From bed5fced7b1b9a2aa55f05cfc68033a6f406bd6a Mon Sep 17 00:00:00 2001 From: "Michael J. Manley" Date: Thu, 23 Jun 2022 11:26:13 -0700 Subject: [PATCH] [no ci] Format Changes --- .clang-format | 148 + .../printer_epsonlx810/lpt_epsonlx810.c | 2679 +- experimental/printer_epsonlx810/plugin.c | 27 +- .../printer_epsonlx810/wx-imagesave.cc | 32 +- includes/private/bswap.h | 192 +- includes/private/bus/mca.h | 3 +- includes/private/bus/pci.h | 8 +- includes/private/codegen/codegen.h | 147 +- includes/private/codegen/codegen_accumulate.h | 8 +- includes/private/codegen/codegen_allocator.h | 6 +- includes/private/codegen/codegen_backend.h | 3 +- .../private/codegen/codegen_backend_arm.h | 3 +- .../private/codegen/codegen_backend_arm64.h | 4 +- .../codegen/codegen_backend_arm64_defs.h | 63 +- .../codegen/codegen_backend_arm64_ops.h | 11 +- .../codegen/codegen_backend_arm_defs.h | 81 +- .../private/codegen/codegen_backend_arm_ops.h | 4 +- .../private/codegen/codegen_backend_x86-64.h | 3 +- .../codegen/codegen_backend_x86-64_defs.h | 5 +- .../codegen/codegen_backend_x86-64_ops.h | 1 - .../codegen_backend_x86-64_ops_helpers.h | 54 +- .../codegen/codegen_backend_x86-64_ops_sse.h | 9 +- .../private/codegen/codegen_backend_x86.h | 3 +- .../codegen/codegen_backend_x86_defs.h | 2 +- .../private/codegen/codegen_backend_x86_ops.h | 1 - .../codegen/codegen_backend_x86_ops_fpu.h | 1 - .../codegen/codegen_backend_x86_ops_helpers.h | 43 +- .../codegen/codegen_backend_x86_ops_sse.h | 9 +- includes/private/codegen/codegen_ir.h | 1 - includes/private/codegen/codegen_ir_defs.h | 642 +- includes/private/codegen/codegen_ops.h | 3 +- includes/private/codegen/codegen_ops_3dnow.h | 1 - includes/private/codegen/codegen_ops_arith.h | 2 - includes/private/codegen/codegen_ops_branch.h | 1 - .../private/codegen/codegen_ops_fpu_arith.h | 1 - .../codegen/codegen_ops_fpu_constant.h | 1 - .../codegen/codegen_ops_fpu_loadstore.h | 1 - .../private/codegen/codegen_ops_fpu_misc.h | 1 - .../private/codegen/codegen_ops_helpers.h | 67 +- includes/private/codegen/codegen_ops_jump.h | 1 - includes/private/codegen/codegen_ops_logic.h | 1 - includes/private/codegen/codegen_ops_misc.h | 1 - .../private/codegen/codegen_ops_mmx_arith.h | 1 - .../private/codegen/codegen_ops_mmx_cmp.h | 1 - .../codegen/codegen_ops_mmx_loadstore.h | 1 - .../private/codegen/codegen_ops_mmx_logic.h | 1 - .../private/codegen/codegen_ops_mmx_pack.h | 1 - .../private/codegen/codegen_ops_mmx_shift.h | 1 - includes/private/codegen/codegen_ops_mov.h | 1 - includes/private/codegen/codegen_ops_shift.h | 1 - includes/private/codegen/codegen_ops_stack.h | 1 - includes/private/codegen/codegen_reg.h | 241 +- .../private/codegen/codegen_timing_common.h | 121 +- includes/private/codegen/codegen_x86-64.h | 8 +- includes/private/cpu/386_common.h | 364 +- includes/private/cpu/386_ops.h | 16491 +++++++++++-- includes/private/cpu/8087.h | 83 +- includes/private/cpu/cpu.h | 83 +- includes/private/cpu/x86.h | 206 +- includes/private/cpu/x86_flags.h | 878 +- includes/private/cpu/x86_ops_3dnow.h | 414 +- includes/private/cpu/x86_ops_arith.h | 1545 +- includes/private/cpu/x86_ops_atomic.h | 568 +- includes/private/cpu/x86_ops_bcd.h | 160 +- includes/private/cpu/x86_ops_bit.h | 682 +- includes/private/cpu/x86_ops_bitscan.h | 242 +- includes/private/cpu/x86_ops_call.h | 1062 +- includes/private/cpu/x86_ops_cyrix.h | 326 +- includes/private/cpu/x86_ops_flag.h | 380 +- includes/private/cpu/x86_ops_fpu.h | 76 +- includes/private/cpu/x86_ops_inc_dec.h | 99 +- includes/private/cpu/x86_ops_int.h | 194 +- includes/private/cpu/x86_ops_io.h | 264 +- includes/private/cpu/x86_ops_jump.h | 597 +- includes/private/cpu/x86_ops_misc.h | 1803 +- includes/private/cpu/x86_ops_mmx.h | 67 +- includes/private/cpu/x86_ops_mmx_arith.h | 816 +- includes/private/cpu/x86_ops_mmx_cmp.h | 232 +- includes/private/cpu/x86_ops_mmx_logic.h | 96 +- includes/private/cpu/x86_ops_mmx_mov.h | 304 +- includes/private/cpu/x86_ops_mmx_pack.h | 416 +- includes/private/cpu/x86_ops_mmx_shift.h | 580 +- includes/private/cpu/x86_ops_mov.h | 1202 +- includes/private/cpu/x86_ops_mov_ctrl.h | 462 +- includes/private/cpu/x86_ops_mov_seg.h | 822 +- includes/private/cpu/x86_ops_movx.h | 332 +- includes/private/cpu/x86_ops_msr.h | 40 +- includes/private/cpu/x86_ops_mul.h | 480 +- includes/private/cpu/x86_ops_pmode.h | 905 +- includes/private/cpu/x86_ops_prefix.h | 275 +- includes/private/cpu/x86_ops_rep.h | 1424 +- includes/private/cpu/x86_ops_ret.h | 380 +- includes/private/cpu/x86_ops_set.h | 54 +- includes/private/cpu/x86_ops_shift.h | 1189 +- includes/private/cpu/x86_ops_stack.h | 972 +- includes/private/cpu/x86_ops_string.h | 1256 +- includes/private/cpu/x86_ops_xchg.h | 358 +- includes/private/cpu/x87.h | 28 +- includes/private/cpu/x87_ops.h | 1793 +- includes/private/cpu/x87_ops_arith.h | 748 +- includes/private/cpu/x87_ops_loadstore.h | 970 +- includes/private/cpu/x87_ops_misc.h | 1523 +- includes/private/cpu/x87_timings.h | 92 +- includes/private/devices/cassette.h | 1 - includes/private/devices/esdi_at.h | 1 - includes/private/devices/f82c710_upc.h | 2 - includes/private/devices/nvr.h | 1 - includes/private/devices/nvr_tc8521.h | 1 - includes/private/devices/ps2_nvr.h | 1 - includes/private/devices/sis496.h | 1 - includes/private/disc/disc.h | 20 +- includes/private/dosbox/cdrom.h | 204 +- includes/private/dosbox/dbopl.h | 364 +- includes/private/dosbox/nukedopl.h | 126 +- includes/private/dosbox/vid_cga_comp.h | 3 +- includes/private/fdi2raw.h | 17 +- includes/private/filters.h | 467 +- includes/private/flash/rom.h | 9 +- includes/private/floppy/fdc.h | 11 +- includes/private/floppy/fdc37c665.h | 1 - includes/private/floppy/fdc37c93x.h | 1 - includes/private/floppy/fdd.h | 1 - includes/private/hdd/hdd_file.h | 18 +- includes/private/hdd/minivhd/cwalk.h | 54 +- includes/private/hdd/minivhd/minivhd.h | 192 +- includes/private/hdd/minivhd/minivhd_create.h | 3 +- .../private/hdd/minivhd/minivhd_internal.h | 116 +- includes/private/hdd/minivhd/minivhd_io.h | 92 +- .../private/hdd/minivhd/minivhd_struct_rw.h | 8 +- includes/private/hdd/minivhd/minivhd_util.h | 52 +- includes/private/ibm.h | 437 +- includes/private/ide/ide.h | 33 +- includes/private/ide/ide_atapi.h | 66 +- includes/private/ide/ide_sff8038i.h | 12 +- includes/private/io.h | 24 +- includes/private/joystick/gameport.h | 4 +- .../joystick/joystick_ch_flightstick_pro.h | 1 - includes/private/joystick/joystick_standard.h | 1 - includes/private/joystick/joystick_sw_pad.h | 1 - includes/private/joystick/joystick_tm_fcs.h | 1 - includes/private/keyboard/keyboard.h | 8 +- includes/private/keyboard/keyboard_amstrad.h | 1 - includes/private/keyboard/keyboard_at.h | 1 - includes/private/keyboard/keyboard_olim24.h | 1 - includes/private/keyboard/keyboard_pcjr.h | 1 - includes/private/keyboard/keyboard_xt.h | 1 - includes/private/memory/mem.h | 113 +- includes/private/memory/mem_bios.h | 1 - includes/private/models/82091aa.h | 1 - includes/private/models/acc2036.h | 1 - includes/private/models/acc2168.h | 1 - includes/private/models/acc3221.h | 1 - includes/private/models/acer386sx.h | 1 - includes/private/models/ali1429.h | 1 - includes/private/models/amstrad.h | 8 +- includes/private/models/cbm_io.h | 1 - includes/private/models/cmd640.h | 1 - includes/private/models/compaq.h | 1 - includes/private/models/cs8230.h | 1 - includes/private/models/dells200.h | 1 - includes/private/models/dma.h | 1 - includes/private/models/headland.h | 1 - includes/private/models/i430fx.h | 1 - includes/private/models/i430hx.h | 1 - includes/private/models/i430lx.h | 1 - includes/private/models/i430vx.h | 1 - includes/private/models/i440bx.h | 1 - includes/private/models/i440fx.h | 1 - includes/private/models/intel.h | 1 - includes/private/models/jim.h | 1 - includes/private/models/laserxt.h | 1 - includes/private/models/model.h | 17 +- includes/private/models/mvp3.h | 1 - includes/private/models/neat.h | 1 - includes/private/models/nmi.h | 3 - includes/private/models/olivetti_m24.h | 1 - includes/private/models/opti495.h | 1 - includes/private/models/pc87306.h | 1 - includes/private/models/pc87307.h | 1 - includes/private/models/pic.h | 1 - includes/private/models/piix.h | 10 +- includes/private/models/piix_pm.h | 1 - includes/private/models/pit.h | 2 - includes/private/models/ps1.h | 1 - includes/private/models/ps2.h | 1 - includes/private/models/ps2_mca.h | 1 - includes/private/models/scat.h | 38 +- includes/private/models/serial.h | 12 +- includes/private/models/sio.h | 1 - includes/private/models/sl82c460.h | 1 - includes/private/models/superxt.h | 1 - includes/private/models/t1000.h | 1 - includes/private/models/t3100e.h | 1 - includes/private/models/um8669f.h | 1 - includes/private/models/um8881f.h | 1 - includes/private/models/vl82c480.h | 1 - includes/private/models/vt82c586b.h | 1 - includes/private/models/w83877tf.h | 1 - includes/private/models/w83977tf.h | 1 - includes/private/models/wd76c10.h | 1 - includes/private/models/xi8088.h | 1 - includes/private/models/zenith.h | 1 - includes/private/mouse/mouse.h | 16 +- includes/private/networking/ne2000.h | 1 - includes/private/networking/nethandler.h | 8 +- includes/private/networking/slirp/bootp.h | 192 +- includes/private/networking/slirp/ctl.h | 12 +- includes/private/networking/slirp/debug.h | 46 +- includes/private/networking/slirp/icmp_var.h | 27 +- includes/private/networking/slirp/if.h | 60 +- includes/private/networking/slirp/ip.h | 308 +- includes/private/networking/slirp/ip_icmp.h | 180 +- includes/private/networking/slirp/libslirp.h | 9 +- includes/private/networking/slirp/main.h | 6 +- includes/private/networking/slirp/mbuf.h | 84 +- includes/private/networking/slirp/misc.h | 46 +- includes/private/networking/slirp/queue.h | 13 +- includes/private/networking/slirp/sbuf.h | 20 +- includes/private/networking/slirp/slirp.h | 193 +- includes/private/networking/slirp/socket.h | 98 +- includes/private/networking/slirp/tcp.h | 125 +- includes/private/networking/slirp/tcp_timer.h | 72 +- includes/private/networking/slirp/tcp_var.h | 282 +- includes/private/networking/slirp/tcpip.h | 48 +- includes/private/networking/slirp/tftp.h | 40 +- includes/private/networking/slirp/udp.h | 64 +- includes/private/pgc_palettes.h | 1954 +- includes/private/plat-dinput.h | 1 - includes/private/plat-joystick.h | 104 +- includes/private/plat-keyboard.h | 24 +- includes/private/plat-midi.h | 1 - includes/private/plat-mouse.h | 13 +- includes/private/plugin-api/config.h | 6 +- includes/private/plugin-api/paths.h | 12 +- includes/private/plugin-api/tinydir.h | 946 +- includes/private/pzx.h | 54 +- includes/private/resources.h | 146 +- includes/private/rtc.h | 241 +- includes/private/rtc_tc8521.h | 45 +- includes/private/scamp.h | 1 - includes/private/scsi/scsi.h | 150 +- includes/private/scsi/scsi_cd.h | 5 +- includes/private/sound/resid-fp/envelope.h | 213 +- includes/private/sound/resid-fp/extfilt.h | 100 +- includes/private/sound/resid-fp/filter.h | 406 +- includes/private/sound/resid-fp/pot.h | 7 +- includes/private/sound/resid-fp/sid.h | 155 +- includes/private/sound/resid-fp/siddefs-fp.h | 21 +- includes/private/sound/resid-fp/voice.h | 55 +- includes/private/sound/resid-fp/wave.h | 429 +- includes/private/sound/sound.h | 1 - includes/private/sound/sound_ad1848.h | 16 +- includes/private/sound/sound_adlib.h | 1 - includes/private/sound/sound_adlibgold.h | 1 - includes/private/sound/sound_audiopci.h | 1 - includes/private/sound/sound_azt2316a.h | 1 - includes/private/sound/sound_cms.h | 1 - includes/private/sound/sound_dbopl.h | 14 +- includes/private/sound/sound_emu8k.h | 243 +- includes/private/sound/sound_gus.h | 1 - includes/private/sound/sound_mpu401_uart.h | 5 +- includes/private/sound/sound_opl.h | 8 +- includes/private/sound/sound_pas16.h | 1 - includes/private/sound/sound_ps1.h | 1 - includes/private/sound/sound_pssj.h | 1 - includes/private/sound/sound_resid.h | 13 +- includes/private/sound/sound_sb.h | 82 +- includes/private/sound/sound_sb_dsp.h | 37 +- includes/private/sound/sound_sn76489.h | 15 +- includes/private/sound/sound_speaker.h | 1 - includes/private/sound/sound_ssi2001.h | 1 - includes/private/sound/sound_wss.h | 1 - includes/private/sound/sound_ym7128.h | 14 +- includes/private/thread.h | 1 - includes/private/timer.h | 103 +- includes/private/video/vid_ati18800.h | 1 - includes/private/video/vid_ati28800.h | 1 - includes/private/video/vid_ati68860_ramdac.h | 8 +- includes/private/video/vid_ati_eeprom.h | 4 +- includes/private/video/vid_ati_mach64.h | 1 - includes/private/video/vid_cga.h | 38 +- includes/private/video/vid_cl5429.h | 1 - includes/private/video/vid_colorplus.h | 1 - includes/private/video/vid_compaq_cga.h | 1 - includes/private/video/vid_ddc.h | 1 - includes/private/video/vid_ega.h | 44 +- includes/private/video/vid_et4000.h | 1 - includes/private/video/vid_et4000w32.h | 1 - includes/private/video/vid_genius.h | 1 - includes/private/video/vid_hercules.h | 1 - includes/private/video/vid_ht216.h | 1 - includes/private/video/vid_icd2061.h | 4 +- includes/private/video/vid_ics2595.h | 4 +- includes/private/video/vid_im1024.h | 1 - includes/private/video/vid_incolor.h | 1 - includes/private/video/vid_mda.h | 11 +- includes/private/video/vid_olivetti_m24.h | 1 - includes/private/video/vid_oti037.h | 1 - includes/private/video/vid_oti067.h | 1 - includes/private/video/vid_paradise.h | 1 - includes/private/video/vid_pc1512.h | 1 - includes/private/video/vid_pc1640.h | 1 - includes/private/video/vid_pc200.h | 1 - includes/private/video/vid_pcjr.h | 1 - includes/private/video/vid_pgc.h | 190 +- includes/private/video/vid_ps1_svga.h | 1 - includes/private/video/vid_s3.h | 1 - includes/private/video/vid_s3_virge.h | 1 - includes/private/video/vid_sdac_ramdac.h | 4 +- includes/private/video/vid_sigma.h | 2 - includes/private/video/vid_stg_ramdac.h | 4 +- includes/private/video/vid_svga.h | 92 +- includes/private/video/vid_svga_render.h | 1 - .../private/video/vid_svga_render_remap.h | 125 +- includes/private/video/vid_t1000.h | 1 - includes/private/video/vid_t3100e.h | 1 - includes/private/video/vid_tandy.h | 1 - includes/private/video/vid_tandysl.h | 1 - includes/private/video/vid_tgui9440.h | 1 - includes/private/video/vid_tkd8001_ramdac.h | 4 +- includes/private/video/vid_tvga.h | 1 - includes/private/video/vid_tvp3026_ramdac.h | 8 +- includes/private/video/vid_unk_ramdac.h | 4 +- includes/private/video/vid_vga.h | 1 - includes/private/video/vid_voodoo.h | 1 - includes/private/video/vid_voodoo_banshee.h | 1 - .../video/vid_voodoo_banshee_blitter.h | 1 - includes/private/video/vid_voodoo_blitter.h | 1 - .../private/video/vid_voodoo_codegen_x86-64.h | 1050 +- .../private/video/vid_voodoo_codegen_x86.h | 1131 +- includes/private/video/vid_voodoo_common.h | 139 +- includes/private/video/vid_voodoo_display.h | 1 - includes/private/video/vid_voodoo_dither.h | 20512 ++++++++-------- includes/private/video/vid_voodoo_fb.h | 1 - includes/private/video/vid_voodoo_fifo.h | 1 - includes/private/video/vid_voodoo_reg.h | 1 - includes/private/video/vid_voodoo_regs.h | 540 +- includes/private/video/vid_voodoo_render.h | 551 +- includes/private/video/vid_voodoo_setup.h | 1 - includes/private/video/vid_voodoo_texture.h | 25 +- includes/private/video/vid_wy700.h | 1 - includes/private/video/video.h | 45 +- includes/private/wx-ui/wx-app.h | 137 +- includes/private/wx-ui/wx-common.h | 1 - includes/private/wx-ui/wx-deviceconfig.h | 2 +- includes/private/wx-ui/wx-dialogbox.h | 28 +- includes/private/wx-ui/wx-display.h | 2 +- includes/private/wx-ui/wx-glsl.h | 4 +- includes/private/wx-ui/wx-glslp-parser.h | 8 +- includes/private/wx-ui/wx-hostconfig.h | 1 - includes/private/wx-ui/wx-sdl2-glw.h | 10 +- includes/private/wx-ui/wx-sdl2-video-gl3.h | 7 +- .../private/wx-ui/wx-sdl2-video-renderer.h | 7 +- includes/private/wx-ui/wx-sdl2-video.h | 33 +- includes/private/wx-ui/wx-sdl2.h | 9 +- includes/private/wx-ui/wx-shaderconfig.h | 3 +- includes/private/wx-ui/wx-status.h | 63 +- includes/private/wx-ui/wx-utils.h | 150 +- includes/public/pcem/config.h | 4 +- includes/public/pcem/cpu.h | 34 +- includes/public/pcem/defines.h | 14 +- includes/public/pcem/devices.h | 140 +- includes/public/pcem/plugin.h | 12 +- src/bus/mca.c | 75 +- src/bus/pci.c | 264 +- src/cdrom/cdrom-image.cc | 756 +- src/cdrom/cdrom-ioctl-dummy.c | 19 +- src/cdrom/cdrom-ioctl-linux.c | 916 +- src/cdrom/cdrom-ioctl-osx.c | 1011 +- src/cdrom/cdrom-ioctl.c | 1182 +- src/cdrom/cdrom-null.c | 125 +- src/codegen/arm32/codegen_backend_arm.c | 524 +- src/codegen/arm32/codegen_backend_arm_ops.c | 1563 +- src/codegen/arm32/codegen_backend_arm_uops.c | 6266 +++-- src/codegen/arm64/codegen_backend_arm64.c | 550 +- src/codegen/arm64/codegen_backend_arm64_imm.c | 1590 +- src/codegen/arm64/codegen_backend_arm64_ops.c | 2022 +- .../arm64/codegen_backend_arm64_uops.c | 6010 ++--- src/codegen/codegen.c | 1107 +- src/codegen/codegen_accumulate.c | 50 +- src/codegen/codegen_allocator.c | 140 +- src/codegen/codegen_block.c | 1104 +- src/codegen/codegen_ir.c | 265 +- src/codegen/codegen_ops.c | 5600 ++++- src/codegen/codegen_ops_3dnow.c | 258 +- src/codegen/codegen_ops_arith.c | 3651 +-- src/codegen/codegen_ops_branch.c | 1609 +- src/codegen/codegen_ops_fpu_arith.c | 827 +- src/codegen/codegen_ops_fpu_constant.c | 24 +- src/codegen/codegen_ops_fpu_loadstore.c | 288 +- src/codegen/codegen_ops_fpu_misc.c | 110 +- src/codegen/codegen_ops_helpers.c | 80 +- src/codegen/codegen_ops_jump.c | 348 +- src/codegen/codegen_ops_logic.c | 956 +- src/codegen/codegen_ops_misc.c | 869 +- src/codegen/codegen_ops_mmx_arith.c | 68 +- src/codegen/codegen_ops_mmx_cmp.c | 54 +- src/codegen/codegen_ops_mmx_loadstore.c | 124 +- src/codegen/codegen_ops_mmx_logic.c | 120 +- src/codegen/codegen_ops_mmx_pack.c | 58 +- src/codegen/codegen_ops_mmx_shift.c | 120 +- src/codegen/codegen_ops_mov.c | 939 +- src/codegen/codegen_ops_shift.c | 1732 +- src/codegen/codegen_ops_stack.c | 522 +- src/codegen/codegen_reg.c | 1264 +- src/codegen/codegen_timing_486.c | 1666 +- src/codegen/codegen_timing_686.c | 2255 +- src/codegen/codegen_timing_common.c | 2003 +- src/codegen/codegen_timing_cyrixiii.c | 1516 +- src/codegen/codegen_timing_k6.c | 4454 ++-- src/codegen/codegen_timing_p6.c | 3914 +-- src/codegen/codegen_timing_pentium.c | 2608 +- src/codegen/codegen_timing_winchip.c | 1666 +- src/codegen/codegen_timing_winchip2.c | 1636 +- src/codegen/codegen_x86-64.c | 1751 +- src/codegen/x86-64/codegen_backend_x86-64.c | 540 +- .../x86-64/codegen_backend_x86-64_ops.c | 2030 +- .../x86-64/codegen_backend_x86-64_ops_sse.c | 572 +- .../x86-64/codegen_backend_x86-64_uops.c | 3536 +-- src/codegen/x86/codegen_backend_x86.c | 549 +- src/codegen/x86/codegen_backend_x86_ops.c | 1328 +- src/codegen/x86/codegen_backend_x86_ops_fpu.c | 74 +- src/codegen/x86/codegen_backend_x86_ops_sse.c | 525 +- src/codegen/x86/codegen_backend_x86_uops.c | 3564 +-- src/cpu/386.c | 478 +- src/cpu/386_common.c | 319 +- src/cpu/386_dynarec.c | 920 +- src/cpu/386_dynarec_ops.c | 48 +- src/cpu/808x.c | 7355 +++--- src/cpu/cpu.c | 3528 +-- src/cpu/cpu_tables.c | 1092 +- src/cpu/x86seg.c | 5667 ++--- src/cpu/x87.c | 114 +- src/cpu/x87_timings.c | 588 +- src/devices/cassette.c | 156 +- src/devices/esdi_at.c | 1148 +- src/devices/f82c710_upc.c | 670 +- src/devices/nvr.c | 1275 +- src/devices/ps2_nvr.c | 128 +- src/devices/sis496.c | 196 +- src/disc/disc.c | 325 +- src/disc/disc_fdi.c | 694 +- src/disc/disc_img.c | 730 +- src/disc/disc_sector.c | 597 +- src/dosbox/vid_cga_comp.c | 369 +- src/fdi2raw.c | 2624 +- src/flash/intel_flash.c | 638 +- src/flash/rom.c | 153 +- src/flash/sst39sf010.c | 342 +- src/flash/tandy_eeprom.c | 232 +- src/flash/tandy_rom.c | 92 +- src/floppy/fdc.c | 2148 +- src/floppy/fdc37c665.c | 222 +- src/floppy/fdc37c93x.c | 352 +- src/floppy/fdd.c | 237 +- src/hdd/hdd.c | 209 +- src/hdd/hdd_esdi.c | 1445 +- src/hdd/hdd_file.c | 262 +- src/hdd/minivhd/cwalk.c | 2043 +- src/hdd/minivhd/libxml2_encoding.c | 684 +- src/hdd/minivhd/minivhd_convert.c | 168 +- src/hdd/minivhd/minivhd_create.c | 779 +- src/hdd/minivhd/minivhd_io.c | 398 +- src/hdd/minivhd/minivhd_manage.c | 777 +- src/hdd/minivhd/minivhd_struct_rw.c | 232 +- src/hdd/minivhd/minivhd_util.c | 434 +- src/ide/ide.c | 1843 +- src/ide/ide_atapi.c | 763 +- src/ide/ide_sff8038i.c | 293 +- src/ide/xtide.c | 172 +- src/io.c | 266 +- src/joystick/gameport.c | 217 +- src/joystick/joystick_ch_flightstick_pro.c | 110 +- src/joystick/joystick_standard.c | 297 +- src/joystick/joystick_sw_pad.c | 244 +- src/joystick/joystick_tm_fcs.c | 111 +- src/keyboard/keyboard.c | 1855 +- src/keyboard/keyboard_amstrad.c | 212 +- src/keyboard/keyboard_at.c | 1383 +- src/keyboard/keyboard_olim24.c | 458 +- src/keyboard/keyboard_pcjr.c | 267 +- src/keyboard/keyboard_xt.c | 371 +- src/lpt/lpt.c | 174 +- src/lpt/lpt_dac.c | 128 +- src/lpt/lpt_dss.c | 101 +- src/mcr.c | 43 +- src/memory/mem.c | 2285 +- src/memory/mem_bios.c | 2231 +- src/mfm/mfm_at.c | 774 +- src/mfm/mfm_xebec.c | 1337 +- src/models/82091aa.c | 328 +- src/models/acc2036.c | 118 +- src/models/acc2168.c | 131 +- src/models/acc3221.c | 129 +- src/models/acer386sx.c | 189 +- src/models/ali1429.c | 84 +- src/models/amstrad.c | 371 +- src/models/cbm_io.c | 45 +- src/models/cmd640.c | 90 +- src/models/compaq.c | 42 +- src/models/cs8230.c | 170 +- src/models/dells200.c | 76 +- src/models/dma.c | 1134 +- src/models/headland.c | 806 +- src/models/i430fx.c | 283 +- src/models/i430hx.c | 279 +- src/models/i430lx.c | 314 +- src/models/i430vx.c | 285 +- src/models/i440bx.c | 293 +- src/models/i440fx.c | 275 +- src/models/intel.c | 232 +- src/models/jim.c | 126 +- src/models/laserxt.c | 171 +- src/models/model.c | 1995 +- src/models/mvp3.c | 344 +- src/models/neat.c | 79 +- src/models/nmi.c | 8 +- src/models/nvr_tc8521.c | 114 +- src/models/olivetti_m24.c | 16 +- src/models/opti495.c | 312 +- src/models/pc87306.c | 278 +- src/models/pc87307.c | 192 +- src/models/pic.c | 627 +- src/models/piix.c | 503 +- src/models/piix_pm.c | 605 +- src/models/pit.c | 966 +- src/models/ps1.c | 458 +- src/models/ps2.c | 179 +- src/models/ps2_mca.c | 1492 +- src/models/scamp.c | 1275 +- src/models/scat.c | 2557 +- src/models/serial.c | 418 +- src/models/sio.c | 289 +- src/models/sl82c460.c | 84 +- src/models/superxt.c | 66 +- src/models/t1000.c | 823 +- src/models/t3100e.c | 808 +- src/models/um8669f.c | 223 +- src/models/um8881f.c | 80 +- src/models/vl82c480.c | 229 +- src/models/vt82c586b.c | 779 +- src/models/w83877tf.c | 340 +- src/models/w83977tf.c | 267 +- src/models/wd76c10.c | 158 +- src/models/xi8088.c | 151 +- src/models/zenith.c | 40 +- src/mouse/mouse.c | 41 +- src/mouse/mouse_msystems.c | 104 +- src/mouse/mouse_ps2.c | 378 +- src/mouse/mouse_serial.c | 118 +- src/networking/ne2000.c | 2713 +- src/networking/nethandler.c | 82 +- src/networking/slirp/bootp.c | 319 +- src/networking/slirp/cksum.c | 199 +- src/networking/slirp/debug.c | 469 +- src/networking/slirp/if.c | 303 +- src/networking/slirp/ip_icmp.c | 510 +- src/networking/slirp/ip_input.c | 1007 +- src/networking/slirp/ip_output.c | 268 +- src/networking/slirp/mbuf.c | 285 +- src/networking/slirp/misc.c | 827 +- src/networking/slirp/queue.c | 107 +- src/networking/slirp/sbuf.c | 290 +- src/networking/slirp/slirp.c | 996 +- src/networking/slirp/socket.c | 1025 +- src/networking/slirp/tcp_input.c | 2901 ++- src/networking/slirp/tcp_output.c | 979 +- src/networking/slirp/tcp_subr.c | 1331 +- src/networking/slirp/tcp_timer.c | 450 +- src/networking/slirp/tftp.c | 374 +- src/networking/slirp/udp.c | 980 +- src/pc.c | 1314 +- src/plugin-api/config.c | 557 +- src/plugin-api/device.c | 330 +- src/plugin-api/logging.c | 148 +- src/plugin-api/paths.c | 332 +- src/plugin-api/plugin.c | 121 +- src/plugin-api/wx-utils.cc | 14 +- src/ppi.c | 5 +- src/pzx.c | 530 +- src/rtc.c | 282 +- src/rtc_tc8521.c | 254 +- src/scsi/scsi.c | 517 +- src/scsi/scsi_53c400.c | 1123 +- src/scsi/scsi_aha1540.c | 4054 ++- src/scsi/scsi_cd.c | 2890 ++- src/scsi/scsi_hd.c | 1232 +- src/scsi/scsi_ibm.c | 1813 +- src/scsi/scsi_zip.c | 1891 +- src/sound/midi_alsa.c | 206 +- src/sound/resid-fp/convolve-sse.cc | 80 +- src/sound/resid-fp/convolve.cc | 9 +- src/sound/resid-fp/envelope.cc | 179 +- src/sound/resid-fp/extfilt.cc | 56 +- src/sound/resid-fp/filter.cc | 144 +- src/sound/resid-fp/pot.cc | 4 +- src/sound/resid-fp/sid.cc | 1005 +- src/sound/resid-fp/voice.cc | 70 +- src/sound/resid-fp/wave.cc | 129 +- src/sound/resid-fp/wave6581_PST.cc | 1029 +- src/sound/resid-fp/wave6581_PS_.cc | 1029 +- src/sound/resid-fp/wave6581_P_T.cc | 1029 +- src/sound/resid-fp/wave6581__ST.cc | 1029 +- src/sound/resid-fp/wave8580_PST.cc | 1029 +- src/sound/resid-fp/wave8580_PS_.cc | 1029 +- src/sound/resid-fp/wave8580_P_T.cc | 1029 +- src/sound/resid-fp/wave8580__ST.cc | 1029 +- src/sound/sdl2-midi.c | 16 +- src/sound/sound.c | 279 +- src/sound/sound_ad1848.c | 451 +- src/sound/sound_adlib.c | 102 +- src/sound/sound_adlibgold.c | 1370 +- src/sound/sound_audiopci.c | 1875 +- src/sound/sound_azt2316a.c | 2314 +- src/sound/sound_cms.c | 303 +- src/sound/sound_dbopl.cc | 212 +- src/sound/sound_emu8k.c | 3548 +-- src/sound/sound_gus.c | 1919 +- src/sound/sound_mpu401_uart.c | 112 +- src/sound/sound_opl.c | 154 +- src/sound/sound_pas16.c | 1042 +- src/sound/sound_ps1.c | 214 +- src/sound/sound_pssj.c | 266 +- src/sound/sound_resid.cc | 99 +- src/sound/sound_sb.c | 2621 +- src/sound/sound_sb_dsp.c | 2291 +- src/sound/sound_sn76489.c | 324 +- src/sound/sound_speaker.c | 50 +- src/sound/sound_ssi2001.c | 72 +- src/sound/sound_wss.c | 131 +- src/sound/sound_ym7128.c | 235 +- src/sound/soundopenal.c | 314 +- src/sound/win-midi.c | 108 +- src/thread-pthread.c | 81 +- src/timer.c | 158 +- src/video/vid_ati18800.c | 400 +- src/video/vid_ati28800.c | 787 +- src/video/vid_ati68860_ramdac.c | 241 +- src/video/vid_ati_eeprom.c | 325 +- src/video/vid_ati_mach64.c | 6670 ++--- src/video/vid_cga.c | 856 +- src/video/vid_cl5429.c | 3721 ++- src/video/vid_colorplus.c | 597 +- src/video/vid_compaq_cga.c | 618 +- src/video/vid_ddc.c | 435 +- src/video/vid_ega.c | 1933 +- src/video/vid_et4000.c | 928 +- src/video/vid_et4000w32.c | 2303 +- src/video/vid_et4000w32i.c | 2 +- src/video/vid_genius.c | 827 +- src/video/vid_hercules.c | 613 +- src/video/vid_ht216.c | 1863 +- src/video/vid_icd2061.c | 80 +- src/video/vid_ics2595.c | 71 +- src/video/vid_im1024.c | 1240 +- src/video/vid_incolor.c | 1591 +- src/video/vid_mda.c | 512 +- src/video/vid_mga.c | 9112 +++---- src/video/vid_olivetti_m24.c | 741 +- src/video/vid_oti037.c | 311 +- src/video/vid_oti067.c | 370 +- src/video/vid_paradise.c | 595 +- src/video/vid_pc1512.c | 830 +- src/video/vid_pc1640.c | 171 +- src/video/vid_pc200.c | 1685 +- src/video/vid_pcjr.c | 960 +- src/video/vid_pgc.c | 3162 ++- src/video/vid_ps1_svga.c | 219 +- src/video/vid_s3.c | 5336 ++-- src/video/vid_s3_virge.c | 7102 +++--- src/video/vid_sdac_ramdac.c | 269 +- src/video/vid_sigma.c | 1291 +- src/video/vid_stg_ramdac.c | 237 +- src/video/vid_svga.c | 2790 ++- src/video/vid_svga_render.c | 1429 +- src/video/vid_t1000.c | 957 +- src/video/vid_t3100e.c | 951 +- src/video/vid_tandy.c | 1089 +- src/video/vid_tandysl.c | 1160 +- src/video/vid_tgui9440.c | 3001 +-- src/video/vid_tkd8001_ramdac.c | 94 +- src/video/vid_tvga.c | 691 +- src/video/vid_tvp3026_ramdac.c | 660 +- src/video/vid_unk_ramdac.c | 110 +- src/video/vid_vga.c | 216 +- src/video/vid_voodoo.c | 2159 +- src/video/vid_voodoo_banshee.c | 4484 ++-- src/video/vid_voodoo_banshee_blitter.c | 2469 +- src/video/vid_voodoo_blitter.c | 761 +- src/video/vid_voodoo_display.c | 874 +- src/video/vid_voodoo_fb.c | 616 +- src/video/vid_voodoo_fifo.c | 717 +- src/video/vid_voodoo_reg.c | 2319 +- src/video/vid_voodoo_render.c | 2487 +- src/video/vid_voodoo_setup.c | 337 +- src/video/vid_voodoo_texture.c | 828 +- src/video/vid_wy700.c | 1451 +- src/video/video.c | 1885 +- src/wx-ui/wx-app.cc | 255 +- src/wx-ui/wx-common.c | 41 +- src/wx-ui/wx-config-eventbinder.cc | 62 +- src/wx-ui/wx-config.c | 3706 ++- src/wx-ui/wx-config_sel.c | 463 +- src/wx-ui/wx-createdisc.cc | 166 +- src/wx-ui/wx-deviceconfig.cc | 385 +- src/wx-ui/wx-dialogbox.cc | 86 +- src/wx-ui/wx-glslp-parser.c | 424 +- src/wx-ui/wx-hostconfig.c | 249 +- src/wx-ui/wx-joystickconfig.cc | 475 +- src/wx-ui/wx-main.cc | 20 +- src/wx-ui/wx-sdl2-display-win.c | 1387 +- src/wx-ui/wx-sdl2-display.c | 1001 +- src/wx-ui/wx-sdl2-joystick.c | 212 +- src/wx-ui/wx-sdl2-keyboard.c | 14 +- src/wx-ui/wx-sdl2-mouse.c | 58 +- src/wx-ui/wx-sdl2-status.c | 240 +- src/wx-ui/wx-sdl2-video-gl3.c | 2421 +- src/wx-ui/wx-sdl2-video-renderer.c | 215 +- src/wx-ui/wx-sdl2-video.c | 376 +- src/wx-ui/wx-sdl2.c | 1313 +- src/wx-ui/wx-shader_man.c | 291 +- src/wx-ui/wx-shaderconfig.cc | 176 +- src/wx-ui/wx-status.cc | 482 +- src/wx-ui/wx-thread.c | 238 +- src/wx-ui/wx-utils.cc | 910 +- 725 files changed, 219949 insertions(+), 199821 deletions(-) create mode 100644 .clang-format diff --git a/.clang-format b/.clang-format new file mode 100644 index 00000000..ff868029 --- /dev/null +++ b/.clang-format @@ -0,0 +1,148 @@ +--- +Language: Cpp +# BasedOnStyle: LLVM +AccessModifierOffset: -4 +AlignAfterOpenBracket: Align +AlignConsecutiveMacros: false +AlignConsecutiveAssignments: false +AlignConsecutiveBitFields: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlines: Right +AlignOperands: Align +AlignTrailingComments: true +AllowAllArgumentsOnNextLine: true +AllowAllConstructorInitializersOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortEnumsOnASingleLine: true +AllowShortBlocksOnASingleLine: Never +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: All +AllowShortLambdasOnASingleLine: All +AllowShortIfStatementsOnASingleLine: Never +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: MultiLine +BinPackArguments: true +BinPackParameters: true +BraceWrapping: + AfterCaseLabel: false + AfterClass: false + AfterControlStatement: Never + AfterEnum: false + AfterFunction: false + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + AfterExternBlock: false + BeforeCatch: false + BeforeElse: false + BeforeLambdaBody: false + BeforeWhile: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Attach +BreakBeforeInheritanceComma: false +BreakInheritanceList: BeforeColon +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +BreakConstructorInitializers: BeforeColon +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: true +ColumnLimit: 130 +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 8 +ContinuationIndentWidth: 8 +Cpp11BracedListStyle: true +DeriveLineEnding: true +DerivePointerAlignment: false +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IncludeBlocks: Preserve +IncludeCategories: + - Regex: '^"(llvm|llvm-c|clang|clang-c)/' + Priority: 2 + SortPriority: 0 + - Regex: '^(<|"(gtest|gmock|isl|json)/)' + Priority: 3 + SortPriority: 0 + - Regex: '.*' + Priority: 1 + SortPriority: 0 +IncludeIsMainRegex: '(Test)?$' +IncludeIsMainSourceRegex: '' +IndentCaseLabels: false +IndentCaseBlocks: false +IndentGotoLabels: true +IndentPPDirectives: None +IndentExternBlock: AfterExternBlock +IndentWidth: 8 +IndentWrappedFunctionNames: false +InsertTrailingCommas: None +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: true +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBinPackProtocolList: Auto +ObjCBlockIndentWidth: 8 +ObjCBreakBeforeNestedBlockParam: true +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 60 +PointerAlignment: Right +ReflowComments: true +SortIncludes: false +SortUsingDeclarations: false +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatements +SpaceBeforeRangeBasedForLoopColon: true +SpaceInEmptyBlock: false +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInConditionalStatement: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +SpaceBeforeSquareBrackets: false +Standard: Latest +StatementMacros: + - Q_UNUSED + - QT_REQUIRE_VERSION +TabWidth: 8 +UseCRLF: false +UseTab: Never +WhitespaceSensitiveMacros: + - STRINGIZE + - PP_STRINGIZE + - BOOST_PP_STRINGIZE +--- diff --git a/experimental/printer_epsonlx810/lpt_epsonlx810.c b/experimental/printer_epsonlx810/lpt_epsonlx810.c index 2d081302..d60097b4 100644 --- a/experimental/printer_epsonlx810/lpt_epsonlx810.c +++ b/experimental/printer_epsonlx810/lpt_epsonlx810.c @@ -84,7 +84,7 @@ #include #include FT_FREETYPE_H -#if defined (WIN32) +#if defined(WIN32) #include #include #endif @@ -117,81 +117,80 @@ #define OUTPUT_TYPE_JPG 4 #define OUTPUT_TYPE_FORWARD_TO_REAL_PRINTER 5 -typedef enum Typeface -{ +typedef enum Typeface { roman = 0, sansserif, } Typeface; -typedef struct lpt_epsonprinter_t -{ - FT_Library FTlib; // FreeType2 library used to render the characters +typedef struct lpt_epsonprinter_t { + FT_Library FTlib; // FreeType2 library used to render the characters - SDL_Surface* page; // Surface representing the current page - FT_Face curFont; // The font currently used to render characters + SDL_Surface *page; // Surface representing the current page + FT_Face curFont; // The font currently used to render characters // TODO: where exactly in relation to the pins are curX and curY? - double curX, curY; // Position of the print head (in inch) + double curX, curY; // Position of the print head (in inch) - uint16_t dpi; // dpi of the page - uint16_t ESCCmd; // ESC-command that is currently processed - bool ESCSeen; // True if last read character was an ESC (0x1B) + uint16_t dpi; // dpi of the page + uint16_t ESCCmd; // ESC-command that is currently processed + bool ESCSeen; // True if last read character was an ESC (0x1B) - uint8_t numParam, neededParam; // Numbers of parameters already read/needed to process command + uint8_t numParam, neededParam; // Numbers of parameters already read/needed to process command - uint8_t params[20]; // Buffer for the read params - uint16_t defaultStyle, style; // Style of font (see STYLE_* constants) - double defaultCPI, cpi, actcpi; // CPI value set by DIP switch, program and the actual one (taking in account font types) + uint8_t params[20]; // Buffer for the read params + uint16_t defaultStyle, style; // Style of font (see STYLE_* constants) + double defaultCPI, cpi, actcpi; // CPI value set by DIP switch, program and the actual one (taking in account font types) - double topMargin, bottomMargin, rightMargin, leftMargin; // Margins of the page (in inch) - double pageWidth, pageHeight; // Size of page (in inch) - double defaultPageWidth, defaultPageHeight; // Default size of page (in inch) - double lineSpacing; // Size of one line (in inch) + double topMargin, bottomMargin, rightMargin, leftMargin; // Margins of the page (in inch) + double pageWidth, pageHeight; // Size of page (in inch) + double defaultPageWidth, defaultPageHeight; // Default size of page (in inch) + double lineSpacing; // Size of one line (in inch) - double horiztabs[32]; // Stores the set horizontal tabs (in inch) - uint8_t numHorizTabs; // Number of configured tabs + double horiztabs[32]; // Stores the set horizontal tabs (in inch) + uint8_t numHorizTabs; // Number of configured tabs - double verttabs[16]; // Stores the set vertical tabs (in inch) - uint8_t numVertTabs; // Number of configured tabs + double verttabs[16]; // Stores the set vertical tabs (in inch) + uint8_t numVertTabs; // Number of configured tabs - uint8_t defaultCharTable, curCharTable; // Default and currently used char table und charset + uint8_t defaultCharTable, curCharTable; // Default and currently used char table und charset uint8_t defaultI18NCharset, curI18NCharset; uint16_t defaultCodePage; - uint8_t defaultQuality, printQuality; // Print quality (see QUALITY_* constants) + uint8_t defaultQuality, printQuality; // Print quality (see QUALITY_* constants) - Typeface defaultNLQtypeFace, NLQtypeFace; // Typeface used in NLQ printing mode + Typeface defaultNLQtypeFace, NLQtypeFace; // Typeface used in NLQ printing mode - bool charRead; // True if a character was read since the printer was last initialized - bool autoFeed; // True if a LF should automatically added after a CR - bool printUpperContr; // True if the upper command characters should be printed + bool charRead; // True if a character was read since the printer was last initialized + bool autoFeed; // True if a LF should automatically added after a CR + bool printUpperContr; // True if the upper command characters should be printed - struct bitGraphicParams // Holds information about printing bit images + struct bitGraphicParams // Holds information about printing bit images { - uint16_t horizDens, vertDens; // Density of image to print (in dpi) - bool adjacent; // Print adjacent pixels? (ignored) - uint8_t bytesColumn; // Bytes per column - uint16_t remBytes; // Bytes left to read before image is done - uint8_t column[6]; // Bytes of the current and last column - uint8_t readBytesColumn; // Bytes read so far for the current column + uint16_t horizDens, vertDens; // Density of image to print (in dpi) + bool adjacent; // Print adjacent pixels? (ignored) + uint8_t bytesColumn; // Bytes per column + uint16_t remBytes; // Bytes left to read before image is done + uint8_t column[6]; // Bytes of the current and last column + uint8_t readBytesColumn; // Bytes read so far for the current column } bitGraph; - uint8_t densk, densl, densy, densz; // Image density modes used in ESC K/L/Y/Z commands + uint8_t densk, densl, densy, densz; // Image density modes used in ESC K/L/Y/Z commands - uint16_t curMap[256]; // Currently used ASCII => Unicode mapping - uint16_t charTables[2]; // Charactertables + uint16_t curMap[256]; // Currently used ASCII => Unicode mapping + uint16_t charTables[2]; // Charactertables -#if defined (WIN32) - HDC printerDC; // Win32 printer device +#if defined(WIN32) + HDC printerDC; // Win32 printer device #endif - int output_type; // Output method selected by user - void* outputHandle; // If not null, additional pages will be appended to the given handle - bool multipageOutput; // If true, all pages are combined to one file/print job etc. until the "eject page" button is pressed - uint16_t multiPageCounter; // Current page (when printing multipages) + int output_type; // Output method selected by user + void *outputHandle; // If not null, additional pages will be appended to the given handle + bool multipageOutput; // If true, all pages are combined to one file/print job etc. until the "eject page" button is + // pressed + uint16_t multiPageCounter; // Current page (when printing multipages) - uint8_t ASCII85Buffer[4]; // Buffer used in ASCII85 encoding - uint8_t ASCII85BufferPos; // Position in ASCII85 encode buffer - uint8_t ASCII85CurCol; // Columns printed so far in the current lines + uint8_t ASCII85Buffer[4]; // Buffer used in ASCII85 encoding + uint8_t ASCII85BufferPos; // Position in ASCII85 encode buffer + uint8_t ASCII85CurCol; // Columns printed so far in the current lines uint8_t last_data; uint8_t controlreg; @@ -258,7 +257,7 @@ void updateCharset(lpt_epsonprinter_t *printer); void outputPage(lpt_epsonprinter_t *printer); // Prints out a byte using ASCII85 encoding (only outputs something every four bytes). When b>255, closes the ASCII85 string -void fprintASCII85(FILE* f, uint16_t b, lpt_epsonprinter_t *printer); +void fprintASCII85(FILE *f, uint16_t b, lpt_epsonprinter_t *printer); // Closes a multipage document void finishMultipage(lpt_epsonprinter_t *printer); @@ -277,8 +276,7 @@ uint8_t getPixel(uint32_t num, lpt_epsonprinter_t *printer); // these are the bsd safe string handling functions #ifndef HAVE_STRLCAT -size_t strlcat(char *dst, const char *src, size_t size) -{ +size_t strlcat(char *dst, const char *src, size_t size) { size_t srclen; size_t dstlen; @@ -301,11 +299,10 @@ size_t strlcat(char *dst, const char *src, size_t size) #endif /* !HAVE_STRLCAT */ #ifndef HAVE_STRLCPY -size_t strlcpy(char *dst, const char *src, size_t size) -{ - size_t srclen; +size_t strlcpy(char *dst, const char *src, size_t size) { + size_t srclen; - size --; + size--; srclen = strlen(src); if (srclen > size) @@ -321,159 +318,168 @@ size_t strlcpy(char *dst, const char *src, size_t size) // Various ASCII codepage to unicode maps static const uint16_t italicsMap[256] = { - 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,0x0008,0x0009,0x000a,0x000b,0x000c,0x000d,0x000e,0x000f, - 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,0x0018,0x0019,0x001a,0x001b,0x001c,0x001d,0x001e,0x001f, - 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,0x002f, - 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,0x003f, - 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,0x004f, - 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,0x005f, - 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,0x006f, - 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,0x007f, -// the rest of these should be rendered in italics - 0x00e0,0x00e8,0x00f9,0x00f2,0x00ec,0x00b0,0x00a3,0x00a1,0x00bf,0x00d1,0x00f1,0x00a4,0x20a7,0x00c5,0x00e5,0x00e7, // TODO: 0x00b0 may be 0x00ba? Also 0x20a7 is annother abbreviation (Pts) instead of the Pt from epson. - 0x00a7,0x00df,0x00c6,0x00e6,0x00d8,0x00f8,0x00a8,0x00c4,0x00d6,0x00dc,0x00e4,0x00f6,0x00fc,0x00c9,0x00e9,0x00a5, - 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,0x002f, - 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,0x003f, - 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,0x004f, - 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,0x005f, - 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,0x006f, - 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,0x0030, // 0xff should be the slashed zero in italics? some fonts have that in codepoint 0xe00f + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, + 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, + 0x001e, 0x001f, 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, + 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, + 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, + 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, + 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, + 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + // the rest of these should be rendered in italics + 0x00e0, 0x00e8, 0x00f9, 0x00f2, 0x00ec, 0x00b0, 0x00a3, 0x00a1, 0x00bf, 0x00d1, 0x00f1, 0x00a4, 0x20a7, 0x00c5, 0x00e5, + 0x00e7, // TODO: 0x00b0 may be 0x00ba? Also 0x20a7 is annother abbreviation (Pts) instead of the Pt from epson. + 0x00a7, 0x00df, 0x00c6, 0x00e6, 0x00d8, 0x00f8, 0x00a8, 0x00c4, 0x00d6, 0x00dc, 0x00e4, 0x00f6, 0x00fc, 0x00c9, 0x00e9, + 0x00a5, 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, + 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, + 0x003d, 0x003e, 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, + 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, + 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, + 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, + 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, + 0x0030, // 0xff should be the slashed zero in italics? some fonts have that in codepoint 0xe00f }; static const uint16_t cp437Map[256] = { - 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,0x0008,0x0009,0x000a,0x000b,0x000c,0x000d,0x000e,0x000f, - 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,0x0018,0x0019,0x001a,0x001b,0x001c,0x001d,0x001e,0x001f, // TODO: 0x0015 should be 0x00a7 in some revisions of the LX-810? - 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,0x002f, - 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,0x003f, - 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,0x004f, - 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,0x005f, - 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,0x006f, - 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,0x007f, - 0x00c7,0x00fc,0x00e9,0x00e2,0x00e4,0x00e0,0x00e5,0x00e7,0x00ea,0x00eb,0x00e8,0x00ef,0x00ee,0x00ec,0x00c4,0x00c5, - 0x00c9,0x00e6,0x00c6,0x00f4,0x00f6,0x00f2,0x00fb,0x00f9,0x00ff,0x00d6,0x00dc,0x00a2,0x00a3,0x00a5,0x20a7,0x0192, - 0x00e1,0x00ed,0x00f3,0x00fa,0x00f1,0x00d1,0x00aa,0x00ba,0x00bf,0x2310,0x00ac,0x00bd,0x00bc,0x00a1,0x00ab,0x00bb, - 0x2591,0x2592,0x2593,0x2502,0x2524,0x2561,0x2562,0x2556,0x2555,0x2563,0x2551,0x2557,0x255d,0x255c,0x255b,0x2510, - 0x2514,0x2534,0x252c,0x251c,0x2500,0x253c,0x255e,0x255f,0x255a,0x2554,0x2569,0x2566,0x2560,0x2550,0x256c,0x2567, - 0x2568,0x2564,0x2565,0x2559,0x2558,0x2552,0x2553,0x256b,0x256a,0x2518,0x250c,0x2588,0x2584,0x258c,0x2590,0x2580, - 0x03b1,0x00df,0x0393,0x03c0,0x03a3,0x03c3,0x00b5,0x03c4,0x03a6,0x0398,0x03a9,0x03b4,0x221e,0x03c6,0x03b5,0x2229, - 0x2261,0x00b1,0x2265,0x2264,0x2320,0x2321,0x00f7,0x2248,0x00b0,0x2219,0x00b7,0x221a,0x207f,0x00b2,0x25a0,0x00a0 -}; + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, + 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, + 0x001e, 0x001f, // TODO: 0x0015 should be 0x00a7 in some revisions of the LX-810? + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, + 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, + 0x003e, 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, + 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, + 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, + 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, + 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7, 0x00ea, + 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5, 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9, + 0x00ff, 0x00d6, 0x00dc, 0x00a2, 0x00a3, 0x00a5, 0x20a7, 0x0192, 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, + 0x00ba, 0x00bf, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, + 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, + 0x253c, 0x255e, 0x255f, 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, 0x2568, 0x2564, 0x2565, 0x2559, + 0x2558, 0x2552, 0x2553, 0x256b, 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, 0x03b1, 0x00df, 0x0393, + 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4, 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x03c6, 0x03b5, 0x2229, 0x2261, 0x00b1, + 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, 0x00b0, 0x2219, 0x00b7, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0}; static const uint16_t cp850Map[256] = { - 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,0x0008,0x0009,0x000a,0x000b,0x000c,0x000d,0x000e,0x000f, - 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,0x0018,0x0019,0x001a,0x001b,0x001c,0x001d,0x001e,0x001f, - 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,0x002f, - 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,0x003f, - 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,0x004f, - 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,0x005f, - 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,0x006f, - 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,0x007f, - 0x00c7,0x00fc,0x00e9,0x00e2,0x00e4,0x00e0,0x00e5,0x00e7,0x00ea,0x00eb,0x00e8,0x00ef,0x00ee,0x00ec,0x00c4,0x00c5, - 0x00c9,0x00e6,0x00c6,0x00f4,0x00f6,0x00f2,0x00fb,0x00f9,0x00ff,0x00d6,0x00dc,0x00f8,0x00a3,0x00d8,0x00d7,0x0192, - 0x00e1,0x00ed,0x00f3,0x00fa,0x00f1,0x00d1,0x00aa,0x00ba,0x00bf,0x00ae,0x00ac,0x00bd,0x00bc,0x00a1,0x00ab,0x00bb, - 0x2591,0x2592,0x2593,0x2502,0x2524,0x00c1,0x00c2,0x00c0,0x00a9,0x2563,0x2551,0x2557,0x255d,0x00a2,0x00a5,0x2510, - 0x2514,0x2534,0x252c,0x251c,0x2500,0x253c,0x00e3,0x00c3,0x255a,0x2554,0x2569,0x2566,0x2560,0x2550,0x256c,0x00a4, - 0x00f0,0x00d0,0x00ca,0x00cb,0x00c8,0x0131,0x00cd,0x00ce,0x00cf,0x2518,0x250c,0x2588,0x2584,0x00a6,0x00cc,0x2580, - 0x00d3,0x00df,0x00d4,0x00d2,0x00f5,0x00d5,0x00b5,0x00fe,0x00de,0x00da,0x00db,0x00d9,0x00fd,0x00dd,0x00af,0x00b4, - 0x00ad,0x00b1,0x2017,0x00be,0x00b6,0x00a7,0x00f7,0x00b8,0x00b0,0x00a8,0x00b7,0x00b9,0x00b3,0x00b2,0x25a0,0x00a0 -}; + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, + 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, + 0x001e, 0x001f, 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, + 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, + 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, + 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, + 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, + 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, + 0x00e7, 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5, 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, + 0x00fb, 0x00f9, 0x00ff, 0x00d6, 0x00dc, 0x00f8, 0x00a3, 0x00d8, 0x00d7, 0x0192, 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, + 0x00d1, 0x00aa, 0x00ba, 0x00bf, 0x00ae, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, 0x2591, 0x2592, 0x2593, 0x2502, + 0x2524, 0x00c1, 0x00c2, 0x00c0, 0x00a9, 0x2563, 0x2551, 0x2557, 0x255d, 0x00a2, 0x00a5, 0x2510, 0x2514, 0x2534, 0x252c, + 0x251c, 0x2500, 0x253c, 0x00e3, 0x00c3, 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x00a4, 0x00f0, 0x00d0, + 0x00ca, 0x00cb, 0x00c8, 0x0131, 0x00cd, 0x00ce, 0x00cf, 0x2518, 0x250c, 0x2588, 0x2584, 0x00a6, 0x00cc, 0x2580, 0x00d3, + 0x00df, 0x00d4, 0x00d2, 0x00f5, 0x00d5, 0x00b5, 0x00fe, 0x00de, 0x00da, 0x00db, 0x00d9, 0x00fd, 0x00dd, 0x00af, 0x00b4, + 0x00ad, 0x00b1, 0x2017, 0x00be, 0x00b6, 0x00a7, 0x00f7, 0x00b8, 0x00b0, 0x00a8, 0x00b7, 0x00b9, 0x00b3, 0x00b2, 0x25a0, + 0x00a0}; static const uint16_t cp860Map[256] = { - 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,0x0008,0x0009,0x000a,0x000b,0x000c,0x000d,0x000e,0x000f, - 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,0x0018,0x0019,0x001a,0x001b,0x001c,0x001d,0x001e,0x001f, - 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,0x002f, - 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,0x003f, - 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,0x004f, - 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,0x005f, - 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,0x006f, - 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,0x007f, - 0x00c7,0x00fc,0x00e9,0x00e2,0x00e3,0x00e0,0x00c1,0x00e7,0x00ea,0x00ca,0x00e8,0x00cd,0x00d4,0x00ec,0x00c3,0x00c2, - 0x00c9,0x00c0,0x00c8,0x00f4,0x00f5,0x00f2,0x00da,0x00f9,0x00cc,0x00d5,0x00dc,0x00a2,0x00a3,0x00d9,0x20a7,0x00d3, - 0x00e1,0x00ed,0x00f3,0x00fa,0x00f1,0x00d1,0x00aa,0x00ba,0x00bf,0x00d2,0x00ac,0x00bd,0x00bc,0x00a1,0x00ab,0x00bb, - 0x2591,0x2592,0x2593,0x2502,0x2524,0x2561,0x2562,0x2556,0x2555,0x2563,0x2551,0x2557,0x255d,0x255c,0x255b,0x2510, - 0x2514,0x2534,0x252c,0x251c,0x2500,0x253c,0x255e,0x255f,0x255a,0x2554,0x2569,0x2566,0x2560,0x2550,0x256c,0x2567, - 0x2568,0x2564,0x2565,0x2559,0x2558,0x2552,0x2553,0x256b,0x256a,0x2518,0x250c,0x2588,0x2584,0x258c,0x2590,0x2580, - 0x03b1,0x00df,0x0393,0x03c0,0x03a3,0x03c3,0x00b5,0x03c4,0x03a6,0x0398,0x03a9,0x03b4,0x221e,0x03c6,0x03b5,0x2229, - 0x2261,0x00b1,0x2265,0x2264,0x2320,0x2321,0x00f7,0x2248,0x00b0,0x2219,0x00b7,0x221a,0x207f,0x00b2,0x25a0,0x00a0 -}; + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, + 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, + 0x001e, 0x001f, 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, + 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, + 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, + 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, + 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, + 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e3, 0x00e0, 0x00c1, + 0x00e7, 0x00ea, 0x00ca, 0x00e8, 0x00cd, 0x00d4, 0x00ec, 0x00c3, 0x00c2, 0x00c9, 0x00c0, 0x00c8, 0x00f4, 0x00f5, 0x00f2, + 0x00da, 0x00f9, 0x00cc, 0x00d5, 0x00dc, 0x00a2, 0x00a3, 0x00d9, 0x20a7, 0x00d3, 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, + 0x00d1, 0x00aa, 0x00ba, 0x00bf, 0x00d2, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, 0x2591, 0x2592, 0x2593, 0x2502, + 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, 0x2514, 0x2534, 0x252c, + 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, 0x2568, 0x2564, + 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, 0x03b1, + 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4, 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x03c6, 0x03b5, 0x2229, + 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, 0x00b0, 0x2219, 0x00b7, 0x221a, 0x207f, 0x00b2, 0x25a0, + 0x00a0}; static const uint16_t cp863Map[256] = { - 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,0x0008,0x0009,0x000a,0x000b,0x000c,0x000d,0x000e,0x000f, - 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,0x0018,0x0019,0x001a,0x001b,0x001c,0x001d,0x001e,0x001f, - 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,0x002f, - 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,0x003f, - 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,0x004f, - 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,0x005f, - 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,0x006f, - 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,0x007f, - 0x00c7,0x00fc,0x00e9,0x00e2,0x00c2,0x00e0,0x00b6,0x00e7,0x00ea,0x00eb,0x00e8,0x00ef,0x00ee,0x2017,0x00c0,0x00a7, - 0x00c9,0x00c8,0x00ca,0x00f4,0x00cb,0x00cf,0x00fb,0x00f9,0x00a4,0x00d4,0x00dc,0x00a2,0x00a3,0x00d9,0x00db,0x0192, - 0x00a6,0x00b4,0x00f3,0x00fa,0x00a8,0x00b8,0x00b3,0x00af,0x00ce,0x2310,0x00ac,0x00bd,0x00bc,0x00be,0x00ab,0x00bb, - 0x2591,0x2592,0x2593,0x2502,0x2524,0x2561,0x2562,0x2556,0x2555,0x2563,0x2551,0x2557,0x255d,0x255c,0x255b,0x2510, - 0x2514,0x2534,0x252c,0x251c,0x2500,0x253c,0x255e,0x255f,0x255a,0x2554,0x2569,0x2566,0x2560,0x2550,0x256c,0x2567, - 0x2568,0x2564,0x2565,0x2559,0x2558,0x2552,0x2553,0x256b,0x256a,0x2518,0x250c,0x2588,0x2584,0x258c,0x2590,0x2580, - 0x03b1,0x00df,0x0393,0x03c0,0x03a3,0x03c3,0x00b5,0x03c4,0x03a6,0x0398,0x03a9,0x03b4,0x221e,0x03c6,0x03b5,0x2229, - 0x2261,0x00b1,0x2265,0x2264,0x2320,0x2321,0x00f7,0x2248,0x00b0,0x2219,0x00b7,0x221a,0x207f,0x00b2,0x25a0,0x00a0 -}; + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, + 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, + 0x001e, 0x001f, 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, + 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, + 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, + 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, + 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, + 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00c2, 0x00e0, 0x00b6, + 0x00e7, 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x2017, 0x00c0, 0x00a7, 0x00c9, 0x00c8, 0x00ca, 0x00f4, 0x00cb, 0x00cf, + 0x00fb, 0x00f9, 0x00a4, 0x00d4, 0x00dc, 0x00a2, 0x00a3, 0x00d9, 0x00db, 0x0192, 0x00a6, 0x00b4, 0x00f3, 0x00fa, 0x00a8, + 0x00b8, 0x00b3, 0x00af, 0x00ce, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00be, 0x00ab, 0x00bb, 0x2591, 0x2592, 0x2593, 0x2502, + 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, 0x2514, 0x2534, 0x252c, + 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, 0x2568, 0x2564, + 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, 0x03b1, + 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4, 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x03c6, 0x03b5, 0x2229, + 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, 0x00b0, 0x2219, 0x00b7, 0x221a, 0x207f, 0x00b2, 0x25a0, + 0x00a0}; static const uint16_t cp865Map[256] = { - 0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006,0x0007,0x0008,0x0009,0x000a,0x000b,0x000c,0x000d,0x000e,0x000f, - 0x0010,0x0011,0x0012,0x0013,0x0014,0x0015,0x0016,0x0017,0x0018,0x0019,0x001a,0x001b,0x001c,0x001d,0x001e,0x001f, - 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027,0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,0x002f, - 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037,0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,0x003f, - 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047,0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,0x004f, - 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057,0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,0x005f, - 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067,0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,0x006f, - 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077,0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,0x007f, - 0x00c7,0x00fc,0x00e9,0x00e2,0x00e4,0x00e0,0x00e5,0x00e7,0x00ea,0x00eb,0x00e8,0x00ef,0x00ee,0x00ec,0x00c4,0x00c5, - 0x00c9,0x00e6,0x00c6,0x00f4,0x00f6,0x00f2,0x00fb,0x00f9,0x00ff,0x00d6,0x00dc,0x00f8,0x00a3,0x00d8,0x20a7,0x0192, - 0x00e1,0x00ed,0x00f3,0x00fa,0x00f1,0x00d1,0x00aa,0x00ba,0x00bf,0x2310,0x00ac,0x00bd,0x00bc,0x00a1,0x00ab,0x00a4, - 0x2591,0x2592,0x2593,0x2502,0x2524,0x2561,0x2562,0x2556,0x2555,0x2563,0x2551,0x2557,0x255d,0x255c,0x255b,0x2510, - 0x2514,0x2534,0x252c,0x251c,0x2500,0x253c,0x255e,0x255f,0x255a,0x2554,0x2569,0x2566,0x2560,0x2550,0x256c,0x2567, - 0x2568,0x2564,0x2565,0x2559,0x2558,0x2552,0x2553,0x256b,0x256a,0x2518,0x250c,0x2588,0x2584,0x258c,0x2590,0x2580, - 0x03b1,0x00df,0x0393,0x03c0,0x03a3,0x03c3,0x00b5,0x03c4,0x03a6,0x0398,0x03a9,0x03b4,0x221e,0x03c6,0x03b5,0x2229, - 0x2261,0x00b1,0x2265,0x2264,0x2320,0x2321,0x00f7,0x2248,0x00b0,0x2219,0x00b7,0x221a,0x207f,0x00b2,0x25a0,0x00a0 + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, + 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, + 0x001e, 0x001f, 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, + 0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, + 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, + 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, + 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, + 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, + 0x00e7, 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5, 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, + 0x00fb, 0x00f9, 0x00ff, 0x00d6, 0x00dc, 0x00f8, 0x00a3, 0x00d8, 0x20a7, 0x0192, 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, + 0x00d1, 0x00aa, 0x00ba, 0x00bf, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00a4, 0x2591, 0x2592, 0x2593, 0x2502, + 0x2524, 0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, 0x2514, 0x2534, 0x252c, + 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, 0x2568, 0x2564, + 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, 0x03b1, + 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4, 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x03c6, 0x03b5, 0x2229, + 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, 0x00b0, 0x2219, 0x00b7, 0x221a, 0x207f, 0x00b2, 0x25a0, + 0x00a0}; + +static const uint16_t intCharSets[13][12] = { + {0x0023, 0x0024, 0x0040, 0x005b, 0x005c, 0x005d, 0x005e, 0x0060, 0x007b, 0x007c, 0x007d, 0x007e}, // USA + {0x0023, 0x0024, 0x00e0, 0x00b0, 0x00e7, 0x00a7, 0x005e, 0x0060, 0x00e9, 0x00f9, 0x00e8, + 0x00a8}, // France TODO: 0x00b0 may be 0x00ba? + {0x0023, 0x0024, 0x00a7, 0x00c4, 0x00d6, 0x00dc, 0x005e, 0x0060, 0x00e4, 0x00f6, 0x00fc, 0x00df}, // Germany + {0x00a3, 0x0024, 0x0040, 0x005b, 0x005c, 0x005d, 0x005e, 0x0060, 0x007b, 0x007c, 0x007d, 0x007e}, // UK + {0x0023, 0x0024, 0x0040, 0x00c6, 0x00d8, 0x00c5, 0x005e, 0x0060, 0x00e6, 0x00f8, 0x00e5, 0x007e}, // Denmark I + {0x0023, 0x00a4, 0x00c9, 0x00c4, 0x00d6, 0x00c5, 0x00dc, 0x00e9, 0x00e4, 0x00f6, 0x00e5, 0x00fc}, // Sweden + {0x0023, 0x0024, 0x0040, 0x00b0, 0x005c, 0x00e9, 0x005e, 0x00f9, 0x00e0, 0x00f2, 0x00e8, + 0x00ec}, // Italy TODO: 0x00b0 may be 0x00ba? + {0x20a7, 0x0024, 0x0040, 0x00a1, 0x00d1, 0x00bf, 0x005e, 0x0060, 0x00a8, 0x00f1, 0x007d, + 0x007e}, // Spain I TODO: 0x20a7 is annother abbreviation (Pts) instead of the Pt from epson. + {0x0023, 0x0024, 0x0040, 0x005b, 0x00a5, 0x005d, 0x005e, 0x0060, 0x007b, 0x007c, 0x007d, 0x007e}, // Japan + {0x0023, 0x00a4, 0x00c9, 0x00c6, 0x00d8, 0x00c5, 0x00dc, 0x00e9, 0x00e6, 0x00f8, 0x00e5, 0x00fc}, // Norway + {0x0023, 0x0024, 0x00c9, 0x00c6, 0x00d8, 0x00c5, 0x00dc, 0x00e9, 0x00e6, 0x00f8, 0x00e5, 0x00fc}, // Denmark II + {0x0023, 0x0024, 0x00e1, 0x00a1, 0x00d1, 0x00bf, 0x00e9, 0x0060, 0x00ed, 0x00f1, 0x00f3, 0x00fa}, // Spain II + {0x0023, 0x0024, 0x00e1, 0x00a1, 0x00d1, 0x00bf, 0x00e9, 0x00fc, 0x00ed, 0x00f1, 0x00f3, 0x00fa}, // Latin America }; -static const uint16_t intCharSets[13][12] = - { - {0x0023, 0x0024, 0x0040, 0x005b, 0x005c, 0x005d, 0x005e, 0x0060, 0x007b, 0x007c, 0x007d, 0x007e}, // USA - {0x0023, 0x0024, 0x00e0, 0x00b0, 0x00e7, 0x00a7, 0x005e, 0x0060, 0x00e9, 0x00f9, 0x00e8, 0x00a8}, // France TODO: 0x00b0 may be 0x00ba? - {0x0023, 0x0024, 0x00a7, 0x00c4, 0x00d6, 0x00dc, 0x005e, 0x0060, 0x00e4, 0x00f6, 0x00fc, 0x00df}, // Germany - {0x00a3, 0x0024, 0x0040, 0x005b, 0x005c, 0x005d, 0x005e, 0x0060, 0x007b, 0x007c, 0x007d, 0x007e}, // UK - {0x0023, 0x0024, 0x0040, 0x00c6, 0x00d8, 0x00c5, 0x005e, 0x0060, 0x00e6, 0x00f8, 0x00e5, 0x007e}, // Denmark I - {0x0023, 0x00a4, 0x00c9, 0x00c4, 0x00d6, 0x00c5, 0x00dc, 0x00e9, 0x00e4, 0x00f6, 0x00e5, 0x00fc}, // Sweden - {0x0023, 0x0024, 0x0040, 0x00b0, 0x005c, 0x00e9, 0x005e, 0x00f9, 0x00e0, 0x00f2, 0x00e8, 0x00ec}, // Italy TODO: 0x00b0 may be 0x00ba? - {0x20a7, 0x0024, 0x0040, 0x00a1, 0x00d1, 0x00bf, 0x005e, 0x0060, 0x00a8, 0x00f1, 0x007d, 0x007e}, // Spain I TODO: 0x20a7 is annother abbreviation (Pts) instead of the Pt from epson. - {0x0023, 0x0024, 0x0040, 0x005b, 0x00a5, 0x005d, 0x005e, 0x0060, 0x007b, 0x007c, 0x007d, 0x007e}, // Japan - {0x0023, 0x00a4, 0x00c9, 0x00c6, 0x00d8, 0x00c5, 0x00dc, 0x00e9, 0x00e6, 0x00f8, 0x00e5, 0x00fc}, // Norway - {0x0023, 0x0024, 0x00c9, 0x00c6, 0x00d8, 0x00c5, 0x00dc, 0x00e9, 0x00e6, 0x00f8, 0x00e5, 0x00fc}, // Denmark II - {0x0023, 0x0024, 0x00e1, 0x00a1, 0x00d1, 0x00bf, 0x00e9, 0x0060, 0x00ed, 0x00f1, 0x00f3, 0x00fa}, // Spain II - {0x0023, 0x0024, 0x00e1, 0x00a1, 0x00d1, 0x00bf, 0x00e9, 0x00fc, 0x00ed, 0x00f1, 0x00f3, 0x00fa}, // Latin America - }; - -void resetPrinterHard(lpt_epsonprinter_t *printer) -{ +void resetPrinterHard(lpt_epsonprinter_t *printer) { printer->charRead = false; resetPrinter(printer, false); } // TODO: see exaclty what is reset with ESC @ -void resetPrinter(lpt_epsonprinter_t *printer, int software_command) -{ - if (!software_command) - { +void resetPrinter(lpt_epsonprinter_t *printer, int software_command) { + if (!software_command) { printer->curX = printer->curY = 0.0; printer->ESCSeen = false; printer->ESCCmd = 0; printer->numParam = printer->neededParam = 0; - // TODO: PRINTABLE AREAS ARE BEING IGNORED! Ok because we "may" print to real paper and then use the areas in the real one? Have two options: 1) Have printable areas 2) Reduce the paper width accordingly. + // TODO: PRINTABLE AREAS ARE BEING IGNORED! Ok because we "may" print to real paper and then use the areas in the + // real one? Have two options: 1) Have printable areas 2) Reduce the paper width accordingly. } printer->topMargin = 0.0; printer->leftMargin = 0.0; printer->rightMargin = printer->pageWidth = printer->defaultPageWidth; printer->bottomMargin = printer->pageHeight = printer->defaultPageHeight; - printer->lineSpacing = (double)1/6; + printer->lineSpacing = (double)1 / 6; printer->cpi = printer->defaultCPI; printer->curCharTable = printer->defaultCharTable; printer->curI18NCharset = printer->defaultI18NCharset; @@ -500,7 +506,7 @@ void resetPrinter(lpt_epsonprinter_t *printer, int software_command) newPage(false, printer); // Default tabs => Each eight characters - for (unsigned int i=0;i<32;i++) + for (unsigned int i = 0; i < 32; i++) printer->horiztabs[i] = i * 8 * (1 / (double)printer->cpi); printer->numHorizTabs = 32; @@ -509,34 +515,32 @@ void resetPrinter(lpt_epsonprinter_t *printer, int software_command) printer->last_data = 0; } -void updateCharset(lpt_epsonprinter_t *printer) -{ +void updateCharset(lpt_epsonprinter_t *printer) { uint16_t *mapToUse = NULL; uint16_t cp = printer->charTables[printer->curCharTable]; - switch(cp) - { - case 0: - mapToUse = (uint16_t*)&italicsMap; - break; - case 437: - mapToUse = (uint16_t*)&cp437Map; - break; - case 850: - mapToUse = (uint16_t*)&cp850Map; - break; - case 860: - mapToUse = (uint16_t*)&cp860Map; - break; - case 863: - mapToUse = (uint16_t*)&cp863Map; - break; - case 865: - mapToUse = (uint16_t*)&cp865Map; - break; - default: - pclog("Unsupported codepage %i. Using CP437 instead.\n", cp); - mapToUse = (uint16_t*)&cp437Map; + switch (cp) { + case 0: + mapToUse = (uint16_t *)&italicsMap; + break; + case 437: + mapToUse = (uint16_t *)&cp437Map; + break; + case 850: + mapToUse = (uint16_t *)&cp850Map; + break; + case 860: + mapToUse = (uint16_t *)&cp860Map; + break; + case 863: + mapToUse = (uint16_t *)&cp863Map; + break; + case 865: + mapToUse = (uint16_t *)&cp865Map; + break; + default: + pclog("Unsupported codepage %i. Using CP437 instead.\n", cp); + mapToUse = (uint16_t *)&cp437Map; } for (int i = 0; i < 256; i++) @@ -559,39 +563,35 @@ void updateCharset(lpt_epsonprinter_t *printer) // TODO: all these fonts are approximations! Even the FX one is not exactly equal to the LX-810 and it is 7-bit ascii only. // TODO: maybe we are calling this unnecessarily (some parameters only affect drawing) -void updateFont(lpt_epsonprinter_t *printer) -{ +void updateFont(lpt_epsonprinter_t *printer) { if (printer->curFont != NULL) FT_Done_Face(printer->curFont); - if (printer->printQuality == QUALITY_NLQ) - { + if (printer->printQuality == QUALITY_NLQ) { const char *fontName; - switch (printer->NLQtypeFace) - { - case roman: - if (printer->style & STYLE_ITALICS) - fontName = "roman_italics.ttf"; - else - fontName = "roman.ttf"; - break; - case sansserif: - if (printer->style & STYLE_ITALICS) - fontName = "sansserif_italics.ttf"; - else - fontName = "sansserif.ttf"; - break; - default: - fatal("Unknown font: %d\n", printer->NLQtypeFace); + switch (printer->NLQtypeFace) { + case roman: + if (printer->style & STYLE_ITALICS) + fontName = "roman_italics.ttf"; + else + fontName = "roman.ttf"; + break; + case sansserif: + if (printer->style & STYLE_ITALICS) + fontName = "sansserif_italics.ttf"; + else + fontName = "sansserif.ttf"; + break; + default: + fatal("Unknown font: %d\n", printer->NLQtypeFace); } char fullpath[MAX_PATH_STRING]; strlcpy(fullpath, printer->fontpath, MAX_PATH_STRING); strlcat(fullpath, fontName, MAX_PATH_STRING); - if (FT_New_Face(printer->FTlib, fullpath, 0, &printer->curFont)) - { + if (FT_New_Face(printer->FTlib, fullpath, 0, &printer->curFont)) { fatal("Unable to load font %s\n", fullpath); printer->curFont = NULL; } @@ -602,64 +602,57 @@ void updateFont(lpt_epsonprinter_t *printer) printer->actcpi = printer->cpi; // TODO: condensed only for draft fonts? - if (printer->cpi != 10 && !(printer->style & STYLE_CONDENSED)) - { + if (printer->cpi != 10 && !(printer->style & STYLE_CONDENSED)) { horizPoints *= (double)10 / (double)printer->cpi; - //vertPoints *= (double)10 / (double)printer->cpi; + // vertPoints *= (double)10 / (double)printer->cpi; } - if (printer->cpi == 10 && (printer->style & STYLE_CONDENSED)) - { + if (printer->cpi == 10 && (printer->style & STYLE_CONDENSED)) { // TODO: 17.125, 17.16 or 17.14? printer->actcpi = 17.125; horizPoints *= (double)10 / (double)17.125; - //vertPoints *= (double)10 / (double)17.125; + // vertPoints *= (double)10 / (double)17.125; } - if (printer->cpi == 12 && (printer->style & STYLE_CONDENSED)) - { + if (printer->cpi == 12 && (printer->style & STYLE_CONDENSED)) { printer->actcpi = 20.0; horizPoints *= (double)10 / (double)20.0; - //vertPoints *= (double)10 / (double)20.0; + // vertPoints *= (double)10 / (double)20.0; } - if ((printer->style & STYLE_DOUBLEWIDTH) || (printer->style & STYLE_DOUBLEWIDTHONELINE)) - { + if ((printer->style & STYLE_DOUBLEWIDTH) || (printer->style & STYLE_DOUBLEWIDTHONELINE)) { printer->actcpi /= 2; horizPoints *= (double)2.0; } - if ((printer->style & STYLE_SUPERSCRIPT) || (printer->style & STYLE_SUBSCRIPT)) - { + if ((printer->style & STYLE_SUPERSCRIPT) || (printer->style & STYLE_SUBSCRIPT)) { // TODO: aparently the horizontal size is the same? - //horizPoints *= (double)2 / (double)3; + // horizPoints *= (double)2 / (double)3; vertPoints *= (double)2 / (double)3; - //actcpi /= (double)2 / (double)3; + // actcpi /= (double)2 / (double)3; } /* TODO: emphasized and double-strike also change width? maybe not */ - FT_Set_Char_Size(printer->curFont, (uint16_t)horizPoints * FREETYPE_FONT_MULTIPLIER, (uint16_t)vertPoints * FREETYPE_FONT_MULTIPLIER, printer->dpi, printer->dpi); - } - else if (printer->printQuality == QUALITY_DRAFT) // TODO: high-speed draft + FT_Set_Char_Size(printer->curFont, (uint16_t)horizPoints * FREETYPE_FONT_MULTIPLIER, + (uint16_t)vertPoints * FREETYPE_FONT_MULTIPLIER, printer->dpi, printer->dpi); + } else if (printer->printQuality == QUALITY_DRAFT) // TODO: high-speed draft { const char *fontName_Base; - // TODO: these fonts are ALL incomplete! Need one with all codepages and all 13 international characters for each. Can I dump this from my LX-810 and do something? + // TODO: these fonts are ALL incomplete! Need one with all codepages and all 13 international characters for each. + // Can I dump this from my LX-810 and do something? if (printer->charTables[printer->curCharTable] == 0) fontName_Base = "FXMatrix105Mono"; else fontName_Base = "FXMatrix105Mono"; const char *fontName_cpi; - if (!(printer->style & STYLE_CONDENSED)) - { + if (!(printer->style & STYLE_CONDENSED)) { if (printer->cpi == 10) fontName_cpi = "Pica"; else if (printer->cpi == 12) fontName_cpi = "Elite"; - } - else - { + } else { if (printer->cpi == 10) fontName_cpi = "Compr"; else if (printer->cpi == 12) @@ -693,14 +686,12 @@ void updateFont(lpt_epsonprinter_t *printer) fontName_subsup = ""; const char *fontName_itemph; - if (printer->style & STYLE_ITALICS) - { + if (printer->style & STYLE_ITALICS) { if (printer->style & STYLE_BOLD) fontName_itemph = "BoldItalic"; else fontName_itemph = "Italic"; - } - else if (printer->style & STYLE_BOLD) + } else if (printer->style & STYLE_BOLD) fontName_itemph = "Bold"; else fontName_itemph = "Regular"; @@ -710,39 +701,36 @@ void updateFont(lpt_epsonprinter_t *printer) printer->actcpi = printer->cpi; - if (printer->cpi != 10 && !(printer->style & STYLE_CONDENSED)) - { + if (printer->cpi != 10 && !(printer->style & STYLE_CONDENSED)) { horizPoints *= (double)10 / (double)printer->cpi; - //vertPoints *= (double)10/ ( double)printer->cpi; + // vertPoints *= (double)10/ ( double)printer->cpi; } - if (printer->cpi == 10 && (printer->style & STYLE_CONDENSED)) - { + if (printer->cpi == 10 && (printer->style & STYLE_CONDENSED)) { // TODO: 17.125, 17.16 or 17.14? printer->actcpi = 17.125; horizPoints *= (double)10 / (double)17.125; - //vertPoints *= (double)10 / (double)17.125; + // vertPoints *= (double)10 / (double)17.125; } - if (printer->cpi == 12 && (printer->style & STYLE_CONDENSED)) - { + if (printer->cpi == 12 && (printer->style & STYLE_CONDENSED)) { printer->actcpi = 20.0; horizPoints *= (double)10 / (double)20.0; - //vertPoints *= (double)10 / (double)20.0; + // vertPoints *= (double)10 / (double)20.0; } - if ((printer->style & STYLE_DOUBLEWIDTH) || (printer->style & STYLE_DOUBLEWIDTHONELINE)) - { + if ((printer->style & STYLE_DOUBLEWIDTH) || (printer->style & STYLE_DOUBLEWIDTHONELINE)) { printer->actcpi /= 2; -// horizPoints *= (double)2.0; // TODO: commenting this because of the font. See also where we adjusted cpi/points because the font already accounted for that in its sizes + // horizPoints *= (double)2.0; // TODO: commenting this because of the font. See + // also where we adjusted cpi/points because the font already accounted for that in + // its sizes } - if ((printer->style & STYLE_SUPERSCRIPT) || (printer->style & STYLE_SUBSCRIPT)) - { + if ((printer->style & STYLE_SUPERSCRIPT) || (printer->style & STYLE_SUBSCRIPT)) { // TODO: aparently the horizontal size is the same? - //horizPoints *= (double)2/(double)3; + // horizPoints *= (double)2/(double)3; vertPoints *= (double)2 / (double)3; - //printer->actcpi /= (double)2/(double)3; + // printer->actcpi /= (double)2/(double)3; } /* TODO: emphasized and double-strike also change width? maybe not */ @@ -759,8 +747,7 @@ void updateFont(lpt_epsonprinter_t *printer) strlcat(fullpath, fontName_itemph, MAX_PATH_STRING); strlcat(fullpath, ".otf", MAX_PATH_STRING); - if (FT_New_Face(printer->FTlib, fullpath, 0, &printer->curFont)) - { + if (FT_New_Face(printer->FTlib, fullpath, 0, &printer->curFont)) { pclog("Unable to load font %s, trying default\n", fullpath); strlcpy(fullpath, printer->fontpath, MAX_PATH_STRING); strlcat(fullpath, "fonts/", MAX_PATH_STRING); @@ -768,107 +755,104 @@ void updateFont(lpt_epsonprinter_t *printer) strlcat(fullpath, fontName_cpi, MAX_PATH_STRING); strlcat(fullpath, "Regular.otf", MAX_PATH_STRING); - if (FT_New_Face(printer->FTlib, fullpath, 0, &printer->curFont)) - { + if (FT_New_Face(printer->FTlib, fullpath, 0, &printer->curFont)) { fatal("Unable to load font %s\n", fullpath); printer->curFont = NULL; } } - FT_Set_Char_Size(printer->curFont, (uint16_t)horizPoints * FREETYPE_FONT_MULTIPLIER, (uint16_t)vertPoints * FREETYPE_FONT_MULTIPLIER, printer->dpi, printer->dpi); - } - else + FT_Set_Char_Size(printer->curFont, (uint16_t)horizPoints * FREETYPE_FONT_MULTIPLIER, + (uint16_t)vertPoints * FREETYPE_FONT_MULTIPLIER, printer->dpi, printer->dpi); + } else fatal("Unknown print quality: %d\n", printer->printQuality); } -bool processCommandChar(uint8_t ch, lpt_epsonprinter_t *printer) -{ - if (printer->ESCSeen) - { +bool processCommandChar(uint8_t ch, lpt_epsonprinter_t *printer) { + if (printer->ESCSeen) { printer->ESCCmd = ch; printer->ESCSeen = false; printer->numParam = 0; - switch (printer->ESCCmd) - { - case 0x02: // Undocumented - case 0x0e: // Select double-width printing (one line) (ESC SO) - case 0x0f: // Select condensed printing (ESC SI) - case 0x1b: // Load/Eject (effect: rewind page) THIS IS NOT AN EPSON COMMAND! (ESC ESC) - case 0x30: // Select 1/8-inch line spacing (ESC 0) - case 0x31: // Select 7/72-inch line spacing (ESC 1) - case 0x32: // Select 1/6-inch line spacing (ESC 2) - case 0x34: // Select italic font (ESC 4) - case 0x35: // Cancel italic font (ESC 5) - case 0x36: // Enable printing of upper control codes (ESC 6) - case 0x37: // Enable upper control codes (ESC 7) - case 0x38: // Disable paper out detection (ESC 8) - case 0x39: // Enable paper out detection (ESC 9) - case 0x3c: // Unidirectional mode (one line) (ESC <) - case 0x40: // Initialize printer (ESC @) - case 0x45: // Select bold font (ESC E) - case 0x46: // Cancel bold font (ESC F) - case 0x47: // Select double-strike printing (ESC G) - case 0x48: // Cancel double-strike printing (ESC H) - case 0x4d: // Select 10.5-point, 12-cpi (ESC M) - case 0x4f: // Cancel bottom margin - case 0x50: // Select 10.5-point, 10-cpi (ESC P) - case 0x54: // Cancel superscript/subscript printing (ESC T) - case 0x73: // Select low-speed mode (ESC s) - printer->neededParam = 0; - break; - case 0x19: // Control paper loading/ejecting (ESC EM) - case 0x21: // Master select (ESC !) - case 0x2d: // Turn underline on/off (ESC -) - case 0x2f: // Select vertical tab channel (ESC /) - case 0x33: // Set n/216-inch line spacing (ESC 3) - case 0x41: // Set n/72-inch line spacing - case 0x43: // Set page length in lines (ESC C) - case 0x49: // Enable printing of control codes (ESC I n) - case 0x4a: // Advance print position vertically (ESC J n) - case 0x4e: // Set bottom margin (ESC N) - case 0x51: // Set right margin (ESC Q) - case 0x52: // Select an international character set (ESC R) - case 0x53: // Select superscript/subscript printing (ESC S) - case 0x55: // Turn unidirectional mode on/off (ESC U) - case 0x57: // Turn double-width printing on/off (ESC W) - case 0x61: // Select justification (ESC a) - case 0x6b: // Select typeface (ESC k) - case 0x6c: // Set left margin (ESC 1) - case 0x70: // Turn proportional mode on/off (ESC p) - case 0x74: // Select character table (ESC t) - case 0x78: // Select NLQ or draft (ESC x) - printer->neededParam = 1; - break; - case 0x3f: // Reassign bit-image mode (ESC ?) - case 0x4b: // Select 60-dpi graphics (ESC K) - case 0x4c: // Select 120-dpi graphics (ESC L) - case 0x59: // Select 120-dpi, double-speed graphics (ESC Y) - case 0x5a: // Select 240-dpi graphics (ESC Z) - printer->neededParam = 2; - break; - case 0x2a: // Select bit image (ESC *) - printer->neededParam = 3; - break; - case 0x62: // Set vertical tabs in VFU channels (ESC b) - case 0x42: // Set vertical tabs (ESC B) - printer->numVertTabs = 0; - return true; - case 0x44: // Set horizontal tabs (ESC D) - printer->numHorizTabs = 0; - return true; - case 0x25: // Select user-defined set (ESC %) - case 0x26: // Define user-defined characters (ESC &) - case 0x3a: // Copy ROM to RAM (ESC :) - fatal("User-defined characters not supported!\n"); - return true; - case 0x28: // Two bytes sequence - return true; - default: - fatal("PRINTER: Unknown command ESC %c (%02X). Unable to skip parameters.\n", printer->ESCCmd, printer->ESCCmd); - printer->neededParam = 0; - printer->ESCCmd = 0; - return true; + switch (printer->ESCCmd) { + case 0x02: // Undocumented + case 0x0e: // Select double-width printing (one line) (ESC SO) + case 0x0f: // Select condensed printing (ESC SI) + case 0x1b: // Load/Eject (effect: rewind page) THIS IS NOT AN EPSON COMMAND! (ESC ESC) + case 0x30: // Select 1/8-inch line spacing (ESC 0) + case 0x31: // Select 7/72-inch line spacing (ESC 1) + case 0x32: // Select 1/6-inch line spacing (ESC 2) + case 0x34: // Select italic font (ESC 4) + case 0x35: // Cancel italic font (ESC 5) + case 0x36: // Enable printing of upper control codes (ESC 6) + case 0x37: // Enable upper control codes (ESC 7) + case 0x38: // Disable paper out detection (ESC 8) + case 0x39: // Enable paper out detection (ESC 9) + case 0x3c: // Unidirectional mode (one line) (ESC <) + case 0x40: // Initialize printer (ESC @) + case 0x45: // Select bold font (ESC E) + case 0x46: // Cancel bold font (ESC F) + case 0x47: // Select double-strike printing (ESC G) + case 0x48: // Cancel double-strike printing (ESC H) + case 0x4d: // Select 10.5-point, 12-cpi (ESC M) + case 0x4f: // Cancel bottom margin + case 0x50: // Select 10.5-point, 10-cpi (ESC P) + case 0x54: // Cancel superscript/subscript printing (ESC T) + case 0x73: // Select low-speed mode (ESC s) + printer->neededParam = 0; + break; + case 0x19: // Control paper loading/ejecting (ESC EM) + case 0x21: // Master select (ESC !) + case 0x2d: // Turn underline on/off (ESC -) + case 0x2f: // Select vertical tab channel (ESC /) + case 0x33: // Set n/216-inch line spacing (ESC 3) + case 0x41: // Set n/72-inch line spacing + case 0x43: // Set page length in lines (ESC C) + case 0x49: // Enable printing of control codes (ESC I n) + case 0x4a: // Advance print position vertically (ESC J n) + case 0x4e: // Set bottom margin (ESC N) + case 0x51: // Set right margin (ESC Q) + case 0x52: // Select an international character set (ESC R) + case 0x53: // Select superscript/subscript printing (ESC S) + case 0x55: // Turn unidirectional mode on/off (ESC U) + case 0x57: // Turn double-width printing on/off (ESC W) + case 0x61: // Select justification (ESC a) + case 0x6b: // Select typeface (ESC k) + case 0x6c: // Set left margin (ESC 1) + case 0x70: // Turn proportional mode on/off (ESC p) + case 0x74: // Select character table (ESC t) + case 0x78: // Select NLQ or draft (ESC x) + printer->neededParam = 1; + break; + case 0x3f: // Reassign bit-image mode (ESC ?) + case 0x4b: // Select 60-dpi graphics (ESC K) + case 0x4c: // Select 120-dpi graphics (ESC L) + case 0x59: // Select 120-dpi, double-speed graphics (ESC Y) + case 0x5a: // Select 240-dpi graphics (ESC Z) + printer->neededParam = 2; + break; + case 0x2a: // Select bit image (ESC *) + printer->neededParam = 3; + break; + case 0x62: // Set vertical tabs in VFU channels (ESC b) + case 0x42: // Set vertical tabs (ESC B) + printer->numVertTabs = 0; + return true; + case 0x44: // Set horizontal tabs (ESC D) + printer->numHorizTabs = 0; + return true; + case 0x25: // Select user-defined set (ESC %) + case 0x26: // Define user-defined characters (ESC &) + case 0x3a: // Copy ROM to RAM (ESC :) + fatal("User-defined characters not supported!\n"); + return true; + case 0x28: // Two bytes sequence + return true; + default: + fatal("PRINTER: Unknown command ESC %c (%02X). Unable to skip parameters.\n", printer->ESCCmd, + printer->ESCCmd); + printer->neededParam = 0; + printer->ESCCmd = 0; + return true; } if (printer->neededParam > 0) @@ -876,293 +860,293 @@ bool processCommandChar(uint8_t ch, lpt_epsonprinter_t *printer) } // Ignore VFU channel setting - if (printer->ESCCmd == 0x62) - { + if (printer->ESCCmd == 0x62) { // TODO: do not ignore this and ESC /? printer->ESCCmd = 0x42; return true; } // Collect vertical tabs - if (printer->ESCCmd == 0x42) - { - if (ch == 0 || (printer->numVertTabs > 0 && printer->verttabs[printer->numVertTabs - 1] > (double)ch * printer->lineSpacing)) // Done + if (printer->ESCCmd == 0x42) { + if (ch == 0 || (printer->numVertTabs > 0 && + printer->verttabs[printer->numVertTabs - 1] > (double)ch * printer->lineSpacing)) // Done printer->ESCCmd = 0; - else - if (printer->numVertTabs < 16) + else if (printer->numVertTabs < 16) printer->verttabs[printer->numVertTabs++] = (double)ch * printer->lineSpacing; } // Collect horizontal tabs - if (printer->ESCCmd == 0x44) - { - if (ch == 0 || (printer->numHorizTabs > 0 && printer->horiztabs[printer->numHorizTabs - 1] > (double)ch * (1/(double)printer->cpi))) // Done + if (printer->ESCCmd == 0x44) { + if (ch == 0 || (printer->numHorizTabs > 0 && + printer->horiztabs[printer->numHorizTabs - 1] > (double)ch * (1 / (double)printer->cpi))) // Done printer->ESCCmd = 0; - else - if (printer->numHorizTabs < 32) + else if (printer->numHorizTabs < 32) printer->horiztabs[printer->numHorizTabs++] = (double)ch * (1 / (double)printer->cpi); } - if (printer->numParam < printer->neededParam) - { + if (printer->numParam < printer->neededParam) { printer->params[printer->numParam++] = ch; if (printer->numParam < printer->neededParam) return true; } - if (printer->ESCCmd != 0) - { - switch (printer->ESCCmd) - { - case 0x02: // Undocumented - // Ignore - break; - case 0x0e: // Select double-width printing (one line) (ESC SO) - printer->style |= STYLE_DOUBLEWIDTHONELINE; + if (printer->ESCCmd != 0) { + switch (printer->ESCCmd) { + case 0x02: // Undocumented + // Ignore + break; + case 0x0e: // Select double-width printing (one line) (ESC SO) + printer->style |= STYLE_DOUBLEWIDTHONELINE; + updateFont(printer); + break; + case 0x0f: // Select condensed printing (ESC SI) + printer->style |= STYLE_CONDENSED; + updateFont(printer); + break; + case 0x19: // Control paper loading/ejecting (ESC EM) + // We are not really loading paper, so most commands can be ignored + if (printer->params[0] == 'R') + newPage(true, printer); + break; + case 0x1b: // Load/Eject (effect: rewind page) THIS IS NOT AN EPSON COMMAND! (ESC ESC) + // TODO: check if this is the true behaviour when having continuous paper. + if (printer->style & STYLE_DOUBLEWIDTHONELINE) { + printer->style &= 0xFFFF - STYLE_DOUBLEWIDTHONELINE; updateFont(printer); - break; - case 0x0f: // Select condensed printing (ESC SI) + } + printer->curX = printer->leftMargin; + printer->curY = printer->topMargin; + break; + case 0x21: // Master select (ESC !) + printer->cpi = printer->params[0] & 0x01 ? 12 : 10; + + // Reset first seven bits + printer->style &= 0xFF80; + if (printer->params[0] & 0x04) printer->style |= STYLE_CONDENSED; - updateFont(printer); - break; - case 0x19: // Control paper loading/ejecting (ESC EM) - // We are not really loading paper, so most commands can be ignored - if (printer->params[0] == 'R') - newPage(true, printer); - break; - case 0x1b: // Load/Eject (effect: rewind page) THIS IS NOT AN EPSON COMMAND! (ESC ESC) - // TODO: check if this is the true behaviour when having continuous paper. - if (printer->style & STYLE_DOUBLEWIDTHONELINE) - { - printer->style &= 0xFFFF - STYLE_DOUBLEWIDTHONELINE; - updateFont(printer); - } - printer->curX = printer->leftMargin; - printer->curY = printer->topMargin; - break; - case 0x21: // Master select (ESC !) - printer->cpi = printer->params[0] & 0x01 ? 12 : 10; - - // Reset first seven bits - printer->style &= 0xFF80; - if (printer->params[0] & 0x04) - printer->style |= STYLE_CONDENSED; - if (printer->params[0] & 0x08) - printer->style |= STYLE_BOLD; - if (printer->params[0] & 0x10) - printer->style |= STYLE_DOUBLESTRIKE; - if (printer->params[0] & 0x20) - printer->style |= STYLE_DOUBLEWIDTH; - if (printer->params[0] & 0x40) - printer->style |= STYLE_ITALICS; - if (printer->params[0] & 0x80) - printer->style |= STYLE_UNDERLINE; - - updateFont(printer); - break; - case 0x2a: // Select bit image (ESC *) - setupBitImage(printer->params[0], PARAM16(1), printer); - break; - case 0x2d: // Turn underline on/off (ESC -) - if (printer->params[0] == 0 || printer->params[0] == 48) - printer->style &= 0xFFFF - STYLE_UNDERLINE; - if (printer->params[0] == 1 || printer->params[0] == 49) - printer->style |= STYLE_UNDERLINE; - updateFont(printer); - break; - case 0x2f: // Select vertical tab channel (ESC /) - // Ignore - break; - case 0x30: // Select 1/8-inch line spacing (ESC 0) - printer->lineSpacing = (double)1 / 8; - break; - case 0x31: // Select 7/72-inch line spacing (ESC 1) - printer->lineSpacing = (double)7 / 72; - break; - case 0x32: // Select 1/6-inch line spacing (ESC 2) - printer->lineSpacing = (double)1 / 6; - break; - case 0x33: // Set n/216-inch line spacing (ESC 3) - printer->lineSpacing = (double)printer->params[0] / 216; - break; - case 0x34: // Select italic font (ESC 4) - printer->style |= STYLE_ITALICS; - updateFont(printer); - break; - case 0x35: // Cancel italic font (ESC 5) - printer->style &= 0xFFFF - STYLE_ITALICS; - updateFont(printer); - break; - case 0x36: // Enable printing of upper control codes (ESC 6) - printer->printUpperContr = true; - break; - case 0x37: // Enable upper control codes (ESC 7) - printer->printUpperContr = false; - break; - case 0x38: // Disable paper out detection (ESC 8) - // We have infinite paper, so just ignore this - break; - case 0x39: // Enable paper out detection (ESC 9) - // We have infinite paper, so just ignore this - break; - case 0x3c: // Unidirectional mode (one line) (ESC <) - // We don't have a print head, so just ignore this - break; - case 0x3f: // Reassign bit-image mode (ESC ?) - if (printer->params[0] == 75) - printer->densk = printer->params[1]; - if (printer->params[0] == 76) - printer->densl = printer->params[1]; - if (printer->params[0] == 89) // TODO: this option here is not present on the LX-810? (Even though the default mode for Y exists) - printer->densy = printer->params[1]; - if (printer->params[0] == 90) - printer->densz = printer->params[1]; - break; - case 0x40: // Initialize printer (ESC @) TODO: one more command that should clear the current line buffer - resetPrinter(printer, true); - break; - case 0x41: // Set n/72-inch line spacing - printer->lineSpacing = (double)printer->params[0] / 72; - break; - case 0x43: // Set page length in lines (ESC C) - if (printer->params[0] != 0) - printer->pageHeight = printer->bottomMargin = (double)printer->params[0] * printer->lineSpacing; // TODO: is this right? Also, we have ALREADY allocated the SDL surface! This can result in memory corruption - else // == 0 => Set page length in inches - { - printer->neededParam = 1; - printer->numParam = 0; - printer->ESCCmd = 0x100; - return true; - } - break; - case 0x45: // Select bold font (ESC E) + if (printer->params[0] & 0x08) printer->style |= STYLE_BOLD; - updateFont(printer); - break; - case 0x46: // Cancel bold font (ESC F) - printer->style &= 0xFFFF - STYLE_BOLD; - updateFont(printer); - break; - case 0x47: // Select dobule-strike printing (ESC G) + if (printer->params[0] & 0x10) printer->style |= STYLE_DOUBLESTRIKE; - updateFont(printer); - break; - case 0x48: // Cancel double-strike printing (ESC H) - printer->style &= 0xFFFF - STYLE_DOUBLESTRIKE; - updateFont(printer); - break; - case 0x49: // Enable printing of control codes (ESC I n) - // TODO: which program/driver did this? Is it undocumented but SHOULD WORK on the LX-810? - pclog("EPSON ESC I: printing of control codes not implemented on the LX-810!\n"); - break; - case 0x4a: // Advance print position vertically (ESC J n) - printer->curY += (double)((double)printer->params[0] / 216); // TODO: this command produces an immediate line feed without carriage return? - if (printer->curY > printer->bottomMargin) - newPage(true, printer); - break; - case 0x4b: // Select 60-dpi graphics (ESC K) - setupBitImage(printer->densk, PARAM16(0), printer); - break; - case 0x4c: // Select 120-dpi graphics (ESC L) - setupBitImage(printer->densl, PARAM16(0), printer); - break; - case 0x4d: // Select 10.5-point, 12-cpi (ESC M) - printer->cpi = 12; - updateFont(printer); - break; - case 0x4e: // Set bottom margin (ESC N) // TODO: does this work like this in the LX-810? - printer->topMargin = 0.0; - printer->bottomMargin = (double)printer->params[0] * printer->lineSpacing; - break; - case 0x4f: // Cancel bottom (and top) margin // TODO: does this work like this in the LX-810? - printer->topMargin = 0.0; - printer->bottomMargin = printer->pageHeight; - break; - case 0x50: // Select 10.5-point, 10-cpi (ESC P) - printer->cpi = 10; - updateFont(printer); - break; - case 0x51: // Set right margin - // TODO: clear previous tab settings and all characters in the current line? Minimum space between the margins? - printer->rightMargin = (double)(printer->params[0] - 1.0) / (double)printer->cpi; - break; - case 0x52: // Select an international character set (ESC R) - if (printer->params[0] <= 12) - { - printer->curI18NCharset = printer->params[0]; - updateCharset(printer); - } - break; - case 0x53: // Select superscript/subscript printing (ESC S) - printer->style &= 0xFFFF - STYLE_SUPERSCRIPT - STYLE_SUBSCRIPT; - if (printer->params[0] == 0 || printer->params[0] == 48) - printer->style |= STYLE_SUPERSCRIPT; - if (printer->params[0] == 1 || printer->params[1] == 49) - printer->style |= STYLE_SUBSCRIPT; - updateFont(printer); - break; - case 0x54: // Cancel superscript/subscript printing (ESC T) - printer->style &= 0xFFFF - STYLE_SUPERSCRIPT - STYLE_SUBSCRIPT; - updateFont(printer); - break; - case 0x55: // Turn unidirectional mode on/off (ESC U) - // We don't have a print head, so just ignore this - break; - case 0x57: // Turn double-width printing on/off (ESC W) - // TODO: see if this is right - if (printer->params[0] == 0 || printer->params[0] == 48) - printer->style &= 0xFFFF - STYLE_DOUBLEWIDTH; - if (printer->params[0] == 1 || printer->params[0] == 49) - printer->style |= STYLE_DOUBLEWIDTH; - updateFont(printer); - break; - case 0x59: // Select 120-dpi, double-speed graphics (ESC Y) - setupBitImage(printer->densy, PARAM16(0), printer); - break; - case 0x5a: // Select 240-dpi graphics (ESC Z) - setupBitImage(printer->densz, PARAM16(0), printer); - break; - case 0x61: // Select justification (ESC a) - // TODO: do this? - break; - case 0x6b: // Select typeface (ESC k) - if (printer->params[0] <= 11 || printer->params[0] == 30 || printer->params[0] == 31) - printer->NLQtypeFace = (Typeface)printer->params[0]; - updateFont(printer); - break; - case 0x6c: // Set left margin (ESC l) - // TODO: clear previous tab settings and all characters in the current line? Minimum space between the margins? - printer->leftMargin = (double)(printer->params[0] - 1.0) / (double)printer->cpi; - if (printer->curX < printer->leftMargin) - printer->curX = printer->leftMargin; - break; - case 0x70: // Turn proportional mode on/off (ESC p) - // TODO: Win3.1 driver did this. Is it undocumented but SHOULD WORK on the LX-810? - pclog("EPSON ESC p: proportional mode not supported by the LX-810!\n"); - break; - case 0x73: // Select low-speed mode (ESC s) - // Ignore - break; - case 0x74: // Select character table (ESC t) - if (printer->params[0] < 2) - printer->curCharTable = printer->params[0]; + if (printer->params[0] & 0x20) + printer->style |= STYLE_DOUBLEWIDTH; + if (printer->params[0] & 0x40) + printer->style |= STYLE_ITALICS; + if (printer->params[0] & 0x80) + printer->style |= STYLE_UNDERLINE; + + updateFont(printer); + break; + case 0x2a: // Select bit image (ESC *) + setupBitImage(printer->params[0], PARAM16(1), printer); + break; + case 0x2d: // Turn underline on/off (ESC -) + if (printer->params[0] == 0 || printer->params[0] == 48) + printer->style &= 0xFFFF - STYLE_UNDERLINE; + if (printer->params[0] == 1 || printer->params[0] == 49) + printer->style |= STYLE_UNDERLINE; + updateFont(printer); + break; + case 0x2f: // Select vertical tab channel (ESC /) + // Ignore + break; + case 0x30: // Select 1/8-inch line spacing (ESC 0) + printer->lineSpacing = (double)1 / 8; + break; + case 0x31: // Select 7/72-inch line spacing (ESC 1) + printer->lineSpacing = (double)7 / 72; + break; + case 0x32: // Select 1/6-inch line spacing (ESC 2) + printer->lineSpacing = (double)1 / 6; + break; + case 0x33: // Set n/216-inch line spacing (ESC 3) + printer->lineSpacing = (double)printer->params[0] / 216; + break; + case 0x34: // Select italic font (ESC 4) + printer->style |= STYLE_ITALICS; + updateFont(printer); + break; + case 0x35: // Cancel italic font (ESC 5) + printer->style &= 0xFFFF - STYLE_ITALICS; + updateFont(printer); + break; + case 0x36: // Enable printing of upper control codes (ESC 6) + printer->printUpperContr = true; + break; + case 0x37: // Enable upper control codes (ESC 7) + printer->printUpperContr = false; + break; + case 0x38: // Disable paper out detection (ESC 8) + // We have infinite paper, so just ignore this + break; + case 0x39: // Enable paper out detection (ESC 9) + // We have infinite paper, so just ignore this + break; + case 0x3c: // Unidirectional mode (one line) (ESC <) + // We don't have a print head, so just ignore this + break; + case 0x3f: // Reassign bit-image mode (ESC ?) + if (printer->params[0] == 75) + printer->densk = printer->params[1]; + if (printer->params[0] == 76) + printer->densl = printer->params[1]; + if (printer->params[0] == 89) // TODO: this option here is not present on the LX-810? (Even though the + // default mode for Y exists) + printer->densy = printer->params[1]; + if (printer->params[0] == 90) + printer->densz = printer->params[1]; + break; + case 0x40: // Initialize printer (ESC @) TODO: one more command that should clear the current line buffer + resetPrinter(printer, true); + break; + case 0x41: // Set n/72-inch line spacing + printer->lineSpacing = (double)printer->params[0] / 72; + break; + case 0x43: // Set page length in lines (ESC C) + if (printer->params[0] != 0) + printer->pageHeight = printer->bottomMargin = + (double)printer->params[0] * + printer->lineSpacing; // TODO: is this right? Also, we have ALREADY allocated the SDL + // surface! This can result in memory corruption + else // == 0 => Set page length in inches + { + printer->neededParam = 1; + printer->numParam = 0; + printer->ESCCmd = 0x100; + return true; + } + break; + case 0x45: // Select bold font (ESC E) + printer->style |= STYLE_BOLD; + updateFont(printer); + break; + case 0x46: // Cancel bold font (ESC F) + printer->style &= 0xFFFF - STYLE_BOLD; + updateFont(printer); + break; + case 0x47: // Select dobule-strike printing (ESC G) + printer->style |= STYLE_DOUBLESTRIKE; + updateFont(printer); + break; + case 0x48: // Cancel double-strike printing (ESC H) + printer->style &= 0xFFFF - STYLE_DOUBLESTRIKE; + updateFont(printer); + break; + case 0x49: // Enable printing of control codes (ESC I n) + // TODO: which program/driver did this? Is it undocumented but SHOULD WORK on the LX-810? + pclog("EPSON ESC I: printing of control codes not implemented on the LX-810!\n"); + break; + case 0x4a: // Advance print position vertically (ESC J n) + printer->curY += + (double)((double)printer->params[0] / + 216); // TODO: this command produces an immediate line feed without carriage return? + if (printer->curY > printer->bottomMargin) + newPage(true, printer); + break; + case 0x4b: // Select 60-dpi graphics (ESC K) + setupBitImage(printer->densk, PARAM16(0), printer); + break; + case 0x4c: // Select 120-dpi graphics (ESC L) + setupBitImage(printer->densl, PARAM16(0), printer); + break; + case 0x4d: // Select 10.5-point, 12-cpi (ESC M) + printer->cpi = 12; + updateFont(printer); + break; + case 0x4e: // Set bottom margin (ESC N) // TODO: does this work like this in the LX-810? + printer->topMargin = 0.0; + printer->bottomMargin = (double)printer->params[0] * printer->lineSpacing; + break; + case 0x4f: // Cancel bottom (and top) margin // TODO: does this work like this in the LX-810? + printer->topMargin = 0.0; + printer->bottomMargin = printer->pageHeight; + break; + case 0x50: // Select 10.5-point, 10-cpi (ESC P) + printer->cpi = 10; + updateFont(printer); + break; + case 0x51: // Set right margin + // TODO: clear previous tab settings and all characters in the current line? Minimum space between the + // margins? + printer->rightMargin = (double)(printer->params[0] - 1.0) / (double)printer->cpi; + break; + case 0x52: // Select an international character set (ESC R) + if (printer->params[0] <= 12) { + printer->curI18NCharset = printer->params[0]; updateCharset(printer); - updateFont(printer); - break; - case 0x78: // Select NLQ or draft (ESC x) - if (printer->params[0] == 0 || printer->params[0] == 48) - printer->printQuality = QUALITY_DRAFT; - if (printer->params[0] == 1 || printer->params[0] == 49) - printer->printQuality = QUALITY_NLQ; - break; - case 0x100: // Set page length in inches (ESC C NUL) - printer->pageHeight = (double)printer->params[0]; - printer->bottomMargin = printer->pageHeight; // TODO: is this right? - printer->topMargin = 0.0; - break; - default: - pclog("PRINTER: Skipped unsupported command ESC %c (%02X)\n", printer->ESCCmd, printer->ESCCmd); + } + break; + case 0x53: // Select superscript/subscript printing (ESC S) + printer->style &= 0xFFFF - STYLE_SUPERSCRIPT - STYLE_SUBSCRIPT; + if (printer->params[0] == 0 || printer->params[0] == 48) + printer->style |= STYLE_SUPERSCRIPT; + if (printer->params[0] == 1 || printer->params[1] == 49) + printer->style |= STYLE_SUBSCRIPT; + updateFont(printer); + break; + case 0x54: // Cancel superscript/subscript printing (ESC T) + printer->style &= 0xFFFF - STYLE_SUPERSCRIPT - STYLE_SUBSCRIPT; + updateFont(printer); + break; + case 0x55: // Turn unidirectional mode on/off (ESC U) + // We don't have a print head, so just ignore this + break; + case 0x57: // Turn double-width printing on/off (ESC W) + // TODO: see if this is right + if (printer->params[0] == 0 || printer->params[0] == 48) + printer->style &= 0xFFFF - STYLE_DOUBLEWIDTH; + if (printer->params[0] == 1 || printer->params[0] == 49) + printer->style |= STYLE_DOUBLEWIDTH; + updateFont(printer); + break; + case 0x59: // Select 120-dpi, double-speed graphics (ESC Y) + setupBitImage(printer->densy, PARAM16(0), printer); + break; + case 0x5a: // Select 240-dpi graphics (ESC Z) + setupBitImage(printer->densz, PARAM16(0), printer); + break; + case 0x61: // Select justification (ESC a) + // TODO: do this? + break; + case 0x6b: // Select typeface (ESC k) + if (printer->params[0] <= 11 || printer->params[0] == 30 || printer->params[0] == 31) + printer->NLQtypeFace = (Typeface)printer->params[0]; + updateFont(printer); + break; + case 0x6c: // Set left margin (ESC l) + // TODO: clear previous tab settings and all characters in the current line? Minimum space between the + // margins? + printer->leftMargin = (double)(printer->params[0] - 1.0) / (double)printer->cpi; + if (printer->curX < printer->leftMargin) + printer->curX = printer->leftMargin; + break; + case 0x70: // Turn proportional mode on/off (ESC p) + // TODO: Win3.1 driver did this. Is it undocumented but SHOULD WORK on the LX-810? + pclog("EPSON ESC p: proportional mode not supported by the LX-810!\n"); + break; + case 0x73: // Select low-speed mode (ESC s) + // Ignore + break; + case 0x74: // Select character table (ESC t) + if (printer->params[0] < 2) + printer->curCharTable = printer->params[0]; + updateCharset(printer); + updateFont(printer); + break; + case 0x78: // Select NLQ or draft (ESC x) + if (printer->params[0] == 0 || printer->params[0] == 48) + printer->printQuality = QUALITY_DRAFT; + if (printer->params[0] == 1 || printer->params[0] == 49) + printer->printQuality = QUALITY_NLQ; + break; + case 0x100: // Set page length in inches (ESC C NUL) + printer->pageHeight = (double)printer->params[0]; + printer->bottomMargin = printer->pageHeight; // TODO: is this right? + printer->topMargin = 0.0; + break; + default: + pclog("PRINTER: Skipped unsupported command ESC %c (%02X)\n", printer->ESCCmd, printer->ESCCmd); } printer->ESCCmd = 0; @@ -1174,136 +1158,128 @@ bool processCommandChar(uint8_t ch, lpt_epsonprinter_t *printer) // TODO: Select 9-Pin Graphics Mode (ESC ^) (has two bytes per column) int control_code_shifted = false; - if (!printer->printUpperContr) - { + if (!printer->printUpperContr) { if ((ch >= 0x80 && ch <= 0x9f) || ch == 0xff) ch -= 0x80; control_code_shifted = true; } - switch (ch) + switch (ch) { + case 0x07: // Beeper (BEL) + // BEEEP! + pclog("PRINTER: BEEP!\n"); + return true; + case 0x08: // Backspace (BS) { - case 0x07: // Beeper (BEL) - // BEEEP! - pclog("PRINTER: BEEP!\n"); - return true; - case 0x08: // Backspace (BS) - { - // TODO: seems more complex than this - double newX = printer->curX - (1 / (double)printer->actcpi); - if (newX >= printer->leftMargin) - printer->curX = newX; - } - return true; - case 0x09: // Tab horizontally (HT) - { - // Find tab right to current pos - double moveTo = -1; - for (uint8_t i = 0; i < printer->numHorizTabs; i++) - if (printer->horiztabs[i] > printer->curX) - moveTo = printer->horiztabs[i]; - // Nothing found => Ignore - if (moveTo > 0 && moveTo < printer->rightMargin) - printer->curX = moveTo; - } - return true; - case 0x0b: // Tab vertically (VT) - if (printer->numVertTabs == 0) // All tabs cancelled => Act like CR - printer->curX = printer->leftMargin; - else if (printer->numVertTabs == 255) // No tabs set since reset => Act like LF - { - printer->curX = printer->leftMargin; - printer->curY += printer->lineSpacing; - if (printer->curY > printer->bottomMargin) - newPage(true, printer); - } - else - { - // Find tab below current pos - double moveTo = -1; - for (uint8_t i = 0; i < printer->numVertTabs; i++) - if (printer->verttabs[i] > printer->curY) - moveTo = printer->verttabs[i]; - - // Nothing found => Act like FF - if (moveTo > printer->bottomMargin || moveTo < 0) - newPage(true, printer); - else - printer->curY = moveTo; - } - if (printer->style & STYLE_DOUBLEWIDTHONELINE) - { - printer->style &= 0xFFFF - STYLE_DOUBLEWIDTHONELINE; - updateFont(printer); - } - return true; - case 0x0c: // Form feed (FF) - if (printer->style & STYLE_DOUBLEWIDTHONELINE) - { - printer->style &= 0xFFFF - STYLE_DOUBLEWIDTHONELINE; - updateFont(printer); - } - newPage(true, printer); - return true; - case 0x0d: // Carriage Return (CR) + // TODO: seems more complex than this + double newX = printer->curX - (1 / (double)printer->actcpi); + if (newX >= printer->leftMargin) + printer->curX = newX; + } + return true; + case 0x09: // Tab horizontally (HT) + { + // Find tab right to current pos + double moveTo = -1; + for (uint8_t i = 0; i < printer->numHorizTabs; i++) + if (printer->horiztabs[i] > printer->curX) + moveTo = printer->horiztabs[i]; + // Nothing found => Ignore + if (moveTo > 0 && moveTo < printer->rightMargin) + printer->curX = moveTo; + } + return true; + case 0x0b: // Tab vertically (VT) + if (printer->numVertTabs == 0) // All tabs cancelled => Act like CR + printer->curX = printer->leftMargin; + else if (printer->numVertTabs == 255) // No tabs set since reset => Act like LF + { printer->curX = printer->leftMargin; - if (!printer->autoFeed) - return true; - case 0x0a: // Line feed - if (printer->style & STYLE_DOUBLEWIDTHONELINE) - { - printer->style &= 0xFFFF - STYLE_DOUBLEWIDTHONELINE; - updateFont(printer); - } - printer->curX = printer->leftMargin; // TODO: \n does this too or just \r? printer->curY += printer->lineSpacing; - if (printer->curY > printer->bottomMargin) newPage(true, printer); - return true; - case 0x0e: //Select double-width printing (one line) (SO) - printer->style |= STYLE_DOUBLEWIDTHONELINE; - updateFont(printer); - return true; - case 0x0f: // Select condensed printing (SI) - printer->style |= STYLE_CONDENSED; - updateFont(printer); - return true; - case 0x11: // Select printer (DC1) - // Ignore - return true; - case 0x12: // Cancel condensed printing (DC2) - printer->style &= 0xFFFF - STYLE_CONDENSED; - updateFont(printer); - return true; - case 0x13: // Deselect printer (DC3) - // Ignore - return true; - case 0x14: // Cancel double-width printing (one line) (DC4) + } else { + // Find tab below current pos + double moveTo = -1; + for (uint8_t i = 0; i < printer->numVertTabs; i++) + if (printer->verttabs[i] > printer->curY) + moveTo = printer->verttabs[i]; + + // Nothing found => Act like FF + if (moveTo > printer->bottomMargin || moveTo < 0) + newPage(true, printer); + else + printer->curY = moveTo; + } + if (printer->style & STYLE_DOUBLEWIDTHONELINE) { printer->style &= 0xFFFF - STYLE_DOUBLEWIDTHONELINE; updateFont(printer); + } + return true; + case 0x0c: // Form feed (FF) + if (printer->style & STYLE_DOUBLEWIDTHONELINE) { + printer->style &= 0xFFFF - STYLE_DOUBLEWIDTHONELINE; + updateFont(printer); + } + newPage(true, printer); + return true; + case 0x0d: // Carriage Return (CR) + printer->curX = printer->leftMargin; + if (!printer->autoFeed) return true; - case 0x18: // Cancel line (CAN) - return true; // TODO: is this used? should we cancel the line being printed? - case 0x1b: // ESC - printer->ESCSeen = true; - return true; - case 0x7f: // Delete character (DEL) - return true; // TODO: is this used? should we cancel the character being printed? - default: - if (control_code_shifted) - { - // TODO: see how this should really happen when the control code isn't processed (there are codepages with printable symbols < 0x20) - ch += 0x80; - } - return false; + case 0x0a: // Line feed + if (printer->style & STYLE_DOUBLEWIDTHONELINE) { + printer->style &= 0xFFFF - STYLE_DOUBLEWIDTHONELINE; + updateFont(printer); + } + printer->curX = printer->leftMargin; // TODO: \n does this too or just \r? + printer->curY += printer->lineSpacing; + + if (printer->curY > printer->bottomMargin) + newPage(true, printer); + return true; + case 0x0e: // Select double-width printing (one line) (SO) + printer->style |= STYLE_DOUBLEWIDTHONELINE; + updateFont(printer); + return true; + case 0x0f: // Select condensed printing (SI) + printer->style |= STYLE_CONDENSED; + updateFont(printer); + return true; + case 0x11: // Select printer (DC1) + // Ignore + return true; + case 0x12: // Cancel condensed printing (DC2) + printer->style &= 0xFFFF - STYLE_CONDENSED; + updateFont(printer); + return true; + case 0x13: // Deselect printer (DC3) + // Ignore + return true; + case 0x14: // Cancel double-width printing (one line) (DC4) + printer->style &= 0xFFFF - STYLE_DOUBLEWIDTHONELINE; + updateFont(printer); + return true; + case 0x18: // Cancel line (CAN) + return true; // TODO: is this used? should we cancel the line being printed? + case 0x1b: // ESC + printer->ESCSeen = true; + return true; + case 0x7f: // Delete character (DEL) + return true; // TODO: is this used? should we cancel the character being printed? + default: + if (control_code_shifted) { + // TODO: see how this should really happen when the control code isn't processed (there are codepages with + // printable symbols < 0x20) + ch += 0x80; + } + return false; } return false; } -void newPage(bool save, lpt_epsonprinter_t *printer) -{ +void newPage(bool save, lpt_epsonprinter_t *printer) { if (save) outputPage(printer); @@ -1317,16 +1293,14 @@ void newPage(bool save, lpt_epsonprinter_t *printer) SDL_FillRect(printer->page, &rect, SDL_MapRGB(printer->page->format, 255, 255, 255)); } -void printChar(lpt_epsonprinter_t *printer) -{ +void printChar(lpt_epsonprinter_t *printer) { uint8_t ch = printer->last_data; printer->charRead = true; if (printer->page == NULL) return; // Are we currently printing a bit graphic? - if (printer->bitGraph.remBytes > 0) - { + if (printer->bitGraph.remBytes > 0) { printBitGraph(ch, printer); return; } @@ -1338,25 +1312,25 @@ void printChar(lpt_epsonprinter_t *printer) // Do not print if no font is available if (!printer->curFont) return; - if(ch == 0) ch = 0x20; + if (ch == 0) + ch = 0x20; // TODO: real italics for the italics charset, where the upper half is (mostly) the lower half italicized. int italicize = false; - if (!(printer->style & STYLE_ITALICS) && printer->charTables[printer->curCharTable] == 0 && ch > 0x7f) // prevent double italics (they are present on the font) + if (!(printer->style & STYLE_ITALICS) && printer->charTables[printer->curCharTable] == 0 && + ch > 0x7f) // prevent double italics (they are present on the font) { italicize = true; } - if (italicize) - { + if (italicize) { FT_Matrix matrix; matrix.xx = 0x10000L; matrix.xy = (FT_Fixed)(0.20 * 0x10000L); matrix.yx = 0; matrix.yy = 0x10000L; FT_Set_Transform(printer->curFont, &matrix, NULL); - } - else + } else FT_Set_Transform(printer->curFont, NULL, NULL); // Find the glyph for the char to render @@ -1368,11 +1342,13 @@ void printChar(lpt_epsonprinter_t *printer) // Render a high-quality bitmap FT_Render_Glyph(printer->curFont->glyph, FT_RENDER_MODE_NORMAL); - // TODO: some fonts have negative left and/or top and as of this writing we don't do printable areas! So do this hack on unsigned ints... + // TODO: some fonts have negative left and/or top and as of this writing we don't do printable areas! So do this hack on + // unsigned ints... uint16_t penX = CURX_INCH_TO_PIXEL_ADD(fmax(0.0, printer->curFont->glyph->bitmap_left)); - uint16_t penY = CURY_INCH_TO_PIXEL_ADD(fmax(0.0, -printer->curFont->glyph->bitmap_top + printer->curFont->size->metrics.ascender / FREETYPE_FONT_MULTIPLIER)); + uint16_t penY = CURY_INCH_TO_PIXEL_ADD(fmax( + 0.0, -printer->curFont->glyph->bitmap_top + printer->curFont->size->metrics.ascender / FREETYPE_FONT_MULTIPLIER)); // handle proportional fonts - penX += (((double)printer->dpi/printer->actcpi) - printer->curFont->glyph->bitmap.width) / 2; + penX += (((double)printer->dpi / printer->actcpi) - printer->curFont->glyph->bitmap.width) / 2; if (printer->style & STYLE_SUBSCRIPT) // TODO: this and other placementes are guesswork penY += printer->curFont->glyph->metrics.vertAdvance / FREETYPE_FONT_MULTIPLIER * (double)1 / (double)3; @@ -1401,54 +1377,47 @@ void printChar(lpt_epsonprinter_t *printer) // Draw lines if desired if (printer->printQuality != QUALITY_DRAFT) // TODO: have the font variations for the NLQ fonts too - if (printer->style & STYLE_UNDERLINE) - { + if (printer->style & STYLE_UNDERLINE) { // Find out where to put the line - uint16_t lineY = CURY_INCH_TO_PIXEL_ADD(printer->curFont->size->metrics.height / FREETYPE_FONT_MULTIPLIER); + uint16_t lineY = + CURY_INCH_TO_PIXEL_ADD(printer->curFont->size->metrics.height / FREETYPE_FONT_MULTIPLIER); // TODO: use previous CURX_INCH_TO_PIXEL or penX here? drawLine(lineStart, CURX_INCH_TO_PIXEL, lineY, printer); } } -void blitGlyph(FT_Bitmap bitmap, uint16_t destx, uint16_t desty, bool add, lpt_epsonprinter_t *printer) -{ - for (unsigned int y = 0; y < bitmap.rows; y++) - { - for (unsigned int x = 0; x < bitmap.width; x++) - { +void blitGlyph(FT_Bitmap bitmap, uint16_t destx, uint16_t desty, bool add, lpt_epsonprinter_t *printer) { + for (unsigned int y = 0; y < bitmap.rows; y++) { + for (unsigned int x = 0; x < bitmap.width; x++) { // Read pixel from glyph bitmap uint8_t *source = bitmap.buffer + x + y * bitmap.pitch; // Ignore background and don't go over the border // TODO: This should not be linear! - if (*source != 0 && (destx + x < (unsigned int)printer->page->w) && (desty + y < (unsigned int)printer->page->h)) - { - uint8_t *target = (uint8_t *)printer->page->pixels + (x + destx) + (y + desty) * printer->page->pitch; - if (add) - { + if (*source != 0 && (destx + x < (unsigned int)printer->page->w) && + (desty + y < (unsigned int)printer->page->h)) { + uint8_t *target = + (uint8_t *)printer->page->pixels + (x + destx) + (y + desty) * printer->page->pitch; + if (add) { if (*target + *source > 255) *target = 255; else *target += *source; - } - else + } else *target = *source; } } } } -void drawLine(uint16_t fromx, uint16_t tox, uint16_t y, lpt_epsonprinter_t *printer) -{ +void drawLine(uint16_t fromx, uint16_t tox, uint16_t y, lpt_epsonprinter_t *printer) { SDL_LockSurface(printer->page); // Draw anti-aliased line - for (unsigned int x = fromx; x <= tox; x++) - { + for (unsigned int x = fromx; x <= tox; x++) { // Skip parts if going over the border - if (x < (unsigned int)printer->page->w) - { + if (x < (unsigned int)printer->page->w) { if (y > 0 && (y - 1) < printer->page->h) *((uint8_t *)printer->page->pixels + x + (y - 1) * printer->page->pitch) = 120; if (y < printer->page->h) @@ -1461,78 +1430,69 @@ void drawLine(uint16_t fromx, uint16_t tox, uint16_t y, lpt_epsonprinter_t *prin SDL_UnlockSurface(printer->page); } -void setAutofeed(bool feed, lpt_epsonprinter_t *printer) -{ - printer->autoFeed = feed; -} +void setAutofeed(bool feed, lpt_epsonprinter_t *printer) { printer->autoFeed = feed; } -bool getAutofeed(lpt_epsonprinter_t *printer) -{ - return printer->autoFeed; -} +bool getAutofeed(lpt_epsonprinter_t *printer) { return printer->autoFeed; } -bool isBusy(lpt_epsonprinter_t *printer) -{ +bool isBusy(lpt_epsonprinter_t *printer) { // We're never busy return false; } -bool ack(lpt_epsonprinter_t *printer) -{ +bool ack(lpt_epsonprinter_t *printer) { // Acknowledge last char read return printer->charRead; } // TODO: see if densities are OK -// TODO: 240x144 setting under windows 95 looks bad when printing bitmap fonts because of the "no adjancent dots" rule? Shouldn't it look a little better? -void setupBitImage(uint8_t dens, uint16_t numCols, lpt_epsonprinter_t *printer) -{ - switch (dens) - { - case 0: // Single-density - printer->bitGraph.horizDens = 60; - printer->bitGraph.vertDens = 72; - printer->bitGraph.adjacent = true; - printer->bitGraph.bytesColumn = 1; - break; - case 1: // Double-density - printer->bitGraph.horizDens = 120; - printer->bitGraph.vertDens = 72; - printer->bitGraph.adjacent = true; - printer->bitGraph.bytesColumn = 1; - break; - case 2: // High-speed double-density - printer->bitGraph.horizDens = 120; - printer->bitGraph.vertDens = 72; - printer->bitGraph.adjacent = false; - printer->bitGraph.bytesColumn = 1; - break; - case 3: // Quadruple-density - printer->bitGraph.horizDens = 240; - printer->bitGraph.vertDens = 72; - printer->bitGraph.adjacent = false; - printer->bitGraph.bytesColumn = 1; - break; - case 4: // CRT I - printer->bitGraph.horizDens = 80; - printer->bitGraph.vertDens = 72; - printer->bitGraph.adjacent = true; - printer->bitGraph.bytesColumn = 1; - break; - case 5: // Plotter (1:1 - printer->bitGraph.horizDens = 72; - printer->bitGraph.vertDens = 72; - printer->bitGraph.adjacent = true; - printer->bitGraph.bytesColumn = 1; - break; - case 6: // CRT II - printer->bitGraph.horizDens = 90; - printer->bitGraph.vertDens = 72; - printer->bitGraph.adjacent = true; - printer->bitGraph.bytesColumn = 1; - break; - default: - fatal("PRINTER: Unsupported bit image density %i\n", dens); +// TODO: 240x144 setting under windows 95 looks bad when printing bitmap fonts because of the "no adjancent dots" rule? Shouldn't +// it look a little better? +void setupBitImage(uint8_t dens, uint16_t numCols, lpt_epsonprinter_t *printer) { + switch (dens) { + case 0: // Single-density + printer->bitGraph.horizDens = 60; + printer->bitGraph.vertDens = 72; + printer->bitGraph.adjacent = true; + printer->bitGraph.bytesColumn = 1; + break; + case 1: // Double-density + printer->bitGraph.horizDens = 120; + printer->bitGraph.vertDens = 72; + printer->bitGraph.adjacent = true; + printer->bitGraph.bytesColumn = 1; + break; + case 2: // High-speed double-density + printer->bitGraph.horizDens = 120; + printer->bitGraph.vertDens = 72; + printer->bitGraph.adjacent = false; + printer->bitGraph.bytesColumn = 1; + break; + case 3: // Quadruple-density + printer->bitGraph.horizDens = 240; + printer->bitGraph.vertDens = 72; + printer->bitGraph.adjacent = false; + printer->bitGraph.bytesColumn = 1; + break; + case 4: // CRT I + printer->bitGraph.horizDens = 80; + printer->bitGraph.vertDens = 72; + printer->bitGraph.adjacent = true; + printer->bitGraph.bytesColumn = 1; + break; + case 5: // Plotter (1:1 + printer->bitGraph.horizDens = 72; + printer->bitGraph.vertDens = 72; + printer->bitGraph.adjacent = true; + printer->bitGraph.bytesColumn = 1; + break; + case 6: // CRT II + printer->bitGraph.horizDens = 90; + printer->bitGraph.vertDens = 72; + printer->bitGraph.adjacent = true; + printer->bitGraph.bytesColumn = 1; + break; + default: + fatal("PRINTER: Unsupported bit image density %i\n", dens); } printer->bitGraph.remBytes = numCols * printer->bitGraph.bytesColumn; @@ -1541,8 +1501,7 @@ void setupBitImage(uint8_t dens, uint16_t numCols, lpt_epsonprinter_t *printer) // TODO: anti-alias because of high dpi, also be mindful that additions when superimposing pin strikes are not linear // TODO: use this for printing when we have the character roms -void printBitGraph(uint8_t ch, lpt_epsonprinter_t *printer) -{ +void printBitGraph(uint8_t ch, lpt_epsonprinter_t *printer) { printer->bitGraph.column[printer->bitGraph.readBytesColumn++] = ch; printer->bitGraph.remBytes--; @@ -1557,39 +1516,30 @@ void printBitGraph(uint8_t ch, lpt_epsonprinter_t *printer) // TODO: other rasterizations where we should do start->end instead of start + steps double pixsizeX; double pixsizeY; - if (printer->emulatePinsForBitmaps) - { + if (printer->emulatePinsForBitmaps) { pixsizeX = 0.01141732283464566929 * printer->dpi; pixsizeY = 0.01141732283464566929 * printer->dpi; - } - else - { + } else { pixsizeX = printer->dpi / printer->bitGraph.horizDens > 0 ? printer->dpi / printer->bitGraph.horizDens : 1; pixsizeY = printer->dpi / printer->bitGraph.vertDens > 0 ? printer->dpi / printer->bitGraph.vertDens : 1; } - for (unsigned int i = 0; i < printer->bitGraph.bytesColumn; i++) - { - for (int j = 7; j >= 0; j--) - { + for (unsigned int i = 0; i < printer->bitGraph.bytesColumn; i++) { + for (int j = 7; j >= 0; j--) { uint8_t pixel = (printer->bitGraph.column[i] >> j) & 0x01; - if (pixel != 0) - { + if (pixel != 0) { int startx; int endx; int starty; int endy; - if (printer->emulatePinsForBitmaps) - { + if (printer->emulatePinsForBitmaps) { startx = CURX_INCH_TO_PIXEL_ADD(-pixsizeX); endx = CURX_INCH_TO_PIXEL_ADD(pixsizeX * 2); starty = CURY_INCH_TO_PIXEL_ADD(-pixsizeY); endy = CURY_INCH_TO_PIXEL_ADD(pixsizeY * 2); - } - else - { + } else { startx = CURX_INCH_TO_PIXEL; endx = CURX_INCH_TO_PIXEL_ADD(pixsizeX); starty = CURY_INCH_TO_PIXEL; @@ -1598,27 +1548,28 @@ void printBitGraph(uint8_t ch, lpt_epsonprinter_t *printer) for (int xx = startx; xx < endx; xx++) for (int yy = starty; yy < endy; yy++) - if ((xx < printer->page->w) && (yy < printer->page->h)) - { - if (printer->emulatePinsForBitmaps) - { + if ((xx < printer->page->w) && (yy < printer->page->h)) { + if (printer->emulatePinsForBitmaps) { double middlex = CURX_INCH_TO_PIXEL_ADD(pixsizeX / 2); double middley = CURY_INCH_TO_PIXEL_ADD(pixsizeY / 2); - double dist = sqrt((xx - middlex) * (xx - middlex) + (yy - middley) * (yy - middley)); + double dist = sqrt((xx - middlex) * (xx - middlex) + + (yy - middley) * (yy - middley)); double radius = pixsizeY / 2; - double ratio = dist/radius; - // pin diameter == 0.29mm == 0.01141732283464566929 inches. 0.35mm or 1/72 inch between pins. - uint8_t source = (ratio <= 1.0) ? (255 * (1 - ratio*ratio)) : 0; - //uint8_t source = (ratio <= 1.0) ? (255 * (1 - ratio)) : 0; - //uint8_t source = (ratio <= 1.0) ? 255 : 0; - uint8_t *target = (uint8_t *)printer->page->pixels + xx + yy * printer->page->pitch; + double ratio = dist / radius; + // pin diameter == 0.29mm == 0.01141732283464566929 inches. 0.35mm + // or 1/72 inch between pins. + uint8_t source = (ratio <= 1.0) ? (255 * (1 - ratio * ratio)) : 0; + // uint8_t source = (ratio <= 1.0) ? (255 * (1 - ratio)) : 0; + // uint8_t source = (ratio <= 1.0) ? 255 : 0; + uint8_t *target = (uint8_t *)printer->page->pixels + xx + + yy * printer->page->pitch; if ((int)*target + (int)source > 255) *target = 255; else *target += source; - } - else - *((uint8_t *)printer->page->pixels + xx + yy * printer->page->pitch) = 255; + } else + *((uint8_t *)printer->page->pixels + xx + + yy * printer->page->pitch) = 255; } } @@ -1636,21 +1587,18 @@ void printBitGraph(uint8_t ch, lpt_epsonprinter_t *printer) printer->curX += (double)1 / (double)printer->bitGraph.horizDens; } -void formFeed(lpt_epsonprinter_t *printer) -{ +void formFeed(lpt_epsonprinter_t *printer) { // Don't output blank pages newPage(!isBlank(printer), printer); finishMultipage(printer); } -static void findNextName(const char* front, const char* ext, char *filename, size_t filename_size, const char *base_path) -{ +static void findNextName(const char *front, const char *ext, char *filename, size_t filename_size, const char *base_path) { char buffer[10]; uint16_t num = 1; FILE *test = NULL; - do - { + do { snprintf(&buffer[0], 10, "%d", num++); strlcpy(filename, base_path, filename_size); strlcat(filename, front, filename_size); @@ -1662,20 +1610,17 @@ static void findNextName(const char* front, const char* ext, char *filename, siz fclose(test); if (num == 999999999) fatal("Too many printed pages! Please make space!\n"); - } - while (test != NULL); + } while (test != NULL); } -void outputPage(lpt_epsonprinter_t *printer) -{ +void outputPage(lpt_epsonprinter_t *printer) { char filename[MAX_PATH_STRING]; - if (printer->output_type == OUTPUT_TYPE_FORWARD_TO_REAL_PRINTER) - { -#if defined (WIN32) + if (printer->output_type == OUTPUT_TYPE_FORWARD_TO_REAL_PRINTER) { +#if defined(WIN32) // You'll need the mouse for the print dialog - if(mouselocked) - CaptureMouse(); + if (mouselocked) + CaptureMouse(); uint16_t physW = GetDeviceCaps(printer->printerDC, PHYSICALWIDTH); uint16_t physH = GetDeviceCaps(printer->printerDC, PHYSICALHEIGHT); @@ -1697,8 +1642,7 @@ void outputPage(lpt_epsonprinter_t *printer) SelectObject(memHDC, bitmap); // Start new printer job? - if (printer->outputHandle == NULL) - { + if (printer->outputHandle == NULL) { DOCINFO docinfo; docinfo.cbSize = sizeof(docinfo); docinfo.lpszDocName = "PCem Printer"; @@ -1715,10 +1659,8 @@ void outputPage(lpt_epsonprinter_t *printer) SDL_Palette *sdlpal = printer->page->format->palette; - for (uint16_t y = 0; y < printer->page->h; y++) - { - for (uint16_t x = 0; x < printer->page->w; x++) - { + for (uint16_t y = 0; y < printer->page->h; y++) { + for (uint16_t x = 0; x < printer->page->w; x++) { uint8_t pixel = *((uint8_t *)printer->page->pixels + x + (y * printer->page->pitch)); uint32_t color = 0; color |= sdlpal->colors[pixel].r; @@ -1734,13 +1676,10 @@ void outputPage(lpt_epsonprinter_t *printer) EndPage(printer->printerDC); - if (printer->multipageOutput) - { + if (printer->multipageOutput) { printer->multiPageCounter++; printer->outputHandle = printer->printerDC; - } - else - { + } else { EndDoc(printer->printerDC); printer->outputHandle = NULL; } @@ -1749,27 +1688,24 @@ void outputPage(lpt_epsonprinter_t *printer) #else fatal("PRINTER: Direct printing not supported under this OS\n"); #endif - } - else if (printer->output_type == OUTPUT_TYPE_POSTSCRIPT) - { - // TODO: this was working even when the last entry on the palette was undefined - see if there is any workaround in this code - FILE* psfile = NULL; + } else if (printer->output_type == OUTPUT_TYPE_POSTSCRIPT) { + // TODO: this was working even when the last entry on the palette was undefined - see if there is any workaround + // in this code + FILE *psfile = NULL; // Continue postscript file? if (printer->outputHandle != NULL) psfile = (FILE *)printer->outputHandle; // Create new file? - if (psfile == NULL) - { + if (psfile == NULL) { if (!printer->multipageOutput) findNextName("page", ".ps", filename, MAX_PATH_STRING, printer->outputpath); else findNextName("doc", ".ps", filename, MAX_PATH_STRING, printer->outputpath); psfile = fopen(filename, "wb"); - if (!psfile) - { + if (!psfile) { fatal("PRINTER: Can't open file %s for printer output\n", filename); return; } @@ -1777,7 +1713,8 @@ void outputPage(lpt_epsonprinter_t *printer) // Print header fprintf(psfile, "%%!PS-Adobe-3.0\n"); fprintf(psfile, "%%%%Pages: (atend)\n"); - fprintf(psfile, "%%%%BoundingBox: 0 0 %i %i\n", (uint16_t)(printer->defaultPageWidth * printer->dpi), (uint16_t)(printer->defaultPageHeight * printer->dpi)); // TODO: use current height here? + fprintf(psfile, "%%%%BoundingBox: 0 0 %i %i\n", (uint16_t)(printer->defaultPageWidth * printer->dpi), + (uint16_t)(printer->defaultPageHeight * printer->dpi)); // TODO: use current height here? fprintf(psfile, "%%%%Creator: PCem Virtual Printer\n"); fprintf(psfile, "%%%%DocumentData: Clean7Bit\n"); fprintf(psfile, "%%%%LanguageLevel: 2\n"); @@ -1786,8 +1723,10 @@ void outputPage(lpt_epsonprinter_t *printer) } fprintf(psfile, "%%%%Page: %i %i\n", printer->multiPageCounter, printer->multiPageCounter); - fprintf(psfile, "%i %i scale\n", (uint16_t)(printer->defaultPageWidth * printer->dpi), (uint16_t)(printer->defaultPageHeight * printer->dpi)); // TODO: use current height here? - fprintf(psfile, "%i %i 8 [%i 0 0 -%i 0 %i]\n", printer->page->w, printer->page->h, printer->page->w, printer->page->h, printer->page->h); + fprintf(psfile, "%i %i scale\n", (uint16_t)(printer->defaultPageWidth * printer->dpi), + (uint16_t)(printer->defaultPageHeight * printer->dpi)); // TODO: use current height here? + fprintf(psfile, "%i %i 8 [%i 0 0 -%i 0 %i]\n", printer->page->w, printer->page->h, printer->page->w, + printer->page->h, printer->page->h); fprintf(psfile, "currentfile\n"); fprintf(psfile, "/ASCII85Decode filter\n"); fprintf(psfile, "/RunLengthDecode filter\n"); @@ -1799,11 +1738,10 @@ void outputPage(lpt_epsonprinter_t *printer) uint32_t numpix = printer->page->h * printer->page->w; printer->ASCII85BufferPos = printer->ASCII85CurCol = 0; - while (pix < numpix) - { + while (pix < numpix) { // Compress data using RLE - if ((pix < numpix - 2) && (getPixel(pix, printer) == getPixel(pix + 1, printer)) && (getPixel(pix, printer) == getPixel(pix + 2, printer))) - { + if ((pix < numpix - 2) && (getPixel(pix, printer) == getPixel(pix + 1, printer)) && + (getPixel(pix, printer) == getPixel(pix + 2, printer))) { // Found three or more pixels with the same color uint8_t sameCount = 3; uint8_t col = getPixel(pix, printer); @@ -1815,17 +1753,13 @@ void outputPage(lpt_epsonprinter_t *printer) // Skip ahead pix += sameCount; - } - else - { + } else { // Find end of heterogenous area uint8_t diffCount = 1; while (diffCount < 128 && diffCount + pix < numpix && - ( - (diffCount + pix < numpix - 2) - || (getPixel(pix + diffCount, printer) != getPixel(pix + diffCount + 1, printer)) - || (getPixel(pix + diffCount, printer) != getPixel(pix + diffCount + 2, printer)) - )) + ((diffCount + pix < numpix - 2) || + (getPixel(pix + diffCount, printer) != getPixel(pix + diffCount + 1, printer)) || + (getPixel(pix + diffCount, printer) != getPixel(pix + diffCount + 2, printer)))) diffCount++; fprintASCII85(psfile, diffCount - 1, printer); @@ -1842,43 +1776,37 @@ void outputPage(lpt_epsonprinter_t *printer) fprintf(psfile, "showpage\n"); - if (printer->multipageOutput) - { + if (printer->multipageOutput) { printer->multiPageCounter++; printer->outputHandle = psfile; - } - else - { + } else { fprintf(psfile, "%%%%Pages: 1\n"); fprintf(psfile, "%%%%EOF\n"); fclose(psfile); printer->outputHandle = NULL; } - } - else - { + } else { const char *ext; const char *output_format; - switch(printer->output_type) - { - case OUTPUT_TYPE_BMP: - ext = ".bmp"; - output_format = IMAGE_BMP; - break; - case OUTPUT_TYPE_PNG: - ext = ".png"; - output_format = IMAGE_PNG; - break; - case OUTPUT_TYPE_TIFF: - ext = ".tiff"; - output_format = IMAGE_TIFF; - break; - case OUTPUT_TYPE_JPG: - ext = ".jpg"; - output_format = IMAGE_JPG; - break; - default: - fatal("PRINTER: Unknown output type: %d\n", printer->output_type); + switch (printer->output_type) { + case OUTPUT_TYPE_BMP: + ext = ".bmp"; + output_format = IMAGE_BMP; + break; + case OUTPUT_TYPE_PNG: + ext = ".png"; + output_format = IMAGE_PNG; + break; + case OUTPUT_TYPE_TIFF: + ext = ".tiff"; + output_format = IMAGE_TIFF; + break; + case OUTPUT_TYPE_JPG: + ext = ".jpg"; + output_format = IMAGE_JPG; + break; + default: + fatal("PRINTER: Unknown output type: %d\n", printer->output_type); } // Find a page that does not exists @@ -1891,10 +1819,8 @@ void outputPage(lpt_epsonprinter_t *printer) SDL_Palette *sdlpal = printer->page->format->palette; - for (int y = 0; y < printer->page->h; y++) - { - for (int x = 0; x < printer->page->w; x++) - { + for (int y = 0; y < printer->page->h; y++) { + for (int x = 0; x < printer->page->w; x++) { uint8_t pixel = *((uint8_t *)printer->page->pixels + x + (y * printer->page->pitch)); *rgbptr++ = sdlpal->colors[pixel].r; @@ -1912,32 +1838,25 @@ void outputPage(lpt_epsonprinter_t *printer) } } -void fprintASCII85(FILE* f, uint16_t b, lpt_epsonprinter_t *printer) -{ - if (b != 256) - { +void fprintASCII85(FILE *f, uint16_t b, lpt_epsonprinter_t *printer) { + if (b != 256) { if (b < 256) printer->ASCII85Buffer[printer->ASCII85BufferPos++] = (uint8_t)b; - if (printer->ASCII85BufferPos == 4 || b == 257) - { - uint32_t num = (uint32_t)printer->ASCII85Buffer[0] << 24 | (uint32_t)printer->ASCII85Buffer[1] << 16 | (uint32_t)printer->ASCII85Buffer[2] << 8 | (uint32_t)printer->ASCII85Buffer[3]; + if (printer->ASCII85BufferPos == 4 || b == 257) { + uint32_t num = (uint32_t)printer->ASCII85Buffer[0] << 24 | (uint32_t)printer->ASCII85Buffer[1] << 16 | + (uint32_t)printer->ASCII85Buffer[2] << 8 | (uint32_t)printer->ASCII85Buffer[3]; // Deal with special case - if (num == 0 && b != 257) - { + if (num == 0 && b != 257) { fprintf(f, "z"); - if (++printer->ASCII85CurCol >= 79) - { + if (++printer->ASCII85CurCol >= 79) { printer->ASCII85CurCol = 0; fprintf(f, "\n"); } - } - else - { + } else { char buffer[5]; - for (int8_t i = 4; i >= 0; i--) - { + for (int8_t i = 4; i >= 0; i--) { buffer[i] = (uint8_t)((uint32_t)num % (uint32_t)85); buffer[i] += 33; num /= (uint32_t)85; @@ -1947,11 +1866,9 @@ void fprintASCII85(FILE* f, uint16_t b, lpt_epsonprinter_t *printer) if (printer->ASCII85CurCol == 0 && buffer[0] == '%') fprintf(f, " "); - for (int i = 0; i < ((b != 257) ? 5 : printer->ASCII85BufferPos + 1); i++) - { + for (int i = 0; i < ((b != 257) ? 5 : printer->ASCII85BufferPos + 1); i++) { fprintf(f, "%c", buffer[i]); - if (++printer->ASCII85CurCol >= 79) - { + if (++printer->ASCII85CurCol >= 79) { printer->ASCII85CurCol = 0; fprintf(f, "\n"); } @@ -1961,12 +1878,10 @@ void fprintASCII85(FILE* f, uint16_t b, lpt_epsonprinter_t *printer) printer->ASCII85BufferPos = 0; } - } - else // Close string + } else // Close string { // Partial tupel if there are still bytes in the buffer - if (printer->ASCII85BufferPos > 0) - { + if (printer->ASCII85BufferPos > 0) { for (uint8_t i = printer->ASCII85BufferPos; i < 4; i++) printer->ASCII85Buffer[i] = 0; @@ -1978,20 +1893,15 @@ void fprintASCII85(FILE* f, uint16_t b, lpt_epsonprinter_t *printer) } } -void finishMultipage(lpt_epsonprinter_t *printer) -{ - if (printer->outputHandle != NULL) - { - if (printer->output_type == OUTPUT_TYPE_POSTSCRIPT) - { +void finishMultipage(lpt_epsonprinter_t *printer) { + if (printer->outputHandle != NULL) { + if (printer->output_type == OUTPUT_TYPE_POSTSCRIPT) { FILE *psfile = (FILE *)printer->outputHandle; fprintf(psfile, "%%%%Pages: %i\n", printer->multiPageCounter); fprintf(psfile, "%%%%EOF\n"); fclose(psfile); - } - else if (printer->output_type == OUTPUT_TYPE_FORWARD_TO_REAL_PRINTER) - { -#if defined (WIN32) + } else if (printer->output_type == OUTPUT_TYPE_FORWARD_TO_REAL_PRINTER) { +#if defined(WIN32) EndDoc(printer->printerDC); #endif } @@ -1999,8 +1909,7 @@ void finishMultipage(lpt_epsonprinter_t *printer) } } -bool isBlank(lpt_epsonprinter_t *printer) -{ +bool isBlank(lpt_epsonprinter_t *printer) { bool blank = true; SDL_LockSurface(printer->page); @@ -2015,14 +1924,12 @@ bool isBlank(lpt_epsonprinter_t *printer) return blank; } -uint8_t getPixel(uint32_t num, lpt_epsonprinter_t *printer) -{ +uint8_t getPixel(uint32_t num, lpt_epsonprinter_t *printer) { // Respect the pitch return *((uint8_t *)printer->page->pixels + (num % printer->page->w) + ((num / printer->page->w) * printer->page->pitch)); } -static void epsonprinter_write_data(uint8_t val, void *p) -{ +static void epsonprinter_write_data(uint8_t val, void *p) { lpt_epsonprinter_t *lpt_epsonprinter = (lpt_epsonprinter_t *)p; #ifdef PRINTER_DEBUG pclog("lx-810 write data %02X\n", val); @@ -2030,8 +1937,7 @@ static void epsonprinter_write_data(uint8_t val, void *p) lpt_epsonprinter->last_data = val; } -static void epsonprinter_write_ctrl(uint8_t val, void *p) -{ +static void epsonprinter_write_ctrl(uint8_t val, void *p) { lpt_epsonprinter_t *lpt_epsonprinter = (lpt_epsonprinter_t *)p; #ifdef PRINTER_DEBUG pclog("lx-810 write control %02X\n", val); @@ -2046,16 +1952,15 @@ static void epsonprinter_write_ctrl(uint8_t val, void *p) lpt_epsonprinter->controlreg = val; } -static uint8_t epsonprinter_read_status(void *p) -{ +static uint8_t epsonprinter_read_status(void *p) { lpt_epsonprinter_t *lpt_epsonprinter = (lpt_epsonprinter_t *)p; uint8_t temp; // Printer is always online and never reports an error - temp = 0x1f;// 0x18; + temp = 0x1f; // 0x18; -// if (lpt_epsonprinter->controlreg & 0x08 == 0) -// temp |= 0x10; + // if (lpt_epsonprinter->controlreg & 0x08 == 0) + // temp |= 0x10; if (!isBusy(lpt_epsonprinter)) temp |= 0x80; @@ -2068,8 +1973,7 @@ static uint8_t epsonprinter_read_status(void *p) return temp; } -static uint8_t epsonprinter_read_ctrl(void *p) -{ +static uint8_t epsonprinter_read_ctrl(void *p) { lpt_epsonprinter_t *lpt_epsonprinter = (lpt_epsonprinter_t *)p; uint8_t temp = 0xe0 | (getAutofeed(lpt_epsonprinter) ? 0x02 : 0x00) | (lpt_epsonprinter->controlreg & 0xfd); #ifdef PRINTER_DEBUG @@ -2079,15 +1983,16 @@ static uint8_t epsonprinter_read_ctrl(void *p) return temp; } -static void *epsonprinter_init() -{ +static void *epsonprinter_init() { lpt_epsonprinter_t *lpt_epsonprinter = (lpt_epsonprinter_t *)malloc(sizeof(lpt_epsonprinter_t)); memset(lpt_epsonprinter, 0, sizeof(lpt_epsonprinter_t)); lpt_epsonprinter->controlreg = 0x04; - // TODO: printable area? (make it an option because the user may want to REALLY print the results and we don't want to add two forced margins?) - // TODO: also follow all mode overrides (relation of dip switches, front panel, software cmds) to the letter from the user manual + // TODO: printable area? (make it an option because the user may want to REALLY print the results and we don't want to add + // two forced margins?) + // TODO: also follow all mode overrides (relation of dip switches, front panel, software cmds) to the letter from the user + // manual // TODO: see if defaults are right everywhere // TODO: possible overflows in 8-bit and 16-bit ints when doing high dpis // TODO: auto-form feed after inactivity option @@ -2101,19 +2006,18 @@ static void *epsonprinter_init() int selected_papersize = device_get_config_int("papersize"); int width; int height; - switch (selected_papersize) - { - case 0: - width = 85; - height = 110; - break; - case 1: - // TODO: should we care about this precision loss? - width = 210 / 254; - height = 297 / 254; - break; - default: - fatal("PRINTER: Invalid paper size\n"); + switch (selected_papersize) { + case 0: + width = 85; + height = 110; + break; + case 1: + // TODO: should we care about this precision loss? + width = 210 / 254; + height = 297 / 254; + break; + default: + fatal("PRINTER: Invalid paper size\n"); } int cpi = device_get_config_int("cpi"); int selected_fontstyle = device_get_config_int("font"); @@ -2121,128 +2025,126 @@ static void *epsonprinter_init() uint8_t quality; Typeface font; // TODO: we are just setting the default NLQ font to Roman when starting with draft, see if this is right. - switch (selected_fontstyle) - { - case 0: - style = 0; - quality = QUALITY_DRAFT; - font = roman; - break; - case 1: - style = STYLE_CONDENSED; - quality = QUALITY_DRAFT; - font = roman; - break; - case 2: - style = 0; - quality = QUALITY_NLQ; - font = roman; - break; - case 3: - style = 0; - quality = QUALITY_NLQ; - font = sansserif; - break; - default: - fatal("PRINTER: Invalid initial font setting: %d\n", selected_fontstyle); + switch (selected_fontstyle) { + case 0: + style = 0; + quality = QUALITY_DRAFT; + font = roman; + break; + case 1: + style = STYLE_CONDENSED; + quality = QUALITY_DRAFT; + font = roman; + break; + case 2: + style = 0; + quality = QUALITY_NLQ; + font = roman; + break; + case 3: + style = 0; + quality = QUALITY_NLQ; + font = sansserif; + break; + default: + fatal("PRINTER: Invalid initial font setting: %d\n", selected_fontstyle); } int selected_charset = device_get_config_int("characterset"); uint8_t chartable, i18ncharset; uint16_t codepage; - switch (selected_charset) - { - case 0: - chartable = 0; - i18ncharset = 0; - codepage = 437; - break; - case 1: - chartable = 1; - i18ncharset = 0; - codepage = 437; - break; - case 2: - chartable = 1; - i18ncharset = 1; - codepage = 437; - break; - case 3: - chartable = 1; - i18ncharset = 2; - codepage = 437; - break; - case 4: - chartable = 1; - i18ncharset = 3; - codepage = 437; - break; - case 5: - chartable = 1; - i18ncharset = 4; - codepage = 437; - break; - case 6: - chartable = 1; - i18ncharset = 5; - codepage = 437; - break; - case 7: - chartable = 1; - i18ncharset = 6; - codepage = 437; - break; - case 8: - chartable = 1; - i18ncharset = 7; - codepage = 437; - break; - case 9: - chartable = 1; - i18ncharset = 8; - codepage = 437; - break; - case 10: - chartable = 1; - i18ncharset = 9; - codepage = 437; - break; - case 11: - chartable = 1; - i18ncharset = 10; - codepage = 437; - break; - case 12: - chartable = 1; - i18ncharset = 11; - codepage = 437; - break; - case 13: - chartable = 1; - i18ncharset = 12; - codepage = 437; - break; - case 14: - chartable = 1; - i18ncharset = 0; - codepage = 850; - break; - case 15: - chartable = 1; - i18ncharset = 0; - codepage = 860; - break; - case 16: - chartable = 1; - i18ncharset = 0; - codepage = 863; - break; - case 17: - chartable = 1; - i18ncharset = 0; - codepage = 865; - break; - default: - fatal("PRINTER: Invalid initial charset setting: %d\n", selected_charset); + switch (selected_charset) { + case 0: + chartable = 0; + i18ncharset = 0; + codepage = 437; + break; + case 1: + chartable = 1; + i18ncharset = 0; + codepage = 437; + break; + case 2: + chartable = 1; + i18ncharset = 1; + codepage = 437; + break; + case 3: + chartable = 1; + i18ncharset = 2; + codepage = 437; + break; + case 4: + chartable = 1; + i18ncharset = 3; + codepage = 437; + break; + case 5: + chartable = 1; + i18ncharset = 4; + codepage = 437; + break; + case 6: + chartable = 1; + i18ncharset = 5; + codepage = 437; + break; + case 7: + chartable = 1; + i18ncharset = 6; + codepage = 437; + break; + case 8: + chartable = 1; + i18ncharset = 7; + codepage = 437; + break; + case 9: + chartable = 1; + i18ncharset = 8; + codepage = 437; + break; + case 10: + chartable = 1; + i18ncharset = 9; + codepage = 437; + break; + case 11: + chartable = 1; + i18ncharset = 10; + codepage = 437; + break; + case 12: + chartable = 1; + i18ncharset = 11; + codepage = 437; + break; + case 13: + chartable = 1; + i18ncharset = 12; + codepage = 437; + break; + case 14: + chartable = 1; + i18ncharset = 0; + codepage = 850; + break; + case 15: + chartable = 1; + i18ncharset = 0; + codepage = 860; + break; + case 16: + chartable = 1; + i18ncharset = 0; + codepage = 863; + break; + case 17: + chartable = 1; + i18ncharset = 0; + codepage = 865; + break; + default: + fatal("PRINTER: Invalid initial charset setting: %d\n", selected_charset); } int emulatepins = device_get_config_int("bitmaps_emulate_pins"); @@ -2253,13 +2155,10 @@ static void *epsonprinter_init() strlcpy(lpt_epsonprinter->outputpath, printer_path, MAX_PATH_STRING - 2); put_backslash(lpt_epsonprinter->outputpath); - if (FT_Init_FreeType(&lpt_epsonprinter->FTlib)) - { + if (FT_Init_FreeType(&lpt_epsonprinter->FTlib)) { fatal("PRINTER: Unable to init Freetype2. Printing disabled\n"); lpt_epsonprinter->page = NULL; - } - else - { + } else { lpt_epsonprinter->dpi = dpi; lpt_epsonprinter->output_type = output_type; lpt_epsonprinter->multipageOutput = multipage; @@ -2278,20 +2177,14 @@ static void *epsonprinter_init() // Create page lpt_epsonprinter->page = SDL_CreateRGBSurface( - 0, - (unsigned int)(lpt_epsonprinter->defaultPageWidth * lpt_epsonprinter->dpi), - (unsigned int)(lpt_epsonprinter->defaultPageHeight * lpt_epsonprinter->dpi), - 8, - 0, - 0, - 0, - 0); + 0, (unsigned int)(lpt_epsonprinter->defaultPageWidth * lpt_epsonprinter->dpi), + (unsigned int)(lpt_epsonprinter->defaultPageHeight * lpt_epsonprinter->dpi), 8, 0, 0, 0, 0); // Set a grey palette - SDL_Palette* palette = lpt_epsonprinter->page->format->palette; + SDL_Palette *palette = lpt_epsonprinter->page->format->palette; for (unsigned int i = 0; i < 256; i++) - palette->colors[i].r = palette->colors[i].g = palette->colors[i].b = 255-i; + palette->colors[i].r = palette->colors[i].g = palette->colors[i].b = 255 - i; lpt_epsonprinter->curFont = NULL; lpt_epsonprinter->autoFeed = false; @@ -2299,19 +2192,18 @@ static void *epsonprinter_init() resetPrinterHard(lpt_epsonprinter); - if (lpt_epsonprinter->output_type == OUTPUT_TYPE_FORWARD_TO_REAL_PRINTER) - { -#if defined (WIN32) + if (lpt_epsonprinter->output_type == OUTPUT_TYPE_FORWARD_TO_REAL_PRINTER) { +#if defined(WIN32) // TODO: this looks like a hack // Show Print dialog to obtain a printer device context PRINTDLG pd; pd.lStructSize = sizeof(PRINTDLG); - pd.hDevMode = (HANDLE) NULL; - pd.hDevNames = (HANDLE) NULL; + pd.hDevMode = (HANDLE)NULL; + pd.hDevNames = (HANDLE)NULL; pd.Flags = PD_RETURNDC; pd.hwndOwner = NULL; - pd.hDC = (HDC) NULL; + pd.hDC = (HDC)NULL; pd.nFromPage = 1; pd.nToPage = 1; pd.nMinPage = 0; @@ -2319,12 +2211,12 @@ static void *epsonprinter_init() pd.nCopies = 1; pd.hInstance = NULL; pd.lCustData = 0L; - pd.lpfnPrintHook = (LPPRINTHOOKPROC) NULL; - pd.lpfnSetupHook = (LPSETUPHOOKPROC) NULL; - pd.lpPrintTemplateName = (LPSTR) NULL; - pd.lpSetupTemplateName = (LPSTR) NULL; - pd.hPrintTemplate = (HANDLE) NULL; - pd.hSetupTemplate = (HANDLE) NULL; + pd.lpfnPrintHook = (LPPRINTHOOKPROC)NULL; + pd.lpfnSetupHook = (LPSETUPHOOKPROC)NULL; + pd.lpPrintTemplateName = (LPSTR)NULL; + pd.lpSetupTemplateName = (LPSTR)NULL; + pd.hPrintTemplate = (HANDLE)NULL; + pd.hSetupTemplate = (HANDLE)NULL; PrintDlg(&pd); // TODO: what if user presses cancel? lpt_epsonprinter->printerDC = pd.hDC; @@ -2338,358 +2230,181 @@ static void *epsonprinter_init() return lpt_epsonprinter; } -static void epsonprinter_close(void *p) -{ +static void epsonprinter_close(void *p) { lpt_epsonprinter_t *lpt_epsonprinter = (lpt_epsonprinter_t *)p; formFeed(lpt_epsonprinter); // eject any pending page - if (lpt_epsonprinter->page != NULL) - { + if (lpt_epsonprinter->page != NULL) { SDL_FreeSurface(lpt_epsonprinter->page); lpt_epsonprinter->page = NULL; FT_Done_FreeType(lpt_epsonprinter->FTlib); } -#if defined (WIN32) +#if defined(WIN32) DeleteDC(lpt_epsonprinter->printerDC); #endif free(lpt_epsonprinter); } -void *epsonprinter_init_lpt1() -{ +void *epsonprinter_init_lpt1() { current_device = (device_t *)&lpt_epsonprinter_device; void *p = epsonprinter_init(); current_device = NULL; - //lpt1_device_attach(&lpt_epsonprinter_device, p); + // lpt1_device_attach(&lpt_epsonprinter_device, p); return p; } -void epsonprinter_close_lpt1(void *p) -{ +void epsonprinter_close_lpt1(void *p) { epsonprinter_close(p); - //lpt1_device_detach(); + // lpt1_device_detach(); } -static device_config_t epsonprinter_config[] = - { - { - .name = "dpi", - .description = "Output DPI", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "240 DPI", - .value = 240 - }, - { - .description = "360 DPI", - .value = 360 - }, - { - .description = "480 DPI", - .value = 480 - }, - { - .description = "600 DPI", - .value = 600 - }, - { - .description = "720 DPI", - .value = 720 - }, - { - .description = "840 DPI", - .value = 840 - }, - { - .description = "960 DPI", - .value = 960 - }, - { - .description = "1080 DPI", - .value = 1080 - }, - { - .description = "" - } - }, - .default_int = 360 - }, - { - .name = "outputtype", - .description = "Output type", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "Postscript (.ps)", - .value = OUTPUT_TYPE_POSTSCRIPT - }, - { - .description = "Bitmap (.bmp)", - .value = OUTPUT_TYPE_BMP - }, - { - .description = "Portable Network Graphics (.png)", - .value = OUTPUT_TYPE_PNG - }, - { - .description = "Tagged Image File Format (.tiff)", - .value = OUTPUT_TYPE_TIFF - }, - { - .description = "JPEG (.jpg)", - .value = OUTPUT_TYPE_JPG - }, -#if defined (WIN32) - { - .description = "Redirect to real printer", - .value = OUTPUT_TYPE_FORWARD_TO_REAL_PRINTER - }, +static device_config_t epsonprinter_config[] = { + {.name = "dpi", + .description = "Output DPI", + .type = CONFIG_SELECTION, + .selection = {{.description = "240 DPI", .value = 240}, + {.description = "360 DPI", .value = 360}, + {.description = "480 DPI", .value = 480}, + {.description = "600 DPI", .value = 600}, + {.description = "720 DPI", .value = 720}, + {.description = "840 DPI", .value = 840}, + {.description = "960 DPI", .value = 960}, + {.description = "1080 DPI", .value = 1080}, + {.description = ""}}, + .default_int = 360}, + {.name = "outputtype", + .description = "Output type", + .type = CONFIG_SELECTION, + .selection = {{.description = "Postscript (.ps)", .value = OUTPUT_TYPE_POSTSCRIPT}, + {.description = "Bitmap (.bmp)", .value = OUTPUT_TYPE_BMP}, + {.description = "Portable Network Graphics (.png)", .value = OUTPUT_TYPE_PNG}, + {.description = "Tagged Image File Format (.tiff)", .value = OUTPUT_TYPE_TIFF}, + {.description = "JPEG (.jpg)", .value = OUTPUT_TYPE_JPG}, +#if defined(WIN32) + {.description = "Redirect to real printer", .value = OUTPUT_TYPE_FORWARD_TO_REAL_PRINTER}, #endif - { - .description = "" - } - }, - .default_int = OUTPUT_TYPE_PNG - }, + {.description = ""}}, + .default_int = OUTPUT_TYPE_PNG}, + {.name = "multipage", + .description = "Multipage for Postscript and real printer", + .type = CONFIG_BINARY, + .default_int = 1}, + {.name = "papersize", + .description = "Default paper size", + .type = CONFIG_SELECTION, + .selection = + {// TODO: more default lengths are supported, see DIP switch settings on the manual and see to with paper types + // they map + {.description = "Letter (8 1/2\" x 11\")", .value = 0}, + {.description = "A4 (210mm x 297mm)", .value = 1}, + {.description = ""}}, + .default_int = 0}, + {.name = "cpi", + .description = "Default CPI (Characters per inch)", + .type = CONFIG_SELECTION, + .selection = {{.description = "10 CPI", .value = 10}, {.description = "12 CPI", .value = 12}, {.description = ""}}, + .default_int = 10}, + /*{ TODO + .name = "shapeofzero", + .description = "Shape of zero", + .type = CONFIG_SELECTION, + .selection = { - .name = "multipage", - .description = "Multipage for Postscript and real printer", - .type = CONFIG_BINARY, - .default_int = 1 - }, - { - .name = "papersize", - .description = "Default paper size", - .type = CONFIG_SELECTION, - .selection = - { - // TODO: more default lengths are supported, see DIP switch settings on the manual and see to with paper types they map - { - .description = "Letter (8 1/2\" x 11\")", - .value = 0 - }, - { - .description = "A4 (210mm x 297mm)", - .value = 1 - }, - { - .description = "" - } - }, - .default_int = 0 - }, - { - .name = "cpi", - .description = "Default CPI (Characters per inch)", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "10 CPI", - .value = 10 - }, - { - .description = "12 CPI", - .value = 12 - }, - { - .description = "" - } - }, - .default_int = 10 - }, - /*{ TODO - .name = "shapeofzero", - .description = "Shape of zero", - .type = CONFIG_SELECTION, - .selection = { - { - .description = "Not Slashed", - .value = 0 - }, - { - .description = "Slashed", - .value = 1 - }, - { - .description = "" - } + .description = "Not Slashed", + .value = 0 }, - .default_int = 0 - },*/ - { - .name = "font", - .description = "Default font", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "Draft", - .value = 0 - }, - { - .description = "Draft condensed", - .value = 1 - }, - { - .description = "NLQ Roman", - .value = 2 - }, - { - .description = "NLQ Sans Serif", - .value = 3 - }, - { - .description = "" - } - }, - .default_int = 0 - }, - /*{ TODO - .name = "draftmode", - .description = "Draft mode", - .type = CONFIG_SELECTION, - .selection = { - { - .description = "Normal", - .value = 0 - }, - { - .description = "High-speed", // TODO: different font, only works at 10 CPI! Reverts do "Draft" otherwise (what about styles?) - .value = 1 - }, - { - .description = "" - } + .description = "Slashed", + .value = 1 }, - .default_int = 0 - },*/ - { - .name = "characterset", - .description = "Default character set", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "Italics", - .value = 0 - }, - { - .description = "CP437 + U.S.A.", - .value = 1 - }, - { - .description = "CP437 + France", - .value = 2 - }, - { - .description = "CP437 + Germany", - .value = 3 - }, - { - .description = "CP437 + U.K.", - .value = 4 - }, - { - .description = "CP437 + Denmark I", - .value = 5 - }, - { - .description = "CP437 + Sweden", - .value = 6 - }, - { - .description = "CP437 + Italy", - .value = 7 - }, - { - .description = "CP437 + Spain I", - .value = 8 - }, - { - .description = "CP437 + Japan (Only available as a printer command on real hardware)", - .value = 9 - }, - { - .description = "CP437 + Norway (Only available as a printer command on real hardware)", - .value = 10 - }, - { - .description = "CP437 + Denmark II (Only available as a printer command on real hardware)", - .value = 11 - }, - { - .description = "CP437 + Spain II (Only available as a printer command on real hardware)", - .value = 12 - }, - { - .description = "CP437 + Latin America (Only available as a printer command on real hardware)", - .value = 13 - }, - // The international character sets above can be selected (via software) with the codepages below, but I don't know if it makes sense. - { - .description = "CP850 (Multilingual)", - .value = 14 - }, - { - .description = "CP860 (Portugal)", - .value = 15 - }, - { - .description = "CP863 (Canada-French)", - .value = 16 - }, - { - .description = "CP865 (Norway)", - .value = 17 - }, - { - .description = "" - } - }, - .default_int = 1 + { + .description = "" + } }, - /*{ TODO: Didn't implement because I didn't test if this is FORCE or just START ON - .name = "autolinefeed", - .description = "Force auto linefeed", - .type = CONFIG_BINARY, - .default_int = 0 - },*/ - /*{ TODO: this forces an upper and lower margin by default - half and inch at each. Can be overridden by software - check if it goes back to these values after a software/command reset. - .name = "skipperforation", - .description = "1-inch skip over perforation", - .type = CONFIG_BINARY, - .default_int = 0 - },*/ + .default_int = 0 + },*/ + {.name = "font", + .description = "Default font", + .type = CONFIG_SELECTION, + .selection = {{.description = "Draft", .value = 0}, + {.description = "Draft condensed", .value = 1}, + {.description = "NLQ Roman", .value = 2}, + {.description = "NLQ Sans Serif", .value = 3}, + {.description = ""}}, + .default_int = 0}, + /*{ TODO + .name = "draftmode", + .description = "Draft mode", + .type = CONFIG_SELECTION, + .selection = { - .name = "bitmaps_emulate_pins", - .description = "Emulate pin spacing when printing graphics", - .type = CONFIG_BINARY, - .default_int = 1 + { + .description = "Normal", + .value = 0 + }, + { + .description = "High-speed", // TODO: different font, only works at 10 CPI! Reverts do "Draft" + otherwise (what about styles?) .value = 1 + }, + { + .description = "" + } }, - { - .type = -1 - } - }; + .default_int = 0 + },*/ + {.name = "characterset", + .description = "Default character set", + .type = CONFIG_SELECTION, + .selection = {{.description = "Italics", .value = 0}, + {.description = "CP437 + U.S.A.", .value = 1}, + {.description = "CP437 + France", .value = 2}, + {.description = "CP437 + Germany", .value = 3}, + {.description = "CP437 + U.K.", .value = 4}, + {.description = "CP437 + Denmark I", .value = 5}, + {.description = "CP437 + Sweden", .value = 6}, + {.description = "CP437 + Italy", .value = 7}, + {.description = "CP437 + Spain I", .value = 8}, + {.description = "CP437 + Japan (Only available as a printer command on real hardware)", .value = 9}, + {.description = "CP437 + Norway (Only available as a printer command on real hardware)", .value = 10}, + {.description = "CP437 + Denmark II (Only available as a printer command on real hardware)", .value = 11}, + {.description = "CP437 + Spain II (Only available as a printer command on real hardware)", .value = 12}, + {.description = "CP437 + Latin America (Only available as a printer command on real hardware)", + .value = 13}, + // The international character sets above can be selected (via software) with the codepages below, but I + // don't know if it makes sense. + {.description = "CP850 (Multilingual)", .value = 14}, + {.description = "CP860 (Portugal)", .value = 15}, + {.description = "CP863 (Canada-French)", .value = 16}, + {.description = "CP865 (Norway)", .value = 17}, + {.description = ""}}, + .default_int = 1}, + /*{ TODO: Didn't implement because I didn't test if this is FORCE or just START ON + .name = "autolinefeed", + .description = "Force auto linefeed", + .type = CONFIG_BINARY, + .default_int = 0 + },*/ + /*{ TODO: this forces an upper and lower margin by default - half and inch at each. Can be overridden by software - check + if it goes back to these values after a software/command reset. .name = "skipperforation", .description = "1-inch skip + over perforation", .type = CONFIG_BINARY, .default_int = 0 + },*/ + {.name = "bitmaps_emulate_pins", + .description = "Emulate pin spacing when printing graphics", + .type = CONFIG_BINARY, + .default_int = 1}, + {.type = -1}}; -lpt_device_t lpt_epsonprinter_device = - { - "Epson LX-810 Printer", - 0, - epsonprinter_init_lpt1, - epsonprinter_close_lpt1, - NULL, - NULL, - NULL, - NULL, - epsonprinter_config, - epsonprinter_write_data, - epsonprinter_write_ctrl, - epsonprinter_read_status - }; +lpt_device_t lpt_epsonprinter_device = {"Epson LX-810 Printer", + 0, + epsonprinter_init_lpt1, + epsonprinter_close_lpt1, + NULL, + NULL, + NULL, + NULL, + epsonprinter_config, + epsonprinter_write_data, + epsonprinter_write_ctrl, + epsonprinter_read_status}; diff --git a/experimental/printer_epsonlx810/plugin.c b/experimental/printer_epsonlx810/plugin.c index c0ce6734..9879593b 100644 --- a/experimental/printer_epsonlx810/plugin.c +++ b/experimental/printer_epsonlx810/plugin.c @@ -6,40 +6,37 @@ extern char pcem_path[512]; -LPT_DEVICE l_epsonlx810 = { "Epson LX-810 Printer", "lpt_epsonlx810", &lpt_epsonprinter_device }; +LPT_DEVICE l_epsonlx810 = {"Epson LX-810 Printer", "lpt_epsonlx810", &lpt_epsonprinter_device}; -#define safe_strncpy(a,b,n) do { strncpy((a),(b),(n)-1); (a)[(n)-1] = 0; } while (0) +#define safe_strncpy(a, b, n) \ + do { \ + strncpy((a), (b), (n)-1); \ + (a)[(n)-1] = 0; \ + } while (0) char printer_path[512]; -void set_printer_path(char *s) -{ +void set_printer_path(char *s) { safe_strncpy(printer_path, s, 512); append_slash(printer_path, 512); } -void load_config() -{ - char* cfg_printer_path = config_get_string(CFG_GLOBAL, "Paths", "printer_path", 0); +void load_config() { + char *cfg_printer_path = config_get_string(CFG_GLOBAL, "Paths", "printer_path", 0); if (cfg_printer_path) set_printer_path(cfg_printer_path); } -void save_config() -{ - config_set_string(CFG_GLOBAL, "Paths", "printer_path", printer_path); -} +void save_config() { config_set_string(CFG_GLOBAL, "Paths", "printer_path", printer_path); } -void init_config() -{ +void init_config() { char s[512]; append_filename(s, pcem_path, "printer/", 512); set_printer_path(s); } -PLUGIN_INIT(printer_epsonlx810) -{ +PLUGIN_INIT(printer_epsonlx810) { add_config_callback(load_config, save_config, init_config); pcem_add_lpt(&l_epsonlx810); } diff --git a/experimental/printer_epsonlx810/wx-imagesave.cc b/experimental/printer_epsonlx810/wx-imagesave.cc index eb4bc6bf..a57a4985 100644 --- a/experimental/printer_epsonlx810/wx-imagesave.cc +++ b/experimental/printer_epsonlx810/wx-imagesave.cc @@ -4,33 +4,28 @@ #include #include -int wx_image_save_fullpath(const char* fullpath, const char* format, unsigned char* rgba, int width, int height, int alpha) -{ +int wx_image_save_fullpath(const char *fullpath, const char *format, unsigned char *rgba, int width, int height, int alpha) { int x, y; wxLogNull logNull; wxImage image(width, height); - if (alpha) - { + if (alpha) { // these will be automatically freed - unsigned char* rgb = (unsigned char*)malloc(width*height*3); - unsigned char* a = (unsigned char*)malloc(width*height); - for (x = 0; x < width; ++x) - { - for (y = 0; y < height; ++y) - { - rgb[(y*width+x)*3+0] = rgba[(y*width+x)*4+0]; - rgb[(y*width+x)*3+1] = rgba[(y*width+x)*4+1]; - rgb[(y*width+x)*3+2] = rgba[(y*width+x)*4+2]; - a[y*width+x] = rgba[(y*width+x)*4+3]; + unsigned char *rgb = (unsigned char *)malloc(width * height * 3); + unsigned char *a = (unsigned char *)malloc(width * height); + for (x = 0; x < width; ++x) { + for (y = 0; y < height; ++y) { + rgb[(y * width + x) * 3 + 0] = rgba[(y * width + x) * 4 + 0]; + rgb[(y * width + x) * 3 + 1] = rgba[(y * width + x) * 4 + 1]; + rgb[(y * width + x) * 3 + 2] = rgba[(y * width + x) * 4 + 2]; + a[y * width + x] = rgba[(y * width + x) * 4 + 3]; } } image.SetData(rgb); image.SetAlpha(a); - } - else + } else image.SetData(rgba, true); - wxImageHandler* h; + wxImageHandler *h; if (!strcmp(format, IMAGE_TIFF)) h = new wxTIFFHandler(); @@ -42,8 +37,7 @@ int wx_image_save_fullpath(const char* fullpath, const char* format, unsigned ch h = new wxPNGHandler(); int res = 0; - if (h) - { + if (h) { wxString p(fullpath); wxFileOutputStream stream(p); diff --git a/includes/private/bswap.h b/includes/private/bswap.h index 6a6a3ca1..fb5f8ce6 100644 --- a/includes/private/bswap.h +++ b/includes/private/bswap.h @@ -8,112 +8,72 @@ #include #else -#define bswap_16(x) \ -({ \ - uint16_t __x = (x); \ - ((uint16_t)( \ - (((uint16_t)(__x) & (uint16_t)0x00ffU) << 8) | \ - (((uint16_t)(__x) & (uint16_t)0xff00U) >> 8) )); \ -}) +#define bswap_16(x) \ + ({ \ + uint16_t __x = (x); \ + ((uint16_t)((((uint16_t)(__x) & (uint16_t)0x00ffU) << 8) | (((uint16_t)(__x) & (uint16_t)0xff00U) >> 8))); \ + }) -#define bswap_32(x) \ -({ \ - uint32_t __x = (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_32(x) \ + ({ \ + uint32_t __x = (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 __x = (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) )); \ -}) +#define bswap_64(x) \ + ({ \ + uint64_t __x = (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 uint16_t bswap16(uint16_t x) { return bswap_16(x); } -static inline uint32_t bswap32(uint32_t x) -{ - return bswap_32(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 uint64_t bswap64(uint64_t x) { return bswap_64(x); } -static inline void bswap16s(uint16_t *s) -{ - *s = bswap16(*s); -} +static inline void bswap16s(uint16_t *s) { *s = bswap16(*s); } -static inline void bswap32s(uint32_t *s) -{ - *s = bswap32(*s); -} +static inline void bswap32s(uint32_t *s) { *s = bswap32(*s); } -static inline void bswap64s(uint64_t *s) -{ - *s = bswap64(*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 le_bswap(v, size) bswap##size(v) #define be_bswaps(v, size) -#define le_bswaps(p, size) *p = bswap ## size(*p); +#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 be_bswap(v, size) bswap##size(v) #define le_bswaps(v, size) -#define be_bswaps(p, size) *p = bswap ## size(*p); +#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);\ -} +#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) @@ -137,52 +97,46 @@ CPU_CONVERT(le, 64, uint64_t) #else -static inline void cpu_to_le16wu(uint16_t *p, uint16_t v) -{ - uint8_t *p1 = (uint8_t *)p; +static inline void cpu_to_le16wu(uint16_t *p, uint16_t v) { + uint8_t *p1 = (uint8_t *)p; - p1[0] = v; - p1[1] = v >> 8; + p1[0] = v; + p1[1] = v >> 8; } -static inline void cpu_to_le32wu(uint32_t *p, uint32_t v) -{ - uint8_t *p1 = (uint8_t *)p; +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; + 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 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 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; +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; + p1[0] = v >> 8; + p1[1] = v; } -static inline void cpu_to_be32wu(uint32_t *p, uint32_t v) -{ - uint8_t *p1 = (uint8_t *)p; +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; + p1[0] = v >> 24; + p1[1] = v >> 16; + p1[2] = v >> 8; + p1[3] = v; } #endif diff --git a/includes/private/bus/mca.h b/includes/private/bus/mca.h index 658461f6..6fef4410 100644 --- a/includes/private/bus/mca.h +++ b/includes/private/bus/mca.h @@ -1,7 +1,8 @@ #ifndef _MCA_H_ #define _MCA_H_ void mca_init(int nr_cards); -void mca_add(uint8_t (*read)(int addr, void *priv), void (*write)(int addr, uint8_t val, void *priv), void (*reset)(void *priv), void *priv); +void mca_add(uint8_t (*read)(int addr, void *priv), void (*write)(int addr, uint8_t val, void *priv), void (*reset)(void *priv), + void *priv); void mca_set_index(int index); uint8_t mca_read(uint16_t port); void mca_write(uint16_t port, uint8_t val); diff --git a/includes/private/bus/pci.h b/includes/private/bus/pci.h index 135b7136..e196aa4f 100644 --- a/includes/private/bus/pci.h +++ b/includes/private/bus/pci.h @@ -2,8 +2,10 @@ #define _PCI_H_ void pci_init(int type); void pci_slot(int card); -void pci_add_specific(int card, uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv); -int pci_add(uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv); +void pci_add_specific(int card, uint8_t (*read)(int func, int addr, void *priv), + void (*write)(int func, int addr, uint8_t val, void *priv), void *priv); +int pci_add(uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), + void *priv); void pci_set_irq_routing(int card, int irq); void pci_set_card_routing(int card, int pci_int); void pci_set_irq(int card, int pci_int); @@ -11,7 +13,7 @@ void pci_clear_irq(int card, int pci_int); #define PCI_REG_COMMAND 0x04 -#define PCI_COMMAND_IO 0x01 +#define PCI_COMMAND_IO 0x01 #define PCI_COMMAND_MEM 0x02 #define PCI_CONFIG_TYPE_1 1 diff --git a/includes/private/codegen/codegen.h b/includes/private/codegen/codegen.h index ac5c0bc3..025f86ed 100644 --- a/includes/private/codegen/codegen.h +++ b/includes/private/codegen/codegen.h @@ -12,25 +12,24 @@ 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 -{ +typedef struct codeblock_t { uint32_t pc; uint32_t _cs; uint32_t phys, phys_2; @@ -44,7 +43,7 @@ typedef struct codeblock_t uint16_t parent, left, right; uint8_t *data; - + uint64_t page_mask, page_mask2; uint64_t *dirty_mask, *dirty_mask2; @@ -86,27 +85,21 @@ extern uint8_t *block_write_data; #define BLOCK_INVALID 0 -static inline int get_block_nr(codeblock_t *block) -{ - return ((uintptr_t)block - (uintptr_t)codeblock) / sizeof(codeblock_t); -} +static inline int get_block_nr(codeblock_t *block) { return ((uintptr_t)block - (uintptr_t)codeblock) / sizeof(codeblock_t); } -static inline codeblock_t *codeblock_tree_find(uint32_t phys, uint32_t _cs) -{ +static inline codeblock_t *codeblock_tree_find(uint32_t phys, uint32_t _cs) { codeblock_t *block; uint64_t a = _cs | ((uint64_t)phys << 32); - + if (!pages[phys >> 12].head) return NULL; - + block = &codeblock[pages[phys >> 12].head]; - while (block) - { + while (block) { uint64_t block_cmp = block->_cs | ((uint64_t)block->phys << 32); - if (a == block_cmp) - { + 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))) + ((block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK))) break; } if (a < block_cmp) @@ -114,48 +107,42 @@ static inline codeblock_t *codeblock_tree_find(uint32_t phys, uint32_t _cs) else block = block->right ? &codeblock[block->right] : NULL; } - + return block; } -static inline void codeblock_tree_add(codeblock_t *new_block) -{ +static inline void codeblock_tree_add(codeblock_t *new_block) { codeblock_t *block = &codeblock[pages[new_block->phys >> 12].head]; uint64_t a = new_block->_cs | ((uint64_t)new_block->phys << 32); - if (!pages[new_block->phys >> 12].head) - { + if (!pages[new_block->phys >> 12].head) { pages[new_block->phys >> 12].head = get_block_nr(new_block); new_block->parent = new_block->left = new_block->right = BLOCK_INVALID; - } - else - { + } else { codeblock_t *old_block = NULL; uint64_t old_block_cmp = 0; - - while (block) - { + + while (block) { old_block = block; old_block_cmp = old_block->_cs | ((uint64_t)old_block->phys << 32); - + if (a < old_block_cmp) block = block->left ? &codeblock[block->left] : NULL; else block = block->right ? &codeblock[block->right] : NULL; } - + if (a < old_block_cmp) old_block->left = get_block_nr(new_block); else old_block->right = get_block_nr(new_block); - + new_block->parent = get_block_nr(old_block); new_block->left = new_block->right = BLOCK_INVALID; } } -static inline void codeblock_tree_delete(codeblock_t *block) -{ +static inline void codeblock_tree_delete(codeblock_t *block) { uint16_t parent_nr = block->parent; codeblock_t *parent; @@ -164,90 +151,71 @@ static inline void codeblock_tree_delete(codeblock_t *block) else parent = NULL; - if (!block->left && !block->right) - { + if (!block->left && !block->right) { /*Easy case - remove from parent*/ if (!parent) pages[block->phys >> 12].head = BLOCK_INVALID; - else - { + else { uint16_t block_nr = get_block_nr(block); - + if (parent->left == block_nr) parent->left = BLOCK_INVALID; if (parent->right == block_nr) parent->right = BLOCK_INVALID; } return; - } - else if (!block->left) - { + } else if (!block->left) { /*Only right node*/ - if (!parent_nr) - { + if (!parent_nr) { pages[block->phys >> 12].head = block->right; codeblock[pages[block->phys >> 12].head].parent = BLOCK_INVALID; - } - else - { + } else { uint16_t block_nr = get_block_nr(block); - if (parent->left == block_nr) - { + if (parent->left == block_nr) { parent->left = block->right; codeblock[parent->left].parent = parent_nr; } - if (parent->right == block_nr) - { + if (parent->right == block_nr) { parent->right = block->right; codeblock[parent->right].parent = parent_nr; } } return; - } - else if (!block->right) - { + } else if (!block->right) { /*Only left node*/ - if (!parent_nr) - { + if (!parent_nr) { pages[block->phys >> 12].head = block->left; codeblock[pages[block->phys >> 12].head].parent = BLOCK_INVALID; - } - else - { + } else { uint16_t block_nr = get_block_nr(block); - if (parent->left == block_nr) - { + if (parent->left == block_nr) { parent->left = block->left; codeblock[parent->left].parent = parent_nr; } - if (parent->right == block_nr) - { + if (parent->right == block_nr) { parent->right = block->left; codeblock[parent->right].parent = parent_nr; } } return; - } - else - { + } else { /*Difficult case - node has two children. Walk right child to find lowest node*/ codeblock_t *lowest = &codeblock[block->right], *highest; codeblock_t *old_parent; uint16_t lowest_nr; - + while (lowest->left) lowest = &codeblock[lowest->left]; lowest_nr = get_block_nr(lowest); - + old_parent = &codeblock[lowest->parent]; /*Replace deleted node with lowest node*/ if (!parent_nr) pages[block->phys >> 12].head = lowest_nr; - else - { + else { uint16_t block_nr = get_block_nr(block); if (parent->left == block_nr) @@ -262,12 +230,10 @@ static inline void codeblock_tree_delete(codeblock_t *block) codeblock[lowest->left].parent = lowest_nr; old_parent->left = BLOCK_INVALID; - + highest = &codeblock[lowest->right]; - if (!lowest->right) - { - if (lowest_nr != block->right) - { + if (!lowest->right) { + if (lowest_nr != block->right) { lowest->right = block->right; codeblock[block->right].parent = lowest_nr; } @@ -277,8 +243,7 @@ static inline void codeblock_tree_delete(codeblock_t *block) while (highest->right) highest = &codeblock[highest->right]; - if (block->right && block->right != lowest_nr) - { + if (block->right && block->right != lowest_nr) { highest->right = block->right; codeblock[block->right].parent = get_block_nr(highest); } @@ -290,26 +255,20 @@ static inline void codeblock_tree_delete(codeblock_t *block) void codegen_mark_code_present_multibyte(codeblock_t *block, uint32_t start_pc, int len); -static inline void codegen_mark_code_present(codeblock_t *block, uint32_t start_pc, int len) -{ - if (len == 1) - { - if (block->flags & CODEBLOCK_BYTE_MASK) - { +static inline void codegen_mark_code_present(codeblock_t *block, uint32_t start_pc, int len) { + if (len == 1) { + if (block->flags & CODEBLOCK_BYTE_MASK) { if (!((start_pc ^ block->pc) & ~0x3f)) /*Starts in second page*/ block->page_mask |= ((uint64_t)1 << (start_pc & PAGE_MASK_MASK)); else block->page_mask2 |= ((uint64_t)1 << (start_pc & PAGE_MASK_MASK)); - } - else - { + } else { if (!((start_pc ^ block->pc) & ~0xfff)) /*Starts in second page*/ block->page_mask |= ((uint64_t)1 << ((start_pc >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK)); else block->page_mask2 |= ((uint64_t)1 << ((start_pc >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK)); } - } - else + } else codegen_mark_code_present_multibyte(block, start_pc, len); } @@ -328,7 +287,8 @@ void codegen_set_op32(); void codegen_flush(); void codegen_check_flush(struct page_t *page, uint64_t mask, uint32_t phys_addr); struct ir_data_t; -x86seg *codegen_generate_ea(struct ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, uint32_t op_32, int stack_offset); +x86seg *codegen_generate_ea(struct ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, + uint32_t op_32, int stack_offset); void codegen_check_seg_read(codeblock_t *block, struct ir_data_t *ir, x86seg *seg); void codegen_check_seg_write(codeblock_t *block, struct ir_data_t *ir, x86seg *seg); @@ -359,8 +319,7 @@ extern void (*codegen_timing_block_start)(); extern void (*codegen_timing_block_end)(); extern int (*codegen_timing_jump_cycles)(); -typedef struct codegen_timing_t -{ +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, uint32_t op_pc); @@ -410,7 +369,7 @@ int codegen_get_instruction_uop(codeblock_t *block, uint32_t pc, int *first_inst void codegen_set_loop_start(struct ir_data_t *ir, int first_instruction); #ifdef DEBUG_EXTRA -extern uint32_t instr_counts[256*256]; +extern uint32_t instr_counts[256 * 256]; #endif #endif diff --git a/includes/private/codegen/codegen_accumulate.h b/includes/private/codegen/codegen_accumulate.h index 8ab31008..147bd141 100644 --- a/includes/private/codegen/codegen_accumulate.h +++ b/includes/private/codegen/codegen_accumulate.h @@ -1,11 +1,10 @@ #ifndef _CODEGEN_ACCUMULATE_H_ #define _CODEGEN_ACCUMULATE_H_ -enum -{ - ACCREG_ins = 0, +enum { + ACCREG_ins = 0, ACCREG_cycles = 1, - + ACCREG_COUNT }; @@ -15,5 +14,4 @@ void codegen_accumulate(int acc_reg, int delta); void codegen_accumulate_flush(struct ir_data_t *ir); void codegen_accumulate_reset(); - #endif /* _CODEGEN_ACCUMULATE_H_ */ diff --git a/includes/private/codegen/codegen_allocator.h b/includes/private/codegen/codegen_allocator.h index ff7febc6..8d8dad17 100644 --- a/includes/private/codegen/codegen_allocator.h +++ b/includes/private/codegen/codegen_allocator.h @@ -4,12 +4,12 @@ /*The allocator handles all allocation of executable memory. Since the two-pass recompiler design makes applying hard limits to codeblock size difficult, the allocator allows memory to be provided as and when required. - + The allocator provides a block size of a little under 1 kB (slightly lower to limit cache aliasing). Each generated codeblock is allocated one block by default, and will allocate additional block(s) once the existing memory is sorted. Blocks are chained together by jump instructions. - + Due to the chaining, the total memory size is limited by the range of a jump instruction. ARMv7 is restricted to +/- 32 MB, ARMv8 to +/- 128 MB, x86 to +/- 2GB. As a result, total memory size is limited to 32 MB on ARMv7*/ @@ -19,7 +19,7 @@ #define MEM_BLOCK_NR 131072 #endif -#define MEM_BLOCK_MASK (MEM_BLOCK_NR-1) +#define MEM_BLOCK_MASK (MEM_BLOCK_NR - 1) #define MEM_BLOCK_SIZE 0x3c0 void codegen_allocator_init(); diff --git a/includes/private/codegen/codegen_backend.h b/includes/private/codegen/codegen_backend.h index 5cbaf672..ac53d3ca 100644 --- a/includes/private/codegen/codegen_backend.h +++ b/includes/private/codegen/codegen_backend.h @@ -31,8 +31,7 @@ extern const uOpFn uop_handlers[]; /*Register will not be preserved across function calls*/ #define HOST_REG_FLAG_VOLATILE (1 << 0) -typedef struct host_reg_def_t -{ +typedef struct host_reg_def_t { int reg; int flags; } host_reg_def_t; diff --git a/includes/private/codegen/codegen_backend_arm.h b/includes/private/codegen/codegen_backend_arm.h index 4152dd46..ccfd0573 100644 --- a/includes/private/codegen/codegen_backend_arm.h +++ b/includes/private/codegen/codegen_backend_arm.h @@ -10,7 +10,7 @@ #define HASH_SIZE 0x20000 #define HASH_MASK 0x1ffff -#define HASH(l) ((l) & 0x1ffff) +#define HASH(l) ((l)&0x1ffff) #define BLOCK_MAX 0x3c0 @@ -26,5 +26,4 @@ void host_arm_nop(codeblock_t *block); void codegen_alloc(codeblock_t *block, int size); - #endif /* _CODEGEN_BACKEND_ARM_H_ */ diff --git a/includes/private/codegen/codegen_backend_arm64.h b/includes/private/codegen/codegen_backend_arm64.h index 619f0f78..b036b69d 100644 --- a/includes/private/codegen/codegen_backend_arm64.h +++ b/includes/private/codegen/codegen_backend_arm64.h @@ -10,11 +10,10 @@ #define HASH_SIZE 0x20000 #define HASH_MASK 0x1ffff -#define HASH(l) ((l) & 0x1ffff) +#define HASH(l) ((l)&0x1ffff) #define BLOCK_MAX 0x3c0 - void host_arm64_BLR(codeblock_t *block, int addr_reg); void host_arm64_CBNZ(codeblock_t *block, int reg, uintptr_t dest); void host_arm64_MOVK_IMM(codeblock_t *block, int reg, uint32_t imm_data); @@ -33,5 +32,4 @@ void host_arm64_mov_imm(codeblock_t *block, int reg, uint32_t imm_data); uint32_t host_arm64_find_imm(uint32_t data); - #endif /* _CODEGEN_BACKEND_ARM64_H_ */ diff --git a/includes/private/codegen/codegen_backend_arm64_defs.h b/includes/private/codegen/codegen_backend_arm64_defs.h index 15408cff..7ad22007 100644 --- a/includes/private/codegen/codegen_backend_arm64_defs.h +++ b/includes/private/codegen/codegen_backend_arm64_defs.h @@ -1,16 +1,16 @@ #ifndef _CODEGEN_BACKEND_ARM64_DEFS_H_ #define _CODEGEN_BACKEND_ARM64_DEFS_H_ -#define REG_W0 0 -#define REG_W1 1 -#define REG_W2 2 -#define REG_W3 3 -#define REG_W4 4 -#define REG_W5 5 -#define REG_W6 6 -#define REG_W7 7 -#define REG_W8 8 -#define REG_W9 9 +#define REG_W0 0 +#define REG_W1 1 +#define REG_W2 2 +#define REG_W3 3 +#define REG_W4 4 +#define REG_W5 5 +#define REG_W6 6 +#define REG_W7 7 +#define REG_W8 8 +#define REG_W9 9 #define REG_W10 10 #define REG_W11 11 #define REG_W12 12 @@ -34,16 +34,16 @@ #define REG_W30 30 #define REG_WZR 31 -#define REG_X0 0 -#define REG_X1 1 -#define REG_X2 2 -#define REG_X3 3 -#define REG_X4 4 -#define REG_X5 5 -#define REG_X6 6 -#define REG_X7 7 -#define REG_X8 8 -#define REG_X9 9 +#define REG_X0 0 +#define REG_X1 1 +#define REG_X2 2 +#define REG_X3 3 +#define REG_X4 4 +#define REG_X5 5 +#define REG_X6 6 +#define REG_X7 7 +#define REG_X8 8 +#define REG_X9 9 #define REG_X10 10 #define REG_X11 11 #define REG_X12 12 @@ -67,16 +67,16 @@ #define REG_X30 30 #define REG_XZR 31 -#define REG_V0 0 -#define REG_V1 1 -#define REG_V2 2 -#define REG_V3 3 -#define REG_V4 4 -#define REG_V5 5 -#define REG_V6 6 -#define REG_V7 7 -#define REG_V8 8 -#define REG_V9 9 +#define REG_V0 0 +#define REG_V1 1 +#define REG_V2 2 +#define REG_V3 3 +#define REG_V4 4 +#define REG_V5 5 +#define REG_V6 6 +#define REG_V7 7 +#define REG_V8 8 +#define REG_V9 9 #define REG_V10 10 #define REG_V11 11 #define REG_V12 12 @@ -109,7 +109,7 @@ #define REG_CPUSTATE REG_X29 -#define REG_TEMP REG_X7 +#define REG_TEMP REG_X7 #define REG_TEMP2 REG_X6 #define REG_V_TEMP REG_V0 @@ -137,5 +137,4 @@ extern void *codegen_fp_round_quad; extern void *codegen_gpf_rout; extern void *codegen_exit_rout; - #endif /* _CODEGEN_BACKEND_ARM64_DEFS_H_ */ diff --git a/includes/private/codegen/codegen_backend_arm64_ops.h b/includes/private/codegen/codegen_backend_arm64_ops.h index cbaf9d5f..98270e42 100644 --- a/includes/private/codegen/codegen_backend_arm64_ops.h +++ b/includes/private/codegen/codegen_backend_arm64_ops.h @@ -254,17 +254,14 @@ void host_arm64_call(codeblock_t *block, void *dst_addr); void host_arm64_jump(codeblock_t *block, uintptr_t dst_addr); void host_arm64_mov_imm(codeblock_t *block, int reg, uint32_t imm_data); - -#define in_range7_x(offset) (((offset) >= -0x200) && ((offset) < (0x200)) && !((offset) & 7)) +#define in_range7_x(offset) (((offset) >= -0x200) && ((offset) < (0x200)) && !((offset)&7)) #define in_range12_b(offset) (((offset) >= 0) && ((offset) < 0x1000)) -#define in_range12_h(offset) (((offset) >= 0) && ((offset) < 0x2000) && !((offset) & 1)) -#define in_range12_w(offset) (((offset) >= 0) && ((offset) < 0x4000) && !((offset) & 3)) -#define in_range12_q(offset) (((offset) >= 0) && ((offset) < 0x8000) && !((offset) & 7)) - +#define in_range12_h(offset) (((offset) >= 0) && ((offset) < 0x2000) && !((offset)&1)) +#define in_range12_w(offset) (((offset) >= 0) && ((offset) < 0x4000) && !((offset)&3)) +#define in_range12_q(offset) (((offset) >= 0) && ((offset) < 0x8000) && !((offset)&7)) void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p); void codegen_alloc(codeblock_t *block, int size); - #endif /* _CODEGEN_BACKEND_ARM64_OPS_H_ */ diff --git a/includes/private/codegen/codegen_backend_arm_defs.h b/includes/private/codegen/codegen_backend_arm_defs.h index e5b88ba3..258aef27 100644 --- a/includes/private/codegen/codegen_backend_arm_defs.h +++ b/includes/private/codegen/codegen_backend_arm_defs.h @@ -1,22 +1,22 @@ #ifndef _CODEGEN_BACKEND_ARM_DEFS_H_ #define _CODEGEN_BACKEND_ARM_DEFS_H_ -#define REG_R0 0 -#define REG_R1 1 -#define REG_R2 2 -#define REG_R3 3 -#define REG_R4 4 -#define REG_R5 5 -#define REG_R6 6 -#define REG_R7 7 -#define REG_R8 8 -#define REG_R9 9 +#define REG_R0 0 +#define REG_R1 1 +#define REG_R2 2 +#define REG_R3 3 +#define REG_R4 4 +#define REG_R5 5 +#define REG_R6 6 +#define REG_R7 7 +#define REG_R8 8 +#define REG_R9 9 #define REG_R10 10 #define REG_R11 11 #define REG_R12 12 -#define REG_HOST_SP 13 -#define REG_LR 14 -#define REG_PC 15 +#define REG_HOST_SP 13 +#define REG_LR 14 +#define REG_PC 15 #define REG_ARG0 REG_R0 #define REG_ARG1 REG_R1 @@ -25,19 +25,19 @@ #define REG_CPUSTATE REG_R10 -#define REG_TEMP REG_R3 +#define REG_TEMP REG_R3 #define REG_TEMP2 REG_R2 -#define REG_D0 0 -#define REG_D1 1 -#define REG_D2 2 -#define REG_D3 3 -#define REG_D4 4 -#define REG_D5 5 -#define REG_D6 6 -#define REG_D7 7 -#define REG_D8 8 -#define REG_D9 9 +#define REG_D0 0 +#define REG_D1 1 +#define REG_D2 2 +#define REG_D3 3 +#define REG_D4 4 +#define REG_D5 5 +#define REG_D6 6 +#define REG_D7 7 +#define REG_D8 8 +#define REG_D9 9 #define REG_D10 10 #define REG_D11 11 #define REG_D12 12 @@ -46,28 +46,28 @@ #define REG_D15 15 #define REG_D_TEMP REG_D0 -#define REG_Q_TEMP REG_D0 +#define REG_Q_TEMP REG_D0 #define REG_Q_TEMP_2 REG_D2 -#define REG_MASK_R0 (1 << REG_R0) -#define REG_MASK_R1 (1 << REG_R1) -#define REG_MASK_R2 (1 << REG_R2) -#define REG_MASK_R3 (1 << REG_R3) -#define REG_MASK_R4 (1 << REG_R4) -#define REG_MASK_R5 (1 << REG_R5) -#define REG_MASK_R6 (1 << REG_R6) -#define REG_MASK_R7 (1 << REG_R7) -#define REG_MASK_R8 (1 << REG_R8) -#define REG_MASK_R9 (1 << REG_R9) +#define REG_MASK_R0 (1 << REG_R0) +#define REG_MASK_R1 (1 << REG_R1) +#define REG_MASK_R2 (1 << REG_R2) +#define REG_MASK_R3 (1 << REG_R3) +#define REG_MASK_R4 (1 << REG_R4) +#define REG_MASK_R5 (1 << REG_R5) +#define REG_MASK_R6 (1 << REG_R6) +#define REG_MASK_R7 (1 << REG_R7) +#define REG_MASK_R8 (1 << REG_R8) +#define REG_MASK_R9 (1 << REG_R9) #define REG_MASK_R10 (1 << REG_R10) #define REG_MASK_R11 (1 << REG_R11) #define REG_MASK_R12 (1 << REG_R12) -#define REG_MASK_SP (1 << REG_HOST_SP) -#define REG_MASK_LR (1 << REG_LR) -#define REG_MASK_PC (1 << REG_PC) +#define REG_MASK_SP (1 << REG_HOST_SP) +#define REG_MASK_LR (1 << REG_LR) +#define REG_MASK_PC (1 << REG_PC) -#define REG_MASK_LOCAL (REG_MASK_R4 | REG_MASK_R5 | REG_MASK_R6 | REG_MASK_R7 | \ - REG_MASK_R8 | REG_MASK_R9 | REG_MASK_R10 | REG_MASK_R11) +#define REG_MASK_LOCAL \ + (REG_MASK_R4 | REG_MASK_R5 | REG_MASK_R6 | REG_MASK_R7 | REG_MASK_R8 | REG_MASK_R9 | REG_MASK_R10 | REG_MASK_R11) #define CODEGEN_HOST_REGS 7 #define CODEGEN_HOST_FP_REGS 8 @@ -91,5 +91,4 @@ extern void *codegen_fp_round; extern void *codegen_gpf_rout; extern void *codegen_exit_rout; - #endif /* _CODEGEN_BACKEND_ARM_DEFS_H_ */ diff --git a/includes/private/codegen/codegen_backend_arm_ops.h b/includes/private/codegen/codegen_backend_arm_ops.h index 46d768af..7ebd4154 100644 --- a/includes/private/codegen/codegen_backend_arm_ops.h +++ b/includes/private/codegen/codegen_backend_arm_ops.h @@ -105,7 +105,8 @@ void host_arm_ORR_IMM_cond(codeblock_t *block, uint32_t cond, int dst_reg, int s void host_arm_ORR_REG_LSL_cond(codeblock_t *block, uint32_t cond, int dst_reg, int src_reg_n, int src_reg_m, int shift); #define host_arm_ORR_IMM(block, dst_reg, src_reg, imm) host_arm_ORR_IMM_cond(block, COND_AL, dst_reg, src_reg, imm) -#define host_arm_ORR_REG_LSL(block, dst_reg, src_reg_a, src_reg_b, shift) host_arm_ORR_REG_LSL_cond(block, COND_AL, dst_reg, src_reg_a, src_reg_b, shift) +#define host_arm_ORR_REG_LSL(block, dst_reg, src_reg_a, src_reg_b, shift) \ + host_arm_ORR_REG_LSL_cond(block, COND_AL, dst_reg, src_reg_a, src_reg_b, shift) #define host_arm_ORRCC_IMM(block, dst_reg, src_reg, imm) host_arm_ORR_IMM_cond(block, COND_CC, dst_reg, src_reg, imm) #define host_arm_ORREQ_IMM(block, dst_reg, src_reg, imm) host_arm_ORR_IMM_cond(block, COND_EQ, dst_reg, src_reg, imm) @@ -254,5 +255,4 @@ void host_arm_VZIP_D8(codeblock_t *block, int d_reg, int m_reg); void host_arm_VZIP_D16(codeblock_t *block, int d_reg, int m_reg); void host_arm_VZIP_D32(codeblock_t *block, int d_reg, int m_reg); - #endif /* _CODEGEN_BACKEND_ARM_OPS_H_ */ diff --git a/includes/private/codegen/codegen_backend_x86-64.h b/includes/private/codegen/codegen_backend_x86-64.h index f2723085..f60604df 100644 --- a/includes/private/codegen/codegen_backend_x86-64.h +++ b/includes/private/codegen/codegen_backend_x86-64.h @@ -10,11 +10,10 @@ #define HASH_SIZE 0x20000 #define HASH_MASK 0x1ffff -#define HASH(l) ((l) & 0x1ffff) +#define HASH(l) ((l)&0x1ffff) #define BLOCK_MAX 0x3c0 #define CODEGEN_BACKEND_HAS_MOV_IMM - #endif /* _CODEGEN_BACKEND_X86_64_H_ */ diff --git a/includes/private/codegen/codegen_backend_x86-64_defs.h b/includes/private/codegen/codegen_backend_x86-64_defs.h index dc0df7f3..1f38114f 100644 --- a/includes/private/codegen/codegen_backend_x86-64_defs.h +++ b/includes/private/codegen/codegen_backend_x86-64_defs.h @@ -30,8 +30,8 @@ #define REG_RBP 5 #define REG_RSI 6 #define REG_RDI 7 -#define REG_R8 8 -#define REG_R9 9 +#define REG_R8 8 +#define REG_R9 9 #define REG_R10 10 #define REG_R11 11 #define REG_R12 12 @@ -70,5 +70,4 @@ extern void *codegen_mem_store_double; extern void *codegen_gpf_rout; extern void *codegen_exit_rout; - #endif /* _CODEGEN_BACKEND_X86_64_DEFS_H_ */ diff --git a/includes/private/codegen/codegen_backend_x86-64_ops.h b/includes/private/codegen/codegen_backend_x86-64_ops.h index 815e5142..89e92fc6 100644 --- a/includes/private/codegen/codegen_backend_x86-64_ops.h +++ b/includes/private/codegen/codegen_backend_x86-64_ops.h @@ -198,5 +198,4 @@ void host_x86_XOR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_XOR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_XOR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg); - #endif /* _CODEGEN_BACKEND_X86_64_OPS_H_ */ diff --git a/includes/private/codegen/codegen_backend_x86-64_ops_helpers.h b/includes/private/codegen/codegen_backend_x86-64_ops_helpers.h index e42b5f11..1735b6fa 100644 --- a/includes/private/codegen/codegen_backend_x86-64_ops_helpers.h +++ b/includes/private/codegen/codegen_backend_x86-64_ops_helpers.h @@ -3,29 +3,23 @@ #define JMP_LEN_BYTES 5 -static inline void codegen_addbyte(codeblock_t *block, uint8_t val) -{ - if (block_pos >= BLOCK_MAX) - { +static inline void codegen_addbyte(codeblock_t *block, uint8_t val) { + if (block_pos >= BLOCK_MAX) { fatal("codegen_addbyte over! %i\n", block_pos); -// CPU_BLOCK_END(); + // CPU_BLOCK_END(); } block_write_data[block_pos++] = val; } -static inline void codegen_addbyte2(codeblock_t *block, uint8_t vala, uint8_t valb) -{ - if (block_pos > (BLOCK_MAX-2)) - { +static inline void codegen_addbyte2(codeblock_t *block, uint8_t vala, uint8_t valb) { + if (block_pos > (BLOCK_MAX - 2)) { fatal("codegen_addbyte2 over! %i\n", block_pos); CPU_BLOCK_END(); } block_write_data[block_pos++] = vala; block_write_data[block_pos++] = valb; } -static inline void codegen_addbyte3(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc) -{ - if (block_pos > (BLOCK_MAX-3)) - { +static inline void codegen_addbyte3(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc) { + if (block_pos > (BLOCK_MAX - 3)) { fatal("codegen_addbyte3 over! %i\n", block_pos); CPU_BLOCK_END(); } @@ -33,10 +27,8 @@ static inline void codegen_addbyte3(codeblock_t *block, uint8_t vala, uint8_t va block_write_data[block_pos++] = valb; block_write_data[block_pos++] = valc; } -static inline void codegen_addbyte4(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc, uint8_t vald) -{ - if (block_pos > (BLOCK_MAX-4)) - { +static inline void codegen_addbyte4(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc, uint8_t vald) { + if (block_pos > (BLOCK_MAX - 4)) { fatal("codegen_addbyte4 over! %i\n", block_pos); CPU_BLOCK_END(); } @@ -46,10 +38,8 @@ static inline void codegen_addbyte4(codeblock_t *block, uint8_t vala, uint8_t va block_write_data[block_pos++] = vald; } -static inline void codegen_addword(codeblock_t *block, uint16_t val) -{ - if (block_pos > (BLOCK_MAX-2)) - { +static inline void codegen_addword(codeblock_t *block, uint16_t val) { + if (block_pos > (BLOCK_MAX - 2)) { fatal("codegen_addword over! %i\n", block_pos); CPU_BLOCK_END(); } @@ -57,10 +47,8 @@ static inline void codegen_addword(codeblock_t *block, uint16_t val) block_pos += 2; } -static inline void codegen_addlong(codeblock_t *block, uint32_t val) -{ - if (block_pos > (BLOCK_MAX-4)) - { +static inline void codegen_addlong(codeblock_t *block, uint32_t val) { + if (block_pos > (BLOCK_MAX - 4)) { fatal("codegen_addlong over! %i\n", block_pos); CPU_BLOCK_END(); } @@ -68,10 +56,8 @@ static inline void codegen_addlong(codeblock_t *block, uint32_t val) block_pos += 4; } -static inline void codegen_addquad(codeblock_t *block, uint64_t val) -{ - if (block_pos > (BLOCK_MAX-8)) - { +static inline void codegen_addquad(codeblock_t *block, uint64_t val) { + if (block_pos > (BLOCK_MAX - 8)) { fatal("codegen_addquad over! %i\n", block_pos); CPU_BLOCK_END(); } @@ -79,10 +65,8 @@ static inline void codegen_addquad(codeblock_t *block, uint64_t val) block_pos += 8; } -static inline void codegen_alloc_bytes(codeblock_t *block, int size) -{ - if (block_pos > ((BLOCK_MAX - size) - JMP_LEN_BYTES)) - { +static inline void codegen_alloc_bytes(codeblock_t *block, int size) { + if (block_pos > ((BLOCK_MAX - size) - JMP_LEN_BYTES)) { /*Current block is full. Allocate a new block*/ struct mem_block_t *new_block = codegen_allocator_allocate(block->head_mem_block, get_block_nr(block)); uint8_t *new_ptr = codeblock_allocator_get_ptr(new_block); @@ -97,12 +81,10 @@ static inline void codegen_alloc_bytes(codeblock_t *block, int size) } } -static inline int is_imm8(uint32_t imm_data) -{ +static inline int is_imm8(uint32_t imm_data) { if (imm_data <= 0x7f || imm_data >= 0xffffff80) return 1; return 0; } - #endif /* _CODEGEN_BACKEND_X86_64_OPS_HELPERS_H_ */ diff --git a/includes/private/codegen/codegen_backend_x86-64_ops_sse.h b/includes/private/codegen/codegen_backend_x86-64_ops_sse.h index 80636a5c..af34f1fc 100644 --- a/includes/private/codegen/codegen_backend_x86-64_ops_sse.h +++ b/includes/private/codegen/codegen_backend_x86-64_ops_sse.h @@ -4,7 +4,7 @@ void host_x86_ADDPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_ADDSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -#define CMPPS_EQ 0 +#define CMPPS_EQ 0 #define CMPPS_NLT 5 #define CMPPS_NLE 6 void host_x86_CMPPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg, int type); @@ -36,11 +36,13 @@ void host_x86_MOVD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg void host_x86_MOVD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MOVQ_ABS_XREG(codeblock_t *block, void *p, int src_reg); -void host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(codeblock_t *block, uint32_t addr, int src_reg_a, int src_reg_b, int shift, int src_reg); +void host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(codeblock_t *block, uint32_t addr, int src_reg_a, int src_reg_b, int shift, + int src_reg); void host_x86_MOVQ_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg); void host_x86_MOVQ_BASE_OFFSET_XREG(codeblock_t *block, int base_reg, int offset, int src_reg); void host_x86_MOVQ_XREG_ABS(codeblock_t *block, int dst_reg, void *p); -void host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int src_reg_a, int src_reg_b, int shift); +void host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int src_reg_a, int src_reg_b, + int shift); void host_x86_MOVQ_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg); void host_x86_MOVQ_XREG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset); @@ -116,5 +118,4 @@ void host_x86_SUBSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_UNPCKLPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); - #endif /* _CODEGEN_BACKEND_X86_64_OPS_SSE_H_ */ diff --git a/includes/private/codegen/codegen_backend_x86.h b/includes/private/codegen/codegen_backend_x86.h index 13917f5d..2799916b 100644 --- a/includes/private/codegen/codegen_backend_x86.h +++ b/includes/private/codegen/codegen_backend_x86.h @@ -10,11 +10,10 @@ #define HASH_SIZE 0x20000 #define HASH_MASK 0x1ffff -#define HASH(l) ((l) & 0x1ffff) +#define HASH(l) ((l)&0x1ffff) #define BLOCK_MAX 0x3c0 #define CODEGEN_BACKEND_HAS_MOV_IMM - #endif /* _CODEGEN_BACKEND_X86_H_ */ diff --git a/includes/private/codegen/codegen_backend_x86_defs.h b/includes/private/codegen/codegen_backend_x86_defs.h index ae44e676..043574c7 100644 --- a/includes/private/codegen/codegen_backend_x86_defs.h +++ b/includes/private/codegen/codegen_backend_x86_defs.h @@ -19,7 +19,7 @@ #define REG_XMM6 6 #define REG_XMM7 7 -#define REG_XMM_TEMP REG_XMM7 +#define REG_XMM_TEMP REG_XMM7 #define REG_XMM_TEMP2 REG_XMM6 #define CODEGEN_HOST_REGS 3 diff --git a/includes/private/codegen/codegen_backend_x86_ops.h b/includes/private/codegen/codegen_backend_x86_ops.h index 9549afe5..9c049eae 100644 --- a/includes/private/codegen/codegen_backend_x86_ops.h +++ b/includes/private/codegen/codegen_backend_x86_ops.h @@ -197,5 +197,4 @@ void host_x86_XOR8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data); void host_x86_XOR16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data); void host_x86_XOR32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data); - #endif /* _CODEGEN_BACKEND_X86_OPS_H_ */ diff --git a/includes/private/codegen/codegen_backend_x86_ops_fpu.h b/includes/private/codegen/codegen_backend_x86_ops_fpu.h index 0fffc4a9..5c1848d7 100644 --- a/includes/private/codegen/codegen_backend_x86_ops_fpu.h +++ b/includes/private/codegen/codegen_backend_x86_ops_fpu.h @@ -7,5 +7,4 @@ void host_x87_FLDCW(codeblock_t *block, void *p); void host_x87_FLDd_BASE(codeblock_t *block, int base_reg); void host_x87_FSTPd_BASE(codeblock_t *block, int base_reg); - #endif /* _CODEGEN_BACKEND_X86_OPS_FPU_H_ */ diff --git a/includes/private/codegen/codegen_backend_x86_ops_helpers.h b/includes/private/codegen/codegen_backend_x86_ops_helpers.h index 0d4f183a..7f350ef7 100644 --- a/includes/private/codegen/codegen_backend_x86_ops_helpers.h +++ b/includes/private/codegen/codegen_backend_x86_ops_helpers.h @@ -3,30 +3,26 @@ #define JMP_LEN_BYTES 5 -static inline void codegen_addbyte(codeblock_t *block, uint8_t val) -{ +static inline void codegen_addbyte(codeblock_t *block, uint8_t val) { if (block_pos >= BLOCK_MAX) fatal("codegen_addbyte over! %i\n", block_pos); block_write_data[block_pos++] = val; } -static inline void codegen_addbyte2(codeblock_t *block, uint8_t vala, uint8_t valb) -{ - if (block_pos > (BLOCK_MAX-2)) +static inline void codegen_addbyte2(codeblock_t *block, uint8_t vala, uint8_t valb) { + if (block_pos > (BLOCK_MAX - 2)) fatal("codegen_addbyte2 over! %i\n", block_pos); block_write_data[block_pos++] = vala; block_write_data[block_pos++] = valb; } -static inline void codegen_addbyte3(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc) -{ - if (block_pos > (BLOCK_MAX-3)) +static inline void codegen_addbyte3(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc) { + if (block_pos > (BLOCK_MAX - 3)) fatal("codegen_addbyte3 over! %i\n", block_pos); block_write_data[block_pos++] = vala; block_write_data[block_pos++] = valb; block_write_data[block_pos++] = valc; } -static inline void codegen_addbyte4(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc, uint8_t vald) -{ - if (block_pos > (BLOCK_MAX-4)) +static inline void codegen_addbyte4(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc, uint8_t vald) { + if (block_pos > (BLOCK_MAX - 4)) fatal("codegen_addbyte4 over! %i\n", block_pos); block_write_data[block_pos++] = vala; block_write_data[block_pos++] = valb; @@ -34,32 +30,28 @@ static inline void codegen_addbyte4(codeblock_t *block, uint8_t vala, uint8_t va block_write_data[block_pos++] = vald; } -static inline void codegen_addword(codeblock_t *block, uint16_t val) -{ - if (block_pos > (BLOCK_MAX-2)) +static inline void codegen_addword(codeblock_t *block, uint16_t val) { + if (block_pos > (BLOCK_MAX - 2)) fatal("codegen_addword over! %i\n", block_pos); *(uint16_t *)&block_write_data[block_pos] = val; block_pos += 2; } -static inline void codegen_addlong(codeblock_t *block, uint32_t val) -{ - if (block_pos > (BLOCK_MAX-4)) +static inline void codegen_addlong(codeblock_t *block, uint32_t val) { + if (block_pos > (BLOCK_MAX - 4)) fatal("codegen_addlong over! %i\n", block_pos); *(uint32_t *)&block_write_data[block_pos] = val; block_pos += 4; } -static inline void codegen_addquad(codeblock_t *block, uint64_t val) -{ - if (block_pos > (BLOCK_MAX-8)) +static inline void codegen_addquad(codeblock_t *block, uint64_t val) { + if (block_pos > (BLOCK_MAX - 8)) fatal("codegen_addquad over! %i\n", block_pos); *(uint64_t *)&block_write_data[block_pos] = val; block_pos += 8; } -static void codegen_allocate_new_block(codeblock_t *block) -{ +static void codegen_allocate_new_block(codeblock_t *block) { /*Current block is full. Allocate a new block*/ struct mem_block_t *new_block = codegen_allocator_allocate(block->head_mem_block, get_block_nr(block)); uint8_t *new_ptr = codeblock_allocator_get_ptr(new_block); @@ -73,18 +65,15 @@ static void codegen_allocate_new_block(codeblock_t *block) block_write_data = new_ptr; } -static inline void codegen_alloc_bytes(codeblock_t *block, int size) -{ +static inline void codegen_alloc_bytes(codeblock_t *block, int size) { if (block_pos > ((BLOCK_MAX - size) - JMP_LEN_BYTES)) codegen_allocate_new_block(block); } -static inline int is_imm8(uint32_t imm_data) -{ +static inline int is_imm8(uint32_t imm_data) { if (imm_data <= 0x7f || imm_data >= 0xffffff80) return 1; return 0; } - #endif /* _CODEGEN_BACKEND_X86_OPS_HELPERS_H_ */ diff --git a/includes/private/codegen/codegen_backend_x86_ops_sse.h b/includes/private/codegen/codegen_backend_x86_ops_sse.h index 6e6966b5..8c84e849 100644 --- a/includes/private/codegen/codegen_backend_x86_ops_sse.h +++ b/includes/private/codegen/codegen_backend_x86_ops_sse.h @@ -4,7 +4,7 @@ void host_x86_ADDPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_ADDSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -#define CMPPS_EQ 0 +#define CMPPS_EQ 0 #define CMPPS_NLT 5 #define CMPPS_NLE 6 void host_x86_CMPPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg, int type); @@ -36,13 +36,15 @@ void host_x86_MOVD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg void host_x86_MOVD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_MOVQ_ABS_XREG(codeblock_t *block, void *p, int src_reg); -void host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(codeblock_t *block, uint32_t addr, int src_reg_a, int src_reg_b, int shift, int src_reg); +void host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(codeblock_t *block, uint32_t addr, int src_reg_a, int src_reg_b, int shift, + int src_reg); void host_x86_MOVQ_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg); void host_x86_MOVQ_BASE_OFFSET_XREG(codeblock_t *block, int base_reg, int offset, int src_reg); void host_x86_MOVQ_STACK_OFFSET_XREG(codeblock_t *block, int offset, int src_reg); void host_x86_MOVQ_XREG_ABS(codeblock_t *block, int dst_reg, void *p); -void host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int src_reg_a, int src_reg_b, int shift); +void host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int src_reg_a, int src_reg_b, + int shift); void host_x86_MOVQ_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg); void host_x86_MOVQ_XREG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset); void host_x86_MOVQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); @@ -113,5 +115,4 @@ void host_x86_SUBSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); void host_x86_UNPCKLPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); - #endif /* _CODEGEN_BACKEND_X86_OPS_SSE_H_ */ diff --git a/includes/private/codegen/codegen_ir.h b/includes/private/codegen/codegen_ir.h index 4d0a6e1a..91a00a14 100644 --- a/includes/private/codegen/codegen_ir.h +++ b/includes/private/codegen/codegen_ir.h @@ -8,5 +8,4 @@ ir_data_t *codegen_ir_init(); void codegen_ir_set_unroll(int count, int start, int first_instruction); void codegen_ir_compile(ir_data_t *ir, codeblock_t *block); - #endif /* _CODEGEN_IR_H_ */ diff --git a/includes/private/codegen/codegen_ir_defs.h b/includes/private/codegen/codegen_ir_defs.h index 609ab4d0..d16c17ef 100644 --- a/includes/private/codegen/codegen_ir_defs.h +++ b/includes/private/codegen/codegen_ir_defs.h @@ -18,313 +18,327 @@ #define UOP_TYPE_ORDER_BARRIER (1 << 27) /*uOP uses source and dest registers*/ -#define UOP_TYPE_PARAMS_REGS (1 << 28) +#define UOP_TYPE_PARAMS_REGS (1 << 28) /*uOP uses pointer*/ #define UOP_TYPE_PARAMS_POINTER (1 << 29) /*uOP uses immediate data*/ -#define UOP_TYPE_PARAMS_IMM (1 << 30) +#define UOP_TYPE_PARAMS_IMM (1 << 30) /*uOP is a jump, with the destination uOP in uop->jump_dest_uop. The compiler must set jump_dest in the destination uOP to the address of the branch offset to be written when known.*/ -#define UOP_TYPE_JUMP (1 << 26) +#define UOP_TYPE_JUMP (1 << 26) /*uOP is the destination of a jump, and must set the destination offset of the jump at compile time.*/ -#define UOP_TYPE_JUMP_DEST (1 << 25) +#define UOP_TYPE_JUMP_DEST (1 << 25) - -#define UOP_LOAD_FUNC_ARG_0 (UOP_TYPE_PARAMS_REGS | 0x00) -#define UOP_LOAD_FUNC_ARG_1 (UOP_TYPE_PARAMS_REGS | 0x01) -#define UOP_LOAD_FUNC_ARG_2 (UOP_TYPE_PARAMS_REGS | 0x02) -#define UOP_LOAD_FUNC_ARG_3 (UOP_TYPE_PARAMS_REGS | 0x03) -#define UOP_LOAD_FUNC_ARG_0_IMM (UOP_TYPE_PARAMS_IMM | 0x08 | UOP_TYPE_BARRIER) -#define UOP_LOAD_FUNC_ARG_1_IMM (UOP_TYPE_PARAMS_IMM | 0x09 | UOP_TYPE_BARRIER) -#define UOP_LOAD_FUNC_ARG_2_IMM (UOP_TYPE_PARAMS_IMM | 0x0a | UOP_TYPE_BARRIER) -#define UOP_LOAD_FUNC_ARG_3_IMM (UOP_TYPE_PARAMS_IMM | 0x0b | UOP_TYPE_BARRIER) -#define UOP_CALL_FUNC (UOP_TYPE_PARAMS_POINTER | 0x10 | UOP_TYPE_BARRIER) +#define UOP_LOAD_FUNC_ARG_0 (UOP_TYPE_PARAMS_REGS | 0x00) +#define UOP_LOAD_FUNC_ARG_1 (UOP_TYPE_PARAMS_REGS | 0x01) +#define UOP_LOAD_FUNC_ARG_2 (UOP_TYPE_PARAMS_REGS | 0x02) +#define UOP_LOAD_FUNC_ARG_3 (UOP_TYPE_PARAMS_REGS | 0x03) +#define UOP_LOAD_FUNC_ARG_0_IMM (UOP_TYPE_PARAMS_IMM | 0x08 | UOP_TYPE_BARRIER) +#define UOP_LOAD_FUNC_ARG_1_IMM (UOP_TYPE_PARAMS_IMM | 0x09 | UOP_TYPE_BARRIER) +#define UOP_LOAD_FUNC_ARG_2_IMM (UOP_TYPE_PARAMS_IMM | 0x0a | UOP_TYPE_BARRIER) +#define UOP_LOAD_FUNC_ARG_3_IMM (UOP_TYPE_PARAMS_IMM | 0x0b | UOP_TYPE_BARRIER) +#define UOP_CALL_FUNC (UOP_TYPE_PARAMS_POINTER | 0x10 | UOP_TYPE_BARRIER) /*UOP_CALL_INSTRUCTION_FUNC - call instruction handler at p, check return value and exit block if non-zero*/ #define UOP_CALL_INSTRUCTION_FUNC (UOP_TYPE_PARAMS_POINTER | 0x11 | UOP_TYPE_BARRIER) -#define UOP_STORE_P_IMM (UOP_TYPE_PARAMS_IMM | 0x12) -#define UOP_STORE_P_IMM_8 (UOP_TYPE_PARAMS_IMM | 0x13) +#define UOP_STORE_P_IMM (UOP_TYPE_PARAMS_IMM | 0x12) +#define UOP_STORE_P_IMM_8 (UOP_TYPE_PARAMS_IMM | 0x13) /*UOP_LOAD_SEG - load segment in src_reg_a to segment p via loadseg(), check return value and exit block if non-zero*/ -#define UOP_LOAD_SEG (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x14 | UOP_TYPE_BARRIER) +#define UOP_LOAD_SEG (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x14 | UOP_TYPE_BARRIER) /*UOP_JMP - jump to ptr*/ -#define UOP_JMP (UOP_TYPE_PARAMS_POINTER | 0x15 | UOP_TYPE_ORDER_BARRIER) +#define UOP_JMP (UOP_TYPE_PARAMS_POINTER | 0x15 | UOP_TYPE_ORDER_BARRIER) /*UOP_CALL_FUNC - call instruction handler at p, dest_reg = return value*/ -#define UOP_CALL_FUNC_RESULT (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x16 | UOP_TYPE_BARRIER) +#define UOP_CALL_FUNC_RESULT (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x16 | UOP_TYPE_BARRIER) /*UOP_JMP_DEST - jump to ptr*/ -#define UOP_JMP_DEST (UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x17 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) -#define UOP_NOP_BARRIER (UOP_TYPE_BARRIER | 0x18) -#define UOP_STORE_P_IMM_16 (UOP_TYPE_PARAMS_IMM | 0x19) +#define UOP_JMP_DEST (UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x17 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +#define UOP_NOP_BARRIER (UOP_TYPE_BARRIER | 0x18) +#define UOP_STORE_P_IMM_16 (UOP_TYPE_PARAMS_IMM | 0x19) #ifdef DEBUG_EXTRA /*UOP_LOG_INSTR - log non-recompiled instruction in imm_data*/ -#define UOP_LOG_INSTR (UOP_TYPE_PARAMS_IMM | 0x1f) +#define UOP_LOG_INSTR (UOP_TYPE_PARAMS_IMM | 0x1f) #endif /*UOP_MOV_PTR - dest_reg = p*/ -#define UOP_MOV_PTR (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x20) +#define UOP_MOV_PTR (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x20) /*UOP_MOV_IMM - dest_reg = imm_data*/ -#define UOP_MOV_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x21) +#define UOP_MOV_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x21) /*UOP_MOV - dest_reg = src_reg_a*/ -#define UOP_MOV (UOP_TYPE_PARAMS_REGS | 0x22) +#define UOP_MOV (UOP_TYPE_PARAMS_REGS | 0x22) /*UOP_MOVZX - dest_reg = zero_extend(src_reg_a)*/ -#define UOP_MOVZX (UOP_TYPE_PARAMS_REGS | 0x23) +#define UOP_MOVZX (UOP_TYPE_PARAMS_REGS | 0x23) /*UOP_MOVSX - dest_reg = sign_extend(src_reg_a)*/ -#define UOP_MOVSX (UOP_TYPE_PARAMS_REGS | 0x24) +#define UOP_MOVSX (UOP_TYPE_PARAMS_REGS | 0x24) /*UOP_MOV_DOUBLE_INT - dest_reg = (double)src_reg_a*/ -#define UOP_MOV_DOUBLE_INT (UOP_TYPE_PARAMS_REGS | 0x25) +#define UOP_MOV_DOUBLE_INT (UOP_TYPE_PARAMS_REGS | 0x25) /*UOP_MOV_INT_DOUBLE - dest_reg = (int)src_reg_a. New rounding control in src_reg_b, old rounding control in src_reg_c*/ -#define UOP_MOV_INT_DOUBLE (UOP_TYPE_PARAMS_REGS | 0x26) +#define UOP_MOV_INT_DOUBLE (UOP_TYPE_PARAMS_REGS | 0x26) /*UOP_MOV_INT_DOUBLE_64 - dest_reg = (int)src_reg_a. New rounding control in src_reg_b, old rounding control in src_reg_c*/ -#define UOP_MOV_INT_DOUBLE_64 (UOP_TYPE_PARAMS_REGS | 0x27) +#define UOP_MOV_INT_DOUBLE_64 (UOP_TYPE_PARAMS_REGS | 0x27) /*UOP_MOV_REG_PTR - dest_reg = *p*/ -#define UOP_MOV_REG_PTR (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x28) +#define UOP_MOV_REG_PTR (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x28) /*UOP_MOVZX_REG_PTR_8 - dest_reg = *(uint8_t *)p*/ -#define UOP_MOVZX_REG_PTR_8 (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x29) +#define UOP_MOVZX_REG_PTR_8 (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x29) /*UOP_MOVZX_REG_PTR_16 - dest_reg = *(uint16_t *)p*/ -#define UOP_MOVZX_REG_PTR_16 (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x2a) +#define UOP_MOVZX_REG_PTR_16 (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x2a) /*UOP_ADD - dest_reg = src_reg_a + src_reg_b*/ -#define UOP_ADD (UOP_TYPE_PARAMS_REGS | 0x30) +#define UOP_ADD (UOP_TYPE_PARAMS_REGS | 0x30) /*UOP_ADD_IMM - dest_reg = src_reg_a + immediate*/ -#define UOP_ADD_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x31) +#define UOP_ADD_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x31) /*UOP_AND - dest_reg = src_reg_a & src_reg_b*/ -#define UOP_AND (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x32) +#define UOP_AND (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x32) /*UOP_AND_IMM - dest_reg = src_reg_a & immediate*/ -#define UOP_AND_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x33) +#define UOP_AND_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x33) /*UOP_ADD_LSHIFT - dest_reg = src_reg_a + (src_reg_b << imm_data) Intended for EA calcluations, imm_data must be between 0 and 3*/ -#define UOP_ADD_LSHIFT (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x34) +#define UOP_ADD_LSHIFT (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x34) /*UOP_OR - dest_reg = src_reg_a | src_reg_b*/ -#define UOP_OR (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x35) +#define UOP_OR (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x35) /*UOP_OR_IMM - dest_reg = src_reg_a | immediate*/ -#define UOP_OR_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x36) +#define UOP_OR_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x36) /*UOP_SUB - dest_reg = src_reg_a - src_reg_b*/ -#define UOP_SUB (UOP_TYPE_PARAMS_REGS | 0x37) +#define UOP_SUB (UOP_TYPE_PARAMS_REGS | 0x37) /*UOP_SUB_IMM - dest_reg = src_reg_a - immediate*/ -#define UOP_SUB_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x38) +#define UOP_SUB_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x38) /*UOP_XOR - dest_reg = src_reg_a ^ src_reg_b*/ -#define UOP_XOR (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x39) +#define UOP_XOR (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x39) /*UOP_XOR_IMM - dest_reg = src_reg_a ^ immediate*/ -#define UOP_XOR_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x3a) +#define UOP_XOR_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x3a) /*UOP_ANDN - dest_reg = ~src_reg_a & src_reg_b*/ -#define UOP_ANDN (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x3b) +#define UOP_ANDN (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x3b) /*UOP_MEM_LOAD_ABS - dest_reg = src_reg_a:[immediate]*/ -#define UOP_MEM_LOAD_ABS (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x40 | UOP_TYPE_ORDER_BARRIER) +#define UOP_MEM_LOAD_ABS (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x40 | UOP_TYPE_ORDER_BARRIER) /*UOP_MEM_LOAD_REG - dest_reg = src_reg_a:[src_reg_b]*/ -#define UOP_MEM_LOAD_REG (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x41 | UOP_TYPE_ORDER_BARRIER) +#define UOP_MEM_LOAD_REG (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x41 | UOP_TYPE_ORDER_BARRIER) /*UOP_MEM_STORE_ABS - src_reg_a:[immediate] = src_reg_b*/ -#define UOP_MEM_STORE_ABS (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x42 | UOP_TYPE_ORDER_BARRIER) +#define UOP_MEM_STORE_ABS (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x42 | UOP_TYPE_ORDER_BARRIER) /*UOP_MEM_STORE_REG - src_reg_a:[src_reg_b] = src_reg_c*/ -#define UOP_MEM_STORE_REG (UOP_TYPE_PARAMS_REGS | 0x43 | UOP_TYPE_ORDER_BARRIER) +#define UOP_MEM_STORE_REG (UOP_TYPE_PARAMS_REGS | 0x43 | UOP_TYPE_ORDER_BARRIER) /*UOP_MEM_STORE_IMM_8 - byte src_reg_a:[src_reg_b] = imm_data*/ -#define UOP_MEM_STORE_IMM_8 (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x44 | UOP_TYPE_ORDER_BARRIER) +#define UOP_MEM_STORE_IMM_8 (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x44 | UOP_TYPE_ORDER_BARRIER) /*UOP_MEM_STORE_IMM_16 - word src_reg_a:[src_reg_b] = imm_data*/ -#define UOP_MEM_STORE_IMM_16 (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x45 | UOP_TYPE_ORDER_BARRIER) +#define UOP_MEM_STORE_IMM_16 (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x45 | UOP_TYPE_ORDER_BARRIER) /*UOP_MEM_STORE_IMM_32 - long src_reg_a:[src_reg_b] = imm_data*/ -#define UOP_MEM_STORE_IMM_32 (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x46 | UOP_TYPE_ORDER_BARRIER) +#define UOP_MEM_STORE_IMM_32 (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x46 | UOP_TYPE_ORDER_BARRIER) /*UOP_MEM_LOAD_SINGLE - dest_reg = (float)src_reg_a:[src_reg_b]*/ -#define UOP_MEM_LOAD_SINGLE (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x47 | UOP_TYPE_ORDER_BARRIER) +#define UOP_MEM_LOAD_SINGLE (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x47 | UOP_TYPE_ORDER_BARRIER) /*UOP_CMP_IMM_JZ - if (src_reg_a == imm_data) then jump to ptr*/ -#define UOP_CMP_IMM_JZ (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x48 | UOP_TYPE_ORDER_BARRIER) +#define UOP_CMP_IMM_JZ (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x48 | UOP_TYPE_ORDER_BARRIER) /*UOP_MEM_LOAD_DOUBLE - dest_reg = (double)src_reg_a:[src_reg_b]*/ -#define UOP_MEM_LOAD_DOUBLE (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x49 | UOP_TYPE_ORDER_BARRIER) +#define UOP_MEM_LOAD_DOUBLE (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x49 | UOP_TYPE_ORDER_BARRIER) /*UOP_MEM_STORE_SINGLE - src_reg_a:[src_reg_b] = src_reg_c*/ -#define UOP_MEM_STORE_SINGLE (UOP_TYPE_PARAMS_REGS | 0x4a | UOP_TYPE_ORDER_BARRIER) +#define UOP_MEM_STORE_SINGLE (UOP_TYPE_PARAMS_REGS | 0x4a | UOP_TYPE_ORDER_BARRIER) /*UOP_MEM_STORE_DOUBLE - src_reg_a:[src_reg_b] = src_reg_c*/ -#define UOP_MEM_STORE_DOUBLE (UOP_TYPE_PARAMS_REGS | 0x4b | UOP_TYPE_ORDER_BARRIER) +#define UOP_MEM_STORE_DOUBLE (UOP_TYPE_PARAMS_REGS | 0x4b | UOP_TYPE_ORDER_BARRIER) /*UOP_CMP_JB - if (src_reg_a < src_reg_b) then jump to ptr*/ -#define UOP_CMP_JB (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x4c | UOP_TYPE_ORDER_BARRIER) +#define UOP_CMP_JB (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x4c | UOP_TYPE_ORDER_BARRIER) /*UOP_CMP_JNBE - if (src_reg_a > src_reg_b) then jump to ptr*/ -#define UOP_CMP_JNBE (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x4d | UOP_TYPE_ORDER_BARRIER) +#define UOP_CMP_JNBE (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x4d | UOP_TYPE_ORDER_BARRIER) /*UOP_SAR - dest_reg = src_reg_a >> src_reg_b*/ -#define UOP_SAR (UOP_TYPE_PARAMS_REGS | 0x50) +#define UOP_SAR (UOP_TYPE_PARAMS_REGS | 0x50) /*UOP_SAR_IMM - dest_reg = src_reg_a >> immediate*/ -#define UOP_SAR_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x51) +#define UOP_SAR_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x51) /*UOP_SHL - dest_reg = src_reg_a << src_reg_b*/ -#define UOP_SHL (UOP_TYPE_PARAMS_REGS | 0x52) +#define UOP_SHL (UOP_TYPE_PARAMS_REGS | 0x52) /*UOP_SHL_IMM - dest_reg = src_reg_a << immediate*/ -#define UOP_SHL_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x53) +#define UOP_SHL_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x53) /*UOP_SHR - dest_reg = src_reg_a >> src_reg_b*/ -#define UOP_SHR (UOP_TYPE_PARAMS_REGS | 0x54) +#define UOP_SHR (UOP_TYPE_PARAMS_REGS | 0x54) /*UOP_SHR_IMM - dest_reg = src_reg_a >> immediate*/ -#define UOP_SHR_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x55) +#define UOP_SHR_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x55) /*UOP_ROL - dest_reg = src_reg_a rotate<< src_reg_b*/ -#define UOP_ROL (UOP_TYPE_PARAMS_REGS | 0x56) +#define UOP_ROL (UOP_TYPE_PARAMS_REGS | 0x56) /*UOP_ROL_IMM - dest_reg = src_reg_a rotate<< immediate*/ -#define UOP_ROL_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x57) +#define UOP_ROL_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x57) /*UOP_ROR - dest_reg = src_reg_a rotate>> src_reg_b*/ -#define UOP_ROR (UOP_TYPE_PARAMS_REGS | 0x58) +#define UOP_ROR (UOP_TYPE_PARAMS_REGS | 0x58) /*UOP_ROR_IMM - dest_reg = src_reg_a rotate>> immediate*/ -#define UOP_ROR_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x59) +#define UOP_ROR_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x59) /*UOP_CMP_IMM_JZ_DEST - if (src_reg_a == imm_data) then jump to ptr*/ -#define UOP_CMP_IMM_JZ_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x60 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +#define UOP_CMP_IMM_JZ_DEST \ + (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x60 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) /*UOP_CMP_IMM_JNZ_DEST - if (src_reg_a != imm_data) then jump to ptr*/ -#define UOP_CMP_IMM_JNZ_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x61 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +#define UOP_CMP_IMM_JNZ_DEST \ + (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x61 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) /*UOP_CMP_JB_DEST - if (src_reg_a < src_reg_b) then jump to ptr*/ -#define UOP_CMP_JB_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x62 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +#define UOP_CMP_JB_DEST \ + (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x62 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) /*UOP_CMP_JNB_DEST - if (src_reg_a >= src_reg_b) then jump to ptr*/ -#define UOP_CMP_JNB_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x63 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +#define UOP_CMP_JNB_DEST \ + (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x63 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) /*UOP_CMP_JO_DEST - if (src_reg_a < src_reg_b) then jump to ptr*/ -#define UOP_CMP_JO_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x64 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +#define UOP_CMP_JO_DEST \ + (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x64 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) /*UOP_CMP_JNO_DEST - if (src_reg_a >= src_reg_b) then jump to ptr*/ -#define UOP_CMP_JNO_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x65 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +#define UOP_CMP_JNO_DEST \ + (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x65 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) /*UOP_CMP_JZ_DEST - if (src_reg_a == src_reg_b) then jump to ptr*/ -#define UOP_CMP_JZ_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x66 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +#define UOP_CMP_JZ_DEST \ + (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x66 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) /*UOP_CMP_JNZ_DEST - if (src_reg_a != src_reg_b) then jump to ptr*/ -#define UOP_CMP_JNZ_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x67 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +#define UOP_CMP_JNZ_DEST \ + (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x67 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) /*UOP_CMP_JL_DEST - if (signed)(src_reg_a < src_reg_b) then jump to ptr*/ -#define UOP_CMP_JL_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x68 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +#define UOP_CMP_JL_DEST \ + (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x68 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) /*UOP_CMP_JNL_DEST - if (signed)(src_reg_a >= src_reg_b) then jump to ptr*/ -#define UOP_CMP_JNL_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x69 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +#define UOP_CMP_JNL_DEST \ + (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x69 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) /*UOP_CMP_JBE_DEST - if (src_reg_a <= src_reg_b) then jump to ptr*/ -#define UOP_CMP_JBE_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x6a | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +#define UOP_CMP_JBE_DEST \ + (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x6a | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) /*UOP_CMP_JNBE_DEST - if (src_reg_a > src_reg_b) then jump to ptr*/ -#define UOP_CMP_JNBE_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x6b | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +#define UOP_CMP_JNBE_DEST \ + (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x6b | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) /*UOP_CMP_JLE_DEST - if (signed)(src_reg_a <= src_reg_b) then jump to ptr*/ -#define UOP_CMP_JLE_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x6c | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +#define UOP_CMP_JLE_DEST \ + (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x6c | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) /*UOP_CMP_JNLE_DEST - if (signed)(src_reg_a > src_reg_b) then jump to ptr*/ -#define UOP_CMP_JNLE_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x6d | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) - +#define UOP_CMP_JNLE_DEST \ + (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x6d | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) /*UOP_TEST_JNS_DEST - if (src_reg_a positive) then jump to ptr*/ -#define UOP_TEST_JNS_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x70 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +#define UOP_TEST_JNS_DEST \ + (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x70 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) /*UOP_TEST_JS_DEST - if (src_reg_a positive) then jump to ptr*/ -#define UOP_TEST_JS_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x71 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +#define UOP_TEST_JS_DEST \ + (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x71 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) /*UOP_FP_ENTER - must be called before any FPU register accessed*/ -#define UOP_FP_ENTER (UOP_TYPE_PARAMS_IMM | 0x80 | UOP_TYPE_BARRIER) +#define UOP_FP_ENTER (UOP_TYPE_PARAMS_IMM | 0x80 | UOP_TYPE_BARRIER) /*UOP_FADD - (floating point) dest_reg = src_reg_a + src_reg_b*/ -#define UOP_FADD (UOP_TYPE_PARAMS_REGS | 0x81) +#define UOP_FADD (UOP_TYPE_PARAMS_REGS | 0x81) /*UOP_FSUB - (floating point) dest_reg = src_reg_a - src_reg_b*/ -#define UOP_FSUB (UOP_TYPE_PARAMS_REGS | 0x82) +#define UOP_FSUB (UOP_TYPE_PARAMS_REGS | 0x82) /*UOP_FMUL - (floating point) dest_reg = src_reg_a * src_reg_b*/ -#define UOP_FMUL (UOP_TYPE_PARAMS_REGS | 0x83) +#define UOP_FMUL (UOP_TYPE_PARAMS_REGS | 0x83) /*UOP_FDIV - (floating point) dest_reg = src_reg_a / src_reg_b*/ -#define UOP_FDIV (UOP_TYPE_PARAMS_REGS | 0x84) +#define UOP_FDIV (UOP_TYPE_PARAMS_REGS | 0x84) /*UOP_FCOM - dest_reg = flags from compare(src_reg_a, src_reg_b)*/ -#define UOP_FCOM (UOP_TYPE_PARAMS_REGS | 0x85) +#define UOP_FCOM (UOP_TYPE_PARAMS_REGS | 0x85) /*UOP_FABS - dest_reg = fabs(src_reg_a)*/ -#define UOP_FABS (UOP_TYPE_PARAMS_REGS | 0x86) +#define UOP_FABS (UOP_TYPE_PARAMS_REGS | 0x86) /*UOP_FCHS - dest_reg = fabs(src_reg_a)*/ -#define UOP_FCHS (UOP_TYPE_PARAMS_REGS | 0x87) +#define UOP_FCHS (UOP_TYPE_PARAMS_REGS | 0x87) /*UOP_FTST - dest_reg = flags from compare(src_reg_a, 0)*/ -#define UOP_FTST (UOP_TYPE_PARAMS_REGS | 0x88) +#define UOP_FTST (UOP_TYPE_PARAMS_REGS | 0x88) /*UOP_FSQRT - dest_reg = fsqrt(src_reg_a)*/ -#define UOP_FSQRT (UOP_TYPE_PARAMS_REGS | 0x89) +#define UOP_FSQRT (UOP_TYPE_PARAMS_REGS | 0x89) /*UOP_MMX_ENTER - must be called before any MMX registers accessed*/ -#define UOP_MMX_ENTER (UOP_TYPE_PARAMS_IMM | 0x90 | UOP_TYPE_BARRIER) +#define UOP_MMX_ENTER (UOP_TYPE_PARAMS_IMM | 0x90 | UOP_TYPE_BARRIER) /*UOP_PADDB - (packed byte) dest_reg = src_reg_a + src_reg_b*/ -#define UOP_PADDB (UOP_TYPE_PARAMS_REGS | 0x91) +#define UOP_PADDB (UOP_TYPE_PARAMS_REGS | 0x91) /*UOP_PADDW - (packed word) dest_reg = src_reg_a + src_reg_b*/ -#define UOP_PADDW (UOP_TYPE_PARAMS_REGS | 0x92) +#define UOP_PADDW (UOP_TYPE_PARAMS_REGS | 0x92) /*UOP_PADDD - (packed long) dest_reg = src_reg_a + src_reg_b*/ -#define UOP_PADDD (UOP_TYPE_PARAMS_REGS | 0x93) +#define UOP_PADDD (UOP_TYPE_PARAMS_REGS | 0x93) /*UOP_PADDSB - (packed byte with signed saturation) dest_reg = src_reg_a + src_reg_b*/ -#define UOP_PADDSB (UOP_TYPE_PARAMS_REGS | 0x94) +#define UOP_PADDSB (UOP_TYPE_PARAMS_REGS | 0x94) /*UOP_PADDSW - (packed word with signed saturation) dest_reg = src_reg_a + src_reg_b*/ -#define UOP_PADDSW (UOP_TYPE_PARAMS_REGS | 0x95) +#define UOP_PADDSW (UOP_TYPE_PARAMS_REGS | 0x95) /*UOP_PADDUSB - (packed byte with unsigned saturation) dest_reg = src_reg_a + src_reg_b*/ -#define UOP_PADDUSB (UOP_TYPE_PARAMS_REGS | 0x96) +#define UOP_PADDUSB (UOP_TYPE_PARAMS_REGS | 0x96) /*UOP_PADDUSW - (packed word with unsigned saturation) dest_reg = src_reg_a + src_reg_b*/ -#define UOP_PADDUSW (UOP_TYPE_PARAMS_REGS | 0x97) +#define UOP_PADDUSW (UOP_TYPE_PARAMS_REGS | 0x97) /*UOP_PSUBB - (packed byte) dest_reg = src_reg_a - src_reg_b*/ -#define UOP_PSUBB (UOP_TYPE_PARAMS_REGS | 0x98) +#define UOP_PSUBB (UOP_TYPE_PARAMS_REGS | 0x98) /*UOP_PSUBW - (packed word) dest_reg = src_reg_a - src_reg_b*/ -#define UOP_PSUBW (UOP_TYPE_PARAMS_REGS | 0x99) +#define UOP_PSUBW (UOP_TYPE_PARAMS_REGS | 0x99) /*UOP_PSUBD - (packed long) dest_reg = src_reg_a - src_reg_b*/ -#define UOP_PSUBD (UOP_TYPE_PARAMS_REGS | 0x9a) +#define UOP_PSUBD (UOP_TYPE_PARAMS_REGS | 0x9a) /*UOP_PSUBSB - (packed byte with signed saturation) dest_reg = src_reg_a - src_reg_b*/ -#define UOP_PSUBSB (UOP_TYPE_PARAMS_REGS | 0x9b) +#define UOP_PSUBSB (UOP_TYPE_PARAMS_REGS | 0x9b) /*UOP_PSUBSW - (packed word with signed saturation) dest_reg = src_reg_a - src_reg_b*/ -#define UOP_PSUBSW (UOP_TYPE_PARAMS_REGS | 0x9c) +#define UOP_PSUBSW (UOP_TYPE_PARAMS_REGS | 0x9c) /*UOP_PSUBUSB - (packed byte with unsigned saturation) dest_reg = src_reg_a - src_reg_b*/ -#define UOP_PSUBUSB (UOP_TYPE_PARAMS_REGS | 0x9d) +#define UOP_PSUBUSB (UOP_TYPE_PARAMS_REGS | 0x9d) /*UOP_PSUBUSW - (packed word with unsigned saturation) dest_reg = src_reg_a - src_reg_b*/ -#define UOP_PSUBUSW (UOP_TYPE_PARAMS_REGS | 0x9e) +#define UOP_PSUBUSW (UOP_TYPE_PARAMS_REGS | 0x9e) /*UOP_PSLLW_IMM - (packed word) dest_reg = src_reg_a << immediate*/ -#define UOP_PSLLW_IMM (UOP_TYPE_PARAMS_REGS | 0x9f) +#define UOP_PSLLW_IMM (UOP_TYPE_PARAMS_REGS | 0x9f) /*UOP_PSLLD_IMM - (packed long) dest_reg = src_reg_a << immediate*/ -#define UOP_PSLLD_IMM (UOP_TYPE_PARAMS_REGS | 0xa0) +#define UOP_PSLLD_IMM (UOP_TYPE_PARAMS_REGS | 0xa0) /*UOP_PSLLQ_IMM - (packed quad) dest_reg = src_reg_a << immediate*/ -#define UOP_PSLLQ_IMM (UOP_TYPE_PARAMS_REGS | 0xa1) +#define UOP_PSLLQ_IMM (UOP_TYPE_PARAMS_REGS | 0xa1) /*UOP_PSRAW_IMM - (packed word) dest_reg = src_reg_a >> immediate*/ -#define UOP_PSRAW_IMM (UOP_TYPE_PARAMS_REGS | 0xa2) +#define UOP_PSRAW_IMM (UOP_TYPE_PARAMS_REGS | 0xa2) /*UOP_PSRAD_IMM - (packed long) dest_reg = src_reg_a >> immediate*/ -#define UOP_PSRAD_IMM (UOP_TYPE_PARAMS_REGS | 0xa3) +#define UOP_PSRAD_IMM (UOP_TYPE_PARAMS_REGS | 0xa3) /*UOP_PSRAQ_IMM - (packed quad) dest_reg = src_reg_a >> immediate*/ -#define UOP_PSRAQ_IMM (UOP_TYPE_PARAMS_REGS | 0xa4) +#define UOP_PSRAQ_IMM (UOP_TYPE_PARAMS_REGS | 0xa4) /*UOP_PSRLW_IMM - (packed word) dest_reg = src_reg_a >> immediate*/ -#define UOP_PSRLW_IMM (UOP_TYPE_PARAMS_REGS | 0xa5) +#define UOP_PSRLW_IMM (UOP_TYPE_PARAMS_REGS | 0xa5) /*UOP_PSRLD_IMM - (packed long) dest_reg = src_reg_a >> immediate*/ -#define UOP_PSRLD_IMM (UOP_TYPE_PARAMS_REGS | 0xa6) +#define UOP_PSRLD_IMM (UOP_TYPE_PARAMS_REGS | 0xa6) /*UOP_PSRLQ_IMM - (packed quad) dest_reg = src_reg_a >> immediate*/ -#define UOP_PSRLQ_IMM (UOP_TYPE_PARAMS_REGS | 0xa7) +#define UOP_PSRLQ_IMM (UOP_TYPE_PARAMS_REGS | 0xa7) /*UOP_PCMPEQB - (packed byte) dest_reg = (src_reg_a == src_reg_b) ? ~0 : 0*/ -#define UOP_PCMPEQB (UOP_TYPE_PARAMS_REGS | 0xa8) +#define UOP_PCMPEQB (UOP_TYPE_PARAMS_REGS | 0xa8) /*UOP_PCMPEQW - (packed word) dest_reg = (src_reg_a == src_reg_b) ? ~0 : 0*/ -#define UOP_PCMPEQW (UOP_TYPE_PARAMS_REGS | 0xa9) +#define UOP_PCMPEQW (UOP_TYPE_PARAMS_REGS | 0xa9) /*UOP_PCMPEQD - (packed long) dest_reg = (src_reg_a == src_reg_b) ? ~0 : 0*/ -#define UOP_PCMPEQD (UOP_TYPE_PARAMS_REGS | 0xaa) +#define UOP_PCMPEQD (UOP_TYPE_PARAMS_REGS | 0xaa) /*UOP_PCMPGTB - (packed signed byte) dest_reg = (src_reg_a > src_reg_b) ? ~0 : 0*/ -#define UOP_PCMPGTB (UOP_TYPE_PARAMS_REGS | 0xab) +#define UOP_PCMPGTB (UOP_TYPE_PARAMS_REGS | 0xab) /*UOP_PCMPGTW - (packed signed word) dest_reg = (src_reg_a > src_reg_b) ? ~0 : 0*/ -#define UOP_PCMPGTW (UOP_TYPE_PARAMS_REGS | 0xac) +#define UOP_PCMPGTW (UOP_TYPE_PARAMS_REGS | 0xac) /*UOP_PCMPGTD - (packed signed long) dest_reg = (src_reg_a > src_reg_b) ? ~0 : 0*/ -#define UOP_PCMPGTD (UOP_TYPE_PARAMS_REGS | 0xad) +#define UOP_PCMPGTD (UOP_TYPE_PARAMS_REGS | 0xad) /*UOP_PUNPCKLBW - (packed byte) dest_reg = interleave low src_reg_a/src_reg_b*/ -#define UOP_PUNPCKLBW (UOP_TYPE_PARAMS_REGS | 0xae) +#define UOP_PUNPCKLBW (UOP_TYPE_PARAMS_REGS | 0xae) /*UOP_PUNPCKLWD - (packed word) dest_reg = interleave low src_reg_a/src_reg_b*/ -#define UOP_PUNPCKLWD (UOP_TYPE_PARAMS_REGS | 0xaf) +#define UOP_PUNPCKLWD (UOP_TYPE_PARAMS_REGS | 0xaf) /*UOP_PUNPCKLDQ - (packed long) dest_reg = interleave low src_reg_a/src_reg_b*/ -#define UOP_PUNPCKLDQ (UOP_TYPE_PARAMS_REGS | 0xb0) +#define UOP_PUNPCKLDQ (UOP_TYPE_PARAMS_REGS | 0xb0) /*UOP_PUNPCKHBW - (packed byte) dest_reg = interleave high src_reg_a/src_reg_b*/ -#define UOP_PUNPCKHBW (UOP_TYPE_PARAMS_REGS | 0xb1) +#define UOP_PUNPCKHBW (UOP_TYPE_PARAMS_REGS | 0xb1) /*UOP_PUNPCKHWD - (packed word) dest_reg = interleave high src_reg_a/src_reg_b*/ -#define UOP_PUNPCKHWD (UOP_TYPE_PARAMS_REGS | 0xb2) +#define UOP_PUNPCKHWD (UOP_TYPE_PARAMS_REGS | 0xb2) /*UOP_PUNPCKHDQ - (packed long) dest_reg = interleave high src_reg_a/src_reg_b*/ -#define UOP_PUNPCKHDQ (UOP_TYPE_PARAMS_REGS | 0xb3) +#define UOP_PUNPCKHDQ (UOP_TYPE_PARAMS_REGS | 0xb3) /*UOP_PACKSSWB - dest_reg = interleave src_reg_a/src_reg_b, converting words to bytes with signed saturation*/ -#define UOP_PACKSSWB (UOP_TYPE_PARAMS_REGS | 0xb4) +#define UOP_PACKSSWB (UOP_TYPE_PARAMS_REGS | 0xb4) /*UOP_PACKSSDW - dest_reg = interleave src_reg_a/src_reg_b, converting longs to words with signed saturation*/ -#define UOP_PACKSSDW (UOP_TYPE_PARAMS_REGS | 0xb5) +#define UOP_PACKSSDW (UOP_TYPE_PARAMS_REGS | 0xb5) /*UOP_PACKUSWB - dest_reg = interleave src_reg_a/src_reg_b, converting words to bytes with unsigned saturation*/ -#define UOP_PACKUSWB (UOP_TYPE_PARAMS_REGS | 0xb6) +#define UOP_PACKUSWB (UOP_TYPE_PARAMS_REGS | 0xb6) /*UOP_PMULLW - (packed word) dest_reg = (src_reg_a * src_reg_b) & 0xffff*/ -#define UOP_PMULLW (UOP_TYPE_PARAMS_REGS | 0xb7) +#define UOP_PMULLW (UOP_TYPE_PARAMS_REGS | 0xb7) /*UOP_PMULHW - (packed word) dest_reg = (src_reg_a * src_reg_b) >> 16*/ -#define UOP_PMULHW (UOP_TYPE_PARAMS_REGS | 0xb8) +#define UOP_PMULHW (UOP_TYPE_PARAMS_REGS | 0xb8) /*UOP_PMADDWD - (packed word) dest_reg = (src_reg_a * src_reg_b) >> 16*/ -#define UOP_PMADDWD (UOP_TYPE_PARAMS_REGS | 0xb9) +#define UOP_PMADDWD (UOP_TYPE_PARAMS_REGS | 0xb9) /*UOP_PFADD - (packed float) dest_reg = src_reg_a + src_reg_b*/ -#define UOP_PFADD (UOP_TYPE_PARAMS_REGS | 0xba) +#define UOP_PFADD (UOP_TYPE_PARAMS_REGS | 0xba) /*UOP_PFSUB - (packed float) dest_reg = src_reg_a - src_reg_b*/ -#define UOP_PFSUB (UOP_TYPE_PARAMS_REGS | 0xbb) +#define UOP_PFSUB (UOP_TYPE_PARAMS_REGS | 0xbb) /*UOP_PFMUL - (packed float) dest_reg = src_reg_a * src_reg_b*/ -#define UOP_PFMUL (UOP_TYPE_PARAMS_REGS | 0xbc) +#define UOP_PFMUL (UOP_TYPE_PARAMS_REGS | 0xbc) /*UOP_PFMAX - (packed float) dest_reg = MAX(src_reg_a, src_reg_b)*/ -#define UOP_PFMAX (UOP_TYPE_PARAMS_REGS | 0xbd) +#define UOP_PFMAX (UOP_TYPE_PARAMS_REGS | 0xbd) /*UOP_PFMIN - (packed float) dest_reg = MIN(src_reg_a, src_reg_b)*/ -#define UOP_PFMIN (UOP_TYPE_PARAMS_REGS | 0xbe) +#define UOP_PFMIN (UOP_TYPE_PARAMS_REGS | 0xbe) /*UOP_PFCMPEQ - (packed float) dest_reg = (src_reg_a == src_reg_b) ? ~0 : 0*/ -#define UOP_PFCMPEQ (UOP_TYPE_PARAMS_REGS | 0xbf) +#define UOP_PFCMPEQ (UOP_TYPE_PARAMS_REGS | 0xbf) /*UOP_PFCMPGE - (packed float) dest_reg = (src_reg_a >= src_reg_b) ? ~0 : 0*/ -#define UOP_PFCMPGE (UOP_TYPE_PARAMS_REGS | 0xc0) +#define UOP_PFCMPGE (UOP_TYPE_PARAMS_REGS | 0xc0) /*UOP_PFCMPGT - (packed float) dest_reg = (src_reg_a > src_reg_b) ? ~0 : 0*/ -#define UOP_PFCMPGT (UOP_TYPE_PARAMS_REGS | 0xc1) +#define UOP_PFCMPGT (UOP_TYPE_PARAMS_REGS | 0xc1) /*UOP_PF2ID - (packed long)dest_reg = (packed float)src_reg_a*/ -#define UOP_PF2ID (UOP_TYPE_PARAMS_REGS | 0xc2) +#define UOP_PF2ID (UOP_TYPE_PARAMS_REGS | 0xc2) /*UOP_PI2FD - (packed float)dest_reg = (packed long)src_reg_a*/ -#define UOP_PI2FD (UOP_TYPE_PARAMS_REGS | 0xc3) +#define UOP_PI2FD (UOP_TYPE_PARAMS_REGS | 0xc3) /*UOP_PFRCP - (packed float) dest_reg[0] = dest_reg[1] = 1.0 / src_reg[0]*/ -#define UOP_PFRCP (UOP_TYPE_PARAMS_REGS | 0xc4) +#define UOP_PFRCP (UOP_TYPE_PARAMS_REGS | 0xc4) /*UOP_PFRSQRT - (packed float) dest_reg[0] = dest_reg[1] = 1.0 / sqrt(src_reg[0])*/ -#define UOP_PFRSQRT (UOP_TYPE_PARAMS_REGS | 0xc5) +#define UOP_PFRSQRT (UOP_TYPE_PARAMS_REGS | 0xc5) #define UOP_MAX 0xc6 @@ -332,8 +346,7 @@ #define UOP_MASK 0xffff -typedef struct uop_t -{ +typedef struct uop_t { uint32_t type; ir_reg_t dest_reg_a; ir_reg_t src_reg_a; @@ -351,29 +364,27 @@ typedef struct uop_t #define UOP_NR_MAX 4096 -typedef struct ir_data_t -{ +typedef struct ir_data_t { uop_t uops[UOP_NR_MAX]; int wr_pos; struct codeblock_t *block; } ir_data_t; -static inline uop_t *uop_alloc(ir_data_t *ir, uint32_t uop_type) -{ +static inline uop_t *uop_alloc(ir_data_t *ir, uint32_t uop_type) { uop_t *uop; - + if (ir->wr_pos >= UOP_NR_MAX) fatal("Exceeded uOP max\n"); - + uop = &ir->uops[ir->wr_pos++]; - + uop->dest_reg_a = invalid_ir_reg; uop->src_reg_a = invalid_ir_reg; uop->src_reg_b = invalid_ir_reg; uop->src_reg_c = invalid_ir_reg; - + uop->pc = cpu_state.oldpc; - + uop->jump_dest_uop = -1; uop->jump_list_next = -1; @@ -383,53 +394,47 @@ static inline uop_t *uop_alloc(ir_data_t *ir, uint32_t uop_type) return uop; } -static inline void uop_set_jump_dest(ir_data_t *ir, int jump_uop) -{ +static inline void uop_set_jump_dest(ir_data_t *ir, int jump_uop) { uop_t *uop = &ir->uops[jump_uop]; - + uop->jump_dest_uop = ir->wr_pos; } -static inline int uop_gen(uint32_t uop_type, ir_data_t *ir) -{ +static inline int uop_gen(uint32_t uop_type, ir_data_t *ir) { uop_t *uop = uop_alloc(ir, uop_type); uop->type = uop_type; - return ir->wr_pos-1; + return ir->wr_pos - 1; } -static inline int uop_gen_reg_src1(uint32_t uop_type, ir_data_t *ir, int src_reg_a) -{ +static inline int uop_gen_reg_src1(uint32_t uop_type, ir_data_t *ir, int src_reg_a) { uop_t *uop = uop_alloc(ir, uop_type); - + uop->type = uop_type; uop->src_reg_a = codegen_reg_read(src_reg_a); - return ir->wr_pos-1; + return ir->wr_pos - 1; } -static inline void uop_gen_reg_src1_arg(uint32_t uop_type, ir_data_t *ir, int arg, int src_reg_a) -{ +static inline void uop_gen_reg_src1_arg(uint32_t uop_type, ir_data_t *ir, int arg, int src_reg_a) { uop_t *uop = uop_alloc(ir, uop_type); uop->type = uop_type; uop->src_reg_a = codegen_reg_read(src_reg_a); } -static inline int uop_gen_reg_src1_imm(uint32_t uop_type, ir_data_t *ir, int src_reg, uint32_t imm) -{ +static inline int uop_gen_reg_src1_imm(uint32_t uop_type, ir_data_t *ir, int src_reg, uint32_t imm) { uop_t *uop = uop_alloc(ir, uop_type); uop->type = uop_type; uop->src_reg_a = codegen_reg_read(src_reg); uop->imm_data = imm; - - return ir->wr_pos-1; + + return ir->wr_pos - 1; } -static inline void uop_gen_reg_dst_imm(uint32_t uop_type, ir_data_t *ir, int dest_reg, uint32_t imm) -{ +static inline void uop_gen_reg_dst_imm(uint32_t uop_type, ir_data_t *ir, int dest_reg, uint32_t imm) { uop_t *uop = uop_alloc(ir, uop_type); uop->type = uop_type; @@ -437,8 +442,7 @@ static inline void uop_gen_reg_dst_imm(uint32_t uop_type, ir_data_t *ir, int des uop->imm_data = imm; } -static inline void uop_gen_reg_dst_pointer(uint32_t uop_type, ir_data_t *ir, int dest_reg, void *p) -{ +static inline void uop_gen_reg_dst_pointer(uint32_t uop_type, ir_data_t *ir, int dest_reg, void *p) { uop_t *uop = uop_alloc(ir, uop_type); uop->type = uop_type; @@ -446,8 +450,7 @@ static inline void uop_gen_reg_dst_pointer(uint32_t uop_type, ir_data_t *ir, int uop->p = p; } -static inline void uop_gen_reg_dst_src1(uint32_t uop_type, ir_data_t *ir, int dest_reg, int src_reg) -{ +static inline void uop_gen_reg_dst_src1(uint32_t uop_type, ir_data_t *ir, int dest_reg, int src_reg) { uop_t *uop = uop_alloc(ir, uop_type); uop->type = uop_type; @@ -455,8 +458,7 @@ static inline void uop_gen_reg_dst_src1(uint32_t uop_type, ir_data_t *ir, int de uop->dest_reg_a = codegen_reg_write(dest_reg, ir->wr_pos - 1); } -static inline void uop_gen_reg_dst_src1_imm(uint32_t uop_type, ir_data_t *ir, int dest_reg, int src_reg_a, uint32_t imm) -{ +static inline void uop_gen_reg_dst_src1_imm(uint32_t uop_type, ir_data_t *ir, int dest_reg, int src_reg_a, uint32_t imm) { uop_t *uop = uop_alloc(ir, uop_type); uop->type = uop_type; @@ -465,8 +467,7 @@ static inline void uop_gen_reg_dst_src1_imm(uint32_t uop_type, ir_data_t *ir, in uop->imm_data = imm; } -static inline void uop_gen_reg_dst_src2(uint32_t uop_type, ir_data_t *ir, int dest_reg, int src_reg_a, int src_reg_b) -{ +static inline void uop_gen_reg_dst_src2(uint32_t uop_type, ir_data_t *ir, int dest_reg, int src_reg_a, int src_reg_b) { uop_t *uop = uop_alloc(ir, uop_type); uop->type = uop_type; @@ -475,8 +476,8 @@ static inline void uop_gen_reg_dst_src2(uint32_t uop_type, ir_data_t *ir, int de uop->dest_reg_a = codegen_reg_write(dest_reg, ir->wr_pos - 1); } -static inline void uop_gen_reg_dst_src2_imm(uint32_t uop_type, ir_data_t *ir, int dest_reg, int src_reg_a, int src_reg_b, uint32_t imm) -{ +static inline void uop_gen_reg_dst_src2_imm(uint32_t uop_type, ir_data_t *ir, int dest_reg, int src_reg_a, int src_reg_b, + uint32_t imm) { uop_t *uop = uop_alloc(ir, uop_type); uop->type = uop_type; @@ -486,8 +487,8 @@ static inline void uop_gen_reg_dst_src2_imm(uint32_t uop_type, ir_data_t *ir, in uop->imm_data = imm; } -static inline void uop_gen_reg_dst_src3(uint32_t uop_type, ir_data_t *ir, int dest_reg, int src_reg_a, int src_reg_b, int src_reg_c) -{ +static inline void uop_gen_reg_dst_src3(uint32_t uop_type, ir_data_t *ir, int dest_reg, int src_reg_a, int src_reg_b, + int src_reg_c) { uop_t *uop = uop_alloc(ir, uop_type); uop->type = uop_type; @@ -497,8 +498,7 @@ static inline void uop_gen_reg_dst_src3(uint32_t uop_type, ir_data_t *ir, int de uop->dest_reg_a = codegen_reg_write(dest_reg, ir->wr_pos - 1); } -static inline void uop_gen_reg_dst_src_imm(uint32_t uop_type, ir_data_t *ir, int dest_reg, int src_reg, uint32_t imm) -{ +static inline void uop_gen_reg_dst_src_imm(uint32_t uop_type, ir_data_t *ir, int dest_reg, int src_reg, uint32_t imm) { uop_t *uop = uop_alloc(ir, uop_type); uop->type = uop_type; @@ -507,19 +507,17 @@ static inline void uop_gen_reg_dst_src_imm(uint32_t uop_type, ir_data_t *ir, int uop->imm_data = imm; } -static inline int uop_gen_reg_src2(uint32_t uop_type, ir_data_t *ir, int src_reg_a, int src_reg_b) -{ +static inline int uop_gen_reg_src2(uint32_t uop_type, ir_data_t *ir, int src_reg_a, int src_reg_b) { uop_t *uop = uop_alloc(ir, uop_type); uop->type = uop_type; uop->src_reg_a = codegen_reg_read(src_reg_a); uop->src_reg_b = codegen_reg_read(src_reg_b); - - return ir->wr_pos-1; + + return ir->wr_pos - 1; } -static inline void uop_gen_reg_src2_imm(uint32_t uop_type, ir_data_t *ir, int src_reg_a, int src_reg_b, uint32_t imm) -{ +static inline void uop_gen_reg_src2_imm(uint32_t uop_type, ir_data_t *ir, int src_reg_a, int src_reg_b, uint32_t imm) { uop_t *uop = uop_alloc(ir, uop_type); uop->type = uop_type; @@ -528,8 +526,7 @@ static inline void uop_gen_reg_src2_imm(uint32_t uop_type, ir_data_t *ir, int sr uop->imm_data = imm; } -static inline void uop_gen_reg_src3(uint32_t uop_type, ir_data_t *ir, int src_reg_a, int src_reg_b, int src_reg_c) -{ +static inline void uop_gen_reg_src3(uint32_t uop_type, ir_data_t *ir, int src_reg_a, int src_reg_b, int src_reg_c) { uop_t *uop = uop_alloc(ir, uop_type); uop->type = uop_type; @@ -538,8 +535,8 @@ static inline void uop_gen_reg_src3(uint32_t uop_type, ir_data_t *ir, int src_re uop->src_reg_c = codegen_reg_read(src_reg_c); } -static inline void uop_gen_reg_src3_imm(uint32_t uop_type, ir_data_t *ir, int src_reg_a, int src_reg_b, int src_reg_c, uint32_t imm) -{ +static inline void uop_gen_reg_src3_imm(uint32_t uop_type, ir_data_t *ir, int src_reg_a, int src_reg_b, int src_reg_c, + uint32_t imm) { uop_t *uop = uop_alloc(ir, uop_type); uop->type = uop_type; @@ -549,33 +546,29 @@ static inline void uop_gen_reg_src3_imm(uint32_t uop_type, ir_data_t *ir, int sr uop->imm_data = imm; } -static inline void uop_gen_imm(uint32_t uop_type, ir_data_t *ir, uint32_t imm) -{ +static inline void uop_gen_imm(uint32_t uop_type, ir_data_t *ir, uint32_t imm) { uop_t *uop = uop_alloc(ir, uop_type); - + uop->type = uop_type; uop->imm_data = imm; } -static inline void uop_gen_pointer(uint32_t uop_type, ir_data_t *ir, void *p) -{ +static inline void uop_gen_pointer(uint32_t uop_type, ir_data_t *ir, void *p) { uop_t *uop = uop_alloc(ir, uop_type); - + uop->type = uop_type; uop->p = p; } -static inline void uop_gen_pointer_imm(uint32_t uop_type, ir_data_t *ir, void *p, uint32_t imm) -{ +static inline void uop_gen_pointer_imm(uint32_t uop_type, ir_data_t *ir, void *p, uint32_t imm) { uop_t *uop = uop_alloc(ir, uop_type); - + uop->type = uop_type; uop->p = p; uop->imm_data = imm; } -static inline void uop_gen_reg_src_pointer(uint32_t uop_type, ir_data_t *ir, int src_reg_a, void *p) -{ +static inline void uop_gen_reg_src_pointer(uint32_t uop_type, ir_data_t *ir, int src_reg_a, void *p) { uop_t *uop = uop_alloc(ir, uop_type); uop->type = uop_type; @@ -583,8 +576,7 @@ static inline void uop_gen_reg_src_pointer(uint32_t uop_type, ir_data_t *ir, int uop->p = p; } -static inline void uop_gen_reg_src_pointer_imm(uint32_t uop_type, ir_data_t *ir, int src_reg_a, void *p, uint32_t imm) -{ +static inline void uop_gen_reg_src_pointer_imm(uint32_t uop_type, ir_data_t *ir, int src_reg_a, void *p, uint32_t imm) { uop_t *uop = uop_alloc(ir, uop_type); uop->type = uop_type; @@ -593,8 +585,7 @@ static inline void uop_gen_reg_src_pointer_imm(uint32_t uop_type, ir_data_t *ir, uop->imm_data = imm; } -static inline void uop_gen_reg_src2_pointer(uint32_t uop_type, ir_data_t *ir, int src_reg_a, int src_reg_b, void *p) -{ +static inline void uop_gen_reg_src2_pointer(uint32_t uop_type, ir_data_t *ir, int src_reg_a, int src_reg_b, void *p) { uop_t *uop = uop_alloc(ir, uop_type); uop->type = uop_type; @@ -603,58 +594,59 @@ static inline void uop_gen_reg_src2_pointer(uint32_t uop_type, ir_data_t *ir, in uop->p = p; } -#define uop_LOAD_FUNC_ARG_REG(ir, arg, reg) uop_gen_reg_src1(UOP_LOAD_FUNC_ARG_0 + arg, ir, reg) +#define uop_LOAD_FUNC_ARG_REG(ir, arg, reg) uop_gen_reg_src1(UOP_LOAD_FUNC_ARG_0 + arg, ir, reg) -#define uop_LOAD_FUNC_ARG_IMM(ir, arg, imm) uop_gen_imm(UOP_LOAD_FUNC_ARG_0_IMM + arg, ir, imm) +#define uop_LOAD_FUNC_ARG_IMM(ir, arg, imm) uop_gen_imm(UOP_LOAD_FUNC_ARG_0_IMM + arg, ir, imm) -#define uop_ADD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_ADD, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_ADD_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_ADD_IMM, ir, dst_reg, src_reg, imm) -#define uop_ADD_LSHIFT(ir, dst_reg, src_reg_a, src_reg_b, shift) uop_gen_reg_dst_src2_imm(UOP_ADD_LSHIFT, ir, dst_reg, src_reg_a, src_reg_b, shift) -#define uop_AND(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_AND, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_AND_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_AND_IMM, ir, dst_reg, src_reg, imm) +#define uop_ADD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_ADD, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_ADD_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_ADD_IMM, ir, dst_reg, src_reg, imm) +#define uop_ADD_LSHIFT(ir, dst_reg, src_reg_a, src_reg_b, shift) \ + uop_gen_reg_dst_src2_imm(UOP_ADD_LSHIFT, ir, dst_reg, src_reg_a, src_reg_b, shift) +#define uop_AND(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_AND, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_AND_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_AND_IMM, ir, dst_reg, src_reg, imm) #define uop_ANDN(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_ANDN, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_OR(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_OR, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_OR_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_OR_IMM, ir, dst_reg, src_reg, imm) -#define uop_SUB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_SUB, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_SUB_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_SUB_IMM, ir, dst_reg, src_reg, imm) -#define uop_XOR(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_XOR, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_XOR_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_XOR_IMM, ir, dst_reg, src_reg, imm) +#define uop_OR(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_OR, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_OR_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_OR_IMM, ir, dst_reg, src_reg, imm) +#define uop_SUB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_SUB, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_SUB_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_SUB_IMM, ir, dst_reg, src_reg, imm) +#define uop_XOR(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_XOR, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_XOR_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_XOR_IMM, ir, dst_reg, src_reg, imm) -#define uop_SAR(ir, dst_reg, src_reg, shift_reg) uop_gen_reg_dst_src2(UOP_SAR, ir, dst_reg, src_reg, shift_reg) -#define uop_SAR_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_SAR_IMM, ir, dst_reg, src_reg, imm) -#define uop_SHL(ir, dst_reg, src_reg, shift_reg) uop_gen_reg_dst_src2(UOP_SHL, ir, dst_reg, src_reg, shift_reg) -#define uop_SHL_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_SHL_IMM, ir, dst_reg, src_reg, imm) -#define uop_SHR(ir, dst_reg, src_reg, shift_reg) uop_gen_reg_dst_src2(UOP_SHR, ir, dst_reg, src_reg, shift_reg) -#define uop_SHR_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_SHR_IMM, ir, dst_reg, src_reg, imm) -#define uop_ROL(ir, dst_reg, src_reg, shift_reg) uop_gen_reg_dst_src2(UOP_ROL, ir, dst_reg, src_reg, shift_reg) -#define uop_ROL_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_ROL_IMM, ir, dst_reg, src_reg, imm) -#define uop_ROR(ir, dst_reg, src_reg, shift_reg) uop_gen_reg_dst_src2(UOP_ROR, ir, dst_reg, src_reg, shift_reg) -#define uop_ROR_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_ROR_IMM, ir, dst_reg, src_reg, imm) +#define uop_SAR(ir, dst_reg, src_reg, shift_reg) uop_gen_reg_dst_src2(UOP_SAR, ir, dst_reg, src_reg, shift_reg) +#define uop_SAR_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_SAR_IMM, ir, dst_reg, src_reg, imm) +#define uop_SHL(ir, dst_reg, src_reg, shift_reg) uop_gen_reg_dst_src2(UOP_SHL, ir, dst_reg, src_reg, shift_reg) +#define uop_SHL_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_SHL_IMM, ir, dst_reg, src_reg, imm) +#define uop_SHR(ir, dst_reg, src_reg, shift_reg) uop_gen_reg_dst_src2(UOP_SHR, ir, dst_reg, src_reg, shift_reg) +#define uop_SHR_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_SHR_IMM, ir, dst_reg, src_reg, imm) +#define uop_ROL(ir, dst_reg, src_reg, shift_reg) uop_gen_reg_dst_src2(UOP_ROL, ir, dst_reg, src_reg, shift_reg) +#define uop_ROL_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_ROL_IMM, ir, dst_reg, src_reg, imm) +#define uop_ROR(ir, dst_reg, src_reg, shift_reg) uop_gen_reg_dst_src2(UOP_ROR, ir, dst_reg, src_reg, shift_reg) +#define uop_ROR_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_ROR_IMM, ir, dst_reg, src_reg, imm) -#define uop_CALL_FUNC(ir, p) uop_gen_pointer(UOP_CALL_FUNC, ir, p) +#define uop_CALL_FUNC(ir, p) uop_gen_pointer(UOP_CALL_FUNC, ir, p) #define uop_CALL_FUNC_RESULT(ir, dst_reg, p) uop_gen_reg_dst_pointer(UOP_CALL_FUNC_RESULT, ir, dst_reg, p) -#define uop_CALL_INSTRUCTION_FUNC(ir, p) uop_gen_pointer(UOP_CALL_INSTRUCTION_FUNC, ir, p) +#define uop_CALL_INSTRUCTION_FUNC(ir, p) uop_gen_pointer(UOP_CALL_INSTRUCTION_FUNC, ir, p) -#define uop_CMP_IMM_JZ(ir, src_reg, imm, p) uop_gen_reg_src_pointer_imm(UOP_CMP_IMM_JZ, ir, src_reg, p, imm) +#define uop_CMP_IMM_JZ(ir, src_reg, imm, p) uop_gen_reg_src_pointer_imm(UOP_CMP_IMM_JZ, ir, src_reg, p, imm) #define uop_CMP_IMM_JNZ_DEST(ir, src_reg, imm) uop_gen_reg_src1_imm(UOP_CMP_IMM_JNZ_DEST, ir, src_reg, imm) -#define uop_CMP_IMM_JZ_DEST(ir, src_reg, imm) uop_gen_reg_src1_imm(UOP_CMP_IMM_JZ_DEST, ir, src_reg, imm) +#define uop_CMP_IMM_JZ_DEST(ir, src_reg, imm) uop_gen_reg_src1_imm(UOP_CMP_IMM_JZ_DEST, ir, src_reg, imm) -#define uop_CMP_JB(ir, src_reg_a, src_reg_b, p) uop_gen_reg_src2_pointer(UOP_CMP_JB, ir, src_reg_a, src_reg_b, p) +#define uop_CMP_JB(ir, src_reg_a, src_reg_b, p) uop_gen_reg_src2_pointer(UOP_CMP_JB, ir, src_reg_a, src_reg_b, p) #define uop_CMP_JNBE(ir, src_reg_a, src_reg_b, p) uop_gen_reg_src2_pointer(UOP_CMP_JNBE, ir, src_reg_a, src_reg_b, p) -#define uop_CMP_JNB_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JNB_DEST, ir, src_reg_a, src_reg_b) +#define uop_CMP_JNB_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JNB_DEST, ir, src_reg_a, src_reg_b) #define uop_CMP_JNBE_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JNBE_DEST, ir, src_reg_a, src_reg_b) -#define uop_CMP_JNL_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JNL_DEST, ir, src_reg_a, src_reg_b) +#define uop_CMP_JNL_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JNL_DEST, ir, src_reg_a, src_reg_b) #define uop_CMP_JNLE_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JNLE_DEST, ir, src_reg_a, src_reg_b) -#define uop_CMP_JNO_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JNO_DEST, ir, src_reg_a, src_reg_b) -#define uop_CMP_JNZ_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JNZ_DEST, ir, src_reg_a, src_reg_b) -#define uop_CMP_JB_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JB_DEST, ir, src_reg_a, src_reg_b) -#define uop_CMP_JBE_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JBE_DEST, ir, src_reg_a, src_reg_b) -#define uop_CMP_JL_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JL_DEST, ir, src_reg_a, src_reg_b) -#define uop_CMP_JLE_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JLE_DEST, ir, src_reg_a, src_reg_b) -#define uop_CMP_JO_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JO_DEST, ir, src_reg_a, src_reg_b) -#define uop_CMP_JZ_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JZ_DEST, ir, src_reg_a, src_reg_b) +#define uop_CMP_JNO_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JNO_DEST, ir, src_reg_a, src_reg_b) +#define uop_CMP_JNZ_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JNZ_DEST, ir, src_reg_a, src_reg_b) +#define uop_CMP_JB_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JB_DEST, ir, src_reg_a, src_reg_b) +#define uop_CMP_JBE_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JBE_DEST, ir, src_reg_a, src_reg_b) +#define uop_CMP_JL_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JL_DEST, ir, src_reg_a, src_reg_b) +#define uop_CMP_JLE_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JLE_DEST, ir, src_reg_a, src_reg_b) +#define uop_CMP_JO_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JO_DEST, ir, src_reg_a, src_reg_b) +#define uop_CMP_JZ_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JZ_DEST, ir, src_reg_a, src_reg_b) #define uop_FADD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_FADD, ir, dst_reg, src_reg_a, src_reg_b) #define uop_FCOM(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_FCOM, ir, dst_reg, src_reg_a, src_reg_b) @@ -667,39 +659,61 @@ static inline void uop_gen_reg_src2_pointer(uint32_t uop_type, ir_data_t *ir, in #define uop_FSQRT(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_FSQRT, ir, dst_reg, src_reg) #define uop_FTST(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_FTST, ir, dst_reg, src_reg) -#define uop_FP_ENTER(ir) do { if (!codegen_fpu_entered) uop_gen_imm(UOP_FP_ENTER, ir, cpu_state.oldpc); codegen_fpu_entered = 1; codegen_mmx_entered = 0; } while (0) -#define uop_MMX_ENTER(ir) do { if (!codegen_mmx_entered) uop_gen_imm(UOP_MMX_ENTER, ir, cpu_state.oldpc); codegen_mmx_entered = 1; codegen_fpu_entered = 0; } while (0) +#define uop_FP_ENTER(ir) \ + do { \ + if (!codegen_fpu_entered) \ + uop_gen_imm(UOP_FP_ENTER, ir, cpu_state.oldpc); \ + codegen_fpu_entered = 1; \ + codegen_mmx_entered = 0; \ + } while (0) +#define uop_MMX_ENTER(ir) \ + do { \ + if (!codegen_mmx_entered) \ + uop_gen_imm(UOP_MMX_ENTER, ir, cpu_state.oldpc); \ + codegen_mmx_entered = 1; \ + codegen_fpu_entered = 0; \ + } while (0) -#define uop_JMP(ir, p) uop_gen_pointer(UOP_JMP, ir, p) -#define uop_JMP_DEST(ir) uop_gen(UOP_JMP_DEST, ir) +#define uop_JMP(ir, p) uop_gen_pointer(UOP_JMP, ir, p) +#define uop_JMP_DEST(ir) uop_gen(UOP_JMP_DEST, ir) #define uop_LOAD_SEG(ir, p, src_reg) uop_gen_reg_src_pointer(UOP_LOAD_SEG, ir, src_reg, p) #define uop_MEM_LOAD_ABS(ir, dst_reg, seg_reg, imm) uop_gen_reg_dst_src_imm(UOP_MEM_LOAD_ABS, ir, dst_reg, seg_reg, imm) -#define uop_MEM_LOAD_REG(ir, dst_reg, seg_reg, addr_reg) uop_gen_reg_dst_src2_imm(UOP_MEM_LOAD_REG, ir, dst_reg, seg_reg, addr_reg, 0) -#define uop_MEM_LOAD_REG_OFFSET(ir, dst_reg, seg_reg, addr_reg, offset) uop_gen_reg_dst_src2_imm(UOP_MEM_LOAD_REG, ir, dst_reg, seg_reg, addr_reg, offset) -#define uop_MEM_LOAD_SINGLE(ir, dst_reg, seg_reg, addr_reg) uop_gen_reg_dst_src2_imm(UOP_MEM_LOAD_SINGLE, ir, dst_reg, seg_reg, addr_reg, 0) -#define uop_MEM_LOAD_DOUBLE(ir, dst_reg, seg_reg, addr_reg) uop_gen_reg_dst_src2_imm(UOP_MEM_LOAD_DOUBLE, ir, dst_reg, seg_reg, addr_reg, 0) +#define uop_MEM_LOAD_REG(ir, dst_reg, seg_reg, addr_reg) \ + uop_gen_reg_dst_src2_imm(UOP_MEM_LOAD_REG, ir, dst_reg, seg_reg, addr_reg, 0) +#define uop_MEM_LOAD_REG_OFFSET(ir, dst_reg, seg_reg, addr_reg, offset) \ + uop_gen_reg_dst_src2_imm(UOP_MEM_LOAD_REG, ir, dst_reg, seg_reg, addr_reg, offset) +#define uop_MEM_LOAD_SINGLE(ir, dst_reg, seg_reg, addr_reg) \ + uop_gen_reg_dst_src2_imm(UOP_MEM_LOAD_SINGLE, ir, dst_reg, seg_reg, addr_reg, 0) +#define uop_MEM_LOAD_DOUBLE(ir, dst_reg, seg_reg, addr_reg) \ + uop_gen_reg_dst_src2_imm(UOP_MEM_LOAD_DOUBLE, ir, dst_reg, seg_reg, addr_reg, 0) #define uop_MEM_STORE_ABS(ir, seg_reg, imm, src_reg) uop_gen_reg_src2_imm(UOP_MEM_STORE_ABS, ir, seg_reg, src_reg, imm) -#define uop_MEM_STORE_REG(ir, seg_reg, addr_reg, src_reg) uop_gen_reg_src3_imm(UOP_MEM_STORE_REG, ir, seg_reg, addr_reg, src_reg, 0) -#define uop_MEM_STORE_REG_OFFSET(ir, seg_reg, addr_reg, offset, src_reg) uop_gen_reg_src3_imm(UOP_MEM_STORE_REG, ir, seg_reg, addr_reg, src_reg, offset) +#define uop_MEM_STORE_REG(ir, seg_reg, addr_reg, src_reg) \ + uop_gen_reg_src3_imm(UOP_MEM_STORE_REG, ir, seg_reg, addr_reg, src_reg, 0) +#define uop_MEM_STORE_REG_OFFSET(ir, seg_reg, addr_reg, offset, src_reg) \ + uop_gen_reg_src3_imm(UOP_MEM_STORE_REG, ir, seg_reg, addr_reg, src_reg, offset) #define uop_MEM_STORE_IMM_8(ir, seg_reg, addr_reg, imm) uop_gen_reg_src2_imm(UOP_MEM_STORE_IMM_8, ir, seg_reg, addr_reg, imm) #define uop_MEM_STORE_IMM_16(ir, seg_reg, addr_reg, imm) uop_gen_reg_src2_imm(UOP_MEM_STORE_IMM_16, ir, seg_reg, addr_reg, imm) #define uop_MEM_STORE_IMM_32(ir, seg_reg, addr_reg, imm) uop_gen_reg_src2_imm(UOP_MEM_STORE_IMM_32, ir, seg_reg, addr_reg, imm) -#define uop_MEM_STORE_SINGLE(ir, seg_reg, addr_reg, src_reg) uop_gen_reg_src3_imm(UOP_MEM_STORE_SINGLE, ir, seg_reg, addr_reg, src_reg, 0) -#define uop_MEM_STORE_DOUBLE(ir, seg_reg, addr_reg, src_reg) uop_gen_reg_src3_imm(UOP_MEM_STORE_DOUBLE, ir, seg_reg, addr_reg, src_reg, 0) +#define uop_MEM_STORE_SINGLE(ir, seg_reg, addr_reg, src_reg) \ + uop_gen_reg_src3_imm(UOP_MEM_STORE_SINGLE, ir, seg_reg, addr_reg, src_reg, 0) +#define uop_MEM_STORE_DOUBLE(ir, seg_reg, addr_reg, src_reg) \ + uop_gen_reg_src3_imm(UOP_MEM_STORE_DOUBLE, ir, seg_reg, addr_reg, src_reg, 0) -#define uop_MOV(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_MOV, ir, dst_reg, src_reg) -#define uop_MOV_IMM(ir, reg, imm) uop_gen_reg_dst_imm(UOP_MOV_IMM, ir, reg, imm) -#define uop_MOV_PTR(ir, reg, p) uop_gen_reg_dst_pointer(UOP_MOV_PTR, ir, reg, p) -#define uop_MOV_REG_PTR(ir, reg, p) uop_gen_reg_dst_pointer(UOP_MOV_REG_PTR, ir, reg, p) -#define uop_MOVZX_REG_PTR_8(ir, reg, p) uop_gen_reg_dst_pointer(UOP_MOVZX_REG_PTR_8, ir, reg, p) -#define uop_MOVZX_REG_PTR_16(ir, reg, p) uop_gen_reg_dst_pointer(UOP_MOVZX_REG_PTR_16, ir, reg, p) -#define uop_MOVSX(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_MOVSX, ir, dst_reg, src_reg) -#define uop_MOVZX(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_MOVZX, ir, dst_reg, src_reg) +#define uop_MOV(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_MOV, ir, dst_reg, src_reg) +#define uop_MOV_IMM(ir, reg, imm) uop_gen_reg_dst_imm(UOP_MOV_IMM, ir, reg, imm) +#define uop_MOV_PTR(ir, reg, p) uop_gen_reg_dst_pointer(UOP_MOV_PTR, ir, reg, p) +#define uop_MOV_REG_PTR(ir, reg, p) uop_gen_reg_dst_pointer(UOP_MOV_REG_PTR, ir, reg, p) +#define uop_MOVZX_REG_PTR_8(ir, reg, p) uop_gen_reg_dst_pointer(UOP_MOVZX_REG_PTR_8, ir, reg, p) +#define uop_MOVZX_REG_PTR_16(ir, reg, p) uop_gen_reg_dst_pointer(UOP_MOVZX_REG_PTR_16, ir, reg, p) +#define uop_MOVSX(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_MOVSX, ir, dst_reg, src_reg) +#define uop_MOVZX(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_MOVZX, ir, dst_reg, src_reg) #define uop_MOV_DOUBLE_INT(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_MOV_DOUBLE_INT, ir, dst_reg, src_reg) -#define uop_MOV_INT_DOUBLE(ir, dst_reg, src_reg/*, nrc, orc*/) uop_gen_reg_dst_src1(UOP_MOV_INT_DOUBLE, ir, dst_reg, src_reg/*, nrc, orc*/) -#define uop_MOV_INT_DOUBLE_64(ir, dst_reg, src_reg_d, src_reg_q, tag) uop_gen_reg_dst_src3(UOP_MOV_INT_DOUBLE_64, ir, dst_reg, src_reg_d, src_reg_q, tag) +#define uop_MOV_INT_DOUBLE(ir, dst_reg, src_reg /*, nrc, orc*/) \ + uop_gen_reg_dst_src1(UOP_MOV_INT_DOUBLE, ir, dst_reg, src_reg /*, nrc, orc*/) +#define uop_MOV_INT_DOUBLE_64(ir, dst_reg, src_reg_d, src_reg_q, tag) \ + uop_gen_reg_dst_src3(UOP_MOV_INT_DOUBLE_64, ir, dst_reg, src_reg_d, src_reg_q, tag) #define uop_NOP_BARRIER(ir) uop_gen(UOP_NOP_BARRIER, ir) @@ -707,11 +721,11 @@ static inline void uop_gen_reg_src2_pointer(uint32_t uop_type, ir_data_t *ir, in #define uop_PACKSSDW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PACKSSDW, ir, dst_reg, src_reg_a, src_reg_b) #define uop_PACKUSWB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PACKUSWB, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PADDB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PADDB, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PADDW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PADDW, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PADDD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PADDD, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PADDSB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PADDSB, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PADDSW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PADDSW, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PADDB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PADDB, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PADDW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PADDW, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PADDD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PADDD, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PADDSB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PADDSB, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PADDSW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PADDSW, ir, dst_reg, src_reg_a, src_reg_b) #define uop_PADDUSB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PADDUSB, ir, dst_reg, src_reg_a, src_reg_b) #define uop_PADDUSW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PADDUSW, ir, dst_reg, src_reg_a, src_reg_b) @@ -722,38 +736,38 @@ static inline void uop_gen_reg_src2_pointer(uint32_t uop_type, ir_data_t *ir, in #define uop_PCMPGTW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PCMPGTW, ir, dst_reg, src_reg_a, src_reg_b) #define uop_PCMPGTD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PCMPGTD, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PF2ID(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_PF2ID, ir, dst_reg, src_reg) -#define uop_PFADD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PFADD, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PF2ID(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_PF2ID, ir, dst_reg, src_reg) +#define uop_PFADD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PFADD, ir, dst_reg, src_reg_a, src_reg_b) #define uop_PFCMPEQ(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PFCMPEQ, ir, dst_reg, src_reg_a, src_reg_b) #define uop_PFCMPGE(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PFCMPGE, ir, dst_reg, src_reg_a, src_reg_b) #define uop_PFCMPGT(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PFCMPGT, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PFMAX(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PFMAX, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PFMIN(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PFMIN, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PFMUL(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PFMUL, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PFRCP(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_PFRCP, ir, dst_reg, src_reg) -#define uop_PFRSQRT(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_PFRSQRT, ir, dst_reg, src_reg) -#define uop_PFSUB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PFSUB, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PI2FD(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_PI2FD, ir, dst_reg, src_reg) +#define uop_PFMAX(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PFMAX, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PFMIN(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PFMIN, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PFMUL(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PFMUL, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PFRCP(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_PFRCP, ir, dst_reg, src_reg) +#define uop_PFRSQRT(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_PFRSQRT, ir, dst_reg, src_reg) +#define uop_PFSUB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PFSUB, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PI2FD(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_PI2FD, ir, dst_reg, src_reg) -#define uop_PMADDWD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PMADDWD, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PMULHW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PMULHW, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PMULLW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PMULLW, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PMADDWD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PMADDWD, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PMULHW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PMULHW, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PMULLW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PMULLW, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PSLLW_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSLLW_IMM, ir, dst_reg, src_reg, imm) -#define uop_PSLLD_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSLLD_IMM, ir, dst_reg, src_reg, imm) -#define uop_PSLLQ_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSLLQ_IMM, ir, dst_reg, src_reg, imm) -#define uop_PSRAW_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSRAW_IMM, ir, dst_reg, src_reg, imm) -#define uop_PSRAD_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSRAD_IMM, ir, dst_reg, src_reg, imm) -#define uop_PSRAQ_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSRAQ_IMM, ir, dst_reg, src_reg, imm) -#define uop_PSRLW_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSRLW_IMM, ir, dst_reg, src_reg, imm) -#define uop_PSRLD_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSRLD_IMM, ir, dst_reg, src_reg, imm) -#define uop_PSRLQ_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSRLQ_IMM, ir, dst_reg, src_reg, imm) +#define uop_PSLLW_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSLLW_IMM, ir, dst_reg, src_reg, imm) +#define uop_PSLLD_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSLLD_IMM, ir, dst_reg, src_reg, imm) +#define uop_PSLLQ_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSLLQ_IMM, ir, dst_reg, src_reg, imm) +#define uop_PSRAW_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSRAW_IMM, ir, dst_reg, src_reg, imm) +#define uop_PSRAD_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSRAD_IMM, ir, dst_reg, src_reg, imm) +#define uop_PSRAQ_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSRAQ_IMM, ir, dst_reg, src_reg, imm) +#define uop_PSRLW_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSRLW_IMM, ir, dst_reg, src_reg, imm) +#define uop_PSRLD_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSRLD_IMM, ir, dst_reg, src_reg, imm) +#define uop_PSRLQ_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSRLQ_IMM, ir, dst_reg, src_reg, imm) -#define uop_PSUBB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PSUBB, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PSUBW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PSUBW, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PSUBD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PSUBD, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PSUBSB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PSUBSB, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PSUBSW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PSUBSW, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PSUBB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PSUBB, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PSUBW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PSUBW, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PSUBD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PSUBD, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PSUBSB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PSUBSB, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PSUBSW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PSUBSW, ir, dst_reg, src_reg_a, src_reg_b) #define uop_PSUBUSB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PSUBUSB, ir, dst_reg, src_reg_a, src_reg_b) #define uop_PSUBUSW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PSUBUSW, ir, dst_reg, src_reg_a, src_reg_b) @@ -764,12 +778,12 @@ static inline void uop_gen_reg_src2_pointer(uint32_t uop_type, ir_data_t *ir, in #define uop_PUNPCKLWD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PUNPCKLWD, ir, dst_reg, src_reg_a, src_reg_b) #define uop_PUNPCKLDQ(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PUNPCKLDQ, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_STORE_PTR_IMM(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM, ir, p, imm) -#define uop_STORE_PTR_IMM_8(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM_8, ir, p, imm) -#define uop_STORE_PTR_IMM_16(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM_16, ir, p, imm) +#define uop_STORE_PTR_IMM(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM, ir, p, imm) +#define uop_STORE_PTR_IMM_8(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM_8, ir, p, imm) +#define uop_STORE_PTR_IMM_16(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM_16, ir, p, imm) #define uop_TEST_JNS_DEST(ir, src_reg) uop_gen_reg_src1(UOP_TEST_JNS_DEST, ir, src_reg) -#define uop_TEST_JS_DEST(ir, src_reg) uop_gen_reg_src1(UOP_TEST_JS_DEST, ir, src_reg) +#define uop_TEST_JS_DEST(ir, src_reg) uop_gen_reg_src1(UOP_TEST_JS_DEST, ir, src_reg) #ifdef DEBUG_EXTRA #define uop_LOG_INSTR(ir, imm) uop_gen_imm(UOP_LOG_INSTR, ir, imm) diff --git a/includes/private/codegen/codegen_ops.h b/includes/private/codegen/codegen_ops.h index 361479b6..aaf06584 100644 --- a/includes/private/codegen/codegen_ops.h +++ b/includes/private/codegen/codegen_ops.h @@ -5,7 +5,8 @@ struct ir_data_t; -typedef uint32_t (*RecompOpFn)(codeblock_t *block, struct ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); +typedef uint32_t (*RecompOpFn)(codeblock_t *block, struct ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, + uint32_t op_pc); extern RecompOpFn recomp_opcodes[512]; extern RecompOpFn recomp_opcodes_0f[512]; diff --git a/includes/private/codegen/codegen_ops_3dnow.h b/includes/private/codegen/codegen_ops_3dnow.h index b23b5551..2c9a3845 100644 --- a/includes/private/codegen/codegen_ops_3dnow.h +++ b/includes/private/codegen/codegen_ops_3dnow.h @@ -17,5 +17,4 @@ uint32_t ropPFSUB(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe uint32_t ropPFSUBR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropPI2FD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); - #endif /* _CODEGEN_OPS_3DNOW_H_ */ diff --git a/includes/private/codegen/codegen_ops_arith.h b/includes/private/codegen/codegen_ops_arith.h index b7a7e385..5879cac8 100644 --- a/includes/private/codegen/codegen_ops_arith.h +++ b/includes/private/codegen/codegen_ops_arith.h @@ -57,7 +57,6 @@ uint32_t rop81_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet uint32_t rop83_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t rop83_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); - uint32_t ropDEC_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropDEC_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); @@ -66,5 +65,4 @@ uint32_t ropINC_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t uint32_t ropINCDEC(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); - #endif /* _CODEGEN_OPS_ARITH_H_ */ diff --git a/includes/private/codegen/codegen_ops_branch.h b/includes/private/codegen/codegen_ops_branch.h index c49231ce..bd0f9220 100644 --- a/includes/private/codegen/codegen_ops_branch.h +++ b/includes/private/codegen/codegen_ops_branch.h @@ -71,5 +71,4 @@ uint32_t ropLOOP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet uint32_t ropLOOPE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropLOOPNE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); - #endif /* _CODEGEN_OPS_BRANCH_H_ */ diff --git a/includes/private/codegen/codegen_ops_fpu_arith.h b/includes/private/codegen/codegen_ops_fpu_arith.h index 6e5eeae2..6210cb70 100644 --- a/includes/private/codegen/codegen_ops_fpu_arith.h +++ b/includes/private/codegen/codegen_ops_fpu_arith.h @@ -65,5 +65,4 @@ uint32_t ropFCHS(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet uint32_t ropFSQRT(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropFTST(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); - #endif /* _CODEGEN_OPS_FPU_ARITH_H_ */ diff --git a/includes/private/codegen/codegen_ops_fpu_constant.h b/includes/private/codegen/codegen_ops_fpu_constant.h index d57960f2..89009faf 100644 --- a/includes/private/codegen/codegen_ops_fpu_constant.h +++ b/includes/private/codegen/codegen_ops_fpu_constant.h @@ -4,5 +4,4 @@ uint32_t ropFLD1(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropFLDZ(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); - #endif /* _CODEGEN_OPS_FPU_CONSTANT_H_ */ diff --git a/includes/private/codegen/codegen_ops_fpu_loadstore.h b/includes/private/codegen/codegen_ops_fpu_loadstore.h index 64b9601b..0e4f662e 100644 --- a/includes/private/codegen/codegen_ops_fpu_loadstore.h +++ b/includes/private/codegen/codegen_ops_fpu_loadstore.h @@ -19,5 +19,4 @@ uint32_t ropFISTl(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe uint32_t ropFISTPl(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropFISTPq(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); - #endif /* _CODEGEN_OPS_FPU_LOADSTORE_H_ */ diff --git a/includes/private/codegen/codegen_ops_fpu_misc.h b/includes/private/codegen/codegen_ops_fpu_misc.h index 8af7d7c2..34f92977 100644 --- a/includes/private/codegen/codegen_ops_fpu_misc.h +++ b/includes/private/codegen/codegen_ops_fpu_misc.h @@ -14,5 +14,4 @@ uint32_t ropFSTSW_AX(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t uint32_t ropFXCH(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); - #endif /* _CODEGEN_OPS_FPU_MISC_H_ */ diff --git a/includes/private/codegen/codegen_ops_helpers.h b/includes/private/codegen/codegen_ops_helpers.h index dd11f27b..845bbd41 100644 --- a/includes/private/codegen/codegen_ops_helpers.h +++ b/includes/private/codegen/codegen_ops_helpers.h @@ -4,100 +4,78 @@ #include "386_common.h" #include "codegen_backend.h" -static inline int LOAD_SP_WITH_OFFSET(ir_data_t *ir, int offset) -{ - if (stack32) - { - if (offset) - { +static inline int LOAD_SP_WITH_OFFSET(ir_data_t *ir, int offset) { + if (stack32) { + if (offset) { uop_ADD_IMM(ir, IREG_eaaddr, IREG_ESP, offset); return IREG_eaaddr; - } - else + } else return IREG_ESP; - } - else - { - if (offset) - { + } else { + if (offset) { uop_ADD_IMM(ir, IREG_eaaddr_W, IREG_SP, offset); uop_MOVZX(ir, IREG_eaaddr, IREG_eaaddr_W); return IREG_eaaddr; - } - else - { + } else { uop_MOVZX(ir, IREG_eaaddr, IREG_SP); return IREG_eaaddr; } } } -static inline int LOAD_SP(ir_data_t *ir) -{ - return LOAD_SP_WITH_OFFSET(ir, 0); -} +static inline int LOAD_SP(ir_data_t *ir) { return LOAD_SP_WITH_OFFSET(ir, 0); } -static inline void ADD_SP(ir_data_t *ir, int offset) -{ +static inline void ADD_SP(ir_data_t *ir, int offset) { if (stack32) uop_ADD_IMM(ir, IREG_ESP, IREG_ESP, offset); else uop_ADD_IMM(ir, IREG_SP, IREG_SP, offset); } -static inline void SUB_SP(ir_data_t *ir, int offset) -{ +static inline void SUB_SP(ir_data_t *ir, int offset) { if (stack32) uop_SUB_IMM(ir, IREG_ESP, IREG_ESP, offset); else uop_SUB_IMM(ir, IREG_SP, IREG_SP, offset); } -static inline void fpu_POP(codeblock_t *block, ir_data_t *ir) -{ +static inline void fpu_POP(codeblock_t *block, ir_data_t *ir) { if (block->flags & CODEBLOCK_STATIC_TOP) uop_MOV_IMM(ir, IREG_FPU_TOP, cpu_state.TOP + 1); else uop_ADD_IMM(ir, IREG_FPU_TOP, IREG_FPU_TOP, 1); } -static inline void fpu_POP2(codeblock_t *block, ir_data_t *ir) -{ +static inline void fpu_POP2(codeblock_t *block, ir_data_t *ir) { if (block->flags & CODEBLOCK_STATIC_TOP) uop_MOV_IMM(ir, IREG_FPU_TOP, cpu_state.TOP + 2); else uop_ADD_IMM(ir, IREG_FPU_TOP, IREG_FPU_TOP, 2); } -static inline void fpu_PUSH(codeblock_t *block, ir_data_t *ir) -{ +static inline void fpu_PUSH(codeblock_t *block, ir_data_t *ir) { if (block->flags & CODEBLOCK_STATIC_TOP) uop_MOV_IMM(ir, IREG_FPU_TOP, cpu_state.TOP - 1); else uop_SUB_IMM(ir, IREG_FPU_TOP, IREG_FPU_TOP, 1); } -static inline void CHECK_SEG_LIMITS(codeblock_t *block, ir_data_t *ir, x86seg *seg, int addr_reg, int end_offset) -{ +static inline void CHECK_SEG_LIMITS(codeblock_t *block, ir_data_t *ir, x86seg *seg, int addr_reg, int end_offset) { if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) return; uop_CMP_JB(ir, addr_reg, ireg_seg_limit_low(seg), codegen_gpf_rout); - if (end_offset) - { + if (end_offset) { uop_ADD_IMM(ir, IREG_temp3, addr_reg, end_offset); uop_CMP_JNBE(ir, IREG_temp3, ireg_seg_limit_high(seg), codegen_gpf_rout); - } - else + } else uop_CMP_JNBE(ir, addr_reg, ireg_seg_limit_high(seg), codegen_gpf_rout); } -static inline void LOAD_IMMEDIATE_FROM_RAM_8(codeblock_t *block, ir_data_t *ir, int dest_reg, uint32_t addr) -{ +static inline void LOAD_IMMEDIATE_FROM_RAM_8(codeblock_t *block, ir_data_t *ir, int dest_reg, uint32_t addr) { uop_MOVZX_REG_PTR_8(ir, dest_reg, get_ram_ptr(addr)); } void LOAD_IMMEDIATE_FROM_RAM_16_unaligned(codeblock_t *block, ir_data_t *ir, int dest_reg, uint32_t addr); -static inline void LOAD_IMMEDIATE_FROM_RAM_16(codeblock_t *block, ir_data_t *ir, int dest_reg, uint32_t addr) -{ +static inline void LOAD_IMMEDIATE_FROM_RAM_16(codeblock_t *block, ir_data_t *ir, int dest_reg, uint32_t addr) { if ((addr & 0xfff) == 0xfff) LOAD_IMMEDIATE_FROM_RAM_16_unaligned(block, ir, dest_reg, addr); else @@ -105,8 +83,7 @@ static inline void LOAD_IMMEDIATE_FROM_RAM_16(codeblock_t *block, ir_data_t *ir, } void LOAD_IMMEDIATE_FROM_RAM_32_unaligned(codeblock_t *block, ir_data_t *ir, int dest_reg, uint32_t addr); -static inline void LOAD_IMMEDIATE_FROM_RAM_32(codeblock_t *block, ir_data_t *ir, int dest_reg, uint32_t addr) -{ +static inline void LOAD_IMMEDIATE_FROM_RAM_32(codeblock_t *block, ir_data_t *ir, int dest_reg, uint32_t addr) { if ((addr & 0xfff) >= 0xffd) LOAD_IMMEDIATE_FROM_RAM_32_unaligned(block, ir, dest_reg, addr); else @@ -114,19 +91,17 @@ static inline void LOAD_IMMEDIATE_FROM_RAM_32(codeblock_t *block, ir_data_t *ir, } int codegen_can_unroll_full(codeblock_t *block, ir_data_t *ir, uint32_t next_pc, uint32_t dest_addr); -static inline int codegen_can_unroll(codeblock_t *block, ir_data_t *ir, uint32_t next_pc, uint32_t dest_addr) -{ +static inline int codegen_can_unroll(codeblock_t *block, ir_data_t *ir, uint32_t next_pc, uint32_t dest_addr) { if (block->flags & CODEBLOCK_BYTE_MASK) return 0; /*Is dest within block?*/ if (dest_addr > next_pc) return 0; - if ((cs+dest_addr) < block->pc) + if ((cs + dest_addr) < block->pc) return 0; return codegen_can_unroll_full(block, ir, next_pc, dest_addr); } - #endif /* _CODEGEN_OPS_HELPERS_H_ */ diff --git a/includes/private/codegen/codegen_ops_jump.h b/includes/private/codegen/codegen_ops_jump.h index d4aa921e..9700681c 100644 --- a/includes/private/codegen/codegen_ops_jump.h +++ b/includes/private/codegen/codegen_ops_jump.h @@ -23,5 +23,4 @@ uint32_t ropRETF_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t uint32_t ropRETF_imm_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropRETF_imm_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); - #endif /* _CODEGEN_OPS_JUMP_H_ */ diff --git a/includes/private/codegen/codegen_ops_logic.h b/includes/private/codegen/codegen_ops_logic.h index 5db9ebb2..57abd3dd 100644 --- a/includes/private/codegen/codegen_ops_logic.h +++ b/includes/private/codegen/codegen_ops_logic.h @@ -38,5 +38,4 @@ uint32_t ropXOR_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ uint32_t ropXOR_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropXOR_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); - #endif /* _CODEGEN_OPS_LOGIC_H_ */ diff --git a/includes/private/codegen/codegen_ops_misc.h b/includes/private/codegen/codegen_ops_misc.h index 2f3f6898..80b155bc 100644 --- a/includes/private/codegen/codegen_ops_misc.h +++ b/includes/private/codegen/codegen_ops_misc.h @@ -39,5 +39,4 @@ uint32_t ropSTD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetc uint32_t ropCLI(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropSTI(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); - #endif /* _CODEGEN_OPS_MISC_H_ */ diff --git a/includes/private/codegen/codegen_ops_mmx_arith.h b/includes/private/codegen/codegen_ops_mmx_arith.h index 74e92b7f..9c5e34ec 100644 --- a/includes/private/codegen/codegen_ops_mmx_arith.h +++ b/includes/private/codegen/codegen_ops_mmx_arith.h @@ -20,5 +20,4 @@ uint32_t ropPMADDWD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t uint32_t ropPMULHW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropPMULLW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); - #endif /* _CODEGEN_OPS_MMX_ARITH_H_ */ diff --git a/includes/private/codegen/codegen_ops_mmx_cmp.h b/includes/private/codegen/codegen_ops_mmx_cmp.h index 485656c3..ed25e95c 100644 --- a/includes/private/codegen/codegen_ops_mmx_cmp.h +++ b/includes/private/codegen/codegen_ops_mmx_cmp.h @@ -7,5 +7,4 @@ uint32_t ropPCMPGTB(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t uint32_t ropPCMPGTW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropPCMPGTD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); - #endif /* _CODEGEN_OPS_MMX_CMP_H_ */ diff --git a/includes/private/codegen/codegen_ops_mmx_loadstore.h b/includes/private/codegen/codegen_ops_mmx_loadstore.h index 34a4e844..1003d3f3 100644 --- a/includes/private/codegen/codegen_ops_mmx_loadstore.h +++ b/includes/private/codegen/codegen_ops_mmx_loadstore.h @@ -6,5 +6,4 @@ uint32_t ropMOVD_d_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t uint32_t ropMOVQ_r_q(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropMOVQ_q_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); - #endif /* _CODEGEN_OPS_MMX_LOADSTORE_H_ */ diff --git a/includes/private/codegen/codegen_ops_mmx_logic.h b/includes/private/codegen/codegen_ops_mmx_logic.h index 374950b4..e9944fd1 100644 --- a/includes/private/codegen/codegen_ops_mmx_logic.h +++ b/includes/private/codegen/codegen_ops_mmx_logic.h @@ -5,5 +5,4 @@ uint32_t ropPANDN(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe uint32_t ropPOR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropPXOR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); - #endif /* _CODEGEN_OPS_MMX_LOGIC_H_ */ diff --git a/includes/private/codegen/codegen_ops_mmx_pack.h b/includes/private/codegen/codegen_ops_mmx_pack.h index 3e43a8df..84132012 100644 --- a/includes/private/codegen/codegen_ops_mmx_pack.h +++ b/includes/private/codegen/codegen_ops_mmx_pack.h @@ -10,5 +10,4 @@ uint32_t ropPUNPCKHBW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_ uint32_t ropPUNPCKHWD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropPUNPCKHDQ(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); - #endif /* _CODEGEN_OPS_MMX_PACK_H_ */ diff --git a/includes/private/codegen/codegen_ops_mmx_shift.h b/includes/private/codegen/codegen_ops_mmx_shift.h index af3de606..8fb867f4 100644 --- a/includes/private/codegen/codegen_ops_mmx_shift.h +++ b/includes/private/codegen/codegen_ops_mmx_shift.h @@ -8,5 +8,4 @@ uint32_t ropPSLLW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fe uint32_t ropPSLLD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropPSLLQ(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); - #endif /* _CODEGEN_OPS_MMX_SHIFT_H_ */ diff --git a/includes/private/codegen/codegen_ops_mov.h b/includes/private/codegen/codegen_ops_mov.h index af92329e..e8860fd1 100644 --- a/includes/private/codegen/codegen_ops_mov.h +++ b/includes/private/codegen/codegen_ops_mov.h @@ -44,5 +44,4 @@ uint32_t ropXCHG_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t uint32_t ropXLAT(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); - #endif /* _CODEGEN_OPS_MOV_H_ */ diff --git a/includes/private/codegen/codegen_ops_shift.h b/includes/private/codegen/codegen_ops_shift.h index 0c277092..67043ef3 100644 --- a/includes/private/codegen/codegen_ops_shift.h +++ b/includes/private/codegen/codegen_ops_shift.h @@ -17,5 +17,4 @@ uint32_t ropSHLD_32_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint3 uint32_t ropSHRD_16_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropSHRD_32_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); - #endif /* _CODEGEN_OPS_SHIFT_H_ */ diff --git a/includes/private/codegen/codegen_ops_stack.h b/includes/private/codegen/codegen_ops_stack.h index a5dab73f..f6b8dd3d 100644 --- a/includes/private/codegen/codegen_ops_stack.h +++ b/includes/private/codegen/codegen_ops_stack.h @@ -50,5 +50,4 @@ uint32_t ropPOPA_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t uint32_t ropPUSHF(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropPUSHFD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); - #endif /* _CODEGEN_OPS_STACK_H_ */ diff --git a/includes/private/codegen/codegen_reg.h b/includes/private/codegen/codegen_reg.h index 447a4cfc..8a51d56c 100644 --- a/includes/private/codegen/codegen_reg.h +++ b/includes/private/codegen/codegen_reg.h @@ -5,44 +5,43 @@ #define IREG_SIZE_SHIFT 8 #define IREG_SIZE_MASK (7 << IREG_SIZE_SHIFT) -#define IREG_GET_REG(reg) ((reg) & IREG_REG_MASK) -#define IREG_GET_SIZE(reg) ((reg) & IREG_SIZE_MASK) +#define IREG_GET_REG(reg) ((reg)&IREG_REG_MASK) +#define IREG_GET_SIZE(reg) ((reg)&IREG_SIZE_MASK) -#define IREG_SIZE_L (0 << IREG_SIZE_SHIFT) -#define IREG_SIZE_W (1 << IREG_SIZE_SHIFT) -#define IREG_SIZE_B (2 << IREG_SIZE_SHIFT) +#define IREG_SIZE_L (0 << IREG_SIZE_SHIFT) +#define IREG_SIZE_W (1 << IREG_SIZE_SHIFT) +#define IREG_SIZE_B (2 << IREG_SIZE_SHIFT) #define IREG_SIZE_BH (3 << IREG_SIZE_SHIFT) -#define IREG_SIZE_D (4 << IREG_SIZE_SHIFT) -#define IREG_SIZE_Q (5 << IREG_SIZE_SHIFT) +#define IREG_SIZE_D (4 << IREG_SIZE_SHIFT) +#define IREG_SIZE_Q (5 << IREG_SIZE_SHIFT) -enum -{ - IREG_EAX = 0, - IREG_ECX = 1, - IREG_EDX = 2, - IREG_EBX = 3, - IREG_ESP = 4, - IREG_EBP = 5, - IREG_ESI = 6, - IREG_EDI = 7, +enum { + IREG_EAX = 0, + IREG_ECX = 1, + IREG_EDX = 2, + IREG_EBX = 3, + IREG_ESP = 4, + IREG_EBP = 5, + IREG_ESI = 6, + IREG_EDI = 7, - IREG_flags_op = 8, - IREG_flags_res = 9, - IREG_flags_op1 = 10, - IREG_flags_op2 = 11, + IREG_flags_op = 8, + IREG_flags_res = 9, + IREG_flags_op1 = 10, + IREG_flags_op2 = 11, - IREG_pc = 12, - IREG_oldpc = 13, + IREG_pc = 12, + IREG_oldpc = 13, - IREG_eaaddr = 14, - IREG_ea_seg = 15, - IREG_op32 = 16, - IREG_ssegsx = 17, - - IREG_rm_mod_reg = 18, - - IREG_ins = 19, - IREG_cycles = 20, + IREG_eaaddr = 14, + IREG_ea_seg = 15, + IREG_op32 = 16, + IREG_ssegsx = 17, + + IREG_rm_mod_reg = 18, + + IREG_ins = 19, + IREG_cycles = 20, IREG_CS_base = 21, IREG_DS_base = 22, @@ -58,19 +57,19 @@ enum IREG_GS_seg = 31, IREG_SS_seg = 32, - /*Temporary registers are stored on the stack, and are not guaranteed to + /*Temporary registers are stored on the stack, and are not guaranteed to be preserved across uOPs. They will not be written back if they will not be read again.*/ - IREG_temp0 = 33, - IREG_temp1 = 34, - IREG_temp2 = 35, - IREG_temp3 = 36, + IREG_temp0 = 33, + IREG_temp1 = 34, + IREG_temp2 = 35, + IREG_temp3 = 36, IREG_FPU_TOP = 37, - IREG_temp0d = 38, - IREG_temp1d = 39, - + IREG_temp0d = 38, + IREG_temp1d = 39, + /*FPU stack registers are physical registers. Use IREG_ST() / IREG_tag() to access. When CODEBLOCK_STATIC_TOP is set, the physical register number will be @@ -85,7 +84,7 @@ enum IREG_ST5 = 45, IREG_ST6 = 46, IREG_ST7 = 47, - + IREG_tag0 = 48, IREG_tag1 = 49, IREG_tag2 = 50, @@ -103,7 +102,7 @@ enum IREG_ST5_i64 = 61, IREG_ST6_i64 = 62, IREG_ST7_i64 = 63, - + IREG_MM0x = 64, IREG_MM1x = 65, IREG_MM2x = 66, @@ -112,13 +111,13 @@ enum IREG_MM5x = 69, IREG_MM6x = 70, IREG_MM7x = 71, - + IREG_NPXCx = 72, IREG_NPXSx = 73, - + IREG_flagsx = 74, IREG_eflagsx = 75, - + IREG_CS_limit_low = 76, IREG_DS_limit_low = 77, IREG_ES_limit_low = 78, @@ -133,62 +132,62 @@ enum IREG_GS_limit_high = 86, IREG_SS_limit_high = 87, - IREG_COUNT = 88, - - IREG_INVALID = 255, - - IREG_AX = IREG_EAX + IREG_SIZE_W, - IREG_CX = IREG_ECX + IREG_SIZE_W, - IREG_DX = IREG_EDX + IREG_SIZE_W, - IREG_BX = IREG_EBX + IREG_SIZE_W, - IREG_SP = IREG_ESP + IREG_SIZE_W, - IREG_BP = IREG_EBP + IREG_SIZE_W, - IREG_SI = IREG_ESI + IREG_SIZE_W, - IREG_DI = IREG_EDI + IREG_SIZE_W, + IREG_COUNT = 88, - IREG_AL = IREG_EAX + IREG_SIZE_B, - IREG_CL = IREG_ECX + IREG_SIZE_B, - IREG_DL = IREG_EDX + IREG_SIZE_B, - IREG_BL = IREG_EBX + IREG_SIZE_B, + IREG_INVALID = 255, - IREG_AH = IREG_EAX + IREG_SIZE_BH, - IREG_CH = IREG_ECX + IREG_SIZE_BH, - IREG_DH = IREG_EDX + IREG_SIZE_BH, - IREG_BH = IREG_EBX + IREG_SIZE_BH, - - IREG_flags_res_W = IREG_flags_res + IREG_SIZE_W, - IREG_flags_op1_W = IREG_flags_op1 + IREG_SIZE_W, - IREG_flags_op2_W = IREG_flags_op2 + IREG_SIZE_W, + IREG_AX = IREG_EAX + IREG_SIZE_W, + IREG_CX = IREG_ECX + IREG_SIZE_W, + IREG_DX = IREG_EDX + IREG_SIZE_W, + IREG_BX = IREG_EBX + IREG_SIZE_W, + IREG_SP = IREG_ESP + IREG_SIZE_W, + IREG_BP = IREG_EBP + IREG_SIZE_W, + IREG_SI = IREG_ESI + IREG_SIZE_W, + IREG_DI = IREG_EDI + IREG_SIZE_W, - IREG_flags_res_B = IREG_flags_res + IREG_SIZE_B, - IREG_flags_op1_B = IREG_flags_op1 + IREG_SIZE_B, - IREG_flags_op2_B = IREG_flags_op2 + IREG_SIZE_B, + IREG_AL = IREG_EAX + IREG_SIZE_B, + IREG_CL = IREG_ECX + IREG_SIZE_B, + IREG_DL = IREG_EDX + IREG_SIZE_B, + IREG_BL = IREG_EBX + IREG_SIZE_B, - IREG_temp0_W = IREG_temp0 + IREG_SIZE_W, - IREG_temp1_W = IREG_temp1 + IREG_SIZE_W, - IREG_temp2_W = IREG_temp2 + IREG_SIZE_W, - IREG_temp3_W = IREG_temp3 + IREG_SIZE_W, - - IREG_temp0_B = IREG_temp0 + IREG_SIZE_B, - IREG_temp1_B = IREG_temp1 + IREG_SIZE_B, - IREG_temp2_B = IREG_temp2 + IREG_SIZE_B, - IREG_temp3_B = IREG_temp3 + IREG_SIZE_B, + IREG_AH = IREG_EAX + IREG_SIZE_BH, + IREG_CH = IREG_ECX + IREG_SIZE_BH, + IREG_DH = IREG_EDX + IREG_SIZE_BH, + IREG_BH = IREG_EBX + IREG_SIZE_BH, - IREG_temp0_D = IREG_temp0d + IREG_SIZE_D, - IREG_temp1_D = IREG_temp1d + IREG_SIZE_D, + IREG_flags_res_W = IREG_flags_res + IREG_SIZE_W, + IREG_flags_op1_W = IREG_flags_op1 + IREG_SIZE_W, + IREG_flags_op2_W = IREG_flags_op2 + IREG_SIZE_W, - IREG_temp0_Q = IREG_temp0d + IREG_SIZE_Q, - IREG_temp1_Q = IREG_temp1d + IREG_SIZE_Q, + IREG_flags_res_B = IREG_flags_res + IREG_SIZE_B, + IREG_flags_op1_B = IREG_flags_op1 + IREG_SIZE_B, + IREG_flags_op2_B = IREG_flags_op2 + IREG_SIZE_B, + + IREG_temp0_W = IREG_temp0 + IREG_SIZE_W, + IREG_temp1_W = IREG_temp1 + IREG_SIZE_W, + IREG_temp2_W = IREG_temp2 + IREG_SIZE_W, + IREG_temp3_W = IREG_temp3 + IREG_SIZE_W, + + IREG_temp0_B = IREG_temp0 + IREG_SIZE_B, + IREG_temp1_B = IREG_temp1 + IREG_SIZE_B, + IREG_temp2_B = IREG_temp2 + IREG_SIZE_B, + IREG_temp3_B = IREG_temp3 + IREG_SIZE_B, + + IREG_temp0_D = IREG_temp0d + IREG_SIZE_D, + IREG_temp1_D = IREG_temp1d + IREG_SIZE_D, + + IREG_temp0_Q = IREG_temp0d + IREG_SIZE_Q, + IREG_temp1_Q = IREG_temp1d + IREG_SIZE_Q, + + IREG_eaaddr_W = IREG_eaaddr + IREG_SIZE_W, - IREG_eaaddr_W = IREG_eaaddr + IREG_SIZE_W, - IREG_CS_seg_W = IREG_CS_seg + IREG_SIZE_W, IREG_DS_seg_W = IREG_DS_seg + IREG_SIZE_W, IREG_ES_seg_W = IREG_ES_seg + IREG_SIZE_W, IREG_FS_seg_W = IREG_FS_seg + IREG_SIZE_W, IREG_GS_seg_W = IREG_GS_seg + IREG_SIZE_W, IREG_SS_seg_W = IREG_SS_seg + IREG_SIZE_W, - + IREG_MM0 = IREG_MM0x + IREG_SIZE_Q, IREG_MM1 = IREG_MM1x + IREG_SIZE_Q, IREG_MM2 = IREG_MM2x + IREG_SIZE_Q, @@ -197,22 +196,22 @@ enum IREG_MM5 = IREG_MM5x + IREG_SIZE_Q, IREG_MM6 = IREG_MM6x + IREG_SIZE_Q, IREG_MM7 = IREG_MM7x + IREG_SIZE_Q, - + IREG_NPXC = IREG_NPXCx + IREG_SIZE_W, IREG_NPXS = IREG_NPXSx + IREG_SIZE_W, - + IREG_ssegs = IREG_ssegsx + IREG_SIZE_B, - + IREG_flags = IREG_flagsx + IREG_SIZE_W, IREG_eflags = IREG_eflagsx + IREG_SIZE_W }; -#define IREG_8(reg) (((reg) & 4) ? (((reg) & 3) + IREG_AH) : ((reg) + IREG_AL)) +#define IREG_8(reg) (((reg)&4) ? (((reg)&3) + IREG_AH) : ((reg) + IREG_AL)) #define IREG_16(reg) ((reg) + IREG_AX) #define IREG_32(reg) ((reg) + IREG_EAX) -#define IREG_ST(r) (IREG_ST0 + ((cpu_state.TOP + (r)) & 7) + IREG_SIZE_D) -#define IREG_ST_i64(r) (IREG_ST0_i64 + ((cpu_state.TOP + (r)) & 7) + IREG_SIZE_Q) +#define IREG_ST(r) (IREG_ST0 + ((cpu_state.TOP + (r)) & 7) + IREG_SIZE_D) +#define IREG_ST_i64(r) (IREG_ST0_i64 + ((cpu_state.TOP + (r)) & 7) + IREG_SIZE_Q) #define IREG_tag(r) (IREG_tag0 + ((cpu_state.TOP + (r)) & 7)) #define IREG_tag_B(r) (IREG_tag0 + ((cpu_state.TOP + (r)) & 7) + IREG_SIZE_B) @@ -220,8 +219,7 @@ enum #define IREG_TOP_diff_stack_offset 32 -static inline int ireg_seg_base(x86seg *seg) -{ +static inline int ireg_seg_base(x86seg *seg) { if (seg == &cpu_state.seg_cs) return IREG_CS_base; if (seg == &cpu_state.seg_ds) @@ -238,8 +236,7 @@ static inline int ireg_seg_base(x86seg *seg) return 0; } -static inline int ireg_seg_limit_low(x86seg *seg) -{ +static inline int ireg_seg_limit_low(x86seg *seg) { if (seg == &cpu_state.seg_cs) return IREG_CS_limit_low; if (seg == &cpu_state.seg_ds) @@ -255,8 +252,7 @@ static inline int ireg_seg_limit_low(x86seg *seg) fatal("ireg_seg_limit_low : unknown segment\n"); return 0; } -static inline int ireg_seg_limit_high(x86seg *seg) -{ +static inline int ireg_seg_limit_high(x86seg *seg) { if (seg == &cpu_state.seg_cs) return IREG_CS_limit_high; if (seg == &cpu_state.seg_ds) @@ -279,10 +275,9 @@ extern uint8_t reg_last_version[IREG_COUNT]; apparently required or not. Do not optimise out.*/ #define REG_FLAGS_REQUIRED (1 << 0) /*This register and the parent uOP have been optimised out.*/ -#define REG_FLAGS_DEAD (1 << 1) +#define REG_FLAGS_DEAD (1 << 1) -typedef struct -{ +typedef struct { /*Refcount of pending reads on this register version*/ uint8_t refcount; /*Flags*/ @@ -299,14 +294,12 @@ extern reg_version_t reg_version[IREG_COUNT][256]; can be optimised out*/ extern uint16_t reg_dead_list; -static inline void add_to_dead_list(reg_version_t *regv, int reg, int version) -{ +static inline void add_to_dead_list(reg_version_t *regv, int reg, int version) { regv->next = reg_dead_list; reg_dead_list = version | (reg << 8); } -typedef struct -{ +typedef struct { uint16_t reg; uint16_t version; } ir_reg_t; @@ -320,11 +313,10 @@ extern int max_version_refcount; #define REG_VERSION_MAX 250 #define REG_REFCOUNT_MAX 250 -static inline ir_reg_t codegen_reg_read(int reg) -{ +static inline ir_reg_t codegen_reg_read(int reg) { ir_reg_t ireg; reg_version_t *version; - + #ifndef RELEASE_BUILD if (IREG_GET_REG(reg) == IREG_INVALID) fatal("codegen_reg_read - IREG_INVALID\n"); @@ -339,43 +331,43 @@ static inline ir_reg_t codegen_reg_read(int reg) fatal("codegen_reg_read - refcount overflow\n"); else #endif - if (version->refcount > REG_REFCOUNT_MAX) + if (version->refcount > REG_REFCOUNT_MAX) CPU_BLOCK_END(); if (version->refcount > max_version_refcount) max_version_refcount = version->refcount; -// pclog("codegen_reg_read: %i %i %i\n", reg & IREG_REG_MASK, ireg.version, reg_version_refcount[IREG_GET_REG(ireg.reg)][ireg.version]); + // pclog("codegen_reg_read: %i %i %i\n", reg & IREG_REG_MASK, ireg.version, + // reg_version_refcount[IREG_GET_REG(ireg.reg)][ireg.version]); return ireg; } int reg_is_native_size(ir_reg_t ir_reg); -static inline ir_reg_t codegen_reg_write(int reg, int uop_nr) -{ +static inline ir_reg_t codegen_reg_write(int reg, int uop_nr) { ir_reg_t ireg; int last_version = reg_last_version[IREG_GET_REG(reg)]; reg_version_t *version; - + #ifndef RELEASE_BUILD if (IREG_GET_REG(reg) == IREG_INVALID) fatal("codegen_reg_write - IREG_INVALID\n"); #endif ireg.reg = reg; ireg.version = last_version + 1; - + if (IREG_GET_REG(reg) > IREG_EBX && last_version && !reg_version[IREG_GET_REG(reg)][last_version].refcount && - !(reg_version[IREG_GET_REG(reg)][last_version].flags & REG_FLAGS_REQUIRED)) - { - if (reg_is_native_size(ireg)) /*Non-native size registers have an implicit dependency on the previous version, so don't add to dead list*/ + !(reg_version[IREG_GET_REG(reg)][last_version].flags & REG_FLAGS_REQUIRED)) { + if (reg_is_native_size(ireg)) /*Non-native size registers have an implicit dependency on the previous version, so + don't add to dead list*/ add_to_dead_list(®_version[IREG_GET_REG(reg)][last_version], IREG_GET_REG(reg), last_version); } - + reg_last_version[IREG_GET_REG(reg)]++; #ifndef RELEASE_BUILD if (!reg_last_version[IREG_GET_REG(reg)]) fatal("codegen_reg_write - version overflow\n"); else #endif - if (reg_last_version[IREG_GET_REG(reg)] > REG_VERSION_MAX) + if (reg_last_version[IREG_GET_REG(reg)] > REG_VERSION_MAX) CPU_BLOCK_END(); if (reg_last_version[IREG_GET_REG(reg)] > max_version_refcount) max_version_refcount = reg_last_version[IREG_GET_REG(reg)]; @@ -384,14 +376,11 @@ static inline ir_reg_t codegen_reg_write(int reg, int uop_nr) version->refcount = 0; version->flags = 0; version->parent_uop = uop_nr; -// pclog("codegen_reg_write: %i\n", reg & IREG_REG_MASK); + // pclog("codegen_reg_write: %i\n", reg & IREG_REG_MASK); return ireg; } -static inline int ir_reg_is_invalid(ir_reg_t ir_reg) -{ - return (IREG_GET_REG(ir_reg.reg) == IREG_INVALID); -} +static inline int ir_reg_is_invalid(ir_reg_t ir_reg) { return (IREG_GET_REG(ir_reg.reg) == IREG_INVALID); } struct ir_data_t; diff --git a/includes/private/codegen/codegen_timing_common.h b/includes/private/codegen/codegen_timing_common.h index 87c34f15..6bef3e05 100644 --- a/includes/private/codegen/codegen_timing_common.h +++ b/includes/private/codegen/codegen_timing_common.h @@ -5,11 +5,11 @@ /*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) +#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 DSTDEP_RM (1ull << 3) #define SRCDEP_SHIFT 4 #define DSTDEP_SHIFT 12 @@ -42,46 +42,44 @@ /*Instruction is MMX shift or pack/unpack instruction*/ #define MMX_SHIFTPACK (1ull << 22) /*Instruction is MMX multiply instruction*/ -#define MMX_MULTIPLY (1ull << 23) +#define MMX_MULTIPLY (1ull << 23) /*Instruction pops the FPU stack*/ -#define FPU_POP (1ull << 24) +#define FPU_POP (1ull << 24) /*Instruction pops the FPU stack twice*/ -#define FPU_POP2 (1ull << 25) +#define FPU_POP2 (1ull << 25) /*Instruction pushes onto the FPU stack*/ -#define FPU_PUSH (1ull << 26) +#define FPU_PUSH (1ull << 26) /*Instruction writes to ST(0)*/ -#define FPU_WRITE_ST0 (1ull << 27) +#define FPU_WRITE_ST0 (1ull << 27) /*Instruction reads from ST(0)*/ -#define FPU_READ_ST0 (1ull << 28) +#define FPU_READ_ST0 (1ull << 28) /*Instruction reads from and writes to ST(0)*/ -#define FPU_RW_ST0 (3ull << 27) +#define FPU_RW_ST0 (3ull << 27) /*Instruction reads from ST(1)*/ -#define FPU_READ_ST1 (1ull << 29) +#define FPU_READ_ST1 (1ull << 29) /*Instruction writes to ST(1)*/ -#define FPU_WRITE_ST1 (1ull << 30) +#define FPU_WRITE_ST1 (1ull << 30) /*Instruction reads from and writes to ST(1)*/ -#define FPU_RW_ST1 (3ull << 29) +#define FPU_RW_ST1 (3ull << 29) /*Instruction reads from ST(reg)*/ -#define FPU_READ_STREG (1ull << 31) +#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_RW_STREG (3ull << 30) #define FPU_FXCH (1ull << 33) -#define HAS_IMM8 (1ull << 34) +#define HAS_IMM8 (1ull << 34) #define HAS_IMM1632 (1ull << 35) - #define REGMASK_IMPL_ESP (1 << 8) #define REGMASK_SHIFTPACK (1 << 9) -#define REGMASK_MULTIPLY (1 << 9) - +#define REGMASK_MULTIPLY (1 << 9) extern uint64_t opcode_deps[256]; extern uint64_t opcode_deps_mod3[256]; @@ -120,50 +118,52 @@ 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) -{ +static inline uint32_t get_addr_regmask(uint64_t data, uint32_t fetchdat, int op_32) { uint32_t addr_regmask = 0; - if (data & MODRM) - { + if (data & MODRM) { uint8_t modrm = fetchdat & 0xff; - if ((modrm & 0xc0) != 0xc0) - { - if (op_32 & 0x200) - { - if ((modrm & 0x7) == 4) - { + 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) - { + 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) - { + } 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; + } 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; } } } @@ -172,22 +172,19 @@ static inline uint32_t get_addr_regmask(uint64_t data, uint32_t fetchdat, int op 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) -{ +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) - { + if (data & SRCDEP_REG) { int reg = (fetchdat >> 3) & 7; if (bit8) reg &= 3; mask |= (1 << reg); } - if (data & SRCDEP_RM) - { + if (data & SRCDEP_RM) { int reg = fetchdat & 7; if (bit8) reg &= 3; @@ -204,18 +201,15 @@ static inline uint32_t get_srcdep_mask(uint64_t data, uint32_t fetchdat, int bit return mask; } -static inline uint32_t get_dstdep_mask(uint64_t data, uint32_t fetchdat, int bit8) -{ +static inline uint32_t get_dstdep_mask(uint64_t data, uint32_t fetchdat, int bit8) { uint32_t mask = 0; - if (data & DSTDEP_REG) - { + if (data & DSTDEP_REG) { int reg = (fetchdat >> 3) & 7; if (bit8) reg &= 3; mask |= (1 << reg); } - if (data & DSTDEP_RM) - { + if (data & DSTDEP_RM) { int reg = fetchdat & 7; if (bit8) reg &= 3; @@ -232,5 +226,4 @@ static inline uint32_t get_dstdep_mask(uint64_t data, uint32_t fetchdat, int bit return mask; } - #endif /* _CODEGEN_TIMING_COMMON_H_ */ diff --git a/includes/private/codegen/codegen_x86-64.h b/includes/private/codegen/codegen_x86-64.h index 5e9fe229..11104062 100644 --- a/includes/private/codegen/codegen_x86-64.h +++ b/includes/private/codegen/codegen_x86-64.h @@ -7,22 +7,18 @@ #define HASH_SIZE 0x20000 #define HASH_MASK 0x1ffff -#define HASH(l) ((l) & 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 -}; +enum { OP_RET = 0xc3 }; #define NR_HOST_REGS 4 extern int host_reg_mapping[NR_HOST_REGS]; #define NR_HOST_XMM_REGS 7 extern int host_reg_xmm_mapping[NR_HOST_XMM_REGS]; - #endif /* _CODEGEN_X86_64_H_ */ diff --git a/includes/private/cpu/386_common.h b/includes/private/cpu/386_common.h index e13400ac..39406e68 100644 --- a/includes/private/cpu/386_common.h +++ b/includes/private/cpu/386_common.h @@ -1,218 +1,280 @@ #ifndef _386_COMMON_H_ #define _386_COMMON_H_ -#define readmemb(s, a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1)?readmembl((s)+(a)): *(uint8_t *)(readlookup2[(uint32_t)((s)+(a))>>12] + (uint32_t)((s) + (a))) ) -#define readmemw(s, a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (((s)+(a)) & 1))?readmemwl((s)+(a)):*(uint16_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) -#define readmeml(s, a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (((s)+(a)) & 3))?readmemll((s)+(a)):*(uint32_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) -#define readmemq(s, a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (((s)+(a)) & 7))?readmemql((s)+(a)):*(uint64_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) +#define readmemb(s, a) \ + ((readlookup2[(uint32_t)((s) + (a)) >> 12] == -1) \ + ? readmembl((s) + (a)) \ + : *(uint8_t *)(readlookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a)))) +#define readmemw(s, a) \ + ((readlookup2[(uint32_t)((s) + (a)) >> 12] == -1 || (((s) + (a)) & 1)) \ + ? readmemwl((s) + (a)) \ + : *(uint16_t *)(readlookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a)))) +#define readmeml(s, a) \ + ((readlookup2[(uint32_t)((s) + (a)) >> 12] == -1 || (((s) + (a)) & 3)) \ + ? readmemll((s) + (a)) \ + : *(uint32_t *)(readlookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a)))) +#define readmemq(s, a) \ + ((readlookup2[(uint32_t)((s) + (a)) >> 12] == -1 || (((s) + (a)) & 7)) \ + ? readmemql((s) + (a)) \ + : *(uint64_t *)(readlookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a)))) -#define writememb(s, a, v) if (writelookup2[(uint32_t)((s)+(a))>>12]==-1) writemembl((s)+(a),v); else *(uint8_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v -#define writememw(s, a, v) if (writelookup2[(uint32_t)((s)+(a))>>12]==-1 || (((s)+(a)) & 1)) writememwl((s)+(a),v); else *(uint16_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v -#define writememl(s, a, v) if (writelookup2[(uint32_t)((s)+(a))>>12]==-1 || (((s)+(a)) & 3)) writememll((s)+(a),v); else *(uint32_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v -#define writememq(s, a, v) if (writelookup2[(uint32_t)((s)+(a))>>12]==-1 || (((s)+(a)) & 7)) writememql((s)+(a),v); else *(uint64_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v +#define writememb(s, a, v) \ + if (writelookup2[(uint32_t)((s) + (a)) >> 12] == -1) \ + writemembl((s) + (a), v); \ + else \ + *(uint8_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v +#define writememw(s, a, v) \ + if (writelookup2[(uint32_t)((s) + (a)) >> 12] == -1 || (((s) + (a)) & 1)) \ + writememwl((s) + (a), v); \ + else \ + *(uint16_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v +#define writememl(s, a, v) \ + if (writelookup2[(uint32_t)((s) + (a)) >> 12] == -1 || (((s) + (a)) & 3)) \ + writememll((s) + (a), v); \ + else \ + *(uint32_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v +#define writememq(s, a, v) \ + if (writelookup2[(uint32_t)((s) + (a)) >> 12] == -1 || (((s) + (a)) & 7)) \ + writememql((s) + (a), v); \ + else \ + *(uint64_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v int checkio(int port); -#define check_io_perm(port) if (!IOPLp || (cpu_state.eflags&VM_FLAG)) \ - { \ - int tempi = checkio(port); \ - if (cpu_state.abrt) return 1; \ - if (tempi) \ - { \ - if (cpu_state.eflags & VM_FLAG) \ - x86gpf_expected(NULL,0); \ - else \ - x86gpf(NULL,0); \ - return 1; \ - } \ - } +#define check_io_perm(port) \ + if (!IOPLp || (cpu_state.eflags & VM_FLAG)) { \ + int tempi = checkio(port); \ + if (cpu_state.abrt) \ + return 1; \ + if (tempi) { \ + if (cpu_state.eflags & VM_FLAG) \ + x86gpf_expected(NULL, 0); \ + else \ + x86gpf(NULL, 0); \ + return 1; \ + } \ + } -#define SEG_CHECK_READ(seg) \ - do \ - { \ - if ((seg)->base == 0xffffffff) \ - { \ - x86gpf("Segment can't read", 0);\ - return 1; \ - } \ +#define SEG_CHECK_READ(seg) \ + do { \ + if ((seg)->base == 0xffffffff) { \ + x86gpf("Segment can't read", 0); \ + return 1; \ + } \ } while (0) -#define SEG_CHECK_WRITE(seg) \ - do \ - { \ - if ((seg)->base == 0xffffffff) \ - { \ - x86gpf("Segment can't write", 0);\ - return 1; \ - } \ +#define SEG_CHECK_WRITE(seg) \ + do { \ + if ((seg)->base == 0xffffffff) { \ + x86gpf("Segment can't write", 0); \ + return 1; \ + } \ } while (0) -#define CHECK_READ(seg, low, high) \ - if ((low < (seg)->limit_low) || (high > (seg)->limit_high) || ((msw & 1) && !(cpu_state.eflags & VM_FLAG) && (((seg)->access & 10) == 8))) \ - { \ - x86gpf("Limit check", 0); \ - return 1; \ +#define CHECK_READ(seg, low, high) \ + if ((low < (seg)->limit_low) || (high > (seg)->limit_high) || \ + ((msw & 1) && !(cpu_state.eflags & VM_FLAG) && (((seg)->access & 10) == 8))) { \ + x86gpf("Limit check", 0); \ + return 1; \ } -#define CHECK_WRITE(seg, low, high) \ - if ((low < (seg)->limit_low) || (high > (seg)->limit_high) || !((seg)->access & 2) || ((msw & 1) && !(cpu_state.eflags & VM_FLAG) && ((seg)->access & 8))) \ - { \ - x86gpf("Limit check", 0); \ - return 1; \ +#define CHECK_WRITE(seg, low, high) \ + if ((low < (seg)->limit_low) || (high > (seg)->limit_high) || !((seg)->access & 2) || \ + ((msw & 1) && !(cpu_state.eflags & VM_FLAG) && ((seg)->access & 8))) { \ + x86gpf("Limit check", 0); \ + return 1; \ } -#define CHECK_WRITE_REP(seg, low, high) \ - if ((low < (seg)->limit_low) || (high > (seg)->limit_high)) \ - { \ - x86gpf("Limit check", 0); \ - break; \ +#define CHECK_WRITE_REP(seg, low, high) \ + if ((low < (seg)->limit_low) || (high > (seg)->limit_high)) { \ + x86gpf("Limit check", 0); \ + break; \ } -#define NOTRM if (!(msw & 1) || (cpu_state.eflags & VM_FLAG))\ - { \ - x86_int(6); \ - return 1; \ - } +#define NOTRM \ + if (!(msw & 1) || (cpu_state.eflags & VM_FLAG)) { \ + x86_int(6); \ + return 1; \ + } static inline uint8_t fastreadb(uint32_t a) { - uint8_t *t; + 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]); + 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; + 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]); + 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; + 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 void *get_ram_ptr(uint32_t a) { - if ((a >> 12) == pccache) - return &pccache2[a]; - else { - uint8_t *t = getpccache(a); - return &t[a]; - } + if ((a >> 12) == pccache) + return &pccache2[a]; + else { + uint8_t *t = getpccache(a); + return &t[a]; + } } static inline uint8_t getbyte() { - cpu_state.pc++; - return fastreadb(cs + (cpu_state.pc - 1)); + 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)); + 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)); + 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); + 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); + 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; - if (eal_r) - return *(uint16_t *)eal_r; - return readmemw(easeg, cpu_state.eaaddr); + if (cpu_mod == 3) + return cpu_state.regs[cpu_rm].w; + 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; - if (eal_r) - return *eal_r; - return readmeml(easeg, cpu_state.eaaddr); + if (cpu_mod == 3) + return cpu_state.regs[cpu_rm].l; + 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 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); + 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); + 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); + 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); -} +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 writemembl(easeg+cpu_state.eaaddr,v); } else if (cpu_rm&4) cpu_state.regs[cpu_rm&3].b.h=v; else cpu_state.regs[cpu_rm].b.l=v -#define seteaw(v) if (cpu_mod!=3) { 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(v) \ + if (cpu_mod != 3) { \ + if (eal_w) \ + *(uint8_t *)eal_w = v; \ + else \ + writemembl(easeg + cpu_state.eaaddr, v); \ + } else if (cpu_rm & 4) \ + cpu_state.regs[cpu_rm & 3].b.h = v; \ + else \ + cpu_state.regs[cpu_rm].b.l = v +#define seteaw(v) \ + if (cpu_mod != 3) { \ + 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 writemembl(easeg+cpu_state.eaaddr,v); -#define seteaw_mem(v) if (eal_w) *(uint16_t *)eal_w=v; else writememwl(easeg+cpu_state.eaaddr,v); -#define seteal_mem(v) if (eal_w) *eal_w=v; else writememll(easeg+cpu_state.eaaddr,v); +#define seteab_mem(v) \ + if (eal_w) \ + *(uint8_t *)eal_w = v; \ + else \ + writemembl(easeg + cpu_state.eaaddr, v); +#define seteaw_mem(v) \ + if (eal_w) \ + *(uint16_t *)eal_w = v; \ + else \ + writememwl(easeg + cpu_state.eaaddr, v); +#define seteal_mem(v) \ + if (eal_w) \ + *eal_w = v; \ + else \ + writememll(easeg + cpu_state.eaaddr, v); -#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 getbytef() \ + ((uint8_t)(fetchdat)); \ + cpu_state.pc++ +#define getwordf() \ + ((uint16_t)(fetchdat)); \ + cpu_state.pc += 2 +#define getbyte2f() \ + ((uint8_t)(fetchdat >> 8)); \ + cpu_state.pc++ +#define getword2f() \ + ((uint16_t)(fetchdat >> 8)); \ + cpu_state.pc += 2 #endif /* _386_COMMON_H_ */ diff --git a/includes/private/cpu/386_ops.h b/includes/private/cpu/386_ops.h index dee17ea8..835a53c5 100644 --- a/includes/private/cpu/386_ops.h +++ b/includes/private/cpu/386_ops.h @@ -2,115 +2,113 @@ #define _386_OPS_H_ #include "x86_ops.h" -#define ILLEGAL_ON(cond) \ - do \ - { \ - if ((cond)) \ - { \ - cpu_state.pc = cpu_state.oldpc; \ - x86illegal(); \ - return 0; \ - } \ +#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; - } else { - writememw(ss, (SP - 2) & 0xFFFF, val); - if (cpu_state.abrt) - return; - SP -= 2; - } + if (stack32) { + writememw(ss, ESP - 2, val); + if (cpu_state.abrt) + return; + ESP -= 2; + } else { + writememw(ss, (SP - 2) & 0xFFFF, val); + if (cpu_state.abrt) + return; + SP -= 2; + } } static inline void PUSH_L(uint32_t val) { - if (stack32) { - writememl(ss, ESP - 4, val); - if (cpu_state.abrt) - return; - ESP -= 4; - } else { - writememl(ss, (SP - 4) & 0xFFFF, val); - if (cpu_state.abrt) - return; - SP -= 4; - } + if (stack32) { + writememl(ss, ESP - 4, val); + if (cpu_state.abrt) + return; + ESP -= 4; + } else { + writememl(ss, (SP - 4) & 0xFFFF, val); + if (cpu_state.abrt) + return; + SP -= 4; + } } static inline uint16_t POP_W() { - uint16_t ret; - if (stack32) { - ret = readmemw(ss, ESP); - if (cpu_state.abrt) - return 0; - ESP += 2; - } else { - ret = readmemw(ss, SP); - if (cpu_state.abrt) - return 0; - SP += 2; - } - return ret; + uint16_t ret; + if (stack32) { + ret = readmemw(ss, ESP); + if (cpu_state.abrt) + return 0; + ESP += 2; + } else { + ret = readmemw(ss, SP); + if (cpu_state.abrt) + return 0; + SP += 2; + } + 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; - } else { - ret = readmeml(ss, SP); - if (cpu_state.abrt) - return 0; - SP += 4; - } - return ret; + uint32_t ret; + if (stack32) { + ret = readmeml(ss, ESP); + if (cpu_state.abrt) + return 0; + ESP += 4; + } else { + ret = readmeml(ss, SP); + if (cpu_state.abrt) + return 0; + SP += 4; + } + 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; - } else { - ret = readmemw(seg, SP); - if (cpu_state.abrt) - return 0; - SP += 2; - } - return ret; + uint16_t ret; + if (stack32) { + ret = readmemw(seg, ESP); + if (cpu_state.abrt) + return 0; + ESP += 2; + } else { + ret = readmemw(seg, SP); + if (cpu_state.abrt) + return 0; + SP += 2; + } + 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; - } else { - ret = readmeml(seg, SP); - if (cpu_state.abrt) - return 0; - SP += 4; - } - return ret; + uint32_t ret; + if (stack32) { + ret = readmeml(seg, ESP); + if (cpu_state.abrt) + return 0; + ESP += 4; + } else { + ret = readmeml(seg, SP); + if (cpu_state.abrt) + return 0; + SP += 4; + } + return ret; } static int ILLEGAL(uint32_t fetchdat) { - cpu_state.pc = cpu_state.oldpc; + cpu_state.pc = cpu_state.oldpc; -// fatal("Illegal instruction %08X\n", fetchdat); - x86illegal(); - return 0; + // fatal("Illegal instruction %08X\n", fetchdat); + x86illegal(); + return 0; } #include "x86_ops_arith.h" @@ -152,1566 +150,14789 @@ static int ILLEGAL(uint32_t fetchdat) { #include "x86_ops_xchg.h" static int op0F_w_a16(uint32_t fetchdat) { - int opcode = fetchdat & 0xff; - cpu_state.pc++; - PREFETCH_PREFIX(); + int opcode = fetchdat & 0xff; + cpu_state.pc++; + PREFETCH_PREFIX(); - return x86_opcodes_0f[opcode](fetchdat >> 8); + return x86_opcodes_0f[opcode](fetchdat >> 8); } static int op0F_l_a16(uint32_t fetchdat) { - int opcode = fetchdat & 0xff; - cpu_state.pc++; - PREFETCH_PREFIX(); + int opcode = fetchdat & 0xff; + cpu_state.pc++; + PREFETCH_PREFIX(); - return x86_opcodes_0f[opcode | 0x100](fetchdat >> 8); + return x86_opcodes_0f[opcode | 0x100](fetchdat >> 8); } static int op0F_w_a32(uint32_t fetchdat) { - int opcode = fetchdat & 0xff; - cpu_state.pc++; - PREFETCH_PREFIX(); + int opcode = fetchdat & 0xff; + cpu_state.pc++; + PREFETCH_PREFIX(); - return x86_opcodes_0f[opcode | 0x200](fetchdat >> 8); + return x86_opcodes_0f[opcode | 0x200](fetchdat >> 8); } static int op0F_l_a32(uint32_t fetchdat) { - int opcode = fetchdat & 0xff; - cpu_state.pc++; - PREFETCH_PREFIX(); + int opcode = fetchdat & 0xff; + cpu_state.pc++; + PREFETCH_PREFIX(); - return x86_opcodes_0f[opcode | 0x300](fetchdat >> 8); + return x86_opcodes_0f[opcode | 0x300](fetchdat >> 8); } -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, - }; - -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, 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, - }; - -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, opRSM, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16, ILLEGAL, - opIMUL_w_w_a16, -/*b0*/ opCMPXCHG_b_a16, opCMPXCHG_w_a16, opLSS_w_a16, opBTR_w_r_a16, opLFS_w_a16, opLGS_w_a16, opMOVZX_w_b_a16, opMOVZX_w_w_a16, ILLEGAL, ILLEGAL, opBA_w_a16, opBTC_w_r_a16, opBSF_w_a16, opBSR_w_a16, - opMOVSX_w_b_a16, ILLEGAL, - -/*c0*/ opXADD_b_a16, opXADD_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, - opBSWAP_EDI, -/*d0*/ ILLEGAL, opPSRLW_a16, opPSRLD_a16, opPSRLQ_a16, ILLEGAL, opPMULLW_a16, ILLEGAL, ILLEGAL, opPSUBUSB_a16, opPSUBUSW_a16, NULL, opPAND_a16, opPADDUSB_a16, opPADDUSW_a16, NULL, opPANDN_a16, -/*e0*/ ILLEGAL, opPSRAW_a16, opPSRAD_a16, ILLEGAL, ILLEGAL, opPMULHW_a16, ILLEGAL, ILLEGAL, opPSUBSB_a16, opPSUBSW_a16, NULL, opPOR_a16, opPADDSB_a16, opPADDSW_a16, NULL, opPXOR_a16, -/*f0*/ ILLEGAL, opPSLLW_a16, opPSLLD_a16, opPSLLQ_a16, ILLEGAL, opPMADDWD_a16, ILLEGAL, ILLEGAL, opPSUBB_a16, opPSUBW_a16, opPSUBD_a16, ILLEGAL, opPADDB_a16, opPADDW_a16, opPADDD_a16, ILLEGAL, - - /*32-bit data, 16-bit addr*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, 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, opRSM, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16, ILLEGAL, - opIMUL_l_l_a16, -/*b0*/ opCMPXCHG_b_a16, opCMPXCHG_l_a16, opLSS_l_a16, opBTR_l_r_a16, opLFS_l_a16, opLGS_l_a16, opMOVZX_l_b_a16, opMOVZX_l_w_a16, ILLEGAL, ILLEGAL, opBA_l_a16, opBTC_l_r_a16, opBSF_l_a16, opBSR_l_a16, - opMOVSX_l_b_a16, opMOVSX_l_w_a16, - -/*c0*/ opXADD_b_a16, opXADD_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, - opBSWAP_EDI, -/*d0*/ ILLEGAL, opPSRLW_a16, opPSRLD_a16, opPSRLQ_a16, ILLEGAL, opPMULLW_a16, ILLEGAL, ILLEGAL, opPSUBUSB_a16, opPSUBUSW_a16, NULL, opPAND_a16, opPADDUSB_a16, opPADDUSW_a16, NULL, opPANDN_a16, -/*e0*/ ILLEGAL, opPSRAW_a16, opPSRAD_a16, ILLEGAL, ILLEGAL, opPMULHW_a16, ILLEGAL, ILLEGAL, opPSUBSB_a16, opPSUBSW_a16, NULL, opPOR_a16, opPADDSB_a16, opPADDSW_a16, NULL, opPXOR_a16, -/*f0*/ ILLEGAL, opPSLLW_a16, opPSLLD_a16, opPSLLQ_a16, ILLEGAL, opPMADDWD_a16, ILLEGAL, ILLEGAL, opPSUBB_a16, opPSUBW_a16, opPSUBD_a16, ILLEGAL, opPADDB_a16, opPADDW_a16, opPADDD_a16, ILLEGAL, - - /*16-bit data, 32-bit addr*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, 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, opRSM, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32, ILLEGAL, - opIMUL_w_w_a32, -/*b0*/ opCMPXCHG_b_a32, opCMPXCHG_w_a32, opLSS_w_a32, opBTR_w_r_a32, opLFS_w_a32, opLGS_w_a32, opMOVZX_w_b_a32, opMOVZX_w_w_a32, ILLEGAL, ILLEGAL, opBA_w_a32, opBTC_w_r_a32, opBSF_w_a32, opBSR_w_a32, - opMOVSX_w_b_a32, ILLEGAL, - -/*c0*/ opXADD_b_a32, opXADD_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, - opBSWAP_EDI, -/*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_a32, -/*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, -/*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, - - /*32-bit data, 32-bit addr*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, 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, opRSM, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32, ILLEGAL, - opIMUL_l_l_a32, -/*b0*/ opCMPXCHG_b_a32, opCMPXCHG_l_a32, opLSS_l_a32, opBTR_l_r_a32, opLFS_l_a32, opLGS_l_a32, opMOVZX_l_b_a32, opMOVZX_l_w_a32, ILLEGAL, ILLEGAL, opBA_l_a32, opBTC_l_r_a32, opBSF_l_a32, opBSR_l_a32, - opMOVSX_l_b_a32, opMOVSX_l_w_a32, - -/*c0*/ opXADD_b_a32, opXADD_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, - opBSWAP_EDI, -/*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_a32, -/*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, -/*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, - }; - -OpFn OP_TABLE(winchip2_0f)[1024] = - { - /*16-bit data, 16-bit addr*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, opPREFETCH_a16, opFEMMS, op3DNOW_a16, -/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*20*/ opMOV_r_CRx_a16, opMOV_r_DRx_a16, opMOV_CRx_r_a16, opMOV_DRx_r_a16, opMOV_r_TRx_a16, 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, opRSM, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16, ILLEGAL, - opIMUL_w_w_a16, -/*b0*/ opCMPXCHG_b_a16, opCMPXCHG_w_a16, opLSS_w_a16, opBTR_w_r_a16, opLFS_w_a16, opLGS_w_a16, opMOVZX_w_b_a16, opMOVZX_w_w_a16, ILLEGAL, ILLEGAL, opBA_w_a16, opBTC_w_r_a16, opBSF_w_a16, opBSR_w_a16, - opMOVSX_w_b_a16, ILLEGAL, - -/*c0*/ opXADD_b_a16, opXADD_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, - opBSWAP_EDI, -/*d0*/ ILLEGAL, opPSRLW_a16, opPSRLD_a16, opPSRLQ_a16, ILLEGAL, opPMULLW_a16, ILLEGAL, ILLEGAL, opPSUBUSB_a16, opPSUBUSW_a16, NULL, opPAND_a16, opPADDUSB_a16, opPADDUSW_a16, NULL, opPANDN_a16, -/*e0*/ ILLEGAL, opPSRAW_a16, opPSRAD_a16, ILLEGAL, ILLEGAL, opPMULHW_a16, ILLEGAL, ILLEGAL, opPSUBSB_a16, opPSUBSW_a16, NULL, opPOR_a16, opPADDSB_a16, opPADDSW_a16, NULL, opPXOR_a16, -/*f0*/ ILLEGAL, opPSLLW_a16, opPSLLD_a16, opPSLLQ_a16, ILLEGAL, opPMADDWD_a16, ILLEGAL, ILLEGAL, opPSUBB_a16, opPSUBW_a16, opPSUBD_a16, ILLEGAL, opPADDB_a16, opPADDW_a16, opPADDD_a16, ILLEGAL, - - /*32-bit data, 16-bit addr*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, opPREFETCH_a16, opFEMMS, op3DNOW_a16, -/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*20*/ opMOV_r_CRx_a16, opMOV_r_DRx_a16, opMOV_CRx_r_a16, opMOV_DRx_r_a16, opMOV_r_TRx_a16, 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, opRSM, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16, ILLEGAL, - opIMUL_l_l_a16, -/*b0*/ opCMPXCHG_b_a16, opCMPXCHG_l_a16, opLSS_l_a16, opBTR_l_r_a16, opLFS_l_a16, opLGS_l_a16, opMOVZX_l_b_a16, opMOVZX_l_w_a16, ILLEGAL, ILLEGAL, opBA_l_a16, opBTC_l_r_a16, opBSF_l_a16, opBSR_l_a16, - opMOVSX_l_b_a16, opMOVSX_l_w_a16, - -/*c0*/ opXADD_b_a16, opXADD_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, - opBSWAP_EDI, -/*d0*/ ILLEGAL, opPSRLW_a16, opPSRLD_a16, opPSRLQ_a16, ILLEGAL, opPMULLW_a16, ILLEGAL, ILLEGAL, opPSUBUSB_a16, opPSUBUSW_a16, NULL, opPAND_a16, opPADDUSB_a16, opPADDUSW_a16, NULL, opPANDN_a16, -/*e0*/ ILLEGAL, opPSRAW_a16, opPSRAD_a16, ILLEGAL, ILLEGAL, opPMULHW_a16, ILLEGAL, ILLEGAL, opPSUBSB_a16, opPSUBSW_a16, NULL, opPOR_a16, opPADDSB_a16, opPADDSW_a16, NULL, opPXOR_a16, -/*f0*/ ILLEGAL, opPSLLW_a16, opPSLLD_a16, opPSLLQ_a16, ILLEGAL, opPMADDWD_a16, ILLEGAL, ILLEGAL, opPSUBB_a16, opPSUBW_a16, opPSUBD_a16, ILLEGAL, opPADDB_a16, opPADDW_a16, opPADDD_a16, ILLEGAL, - - /*16-bit data, 32-bit addr*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, opPREFETCH_a32, opFEMMS, op3DNOW_a32, -/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*20*/ opMOV_r_CRx_a32, opMOV_r_DRx_a32, opMOV_CRx_r_a32, opMOV_DRx_r_a32, opMOV_r_TRx_a32, 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, opRSM, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32, ILLEGAL, - opIMUL_w_w_a32, -/*b0*/ opCMPXCHG_b_a32, opCMPXCHG_w_a32, opLSS_w_a32, opBTR_w_r_a32, opLFS_w_a32, opLGS_w_a32, opMOVZX_w_b_a32, opMOVZX_w_w_a32, ILLEGAL, ILLEGAL, opBA_w_a32, opBTC_w_r_a32, opBSF_w_a32, opBSR_w_a32, - opMOVSX_w_b_a32, ILLEGAL, - -/*c0*/ opXADD_b_a32, opXADD_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, - opBSWAP_EDI, -/*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_a32, -/*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, -/*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, - - /*32-bit data, 32-bit addr*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, opPREFETCH_a32, opFEMMS, op3DNOW_a32, -/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*20*/ opMOV_r_CRx_a32, opMOV_r_DRx_a32, opMOV_CRx_r_a32, opMOV_DRx_r_a32, opMOV_r_TRx_a32, 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, opRSM, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32, ILLEGAL, - opIMUL_l_l_a32, -/*b0*/ opCMPXCHG_b_a32, opCMPXCHG_l_a32, opLSS_l_a32, opBTR_l_r_a32, opLFS_l_a32, opLGS_l_a32, opMOVZX_l_b_a32, opMOVZX_l_w_a32, ILLEGAL, ILLEGAL, opBA_l_a32, opBTC_l_r_a32, opBSF_l_a32, opBSR_l_a32, - opMOVSX_l_b_a32, opMOVSX_l_w_a32, - -/*c0*/ opXADD_b_a32, opXADD_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, - opBSWAP_EDI, -/*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_a32, -/*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, -/*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, - }; - -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, opRSM, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16, ILLEGAL, - opIMUL_w_w_a16, -/*b0*/ opCMPXCHG_b_a16, opCMPXCHG_w_a16, opLSS_w_a16, opBTR_w_r_a16, opLFS_w_a16, opLGS_w_a16, opMOVZX_w_b_a16, opMOVZX_w_w_a16, ILLEGAL, ILLEGAL, opBA_w_a16, opBTC_w_r_a16, opBSF_w_a16, opBSR_w_a16, - opMOVSX_w_b_a16, ILLEGAL, - -/*c0*/ opXADD_b_a16, opXADD_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, - opBSWAP_EDI, -/*d0*/ ILLEGAL, 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, opRSM, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16, ILLEGAL, - opIMUL_l_l_a16, -/*b0*/ opCMPXCHG_b_a16, opCMPXCHG_l_a16, opLSS_l_a16, opBTR_l_r_a16, opLFS_l_a16, opLGS_l_a16, opMOVZX_l_b_a16, opMOVZX_l_w_a16, ILLEGAL, ILLEGAL, opBA_l_a16, opBTC_l_r_a16, opBSF_l_a16, opBSR_l_a16, - opMOVSX_l_b_a16, opMOVSX_l_w_a16, - -/*c0*/ opXADD_b_a16, opXADD_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, - opBSWAP_EDI, -/*d0*/ ILLEGAL, 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, opRSM, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32, ILLEGAL, - opIMUL_w_w_a32, -/*b0*/ opCMPXCHG_b_a32, opCMPXCHG_w_a32, opLSS_w_a32, opBTR_w_r_a32, opLFS_w_a32, opLGS_w_a32, opMOVZX_w_b_a32, opMOVZX_w_w_a32, ILLEGAL, ILLEGAL, opBA_w_a32, opBTC_w_r_a32, opBSF_w_a32, opBSR_w_a32, - opMOVSX_w_b_a32, ILLEGAL, - -/*c0*/ opXADD_b_a32, opXADD_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, - opBSWAP_EDI, -/*d0*/ ILLEGAL, 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, opRSM, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32, ILLEGAL, - opIMUL_l_l_a32, -/*b0*/ opCMPXCHG_b_a32, opCMPXCHG_l_a32, opLSS_l_a32, opBTR_l_r_a32, opLFS_l_a32, opLGS_l_a32, opMOVZX_l_b_a32, opMOVZX_l_w_a32, ILLEGAL, ILLEGAL, opBA_l_a32, opBTC_l_r_a32, opBSF_l_a32, opBSR_l_a32, - opMOVSX_l_b_a32, opMOVSX_l_w_a32, - -/*c0*/ opXADD_b_a32, opXADD_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, - opBSWAP_EDI, -/*d0*/ ILLEGAL, 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, - }; - -OpFn OP_TABLE(c6x86_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, opSVDC_a16, opRSDC_a16, opSVLDT_a16, opRSLDT_a16, opSVTS_a16, opRSTS_a16, opSMINT, 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, opRSM, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16, ILLEGAL, - opIMUL_w_w_a16, -/*b0*/ opCMPXCHG_b_a16, opCMPXCHG_w_a16, opLSS_w_a16, opBTR_w_r_a16, opLFS_w_a16, opLGS_w_a16, opMOVZX_w_b_a16, opMOVZX_w_w_a16, ILLEGAL, ILLEGAL, opBA_w_a16, opBTC_w_r_a16, opBSF_w_a16, opBSR_w_a16, - opMOVSX_w_b_a16, ILLEGAL, - -/*c0*/ opXADD_b_a16, opXADD_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, - opBSWAP_EDI, -/*d0*/ ILLEGAL, 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, opSVDC_a16, opRSDC_a16, opSVLDT_a16, opRSLDT_a16, opSVTS_a16, opRSTS_a16, opSMINT, 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, opRSM, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16, ILLEGAL, - opIMUL_l_l_a16, -/*b0*/ opCMPXCHG_b_a16, opCMPXCHG_l_a16, opLSS_l_a16, opBTR_l_r_a16, opLFS_l_a16, opLGS_l_a16, opMOVZX_l_b_a16, opMOVZX_l_w_a16, ILLEGAL, ILLEGAL, opBA_l_a16, opBTC_l_r_a16, opBSF_l_a16, opBSR_l_a16, - opMOVSX_l_b_a16, opMOVSX_l_w_a16, - -/*c0*/ opXADD_b_a16, opXADD_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, - opBSWAP_EDI, -/*d0*/ ILLEGAL, 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, opSVDC_a32, opRSDC_a32, opSVLDT_a32, opRSLDT_a32, opSVTS_a32, opRSTS_a32, opSMINT, 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, opRSM, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32, ILLEGAL, - opIMUL_w_w_a32, -/*b0*/ opCMPXCHG_b_a32, opCMPXCHG_w_a32, opLSS_w_a32, opBTR_w_r_a32, opLFS_w_a32, opLGS_w_a32, opMOVZX_w_b_a32, opMOVZX_w_w_a32, ILLEGAL, ILLEGAL, opBA_w_a32, opBTC_w_r_a32, opBSF_w_a32, opBSR_w_a32, - opMOVSX_w_b_a32, ILLEGAL, - -/*c0*/ opXADD_b_a32, opXADD_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, - opBSWAP_EDI, -/*d0*/ ILLEGAL, 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, opSVDC_a32, opRSDC_a32, opSVLDT_a32, opRSLDT_a32, opSVTS_a32, opRSTS_a32, opSMINT, 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, opRSM, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32, ILLEGAL, - opIMUL_l_l_a32, -/*b0*/ opCMPXCHG_b_a32, opCMPXCHG_l_a32, opLSS_l_a32, opBTR_l_r_a32, opLFS_l_a32, opLGS_l_a32, opMOVZX_l_b_a32, opMOVZX_l_w_a32, ILLEGAL, ILLEGAL, opBA_l_a32, opBTC_l_r_a32, opBSF_l_a32, opBSR_l_a32, - opMOVSX_l_b_a32, opMOVSX_l_w_a32, - -/*c0*/ opXADD_b_a32, opXADD_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, - opBSWAP_EDI, -/*d0*/ ILLEGAL, 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, - }; - -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, opRSM, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16, ILLEGAL, - opIMUL_w_w_a16, -/*b0*/ opCMPXCHG_b_a16, opCMPXCHG_w_a16, opLSS_w_a16, opBTR_w_r_a16, opLFS_w_a16, opLGS_w_a16, opMOVZX_w_b_a16, opMOVZX_w_w_a16, ILLEGAL, ILLEGAL, opBA_w_a16, opBTC_w_r_a16, opBSF_w_a16, opBSR_w_a16, - opMOVSX_w_b_a16, ILLEGAL, - -/*c0*/ opXADD_b_a16, opXADD_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, - opBSWAP_EDI, -/*d0*/ ILLEGAL, opPSRLW_a16, opPSRLD_a16, opPSRLQ_a16, ILLEGAL, opPMULLW_a16, ILLEGAL, ILLEGAL, opPSUBUSB_a16, opPSUBUSW_a16, NULL, opPAND_a16, opPADDUSB_a16, opPADDUSW_a16, NULL, opPANDN_a16, -/*e0*/ ILLEGAL, opPSRAW_a16, opPSRAD_a16, ILLEGAL, ILLEGAL, opPMULHW_a16, ILLEGAL, ILLEGAL, opPSUBSB_a16, opPSUBSW_a16, NULL, opPOR_a16, opPADDSB_a16, opPADDSW_a16, NULL, opPXOR_a16, -/*f0*/ ILLEGAL, opPSLLW_a16, opPSLLD_a16, opPSLLQ_a16, ILLEGAL, opPMADDWD_a16, ILLEGAL, ILLEGAL, opPSUBB_a16, opPSUBW_a16, opPSUBD_a16, ILLEGAL, opPADDB_a16, opPADDW_a16, opPADDD_a16, ILLEGAL, - - /*32-bit data, 16-bit addr*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, 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, opRSM, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16, ILLEGAL, - opIMUL_l_l_a16, -/*b0*/ opCMPXCHG_b_a16, opCMPXCHG_l_a16, opLSS_l_a16, opBTR_l_r_a16, opLFS_l_a16, opLGS_l_a16, opMOVZX_l_b_a16, opMOVZX_l_w_a16, ILLEGAL, ILLEGAL, opBA_l_a16, opBTC_l_r_a16, opBSF_l_a16, opBSR_l_a16, - opMOVSX_l_b_a16, opMOVSX_l_w_a16, - -/*c0*/ opXADD_b_a16, opXADD_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, - opBSWAP_EDI, -/*d0*/ ILLEGAL, opPSRLW_a16, opPSRLD_a16, opPSRLQ_a16, ILLEGAL, opPMULLW_a16, ILLEGAL, ILLEGAL, opPSUBUSB_a16, opPSUBUSW_a16, NULL, opPAND_a16, opPADDUSB_a16, opPADDUSW_a16, NULL, opPANDN_a16, -/*e0*/ ILLEGAL, opPSRAW_a16, opPSRAD_a16, ILLEGAL, ILLEGAL, opPMULHW_a16, ILLEGAL, ILLEGAL, opPSUBSB_a16, opPSUBSW_a16, NULL, opPOR_a16, opPADDSB_a16, opPADDSW_a16, NULL, opPXOR_a16, -/*f0*/ ILLEGAL, opPSLLW_a16, opPSLLD_a16, opPSLLQ_a16, ILLEGAL, opPMADDWD_a16, ILLEGAL, ILLEGAL, opPSUBB_a16, opPSUBW_a16, opPSUBD_a16, ILLEGAL, opPADDB_a16, opPADDW_a16, opPADDD_a16, ILLEGAL, - - /*16-bit data, 32-bit addr*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, 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, opRSM, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32, ILLEGAL, - opIMUL_w_w_a32, -/*b0*/ opCMPXCHG_b_a32, opCMPXCHG_w_a32, opLSS_w_a32, opBTR_w_r_a32, opLFS_w_a32, opLGS_w_a32, opMOVZX_w_b_a32, opMOVZX_w_w_a32, ILLEGAL, ILLEGAL, opBA_w_a32, opBTC_w_r_a32, opBSF_w_a32, opBSR_w_a32, - opMOVSX_w_b_a32, ILLEGAL, - -/*c0*/ opXADD_b_a32, opXADD_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, - opBSWAP_EDI, -/*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_a32, -/*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, -/*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, - - /*32-bit data, 32-bit addr*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, 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, opRSM, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32, ILLEGAL, - opIMUL_l_l_a32, -/*b0*/ opCMPXCHG_b_a32, opCMPXCHG_l_a32, opLSS_l_a32, opBTR_l_r_a32, opLFS_l_a32, opLGS_l_a32, opMOVZX_l_b_a32, opMOVZX_l_w_a32, ILLEGAL, ILLEGAL, opBA_l_a32, opBTC_l_r_a32, opBSF_l_a32, opBSR_l_a32, - opMOVSX_l_b_a32, opMOVSX_l_w_a32, - -/*c0*/ opXADD_b_a32, opXADD_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, - opBSWAP_EDI, -/*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_a32, -/*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, -/*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, - }; - -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, opRDSHR_a16, opWRSHR_a16, 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, opSVDC_a16, opRSDC_a16, opSVLDT_a16, opRSLDT_a16, opSVTS_a16, opRSTS_a16, - opMOVD_mm_l_a16_cx, opMOVQ_mm_q_a16, - -/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w, -/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, - opSETNLE_a16, -/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16, ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16, ILLEGAL, - opIMUL_w_w_a16, -/*b0*/ opCMPXCHG_b_a16, opCMPXCHG_w_a16, opLSS_w_a16, opBTR_w_r_a16, opLFS_w_a16, opLGS_w_a16, opMOVZX_w_b_a16, opMOVZX_w_w_a16, ILLEGAL, ILLEGAL, opBA_w_a16, opBTC_w_r_a16, opBSF_w_a16, opBSR_w_a16, - opMOVSX_w_b_a16, ILLEGAL, - -/*c0*/ opXADD_b_a16, opXADD_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, - opBSWAP_EDI, -/*d0*/ ILLEGAL, opPSRLW_a16, opPSRLD_a16, opPSRLQ_a16, ILLEGAL, opPMULLW_a16, ILLEGAL, ILLEGAL, opPSUBUSB_a16, opPSUBUSW_a16, NULL, opPAND_a16, opPADDUSB_a16, opPADDUSW_a16, NULL, opPANDN_a16, -/*e0*/ ILLEGAL, opPSRAW_a16, opPSRAD_a16, ILLEGAL, ILLEGAL, opPMULHW_a16, ILLEGAL, ILLEGAL, opPSUBSB_a16, opPSUBSW_a16, NULL, opPOR_a16, opPADDSB_a16, opPADDSW_a16, NULL, opPXOR_a16, -/*f0*/ ILLEGAL, opPSLLW_a16, opPSLLD_a16, opPSLLQ_a16, ILLEGAL, opPMADDWD_a16, ILLEGAL, ILLEGAL, opPSUBB_a16, opPSUBW_a16, opPSUBD_a16, ILLEGAL, opPADDB_a16, opPADDW_a16, opPADDD_a16, ILLEGAL, - - /*32-bit data, 16-bit addr*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, 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, opRDSHR_a16, opWRSHR_a16, 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, opSVDC_a16, opRSDC_a16, opSVLDT_a16, opRSLDT_a16, opSVTS_a16, opRSTS_a16, - opMOVD_mm_l_a16_cx, opMOVQ_mm_q_a16, - -/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l, -/*90*/ opSETO_a16, opSETNO_a16, opSETB_a16, opSETNB_a16, opSETE_a16, opSETNE_a16, opSETBE_a16, opSETNBE_a16, opSETS_a16, opSETNS_a16, opSETP_a16, opSETNP_a16, opSETL_a16, opSETNL_a16, opSETLE_a16, - opSETNLE_a16, -/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16, ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16, ILLEGAL, - opIMUL_l_l_a16, -/*b0*/ opCMPXCHG_b_a16, opCMPXCHG_l_a16, opLSS_l_a16, opBTR_l_r_a16, opLFS_l_a16, opLGS_l_a16, opMOVZX_l_b_a16, opMOVZX_l_w_a16, ILLEGAL, ILLEGAL, opBA_l_a16, opBTC_l_r_a16, opBSF_l_a16, opBSR_l_a16, - opMOVSX_l_b_a16, opMOVSX_l_w_a16, - -/*c0*/ opXADD_b_a16, opXADD_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, - opBSWAP_EDI, -/*d0*/ ILLEGAL, opPSRLW_a16, opPSRLD_a16, opPSRLQ_a16, ILLEGAL, opPMULLW_a16, ILLEGAL, ILLEGAL, opPSUBUSB_a16, opPSUBUSW_a16, NULL, opPAND_a16, opPADDUSB_a16, opPADDUSW_a16, NULL, opPANDN_a16, -/*e0*/ ILLEGAL, opPSRAW_a16, opPSRAD_a16, ILLEGAL, ILLEGAL, opPMULHW_a16, ILLEGAL, ILLEGAL, opPSUBSB_a16, opPSUBSW_a16, NULL, opPOR_a16, opPADDSB_a16, opPADDSW_a16, NULL, opPXOR_a16, -/*f0*/ ILLEGAL, opPSLLW_a16, opPSLLD_a16, opPSLLQ_a16, ILLEGAL, opPMADDWD_a16, ILLEGAL, ILLEGAL, opPSUBB_a16, opPSUBW_a16, opPSUBD_a16, ILLEGAL, opPADDB_a16, opPADDW_a16, opPADDD_a16, ILLEGAL, - - /*16-bit data, 32-bit addr*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, 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, opRDSHR_a32, opWRSHR_a32, 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, opSVDC_a32, opRSDC_a32, opSVLDT_a32, opRSLDT_a32, opSVTS_a32, opRSTS_a32, - opMOVD_mm_l_a32_cx, opMOVQ_mm_q_a32, - -/*80*/ opJO_w, opJNO_w, opJB_w, opJNB_w, opJE_w, opJNE_w, opJBE_w, opJNBE_w, opJS_w, opJNS_w, opJP_w, opJNP_w, opJL_w, opJNL_w, opJLE_w, opJNLE_w, -/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, - opSETNLE_a32, -/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32, ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, opRSM, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32, ILLEGAL, - opIMUL_w_w_a32, -/*b0*/ opCMPXCHG_b_a32, opCMPXCHG_w_a32, opLSS_w_a32, opBTR_w_r_a32, opLFS_w_a32, opLGS_w_a32, opMOVZX_w_b_a32, opMOVZX_w_w_a32, ILLEGAL, ILLEGAL, opBA_w_a32, opBTC_w_r_a32, opBSF_w_a32, opBSR_w_a32, - opMOVSX_w_b_a32, ILLEGAL, - -/*c0*/ opXADD_b_a32, opXADD_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, - opBSWAP_EDI, -/*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_a32, -/*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, -/*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, - - /*32-bit data, 32-bit addr*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, 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, opRDSHR_a32, opWRSHR_a32, 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, opSVDC_a16, opRSDC_a16, opSVLDT_a16, opRSLDT_a16, opSVTS_a16, opRSTS_a16, - opMOVD_mm_l_a32_cx, opMOVQ_mm_q_a32, - -/*80*/ opJO_l, opJNO_l, opJB_l, opJNB_l, opJE_l, opJNE_l, opJBE_l, opJNBE_l, opJS_l, opJNS_l, opJP_l, opJNP_l, opJL_l, opJNL_l, opJLE_l, opJNLE_l, -/*90*/ opSETO_a32, opSETNO_a32, opSETB_a32, opSETNB_a32, opSETE_a32, opSETNE_a32, opSETBE_a32, opSETNBE_a32, opSETS_a32, opSETNS_a32, opSETP_a32, opSETNP_a32, opSETL_a32, opSETNL_a32, opSETLE_a32, - opSETNLE_a32, -/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32, ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, opRSM, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32, ILLEGAL, - opIMUL_l_l_a32, -/*b0*/ opCMPXCHG_b_a32, opCMPXCHG_l_a32, opLSS_l_a32, opBTR_l_r_a32, opLFS_l_a32, opLGS_l_a32, opMOVZX_l_b_a32, opMOVZX_l_w_a32, ILLEGAL, ILLEGAL, opBA_l_a32, opBTC_l_r_a32, opBSF_l_a32, opBSR_l_a32, - opMOVSX_l_b_a32, opMOVSX_l_w_a32, - -/*c0*/ opXADD_b_a32, opXADD_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, - opBSWAP_EDI, -/*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_a32, -/*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, -/*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, - }; - -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, ILLEGAL, ILLEGAL, ILLEGAL, -/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, -/*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, 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*/ 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, opRSM, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16, ILLEGAL, - opIMUL_w_w_a16, -/*b0*/ opCMPXCHG_b_a16, opCMPXCHG_w_a16, opLSS_w_a16, opBTR_w_r_a16, opLFS_w_a16, opLGS_w_a16, opMOVZX_w_b_a16, opMOVZX_w_w_a16, ILLEGAL, ILLEGAL, opBA_w_a16, opBTC_w_r_a16, opBSF_w_a16, opBSR_w_a16, - opMOVSX_w_b_a16, ILLEGAL, - -/*c0*/ opXADD_b_a16, opXADD_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, - opBSWAP_EDI, -/*d0*/ ILLEGAL, 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, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, -/*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, 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*/ 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, opRSM, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16, ILLEGAL, - opIMUL_l_l_a16, -/*b0*/ opCMPXCHG_b_a16, opCMPXCHG_l_a16, opLSS_l_a16, opBTR_l_r_a16, opLFS_l_a16, opLGS_l_a16, opMOVZX_l_b_a16, opMOVZX_l_w_a16, ILLEGAL, ILLEGAL, opBA_l_a16, opBTC_l_r_a16, opBSF_l_a16, opBSR_l_a16, - opMOVSX_l_b_a16, opMOVSX_l_w_a16, - -/*c0*/ opXADD_b_a16, opXADD_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, - opBSWAP_EDI, -/*d0*/ ILLEGAL, 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, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, -/*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, 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*/ 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, opRSM, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32, ILLEGAL, - opIMUL_w_w_a32, -/*b0*/ opCMPXCHG_b_a32, opCMPXCHG_w_a32, opLSS_w_a32, opBTR_w_r_a32, opLFS_w_a32, opLGS_w_a32, opMOVZX_w_b_a32, opMOVZX_w_w_a32, ILLEGAL, ILLEGAL, opBA_w_a32, opBTC_w_r_a32, opBSF_w_a32, opBSR_w_a32, - opMOVSX_w_b_a32, ILLEGAL, - -/*c0*/ opXADD_b_a32, opXADD_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, - opBSWAP_EDI, -/*d0*/ ILLEGAL, 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, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, -/*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, 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*/ 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, opRSM, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32, ILLEGAL, - opIMUL_l_l_a32, -/*b0*/ opCMPXCHG_b_a32, opCMPXCHG_l_a32, opLSS_l_a32, opBTR_l_r_a32, opLFS_l_a32, opLGS_l_a32, opMOVZX_l_b_a32, opMOVZX_l_w_a32, ILLEGAL, ILLEGAL, opBA_l_a32, opBTC_l_r_a32, opBSF_l_a32, opBSR_l_a32, - opMOVSX_l_b_a32, opMOVSX_l_w_a32, - -/*c0*/ opXADD_b_a32, opXADD_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, - opBSWAP_EDI, -/*d0*/ ILLEGAL, 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, - }; - -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, ILLEGAL, ILLEGAL, ILLEGAL, -/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, -/*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, opRSM, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16, ILLEGAL, - opIMUL_w_w_a16, -/*b0*/ opCMPXCHG_b_a16, opCMPXCHG_w_a16, opLSS_w_a16, opBTR_w_r_a16, opLFS_w_a16, opLGS_w_a16, opMOVZX_w_b_a16, opMOVZX_w_w_a16, ILLEGAL, ILLEGAL, opBA_w_a16, opBTC_w_r_a16, opBSF_w_a16, opBSR_w_a16, - opMOVSX_w_b_a16, ILLEGAL, - -/*c0*/ opXADD_b_a16, opXADD_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, - opBSWAP_EDI, -/*d0*/ ILLEGAL, opPSRLW_a16, opPSRLD_a16, opPSRLQ_a16, ILLEGAL, opPMULLW_a16, ILLEGAL, ILLEGAL, opPSUBUSB_a16, opPSUBUSW_a16, NULL, opPAND_a16, opPADDUSB_a16, opPADDUSW_a16, NULL, opPANDN_a16, -/*e0*/ ILLEGAL, opPSRAW_a16, opPSRAD_a16, ILLEGAL, ILLEGAL, opPMULHW_a16, ILLEGAL, ILLEGAL, opPSUBSB_a16, opPSUBSW_a16, NULL, opPOR_a16, opPADDSB_a16, opPADDSW_a16, NULL, opPXOR_a16, -/*f0*/ ILLEGAL, opPSLLW_a16, opPSLLD_a16, opPSLLQ_a16, ILLEGAL, opPMADDWD_a16, ILLEGAL, ILLEGAL, opPSUBB_a16, opPSUBW_a16, opPSUBD_a16, ILLEGAL, opPADDB_a16, opPADDW_a16, opPADDD_a16, ILLEGAL, - - /*32-bit data, 16-bit addr*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ op0F00_a16, op0F01_l_a16, opLAR_l_a16, opLSL_l_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, opHINTNOP_a16, -/*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, opRSM, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16, ILLEGAL, - opIMUL_l_l_a16, -/*b0*/ opCMPXCHG_b_a16, opCMPXCHG_l_a16, opLSS_l_a16, opBTR_l_r_a16, opLFS_l_a16, opLGS_l_a16, opMOVZX_l_b_a16, opMOVZX_l_w_a16, ILLEGAL, ILLEGAL, opBA_l_a16, opBTC_l_r_a16, opBSF_l_a16, opBSR_l_a16, - opMOVSX_l_b_a16, opMOVSX_l_w_a16, - -/*c0*/ opXADD_b_a16, opXADD_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, - opBSWAP_EDI, -/*d0*/ ILLEGAL, opPSRLW_a16, opPSRLD_a16, opPSRLQ_a16, ILLEGAL, opPMULLW_a16, ILLEGAL, ILLEGAL, opPSUBUSB_a16, opPSUBUSW_a16, NULL, opPAND_a16, opPADDUSB_a16, opPADDUSW_a16, NULL, opPANDN_a16, -/*e0*/ ILLEGAL, opPSRAW_a16, opPSRAD_a16, ILLEGAL, ILLEGAL, opPMULHW_a16, ILLEGAL, ILLEGAL, opPSUBSB_a16, opPSUBSW_a16, NULL, opPOR_a16, opPADDSB_a16, opPADDSW_a16, NULL, opPXOR_a16, -/*f0*/ ILLEGAL, opPSLLW_a16, opPSLLD_a16, opPSLLQ_a16, ILLEGAL, opPMADDWD_a16, ILLEGAL, ILLEGAL, opPSUBB_a16, opPSUBW_a16, opPSUBD_a16, ILLEGAL, opPADDB_a16, opPADDW_a16, opPADDD_a16, ILLEGAL, - - /*16-bit data, 32-bit addr*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ op0F00_a32, op0F01_w_a32, opLAR_w_a32, opLSL_w_a32, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, -/*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, opRSM, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32, ILLEGAL, - opIMUL_w_w_a32, -/*b0*/ opCMPXCHG_b_a32, opCMPXCHG_w_a32, opLSS_w_a32, opBTR_w_r_a32, opLFS_w_a32, opLGS_w_a32, opMOVZX_w_b_a32, opMOVZX_w_w_a32, ILLEGAL, ILLEGAL, opBA_w_a32, opBTC_w_r_a32, opBSF_w_a32, opBSR_w_a32, - opMOVSX_w_b_a32, ILLEGAL, - -/*c0*/ opXADD_b_a32, opXADD_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, - opBSWAP_EDI, -/*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_a32, -/*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, -/*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, - - /*32-bit data, 32-bit addr*/ -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ op0F00_a32, op0F01_l_a32, opLAR_l_a32, opLSL_l_a32, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, opHINTNOP_a32, -/*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, opRSM, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32, ILLEGAL, - opIMUL_l_l_a32, -/*b0*/ opCMPXCHG_b_a32, opCMPXCHG_l_a32, opLSS_l_a32, opBTR_l_r_a32, opLFS_l_a32, opLGS_l_a32, opMOVZX_l_b_a32, opMOVZX_l_w_a32, ILLEGAL, ILLEGAL, opBA_l_a32, opBTC_l_r_a32, opBSF_l_a32, opBSR_l_a32, - opMOVSX_l_b_a32, opMOVSX_l_w_a32, - -/*c0*/ opXADD_b_a32, opXADD_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, - opBSWAP_EDI, -/*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_a32, -/*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, -/*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, - }; - -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, - }; - -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, - }; - -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, - }; - -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, - }; +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, +}; + +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, + 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, +}; + +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, + opRSM, + opBTS_w_r_a16, + opSHRD_w_i_a16, + opSHRD_w_CL_a16, + ILLEGAL, + opIMUL_w_w_a16, + /*b0*/ opCMPXCHG_b_a16, + opCMPXCHG_w_a16, + opLSS_w_a16, + opBTR_w_r_a16, + opLFS_w_a16, + opLGS_w_a16, + opMOVZX_w_b_a16, + opMOVZX_w_w_a16, + ILLEGAL, + ILLEGAL, + opBA_w_a16, + opBTC_w_r_a16, + opBSF_w_a16, + opBSR_w_a16, + opMOVSX_w_b_a16, + ILLEGAL, + + /*c0*/ opXADD_b_a16, + opXADD_w_a16, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + opCMPXCHG8B_a16, + opBSWAP_EAX, + opBSWAP_ECX, + opBSWAP_EDX, + opBSWAP_EBX, + opBSWAP_ESP, + opBSWAP_EBP, + opBSWAP_ESI, + opBSWAP_EDI, + /*d0*/ ILLEGAL, + opPSRLW_a16, + opPSRLD_a16, + opPSRLQ_a16, + ILLEGAL, + opPMULLW_a16, + ILLEGAL, + ILLEGAL, + opPSUBUSB_a16, + opPSUBUSW_a16, + NULL, + opPAND_a16, + opPADDUSB_a16, + opPADDUSW_a16, + NULL, + opPANDN_a16, + /*e0*/ ILLEGAL, + opPSRAW_a16, + opPSRAD_a16, + ILLEGAL, + ILLEGAL, + opPMULHW_a16, + ILLEGAL, + ILLEGAL, + opPSUBSB_a16, + opPSUBSW_a16, + NULL, + opPOR_a16, + opPADDSB_a16, + opPADDSW_a16, + NULL, + opPXOR_a16, + /*f0*/ ILLEGAL, + opPSLLW_a16, + opPSLLD_a16, + opPSLLQ_a16, + ILLEGAL, + opPMADDWD_a16, + ILLEGAL, + ILLEGAL, + opPSUBB_a16, + opPSUBW_a16, + opPSUBD_a16, + ILLEGAL, + opPADDB_a16, + opPADDW_a16, + opPADDD_a16, + ILLEGAL, + + /*32-bit data, 16-bit addr*/ + /* 00 01 02 03 04 05 06 07 + 08 09 0a 0b 0c 0d 0e 0f*/ + /*00*/ op0F00_a16, + op0F01_l_a16, + opLAR_l_a16, + opLSL_l_a16, + ILLEGAL, + 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, + opRSM, + opBTS_l_r_a16, + opSHRD_l_i_a16, + opSHRD_l_CL_a16, + ILLEGAL, + opIMUL_l_l_a16, + /*b0*/ opCMPXCHG_b_a16, + opCMPXCHG_l_a16, + opLSS_l_a16, + opBTR_l_r_a16, + opLFS_l_a16, + opLGS_l_a16, + opMOVZX_l_b_a16, + opMOVZX_l_w_a16, + ILLEGAL, + ILLEGAL, + opBA_l_a16, + opBTC_l_r_a16, + opBSF_l_a16, + opBSR_l_a16, + opMOVSX_l_b_a16, + opMOVSX_l_w_a16, + + /*c0*/ opXADD_b_a16, + opXADD_l_a16, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + opCMPXCHG8B_a16, + opBSWAP_EAX, + opBSWAP_ECX, + opBSWAP_EDX, + opBSWAP_EBX, + opBSWAP_ESP, + opBSWAP_EBP, + opBSWAP_ESI, + opBSWAP_EDI, + /*d0*/ ILLEGAL, + opPSRLW_a16, + opPSRLD_a16, + opPSRLQ_a16, + ILLEGAL, + opPMULLW_a16, + ILLEGAL, + ILLEGAL, + opPSUBUSB_a16, + opPSUBUSW_a16, + NULL, + opPAND_a16, + opPADDUSB_a16, + opPADDUSW_a16, + NULL, + opPANDN_a16, + /*e0*/ ILLEGAL, + opPSRAW_a16, + opPSRAD_a16, + ILLEGAL, + ILLEGAL, + opPMULHW_a16, + ILLEGAL, + ILLEGAL, + opPSUBSB_a16, + opPSUBSW_a16, + NULL, + opPOR_a16, + opPADDSB_a16, + opPADDSW_a16, + NULL, + opPXOR_a16, + /*f0*/ ILLEGAL, + opPSLLW_a16, + opPSLLD_a16, + opPSLLQ_a16, + ILLEGAL, + opPMADDWD_a16, + ILLEGAL, + ILLEGAL, + opPSUBB_a16, + opPSUBW_a16, + opPSUBD_a16, + ILLEGAL, + opPADDB_a16, + opPADDW_a16, + opPADDD_a16, + ILLEGAL, + + /*16-bit data, 32-bit addr*/ + /* 00 01 02 03 04 05 06 07 + 08 09 0a 0b 0c 0d 0e 0f*/ + /*00*/ op0F00_a32, + op0F01_w_a32, + opLAR_w_a32, + opLSL_w_a32, + ILLEGAL, + 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, + opRSM, + opBTS_w_r_a32, + opSHRD_w_i_a32, + opSHRD_w_CL_a32, + ILLEGAL, + opIMUL_w_w_a32, + /*b0*/ opCMPXCHG_b_a32, + opCMPXCHG_w_a32, + opLSS_w_a32, + opBTR_w_r_a32, + opLFS_w_a32, + opLGS_w_a32, + opMOVZX_w_b_a32, + opMOVZX_w_w_a32, + ILLEGAL, + ILLEGAL, + opBA_w_a32, + opBTC_w_r_a32, + opBSF_w_a32, + opBSR_w_a32, + opMOVSX_w_b_a32, + ILLEGAL, + + /*c0*/ opXADD_b_a32, + opXADD_w_a32, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + opCMPXCHG8B_a32, + opBSWAP_EAX, + opBSWAP_ECX, + opBSWAP_EDX, + opBSWAP_EBX, + opBSWAP_ESP, + opBSWAP_EBP, + opBSWAP_ESI, + opBSWAP_EDI, + /*d0*/ ILLEGAL, + opPSRLW_a32, + opPSRLD_a32, + opPSRLQ_a32, + ILLEGAL, + opPMULLW_a32, + ILLEGAL, + ILLEGAL, + opPSUBUSB_a32, + opPSUBUSW_a32, + NULL, + opPAND_a32, + opPADDUSB_a32, + opPADDUSW_a32, + NULL, + opPANDN_a32, + /*e0*/ ILLEGAL, + opPSRAW_a32, + opPSRAD_a32, + ILLEGAL, + ILLEGAL, + opPMULHW_a32, + ILLEGAL, + ILLEGAL, + opPSUBSB_a32, + opPSUBSW_a32, + NULL, + opPOR_a32, + opPADDSB_a32, + opPADDSW_a32, + NULL, + opPXOR_a32, + /*f0*/ ILLEGAL, + opPSLLW_a32, + opPSLLD_a32, + opPSLLQ_a32, + ILLEGAL, + opPMADDWD_a32, + ILLEGAL, + ILLEGAL, + opPSUBB_a32, + opPSUBW_a32, + opPSUBD_a32, + ILLEGAL, + opPADDB_a32, + opPADDW_a32, + opPADDD_a32, + ILLEGAL, + + /*32-bit data, 32-bit addr*/ + /* 00 01 02 03 04 05 06 07 + 08 09 0a 0b 0c 0d 0e 0f*/ + /*00*/ op0F00_a32, + op0F01_l_a32, + opLAR_l_a32, + opLSL_l_a32, + ILLEGAL, + 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, + opRSM, + opBTS_l_r_a32, + opSHRD_l_i_a32, + opSHRD_l_CL_a32, + ILLEGAL, + opIMUL_l_l_a32, + /*b0*/ opCMPXCHG_b_a32, + opCMPXCHG_l_a32, + opLSS_l_a32, + opBTR_l_r_a32, + opLFS_l_a32, + opLGS_l_a32, + opMOVZX_l_b_a32, + opMOVZX_l_w_a32, + ILLEGAL, + ILLEGAL, + opBA_l_a32, + opBTC_l_r_a32, + opBSF_l_a32, + opBSR_l_a32, + opMOVSX_l_b_a32, + opMOVSX_l_w_a32, + + /*c0*/ opXADD_b_a32, + opXADD_l_a32, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + opCMPXCHG8B_a32, + opBSWAP_EAX, + opBSWAP_ECX, + opBSWAP_EDX, + opBSWAP_EBX, + opBSWAP_ESP, + opBSWAP_EBP, + opBSWAP_ESI, + opBSWAP_EDI, + /*d0*/ ILLEGAL, + opPSRLW_a32, + opPSRLD_a32, + opPSRLQ_a32, + ILLEGAL, + opPMULLW_a32, + ILLEGAL, + ILLEGAL, + opPSUBUSB_a32, + opPSUBUSW_a32, + NULL, + opPAND_a32, + opPADDUSB_a32, + opPADDUSW_a32, + NULL, + opPANDN_a32, + /*e0*/ ILLEGAL, + opPSRAW_a32, + opPSRAD_a32, + ILLEGAL, + ILLEGAL, + opPMULHW_a32, + ILLEGAL, + ILLEGAL, + opPSUBSB_a32, + opPSUBSW_a32, + NULL, + opPOR_a32, + opPADDSB_a32, + opPADDSW_a32, + NULL, + opPXOR_a32, + /*f0*/ ILLEGAL, + opPSLLW_a32, + opPSLLD_a32, + opPSLLQ_a32, + ILLEGAL, + opPMADDWD_a32, + ILLEGAL, + ILLEGAL, + opPSUBB_a32, + opPSUBW_a32, + opPSUBD_a32, + ILLEGAL, + opPADDB_a32, + opPADDW_a32, + opPADDD_a32, + ILLEGAL, +}; + +OpFn OP_TABLE(winchip2_0f)[1024] = { + /*16-bit data, 16-bit addr*/ + /* 00 01 02 03 04 05 06 07 + 08 09 0a 0b 0c 0d 0e 0f*/ + /*00*/ op0F00_a16, + op0F01_w_a16, + opLAR_w_a16, + opLSL_w_a16, + ILLEGAL, + ILLEGAL, + opCLTS, + ILLEGAL, + opINVD, + opWBINVD, + ILLEGAL, + ILLEGAL, + ILLEGAL, + opPREFETCH_a16, + opFEMMS, + op3DNOW_a16, + /*10*/ ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + /*20*/ opMOV_r_CRx_a16, + opMOV_r_DRx_a16, + opMOV_CRx_r_a16, + opMOV_DRx_r_a16, + opMOV_r_TRx_a16, + 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, + opRSM, + opBTS_w_r_a16, + opSHRD_w_i_a16, + opSHRD_w_CL_a16, + ILLEGAL, + opIMUL_w_w_a16, + /*b0*/ opCMPXCHG_b_a16, + opCMPXCHG_w_a16, + opLSS_w_a16, + opBTR_w_r_a16, + opLFS_w_a16, + opLGS_w_a16, + opMOVZX_w_b_a16, + opMOVZX_w_w_a16, + ILLEGAL, + ILLEGAL, + opBA_w_a16, + opBTC_w_r_a16, + opBSF_w_a16, + opBSR_w_a16, + opMOVSX_w_b_a16, + ILLEGAL, + + /*c0*/ opXADD_b_a16, + opXADD_w_a16, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + opCMPXCHG8B_a16, + opBSWAP_EAX, + opBSWAP_ECX, + opBSWAP_EDX, + opBSWAP_EBX, + opBSWAP_ESP, + opBSWAP_EBP, + opBSWAP_ESI, + opBSWAP_EDI, + /*d0*/ ILLEGAL, + opPSRLW_a16, + opPSRLD_a16, + opPSRLQ_a16, + ILLEGAL, + opPMULLW_a16, + ILLEGAL, + ILLEGAL, + opPSUBUSB_a16, + opPSUBUSW_a16, + NULL, + opPAND_a16, + opPADDUSB_a16, + opPADDUSW_a16, + NULL, + opPANDN_a16, + /*e0*/ ILLEGAL, + opPSRAW_a16, + opPSRAD_a16, + ILLEGAL, + ILLEGAL, + opPMULHW_a16, + ILLEGAL, + ILLEGAL, + opPSUBSB_a16, + opPSUBSW_a16, + NULL, + opPOR_a16, + opPADDSB_a16, + opPADDSW_a16, + NULL, + opPXOR_a16, + /*f0*/ ILLEGAL, + opPSLLW_a16, + opPSLLD_a16, + opPSLLQ_a16, + ILLEGAL, + opPMADDWD_a16, + ILLEGAL, + ILLEGAL, + opPSUBB_a16, + opPSUBW_a16, + opPSUBD_a16, + ILLEGAL, + opPADDB_a16, + opPADDW_a16, + opPADDD_a16, + ILLEGAL, + + /*32-bit data, 16-bit addr*/ + /* 00 01 02 03 04 05 06 07 + 08 09 0a 0b 0c 0d 0e 0f*/ + /*00*/ op0F00_a16, + op0F01_l_a16, + opLAR_l_a16, + opLSL_l_a16, + ILLEGAL, + ILLEGAL, + opCLTS, + ILLEGAL, + opINVD, + opWBINVD, + ILLEGAL, + ILLEGAL, + ILLEGAL, + opPREFETCH_a16, + opFEMMS, + op3DNOW_a16, + /*10*/ ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + /*20*/ opMOV_r_CRx_a16, + opMOV_r_DRx_a16, + opMOV_CRx_r_a16, + opMOV_DRx_r_a16, + opMOV_r_TRx_a16, + 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, + opRSM, + opBTS_l_r_a16, + opSHRD_l_i_a16, + opSHRD_l_CL_a16, + ILLEGAL, + opIMUL_l_l_a16, + /*b0*/ opCMPXCHG_b_a16, + opCMPXCHG_l_a16, + opLSS_l_a16, + opBTR_l_r_a16, + opLFS_l_a16, + opLGS_l_a16, + opMOVZX_l_b_a16, + opMOVZX_l_w_a16, + ILLEGAL, + ILLEGAL, + opBA_l_a16, + opBTC_l_r_a16, + opBSF_l_a16, + opBSR_l_a16, + opMOVSX_l_b_a16, + opMOVSX_l_w_a16, + + /*c0*/ opXADD_b_a16, + opXADD_l_a16, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + opCMPXCHG8B_a16, + opBSWAP_EAX, + opBSWAP_ECX, + opBSWAP_EDX, + opBSWAP_EBX, + opBSWAP_ESP, + opBSWAP_EBP, + opBSWAP_ESI, + opBSWAP_EDI, + /*d0*/ ILLEGAL, + opPSRLW_a16, + opPSRLD_a16, + opPSRLQ_a16, + ILLEGAL, + opPMULLW_a16, + ILLEGAL, + ILLEGAL, + opPSUBUSB_a16, + opPSUBUSW_a16, + NULL, + opPAND_a16, + opPADDUSB_a16, + opPADDUSW_a16, + NULL, + opPANDN_a16, + /*e0*/ ILLEGAL, + opPSRAW_a16, + opPSRAD_a16, + ILLEGAL, + ILLEGAL, + opPMULHW_a16, + ILLEGAL, + ILLEGAL, + opPSUBSB_a16, + opPSUBSW_a16, + NULL, + opPOR_a16, + opPADDSB_a16, + opPADDSW_a16, + NULL, + opPXOR_a16, + /*f0*/ ILLEGAL, + opPSLLW_a16, + opPSLLD_a16, + opPSLLQ_a16, + ILLEGAL, + opPMADDWD_a16, + ILLEGAL, + ILLEGAL, + opPSUBB_a16, + opPSUBW_a16, + opPSUBD_a16, + ILLEGAL, + opPADDB_a16, + opPADDW_a16, + opPADDD_a16, + ILLEGAL, + + /*16-bit data, 32-bit addr*/ + /* 00 01 02 03 04 05 06 07 + 08 09 0a 0b 0c 0d 0e 0f*/ + /*00*/ op0F00_a32, + op0F01_w_a32, + opLAR_w_a32, + opLSL_w_a32, + ILLEGAL, + ILLEGAL, + opCLTS, + ILLEGAL, + opINVD, + opWBINVD, + ILLEGAL, + ILLEGAL, + ILLEGAL, + opPREFETCH_a32, + opFEMMS, + op3DNOW_a32, + /*10*/ ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + /*20*/ opMOV_r_CRx_a32, + opMOV_r_DRx_a32, + opMOV_CRx_r_a32, + opMOV_DRx_r_a32, + opMOV_r_TRx_a32, + 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, + opRSM, + opBTS_w_r_a32, + opSHRD_w_i_a32, + opSHRD_w_CL_a32, + ILLEGAL, + opIMUL_w_w_a32, + /*b0*/ opCMPXCHG_b_a32, + opCMPXCHG_w_a32, + opLSS_w_a32, + opBTR_w_r_a32, + opLFS_w_a32, + opLGS_w_a32, + opMOVZX_w_b_a32, + opMOVZX_w_w_a32, + ILLEGAL, + ILLEGAL, + opBA_w_a32, + opBTC_w_r_a32, + opBSF_w_a32, + opBSR_w_a32, + opMOVSX_w_b_a32, + ILLEGAL, + + /*c0*/ opXADD_b_a32, + opXADD_w_a32, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + opCMPXCHG8B_a32, + opBSWAP_EAX, + opBSWAP_ECX, + opBSWAP_EDX, + opBSWAP_EBX, + opBSWAP_ESP, + opBSWAP_EBP, + opBSWAP_ESI, + opBSWAP_EDI, + /*d0*/ ILLEGAL, + opPSRLW_a32, + opPSRLD_a32, + opPSRLQ_a32, + ILLEGAL, + opPMULLW_a32, + ILLEGAL, + ILLEGAL, + opPSUBUSB_a32, + opPSUBUSW_a32, + NULL, + opPAND_a32, + opPADDUSB_a32, + opPADDUSW_a32, + NULL, + opPANDN_a32, + /*e0*/ ILLEGAL, + opPSRAW_a32, + opPSRAD_a32, + ILLEGAL, + ILLEGAL, + opPMULHW_a32, + ILLEGAL, + ILLEGAL, + opPSUBSB_a32, + opPSUBSW_a32, + NULL, + opPOR_a32, + opPADDSB_a32, + opPADDSW_a32, + NULL, + opPXOR_a32, + /*f0*/ ILLEGAL, + opPSLLW_a32, + opPSLLD_a32, + opPSLLQ_a32, + ILLEGAL, + opPMADDWD_a32, + ILLEGAL, + ILLEGAL, + opPSUBB_a32, + opPSUBW_a32, + opPSUBD_a32, + ILLEGAL, + opPADDB_a32, + opPADDW_a32, + opPADDD_a32, + ILLEGAL, + + /*32-bit data, 32-bit addr*/ + /* 00 01 02 03 04 05 06 07 + 08 09 0a 0b 0c 0d 0e 0f*/ + /*00*/ op0F00_a32, + op0F01_l_a32, + opLAR_l_a32, + opLSL_l_a32, + ILLEGAL, + ILLEGAL, + opCLTS, + ILLEGAL, + opINVD, + opWBINVD, + ILLEGAL, + ILLEGAL, + ILLEGAL, + opPREFETCH_a32, + opFEMMS, + op3DNOW_a32, + /*10*/ ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + /*20*/ opMOV_r_CRx_a32, + opMOV_r_DRx_a32, + opMOV_CRx_r_a32, + opMOV_DRx_r_a32, + opMOV_r_TRx_a32, + 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, + opRSM, + opBTS_l_r_a32, + opSHRD_l_i_a32, + opSHRD_l_CL_a32, + ILLEGAL, + opIMUL_l_l_a32, + /*b0*/ opCMPXCHG_b_a32, + opCMPXCHG_l_a32, + opLSS_l_a32, + opBTR_l_r_a32, + opLFS_l_a32, + opLGS_l_a32, + opMOVZX_l_b_a32, + opMOVZX_l_w_a32, + ILLEGAL, + ILLEGAL, + opBA_l_a32, + opBTC_l_r_a32, + opBSF_l_a32, + opBSR_l_a32, + opMOVSX_l_b_a32, + opMOVSX_l_w_a32, + + /*c0*/ opXADD_b_a32, + opXADD_l_a32, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + opCMPXCHG8B_a32, + opBSWAP_EAX, + opBSWAP_ECX, + opBSWAP_EDX, + opBSWAP_EBX, + opBSWAP_ESP, + opBSWAP_EBP, + opBSWAP_ESI, + opBSWAP_EDI, + /*d0*/ ILLEGAL, + opPSRLW_a32, + opPSRLD_a32, + opPSRLQ_a32, + ILLEGAL, + opPMULLW_a32, + ILLEGAL, + ILLEGAL, + opPSUBUSB_a32, + opPSUBUSW_a32, + NULL, + opPAND_a32, + opPADDUSB_a32, + opPADDUSW_a32, + NULL, + opPANDN_a32, + /*e0*/ ILLEGAL, + opPSRAW_a32, + opPSRAD_a32, + ILLEGAL, + ILLEGAL, + opPMULHW_a32, + ILLEGAL, + ILLEGAL, + opPSUBSB_a32, + opPSUBSW_a32, + NULL, + opPOR_a32, + opPADDSB_a32, + opPADDSW_a32, + NULL, + opPXOR_a32, + /*f0*/ ILLEGAL, + opPSLLW_a32, + opPSLLD_a32, + opPSLLQ_a32, + ILLEGAL, + opPMADDWD_a32, + ILLEGAL, + ILLEGAL, + opPSUBB_a32, + opPSUBW_a32, + opPSUBD_a32, + ILLEGAL, + opPADDB_a32, + opPADDW_a32, + opPADDD_a32, + ILLEGAL, +}; + +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, + opRSM, + opBTS_w_r_a16, + opSHRD_w_i_a16, + opSHRD_w_CL_a16, + ILLEGAL, + opIMUL_w_w_a16, + /*b0*/ opCMPXCHG_b_a16, + opCMPXCHG_w_a16, + opLSS_w_a16, + opBTR_w_r_a16, + opLFS_w_a16, + opLGS_w_a16, + opMOVZX_w_b_a16, + opMOVZX_w_w_a16, + ILLEGAL, + ILLEGAL, + opBA_w_a16, + opBTC_w_r_a16, + opBSF_w_a16, + opBSR_w_a16, + opMOVSX_w_b_a16, + ILLEGAL, + + /*c0*/ opXADD_b_a16, + opXADD_w_a16, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + opCMPXCHG8B_a16, + opBSWAP_EAX, + opBSWAP_ECX, + opBSWAP_EDX, + opBSWAP_EBX, + opBSWAP_ESP, + opBSWAP_EBP, + opBSWAP_ESI, + opBSWAP_EDI, + /*d0*/ ILLEGAL, + 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, + opRSM, + opBTS_l_r_a16, + opSHRD_l_i_a16, + opSHRD_l_CL_a16, + ILLEGAL, + opIMUL_l_l_a16, + /*b0*/ opCMPXCHG_b_a16, + opCMPXCHG_l_a16, + opLSS_l_a16, + opBTR_l_r_a16, + opLFS_l_a16, + opLGS_l_a16, + opMOVZX_l_b_a16, + opMOVZX_l_w_a16, + ILLEGAL, + ILLEGAL, + opBA_l_a16, + opBTC_l_r_a16, + opBSF_l_a16, + opBSR_l_a16, + opMOVSX_l_b_a16, + opMOVSX_l_w_a16, + + /*c0*/ opXADD_b_a16, + opXADD_l_a16, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + opCMPXCHG8B_a16, + opBSWAP_EAX, + opBSWAP_ECX, + opBSWAP_EDX, + opBSWAP_EBX, + opBSWAP_ESP, + opBSWAP_EBP, + opBSWAP_ESI, + opBSWAP_EDI, + /*d0*/ ILLEGAL, + 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, + opRSM, + opBTS_w_r_a32, + opSHRD_w_i_a32, + opSHRD_w_CL_a32, + ILLEGAL, + opIMUL_w_w_a32, + /*b0*/ opCMPXCHG_b_a32, + opCMPXCHG_w_a32, + opLSS_w_a32, + opBTR_w_r_a32, + opLFS_w_a32, + opLGS_w_a32, + opMOVZX_w_b_a32, + opMOVZX_w_w_a32, + ILLEGAL, + ILLEGAL, + opBA_w_a32, + opBTC_w_r_a32, + opBSF_w_a32, + opBSR_w_a32, + opMOVSX_w_b_a32, + ILLEGAL, + + /*c0*/ opXADD_b_a32, + opXADD_w_a32, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + opCMPXCHG8B_a32, + opBSWAP_EAX, + opBSWAP_ECX, + opBSWAP_EDX, + opBSWAP_EBX, + opBSWAP_ESP, + opBSWAP_EBP, + opBSWAP_ESI, + opBSWAP_EDI, + /*d0*/ ILLEGAL, + 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, + opRSM, + opBTS_l_r_a32, + opSHRD_l_i_a32, + opSHRD_l_CL_a32, + ILLEGAL, + opIMUL_l_l_a32, + /*b0*/ opCMPXCHG_b_a32, + opCMPXCHG_l_a32, + opLSS_l_a32, + opBTR_l_r_a32, + opLFS_l_a32, + opLGS_l_a32, + opMOVZX_l_b_a32, + opMOVZX_l_w_a32, + ILLEGAL, + ILLEGAL, + opBA_l_a32, + opBTC_l_r_a32, + opBSF_l_a32, + opBSR_l_a32, + opMOVSX_l_b_a32, + opMOVSX_l_w_a32, + + /*c0*/ opXADD_b_a32, + opXADD_l_a32, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + opCMPXCHG8B_a32, + opBSWAP_EAX, + opBSWAP_ECX, + opBSWAP_EDX, + opBSWAP_EBX, + opBSWAP_ESP, + opBSWAP_EBP, + opBSWAP_ESI, + opBSWAP_EDI, + /*d0*/ ILLEGAL, + 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, +}; + +OpFn OP_TABLE(c6x86_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, + opSVDC_a16, + opRSDC_a16, + opSVLDT_a16, + opRSLDT_a16, + opSVTS_a16, + opRSTS_a16, + opSMINT, + 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, + opRSM, + opBTS_w_r_a16, + opSHRD_w_i_a16, + opSHRD_w_CL_a16, + ILLEGAL, + opIMUL_w_w_a16, + /*b0*/ opCMPXCHG_b_a16, + opCMPXCHG_w_a16, + opLSS_w_a16, + opBTR_w_r_a16, + opLFS_w_a16, + opLGS_w_a16, + opMOVZX_w_b_a16, + opMOVZX_w_w_a16, + ILLEGAL, + ILLEGAL, + opBA_w_a16, + opBTC_w_r_a16, + opBSF_w_a16, + opBSR_w_a16, + opMOVSX_w_b_a16, + ILLEGAL, + + /*c0*/ opXADD_b_a16, + opXADD_w_a16, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + opCMPXCHG8B_a16, + opBSWAP_EAX, + opBSWAP_ECX, + opBSWAP_EDX, + opBSWAP_EBX, + opBSWAP_ESP, + opBSWAP_EBP, + opBSWAP_ESI, + opBSWAP_EDI, + /*d0*/ ILLEGAL, + 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, + opSVDC_a16, + opRSDC_a16, + opSVLDT_a16, + opRSLDT_a16, + opSVTS_a16, + opRSTS_a16, + opSMINT, + 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, + opRSM, + opBTS_l_r_a16, + opSHRD_l_i_a16, + opSHRD_l_CL_a16, + ILLEGAL, + opIMUL_l_l_a16, + /*b0*/ opCMPXCHG_b_a16, + opCMPXCHG_l_a16, + opLSS_l_a16, + opBTR_l_r_a16, + opLFS_l_a16, + opLGS_l_a16, + opMOVZX_l_b_a16, + opMOVZX_l_w_a16, + ILLEGAL, + ILLEGAL, + opBA_l_a16, + opBTC_l_r_a16, + opBSF_l_a16, + opBSR_l_a16, + opMOVSX_l_b_a16, + opMOVSX_l_w_a16, + + /*c0*/ opXADD_b_a16, + opXADD_l_a16, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + opCMPXCHG8B_a16, + opBSWAP_EAX, + opBSWAP_ECX, + opBSWAP_EDX, + opBSWAP_EBX, + opBSWAP_ESP, + opBSWAP_EBP, + opBSWAP_ESI, + opBSWAP_EDI, + /*d0*/ ILLEGAL, + 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, + opSVDC_a32, + opRSDC_a32, + opSVLDT_a32, + opRSLDT_a32, + opSVTS_a32, + opRSTS_a32, + opSMINT, + 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, + opRSM, + opBTS_w_r_a32, + opSHRD_w_i_a32, + opSHRD_w_CL_a32, + ILLEGAL, + opIMUL_w_w_a32, + /*b0*/ opCMPXCHG_b_a32, + opCMPXCHG_w_a32, + opLSS_w_a32, + opBTR_w_r_a32, + opLFS_w_a32, + opLGS_w_a32, + opMOVZX_w_b_a32, + opMOVZX_w_w_a32, + ILLEGAL, + ILLEGAL, + opBA_w_a32, + opBTC_w_r_a32, + opBSF_w_a32, + opBSR_w_a32, + opMOVSX_w_b_a32, + ILLEGAL, + + /*c0*/ opXADD_b_a32, + opXADD_w_a32, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + opCMPXCHG8B_a32, + opBSWAP_EAX, + opBSWAP_ECX, + opBSWAP_EDX, + opBSWAP_EBX, + opBSWAP_ESP, + opBSWAP_EBP, + opBSWAP_ESI, + opBSWAP_EDI, + /*d0*/ ILLEGAL, + 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, + opSVDC_a32, + opRSDC_a32, + opSVLDT_a32, + opRSLDT_a32, + opSVTS_a32, + opRSTS_a32, + opSMINT, + 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, + opRSM, + opBTS_l_r_a32, + opSHRD_l_i_a32, + opSHRD_l_CL_a32, + ILLEGAL, + opIMUL_l_l_a32, + /*b0*/ opCMPXCHG_b_a32, + opCMPXCHG_l_a32, + opLSS_l_a32, + opBTR_l_r_a32, + opLFS_l_a32, + opLGS_l_a32, + opMOVZX_l_b_a32, + opMOVZX_l_w_a32, + ILLEGAL, + ILLEGAL, + opBA_l_a32, + opBTC_l_r_a32, + opBSF_l_a32, + opBSR_l_a32, + opMOVSX_l_b_a32, + opMOVSX_l_w_a32, + + /*c0*/ opXADD_b_a32, + opXADD_l_a32, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + opCMPXCHG8B_a32, + opBSWAP_EAX, + opBSWAP_ECX, + opBSWAP_EDX, + opBSWAP_EBX, + opBSWAP_ESP, + opBSWAP_EBP, + opBSWAP_ESI, + opBSWAP_EDI, + /*d0*/ ILLEGAL, + 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, +}; + +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, + opRSM, + opBTS_w_r_a16, + opSHRD_w_i_a16, + opSHRD_w_CL_a16, + ILLEGAL, + opIMUL_w_w_a16, + /*b0*/ opCMPXCHG_b_a16, + opCMPXCHG_w_a16, + opLSS_w_a16, + opBTR_w_r_a16, + opLFS_w_a16, + opLGS_w_a16, + opMOVZX_w_b_a16, + opMOVZX_w_w_a16, + ILLEGAL, + ILLEGAL, + opBA_w_a16, + opBTC_w_r_a16, + opBSF_w_a16, + opBSR_w_a16, + opMOVSX_w_b_a16, + ILLEGAL, + + /*c0*/ opXADD_b_a16, + opXADD_w_a16, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + opCMPXCHG8B_a16, + opBSWAP_EAX, + opBSWAP_ECX, + opBSWAP_EDX, + opBSWAP_EBX, + opBSWAP_ESP, + opBSWAP_EBP, + opBSWAP_ESI, + opBSWAP_EDI, + /*d0*/ ILLEGAL, + opPSRLW_a16, + opPSRLD_a16, + opPSRLQ_a16, + ILLEGAL, + opPMULLW_a16, + ILLEGAL, + ILLEGAL, + opPSUBUSB_a16, + opPSUBUSW_a16, + NULL, + opPAND_a16, + opPADDUSB_a16, + opPADDUSW_a16, + NULL, + opPANDN_a16, + /*e0*/ ILLEGAL, + opPSRAW_a16, + opPSRAD_a16, + ILLEGAL, + ILLEGAL, + opPMULHW_a16, + ILLEGAL, + ILLEGAL, + opPSUBSB_a16, + opPSUBSW_a16, + NULL, + opPOR_a16, + opPADDSB_a16, + opPADDSW_a16, + NULL, + opPXOR_a16, + /*f0*/ ILLEGAL, + opPSLLW_a16, + opPSLLD_a16, + opPSLLQ_a16, + ILLEGAL, + opPMADDWD_a16, + ILLEGAL, + ILLEGAL, + opPSUBB_a16, + opPSUBW_a16, + opPSUBD_a16, + ILLEGAL, + opPADDB_a16, + opPADDW_a16, + opPADDD_a16, + ILLEGAL, + + /*32-bit data, 16-bit addr*/ + /* 00 01 02 03 04 05 06 07 + 08 09 0a 0b 0c 0d 0e 0f*/ + /*00*/ op0F00_a16, + op0F01_l_a16, + opLAR_l_a16, + opLSL_l_a16, + ILLEGAL, + 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, + opRSM, + opBTS_l_r_a16, + opSHRD_l_i_a16, + opSHRD_l_CL_a16, + ILLEGAL, + opIMUL_l_l_a16, + /*b0*/ opCMPXCHG_b_a16, + opCMPXCHG_l_a16, + opLSS_l_a16, + opBTR_l_r_a16, + opLFS_l_a16, + opLGS_l_a16, + opMOVZX_l_b_a16, + opMOVZX_l_w_a16, + ILLEGAL, + ILLEGAL, + opBA_l_a16, + opBTC_l_r_a16, + opBSF_l_a16, + opBSR_l_a16, + opMOVSX_l_b_a16, + opMOVSX_l_w_a16, + + /*c0*/ opXADD_b_a16, + opXADD_l_a16, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + opCMPXCHG8B_a16, + opBSWAP_EAX, + opBSWAP_ECX, + opBSWAP_EDX, + opBSWAP_EBX, + opBSWAP_ESP, + opBSWAP_EBP, + opBSWAP_ESI, + opBSWAP_EDI, + /*d0*/ ILLEGAL, + opPSRLW_a16, + opPSRLD_a16, + opPSRLQ_a16, + ILLEGAL, + opPMULLW_a16, + ILLEGAL, + ILLEGAL, + opPSUBUSB_a16, + opPSUBUSW_a16, + NULL, + opPAND_a16, + opPADDUSB_a16, + opPADDUSW_a16, + NULL, + opPANDN_a16, + /*e0*/ ILLEGAL, + opPSRAW_a16, + opPSRAD_a16, + ILLEGAL, + ILLEGAL, + opPMULHW_a16, + ILLEGAL, + ILLEGAL, + opPSUBSB_a16, + opPSUBSW_a16, + NULL, + opPOR_a16, + opPADDSB_a16, + opPADDSW_a16, + NULL, + opPXOR_a16, + /*f0*/ ILLEGAL, + opPSLLW_a16, + opPSLLD_a16, + opPSLLQ_a16, + ILLEGAL, + opPMADDWD_a16, + ILLEGAL, + ILLEGAL, + opPSUBB_a16, + opPSUBW_a16, + opPSUBD_a16, + ILLEGAL, + opPADDB_a16, + opPADDW_a16, + opPADDD_a16, + ILLEGAL, + + /*16-bit data, 32-bit addr*/ + /* 00 01 02 03 04 05 06 07 + 08 09 0a 0b 0c 0d 0e 0f*/ + /*00*/ op0F00_a32, + op0F01_w_a32, + opLAR_w_a32, + opLSL_w_a32, + ILLEGAL, + 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, + opRSM, + opBTS_w_r_a32, + opSHRD_w_i_a32, + opSHRD_w_CL_a32, + ILLEGAL, + opIMUL_w_w_a32, + /*b0*/ opCMPXCHG_b_a32, + opCMPXCHG_w_a32, + opLSS_w_a32, + opBTR_w_r_a32, + opLFS_w_a32, + opLGS_w_a32, + opMOVZX_w_b_a32, + opMOVZX_w_w_a32, + ILLEGAL, + ILLEGAL, + opBA_w_a32, + opBTC_w_r_a32, + opBSF_w_a32, + opBSR_w_a32, + opMOVSX_w_b_a32, + ILLEGAL, + + /*c0*/ opXADD_b_a32, + opXADD_w_a32, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + opCMPXCHG8B_a32, + opBSWAP_EAX, + opBSWAP_ECX, + opBSWAP_EDX, + opBSWAP_EBX, + opBSWAP_ESP, + opBSWAP_EBP, + opBSWAP_ESI, + opBSWAP_EDI, + /*d0*/ ILLEGAL, + opPSRLW_a32, + opPSRLD_a32, + opPSRLQ_a32, + ILLEGAL, + opPMULLW_a32, + ILLEGAL, + ILLEGAL, + opPSUBUSB_a32, + opPSUBUSW_a32, + NULL, + opPAND_a32, + opPADDUSB_a32, + opPADDUSW_a32, + NULL, + opPANDN_a32, + /*e0*/ ILLEGAL, + opPSRAW_a32, + opPSRAD_a32, + ILLEGAL, + ILLEGAL, + opPMULHW_a32, + ILLEGAL, + ILLEGAL, + opPSUBSB_a32, + opPSUBSW_a32, + NULL, + opPOR_a32, + opPADDSB_a32, + opPADDSW_a32, + NULL, + opPXOR_a32, + /*f0*/ ILLEGAL, + opPSLLW_a32, + opPSLLD_a32, + opPSLLQ_a32, + ILLEGAL, + opPMADDWD_a32, + ILLEGAL, + ILLEGAL, + opPSUBB_a32, + opPSUBW_a32, + opPSUBD_a32, + ILLEGAL, + opPADDB_a32, + opPADDW_a32, + opPADDD_a32, + ILLEGAL, + + /*32-bit data, 32-bit addr*/ + /* 00 01 02 03 04 05 06 07 + 08 09 0a 0b 0c 0d 0e 0f*/ + /*00*/ op0F00_a32, + op0F01_l_a32, + opLAR_l_a32, + opLSL_l_a32, + ILLEGAL, + 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, + opRSM, + opBTS_l_r_a32, + opSHRD_l_i_a32, + opSHRD_l_CL_a32, + ILLEGAL, + opIMUL_l_l_a32, + /*b0*/ opCMPXCHG_b_a32, + opCMPXCHG_l_a32, + opLSS_l_a32, + opBTR_l_r_a32, + opLFS_l_a32, + opLGS_l_a32, + opMOVZX_l_b_a32, + opMOVZX_l_w_a32, + ILLEGAL, + ILLEGAL, + opBA_l_a32, + opBTC_l_r_a32, + opBSF_l_a32, + opBSR_l_a32, + opMOVSX_l_b_a32, + opMOVSX_l_w_a32, + + /*c0*/ opXADD_b_a32, + opXADD_l_a32, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + opCMPXCHG8B_a32, + opBSWAP_EAX, + opBSWAP_ECX, + opBSWAP_EDX, + opBSWAP_EBX, + opBSWAP_ESP, + opBSWAP_EBP, + opBSWAP_ESI, + opBSWAP_EDI, + /*d0*/ ILLEGAL, + opPSRLW_a32, + opPSRLD_a32, + opPSRLQ_a32, + ILLEGAL, + opPMULLW_a32, + ILLEGAL, + ILLEGAL, + opPSUBUSB_a32, + opPSUBUSW_a32, + NULL, + opPAND_a32, + opPADDUSB_a32, + opPADDUSW_a32, + NULL, + opPANDN_a32, + /*e0*/ ILLEGAL, + opPSRAW_a32, + opPSRAD_a32, + ILLEGAL, + ILLEGAL, + opPMULHW_a32, + ILLEGAL, + ILLEGAL, + opPSUBSB_a32, + opPSUBSW_a32, + NULL, + opPOR_a32, + opPADDSB_a32, + opPADDSW_a32, + NULL, + opPXOR_a32, + /*f0*/ ILLEGAL, + opPSLLW_a32, + opPSLLD_a32, + opPSLLQ_a32, + ILLEGAL, + opPMADDWD_a32, + ILLEGAL, + ILLEGAL, + opPSUBB_a32, + opPSUBW_a32, + opPSUBD_a32, + ILLEGAL, + opPADDB_a32, + opPADDW_a32, + opPADDD_a32, + ILLEGAL, +}; + +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, + opRDSHR_a16, + opWRSHR_a16, + 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, + opSVDC_a16, + opRSDC_a16, + opSVLDT_a16, + opRSLDT_a16, + opSVTS_a16, + opRSTS_a16, + opMOVD_mm_l_a16_cx, + opMOVQ_mm_q_a16, + + /*80*/ opJO_w, + opJNO_w, + opJB_w, + opJNB_w, + opJE_w, + opJNE_w, + opJBE_w, + opJNBE_w, + opJS_w, + opJNS_w, + opJP_w, + opJNP_w, + opJL_w, + opJNL_w, + opJLE_w, + opJNLE_w, + /*90*/ opSETO_a16, + opSETNO_a16, + opSETB_a16, + opSETNB_a16, + opSETE_a16, + opSETNE_a16, + opSETBE_a16, + opSETNBE_a16, + opSETS_a16, + opSETNS_a16, + opSETP_a16, + opSETNP_a16, + opSETL_a16, + opSETNL_a16, + opSETLE_a16, + opSETNLE_a16, + /*a0*/ opPUSH_FS_w, + opPOP_FS_w, + opCPUID, + opBT_w_r_a16, + opSHLD_w_i_a16, + opSHLD_w_CL_a16, + ILLEGAL, + ILLEGAL, + opPUSH_GS_w, + opPOP_GS_w, + opRSM, + opBTS_w_r_a16, + opSHRD_w_i_a16, + opSHRD_w_CL_a16, + ILLEGAL, + opIMUL_w_w_a16, + /*b0*/ opCMPXCHG_b_a16, + opCMPXCHG_w_a16, + opLSS_w_a16, + opBTR_w_r_a16, + opLFS_w_a16, + opLGS_w_a16, + opMOVZX_w_b_a16, + opMOVZX_w_w_a16, + ILLEGAL, + ILLEGAL, + opBA_w_a16, + opBTC_w_r_a16, + opBSF_w_a16, + opBSR_w_a16, + opMOVSX_w_b_a16, + ILLEGAL, + + /*c0*/ opXADD_b_a16, + opXADD_w_a16, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + opCMPXCHG8B_a16, + opBSWAP_EAX, + opBSWAP_ECX, + opBSWAP_EDX, + opBSWAP_EBX, + opBSWAP_ESP, + opBSWAP_EBP, + opBSWAP_ESI, + opBSWAP_EDI, + /*d0*/ ILLEGAL, + opPSRLW_a16, + opPSRLD_a16, + opPSRLQ_a16, + ILLEGAL, + opPMULLW_a16, + ILLEGAL, + ILLEGAL, + opPSUBUSB_a16, + opPSUBUSW_a16, + NULL, + opPAND_a16, + opPADDUSB_a16, + opPADDUSW_a16, + NULL, + opPANDN_a16, + /*e0*/ ILLEGAL, + opPSRAW_a16, + opPSRAD_a16, + ILLEGAL, + ILLEGAL, + opPMULHW_a16, + ILLEGAL, + ILLEGAL, + opPSUBSB_a16, + opPSUBSW_a16, + NULL, + opPOR_a16, + opPADDSB_a16, + opPADDSW_a16, + NULL, + opPXOR_a16, + /*f0*/ ILLEGAL, + opPSLLW_a16, + opPSLLD_a16, + opPSLLQ_a16, + ILLEGAL, + opPMADDWD_a16, + ILLEGAL, + ILLEGAL, + opPSUBB_a16, + opPSUBW_a16, + opPSUBD_a16, + ILLEGAL, + opPADDB_a16, + opPADDW_a16, + opPADDD_a16, + ILLEGAL, + + /*32-bit data, 16-bit addr*/ + /* 00 01 02 03 04 05 06 07 + 08 09 0a 0b 0c 0d 0e 0f*/ + /*00*/ op0F00_a16, + op0F01_l_a16, + opLAR_l_a16, + opLSL_l_a16, + ILLEGAL, + 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, + opRDSHR_a16, + opWRSHR_a16, + 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, + opSVDC_a16, + opRSDC_a16, + opSVLDT_a16, + opRSLDT_a16, + opSVTS_a16, + opRSTS_a16, + opMOVD_mm_l_a16_cx, + opMOVQ_mm_q_a16, + + /*80*/ opJO_l, + opJNO_l, + opJB_l, + opJNB_l, + opJE_l, + opJNE_l, + opJBE_l, + opJNBE_l, + opJS_l, + opJNS_l, + opJP_l, + opJNP_l, + opJL_l, + opJNL_l, + opJLE_l, + opJNLE_l, + /*90*/ opSETO_a16, + opSETNO_a16, + opSETB_a16, + opSETNB_a16, + opSETE_a16, + opSETNE_a16, + opSETBE_a16, + opSETNBE_a16, + opSETS_a16, + opSETNS_a16, + opSETP_a16, + opSETNP_a16, + opSETL_a16, + opSETNL_a16, + opSETLE_a16, + opSETNLE_a16, + /*a0*/ opPUSH_FS_l, + opPOP_FS_l, + opCPUID, + opBT_l_r_a16, + opSHLD_l_i_a16, + opSHLD_l_CL_a16, + ILLEGAL, + ILLEGAL, + opPUSH_GS_l, + opPOP_GS_l, + opRSM, + opBTS_l_r_a16, + opSHRD_l_i_a16, + opSHRD_l_CL_a16, + ILLEGAL, + opIMUL_l_l_a16, + /*b0*/ opCMPXCHG_b_a16, + opCMPXCHG_l_a16, + opLSS_l_a16, + opBTR_l_r_a16, + opLFS_l_a16, + opLGS_l_a16, + opMOVZX_l_b_a16, + opMOVZX_l_w_a16, + ILLEGAL, + ILLEGAL, + opBA_l_a16, + opBTC_l_r_a16, + opBSF_l_a16, + opBSR_l_a16, + opMOVSX_l_b_a16, + opMOVSX_l_w_a16, + + /*c0*/ opXADD_b_a16, + opXADD_l_a16, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + opCMPXCHG8B_a16, + opBSWAP_EAX, + opBSWAP_ECX, + opBSWAP_EDX, + opBSWAP_EBX, + opBSWAP_ESP, + opBSWAP_EBP, + opBSWAP_ESI, + opBSWAP_EDI, + /*d0*/ ILLEGAL, + opPSRLW_a16, + opPSRLD_a16, + opPSRLQ_a16, + ILLEGAL, + opPMULLW_a16, + ILLEGAL, + ILLEGAL, + opPSUBUSB_a16, + opPSUBUSW_a16, + NULL, + opPAND_a16, + opPADDUSB_a16, + opPADDUSW_a16, + NULL, + opPANDN_a16, + /*e0*/ ILLEGAL, + opPSRAW_a16, + opPSRAD_a16, + ILLEGAL, + ILLEGAL, + opPMULHW_a16, + ILLEGAL, + ILLEGAL, + opPSUBSB_a16, + opPSUBSW_a16, + NULL, + opPOR_a16, + opPADDSB_a16, + opPADDSW_a16, + NULL, + opPXOR_a16, + /*f0*/ ILLEGAL, + opPSLLW_a16, + opPSLLD_a16, + opPSLLQ_a16, + ILLEGAL, + opPMADDWD_a16, + ILLEGAL, + ILLEGAL, + opPSUBB_a16, + opPSUBW_a16, + opPSUBD_a16, + ILLEGAL, + opPADDB_a16, + opPADDW_a16, + opPADDD_a16, + ILLEGAL, + + /*16-bit data, 32-bit addr*/ + /* 00 01 02 03 04 05 06 07 + 08 09 0a 0b 0c 0d 0e 0f*/ + /*00*/ op0F00_a32, + op0F01_w_a32, + opLAR_w_a32, + opLSL_w_a32, + ILLEGAL, + 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, + opRDSHR_a32, + opWRSHR_a32, + 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, + opSVDC_a32, + opRSDC_a32, + opSVLDT_a32, + opRSLDT_a32, + opSVTS_a32, + opRSTS_a32, + opMOVD_mm_l_a32_cx, + opMOVQ_mm_q_a32, + + /*80*/ opJO_w, + opJNO_w, + opJB_w, + opJNB_w, + opJE_w, + opJNE_w, + opJBE_w, + opJNBE_w, + opJS_w, + opJNS_w, + opJP_w, + opJNP_w, + opJL_w, + opJNL_w, + opJLE_w, + opJNLE_w, + /*90*/ opSETO_a32, + opSETNO_a32, + opSETB_a32, + opSETNB_a32, + opSETE_a32, + opSETNE_a32, + opSETBE_a32, + opSETNBE_a32, + opSETS_a32, + opSETNS_a32, + opSETP_a32, + opSETNP_a32, + opSETL_a32, + opSETNL_a32, + opSETLE_a32, + opSETNLE_a32, + /*a0*/ opPUSH_FS_w, + opPOP_FS_w, + opCPUID, + opBT_w_r_a32, + opSHLD_w_i_a32, + opSHLD_w_CL_a32, + ILLEGAL, + ILLEGAL, + opPUSH_GS_w, + opPOP_GS_w, + opRSM, + opBTS_w_r_a32, + opSHRD_w_i_a32, + opSHRD_w_CL_a32, + ILLEGAL, + opIMUL_w_w_a32, + /*b0*/ opCMPXCHG_b_a32, + opCMPXCHG_w_a32, + opLSS_w_a32, + opBTR_w_r_a32, + opLFS_w_a32, + opLGS_w_a32, + opMOVZX_w_b_a32, + opMOVZX_w_w_a32, + ILLEGAL, + ILLEGAL, + opBA_w_a32, + opBTC_w_r_a32, + opBSF_w_a32, + opBSR_w_a32, + opMOVSX_w_b_a32, + ILLEGAL, + + /*c0*/ opXADD_b_a32, + opXADD_w_a32, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + opCMPXCHG8B_a32, + opBSWAP_EAX, + opBSWAP_ECX, + opBSWAP_EDX, + opBSWAP_EBX, + opBSWAP_ESP, + opBSWAP_EBP, + opBSWAP_ESI, + opBSWAP_EDI, + /*d0*/ ILLEGAL, + opPSRLW_a32, + opPSRLD_a32, + opPSRLQ_a32, + ILLEGAL, + opPMULLW_a32, + ILLEGAL, + ILLEGAL, + opPSUBUSB_a32, + opPSUBUSW_a32, + NULL, + opPAND_a32, + opPADDUSB_a32, + opPADDUSW_a32, + NULL, + opPANDN_a32, + /*e0*/ ILLEGAL, + opPSRAW_a32, + opPSRAD_a32, + ILLEGAL, + ILLEGAL, + opPMULHW_a32, + ILLEGAL, + ILLEGAL, + opPSUBSB_a32, + opPSUBSW_a32, + NULL, + opPOR_a32, + opPADDSB_a32, + opPADDSW_a32, + NULL, + opPXOR_a32, + /*f0*/ ILLEGAL, + opPSLLW_a32, + opPSLLD_a32, + opPSLLQ_a32, + ILLEGAL, + opPMADDWD_a32, + ILLEGAL, + ILLEGAL, + opPSUBB_a32, + opPSUBW_a32, + opPSUBD_a32, + ILLEGAL, + opPADDB_a32, + opPADDW_a32, + opPADDD_a32, + ILLEGAL, + + /*32-bit data, 32-bit addr*/ + /* 00 01 02 03 04 05 06 07 + 08 09 0a 0b 0c 0d 0e 0f*/ + /*00*/ op0F00_a32, + op0F01_l_a32, + opLAR_l_a32, + opLSL_l_a32, + ILLEGAL, + 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, + opRDSHR_a32, + opWRSHR_a32, + 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, + opSVDC_a16, + opRSDC_a16, + opSVLDT_a16, + opRSLDT_a16, + opSVTS_a16, + opRSTS_a16, + opMOVD_mm_l_a32_cx, + opMOVQ_mm_q_a32, + + /*80*/ opJO_l, + opJNO_l, + opJB_l, + opJNB_l, + opJE_l, + opJNE_l, + opJBE_l, + opJNBE_l, + opJS_l, + opJNS_l, + opJP_l, + opJNP_l, + opJL_l, + opJNL_l, + opJLE_l, + opJNLE_l, + /*90*/ opSETO_a32, + opSETNO_a32, + opSETB_a32, + opSETNB_a32, + opSETE_a32, + opSETNE_a32, + opSETBE_a32, + opSETNBE_a32, + opSETS_a32, + opSETNS_a32, + opSETP_a32, + opSETNP_a32, + opSETL_a32, + opSETNL_a32, + opSETLE_a32, + opSETNLE_a32, + /*a0*/ opPUSH_FS_l, + opPOP_FS_l, + opCPUID, + opBT_l_r_a32, + opSHLD_l_i_a32, + opSHLD_l_CL_a32, + ILLEGAL, + ILLEGAL, + opPUSH_GS_l, + opPOP_GS_l, + opRSM, + opBTS_l_r_a32, + opSHRD_l_i_a32, + opSHRD_l_CL_a32, + ILLEGAL, + opIMUL_l_l_a32, + /*b0*/ opCMPXCHG_b_a32, + opCMPXCHG_l_a32, + opLSS_l_a32, + opBTR_l_r_a32, + opLFS_l_a32, + opLGS_l_a32, + opMOVZX_l_b_a32, + opMOVZX_l_w_a32, + ILLEGAL, + ILLEGAL, + opBA_l_a32, + opBTC_l_r_a32, + opBSF_l_a32, + opBSR_l_a32, + opMOVSX_l_b_a32, + opMOVSX_l_w_a32, + + /*c0*/ opXADD_b_a32, + opXADD_l_a32, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + opCMPXCHG8B_a32, + opBSWAP_EAX, + opBSWAP_ECX, + opBSWAP_EDX, + opBSWAP_EBX, + opBSWAP_ESP, + opBSWAP_EBP, + opBSWAP_ESI, + opBSWAP_EDI, + /*d0*/ ILLEGAL, + opPSRLW_a32, + opPSRLD_a32, + opPSRLQ_a32, + ILLEGAL, + opPMULLW_a32, + ILLEGAL, + ILLEGAL, + opPSUBUSB_a32, + opPSUBUSW_a32, + NULL, + opPAND_a32, + opPADDUSB_a32, + opPADDUSW_a32, + NULL, + opPANDN_a32, + /*e0*/ ILLEGAL, + opPSRAW_a32, + opPSRAD_a32, + ILLEGAL, + ILLEGAL, + opPMULHW_a32, + ILLEGAL, + ILLEGAL, + opPSUBSB_a32, + opPSUBSW_a32, + NULL, + opPOR_a32, + opPADDSB_a32, + opPADDSW_a32, + NULL, + opPXOR_a32, + /*f0*/ ILLEGAL, + opPSLLW_a32, + opPSLLD_a32, + opPSLLQ_a32, + ILLEGAL, + opPMADDWD_a32, + ILLEGAL, + ILLEGAL, + opPSUBB_a32, + opPSUBW_a32, + opPSUBD_a32, + ILLEGAL, + opPADDB_a32, + opPADDW_a32, + opPADDD_a32, + ILLEGAL, +}; + +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, + ILLEGAL, + ILLEGAL, + ILLEGAL, + /*10*/ ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + opHINTNOP_a16, + opHINTNOP_a16, + opHINTNOP_a16, + opHINTNOP_a16, + opHINTNOP_a16, + opHINTNOP_a16, + opHINTNOP_a16, + opHINTNOP_a16, + /*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, + 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*/ 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, + opRSM, + opBTS_w_r_a16, + opSHRD_w_i_a16, + opSHRD_w_CL_a16, + ILLEGAL, + opIMUL_w_w_a16, + /*b0*/ opCMPXCHG_b_a16, + opCMPXCHG_w_a16, + opLSS_w_a16, + opBTR_w_r_a16, + opLFS_w_a16, + opLGS_w_a16, + opMOVZX_w_b_a16, + opMOVZX_w_w_a16, + ILLEGAL, + ILLEGAL, + opBA_w_a16, + opBTC_w_r_a16, + opBSF_w_a16, + opBSR_w_a16, + opMOVSX_w_b_a16, + ILLEGAL, + + /*c0*/ opXADD_b_a16, + opXADD_w_a16, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + opCMPXCHG8B_a16, + opBSWAP_EAX, + opBSWAP_ECX, + opBSWAP_EDX, + opBSWAP_EBX, + opBSWAP_ESP, + opBSWAP_EBP, + opBSWAP_ESI, + opBSWAP_EDI, + /*d0*/ ILLEGAL, + 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, + opHINTNOP_a16, + opHINTNOP_a16, + opHINTNOP_a16, + opHINTNOP_a16, + opHINTNOP_a16, + opHINTNOP_a16, + opHINTNOP_a16, + opHINTNOP_a16, + /*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, + 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*/ 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, + opRSM, + opBTS_l_r_a16, + opSHRD_l_i_a16, + opSHRD_l_CL_a16, + ILLEGAL, + opIMUL_l_l_a16, + /*b0*/ opCMPXCHG_b_a16, + opCMPXCHG_l_a16, + opLSS_l_a16, + opBTR_l_r_a16, + opLFS_l_a16, + opLGS_l_a16, + opMOVZX_l_b_a16, + opMOVZX_l_w_a16, + ILLEGAL, + ILLEGAL, + opBA_l_a16, + opBTC_l_r_a16, + opBSF_l_a16, + opBSR_l_a16, + opMOVSX_l_b_a16, + opMOVSX_l_w_a16, + + /*c0*/ opXADD_b_a16, + opXADD_l_a16, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + opCMPXCHG8B_a16, + opBSWAP_EAX, + opBSWAP_ECX, + opBSWAP_EDX, + opBSWAP_EBX, + opBSWAP_ESP, + opBSWAP_EBP, + opBSWAP_ESI, + opBSWAP_EDI, + /*d0*/ ILLEGAL, + 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, + opHINTNOP_a32, + opHINTNOP_a32, + opHINTNOP_a32, + opHINTNOP_a32, + opHINTNOP_a32, + opHINTNOP_a32, + opHINTNOP_a32, + opHINTNOP_a32, + /*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, + 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*/ 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, + opRSM, + opBTS_w_r_a32, + opSHRD_w_i_a32, + opSHRD_w_CL_a32, + ILLEGAL, + opIMUL_w_w_a32, + /*b0*/ opCMPXCHG_b_a32, + opCMPXCHG_w_a32, + opLSS_w_a32, + opBTR_w_r_a32, + opLFS_w_a32, + opLGS_w_a32, + opMOVZX_w_b_a32, + opMOVZX_w_w_a32, + ILLEGAL, + ILLEGAL, + opBA_w_a32, + opBTC_w_r_a32, + opBSF_w_a32, + opBSR_w_a32, + opMOVSX_w_b_a32, + ILLEGAL, + + /*c0*/ opXADD_b_a32, + opXADD_w_a32, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + opCMPXCHG8B_a32, + opBSWAP_EAX, + opBSWAP_ECX, + opBSWAP_EDX, + opBSWAP_EBX, + opBSWAP_ESP, + opBSWAP_EBP, + opBSWAP_ESI, + opBSWAP_EDI, + /*d0*/ ILLEGAL, + 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, + opHINTNOP_a32, + opHINTNOP_a32, + opHINTNOP_a32, + opHINTNOP_a32, + opHINTNOP_a32, + opHINTNOP_a32, + opHINTNOP_a32, + opHINTNOP_a32, + /*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, + 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*/ 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, + opRSM, + opBTS_l_r_a32, + opSHRD_l_i_a32, + opSHRD_l_CL_a32, + ILLEGAL, + opIMUL_l_l_a32, + /*b0*/ opCMPXCHG_b_a32, + opCMPXCHG_l_a32, + opLSS_l_a32, + opBTR_l_r_a32, + opLFS_l_a32, + opLGS_l_a32, + opMOVZX_l_b_a32, + opMOVZX_l_w_a32, + ILLEGAL, + ILLEGAL, + opBA_l_a32, + opBTC_l_r_a32, + opBSF_l_a32, + opBSR_l_a32, + opMOVSX_l_b_a32, + opMOVSX_l_w_a32, + + /*c0*/ opXADD_b_a32, + opXADD_l_a32, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + opCMPXCHG8B_a32, + opBSWAP_EAX, + opBSWAP_ECX, + opBSWAP_EDX, + opBSWAP_EBX, + opBSWAP_ESP, + opBSWAP_EBP, + opBSWAP_ESI, + opBSWAP_EDI, + /*d0*/ ILLEGAL, + 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, +}; + +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, + ILLEGAL, + ILLEGAL, + ILLEGAL, + /*10*/ ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + opHINTNOP_a16, + opHINTNOP_a16, + opHINTNOP_a16, + opHINTNOP_a16, + opHINTNOP_a16, + opHINTNOP_a16, + opHINTNOP_a16, + opHINTNOP_a16, + /*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, + opRSM, + opBTS_w_r_a16, + opSHRD_w_i_a16, + opSHRD_w_CL_a16, + ILLEGAL, + opIMUL_w_w_a16, + /*b0*/ opCMPXCHG_b_a16, + opCMPXCHG_w_a16, + opLSS_w_a16, + opBTR_w_r_a16, + opLFS_w_a16, + opLGS_w_a16, + opMOVZX_w_b_a16, + opMOVZX_w_w_a16, + ILLEGAL, + ILLEGAL, + opBA_w_a16, + opBTC_w_r_a16, + opBSF_w_a16, + opBSR_w_a16, + opMOVSX_w_b_a16, + ILLEGAL, + + /*c0*/ opXADD_b_a16, + opXADD_w_a16, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + opCMPXCHG8B_a16, + opBSWAP_EAX, + opBSWAP_ECX, + opBSWAP_EDX, + opBSWAP_EBX, + opBSWAP_ESP, + opBSWAP_EBP, + opBSWAP_ESI, + opBSWAP_EDI, + /*d0*/ ILLEGAL, + opPSRLW_a16, + opPSRLD_a16, + opPSRLQ_a16, + ILLEGAL, + opPMULLW_a16, + ILLEGAL, + ILLEGAL, + opPSUBUSB_a16, + opPSUBUSW_a16, + NULL, + opPAND_a16, + opPADDUSB_a16, + opPADDUSW_a16, + NULL, + opPANDN_a16, + /*e0*/ ILLEGAL, + opPSRAW_a16, + opPSRAD_a16, + ILLEGAL, + ILLEGAL, + opPMULHW_a16, + ILLEGAL, + ILLEGAL, + opPSUBSB_a16, + opPSUBSW_a16, + NULL, + opPOR_a16, + opPADDSB_a16, + opPADDSW_a16, + NULL, + opPXOR_a16, + /*f0*/ ILLEGAL, + opPSLLW_a16, + opPSLLD_a16, + opPSLLQ_a16, + ILLEGAL, + opPMADDWD_a16, + ILLEGAL, + ILLEGAL, + opPSUBB_a16, + opPSUBW_a16, + opPSUBD_a16, + ILLEGAL, + opPADDB_a16, + opPADDW_a16, + opPADDD_a16, + ILLEGAL, + + /*32-bit data, 16-bit addr*/ + /* 00 01 02 03 04 05 06 07 + 08 09 0a 0b 0c 0d 0e 0f*/ + /*00*/ op0F00_a16, + op0F01_l_a16, + opLAR_l_a16, + opLSL_l_a16, + ILLEGAL, + ILLEGAL, + opCLTS, + ILLEGAL, + opINVD, + opWBINVD, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + /*10*/ ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + opHINTNOP_a16, + opHINTNOP_a16, + opHINTNOP_a16, + opHINTNOP_a16, + opHINTNOP_a16, + opHINTNOP_a16, + opHINTNOP_a16, + opHINTNOP_a16, + /*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, + opRSM, + opBTS_l_r_a16, + opSHRD_l_i_a16, + opSHRD_l_CL_a16, + ILLEGAL, + opIMUL_l_l_a16, + /*b0*/ opCMPXCHG_b_a16, + opCMPXCHG_l_a16, + opLSS_l_a16, + opBTR_l_r_a16, + opLFS_l_a16, + opLGS_l_a16, + opMOVZX_l_b_a16, + opMOVZX_l_w_a16, + ILLEGAL, + ILLEGAL, + opBA_l_a16, + opBTC_l_r_a16, + opBSF_l_a16, + opBSR_l_a16, + opMOVSX_l_b_a16, + opMOVSX_l_w_a16, + + /*c0*/ opXADD_b_a16, + opXADD_l_a16, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + opCMPXCHG8B_a16, + opBSWAP_EAX, + opBSWAP_ECX, + opBSWAP_EDX, + opBSWAP_EBX, + opBSWAP_ESP, + opBSWAP_EBP, + opBSWAP_ESI, + opBSWAP_EDI, + /*d0*/ ILLEGAL, + opPSRLW_a16, + opPSRLD_a16, + opPSRLQ_a16, + ILLEGAL, + opPMULLW_a16, + ILLEGAL, + ILLEGAL, + opPSUBUSB_a16, + opPSUBUSW_a16, + NULL, + opPAND_a16, + opPADDUSB_a16, + opPADDUSW_a16, + NULL, + opPANDN_a16, + /*e0*/ ILLEGAL, + opPSRAW_a16, + opPSRAD_a16, + ILLEGAL, + ILLEGAL, + opPMULHW_a16, + ILLEGAL, + ILLEGAL, + opPSUBSB_a16, + opPSUBSW_a16, + NULL, + opPOR_a16, + opPADDSB_a16, + opPADDSW_a16, + NULL, + opPXOR_a16, + /*f0*/ ILLEGAL, + opPSLLW_a16, + opPSLLD_a16, + opPSLLQ_a16, + ILLEGAL, + opPMADDWD_a16, + ILLEGAL, + ILLEGAL, + opPSUBB_a16, + opPSUBW_a16, + opPSUBD_a16, + ILLEGAL, + opPADDB_a16, + opPADDW_a16, + opPADDD_a16, + ILLEGAL, + + /*16-bit data, 32-bit addr*/ + /* 00 01 02 03 04 05 06 07 + 08 09 0a 0b 0c 0d 0e 0f*/ + /*00*/ op0F00_a32, + op0F01_w_a32, + opLAR_w_a32, + opLSL_w_a32, + ILLEGAL, + ILLEGAL, + opCLTS, + ILLEGAL, + opINVD, + opWBINVD, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + /*10*/ ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + opHINTNOP_a32, + opHINTNOP_a32, + opHINTNOP_a32, + opHINTNOP_a32, + opHINTNOP_a32, + opHINTNOP_a32, + opHINTNOP_a32, + opHINTNOP_a32, + /*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, + opRSM, + opBTS_w_r_a32, + opSHRD_w_i_a32, + opSHRD_w_CL_a32, + ILLEGAL, + opIMUL_w_w_a32, + /*b0*/ opCMPXCHG_b_a32, + opCMPXCHG_w_a32, + opLSS_w_a32, + opBTR_w_r_a32, + opLFS_w_a32, + opLGS_w_a32, + opMOVZX_w_b_a32, + opMOVZX_w_w_a32, + ILLEGAL, + ILLEGAL, + opBA_w_a32, + opBTC_w_r_a32, + opBSF_w_a32, + opBSR_w_a32, + opMOVSX_w_b_a32, + ILLEGAL, + + /*c0*/ opXADD_b_a32, + opXADD_w_a32, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + opCMPXCHG8B_a32, + opBSWAP_EAX, + opBSWAP_ECX, + opBSWAP_EDX, + opBSWAP_EBX, + opBSWAP_ESP, + opBSWAP_EBP, + opBSWAP_ESI, + opBSWAP_EDI, + /*d0*/ ILLEGAL, + opPSRLW_a32, + opPSRLD_a32, + opPSRLQ_a32, + ILLEGAL, + opPMULLW_a32, + ILLEGAL, + ILLEGAL, + opPSUBUSB_a32, + opPSUBUSW_a32, + NULL, + opPAND_a32, + opPADDUSB_a32, + opPADDUSW_a32, + NULL, + opPANDN_a32, + /*e0*/ ILLEGAL, + opPSRAW_a32, + opPSRAD_a32, + ILLEGAL, + ILLEGAL, + opPMULHW_a32, + ILLEGAL, + ILLEGAL, + opPSUBSB_a32, + opPSUBSW_a32, + NULL, + opPOR_a32, + opPADDSB_a32, + opPADDSW_a32, + NULL, + opPXOR_a32, + /*f0*/ ILLEGAL, + opPSLLW_a32, + opPSLLD_a32, + opPSLLQ_a32, + ILLEGAL, + opPMADDWD_a32, + ILLEGAL, + ILLEGAL, + opPSUBB_a32, + opPSUBW_a32, + opPSUBD_a32, + ILLEGAL, + opPADDB_a32, + opPADDW_a32, + opPADDD_a32, + ILLEGAL, + + /*32-bit data, 32-bit addr*/ + /* 00 01 02 03 04 05 06 07 + 08 09 0a 0b 0c 0d 0e 0f*/ + /*00*/ op0F00_a32, + op0F01_l_a32, + opLAR_l_a32, + opLSL_l_a32, + ILLEGAL, + ILLEGAL, + opCLTS, + ILLEGAL, + opINVD, + opWBINVD, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + /*10*/ ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + opHINTNOP_a32, + opHINTNOP_a32, + opHINTNOP_a32, + opHINTNOP_a32, + opHINTNOP_a32, + opHINTNOP_a32, + opHINTNOP_a32, + opHINTNOP_a32, + /*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, + opRSM, + opBTS_l_r_a32, + opSHRD_l_i_a32, + opSHRD_l_CL_a32, + ILLEGAL, + opIMUL_l_l_a32, + /*b0*/ opCMPXCHG_b_a32, + opCMPXCHG_l_a32, + opLSS_l_a32, + opBTR_l_r_a32, + opLFS_l_a32, + opLGS_l_a32, + opMOVZX_l_b_a32, + opMOVZX_l_w_a32, + ILLEGAL, + ILLEGAL, + opBA_l_a32, + opBTC_l_r_a32, + opBSF_l_a32, + opBSR_l_a32, + opMOVSX_l_b_a32, + opMOVSX_l_w_a32, + + /*c0*/ opXADD_b_a32, + opXADD_l_a32, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + ILLEGAL, + opCMPXCHG8B_a32, + opBSWAP_EAX, + opBSWAP_ECX, + opBSWAP_EDX, + opBSWAP_EBX, + opBSWAP_ESP, + opBSWAP_EBP, + opBSWAP_ESI, + opBSWAP_EDI, + /*d0*/ ILLEGAL, + opPSRLW_a32, + opPSRLD_a32, + opPSRLQ_a32, + ILLEGAL, + opPMULLW_a32, + ILLEGAL, + ILLEGAL, + opPSUBUSB_a32, + opPSUBUSW_a32, + NULL, + opPAND_a32, + opPADDUSB_a32, + opPADDUSW_a32, + NULL, + opPANDN_a32, + /*e0*/ ILLEGAL, + opPSRAW_a32, + opPSRAD_a32, + ILLEGAL, + ILLEGAL, + opPMULHW_a32, + ILLEGAL, + ILLEGAL, + opPSUBSB_a32, + opPSUBSW_a32, + NULL, + opPOR_a32, + opPADDSB_a32, + opPADDSW_a32, + NULL, + opPXOR_a32, + /*f0*/ ILLEGAL, + opPSLLW_a32, + opPSLLD_a32, + opPSLLQ_a32, + ILLEGAL, + opPMADDWD_a32, + ILLEGAL, + ILLEGAL, + opPSUBB_a32, + opPSUBW_a32, + opPSUBD_a32, + ILLEGAL, + opPADDB_a32, + opPADDW_a32, + opPADDD_a32, + ILLEGAL, +}; + +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, +}; + +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, +}; + +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, +}; + +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, +}; #include "x87_ops.h" diff --git a/includes/private/cpu/8087.h b/includes/private/cpu/8087.h index 06f60633..2dd1ccc7 100644 --- a/includes/private/cpu/8087.h +++ b/includes/private/cpu/8087.h @@ -4,7 +4,7 @@ /*This file is a series of macros to get the 386+ based x87 emulation working with the 808x emulation*/ #define X8087 -#define OP_TABLE(name) ops_808x_ ## name +#define OP_TABLE(name) ops_808x_##name #define CLOCK_CYCLES(c) cycles -= (c) #define CLOCK_CYCLES_ALWAYS(c) cycles -= (c) @@ -16,50 +16,45 @@ #define CHECK_WRITE(seg, addr_lo, addr_hi) #define PREFETCH_RUN(timing, bytes, rmdat, a, b, c, d, e) -static uint32_t readmeml(uint32_t seg, uint32_t addr) { - return readmemw(seg, addr) | (readmemw(seg, addr + 2) << 16); -} +static uint32_t readmeml(uint32_t seg, uint32_t addr) { return readmemw(seg, addr) | (readmemw(seg, addr + 2) << 16); } static uint64_t readmemq(uint32_t seg, uint32_t addr) { - return (uint64_t)readmemw(seg, addr) | ((uint64_t)readmemw(seg, addr + 2) << 16) | - ((uint64_t)readmemw(seg, addr + 4) << 32) | - ((uint64_t)readmemw(seg, addr + 6) << 48); + return (uint64_t)readmemw(seg, addr) | ((uint64_t)readmemw(seg, addr + 2) << 16) | + ((uint64_t)readmemw(seg, addr + 4) << 32) | ((uint64_t)readmemw(seg, addr + 6) << 48); } -static void writememb_8087(uint32_t seg, uint32_t addr, uint8_t val) { - writememb(seg + addr, val); -} +static void writememb_8087(uint32_t seg, uint32_t addr, uint8_t val) { writememb(seg + addr, val); } static void writememl(uint32_t seg, uint32_t addr, uint32_t val) { - writememw(seg, addr, val & 0xffff); - writememw(seg, addr + 2, (val >> 16) & 0xffff); + writememw(seg, addr, val & 0xffff); + writememw(seg, addr + 2, (val >> 16) & 0xffff); } static void writememq(uint32_t seg, uint32_t addr, uint64_t val) { - writememw(seg, addr, val & 0xffff); - writememw(seg, addr + 2, (val >> 16) & 0xffff); - writememw(seg, addr + 4, (val >> 32) & 0xffff); - writememw(seg, addr + 6, (val >> 48) & 0xffff); + writememw(seg, addr, val & 0xffff); + writememw(seg, addr + 2, (val >> 16) & 0xffff); + writememw(seg, addr + 4, (val >> 32) & 0xffff); + writememw(seg, addr + 6, (val >> 48) & 0xffff); } static inline uint32_t geteal() { - if (cpu_mod == 3) - fatal("geteal cpu_mod==3\n"); - return readmeml(easeg, cpu_state.eaaddr); + if (cpu_mod == 3) + fatal("geteal cpu_mod==3\n"); + return readmeml(easeg, cpu_state.eaaddr); } static inline uint64_t geteaq() { - if (cpu_mod == 3) - fatal("geteaq cpu_mod==3\n"); - return readmemq(easeg, cpu_state.eaaddr); + if (cpu_mod == 3) + fatal("geteaq cpu_mod==3\n"); + return readmemq(easeg, cpu_state.eaaddr); } static inline void seteal(uint32_t val) { - if (cpu_mod == 3) - fatal("seteal cpu_mod==3\n"); - else - writememl(easeg, cpu_state.eaaddr, val); + if (cpu_mod == 3) + fatal("seteal cpu_mod==3\n"); + else + writememl(easeg, cpu_state.eaaddr, val); } static inline void seteaq(uint64_t val) { - if (cpu_mod == 3) - fatal("seteaq cpu_mod==3\n"); - else - writememq(easeg, cpu_state.eaaddr, val); + if (cpu_mod == 3) + fatal("seteaq cpu_mod==3\n"); + else + writememq(easeg, cpu_state.eaaddr, val); } #define flags_rebuild() @@ -70,21 +65,21 @@ static inline void seteaq(uint64_t val) { #define VF_SET() (cpu_state.flags & V_FLAG) #define ZF_SET() (cpu_state.flags & Z_FLAG) -#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_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_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 writememb writememb_8087 diff --git a/includes/private/cpu/cpu.h b/includes/private/cpu/cpu.h index e84e2194..5c5035a2 100644 --- a/includes/private/cpu/cpu.h +++ b/includes/private/cpu/cpu.h @@ -14,46 +14,46 @@ extern int fpu_type; #define CPU_286 2 /*386 class CPUs*/ -#define CPU_386SX 3 -#define CPU_386DX 4 +#define CPU_386SX 3 +#define CPU_386DX 4 #define CPU_486SLC 5 #define CPU_486DLC 6 /*486 class CPUs*/ -#define CPU_i486SX 7 +#define CPU_i486SX 7 #define CPU_Am486SX 8 -#define CPU_Cx486S 9 -#define CPU_i486DX 10 +#define CPU_Cx486S 9 +#define CPU_i486DX 10 #define CPU_Am486DX 11 #define CPU_Cx486DX 12 -#define CPU_iDX4 13 -#define CPU_Cx5x86 14 +#define CPU_iDX4 13 +#define CPU_Cx5x86 14 /*586 class CPUs*/ #define CPU_WINCHIP 15 #define CPU_WINCHIP2 16 #define CPU_PENTIUM 17 #define CPU_PENTIUMMMX 18 -#define CPU_Cx6x86 19 -#define CPU_Cx6x86MX 20 -#define CPU_Cx6x86L 21 -#define CPU_CxGX1 22 -#define CPU_K6 23 -#define CPU_K6_2 24 -#define CPU_K6_3 25 -#define CPU_K6_2P 26 -#define CPU_K6_3P 27 -#define CPU_PENTIUMPRO 28 -#define CPU_PENTIUM_2 29 -#define CPU_CELERON 30 -#define CPU_CELERON_A 31 -#define CPU_CYRIX_III 32 +#define CPU_Cx6x86 19 +#define CPU_Cx6x86MX 20 +#define CPU_Cx6x86L 21 +#define CPU_CxGX1 22 +#define CPU_K6 23 +#define CPU_K6_2 24 +#define CPU_K6_3 25 +#define CPU_K6_2P 26 +#define CPU_K6_3P 27 +#define CPU_PENTIUMPRO 28 +#define CPU_PENTIUM_2 29 +#define CPU_CELERON 30 +#define CPU_CELERON_A 31 +#define CPU_CYRIX_III 32 #define MANU_INTEL 0 -#define MANU_AMD 1 +#define MANU_AMD 1 #define MANU_CYRIX 2 -#define MANU_IDT 3 -#define MANU_VIA 4 +#define MANU_IDT 3 +#define MANU_VIA 4 extern int timing_rr; extern int timing_mr, timing_mrl; @@ -69,14 +69,7 @@ extern int timing_jmp_rm, timing_jmp_pm, timing_jmp_pm_gate; extern int timing_misaligned; -enum { - FPU_NONE, - FPU_8087, - FPU_287, - FPU_287XL, - FPU_387, - FPU_BUILTIN -}; +enum { FPU_NONE, FPU_8087, FPU_287, FPU_287XL, FPU_387, FPU_BUILTIN }; extern CPU *cpu_s; @@ -122,24 +115,22 @@ extern int cpu_multi; /*Cyrix 5x86/6x86 only has data misalignment penalties when crossing 8-byte boundaries*/ extern int cpu_cyrix_alignment; -#define CPU_FEATURE_RDTSC (1 << 0) -#define CPU_FEATURE_MSR (1 << 1) -#define CPU_FEATURE_MMX (1 << 2) -#define CPU_FEATURE_CR4 (1 << 3) -#define CPU_FEATURE_VME (1 << 4) -#define CPU_FEATURE_CX8 (1 << 5) -#define CPU_FEATURE_3DNOW (1 << 6) +#define CPU_FEATURE_RDTSC (1 << 0) +#define CPU_FEATURE_MSR (1 << 1) +#define CPU_FEATURE_MMX (1 << 2) +#define CPU_FEATURE_CR4 (1 << 3) +#define CPU_FEATURE_VME (1 << 4) +#define CPU_FEATURE_CX8 (1 << 5) +#define CPU_FEATURE_3DNOW (1 << 6) #define CPU_FEATURE_SYSCALL (1 << 7) extern uint32_t cpu_features; -static inline int cpu_has_feature(int feature) { - return cpu_features & feature; -} +static inline int cpu_has_feature(int feature) { return cpu_features & feature; } -#define CR4_TSD (1 << 2) -#define CR4_DE (1 << 3) -#define CR4_MCE (1 << 6) -#define CR4_PCE (1 << 8) +#define CR4_TSD (1 << 2) +#define CR4_DE (1 << 3) +#define CR4_MCE (1 << 6) +#define CR4_PCE (1 << 8) extern uint64_t cpu_CR4_mask; diff --git a/includes/private/cpu/x86.h b/includes/private/cpu/x86.h index 6002eef4..789dfd26 100644 --- a/includes/private/cpu/x86.h +++ b/includes/private/cpu/x86.h @@ -27,92 +27,92 @@ #define BH cpu_state.regs[3].b.h typedef union { - uint32_t l; - uint16_t w; - struct { - uint8_t l, h; - } b; + uint32_t l; + uint16_t w; + struct { + uint8_t l, h; + } b; } x86reg; typedef struct { - uint32_t base; - uint32_t limit, limit_raw; - uint8_t access, access2; - uint16_t seg; - uint32_t limit_low, limit_high; - int checked; /*Non-zero if selector is known to be valid*/ + uint32_t base; + uint32_t limit, limit_raw; + uint8_t access, access2; + uint16_t seg; + uint32_t limit_low, limit_high; + int checked; /*Non-zero if selector is known to be valid*/ } x86seg; typedef union MMX_REG { - 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]; - float f[2]; + 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]; + float f[2]; } MMX_REG; struct { - x86reg regs[8]; + x86reg regs[8]; - uint8_t tag[8]; + uint8_t tag[8]; - x86seg *ea_seg; - uint32_t eaaddr; + x86seg *ea_seg; + uint32_t eaaddr; - int flags_op; - uint32_t flags_res; - uint32_t flags_op1, flags_op2; + int flags_op; + uint32_t flags_res; + uint32_t flags_op1, flags_op2; - uint32_t pc; - uint32_t oldpc; - uint32_t op32; + uint32_t pc; + uint32_t oldpc; + uint32_t op32; - int TOP; + int TOP; - union { - struct { - int8_t rm, mod, reg; - } rm_mod_reg; - uint32_t rm_mod_reg_data; - } rm_data; + union { + struct { + int8_t rm, mod, reg; + } rm_mod_reg; + uint32_t rm_mod_reg_data; + } rm_data; - int8_t ssegs; - int8_t ismmx; - int8_t abrt; - int8_t smi_pending; + int8_t ssegs; + int8_t ismmx; + int8_t abrt; + int8_t smi_pending; - int _cycles; - int cpu_recomp_ins; + int _cycles; + int cpu_recomp_ins; - uint16_t npxs, npxc; + uint16_t npxs, npxc; - double ST[8]; + double ST[8]; - uint16_t MM_w4[8]; + uint16_t MM_w4[8]; - MMX_REG MM[8]; + MMX_REG MM[8]; - uint32_t old_fp_control, new_fp_control; + uint32_t old_fp_control, new_fp_control; #if defined i386 || defined __i386 || defined __i386__ || defined _X86_ - uint16_t old_fp_control2, new_fp_control2; + uint16_t old_fp_control2, new_fp_control2; #endif #if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined __amd64__ - uint32_t trunc_fp_control; + uint32_t trunc_fp_control; #endif - x86seg seg_cs, seg_ds, seg_es, seg_ss, seg_fs, seg_gs; + x86seg seg_cs, seg_ds, seg_es, seg_ss, seg_fs, seg_gs; - union { - uint32_t l; - uint16_t w; - } CR0; + union { + uint32_t l; + uint16_t w; + } CR0; - uint16_t flags, eflags; + uint16_t flags, eflags; - uint32_t smbase; + uint32_t smbase; } cpu_state; #define cpu_state_offset(MEMBER) ((uintptr_t)&cpu_state.MEMBER - (uintptr_t)&cpu_state - 128) @@ -140,19 +140,19 @@ extern int cycles_main; //#define seg_fs _fs.base #define gs cpu_state.seg_gs.base -#define CPL ((cpu_state.seg_cs.access>>5)&3) +#define CPL ((cpu_state.seg_cs.access >> 5) & 3) -#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 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 VM_FLAG 0x0002 /*In EFLAGS*/ #define VIF_FLAG 0x0008 /*In EFLAGS*/ #define VIP_FLAG 0x0010 /*In EFLAGS*/ @@ -164,7 +164,7 @@ extern int cycles_main; #define IOPL ((cpu_state.flags >> 12) & 3) -#define IOPLp ((!(msw&1)) || (CPL<=IOPL)) +#define IOPLp ((!(msw & 1)) || (CPL <= IOPL)) extern x86seg gdt, ldt, idt, tr; @@ -178,17 +178,17 @@ extern uint16_t cpu_cur_status; /*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_USE32 (1 << 0) #define CPU_STATUS_STACK32 (1 << 1) -#define CPU_STATUS_PMODE (1 << 2) -#define CPU_STATUS_V86 (1 << 3) -#define CPU_STATUS_SMM (1 << 4) +#define CPU_STATUS_PMODE (1 << 2) +#define CPU_STATUS_V86 (1 << 3) +#define CPU_STATUS_SMM (1 << 4) #define CPU_STATUS_FLAGS 0xff /*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 << 8) -#define CPU_STATUS_NOTFLATSS (1 << 9) +#define CPU_STATUS_NOTFLATDS (1 << 8) +#define CPU_STATUS_NOTFLATSS (1 << 9) #define CPU_STATUS_MASK 0xff00 extern uint32_t rmdat; @@ -222,20 +222,28 @@ extern float mips, flops; #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 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 +#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 -#define fetchea() { rmdat=readmemb(cs+pc); pc++; \ - reg=(rmdat>>3)&7; \ - mod=(rmdat>>6)&3; \ - rm=rmdat&7; \ - if (mod!=3) fetcheal(); } +#define fetchea() \ + { \ + rmdat = readmemb(cs + pc); \ + pc++; \ + reg = (rmdat >> 3) & 7; \ + mod = (rmdat >> 6) & 3; \ + rm = rmdat & 7; \ + if (mod != 3) \ + fetcheal(); \ + } extern int optype; #define JMP 1 @@ -243,26 +251,18 @@ extern int optype; #define IRET 3 #define OPTYPE_INT 4 -enum { - ABRT_NONE = 0, - ABRT_GEN, - ABRT_TS = 0xA, - ABRT_NP = 0xB, - ABRT_SS = 0xC, - ABRT_GPF = 0xD, - ABRT_PF = 0xE -}; +enum { ABRT_NONE = 0, ABRT_GEN, ABRT_TS = 0xA, ABRT_NP = 0xB, ABRT_SS = 0xC, ABRT_GPF = 0xD, ABRT_PF = 0xE }; #define ABRT_MASK 0x7f /*An 'expected' exception is one that would be expected to occur on every execution of this code path; eg a GPF due to being in v86 mode. An 'unexpected' exception is one that would be unlikely to occur on the next exception, eg a page fault may be fixed up by the exception handler and the next execution would not hit it. - + This distinction is used by the dynarec; a block that hits an 'expected' exception would be compiled, a block that hits an 'unexpected' exception would be rejected so that we don't end up with an unnecessarily short block*/ -#define ABRT_EXPECTED 0x80 +#define ABRT_EXPECTED 0x80 extern uint32_t abrt_error; void x86_doabrt(int x86_abrt); @@ -319,11 +319,11 @@ void cyrix_write_seg_descriptor(uint32_t addr, x86seg *seg); #define SMHR_ADDR_MASK (0xfffffffc) struct { - struct { - uint32_t base; - uint64_t size; - } arr[8]; - uint32_t smhr; + struct { + uint32_t base; + uint64_t size; + } arr[8]; + uint32_t smhr; } cyrix; #endif /* _X86_H_ */ diff --git a/includes/private/cpu/x86_flags.h b/includes/private/cpu/x86_flags.h index 856f7551..ed89a8eb 100644 --- a/includes/private/cpu/x86_flags.h +++ b/includes/private/cpu/x86_flags.h @@ -3,356 +3,411 @@ extern int tempc; enum { - FLAGS_UNKNOWN, + FLAGS_UNKNOWN, - FLAGS_ZN8, - FLAGS_ZN16, - FLAGS_ZN32, + FLAGS_ZN8, + FLAGS_ZN16, + FLAGS_ZN32, - FLAGS_ADD8, - FLAGS_ADD16, - FLAGS_ADD32, + FLAGS_ADD8, + FLAGS_ADD16, + FLAGS_ADD32, - FLAGS_SUB8, - FLAGS_SUB16, - FLAGS_SUB32, + FLAGS_SUB8, + FLAGS_SUB16, + FLAGS_SUB32, - FLAGS_SHL8, - FLAGS_SHL16, - FLAGS_SHL32, + FLAGS_SHL8, + FLAGS_SHL16, + FLAGS_SHL32, - FLAGS_SHR8, - FLAGS_SHR16, - FLAGS_SHR32, + FLAGS_SHR8, + FLAGS_SHR16, + FLAGS_SHR32, - FLAGS_SAR8, - FLAGS_SAR16, - FLAGS_SAR32, + FLAGS_SAR8, + FLAGS_SAR16, + FLAGS_SAR32, - FLAGS_ROL8, - FLAGS_ROL16, - FLAGS_ROL32, + FLAGS_ROL8, + FLAGS_ROL16, + FLAGS_ROL32, - FLAGS_ROR8, - FLAGS_ROR16, - FLAGS_ROR32, + FLAGS_ROR8, + FLAGS_ROR16, + FLAGS_ROR32, - FLAGS_INC8, - FLAGS_INC16, - FLAGS_INC32, + FLAGS_INC8, + FLAGS_INC16, + FLAGS_INC32, - FLAGS_DEC8, - FLAGS_DEC16, - FLAGS_DEC32, + FLAGS_DEC8, + FLAGS_DEC16, + FLAGS_DEC32, - FLAGS_ADC8, - FLAGS_ADC16, - FLAGS_ADC32, + FLAGS_ADC8, + FLAGS_ADC16, + FLAGS_ADC32, - FLAGS_SBC8, - FLAGS_SBC16, - FLAGS_SBC32 + FLAGS_SBC8, + FLAGS_SBC16, + FLAGS_SBC32 }; 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: - case FLAGS_ADC8: - case FLAGS_ADC16: - case FLAGS_ADC32: - case FLAGS_SBC8: - case FLAGS_SBC16: - case FLAGS_SBC32:return !cpu_state.flags_res; + 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: + case FLAGS_ADC8: + case FLAGS_ADC16: + case FLAGS_ADC32: + case FLAGS_SBC8: + case FLAGS_SBC16: + case FLAGS_SBC32: + return !cpu_state.flags_res; - case FLAGS_ROL8: - case FLAGS_ROL16: - case FLAGS_ROL32: - case FLAGS_ROR8: - case FLAGS_ROR16: - case FLAGS_ROR32: - case FLAGS_UNKNOWN:return cpu_state.flags & Z_FLAG; - } - return 0; + case FLAGS_ROL8: + case FLAGS_ROL16: + case FLAGS_ROL32: + case FLAGS_ROR8: + case FLAGS_ROR16: + case FLAGS_ROR32: + case FLAGS_UNKNOWN: + return cpu_state.flags & Z_FLAG; + } + 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: - case FLAGS_ADC8: - case FLAGS_SBC8:return cpu_state.flags_res & 0x80; + 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: + case FLAGS_ADC8: + case FLAGS_SBC8: + 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: - case FLAGS_ADC16: - case FLAGS_SBC16:return cpu_state.flags_res & 0x8000; + case FLAGS_ZN16: + case FLAGS_ADD16: + case FLAGS_SUB16: + case FLAGS_SHL16: + case FLAGS_SHR16: + case FLAGS_SAR16: + case FLAGS_INC16: + case FLAGS_DEC16: + case FLAGS_ADC16: + case FLAGS_SBC16: + 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: - case FLAGS_ADC32: - case FLAGS_SBC32:return cpu_state.flags_res & 0x80000000; + case FLAGS_ZN32: + case FLAGS_ADD32: + case FLAGS_SUB32: + case FLAGS_SHL32: + case FLAGS_SHR32: + case FLAGS_SAR32: + case FLAGS_INC32: + case FLAGS_DEC32: + case FLAGS_ADC32: + case FLAGS_SBC32: + return cpu_state.flags_res & 0x80000000; - case FLAGS_ROL8: - case FLAGS_ROL16: - case FLAGS_ROL32: - case FLAGS_ROR8: - case FLAGS_ROR16: - case FLAGS_ROR32: - case FLAGS_UNKNOWN:return cpu_state.flags & N_FLAG; - } - return 0; + case FLAGS_ROL8: + case FLAGS_ROL16: + case FLAGS_ROL32: + case FLAGS_ROR8: + case FLAGS_ROR16: + case FLAGS_ROR32: + case FLAGS_UNKNOWN: + return cpu_state.flags & N_FLAG; + } + 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: - case FLAGS_ADC8: - case FLAGS_ADC16: - case FLAGS_ADC32: - case FLAGS_SBC8: - case FLAGS_SBC16: - case FLAGS_SBC32:return znptable8[cpu_state.flags_res & 0xff] & P_FLAG; + 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: + case FLAGS_ADC8: + case FLAGS_ADC16: + case FLAGS_ADC32: + case FLAGS_SBC8: + case FLAGS_SBC16: + case FLAGS_SBC32: + return znptable8[cpu_state.flags_res & 0xff] & P_FLAG; - case FLAGS_ROL8: - case FLAGS_ROL16: - case FLAGS_ROL32: - case FLAGS_ROR8: - case FLAGS_ROR16: - case FLAGS_ROR32: - case FLAGS_UNKNOWN:return cpu_state.flags & P_FLAG; - } - return 0; + case FLAGS_ROL8: + case FLAGS_ROL16: + case FLAGS_ROL32: + case FLAGS_ROR8: + case FLAGS_ROR16: + case FLAGS_ROR32: + case FLAGS_UNKNOWN: + return cpu_state.flags & P_FLAG; + } + 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; + 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_ADC8: - 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_ADC16: - 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_ADC32: - 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_ADC8: + 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_ADC16: + 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_ADC32: + 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_SBC8: - 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_SBC16: - 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_SBC32: - 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_SBC8: + 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_SBC16: + 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_SBC32: + 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_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_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_ROL8:return (cpu_state.flags_res ^ (cpu_state.flags_res >> 7)) & 1; - case FLAGS_ROL16:return (cpu_state.flags_res ^ (cpu_state.flags_res >> 15)) & 1; - case FLAGS_ROL32:return (cpu_state.flags_res ^ (cpu_state.flags_res >> 31)) & 1; + case FLAGS_ROL8: + return (cpu_state.flags_res ^ (cpu_state.flags_res >> 7)) & 1; + case FLAGS_ROL16: + return (cpu_state.flags_res ^ (cpu_state.flags_res >> 15)) & 1; + case FLAGS_ROL32: + return (cpu_state.flags_res ^ (cpu_state.flags_res >> 31)) & 1; - case FLAGS_ROR8:return (cpu_state.flags_res ^ (cpu_state.flags_res >> 1)) & 0x40; - case FLAGS_ROR16:return (cpu_state.flags_res ^ (cpu_state.flags_res >> 1)) & 0x4000; - case FLAGS_ROR32:return (cpu_state.flags_res ^ (cpu_state.flags_res >> 1)) & 0x40000000; + case FLAGS_ROR8: + return (cpu_state.flags_res ^ (cpu_state.flags_res >> 1)) & 0x40; + case FLAGS_ROR16: + return (cpu_state.flags_res ^ (cpu_state.flags_res >> 1)) & 0x4000; + case FLAGS_ROR32: + return (cpu_state.flags_res ^ (cpu_state.flags_res >> 1)) & 0x40000000; - case FLAGS_UNKNOWN:return cpu_state.flags & V_FLAG; - } - return 0; + case FLAGS_UNKNOWN: + return cpu_state.flags & V_FLAG; + } + 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; + 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_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_ADC8: - return ((cpu_state.flags_res & 0xf) < (cpu_state.flags_op1 & 0xf)) || - ((cpu_state.flags_res & 0xf) == (cpu_state.flags_op1 & 0xf) && cpu_state.flags_op2 == 0xff); - case FLAGS_ADC16: - return ((cpu_state.flags_res & 0xf) < (cpu_state.flags_op1 & 0xf)) || - ((cpu_state.flags_res & 0xf) == (cpu_state.flags_op1 & 0xf) && cpu_state.flags_op2 == 0xffff); - case FLAGS_ADC32: - return ((cpu_state.flags_res & 0xf) < (cpu_state.flags_op1 & 0xf)) || - ((cpu_state.flags_res & 0xf) == (cpu_state.flags_op1 & 0xf) && cpu_state.flags_op2 == 0xffffffff); + case FLAGS_ADC8: + return ((cpu_state.flags_res & 0xf) < (cpu_state.flags_op1 & 0xf)) || + ((cpu_state.flags_res & 0xf) == (cpu_state.flags_op1 & 0xf) && cpu_state.flags_op2 == 0xff); + case FLAGS_ADC16: + return ((cpu_state.flags_res & 0xf) < (cpu_state.flags_op1 & 0xf)) || + ((cpu_state.flags_res & 0xf) == (cpu_state.flags_op1 & 0xf) && cpu_state.flags_op2 == 0xffff); + case FLAGS_ADC32: + return ((cpu_state.flags_res & 0xf) < (cpu_state.flags_op1 & 0xf)) || + ((cpu_state.flags_res & 0xf) == (cpu_state.flags_op1 & 0xf) && cpu_state.flags_op2 == 0xffffffff); - case FLAGS_SUB8: - 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_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_SBC8: - case FLAGS_SBC16: - case FLAGS_SBC32: - return ((cpu_state.flags_op1 & 0xf) < (cpu_state.flags_op2 & 0xf)) || - ((cpu_state.flags_op1 & 0xf) == (cpu_state.flags_op2 & 0xf) && (cpu_state.flags_res & 0xf) != 0); + case FLAGS_SBC8: + case FLAGS_SBC16: + case FLAGS_SBC32: + return ((cpu_state.flags_op1 & 0xf) < (cpu_state.flags_op2 & 0xf)) || + ((cpu_state.flags_op1 & 0xf) == (cpu_state.flags_op2 & 0xf) && (cpu_state.flags_res & 0xf) != 0); - case FLAGS_ROL8: - case FLAGS_ROL16: - case FLAGS_ROL32: - case FLAGS_ROR8: - case FLAGS_ROR16: - case FLAGS_ROR32: - case FLAGS_UNKNOWN:return cpu_state.flags & A_FLAG; - } - return 0; + case FLAGS_ROL8: + case FLAGS_ROL16: + case FLAGS_ROL32: + case FLAGS_ROR8: + case FLAGS_ROR16: + case FLAGS_ROR32: + case FLAGS_UNKNOWN: + return cpu_state.flags & A_FLAG; + } + 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) ? 1 : 0; - case FLAGS_ADD16:return ((cpu_state.flags_op1 + cpu_state.flags_op2) & 0x10000) ? 1 : 0; - case FLAGS_ADD32:return (cpu_state.flags_res < cpu_state.flags_op1); + switch (cpu_state.flags_op) { + case FLAGS_ADD8: + return ((cpu_state.flags_op1 + cpu_state.flags_op2) & 0x100) ? 1 : 0; + case FLAGS_ADD16: + return ((cpu_state.flags_op1 + cpu_state.flags_op2) & 0x10000) ? 1 : 0; + case FLAGS_ADD32: + return (cpu_state.flags_res < cpu_state.flags_op1); - case FLAGS_ADC8: - return (cpu_state.flags_res < cpu_state.flags_op1) || - (cpu_state.flags_res == cpu_state.flags_op1 && cpu_state.flags_op2 == 0xff); - case FLAGS_ADC16: - return (cpu_state.flags_res < cpu_state.flags_op1) || - (cpu_state.flags_res == cpu_state.flags_op1 && cpu_state.flags_op2 == 0xffff); - case FLAGS_ADC32: - return (cpu_state.flags_res < cpu_state.flags_op1) || - (cpu_state.flags_res == cpu_state.flags_op1 && cpu_state.flags_op2 == 0xffffffff); + case FLAGS_ADC8: + return (cpu_state.flags_res < cpu_state.flags_op1) || + (cpu_state.flags_res == cpu_state.flags_op1 && cpu_state.flags_op2 == 0xff); + case FLAGS_ADC16: + return (cpu_state.flags_res < cpu_state.flags_op1) || + (cpu_state.flags_res == cpu_state.flags_op1 && cpu_state.flags_op2 == 0xffff); + case FLAGS_ADC32: + return (cpu_state.flags_res < cpu_state.flags_op1) || + (cpu_state.flags_res == cpu_state.flags_op1 && cpu_state.flags_op2 == 0xffffffff); - case FLAGS_SUB8: - case FLAGS_SUB16: - case FLAGS_SUB32:return (cpu_state.flags_op1 < cpu_state.flags_op2); + case FLAGS_SUB8: + case FLAGS_SUB16: + case FLAGS_SUB32: + return (cpu_state.flags_op1 < cpu_state.flags_op2); - case FLAGS_SBC8: - case FLAGS_SBC16: - case FLAGS_SBC32: - return (cpu_state.flags_op1 < cpu_state.flags_op2) || - (cpu_state.flags_op1 == cpu_state.flags_op2 && cpu_state.flags_res != 0); + case FLAGS_SBC8: + case FLAGS_SBC16: + case FLAGS_SBC32: + return (cpu_state.flags_op1 < cpu_state.flags_op2) || + (cpu_state.flags_op1 == cpu_state.flags_op2 && cpu_state.flags_res != 0); - case FLAGS_SHL8:return ((cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x80) ? 1 : 0; - case FLAGS_SHL16:return ((cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x8000) ? 1 : 0; - case FLAGS_SHL32:return ((cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x80000000) ? 1 : 0; + case FLAGS_SHL8: + return ((cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x80) ? 1 : 0; + case FLAGS_SHL16: + return ((cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x8000) ? 1 : 0; + case FLAGS_SHL32: + return ((cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x80000000) ? 1 : 0; - case FLAGS_SHR8: - case FLAGS_SHR16: - case FLAGS_SHR32:return (cpu_state.flags_op1 >> (cpu_state.flags_op2 - 1)) & 1; + 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_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_ZN8: + case FLAGS_ZN16: + case FLAGS_ZN32: + return 0; - case FLAGS_ROL8: - case FLAGS_ROL16: - case FLAGS_ROL32:return cpu_state.flags_res & 1; + case FLAGS_ROL8: + case FLAGS_ROL16: + case FLAGS_ROL32: + return cpu_state.flags_res & 1; - case FLAGS_ROR8:return (cpu_state.flags_res & 0x80) ? 1 : 0; - case FLAGS_ROR16:return (cpu_state.flags_res & 0x8000) ? 1 : 0; - case FLAGS_ROR32:return (cpu_state.flags_res & 0x80000000) ? 1 : 0; + case FLAGS_ROR8: + return (cpu_state.flags_res & 0x80) ? 1 : 0; + case FLAGS_ROR16: + return (cpu_state.flags_res & 0x8000) ? 1 : 0; + case FLAGS_ROR32: + return (cpu_state.flags_res & 0x80000000) ? 1 : 0; - case FLAGS_DEC8: - case FLAGS_DEC16: - case FLAGS_DEC32: - case FLAGS_INC8: - case FLAGS_INC16: - case FLAGS_INC32: - case FLAGS_UNKNOWN:return cpu_state.flags & C_FLAG; - } - return 0; + case FLAGS_DEC8: + case FLAGS_DEC16: + case FLAGS_DEC32: + case FLAGS_INC8: + case FLAGS_INC16: + case FLAGS_INC32: + case FLAGS_UNKNOWN: + return cpu_state.flags & C_FLAG; + } + return 0; } //#define ZF_SET() (flags & Z_FLAG) @@ -363,186 +418,183 @@ static inline int CF_SET() { //#define AF_SET() (flags & A_FLAG) 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; - cpu_state.flags = (cpu_state.flags & ~0x8d5) | tempf; - cpu_state.flags_op = FLAGS_UNKNOWN; - } + 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; + cpu_state.flags = (cpu_state.flags & ~0x8d5) | tempf; + cpu_state.flags_op = FLAGS_UNKNOWN; + } } -static inline void flags_extract() { - 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()) - cpu_state.flags |= C_FLAG; - else - cpu_state.flags &= ~C_FLAG; - } + if (cpu_state.flags_op != FLAGS_UNKNOWN) { + if (CF_SET()) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + } } static inline int flags_res_valid() { - if (cpu_state.flags_op == FLAGS_UNKNOWN || - (cpu_state.flags_op >= FLAGS_ROL8 && cpu_state.flags_op <= FLAGS_ROR32)) - return 0; + if (cpu_state.flags_op == FLAGS_UNKNOWN || (cpu_state.flags_op >= FLAGS_ROL8 && cpu_state.flags_op <= FLAGS_ROR32)) + return 0; - return 1; + return 1; } static inline void setznp8(uint8_t val) { - cpu_state.flags_op = FLAGS_ZN8; - cpu_state.flags_res = 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; + 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; + 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; \ +#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; -#define set_flags_rotate(op, res) \ - cpu_state.flags_op = op; \ +#define set_flags_rotate(op, res) \ + cpu_state.flags_op = op; \ cpu_state.flags_res = res; static inline void setadd8(uint8_t a, uint8_t b) { - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a + b) & 0xff; - cpu_state.flags_op = FLAGS_ADD8; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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) { - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a + b + tempc) & 0xff; - cpu_state.flags_op = FLAGS_ADC8; + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = (a + b + tempc) & 0xff; + cpu_state.flags_op = FLAGS_ADC8; } static inline void setadc16(uint16_t a, uint16_t b) { - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a + b + tempc) & 0xffff; - cpu_state.flags_op = FLAGS_ADC16; + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = (a + b + tempc) & 0xffff; + cpu_state.flags_op = FLAGS_ADC16; } static inline void setadc32(uint32_t a, uint32_t b) { - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = a + b + tempc; - cpu_state.flags_op = FLAGS_ADC32; + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = a + b + tempc; + cpu_state.flags_op = FLAGS_ADC32; } static inline void setsbc8(uint8_t a, uint8_t b) { - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a - (b + tempc)) & 0xff; - cpu_state.flags_op = FLAGS_SBC8; + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = (a - (b + tempc)) & 0xff; + cpu_state.flags_op = FLAGS_SBC8; } static inline void setsbc16(uint16_t a, uint16_t b) { - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a - (b + tempc)) & 0xffff; - cpu_state.flags_op = FLAGS_SBC16; + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = (a - (b + tempc)) & 0xffff; + cpu_state.flags_op = FLAGS_SBC16; } static inline void setsbc32(uint32_t a, uint32_t b) { - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = a - (b + tempc); - cpu_state.flags_op = FLAGS_SBC32; + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = a - (b + tempc); + cpu_state.flags_op = FLAGS_SBC32; } extern void cpu_386_flags_extract(); diff --git a/includes/private/cpu/x86_ops_3dnow.h b/includes/private/cpu/x86_ops_3dnow.h index e27f3a62..b6086140 100644 --- a/includes/private/cpu/x86_ops_3dnow.h +++ b/includes/private/cpu/x86_ops_3dnow.h @@ -3,320 +3,340 @@ #include static int opPREFETCH_a16(uint32_t fetchdat) { - fetch_ea_16(fetchdat); - ILLEGAL_ON(cpu_mod == 3); + fetch_ea_16(fetchdat); + ILLEGAL_ON(cpu_mod == 3); - CLOCK_CYCLES(1); - return 0; + CLOCK_CYCLES(1); + return 0; } static int opPREFETCH_a32(uint32_t fetchdat) { - fetch_ea_32(fetchdat); - ILLEGAL_ON(cpu_mod == 3); + fetch_ea_32(fetchdat); + ILLEGAL_ON(cpu_mod == 3); - CLOCK_CYCLES(1); - return 0; + CLOCK_CYCLES(1); + return 0; } static int opFEMMS(uint32_t fetchdat) { - ILLEGAL_ON(!cpu_has_feature(CPU_FEATURE_MMX)); - if (cr0 & 0xc) { - x86_int(7); - return 1; - } - x87_emms(); - CLOCK_CYCLES(1); - return 0; + ILLEGAL_ON(!cpu_has_feature(CPU_FEATURE_MMX)); + if (cr0 & 0xc) { + x86_int(7); + return 1; + } + x87_emms(); + CLOCK_CYCLES(1); + return 0; } static int opPAVGUSB(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_GETSRC(); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].b[0] + src.b[0] + 1) >> 1; - cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].b[1] + src.b[1] + 1) >> 1; - cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].b[2] + src.b[2] + 1) >> 1; - cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].b[3] + src.b[3] + 1) >> 1; - cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].b[4] + src.b[4] + 1) >> 1; - cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].b[5] + src.b[5] + 1) >> 1; - cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].b[6] + src.b[6] + 1) >> 1; - cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].b[7] + src.b[7] + 1) >> 1; + cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].b[0] + src.b[0] + 1) >> 1; + cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].b[1] + src.b[1] + 1) >> 1; + cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].b[2] + src.b[2] + 1) >> 1; + cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].b[3] + src.b[3] + 1) >> 1; + cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].b[4] + src.b[4] + 1) >> 1; + cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].b[5] + src.b[5] + 1) >> 1; + cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].b[6] + src.b[6] + 1) >> 1; + cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].b[7] + src.b[7] + 1) >> 1; - return 0; + return 0; } static int opPF2ID(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_GETSRC(); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].sl[0] = (int32_t)src.f[0]; - cpu_state.MM[cpu_reg].sl[1] = (int32_t)src.f[1]; + cpu_state.MM[cpu_reg].sl[0] = (int32_t)src.f[0]; + cpu_state.MM[cpu_reg].sl[1] = (int32_t)src.f[1]; - return 0; + return 0; } static int opPFACC(uint32_t fetchdat) { - MMX_REG src; - float tempf; + MMX_REG src; + float tempf; - MMX_GETSRC(); + MMX_GETSRC(); - tempf = cpu_state.MM[cpu_reg].f[0] + cpu_state.MM[cpu_reg].f[1]; - cpu_state.MM[cpu_reg].f[1] = src.f[0] + src.f[1]; - cpu_state.MM[cpu_reg].f[0] = tempf; + tempf = cpu_state.MM[cpu_reg].f[0] + cpu_state.MM[cpu_reg].f[1]; + cpu_state.MM[cpu_reg].f[1] = src.f[0] + src.f[1]; + cpu_state.MM[cpu_reg].f[0] = tempf; - return 0; + return 0; } static int opPFADD(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_GETSRC(); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].f[0] += src.f[0]; - cpu_state.MM[cpu_reg].f[1] += src.f[1]; + cpu_state.MM[cpu_reg].f[0] += src.f[0]; + cpu_state.MM[cpu_reg].f[1] += src.f[1]; - return 0; + return 0; } static int opPFCMPEQ(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_GETSRC(); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].f[0] == src.f[0]) ? 0xffffffff : 0; - cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].f[1] == src.f[1]) ? 0xffffffff : 0; + cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].f[0] == src.f[0]) ? 0xffffffff : 0; + cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].f[1] == src.f[1]) ? 0xffffffff : 0; - return 0; + return 0; } static int opPFCMPGE(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_GETSRC(); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].f[0] >= src.f[0]) ? 0xffffffff : 0; - cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].f[1] >= src.f[1]) ? 0xffffffff : 0; + cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].f[0] >= src.f[0]) ? 0xffffffff : 0; + cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].f[1] >= src.f[1]) ? 0xffffffff : 0; - return 0; + return 0; } static int opPFCMPGT(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_GETSRC(); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].f[0] > src.f[0]) ? 0xffffffff : 0; - cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].f[1] > src.f[1]) ? 0xffffffff : 0; + cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].f[0] > src.f[0]) ? 0xffffffff : 0; + cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].f[1] > src.f[1]) ? 0xffffffff : 0; - return 0; + return 0; } static int opPFMAX(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_GETSRC(); + MMX_GETSRC(); - if (src.f[0] > cpu_state.MM[cpu_reg].f[0]) - cpu_state.MM[cpu_reg].f[0] = src.f[0]; - if (src.f[1] > cpu_state.MM[cpu_reg].f[1]) - cpu_state.MM[cpu_reg].f[1] = src.f[1]; + if (src.f[0] > cpu_state.MM[cpu_reg].f[0]) + cpu_state.MM[cpu_reg].f[0] = src.f[0]; + if (src.f[1] > cpu_state.MM[cpu_reg].f[1]) + cpu_state.MM[cpu_reg].f[1] = src.f[1]; - return 0; + return 0; } static int opPFMIN(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_GETSRC(); + MMX_GETSRC(); - if (src.f[0] < cpu_state.MM[cpu_reg].f[0]) - cpu_state.MM[cpu_reg].f[0] = src.f[0]; - if (src.f[1] < cpu_state.MM[cpu_reg].f[1]) - cpu_state.MM[cpu_reg].f[1] = src.f[1]; + if (src.f[0] < cpu_state.MM[cpu_reg].f[0]) + cpu_state.MM[cpu_reg].f[0] = src.f[0]; + if (src.f[1] < cpu_state.MM[cpu_reg].f[1]) + cpu_state.MM[cpu_reg].f[1] = src.f[1]; - return 0; + return 0; } static int opPFMUL(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_GETSRC(); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].f[0] *= src.f[0]; - cpu_state.MM[cpu_reg].f[1] *= src.f[1]; + cpu_state.MM[cpu_reg].f[0] *= src.f[0]; + cpu_state.MM[cpu_reg].f[1] *= src.f[1]; - return 0; + return 0; } static int opPFRCP(uint32_t fetchdat) { - union { - uint32_t i; - float f; - } src; + union { + uint32_t i; + float f; + } src; - if (cpu_mod == 3) { - src.f = cpu_state.MM[cpu_rm].f[0]; - CLOCK_CYCLES(1); - } else { - SEG_CHECK_READ(cpu_state.ea_seg); - src.i = readmeml(easeg, cpu_state.eaaddr); - if (cpu_state.abrt) - return 1; - CLOCK_CYCLES(2); - } + if (cpu_mod == 3) { + src.f = cpu_state.MM[cpu_rm].f[0]; + CLOCK_CYCLES(1); + } else { + SEG_CHECK_READ(cpu_state.ea_seg); + src.i = readmeml(easeg, cpu_state.eaaddr); + if (cpu_state.abrt) + return 1; + CLOCK_CYCLES(2); + } - cpu_state.MM[cpu_reg].f[0] = 1.0 / src.f; - cpu_state.MM[cpu_reg].f[1] = cpu_state.MM[cpu_reg].f[0]; + cpu_state.MM[cpu_reg].f[0] = 1.0 / src.f; + cpu_state.MM[cpu_reg].f[1] = cpu_state.MM[cpu_reg].f[0]; - return 0; + return 0; } /*Since opPFRCP() calculates a full precision reciprocal, treat the followup iterations as MOVs*/ static int opPFRCPIT1(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_GETSRC(); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].f[0] = src.f[0]; - cpu_state.MM[cpu_reg].f[1] = src.f[1]; + cpu_state.MM[cpu_reg].f[0] = src.f[0]; + cpu_state.MM[cpu_reg].f[1] = src.f[1]; - return 0; + return 0; } static int opPFRCPIT2(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_GETSRC(); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].f[0] = src.f[0]; - cpu_state.MM[cpu_reg].f[1] = src.f[1]; + cpu_state.MM[cpu_reg].f[0] = src.f[0]; + cpu_state.MM[cpu_reg].f[1] = src.f[1]; - return 0; + return 0; } static int opPFRSQRT(uint32_t fetchdat) { - union { - uint32_t i; - float f; - } src; + union { + uint32_t i; + float f; + } src; - if (cpu_mod == 3) { - src.f = cpu_state.MM[cpu_rm].f[0]; - CLOCK_CYCLES(1); - } else { - SEG_CHECK_READ(cpu_state.ea_seg); - src.i = readmeml(easeg, cpu_state.eaaddr); - if (cpu_state.abrt) - return 1; - CLOCK_CYCLES(2); - } + if (cpu_mod == 3) { + src.f = cpu_state.MM[cpu_rm].f[0]; + CLOCK_CYCLES(1); + } else { + SEG_CHECK_READ(cpu_state.ea_seg); + src.i = readmeml(easeg, cpu_state.eaaddr); + if (cpu_state.abrt) + return 1; + CLOCK_CYCLES(2); + } - cpu_state.MM[cpu_reg].f[0] = 1.0 / sqrt(src.f); - cpu_state.MM[cpu_reg].f[1] = cpu_state.MM[cpu_reg].f[0]; + cpu_state.MM[cpu_reg].f[0] = 1.0 / sqrt(src.f); + cpu_state.MM[cpu_reg].f[1] = cpu_state.MM[cpu_reg].f[0]; - return 0; + return 0; } /*Since opPFRSQRT() calculates a full precision inverse square root, treat the followup iteration as a NOP*/ static int opPFRSQIT1(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_GETSRC(); - UNUSED(src); + MMX_GETSRC(); + UNUSED(src); - return 0; + return 0; } static int opPFSUB(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_GETSRC(); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].f[0] -= src.f[0]; - cpu_state.MM[cpu_reg].f[1] -= src.f[1]; + cpu_state.MM[cpu_reg].f[0] -= src.f[0]; + cpu_state.MM[cpu_reg].f[1] -= src.f[1]; - return 0; + return 0; } static int opPFSUBR(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_GETSRC(); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].f[0] = src.f[0] - cpu_state.MM[cpu_reg].f[0]; - cpu_state.MM[cpu_reg].f[1] = src.f[1] - cpu_state.MM[cpu_reg].f[1]; + cpu_state.MM[cpu_reg].f[0] = src.f[0] - cpu_state.MM[cpu_reg].f[0]; + cpu_state.MM[cpu_reg].f[1] = src.f[1] - cpu_state.MM[cpu_reg].f[1]; - return 0; + return 0; } static int opPI2FD(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_GETSRC(); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].f[0] = (float)src.sl[0]; - cpu_state.MM[cpu_reg].f[1] = (float)src.sl[1]; + cpu_state.MM[cpu_reg].f[0] = (float)src.sl[0]; + cpu_state.MM[cpu_reg].f[1] = (float)src.sl[1]; - return 0; + return 0; } static int opPMULHRW(uint32_t fetchdat) { - if (cpu_mod == 3) { - cpu_state.MM[cpu_reg].w[0] = (((int32_t)cpu_state.MM[cpu_reg].sw[0] * (int32_t)cpu_state.MM[cpu_rm].sw[0]) + 0x8000) >> 16; - cpu_state.MM[cpu_reg].w[1] = (((int32_t)cpu_state.MM[cpu_reg].sw[1] * (int32_t)cpu_state.MM[cpu_rm].sw[1]) + 0x8000) >> 16; - cpu_state.MM[cpu_reg].w[2] = (((int32_t)cpu_state.MM[cpu_reg].sw[2] * (int32_t)cpu_state.MM[cpu_rm].sw[2]) + 0x8000) >> 16; - cpu_state.MM[cpu_reg].w[3] = (((int32_t)cpu_state.MM[cpu_reg].sw[3] * (int32_t)cpu_state.MM[cpu_rm].sw[3]) + 0x8000) >> 16; - CLOCK_CYCLES(1); - } else { - MMX_REG src; + if (cpu_mod == 3) { + cpu_state.MM[cpu_reg].w[0] = + (((int32_t)cpu_state.MM[cpu_reg].sw[0] * (int32_t)cpu_state.MM[cpu_rm].sw[0]) + 0x8000) >> 16; + cpu_state.MM[cpu_reg].w[1] = + (((int32_t)cpu_state.MM[cpu_reg].sw[1] * (int32_t)cpu_state.MM[cpu_rm].sw[1]) + 0x8000) >> 16; + cpu_state.MM[cpu_reg].w[2] = + (((int32_t)cpu_state.MM[cpu_reg].sw[2] * (int32_t)cpu_state.MM[cpu_rm].sw[2]) + 0x8000) >> 16; + cpu_state.MM[cpu_reg].w[3] = + (((int32_t)cpu_state.MM[cpu_reg].sw[3] * (int32_t)cpu_state.MM[cpu_rm].sw[3]) + 0x8000) >> 16; + CLOCK_CYCLES(1); + } else { + MMX_REG src; - SEG_CHECK_READ(cpu_state.ea_seg); - src.l[0] = readmeml(easeg, cpu_state.eaaddr); - src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); - if (cpu_state.abrt) - return 0; - cpu_state.MM[cpu_reg].w[0] = ((int32_t)(cpu_state.MM[cpu_reg].sw[0] * (int32_t)src.sw[0]) + 0x8000) >> 16; - cpu_state.MM[cpu_reg].w[1] = ((int32_t)(cpu_state.MM[cpu_reg].sw[1] * (int32_t)src.sw[1]) + 0x8000) >> 16; - cpu_state.MM[cpu_reg].w[2] = ((int32_t)(cpu_state.MM[cpu_reg].sw[2] * (int32_t)src.sw[2]) + 0x8000) >> 16; - cpu_state.MM[cpu_reg].w[3] = ((int32_t)(cpu_state.MM[cpu_reg].sw[3] * (int32_t)src.sw[3]) + 0x8000) >> 16; - CLOCK_CYCLES(2); - } - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + src.l[0] = readmeml(easeg, cpu_state.eaaddr); + src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) + return 0; + cpu_state.MM[cpu_reg].w[0] = ((int32_t)(cpu_state.MM[cpu_reg].sw[0] * (int32_t)src.sw[0]) + 0x8000) >> 16; + cpu_state.MM[cpu_reg].w[1] = ((int32_t)(cpu_state.MM[cpu_reg].sw[1] * (int32_t)src.sw[1]) + 0x8000) >> 16; + cpu_state.MM[cpu_reg].w[2] = ((int32_t)(cpu_state.MM[cpu_reg].sw[2] * (int32_t)src.sw[2]) + 0x8000) >> 16; + cpu_state.MM[cpu_reg].w[3] = ((int32_t)(cpu_state.MM[cpu_reg].sw[3] * (int32_t)src.sw[3]) + 0x8000) >> 16; + CLOCK_CYCLES(2); + } + return 0; } -OpFn OP_TABLE(3DNOW)[256] = - { -/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opPI2FD, ILLEGAL, ILLEGAL, -/*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opPF2ID, ILLEGAL, ILLEGAL, -/*20*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +OpFn OP_TABLE(3DNOW)[256] = { + /* 00 01 02 03 04 05 06 07 + 08 09 0a 0b 0c 0d 0e 0f*/ + /*00*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opPI2FD, ILLEGAL, ILLEGAL, + /*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opPF2ID, ILLEGAL, ILLEGAL, + /*20*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + /*30*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + /*40*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + /*50*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + /*60*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + /*70*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*80*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*90*/ opPFCMPGE, ILLEGAL, ILLEGAL, ILLEGAL, opPFMIN, ILLEGAL, opPFRCP, opPFRSQRT, ILLEGAL, ILLEGAL, opPFSUB, ILLEGAL, ILLEGAL, ILLEGAL, opPFADD, ILLEGAL, -/*a0*/ opPFCMPGT, ILLEGAL, ILLEGAL, ILLEGAL, opPFMAX, ILLEGAL, opPFRCPIT1, opPFRSQIT1, ILLEGAL, ILLEGAL, opPFSUBR, ILLEGAL, ILLEGAL, ILLEGAL, opPFACC, ILLEGAL, -/*b0*/ opPFCMPEQ, ILLEGAL, ILLEGAL, ILLEGAL, opPFMUL, ILLEGAL, opPFRCPIT2, opPMULHRW, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opPAVGUSB, + /*80*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + /*90*/ opPFCMPGE, ILLEGAL, ILLEGAL, ILLEGAL, opPFMIN, ILLEGAL, opPFRCP, opPFRSQRT, + ILLEGAL, ILLEGAL, opPFSUB, ILLEGAL, ILLEGAL, ILLEGAL, opPFADD, ILLEGAL, + /*a0*/ opPFCMPGT, ILLEGAL, ILLEGAL, ILLEGAL, opPFMAX, ILLEGAL, opPFRCPIT1, opPFRSQIT1, + ILLEGAL, ILLEGAL, opPFSUBR, ILLEGAL, ILLEGAL, ILLEGAL, opPFACC, ILLEGAL, + /*b0*/ opPFCMPEQ, ILLEGAL, ILLEGAL, ILLEGAL, opPFMUL, ILLEGAL, opPFRCPIT2, opPMULHRW, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opPAVGUSB, -/*c0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - }; + /*c0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + /*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + /*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +}; static int op3DNOW_a16(uint32_t fetchdat) { - uint8_t opcode; + uint8_t opcode; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - opcode = fastreadb(cs + cpu_state.pc); - if (cpu_state.abrt) - return 1; - cpu_state.pc++; + fetch_ea_16(fetchdat); + opcode = fastreadb(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; - return x86_opcodes_3DNOW[opcode](0); + return x86_opcodes_3DNOW[opcode](0); } static int op3DNOW_a32(uint32_t fetchdat) { - uint8_t opcode; + uint8_t opcode; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - opcode = fastreadb(cs + cpu_state.pc); - if (cpu_state.abrt) - return 1; - cpu_state.pc++; + fetch_ea_32(fetchdat); + opcode = fastreadb(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; - return x86_opcodes_3DNOW[opcode](0); + return x86_opcodes_3DNOW[opcode](0); } #endif /* _X86_OPS_3DNOW_H_ */ diff --git a/includes/private/cpu/x86_ops_arith.h b/includes/private/cpu/x86_ops_arith.h index a3e06d28..7018ee39 100644 --- a/includes/private/cpu/x86_ops_arith.h +++ b/includes/private/cpu/x86_ops_arith.h @@ -1,292 +1,312 @@ #ifndef _X86_OPS_ARITH_H_ #define _X86_OPS_ARITH_H_ -#define OP_ARITH(name, operation, setflags, flagops, gettempc) \ - static int op ## name ## _b_rmw_a16(uint32_t fetchdat) \ - { \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_16(fetchdat); \ - if (cpu_mod == 3) \ - { \ - uint8_t dst = getr8(cpu_rm); \ - uint8_t 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 \ - { \ - uint8_t dst; \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - dst = geteab(); if (cpu_state.abrt) return 1; \ - uint8_t 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) \ - { \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_32(fetchdat); \ - if (cpu_mod == 3) \ - { \ - uint8_t dst = getr8(cpu_rm); \ - uint8_t 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 \ - { \ - uint8_t dst; \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - dst = geteab(); if (cpu_state.abrt) return 1; \ - uint8_t 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) \ - { \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_16(fetchdat); \ - if (cpu_mod == 3) \ - { \ - uint16_t dst = cpu_state.regs[cpu_rm].w; \ - uint16_t 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 \ - { \ - uint16_t dst; \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - dst = geteaw(); if (cpu_state.abrt) return 1; \ - uint16_t 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) \ - { \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_32(fetchdat); \ - if (cpu_mod == 3) \ - { \ - uint16_t dst = cpu_state.regs[cpu_rm].w; \ - uint16_t 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 \ - { \ - uint16_t dst; \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - dst = geteaw(); if (cpu_state.abrt) return 1; \ - uint16_t 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) \ - { \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_16(fetchdat); \ - if (cpu_mod == 3) \ - { \ - uint32_t dst = cpu_state.regs[cpu_rm].l; \ - uint32_t 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 \ - { \ - uint32_t dst; \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - dst = geteal(); if (cpu_state.abrt) return 1; \ - uint32_t 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) \ - { \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_32(fetchdat); \ - if (cpu_mod == 3) \ - { \ - uint32_t dst = cpu_state.regs[cpu_rm].l; \ - uint32_t 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 \ - { \ - uint32_t dst; \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - dst = geteal(); if (cpu_state.abrt) return 1; \ - uint32_t 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); \ - if (cpu_mod != 3) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - 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); \ - if (cpu_mod != 3) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - 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); \ - if (cpu_mod != 3) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - 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); \ - if (cpu_mod != 3) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - 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); \ - if (cpu_mod != 3) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - 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); \ - if (cpu_mod != 3) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - 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; \ +#define OP_ARITH(name, operation, setflags, flagops, gettempc) \ + static int op##name##_b_rmw_a16(uint32_t fetchdat) { \ + if (gettempc) \ + tempc = CF_SET() ? 1 : 0; \ + fetch_ea_16(fetchdat); \ + if (cpu_mod == 3) { \ + uint8_t dst = getr8(cpu_rm); \ + uint8_t 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 { \ + uint8_t dst; \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + dst = geteab(); \ + if (cpu_state.abrt) \ + return 1; \ + uint8_t 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) { \ + if (gettempc) \ + tempc = CF_SET() ? 1 : 0; \ + fetch_ea_32(fetchdat); \ + if (cpu_mod == 3) { \ + uint8_t dst = getr8(cpu_rm); \ + uint8_t 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 { \ + uint8_t dst; \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + dst = geteab(); \ + if (cpu_state.abrt) \ + return 1; \ + uint8_t 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) { \ + if (gettempc) \ + tempc = CF_SET() ? 1 : 0; \ + fetch_ea_16(fetchdat); \ + if (cpu_mod == 3) { \ + uint16_t dst = cpu_state.regs[cpu_rm].w; \ + uint16_t 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 { \ + uint16_t dst; \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + dst = geteaw(); \ + if (cpu_state.abrt) \ + return 1; \ + uint16_t 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) { \ + if (gettempc) \ + tempc = CF_SET() ? 1 : 0; \ + fetch_ea_32(fetchdat); \ + if (cpu_mod == 3) { \ + uint16_t dst = cpu_state.regs[cpu_rm].w; \ + uint16_t 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 { \ + uint16_t dst; \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + dst = geteaw(); \ + if (cpu_state.abrt) \ + return 1; \ + uint16_t 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) { \ + if (gettempc) \ + tempc = CF_SET() ? 1 : 0; \ + fetch_ea_16(fetchdat); \ + if (cpu_mod == 3) { \ + uint32_t dst = cpu_state.regs[cpu_rm].l; \ + uint32_t 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 { \ + uint32_t dst; \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + dst = geteal(); \ + if (cpu_state.abrt) \ + return 1; \ + uint32_t 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) { \ + if (gettempc) \ + tempc = CF_SET() ? 1 : 0; \ + fetch_ea_32(fetchdat); \ + if (cpu_mod == 3) { \ + uint32_t dst = cpu_state.regs[cpu_rm].l; \ + uint32_t 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 { \ + uint32_t dst; \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + dst = geteal(); \ + if (cpu_state.abrt) \ + return 1; \ + uint32_t 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); \ + if (cpu_mod != 3) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + 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); \ + if (cpu_mod != 3) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + 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); \ + if (cpu_mod != 3) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + 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); \ + if (cpu_mod != 3) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + 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); \ + if (cpu_mod != 3) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + 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); \ + if (cpu_mod != 3) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + 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) @@ -294,574 +314,601 @@ 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(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); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - 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; + uint8_t dst; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + 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); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - 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; + uint8_t dst; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + 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); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - 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; + uint16_t dst; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + 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); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - 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; + uint16_t dst; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + 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); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - 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; + uint32_t dst; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + 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); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - 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; + uint32_t dst; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + 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); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - 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; + uint8_t src; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + 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); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - 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; + uint8_t src; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + 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); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - 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; + uint16_t src; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + 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); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - 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; + uint16_t src; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + 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); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - 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; + uint32_t src; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + 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); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - 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; + uint32_t src; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + 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; + 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; + 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; + 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); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - 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; + uint8_t temp, temp2; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + 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); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - 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; + uint8_t temp, temp2; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + 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); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - 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; + uint16_t temp, temp2; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + 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); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - 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; + uint16_t temp, temp2; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + 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); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - 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; + uint32_t temp, temp2; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + 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); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - 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; + uint32_t temp, temp2; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + 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; + 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; + 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; + 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; \ +#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; + uint8_t src, dst; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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); + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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; + return 0; } static int op80_a32(uint32_t fetchdat) { - uint8_t src, dst; + uint8_t src, dst; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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); + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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; + return 0; } static int op81_w_a16(uint32_t fetchdat) { - uint16_t src, dst; + uint16_t src, dst; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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); + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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; + return 0; } static int op81_w_a32(uint32_t fetchdat) { - uint16_t src, dst; + uint16_t src, dst; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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); + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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; + return 0; } static int op81_l_a16(uint32_t fetchdat) { - uint32_t src, dst; + uint32_t src, dst; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - src = getlong(); - if (cpu_state.abrt) - return 1; - ARITH_MULTI(l, 32); - if ((rmdat & 0x38) == 0x38) - 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); + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + src = getlong(); + if (cpu_state.abrt) + return 1; + ARITH_MULTI(l, 32); + if ((rmdat & 0x38) == 0x38) + 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; + return 0; } static int op81_l_a32(uint32_t fetchdat) { - uint32_t src, dst; + uint32_t src, dst; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - src = getlong(); - if (cpu_state.abrt) - return 1; - ARITH_MULTI(l, 32); - if ((rmdat & 0x38) == 0x38) - 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); + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + src = getlong(); + if (cpu_state.abrt) + return 1; + ARITH_MULTI(l, 32); + if ((rmdat & 0x38) == 0x38) + 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; + return 0; } static int op83_w_a16(uint32_t fetchdat) { - uint16_t src, dst; + uint16_t src, dst; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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); + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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; + return 0; } static int op83_w_a32(uint32_t fetchdat) { - uint16_t src, dst; + uint16_t src, dst; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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); + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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; + return 0; } static int op83_l_a16(uint32_t fetchdat) { - uint32_t src, dst; + uint32_t src, dst; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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); + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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; + return 0; } static int op83_l_a32(uint32_t fetchdat) { - uint32_t src, dst; + uint32_t src, dst; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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); + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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; + return 0; } #endif /* _X86_OPS_ARITH_H_ */ diff --git a/includes/private/cpu/x86_ops_atomic.h b/includes/private/cpu/x86_ops_atomic.h index 001e7909..ff90aa15 100644 --- a/includes/private/cpu/x86_ops_atomic.h +++ b/includes/private/cpu/x86_ops_atomic.h @@ -1,322 +1,322 @@ #ifndef _X86_OPS_ATOMIC_H_ #define _X86_OPS_ATOMIC_H_ 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); - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteab(); - if (cpu_state.abrt) - return 1; - if (AL == temp) - seteab(getr8(cpu_reg)); - else - AL = temp; - if (cpu_state.abrt) - return 1; - setsub8(temp2, temp); - CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10); - return 0; + uint8_t temp, temp2 = AL; + if (!is486) { + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + return 1; + } + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; + if (AL == temp) + seteab(getr8(cpu_reg)); + else + AL = temp; + 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); - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteab(); - if (cpu_state.abrt) - return 1; - if (AL == temp) - seteab(getr8(cpu_reg)); - else - AL = temp; - if (cpu_state.abrt) - return 1; - setsub8(temp2, temp); - CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10); - return 0; + uint8_t temp, temp2 = AL; + if (!is486) { + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + return 1; + } + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; + if (AL == temp) + seteab(getr8(cpu_reg)); + else + AL = temp; + 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); - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteaw(); - if (cpu_state.abrt) - return 1; - if (AX == temp) - seteaw(cpu_state.regs[cpu_reg].w); - else - AX = temp; - if (cpu_state.abrt) - return 1; - setsub16(temp2, temp); - CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10); - return 0; + uint16_t temp, temp2 = AX; + if (!is486) { + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + return 1; + } + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + if (AX == temp) + seteaw(cpu_state.regs[cpu_reg].w); + else + AX = temp; + 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); - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteaw(); - if (cpu_state.abrt) - return 1; - if (AX == temp) - seteaw(cpu_state.regs[cpu_reg].w); - else - AX = temp; - if (cpu_state.abrt) - return 1; - setsub16(temp2, temp); - CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10); - return 0; + uint16_t temp, temp2 = AX; + if (!is486) { + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + return 1; + } + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + if (AX == temp) + seteaw(cpu_state.regs[cpu_reg].w); + else + AX = temp; + 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); - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteal(); - if (cpu_state.abrt) - return 1; - if (EAX == temp) - seteal(cpu_state.regs[cpu_reg].l); - else - EAX = temp; - if (cpu_state.abrt) - return 1; - setsub32(temp2, temp); - CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10); - return 0; + uint32_t temp, temp2 = EAX; + if (!is486) { + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + return 1; + } + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteal(); + if (cpu_state.abrt) + return 1; + if (EAX == temp) + seteal(cpu_state.regs[cpu_reg].l); + else + EAX = temp; + 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); - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteal(); - if (cpu_state.abrt) - return 1; - if (EAX == temp) - seteal(cpu_state.regs[cpu_reg].l); - else - EAX = temp; - if (cpu_state.abrt) - return 1; - setsub32(temp2, temp); - CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10); - return 0; + uint32_t temp, temp2 = EAX; + if (!is486) { + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + return 1; + } + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteal(); + if (cpu_state.abrt) + return 1; + if (EAX == temp) + seteal(cpu_state.regs[cpu_reg].l); + else + EAX = temp; + 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); - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteal(); - temp_hi = readmeml(easeg, cpu_state.eaaddr + 4); - if (cpu_state.abrt) - return 0; - if (EAX == temp && EDX == temp_hi) { - 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) - cpu_state.flags |= Z_FLAG; - else - cpu_state.flags &= ~Z_FLAG; - cycles -= (cpu_mod == 3) ? 6 : 10; - return 0; + 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); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteal(); + temp_hi = readmeml(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) + return 0; + if (EAX == temp && EDX == temp_hi) { + 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) + cpu_state.flags |= Z_FLAG; + else + cpu_state.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); - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteal(); - temp_hi = readmeml(easeg, cpu_state.eaaddr + 4); - if (cpu_state.abrt) - return 0; - if (EAX == temp && EDX == temp_hi) { - 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) - cpu_state.flags |= Z_FLAG; - else - cpu_state.flags &= ~Z_FLAG; - cycles -= (cpu_mod == 3) ? 6 : 10; - return 0; + 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); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteal(); + temp_hi = readmeml(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) + return 0; + if (EAX == temp && EDX == temp_hi) { + 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) + cpu_state.flags |= Z_FLAG; + else + cpu_state.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); - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteab(); - if (cpu_state.abrt) - return 1; - seteab(temp + getr8(cpu_reg)); - if (cpu_state.abrt) - return 1; - setadd8(temp, getr8(cpu_reg)); - setr8(cpu_reg, temp); - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4); - return 0; + uint8_t temp; + if (!is486) { + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + return 1; + } + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; + seteab(temp + getr8(cpu_reg)); + if (cpu_state.abrt) + return 1; + setadd8(temp, getr8(cpu_reg)); + 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); - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteab(); - if (cpu_state.abrt) - return 1; - seteab(temp + getr8(cpu_reg)); - if (cpu_state.abrt) - return 1; - setadd8(temp, getr8(cpu_reg)); - setr8(cpu_reg, temp); - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4); - return 0; + uint8_t temp; + if (!is486) { + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + return 1; + } + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; + seteab(temp + getr8(cpu_reg)); + if (cpu_state.abrt) + return 1; + setadd8(temp, getr8(cpu_reg)); + 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); - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteaw(); - if (cpu_state.abrt) - return 1; - seteaw(temp + cpu_state.regs[cpu_reg].w); - if (cpu_state.abrt) - return 1; - setadd16(temp, cpu_state.regs[cpu_reg].w); - cpu_state.regs[cpu_reg].w = temp; - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4); - return 0; + uint16_t temp; + if (!is486) { + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + return 1; + } + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + seteaw(temp + cpu_state.regs[cpu_reg].w); + if (cpu_state.abrt) + return 1; + setadd16(temp, cpu_state.regs[cpu_reg].w); + 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); - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteaw(); - if (cpu_state.abrt) - return 1; - seteaw(temp + cpu_state.regs[cpu_reg].w); - if (cpu_state.abrt) - return 1; - setadd16(temp, cpu_state.regs[cpu_reg].w); - cpu_state.regs[cpu_reg].w = temp; - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4); - return 0; + uint16_t temp; + if (!is486) { + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + return 1; + } + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + seteaw(temp + cpu_state.regs[cpu_reg].w); + if (cpu_state.abrt) + return 1; + setadd16(temp, cpu_state.regs[cpu_reg].w); + 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); - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteal(); - if (cpu_state.abrt) - return 1; - seteal(temp + cpu_state.regs[cpu_reg].l); - if (cpu_state.abrt) - return 1; - setadd32(temp, cpu_state.regs[cpu_reg].l); - cpu_state.regs[cpu_reg].l = temp; - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4); - return 0; + uint32_t temp; + if (!is486) { + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + return 1; + } + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteal(); + if (cpu_state.abrt) + return 1; + seteal(temp + cpu_state.regs[cpu_reg].l); + if (cpu_state.abrt) + return 1; + setadd32(temp, cpu_state.regs[cpu_reg].l); + 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); - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteal(); - if (cpu_state.abrt) - return 1; - seteal(temp + cpu_state.regs[cpu_reg].l); - if (cpu_state.abrt) - return 1; - setadd32(temp, cpu_state.regs[cpu_reg].l); - cpu_state.regs[cpu_reg].l = temp; - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4); - return 0; + uint32_t temp; + if (!is486) { + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + return 1; + } + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteal(); + if (cpu_state.abrt) + return 1; + seteal(temp + cpu_state.regs[cpu_reg].l); + if (cpu_state.abrt) + return 1; + setadd32(temp, cpu_state.regs[cpu_reg].l); + cpu_state.regs[cpu_reg].l = temp; + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4); + return 0; } #endif /* _X86_OPS_ATOMIC_H_ */ diff --git a/includes/private/cpu/x86_ops_bcd.h b/includes/private/cpu/x86_ops_bcd.h index 33db2cb3..ff87a453 100644 --- a/includes/private/cpu/x86_ops_bcd.h +++ b/includes/private/cpu/x86_ops_bcd.h @@ -1,107 +1,107 @@ #ifndef _X86_OPS_BCD_H_ #define _X86_OPS_BCD_H_ static int opAAA(uint32_t fetchdat) { - flags_rebuild(); - if ((cpu_state.flags & A_FLAG) || ((AL & 0xF) > 9)) { - AL += 6; - AH++; - cpu_state.flags |= (A_FLAG | C_FLAG); - } else - cpu_state.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; + flags_rebuild(); + if ((cpu_state.flags & A_FLAG) || ((AL & 0xF) > 9)) { + AL += 6; + AH++; + cpu_state.flags |= (A_FLAG | C_FLAG); + } else + cpu_state.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; + 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; + 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 ((cpu_state.flags & A_FLAG) || ((AL & 0xF) > 9)) { - AL -= 6; - AH--; - cpu_state.flags |= (A_FLAG | C_FLAG); - } else - cpu_state.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; + flags_rebuild(); + if ((cpu_state.flags & A_FLAG) || ((AL & 0xF) > 9)) { + AL -= 6; + AH--; + cpu_state.flags |= (A_FLAG | C_FLAG); + } else + cpu_state.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; + uint16_t tempw; - flags_rebuild(); - if ((cpu_state.flags & A_FLAG) || ((AL & 0xf) > 9)) { - int tempi = ((uint16_t)AL) + 6; - AL += 6; - cpu_state.flags |= A_FLAG; - if (tempi & 0x100) - cpu_state.flags |= C_FLAG; - } - if ((cpu_state.flags & C_FLAG) || (AL > 0x9f)) { - AL += 0x60; - cpu_state.flags |= C_FLAG; - } + flags_rebuild(); + if ((cpu_state.flags & A_FLAG) || ((AL & 0xf) > 9)) { + int tempi = ((uint16_t)AL) + 6; + AL += 6; + cpu_state.flags |= A_FLAG; + if (tempi & 0x100) + cpu_state.flags |= C_FLAG; + } + if ((cpu_state.flags & C_FLAG) || (AL > 0x9f)) { + AL += 0x60; + cpu_state.flags |= C_FLAG; + } - tempw = cpu_state.flags & (C_FLAG | A_FLAG); - setznp8(AL); - flags_rebuild(); - cpu_state.flags |= tempw; - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 1, -1, 0, 0, 0, 0, 0); + tempw = cpu_state.flags & (C_FLAG | A_FLAG); + setznp8(AL); + flags_rebuild(); + cpu_state.flags |= tempw; + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 0, 0, 0, 0, 0); - return 0; + return 0; } static int opDAS(uint32_t fetchdat) { - uint16_t tempw; + uint16_t tempw; - flags_rebuild(); - if ((cpu_state.flags & A_FLAG) || ((AL & 0xf) > 9)) { - int tempi = ((uint16_t)AL) - 6; - AL -= 6; - cpu_state.flags |= A_FLAG; - if (tempi & 0x100) - cpu_state.flags |= C_FLAG; - } - if ((cpu_state.flags & C_FLAG) || (AL > 0x9f)) { - AL -= 0x60; - cpu_state.flags |= C_FLAG; - } + flags_rebuild(); + if ((cpu_state.flags & A_FLAG) || ((AL & 0xf) > 9)) { + int tempi = ((uint16_t)AL) - 6; + AL -= 6; + cpu_state.flags |= A_FLAG; + if (tempi & 0x100) + cpu_state.flags |= C_FLAG; + } + if ((cpu_state.flags & C_FLAG) || (AL > 0x9f)) { + AL -= 0x60; + cpu_state.flags |= C_FLAG; + } - tempw = cpu_state.flags & (C_FLAG | A_FLAG); - setznp8(AL); - flags_rebuild(); - cpu_state.flags |= tempw; - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 1, -1, 0, 0, 0, 0, 0); + tempw = cpu_state.flags & (C_FLAG | A_FLAG); + setznp8(AL); + flags_rebuild(); + cpu_state.flags |= tempw; + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 0, 0, 0, 0, 0); - return 0; + return 0; } #endif /* _X86_OPS_BCD_H_ */ diff --git a/includes/private/cpu/x86_ops_bit.h b/includes/private/cpu/x86_ops_bit.h index dceb7a9f..65209a4e 100644 --- a/includes/private/cpu/x86_ops_bit.h +++ b/includes/private/cpu/x86_ops_bit.h @@ -1,372 +1,398 @@ #ifndef _X86_OPS_BIT_H_ #define _X86_OPS_BIT_H_ static int opBT_w_r_a16(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); - eal_r = 0; - temp = geteaw(); - if (cpu_state.abrt) - return 1; - flags_rebuild(); - if (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) - cpu_state.flags |= C_FLAG; - else - cpu_state.flags &= ~C_FLAG; + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); + eal_r = 0; + temp = geteaw(); + if (cpu_state.abrt) + return 1; + flags_rebuild(); + if (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, 1, 0, 0, 0, 0); - return 0; + 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; + uint16_t temp; - fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); - eal_r = 0; - temp = geteaw(); - if (cpu_state.abrt) - return 1; - flags_rebuild(); - if (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) - cpu_state.flags |= C_FLAG; - else - cpu_state.flags &= ~C_FLAG; + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); + eal_r = 0; + temp = geteaw(); + if (cpu_state.abrt) + return 1; + flags_rebuild(); + if (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, 1, 0, 0, 0, 1); - return 0; + 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; + uint32_t temp; - fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); - eal_r = 0; - temp = geteal(); - if (cpu_state.abrt) - return 1; - flags_rebuild(); - if (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) - cpu_state.flags |= C_FLAG; - else - cpu_state.flags &= ~C_FLAG; + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); + eal_r = 0; + temp = geteal(); + if (cpu_state.abrt) + return 1; + flags_rebuild(); + if (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, 0, 1, 0, 0, 0); - return 0; + 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; + uint32_t temp; - fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); - eal_r = 0; - temp = geteal(); - if (cpu_state.abrt) - return 1; - flags_rebuild(); - if (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) - cpu_state.flags |= C_FLAG; - else - cpu_state.flags &= ~C_FLAG; + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); + eal_r = 0; + temp = geteal(); + if (cpu_state.abrt) + return 1; + flags_rebuild(); + if (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, 0, 1, 0, 0, 1); - return 0; + 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); \ - if (cpu_mod != 3) \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - 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) cpu_state.flags |= C_FLAG; \ - else cpu_state.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); \ - if (cpu_mod != 3) \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - 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) cpu_state.flags |= C_FLAG; \ - else cpu_state.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); \ - if (cpu_mod != 3) \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - 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) cpu_state.flags |= C_FLAG; \ - else cpu_state.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); \ - if (cpu_mod != 3) \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - 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) cpu_state.flags |= C_FLAG; \ - else cpu_state.flags &= ~C_FLAG; \ - \ - CLOCK_CYCLES(6); \ - PREFETCH_RUN(6, 2, rmdat, 0,1,0,1, 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); \ + if (cpu_mod != 3) \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + 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) \ + cpu_state.flags |= C_FLAG; \ + else \ + cpu_state.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); \ + if (cpu_mod != 3) \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + 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) \ + cpu_state.flags |= C_FLAG; \ + else \ + cpu_state.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); \ + if (cpu_mod != 3) \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + 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) \ + cpu_state.flags |= C_FLAG; \ + else \ + cpu_state.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); \ + if (cpu_mod != 3) \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + 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) \ + cpu_state.flags |= C_FLAG; \ + else \ + cpu_state.flags &= ~C_FLAG; \ + \ + CLOCK_CYCLES(6); \ + PREFETCH_RUN(6, 2, rmdat, 0, 1, 0, 1, 1); \ + return 0; \ } -opBT(C, ^=) -opBT(R, &=~) -opBT(S, |=) +opBT(C, ^=) opBT(R, &= ~) opBT(S, |=) -static int opBA_w_a16(uint32_t fetchdat) { - int tempc, count; - uint16_t temp; + static int opBA_w_a16(uint32_t fetchdat) { + int tempc, count; + uint16_t temp; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteaw(); - count = getbyte(); - if (cpu_state.abrt) - return 1; - tempc = temp & (1 << count); - flags_rebuild(); - switch (rmdat & 0x38) { - case 0x20: /*BT w,imm*/ - if (tempc) - cpu_state.flags |= C_FLAG; - else - cpu_state.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; + 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) + cpu_state.flags |= C_FLAG; + else + cpu_state.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) - cpu_state.flags |= C_FLAG; - else - cpu_state.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; + 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) + cpu_state.flags |= C_FLAG; + else + cpu_state.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; + int tempc, count; + uint16_t temp; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteaw(); - count = getbyte(); - if (cpu_state.abrt) - return 1; - tempc = temp & (1 << count); - flags_rebuild(); - switch (rmdat & 0x38) { - case 0x20: /*BT w,imm*/ - if (tempc) - cpu_state.flags |= C_FLAG; - else - cpu_state.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; + 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) + cpu_state.flags |= C_FLAG; + else + cpu_state.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) - cpu_state.flags |= C_FLAG; - else - cpu_state.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; + 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) + cpu_state.flags |= C_FLAG; + else + cpu_state.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; + int tempc, count; + uint32_t temp; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteal(); - count = getbyte(); - if (cpu_state.abrt) - return 1; - tempc = temp & (1 << count); - flags_rebuild(); - switch (rmdat & 0x38) { - case 0x20: /*BT w,imm*/ - if (tempc) - cpu_state.flags |= C_FLAG; - else - cpu_state.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; + 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) + cpu_state.flags |= C_FLAG; + else + cpu_state.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) - cpu_state.flags |= C_FLAG; - else - cpu_state.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; + 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) + cpu_state.flags |= C_FLAG; + else + cpu_state.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; + int tempc, count; + uint32_t temp; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteal(); - count = getbyte(); - if (cpu_state.abrt) - return 1; - tempc = temp & (1 << count); - flags_rebuild(); - switch (rmdat & 0x38) { - case 0x20: /*BT w,imm*/ - if (tempc) - cpu_state.flags |= C_FLAG; - else - cpu_state.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; + 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) + cpu_state.flags |= C_FLAG; + else + cpu_state.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) - cpu_state.flags |= C_FLAG; - else - cpu_state.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; + 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) + cpu_state.flags |= C_FLAG; + else + cpu_state.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; } #endif /* _X86_OPS_BIT_H_ */ diff --git a/includes/private/cpu/x86_ops_bitscan.h b/includes/private/cpu/x86_ops_bitscan.h index f72a7f15..dd665131 100644 --- a/includes/private/cpu/x86_ops_bitscan.h +++ b/includes/private/cpu/x86_ops_bitscan.h @@ -1,170 +1,166 @@ #ifndef _X86_OPS_BITSCAN_H_ #define _X86_OPS_BITSCAN_H_ -#define BS_common(start, end, dir, dest, time) \ - flags_rebuild(); \ - instr_cycles = 0; \ - if (temp) \ - { \ - int c; \ - cpu_state.flags &= ~Z_FLAG; \ - for (c = start; c != end; c += dir) \ - { \ - CLOCK_CYCLES(time); \ - instr_cycles += time; \ - if (temp & (1 << c)) \ - { \ - dest = c; \ - break; \ - } \ - } \ - } \ - else \ +#define BS_common(start, end, dir, dest, time) \ + flags_rebuild(); \ + instr_cycles = 0; \ + if (temp) { \ + int c; \ + cpu_state.flags &= ~Z_FLAG; \ + for (c = start; c != end; c += dir) { \ + CLOCK_CYCLES(time); \ + instr_cycles += time; \ + if (temp & (1 << c)) { \ + dest = c; \ + break; \ + } \ + } \ + } else \ cpu_state.flags |= Z_FLAG; static int opBSF_w_a16(uint32_t fetchdat) { - uint16_t temp; - int instr_cycles; + uint16_t temp; + int instr_cycles; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteaw(); - if (cpu_state.abrt) - return 1; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; - BS_common(0, 16, 1, cpu_state.regs[cpu_reg].w, (is486) ? 1 : 3); + 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; + 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; + uint16_t temp; + int instr_cycles; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteaw(); - if (cpu_state.abrt) - return 1; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; - BS_common(0, 16, 1, cpu_state.regs[cpu_reg].w, (is486) ? 1 : 3); + 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; + 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; + uint32_t temp; + int instr_cycles; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteal(); - if (cpu_state.abrt) - return 1; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteal(); + if (cpu_state.abrt) + return 1; - BS_common(0, 32, 1, cpu_state.regs[cpu_reg].l, (is486) ? 1 : 3); + 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; + 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; + uint32_t temp; + int instr_cycles; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteal(); - if (cpu_state.abrt) - return 1; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteal(); + if (cpu_state.abrt) + return 1; - BS_common(0, 32, 1, cpu_state.regs[cpu_reg].l, (is486) ? 1 : 3); + 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; + 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; + uint16_t temp; + int instr_cycles; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteaw(); - if (cpu_state.abrt) - return 1; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; - BS_common(15, -1, -1, cpu_state.regs[cpu_reg].w, 3); + 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; + 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; + uint16_t temp; + int instr_cycles; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteaw(); - if (cpu_state.abrt) - return 1; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; - BS_common(15, -1, -1, cpu_state.regs[cpu_reg].w, 3); + 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; + 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; + uint32_t temp; + int instr_cycles; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteal(); - if (cpu_state.abrt) - return 1; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteal(); + if (cpu_state.abrt) + return 1; - BS_common(31, -1, -1, cpu_state.regs[cpu_reg].l, 3); + 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; + 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; + uint32_t temp; + int instr_cycles; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteal(); - if (cpu_state.abrt) - return 1; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteal(); + if (cpu_state.abrt) + return 1; - BS_common(31, -1, -1, cpu_state.regs[cpu_reg].l, 3); + 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; + 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; } #endif /* _X86_OPS_BITSCAN_H_ */ diff --git a/includes/private/cpu/x86_ops_call.h b/includes/private/cpu/x86_ops_call.h index a306260c..d340c4a6 100644 --- a/includes/private/cpu/x86_ops_call.h +++ b/includes/private/cpu/x86_ops_call.h @@ -1,555 +1,603 @@ #ifndef _X86_OPS_CALL_H_ #define _X86_OPS_CALL_H_ -#define CALL_FAR_w(new_seg, new_pc) \ - old_cs = CS; \ - old_pc = cpu_state.pc; \ - cpu_state.pc = new_pc; \ - optype = CALL; \ - cgate16 = cgate32 = 0; \ - if (msw & 1) loadcscall(new_seg, old_pc); \ - 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) { CS = old_cs; cgate16 = cgate32 = 0; return 1; } \ - PUSH_L(old_pc); if (cpu_state.abrt) { CS = old_cs; ESP = old_esp; return 1; } \ - } \ - else \ - { \ - uint32_t old_esp = ESP; \ - PUSH_W(old_cs); if (cpu_state.abrt) { CS = old_cs; cgate16 = cgate32 = 0; return 1; } \ - PUSH_W(old_pc); if (cpu_state.abrt) { CS = old_cs; ESP = old_esp; return 1; } \ +#define CALL_FAR_w(new_seg, new_pc) \ + old_cs = CS; \ + old_pc = cpu_state.pc; \ + cpu_state.pc = new_pc; \ + optype = CALL; \ + cgate16 = cgate32 = 0; \ + if (msw & 1) \ + loadcscall(new_seg, old_pc); \ + 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) { \ + CS = old_cs; \ + cgate16 = cgate32 = 0; \ + return 1; \ + } \ + PUSH_L(old_pc); \ + if (cpu_state.abrt) { \ + CS = old_cs; \ + ESP = old_esp; \ + return 1; \ + } \ + } else { \ + uint32_t old_esp = ESP; \ + PUSH_W(old_cs); \ + if (cpu_state.abrt) { \ + CS = old_cs; \ + cgate16 = cgate32 = 0; \ + return 1; \ + } \ + PUSH_W(old_pc); \ + if (cpu_state.abrt) { \ + CS = old_cs; \ + ESP = old_esp; \ + return 1; \ + } \ } -#define CALL_FAR_l(new_seg, new_pc) \ - old_cs = CS; \ - old_pc = cpu_state.pc; \ - cpu_state.pc = new_pc; \ - optype = CALL; \ - cgate16 = cgate32 = 0; \ - if (msw & 1) loadcscall(new_seg, old_pc); \ - 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) { CS = old_cs; cgate16 = cgate32 = 0; return 1; } \ - PUSH_W(old_pc); if (cpu_state.abrt) { CS = old_cs; ESP = old_esp; return 1; } \ - } \ - else \ - { \ - uint32_t old_esp = ESP; \ - PUSH_L(old_cs); if (cpu_state.abrt) { CS = old_cs; cgate16 = cgate32 = 0; return 1; } \ - PUSH_L(old_pc); if (cpu_state.abrt) { CS = old_cs; ESP = old_esp; return 1; } \ +#define CALL_FAR_l(new_seg, new_pc) \ + old_cs = CS; \ + old_pc = cpu_state.pc; \ + cpu_state.pc = new_pc; \ + optype = CALL; \ + cgate16 = cgate32 = 0; \ + if (msw & 1) \ + loadcscall(new_seg, old_pc); \ + 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) { \ + CS = old_cs; \ + cgate16 = cgate32 = 0; \ + return 1; \ + } \ + PUSH_W(old_pc); \ + if (cpu_state.abrt) { \ + CS = old_cs; \ + ESP = old_esp; \ + return 1; \ + } \ + } else { \ + uint32_t old_esp = ESP; \ + PUSH_L(old_cs); \ + if (cpu_state.abrt) { \ + CS = old_cs; \ + cgate16 = cgate32 = 0; \ + return 1; \ + } \ + PUSH_L(old_pc); \ + if (cpu_state.abrt) { \ + CS = old_cs; \ + ESP = old_esp; \ + return 1; \ + } \ } static int opCALL_far_w(uint32_t fetchdat) { - uint32_t old_cs, old_pc; - uint16_t new_cs, new_pc; - int cycles_old = cycles; - UNUSED(cycles_old); + uint32_t old_cs, old_pc; + uint16_t new_cs, new_pc; + int cycles_old = cycles; + UNUSED(cycles_old); - new_pc = getwordf(); - new_cs = getword(); - if (cpu_state.abrt) - return 1; + 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(); + 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; + 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; - UNUSED(cycles_old); + uint32_t old_cs, old_pc; + uint32_t new_cs, new_pc; + int cycles_old = cycles; + UNUSED(cycles_old); - new_pc = getlong(); - new_cs = getword(); - if (cpu_state.abrt) - return 1; + 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(); + 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; + 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; - UNUSED(cycles_old); + uint16_t old_cs, new_cs; + uint32_t old_pc, new_pc; + int cycles_old = cycles; + UNUSED(cycles_old); - uint16_t temp; + uint16_t temp; - fetch_ea_16(fetchdat); + fetch_ea_16(fetchdat); - switch (rmdat & 0x38) { - case 0x00: /*INC w*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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*/ - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - 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*/ - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - new_pc = readmemw(easeg, cpu_state.eaaddr); - new_cs = readmemw(easeg, (cpu_state.eaaddr + 2)); - if (cpu_state.abrt) - return 1; + switch (rmdat & 0x38) { + case 0x00: /*INC w*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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*/ + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + 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*/ + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + 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*/ - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - 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*/ - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - old_pc = 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, old_pc); - 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*/ - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - 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; + 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*/ + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + 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*/ + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + old_pc = 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, old_pc); + 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*/ + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + 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; + 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; - UNUSED(cycles_old); + uint16_t old_cs, new_cs; + uint32_t old_pc, new_pc; + int cycles_old = cycles; + UNUSED(cycles_old); - uint16_t temp; + uint16_t temp; - fetch_ea_32(fetchdat); + fetch_ea_32(fetchdat); - switch (rmdat & 0x38) { - case 0x00: /*INC w*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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*/ - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - 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*/ - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - new_pc = readmemw(easeg, cpu_state.eaaddr); - new_cs = readmemw(easeg, (cpu_state.eaaddr + 2)); - if (cpu_state.abrt) - return 1; + switch (rmdat & 0x38) { + case 0x00: /*INC w*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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*/ + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + 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*/ + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + 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*/ - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - 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*/ - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - old_pc = 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, old_pc); - 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*/ - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - 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; + 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*/ + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + 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*/ + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + old_pc = 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, old_pc); + 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*/ + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + 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; + 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; - UNUSED(cycles_old); + uint16_t old_cs, new_cs; + uint32_t old_pc, new_pc; + int cycles_old = cycles; + UNUSED(cycles_old); - uint32_t temp; + uint32_t temp; - fetch_ea_16(fetchdat); + fetch_ea_16(fetchdat); - switch (rmdat & 0x38) { - case 0x00: /*INC l*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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*/ - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - 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*/ - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - new_pc = readmeml(easeg, cpu_state.eaaddr); - new_cs = readmemw(easeg, (cpu_state.eaaddr + 4)); - if (cpu_state.abrt) - return 1; + switch (rmdat & 0x38) { + case 0x00: /*INC l*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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*/ + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + 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*/ + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + 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*/ - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - 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*/ - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - old_pc = 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, old_pc); - 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*/ - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - 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; + 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*/ + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + 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*/ + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + old_pc = 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, old_pc); + 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*/ + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + 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; + 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; - UNUSED(cycles_old); + uint16_t old_cs, new_cs; + uint32_t old_pc, new_pc; + int cycles_old = cycles; + UNUSED(cycles_old); - uint32_t temp; + uint32_t temp; - fetch_ea_32(fetchdat); + fetch_ea_32(fetchdat); - switch (rmdat & 0x38) { - case 0x00: /*INC l*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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*/ - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - 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*/ - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - new_pc = readmeml(easeg, cpu_state.eaaddr); - new_cs = readmemw(easeg, (cpu_state.eaaddr + 4)); - if (cpu_state.abrt) - return 1; + switch (rmdat & 0x38) { + case 0x00: /*INC l*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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*/ + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + 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*/ + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + 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*/ - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - 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*/ - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - old_pc = 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, old_pc); - 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*/ - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - 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; + 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*/ + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + 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*/ + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + old_pc = 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, old_pc); + 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*/ + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + 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; + default: + // fatal("Bad FF opcode %02X\n",rmdat&0x38); + x86illegal(); + } + return cpu_state.abrt; } #endif /* _X86_OPS_CALL_H_ */ diff --git a/includes/private/cpu/x86_ops_cyrix.h b/includes/private/cpu/x86_ops_cyrix.h index 5d0b7407..caf61f03 100644 --- a/includes/private/cpu/x86_ops_cyrix.h +++ b/includes/private/cpu/x86_ops_cyrix.h @@ -4,229 +4,231 @@ #ifndef _X86_OPS_CYRIX_H_ #define _X86_OPS_CYRIX_H_ static void opSVDC_common(uint32_t fetchdat) { - switch (rmdat & 0x38) { - case 0x00: /*ES*/ - cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_es); - writememw(0, easeg + cpu_state.eaaddr + 8, ES); - break; - case 0x08: /*CS*/ - cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_cs); - writememw(0, easeg + cpu_state.eaaddr + 8, CS); - break; - case 0x18: /*DS*/ - cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_ds); - writememw(0, easeg + cpu_state.eaaddr + 8, DS); - break; - case 0x10: /*SS*/ - cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_ss); - writememw(0, easeg + cpu_state.eaaddr + 8, SS); - break; - case 0x20: /*FS*/ - cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_fs); - writememw(0, easeg + cpu_state.eaaddr + 8, FS); - break; - case 0x28: /*GS*/ - cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_gs); - writememw(0, easeg + cpu_state.eaaddr + 8, GS); - break; - default:pclog("opSVDC: unknown rmdat %02x\n", rmdat); - x86illegal(); - } + switch (rmdat & 0x38) { + case 0x00: /*ES*/ + cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_es); + writememw(0, easeg + cpu_state.eaaddr + 8, ES); + break; + case 0x08: /*CS*/ + cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_cs); + writememw(0, easeg + cpu_state.eaaddr + 8, CS); + break; + case 0x18: /*DS*/ + cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_ds); + writememw(0, easeg + cpu_state.eaaddr + 8, DS); + break; + case 0x10: /*SS*/ + cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_ss); + writememw(0, easeg + cpu_state.eaaddr + 8, SS); + break; + case 0x20: /*FS*/ + cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_fs); + writememw(0, easeg + cpu_state.eaaddr + 8, FS); + break; + case 0x28: /*GS*/ + cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_gs); + writememw(0, easeg + cpu_state.eaaddr + 8, GS); + break; + default: + pclog("opSVDC: unknown rmdat %02x\n", rmdat); + x86illegal(); + } } static int opSVDC_a16(uint32_t fetchdat) { - if (cpu_cur_status & CPU_STATUS_SMM) { - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - opSVDC_common(fetchdat); - } else - x86illegal(); + if (cpu_cur_status & CPU_STATUS_SMM) { + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + opSVDC_common(fetchdat); + } else + x86illegal(); - return cpu_state.abrt; + return cpu_state.abrt; } static int opSVDC_a32(uint32_t fetchdat) { - if (cpu_cur_status & CPU_STATUS_SMM) { - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - opSVDC_common(fetchdat); - } else - x86illegal(); + if (cpu_cur_status & CPU_STATUS_SMM) { + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + opSVDC_common(fetchdat); + } else + x86illegal(); - return cpu_state.abrt; + return cpu_state.abrt; } static void opRSDC_common(uint32_t fetchdat) { - switch (rmdat & 0x38) { - case 0x00: /*ES*/ - cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_es); - break; - case 0x18: /*DS*/ - cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_ds); - break; - case 0x10: /*SS*/ - cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_ss); - break; - case 0x20: /*FS*/ - cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_fs); - break; - case 0x28: /*GS*/ - cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_gs); - break; - default:pclog("opRSDC: unknown rmdat %02x\n", rmdat); - x86illegal(); - } + switch (rmdat & 0x38) { + case 0x00: /*ES*/ + cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_es); + break; + case 0x18: /*DS*/ + cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_ds); + break; + case 0x10: /*SS*/ + cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_ss); + break; + case 0x20: /*FS*/ + cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_fs); + break; + case 0x28: /*GS*/ + cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_gs); + break; + default: + pclog("opRSDC: unknown rmdat %02x\n", rmdat); + x86illegal(); + } } static int opRSDC_a16(uint32_t fetchdat) { - if (cpu_cur_status & CPU_STATUS_SMM) { - fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - opRSDC_common(fetchdat); - } else - x86illegal(); + if (cpu_cur_status & CPU_STATUS_SMM) { + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + opRSDC_common(fetchdat); + } else + x86illegal(); - return cpu_state.abrt; + return cpu_state.abrt; } static int opRSDC_a32(uint32_t fetchdat) { - if (cpu_cur_status & CPU_STATUS_SMM) { - fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - opRSDC_common(fetchdat); - } else - x86illegal(); + if (cpu_cur_status & CPU_STATUS_SMM) { + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + opRSDC_common(fetchdat); + } else + x86illegal(); - return cpu_state.abrt; + return cpu_state.abrt; } static int opSVLDT_a16(uint32_t fetchdat) { - if (cpu_cur_status & CPU_STATUS_SMM) { - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &ldt); - writememw(0, easeg + cpu_state.eaaddr + 8, ldt.seg); - } else - x86illegal(); + if (cpu_cur_status & CPU_STATUS_SMM) { + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &ldt); + writememw(0, easeg + cpu_state.eaaddr + 8, ldt.seg); + } else + x86illegal(); - return cpu_state.abrt; + return cpu_state.abrt; } static int opSVLDT_a32(uint32_t fetchdat) { - if (cpu_cur_status & CPU_STATUS_SMM) { - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &ldt); - writememw(0, easeg + cpu_state.eaaddr + 8, ldt.seg); - } else - x86illegal(); + if (cpu_cur_status & CPU_STATUS_SMM) { + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &ldt); + writememw(0, easeg + cpu_state.eaaddr + 8, ldt.seg); + } else + x86illegal(); - return cpu_state.abrt; + return cpu_state.abrt; } static int opRSLDT_a16(uint32_t fetchdat) { - if (cpu_cur_status & CPU_STATUS_SMM) { - fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &ldt); - } else - x86illegal(); + if (cpu_cur_status & CPU_STATUS_SMM) { + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &ldt); + } else + x86illegal(); - return cpu_state.abrt; + return cpu_state.abrt; } static int opRSLDT_a32(uint32_t fetchdat) { - if (cpu_cur_status & CPU_STATUS_SMM) { - fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &ldt); - } else - x86illegal(); + if (cpu_cur_status & CPU_STATUS_SMM) { + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &ldt); + } else + x86illegal(); - return cpu_state.abrt; + return cpu_state.abrt; } static int opSVTS_a16(uint32_t fetchdat) { - if (cpu_cur_status & CPU_STATUS_SMM) { - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &tr); - writememw(0, easeg + cpu_state.eaaddr + 8, tr.seg); - } else - x86illegal(); + if (cpu_cur_status & CPU_STATUS_SMM) { + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &tr); + writememw(0, easeg + cpu_state.eaaddr + 8, tr.seg); + } else + x86illegal(); - return cpu_state.abrt; + return cpu_state.abrt; } static int opSVTS_a32(uint32_t fetchdat) { - if (cpu_cur_status & CPU_STATUS_SMM) { - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &tr); - writememw(0, easeg + cpu_state.eaaddr + 8, tr.seg); - } else - x86illegal(); + if (cpu_cur_status & CPU_STATUS_SMM) { + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &tr); + writememw(0, easeg + cpu_state.eaaddr + 8, tr.seg); + } else + x86illegal(); - return cpu_state.abrt; + return cpu_state.abrt; } static int opRSTS_a16(uint32_t fetchdat) { - if (cpu_cur_status & CPU_STATUS_SMM) { - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &tr); - writememw(0, easeg + cpu_state.eaaddr + 8, tr.seg); - } else - x86illegal(); + if (cpu_cur_status & CPU_STATUS_SMM) { + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &tr); + writememw(0, easeg + cpu_state.eaaddr + 8, tr.seg); + } else + x86illegal(); - return cpu_state.abrt; + return cpu_state.abrt; } static int opRSTS_a32(uint32_t fetchdat) { - if (cpu_cur_status & CPU_STATUS_SMM) { - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &tr); - writememw(0, easeg + cpu_state.eaaddr + 8, tr.seg); - } else - x86illegal(); + if (cpu_cur_status & CPU_STATUS_SMM) { + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &tr); + writememw(0, easeg + cpu_state.eaaddr + 8, tr.seg); + } else + x86illegal(); - return cpu_state.abrt; + return cpu_state.abrt; } static int opSMINT(uint32_t fetchdat) { - if (cpu_cur_status & CPU_STATUS_SMM) - fatal("opSMINT\n"); - else - x86illegal(); + if (cpu_cur_status & CPU_STATUS_SMM) + fatal("opSMINT\n"); + else + x86illegal(); - return 1; + return 1; } static int opRDSHR_a16(uint32_t fetchdat) { - if (cpu_cur_status & CPU_STATUS_SMM) - fatal("opRDSHR_a16\n"); - else - x86illegal(); + if (cpu_cur_status & CPU_STATUS_SMM) + fatal("opRDSHR_a16\n"); + else + x86illegal(); - return 1; + return 1; } static int opRDSHR_a32(uint32_t fetchdat) { - if (cpu_cur_status & CPU_STATUS_SMM) - fatal("opRDSHR_a32\n"); - else - x86illegal(); + if (cpu_cur_status & CPU_STATUS_SMM) + fatal("opRDSHR_a32\n"); + else + x86illegal(); - return 1; + return 1; } static int opWRSHR_a16(uint32_t fetchdat) { - if (cpu_cur_status & CPU_STATUS_SMM) - fatal("opWRSHR_a16\n"); - else - x86illegal(); + if (cpu_cur_status & CPU_STATUS_SMM) + fatal("opWRSHR_a16\n"); + else + x86illegal(); - return 1; + return 1; } static int opWRSHR_a32(uint32_t fetchdat) { - if (cpu_cur_status & CPU_STATUS_SMM) - fatal("opWRSHR_a32\n"); - else - x86illegal(); + if (cpu_cur_status & CPU_STATUS_SMM) + fatal("opWRSHR_a32\n"); + else + x86illegal(); - return 1; + return 1; } #endif /* _X86_OPS_CYRIX_H_ */ diff --git a/includes/private/cpu/x86_ops_flag.h b/includes/private/cpu/x86_ops_flag.h index 085b8b23..e7bd95da 100644 --- a/includes/private/cpu/x86_ops_flag.h +++ b/includes/private/cpu/x86_ops_flag.h @@ -1,255 +1,253 @@ #ifndef _X86_OPS_FLAG_H_ #define _X86_OPS_FLAG_H_ static int opCMC(uint32_t fetchdat) { - flags_rebuild(); - cpu_state.flags ^= C_FLAG; - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0); - return 0; + flags_rebuild(); + cpu_state.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(); - cpu_state.flags &= ~C_FLAG; - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0); - return 0; + flags_rebuild(); + cpu_state.flags &= ~C_FLAG; + CLOCK_CYCLES(2); + PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0); + return 0; } static int opCLD(uint32_t fetchdat) { - cpu_state.flags &= ~D_FLAG; - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0); - return 0; + cpu_state.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 ((!(cpu_state.eflags & VM_FLAG) && (cr4 & CR4_PVI)) || - ((cpu_state.eflags & VM_FLAG) && (cr4 & CR4_VME))) { - cpu_state.eflags &= ~VIF_FLAG; - } else { - x86gpf(NULL, 0); - return 1; - } - } else - cpu_state.flags &= ~I_FLAG; + if (!IOPLp) { + if ((!(cpu_state.eflags & VM_FLAG) && (cr4 & CR4_PVI)) || ((cpu_state.eflags & VM_FLAG) && (cr4 & CR4_VME))) { + cpu_state.eflags &= ~VIF_FLAG; + } else { + x86gpf(NULL, 0); + return 1; + } + } else + cpu_state.flags &= ~I_FLAG; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); - return 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; } static int opSTC(uint32_t fetchdat) { - flags_rebuild(); - cpu_state.flags |= C_FLAG; - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0); - return 0; + flags_rebuild(); + cpu_state.flags |= C_FLAG; + CLOCK_CYCLES(2); + PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0); + return 0; } static int opSTD(uint32_t fetchdat) { - cpu_state.flags |= D_FLAG; - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0); - return 0; + cpu_state.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 ((!(cpu_state.eflags & VM_FLAG) && (cr4 & CR4_PVI)) || - ((cpu_state.eflags & VM_FLAG) && (cr4 & CR4_VME))) { - if (cpu_state.eflags & VIP_FLAG) { - x86gpf(NULL, 0); - return 1; - } else - cpu_state.eflags |= VIF_FLAG; - } else { - x86gpf(NULL, 0); - return 1; - } - } else - cpu_state.flags |= I_FLAG; + if (!IOPLp) { + if ((!(cpu_state.eflags & VM_FLAG) && (cr4 & CR4_PVI)) || ((cpu_state.eflags & VM_FLAG) && (cr4 & CR4_VME))) { + if (cpu_state.eflags & VIP_FLAG) { + x86gpf(NULL, 0); + return 1; + } else + cpu_state.eflags |= VIF_FLAG; + } else { + x86gpf(NULL, 0); + return 1; + } + } else + cpu_state.flags |= I_FLAG; - /*First instruction after STI will always execute, regardless of whether - there is a pending interrupt*/ - cpu_end_block_after_ins = 2; + /*First instruction after STI will always execute, regardless of whether + there is a pending interrupt*/ + cpu_end_block_after_ins = 2; - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0); - return 0; + CLOCK_CYCLES(2); + PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0); + return 0; } static int opSAHF(uint32_t fetchdat) { - flags_rebuild(); - cpu_state.flags = (cpu_state.flags & 0xff00) | (AH & 0xd5) | 2; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + flags_rebuild(); + cpu_state.flags = (cpu_state.flags & 0xff00) | (AH & 0xd5) | 2; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); - codegen_flags_changed = 0; + codegen_flags_changed = 0; - return 0; + return 0; } static int opLAHF(uint32_t fetchdat) { - flags_rebuild(); - AH = cpu_state.flags & 0xff; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); - return 0; + flags_rebuild(); + AH = cpu_state.flags & 0xff; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; } static int opPUSHF(uint32_t fetchdat) { - if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) { - if (cr4 & CR4_VME) { - uint16_t temp; + if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) { + if (cr4 & CR4_VME) { + uint16_t temp; - flags_rebuild(); - temp = (cpu_state.flags & ~I_FLAG) | 0x3000; - if (cpu_state.eflags & VIF_FLAG) - temp |= I_FLAG; - PUSH_W(temp); - } else { - x86gpf(NULL, 0); - return 1; - } - } else { - flags_rebuild(); - PUSH_W(cpu_state.flags); - } - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 1, -1, 0, 0, 1, 0, 0); - return cpu_state.abrt; + flags_rebuild(); + temp = (cpu_state.flags & ~I_FLAG) | 0x3000; + if (cpu_state.eflags & VIF_FLAG) + temp |= I_FLAG; + PUSH_W(temp); + } else { + x86gpf(NULL, 0); + return 1; + } + } else { + flags_rebuild(); + PUSH_W(cpu_state.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 ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) { - x86gpf(NULL, 0); - return 1; - } - if (cpu_CR4_mask & CR4_VME) - tempw = cpu_state.eflags & 0x3c; - else if (CPUID) - tempw = cpu_state.eflags & 0x24; - else - tempw = cpu_state.eflags & 4; - flags_rebuild(); - PUSH_L(cpu_state.flags | (tempw << 16)); - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 1, -1, 0, 0, 0, 1, 0); - return cpu_state.abrt; + uint16_t tempw; + if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) { + x86gpf(NULL, 0); + return 1; + } + if (cpu_CR4_mask & CR4_VME) + tempw = cpu_state.eflags & 0x3c; + else if (CPUID) + tempw = cpu_state.eflags & 0x24; + else + tempw = cpu_state.eflags & 4; + flags_rebuild(); + PUSH_L(cpu_state.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; + uint16_t tempw; - if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) { - x86gpf(NULL, 0); - return 1; - } + if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) { + x86gpf(NULL, 0); + return 1; + } - tempw = POP_W(); - if (cpu_state.abrt) - return 1; + tempw = POP_W(); + if (cpu_state.abrt) + return 1; - if (!(msw & 1)) - cpu_state.flags = (cpu_state.flags & 0x7000) | (tempw & 0x0fd5) | 2; - else if (!(CPL)) - cpu_state.flags = (tempw & 0x7fd5) | 2; - else if (IOPLp) - cpu_state.flags = (cpu_state.flags & 0x3000) | (tempw & 0x4fd5) | 2; - else - cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2; - flags_extract(); + if (!(msw & 1)) + cpu_state.flags = (cpu_state.flags & 0x7000) | (tempw & 0x0fd5) | 2; + else if (!(CPL)) + cpu_state.flags = (tempw & 0x7fd5) | 2; + else if (IOPLp) + cpu_state.flags = (cpu_state.flags & 0x3000) | (tempw & 0x4fd5) | 2; + else + cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2; + flags_extract(); - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0); + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0); - codegen_flags_changed = 0; + codegen_flags_changed = 0; - return 0; + return 0; } static int opPOPF(uint32_t fetchdat) { - uint16_t tempw; + uint16_t tempw; - if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) { - if (cr4 & CR4_VME) { - uint32_t old_esp = ESP; + if ((cpu_state.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; - } + tempw = POP_W(); + if (cpu_state.abrt) { + ESP = old_esp; + return 1; + } - if ((tempw & T_FLAG) || ((tempw & I_FLAG) && (cpu_state.eflags & VIP_FLAG))) { - ESP = old_esp; - x86gpf(NULL, 0); - return 1; - } - if (tempw & I_FLAG) - cpu_state.eflags |= VIF_FLAG; - else - cpu_state.eflags &= ~VIF_FLAG; - cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2; - } else { - x86gpf(NULL, 0); - return 1; - } - } else { - tempw = POP_W(); - if (cpu_state.abrt) - return 1; + if ((tempw & T_FLAG) || ((tempw & I_FLAG) && (cpu_state.eflags & VIP_FLAG))) { + ESP = old_esp; + x86gpf(NULL, 0); + return 1; + } + if (tempw & I_FLAG) + cpu_state.eflags |= VIF_FLAG; + else + cpu_state.eflags &= ~VIF_FLAG; + cpu_state.flags = (cpu_state.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)) - cpu_state.flags = (tempw & 0x7fd5) | 2; - else if (IOPLp) - cpu_state.flags = (cpu_state.flags & 0x3000) | (tempw & 0x4fd5) | 2; - else - cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2; - } - flags_extract(); + if (!(CPL) || !(msw & 1)) + cpu_state.flags = (tempw & 0x7fd5) | 2; + else if (IOPLp) + cpu_state.flags = (cpu_state.flags & 0x3000) | (tempw & 0x4fd5) | 2; + else + cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2; + } + flags_extract(); - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0); + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0); - codegen_flags_changed = 0; + codegen_flags_changed = 0; - return 0; + return 0; } static int opPOPFD(uint32_t fetchdat) { - uint32_t templ; + uint32_t templ; - if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) { - x86gpf(NULL, 0); - return 1; - } + if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) { + x86gpf(NULL, 0); + return 1; + } - templ = POP_L(); - if (cpu_state.abrt) - return 1; + templ = POP_L(); + if (cpu_state.abrt) + return 1; - if (!(CPL) || !(msw & 1)) - cpu_state.flags = (templ & 0x7fd5) | 2; - else if (IOPLp) - cpu_state.flags = (cpu_state.flags & 0x3000) | (templ & 0x4fd5) | 2; - else - cpu_state.flags = (cpu_state.flags & 0x3200) | (templ & 0x4dd5) | 2; + if (!(CPL) || !(msw & 1)) + cpu_state.flags = (templ & 0x7fd5) | 2; + else if (IOPLp) + cpu_state.flags = (cpu_state.flags & 0x3000) | (templ & 0x4fd5) | 2; + else + cpu_state.flags = (cpu_state.flags & 0x3200) | (templ & 0x4dd5) | 2; - templ &= is486 ? 0x3c0000 : 0; - templ |= ((cpu_state.eflags & 3) << 16); - if (cpu_CR4_mask & CR4_VME) - cpu_state.eflags = (templ >> 16) & 0x3f; - else if (CPUID) - cpu_state.eflags = (templ >> 16) & 0x27; - else if (is486) - cpu_state.eflags = (templ >> 16) & 7; - else - cpu_state.eflags = (templ >> 16) & 3; + templ &= is486 ? 0x3c0000 : 0; + templ |= ((cpu_state.eflags & 3) << 16); + if (cpu_CR4_mask & CR4_VME) + cpu_state.eflags = (templ >> 16) & 0x3f; + else if (CPUID) + cpu_state.eflags = (templ >> 16) & 0x27; + else if (is486) + cpu_state.eflags = (templ >> 16) & 7; + else + cpu_state.eflags = (templ >> 16) & 3; - flags_extract(); + flags_extract(); - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 0, 1, 0, 0, 0); + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 0, 1, 0, 0, 0); - codegen_flags_changed = 0; + codegen_flags_changed = 0; - return 0; + return 0; } #endif /* _X86_OPS_FLAG_H_ */ diff --git a/includes/private/cpu/x86_ops_fpu.h b/includes/private/cpu/x86_ops_fpu.h index 1e4468ed..53d9665a 100644 --- a/includes/private/cpu/x86_ops_fpu.h +++ b/includes/private/cpu/x86_ops_fpu.h @@ -1,68 +1,36 @@ #ifndef _X86_OPS_FPU_H_ #define _X86_OPS_FPU_H_ -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_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_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_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_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_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_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_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 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; + if ((cr0 & 0xa) == 0xa) { + x86_int(7); + return 1; + } + CLOCK_CYCLES(4); + return 0; } #endif /* _X86_OPS_FPU_H_ */ diff --git a/includes/private/cpu/x86_ops_inc_dec.h b/includes/private/cpu/x86_ops_inc_dec.h index 9532bad5..340ed50e 100644 --- a/includes/private/cpu/x86_ops_inc_dec.h +++ b/includes/private/cpu/x86_ops_inc_dec.h @@ -1,13 +1,12 @@ #ifndef _X86_OPS_INC_DEC_H_ #define _X86_OPS_INC_DEC_H_ -#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; \ +#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) @@ -47,54 +46,54 @@ 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; + uint8_t temp; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteab(); - if (cpu_state.abrt) - return 1; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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; + 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; + uint8_t temp; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteab(); - if (cpu_state.abrt) - return 1; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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; + 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; } #endif /* _X86_OPS_INC_DEC_H_ */ diff --git a/includes/private/cpu/x86_ops_int.h b/includes/private/cpu/x86_ops_int.h index 1da45069..c84cf8d5 100644 --- a/includes/private/cpu/x86_ops_int.h +++ b/includes/private/cpu/x86_ops_int.h @@ -1,120 +1,120 @@ #ifndef _X86_OPS_INT_H_ #define _X86_OPS_INT_H_ static int opINT3(uint32_t fetchdat) { - int cycles_old = cycles; - UNUSED(cycles_old); - if ((cr0 & 1) && (cpu_state.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; + int cycles_old = cycles; + UNUSED(cycles_old); + if ((cr0 & 1) && (cpu_state.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; - UNUSED(cycles_old); - if ((cr0 & 1) && (cpu_state.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; + int cycles_old = cycles; + UNUSED(cycles_old); + if ((cr0 & 1) && (cpu_state.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; - UNUSED(cycles_old); - uint8_t temp = getbytef(); + int cycles_old = cycles; + UNUSED(cycles_old); + uint8_t temp = getbytef(); - if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) { - if (cr4 & CR4_VME) { - uint16_t t; - uint8_t d; + if ((cr0 & 1) && (cpu_state.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; + 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; + 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_expected(NULL, 0); - return 1; - } -// /*if (temp == 0x10 && AH == 0xe) */pclog("INT %02X : %04X %04X %04X %04X %c %04X:%04X\n", temp, AX, BX, CX, DX, (AL < 32) ? ' ' : AL, CS, pc); -// if (CS == 0x0028 && pc == 0xC03813C0) -// output = 3; -/* if (pc == 0x8028009A) - output = 3; - if (pc == 0x80282B6F) - { - __times++; - if (__times == 2) - fatal("WRONG\n"); + 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_expected(NULL, 0); + return 1; } - if (pc == 0x802809CE) - fatal("RIGHT\n");*/ -// if (CS == 0x0028 && pc == 0x80037FE9) -// output = 3; -//if (CS == 0x9087 && pc == 0x3763) -// fatal("Here\n"); -//if (CS==0x9087 && pc == 0x0850) -// output = 1; + // /*if (temp == 0x10 && AH == 0xe) */pclog("INT %02X : %04X %04X %04X %04X %c %04X:%04X\n", temp, AX, BX, CX, + // DX, (AL < 32) ? ' ' : AL, CS, pc); if (CS == 0x0028 && pc == 0xC03813C0) + // output = 3; + /* if (pc == 0x8028009A) + output = 3; + if (pc == 0x80282B6F) + { + __times++; + if (__times == 2) + fatal("WRONG\n"); + } + if (pc == 0x802809CE) + fatal("RIGHT\n");*/ + // if (CS == 0x0028 && pc == 0x80037FE9) + // output = 3; + // if (CS == 0x9087 && pc == 0x3763) + // fatal("Here\n"); + // if (CS==0x9087 && pc == 0x0850) + // output = 1; -/* if (output && pc == 0x80033008) - { - __times++; - if (__times == 2) - fatal("WRONG\n"); - }*/ -/* if (output && pc == 0x80D8) - { - __times++; - if (__times == 2) - fatal("RIGHT\n"); - }*/ + /* if (output && pc == 0x80033008) + { + __times++; + if (__times == 2) + fatal("WRONG\n"); + }*/ + /* if (output && pc == 0x80D8) + { + __times++; + if (__times == 2) + fatal("RIGHT\n"); + }*/ - x86_int_sw(temp); - PREFETCH_RUN(cycles_old - cycles, 2, -1, 0, 0, 0, 0, 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; - UNUSED(cycles_old); + int cycles_old = cycles; + UNUSED(cycles_old); - if ((cr0 & 1) && (cpu_state.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; + if ((cr0 & 1) && (cpu_state.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; } #endif /* _X86_OPS_INT_H_ */ diff --git a/includes/private/cpu/x86_ops_io.h b/includes/private/cpu/x86_ops_io.h index e39ad822..de16d310 100644 --- a/includes/private/cpu/x86_ops_io.h +++ b/includes/private/cpu/x86_ops_io.h @@ -1,163 +1,163 @@ #ifndef _X86_OPS_IO_H_ #define _X86_OPS_IO_H_ 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 (cpu_state.smi_pending) - return 1; - if (nmi && nmi_enable && nmi_mask) - return 1; - return 0; + 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 (cpu_state.smi_pending) + return 1; + 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 (cpu_state.smi_pending) - return 1; - if (nmi && nmi_enable && nmi_mask) - return 1; - return 0; + 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 (cpu_state.smi_pending) + return 1; + 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 (cpu_state.smi_pending) - return 1; - if (nmi && nmi_enable && nmi_mask) - return 1; - return 0; + 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 (cpu_state.smi_pending) + return 1; + 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 (cpu_state.smi_pending) - return 1; - if (nmi && nmi_enable && nmi_mask) - return 1; - if (port == 0x64) - return x86_was_reset; - return 0; + 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 (cpu_state.smi_pending) + return 1; + if (nmi && nmi_enable && nmi_mask) + return 1; + if (port == 0x64) + return x86_was_reset; + 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 (cpu_state.smi_pending) - return 1; - if (nmi && nmi_enable && nmi_mask) - return 1; - return 0; + 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 (cpu_state.smi_pending) + return 1; + 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 (cpu_state.smi_pending) - return 1; - if (nmi && nmi_enable && nmi_mask) - return 1; - return 0; + 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 (cpu_state.smi_pending) + return 1; + 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 (cpu_state.smi_pending) - return 1; - if (nmi && nmi_enable && nmi_mask) - return 1; - return 0; + check_io_perm(DX); + AL = inb(DX); + CLOCK_CYCLES(12); + PREFETCH_RUN(12, 1, -1, 1, 0, 0, 0, 0); + if (cpu_state.smi_pending) + return 1; + 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 (cpu_state.smi_pending) - return 1; - if (nmi && nmi_enable && nmi_mask) - return 1; - return 0; + 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 (cpu_state.smi_pending) + return 1; + 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 (cpu_state.smi_pending) - return 1; - if (nmi && nmi_enable && nmi_mask) - return 1; - return 0; + 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 (cpu_state.smi_pending) + return 1; + 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 (cpu_state.smi_pending) - return 1; - if (nmi && nmi_enable && nmi_mask) - return 1; - return x86_was_reset; + check_io_perm(DX); + outb(DX, AL); + CLOCK_CYCLES(11); + PREFETCH_RUN(11, 1, -1, 0, 0, 1, 0, 0); + if (cpu_state.smi_pending) + return 1; + if (nmi && nmi_enable && nmi_mask) + return 1; + return x86_was_reset; } static int opOUT_AX_DX(uint32_t fetchdat) { - //pclog("OUT_AX_DX %04X %04X\n", DX, AX); - 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 (cpu_state.smi_pending) - return 1; - if (nmi && nmi_enable && nmi_mask) - return 1; - return 0; + // pclog("OUT_AX_DX %04X %04X\n", DX, AX); + 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 (cpu_state.smi_pending) + return 1; + 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 (cpu_state.smi_pending) - return 1; - if (nmi && nmi_enable && nmi_mask) - return 1; - return 0; + 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 (cpu_state.smi_pending) + return 1; + if (nmi && nmi_enable && nmi_mask) + return 1; + return 0; } #endif /* _X86_OPS_IO_H_ */ diff --git a/includes/private/cpu/x86_ops_jump.h b/includes/private/cpu/x86_ops_jump.h index c158a88c..28f5cc32 100644 --- a/includes/private/cpu/x86_ops_jump.h +++ b/includes/private/cpu/x86_ops_jump.h @@ -1,370 +1,351 @@ #ifndef _X86_OPS_JUMP_H_ #define _X86_OPS_JUMP_H_ -#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_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_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; \ - if (!(cpu_state.op32 & 0x100)) \ - cpu_state.pc &= 0xffff; \ - CLOCK_CYCLES_ALWAYS(timing_bt); \ - CPU_BLOCK_END(); \ - PREFETCH_RUN(timing_bt+timing_bnt, 2, -1, 0,0,0,0, 0); \ - 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; \ - cpu_state.pc &= 0xffff; \ - CLOCK_CYCLES_ALWAYS(timing_bt); \ - CPU_BLOCK_END(); \ - PREFETCH_RUN(timing_bt+timing_bnt, 3, -1, 0,0,0,0, 0); \ - 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; \ - } \ +#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; \ + if (!(cpu_state.op32 & 0x100)) \ + cpu_state.pc &= 0xffff; \ + CLOCK_CYCLES_ALWAYS(timing_bt); \ + CPU_BLOCK_END(); \ + PREFETCH_RUN(timing_bt + timing_bnt, 2, -1, 0, 0, 0, 0, 0); \ + 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; \ + cpu_state.pc &= 0xffff; \ + CLOCK_CYCLES_ALWAYS(timing_bt); \ + CPU_BLOCK_END(); \ + PREFETCH_RUN(timing_bt + timing_bnt, 3, -1, 0, 0, 0, 0, 0); \ + 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) +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; - if (!(cpu_state.op32 & 0x100)) - cpu_state.pc &= 0xffff; - CPU_BLOCK_END(); - PREFETCH_FLUSH(); - return 1; - } - return 0; + 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; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; + 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; - if (!(cpu_state.op32 & 0x100)) - cpu_state.pc &= 0xffff; - CPU_BLOCK_END(); - PREFETCH_FLUSH(); - return 1; - } - return 0; + 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; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; + 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; - if (!(cpu_state.op32 & 0x100)) - cpu_state.pc &= 0xffff; - CPU_BLOCK_END(); - PREFETCH_FLUSH(); - return 1; - } - return 0; + 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; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; + 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; - if (!(cpu_state.op32 & 0x100)) - cpu_state.pc &= 0xffff; - CPU_BLOCK_END(); - PREFETCH_FLUSH(); - return 1; - } - return 0; + 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; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; + 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; - if (!(cpu_state.op32 & 0x100)) - cpu_state.pc &= 0xffff; - CPU_BLOCK_END(); - PREFETCH_FLUSH(); - return 1; - } - return 0; + 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; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; + 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; - if (!(cpu_state.op32 & 0x100)) - cpu_state.pc &= 0xffff; - CPU_BLOCK_END(); - PREFETCH_FLUSH(); - return 1; - } - return 0; + 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; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; + 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; - if (!(cpu_state.op32 & 0x100)) - cpu_state.pc &= 0xffff; - CLOCK_CYCLES(4); - CPU_BLOCK_END(); - PREFETCH_RUN(9, 2, -1, 0, 0, 0, 0, 0); - PREFETCH_FLUSH(); - return 1; - } - PREFETCH_RUN(5, 2, -1, 0, 0, 0, 0, 0); - return 0; + int8_t offset = (int8_t)getbytef(); + CLOCK_CYCLES(5); + if (!CX) { + cpu_state.pc += offset; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; + CLOCK_CYCLES(4); + CPU_BLOCK_END(); + PREFETCH_RUN(9, 2, -1, 0, 0, 0, 0, 0); + 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; - if (!(cpu_state.op32 & 0x100)) - cpu_state.pc &= 0xffff; - CLOCK_CYCLES(4); - CPU_BLOCK_END(); - PREFETCH_RUN(9, 2, -1, 0, 0, 0, 0, 0); - PREFETCH_FLUSH(); - return 1; - } - PREFETCH_RUN(5, 2, -1, 0, 0, 0, 0, 0); - return 0; + int8_t offset = (int8_t)getbytef(); + CLOCK_CYCLES(5); + if (!ECX) { + cpu_state.pc += offset; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; + CLOCK_CYCLES(4); + CPU_BLOCK_END(); + PREFETCH_RUN(9, 2, -1, 0, 0, 0, 0, 0); + 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; - if (!(cpu_state.op32 & 0x100)) - cpu_state.pc &= 0xffff; - CPU_BLOCK_END(); - CLOCK_CYCLES((is486) ? 3 : 7); - PREFETCH_RUN(7, 2, -1, 0, 0, 0, 0, 0); - PREFETCH_FLUSH(); - return 0; + int8_t offset = (int8_t)getbytef(); + cpu_state.pc += offset; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; + CPU_BLOCK_END(); + CLOCK_CYCLES((is486) ? 3 : 7); + PREFETCH_RUN(7, 2, -1, 0, 0, 0, 0, 0); + PREFETCH_FLUSH(); + return 0; } static int opJMP_r16(uint32_t fetchdat) { - int16_t offset = (int16_t)getwordf(); - cpu_state.pc += offset; - cpu_state.pc &= 0xffff; - CPU_BLOCK_END(); - CLOCK_CYCLES((is486) ? 3 : 7); - PREFETCH_RUN(7, 3, -1, 0, 0, 0, 0, 0); - PREFETCH_FLUSH(); - return 0; + int16_t offset = (int16_t)getwordf(); + cpu_state.pc += offset; + cpu_state.pc &= 0xffff; + CPU_BLOCK_END(); + CLOCK_CYCLES((is486) ? 3 : 7); + PREFETCH_RUN(7, 3, -1, 0, 0, 0, 0, 0); + 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; + 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 = getwordf(); - uint16_t seg = getword(); - if (cpu_state.abrt) - return 1; - uint32_t old_pc = cpu_state.pc; - cpu_state.pc = addr; - loadcsjmp(seg, old_pc); - CPU_BLOCK_END(); - PREFETCH_RUN(11, 5, -1, 0, 0, 0, 0, 0); - PREFETCH_FLUSH(); - return 0; + uint16_t addr = getwordf(); + uint16_t seg = getword(); + if (cpu_state.abrt) + return 1; + uint32_t old_pc = cpu_state.pc; + cpu_state.pc = addr; + loadcsjmp(seg, old_pc); + 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) { - uint32_t addr = getlong(); - uint16_t seg = getword(); - if (cpu_state.abrt) - return 1; - uint32_t old_pc = cpu_state.pc; - cpu_state.pc = addr; - loadcsjmp(seg, old_pc); - CPU_BLOCK_END(); - PREFETCH_RUN(11, 7, -1, 0, 0, 0, 0, 0); - PREFETCH_FLUSH(); - return 0; + uint32_t addr = getlong(); + uint16_t seg = getword(); + if (cpu_state.abrt) + return 1; + uint32_t old_pc = cpu_state.pc; + cpu_state.pc = addr; + loadcsjmp(seg, old_pc); + 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_state.pc &= 0xffff; - CPU_BLOCK_END(); - CLOCK_CYCLES((is486) ? 3 : 7); - PREFETCH_RUN(7, 3, -1, 0, 0, 1, 0, 0); - PREFETCH_FLUSH(); - return 0; + int16_t addr = (int16_t)getwordf(); + PUSH_W(cpu_state.pc); + cpu_state.pc += addr; + cpu_state.pc &= 0xffff; + CPU_BLOCK_END(); + CLOCK_CYCLES((is486) ? 3 : 7); + PREFETCH_RUN(7, 3, -1, 0, 0, 1, 0, 0); + 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; + 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; + uint16_t ret; - ret = POP_W(); - if (cpu_state.abrt) - return 1; - cpu_state.pc = ret; - CPU_BLOCK_END(); + 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; + 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; + uint32_t ret; - ret = POP_L(); - if (cpu_state.abrt) - return 1; - cpu_state.pc = ret; - CPU_BLOCK_END(); + 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; + 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 offset = getwordf(); - uint16_t ret; + uint16_t offset = getwordf(); + uint16_t ret; - ret = POP_W(); - if (cpu_state.abrt) - return 1; - if (stack32) - ESP += offset; - else - SP += offset; - cpu_state.pc = ret; - CPU_BLOCK_END(); + 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; + 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) { - uint16_t offset = getwordf(); - uint32_t ret; + uint16_t offset = getwordf(); + uint32_t ret; - ret = POP_L(); - if (cpu_state.abrt) - return 1; - if (stack32) - ESP += offset; - else - SP += offset; - cpu_state.pc = ret; - CPU_BLOCK_END(); + 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; + CLOCK_CYCLES((is486) ? 5 : 10); + PREFETCH_RUN(10, 5, -1, 0, 1, 0, 0, 0); + PREFETCH_FLUSH(); + return 0; } #endif /* _X86_OPS_JUMP_H_ */ diff --git a/includes/private/cpu/x86_ops_misc.h b/includes/private/cpu/x86_ops_misc.h index e14a29c6..97aa4f83 100644 --- a/includes/private/cpu/x86_ops_misc.h +++ b/includes/private/cpu/x86_ops_misc.h @@ -1,1016 +1,1041 @@ #ifndef _X86_OPS_MISC_H_ #define _X86_OPS_MISC_H_ 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; + 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; + 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; + 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; + 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; + 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; + 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; + int tempws, tempws2 = 0; + uint16_t tempw, src16; + uint8_t src, dst; + int8_t temps; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); - 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*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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) - cpu_state.flags |= (C_FLAG | V_FLAG); - else - cpu_state.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) - cpu_state.flags |= (C_FLAG | V_FLAG); - else - cpu_state.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(); - cpu_state.flags |= 0x8D5; /*Not a Cyrix*/ - cpu_state.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(); - cpu_state.flags |= 0x8D5; /*Not a Cyrix*/ - cpu_state.flags &= ~1; - } - } else { -// pclog("IDIVb exception - %X / %08X = %X\n", tempws, dst, tempws2); - x86_int(0); - return 1; - } - CLOCK_CYCLES(19); - PREFETCH_RUN(19, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); - break; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + 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*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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) + cpu_state.flags |= (C_FLAG | V_FLAG); + else + cpu_state.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) + cpu_state.flags |= (C_FLAG | V_FLAG); + else + cpu_state.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(); + cpu_state.flags |= 0x8D5; /*Not a Cyrix*/ + cpu_state.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(); + cpu_state.flags |= 0x8D5; /*Not a Cyrix*/ + cpu_state.flags &= ~1; + } + } else { + // pclog("IDIVb exception - %X / %08X = %X\n", tempws, dst, tempws2); + 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; + 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; + int tempws, tempws2 = 0; + uint16_t tempw, src16; + uint8_t src, dst; + int8_t temps; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - 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*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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) - cpu_state.flags |= (C_FLAG | V_FLAG); - else - cpu_state.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) - cpu_state.flags |= (C_FLAG | V_FLAG); - else - cpu_state.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(); - cpu_state.flags |= 0x8D5; /*Not a Cyrix*/ - cpu_state.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(); - cpu_state.flags |= 0x8D5; /*Not a Cyrix*/ - cpu_state.flags &= ~1; - } - } else { -// pclog("IDIVb exception - %X / %08X = %X\n", tempws, dst, tempws2); - x86_int(0); - return 1; - } - CLOCK_CYCLES(19); - PREFETCH_RUN(19, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); - break; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + 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*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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) + cpu_state.flags |= (C_FLAG | V_FLAG); + else + cpu_state.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) + cpu_state.flags |= (C_FLAG | V_FLAG); + else + cpu_state.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(); + cpu_state.flags |= 0x8D5; /*Not a Cyrix*/ + cpu_state.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(); + cpu_state.flags |= 0x8D5; /*Not a Cyrix*/ + cpu_state.flags &= ~1; + } + } else { + // pclog("IDIVb exception - %X / %08X = %X\n", tempws, dst, tempws2); + 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; + 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; + uint32_t templ, templ2; + int tempws, tempws2 = 0; + int16_t temps16; + uint16_t src, dst; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - 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*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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) - cpu_state.flags |= (C_FLAG | V_FLAG); - else - cpu_state.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) - cpu_state.flags |= (C_FLAG | V_FLAG); - else - cpu_state.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 { -// fatal("DIVw BY 0 %04X:%04X %i\n",cs>>4,pc,ins); - 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 { -// pclog("IDIVw exception - %X / %08X = %X\n",tempws, dst, tempws2); - x86_int(0); - return 1; - } - CLOCK_CYCLES(27); - PREFETCH_RUN(27, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); - break; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + 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*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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) + cpu_state.flags |= (C_FLAG | V_FLAG); + else + cpu_state.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) + cpu_state.flags |= (C_FLAG | V_FLAG); + else + cpu_state.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 { + // fatal("DIVw BY 0 %04X:%04X %i\n",cs>>4,pc,ins); + 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 { + // pclog("IDIVw exception - %X / %08X = %X\n",tempws, dst, tempws2); + 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; + 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 = 1; - int16_t temps16; - uint16_t src, dst; + uint32_t templ, templ2; + int tempws, tempws2 = 1; + int16_t temps16; + uint16_t src, dst; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - 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*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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) - cpu_state.flags |= (C_FLAG | V_FLAG); - else - cpu_state.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) - cpu_state.flags |= (C_FLAG | V_FLAG); - else - cpu_state.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 { -// fatal("DIVw BY 0 %04X:%04X %i\n",cs>>4,pc,ins); - 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 { -// pclog("IDIVw exception - %X / %08X = %X\n", tempws, dst, tempws2); - x86_int(0); - return 1; - } - CLOCK_CYCLES(27); - PREFETCH_RUN(27, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); - break; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + 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*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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) + cpu_state.flags |= (C_FLAG | V_FLAG); + else + cpu_state.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) + cpu_state.flags |= (C_FLAG | V_FLAG); + else + cpu_state.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 { + // fatal("DIVw BY 0 %04X:%04X %i\n",cs>>4,pc,ins); + 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 { + // pclog("IDIVw exception - %X / %08X = %X\n", tempws, dst, tempws2); + 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; + 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; + uint64_t temp64; + uint32_t src, dst; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - dst = geteal(); - if (cpu_state.abrt) - return 1; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + 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*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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) - cpu_state.flags |= (C_FLAG | V_FLAG); - else - cpu_state.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) - cpu_state.flags |= (C_FLAG | V_FLAG); - else - cpu_state.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; + 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*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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) + cpu_state.flags |= (C_FLAG | V_FLAG); + else + cpu_state.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) + cpu_state.flags |= (C_FLAG | V_FLAG); + else + cpu_state.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; + 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; + uint64_t temp64; + uint32_t src, dst; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - dst = geteal(); - if (cpu_state.abrt) - return 1; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + 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*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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) - cpu_state.flags |= (C_FLAG | V_FLAG); - else - cpu_state.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) - cpu_state.flags |= (C_FLAG | V_FLAG); - else - cpu_state.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; + 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*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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) + cpu_state.flags |= (C_FLAG | V_FLAG); + else + cpu_state.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) + cpu_state.flags |= (C_FLAG | V_FLAG); + else + cpu_state.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; + default: + pclog("Bad F7 opcode %02X\n", rmdat & 0x38); + x86illegal(); + } + return 0; } static int opHLT(uint32_t fetchdat) { - if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { - x86gpf(NULL, 0); - return 1; - } - if (!((cpu_state.flags & I_FLAG) && pic_intpending)) { - CLOCK_CYCLES_ALWAYS(100); - cpu_state.pc--; - } else - CLOCK_CYCLES(5); + if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + x86gpf(NULL, 0); + return 1; + } + if (!((cpu_state.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); + CPU_BLOCK_END(); + PREFETCH_RUN(100, 1, -1, 0, 0, 0, 0, 0); - return 0; + return 0; } static int opLOCK(uint32_t fetchdat) { - fetchdat = fastreadl(cs + cpu_state.pc); - if (cpu_state.abrt) - return 0; - cpu_state.pc++; + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) + return 0; + cpu_state.pc++; - ILLEGAL_ON((fetchdat & 0xff) == 0x90); + ILLEGAL_ON((fetchdat & 0xff) == 0x90); - CLOCK_CYCLES(4); - PREFETCH_PREFIX(); - return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + 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; + int16_t low, high; - fetch_ea_16(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - SEG_CHECK_READ(cpu_state.ea_seg); - low = geteaw(); - high = readmemw(easeg, cpu_state.eaaddr + 2); - if (cpu_state.abrt) - return 1; + fetch_ea_16(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); + 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; - } + 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; + 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; + int16_t low, high; - fetch_ea_32(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - SEG_CHECK_READ(cpu_state.ea_seg); - low = geteaw(); - high = readmemw(easeg, cpu_state.eaaddr + 2); - if (cpu_state.abrt) - return 1; + fetch_ea_32(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); + 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; - } + 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; + 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; + int32_t low, high; - fetch_ea_16(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - SEG_CHECK_READ(cpu_state.ea_seg); - low = geteal(); - high = readmeml(easeg, cpu_state.eaaddr + 4); - if (cpu_state.abrt) - return 1; + fetch_ea_16(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); + 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; - } + 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; + 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; + int32_t low, high; - fetch_ea_32(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - SEG_CHECK_READ(cpu_state.ea_seg); - low = geteal(); - high = readmeml(easeg, cpu_state.eaaddr + 4); - if (cpu_state.abrt) - return 1; + fetch_ea_32(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); + 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; - } + 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; + 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 || (cpu_state.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; + if ((CPL || (cpu_state.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; + 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; + 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); - cpu_state.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); - cpu_state.seg_es.access = readmemb(0, 0x839); - cpu_state.seg_es.limit = readmemw(0, 0x83A); - cs = readmemw(0, 0x83C) | (readmemb(0, 0x83E) << 16); - cpu_state.seg_cs.access = readmemb(0, 0x83F); - cpu_state.seg_cs.limit = readmemw(0, 0x840); - ss = readmemw(0, 0x842) | (readmemb(0, 0x844) << 16); - cpu_state.seg_ss.access = readmemb(0, 0x845); - cpu_state.seg_ss.limit = readmemw(0, 0x846); - if (cpu_state.seg_ss.base == 0 && cpu_state.seg_ss.limit_low == 0 && cpu_state.seg_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); - cpu_state.seg_ds.access = readmemb(0, 0x84B); - cpu_state.seg_ds.limit = readmemw(0, 0x84C); - if (cpu_state.seg_ds.base == 0 && cpu_state.seg_ds.limit_low == 0 && cpu_state.seg_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; + if (CPL && (cr0 & 1)) { + x86gpf(NULL, 0); + return 1; + } + msw = (msw & 1) | readmemw(0, 0x806); + cpu_state.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); + cpu_state.seg_es.access = readmemb(0, 0x839); + cpu_state.seg_es.limit = readmemw(0, 0x83A); + cs = readmemw(0, 0x83C) | (readmemb(0, 0x83E) << 16); + cpu_state.seg_cs.access = readmemb(0, 0x83F); + cpu_state.seg_cs.limit = readmemw(0, 0x840); + ss = readmemw(0, 0x842) | (readmemb(0, 0x844) << 16); + cpu_state.seg_ss.access = readmemb(0, 0x845); + cpu_state.seg_ss.limit = readmemw(0, 0x846); + if (cpu_state.seg_ss.base == 0 && cpu_state.seg_ss.limit_low == 0 && cpu_state.seg_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); + cpu_state.seg_ds.access = readmemb(0, 0x84B); + cpu_state.seg_ds.limit = readmemw(0, 0x84C); + if (cpu_state.seg_ds.base == 0 && cpu_state.seg_ds.limit_low == 0 && cpu_state.seg_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; - } + 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); + 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 == &cpu_state.seg_cs) - use32 = (segdat3 & 0x40) ? 0x300 : 0; - if (s == &cpu_state.seg_ss) - stack32 = (segdat3 & 0x40) ? 1 : 0; + if (s == &cpu_state.seg_cs) + use32 = (segdat3 & 0x40) ? 0x300 : 0; + if (s == &cpu_state.seg_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; + 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); + set_segment_limit(s, segdat3); - if (s == &cpu_state.seg_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 == &cpu_state.seg_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; - } + if (s == &cpu_state.seg_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 == &cpu_state.seg_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; + uint32_t la_addr = es + EDI; - cr0 = readmeml(0, la_addr); - cpu_state.flags = readmemw(0, la_addr + 4); - cpu_state.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); + cr0 = readmeml(0, la_addr); + cpu_state.flags = readmemw(0, la_addr + 4); + cpu_state.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, &cpu_state.seg_gs); - loadall_load_segment(la_addr + 0x90, &cpu_state.seg_fs); - loadall_load_segment(la_addr + 0x9c, &cpu_state.seg_ds); - loadall_load_segment(la_addr + 0xa8, &cpu_state.seg_ss); - loadall_load_segment(la_addr + 0xb4, &cpu_state.seg_cs); - loadall_load_segment(la_addr + 0xc0, &cpu_state.seg_es); + 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, &cpu_state.seg_gs); + loadall_load_segment(la_addr + 0x90, &cpu_state.seg_fs); + loadall_load_segment(la_addr + 0x9c, &cpu_state.seg_ds); + loadall_load_segment(la_addr + 0xa8, &cpu_state.seg_ss); + loadall_load_segment(la_addr + 0xb4, &cpu_state.seg_cs); + loadall_load_segment(la_addr + 0xc0, &cpu_state.seg_es); - if (CPL == 3 && oldcpl != 3) - flushmmucache_cr3(); - oldcpl = CPL; + if (CPL == 3 && oldcpl != 3) + flushmmucache_cr3(); + oldcpl = CPL; - CLOCK_CYCLES(350); - return 0; + 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; + 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_has_feature(CPU_FEATURE_MSR)) { - cpu_RDMSR(); - CLOCK_CYCLES(9); - return 0; - } - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - return 1; + if (cpu_has_feature(CPU_FEATURE_MSR)) { + cpu_RDMSR(); + CLOCK_CYCLES(9); + return 0; + } + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + return 1; } static int opWRMSR(uint32_t fetchdat) { - if (cpu_has_feature(CPU_FEATURE_MSR)) { - cpu_WRMSR(); - CLOCK_CYCLES(9); - return 0; - } - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - return 1; + if (cpu_has_feature(CPU_FEATURE_MSR)) { + cpu_WRMSR(); + CLOCK_CYCLES(9); + return 0; + } + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + return 1; } static int opSYSENTER(uint32_t fetchdat) { - if (!(cr0 & 1) || !(sysenter_cs & 0xfffc)) { - x86gpf(NULL, 0); - return 1; - } -// pclog("opSYSENTER: CS=%04x EIP=%08x ESP=%08x %04x:%08x %i\n", sysenter_cs, sysenter_eip, sysenter_esp, CS,cpu_state.pc, times); - sysenter(); - CPU_BLOCK_END(); - return 0; + if (!(cr0 & 1) || !(sysenter_cs & 0xfffc)) { + x86gpf(NULL, 0); + return 1; + } + // pclog("opSYSENTER: CS=%04x EIP=%08x ESP=%08x %04x:%08x %i\n", sysenter_cs, sysenter_eip, sysenter_esp, + // CS,cpu_state.pc, times); + sysenter(); + CPU_BLOCK_END(); + return 0; } static int opSYSEXIT(uint32_t fetchdat) { - if (!(cr0 & 1) || !(sysenter_cs & 0xfffc) || CPL) { - x86gpf(NULL, 0); - return 1; - } -// pclog("opSYSEXIT\n"); - sysexit(); - CPU_BLOCK_END(); - return 0; + if (!(cr0 & 1) || !(sysenter_cs & 0xfffc) || CPL) { + x86gpf(NULL, 0); + return 1; + } + // pclog("opSYSEXIT\n"); + sysexit(); + CPU_BLOCK_END(); + return 0; } static int opHINTNOP_a16(uint32_t fetchdat) { - fetch_ea_16(fetchdat); - return 0; + fetch_ea_16(fetchdat); + return 0; } static int opHINTNOP_a32(uint32_t fetchdat) { - fetch_ea_32(fetchdat); - return 0; + fetch_ea_32(fetchdat); + return 0; } #endif /* _X86_OPS_MISC_H_ */ diff --git a/includes/private/cpu/x86_ops_mmx.h b/includes/private/cpu/x86_ops_mmx.h index 68bfcd79..8c2c554a 100644 --- a/includes/private/cpu/x86_ops_mmx.h +++ b/includes/private/cpu/x86_ops_mmx.h @@ -5,46 +5,43 @@ #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 \ - { \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - src.q = readmemq(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; \ - CLOCK_CYCLES(2); \ +#define MMX_GETSRC() \ + if (cpu_mod == 3) { \ + src = cpu_state.MM[cpu_rm]; \ + CLOCK_CYCLES(1); \ + } else { \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + src.q = readmemq(easeg, cpu_state.eaaddr); \ + if (cpu_state.abrt) \ + return 1; \ + CLOCK_CYCLES(2); \ } -#define MMX_ENTER() \ - if (!cpu_has_feature(CPU_FEATURE_MMX)) \ - { \ - cpu_state.pc = cpu_state.oldpc; \ - x86illegal(); \ - return 1; \ - } \ - if (cr0 & 0xc) \ - { \ - x86_int(7); \ - return 1; \ - } \ +#define MMX_ENTER() \ + if (!cpu_has_feature(CPU_FEATURE_MMX)) { \ + 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_has_feature(CPU_FEATURE_MMX)) { - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - return 1; - } - if (cr0 & 0xc) { - x86_int(7); - return 1; - } - x87_emms(); - CLOCK_CYCLES(100); /*Guess*/ - return 0; + if (!cpu_has_feature(CPU_FEATURE_MMX)) { + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + return 1; + } + if (cr0 & 0xc) { + x86_int(7); + return 1; + } + x87_emms(); + CLOCK_CYCLES(100); /*Guess*/ + return 0; } #endif /* _X86_OPS_MMX_H_ */ diff --git a/includes/private/cpu/x86_ops_mmx_arith.h b/includes/private/cpu/x86_ops_mmx_arith.h index 11ceb77f..2eb5fb96 100644 --- a/includes/private/cpu/x86_ops_mmx_arith.h +++ b/includes/private/cpu/x86_ops_mmx_arith.h @@ -1,594 +1,598 @@ #ifndef _X86_OPS_MMX_ARITH_H_ #define _X86_OPS_MMX_ARITH_H_ static int opPADDB_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + 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]; + 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; + return 0; } static int opPADDB_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + 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]; + 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; + return 0; } static int opPADDW_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + 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]; + 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; + return 0; } static int opPADDW_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + 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]; + 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; + return 0; } static int opPADDD_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + 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]; + cpu_state.MM[cpu_reg].l[0] += src.l[0]; + cpu_state.MM[cpu_reg].l[1] += src.l[1]; - return 0; + return 0; } static int opPADDD_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + 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]; + cpu_state.MM[cpu_reg].l[0] += src.l[0]; + cpu_state.MM[cpu_reg].l[1] += src.l[1]; - return 0; + return 0; } static int opPADDSB_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + 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]); + 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; + return 0; } static int opPADDSB_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + 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]); + 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; + return 0; } static int opPADDUSB_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + 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]); + 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; + return 0; } static int opPADDUSB_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + 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]); + 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; + return 0; } static int opPADDSW_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + 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]); + 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; + return 0; } static int opPADDSW_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + 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]); + 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; + return 0; } static int opPADDUSW_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + 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]); + 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; + return 0; } static int opPADDUSW_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + 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]); + 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; + return 0; } static int opPMADDWD_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + 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[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]); + 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; + return 0; } static int opPMADDWD_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + 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[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]); + 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; + return 0; } static int opPMULLW_a16(uint32_t fetchdat) { - MMX_ENTER(); + 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; + 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; - SEG_CHECK_READ(cpu_state.ea_seg); - src.l[0] = readmeml(easeg, cpu_state.eaaddr); - src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); - if (cpu_state.abrt) - return 0; - cpu_state.MM[cpu_reg].w[0] *= 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; + SEG_CHECK_READ(cpu_state.ea_seg); + src.l[0] = readmeml(easeg, cpu_state.eaaddr); + src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) + return 0; + cpu_state.MM[cpu_reg].w[0] *= 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(); + 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; + 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; - SEG_CHECK_READ(cpu_state.ea_seg); - src.l[0] = readmeml(easeg, cpu_state.eaaddr); - src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); - if (cpu_state.abrt) - return 0; - cpu_state.MM[cpu_reg].w[0] *= 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; + SEG_CHECK_READ(cpu_state.ea_seg); + src.l[0] = readmeml(easeg, cpu_state.eaaddr); + src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) + return 0; + cpu_state.MM[cpu_reg].w[0] *= 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(); + 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; + 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; - SEG_CHECK_READ(cpu_state.ea_seg); - src.l[0] = readmeml(easeg, cpu_state.eaaddr); - src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); - if (cpu_state.abrt) - return 0; - cpu_state.MM[cpu_reg].w[0] = ((int32_t)cpu_state.MM[cpu_reg].sw[0] * (int32_t)src.sw[0]) >> 16; - 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; + SEG_CHECK_READ(cpu_state.ea_seg); + src.l[0] = readmeml(easeg, cpu_state.eaaddr); + src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) + return 0; + cpu_state.MM[cpu_reg].w[0] = ((int32_t)cpu_state.MM[cpu_reg].sw[0] * (int32_t)src.sw[0]) >> 16; + 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(); + 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; + 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; - SEG_CHECK_READ(cpu_state.ea_seg); - src.l[0] = readmeml(easeg, cpu_state.eaaddr); - src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); - if (cpu_state.abrt) - return 0; - cpu_state.MM[cpu_reg].w[0] = ((int32_t)cpu_state.MM[cpu_reg].sw[0] * (int32_t)src.sw[0]) >> 16; - 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; + SEG_CHECK_READ(cpu_state.ea_seg); + src.l[0] = readmeml(easeg, cpu_state.eaaddr); + src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) + return 0; + cpu_state.MM[cpu_reg].w[0] = ((int32_t)cpu_state.MM[cpu_reg].sw[0] * (int32_t)src.sw[0]) >> 16; + 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(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + 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]; + 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; + return 0; } static int opPSUBB_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + 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]; + 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; + return 0; } static int opPSUBW_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + 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]; + 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; + return 0; } static int opPSUBW_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + 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]; + 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; + return 0; } static int opPSUBD_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + 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]; + cpu_state.MM[cpu_reg].l[0] -= src.l[0]; + cpu_state.MM[cpu_reg].l[1] -= src.l[1]; - return 0; + return 0; } static int opPSUBD_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + 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]; + cpu_state.MM[cpu_reg].l[0] -= src.l[0]; + cpu_state.MM[cpu_reg].l[1] -= src.l[1]; - return 0; + return 0; } static int opPSUBSB_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + 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]); + 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; + return 0; } static int opPSUBSB_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + 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]); + 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; + return 0; } static int opPSUBUSB_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + 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]); + 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; + return 0; } static int opPSUBUSB_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + 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]); + 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; + return 0; } static int opPSUBSW_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + 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]); + 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; + return 0; } static int opPSUBSW_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + 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]); + 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; + return 0; } static int opPSUBUSW_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + 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]); + 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; + return 0; } static int opPSUBUSW_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + 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]); + 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; + return 0; } #endif /* _X86_OPS_MMX_ARITH_H_ */ diff --git a/includes/private/cpu/x86_ops_mmx_cmp.h b/includes/private/cpu/x86_ops_mmx_cmp.h index b7470f86..b3d9c0cd 100644 --- a/includes/private/cpu/x86_ops_mmx_cmp.h +++ b/includes/private/cpu/x86_ops_mmx_cmp.h @@ -1,197 +1,197 @@ #ifndef _X86_OPS_MMX_CMP_H_ #define _X86_OPS_MMX_CMP_H_ static int opPCMPEQB_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + 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; + 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; + return 0; } static int opPCMPEQB_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + 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; + 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; + return 0; } static int opPCMPGTB_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + 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; + 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; + return 0; } static int opPCMPGTB_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + 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; + 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; + return 0; } static int opPCMPEQW_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + 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; + 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; + return 0; } static int opPCMPEQW_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + 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; + 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; + return 0; } static int opPCMPGTW_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + 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; + 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; + return 0; } static int opPCMPGTW_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + 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; + 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; + return 0; } static int opPCMPEQD_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + 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; + 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; + return 0; } static int opPCMPEQD_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(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; + 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; + return 0; } static int opPCMPGTD_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + 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; + 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; + return 0; } static int opPCMPGTD_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(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; + 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; + return 0; } #endif /* _X86_OPS_MMX_CMP_H_ */ diff --git a/includes/private/cpu/x86_ops_mmx_logic.h b/includes/private/cpu/x86_ops_mmx_logic.h index 016580d9..37e422b9 100644 --- a/includes/private/cpu/x86_ops_mmx_logic.h +++ b/includes/private/cpu/x86_ops_mmx_logic.h @@ -1,87 +1,87 @@ #ifndef _X86_OPS_MMX_LOGIC_H_ #define _X86_OPS_MMX_LOGIC_H_ static int opPAND_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].q &= src.q; - return 0; + cpu_state.MM[cpu_reg].q &= src.q; + return 0; } static int opPAND_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].q &= src.q; - return 0; + cpu_state.MM[cpu_reg].q &= src.q; + return 0; } static int opPANDN_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].q = ~cpu_state.MM[cpu_reg].q & src.q; - return 0; + 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(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].q = ~cpu_state.MM[cpu_reg].q & src.q; - return 0; + 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(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].q |= src.q; - return 0; + cpu_state.MM[cpu_reg].q |= src.q; + return 0; } static int opPOR_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].q |= src.q; - return 0; + cpu_state.MM[cpu_reg].q |= src.q; + return 0; } static int opPXOR_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].q ^= src.q; - return 0; + cpu_state.MM[cpu_reg].q ^= src.q; + return 0; } static int opPXOR_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].q ^= src.q; - return 0; + cpu_state.MM[cpu_reg].q ^= src.q; + return 0; } #endif /* _X86_OPS_MMX_LOGIC_H_ */ diff --git a/includes/private/cpu/x86_ops_mmx_mov.h b/includes/private/cpu/x86_ops_mmx_mov.h index 3732473d..e825c60e 100644 --- a/includes/private/cpu/x86_ops_mmx_mov.h +++ b/includes/private/cpu/x86_ops_mmx_mov.h @@ -1,199 +1,199 @@ #ifndef _X86_OPS_MMX_MOV_H_ #define _X86_OPS_MMX_MOV_H_ static int opMOVD_l_mm_a16(uint32_t fetchdat) { - MMX_ENTER(); + 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; + 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; - SEG_CHECK_READ(cpu_state.ea_seg); - dst = readmeml(easeg, cpu_state.eaaddr); - if (cpu_state.abrt) - return 1; - cpu_state.MM[cpu_reg].l[0] = dst; - cpu_state.MM[cpu_reg].l[1] = 0; + SEG_CHECK_READ(cpu_state.ea_seg); + dst = readmeml(easeg, cpu_state.eaaddr); + if (cpu_state.abrt) + return 1; + cpu_state.MM[cpu_reg].l[0] = dst; + cpu_state.MM[cpu_reg].l[1] = 0; - CLOCK_CYCLES(2); - } - return 0; + CLOCK_CYCLES(2); + } + return 0; } static int opMOVD_l_mm_a32(uint32_t fetchdat) { - MMX_ENTER(); + 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; + 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; - SEG_CHECK_READ(cpu_state.ea_seg); - dst = readmeml(easeg, cpu_state.eaaddr); - if (cpu_state.abrt) - return 1; - cpu_state.MM[cpu_reg].l[0] = dst; - cpu_state.MM[cpu_reg].l[1] = 0; + SEG_CHECK_READ(cpu_state.ea_seg); + dst = readmeml(easeg, cpu_state.eaaddr); + if (cpu_state.abrt) + return 1; + cpu_state.MM[cpu_reg].l[0] = dst; + cpu_state.MM[cpu_reg].l[1] = 0; - CLOCK_CYCLES(2); - } - return 0; + CLOCK_CYCLES(2); + } + return 0; } static int opMOVD_mm_l_a16(uint32_t fetchdat) { - MMX_ENTER(); + 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 { - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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; + 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 { + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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(); + 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 { - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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; + 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 { + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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; } /*Cyrix maps both MOVD and SMINT to the same opcode*/ static int opMOVD_mm_l_a16_cx(uint32_t fetchdat) { - if (cpu_cur_status & CPU_STATUS_SMM) - return opSMINT(fetchdat); + if (cpu_cur_status & CPU_STATUS_SMM) + return opSMINT(fetchdat); - MMX_ENTER(); + 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 { - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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; + 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 { + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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_cx(uint32_t fetchdat) { - if (cpu_cur_status & CPU_STATUS_SMM) - return opSMINT(fetchdat); + if (cpu_cur_status & CPU_STATUS_SMM) + return opSMINT(fetchdat); - MMX_ENTER(); + 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 { - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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; + 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 { + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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(); + 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; + 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; - SEG_CHECK_READ(cpu_state.ea_seg); - dst = readmemq(easeg, cpu_state.eaaddr); - if (cpu_state.abrt) - return 1; - cpu_state.MM[cpu_reg].q = dst; - CLOCK_CYCLES(2); - } - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + dst = readmemq(easeg, cpu_state.eaaddr); + if (cpu_state.abrt) + return 1; + cpu_state.MM[cpu_reg].q = dst; + CLOCK_CYCLES(2); + } + return 0; } static int opMOVQ_q_mm_a32(uint32_t fetchdat) { - MMX_ENTER(); + 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; + 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; - SEG_CHECK_READ(cpu_state.ea_seg); - dst = readmemq(easeg, cpu_state.eaaddr); - if (cpu_state.abrt) - return 1; - cpu_state.MM[cpu_reg].q = dst; - CLOCK_CYCLES(2); - } - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + dst = readmemq(easeg, cpu_state.eaaddr); + if (cpu_state.abrt) + return 1; + cpu_state.MM[cpu_reg].q = dst; + CLOCK_CYCLES(2); + } + return 0; } static int opMOVQ_mm_q_a16(uint32_t fetchdat) { - MMX_ENTER(); + 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 { - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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; + fetch_ea_16(fetchdat); + if (cpu_mod == 3) { + cpu_state.MM[cpu_rm].q = cpu_state.MM[cpu_reg].q; + CLOCK_CYCLES(1); + } else { + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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(); + 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 { - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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; + fetch_ea_32(fetchdat); + if (cpu_mod == 3) { + cpu_state.MM[cpu_rm].q = cpu_state.MM[cpu_reg].q; + CLOCK_CYCLES(1); + } else { + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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; } #endif /* _X86_OPS_MMX_MOV_H_ */ diff --git a/includes/private/cpu/x86_ops_mmx_pack.h b/includes/private/cpu/x86_ops_mmx_pack.h index 4af9452d..cc995447 100644 --- a/includes/private/cpu/x86_ops_mmx_pack.h +++ b/includes/private/cpu/x86_ops_mmx_pack.h @@ -1,310 +1,310 @@ #ifndef _X86_OPS_MMX_PACK_H_ #define _X86_OPS_MMX_PACK_H_ static int opPUNPCKLDQ_a16(uint32_t fetchdat) { - MMX_ENTER(); + 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; + 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; - SEG_CHECK_READ(cpu_state.ea_seg); - src = readmeml(easeg, cpu_state.eaaddr); - if (cpu_state.abrt) - return 0; - cpu_state.MM[cpu_reg].l[1] = src; + SEG_CHECK_READ(cpu_state.ea_seg); + src = readmeml(easeg, cpu_state.eaaddr); + if (cpu_state.abrt) + return 0; + cpu_state.MM[cpu_reg].l[1] = src; - CLOCK_CYCLES(2); - } - return 0; + CLOCK_CYCLES(2); + } + return 0; } static int opPUNPCKLDQ_a32(uint32_t fetchdat) { - MMX_ENTER(); + 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; + 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; - SEG_CHECK_READ(cpu_state.ea_seg); - src = readmeml(easeg, cpu_state.eaaddr); - if (cpu_state.abrt) - return 0; - cpu_state.MM[cpu_reg].l[1] = src; + SEG_CHECK_READ(cpu_state.ea_seg); + src = readmeml(easeg, cpu_state.eaaddr); + if (cpu_state.abrt) + return 0; + cpu_state.MM[cpu_reg].l[1] = src; - CLOCK_CYCLES(2); - } - return 0; + CLOCK_CYCLES(2); + } + return 0; } static int opPUNPCKHDQ_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + 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]; + 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; + return 0; } static int opPUNPCKHDQ_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + 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]; + 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; + return 0; } static int opPUNPCKLBW_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + 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]; + 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; + return 0; } static int opPUNPCKLBW_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + 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]; + 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; + return 0; } static int opPUNPCKHBW_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + 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]; + 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; + return 0; } static int opPUNPCKHBW_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + 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]; + 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; + return 0; } static int opPUNPCKLWD_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + 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]; + 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; + return 0; } static int opPUNPCKLWD_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + 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]; + 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; + return 0; } static int opPUNPCKHWD_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + 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]; + 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; + return 0; } static int opPUNPCKHWD_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + 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]; + 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; + return 0; } static int opPACKSSWB_a16(uint32_t fetchdat) { - MMX_REG src, dst; - MMX_ENTER(); + MMX_REG src, dst; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); - dst = cpu_state.MM[cpu_reg]; + 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]); + 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; + return 0; } static int opPACKSSWB_a32(uint32_t fetchdat) { - MMX_REG src, dst; - MMX_ENTER(); + MMX_REG src, dst; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); - dst = cpu_state.MM[cpu_reg]; + 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]); + 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; + return 0; } static int opPACKUSWB_a16(uint32_t fetchdat) { - MMX_REG src, dst; - MMX_ENTER(); + MMX_REG src, dst; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); - dst = cpu_state.MM[cpu_reg]; + 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]); + 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; + return 0; } static int opPACKUSWB_a32(uint32_t fetchdat) { - MMX_REG src, dst; - MMX_ENTER(); + MMX_REG src, dst; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); - dst = cpu_state.MM[cpu_reg]; + 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]); + 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; + return 0; } static int opPACKSSDW_a16(uint32_t fetchdat) { - MMX_REG src, dst; - MMX_ENTER(); + MMX_REG src, dst; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); - dst = cpu_state.MM[cpu_reg]; + 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]); + 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; + return 0; } static int opPACKSSDW_a32(uint32_t fetchdat) { - MMX_REG src, dst; - MMX_ENTER(); + MMX_REG src, dst; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); - dst = cpu_state.MM[cpu_reg]; + 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]); + 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; + return 0; } #endif /* _X86_OPS_MMX_PACK_H_ */ diff --git a/includes/private/cpu/x86_ops_mmx_shift.h b/includes/private/cpu/x86_ops_mmx_shift.h index 87271a09..bd91901f 100644 --- a/includes/private/cpu/x86_ops_mmx_shift.h +++ b/includes/private/cpu/x86_ops_mmx_shift.h @@ -1,420 +1,422 @@ #ifndef _X86_OPS_MMX_SHIFT_H_ #define _X86_OPS_MMX_SHIFT_H_ -#define MMX_GETSHIFT() \ - if (cpu_mod == 3) \ - { \ - shift = cpu_state.MM[cpu_rm].b[0]; \ - CLOCK_CYCLES(1); \ - } \ - else \ - { \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - shift = readmemb(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 0; \ - CLOCK_CYCLES(2); \ +#define MMX_GETSHIFT() \ + if (cpu_mod == 3) { \ + shift = cpu_state.MM[cpu_rm].b[0]; \ + CLOCK_CYCLES(1); \ + } else { \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + 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; + int reg = fetchdat & 7; + int op = fetchdat & 0x38; + int shift = (fetchdat >> 8) & 0xff; - cpu_state.pc += 2; - MMX_ENTER(); + 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; - } + 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; + CLOCK_CYCLES(1); + return 0; } static int opPSLLW_a16(uint32_t fetchdat) { - int shift; + int shift; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSHIFT(); + 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; - } + 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; + return 0; } static int opPSLLW_a32(uint32_t fetchdat) { - int shift; + int shift; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSHIFT(); + 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; - } + 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; + return 0; } static int opPSRLW_a16(uint32_t fetchdat) { - int shift; + int shift; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSHIFT(); + 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; - } + 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; + return 0; } static int opPSRLW_a32(uint32_t fetchdat) { - int shift; + int shift; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSHIFT(); + 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; - } + 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; + return 0; } static int opPSRAW_a16(uint32_t fetchdat) { - int shift; + int shift; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSHIFT(); + fetch_ea_16(fetchdat); + MMX_GETSHIFT(); - if (shift > 15) - shift = 15; + 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; + 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; + return 0; } static int opPSRAW_a32(uint32_t fetchdat) { - int shift; + int shift; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSHIFT(); + fetch_ea_32(fetchdat); + MMX_GETSHIFT(); - if (shift > 15) - shift = 15; + 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; + 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; + return 0; } static int opPSxxD_imm(uint32_t fetchdat) { - int reg = fetchdat & 7; - int op = fetchdat & 0x38; - int shift = (fetchdat >> 8) & 0xff; + int reg = fetchdat & 7; + int op = fetchdat & 0x38; + int shift = (fetchdat >> 8) & 0xff; - cpu_state.pc += 2; - MMX_ENTER(); + 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; - } + 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; + CLOCK_CYCLES(1); + return 0; } static int opPSLLD_a16(uint32_t fetchdat) { - int shift; + int shift; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSHIFT(); + 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; - } + 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; + return 0; } static int opPSLLD_a32(uint32_t fetchdat) { - int shift; + int shift; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSHIFT(); + 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; - } + 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; + return 0; } static int opPSRLD_a16(uint32_t fetchdat) { - int shift; + int shift; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSHIFT(); + 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; - } + 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; + return 0; } static int opPSRLD_a32(uint32_t fetchdat) { - int shift; + int shift; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSHIFT(); + 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; - } + 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; + return 0; } static int opPSRAD_a16(uint32_t fetchdat) { - int shift; + int shift; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSHIFT(); + fetch_ea_16(fetchdat); + MMX_GETSHIFT(); - if (shift > 31) - shift = 31; + if (shift > 31) + shift = 31; - cpu_state.MM[cpu_reg].sl[0] >>= shift; - cpu_state.MM[cpu_reg].sl[1] >>= shift; + cpu_state.MM[cpu_reg].sl[0] >>= shift; + cpu_state.MM[cpu_reg].sl[1] >>= shift; - return 0; + return 0; } static int opPSRAD_a32(uint32_t fetchdat) { - int shift; + int shift; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSHIFT(); + fetch_ea_32(fetchdat); + MMX_GETSHIFT(); - if (shift > 31) - shift = 31; + if (shift > 31) + shift = 31; - cpu_state.MM[cpu_reg].sl[0] >>= shift; - cpu_state.MM[cpu_reg].sl[1] >>= shift; + cpu_state.MM[cpu_reg].sl[0] >>= shift; + cpu_state.MM[cpu_reg].sl[1] >>= shift; - return 0; + return 0; } static int opPSxxQ_imm(uint32_t fetchdat) { - int reg = fetchdat & 7; - int op = fetchdat & 0x38; - int shift = (fetchdat >> 8) & 0xff; + int reg = fetchdat & 7; + int op = fetchdat & 0x38; + int shift = (fetchdat >> 8) & 0xff; - cpu_state.pc += 2; - MMX_ENTER(); + 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; - } + 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; + CLOCK_CYCLES(1); + return 0; } static int opPSLLQ_a16(uint32_t fetchdat) { - int shift; + int shift; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSHIFT(); + fetch_ea_16(fetchdat); + MMX_GETSHIFT(); - if (shift > 63) - cpu_state.MM[cpu_reg].q = 0; - else - cpu_state.MM[cpu_reg].q <<= shift; + if (shift > 63) + cpu_state.MM[cpu_reg].q = 0; + else + cpu_state.MM[cpu_reg].q <<= shift; - return 0; + return 0; } static int opPSLLQ_a32(uint32_t fetchdat) { - int shift; + int shift; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSHIFT(); + fetch_ea_32(fetchdat); + MMX_GETSHIFT(); - if (shift > 63) - cpu_state.MM[cpu_reg].q = 0; - else - cpu_state.MM[cpu_reg].q <<= shift; + if (shift > 63) + cpu_state.MM[cpu_reg].q = 0; + else + cpu_state.MM[cpu_reg].q <<= shift; - return 0; + return 0; } static int opPSRLQ_a16(uint32_t fetchdat) { - int shift; + int shift; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSHIFT(); + fetch_ea_16(fetchdat); + MMX_GETSHIFT(); - if (shift > 63) - cpu_state.MM[cpu_reg].q = 0; - else - cpu_state.MM[cpu_reg].q >>= shift; + if (shift > 63) + cpu_state.MM[cpu_reg].q = 0; + else + cpu_state.MM[cpu_reg].q >>= shift; - return 0; + return 0; } static int opPSRLQ_a32(uint32_t fetchdat) { - int shift; + int shift; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSHIFT(); + fetch_ea_32(fetchdat); + MMX_GETSHIFT(); - if (shift > 63) - cpu_state.MM[cpu_reg].q = 0; - else - cpu_state.MM[cpu_reg].q >>= shift; + if (shift > 63) + cpu_state.MM[cpu_reg].q = 0; + else + cpu_state.MM[cpu_reg].q >>= shift; - return 0; + return 0; } #endif /* _X86_OPS_MMX_SHIFT_H_ */ diff --git a/includes/private/cpu/x86_ops_mov.h b/includes/private/cpu/x86_ops_mov.h index 4a468b49..b97568ab 100644 --- a/includes/private/cpu/x86_ops_mov.h +++ b/includes/private/cpu/x86_ops_mov.h @@ -1,750 +1,732 @@ #ifndef _X86_OPS_MOV_H_ #define _X86_OPS_MOV_H_ 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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); - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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; + uint8_t temp; + fetch_ea_16(fetchdat); + ILLEGAL_ON((rmdat & 0x38) != 0); + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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); - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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; + uint8_t temp; + fetch_ea_32(fetchdat); + ILLEGAL_ON((rmdat & 0x38) != 0); + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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); - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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; + uint16_t temp; + fetch_ea_16(fetchdat); + ILLEGAL_ON((rmdat & 0x38) != 0); + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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); - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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; + uint16_t temp; + fetch_ea_32(fetchdat); + ILLEGAL_ON((rmdat & 0x38) != 0); + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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); - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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; + uint32_t temp; + fetch_ea_16(fetchdat); + ILLEGAL_ON((rmdat & 0x38) != 0); + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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); - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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; + uint32_t temp; + fetch_ea_32(fetchdat); + ILLEGAL_ON((rmdat & 0x38) != 0); + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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) { - uint16_t addr = getwordf(); - uint8_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - 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; + uint16_t addr = getwordf(); + uint8_t temp; + SEG_CHECK_READ(cpu_state.ea_seg); + 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) { - uint32_t addr = getlong(); - uint8_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - 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; + uint32_t addr = getlong(); + uint8_t temp; + SEG_CHECK_READ(cpu_state.ea_seg); + 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 addr = getwordf(); - uint16_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - 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; + uint16_t addr = getwordf(); + uint16_t temp; + SEG_CHECK_READ(cpu_state.ea_seg); + 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) { - uint32_t addr = getlong(); - uint16_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - 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; + uint32_t addr = getlong(); + uint16_t temp; + SEG_CHECK_READ(cpu_state.ea_seg); + 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) { - uint16_t addr = getwordf(); - uint32_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - 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; + uint16_t addr = getwordf(); + uint32_t temp; + SEG_CHECK_READ(cpu_state.ea_seg); + 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 addr = getlong(); - uint32_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - 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; + uint32_t addr = getlong(); + uint32_t temp; + SEG_CHECK_READ(cpu_state.ea_seg); + 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(); - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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; + uint16_t addr = getwordf(); + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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(); - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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; + uint32_t addr = getlong(); + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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(); - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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; + uint16_t addr = getwordf(); + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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; - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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; + uint32_t addr = getlong(); + if (cpu_state.abrt) + return 1; + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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(); - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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; + uint16_t addr = getwordf(); + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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; - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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; + uint32_t addr = getlong(); + if (cpu_state.abrt) + return 1; + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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_state.eaaddr; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 0); - return 0; + fetch_ea_16(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + cpu_state.regs[cpu_reg].w = 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_state.eaaddr; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 1); - return 0; + fetch_ea_32(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + cpu_state.regs[cpu_reg].w = 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_state.eaaddr & 0xffff; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 0); - return 0; + fetch_ea_16(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + cpu_state.regs[cpu_reg].l = 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_state.eaaddr; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 1); - return 0; + fetch_ea_32(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + cpu_state.regs[cpu_reg].l = 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; + uint32_t addr = (BX + AL) & 0xFFFF; + uint8_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - 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; + SEG_CHECK_READ(cpu_state.ea_seg); + 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; + uint32_t addr = EBX + AL; + uint8_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - 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; + SEG_CHECK_READ(cpu_state.ea_seg); + 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 { - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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; + 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 { + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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 { - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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; + 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 { + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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 { - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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; + 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 { + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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 { - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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; + 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 { + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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 { - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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; + 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 { + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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 { - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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; + 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 { + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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; - SEG_CHECK_READ(cpu_state.ea_seg); - 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; + 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; + SEG_CHECK_READ(cpu_state.ea_seg); + 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; - SEG_CHECK_READ(cpu_state.ea_seg); - 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; + 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; + SEG_CHECK_READ(cpu_state.ea_seg); + 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; - SEG_CHECK_READ(cpu_state.ea_seg); - 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; + 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; + SEG_CHECK_READ(cpu_state.ea_seg); + 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; - SEG_CHECK_READ(cpu_state.ea_seg); - 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; + 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; + SEG_CHECK_READ(cpu_state.ea_seg); + 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; - SEG_CHECK_READ(cpu_state.ea_seg); - 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; + 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; + SEG_CHECK_READ(cpu_state.ea_seg); + 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; - SEG_CHECK_READ(cpu_state.ea_seg); - 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; + 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; + SEG_CHECK_READ(cpu_state.ea_seg); + 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; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - 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; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - 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; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - 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); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - temp = geteal(); if (cpu_state.abrt) return 1; \ - cpu_state.regs[cpu_reg].l = temp; \ - } \ - } \ - CLOCK_CYCLES(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; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + 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; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + 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; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + 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); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + 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) +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) #endif /* _X86_OPS_MOV_H_ */ diff --git a/includes/private/cpu/x86_ops_mov_ctrl.h b/includes/private/cpu/x86_ops_mov_ctrl.h index 1ea880ae..d40f45a7 100644 --- a/includes/private/cpu/x86_ops_mov_ctrl.h +++ b/includes/private/cpu/x86_ops_mov_ctrl.h @@ -1,261 +1,275 @@ #ifndef _X86_OPS_MOV_CTRL_H_ #define _X86_OPS_MOV_CTRL_H_ static int opMOV_r_CRx_a16(uint32_t fetchdat) { - if ((CPL || (cpu_state.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_has_feature(CPU_FEATURE_CR4)) { - 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; + if ((CPL || (cpu_state.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_has_feature(CPU_FEATURE_CR4)) { + 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 || (cpu_state.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_has_feature(CPU_FEATURE_CR4)) { - 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; + if ((CPL || (cpu_state.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_has_feature(CPU_FEATURE_CR4)) { + 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 || (cpu_state.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; + if ((CPL || (cpu_state.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 || (cpu_state.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; + if ((CPL || (cpu_state.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; + uint32_t old_cr0 = cr0; - if ((CPL || (cpu_state.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_has_feature(CPU_FEATURE_CR4)) { - cr4 = cpu_state.regs[cpu_rm].l & cpu_CR4_mask; - break; - } + if ((CPL || (cpu_state.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_has_feature(CPU_FEATURE_CR4)) { + 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; + 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; + uint32_t old_cr0 = cr0; - if ((CPL || (cpu_state.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_has_feature(CPU_FEATURE_CR4)) { - cr4 = cpu_state.regs[cpu_rm].l & cpu_CR4_mask; - break; - } + if ((CPL || (cpu_state.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_has_feature(CPU_FEATURE_CR4)) { + 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; + 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 || (cpu_state.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; + if ((CPL || (cpu_state.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 || (cpu_state.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; + if ((CPL || (cpu_state.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 || (cpu_state.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; + if ((CPL || (cpu_state.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 || (cpu_state.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; + if ((CPL || (cpu_state.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 || (cpu_state.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; + if ((CPL || (cpu_state.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 || (cpu_state.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; + if ((CPL || (cpu_state.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; } #endif /* _X86_OPS_MOV_CTRL_H_ */ diff --git a/includes/private/cpu/x86_ops_mov_seg.h b/includes/private/cpu/x86_ops_mov_seg.h index 8eef765a..20d7573e 100644 --- a/includes/private/cpu/x86_ops_mov_seg.h +++ b/includes/private/cpu/x86_ops_mov_seg.h @@ -1,469 +1,491 @@ #ifndef _X86_OPS_MOV_SEG_H_ #define _X86_OPS_MOV_SEG_H_ static int opMOV_w_seg_a16(uint32_t fetchdat) { - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); - 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; - } + 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; + 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); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); - 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; - } + 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; + 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); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); - 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; - } + 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; + 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); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); - 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; - } + 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; + 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; + uint16_t new_seg; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - new_seg = geteaw(); - if (cpu_state.abrt) - return 1; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + new_seg = geteaw(); + if (cpu_state.abrt) + return 1; - switch (rmdat & 0x38) { - case 0x00: /*ES*/ - loadseg(new_seg, &cpu_state.seg_es); - break; - case 0x18: /*DS*/ - loadseg(new_seg, &cpu_state.seg_ds); - break; - case 0x10: /*SS*/ - loadseg(new_seg, &cpu_state.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 = &cpu_state.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, &cpu_state.seg_fs); - break; - case 0x28: /*GS*/ - loadseg(new_seg, &cpu_state.seg_gs); - break; - } + switch (rmdat & 0x38) { + case 0x00: /*ES*/ + loadseg(new_seg, &cpu_state.seg_es); + break; + case 0x18: /*DS*/ + loadseg(new_seg, &cpu_state.seg_ds); + break; + case 0x10: /*SS*/ + loadseg(new_seg, &cpu_state.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 = &cpu_state.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, &cpu_state.seg_fs); + break; + case 0x28: /*GS*/ + loadseg(new_seg, &cpu_state.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; + 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; + uint16_t new_seg; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - new_seg = geteaw(); - if (cpu_state.abrt) - return 1; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + new_seg = geteaw(); + if (cpu_state.abrt) + return 1; - switch (rmdat & 0x38) { - case 0x00: /*ES*/ - loadseg(new_seg, &cpu_state.seg_es); - break; - case 0x18: /*DS*/ - loadseg(new_seg, &cpu_state.seg_ds); - break; - case 0x10: /*SS*/ - loadseg(new_seg, &cpu_state.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 = &cpu_state.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, &cpu_state.seg_fs); - break; - case 0x28: /*GS*/ - loadseg(new_seg, &cpu_state.seg_gs); - break; - } + switch (rmdat & 0x38) { + case 0x00: /*ES*/ + loadseg(new_seg, &cpu_state.seg_es); + break; + case 0x18: /*DS*/ + loadseg(new_seg, &cpu_state.seg_ds); + break; + case 0x10: /*SS*/ + loadseg(new_seg, &cpu_state.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 = &cpu_state.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, &cpu_state.seg_fs); + break; + case 0x28: /*GS*/ + loadseg(new_seg, &cpu_state.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; + 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; + uint16_t addr, seg; - fetch_ea_16(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - SEG_CHECK_READ(cpu_state.ea_seg); - addr = readmemw(easeg, cpu_state.eaaddr); - seg = readmemw(easeg, cpu_state.eaaddr + 2); - if (cpu_state.abrt) - return 1; - loadseg(seg, &cpu_state.seg_ds); - if (cpu_state.abrt) - return 1; - cpu_state.regs[cpu_reg].w = addr; + fetch_ea_16(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); + addr = readmemw(easeg, cpu_state.eaaddr); + seg = readmemw(easeg, cpu_state.eaaddr + 2); + if (cpu_state.abrt) + return 1; + loadseg(seg, &cpu_state.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; + 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; + uint16_t addr, seg; - fetch_ea_32(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - SEG_CHECK_READ(cpu_state.ea_seg); - addr = readmemw(easeg, cpu_state.eaaddr); - seg = readmemw(easeg, cpu_state.eaaddr + 2); - if (cpu_state.abrt) - return 1; - loadseg(seg, &cpu_state.seg_ds); - if (cpu_state.abrt) - return 1; - cpu_state.regs[cpu_reg].w = addr; + fetch_ea_32(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); + addr = readmemw(easeg, cpu_state.eaaddr); + seg = readmemw(easeg, cpu_state.eaaddr + 2); + if (cpu_state.abrt) + return 1; + loadseg(seg, &cpu_state.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; + 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; + uint32_t addr; + uint16_t seg; - fetch_ea_16(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - SEG_CHECK_READ(cpu_state.ea_seg); - addr = readmeml(easeg, cpu_state.eaaddr); - seg = readmemw(easeg, cpu_state.eaaddr + 4); - if (cpu_state.abrt) - return 1; - loadseg(seg, &cpu_state.seg_ds); - if (cpu_state.abrt) - return 1; - cpu_state.regs[cpu_reg].l = addr; + fetch_ea_16(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); + addr = readmeml(easeg, cpu_state.eaaddr); + seg = readmemw(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) + return 1; + loadseg(seg, &cpu_state.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; + 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; + uint32_t addr; + uint16_t seg; - fetch_ea_32(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - SEG_CHECK_READ(cpu_state.ea_seg); - addr = readmeml(easeg, cpu_state.eaaddr); - seg = readmemw(easeg, cpu_state.eaaddr + 4); - if (cpu_state.abrt) - return 1; - loadseg(seg, &cpu_state.seg_ds); - if (cpu_state.abrt) - return 1; - cpu_state.regs[cpu_reg].l = addr; + fetch_ea_32(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); + addr = readmeml(easeg, cpu_state.eaaddr); + seg = readmemw(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) + return 1; + loadseg(seg, &cpu_state.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; + 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; + uint16_t addr, seg; - fetch_ea_16(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - SEG_CHECK_READ(cpu_state.ea_seg); - addr = readmemw(easeg, cpu_state.eaaddr); - seg = readmemw(easeg, cpu_state.eaaddr + 2); - if (cpu_state.abrt) - return 1; - loadseg(seg, &cpu_state.seg_ss); - if (cpu_state.abrt) - return 1; - cpu_state.regs[cpu_reg].w = addr; + fetch_ea_16(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); + addr = readmemw(easeg, cpu_state.eaaddr); + seg = readmemw(easeg, cpu_state.eaaddr + 2); + if (cpu_state.abrt) + return 1; + loadseg(seg, &cpu_state.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; + 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; + uint16_t addr, seg; - fetch_ea_32(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - SEG_CHECK_READ(cpu_state.ea_seg); - addr = readmemw(easeg, cpu_state.eaaddr); - seg = readmemw(easeg, cpu_state.eaaddr + 2); - if (cpu_state.abrt) - return 1; - loadseg(seg, &cpu_state.seg_ss); - if (cpu_state.abrt) - return 1; - cpu_state.regs[cpu_reg].w = addr; + fetch_ea_32(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); + addr = readmemw(easeg, cpu_state.eaaddr); + seg = readmemw(easeg, cpu_state.eaaddr + 2); + if (cpu_state.abrt) + return 1; + loadseg(seg, &cpu_state.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; + 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; + uint32_t addr; + uint16_t seg; - fetch_ea_16(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - SEG_CHECK_READ(cpu_state.ea_seg); - addr = readmeml(easeg, cpu_state.eaaddr); - seg = readmemw(easeg, cpu_state.eaaddr + 4); - if (cpu_state.abrt) - return 1; - loadseg(seg, &cpu_state.seg_ss); - if (cpu_state.abrt) - return 1; - cpu_state.regs[cpu_reg].l = addr; + fetch_ea_16(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); + addr = readmeml(easeg, cpu_state.eaaddr); + seg = readmemw(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) + return 1; + loadseg(seg, &cpu_state.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; + 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; + uint32_t addr; + uint16_t seg; - fetch_ea_32(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - SEG_CHECK_READ(cpu_state.ea_seg); - addr = readmeml(easeg, cpu_state.eaaddr); - seg = readmemw(easeg, cpu_state.eaaddr + 4); - if (cpu_state.abrt) - return 1; - loadseg(seg, &cpu_state.seg_ss); - if (cpu_state.abrt) - return 1; - cpu_state.regs[cpu_reg].l = addr; + fetch_ea_32(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); + addr = readmeml(easeg, cpu_state.eaaddr); + seg = readmemw(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) + return 1; + loadseg(seg, &cpu_state.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; + 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); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - 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); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - 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); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - 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); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - 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; \ +#define opLsel(name, sel) \ + static int opL##name##_w_a16(uint32_t fetchdat) { \ + uint16_t addr, seg; \ + \ + fetch_ea_16(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + 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); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + 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); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + 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); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + 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, cpu_state.seg_es) -opLsel(FS, cpu_state.seg_fs) -opLsel(GS, cpu_state.seg_gs) +opLsel(ES, cpu_state.seg_es) opLsel(FS, cpu_state.seg_fs) opLsel(GS, cpu_state.seg_gs) #endif /* _X86_OPS_MOV_SEG_H_ */ diff --git a/includes/private/cpu/x86_ops_movx.h b/includes/private/cpu/x86_ops_movx.h index 301a8420..541cfcfe 100644 --- a/includes/private/cpu/x86_ops_movx.h +++ b/includes/private/cpu/x86_ops_movx.h @@ -1,227 +1,227 @@ #ifndef _X86_OPS_MOVX_H_ #define _X86_OPS_MOVX_H_ static int opMOVZX_w_b_a16(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteab(); - if (cpu_state.abrt) - return 1; - cpu_state.regs[cpu_reg].w = (uint16_t)temp; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + 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; + 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; + uint8_t temp; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteab(); - if (cpu_state.abrt) - return 1; - cpu_state.regs[cpu_reg].w = (uint16_t)temp; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + 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; + 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; + uint8_t temp; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteab(); - if (cpu_state.abrt) - return 1; - cpu_state.regs[cpu_reg].l = (uint32_t)temp; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + 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; + 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; + uint8_t temp; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteab(); - if (cpu_state.abrt) - return 1; - cpu_state.regs[cpu_reg].l = (uint32_t)temp; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + 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; + 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; + uint16_t temp; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteaw(); - if (cpu_state.abrt) - return 1; - cpu_state.regs[cpu_reg].w = temp; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + 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; + 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; + uint16_t temp; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteaw(); - if (cpu_state.abrt) - return 1; - cpu_state.regs[cpu_reg].w = temp; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + 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; + 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; + uint16_t temp; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteaw(); - if (cpu_state.abrt) - return 1; - cpu_state.regs[cpu_reg].l = (uint32_t)temp; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + 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; + 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; + uint16_t temp; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteaw(); - if (cpu_state.abrt) - return 1; - cpu_state.regs[cpu_reg].l = (uint32_t)temp; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + 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; + 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; + uint8_t temp; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - 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; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + 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; + 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; + uint8_t temp; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - 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; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + 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; + 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; + uint8_t temp; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - 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; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + 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; + 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; + uint8_t temp; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - 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; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + 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; + 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; + uint16_t temp; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - 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; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + 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; + 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; + uint16_t temp; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - 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; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + 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; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + return 0; } #endif /* _X86_OPS_MOVX_H_ */ diff --git a/includes/private/cpu/x86_ops_msr.h b/includes/private/cpu/x86_ops_msr.h index 985a03b1..011b269b 100644 --- a/includes/private/cpu/x86_ops_msr.h +++ b/includes/private/cpu/x86_ops_msr.h @@ -1,29 +1,29 @@ #ifndef _X86_OPS_MSR_H_ #define _X86_OPS_MSR_H_ static int opRDTSC(uint32_t fetchdat) { - if (!cpu_has_feature(CPU_FEATURE_RDTSC)) { - 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; + if (!cpu_has_feature(CPU_FEATURE_RDTSC)) { + 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; + if (ECX > 1 || (!(cr4 & CR4_PCE) && (cr0 & 1) && CPL)) { + x86gpf("RDPMC not allowed", 0); + return 1; + } + EAX = EDX = 0; + CLOCK_CYCLES(1); + return 0; } #endif /* _X86_OPS_MSR_H_ */ diff --git a/includes/private/cpu/x86_ops_mul.h b/includes/private/cpu/x86_ops_mul.h index 034e7c52..462bcb6a 100644 --- a/includes/private/cpu/x86_ops_mul.h +++ b/includes/private/cpu/x86_ops_mul.h @@ -1,317 +1,317 @@ #ifndef _X86_OPS_MUL_H_ #define _X86_OPS_MUL_H_ static int opIMUL_w_iw_a16(uint32_t fetchdat) { - int32_t templ; - int16_t tempw, tempw2; + int32_t templ; + int16_t tempw, tempw2; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); - tempw = geteaw(); - if (cpu_state.abrt) - return 1; - tempw2 = getword(); - if (cpu_state.abrt) - return 1; + 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) - cpu_state.flags |= C_FLAG | V_FLAG; - else - cpu_state.flags &= ~(C_FLAG | V_FLAG); - cpu_state.regs[cpu_reg].w = templ & 0xffff; + templ = ((int)tempw) * ((int)tempw2); + flags_rebuild(); + if ((templ >> 15) != 0 && (templ >> 15) != -1) + cpu_state.flags |= C_FLAG | V_FLAG; + else + cpu_state.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; + 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; + int32_t templ; + int16_t tempw, tempw2; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); - tempw = geteaw(); - if (cpu_state.abrt) - return 1; - tempw2 = getword(); - if (cpu_state.abrt) - return 1; + 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) - cpu_state.flags |= C_FLAG | V_FLAG; - else - cpu_state.flags &= ~(C_FLAG | V_FLAG); - cpu_state.regs[cpu_reg].w = templ & 0xffff; + templ = ((int)tempw) * ((int)tempw2); + flags_rebuild(); + if ((templ >> 15) != 0 && (templ >> 15) != -1) + cpu_state.flags |= C_FLAG | V_FLAG; + else + cpu_state.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; + 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; + int64_t temp64; + int32_t templ, templ2; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); - templ = geteal(); - if (cpu_state.abrt) - return 1; - templ2 = getlong(); - if (cpu_state.abrt) - return 1; + 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) - cpu_state.flags |= C_FLAG | V_FLAG; - else - cpu_state.flags &= ~(C_FLAG | V_FLAG); - cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff; + temp64 = ((int64_t)templ) * ((int64_t)templ2); + flags_rebuild(); + if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) + cpu_state.flags |= C_FLAG | V_FLAG; + else + cpu_state.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; + 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; + int64_t temp64; + int32_t templ, templ2; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); - templ = geteal(); - if (cpu_state.abrt) - return 1; - templ2 = getlong(); - if (cpu_state.abrt) - return 1; + 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) - cpu_state.flags |= C_FLAG | V_FLAG; - else - cpu_state.flags &= ~(C_FLAG | V_FLAG); - cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff; + temp64 = ((int64_t)templ) * ((int64_t)templ2); + flags_rebuild(); + if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) + cpu_state.flags |= C_FLAG | V_FLAG; + else + cpu_state.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; + 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; + int32_t templ; + int16_t tempw, tempw2; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); - tempw = geteaw(); - if (cpu_state.abrt) - return 1; - tempw2 = getbyte(); - if (cpu_state.abrt) - return 1; - if (tempw2 & 0x80) - tempw2 |= 0xff00; + 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) - cpu_state.flags |= C_FLAG | V_FLAG; - else - cpu_state.flags &= ~(C_FLAG | V_FLAG); - cpu_state.regs[cpu_reg].w = templ & 0xffff; + templ = ((int)tempw) * ((int)tempw2); + flags_rebuild(); + if ((templ >> 15) != 0 && (templ >> 15) != -1) + cpu_state.flags |= C_FLAG | V_FLAG; + else + cpu_state.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; + 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; + int32_t templ; + int16_t tempw, tempw2; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); - tempw = geteaw(); - if (cpu_state.abrt) - return 1; - tempw2 = getbyte(); - if (cpu_state.abrt) - return 1; - if (tempw2 & 0x80) - tempw2 |= 0xff00; + 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) - cpu_state.flags |= C_FLAG | V_FLAG; - else - cpu_state.flags &= ~(C_FLAG | V_FLAG); - cpu_state.regs[cpu_reg].w = templ & 0xffff; + templ = ((int)tempw) * ((int)tempw2); + flags_rebuild(); + if ((templ >> 15) != 0 && (templ >> 15) != -1) + cpu_state.flags |= C_FLAG | V_FLAG; + else + cpu_state.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; + 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; + int64_t temp64; + int32_t templ, templ2; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); - templ = geteal(); - if (cpu_state.abrt) - return 1; - templ2 = getbyte(); - if (cpu_state.abrt) - return 1; - if (templ2 & 0x80) - templ2 |= 0xffffff00; + 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) - cpu_state.flags |= C_FLAG | V_FLAG; - else - cpu_state.flags &= ~(C_FLAG | V_FLAG); - cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff; + temp64 = ((int64_t)templ) * ((int64_t)templ2); + flags_rebuild(); + if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) + cpu_state.flags |= C_FLAG | V_FLAG; + else + cpu_state.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; + 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; + int64_t temp64; + int32_t templ, templ2; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); - templ = geteal(); - if (cpu_state.abrt) - return 1; - templ2 = getbyte(); - if (cpu_state.abrt) - return 1; - if (templ2 & 0x80) - templ2 |= 0xffffff00; + 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) - cpu_state.flags |= C_FLAG | V_FLAG; - else - cpu_state.flags &= ~(C_FLAG | V_FLAG); - cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff; + temp64 = ((int64_t)templ) * ((int64_t)templ2); + flags_rebuild(); + if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) + cpu_state.flags |= C_FLAG | V_FLAG; + else + cpu_state.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; + 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; + int32_t templ; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); - templ = (int32_t)(int16_t)cpu_state.regs[cpu_reg].w * (int32_t)(int16_t)geteaw(); - if (cpu_state.abrt) - return 1; - cpu_state.regs[cpu_reg].w = templ & 0xFFFF; - flags_rebuild(); - if ((templ >> 15) != 0 && (templ >> 15) != -1) - cpu_state.flags |= C_FLAG | V_FLAG; - else - cpu_state.flags &= ~(C_FLAG | V_FLAG); + 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) + cpu_state.flags |= C_FLAG | V_FLAG; + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); - CLOCK_CYCLES(18); - PREFETCH_RUN(18, 2, rmdat, 1, 0, 0, 0, 0); - return 0; + 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; + int32_t templ; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); - templ = (int32_t)(int16_t)cpu_state.regs[cpu_reg].w * (int32_t)(int16_t)geteaw(); - if (cpu_state.abrt) - return 1; - cpu_state.regs[cpu_reg].w = templ & 0xFFFF; - flags_rebuild(); - if ((templ >> 15) != 0 && (templ >> 15) != -1) - cpu_state.flags |= C_FLAG | V_FLAG; - else - cpu_state.flags &= ~(C_FLAG | V_FLAG); + 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) + cpu_state.flags |= C_FLAG | V_FLAG; + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); - CLOCK_CYCLES(18); - PREFETCH_RUN(18, 2, rmdat, 1, 0, 0, 0, 1); - return 0; + 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; + int64_t temp64; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); - temp64 = (int64_t)(int32_t)cpu_state.regs[cpu_reg].l * (int64_t)(int32_t)geteal(); - if (cpu_state.abrt) - return 1; - cpu_state.regs[cpu_reg].l = temp64 & 0xFFFFFFFF; - flags_rebuild(); - if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) - cpu_state.flags |= C_FLAG | V_FLAG; - else - cpu_state.flags &= ~(C_FLAG | V_FLAG); + 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) + cpu_state.flags |= C_FLAG | V_FLAG; + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); - CLOCK_CYCLES(30); - PREFETCH_RUN(30, 2, rmdat, 0, 1, 0, 0, 0); - return 0; + 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; + int64_t temp64; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); - temp64 = (int64_t)(int32_t)cpu_state.regs[cpu_reg].l * (int64_t)(int32_t)geteal(); - if (cpu_state.abrt) - return 1; - cpu_state.regs[cpu_reg].l = temp64 & 0xFFFFFFFF; - flags_rebuild(); - if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) - cpu_state.flags |= C_FLAG | V_FLAG; - else - cpu_state.flags &= ~(C_FLAG | V_FLAG); + 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) + cpu_state.flags |= C_FLAG | V_FLAG; + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); - CLOCK_CYCLES(30); - PREFETCH_RUN(30, 2, rmdat, 0, 1, 0, 0, 1); - return 0; + CLOCK_CYCLES(30); + PREFETCH_RUN(30, 2, rmdat, 0, 1, 0, 0, 1); + return 0; } #endif /* _X86_OPS_MUL_H_ */ diff --git a/includes/private/cpu/x86_ops_pmode.h b/includes/private/cpu/x86_ops_pmode.h index a6f5500b..53333218 100644 --- a/includes/private/cpu/x86_ops_pmode.h +++ b/includes/private/cpu/x86_ops_pmode.h @@ -1,506 +1,519 @@ #ifndef _X86_OPS_PMODE_H_ #define _X86_OPS_PMODE_H_ static int opARPL_a16(uint32_t fetchdat) { - uint16_t temp_seg; + uint16_t temp_seg; - NOTRM - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - pclog("ARPL_a16\n"); - temp_seg = geteaw(); - if (cpu_state.abrt) - return 1; + NOTRM + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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; - cpu_state.flags |= Z_FLAG; - } else - cpu_state.flags &= ~Z_FLAG; + 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; + cpu_state.flags |= Z_FLAG; + } else + cpu_state.flags &= ~Z_FLAG; - CLOCK_CYCLES(is486 ? 9 : 20); - PREFETCH_RUN(is486 ? 9 : 20, 2, rmdat, 1, 0, 1, 0, 0); - return 0; + 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; + uint16_t temp_seg; - NOTRM - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - pclog("ARPL_a32\n"); - temp_seg = geteaw(); - if (cpu_state.abrt) - return 1; + NOTRM + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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; - cpu_state.flags |= Z_FLAG; - } else - cpu_state.flags &= ~Z_FLAG; + 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; + cpu_state.flags |= Z_FLAG; + } else + cpu_state.flags &= ~Z_FLAG; - CLOCK_CYCLES(is486 ? 9 : 20); - PREFETCH_RUN(is486 ? 9 : 20, 2, rmdat, 1, 0, 1, 0, 1); - return 0; + 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); \ - if (cpu_mod != 3) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - \ - sel = geteaw(); if (cpu_state.abrt) return 1; \ - \ - flags_rebuild(); \ - if (!(sel & 0xfffc)) { cpu_state.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; \ - } \ - cpu_state.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) \ - { \ - cpu_state.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; \ +#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); \ + if (cpu_mod != 3) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + \ + sel = geteaw(); \ + if (cpu_state.abrt) \ + return 1; \ + \ + flags_rebuild(); \ + if (!(sel & 0xfffc)) { \ + cpu_state.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; \ + } \ + cpu_state.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) { \ + cpu_state.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) +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); \ - if (cpu_mod != 3) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - \ - sel = geteaw(); if (cpu_state.abrt) return 1; \ - flags_rebuild(); \ - cpu_state.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) \ - { \ - cpu_state.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; \ +#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); \ + if (cpu_mod != 3) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + \ + sel = geteaw(); \ + if (cpu_state.abrt) \ + return 1; \ + flags_rebuild(); \ + cpu_state.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) { \ + cpu_state.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) + 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, access2; + 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, access2; -// pclog("op0F00 %02X %04X:%04X\n", rmdat & 0x38, CS, pc); - switch (rmdat & 0x38) { - case 0x00: /*SLDT*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(ldt.seg); - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 2, rmdat, 0, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); - break; - case 0x08: /*STR*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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 || cpu_state.eflags & VM_FLAG) && (cr0 & 1)) { - pclog("Invalid LLDT!\n"); - x86gpf(NULL, 0); - return 1; - } - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - 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); - access2 = readmemb(0, addr + 6); - granularity = readmemb(0, addr + 6) & 0x80; - if (cpu_state.abrt) - return 1; - ldt.limit = limit; - ldt.limit_raw = limit; - ldt.access = access; - ldt.access2 = access2; - 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 || cpu_state.eflags & VM_FLAG) && (cr0 & 1)) { - pclog("Invalid LTR!\n"); - x86gpf(NULL, 0); - break; - } - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - 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); - access2 = readmemb(0, addr + 6); - 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.limit_raw = limit; - tr.access = access; - tr.access2 = access2; - 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*/ - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - sel = geteaw(); - if (cpu_state.abrt) - return 1; - flags_rebuild(); - cpu_state.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) - cpu_state.flags |= Z_FLAG; - CLOCK_CYCLES(20); - PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 1 : 2, 0, 0, 0, ea32); - break; - case 0x28: /*VERW*/ - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - sel = geteaw(); - if (cpu_state.abrt) - return 1; - flags_rebuild(); - cpu_state.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) - cpu_state.flags |= Z_FLAG; - CLOCK_CYCLES(20); - PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 1 : 2, 0, 0, 0, ea32); - break; + // pclog("op0F00 %02X %04X:%04X\n", rmdat & 0x38, CS, pc); + switch (rmdat & 0x38) { + case 0x00: /*SLDT*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(ldt.seg); + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 2, rmdat, 0, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); + break; + case 0x08: /*STR*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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 || cpu_state.eflags & VM_FLAG) && (cr0 & 1)) { + pclog("Invalid LLDT!\n"); + x86gpf(NULL, 0); + return 1; + } + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + 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); + access2 = readmemb(0, addr + 6); + granularity = readmemb(0, addr + 6) & 0x80; + if (cpu_state.abrt) + return 1; + ldt.limit = limit; + ldt.limit_raw = limit; + ldt.access = access; + ldt.access2 = access2; + 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 || cpu_state.eflags & VM_FLAG) && (cr0 & 1)) { + pclog("Invalid LTR!\n"); + x86gpf(NULL, 0); + break; + } + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + 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); + access2 = readmemb(0, addr + 6); + 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.limit_raw = limit; + tr.access = access; + tr.access2 = access2; + 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*/ + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + sel = geteaw(); + if (cpu_state.abrt) + return 1; + flags_rebuild(); + cpu_state.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) + cpu_state.flags |= Z_FLAG; + CLOCK_CYCLES(20); + PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 1 : 2, 0, 0, 0, ea32); + break; + case 0x28: /*VERW*/ + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + sel = geteaw(); + if (cpu_state.abrt) + return 1; + flags_rebuild(); + cpu_state.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) + cpu_state.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; + 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 + NOTRM - fetch_ea_16(fetchdat); + fetch_ea_16(fetchdat); - return op0F00_common(fetchdat, 0); + return op0F00_common(fetchdat, 0); } static int op0F00_a32(uint32_t fetchdat) { - NOTRM + NOTRM - fetch_ea_32(fetchdat); + fetch_ea_32(fetchdat); - return op0F00_common(fetchdat, 1); + 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*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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 || cpu_state.eflags & VM_FLAG) && (cr0 & 1)) { - pclog("Invalid LGDT!\n"); - x86gpf(NULL, 0); - break; - } - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); -// 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 || cpu_state.eflags & VM_FLAG) && (cr0 & 1)) { - pclog("Invalid LIDT!\n"); - x86gpf(NULL, 0); - break; - } - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); -// 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; + uint32_t base; + uint16_t limit, tempw; + // pclog("op0F01 %02X %04X:%04X\n", rmdat & 0x38, CS, pc); + switch (rmdat & 0x38) { + case 0x00: /*SGDT*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(gdt.limit); + base = gdt.base; // is32 ? gdt.base : (gdt.base & 0xffffff); + 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*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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 || cpu_state.eflags & VM_FLAG) && (cr0 & 1)) { + pclog("Invalid LGDT!\n"); + x86gpf(NULL, 0); + break; + } + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + // 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 || cpu_state.eflags & VM_FLAG) && (cr0 & 1)) { + pclog("Invalid LIDT!\n"); + x86gpf(NULL, 0); + break; + } + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + // 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 (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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 || cpu_state.eflags & VM_FLAG) && (msw & 1)) { - pclog("LMSW - ring not zero!\n"); - x86gpf(NULL, 0); - break; - } - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - 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 0x20: /*SMSW*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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 || cpu_state.eflags & VM_FLAG) && (msw & 1)) { + pclog("LMSW - ring not zero!\n"); + x86gpf(NULL, 0); + break; + } + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + 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 || cpu_state.eflags & VM_FLAG) && (cr0 & 1)) { - pclog("Invalid INVLPG!\n"); - x86gpf(NULL, 0); - break; - } - SEG_CHECK_READ(cpu_state.ea_seg); - mmu_invalidate(ds + cpu_state.eaaddr); - CLOCK_CYCLES(12); - PREFETCH_RUN(12, 2, rmdat, 0, 0, 0, 0, ea32); - break; - } + case 0x38: /*INVLPG*/ + if (is486) { + if ((CPL || cpu_state.eflags & VM_FLAG) && (cr0 & 1)) { + pclog("Invalid INVLPG!\n"); + x86gpf(NULL, 0); + break; + } + SEG_CHECK_READ(cpu_state.ea_seg); + mmu_invalidate(ds + cpu_state.eaaddr); + CLOCK_CYCLES(12); + PREFETCH_RUN(12, 2, rmdat, 0, 0, 0, 0, ea32); + break; + } - default:pclog("Bad 0F 01 opcode %02X\n", rmdat & 0x38); - cpu_state.pc -= 3; - x86illegal(); - break; - } - return cpu_state.abrt; + 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); + fetch_ea_16(fetchdat); - return op0F01_common(fetchdat, 0, 0, 0); + return op0F01_common(fetchdat, 0, 0, 0); } static int op0F01_w_a32(uint32_t fetchdat) { - fetch_ea_32(fetchdat); + fetch_ea_32(fetchdat); - return op0F01_common(fetchdat, 0, 0, 1); + return op0F01_common(fetchdat, 0, 0, 1); } static int op0F01_l_a16(uint32_t fetchdat) { - fetch_ea_16(fetchdat); + fetch_ea_16(fetchdat); - return op0F01_common(fetchdat, 1, 0, 0); + return op0F01_common(fetchdat, 1, 0, 0); } static int op0F01_l_a32(uint32_t fetchdat) { - fetch_ea_32(fetchdat); + fetch_ea_32(fetchdat); - return op0F01_common(fetchdat, 1, 0, 1); + return op0F01_common(fetchdat, 1, 0, 1); } static int op0F01_286(uint32_t fetchdat) { - fetch_ea_16(fetchdat); + fetch_ea_16(fetchdat); - return op0F01_common(fetchdat, 0, 1, 0); + return op0F01_common(fetchdat, 0, 1, 0); } static int opRSM(uint32_t fetchdat) { - if (cpu_cur_status & CPU_STATUS_SMM) - x86_smi_leave(); - else - x86illegal(); + if (cpu_cur_status & CPU_STATUS_SMM) + x86_smi_leave(); + else + x86illegal(); - return 1; + return 1; } #endif /* _X86_OPS_PMODE_H_ */ diff --git a/includes/private/cpu/x86_ops_prefix.h b/includes/private/cpu/x86_ops_prefix.h index 11d0745d..426b32e9 100644 --- a/includes/private/cpu/x86_ops_prefix.h +++ b/includes/private/cpu/x86_ops_prefix.h @@ -1,171 +1,168 @@ #ifndef _X86_OPS_PREFIX_H_ #define _X86_OPS_PREFIX_H_ -#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); \ -} +#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, cpu_state.seg_cs, x86_opcodes, x86_opcodes) -op_seg(DS, cpu_state.seg_ds, x86_opcodes, x86_opcodes) -op_seg(ES, cpu_state.seg_es, x86_opcodes, x86_opcodes) -op_seg(FS, cpu_state.seg_fs, x86_opcodes, x86_opcodes) -op_seg(GS, cpu_state.seg_gs, x86_opcodes, x86_opcodes) -op_seg(SS, cpu_state.seg_ss, x86_opcodes, x86_opcodes) +op_seg(CS, cpu_state.seg_cs, x86_opcodes, x86_opcodes) op_seg(DS, cpu_state.seg_ds, x86_opcodes, x86_opcodes) + op_seg(ES, cpu_state.seg_es, x86_opcodes, x86_opcodes) op_seg(FS, cpu_state.seg_fs, x86_opcodes, x86_opcodes) op_seg( + GS, cpu_state.seg_gs, x86_opcodes, x86_opcodes) op_seg(SS, cpu_state.seg_ss, x86_opcodes, x86_opcodes) -op_seg(CS_REPE, cpu_state.seg_cs, x86_opcodes_REPE, x86_opcodes) -op_seg(DS_REPE, cpu_state.seg_ds, x86_opcodes_REPE, x86_opcodes) -op_seg(ES_REPE, cpu_state.seg_es, x86_opcodes_REPE, x86_opcodes) -op_seg(FS_REPE, cpu_state.seg_fs, x86_opcodes_REPE, x86_opcodes) -op_seg(GS_REPE, cpu_state.seg_gs, x86_opcodes_REPE, x86_opcodes) -op_seg(SS_REPE, cpu_state.seg_ss, x86_opcodes_REPE, x86_opcodes) + op_seg(CS_REPE, cpu_state.seg_cs, x86_opcodes_REPE, + x86_opcodes) op_seg(DS_REPE, cpu_state.seg_ds, x86_opcodes_REPE, + x86_opcodes) op_seg(ES_REPE, cpu_state.seg_es, x86_opcodes_REPE, x86_opcodes) + op_seg(FS_REPE, cpu_state.seg_fs, x86_opcodes_REPE, + x86_opcodes) op_seg(GS_REPE, cpu_state.seg_gs, x86_opcodes_REPE, + x86_opcodes) op_seg(SS_REPE, cpu_state.seg_ss, x86_opcodes_REPE, x86_opcodes) -op_seg(CS_REPNE, cpu_state.seg_cs, x86_opcodes_REPNE, x86_opcodes) -op_seg(DS_REPNE, cpu_state.seg_ds, x86_opcodes_REPNE, x86_opcodes) -op_seg(ES_REPNE, cpu_state.seg_es, x86_opcodes_REPNE, x86_opcodes) -op_seg(FS_REPNE, cpu_state.seg_fs, x86_opcodes_REPNE, x86_opcodes) -op_seg(GS_REPNE, cpu_state.seg_gs, x86_opcodes_REPNE, x86_opcodes) -op_seg(SS_REPNE, cpu_state.seg_ss, x86_opcodes_REPNE, x86_opcodes) + op_seg(CS_REPNE, cpu_state.seg_cs, x86_opcodes_REPNE, + x86_opcodes) op_seg(DS_REPNE, cpu_state.seg_ds, x86_opcodes_REPNE, x86_opcodes) + op_seg(ES_REPNE, cpu_state.seg_es, x86_opcodes_REPNE, x86_opcodes) + op_seg(FS_REPNE, cpu_state.seg_fs, x86_opcodes_REPNE, x86_opcodes) + op_seg(GS_REPNE, cpu_state.seg_gs, x86_opcodes_REPNE, x86_opcodes) + op_seg(SS_REPNE, cpu_state.seg_ss, x86_opcodes_REPNE, x86_opcodes) -static int op_66(uint32_t fetchdat) /*Data size select*/ + 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++; + 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); + 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++; + 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); + 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++; + 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); + 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++; + 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); + 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++; + 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); + 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++; + 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); + 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); } #endif /* _X86_OPS_PREFIX_H_ */ diff --git a/includes/private/cpu/x86_ops_rep.h b/includes/private/cpu/x86_ops_rep.h index 55a37cc7..ae0ff0f4 100644 --- a/includes/private/cpu/x86_ops_rep.h +++ b/includes/private/cpu/x86_ops_rep.h @@ -1,665 +1,735 @@ #ifndef _X86_OPS_REP_H_ #define _X86_OPS_REP_H_ -#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; \ - \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - check_io_perm(DX); \ - temp = inb(DX); \ - writememb(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \ - \ - if (cpu_state.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; \ - \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - check_io_perm(DX); \ - check_io_perm(DX+1); \ - temp = inw(DX); \ - writememw(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \ - \ - if (cpu_state.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; \ - \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - 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 (cpu_state.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; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - temp = readmemb(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ - check_io_perm(DX); \ - outb(DX, temp); \ - if (cpu_state.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; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - 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 (cpu_state.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; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - 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 (cpu_state.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*/ \ - if (CNT_REG > 0) \ - { \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - } \ - while (CNT_REG > 0) \ - { \ - uint8_t temp; \ - \ - CHECK_WRITE_REP(&cpu_state.seg_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 (cpu_state.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*/ \ - if (CNT_REG > 0) \ - { \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - } \ - while (CNT_REG > 0) \ - { \ - uint16_t temp; \ - \ - CHECK_WRITE_REP(&cpu_state.seg_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 (cpu_state.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*/ \ - if (CNT_REG > 0) \ - { \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - } \ - while (CNT_REG > 0) \ - { \ - uint32_t temp; \ - \ - CHECK_WRITE_REP(&cpu_state.seg_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 (cpu_state.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*/ \ - if (CNT_REG > 0) \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - while (CNT_REG > 0) \ - { \ - CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \ - writememb(es, DEST_REG, AL); if (cpu_state.abrt) return 1; \ - if (cpu_state.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*/ \ - if (CNT_REG > 0) \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - while (CNT_REG > 0) \ - { \ - CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG+1); \ - writememw(es, DEST_REG, AX); if (cpu_state.abrt) return 1; \ - if (cpu_state.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*/ \ - if (CNT_REG > 0) \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - while (CNT_REG > 0) \ - { \ - CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG+3); \ - writememl(es, DEST_REG, EAX); if (cpu_state.abrt) return 1; \ - if (cpu_state.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*/ \ - if (CNT_REG > 0) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - while (CNT_REG > 0) \ - { \ - AL = readmemb(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ - if (cpu_state.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*/ \ - if (CNT_REG > 0) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - while (CNT_REG > 0) \ - { \ - AX = readmemw(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ - if (cpu_state.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*/ \ - if (CNT_REG > 0) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - while (CNT_REG > 0) \ - { \ - EAX = readmeml(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ - if (cpu_state.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(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; \ + \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + check_io_perm(DX); \ + temp = inb(DX); \ + writememb(es, DEST_REG, temp); \ + if (cpu_state.abrt) \ + return 1; \ + \ + if (cpu_state.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; \ + \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + check_io_perm(DX); \ + check_io_perm(DX + 1); \ + temp = inw(DX); \ + writememw(es, DEST_REG, temp); \ + if (cpu_state.abrt) \ + return 1; \ + \ + if (cpu_state.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; \ + \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + 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 (cpu_state.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; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + temp = readmemb(cpu_state.ea_seg->base, SRC_REG); \ + if (cpu_state.abrt) \ + return 1; \ + check_io_perm(DX); \ + outb(DX, temp); \ + if (cpu_state.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; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + 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 (cpu_state.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; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + 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 (cpu_state.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*/ \ + if (CNT_REG > 0) { \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + } \ + while (CNT_REG > 0) { \ + uint8_t temp; \ + \ + CHECK_WRITE_REP(&cpu_state.seg_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 (cpu_state.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*/ \ + if (CNT_REG > 0) { \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + } \ + while (CNT_REG > 0) { \ + uint16_t temp; \ + \ + CHECK_WRITE_REP(&cpu_state.seg_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 (cpu_state.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*/ \ + if (CNT_REG > 0) { \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + } \ + while (CNT_REG > 0) { \ + uint32_t temp; \ + \ + CHECK_WRITE_REP(&cpu_state.seg_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 (cpu_state.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*/ \ + if (CNT_REG > 0) \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + while (CNT_REG > 0) { \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \ + writememb(es, DEST_REG, AL); \ + if (cpu_state.abrt) \ + return 1; \ + if (cpu_state.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*/ \ + if (CNT_REG > 0) \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + while (CNT_REG > 0) { \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1); \ + writememw(es, DEST_REG, AX); \ + if (cpu_state.abrt) \ + return 1; \ + if (cpu_state.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*/ \ + if (CNT_REG > 0) \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + while (CNT_REG > 0) { \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3); \ + writememl(es, DEST_REG, EAX); \ + if (cpu_state.abrt) \ + return 1; \ + if (cpu_state.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*/ \ + if (CNT_REG > 0) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + while (CNT_REG > 0) { \ + AL = readmemb(cpu_state.ea_seg->base, SRC_REG); \ + if (cpu_state.abrt) \ + return 1; \ + if (cpu_state.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*/ \ + if (CNT_REG > 0) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + while (CNT_REG > 0) { \ + AX = readmemw(cpu_state.ea_seg->base, SRC_REG); \ + if (cpu_state.abrt) \ + return 1; \ + if (cpu_state.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*/ \ + if (CNT_REG > 0) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + while (CNT_REG > 0) { \ + EAX = readmeml(cpu_state.ea_seg->base, SRC_REG); \ + if (cpu_state.abrt) \ + return 1; \ + if (cpu_state.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, temp2; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - SEG_CHECK_READ(&cpu_state.seg_es); \ - temp = readmemb(cpu_state.ea_seg->base, SRC_REG); \ - temp2 = readmemb(es, DEST_REG); if (cpu_state.abrt) return 1; \ - \ - if (cpu_state.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, temp2; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - SEG_CHECK_READ(&cpu_state.seg_es); \ - temp = readmemw(cpu_state.ea_seg->base, SRC_REG); \ - temp2 = readmemw(es, DEST_REG); if (cpu_state.abrt) return 1; \ - \ - if (cpu_state.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, temp2; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - SEG_CHECK_READ(&cpu_state.seg_es); \ - temp = readmeml(cpu_state.ea_seg->base, SRC_REG); \ - temp2 = readmeml(es, DEST_REG); if (cpu_state.abrt) return 1; \ - \ - if (cpu_state.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; \ - if ((CNT_REG > 0) && (FV == tempz)) \ - SEG_CHECK_READ(&cpu_state.seg_es); \ - 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 (cpu_state.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; \ - if ((CNT_REG > 0) && (FV == tempz)) \ - SEG_CHECK_READ(&cpu_state.seg_es); \ - 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 (cpu_state.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; \ - if ((CNT_REG > 0) && (FV == tempz)) \ - SEG_CHECK_READ(&cpu_state.seg_es); \ - 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 (cpu_state.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; \ -} +#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, temp2; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_READ(&cpu_state.seg_es); \ + temp = readmemb(cpu_state.ea_seg->base, SRC_REG); \ + temp2 = readmemb(es, DEST_REG); \ + if (cpu_state.abrt) \ + return 1; \ + \ + if (cpu_state.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, temp2; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_READ(&cpu_state.seg_es); \ + temp = readmemw(cpu_state.ea_seg->base, SRC_REG); \ + temp2 = readmemw(es, DEST_REG); \ + if (cpu_state.abrt) \ + return 1; \ + \ + if (cpu_state.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, temp2; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_READ(&cpu_state.seg_es); \ + temp = readmeml(cpu_state.ea_seg->base, SRC_REG); \ + temp2 = readmeml(es, DEST_REG); \ + if (cpu_state.abrt) \ + return 1; \ + \ + if (cpu_state.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; \ + if ((CNT_REG > 0) && (FV == tempz)) \ + SEG_CHECK_READ(&cpu_state.seg_es); \ + 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 (cpu_state.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; \ + if ((CNT_REG > 0) && (FV == tempz)) \ + SEG_CHECK_READ(&cpu_state.seg_es); \ + 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 (cpu_state.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; \ + if ((CNT_REG > 0) && (FV == tempz)) \ + SEG_CHECK_READ(&cpu_state.seg_es); \ + 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 (cpu_state.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) @@ -669,28 +739,28 @@ 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++; + 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); + 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++; + 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); + 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); } #endif /* _X86_OPS_REP_H_ */ diff --git a/includes/private/cpu/x86_ops_ret.h b/includes/private/cpu/x86_ops_ret.h index a5691a37..5ec3fadc 100644 --- a/includes/private/cpu/x86_ops_ret.h +++ b/includes/private/cpu/x86_ops_ret.h @@ -1,232 +1,230 @@ #ifndef _X86_OPS_RET_H_ #define _X86_OPS_RET_H_ -#define RETF_a16(stack_offset) \ - if ((msw&1) && !(cpu_state.eflags&VM_FLAG)) \ - { \ - pmoderetf(0, stack_offset); \ - return 1; \ - } \ - 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_a16(stack_offset) \ + if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) { \ + pmoderetf(0, stack_offset); \ + return 1; \ + } \ + 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) && !(cpu_state.eflags&VM_FLAG)) \ - { \ - pmoderetf(1, stack_offset); \ - return 1; \ - } \ - 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; +#define RETF_a32(stack_offset) \ + if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) { \ + pmoderetf(1, stack_offset); \ + return 1; \ + } \ + 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; - UNUSED(cycles_old); + int cycles_old = cycles; + UNUSED(cycles_old); - CPU_BLOCK_END(); - RETF_a16(0); + CPU_BLOCK_END(); + RETF_a16(0); - PREFETCH_RUN(cycles_old - cycles, 1, -1, 2, 0, 0, 0, 0); - PREFETCH_FLUSH(); - return 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; - UNUSED(cycles_old); + int cycles_old = cycles; + UNUSED(cycles_old); - CPU_BLOCK_END(); - RETF_a32(0); + CPU_BLOCK_END(); + RETF_a32(0); - PREFETCH_RUN(cycles_old - cycles, 1, -1, 0, 2, 0, 0, 1); - PREFETCH_FLUSH(); - return 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; - UNUSED(cycles_old); + uint16_t offset = getwordf(); + int cycles_old = cycles; + UNUSED(cycles_old); - CPU_BLOCK_END(); - RETF_a16(offset); + CPU_BLOCK_END(); + RETF_a16(offset); - PREFETCH_RUN(cycles_old - cycles, 3, -1, 2, 0, 0, 0, 0); - PREFETCH_FLUSH(); - return 0; + 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; - UNUSED(cycles_old); + uint16_t offset = getwordf(); + int cycles_old = cycles; + UNUSED(cycles_old); - CPU_BLOCK_END(); - RETF_a32(offset); + CPU_BLOCK_END(); + RETF_a32(offset); - PREFETCH_RUN(cycles_old - cycles, 3, -1, 0, 2, 0, 0, 1); - PREFETCH_FLUSH(); - return 0; + 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; - UNUSED(cycles_old); + int cycles_old = cycles; + UNUSED(cycles_old); - if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) { - x86gpf(NULL, 0); - return 1; - } - if (msw & 1) { - optype = IRET; - pmodeiret(0); - optype = 0; - } else { - uint16_t new_cs; - if (stack32) { - cpu_state.pc = readmemw(ss, ESP); - new_cs = readmemw(ss, ESP + 2); - cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ESP + 4) & 0xffd5) | 2; - ESP += 6; - } else { - cpu_state.pc = readmemw(ss, SP); - new_cs = readmemw(ss, ((SP + 2) & 0xffff)); - cpu_state.flags = (cpu_state.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(); + if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) { + x86gpf(NULL, 0); + return 1; + } + if (msw & 1) { + optype = IRET; + pmodeiret(0); + optype = 0; + } else { + uint16_t new_cs; + if (stack32) { + cpu_state.pc = readmemw(ss, ESP); + new_cs = readmemw(ss, ESP + 2); + cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ESP + 4) & 0xffd5) | 2; + ESP += 6; + } else { + cpu_state.pc = readmemw(ss, SP); + new_cs = readmemw(ss, ((SP + 2) & 0xffff)); + cpu_state.flags = (cpu_state.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; + 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; - UNUSED(cycles_old); + int cycles_old = cycles; + UNUSED(cycles_old); - if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) { - if (cr4 & CR4_VME) { - uint16_t new_pc, new_cs, new_flags; + if ((cr0 & 1) && (cpu_state.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; + 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) && (cpu_state.eflags & VIP_FLAG))) { - x86gpf(NULL, 0); - return 1; - } - SP += 6; - if (new_flags & I_FLAG) - cpu_state.eflags |= VIF_FLAG; - else - cpu_state.eflags &= ~VIF_FLAG; - cpu_state.flags = (cpu_state.flags & 0x3300) | (new_flags & 0x4cd5) | 2; - loadcs(new_cs); - cpu_state.pc = new_pc; + if ((new_flags & T_FLAG) || ((new_flags & I_FLAG) && (cpu_state.eflags & VIP_FLAG))) { + x86gpf(NULL, 0); + return 1; + } + SP += 6; + if (new_flags & I_FLAG) + cpu_state.eflags |= VIF_FLAG; + else + cpu_state.eflags &= ~VIF_FLAG; + cpu_state.flags = (cpu_state.flags & 0x3300) | (new_flags & 0x4cd5) | 2; + loadcs(new_cs); + cpu_state.pc = new_pc; - cycles -= timing_iret_rm; - } else { - x86gpf_expected(NULL, 0); - return 1; - } - } else { - if (msw & 1) { - optype = IRET; - pmodeiret(0); - optype = 0; - } else { - uint16_t new_cs; - if (stack32) { - cpu_state.pc = readmemw(ss, ESP); - new_cs = readmemw(ss, ESP + 2); - cpu_state.flags = (readmemw(ss, ESP + 4) & 0xffd5) | 2; - ESP += 6; - } else { - cpu_state.pc = readmemw(ss, SP); - new_cs = readmemw(ss, ((SP + 2) & 0xffff)); - cpu_state.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(); + cycles -= timing_iret_rm; + } else { + x86gpf_expected(NULL, 0); + return 1; + } + } else { + if (msw & 1) { + optype = IRET; + pmodeiret(0); + optype = 0; + } else { + uint16_t new_cs; + if (stack32) { + cpu_state.pc = readmemw(ss, ESP); + new_cs = readmemw(ss, ESP + 2); + cpu_state.flags = (readmemw(ss, ESP + 4) & 0xffd5) | 2; + ESP += 6; + } else { + cpu_state.pc = readmemw(ss, SP); + new_cs = readmemw(ss, ((SP + 2) & 0xffff)); + cpu_state.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; + 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; - UNUSED(cycles_old); + int cycles_old = cycles; + UNUSED(cycles_old); - if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) { - x86gpf_expected(NULL, 0); - return 1; - } - if (msw & 1) { - optype = IRET; - pmodeiret(1); - optype = 0; - } else { - uint16_t new_cs; - if (stack32) { - cpu_state.pc = readmeml(ss, ESP); - new_cs = readmemw(ss, ESP + 4); - cpu_state.flags = (readmemw(ss, ESP + 8) & 0xffd5) | 2; - cpu_state.eflags = readmemw(ss, ESP + 10); - ESP += 12; - } else { - cpu_state.pc = readmeml(ss, SP); - new_cs = readmemw(ss, ((SP + 4) & 0xffff)); - cpu_state.flags = (readmemw(ss, (SP + 8) & 0xffff) & 0xffd5) | 2; - cpu_state.eflags = readmemw(ss, (SP + 10) & 0xffff); - SP += 12; - } - loadcs(new_cs); - cycles -= timing_iret_rm; - } - flags_extract(); - nmi_enable = 1; - CPU_BLOCK_END(); + if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) { + x86gpf_expected(NULL, 0); + return 1; + } + if (msw & 1) { + optype = IRET; + pmodeiret(1); + optype = 0; + } else { + uint16_t new_cs; + if (stack32) { + cpu_state.pc = readmeml(ss, ESP); + new_cs = readmemw(ss, ESP + 4); + cpu_state.flags = (readmemw(ss, ESP + 8) & 0xffd5) | 2; + cpu_state.eflags = readmemw(ss, ESP + 10); + ESP += 12; + } else { + cpu_state.pc = readmeml(ss, SP); + new_cs = readmemw(ss, ((SP + 4) & 0xffff)); + cpu_state.flags = (readmemw(ss, (SP + 8) & 0xffff) & 0xffd5) | 2; + cpu_state.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; + PREFETCH_RUN(cycles_old - cycles, 1, -1, 0, 2, 0, 0, 1); + PREFETCH_FLUSH(); + return cpu_state.abrt; } #endif /* _X86_OPS_RET_H_ */ diff --git a/includes/private/cpu/x86_ops_set.h b/includes/private/cpu/x86_ops_set.h index b3e5266f..79f7cf3f 100644 --- a/includes/private/cpu/x86_ops_set.h +++ b/includes/private/cpu/x86_ops_set.h @@ -1,41 +1,25 @@ #ifndef _X86_OPS_SET_H_ #define _X86_OPS_SET_H_ -#define opSET(condition) \ - static int opSET ## condition ## _a16(uint32_t fetchdat) \ - { \ - fetch_ea_16(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - seteab((cond_ ## condition) ? 1 : 0); \ - CLOCK_CYCLES(4); \ - return cpu_state.abrt; \ - } \ - \ - static int opSET ## condition ## _a32(uint32_t fetchdat) \ - { \ - fetch_ea_32(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - seteab((cond_ ## condition) ? 1 : 0); \ - CLOCK_CYCLES(4); \ - return cpu_state.abrt; \ +#define opSET(condition) \ + static int opSET##condition##_a16(uint32_t fetchdat) { \ + fetch_ea_16(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + seteab((cond_##condition) ? 1 : 0); \ + CLOCK_CYCLES(4); \ + return cpu_state.abrt; \ + } \ + \ + static int opSET##condition##_a32(uint32_t fetchdat) { \ + fetch_ea_32(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + 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) +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) #endif /* _X86_OPS_SET_H_ */ diff --git a/includes/private/cpu/x86_ops_shift.h b/includes/private/cpu/x86_ops_shift.h index a55df768..f7e4acd8 100644 --- a/includes/private/cpu/x86_ops_shift.h +++ b/includes/private/cpu/x86_ops_shift.h @@ -1,627 +1,716 @@ #ifndef _X86_OPS_SHIFT_H_ #define _X86_OPS_SHIFT_H_ -#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*/ \ - temp = (temp << (c & 7)) | (temp >> (8-(c & 7))); \ - seteab(temp); if (cpu_state.abrt) return 1; \ - set_flags_rotate(FLAGS_ROL8, 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; \ - case 0x08: /*ROR b,CL*/ \ - temp = (temp >> (c & 7)) | (temp << (8-(c & 7))); \ - seteab(temp); if (cpu_state.abrt) return 1; \ - set_flags_rotate(FLAGS_ROR8, temp); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - 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 = cpu_state.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; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) cpu_state.flags |= C_FLAG; \ - if ((cpu_state.flags & C_FLAG) ^ (temp >> 7)) cpu_state.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 = cpu_state.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; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) cpu_state.flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x40) cpu_state.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_b(c, ea32) \ + { \ + uint8_t temp_orig = temp; \ + if (!c) \ + return 0; \ + flags_rebuild(); \ + switch (rmdat & 0x38) { \ + case 0x00: /*ROL b, c*/ \ + temp = (temp << (c & 7)) | (temp >> (8 - (c & 7))); \ + seteab(temp); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_rotate(FLAGS_ROL8, 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; \ + case 0x08: /*ROR b,CL*/ \ + temp = (temp >> (c & 7)) | (temp << (8 - (c & 7))); \ + seteab(temp); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_rotate(FLAGS_ROR8, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + 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 = cpu_state.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; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) \ + cpu_state.flags |= C_FLAG; \ + if ((cpu_state.flags & C_FLAG) ^ (temp >> 7)) \ + cpu_state.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 = cpu_state.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; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) \ + cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 1)) & 0x40) \ + cpu_state.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*/ \ - temp = (temp << (c & 15)) | (temp >> (16-(c & 15))); \ - seteaw(temp); if (cpu_state.abrt) return 1; \ - set_flags_rotate(FLAGS_ROL16, 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; \ - case 0x08: /*ROR w,CL*/ \ - temp = (temp >> (c & 15)) | (temp << (16-(c & 15))); \ - seteaw(temp); if (cpu_state.abrt) return 1; \ - set_flags_rotate(FLAGS_ROR16, 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; \ - case 0x10: /*RCL w, c*/ \ - temp2 = cpu_state.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; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) cpu_state.flags |= C_FLAG; \ - if ((cpu_state.flags & C_FLAG) ^ (temp >> 15)) cpu_state.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 = cpu_state.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; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) cpu_state.flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x4000) cpu_state.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_w(c, ea32) \ + { \ + uint16_t temp_orig = temp; \ + if (!c) \ + return 0; \ + flags_rebuild(); \ + switch (rmdat & 0x38) { \ + case 0x00: /*ROL w, c*/ \ + temp = (temp << (c & 15)) | (temp >> (16 - (c & 15))); \ + seteaw(temp); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_rotate(FLAGS_ROL16, 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; \ + case 0x08: /*ROR w,CL*/ \ + temp = (temp >> (c & 15)) | (temp << (16 - (c & 15))); \ + seteaw(temp); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_rotate(FLAGS_ROR16, 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; \ + case 0x10: /*RCL w, c*/ \ + temp2 = cpu_state.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; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) \ + cpu_state.flags |= C_FLAG; \ + if ((cpu_state.flags & C_FLAG) ^ (temp >> 15)) \ + cpu_state.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 = cpu_state.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; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) \ + cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 1)) & 0x4000) \ + cpu_state.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*/ \ - temp = (temp << c) | (temp >> (32-c)); \ - seteal(temp); if (cpu_state.abrt) return 1; \ - set_flags_rotate(FLAGS_ROL32, 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; \ - case 0x08: /*ROR l,CL*/ \ - temp = (temp >> c) | (temp << (32-c)); \ - seteal(temp); if (cpu_state.abrt) return 1; \ - set_flags_rotate(FLAGS_ROR32, 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; \ - 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; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) cpu_state.flags |= C_FLAG; \ - if ((cpu_state.flags & C_FLAG) ^ (temp >> 31)) cpu_state.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 = cpu_state.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; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) cpu_state.flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x40000000) cpu_state.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; \ - } \ +#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*/ \ + temp = (temp << c) | (temp >> (32 - c)); \ + seteal(temp); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_rotate(FLAGS_ROL32, 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; \ + case 0x08: /*ROR l,CL*/ \ + temp = (temp >> c) | (temp << (32 - c)); \ + seteal(temp); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_rotate(FLAGS_ROR32, 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; \ + 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; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) \ + cpu_state.flags |= C_FLAG; \ + if ((cpu_state.flags & C_FLAG) ^ (temp >> 31)) \ + cpu_state.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 = cpu_state.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; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) \ + cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 1)) & 0x40000000) \ + cpu_state.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; + int c; + int tempc; + uint8_t temp, temp2; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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; + int c; + int tempc; + uint8_t temp, temp2; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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; + int c; + int tempc; + uint16_t temp, temp2; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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; + int c; + int tempc; + uint16_t temp, temp2; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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; + int c; + int tempc; + uint32_t temp, temp2; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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; + int c; + int tempc; + uint32_t temp, temp2; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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; + int c = 1; + int tempc; + uint8_t temp, temp2; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteab(); - if (cpu_state.abrt) - return 1; - OP_SHIFT_b(c, 0); - return 0; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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; + int c = 1; + int tempc; + uint8_t temp, temp2; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteab(); - if (cpu_state.abrt) - return 1; - OP_SHIFT_b(c, 1); - return 0; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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; + int c = 1; + int tempc; + uint16_t temp, temp2; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteaw(); - if (cpu_state.abrt) - return 1; - OP_SHIFT_w(c, 0); - return 0; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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; + int c = 1; + int tempc; + uint16_t temp, temp2; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteaw(); - if (cpu_state.abrt) - return 1; - OP_SHIFT_w(c, 1); - return 0; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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; + int c = 1; + int tempc; + uint32_t temp, temp2; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteal(); - if (cpu_state.abrt) - return 1; - OP_SHIFT_l(c, 0); - return 0; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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; + int c = 1; + int tempc; + uint32_t temp, temp2; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteal(); - if (cpu_state.abrt) - return 1; - OP_SHIFT_l(c, 1); - return 0; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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; + int c; + int tempc; + uint8_t temp, temp2; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - c = CL & 31; - temp = geteab(); - if (cpu_state.abrt) - return 1; - OP_SHIFT_b(c, 0); - return 0; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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; + int c; + int tempc; + uint8_t temp, temp2; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - c = CL & 31; - temp = geteab(); - if (cpu_state.abrt) - return 1; - OP_SHIFT_b(c, 1); - return 0; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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; + int c; + int tempc; + uint16_t temp, temp2; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - c = CL & 31; - temp = geteaw(); - if (cpu_state.abrt) - return 1; - OP_SHIFT_w(c, 0); - return 0; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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; + int c; + int tempc; + uint16_t temp, temp2; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - c = CL & 31; - temp = geteaw(); - if (cpu_state.abrt) - return 1; - OP_SHIFT_w(c, 1); - return 0; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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; + int c; + int tempc; + uint32_t temp, temp2; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - c = CL & 31; - temp = geteal(); - if (cpu_state.abrt) - return 1; - OP_SHIFT_l(c, 0); - return 0; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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; + int c; + int tempc; + uint32_t temp, temp2; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - c = CL & 31; - temp = geteal(); - if (cpu_state.abrt) - return 1; - OP_SHIFT_l(c, 1); - return 0; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + c = CL & 31; + temp = geteal(); + if (cpu_state.abrt) + return 1; + OP_SHIFT_l(c, 1); + return 0; } -#define SHLD_w() \ - if (count) \ - { \ - uint16_t tempw = geteaw(); if (cpu_state.abrt) return 1; \ - int tempc = ((tempw << (count - 1)) & (1 << 15)) ? 1 : 0; \ - uint32_t 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) cpu_state.flags |= C_FLAG; \ +#define SHLD_w() \ + if (count) { \ + uint16_t tempw = geteaw(); \ + if (cpu_state.abrt) \ + return 1; \ + int tempc = ((tempw << (count - 1)) & (1 << 15)) ? 1 : 0; \ + uint32_t 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) \ + cpu_state.flags |= C_FLAG; \ } -#define SHLD_l() \ - if (count) \ - { \ - uint32_t templ = geteal(); if (cpu_state.abrt) return 1; \ - int 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) cpu_state.flags |= C_FLAG; \ +#define SHLD_l() \ + if (count) { \ + uint32_t templ = geteal(); \ + if (cpu_state.abrt) \ + return 1; \ + int 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) \ + cpu_state.flags |= C_FLAG; \ } -#define SHRD_w() \ - if (count) \ - { \ - uint16_t tempw = geteaw(); if (cpu_state.abrt) return 1; \ - int tempc = (tempw >> (count - 1)) & 1; \ - uint32_t 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) cpu_state.flags |= C_FLAG; \ +#define SHRD_w() \ + if (count) { \ + uint16_t tempw = geteaw(); \ + if (cpu_state.abrt) \ + return 1; \ + int tempc = (tempw >> (count - 1)) & 1; \ + uint32_t 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) \ + cpu_state.flags |= C_FLAG; \ } -#define SHRD_l() \ - if (count) \ - { \ - uint32_t templ = geteal(); if (cpu_state.abrt) return 1; \ - int 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) cpu_state.flags |= C_FLAG; \ +#define SHRD_l() \ + if (count) { \ + uint32_t templ = geteal(); \ + if (cpu_state.abrt) \ + return 1; \ + int 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) \ + cpu_state.flags |= C_FLAG; \ } -#define opSHxD(operation) \ - static int op ## operation ## _i_a16(uint32_t fetchdat) \ - { \ - int count; \ - \ - fetch_ea_16(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - 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); \ - if (cpu_mod != 3) \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - 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); \ - if (cpu_mod != 3) \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - 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); \ - if (cpu_mod != 3) \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - 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; \ +#define opSHxD(operation) \ + static int op##operation##_i_a16(uint32_t fetchdat) { \ + int count; \ + \ + fetch_ea_16(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + 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); \ + if (cpu_mod != 3) \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + 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); \ + if (cpu_mod != 3) \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + 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); \ + if (cpu_mod != 3) \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + 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) +opSHxD(SHLD_w) opSHxD(SHLD_l) opSHxD(SHRD_w) opSHxD(SHRD_l) #endif /* _X86_OPS_SHIFT_H_ */ diff --git a/includes/private/cpu/x86_ops_stack.h b/includes/private/cpu/x86_ops_stack.h index 655294df..003f2b32 100644 --- a/includes/private/cpu/x86_ops_stack.h +++ b/includes/private/cpu/x86_ops_stack.h @@ -1,39 +1,35 @@ #ifndef _X86_OPS_STACK_H_ #define _X86_OPS_STACK_H_ -#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_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 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_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; \ +#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) @@ -73,489 +69,493 @@ 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; + 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; + 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; + 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; + 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; + 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; + 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(); + uint16_t tempw = getbytef(); - if (tempw & 0x80) - tempw |= 0xFF00; - PUSH_W(tempw); + 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; + 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(); + uint32_t templ = getbytef(); - if (templ & 0x80) - templ |= 0xFFFFFF00; - PUSH_L(templ); + 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; + 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; + uint16_t temp; - temp = POP_W(); - if (cpu_state.abrt) - return 1; + temp = POP_W(); + if (cpu_state.abrt) + return 1; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(temp); - if (cpu_state.abrt) { - if (stack32) - ESP -= 2; - else - SP -= 2; - } + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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; + 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; + uint16_t temp; - temp = POP_W(); - if (cpu_state.abrt) - return 1; + temp = POP_W(); + if (cpu_state.abrt) + return 1; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(temp); - if (cpu_state.abrt) { - if (stack32) - ESP -= 2; - else - SP -= 2; - } + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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; + 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; + uint32_t temp; - temp = POP_L(); - if (cpu_state.abrt) - return 1; + temp = POP_L(); + if (cpu_state.abrt) + return 1; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteal(temp); - if (cpu_state.abrt) { - if (stack32) - ESP -= 4; - else - SP -= 4; - } + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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; + 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; + uint32_t temp; - temp = POP_L(); - if (cpu_state.abrt) - return 1; + temp = POP_L(); + if (cpu_state.abrt) + return 1; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteal(temp); - if (cpu_state.abrt) { - if (stack32) - ESP -= 4; - else - SP -= 4; - } + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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; + 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 = getwordf(); - int count = (fetchdat >> 16) & 0xff; - cpu_state.pc++; - uint32_t tempEBP = EBP, tempESP = ESP, frame_ptr; - int reads = 0, writes = 1, instr_cycles = 0; + uint16_t offset = getwordf(); + int count = (fetchdat >> 16) & 0xff; + cpu_state.pc++; + uint32_t tempEBP = EBP, tempESP = ESP, frame_ptr; + int reads = 0, writes = 1, instr_cycles = 0; - PUSH_W(BP); - if (cpu_state.abrt) - return 1; - frame_ptr = ESP; + PUSH_W(BP); + if (cpu_state.abrt) + return 1; + frame_ptr = ESP; - if (count > 0) { - while (--count) { - uint16_t tempw; + if (count > 0) { + while (--count) { + uint16_t tempw; - 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; + 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; + 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 = getwordf(); - int count = (fetchdat >> 16) & 0xff; - cpu_state.pc++; - uint32_t tempEBP = EBP, tempESP = ESP, frame_ptr; - int reads = 0, writes = 1, instr_cycles = 0; + uint16_t offset = getwordf(); + int count = (fetchdat >> 16) & 0xff; + cpu_state.pc++; + uint32_t tempEBP = EBP, tempESP = ESP, frame_ptr; + int reads = 0, writes = 1, instr_cycles = 0; - PUSH_L(EBP); - if (cpu_state.abrt) - return 1; - frame_ptr = ESP; + PUSH_L(EBP); + if (cpu_state.abrt) + return 1; + frame_ptr = ESP; - if (count > 0) { - while (--count) { - uint32_t templ; + if (count > 0) { + while (--count) { + uint32_t templ; - 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; + 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; + 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; + uint32_t tempESP = ESP; + uint16_t temp; - SP = BP; - temp = POP_W(); - if (cpu_state.abrt) { - ESP = tempESP; - return 1; - } - BP = 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; + 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; + uint32_t tempESP = ESP; + uint32_t temp; - ESP = EBP; - temp = POP_L(); - if (cpu_state.abrt) { - ESP = tempESP; - return 1; - } - EBP = 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; + 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 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; \ +#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); @@ -571,56 +571,56 @@ POP_SEG_OPS(FS, &cpu_state.seg_fs); POP_SEG_OPS(GS, &cpu_state.seg_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, &cpu_state.seg_ss); - if (cpu_state.abrt) { - ESP = temp_esp; - return 1; - } - CLOCK_CYCLES(is486 ? 3 : 7); - PREFETCH_RUN(is486 ? 3 : 7, 1, -1, 0, 0, 1, 0, 0); + uint16_t temp_seg; + uint32_t temp_esp = ESP; + temp_seg = POP_W(); + if (cpu_state.abrt) + return 1; + loadseg(temp_seg, &cpu_state.seg_ss); + if (cpu_state.abrt) { + ESP = temp_esp; + return 1; + } + 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 = &cpu_state.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); + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; + cpu_state.ssegs = 0; + cpu_state.ea_seg = &cpu_state.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; + 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, &cpu_state.seg_ss); - if (cpu_state.abrt) { - ESP = temp_esp; - return 1; - } - CLOCK_CYCLES(is486 ? 3 : 7); - PREFETCH_RUN(is486 ? 3 : 7, 1, -1, 0, 0, 1, 0, 0); + uint32_t temp_seg; + uint32_t temp_esp = ESP; + temp_seg = POP_L(); + if (cpu_state.abrt) + return 1; + loadseg(temp_seg & 0xffff, &cpu_state.seg_ss); + if (cpu_state.abrt) { + ESP = temp_esp; + return 1; + } + 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 = &cpu_state.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); + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; + cpu_state.ssegs = 0; + cpu_state.ea_seg = &cpu_state.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; + return 1; } #endif /* _X86_OPS_STACK_H_ */ diff --git a/includes/private/cpu/x86_ops_string.h b/includes/private/cpu/x86_ops_string.h index b64a9132..35e041e3 100644 --- a/includes/private/cpu/x86_ops_string.h +++ b/includes/private/cpu/x86_ops_string.h @@ -1,772 +1,772 @@ #ifndef _X86_OPS_STRING_H_ #define _X86_OPS_STRING_H_ static int opMOVSB_a16(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - SEG_CHECK_WRITE(&cpu_state.seg_es); - temp = readmemb(cpu_state.ea_seg->base, SI); - if (cpu_state.abrt) - return 1; - writememb(es, DI, temp); - if (cpu_state.abrt) - return 1; - if (cpu_state.flags & D_FLAG) { - DI--; - SI--; - } else { - DI++; - SI++; - } - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 1, 0, 1, 0, 0); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_WRITE(&cpu_state.seg_es); + temp = readmemb(cpu_state.ea_seg->base, SI); + if (cpu_state.abrt) + return 1; + writememb(es, DI, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) { + DI--; + SI--; + } else { + DI++; + SI++; + } + 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; + uint8_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - SEG_CHECK_WRITE(&cpu_state.seg_es); - temp = readmemb(cpu_state.ea_seg->base, ESI); - if (cpu_state.abrt) - return 1; - writememb(es, EDI, temp); - if (cpu_state.abrt) - return 1; - if (cpu_state.flags & D_FLAG) { - EDI--; - ESI--; - } else { - EDI++; - ESI++; - } - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 1, 0, 1, 0, 1); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_WRITE(&cpu_state.seg_es); + temp = readmemb(cpu_state.ea_seg->base, ESI); + if (cpu_state.abrt) + return 1; + writememb(es, EDI, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) { + EDI--; + ESI--; + } else { + EDI++; + ESI++; + } + 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; + uint16_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - SEG_CHECK_WRITE(&cpu_state.seg_es); - temp = readmemw(cpu_state.ea_seg->base, SI); - if (cpu_state.abrt) - return 1; - writememw(es, DI, temp); - if (cpu_state.abrt) - return 1; - if (cpu_state.flags & D_FLAG) { - DI -= 2; - SI -= 2; - } else { - DI += 2; - SI += 2; - } - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 1, 0, 1, 0, 0); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_WRITE(&cpu_state.seg_es); + temp = readmemw(cpu_state.ea_seg->base, SI); + if (cpu_state.abrt) + return 1; + writememw(es, DI, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) { + DI -= 2; + SI -= 2; + } else { + DI += 2; + SI += 2; + } + 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; + uint16_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - SEG_CHECK_WRITE(&cpu_state.seg_es); - temp = readmemw(cpu_state.ea_seg->base, ESI); - if (cpu_state.abrt) - return 1; - writememw(es, EDI, temp); - if (cpu_state.abrt) - return 1; - if (cpu_state.flags & D_FLAG) { - EDI -= 2; - ESI -= 2; - } else { - EDI += 2; - ESI += 2; - } - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 1, 0, 1, 0, 1); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_WRITE(&cpu_state.seg_es); + temp = readmemw(cpu_state.ea_seg->base, ESI); + if (cpu_state.abrt) + return 1; + writememw(es, EDI, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) { + EDI -= 2; + ESI -= 2; + } else { + EDI += 2; + ESI += 2; + } + 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; + uint32_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - SEG_CHECK_WRITE(&cpu_state.seg_es); - temp = readmeml(cpu_state.ea_seg->base, SI); - if (cpu_state.abrt) - return 1; - writememl(es, DI, temp); - if (cpu_state.abrt) - return 1; - if (cpu_state.flags & D_FLAG) { - DI -= 4; - SI -= 4; - } else { - DI += 4; - SI += 4; - } - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 0, 1, 0, 1, 0); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_WRITE(&cpu_state.seg_es); + temp = readmeml(cpu_state.ea_seg->base, SI); + if (cpu_state.abrt) + return 1; + writememl(es, DI, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) { + DI -= 4; + SI -= 4; + } else { + DI += 4; + SI += 4; + } + 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; + uint32_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - SEG_CHECK_WRITE(&cpu_state.seg_es); - temp = readmeml(cpu_state.ea_seg->base, ESI); - if (cpu_state.abrt) - return 1; - writememl(es, EDI, temp); - if (cpu_state.abrt) - return 1; - if (cpu_state.flags & D_FLAG) { - EDI -= 4; - ESI -= 4; - } else { - EDI += 4; - ESI += 4; - } - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 0, 1, 0, 1, 1); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_WRITE(&cpu_state.seg_es); + temp = readmeml(cpu_state.ea_seg->base, ESI); + if (cpu_state.abrt) + return 1; + writememl(es, EDI, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) { + EDI -= 4; + ESI -= 4; + } else { + EDI += 4; + ESI += 4; + } + 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, dst; + uint8_t src, dst; - SEG_CHECK_READ(cpu_state.ea_seg); - SEG_CHECK_READ(&cpu_state.seg_es); - src = readmemb(cpu_state.ea_seg->base, SI); - dst = readmemb(es, DI); - if (cpu_state.abrt) - return 1; - setsub8(src, dst); - if (cpu_state.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; + SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(&cpu_state.seg_es); + src = readmemb(cpu_state.ea_seg->base, SI); + dst = readmemb(es, DI); + if (cpu_state.abrt) + return 1; + setsub8(src, dst); + if (cpu_state.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, dst; + uint8_t src, dst; - SEG_CHECK_READ(cpu_state.ea_seg); - SEG_CHECK_READ(&cpu_state.seg_es); - src = readmemb(cpu_state.ea_seg->base, ESI); - dst = readmemb(es, EDI); - if (cpu_state.abrt) - return 1; - setsub8(src, dst); - if (cpu_state.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; + SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(&cpu_state.seg_es); + src = readmemb(cpu_state.ea_seg->base, ESI); + dst = readmemb(es, EDI); + if (cpu_state.abrt) + return 1; + setsub8(src, dst); + if (cpu_state.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, dst; + uint16_t src, dst; - SEG_CHECK_READ(cpu_state.ea_seg); - SEG_CHECK_READ(&cpu_state.seg_es); - src = readmemw(cpu_state.ea_seg->base, SI); - dst = readmemw(es, DI); - if (cpu_state.abrt) - return 1; - setsub16(src, dst); - if (cpu_state.flags & D_FLAG) { - DI -= 2; - SI -= 2; - } else { - DI += 2; - SI += 2; - } - CLOCK_CYCLES((is486) ? 8 : 10); - PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 2, 0, 0, 0, 0); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(&cpu_state.seg_es); + src = readmemw(cpu_state.ea_seg->base, SI); + dst = readmemw(es, DI); + if (cpu_state.abrt) + return 1; + setsub16(src, dst); + if (cpu_state.flags & D_FLAG) { + DI -= 2; + SI -= 2; + } else { + DI += 2; + SI += 2; + } + 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, dst; + uint16_t src, dst; - SEG_CHECK_READ(cpu_state.ea_seg); - SEG_CHECK_READ(&cpu_state.seg_es); - src = readmemw(cpu_state.ea_seg->base, ESI); - dst = readmemw(es, EDI); - if (cpu_state.abrt) - return 1; - setsub16(src, dst); - if (cpu_state.flags & D_FLAG) { - EDI -= 2; - ESI -= 2; - } else { - EDI += 2; - ESI += 2; - } - CLOCK_CYCLES((is486) ? 8 : 10); - PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 2, 0, 0, 0, 1); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(&cpu_state.seg_es); + src = readmemw(cpu_state.ea_seg->base, ESI); + dst = readmemw(es, EDI); + if (cpu_state.abrt) + return 1; + setsub16(src, dst); + if (cpu_state.flags & D_FLAG) { + EDI -= 2; + ESI -= 2; + } else { + EDI += 2; + ESI += 2; + } + 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, dst; + uint32_t src, dst; - SEG_CHECK_READ(cpu_state.ea_seg); - SEG_CHECK_READ(&cpu_state.seg_es); - src = readmeml(cpu_state.ea_seg->base, SI); - dst = readmeml(es, DI); - if (cpu_state.abrt) - return 1; - setsub32(src, dst); - if (cpu_state.flags & D_FLAG) { - DI -= 4; - SI -= 4; - } else { - DI += 4; - SI += 4; - } - CLOCK_CYCLES((is486) ? 8 : 10); - PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 0, 2, 0, 0, 0); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(&cpu_state.seg_es); + src = readmeml(cpu_state.ea_seg->base, SI); + dst = readmeml(es, DI); + if (cpu_state.abrt) + return 1; + setsub32(src, dst); + if (cpu_state.flags & D_FLAG) { + DI -= 4; + SI -= 4; + } else { + DI += 4; + SI += 4; + } + 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, dst; + uint32_t src, dst; - SEG_CHECK_READ(cpu_state.ea_seg); - SEG_CHECK_READ(&cpu_state.seg_es); - src = readmeml(cpu_state.ea_seg->base, ESI); - dst = readmeml(es, EDI); - if (cpu_state.abrt) - return 1; - setsub32(src, dst); - if (cpu_state.flags & D_FLAG) { - EDI -= 4; - ESI -= 4; - } else { - EDI += 4; - ESI += 4; - } - CLOCK_CYCLES((is486) ? 8 : 10); - PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 0, 2, 0, 0, 1); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + SEG_CHECK_READ(&cpu_state.seg_es); + src = readmeml(cpu_state.ea_seg->base, ESI); + dst = readmeml(es, EDI); + if (cpu_state.abrt) + return 1; + setsub32(src, dst); + if (cpu_state.flags & D_FLAG) { + EDI -= 4; + ESI -= 4; + } else { + EDI += 4; + ESI += 4; + } + 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) { - SEG_CHECK_WRITE(&cpu_state.seg_es); - writememb(es, DI, AL); - if (cpu_state.abrt) - return 1; - if (cpu_state.flags & D_FLAG) - DI--; - else - DI++; - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 1, -1, 0, 0, 1, 0, 0); - return 0; + SEG_CHECK_WRITE(&cpu_state.seg_es); + writememb(es, DI, AL); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + DI--; + else + DI++; + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 0, 0, 1, 0, 0); + return 0; } static int opSTOSB_a32(uint32_t fetchdat) { - SEG_CHECK_WRITE(&cpu_state.seg_es); - writememb(es, EDI, AL); - if (cpu_state.abrt) - return 1; - if (cpu_state.flags & D_FLAG) - EDI--; - else - EDI++; - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 1, -1, 0, 0, 1, 0, 1); - return 0; + SEG_CHECK_WRITE(&cpu_state.seg_es); + writememb(es, EDI, AL); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + EDI--; + else + EDI++; + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 0, 0, 1, 0, 1); + return 0; } static int opSTOSW_a16(uint32_t fetchdat) { - SEG_CHECK_WRITE(&cpu_state.seg_es); - writememw(es, DI, AX); - if (cpu_state.abrt) - return 1; - if (cpu_state.flags & D_FLAG) - DI -= 2; - else - DI += 2; - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 1, -1, 0, 0, 1, 0, 0); - return 0; + SEG_CHECK_WRITE(&cpu_state.seg_es); + writememw(es, DI, AX); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + DI -= 2; + else + DI += 2; + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 0, 0, 1, 0, 0); + return 0; } static int opSTOSW_a32(uint32_t fetchdat) { - SEG_CHECK_WRITE(&cpu_state.seg_es); - writememw(es, EDI, AX); - if (cpu_state.abrt) - return 1; - if (cpu_state.flags & D_FLAG) - EDI -= 2; - else - EDI += 2; - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 1, -1, 0, 0, 1, 0, 1); - return 0; + SEG_CHECK_WRITE(&cpu_state.seg_es); + writememw(es, EDI, AX); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + EDI -= 2; + else + EDI += 2; + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 0, 0, 1, 0, 1); + return 0; } static int opSTOSL_a16(uint32_t fetchdat) { - SEG_CHECK_WRITE(&cpu_state.seg_es); - writememl(es, DI, EAX); - if (cpu_state.abrt) - return 1; - if (cpu_state.flags & D_FLAG) - DI -= 4; - else - DI += 4; - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 1, -1, 0, 0, 0, 1, 0); - return 0; + SEG_CHECK_WRITE(&cpu_state.seg_es); + writememl(es, DI, EAX); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + DI -= 4; + else + DI += 4; + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 0, 0, 0, 1, 0); + return 0; } static int opSTOSL_a32(uint32_t fetchdat) { - SEG_CHECK_WRITE(&cpu_state.seg_es); - writememl(es, EDI, EAX); - if (cpu_state.abrt) - return 1; - if (cpu_state.flags & D_FLAG) - EDI -= 4; - else - EDI += 4; - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 1, -1, 0, 0, 0, 1, 1); - return 0; + SEG_CHECK_WRITE(&cpu_state.seg_es); + writememl(es, EDI, EAX); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + EDI -= 4; + else + EDI += 4; + 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; + uint8_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - temp = readmemb(cpu_state.ea_seg->base, SI); - if (cpu_state.abrt) - return 1; - AL = temp; - if (cpu_state.flags & D_FLAG) - SI--; - else - SI++; - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + temp = readmemb(cpu_state.ea_seg->base, SI); + if (cpu_state.abrt) + return 1; + AL = temp; + if (cpu_state.flags & D_FLAG) + SI--; + else + SI++; + 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; + uint8_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - temp = readmemb(cpu_state.ea_seg->base, ESI); - if (cpu_state.abrt) - return 1; - AL = temp; - if (cpu_state.flags & D_FLAG) - ESI--; - else - ESI++; - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 1); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + temp = readmemb(cpu_state.ea_seg->base, ESI); + if (cpu_state.abrt) + return 1; + AL = temp; + if (cpu_state.flags & D_FLAG) + ESI--; + else + ESI++; + 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; + uint16_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - temp = readmemw(cpu_state.ea_seg->base, SI); - if (cpu_state.abrt) - return 1; - AX = temp; - if (cpu_state.flags & D_FLAG) - SI -= 2; - else - SI += 2; - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + temp = readmemw(cpu_state.ea_seg->base, SI); + if (cpu_state.abrt) + return 1; + AX = temp; + if (cpu_state.flags & D_FLAG) + SI -= 2; + else + SI += 2; + 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; + uint16_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - temp = readmemw(cpu_state.ea_seg->base, ESI); - if (cpu_state.abrt) - return 1; - AX = temp; - if (cpu_state.flags & D_FLAG) - ESI -= 2; - else - ESI += 2; - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 1); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + temp = readmemw(cpu_state.ea_seg->base, ESI); + if (cpu_state.abrt) + return 1; + AX = temp; + if (cpu_state.flags & D_FLAG) + ESI -= 2; + else + ESI += 2; + 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; + uint32_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - temp = readmeml(cpu_state.ea_seg->base, SI); - if (cpu_state.abrt) - return 1; - EAX = temp; - if (cpu_state.flags & D_FLAG) - SI -= 4; - else - SI += 4; - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 0, 1, 0, 0, 0); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + temp = readmeml(cpu_state.ea_seg->base, SI); + if (cpu_state.abrt) + return 1; + EAX = temp; + if (cpu_state.flags & D_FLAG) + SI -= 4; + else + SI += 4; + 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; + uint32_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - temp = readmeml(cpu_state.ea_seg->base, ESI); - if (cpu_state.abrt) - return 1; - EAX = temp; - if (cpu_state.flags & D_FLAG) - ESI -= 4; - else - ESI += 4; - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 0, 1, 0, 0, 1); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + temp = readmeml(cpu_state.ea_seg->base, ESI); + if (cpu_state.abrt) + return 1; + EAX = temp; + if (cpu_state.flags & D_FLAG) + ESI -= 4; + else + ESI += 4; + 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; + uint8_t temp; - SEG_CHECK_READ(&cpu_state.seg_es); - temp = readmemb(es, DI); - if (cpu_state.abrt) - return 1; - setsub8(AL, temp); - if (cpu_state.flags & D_FLAG) - DI--; - else - DI++; - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 1, 0, 0, 0, 0); - return 0; + SEG_CHECK_READ(&cpu_state.seg_es); + temp = readmemb(es, DI); + if (cpu_state.abrt) + return 1; + setsub8(AL, temp); + if (cpu_state.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; + uint8_t temp; - SEG_CHECK_READ(&cpu_state.seg_es); - temp = readmemb(es, EDI); - if (cpu_state.abrt) - return 1; - setsub8(AL, temp); - if (cpu_state.flags & D_FLAG) - EDI--; - else - EDI++; - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 1, 0, 0, 0, 1); - return 0; + SEG_CHECK_READ(&cpu_state.seg_es); + temp = readmemb(es, EDI); + if (cpu_state.abrt) + return 1; + setsub8(AL, temp); + if (cpu_state.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; + uint16_t temp; - SEG_CHECK_READ(&cpu_state.seg_es); - temp = readmemw(es, DI); - if (cpu_state.abrt) - return 1; - setsub16(AX, temp); - if (cpu_state.flags & D_FLAG) - DI -= 2; - else - DI += 2; - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 1, 0, 0, 0, 0); - return 0; + SEG_CHECK_READ(&cpu_state.seg_es); + temp = readmemw(es, DI); + if (cpu_state.abrt) + return 1; + setsub16(AX, temp); + if (cpu_state.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; + uint16_t temp; - SEG_CHECK_READ(&cpu_state.seg_es); - temp = readmemw(es, EDI); - if (cpu_state.abrt) - return 1; - setsub16(AX, temp); - if (cpu_state.flags & D_FLAG) - EDI -= 2; - else - EDI += 2; - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 1, 0, 0, 0, 1); - return 0; + SEG_CHECK_READ(&cpu_state.seg_es); + temp = readmemw(es, EDI); + if (cpu_state.abrt) + return 1; + setsub16(AX, temp); + if (cpu_state.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; + uint32_t temp; - SEG_CHECK_READ(&cpu_state.seg_es); - temp = readmeml(es, DI); - if (cpu_state.abrt) - return 1; - setsub32(EAX, temp); - if (cpu_state.flags & D_FLAG) - DI -= 4; - else - DI += 4; - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 0, 1, 0, 0, 0); - return 0; + SEG_CHECK_READ(&cpu_state.seg_es); + temp = readmeml(es, DI); + if (cpu_state.abrt) + return 1; + setsub32(EAX, temp); + if (cpu_state.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; + uint32_t temp; - SEG_CHECK_READ(&cpu_state.seg_es); - temp = readmeml(es, EDI); - if (cpu_state.abrt) - return 1; - setsub32(EAX, temp); - if (cpu_state.flags & D_FLAG) - EDI -= 4; - else - EDI += 4; - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 0, 1, 0, 0, 1); - return 0; + SEG_CHECK_READ(&cpu_state.seg_es); + temp = readmeml(es, EDI); + if (cpu_state.abrt) + return 1; + setsub32(EAX, temp); + if (cpu_state.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; + uint8_t temp; - SEG_CHECK_WRITE(&cpu_state.seg_es); - check_io_perm(DX); - temp = inb(DX); - writememb(es, DI, temp); - if (cpu_state.abrt) - return 1; - if (cpu_state.flags & D_FLAG) - DI--; - else - DI++; - CLOCK_CYCLES(15); - PREFETCH_RUN(15, 1, -1, 1, 0, 1, 0, 0); - return 0; + SEG_CHECK_WRITE(&cpu_state.seg_es); + check_io_perm(DX); + temp = inb(DX); + writememb(es, DI, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + DI--; + else + DI++; + 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; + uint8_t temp; - SEG_CHECK_WRITE(&cpu_state.seg_es); - check_io_perm(DX); - temp = inb(DX); - writememb(es, EDI, temp); - if (cpu_state.abrt) - return 1; - if (cpu_state.flags & D_FLAG) - EDI--; - else - EDI++; - CLOCK_CYCLES(15); - PREFETCH_RUN(15, 1, -1, 1, 0, 1, 0, 1); - return 0; + SEG_CHECK_WRITE(&cpu_state.seg_es); + check_io_perm(DX); + temp = inb(DX); + writememb(es, EDI, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + EDI--; + else + EDI++; + 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; + uint16_t temp; - SEG_CHECK_WRITE(&cpu_state.seg_es); - check_io_perm(DX); - check_io_perm(DX + 1); - temp = inw(DX); - writememw(es, DI, temp); - if (cpu_state.abrt) - return 1; - if (cpu_state.flags & D_FLAG) - DI -= 2; - else - DI += 2; - CLOCK_CYCLES(15); - PREFETCH_RUN(15, 1, -1, 1, 0, 1, 0, 0); - return 0; + SEG_CHECK_WRITE(&cpu_state.seg_es); + check_io_perm(DX); + check_io_perm(DX + 1); + temp = inw(DX); + writememw(es, DI, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + DI -= 2; + else + DI += 2; + 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; + uint16_t temp; - SEG_CHECK_WRITE(&cpu_state.seg_es); - check_io_perm(DX); - check_io_perm(DX + 1); - temp = inw(DX); - writememw(es, EDI, temp); - if (cpu_state.abrt) - return 1; - if (cpu_state.flags & D_FLAG) - EDI -= 2; - else - EDI += 2; - CLOCK_CYCLES(15); - PREFETCH_RUN(15, 1, -1, 1, 0, 1, 0, 1); - return 0; + SEG_CHECK_WRITE(&cpu_state.seg_es); + check_io_perm(DX); + check_io_perm(DX + 1); + temp = inw(DX); + writememw(es, EDI, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + EDI -= 2; + else + EDI += 2; + 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; + uint32_t temp; - SEG_CHECK_WRITE(&cpu_state.seg_es); - 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 (cpu_state.flags & D_FLAG) - DI -= 4; - else - DI += 4; - CLOCK_CYCLES(15); - PREFETCH_RUN(15, 1, -1, 0, 1, 0, 1, 0); - return 0; + SEG_CHECK_WRITE(&cpu_state.seg_es); + 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 (cpu_state.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; + uint32_t temp; - SEG_CHECK_WRITE(&cpu_state.seg_es); - 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 (cpu_state.flags & D_FLAG) - EDI -= 4; - else - EDI += 4; - CLOCK_CYCLES(15); - PREFETCH_RUN(15, 1, -1, 0, 1, 0, 1, 1); - return 0; + SEG_CHECK_WRITE(&cpu_state.seg_es); + 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 (cpu_state.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; + uint8_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - temp = readmemb(cpu_state.ea_seg->base, SI); - if (cpu_state.abrt) - return 1; - check_io_perm(DX); - if (cpu_state.flags & D_FLAG) - SI--; - else - SI++; - outb(DX, temp); - CLOCK_CYCLES(14); - PREFETCH_RUN(14, 1, -1, 1, 0, 1, 0, 0); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + temp = readmemb(cpu_state.ea_seg->base, SI); + if (cpu_state.abrt) + return 1; + check_io_perm(DX); + if (cpu_state.flags & D_FLAG) + SI--; + else + SI++; + 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; + uint8_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - temp = readmemb(cpu_state.ea_seg->base, ESI); - if (cpu_state.abrt) - return 1; - check_io_perm(DX); - if (cpu_state.flags & D_FLAG) - ESI--; - else - ESI++; - outb(DX, temp); - CLOCK_CYCLES(14); - PREFETCH_RUN(14, 1, -1, 1, 0, 1, 0, 1); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + temp = readmemb(cpu_state.ea_seg->base, ESI); + if (cpu_state.abrt) + return 1; + check_io_perm(DX); + if (cpu_state.flags & D_FLAG) + ESI--; + else + ESI++; + 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; + uint16_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - temp = readmemw(cpu_state.ea_seg->base, SI); - if (cpu_state.abrt) - return 1; - check_io_perm(DX); - check_io_perm(DX + 1); - if (cpu_state.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; + SEG_CHECK_READ(cpu_state.ea_seg); + temp = readmemw(cpu_state.ea_seg->base, SI); + if (cpu_state.abrt) + return 1; + check_io_perm(DX); + check_io_perm(DX + 1); + if (cpu_state.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; + uint16_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - temp = readmemw(cpu_state.ea_seg->base, ESI); - if (cpu_state.abrt) - return 1; - check_io_perm(DX); - check_io_perm(DX + 1); - if (cpu_state.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; + SEG_CHECK_READ(cpu_state.ea_seg); + temp = readmemw(cpu_state.ea_seg->base, ESI); + if (cpu_state.abrt) + return 1; + check_io_perm(DX); + check_io_perm(DX + 1); + if (cpu_state.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; + uint32_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - 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 (cpu_state.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; + SEG_CHECK_READ(cpu_state.ea_seg); + 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 (cpu_state.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; + uint32_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - 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 (cpu_state.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; + SEG_CHECK_READ(cpu_state.ea_seg); + 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 (cpu_state.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; } #endif /* _X86_OPS_STRING_H_ */ diff --git a/includes/private/cpu/x86_ops_xchg.h b/includes/private/cpu/x86_ops_xchg.h index 6a248f98..aeab6f1a 100644 --- a/includes/private/cpu/x86_ops_xchg.h +++ b/includes/private/cpu/x86_ops_xchg.h @@ -1,240 +1,232 @@ #ifndef _X86_OPS_XCHG_H_ #define _X86_OPS_XCHG_H_ static int opXCHG_b_a16(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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; + uint8_t temp; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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; + uint16_t temp; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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; + uint16_t temp; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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; + uint32_t temp; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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; + uint32_t temp; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; \ +#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) +opBSWAP(EAX) opBSWAP(EBX) opBSWAP(ECX) opBSWAP(EDX) opBSWAP(ESI) opBSWAP(EDI) opBSWAP(EBP) opBSWAP(ESP) #endif /* _X86_OPS_XCHG_H_ */ diff --git a/includes/private/cpu/x87.h b/includes/private/cpu/x87.h index 04dd0248..353ecc32 100644 --- a/includes/private/cpu/x87.h +++ b/includes/private/cpu/x87.h @@ -1,22 +1,22 @@ #ifndef _X87_H_ #define _X87_H_ -#define C0 (1<<8) -#define C1 (1<<9) -#define C2 (1<<10) -#define C3 (1<<14) +#define C0 (1 << 8) +#define C1 (1 << 9) +#define C2 (1 << 10) +#define C3 (1 << 14) uint32_t x87_pc_off, x87_op_off; uint16_t x87_pc_seg, x87_op_seg; static inline void x87_set_mmx() { - cpu_state.TOP = 0; - *(uint64_t *)cpu_state.tag = 0x0101010101010101ull; - cpu_state.ismmx = 1; + cpu_state.TOP = 0; + *(uint64_t *)cpu_state.tag = 0x0101010101010101ull; + cpu_state.ismmx = 1; } static inline void x87_emms() { - *(uint64_t *)cpu_state.tag = 0; - cpu_state.ismmx = 0; + *(uint64_t *)cpu_state.tag = 0; + cpu_state.ismmx = 0; } uint16_t x87_gettag(); @@ -24,15 +24,15 @@ void x87_settag(uint16_t new_tag); void x87_dumpregs(); void x87_reset(); -#define TAG_EMPTY 0 -#define TAG_VALID (1 << 0) +#define TAG_EMPTY 0 +#define TAG_VALID (1 << 0) /*Hack for FPU copy. If set then MM[].q contains the 64-bit integer loaded by FILD*/ #define TAG_UINT64 (1 << 7) #define X87_ROUNDING_NEAREST 0 -#define X87_ROUNDING_DOWN 1 -#define X87_ROUNDING_UP 2 -#define X87_ROUNDING_CHOP 3 +#define X87_ROUNDING_DOWN 1 +#define X87_ROUNDING_UP 2 +#define X87_ROUNDING_CHOP 3 void codegen_set_rounding_mode(int mode); diff --git a/includes/private/cpu/x87_ops.h b/includes/private/cpu/x87_ops.h index c33f3416..e1ce852d 100644 --- a/includes/private/cpu/x87_ops.h +++ b/includes/private/cpu/x87_ops.h @@ -8,209 +8,203 @@ 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 ST(x) cpu_state.ST[((cpu_state.TOP + (x)) & 7)] #define STATUS_ZERODIVIDE 4 #define FPCW_DISI (1 << 7) -#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; \ +#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_checkexceptions() { -} +static inline void x87_checkexceptions() {} static inline void x87_push(double i) { - cpu_state.TOP--; - cpu_state.ST[cpu_state.TOP & 7] = i; - cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID; + cpu_state.TOP--; + cpu_state.ST[cpu_state.TOP & 7] = i; + cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID; } static inline void x87_push_u64(uint64_t i) { - union { - double d; - uint64_t ll; - } td; + union { + double d; + uint64_t ll; + } td; - td.ll = i; + td.ll = i; - cpu_state.TOP--; - cpu_state.ST[cpu_state.TOP & 7] = td.d; - cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID; + cpu_state.TOP--; + cpu_state.ST[cpu_state.TOP & 7] = td.d; + cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID; } static inline double x87_pop() { - double t = cpu_state.ST[cpu_state.TOP & 7]; - cpu_state.tag[cpu_state.TOP & 7] = TAG_EMPTY; - cpu_state.TOP++; - return t; + double t = cpu_state.ST[cpu_state.TOP & 7]; + cpu_state.tag[cpu_state.TOP & 7] = TAG_EMPTY; + cpu_state.TOP++; + return t; } static inline int64_t x87_fround(double b) { - int64_t a, c; + 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; - } + 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; + return 0; } #define BIAS80 16383 #define BIAS64 1023 static inline double x87_ld80() { - 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); + 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); - int64_t exp64 = (((test.begin & 0x7fff) - BIAS80)); - int64_t blah = ((exp64 > 0) ? exp64 : -exp64) & 0x3ff; - int64_t exp64final = ((exp64 > 0) ? blah : -blah) + BIAS64; + int64_t exp64 = (((test.begin & 0x7fff) - BIAS80)); + int64_t blah = ((exp64 > 0) ? exp64 : -exp64) & 0x3ff; + int64_t exp64final = ((exp64 > 0) ? blah : -blah) + BIAS64; - int64_t mant64 = (test.eind.ll >> 11) & (0xfffffffffffff); - int64_t sign = (test.begin & 0x8000) ? 1 : 0; + int64_t mant64 = (test.eind.ll >> 11) & (0xfffffffffffff); + int64_t 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++; + 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; + test.eind.ll = (sign << 63) | (exp64final << 52) | mant64; - return test.eind.d; + return test.eind.d; } static inline void x87_st80(double d) { - struct { - int16_t begin; - union { - double d; - uint64_t ll; - } eind; - } test; + struct { + int16_t begin; + union { + double d; + uint64_t ll; + } eind; + } test; - test.eind.d = d; + test.eind.d = d; - int64_t sign80 = (test.eind.ll & (0x8000000000000000)) ? 1 : 0; - int64_t exp80 = test.eind.ll & (0x7ff0000000000000); - int64_t exp80final = (exp80 >> 52); - int64_t mant80 = test.eind.ll & (0x000fffffffffffff); - int64_t mant80final = (mant80 << 11); + int64_t sign80 = (test.eind.ll & (0x8000000000000000)) ? 1 : 0; + int64_t exp80 = test.eind.ll & (0x7ff0000000000000); + int64_t exp80final = (exp80 >> 52); + int64_t mant80 = test.eind.ll & (0x000fffffffffffff); + int64_t mant80final = (mant80 << 11); - if (exp80final == 0x7ff) /*Infinity / Nan*/ - { - exp80final = 0x7fff; - mant80final |= (0x8000000000000000); - } else if (d != 0) { //Zero is a special case - // Elvira wants the 8 and tcalc doesn't - mant80final |= (0x8000000000000000); - //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; + if (exp80final == 0x7ff) /*Infinity / Nan*/ + { + exp80final = 0x7fff; + mant80final |= (0x8000000000000000); + } else if (d != 0) { // Zero is a special case + // Elvira wants the 8 and tcalc doesn't + mant80final |= (0x8000000000000000); + // 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); - writememl(easeg, cpu_state.eaaddr + 4, test.eind.ll >> 32); - writememw(easeg, cpu_state.eaaddr + 8, test.begin); + writememl(easeg, cpu_state.eaaddr, test.eind.ll); + 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; + 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]); + 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; + 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); + 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] & TAG_UINT64)) { - cpu_state.ST[reg] = (double)cpu_state.MM[reg].q; - } else { - cpu_state.tag[reg] &= ~TAG_UINT64; - cpu_state.ST[reg] = x87_ld80(); - } + if ((cpu_state.MM_w4[reg] == 0x5555) && (cpu_state.tag[reg] & TAG_UINT64)) { + cpu_state.ST[reg] = (double)cpu_state.MM[reg].q; + } else { + cpu_state.tag[reg] &= ~TAG_UINT64; + cpu_state.ST[reg] = x87_ld80(); + } } 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); + 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); + 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 __amd64__ - uint32_t out; + uint32_t out; - /* Memory barrier, to force GCC to write to the input parameters + /* Memory barrier, to force GCC to write to the input parameters * before the compare rather than after */ - asm volatile ("" : : : "memory"); + asm volatile("" : : : "memory"); - asm( - "fldl %2\n" - "fldl %1\n" - "fclex\n" - "fcompp\n" - "fnstsw %0\n" - : "=m" (out) - : "m" (a), "m" (b) - ); + asm("fldl %2\n" + "fldl %1\n" + "fclex\n" + "fcompp\n" + "fnstsw %0\n" + : "=m"(out) + : "m"(a), "m"(b)); - return out & (C0 | C2 | C3); + return out & (C0 | C2 | C3); #else - /* Generic C version is known to give incorrect results in some + /* Generic C version is known to give incorrect results in some * situations, eg comparison of infinity (Unreal) */ uint32_t out = 0; @@ -225,25 +219,23 @@ static inline uint16_t x87_compare(double a, double b) { static inline uint16_t x87_ucompare(double a, double b) { #if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined __amd64__ - uint32_t out; + uint32_t out; - /* Memory barrier, to force GCC to write to the input parameters + /* Memory barrier, to force GCC to write to the input parameters * before the compare rather than after */ - asm volatile ("" : : : "memory"); + asm volatile("" : : : "memory"); - asm( - "fldl %2\n" - "fldl %1\n" - "fclex\n" - "fucompp\n" - "fnstsw %0\n" - : "=m" (out) - : "m" (a), "m" (b) - ); + asm("fldl %2\n" + "fldl %1\n" + "fclex\n" + "fucompp\n" + "fnstsw %0\n" + : "=m"(out) + : "m"(a), "m"(b)); - return out & (C0 | C2 | C3); + return out & (C0 | C2 | C3); #else - /* Generic C version is known to give incorrect results in some + /* Generic C version is known to give incorrect results in some * situations, eg comparison of infinity (Unreal) */ uint32_t out = 0; @@ -257,26 +249,25 @@ static inline uint16_t x87_ucompare(double a, double b) { } typedef union { - float s; - uint32_t i; + float s; + uint32_t i; } x87_ts; typedef union { - double d; - uint64_t i; + double d; + uint64_t i; } x87_td; #ifdef X8087 #define FP_ENTER() fpucount++ #else -#define FP_ENTER() do \ - { \ - if (cr0 & 0xc) \ - { \ - x86_int(7); \ - return 1; \ - } \ - fpucount++; \ +#define FP_ENTER() \ + do { \ + if (cr0 & 0xc) { \ + x86_int(7); \ + return 1; \ + } \ + fpucount++; \ } while (0) #endif @@ -285,871 +276,841 @@ typedef union { #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; - } + 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; - } + 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; + 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; + fetch_ea_32(fetchdat); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 0); + return 0; } -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 - }; -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 - }; +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}; +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}; #define ILLEGAL FPU_ILLEGAL_a16 -OpFn OP_TABLE(fpu_d9_a16)[256] = - { - opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, +OpFn OP_TABLE(fpu_d9_a16)[256] = { + opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, /*Invalid*/ - opFCHS, opFABS, ILLEGAL, ILLEGAL, opFTST, opFXAM, ILLEGAL, ILLEGAL, - opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL, - opF2XM1, opFYL2X, opFPTAN, opFPATAN, ILLEGAL, opFPREM1, opFDECSTP, opFINCSTP, - opFPREM, opFYL2XP1, opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS - }; + opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, + opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, + opFNOP, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, /*Invalid*/ + opFCHS, opFABS, ILLEGAL, ILLEGAL, opFTST, opFXAM, ILLEGAL, ILLEGAL, + opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL, + opF2XM1, opFYL2X, opFPTAN, opFPATAN, ILLEGAL, opFPREM1, opFDECSTP, opFINCSTP, + opFPREM, opFYL2XP1, opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS}; #undef ILLEGAL #define ILLEGAL FPU_ILLEGAL_a32 -OpFn OP_TABLE(fpu_d9_a32)[256] = - { - opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, +OpFn OP_TABLE(fpu_d9_a32)[256] = { + opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, /*Invalid*/ - opFCHS, opFABS, ILLEGAL, ILLEGAL, opFTST, opFXAM, ILLEGAL, ILLEGAL, - opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL, - opF2XM1, opFYL2X, opFPTAN, opFPATAN, ILLEGAL, opFPREM1, opFDECSTP, opFINCSTP, - opFPREM, opFYL2XP1, opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS - }; + opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, + opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, + opFNOP, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, /*Invalid*/ + opFCHS, opFABS, ILLEGAL, ILLEGAL, opFTST, opFXAM, ILLEGAL, ILLEGAL, + opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL, + opF2XM1, opFYL2X, opFPTAN, opFPATAN, ILLEGAL, opFPREM1, opFDECSTP, opFINCSTP, + opFPREM, opFYL2XP1, opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS}; #undef ILLEGAL #define ILLEGAL FPU_ILLEGAL_a16 -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, +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, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, opFUCOMPP, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - }; + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, opFUCOMPP, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +}; #undef ILLEGAL #define ILLEGAL FPU_ILLEGAL_a32 -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, +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, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, opFUCOMPP, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - }; + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, opFUCOMPP, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +}; #undef ILLEGAL #define ILLEGAL FPU_ILLEGAL_a16 -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, +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, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, opFUCOMPP, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - }; + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, opFUCOMPP, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +}; #undef ILLEGAL #define ILLEGAL FPU_ILLEGAL_a32 -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, +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, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, opFUCOMPP, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - }; + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, opFUCOMPP, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +}; #undef ILLEGAL #define ILLEGAL FPU_ILLEGAL_a16 -OpFn OP_TABLE(fpu_db_a16)[256] = - { - opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, +OpFn OP_TABLE(fpu_db_a16)[256] = { + opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - opFENI, opFDISI, opFCLEX, opFINIT, opFNOP, opFNOP, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - }; + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFENI, opFDISI, opFCLEX, opFINIT, opFNOP, opFNOP, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +}; #undef ILLEGAL #define ILLEGAL FPU_ILLEGAL_a32 -OpFn OP_TABLE(fpu_db_a32)[256] = - { - opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, +OpFn OP_TABLE(fpu_db_a32)[256] = { + opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - opFENI, opFDISI, opFCLEX, opFINIT, opFNOP, opFNOP, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - }; + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFENI, opFDISI, opFCLEX, opFINIT, opFNOP, opFNOP, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +}; #undef ILLEGAL #define ILLEGAL FPU_ILLEGAL_a16 -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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, +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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, - ILLEGAL, opFNOP, opFCLEX, opFINIT, opFNOP, opFNOP, ILLEGAL, ILLEGAL, - opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, - opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - }; + 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, + ILLEGAL, opFNOP, opFCLEX, opFINIT, opFNOP, opFNOP, ILLEGAL, ILLEGAL, + opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, + opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +}; #undef ILLEGAL #define ILLEGAL FPU_ILLEGAL_a32 -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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, +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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, - ILLEGAL, opFNOP, opFCLEX, opFINIT, opFNOP, opFNOP, ILLEGAL, ILLEGAL, - opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, - opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - }; + 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, + ILLEGAL, opFNOP, opFCLEX, opFINIT, opFNOP, opFNOP, ILLEGAL, ILLEGAL, + opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, + opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +}; #undef ILLEGAL -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 - }; -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 - }; +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}; +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}; #define ILLEGAL FPU_ILLEGAL_a16 -OpFn OP_TABLE(fpu_dd_a16)[256] = - { - opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, +OpFn OP_TABLE(fpu_dd_a16)[256] = { + opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - }; + opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +}; #undef ILLEGAL #define ILLEGAL FPU_ILLEGAL_a32 -OpFn OP_TABLE(fpu_dd_a32)[256] = - { - opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, +OpFn OP_TABLE(fpu_dd_a32)[256] = { + opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - }; + opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +}; #undef ILLEGAL #define ILLEGAL FPU_ILLEGAL_a16 -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, +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, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, opFCOMPP, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, - }; + opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, + opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, opFCOMPP, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, +}; #undef ILLEGAL #define ILLEGAL FPU_ILLEGAL_a32 -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, +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, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, opFCOMPP, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, - }; + opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, + opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, opFCOMPP, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, +}; #undef ILLEGAL #define ILLEGAL FPU_ILLEGAL_a16 -OpFn OP_TABLE(fpu_df_a16)[256] = - { - opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, +OpFn OP_TABLE(fpu_df_a16)[256] = { + opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - opFSTSW_AX, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - }; + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFSTSW_AX, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +}; #undef ILLEGAL #define ILLEGAL FPU_ILLEGAL_a32 -OpFn OP_TABLE(fpu_df_a32)[256] = - { - opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, +OpFn OP_TABLE(fpu_df_a32)[256] = { + opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - opFSTSW_AX, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - }; + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFSTSW_AX, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +}; #undef ILLEGAL #define ILLEGAL FPU_ILLEGAL_a16 -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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, +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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - opFSTSW_AX, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, - opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - }; + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFSTSW_AX, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, + opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +}; #undef ILLEGAL #define ILLEGAL FPU_ILLEGAL_a32 -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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, +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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + 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, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - opFSTSW_AX, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, - opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - }; + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFSTSW_AX, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, + opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +}; #undef ILLEGAL -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, +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, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, - op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, - op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, - op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, - op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, - op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, - op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, - op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, - op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, - }; -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_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, + op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, +}; +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, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, - op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, - op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, - op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, - op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, - op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, - op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, - op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, - op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, - }; + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, + op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, +}; #endif /* _X87_OPS_H_ */ diff --git a/includes/private/cpu/x87_ops_arith.h b/includes/private/cpu/x87_ops_arith.h index 6c0c24df..0214ed23 100644 --- a/includes/private/cpu/x87_ops_arith.h +++ b/includes/private/cpu/x87_ops_arith.h @@ -1,446 +1,452 @@ #ifndef _X87_OPS_ARITH_H_ #define _X87_OPS_ARITH_H_ -#define opFPU(name, optype, a_size, load_var, get, use_var, cycle_postfix) \ -static int opFADD ## name ## _a ## a_size(uint32_t fetchdat) \ -{ \ - optype t; \ - FP_ENTER(); \ - fetch_ea_ ## a_size(fetchdat); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - load_var = get(); if (cpu_state.abrt) return 1; \ - 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&7] = TAG_VALID; \ - CLOCK_CYCLES(x87_timings.fadd ## cycle_postfix); \ - return 0; \ -} \ -static int opFCOM ## name ## _a ## a_size(uint32_t fetchdat) \ -{ \ - optype t; \ - FP_ENTER(); \ - fetch_ea_ ## a_size(fetchdat); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - load_var = get(); if (cpu_state.abrt) return 1; \ - cpu_state.npxs &= ~(C0|C2|C3); \ - cpu_state.npxs |= x87_compare(ST(0), (double)use_var); \ - CLOCK_CYCLES(x87_timings.fcom ## cycle_postfix); \ - return 0; \ -} \ -static int opFCOMP ## name ## _a ## a_size(uint32_t fetchdat) \ -{ \ - optype t; \ - FP_ENTER(); \ - fetch_ea_ ## a_size(fetchdat); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - load_var = get(); if (cpu_state.abrt) return 1; \ - cpu_state.npxs &= ~(C0|C2|C3); \ - cpu_state.npxs |= x87_compare(ST(0), (double)use_var); \ - x87_pop(); \ - CLOCK_CYCLES(x87_timings.fcom ## cycle_postfix); \ - return 0; \ -} \ -static int opFDIV ## name ## _a ## a_size(uint32_t fetchdat) \ -{ \ - optype t; \ - FP_ENTER(); \ - fetch_ea_ ## a_size(fetchdat); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - load_var = get(); if (cpu_state.abrt) return 1; \ - x87_div(ST(0), ST(0), use_var); \ - cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; \ - CLOCK_CYCLES(x87_timings.fdiv ## cycle_postfix); \ - return 0; \ -} \ -static int opFDIVR ## name ## _a ## a_size(uint32_t fetchdat) \ -{ \ - optype t; \ - FP_ENTER(); \ - fetch_ea_ ## a_size(fetchdat); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - load_var = get(); if (cpu_state.abrt) return 1; \ - x87_div(ST(0), use_var, ST(0)); \ - cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; \ - CLOCK_CYCLES(x87_timings.fdiv ## cycle_postfix); \ - return 0; \ -} \ -static int opFMUL ## name ## _a ## a_size(uint32_t fetchdat) \ -{ \ - optype t; \ - FP_ENTER(); \ - fetch_ea_ ## a_size(fetchdat); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - load_var = get(); if (cpu_state.abrt) return 1; \ - ST(0) *= use_var; \ - cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; \ - CLOCK_CYCLES(x87_timings.fmul ## cycle_postfix); \ - return 0; \ -} \ -static int opFSUB ## name ## _a ## a_size(uint32_t fetchdat) \ -{ \ - optype t; \ - FP_ENTER(); \ - fetch_ea_ ## a_size(fetchdat); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - load_var = get(); if (cpu_state.abrt) return 1; \ - ST(0) -= use_var; \ - cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; \ - CLOCK_CYCLES(x87_timings.fadd ## cycle_postfix); \ - return 0; \ -} \ -static int opFSUBR ## name ## _a ## a_size(uint32_t fetchdat) \ -{ \ - optype t; \ - FP_ENTER(); \ - fetch_ea_ ## a_size(fetchdat); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - load_var = get(); if (cpu_state.abrt) return 1; \ - ST(0) = use_var - ST(0); \ - cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; \ - CLOCK_CYCLES(x87_timings.fadd ## cycle_postfix); \ - return 0; \ -} +#define opFPU(name, optype, a_size, load_var, get, use_var, cycle_postfix) \ + static int opFADD##name##_a##a_size(uint32_t fetchdat) { \ + optype t; \ + FP_ENTER(); \ + fetch_ea_##a_size(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + load_var = get(); \ + if (cpu_state.abrt) \ + return 1; \ + 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 & 7] = TAG_VALID; \ + CLOCK_CYCLES(x87_timings.fadd##cycle_postfix); \ + return 0; \ + } \ + static int opFCOM##name##_a##a_size(uint32_t fetchdat) { \ + optype t; \ + FP_ENTER(); \ + fetch_ea_##a_size(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + load_var = get(); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.npxs &= ~(C0 | C2 | C3); \ + cpu_state.npxs |= x87_compare(ST(0), (double)use_var); \ + CLOCK_CYCLES(x87_timings.fcom##cycle_postfix); \ + return 0; \ + } \ + static int opFCOMP##name##_a##a_size(uint32_t fetchdat) { \ + optype t; \ + FP_ENTER(); \ + fetch_ea_##a_size(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + load_var = get(); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.npxs &= ~(C0 | C2 | C3); \ + cpu_state.npxs |= x87_compare(ST(0), (double)use_var); \ + x87_pop(); \ + CLOCK_CYCLES(x87_timings.fcom##cycle_postfix); \ + return 0; \ + } \ + static int opFDIV##name##_a##a_size(uint32_t fetchdat) { \ + optype t; \ + FP_ENTER(); \ + fetch_ea_##a_size(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + load_var = get(); \ + if (cpu_state.abrt) \ + return 1; \ + x87_div(ST(0), ST(0), use_var); \ + cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID; \ + CLOCK_CYCLES(x87_timings.fdiv##cycle_postfix); \ + return 0; \ + } \ + static int opFDIVR##name##_a##a_size(uint32_t fetchdat) { \ + optype t; \ + FP_ENTER(); \ + fetch_ea_##a_size(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + load_var = get(); \ + if (cpu_state.abrt) \ + return 1; \ + x87_div(ST(0), use_var, ST(0)); \ + cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID; \ + CLOCK_CYCLES(x87_timings.fdiv##cycle_postfix); \ + return 0; \ + } \ + static int opFMUL##name##_a##a_size(uint32_t fetchdat) { \ + optype t; \ + FP_ENTER(); \ + fetch_ea_##a_size(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + load_var = get(); \ + if (cpu_state.abrt) \ + return 1; \ + ST(0) *= use_var; \ + cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID; \ + CLOCK_CYCLES(x87_timings.fmul##cycle_postfix); \ + return 0; \ + } \ + static int opFSUB##name##_a##a_size(uint32_t fetchdat) { \ + optype t; \ + FP_ENTER(); \ + fetch_ea_##a_size(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + load_var = get(); \ + if (cpu_state.abrt) \ + return 1; \ + ST(0) -= use_var; \ + cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID; \ + CLOCK_CYCLES(x87_timings.fadd##cycle_postfix); \ + return 0; \ + } \ + static int opFSUBR##name##_a##a_size(uint32_t fetchdat) { \ + optype t; \ + FP_ENTER(); \ + fetch_ea_##a_size(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + load_var = get(); \ + if (cpu_state.abrt) \ + return 1; \ + ST(0) = use_var - ST(0); \ + cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID; \ + CLOCK_CYCLES(x87_timings.fadd##cycle_postfix); \ + return 0; \ + } -opFPU(s, x87_ts, 16, t.i, geteal, t.s, _32) -opFPU(s, x87_ts, 32, t.i, geteal, t.s, _32) -opFPU(d, x87_td, 16, t.i, geteaq, t.d, _64) -opFPU(d, x87_td, 32, t.i, geteaq, t.d, _64) +opFPU(s, x87_ts, 16, t.i, geteal, t.s, _32) opFPU(s, x87_ts, 32, t.i, geteal, t.s, _32) + opFPU(d, x87_td, 16, t.i, geteaq, t.d, _64) opFPU(d, x87_td, 32, t.i, geteaq, t.d, _64) -opFPU(iw, uint16_t, 16, t, geteaw, (double)(int16_t)t, _i16) -opFPU(iw, uint16_t, 32, t, geteaw, (double)(int16_t)t, _i16) -opFPU(il, uint32_t, 16, t, geteal, (double)(int32_t)t, _i32) -opFPU(il, uint32_t, 32, t, geteal, (double)(int32_t)t, _i32) + opFPU(iw, uint16_t, 16, t, geteaw, (double)(int16_t)t, _i16) + opFPU(iw, uint16_t, 32, t, geteaw, (double)(int16_t)t, _i16) + opFPU(il, uint32_t, 16, t, geteal, (double)(int32_t)t, _i32) + opFPU(il, uint32_t, 32, t, geteal, (double)(int32_t)t, _i32) -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 & 7] = TAG_VALID; - CLOCK_CYCLES(x87_timings.fadd); - return 0; + 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 & 7] = TAG_VALID; + CLOCK_CYCLES(x87_timings.fadd); + 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_VALID; - CLOCK_CYCLES(x87_timings.fadd); - return 0; + 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_VALID; + CLOCK_CYCLES(x87_timings.fadd); + 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_VALID; - x87_pop(); - CLOCK_CYCLES(x87_timings.fadd); - return 0; + 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_VALID; + x87_pop(); + CLOCK_CYCLES(x87_timings.fadd); + 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(x87_timings.fadd); - return 0; + 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(x87_timings.fadd); + 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(x87_timings.fadd); - return 0; + 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(x87_timings.fadd); + return 0; } static int opFCOMPP(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - if (fplog) - pclog("FCOMPP\n"); - cpu_state.npxs &= ~(C0 | C2 | C3); - if (*(uint64_t *)&ST(0) == ((uint64_t)1 << 63) && *(uint64_t *)&ST(1) == 0) - cpu_state.npxs |= C0; /*Nasty hack to fix 80387 detection*/ - else - cpu_state.npxs |= x87_compare(ST(0), ST(1)); + FP_ENTER(); + cpu_state.pc++; + if (fplog) + pclog("FCOMPP\n"); + cpu_state.npxs &= ~(C0 | C2 | C3); + if (*(uint64_t *)&ST(0) == ((uint64_t)1 << 63) && *(uint64_t *)&ST(1) == 0) + 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(x87_timings.fadd); - return 0; + x87_pop(); + x87_pop(); + CLOCK_CYCLES(x87_timings.fadd); + 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(x87_timings.fucom); - return 0; + 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(x87_timings.fucom); + return 0; } static int opFCOMI(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - if (fplog) - pclog("FICOM\n"); - flags_rebuild(); - cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG); - if (ST(0) == ST(fetchdat & 7)) - cpu_state.flags |= Z_FLAG; - else if (ST(0) < ST(fetchdat & 7)) - cpu_state.flags |= C_FLAG; - CLOCK_CYCLES(x87_timings.fcom); - return 0; + FP_ENTER(); + cpu_state.pc++; + if (fplog) + pclog("FICOM\n"); + flags_rebuild(); + cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG); + if (ST(0) == ST(fetchdat & 7)) + cpu_state.flags |= Z_FLAG; + else if (ST(0) < ST(fetchdat & 7)) + cpu_state.flags |= C_FLAG; + CLOCK_CYCLES(x87_timings.fcom); + return 0; } static int opFCOMIP(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - if (fplog) - pclog("FICOMP\n"); - flags_rebuild(); - cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG); - if (ST(0) == ST(fetchdat & 7)) - cpu_state.flags |= Z_FLAG; - else if (ST(0) < ST(fetchdat & 7)) - cpu_state.flags |= C_FLAG; - x87_pop(); - CLOCK_CYCLES(x87_timings.fcom); - return 0; + FP_ENTER(); + cpu_state.pc++; + if (fplog) + pclog("FICOMP\n"); + flags_rebuild(); + cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG); + if (ST(0) == ST(fetchdat & 7)) + cpu_state.flags |= Z_FLAG; + else if (ST(0) < ST(fetchdat & 7)) + cpu_state.flags |= C_FLAG; + x87_pop(); + CLOCK_CYCLES(x87_timings.fcom); + 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 & 7] = TAG_VALID; - CLOCK_CYCLES(x87_timings.fdiv); - return 0; + 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 & 7] = TAG_VALID; + CLOCK_CYCLES(x87_timings.fdiv); + 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_VALID; - CLOCK_CYCLES(x87_timings.fdiv); - return 0; + 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_VALID; + CLOCK_CYCLES(x87_timings.fdiv); + 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_VALID; - x87_pop(); - CLOCK_CYCLES(x87_timings.fdiv); - return 0; + 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_VALID; + x87_pop(); + CLOCK_CYCLES(x87_timings.fdiv); + 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 & 7] = TAG_VALID; - CLOCK_CYCLES(x87_timings.fdiv); - return 0; + 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 & 7] = TAG_VALID; + CLOCK_CYCLES(x87_timings.fdiv); + 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_VALID; - CLOCK_CYCLES(x87_timings.fdiv); - return 0; + 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_VALID; + CLOCK_CYCLES(x87_timings.fdiv); + 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_VALID; - x87_pop(); - CLOCK_CYCLES(x87_timings.fdiv); - return 0; + 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_VALID; + x87_pop(); + CLOCK_CYCLES(x87_timings.fdiv); + 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 & 7] = TAG_VALID; - CLOCK_CYCLES(x87_timings.fmul); - return 0; + FP_ENTER(); + cpu_state.pc++; + if (fplog) + pclog("FMUL\n"); + ST(0) = ST(0) * ST(fetchdat & 7); + cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID; + CLOCK_CYCLES(x87_timings.fmul); + 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_VALID; - CLOCK_CYCLES(x87_timings.fmul); - return 0; + 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_VALID; + CLOCK_CYCLES(x87_timings.fmul); + 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_VALID; - x87_pop(); - CLOCK_CYCLES(x87_timings.fmul); - return 0; + 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_VALID; + x87_pop(); + CLOCK_CYCLES(x87_timings.fmul); + 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 & 7] = TAG_VALID; - CLOCK_CYCLES(x87_timings.fadd); - return 0; + FP_ENTER(); + cpu_state.pc++; + if (fplog) + pclog("FSUB\n"); + ST(0) = ST(0) - ST(fetchdat & 7); + cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID; + CLOCK_CYCLES(x87_timings.fadd); + 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_VALID; - CLOCK_CYCLES(x87_timings.fadd); - return 0; + 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_VALID; + CLOCK_CYCLES(x87_timings.fadd); + 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_VALID; - x87_pop(); - CLOCK_CYCLES(x87_timings.fadd); - return 0; + 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_VALID; + x87_pop(); + CLOCK_CYCLES(x87_timings.fadd); + 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 & 7] = TAG_VALID; - CLOCK_CYCLES(x87_timings.fadd); - return 0; + FP_ENTER(); + cpu_state.pc++; + if (fplog) + pclog("FSUBR\n"); + ST(0) = ST(fetchdat & 7) - ST(0); + cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID; + CLOCK_CYCLES(x87_timings.fadd); + 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_VALID; - CLOCK_CYCLES(x87_timings.fadd); - return 0; + 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_VALID; + CLOCK_CYCLES(x87_timings.fadd); + 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_VALID; - x87_pop(); - CLOCK_CYCLES(x87_timings.fadd); - return 0; + 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_VALID; + x87_pop(); + CLOCK_CYCLES(x87_timings.fadd); + 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(x87_timings.fucom); - return 0; + 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(x87_timings.fucom); + 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(x87_timings.fucom); - return 0; + 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(x87_timings.fucom); + return 0; } static int opFUCOMI(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - if (fplog) - pclog("FUCOMI\n"); - flags_rebuild(); - cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG); - if (ST(0) == ST(fetchdat & 7)) - cpu_state.flags |= Z_FLAG; - else if (ST(0) < ST(fetchdat & 7)) - cpu_state.flags |= C_FLAG; - CLOCK_CYCLES(x87_timings.fucom); - return 0; + FP_ENTER(); + cpu_state.pc++; + if (fplog) + pclog("FUCOMI\n"); + flags_rebuild(); + cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG); + if (ST(0) == ST(fetchdat & 7)) + cpu_state.flags |= Z_FLAG; + else if (ST(0) < ST(fetchdat & 7)) + cpu_state.flags |= C_FLAG; + CLOCK_CYCLES(x87_timings.fucom); + return 0; } static int opFUCOMIP(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - if (fplog) - pclog("FUCOMIP\n"); - flags_rebuild(); - cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG); - if (ST(0) == ST(fetchdat & 7)) - cpu_state.flags |= Z_FLAG; - else if (ST(0) < ST(fetchdat & 7)) - cpu_state.flags |= C_FLAG; - x87_pop(); - CLOCK_CYCLES(x87_timings.fucom); - return 0; + FP_ENTER(); + cpu_state.pc++; + if (fplog) + pclog("FUCOMIP\n"); + flags_rebuild(); + cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG); + if (ST(0) == ST(fetchdat & 7)) + cpu_state.flags |= Z_FLAG; + else if (ST(0) < ST(fetchdat & 7)) + cpu_state.flags |= C_FLAG; + x87_pop(); + CLOCK_CYCLES(x87_timings.fucom); + return 0; } #endif /* _X87_OPS_ARITH_H_ */ diff --git a/includes/private/cpu/x87_ops_loadstore.h b/includes/private/cpu/x87_ops_loadstore.h index f206c996..0ab282f5 100644 --- a/includes/private/cpu/x87_ops_loadstore.h +++ b/includes/private/cpu/x87_ops_loadstore.h @@ -1,574 +1,576 @@ #ifndef _X87_OPS_LOADSTORE_H_ #define _X87_OPS_LOADSTORE_H_ static int opFILDiw_a16(uint32_t fetchdat) { - int16_t temp; - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - 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(x87_timings.fild_16); - return 0; + int16_t temp; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + 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(x87_timings.fild_16); + return 0; } static int opFILDiw_a32(uint32_t fetchdat) { - int16_t temp; - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - 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(x87_timings.fild_16); - return 0; + int16_t temp; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + 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(x87_timings.fild_16); + return 0; } static int opFISTiw_a16(uint32_t fetchdat) { - int64_t temp64; - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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(x87_timings.fist_16); - return cpu_state.abrt; + int64_t temp64; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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(x87_timings.fist_16); + return cpu_state.abrt; } static int opFISTiw_a32(uint32_t fetchdat) { - int64_t temp64; - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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(x87_timings.fist_16); - return cpu_state.abrt; + int64_t temp64; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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(x87_timings.fist_16); + return cpu_state.abrt; } static int opFISTPiw_a16(uint32_t fetchdat) { - int64_t temp64; - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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(x87_timings.fist_16); - return 0; + int64_t temp64; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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(x87_timings.fist_16); + return 0; } static int opFISTPiw_a32(uint32_t fetchdat) { - int64_t temp64; - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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(x87_timings.fist_16); - return 0; + int64_t temp64; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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(x87_timings.fist_16); + return 0; } static int opFILDiq_a16(uint32_t fetchdat) { - int64_t temp64; - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - 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 & 7].q = temp64; - cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID | TAG_UINT64; + int64_t temp64; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + 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 & 7].q = temp64; + cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID | TAG_UINT64; - CLOCK_CYCLES(x87_timings.fild_64); - return 0; + CLOCK_CYCLES(x87_timings.fild_64); + return 0; } static int opFILDiq_a32(uint32_t fetchdat) { - int64_t temp64; - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - 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 & 7].q = temp64; - cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID | TAG_UINT64; + int64_t temp64; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + 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 & 7].q = temp64; + cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID | TAG_UINT64; - CLOCK_CYCLES(x87_timings.fild_64); - return 0; + CLOCK_CYCLES(x87_timings.fild_64); + return 0; } static int FBSTP_a16(uint32_t fetchdat) { - double tempd; - int c; - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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(); - CLOCK_CYCLES(x87_timings.fbstp); - return 0; + double tempd; + int c; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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(); + CLOCK_CYCLES(x87_timings.fbstp); + return 0; } static int FBSTP_a32(uint32_t fetchdat) { - double tempd; - int c; - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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(); - CLOCK_CYCLES(x87_timings.fbstp); - return 0; + double tempd; + int c; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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(); + CLOCK_CYCLES(x87_timings.fbstp); + return 0; } static int FISTPiq_a16(uint32_t fetchdat) { - int64_t temp64; - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - if (fplog) - pclog("FISTPl %08X:%08X\n", easeg, cpu_state.eaaddr); - if (cpu_state.tag[cpu_state.TOP & 7] & TAG_UINT64) - temp64 = cpu_state.MM[cpu_state.TOP & 7].q; - else - temp64 = x87_fround(ST(0)); - seteaq(temp64); - if (cpu_state.abrt) - return 1; - x87_pop(); - CLOCK_CYCLES(x87_timings.fist_64); - return 0; + int64_t temp64; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + if (fplog) + pclog("FISTPl %08X:%08X\n", easeg, cpu_state.eaaddr); + if (cpu_state.tag[cpu_state.TOP & 7] & TAG_UINT64) + temp64 = cpu_state.MM[cpu_state.TOP & 7].q; + else + temp64 = x87_fround(ST(0)); + seteaq(temp64); + if (cpu_state.abrt) + return 1; + x87_pop(); + CLOCK_CYCLES(x87_timings.fist_64); + return 0; } static int FISTPiq_a32(uint32_t fetchdat) { - int64_t temp64; - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - if (fplog) - pclog("FISTPl %08X:%08X\n", easeg, cpu_state.eaaddr); - if (cpu_state.tag[cpu_state.TOP & 7] & TAG_UINT64) - temp64 = cpu_state.MM[cpu_state.TOP & 7].q; - else - temp64 = x87_fround(ST(0)); - seteaq(temp64); - if (cpu_state.abrt) - return 1; - x87_pop(); - CLOCK_CYCLES(x87_timings.fist_64); - return 0; + int64_t temp64; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + if (fplog) + pclog("FISTPl %08X:%08X\n", easeg, cpu_state.eaaddr); + if (cpu_state.tag[cpu_state.TOP & 7] & TAG_UINT64) + temp64 = cpu_state.MM[cpu_state.TOP & 7].q; + else + temp64 = x87_fround(ST(0)); + seteaq(temp64); + if (cpu_state.abrt) + return 1; + x87_pop(); + CLOCK_CYCLES(x87_timings.fist_64); + return 0; } static int opFILDil_a16(uint32_t fetchdat) { - int32_t templ; - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - 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(x87_timings.fild_32); - return 0; + int32_t templ; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + 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(x87_timings.fild_32); + return 0; } static int opFILDil_a32(uint32_t fetchdat) { - int32_t templ; - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - 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(x87_timings.fild_32); - return 0; + int32_t templ; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + 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(x87_timings.fild_32); + return 0; } static int opFISTil_a16(uint32_t fetchdat) { - int64_t temp64; - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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(x87_timings.fist_32); - return cpu_state.abrt; + int64_t temp64; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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(x87_timings.fist_32); + return cpu_state.abrt; } static int opFISTil_a32(uint32_t fetchdat) { - int64_t temp64; - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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(x87_timings.fist_32); - return cpu_state.abrt; + int64_t temp64; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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(x87_timings.fist_32); + return cpu_state.abrt; } static int opFISTPil_a16(uint32_t fetchdat) { - int64_t temp64; - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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(x87_timings.fist_32); - return 0; + int64_t temp64; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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(x87_timings.fist_32); + return 0; } static int opFISTPil_a32(uint32_t fetchdat) { - int64_t temp64; - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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(x87_timings.fist_32); - return 0; + int64_t temp64; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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(x87_timings.fist_32); + return 0; } static int opFLDe_a16(uint32_t fetchdat) { - double t; - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - 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(x87_timings.fld_80); - return 0; + double t; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + 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(x87_timings.fld_80); + return 0; } static int opFLDe_a32(uint32_t fetchdat) { - double t; - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - 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(x87_timings.fld_80); - return 0; + double t; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + 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(x87_timings.fld_80); + return 0; } static int opFSTPe_a16(uint32_t fetchdat) { - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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(x87_timings.fst_80); - return 0; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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(x87_timings.fst_80); + return 0; } static int opFSTPe_a32(uint32_t fetchdat) { - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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(x87_timings.fst_80); - return 0; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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(x87_timings.fst_80); + return 0; } static int opFLDd_a16(uint32_t fetchdat) { - x87_td t; - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - 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(x87_timings.fld_64); - return 0; + x87_td t; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + 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(x87_timings.fld_64); + return 0; } static int opFLDd_a32(uint32_t fetchdat) { - x87_td t; - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - 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(x87_timings.fld_64); - return 0; + x87_td t; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + 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(x87_timings.fld_64); + return 0; } static int opFSTd_a16(uint32_t fetchdat) { - x87_td t; - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - if (fplog) - pclog("FSTd %08X:%08X\n", easeg, cpu_state.eaaddr); - t.d = ST(0); - seteaq(t.i); - CLOCK_CYCLES(x87_timings.fst_64); - return cpu_state.abrt; + x87_td t; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + if (fplog) + pclog("FSTd %08X:%08X\n", easeg, cpu_state.eaaddr); + t.d = ST(0); + seteaq(t.i); + CLOCK_CYCLES(x87_timings.fst_64); + return cpu_state.abrt; } static int opFSTd_a32(uint32_t fetchdat) { - x87_td t; - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - if (fplog) - pclog("FSTd %08X:%08X\n", easeg, cpu_state.eaaddr); - t.d = ST(0); - seteaq(t.i); - CLOCK_CYCLES(x87_timings.fst_64); - return cpu_state.abrt; + x87_td t; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + if (fplog) + pclog("FSTd %08X:%08X\n", easeg, cpu_state.eaaddr); + t.d = ST(0); + seteaq(t.i); + CLOCK_CYCLES(x87_timings.fst_64); + return cpu_state.abrt; } static int opFSTPd_a16(uint32_t fetchdat) { - x87_td t; - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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(x87_timings.fst_64); - return 0; + x87_td t; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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(x87_timings.fst_64); + return 0; } static int opFSTPd_a32(uint32_t fetchdat) { - x87_td t; - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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(x87_timings.fst_64); - return 0; + x87_td t; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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(x87_timings.fst_64); + return 0; } static int opFLDs_a16(uint32_t fetchdat) { - x87_ts ts; - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - 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(x87_timings.fld_32); - return 0; + x87_ts ts; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + 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(x87_timings.fld_32); + return 0; } static int opFLDs_a32(uint32_t fetchdat) { - x87_ts ts; - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - 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(x87_timings.fld_32); - return 0; + x87_ts ts; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + 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(x87_timings.fld_32); + return 0; } static int opFSTs_a16(uint32_t fetchdat) { - x87_ts ts; - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - if (fplog) - pclog("FSTs %08X:%08X\n", easeg, cpu_state.eaaddr); - ts.s = (float)ST(0); - seteal(ts.i); - CLOCK_CYCLES(x87_timings.fst_32); - return cpu_state.abrt; + x87_ts ts; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + if (fplog) + pclog("FSTs %08X:%08X\n", easeg, cpu_state.eaaddr); + ts.s = (float)ST(0); + seteal(ts.i); + CLOCK_CYCLES(x87_timings.fst_32); + return cpu_state.abrt; } static int opFSTs_a32(uint32_t fetchdat) { - x87_ts ts; - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - if (fplog) - pclog("FSTs %08X:%08X\n", easeg, cpu_state.eaaddr); - ts.s = (float)ST(0); - seteal(ts.i); - CLOCK_CYCLES(x87_timings.fst_32); - return cpu_state.abrt; + x87_ts ts; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + if (fplog) + pclog("FSTs %08X:%08X\n", easeg, cpu_state.eaaddr); + ts.s = (float)ST(0); + seteal(ts.i); + CLOCK_CYCLES(x87_timings.fst_32); + return cpu_state.abrt; } static int opFSTPs_a16(uint32_t fetchdat) { - x87_ts ts; - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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(x87_timings.fst_32); - return 0; + x87_ts ts; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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(x87_timings.fst_32); + return 0; } static int opFSTPs_a32(uint32_t fetchdat) { - x87_ts ts; - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - 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(x87_timings.fst_32); - return 0; + x87_ts ts; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + 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(x87_timings.fst_32); + return 0; } #endif /* _X87_OPS_LOADSTORE_H_ */ diff --git a/includes/private/cpu/x87_ops_misc.h b/includes/private/cpu/x87_ops_misc.h index 20eda80e..0d13b608 100644 --- a/includes/private/cpu/x87_ops_misc.h +++ b/includes/private/cpu/x87_ops_misc.h @@ -1,934 +1,927 @@ #ifndef _X87_OPS_MISC_H_ #define _X87_OPS_MISC_H_ static int opFDISI(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - if (fpu_type == FPU_8087) { - cpu_state.npxc |= FPCW_DISI; - CLOCK_CYCLES(x87_timings.fdisi_eni); - } else - CLOCK_CYCLES(x87_timings.fnop); - return 0; + FP_ENTER(); + cpu_state.pc++; + if (fpu_type == FPU_8087) { + cpu_state.npxc |= FPCW_DISI; + CLOCK_CYCLES(x87_timings.fdisi_eni); + } else + CLOCK_CYCLES(x87_timings.fnop); + return 0; } static int opFENI(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - if (fpu_type == FPU_8087) { - cpu_state.npxc &= ~FPCW_DISI; - CLOCK_CYCLES(x87_timings.fdisi_eni); - } else - CLOCK_CYCLES(x87_timings.fnop); - return 0; + FP_ENTER(); + cpu_state.pc++; + if (fpu_type == FPU_8087) { + cpu_state.npxc &= ~FPCW_DISI; + CLOCK_CYCLES(x87_timings.fdisi_eni); + } else + CLOCK_CYCLES(x87_timings.fnop); + return 0; } static int opFSTSW_AX(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - if (fplog) - pclog("FSTSW\n"); - AX = cpu_state.npxs; - CLOCK_CYCLES(x87_timings.fstcw_sw); - return 0; + FP_ENTER(); + cpu_state.pc++; + if (fplog) + pclog("FSTSW\n"); + AX = cpu_state.npxs; + CLOCK_CYCLES(x87_timings.fstcw_sw); + return 0; } static int opFNOP(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - CLOCK_CYCLES(x87_timings.fnop); - return 0; + FP_ENTER(); + cpu_state.pc++; + CLOCK_CYCLES(x87_timings.fnop); + return 0; } static int opFCLEX(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - cpu_state.npxs &= 0xff00; - CLOCK_CYCLES(x87_timings.fclex); - return 0; + FP_ENTER(); + cpu_state.pc++; + cpu_state.npxs &= 0xff00; + CLOCK_CYCLES(x87_timings.fclex); + return 0; } static int opFINIT(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - if (fpu_type == FPU_8087) - cpu_state.npxc = 0x3ff; - else - cpu_state.npxc = 0x37f; - codegen_set_rounding_mode(X87_ROUNDING_NEAREST); - cpu_state.npxs = 0; - *(uint64_t *)cpu_state.tag = 0; - cpu_state.TOP = 0; - cpu_state.ismmx = 0; - CLOCK_CYCLES(x87_timings.finit); - CPU_BLOCK_END(); - return 0; + FP_ENTER(); + cpu_state.pc++; + if (fpu_type == FPU_8087) + cpu_state.npxc = 0x3ff; + else + cpu_state.npxc = 0x37f; + codegen_set_rounding_mode(X87_ROUNDING_NEAREST); + cpu_state.npxs = 0; + *(uint64_t *)cpu_state.tag = 0; + cpu_state.TOP = 0; + cpu_state.ismmx = 0; + CLOCK_CYCLES(x87_timings.finit); + CPU_BLOCK_END(); + 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] = TAG_EMPTY; - CLOCK_CYCLES(x87_timings.ffree); - return 0; + FP_ENTER(); + cpu_state.pc++; + if (fplog) + pclog("FFREE\n"); + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_EMPTY; + CLOCK_CYCLES(x87_timings.ffree); + 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(x87_timings.fst); - return 0; + 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(x87_timings.fst); + 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(x87_timings.fst); - return 0; + 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(x87_timings.fst); + return 0; } static int FSTOR() { - 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); - codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); - 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); - codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); - 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); + 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); + codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); + 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); + codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); + 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*/ - 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 && (*(uint64_t *)cpu_state.tag == 0x0101010101010101ull)) - cpu_state.ismmx = 1; + 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*/ + 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 && + (*(uint64_t *)cpu_state.tag == 0x0101010101010101ull)) + cpu_state.ismmx = 1; - CLOCK_CYCLES(x87_timings.frstor); - 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; + CLOCK_CYCLES(x87_timings.frstor); + 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); - SEG_CHECK_READ(cpu_state.ea_seg); - FSTOR(); - return cpu_state.abrt; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + FSTOR(); + return cpu_state.abrt; } static int opFSTOR_a32(uint32_t fetchdat) { - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - FSTOR(); - return cpu_state.abrt; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + FSTOR(); + return cpu_state.abrt; } static int FSAVE() { - 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 & 7) << 11); + 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 & 7) << 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; - } + 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; - codegen_set_rounding_mode(X87_ROUNDING_NEAREST); - cpu_state.npxs = 0; - *(uint64_t *)cpu_state.tag = 0; - cpu_state.TOP = 0; - cpu_state.ismmx = 0; + cpu_state.npxc = 0x37F; + codegen_set_rounding_mode(X87_ROUNDING_NEAREST); + cpu_state.npxs = 0; + *(uint64_t *)cpu_state.tag = 0; + cpu_state.TOP = 0; + cpu_state.ismmx = 0; - CLOCK_CYCLES(x87_timings.fsave); - return cpu_state.abrt; + CLOCK_CYCLES(x87_timings.fsave); + return cpu_state.abrt; } static int opFSAVE_a16(uint32_t fetchdat) { - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - FSAVE(); - return cpu_state.abrt; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + FSAVE(); + return cpu_state.abrt; } static int opFSAVE_a32(uint32_t fetchdat) { - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - FSAVE(); - return cpu_state.abrt; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + FSAVE(); + return cpu_state.abrt; } static int opFSTSW_a16(uint32_t fetchdat) { - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - if (fplog) - pclog("FSTSW %08X:%08X\n", easeg, cpu_state.eaaddr); - seteaw((cpu_state.npxs & 0xC7FF) | ((cpu_state.TOP & 7) << 11)); - CLOCK_CYCLES(x87_timings.fstcw_sw); - return cpu_state.abrt; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + if (fplog) + pclog("FSTSW %08X:%08X\n", easeg, cpu_state.eaaddr); + seteaw((cpu_state.npxs & 0xC7FF) | ((cpu_state.TOP & 7) << 11)); + CLOCK_CYCLES(x87_timings.fstcw_sw); + return cpu_state.abrt; } static int opFSTSW_a32(uint32_t fetchdat) { - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - if (fplog) - pclog("FSTSW %08X:%08X\n", easeg, cpu_state.eaaddr); - seteaw((cpu_state.npxs & 0xC7FF) | ((cpu_state.TOP & 7) << 11)); - CLOCK_CYCLES(x87_timings.fstcw_sw); - return cpu_state.abrt; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + if (fplog) + pclog("FSTSW %08X:%08X\n", easeg, cpu_state.eaaddr); + seteaw((cpu_state.npxs & 0xC7FF) | ((cpu_state.TOP & 7) << 11)); + CLOCK_CYCLES(x87_timings.fstcw_sw); + return cpu_state.abrt; } static int opFLD(uint32_t fetchdat) { - int old_tag; - uint64_t old_i64; + 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 & 7] = old_tag; - cpu_state.MM[cpu_state.TOP & 7].q = old_i64; - CLOCK_CYCLES(x87_timings.fld); - return 0; + 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 & 7] = old_tag; + cpu_state.MM[cpu_state.TOP & 7].q = old_i64; + CLOCK_CYCLES(x87_timings.fld); + 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 & 7]; - cpu_state.tag[cpu_state.TOP & 7] = 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 & 7].q; - cpu_state.MM[cpu_state.TOP & 7].q = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; - cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q = old_i64; + 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 & 7]; + cpu_state.tag[cpu_state.TOP & 7] = 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 & 7].q; + cpu_state.MM[cpu_state.TOP & 7].q = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; + cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q = old_i64; - CLOCK_CYCLES(x87_timings.fxch); - return 0; + CLOCK_CYCLES(x87_timings.fxch); + 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 & 7] = TAG_VALID; - CLOCK_CYCLES(x87_timings.fchs); - return 0; + FP_ENTER(); + cpu_state.pc++; + if (fplog) + pclog("FCHS\n"); + ST(0) = -ST(0); + cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID; + CLOCK_CYCLES(x87_timings.fchs); + 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 & 7] = TAG_VALID; - CLOCK_CYCLES(x87_timings.fabs); - return 0; + FP_ENTER(); + cpu_state.pc++; + if (fplog) + pclog("FABS %f\n", ST(0)); + ST(0) = fabs(ST(0)); + cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID; + CLOCK_CYCLES(x87_timings.fabs); + 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(x87_timings.ftst); - return 0; + 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(x87_timings.ftst); + 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] == TAG_EMPTY) - cpu_state.npxs |= (C0 | C3); - else if (ST(0) == 0.0) - cpu_state.npxs |= C3; - else - cpu_state.npxs |= C2; - if (ST(0) < 0.0) - cpu_state.npxs |= C1; - CLOCK_CYCLES(x87_timings.fxam); - return 0; + 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] == TAG_EMPTY) + cpu_state.npxs |= (C0 | C3); + else if (ST(0) == 0.0) + cpu_state.npxs |= C3; + else + cpu_state.npxs |= C2; + if (ST(0) < 0.0) + cpu_state.npxs |= C1; + CLOCK_CYCLES(x87_timings.fxam); + return 0; } static int opFLD1(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - if (fplog) - pclog("FLD1\n"); - x87_push(1.0); - CLOCK_CYCLES(x87_timings.fld_z1); - return 0; + FP_ENTER(); + cpu_state.pc++; + if (fplog) + pclog("FLD1\n"); + x87_push(1.0); + CLOCK_CYCLES(x87_timings.fld_z1); + return 0; } static int opFLDL2T(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - if (fplog) - pclog("FLDL2T\n"); - x87_push(3.3219280948873623); - CLOCK_CYCLES(x87_timings.fld_const); - return 0; + FP_ENTER(); + cpu_state.pc++; + if (fplog) + pclog("FLDL2T\n"); + x87_push(3.3219280948873623); + CLOCK_CYCLES(x87_timings.fld_const); + return 0; } static int opFLDL2E(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - if (fplog) - pclog("FLDL2E\n"); - x87_push(1.4426950408889634); - CLOCK_CYCLES(x87_timings.fld_const); - return 0; + FP_ENTER(); + cpu_state.pc++; + if (fplog) + pclog("FLDL2E\n"); + x87_push(1.4426950408889634); + CLOCK_CYCLES(x87_timings.fld_const); + return 0; } static int opFLDPI(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - if (fplog) - pclog("FLDPI\n"); - x87_push(3.141592653589793); - CLOCK_CYCLES(x87_timings.fld_const); - return 0; + FP_ENTER(); + cpu_state.pc++; + if (fplog) + pclog("FLDPI\n"); + x87_push(3.141592653589793); + CLOCK_CYCLES(x87_timings.fld_const); + return 0; } static int opFLDEG2(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - if (fplog) - pclog("FLDEG2\n"); - x87_push(0.3010299956639812); - CLOCK_CYCLES(x87_timings.fld_const); - return 0; + FP_ENTER(); + cpu_state.pc++; + if (fplog) + pclog("FLDEG2\n"); + x87_push(0.3010299956639812); + CLOCK_CYCLES(x87_timings.fld_const); + return 0; } static int opFLDLN2(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - if (fplog) - pclog("FLDLN2\n"); - x87_push_u64(0x3fe62e42fefa39f0ull); - CLOCK_CYCLES(x87_timings.fld_const); - return 0; + FP_ENTER(); + cpu_state.pc++; + if (fplog) + pclog("FLDLN2\n"); + x87_push_u64(0x3fe62e42fefa39f0ull); + CLOCK_CYCLES(x87_timings.fld_const); + 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] = TAG_VALID; - CLOCK_CYCLES(x87_timings.fld_z1); - return 0; + FP_ENTER(); + cpu_state.pc++; + if (fplog) + pclog("FLDZ\n"); + x87_push(0.0); + cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID; + CLOCK_CYCLES(x87_timings.fld_z1); + 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 & 7] = TAG_VALID; - CLOCK_CYCLES(x87_timings.f2xm1); - return 0; + 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 & 7] = TAG_VALID; + CLOCK_CYCLES(x87_timings.f2xm1); + 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_VALID; - x87_pop(); - CLOCK_CYCLES(x87_timings.fyl2x); - return 0; + 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_VALID; + x87_pop(); + CLOCK_CYCLES(x87_timings.fyl2x); + return 0; } static int opFYL2XP1(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - if (fplog) - pclog("FYL2XP1\n"); - ST(1) = ST(1) * (log(ST(0) + 1.0) / log(2.0)); - cpu_state.tag[(cpu_state.TOP + 1) & 7] = TAG_VALID; - x87_pop(); - CLOCK_CYCLES(x87_timings.fyl2xp1); - return 0; + FP_ENTER(); + cpu_state.pc++; + if (fplog) + pclog("FYL2XP1\n"); + ST(1) = ST(1) * (log(ST(0) + 1.0) / log(2.0)); + cpu_state.tag[(cpu_state.TOP + 1) & 7] = TAG_VALID; + x87_pop(); + CLOCK_CYCLES(x87_timings.fyl2xp1); + 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 & 7] = TAG_VALID; - x87_push(1.0); - cpu_state.npxs &= ~C2; - CLOCK_CYCLES(x87_timings.fptan); - return 0; + FP_ENTER(); + cpu_state.pc++; + if (fplog) + pclog("FPTAN\n"); + ST(0) = tan(ST(0)); + cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID; + x87_push(1.0); + cpu_state.npxs &= ~C2; + CLOCK_CYCLES(x87_timings.fptan); + 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_VALID; - x87_pop(); - CLOCK_CYCLES(x87_timings.fpatan); - return 0; + 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_VALID; + x87_pop(); + CLOCK_CYCLES(x87_timings.fpatan); + return 0; } static int opFDECSTP(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - if (fplog) - pclog("FDECSTP\n"); - cpu_state.TOP--; - CLOCK_CYCLES(x87_timings.fincdecstp); - return 0; + FP_ENTER(); + cpu_state.pc++; + if (fplog) + pclog("FDECSTP\n"); + cpu_state.TOP--; + CLOCK_CYCLES(x87_timings.fincdecstp); + return 0; } static int opFINCSTP(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - if (fplog) - pclog("FDECSTP\n"); - cpu_state.TOP++; - CLOCK_CYCLES(x87_timings.fincdecstp); - return 0; + FP_ENTER(); + cpu_state.pc++; + if (fplog) + pclog("FDECSTP\n"); + cpu_state.TOP++; + CLOCK_CYCLES(x87_timings.fincdecstp); + 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 & 7] = TAG_VALID; - 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(x87_timings.fprem); - return 0; + 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 & 7] = TAG_VALID; + 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(x87_timings.fprem); + 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 & 7] = TAG_VALID; - 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(x87_timings.fprem1); - return 0; + 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 & 7] = TAG_VALID; + 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(x87_timings.fprem1); + 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 & 7] = TAG_VALID; - CLOCK_CYCLES(x87_timings.fsqrt); - return 0; + FP_ENTER(); + cpu_state.pc++; + if (fplog) + pclog("FSQRT\n"); + ST(0) = sqrt(ST(0)); + cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID; + CLOCK_CYCLES(x87_timings.fsqrt); + 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 & 7] = TAG_VALID; - x87_push(cos(td)); - cpu_state.npxs &= ~C2; - CLOCK_CYCLES(x87_timings.fsincos); - return 0; + 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 & 7] = TAG_VALID; + x87_push(cos(td)); + cpu_state.npxs &= ~C2; + CLOCK_CYCLES(x87_timings.fsincos); + 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 & 7] = TAG_VALID; - if (fplog) - pclog("%g\n", ST(0)); - CLOCK_CYCLES(x87_timings.frndint); - return 0; + 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 & 7] = TAG_VALID; + if (fplog) + pclog("%g\n", ST(0)); + CLOCK_CYCLES(x87_timings.frndint); + 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); - if (ST(0) != 0.0) - ST(0) = ST(0) * pow(2.0, (double)temp64); - cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID; - CLOCK_CYCLES(x87_timings.fscale); - return 0; + int64_t temp64; + FP_ENTER(); + cpu_state.pc++; + if (fplog) + pclog("FSCALE\n"); + temp64 = (int64_t)ST(1); + if (ST(0) != 0.0) + ST(0) = ST(0) * pow(2.0, (double)temp64); + cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID; + CLOCK_CYCLES(x87_timings.fscale); + 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 & 7] = TAG_VALID; - cpu_state.npxs &= ~C2; - CLOCK_CYCLES(x87_timings.fsin_cos); - return 0; + FP_ENTER(); + cpu_state.pc++; + if (fplog) + pclog("FSIN\n"); + ST(0) = sin(ST(0)); + cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID; + cpu_state.npxs &= ~C2; + CLOCK_CYCLES(x87_timings.fsin_cos); + 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 & 7] = TAG_VALID; - cpu_state.npxs &= ~C2; - CLOCK_CYCLES(x87_timings.fsin_cos); - return 0; + FP_ENTER(); + cpu_state.pc++; + if (fplog) + pclog("FCOS\n"); + ST(0) = cos(ST(0)); + cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID; + cpu_state.npxs &= ~C2; + CLOCK_CYCLES(x87_timings.fsin_cos); + 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); - codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); - 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); - codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); - 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(x87_timings.fldenv); - return cpu_state.abrt; + 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); + codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); + 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); + codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); + 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(x87_timings.fldenv); + return cpu_state.abrt; } static int opFLDENV_a16(uint32_t fetchdat) { - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - FLDENV(); - return cpu_state.abrt; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + FLDENV(); + return cpu_state.abrt; } static int opFLDENV_a32(uint32_t fetchdat) { - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - FLDENV(); - return cpu_state.abrt; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + FLDENV(); + return cpu_state.abrt; } static int opFLDCW_a16(uint32_t fetchdat) { - uint16_t tempw; - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - if (fplog) - pclog("FLDCW %08X:%08X\n", easeg, cpu_state.eaaddr); - tempw = geteaw(); - if (cpu_state.abrt) - return 1; - cpu_state.npxc = tempw; - codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); - CLOCK_CYCLES(x87_timings.fldcw); - return 0; + uint16_t tempw; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + if (fplog) + pclog("FLDCW %08X:%08X\n", easeg, cpu_state.eaaddr); + tempw = geteaw(); + if (cpu_state.abrt) + return 1; + cpu_state.npxc = tempw; + codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); + CLOCK_CYCLES(x87_timings.fldcw); + return 0; } static int opFLDCW_a32(uint32_t fetchdat) { - uint16_t tempw; - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - if (fplog) - pclog("FLDCW %08X:%08X\n", easeg, cpu_state.eaaddr); - tempw = geteaw(); - if (cpu_state.abrt) - return 1; - cpu_state.npxc = tempw; - codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); - CLOCK_CYCLES(x87_timings.fldcw); - return 0; + uint16_t tempw; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + if (fplog) + pclog("FLDCW %08X:%08X\n", easeg, cpu_state.eaaddr); + tempw = geteaw(); + if (cpu_state.abrt) + return 1; + cpu_state.npxc = tempw; + codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); + CLOCK_CYCLES(x87_timings.fldcw); + return 0; } static int FSTENV() { - FP_ENTER(); - if (fplog) - pclog("FSTENV %08X:%08X\n", easeg, cpu_state.eaaddr); - cpu_state.npxs = (cpu_state.npxs & ~(7 << 11)) | ((cpu_state.TOP & 7) << 11); + FP_ENTER(); + if (fplog) + pclog("FSTENV %08X:%08X\n", easeg, cpu_state.eaaddr); + cpu_state.npxs = (cpu_state.npxs & ~(7 << 11)) | ((cpu_state.TOP & 7) << 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); - 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(x87_timings.fstenv); - return cpu_state.abrt; + 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(x87_timings.fstenv); + return cpu_state.abrt; } static int opFSTENV_a16(uint32_t fetchdat) { - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - FSTENV(); - return cpu_state.abrt; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + FSTENV(); + return cpu_state.abrt; } static int opFSTENV_a32(uint32_t fetchdat) { - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - FSTENV(); - return cpu_state.abrt; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + FSTENV(); + return cpu_state.abrt; } static int opFSTCW_a16(uint32_t fetchdat) { - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - if (fplog) - pclog("FSTCW %08X:%08X\n", easeg, cpu_state.eaaddr); - seteaw(cpu_state.npxc); - CLOCK_CYCLES(x87_timings.fstcw_sw); - return cpu_state.abrt; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + if (fplog) + pclog("FSTCW %08X:%08X\n", easeg, cpu_state.eaaddr); + seteaw(cpu_state.npxc); + CLOCK_CYCLES(x87_timings.fstcw_sw); + return cpu_state.abrt; } static int opFSTCW_a32(uint32_t fetchdat) { - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - if (fplog) - pclog("FSTCW %08X:%08X\n", easeg, cpu_state.eaaddr); - seteaw(cpu_state.npxc); - CLOCK_CYCLES(x87_timings.fstcw_sw); - return cpu_state.abrt; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + if (fplog) + pclog("FSTCW %08X:%08X\n", easeg, cpu_state.eaaddr); + seteaw(cpu_state.npxc); + CLOCK_CYCLES(x87_timings.fstcw_sw); + 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&7] = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7]; \ - cpu_state.MM[cpu_state.TOP&7].q = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; \ - ST(0) = ST(fetchdat & 7); \ - } \ - CLOCK_CYCLES(4); \ - return 0; \ +#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 & 7] = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7]; \ + cpu_state.MM[cpu_state.TOP & 7].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()) +#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) +opFCMOV(B) opFCMOV(E) opFCMOV(BE) opFCMOV(U) opFCMOV(NB) opFCMOV(NE) opFCMOV(NBE) opFCMOV(NU) #endif /* _X87_OPS_MISC_H_ */ diff --git a/includes/private/cpu/x87_timings.h b/includes/private/cpu/x87_timings.h index 0930af09..e35a0083 100644 --- a/includes/private/cpu/x87_timings.h +++ b/includes/private/cpu/x87_timings.h @@ -1,52 +1,52 @@ #ifndef _X87_TIMINGS_H_ #define _X87_TIMINGS_H_ typedef struct { - int f2xm1; - int fabs; - int fadd, fadd_32, fadd_64; - int fbld; - int fbstp; - int fchs; - int fclex; - int fcom, fcom_32, fcom_64; - int fcos; - int fincdecstp; - int fdisi_eni; - int fdiv, fdiv_32, fdiv_64; - int ffree; - int fadd_i16, fadd_i32; - int fcom_i16, fcom_i32; - int fdiv_i16, fdiv_i32; - int fild_16, fild_32, fild_64; - int fmul_i16, fmul_i32; - int finit; - int fist_16, fist_32, fist_64; - int fld, fld_32, fld_64, fld_80; - int fld_z1, fld_const; - int fldcw; - int fldenv; - int fmul, fmul_32, fmul_64; - int fnop; - int fpatan; - int fprem, fprem1; - int fptan; - int frndint; - int frstor; - int fsave; - int fscale; - int fsetpm; - int fsin_cos, fsincos; - int fsqrt; - int fst, fst_32, fst_64, fst_80; - int fstcw_sw; - int fstenv; - int ftst; - int fucom; - int fwait; - int fxam; - int fxch; - int fxtract; - int fyl2x, fyl2xp1; + int f2xm1; + int fabs; + int fadd, fadd_32, fadd_64; + int fbld; + int fbstp; + int fchs; + int fclex; + int fcom, fcom_32, fcom_64; + int fcos; + int fincdecstp; + int fdisi_eni; + int fdiv, fdiv_32, fdiv_64; + int ffree; + int fadd_i16, fadd_i32; + int fcom_i16, fcom_i32; + int fdiv_i16, fdiv_i32; + int fild_16, fild_32, fild_64; + int fmul_i16, fmul_i32; + int finit; + int fist_16, fist_32, fist_64; + int fld, fld_32, fld_64, fld_80; + int fld_z1, fld_const; + int fldcw; + int fldenv; + int fmul, fmul_32, fmul_64; + int fnop; + int fpatan; + int fprem, fprem1; + int fptan; + int frndint; + int frstor; + int fsave; + int fscale; + int fsetpm; + int fsin_cos, fsincos; + int fsqrt; + int fst, fst_32, fst_64, fst_80; + int fstcw_sw; + int fstenv; + int ftst; + int fucom; + int fwait; + int fxam; + int fxch; + int fxtract; + int fyl2x, fyl2xp1; } x87_timings_t; extern const x87_timings_t x87_timings_8087; diff --git a/includes/private/devices/cassette.h b/includes/private/devices/cassette.h index 3979dc6e..4c5737ef 100644 --- a/includes/private/devices/cassette.h +++ b/includes/private/devices/cassette.h @@ -32,5 +32,4 @@ void cassette_load(const char *filename); extern char cassettefn[256]; - #endif /* _CASSETTE_H_ */ diff --git a/includes/private/devices/esdi_at.h b/includes/private/devices/esdi_at.h index 0b551662..4fa84002 100644 --- a/includes/private/devices/esdi_at.h +++ b/includes/private/devices/esdi_at.h @@ -2,5 +2,4 @@ #define _ESDI_AT_H_ extern device_t wd1007vse1_device; - #endif /* _ESDI_AT_H_ */ diff --git a/includes/private/devices/f82c710_upc.h b/includes/private/devices/f82c710_upc.h index 37b10a7e..dfbba052 100644 --- a/includes/private/devices/f82c710_upc.h +++ b/includes/private/devices/f82c710_upc.h @@ -6,6 +6,4 @@ void upc_set_mouse(void (*mouse_write)(uint8_t val, void *p), void *p); extern device_t f82c710_upc_device; - - #endif /* _F82C710_UPC_H_ */ diff --git a/includes/private/devices/nvr.h b/includes/private/devices/nvr.h index 23c37873..7e591ccd 100644 --- a/includes/private/devices/nvr.h +++ b/includes/private/devices/nvr.h @@ -17,5 +17,4 @@ extern uint8_t nvrram[128]; extern int nvrmask; extern int oldromset; - #endif /* _NVR_H_ */ diff --git a/includes/private/devices/nvr_tc8521.h b/includes/private/devices/nvr_tc8521.h index 254e9348..4cf33168 100644 --- a/includes/private/devices/nvr_tc8521.h +++ b/includes/private/devices/nvr_tc8521.h @@ -13,5 +13,4 @@ void tc8521_nvr_recalc(); FILE *nvrfopen(char *fn, char *mode); - #endif /* _NVR_TC8521_H_ */ diff --git a/includes/private/devices/ps2_nvr.h b/includes/private/devices/ps2_nvr.h index 84c4b316..c08574bc 100644 --- a/includes/private/devices/ps2_nvr.h +++ b/includes/private/devices/ps2_nvr.h @@ -2,5 +2,4 @@ #define _PS2_NVR_H_ extern device_t ps2_nvr_device; - #endif /* _PS2_NVR_H_ */ diff --git a/includes/private/devices/sis496.h b/includes/private/devices/sis496.h index 0ef6651a..86098c7d 100644 --- a/includes/private/devices/sis496.h +++ b/includes/private/devices/sis496.h @@ -2,5 +2,4 @@ #define _SIS496_H_ extern device_t sis496_device; - #endif /* _SIS496_H_ */ diff --git a/includes/private/disc/disc.h b/includes/private/disc/disc.h index 72d3486c..455d21ee 100644 --- a/includes/private/disc/disc.h +++ b/includes/private/disc/disc.h @@ -1,14 +1,14 @@ #ifndef _DISC_H_ #define _DISC_H_ 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 (*readaddress)(int drive, int track, int side, int density); - void (*format)(int drive, int track, int side, int density, uint8_t fill); - int (*hole)(int drive); - void (*stop)(); - void (*poll)(); + 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 (*readaddress)(int drive, int track, int side, int density); + void (*format)(int drive, int track, int side, int density, uint8_t fill); + int (*hole)(int drive); + void (*stop)(); + void (*poll)(); } DRIVE; extern DRIVE drives[2]; @@ -52,7 +52,7 @@ extern int motorspin; extern int motoron; extern int defaultwriteprot; -//extern char discfns[4][260]; +// extern char discfns[4][260]; extern int writeprot[2], fwriteprot[2]; extern int disc_track[2]; @@ -62,6 +62,6 @@ extern int drive_type[2]; /*Used in the Read A Track command. Only valid for disc_readsector(). */ #define SECTOR_FIRST -2 -#define SECTOR_NEXT -1 +#define SECTOR_NEXT -1 #endif /* _DISC_H_ */ diff --git a/includes/private/dosbox/cdrom.h b/includes/private/dosbox/cdrom.h index 603deb7e..2a6d5e17 100644 --- a/includes/private/dosbox/cdrom.h +++ b/includes/private/dosbox/cdrom.h @@ -36,137 +36,137 @@ #include typedef signed int Bits; typedef unsigned int Bitu; -typedef int8_t Bit8s; -typedef uint8_t Bit8u; -typedef int16_t Bit16s; +typedef int8_t Bit8s; +typedef uint8_t Bit8u; +typedef int16_t Bit16s; typedef uint16_t Bit16u; -typedef int32_t Bit32s; +typedef int32_t Bit32s; typedef uint32_t Bit32u; typedef size_t PhysPt; -#define RAW_SECTOR_SIZE 2352 -#define COOKED_SECTOR_SIZE 2048 +#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)) - +#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; + unsigned char min; + unsigned char sec; + unsigned char fr; } TMSF; typedef struct SCtrl { - Bit8u out[4]; // output channel - Bit8u vol[4]; // channel volume + Bit8u out[4]; // output channel + Bit8u vol[4]; // channel volume } TCtrl; -extern int CDROM_GetMountType(char* path, int force); +extern int CDROM_GetMountType(char *path, int force); -class CDROM_Interface -{ -public: -// CDROM_Interface (void); - virtual ~CDROM_Interface (void) {}; +class CDROM_Interface { + public: + // CDROM_Interface (void); + virtual ~CDROM_Interface(void){}; - virtual bool SetDevice (char* path, int forceCD) = 0; + virtual bool SetDevice(char *path, int forceCD) = 0; - virtual bool GetUPC (unsigned char& attr, char* upc) = 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 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 ReadSectors(PhysPt buffer, bool raw, unsigned long sector, unsigned long num) = 0; - virtual bool LoadUnloadMedia (bool unload) = 0; + virtual bool LoadUnloadMedia(bool unload) = 0; - virtual void InitNewMedia (void) {}; + virtual void InitNewMedia(void){}; }; -class CDROM_Interface_Image : public CDROM_Interface -{ -private: - class TrackFile { - public: - virtual bool read(Bit8u *buffer, int seek, int count) = 0; - virtual int getLength() = 0; - virtual ~TrackFile() { }; - }; - - class BinaryFile : public TrackFile { - public: - BinaryFile(const char *filename, bool &error); - ~BinaryFile(); - bool read(Bit8u *buffer, int seek, int count); - int getLength(); - private: - BinaryFile(); - std::ifstream *file; - }; - - struct Track { - int number; - int track_number; - int attr; - int start; - int length; - int skip; - int sectorSize; - bool mode2; - TrackFile *file; - }; +class CDROM_Interface_Image : public CDROM_Interface { + private: + class TrackFile { + public: + virtual bool read(Bit8u *buffer, int seek, int count) = 0; + virtual int getLength() = 0; + virtual ~TrackFile(){}; + }; -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 HasDataTrack (void); - bool HasAudioTracks (void); - - int GetTrack (int sector); + class BinaryFile : public TrackFile { + public: + BinaryFile(const char *filename, bool &error); + ~BinaryFile(); + bool read(Bit8u *buffer, int seek, int count); + int getLength(); -private: - // player -static void CDAudioCallBack(Bitu len); + private: + BinaryFile(); + std::ifstream *file; + }; - void ClearTracks(); - bool LoadIsoFile(char *filename); - bool CanReadPVD(TrackFile *file, int 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(int &frames, std::istream &in); - bool GetCueString(std::string &str, std::istream &in); - bool AddTrack(Track &curr, int &shift, int prestart, int &totalPregap, int currPregap); + struct Track { + int number; + int track_number; + int attr; + int start; + int length; + int skip; + int sectorSize; + bool mode2; + TrackFile *file; + }; - std::vector tracks; -typedef std::vector::iterator track_it; - std::string mcn; + 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 HasDataTrack(void); + bool HasAudioTracks(void); + + int GetTrack(int sector); + + private: + // player + static void CDAudioCallBack(Bitu len); + + void ClearTracks(); + bool LoadIsoFile(char *filename); + bool CanReadPVD(TrackFile *file, int 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(int &frames, std::istream &in); + bool GetCueString(std::string &str, std::istream &in); + bool AddTrack(Track &curr, int &shift, int prestart, int &totalPregap, int currPregap); + + std::vector tracks; + typedef std::vector::iterator track_it; + std::string mcn; }; #endif /* __CDROM_INTERFACE__ */ diff --git a/includes/private/dosbox/dbopl.h b/includes/private/dosbox/dbopl.h index 99537374..3671fc19 100644 --- a/includes/private/dosbox/dbopl.h +++ b/includes/private/dosbox/dbopl.h @@ -24,25 +24,25 @@ #include typedef signed int Bits; typedef unsigned int Bitu; -typedef int8_t Bit8s; -typedef uint8_t Bit8u; -typedef int16_t Bit16s; +typedef int8_t Bit8s; +typedef uint8_t Bit8u; +typedef int16_t Bit16s; typedef uint16_t Bit16u; -typedef int32_t Bit32s; +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 +// 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 +// Select the type of wave generator routine #define DBOPL_WAVE WAVE_TABLEMUL namespace DBOPL { @@ -52,228 +52,224 @@ struct Operator; struct Channel; #if (DBOPL_WAVE == WAVE_HANDLER) -typedef Bits ( DB_FASTCALL *WaveHandler) ( Bitu i, Bitu volume ); +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 ); +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 +// Different synth modes that can generate blocks of data typedef enum { - sm2AM, - sm2FM, - sm3AM, - sm3FM, - sm4Start, - sm3FMFM, - sm3AMFM, - sm3FMAM, - sm3AMAM, - sm6Start, - sm2Percussion, - sm3Percussion, + sm2AM, + sm2FM, + sm3AM, + sm3FM, + sm4Start, + sm3FMFM, + sm3AMFM, + sm3FMAM, + sm3AMAM, + sm6Start, + sm2Percussion, + sm3Percussion, } SynthMode; -//Shifts for the values contained in chandata variable +// Shifts for the values contained in chandata variable enum { - SHIFT_KSLBASE = 16, - SHIFT_KEYCODE = 24, + 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, - }; + 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; + typedef enum { + OFF, + RELEASE, + SUSTAIN, + DECAY, + ATTACK, + } State; - VolumeHandler volHandler; + VolumeHandler volHandler; #if (DBOPL_WAVE == WAVE_HANDLER) - WaveHandler waveHandler; //Routine that generate a wave + WaveHandler waveHandler; // Routine that generate a wave #else - Bit16s* waveBase; - Bit32u waveMask; - Bit32u waveStart; + 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 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 + 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 - 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( ); + Bit32u attackAdd; // Timers for the different states of the envelope + Bit32u decayAdd; + Bit32u releaseAdd; + Bit32u rateIndex; // Current position of the evenlope - 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 ); + 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; - bool Silent() const; - void Prepare( const Chip* chip ); + private: + void SetState(Bit8u s); + void UpdateAttack(const Chip *chip); + void UpdateRelease(const Chip *chip); + void UpdateDecay(const Chip *chip); - void KeyOn( Bit8u mask); - void KeyOff( Bit8u mask); + public: + void UpdateAttenuation(); + void UpdateRates(const Chip *chip); + void UpdateFrequency(); - template< State state> - Bits TemplateVolume( ); + 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); - Bit32s RateForward( Bit32u add ); - Bitu ForwardWave(); - Bitu ForwardVolume(); + bool Silent() const; + void Prepare(const Chip *chip); - Bits GetSample( Bits modulation ); - Bits GetWave( Bitu index, Bitu vol ); -public: - Operator(); + void KeyOn(Bit8u mask); + void KeyOff(Bit8u mask); + + template 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 + 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; + 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 ); + // 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 ); + // call this for the first channel + template void GeneratePercussion(Chip *chip, Bit32s *output); - //Generate blocks of data in specific modes - template - Channel* BlockTemplate( Chip* chip, Bit32u samples, Bit32s* output ); - Channel(); + // 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; - + // This is used as the base counter for vibrato and tremolo + Bit32u lfoCounter; + Bit32u lfoAdd; - Bit32u noiseCounter; - Bit32u noiseAdd; - Bit32u noiseValue; + 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]; + // 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]; + // 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; + 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; - //Return the maximum amount of samples before and LFO change - Bit32u ForwardLFO( Bit32u samples ); - Bit32u ForwardNoise(); + int is_opl3; - void WriteBD( Bit8u val ); - void WriteReg(Bit32u reg, Bit8u val ); + // Return the maximum amount of samples before and LFO change + Bit32u ForwardLFO(Bit32u samples); + Bit32u ForwardNoise(); - Bit32u WriteAddr( Bit32u port, Bit8u val ); + void WriteBD(Bit8u val); + void WriteReg(Bit32u reg, Bit8u val); - void GenerateBlock2( Bitu samples, Bit32s* output ); - void GenerateBlock3( Bitu samples, Bit32s* output ); + Bit32u WriteAddr(Bit32u port, Bit8u val); - void Generate( Bit32u samples ); - void Setup( Bit32u r, int chip_is_opl3 ); + void GenerateBlock2(Bitu samples, Bit32s *output); + void GenerateBlock3(Bitu samples, Bit32s *output); - Chip(); + 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 ); + 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 +void InitTables(void); +}; // namespace DBOPL #endif /* _DBOPL_H_ */ diff --git a/includes/private/dosbox/nukedopl.h b/includes/private/dosbox/nukedopl.h index ccebfc22..63fc0e32 100644 --- a/includes/private/dosbox/nukedopl.h +++ b/includes/private/dosbox/nukedopl.h @@ -16,11 +16,11 @@ #include typedef signed int Bits; typedef unsigned int Bitu; -typedef int8_t Bit8s; -typedef uint8_t Bit8u; -typedef int16_t Bit16s; +typedef int8_t Bit8s; +typedef uint8_t Bit8u; +typedef int16_t Bit16s; typedef uint16_t Bit16u; -typedef int32_t Bit32s; +typedef int32_t Bit32s; typedef uint32_t Bit32u; struct opl3_chip; @@ -28,74 +28,74 @@ struct opl3_slot; struct opl3_channel; 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_phase; - Bit32u timer; + 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_phase; + Bit32u timer; }; 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; + 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; }; struct opl3_chip { - opl3_channel channel[18]; - opl3_slot slot[36]; - Bit16u timer; - Bit8u newm; - Bit8u nts; - Bit8u rhy; - Bit8u vibpos; - Bit8u vibshift; - Bit8u tremolo; - Bit8u tremolopos; - Bit8u tremoloshift; - Bit32u noise; - Bit16s zeromod; - Bit32s mixbuff[2]; + opl3_channel channel[18]; + opl3_slot slot[36]; + Bit16u timer; + Bit8u newm; + Bit8u nts; + Bit8u rhy; + Bit8u vibpos; + Bit8u vibshift; + Bit8u tremolo; + Bit8u tremolopos; + Bit8u tremoloshift; + Bit32u noise; + Bit16s zeromod; + Bit32s mixbuff[2]; - Bit32s rateratio; - Bit32s samplecnt; - Bit16s oldsamples[2]; - Bit16s samples[2]; + Bit32s rateratio; + Bit32s samplecnt; + Bit16s oldsamples[2]; + Bit16s samples[2]; }; -//void OPL3_Generate(opl3_chip *chip, Bit16s *buf); -//void OPL3_GenerateResampled(opl3_chip *chip, Bit16s *buf); +// 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); diff --git a/includes/private/dosbox/vid_cga_comp.h b/includes/private/dosbox/vid_cga_comp.h index f56a9513..587d2c2c 100644 --- a/includes/private/dosbox/vid_cga_comp.h +++ b/includes/private/dosbox/vid_cga_comp.h @@ -7,7 +7,6 @@ void update_cga16_color(uint8_t cgamode); void cga_comp_init(int revision); -Bit8u * Composite_Process(uint8_t cgamode, Bit8u border, Bit32u blocks/*, bool doublewidth*/, Bit8u *TempLine); - +Bit8u *Composite_Process(uint8_t cgamode, Bit8u border, Bit32u blocks /*, bool doublewidth*/, Bit8u *TempLine); #endif /* _VID_CGA_COMP_H_ */ diff --git a/includes/private/fdi2raw.h b/includes/private/fdi2raw.h index ea6fb82c..dfc111a4 100644 --- a/includes/private/fdi2raw.h +++ b/includes/private/fdi2raw.h @@ -13,19 +13,20 @@ typedef struct fdi FDI; 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_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 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 void fdi2raw_header_free(FDI *); extern int fdi2raw_get_last_track(FDI *); -extern int fdi2raw_get_num_sector (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_type(FDI *); +extern int fdi2raw_get_bit_rate(FDI *); +extern int fdi2raw_get_rotation(FDI *); +extern int fdi2raw_get_write_protect(FDI *); #ifdef __cplusplus } diff --git a/includes/private/filters.h b/includes/private/filters.h index 3884e589..0f511f4e 100644 --- a/includes/private/filters.h +++ b/includes/private/filters.h @@ -2,381 +2,296 @@ #define _FILTERS_H_ #define NCoef 2 -//fc=350Hz +// fc=350Hz static inline float low_iir(int i, float NewSample) { - float ACoef[NCoef+1] = { - 0.00049713569693400649, - 0.00099427139386801299, - 0.00049713569693400649 - }; + float ACoef[NCoef + 1] = {0.00049713569693400649, 0.00099427139386801299, 0.00049713569693400649}; - float BCoef[NCoef+1] = { - 1.00000000000000000000, - -1.93522955470669530000, - 0.93726236021404663000 - }; + 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; + 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]; - } + // 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]; + // 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]; + return y[i][0]; } -//fc=350Hz +// fc=350Hz static inline float low_cut_iir(int i, float NewSample) { - float ACoef[NCoef+1] = { - 0.96839970114733542000, - -1.93679940229467080000, - 0.96839970114733542000 - }; + float ACoef[NCoef + 1] = {0.96839970114733542000, -1.93679940229467080000, 0.96839970114733542000}; - float BCoef[NCoef+1] = { - 1.00000000000000000000, - -1.93522955471202770000, - 0.93726236021916731000 - }; + 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; + 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]; - } + // 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]; + // 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]; + return y[i][0]; } -//fc=3.5kHz +// fc=3.5kHz static inline float high_iir(int i, float NewSample) { - float ACoef[NCoef+1] = { - 0.72248704753064896000, - -1.44497409506129790000, - 0.72248704753064896000 - }; + 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; + 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]; - } + // 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]; + // 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]; + return y[i][0]; } -//fc=3.5kHz +// fc=3.5kHz static inline float high_cut_iir(int i, float NewSample) { - float ACoef[NCoef+1] = { - 0.03927726802250377400, - 0.07855453604500754700, - 0.03927726802250377400 - }; + 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; + 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]; - } + // 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]; + // 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]; + return y[i][0]; } - #undef NCoef #define NCoef 2 -//fc=3.2kHz +// fc=3.2kHz static inline float sb_iir(int i, float NewSample) { - float ACoef[NCoef+1] = { - 0.03356837051492005100, - 0.06713674102984010200, - 0.03356837051492005100 - }; + 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, -1.41898265221812010000, 0.55326988968868285000}; - 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; + /* float ACoef[NCoef+1] = { + 0.17529642630084405000, + 0.17529642630084405000 + }; - //shift the old samples - for(n=NCoef; n>0; n--) { - x[i][n] = x[i][n-1]; - y[i][n] = y[i][n-1]; - } + 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; - //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]; + // shift the old samples + for (n = NCoef; n > 0; n--) { + x[i][n] = x[i][n - 1]; + y[i][n] = y[i][n - 1]; + } - return y[i][0]; + // 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 +// fc=150Hz static inline float adgold_highpass_iir(int i, float NewSample) { - float ACoef[NCoef+1] = { - 0.98657437157334349000, - -1.97314874314668700000, - 0.98657437157334349000 - }; + float ACoef[NCoef + 1] = {0.98657437157334349000, -1.97314874314668700000, 0.98657437157334349000}; - float BCoef[NCoef+1] = { - 1.00000000000000000000, - -1.97223372919758360000, - 0.97261396931534050000 - }; + 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; + 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]; - } + // 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]; + // 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 +// fc=150Hz static inline float adgold_lowpass_iir(int i, float NewSample) { - float ACoef[NCoef+1] = { - 0.00009159473951071446, - 0.00018318947902142891, - 0.00009159473951071446 - }; + float ACoef[NCoef + 1] = {0.00009159473951071446, 0.00018318947902142891, 0.00009159473951071446}; - float BCoef[NCoef+1] = { - 1.00000000000000000000, - -1.97223372919526560000, - 0.97261396931306277000 - }; + 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; + 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]; - } + // 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]; + // 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 +// fc=56Hz static inline float adgold_pseudo_stereo_iir(float NewSample) { - float ACoef[NCoef+1] = { - 0.00001409030866231767, - 0.00002818061732463533, - 0.00001409030866231767 - }; + float ACoef[NCoef + 1] = {0.00001409030866231767, 0.00002818061732463533, 0.00001409030866231767}; - float BCoef[NCoef+1] = { - 1.00000000000000000000, - -1.98733021473466760000, - 0.98738361004063568000 - }; + 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; + 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]; - } + // 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]; + // 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 +// fc=3.2kHz - probably incorrect static inline float dss_iir(float NewSample) { - float ACoef[NCoef+1] = { - 0.03356837051492005100, - 0.06713674102984010200, - 0.03356837051492005100 - }; + 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; + float BCoef[NCoef + 1] = {1.00000000000000000000, -1.41898265221812010000, 0.55326988968868285000}; - //shift the old samples - for(n=NCoef; n>0; n--) { - x[n] = x[n-1]; - y[n] = y[n-1]; - } + static float y[NCoef + 1]; // output samples + static float x[NCoef + 1]; // input samples + int n; - //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]; + // shift the old samples + for (n = NCoef; n > 0; n--) { + x[n] = x[n - 1]; + y[n] = y[n - 1]; + } - return y[0]; + // 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 ACoef[NCoef + 1] = {0.99901119820285345000, -0.99901119820285345000}; - float BCoef[NCoef+1] = { - 1.00000000000000000000, - -0.99869185905052738000 - }; + 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; + 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]; - } + // 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]; + // 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 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 + // 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 = 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)]; + out += low_fir_sb16_coef[n] * x[i][(n + pos) - (SB16_NCoef + 1)]; - if (i == 1) - { + if (i == 1) { pos++; if (pos > SB16_NCoef) pos = 0; } - + return out; } - #endif /* _FILTERS_H_ */ diff --git a/includes/private/flash/rom.h b/includes/private/flash/rom.h index 1a41f056..6d05aa28 100644 --- a/includes/private/flash/rom.h +++ b/includes/private/flash/rom.h @@ -5,13 +5,14 @@ FILE *romfopen(char *fn, char *mode); int rom_present(char *fn); typedef struct rom_t { - uint8_t *rom; - uint32_t mask; - mem_mapping_t mapping; + uint8_t *rom; + uint32_t mask; + mem_mapping_t mapping; } rom_t; int rom_init(rom_t *rom, char *fn, uint32_t address, int size, int mask, int file_offset, uint32_t flags); -int rom_init_interleaved(rom_t *rom, char *fn_low, char *fn_high, uint32_t address, int size, int mask, int file_offset, uint32_t flags); +int rom_init_interleaved(rom_t *rom, char *fn_low, char *fn_high, uint32_t address, int size, int mask, int file_offset, + uint32_t flags); uint8_t rom_read(uint32_t addr, void *p); uint16_t rom_readw(uint32_t addr, void *p); diff --git a/includes/private/floppy/fdc.h b/includes/private/floppy/fdc.h index c73a4686..420c9852 100644 --- a/includes/private/floppy/fdc.h +++ b/includes/private/floppy/fdc.h @@ -27,15 +27,6 @@ void fdc_update_densel_polarity(int densel_polarity); void fdc_update_densel_force(int densel_force); void fdc_update_drvrate(int drive, int drvrate); - - -enum -{ - FDC_STATUS_AM_NOT_FOUND, - FDC_STATUS_NOT_FOUND, - FDC_STATUS_WRONG_CYLINDER, - FDC_STATUS_BAD_CYLINDER -}; - +enum { FDC_STATUS_AM_NOT_FOUND, FDC_STATUS_NOT_FOUND, FDC_STATUS_WRONG_CYLINDER, FDC_STATUS_BAD_CYLINDER }; #endif /* _FDC_H_ */ diff --git a/includes/private/floppy/fdc37c665.h b/includes/private/floppy/fdc37c665.h index 8a76f726..4d601eda 100644 --- a/includes/private/floppy/fdc37c665.h +++ b/includes/private/floppy/fdc37c665.h @@ -2,5 +2,4 @@ #define _FDC37C665_H_ extern void fdc37c665_init(); - #endif /* _FDC37C665_H_ */ diff --git a/includes/private/floppy/fdc37c93x.h b/includes/private/floppy/fdc37c93x.h index 35b24509..90ce82cf 100644 --- a/includes/private/floppy/fdc37c93x.h +++ b/includes/private/floppy/fdc37c93x.h @@ -2,5 +2,4 @@ #define _FDC37C93X_H_ extern void fdc37c932fr_init(); - #endif /* _FDC37C93X_H_ */ diff --git a/includes/private/floppy/fdd.h b/includes/private/floppy/fdd.h index c146e30b..76e437f6 100644 --- a/includes/private/floppy/fdd.h +++ b/includes/private/floppy/fdd.h @@ -16,5 +16,4 @@ int fdd_get_type(int drive); extern int fdd_swap; - #endif /* _FDD_H_ */ diff --git a/includes/private/hdd/hdd_file.h b/includes/private/hdd/hdd_file.h index 163422bb..3ae96ff8 100644 --- a/includes/private/hdd/hdd_file.h +++ b/includes/private/hdd/hdd_file.h @@ -1,18 +1,18 @@ #ifndef _HDD_FILE_H_ #define _HDD_FILE_H_ typedef enum hdd_img_type { - HDD_IMG_RAW, - HDD_IMG_VHD, + HDD_IMG_RAW, + HDD_IMG_VHD, } hdd_img_type; typedef struct hdd_file_t { - void *f; - int spt; - int hpc; - int tracks; - int sectors; - int read_only; - hdd_img_type img_type; + void *f; + int spt; + int hpc; + int tracks; + int sectors; + int read_only; + hdd_img_type img_type; } hdd_file_t; void hdd_load(hdd_file_t *hdd, int d, const char *fn); diff --git a/includes/private/hdd/minivhd/cwalk.h b/includes/private/hdd/minivhd/cwalk.h index b0ac61fb..2b2ab281 100644 --- a/includes/private/hdd/minivhd/cwalk.h +++ b/includes/private/hdd/minivhd/cwalk.h @@ -12,11 +12,11 @@ * and "log". */ struct cwk_segment { - const char *path; - const char *segments; - const char *begin; - const char *end; - size_t size; + const char *path; + const char *segments; + const char *begin; + const char *end; + size_t size; }; /** @@ -27,20 +27,13 @@ struct cwk_segment { * CWK_CURRENT - "./" current folder segment * CWK_BACK - "../" relative back navigation segment */ -enum cwk_segment_type { - CWK_NORMAL, - CWK_CURRENT, - CWK_BACK -}; +enum cwk_segment_type { CWK_NORMAL, CWK_CURRENT, CWK_BACK }; /** * @brief Determines the style which is used for the path parsing and * generation. */ -enum cwk_path_style { - CWK_STYLE_WINDOWS, - CWK_STYLE_UNIX -}; +enum cwk_path_style { CWK_STYLE_WINDOWS, CWK_STYLE_UNIX }; /** * @brief Generates an absolute path based on a base. @@ -60,8 +53,7 @@ enum cwk_path_style { * @param buffer_size The size of the result buffer. * @return Returns the total amount of characters of the new absolute path. */ -size_t cwk_path_get_absolute(const char *base, const char *path, char *buffer, - size_t buffer_size); +size_t cwk_path_get_absolute(const char *base, const char *path, char *buffer, size_t buffer_size); /** * @brief Generates a relative path based on a base. @@ -80,8 +72,7 @@ size_t cwk_path_get_absolute(const char *base, const char *path, char *buffer, * @param buffer_size The size of the result buffer. * @return Returns the total amount of characters of the full path. */ -size_t cwk_path_get_relative(const char *base_directory, const char *path, - char *buffer, size_t buffer_size); +size_t cwk_path_get_relative(const char *base_directory, const char *path, char *buffer, size_t buffer_size); /** * @brief Joins two paths together. @@ -100,8 +91,7 @@ size_t cwk_path_get_relative(const char *base_directory, const char *path, * @param buffer_size The size of the result buffer. * @return Returns the total amount of characters of the full, combined path. */ -size_t cwk_path_join(const char *path_a, const char *path_b, char *buffer, - size_t buffer_size); +size_t cwk_path_join(const char *path_a, const char *path_b, char *buffer, size_t buffer_size); /** * @brief Joins multiple paths together. @@ -120,8 +110,7 @@ size_t cwk_path_join(const char *path_a, const char *path_b, char *buffer, * @param buffer_size The size of the result buffer. * @return Returns the total amount of characters of the full, combined path. */ -size_t cwk_path_join_multiple(const char **paths, char *buffer, - size_t buffer_size); +size_t cwk_path_join_multiple(const char **paths, char *buffer, size_t buffer_size); /** * @brief Determines the root of a path. @@ -152,8 +141,7 @@ void cwk_path_get_root(const char *path, size_t *length); * to. * @return Returns the total amount of characters of the new path. */ -size_t cwk_path_change_root(const char *path, const char *new_root, - char *buffer, size_t buffer_size); +size_t cwk_path_change_root(const char *path, const char *new_root, char *buffer, size_t buffer_size); /** * @brief Determine whether the path is absolute or not. @@ -190,8 +178,7 @@ bool cwk_path_is_relative(const char *path); * @param basename The output of the basename pointer. * @param length The output of the length of the basename. */ -void cwk_path_get_basename(const char *path, const char **basename, - size_t *length); +void cwk_path_get_basename(const char *path, const char **basename, size_t *length); /** * @brief Changes the basename of a file path. @@ -211,8 +198,7 @@ void cwk_path_get_basename(const char *path, const char **basename, * @return Returns the size which the complete new path would have if it was not * truncated. */ -size_t cwk_path_change_basename(const char *path, const char *new_basename, - char *buffer, size_t buffer_size); +size_t cwk_path_change_basename(const char *path, const char *new_basename, char *buffer, size_t buffer_size); /** * @brief Gets the dirname of a file path. @@ -242,8 +228,7 @@ void cwk_path_get_dirname(const char *path, size_t *length); * @param length The output of the length of the extension. * @return Returns true if an extension is found or false otherwise. */ -bool cwk_path_get_extension(const char *path, const char **extension, - size_t *length); +bool cwk_path_get_extension(const char *path, const char **extension, size_t *length); /** * @brief Determines whether the file path has an extension. @@ -276,8 +261,7 @@ bool cwk_path_has_extension(const char *path); * @return Returns the total size which the output would have if it was not * truncated. */ -size_t cwk_path_change_extension(const char *path, const char *new_extension, - char *buffer, size_t buffer_size); +size_t cwk_path_change_extension(const char *path, const char *new_extension, char *buffer, size_t buffer_size); /** * @brief Creates a normalized version of the path. @@ -380,8 +364,7 @@ bool cwk_path_get_previous_segment(struct cwk_segment *segment); * @param segment The segment which will be inspected. * @return Returns the type of the segment. */ -enum cwk_segment_type cwk_path_get_segment_type( - const struct cwk_segment *segment); +enum cwk_segment_type cwk_path_get_segment_type(const struct cwk_segment *segment); /** * @brief Changes the content of a segment. @@ -400,8 +383,7 @@ enum cwk_segment_type cwk_path_get_segment_type( * @return Returns the total size which would have been written if the output * was not truncated. */ -size_t cwk_path_change_segment(struct cwk_segment *segment, const char *value, - char *buffer, size_t buffer_size); +size_t cwk_path_change_segment(struct cwk_segment *segment, const char *value, char *buffer, size_t buffer_size); /** * @brief Checks whether the submitted pointer points to a separator. diff --git a/includes/private/hdd/minivhd/minivhd.h b/includes/private/hdd/minivhd/minivhd.h index 3d17bc99..6c08fca3 100644 --- a/includes/private/hdd/minivhd/minivhd.h +++ b/includes/private/hdd/minivhd/minivhd.h @@ -8,72 +8,73 @@ extern int mvhd_errno; typedef enum MVHDError { - MVHD_ERR_MEM = -128, - MVHD_ERR_FILE, - MVHD_ERR_NOT_VHD, - MVHD_ERR_TYPE, - MVHD_ERR_FOOTER_CHECKSUM, - MVHD_ERR_SPARSE_CHECKSUM, - MVHD_ERR_UTF_TRANSCODING_FAILED, - MVHD_ERR_UTF_SIZE, - MVHD_ERR_PATH_REL, - MVHD_ERR_PATH_LEN, - MVHD_ERR_PAR_NOT_FOUND, - MVHD_ERR_INVALID_PAR_UUID, - MVHD_ERR_INVALID_GEOM, - MVHD_ERR_INVALID_SIZE, - MVHD_ERR_INVALID_BLOCK_SIZE, - MVHD_ERR_INVALID_PARAMS, - MVHD_ERR_CONV_SIZE, - MVHD_ERR_TIMESTAMP + MVHD_ERR_MEM = -128, + MVHD_ERR_FILE, + MVHD_ERR_NOT_VHD, + MVHD_ERR_TYPE, + MVHD_ERR_FOOTER_CHECKSUM, + MVHD_ERR_SPARSE_CHECKSUM, + MVHD_ERR_UTF_TRANSCODING_FAILED, + MVHD_ERR_UTF_SIZE, + MVHD_ERR_PATH_REL, + MVHD_ERR_PATH_LEN, + MVHD_ERR_PAR_NOT_FOUND, + MVHD_ERR_INVALID_PAR_UUID, + MVHD_ERR_INVALID_GEOM, + MVHD_ERR_INVALID_SIZE, + MVHD_ERR_INVALID_BLOCK_SIZE, + MVHD_ERR_INVALID_PARAMS, + MVHD_ERR_CONV_SIZE, + MVHD_ERR_TIMESTAMP } MVHDError; -typedef enum MVHDType { - MVHD_TYPE_FIXED = 2, - MVHD_TYPE_DYNAMIC = 3, - MVHD_TYPE_DIFF = 4 -} MVHDType; +typedef enum MVHDType { MVHD_TYPE_FIXED = 2, MVHD_TYPE_DYNAMIC = 3, MVHD_TYPE_DIFF = 4 } MVHDType; typedef enum MVHDBlockSize { - MVHD_BLOCK_DEFAULT = 0, /**< 2 MB blocks */ - MVHD_BLOCK_SMALL = 1024, /**< 512 KB blocks */ - MVHD_BLOCK_LARGE = 4096 /**< 2 MB blocks */ + MVHD_BLOCK_DEFAULT = 0, /**< 2 MB blocks */ + MVHD_BLOCK_SMALL = 1024, /**< 512 KB blocks */ + MVHD_BLOCK_LARGE = 4096 /**< 2 MB blocks */ } MVHDBlockSize; typedef struct MVHDGeom { - uint16_t cyl; - uint8_t heads; - uint8_t spt; + uint16_t cyl; + uint8_t heads; + uint8_t spt; } MVHDGeom; typedef void (*mvhd_progress_callback)(uint32_t current_sector, uint32_t total_sectors); typedef struct MVHDCreationOptions { - int type; /** MVHD_TYPE_FIXED, MVHD_TYPE_DYNAMIC, or MVHD_TYPE_DIFF */ - char *path; /** Absolute path of the new VHD file */ - char *parent_path; /** For MVHD_TYPE_DIFF, this is the absolute path of the VHD's parent. For non-diff VHDs, this should be NULL. */ - uint64_t size_in_bytes; /** Total size of the VHD's virtual disk in bytes. Must be a multiple of 512. If 0, the size is auto-calculated from the geometry field. Ignored for MVHD_TYPE_DIFF. */ - MVHDGeom geometry; /** The geometry of the VHD. If set to 0, the geometry is auto-calculated from the size_in_bytes field. */ - uint32_t block_size_in_sectors; /** MVHD_BLOCK_LARGE or MVHD_BLOCK_SMALL, or 0 for the default value. The number of sectors per block. */ - mvhd_progress_callback progress_callback; /** Optional; if not NULL, gets called to indicate progress on the creation operation. Only applies to MVHD_TYPE_FIXED. */ + int type; /** MVHD_TYPE_FIXED, MVHD_TYPE_DYNAMIC, or MVHD_TYPE_DIFF */ + char *path; /** Absolute path of the new VHD file */ + char *parent_path; /** For MVHD_TYPE_DIFF, this is the absolute path of the VHD's parent. For non-diff VHDs, this should + be NULL. */ + uint64_t size_in_bytes; /** Total size of the VHD's virtual disk in bytes. Must be a multiple of 512. If 0, the size is + auto-calculated from the geometry field. Ignored for MVHD_TYPE_DIFF. */ + MVHDGeom geometry; /** The geometry of the VHD. If set to 0, the geometry is auto-calculated from the size_in_bytes field. + */ + uint32_t block_size_in_sectors; /** MVHD_BLOCK_LARGE or MVHD_BLOCK_SMALL, or 0 for the default value. The number of + sectors per block. */ + mvhd_progress_callback progress_callback; /** Optional; if not NULL, gets called to indicate progress on the creation + operation. Only applies to MVHD_TYPE_FIXED. */ } MVHDCreationOptions; typedef struct MVHDMeta MVHDMeta; /** * \brief Output a string from a MiniVHD error number - * + * * \param [in] err is the error number to return string from - * + * * \return Error string */ const char *mvhd_strerr(MVHDError err); /** * \brief A simple test to see if a given file is a VHD - * + * * \param [in] f file to test - * + * * \retval true if f is a VHD * \retval false if f is not a VHD */ @@ -81,20 +82,20 @@ bool mvhd_file_is_vhd(FILE *f); /** * \brief Open a VHD image for reading and/or writing - * - * The returned pointer contains all required values and structures (and files) to + * + * The returned pointer contains all required values and structures (and files) to * read and write to a VHD file. - * + * * Remember to call mvhd_close() when you are finished. - * + * * \param [in] Absolute path to VHD file. Relative path will cause issues when opening * a differencing VHD file * \param [in] readonly set this to true to open the VHD in a read only manner - * \param [out] err will be set if the VHD fails to open. Value could be one of - * MVHD_ERR_MEM, MVHD_ERR_FILE, MVHD_ERR_NOT_VHD, MVHD_ERR_FOOTER_CHECKSUM, MVHD_ERR_SPARSE_CHECKSUM, + * \param [out] err will be set if the VHD fails to open. Value could be one of + * MVHD_ERR_MEM, MVHD_ERR_FILE, MVHD_ERR_NOT_VHD, MVHD_ERR_FOOTER_CHECKSUM, MVHD_ERR_SPARSE_CHECKSUM, * MVHD_ERR_TYPE, MVHD_ERR_TIMESTAMP * If MVHD_ERR_FILE is set, mvhd_errno will be set to the appropriate system errno value - * + * * \return MVHDMeta pointer. If NULL, check err. err may also be set to MVHD_ERR_TIMESTAMP if * opening a differencing VHD. */ @@ -102,52 +103,52 @@ MVHDMeta *mvhd_open(const char *path, bool readonly, int *err); /** * \brief Update the parent modified timestamp in the VHD file - * + * * Differencing VHD's use a parent last modified timestamp to try and detect if the * parent has been modified after the child has been created. However, this is rather * fragile and can be broken by moving/copying the parent. Also, MS DiskPart does not * set this timestamp in the child :( - * + * * Be careful when using this function that you don't update the timestamp after the * parent actually has been modified. - * + * * \param [in] vhdm Differencing VHD to update. * \param [out] err will be set if the timestamp could not be updated - * + * * \return non-zero on error, 0 on success */ int mvhd_diff_update_par_timestamp(MVHDMeta *vhdm, int *err); /** * \brief Create a fixed VHD image - * + * * \param [in] path is the absolute path to the image to create * \param [in] geom is the HDD geometry of the image to create. Determines final image size * \param [out] err indicates what error occurred, if any - * \param [out] progress_callback optional; if not NULL, gets called to indicate progress on the creation operation - * + * \param [out] progress_callback optional; if not NULL, gets called to indicate progress on the creation operation + * * \retval NULL if an error occurrs. Check value of *err for actual error. Otherwise returns pointer to a MVHDMeta struct */ MVHDMeta *mvhd_create_fixed(const char *path, MVHDGeom geom, int *err, mvhd_progress_callback progress_callback); /** * \brief Create sparse (dynamic) VHD image. - * + * * \param [in] path is the absolute path to the VHD file to create * \param [in] geom is the HDD geometry of the image to create. Determines final image size - * \param [out] err indicates what error occurred, if any - * + * \param [out] err indicates what error occurred, if any + * * \return NULL if an error occurrs. Check value of *err for actual error. Otherwise returns pointer to a MVHDMeta struct */ MVHDMeta *mvhd_create_sparse(const char *path, MVHDGeom geom, int *err); /** * \brief Create differencing VHD imagee. - * + * * \param [in] path is the absolute path to the VHD file to create - * \param [in] par_path is the absolute path to a parent image. If NULL, a sparse image is created, otherwise create a differencing image - * \param [out] err indicates what error occurred, if any - * + * \param [in] par_path is the absolute path to a parent image. If NULL, a sparse image is created, otherwise create a + * differencing image \param [out] err indicates what error occurred, if any + * * \return NULL if an error occurrs. Check value of *err for actual error. Otherwise returns pointer to a MVHDMeta struct */ MVHDMeta *mvhd_create_diff(const char *path, const char *par_path, int *err); @@ -155,7 +156,8 @@ MVHDMeta *mvhd_create_diff(const char *path, const char *par_path, int *err); /** * \brief Create a VHD using the provided options * - * Use mvhd_create_ex if you want more control over the VHD's options. For quick creation, you can use mvhd_create_fixed, mvhd_create_sparse, or mvhd_create_diff. + * Use mvhd_create_ex if you want more control over the VHD's options. For quick creation, you can use mvhd_create_fixed, + * mvhd_create_sparse, or mvhd_create_diff. * * \param [in] options the VHD creation options. * \param [out] err indicates what error occurred, if any @@ -166,48 +168,48 @@ MVHDMeta *mvhd_create_ex(MVHDCreationOptions options, int *err); /** * \brief Safely close a VHD image - * + * * \param [in] vhdm MiniVHD data structure to close */ void mvhd_close(MVHDMeta *vhdm); /** * \brief Calculate hard disk geometry from a provided size - * + * * The VHD format uses Cylinder, Heads, Sectors per Track (CHS) when accessing the disk. * The size of the disk can be determined from C * H * S * sector_size. - * + * * Note, maximum geometry size (in bytes) is 65535 * 16 * 255 * 512, which is 127GB. * However, the maximum VHD size is 2040GB. For VHDs larger than 127GB, the geometry size will be * smaller than the actual VHD size. - * + * * This function determines the appropriate CHS geometry from a provided size in bytes. - * The calculations used are those provided in "Appendix: CHS Calculation" from the document + * The calculations used are those provided in "Appendix: CHS Calculation" from the document * "Virtual Hard Disk Image Format Specification" provided by Microsoft. - * + * * \param [in] size the desired VHD image size, in bytes - * + * * \return MVHDGeom the calculated geometry. This can be used in the appropriate create functions. */ MVHDGeom mvhd_calculate_geometry(uint64_t size); /** * \brief Get the CHS geometry from the image - * + * * \param [in] vhdm MiniVHD data structure - * + * * \return The CHS geometry as stored in the image */ MVHDGeom mvhd_get_geometry(MVHDMeta *vhdm); /** * \brief Get the 'current_size' value from the image - * + * * Note that the size returned may not match the size calculated from the * CHS geometry. It is up to the caller to decide how best to handle this. - * + * * \param [in] vhdm MiniVHD data structure - * + * * \return The 'current_size' value in bytes, as stored in the image. * Note, this may not match the CHS geometry. */ @@ -215,94 +217,94 @@ uint64_t mvhd_get_current_size(MVHDMeta *vhdm); /** * \brief Calculate CHS geometry size in bytes - * + * * \param [in] geom the CHS geometry to calculate - * + * * \return the size in bytes */ uint64_t mvhd_calc_size_bytes(MVHDGeom *geom); /** * \brief Calculate CHS geometry size in sectors - * + * * \param [in] geom the CHS geometry to calculate - * + * * \return the size in sectors */ uint32_t mvhd_calc_size_sectors(MVHDGeom *geom); /** * \brief Convert a raw disk image to a fixed VHD image - * + * * \param [in] utf8_raw_path is the path of the raw image to convert * \param [in] utf8_vhd_path is the path of the VHD to create * \param [out] err indicates what error occurred, if any - * + * * \return NULL if an error occurrs. Check value of *err for actual error. Otherwise returns pointer to a MVHDMeta struct */ MVHDMeta *mvhd_convert_to_vhd_fixed(const char *utf8_raw_path, const char *utf8_vhd_path, int *err); /** * \brief Convert a raw disk image to a sparse VHD image - * + * * \param [in] utf8_raw_path is the path of the raw image to convert * \param [in] utf8_vhd_path is the path of the VHD to create * \param [out] err indicates what error occurred, if any - * + * * \return NULL if an error occurrs. Check value of *err for actual error. Otherwise returns pointer to a MVHDMeta struct */ MVHDMeta *mvhd_convert_to_vhd_sparse(const char *utf8_raw_path, const char *utf8_vhd_path, int *err); /** * \brief Convert a VHD image to a raw disk image - * + * * \param [in] utf8_vhd_path is the path of the VHD to convert * \param [in] utf8_raw_path is the path of the raw image to create * \param [out] err indicates what error occurred, if any - * + * * \return NULL if an error occurrs. Check value of *err for actual error. Otherwise returns the raw disk image FILE pointer */ FILE *mvhd_convert_to_raw(const char *utf8_vhd_path, const char *utf8_raw_path, int *err); /** * \brief Read sectors from VHD file - * + * * Read num_sectors, beginning at offset from the VHD file into a buffer - * + * * \param [in] vhdm MiniVHD data structure * \param [in] offset the sector offset from which to start reading from * \param [in] num_sectors the number of sectors to read * \param [out] out_buff the buffer to write sector data to - * + * * \return the number of sectors that were not read, or zero */ int mvhd_read_sectors(MVHDMeta *vhdm, uint32_t offset, int num_sectors, void *out_buff); /** * \brief Write sectors to VHD file - * + * * Write num_sectors, beginning at offset from a buffer VHD file into the VHD file - * + * * \param [in] vhdm MiniVHD data structure * \param [in] offset the sector offset from which to start writing to * \param [in] num_sectors the number of sectors to write * \param [in] in_buffer the buffer to write sector data to - * + * * \return the number of sectors that were not written, or zero */ int mvhd_write_sectors(MVHDMeta *vhdm, uint32_t offset, int num_sectors, void *in_buff); /** * \brief Write zeroed sectors to VHD file - * - * Write num_sectors, beginning at offset, of zero data into the VHD file. - * We reuse the existing write functions, with a preallocated zero buffer as + * + * Write num_sectors, beginning at offset, of zero data into the VHD file. + * We reuse the existing write functions, with a preallocated zero buffer as * our source buffer. - * + * * \param [in] vhdm MiniVHD data structure * \param [in] offset the sector offset from which to start writing to * \param [in] num_sectors the number of sectors to write - * + * * \return the number of sectors that were not written, or zero */ int mvhd_format_sectors(MVHDMeta *vhdm, uint32_t offset, int num_sectors); diff --git a/includes/private/hdd/minivhd/minivhd_create.h b/includes/private/hdd/minivhd/minivhd_create.h index 36fbd9f7..24b1a4af 100644 --- a/includes/private/hdd/minivhd/minivhd_create.h +++ b/includes/private/hdd/minivhd/minivhd_create.h @@ -3,6 +3,7 @@ #include #include "minivhd.h" -MVHDMeta *mvhd_create_fixed_raw(const char *path, FILE *raw_img, uint64_t size_in_bytes, MVHDGeom *geom, int *err, mvhd_progress_callback progress_callback); +MVHDMeta *mvhd_create_fixed_raw(const char *path, FILE *raw_img, uint64_t size_in_bytes, MVHDGeom *geom, int *err, + mvhd_progress_callback progress_callback); #endif diff --git a/includes/private/hdd/minivhd/minivhd_internal.h b/includes/private/hdd/minivhd/minivhd_internal.h index 02989122..77549017 100644 --- a/includes/private/hdd/minivhd/minivhd_internal.h +++ b/includes/private/hdd/minivhd/minivhd_internal.h @@ -14,7 +14,7 @@ #define MVHD_MAX_SIZE_IN_BYTES 0x1fe00000000 #define MVHD_SPARSE_BLK 0xffffffff -/* For simplicity, we don't handle paths longer than this +/* For simplicity, we don't handle paths longer than this * Note, this is the max path in characters, as that is what * Windows uses */ @@ -25,72 +25,72 @@ #define MVHD_DIF_LOC_W2KU 0x57326B75 typedef struct MVHDSectorBitmap { - uint8_t *curr_bitmap; - int sector_count; - int curr_block; + uint8_t *curr_bitmap; + int sector_count; + int curr_block; } MVHDSectorBitmap; typedef struct MVHDFooter { - uint8_t cookie[8]; - uint32_t features; - uint32_t fi_fmt_vers; - uint64_t data_offset; - uint32_t timestamp; - uint8_t cr_app[4]; - uint32_t cr_vers; - uint8_t cr_host_os[4]; - uint64_t orig_sz; - uint64_t curr_sz; - struct { - uint16_t cyl; - uint8_t heads; - uint8_t spt; - } geom; - uint32_t disk_type; - uint32_t checksum; - uint8_t uuid[16]; - uint8_t saved_st; - uint8_t reserved[427]; + uint8_t cookie[8]; + uint32_t features; + uint32_t fi_fmt_vers; + uint64_t data_offset; + uint32_t timestamp; + uint8_t cr_app[4]; + uint32_t cr_vers; + uint8_t cr_host_os[4]; + uint64_t orig_sz; + uint64_t curr_sz; + struct { + uint16_t cyl; + uint8_t heads; + uint8_t spt; + } geom; + uint32_t disk_type; + uint32_t checksum; + uint8_t uuid[16]; + uint8_t saved_st; + uint8_t reserved[427]; } MVHDFooter; typedef struct MVHDSparseHeader { - uint8_t cookie[8]; - uint64_t data_offset; - uint64_t bat_offset; - uint32_t head_vers; - uint32_t max_bat_ent; - uint32_t block_sz; - uint32_t checksum; - uint8_t par_uuid[16]; - uint32_t par_timestamp; - uint32_t reserved_1; - uint8_t par_utf16_name[512]; - struct { - uint32_t plat_code; - uint32_t plat_data_space; - uint32_t plat_data_len; - uint32_t reserved; - uint64_t plat_data_offset; - } par_loc_entry[8]; - uint8_t reserved_2[256]; + uint8_t cookie[8]; + uint64_t data_offset; + uint64_t bat_offset; + uint32_t head_vers; + uint32_t max_bat_ent; + uint32_t block_sz; + uint32_t checksum; + uint8_t par_uuid[16]; + uint32_t par_timestamp; + uint32_t reserved_1; + uint8_t par_utf16_name[512]; + struct { + uint32_t plat_code; + uint32_t plat_data_space; + uint32_t plat_data_len; + uint32_t reserved; + uint64_t plat_data_offset; + } par_loc_entry[8]; + uint8_t reserved_2[256]; } MVHDSparseHeader; struct MVHDMeta { - FILE *f; - bool readonly; - char filename[MVHD_MAX_PATH_BYTES]; - struct MVHDMeta *parent; - MVHDFooter footer; - MVHDSparseHeader sparse; - uint32_t *block_offset; - int sect_per_block; - MVHDSectorBitmap bitmap; - int (*read_sectors)(MVHDMeta *, uint32_t, int, void *); - int (*write_sectors)(MVHDMeta *, uint32_t, int, void *); - struct { - uint8_t *zero_data; - int sector_count; - } format_buffer; + FILE *f; + bool readonly; + char filename[MVHD_MAX_PATH_BYTES]; + struct MVHDMeta *parent; + MVHDFooter footer; + MVHDSparseHeader sparse; + uint32_t *block_offset; + int sect_per_block; + MVHDSectorBitmap bitmap; + int (*read_sectors)(MVHDMeta *, uint32_t, int, void *); + int (*write_sectors)(MVHDMeta *, uint32_t, int, void *); + struct { + uint8_t *zero_data; + int sector_count; + } format_buffer; }; #endif diff --git a/includes/private/hdd/minivhd/minivhd_io.h b/includes/private/hdd/minivhd/minivhd_io.h index c7603fa7..98bae961 100644 --- a/includes/private/hdd/minivhd/minivhd_io.h +++ b/includes/private/hdd/minivhd/minivhd_io.h @@ -4,10 +4,10 @@ /** * \brief Write zero filled sectors to file. - * - * Note, the caller should set the file position before calling this + * + * Note, the caller should set the file position before calling this * function for correct operation. - * + * * \param [in] f File to write sectors to * \param [in] sector_count The number of sectors to write */ @@ -15,16 +15,16 @@ void mvhd_write_empty_sectors(FILE *f, int sector_count); /** * \brief Read a fixed VHD image - * - * Fixed VHD images are essentially raw image files with a footer tacked on + * + * Fixed VHD images are essentially raw image files with a footer tacked on * the end. They are therefore straightforward to write - * + * * \param [in] vhdm MiniVHD data structure * \param [in] offset Sector offset to read from * \param [in] num_sectors The desired number of sectors to read - * \param [out] out_buff An output buffer to store read sectors. Must be + * \param [out] out_buff An output buffer to store read sectors. Must be * large enough to hold num_sectors worth of sectors. - * + * * \retval 0 num_sectors were read from file * \retval >0 < num_sectors were read from file */ @@ -32,19 +32,19 @@ int mvhd_fixed_read(MVHDMeta *vhdm, uint32_t offset, int num_sectors, void *out_ /** * \brief Read a sparse VHD image - * - * Sparse, or dynamic images are VHD images that grow as data is written to them. - * - * This function implements the logic to read sectors from the file, taking into - * account the fact that blocks may be stored on disk in any order, and that the + * + * Sparse, or dynamic images are VHD images that grow as data is written to them. + * + * This function implements the logic to read sectors from the file, taking into + * account the fact that blocks may be stored on disk in any order, and that the * read could cross block boundaries. - * + * * \param [in] vhdm MiniVHD data structure * \param [in] offset Sector offset to read from * \param [in] num_sectors The desired number of sectors to read - * \param [out] out_buff An output buffer to store read sectors. Must be + * \param [out] out_buff An output buffer to store read sectors. Must be * large enough to hold num_sectors worth of sectors. - * + * * \retval 0 num_sectors were read from file * \retval >0 < num_sectors were read from file */ @@ -52,22 +52,22 @@ int mvhd_sparse_read(MVHDMeta *vhdm, uint32_t offset, int num_sectors, void *out /** * \brief Read a differencing VHD image - * - * Differencing images are a variant of a sparse image. They contain the grow-on-demand - * properties of sparse images, but also reference a parent image. Data is read from the + * + * Differencing images are a variant of a sparse image. They contain the grow-on-demand + * properties of sparse images, but also reference a parent image. Data is read from the * child image only if it is newer than the data stored in the parent image. - * - * This function implements the logic to read sectors from the child, or a parent image. - * Differencing images may have a differencing image as a parent, creating a chain of images. - * There is no theoretical chain length limit, although I do not consider long chains to be + * + * This function implements the logic to read sectors from the child, or a parent image. + * Differencing images may have a differencing image as a parent, creating a chain of images. + * There is no theoretical chain length limit, although I do not consider long chains to be * advisable. Verifying the parent-child relationship is not very robust. - * + * * \param [in] vhdm MiniVHD data structure * \param [in] offset Sector offset to read from * \param [in] num_sectors The desired number of sectors to read - * \param [out] out_buff An output buffer to store read sectors. Must be + * \param [out] out_buff An output buffer to store read sectors. Must be * large enough to hold num_sectors worth of sectors. - * + * * \retval 0 num_sectors were read from file * \retval >0 < num_sectors were read from file */ @@ -75,16 +75,16 @@ int mvhd_diff_read(MVHDMeta *vhdm, uint32_t offset, int num_sectors, void *out_b /** * \brief Write to a fixed VHD image - * - * Fixed VHD images are essentially raw image files with a footer tacked on + * + * Fixed VHD images are essentially raw image files with a footer tacked on * the end. They are therefore straightforward to write - * + * * \param [in] vhdm MiniVHD data structure * \param [in] offset Sector offset to write to * \param [in] num_sectors The desired number of sectors to write - * \param [in] in_buff A source buffer to write sectors from. Must be + * \param [in] in_buff A source buffer to write sectors from. Must be * large enough to hold num_sectors worth of sectors. - * + * * \retval 0 num_sectors were written to file * \retval >0 < num_sectors were written to file */ @@ -92,24 +92,24 @@ int mvhd_fixed_write(MVHDMeta *vhdm, uint32_t offset, int num_sectors, void *in_ /** * \brief Write to a sparse or differencing VHD image - * - * Sparse, or dynamic images are VHD images that grow as data is written to them. - * - * Differencing images are a variant of a sparse image. They contain the grow-on-demand - * properties of sparse images, but also reference a parent image. Data is always written - * to the child image. This makes writing to differencing images essentially identical to + * + * Sparse, or dynamic images are VHD images that grow as data is written to them. + * + * Differencing images are a variant of a sparse image. They contain the grow-on-demand + * properties of sparse images, but also reference a parent image. Data is always written + * to the child image. This makes writing to differencing images essentially identical to * writing to sparse images, hence they use the same function. - * - * This function implements the logic to write sectors to the file, taking into - * account the fact that blocks may be stored on disk in any order, and that the + * + * This function implements the logic to write sectors to the file, taking into + * account the fact that blocks may be stored on disk in any order, and that the * write operation could cross block boundaries. - * + * * \param [in] vhdm MiniVHD data structure * \param [in] offset Sector offset to write to * \param [in] num_sectors The desired number of sectors to write - * \param [in] in_buff A source buffer to write sectors from. Must be + * \param [in] in_buff A source buffer to write sectors from. Must be * large enough to hold num_sectors worth of sectors. - * + * * \retval 0 num_sectors were written to file * \retval >0 < num_sectors were written to file */ @@ -117,13 +117,13 @@ int mvhd_sparse_diff_write(MVHDMeta *vhdm, uint32_t offset, int num_sectors, voi /** * \brief A no-op function to "write" to read-only VHD images - * + * * \param [in] vhdm MiniVHD data structure * \param [in] offset Sector offset to write to * \param [in] num_sectors The desired number of sectors to write - * \param [in] in_buff A source buffer to write sectors from. Must be + * \param [in] in_buff A source buffer to write sectors from. Must be * large enough to hold num_sectors worth of sectors. - * + * * \retval 0 num_sectors were written to file * \retval >0 < num_sectors were written to file */ diff --git a/includes/private/hdd/minivhd/minivhd_struct_rw.h b/includes/private/hdd/minivhd/minivhd_struct_rw.h index 2b264ac6..aac7184c 100644 --- a/includes/private/hdd/minivhd/minivhd_struct_rw.h +++ b/includes/private/hdd/minivhd/minivhd_struct_rw.h @@ -5,7 +5,7 @@ /** * \brief Save the contents of a VHD footer from a buffer to a struct - * + * * \param [out] footer save contents of buffer into footer * \param [in] buffer VHD footer in raw bytes */ @@ -13,7 +13,7 @@ void mvhd_buffer_to_footer(MVHDFooter *footer, uint8_t *buffer); /** * \brief Save the contents of a VHD sparse header from a buffer to a struct - * + * * \param [out] header save contents of buffer into header * \param [in] buffer VHD header in raw bytes */ @@ -21,7 +21,7 @@ void mvhd_buffer_to_header(MVHDSparseHeader *header, uint8_t *buffer); /** * \brief Save the contents of a VHD footer struct to a buffer - * + * * \param [in] footer save contents of struct into buffer * \param [out] buffer VHD footer in raw bytes */ @@ -29,7 +29,7 @@ void mvhd_footer_to_buffer(MVHDFooter *footer, uint8_t *buffer); /** * \brief Save the contents of a VHD sparse header struct to a buffer - * + * * \param [in] header save contents of struct into buffer * \param [out] buffer VHD sparse header in raw bytes */ diff --git a/includes/private/hdd/minivhd/minivhd_util.h b/includes/private/hdd/minivhd/minivhd_util.h index 357660f8..ce27e5e8 100644 --- a/includes/private/hdd/minivhd/minivhd_util.h +++ b/includes/private/hdd/minivhd/minivhd_util.h @@ -20,9 +20,9 @@ uint64_t mvhd_to_be64(uint64_t val); /** * \brief Check if provided buffer begins with the string "conectix" - * + * * \param [in] buffer The buffer to compare. Must be at least 8 bytes in length - * + * * \return true if the buffer begins with "conectix" * \return false if the buffer does not begin with "conectix" */ @@ -30,7 +30,7 @@ bool mvhd_is_conectix_str(const void *buffer); /** * \brief Generate a raw 16 byte UUID - * + * * \param [out] uuid A 16 byte buffer in which the generated UUID will be stored to */ void mvhd_generate_uuid(uint8_t *uuid); @@ -42,9 +42,9 @@ uint32_t vhd_calc_timestamp(void); /** * \brief Convert an epoch timestamp to a VHD timestamp - * + * * \param [in] ts epoch timestamp to convert. - * + * * \return The adjusted timestamp, or 0 if the input timestamp is * earlier that 1 Janurary 2000 */ @@ -52,26 +52,26 @@ uint32_t mvhd_epoch_to_vhd_ts(time_t ts); /** * \brief Return the created time from a VHD image - * + * * \param [in] vhdm Pointer to the MiniVHD metadata structure - * + * * \return The created time, as a Unix timestamp */ time_t vhd_get_created_time(MVHDMeta *vhdm); /** * \brief Cross platform, unicode filepath opening - * - * This function accounts for the fact that fopen() handles file paths differently compared to other - * operating systems. Windows version of fopen() will not handle multi byte encoded text like UTF-8. - * - * Unicode filepath support on Windows requires using the _wfopen() function, which expects UTF-16LE + * + * This function accounts for the fact that fopen() handles file paths differently compared to other + * operating systems. Windows version of fopen() will not handle multi byte encoded text like UTF-8. + * + * Unicode filepath support on Windows requires using the _wfopen() function, which expects UTF-16LE * encoded path and modestring. - * + * * \param [in] path The filepath to open as a UTF-8 string * \param [in] mode The mode string to use (eg: "rb+"") * \param [out] err The error value, if an error occurrs - * + * * \return a FILE pointer if successful, NULL otherwise. If NULL, check the value of err */ FILE *mvhd_fopen(const char *path, const char *mode, int *err); @@ -80,52 +80,52 @@ void mvhd_set_encoding_err(int encoding_retval, int *err); /** * \brief Generate VHD footer checksum - * + * * \param [in] vhdm MiniVHD data structure */ uint32_t mvhd_gen_footer_checksum(MVHDFooter *footer); /** * \brief Generate VHD sparse header checksum - * + * * \param [in] vhdm MiniVHD data structure */ uint32_t mvhd_gen_sparse_checksum(MVHDSparseHeader *header); /** * \brief Get current position in file stream - * - * This is a portable version of the POSIX ftello64(). * + * + * This is a portable version of the POSIX ftello64(). * */ int64_t mvhd_ftello64(FILE *stream); /** * \brief Reposition the file stream's position - * - * This is a portable version of the POSIX fseeko64(). * + * + * This is a portable version of the POSIX fseeko64(). * */ int mvhd_fseeko64(FILE *stream, int64_t offset, int origin); /** * \brief Calculate the CRC32 of a data buffer. - * + * * This function can be used for verifying data integrity. - * + * * \param [in] data The data buffer * \param [in] n_bytes The size of the data buffer in bytes - * + * * \return The CRC32 of the data buffer */ uint32_t mvhd_crc32(const void *data, size_t n_bytes); /** * \brief Calculate the file modification timestamp. - * + * * This function is primarily to help protect differencing VHD's - * + * * \param [in] path the UTF-8 file path * \param [out] err The error value, if an error occurrs - * + * * \return The file modified timestamp, in VHD compatible timestamp. * 'err' will be set to non-zero on error */ diff --git a/includes/private/ibm.h b/includes/private/ibm.h index ced6a657..9c2fcdd5 100644 --- a/includes/private/ibm.h +++ b/includes/private/ibm.h @@ -13,14 +13,14 @@ #undef ABS #endif -#define ABS(x) ((x) > 0 ? (x) : -(x)) +#define ABS(x) ((x) > 0 ? (x) : -(x)) #define MAX(a, b) (((a) > (b)) ? (a) : (b)) #define READFLASH_FDC 0 #define READFLASH_HDC 4 -#define readflash_set(offset, drive) readflash |= 1<<((offset)+(drive)) -#define readflash_clear(offset, drive) readflash &= ~(1<<((offset)+(drive))) -#define readflash_get(offset, drive) ((readflash&(1<<((offset)+(drive)))) != 0) +#define readflash_set(offset, drive) readflash |= 1 << ((offset) + (drive)) +#define readflash_clear(offset, drive) readflash &= ~(1 << ((offset) + (drive))) +#define readflash_get(offset, drive) ((readflash & (1 << ((offset) + (drive)))) != 0) /*Memory*/ uint8_t *ram; @@ -71,37 +71,37 @@ extern int cycles_lost; /*Timer*/ typedef struct PIT_nr { - int nr; - struct PIT *pit; + int nr; + struct PIT *pit; } PIT_nr; typedef struct PIT { - uint32_t l[3]; - pc_timer_t timer[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]; - int running[3]; - int enabled[3]; - int newcount[3]; - int count[3]; - int using_timer[3]; - int initial[3]; - int latched[3]; - int disabled[3]; + uint32_t l[3]; + pc_timer_t timer[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]; + int 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]; + uint8_t read_status[3]; + int do_read_status[3]; - PIT_nr pit_nr[3]; + PIT_nr pit_nr[3]; - void (*set_out_funcs[3])(int new_out, int old_out); + void (*set_out_funcs[3])(int new_out, int old_out); } PIT; PIT pit, pit2; @@ -109,44 +109,44 @@ void setpitclock(float clock); float pit_timer0_freq(); -#define cpu_rm cpu_state.rm_data.rm_mod_reg.rm +#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 /*DMA*/ typedef struct dma_t { - 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; + 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; + uint8_t ps2_mode; + uint8_t arb_level; + uint16_t io_addr; } dma_t; dma_t dma[8]; /*PPI*/ typedef struct PPI { - int s2; - uint8_t pa, pb; + int s2; + uint8_t pa, pb; } PPI; PPI ppi; /*PIC*/ typedef struct PIC { - uint8_t icw1, icw4, mask, ins, pend, mask2; - int icw; - uint8_t vector; - int read; - uint8_t level_sensitive; + uint8_t icw1, icw4, mask, ins, pend, mask2; + int icw; + uint8_t vector; + int read; + uint8_t level_sensitive; } PIC; PIC pic, pic2; @@ -161,108 +161,108 @@ int GAMEBLASTER, GUS, SSI2001, voodoo_enabled; extern int AMSTRAD, AT, is386, PCI, TANDY, MCA; enum { - ROM_IBMPC = 0, - ROM_IBMXT, - ROM_IBMPCJR, - ROM_GENXT, /*'Generic XT BIOS'*/ - ROM_CBM_PC10, - ROM_SUPER16T, - ROM_SUPER16TE, - ROM_DTKXT, - ROM_EUROPC, - ROM_OLIM24, - ROM_TANDY, - ROM_PC1512, - ROM_PC200, - ROM_PC1640, - ROM_PC2086, - ROM_PC3086, - ROM_AMIXT, /*XT Clone with AMI BIOS*/ - ROM_LTXT, - ROM_LXT3, - ROM_PX386, - ROM_DTK386, - ROM_PXXT, - ROM_JUKOPC, - ROM_TANDY1000HX, - ROM_TANDY1000SL2, - ROM_IBMAT, - ROM_CMDPC30, - ROM_AMI286, - ROM_TG286M, - ROM_AWARD286, - ROM_GDC212M, - ROM_GW286CT, - ROM_SPC4200P, - ROM_SPC4216P, - ROM_SPC4620P, - ROM_DELL200, - ROM_MISC286, - ROM_IBMAT386, - ROM_ACER386, - ROM_KMXC02, - ROM_MEGAPC, - ROM_AMA932J, - ROM_AMI386SX, - ROM_SPC6000A, - ROM_SPC6033P, - ROM_AMI486, - ROM_WIN486, - ROM_PCI486, - ROM_SIS496, - ROM_P55VA, /* Epox P55-VA/430VX/Award/SMC FDC37C932FR*/ - ROM_P55TVP4, /* ASUS P/I-P55TVP4/430VX/Award/Winbond W8387F*/ - ROM_430VX, - ROM_ENDEAVOR, - ROM_REVENGE, - ROM_IBMPS1_2011, - ROM_DESKPRO_386, - ROM_IBMPS1_2121, - ROM_AMI386DX_OPTI495, - ROM_MR386DX_OPTI495, - ROM_P55T2P4, /* ASUS P/I-P55T2P4/430HX/Award/Winbond W8387F*/ - ROM_IBMPS2_M30_286, - ROM_IBMPS2_M50, - ROM_IBMPS2_M55SX, - ROM_IBMPS2_M80, - ROM_ATARIPC3, - ROM_IBMXT286, - ROM_EPSON_PCAX, - ROM_EPSON_PCAX2E, - ROM_EPSON_PCAX3, - ROM_T3100E, - ROM_T1000, - ROM_T1200, - ROM_PB_L300SX, - ROM_NCR_PC4I, - ROM_TO16_PC, - ROM_COMPAQ_PII, - ROM_ELX_PC425X, - ROM_PB570, - ROM_ZAPPA, - ROM_PB520R, - ROM_COMPAQ_PIP, - ROM_XI8088, - ROM_IBMPS2_M70_TYPE3, - ROM_IBMPS2_M70_TYPE4, - ROM_TULIP_TC7, - ROM_ZD_SUPERS, /* [8088] Zenith Data Systems SupersPort */ - ROM_PB410A, - ROM_PPC512, - ROM_BULL_MICRAL_45, - ROM_FIC_VA503P, - ROM_CBM_SL386SX25, - ROM_IBMPS1_2133_451, - ROM_ECS_386_32, - ROM_LEDGE_MODELM, - ROM_HYUNDAI_SUPER286TR, - ROM_ITAUTEC_INFOWAYM, - ROM_DESKPRO, - ROM_VS440FX, - ROM_GA686BX, - ROM_PC5086, + ROM_IBMPC = 0, + ROM_IBMXT, + ROM_IBMPCJR, + ROM_GENXT, /*'Generic XT BIOS'*/ + ROM_CBM_PC10, + ROM_SUPER16T, + ROM_SUPER16TE, + ROM_DTKXT, + ROM_EUROPC, + ROM_OLIM24, + ROM_TANDY, + ROM_PC1512, + ROM_PC200, + ROM_PC1640, + ROM_PC2086, + ROM_PC3086, + ROM_AMIXT, /*XT Clone with AMI BIOS*/ + ROM_LTXT, + ROM_LXT3, + ROM_PX386, + ROM_DTK386, + ROM_PXXT, + ROM_JUKOPC, + ROM_TANDY1000HX, + ROM_TANDY1000SL2, + ROM_IBMAT, + ROM_CMDPC30, + ROM_AMI286, + ROM_TG286M, + ROM_AWARD286, + ROM_GDC212M, + ROM_GW286CT, + ROM_SPC4200P, + ROM_SPC4216P, + ROM_SPC4620P, + ROM_DELL200, + ROM_MISC286, + ROM_IBMAT386, + ROM_ACER386, + ROM_KMXC02, + ROM_MEGAPC, + ROM_AMA932J, + ROM_AMI386SX, + ROM_SPC6000A, + ROM_SPC6033P, + ROM_AMI486, + ROM_WIN486, + ROM_PCI486, + ROM_SIS496, + ROM_P55VA, /* Epox P55-VA/430VX/Award/SMC FDC37C932FR*/ + ROM_P55TVP4, /* ASUS P/I-P55TVP4/430VX/Award/Winbond W8387F*/ + ROM_430VX, + ROM_ENDEAVOR, + ROM_REVENGE, + ROM_IBMPS1_2011, + ROM_DESKPRO_386, + ROM_IBMPS1_2121, + ROM_AMI386DX_OPTI495, + ROM_MR386DX_OPTI495, + ROM_P55T2P4, /* ASUS P/I-P55T2P4/430HX/Award/Winbond W8387F*/ + ROM_IBMPS2_M30_286, + ROM_IBMPS2_M50, + ROM_IBMPS2_M55SX, + ROM_IBMPS2_M80, + ROM_ATARIPC3, + ROM_IBMXT286, + ROM_EPSON_PCAX, + ROM_EPSON_PCAX2E, + ROM_EPSON_PCAX3, + ROM_T3100E, + ROM_T1000, + ROM_T1200, + ROM_PB_L300SX, + ROM_NCR_PC4I, + ROM_TO16_PC, + ROM_COMPAQ_PII, + ROM_ELX_PC425X, + ROM_PB570, + ROM_ZAPPA, + ROM_PB520R, + ROM_COMPAQ_PIP, + ROM_XI8088, + ROM_IBMPS2_M70_TYPE3, + ROM_IBMPS2_M70_TYPE4, + ROM_TULIP_TC7, + ROM_ZD_SUPERS, /* [8088] Zenith Data Systems SupersPort */ + ROM_PB410A, + ROM_PPC512, + ROM_BULL_MICRAL_45, + ROM_FIC_VA503P, + ROM_CBM_SL386SX25, + ROM_IBMPS1_2133_451, + ROM_ECS_386_32, + ROM_LEDGE_MODELM, + ROM_HYUNDAI_SUPER286TR, + ROM_ITAUTEC_INFOWAYM, + ROM_DESKPRO, + ROM_VS440FX, + ROM_GA686BX, + ROM_PC5086, - ROM_BUILTIN_MAX, + ROM_BUILTIN_MAX, }; extern int romspresent[ROM_MAX]; @@ -271,57 +271,57 @@ int hasfpu; int romset; enum { - GFX_BUILTIN = -1, - GFX_CGA = 0, - GFX_MDA, - GFX_HERCULES, - GFX_EGA, /*Using IBM EGA BIOS*/ - GFX_TVGA, /*Using Trident TVGA8900D BIOS*/ - GFX_ET4000, /*Tseng ET4000*/ - GFX_KASAN16VGA, /*Kasan Hangulmadang-16 (Tseng ET4000AX)*/ - GFX_TGKOREANVGA, /*Trigem Korean VGA(Tseng ET4000AX)*/ - GFX_ET4000W32, /*Tseng ET4000/W32p (Diamond Stealth 32)*/ - GFX_BAHAMAS64, /*S3 Vision864 (Paradise Bahamas 64)*/ - GFX_N9_9FX, /*S3 764/Trio64 (Number Nine 9FX)*/ - GFX_VIRGE, /*S3 Virge*/ - GFX_TGUI9440, /*Trident TGUI9440*/ - GFX_VGA, /*IBM VGA*/ - GFX_VGAEDGE16, /*ATI VGA Edge-16 (18800-1)*/ - GFX_ATIKOREANVGA, /*ATI Korean VGA (28800-5)*/ - GFX_VGACHARGER, /*ATI VGA Charger (28800-5)*/ - GFX_OTI067, /*Oak OTI-067*/ - GFX_MACH64GX, /*ATI Graphics Pro Turbo (Mach64)*/ - GFX_CL_GD5429, /*Cirrus Logic CL-GD5429*/ - GFX_VIRGEDX, /*S3 Virge/DX*/ - GFX_PHOENIX_TRIO32, /*S3 732/Trio32 (Phoenix)*/ - GFX_PHOENIX_TRIO64, /*S3 764/Trio64 (Phoenix)*/ - GFX_INCOLOR, /* Hercules InColor */ - GFX_COLORPLUS, /* Plantronics ColorPlus */ - GFX_WY700, /* Wyse 700 */ - GFX_GENIUS, /* MDSI Genius */ - GFX_MACH64VT2, /*ATI Mach64 VT2*/ - GFX_OLIVETTI_GO481, /*Olivetti GO481 PVGA1A*/ - GFX_TGUI9400CXI, /*Trident TGUI9440CXi*/ - GFX_CL_GD5430, /*Cirrus Logic CL-GD5430*/ - GFX_CL_GD5434, /*Cirrus Logic CL-GD5434*/ - GFX_OTI037, /*Oak OTI-037*/ - GFX_COMPAQ_CGA, /*Compaq CGA*/ - GFX_SIGMA400, /*Sigma Designs Color 400 */ - GFX_PGC, /*Professional Graphics Controller */ - GFX_IM1024, /*Vermont Microsystems IM1024 */ - GFX_EGAWONDER800, /*ATI EGA Wonder 800+*/ - GFX_MYSTIQUE, /*Matrox Mystique*/ - GFX_AVGA2, /*Acumos AVGA2 / Cirrus Logic CL-GD5402*/ - GFX_CL_GD5428, /*Cirrus Logic CL-GD5428*/ - GFX_IBM_GD5428, /*IBM 1MB SVGA Adapter/A*/ - GFX_TVGA9000B, /*Trident TVGA9000B*/ - GFX_BANSHEE, /*Voodoo Banshee - reference PCI board with SGRAM*/ - GFX_CL_BANSHEE, /*Creative Labs Voodoo Blaster Banshee PCI - with SDRAM*/ - GFX_VOODOO_3_2000, /*Voodoo 3 2000*/ - GFX_VOODOO_3_3000, /*Voodoo 3 3000*/ - GFX_MILLENNIUM, /*Matrox Millennium*/ + GFX_BUILTIN = -1, + GFX_CGA = 0, + GFX_MDA, + GFX_HERCULES, + GFX_EGA, /*Using IBM EGA BIOS*/ + GFX_TVGA, /*Using Trident TVGA8900D BIOS*/ + GFX_ET4000, /*Tseng ET4000*/ + GFX_KASAN16VGA, /*Kasan Hangulmadang-16 (Tseng ET4000AX)*/ + GFX_TGKOREANVGA, /*Trigem Korean VGA(Tseng ET4000AX)*/ + GFX_ET4000W32, /*Tseng ET4000/W32p (Diamond Stealth 32)*/ + GFX_BAHAMAS64, /*S3 Vision864 (Paradise Bahamas 64)*/ + GFX_N9_9FX, /*S3 764/Trio64 (Number Nine 9FX)*/ + GFX_VIRGE, /*S3 Virge*/ + GFX_TGUI9440, /*Trident TGUI9440*/ + GFX_VGA, /*IBM VGA*/ + GFX_VGAEDGE16, /*ATI VGA Edge-16 (18800-1)*/ + GFX_ATIKOREANVGA, /*ATI Korean VGA (28800-5)*/ + GFX_VGACHARGER, /*ATI VGA Charger (28800-5)*/ + GFX_OTI067, /*Oak OTI-067*/ + GFX_MACH64GX, /*ATI Graphics Pro Turbo (Mach64)*/ + GFX_CL_GD5429, /*Cirrus Logic CL-GD5429*/ + GFX_VIRGEDX, /*S3 Virge/DX*/ + GFX_PHOENIX_TRIO32, /*S3 732/Trio32 (Phoenix)*/ + GFX_PHOENIX_TRIO64, /*S3 764/Trio64 (Phoenix)*/ + GFX_INCOLOR, /* Hercules InColor */ + GFX_COLORPLUS, /* Plantronics ColorPlus */ + GFX_WY700, /* Wyse 700 */ + GFX_GENIUS, /* MDSI Genius */ + GFX_MACH64VT2, /*ATI Mach64 VT2*/ + GFX_OLIVETTI_GO481, /*Olivetti GO481 PVGA1A*/ + GFX_TGUI9400CXI, /*Trident TGUI9440CXi*/ + GFX_CL_GD5430, /*Cirrus Logic CL-GD5430*/ + GFX_CL_GD5434, /*Cirrus Logic CL-GD5434*/ + GFX_OTI037, /*Oak OTI-037*/ + GFX_COMPAQ_CGA, /*Compaq CGA*/ + GFX_SIGMA400, /*Sigma Designs Color 400 */ + GFX_PGC, /*Professional Graphics Controller */ + GFX_IM1024, /*Vermont Microsystems IM1024 */ + GFX_EGAWONDER800, /*ATI EGA Wonder 800+*/ + GFX_MYSTIQUE, /*Matrox Mystique*/ + GFX_AVGA2, /*Acumos AVGA2 / Cirrus Logic CL-GD5402*/ + GFX_CL_GD5428, /*Cirrus Logic CL-GD5428*/ + GFX_IBM_GD5428, /*IBM 1MB SVGA Adapter/A*/ + GFX_TVGA9000B, /*Trident TVGA9000B*/ + GFX_BANSHEE, /*Voodoo Banshee - reference PCI board with SGRAM*/ + GFX_CL_BANSHEE, /*Creative Labs Voodoo Blaster Banshee PCI - with SDRAM*/ + GFX_VOODOO_3_2000, /*Voodoo 3 2000*/ + GFX_VOODOO_3_3000, /*Voodoo 3 3000*/ + GFX_MILLENNIUM, /*Matrox Millennium*/ - GFX_BUILTIN_MAX, + GFX_BUILTIN_MAX, }; extern int gfx_present[GFX_MAX]; @@ -347,25 +347,24 @@ extern uint64_t VGACONST1, VGACONST2; extern uint64_t RTCCONST; int gated, speakval, speakon; - /*Sound Blaster*/ -#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*/ +#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*/ /*Hard disc*/ typedef struct { - FILE *f; - int spt, hpc; /*Sectors per track, heads per cylinder*/ - int tracks; + FILE *f; + int spt, hpc; /*Sectors per track, heads per cylinder*/ + int tracks; } PcemHDC; PcemHDC hdc[7]; @@ -378,11 +377,11 @@ extern int cdrom_drive; extern int old_cdrom_drive; extern int idecallback[2]; -#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 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 extern uint32_t atapi_get_cd_volume(int channel); diff --git a/includes/private/ide/ide.h b/includes/private/ide/ide.h index d9ce4b27..af3dcea8 100644 --- a/includes/private/ide/ide.h +++ b/includes/private/ide/ide.h @@ -17,9 +17,8 @@ extern void ide_sec_enable(); extern void ide_pri_disable(); extern void ide_sec_disable(); extern void ide_set_bus_master(int (*read_data)(int channel, uint8_t *data, int size, void *p), - int (*write_data)(int channel, uint8_t *data, int size, void *p), - void (*set_irq)(int channel, void *p), - void *p); + int (*write_data)(int channel, uint8_t *data, int size, void *p), + void (*set_irq)(int channel, void *p), void *p); void ide_irq_raise(struct IDE *ide); void ide_reset_devices(); @@ -46,23 +45,23 @@ uint32_t atapi_get_cd_volume(int channel); extern device_t ide_device; /* Bits of 'atastat' */ -#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 +#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 ABRT_ERR 0x04 /* Command aborted */ +#define MCR_ERR 0x08 /* Media change request */ -#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_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 +#define FEATURE_DISABLE_IRQ_SERVICE 0xde #endif //__IDE__ diff --git a/includes/private/ide/ide_atapi.h b/includes/private/ide/ide_atapi.h index ecfb3711..69e54a55 100644 --- a/includes/private/ide/ide_atapi.h +++ b/includes/private/ide/ide_atapi.h @@ -5,25 +5,25 @@ /*ATAPI stuff*/ typedef struct ATAPI { - int (*ready)(void); - int (*medium_changed)(void); - int (*readtoc)(uint8_t *b, uint8_t starttrack, int msf, int maxlen, int single); - int (*readtoc_session)(uint8_t *b, int msf, int maxlen); - int (*readtoc_raw)(uint8_t *b, int maxlen); - uint8_t (*getcurrentsubchannel)(uint8_t *b, int msf); - int (*readsector)(uint8_t *b, int sector, int count); - void (*readsector_raw)(uint8_t *b, int sector); - void (*playaudio)(uint32_t pos, uint32_t len, int ismsf); - void (*seek)(uint32_t pos); - void (*load)(void); - void (*eject)(void); - void (*pause)(void); - void (*resume)(void); - uint32_t (*size)(void); - int (*status)(void); - int (*is_track_audio)(uint32_t pos, int ismsf); - void (*stop)(void); - void (*exit)(void); + int (*ready)(void); + int (*medium_changed)(void); + int (*readtoc)(uint8_t *b, uint8_t starttrack, int msf, int maxlen, int single); + int (*readtoc_session)(uint8_t *b, int msf, int maxlen); + int (*readtoc_raw)(uint8_t *b, int maxlen); + uint8_t (*getcurrentsubchannel)(uint8_t *b, int msf); + int (*readsector)(uint8_t *b, int sector, int count); + void (*readsector_raw)(uint8_t *b, int sector); + void (*playaudio)(uint32_t pos, uint32_t len, int ismsf); + void (*seek)(uint32_t pos); + void (*load)(void); + void (*eject)(void); + void (*pause)(void); + void (*resume)(void); + uint32_t (*size)(void); + int (*status)(void); + int (*is_track_audio)(uint32_t pos, int ismsf); + void (*stop)(void); + void (*exit)(void); } ATAPI; extern ATAPI *atapi; @@ -31,28 +31,28 @@ extern ATAPI *atapi; void atapi_discchanged(); typedef struct atapi_device_t { - scsi_bus_t bus; + scsi_bus_t bus; - uint8_t command[12]; - int command_pos; + uint8_t command[12]; + int command_pos; - int state; + int state; - int max_transfer_len; + int max_transfer_len; - uint8_t data[65536]; - int data_read_pos, data_write_pos; + uint8_t data[65536]; + int data_read_pos, data_write_pos; - int bus_state; + int bus_state; - struct IDE *ide; + struct IDE *ide; - int board; - uint8_t *atastat; - uint8_t *error; - int *cylinder; + int board; + uint8_t *atastat; + uint8_t *error; + int *cylinder; - int use_dma; + int use_dma; } atapi_device_t; void atapi_data_write(atapi_device_t *atapi_dev, uint16_t val); diff --git a/includes/private/ide/ide_sff8038i.h b/includes/private/ide/ide_sff8038i.h index 1cd45fa6..fd2a3736 100644 --- a/includes/private/ide/ide_sff8038i.h +++ b/includes/private/ide/ide_sff8038i.h @@ -1,12 +1,12 @@ #ifndef _IDE_SFF8038I_H_ #define _IDE_SFF8038I_H_ typedef struct sff_busmaster_t { - uint8_t command; - uint8_t status; - uint32_t ptr, ptr_cur; - int count; - uint32_t addr; - int eot; + uint8_t command; + uint8_t status; + uint32_t ptr, ptr_cur; + int count; + uint32_t addr; + int eot; } sff_busmaster_t; uint8_t sff_bus_master_read(uint16_t port, void *p); diff --git a/includes/private/io.h b/includes/private/io.h index bce5df2b..6e3db02a 100644 --- a/includes/private/io.h +++ b/includes/private/io.h @@ -5,22 +5,14 @@ void io_init(); -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); +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); -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); +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); #endif /* _IO_H_ */ diff --git a/includes/private/joystick/gameport.h b/includes/private/joystick/gameport.h index c26e90fd..0df7bd40 100644 --- a/includes/private/joystick/gameport.h +++ b/includes/private/joystick/gameport.h @@ -3,8 +3,7 @@ extern device_t gameport_device; extern device_t gameport_201_device; -typedef struct -{ +typedef struct { char name[80]; void *(*init)(); void (*close)(void *p); @@ -33,5 +32,4 @@ void gameport_update_joystick_type(); #define AXIS_NOT_PRESENT -99999 - #endif /* _GAMEPORT_H_ */ diff --git a/includes/private/joystick/joystick_ch_flightstick_pro.h b/includes/private/joystick/joystick_ch_flightstick_pro.h index 2f8529b7..f9d78984 100644 --- a/includes/private/joystick/joystick_ch_flightstick_pro.h +++ b/includes/private/joystick/joystick_ch_flightstick_pro.h @@ -2,5 +2,4 @@ #define _JOYSTICK_CH_FLIGHTSTICK_PRO_H_ extern joystick_if_t joystick_ch_flightstick_pro; - #endif /* _JOYSTICK_CH_FLIGHTSTICK_PRO_H_ */ diff --git a/includes/private/joystick/joystick_standard.h b/includes/private/joystick/joystick_standard.h index cec9babc..c6ec05e0 100644 --- a/includes/private/joystick/joystick_standard.h +++ b/includes/private/joystick/joystick_standard.h @@ -5,5 +5,4 @@ extern joystick_if_t joystick_standard_4button; extern joystick_if_t joystick_standard_6button; extern joystick_if_t joystick_standard_8button; - #endif /* _JOYSTICK_STANDARD_H_ */ diff --git a/includes/private/joystick/joystick_sw_pad.h b/includes/private/joystick/joystick_sw_pad.h index 50ecd212..af1806ee 100644 --- a/includes/private/joystick/joystick_sw_pad.h +++ b/includes/private/joystick/joystick_sw_pad.h @@ -2,5 +2,4 @@ #define _JOYSTICK_SW_PAD_H_ extern joystick_if_t joystick_sw_pad; - #endif /* _JOYSTICK_SW_PAD_H_ */ diff --git a/includes/private/joystick/joystick_tm_fcs.h b/includes/private/joystick/joystick_tm_fcs.h index e74969e8..29f51900 100644 --- a/includes/private/joystick/joystick_tm_fcs.h +++ b/includes/private/joystick/joystick_tm_fcs.h @@ -2,5 +2,4 @@ #define _JOYSTICK_TM_FCS_H_ extern joystick_if_t joystick_tm_fcs; - #endif /* _JOYSTICK_TM_FCS_H_ */ diff --git a/includes/private/keyboard/keyboard.h b/includes/private/keyboard/keyboard.h index c5c420db..6dbd620a 100644 --- a/includes/private/keyboard/keyboard.h +++ b/includes/private/keyboard/keyboard.h @@ -7,15 +7,9 @@ extern int keyboard_scan; extern uint8_t pcem_key[272]; -enum -{ - SCANCODE_SET_1, - SCANCODE_SET_2, - SCANCODE_SET_3 -}; +enum { SCANCODE_SET_1, SCANCODE_SET_2, SCANCODE_SET_3 }; void keyboard_set_scancode_set(int set); void keyboard_send_scancode(int code, int is_break); - #endif /* _KEYBOARD_H_ */ diff --git a/includes/private/keyboard/keyboard_amstrad.h b/includes/private/keyboard/keyboard_amstrad.h index 400ab2d1..3b3884af 100644 --- a/includes/private/keyboard/keyboard_amstrad.h +++ b/includes/private/keyboard/keyboard_amstrad.h @@ -4,5 +4,4 @@ void keyboard_amstrad_init(); void keyboard_amstrad_reset(); void keyboard_amstrad_poll(); - #endif /* _KEYBOARD_AMSTRAD_H_ */ diff --git a/includes/private/keyboard/keyboard_at.h b/includes/private/keyboard/keyboard_at.h index aa57069f..ee675303 100644 --- a/includes/private/keyboard/keyboard_at.h +++ b/includes/private/keyboard/keyboard_at.h @@ -11,5 +11,4 @@ extern uint8_t mouse_queue[16]; extern int mouse_queue_start, mouse_queue_end; extern int mouse_scan; - #endif /* _KEYBOARD_AT_H_ */ diff --git a/includes/private/keyboard/keyboard_olim24.h b/includes/private/keyboard/keyboard_olim24.h index 5d0ebbc9..0dda9d31 100644 --- a/includes/private/keyboard/keyboard_olim24.h +++ b/includes/private/keyboard/keyboard_olim24.h @@ -6,5 +6,4 @@ void keyboard_olim24_poll(); extern mouse_t mouse_olim24; - #endif /* _KEYBOARD_OLIM24_H_ */ diff --git a/includes/private/keyboard/keyboard_pcjr.h b/includes/private/keyboard/keyboard_pcjr.h index 058d0b7a..09c7aadd 100644 --- a/includes/private/keyboard/keyboard_pcjr.h +++ b/includes/private/keyboard/keyboard_pcjr.h @@ -4,5 +4,4 @@ void keyboard_pcjr_init(); void keyboard_pcjr_reset(); void keyboard_pcjr_poll(); - #endif /* _KEYBOARD_PCJR_H_ */ diff --git a/includes/private/keyboard/keyboard_xt.h b/includes/private/keyboard/keyboard_xt.h index 943bc80c..795a3841 100644 --- a/includes/private/keyboard/keyboard_xt.h +++ b/includes/private/keyboard/keyboard_xt.h @@ -5,5 +5,4 @@ void keyboard_tandy_init(); void keyboard_xt_reset(); void keyboard_xt_poll(); - #endif /* _KEYBOARD_XT_H_ */ diff --git a/includes/private/memory/mem.h b/includes/private/memory/mem.h index 6b93745a..f2ffb0dd 100644 --- a/includes/private/memory/mem.h +++ b/includes/private/memory/mem.h @@ -3,26 +3,25 @@ #include "x86.h" -typedef struct mem_mapping_t -{ +typedef struct mem_mapping_t { struct mem_mapping_t *prev, *next; int enable; - + uint32_t base; uint32_t size; - uint8_t (*read_b)(uint32_t addr, void *priv); + 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_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; @@ -31,33 +30,23 @@ typedef struct mem_mapping_t /*Only present on internal bus (RAM)*/ #define MEM_MAPPING_INTERNAL 2 /*Executing from ROM may involve additional wait states*/ -#define MEM_MAPPING_ROM 4 +#define MEM_MAPPING_ROM 4 -extern uint8_t *ram,*rom; +extern uint8_t *ram, *rom; extern uint8_t romext[32768]; -extern int readlnum,writelnum; +extern int readlnum, writelnum; extern int memspeed[11]; extern uint32_t biosmask; -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); -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)); +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); +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)); void mem_mapping_set_p(mem_mapping_t *mapping, void *p); void mem_mapping_set_addr(mem_mapping_t *mapping, uint32_t base, uint32_t size); void mem_mapping_set_exec(mem_mapping_t *mapping, uint8_t *exec); @@ -66,16 +55,16 @@ void mem_mapping_enable(mem_mapping_t *mapping); void mem_set_mem_state(uint32_t base, uint32_t size, int state); -#define MEM_READ_ANY 0x00 -#define MEM_READ_INTERNAL 0x10 -#define MEM_READ_EXTERNAL 0x20 -#define MEM_READ_MASK 0xf0 +#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_ANY 0x00 #define MEM_WRITE_INTERNAL 0x01 #define MEM_WRITE_EXTERNAL 0x02 #define MEM_WRITE_DISABLED 0x03 -#define MEM_WRITE_MASK 0x0f +#define MEM_WRITE_MASK 0x0f extern int mem_a20_alt; extern int mem_a20_key; @@ -88,7 +77,7 @@ void mem_writeb_phys(uint32_t addr, uint8_t val); void mem_writew_phys(uint32_t addr, uint16_t val); void mem_writel_phys(uint32_t addr, uint32_t val); -uint8_t mem_read_ram(uint32_t addr, void *priv); +uint8_t mem_read_ram(uint32_t addr, void *priv); uint16_t mem_read_ramw(uint32_t addr, void *priv); uint32_t mem_read_raml(uint32_t addr, void *priv); @@ -96,7 +85,7 @@ void mem_write_ram(uint32_t addr, uint8_t val, void *priv); void mem_write_ramw(uint32_t addr, uint16_t val, void *priv); void mem_write_raml(uint32_t addr, uint32_t val, void *priv); -uint8_t mem_read_bios(uint32_t addr, void *priv); +uint8_t mem_read_bios(uint32_t addr, void *priv); uint16_t mem_read_biosw(uint32_t addr, void *priv); uint32_t mem_read_biosl(uint32_t addr, void *priv); @@ -117,26 +106,25 @@ extern uint64_t *byte_code_present_mask; #define PAGE_BYTE_MASK_SHIFT 6 #define PAGE_BYTE_MASK_OFFSET_MASK 63 -#define PAGE_BYTE_MASK_MASK 63 +#define PAGE_BYTE_MASK_MASK 63 #define EVICT_NOT_IN_LIST ((uint32_t)-1) -typedef struct page_t -{ +typedef struct page_t { void (*write_b)(uint32_t addr, uint8_t val, struct page_t *p); void (*write_w)(uint32_t addr, uint16_t val, struct page_t *p); void (*write_l)(uint32_t addr, uint32_t val, struct page_t *p); - + uint8_t *mem; - + uint16_t block, block_2; - + /*Head of codeblock tree associated with this page*/ uint16_t head; - + uint64_t code_present_mask, dirty_mask; - + uint32_t evict_prev, evict_next; - + uint64_t *byte_dirty_mask; uint64_t *byte_code_present_mask; } page_t; @@ -146,50 +134,43 @@ extern page_t *pages; extern page_t **page_lookup; extern uint32_t purgable_page_list_head; -static inline int page_in_evict_list(page_t *p) -{ - return (p->evict_prev != EVICT_NOT_IN_LIST); -} +static inline int page_in_evict_list(page_t *p) { return (p->evict_prev != EVICT_NOT_IN_LIST); } void page_remove_from_evict_list(page_t *p); void page_add_to_evict_list(page_t *p); int mem_addr_is_ram(uint32_t addr); uint32_t mmutranslate_noabrt(uint32_t addr, int rw); -extern uint32_t get_phys_virt,get_phys_phys; -static inline uint32_t get_phys(uint32_t addr) -{ +extern uint32_t get_phys_virt, get_phys_phys; +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)) - { + + if (!(cr0 >> 31)) { get_phys_phys = (addr & rammask) & ~0xfff; return addr & rammask; } - + if (readlookup2[addr >> 12] != -1) get_phys_phys = ((uintptr_t)readlookup2[addr >> 12] + (addr & ~0xfff)) - (uintptr_t)ram; - else - { + else { get_phys_phys = (mmutranslatereal(addr, 0) & rammask) & ~0xfff; if (!cpu_state.abrt && mem_addr_is_ram(get_phys_phys)) addreadlookup(get_phys_virt, get_phys_phys); } - + return get_phys_phys | (addr & 0xfff); -// return mmutranslatereal(addr, 0) & rammask; + // return mmutranslatereal(addr, 0) & rammask; } -static inline uint32_t get_phys_noabrt(uint32_t addr) -{ +static inline uint32_t get_phys_noabrt(uint32_t addr) { uint32_t phys_addr; - + if (!(cr0 >> 31)) return addr & rammask; - + if (readlookup2[addr >> 12] != -1) return ((uintptr_t)readlookup2[addr >> 12] + addr) - (uintptr_t)ram; diff --git a/includes/private/memory/mem_bios.h b/includes/private/memory/mem_bios.h index 701dda94..4a4f3b8c 100644 --- a/includes/private/memory/mem_bios.h +++ b/includes/private/memory/mem_bios.h @@ -2,5 +2,4 @@ #define _MEM_BIOS_H_ int loadbios(); - #endif /* _MEM_BIOS_H_ */ diff --git a/includes/private/models/82091aa.h b/includes/private/models/82091aa.h index 498d7a8e..1f425716 100644 --- a/includes/private/models/82091aa.h +++ b/includes/private/models/82091aa.h @@ -3,5 +3,4 @@ void aip_82091aa_init(uint16_t base); - #endif /* _82091AA_H_ */ diff --git a/includes/private/models/acc2036.h b/includes/private/models/acc2036.h index fb11ca6a..d246db53 100644 --- a/includes/private/models/acc2036.h +++ b/includes/private/models/acc2036.h @@ -3,5 +3,4 @@ void acc2036_init(); - #endif /* _ACC2036_H_ */ diff --git a/includes/private/models/acc2168.h b/includes/private/models/acc2168.h index 055c7991..99e5ee3a 100644 --- a/includes/private/models/acc2168.h +++ b/includes/private/models/acc2168.h @@ -3,5 +3,4 @@ void acc2168_init(); - #endif /* _ACC2168_H_ */ diff --git a/includes/private/models/acc3221.h b/includes/private/models/acc3221.h index 03c356c2..d9fea867 100644 --- a/includes/private/models/acc3221.h +++ b/includes/private/models/acc3221.h @@ -3,5 +3,4 @@ void acc3221_init(); - #endif /* _ACC3221_H_ */ diff --git a/includes/private/models/acer386sx.h b/includes/private/models/acer386sx.h index 5fe59056..777c492c 100644 --- a/includes/private/models/acer386sx.h +++ b/includes/private/models/acer386sx.h @@ -4,5 +4,4 @@ void acer386sx_init(); void acer386sx_set_oti067(void *oti067); - #endif /* _ACER386SX_H_ */ diff --git a/includes/private/models/ali1429.h b/includes/private/models/ali1429.h index 3c14e1c8..0a3a566c 100644 --- a/includes/private/models/ali1429.h +++ b/includes/private/models/ali1429.h @@ -4,5 +4,4 @@ void ali1429_init(); void ali1429_reset(); - #endif /* _ALI1429_H_ */ diff --git a/includes/private/models/amstrad.h b/includes/private/models/amstrad.h index 0582d131..f50576fd 100644 --- a/includes/private/models/amstrad.h +++ b/includes/private/models/amstrad.h @@ -12,12 +12,6 @@ extern device_t ams1512_device; extern device_t ams2086_device; extern device_t ams3086_device; -enum -{ - AMSTRAD_NOLATCH, - AMSTRAD_SW9, - AMSTRAD_SW10 -}; - +enum { AMSTRAD_NOLATCH, AMSTRAD_SW9, AMSTRAD_SW10 }; #endif /* _AMSTRAD_H_ */ diff --git a/includes/private/models/cbm_io.h b/includes/private/models/cbm_io.h index 547dde6d..1eff5bda 100644 --- a/includes/private/models/cbm_io.h +++ b/includes/private/models/cbm_io.h @@ -3,5 +3,4 @@ void cbm_io_init(); - #endif /* _CBM_IO_H_ */ diff --git a/includes/private/models/cmd640.h b/includes/private/models/cmd640.h index 200f0742..6911ae51 100644 --- a/includes/private/models/cmd640.h +++ b/includes/private/models/cmd640.h @@ -3,5 +3,4 @@ void cmd640b_init(int card); - #endif /* _CMD640_H_ */ diff --git a/includes/private/models/compaq.h b/includes/private/models/compaq.h index 7e1d4380..e3b250fb 100644 --- a/includes/private/models/compaq.h +++ b/includes/private/models/compaq.h @@ -2,5 +2,4 @@ #define _COMPAQ_H_ void compaq_init(); - #endif /* _COMPAQ_H_ */ diff --git a/includes/private/models/cs8230.h b/includes/private/models/cs8230.h index 42fb2fa8..8d60a352 100644 --- a/includes/private/models/cs8230.h +++ b/includes/private/models/cs8230.h @@ -2,5 +2,4 @@ #define _CS8230_H_ void cs8230_init(void); - #endif /* _CS8230_H_ */ diff --git a/includes/private/models/dells200.h b/includes/private/models/dells200.h index 1bb5f780..3ff8de6f 100644 --- a/includes/private/models/dells200.h +++ b/includes/private/models/dells200.h @@ -2,5 +2,4 @@ #define _DELLS200_H_ void dells200_chipset_init(); - #endif /* _DELLS200_H_ */ diff --git a/includes/private/models/dma.h b/includes/private/models/dma.h index 5e9a05a5..3437049e 100644 --- a/includes/private/models/dma.h +++ b/includes/private/models/dma.h @@ -18,5 +18,4 @@ void writedma2(uint8_t temp); int dma_channel_read(int channel); int dma_channel_write(int channel, uint16_t val); - #endif /* _DMA_H_ */ diff --git a/includes/private/models/headland.h b/includes/private/models/headland.h index eb9879ad..b7b7ad24 100644 --- a/includes/private/models/headland.h +++ b/includes/private/models/headland.h @@ -2,5 +2,4 @@ #define _HEADLAND_H_ void headland_init(); - #endif /* _HEADLAND_H_ */ diff --git a/includes/private/models/i430fx.h b/includes/private/models/i430fx.h index 1634e75e..d8047317 100644 --- a/includes/private/models/i430fx.h +++ b/includes/private/models/i430fx.h @@ -3,5 +3,4 @@ void i430fx_init(); void i430fx_reset(); - #endif /* _I430FX_H_ */ diff --git a/includes/private/models/i430hx.h b/includes/private/models/i430hx.h index 0471c9a1..ba069664 100644 --- a/includes/private/models/i430hx.h +++ b/includes/private/models/i430hx.h @@ -3,5 +3,4 @@ void i430hx_init(); void i430hx_reset(); - #endif /* _I430HX_H_ */ diff --git a/includes/private/models/i430lx.h b/includes/private/models/i430lx.h index 4966160e..4a2584ff 100644 --- a/includes/private/models/i430lx.h +++ b/includes/private/models/i430lx.h @@ -2,5 +2,4 @@ #define _I430LX_H_ void i430lx_init(); - #endif /* _I430LX_H_ */ diff --git a/includes/private/models/i430vx.h b/includes/private/models/i430vx.h index eb58b7f2..a9113ecd 100644 --- a/includes/private/models/i430vx.h +++ b/includes/private/models/i430vx.h @@ -3,5 +3,4 @@ void i430vx_init(); void i430vx_reset(); - #endif /* _I430VX_H_ */ diff --git a/includes/private/models/i440bx.h b/includes/private/models/i440bx.h index d9672f5d..b1fdcb35 100644 --- a/includes/private/models/i440bx.h +++ b/includes/private/models/i440bx.h @@ -3,5 +3,4 @@ void i440bx_init(); void i440bx_reset(); - #endif /* _I440BX_H_ */ diff --git a/includes/private/models/i440fx.h b/includes/private/models/i440fx.h index 0e71f68b..d17df9ba 100644 --- a/includes/private/models/i440fx.h +++ b/includes/private/models/i440fx.h @@ -3,5 +3,4 @@ void i440fx_init(); void i440fx_reset(); - #endif /* _I440FX_H_ */ diff --git a/includes/private/models/intel.h b/includes/private/models/intel.h index 11899776..92119248 100644 --- a/includes/private/models/intel.h +++ b/includes/private/models/intel.h @@ -4,5 +4,4 @@ void intel_batman_init(); void intel_endeavor_init(); void intel_zappa_init(); - #endif /* _INTEL_H_ */ diff --git a/includes/private/models/jim.h b/includes/private/models/jim.h index d3f42523..80d06d26 100644 --- a/includes/private/models/jim.h +++ b/includes/private/models/jim.h @@ -2,5 +2,4 @@ #define _JIM_H_ void jim_init(); - #endif /* _JIM_H_ */ diff --git a/includes/private/models/laserxt.h b/includes/private/models/laserxt.h index e3fa5a88..8b7f44e1 100644 --- a/includes/private/models/laserxt.h +++ b/includes/private/models/laserxt.h @@ -2,5 +2,4 @@ #define _LASERXT_H_ void laserxt_init(); - #endif /* _LASERXT_H_ */ diff --git a/includes/private/models/model.h b/includes/private/models/model.h index f9bc078e..080d287b 100644 --- a/includes/private/models/model.h +++ b/includes/private/models/model.h @@ -3,23 +3,23 @@ #include -#define MODEL_AT 1 -#define MODEL_PS2 2 +#define MODEL_AT 1 +#define MODEL_PS2 2 #define MODEL_AMSTRAD 4 -#define MODEL_OLIM24 8 +#define MODEL_OLIM24 8 #define MODEL_HAS_IDE 0x10 -#define MODEL_MCA 0x20 -#define MODEL_PCI 0x40 +#define MODEL_MCA 0x20 +#define MODEL_PCI 0x40 /*Machine has no integrated graphics*/ -#define MODEL_GFX_NONE 0x000 +#define MODEL_GFX_NONE 0x000 /*Machine has integrated graphics that can not be disabled*/ -#define MODEL_GFX_FIXED 0x100 +#define MODEL_GFX_FIXED 0x100 /*Machine has integrated graphics that can be disabled by jumpers or switches*/ #define MODEL_GFX_DISABLE_HW 0x200 /*Machine has integrated graphics that can be disabled through software*/ #define MODEL_GFX_DISABLE_SW 0x300 -#define MODEL_GFX_MASK 0x300 +#define MODEL_GFX_MASK 0x300 extern MODEL *models[ROM_MAX]; @@ -37,5 +37,4 @@ void model_init_builtin(); int model_has_fixed_gfx(int model); int model_has_optional_gfx(int model); - #endif /* _MODEL_H_ */ diff --git a/includes/private/models/mvp3.h b/includes/private/models/mvp3.h index 8ab7484e..8adfef7e 100644 --- a/includes/private/models/mvp3.h +++ b/includes/private/models/mvp3.h @@ -2,5 +2,4 @@ #define _MVP3_H_ void mvp3_init(); - #endif /* _MVP3_H_ */ diff --git a/includes/private/models/neat.h b/includes/private/models/neat.h index cd1a67b4..03104e58 100644 --- a/includes/private/models/neat.h +++ b/includes/private/models/neat.h @@ -2,5 +2,4 @@ #define _NEAT_H_ void neat_init(); - #endif /* _NEAT_H_ */ diff --git a/includes/private/models/nmi.h b/includes/private/models/nmi.h index 7de47da0..97838c06 100644 --- a/includes/private/models/nmi.h +++ b/includes/private/models/nmi.h @@ -4,7 +4,4 @@ void nmi_init(); void nmi_write(uint16_t port, uint8_t val, void *p); extern int nmi_mask; - - - #endif /* _NMI_H_ */ diff --git a/includes/private/models/olivetti_m24.h b/includes/private/models/olivetti_m24.h index f6e15f83..47bf1764 100644 --- a/includes/private/models/olivetti_m24.h +++ b/includes/private/models/olivetti_m24.h @@ -2,5 +2,4 @@ #define _OLIVETTI_M24_H_ void olivetti_m24_init(); - #endif /* _OLIVETTI_M24_H_ */ diff --git a/includes/private/models/opti495.h b/includes/private/models/opti495.h index 36d83a5b..364cee84 100644 --- a/includes/private/models/opti495.h +++ b/includes/private/models/opti495.h @@ -2,5 +2,4 @@ #define _OPTI495_H_ void opti495_init(); - #endif /* _OPTI495_H_ */ diff --git a/includes/private/models/pc87306.h b/includes/private/models/pc87306.h index 67fc7a01..836ccff6 100644 --- a/includes/private/models/pc87306.h +++ b/includes/private/models/pc87306.h @@ -2,5 +2,4 @@ #define _PC87306_H_ void pc87306_init(uint16_t addr); - #endif /* _PC87306_H_ */ diff --git a/includes/private/models/pc87307.h b/includes/private/models/pc87307.h index f5852454..e3bd472e 100644 --- a/includes/private/models/pc87307.h +++ b/includes/private/models/pc87307.h @@ -2,5 +2,4 @@ #define _PC87307_H_ void pc87307_init(uint16_t addr); - #endif /* _PC87307_H_ */ diff --git a/includes/private/models/pic.h b/includes/private/models/pic.h index 8a990ed3..e22314a2 100644 --- a/includes/private/models/pic.h +++ b/includes/private/models/pic.h @@ -12,5 +12,4 @@ uint8_t picinterrupt(); void picclear(int num); void dumppic(); - #endif /* _PIC_H_ */ diff --git a/includes/private/models/piix.h b/includes/private/models/piix.h index 90656dfd..e1834658 100644 --- a/includes/private/models/piix.h +++ b/includes/private/models/piix.h @@ -3,16 +3,14 @@ void piix_init(int card, int pci_a, int pci_b, int pci_c, int pci_d, void (*nb_reset)()); void piix4_init(int card, int pci_a, int pci_b, int pci_c, int pci_d, void (*nb_reset)()); -typedef struct piix_t -{ +typedef struct piix_t { int type; /*PIIX4*/ uint8_t card_pm[256]; uint16_t pmba; - struct - { + struct { uint8_t apmc, apms; uint64_t timer_offset; @@ -35,13 +33,11 @@ typedef struct piix_t } pm; uint16_t smbba; - struct - { + struct { uint8_t host_ctrl; } smbus; uint8_t port_92; } piix_t; - #endif /* _PIIX_H_ */ diff --git a/includes/private/models/piix_pm.h b/includes/private/models/piix_pm.h index 51c7c706..b29ef61b 100644 --- a/includes/private/models/piix_pm.h +++ b/includes/private/models/piix_pm.h @@ -4,5 +4,4 @@ void piix_pm_init(piix_t *piix); void piix_pm_pci_write(int addr, uint8_t val, void *p); uint8_t piix_pm_pci_read(int addr, void *p); - #endif /* _PIIX_PM_H_ */ diff --git a/includes/private/models/pit.h b/includes/private/models/pit.h index 642f32a6..eceb10c3 100644 --- a/includes/private/models/pit.h +++ b/includes/private/models/pit.h @@ -9,7 +9,6 @@ void pit_set_using_timer(PIT *pit, int t, int using_timer); void pit_set_out_func(PIT *pit, int t, void (*func)(int new_out, int old_out)); void pit_clock(PIT *pit, int t); - void pit_null_timer(int new_out, int old_out); void pit_irq0_timer(int new_out, int old_out); void pit_irq0_timer_pcjr(int new_out, int old_out); @@ -17,5 +16,4 @@ void pit_refresh_timer_xt(int new_out, int old_out); void pit_refresh_timer_at(int new_out, int old_out); void pit_speaker_timer(int new_out, int old_out); - #endif /* _PIT_H_ */ diff --git a/includes/private/models/ps1.h b/includes/private/models/ps1.h index c19c146b..54ae9f7a 100644 --- a/includes/private/models/ps1.h +++ b/includes/private/models/ps1.h @@ -4,5 +4,4 @@ void ps1mb_init(); void ps1mb_m2121_init(); void ps1mb_m2133_init(void); - #endif /* _PS1_H_ */ diff --git a/includes/private/models/ps2.h b/includes/private/models/ps2.h index 6e2b8104..5195331e 100644 --- a/includes/private/models/ps2.h +++ b/includes/private/models/ps2.h @@ -2,5 +2,4 @@ #define _PS2_H_ void ps2board_init(); - #endif /* _PS2_H_ */ diff --git a/includes/private/models/ps2_mca.h b/includes/private/models/ps2_mca.h index 4b785163..b9ce7c32 100644 --- a/includes/private/models/ps2_mca.h +++ b/includes/private/models/ps2_mca.h @@ -7,5 +7,4 @@ void ps2_mca_board_model_80_type2_init(); void ps2_cache_clean(); - #endif /* _PS2_MCA_H_ */ diff --git a/includes/private/models/scat.h b/includes/private/models/scat.h index 08310e27..c49e92ca 100644 --- a/includes/private/models/scat.h +++ b/includes/private/models/scat.h @@ -1,28 +1,27 @@ #ifndef _SCAT_H_ #define _SCAT_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 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_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 +#define SCATSX_CAS_TIMING_FOR_DMA 0x64 -typedef struct scat_t -{ +typedef struct scat_t { uint8_t regs_2x8; uint8_t regs_2x9; } scat_t; @@ -30,5 +29,4 @@ typedef struct scat_t void scat_init(); void scatsx_init(); - #endif /* _SCAT_H_ */ diff --git a/includes/private/models/serial.h b/includes/private/models/serial.h index 03b32188..0f362e2d 100644 --- a/includes/private/models/serial.h +++ b/includes/private/models/serial.h @@ -14,15 +14,14 @@ void serial_reset(); struct SERIAL; -typedef struct -{ - uint8_t lsr,thr,mctrl,rcr,iir,ier,lcr,msr; - uint8_t dlab1,dlab2; +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; uint16_t addr; @@ -31,7 +30,7 @@ typedef struct uint8_t fifo[256]; int fifo_read, fifo_write; int has_fifo; - + pc_timer_t receive_timer; } SERIAL; @@ -39,5 +38,4 @@ void serial_write_fifo(SERIAL *serial, uint8_t dat); extern SERIAL serial1, serial2; - #endif /* _SERIAL_H_ */ diff --git a/includes/private/models/sio.h b/includes/private/models/sio.h index d999646a..31d3f5ce 100644 --- a/includes/private/models/sio.h +++ b/includes/private/models/sio.h @@ -2,5 +2,4 @@ #define _SIO_H_ void sio_init(int card, int pci_a, int pci_b, int pci_c, int pci_d); - #endif /* _SIO_H_ */ diff --git a/includes/private/models/sl82c460.h b/includes/private/models/sl82c460.h index 88747412..0fb02d55 100644 --- a/includes/private/models/sl82c460.h +++ b/includes/private/models/sl82c460.h @@ -2,5 +2,4 @@ #define _SL82C460_H_ void sl82c460_init(); - #endif /* _SL82C460_H_ */ diff --git a/includes/private/models/superxt.h b/includes/private/models/superxt.h index 141bdf8e..182dd706 100644 --- a/includes/private/models/superxt.h +++ b/includes/private/models/superxt.h @@ -2,5 +2,4 @@ #define _SUPERXT_H_ void superxt_init(); - #endif /* _SUPERXT_H_ */ diff --git a/includes/private/models/t1000.h b/includes/private/models/t1000.h index 4ac1f03c..2d047880 100644 --- a/includes/private/models/t1000.h +++ b/includes/private/models/t1000.h @@ -10,5 +10,4 @@ void t1000_configsys_savenvr(); void t1000_emsboard_savenvr(); void t1200_state_savenvr(); - #endif /* _T1000_H_ */ diff --git a/includes/private/models/t3100e.h b/includes/private/models/t3100e.h index ef0b1f8b..5d2fdfad 100644 --- a/includes/private/models/t3100e.h +++ b/includes/private/models/t3100e.h @@ -8,5 +8,4 @@ void t3100e_turbo_set(uint8_t value); uint8_t t3100e_mono_get(); void t3100e_mono_set(uint8_t value); - #endif /* _T3100E_H_ */ diff --git a/includes/private/models/um8669f.h b/includes/private/models/um8669f.h index 6524592f..6f380aa8 100644 --- a/includes/private/models/um8669f.h +++ b/includes/private/models/um8669f.h @@ -2,5 +2,4 @@ #define _UM8669F_H_ extern void um8669f_init(); - #endif /* _UM8669F_H_ */ diff --git a/includes/private/models/um8881f.h b/includes/private/models/um8881f.h index d6ab7cf5..f74a144a 100644 --- a/includes/private/models/um8881f.h +++ b/includes/private/models/um8881f.h @@ -2,5 +2,4 @@ #define _UM8881F_H_ void um8881f_init(); - #endif /* _UM8881F_H_ */ diff --git a/includes/private/models/vl82c480.h b/includes/private/models/vl82c480.h index 22c6a963..e07e016e 100644 --- a/includes/private/models/vl82c480.h +++ b/includes/private/models/vl82c480.h @@ -2,5 +2,4 @@ #define _VL82C480_H_ void vl82c480_init(void); - #endif /* _VL82C480_H_ */ diff --git a/includes/private/models/vt82c586b.h b/includes/private/models/vt82c586b.h index 8e3f2269..0a41c923 100644 --- a/includes/private/models/vt82c586b.h +++ b/includes/private/models/vt82c586b.h @@ -2,5 +2,4 @@ #define _VT82C586B_H_ void vt82c586b_init(int card, int pci_a, int pci_b, int pci_c, int pci_d); - #endif /* _VT82C586B_H_ */ diff --git a/includes/private/models/w83877tf.h b/includes/private/models/w83877tf.h index cfbe48a5..4de1129d 100644 --- a/includes/private/models/w83877tf.h +++ b/includes/private/models/w83877tf.h @@ -3,5 +3,4 @@ void w83877f_init(uint16_t base, uint8_t key); void w83877tf_init(uint16_t base, uint8_t key); - #endif /* _W83877TF_H_ */ diff --git a/includes/private/models/w83977tf.h b/includes/private/models/w83977tf.h index 13c2c1e6..51aa33a8 100644 --- a/includes/private/models/w83977tf.h +++ b/includes/private/models/w83977tf.h @@ -2,5 +2,4 @@ #define _W83977TF_H_ void w83977tf_init(uint16_t base, uint8_t key); - #endif /* _W83977TF_H_ */ diff --git a/includes/private/models/wd76c10.h b/includes/private/models/wd76c10.h index 714bebe6..cc5033a8 100644 --- a/includes/private/models/wd76c10.h +++ b/includes/private/models/wd76c10.h @@ -2,5 +2,4 @@ #define _WD76C10_H_ void wd76c10_init(); - #endif /* _WD76C10_H_ */ diff --git a/includes/private/models/xi8088.h b/includes/private/models/xi8088.h index 883d572f..f95b2a72 100644 --- a/includes/private/models/xi8088.h +++ b/includes/private/models/xi8088.h @@ -8,5 +8,4 @@ uint8_t xi8088_turbo_get(); void xi8088_turbo_set(uint8_t value); int xi8088_bios_128kb(); - #endif /* _XI8088_H_ */ diff --git a/includes/private/models/zenith.h b/includes/private/models/zenith.h index a1cf10a0..61b17707 100644 --- a/includes/private/models/zenith.h +++ b/includes/private/models/zenith.h @@ -2,5 +2,4 @@ #define _ZENITH_H_ device_t zenith_scratchpad_device; - #endif /* _ZENITH_H_ */ diff --git a/includes/private/mouse/mouse.h b/includes/private/mouse/mouse.h index b97a4588..c4523a0b 100644 --- a/includes/private/mouse/mouse.h +++ b/includes/private/mouse/mouse.h @@ -8,21 +8,21 @@ void mouse_poll(int x, int y, int z, int b); char *mouse_get_name(int mouse); int mouse_get_type(int mouse); -#define MOUSE_TYPE_SERIAL 0 -#define MOUSE_TYPE_PS2 1 +#define MOUSE_TYPE_SERIAL 0 +#define MOUSE_TYPE_PS2 1 #define MOUSE_TYPE_AMSTRAD 2 -#define MOUSE_TYPE_OLIM24 3 +#define MOUSE_TYPE_OLIM24 3 #define MOUSE_TYPE_IF_MASK 3 #define MOUSE_TYPE_3BUTTON (1 << 31) typedef struct { - char name[80]; - void *(*init)(); - void (*close)(void *p); - void (*poll)(int x, int y, int z, int b, void *p); - int type; + char name[80]; + void *(*init)(); + void (*close)(void *p); + void (*poll)(int x, int y, int z, int b, void *p); + int type; } mouse_t; extern int mouse_type; diff --git a/includes/private/networking/ne2000.h b/includes/private/networking/ne2000.h index 509d9518..cd0307c7 100644 --- a/includes/private/networking/ne2000.h +++ b/includes/private/networking/ne2000.h @@ -3,5 +3,4 @@ extern device_t ne2000_device; extern device_t rtl8029as_device; - #endif /* _NE2000_H_ */ diff --git a/includes/private/networking/nethandler.h b/includes/private/networking/nethandler.h index 5eb4aa2e..1673c432 100644 --- a/includes/private/networking/nethandler.h +++ b/includes/private/networking/nethandler.h @@ -1,7 +1,7 @@ #ifndef _NETHANDLER_H_ #define _NETHANDLER_H_ -//void vlan_handler(int (*can_receive)(void *p), void (*receive)(void *p, const uint8_t *buf, int size), void *p); +// void vlan_handler(int (*can_receive)(void *p), void (*receive)(void *p, const uint8_t *buf, int size), void *p); void vlan_handler(void (*poller)(void *p), void *p); extern int network_card_current; @@ -20,11 +20,7 @@ void closepcap(); void vlan_reset(); -enum -{ - NET_SLIRP = 0, - NET_PCAP = 1 -}; +enum { NET_SLIRP = 0, NET_PCAP = 1 }; void network_card_init_builtin(); diff --git a/includes/private/networking/slirp/bootp.h b/includes/private/networking/slirp/bootp.h index b2ee26e9..d0ce1387 100644 --- a/includes/private/networking/slirp/bootp.h +++ b/includes/private/networking/slirp/bootp.h @@ -1,117 +1,117 @@ /* bootp/dhcp defines */ -#define BOOTP_SERVER 67 -#define BOOTP_CLIENT 68 +#define BOOTP_SERVER 67 +#define BOOTP_CLIENT 68 -#define BOOTP_REQUEST 1 -#define BOOTP_REPLY 2 +#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_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 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 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 DHCPDISCOVER 1 +#define DHCPOFFER 2 +#define DHCPREQUEST 3 +#define DHCPACK 5 -#define RFC1533_VENDOR_MAJOR 0 -#define RFC1533_VENDOR_MINOR 0 +#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_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_MOTD 184 #define RFC1533_VENDOR_NUMOFMOTD 8 -#define RFC1533_VENDOR_IMG 192 -#define RFC1533_VENDOR_NUMOFIMG 16 +#define RFC1533_VENDOR_IMG 192 +#define RFC1533_VENDOR_NUMOFIMG 16 -#define RFC1533_END 255 -#define BOOTP_VENDOR_LEN 64 -#define DHCP_OPT_LEN 312 +#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]; + 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 diff --git a/includes/private/networking/slirp/ctl.h b/includes/private/networking/slirp/ctl.h index 4a8576dc..b002201f 100644 --- a/includes/private/networking/slirp/ctl.h +++ b/includes/private/networking/slirp/ctl.h @@ -1,7 +1,7 @@ -#define CTL_CMD 0 -#define CTL_EXEC 1 -#define CTL_ALIAS 2 -#define CTL_DNS 3 +#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" +#define CTL_SPECIAL "10.0.2.0" +#define CTL_LOCAL "10.0.2.15" diff --git a/includes/private/networking/slirp/debug.h b/includes/private/networking/slirp/debug.h index 9a8c5e8c..68846eee 100644 --- a/includes/private/networking/slirp/debug.h +++ b/includes/private/networking/slirp/debug.h @@ -1,12 +1,12 @@ /* * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the + * + * Please read the file COPYRIGHT for the * terms and conditions of the copyright. */ -#define PRN_STDERR 1 -#define PRN_SPRINTF 2 +#define PRN_STDERR 1 +#define PRN_SPRINTF 2 extern FILE *dfd; extern FILE *lfd; @@ -16,15 +16,36 @@ 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 +#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); } - +#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 @@ -37,7 +58,7 @@ extern int slirp_debug; #endif void debug_init _P((char *, int)); -//void ttystats _P((struct ttys *)); +// void ttystats _P((struct ttys *)); void allttystats _P((void)); void ipstats _P((void)); void vjstats _P((void)); @@ -47,4 +68,3 @@ void icmpstats _P((void)); void mbufstats _P((void)); void sockstats _P((void)); void slirp_exit _P((int)); - diff --git a/includes/private/networking/slirp/icmp_var.h b/includes/private/networking/slirp/icmp_var.h index 9af222fb..bfb7de39 100644 --- a/includes/private/networking/slirp/icmp_var.h +++ b/includes/private/networking/slirp/icmp_var.h @@ -38,27 +38,24 @@ * 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 */ + /* 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_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 }, \ -} +#define ICMPCTL_NAMES \ + { {0, 0}, {"maskrepl", CTLTYPE_INT}, {"stats", CTLTYPE_STRUCT}, } extern struct icmpstat icmpstat; diff --git a/includes/private/networking/slirp/if.h b/includes/private/networking/slirp/if.h index 85a5a96d..ee45d038 100644 --- a/includes/private/networking/slirp/if.h +++ b/includes/private/networking/slirp/if.h @@ -1,50 +1,50 @@ /* * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the + * + * 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 */ +#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 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; +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 */ + 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/includes/private/networking/slirp/ip.h b/includes/private/networking/slirp/ip.h index 9af18745..14109fc6 100644 --- a/includes/private/networking/slirp/ip.h +++ b/includes/private/networking/slirp/ip.h @@ -34,40 +34,40 @@ #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 +#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 +#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 */ +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 +#define IPVERSION 4 #if defined(_MSC_VER) #pragma pack(push, 1) @@ -82,67 +82,67 @@ typedef u_int32_t n_long; /* long as received from the net */ struct ip { #ifdef WORDS_BIGENDIAN - u_char ip_v:4, /* version */ - ip_hl:4; /* header length */ + u_char ip_v : 4, /* version */ + ip_hl : 4; /* header length */ #else - u_char ip_hl:4, /* header length */ - ip_v:4; /* version */ + 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 */ + 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 +#pragma pack(PACK_END) // WAS 0 #endif -#define IP_MAXPACKET 65535 /* maximum packet size */ +#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 +#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_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_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_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 */ +#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 */ +#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. @@ -151,24 +151,24 @@ struct ip { #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 */ +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 */ + 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 */ + 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; + 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 @@ -176,40 +176,38 @@ struct ip_timestamp { #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 */ +#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 +#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 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 */ +#define IP_MSS 576 /* default maximum segment size */ struct mbuf_ptr { - union - { - struct mbuf *mptr; - uint64_t dummy; - } m; + union { + struct mbuf *mptr; + uint64_t dummy; + } m; }; - struct qlink { - void *next, *prev; + void *next, *prev; }; /* @@ -220,12 +218,12 @@ struct qlink { #endif struct ipovly { - struct mbuf_ptr ih_mbuf; /* backpointer to mbuf */ - 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 */ + struct mbuf_ptr ih_mbuf; /* backpointer to mbuf */ + 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 @@ -244,12 +242,12 @@ struct ipovly { * size 28 bytes */ struct ipq { - struct qlink frag_link; /* to ip headers of fragments */ - struct qlink ip_link; /* to other reass headers */ - 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 */ - struct in_addr ipq_src,ipq_dst; + struct qlink frag_link; /* to ip headers of fragments */ + struct qlink ip_link; /* to other reass headers */ + 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 */ + struct in_addr ipq_src, ipq_dst; }; /* @@ -257,16 +255,16 @@ struct ipq { * * Note: ipf_link must be at same offset as frag_link above */ -struct ipasfrag { - struct qlink ipf_link; - struct ip ipf_ip; +struct ipasfrag { + struct qlink ipf_link; + struct ip ipf_ip; }; -#define ipf_off ipf_ip.ip_off -#define ipf_tos ipf_ip.ip_tos -#define ipf_len ipf_ip.ip_len -#define ipf_next ipf_link.next -#define ipf_prev ipf_link.prev +#define ipf_off ipf_ip.ip_off +#define ipf_tos ipf_ip.ip_tos +#define ipf_len ipf_ip.ip_len +#define ipf_next ipf_link.next +#define ipf_prev ipf_link.prev /* * Structure stored in mbuf in inpcb.ip_options @@ -274,11 +272,11 @@ struct ipasfrag { * The actual length of the options (including ipopt_dst) * is in m_len. */ -#define MAX_IPOPTLEN 40 +#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 */ + struct in_addr ipopt_dst; /* first-hop dst if source routed */ + int8_t ipopt_list[MAX_IPOPTLEN]; /* options proper */ }; /* @@ -286,37 +284,37 @@ struct ipoption { * 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 */ +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 */ +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/includes/private/networking/slirp/ip_icmp.h b/includes/private/networking/slirp/ip_icmp.h index 20fcda1b..c1addb50 100644 --- a/includes/private/networking/slirp/ip_icmp.h +++ b/includes/private/networking/slirp/ip_icmp.h @@ -48,50 +48,50 @@ typedef u_int32_t n_time; #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; + 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 + /* 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 @@ -106,60 +106,58 @@ struct icmp { * 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 */ +#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_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_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) +#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 *)); diff --git a/includes/private/networking/slirp/libslirp.h b/includes/private/networking/slirp/libslirp.h index 8a1aa31e..f82169af 100644 --- a/includes/private/networking/slirp/libslirp.h +++ b/includes/private/networking/slirp/libslirp.h @@ -15,8 +15,7 @@ extern "C" { int slirp_init(void); -int slirp_select_fill(int *pnfds, - fd_set *readfds, fd_set *writefds, fd_set *xfds); +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); @@ -26,10 +25,8 @@ void slirp_input(const uint8 *pkt, int pkt_len); 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); +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]; diff --git a/includes/private/networking/slirp/main.h b/includes/private/networking/slirp/main.h index 181b6ae8..97062f12 100644 --- a/includes/private/networking/slirp/main.h +++ b/includes/private/networking/slirp/main.h @@ -1,7 +1,7 @@ /* * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the + * + * Please read the file COPYRIGHT for the * terms and conditions of the copyright. */ @@ -26,7 +26,7 @@ extern int ctty_closed; * 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) +#define TIME_DIFF(x, y) (x) - (y) < 0 ? ~0 - (y) + (x) : (x) - (y) extern char *slirp_tty; extern char *exec_shell; diff --git a/includes/private/networking/slirp/mbuf.h b/includes/private/networking/slirp/mbuf.h index 13ef8152..1a1b9179 100644 --- a/includes/private/networking/slirp/mbuf.h +++ b/includes/private/networking/slirp/mbuf.h @@ -35,15 +35,14 @@ #define m_freem m_free - -#define MINCSIZE 4096 /* Amount to increase mbuf if too small */ +#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 mtod(m, t) ((t)(m)->m_data) /* #define dtom(x) ((struct SLIRPmbuf *)((int)(x) & ~(M_SIZE-1))) */ /* XXX About mbufs for slirp: @@ -57,26 +56,23 @@ /* 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 */ + 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 */ - size_t mh_len; /* Amount of data in this mbuf */ + size_t mh_size; /* Size of data */ + struct SLIRPsocket *mh_so; + + SLIRPcaddr_t mh_data; /* Location of data */ + size_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)) +#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 @@ -85,24 +81,24 @@ struct m_hdr { #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; + 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 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 @@ -110,34 +106,34 @@ struct SLIRPmbuf { #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 */ +#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 */ - + int mbs_alloced; /* Number of mbufs allocated */ }; -extern struct mbstat mbstat; +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)); +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 *)); +struct SLIRPmbuf *dtom _P((void *)); #endif diff --git a/includes/private/networking/slirp/misc.h b/includes/private/networking/slirp/misc.h index c509deb9..c8f69bd8 100644 --- a/includes/private/networking/slirp/misc.h +++ b/includes/private/networking/slirp/misc.h @@ -1,7 +1,7 @@ /* * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the + * + * Please read the file COPYRIGHT for the * terms and conditions of the copyright. */ @@ -9,17 +9,17 @@ #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; + 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 int(*lprint_print) _P((void *, const char *, va_list)); extern char *lprint_ptr, *lprint_ptr2, **lprint_arg; extern struct sbuf *lprint_sb; @@ -41,26 +41,26 @@ void do_wait _P((int)); #define EMU_IDENT 0x7 #define EMU_RSH 0x8 -#define EMU_NOCONNECT 0x10 /* Don't connect */ +#define EMU_NOCONNECT 0x10 /* Don't connect */ /* UDP emulations */ -#define EMU_TALK 0x1 -#define EMU_NTALK 0x2 -#define EMU_CUSEEME 0x3 +#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; + 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; + 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; @@ -70,8 +70,8 @@ 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 *)); +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)); diff --git a/includes/private/networking/slirp/queue.h b/includes/private/networking/slirp/queue.h index 786950ab..c6dbf4bb 100644 --- a/includes/private/networking/slirp/queue.h +++ b/includes/private/networking/slirp/queue.h @@ -1,4 +1,4 @@ -/* +/* * File: queue.h * Author: Robert I. Pitts * Last Modified: March 9, 2000 @@ -15,8 +15,8 @@ * 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 +#define ERROR_QUEUE 2 +#define ERROR_MEMORY 3 /* * Type: queueElementT @@ -28,7 +28,7 @@ typedef unsigned char *queueElementT; */ -struct queuepacket{ +struct queuepacket { int len; unsigned char data[2000]; }; @@ -48,7 +48,7 @@ typedef struct queuepacket *queueElementT; * of struct. */ -typedef struct queueCDT *queueADT; +typedef struct queueCDT *queueADT; /* * Function: QueueCreate @@ -84,7 +84,6 @@ void QueueDestroy(queueADT queue); void QueueEnter(queueADT queue, queueElementT element); queueElementT QueueDelete(queueADT queue); - /* * Functions: QueueIsEmpty, QueueIsFull * Usage: if (QueueIsEmpty(queue)) ... @@ -98,4 +97,4 @@ int QueueIsFull(queueADT queue); int QueuePeek(queueADT queue); -#endif /* not defined _QUEUE_H */ +#endif /* not defined _QUEUE_H */ diff --git a/includes/private/networking/slirp/sbuf.h b/includes/private/networking/slirp/sbuf.h index aa4724df..52fd5901 100644 --- a/includes/private/networking/slirp/sbuf.h +++ b/includes/private/networking/slirp/sbuf.h @@ -1,24 +1,24 @@ /* * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the + * + * 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 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 */ + 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 *)); diff --git a/includes/private/networking/slirp/slirp.h b/includes/private/networking/slirp/slirp.h index 1be424ee..207c1296 100644 --- a/includes/private/networking/slirp/slirp.h +++ b/includes/private/networking/slirp/slirp.h @@ -2,7 +2,7 @@ #define __COMMON_H__ #ifdef __linux__ -#include // for open +#include // for open #include // for close #endif @@ -17,14 +17,12 @@ #include "slirp_config.h" #ifndef container_of -#define container_of(address, type, field) ((type *)( \ - (uintptr_t)(address) - \ - (uintptr_t)(&((type *)0)->field))) +#define container_of(address, type, field) ((type *)((uintptr_t)(address) - (uintptr_t)(&((type *)0)->field))) #endif #ifdef _WIN32 -#ifdef __GNUC__ //MINGW? -# include +#ifdef __GNUC__ // MINGW? +#include typedef uint8_t u_int8_t; typedef uint16_t u_int16_t; typedef uint32_t u_int32_t; @@ -33,60 +31,60 @@ 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 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; +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 //needs to be on top otherwise, it'll pull in winsock1 +#include -# include -# include +#include +#include -# define USE_FIONBIO 1 -# define EWOULDBLOCK WSAEWOULDBLOCK -# define EINPROGRESS WSAEINPROGRESS -# define ENOTCONN WSAENOTCONN -# define EHOSTUNREACH WSAEHOSTUNREACH -# define ENETUNREACH WSAENETUNREACH -# define ECONNREFUSED WSAECONNREFUSED +#define USE_FIONBIO 1 +#define EWOULDBLOCK WSAEWOULDBLOCK +#define EINPROGRESS WSAEINPROGRESS +#define ENOTCONN WSAENOTCONN +#define EHOSTUNREACH WSAEHOSTUNREACH +#define ENETUNREACH WSAENETUNREACH +#define ECONNREFUSED WSAECONNREFUSED /* 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 +#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 typedef int ioctlsockopt_t; -# define ioctlsocket ioctl -# define closesocket(s) close(s) -# define O_BINARY 0 +#define ioctlsocket ioctl +#define closesocket(s) close(s) +#define O_BINARY 0 typedef char *SLIRPcaddr_t; #endif #include #ifdef HAVE_SYS_BITYPES_H -# include +#include #endif #ifdef HAVE_STDINT_H -# include +#include #endif #ifdef HAVE_UNISTD_H -# include +#include #endif #ifndef _MSC_VER @@ -99,29 +97,29 @@ typedef char *SLIRPcaddr_t; 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 == 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 +#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 */ @@ -130,11 +128,11 @@ typedef u_int16_t uint16; typedef u_int32_t uint32; #ifdef HAVE_UNISTD_H -# include +#include #endif #ifdef HAVE_STDLIB_H -# include +#include #endif #include @@ -145,21 +143,21 @@ typedef u_int32_t uint32; #endif #if TIME_WITH_SYS_TIME -# include -# include +#include +#include #else -# if HAVE_SYS_TIME_H -# include -# else -# include -# endif +#if HAVE_SYS_TIME_H +#include +#else +#include +#endif #endif #ifdef HAVE_STRING_H -# include +#include #else #ifndef _MSC_VER -# include +#include #else #include #endif @@ -171,9 +169,9 @@ typedef u_int32_t uint32; #ifndef _P #ifndef NO_PROTOTYPES -# define _P(x) x +#define _P(x) x #else -# define _P(x) () +#define _P(x) () #endif #endif @@ -207,26 +205,26 @@ int inet_aton _P((const char *cp, struct in_addr *ia)); #endif #include #ifdef HAVE_SYS_SIGNAL_H -# include +#include #endif #ifndef _WIN32 #include #endif #if defined(HAVE_SYS_IOCTL_H) -# include +#include #endif #ifdef HAVE_SYS_SELECT_H -# include +#include #endif #ifdef HAVE_SYS_WAIT_H -# include +#include #endif #ifdef HAVE_SYS_FILIO_H -# include +#include #endif #ifdef USE_PPP @@ -253,7 +251,7 @@ int inet_aton _P((const char *cp, struct in_addr *ia)); #include "debug.h" #if defined __GNUC__ -#define PACKED__ __attribute__ ((packed)) +#define PACKED__ __attribute__((packed)) #elif defined __sgi #define PRAGMA_PACK_SUPPORTED 1 #define PACK_END 0 @@ -306,32 +304,32 @@ 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 *, ...)); +#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)); +#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 +extern char *strerror _P((int error)); +#define HAVE_STRERROR #endif #endif #ifndef HAVE_INDEX - char *index _P((const char *, int)); +char *index _P((const char *, int)); #endif #ifndef HAVE_GETHOSTID - long gethostid _P((void)); +long gethostid _P((void)); #endif void lprint _P((const char *, ...)); @@ -352,7 +350,7 @@ 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((struct ip *, struct ipq *)); +struct ip *ip_reass _P((struct ip *, 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 *)); @@ -377,8 +375,8 @@ void tcp_setpersist _P((register struct tcpcb *)); 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 *)); +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 *)); @@ -389,7 +387,6 @@ 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 @@ -403,8 +400,8 @@ struct tcpcb *tcp_drop(struct tcpcb *tp, int err); #endif #ifndef _WIN32 -#define min(x,y) ((x) < (y) ? (x) : (y)) -#define max(x,y) ((x) > (y) ? (x) : (y)) +#define min(x, y) ((x) < (y) ? (x) : (y)) +#define max(x, y) ((x) > (y) ? (x) : (y)) #endif #ifdef _WIN32 diff --git a/includes/private/networking/slirp/socket.h b/includes/private/networking/slirp/socket.h index 3a777934..bdb085eb 100644 --- a/includes/private/networking/slirp/socket.h +++ b/includes/private/networking/slirp/socket.h @@ -1,7 +1,7 @@ /* * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the + * + * Please read the file COPYRIGHT for the * terms and conditions of the copyright. */ @@ -18,72 +18,70 @@ */ struct SLIRPsocket { - struct SLIRPsocket *so_next,*so_prev; /* For a linked list of sockets */ + struct SLIRPsocket *so_next, *so_prev; /* For a linked list of sockets */ - int s; /* The actual socket */ + 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 */ + /* 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_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_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 */ +#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; + 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)); +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 *)); @@ -91,7 +89,7 @@ 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)); +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 *)); diff --git a/includes/private/networking/slirp/tcp.h b/includes/private/networking/slirp/tcp.h index 38c41bbf..a7eed16b 100644 --- a/includes/private/networking/slirp/tcp.h +++ b/includes/private/networking/slirp/tcp.h @@ -33,10 +33,10 @@ #ifndef _TCP_H_ #define _TCP_H_ -typedef u_int32_t tcp_seq; +typedef u_int32_t tcp_seq; -#define PR_SLOWHZ 2 /* 2 slow timeouts per second (approx) */ -#define PR_FASTHZ 5 /* 5 fast timeouts per second (not important) */ +#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; @@ -54,27 +54,27 @@ extern struct SLIRPsocket *tcp_last_so; #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 */ + 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) */ + u_char th_off : 4, /* data offset */ + th_x2 : 4; /* (unused) */ #else - u_char th_x2:4, /* (unused) */ - th_off:4; /* data offset */ + 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 */ + 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 @@ -83,21 +83,20 @@ struct tcphdr { #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_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) +#define TCPOPT_TSTAMP_HDR (TCPOPT_NOP << 24 | TCPOPT_NOP << 16 | TCPOPT_TIMESTAMP << 8 | TCPOLEN_TIMESTAMP) /* * Default maximum segment size for TCP. @@ -107,11 +106,11 @@ struct tcphdr { * * We make this 1460 because we only care about Ethernet in the qemu context. */ -#define TCP_MSS 1460 +#define TCP_MSS 1460 -#define TCP_MAXWIN 65535 /* largest value for (unscaled) window */ +#define TCP_MAXWIN 65535 /* largest value for (unscaled) window */ -#define TCP_MAX_WINSHIFT 14 /* maximum window shift */ +#define TCP_MAX_WINSHIFT 14 /* maximum window shift */ /* * User-settable options (used with setsockopt). @@ -121,60 +120,58 @@ struct tcphdr { * so we undefine them. */ #undef TCP_NODELAY -#define TCP_NODELAY 0x01 /* don't delay send to coalesce packets */ +#define TCP_NODELAY 0x01 /* don't delay send to coalesce packets */ #undef TCP_MAXSEG -/* #define TCP_MAXSEG 0x02 */ /* set maximum segment size */ +/* #define TCP_MAXSEG 0x02 */ /* set maximum segment size */ /* * TCP FSM state definitions. * Per RFC793, September, 1981. */ -#define TCP_NSTATES 11 +#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 */ +#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 */ +#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 */ +#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_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_HAVERCVDSYN(s) ((s) >= TCPS_SYN_RECEIVED) #define TCPS_HAVEESTABLISHED(s) ((s) >= TCPS_ESTABLISHED) -#define TCPS_HAVERCVDFIN(s) ((s) >= TCPS_TIME_WAIT) +#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) +#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_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_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 */ +#define TCP_ISSINCR (125 * 1024) /* increment for tcp_iss each second */ -extern tcp_seq tcp_iss; /* tcp initial send seq # */ +extern tcp_seq tcp_iss; /* tcp initial send seq # */ extern char *tcpstates[]; diff --git a/includes/private/networking/slirp/tcp_timer.h b/includes/private/networking/slirp/tcp_timer.h index 0bc438c7..198625c2 100644 --- a/includes/private/networking/slirp/tcp_timer.h +++ b/includes/private/networking/slirp/tcp_timer.h @@ -37,12 +37,12 @@ * Definitions of the TCP timers. These timers are counted * down PR_SLOWHZ times a second. */ -#define TCPT_NTIMERS 4 +#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 */ +#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. @@ -83,49 +83,49 @@ /* * Time constants. */ -#define TCPTV_MSL ( 5*PR_SLOWHZ) /* max seg lifetime (hah!) */ +#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_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_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_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 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_LINGERTIME 120 /* linger at most 2 minutes */ -#define TCP_MAXRXTSHIFT 12 /* maximum retransmits */ +#define TCP_MAXRXTSHIFT 12 /* maximum retransmits */ - -#ifdef TCPTIMERS -char *tcptimers[] = - { "REXMT", "PERSIST", "KEEP", "2MSL" }; +#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); \ -} +#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_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; @@ -133,6 +133,6 @@ 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)); +struct tcpcb *tcp_timers _P((register struct tcpcb *, int)); #endif diff --git a/includes/private/networking/slirp/tcp_var.h b/includes/private/networking/slirp/tcp_var.h index 825092c1..ccfd0c60 100644 --- a/includes/private/networking/slirp/tcp_var.h +++ b/includes/private/networking/slirp/tcp_var.h @@ -40,95 +40,94 @@ * Tcp control block, one per tcp; fields: */ struct tcpcb { - struct tcpiphdr *seg_next; /* sequencing queue */ - struct tcpiphdr *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 */ + struct tcpiphdr *seg_next; /* sequencing queue */ + struct tcpiphdr *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; + /* 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 */ + 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; + /* 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) +#define sototcpcb(so) ((so)->so_tcpcb) /* * The smoothed round-trip time and estimated variance @@ -139,10 +138,10 @@ struct tcpcb { * 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 */ +#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. @@ -157,8 +156,7 @@ struct tcpcb { * 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) +#define TCP_REXMTVAL(tp) (((tp)->t_srtt >> TCP_RTT_SHIFT) + (tp)->t_rttvar) /* * TCP statistics. @@ -166,62 +164,62 @@ struct tcpcb { * 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_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_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 */ + 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 */ +extern struct tcpstat tcpstat; /* tcp statistics */ +extern u_int32_t tcp_now; /* for RFC 1323 timestamps */ #endif diff --git a/includes/private/networking/slirp/tcpip.h b/includes/private/networking/slirp/tcpip.h index d704667e..3f143ec0 100644 --- a/includes/private/networking/slirp/tcpip.h +++ b/includes/private/networking/slirp/tcpip.h @@ -37,41 +37,41 @@ * Tcp+ip header, after ip options removed. */ struct tcpiphdr { - struct ipovly ti_i; /* overlaid ip structure */ - struct tcphdr ti_t; /* tcp header */ + struct ipovly ti_i; /* overlaid ip structure */ + struct tcphdr ti_t; /* tcp header */ }; -#define ti_mbuf ti_i.ih_mbuf.m.mptr -#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 +#define ti_mbuf ti_i.ih_mbuf.m.mptr +#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 -#define tcpiphdr2qlink(T) ((struct qlink*)(((char*)(T)) - sizeof(struct qlink))) -#define qlink2tcpiphdr(Q) ((struct tcpiphdr*)(((char*)(Q)) + sizeof(struct qlink))) +#define tcpiphdr2qlink(T) ((struct qlink *)(((char *)(T)) - sizeof(struct qlink))) +#define qlink2tcpiphdr(Q) ((struct tcpiphdr *)(((char *)(Q)) + sizeof(struct qlink))) #define tcpiphdr_next(T) qlink2tcpiphdr(tcpiphdr2qlink(T)->next) #define tcpiphdr_prev(T) qlink2tcpiphdr(tcpiphdr2qlink(T)->prev) #define tcpfrag_list_first(T) qlink2tcpiphdr((T)->seg_next) -#define tcpfrag_list_end(F, T) (tcpiphdr2qlink(F) == (struct qlink*)(T)) -#define tcpfrag_list_empty(T) ((T)->seg_next == (struct tcpiphdr*)(T)) +#define tcpfrag_list_end(F, T) (tcpiphdr2qlink(F) == (struct qlink *)(T)) +#define tcpfrag_list_empty(T) ((T)->seg_next == (struct tcpiphdr *)(T)) /* * Just a clean way to get to the first byte * of the packet */ struct tcpiphdr_2 { - struct tcpiphdr dummy; - char first_char; + struct tcpiphdr dummy; + char first_char; }; #endif diff --git a/includes/private/networking/slirp/tftp.h b/includes/private/networking/slirp/tftp.h index ba417411..e21a7c02 100644 --- a/includes/private/networking/slirp/tftp.h +++ b/includes/private/networking/slirp/tftp.h @@ -2,13 +2,13 @@ #define TFTP_SESSIONS_MAX 3 -#define TFTP_SERVER 69 +#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_RRQ 1 +#define TFTP_WRQ 2 +#define TFTP_DATA 3 +#define TFTP_ACK 4 +#define TFTP_ERROR 5 #define TFTP_FILENAME_MAX 512 @@ -17,20 +17,20 @@ #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; + 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 diff --git a/includes/private/networking/slirp/udp.h b/includes/private/networking/slirp/udp.h index c1647dd7..7ce12114 100644 --- a/includes/private/networking/slirp/udp.h +++ b/includes/private/networking/slirp/udp.h @@ -47,10 +47,10 @@ extern struct SLIRPsocket *udp_last_so; #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 */ + 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 @@ -61,39 +61,39 @@ struct udphdr { * UDP kernel structures and variables. */ struct udpiphdr { - struct ipovly ui_i; /* overlaid ip structure */ - struct udphdr ui_u; /* udp header */ + struct ipovly ui_i; /* overlaid ip structure */ + struct udphdr ui_u; /* udp header */ }; -#define ui_mbuf ui_i.ih_mbuf.m.mptr -#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 +#define ui_mbuf ui_i.ih_mbuf.m.mptr +#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 */ + /* 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 +#define UDPCTL_CHECKSUM 1 /* checksum UDP packets */ +#define UDPCTL_MAXID 2 extern struct udpstat udpstat; extern struct SLIRPsocket udb; @@ -106,8 +106,6 @@ 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); +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/includes/private/pgc_palettes.h b/includes/private/pgc_palettes.h index 2d3d0dd2..80cac77a 100644 --- a/includes/private/pgc_palettes.h +++ b/includes/private/pgc_palettes.h @@ -1,1554 +1,402 @@ /* Palette 0: Default */ - { - makecol(0x00,0x00,0x00), - makecol(0x11,0x11,0x11), - makecol(0x22,0x22,0x22), - makecol(0x33,0x33,0x33), - makecol(0x44,0x44,0x44), - makecol(0x55,0x55,0x55), - makecol(0x66,0x66,0x66), - makecol(0x77,0x77,0x77), - makecol(0x88,0x88,0x88), - makecol(0x99,0x99,0x99), - makecol(0xaa,0xaa,0xaa), - makecol(0xbb,0xbb,0xbb), - makecol(0xcc,0xcc,0xcc), - makecol(0xdd,0xdd,0xdd), - makecol(0xee,0xee,0xee), - makecol(0xff,0xff,0xff), - makecol(0x00,0x00,0x00), - makecol(0x00,0x22,0x00), - makecol(0x00,0x44,0x00), - makecol(0x00,0x66,0x00), - makecol(0x00,0x88,0x00), - makecol(0x00,0xaa,0x00), - makecol(0x00,0xcc,0x00), - makecol(0x00,0xee,0x00), - makecol(0x00,0xff,0x00), - makecol(0x22,0xff,0x22), - makecol(0x44,0xff,0x44), - makecol(0x66,0xff,0x66), - makecol(0x88,0xff,0x88), - makecol(0xaa,0xff,0xaa), - makecol(0xcc,0xff,0xcc), - makecol(0xee,0xff,0xee), - makecol(0x00,0x00,0x00), - makecol(0x00,0x22,0x11), - makecol(0x00,0x44,0x22), - makecol(0x00,0x66,0x33), - makecol(0x00,0x88,0x44), - makecol(0x00,0xaa,0x55), - makecol(0x00,0xcc,0x66), - makecol(0x00,0xee,0x77), - makecol(0x00,0xff,0x88), - makecol(0x22,0xff,0x99), - makecol(0x44,0xff,0xaa), - makecol(0x66,0xff,0xbb), - makecol(0x88,0xff,0xcc), - makecol(0xaa,0xff,0xdd), - makecol(0xcc,0xff,0xee), - makecol(0xee,0xff,0xff), - makecol(0x00,0x00,0x00), - makecol(0x00,0x22,0x22), - makecol(0x00,0x44,0x44), - makecol(0x00,0x66,0x66), - makecol(0x00,0x88,0x88), - makecol(0x00,0xaa,0xaa), - makecol(0x00,0xcc,0xcc), - makecol(0x00,0xee,0xee), - makecol(0x00,0xff,0xff), - makecol(0x22,0xff,0xff), - makecol(0x44,0xff,0xff), - makecol(0x66,0xff,0xff), - makecol(0x88,0xff,0xff), - makecol(0xaa,0xff,0xff), - makecol(0xcc,0xff,0xff), - makecol(0xee,0xff,0xff), - makecol(0x00,0x00,0x00), - makecol(0x00,0x11,0x22), - makecol(0x00,0x22,0x44), - makecol(0x00,0x33,0x66), - makecol(0x00,0x44,0x88), - makecol(0x00,0x55,0xaa), - makecol(0x00,0x66,0xcc), - makecol(0x00,0x77,0xee), - makecol(0x00,0x88,0xff), - makecol(0x22,0x99,0xff), - makecol(0x44,0xaa,0xff), - makecol(0x66,0xbb,0xff), - makecol(0x88,0xcc,0xff), - makecol(0xaa,0xdd,0xff), - makecol(0xcc,0xee,0xff), - makecol(0xee,0xff,0xff), - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x22), - makecol(0x00,0x00,0x44), - makecol(0x00,0x00,0x66), - makecol(0x00,0x00,0x88), - makecol(0x00,0x00,0xaa), - makecol(0x00,0x00,0xcc), - makecol(0x00,0x00,0xee), - makecol(0x00,0x00,0xff), - makecol(0x22,0x22,0xff), - makecol(0x44,0x44,0xff), - makecol(0x66,0x66,0xff), - makecol(0x88,0x88,0xff), - makecol(0xaa,0xaa,0xff), - makecol(0xcc,0xcc,0xff), - makecol(0xee,0xee,0xff), - makecol(0x00,0x00,0x00), - makecol(0x11,0x00,0x22), - makecol(0x22,0x00,0x44), - makecol(0x33,0x00,0x66), - makecol(0x44,0x00,0x88), - makecol(0x55,0x00,0xaa), - makecol(0x66,0x00,0xcc), - makecol(0x77,0x00,0xee), - makecol(0x88,0x00,0xff), - makecol(0x99,0x22,0xff), - makecol(0xaa,0x44,0xff), - makecol(0xbb,0x66,0xff), - makecol(0xcc,0x88,0xff), - makecol(0xdd,0xaa,0xff), - makecol(0xee,0xcc,0xff), - makecol(0xff,0xee,0xff), - makecol(0x00,0x00,0x00), - makecol(0x22,0x00,0x22), - makecol(0x44,0x00,0x44), - makecol(0x66,0x00,0x66), - makecol(0x88,0x00,0x88), - makecol(0xaa,0x00,0xaa), - makecol(0xcc,0x00,0xcc), - makecol(0xee,0x00,0xee), - makecol(0xff,0x00,0xff), - makecol(0xff,0x22,0xff), - makecol(0xff,0x44,0xff), - makecol(0xff,0x66,0xff), - makecol(0xff,0x88,0xff), - makecol(0xff,0xaa,0xff), - makecol(0xff,0xcc,0xff), - makecol(0xff,0xee,0xff), - makecol(0x00,0x00,0x00), - makecol(0x22,0x00,0x11), - makecol(0x44,0x00,0x22), - makecol(0x66,0x00,0x33), - makecol(0x88,0x00,0x44), - makecol(0xaa,0x00,0x55), - makecol(0xcc,0x00,0x66), - makecol(0xee,0x00,0x77), - makecol(0xff,0x00,0x88), - makecol(0xff,0x22,0x99), - makecol(0xff,0x44,0xaa), - makecol(0xff,0x66,0xbb), - makecol(0xff,0x88,0xcc), - makecol(0xff,0xaa,0xdd), - makecol(0xff,0xcc,0xee), - makecol(0xff,0xee,0xff), - makecol(0x00,0x00,0x00), - makecol(0x22,0x00,0x00), - makecol(0x44,0x00,0x00), - makecol(0x66,0x00,0x00), - makecol(0x88,0x00,0x00), - makecol(0xaa,0x00,0x00), - makecol(0xcc,0x00,0x00), - makecol(0xee,0x00,0x00), - makecol(0xff,0x00,0x00), - makecol(0xff,0x22,0x22), - makecol(0xff,0x44,0x44), - makecol(0xff,0x66,0x66), - makecol(0xff,0x88,0x88), - makecol(0xff,0xaa,0xaa), - makecol(0xff,0xcc,0xcc), - makecol(0xff,0xee,0xee), - makecol(0x00,0x00,0x00), - makecol(0x22,0x11,0x00), - makecol(0x44,0x22,0x00), - makecol(0x66,0x33,0x00), - makecol(0x88,0x44,0x00), - makecol(0xaa,0x55,0x00), - makecol(0xcc,0x66,0x00), - makecol(0xee,0x77,0x00), - makecol(0xff,0x88,0x00), - makecol(0xff,0x99,0x22), - makecol(0xff,0xaa,0x44), - makecol(0xff,0xbb,0x66), - makecol(0xff,0xcc,0x88), - makecol(0xff,0xdd,0xaa), - makecol(0xff,0xee,0xcc), - makecol(0xff,0xff,0xee), - makecol(0x00,0x00,0x00), - makecol(0x22,0x22,0x00), - makecol(0x44,0x44,0x00), - makecol(0x66,0x66,0x00), - makecol(0x88,0x88,0x00), - makecol(0xaa,0xaa,0x00), - makecol(0xcc,0xcc,0x00), - makecol(0xee,0xee,0x00), - makecol(0xff,0xff,0x00), - makecol(0xff,0xff,0x22), - makecol(0xff,0xff,0x44), - makecol(0xff,0xff,0x66), - makecol(0xff,0xff,0x88), - makecol(0xff,0xff,0xaa), - makecol(0xff,0xff,0xcc), - makecol(0xff,0xff,0xee), - makecol(0x00,0x00,0x00), - makecol(0x11,0x22,0x00), - makecol(0x22,0x44,0x00), - makecol(0x33,0x66,0x00), - makecol(0x44,0x88,0x00), - makecol(0x55,0xaa,0x00), - makecol(0x66,0xcc,0x00), - makecol(0x77,0xee,0x00), - makecol(0x88,0xff,0x00), - makecol(0x99,0xff,0x22), - makecol(0xaa,0xff,0x44), - makecol(0xbb,0xff,0x66), - makecol(0xcc,0xff,0x88), - makecol(0xdd,0xff,0xaa), - makecol(0xee,0xff,0xcc), - makecol(0xff,0xff,0xee), - makecol(0x00,0x00,0x00), - makecol(0x00,0x11,0x00), - makecol(0x11,0x33,0x11), - makecol(0x11,0x44,0x11), - makecol(0x22,0x66,0x22), - makecol(0x22,0x77,0x22), - makecol(0x33,0x99,0x33), - makecol(0x33,0xaa,0x33), - makecol(0x44,0xcc,0x44), - makecol(0x55,0xcc,0x55), - makecol(0x77,0xdd,0x77), - makecol(0x88,0xdd,0x88), - makecol(0xaa,0xee,0xaa), - makecol(0xbb,0xee,0xbb), - makecol(0xdd,0xff,0xdd), - makecol(0xee,0xff,0xee), - makecol(0x00,0x00,0x00), - makecol(0x11,0x00,0x00), - makecol(0x33,0x11,0x11), - makecol(0x44,0x11,0x11), - makecol(0x66,0x22,0x22), - makecol(0x77,0x22,0x22), - makecol(0x99,0x33,0x33), - makecol(0xaa,0x33,0x33), - makecol(0xcc,0x44,0x44), - makecol(0xcc,0x55,0x55), - makecol(0xdd,0x77,0x77), - makecol(0xdd,0x88,0x88), - makecol(0xee,0xaa,0xaa), - makecol(0xee,0xbb,0xbb), - makecol(0xff,0xdd,0xdd), - makecol(0xff,0xee,0xee), - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x11), - makecol(0x11,0x11,0x33), - makecol(0x11,0x11,0x44), - makecol(0x22,0x22,0x66), - makecol(0x22,0x22,0x77), - makecol(0x33,0x33,0x99), - makecol(0x33,0x33,0xaa), - makecol(0x44,0x44,0xcc), - makecol(0x55,0x55,0xcc), - makecol(0x77,0x77,0xdd), - makecol(0x88,0x88,0xdd), - makecol(0xaa,0xaa,0xee), - makecol(0xbb,0xbb,0xee), - makecol(0xdd,0xdd,0xff), - makecol(0xee,0xee,0xff), - }, -/* Palette 1: 16-colour palette */ - { - makecol(0x88,0x66,0xdd), - makecol(0x00,0x00,0x00), - makecol(0x44,0x77,0x22), - makecol(0x77,0xaa,0x44), - makecol(0x00,0x77,0x00), - makecol(0x00,0xff,0x00), - makecol(0x77,0xff,0x00), - makecol(0xff,0xff,0x00), - makecol(0xff,0xaa,0x00), - makecol(0xff,0x00,0x00), - makecol(0x77,0x00,0x00), - makecol(0x77,0x00,0x77), - makecol(0x00,0x00,0x77), - makecol(0x99,0xee,0x66), - makecol(0x77,0x77,0x77), - makecol(0xff,0xff,0xff), - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x00), - makecol(0x44,0x77,0x22), - makecol(0x44,0x77,0x22), - makecol(0x44,0x77,0x22), - makecol(0x44,0x77,0x22), - makecol(0x44,0x77,0x22), - makecol(0x44,0x77,0x22), - makecol(0x44,0x77,0x22), - makecol(0x44,0x77,0x22), - makecol(0x44,0x77,0x22), - makecol(0x44,0x77,0x22), - makecol(0x44,0x77,0x22), - makecol(0x44,0x77,0x22), - makecol(0x44,0x77,0x22), - makecol(0x44,0x77,0x22), - makecol(0x44,0x77,0x22), - makecol(0x44,0x77,0x22), - makecol(0x77,0xaa,0x44), - makecol(0x77,0xaa,0x44), - makecol(0x77,0xaa,0x44), - makecol(0x77,0xaa,0x44), - makecol(0x77,0xaa,0x44), - makecol(0x77,0xaa,0x44), - makecol(0x77,0xaa,0x44), - makecol(0x77,0xaa,0x44), - makecol(0x77,0xaa,0x44), - makecol(0x77,0xaa,0x44), - makecol(0x77,0xaa,0x44), - makecol(0x77,0xaa,0x44), - makecol(0x77,0xaa,0x44), - makecol(0x77,0xaa,0x44), - makecol(0x77,0xaa,0x44), - makecol(0x77,0xaa,0x44), - makecol(0x00,0x77,0x00), - makecol(0x00,0x77,0x00), - makecol(0x00,0x77,0x00), - makecol(0x00,0x77,0x00), - makecol(0x00,0x77,0x00), - makecol(0x00,0x77,0x00), - makecol(0x00,0x77,0x00), - makecol(0x00,0x77,0x00), - makecol(0x00,0x77,0x00), - makecol(0x00,0x77,0x00), - makecol(0x00,0x77,0x00), - makecol(0x00,0x77,0x00), - makecol(0x00,0x77,0x00), - makecol(0x00,0x77,0x00), - makecol(0x00,0x77,0x00), - makecol(0x00,0x77,0x00), - makecol(0x00,0xff,0x00), - makecol(0x00,0xff,0x00), - makecol(0x00,0xff,0x00), - makecol(0x00,0xff,0x00), - makecol(0x00,0xff,0x00), - makecol(0x00,0xff,0x00), - makecol(0x00,0xff,0x00), - makecol(0x00,0xff,0x00), - makecol(0x00,0xff,0x00), - makecol(0x00,0xff,0x00), - makecol(0x00,0xff,0x00), - makecol(0x00,0xff,0x00), - makecol(0x00,0xff,0x00), - makecol(0x00,0xff,0x00), - makecol(0x00,0xff,0x00), - makecol(0x00,0xff,0x00), - makecol(0x77,0xff,0x00), - makecol(0x77,0xff,0x00), - makecol(0x77,0xff,0x00), - makecol(0x77,0xff,0x00), - makecol(0x77,0xff,0x00), - makecol(0x77,0xff,0x00), - makecol(0x77,0xff,0x00), - makecol(0x77,0xff,0x00), - makecol(0x77,0xff,0x00), - makecol(0x77,0xff,0x00), - makecol(0x77,0xff,0x00), - makecol(0x77,0xff,0x00), - makecol(0x77,0xff,0x00), - makecol(0x77,0xff,0x00), - makecol(0x77,0xff,0x00), - makecol(0x77,0xff,0x00), - makecol(0xff,0xff,0x00), - makecol(0xff,0xff,0x00), - makecol(0xff,0xff,0x00), - makecol(0xff,0xff,0x00), - makecol(0xff,0xff,0x00), - makecol(0xff,0xff,0x00), - makecol(0xff,0xff,0x00), - makecol(0xff,0xff,0x00), - makecol(0xff,0xff,0x00), - makecol(0xff,0xff,0x00), - makecol(0xff,0xff,0x00), - makecol(0xff,0xff,0x00), - makecol(0xff,0xff,0x00), - makecol(0xff,0xff,0x00), - makecol(0xff,0xff,0x00), - makecol(0xff,0xff,0x00), - makecol(0xff,0xaa,0x00), - makecol(0xff,0xaa,0x00), - makecol(0xff,0xaa,0x00), - makecol(0xff,0xaa,0x00), - makecol(0xff,0xaa,0x00), - makecol(0xff,0xaa,0x00), - makecol(0xff,0xaa,0x00), - makecol(0xff,0xaa,0x00), - makecol(0xff,0xaa,0x00), - makecol(0xff,0xaa,0x00), - makecol(0xff,0xaa,0x00), - makecol(0xff,0xaa,0x00), - makecol(0xff,0xaa,0x00), - makecol(0xff,0xaa,0x00), - makecol(0xff,0xaa,0x00), - makecol(0xff,0xaa,0x00), - makecol(0xff,0x00,0x00), - makecol(0xff,0x00,0x00), - makecol(0xff,0x00,0x00), - makecol(0xff,0x00,0x00), - makecol(0xff,0x00,0x00), - makecol(0xff,0x00,0x00), - makecol(0xff,0x00,0x00), - makecol(0xff,0x00,0x00), - makecol(0xff,0x00,0x00), - makecol(0xff,0x00,0x00), - makecol(0xff,0x00,0x00), - makecol(0xff,0x00,0x00), - makecol(0xff,0x00,0x00), - makecol(0xff,0x00,0x00), - makecol(0xff,0x00,0x00), - makecol(0xff,0x00,0x00), - makecol(0x77,0x00,0x00), - makecol(0x77,0x00,0x00), - makecol(0x77,0x00,0x00), - makecol(0x77,0x00,0x00), - makecol(0x77,0x00,0x00), - makecol(0x77,0x00,0x00), - makecol(0x77,0x00,0x00), - makecol(0x77,0x00,0x00), - makecol(0x77,0x00,0x00), - makecol(0x77,0x00,0x00), - makecol(0x77,0x00,0x00), - makecol(0x77,0x00,0x00), - makecol(0x77,0x00,0x00), - makecol(0x77,0x00,0x00), - makecol(0x77,0x00,0x00), - makecol(0x77,0x00,0x00), - makecol(0x77,0x00,0x77), - makecol(0x77,0x00,0x77), - makecol(0x77,0x00,0x77), - makecol(0x77,0x00,0x77), - makecol(0x77,0x00,0x77), - makecol(0x77,0x00,0x77), - makecol(0x77,0x00,0x77), - makecol(0x77,0x00,0x77), - makecol(0x77,0x00,0x77), - makecol(0x77,0x00,0x77), - makecol(0x77,0x00,0x77), - makecol(0x77,0x00,0x77), - makecol(0x77,0x00,0x77), - makecol(0x77,0x00,0x77), - makecol(0x77,0x00,0x77), - makecol(0x77,0x00,0x77), - makecol(0x00,0x00,0x77), - makecol(0x00,0x00,0x77), - makecol(0x00,0x00,0x77), - makecol(0x00,0x00,0x77), - makecol(0x00,0x00,0x77), - makecol(0x00,0x00,0x77), - makecol(0x00,0x00,0x77), - makecol(0x00,0x00,0x77), - makecol(0x00,0x00,0x77), - makecol(0x00,0x00,0x77), - makecol(0x00,0x00,0x77), - makecol(0x00,0x00,0x77), - makecol(0x00,0x00,0x77), - makecol(0x00,0x00,0x77), - makecol(0x00,0x00,0x77), - makecol(0x00,0x00,0x77), - makecol(0x99,0xee,0x66), - makecol(0x99,0xee,0x66), - makecol(0x99,0xee,0x66), - makecol(0x99,0xee,0x66), - makecol(0x99,0xee,0x66), - makecol(0x99,0xee,0x66), - makecol(0x99,0xee,0x66), - makecol(0x99,0xee,0x66), - makecol(0x99,0xee,0x66), - makecol(0x99,0xee,0x66), - makecol(0x99,0xee,0x66), - makecol(0x99,0xee,0x66), - makecol(0x99,0xee,0x66), - makecol(0x99,0xee,0x66), - makecol(0x99,0xee,0x66), - makecol(0x99,0xee,0x66), - makecol(0x77,0x77,0x77), - makecol(0x77,0x77,0x77), - makecol(0x77,0x77,0x77), - makecol(0x77,0x77,0x77), - makecol(0x77,0x77,0x77), - makecol(0x77,0x77,0x77), - makecol(0x77,0x77,0x77), - makecol(0x77,0x77,0x77), - makecol(0x77,0x77,0x77), - makecol(0x77,0x77,0x77), - makecol(0x77,0x77,0x77), - makecol(0x77,0x77,0x77), - makecol(0x77,0x77,0x77), - makecol(0x77,0x77,0x77), - makecol(0x77,0x77,0x77), - makecol(0x77,0x77,0x77), - makecol(0xff,0xff,0xff), - makecol(0xff,0xff,0xff), - makecol(0xff,0xff,0xff), - makecol(0xff,0xff,0xff), - makecol(0xff,0xff,0xff), - makecol(0xff,0xff,0xff), - makecol(0xff,0xff,0xff), - makecol(0xff,0xff,0xff), - makecol(0xff,0xff,0xff), - makecol(0xff,0xff,0xff), - makecol(0xff,0xff,0xff), - makecol(0xff,0xff,0xff), - makecol(0xff,0xff,0xff), - makecol(0xff,0xff,0xff), - makecol(0xff,0xff,0xff), - makecol(0xff,0xff,0xff), - }, -/* Palette 2: 2-3-3 truecolour */ - { - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x33), - makecol(0x00,0x00,0x55), - makecol(0x00,0x00,0x77), - makecol(0x00,0x00,0x99), - makecol(0x00,0x00,0xbb), - makecol(0x00,0x00,0xdd), - makecol(0x00,0x00,0xff), - makecol(0x33,0x00,0x00), - makecol(0x33,0x00,0x33), - makecol(0x33,0x00,0x55), - makecol(0x33,0x00,0x77), - makecol(0x33,0x00,0x99), - makecol(0x33,0x00,0xbb), - makecol(0x33,0x00,0xdd), - makecol(0x33,0x00,0xff), - makecol(0x55,0x00,0x00), - makecol(0x55,0x00,0x33), - makecol(0x55,0x00,0x55), - makecol(0x55,0x00,0x77), - makecol(0x55,0x00,0x99), - makecol(0x55,0x00,0xbb), - makecol(0x55,0x00,0xdd), - makecol(0x55,0x00,0xff), - makecol(0x77,0x00,0x00), - makecol(0x77,0x00,0x33), - makecol(0x77,0x00,0x55), - makecol(0x77,0x00,0x77), - makecol(0x77,0x00,0x99), - makecol(0x77,0x00,0xbb), - makecol(0x77,0x00,0xdd), - makecol(0x77,0x00,0xff), - makecol(0x99,0x00,0x00), - makecol(0x99,0x00,0x33), - makecol(0x99,0x00,0x55), - makecol(0x99,0x00,0x77), - makecol(0x99,0x00,0x99), - makecol(0x99,0x00,0xbb), - makecol(0x99,0x00,0xdd), - makecol(0x99,0x00,0xff), - makecol(0xbb,0x00,0x00), - makecol(0xbb,0x00,0x33), - makecol(0xbb,0x00,0x55), - makecol(0xbb,0x00,0x77), - makecol(0xbb,0x00,0x99), - makecol(0xbb,0x00,0xbb), - makecol(0xbb,0x00,0xdd), - makecol(0xbb,0x00,0xff), - makecol(0xdd,0x00,0x00), - makecol(0xdd,0x00,0x33), - makecol(0xdd,0x00,0x55), - makecol(0xdd,0x00,0x77), - makecol(0xdd,0x00,0x99), - makecol(0xdd,0x00,0xbb), - makecol(0xdd,0x00,0xdd), - makecol(0xdd,0x00,0xff), - makecol(0xff,0x00,0x00), - makecol(0xff,0x00,0x33), - makecol(0xff,0x00,0x55), - makecol(0xff,0x00,0x77), - makecol(0xff,0x00,0x99), - makecol(0xff,0x00,0xbb), - makecol(0xff,0x00,0xdd), - makecol(0xff,0x00,0xff), - makecol(0x00,0x55,0x00), - makecol(0x00,0x55,0x33), - makecol(0x00,0x55,0x55), - makecol(0x00,0x55,0x77), - makecol(0x00,0x55,0x99), - makecol(0x00,0x55,0xbb), - makecol(0x00,0x55,0xdd), - makecol(0x00,0x55,0xff), - makecol(0x33,0x55,0x00), - makecol(0x33,0x55,0x33), - makecol(0x33,0x55,0x55), - makecol(0x33,0x55,0x77), - makecol(0x33,0x55,0x99), - makecol(0x33,0x55,0xbb), - makecol(0x33,0x55,0xdd), - makecol(0x33,0x55,0xff), - makecol(0x55,0x55,0x00), - makecol(0x55,0x55,0x33), - makecol(0x55,0x55,0x55), - makecol(0x55,0x55,0x77), - makecol(0x55,0x55,0x99), - makecol(0x55,0x55,0xbb), - makecol(0x55,0x55,0xdd), - makecol(0x55,0x55,0xff), - makecol(0x77,0x55,0x00), - makecol(0x77,0x55,0x33), - makecol(0x77,0x55,0x55), - makecol(0x77,0x55,0x77), - makecol(0x77,0x55,0x99), - makecol(0x77,0x55,0xbb), - makecol(0x77,0x55,0xdd), - makecol(0x77,0x55,0xff), - makecol(0x99,0x55,0x00), - makecol(0x99,0x55,0x33), - makecol(0x99,0x55,0x55), - makecol(0x99,0x55,0x77), - makecol(0x99,0x55,0x99), - makecol(0x99,0x55,0xbb), - makecol(0x99,0x55,0xdd), - makecol(0x99,0x55,0xff), - makecol(0xbb,0x55,0x00), - makecol(0xbb,0x55,0x33), - makecol(0xbb,0x55,0x55), - makecol(0xbb,0x55,0x77), - makecol(0xbb,0x55,0x99), - makecol(0xbb,0x55,0xbb), - makecol(0xbb,0x55,0xdd), - makecol(0xbb,0x55,0xff), - makecol(0xdd,0x55,0x00), - makecol(0xdd,0x55,0x33), - makecol(0xdd,0x55,0x55), - makecol(0xdd,0x55,0x77), - makecol(0xdd,0x55,0x99), - makecol(0xdd,0x55,0xbb), - makecol(0xdd,0x55,0xdd), - makecol(0xdd,0x55,0xff), - makecol(0xff,0x55,0x00), - makecol(0xff,0x55,0x33), - makecol(0xff,0x55,0x55), - makecol(0xff,0x55,0x77), - makecol(0xff,0x55,0x99), - makecol(0xff,0x55,0xbb), - makecol(0xff,0x55,0xdd), - makecol(0xff,0x55,0xff), - makecol(0x00,0xaa,0x00), - makecol(0x00,0xaa,0x33), - makecol(0x00,0xaa,0x55), - makecol(0x00,0xaa,0x77), - makecol(0x00,0xaa,0x99), - makecol(0x00,0xaa,0xbb), - makecol(0x00,0xaa,0xdd), - makecol(0x00,0xaa,0xff), - makecol(0x33,0xaa,0x00), - makecol(0x33,0xaa,0x33), - makecol(0x33,0xaa,0x55), - makecol(0x33,0xaa,0x77), - makecol(0x33,0xaa,0x99), - makecol(0x33,0xaa,0xbb), - makecol(0x33,0xaa,0xdd), - makecol(0x33,0xaa,0xff), - makecol(0x55,0xaa,0x00), - makecol(0x55,0xaa,0x33), - makecol(0x55,0xaa,0x55), - makecol(0x55,0xaa,0x77), - makecol(0x55,0xaa,0x99), - makecol(0x55,0xaa,0xbb), - makecol(0x55,0xaa,0xdd), - makecol(0x55,0xaa,0xff), - makecol(0x77,0xaa,0x00), - makecol(0x77,0xaa,0x33), - makecol(0x77,0xaa,0x55), - makecol(0x77,0xaa,0x77), - makecol(0x77,0xaa,0x99), - makecol(0x77,0xaa,0xbb), - makecol(0x77,0xaa,0xdd), - makecol(0x77,0xaa,0xff), - makecol(0x99,0xaa,0x00), - makecol(0x99,0xaa,0x33), - makecol(0x99,0xaa,0x55), - makecol(0x99,0xaa,0x77), - makecol(0x99,0xaa,0x99), - makecol(0x99,0xaa,0xbb), - makecol(0x99,0xaa,0xdd), - makecol(0x99,0xaa,0xff), - makecol(0xbb,0xaa,0x00), - makecol(0xbb,0xaa,0x33), - makecol(0xbb,0xaa,0x55), - makecol(0xbb,0xaa,0x77), - makecol(0xbb,0xaa,0x99), - makecol(0xbb,0xaa,0xbb), - makecol(0xbb,0xaa,0xdd), - makecol(0xbb,0xaa,0xff), - makecol(0xdd,0xaa,0x00), - makecol(0xdd,0xaa,0x33), - makecol(0xdd,0xaa,0x55), - makecol(0xdd,0xaa,0x77), - makecol(0xdd,0xaa,0x99), - makecol(0xdd,0xaa,0xbb), - makecol(0xdd,0xaa,0xdd), - makecol(0xdd,0xaa,0xff), - makecol(0xff,0xaa,0x00), - makecol(0xff,0xaa,0x33), - makecol(0xff,0xaa,0x55), - makecol(0xff,0xaa,0x77), - makecol(0xff,0xaa,0x99), - makecol(0xff,0xaa,0xbb), - makecol(0xff,0xaa,0xdd), - makecol(0xff,0xaa,0xee), - makecol(0x00,0xff,0x00), - makecol(0x00,0xff,0x33), - makecol(0x00,0xff,0x55), - makecol(0x00,0xff,0x77), - makecol(0x00,0xff,0x99), - makecol(0x00,0xff,0xbb), - makecol(0x00,0xff,0xdd), - makecol(0x00,0xff,0xff), - makecol(0x33,0xff,0x00), - makecol(0x33,0xff,0x33), - makecol(0x33,0xff,0x55), - makecol(0x33,0xff,0x77), - makecol(0x33,0xff,0x99), - makecol(0x33,0xff,0xbb), - makecol(0x33,0xff,0xdd), - makecol(0x33,0xff,0xff), - makecol(0x55,0xff,0x00), - makecol(0x55,0xff,0x33), - makecol(0x55,0xff,0x55), - makecol(0x55,0xff,0x77), - makecol(0x55,0xff,0x99), - makecol(0x55,0xff,0xbb), - makecol(0x55,0xff,0xdd), - makecol(0x55,0xff,0xff), - makecol(0x77,0xff,0x00), - makecol(0x77,0xff,0x33), - makecol(0x77,0xff,0x55), - makecol(0x77,0xff,0x77), - makecol(0x77,0xff,0x99), - makecol(0x77,0xff,0xbb), - makecol(0x77,0xff,0xdd), - makecol(0x77,0xff,0xff), - makecol(0x99,0xff,0x00), - makecol(0x99,0xff,0x33), - makecol(0x99,0xff,0x55), - makecol(0x99,0xff,0x77), - makecol(0x99,0xff,0x99), - makecol(0x99,0xff,0xbb), - makecol(0x99,0xff,0xdd), - makecol(0x99,0xff,0xff), - makecol(0xbb,0xff,0x00), - makecol(0xbb,0xff,0x33), - makecol(0xbb,0xff,0x55), - makecol(0xbb,0xff,0x77), - makecol(0xbb,0xff,0x99), - makecol(0xbb,0xff,0xbb), - makecol(0xbb,0xff,0xdd), - makecol(0xbb,0xff,0xff), - makecol(0xdd,0xff,0x00), - makecol(0xdd,0xff,0x33), - makecol(0xdd,0xff,0x55), - makecol(0xdd,0xff,0x77), - makecol(0xdd,0xff,0x99), - makecol(0xdd,0xff,0xbb), - makecol(0xdd,0xff,0xdd), - makecol(0xdd,0xff,0xff), - makecol(0xff,0xff,0x00), - makecol(0xff,0xff,0x33), - makecol(0xff,0xff,0x55), - makecol(0xff,0xff,0x77), - makecol(0xff,0xff,0x99), - makecol(0xff,0xff,0xbb), - makecol(0xff,0xff,0xdd), - makecol(0xff,0xff,0xff), - }, -/* Palette 3: 3-2-3 truecolour */ - { - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x33), - makecol(0x00,0x00,0x55), - makecol(0x00,0x00,0x77), - makecol(0x00,0x00,0x99), - makecol(0x00,0x00,0xbb), - makecol(0x00,0x00,0xdd), - makecol(0x00,0x00,0xff), - makecol(0x55,0x00,0x00), - makecol(0x55,0x00,0x33), - makecol(0x55,0x00,0x55), - makecol(0x55,0x00,0x77), - makecol(0x55,0x00,0x99), - makecol(0x55,0x00,0xbb), - makecol(0x55,0x00,0xdd), - makecol(0x55,0x00,0xff), - makecol(0xaa,0x00,0x00), - makecol(0xaa,0x00,0x33), - makecol(0xaa,0x00,0x55), - makecol(0xaa,0x00,0x77), - makecol(0xaa,0x00,0x99), - makecol(0xaa,0x00,0xbb), - makecol(0xaa,0x00,0xdd), - makecol(0xaa,0x00,0xff), - makecol(0xff,0x00,0x00), - makecol(0xff,0x00,0x33), - makecol(0xff,0x00,0x55), - makecol(0xff,0x00,0x77), - makecol(0xff,0x00,0x99), - makecol(0xff,0x00,0xbb), - makecol(0xff,0x00,0xdd), - makecol(0xff,0x00,0xff), - makecol(0x00,0x33,0x00), - makecol(0x00,0x33,0x33), - makecol(0x00,0x33,0x55), - makecol(0x00,0x33,0x77), - makecol(0x00,0x33,0x99), - makecol(0x00,0x33,0xbb), - makecol(0x00,0x33,0xdd), - makecol(0x00,0x33,0xff), - makecol(0x55,0x33,0x00), - makecol(0x55,0x33,0x33), - makecol(0x55,0x33,0x55), - makecol(0x55,0x33,0x77), - makecol(0x55,0x33,0x99), - makecol(0x55,0x33,0xbb), - makecol(0x55,0x33,0xdd), - makecol(0x55,0x33,0xff), - makecol(0xaa,0x33,0x00), - makecol(0xaa,0x33,0x33), - makecol(0xaa,0x33,0x55), - makecol(0xaa,0x33,0x77), - makecol(0xaa,0x33,0x99), - makecol(0xaa,0x33,0xbb), - makecol(0xaa,0x33,0xdd), - makecol(0xaa,0x33,0xff), - makecol(0xff,0x33,0x00), - makecol(0xff,0x33,0x33), - makecol(0xff,0x33,0x55), - makecol(0xff,0x33,0x77), - makecol(0xff,0x33,0x99), - makecol(0xff,0x33,0xbb), - makecol(0xff,0x33,0xdd), - makecol(0xff,0x33,0xff), - makecol(0x00,0x55,0x00), - makecol(0x00,0x55,0x33), - makecol(0x00,0x55,0x55), - makecol(0x00,0x55,0x77), - makecol(0x00,0x55,0x99), - makecol(0x00,0x55,0xbb), - makecol(0x00,0x55,0xdd), - makecol(0x00,0x55,0xff), - makecol(0x55,0x55,0x00), - makecol(0x55,0x55,0x33), - makecol(0x55,0x55,0x55), - makecol(0x55,0x55,0x77), - makecol(0x55,0x55,0x99), - makecol(0x55,0x55,0xbb), - makecol(0x55,0x55,0xdd), - makecol(0x55,0x55,0xff), - makecol(0xaa,0x55,0x00), - makecol(0xaa,0x55,0x33), - makecol(0xaa,0x55,0x55), - makecol(0xaa,0x55,0x77), - makecol(0xaa,0x55,0x99), - makecol(0xaa,0x55,0xbb), - makecol(0xaa,0x55,0xdd), - makecol(0xaa,0x55,0xff), - makecol(0xff,0x55,0x00), - makecol(0xff,0x55,0x33), - makecol(0xff,0x55,0x55), - makecol(0xff,0x55,0x77), - makecol(0xff,0x55,0x99), - makecol(0xff,0x55,0xbb), - makecol(0xff,0x55,0xdd), - makecol(0xff,0x55,0xff), - makecol(0x00,0x77,0x00), - makecol(0x00,0x77,0x33), - makecol(0x00,0x77,0x55), - makecol(0x00,0x77,0x77), - makecol(0x00,0x77,0x99), - makecol(0x00,0x77,0xbb), - makecol(0x00,0x77,0xdd), - makecol(0x00,0x77,0xff), - makecol(0x55,0x77,0x00), - makecol(0x55,0x77,0x33), - makecol(0x55,0x77,0x55), - makecol(0x55,0x77,0x77), - makecol(0x55,0x77,0x99), - makecol(0x55,0x77,0xbb), - makecol(0x55,0x77,0xdd), - makecol(0x55,0x77,0xff), - makecol(0xaa,0x77,0x00), - makecol(0xaa,0x77,0x33), - makecol(0xaa,0x77,0x55), - makecol(0xaa,0x77,0x77), - makecol(0xaa,0x77,0x99), - makecol(0xaa,0x77,0xbb), - makecol(0xaa,0x77,0xdd), - makecol(0xaa,0x77,0xff), - makecol(0xff,0x77,0x00), - makecol(0xff,0x77,0x33), - makecol(0xff,0x77,0x55), - makecol(0xff,0x77,0x77), - makecol(0xff,0x77,0x99), - makecol(0xff,0x77,0xbb), - makecol(0xff,0x77,0xdd), - makecol(0xff,0x77,0xff), - makecol(0x00,0x99,0x00), - makecol(0x00,0x99,0x33), - makecol(0x00,0x99,0x55), - makecol(0x00,0x99,0x77), - makecol(0x00,0x99,0x99), - makecol(0x00,0x99,0xbb), - makecol(0x00,0x99,0xdd), - makecol(0x00,0x99,0xff), - makecol(0x55,0x99,0x00), - makecol(0x55,0x99,0x33), - makecol(0x55,0x99,0x55), - makecol(0x55,0x99,0x77), - makecol(0x55,0x99,0x99), - makecol(0x55,0x99,0xbb), - makecol(0x55,0x99,0xdd), - makecol(0x55,0x99,0xff), - makecol(0xaa,0x99,0x00), - makecol(0xaa,0x99,0x33), - makecol(0xaa,0x99,0x55), - makecol(0xaa,0x99,0x77), - makecol(0xaa,0x99,0x99), - makecol(0xaa,0x99,0xbb), - makecol(0xaa,0x99,0xdd), - makecol(0xaa,0x99,0xff), - makecol(0xff,0x99,0x00), - makecol(0xff,0x99,0x33), - makecol(0xff,0x99,0x55), - makecol(0xff,0x99,0x77), - makecol(0xff,0x99,0x99), - makecol(0xff,0x99,0xbb), - makecol(0xff,0x99,0xdd), - makecol(0xff,0x99,0xff), - makecol(0x00,0xbb,0x00), - makecol(0x00,0xbb,0x33), - makecol(0x00,0xbb,0x55), - makecol(0x00,0xbb,0x77), - makecol(0x00,0xbb,0x99), - makecol(0x00,0xbb,0xbb), - makecol(0x00,0xbb,0xdd), - makecol(0x00,0xbb,0xff), - makecol(0x55,0xbb,0x00), - makecol(0x55,0xbb,0x33), - makecol(0x55,0xbb,0x55), - makecol(0x55,0xbb,0x77), - makecol(0x55,0xbb,0x99), - makecol(0x55,0xbb,0xbb), - makecol(0x55,0xbb,0xdd), - makecol(0x55,0xbb,0xff), - makecol(0xaa,0xbb,0x00), - makecol(0xaa,0xbb,0x33), - makecol(0xaa,0xbb,0x55), - makecol(0xaa,0xbb,0x77), - makecol(0xaa,0xbb,0x99), - makecol(0xaa,0xbb,0xbb), - makecol(0xaa,0xbb,0xdd), - makecol(0xaa,0xbb,0xff), - makecol(0xff,0xbb,0x00), - makecol(0xff,0xbb,0x33), - makecol(0xff,0xbb,0x55), - makecol(0xff,0xbb,0x77), - makecol(0xff,0xbb,0x99), - makecol(0xff,0xbb,0xbb), - makecol(0xff,0xbb,0xdd), - makecol(0xff,0xbb,0xff), - makecol(0x00,0xdd,0x00), - makecol(0x00,0xdd,0x33), - makecol(0x00,0xdd,0x55), - makecol(0x00,0xdd,0x77), - makecol(0x00,0xdd,0x99), - makecol(0x00,0xdd,0xbb), - makecol(0x00,0xdd,0xdd), - makecol(0x00,0xdd,0xff), - makecol(0x55,0xdd,0x00), - makecol(0x55,0xdd,0x33), - makecol(0x55,0xdd,0x55), - makecol(0x55,0xdd,0x77), - makecol(0x55,0xdd,0x99), - makecol(0x55,0xdd,0xbb), - makecol(0x55,0xdd,0xdd), - makecol(0x55,0xdd,0xff), - makecol(0xaa,0xdd,0x00), - makecol(0xaa,0xdd,0x33), - makecol(0xaa,0xdd,0x55), - makecol(0xaa,0xdd,0x77), - makecol(0xaa,0xdd,0x99), - makecol(0xaa,0xdd,0xbb), - makecol(0xaa,0xdd,0xdd), - makecol(0xaa,0xdd,0xff), - makecol(0xff,0xdd,0x00), - makecol(0xff,0xdd,0x33), - makecol(0xff,0xdd,0x55), - makecol(0xff,0xdd,0x77), - makecol(0xff,0xdd,0x99), - makecol(0xff,0xdd,0xbb), - makecol(0xff,0xdd,0xdd), - makecol(0xff,0xdd,0xff), - makecol(0x00,0xff,0x00), - makecol(0x00,0xff,0x33), - makecol(0x00,0xff,0x55), - makecol(0x00,0xff,0x77), - makecol(0x00,0xff,0x99), - makecol(0x00,0xff,0xbb), - makecol(0x00,0xff,0xdd), - makecol(0x00,0xff,0xff), - makecol(0x55,0xff,0x00), - makecol(0x55,0xff,0x33), - makecol(0x55,0xff,0x55), - makecol(0x55,0xff,0x77), - makecol(0x55,0xff,0x99), - makecol(0x55,0xff,0xbb), - makecol(0x55,0xff,0xdd), - makecol(0x55,0xff,0xff), - makecol(0xaa,0xff,0x00), - makecol(0xaa,0xff,0x33), - makecol(0xaa,0xff,0x55), - makecol(0xaa,0xff,0x77), - makecol(0xaa,0xff,0x99), - makecol(0xaa,0xff,0xbb), - makecol(0xaa,0xff,0xdd), - makecol(0xaa,0xff,0xff), - makecol(0xff,0xff,0x00), - makecol(0xff,0xff,0x33), - makecol(0xff,0xff,0x55), - makecol(0xff,0xff,0x77), - makecol(0xff,0xff,0x99), - makecol(0xff,0xff,0xbb), - makecol(0xff,0xff,0xdd), - makecol(0xff,0xff,0xff), - }, -/* Palette 4: 3-3-2 truecolour */ - { - makecol(0x00, 0x00, 0x00), - makecol(0x00, 0x00, 0x55), - makecol(0x00, 0x00, 0xaa), - makecol(0x00, 0x00, 0xff), - makecol(0x00, 0x33, 0x00), - makecol(0x00, 0x33, 0x55), - makecol(0x00, 0x33, 0xaa), - makecol(0x00, 0x33, 0xff), - makecol(0x00, 0x55, 0x00), - makecol(0x00, 0x55, 0x55), - makecol(0x00, 0x55, 0xaa), - makecol(0x00, 0x55, 0xff), - makecol(0x00, 0x77, 0x00), - makecol(0x00, 0x77, 0x55), - makecol(0x00, 0x77, 0xaa), - makecol(0x00, 0x77, 0xff), - makecol(0x00, 0x99, 0x00), - makecol(0x00, 0x99, 0x55), - makecol(0x00, 0x99, 0xaa), - makecol(0x00, 0x99, 0xff), - makecol(0x00, 0xbb, 0x00), - makecol(0x00, 0xbb, 0x55), - makecol(0x00, 0xbb, 0xaa), - makecol(0x00, 0xbb, 0xff), - makecol(0x00, 0xdd, 0x00), - makecol(0x00, 0xdd, 0x55), - makecol(0x00, 0xdd, 0xaa), - makecol(0x00, 0xdd, 0xff), - makecol(0x00, 0xff, 0x00), - makecol(0x00, 0xff, 0x55), - makecol(0x00, 0xff, 0xaa), - makecol(0x00, 0xff, 0xff), - makecol(0x33, 0x00, 0x00), - makecol(0x33, 0x00, 0x55), - makecol(0x33, 0x00, 0xaa), - makecol(0x33, 0x00, 0xff), - makecol(0x33, 0x33, 0x00), - makecol(0x33, 0x33, 0x55), - makecol(0x33, 0x33, 0xaa), - makecol(0x33, 0x33, 0xff), - makecol(0x33, 0x55, 0x00), - makecol(0x33, 0x55, 0x55), - makecol(0x33, 0x55, 0xaa), - makecol(0x33, 0x55, 0xff), - makecol(0x33, 0x77, 0x00), - makecol(0x33, 0x77, 0x55), - makecol(0x33, 0x77, 0xaa), - makecol(0x33, 0x77, 0xff), - makecol(0x33, 0x99, 0x00), - makecol(0x33, 0x99, 0x55), - makecol(0x33, 0x99, 0xaa), - makecol(0x33, 0x99, 0xff), - makecol(0x33, 0xbb, 0x00), - makecol(0x33, 0xbb, 0x55), - makecol(0x33, 0xbb, 0xaa), - makecol(0x33, 0xbb, 0xff), - makecol(0x33, 0xdd, 0x00), - makecol(0x33, 0xdd, 0x55), - makecol(0x33, 0xdd, 0xaa), - makecol(0x33, 0xdd, 0xff), - makecol(0x33, 0xff, 0x00), - makecol(0x33, 0xff, 0x55), - makecol(0x33, 0xff, 0xaa), - makecol(0x33, 0xff, 0xff), - makecol(0x55, 0x00, 0x00), - makecol(0x55, 0x00, 0x55), - makecol(0x55, 0x00, 0xaa), - makecol(0x55, 0x00, 0xff), - makecol(0x55, 0x33, 0x00), - makecol(0x55, 0x33, 0x55), - makecol(0x55, 0x33, 0xaa), - makecol(0x55, 0x33, 0xff), - makecol(0x55, 0x55, 0x00), - makecol(0x55, 0x55, 0x55), - makecol(0x55, 0x55, 0xaa), - makecol(0x55, 0x55, 0xff), - makecol(0x55, 0x77, 0x00), - makecol(0x55, 0x77, 0x55), - makecol(0x55, 0x77, 0xaa), - makecol(0x55, 0x77, 0xff), - makecol(0x55, 0x99, 0x00), - makecol(0x55, 0x99, 0x55), - makecol(0x55, 0x99, 0xaa), - makecol(0x55, 0x99, 0xff), - makecol(0x55, 0xbb, 0x00), - makecol(0x55, 0xbb, 0x55), - makecol(0x55, 0xbb, 0xaa), - makecol(0x55, 0xbb, 0xff), - makecol(0x55, 0xdd, 0x00), - makecol(0x55, 0xdd, 0x55), - makecol(0x55, 0xdd, 0xaa), - makecol(0x55, 0xdd, 0xff), - makecol(0x55, 0xff, 0x00), - makecol(0x55, 0xff, 0x55), - makecol(0x55, 0xff, 0xaa), - makecol(0x55, 0xff, 0xff), - makecol(0x77, 0x00, 0x00), - makecol(0x77, 0x00, 0x55), - makecol(0x77, 0x00, 0xaa), - makecol(0x77, 0x00, 0xff), - makecol(0x77, 0x33, 0x00), - makecol(0x77, 0x33, 0x55), - makecol(0x77, 0x33, 0xaa), - makecol(0x77, 0x33, 0xff), - makecol(0x77, 0x55, 0x00), - makecol(0x77, 0x55, 0x55), - makecol(0x77, 0x55, 0xaa), - makecol(0x77, 0x55, 0xff), - makecol(0x77, 0x77, 0x00), - makecol(0x77, 0x77, 0x55), - makecol(0x77, 0x77, 0xaa), - makecol(0x77, 0x77, 0xff), - makecol(0x77, 0x99, 0x00), - makecol(0x77, 0x99, 0x55), - makecol(0x77, 0x99, 0xaa), - makecol(0x77, 0x99, 0xff), - makecol(0x77, 0xbb, 0x00), - makecol(0x77, 0xbb, 0x55), - makecol(0x77, 0xbb, 0xaa), - makecol(0x77, 0xbb, 0xff), - makecol(0x77, 0xdd, 0x00), - makecol(0x77, 0xdd, 0x55), - makecol(0x77, 0xdd, 0xaa), - makecol(0x77, 0xdd, 0xff), - makecol(0x77, 0xff, 0x00), - makecol(0x77, 0xff, 0x55), - makecol(0x77, 0xff, 0xaa), - makecol(0x77, 0xff, 0xff), - makecol(0x99, 0x00, 0x00), - makecol(0x99, 0x00, 0x55), - makecol(0x99, 0x00, 0xaa), - makecol(0x99, 0x00, 0xff), - makecol(0x99, 0x33, 0x00), - makecol(0x99, 0x33, 0x55), - makecol(0x99, 0x33, 0xaa), - makecol(0x99, 0x33, 0xff), - makecol(0x99, 0x55, 0x00), - makecol(0x99, 0x55, 0x55), - makecol(0x99, 0x55, 0xaa), - makecol(0x99, 0x55, 0xff), - makecol(0x99, 0x77, 0x00), - makecol(0x99, 0x77, 0x55), - makecol(0x99, 0x77, 0xaa), - makecol(0x99, 0x77, 0xff), - makecol(0x99, 0x99, 0x00), - makecol(0x99, 0x99, 0x55), - makecol(0x99, 0x99, 0xaa), - makecol(0x99, 0x99, 0xff), - makecol(0x99, 0xbb, 0x00), - makecol(0x99, 0xbb, 0x55), - makecol(0x99, 0xbb, 0xaa), - makecol(0x99, 0xbb, 0xff), - makecol(0x99, 0xdd, 0x00), - makecol(0x99, 0xdd, 0x55), - makecol(0x99, 0xdd, 0xaa), - makecol(0x99, 0xdd, 0xff), - makecol(0x99, 0xff, 0x00), - makecol(0x99, 0xff, 0x55), - makecol(0x99, 0xff, 0xaa), - makecol(0x99, 0xff, 0xff), - makecol(0xbb, 0x00, 0x00), - makecol(0xbb, 0x00, 0x55), - makecol(0xbb, 0x00, 0xaa), - makecol(0xbb, 0x00, 0xff), - makecol(0xbb, 0x33, 0x00), - makecol(0xbb, 0x33, 0x55), - makecol(0xbb, 0x33, 0xaa), - makecol(0xbb, 0x33, 0xff), - makecol(0xbb, 0x55, 0x00), - makecol(0xbb, 0x55, 0x55), - makecol(0xbb, 0x55, 0xaa), - makecol(0xbb, 0x55, 0xff), - makecol(0xbb, 0x77, 0x00), - makecol(0xbb, 0x77, 0x55), - makecol(0xbb, 0x77, 0xaa), - makecol(0xbb, 0x77, 0xff), - makecol(0xbb, 0x99, 0x00), - makecol(0xbb, 0x99, 0x55), - makecol(0xbb, 0x99, 0xaa), - makecol(0xbb, 0x99, 0xff), - makecol(0xbb, 0xbb, 0x00), - makecol(0xbb, 0xbb, 0x55), - makecol(0xbb, 0xbb, 0xaa), - makecol(0xbb, 0xbb, 0xff), - makecol(0xbb, 0xdd, 0x00), - makecol(0xbb, 0xdd, 0x55), - makecol(0xbb, 0xdd, 0xaa), - makecol(0xbb, 0xdd, 0xff), - makecol(0xbb, 0xff, 0x00), - makecol(0xbb, 0xff, 0x55), - makecol(0xbb, 0xff, 0xaa), - makecol(0xbb, 0xff, 0xff), - makecol(0xdd, 0x00, 0x00), - makecol(0xdd, 0x00, 0x55), - makecol(0xdd, 0x00, 0xaa), - makecol(0xdd, 0x00, 0xff), - makecol(0xdd, 0x33, 0x00), - makecol(0xdd, 0x33, 0x55), - makecol(0xdd, 0x33, 0xaa), - makecol(0xdd, 0x33, 0xff), - makecol(0xdd, 0x55, 0x00), - makecol(0xdd, 0x55, 0x55), - makecol(0xdd, 0x55, 0xaa), - makecol(0xdd, 0x55, 0xff), - makecol(0xdd, 0x77, 0x00), - makecol(0xdd, 0x77, 0x55), - makecol(0xdd, 0x77, 0xaa), - makecol(0xdd, 0x77, 0xff), - makecol(0xdd, 0x99, 0x00), - makecol(0xdd, 0x99, 0x55), - makecol(0xdd, 0x99, 0xaa), - makecol(0xdd, 0x99, 0xff), - makecol(0xdd, 0xbb, 0x00), - makecol(0xdd, 0xbb, 0x55), - makecol(0xdd, 0xbb, 0xaa), - makecol(0xdd, 0xbb, 0xff), - makecol(0xdd, 0xdd, 0x00), - makecol(0xdd, 0xdd, 0x55), - makecol(0xdd, 0xdd, 0xaa), - makecol(0xdd, 0xdd, 0xff), - makecol(0xdd, 0xff, 0x00), - makecol(0xdd, 0xff, 0x55), - makecol(0xdd, 0xff, 0xaa), - makecol(0xdd, 0xff, 0xff), - makecol(0xff, 0x00, 0x00), - makecol(0xff, 0x00, 0x55), - makecol(0xff, 0x00, 0xaa), - makecol(0xff, 0x00, 0xff), - makecol(0xff, 0x33, 0x00), - makecol(0xff, 0x33, 0x55), - makecol(0xff, 0x33, 0xaa), - makecol(0xff, 0x33, 0xff), - makecol(0xff, 0x55, 0x00), - makecol(0xff, 0x55, 0x55), - makecol(0xff, 0x55, 0xaa), - makecol(0xff, 0x55, 0xff), - makecol(0xff, 0x77, 0x00), - makecol(0xff, 0x77, 0x55), - makecol(0xff, 0x77, 0xaa), - makecol(0xff, 0x77, 0xff), - makecol(0xff, 0x99, 0x00), - makecol(0xff, 0x99, 0x55), - makecol(0xff, 0x99, 0xaa), - makecol(0xff, 0x99, 0xff), - makecol(0xff, 0xbb, 0x00), - makecol(0xff, 0xbb, 0x55), - makecol(0xff, 0xbb, 0xaa), - makecol(0xff, 0xbb, 0xff), - makecol(0xff, 0xdd, 0x00), - makecol(0xff, 0xdd, 0x55), - makecol(0xff, 0xdd, 0xaa), - makecol(0xff, 0xdd, 0xff), - makecol(0xff, 0xff, 0x00), - makecol(0xff, 0xff, 0x55), - makecol(0xff, 0xff, 0xaa), - makecol(0xff, 0xff, 0xff), - }, -/* Palette 5: 6x6x6 colour cube */ - { - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x33), - makecol(0x00,0x00,0x66), - makecol(0x00,0x00,0x99), - makecol(0x00,0x00,0xcc), - makecol(0x00,0x00,0xff), - makecol(0x33,0x00,0x00), - makecol(0x33,0x00,0x33), - makecol(0x33,0x00,0x66), - makecol(0x33,0x00,0x99), - makecol(0x33,0x00,0xcc), - makecol(0x33,0x00,0xff), - makecol(0x66,0x00,0x00), - makecol(0x66,0x00,0x33), - makecol(0x66,0x00,0x66), - makecol(0x66,0x00,0x99), - makecol(0x66,0x00,0xcc), - makecol(0x66,0x00,0xff), - makecol(0x99,0x00,0x00), - makecol(0x99,0x00,0x33), - makecol(0x99,0x00,0x66), - makecol(0x99,0x00,0x99), - makecol(0x99,0x00,0xcc), - makecol(0x99,0x00,0xff), - makecol(0xcc,0x00,0x00), - makecol(0xcc,0x00,0x33), - makecol(0xcc,0x00,0x66), - makecol(0xcc,0x00,0x99), - makecol(0xcc,0x00,0xcc), - makecol(0xcc,0x00,0xff), - makecol(0xff,0x00,0x00), - makecol(0xff,0x00,0x33), - makecol(0xff,0x00,0x66), - makecol(0xff,0x00,0x99), - makecol(0xff,0x00,0xcc), - makecol(0xff,0x00,0xff), - makecol(0x00,0x33,0x00), - makecol(0x00,0x33,0x33), - makecol(0x00,0x33,0x66), - makecol(0x00,0x33,0x99), - makecol(0x00,0x33,0xcc), - makecol(0x00,0x33,0xff), - makecol(0x33,0x33,0x00), - makecol(0x33,0x33,0x33), - makecol(0x33,0x33,0x66), - makecol(0x33,0x33,0x99), - makecol(0x33,0x33,0xcc), - makecol(0x33,0x33,0xff), - makecol(0x66,0x33,0x00), - makecol(0x66,0x33,0x33), - makecol(0x66,0x33,0x66), - makecol(0x66,0x33,0x99), - makecol(0x66,0x33,0xcc), - makecol(0x66,0x33,0xff), - makecol(0x99,0x33,0x00), - makecol(0x99,0x33,0x33), - makecol(0x99,0x33,0x66), - makecol(0x99,0x33,0x99), - makecol(0x99,0x33,0xcc), - makecol(0x99,0x33,0xff), - makecol(0xcc,0x33,0x00), - makecol(0xcc,0x33,0x33), - makecol(0xcc,0x33,0x66), - makecol(0xcc,0x33,0x99), - makecol(0xcc,0x33,0xcc), - makecol(0xcc,0x33,0xff), - makecol(0xff,0x33,0x00), - makecol(0xff,0x33,0x33), - makecol(0xff,0x33,0x66), - makecol(0xff,0x33,0x99), - makecol(0xff,0x33,0xcc), - makecol(0xff,0x33,0xff), - makecol(0x00,0x66,0x00), - makecol(0x00,0x66,0x33), - makecol(0x00,0x66,0x66), - makecol(0x00,0x66,0x99), - makecol(0x00,0x66,0xcc), - makecol(0x00,0x66,0xff), - makecol(0x33,0x66,0x00), - makecol(0x33,0x66,0x33), - makecol(0x33,0x66,0x66), - makecol(0x33,0x66,0x99), - makecol(0x33,0x66,0xcc), - makecol(0x33,0x66,0xff), - makecol(0x66,0x66,0x00), - makecol(0x66,0x66,0x33), - makecol(0x66,0x66,0x66), - makecol(0x66,0x66,0x99), - makecol(0x66,0x66,0xcc), - makecol(0x66,0x66,0xff), - makecol(0x99,0x66,0x00), - makecol(0x99,0x66,0x33), - makecol(0x99,0x66,0x66), - makecol(0x99,0x66,0x99), - makecol(0x99,0x66,0xcc), - makecol(0x99,0x66,0xff), - makecol(0xcc,0x66,0x00), - makecol(0xcc,0x66,0x33), - makecol(0xcc,0x66,0x66), - makecol(0xcc,0x66,0x99), - makecol(0xcc,0x66,0xcc), - makecol(0xcc,0x66,0xff), - makecol(0xff,0x66,0x00), - makecol(0xff,0x66,0x33), - makecol(0xff,0x66,0x66), - makecol(0xff,0x66,0x99), - makecol(0xff,0x66,0xcc), - makecol(0xff,0x66,0xff), - makecol(0x00,0x99,0x00), - makecol(0x00,0x99,0x33), - makecol(0x00,0x99,0x66), - makecol(0x00,0x99,0x99), - makecol(0x00,0x99,0xcc), - makecol(0x00,0x99,0xff), - makecol(0x33,0x99,0x00), - makecol(0x33,0x99,0x33), - makecol(0x33,0x99,0x66), - makecol(0x33,0x99,0x99), - makecol(0x33,0x99,0xcc), - makecol(0x33,0x99,0xff), - makecol(0x66,0x99,0x00), - makecol(0x66,0x99,0x33), - makecol(0x66,0x99,0x66), - makecol(0x66,0x99,0x99), - makecol(0x66,0x99,0xcc), - makecol(0x66,0x99,0xff), - makecol(0x99,0x99,0x00), - makecol(0x99,0x99,0x33), - makecol(0x99,0x99,0x66), - makecol(0x99,0x99,0x99), - makecol(0x99,0x99,0xcc), - makecol(0x99,0x99,0xff), - makecol(0xcc,0x99,0x00), - makecol(0xcc,0x99,0x33), - makecol(0xcc,0x99,0x66), - makecol(0xcc,0x99,0x99), - makecol(0xcc,0x99,0xcc), - makecol(0xcc,0x99,0xff), - makecol(0xff,0x99,0x00), - makecol(0xff,0x99,0x33), - makecol(0xff,0x99,0x66), - makecol(0xff,0x99,0x99), - makecol(0xff,0x99,0xcc), - makecol(0xff,0x99,0xff), - makecol(0x00,0xcc,0x00), - makecol(0x00,0xcc,0x33), - makecol(0x00,0xcc,0x66), - makecol(0x00,0xcc,0x99), - makecol(0x00,0xcc,0xcc), - makecol(0x00,0xcc,0xff), - makecol(0x33,0xcc,0x00), - makecol(0x33,0xcc,0x33), - makecol(0x33,0xcc,0x66), - makecol(0x33,0xcc,0x99), - makecol(0x33,0xcc,0xcc), - makecol(0x33,0xcc,0xff), - makecol(0x66,0xcc,0x00), - makecol(0x66,0xcc,0x33), - makecol(0x66,0xcc,0x66), - makecol(0x66,0xcc,0x99), - makecol(0x66,0xcc,0xcc), - makecol(0x66,0xcc,0xff), - makecol(0x99,0xcc,0x00), - makecol(0x99,0xcc,0x33), - makecol(0x99,0xcc,0x66), - makecol(0x99,0xcc,0x99), - makecol(0x99,0xcc,0xcc), - makecol(0x99,0xcc,0xff), - makecol(0xcc,0xcc,0x00), - makecol(0xcc,0xcc,0x33), - makecol(0xcc,0xcc,0x66), - makecol(0xcc,0xcc,0x99), - makecol(0xcc,0xcc,0xcc), - makecol(0xcc,0xcc,0xff), - makecol(0xff,0xcc,0x00), - makecol(0xff,0xcc,0x33), - makecol(0xff,0xcc,0x66), - makecol(0xff,0xcc,0x99), - makecol(0xff,0xcc,0xcc), - makecol(0xff,0xcc,0xff), - makecol(0x00,0xff,0x00), - makecol(0x00,0xff,0x33), - makecol(0x00,0xff,0x66), - makecol(0x00,0xff,0x99), - makecol(0x00,0xff,0xcc), - makecol(0x00,0xff,0xff), - makecol(0x33,0xff,0x00), - makecol(0x33,0xff,0x33), - makecol(0x33,0xff,0x66), - makecol(0x33,0xff,0x99), - makecol(0x33,0xff,0xcc), - makecol(0x33,0xff,0xff), - makecol(0x66,0xff,0x00), - makecol(0x66,0xff,0x33), - makecol(0x66,0xff,0x66), - makecol(0x66,0xff,0x99), - makecol(0x66,0xff,0xcc), - makecol(0x66,0xff,0xff), - makecol(0x99,0xff,0x00), - makecol(0x99,0xff,0x33), - makecol(0x99,0xff,0x66), - makecol(0x99,0xff,0x99), - makecol(0x99,0xff,0xcc), - makecol(0x99,0xff,0xff), - makecol(0xcc,0xff,0x00), - makecol(0xcc,0xff,0x33), - makecol(0xcc,0xff,0x66), - makecol(0xcc,0xff,0x99), - makecol(0xcc,0xff,0xcc), - makecol(0xcc,0xff,0xff), - makecol(0xff,0xff,0x00), - makecol(0xff,0xff,0x33), - makecol(0xff,0xff,0x66), - makecol(0xff,0xff,0x99), - makecol(0xff,0xff,0xcc), - makecol(0xff,0xff,0xff), - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x00), - makecol(0x00,0x00,0x00), - }, +{ + makecol(0x00, 0x00, 0x00), makecol(0x11, 0x11, 0x11), makecol(0x22, 0x22, 0x22), makecol(0x33, 0x33, 0x33), + makecol(0x44, 0x44, 0x44), makecol(0x55, 0x55, 0x55), makecol(0x66, 0x66, 0x66), makecol(0x77, 0x77, 0x77), + makecol(0x88, 0x88, 0x88), makecol(0x99, 0x99, 0x99), makecol(0xaa, 0xaa, 0xaa), makecol(0xbb, 0xbb, 0xbb), + makecol(0xcc, 0xcc, 0xcc), makecol(0xdd, 0xdd, 0xdd), makecol(0xee, 0xee, 0xee), makecol(0xff, 0xff, 0xff), + makecol(0x00, 0x00, 0x00), makecol(0x00, 0x22, 0x00), makecol(0x00, 0x44, 0x00), makecol(0x00, 0x66, 0x00), + makecol(0x00, 0x88, 0x00), makecol(0x00, 0xaa, 0x00), makecol(0x00, 0xcc, 0x00), makecol(0x00, 0xee, 0x00), + makecol(0x00, 0xff, 0x00), makecol(0x22, 0xff, 0x22), makecol(0x44, 0xff, 0x44), makecol(0x66, 0xff, 0x66), + makecol(0x88, 0xff, 0x88), makecol(0xaa, 0xff, 0xaa), makecol(0xcc, 0xff, 0xcc), makecol(0xee, 0xff, 0xee), + makecol(0x00, 0x00, 0x00), makecol(0x00, 0x22, 0x11), makecol(0x00, 0x44, 0x22), makecol(0x00, 0x66, 0x33), + makecol(0x00, 0x88, 0x44), makecol(0x00, 0xaa, 0x55), makecol(0x00, 0xcc, 0x66), makecol(0x00, 0xee, 0x77), + makecol(0x00, 0xff, 0x88), makecol(0x22, 0xff, 0x99), makecol(0x44, 0xff, 0xaa), makecol(0x66, 0xff, 0xbb), + makecol(0x88, 0xff, 0xcc), makecol(0xaa, 0xff, 0xdd), makecol(0xcc, 0xff, 0xee), makecol(0xee, 0xff, 0xff), + makecol(0x00, 0x00, 0x00), makecol(0x00, 0x22, 0x22), makecol(0x00, 0x44, 0x44), makecol(0x00, 0x66, 0x66), + makecol(0x00, 0x88, 0x88), makecol(0x00, 0xaa, 0xaa), makecol(0x00, 0xcc, 0xcc), makecol(0x00, 0xee, 0xee), + makecol(0x00, 0xff, 0xff), makecol(0x22, 0xff, 0xff), makecol(0x44, 0xff, 0xff), makecol(0x66, 0xff, 0xff), + makecol(0x88, 0xff, 0xff), makecol(0xaa, 0xff, 0xff), makecol(0xcc, 0xff, 0xff), makecol(0xee, 0xff, 0xff), + makecol(0x00, 0x00, 0x00), makecol(0x00, 0x11, 0x22), makecol(0x00, 0x22, 0x44), makecol(0x00, 0x33, 0x66), + makecol(0x00, 0x44, 0x88), makecol(0x00, 0x55, 0xaa), makecol(0x00, 0x66, 0xcc), makecol(0x00, 0x77, 0xee), + makecol(0x00, 0x88, 0xff), makecol(0x22, 0x99, 0xff), makecol(0x44, 0xaa, 0xff), makecol(0x66, 0xbb, 0xff), + makecol(0x88, 0xcc, 0xff), makecol(0xaa, 0xdd, 0xff), makecol(0xcc, 0xee, 0xff), makecol(0xee, 0xff, 0xff), + makecol(0x00, 0x00, 0x00), makecol(0x00, 0x00, 0x22), makecol(0x00, 0x00, 0x44), makecol(0x00, 0x00, 0x66), + makecol(0x00, 0x00, 0x88), makecol(0x00, 0x00, 0xaa), makecol(0x00, 0x00, 0xcc), makecol(0x00, 0x00, 0xee), + makecol(0x00, 0x00, 0xff), makecol(0x22, 0x22, 0xff), makecol(0x44, 0x44, 0xff), makecol(0x66, 0x66, 0xff), + makecol(0x88, 0x88, 0xff), makecol(0xaa, 0xaa, 0xff), makecol(0xcc, 0xcc, 0xff), makecol(0xee, 0xee, 0xff), + makecol(0x00, 0x00, 0x00), makecol(0x11, 0x00, 0x22), makecol(0x22, 0x00, 0x44), makecol(0x33, 0x00, 0x66), + makecol(0x44, 0x00, 0x88), makecol(0x55, 0x00, 0xaa), makecol(0x66, 0x00, 0xcc), makecol(0x77, 0x00, 0xee), + makecol(0x88, 0x00, 0xff), makecol(0x99, 0x22, 0xff), makecol(0xaa, 0x44, 0xff), makecol(0xbb, 0x66, 0xff), + makecol(0xcc, 0x88, 0xff), makecol(0xdd, 0xaa, 0xff), makecol(0xee, 0xcc, 0xff), makecol(0xff, 0xee, 0xff), + makecol(0x00, 0x00, 0x00), makecol(0x22, 0x00, 0x22), makecol(0x44, 0x00, 0x44), makecol(0x66, 0x00, 0x66), + makecol(0x88, 0x00, 0x88), makecol(0xaa, 0x00, 0xaa), makecol(0xcc, 0x00, 0xcc), makecol(0xee, 0x00, 0xee), + makecol(0xff, 0x00, 0xff), makecol(0xff, 0x22, 0xff), makecol(0xff, 0x44, 0xff), makecol(0xff, 0x66, 0xff), + makecol(0xff, 0x88, 0xff), makecol(0xff, 0xaa, 0xff), makecol(0xff, 0xcc, 0xff), makecol(0xff, 0xee, 0xff), + makecol(0x00, 0x00, 0x00), makecol(0x22, 0x00, 0x11), makecol(0x44, 0x00, 0x22), makecol(0x66, 0x00, 0x33), + makecol(0x88, 0x00, 0x44), makecol(0xaa, 0x00, 0x55), makecol(0xcc, 0x00, 0x66), makecol(0xee, 0x00, 0x77), + makecol(0xff, 0x00, 0x88), makecol(0xff, 0x22, 0x99), makecol(0xff, 0x44, 0xaa), makecol(0xff, 0x66, 0xbb), + makecol(0xff, 0x88, 0xcc), makecol(0xff, 0xaa, 0xdd), makecol(0xff, 0xcc, 0xee), makecol(0xff, 0xee, 0xff), + makecol(0x00, 0x00, 0x00), makecol(0x22, 0x00, 0x00), makecol(0x44, 0x00, 0x00), makecol(0x66, 0x00, 0x00), + makecol(0x88, 0x00, 0x00), makecol(0xaa, 0x00, 0x00), makecol(0xcc, 0x00, 0x00), makecol(0xee, 0x00, 0x00), + makecol(0xff, 0x00, 0x00), makecol(0xff, 0x22, 0x22), makecol(0xff, 0x44, 0x44), makecol(0xff, 0x66, 0x66), + makecol(0xff, 0x88, 0x88), makecol(0xff, 0xaa, 0xaa), makecol(0xff, 0xcc, 0xcc), makecol(0xff, 0xee, 0xee), + makecol(0x00, 0x00, 0x00), makecol(0x22, 0x11, 0x00), makecol(0x44, 0x22, 0x00), makecol(0x66, 0x33, 0x00), + makecol(0x88, 0x44, 0x00), makecol(0xaa, 0x55, 0x00), makecol(0xcc, 0x66, 0x00), makecol(0xee, 0x77, 0x00), + makecol(0xff, 0x88, 0x00), makecol(0xff, 0x99, 0x22), makecol(0xff, 0xaa, 0x44), makecol(0xff, 0xbb, 0x66), + makecol(0xff, 0xcc, 0x88), makecol(0xff, 0xdd, 0xaa), makecol(0xff, 0xee, 0xcc), makecol(0xff, 0xff, 0xee), + makecol(0x00, 0x00, 0x00), makecol(0x22, 0x22, 0x00), makecol(0x44, 0x44, 0x00), makecol(0x66, 0x66, 0x00), + makecol(0x88, 0x88, 0x00), makecol(0xaa, 0xaa, 0x00), makecol(0xcc, 0xcc, 0x00), makecol(0xee, 0xee, 0x00), + makecol(0xff, 0xff, 0x00), makecol(0xff, 0xff, 0x22), makecol(0xff, 0xff, 0x44), makecol(0xff, 0xff, 0x66), + makecol(0xff, 0xff, 0x88), makecol(0xff, 0xff, 0xaa), makecol(0xff, 0xff, 0xcc), makecol(0xff, 0xff, 0xee), + makecol(0x00, 0x00, 0x00), makecol(0x11, 0x22, 0x00), makecol(0x22, 0x44, 0x00), makecol(0x33, 0x66, 0x00), + makecol(0x44, 0x88, 0x00), makecol(0x55, 0xaa, 0x00), makecol(0x66, 0xcc, 0x00), makecol(0x77, 0xee, 0x00), + makecol(0x88, 0xff, 0x00), makecol(0x99, 0xff, 0x22), makecol(0xaa, 0xff, 0x44), makecol(0xbb, 0xff, 0x66), + makecol(0xcc, 0xff, 0x88), makecol(0xdd, 0xff, 0xaa), makecol(0xee, 0xff, 0xcc), makecol(0xff, 0xff, 0xee), + makecol(0x00, 0x00, 0x00), makecol(0x00, 0x11, 0x00), makecol(0x11, 0x33, 0x11), makecol(0x11, 0x44, 0x11), + makecol(0x22, 0x66, 0x22), makecol(0x22, 0x77, 0x22), makecol(0x33, 0x99, 0x33), makecol(0x33, 0xaa, 0x33), + makecol(0x44, 0xcc, 0x44), makecol(0x55, 0xcc, 0x55), makecol(0x77, 0xdd, 0x77), makecol(0x88, 0xdd, 0x88), + makecol(0xaa, 0xee, 0xaa), makecol(0xbb, 0xee, 0xbb), makecol(0xdd, 0xff, 0xdd), makecol(0xee, 0xff, 0xee), + makecol(0x00, 0x00, 0x00), makecol(0x11, 0x00, 0x00), makecol(0x33, 0x11, 0x11), makecol(0x44, 0x11, 0x11), + makecol(0x66, 0x22, 0x22), makecol(0x77, 0x22, 0x22), makecol(0x99, 0x33, 0x33), makecol(0xaa, 0x33, 0x33), + makecol(0xcc, 0x44, 0x44), makecol(0xcc, 0x55, 0x55), makecol(0xdd, 0x77, 0x77), makecol(0xdd, 0x88, 0x88), + makecol(0xee, 0xaa, 0xaa), makecol(0xee, 0xbb, 0xbb), makecol(0xff, 0xdd, 0xdd), makecol(0xff, 0xee, 0xee), + makecol(0x00, 0x00, 0x00), makecol(0x00, 0x00, 0x11), makecol(0x11, 0x11, 0x33), makecol(0x11, 0x11, 0x44), + makecol(0x22, 0x22, 0x66), makecol(0x22, 0x22, 0x77), makecol(0x33, 0x33, 0x99), makecol(0x33, 0x33, 0xaa), + makecol(0x44, 0x44, 0xcc), makecol(0x55, 0x55, 0xcc), makecol(0x77, 0x77, 0xdd), makecol(0x88, 0x88, 0xdd), + makecol(0xaa, 0xaa, 0xee), makecol(0xbb, 0xbb, 0xee), makecol(0xdd, 0xdd, 0xff), makecol(0xee, 0xee, 0xff), +}, + /* Palette 1: 16-colour palette */ + { + makecol(0x88, 0x66, 0xdd), makecol(0x00, 0x00, 0x00), makecol(0x44, 0x77, 0x22), makecol(0x77, 0xaa, 0x44), + makecol(0x00, 0x77, 0x00), makecol(0x00, 0xff, 0x00), makecol(0x77, 0xff, 0x00), makecol(0xff, 0xff, 0x00), + makecol(0xff, 0xaa, 0x00), makecol(0xff, 0x00, 0x00), makecol(0x77, 0x00, 0x00), makecol(0x77, 0x00, 0x77), + makecol(0x00, 0x00, 0x77), makecol(0x99, 0xee, 0x66), makecol(0x77, 0x77, 0x77), makecol(0xff, 0xff, 0xff), + makecol(0x00, 0x00, 0x00), makecol(0x00, 0x00, 0x00), makecol(0x00, 0x00, 0x00), makecol(0x00, 0x00, 0x00), + makecol(0x00, 0x00, 0x00), makecol(0x00, 0x00, 0x00), makecol(0x00, 0x00, 0x00), makecol(0x00, 0x00, 0x00), + makecol(0x00, 0x00, 0x00), makecol(0x00, 0x00, 0x00), makecol(0x00, 0x00, 0x00), makecol(0x00, 0x00, 0x00), + makecol(0x00, 0x00, 0x00), makecol(0x00, 0x00, 0x00), makecol(0x00, 0x00, 0x00), makecol(0x00, 0x00, 0x00), + makecol(0x44, 0x77, 0x22), makecol(0x44, 0x77, 0x22), makecol(0x44, 0x77, 0x22), makecol(0x44, 0x77, 0x22), + makecol(0x44, 0x77, 0x22), makecol(0x44, 0x77, 0x22), makecol(0x44, 0x77, 0x22), makecol(0x44, 0x77, 0x22), + makecol(0x44, 0x77, 0x22), makecol(0x44, 0x77, 0x22), makecol(0x44, 0x77, 0x22), makecol(0x44, 0x77, 0x22), + makecol(0x44, 0x77, 0x22), makecol(0x44, 0x77, 0x22), makecol(0x44, 0x77, 0x22), makecol(0x44, 0x77, 0x22), + makecol(0x77, 0xaa, 0x44), makecol(0x77, 0xaa, 0x44), makecol(0x77, 0xaa, 0x44), makecol(0x77, 0xaa, 0x44), + makecol(0x77, 0xaa, 0x44), makecol(0x77, 0xaa, 0x44), makecol(0x77, 0xaa, 0x44), makecol(0x77, 0xaa, 0x44), + makecol(0x77, 0xaa, 0x44), makecol(0x77, 0xaa, 0x44), makecol(0x77, 0xaa, 0x44), makecol(0x77, 0xaa, 0x44), + makecol(0x77, 0xaa, 0x44), makecol(0x77, 0xaa, 0x44), makecol(0x77, 0xaa, 0x44), makecol(0x77, 0xaa, 0x44), + makecol(0x00, 0x77, 0x00), makecol(0x00, 0x77, 0x00), makecol(0x00, 0x77, 0x00), makecol(0x00, 0x77, 0x00), + makecol(0x00, 0x77, 0x00), makecol(0x00, 0x77, 0x00), makecol(0x00, 0x77, 0x00), makecol(0x00, 0x77, 0x00), + makecol(0x00, 0x77, 0x00), makecol(0x00, 0x77, 0x00), makecol(0x00, 0x77, 0x00), makecol(0x00, 0x77, 0x00), + makecol(0x00, 0x77, 0x00), makecol(0x00, 0x77, 0x00), makecol(0x00, 0x77, 0x00), makecol(0x00, 0x77, 0x00), + makecol(0x00, 0xff, 0x00), makecol(0x00, 0xff, 0x00), makecol(0x00, 0xff, 0x00), makecol(0x00, 0xff, 0x00), + makecol(0x00, 0xff, 0x00), makecol(0x00, 0xff, 0x00), makecol(0x00, 0xff, 0x00), makecol(0x00, 0xff, 0x00), + makecol(0x00, 0xff, 0x00), makecol(0x00, 0xff, 0x00), makecol(0x00, 0xff, 0x00), makecol(0x00, 0xff, 0x00), + makecol(0x00, 0xff, 0x00), makecol(0x00, 0xff, 0x00), makecol(0x00, 0xff, 0x00), makecol(0x00, 0xff, 0x00), + makecol(0x77, 0xff, 0x00), makecol(0x77, 0xff, 0x00), makecol(0x77, 0xff, 0x00), makecol(0x77, 0xff, 0x00), + makecol(0x77, 0xff, 0x00), makecol(0x77, 0xff, 0x00), makecol(0x77, 0xff, 0x00), makecol(0x77, 0xff, 0x00), + makecol(0x77, 0xff, 0x00), makecol(0x77, 0xff, 0x00), makecol(0x77, 0xff, 0x00), makecol(0x77, 0xff, 0x00), + makecol(0x77, 0xff, 0x00), makecol(0x77, 0xff, 0x00), makecol(0x77, 0xff, 0x00), makecol(0x77, 0xff, 0x00), + makecol(0xff, 0xff, 0x00), makecol(0xff, 0xff, 0x00), makecol(0xff, 0xff, 0x00), makecol(0xff, 0xff, 0x00), + makecol(0xff, 0xff, 0x00), makecol(0xff, 0xff, 0x00), makecol(0xff, 0xff, 0x00), makecol(0xff, 0xff, 0x00), + makecol(0xff, 0xff, 0x00), makecol(0xff, 0xff, 0x00), makecol(0xff, 0xff, 0x00), makecol(0xff, 0xff, 0x00), + makecol(0xff, 0xff, 0x00), makecol(0xff, 0xff, 0x00), makecol(0xff, 0xff, 0x00), makecol(0xff, 0xff, 0x00), + makecol(0xff, 0xaa, 0x00), makecol(0xff, 0xaa, 0x00), makecol(0xff, 0xaa, 0x00), makecol(0xff, 0xaa, 0x00), + makecol(0xff, 0xaa, 0x00), makecol(0xff, 0xaa, 0x00), makecol(0xff, 0xaa, 0x00), makecol(0xff, 0xaa, 0x00), + makecol(0xff, 0xaa, 0x00), makecol(0xff, 0xaa, 0x00), makecol(0xff, 0xaa, 0x00), makecol(0xff, 0xaa, 0x00), + makecol(0xff, 0xaa, 0x00), makecol(0xff, 0xaa, 0x00), makecol(0xff, 0xaa, 0x00), makecol(0xff, 0xaa, 0x00), + makecol(0xff, 0x00, 0x00), makecol(0xff, 0x00, 0x00), makecol(0xff, 0x00, 0x00), makecol(0xff, 0x00, 0x00), + makecol(0xff, 0x00, 0x00), makecol(0xff, 0x00, 0x00), makecol(0xff, 0x00, 0x00), makecol(0xff, 0x00, 0x00), + makecol(0xff, 0x00, 0x00), makecol(0xff, 0x00, 0x00), makecol(0xff, 0x00, 0x00), makecol(0xff, 0x00, 0x00), + makecol(0xff, 0x00, 0x00), makecol(0xff, 0x00, 0x00), makecol(0xff, 0x00, 0x00), makecol(0xff, 0x00, 0x00), + makecol(0x77, 0x00, 0x00), makecol(0x77, 0x00, 0x00), makecol(0x77, 0x00, 0x00), makecol(0x77, 0x00, 0x00), + makecol(0x77, 0x00, 0x00), makecol(0x77, 0x00, 0x00), makecol(0x77, 0x00, 0x00), makecol(0x77, 0x00, 0x00), + makecol(0x77, 0x00, 0x00), makecol(0x77, 0x00, 0x00), makecol(0x77, 0x00, 0x00), makecol(0x77, 0x00, 0x00), + makecol(0x77, 0x00, 0x00), makecol(0x77, 0x00, 0x00), makecol(0x77, 0x00, 0x00), makecol(0x77, 0x00, 0x00), + makecol(0x77, 0x00, 0x77), makecol(0x77, 0x00, 0x77), makecol(0x77, 0x00, 0x77), makecol(0x77, 0x00, 0x77), + makecol(0x77, 0x00, 0x77), makecol(0x77, 0x00, 0x77), makecol(0x77, 0x00, 0x77), makecol(0x77, 0x00, 0x77), + makecol(0x77, 0x00, 0x77), makecol(0x77, 0x00, 0x77), makecol(0x77, 0x00, 0x77), makecol(0x77, 0x00, 0x77), + makecol(0x77, 0x00, 0x77), makecol(0x77, 0x00, 0x77), makecol(0x77, 0x00, 0x77), makecol(0x77, 0x00, 0x77), + makecol(0x00, 0x00, 0x77), makecol(0x00, 0x00, 0x77), makecol(0x00, 0x00, 0x77), makecol(0x00, 0x00, 0x77), + makecol(0x00, 0x00, 0x77), makecol(0x00, 0x00, 0x77), makecol(0x00, 0x00, 0x77), makecol(0x00, 0x00, 0x77), + makecol(0x00, 0x00, 0x77), makecol(0x00, 0x00, 0x77), makecol(0x00, 0x00, 0x77), makecol(0x00, 0x00, 0x77), + makecol(0x00, 0x00, 0x77), makecol(0x00, 0x00, 0x77), makecol(0x00, 0x00, 0x77), makecol(0x00, 0x00, 0x77), + makecol(0x99, 0xee, 0x66), makecol(0x99, 0xee, 0x66), makecol(0x99, 0xee, 0x66), makecol(0x99, 0xee, 0x66), + makecol(0x99, 0xee, 0x66), makecol(0x99, 0xee, 0x66), makecol(0x99, 0xee, 0x66), makecol(0x99, 0xee, 0x66), + makecol(0x99, 0xee, 0x66), makecol(0x99, 0xee, 0x66), makecol(0x99, 0xee, 0x66), makecol(0x99, 0xee, 0x66), + makecol(0x99, 0xee, 0x66), makecol(0x99, 0xee, 0x66), makecol(0x99, 0xee, 0x66), makecol(0x99, 0xee, 0x66), + makecol(0x77, 0x77, 0x77), makecol(0x77, 0x77, 0x77), makecol(0x77, 0x77, 0x77), makecol(0x77, 0x77, 0x77), + makecol(0x77, 0x77, 0x77), makecol(0x77, 0x77, 0x77), makecol(0x77, 0x77, 0x77), makecol(0x77, 0x77, 0x77), + makecol(0x77, 0x77, 0x77), makecol(0x77, 0x77, 0x77), makecol(0x77, 0x77, 0x77), makecol(0x77, 0x77, 0x77), + makecol(0x77, 0x77, 0x77), makecol(0x77, 0x77, 0x77), makecol(0x77, 0x77, 0x77), makecol(0x77, 0x77, 0x77), + makecol(0xff, 0xff, 0xff), makecol(0xff, 0xff, 0xff), makecol(0xff, 0xff, 0xff), makecol(0xff, 0xff, 0xff), + makecol(0xff, 0xff, 0xff), makecol(0xff, 0xff, 0xff), makecol(0xff, 0xff, 0xff), makecol(0xff, 0xff, 0xff), + makecol(0xff, 0xff, 0xff), makecol(0xff, 0xff, 0xff), makecol(0xff, 0xff, 0xff), makecol(0xff, 0xff, 0xff), + makecol(0xff, 0xff, 0xff), makecol(0xff, 0xff, 0xff), makecol(0xff, 0xff, 0xff), makecol(0xff, 0xff, 0xff), + }, + /* Palette 2: 2-3-3 truecolour */ + { + makecol(0x00, 0x00, 0x00), makecol(0x00, 0x00, 0x33), makecol(0x00, 0x00, 0x55), makecol(0x00, 0x00, 0x77), + makecol(0x00, 0x00, 0x99), makecol(0x00, 0x00, 0xbb), makecol(0x00, 0x00, 0xdd), makecol(0x00, 0x00, 0xff), + makecol(0x33, 0x00, 0x00), makecol(0x33, 0x00, 0x33), makecol(0x33, 0x00, 0x55), makecol(0x33, 0x00, 0x77), + makecol(0x33, 0x00, 0x99), makecol(0x33, 0x00, 0xbb), makecol(0x33, 0x00, 0xdd), makecol(0x33, 0x00, 0xff), + makecol(0x55, 0x00, 0x00), makecol(0x55, 0x00, 0x33), makecol(0x55, 0x00, 0x55), makecol(0x55, 0x00, 0x77), + makecol(0x55, 0x00, 0x99), makecol(0x55, 0x00, 0xbb), makecol(0x55, 0x00, 0xdd), makecol(0x55, 0x00, 0xff), + makecol(0x77, 0x00, 0x00), makecol(0x77, 0x00, 0x33), makecol(0x77, 0x00, 0x55), makecol(0x77, 0x00, 0x77), + makecol(0x77, 0x00, 0x99), makecol(0x77, 0x00, 0xbb), makecol(0x77, 0x00, 0xdd), makecol(0x77, 0x00, 0xff), + makecol(0x99, 0x00, 0x00), makecol(0x99, 0x00, 0x33), makecol(0x99, 0x00, 0x55), makecol(0x99, 0x00, 0x77), + makecol(0x99, 0x00, 0x99), makecol(0x99, 0x00, 0xbb), makecol(0x99, 0x00, 0xdd), makecol(0x99, 0x00, 0xff), + makecol(0xbb, 0x00, 0x00), makecol(0xbb, 0x00, 0x33), makecol(0xbb, 0x00, 0x55), makecol(0xbb, 0x00, 0x77), + makecol(0xbb, 0x00, 0x99), makecol(0xbb, 0x00, 0xbb), makecol(0xbb, 0x00, 0xdd), makecol(0xbb, 0x00, 0xff), + makecol(0xdd, 0x00, 0x00), makecol(0xdd, 0x00, 0x33), makecol(0xdd, 0x00, 0x55), makecol(0xdd, 0x00, 0x77), + makecol(0xdd, 0x00, 0x99), makecol(0xdd, 0x00, 0xbb), makecol(0xdd, 0x00, 0xdd), makecol(0xdd, 0x00, 0xff), + makecol(0xff, 0x00, 0x00), makecol(0xff, 0x00, 0x33), makecol(0xff, 0x00, 0x55), makecol(0xff, 0x00, 0x77), + makecol(0xff, 0x00, 0x99), makecol(0xff, 0x00, 0xbb), makecol(0xff, 0x00, 0xdd), makecol(0xff, 0x00, 0xff), + makecol(0x00, 0x55, 0x00), makecol(0x00, 0x55, 0x33), makecol(0x00, 0x55, 0x55), makecol(0x00, 0x55, 0x77), + makecol(0x00, 0x55, 0x99), makecol(0x00, 0x55, 0xbb), makecol(0x00, 0x55, 0xdd), makecol(0x00, 0x55, 0xff), + makecol(0x33, 0x55, 0x00), makecol(0x33, 0x55, 0x33), makecol(0x33, 0x55, 0x55), makecol(0x33, 0x55, 0x77), + makecol(0x33, 0x55, 0x99), makecol(0x33, 0x55, 0xbb), makecol(0x33, 0x55, 0xdd), makecol(0x33, 0x55, 0xff), + makecol(0x55, 0x55, 0x00), makecol(0x55, 0x55, 0x33), makecol(0x55, 0x55, 0x55), makecol(0x55, 0x55, 0x77), + makecol(0x55, 0x55, 0x99), makecol(0x55, 0x55, 0xbb), makecol(0x55, 0x55, 0xdd), makecol(0x55, 0x55, 0xff), + makecol(0x77, 0x55, 0x00), makecol(0x77, 0x55, 0x33), makecol(0x77, 0x55, 0x55), makecol(0x77, 0x55, 0x77), + makecol(0x77, 0x55, 0x99), makecol(0x77, 0x55, 0xbb), makecol(0x77, 0x55, 0xdd), makecol(0x77, 0x55, 0xff), + makecol(0x99, 0x55, 0x00), makecol(0x99, 0x55, 0x33), makecol(0x99, 0x55, 0x55), makecol(0x99, 0x55, 0x77), + makecol(0x99, 0x55, 0x99), makecol(0x99, 0x55, 0xbb), makecol(0x99, 0x55, 0xdd), makecol(0x99, 0x55, 0xff), + makecol(0xbb, 0x55, 0x00), makecol(0xbb, 0x55, 0x33), makecol(0xbb, 0x55, 0x55), makecol(0xbb, 0x55, 0x77), + makecol(0xbb, 0x55, 0x99), makecol(0xbb, 0x55, 0xbb), makecol(0xbb, 0x55, 0xdd), makecol(0xbb, 0x55, 0xff), + makecol(0xdd, 0x55, 0x00), makecol(0xdd, 0x55, 0x33), makecol(0xdd, 0x55, 0x55), makecol(0xdd, 0x55, 0x77), + makecol(0xdd, 0x55, 0x99), makecol(0xdd, 0x55, 0xbb), makecol(0xdd, 0x55, 0xdd), makecol(0xdd, 0x55, 0xff), + makecol(0xff, 0x55, 0x00), makecol(0xff, 0x55, 0x33), makecol(0xff, 0x55, 0x55), makecol(0xff, 0x55, 0x77), + makecol(0xff, 0x55, 0x99), makecol(0xff, 0x55, 0xbb), makecol(0xff, 0x55, 0xdd), makecol(0xff, 0x55, 0xff), + makecol(0x00, 0xaa, 0x00), makecol(0x00, 0xaa, 0x33), makecol(0x00, 0xaa, 0x55), makecol(0x00, 0xaa, 0x77), + makecol(0x00, 0xaa, 0x99), makecol(0x00, 0xaa, 0xbb), makecol(0x00, 0xaa, 0xdd), makecol(0x00, 0xaa, 0xff), + makecol(0x33, 0xaa, 0x00), makecol(0x33, 0xaa, 0x33), makecol(0x33, 0xaa, 0x55), makecol(0x33, 0xaa, 0x77), + makecol(0x33, 0xaa, 0x99), makecol(0x33, 0xaa, 0xbb), makecol(0x33, 0xaa, 0xdd), makecol(0x33, 0xaa, 0xff), + makecol(0x55, 0xaa, 0x00), makecol(0x55, 0xaa, 0x33), makecol(0x55, 0xaa, 0x55), makecol(0x55, 0xaa, 0x77), + makecol(0x55, 0xaa, 0x99), makecol(0x55, 0xaa, 0xbb), makecol(0x55, 0xaa, 0xdd), makecol(0x55, 0xaa, 0xff), + makecol(0x77, 0xaa, 0x00), makecol(0x77, 0xaa, 0x33), makecol(0x77, 0xaa, 0x55), makecol(0x77, 0xaa, 0x77), + makecol(0x77, 0xaa, 0x99), makecol(0x77, 0xaa, 0xbb), makecol(0x77, 0xaa, 0xdd), makecol(0x77, 0xaa, 0xff), + makecol(0x99, 0xaa, 0x00), makecol(0x99, 0xaa, 0x33), makecol(0x99, 0xaa, 0x55), makecol(0x99, 0xaa, 0x77), + makecol(0x99, 0xaa, 0x99), makecol(0x99, 0xaa, 0xbb), makecol(0x99, 0xaa, 0xdd), makecol(0x99, 0xaa, 0xff), + makecol(0xbb, 0xaa, 0x00), makecol(0xbb, 0xaa, 0x33), makecol(0xbb, 0xaa, 0x55), makecol(0xbb, 0xaa, 0x77), + makecol(0xbb, 0xaa, 0x99), makecol(0xbb, 0xaa, 0xbb), makecol(0xbb, 0xaa, 0xdd), makecol(0xbb, 0xaa, 0xff), + makecol(0xdd, 0xaa, 0x00), makecol(0xdd, 0xaa, 0x33), makecol(0xdd, 0xaa, 0x55), makecol(0xdd, 0xaa, 0x77), + makecol(0xdd, 0xaa, 0x99), makecol(0xdd, 0xaa, 0xbb), makecol(0xdd, 0xaa, 0xdd), makecol(0xdd, 0xaa, 0xff), + makecol(0xff, 0xaa, 0x00), makecol(0xff, 0xaa, 0x33), makecol(0xff, 0xaa, 0x55), makecol(0xff, 0xaa, 0x77), + makecol(0xff, 0xaa, 0x99), makecol(0xff, 0xaa, 0xbb), makecol(0xff, 0xaa, 0xdd), makecol(0xff, 0xaa, 0xee), + makecol(0x00, 0xff, 0x00), makecol(0x00, 0xff, 0x33), makecol(0x00, 0xff, 0x55), makecol(0x00, 0xff, 0x77), + makecol(0x00, 0xff, 0x99), makecol(0x00, 0xff, 0xbb), makecol(0x00, 0xff, 0xdd), makecol(0x00, 0xff, 0xff), + makecol(0x33, 0xff, 0x00), makecol(0x33, 0xff, 0x33), makecol(0x33, 0xff, 0x55), makecol(0x33, 0xff, 0x77), + makecol(0x33, 0xff, 0x99), makecol(0x33, 0xff, 0xbb), makecol(0x33, 0xff, 0xdd), makecol(0x33, 0xff, 0xff), + makecol(0x55, 0xff, 0x00), makecol(0x55, 0xff, 0x33), makecol(0x55, 0xff, 0x55), makecol(0x55, 0xff, 0x77), + makecol(0x55, 0xff, 0x99), makecol(0x55, 0xff, 0xbb), makecol(0x55, 0xff, 0xdd), makecol(0x55, 0xff, 0xff), + makecol(0x77, 0xff, 0x00), makecol(0x77, 0xff, 0x33), makecol(0x77, 0xff, 0x55), makecol(0x77, 0xff, 0x77), + makecol(0x77, 0xff, 0x99), makecol(0x77, 0xff, 0xbb), makecol(0x77, 0xff, 0xdd), makecol(0x77, 0xff, 0xff), + makecol(0x99, 0xff, 0x00), makecol(0x99, 0xff, 0x33), makecol(0x99, 0xff, 0x55), makecol(0x99, 0xff, 0x77), + makecol(0x99, 0xff, 0x99), makecol(0x99, 0xff, 0xbb), makecol(0x99, 0xff, 0xdd), makecol(0x99, 0xff, 0xff), + makecol(0xbb, 0xff, 0x00), makecol(0xbb, 0xff, 0x33), makecol(0xbb, 0xff, 0x55), makecol(0xbb, 0xff, 0x77), + makecol(0xbb, 0xff, 0x99), makecol(0xbb, 0xff, 0xbb), makecol(0xbb, 0xff, 0xdd), makecol(0xbb, 0xff, 0xff), + makecol(0xdd, 0xff, 0x00), makecol(0xdd, 0xff, 0x33), makecol(0xdd, 0xff, 0x55), makecol(0xdd, 0xff, 0x77), + makecol(0xdd, 0xff, 0x99), makecol(0xdd, 0xff, 0xbb), makecol(0xdd, 0xff, 0xdd), makecol(0xdd, 0xff, 0xff), + makecol(0xff, 0xff, 0x00), makecol(0xff, 0xff, 0x33), makecol(0xff, 0xff, 0x55), makecol(0xff, 0xff, 0x77), + makecol(0xff, 0xff, 0x99), makecol(0xff, 0xff, 0xbb), makecol(0xff, 0xff, 0xdd), makecol(0xff, 0xff, 0xff), + }, + /* Palette 3: 3-2-3 truecolour */ + { + makecol(0x00, 0x00, 0x00), makecol(0x00, 0x00, 0x33), makecol(0x00, 0x00, 0x55), makecol(0x00, 0x00, 0x77), + makecol(0x00, 0x00, 0x99), makecol(0x00, 0x00, 0xbb), makecol(0x00, 0x00, 0xdd), makecol(0x00, 0x00, 0xff), + makecol(0x55, 0x00, 0x00), makecol(0x55, 0x00, 0x33), makecol(0x55, 0x00, 0x55), makecol(0x55, 0x00, 0x77), + makecol(0x55, 0x00, 0x99), makecol(0x55, 0x00, 0xbb), makecol(0x55, 0x00, 0xdd), makecol(0x55, 0x00, 0xff), + makecol(0xaa, 0x00, 0x00), makecol(0xaa, 0x00, 0x33), makecol(0xaa, 0x00, 0x55), makecol(0xaa, 0x00, 0x77), + makecol(0xaa, 0x00, 0x99), makecol(0xaa, 0x00, 0xbb), makecol(0xaa, 0x00, 0xdd), makecol(0xaa, 0x00, 0xff), + makecol(0xff, 0x00, 0x00), makecol(0xff, 0x00, 0x33), makecol(0xff, 0x00, 0x55), makecol(0xff, 0x00, 0x77), + makecol(0xff, 0x00, 0x99), makecol(0xff, 0x00, 0xbb), makecol(0xff, 0x00, 0xdd), makecol(0xff, 0x00, 0xff), + makecol(0x00, 0x33, 0x00), makecol(0x00, 0x33, 0x33), makecol(0x00, 0x33, 0x55), makecol(0x00, 0x33, 0x77), + makecol(0x00, 0x33, 0x99), makecol(0x00, 0x33, 0xbb), makecol(0x00, 0x33, 0xdd), makecol(0x00, 0x33, 0xff), + makecol(0x55, 0x33, 0x00), makecol(0x55, 0x33, 0x33), makecol(0x55, 0x33, 0x55), makecol(0x55, 0x33, 0x77), + makecol(0x55, 0x33, 0x99), makecol(0x55, 0x33, 0xbb), makecol(0x55, 0x33, 0xdd), makecol(0x55, 0x33, 0xff), + makecol(0xaa, 0x33, 0x00), makecol(0xaa, 0x33, 0x33), makecol(0xaa, 0x33, 0x55), makecol(0xaa, 0x33, 0x77), + makecol(0xaa, 0x33, 0x99), makecol(0xaa, 0x33, 0xbb), makecol(0xaa, 0x33, 0xdd), makecol(0xaa, 0x33, 0xff), + makecol(0xff, 0x33, 0x00), makecol(0xff, 0x33, 0x33), makecol(0xff, 0x33, 0x55), makecol(0xff, 0x33, 0x77), + makecol(0xff, 0x33, 0x99), makecol(0xff, 0x33, 0xbb), makecol(0xff, 0x33, 0xdd), makecol(0xff, 0x33, 0xff), + makecol(0x00, 0x55, 0x00), makecol(0x00, 0x55, 0x33), makecol(0x00, 0x55, 0x55), makecol(0x00, 0x55, 0x77), + makecol(0x00, 0x55, 0x99), makecol(0x00, 0x55, 0xbb), makecol(0x00, 0x55, 0xdd), makecol(0x00, 0x55, 0xff), + makecol(0x55, 0x55, 0x00), makecol(0x55, 0x55, 0x33), makecol(0x55, 0x55, 0x55), makecol(0x55, 0x55, 0x77), + makecol(0x55, 0x55, 0x99), makecol(0x55, 0x55, 0xbb), makecol(0x55, 0x55, 0xdd), makecol(0x55, 0x55, 0xff), + makecol(0xaa, 0x55, 0x00), makecol(0xaa, 0x55, 0x33), makecol(0xaa, 0x55, 0x55), makecol(0xaa, 0x55, 0x77), + makecol(0xaa, 0x55, 0x99), makecol(0xaa, 0x55, 0xbb), makecol(0xaa, 0x55, 0xdd), makecol(0xaa, 0x55, 0xff), + makecol(0xff, 0x55, 0x00), makecol(0xff, 0x55, 0x33), makecol(0xff, 0x55, 0x55), makecol(0xff, 0x55, 0x77), + makecol(0xff, 0x55, 0x99), makecol(0xff, 0x55, 0xbb), makecol(0xff, 0x55, 0xdd), makecol(0xff, 0x55, 0xff), + makecol(0x00, 0x77, 0x00), makecol(0x00, 0x77, 0x33), makecol(0x00, 0x77, 0x55), makecol(0x00, 0x77, 0x77), + makecol(0x00, 0x77, 0x99), makecol(0x00, 0x77, 0xbb), makecol(0x00, 0x77, 0xdd), makecol(0x00, 0x77, 0xff), + makecol(0x55, 0x77, 0x00), makecol(0x55, 0x77, 0x33), makecol(0x55, 0x77, 0x55), makecol(0x55, 0x77, 0x77), + makecol(0x55, 0x77, 0x99), makecol(0x55, 0x77, 0xbb), makecol(0x55, 0x77, 0xdd), makecol(0x55, 0x77, 0xff), + makecol(0xaa, 0x77, 0x00), makecol(0xaa, 0x77, 0x33), makecol(0xaa, 0x77, 0x55), makecol(0xaa, 0x77, 0x77), + makecol(0xaa, 0x77, 0x99), makecol(0xaa, 0x77, 0xbb), makecol(0xaa, 0x77, 0xdd), makecol(0xaa, 0x77, 0xff), + makecol(0xff, 0x77, 0x00), makecol(0xff, 0x77, 0x33), makecol(0xff, 0x77, 0x55), makecol(0xff, 0x77, 0x77), + makecol(0xff, 0x77, 0x99), makecol(0xff, 0x77, 0xbb), makecol(0xff, 0x77, 0xdd), makecol(0xff, 0x77, 0xff), + makecol(0x00, 0x99, 0x00), makecol(0x00, 0x99, 0x33), makecol(0x00, 0x99, 0x55), makecol(0x00, 0x99, 0x77), + makecol(0x00, 0x99, 0x99), makecol(0x00, 0x99, 0xbb), makecol(0x00, 0x99, 0xdd), makecol(0x00, 0x99, 0xff), + makecol(0x55, 0x99, 0x00), makecol(0x55, 0x99, 0x33), makecol(0x55, 0x99, 0x55), makecol(0x55, 0x99, 0x77), + makecol(0x55, 0x99, 0x99), makecol(0x55, 0x99, 0xbb), makecol(0x55, 0x99, 0xdd), makecol(0x55, 0x99, 0xff), + makecol(0xaa, 0x99, 0x00), makecol(0xaa, 0x99, 0x33), makecol(0xaa, 0x99, 0x55), makecol(0xaa, 0x99, 0x77), + makecol(0xaa, 0x99, 0x99), makecol(0xaa, 0x99, 0xbb), makecol(0xaa, 0x99, 0xdd), makecol(0xaa, 0x99, 0xff), + makecol(0xff, 0x99, 0x00), makecol(0xff, 0x99, 0x33), makecol(0xff, 0x99, 0x55), makecol(0xff, 0x99, 0x77), + makecol(0xff, 0x99, 0x99), makecol(0xff, 0x99, 0xbb), makecol(0xff, 0x99, 0xdd), makecol(0xff, 0x99, 0xff), + makecol(0x00, 0xbb, 0x00), makecol(0x00, 0xbb, 0x33), makecol(0x00, 0xbb, 0x55), makecol(0x00, 0xbb, 0x77), + makecol(0x00, 0xbb, 0x99), makecol(0x00, 0xbb, 0xbb), makecol(0x00, 0xbb, 0xdd), makecol(0x00, 0xbb, 0xff), + makecol(0x55, 0xbb, 0x00), makecol(0x55, 0xbb, 0x33), makecol(0x55, 0xbb, 0x55), makecol(0x55, 0xbb, 0x77), + makecol(0x55, 0xbb, 0x99), makecol(0x55, 0xbb, 0xbb), makecol(0x55, 0xbb, 0xdd), makecol(0x55, 0xbb, 0xff), + makecol(0xaa, 0xbb, 0x00), makecol(0xaa, 0xbb, 0x33), makecol(0xaa, 0xbb, 0x55), makecol(0xaa, 0xbb, 0x77), + makecol(0xaa, 0xbb, 0x99), makecol(0xaa, 0xbb, 0xbb), makecol(0xaa, 0xbb, 0xdd), makecol(0xaa, 0xbb, 0xff), + makecol(0xff, 0xbb, 0x00), makecol(0xff, 0xbb, 0x33), makecol(0xff, 0xbb, 0x55), makecol(0xff, 0xbb, 0x77), + makecol(0xff, 0xbb, 0x99), makecol(0xff, 0xbb, 0xbb), makecol(0xff, 0xbb, 0xdd), makecol(0xff, 0xbb, 0xff), + makecol(0x00, 0xdd, 0x00), makecol(0x00, 0xdd, 0x33), makecol(0x00, 0xdd, 0x55), makecol(0x00, 0xdd, 0x77), + makecol(0x00, 0xdd, 0x99), makecol(0x00, 0xdd, 0xbb), makecol(0x00, 0xdd, 0xdd), makecol(0x00, 0xdd, 0xff), + makecol(0x55, 0xdd, 0x00), makecol(0x55, 0xdd, 0x33), makecol(0x55, 0xdd, 0x55), makecol(0x55, 0xdd, 0x77), + makecol(0x55, 0xdd, 0x99), makecol(0x55, 0xdd, 0xbb), makecol(0x55, 0xdd, 0xdd), makecol(0x55, 0xdd, 0xff), + makecol(0xaa, 0xdd, 0x00), makecol(0xaa, 0xdd, 0x33), makecol(0xaa, 0xdd, 0x55), makecol(0xaa, 0xdd, 0x77), + makecol(0xaa, 0xdd, 0x99), makecol(0xaa, 0xdd, 0xbb), makecol(0xaa, 0xdd, 0xdd), makecol(0xaa, 0xdd, 0xff), + makecol(0xff, 0xdd, 0x00), makecol(0xff, 0xdd, 0x33), makecol(0xff, 0xdd, 0x55), makecol(0xff, 0xdd, 0x77), + makecol(0xff, 0xdd, 0x99), makecol(0xff, 0xdd, 0xbb), makecol(0xff, 0xdd, 0xdd), makecol(0xff, 0xdd, 0xff), + makecol(0x00, 0xff, 0x00), makecol(0x00, 0xff, 0x33), makecol(0x00, 0xff, 0x55), makecol(0x00, 0xff, 0x77), + makecol(0x00, 0xff, 0x99), makecol(0x00, 0xff, 0xbb), makecol(0x00, 0xff, 0xdd), makecol(0x00, 0xff, 0xff), + makecol(0x55, 0xff, 0x00), makecol(0x55, 0xff, 0x33), makecol(0x55, 0xff, 0x55), makecol(0x55, 0xff, 0x77), + makecol(0x55, 0xff, 0x99), makecol(0x55, 0xff, 0xbb), makecol(0x55, 0xff, 0xdd), makecol(0x55, 0xff, 0xff), + makecol(0xaa, 0xff, 0x00), makecol(0xaa, 0xff, 0x33), makecol(0xaa, 0xff, 0x55), makecol(0xaa, 0xff, 0x77), + makecol(0xaa, 0xff, 0x99), makecol(0xaa, 0xff, 0xbb), makecol(0xaa, 0xff, 0xdd), makecol(0xaa, 0xff, 0xff), + makecol(0xff, 0xff, 0x00), makecol(0xff, 0xff, 0x33), makecol(0xff, 0xff, 0x55), makecol(0xff, 0xff, 0x77), + makecol(0xff, 0xff, 0x99), makecol(0xff, 0xff, 0xbb), makecol(0xff, 0xff, 0xdd), makecol(0xff, 0xff, 0xff), + }, + /* Palette 4: 3-3-2 truecolour */ + { + makecol(0x00, 0x00, 0x00), makecol(0x00, 0x00, 0x55), makecol(0x00, 0x00, 0xaa), makecol(0x00, 0x00, 0xff), + makecol(0x00, 0x33, 0x00), makecol(0x00, 0x33, 0x55), makecol(0x00, 0x33, 0xaa), makecol(0x00, 0x33, 0xff), + makecol(0x00, 0x55, 0x00), makecol(0x00, 0x55, 0x55), makecol(0x00, 0x55, 0xaa), makecol(0x00, 0x55, 0xff), + makecol(0x00, 0x77, 0x00), makecol(0x00, 0x77, 0x55), makecol(0x00, 0x77, 0xaa), makecol(0x00, 0x77, 0xff), + makecol(0x00, 0x99, 0x00), makecol(0x00, 0x99, 0x55), makecol(0x00, 0x99, 0xaa), makecol(0x00, 0x99, 0xff), + makecol(0x00, 0xbb, 0x00), makecol(0x00, 0xbb, 0x55), makecol(0x00, 0xbb, 0xaa), makecol(0x00, 0xbb, 0xff), + makecol(0x00, 0xdd, 0x00), makecol(0x00, 0xdd, 0x55), makecol(0x00, 0xdd, 0xaa), makecol(0x00, 0xdd, 0xff), + makecol(0x00, 0xff, 0x00), makecol(0x00, 0xff, 0x55), makecol(0x00, 0xff, 0xaa), makecol(0x00, 0xff, 0xff), + makecol(0x33, 0x00, 0x00), makecol(0x33, 0x00, 0x55), makecol(0x33, 0x00, 0xaa), makecol(0x33, 0x00, 0xff), + makecol(0x33, 0x33, 0x00), makecol(0x33, 0x33, 0x55), makecol(0x33, 0x33, 0xaa), makecol(0x33, 0x33, 0xff), + makecol(0x33, 0x55, 0x00), makecol(0x33, 0x55, 0x55), makecol(0x33, 0x55, 0xaa), makecol(0x33, 0x55, 0xff), + makecol(0x33, 0x77, 0x00), makecol(0x33, 0x77, 0x55), makecol(0x33, 0x77, 0xaa), makecol(0x33, 0x77, 0xff), + makecol(0x33, 0x99, 0x00), makecol(0x33, 0x99, 0x55), makecol(0x33, 0x99, 0xaa), makecol(0x33, 0x99, 0xff), + makecol(0x33, 0xbb, 0x00), makecol(0x33, 0xbb, 0x55), makecol(0x33, 0xbb, 0xaa), makecol(0x33, 0xbb, 0xff), + makecol(0x33, 0xdd, 0x00), makecol(0x33, 0xdd, 0x55), makecol(0x33, 0xdd, 0xaa), makecol(0x33, 0xdd, 0xff), + makecol(0x33, 0xff, 0x00), makecol(0x33, 0xff, 0x55), makecol(0x33, 0xff, 0xaa), makecol(0x33, 0xff, 0xff), + makecol(0x55, 0x00, 0x00), makecol(0x55, 0x00, 0x55), makecol(0x55, 0x00, 0xaa), makecol(0x55, 0x00, 0xff), + makecol(0x55, 0x33, 0x00), makecol(0x55, 0x33, 0x55), makecol(0x55, 0x33, 0xaa), makecol(0x55, 0x33, 0xff), + makecol(0x55, 0x55, 0x00), makecol(0x55, 0x55, 0x55), makecol(0x55, 0x55, 0xaa), makecol(0x55, 0x55, 0xff), + makecol(0x55, 0x77, 0x00), makecol(0x55, 0x77, 0x55), makecol(0x55, 0x77, 0xaa), makecol(0x55, 0x77, 0xff), + makecol(0x55, 0x99, 0x00), makecol(0x55, 0x99, 0x55), makecol(0x55, 0x99, 0xaa), makecol(0x55, 0x99, 0xff), + makecol(0x55, 0xbb, 0x00), makecol(0x55, 0xbb, 0x55), makecol(0x55, 0xbb, 0xaa), makecol(0x55, 0xbb, 0xff), + makecol(0x55, 0xdd, 0x00), makecol(0x55, 0xdd, 0x55), makecol(0x55, 0xdd, 0xaa), makecol(0x55, 0xdd, 0xff), + makecol(0x55, 0xff, 0x00), makecol(0x55, 0xff, 0x55), makecol(0x55, 0xff, 0xaa), makecol(0x55, 0xff, 0xff), + makecol(0x77, 0x00, 0x00), makecol(0x77, 0x00, 0x55), makecol(0x77, 0x00, 0xaa), makecol(0x77, 0x00, 0xff), + makecol(0x77, 0x33, 0x00), makecol(0x77, 0x33, 0x55), makecol(0x77, 0x33, 0xaa), makecol(0x77, 0x33, 0xff), + makecol(0x77, 0x55, 0x00), makecol(0x77, 0x55, 0x55), makecol(0x77, 0x55, 0xaa), makecol(0x77, 0x55, 0xff), + makecol(0x77, 0x77, 0x00), makecol(0x77, 0x77, 0x55), makecol(0x77, 0x77, 0xaa), makecol(0x77, 0x77, 0xff), + makecol(0x77, 0x99, 0x00), makecol(0x77, 0x99, 0x55), makecol(0x77, 0x99, 0xaa), makecol(0x77, 0x99, 0xff), + makecol(0x77, 0xbb, 0x00), makecol(0x77, 0xbb, 0x55), makecol(0x77, 0xbb, 0xaa), makecol(0x77, 0xbb, 0xff), + makecol(0x77, 0xdd, 0x00), makecol(0x77, 0xdd, 0x55), makecol(0x77, 0xdd, 0xaa), makecol(0x77, 0xdd, 0xff), + makecol(0x77, 0xff, 0x00), makecol(0x77, 0xff, 0x55), makecol(0x77, 0xff, 0xaa), makecol(0x77, 0xff, 0xff), + makecol(0x99, 0x00, 0x00), makecol(0x99, 0x00, 0x55), makecol(0x99, 0x00, 0xaa), makecol(0x99, 0x00, 0xff), + makecol(0x99, 0x33, 0x00), makecol(0x99, 0x33, 0x55), makecol(0x99, 0x33, 0xaa), makecol(0x99, 0x33, 0xff), + makecol(0x99, 0x55, 0x00), makecol(0x99, 0x55, 0x55), makecol(0x99, 0x55, 0xaa), makecol(0x99, 0x55, 0xff), + makecol(0x99, 0x77, 0x00), makecol(0x99, 0x77, 0x55), makecol(0x99, 0x77, 0xaa), makecol(0x99, 0x77, 0xff), + makecol(0x99, 0x99, 0x00), makecol(0x99, 0x99, 0x55), makecol(0x99, 0x99, 0xaa), makecol(0x99, 0x99, 0xff), + makecol(0x99, 0xbb, 0x00), makecol(0x99, 0xbb, 0x55), makecol(0x99, 0xbb, 0xaa), makecol(0x99, 0xbb, 0xff), + makecol(0x99, 0xdd, 0x00), makecol(0x99, 0xdd, 0x55), makecol(0x99, 0xdd, 0xaa), makecol(0x99, 0xdd, 0xff), + makecol(0x99, 0xff, 0x00), makecol(0x99, 0xff, 0x55), makecol(0x99, 0xff, 0xaa), makecol(0x99, 0xff, 0xff), + makecol(0xbb, 0x00, 0x00), makecol(0xbb, 0x00, 0x55), makecol(0xbb, 0x00, 0xaa), makecol(0xbb, 0x00, 0xff), + makecol(0xbb, 0x33, 0x00), makecol(0xbb, 0x33, 0x55), makecol(0xbb, 0x33, 0xaa), makecol(0xbb, 0x33, 0xff), + makecol(0xbb, 0x55, 0x00), makecol(0xbb, 0x55, 0x55), makecol(0xbb, 0x55, 0xaa), makecol(0xbb, 0x55, 0xff), + makecol(0xbb, 0x77, 0x00), makecol(0xbb, 0x77, 0x55), makecol(0xbb, 0x77, 0xaa), makecol(0xbb, 0x77, 0xff), + makecol(0xbb, 0x99, 0x00), makecol(0xbb, 0x99, 0x55), makecol(0xbb, 0x99, 0xaa), makecol(0xbb, 0x99, 0xff), + makecol(0xbb, 0xbb, 0x00), makecol(0xbb, 0xbb, 0x55), makecol(0xbb, 0xbb, 0xaa), makecol(0xbb, 0xbb, 0xff), + makecol(0xbb, 0xdd, 0x00), makecol(0xbb, 0xdd, 0x55), makecol(0xbb, 0xdd, 0xaa), makecol(0xbb, 0xdd, 0xff), + makecol(0xbb, 0xff, 0x00), makecol(0xbb, 0xff, 0x55), makecol(0xbb, 0xff, 0xaa), makecol(0xbb, 0xff, 0xff), + makecol(0xdd, 0x00, 0x00), makecol(0xdd, 0x00, 0x55), makecol(0xdd, 0x00, 0xaa), makecol(0xdd, 0x00, 0xff), + makecol(0xdd, 0x33, 0x00), makecol(0xdd, 0x33, 0x55), makecol(0xdd, 0x33, 0xaa), makecol(0xdd, 0x33, 0xff), + makecol(0xdd, 0x55, 0x00), makecol(0xdd, 0x55, 0x55), makecol(0xdd, 0x55, 0xaa), makecol(0xdd, 0x55, 0xff), + makecol(0xdd, 0x77, 0x00), makecol(0xdd, 0x77, 0x55), makecol(0xdd, 0x77, 0xaa), makecol(0xdd, 0x77, 0xff), + makecol(0xdd, 0x99, 0x00), makecol(0xdd, 0x99, 0x55), makecol(0xdd, 0x99, 0xaa), makecol(0xdd, 0x99, 0xff), + makecol(0xdd, 0xbb, 0x00), makecol(0xdd, 0xbb, 0x55), makecol(0xdd, 0xbb, 0xaa), makecol(0xdd, 0xbb, 0xff), + makecol(0xdd, 0xdd, 0x00), makecol(0xdd, 0xdd, 0x55), makecol(0xdd, 0xdd, 0xaa), makecol(0xdd, 0xdd, 0xff), + makecol(0xdd, 0xff, 0x00), makecol(0xdd, 0xff, 0x55), makecol(0xdd, 0xff, 0xaa), makecol(0xdd, 0xff, 0xff), + makecol(0xff, 0x00, 0x00), makecol(0xff, 0x00, 0x55), makecol(0xff, 0x00, 0xaa), makecol(0xff, 0x00, 0xff), + makecol(0xff, 0x33, 0x00), makecol(0xff, 0x33, 0x55), makecol(0xff, 0x33, 0xaa), makecol(0xff, 0x33, 0xff), + makecol(0xff, 0x55, 0x00), makecol(0xff, 0x55, 0x55), makecol(0xff, 0x55, 0xaa), makecol(0xff, 0x55, 0xff), + makecol(0xff, 0x77, 0x00), makecol(0xff, 0x77, 0x55), makecol(0xff, 0x77, 0xaa), makecol(0xff, 0x77, 0xff), + makecol(0xff, 0x99, 0x00), makecol(0xff, 0x99, 0x55), makecol(0xff, 0x99, 0xaa), makecol(0xff, 0x99, 0xff), + makecol(0xff, 0xbb, 0x00), makecol(0xff, 0xbb, 0x55), makecol(0xff, 0xbb, 0xaa), makecol(0xff, 0xbb, 0xff), + makecol(0xff, 0xdd, 0x00), makecol(0xff, 0xdd, 0x55), makecol(0xff, 0xdd, 0xaa), makecol(0xff, 0xdd, 0xff), + makecol(0xff, 0xff, 0x00), makecol(0xff, 0xff, 0x55), makecol(0xff, 0xff, 0xaa), makecol(0xff, 0xff, 0xff), + }, + /* Palette 5: 6x6x6 colour cube */ + { + makecol(0x00, 0x00, 0x00), makecol(0x00, 0x00, 0x33), makecol(0x00, 0x00, 0x66), makecol(0x00, 0x00, 0x99), + makecol(0x00, 0x00, 0xcc), makecol(0x00, 0x00, 0xff), makecol(0x33, 0x00, 0x00), makecol(0x33, 0x00, 0x33), + makecol(0x33, 0x00, 0x66), makecol(0x33, 0x00, 0x99), makecol(0x33, 0x00, 0xcc), makecol(0x33, 0x00, 0xff), + makecol(0x66, 0x00, 0x00), makecol(0x66, 0x00, 0x33), makecol(0x66, 0x00, 0x66), makecol(0x66, 0x00, 0x99), + makecol(0x66, 0x00, 0xcc), makecol(0x66, 0x00, 0xff), makecol(0x99, 0x00, 0x00), makecol(0x99, 0x00, 0x33), + makecol(0x99, 0x00, 0x66), makecol(0x99, 0x00, 0x99), makecol(0x99, 0x00, 0xcc), makecol(0x99, 0x00, 0xff), + makecol(0xcc, 0x00, 0x00), makecol(0xcc, 0x00, 0x33), makecol(0xcc, 0x00, 0x66), makecol(0xcc, 0x00, 0x99), + makecol(0xcc, 0x00, 0xcc), makecol(0xcc, 0x00, 0xff), makecol(0xff, 0x00, 0x00), makecol(0xff, 0x00, 0x33), + makecol(0xff, 0x00, 0x66), makecol(0xff, 0x00, 0x99), makecol(0xff, 0x00, 0xcc), makecol(0xff, 0x00, 0xff), + makecol(0x00, 0x33, 0x00), makecol(0x00, 0x33, 0x33), makecol(0x00, 0x33, 0x66), makecol(0x00, 0x33, 0x99), + makecol(0x00, 0x33, 0xcc), makecol(0x00, 0x33, 0xff), makecol(0x33, 0x33, 0x00), makecol(0x33, 0x33, 0x33), + makecol(0x33, 0x33, 0x66), makecol(0x33, 0x33, 0x99), makecol(0x33, 0x33, 0xcc), makecol(0x33, 0x33, 0xff), + makecol(0x66, 0x33, 0x00), makecol(0x66, 0x33, 0x33), makecol(0x66, 0x33, 0x66), makecol(0x66, 0x33, 0x99), + makecol(0x66, 0x33, 0xcc), makecol(0x66, 0x33, 0xff), makecol(0x99, 0x33, 0x00), makecol(0x99, 0x33, 0x33), + makecol(0x99, 0x33, 0x66), makecol(0x99, 0x33, 0x99), makecol(0x99, 0x33, 0xcc), makecol(0x99, 0x33, 0xff), + makecol(0xcc, 0x33, 0x00), makecol(0xcc, 0x33, 0x33), makecol(0xcc, 0x33, 0x66), makecol(0xcc, 0x33, 0x99), + makecol(0xcc, 0x33, 0xcc), makecol(0xcc, 0x33, 0xff), makecol(0xff, 0x33, 0x00), makecol(0xff, 0x33, 0x33), + makecol(0xff, 0x33, 0x66), makecol(0xff, 0x33, 0x99), makecol(0xff, 0x33, 0xcc), makecol(0xff, 0x33, 0xff), + makecol(0x00, 0x66, 0x00), makecol(0x00, 0x66, 0x33), makecol(0x00, 0x66, 0x66), makecol(0x00, 0x66, 0x99), + makecol(0x00, 0x66, 0xcc), makecol(0x00, 0x66, 0xff), makecol(0x33, 0x66, 0x00), makecol(0x33, 0x66, 0x33), + makecol(0x33, 0x66, 0x66), makecol(0x33, 0x66, 0x99), makecol(0x33, 0x66, 0xcc), makecol(0x33, 0x66, 0xff), + makecol(0x66, 0x66, 0x00), makecol(0x66, 0x66, 0x33), makecol(0x66, 0x66, 0x66), makecol(0x66, 0x66, 0x99), + makecol(0x66, 0x66, 0xcc), makecol(0x66, 0x66, 0xff), makecol(0x99, 0x66, 0x00), makecol(0x99, 0x66, 0x33), + makecol(0x99, 0x66, 0x66), makecol(0x99, 0x66, 0x99), makecol(0x99, 0x66, 0xcc), makecol(0x99, 0x66, 0xff), + makecol(0xcc, 0x66, 0x00), makecol(0xcc, 0x66, 0x33), makecol(0xcc, 0x66, 0x66), makecol(0xcc, 0x66, 0x99), + makecol(0xcc, 0x66, 0xcc), makecol(0xcc, 0x66, 0xff), makecol(0xff, 0x66, 0x00), makecol(0xff, 0x66, 0x33), + makecol(0xff, 0x66, 0x66), makecol(0xff, 0x66, 0x99), makecol(0xff, 0x66, 0xcc), makecol(0xff, 0x66, 0xff), + makecol(0x00, 0x99, 0x00), makecol(0x00, 0x99, 0x33), makecol(0x00, 0x99, 0x66), makecol(0x00, 0x99, 0x99), + makecol(0x00, 0x99, 0xcc), makecol(0x00, 0x99, 0xff), makecol(0x33, 0x99, 0x00), makecol(0x33, 0x99, 0x33), + makecol(0x33, 0x99, 0x66), makecol(0x33, 0x99, 0x99), makecol(0x33, 0x99, 0xcc), makecol(0x33, 0x99, 0xff), + makecol(0x66, 0x99, 0x00), makecol(0x66, 0x99, 0x33), makecol(0x66, 0x99, 0x66), makecol(0x66, 0x99, 0x99), + makecol(0x66, 0x99, 0xcc), makecol(0x66, 0x99, 0xff), makecol(0x99, 0x99, 0x00), makecol(0x99, 0x99, 0x33), + makecol(0x99, 0x99, 0x66), makecol(0x99, 0x99, 0x99), makecol(0x99, 0x99, 0xcc), makecol(0x99, 0x99, 0xff), + makecol(0xcc, 0x99, 0x00), makecol(0xcc, 0x99, 0x33), makecol(0xcc, 0x99, 0x66), makecol(0xcc, 0x99, 0x99), + makecol(0xcc, 0x99, 0xcc), makecol(0xcc, 0x99, 0xff), makecol(0xff, 0x99, 0x00), makecol(0xff, 0x99, 0x33), + makecol(0xff, 0x99, 0x66), makecol(0xff, 0x99, 0x99), makecol(0xff, 0x99, 0xcc), makecol(0xff, 0x99, 0xff), + makecol(0x00, 0xcc, 0x00), makecol(0x00, 0xcc, 0x33), makecol(0x00, 0xcc, 0x66), makecol(0x00, 0xcc, 0x99), + makecol(0x00, 0xcc, 0xcc), makecol(0x00, 0xcc, 0xff), makecol(0x33, 0xcc, 0x00), makecol(0x33, 0xcc, 0x33), + makecol(0x33, 0xcc, 0x66), makecol(0x33, 0xcc, 0x99), makecol(0x33, 0xcc, 0xcc), makecol(0x33, 0xcc, 0xff), + makecol(0x66, 0xcc, 0x00), makecol(0x66, 0xcc, 0x33), makecol(0x66, 0xcc, 0x66), makecol(0x66, 0xcc, 0x99), + makecol(0x66, 0xcc, 0xcc), makecol(0x66, 0xcc, 0xff), makecol(0x99, 0xcc, 0x00), makecol(0x99, 0xcc, 0x33), + makecol(0x99, 0xcc, 0x66), makecol(0x99, 0xcc, 0x99), makecol(0x99, 0xcc, 0xcc), makecol(0x99, 0xcc, 0xff), + makecol(0xcc, 0xcc, 0x00), makecol(0xcc, 0xcc, 0x33), makecol(0xcc, 0xcc, 0x66), makecol(0xcc, 0xcc, 0x99), + makecol(0xcc, 0xcc, 0xcc), makecol(0xcc, 0xcc, 0xff), makecol(0xff, 0xcc, 0x00), makecol(0xff, 0xcc, 0x33), + makecol(0xff, 0xcc, 0x66), makecol(0xff, 0xcc, 0x99), makecol(0xff, 0xcc, 0xcc), makecol(0xff, 0xcc, 0xff), + makecol(0x00, 0xff, 0x00), makecol(0x00, 0xff, 0x33), makecol(0x00, 0xff, 0x66), makecol(0x00, 0xff, 0x99), + makecol(0x00, 0xff, 0xcc), makecol(0x00, 0xff, 0xff), makecol(0x33, 0xff, 0x00), makecol(0x33, 0xff, 0x33), + makecol(0x33, 0xff, 0x66), makecol(0x33, 0xff, 0x99), makecol(0x33, 0xff, 0xcc), makecol(0x33, 0xff, 0xff), + makecol(0x66, 0xff, 0x00), makecol(0x66, 0xff, 0x33), makecol(0x66, 0xff, 0x66), makecol(0x66, 0xff, 0x99), + makecol(0x66, 0xff, 0xcc), makecol(0x66, 0xff, 0xff), makecol(0x99, 0xff, 0x00), makecol(0x99, 0xff, 0x33), + makecol(0x99, 0xff, 0x66), makecol(0x99, 0xff, 0x99), makecol(0x99, 0xff, 0xcc), makecol(0x99, 0xff, 0xff), + makecol(0xcc, 0xff, 0x00), makecol(0xcc, 0xff, 0x33), makecol(0xcc, 0xff, 0x66), makecol(0xcc, 0xff, 0x99), + makecol(0xcc, 0xff, 0xcc), makecol(0xcc, 0xff, 0xff), makecol(0xff, 0xff, 0x00), makecol(0xff, 0xff, 0x33), + makecol(0xff, 0xff, 0x66), makecol(0xff, 0xff, 0x99), makecol(0xff, 0xff, 0xcc), makecol(0xff, 0xff, 0xff), + makecol(0x00, 0x00, 0x00), makecol(0x00, 0x00, 0x00), makecol(0x00, 0x00, 0x00), makecol(0x00, 0x00, 0x00), + makecol(0x00, 0x00, 0x00), makecol(0x00, 0x00, 0x00), makecol(0x00, 0x00, 0x00), makecol(0x00, 0x00, 0x00), + makecol(0x00, 0x00, 0x00), makecol(0x00, 0x00, 0x00), makecol(0x00, 0x00, 0x00), makecol(0x00, 0x00, 0x00), + makecol(0x00, 0x00, 0x00), makecol(0x00, 0x00, 0x00), makecol(0x00, 0x00, 0x00), makecol(0x00, 0x00, 0x00), + makecol(0x00, 0x00, 0x00), makecol(0x00, 0x00, 0x00), makecol(0x00, 0x00, 0x00), makecol(0x00, 0x00, 0x00), + makecol(0x00, 0x00, 0x00), makecol(0x00, 0x00, 0x00), makecol(0x00, 0x00, 0x00), makecol(0x00, 0x00, 0x00), + makecol(0x00, 0x00, 0x00), makecol(0x00, 0x00, 0x00), makecol(0x00, 0x00, 0x00), makecol(0x00, 0x00, 0x00), + makecol(0x00, 0x00, 0x00), makecol(0x00, 0x00, 0x00), makecol(0x00, 0x00, 0x00), makecol(0x00, 0x00, 0x00), + makecol(0x00, 0x00, 0x00), makecol(0x00, 0x00, 0x00), makecol(0x00, 0x00, 0x00), makecol(0x00, 0x00, 0x00), + makecol(0x00, 0x00, 0x00), makecol(0x00, 0x00, 0x00), makecol(0x00, 0x00, 0x00), makecol(0x00, 0x00, 0x00), + }, diff --git a/includes/private/plat-dinput.h b/includes/private/plat-dinput.h index 4a1a43c4..53e3e89d 100644 --- a/includes/private/plat-dinput.h +++ b/includes/private/plat-dinput.h @@ -3,5 +3,4 @@ extern LPDIRECTINPUT lpdi; - #endif /* _PLAT_DINPUT_H_ */ diff --git a/includes/private/plat-joystick.h b/includes/private/plat-joystick.h index 24138ac8..4549c35c 100644 --- a/includes/private/plat-joystick.h +++ b/includes/private/plat-joystick.h @@ -3,69 +3,63 @@ #ifdef __cplusplus extern "C" { #endif - void joystick_init(); - void joystick_close(); - void joystick_poll(); - - typedef struct plat_joystick_t - { - 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; +void joystick_init(); +void joystick_close(); +void joystick_poll(); - #define MAX_PLAT_JOYSTICKS 8 +typedef struct plat_joystick_t { + char name[64]; - extern plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; - extern int joysticks_present; + int a[8]; + int b[32]; + int p[4]; - #define POV_X 0x80000000 - #define POV_Y 0x40000000 - - typedef struct joystick_t - { - 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; + struct { + char name[32]; + int id; + } axis[8]; - #define MAX_JOYSTICKS 4 - extern joystick_t joystick_state[MAX_JOYSTICKS]; + struct { + char name[32]; + int id; + } button[32]; - #define JOYSTICK_PRESENT(n) (joystick_state[n].plat_joystick_nr != 0) + struct { + char name[32]; + int id; + } pov[4]; + + int nr_axes; + int nr_buttons; + int nr_povs; +} plat_joystick_t; + +#define MAX_PLAT_JOYSTICKS 8 + +extern plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; +extern int joysticks_present; + +#define POV_X 0x80000000 +#define POV_Y 0x40000000 + +typedef struct joystick_t { + 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; + +#define MAX_JOYSTICKS 4 +extern joystick_t joystick_state[MAX_JOYSTICKS]; + +#define JOYSTICK_PRESENT(n) (joystick_state[n].plat_joystick_nr != 0) #ifdef __cplusplus } #endif - #endif /* _PLAT_JOYSTICK_H_ */ diff --git a/includes/private/plat-keyboard.h b/includes/private/plat-keyboard.h index ff89c86a..2a27ffa3 100644 --- a/includes/private/plat-keyboard.h +++ b/includes/private/plat-keyboard.h @@ -3,24 +3,22 @@ #ifdef __cplusplus extern "C" { #endif - #include - - void keyboard_init(); - void keyboard_close(); - void keyboard_poll_host(); - extern uint8_t pcem_key[272]; - extern int rawinputkey[272]; - +#include + +void keyboard_init(); +void keyboard_close(); +void keyboard_poll_host(); +extern uint8_t pcem_key[272]; +extern int rawinputkey[272]; + #ifndef __unix - #define KEY_LCONTROL 0x1d - #define KEY_RCONTROL (0x1d | 0x80) - #define KEY_END (0x4f | 0x80) +#define KEY_LCONTROL 0x1d +#define KEY_RCONTROL (0x1d | 0x80) +#define KEY_END (0x4f | 0x80) #endif #ifdef __cplusplus } #endif - - #endif /* _PLAT_KEYBOARD_H_ */ diff --git a/includes/private/plat-midi.h b/includes/private/plat-midi.h index 64ea4354..f1ebab74 100644 --- a/includes/private/plat-midi.h +++ b/includes/private/plat-midi.h @@ -6,5 +6,4 @@ void midi_write(uint8_t val); int midi_get_num_devs(); void midi_get_dev_name(int num, char *s); - #endif /* _PLAT_MIDI_H_ */ diff --git a/includes/private/plat-mouse.h b/includes/private/plat-mouse.h index ca93b7e3..e8a50658 100644 --- a/includes/private/plat-mouse.h +++ b/includes/private/plat-mouse.h @@ -4,15 +4,14 @@ extern "C" { #endif - void mouse_init(); - void mouse_close(); - extern int mouse_buttons; - void mouse_poll_host(); - void mouse_get_mickeys(int *x, int *y, int *z); - extern int mousecapture; +void mouse_init(); +void mouse_close(); +extern int mouse_buttons; +void mouse_poll_host(); +void mouse_get_mickeys(int *x, int *y, int *z); +extern int mousecapture; #ifdef __cplusplus } #endif - #endif /* _PLAT_MOUSE_H_ */ diff --git a/includes/private/plugin-api/config.h b/includes/private/plugin-api/config.h index e7ecd8de..567a5742 100644 --- a/includes/private/plugin-api/config.h +++ b/includes/private/plugin-api/config.h @@ -18,9 +18,9 @@ extern char config_file_default[256]; extern char config_name[256]; typedef struct config_callback_t { - void (*loadconfig)(); - void (*saveconfig)(); - void (*onloaded)(); + void (*loadconfig)(); + void (*saveconfig)(); + void (*onloaded)(); } config_callback_t; extern config_callback_t config_callbacks[CALLBACK_MAX]; extern int num_config_callbacks; diff --git a/includes/private/plugin-api/paths.h b/includes/private/plugin-api/paths.h index 6b19aca1..fb3e9ddc 100644 --- a/includes/private/plugin-api/paths.h +++ b/includes/private/plugin-api/paths.h @@ -11,9 +11,9 @@ extern char nvr_default_path[512]; void get_pcem_path(char *s, int size); char get_path_separator(); void paths_init(); -int dir_exists(char* path); +int dir_exists(char *path); -int get_roms_path(int p, char* s, int size); +int get_roms_path(int p, char *s, int size); /* set the default paths to make them permanent */ void set_default_roms_paths(char *s); @@ -24,12 +24,16 @@ void set_default_screenshots_path(char *s); void set_default_nvr_default_path(char *s); /* set the paths temporarily for this session */ -void set_roms_paths(char* path); +void set_roms_paths(char *path); void set_nvr_path(char *s); void set_logs_path(char *s); void set_configs_path(char *s); void set_screenshots_path(char *s); -#define safe_strncpy(a, b, n) do { strncpy((a),(b),(n)-1); (a)[(n)-1] = 0; } while (0) +#define safe_strncpy(a, b, n) \ + do { \ + strncpy((a), (b), (n)-1); \ + (a)[(n)-1] = 0; \ + } while (0) #endif /* _PATHS_H_ */ diff --git a/includes/private/plugin-api/tinydir.h b/includes/private/plugin-api/tinydir.h index 614ab5d1..fa5959ab 100644 --- a/includes/private/plugin-api/tinydir.h +++ b/includes/private/plugin-api/tinydir.h @@ -47,88 +47,85 @@ extern "C" { #ifdef __MINGW32__ // HACK: Since GCC doesnt define these right, putting it here for now. #ifndef _FSIZE_T_DEFINED -typedef unsigned long _fsize_t; +typedef unsigned long _fsize_t; #define _FSIZE_T_DEFINED #endif -struct _finddata_t -{ - unsigned attrib; /* Attributes, see constants above. */ - time_t time_create; - time_t time_access; /* always midnight local time */ - time_t time_write; - _fsize_t size; - char name[FILENAME_MAX]; /* may include spaces. */ +struct _finddata_t { + unsigned attrib; /* Attributes, see constants above. */ + time_t time_create; + time_t time_access; /* always midnight local time */ + time_t time_write; + _fsize_t size; + char name[FILENAME_MAX]; /* may include spaces. */ }; -struct _wfinddata_t -{ - unsigned attrib; /* Attributes, see constants above. */ - time_t time_create; - time_t time_access; /* always midnight local time */ - time_t time_write; - size_t size; - wchar_t name[FILENAME_MAX]; /* may include spaces. */ +struct _wfinddata_t { + unsigned attrib; /* Attributes, see constants above. */ + time_t time_create; + time_t time_access; /* always midnight local time */ + time_t time_write; + size_t size; + wchar_t name[FILENAME_MAX]; /* may include spaces. */ }; #endif #ifdef _MSC_VER -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN -# endif -# include -# include -# pragma warning(push) -# pragma warning (disable : 4996) +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#include +#pragma warning(push) +#pragma warning(disable : 4996) #else -# include -# include -# include -# include +#include +#include +#include +#include #endif #ifdef __MINGW32__ -# include +#include #endif - /* types */ /* Windows UNICODE wide character support */ #if defined _MSC_VER || defined __MINGW32__ -# define _tinydir_char_t TCHAR -# define TINYDIR_STRING(s) _TEXT(s) -# define _tinydir_strlen _tcslen -# define _tinydir_strcpy _tcscpy -# define _tinydir_strcat _tcscat -# define _tinydir_strcmp _tcscmp -# define _tinydir_strrchr _tcsrchr -# define _tinydir_strncmp _tcsncmp +#define _tinydir_char_t TCHAR +#define TINYDIR_STRING(s) _TEXT(s) +#define _tinydir_strlen _tcslen +#define _tinydir_strcpy _tcscpy +#define _tinydir_strcat _tcscat +#define _tinydir_strcmp _tcscmp +#define _tinydir_strrchr _tcsrchr +#define _tinydir_strncmp _tcsncmp #else -# define _tinydir_char_t char -# define TINYDIR_STRING(s) s -# define _tinydir_strlen strlen -# define _tinydir_strcpy strcpy -# define _tinydir_strcat strcat -# define _tinydir_strcmp strcmp -# define _tinydir_strrchr strrchr -# define _tinydir_strncmp strncmp +#define _tinydir_char_t char +#define TINYDIR_STRING(s) s +#define _tinydir_strlen strlen +#define _tinydir_strcpy strcpy +#define _tinydir_strcat strcat +#define _tinydir_strcmp strcmp +#define _tinydir_strrchr strrchr +#define _tinydir_strncmp strncmp #endif #if (defined _MSC_VER || defined __MINGW32__) -# include -# define _TINYDIR_PATH_MAX MAX_PATH -#elif defined __linux__ -# include -# ifdef PATH_MAX -# define _TINYDIR_PATH_MAX PATH_MAX -# endif +#include +#define _TINYDIR_PATH_MAX MAX_PATH +#elif defined __linux__ +#include +#ifdef PATH_MAX +#define _TINYDIR_PATH_MAX PATH_MAX +#endif #elif defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) -# include -# if defined(BSD) -# include -# ifdef PATH_MAX -# define _TINYDIR_PATH_MAX PATH_MAX -# endif -# endif +#include +#if defined(BSD) +#include +#ifdef PATH_MAX +#define _TINYDIR_PATH_MAX PATH_MAX +#endif +#endif #endif #ifndef _TINYDIR_PATH_MAX @@ -137,9 +134,9 @@ struct _wfinddata_t #ifdef _MSC_VER /* extra chars for the "\\*" mask */ -# define _TINYDIR_PATH_EXTRA 2 +#define _TINYDIR_PATH_EXTRA 2 #else -# define _TINYDIR_PATH_EXTRA 0 +#define _TINYDIR_PATH_EXTRA 0 #endif #define _TINYDIR_FILENAME_MAX 256 @@ -149,16 +146,16 @@ struct _wfinddata_t #endif #ifdef _MSC_VER -# define _TINYDIR_FUNC static __inline +#define _TINYDIR_FUNC static __inline #elif !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L -# define _TINYDIR_FUNC static __inline__ +#define _TINYDIR_FUNC static __inline__ #elif defined(__cplusplus) -# define _TINYDIR_FUNC static inline +#define _TINYDIR_FUNC static inline #elif defined(__GNUC__) /* Suppress unused function warning */ -# define _TINYDIR_FUNC __attribute__((unused)) static +#define _TINYDIR_FUNC __attribute__((unused)) static #else -# define _TINYDIR_FUNC static +#define _TINYDIR_FUNC static #endif /* readdir_r usage; define TINYDIR_USE_READDIR_R to use it (if supported) */ @@ -166,31 +163,27 @@ struct _wfinddata_t /* readdir_r is a POSIX-only function, and may not be available under various * environments/settings, e.g. MinGW. Use readdir fallback */ -#if _POSIX_C_SOURCE >= 1 || _XOPEN_SOURCE || _BSD_SOURCE || _SVID_SOURCE ||\ - _POSIX_SOURCE -# define _TINYDIR_HAS_READDIR_R +#if _POSIX_C_SOURCE >= 1 || _XOPEN_SOURCE || _BSD_SOURCE || _SVID_SOURCE || _POSIX_SOURCE +#define _TINYDIR_HAS_READDIR_R #endif #if _POSIX_C_SOURCE >= 200112L -# define _TINYDIR_HAS_FPATHCONF -# include +#define _TINYDIR_HAS_FPATHCONF +#include #endif -#if _BSD_SOURCE || _SVID_SOURCE || \ - (_POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700) -# define _TINYDIR_HAS_DIRFD -# include +#if _BSD_SOURCE || _SVID_SOURCE || (_POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700) +#define _TINYDIR_HAS_DIRFD +#include #endif -#if defined _TINYDIR_HAS_FPATHCONF && defined _TINYDIR_HAS_DIRFD &&\ - defined _PC_NAME_MAX -# define _TINYDIR_USE_FPATHCONF +#if defined _TINYDIR_HAS_FPATHCONF && defined _TINYDIR_HAS_DIRFD && defined _PC_NAME_MAX +#define _TINYDIR_USE_FPATHCONF #endif -#if defined __MINGW32__ || !defined _TINYDIR_HAS_READDIR_R ||\ - !(defined _TINYDIR_USE_FPATHCONF || defined NAME_MAX) -# define _TINYDIR_USE_READDIR +#if defined __MINGW32__ || !defined _TINYDIR_HAS_READDIR_R || !(defined _TINYDIR_USE_FPATHCONF || defined NAME_MAX) +#define _TINYDIR_USE_READDIR #endif /* Use readdir by default */ #else -# define _TINYDIR_USE_READDIR +#define _TINYDIR_USE_READDIR #endif /* MINGW32 has two versions of dirent, ASCII and UNICODE*/ @@ -211,54 +204,51 @@ struct _wfinddata_t #endif /* Allow user to use a custom allocator by defining _TINYDIR_MALLOC and _TINYDIR_FREE. */ -#if defined(_TINYDIR_MALLOC) && defined(_TINYDIR_FREE) +#if defined(_TINYDIR_MALLOC) && defined(_TINYDIR_FREE) #elif !defined(_TINYDIR_MALLOC) && !defined(_TINYDIR_FREE) #else #error "Either define both alloc and free or none of them!" #endif #if !defined(_TINYDIR_MALLOC) - #define _TINYDIR_MALLOC(_size) malloc(_size) - #define _TINYDIR_FREE(_ptr) free(_ptr) +#define _TINYDIR_MALLOC(_size) malloc(_size) +#define _TINYDIR_FREE(_ptr) free(_ptr) #endif /* !defined(_TINYDIR_MALLOC) */ -typedef struct tinydir_file -{ - _tinydir_char_t path[_TINYDIR_PATH_MAX]; - _tinydir_char_t name[_TINYDIR_FILENAME_MAX]; - _tinydir_char_t *extension; - int is_dir; - int is_reg; +typedef struct tinydir_file { + _tinydir_char_t path[_TINYDIR_PATH_MAX]; + _tinydir_char_t name[_TINYDIR_FILENAME_MAX]; + _tinydir_char_t *extension; + int is_dir; + int is_reg; #ifndef _MSC_VER #ifdef __MINGW32__ - struct _stat _s; + struct _stat _s; #else - struct stat _s; + struct stat _s; #endif #endif } tinydir_file; -typedef struct tinydir_dir -{ - _tinydir_char_t path[_TINYDIR_PATH_MAX]; - int has_next; - size_t n_files; +typedef struct tinydir_dir { + _tinydir_char_t path[_TINYDIR_PATH_MAX]; + int has_next; + size_t n_files; - tinydir_file *_files; + tinydir_file *_files; #ifdef _MSC_VER - HANDLE _h; - WIN32_FIND_DATA _f; + HANDLE _h; + WIN32_FIND_DATA _f; #else - _TINYDIR_DIR *_d; - struct _tinydir_dirent *_e; + _TINYDIR_DIR *_d; + struct _tinydir_dirent *_e; #ifndef _TINYDIR_USE_READDIR - struct _tinydir_dirent *_ep; + struct _tinydir_dirent *_ep; #endif #endif } tinydir_dir; - /* declarations */ _TINYDIR_FUNC @@ -290,527 +280,457 @@ size_t _tinydir_dirent_buf_size(_TINYDIR_DIR *dirp); #endif #endif - /* definitions*/ _TINYDIR_FUNC -int tinydir_open(tinydir_dir *dir, const _tinydir_char_t *path) -{ +int tinydir_open(tinydir_dir *dir, const _tinydir_char_t *path) { #ifndef _MSC_VER #ifndef _TINYDIR_USE_READDIR - int error; - int size; /* using int size */ + int error; + int size; /* using int size */ #endif #else - _tinydir_char_t path_buf[_TINYDIR_PATH_MAX]; + _tinydir_char_t path_buf[_TINYDIR_PATH_MAX]; #endif - _tinydir_char_t *pathp; + _tinydir_char_t *pathp; - if (dir == NULL || path == NULL || _tinydir_strlen(path) == 0) - { - errno = EINVAL; - return -1; - } - if (_tinydir_strlen(path) + _TINYDIR_PATH_EXTRA >= _TINYDIR_PATH_MAX) - { - errno = ENAMETOOLONG; - return -1; - } + if (dir == NULL || path == NULL || _tinydir_strlen(path) == 0) { + errno = EINVAL; + return -1; + } + if (_tinydir_strlen(path) + _TINYDIR_PATH_EXTRA >= _TINYDIR_PATH_MAX) { + errno = ENAMETOOLONG; + return -1; + } - /* initialise dir */ - dir->_files = NULL; + /* initialise dir */ + dir->_files = NULL; #ifdef _MSC_VER - dir->_h = INVALID_HANDLE_VALUE; + dir->_h = INVALID_HANDLE_VALUE; #else - dir->_d = NULL; + dir->_d = NULL; #ifndef _TINYDIR_USE_READDIR - dir->_ep = NULL; + dir->_ep = NULL; #endif #endif - tinydir_close(dir); + tinydir_close(dir); - _tinydir_strcpy(dir->path, path); - /* Remove trailing slashes */ - pathp = &dir->path[_tinydir_strlen(dir->path) - 1]; - while (pathp != dir->path && (*pathp == TINYDIR_STRING('\\') || *pathp == TINYDIR_STRING('/'))) - { - *pathp = TINYDIR_STRING('\0'); - pathp++; - } + _tinydir_strcpy(dir->path, path); + /* Remove trailing slashes */ + pathp = &dir->path[_tinydir_strlen(dir->path) - 1]; + while (pathp != dir->path && (*pathp == TINYDIR_STRING('\\') || *pathp == TINYDIR_STRING('/'))) { + *pathp = TINYDIR_STRING('\0'); + pathp++; + } #ifdef _MSC_VER - _tinydir_strcpy(path_buf, dir->path); - _tinydir_strcat(path_buf, TINYDIR_STRING("\\*")); + _tinydir_strcpy(path_buf, dir->path); + _tinydir_strcat(path_buf, TINYDIR_STRING("\\*")); #if (defined WINAPI_FAMILY) && (WINAPI_FAMILY != WINAPI_FAMILY_DESKTOP_APP) - dir->_h = FindFirstFileEx(path_buf, FindExInfoStandard, &dir->_f, FindExSearchNameMatch, NULL, 0); + dir->_h = FindFirstFileEx(path_buf, FindExInfoStandard, &dir->_f, FindExSearchNameMatch, NULL, 0); #else - dir->_h = FindFirstFile(path_buf, &dir->_f); + dir->_h = FindFirstFile(path_buf, &dir->_f); #endif - if (dir->_h == INVALID_HANDLE_VALUE) - { - errno = ENOENT; + if (dir->_h == INVALID_HANDLE_VALUE) { + errno = ENOENT; #else - dir->_d = _tinydir_opendir(path); - if (dir->_d == NULL) - { + dir->_d = _tinydir_opendir(path); + if (dir->_d == NULL) { #endif - goto bail; - } + goto bail; + } - /* read first file */ - dir->has_next = 1; + /* read first file */ + dir->has_next = 1; #ifndef _MSC_VER #ifdef _TINYDIR_USE_READDIR - dir->_e = _tinydir_readdir(dir->_d); + dir->_e = _tinydir_readdir(dir->_d); #else - /* allocate dirent buffer for readdir_r */ - size = _tinydir_dirent_buf_size(dir->_d); /* conversion to int */ - if (size == -1) return -1; - dir->_ep = (struct _tinydir_dirent*)_TINYDIR_MALLOC(size); - if (dir->_ep == NULL) return -1; + /* allocate dirent buffer for readdir_r */ + size = _tinydir_dirent_buf_size(dir->_d); /* conversion to int */ + if (size == -1) + return -1; + dir->_ep = (struct _tinydir_dirent *)_TINYDIR_MALLOC(size); + if (dir->_ep == NULL) + return -1; - error = readdir_r(dir->_d, dir->_ep, &dir->_e); - if (error != 0) return -1; + error = readdir_r(dir->_d, dir->_ep, &dir->_e); + if (error != 0) + return -1; #endif - if (dir->_e == NULL) - { - dir->has_next = 0; - } + if (dir->_e == NULL) { + dir->has_next = 0; + } #endif - return 0; + return 0; bail: - tinydir_close(dir); - return -1; + tinydir_close(dir); + return -1; } _TINYDIR_FUNC -int tinydir_open_sorted(tinydir_dir *dir, const _tinydir_char_t *path) -{ - /* Count the number of files first, to pre-allocate the files array */ - size_t n_files = 0; - if (tinydir_open(dir, path) == -1) - { - return -1; - } - while (dir->has_next) - { - n_files++; - if (tinydir_next(dir) == -1) - { - goto bail; - } - } - tinydir_close(dir); +int tinydir_open_sorted(tinydir_dir *dir, const _tinydir_char_t *path) { + /* Count the number of files first, to pre-allocate the files array */ + size_t n_files = 0; + if (tinydir_open(dir, path) == -1) { + return -1; + } + while (dir->has_next) { + n_files++; + if (tinydir_next(dir) == -1) { + goto bail; + } + } + tinydir_close(dir); - if (n_files == 0 || tinydir_open(dir, path) == -1) - { - return -1; - } + if (n_files == 0 || tinydir_open(dir, path) == -1) { + return -1; + } - dir->n_files = 0; - dir->_files = (tinydir_file *)_TINYDIR_MALLOC(sizeof *dir->_files * n_files); - if (dir->_files == NULL) - { - goto bail; - } - while (dir->has_next) - { - tinydir_file *p_file; - dir->n_files++; + dir->n_files = 0; + dir->_files = (tinydir_file *)_TINYDIR_MALLOC(sizeof *dir->_files * n_files); + if (dir->_files == NULL) { + goto bail; + } + while (dir->has_next) { + tinydir_file *p_file; + dir->n_files++; - p_file = &dir->_files[dir->n_files - 1]; - if (tinydir_readfile(dir, p_file) == -1) - { - goto bail; - } + p_file = &dir->_files[dir->n_files - 1]; + if (tinydir_readfile(dir, p_file) == -1) { + goto bail; + } - if (tinydir_next(dir) == -1) - { - goto bail; - } + if (tinydir_next(dir) == -1) { + goto bail; + } - /* Just in case the number of files has changed between the first and - second reads, terminate without writing into unallocated memory */ - if (dir->n_files == n_files) - { - break; - } - } + /* Just in case the number of files has changed between the first and + second reads, terminate without writing into unallocated memory */ + if (dir->n_files == n_files) { + break; + } + } - qsort(dir->_files, dir->n_files, sizeof(tinydir_file), _tinydir_file_cmp); + qsort(dir->_files, dir->n_files, sizeof(tinydir_file), _tinydir_file_cmp); - return 0; + return 0; bail: - tinydir_close(dir); - return -1; + tinydir_close(dir); + return -1; } _TINYDIR_FUNC -void tinydir_close(tinydir_dir *dir) -{ - if (dir == NULL) - { - return; - } +void tinydir_close(tinydir_dir *dir) { + if (dir == NULL) { + return; + } - memset(dir->path, 0, sizeof(dir->path)); - dir->has_next = 0; - dir->n_files = 0; - _TINYDIR_FREE(dir->_files); - dir->_files = NULL; + memset(dir->path, 0, sizeof(dir->path)); + dir->has_next = 0; + dir->n_files = 0; + _TINYDIR_FREE(dir->_files); + dir->_files = NULL; #ifdef _MSC_VER - if (dir->_h != INVALID_HANDLE_VALUE) - { - FindClose(dir->_h); - } - dir->_h = INVALID_HANDLE_VALUE; + if (dir->_h != INVALID_HANDLE_VALUE) { + FindClose(dir->_h); + } + dir->_h = INVALID_HANDLE_VALUE; #else - if (dir->_d) - { - _tinydir_closedir(dir->_d); - } - dir->_d = NULL; - dir->_e = NULL; + if (dir->_d) { + _tinydir_closedir(dir->_d); + } + dir->_d = NULL; + dir->_e = NULL; #ifndef _TINYDIR_USE_READDIR - _TINYDIR_FREE(dir->_ep); - dir->_ep = NULL; + _TINYDIR_FREE(dir->_ep); + dir->_ep = NULL; #endif #endif } _TINYDIR_FUNC -int tinydir_next(tinydir_dir *dir) -{ - if (dir == NULL) - { - errno = EINVAL; - return -1; - } - if (!dir->has_next) - { - errno = ENOENT; - return -1; - } +int tinydir_next(tinydir_dir *dir) { + if (dir == NULL) { + errno = EINVAL; + return -1; + } + if (!dir->has_next) { + errno = ENOENT; + return -1; + } #ifdef _MSC_VER - if (FindNextFile(dir->_h, &dir->_f) == 0) + if (FindNextFile(dir->_h, &dir->_f) == 0) #else #ifdef _TINYDIR_USE_READDIR - dir->_e = _tinydir_readdir(dir->_d); + dir->_e = _tinydir_readdir(dir->_d); #else - if (dir->_ep == NULL) - { - return -1; - } - if (readdir_r(dir->_d, dir->_ep, &dir->_e) != 0) - { - return -1; - } + if (dir->_ep == NULL) { + return -1; + } + if (readdir_r(dir->_d, dir->_ep, &dir->_e) != 0) { + return -1; + } #endif - if (dir->_e == NULL) + if (dir->_e == NULL) #endif - { - dir->has_next = 0; + { + dir->has_next = 0; #ifdef _MSC_VER - if (GetLastError() != ERROR_SUCCESS && - GetLastError() != ERROR_NO_MORE_FILES) - { - tinydir_close(dir); - errno = EIO; - return -1; - } + if (GetLastError() != ERROR_SUCCESS && GetLastError() != ERROR_NO_MORE_FILES) { + tinydir_close(dir); + errno = EIO; + return -1; + } #endif - } + } - return 0; + return 0; } _TINYDIR_FUNC -int tinydir_readfile(const tinydir_dir *dir, tinydir_file *file) -{ - const _tinydir_char_t *filename; - if (dir == NULL || file == NULL) - { - errno = EINVAL; - return -1; - } +int tinydir_readfile(const tinydir_dir *dir, tinydir_file *file) { + const _tinydir_char_t *filename; + if (dir == NULL || file == NULL) { + errno = EINVAL; + return -1; + } #ifdef _MSC_VER - if (dir->_h == INVALID_HANDLE_VALUE) + if (dir->_h == INVALID_HANDLE_VALUE) #else - if (dir->_e == NULL) + if (dir->_e == NULL) #endif - { - errno = ENOENT; - return -1; - } - filename = + { + errno = ENOENT; + return -1; + } + filename = #ifdef _MSC_VER - dir->_f.cFileName; + dir->_f.cFileName; #else - dir->_e->d_name; + dir->_e->d_name; #endif - if (_tinydir_strlen(dir->path) + - _tinydir_strlen(filename) + 1 + _TINYDIR_PATH_EXTRA >= - _TINYDIR_PATH_MAX) - { - /* the path for the file will be too long */ - errno = ENAMETOOLONG; - return -1; - } - if (_tinydir_strlen(filename) >= _TINYDIR_FILENAME_MAX) - { - errno = ENAMETOOLONG; - return -1; - } + if (_tinydir_strlen(dir->path) + _tinydir_strlen(filename) + 1 + _TINYDIR_PATH_EXTRA >= _TINYDIR_PATH_MAX) { + /* the path for the file will be too long */ + errno = ENAMETOOLONG; + return -1; + } + if (_tinydir_strlen(filename) >= _TINYDIR_FILENAME_MAX) { + errno = ENAMETOOLONG; + return -1; + } - _tinydir_strcpy(file->path, dir->path); - if (_tinydir_strcmp(dir->path, TINYDIR_STRING("/")) != 0) - _tinydir_strcat(file->path, TINYDIR_STRING("/")); - _tinydir_strcpy(file->name, filename); - _tinydir_strcat(file->path, filename); + _tinydir_strcpy(file->path, dir->path); + if (_tinydir_strcmp(dir->path, TINYDIR_STRING("/")) != 0) + _tinydir_strcat(file->path, TINYDIR_STRING("/")); + _tinydir_strcpy(file->name, filename); + _tinydir_strcat(file->path, filename); #ifndef _MSC_VER #ifdef __MINGW32__ - if (_tstat( -#elif (defined _BSD_SOURCE) || (defined _DEFAULT_SOURCE) \ - || ((defined _XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)) \ - || ((defined _POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L)) \ - || ((defined __APPLE__) && (defined __MACH__)) \ - || (defined BSD) - if (lstat( + if (_tstat( +#elif (defined _BSD_SOURCE) || (defined _DEFAULT_SOURCE) || ((defined _XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)) || \ + ((defined _POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L)) || ((defined __APPLE__) && (defined __MACH__)) || \ + (defined BSD) + if (lstat( #else - if (stat( + if (stat( #endif - file->path, &file->_s) == -1) - { - return -1; - } + file->path, &file->_s) == -1) { + return -1; + } #endif - _tinydir_get_ext(file); + _tinydir_get_ext(file); - file->is_dir = + file->is_dir = #ifdef _MSC_VER - !!(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY); + !!(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY); #else - S_ISDIR(file->_s.st_mode); + S_ISDIR(file->_s.st_mode); #endif - file->is_reg = + file->is_reg = #ifdef _MSC_VER - !!(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_NORMAL) || - ( - !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_DEVICE) && - !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && - !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_ENCRYPTED) && + !!(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_NORMAL) || + (!(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_DEVICE) && !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && + !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_ENCRYPTED) && #ifdef FILE_ATTRIBUTE_INTEGRITY_STREAM - !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_INTEGRITY_STREAM) && + !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_INTEGRITY_STREAM) && #endif #ifdef FILE_ATTRIBUTE_NO_SCRUB_DATA - !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_NO_SCRUB_DATA) && + !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_NO_SCRUB_DATA) && #endif - !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_OFFLINE) && - !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY)); + !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_OFFLINE) && !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY)); #else - S_ISREG(file->_s.st_mode); + S_ISREG(file->_s.st_mode); #endif - return 0; + return 0; } _TINYDIR_FUNC -int tinydir_readfile_n(const tinydir_dir *dir, tinydir_file *file, size_t i) -{ - if (dir == NULL || file == NULL) - { - errno = EINVAL; - return -1; - } - if (i >= dir->n_files) - { - errno = ENOENT; - return -1; - } +int tinydir_readfile_n(const tinydir_dir *dir, tinydir_file *file, size_t i) { + if (dir == NULL || file == NULL) { + errno = EINVAL; + return -1; + } + if (i >= dir->n_files) { + errno = ENOENT; + return -1; + } - memcpy(file, &dir->_files[i], sizeof(tinydir_file)); - _tinydir_get_ext(file); + memcpy(file, &dir->_files[i], sizeof(tinydir_file)); + _tinydir_get_ext(file); - return 0; + return 0; } _TINYDIR_FUNC -int tinydir_open_subdir_n(tinydir_dir *dir, size_t i) -{ - _tinydir_char_t path[_TINYDIR_PATH_MAX]; - if (dir == NULL) - { - errno = EINVAL; - return -1; - } - if (i >= dir->n_files || !dir->_files[i].is_dir) - { - errno = ENOENT; - return -1; - } +int tinydir_open_subdir_n(tinydir_dir *dir, size_t i) { + _tinydir_char_t path[_TINYDIR_PATH_MAX]; + if (dir == NULL) { + errno = EINVAL; + return -1; + } + if (i >= dir->n_files || !dir->_files[i].is_dir) { + errno = ENOENT; + return -1; + } - _tinydir_strcpy(path, dir->_files[i].path); - tinydir_close(dir); - if (tinydir_open_sorted(dir, path) == -1) - { - return -1; - } + _tinydir_strcpy(path, dir->_files[i].path); + tinydir_close(dir); + if (tinydir_open_sorted(dir, path) == -1) { + return -1; + } - return 0; + return 0; } /* Open a single file given its path */ _TINYDIR_FUNC -int tinydir_file_open(tinydir_file *file, const _tinydir_char_t *path) -{ - tinydir_dir dir; - int result = 0; - int found = 0; - _tinydir_char_t dir_name_buf[_TINYDIR_PATH_MAX]; - _tinydir_char_t file_name_buf[_TINYDIR_FILENAME_MAX]; - _tinydir_char_t *dir_name; - _tinydir_char_t *base_name; +int tinydir_file_open(tinydir_file *file, const _tinydir_char_t *path) { + tinydir_dir dir; + int result = 0; + int found = 0; + _tinydir_char_t dir_name_buf[_TINYDIR_PATH_MAX]; + _tinydir_char_t file_name_buf[_TINYDIR_FILENAME_MAX]; + _tinydir_char_t *dir_name; + _tinydir_char_t *base_name; #if (defined _MSC_VER || defined __MINGW32__) - _tinydir_char_t drive_buf[_TINYDIR_PATH_MAX]; - _tinydir_char_t ext_buf[_TINYDIR_FILENAME_MAX]; + _tinydir_char_t drive_buf[_TINYDIR_PATH_MAX]; + _tinydir_char_t ext_buf[_TINYDIR_FILENAME_MAX]; #endif - if (file == NULL || path == NULL || _tinydir_strlen(path) == 0) - { - errno = EINVAL; - return -1; - } - if (_tinydir_strlen(path) + _TINYDIR_PATH_EXTRA >= _TINYDIR_PATH_MAX) - { - errno = ENAMETOOLONG; - return -1; - } + if (file == NULL || path == NULL || _tinydir_strlen(path) == 0) { + errno = EINVAL; + return -1; + } + if (_tinydir_strlen(path) + _TINYDIR_PATH_EXTRA >= _TINYDIR_PATH_MAX) { + errno = ENAMETOOLONG; + return -1; + } - /* Get the parent path */ + /* Get the parent path */ #if (defined _MSC_VER || defined __MINGW32__) #if ((defined _MSC_VER) && (_MSC_VER >= 1400)) - errno = _tsplitpath_s( - path, - drive_buf, _TINYDIR_DRIVE_MAX, - dir_name_buf, _TINYDIR_FILENAME_MAX, - file_name_buf, _TINYDIR_FILENAME_MAX, - ext_buf, _TINYDIR_FILENAME_MAX); + errno = _tsplitpath_s(path, drive_buf, _TINYDIR_DRIVE_MAX, dir_name_buf, _TINYDIR_FILENAME_MAX, file_name_buf, + _TINYDIR_FILENAME_MAX, ext_buf, _TINYDIR_FILENAME_MAX); #else - _tsplitpath( - path, - drive_buf, - dir_name_buf, - file_name_buf, - ext_buf); + _tsplitpath(path, drive_buf, dir_name_buf, file_name_buf, ext_buf); #endif - if (errno) - { - return -1; - } + if (errno) { + return -1; + } /* _splitpath_s not work fine with only filename and widechar support */ #ifdef _UNICODE - if (drive_buf[0] == L'\xFEFE') - drive_buf[0] = '\0'; - if (dir_name_buf[0] == L'\xFEFE') - dir_name_buf[0] = '\0'; + if (drive_buf[0] == L'\xFEFE') + drive_buf[0] = '\0'; + if (dir_name_buf[0] == L'\xFEFE') + dir_name_buf[0] = '\0'; #endif - /* Emulate the behavior of dirname by returning "." for dir name if it's - empty */ - if (drive_buf[0] == '\0' && dir_name_buf[0] == '\0') - { - _tinydir_strcpy(dir_name_buf, TINYDIR_STRING(".")); - } - /* Concatenate the drive letter and dir name to form full dir name */ - _tinydir_strcat(drive_buf, dir_name_buf); - dir_name = drive_buf; - /* Concatenate the file name and extension to form base name */ - _tinydir_strcat(file_name_buf, ext_buf); - base_name = file_name_buf; + /* Emulate the behavior of dirname by returning "." for dir name if it's + empty */ + if (drive_buf[0] == '\0' && dir_name_buf[0] == '\0') { + _tinydir_strcpy(dir_name_buf, TINYDIR_STRING(".")); + } + /* Concatenate the drive letter and dir name to form full dir name */ + _tinydir_strcat(drive_buf, dir_name_buf); + dir_name = drive_buf; + /* Concatenate the file name and extension to form base name */ + _tinydir_strcat(file_name_buf, ext_buf); + base_name = file_name_buf; #else - _tinydir_strcpy(dir_name_buf, path); - dir_name = dirname(dir_name_buf); - _tinydir_strcpy(file_name_buf, path); - base_name = basename(file_name_buf); + _tinydir_strcpy(dir_name_buf, path); + dir_name = dirname(dir_name_buf); + _tinydir_strcpy(file_name_buf, path); + base_name = basename(file_name_buf); #endif - /* Special case: if the path is a root dir, open the parent dir as the file */ + /* Special case: if the path is a root dir, open the parent dir as the file */ #if (defined _MSC_VER || defined __MINGW32__) - if (_tinydir_strlen(base_name) == 0) + if (_tinydir_strlen(base_name) == 0) #else - if ((_tinydir_strcmp(base_name, TINYDIR_STRING("/"))) == 0) + if ((_tinydir_strcmp(base_name, TINYDIR_STRING("/"))) == 0) #endif - { - memset(file, 0, sizeof * file); - file->is_dir = 1; - file->is_reg = 0; - _tinydir_strcpy(file->path, dir_name); - file->extension = file->path + _tinydir_strlen(file->path); - return 0; - } + { + memset(file, 0, sizeof *file); + file->is_dir = 1; + file->is_reg = 0; + _tinydir_strcpy(file->path, dir_name); + file->extension = file->path + _tinydir_strlen(file->path); + return 0; + } - /* Open the parent directory */ - if (tinydir_open(&dir, dir_name) == -1) - { - return -1; - } + /* Open the parent directory */ + if (tinydir_open(&dir, dir_name) == -1) { + return -1; + } - /* Read through the parent directory and look for the file */ - while (dir.has_next) - { - if (tinydir_readfile(&dir, file) == -1) - { - result = -1; - goto bail; - } - if (_tinydir_strcmp(file->name, base_name) == 0) - { - /* File found */ - found = 1; - break; - } - tinydir_next(&dir); - } - if (!found) - { - result = -1; - errno = ENOENT; - } + /* Read through the parent directory and look for the file */ + while (dir.has_next) { + if (tinydir_readfile(&dir, file) == -1) { + result = -1; + goto bail; + } + if (_tinydir_strcmp(file->name, base_name) == 0) { + /* File found */ + found = 1; + break; + } + tinydir_next(&dir); + } + if (!found) { + result = -1; + errno = ENOENT; + } bail: - tinydir_close(&dir); - return result; + tinydir_close(&dir); + return result; } _TINYDIR_FUNC -void _tinydir_get_ext(tinydir_file *file) -{ - _tinydir_char_t *period = _tinydir_strrchr(file->name, TINYDIR_STRING('.')); - if (period == NULL) - { - file->extension = &(file->name[_tinydir_strlen(file->name)]); - } - else - { - file->extension = period + 1; - } +void _tinydir_get_ext(tinydir_file *file) { + _tinydir_char_t *period = _tinydir_strrchr(file->name, TINYDIR_STRING('.')); + if (period == NULL) { + file->extension = &(file->name[_tinydir_strlen(file->name)]); + } else { + file->extension = period + 1; + } } _TINYDIR_FUNC -int _tinydir_file_cmp(const void *a, const void *b) -{ - const tinydir_file *fa = (const tinydir_file *)a; - const tinydir_file *fb = (const tinydir_file *)b; - if (fa->is_dir != fb->is_dir) - { - return -(fa->is_dir - fb->is_dir); - } - return _tinydir_strncmp(fa->name, fb->name, _TINYDIR_FILENAME_MAX); +int _tinydir_file_cmp(const void *a, const void *b) { + const tinydir_file *fa = (const tinydir_file *)a; + const tinydir_file *fb = (const tinydir_file *)b; + if (fa->is_dir != fb->is_dir) { + return -(fa->is_dir - fb->is_dir); + } + return _tinydir_strncmp(fa->name, fb->name, _TINYDIR_FILENAME_MAX); } #ifndef _MSC_VER @@ -820,36 +740,34 @@ The following authored by Ben Hutchings from https://womble.decadent.org.uk/readdir_r-advisory.html */ /* Calculate the required buffer size (in bytes) for directory * -* entries read from the given directory handle. Return -1 if this * -* this cannot be done. * -* * -* This code does not trust values of NAME_MAX that are less than * -* 255, since some systems (including at least HP-UX) incorrectly * -* define it to be a smaller value. */ + * entries read from the given directory handle. Return -1 if this * + * this cannot be done. * + * * + * This code does not trust values of NAME_MAX that are less than * + * 255, since some systems (including at least HP-UX) incorrectly * + * define it to be a smaller value. */ _TINYDIR_FUNC -size_t _tinydir_dirent_buf_size(_TINYDIR_DIR *dirp) -{ - long name_max; - size_t name_end; - /* parameter may be unused */ - (void)dirp; +size_t _tinydir_dirent_buf_size(_TINYDIR_DIR *dirp) { + long name_max; + size_t name_end; + /* parameter may be unused */ + (void)dirp; #if defined _TINYDIR_USE_FPATHCONF - name_max = fpathconf(dirfd(dirp), _PC_NAME_MAX); - if (name_max == -1) + name_max = fpathconf(dirfd(dirp), _PC_NAME_MAX); + if (name_max == -1) #if defined(NAME_MAX) - name_max = (NAME_MAX > 255) ? NAME_MAX : 255; + name_max = (NAME_MAX > 255) ? NAME_MAX : 255; #else - return (size_t)(-1); + return (size_t)(-1); #endif #elif defined(NAME_MAX) - name_max = (NAME_MAX > 255) ? NAME_MAX : 255; + name_max = (NAME_MAX > 255) ? NAME_MAX : 255; #else #error "buffer size for readdir_r cannot be determined" #endif - name_end = (size_t)offsetof(struct _tinydir_dirent, d_name) + name_max + 1; - return (name_end > sizeof(struct _tinydir_dirent) ? - name_end : sizeof(struct _tinydir_dirent)); + name_end = (size_t)offsetof(struct _tinydir_dirent, d_name) + name_max + 1; + return (name_end > sizeof(struct _tinydir_dirent) ? name_end : sizeof(struct _tinydir_dirent)); } #endif #endif @@ -858,8 +776,8 @@ size_t _tinydir_dirent_buf_size(_TINYDIR_DIR *dirp) } #endif -# if defined (_MSC_VER) -# pragma warning(pop) -# endif +#if defined(_MSC_VER) +#pragma warning(pop) +#endif #endif diff --git a/includes/private/pzx.h b/includes/private/pzx.h index 7f4b7fa2..2dc7539d 100644 --- a/includes/private/pzx.h +++ b/includes/private/pzx.h @@ -24,36 +24,36 @@ #define _PZX_H_ typedef enum { - PZX_CLOSED, /* File is not open */ - PZX_IDLE, /* File is open, no block loaded */ - PZX_IN_PULS, /* File is open, current block is a PULS block */ - PZX_IN_DATA, /* File is open, current block is a DATA block */ - PZX_IN_PAUS, /* File is open, current block is a PAUS block */ + PZX_CLOSED, /* File is not open */ + PZX_IDLE, /* File is open, no block loaded */ + PZX_IN_PULS, /* File is open, current block is a PULS block */ + PZX_IN_DATA, /* File is open, current block is a DATA block */ + PZX_IN_PAUS, /* File is open, current block is a PAUS block */ } PZX_STATE; typedef struct pzxfile_t { - FILE *input; /* Input PZX file */ - uint8_t *curblock; /* Currently-loaded block, if any */ - int level; /* Current signal level */ - PZX_STATE state; /* State machine current status */ -/* State variables for PULS */ - uint32_t puls_ptr; /* Pointer within PULS block */ - uint32_t puls_len; /* Length of PULS block */ - uint32_t puls_count; /* Count of pulses */ - uint32_t puls_duration; /* Duration of each pulse */ - uint32_t puls_remain; /* Time remaining in this pulse */ -/* State variables for PAUS */ - uint32_t paus_remain; /* Time remaining in this pause */ -/* State variables for DATA */ - uint32_t data_ptr; /* Pointer within DATA block */ - uint32_t data_bits; /* Count of bits */ - uint16_t data_tail; /* Length of pulse after last bit */ - uint8_t data_mask; /* Mask for current bit */ - uint8_t data_p0; /* Length of 0 encoding */ - uint8_t data_p1; /* Length of 1 encoding */ - int data_p; /* Current sequence being emitted */ - uint32_t data_w; /* Current waveform */ - uint32_t data_remain; /* Current data pulse time remaining */ + FILE *input; /* Input PZX file */ + uint8_t *curblock; /* Currently-loaded block, if any */ + int level; /* Current signal level */ + PZX_STATE state; /* State machine current status */ + /* State variables for PULS */ + uint32_t puls_ptr; /* Pointer within PULS block */ + uint32_t puls_len; /* Length of PULS block */ + uint32_t puls_count; /* Count of pulses */ + uint32_t puls_duration; /* Duration of each pulse */ + uint32_t puls_remain; /* Time remaining in this pulse */ + /* State variables for PAUS */ + uint32_t paus_remain; /* Time remaining in this pause */ + /* State variables for DATA */ + uint32_t data_ptr; /* Pointer within DATA block */ + uint32_t data_bits; /* Count of bits */ + uint16_t data_tail; /* Length of pulse after last bit */ + uint8_t data_mask; /* Mask for current bit */ + uint8_t data_p0; /* Length of 0 encoding */ + uint8_t data_p1; /* Length of 1 encoding */ + int data_p; /* Current sequence being emitted */ + uint32_t data_w; /* Current waveform */ + uint32_t data_remain; /* Current data pulse time remaining */ } pzxfile_t; uint8_t *pzx_load_block(FILE *fp); diff --git a/includes/private/resources.h b/includes/private/resources.h index 02b47727..e6fde283 100644 --- a/includes/private/resources.h +++ b/includes/private/resources.h @@ -1,35 +1,35 @@ -#define IDM_FILE_RESET 40000 -#define IDM_FILE_HRESET 40001 -#define IDM_FILE_EXIT 40002 +#define IDM_FILE_RESET 40000 +#define IDM_FILE_HRESET 40001 +#define IDM_FILE_EXIT 40002 #define IDM_FILE_RESET_CAD 40003 -#define IDM_DISC_A 40010 -#define IDM_DISC_B 40011 -#define IDM_EJECT_A 40012 -#define IDM_EJECT_B 40013 -#define IDM_HDCONF 40014 -#define IDM_BPB_DISABLE 40015 -#define IDM_CONFIG 40020 -#define IDM_STATUS 40030 -#define IDM_CASSETTE_LOAD 40040 +#define IDM_DISC_A 40010 +#define IDM_DISC_B 40011 +#define IDM_EJECT_A 40012 +#define IDM_EJECT_B 40013 +#define IDM_HDCONF 40014 +#define IDM_BPB_DISABLE 40015 +#define IDM_CONFIG 40020 +#define IDM_STATUS 40030 +#define IDM_CASSETTE_LOAD 40040 #define IDM_CASSETTE_EJECT 40041 -#define IDM_VID_RESIZE 40050 -#define IDM_VID_REMEMBER 40051 -#define IDM_VID_ASPECT 40052 -#define IDM_VID_DISC 40053 -#define IDM_VID_DDRAW 40060 -#define IDM_VID_D3D 40061 +#define IDM_VID_RESIZE 40050 +#define IDM_VID_REMEMBER 40051 +#define IDM_VID_ASPECT 40052 +#define IDM_VID_DISC 40053 +#define IDM_VID_DDRAW 40060 +#define IDM_VID_D3D 40061 #define IDM_VID_FULLSCREEN 40070 -#define IDM_VID_FS_FULL 40071 -#define IDM_VID_FS_43 40072 -#define IDM_VID_FS_SQ 40073 -#define IDM_VID_FS_INT 40074 -#define IDM_BUF_100MS 40080 -#define IDM_BUF_200MS 40081 -#define IDM_BUF_400MS 40082 -#define IDM_CDROM_EMPTY 40100 -#define IDM_CDROM_REAL 40100 +#define IDM_VID_FS_FULL 40071 +#define IDM_VID_FS_43 40072 +#define IDM_VID_FS_SQ 40073 +#define IDM_VID_FS_INT 40074 +#define IDM_BUF_100MS 40080 +#define IDM_BUF_200MS 40081 +#define IDM_BUF_400MS 40082 +#define IDM_CDROM_EMPTY 40100 +#define IDM_CDROM_REAL 40100 #define IDM_CDROM_DISABLED 40200 -#define IDM_CDROM_IMAGE 40201 +#define IDM_CDROM_IMAGE 40201 #define IDC_COMBO1 1000 #define IDC_COMBOVID 1001 @@ -39,11 +39,11 @@ #define IDC_COMBO486 1006 #define IDC_COMBOSND 1007 #define IDC_COMBOCPUM 1060 -#define IDC_COMBOSPD 1061 -#define IDC_COMBODRA 1062 -#define IDC_COMBODRB 1063 -#define IDC_COMBOJOY 1064 -#define IDC_COMBOWS 1065 +#define IDC_COMBOSPD 1061 +#define IDC_COMBODRA 1062 +#define IDC_COMBODRB 1063 +#define IDC_COMBOJOY 1064 +#define IDC_COMBOWS 1065 #define IDC_COMBOMOUSE 1066 #define IDC_COMBOHDD 1067 #define IDC_COMBONETCARD 1068 @@ -57,39 +57,39 @@ #define IDC_CHECKDYNAREC 1017 #define IDC_CHECKSYNC 1018 #define IDC_STATIC 1020 -#define IDC_EDIT1 1030 -#define IDC_EDIT2 1031 -#define IDC_EDIT3 1032 -#define IDC_EDIT4 1033 -#define IDC_EDIT5 1034 -#define IDC_EDIT6 1035 -#define IDC_TEXT1 1040 -#define IDC_TEXT2 1041 -#define IDC_EDITC 1050 -#define IDC_CFILE 1051 -#define IDC_CNEW 1052 -#define IDC_EDITD 1053 -#define IDC_DFILE 1054 -#define IDC_DNEW 1055 +#define IDC_EDIT1 1030 +#define IDC_EDIT2 1031 +#define IDC_EDIT3 1032 +#define IDC_EDIT4 1033 +#define IDC_EDIT5 1034 +#define IDC_EDIT6 1035 +#define IDC_TEXT1 1040 +#define IDC_TEXT2 1041 +#define IDC_EDITC 1050 +#define IDC_CFILE 1051 +#define IDC_CNEW 1052 +#define IDC_EDITD 1053 +#define IDC_DFILE 1054 +#define IDC_DNEW 1055 #define IDC_EJECTC 1056 #define IDC_EJECTD 1057 -#define IDC_EDITE 1058 -#define IDC_EFILE 1059 -#define IDC_ENEW 1060 -#define IDC_EDITF 1061 -#define IDC_FFILE 1062 -#define IDC_FNEW 1063 +#define IDC_EDITE 1058 +#define IDC_EFILE 1059 +#define IDC_ENEW 1060 +#define IDC_EDITF 1061 +#define IDC_FFILE 1062 +#define IDC_FNEW 1063 #define IDC_EJECTE 1064 #define IDC_EJECTF 1065 #define IDC_MEMSPIN 1070 #define IDC_MEMTEXT 1071 -#define IDC_CHDD 1080 +#define IDC_CHDD 1080 #define IDC_CCDROM 1081 -#define IDC_DHDD 1082 +#define IDC_DHDD 1082 #define IDC_DCDROM 1083 -#define IDC_EHDD 1084 +#define IDC_EHDD 1084 #define IDC_ECDROM 1085 -#define IDC_FHDD 1086 +#define IDC_FHDD 1086 #define IDC_FCDROM 1087 #define IDC_STEXT1 1100 #define IDC_STEXT2 1101 @@ -102,26 +102,26 @@ #define IDC_STEXT_DEVICE 1108 #define IDC_TEXT_MB 1120 -#define IDC_EDIT_C_SPT 1200 -#define IDC_EDIT_C_HPC 1201 -#define IDC_EDIT_C_CYL 1202 -#define IDC_EDIT_D_SPT 1203 -#define IDC_EDIT_D_HPC 1204 -#define IDC_EDIT_D_CYL 1205 -#define IDC_EDIT_E_SPT 1206 -#define IDC_EDIT_E_HPC 1207 -#define IDC_EDIT_E_CYL 1208 -#define IDC_EDIT_F_SPT 1209 -#define IDC_EDIT_F_HPC 1210 -#define IDC_EDIT_F_CYL 1211 +#define IDC_EDIT_C_SPT 1200 +#define IDC_EDIT_C_HPC 1201 +#define IDC_EDIT_C_CYL 1202 +#define IDC_EDIT_D_SPT 1203 +#define IDC_EDIT_D_HPC 1204 +#define IDC_EDIT_D_CYL 1205 +#define IDC_EDIT_E_SPT 1206 +#define IDC_EDIT_E_HPC 1207 +#define IDC_EDIT_E_CYL 1208 +#define IDC_EDIT_F_SPT 1209 +#define IDC_EDIT_F_HPC 1210 +#define IDC_EDIT_F_CYL 1211 #define IDC_TEXT_C_SIZE 1220 #define IDC_TEXT_D_SIZE 1221 #define IDC_TEXT_E_SIZE 1222 #define IDC_TEXT_F_SIZE 1223 -#define IDC_EDIT_C_FN 1230 -#define IDC_EDIT_D_FN 1231 -#define IDC_EDIT_E_FN 1232 -#define IDC_EDIT_F_FN 1233 +#define IDC_EDIT_C_FN 1230 +#define IDC_EDIT_D_FN 1231 +#define IDC_EDIT_E_FN 1232 +#define IDC_EDIT_F_FN 1233 #define IDC_HDTYPE 1280 #define IDC_HDFORMAT 1281 diff --git a/includes/private/rtc.h b/includes/private/rtc.h index 04ea3ac5..8ba0aa18 100644 --- a/includes/private/rtc.h +++ b/includes/private/rtc.h @@ -1,27 +1,28 @@ #ifndef _RTC_H_ #define _RTC_H_ #define BCD(X) (((X) % 10) | (((X) / 10) << 4)) -#define DCB(X) ((((X) & 0xF0) >> 4) * 10 + ((X) & 0x0F)) +#define DCB(X) ((((X)&0xF0) >> 4) * 10 + ((X)&0x0F)) enum RTC_ADDR { - RTC_SECONDS, - RTC_ALARMSECONDS, - RTC_MINUTES, - RTC_ALARMMINUTES, - RTC_HOURS, - RTC_ALARMHOURS, - RTC_DOW, - RTC_DOM, - RTC_MONTH, - RTC_YEAR, - RTC_REGA, - RTC_REGB, - RTC_REGC, - RTC_REGD + RTC_SECONDS, + RTC_ALARMSECONDS, + RTC_MINUTES, + RTC_ALARMMINUTES, + RTC_HOURS, + RTC_ALARMHOURS, + RTC_DOW, + RTC_DOM, + RTC_MONTH, + RTC_YEAR, + RTC_REGA, + RTC_REGB, + RTC_REGC, + RTC_REGD }; -/* 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. */ +/* 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. */ #define RTC_CENTURY 0x32 /* When the 12-hour format is selected, the higher-order bit of the hours byte represents PM when it is logic 1. */ @@ -29,139 +30,143 @@ enum RTC_ADDR { /* Register A bitflags */ enum RTC_RA_BITS { -/* Rate Selector (RS0) + /* Rate Selector (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. + 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. */ - RTC_RS = 0b1111, -/* DV0 + 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. */ + RTC_RS = 0b1111, + /* 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. */ - RTC_DV0 = 0b1110000, -/* Update-In-Progress (UIP) + 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. */ + RTC_DV0 = 0b1110000, + /* 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. */ - RTC_UIP = 0b10000000 + 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. */ + RTC_UIP = 0b10000000 }; /* Register B bitflags */ enum RTC_RB_BITS { -/* Daylight Saving Enable (DSE) + /* 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. */ - RTC_DSE = 0b1, -/* 24/12 + 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. */ + RTC_DSE = 0b1, + /* 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. */ - RTC_2412 = 0b10, -/* Data Mode (DM) + 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. */ + RTC_2412 = 0b10, + /* 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. */ - RTC_DM = 0b100, -/* Square-Wave Enable (SQWE) + 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. */ + RTC_DM = 0b100, + /* 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. */ - RTC_SQWE = 0b1000, -/* Update-Ended Interrupt Enable (UIE) + 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. */ + RTC_SQWE = 0b1000, + /* 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. */ - RTC_UIE = 0b10000, -/* Alarm Interrupt Enable (AIE) + 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. */ + RTC_UIE = 0b10000, + /* 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. */ - RTC_AIE = 0b100000, -/* Periodic Interrupt Enable (PIE) + 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. */ + RTC_AIE = 0b100000, + /* 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 by any internal device functions, but is cleared to 0 on !RESET. */ - RTC_PIE = 0b1000000, -/* SET + 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 by any internal device functions, but is cleared to 0 on !RESET. */ + RTC_PIE = 0b1000000, + /* 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. */ - RTC_SET = 0b10000000 + 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. */ + RTC_SET = 0b10000000 }; /* Register C bitflags */ enum RTC_RC_BITS { -/* Unused + /* Unused - These bits are unused in Register C. These bits always read 0 and cannot be written. */ - RTC_RC = 0b1111, -/* Update-Ended Interrupt Flag (UF) + These bits are unused in Register C. These bits always read 0 and cannot be written. */ + RTC_RC = 0b1111, + /* 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. */ - RTC_UF = 0b10000, -/* Alarm Interrupt Flag (AF) + 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. */ + RTC_UF = 0b10000, + /* 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. */ - RTC_AF = 0b100000, -/* Periodic Interrupt Flag (PF) + 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. */ + RTC_AF = 0b100000, + /* 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. */ - RTC_PF = 0b1000000, -/* Interrupt Request Flag (IRQF) + 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. */ + RTC_PF = 0b1000000, + /* 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 + 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. */ - RTC_IRQF = 0b10000000 + 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. */ + RTC_IRQF = 0b10000000 }; /* Register D bitflags */ enum RTC_RD_BITS { -/* Unused + /* Unused - The remaining bits of Register D are not usable. They cannot be written and they always read 0. */ - RTC_RD = 0b1111111, -/* Valid RAM and Time (VRT) + The remaining bits of Register D are not usable. They cannot be written and they always read 0. */ + RTC_RD = 0b1111111, + /* 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. */ - RTC_VRT = 0b10000000 + 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. */ + RTC_VRT = 0b10000000 }; void rtc_tick(); diff --git a/includes/private/rtc_tc8521.h b/includes/private/rtc_tc8521.h index 8526168a..caa4c3b9 100644 --- a/includes/private/rtc_tc8521.h +++ b/includes/private/rtc_tc8521.h @@ -4,36 +4,33 @@ #ifndef _RTC_TC8521_H_ #define _RTC_TC8521_H_ -enum TC8521_ADDR -{ - /* Page 0 registers */ - TC8521_SECOND1, - 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 +enum TC8521_ADDR { + /* Page 0 registers */ + TC8521_SECOND1, + 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 }; - void tc8521_tick(); void tc8521_update(uint8_t *nvrram, int reg); void tc8521_get(uint8_t *nvrram); void tc8521_internal_set_nvrram(uint8_t *nvrram); void tc8521_internal_sync(uint8_t *nvrram); - #endif /* _RTC_TC8521_H_ */ diff --git a/includes/private/scamp.h b/includes/private/scamp.h index c3e201dd..2ffa28b2 100644 --- a/includes/private/scamp.h +++ b/includes/private/scamp.h @@ -2,5 +2,4 @@ #define _SCAMP_H_ void scamp_init(void); - #endif /* _SCAMP_H_ */ diff --git a/includes/private/scsi/scsi.h b/includes/private/scsi/scsi.h index 8b42998d..82bbf39d 100644 --- a/includes/private/scsi/scsi.h +++ b/includes/private/scsi/scsi.h @@ -5,87 +5,87 @@ struct scsi_bus_t; struct atapi_device_t; typedef struct scsi_device_t { - void *(*init)(struct scsi_bus_t *bus, int id); - void *(*atapi_init)(struct scsi_bus_t *bus, int id, struct atapi_device_t *atapi_dev); - void (*close)(void *p); - void (*reset)(void *p); + void *(*init)(struct scsi_bus_t *bus, int id); + void *(*atapi_init)(struct scsi_bus_t *bus, int id, struct atapi_device_t *atapi_dev); + void (*close)(void *p); + void (*reset)(void *p); - void (*start_command)(void *p); - int (*command)(uint8_t *cdb, void *p); + void (*start_command)(void *p); + int (*command)(uint8_t *cdb, void *p); - uint8_t (*get_status)(void *p); - uint8_t (*get_sense_key)(void *p); - int (*get_bytes_required)(void *p); + uint8_t (*get_status)(void *p); + uint8_t (*get_sense_key)(void *p); + int (*get_bytes_required)(void *p); - void (*atapi_identify)(uint16_t *buffer, void *p); - int (*atapi_set_feature)(uint8_t feature, uint8_t val, void *p); + void (*atapi_identify)(uint16_t *buffer, void *p); + int (*atapi_set_feature)(uint8_t feature, uint8_t val, void *p); - uint8_t (*read)(void *p); - void (*write)(uint8_t val, void *p); - int (*read_complete)(void *p); - int (*write_complete)(void *p); + uint8_t (*read)(void *p); + void (*write)(uint8_t val, void *p); + int (*read_complete)(void *p); + int (*write_complete)(void *p); } scsi_device_t; #define CDB_MAX_LEN 20 typedef struct scsi_bus_t { - int state; - int new_state; - int clear_req; - uint32_t bus_in, bus_out; - int dev_id; + int state; + int new_state; + int clear_req; + uint32_t bus_in, bus_out; + int dev_id; - int command_pos; - uint8_t command[CDB_MAX_LEN]; + int command_pos; + uint8_t command[CDB_MAX_LEN]; - scsi_device_t *devices[8]; - void *device_data[8]; + scsi_device_t *devices[8]; + void *device_data[8]; - int change_state_delay; - int new_req_delay; + int change_state_delay; + int new_req_delay; - int is_atapi; + int is_atapi; } scsi_bus_t; -//int scsi_add_data(uint8_t val); -//int scsi_get_data(); +// int scsi_add_data(uint8_t val); +// int scsi_get_data(); void scsi_set_phase(uint8_t phase); void scsi_set_irq(uint8_t status); -#define SCSI_TEST_UNIT_READY 0x00 -#define SCSI_REZERO_UNIT 0x01 -#define SCSI_REQUEST_SENSE 0x03 -#define SCSI_FORMAT 0x04 -#define SCSI_READ_6 0x08 -#define SCSI_WRITE_6 0x0a -#define SCSI_SEEK_6 0x0b -#define SCSI_INQUIRY 0x12 -#define SCSI_MODE_SELECT_6 0x15 -#define SCSI_MODE_SENSE_6 0x1a -#define SCSI_START_STOP_UNIT 0x1b +#define SCSI_TEST_UNIT_READY 0x00 +#define SCSI_REZERO_UNIT 0x01 +#define SCSI_REQUEST_SENSE 0x03 +#define SCSI_FORMAT 0x04 +#define SCSI_READ_6 0x08 +#define SCSI_WRITE_6 0x0a +#define SCSI_SEEK_6 0x0b +#define SCSI_INQUIRY 0x12 +#define SCSI_MODE_SELECT_6 0x15 +#define SCSI_MODE_SENSE_6 0x1a +#define SCSI_START_STOP_UNIT 0x1b #define SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1e -#define SCSI_READ_CAPACITY_10 0x25 -#define SCSI_READ_10 0x28 -#define SCSI_WRITE_10 0x2a -#define SCSI_SEEK_10 0x2b -#define SCSI_WRITE_AND_VERIFY 0x2e -#define SCSI_VERIFY_10 0x2f -#define SCSI_READ_BUFFER 0x3c -#define SCSI_MODE_SENSE_10 0x5a +#define SCSI_READ_CAPACITY_10 0x25 +#define SCSI_READ_10 0x28 +#define SCSI_WRITE_10 0x2a +#define SCSI_SEEK_10 0x2b +#define SCSI_WRITE_AND_VERIFY 0x2e +#define SCSI_VERIFY_10 0x2f +#define SCSI_READ_BUFFER 0x3c +#define SCSI_MODE_SENSE_10 0x5a -#define SCSI_RESERVE 0x16 -#define SCSI_RELEASE 0x17 -#define SEND_DIAGNOSTIC 0x1d +#define SCSI_RESERVE 0x16 +#define SCSI_RELEASE 0x17 +#define SEND_DIAGNOSTIC 0x1d -#define STATUS_GOOD 0x00 +#define STATUS_GOOD 0x00 #define STATUS_CHECK_CONDITION 0x02 #define MSG_COMMAND_COMPLETE 0x00 #define BUS_DBP 0x01 #define BUS_SEL 0x02 -#define BUS_IO 0x04 -#define BUS_CD 0x08 +#define BUS_IO 0x04 +#define BUS_CD 0x08 #define BUS_MSG 0x10 #define BUS_REQ 0x20 #define BUS_BSY 0x40 @@ -109,31 +109,31 @@ void scsi_bus_reset(scsi_bus_t *bus); void scsi_bus_atapi_init(scsi_bus_t *bus, scsi_device_t *device, int id, struct atapi_device_t *atapi_dev); -#define KEY_NONE 0 -#define KEY_NOT_READY 2 -#define KEY_ILLEGAL_REQ 5 -#define KEY_UNIT_ATTENTION 6 -#define KEY_DATA_PROTECT 7 +#define KEY_NONE 0 +#define KEY_NOT_READY 2 +#define KEY_ILLEGAL_REQ 5 +#define KEY_UNIT_ATTENTION 6 +#define KEY_DATA_PROTECT 7 -#define ASC_AUDIO_PLAY_OPERATION 0x00 -#define ASC_ILLEGAL_OPCODE 0x20 -#define ASC_LBA_OUT_OF_RANGE 0x21 -#define ASC_INV_FIELD_IN_CMD_PACKET 0x24 -#define ASC_INVALID_LUN 0x25 -#define ASC_WRITE_PROTECT 0x27 -#define ASC_MEDIUM_MAY_HAVE_CHANGED 0x28 -#define ASC_MEDIUM_NOT_PRESENT 0x3a -#define ASC_DATA_PHASE_ERROR 0x4b -#define ASC_ILLEGAL_MODE_FOR_THIS_TRACK 0x64 +#define ASC_AUDIO_PLAY_OPERATION 0x00 +#define ASC_ILLEGAL_OPCODE 0x20 +#define ASC_LBA_OUT_OF_RANGE 0x21 +#define ASC_INV_FIELD_IN_CMD_PACKET 0x24 +#define ASC_INVALID_LUN 0x25 +#define ASC_WRITE_PROTECT 0x27 +#define ASC_MEDIUM_MAY_HAVE_CHANGED 0x28 +#define ASC_MEDIUM_NOT_PRESENT 0x3a +#define ASC_DATA_PHASE_ERROR 0x4b +#define ASC_ILLEGAL_MODE_FOR_THIS_TRACK 0x64 -#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_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) +#define SCSI_PHASE_MESSAGE_IN (BUS_MSG | BUS_CD | BUS_IO) #define START_STOP_START 0x01 -#define START_STOP_LOEJ 0x02 +#define START_STOP_LOEJ 0x02 #endif /*_SCSI_H_*/ diff --git a/includes/private/scsi/scsi_cd.h b/includes/private/scsi/scsi_cd.h index 7de09512..aae6d622 100644 --- a/includes/private/scsi/scsi_cd.h +++ b/includes/private/scsi/scsi_cd.h @@ -10,8 +10,9 @@ extern int cd_speed; #define MAX_CD_MODEL 12 -#define CD_MODEL_INTERFACE_ALL 0 // even when controller is not IDE and not SCSI (to always have the PCemCD model as default, even when not selectable) -#define CD_MODEL_INTERFACE_IDE 1 +#define CD_MODEL_INTERFACE_ALL \ + 0 // even when controller is not IDE and not SCSI (to always have the PCemCD model as default, even when not selectable) +#define CD_MODEL_INTERFACE_IDE 1 #define CD_MODEL_INTERFACE_SCSI 2 char *cd_get_model(int i); diff --git a/includes/private/sound/resid-fp/envelope.h b/includes/private/sound/resid-fp/envelope.h index 556e71a4..7920ab95 100644 --- a/includes/private/sound/resid-fp/envelope.h +++ b/includes/private/sound/resid-fp/envelope.h @@ -31,144 +31,137 @@ // 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(); +class EnvelopeGeneratorFP { + public: + EnvelopeGeneratorFP(); - enum State { ATTACK, DECAY_SUSTAIN, RELEASE }; + enum State { ATTACK, DECAY_SUSTAIN, RELEASE }; - RESID_INLINE void clock(); - void reset(); + RESID_INLINE void clock(); + void reset(); - void writeCONTROL_REG(reg8); - void writeATTACK_DECAY(reg8); - void writeSUSTAIN_RELEASE(reg8); - reg8 readENV(); + void writeCONTROL_REG(reg8); + void writeATTACK_DECAY(reg8); + void writeSUSTAIN_RELEASE(reg8); + reg8 readENV(); - // 8-bit envelope output. - RESID_INLINE reg8 output(); + // 8-bit envelope output. + RESID_INLINE reg8 output(); -protected: - void update_rate_period(reg16 period); + 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; + 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; + reg4 attack; + reg4 decay; + reg4 sustain; + reg4 release; - reg8 gate; + reg8 gate; - State state; + State state; - // Lookup table to convert from attack, decay, or release value to rate - // counter period. - static reg16 rate_counter_period[]; + // 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[]; + // The 16 selectable sustain levels. + static reg8 sustain_level[]; -friend class SIDFP; + friend class SIDFP; }; - // ---------------------------------------------------------------------------- // SID clocking - 1 cycle. // ---------------------------------------------------------------------------- RESID_INLINE -void EnvelopeGeneratorFP::clock() -{ - if (++ rate_counter != rate_period) - return; +void EnvelopeGeneratorFP::clock() { + if (++rate_counter != rate_period) + return; - rate_counter = 0; + 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; + // 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; - } + // 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; + 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; + } - // When the envelope counter is changed to zero, it is frozen at zero. - // This has been verified by sampling ENV3. - hold_zero = true; - 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; -} +reg8 EnvelopeGeneratorFP::output() { return envelope_counter; } #endif // not __ENVELOPE_H__ diff --git a/includes/private/sound/resid-fp/extfilt.h b/includes/private/sound/resid-fp/extfilt.h index b0e04d3b..19d59482 100644 --- a/includes/private/sound/resid-fp/extfilt.h +++ b/includes/private/sound/resid-fp/extfilt.h @@ -37,84 +37,78 @@ // of kHz. This calls for a sampling frequency of several MHz, which is far // too high for practical use. // ---------------------------------------------------------------------------- -class ExternalFilterFP -{ -public: - ExternalFilterFP(); +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); + 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(); + RESID_INLINE void clock(float Vi); + void reset(); - // Audio output (20 bits). - RESID_INLINE float output(); + // Audio output (20 bits). + RESID_INLINE float output(); -private: - void _set_sampling_parameter(); - void nuke_denormals(); + private: + void _set_sampling_parameter(); + void nuke_denormals(); - // Filter enabled. - bool enabled; + // Filter enabled. + bool enabled; - // Maximum mixer DC offset. - float mixer_DC; + // Maximum mixer DC offset. + float mixer_DC; - // Relevant clocks - float clock_frequency, pass_frequency; + // Relevant clocks + float clock_frequency, pass_frequency; - // State of filters. - float Vlp; // lowpass - float Vhp; // highpass - float Vo; + // State of filters. + float Vlp; // lowpass + float Vhp; // highpass + float Vo; - // Cutoff frequencies. - float w0lp; - float w0hp; + // Cutoff frequencies. + float w0lp; + float w0hp; -friend class SIDFP; + 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; - } +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; + 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; -} +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; +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/includes/private/sound/resid-fp/filter.h b/includes/private/sound/resid-fp/filter.h index 13e6aa67..ec249698 100644 --- a/includes/private/sound/resid-fp/filter.h +++ b/includes/private/sound/resid-fp/filter.h @@ -57,7 +57,7 @@ // // SID filter // ---------- -// +// // ----------------------------------------------- // | | // | ---Rq-- | @@ -66,15 +66,15 @@ // | | | | // | | ---C---| ---C---| // | | | | | | -// | --R1-- ---R1-- |---Rs--| |---Rs--| +// | --R1-- ---R1-- |---Rs--| |---Rs--| // | | | | | | | | // ----R1--|-----[A>--|--R-----[A>--|--R-----[A>--| // | | | | // vi -----R1-- | | | -// +// // vhp vbp vlp -// -// +// +// // vi - input voltage // vhp - highpass output // vbp - bandpass output @@ -85,14 +85,14 @@ // R - NMOS FET voltage controlled resistor controlling cutoff frequency // Rs - shunt resitor // C - capacitor -// -// -// +// +// +// // SID integrator // -------------- -// +// // V+ -// +// // | // | // -----| @@ -114,86 +114,84 @@ // R1 V- // | // | -// +// // Vw // // ---------------------------------------------------------------------------- -class FilterFP -{ -public: - FilterFP(); +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); + 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(); + 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); + // 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(); + 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; + // Filter enabled. + bool enabled; - // 6581/8580 filter model (XXX: we should specialize in separate classes) - chip_model model; + // 6581/8580 filter model (XXX: we should specialize in separate classes) + chip_model model; - // Filter cutoff frequency. - reg12 fc; + // Filter cutoff frequency. + reg12 fc; - // Filter resonance. - reg8 res; + // Filter resonance. + reg8 res; - // Selects which inputs to route through filter. - reg8 filt; + // Selects which inputs to route through filter. + reg8 filt; - // Switch voice 3 off. - reg8 voice3off; + // Switch voice 3 off. + reg8 voice3off; - // Highpass, bandpass, and lowpass filter modes. - reg8 hp_bp_lp; + // Highpass, bandpass, and lowpass filter modes. + reg8 hp_bp_lp; - // Output master volume. - reg4 vol; - float volf; /* avoid integer-to-float conversion at output */ + // Output master volume. + reg4 vol; + float volf; /* avoid integer-to-float conversion at output */ - // clock - float clock_frequency; + // clock + float clock_frequency; - /* Distortion params for Type3 */ - float distortion_rate, distortion_point, distortion_cf_threshold; + /* Distortion params for Type3 */ + float distortion_rate, distortion_point, distortion_cf_threshold; - /* Type3 params. */ - float type3_baseresistance, type3_offset, type3_steepness, type3_minimumfetresistance; + /* Type3 params. */ + float type3_baseresistance, type3_offset, type3_steepness, type3_minimumfetresistance; - /* Type4 params */ - float type4_k, type4_b; + /* Type4 params */ + float type4_k, type4_b; - // State of filter. - float Vhp, Vbp, Vlp; + // 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; + /* 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; + friend class SIDFP; }; // ---------------------------------------------------------------------------- @@ -211,173 +209,167 @@ const float outputleveldifference_bp_hp = 1.2f; RESID_INLINE static float fastexp(float val) { - typedef union { - int i; - float f; - } conv; + typedef union { + int i; + float f; + } conv; - conv tmp; + 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; + /* 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; + /* 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 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; + 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; + /* 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; +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; +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; + // 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 (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; + if (!enabled) + return (Vnf - Vi) * volf; - 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; + Vf += Vlp; if (hp_bp_lp & 2) - Vbp += (Vf + Vnf - Vbp) * distortion_cf_threshold; + Vf += Vbp; 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; + Vf += Vhp; - /* 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; + if (model == MOS6581FP) { + float diff1, diff2; - Vf += Vnf; - } - - return Vf * volf; + 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; +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/includes/private/sound/resid-fp/pot.h b/includes/private/sound/resid-fp/pot.h index e1deeabd..0248a8ca 100644 --- a/includes/private/sound/resid-fp/pot.h +++ b/includes/private/sound/resid-fp/pot.h @@ -22,10 +22,9 @@ #include "siddefs-fp.h" -class PotentiometerFP -{ -public: - reg8 readPOT(); +class PotentiometerFP { + public: + reg8 readPOT(); }; #endif diff --git a/includes/private/sound/resid-fp/sid.h b/includes/private/sound/resid-fp/sid.h index 6dad2e0c..45864c2c 100644 --- a/includes/private/sound/resid-fp/sid.h +++ b/includes/private/sound/resid-fp/sid.h @@ -26,105 +26,100 @@ #include "extfilt.h" #include "pot.h" -class SIDFP -{ -public: - SIDFP(); - ~SIDFP(); +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; } + 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 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); + void clock(); + int clock(cycle_count &delta_t, short *buf, int n, int interleave = 1); + void reset(); - // Read/write state. - class State - { - public: - State(); + // Read/write registers. + reg8 read(reg8 offset); + void write(reg8 offset, reg8 value); - char sid_register[0x20]; + // Read/write state. + class State { + public: + State(); - reg8 bus_value; - cycle_count bus_value_ttl; + char sid_register[0x20]; - 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); + reg8 bus_value; + cycle_count bus_value_ttl; - // 16-bit input (EXT IN). - void input(int sample); + 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]; + }; - // output in range -32768 .. 32767, not clipped (AUDIO OUT) - float output(); + State read_state(); + void write_state(const State &state); -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); + // 16-bit input (EXT IN). + void input(int sample); - VoiceFP voice[3]; - FilterFP filter; - ExternalFilterFP extfilt; - PotentiometerFP potx; - PotentiometerFP poty; + // output in range -32768 .. 32767, not clipped (AUDIO OUT) + float output(); - reg8 bus_value; - cycle_count bus_value_ttl; + 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); - float clock_frequency; + VoiceFP voice[3]; + FilterFP filter; + ExternalFilterFP extfilt; + PotentiometerFP potx; + PotentiometerFP poty; - // External audio input. - float ext_in; + reg8 bus_value; + cycle_count bus_value_ttl; - enum { RINGSIZE = 16384 }; + float clock_frequency; - // 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; + // External audio input. + float ext_in; - // Ring buffer with overflow for contiguous storage of RINGSIZE samples. - float* sample; + enum { RINGSIZE = 16384 }; - // FIR_RES filter tables (FIR_N*FIR_RES). - float* fir; + // Sampling variables. + sampling_method sampling; + float cycles_per_sample; + float sample_offset; + int sample_index; + int fir_N; + int fir_RES; - bool can_use_sse; + // 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/includes/private/sound/resid-fp/siddefs-fp.h b/includes/private/sound/resid-fp/siddefs-fp.h index 1f3f7271..e5a01e1c 100644 --- a/includes/private/sound/resid-fp/siddefs-fp.h +++ b/includes/private/sound/resid-fp/siddefs-fp.h @@ -21,17 +21,17 @@ #define __SIDDEFS_FP_H__ #ifndef M_PI -#define M_PI 3.14159265358979323846 -#define M_PI_f 3.14159265358979323846f +#define M_PI 3.14159265358979323846 +#define M_PI_f 3.14159265358979323846f #else -#define M_PI_f ((float) M_PI) +#define M_PI_f ((float)M_PI) #endif #ifndef M_LN2 -#define M_LN2 0.69314718055994530942 +#define M_LN2 0.69314718055994530942 #define M_LN2_f 0.69314718055994530942f #else -#define M_LN2_f ((float) M_LN2) +#define M_LN2_f ((float)M_LN2) #endif // Define bool, true, and false for C++ compilers that lack these keywords. @@ -58,16 +58,15 @@ typedef unsigned int reg24; typedef int cycle_count; -enum chip_model { MOS6581FP=1, MOS8580FP }; +enum chip_model { MOS6581FP = 1, MOS8580FP }; -enum sampling_method { SAMPLE_INTERPOLATE=1, SAMPLE_RESAMPLE_INTERPOLATE }; +enum sampling_method { SAMPLE_INTERPOLATE = 1, SAMPLE_RESAMPLE_INTERPOLATE }; -extern "C" -{ +extern "C" { #ifndef __VERSION_CC__ -extern const char* resid_version_string; +extern const char *resid_version_string; #else -const char* resid_version_string = VERSION; +const char *resid_version_string = VERSION; #endif } diff --git a/includes/private/sound/resid-fp/voice.h b/includes/private/sound/resid-fp/voice.h index 3a9e3fc9..e02036af 100644 --- a/includes/private/sound/resid-fp/voice.h +++ b/includes/private/sound/resid-fp/voice.h @@ -24,34 +24,34 @@ #include "wave.h" #include "envelope.h" -class VoiceFP -{ -public: - VoiceFP(); +class VoiceFP { + public: + VoiceFP(); - void set_chip_model(chip_model model); - void set_sync_source(VoiceFP*); - void reset(); + void set_chip_model(chip_model model); + void set_sync_source(VoiceFP *); + void reset(); - void writeCONTROL_REG(reg8); + void writeCONTROL_REG(reg8); - // Amplitude modulated waveform output. - // Range [-2048*255, 2047*255]. - RESID_INLINE float output(); + // Amplitude modulated waveform output. + // Range [-2048*255, 2047*255]. + RESID_INLINE float output(); - void set_nonlinearity(float nl); -protected: - void calculate_dac_tables(); + void set_nonlinearity(float nl); - WaveformGeneratorFP wave; - EnvelopeGeneratorFP envelope; + protected: + void calculate_dac_tables(); - // Multiplying D/A DC offset. - float voice_DC, wave_zero, nonlinearity; + WaveformGeneratorFP wave; + EnvelopeGeneratorFP envelope; - float env_dac[256]; - float voice_dac[4096]; -friend class SIDFP; + // Multiplying D/A DC offset. + float voice_DC, wave_zero, nonlinearity; + + float env_dac[256]; + float voice_dac[4096]; + friend class SIDFP; }; // ---------------------------------------------------------------------------- @@ -60,14 +60,13 @@ friend class SIDFP; // ---------------------------------------------------------------------------- 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]; +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; + return _w * _e + voice_DC; } #endif // not __VOICE_H__ diff --git a/includes/private/sound/resid-fp/wave.h b/includes/private/sound/resid-fp/wave.h index 07d229ba..404cc481 100644 --- a/includes/private/sound/resid-fp/wave.h +++ b/includes/private/sound/resid-fp/wave.h @@ -30,137 +30,137 @@ // 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(); +class WaveformGeneratorFP { + public: + WaveformGeneratorFP(); - void set_sync_source(WaveformGeneratorFP*); - void set_chip_model(chip_model model); + void set_sync_source(WaveformGeneratorFP *); + void set_chip_model(chip_model model); - RESID_INLINE void clock(); - RESID_INLINE void synchronize(); - void reset(); + 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(); + 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(); + // 12-bit waveform output. + RESID_INLINE reg12 output(); -protected: - const WaveformGeneratorFP* sync_source; - WaveformGeneratorFP* sync_dest; + protected: + const WaveformGeneratorFP *sync_source; + WaveformGeneratorFP *sync_dest; - // Tell whether the accumulator MSB was set high on this cycle. - bool msb_rising; + // 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; + 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; + // 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 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. + // 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(); + // 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[]; + // 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[]; + 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; + reg8 *wave__ST; + reg8 *wave_P_T; + reg8 *wave_PS_; + reg8 *wave_PST; -friend class VoiceFP; -friend class SIDFP; + 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___(); +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; } - } - return; - } - reg24 accumulator_prev = accumulator; + reg24 accumulator_prev = accumulator; - // Calculate new accumulator value; - accumulator += freq; - accumulator &= 0xffffff; + // 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); + // 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; + // 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___(); - } + /* 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___(); - } + // 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___(); + } } // ---------------------------------------------------------------------------- @@ -171,17 +171,15 @@ void WaveformGeneratorFP::clock() // 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; - } +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, @@ -196,21 +194,16 @@ void WaveformGeneratorFP::synchronize() // 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; +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; -} +reg12 WaveformGeneratorFP::output__S_() { return accumulator >> 12; } // Pulse: // The upper 12 bits of the accumulator are used. @@ -223,10 +216,7 @@ reg12 WaveformGeneratorFP::output__S_() // regardless of the pulse width setting. // RESID_INLINE -reg12 WaveformGeneratorFP::output_P__() -{ - return (test || accumulator >= pw_acc_scale) ? 0xfff : 0x000; -} +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 @@ -248,17 +238,10 @@ reg12 WaveformGeneratorFP::output_P__() // 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); +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: @@ -269,7 +252,7 @@ reg12 WaveformGeneratorFP::outputN___() // 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 // ----------------------- @@ -303,14 +286,14 @@ reg12 WaveformGeneratorFP::outputN___() // // 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. @@ -318,32 +301,22 @@ reg12 WaveformGeneratorFP::outputN___() // 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; +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_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__(); -} +reg12 WaveformGeneratorFP::output_PS_() { return (wave_PS_[output__S_()] << 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__(); -} +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. @@ -355,103 +328,81 @@ reg12 WaveformGeneratorFP::output_PST() // noise. We hope that nobody is actually using it. // RESID_INLINE -reg12 WaveformGeneratorFP::outputN__T() -{ - return 0; -} +reg12 WaveformGeneratorFP::outputN__T() { return 0; } RESID_INLINE -reg12 WaveformGeneratorFP::outputN_S_() -{ - return 0; -} +reg12 WaveformGeneratorFP::outputN_S_() { return 0; } RESID_INLINE -reg12 WaveformGeneratorFP::outputN_ST() -{ - return 0; -} +reg12 WaveformGeneratorFP::outputN_ST() { return 0; } RESID_INLINE -reg12 WaveformGeneratorFP::outputNP__() -{ - return 0; -} +reg12 WaveformGeneratorFP::outputNP__() { return 0; } RESID_INLINE -reg12 WaveformGeneratorFP::outputNP_T() -{ - return 0; -} +reg12 WaveformGeneratorFP::outputNP_T() { return 0; } RESID_INLINE -reg12 WaveformGeneratorFP::outputNPS_() -{ - return 0; -} +reg12 WaveformGeneratorFP::outputNPS_() { return 0; } RESID_INLINE -reg12 WaveformGeneratorFP::outputNPST() -{ - return 0; -} +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; +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/includes/private/sound/sound.h b/includes/private/sound/sound.h index 6095af2b..7abaa677 100644 --- a/includes/private/sound/sound.h +++ b/includes/private/sound/sound.h @@ -39,5 +39,4 @@ extern int sound_gain; extern int SOUNDBUFLEN; #define MAXSOUNDBUFLEN (48000 / 10) - #endif /* _SOUND_H_ */ diff --git a/includes/private/sound/sound_ad1848.h b/includes/private/sound/sound_ad1848.h index b3e38290..c1c78372 100644 --- a/includes/private/sound/sound_ad1848.h +++ b/includes/private/sound/sound_ad1848.h @@ -6,25 +6,24 @@ #define AD1848_TYPE_CS4248 1 #define AD1848_TYPE_CS4231 2 -typedef struct ad1848_t -{ +typedef struct ad1848_t { int index; uint8_t regs[32]; // 16 original + 16 CS4231A extensions uint8_t status; - + int trd; int mce; - + int count; - + int16_t out_l, out_r; - + int enable; int irq, dma; - + int freq; - + pc_timer_t timer; uint64_t timer_latch; @@ -45,5 +44,4 @@ void ad1848_speed_changed(ad1848_t *ad1848); void ad1848_init(ad1848_t *ad1848, int type); - #endif /* _SOUND_AD1848_H_ */ diff --git a/includes/private/sound/sound_adlib.h b/includes/private/sound/sound_adlib.h index a67dd879..fe621721 100644 --- a/includes/private/sound/sound_adlib.h +++ b/includes/private/sound/sound_adlib.h @@ -3,5 +3,4 @@ extern device_t adlib_device; extern device_t adlib_mca_device; - #endif /* _SOUND_ADLIB_H_ */ diff --git a/includes/private/sound/sound_adlibgold.h b/includes/private/sound/sound_adlibgold.h index 4143fd3d..a70fcaf0 100644 --- a/includes/private/sound/sound_adlibgold.h +++ b/includes/private/sound/sound_adlibgold.h @@ -2,5 +2,4 @@ #define _SOUND_ADLIBGOLD_H_ extern device_t adgold_device; - #endif /* _SOUND_ADLIBGOLD_H_ */ diff --git a/includes/private/sound/sound_audiopci.h b/includes/private/sound/sound_audiopci.h index ff22d463..0ed38206 100644 --- a/includes/private/sound/sound_audiopci.h +++ b/includes/private/sound/sound_audiopci.h @@ -2,5 +2,4 @@ #define _SOUND_AUDIOPCI_H_ extern device_t es1371_device; - #endif /* _SOUND_AUDIOPCI_H_ */ diff --git a/includes/private/sound/sound_azt2316a.h b/includes/private/sound/sound_azt2316a.h index 1db5928a..0ab58157 100644 --- a/includes/private/sound/sound_azt2316a.h +++ b/includes/private/sound/sound_azt2316a.h @@ -5,5 +5,4 @@ extern device_t azt1605_device; void azt2316a_enable_wss(uint8_t enable, void *p); - #endif /* _SOUND_AZT2316A_H_ */ diff --git a/includes/private/sound/sound_cms.h b/includes/private/sound/sound_cms.h index 0d0bb8d6..52c54383 100644 --- a/includes/private/sound/sound_cms.h +++ b/includes/private/sound/sound_cms.h @@ -2,5 +2,4 @@ #define _SOUND_CMS_H_ extern device_t cms_device; - #endif /* _SOUND_CMS_H_ */ diff --git a/includes/private/sound/sound_dbopl.h b/includes/private/sound/sound_dbopl.h index 78177784..1817b004 100644 --- a/includes/private/sound/sound_dbopl.h +++ b/includes/private/sound/sound_dbopl.h @@ -3,15 +3,15 @@ #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, int opl_emu); - 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); +void opl_init(void (*timer_callback)(void *param, int timer, int64_t period), void *timer_param, int nr, int is_opl3, + int opl_emu); +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); #ifdef __cplusplus } #endif - #endif /* _SOUND_DBOPL_H_ */ diff --git a/includes/private/sound/sound_emu8k.h b/includes/private/sound/sound_emu8k.h index aaf22286..ae0abbb8 100644 --- a/includes/private/sound/sound_emu8k.h +++ b/includes/private/sound/sound_emu8k.h @@ -5,7 +5,7 @@ #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_RAM_POINTERS_MASK 0x3F #define EMU8K_LFOCHORUS_SIZE 0x4000 /* * Everything in this file assumes little endian @@ -18,7 +18,7 @@ typedef struct emu8k_mem_internal_t { uint16_t fract_lw_address; uint16_t fract_address; uint32_t int_address; - }; + }; }; } emu8k_mem_internal_t; @@ -30,13 +30,13 @@ typedef struct emu8k_mem_pointers_t { 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. @@ -45,26 +45,27 @@ typedef struct emu8k_mem_pointers_t { 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" + " 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 + + 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 + * 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 @@ -77,9 +78,9 @@ typedef struct emu8k_mem_pointers_t { * contains the destination volume, and the lower byte contains the ramp time. */ -/* attack_amount is linear amplitude (added directly to value). +/* 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), + * 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. */ @@ -91,8 +92,6 @@ typedef struct emu8k_envelope_t { 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; @@ -100,8 +99,8 @@ typedef struct emu8k_chorus_eng_t { double lfodepth_multip; double delay_offset_samples_right; emu8k_mem_internal_t lfo_inc; - emu8k_mem_internal_t lfo_pos; - + emu8k_mem_internal_t lfo_pos; + int32_t chorus_left_buffer[EMU8K_LFOCHORUS_SIZE]; int32_t chorus_right_buffer[EMU8K_LFOCHORUS_SIZE]; @@ -110,18 +109,17 @@ typedef struct 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 + 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 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 @@ -131,7 +129,7 @@ typedef struct emu8k_chorus_eng_t { 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]; @@ -151,11 +149,11 @@ typedef struct emu8k_reverb_eng_t { uint8_t refl_in_amp; - emu8k_reverb_combfilter_t reflections[6]; + 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; @@ -163,14 +161,12 @@ typedef struct emu8k_slide_t { int32_t last; } emu8k_slide_t; - -typedef struct emu8k_voice_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 */ + uint16_t cpf_curr_pitch; /* 0x4000 = no shift. Linear increment */ }; }; union { @@ -204,21 +200,21 @@ typedef struct emu8k_voice_t uint32_t unknown_data0_5; union { uint32_t psst; - struct { + 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]; */ +#define PSST_LOOP_START_MASK 0x00FFFFFF /* In samples, i.e. uint16_t array[BOARD_RAM/2]; */ }; union { uint32_t csl; - struct { + 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]; */ +#define CSL_LOOP_END_MASK 0x00FFFFFF /* In samples, i.e. uint16_t array[BOARD_RAM/2]; */ }; union { uint32_t ccca; @@ -228,61 +224,60 @@ typedef struct emu8k_voice_t 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) - +#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) - +#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) - +#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) - +#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) - +#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) - +#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) - +#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) - - +#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 - +#define INTIAL_PITCH_CENTER 0xE000 +#define INTIAL_PITCH_OCTAVE 0x1000 + union { uint16_t ifatn; - struct{ + struct { uint8_t ifatn_attenuation; uint8_t ifatn_init_filter; }; @@ -315,17 +310,17 @@ typedef struct emu8k_voice_t 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; @@ -345,20 +340,19 @@ typedef struct emu8k_voice_t } emu8k_voice_t; -typedef struct emu8k_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. */ @@ -369,28 +363,23 @@ typedef struct emu8k_t 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[MAXSOUNDBUFLEN]; emu8k_reverb_eng_t reverb_engine; int32_t reverb_in_buffer[MAXSOUNDBUFLEN]; - + int pos; int32_t buffer[MAXSOUNDBUFLEN * 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 @@ -447,7 +436,7 @@ Section E - Introduction to the EMU8000 Chip 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, @@ -456,11 +445,11 @@ Section E - Introduction to the EMU8000 Chip 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 @@ -469,7 +458,7 @@ Section E - Introduction to the EMU8000 Chip 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 @@ -483,7 +472,7 @@ Section E - Introduction to the EMU8000 Chip 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 @@ -501,7 +490,7 @@ Section E - Introduction to the EMU8000 Chip 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, @@ -510,7 +499,7 @@ Section E - Introduction to the EMU8000 Chip 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 @@ -536,7 +525,7 @@ Section E - Introduction to the EMU8000 Chip 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. @@ -557,14 +546,14 @@ Section E - Introduction to the EMU8000 Chip 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 @@ -618,9 +607,9 @@ Section E - Introduction to the EMU8000 Chip 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) @@ -653,12 +642,12 @@ Short Delay Short Delay + Feedback // 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; + 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): @@ -699,16 +688,16 @@ Hall 1: 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 +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, diff --git a/includes/private/sound/sound_gus.h b/includes/private/sound/sound_gus.h index 657bde4d..ce786a10 100644 --- a/includes/private/sound/sound_gus.h +++ b/includes/private/sound/sound_gus.h @@ -2,5 +2,4 @@ #define _SOUND_GUS_H_ extern device_t gus_device; - #endif /* _SOUND_GUS_H_ */ diff --git a/includes/private/sound/sound_mpu401_uart.h b/includes/private/sound/sound_mpu401_uart.h index 57fd4266..eac4eb9d 100644 --- a/includes/private/sound/sound_mpu401_uart.h +++ b/includes/private/sound/sound_mpu401_uart.h @@ -1,15 +1,14 @@ #ifndef _SOUND_MPU401_UART_H_ #define _SOUND_MPU401_UART_H_ -typedef struct mpu401_uart_t -{ +typedef struct mpu401_uart_t { uint8_t status; uint8_t rx_data; int uart_mode; uint16_t addr; int irq; - + int is_aztech; } mpu401_uart_t; diff --git a/includes/private/sound/sound_opl.h b/includes/private/sound/sound_opl.h index e42078a0..fa6ce95c 100644 --- a/includes/private/sound/sound_opl.h +++ b/includes/private/sound/sound_opl.h @@ -2,16 +2,15 @@ #define _SOUND_OPL_H_ #include "sound.h" -typedef struct opl_t -{ +typedef struct opl_t { int chip_nr[2]; - + pc_timer_t timers[2][2]; int16_t filtbuf[2]; int16_t buffer[MAXSOUNDBUFLEN * 2]; - int pos; + int pos; } opl_t; uint8_t opl2_read(uint16_t a, void *priv); @@ -35,5 +34,4 @@ void opl3_update2(opl_t *opl); #define OPL_DBOPL 0 #define OPL_NUKED 1 - #endif /* _SOUND_OPL_H_ */ diff --git a/includes/private/sound/sound_pas16.h b/includes/private/sound/sound_pas16.h index 0faab5d1..53229c09 100644 --- a/includes/private/sound/sound_pas16.h +++ b/includes/private/sound/sound_pas16.h @@ -2,5 +2,4 @@ #define _SOUND_PAS16_H_ extern device_t pas16_device; - #endif /* _SOUND_PAS16_H_ */ diff --git a/includes/private/sound/sound_ps1.h b/includes/private/sound/sound_ps1.h index 8049b635..69cc86fa 100644 --- a/includes/private/sound/sound_ps1.h +++ b/includes/private/sound/sound_ps1.h @@ -2,5 +2,4 @@ #define _SOUND_PS1_H_ extern device_t ps1_audio_device; - #endif /* _SOUND_PS1_H_ */ diff --git a/includes/private/sound/sound_pssj.h b/includes/private/sound/sound_pssj.h index 0cd014af..d2d44bf0 100644 --- a/includes/private/sound/sound_pssj.h +++ b/includes/private/sound/sound_pssj.h @@ -2,5 +2,4 @@ #define _SOUND_PSSJ_H_ extern device_t pssj_device; - #endif /* _SOUND_PSSJ_H_ */ diff --git a/includes/private/sound/sound_resid.h b/includes/private/sound/sound_resid.h index 363ad631..3b48aeac 100644 --- a/includes/private/sound/sound_resid.h +++ b/includes/private/sound/sound_resid.h @@ -3,15 +3,14 @@ #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); +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 - #endif /* _SOUND_RESID_H_ */ diff --git a/includes/private/sound/sound_sb.h b/includes/private/sound/sound_sb.h index 0f0902e5..5f289318 100644 --- a/includes/private/sound/sound_sb.h +++ b/includes/private/sound/sound_sb.h @@ -16,8 +16,7 @@ extern device_t sb_16_device; extern device_t sb_awe32_device; /* SB 2.0 CD version */ -typedef struct sb_ct1335_mixer_t -{ +typedef struct sb_ct1335_mixer_t { int32_t master; int32_t voice; int32_t fm; @@ -27,86 +26,83 @@ typedef struct sb_ct1335_mixer_t uint8_t regs[256]; } sb_ct1335_mixer_t; /* SB PRO */ -typedef struct sb_ct1345_mixer_t -{ +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 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 -{ +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 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 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 +#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 +#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 -{ - opl_t opl; - sb_dsp_t dsp; +typedef struct sb_t { + 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; }; - mpu401_uart_t mpu; - emu8k_t emu8k; + mpu401_uart_t mpu; + emu8k_t emu8k; int pos; - + uint8_t pos_regs[8]; - + int opl_emu; } sb_t; @@ -114,7 +110,7 @@ typedef struct sb_t void sb_get_buffer_sbpro(int32_t *buffer, int len, void *p); void sb_ct1345_mixer_write(uint16_t addr, uint8_t val, void *p); uint8_t sb_ct1345_mixer_read(uint16_t addr, void *p); -void sb_ct1345_mixer_reset(sb_t* sb); +void sb_ct1345_mixer_reset(sb_t *sb); void sb_close(void *p); void sb_speed_changed(void *p); diff --git a/includes/private/sound/sound_sb_dsp.h b/includes/private/sound/sound_sb_dsp.h index e5e2b284..f35813ed 100644 --- a/includes/private/sound/sound_sb_dsp.h +++ b/includes/private/sound/sound_sb_dsp.h @@ -2,21 +2,22 @@ #define _SOUND_SB_DSP_H_ /*Sound Blaster Clones, for quirks*/ -#define SB_SUBTYPE_DEFAULT 0 /*Handle as a Creative card*/ +#define SB_SUBTYPE_DEFAULT 0 /*Handle as a Creative card*/ #define SB_SUBTYPE_CLONE_AZT2316A_0X11 1 /*Aztech Sound Galaxy Pro 16 AB, DSP 3.1 - SBPRO2 clone*/ -#define SB_SUBTYPE_CLONE_AZT1605_0X0C 2 /*Aztech Sound Galaxy Nova 16 Extra / Packard Bell Forte 16, DSP 2.1 - SBPRO2 clone*/ +#define SB_SUBTYPE_CLONE_AZT1605_0X0C 2 /*Aztech Sound Galaxy Nova 16 Extra / Packard Bell Forte 16, DSP 2.1 - SBPRO2 clone*/ // aztech-related -#define IS_AZTECH(dsp) ((dsp)->sb_subtype == SB_SUBTYPE_CLONE_AZT2316A_0X11 || (dsp)->sb_subtype == SB_SUBTYPE_CLONE_AZT1605_0X0C) // check for future AZT cards here -#define AZTECH_EEPROM_SIZE 16 +#define IS_AZTECH(dsp) \ + ((dsp)->sb_subtype == SB_SUBTYPE_CLONE_AZT2316A_0X11 || \ + (dsp)->sb_subtype == SB_SUBTYPE_CLONE_AZT1605_0X0C) // check for future AZT cards here +#define AZTECH_EEPROM_SIZE 16 -typedef struct sb_dsp_t -{ +typedef struct sb_dsp_t { int sb_type; int sb_subtype; // which clone - void *parent; // "sb_t *" if default subtype, "azt2316a_t *" if aztech. + void *parent; // "sb_t *" if default subtype, "azt2316a_t *" if aztech. - 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_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; @@ -37,7 +38,7 @@ typedef struct sb_dsp_t uint8_t sb_data[8]; int sb_freq; - + int16_t sbdat; int sbdat2; int16_t sbdatl, sbdatr; @@ -58,22 +59,22 @@ typedef struct sb_dsp_t int sb_irq8, sb_irq16; uint8_t sb_asp_regs[256]; - + int sbenable, sb_enable_i; - + pc_timer_t output_timer, input_timer; - + uint64_t sblatcho, sblatchi; - + uint16_t sb_addr; - + int stereo; - + int asp_data_len; - - pc_timer_t wb_timer; + + pc_timer_t wb_timer; int wb_full; - + int busy_count; int record_pos_read; diff --git a/includes/private/sound/sound_sn76489.h b/includes/private/sound/sound_sn76489.h index bae60fcb..a2ae4514 100644 --- a/includes/private/sound/sound_sn76489.h +++ b/includes/private/sound/sound_sn76489.h @@ -2,20 +2,14 @@ #define _SOUND_SN76489_H_ #include "sound.h" -enum -{ - SN76496, - NCR8496, - PSSJ -}; +enum { SN76496, NCR8496, PSSJ }; extern device_t sn76489_device; extern device_t ncr8496_device; extern int sn76489_mute; -typedef struct sn76489_t -{ +typedef struct sn76489_t { int stat[4]; int latch[4], count[4]; int freqlo[4], freqhi[4]; @@ -26,15 +20,14 @@ typedef struct sn76489_t uint8_t firstdat; int type; int extra_divide; - + int16_t buffer[MAXSOUNDBUFLEN]; 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); - #endif /* _SOUND_SN76489_H_ */ diff --git a/includes/private/sound/sound_speaker.h b/includes/private/sound/sound_speaker.h index 8597de5d..bd3c5726 100644 --- a/includes/private/sound/sound_speaker.h +++ b/includes/private/sound/sound_speaker.h @@ -9,5 +9,4 @@ extern int speaker_enable, was_speaker_enable; void speaker_update(); - #endif /* _SOUND_SPEAKER_H_ */ diff --git a/includes/private/sound/sound_ssi2001.h b/includes/private/sound/sound_ssi2001.h index 29c582ac..36db3ada 100644 --- a/includes/private/sound/sound_ssi2001.h +++ b/includes/private/sound/sound_ssi2001.h @@ -2,5 +2,4 @@ #define _SOUND_SSI2001_H_ extern device_t ssi2001_device; - #endif /* _SOUND_SSI2001_H_ */ diff --git a/includes/private/sound/sound_wss.h b/includes/private/sound/sound_wss.h index 25cf05d8..9a6d236c 100644 --- a/includes/private/sound/sound_wss.h +++ b/includes/private/sound/sound_wss.h @@ -2,5 +2,4 @@ #define _SOUND_WSS_H_ extern device_t wss_device; - #endif /* _SOUND_WSS_H_ */ diff --git a/includes/private/sound/sound_ym7128.h b/includes/private/sound/sound_ym7128.h index 50203140..86153dee 100644 --- a/includes/private/sound/sound_ym7128.h +++ b/includes/private/sound/sound_ym7128.h @@ -1,24 +1,23 @@ #ifndef _SOUND_YM7128_H_ #define _SOUND_YM7128_H_ -typedef struct ym7128_t -{ +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; @@ -26,5 +25,4 @@ 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); - #endif /* _SOUND_YM7128_H_ */ diff --git a/includes/private/thread.h b/includes/private/thread.h index da3ba50c..685cca09 100644 --- a/includes/private/thread.h +++ b/includes/private/thread.h @@ -19,5 +19,4 @@ void thread_destroy_mutex(mutex_t *mutex); void thread_sleep(int t); - #endif /* _THREAD_H_ */ diff --git a/includes/private/timer.h b/includes/private/timer.h index 181c1ce3..06b43a2a 100644 --- a/includes/private/timer.h +++ b/includes/private/timer.h @@ -7,7 +7,7 @@ 32:32 fixed point format, with the integer part compared against the TSC. The fractional part is used when advancing the timestamp to ensure a more accurate period. - + As the timer only stores 32 bits of integer timestamp, and the TSC is 64 bits, the timer period can only be at most 0x7fffffff CPU cycles. To allow room for (optimistic) CPU frequency growth, timer period must be at most 1 second. @@ -15,16 +15,15 @@ When a timer callback is called, the timer has been disabled. If the timer is to repeat, the callback must call timer_advance_u64(). This is a change from the old timer API.*/ -typedef struct pc_timer_t -{ - uint32_t ts_integer; - uint32_t ts_frac; - int enabled; +typedef struct pc_timer_t { + uint32_t ts_integer; + uint32_t ts_frac; + int enabled; - void (*callback)(void *p); - void *p; + void (*callback)(void *p); + void *p; - struct pc_timer_t *prev, *next; + struct pc_timer_t *prev, *next; } pc_timer_t; /*Timestamp of nearest enabled timer. CPU emulation must call timer_process() @@ -58,85 +57,67 @@ extern uint64_t TIMER_USEC; /*Advance timer by delay, specified in 32:32 format. This should be used to resume a recurring timer in a callback routine*/ -static inline void timer_advance_u64(pc_timer_t *timer, uint64_t delay) -{ - uint32_t int_delay = delay >> 32; - uint32_t frac_delay = delay & 0xffffffff; +static inline void timer_advance_u64(pc_timer_t *timer, uint64_t delay) { + uint32_t int_delay = delay >> 32; + uint32_t frac_delay = delay & 0xffffffff; - if ((frac_delay + timer->ts_frac) < frac_delay) - timer->ts_integer++; - timer->ts_frac += frac_delay; - timer->ts_integer += int_delay; + if ((frac_delay + timer->ts_frac) < frac_delay) + timer->ts_integer++; + timer->ts_frac += frac_delay; + timer->ts_integer += int_delay; - timer_enable(timer); + timer_enable(timer); } /*Set a timer to the given delay, specified in 32:32 format. This should be used when starting a timer*/ -static inline void timer_set_delay_u64(pc_timer_t *timer, uint64_t delay) -{ - uint32_t int_delay = delay >> 32; - uint32_t frac_delay = delay & 0xffffffff; +static inline void timer_set_delay_u64(pc_timer_t *timer, uint64_t delay) { + uint32_t int_delay = delay >> 32; + uint32_t frac_delay = delay & 0xffffffff; - timer->ts_frac = frac_delay; - timer->ts_integer = int_delay + (uint32_t)tsc; + timer->ts_frac = frac_delay; + timer->ts_integer = int_delay + (uint32_t)tsc; - timer_enable(timer); + timer_enable(timer); } /*True if timer currently enabled*/ -static inline int timer_is_enabled(pc_timer_t *timer) -{ - return timer->enabled; -} +static inline int timer_is_enabled(pc_timer_t *timer) { return timer->enabled; } /*Return integer timestamp of timer*/ -static inline uint32_t timer_get_ts_int(pc_timer_t *timer) -{ - return timer->ts_integer; -} +static inline uint32_t timer_get_ts_int(pc_timer_t *timer) { return timer->ts_integer; } /*Return remaining time before timer expires, in us. If the timer has already expired then return 0*/ -static inline uint32_t timer_get_remaining_us(pc_timer_t *timer) -{ - if (timer->enabled) - { - int64_t remaining = (((uint64_t)timer->ts_integer << 32) | timer->ts_frac) - (tsc << 32); +static inline uint32_t timer_get_remaining_us(pc_timer_t *timer) { + if (timer->enabled) { + int64_t remaining = (((uint64_t)timer->ts_integer << 32) | timer->ts_frac) - (tsc << 32); - if (remaining < 0) - return 0; - return remaining / TIMER_USEC; - } + if (remaining < 0) + return 0; + return remaining / TIMER_USEC; + } - return 0; + return 0; } /*Return remaining time before timer expires, in 32:32 timestamp format. If the timer has already expired then return 0*/ -static inline uint64_t timer_get_remaining_u64(pc_timer_t *timer) -{ - if (timer->enabled) - { - int64_t remaining = (((uint64_t)timer->ts_integer << 32) | timer->ts_frac) - (tsc << 32); +static inline uint64_t timer_get_remaining_u64(pc_timer_t *timer) { + if (timer->enabled) { + int64_t remaining = (((uint64_t)timer->ts_integer << 32) | timer->ts_frac) - (tsc << 32); - if (remaining < 0) - return 0; - return remaining; - } + if (remaining < 0) + return 0; + return remaining; + } - return 0; + return 0; } /*Set timer callback function*/ -static inline void timer_set_callback(pc_timer_t *timer, void (*callback)(void *p)) -{ - timer->callback = callback; -} +static inline void timer_set_callback(pc_timer_t *timer, void (*callback)(void *p)) { timer->callback = callback; } /*Set timer private data*/ -static inline void timer_set_p(pc_timer_t *timer, void *p) -{ - timer->p = p; -} +static inline void timer_set_p(pc_timer_t *timer, void *p) { timer->p = p; } #endif /*_TIMER_H_*/ diff --git a/includes/private/video/vid_ati18800.h b/includes/private/video/vid_ati18800.h index fa71abeb..923de633 100644 --- a/includes/private/video/vid_ati18800.h +++ b/includes/private/video/vid_ati18800.h @@ -3,5 +3,4 @@ extern device_t ati18800_device; extern device_t ati_ega_wonder_800_device; - #endif /* _VID_ATI18800_H_ */ diff --git a/includes/private/video/vid_ati28800.h b/includes/private/video/vid_ati28800.h index 9e27f3db..2d00a783 100644 --- a/includes/private/video/vid_ati28800.h +++ b/includes/private/video/vid_ati28800.h @@ -5,5 +5,4 @@ extern device_t ati28800k_device; extern device_t ati28800k_spc4620p_device; extern device_t ati28800k_spc6033p_device; - #endif /* _VID_ATI28800_H_ */ diff --git a/includes/private/video/vid_ati68860_ramdac.h b/includes/private/video/vid_ati68860_ramdac.h index 1a841b77..ff847850 100644 --- a/includes/private/video/vid_ati68860_ramdac.h +++ b/includes/private/video/vid_ati68860_ramdac.h @@ -1,15 +1,14 @@ #ifndef _VID_ATI68860_RAMDAC_H_ #define _VID_ATI68860_RAMDAC_H_ -typedef struct ati68860_ramdac_t -{ +typedef struct ati68860_ramdac_t { uint8_t regs[16]; void (*render)(struct svga_t *svga); - + int dac_write, dac_pos; int dac_r, dac_g; PALETTE pal; uint32_t pallook[2]; - + int ramdac_type; } ati68860_ramdac_t; @@ -18,5 +17,4 @@ uint8_t ati68860_ramdac_in(uint16_t addr, ati68860_ramdac_t *ramdac, svga_t *svg void ati68860_ramdac_init(ati68860_ramdac_t *ramdac); void ati68860_set_ramdac_type(ati68860_ramdac_t *ramdac, int type); - #endif /* _VID_ATI68860_RAMDAC_H_ */ diff --git a/includes/private/video/vid_ati_eeprom.h b/includes/private/video/vid_ati_eeprom.h index 57b15cc0..fdda2b48 100644 --- a/includes/private/video/vid_ati_eeprom.h +++ b/includes/private/video/vid_ati_eeprom.h @@ -1,7 +1,6 @@ #ifndef _VID_ATI_EEPROM_H_ #define _VID_ATI_EEPROM_H_ -typedef struct ati_eeprom_t -{ +typedef struct ati_eeprom_t { uint16_t data[256]; int oldclk, oldena; @@ -17,5 +16,4 @@ void ati_eeprom_load(ati_eeprom_t *eeprom, char *fn, int type); void ati_eeprom_write(ati_eeprom_t *eeprom, int ena, int clk, int dat); int ati_eeprom_read(ati_eeprom_t *eeprom); - #endif /* _VID_ATI_EEPROM_H_ */ diff --git a/includes/private/video/vid_ati_mach64.h b/includes/private/video/vid_ati_mach64.h index bbdc73cf..168fd431 100644 --- a/includes/private/video/vid_ati_mach64.h +++ b/includes/private/video/vid_ati_mach64.h @@ -3,5 +3,4 @@ extern device_t mach64gx_device; extern device_t mach64vt2_device; - #endif /* _VID_ATI_MACH64_H_ */ diff --git a/includes/private/video/vid_cga.h b/includes/private/video/vid_cga.h index 2010ed7a..2423ef26 100644 --- a/includes/private/video/vid_cga.h +++ b/includes/private/video/vid_cga.h @@ -1,17 +1,16 @@ #ifndef _VID_CGA_H_ #define _VID_CGA_H_ -typedef struct cga_t -{ +typedef struct cga_t { mem_mapping_t mapping; - + int crtcreg; uint8_t crtc[32]; - + uint8_t cgastat; - + uint8_t cgamode, cgacol; - int fontbase; + int fontbase; int linepos, displine; int sc, vc; int cgadispon; @@ -21,30 +20,29 @@ typedef struct cga_t int oddeven; uint64_t dispontime, dispofftime; - pc_timer_t timer; - + pc_timer_t timer; + int firstline, lastline; - + int drawcursor; - + uint8_t *vram; - + uint8_t charbuffer[256]; - int revision; - int composite; - int snow_enabled; + int revision; + int composite; + int snow_enabled; } cga_t; -void cga_init(cga_t *cga); -void cga_out(uint16_t addr, uint8_t val, void *p); +void cga_init(cga_t *cga); +void cga_out(uint16_t addr, uint8_t val, void *p); uint8_t cga_in(uint16_t addr, void *p); -void cga_write(uint32_t addr, uint8_t val, void *p); +void cga_write(uint32_t addr, uint8_t val, void *p); uint8_t cga_read(uint32_t addr, void *p); -void cga_recalctimings(cga_t *cga); -void cga_poll(void *p); +void cga_recalctimings(cga_t *cga); +void cga_poll(void *p); extern device_t cga_device; - #endif /* _VID_CGA_H_ */ diff --git a/includes/private/video/vid_cl5429.h b/includes/private/video/vid_cl5429.h index bd238318..a087bbbe 100644 --- a/includes/private/video/vid_cl5429.h +++ b/includes/private/video/vid_cl5429.h @@ -12,5 +12,4 @@ extern device_t gd5430_pb570_device; extern device_t gd5434_device; extern device_t gd5434_pb520r_device; - #endif /* _VID_CL5429_H_ */ diff --git a/includes/private/video/vid_colorplus.h b/includes/private/video/vid_colorplus.h index 1cd5591d..679977f0 100644 --- a/includes/private/video/vid_colorplus.h +++ b/includes/private/video/vid_colorplus.h @@ -2,5 +2,4 @@ #define _VID_COLORPLUS_H_ extern device_t colorplus_device; - #endif /* _VID_COLORPLUS_H_ */ diff --git a/includes/private/video/vid_compaq_cga.h b/includes/private/video/vid_compaq_cga.h index 8eb0159f..faca6011 100644 --- a/includes/private/video/vid_compaq_cga.h +++ b/includes/private/video/vid_compaq_cga.h @@ -2,5 +2,4 @@ #define _VID_COMPAQ_CGA_H_ extern device_t compaq_cga_device; - #endif /* _VID_COMPAQ_CGA_H_ */ diff --git a/includes/private/video/vid_ddc.h b/includes/private/video/vid_ddc.h index 24935987..ee5997f2 100644 --- a/includes/private/video/vid_ddc.h +++ b/includes/private/video/vid_ddc.h @@ -5,5 +5,4 @@ void ddc_i2c_change(int new_clock, int new_data); int ddc_read_clock(void); int ddc_read_data(void); - #endif /* _VID_DDC_H_ */ diff --git a/includes/private/video/vid_ega.h b/includes/private/video/vid_ega.h index d7d513b5..90b4dddb 100644 --- a/includes/private/video/vid_ega.h +++ b/includes/private/video/vid_ega.h @@ -1,11 +1,10 @@ #ifndef _VID_EGA_H_ #define _VID_EGA_H_ -typedef struct ega_t -{ +typedef struct ega_t { mem_mapping_t mapping; - + rom_t bios_rom; - + uint8_t crtcreg; uint8_t crtc[32]; uint8_t gdcreg[16]; @@ -14,38 +13,38 @@ typedef struct ega_t int attraddr, attrff; uint8_t seqregs[64]; int seqaddr; - + uint8_t miscout; int vidclock; uint8_t la, lb, lc, ld; - + uint8_t stat; - + int fast; uint8_t colourcompare, colournocare; int readmode, writemode, readplane; int chain4, chain2_read, chain2_write; uint8_t writemask; uint32_t charseta, charsetb; - + uint8_t egapal[16]; uint32_t *pallook; int vtotal, dispend, vsyncstart, split; - int hdisp, htotal, hdisp_time, rowoffset; + int hdisp, htotal, hdisp_time, rowoffset; int lowres, interlace; int linedbl, rowcount; double clock; uint32_t ma_latch; - + int vres; - + uint64_t dispontime, dispofftime; - pc_timer_t timer; - + pc_timer_t timer; + uint8_t scrblank; - + int dispon; int hdisp_on; @@ -55,11 +54,11 @@ typedef struct ega_t int linepos, vslines, linecountff, oddeven; int con, cursoron, blink; int scrollcache; - + int firstline, lastline; int firstline_draw, lastline_draw; int displine; - + uint8_t *vram; int vrammask; uint32_t vram_limit; @@ -68,16 +67,15 @@ typedef struct ega_t int frames; } ega_t; -void *ega_standalone_init(); -void ega_out(uint16_t addr, uint8_t val, void *p); +void *ega_standalone_init(); +void ega_out(uint16_t addr, uint8_t val, void *p); uint8_t ega_in(uint16_t addr, void *p); -void ega_poll(void *p); -void ega_recalctimings(struct ega_t *ega); -void ega_write(uint32_t addr, uint8_t val, void *p); +void ega_poll(void *p); +void ega_recalctimings(struct ega_t *ega); +void ega_write(uint32_t addr, uint8_t val, void *p); uint8_t ega_read(uint32_t addr, void *p); -void ega_init(ega_t *ega, int monitor_type, int is_mono); +void ega_init(ega_t *ega, int monitor_type, int is_mono); extern device_t ega_device; - #endif /* _VID_EGA_H_ */ diff --git a/includes/private/video/vid_et4000.h b/includes/private/video/vid_et4000.h index 88096f76..8e802f17 100644 --- a/includes/private/video/vid_et4000.h +++ b/includes/private/video/vid_et4000.h @@ -4,5 +4,4 @@ extern device_t et4000_device; extern device_t et4000k_device; extern device_t et4000_kasan_device; - #endif /* _VID_ET4000_H_ */ diff --git a/includes/private/video/vid_et4000w32.h b/includes/private/video/vid_et4000w32.h index 9fa23894..92bda066 100644 --- a/includes/private/video/vid_et4000w32.h +++ b/includes/private/video/vid_et4000w32.h @@ -2,5 +2,4 @@ #define _VID_ET4000W32_H_ extern device_t et4000w32p_device; - #endif /* _VID_ET4000W32_H_ */ diff --git a/includes/private/video/vid_genius.h b/includes/private/video/vid_genius.h index 2568164e..3cf15fda 100644 --- a/includes/private/video/vid_genius.h +++ b/includes/private/video/vid_genius.h @@ -2,5 +2,4 @@ #define _VID_GENIUS_H_ extern device_t genius_device; - #endif /* _VID_GENIUS_H_ */ diff --git a/includes/private/video/vid_hercules.h b/includes/private/video/vid_hercules.h index f52fd96c..31df1f1f 100644 --- a/includes/private/video/vid_hercules.h +++ b/includes/private/video/vid_hercules.h @@ -2,5 +2,4 @@ #define _VID_HERCULES_H_ extern device_t hercules_device; - #endif /* _VID_HERCULES_H_ */ diff --git a/includes/private/video/vid_ht216.h b/includes/private/video/vid_ht216.h index ed8e8645..c0239a6b 100644 --- a/includes/private/video/vid_ht216.h +++ b/includes/private/video/vid_ht216.h @@ -2,5 +2,4 @@ #define _VID_HT216_H_ extern device_t ht216_32_pb410a_device; - #endif /* _VID_HT216_H_ */ diff --git a/includes/private/video/vid_icd2061.h b/includes/private/video/vid_icd2061.h index 653d413a..f18c1c70 100644 --- a/includes/private/video/vid_icd2061.h +++ b/includes/private/video/vid_icd2061.h @@ -1,7 +1,6 @@ #ifndef _VID_ICD2061_H_ #define _VID_ICD2061_H_ -typedef struct icd2061_t -{ +typedef struct icd2061_t { int state; int status; int pos; @@ -15,5 +14,4 @@ typedef struct icd2061_t void icd2061_write(icd2061_t *icd2061, int val); double icd2061_getfreq(icd2061_t *icd2061, int i); - #endif /* _VID_ICD2061_H_ */ diff --git a/includes/private/video/vid_ics2595.h b/includes/private/video/vid_ics2595.h index 25404e3b..439a709f 100644 --- a/includes/private/video/vid_ics2595.h +++ b/includes/private/video/vid_ics2595.h @@ -1,7 +1,6 @@ #ifndef _VID_ICS2595_H_ #define _VID_ICS2595_H_ -typedef struct ics2595_t -{ +typedef struct ics2595_t { int oldfs3, oldfs2; int dat; int pos; @@ -13,5 +12,4 @@ typedef struct ics2595_t void ics2595_write(ics2595_t *ics2595, int strobe, int dat); - #endif /* _VID_ICS2595_H_ */ diff --git a/includes/private/video/vid_im1024.h b/includes/private/video/vid_im1024.h index e80267fe..caeb44cd 100644 --- a/includes/private/video/vid_im1024.h +++ b/includes/private/video/vid_im1024.h @@ -2,5 +2,4 @@ #define _VID_IM1024_H_ extern device_t im1024_device; - #endif /* _VID_IM1024_H_ */ diff --git a/includes/private/video/vid_incolor.h b/includes/private/video/vid_incolor.h index ea4a1e4a..2f97c25e 100644 --- a/includes/private/video/vid_incolor.h +++ b/includes/private/video/vid_incolor.h @@ -2,5 +2,4 @@ #define _VID_INCOLOR_H_ extern device_t incolor_device; - #endif /* _VID_INCOLOR_H_ */ diff --git a/includes/private/video/vid_mda.h b/includes/private/video/vid_mda.h index 42c9b0fe..8dc28cb6 100644 --- a/includes/private/video/vid_mda.h +++ b/includes/private/video/vid_mda.h @@ -1,15 +1,14 @@ #ifndef _VID_MDA_H_ #define _VID_MDA_H_ -typedef struct mda_t -{ +typedef struct mda_t { mem_mapping_t mapping; - + uint8_t crtc[32]; int crtcreg; - + uint8_t ctrl, stat; - + uint64_t dispontime, dispofftime; pc_timer_t timer; @@ -38,6 +37,4 @@ void mda_setcol(int chr, int blink, int fg, uint8_t cga_ink); extern device_t mda_device; - - #endif /* _VID_MDA_H_ */ diff --git a/includes/private/video/vid_olivetti_m24.h b/includes/private/video/vid_olivetti_m24.h index 450b5430..b6d6e46a 100644 --- a/includes/private/video/vid_olivetti_m24.h +++ b/includes/private/video/vid_olivetti_m24.h @@ -2,5 +2,4 @@ #define _VID_OLIVETTI_M24_H_ extern device_t m24_device; - #endif /* _VID_OLIVETTI_M24_H_ */ diff --git a/includes/private/video/vid_oti037.h b/includes/private/video/vid_oti037.h index 85a9c8eb..b566e0af 100644 --- a/includes/private/video/vid_oti037.h +++ b/includes/private/video/vid_oti037.h @@ -2,5 +2,4 @@ #define _VID_OTI037_H_ extern device_t oti037_device; - #endif /* _VID_OTI037_H_ */ diff --git a/includes/private/video/vid_oti067.h b/includes/private/video/vid_oti067.h index 949d4b0c..ca55b5da 100644 --- a/includes/private/video/vid_oti067.h +++ b/includes/private/video/vid_oti067.h @@ -6,5 +6,4 @@ extern device_t oti067_ama932j_device; void oti067_enable_disable(void *p, int enable); - #endif /* _VID_OTI067_H_ */ diff --git a/includes/private/video/vid_paradise.h b/includes/private/video/vid_paradise.h index 6a2a0a4d..5fd8233b 100644 --- a/includes/private/video/vid_paradise.h +++ b/includes/private/video/vid_paradise.h @@ -5,5 +5,4 @@ extern device_t paradise_pvga1a_pc3086_device; extern device_t paradise_wd90c11_megapc_device; extern device_t paradise_pvga1a_oli_go481_device; - #endif /* _VID_PARADISE_H_ */ diff --git a/includes/private/video/vid_pc1512.h b/includes/private/video/vid_pc1512.h index f8242276..9e75d732 100644 --- a/includes/private/video/vid_pc1512.h +++ b/includes/private/video/vid_pc1512.h @@ -2,5 +2,4 @@ #define _VID_PC1512_H_ extern device_t pc1512_device; - #endif /* _VID_PC1512_H_ */ diff --git a/includes/private/video/vid_pc1640.h b/includes/private/video/vid_pc1640.h index 5b55b25d..d91978ff 100644 --- a/includes/private/video/vid_pc1640.h +++ b/includes/private/video/vid_pc1640.h @@ -2,5 +2,4 @@ #define _VID_PC1640_H_ extern device_t pc1640_device; - #endif /* _VID_PC1640_H_ */ diff --git a/includes/private/video/vid_pc200.h b/includes/private/video/vid_pc200.h index e5f9170e..2c73a54f 100644 --- a/includes/private/video/vid_pc200.h +++ b/includes/private/video/vid_pc200.h @@ -5,5 +5,4 @@ extern device_t ppc512_device; extern int pc200_is_mda; - #endif /* _VID_PC200_H_ */ diff --git a/includes/private/video/vid_pcjr.h b/includes/private/video/vid_pcjr.h index 0e81faae..ae028388 100644 --- a/includes/private/video/vid_pcjr.h +++ b/includes/private/video/vid_pcjr.h @@ -3,5 +3,4 @@ extern device_t pcjr_video_device; extern device_t pcjr_device; - #endif /* _VID_PCJR_H_ */ diff --git a/includes/private/video/vid_pgc.h b/includes/private/video/vid_pgc.h index 64325b92..18275699 100644 --- a/includes/private/video/vid_pgc.h +++ b/includes/private/video/vid_pgc.h @@ -4,75 +4,70 @@ struct pgc_core_t; -typedef struct pgc_commandlist_t -{ - uint8_t *list; - uint32_t listmax; - uint32_t wrptr; - uint32_t rdptr; - uint32_t repeat; - struct pgc_commandlist_t *chain; +typedef struct pgc_commandlist_t { + uint8_t *list; + uint32_t listmax; + uint32_t wrptr; + uint32_t rdptr; + uint32_t repeat; + struct pgc_commandlist_t *chain; } pgc_commandlist_t; int pgc_commandlist_append(pgc_commandlist_t *list, uint8_t v); -typedef struct pgc_command_t -{ - char ascii[6]; - uint8_t hex; - void (*handler)(struct pgc_core_t *pgc); - int (*parser) (struct pgc_core_t *pgc, pgc_commandlist_t *cl, - int p); - int p; +typedef struct pgc_command_t { + char ascii[6]; + uint8_t hex; + void (*handler)(struct pgc_core_t *pgc); + int (*parser)(struct pgc_core_t *pgc, pgc_commandlist_t *cl, int p); + int p; } pgc_command_t; - -typedef struct pgc_core_t -{ +typedef struct pgc_core_t { mem_mapping_t mapping; mem_mapping_t cga_mapping; - - pgc_commandlist_t *clist; - pgc_commandlist_t *clcur; - uint8_t mapram[2048]; /* Host <--> PGC communication buffer */ + + pgc_commandlist_t *clist; + pgc_commandlist_t *clcur; + uint8_t mapram[2048]; /* Host <--> PGC communication buffer */ uint8_t *cga_vram; uint8_t *vram; - char asc_command[7]; - uint8_t hex_command; - uint32_t palette[256]; - uint32_t userpal[256]; - uint32_t maxw, maxh; /* Maximum framebuffer size */ - uint32_t visw, vish; /* Maximum screen size */ - uint32_t screenw, screenh; - int16_t pan_x, pan_y; - uint16_t win_x1, win_x2, win_y1, win_y2; - uint16_t vp_x1, vp_x2, vp_y1, vp_y2; - int16_t fill_pattern[16]; - int16_t line_pattern; - uint8_t draw_mode; - uint8_t fill_mode; - uint8_t colour; - uint8_t tjust_h; /* Horizontal alignment 1=left 2=centre 3=right*/ - uint8_t tjust_v; /* Vertical alignment 1=bottom 2=centre 3=top*/ - int32_t tsize; /* Horizontal spacing */ + char asc_command[7]; + uint8_t hex_command; + uint32_t palette[256]; + uint32_t userpal[256]; + uint32_t maxw, maxh; /* Maximum framebuffer size */ + uint32_t visw, vish; /* Maximum screen size */ + uint32_t screenw, screenh; + int16_t pan_x, pan_y; + uint16_t win_x1, win_x2, win_y1, win_y2; + uint16_t vp_x1, vp_x2, vp_y1, vp_y2; + int16_t fill_pattern[16]; + int16_t line_pattern; + uint8_t draw_mode; + uint8_t fill_mode; + uint8_t colour; + uint8_t tjust_h; /* Horizontal alignment 1=left 2=centre 3=right*/ + uint8_t tjust_v; /* Vertical alignment 1=bottom 2=centre 3=top*/ + int32_t tsize; /* Horizontal spacing */ - int32_t x, y, z;/* Drawing position */ + int32_t x, y, z; /* Drawing position */ - const pgc_command_t *pgc_commands; - thread_t *pgc_thread; - event_t *pgc_wake_thread; + const pgc_command_t *pgc_commands; + thread_t *pgc_thread; + event_t *pgc_wake_thread; pc_timer_t wake_timer; -// int wake_timer; + // int wake_timer; - int waiting_input_fifo; - int waiting_output_fifo; - int waiting_error_fifo; - int cga_enabled; - int cga_selected; - int ascii_mode; - int result_count; - - int fontbase; + int waiting_input_fifo; + int waiting_output_fifo; + int waiting_error_fifo; + int cga_enabled; + int cga_selected; + int ascii_mode; + int result_count; + + int fontbase; int linepos, displine; int vc; int cgadispon; @@ -83,61 +78,61 @@ typedef struct pgc_core_t uint64_t dispontime, dispofftime; pc_timer_t timer; -// int vidtime; + // int vidtime; double native_pixel_clock; - + int drawcursor; - - int (*inputbyte)(struct pgc_core_t *pgc, uint8_t *result); + + int (*inputbyte)(struct pgc_core_t *pgc, uint8_t *result); } pgc_core_t; -void pgc_init(pgc_core_t *pgc); -void pgc_out(uint16_t addr, uint8_t val, void *p); +void pgc_init(pgc_core_t *pgc); +void pgc_out(uint16_t addr, uint8_t val, void *p); uint8_t pgc_in(uint16_t addr, void *p); -void pgc_write(uint32_t addr, uint8_t val, void *p); +void pgc_write(uint32_t addr, uint8_t val, void *p); uint8_t pgc_read(uint32_t addr, void *p); -void pgc_recalctimings(pgc_core_t *pgc); -void pgc_poll(void *p); -void pgc_reset(pgc_core_t *pgc); -void pgc_wake(pgc_core_t *pgc); +void pgc_recalctimings(pgc_core_t *pgc); +void pgc_poll(void *p); +void pgc_reset(pgc_core_t *pgc); +void pgc_wake(pgc_core_t *pgc); /* Plot a pixel (raster coordinates, current ink) */ -void pgc_plot(pgc_core_t *pgc, uint16_t x, uint16_t y); -void pgc_write_pixel(pgc_core_t *pgc, uint16_t x, uint16_t y, uint8_t ink); +void pgc_plot(pgc_core_t *pgc, uint16_t x, uint16_t y); +void pgc_write_pixel(pgc_core_t *pgc, uint16_t x, uint16_t y, uint8_t ink); uint8_t pgc_read_pixel(pgc_core_t *pgc, uint16_t x, uint16_t y); uint8_t *pgc_vram_addr(pgc_core_t *pgc, int16_t x, int16_t y); /* Draw line (window coordinates) */ uint16_t pgc_draw_line(pgc_core_t *pgc, int32_t x1, int32_t y1, int32_t x2, int32_t y2, uint16_t linemask); /* Draw line (raster coordinates) */ uint16_t pgc_draw_line_r(pgc_core_t *pgc, int32_t x1, int32_t y1, int32_t x2, int32_t y2, uint16_t linemask); -void pgc_draw_ellipse(pgc_core_t *pgc, int32_t x, int32_t y); -void pgc_fill_polygon(pgc_core_t *pgc, unsigned corners, int32_t *x, int32_t *y); +void pgc_draw_ellipse(pgc_core_t *pgc, int32_t x, int32_t y); +void pgc_fill_polygon(pgc_core_t *pgc, unsigned corners, int32_t *x, int32_t *y); /* Horizontal line in fill pattern (raster coordinates) */ -void pgc_fill_line_r(pgc_core_t *pgc, int32_t x0, int32_t x1, int32_t y); +void pgc_fill_line_r(pgc_core_t *pgc, int32_t x0, int32_t x1, int32_t y); /* Convert to raster coordinates */ -void pgc_sto_raster(pgc_core_t *pgc, int16_t *x, int16_t *y); -void pgc_ito_raster(pgc_core_t *pgc, int32_t *x, int32_t *y); -void pgc_dto_raster(pgc_core_t *pgc, double *x, double *y); +void pgc_sto_raster(pgc_core_t *pgc, int16_t *x, int16_t *y); +void pgc_ito_raster(pgc_core_t *pgc, int32_t *x, int32_t *y); +void pgc_dto_raster(pgc_core_t *pgc, double *x, double *y); /* Read/write to the PGC's FIFOs */ -int pgc_input_byte(pgc_core_t *pgc, uint8_t *val); -int pgc_output_byte(pgc_core_t *pgc, uint8_t val); -int pgc_output_string(pgc_core_t *pgc, const char *val); -int pgc_error_byte(pgc_core_t *pgc, uint8_t val); -int pgc_error_string(pgc_core_t *pgc, const char *val); +int pgc_input_byte(pgc_core_t *pgc, uint8_t *val); +int pgc_output_byte(pgc_core_t *pgc, uint8_t val); +int pgc_output_string(pgc_core_t *pgc, const char *val); +int pgc_error_byte(pgc_core_t *pgc, uint8_t val); +int pgc_error_string(pgc_core_t *pgc, const char *val); -int pgc_param_byte(pgc_core_t *pgc, uint8_t *val); -int pgc_param_word(pgc_core_t *pgc, int16_t *val); -int pgc_param_coord(pgc_core_t *pgc, int32_t *val); -int pgc_result_byte(pgc_core_t *pgc, uint8_t val); -int pgc_result_word(pgc_core_t *pgc, int16_t val); -int pgc_result_coord(pgc_core_t *pgc, int32_t val); +int pgc_param_byte(pgc_core_t *pgc, uint8_t *val); +int pgc_param_word(pgc_core_t *pgc, int16_t *val); +int pgc_param_coord(pgc_core_t *pgc, int32_t *val); +int pgc_result_byte(pgc_core_t *pgc, uint8_t val); +int pgc_result_word(pgc_core_t *pgc, int16_t val); +int pgc_result_coord(pgc_core_t *pgc, int32_t val); void pgc_sleep(pgc_core_t *pgc); int pgc_error(pgc_core_t *pgc, int err); void pgc_core_init(pgc_core_t *pgc, int maxw, int maxh, int visw, int vish, - int (*inpbyte)(struct pgc_core_t *pgc, uint8_t *result), double native_pixel_clock); + int (*inpbyte)(struct pgc_core_t *pgc, uint8_t *result), double native_pixel_clock); void pgc_speed_changed(void *p); void pgc_close(void *p); @@ -150,20 +145,19 @@ int pgc_parse_coords(pgc_core_t *pgc, pgc_commandlist_t *cl, int p); extern device_t pgc_device; -#define PGC_ERROR_RANGE 0x01 -#define PGC_ERROR_INTEGER 0x02 -#define PGC_ERROR_MEMORY 0x03 +#define PGC_ERROR_RANGE 0x01 +#define PGC_ERROR_INTEGER 0x02 +#define PGC_ERROR_MEMORY 0x03 #define PGC_ERROR_OVERFLOW 0x04 -#define PGC_ERROR_DIGIT 0x05 -#define PGC_ERROR_OPCODE 0x06 -#define PGC_ERROR_RUNNING 0x07 -#define PGC_ERROR_STACK 0x08 -#define PGC_ERROR_TOOLONG 0x09 -#define PGC_ERROR_AREA 0x0A -#define PGC_ERROR_MISSING 0x0B +#define PGC_ERROR_DIGIT 0x05 +#define PGC_ERROR_OPCODE 0x06 +#define PGC_ERROR_RUNNING 0x07 +#define PGC_ERROR_STACK 0x08 +#define PGC_ERROR_TOOLONG 0x09 +#define PGC_ERROR_AREA 0x0A +#define PGC_ERROR_MISSING 0x0B /* #define PGCLOG(x) pclog x */ -#define PGCLOG(x) - +#define PGCLOG(x) #endif /* _VID_PGC_H_ */ diff --git a/includes/private/video/vid_ps1_svga.h b/includes/private/video/vid_ps1_svga.h index 8a9ae8d2..bf5ed112 100644 --- a/includes/private/video/vid_ps1_svga.h +++ b/includes/private/video/vid_ps1_svga.h @@ -2,5 +2,4 @@ #define _VID_PS1_SVGA_H_ extern device_t ps1_m2121_svga_device; - #endif /* _VID_PS1_SVGA_H_ */ diff --git a/includes/private/video/vid_s3.h b/includes/private/video/vid_s3.h index 435e4440..832d685b 100644 --- a/includes/private/video/vid_s3.h +++ b/includes/private/video/vid_s3.h @@ -5,5 +5,4 @@ device_t s3_9fx_device; device_t s3_phoenix_trio32_device; device_t s3_phoenix_trio64_device; - #endif /* _VID_S3_H_ */ diff --git a/includes/private/video/vid_s3_virge.h b/includes/private/video/vid_s3_virge.h index cd0eed22..af3635b8 100644 --- a/includes/private/video/vid_s3_virge.h +++ b/includes/private/video/vid_s3_virge.h @@ -3,5 +3,4 @@ extern device_t s3_virge_device; extern device_t s3_virge_375_device; - #endif /* _VID_S3_VIRGE_H_ */ diff --git a/includes/private/video/vid_sdac_ramdac.h b/includes/private/video/vid_sdac_ramdac.h index 1a374a4a..b01481e1 100644 --- a/includes/private/video/vid_sdac_ramdac.h +++ b/includes/private/video/vid_sdac_ramdac.h @@ -1,7 +1,6 @@ #ifndef _VID_SDAC_RAMDAC_H_ #define _VID_SDAC_RAMDAC_H_ -typedef struct sdac_ramdac_t -{ +typedef struct sdac_ramdac_t { int magic_count; uint8_t command; int windex, rindex; @@ -17,5 +16,4 @@ uint8_t sdac_ramdac_in(uint16_t addr, sdac_ramdac_t *ramdac, svga_t *svga); float sdac_getclock(int clock, void *p); - #endif /* _VID_SDAC_RAMDAC_H_ */ diff --git a/includes/private/video/vid_sigma.h b/includes/private/video/vid_sigma.h index 64c02bb1..5464e1b0 100644 --- a/includes/private/video/vid_sigma.h +++ b/includes/private/video/vid_sigma.h @@ -2,6 +2,4 @@ #define _VID_SIGMA_H_ extern device_t sigma_device; - - #endif /* _VID_SIGMA_H_ */ diff --git a/includes/private/video/vid_stg_ramdac.h b/includes/private/video/vid_stg_ramdac.h index f6e317ac..bd1d2e25 100644 --- a/includes/private/video/vid_stg_ramdac.h +++ b/includes/private/video/vid_stg_ramdac.h @@ -1,7 +1,6 @@ #ifndef _VID_STG_RAMDAC_H_ #define _VID_STG_RAMDAC_H_ -typedef struct stg_ramdac_t -{ +typedef struct stg_ramdac_t { int magic_count; uint8_t command; int index; @@ -11,5 +10,4 @@ typedef struct stg_ramdac_t void stg_ramdac_out(uint16_t addr, uint8_t val, stg_ramdac_t *ramdac, svga_t *svga); uint8_t stg_ramdac_in(uint16_t addr, stg_ramdac_t *ramdac, svga_t *svga); - #endif /* _VID_STG_RAMDAC_H_ */ diff --git a/includes/private/video/vid_svga.h b/includes/private/video/vid_svga.h index db49171e..33be2806 100644 --- a/includes/private/video/vid_svga.h +++ b/includes/private/video/vid_svga.h @@ -1,9 +1,8 @@ #ifndef _VID_SVGA_H_ #define _VID_SVGA_H_ -typedef struct svga_t -{ +typedef struct svga_t { mem_mapping_t mapping; - + uint8_t crtcreg; uint8_t crtc[128]; uint8_t gdcreg[64]; @@ -13,7 +12,7 @@ typedef struct svga_t int attr_palette_enable; uint8_t seqregs[64]; int seqaddr; - + uint8_t miscout; int vidclock; @@ -22,26 +21,26 @@ typedef struct svga_t 1MB-2MB - VRAM mirror 2MB-4MB - open bus 4MB-xMB - mirror of above - + For the example memory map, decode_mask would be 4MB-1 (4MB address space), vram_max would be 2MB (present video memory only responds to first 2MB), vram_mask would be 1MB-1 (video memory wraps at 1MB) */ uint32_t decode_mask; uint32_t vram_max; uint32_t vram_mask; - + uint8_t la, lb, lc, ld; - + uint8_t dac_mask, dac_status; int dac_read, dac_write, dac_pos; int dac_r, dac_g; - + uint8_t cgastat; - + uint8_t plane_mask; - + int fb_only; - + int fast; uint8_t colourcompare, colournocare; int readmode, writemode, readplane; @@ -50,26 +49,26 @@ typedef struct svga_t uint32_t charseta, charsetb; int set_reset_disabled; - + uint8_t egapal[16]; uint32_t pallook[512]; PALETTE vgapal; - + int ramdac_type; int vtotal, dispend, vsyncstart, split, vblankstart; - int hdisp, hdisp_old, htotal, hdisp_time, rowoffset; + int hdisp, hdisp_old, htotal, hdisp_time, rowoffset; int lowres, interlace; int linedbl, rowcount; double clock; uint32_t ma_latch, ca_adj; int bpp; - + uint64_t dispontime, dispofftime; pc_timer_t timer; - + uint8_t scrblank; - + int dispon; int hdisp_on; @@ -80,27 +79,26 @@ typedef struct svga_t int con, cursoron, blink; int scrollcache; int char_width; - + int firstline, lastline; int firstline_draw, lastline_draw; int displine; - + uint8_t *vram; uint8_t *changedvram; uint32_t vram_display_mask; uint32_t banked_mask; uint32_t write_bank, read_bank; - + int fullchange; - + int video_res_x, video_res_y, video_bpp; int video_res_override; /*If clear then SVGA code will set above variables, if set then card code will*/ int frames, fps; - struct - { + struct { int ena; int x, y; int xoff, yoff; @@ -109,33 +107,33 @@ typedef struct svga_t uint32_t pitch; int v_acc, h_acc; } hwcursor, hwcursor_latch, overlay, overlay_latch; - + int hwcursor_on; int overlay_on; - + int hwcursor_oddeven; int overlay_oddeven; - + void (*render)(struct svga_t *svga); void (*recalctimings_ex)(struct svga_t *svga); - void (*video_out)(uint16_t addr, uint8_t val, void *p); - uint8_t (*video_in) (uint16_t addr, void *p); + void (*video_out)(uint16_t addr, uint8_t val, void *p); + uint8_t (*video_in)(uint16_t addr, void *p); void (*hwcursor_draw)(struct svga_t *svga, int displine); void (*overlay_draw)(struct svga_t *svga, int displine); - + void (*vblank_start)(struct svga_t *svga); - + /*Called when VC=R18 and friends. If this returns zero then MA resetting is skipped. Matrox Mystique in Power mode reuses this counter for vertical line interrupt*/ int (*line_compare)(struct svga_t *svga); - + /*Called at the start of vertical sync*/ void (*vsync_callback)(struct svga_t *svga); - + /*If set then another device is driving the monitor output and the SVGA card should not attempt to display anything */ int override; @@ -147,7 +145,7 @@ typedef struct svga_t uint16_t ksc5601_english_font_type; int vertical_linedbl; - + /*Used to implement CRTC[0x17] bit 2 hsync divisor*/ int hsync_divisor; @@ -162,28 +160,25 @@ typedef struct svga_t uint32_t (*remap_func)(struct svga_t *svga, uint32_t in_addr); } svga_t; -extern int svga_init(svga_t *svga, void *p, int memsize, - void (*recalctimings_ex)(struct svga_t *svga), - uint8_t (*video_in) (uint16_t addr, void *p), - void (*video_out)(uint16_t addr, uint8_t val, void *p), - void (*hwcursor_draw)(struct svga_t *svga, int displine), - void (*overlay_draw)(struct svga_t *svga, int displine)); +extern int svga_init(svga_t *svga, void *p, int memsize, void (*recalctimings_ex)(struct svga_t *svga), + uint8_t (*video_in)(uint16_t addr, void *p), void (*video_out)(uint16_t addr, uint8_t val, void *p), + void (*hwcursor_draw)(struct svga_t *svga, int displine), + void (*overlay_draw)(struct svga_t *svga, int displine)); void svga_close(svga_t *svga); extern void svga_recalctimings(svga_t *svga); - -uint8_t svga_read(uint32_t addr, void *p); +uint8_t svga_read(uint32_t addr, void *p); uint16_t svga_readw(uint32_t addr, void *p); uint32_t svga_readl(uint32_t addr, void *p); -void svga_write(uint32_t addr, uint8_t val, void *p); -void svga_writew(uint32_t addr, uint16_t val, void *p); -void svga_writel(uint32_t addr, uint32_t val, void *p); -uint8_t svga_read_linear(uint32_t addr, void *p); +void svga_write(uint32_t addr, uint8_t val, void *p); +void svga_writew(uint32_t addr, uint16_t val, void *p); +void svga_writel(uint32_t addr, uint32_t val, void *p); +uint8_t svga_read_linear(uint32_t addr, void *p); uint16_t svga_readw_linear(uint32_t addr, void *p); uint32_t svga_readl_linear(uint32_t addr, void *p); -void svga_write_linear(uint32_t addr, uint8_t val, void *p); -void svga_writew_linear(uint32_t addr, uint16_t val, void *p); -void svga_writel_linear(uint32_t addr, uint32_t val, void *p); +void svga_write_linear(uint32_t addr, uint8_t val, void *p); +void svga_writew_linear(uint32_t addr, uint16_t val, void *p); +void svga_writel_linear(uint32_t addr, uint32_t val, void *p); void svga_add_status_info(char *s, int max_len, void *p); @@ -201,5 +196,4 @@ void svga_set_ramdac_type(svga_t *svga, int type); void svga_doblit(int y1, int y2, int wx, int wy, svga_t *svga); - #endif /* _VID_SVGA_H_ */ diff --git a/includes/private/video/vid_svga_render.h b/includes/private/video/vid_svga_render.h index 91377aec..eac078be 100644 --- a/includes/private/video/vid_svga_render.h +++ b/includes/private/video/vid_svga_render.h @@ -38,5 +38,4 @@ void svga_render_RGBA8888_highres(svga_t *svga); extern void (*svga_render)(svga_t *svga); - #endif /* _VID_SVGA_RENDER_H_ */ diff --git a/includes/private/video/vid_svga_render_remap.h b/includes/private/video/vid_svga_render_remap.h index d747b228..857d2112 100644 --- a/includes/private/video/vid_svga_render_remap.h +++ b/includes/private/video/vid_svga_render_remap.h @@ -6,61 +6,51 @@ row 1 -> MA14 */ -//S3 - enhanced mode mappings CR31.3 can force doubleword mode -//Cirrus Logic handles SVGA writes seperately -//S3, CL, TGUI blitters need checking +// S3 - enhanced mode mappings CR31.3 can force doubleword mode +// Cirrus Logic handles SVGA writes seperately +// S3, CL, TGUI blitters need checking -//CL, S3, Mach64, ET4000, Banshee, TGUI all okay -//Still to check - ViRGE, HT216 +// CL, S3, Mach64, ET4000, Banshee, TGUI all okay +// Still to check - ViRGE, HT216 #ifndef _VID_SVGA_RENDER_REMAP_H_ #define _VID_SVGA_RENDER_REMAP_H_ -#define VAR_BYTE_MODE (0 << 0) +#define VAR_BYTE_MODE (0 << 0) #define VAR_WORD_MODE_MA13 (1 << 0) #define VAR_WORD_MODE_MA15 (2 << 0) -#define VAR_DWORD_MODE (3 << 0) -#define VAR_MODE_MASK (3 << 0) -#define VAR_ROW0_MA13 (1 << 2) -#define VAR_ROW1_MA14 (1 << 3) +#define VAR_DWORD_MODE (3 << 0) +#define VAR_MODE_MASK (3 << 0) +#define VAR_ROW0_MA13 (1 << 2) +#define VAR_ROW1_MA14 (1 << 3) -#define ADDRESS_REMAP_FUNC(nr) \ - static uint32_t address_remap_func_ ## nr(svga_t *svga, uint32_t in_addr) \ - { \ - uint32_t out_addr; \ - \ - switch (nr & VAR_MODE_MASK) \ - { \ - case VAR_BYTE_MODE: \ - out_addr = in_addr; \ - break; \ - \ - case VAR_WORD_MODE_MA13: \ - out_addr = ((in_addr << 1) & 0x1fff8) | \ - ((in_addr >> 13) & 0x4) | \ - (in_addr & ~0x1ffff); \ - break; \ - \ - case VAR_WORD_MODE_MA15: \ - out_addr = ((in_addr << 1) & 0x1fff8) | \ - ((in_addr >> 15) & 0x4) | \ - (in_addr & ~0x1ffff); \ - break; \ - \ - case VAR_DWORD_MODE: \ - out_addr = ((in_addr << 2) & 0x3fff0) | \ - ((in_addr >> 14) & 0xc) | \ - (in_addr & ~0x3ffff); \ - break; \ - } \ - \ - if (nr & VAR_ROW0_MA13) \ - out_addr = (out_addr & ~(1 << (13+2))) | \ - ((svga->sc & 1) ? (1 << (13+2)) : 0); \ - if (nr & VAR_ROW1_MA14) \ - out_addr = (out_addr & ~(1 << (14+2))) | \ - ((svga->sc & 2) ? (1 << (14+2)) : 0); \ - \ - return out_addr; \ +#define ADDRESS_REMAP_FUNC(nr) \ + static uint32_t address_remap_func_##nr(svga_t *svga, uint32_t in_addr) { \ + uint32_t out_addr; \ + \ + switch (nr & VAR_MODE_MASK) { \ + case VAR_BYTE_MODE: \ + out_addr = in_addr; \ + break; \ + \ + case VAR_WORD_MODE_MA13: \ + out_addr = ((in_addr << 1) & 0x1fff8) | ((in_addr >> 13) & 0x4) | (in_addr & ~0x1ffff); \ + break; \ + \ + case VAR_WORD_MODE_MA15: \ + out_addr = ((in_addr << 1) & 0x1fff8) | ((in_addr >> 15) & 0x4) | (in_addr & ~0x1ffff); \ + break; \ + \ + case VAR_DWORD_MODE: \ + out_addr = ((in_addr << 2) & 0x3fff0) | ((in_addr >> 14) & 0xc) | (in_addr & ~0x3ffff); \ + break; \ + } \ + \ + if (nr & VAR_ROW0_MA13) \ + out_addr = (out_addr & ~(1 << (13 + 2))) | ((svga->sc & 1) ? (1 << (13 + 2)) : 0); \ + if (nr & VAR_ROW1_MA14) \ + out_addr = (out_addr & ~(1 << (14 + 2))) | ((svga->sc & 2) ? (1 << (14 + 2)) : 0); \ + \ + return out_addr; \ } ADDRESS_REMAP_FUNC(0) @@ -80,34 +70,18 @@ ADDRESS_REMAP_FUNC(13) ADDRESS_REMAP_FUNC(14) ADDRESS_REMAP_FUNC(15) -static uint32_t (*address_remap_funcs[16])(svga_t *svga, uint32_t in_addr) = -{ - address_remap_func_0, - address_remap_func_1, - address_remap_func_2, - address_remap_func_3, - address_remap_func_4, - address_remap_func_5, - address_remap_func_6, - address_remap_func_7, - address_remap_func_8, - address_remap_func_9, - address_remap_func_10, - address_remap_func_11, - address_remap_func_12, - address_remap_func_13, - address_remap_func_14, - address_remap_func_15 -}; +static uint32_t (*address_remap_funcs[16])(svga_t *svga, uint32_t in_addr) = { + address_remap_func_0, address_remap_func_1, address_remap_func_2, address_remap_func_3, + address_remap_func_4, address_remap_func_5, address_remap_func_6, address_remap_func_7, + address_remap_func_8, address_remap_func_9, address_remap_func_10, address_remap_func_11, + address_remap_func_12, address_remap_func_13, address_remap_func_14, address_remap_func_15}; -void svga_recalc_remap_func(svga_t *svga) -{ +void svga_recalc_remap_func(svga_t *svga) { int func_nr; - + if (svga->fb_only) func_nr = 0; - else - { + else { if (svga->force_dword_mode) func_nr = VAR_DWORD_MODE; else if (svga->crtc[0x14] & (1 << 6)) @@ -118,18 +92,17 @@ void svga_recalc_remap_func(svga_t *svga) func_nr = VAR_WORD_MODE_MA15; else func_nr = VAR_WORD_MODE_MA13; - + if (!(svga->crtc[0x17] & (1 << 0))) func_nr |= VAR_ROW0_MA13; if (!(svga->crtc[0x17] & (1 << 1))) func_nr |= VAR_ROW1_MA14; } -// pclog("svga_recalc_remap_func: fb_only=%i chain4=%i packed_chain4=%i crtc[14]=%02x crtc[17]=%02x func_nr=%i\n", -// svga->fb_only, svga->chain4, svga->packed_chain4, svga->crtc[0x14], svga->crtc[0x17], func_nr); + // pclog("svga_recalc_remap_func: fb_only=%i chain4=%i packed_chain4=%i crtc[14]=%02x crtc[17]=%02x func_nr=%i\n", + // svga->fb_only, svga->chain4, svga->packed_chain4, svga->crtc[0x14], svga->crtc[0x17], func_nr); svga->remap_required = (func_nr != 0); svga->remap_func = address_remap_funcs[func_nr]; } - #endif /* _VID_SVGA_RENDER_REMAP_H_ */ diff --git a/includes/private/video/vid_t1000.h b/includes/private/video/vid_t1000.h index 7c7c9467..5082149c 100644 --- a/includes/private/video/vid_t1000.h +++ b/includes/private/video/vid_t1000.h @@ -6,5 +6,4 @@ void t1000_video_options_set(uint8_t options); void t1000_display_set(uint8_t internal); void t1000_video_enable(uint8_t enabled); - #endif /* _VID_T1000_H_ */ diff --git a/includes/private/video/vid_t3100e.h b/includes/private/video/vid_t3100e.h index 713af229..635d81cf 100644 --- a/includes/private/video/vid_t3100e.h +++ b/includes/private/video/vid_t3100e.h @@ -5,5 +5,4 @@ extern device_t t3100e_device; void t3100e_video_options_set(uint8_t options); void t3100e_display_set(uint8_t internal); - #endif /* _VID_T3100E_H_ */ diff --git a/includes/private/video/vid_tandy.h b/includes/private/video/vid_tandy.h index c5df0a0a..e8935cb1 100644 --- a/includes/private/video/vid_tandy.h +++ b/includes/private/video/vid_tandy.h @@ -5,5 +5,4 @@ extern device_t tandy_device; extern device_t tandy1000_device; extern device_t tandy1000hx_device; - #endif /* _VID_TANDY_H_ */ diff --git a/includes/private/video/vid_tandysl.h b/includes/private/video/vid_tandysl.h index 99d9722f..e928c58f 100644 --- a/includes/private/video/vid_tandysl.h +++ b/includes/private/video/vid_tandysl.h @@ -2,5 +2,4 @@ #define _VID_TANDYSL_H_ extern device_t tandysl_device; - #endif /* _VID_TANDYSL_H_ */ diff --git a/includes/private/video/vid_tgui9440.h b/includes/private/video/vid_tgui9440.h index cd137628..bda471de 100644 --- a/includes/private/video/vid_tgui9440.h +++ b/includes/private/video/vid_tgui9440.h @@ -4,5 +4,4 @@ extern device_t tgui9400cxi_device; extern device_t tgui9400cxi_elx_device; extern device_t tgui9440_device; - #endif /* _VID_TGUI9440_H_ */ diff --git a/includes/private/video/vid_tkd8001_ramdac.h b/includes/private/video/vid_tkd8001_ramdac.h index 489617e4..0a32b1f0 100644 --- a/includes/private/video/vid_tkd8001_ramdac.h +++ b/includes/private/video/vid_tkd8001_ramdac.h @@ -1,7 +1,6 @@ #ifndef _VID_TKD8001_RAMDAC_H_ #define _VID_TKD8001_RAMDAC_H_ -typedef struct tkd8001_ramdac_t -{ +typedef struct tkd8001_ramdac_t { int state; uint8_t ctrl; } tkd8001_ramdac_t; @@ -9,5 +8,4 @@ typedef struct tkd8001_ramdac_t void tkd8001_ramdac_out(uint16_t addr, uint8_t val, tkd8001_ramdac_t *ramdac, svga_t *svga); uint8_t tkd8001_ramdac_in(uint16_t addr, tkd8001_ramdac_t *ramdac, svga_t *svga); - #endif /* _VID_TKD8001_RAMDAC_H_ */ diff --git a/includes/private/video/vid_tvga.h b/includes/private/video/vid_tvga.h index 42c57e3f..58ad1f32 100644 --- a/includes/private/video/vid_tvga.h +++ b/includes/private/video/vid_tvga.h @@ -3,5 +3,4 @@ extern device_t tvga8900d_device; extern device_t tvga9000b_device; - #endif /* _VID_TVGA_H_ */ diff --git a/includes/private/video/vid_tvp3026_ramdac.h b/includes/private/video/vid_tvp3026_ramdac.h index 1ae0d667..cd15bdae 100644 --- a/includes/private/video/vid_tvp3026_ramdac.h +++ b/includes/private/video/vid_tvp3026_ramdac.h @@ -1,19 +1,17 @@ #ifndef _VID_TVP3026_RAMDAC_H_ #define _VID_TVP3026_RAMDAC_H_ -typedef struct tvp3026_ramdac_t -{ +typedef struct tvp3026_ramdac_t { int reg_idx; uint16_t regs[256]; int cursor_ena, cursor_mode; uint8_t cursor_control; int cursor_x, cursor_y; uint8_t cursor_data[1024]; - struct - { + struct { uint8_t m, n, p; } pix, mem, loop; - + int cursor_pal_read, cursor_pal_write, cursor_pal_pos; int cursor_pal_r, cursor_pal_g; RGB cursor_pal[4]; diff --git a/includes/private/video/vid_unk_ramdac.h b/includes/private/video/vid_unk_ramdac.h index 77528070..90b796e6 100644 --- a/includes/private/video/vid_unk_ramdac.h +++ b/includes/private/video/vid_unk_ramdac.h @@ -1,7 +1,6 @@ #ifndef _VID_UNK_RAMDAC_H_ #define _VID_UNK_RAMDAC_H_ -typedef struct unk_ramdac_t -{ +typedef struct unk_ramdac_t { int state; uint8_t ctrl; } unk_ramdac_t; @@ -9,5 +8,4 @@ typedef struct unk_ramdac_t void unk_ramdac_out(uint16_t addr, uint8_t val, unk_ramdac_t *ramdac, svga_t *svga); uint8_t unk_ramdac_in(uint16_t addr, unk_ramdac_t *ramdac, svga_t *svga); - #endif /* _VID_UNK_RAMDAC_H_ */ diff --git a/includes/private/video/vid_vga.h b/includes/private/video/vid_vga.h index 7864f765..a7ac5645 100644 --- a/includes/private/video/vid_vga.h +++ b/includes/private/video/vid_vga.h @@ -9,5 +9,4 @@ void vga_enable(void *p); struct svga_t; extern struct svga_t *mb_vga; - #endif /* _VID_VGA_H_ */ diff --git a/includes/private/video/vid_voodoo.h b/includes/private/video/vid_voodoo.h index b8485fac..121458d7 100644 --- a/includes/private/video/vid_voodoo.h +++ b/includes/private/video/vid_voodoo.h @@ -2,5 +2,4 @@ #define _VID_VOODOO_H_ extern device_t voodoo_device; - #endif /* _VID_VOODOO_H_ */ diff --git a/includes/private/video/vid_voodoo_banshee.h b/includes/private/video/vid_voodoo_banshee.h index 1777f2bf..8e6d0da5 100644 --- a/includes/private/video/vid_voodoo_banshee.h +++ b/includes/private/video/vid_voodoo_banshee.h @@ -7,5 +7,4 @@ extern device_t voodoo_3_3000_device; void banshee_set_overlay_addr(void *p, uint32_t addr); - #endif /* _VID_VOODOO_BANSHEE_H_ */ diff --git a/includes/private/video/vid_voodoo_banshee_blitter.h b/includes/private/video/vid_voodoo_banshee_blitter.h index b0155838..3fe1fe4e 100644 --- a/includes/private/video/vid_voodoo_banshee_blitter.h +++ b/includes/private/video/vid_voodoo_banshee_blitter.h @@ -2,5 +2,4 @@ #define _VID_VOODOO_BANSHEE_BLITTER_H_ void voodoo_2d_reg_writel(voodoo_t *voodoo, uint32_t addr, uint32_t val); - #endif /* _VID_VOODOO_BANSHEE_BLITTER_H_ */ diff --git a/includes/private/video/vid_voodoo_blitter.h b/includes/private/video/vid_voodoo_blitter.h index 4aa8e7a2..cdede834 100644 --- a/includes/private/video/vid_voodoo_blitter.h +++ b/includes/private/video/vid_voodoo_blitter.h @@ -4,5 +4,4 @@ void voodoo_v2_blit_start(voodoo_t *voodoo); void voodoo_v2_blit_data(voodoo_t *voodoo, uint32_t data); void voodoo_fastfill(voodoo_t *voodoo, voodoo_params_t *params); - #endif /* _VID_VOODOO_BLITTER_H_ */ diff --git a/includes/private/video/vid_voodoo_codegen_x86-64.h b/includes/private/video/vid_voodoo_codegen_x86-64.h index f2bbecf2..100e4f8e 100644 --- a/includes/private/video/vid_voodoo_codegen_x86-64.h +++ b/includes/private/video/vid_voodoo_codegen_x86-64.h @@ -1,5 +1,5 @@ /*Registers : - + alphaMode fbzMode & 0x1f3fff fbzColorPath @@ -21,13 +21,12 @@ #include #define BLOCK_NUM 8 -#define BLOCK_MASK (BLOCK_NUM-1) +#define BLOCK_MASK (BLOCK_NUM - 1) #define BLOCK_SIZE 8192 #define LOD_MASK (LOD_TMIRROR_S | LOD_TMIRROR_T) -typedef struct voodoo_x86_data_t -{ +typedef struct voodoo_x86_data_t { uint8_t code_block[BLOCK_SIZE]; int xdir; uint32_t alphaMode; @@ -36,61 +35,59 @@ typedef struct voodoo_x86_data_t uint32_t fbzColorPath; uint32_t textureMode[2]; uint32_t tLOD[2]; - uint32_t trexInit1; + uint32_t trexInit1; int is_tiled; } voodoo_x86_data_t; -//static voodoo_x86_data_t voodoo_x86_data[2][BLOCK_NUM]; +// static voodoo_x86_data_t voodoo_x86_data[2][BLOCK_NUM]; static int last_block[4] = {0, 0}; static int next_block_to_write[4] = {0, 0}; -#define addbyte(val) \ - do { \ - code_block[block_pos++] = val; \ - if (block_pos >= BLOCK_SIZE) \ - fatal("Over!\n"); \ +#define addbyte(val) \ + do { \ + code_block[block_pos++] = val; \ + if (block_pos >= BLOCK_SIZE) \ + fatal("Over!\n"); \ } while (0) -#define addword(val) \ - do { \ - *(uint16_t *)&code_block[block_pos] = val; \ - block_pos += 2; \ - if (block_pos >= BLOCK_SIZE) \ - fatal("Over!\n"); \ +#define addword(val) \ + do { \ + *(uint16_t *)&code_block[block_pos] = val; \ + block_pos += 2; \ + if (block_pos >= BLOCK_SIZE) \ + fatal("Over!\n"); \ } while (0) -#define addlong(val) \ - do { \ - *(uint32_t *)&code_block[block_pos] = val; \ - block_pos += 4; \ - if (block_pos >= BLOCK_SIZE) \ - fatal("Over!\n"); \ +#define addlong(val) \ + do { \ + *(uint32_t *)&code_block[block_pos] = val; \ + block_pos += 4; \ + if (block_pos >= BLOCK_SIZE) \ + fatal("Over!\n"); \ } while (0) -#define addquad(val) \ - do { \ - *(uint64_t *)&code_block[block_pos] = val; \ - block_pos += 8; \ - if (block_pos >= BLOCK_SIZE) \ - fatal("Over!\n"); \ +#define addquad(val) \ + do { \ + *(uint64_t *)&code_block[block_pos] = val; \ + block_pos += 8; \ + if (block_pos >= BLOCK_SIZE) \ + fatal("Over!\n"); \ } while (0) - -static __m128i xmm_01_w;// = 0x0001000100010001ull; -static __m128i xmm_ff_w;// = 0x00ff00ff00ff00ffull; -static __m128i xmm_ff_b;// = 0x00000000ffffffffull; +static __m128i xmm_01_w; // = 0x0001000100010001ull; +static __m128i xmm_ff_w; // = 0x00ff00ff00ff00ffull; +static __m128i xmm_ff_b; // = 0x00000000ffffffffull; static __m128i alookup[257], aminuslookup[256]; -static __m128i minus_254;// = 0xff02ff02ff02ff02ull; -static __m128i bilinear_lookup[256*2]; +static __m128i minus_254; // = 0xff02ff02ff02ff02ull; +static __m128i bilinear_lookup[256 * 2]; static __m128i xmm_00_ff_w[2]; static uint32_t i_00_ff_w[2] = {0, 0xff}; -static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int block_pos, int tmu) -{ - if (params->textureMode[tmu] & 1) - { +static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, + int block_pos, int tmu) { + if (params->textureMode[tmu] & 1) { addbyte(0x48); /*MOV RBX, state->tmu0_s*/ addbyte(0x8b); addbyte(0x9f); @@ -193,13 +190,11 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addlong(offsetof(voodoo_state_t, lod_max[tmu])); addbyte(0xc1); /*SHR EAX, 8*/ addbyte(0xe8); - addbyte(8); + addbyte(8); addbyte(0x89); /*MOV state->lod, EAX*/ addbyte(0x87); addlong(offsetof(voodoo_state_t, lod)); - } - else - { + } else { addbyte(0x48); /*MOV RAX, state->tmu0_s*/ addbyte(0x8b); addbyte(0x87); @@ -225,7 +220,7 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addlong(offsetof(voodoo_state_t, tex_s)); addbyte(0xc1); /*SHR EBX, 8*/ addbyte(0xeb); - addbyte(8); + addbyte(8); addbyte(0x48); /*MOV state->tex_t, RCX*/ addbyte(0x89); addbyte(0x8f); @@ -235,10 +230,8 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addlong(offsetof(voodoo_state_t, lod)); } - if (params->fbzColorPath & FBZCP_TEXTURE_ENABLED) - { - if (voodoo->bilinear_enabled && (params->textureMode[tmu] & 6)) - { + if (params->fbzColorPath & FBZCP_TEXTURE_ENABLED) { + if (voodoo->bilinear_enabled && (params->textureMode[tmu] & 6)) { addbyte(0xb2); /*MOV DL, 8*/ addbyte(8); addbyte(0x8b); /*MOV ECX, state->lod[RDI]*/ @@ -248,10 +241,10 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addlong(1); addbyte(0x28); /*SUB DL, CL*/ addbyte(0xca); -// addbyte(0x8a); /*MOV DL, params->tex_shift[RSI+ECX*4]*/ -// addbyte(0x94); -// addbyte(0x8e); -// addlong(offsetof(voodoo_params_t, tex_shift)); + // addbyte(0x8a); /*MOV DL, params->tex_shift[RSI+ECX*4]*/ + // addbyte(0x94); + // addbyte(0x8e); + // addlong(offsetof(voodoo_params_t, tex_shift)); addbyte(0xd3); /*SHL EBP, CL*/ addbyte(0xe5); addbyte(0x8b); /*MOV EAX, state->tex_s[RDI]*/ @@ -263,8 +256,7 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0x8b); /*MOV EBX, state->tex_t[RDI]*/ addbyte(0x9f); addlong(offsetof(voodoo_state_t, tex_t)); - if (params->tLOD[tmu] & LOD_TMIRROR_S) - { + if (params->tLOD[tmu] & LOD_TMIRROR_S) { addbyte(0xa9); /*TEST EAX, 0x1000*/ addlong(0x1000); addbyte(0x74); /*JZ +*/ @@ -272,8 +264,7 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0xf7); /*NOT EAX*/ addbyte(0xd0); } - if (params->tLOD[tmu] & LOD_TMIRROR_T) - { + if (params->tLOD[tmu] & LOD_TMIRROR_T) { addbyte(0xf7); /*TEST EBX, 0x1000*/ addbyte(0xc3); addlong(0x1000); @@ -334,8 +325,7 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0xd1); addbyte(0x89); /*MOV EDX, EBX*/ addbyte(0xda); - if (!state->clamp_s[tmu]) - { + if (!state->clamp_s[tmu]) { addbyte(0x23); /*AND EAX, params->tex_w_mask[ESI]*/ addbyte(0x86); addlong(offsetof(voodoo_params_t, tex_w_mask[tmu])); @@ -343,8 +333,7 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0x83); /*ADD EDX, 1*/ addbyte(0xc2); addbyte(1); - if (state->clamp_t[tmu]) - { + if (state->clamp_t[tmu]) { addbyte(0x41); /*CMOVS EDX, R10(alookup[0](zero))*/ addbyte(0x0f); addbyte(0x48); @@ -369,9 +358,7 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0x47); addbyte(0x9e); addlong(offsetof(voodoo_params_t, tex_h_mask[tmu])); - } - else - { + } else { addbyte(0x23); /*AND EDX, params->tex_h_mask[ESI]*/ addbyte(0x96); addlong(offsetof(voodoo_params_t, tex_h_mask[tmu])); @@ -394,8 +381,7 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0x54); addbyte(0x95); addbyte(0); - if (state->clamp_s[tmu]) - { + if (state->clamp_s[tmu]) { addbyte(0x8b); /*MOV EBP, params->tex_w_mask[ESI]*/ addbyte(0xae); addlong(offsetof(voodoo_params_t, tex_w_mask[tmu])); @@ -409,17 +395,15 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0x48); addbyte(0x02); addbyte(0x78); /*JS + - clamp on 0*/ - addbyte(2+3+2+ 5+5+2); + addbyte(2 + 3 + 2 + 5 + 5 + 2); addbyte(0x3b); /*CMP EAX, EBP*/ addbyte(0xc5); addbyte(0x0f); /*CMOVAE EAX, EBP*/ addbyte(0x43); addbyte(0xc5); addbyte(0x73); /*JAE + - clamp on +*/ - addbyte(5+5+2); - } - else - { + addbyte(5 + 5 + 2); + } else { addbyte(0x3b); /*CMP EAX, params->tex_w_mask[ESI] - is S at texture edge (ie will wrap/clamp)?*/ addbyte(0x86); addlong(offsetof(voodoo_params_t, tex_w_mask[tmu])); @@ -427,7 +411,7 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0xb7); addlong(offsetof(voodoo_state_t, ebp_store)); addbyte(0x74); /*JE +*/ - addbyte(5+5+2); + addbyte(5 + 5 + 2); } addbyte(0xf3); /*MOVQ XMM0, [RBX+RAX*4]*/ @@ -441,10 +425,9 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0x0c); addbyte(0x82); - if (state->clamp_s[tmu]) - { + if (state->clamp_s[tmu]) { addbyte(0xeb); /*JMP +*/ - addbyte(5+5+4+4); + addbyte(5 + 5 + 4 + 4); /*S clamped - the two S coordinates are the same*/ addbyte(0x66); /*MOVD XMM0, [RBX+RAX*4]*/ @@ -465,11 +448,9 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0x0f); addbyte(0x62); addbyte(0xc9); - } - else - { + } else { addbyte(0xeb); /*JMP +*/ - addbyte(5+5+5+5+6+6); + addbyte(5 + 5 + 5 + 5 + 6 + 6); /*S wrapped - the two S coordinates are not contiguous*/ addbyte(0x66); /*MOVD XMM0, [RBX+EAX*4]*/ @@ -558,7 +539,7 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0x0f); addbyte(0x67); addbyte(0xc0); - + addbyte(0x4c); /*MOV RSI, R15*/ addbyte(0x89); addbyte(0xfe); @@ -566,10 +547,8 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0x66); /*MOV EAX, XMM0*/ addbyte(0x0f); addbyte(0x7e); - addbyte(0xc0); - } - else - { + addbyte(0xc0); + } else { addbyte(0xb2); /*MOV DL, 8*/ addbyte(8); addbyte(0x8b); /*MOV ECX, state->lod[RDI]*/ @@ -591,8 +570,7 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0x8b); /*MOV EBX, state->tex_t[EDI]*/ addbyte(0x9f); addlong(offsetof(voodoo_state_t, tex_t)); - if (params->tLOD[tmu] & LOD_TMIRROR_S) - { + if (params->tLOD[tmu] & LOD_TMIRROR_S) { addbyte(0xa9); /*TEST EAX, 0x1000*/ addlong(0x1000); addbyte(0x74); /*JZ +*/ @@ -600,8 +578,7 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0xf7); /*NOT EAX*/ addbyte(0xd0); } - if (params->tLOD[tmu] & LOD_TMIRROR_T) - { + if (params->tLOD[tmu] & LOD_TMIRROR_T) { addbyte(0xf7); /*TEST EBX, 0x1000*/ addbyte(0xc3); addlong(0x1000); @@ -614,8 +591,7 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0xe8); addbyte(0xd3); /*SHR EBX, CL*/ addbyte(0xeb); - if (state->clamp_s[tmu]) - { + if (state->clamp_s[tmu]) { addbyte(0x85); /*TEST EAX, EAX*/ addbyte(0xc0); addbyte(0x41); /*CMOVS EAX, R10(alookup[0](zero))*/ @@ -632,16 +608,13 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0x8e); addlong(offsetof(voodoo_params_t, tex_w_mask[tmu]) - 0x10); - } - else - { + } else { addbyte(0x23); /*AND EAX, params->tex_w_mask-0x10[ESI+ECX*4]*/ addbyte(0x84); addbyte(0x8e); addlong(offsetof(voodoo_params_t, tex_w_mask[tmu]) - 0x10); } - if (state->clamp_t[tmu]) - { + if (state->clamp_t[tmu]) { addbyte(0x85); /*TEST EBX, EBX*/ addbyte(0xdb); addbyte(0x41); /*CMOVS EBX, R10(alookup[0](zero))*/ @@ -657,9 +630,7 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0x9c); addbyte(0x8e); addlong(offsetof(voodoo_params_t, tex_h_mask[tmu]) - 0x10); - } - else - { + } else { addbyte(0x23); /*AND EBX, params->tex_h_mask-0x10[ESI+ECX*4]*/ addbyte(0x9c); addbyte(0x8e); @@ -682,8 +653,8 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v return block_pos; } -static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int depthop) -{ +static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, + int depthop) { int block_pos = 0; int z_skip_pos = 0; int a_skip_pos = 0; @@ -691,24 +662,24 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo int depth_jump_pos = 0; int depth_jump_pos2 = 0; int loop_jump_pos = 0; -// xmm_01_w = (__m128i)0x0001000100010001ull; -// xmm_ff_w = (__m128i)0x00ff00ff00ff00ffull; -// xmm_ff_b = (__m128i)0x00000000ffffffffull; + // xmm_01_w = (__m128i)0x0001000100010001ull; + // xmm_ff_w = (__m128i)0x00ff00ff00ff00ffull; + // xmm_ff_b = (__m128i)0x00000000ffffffffull; xmm_01_w = _mm_set_epi32(0, 0, 0x00010001, 0x00010001); xmm_ff_w = _mm_set_epi32(0, 0, 0x00ff00ff, 0x00ff00ff); xmm_ff_b = _mm_set_epi32(0, 0, 0, 0x00ffffff); minus_254 = _mm_set_epi32(0, 0, 0xff02ff02, 0xff02ff02); -// *(uint64_t *)&const_1_48 = 0x45b0000000000000ull; -// block_pos = 0; -// voodoo_get_depth = &code_block[block_pos]; + // *(uint64_t *)&const_1_48 = 0x45b0000000000000ull; + // block_pos = 0; + // voodoo_get_depth = &code_block[block_pos]; /*W at (%esp+4) Z at (%esp+12) new_depth at (%esp+16)*/ -// if ((params->fbzMode & FBZ_DEPTH_ENABLE) && (depth_op == DEPTHOP_NEVER)) -// { -// addbyte(0xC3); /*RET*/ -// return; -// } + // if ((params->fbzMode & FBZ_DEPTH_ENABLE) && (depth_op == DEPTHOP_NEVER)) + // { + // addbyte(0xC3); /*RET*/ + // return; + // } addbyte(0x55); /*PUSH RBP*/ addbyte(0x57); /*PUSH RDI*/ addbyte(0x56); /*PUSH RSI*/ @@ -721,7 +692,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x56); addbyte(0x41); /*PUSH R15*/ addbyte(0x57); - + addbyte(0x49); /*MOV R15, xmm_01_w*/ addbyte(0xbf); addquad((uint64_t)(uintptr_t)&xmm_01_w); @@ -769,9 +740,9 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x49); /*MOV R14, RCX (real_y)*/ addbyte(0x89); addbyte(0xce); - addbyte(0x49); /*MOV R15, RSI (voodoo_state)*/ - addbyte(0x89); - addbyte(0xf7); + addbyte(0x49); /*MOV R15, RSI (voodoo_state)*/ + addbyte(0x89); + addbyte(0xf7); #endif addbyte(0x49); /*MOV R9, logtable*/ @@ -794,8 +765,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x4c); /*MOV RSI, R15*/ addbyte(0x89); addbyte(0xfe); - if (params->col_tiled || params->aux_tiled) - { + if (params->col_tiled || params->aux_tiled) { addbyte(0x8b); /*MOV EAX, state->x[EDI]*/ addbyte(0x87); addlong(offsetof(voodoo_state_t, x)); @@ -821,19 +791,19 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xef); addbyte(0xd2); - if ((params->fbzMode & FBZ_W_BUFFER) || (params->fogMode & (FOG_ENABLE|FOG_CONSTANT|FOG_Z|FOG_ALPHA)) == FOG_ENABLE) - { + if ((params->fbzMode & FBZ_W_BUFFER) || + (params->fogMode & (FOG_ENABLE | FOG_CONSTANT | FOG_Z | FOG_ALPHA)) == FOG_ENABLE) { addbyte(0xb8); /*MOV new_depth, 0*/ addlong(0); addbyte(0x66); /*TEST w+4, 0xffff*/ addbyte(0xf7); addbyte(0x87); - addlong(offsetof(voodoo_state_t, w)+4); + addlong(offsetof(voodoo_state_t, w) + 4); addword(0xffff); addbyte(0x75); /*JNZ got_depth*/ depth_jump_pos = block_pos; addbyte(0); -// addbyte(4+5+2+3+2+5+5+3+2+2+2+/*3+*/3+2+6+4+5+2+3); + // addbyte(4+5+2+3+2+5+5+3+2+2+2+/*3+*/3+2+6+4+5+2+3); addbyte(0x8b); /*MOV EDX, w*/ addbyte(0x97); addlong(offsetof(voodoo_state_t, w)); @@ -847,7 +817,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x74); /*JZ got_depth*/ depth_jump_pos2 = block_pos; addbyte(0); -// addbyte(5+5+3+2+2+2+/*3+*/3+2+6+4+5+2+3); + // addbyte(5+5+3+2+2+2+/*3+*/3+2+6+4+5+2+3); addbyte(0xb9); /*MOV ECX, 19*/ addlong(19); addbyte(0x0f); /*BSR EAX, EDX*/ @@ -886,16 +856,14 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo *(uint8_t *)&code_block[depth_jump_pos] = (block_pos - depth_jump_pos) - 1; if (depth_jump_pos) *(uint8_t *)&code_block[depth_jump_pos2] = (block_pos - depth_jump_pos2) - 1; - - if ((params->fogMode & (FOG_ENABLE|FOG_CONSTANT|FOG_Z|FOG_ALPHA)) == FOG_ENABLE) - { + + if ((params->fogMode & (FOG_ENABLE | FOG_CONSTANT | FOG_Z | FOG_ALPHA)) == FOG_ENABLE) { addbyte(0x89); /*MOV state->w_depth[EDI], EAX*/ addbyte(0x87); addlong(offsetof(voodoo_state_t, w_depth)); } } - if (!(params->fbzMode & FBZ_W_BUFFER)) - { + if (!(params->fbzMode & FBZ_W_BUFFER)) { addbyte(0x8b); /*MOV EAX, z*/ addbyte(0x87); addlong(offsetof(voodoo_state_t, z)); @@ -916,11 +884,10 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xc3); } - if (params->fbzMode & FBZ_DEPTH_BIAS) - { + if (params->fbzMode & FBZ_DEPTH_BIAS) { addbyte(0x03); /*ADD EAX, params->zaColor[ESI]*/ addbyte(0x86); - addlong(offsetof(voodoo_params_t, zaColor)); + addlong(offsetof(voodoo_params_t, zaColor)); addbyte(0x25); /*AND EAX, 0xffff*/ addlong(0xffff); } @@ -929,8 +896,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x87); addlong(offsetof(voodoo_state_t, new_depth)); - if ((params->fbzMode & FBZ_DEPTH_ENABLE) && (depthop != DEPTHOP_ALWAYS) && (depthop != DEPTHOP_NEVER)) - { + if ((params->fbzMode & FBZ_DEPTH_ENABLE) && (depthop != DEPTHOP_ALWAYS) && (depthop != DEPTHOP_NEVER)) { addbyte(0x8b); /*MOV EBX, state->x[EDI]*/ addbyte(0x9f); if (params->aux_tiled) @@ -945,8 +911,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xb7); addbyte(0x1c); addbyte(0x59); - if (params->fbzMode & FBZ_DEPTH_SOURCE) - { + if (params->fbzMode & FBZ_DEPTH_SOURCE) { addbyte(0x0f); /*MOVZX EAX, zaColor[RSI]*/ addbyte(0xb7); addbyte(0x86); @@ -954,66 +919,51 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo } addbyte(0x39); /*CMP EAX, EBX*/ addbyte(0xd8); - if (depthop == DEPTHOP_LESSTHAN) - { + if (depthop == DEPTHOP_LESSTHAN) { addbyte(0x0f); /*JAE skip*/ addbyte(0x83); z_skip_pos = block_pos; addlong(0); - } - else if (depthop == DEPTHOP_EQUAL) - { + } else if (depthop == DEPTHOP_EQUAL) { addbyte(0x0f); /*JNE skip*/ addbyte(0x85); z_skip_pos = block_pos; addlong(0); - } - else if (depthop == DEPTHOP_LESSTHANEQUAL) - { + } else if (depthop == DEPTHOP_LESSTHANEQUAL) { addbyte(0x0f); /*JA skip*/ addbyte(0x87); z_skip_pos = block_pos; addlong(0); - } - else if (depthop == DEPTHOP_GREATERTHAN) - { + } else if (depthop == DEPTHOP_GREATERTHAN) { addbyte(0x0f); /*JBE skip*/ addbyte(0x86); z_skip_pos = block_pos; addlong(0); - } - else if (depthop == DEPTHOP_NOTEQUAL) - { + } else if (depthop == DEPTHOP_NOTEQUAL) { addbyte(0x0f); /*JE skip*/ addbyte(0x84); z_skip_pos = block_pos; addlong(0); - } - else if (depthop == DEPTHOP_GREATERTHANEQUAL) - { + } else if (depthop == DEPTHOP_GREATERTHANEQUAL) { addbyte(0x0f); /*JB skip*/ addbyte(0x82); z_skip_pos = block_pos; addlong(0); - } - else + } else fatal("Bad depth_op\n"); - } - else if ((params->fbzMode & FBZ_DEPTH_ENABLE) && (depthop == DEPTHOP_NEVER)) - { + } else if ((params->fbzMode & FBZ_DEPTH_ENABLE) && (depthop == DEPTHOP_NEVER)) { addbyte(0xC3); /*RET*/ } /*XMM0 = colour*/ /*XMM2 = 0 (for unpacking*/ - + /*EDI = state, ESI = params*/ - if ((params->textureMode[0] & TEXTUREMODE_LOCAL_MASK) == TEXTUREMODE_LOCAL || !voodoo->dual_tmus) - { + if ((params->textureMode[0] & TEXTUREMODE_LOCAL_MASK) == TEXTUREMODE_LOCAL || !voodoo->dual_tmus) { /*TMU0 only sampling local colour or only one TMU, only sample TMU0*/ block_pos = codegen_texture_fetch(code_block, voodoo, params, state, block_pos, 0); - + addbyte(0x66); /*MOVD XMM0, EAX*/ addbyte(0x0f); addbyte(0x6e); @@ -1024,12 +974,10 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x89); /*MOV state->tex_a[RDI], EAX*/ addbyte(0x87); addlong(offsetof(voodoo_state_t, tex_a)); - } - else if ((params->textureMode[0] & TEXTUREMODE_MASK) == TEXTUREMODE_PASSTHROUGH) - { + } else if ((params->textureMode[0] & TEXTUREMODE_MASK) == TEXTUREMODE_PASSTHROUGH) { /*TMU0 in pass-through mode, only sample TMU1*/ block_pos = codegen_texture_fetch(code_block, voodoo, params, state, block_pos, 1); - + addbyte(0x66); /*MOVD XMM0, EAX*/ addbyte(0x0f); addbyte(0x6e); @@ -1040,40 +988,31 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x89); /*MOV state->tex_a[RDI], EAX*/ addbyte(0x87); addlong(offsetof(voodoo_state_t, tex_a)); - } - else - { + } else { block_pos = codegen_texture_fetch(code_block, voodoo, params, state, block_pos, 1); addbyte(0x66); /*MOVD XMM3, EAX*/ addbyte(0x0f); addbyte(0x6e); addbyte(0xd8); - if ((params->textureMode[1] & TEXTUREMODE_TRILINEAR) && tc_sub_clocal_1) - { + if ((params->textureMode[1] & TEXTUREMODE_TRILINEAR) && tc_sub_clocal_1) { addbyte(0x8b); /*MOV EAX, state->lod*/ addbyte(0x87); addlong(offsetof(voodoo_state_t, lod)); - if (!tc_reverse_blend_1) - { + if (!tc_reverse_blend_1) { addbyte(0xbb); /*MOV EBX, 1*/ addlong(1); - } - else - { + } else { addbyte(0x31); /*XOR EBX, EBX*/ addbyte(0xdb); } addbyte(0x83); /*AND EAX, 1*/ addbyte(0xe0); addbyte(1); - if (!tca_reverse_blend_1) - { + if (!tca_reverse_blend_1) { addbyte(0xb9); /*MOV ECX, 1*/ addlong(1); - } - else - { + } else { addbyte(0x31); /*XOR ECX, ECX*/ addbyte(0xc9); } @@ -1090,36 +1029,34 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x0f); addbyte(0x60); addbyte(0xda); - if (tc_sub_clocal_1) - { - switch (tc_mselect_1) - { - case TC_MSELECT_ZERO: + if (tc_sub_clocal_1) { + switch (tc_mselect_1) { + case TC_MSELECT_ZERO: addbyte(0x66); /*PXOR XMM0, XMM0*/ addbyte(0x0f); addbyte(0xef); addbyte(0xc0); break; - case TC_MSELECT_CLOCAL: + case TC_MSELECT_CLOCAL: addbyte(0xf3); /*MOVQ XMM0, XMM3*/ addbyte(0x0f); addbyte(0x7e); addbyte(0xc3); break; - case TC_MSELECT_AOTHER: + case TC_MSELECT_AOTHER: addbyte(0x66); /*PXOR XMM0, XMM0*/ addbyte(0x0f); addbyte(0xef); addbyte(0xc0); break; - case TC_MSELECT_ALOCAL: + case TC_MSELECT_ALOCAL: addbyte(0xf2); /*PSHUFLW XMM0, XMM3, 0xff*/ addbyte(0x0f); addbyte(0x70); addbyte(0xc3); addbyte(0xff); break; - case TC_MSELECT_DETAIL: + case TC_MSELECT_DETAIL: addbyte(0xb8); /*MOV EAX, params->detail_bias[1]*/ addlong(params->detail_bias[1]); addbyte(0x2b); /*SUB EAX, state->lod*/ @@ -1145,7 +1082,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xc0); addbyte(0); break; - case TC_MSELECT_LOD_FRAC: + case TC_MSELECT_LOD_FRAC: addbyte(0x66); /*MOVD XMM0, state->lod_frac[1]*/ addbyte(0x0f); addbyte(0x6e); @@ -1158,17 +1095,14 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0); break; } - if (params->textureMode[1] & TEXTUREMODE_TRILINEAR) - { + if (params->textureMode[1] & TEXTUREMODE_TRILINEAR) { addbyte(0x66); /*PXOR XMM0, R12(xmm_00_ff_w)[EBX]*/ addbyte(0x41); addbyte(0x0f); addbyte(0xef); addbyte(0x04); addbyte(0x1c); - } - else if (!tc_reverse_blend_1) - { + } else if (!tc_reverse_blend_1) { addbyte(0x66); /*PXOR XMM0, XMM9(xmm_ff_w)*/ addbyte(0x41); addbyte(0x0f); @@ -1213,15 +1147,12 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x0f); addbyte(0xf9); addbyte(0xc8); - if (tc_add_clocal_1) - { + if (tc_add_clocal_1) { addbyte(0x66); /*PADDW XMM1, XMM3*/ addbyte(0x0f); addbyte(0xfd); addbyte(0xcb); - } - else if (tc_add_alocal_1) - { + } else if (tc_add_alocal_1) { addbyte(0xf2); /*PSHUFLW XMM0, XMM3, 0xff*/ addbyte(0x0f); addbyte(0x70); @@ -1236,8 +1167,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x0f); addbyte(0x67); addbyte(0xd9); - if (tca_sub_clocal_1) - { + if (tca_sub_clocal_1) { addbyte(0x66); /*MOVD EBX, XMM3*/ addbyte(0x0f); addbyte(0x7e); @@ -1249,30 +1179,28 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xda); } - if (tca_sub_clocal_1) - { + if (tca_sub_clocal_1) { addbyte(0xc1); /*SHR EBX, 24*/ addbyte(0xeb); addbyte(24); - switch (tca_mselect_1) - { - case TCA_MSELECT_ZERO: + switch (tca_mselect_1) { + case TCA_MSELECT_ZERO: addbyte(0x31); /*XOR EAX, EAX*/ addbyte(0xc0); break; - case TCA_MSELECT_CLOCAL: + case TCA_MSELECT_CLOCAL: addbyte(0x89); /*MOV EAX, EBX*/ addbyte(0xd8); break; - case TCA_MSELECT_AOTHER: + case TCA_MSELECT_AOTHER: addbyte(0x31); /*XOR EAX, EAX*/ addbyte(0xc0); break; - case TCA_MSELECT_ALOCAL: + case TCA_MSELECT_ALOCAL: addbyte(0x89); /*MOV EAX, EBX*/ addbyte(0xd8); break; - case TCA_MSELECT_DETAIL: + case TCA_MSELECT_DETAIL: addbyte(0xb8); /*MOV EAX, params->detail_bias[1]*/ addlong(params->detail_bias[1]); addbyte(0x2b); /*SUB EAX, state->lod*/ @@ -1289,22 +1217,19 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x4d); addbyte(0xc2); break; - case TCA_MSELECT_LOD_FRAC: + case TCA_MSELECT_LOD_FRAC: addbyte(0x8b); /*MOV EAX, state->lod_frac[1]*/ addbyte(0x87); addlong(offsetof(voodoo_state_t, lod_frac[1])); break; } - if (params->textureMode[1] & TEXTUREMODE_TRILINEAR) - { + if (params->textureMode[1] & TEXTUREMODE_TRILINEAR) { addbyte(0x41); /*XOR EAX, R13(i_00_ff_w)[ECX*4]*/ addbyte(0x33); addbyte(0x44); addbyte(0x8d); addbyte(0); - } - else if (!tc_reverse_blend_1) - { + } else if (!tc_reverse_blend_1) { addbyte(0x35); /*XOR EAX, 0xff*/ addlong(0xff); } @@ -1321,8 +1246,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xc1); /*SAR EAX, 8*/ addbyte(0xf8); addbyte(8); - if (tca_add_clocal_1 || tca_add_alocal_1) - { + if (tca_add_clocal_1 || tca_add_alocal_1) { addbyte(0x01); /*ADD EAX, EBX*/ addbyte(0xd8); } @@ -1337,7 +1261,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xd8); addbyte(3); } - + block_pos = codegen_texture_fetch(code_block, voodoo, params, state, block_pos, 0); addbyte(0x66); /*MOVD XMM0, EAX*/ @@ -1348,32 +1272,25 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x0f); addbyte(0x6e); addbyte(0xf8); - - if (params->textureMode[0] & TEXTUREMODE_TRILINEAR) - { + + if (params->textureMode[0] & TEXTUREMODE_TRILINEAR) { addbyte(0x8b); /*MOV EAX, state->lod*/ addbyte(0x87); addlong(offsetof(voodoo_state_t, lod)); - if (!tc_reverse_blend) - { + if (!tc_reverse_blend) { addbyte(0xbb); /*MOV EBX, 1*/ addlong(1); - } - else - { + } else { addbyte(0x31); /*XOR EBX, EBX*/ addbyte(0xdb); } addbyte(0x83); /*AND EAX, 1*/ addbyte(0xe0); addbyte(1); - if (!tca_reverse_blend) - { + if (!tca_reverse_blend) { addbyte(0xb9); /*MOV ECX, 1*/ addlong(1); - } - else - { + } else { addbyte(0x31); /*XOR ECX, ECX*/ addbyte(0xc9); } @@ -1393,57 +1310,52 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x0f); addbyte(0x60); addbyte(0xc2); - if (tc_zero_other) - { + if (tc_zero_other) { addbyte(0x66); /*PXOR XMM1, XMM1*/ addbyte(0x0f); addbyte(0xef); addbyte(0xc9); - } - else - { + } else { addbyte(0xf3); /*MOV XMM1, XMM3*/ addbyte(0x0f); addbyte(0x7e); addbyte(0xcb); } - if (tc_sub_clocal) - { + if (tc_sub_clocal) { addbyte(0x66); /*PSUBW XMM1, XMM0*/ addbyte(0x0f); addbyte(0xf9); addbyte(0xc8); } - switch (tc_mselect) - { - case TC_MSELECT_ZERO: + switch (tc_mselect) { + case TC_MSELECT_ZERO: addbyte(0x66); /*PXOR XMM4, XMM4*/ addbyte(0x0f); addbyte(0xef); addbyte(0xe4); break; - case TC_MSELECT_CLOCAL: + case TC_MSELECT_CLOCAL: addbyte(0xf3); /*MOV XMM4, XMM0*/ addbyte(0x0f); addbyte(0x7e); addbyte(0xe0); break; - case TC_MSELECT_AOTHER: + case TC_MSELECT_AOTHER: addbyte(0xf2); /*PSHUFLW XMM4, XMM3, 3, 3, 3, 3*/ addbyte(0x0f); addbyte(0x70); addbyte(0xe3); addbyte(0xff); break; - case TC_MSELECT_ALOCAL: + case TC_MSELECT_ALOCAL: addbyte(0xf2); /*PSHUFLW XMM4, XMM0, 3, 3, 3, 3*/ addbyte(0x0f); addbyte(0x70); addbyte(0xe0); addbyte(0xff); break; - case TC_MSELECT_DETAIL: + case TC_MSELECT_DETAIL: addbyte(0xb8); /*MOV EAX, params->detail_bias[0]*/ addlong(params->detail_bias[0]); addbyte(0x2b); /*SUB EAX, state->lod*/ @@ -1469,7 +1381,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xe4); addbyte(0); break; - case TC_MSELECT_LOD_FRAC: + case TC_MSELECT_LOD_FRAC: addbyte(0x66); /*MOVD XMM0, state->lod_frac[0]*/ addbyte(0x0f); addbyte(0x6e); @@ -1482,17 +1394,14 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0); break; } - if (params->textureMode[0] & TEXTUREMODE_TRILINEAR) - { + if (params->textureMode[0] & TEXTUREMODE_TRILINEAR) { addbyte(0x66); /*PXOR XMM4, R12(xmm_00_ff_w)[EBX]*/ addbyte(0x41); addbyte(0x0f); addbyte(0xef); addbyte(0x24); addbyte(0x1c); - } - else if (!tc_reverse_blend) - { + } else if (!tc_reverse_blend) { addbyte(0x66); /*PXOR XMM4, XMM9(xmm_ff_w)*/ addbyte(0x41); addbyte(0x0f); @@ -1513,8 +1422,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xd5); addbyte(0xcc); - if (tca_sub_clocal) - { + if (tca_sub_clocal) { addbyte(0x66); /*MOV EBX, XMM7*/ addbyte(0x0f); addbyte(0x7e); @@ -1539,22 +1447,18 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x6b); addbyte(0xc9); - if (tca_sub_clocal) - { + if (tca_sub_clocal) { addbyte(0xc1); /*SHR EBX, 24*/ addbyte(0xeb); addbyte(24); } - if (tc_add_clocal) - { + if (tc_add_clocal) { addbyte(0x66); /*PADDW XMM1, XMM0*/ addbyte(0x0f); addbyte(0xfd); addbyte(0xc8); - } - else if (tc_add_alocal) - { + } else if (tc_add_alocal) { addbyte(0xf2); /*PSHUFLW XMM4, XMM0, 3, 3, 3, 3*/ addbyte(0x0f); addbyte(0x70); @@ -1565,15 +1469,14 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xfc); addbyte(0xcc); } - if (tc_invert_output) - { + if (tc_invert_output) { addbyte(0x66); /*PXOR XMM1, XMM9(xmm_ff_w)*/ addbyte(0x41); addbyte(0x0f); addbyte(0xef); addbyte(0xc9); } - + addbyte(0x66); /*PACKUSWB XMM0, XMM0*/ addbyte(0x0f); addbyte(0x67); @@ -1586,14 +1489,11 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x0f); addbyte(0x67); addbyte(0xc9); - - if (tca_zero_other) - { + + if (tca_zero_other) { addbyte(0x31); /*XOR EAX, EAX*/ addbyte(0xc0); - } - else - { + } else { addbyte(0x66); /*MOV EAX, XMM3*/ addbyte(0x0f); addbyte(0x7e); @@ -1602,18 +1502,16 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xe8); addbyte(24); } - if (tca_sub_clocal) - { + if (tca_sub_clocal) { addbyte(0x29); /*SUB EAX, EBX*/ addbyte(0xd8); } - switch (tca_mselect) - { - case TCA_MSELECT_ZERO: + switch (tca_mselect) { + case TCA_MSELECT_ZERO: addbyte(0x31); /*XOR EBX, EBX*/ addbyte(0xdb); break; - case TCA_MSELECT_CLOCAL: + case TCA_MSELECT_CLOCAL: addbyte(0x66); /*MOV EBX, XMM7*/ addbyte(0x0f); addbyte(0x7e); @@ -1622,7 +1520,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xeb); addbyte(24); break; - case TCA_MSELECT_AOTHER: + case TCA_MSELECT_AOTHER: addbyte(0x66); /*MOV EBX, XMM3*/ addbyte(0x0f); addbyte(0x7e); @@ -1631,7 +1529,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xeb); addbyte(24); break; - case TCA_MSELECT_ALOCAL: + case TCA_MSELECT_ALOCAL: addbyte(0x66); /*MOV EBX, XMM7*/ addbyte(0x0f); addbyte(0x7e); @@ -1640,7 +1538,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xeb); addbyte(24); break; - case TCA_MSELECT_DETAIL: + case TCA_MSELECT_DETAIL: addbyte(0xbb); /*MOV EBX, params->detail_bias[1]*/ addlong(params->detail_bias[1]); addbyte(0x2b); /*SUB EBX, state->lod*/ @@ -1657,22 +1555,19 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x4d); addbyte(0xda); break; - case TCA_MSELECT_LOD_FRAC: + case TCA_MSELECT_LOD_FRAC: addbyte(0x8b); /*MOV EBX, state->lod_frac[0]*/ addbyte(0x9f); addlong(offsetof(voodoo_state_t, lod_frac[0])); break; } - if (params->textureMode[0] & TEXTUREMODE_TRILINEAR) - { + if (params->textureMode[0] & TEXTUREMODE_TRILINEAR) { addbyte(0x41); /*XOR EBX, R13(i_00_ff_w)[ECX*4]*/ addbyte(0x33); addbyte(0x5c); addbyte(0x8d); addbyte(0); - } - else if (!tca_reverse_blend) - { + } else if (!tca_reverse_blend) { addbyte(0x81); /*XOR EBX, 0xFF*/ addbyte(0xf3); addlong(0xff); @@ -1689,8 +1584,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xc1); /*SAR EAX, 8*/ addbyte(0xf8); addbyte(8); - if (tca_add_clocal || tca_add_alocal) - { + if (tca_add_clocal || tca_add_alocal) { addbyte(0x66); /*MOV EBX, XMM7*/ addbyte(0x0f); addbyte(0x7e); @@ -1711,8 +1605,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x0f); /*CMOVA EAX, EDX*/ addbyte(0x47); addbyte(0xc2); - if (tca_invert_output) - { + if (tca_invert_output) { addbyte(0x35); /*XOR EAX, 0xff*/ addlong(0xff); } @@ -1726,19 +1619,16 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x7e); addbyte(0xc1); } - if (cc_mselect == CC_MSELECT_TEXRGB) - { + if (cc_mselect == CC_MSELECT_TEXRGB) { addbyte(0xf3); /*MOVD XMM4, XMM0*/ addbyte(0x0f); addbyte(0x7e); addbyte(0xe0); } - if ((params->fbzMode & FBZ_CHROMAKEY)) - { - switch (_rgb_sel) - { - case CC_LOCALSELECT_ITER_RGB: + if ((params->fbzMode & FBZ_CHROMAKEY)) { + switch (_rgb_sel) { + case CC_LOCALSELECT_ITER_RGB: addbyte(0xf3); /*MOVDQU XMM0, ib*/ /* ir, ig and ib must be in same dqword!*/ addbyte(0x0f); addbyte(0x6f); @@ -1762,12 +1652,12 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x7e); addbyte(0xc0); break; - case CC_LOCALSELECT_COLOR1: + case CC_LOCALSELECT_COLOR1: addbyte(0x8b); /*MOV EAX, params->color1[RSI]*/ addbyte(0x86); addlong(offsetof(voodoo_params_t, color1)); break; - case CC_LOCALSELECT_TEX: + case CC_LOCALSELECT_TEX: addbyte(0x66); /*MOVD EAX, XMM0*/ addbyte(0x0f); addbyte(0x7e); @@ -1788,8 +1678,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addlong(0); } - if (voodoo->trexInit1[0] & (1 << 18)) - { + if (voodoo->trexInit1[0] & (1 << 18)) { addbyte(0xb8); /*MOV EAX, tmuConfig*/ addlong(voodoo->tmuConfig); addbyte(0x66); /*MOVD XMM0, EAX*/ @@ -1798,12 +1687,10 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xc0); } - if (params->alphaMode & ((1 << 0) | (1 << 4))) - { + if (params->alphaMode & ((1 << 0) | (1 << 4))) { /*EBX = a_other*/ - switch (a_sel) - { - case A_SEL_ITER_A: + switch (a_sel) { + case A_SEL_ITER_A: addbyte(0x8b); /*MOV EBX, state->ia*/ addbyte(0x9f); addlong(offsetof(voodoo_state_t, ia)); @@ -1823,41 +1710,37 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x47); addbyte(0xda); break; - case A_SEL_TEX: + case A_SEL_TEX: addbyte(0x8b); /*MOV EBX, state->tex_a*/ addbyte(0x9f); addlong(offsetof(voodoo_state_t, tex_a)); break; - case A_SEL_COLOR1: + case A_SEL_COLOR1: addbyte(0x0f); /*MOVZX EBX, params->color1+3*/ addbyte(0xb6); addbyte(0x9e); - addlong(offsetof(voodoo_params_t, color1)+3); + addlong(offsetof(voodoo_params_t, color1) + 3); break; - default: + default: addbyte(0x31); /*XOR EBX, EBX*/ addbyte(0xdb); break; } /*ECX = a_local*/ - switch (cca_localselect) - { - case CCA_LOCALSELECT_ITER_A: - if (a_sel == A_SEL_ITER_A) - { + switch (cca_localselect) { + case CCA_LOCALSELECT_ITER_A: + if (a_sel == A_SEL_ITER_A) { addbyte(0x89); /*MOV ECX, EBX*/ addbyte(0xd9); - } - else - { + } else { addbyte(0x8b); /*MOV ECX, state->ia*/ addbyte(0x8f); addlong(offsetof(voodoo_state_t, ia)); addbyte(0x31); /*XOR EAX, EAX*/ - addbyte(0xc0); + addbyte(0xc0); addbyte(0xba); /*MOV EDX, 0xff*/ addlong(0xff); - addbyte(0xc1);/*SAR ECX, 12*/ + addbyte(0xc1); /*SAR ECX, 12*/ addbyte(0xf9); addbyte(12); addbyte(0x0f); /*CMOVS ECX, EAX*/ @@ -1870,24 +1753,23 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xca); } break; - case CCA_LOCALSELECT_COLOR0: + case CCA_LOCALSELECT_COLOR0: addbyte(0x0f); /*MOVZX ECX, params->color0+3*/ addbyte(0xb6); addbyte(0x8e); - addlong(offsetof(voodoo_params_t, color0)+3); + addlong(offsetof(voodoo_params_t, color0) + 3); break; - case CCA_LOCALSELECT_ITER_Z: + case CCA_LOCALSELECT_ITER_Z: addbyte(0x8b); /*MOV ECX, state->z*/ addbyte(0x8f); addlong(offsetof(voodoo_state_t, z)); - if (a_sel != A_SEL_ITER_A) - { + if (a_sel != A_SEL_ITER_A) { addbyte(0x31); /*XOR EAX, EAX*/ - addbyte(0xc0); + addbyte(0xc0); addbyte(0xba); /*MOV EDX, 0xff*/ addlong(0xff); } - addbyte(0xc1);/*SAR ECX, 20*/ + addbyte(0xc1); /*SAR ECX, 20*/ addbyte(0xf9); addbyte(20); addbyte(0x0f); /*CMOVS ECX, EAX*/ @@ -1899,46 +1781,37 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x47); addbyte(0xca); break; - - default: + + default: addbyte(0xb9); /*MOV ECX, 0xff*/ addlong(0xff); break; } - if (cca_zero_other) - { + if (cca_zero_other) { addbyte(0x31); /*XOR EDX, EDX*/ addbyte(0xd2); - } - else - { + } else { addbyte(0x89); /*MOV EDX, EBX*/ addbyte(0xda); } - - if (cca_sub_clocal) - { + + if (cca_sub_clocal) { addbyte(0x29); /*SUB EDX, ECX*/ addbyte(0xca); } } - if (cc_sub_clocal || cc_mselect == 1 || cc_add == 1) - { + if (cc_sub_clocal || cc_mselect == 1 || cc_add == 1) { /*XMM1 = local*/ - if (!cc_localselect_override) - { - if (cc_localselect) - { + if (!cc_localselect_override) { + if (cc_localselect) { addbyte(0x66); /*MOVD XMM1, params->color0*/ addbyte(0x0f); addbyte(0x6e); addbyte(0x8e); addlong(offsetof(voodoo_params_t, color0)); - } - else - { + } else { addbyte(0xf3); /*MOVDQU XMM1, ib*/ /* ir, ig and ib must be in same dqword!*/ addbyte(0x0f); addbyte(0x6f); @@ -1958,52 +1831,48 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x67); addbyte(0xc9); } - } - else - { + } else { addbyte(0xf6); /*TEST state->tex_a, 0x80*/ addbyte(0x87); addbyte(0x23); addlong(offsetof(voodoo_state_t, tex_a)); addbyte(0x80); - addbyte(0x74);/*JZ !cc_localselect*/ - addbyte(8+2); - addbyte(0x66); /*MOVD XMM1, params->color0*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0x8e); - addlong(offsetof(voodoo_params_t, color0)); - addbyte(0xeb); /*JMP +*/ - addbyte(8+5+4+4); + addbyte(0x74); /*JZ !cc_localselect*/ + addbyte(8 + 2); + addbyte(0x66); /*MOVD XMM1, params->color0*/ + addbyte(0x0f); + addbyte(0x6e); + addbyte(0x8e); + addlong(offsetof(voodoo_params_t, color0)); + addbyte(0xeb); /*JMP +*/ + addbyte(8 + 5 + 4 + 4); /*!cc_localselect:*/ - addbyte(0xf3); /*MOVDQU XMM1, ib*/ /* ir, ig and ib must be in same dqword!*/ - addbyte(0x0f); - addbyte(0x6f); - addbyte(0x8f); - addlong(offsetof(voodoo_state_t, ib)); - addbyte(0x66); /*PSRAD XMM1, 12*/ - addbyte(0x0f); - addbyte(0x72); - addbyte(0xe1); - addbyte(12); - addbyte(0x66); /*PACKSSDW XMM1, XMM1*/ - addbyte(0x0f); - addbyte(0x6b); - addbyte(0xc9); - addbyte(0x66); /*PACKUSWB XMM1, XMM1*/ - addbyte(0x0f); - addbyte(0x67); - addbyte(0xc9); + addbyte(0xf3); /*MOVDQU XMM1, ib*/ /* ir, ig and ib must be in same dqword!*/ + addbyte(0x0f); + addbyte(0x6f); + addbyte(0x8f); + addlong(offsetof(voodoo_state_t, ib)); + addbyte(0x66); /*PSRAD XMM1, 12*/ + addbyte(0x0f); + addbyte(0x72); + addbyte(0xe1); + addbyte(12); + addbyte(0x66); /*PACKSSDW XMM1, XMM1*/ + addbyte(0x0f); + addbyte(0x6b); + addbyte(0xc9); + addbyte(0x66); /*PACKUSWB XMM1, XMM1*/ + addbyte(0x0f); + addbyte(0x67); + addbyte(0xc9); } addbyte(0x66); /*PUNPCKLBW XMM1, XMM2*/ addbyte(0x0f); addbyte(0x60); addbyte(0xca); } - if (!cc_zero_other) - { - if (_rgb_sel == CC_LOCALSELECT_ITER_RGB) - { + if (!cc_zero_other) { + if (_rgb_sel == CC_LOCALSELECT_ITER_RGB) { addbyte(0xf3); /*MOVDQU XMM0, ib*/ /* ir, ig and ib must be in same dqword!*/ addbyte(0x0f); addbyte(0x6f); @@ -2022,9 +1891,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x0f); addbyte(0x67); addbyte(0xc0); - } - else if (_rgb_sel == CC_LOCALSELECT_TEX) - { + } else if (_rgb_sel == CC_LOCALSELECT_TEX) { #if 0 addbyte(0xf3); /*MOVDQU XMM0, state->tex_b*/ addbyte(0x0f); @@ -2040,39 +1907,31 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x67); addbyte(0xc0); #endif - } - else if (_rgb_sel == CC_LOCALSELECT_COLOR1) - { + } else if (_rgb_sel == CC_LOCALSELECT_COLOR1) { addbyte(0x66); /*MOVD XMM0, params->color1*/ addbyte(0x0f); addbyte(0x6e); addbyte(0x86); addlong(offsetof(voodoo_params_t, color1)); - } - else - { + } else { /*MOVD XMM0, src_r*/ } addbyte(0x66); /*PUNPCKLBW XMM0, XMM2*/ addbyte(0x0f); addbyte(0x60); addbyte(0xc2); - if (cc_sub_clocal) - { + if (cc_sub_clocal) { addbyte(0x66); /*PSUBW XMM0, XMM1*/ addbyte(0x0f); addbyte(0xf9); addbyte(0xc1); } - } - else - { + } else { addbyte(0x66); /*PXOR XMM0, XMM0*/ addbyte(0x0f); addbyte(0xef); addbyte(0xc0); - if (cc_sub_clocal) - { + if (cc_sub_clocal) { addbyte(0x66); /*PSUBW XMM0, XMM1*/ addbyte(0x0f); addbyte(0xf9); @@ -2080,39 +1939,35 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo } } - if (params->alphaMode & ((1 << 0) | (1 << 4))) - { - if (!(cca_mselect == 0 && cca_reverse_blend == 0)) - { - switch (cca_mselect) - { - case CCA_MSELECT_ALOCAL: + if (params->alphaMode & ((1 << 0) | (1 << 4))) { + if (!(cca_mselect == 0 && cca_reverse_blend == 0)) { + switch (cca_mselect) { + case CCA_MSELECT_ALOCAL: addbyte(0x89); /*MOV EAX, ECX*/ addbyte(0xc8); break; - case CCA_MSELECT_AOTHER: + case CCA_MSELECT_AOTHER: addbyte(0x89); /*MOV EAX, EBX*/ addbyte(0xd8); break; - case CCA_MSELECT_ALOCAL2: + case CCA_MSELECT_ALOCAL2: addbyte(0x89); /*MOV EAX, ECX*/ addbyte(0xc8); break; - case CCA_MSELECT_TEX: + case CCA_MSELECT_TEX: addbyte(0x0f); /*MOVZX EAX, state->tex_a*/ addbyte(0xb6); addbyte(0x87); addlong(offsetof(voodoo_state_t, tex_a)); break; - case CCA_MSELECT_ZERO: - default: + case CCA_MSELECT_ZERO: + default: addbyte(0x31); /*XOR EAX, EAX*/ addbyte(0xc0); break; } - if (!cca_reverse_blend) - { + if (!cca_reverse_blend) { addbyte(0x35); /*XOR EAX, 0xff*/ addlong(0xff); } @@ -2128,14 +1983,12 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo } } - if ((params->alphaMode & ((1 << 0) | (1 << 4)))) - { + if ((params->alphaMode & ((1 << 0) | (1 << 4)))) { addbyte(0x31); /*XOR EAX, EAX*/ addbyte(0xc0); } - - if (!(cc_mselect == 0 && cc_reverse_blend == 0) && cc_mselect == CC_MSELECT_AOTHER) - { + + if (!(cc_mselect == 0 && cc_reverse_blend == 0) && cc_mselect == CC_MSELECT_AOTHER) { /*Copy a_other to XMM3 before it gets modified*/ addbyte(0x66); /*MOVD XMM3, EDX*/ addbyte(0x0f); @@ -2147,15 +2000,13 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xdb); addbyte(0x00); } - - if (cca_add && (params->alphaMode & ((1 << 0) | (1 << 4)))) - { + + if (cca_add && (params->alphaMode & ((1 << 0) | (1 << 4)))) { addbyte(0x01); /*ADD EDX, ECX*/ addbyte(0xca); } - if ((params->alphaMode & ((1 << 0) | (1 << 4)))) - { + if ((params->alphaMode & ((1 << 0) | (1 << 4)))) { addbyte(0x85); /*TEST EDX, EDX*/ addbyte(0xd2); addbyte(0x0f); /*CMOVS EDX, EAX*/ @@ -2169,31 +2020,28 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x0f); /*CMOVA EDX, EAX*/ addbyte(0x47); addbyte(0xd0); - if (cca_invert_output) - { + if (cca_invert_output) { addbyte(0x81); /*XOR EDX, 0xff*/ addbyte(0xf2); addlong(0xff); } } - if (!(cc_mselect == 0 && cc_reverse_blend == 0)) - { - switch (cc_mselect) - { - case CC_MSELECT_ZERO: + if (!(cc_mselect == 0 && cc_reverse_blend == 0)) { + switch (cc_mselect) { + case CC_MSELECT_ZERO: addbyte(0x66); /*PXOR XMM3, XMM3*/ addbyte(0x0f); addbyte(0xef); addbyte(0xdb); break; - case CC_MSELECT_CLOCAL: + case CC_MSELECT_CLOCAL: addbyte(0xf3); /*MOV XMM3, XMM1*/ addbyte(0x0f); addbyte(0x7e); addbyte(0xd9); break; - case CC_MSELECT_ALOCAL: + case CC_MSELECT_ALOCAL: addbyte(0x66); /*MOVD XMM3, ECX*/ addbyte(0x0f); addbyte(0x6e); @@ -2204,10 +2052,10 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xdb); addbyte(0x00); break; - case CC_MSELECT_AOTHER: + case CC_MSELECT_AOTHER: /*Handled above*/ break; - case CC_MSELECT_TEX: + case CC_MSELECT_TEX: addbyte(0x66); /*PINSRW XMM3, state->tex_a, 0*/ addbyte(0x0f); addbyte(0xc4); @@ -2227,7 +2075,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addlong(offsetof(voodoo_state_t, tex_a)); addbyte(2); break; - case CC_MSELECT_TEXRGB: + case CC_MSELECT_TEXRGB: addbyte(0x66); /*PUNPCKLBW XMM4, XMM2*/ addbyte(0x0f); addbyte(0x60); @@ -2237,19 +2085,18 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x7e); addbyte(0xdc); break; - default: + default: addbyte(0x66); /*PXOR XMM3, XMM3*/ addbyte(0x0f); addbyte(0xef); addbyte(0xdb); - break; + break; } addbyte(0xf3); /*MOV XMM4, XMM0*/ addbyte(0x0f); addbyte(0x7e); addbyte(0xe0); - if (!cc_reverse_blend) - { + if (!cc_reverse_blend) { addbyte(0x66); /*PXOR XMM3, XMM9(xmm_ff_w)*/ addbyte(0x41); addbyte(0x0f); @@ -2283,9 +2130,8 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x6b); addbyte(0xc0); } - - if (cc_add == 1) - { + + if (cc_add == 1) { addbyte(0x66); /*PADDW XMM0, XMM1*/ addbyte(0x0f); addbyte(0xfd); @@ -2297,8 +2143,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x67); addbyte(0xc0); - if (cc_invert_output) - { + if (cc_invert_output) { addbyte(0x66); /*PXOR XMM0, XMM10(xmm_ff_b)*/ addbyte(0x41); addbyte(0x0f); @@ -2306,10 +2151,8 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xc2); } - if (params->fogMode & FOG_ENABLE) - { - if (params->fogMode & FOG_CONSTANT) - { + if (params->fogMode & FOG_ENABLE) { + if (params->fogMode & FOG_CONSTANT) { addbyte(0x66); /*MOVD XMM3, params->fogColor[ESI]*/ addbyte(0x0f); addbyte(0x6e); @@ -2319,16 +2162,13 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x0f); addbyte(0xdc); addbyte(0xc3); - } - else - { + } else { addbyte(0x66); /*PUNPCKLBW XMM0, XMM2*/ addbyte(0x0f); addbyte(0x60); addbyte(0xc2); - if (!(params->fogMode & FOG_ADD)) - { + if (!(params->fogMode & FOG_ADD)) { addbyte(0x66); /*MOVD XMM3, params->fogColor[ESI]*/ addbyte(0x0f); addbyte(0x6e); @@ -2338,17 +2178,14 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x0f); addbyte(0x60); addbyte(0xda); - } - else - { + } else { addbyte(0x66); /*PXOR XMM3, XMM3*/ addbyte(0x0f); addbyte(0xef); addbyte(0xdb); } - - if (!(params->fogMode & FOG_MULT)) - { + + if (!(params->fogMode & FOG_MULT)) { addbyte(0x66); /*PSUBW XMM3, XMM0*/ addbyte(0x0f); addbyte(0xf9); @@ -2362,9 +2199,8 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xe3); addbyte(1); - switch (params->fogMode & (FOG_Z|FOG_ALPHA)) - { - case 0: + switch (params->fogMode & (FOG_Z | FOG_ALPHA)) { + case 0: addbyte(0x8b); /*MOV EBX, state->w_depth[EDI]*/ addbyte(0x9f); addlong(offsetof(voodoo_state_t, w_depth)); @@ -2384,7 +2220,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xf6); /*MUL params->fogTable+1[ESI+EBX*2]*/ addbyte(0xa4); addbyte(0x5e); - addlong(offsetof(voodoo_params_t, fogTable)+1); + addlong(offsetof(voodoo_params_t, fogTable) + 1); addbyte(0x0f); /*MOVZX EBX, params->fogTable[ESI+EBX*2]*/ addbyte(0xb6); addbyte(0x9c); @@ -2395,13 +2231,14 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(10); addbyte(0x01); /*ADD EAX, EBX*/ addbyte(0xd8); -/* int fog_idx = (w_depth >> 10) & 0x3f; + /* int fog_idx = (w_depth >> 10) & 0x3f; - fog_a = params->fogTable[fog_idx].fog; - fog_a += (params->fogTable[fog_idx].dfog * ((w_depth >> 2) & 0xff)) >> 10;*/ + fog_a = params->fogTable[fog_idx].fog; + fog_a += (params->fogTable[fog_idx].dfog * ((w_depth >> 2) & + 0xff)) >> 10;*/ break; - - case FOG_Z: + + case FOG_Z: addbyte(0x8b); /*MOV EAX, state->z[EDI]*/ addbyte(0x87); addlong(offsetof(voodoo_state_t, z)); @@ -2410,10 +2247,10 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(12); addbyte(0x25); /*AND EAX, 0xff*/ addlong(0xff); -// fog_a = (z >> 20) & 0xff; + // fog_a = (z >> 20) & 0xff; break; - - case FOG_ALPHA: + + case FOG_ALPHA: addbyte(0x8b); /*MOV EAX, state->ia[EDI]*/ addbyte(0x87); addlong(offsetof(voodoo_state_t, ia)); @@ -2432,13 +2269,13 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x0f); /*CMOVAE EAX, EBX*/ addbyte(0x43); addbyte(0xc3); -// fog_a = CLAMP(ia >> 12); + // fog_a = CLAMP(ia >> 12); break; - - case FOG_W: + + case FOG_W: addbyte(0x8b); /*MOV EAX, state->w[EDI]+4*/ addbyte(0x87); - addlong(offsetof(voodoo_state_t, w)+4); + addlong(offsetof(voodoo_state_t, w) + 4); addbyte(0x31); /*XOR EBX, EBX*/ addbyte(0xdb); addbyte(0x09); /*OR EAX, EAX*/ @@ -2453,7 +2290,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x0f); /*CMOVAE EAX, EBX*/ addbyte(0x43); addbyte(0xc3); -// fog_a = CLAMP(w >> 32); + // fog_a = CLAMP(w >> 32); break; } addbyte(0x01); /*ADD EAX, EAX*/ @@ -2472,15 +2309,12 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xe3); addbyte(7); - if (params->fogMode & FOG_MULT) - { + if (params->fogMode & FOG_MULT) { addbyte(0xf3); /*MOV XMM0, XMM3*/ addbyte(0x0f); addbyte(0x7e); addbyte(0xc3); - } - else - { + } else { addbyte(0x66); /*PADDW XMM0, XMM3*/ addbyte(0x0f); addbyte(0xfd); @@ -2493,8 +2327,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo } } - if ((params->alphaMode & 1) && (alpha_func != AFUNC_NEVER) && (alpha_func != AFUNC_ALWAYS)) - { + if ((params->alphaMode & 1) && (alpha_func != AFUNC_NEVER) && (alpha_func != AFUNC_ALWAYS)) { addbyte(0x0f); /*MOVZX ECX, params->alphaMode+3*/ addbyte(0xb6); addbyte(0x8e); @@ -2502,53 +2335,49 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x39); /*CMP EDX, ECX*/ addbyte(0xca); - switch (alpha_func) - { - case AFUNC_LESSTHAN: + switch (alpha_func) { + case AFUNC_LESSTHAN: addbyte(0x0f); /*JAE skip*/ addbyte(0x83); a_skip_pos = block_pos; addlong(0); break; - case AFUNC_EQUAL: + case AFUNC_EQUAL: addbyte(0x0f); /*JNE skip*/ addbyte(0x85); a_skip_pos = block_pos; addlong(0); break; - case AFUNC_LESSTHANEQUAL: + case AFUNC_LESSTHANEQUAL: addbyte(0x0f); /*JA skip*/ addbyte(0x87); a_skip_pos = block_pos; addlong(0); break; - case AFUNC_GREATERTHAN: + case AFUNC_GREATERTHAN: addbyte(0x0f); /*JBE skip*/ addbyte(0x86); a_skip_pos = block_pos; addlong(0); break; - case AFUNC_NOTEQUAL: + case AFUNC_NOTEQUAL: addbyte(0x0f); /*JE skip*/ addbyte(0x84); a_skip_pos = block_pos; addlong(0); break; - case AFUNC_GREATERTHANEQUAL: + case AFUNC_GREATERTHANEQUAL: addbyte(0x0f); /*JB skip*/ addbyte(0x82); a_skip_pos = block_pos; addlong(0); break; } - } - else if ((params->alphaMode & 1) && (alpha_func == AFUNC_NEVER)) - { + } else if ((params->alphaMode & 1) && (alpha_func == AFUNC_NEVER)) { addbyte(0xC3); /*RET*/ } - - if (params->alphaMode & (1 << 4)) - { + + if (params->alphaMode & (1 << 4)) { addbyte(0x49); /*MOV R8, rgb565*/ addbyte(0xb8); addquad((uintptr_t)rgb565); @@ -2587,16 +2416,15 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x0f); addbyte(0x7e); addbyte(0xf4); - - switch (dest_afunc) - { - case AFUNC_AZERO: + + switch (dest_afunc) { + case AFUNC_AZERO: addbyte(0x66); /*PXOR XMM4, XMM4*/ addbyte(0x0f); addbyte(0xef); addbyte(0xe4); break; - case AFUNC_ASRC_ALPHA: + case AFUNC_ASRC_ALPHA: addbyte(0x66); /*PMULLW XMM4, R10(alookup)[EDX*8]*/ addbyte(0x41); addbyte(0x0f); @@ -2612,7 +2440,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x0f); addbyte(0xfd); addbyte(0x62); - addbyte(8*2); + addbyte(8 * 2); addbyte(0x66); /*PSRLW XMM5, 8*/ addbyte(0x0f); addbyte(0x71); @@ -2628,7 +2456,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xd4); addbyte(8); break; - case AFUNC_A_COLOR: + case AFUNC_A_COLOR: addbyte(0x66); /*PMULLW XMM4, XMM0*/ addbyte(0x0f); addbyte(0xd5); @@ -2642,7 +2470,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x0f); addbyte(0xfd); addbyte(0x62); - addbyte(8*2); + addbyte(8 * 2); addbyte(0x66); /*PSRLW XMM5, 8*/ addbyte(0x0f); addbyte(0x71); @@ -2658,11 +2486,11 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xd4); addbyte(8); break; - case AFUNC_ADST_ALPHA: + case AFUNC_ADST_ALPHA: break; - case AFUNC_AONE: + case AFUNC_AONE: break; - case AFUNC_AOMSRC_ALPHA: + case AFUNC_AOMSRC_ALPHA: addbyte(0x66); /*PMULLW XMM4, R11(aminuslookup)[EDX*8]*/ addbyte(0x41); addbyte(0x0f); @@ -2678,7 +2506,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x0f); addbyte(0xfd); addbyte(0x62); - addbyte(8*2); + addbyte(8 * 2); addbyte(0x66); /*PSRLW XMM5, 8*/ addbyte(0x0f); addbyte(0x71); @@ -2694,7 +2522,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xd4); addbyte(8); break; - case AFUNC_AOM_COLOR: + case AFUNC_AOM_COLOR: addbyte(0xf3); /*MOVQ XMM5, XMM9(xmm_ff_w)*/ addbyte(0x41); addbyte(0x0f); @@ -2717,7 +2545,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x0f); addbyte(0xfd); addbyte(0x62); - addbyte(8*2); + addbyte(8 * 2); addbyte(0x66); /*PSRLW XMM5, 8*/ addbyte(0x0f); addbyte(0x71); @@ -2733,13 +2561,13 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xd4); addbyte(8); break; - case AFUNC_AOMDST_ALPHA: + case AFUNC_AOMDST_ALPHA: addbyte(0x66); /*PXOR XMM4, XMM4*/ addbyte(0x0f); addbyte(0xef); addbyte(0xe4); break; - case AFUNC_ASATURATE: + case AFUNC_ASATURATE: addbyte(0x66); /*PMULLW XMM4, XMM11(minus_254)*/ addbyte(0x41); addbyte(0x0f); @@ -2754,7 +2582,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x0f); addbyte(0xfd); addbyte(0x62); - addbyte(8*2); + addbyte(8 * 2); addbyte(0x66); /*PSRLW XMM5, 8*/ addbyte(0x0f); addbyte(0x71); @@ -2771,15 +2599,14 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(8); } - switch (src_afunc) - { - case AFUNC_AZERO: + switch (src_afunc) { + case AFUNC_AZERO: addbyte(0x66); /*PXOR XMM0, XMM0*/ addbyte(0x0f); addbyte(0xef); addbyte(0xc0); break; - case AFUNC_ASRC_ALPHA: + case AFUNC_ASRC_ALPHA: addbyte(0x66); /*PMULLW XMM0, R10(alookup)[EDX*8]*/ addbyte(0x41); addbyte(0x0f); @@ -2795,7 +2622,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x0f); addbyte(0xfd); addbyte(0x42); - addbyte(8*2); + addbyte(8 * 2); addbyte(0x66); /*PSRLW XMM5, 8*/ addbyte(0x0f); addbyte(0x71); @@ -2811,7 +2638,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xd0); addbyte(8); break; - case AFUNC_A_COLOR: + case AFUNC_A_COLOR: addbyte(0x66); /*PMULLW XMM0, XMM6*/ addbyte(0x0f); addbyte(0xd5); @@ -2825,7 +2652,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x0f); addbyte(0xfd); addbyte(0x42); - addbyte(8*2); + addbyte(8 * 2); addbyte(0x66); /*PSRLW XMM5, 8*/ addbyte(0x0f); addbyte(0x71); @@ -2841,11 +2668,11 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xd0); addbyte(8); break; - case AFUNC_ADST_ALPHA: + case AFUNC_ADST_ALPHA: break; - case AFUNC_AONE: + case AFUNC_AONE: break; - case AFUNC_AOMSRC_ALPHA: + case AFUNC_AOMSRC_ALPHA: addbyte(0x66); /*PMULLW XMM0, R11(aminuslookup)[EDX*8]*/ addbyte(0x41); addbyte(0x0f); @@ -2861,7 +2688,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x0f); addbyte(0xfd); addbyte(0x42); - addbyte(8*2); + addbyte(8 * 2); addbyte(0x66); /*PSRLW XMM5, 8*/ addbyte(0x0f); addbyte(0x71); @@ -2877,7 +2704,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xd0); addbyte(8); break; - case AFUNC_AOM_COLOR: + case AFUNC_AOM_COLOR: addbyte(0xf3); /*MOVQ XMM5, XMM9(xmm_ff_w)*/ addbyte(0x41); addbyte(0x0f); @@ -2900,7 +2727,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x0f); addbyte(0xfd); addbyte(0x42); - addbyte(8*2); + addbyte(8 * 2); addbyte(0x66); /*PSRLW XMM5, 8*/ addbyte(0x0f); addbyte(0x71); @@ -2916,16 +2743,16 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xd0); addbyte(8); break; - case AFUNC_AOMDST_ALPHA: + case AFUNC_AOMDST_ALPHA: addbyte(0x66); /*PXOR XMM0, XMM0*/ addbyte(0x0f); addbyte(0xef); addbyte(0xc0); break; - case AFUNC_ACOLORBEFOREFOG: + case AFUNC_ACOLORBEFOREFOG: break; } - + addbyte(0x66); /*PADDW XMM0, XMM4*/ addbyte(0x0f); addbyte(0xfd); @@ -2948,11 +2775,9 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x0f); addbyte(0x7e); addbyte(0xc0); - - if (params->fbzMode & FBZ_RGB_WMASK) - { - if (dither) - { + + if (params->fbzMode & FBZ_RGB_WMASK) { + if (dither) { addbyte(0x49); /*MOV R8, dither_rb*/ addbyte(0xb8); addquad(dither2x2 ? (uintptr_t)dither_rb2x2 : (uintptr_t)dither_rb); @@ -2962,8 +2787,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x0f); /*MOVZX EBX, AH*/ /*G*/ addbyte(0xb6); addbyte(0xdc); - if (dither2x2) - { + if (dither2x2) { addbyte(0x83); /*AND EDX, 1*/ addbyte(0xe2); addbyte(1); @@ -2973,9 +2797,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xc1); /*SHL EBX, 2*/ addbyte(0xe3); addbyte(2); - } - else - { + } else { addbyte(0x83); /*AND EDX, 3*/ addbyte(0xe2); addbyte(3); @@ -2989,17 +2811,14 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x0f); /*MOVZX ECX, AL*/ /*R*/ addbyte(0xb6); addbyte(0xc8); - if (dither2x2) - { + if (dither2x2) { addbyte(0xc1); /*SHR EAX, 14*/ addbyte(0xe8); addbyte(14); addbyte(0x8d); /*LEA ESI, RDX+RSI*2*/ addbyte(0x34); addbyte(0x72); - } - else - { + } else { addbyte(0xc1); /*SHR EAX, 12*/ addbyte(0xe8); addbyte(12); @@ -3016,16 +2835,13 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x4c); /*ADD RSI, R8*/ addbyte(0x01); addbyte(0xc6); - if (dither2x2) - { + if (dither2x2) { addbyte(0xc1); /*SHL ECX, 2*/ addbyte(0xe1); addbyte(2); addbyte(0x25); /*AND EAX, 0x3fc*/ /*B*/ addlong(0x3fc); - } - else - { + } else { addbyte(0xc1); /*SHL ECX, 4*/ addbyte(0xe1); addbyte(4); @@ -3036,7 +2852,8 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xb6); addbyte(0x9c); addbyte(0x1e); - addlong(dither2x2 ? ((uintptr_t)dither_g2x2 - (uintptr_t)dither_rb2x2) : ((uintptr_t)dither_g - (uintptr_t)dither_rb)); + addlong(dither2x2 ? ((uintptr_t)dither_g2x2 - (uintptr_t)dither_rb2x2) + : ((uintptr_t)dither_g - (uintptr_t)dither_rb)); addbyte(0x0f); /*MOVZX ECX, dither_rb[RCX+RSI]*/ addbyte(0xb6); addbyte(0x0c); @@ -3055,9 +2872,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xd8); addbyte(0x09); /*OR EAX, ECX*/ addbyte(0xc8); - } - else - { + } else { addbyte(0x89); /*MOV EBX, EAX*/ addbyte(0xc3); addbyte(0x0f); /*MOVZX ECX, AH*/ @@ -3096,8 +2911,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x56); } - if ((params->fbzMode & (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) == (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) - { + if ((params->fbzMode & (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) == (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) { addbyte(0x8b); /*MOV EDX, state->x[EDI]*/ addbyte(0x97); if (params->aux_tiled) @@ -3148,7 +2962,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x0f); addbyte(0x6f); addbyte(0x86); - addlong(offsetof(voodoo_params_t, dBdX)); + addlong(offsetof(voodoo_params_t, dBdX)); addbyte(0x8b); /*MOV EAX, params->dZdX[ESI]*/ addbyte(0x86); addlong(offsetof(voodoo_params_t, dZdX)); @@ -3163,15 +2977,12 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xb6); addlong(offsetof(voodoo_params_t, tmu[0].dWdX)); - if (state->xdir > 0) - { + if (state->xdir > 0) { addbyte(0x66); /*PADDD XMM1, XMM0*/ addbyte(0x0f); addbyte(0xfe); addbyte(0xc8); - } - else - { + } else { addbyte(0x66); /*PSUBD XMM1, XMM0*/ addbyte(0x0f); addbyte(0xfa); @@ -3194,8 +3005,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xbe); addlong(offsetof(voodoo_params_t, dWdX)); - if (state->xdir > 0) - { + if (state->xdir > 0) { addbyte(0x66); /*PADDQ XMM3, XMM5*/ addbyte(0x0f); addbyte(0xd4); @@ -3210,10 +3020,8 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xc7); addbyte(0x01); /*ADD state->z[EDI], EAX*/ addbyte(0x87); - addlong(offsetof(voodoo_state_t, z)); - } - else - { + addlong(offsetof(voodoo_state_t, z)); + } else { addbyte(0x66); /*PSUBQ XMM3, XMM5*/ addbyte(0x0f); addbyte(0xfb); @@ -3228,11 +3036,10 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xc7); addbyte(0x29); /*SUB state->z[EDI], EAX*/ addbyte(0x87); - addlong(offsetof(voodoo_state_t, z)); + addlong(offsetof(voodoo_state_t, z)); } - if (voodoo->dual_tmus) - { + if (voodoo->dual_tmus) { addbyte(0xf3); /*MOVDQU XMM5, params->tmu[1].dSdX[ESI]*/ addbyte(0x0f); addbyte(0x6f); @@ -3261,8 +3068,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x87); addlong(offsetof(voodoo_state_t, w)); - if (voodoo->dual_tmus) - { + if (voodoo->dual_tmus) { addbyte(0xf3); /*MOVDQU XMM3, state->tmu1_s[EDI]*/ addbyte(0x0f); addbyte(0x6f); @@ -3274,8 +3080,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xa7); addlong(offsetof(voodoo_state_t, tmu1_w)); - if (state->xdir > 0) - { + if (state->xdir > 0) { addbyte(0x66); /*PADDQ XMM3, XMM5*/ addbyte(0x0f); addbyte(0xd4); @@ -3284,9 +3089,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x0f); addbyte(0xd4); addbyte(0xe6); - } - else - { + } else { addbyte(0x66); /*PSUBQ XMM3, XMM5*/ addbyte(0x0f); addbyte(0xfb); @@ -3296,7 +3099,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xfb); addbyte(0xe6); } - + addbyte(0xf3); /*MOVDQU state->tmu1_s, XMM3*/ addbyte(0x0f); addbyte(0x7f); @@ -3308,44 +3111,37 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xa7); addlong(offsetof(voodoo_state_t, tmu1_w)); } - + addbyte(0x83); /*ADD state->pixel_count[EDI], 1*/ addbyte(0x87); addlong(offsetof(voodoo_state_t, pixel_count)); addbyte(1); - if (params->fbzColorPath & FBZCP_TEXTURE_ENABLED) - { + if (params->fbzColorPath & FBZCP_TEXTURE_ENABLED) { if ((params->textureMode[0] & TEXTUREMODE_MASK) == TEXTUREMODE_PASSTHROUGH || - (params->textureMode[0] & TEXTUREMODE_LOCAL_MASK) == TEXTUREMODE_LOCAL) - { + (params->textureMode[0] & TEXTUREMODE_LOCAL_MASK) == TEXTUREMODE_LOCAL) { addbyte(0x83); /*ADD state->texel_count[EDI], 1*/ addbyte(0x87); addlong(offsetof(voodoo_state_t, texel_count)); addbyte(1); - } - else - { + } else { addbyte(0x83); /*ADD state->texel_count[EDI], 2*/ addbyte(0x87); addlong(offsetof(voodoo_state_t, texel_count)); addbyte(2); - } + } } addbyte(0x8b); /*MOV EAX, state->x[EDI]*/ addbyte(0x87); addlong(offsetof(voodoo_state_t, x)); - - if (state->xdir > 0) - { + + if (state->xdir > 0) { addbyte(0x83); /*ADD state->x[EDI], 1*/ addbyte(0x87); addlong(offsetof(voodoo_state_t, x)); addbyte(1); - } - else - { + } else { addbyte(0x83); /*SUB state->x[EDI], 1*/ addbyte(0xaf); addlong(offsetof(voodoo_state_t, x)); @@ -3360,54 +3156,46 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addlong(loop_jump_pos - (block_pos + 4)); addbyte(0x41); /*POP R15*/ - addbyte(0x5f); + addbyte(0x5f); addbyte(0x41); /*POP R14*/ addbyte(0x5e); addbyte(0x41); /*POP R13*/ - addbyte(0x5d); + addbyte(0x5d); addbyte(0x41); /*POP R12*/ addbyte(0x5c); - addbyte(0x5b); /*POP RBX*/ + addbyte(0x5b); /*POP RBX*/ addbyte(0x5e); /*POP RSI*/ addbyte(0x5f); /*POP RDI*/ addbyte(0x5d); /*POP RBP*/ - + addbyte(0xC3); /*RET*/ } int voodoo_recomp = 0; -static inline void *voodoo_get_block(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int odd_even) -{ +static inline void *voodoo_get_block(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int odd_even) { int c; int b = last_block[odd_even]; voodoo_x86_data_t *voodoo_x86_data = voodoo->codegen_data; voodoo_x86_data_t *data; - - for (c = 0; c < 8; c++) - { - data = &voodoo_x86_data[odd_even + c*4]; //&voodoo_x86_data[odd_even][b]; - - if (state->xdir == data->xdir && - params->alphaMode == data->alphaMode && - params->fbzMode == data->fbzMode && - params->fogMode == data->fogMode && - params->fbzColorPath == data->fbzColorPath && - (voodoo->trexInit1[0] & (1 << 18)) == data->trexInit1 && - params->textureMode[0] == data->textureMode[0] && - params->textureMode[1] == data->textureMode[1] && - (params->tLOD[0] & LOD_MASK) == data->tLOD[0] && + + for (c = 0; c < 8; c++) { + data = &voodoo_x86_data[odd_even + c * 4]; //&voodoo_x86_data[odd_even][b]; + + if (state->xdir == data->xdir && params->alphaMode == data->alphaMode && params->fbzMode == data->fbzMode && + params->fogMode == data->fogMode && params->fbzColorPath == data->fbzColorPath && + (voodoo->trexInit1[0] & (1 << 18)) == data->trexInit1 && params->textureMode[0] == data->textureMode[0] && + params->textureMode[1] == data->textureMode[1] && (params->tLOD[0] & LOD_MASK) == data->tLOD[0] && (params->tLOD[1] & LOD_MASK) == data->tLOD[1] && - ((params->col_tiled || params->aux_tiled) ? 1 : 0) == data->is_tiled) - { + ((params->col_tiled || params->aux_tiled) ? 1 : 0) == data->is_tiled) { last_block[odd_even] = b; return data->code_block; } - + b = (b + 1) & 7; } -voodoo_recomp++; - data = &voodoo_x86_data[odd_even + next_block_to_write[odd_even]*4]; -// code_block = data->code_block; - + voodoo_recomp++; + data = &voodoo_x86_data[odd_even + next_block_to_write[odd_even] * 4]; + // code_block = data->code_block; + voodoo_generate(data->code_block, voodoo, params, state, depth_op); data->xdir = state->xdir; @@ -3423,51 +3211,49 @@ voodoo_recomp++; data->is_tiled = (params->col_tiled || params->aux_tiled) ? 1 : 0; next_block_to_write[odd_even] = (next_block_to_write[odd_even] + 1) & 7; - + return data->code_block; } -void voodoo_codegen_init(voodoo_t *voodoo) -{ +void voodoo_codegen_init(voodoo_t *voodoo) { int c; #if WIN64 voodoo->codegen_data = VirtualAlloc(NULL, sizeof(voodoo_x86_data_t) * BLOCK_NUM * 4, MEM_COMMIT, PAGE_EXECUTE_READWRITE); #else - voodoo->codegen_data = mmap(0, sizeof(voodoo_x86_data_t) * BLOCK_NUM*4, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, 0, 0); + voodoo->codegen_data = mmap(0, sizeof(voodoo_x86_data_t) * BLOCK_NUM * 4, PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_ANON | MAP_PRIVATE, 0, 0); #endif - for (c = 0; c < 256; c++) - { + for (c = 0; c < 256; c++) { int d[4]; int _ds = c & 0xf; int dt = c >> 4; - + alookup[c] = _mm_set_epi32(0, 0, c | (c << 16), c | (c << 16)); - aminuslookup[c] = _mm_set_epi32(0, 0, (255-c) | ((255-c) << 16), (255-c) | ((255-c) << 16)); + aminuslookup[c] = _mm_set_epi32(0, 0, (255 - c) | ((255 - c) << 16), (255 - c) | ((255 - c) << 16)); d[0] = (16 - _ds) * (16 - dt); - d[1] = _ds * (16 - dt); + d[1] = _ds * (16 - dt); d[2] = (16 - _ds) * dt; d[3] = _ds * dt; - bilinear_lookup[c*2] = _mm_set_epi32(d[1] | (d[1] << 16), d[1] | (d[1] << 16), d[0] | (d[0] << 16), d[0] | (d[0] << 16)); - bilinear_lookup[c*2 + 1] = _mm_set_epi32(d[3] | (d[3] << 16), d[3] | (d[3] << 16), d[2] | (d[2] << 16), d[2] | (d[2] << 16)); + bilinear_lookup[c * 2] = + _mm_set_epi32(d[1] | (d[1] << 16), d[1] | (d[1] << 16), d[0] | (d[0] << 16), d[0] | (d[0] << 16)); + bilinear_lookup[c * 2 + 1] = + _mm_set_epi32(d[3] | (d[3] << 16), d[3] | (d[3] << 16), d[2] | (d[2] << 16), d[2] | (d[2] << 16)); } alookup[256] = _mm_set_epi32(0, 0, 256 | (256 << 16), 256 | (256 << 16)); xmm_00_ff_w[0] = _mm_set_epi32(0, 0, 0, 0); xmm_00_ff_w[1] = _mm_set_epi32(0, 0, 0xff | (0xff << 16), 0xff | (0xff << 16)); } -void voodoo_codegen_close(voodoo_t *voodoo) -{ +void voodoo_codegen_close(voodoo_t *voodoo) { #if WIN64 VirtualFree(voodoo->codegen_data, 0, MEM_RELEASE); #else - munmap(voodoo->codegen_data, sizeof(voodoo_x86_data_t) * BLOCK_NUM*4); + munmap(voodoo->codegen_data, sizeof(voodoo_x86_data_t) * BLOCK_NUM * 4); #endif } - - #endif /* _VID_VOODOO_CODEGEN_X86_64_H_ */ diff --git a/includes/private/video/vid_voodoo_codegen_x86.h b/includes/private/video/vid_voodoo_codegen_x86.h index e6046807..ca3166a6 100644 --- a/includes/private/video/vid_voodoo_codegen_x86.h +++ b/includes/private/video/vid_voodoo_codegen_x86.h @@ -1,5 +1,5 @@ /*Registers : - + alphaMode fbzMode & 0x1f3fff fbzColorPath @@ -21,13 +21,12 @@ #include #define BLOCK_NUM 8 -#define BLOCK_MASK (BLOCK_NUM-1) +#define BLOCK_MASK (BLOCK_NUM - 1) #define BLOCK_SIZE 8192 #define LOD_MASK (LOD_TMIRROR_S | LOD_TMIRROR_T) -typedef struct voodoo_x86_data_t -{ +typedef struct voodoo_x86_data_t { uint8_t code_block[BLOCK_SIZE]; int xdir; uint32_t alphaMode; @@ -36,62 +35,60 @@ typedef struct voodoo_x86_data_t uint32_t fbzColorPath; uint32_t textureMode[2]; uint32_t tLOD[2]; - uint32_t trexInit1; + uint32_t trexInit1; int is_tiled; } voodoo_x86_data_t; static int last_block[4] = {0, 0}; static int next_block_to_write[4] = {0, 0}; -#define addbyte(val) \ - do { \ - code_block[block_pos++] = val; \ - if (block_pos >= BLOCK_SIZE) \ - fatal("Over!\n"); \ +#define addbyte(val) \ + do { \ + code_block[block_pos++] = val; \ + if (block_pos >= BLOCK_SIZE) \ + fatal("Over!\n"); \ } while (0) -#define addword(val) \ - do { \ - *(uint16_t *)&code_block[block_pos] = val; \ - block_pos += 2; \ - if (block_pos >= BLOCK_SIZE) \ - fatal("Over!\n"); \ +#define addword(val) \ + do { \ + *(uint16_t *)&code_block[block_pos] = val; \ + block_pos += 2; \ + if (block_pos >= BLOCK_SIZE) \ + fatal("Over!\n"); \ } while (0) -#define addlong(val) \ - do { \ - *(uint32_t *)&code_block[block_pos] = val; \ - block_pos += 4; \ - if (block_pos >= BLOCK_SIZE) \ - fatal("Over!\n"); \ +#define addlong(val) \ + do { \ + *(uint32_t *)&code_block[block_pos] = val; \ + block_pos += 4; \ + if (block_pos >= BLOCK_SIZE) \ + fatal("Over!\n"); \ } while (0) -#define addquad(val) \ - do { \ - *(uint64_t *)&code_block[block_pos] = val; \ - block_pos += 8; \ - if (block_pos >= BLOCK_SIZE) \ - fatal("Over!\n"); \ +#define addquad(val) \ + do { \ + *(uint64_t *)&code_block[block_pos] = val; \ + block_pos += 8; \ + if (block_pos >= BLOCK_SIZE) \ + fatal("Over!\n"); \ } while (0) - -static __m128i xmm_01_w;// = 0x0001000100010001ull; -static __m128i xmm_ff_w;// = 0x00ff00ff00ff00ffull; -static __m128i xmm_ff_b;// = 0x00000000ffffffffull; +static __m128i xmm_01_w; // = 0x0001000100010001ull; +static __m128i xmm_ff_w; // = 0x00ff00ff00ff00ffull; +static __m128i xmm_ff_b; // = 0x00000000ffffffffull; static uint32_t zero = 0; static double const_1_48 = (double)(1ull << 4); static __m128i alookup[257], aminuslookup[256]; -static __m128i minus_254;// = 0xff02ff02ff02ff02ull; -static __m128i bilinear_lookup[256*2]; +static __m128i minus_254; // = 0xff02ff02ff02ff02ull; +static __m128i bilinear_lookup[256 * 2]; static __m128i xmm_00_ff_w[2]; static uint32_t i_00_ff_w[2] = {0, 0xff}; -static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int block_pos, int tmu) -{ - if (params->textureMode[tmu] & 1) - { +static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, + int block_pos, int tmu) { + if (params->textureMode[tmu] & 1) { addbyte(0xdf); /*FILDq state->tmu0_w*/ addbyte(0xaf); addlong(tmu ? offsetof(voodoo_state_t, tmu1_w) : offsetof(voodoo_state_t, tmu0_w)); @@ -106,17 +103,17 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0xdf); /*FILDq state->tmu0_t*/ /*ST(0)=t, ST(1)=s, ST(2)=1/w*/ addbyte(0xaf); addlong(tmu ? offsetof(voodoo_state_t, tmu1_t) : offsetof(voodoo_state_t, tmu0_t)); - addbyte(0xd9); /*FXCH ST(1)*/ /*ST(0)=s, ST(1)=t, ST(2)=1/w*/ + addbyte(0xd9); /*FXCH ST(1)*/ /*ST(0)=s, ST(1)=t, ST(2)=1/w*/ addbyte(0xc9); - addbyte(0xd8); /*FMUL ST(2)*/ /*ST(0)=s/w, ST(1)=t, ST(2)=1/w*/ + addbyte(0xd8); /*FMUL ST(2)*/ /*ST(0)=s/w, ST(1)=t, ST(2)=1/w*/ addbyte(0xca); - addbyte(0xd9); /*FXCH ST(1)*/ /*ST(0)=t, ST(1)=s/w, ST(2)=1/w*/ + addbyte(0xd9); /*FXCH ST(1)*/ /*ST(0)=t, ST(1)=s/w, ST(2)=1/w*/ addbyte(0xc9); - addbyte(0xd8); /*FMUL ST(2)*/ /*ST(0)=t/w, ST(1)=s/w, ST(2)=1/w*/ + addbyte(0xd8); /*FMUL ST(2)*/ /*ST(0)=t/w, ST(1)=s/w, ST(2)=1/w*/ addbyte(0xca); - addbyte(0xd9); /*FXCH ST(2)*/ /*ST(0)=1/w, ST(1)=s/w, ST(2)=t/w*/ + addbyte(0xd9); /*FXCH ST(2)*/ /*ST(0)=1/w, ST(1)=s/w, ST(2)=t/w*/ addbyte(0xca); - addbyte(0xd9); /*FSTPs log_temp*/ /*ST(0)=s/w, ST(1)=t/w*/ + addbyte(0xd9); /*FSTPs log_temp*/ /*ST(0)=s/w, ST(1)=t/w*/ addbyte(0x9f); addlong(offsetof(voodoo_state_t, log_temp)); addbyte(0xdf); /*FSITPq state->tex_s*/ @@ -137,7 +134,7 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0x25); /*AND EAX, 0xff00*/ addlong(0xff00); addbyte(0x2d); /*SUB EAX, (127-44)<<8*/ - addlong((127-44+19) << 8); + addlong((127 - 44 + 19) << 8); addbyte(0x0f); /*MOVZX EBX, logtable[EBX]*/ addbyte(0xb6); addbyte(0x9b); @@ -173,9 +170,7 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0x89); /*MOV state->lod, EAX*/ addbyte(0x87); addlong(offsetof(voodoo_state_t, lod)); - } - else - { + } else { addbyte(0xf3); /*MOVQ XMM4, state->tmu0_s*/ addbyte(0x0f); addbyte(0x7e); @@ -208,7 +203,7 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0xd8); addbyte(0xc1); /*SHR EAX, 8*/ addbyte(0xe8); - addbyte(8); + addbyte(8); addbyte(0x66); /*MOVQ state->tex_s, XMM4*/ addbyte(0x0f); addbyte(0xd6); @@ -227,10 +222,8 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addlong(offsetof(voodoo_state_t, lod)); } /*EAX = state->lod*/ - if (params->fbzColorPath & FBZCP_TEXTURE_ENABLED) - { - if (voodoo->bilinear_enabled && (params->textureMode[tmu] & 6)) - { + if (params->fbzColorPath & FBZCP_TEXTURE_ENABLED) { + if (voodoo->bilinear_enabled && (params->textureMode[tmu] & 6)) { addbyte(0x8b); /*MOV ECX, state->tex_lod[tmu]*/ addbyte(0x8f); addlong(offsetof(voodoo_state_t, tex_lod[tmu])); @@ -251,8 +244,7 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0x8b); /*MOV EBX, state->tex_t[EDI]*/ addbyte(0x9f); addlong(offsetof(voodoo_state_t, tex_t)); - if (params->tLOD[tmu] & LOD_TMIRROR_S) - { + if (params->tLOD[tmu] & LOD_TMIRROR_S) { addbyte(0xa9); /*TEST EAX, 0x1000*/ addlong(0x1000); addbyte(0x74); /*JZ +*/ @@ -260,8 +252,7 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0xf7); /*NOT EAX*/ addbyte(0xd0); } - if (params->tLOD[tmu] & LOD_TMIRROR_T) - { + if (params->tLOD[tmu] & LOD_TMIRROR_T) { addbyte(0xf7); /*TEST EBX, 0x1000*/ addbyte(0xc3); addlong(0x1000); @@ -320,8 +311,7 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0xd1); addbyte(0x89); /*MOV EDX, EBX*/ addbyte(0xda); - if (!state->clamp_s[tmu]) - { + if (!state->clamp_s[tmu]) { addbyte(0x23); /*AND EAX, params->tex_w_mask[ESI]*/ addbyte(0x86); addlong(offsetof(voodoo_params_t, tex_w_mask[tmu])); @@ -329,8 +319,7 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0x83); /*ADD EDX, 1*/ addbyte(0xc2); addbyte(1); - if (state->clamp_t[tmu]) - { + if (state->clamp_t[tmu]) { addbyte(0x0f); /*CMOVS EDX, zero*/ addbyte(0x48); addbyte(0x15); @@ -355,9 +344,7 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0x47); addbyte(0x9e); addlong(offsetof(voodoo_params_t, tex_h_mask[tmu])); - } - else - { + } else { addbyte(0x23); /*AND EDX, params->tex_h_mask[ESI]*/ addbyte(0x96); addlong(offsetof(voodoo_params_t, tex_h_mask[tmu])); @@ -378,8 +365,7 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0x54); addbyte(0x95); addbyte(0); - if (state->clamp_s[tmu]) - { + if (state->clamp_s[tmu]) { addbyte(0x8b); /*MOV EBP, params->tex_w_mask[ESI]*/ addbyte(0xae); addlong(offsetof(voodoo_params_t, tex_w_mask[tmu])); @@ -393,17 +379,15 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0x05); addlong((uint32_t)&zero); addbyte(0x78); /*JS + - clamp on 0*/ - addbyte(2+3+2+ 5+5+2); + addbyte(2 + 3 + 2 + 5 + 5 + 2); addbyte(0x3b); /*CMP EAX, EBP*/ addbyte(0xc5); addbyte(0x0f); /*CMOVAE EAX, EBP*/ addbyte(0x43); addbyte(0xc5); addbyte(0x73); /*JAE + - clamp on +*/ - addbyte(5+5+2); - } - else - { + addbyte(5 + 5 + 2); + } else { addbyte(0x3b); /*CMP EAX, params->tex_w_mask[ESI] - is S at texture edge (ie will wrap/clamp)?*/ addbyte(0x86); addlong(offsetof(voodoo_params_t, tex_w_mask[tmu])); @@ -411,7 +395,7 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0xb7); addlong(offsetof(voodoo_state_t, ebp_store)); addbyte(0x74); /*JE +*/ - addbyte(5+5+2); + addbyte(5 + 5 + 2); } addbyte(0xf3); /*MOVQ XMM0, [EBX+EAX*4]*/ @@ -424,11 +408,10 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0x7e); addbyte(0x0c); addbyte(0x82); - - if (state->clamp_s[tmu]) - { + + if (state->clamp_s[tmu]) { addbyte(0xeb); /*JMP +*/ - addbyte(5+5+4+4); + addbyte(5 + 5 + 4 + 4); /*S clamped - the two S coordinates are the same*/ addbyte(0x66); /*MOVD XMM0, [EBX+EAX*4]*/ @@ -449,11 +432,9 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0x0f); addbyte(0x62); addbyte(0xc9); - } - else - { + } else { addbyte(0xeb); /*JMP +*/ - addbyte(5+5+5+5+6+6); + addbyte(5 + 5 + 5 + 5 + 6 + 6); /*S wrapped - the two S coordinates are not contiguous*/ addbyte(0x66); /*MOVD XMM0, [EBX+EAX*4]*/ @@ -498,7 +479,7 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0x0f); addbyte(0x60); addbyte(0xca); - + addbyte(0x81); /*ADD ESI, bilinear_lookup*/ addbyte(0xc6); addlong((uint32_t)bilinear_lookup); @@ -538,19 +519,17 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0x0f); addbyte(0x67); addbyte(0xc0); - + addbyte(0x8b); /*MOV ESI, [ESP+8]*/ addbyte(0x74); addbyte(0x24); - addbyte(8+16); /*CHECK!*/ + addbyte(8 + 16); /*CHECK!*/ addbyte(0x66); /*MOV EAX, XMM0*/ addbyte(0x0f); addbyte(0x7e); - addbyte(0xc0); - } - else - { + addbyte(0xc0); + } else { addbyte(0x8b); /*MOV ECX, state->tex_lod[tmu]*/ addbyte(0x8f); addlong(offsetof(voodoo_state_t, tex_lod[tmu])); @@ -574,8 +553,7 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0x8b); /*MOV EBX, state->tex_t[EDI]*/ addbyte(0x9f); addlong(offsetof(voodoo_state_t, tex_t)); - if (params->tLOD[tmu] & LOD_TMIRROR_S) - { + if (params->tLOD[tmu] & LOD_TMIRROR_S) { addbyte(0xa9); /*TEST EAX, 0x1000*/ addlong(0x1000); addbyte(0x74); /*JZ +*/ @@ -583,8 +561,7 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0xf7); /*NOT EAX*/ addbyte(0xd0); } - if (params->tLOD[tmu] & LOD_TMIRROR_T) - { + if (params->tLOD[tmu] & LOD_TMIRROR_T) { addbyte(0xf7); /*TEST EBX, 0x1000*/ addbyte(0xc3); addlong(0x1000); @@ -597,8 +574,7 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0xe8); addbyte(0xd3); /*SHR EBX, CL*/ addbyte(0xeb); - if (state->clamp_s[tmu]) - { + if (state->clamp_s[tmu]) { addbyte(0x85); /*TEST EAX, EAX*/ addbyte(0xc0); addbyte(0x0f); /*CMOVS EAX, zero*/ @@ -615,16 +591,13 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0x8e); addlong(offsetof(voodoo_params_t, tex_w_mask[tmu]) - 0x10); - } - else - { + } else { addbyte(0x23); /*AND EAX, params->tex_w_mask-0x10[ESI+ECX*4]*/ addbyte(0x84); addbyte(0x8e); addlong(offsetof(voodoo_params_t, tex_w_mask[tmu]) - 0x10); } - if (state->clamp_t[tmu]) - { + if (state->clamp_t[tmu]) { addbyte(0x85); /*TEST EBX, EBX*/ addbyte(0xdb); addbyte(0x0f); /*CMOVS EBX, zero*/ @@ -640,9 +613,7 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0x9c); addbyte(0x8e); addlong(offsetof(voodoo_params_t, tex_h_mask[tmu]) - 0x10); - } - else - { + } else { addbyte(0x23); /*AND EBX, params->tex_h_mask-0x10[ESI+ECX*4]*/ addbyte(0x9c); addbyte(0x8e); @@ -665,8 +636,8 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v return block_pos; } -static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int depthop) -{ +static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, + int depthop) { int block_pos = 0; int z_skip_pos = 0; int a_skip_pos = 0; @@ -674,40 +645,39 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo int depth_jump_pos = 0; int depth_jump_pos2 = 0; int loop_jump_pos = 0; -// xmm_01_w = (__m128i)0x0001000100010001ull; -// xmm_ff_w = (__m128i)0x00ff00ff00ff00ffull; -// xmm_ff_b = (__m128i)0x00000000ffffffffull; + // xmm_01_w = (__m128i)0x0001000100010001ull; + // xmm_ff_w = (__m128i)0x00ff00ff00ff00ffull; + // xmm_ff_b = (__m128i)0x00000000ffffffffull; xmm_01_w = _mm_set_epi32(0, 0, 0x00010001, 0x00010001); xmm_ff_w = _mm_set_epi32(0, 0, 0x00ff00ff, 0x00ff00ff); xmm_ff_b = _mm_set_epi32(0, 0, 0, 0x00ffffff); minus_254 = _mm_set_epi32(0, 0, 0xff02ff02, 0xff02ff02); -// *(uint64_t *)&const_1_48 = 0x45b0000000000000ull; -// block_pos = 0; -// voodoo_get_depth = &code_block[block_pos]; + // *(uint64_t *)&const_1_48 = 0x45b0000000000000ull; + // block_pos = 0; + // voodoo_get_depth = &code_block[block_pos]; /*W at (%esp+4) Z at (%esp+12) new_depth at (%esp+16)*/ -// if ((params->fbzMode & FBZ_DEPTH_ENABLE) && (depth_op == DEPTHOP_NEVER)) -// { -// addbyte(0xC3); /*RET*/ -// return; -// } + // if ((params->fbzMode & FBZ_DEPTH_ENABLE) && (depth_op == DEPTHOP_NEVER)) + // { + // addbyte(0xC3); /*RET*/ + // return; + // } addbyte(0x55); /*PUSH EBP*/ addbyte(0x57); /*PUSH EDI*/ addbyte(0x56); /*PUSH ESI*/ addbyte(0x53); /*PUSH EBX*/ - + addbyte(0x8b); /*MOV EDI, [ESP+4]*/ addbyte(0x7c); addbyte(0x24); - addbyte(4+16); + addbyte(4 + 16); loop_jump_pos = block_pos; addbyte(0x8b); /*MOV ESI, [ESP+8]*/ addbyte(0x74); addbyte(0x24); - addbyte(8+16); - if (params->col_tiled || params->aux_tiled) - { + addbyte(8 + 16); + if (params->col_tiled || params->aux_tiled) { addbyte(0x8b); /*MOV EAX, state->x[EDI]*/ addbyte(0x87); addlong(offsetof(voodoo_state_t, x)); @@ -733,19 +703,19 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xef); addbyte(0xd2); - if ((params->fbzMode & FBZ_W_BUFFER) || (params->fogMode & (FOG_ENABLE|FOG_CONSTANT|FOG_Z|FOG_ALPHA)) == FOG_ENABLE) - { + if ((params->fbzMode & FBZ_W_BUFFER) || + (params->fogMode & (FOG_ENABLE | FOG_CONSTANT | FOG_Z | FOG_ALPHA)) == FOG_ENABLE) { addbyte(0xb8); /*MOV new_depth, 0*/ addlong(0); addbyte(0x66); /*TEST w+4, 0xffff*/ addbyte(0xf7); addbyte(0x87); - addlong(offsetof(voodoo_state_t, w)+4); + addlong(offsetof(voodoo_state_t, w) + 4); addword(0xffff); addbyte(0x75); /*JNZ got_depth*/ depth_jump_pos = block_pos; addbyte(0); -// addbyte(4+5+2+3+2+5+5+3+2+2+2+/*3+*/3+2+6+4+5+2+3); + // addbyte(4+5+2+3+2+5+5+3+2+2+2+/*3+*/3+2+6+4+5+2+3); addbyte(0x8b); /*MOV EDX, w*/ addbyte(0x97); addlong(offsetof(voodoo_state_t, w)); @@ -759,7 +729,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x74); /*JZ got_depth*/ depth_jump_pos2 = block_pos; addbyte(0); -// addbyte(5+5+3+2+2+2+/*3+*/3+2+6+4+5+2+3); + // addbyte(5+5+3+2+2+2+/*3+*/3+2+6+4+5+2+3); addbyte(0xb9); /*MOV ECX, 19*/ addlong(19); addbyte(0x0f); /*BSR EAX, EDX*/ @@ -797,16 +767,14 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo *(uint8_t *)&code_block[depth_jump_pos] = (block_pos - depth_jump_pos) - 1; if (depth_jump_pos) *(uint8_t *)&code_block[depth_jump_pos2] = (block_pos - depth_jump_pos2) - 1; - - if ((params->fogMode & (FOG_ENABLE|FOG_CONSTANT|FOG_Z|FOG_ALPHA)) == FOG_ENABLE) - { + + if ((params->fogMode & (FOG_ENABLE | FOG_CONSTANT | FOG_Z | FOG_ALPHA)) == FOG_ENABLE) { addbyte(0x89); /*MOV state->w_depth[EDI], EAX*/ addbyte(0x87); addlong(offsetof(voodoo_state_t, w_depth)); } } - if (!(params->fbzMode & FBZ_W_BUFFER)) - { + if (!(params->fbzMode & FBZ_W_BUFFER)) { addbyte(0x8b); /*MOV EAX, z*/ addbyte(0x87); addlong(offsetof(voodoo_state_t, z)); @@ -826,15 +794,13 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x47); addbyte(0xc3); } - - if (params->fbzMode & FBZ_DEPTH_BIAS) - { + + if (params->fbzMode & FBZ_DEPTH_BIAS) { addbyte(0x0f); /*MOVSX EDX, params->zaColor[ESI]*/ addbyte(0xbf); addbyte(0x96); - addlong(offsetof(voodoo_params_t, zaColor)); - if (params->fbzMode & FBZ_W_BUFFER) - { + addlong(offsetof(voodoo_params_t, zaColor)); + if (params->fbzMode & FBZ_W_BUFFER) { addbyte(0xbb); /*MOV EBX, 0xffff*/ addlong(0xffff); addbyte(0x31); /*XOR ECX, ECX*/ @@ -856,23 +822,21 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x87); addlong(offsetof(voodoo_state_t, new_depth)); - if ((params->fbzMode & FBZ_DEPTH_ENABLE) && (depthop != DEPTHOP_ALWAYS) && (depthop != DEPTHOP_NEVER)) - { + if ((params->fbzMode & FBZ_DEPTH_ENABLE) && (depthop != DEPTHOP_ALWAYS) && (depthop != DEPTHOP_NEVER)) { addbyte(0x8b); /*MOV EBX, state->x[EDI]*/ addbyte(0x9f); if (params->aux_tiled) addlong(offsetof(voodoo_state_t, x_tiled)); else addlong(offsetof(voodoo_state_t, x)); - addbyte(0x8b);/*MOV ECX, aux_mem[EDI]*/ + addbyte(0x8b); /*MOV ECX, aux_mem[EDI]*/ addbyte(0x8f); addlong(offsetof(voodoo_state_t, aux_mem)); addbyte(0x0f); /*MOVZX EBX, [ECX+EBX*2]*/ addbyte(0xb7); addbyte(0x1c); addbyte(0x59); - if (params->fbzMode & FBZ_DEPTH_SOURCE) - { + if (params->fbzMode & FBZ_DEPTH_SOURCE) { addbyte(0x0f); /*MOVZX EAX, zaColor[ESI]*/ addbyte(0xb7); addbyte(0x86); @@ -880,75 +844,59 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo } addbyte(0x39); /*CMP EAX, EBX*/ addbyte(0xd8); - if (depthop == DEPTHOP_LESSTHAN) - { + if (depthop == DEPTHOP_LESSTHAN) { addbyte(0x0f); /*JAE skip*/ addbyte(0x83); z_skip_pos = block_pos; addlong(0); - } - else if (depthop == DEPTHOP_EQUAL) - { + } else if (depthop == DEPTHOP_EQUAL) { addbyte(0x0f); /*JNE skip*/ addbyte(0x85); z_skip_pos = block_pos; addlong(0); - } - else if (depthop == DEPTHOP_LESSTHANEQUAL) - { + } else if (depthop == DEPTHOP_LESSTHANEQUAL) { addbyte(0x0f); /*JA skip*/ addbyte(0x87); z_skip_pos = block_pos; addlong(0); - } - else if (depthop == DEPTHOP_GREATERTHAN) - { + } else if (depthop == DEPTHOP_GREATERTHAN) { addbyte(0x0f); /*JBE skip*/ addbyte(0x86); z_skip_pos = block_pos; addlong(0); - } - else if (depthop == DEPTHOP_NOTEQUAL) - { + } else if (depthop == DEPTHOP_NOTEQUAL) { addbyte(0x0f); /*JE skip*/ addbyte(0x84); z_skip_pos = block_pos; addlong(0); - } - else if (depthop == DEPTHOP_GREATERTHANEQUAL) - { + } else if (depthop == DEPTHOP_GREATERTHANEQUAL) { addbyte(0x0f); /*JB skip*/ addbyte(0x82); z_skip_pos = block_pos; addlong(0); - } - else + } else fatal("Bad depth_op\n"); - } - else if ((params->fbzMode & FBZ_DEPTH_ENABLE) && (depthop == DEPTHOP_NEVER)) - { + } else if ((params->fbzMode & FBZ_DEPTH_ENABLE) && (depthop == DEPTHOP_NEVER)) { addbyte(0xC3); /*RET*/ -// addbyte(0x30); /*XOR EAX, EAX*/ -// addbyte(0xc0); + // addbyte(0x30); /*XOR EAX, EAX*/ + // addbyte(0xc0); } -// else -// { -// addbyte(0xb0); /*MOV AL, 1*/ -// addbyte(1); -// } + // else + // { + // addbyte(0xb0); /*MOV AL, 1*/ + // addbyte(1); + // } - -// voodoo_combine = &code_block[block_pos]; + // voodoo_combine = &code_block[block_pos]; /*XMM0 = colour*/ /*XMM2 = 0 (for unpacking*/ - + /*EDI = state, ESI = params*/ - if ((params->textureMode[0] & TEXTUREMODE_LOCAL_MASK) == TEXTUREMODE_LOCAL || !voodoo->dual_tmus) - { + if ((params->textureMode[0] & TEXTUREMODE_LOCAL_MASK) == TEXTUREMODE_LOCAL || !voodoo->dual_tmus) { /*TMU0 only sampling local colour or only one TMU, only sample TMU0*/ block_pos = codegen_texture_fetch(code_block, voodoo, params, state, block_pos, 0); - + addbyte(0x66); /*MOVD XMM0, EAX*/ addbyte(0x0f); addbyte(0x6e); @@ -959,12 +907,10 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x89); /*MOV state->tex_a[EDI], EAX*/ addbyte(0x87); addlong(offsetof(voodoo_state_t, tex_a)); - } - else if ((params->textureMode[0] & TEXTUREMODE_MASK) == TEXTUREMODE_PASSTHROUGH) - { + } else if ((params->textureMode[0] & TEXTUREMODE_MASK) == TEXTUREMODE_PASSTHROUGH) { /*TMU0 in pass-through mode, only sample TMU1*/ block_pos = codegen_texture_fetch(code_block, voodoo, params, state, block_pos, 1); - + addbyte(0x66); /*MOVD XMM0, EAX*/ addbyte(0x0f); addbyte(0x6e); @@ -975,40 +921,31 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x89); /*MOV state->tex_a[EDI], EAX*/ addbyte(0x87); addlong(offsetof(voodoo_state_t, tex_a)); - } - else - { + } else { block_pos = codegen_texture_fetch(code_block, voodoo, params, state, block_pos, 1); addbyte(0x66); /*MOVD XMM3, EAX*/ addbyte(0x0f); addbyte(0x6e); addbyte(0xd8); - if ((params->textureMode[1] & TEXTUREMODE_TRILINEAR) && tc_sub_clocal_1) - { + if ((params->textureMode[1] & TEXTUREMODE_TRILINEAR) && tc_sub_clocal_1) { addbyte(0x8b); /*MOV EAX, state->lod*/ addbyte(0x87); addlong(offsetof(voodoo_state_t, lod)); - if (!tc_reverse_blend_1) - { + if (!tc_reverse_blend_1) { addbyte(0xbb); /*MOV EBX, 1*/ addlong(1); - } - else - { + } else { addbyte(0x31); /*XOR EBX, EBX*/ addbyte(0xdb); } addbyte(0x83); /*AND EAX, 1*/ addbyte(0xe0); addbyte(1); - if (!tca_reverse_blend_1) - { + if (!tca_reverse_blend_1) { addbyte(0xb9); /*MOV ECX, 1*/ addlong(1); - } - else - { + } else { addbyte(0x31); /*XOR ECX, ECX*/ addbyte(0xc9); } @@ -1025,36 +962,34 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x0f); addbyte(0x60); addbyte(0xda); - if (tc_sub_clocal_1) - { - switch (tc_mselect_1) - { - case TC_MSELECT_ZERO: + if (tc_sub_clocal_1) { + switch (tc_mselect_1) { + case TC_MSELECT_ZERO: addbyte(0x66); /*PXOR XMM0, XMM0*/ addbyte(0x0f); addbyte(0xef); addbyte(0xc0); break; - case TC_MSELECT_CLOCAL: + case TC_MSELECT_CLOCAL: addbyte(0xf3); /*MOVQ XMM0, XMM3*/ addbyte(0x0f); addbyte(0x7e); addbyte(0xc3); break; - case TC_MSELECT_AOTHER: + case TC_MSELECT_AOTHER: addbyte(0x66); /*PXOR XMM0, XMM0*/ addbyte(0x0f); addbyte(0xef); addbyte(0xc0); break; - case TC_MSELECT_ALOCAL: + case TC_MSELECT_ALOCAL: addbyte(0xf2); /*PSHUFLW XMM0, XMM3, 0xff*/ addbyte(0x0f); addbyte(0x70); addbyte(0xc3); addbyte(0xff); break; - case TC_MSELECT_DETAIL: + case TC_MSELECT_DETAIL: addbyte(0xb8); /*MOV EAX, params->detail_bias[1]*/ addlong(params->detail_bias[1]); addbyte(0x2b); /*SUB EAX, state->lod*/ @@ -1080,7 +1015,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xc0); addbyte(0); break; - case TC_MSELECT_LOD_FRAC: + case TC_MSELECT_LOD_FRAC: addbyte(0x66); /*MOVD XMM0, state->lod_frac[1]*/ addbyte(0x0f); addbyte(0x6e); @@ -1093,16 +1028,13 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0); break; } - if (params->textureMode[1] & TEXTUREMODE_TRILINEAR) - { + if (params->textureMode[1] & TEXTUREMODE_TRILINEAR) { addbyte(0x66); /*PXOR XMM0, xmm_00_ff_w[EBX]*/ addbyte(0x0f); addbyte(0xef); addbyte(0x83); addlong((uint32_t)&xmm_00_ff_w[0]); - } - else if (!tc_reverse_blend_1) - { + } else if (!tc_reverse_blend_1) { addbyte(0x66); /*PXOR XMM0, xmm_ff_w*/ addbyte(0x0f); addbyte(0xef); @@ -1147,15 +1079,12 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x0f); addbyte(0xf9); addbyte(0xc8); - if (tc_add_clocal_1) - { + if (tc_add_clocal_1) { addbyte(0x66); /*PADDW XMM1, XMM3*/ addbyte(0x0f); addbyte(0xfd); addbyte(0xcb); - } - else if (tc_add_alocal_1) - { + } else if (tc_add_alocal_1) { addbyte(0xf2); /*PSHUFLW XMM0, XMM3, 0xff*/ addbyte(0x0f); addbyte(0x70); @@ -1174,8 +1103,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x0f); addbyte(0x67); addbyte(0xdb); - if (tca_sub_clocal_1) - { + if (tca_sub_clocal_1) { addbyte(0x66); /*MOVD EBX, XMM3*/ addbyte(0x0f); addbyte(0x7e); @@ -1187,30 +1115,28 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xda); } - if (tca_sub_clocal_1) - { + if (tca_sub_clocal_1) { addbyte(0xc1); /*SHR EBX, 24*/ addbyte(0xeb); addbyte(24); - switch (tca_mselect_1) - { - case TCA_MSELECT_ZERO: + switch (tca_mselect_1) { + case TCA_MSELECT_ZERO: addbyte(0x31); /*XOR EAX, EAX*/ addbyte(0xc0); break; - case TCA_MSELECT_CLOCAL: + case TCA_MSELECT_CLOCAL: addbyte(0x89); /*MOV EAX, EBX*/ addbyte(0xd8); break; - case TCA_MSELECT_AOTHER: + case TCA_MSELECT_AOTHER: addbyte(0x31); /*XOR EAX, EAX*/ addbyte(0xc0); break; - case TCA_MSELECT_ALOCAL: + case TCA_MSELECT_ALOCAL: addbyte(0x89); /*MOV EAX, EBX*/ addbyte(0xd8); break; - case TCA_MSELECT_DETAIL: + case TCA_MSELECT_DETAIL: addbyte(0xb8); /*MOV EAX, params->detail_bias[1]*/ addlong(params->detail_bias[1]); addbyte(0x2b); /*SUB EAX, state->lod*/ @@ -1227,21 +1153,18 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x4d); addbyte(0xc2); break; - case TCA_MSELECT_LOD_FRAC: + case TCA_MSELECT_LOD_FRAC: addbyte(0x8b); /*MOV EAX, state->lod_frac[1]*/ addbyte(0x87); addlong(offsetof(voodoo_state_t, lod_frac[1])); break; } - if (params->textureMode[1] & TEXTUREMODE_TRILINEAR) - { + if (params->textureMode[1] & TEXTUREMODE_TRILINEAR) { addbyte(0x33); /*XOR EAX, i_00_ff_w[ECX*4]*/ addbyte(0x04); addbyte(0x8d); addlong((uint32_t)i_00_ff_w); - } - else if (!tc_reverse_blend_1) - { + } else if (!tc_reverse_blend_1) { addbyte(0x35); /*XOR EAX, 0xff*/ addlong(0xff); } @@ -1258,8 +1181,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xc1); /*SAR EAX, 8*/ addbyte(0xf8); addbyte(8); - if (tca_add_clocal_1 || tca_add_alocal_1) - { + if (tca_add_clocal_1 || tca_add_alocal_1) { addbyte(0x01); /*ADD EAX, EBX*/ addbyte(0xd8); } @@ -1274,7 +1196,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xd8); addbyte(3); } - + block_pos = codegen_texture_fetch(code_block, voodoo, params, state, block_pos, 0); addbyte(0x66); /*MOVD XMM0, EAX*/ @@ -1285,32 +1207,25 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x0f); addbyte(0x6e); addbyte(0xf8); - - if (params->textureMode[0] & TEXTUREMODE_TRILINEAR) - { + + if (params->textureMode[0] & TEXTUREMODE_TRILINEAR) { addbyte(0x8b); /*MOV EAX, state->lod*/ addbyte(0x87); addlong(offsetof(voodoo_state_t, lod)); - if (!tc_reverse_blend) - { + if (!tc_reverse_blend) { addbyte(0xbb); /*MOV EBX, 1*/ addlong(1); - } - else - { + } else { addbyte(0x31); /*XOR EBX, EBX*/ addbyte(0xdb); } addbyte(0x83); /*AND EAX, 1*/ addbyte(0xe0); addbyte(1); - if (!tca_reverse_blend) - { + if (!tca_reverse_blend) { addbyte(0xb9); /*MOV ECX, 1*/ addlong(1); - } - else - { + } else { addbyte(0x31); /*XOR ECX, ECX*/ addbyte(0xc9); } @@ -1330,57 +1245,52 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x0f); addbyte(0x60); addbyte(0xc2); - if (tc_zero_other) - { + if (tc_zero_other) { addbyte(0x66); /*PXOR XMM1, XMM1*/ addbyte(0x0f); addbyte(0xef); addbyte(0xc9); - } - else - { + } else { addbyte(0xf3); /*MOV XMM1, XMM3*/ addbyte(0x0f); addbyte(0x7e); addbyte(0xcb); } - if (tc_sub_clocal) - { + if (tc_sub_clocal) { addbyte(0x66); /*PSUBW XMM1, XMM0*/ addbyte(0x0f); addbyte(0xf9); addbyte(0xc8); } - switch (tc_mselect) - { - case TC_MSELECT_ZERO: + switch (tc_mselect) { + case TC_MSELECT_ZERO: addbyte(0x66); /*PXOR XMM4, XMM4*/ addbyte(0x0f); addbyte(0xef); addbyte(0xe4); break; - case TC_MSELECT_CLOCAL: + case TC_MSELECT_CLOCAL: addbyte(0xf3); /*MOV XMM4, XMM0*/ addbyte(0x0f); addbyte(0x7e); addbyte(0xe0); break; - case TC_MSELECT_AOTHER: + case TC_MSELECT_AOTHER: addbyte(0xf2); /*PSHUFLW XMM4, XMM3, 3, 3, 3, 3*/ addbyte(0x0f); addbyte(0x70); addbyte(0xe3); addbyte(0xff); break; - case TC_MSELECT_ALOCAL: + case TC_MSELECT_ALOCAL: addbyte(0xf2); /*PSHUFLW XMM4, XMM0, 3, 3, 3, 3*/ addbyte(0x0f); addbyte(0x70); addbyte(0xe0); addbyte(0xff); break; - case TC_MSELECT_DETAIL: + case TC_MSELECT_DETAIL: addbyte(0xb8); /*MOV EAX, params->detail_bias[0]*/ addlong(params->detail_bias[0]); addbyte(0x2b); /*SUB EAX, state->lod*/ @@ -1406,7 +1316,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xe4); addbyte(0); break; - case TC_MSELECT_LOD_FRAC: + case TC_MSELECT_LOD_FRAC: addbyte(0x66); /*MOVD XMM0, state->lod_frac[0]*/ addbyte(0x0f); addbyte(0x6e); @@ -1419,16 +1329,13 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0); break; } - if (params->textureMode[0] & TEXTUREMODE_TRILINEAR) - { + if (params->textureMode[0] & TEXTUREMODE_TRILINEAR) { addbyte(0x66); /*PXOR XMM4, xmm_00_ff_w[EBX]*/ addbyte(0x0f); addbyte(0xef); addbyte(0xa3); addlong((uint32_t)&xmm_00_ff_w[0]); - } - else if (!tc_reverse_blend) - { + } else if (!tc_reverse_blend) { addbyte(0x66); /*PXOR XMM4, FF*/ addbyte(0x0f); addbyte(0xef); @@ -1449,8 +1356,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xd5); addbyte(0xcc); - if (tca_sub_clocal) - { + if (tca_sub_clocal) { addbyte(0x66); /*MOV EBX, XMM7*/ addbyte(0x0f); addbyte(0x7e); @@ -1475,22 +1381,18 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x6b); addbyte(0xc9); - if (tca_sub_clocal) - { + if (tca_sub_clocal) { addbyte(0xc1); /*SHR EBX, 24*/ addbyte(0xeb); addbyte(24); } - - if (tc_add_clocal) - { + + if (tc_add_clocal) { addbyte(0x66); /*PADDW XMM1, XMM0*/ addbyte(0x0f); addbyte(0xfd); addbyte(0xc8); - } - else if (tc_add_alocal) - { + } else if (tc_add_alocal) { addbyte(0xf2); /*PSHUFLW XMM4, XMM0, 3, 3, 3, 3*/ addbyte(0x0f); addbyte(0x70); @@ -1501,7 +1403,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xfd); addbyte(0xcc); } - + addbyte(0x66); /*PACKUSWB XMM0, XMM0*/ addbyte(0x0f); addbyte(0x67); @@ -1514,22 +1416,18 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x0f); addbyte(0x67); addbyte(0xc9); - if (tc_invert_output) - { + if (tc_invert_output) { addbyte(0x66); /*PXOR XMM1, FF*/ addbyte(0x0f); addbyte(0xef); addbyte(0x0d); addlong((uint32_t)&xmm_ff_b); } - - if (tca_zero_other) - { + + if (tca_zero_other) { addbyte(0x31); /*XOR EAX, EAX*/ addbyte(0xc0); - } - else - { + } else { addbyte(0x66); /*MOV EAX, XMM3*/ addbyte(0x0f); addbyte(0x7e); @@ -1538,18 +1436,16 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xe8); addbyte(24); } - if (tca_sub_clocal) - { + if (tca_sub_clocal) { addbyte(0x29); /*SUB EAX, EBX*/ addbyte(0xd8); } - switch (tca_mselect) - { - case TCA_MSELECT_ZERO: + switch (tca_mselect) { + case TCA_MSELECT_ZERO: addbyte(0x31); /*XOR EBX, EBX*/ addbyte(0xdb); break; - case TCA_MSELECT_CLOCAL: + case TCA_MSELECT_CLOCAL: addbyte(0x66); /*MOV EBX, XMM7*/ addbyte(0x0f); addbyte(0x7e); @@ -1558,7 +1454,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xeb); addbyte(24); break; - case TCA_MSELECT_AOTHER: + case TCA_MSELECT_AOTHER: addbyte(0x66); /*MOV EBX, XMM3*/ addbyte(0x0f); addbyte(0x7e); @@ -1567,7 +1463,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xeb); addbyte(24); break; - case TCA_MSELECT_ALOCAL: + case TCA_MSELECT_ALOCAL: addbyte(0x66); /*MOV EBX, XMM7*/ addbyte(0x0f); addbyte(0x7e); @@ -1576,7 +1472,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xeb); addbyte(24); break; - case TCA_MSELECT_DETAIL: + case TCA_MSELECT_DETAIL: addbyte(0xbb); /*MOV EBX, params->detail_bias[1]*/ addlong(params->detail_bias[1]); addbyte(0x2b); /*SUB EBX, state->lod*/ @@ -1593,21 +1489,18 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x4d); addbyte(0xda); break; - case TCA_MSELECT_LOD_FRAC: + case TCA_MSELECT_LOD_FRAC: addbyte(0x8b); /*MOV EBX, state->lod_frac[0]*/ addbyte(0x9f); addlong(offsetof(voodoo_state_t, lod_frac[0])); break; } - if (params->textureMode[0] & TEXTUREMODE_TRILINEAR) - { + if (params->textureMode[0] & TEXTUREMODE_TRILINEAR) { addbyte(0x33); /*XOR EBX, i_00_ff_w[ECX*4]*/ addbyte(0x1c); addbyte(0x8d); addlong((uint32_t)i_00_ff_w); - } - else if (!tca_reverse_blend) - { + } else if (!tca_reverse_blend) { addbyte(0x81); /*XOR EBX, 0xFF*/ addbyte(0xf3); addlong(0xff); @@ -1624,8 +1517,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xc1); /*SAR EAX, 8*/ addbyte(0xf8); addbyte(8); - if (tca_add_clocal || tca_add_alocal) - { + if (tca_add_clocal || tca_add_alocal) { addbyte(0x66); /*MOV EBX, XMM7*/ addbyte(0x0f); addbyte(0x7e); @@ -1646,8 +1538,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x0f); /*CMOVA EAX, EDX*/ addbyte(0x47); addbyte(0xc2); - if (tca_invert_output) - { + if (tca_invert_output) { addbyte(0x35); /*XOR EAX, 0xff*/ addlong(0xff); } @@ -1661,19 +1552,16 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x7e); addbyte(0xc1); } - if (cc_mselect == CC_MSELECT_TEXRGB) - { + if (cc_mselect == CC_MSELECT_TEXRGB) { addbyte(0xf3); /*MOVD XMM4, XMM0*/ addbyte(0x0f); addbyte(0x7e); addbyte(0xe0); } - if ((params->fbzMode & FBZ_CHROMAKEY)) - { - switch (_rgb_sel) - { - case CC_LOCALSELECT_ITER_RGB: + if ((params->fbzMode & FBZ_CHROMAKEY)) { + switch (_rgb_sel) { + case CC_LOCALSELECT_ITER_RGB: addbyte(0xf3); /*MOVDQU XMM0, ib*/ /* ir, ig and ib must be in same dqword!*/ addbyte(0x0f); addbyte(0x6f); @@ -1697,12 +1585,12 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x7e); addbyte(0xc0); break; - case CC_LOCALSELECT_COLOR1: + case CC_LOCALSELECT_COLOR1: addbyte(0x8b); /*MOV EAX, params->color1[ESI]*/ addbyte(0x86); addlong(offsetof(voodoo_params_t, color1)); break; - case CC_LOCALSELECT_TEX: + case CC_LOCALSELECT_TEX: addbyte(0x66); /*MOVD EAX, XMM0*/ addbyte(0x0f); addbyte(0x7e); @@ -1723,8 +1611,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addlong(0); } - if (voodoo->trexInit1[0] & (1 << 18)) - { + if (voodoo->trexInit1[0] & (1 << 18)) { addbyte(0xb8); /*MOV EAX, tmuConfig*/ addlong(voodoo->tmuConfig); addbyte(0x66); /*MOVD XMM0, EAX*/ @@ -1733,12 +1620,12 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xc0); } - if ((params->alphaMode & ((1 << 0) | (1 << 4))) || (!(cc_mselect == 0 && cc_reverse_blend == 0) && (cc_mselect == CC_MSELECT_AOTHER || cc_mselect == CC_MSELECT_ALOCAL))) - { + if ((params->alphaMode & ((1 << 0) | (1 << 4))) || + (!(cc_mselect == 0 && cc_reverse_blend == 0) && + (cc_mselect == CC_MSELECT_AOTHER || cc_mselect == CC_MSELECT_ALOCAL))) { /*EBX = a_other*/ - switch (a_sel) - { - case A_SEL_ITER_A: + switch (a_sel) { + case A_SEL_ITER_A: addbyte(0x8b); /*MOV EBX, state->ia*/ addbyte(0x9f); addlong(offsetof(voodoo_state_t, ia)); @@ -1758,41 +1645,37 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x47); addbyte(0xda); break; - case A_SEL_TEX: + case A_SEL_TEX: addbyte(0x8b); /*MOV EBX, state->tex_a*/ addbyte(0x9f); addlong(offsetof(voodoo_state_t, tex_a)); break; - case A_SEL_COLOR1: + case A_SEL_COLOR1: addbyte(0x0f); /*MOVZX EBX, params->color1+3*/ addbyte(0xb6); addbyte(0x9e); - addlong(offsetof(voodoo_params_t, color1)+3); + addlong(offsetof(voodoo_params_t, color1) + 3); break; - default: + default: addbyte(0x31); /*XOR EBX, EBX*/ addbyte(0xdb); break; } /*ECX = a_local*/ - switch (cca_localselect) - { - case CCA_LOCALSELECT_ITER_A: - if (a_sel == A_SEL_ITER_A) - { + switch (cca_localselect) { + case CCA_LOCALSELECT_ITER_A: + if (a_sel == A_SEL_ITER_A) { addbyte(0x89); /*MOV ECX, EBX*/ addbyte(0xd9); - } - else - { + } else { addbyte(0x8b); /*MOV ECX, state->ia*/ addbyte(0x8f); addlong(offsetof(voodoo_state_t, ia)); addbyte(0x31); /*XOR EAX, EAX*/ - addbyte(0xc0); + addbyte(0xc0); addbyte(0xba); /*MOV EDX, 0xff*/ addlong(0xff); - addbyte(0xc1);/*SAR ECX, 12*/ + addbyte(0xc1); /*SAR ECX, 12*/ addbyte(0xf9); addbyte(12); addbyte(0x0f); /*CMOVS ECX, EAX*/ @@ -1805,24 +1688,23 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xca); } break; - case CCA_LOCALSELECT_COLOR0: + case CCA_LOCALSELECT_COLOR0: addbyte(0x0f); /*MOVZX ECX, params->color0+3*/ addbyte(0xb6); addbyte(0x8e); - addlong(offsetof(voodoo_params_t, color0)+3); + addlong(offsetof(voodoo_params_t, color0) + 3); break; - case CCA_LOCALSELECT_ITER_Z: + case CCA_LOCALSELECT_ITER_Z: addbyte(0x8b); /*MOV ECX, state->z*/ addbyte(0x8f); addlong(offsetof(voodoo_state_t, z)); - if (a_sel != A_SEL_ITER_A) - { + if (a_sel != A_SEL_ITER_A) { addbyte(0x31); /*XOR EAX, EAX*/ - addbyte(0xc0); + addbyte(0xc0); addbyte(0xba); /*MOV EDX, 0xff*/ addlong(0xff); } - addbyte(0xc1);/*SAR ECX, 20*/ + addbyte(0xc1); /*SAR ECX, 20*/ addbyte(0xf9); addbyte(20); addbyte(0x0f); /*CMOVS ECX, EAX*/ @@ -1834,46 +1716,37 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x47); addbyte(0xca); break; - - default: + + default: addbyte(0xb9); /*MOV ECX, 0xff*/ addlong(0xff); break; } - if (cca_zero_other) - { + if (cca_zero_other) { addbyte(0x31); /*XOR EDX, EDX*/ addbyte(0xd2); - } - else - { + } else { addbyte(0x89); /*MOV EDX, EBX*/ addbyte(0xda); } - - if (cca_sub_clocal) - { + + if (cca_sub_clocal) { addbyte(0x29); /*SUB EDX, ECX*/ addbyte(0xca); } } - if (cc_sub_clocal || cc_mselect == 1 || cc_add == 1) - { + if (cc_sub_clocal || cc_mselect == 1 || cc_add == 1) { /*XMM1 = local*/ - if (!cc_localselect_override) - { - if (cc_localselect) - { + if (!cc_localselect_override) { + if (cc_localselect) { addbyte(0x66); /*MOVD XMM1, params->color0*/ addbyte(0x0f); addbyte(0x6e); addbyte(0x8e); addlong(offsetof(voodoo_params_t, color0)); - } - else - { + } else { addbyte(0xf3); /*MOVDQU XMM1, ib*/ /* ir, ig and ib must be in same dqword!*/ addbyte(0x0f); addbyte(0x6f); @@ -1893,51 +1766,47 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x67); addbyte(0xc9); } - } - else - { + } else { addbyte(0xf6); /*TEST state->tex_a, 0x80*/ addbyte(0x87); addlong(offsetof(voodoo_state_t, tex_a)); addbyte(0x80); - addbyte(0x74);/*JZ !cc_localselect*/ - addbyte(8+2); - addbyte(0x66); /*MOVD XMM1, params->color0*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0x8e); - addlong(offsetof(voodoo_params_t, color0)); - addbyte(0xeb); /*JMP +*/ - addbyte(8+5+4+4); + addbyte(0x74); /*JZ !cc_localselect*/ + addbyte(8 + 2); + addbyte(0x66); /*MOVD XMM1, params->color0*/ + addbyte(0x0f); + addbyte(0x6e); + addbyte(0x8e); + addlong(offsetof(voodoo_params_t, color0)); + addbyte(0xeb); /*JMP +*/ + addbyte(8 + 5 + 4 + 4); /*!cc_localselect:*/ - addbyte(0xf3); /*MOVDQU XMM1, ib*/ /* ir, ig and ib must be in same dqword!*/ - addbyte(0x0f); - addbyte(0x6f); - addbyte(0x8f); - addlong(offsetof(voodoo_state_t, ib)); - addbyte(0x66); /*PSRAD XMM1, 12*/ - addbyte(0x0f); - addbyte(0x72); - addbyte(0xe1); - addbyte(12); - addbyte(0x66); /*PACKSSDW XMM1, XMM1*/ - addbyte(0x0f); - addbyte(0x6b); - addbyte(0xc9); - addbyte(0x66); /*PACKUSWB XMM1, XMM1*/ - addbyte(0x0f); - addbyte(0x67); - addbyte(0xc9); + addbyte(0xf3); /*MOVDQU XMM1, ib*/ /* ir, ig and ib must be in same dqword!*/ + addbyte(0x0f); + addbyte(0x6f); + addbyte(0x8f); + addlong(offsetof(voodoo_state_t, ib)); + addbyte(0x66); /*PSRAD XMM1, 12*/ + addbyte(0x0f); + addbyte(0x72); + addbyte(0xe1); + addbyte(12); + addbyte(0x66); /*PACKSSDW XMM1, XMM1*/ + addbyte(0x0f); + addbyte(0x6b); + addbyte(0xc9); + addbyte(0x66); /*PACKUSWB XMM1, XMM1*/ + addbyte(0x0f); + addbyte(0x67); + addbyte(0xc9); } addbyte(0x66); /*PUNPCKLBW XMM1, XMM2*/ addbyte(0x0f); addbyte(0x60); addbyte(0xca); } - if (!cc_zero_other) - { - if (_rgb_sel == CC_LOCALSELECT_ITER_RGB) - { + if (!cc_zero_other) { + if (_rgb_sel == CC_LOCALSELECT_ITER_RGB) { addbyte(0xf3); /*MOVDQU XMM0, ib*/ /* ir, ig and ib must be in same dqword!*/ addbyte(0x0f); addbyte(0x6f); @@ -1956,9 +1825,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x0f); addbyte(0x67); addbyte(0xc0); - } - else if (_rgb_sel == CC_LOCALSELECT_TEX) - { + } else if (_rgb_sel == CC_LOCALSELECT_TEX) { #if 0 addbyte(0xf3); /*MOVDQU XMM0, state->tex_b*/ addbyte(0x0f); @@ -1974,39 +1841,31 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x67); addbyte(0xc0); #endif - } - else if (_rgb_sel == CC_LOCALSELECT_COLOR1) - { + } else if (_rgb_sel == CC_LOCALSELECT_COLOR1) { addbyte(0x66); /*MOVD XMM0, params->color1*/ addbyte(0x0f); addbyte(0x6e); addbyte(0x86); addlong(offsetof(voodoo_params_t, color1)); - } - else - { + } else { /*MOVD XMM0, src_r*/ } addbyte(0x66); /*PUNPCKLBW XMM0, XMM2*/ addbyte(0x0f); addbyte(0x60); addbyte(0xc2); - if (cc_sub_clocal) - { + if (cc_sub_clocal) { addbyte(0x66); /*PSUBW XMM0, XMM1*/ addbyte(0x0f); addbyte(0xf9); addbyte(0xc1); } - } - else - { + } else { addbyte(0x66); /*PXOR XMM0, XMM0*/ addbyte(0x0f); addbyte(0xef); addbyte(0xc0); - if (cc_sub_clocal) - { + if (cc_sub_clocal) { addbyte(0x66); /*PSUBW XMM0, XMM1*/ addbyte(0x0f); addbyte(0xf9); @@ -2014,39 +1873,35 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo } } - if (params->alphaMode & ((1 << 0) | (1 << 4))) - { - if (!(cca_mselect == 0 && cca_reverse_blend == 0)) - { - switch (cca_mselect) - { - case CCA_MSELECT_ALOCAL: + if (params->alphaMode & ((1 << 0) | (1 << 4))) { + if (!(cca_mselect == 0 && cca_reverse_blend == 0)) { + switch (cca_mselect) { + case CCA_MSELECT_ALOCAL: addbyte(0x89); /*MOV EAX, ECX*/ addbyte(0xc8); break; - case CCA_MSELECT_AOTHER: + case CCA_MSELECT_AOTHER: addbyte(0x89); /*MOV EAX, EBX*/ addbyte(0xd8); break; - case CCA_MSELECT_ALOCAL2: + case CCA_MSELECT_ALOCAL2: addbyte(0x89); /*MOV EAX, ECX*/ addbyte(0xc8); break; - case CCA_MSELECT_TEX: + case CCA_MSELECT_TEX: addbyte(0x0f); /*MOVZX EAX, state->tex_a*/ addbyte(0xb6); addbyte(0x87); addlong(offsetof(voodoo_state_t, tex_a)); break; - case CCA_MSELECT_ZERO: - default: + case CCA_MSELECT_ZERO: + default: addbyte(0x31); /*XOR EAX, EAX*/ addbyte(0xc0); break; } - if (!cca_reverse_blend) - { + if (!cca_reverse_blend) { addbyte(0x35); /*XOR EAX, 0xff*/ addlong(0xff); } @@ -2062,14 +1917,12 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo } } - if ((params->alphaMode & ((1 << 0) | (1 << 4)))) - { + if ((params->alphaMode & ((1 << 0) | (1 << 4)))) { addbyte(0x31); /*XOR EAX, EAX*/ addbyte(0xc0); } - - if (!(cc_mselect == 0 && cc_reverse_blend == 0) && cc_mselect == CC_MSELECT_AOTHER) - { + + if (!(cc_mselect == 0 && cc_reverse_blend == 0) && cc_mselect == CC_MSELECT_AOTHER) { /*Copy a_other to XMM3 before it gets modified*/ addbyte(0x66); /*MOVD XMM3, EDX*/ addbyte(0x0f); @@ -2081,15 +1934,13 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xdb); addbyte(0x00); } - - if (cca_add && (params->alphaMode & ((1 << 0) | (1 << 4)))) - { + + if (cca_add && (params->alphaMode & ((1 << 0) | (1 << 4)))) { addbyte(0x01); /*ADD EDX, ECX*/ addbyte(0xca); } - - if ((params->alphaMode & ((1 << 0) | (1 << 4)))) - { + + if ((params->alphaMode & ((1 << 0) | (1 << 4)))) { addbyte(0x85); /*TEST EDX, EDX*/ addbyte(0xd2); addbyte(0x0f); /*CMOVS EDX, EAX*/ @@ -2104,31 +1955,28 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x47); addbyte(0xd0); - if (cca_invert_output) - { + if (cca_invert_output) { addbyte(0x81); /*XOR EDX, 0xff*/ addbyte(0xf2); addlong(0xff); } } - if (!(cc_mselect == 0 && cc_reverse_blend == 0)) - { - switch (cc_mselect) - { - case CC_MSELECT_ZERO: + if (!(cc_mselect == 0 && cc_reverse_blend == 0)) { + switch (cc_mselect) { + case CC_MSELECT_ZERO: addbyte(0x66); /*PXOR XMM3, XMM3*/ addbyte(0x0f); addbyte(0xef); addbyte(0xdb); break; - case CC_MSELECT_CLOCAL: + case CC_MSELECT_CLOCAL: addbyte(0xf3); /*MOV XMM3, XMM1*/ addbyte(0x0f); addbyte(0x7e); addbyte(0xd9); break; - case CC_MSELECT_ALOCAL: + case CC_MSELECT_ALOCAL: addbyte(0x66); /*MOVD XMM3, ECX*/ addbyte(0x0f); addbyte(0x6e); @@ -2139,10 +1987,10 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xdb); addbyte(0x00); break; - case CC_MSELECT_AOTHER: + case CC_MSELECT_AOTHER: /*Handled above*/ break; - case CC_MSELECT_TEX: + case CC_MSELECT_TEX: addbyte(0x66); /*PINSRW XMM3, state->tex_a, 0*/ addbyte(0x0f); addbyte(0xc4); @@ -2162,7 +2010,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addlong(offsetof(voodoo_state_t, tex_a)); addbyte(2); break; - case CC_MSELECT_TEXRGB: + case CC_MSELECT_TEXRGB: addbyte(0x66); /*PUNPCKLBW XMM4, XMM2*/ addbyte(0x0f); addbyte(0x60); @@ -2172,7 +2020,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x7e); addbyte(0xdc); break; - default: + default: addbyte(0x66); /*PXOR XMM3, XMM3*/ addbyte(0x0f); addbyte(0xef); @@ -2183,8 +2031,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x0f); addbyte(0x7e); addbyte(0xe0); - if (!cc_reverse_blend) - { + if (!cc_reverse_blend) { addbyte(0x66); /*PXOR XMM3, 0xff*/ addbyte(0x0f); addbyte(0xef); @@ -2218,9 +2065,8 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x6b); addbyte(0xc0); } - - if (cc_add == 1) - { + + if (cc_add == 1) { addbyte(0x66); /*PADDW XMM0, XMM1*/ addbyte(0x0f); addbyte(0xfd); @@ -2232,24 +2078,21 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x67); addbyte(0xc0); - if (cc_invert_output) - { + if (cc_invert_output) { addbyte(0x66); /*PXOR XMM0, 0xff*/ addbyte(0x0f); addbyte(0xef); addbyte(0x05); addlong((uint32_t)&xmm_ff_b); } -//#if 0 -// addbyte(0x66); /*MOVD state->out[EDI], XMM0*/ -// addbyte(0x0f); -// addbyte(0x7e); -// addbyte(0x87); -// addlong(offsetof(voodoo_state_t, out)); - if (params->fogMode & FOG_ENABLE) - { - if (params->fogMode & FOG_CONSTANT) - { + //#if 0 + // addbyte(0x66); /*MOVD state->out[EDI], XMM0*/ + // addbyte(0x0f); + // addbyte(0x7e); + // addbyte(0x87); + // addlong(offsetof(voodoo_state_t, out)); + if (params->fogMode & FOG_ENABLE) { + if (params->fogMode & FOG_CONSTANT) { addbyte(0x66); /*MOVD XMM3, params->fogColor[ESI]*/ addbyte(0x0f); addbyte(0x6e); @@ -2259,21 +2102,18 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x0f); addbyte(0xdc); addbyte(0xc3); -/* src_r += params->fogColor.r; - src_g += params->fogColor.g; - src_b += params->fogColor.b; */ - } - else - { + /* src_r += params->fogColor.r; + src_g += params->fogColor.g; + src_b += params->fogColor.b; */ + } else { /*int fog_r, fog_g, fog_b, fog_a; */ - + addbyte(0x66); /*PUNPCKLBW XMM0, XMM2*/ addbyte(0x0f); addbyte(0x60); addbyte(0xc2); - if (!(params->fogMode & FOG_ADD)) - { + if (!(params->fogMode & FOG_ADD)) { addbyte(0x66); /*MOVD XMM3, params->fogColor[ESI]*/ addbyte(0x0f); addbyte(0x6e); @@ -2283,17 +2123,14 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x0f); addbyte(0x60); addbyte(0xda); - } - else - { + } else { addbyte(0x66); /*PXOR XMM3, XMM3*/ addbyte(0x0f); addbyte(0xef); addbyte(0xdb); } - - if (!(params->fogMode & FOG_MULT)) - { + + if (!(params->fogMode & FOG_MULT)) { addbyte(0x66); /*PSUBW XMM3, XMM0*/ addbyte(0x0f); addbyte(0xf9); @@ -2307,9 +2144,8 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xe3); addbyte(1); - switch (params->fogMode & (FOG_Z|FOG_ALPHA)) - { - case 0: + switch (params->fogMode & (FOG_Z | FOG_ALPHA)) { + case 0: addbyte(0x8b); /*MOV EBX, state->w_depth[EDI]*/ addbyte(0x9f); addlong(offsetof(voodoo_state_t, w_depth)); @@ -2329,7 +2165,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xf6); /*MUL params->fogTable+1[ESI+EBX*2]*/ addbyte(0xa4); addbyte(0x5e); - addlong(offsetof(voodoo_params_t, fogTable)+1); + addlong(offsetof(voodoo_params_t, fogTable) + 1); addbyte(0x0f); /*MOVZX EBX, params->fogTable[ESI+EBX*2]*/ addbyte(0xb6); addbyte(0x9c); @@ -2341,13 +2177,14 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x01); /*ADD EAX, EBX*/ addbyte(0xd8); -/* int fog_idx = (w_depth >> 10) & 0x3f; + /* int fog_idx = (w_depth >> 10) & 0x3f; - fog_a = params->fogTable[fog_idx].fog; - fog_a += (params->fogTable[fog_idx].dfog * ((w_depth >> 2) & 0xff)) >> 10;*/ + fog_a = params->fogTable[fog_idx].fog; + fog_a += (params->fogTable[fog_idx].dfog * ((w_depth >> 2) & + 0xff)) >> 10;*/ break; - - case FOG_Z: + + case FOG_Z: addbyte(0x8b); /*MOV EAX, state->z[EDI]*/ addbyte(0x87); addlong(offsetof(voodoo_state_t, z)); @@ -2356,10 +2193,10 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(12); addbyte(0x25); /*AND EAX, 0xff*/ addlong(0xff); -// fog_a = (z >> 20) & 0xff; + // fog_a = (z >> 20) & 0xff; break; - - case FOG_ALPHA: + + case FOG_ALPHA: addbyte(0x8b); /*MOV EAX, state->ia[EDI]*/ addbyte(0x87); addlong(offsetof(voodoo_state_t, ia)); @@ -2378,13 +2215,13 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x0f); /*CMOVAE EAX, EBX*/ addbyte(0x43); addbyte(0xc3); -// fog_a = CLAMP(ia >> 12); + // fog_a = CLAMP(ia >> 12); break; - - case FOG_W: + + case FOG_W: addbyte(0x8b); /*MOV EAX, state->w[EDI]+4*/ addbyte(0x87); - addlong(offsetof(voodoo_state_t, w)+4); + addlong(offsetof(voodoo_state_t, w) + 4); addbyte(0x31); /*XOR EBX, EBX*/ addbyte(0xdb); addbyte(0x09); /*OR EAX, EAX*/ @@ -2399,12 +2236,12 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x0f); /*CMOVAE EAX, EBX*/ addbyte(0x43); addbyte(0xc3); -// fog_a = CLAMP(w >> 32); + // fog_a = CLAMP(w >> 32); break; } addbyte(0x01); /*ADD EAX, EAX*/ addbyte(0xc0); -// fog_a++; + // fog_a++; addbyte(0x66); /*PMULLW XMM3, alookup+4[EAX*8]*/ addbyte(0x0f); @@ -2417,26 +2254,23 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x71); addbyte(0xe3); addbyte(7); -/* fog_r = (fog_r * fog_a) >> 8; - fog_g = (fog_g * fog_a) >> 8; - fog_b = (fog_b * fog_a) >> 8;*/ + /* fog_r = (fog_r * fog_a) >> 8; + fog_g = (fog_g * fog_a) >> 8; + fog_b = (fog_b * fog_a) >> 8;*/ - if (params->fogMode & FOG_MULT) - { + if (params->fogMode & FOG_MULT) { addbyte(0xf3); /*MOV XMM0, XMM3*/ addbyte(0x0f); addbyte(0x7e); addbyte(0xc3); - } - else - { + } else { addbyte(0x66); /*PADDW XMM0, XMM3*/ addbyte(0x0f); addbyte(0xfd); addbyte(0xc3); -/* src_r += fog_r; - src_g += fog_g; - src_b += fog_b;*/ + /* src_r += fog_r; + src_g += fog_g; + src_b += fog_b;*/ } addbyte(0x66); /*PACKUSWB XMM0, XMM0*/ addbyte(0x0f); @@ -2444,13 +2278,12 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xc0); } -/* src_r = CLAMP(src_r); - src_g = CLAMP(src_g); - src_b = CLAMP(src_b);*/ + /* src_r = CLAMP(src_r); + src_g = CLAMP(src_g); + src_b = CLAMP(src_b);*/ } - if ((params->alphaMode & 1) && (alpha_func != AFUNC_NEVER) && (alpha_func != AFUNC_ALWAYS)) - { + if ((params->alphaMode & 1) && (alpha_func != AFUNC_NEVER) && (alpha_func != AFUNC_ALWAYS)) { addbyte(0x0f); /*MOVZX ECX, params->alphaMode+3*/ addbyte(0xb6); addbyte(0x8e); @@ -2458,53 +2291,49 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x39); /*CMP EDX, ECX*/ addbyte(0xca); - switch (alpha_func) - { - case AFUNC_LESSTHAN: + switch (alpha_func) { + case AFUNC_LESSTHAN: addbyte(0x0f); /*JAE skip*/ addbyte(0x83); a_skip_pos = block_pos; addlong(0); break; - case AFUNC_EQUAL: + case AFUNC_EQUAL: addbyte(0x0f); /*JNE skip*/ addbyte(0x85); a_skip_pos = block_pos; addlong(0); break; - case AFUNC_LESSTHANEQUAL: + case AFUNC_LESSTHANEQUAL: addbyte(0x0f); /*JA skip*/ addbyte(0x87); a_skip_pos = block_pos; addlong(0); break; - case AFUNC_GREATERTHAN: + case AFUNC_GREATERTHAN: addbyte(0x0f); /*JBE skip*/ addbyte(0x86); a_skip_pos = block_pos; addlong(0); break; - case AFUNC_NOTEQUAL: + case AFUNC_NOTEQUAL: addbyte(0x0f); /*JE skip*/ addbyte(0x84); a_skip_pos = block_pos; addlong(0); break; - case AFUNC_GREATERTHANEQUAL: + case AFUNC_GREATERTHANEQUAL: addbyte(0x0f); /*JB skip*/ addbyte(0x82); a_skip_pos = block_pos; addlong(0); break; } - } - else if ((params->alphaMode & 1) && (alpha_func == AFUNC_NEVER)) - { + } else if ((params->alphaMode & 1) && (alpha_func == AFUNC_NEVER)) { addbyte(0xC3); /*RET*/ } - - if (params->alphaMode & (1 << 4)) - { + + if (params->alphaMode & (1 << 4)) { addbyte(0x8b); /*MOV EAX, state->x[EDI]*/ addbyte(0x87); if (params->col_tiled) @@ -2539,16 +2368,15 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x0f); addbyte(0x7e); addbyte(0xf4); - - switch (dest_afunc) - { - case AFUNC_AZERO: + + switch (dest_afunc) { + case AFUNC_AZERO: addbyte(0x66); /*PXOR XMM4, XMM4*/ addbyte(0x0f); addbyte(0xef); addbyte(0xe4); break; - case AFUNC_ASRC_ALPHA: + case AFUNC_ASRC_ALPHA: addbyte(0x66); /*PMULLW XMM4, alookup[EDX*8]*/ addbyte(0x0f); addbyte(0xd5); @@ -2579,7 +2407,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xd4); addbyte(8); break; - case AFUNC_A_COLOR: + case AFUNC_A_COLOR: addbyte(0x66); /*PMULLW XMM4, XMM0*/ addbyte(0x0f); addbyte(0xd5); @@ -2608,11 +2436,11 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xd4); addbyte(8); break; - case AFUNC_ADST_ALPHA: + case AFUNC_ADST_ALPHA: break; - case AFUNC_AONE: + case AFUNC_AONE: break; - case AFUNC_AOMSRC_ALPHA: + case AFUNC_AOMSRC_ALPHA: addbyte(0x66); /*PMULLW XMM4, aminuslookup[EDX*8]*/ addbyte(0x0f); addbyte(0xd5); @@ -2643,7 +2471,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xd4); addbyte(8); break; - case AFUNC_AOM_COLOR: + case AFUNC_AOM_COLOR: addbyte(0xf3); /*MOVQ XMM5, xmm_ff_w*/ addbyte(0x0f); addbyte(0x7e); @@ -2681,13 +2509,13 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xd4); addbyte(8); break; - case AFUNC_AOMDST_ALPHA: + case AFUNC_AOMDST_ALPHA: addbyte(0x66); /*PXOR XMM4, XMM4*/ addbyte(0x0f); addbyte(0xef); addbyte(0xe4); break; - case AFUNC_ASATURATE: + case AFUNC_ASATURATE: addbyte(0x66); /*PMULLW XMM4, minus_254*/ addbyte(0x0f); addbyte(0xd5); @@ -2718,15 +2546,14 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(8); } - switch (src_afunc) - { - case AFUNC_AZERO: + switch (src_afunc) { + case AFUNC_AZERO: addbyte(0x66); /*PXOR XMM0, XMM0*/ addbyte(0x0f); addbyte(0xef); addbyte(0xc0); break; - case AFUNC_ASRC_ALPHA: + case AFUNC_ASRC_ALPHA: addbyte(0x66); /*PMULLW XMM0, alookup[EDX*8]*/ addbyte(0x0f); addbyte(0xd5); @@ -2757,7 +2584,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xd0); addbyte(8); break; - case AFUNC_A_COLOR: + case AFUNC_A_COLOR: addbyte(0x66); /*PMULLW XMM0, XMM6*/ addbyte(0x0f); addbyte(0xd5); @@ -2786,11 +2613,11 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xd0); addbyte(8); break; - case AFUNC_ADST_ALPHA: + case AFUNC_ADST_ALPHA: break; - case AFUNC_AONE: + case AFUNC_AONE: break; - case AFUNC_AOMSRC_ALPHA: + case AFUNC_AOMSRC_ALPHA: addbyte(0x66); /*PMULLW XMM0, aminuslookup[EDX*8]*/ addbyte(0x0f); addbyte(0xd5); @@ -2821,7 +2648,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xd0); addbyte(8); break; - case AFUNC_AOM_COLOR: + case AFUNC_AOM_COLOR: addbyte(0xf3); /*MOVQ XMM5, xmm_ff_w*/ addbyte(0x0f); addbyte(0x7e); @@ -2859,16 +2686,16 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xd0); addbyte(8); break; - case AFUNC_AOMDST_ALPHA: + case AFUNC_AOMDST_ALPHA: addbyte(0x66); /*PXOR XMM0, XMM0*/ addbyte(0x0f); addbyte(0xef); addbyte(0xc0); break; - case AFUNC_ACOLORBEFOREFOG: + case AFUNC_ACOLORBEFOREFOG: break; } - + addbyte(0x66); /*PADDW XMM0, XMM4*/ addbyte(0x0f); addbyte(0xfd); @@ -2879,13 +2706,12 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x67); addbyte(0xc0); } -//#endif - -// addbyte(0x8b); /*MOV EDX, x (ESP+12)*/ -// addbyte(0x54); -// addbyte(0x24); -// addbyte(12); + //#endif + // addbyte(0x8b); /*MOV EDX, x (ESP+12)*/ + // addbyte(0x54); + // addbyte(0x24); + // addbyte(12); addbyte(0x8b); /*MOV EDX, state->x[EDI]*/ addbyte(0x97); @@ -2898,24 +2724,21 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x0f); addbyte(0x7e); addbyte(0xc0); - - if (params->fbzMode & FBZ_RGB_WMASK) - { -// addbyte(0x89); /*MOV state->rgb_out[EDI], EAX*/ -// addbyte(0x87); -// addlong(offsetof(voodoo_state_t, rgb_out)); - - if (dither) - { + + if (params->fbzMode & FBZ_RGB_WMASK) { + // addbyte(0x89); /*MOV state->rgb_out[EDI], EAX*/ + // addbyte(0x87); + // addlong(offsetof(voodoo_state_t, rgb_out)); + + if (dither) { addbyte(0x8b); /*MOV ESI, real_y (ESP+16)*/ addbyte(0x74); addbyte(0x24); - addbyte(16+16); + addbyte(16 + 16); addbyte(0x0f); /*MOVZX EBX, AH*/ /*G*/ addbyte(0xb6); addbyte(0xdc); - if (dither2x2) - { + if (dither2x2) { addbyte(0x83); /*AND EDX, 1*/ addbyte(0xe2); addbyte(1); @@ -2925,9 +2748,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xc1); /*SHL EBX, 2*/ addbyte(0xe3); addbyte(2); - } - else - { + } else { addbyte(0x83); /*AND EDX, 3*/ addbyte(0xe2); addbyte(3); @@ -2941,17 +2762,14 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x0f); /*MOVZX ECX, AL*/ /*R*/ addbyte(0xb6); addbyte(0xc8); - if (dither2x2) - { + if (dither2x2) { addbyte(0xc1); /*SHR EAX, 14*/ addbyte(0xe8); addbyte(14); addbyte(0x8d); /*LEA ESI, EDX+ESI*2*/ addbyte(0x34); addbyte(0x72); - } - else - { + } else { addbyte(0xc1); /*SHR EAX, 12*/ addbyte(0xe8); addbyte(12); @@ -2965,16 +2783,13 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addlong(offsetof(voodoo_state_t, x_tiled)); else addlong(offsetof(voodoo_state_t, x)); - if (dither2x2) - { + if (dither2x2) { addbyte(0xc1); /*SHL ECX, 2*/ addbyte(0xe1); addbyte(2); addbyte(0x25); /*AND EAX, 0x3fc*/ /*B*/ addlong(0x3fc); - } - else - { + } else { addbyte(0xc1); /*SHL ECX, 4*/ addbyte(0xe1); addbyte(4); @@ -3006,9 +2821,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xd8); addbyte(0x09); /*OR EAX, ECX*/ addbyte(0xc8); - } - else - { + } else { addbyte(0x89); /*MOV EBX, EAX*/ addbyte(0xc3); addbyte(0x0f); /*MOVZX ECX, AH*/ @@ -3046,8 +2859,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x56); } - if ((params->fbzMode & (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) == (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) - { + if ((params->fbzMode & (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) == (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) { addbyte(0x8b); /*MOV EDX, state->x[EDI]*/ addbyte(0x97); if (params->aux_tiled) @@ -3074,14 +2886,12 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo if (chroma_skip_pos) *(uint32_t *)&code_block[chroma_skip_pos] = (block_pos - chroma_skip_pos) - 4; - addbyte(0x8b); /*MOV ESI, [ESP+8]*/ addbyte(0x74); addbyte(0x24); - addbyte(8+16); + addbyte(8 + 16); - if (voodoo->dual_tmus) - { + if (voodoo->dual_tmus) { addbyte(0xf3); /*MOVDQU XMM3, state->tmu1_s[EDI]*/ addbyte(0x0f); addbyte(0x6f); @@ -3102,8 +2912,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x7e); addbyte(0xb6); addlong(offsetof(voodoo_params_t, tmu[1].dWdX)); - if (state->xdir > 0) - { + if (state->xdir > 0) { addbyte(0x66); /*PADDQ XMM3, XMM5*/ addbyte(0x0f); addbyte(0xd4); @@ -3112,9 +2921,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x0f); addbyte(0xd4); addbyte(0xe6); - } - else - { + } else { addbyte(0x66); /*PSUBQ XMM3, XMM5*/ addbyte(0x0f); addbyte(0xfb); @@ -3155,7 +2962,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x0f); addbyte(0x6f); addbyte(0x86); - addlong(offsetof(voodoo_params_t, dBdX)); + addlong(offsetof(voodoo_params_t, dBdX)); addbyte(0x8b); /*MOV EAX, params->dZdX[ESI]*/ addbyte(0x86); addlong(offsetof(voodoo_params_t, dZdX)); @@ -3170,15 +2977,12 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xb6); addlong(offsetof(voodoo_params_t, tmu[0].dWdX)); - if (state->xdir > 0) - { + if (state->xdir > 0) { addbyte(0x66); /*PADDD XMM1, XMM0*/ addbyte(0x0f); addbyte(0xfe); addbyte(0xc8); - } - else - { + } else { addbyte(0x66); /*PSUBD XMM1, XMM0*/ addbyte(0x0f); addbyte(0xfa); @@ -3201,8 +3005,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xbe); addlong(offsetof(voodoo_params_t, dWdX)); - if (state->xdir > 0) - { + if (state->xdir > 0) { addbyte(0x66); /*PADDQ XMM3, XMM5*/ addbyte(0x0f); addbyte(0xd4); @@ -3217,10 +3020,8 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xc7); addbyte(0x01); /*ADD state->z[EDI], EAX*/ addbyte(0x87); - addlong(offsetof(voodoo_state_t, z)); - } - else - { + addlong(offsetof(voodoo_state_t, z)); + } else { addbyte(0x66); /*PSUBQ XMM3, XMM5*/ addbyte(0x0f); addbyte(0xfb); @@ -3235,7 +3036,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xc7); addbyte(0x29); /*SUB state->z[EDI], EAX*/ addbyte(0x87); - addlong(offsetof(voodoo_state_t, z)); + addlong(offsetof(voodoo_state_t, z)); } addbyte(0xf3); /*MOVDQU state->tmu0_s, XMM3*/ @@ -3253,43 +3054,36 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xd6); addbyte(0x87); addlong(offsetof(voodoo_state_t, w)); - + addbyte(0x83); /*ADD state->pixel_count[EDI], 1*/ addbyte(0x87); addlong(offsetof(voodoo_state_t, pixel_count)); addbyte(1); - if (params->fbzColorPath & FBZCP_TEXTURE_ENABLED) - { + if (params->fbzColorPath & FBZCP_TEXTURE_ENABLED) { if ((params->textureMode[0] & TEXTUREMODE_MASK) == TEXTUREMODE_PASSTHROUGH || - (params->textureMode[0] & TEXTUREMODE_LOCAL_MASK) == TEXTUREMODE_LOCAL) - { + (params->textureMode[0] & TEXTUREMODE_LOCAL_MASK) == TEXTUREMODE_LOCAL) { addbyte(0x83); /*ADD state->texel_count[EDI], 1*/ addbyte(0x87); addlong(offsetof(voodoo_state_t, texel_count)); addbyte(1); - } - else - { + } else { addbyte(0x83); /*ADD state->texel_count[EDI], 2*/ addbyte(0x87); addlong(offsetof(voodoo_state_t, texel_count)); addbyte(2); - } + } } addbyte(0x8b); /*MOV EAX, state->x[EDI]*/ addbyte(0x87); addlong(offsetof(voodoo_state_t, x)); - - if (state->xdir > 0) - { + + if (state->xdir > 0) { addbyte(0x83); /*ADD state->x[EDI], 1*/ addbyte(0x87); addlong(offsetof(voodoo_state_t, x)); addbyte(1); - } - else - { + } else { addbyte(0x83); /*SUB state->x[EDI], 1*/ addbyte(0xaf); addlong(offsetof(voodoo_state_t, x)); @@ -3302,52 +3096,44 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x0f); /*JNZ loop_jump_pos*/ addbyte(0x85); addlong(loop_jump_pos - (block_pos + 4)); - - addbyte(0x5b); /*POP EBX*/ + + addbyte(0x5b); /*POP EBX*/ addbyte(0x5e); /*POP ESI*/ addbyte(0x5f); /*POP EDI*/ addbyte(0x5d); /*POP EBP*/ - + addbyte(0xC3); /*RET*/ - + if (params->textureMode[1] & TEXTUREMODE_TRILINEAR) cs = cs; } int voodoo_recomp = 0; -static inline void *voodoo_get_block(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int odd_even) -{ +static inline void *voodoo_get_block(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int odd_even) { int c; int b = last_block[odd_even]; voodoo_x86_data_t *data; voodoo_x86_data_t *codegen_data = voodoo->codegen_data; - - for (c = 0; c < 8; c++) - { - data = &codegen_data[odd_even + b*4]; - - if (state->xdir == data->xdir && - params->alphaMode == data->alphaMode && - params->fbzMode == data->fbzMode && - params->fogMode == data->fogMode && - params->fbzColorPath == data->fbzColorPath && - (voodoo->trexInit1[0] & (1 << 18)) == data->trexInit1 && - params->textureMode[0] == data->textureMode[0] && - params->textureMode[1] == data->textureMode[1] && - (params->tLOD[0] & LOD_MASK) == data->tLOD[0] && + + for (c = 0; c < 8; c++) { + data = &codegen_data[odd_even + b * 4]; + + if (state->xdir == data->xdir && params->alphaMode == data->alphaMode && params->fbzMode == data->fbzMode && + params->fogMode == data->fogMode && params->fbzColorPath == data->fbzColorPath && + (voodoo->trexInit1[0] & (1 << 18)) == data->trexInit1 && params->textureMode[0] == data->textureMode[0] && + params->textureMode[1] == data->textureMode[1] && (params->tLOD[0] & LOD_MASK) == data->tLOD[0] && (params->tLOD[1] & LOD_MASK) == data->tLOD[1] && - ((params->col_tiled || params->aux_tiled) ? 1 : 0) == data->is_tiled) - { + ((params->col_tiled || params->aux_tiled) ? 1 : 0) == data->is_tiled) { last_block[odd_even] = b; return data->code_block; } - + b = (b + 1) & 7; } -voodoo_recomp++; - data = &codegen_data[odd_even + next_block_to_write[odd_even]*4]; -// code_block = data->code_block; - + voodoo_recomp++; + data = &codegen_data[odd_even + next_block_to_write[odd_even] * 4]; + // code_block = data->code_block; + voodoo_generate(data->code_block, voodoo, params, state, depth_op); data->xdir = state->xdir; @@ -3363,56 +3149,55 @@ voodoo_recomp++; data->is_tiled = (params->col_tiled || params->aux_tiled) ? 1 : 0; next_block_to_write[odd_even] = (next_block_to_write[odd_even] + 1) & 7; - + return data->code_block; } -void voodoo_codegen_init(voodoo_t *voodoo) -{ +void voodoo_codegen_init(voodoo_t *voodoo) { int c; #if defined(__linux__) || defined(__APPLE__) - void *start; - size_t len; - long pagesize = sysconf(_SC_PAGESIZE); - long pagemask = ~(pagesize - 1); + void *start; + size_t len; + long pagesize = sysconf(_SC_PAGESIZE); + long pagemask = ~(pagesize - 1); #endif #if defined WIN32 || defined _WIN32 || defined _WIN32 - voodoo->codegen_data = VirtualAlloc(NULL, sizeof(voodoo_x86_data_t) * BLOCK_NUM*4, MEM_COMMIT, PAGE_EXECUTE_READWRITE); + voodoo->codegen_data = VirtualAlloc(NULL, sizeof(voodoo_x86_data_t) * BLOCK_NUM * 4, MEM_COMMIT, PAGE_EXECUTE_READWRITE); #else - voodoo->codegen_data = mmap(0, sizeof(voodoo_x86_data_t) * BLOCK_NUM*4, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, 0, 0); + voodoo->codegen_data = mmap(0, sizeof(voodoo_x86_data_t) * BLOCK_NUM * 4, PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_ANON | MAP_PRIVATE, 0, 0); #endif - for (c = 0; c < 256; c++) - { + for (c = 0; c < 256; c++) { int d[4]; int _ds = c & 0xf; int dt = c >> 4; - + alookup[c] = _mm_set_epi32(0, 0, c | (c << 16), c | (c << 16)); - aminuslookup[c] = _mm_set_epi32(0, 0, (255-c) | ((255-c) << 16), (255-c) | ((255-c) << 16)); + aminuslookup[c] = _mm_set_epi32(0, 0, (255 - c) | ((255 - c) << 16), (255 - c) | ((255 - c) << 16)); d[0] = (16 - _ds) * (16 - dt); - d[1] = _ds * (16 - dt); + d[1] = _ds * (16 - dt); d[2] = (16 - _ds) * dt; d[3] = _ds * dt; - bilinear_lookup[c*2] = _mm_set_epi32(d[1] | (d[1] << 16), d[1] | (d[1] << 16), d[0] | (d[0] << 16), d[0] | (d[0] << 16)); - bilinear_lookup[c*2 + 1] = _mm_set_epi32(d[3] | (d[3] << 16), d[3] | (d[3] << 16), d[2] | (d[2] << 16), d[2] | (d[2] << 16)); + bilinear_lookup[c * 2] = + _mm_set_epi32(d[1] | (d[1] << 16), d[1] | (d[1] << 16), d[0] | (d[0] << 16), d[0] | (d[0] << 16)); + bilinear_lookup[c * 2 + 1] = + _mm_set_epi32(d[3] | (d[3] << 16), d[3] | (d[3] << 16), d[2] | (d[2] << 16), d[2] | (d[2] << 16)); } alookup[256] = _mm_set_epi32(0, 0, 256 | (256 << 16), 256 | (256 << 16)); xmm_00_ff_w[0] = _mm_set_epi32(0, 0, 0, 0); xmm_00_ff_w[1] = _mm_set_epi32(0, 0, 0xff | (0xff << 16), 0xff | (0xff << 16)); } -void voodoo_codegen_close(voodoo_t *voodoo) -{ +void voodoo_codegen_close(voodoo_t *voodoo) { #if defined WIN32 || defined _WIN32 || defined _WIN32 VirtualFree(voodoo->codegen_data, 0, MEM_RELEASE); #else - munmap(voodoo->codegen_data, sizeof(voodoo_x86_data_t) * BLOCK_NUM*4); + munmap(voodoo->codegen_data, sizeof(voodoo_x86_data_t) * BLOCK_NUM * 4); #endif } - #endif /* _VID_VOODOO_CODEGEN_X86_H_ */ diff --git a/includes/private/video/vid_voodoo_common.h b/includes/private/video/vid_voodoo_common.h index 87dccfee..dcf896aa 100644 --- a/includes/private/video/vid_voodoo_common.h +++ b/includes/private/video/vid_voodoo_common.h @@ -12,42 +12,29 @@ #define CLAMP(x) (((x) < 0) ? 0 : (((x) > 0xff) ? 0xff : (x))) #define CLAMP16(x) (((x) < 0) ? 0 : (((x) > 0xffff) ? 0xffff : (x))) - #define LOD_MAX 8 #define TEX_DIRTY_SHIFT 10 #define TEX_CACHE_MAX 64 -enum -{ - VOODOO_1 = 0, - VOODOO_SB50, - VOODOO_2, - VOODOO_BANSHEE, - VOODOO_3 -}; +enum { VOODOO_1 = 0, VOODOO_SB50, VOODOO_2, VOODOO_BANSHEE, VOODOO_3 }; -typedef union int_float -{ +typedef union int_float { uint32_t i; float f; } int_float; -typedef struct rgb_t -{ +typedef struct rgb_t { uint8_t b, g, r; uint8_t pad; } rgb_t; -typedef struct rgba8_t -{ +typedef struct rgba8_t { uint8_t b, g, r, a; } rgba8_t; -typedef union rgba_u -{ - struct - { +typedef union rgba_u { + struct { uint8_t b, g, r, a; } rgba; uint32_t u; @@ -58,19 +45,18 @@ typedef union rgba_u #define FIFO_ENTRY_SIZE (1 << 31) #define FIFO_ENTRIES (voodoo->fifo_write_idx - voodoo->fifo_read_idx) -#define FIFO_FULL ((voodoo->fifo_write_idx - voodoo->fifo_read_idx) >= FIFO_SIZE-4) -#define FIFO_EMPTY (voodoo->fifo_read_idx == voodoo->fifo_write_idx) +#define FIFO_FULL ((voodoo->fifo_write_idx - voodoo->fifo_read_idx) >= FIFO_SIZE - 4) +#define FIFO_EMPTY (voodoo->fifo_read_idx == voodoo->fifo_write_idx) #define FIFO_TYPE 0xff000000 #define FIFO_ADDR 0x00ffffff -enum -{ - FIFO_INVALID = (0x00 << 24), - FIFO_WRITEL_REG = (0x01 << 24), - FIFO_WRITEW_FB = (0x02 << 24), - FIFO_WRITEL_FB = (0x03 << 24), - FIFO_WRITEL_TEX = (0x04 << 24), +enum { + FIFO_INVALID = (0x00 << 24), + FIFO_WRITEL_REG = (0x01 << 24), + FIFO_WRITEW_FB = (0x02 << 24), + FIFO_WRITEL_FB = (0x03 << 24), + FIFO_WRITEL_TEX = (0x04 << 24), FIFO_WRITEL_2DREG = (0x05 << 24) }; @@ -79,31 +65,28 @@ enum #define PARAM_ENTRY_SIZE (1 << 31) #define PARAM_ENTRIES(x) (voodoo->params_write_idx - voodoo->params_read_idx[x]) -#define PARAM_FULL(x) ((voodoo->params_write_idx - voodoo->params_read_idx[x]) >= PARAM_SIZE) -#define PARAM_EMPTY(x) (voodoo->params_read_idx[x] == voodoo->params_write_idx) +#define PARAM_FULL(x) ((voodoo->params_write_idx - voodoo->params_read_idx[x]) >= PARAM_SIZE) +#define PARAM_EMPTY(x) (voodoo->params_read_idx[x] == voodoo->params_write_idx) -typedef struct -{ +typedef struct { uint32_t addr_type; uint32_t val; } fifo_entry_t; -typedef struct voodoo_params_t -{ +typedef struct voodoo_params_t { int command; int32_t vertexAx, vertexAy, vertexBx, vertexBy, vertexCx, vertexCy; uint32_t startR, startG, startB, startZ, startA; - int32_t dBdX, dGdX, dRdX, dAdX, dZdX; + int32_t dBdX, dGdX, dRdX, dAdX, dZdX; - int32_t dBdY, dGdY, dRdY, dAdY, dZdY; + int32_t dBdY, dGdY, dRdY, dAdY, dZdY; int64_t startW, dWdX, dWdY; - struct - { + struct { int64_t startS, startT, startW, p1; int64_t dSdX, dTdX, dWdX, p2; int64_t dSdY, dTdY, dWdY, p3; @@ -116,8 +99,7 @@ typedef struct voodoo_params_t uint32_t fogMode; rgb_t fogColor; - struct - { + struct { uint8_t fog, dfog; } fogTable[64]; @@ -133,14 +115,14 @@ typedef struct voodoo_params_t uint32_t texBaseAddr[2], texBaseAddr1[2], texBaseAddr2[2], texBaseAddr38[2]; - uint32_t tex_base[2][LOD_MAX+2]; - uint32_t tex_end[2][LOD_MAX+2]; + uint32_t tex_base[2][LOD_MAX + 2]; + uint32_t tex_end[2][LOD_MAX + 2]; int tex_width[2]; - int tex_w_mask[2][LOD_MAX+2]; - int tex_w_nmask[2][LOD_MAX+2]; - int tex_h_mask[2][LOD_MAX+2]; - int tex_shift[2][LOD_MAX+2]; - int tex_lod[2][LOD_MAX+2]; + int tex_w_mask[2][LOD_MAX + 2]; + int tex_w_nmask[2][LOD_MAX + 2]; + int tex_h_mask[2][LOD_MAX + 2]; + int tex_shift[2][LOD_MAX + 2]; + int tex_lod[2][LOD_MAX + 2]; int tex_entry[2]; int detail_max[2], detail_bias[2], detail_scale[2]; @@ -163,8 +145,7 @@ typedef struct voodoo_params_t int row_width, aux_row_width; } voodoo_params_t; -typedef struct texture_t -{ +typedef struct texture_t { uint32_t base; uint32_t tLOD; volatile int refcount, refcount_r[4]; @@ -174,8 +155,7 @@ typedef struct texture_t uint32_t *data; } texture_t; -typedef struct vert_t -{ +typedef struct vert_t { float sVx, sVy; float sRed, sGreen, sBlue, sAlpha; float sVz, sWb; @@ -183,14 +163,12 @@ typedef struct vert_t float sW1, sS1, sT1; } vert_t; -typedef struct clip_t -{ +typedef struct clip_t { int x_min, x_max; int y_min, y_max; } clip_t; -typedef struct voodoo_t -{ +typedef struct voodoo_t { mem_mapping_t mapping; int pci_enable; @@ -222,7 +200,7 @@ typedef struct voodoo_t int row_width, aux_row_width; int block_width; - + int col_tiled, aux_tiled; uint8_t *fb_mem, *tex_mem[2]; @@ -251,8 +229,7 @@ typedef struct voodoo_t int h_disp; int v_retrace; - struct - { + struct { uint32_t y[4], i[4], q[4]; } nccTable[2][2]; @@ -321,9 +298,9 @@ typedef struct voodoo_t int flush; int scrfilter; - int scrfilterEnabled; - int scrfilterThreshold; - int scrfilterThresholdOld; + int scrfilterEnabled; + int scrfilterThreshold; + int scrfilterThresholdOld; uint32_t last_write_addr; @@ -354,9 +331,8 @@ typedef struct voodoo_t uint32_t bltCommand; uint32_t leftOverlayBuf; - - struct - { + + struct { int dst_x, dst_y; int cur_x; int size_x, size_y; @@ -364,8 +340,7 @@ typedef struct voodoo_t int dst_stride; } blt; - struct - { + struct { uint32_t bresError0, bresError1; uint32_t clip0Min, clip0Max; uint32_t clip1Min, clip1Max; @@ -382,7 +357,7 @@ typedef struct voodoo_t uint32_t srcFormat; uint32_t srcSize; uint32_t srcXY; - + uint32_t colorPattern[64]; int bres_error_0, bres_error_1; @@ -401,11 +376,11 @@ typedef struct voodoo_t int srcX, srcY; int src_stride; int old_srcX; - + /*Used for handling packed 24bpp host data*/ int host_data_remainder; uint32_t old_host_data; - + /*Polyfill coordinates*/ int lx[2], rx[2]; int ly[2], ry[2]; @@ -417,7 +392,7 @@ typedef struct voodoo_t int lx_cur, rx_cur; clip_t clip[2]; - + uint8_t host_data[16384]; int host_data_count; int host_data_size_src, host_data_size_dest; @@ -428,20 +403,19 @@ typedef struct voodoo_t int line_pix_pos, line_bit_pos; int line_rep_cnt, line_bit_mask_size; } banshee_blt; - - struct - { + + struct { uint32_t vidOverlayStartCoords; uint32_t vidOverlayEndScreenCoords; uint32_t vidOverlayDudx, vidOverlayDudxOffsetSrcWidth; uint32_t vidOverlayDvdy, vidOverlayDvdyOffset; - //uint32_t vidDesktopOverlayStride; - + // uint32_t vidDesktopOverlayStride; + int start_x, start_y; int end_x, end_y; int size_x, size_y; int overlay_bytes; - + unsigned int src_y; } overlay; @@ -455,7 +429,7 @@ typedef struct voodoo_t int fb_write_buffer, fb_draw_buffer; int buffer_cutoff; - + uint32_t tile_base, tile_stride; int tile_stride_shift, tile_x, tile_x_real; @@ -485,15 +459,13 @@ typedef struct voodoo_t void *codegen_data; struct voodoo_set_t *set; - - + uint8_t *vram, *changedvram; - + void *p; } voodoo_t; -typedef struct voodoo_set_t -{ +typedef struct voodoo_set_t { voodoo_t *voodoos[2]; mem_mapping_t snoop_mapping; @@ -501,10 +473,8 @@ typedef struct voodoo_set_t int nr_cards; } voodoo_set_t; - extern rgba8_t rgb332[0x100], ai44[0x100], rgb565[0x10000], argb1555[0x10000], argb4444[0x10000], ai88[0x10000]; - void voodoo_generate_vb_filters(voodoo_t *voodoo, int fcr, int fcg); void voodoo_recalc(voodoo_t *voodoo); @@ -513,5 +483,4 @@ void voodoo_update_ncc(voodoo_t *voodoo, int tmu); void *voodoo_2d3d_card_init(int type); void voodoo_card_close(voodoo_t *voodoo); - #endif /* _VID_VOODOO_COMMON_H_ */ diff --git a/includes/private/video/vid_voodoo_display.h b/includes/private/video/vid_voodoo_display.h index f15a69a3..7d3df160 100644 --- a/includes/private/video/vid_voodoo_display.h +++ b/includes/private/video/vid_voodoo_display.h @@ -7,5 +7,4 @@ void voodoo_generate_filter_v2(voodoo_t *voodoo); void voodoo_threshold_check(voodoo_t *voodoo); void voodoo_callback(void *p); - #endif /* _VID_VOODOO_DISPLAY_H_ */ diff --git a/includes/private/video/vid_voodoo_dither.h b/includes/private/video/vid_voodoo_dither.h index dec93aee..c931eefb 100644 --- a/includes/private/video/vid_voodoo_dither.h +++ b/includes/private/video/vid_voodoo_dither.h @@ -1,10285 +1,10269 @@ #ifndef _VID_VOODOO_DITHER_H_ #define _VID_VOODOO_DITHER_H_ -static const uint8_t dither_rb[256][4][4] = -{ - { - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - }, - { - {0, 0, 0, 0}, - {0, 0, 1, 0}, - {0, 0, 0, 0}, - {1, 0, 0, 0}, - }, - { - {0, 0, 0, 0}, - {1, 0, 1, 0}, - {0, 0, 0, 0}, - {1, 0, 1, 0}, - }, - { - {0, 0, 0, 1}, - {1, 0, 1, 0}, - {0, 1, 0, 0}, - {1, 0, 1, 0}, - }, - { - {0, 1, 0, 1}, - {1, 0, 1, 0}, - {0, 1, 0, 1}, - {1, 0, 1, 0}, - }, - { - {0, 1, 0, 1}, - {1, 0, 1, 1}, - {0, 1, 0, 1}, - {1, 1, 1, 0}, - }, - { - {0, 1, 0, 1}, - {1, 1, 1, 1}, - {0, 1, 0, 1}, - {1, 1, 1, 1}, - }, - { - {0, 1, 1, 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, 1, 1}, - {1, 1, 2, 1}, - {1, 1, 1, 1}, - {2, 1, 1, 1}, - }, - { - {1, 1, 1, 1}, - {2, 1, 2, 1}, - {1, 1, 1, 1}, - {2, 1, 2, 1}, - }, - { - {1, 1, 1, 2}, - {2, 1, 2, 1}, - {1, 2, 1, 1}, - {2, 1, 2, 1}, - }, - { - {1, 2, 1, 2}, - {2, 1, 2, 1}, - {1, 2, 1, 2}, - {2, 1, 2, 1}, - }, - { - {1, 2, 1, 2}, - {2, 1, 2, 2}, - {1, 2, 1, 2}, - {2, 2, 2, 1}, - }, - { - {1, 2, 1, 2}, - {2, 2, 2, 2}, - {1, 2, 1, 2}, - {2, 2, 2, 2}, - }, - { - {1, 2, 2, 2}, - {2, 2, 2, 2}, - {2, 2, 1, 2}, - {2, 2, 2, 2}, - }, - { - {1, 2, 2, 2}, - {2, 2, 2, 2}, - {2, 2, 2, 2}, - {2, 2, 2, 2}, - }, - { - {2, 2, 2, 2}, - {2, 2, 2, 2}, - {2, 2, 2, 2}, - {3, 2, 2, 2}, - }, - { - {2, 2, 2, 2}, - {2, 2, 3, 2}, - {2, 2, 2, 2}, - {3, 2, 3, 2}, - }, - { - {2, 2, 2, 2}, - {3, 2, 3, 2}, - {2, 3, 2, 2}, - {3, 2, 3, 2}, - }, - { - {2, 2, 2, 3}, - {3, 2, 3, 2}, - {2, 3, 2, 3}, - {3, 2, 3, 2}, - }, - { - {2, 3, 2, 3}, - {3, 2, 3, 2}, - {2, 3, 2, 3}, - {3, 3, 3, 2}, - }, - { - {2, 3, 2, 3}, - {3, 2, 3, 3}, - {2, 3, 2, 3}, - {3, 3, 3, 3}, - }, - { - {2, 3, 2, 3}, - {3, 3, 3, 3}, - {3, 3, 2, 3}, - {3, 3, 3, 3}, - }, - { - {2, 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}, - {4, 3, 3, 3}, - }, - { - {3, 3, 3, 3}, - {3, 3, 4, 3}, - {3, 3, 3, 3}, - {4, 3, 4, 3}, - }, - { - {3, 3, 3, 3}, - {4, 3, 4, 3}, - {3, 4, 3, 3}, - {4, 3, 4, 3}, - }, - { - {3, 3, 3, 4}, - {4, 3, 4, 3}, - {3, 4, 3, 4}, - {4, 3, 4, 3}, - }, - { - {3, 4, 3, 4}, - {4, 3, 4, 3}, - {3, 4, 3, 4}, - {4, 4, 4, 3}, - }, - { - {3, 4, 3, 4}, - {4, 3, 4, 4}, - {3, 4, 3, 4}, - {4, 4, 4, 4}, - }, - { - {3, 4, 3, 4}, - {4, 4, 4, 4}, - {4, 4, 3, 4}, - {4, 4, 4, 4}, - }, - { - {3, 4, 4, 4}, - {4, 4, 4, 4}, - {4, 4, 3, 4}, - {4, 4, 4, 4}, - }, - { - {4, 4, 4, 4}, - {4, 4, 4, 4}, - {4, 4, 4, 4}, - {4, 4, 4, 4}, - }, - { - {4, 4, 4, 4}, - {4, 4, 5, 4}, - {4, 4, 4, 4}, - {5, 4, 4, 4}, - }, - { - {4, 4, 4, 4}, - {5, 4, 5, 4}, - {4, 4, 4, 4}, - {5, 4, 5, 4}, - }, - { - {4, 4, 4, 5}, - {5, 4, 5, 4}, - {4, 5, 4, 4}, - {5, 4, 5, 4}, - }, - { - {4, 5, 4, 5}, - {5, 4, 5, 4}, - {4, 5, 4, 5}, - {5, 4, 5, 4}, - }, - { - {4, 5, 4, 5}, - {5, 4, 5, 5}, - {4, 5, 4, 5}, - {5, 5, 5, 4}, - }, - { - {4, 5, 4, 5}, - {5, 5, 5, 5}, - {4, 5, 4, 5}, - {5, 5, 5, 5}, - }, - { - {4, 5, 5, 5}, - {5, 5, 5, 5}, - {5, 5, 4, 5}, - {5, 5, 5, 5}, - }, - { - {5, 5, 5, 5}, - {5, 5, 5, 5}, - {5, 5, 5, 5}, - {5, 5, 5, 5}, - }, - { - {5, 5, 5, 5}, - {5, 5, 6, 5}, - {5, 5, 5, 5}, - {6, 5, 5, 5}, - }, - { - {5, 5, 5, 5}, - {6, 5, 6, 5}, - {5, 5, 5, 5}, - {6, 5, 6, 5}, - }, - { - {5, 5, 5, 6}, - {6, 5, 6, 5}, - {5, 6, 5, 5}, - {6, 5, 6, 5}, - }, - { - {5, 6, 5, 6}, - {6, 5, 6, 5}, - {5, 6, 5, 6}, - {6, 5, 6, 5}, - }, - { - {5, 6, 5, 6}, - {6, 5, 6, 6}, - {5, 6, 5, 6}, - {6, 6, 6, 5}, - }, - { - {5, 6, 5, 6}, - {6, 6, 6, 6}, - {5, 6, 5, 6}, - {6, 6, 6, 6}, - }, - { - {5, 6, 5, 6}, - {6, 6, 6, 6}, - {6, 6, 5, 6}, - {6, 6, 6, 6}, - }, - { - {5, 6, 6, 6}, - {6, 6, 6, 6}, - {6, 6, 6, 6}, - {6, 6, 6, 6}, - }, - { - {6, 6, 6, 6}, - {6, 6, 6, 6}, - {6, 6, 6, 6}, - {7, 6, 6, 6}, - }, - { - {6, 6, 6, 6}, - {6, 6, 7, 6}, - {6, 6, 6, 6}, - {7, 6, 7, 6}, - }, - { - {6, 6, 6, 6}, - {7, 6, 7, 6}, - {6, 7, 6, 6}, - {7, 6, 7, 6}, - }, - { - {6, 6, 6, 7}, - {7, 6, 7, 6}, - {6, 7, 6, 7}, - {7, 6, 7, 6}, - }, - { - {6, 7, 6, 7}, - {7, 6, 7, 6}, - {6, 7, 6, 7}, - {7, 7, 7, 6}, - }, - { - {6, 7, 6, 7}, - {7, 6, 7, 7}, - {6, 7, 6, 7}, - {7, 7, 7, 7}, - }, - { - {6, 7, 6, 7}, - {7, 7, 7, 7}, - {7, 7, 6, 7}, - {7, 7, 7, 7}, - }, - { - {6, 7, 7, 7}, - {7, 7, 7, 7}, - {7, 7, 7, 7}, - {7, 7, 7, 7}, - }, - { - {7, 7, 7, 7}, - {7, 7, 7, 7}, - {7, 7, 7, 7}, - {8, 7, 7, 7}, - }, - { - {7, 7, 7, 7}, - {7, 7, 8, 7}, - {7, 7, 7, 7}, - {8, 7, 8, 7}, - }, - { - {7, 7, 7, 7}, - {8, 7, 8, 7}, - {7, 8, 7, 7}, - {8, 7, 8, 7}, - }, - { - {7, 7, 7, 8}, - {8, 7, 8, 7}, - {7, 8, 7, 8}, - {8, 7, 8, 7}, - }, - { - {7, 8, 7, 8}, - {8, 7, 8, 7}, - {7, 8, 7, 8}, - {8, 8, 8, 7}, - }, - { - {7, 8, 7, 8}, - {8, 7, 8, 8}, - {7, 8, 7, 8}, - {8, 8, 8, 8}, - }, - { - {7, 8, 7, 8}, - {8, 8, 8, 8}, - {7, 8, 7, 8}, - {8, 8, 8, 8}, - }, - { - {7, 8, 8, 8}, - {8, 8, 8, 8}, - {8, 8, 7, 8}, - {8, 8, 8, 8}, - }, - { - {8, 8, 8, 8}, - {8, 8, 8, 8}, - {8, 8, 8, 8}, - {8, 8, 8, 8}, - }, - { - {8, 8, 8, 8}, - {8, 8, 9, 8}, - {8, 8, 8, 8}, - {9, 8, 8, 8}, - }, - { - {8, 8, 8, 8}, - {9, 8, 9, 8}, - {8, 8, 8, 8}, - {9, 8, 9, 8}, - }, - { - {8, 8, 8, 9}, - {9, 8, 9, 8}, - {8, 9, 8, 8}, - {9, 8, 9, 8}, - }, - { - {8, 9, 8, 9}, - {9, 8, 9, 8}, - {8, 9, 8, 9}, - {9, 8, 9, 8}, - }, - { - {8, 9, 8, 9}, - {9, 8, 9, 9}, - {8, 9, 8, 9}, - {9, 9, 9, 8}, - }, - { - {8, 9, 8, 9}, - {9, 9, 9, 9}, - {8, 9, 8, 9}, - {9, 9, 9, 9}, - }, - { - {8, 9, 9, 9}, - {9, 9, 9, 9}, - {9, 9, 8, 9}, - {9, 9, 9, 9}, - }, - { - {9, 9, 9, 9}, - {9, 9, 9, 9}, - {9, 9, 9, 9}, - {9, 9, 9, 9}, - }, - { - {9, 9, 9, 9}, - {9, 9, 10, 9}, - {9, 9, 9, 9}, - {10, 9, 9, 9}, - }, - { - {9, 9, 9, 9}, - {10, 9, 10, 9}, - {9, 9, 9, 9}, - {10, 9, 10, 9}, - }, - { - {9, 9, 9, 10}, - {10, 9, 10, 9}, - {9, 10, 9, 9}, - {10, 9, 10, 9}, - }, - { - {9, 10, 9, 10}, - {10, 9, 10, 9}, - {9, 10, 9, 10}, - {10, 9, 10, 9}, - }, - { - {9, 10, 9, 10}, - {10, 9, 10, 10}, - {9, 10, 9, 10}, - {10, 10, 10, 9}, - }, - { - {9, 10, 9, 10}, - {10, 9, 10, 10}, - {9, 10, 9, 10}, - {10, 10, 10, 10}, - }, - { - {9, 10, 9, 10}, - {10, 10, 10, 10}, - {10, 10, 9, 10}, - {10, 10, 10, 10}, - }, - { - {9, 10, 10, 10}, - {10, 10, 10, 10}, - {10, 10, 10, 10}, - {10, 10, 10, 10}, - }, - { - {10, 10, 10, 10}, - {10, 10, 10, 10}, - {10, 10, 10, 10}, - {11, 10, 10, 10}, - }, - { - {10, 10, 10, 10}, - {10, 10, 11, 10}, - {10, 10, 10, 10}, - {11, 10, 11, 10}, - }, - { - {10, 10, 10, 10}, - {11, 10, 11, 10}, - {10, 11, 10, 10}, - {11, 10, 11, 10}, - }, - { - {10, 10, 10, 11}, - {11, 10, 11, 10}, - {10, 11, 10, 11}, - {11, 10, 11, 10}, - }, - { - {10, 11, 10, 11}, - {11, 10, 11, 10}, - {10, 11, 10, 11}, - {11, 11, 11, 10}, - }, - { - {10, 11, 10, 11}, - {11, 10, 11, 11}, - {10, 11, 10, 11}, - {11, 11, 11, 11}, - }, - { - {10, 11, 10, 11}, - {11, 11, 11, 11}, - {11, 11, 10, 11}, - {11, 11, 11, 11}, - }, - { - {10, 11, 11, 11}, - {11, 11, 11, 11}, - {11, 11, 11, 11}, - {11, 11, 11, 11}, - }, - { - {11, 11, 11, 11}, - {11, 11, 11, 11}, - {11, 11, 11, 11}, - {12, 11, 11, 11}, - }, - { - {11, 11, 11, 11}, - {11, 11, 12, 11}, - {11, 11, 11, 11}, - {12, 11, 12, 11}, - }, - { - {11, 11, 11, 11}, - {12, 11, 12, 11}, - {11, 12, 11, 11}, - {12, 11, 12, 11}, - }, - { - {11, 11, 11, 12}, - {12, 11, 12, 11}, - {11, 12, 11, 12}, - {12, 11, 12, 11}, - }, - { - {11, 12, 11, 12}, - {12, 11, 12, 11}, - {11, 12, 11, 12}, - {12, 12, 12, 11}, - }, - { - {11, 12, 11, 12}, - {12, 11, 12, 12}, - {11, 12, 11, 12}, - {12, 12, 12, 11}, - }, - { - {11, 12, 11, 12}, - {12, 12, 12, 12}, - {11, 12, 11, 12}, - {12, 12, 12, 12}, - }, - { - {11, 12, 12, 12}, - {12, 12, 12, 12}, - {12, 12, 11, 12}, - {12, 12, 12, 12}, - }, - { - {12, 12, 12, 12}, - {12, 12, 12, 12}, - {12, 12, 12, 12}, - {12, 12, 12, 12}, - }, - { - {12, 12, 12, 12}, - {12, 12, 13, 12}, - {12, 12, 12, 12}, - {13, 12, 12, 12}, - }, - { - {12, 12, 12, 12}, - {13, 12, 13, 12}, - {12, 12, 12, 12}, - {13, 12, 13, 12}, - }, - { - {12, 12, 12, 13}, - {13, 12, 13, 12}, - {12, 13, 12, 12}, - {13, 12, 13, 12}, - }, - { - {12, 13, 12, 13}, - {13, 12, 13, 12}, - {12, 13, 12, 13}, - {13, 12, 13, 12}, - }, - { - {12, 13, 12, 13}, - {13, 12, 13, 13}, - {12, 13, 12, 13}, - {13, 13, 13, 12}, - }, - { - {12, 13, 12, 13}, - {13, 13, 13, 13}, - {12, 13, 12, 13}, - {13, 13, 13, 13}, - }, - { - {12, 13, 13, 13}, - {13, 13, 13, 13}, - {13, 13, 12, 13}, - {13, 13, 13, 13}, - }, - { - {13, 13, 13, 13}, - {13, 13, 13, 13}, - {13, 13, 13, 13}, - {13, 13, 13, 13}, - }, - { - {13, 13, 13, 13}, - {13, 13, 14, 13}, - {13, 13, 13, 13}, - {14, 13, 13, 13}, - }, - { - {13, 13, 13, 13}, - {14, 13, 14, 13}, - {13, 13, 13, 13}, - {14, 13, 14, 13}, - }, - { - {13, 13, 13, 14}, - {14, 13, 14, 13}, - {13, 14, 13, 13}, - {14, 13, 14, 13}, - }, - { - {13, 14, 13, 14}, - {14, 13, 14, 13}, - {13, 14, 13, 14}, - {14, 13, 14, 13}, - }, - { - {13, 14, 13, 14}, - {14, 13, 14, 13}, - {13, 14, 13, 14}, - {14, 14, 14, 13}, - }, - { - {13, 14, 13, 14}, - {14, 13, 14, 14}, - {13, 14, 13, 14}, - {14, 14, 14, 14}, - }, - { - {13, 14, 13, 14}, - {14, 14, 14, 14}, - {14, 14, 13, 14}, - {14, 14, 14, 14}, - }, - { - {13, 14, 14, 14}, - {14, 14, 14, 14}, - {14, 14, 14, 14}, - {14, 14, 14, 14}, - }, - { - {14, 14, 14, 14}, - {14, 14, 14, 14}, - {14, 14, 14, 14}, - {15, 14, 14, 14}, - }, - { - {14, 14, 14, 14}, - {14, 14, 15, 14}, - {14, 14, 14, 14}, - {15, 14, 15, 14}, - }, - { - {14, 14, 14, 14}, - {15, 14, 15, 14}, - {14, 15, 14, 14}, - {15, 14, 15, 14}, - }, - { - {14, 14, 14, 15}, - {15, 14, 15, 14}, - {14, 15, 14, 15}, - {15, 14, 15, 14}, - }, - { - {14, 15, 14, 15}, - {15, 14, 15, 14}, - {14, 15, 14, 15}, - {15, 15, 15, 14}, - }, - { - {14, 15, 14, 15}, - {15, 14, 15, 15}, - {14, 15, 14, 15}, - {15, 15, 15, 15}, - }, - { - {14, 15, 14, 15}, - {15, 15, 15, 15}, - {15, 15, 14, 15}, - {15, 15, 15, 15}, - }, - { - {14, 15, 15, 15}, - {15, 15, 15, 15}, - {15, 15, 15, 15}, - {15, 15, 15, 15}, - }, - { - {15, 15, 15, 15}, - {15, 15, 15, 15}, - {15, 15, 15, 15}, - {16, 15, 15, 15}, - }, - { - {15, 15, 15, 15}, - {15, 15, 16, 15}, - {15, 15, 15, 15}, - {16, 15, 16, 15}, - }, - { - {15, 15, 15, 15}, - {16, 15, 16, 15}, - {15, 16, 15, 15}, - {16, 15, 16, 15}, - }, - { - {15, 15, 15, 16}, - {16, 15, 16, 15}, - {15, 16, 15, 16}, - {16, 15, 16, 15}, - }, - { - {15, 16, 15, 16}, - {16, 15, 16, 15}, - {15, 16, 15, 16}, - {16, 16, 16, 15}, - }, - { - {15, 16, 15, 16}, - {16, 15, 16, 16}, - {15, 16, 15, 16}, - {16, 16, 16, 16}, - }, - { - {15, 16, 15, 16}, - {16, 16, 16, 16}, - {16, 16, 15, 16}, - {16, 16, 16, 16}, - }, - { - {15, 16, 16, 16}, - {16, 16, 16, 16}, - {16, 16, 16, 16}, - {16, 16, 16, 16}, - }, - { - {16, 16, 16, 16}, - {16, 16, 16, 16}, - {16, 16, 16, 16}, - {17, 16, 16, 16}, - }, - { - {16, 16, 16, 16}, - {16, 16, 17, 16}, - {16, 16, 16, 16}, - {17, 16, 17, 16}, - }, - { - {16, 16, 16, 16}, - {17, 16, 17, 16}, - {16, 17, 16, 16}, - {17, 16, 17, 16}, - }, - { - {16, 16, 16, 17}, - {17, 16, 17, 16}, - {16, 17, 16, 17}, - {17, 16, 17, 16}, - }, - { - {16, 17, 16, 17}, - {17, 16, 17, 16}, - {16, 17, 16, 17}, - {17, 17, 17, 16}, - }, - { - {16, 17, 16, 17}, - {17, 16, 17, 17}, - {16, 17, 16, 17}, - {17, 17, 17, 17}, - }, - { - {16, 17, 16, 17}, - {17, 17, 17, 17}, - {17, 17, 16, 17}, - {17, 17, 17, 17}, - }, - { - {16, 17, 17, 17}, - {17, 17, 17, 17}, - {17, 17, 17, 17}, - {17, 17, 17, 17}, - }, - { - {17, 17, 17, 17}, - {17, 17, 17, 17}, - {17, 17, 17, 17}, - {18, 17, 17, 17}, - }, - { - {17, 17, 17, 17}, - {17, 17, 18, 17}, - {17, 17, 17, 17}, - {18, 17, 18, 17}, - }, - { - {17, 17, 17, 17}, - {18, 17, 18, 17}, - {17, 18, 17, 17}, - {18, 17, 18, 17}, - }, - { - {17, 17, 17, 18}, - {18, 17, 18, 17}, - {17, 18, 17, 18}, - {18, 17, 18, 17}, - }, - { - {17, 18, 17, 18}, - {18, 17, 18, 17}, - {17, 18, 17, 18}, - {18, 17, 18, 17}, - }, - { - {17, 18, 17, 18}, - {18, 17, 18, 18}, - {17, 18, 17, 18}, - {18, 18, 18, 17}, - }, - { - {17, 18, 17, 18}, - {18, 18, 18, 18}, - {17, 18, 17, 18}, - {18, 18, 18, 18}, - }, - { - {17, 18, 18, 18}, - {18, 18, 18, 18}, - {18, 18, 17, 18}, - {18, 18, 18, 18}, - }, - { - {18, 18, 18, 18}, - {18, 18, 18, 18}, - {18, 18, 18, 18}, - {18, 18, 18, 18}, - }, - { - {18, 18, 18, 18}, - {18, 18, 19, 18}, - {18, 18, 18, 18}, - {19, 18, 18, 18}, - }, - { - {18, 18, 18, 18}, - {19, 18, 19, 18}, - {18, 18, 18, 18}, - {19, 18, 19, 18}, - }, - { - {18, 18, 18, 19}, - {19, 18, 19, 18}, - {18, 19, 18, 18}, - {19, 18, 19, 18}, - }, - { - {18, 19, 18, 19}, - {19, 18, 19, 18}, - {18, 19, 18, 19}, - {19, 18, 19, 18}, - }, - { - {18, 19, 18, 19}, - {19, 18, 19, 19}, - {18, 19, 18, 19}, - {19, 19, 19, 18}, - }, - { - {18, 19, 18, 19}, - {19, 19, 19, 19}, - {18, 19, 18, 19}, - {19, 19, 19, 19}, - }, - { - {18, 19, 19, 19}, - {19, 19, 19, 19}, - {19, 19, 18, 19}, - {19, 19, 19, 19}, - }, - { - {19, 19, 19, 19}, - {19, 19, 19, 19}, - {19, 19, 19, 19}, - {19, 19, 19, 19}, - }, - { - {19, 19, 19, 19}, - {19, 19, 20, 19}, - {19, 19, 19, 19}, - {20, 19, 19, 19}, - }, - { - {19, 19, 19, 19}, - {20, 19, 20, 19}, - {19, 19, 19, 19}, - {20, 19, 20, 19}, - }, - { - {19, 19, 19, 20}, - {20, 19, 20, 19}, - {19, 20, 19, 19}, - {20, 19, 20, 19}, - }, - { - {19, 19, 19, 20}, - {20, 19, 20, 19}, - {19, 20, 19, 20}, - {20, 19, 20, 19}, - }, - { - {19, 20, 19, 20}, - {20, 19, 20, 19}, - {19, 20, 19, 20}, - {20, 20, 20, 19}, - }, - { - {19, 20, 19, 20}, - {20, 19, 20, 20}, - {19, 20, 19, 20}, - {20, 20, 20, 20}, - }, - { - {19, 20, 19, 20}, - {20, 20, 20, 20}, - {20, 20, 19, 20}, - {20, 20, 20, 20}, - }, - { - {19, 20, 20, 20}, - {20, 20, 20, 20}, - {20, 20, 20, 20}, - {20, 20, 20, 20}, - }, - { - {20, 20, 20, 20}, - {20, 20, 20, 20}, - {20, 20, 20, 20}, - {21, 20, 20, 20}, - }, - { - {20, 20, 20, 20}, - {20, 20, 21, 20}, - {20, 20, 20, 20}, - {21, 20, 21, 20}, - }, - { - {20, 20, 20, 20}, - {21, 20, 21, 20}, - {20, 21, 20, 20}, - {21, 20, 21, 20}, - }, - { - {20, 20, 20, 21}, - {21, 20, 21, 20}, - {20, 21, 20, 21}, - {21, 20, 21, 20}, - }, - { - {20, 21, 20, 21}, - {21, 20, 21, 20}, - {20, 21, 20, 21}, - {21, 21, 21, 20}, - }, - { - {20, 21, 20, 21}, - {21, 20, 21, 21}, - {20, 21, 20, 21}, - {21, 21, 21, 21}, - }, - { - {20, 21, 20, 21}, - {21, 21, 21, 21}, - {21, 21, 20, 21}, - {21, 21, 21, 21}, - }, - { - {20, 21, 21, 21}, - {21, 21, 21, 21}, - {21, 21, 21, 21}, - {21, 21, 21, 21}, - }, - { - {21, 21, 21, 21}, - {21, 21, 21, 21}, - {21, 21, 21, 21}, - {22, 21, 21, 21}, - }, - { - {21, 21, 21, 21}, - {21, 21, 22, 21}, - {21, 21, 21, 21}, - {22, 21, 22, 21}, - }, - { - {21, 21, 21, 21}, - {22, 21, 22, 21}, - {21, 22, 21, 21}, - {22, 21, 22, 21}, - }, - { - {21, 21, 21, 22}, - {22, 21, 22, 21}, - {21, 22, 21, 21}, - {22, 21, 22, 21}, - }, - { - {21, 22, 21, 22}, - {22, 21, 22, 21}, - {21, 22, 21, 22}, - {22, 21, 22, 21}, - }, - { - {21, 22, 21, 22}, - {22, 21, 22, 22}, - {21, 22, 21, 22}, - {22, 22, 22, 21}, - }, - { - {21, 22, 21, 22}, - {22, 22, 22, 22}, - {21, 22, 21, 22}, - {22, 22, 22, 22}, - }, - { - {21, 22, 22, 22}, - {22, 22, 22, 22}, - {22, 22, 21, 22}, - {22, 22, 22, 22}, - }, - { - {22, 22, 22, 22}, - {22, 22, 22, 22}, - {22, 22, 22, 22}, - {22, 22, 22, 22}, - }, - { - {22, 22, 22, 22}, - {22, 22, 23, 22}, - {22, 22, 22, 22}, - {23, 22, 22, 22}, - }, - { - {22, 22, 22, 22}, - {23, 22, 23, 22}, - {22, 22, 22, 22}, - {23, 22, 23, 22}, - }, - { - {22, 22, 22, 23}, - {23, 22, 23, 22}, - {22, 23, 22, 22}, - {23, 22, 23, 22}, - }, - { - {22, 23, 22, 23}, - {23, 22, 23, 22}, - {22, 23, 22, 23}, - {23, 22, 23, 22}, - }, - { - {22, 23, 22, 23}, - {23, 22, 23, 23}, - {22, 23, 22, 23}, - {23, 23, 23, 22}, - }, - { - {22, 23, 22, 23}, - {23, 23, 23, 23}, - {22, 23, 22, 23}, - {23, 23, 23, 23}, - }, - { - {22, 23, 23, 23}, - {23, 23, 23, 23}, - {23, 23, 22, 23}, - {23, 23, 23, 23}, - }, - { - {23, 23, 23, 23}, - {23, 23, 23, 23}, - {23, 23, 23, 23}, - {23, 23, 23, 23}, - }, - { - {23, 23, 23, 23}, - {23, 23, 24, 23}, - {23, 23, 23, 23}, - {24, 23, 23, 23}, - }, - { - {23, 23, 23, 23}, - {24, 23, 24, 23}, - {23, 23, 23, 23}, - {24, 23, 24, 23}, - }, - { - {23, 23, 23, 23}, - {24, 23, 24, 23}, - {23, 24, 23, 23}, - {24, 23, 24, 23}, - }, - { - {23, 23, 23, 24}, - {24, 23, 24, 23}, - {23, 24, 23, 24}, - {24, 23, 24, 23}, - }, - { - {23, 24, 23, 24}, - {24, 23, 24, 23}, - {23, 24, 23, 24}, - {24, 24, 24, 23}, - }, - { - {23, 24, 23, 24}, - {24, 23, 24, 24}, - {23, 24, 23, 24}, - {24, 24, 24, 24}, - }, - { - {23, 24, 23, 24}, - {24, 24, 24, 24}, - {24, 24, 23, 24}, - {24, 24, 24, 24}, - }, - { - {23, 24, 24, 24}, - {24, 24, 24, 24}, - {24, 24, 24, 24}, - {24, 24, 24, 24}, - }, - { - {24, 24, 24, 24}, - {24, 24, 24, 24}, - {24, 24, 24, 24}, - {25, 24, 24, 24}, - }, - { - {24, 24, 24, 24}, - {24, 24, 25, 24}, - {24, 24, 24, 24}, - {25, 24, 25, 24}, - }, - { - {24, 24, 24, 24}, - {25, 24, 25, 24}, - {24, 25, 24, 24}, - {25, 24, 25, 24}, - }, - { - {24, 24, 24, 25}, - {25, 24, 25, 24}, - {24, 25, 24, 25}, - {25, 24, 25, 24}, - }, - { - {24, 25, 24, 25}, - {25, 24, 25, 24}, - {24, 25, 24, 25}, - {25, 25, 25, 24}, - }, - { - {24, 25, 24, 25}, - {25, 24, 25, 25}, - {24, 25, 24, 25}, - {25, 25, 25, 25}, - }, - { - {24, 25, 24, 25}, - {25, 25, 25, 25}, - {25, 25, 24, 25}, - {25, 25, 25, 25}, - }, - { - {24, 25, 25, 25}, - {25, 25, 25, 25}, - {25, 25, 25, 25}, - {25, 25, 25, 25}, - }, - { - {25, 25, 25, 25}, - {25, 25, 25, 25}, - {25, 25, 25, 25}, - {26, 25, 25, 25}, - }, - { - {25, 25, 25, 25}, - {25, 25, 26, 25}, - {25, 25, 25, 25}, - {26, 25, 26, 25}, - }, - { - {25, 25, 25, 25}, - {26, 25, 26, 25}, - {25, 25, 25, 25}, - {26, 25, 26, 25}, - }, - { - {25, 25, 25, 26}, - {26, 25, 26, 25}, - {25, 26, 25, 25}, - {26, 25, 26, 25}, - }, - { - {25, 26, 25, 26}, - {26, 25, 26, 25}, - {25, 26, 25, 26}, - {26, 25, 26, 25}, - }, - { - {25, 26, 25, 26}, - {26, 25, 26, 26}, - {25, 26, 25, 26}, - {26, 26, 26, 25}, - }, - { - {25, 26, 25, 26}, - {26, 26, 26, 26}, - {25, 26, 25, 26}, - {26, 26, 26, 26}, - }, - { - {25, 26, 26, 26}, - {26, 26, 26, 26}, - {26, 26, 25, 26}, - {26, 26, 26, 26}, - }, - { - {26, 26, 26, 26}, - {26, 26, 26, 26}, - {26, 26, 26, 26}, - {26, 26, 26, 26}, - }, - { - {26, 26, 26, 26}, - {26, 26, 27, 26}, - {26, 26, 26, 26}, - {27, 26, 26, 26}, - }, - { - {26, 26, 26, 26}, - {27, 26, 27, 26}, - {26, 26, 26, 26}, - {27, 26, 27, 26}, - }, - { - {26, 26, 26, 27}, - {27, 26, 27, 26}, - {26, 27, 26, 26}, - {27, 26, 27, 26}, - }, - { - {26, 27, 26, 27}, - {27, 26, 27, 26}, - {26, 27, 26, 27}, - {27, 26, 27, 26}, - }, - { - {26, 27, 26, 27}, - {27, 26, 27, 27}, - {26, 27, 26, 27}, - {27, 27, 27, 26}, - }, - { - {26, 27, 26, 27}, - {27, 27, 27, 27}, - {26, 27, 26, 27}, - {27, 27, 27, 27}, - }, - { - {26, 27, 27, 27}, - {27, 27, 27, 27}, - {27, 27, 26, 27}, - {27, 27, 27, 27}, - }, - { - {27, 27, 27, 27}, - {27, 27, 27, 27}, - {27, 27, 27, 27}, - {27, 27, 27, 27}, - }, - { - {27, 27, 27, 27}, - {27, 27, 28, 27}, - {27, 27, 27, 27}, - {28, 27, 27, 27}, - }, - { - {27, 27, 27, 27}, - {27, 27, 28, 27}, - {27, 27, 27, 27}, - {28, 27, 28, 27}, - }, - { - {27, 27, 27, 27}, - {28, 27, 28, 27}, - {27, 28, 27, 27}, - {28, 27, 28, 27}, - }, - { - {27, 27, 27, 28}, - {28, 27, 28, 27}, - {27, 28, 27, 28}, - {28, 27, 28, 27}, - }, - { - {27, 28, 27, 28}, - {28, 27, 28, 27}, - {27, 28, 27, 28}, - {28, 28, 28, 27}, - }, - { - {27, 28, 27, 28}, - {28, 27, 28, 28}, - {27, 28, 27, 28}, - {28, 28, 28, 28}, - }, - { - {27, 28, 27, 28}, - {28, 28, 28, 28}, - {28, 28, 27, 28}, - {28, 28, 28, 28}, - }, - { - {27, 28, 28, 28}, - {28, 28, 28, 28}, - {28, 28, 28, 28}, - {28, 28, 28, 28}, - }, - { - {28, 28, 28, 28}, - {28, 28, 28, 28}, - {28, 28, 28, 28}, - {29, 28, 28, 28}, - }, - { - {28, 28, 28, 28}, - {28, 28, 29, 28}, - {28, 28, 28, 28}, - {29, 28, 29, 28}, - }, - { - {28, 28, 28, 28}, - {29, 28, 29, 28}, - {28, 29, 28, 28}, - {29, 28, 29, 28}, - }, - { - {28, 28, 28, 29}, - {29, 28, 29, 28}, - {28, 29, 28, 29}, - {29, 28, 29, 28}, - }, - { - {28, 29, 28, 29}, - {29, 28, 29, 28}, - {28, 29, 28, 29}, - {29, 29, 29, 28}, - }, - { - {28, 29, 28, 29}, - {29, 28, 29, 29}, - {28, 29, 28, 29}, - {29, 29, 29, 29}, - }, - { - {28, 29, 28, 29}, - {29, 29, 29, 29}, - {29, 29, 28, 29}, - {29, 29, 29, 29}, - }, - { - {28, 29, 29, 29}, - {29, 29, 29, 29}, - {29, 29, 29, 29}, - {29, 29, 29, 29}, - }, - { - {29, 29, 29, 29}, - {29, 29, 29, 29}, - {29, 29, 29, 29}, - {30, 29, 29, 29}, - }, - { - {29, 29, 29, 29}, - {29, 29, 30, 29}, - {29, 29, 29, 29}, - {30, 29, 29, 29}, - }, - { - {29, 29, 29, 29}, - {30, 29, 30, 29}, - {29, 29, 29, 29}, - {30, 29, 30, 29}, - }, - { - {29, 29, 29, 30}, - {30, 29, 30, 29}, - {29, 30, 29, 29}, - {30, 29, 30, 29}, - }, - { - {29, 30, 29, 30}, - {30, 29, 30, 29}, - {29, 30, 29, 30}, - {30, 29, 30, 29}, - }, - { - {29, 30, 29, 30}, - {30, 29, 30, 30}, - {29, 30, 29, 30}, - {30, 30, 30, 29}, - }, - { - {29, 30, 29, 30}, - {30, 30, 30, 30}, - {29, 30, 29, 30}, - {30, 30, 30, 30}, - }, - { - {29, 30, 30, 30}, - {30, 30, 30, 30}, - {30, 30, 29, 30}, - {30, 30, 30, 30}, - }, - { - {30, 30, 30, 30}, - {30, 30, 30, 30}, - {30, 30, 30, 30}, - {30, 30, 30, 30}, - }, - { - {30, 30, 30, 30}, - {30, 30, 31, 30}, - {30, 30, 30, 30}, - {31, 30, 30, 30}, - }, - { - {30, 30, 30, 30}, - {31, 30, 31, 30}, - {30, 30, 30, 30}, - {31, 30, 31, 30}, - }, - { - {30, 30, 30, 31}, - {31, 30, 31, 30}, - {30, 31, 30, 30}, - {31, 30, 31, 30}, - }, - { - {30, 31, 30, 31}, - {31, 30, 31, 30}, - {30, 31, 30, 31}, - {31, 30, 31, 30}, - }, - { - {30, 31, 30, 31}, - {31, 30, 31, 31}, - {30, 31, 30, 31}, - {31, 31, 31, 30}, - }, - { - {30, 31, 30, 31}, - {31, 31, 31, 31}, - {30, 31, 30, 31}, - {31, 31, 31, 31}, - }, - { - {30, 31, 31, 31}, - {31, 31, 31, 31}, - {31, 31, 30, 31}, - {31, 31, 31, 31}, - }, - { - {31, 31, 31, 31}, - {31, 31, 31, 31}, - {31, 31, 31, 31}, - {31, 31, 31, 31}, - }, +static const uint8_t dither_rb[256][4][4] = { + { + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + }, + { + {0, 0, 0, 0}, + {0, 0, 1, 0}, + {0, 0, 0, 0}, + {1, 0, 0, 0}, + }, + { + {0, 0, 0, 0}, + {1, 0, 1, 0}, + {0, 0, 0, 0}, + {1, 0, 1, 0}, + }, + { + {0, 0, 0, 1}, + {1, 0, 1, 0}, + {0, 1, 0, 0}, + {1, 0, 1, 0}, + }, + { + {0, 1, 0, 1}, + {1, 0, 1, 0}, + {0, 1, 0, 1}, + {1, 0, 1, 0}, + }, + { + {0, 1, 0, 1}, + {1, 0, 1, 1}, + {0, 1, 0, 1}, + {1, 1, 1, 0}, + }, + { + {0, 1, 0, 1}, + {1, 1, 1, 1}, + {0, 1, 0, 1}, + {1, 1, 1, 1}, + }, + { + {0, 1, 1, 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, 1, 1}, + {1, 1, 2, 1}, + {1, 1, 1, 1}, + {2, 1, 1, 1}, + }, + { + {1, 1, 1, 1}, + {2, 1, 2, 1}, + {1, 1, 1, 1}, + {2, 1, 2, 1}, + }, + { + {1, 1, 1, 2}, + {2, 1, 2, 1}, + {1, 2, 1, 1}, + {2, 1, 2, 1}, + }, + { + {1, 2, 1, 2}, + {2, 1, 2, 1}, + {1, 2, 1, 2}, + {2, 1, 2, 1}, + }, + { + {1, 2, 1, 2}, + {2, 1, 2, 2}, + {1, 2, 1, 2}, + {2, 2, 2, 1}, + }, + { + {1, 2, 1, 2}, + {2, 2, 2, 2}, + {1, 2, 1, 2}, + {2, 2, 2, 2}, + }, + { + {1, 2, 2, 2}, + {2, 2, 2, 2}, + {2, 2, 1, 2}, + {2, 2, 2, 2}, + }, + { + {1, 2, 2, 2}, + {2, 2, 2, 2}, + {2, 2, 2, 2}, + {2, 2, 2, 2}, + }, + { + {2, 2, 2, 2}, + {2, 2, 2, 2}, + {2, 2, 2, 2}, + {3, 2, 2, 2}, + }, + { + {2, 2, 2, 2}, + {2, 2, 3, 2}, + {2, 2, 2, 2}, + {3, 2, 3, 2}, + }, + { + {2, 2, 2, 2}, + {3, 2, 3, 2}, + {2, 3, 2, 2}, + {3, 2, 3, 2}, + }, + { + {2, 2, 2, 3}, + {3, 2, 3, 2}, + {2, 3, 2, 3}, + {3, 2, 3, 2}, + }, + { + {2, 3, 2, 3}, + {3, 2, 3, 2}, + {2, 3, 2, 3}, + {3, 3, 3, 2}, + }, + { + {2, 3, 2, 3}, + {3, 2, 3, 3}, + {2, 3, 2, 3}, + {3, 3, 3, 3}, + }, + { + {2, 3, 2, 3}, + {3, 3, 3, 3}, + {3, 3, 2, 3}, + {3, 3, 3, 3}, + }, + { + {2, 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}, + {4, 3, 3, 3}, + }, + { + {3, 3, 3, 3}, + {3, 3, 4, 3}, + {3, 3, 3, 3}, + {4, 3, 4, 3}, + }, + { + {3, 3, 3, 3}, + {4, 3, 4, 3}, + {3, 4, 3, 3}, + {4, 3, 4, 3}, + }, + { + {3, 3, 3, 4}, + {4, 3, 4, 3}, + {3, 4, 3, 4}, + {4, 3, 4, 3}, + }, + { + {3, 4, 3, 4}, + {4, 3, 4, 3}, + {3, 4, 3, 4}, + {4, 4, 4, 3}, + }, + { + {3, 4, 3, 4}, + {4, 3, 4, 4}, + {3, 4, 3, 4}, + {4, 4, 4, 4}, + }, + { + {3, 4, 3, 4}, + {4, 4, 4, 4}, + {4, 4, 3, 4}, + {4, 4, 4, 4}, + }, + { + {3, 4, 4, 4}, + {4, 4, 4, 4}, + {4, 4, 3, 4}, + {4, 4, 4, 4}, + }, + { + {4, 4, 4, 4}, + {4, 4, 4, 4}, + {4, 4, 4, 4}, + {4, 4, 4, 4}, + }, + { + {4, 4, 4, 4}, + {4, 4, 5, 4}, + {4, 4, 4, 4}, + {5, 4, 4, 4}, + }, + { + {4, 4, 4, 4}, + {5, 4, 5, 4}, + {4, 4, 4, 4}, + {5, 4, 5, 4}, + }, + { + {4, 4, 4, 5}, + {5, 4, 5, 4}, + {4, 5, 4, 4}, + {5, 4, 5, 4}, + }, + { + {4, 5, 4, 5}, + {5, 4, 5, 4}, + {4, 5, 4, 5}, + {5, 4, 5, 4}, + }, + { + {4, 5, 4, 5}, + {5, 4, 5, 5}, + {4, 5, 4, 5}, + {5, 5, 5, 4}, + }, + { + {4, 5, 4, 5}, + {5, 5, 5, 5}, + {4, 5, 4, 5}, + {5, 5, 5, 5}, + }, + { + {4, 5, 5, 5}, + {5, 5, 5, 5}, + {5, 5, 4, 5}, + {5, 5, 5, 5}, + }, + { + {5, 5, 5, 5}, + {5, 5, 5, 5}, + {5, 5, 5, 5}, + {5, 5, 5, 5}, + }, + { + {5, 5, 5, 5}, + {5, 5, 6, 5}, + {5, 5, 5, 5}, + {6, 5, 5, 5}, + }, + { + {5, 5, 5, 5}, + {6, 5, 6, 5}, + {5, 5, 5, 5}, + {6, 5, 6, 5}, + }, + { + {5, 5, 5, 6}, + {6, 5, 6, 5}, + {5, 6, 5, 5}, + {6, 5, 6, 5}, + }, + { + {5, 6, 5, 6}, + {6, 5, 6, 5}, + {5, 6, 5, 6}, + {6, 5, 6, 5}, + }, + { + {5, 6, 5, 6}, + {6, 5, 6, 6}, + {5, 6, 5, 6}, + {6, 6, 6, 5}, + }, + { + {5, 6, 5, 6}, + {6, 6, 6, 6}, + {5, 6, 5, 6}, + {6, 6, 6, 6}, + }, + { + {5, 6, 5, 6}, + {6, 6, 6, 6}, + {6, 6, 5, 6}, + {6, 6, 6, 6}, + }, + { + {5, 6, 6, 6}, + {6, 6, 6, 6}, + {6, 6, 6, 6}, + {6, 6, 6, 6}, + }, + { + {6, 6, 6, 6}, + {6, 6, 6, 6}, + {6, 6, 6, 6}, + {7, 6, 6, 6}, + }, + { + {6, 6, 6, 6}, + {6, 6, 7, 6}, + {6, 6, 6, 6}, + {7, 6, 7, 6}, + }, + { + {6, 6, 6, 6}, + {7, 6, 7, 6}, + {6, 7, 6, 6}, + {7, 6, 7, 6}, + }, + { + {6, 6, 6, 7}, + {7, 6, 7, 6}, + {6, 7, 6, 7}, + {7, 6, 7, 6}, + }, + { + {6, 7, 6, 7}, + {7, 6, 7, 6}, + {6, 7, 6, 7}, + {7, 7, 7, 6}, + }, + { + {6, 7, 6, 7}, + {7, 6, 7, 7}, + {6, 7, 6, 7}, + {7, 7, 7, 7}, + }, + { + {6, 7, 6, 7}, + {7, 7, 7, 7}, + {7, 7, 6, 7}, + {7, 7, 7, 7}, + }, + { + {6, 7, 7, 7}, + {7, 7, 7, 7}, + {7, 7, 7, 7}, + {7, 7, 7, 7}, + }, + { + {7, 7, 7, 7}, + {7, 7, 7, 7}, + {7, 7, 7, 7}, + {8, 7, 7, 7}, + }, + { + {7, 7, 7, 7}, + {7, 7, 8, 7}, + {7, 7, 7, 7}, + {8, 7, 8, 7}, + }, + { + {7, 7, 7, 7}, + {8, 7, 8, 7}, + {7, 8, 7, 7}, + {8, 7, 8, 7}, + }, + { + {7, 7, 7, 8}, + {8, 7, 8, 7}, + {7, 8, 7, 8}, + {8, 7, 8, 7}, + }, + { + {7, 8, 7, 8}, + {8, 7, 8, 7}, + {7, 8, 7, 8}, + {8, 8, 8, 7}, + }, + { + {7, 8, 7, 8}, + {8, 7, 8, 8}, + {7, 8, 7, 8}, + {8, 8, 8, 8}, + }, + { + {7, 8, 7, 8}, + {8, 8, 8, 8}, + {7, 8, 7, 8}, + {8, 8, 8, 8}, + }, + { + {7, 8, 8, 8}, + {8, 8, 8, 8}, + {8, 8, 7, 8}, + {8, 8, 8, 8}, + }, + { + {8, 8, 8, 8}, + {8, 8, 8, 8}, + {8, 8, 8, 8}, + {8, 8, 8, 8}, + }, + { + {8, 8, 8, 8}, + {8, 8, 9, 8}, + {8, 8, 8, 8}, + {9, 8, 8, 8}, + }, + { + {8, 8, 8, 8}, + {9, 8, 9, 8}, + {8, 8, 8, 8}, + {9, 8, 9, 8}, + }, + { + {8, 8, 8, 9}, + {9, 8, 9, 8}, + {8, 9, 8, 8}, + {9, 8, 9, 8}, + }, + { + {8, 9, 8, 9}, + {9, 8, 9, 8}, + {8, 9, 8, 9}, + {9, 8, 9, 8}, + }, + { + {8, 9, 8, 9}, + {9, 8, 9, 9}, + {8, 9, 8, 9}, + {9, 9, 9, 8}, + }, + { + {8, 9, 8, 9}, + {9, 9, 9, 9}, + {8, 9, 8, 9}, + {9, 9, 9, 9}, + }, + { + {8, 9, 9, 9}, + {9, 9, 9, 9}, + {9, 9, 8, 9}, + {9, 9, 9, 9}, + }, + { + {9, 9, 9, 9}, + {9, 9, 9, 9}, + {9, 9, 9, 9}, + {9, 9, 9, 9}, + }, + { + {9, 9, 9, 9}, + {9, 9, 10, 9}, + {9, 9, 9, 9}, + {10, 9, 9, 9}, + }, + { + {9, 9, 9, 9}, + {10, 9, 10, 9}, + {9, 9, 9, 9}, + {10, 9, 10, 9}, + }, + { + {9, 9, 9, 10}, + {10, 9, 10, 9}, + {9, 10, 9, 9}, + {10, 9, 10, 9}, + }, + { + {9, 10, 9, 10}, + {10, 9, 10, 9}, + {9, 10, 9, 10}, + {10, 9, 10, 9}, + }, + { + {9, 10, 9, 10}, + {10, 9, 10, 10}, + {9, 10, 9, 10}, + {10, 10, 10, 9}, + }, + { + {9, 10, 9, 10}, + {10, 9, 10, 10}, + {9, 10, 9, 10}, + {10, 10, 10, 10}, + }, + { + {9, 10, 9, 10}, + {10, 10, 10, 10}, + {10, 10, 9, 10}, + {10, 10, 10, 10}, + }, + { + {9, 10, 10, 10}, + {10, 10, 10, 10}, + {10, 10, 10, 10}, + {10, 10, 10, 10}, + }, + { + {10, 10, 10, 10}, + {10, 10, 10, 10}, + {10, 10, 10, 10}, + {11, 10, 10, 10}, + }, + { + {10, 10, 10, 10}, + {10, 10, 11, 10}, + {10, 10, 10, 10}, + {11, 10, 11, 10}, + }, + { + {10, 10, 10, 10}, + {11, 10, 11, 10}, + {10, 11, 10, 10}, + {11, 10, 11, 10}, + }, + { + {10, 10, 10, 11}, + {11, 10, 11, 10}, + {10, 11, 10, 11}, + {11, 10, 11, 10}, + }, + { + {10, 11, 10, 11}, + {11, 10, 11, 10}, + {10, 11, 10, 11}, + {11, 11, 11, 10}, + }, + { + {10, 11, 10, 11}, + {11, 10, 11, 11}, + {10, 11, 10, 11}, + {11, 11, 11, 11}, + }, + { + {10, 11, 10, 11}, + {11, 11, 11, 11}, + {11, 11, 10, 11}, + {11, 11, 11, 11}, + }, + { + {10, 11, 11, 11}, + {11, 11, 11, 11}, + {11, 11, 11, 11}, + {11, 11, 11, 11}, + }, + { + {11, 11, 11, 11}, + {11, 11, 11, 11}, + {11, 11, 11, 11}, + {12, 11, 11, 11}, + }, + { + {11, 11, 11, 11}, + {11, 11, 12, 11}, + {11, 11, 11, 11}, + {12, 11, 12, 11}, + }, + { + {11, 11, 11, 11}, + {12, 11, 12, 11}, + {11, 12, 11, 11}, + {12, 11, 12, 11}, + }, + { + {11, 11, 11, 12}, + {12, 11, 12, 11}, + {11, 12, 11, 12}, + {12, 11, 12, 11}, + }, + { + {11, 12, 11, 12}, + {12, 11, 12, 11}, + {11, 12, 11, 12}, + {12, 12, 12, 11}, + }, + { + {11, 12, 11, 12}, + {12, 11, 12, 12}, + {11, 12, 11, 12}, + {12, 12, 12, 11}, + }, + { + {11, 12, 11, 12}, + {12, 12, 12, 12}, + {11, 12, 11, 12}, + {12, 12, 12, 12}, + }, + { + {11, 12, 12, 12}, + {12, 12, 12, 12}, + {12, 12, 11, 12}, + {12, 12, 12, 12}, + }, + { + {12, 12, 12, 12}, + {12, 12, 12, 12}, + {12, 12, 12, 12}, + {12, 12, 12, 12}, + }, + { + {12, 12, 12, 12}, + {12, 12, 13, 12}, + {12, 12, 12, 12}, + {13, 12, 12, 12}, + }, + { + {12, 12, 12, 12}, + {13, 12, 13, 12}, + {12, 12, 12, 12}, + {13, 12, 13, 12}, + }, + { + {12, 12, 12, 13}, + {13, 12, 13, 12}, + {12, 13, 12, 12}, + {13, 12, 13, 12}, + }, + { + {12, 13, 12, 13}, + {13, 12, 13, 12}, + {12, 13, 12, 13}, + {13, 12, 13, 12}, + }, + { + {12, 13, 12, 13}, + {13, 12, 13, 13}, + {12, 13, 12, 13}, + {13, 13, 13, 12}, + }, + { + {12, 13, 12, 13}, + {13, 13, 13, 13}, + {12, 13, 12, 13}, + {13, 13, 13, 13}, + }, + { + {12, 13, 13, 13}, + {13, 13, 13, 13}, + {13, 13, 12, 13}, + {13, 13, 13, 13}, + }, + { + {13, 13, 13, 13}, + {13, 13, 13, 13}, + {13, 13, 13, 13}, + {13, 13, 13, 13}, + }, + { + {13, 13, 13, 13}, + {13, 13, 14, 13}, + {13, 13, 13, 13}, + {14, 13, 13, 13}, + }, + { + {13, 13, 13, 13}, + {14, 13, 14, 13}, + {13, 13, 13, 13}, + {14, 13, 14, 13}, + }, + { + {13, 13, 13, 14}, + {14, 13, 14, 13}, + {13, 14, 13, 13}, + {14, 13, 14, 13}, + }, + { + {13, 14, 13, 14}, + {14, 13, 14, 13}, + {13, 14, 13, 14}, + {14, 13, 14, 13}, + }, + { + {13, 14, 13, 14}, + {14, 13, 14, 13}, + {13, 14, 13, 14}, + {14, 14, 14, 13}, + }, + { + {13, 14, 13, 14}, + {14, 13, 14, 14}, + {13, 14, 13, 14}, + {14, 14, 14, 14}, + }, + { + {13, 14, 13, 14}, + {14, 14, 14, 14}, + {14, 14, 13, 14}, + {14, 14, 14, 14}, + }, + { + {13, 14, 14, 14}, + {14, 14, 14, 14}, + {14, 14, 14, 14}, + {14, 14, 14, 14}, + }, + { + {14, 14, 14, 14}, + {14, 14, 14, 14}, + {14, 14, 14, 14}, + {15, 14, 14, 14}, + }, + { + {14, 14, 14, 14}, + {14, 14, 15, 14}, + {14, 14, 14, 14}, + {15, 14, 15, 14}, + }, + { + {14, 14, 14, 14}, + {15, 14, 15, 14}, + {14, 15, 14, 14}, + {15, 14, 15, 14}, + }, + { + {14, 14, 14, 15}, + {15, 14, 15, 14}, + {14, 15, 14, 15}, + {15, 14, 15, 14}, + }, + { + {14, 15, 14, 15}, + {15, 14, 15, 14}, + {14, 15, 14, 15}, + {15, 15, 15, 14}, + }, + { + {14, 15, 14, 15}, + {15, 14, 15, 15}, + {14, 15, 14, 15}, + {15, 15, 15, 15}, + }, + { + {14, 15, 14, 15}, + {15, 15, 15, 15}, + {15, 15, 14, 15}, + {15, 15, 15, 15}, + }, + { + {14, 15, 15, 15}, + {15, 15, 15, 15}, + {15, 15, 15, 15}, + {15, 15, 15, 15}, + }, + { + {15, 15, 15, 15}, + {15, 15, 15, 15}, + {15, 15, 15, 15}, + {16, 15, 15, 15}, + }, + { + {15, 15, 15, 15}, + {15, 15, 16, 15}, + {15, 15, 15, 15}, + {16, 15, 16, 15}, + }, + { + {15, 15, 15, 15}, + {16, 15, 16, 15}, + {15, 16, 15, 15}, + {16, 15, 16, 15}, + }, + { + {15, 15, 15, 16}, + {16, 15, 16, 15}, + {15, 16, 15, 16}, + {16, 15, 16, 15}, + }, + { + {15, 16, 15, 16}, + {16, 15, 16, 15}, + {15, 16, 15, 16}, + {16, 16, 16, 15}, + }, + { + {15, 16, 15, 16}, + {16, 15, 16, 16}, + {15, 16, 15, 16}, + {16, 16, 16, 16}, + }, + { + {15, 16, 15, 16}, + {16, 16, 16, 16}, + {16, 16, 15, 16}, + {16, 16, 16, 16}, + }, + { + {15, 16, 16, 16}, + {16, 16, 16, 16}, + {16, 16, 16, 16}, + {16, 16, 16, 16}, + }, + { + {16, 16, 16, 16}, + {16, 16, 16, 16}, + {16, 16, 16, 16}, + {17, 16, 16, 16}, + }, + { + {16, 16, 16, 16}, + {16, 16, 17, 16}, + {16, 16, 16, 16}, + {17, 16, 17, 16}, + }, + { + {16, 16, 16, 16}, + {17, 16, 17, 16}, + {16, 17, 16, 16}, + {17, 16, 17, 16}, + }, + { + {16, 16, 16, 17}, + {17, 16, 17, 16}, + {16, 17, 16, 17}, + {17, 16, 17, 16}, + }, + { + {16, 17, 16, 17}, + {17, 16, 17, 16}, + {16, 17, 16, 17}, + {17, 17, 17, 16}, + }, + { + {16, 17, 16, 17}, + {17, 16, 17, 17}, + {16, 17, 16, 17}, + {17, 17, 17, 17}, + }, + { + {16, 17, 16, 17}, + {17, 17, 17, 17}, + {17, 17, 16, 17}, + {17, 17, 17, 17}, + }, + { + {16, 17, 17, 17}, + {17, 17, 17, 17}, + {17, 17, 17, 17}, + {17, 17, 17, 17}, + }, + { + {17, 17, 17, 17}, + {17, 17, 17, 17}, + {17, 17, 17, 17}, + {18, 17, 17, 17}, + }, + { + {17, 17, 17, 17}, + {17, 17, 18, 17}, + {17, 17, 17, 17}, + {18, 17, 18, 17}, + }, + { + {17, 17, 17, 17}, + {18, 17, 18, 17}, + {17, 18, 17, 17}, + {18, 17, 18, 17}, + }, + { + {17, 17, 17, 18}, + {18, 17, 18, 17}, + {17, 18, 17, 18}, + {18, 17, 18, 17}, + }, + { + {17, 18, 17, 18}, + {18, 17, 18, 17}, + {17, 18, 17, 18}, + {18, 17, 18, 17}, + }, + { + {17, 18, 17, 18}, + {18, 17, 18, 18}, + {17, 18, 17, 18}, + {18, 18, 18, 17}, + }, + { + {17, 18, 17, 18}, + {18, 18, 18, 18}, + {17, 18, 17, 18}, + {18, 18, 18, 18}, + }, + { + {17, 18, 18, 18}, + {18, 18, 18, 18}, + {18, 18, 17, 18}, + {18, 18, 18, 18}, + }, + { + {18, 18, 18, 18}, + {18, 18, 18, 18}, + {18, 18, 18, 18}, + {18, 18, 18, 18}, + }, + { + {18, 18, 18, 18}, + {18, 18, 19, 18}, + {18, 18, 18, 18}, + {19, 18, 18, 18}, + }, + { + {18, 18, 18, 18}, + {19, 18, 19, 18}, + {18, 18, 18, 18}, + {19, 18, 19, 18}, + }, + { + {18, 18, 18, 19}, + {19, 18, 19, 18}, + {18, 19, 18, 18}, + {19, 18, 19, 18}, + }, + { + {18, 19, 18, 19}, + {19, 18, 19, 18}, + {18, 19, 18, 19}, + {19, 18, 19, 18}, + }, + { + {18, 19, 18, 19}, + {19, 18, 19, 19}, + {18, 19, 18, 19}, + {19, 19, 19, 18}, + }, + { + {18, 19, 18, 19}, + {19, 19, 19, 19}, + {18, 19, 18, 19}, + {19, 19, 19, 19}, + }, + { + {18, 19, 19, 19}, + {19, 19, 19, 19}, + {19, 19, 18, 19}, + {19, 19, 19, 19}, + }, + { + {19, 19, 19, 19}, + {19, 19, 19, 19}, + {19, 19, 19, 19}, + {19, 19, 19, 19}, + }, + { + {19, 19, 19, 19}, + {19, 19, 20, 19}, + {19, 19, 19, 19}, + {20, 19, 19, 19}, + }, + { + {19, 19, 19, 19}, + {20, 19, 20, 19}, + {19, 19, 19, 19}, + {20, 19, 20, 19}, + }, + { + {19, 19, 19, 20}, + {20, 19, 20, 19}, + {19, 20, 19, 19}, + {20, 19, 20, 19}, + }, + { + {19, 19, 19, 20}, + {20, 19, 20, 19}, + {19, 20, 19, 20}, + {20, 19, 20, 19}, + }, + { + {19, 20, 19, 20}, + {20, 19, 20, 19}, + {19, 20, 19, 20}, + {20, 20, 20, 19}, + }, + { + {19, 20, 19, 20}, + {20, 19, 20, 20}, + {19, 20, 19, 20}, + {20, 20, 20, 20}, + }, + { + {19, 20, 19, 20}, + {20, 20, 20, 20}, + {20, 20, 19, 20}, + {20, 20, 20, 20}, + }, + { + {19, 20, 20, 20}, + {20, 20, 20, 20}, + {20, 20, 20, 20}, + {20, 20, 20, 20}, + }, + { + {20, 20, 20, 20}, + {20, 20, 20, 20}, + {20, 20, 20, 20}, + {21, 20, 20, 20}, + }, + { + {20, 20, 20, 20}, + {20, 20, 21, 20}, + {20, 20, 20, 20}, + {21, 20, 21, 20}, + }, + { + {20, 20, 20, 20}, + {21, 20, 21, 20}, + {20, 21, 20, 20}, + {21, 20, 21, 20}, + }, + { + {20, 20, 20, 21}, + {21, 20, 21, 20}, + {20, 21, 20, 21}, + {21, 20, 21, 20}, + }, + { + {20, 21, 20, 21}, + {21, 20, 21, 20}, + {20, 21, 20, 21}, + {21, 21, 21, 20}, + }, + { + {20, 21, 20, 21}, + {21, 20, 21, 21}, + {20, 21, 20, 21}, + {21, 21, 21, 21}, + }, + { + {20, 21, 20, 21}, + {21, 21, 21, 21}, + {21, 21, 20, 21}, + {21, 21, 21, 21}, + }, + { + {20, 21, 21, 21}, + {21, 21, 21, 21}, + {21, 21, 21, 21}, + {21, 21, 21, 21}, + }, + { + {21, 21, 21, 21}, + {21, 21, 21, 21}, + {21, 21, 21, 21}, + {22, 21, 21, 21}, + }, + { + {21, 21, 21, 21}, + {21, 21, 22, 21}, + {21, 21, 21, 21}, + {22, 21, 22, 21}, + }, + { + {21, 21, 21, 21}, + {22, 21, 22, 21}, + {21, 22, 21, 21}, + {22, 21, 22, 21}, + }, + { + {21, 21, 21, 22}, + {22, 21, 22, 21}, + {21, 22, 21, 21}, + {22, 21, 22, 21}, + }, + { + {21, 22, 21, 22}, + {22, 21, 22, 21}, + {21, 22, 21, 22}, + {22, 21, 22, 21}, + }, + { + {21, 22, 21, 22}, + {22, 21, 22, 22}, + {21, 22, 21, 22}, + {22, 22, 22, 21}, + }, + { + {21, 22, 21, 22}, + {22, 22, 22, 22}, + {21, 22, 21, 22}, + {22, 22, 22, 22}, + }, + { + {21, 22, 22, 22}, + {22, 22, 22, 22}, + {22, 22, 21, 22}, + {22, 22, 22, 22}, + }, + { + {22, 22, 22, 22}, + {22, 22, 22, 22}, + {22, 22, 22, 22}, + {22, 22, 22, 22}, + }, + { + {22, 22, 22, 22}, + {22, 22, 23, 22}, + {22, 22, 22, 22}, + {23, 22, 22, 22}, + }, + { + {22, 22, 22, 22}, + {23, 22, 23, 22}, + {22, 22, 22, 22}, + {23, 22, 23, 22}, + }, + { + {22, 22, 22, 23}, + {23, 22, 23, 22}, + {22, 23, 22, 22}, + {23, 22, 23, 22}, + }, + { + {22, 23, 22, 23}, + {23, 22, 23, 22}, + {22, 23, 22, 23}, + {23, 22, 23, 22}, + }, + { + {22, 23, 22, 23}, + {23, 22, 23, 23}, + {22, 23, 22, 23}, + {23, 23, 23, 22}, + }, + { + {22, 23, 22, 23}, + {23, 23, 23, 23}, + {22, 23, 22, 23}, + {23, 23, 23, 23}, + }, + { + {22, 23, 23, 23}, + {23, 23, 23, 23}, + {23, 23, 22, 23}, + {23, 23, 23, 23}, + }, + { + {23, 23, 23, 23}, + {23, 23, 23, 23}, + {23, 23, 23, 23}, + {23, 23, 23, 23}, + }, + { + {23, 23, 23, 23}, + {23, 23, 24, 23}, + {23, 23, 23, 23}, + {24, 23, 23, 23}, + }, + { + {23, 23, 23, 23}, + {24, 23, 24, 23}, + {23, 23, 23, 23}, + {24, 23, 24, 23}, + }, + { + {23, 23, 23, 23}, + {24, 23, 24, 23}, + {23, 24, 23, 23}, + {24, 23, 24, 23}, + }, + { + {23, 23, 23, 24}, + {24, 23, 24, 23}, + {23, 24, 23, 24}, + {24, 23, 24, 23}, + }, + { + {23, 24, 23, 24}, + {24, 23, 24, 23}, + {23, 24, 23, 24}, + {24, 24, 24, 23}, + }, + { + {23, 24, 23, 24}, + {24, 23, 24, 24}, + {23, 24, 23, 24}, + {24, 24, 24, 24}, + }, + { + {23, 24, 23, 24}, + {24, 24, 24, 24}, + {24, 24, 23, 24}, + {24, 24, 24, 24}, + }, + { + {23, 24, 24, 24}, + {24, 24, 24, 24}, + {24, 24, 24, 24}, + {24, 24, 24, 24}, + }, + { + {24, 24, 24, 24}, + {24, 24, 24, 24}, + {24, 24, 24, 24}, + {25, 24, 24, 24}, + }, + { + {24, 24, 24, 24}, + {24, 24, 25, 24}, + {24, 24, 24, 24}, + {25, 24, 25, 24}, + }, + { + {24, 24, 24, 24}, + {25, 24, 25, 24}, + {24, 25, 24, 24}, + {25, 24, 25, 24}, + }, + { + {24, 24, 24, 25}, + {25, 24, 25, 24}, + {24, 25, 24, 25}, + {25, 24, 25, 24}, + }, + { + {24, 25, 24, 25}, + {25, 24, 25, 24}, + {24, 25, 24, 25}, + {25, 25, 25, 24}, + }, + { + {24, 25, 24, 25}, + {25, 24, 25, 25}, + {24, 25, 24, 25}, + {25, 25, 25, 25}, + }, + { + {24, 25, 24, 25}, + {25, 25, 25, 25}, + {25, 25, 24, 25}, + {25, 25, 25, 25}, + }, + { + {24, 25, 25, 25}, + {25, 25, 25, 25}, + {25, 25, 25, 25}, + {25, 25, 25, 25}, + }, + { + {25, 25, 25, 25}, + {25, 25, 25, 25}, + {25, 25, 25, 25}, + {26, 25, 25, 25}, + }, + { + {25, 25, 25, 25}, + {25, 25, 26, 25}, + {25, 25, 25, 25}, + {26, 25, 26, 25}, + }, + { + {25, 25, 25, 25}, + {26, 25, 26, 25}, + {25, 25, 25, 25}, + {26, 25, 26, 25}, + }, + { + {25, 25, 25, 26}, + {26, 25, 26, 25}, + {25, 26, 25, 25}, + {26, 25, 26, 25}, + }, + { + {25, 26, 25, 26}, + {26, 25, 26, 25}, + {25, 26, 25, 26}, + {26, 25, 26, 25}, + }, + { + {25, 26, 25, 26}, + {26, 25, 26, 26}, + {25, 26, 25, 26}, + {26, 26, 26, 25}, + }, + { + {25, 26, 25, 26}, + {26, 26, 26, 26}, + {25, 26, 25, 26}, + {26, 26, 26, 26}, + }, + { + {25, 26, 26, 26}, + {26, 26, 26, 26}, + {26, 26, 25, 26}, + {26, 26, 26, 26}, + }, + { + {26, 26, 26, 26}, + {26, 26, 26, 26}, + {26, 26, 26, 26}, + {26, 26, 26, 26}, + }, + { + {26, 26, 26, 26}, + {26, 26, 27, 26}, + {26, 26, 26, 26}, + {27, 26, 26, 26}, + }, + { + {26, 26, 26, 26}, + {27, 26, 27, 26}, + {26, 26, 26, 26}, + {27, 26, 27, 26}, + }, + { + {26, 26, 26, 27}, + {27, 26, 27, 26}, + {26, 27, 26, 26}, + {27, 26, 27, 26}, + }, + { + {26, 27, 26, 27}, + {27, 26, 27, 26}, + {26, 27, 26, 27}, + {27, 26, 27, 26}, + }, + { + {26, 27, 26, 27}, + {27, 26, 27, 27}, + {26, 27, 26, 27}, + {27, 27, 27, 26}, + }, + { + {26, 27, 26, 27}, + {27, 27, 27, 27}, + {26, 27, 26, 27}, + {27, 27, 27, 27}, + }, + { + {26, 27, 27, 27}, + {27, 27, 27, 27}, + {27, 27, 26, 27}, + {27, 27, 27, 27}, + }, + { + {27, 27, 27, 27}, + {27, 27, 27, 27}, + {27, 27, 27, 27}, + {27, 27, 27, 27}, + }, + { + {27, 27, 27, 27}, + {27, 27, 28, 27}, + {27, 27, 27, 27}, + {28, 27, 27, 27}, + }, + { + {27, 27, 27, 27}, + {27, 27, 28, 27}, + {27, 27, 27, 27}, + {28, 27, 28, 27}, + }, + { + {27, 27, 27, 27}, + {28, 27, 28, 27}, + {27, 28, 27, 27}, + {28, 27, 28, 27}, + }, + { + {27, 27, 27, 28}, + {28, 27, 28, 27}, + {27, 28, 27, 28}, + {28, 27, 28, 27}, + }, + { + {27, 28, 27, 28}, + {28, 27, 28, 27}, + {27, 28, 27, 28}, + {28, 28, 28, 27}, + }, + { + {27, 28, 27, 28}, + {28, 27, 28, 28}, + {27, 28, 27, 28}, + {28, 28, 28, 28}, + }, + { + {27, 28, 27, 28}, + {28, 28, 28, 28}, + {28, 28, 27, 28}, + {28, 28, 28, 28}, + }, + { + {27, 28, 28, 28}, + {28, 28, 28, 28}, + {28, 28, 28, 28}, + {28, 28, 28, 28}, + }, + { + {28, 28, 28, 28}, + {28, 28, 28, 28}, + {28, 28, 28, 28}, + {29, 28, 28, 28}, + }, + { + {28, 28, 28, 28}, + {28, 28, 29, 28}, + {28, 28, 28, 28}, + {29, 28, 29, 28}, + }, + { + {28, 28, 28, 28}, + {29, 28, 29, 28}, + {28, 29, 28, 28}, + {29, 28, 29, 28}, + }, + { + {28, 28, 28, 29}, + {29, 28, 29, 28}, + {28, 29, 28, 29}, + {29, 28, 29, 28}, + }, + { + {28, 29, 28, 29}, + {29, 28, 29, 28}, + {28, 29, 28, 29}, + {29, 29, 29, 28}, + }, + { + {28, 29, 28, 29}, + {29, 28, 29, 29}, + {28, 29, 28, 29}, + {29, 29, 29, 29}, + }, + { + {28, 29, 28, 29}, + {29, 29, 29, 29}, + {29, 29, 28, 29}, + {29, 29, 29, 29}, + }, + { + {28, 29, 29, 29}, + {29, 29, 29, 29}, + {29, 29, 29, 29}, + {29, 29, 29, 29}, + }, + { + {29, 29, 29, 29}, + {29, 29, 29, 29}, + {29, 29, 29, 29}, + {30, 29, 29, 29}, + }, + { + {29, 29, 29, 29}, + {29, 29, 30, 29}, + {29, 29, 29, 29}, + {30, 29, 29, 29}, + }, + { + {29, 29, 29, 29}, + {30, 29, 30, 29}, + {29, 29, 29, 29}, + {30, 29, 30, 29}, + }, + { + {29, 29, 29, 30}, + {30, 29, 30, 29}, + {29, 30, 29, 29}, + {30, 29, 30, 29}, + }, + { + {29, 30, 29, 30}, + {30, 29, 30, 29}, + {29, 30, 29, 30}, + {30, 29, 30, 29}, + }, + { + {29, 30, 29, 30}, + {30, 29, 30, 30}, + {29, 30, 29, 30}, + {30, 30, 30, 29}, + }, + { + {29, 30, 29, 30}, + {30, 30, 30, 30}, + {29, 30, 29, 30}, + {30, 30, 30, 30}, + }, + { + {29, 30, 30, 30}, + {30, 30, 30, 30}, + {30, 30, 29, 30}, + {30, 30, 30, 30}, + }, + { + {30, 30, 30, 30}, + {30, 30, 30, 30}, + {30, 30, 30, 30}, + {30, 30, 30, 30}, + }, + { + {30, 30, 30, 30}, + {30, 30, 31, 30}, + {30, 30, 30, 30}, + {31, 30, 30, 30}, + }, + { + {30, 30, 30, 30}, + {31, 30, 31, 30}, + {30, 30, 30, 30}, + {31, 30, 31, 30}, + }, + { + {30, 30, 30, 31}, + {31, 30, 31, 30}, + {30, 31, 30, 30}, + {31, 30, 31, 30}, + }, + { + {30, 31, 30, 31}, + {31, 30, 31, 30}, + {30, 31, 30, 31}, + {31, 30, 31, 30}, + }, + { + {30, 31, 30, 31}, + {31, 30, 31, 31}, + {30, 31, 30, 31}, + {31, 31, 31, 30}, + }, + { + {30, 31, 30, 31}, + {31, 31, 31, 31}, + {30, 31, 30, 31}, + {31, 31, 31, 31}, + }, + { + {30, 31, 31, 31}, + {31, 31, 31, 31}, + {31, 31, 30, 31}, + {31, 31, 31, 31}, + }, + { + {31, 31, 31, 31}, + {31, 31, 31, 31}, + {31, 31, 31, 31}, + {31, 31, 31, 31}, + }, }; -static const uint8_t dither_g[256][4][4] = -{ - { - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - }, - { - {0, 0, 0, 0}, - {1, 0, 1, 0}, - {0, 0, 0, 0}, - {1, 0, 1, 0}, - }, - { - {0, 1, 0, 1}, - {1, 0, 1, 0}, - {0, 1, 0, 1}, - {1, 0, 1, 0}, - }, - { - {0, 1, 0, 1}, - {1, 1, 1, 1}, - {0, 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, 1, 1}, - {2, 1, 2, 1}, - {1, 1, 1, 1}, - {2, 1, 2, 1}, - }, - { - {1, 2, 1, 2}, - {2, 1, 2, 1}, - {1, 2, 1, 2}, - {2, 1, 2, 1}, - }, - { - {1, 2, 1, 2}, - {2, 2, 2, 2}, - {1, 2, 1, 2}, - {2, 2, 2, 2}, - }, - { - {2, 2, 2, 2}, - {2, 2, 2, 2}, - {2, 2, 2, 2}, - {2, 2, 2, 2}, - }, - { - {2, 2, 2, 2}, - {3, 2, 3, 2}, - {2, 2, 2, 2}, - {3, 2, 3, 2}, - }, - { - {2, 3, 2, 3}, - {3, 2, 3, 2}, - {2, 3, 2, 3}, - {3, 2, 3, 2}, - }, - { - {2, 3, 2, 3}, - {3, 3, 3, 3}, - {2, 3, 2, 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}, - {4, 3, 4, 3}, - {3, 3, 3, 3}, - {4, 3, 4, 3}, - }, - { - {3, 4, 3, 4}, - {4, 3, 4, 3}, - {3, 4, 3, 4}, - {4, 3, 4, 3}, - }, - { - {3, 4, 3, 4}, - {4, 4, 4, 4}, - {3, 4, 3, 4}, - {4, 4, 4, 4}, - }, - { - {3, 4, 4, 4}, - {4, 4, 4, 4}, - {4, 4, 4, 4}, - {4, 4, 4, 4}, - }, - { - {4, 4, 4, 4}, - {4, 4, 5, 4}, - {4, 4, 4, 4}, - {5, 4, 5, 4}, - }, - { - {4, 4, 4, 5}, - {5, 4, 5, 4}, - {4, 5, 4, 5}, - {5, 4, 5, 4}, - }, - { - {4, 5, 4, 5}, - {5, 4, 5, 5}, - {4, 5, 4, 5}, - {5, 5, 5, 5}, - }, - { - {4, 5, 5, 5}, - {5, 5, 5, 5}, - {5, 5, 5, 5}, - {5, 5, 5, 5}, - }, - { - {5, 5, 5, 5}, - {5, 5, 6, 5}, - {5, 5, 5, 5}, - {6, 5, 6, 5}, - }, - { - {5, 5, 5, 6}, - {6, 5, 6, 5}, - {5, 6, 5, 6}, - {6, 5, 6, 5}, - }, - { - {5, 6, 5, 6}, - {6, 5, 6, 6}, - {5, 6, 5, 6}, - {6, 6, 6, 6}, - }, - { - {5, 6, 6, 6}, - {6, 6, 6, 6}, - {6, 6, 6, 6}, - {6, 6, 6, 6}, - }, - { - {6, 6, 6, 6}, - {6, 6, 7, 6}, - {6, 6, 6, 6}, - {7, 6, 7, 6}, - }, - { - {6, 6, 6, 7}, - {7, 6, 7, 6}, - {6, 7, 6, 7}, - {7, 6, 7, 6}, - }, - { - {6, 7, 6, 7}, - {7, 6, 7, 7}, - {6, 7, 6, 7}, - {7, 7, 7, 7}, - }, - { - {6, 7, 7, 7}, - {7, 7, 7, 7}, - {7, 7, 7, 7}, - {7, 7, 7, 7}, - }, - { - {7, 7, 7, 7}, - {7, 7, 8, 7}, - {7, 7, 7, 7}, - {8, 7, 8, 7}, - }, - { - {7, 7, 7, 8}, - {8, 7, 8, 7}, - {7, 8, 7, 8}, - {8, 7, 8, 7}, - }, - { - {7, 8, 7, 8}, - {8, 7, 8, 8}, - {7, 8, 7, 8}, - {8, 8, 8, 8}, - }, - { - {7, 8, 8, 8}, - {8, 8, 8, 8}, - {8, 8, 7, 8}, - {8, 8, 8, 8}, - }, - { - {8, 8, 8, 8}, - {8, 8, 9, 8}, - {8, 8, 8, 8}, - {9, 8, 8, 8}, - }, - { - {8, 8, 8, 9}, - {9, 8, 9, 8}, - {8, 9, 8, 8}, - {9, 8, 9, 8}, - }, - { - {8, 9, 8, 9}, - {9, 8, 9, 9}, - {8, 9, 8, 9}, - {9, 9, 9, 8}, - }, - { - {8, 9, 9, 9}, - {9, 9, 9, 9}, - {9, 9, 8, 9}, - {9, 9, 9, 9}, - }, - { - {9, 9, 9, 9}, - {9, 9, 10, 9}, - {9, 9, 9, 9}, - {10, 9, 9, 9}, - }, - { - {9, 9, 9, 10}, - {10, 9, 10, 9}, - {9, 10, 9, 9}, - {10, 9, 10, 9}, - }, - { - {9, 10, 9, 10}, - {10, 9, 10, 10}, - {9, 10, 9, 10}, - {10, 10, 10, 9}, - }, - { - {9, 10, 10, 10}, - {10, 10, 10, 10}, - {10, 10, 9, 10}, - {10, 10, 10, 10}, - }, - { - {10, 10, 10, 10}, - {10, 10, 11, 10}, - {10, 10, 10, 10}, - {11, 10, 10, 10}, - }, - { - {10, 10, 10, 11}, - {11, 10, 11, 10}, - {10, 11, 10, 10}, - {11, 10, 11, 10}, - }, - { - {10, 11, 10, 11}, - {11, 10, 11, 11}, - {10, 11, 10, 11}, - {11, 11, 11, 10}, - }, - { - {10, 11, 11, 11}, - {11, 11, 11, 11}, - {11, 11, 10, 11}, - {11, 11, 11, 11}, - }, - { - {11, 11, 11, 11}, - {11, 11, 12, 11}, - {11, 11, 11, 11}, - {12, 11, 11, 11}, - }, - { - {11, 11, 11, 12}, - {12, 11, 12, 11}, - {11, 12, 11, 11}, - {12, 11, 12, 11}, - }, - { - {11, 12, 11, 12}, - {12, 11, 12, 12}, - {11, 12, 11, 12}, - {12, 12, 12, 11}, - }, - { - {11, 12, 11, 12}, - {12, 12, 12, 12}, - {12, 12, 11, 12}, - {12, 12, 12, 12}, - }, - { - {12, 12, 12, 12}, - {12, 12, 12, 12}, - {12, 12, 12, 12}, - {13, 12, 12, 12}, - }, - { - {12, 12, 12, 12}, - {13, 12, 13, 12}, - {12, 13, 12, 12}, - {13, 12, 13, 12}, - }, - { - {12, 13, 12, 13}, - {13, 12, 13, 12}, - {12, 13, 12, 13}, - {13, 13, 13, 12}, - }, - { - {12, 13, 12, 13}, - {13, 13, 13, 13}, - {13, 13, 12, 13}, - {13, 13, 13, 13}, - }, - { - {13, 13, 13, 13}, - {13, 13, 13, 13}, - {13, 13, 13, 13}, - {14, 13, 13, 13}, - }, - { - {13, 13, 13, 13}, - {14, 13, 14, 13}, - {13, 14, 13, 13}, - {14, 13, 14, 13}, - }, - { - {13, 14, 13, 14}, - {14, 13, 14, 13}, - {13, 14, 13, 14}, - {14, 14, 14, 13}, - }, - { - {13, 14, 13, 14}, - {14, 14, 14, 14}, - {14, 14, 13, 14}, - {14, 14, 14, 14}, - }, - { - {14, 14, 14, 14}, - {14, 14, 14, 14}, - {14, 14, 14, 14}, - {15, 14, 14, 14}, - }, - { - {14, 14, 14, 14}, - {15, 14, 15, 14}, - {14, 15, 14, 14}, - {15, 14, 15, 14}, - }, - { - {14, 15, 14, 15}, - {15, 14, 15, 14}, - {14, 15, 14, 15}, - {15, 15, 15, 14}, - }, - { - {14, 15, 14, 15}, - {15, 15, 15, 15}, - {15, 15, 14, 15}, - {15, 15, 15, 15}, - }, - { - {15, 15, 15, 15}, - {15, 15, 15, 15}, - {15, 15, 15, 15}, - {16, 15, 15, 15}, - }, - { - {15, 15, 15, 15}, - {16, 15, 16, 15}, - {15, 16, 15, 15}, - {16, 15, 16, 15}, - }, - { - {15, 16, 15, 16}, - {16, 15, 16, 15}, - {15, 16, 15, 16}, - {16, 16, 16, 15}, - }, - { - {15, 16, 15, 16}, - {16, 16, 16, 16}, - {16, 16, 15, 16}, - {16, 16, 16, 16}, - }, - { - {16, 16, 16, 16}, - {16, 16, 16, 16}, - {16, 16, 16, 16}, - {17, 16, 16, 16}, - }, - { - {16, 16, 16, 16}, - {17, 16, 17, 16}, - {16, 17, 16, 16}, - {17, 16, 17, 16}, - }, - { - {16, 17, 16, 17}, - {17, 16, 17, 16}, - {16, 17, 16, 17}, - {17, 17, 17, 16}, - }, - { - {16, 17, 16, 17}, - {17, 17, 17, 17}, - {17, 17, 16, 17}, - {17, 17, 17, 17}, - }, - { - {17, 17, 17, 17}, - {17, 17, 17, 17}, - {17, 17, 17, 17}, - {18, 17, 17, 17}, - }, - { - {17, 17, 17, 17}, - {18, 17, 18, 17}, - {17, 18, 17, 17}, - {18, 17, 18, 17}, - }, - { - {17, 18, 17, 18}, - {18, 17, 18, 17}, - {17, 18, 17, 18}, - {18, 18, 18, 17}, - }, - { - {17, 18, 17, 18}, - {18, 18, 18, 18}, - {18, 18, 17, 18}, - {18, 18, 18, 18}, - }, - { - {18, 18, 18, 18}, - {18, 18, 18, 18}, - {18, 18, 18, 18}, - {19, 18, 18, 18}, - }, - { - {18, 18, 18, 18}, - {19, 18, 19, 18}, - {18, 19, 18, 18}, - {19, 18, 19, 18}, - }, - { - {18, 19, 18, 19}, - {19, 18, 19, 18}, - {18, 19, 18, 19}, - {19, 19, 19, 18}, - }, - { - {18, 19, 18, 19}, - {19, 19, 19, 19}, - {19, 19, 18, 19}, - {19, 19, 19, 19}, - }, - { - {19, 19, 19, 19}, - {19, 19, 19, 19}, - {19, 19, 19, 19}, - {20, 19, 19, 19}, - }, - { - {19, 19, 19, 19}, - {20, 19, 20, 19}, - {19, 20, 19, 19}, - {20, 19, 20, 19}, - }, - { - {19, 20, 19, 20}, - {20, 19, 20, 19}, - {19, 20, 19, 20}, - {20, 20, 20, 19}, - }, - { - {19, 20, 19, 20}, - {20, 20, 20, 20}, - {19, 20, 19, 20}, - {20, 20, 20, 20}, - }, - { - {20, 20, 20, 20}, - {20, 20, 20, 20}, - {20, 20, 20, 20}, - {20, 20, 20, 20}, - }, - { - {20, 20, 20, 20}, - {21, 20, 21, 20}, - {20, 20, 20, 20}, - {21, 20, 21, 20}, - }, - { - {20, 21, 20, 21}, - {21, 20, 21, 20}, - {20, 21, 20, 21}, - {21, 20, 21, 20}, - }, - { - {20, 21, 20, 21}, - {21, 21, 21, 21}, - {20, 21, 20, 21}, - {21, 21, 21, 21}, - }, - { - {21, 21, 21, 21}, - {21, 21, 21, 21}, - {21, 21, 21, 21}, - {21, 21, 21, 21}, - }, - { - {21, 21, 21, 21}, - {22, 21, 22, 21}, - {21, 21, 21, 21}, - {22, 21, 22, 21}, - }, - { - {21, 22, 21, 22}, - {22, 21, 22, 21}, - {21, 22, 21, 22}, - {22, 21, 22, 21}, - }, - { - {21, 22, 21, 22}, - {22, 22, 22, 22}, - {21, 22, 21, 22}, - {22, 22, 22, 22}, - }, - { - {22, 22, 22, 22}, - {22, 22, 22, 22}, - {22, 22, 22, 22}, - {22, 22, 22, 22}, - }, - { - {22, 22, 22, 22}, - {23, 22, 23, 22}, - {22, 22, 22, 22}, - {23, 22, 23, 22}, - }, - { - {22, 23, 22, 23}, - {23, 22, 23, 22}, - {22, 23, 22, 23}, - {23, 22, 23, 22}, - }, - { - {22, 23, 22, 23}, - {23, 23, 23, 23}, - {22, 23, 22, 23}, - {23, 23, 23, 23}, - }, - { - {23, 23, 23, 23}, - {23, 23, 23, 23}, - {23, 23, 23, 23}, - {23, 23, 23, 23}, - }, - { - {23, 23, 23, 23}, - {24, 23, 24, 23}, - {23, 23, 23, 23}, - {24, 23, 24, 23}, - }, - { - {23, 24, 23, 24}, - {24, 23, 24, 23}, - {23, 24, 23, 24}, - {24, 23, 24, 23}, - }, - { - {23, 24, 23, 24}, - {24, 23, 24, 24}, - {23, 24, 23, 24}, - {24, 24, 24, 24}, - }, - { - {23, 24, 24, 24}, - {24, 24, 24, 24}, - {24, 24, 24, 24}, - {24, 24, 24, 24}, - }, - { - {24, 24, 24, 24}, - {24, 24, 25, 24}, - {24, 24, 24, 24}, - {25, 24, 25, 24}, - }, - { - {24, 24, 24, 25}, - {25, 24, 25, 24}, - {24, 25, 24, 25}, - {25, 24, 25, 24}, - }, - { - {24, 25, 24, 25}, - {25, 24, 25, 25}, - {24, 25, 24, 25}, - {25, 25, 25, 25}, - }, - { - {24, 25, 25, 25}, - {25, 25, 25, 25}, - {25, 25, 25, 25}, - {25, 25, 25, 25}, - }, - { - {25, 25, 25, 25}, - {25, 25, 26, 25}, - {25, 25, 25, 25}, - {26, 25, 26, 25}, - }, - { - {25, 25, 25, 26}, - {26, 25, 26, 25}, - {25, 26, 25, 26}, - {26, 25, 26, 25}, - }, - { - {25, 26, 25, 26}, - {26, 25, 26, 26}, - {25, 26, 25, 26}, - {26, 26, 26, 26}, - }, - { - {25, 26, 26, 26}, - {26, 26, 26, 26}, - {26, 26, 26, 26}, - {26, 26, 26, 26}, - }, - { - {26, 26, 26, 26}, - {26, 26, 27, 26}, - {26, 26, 26, 26}, - {27, 26, 27, 26}, - }, - { - {26, 26, 26, 27}, - {27, 26, 27, 26}, - {26, 27, 26, 27}, - {27, 26, 27, 26}, - }, - { - {26, 27, 26, 27}, - {27, 26, 27, 27}, - {26, 27, 26, 27}, - {27, 27, 27, 27}, - }, - { - {26, 27, 27, 27}, - {27, 27, 27, 27}, - {27, 27, 27, 27}, - {27, 27, 27, 27}, - }, - { - {27, 27, 27, 27}, - {27, 27, 28, 27}, - {27, 27, 27, 27}, - {28, 27, 28, 27}, - }, - { - {27, 27, 27, 28}, - {28, 27, 28, 27}, - {27, 28, 27, 28}, - {28, 27, 28, 27}, - }, - { - {27, 28, 27, 28}, - {28, 27, 28, 28}, - {27, 28, 27, 28}, - {28, 28, 28, 27}, - }, - { - {27, 28, 28, 28}, - {28, 28, 28, 28}, - {28, 28, 27, 28}, - {28, 28, 28, 28}, - }, - { - {28, 28, 28, 28}, - {28, 28, 29, 28}, - {28, 28, 28, 28}, - {29, 28, 28, 28}, - }, - { - {28, 28, 28, 29}, - {29, 28, 29, 28}, - {28, 29, 28, 28}, - {29, 28, 29, 28}, - }, - { - {28, 29, 28, 29}, - {29, 28, 29, 29}, - {28, 29, 28, 29}, - {29, 29, 29, 28}, - }, - { - {28, 29, 29, 29}, - {29, 29, 29, 29}, - {29, 29, 28, 29}, - {29, 29, 29, 29}, - }, - { - {29, 29, 29, 29}, - {29, 29, 30, 29}, - {29, 29, 29, 29}, - {30, 29, 29, 29}, - }, - { - {29, 29, 29, 30}, - {30, 29, 30, 29}, - {29, 30, 29, 29}, - {30, 29, 30, 29}, - }, - { - {29, 30, 29, 30}, - {30, 29, 30, 30}, - {29, 30, 29, 30}, - {30, 30, 30, 29}, - }, - { - {29, 30, 30, 30}, - {30, 30, 30, 30}, - {30, 30, 29, 30}, - {30, 30, 30, 30}, - }, - { - {30, 30, 30, 30}, - {30, 30, 31, 30}, - {30, 30, 30, 30}, - {31, 30, 30, 30}, - }, - { - {30, 30, 30, 31}, - {31, 30, 31, 30}, - {30, 31, 30, 30}, - {31, 30, 31, 30}, - }, - { - {30, 31, 30, 31}, - {31, 30, 31, 31}, - {30, 31, 30, 31}, - {31, 31, 31, 30}, - }, - { - {30, 31, 31, 31}, - {31, 31, 31, 31}, - {31, 31, 30, 31}, - {31, 31, 31, 31}, - }, - { - {31, 31, 31, 31}, - {31, 31, 32, 31}, - {31, 31, 31, 31}, - {32, 31, 31, 31}, - }, - { - {31, 31, 31, 32}, - {32, 31, 32, 31}, - {31, 32, 31, 31}, - {32, 31, 32, 31}, - }, - { - {31, 32, 31, 32}, - {32, 31, 32, 32}, - {31, 32, 31, 32}, - {32, 32, 32, 31}, - }, - { - {31, 32, 32, 32}, - {32, 32, 32, 32}, - {32, 32, 31, 32}, - {32, 32, 32, 32}, - }, - { - {32, 32, 32, 32}, - {32, 32, 33, 32}, - {32, 32, 32, 32}, - {33, 32, 32, 32}, - }, - { - {32, 32, 32, 33}, - {33, 32, 33, 32}, - {32, 33, 32, 32}, - {33, 32, 33, 32}, - }, - { - {32, 33, 32, 33}, - {33, 32, 33, 33}, - {32, 33, 32, 33}, - {33, 33, 33, 32}, - }, - { - {32, 33, 33, 33}, - {33, 33, 33, 33}, - {33, 33, 32, 33}, - {33, 33, 33, 33}, - }, - { - {33, 33, 33, 33}, - {33, 33, 34, 33}, - {33, 33, 33, 33}, - {34, 33, 33, 33}, - }, - { - {33, 33, 33, 34}, - {34, 33, 34, 33}, - {33, 34, 33, 33}, - {34, 33, 34, 33}, - }, - { - {33, 34, 33, 34}, - {34, 33, 34, 34}, - {33, 34, 33, 34}, - {34, 34, 34, 33}, - }, - { - {33, 34, 34, 34}, - {34, 34, 34, 34}, - {34, 34, 33, 34}, - {34, 34, 34, 34}, - }, - { - {34, 34, 34, 34}, - {34, 34, 35, 34}, - {34, 34, 34, 34}, - {35, 34, 34, 34}, - }, - { - {34, 34, 34, 35}, - {35, 34, 35, 34}, - {34, 35, 34, 34}, - {35, 34, 35, 34}, - }, - { - {34, 35, 34, 35}, - {35, 34, 35, 35}, - {34, 35, 34, 35}, - {35, 35, 35, 34}, - }, - { - {34, 35, 35, 35}, - {35, 35, 35, 35}, - {35, 35, 34, 35}, - {35, 35, 35, 35}, - }, - { - {35, 35, 35, 35}, - {35, 35, 36, 35}, - {35, 35, 35, 35}, - {36, 35, 35, 35}, - }, - { - {35, 35, 35, 36}, - {36, 35, 36, 35}, - {35, 36, 35, 35}, - {36, 35, 36, 35}, - }, - { - {35, 36, 35, 36}, - {36, 35, 36, 35}, - {35, 36, 35, 36}, - {36, 36, 36, 35}, - }, - { - {35, 36, 35, 36}, - {36, 36, 36, 36}, - {36, 36, 35, 36}, - {36, 36, 36, 36}, - }, - { - {36, 36, 36, 36}, - {36, 36, 36, 36}, - {36, 36, 36, 36}, - {37, 36, 36, 36}, - }, - { - {36, 36, 36, 36}, - {37, 36, 37, 36}, - {36, 37, 36, 36}, - {37, 36, 37, 36}, - }, - { - {36, 37, 36, 37}, - {37, 36, 37, 36}, - {36, 37, 36, 37}, - {37, 37, 37, 36}, - }, - { - {36, 37, 36, 37}, - {37, 37, 37, 37}, - {37, 37, 36, 37}, - {37, 37, 37, 37}, - }, - { - {37, 37, 37, 37}, - {37, 37, 37, 37}, - {37, 37, 37, 37}, - {38, 37, 37, 37}, - }, - { - {37, 37, 37, 37}, - {38, 37, 38, 37}, - {37, 38, 37, 37}, - {38, 37, 38, 37}, - }, - { - {37, 38, 37, 38}, - {38, 37, 38, 37}, - {37, 38, 37, 38}, - {38, 38, 38, 37}, - }, - { - {37, 38, 37, 38}, - {38, 38, 38, 38}, - {38, 38, 37, 38}, - {38, 38, 38, 38}, - }, - { - {38, 38, 38, 38}, - {38, 38, 38, 38}, - {38, 38, 38, 38}, - {39, 38, 38, 38}, - }, - { - {38, 38, 38, 38}, - {39, 38, 39, 38}, - {38, 39, 38, 38}, - {39, 38, 39, 38}, - }, - { - {38, 39, 38, 39}, - {39, 38, 39, 38}, - {38, 39, 38, 39}, - {39, 39, 39, 38}, - }, - { - {38, 39, 38, 39}, - {39, 39, 39, 39}, - {39, 39, 38, 39}, - {39, 39, 39, 39}, - }, - { - {39, 39, 39, 39}, - {39, 39, 39, 39}, - {39, 39, 39, 39}, - {40, 39, 39, 39}, - }, - { - {39, 39, 39, 39}, - {40, 39, 40, 39}, - {39, 40, 39, 39}, - {40, 39, 40, 39}, - }, - { - {39, 40, 39, 40}, - {40, 39, 40, 39}, - {39, 40, 39, 40}, - {40, 39, 40, 39}, - }, - { - {39, 40, 39, 40}, - {40, 40, 40, 40}, - {39, 40, 39, 40}, - {40, 40, 40, 40}, - }, - { - {40, 40, 40, 40}, - {40, 40, 40, 40}, - {40, 40, 40, 40}, - {40, 40, 40, 40}, - }, - { - {40, 40, 40, 40}, - {41, 40, 41, 40}, - {40, 40, 40, 40}, - {41, 40, 41, 40}, - }, - { - {40, 41, 40, 41}, - {41, 40, 41, 40}, - {40, 41, 40, 41}, - {41, 40, 41, 40}, - }, - { - {40, 41, 40, 41}, - {41, 41, 41, 41}, - {40, 41, 40, 41}, - {41, 41, 41, 41}, - }, - { - {41, 41, 41, 41}, - {41, 41, 41, 41}, - {41, 41, 41, 41}, - {41, 41, 41, 41}, - }, - { - {41, 41, 41, 41}, - {42, 41, 42, 41}, - {41, 41, 41, 41}, - {42, 41, 42, 41}, - }, - { - {41, 42, 41, 42}, - {42, 41, 42, 41}, - {41, 42, 41, 42}, - {42, 41, 42, 41}, - }, - { - {41, 42, 41, 42}, - {42, 42, 42, 42}, - {41, 42, 41, 42}, - {42, 42, 42, 42}, - }, - { - {42, 42, 42, 42}, - {42, 42, 42, 42}, - {42, 42, 42, 42}, - {42, 42, 42, 42}, - }, - { - {42, 42, 42, 42}, - {43, 42, 43, 42}, - {42, 42, 42, 42}, - {43, 42, 43, 42}, - }, - { - {42, 43, 42, 43}, - {43, 42, 43, 42}, - {42, 43, 42, 43}, - {43, 42, 43, 42}, - }, - { - {42, 43, 42, 43}, - {43, 43, 43, 43}, - {42, 43, 42, 43}, - {43, 43, 43, 43}, - }, - { - {43, 43, 43, 43}, - {43, 43, 43, 43}, - {43, 43, 43, 43}, - {43, 43, 43, 43}, - }, - { - {43, 43, 43, 43}, - {44, 43, 44, 43}, - {43, 43, 43, 43}, - {44, 43, 44, 43}, - }, - { - {43, 43, 43, 44}, - {44, 43, 44, 43}, - {43, 44, 43, 44}, - {44, 43, 44, 43}, - }, - { - {43, 44, 43, 44}, - {44, 43, 44, 44}, - {43, 44, 43, 44}, - {44, 44, 44, 44}, - }, - { - {43, 44, 44, 44}, - {44, 44, 44, 44}, - {44, 44, 44, 44}, - {44, 44, 44, 44}, - }, - { - {44, 44, 44, 44}, - {44, 44, 45, 44}, - {44, 44, 44, 44}, - {45, 44, 45, 44}, - }, - { - {44, 44, 44, 45}, - {45, 44, 45, 44}, - {44, 45, 44, 45}, - {45, 44, 45, 44}, - }, - { - {44, 45, 44, 45}, - {45, 44, 45, 45}, - {44, 45, 44, 45}, - {45, 45, 45, 45}, - }, - { - {44, 45, 45, 45}, - {45, 45, 45, 45}, - {45, 45, 45, 45}, - {45, 45, 45, 45}, - }, - { - {45, 45, 45, 45}, - {45, 45, 46, 45}, - {45, 45, 45, 45}, - {46, 45, 46, 45}, - }, - { - {45, 45, 45, 46}, - {46, 45, 46, 45}, - {45, 46, 45, 46}, - {46, 45, 46, 45}, - }, - { - {45, 46, 45, 46}, - {46, 45, 46, 46}, - {45, 46, 45, 46}, - {46, 46, 46, 46}, - }, - { - {45, 46, 46, 46}, - {46, 46, 46, 46}, - {46, 46, 46, 46}, - {46, 46, 46, 46}, - }, - { - {46, 46, 46, 46}, - {46, 46, 47, 46}, - {46, 46, 46, 46}, - {47, 46, 47, 46}, - }, - { - {46, 46, 46, 47}, - {47, 46, 47, 46}, - {46, 47, 46, 47}, - {47, 46, 47, 46}, - }, - { - {46, 47, 46, 47}, - {47, 46, 47, 47}, - {46, 47, 46, 47}, - {47, 47, 47, 47}, - }, - { - {46, 47, 47, 47}, - {47, 47, 47, 47}, - {47, 47, 47, 47}, - {47, 47, 47, 47}, - }, - { - {47, 47, 47, 47}, - {47, 47, 48, 47}, - {47, 47, 47, 47}, - {48, 47, 48, 47}, - }, - { - {47, 47, 47, 48}, - {48, 47, 48, 47}, - {47, 48, 47, 48}, - {48, 47, 48, 47}, - }, - { - {47, 48, 47, 48}, - {48, 47, 48, 48}, - {47, 48, 47, 48}, - {48, 48, 48, 48}, - }, - { - {47, 48, 48, 48}, - {48, 48, 48, 48}, - {48, 48, 48, 48}, - {48, 48, 48, 48}, - }, - { - {48, 48, 48, 48}, - {48, 48, 49, 48}, - {48, 48, 48, 48}, - {49, 48, 49, 48}, - }, - { - {48, 48, 48, 49}, - {49, 48, 49, 48}, - {48, 49, 48, 49}, - {49, 48, 49, 48}, - }, - { - {48, 49, 48, 49}, - {49, 48, 49, 49}, - {48, 49, 48, 49}, - {49, 49, 49, 49}, - }, - { - {48, 49, 49, 49}, - {49, 49, 49, 49}, - {49, 49, 49, 49}, - {49, 49, 49, 49}, - }, - { - {49, 49, 49, 49}, - {49, 49, 50, 49}, - {49, 49, 49, 49}, - {50, 49, 50, 49}, - }, - { - {49, 49, 49, 50}, - {50, 49, 50, 49}, - {49, 50, 49, 50}, - {50, 49, 50, 49}, - }, - { - {49, 50, 49, 50}, - {50, 49, 50, 50}, - {49, 50, 49, 50}, - {50, 50, 50, 50}, - }, - { - {49, 50, 50, 50}, - {50, 50, 50, 50}, - {50, 50, 50, 50}, - {50, 50, 50, 50}, - }, - { - {50, 50, 50, 50}, - {50, 50, 51, 50}, - {50, 50, 50, 50}, - {51, 50, 51, 50}, - }, - { - {50, 50, 50, 51}, - {51, 50, 51, 50}, - {50, 51, 50, 51}, - {51, 50, 51, 50}, - }, - { - {50, 51, 50, 51}, - {51, 50, 51, 51}, - {50, 51, 50, 51}, - {51, 51, 51, 51}, - }, - { - {50, 51, 51, 51}, - {51, 51, 51, 51}, - {51, 51, 51, 51}, - {51, 51, 51, 51}, - }, - { - {51, 51, 51, 51}, - {51, 51, 52, 51}, - {51, 51, 51, 51}, - {52, 51, 52, 51}, - }, - { - {51, 51, 51, 52}, - {52, 51, 52, 51}, - {51, 52, 51, 51}, - {52, 51, 52, 51}, - }, - { - {51, 52, 51, 52}, - {52, 51, 52, 52}, - {51, 52, 51, 52}, - {52, 52, 52, 51}, - }, - { - {51, 52, 52, 52}, - {52, 52, 52, 52}, - {52, 52, 51, 52}, - {52, 52, 52, 52}, - }, - { - {52, 52, 52, 52}, - {52, 52, 53, 52}, - {52, 52, 52, 52}, - {53, 52, 52, 52}, - }, - { - {52, 52, 52, 53}, - {53, 52, 53, 52}, - {52, 53, 52, 52}, - {53, 52, 53, 52}, - }, - { - {52, 53, 52, 53}, - {53, 52, 53, 53}, - {52, 53, 52, 53}, - {53, 53, 53, 52}, - }, - { - {52, 53, 53, 53}, - {53, 53, 53, 53}, - {53, 53, 52, 53}, - {53, 53, 53, 53}, - }, - { - {53, 53, 53, 53}, - {53, 53, 54, 53}, - {53, 53, 53, 53}, - {54, 53, 53, 53}, - }, - { - {53, 53, 53, 54}, - {54, 53, 54, 53}, - {53, 54, 53, 53}, - {54, 53, 54, 53}, - }, - { - {53, 54, 53, 54}, - {54, 53, 54, 54}, - {53, 54, 53, 54}, - {54, 54, 54, 53}, - }, - { - {53, 54, 54, 54}, - {54, 54, 54, 54}, - {54, 54, 53, 54}, - {54, 54, 54, 54}, - }, - { - {54, 54, 54, 54}, - {54, 54, 55, 54}, - {54, 54, 54, 54}, - {55, 54, 54, 54}, - }, - { - {54, 54, 54, 55}, - {55, 54, 55, 54}, - {54, 55, 54, 54}, - {55, 54, 55, 54}, - }, - { - {54, 55, 54, 55}, - {55, 54, 55, 55}, - {54, 55, 54, 55}, - {55, 55, 55, 54}, - }, - { - {54, 55, 55, 55}, - {55, 55, 55, 55}, - {55, 55, 54, 55}, - {55, 55, 55, 55}, - }, - { - {55, 55, 55, 55}, - {55, 55, 56, 55}, - {55, 55, 55, 55}, - {56, 55, 55, 55}, - }, - { - {55, 55, 55, 55}, - {56, 55, 56, 55}, - {55, 56, 55, 55}, - {56, 55, 56, 55}, - }, - { - {55, 56, 55, 56}, - {56, 55, 56, 55}, - {55, 56, 55, 56}, - {56, 56, 56, 55}, - }, - { - {55, 56, 55, 56}, - {56, 56, 56, 56}, - {56, 56, 55, 56}, - {56, 56, 56, 56}, - }, - { - {56, 56, 56, 56}, - {56, 56, 56, 56}, - {56, 56, 56, 56}, - {57, 56, 56, 56}, - }, - { - {56, 56, 56, 56}, - {57, 56, 57, 56}, - {56, 57, 56, 56}, - {57, 56, 57, 56}, - }, - { - {56, 57, 56, 57}, - {57, 56, 57, 56}, - {56, 57, 56, 57}, - {57, 57, 57, 56}, - }, - { - {56, 57, 56, 57}, - {57, 57, 57, 57}, - {57, 57, 56, 57}, - {57, 57, 57, 57}, - }, - { - {57, 57, 57, 57}, - {57, 57, 57, 57}, - {57, 57, 57, 57}, - {58, 57, 57, 57}, - }, - { - {57, 57, 57, 57}, - {58, 57, 58, 57}, - {57, 58, 57, 57}, - {58, 57, 58, 57}, - }, - { - {57, 58, 57, 58}, - {58, 57, 58, 57}, - {57, 58, 57, 58}, - {58, 58, 58, 57}, - }, - { - {57, 58, 57, 58}, - {58, 58, 58, 58}, - {58, 58, 57, 58}, - {58, 58, 58, 58}, - }, - { - {58, 58, 58, 58}, - {58, 58, 58, 58}, - {58, 58, 58, 58}, - {59, 58, 58, 58}, - }, - { - {58, 58, 58, 58}, - {59, 58, 59, 58}, - {58, 59, 58, 58}, - {59, 58, 59, 58}, - }, - { - {58, 59, 58, 59}, - {59, 58, 59, 58}, - {58, 59, 58, 59}, - {59, 59, 59, 58}, - }, - { - {58, 59, 58, 59}, - {59, 59, 59, 59}, - {59, 59, 58, 59}, - {59, 59, 59, 59}, - }, - { - {59, 59, 59, 59}, - {59, 59, 59, 59}, - {59, 59, 59, 59}, - {60, 59, 59, 59}, - }, - { - {59, 59, 59, 59}, - {60, 59, 60, 59}, - {59, 59, 59, 59}, - {60, 59, 60, 59}, - }, - { - {59, 60, 59, 60}, - {60, 59, 60, 59}, - {59, 60, 59, 60}, - {60, 59, 60, 59}, - }, - { - {59, 60, 59, 60}, - {60, 60, 60, 60}, - {59, 60, 59, 60}, - {60, 60, 60, 60}, - }, - { - {60, 60, 60, 60}, - {60, 60, 60, 60}, - {60, 60, 60, 60}, - {60, 60, 60, 60}, - }, - { - {60, 60, 60, 60}, - {61, 60, 61, 60}, - {60, 60, 60, 60}, - {61, 60, 61, 60}, - }, - { - {60, 61, 60, 61}, - {61, 60, 61, 60}, - {60, 61, 60, 61}, - {61, 60, 61, 60}, - }, - { - {60, 61, 60, 61}, - {61, 61, 61, 61}, - {60, 61, 60, 61}, - {61, 61, 61, 61}, - }, - { - {61, 61, 61, 61}, - {61, 61, 61, 61}, - {61, 61, 61, 61}, - {61, 61, 61, 61}, - }, - { - {61, 61, 61, 61}, - {62, 61, 62, 61}, - {61, 61, 61, 61}, - {62, 61, 62, 61}, - }, - { - {61, 62, 61, 62}, - {62, 61, 62, 61}, - {61, 62, 61, 62}, - {62, 61, 62, 61}, - }, - { - {61, 62, 61, 62}, - {62, 62, 62, 62}, - {61, 62, 61, 62}, - {62, 62, 62, 62}, - }, - { - {62, 62, 62, 62}, - {62, 62, 62, 62}, - {62, 62, 62, 62}, - {62, 62, 62, 62}, - }, - { - {62, 62, 62, 62}, - {63, 62, 63, 62}, - {62, 62, 62, 62}, - {63, 62, 63, 62}, - }, - { - {62, 63, 62, 63}, - {63, 62, 63, 62}, - {62, 63, 62, 63}, - {63, 62, 63, 62}, - }, - { - {62, 63, 62, 63}, - {63, 63, 63, 63}, - {62, 63, 62, 63}, - {63, 63, 63, 63}, - }, - { - {63, 63, 63, 63}, - {63, 63, 63, 63}, - {63, 63, 63, 63}, - {63, 63, 63, 63}, - }, +static const uint8_t dither_g[256][4][4] = { + { + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + }, + { + {0, 0, 0, 0}, + {1, 0, 1, 0}, + {0, 0, 0, 0}, + {1, 0, 1, 0}, + }, + { + {0, 1, 0, 1}, + {1, 0, 1, 0}, + {0, 1, 0, 1}, + {1, 0, 1, 0}, + }, + { + {0, 1, 0, 1}, + {1, 1, 1, 1}, + {0, 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, 1, 1}, + {2, 1, 2, 1}, + {1, 1, 1, 1}, + {2, 1, 2, 1}, + }, + { + {1, 2, 1, 2}, + {2, 1, 2, 1}, + {1, 2, 1, 2}, + {2, 1, 2, 1}, + }, + { + {1, 2, 1, 2}, + {2, 2, 2, 2}, + {1, 2, 1, 2}, + {2, 2, 2, 2}, + }, + { + {2, 2, 2, 2}, + {2, 2, 2, 2}, + {2, 2, 2, 2}, + {2, 2, 2, 2}, + }, + { + {2, 2, 2, 2}, + {3, 2, 3, 2}, + {2, 2, 2, 2}, + {3, 2, 3, 2}, + }, + { + {2, 3, 2, 3}, + {3, 2, 3, 2}, + {2, 3, 2, 3}, + {3, 2, 3, 2}, + }, + { + {2, 3, 2, 3}, + {3, 3, 3, 3}, + {2, 3, 2, 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}, + {4, 3, 4, 3}, + {3, 3, 3, 3}, + {4, 3, 4, 3}, + }, + { + {3, 4, 3, 4}, + {4, 3, 4, 3}, + {3, 4, 3, 4}, + {4, 3, 4, 3}, + }, + { + {3, 4, 3, 4}, + {4, 4, 4, 4}, + {3, 4, 3, 4}, + {4, 4, 4, 4}, + }, + { + {3, 4, 4, 4}, + {4, 4, 4, 4}, + {4, 4, 4, 4}, + {4, 4, 4, 4}, + }, + { + {4, 4, 4, 4}, + {4, 4, 5, 4}, + {4, 4, 4, 4}, + {5, 4, 5, 4}, + }, + { + {4, 4, 4, 5}, + {5, 4, 5, 4}, + {4, 5, 4, 5}, + {5, 4, 5, 4}, + }, + { + {4, 5, 4, 5}, + {5, 4, 5, 5}, + {4, 5, 4, 5}, + {5, 5, 5, 5}, + }, + { + {4, 5, 5, 5}, + {5, 5, 5, 5}, + {5, 5, 5, 5}, + {5, 5, 5, 5}, + }, + { + {5, 5, 5, 5}, + {5, 5, 6, 5}, + {5, 5, 5, 5}, + {6, 5, 6, 5}, + }, + { + {5, 5, 5, 6}, + {6, 5, 6, 5}, + {5, 6, 5, 6}, + {6, 5, 6, 5}, + }, + { + {5, 6, 5, 6}, + {6, 5, 6, 6}, + {5, 6, 5, 6}, + {6, 6, 6, 6}, + }, + { + {5, 6, 6, 6}, + {6, 6, 6, 6}, + {6, 6, 6, 6}, + {6, 6, 6, 6}, + }, + { + {6, 6, 6, 6}, + {6, 6, 7, 6}, + {6, 6, 6, 6}, + {7, 6, 7, 6}, + }, + { + {6, 6, 6, 7}, + {7, 6, 7, 6}, + {6, 7, 6, 7}, + {7, 6, 7, 6}, + }, + { + {6, 7, 6, 7}, + {7, 6, 7, 7}, + {6, 7, 6, 7}, + {7, 7, 7, 7}, + }, + { + {6, 7, 7, 7}, + {7, 7, 7, 7}, + {7, 7, 7, 7}, + {7, 7, 7, 7}, + }, + { + {7, 7, 7, 7}, + {7, 7, 8, 7}, + {7, 7, 7, 7}, + {8, 7, 8, 7}, + }, + { + {7, 7, 7, 8}, + {8, 7, 8, 7}, + {7, 8, 7, 8}, + {8, 7, 8, 7}, + }, + { + {7, 8, 7, 8}, + {8, 7, 8, 8}, + {7, 8, 7, 8}, + {8, 8, 8, 8}, + }, + { + {7, 8, 8, 8}, + {8, 8, 8, 8}, + {8, 8, 7, 8}, + {8, 8, 8, 8}, + }, + { + {8, 8, 8, 8}, + {8, 8, 9, 8}, + {8, 8, 8, 8}, + {9, 8, 8, 8}, + }, + { + {8, 8, 8, 9}, + {9, 8, 9, 8}, + {8, 9, 8, 8}, + {9, 8, 9, 8}, + }, + { + {8, 9, 8, 9}, + {9, 8, 9, 9}, + {8, 9, 8, 9}, + {9, 9, 9, 8}, + }, + { + {8, 9, 9, 9}, + {9, 9, 9, 9}, + {9, 9, 8, 9}, + {9, 9, 9, 9}, + }, + { + {9, 9, 9, 9}, + {9, 9, 10, 9}, + {9, 9, 9, 9}, + {10, 9, 9, 9}, + }, + { + {9, 9, 9, 10}, + {10, 9, 10, 9}, + {9, 10, 9, 9}, + {10, 9, 10, 9}, + }, + { + {9, 10, 9, 10}, + {10, 9, 10, 10}, + {9, 10, 9, 10}, + {10, 10, 10, 9}, + }, + { + {9, 10, 10, 10}, + {10, 10, 10, 10}, + {10, 10, 9, 10}, + {10, 10, 10, 10}, + }, + { + {10, 10, 10, 10}, + {10, 10, 11, 10}, + {10, 10, 10, 10}, + {11, 10, 10, 10}, + }, + { + {10, 10, 10, 11}, + {11, 10, 11, 10}, + {10, 11, 10, 10}, + {11, 10, 11, 10}, + }, + { + {10, 11, 10, 11}, + {11, 10, 11, 11}, + {10, 11, 10, 11}, + {11, 11, 11, 10}, + }, + { + {10, 11, 11, 11}, + {11, 11, 11, 11}, + {11, 11, 10, 11}, + {11, 11, 11, 11}, + }, + { + {11, 11, 11, 11}, + {11, 11, 12, 11}, + {11, 11, 11, 11}, + {12, 11, 11, 11}, + }, + { + {11, 11, 11, 12}, + {12, 11, 12, 11}, + {11, 12, 11, 11}, + {12, 11, 12, 11}, + }, + { + {11, 12, 11, 12}, + {12, 11, 12, 12}, + {11, 12, 11, 12}, + {12, 12, 12, 11}, + }, + { + {11, 12, 11, 12}, + {12, 12, 12, 12}, + {12, 12, 11, 12}, + {12, 12, 12, 12}, + }, + { + {12, 12, 12, 12}, + {12, 12, 12, 12}, + {12, 12, 12, 12}, + {13, 12, 12, 12}, + }, + { + {12, 12, 12, 12}, + {13, 12, 13, 12}, + {12, 13, 12, 12}, + {13, 12, 13, 12}, + }, + { + {12, 13, 12, 13}, + {13, 12, 13, 12}, + {12, 13, 12, 13}, + {13, 13, 13, 12}, + }, + { + {12, 13, 12, 13}, + {13, 13, 13, 13}, + {13, 13, 12, 13}, + {13, 13, 13, 13}, + }, + { + {13, 13, 13, 13}, + {13, 13, 13, 13}, + {13, 13, 13, 13}, + {14, 13, 13, 13}, + }, + { + {13, 13, 13, 13}, + {14, 13, 14, 13}, + {13, 14, 13, 13}, + {14, 13, 14, 13}, + }, + { + {13, 14, 13, 14}, + {14, 13, 14, 13}, + {13, 14, 13, 14}, + {14, 14, 14, 13}, + }, + { + {13, 14, 13, 14}, + {14, 14, 14, 14}, + {14, 14, 13, 14}, + {14, 14, 14, 14}, + }, + { + {14, 14, 14, 14}, + {14, 14, 14, 14}, + {14, 14, 14, 14}, + {15, 14, 14, 14}, + }, + { + {14, 14, 14, 14}, + {15, 14, 15, 14}, + {14, 15, 14, 14}, + {15, 14, 15, 14}, + }, + { + {14, 15, 14, 15}, + {15, 14, 15, 14}, + {14, 15, 14, 15}, + {15, 15, 15, 14}, + }, + { + {14, 15, 14, 15}, + {15, 15, 15, 15}, + {15, 15, 14, 15}, + {15, 15, 15, 15}, + }, + { + {15, 15, 15, 15}, + {15, 15, 15, 15}, + {15, 15, 15, 15}, + {16, 15, 15, 15}, + }, + { + {15, 15, 15, 15}, + {16, 15, 16, 15}, + {15, 16, 15, 15}, + {16, 15, 16, 15}, + }, + { + {15, 16, 15, 16}, + {16, 15, 16, 15}, + {15, 16, 15, 16}, + {16, 16, 16, 15}, + }, + { + {15, 16, 15, 16}, + {16, 16, 16, 16}, + {16, 16, 15, 16}, + {16, 16, 16, 16}, + }, + { + {16, 16, 16, 16}, + {16, 16, 16, 16}, + {16, 16, 16, 16}, + {17, 16, 16, 16}, + }, + { + {16, 16, 16, 16}, + {17, 16, 17, 16}, + {16, 17, 16, 16}, + {17, 16, 17, 16}, + }, + { + {16, 17, 16, 17}, + {17, 16, 17, 16}, + {16, 17, 16, 17}, + {17, 17, 17, 16}, + }, + { + {16, 17, 16, 17}, + {17, 17, 17, 17}, + {17, 17, 16, 17}, + {17, 17, 17, 17}, + }, + { + {17, 17, 17, 17}, + {17, 17, 17, 17}, + {17, 17, 17, 17}, + {18, 17, 17, 17}, + }, + { + {17, 17, 17, 17}, + {18, 17, 18, 17}, + {17, 18, 17, 17}, + {18, 17, 18, 17}, + }, + { + {17, 18, 17, 18}, + {18, 17, 18, 17}, + {17, 18, 17, 18}, + {18, 18, 18, 17}, + }, + { + {17, 18, 17, 18}, + {18, 18, 18, 18}, + {18, 18, 17, 18}, + {18, 18, 18, 18}, + }, + { + {18, 18, 18, 18}, + {18, 18, 18, 18}, + {18, 18, 18, 18}, + {19, 18, 18, 18}, + }, + { + {18, 18, 18, 18}, + {19, 18, 19, 18}, + {18, 19, 18, 18}, + {19, 18, 19, 18}, + }, + { + {18, 19, 18, 19}, + {19, 18, 19, 18}, + {18, 19, 18, 19}, + {19, 19, 19, 18}, + }, + { + {18, 19, 18, 19}, + {19, 19, 19, 19}, + {19, 19, 18, 19}, + {19, 19, 19, 19}, + }, + { + {19, 19, 19, 19}, + {19, 19, 19, 19}, + {19, 19, 19, 19}, + {20, 19, 19, 19}, + }, + { + {19, 19, 19, 19}, + {20, 19, 20, 19}, + {19, 20, 19, 19}, + {20, 19, 20, 19}, + }, + { + {19, 20, 19, 20}, + {20, 19, 20, 19}, + {19, 20, 19, 20}, + {20, 20, 20, 19}, + }, + { + {19, 20, 19, 20}, + {20, 20, 20, 20}, + {19, 20, 19, 20}, + {20, 20, 20, 20}, + }, + { + {20, 20, 20, 20}, + {20, 20, 20, 20}, + {20, 20, 20, 20}, + {20, 20, 20, 20}, + }, + { + {20, 20, 20, 20}, + {21, 20, 21, 20}, + {20, 20, 20, 20}, + {21, 20, 21, 20}, + }, + { + {20, 21, 20, 21}, + {21, 20, 21, 20}, + {20, 21, 20, 21}, + {21, 20, 21, 20}, + }, + { + {20, 21, 20, 21}, + {21, 21, 21, 21}, + {20, 21, 20, 21}, + {21, 21, 21, 21}, + }, + { + {21, 21, 21, 21}, + {21, 21, 21, 21}, + {21, 21, 21, 21}, + {21, 21, 21, 21}, + }, + { + {21, 21, 21, 21}, + {22, 21, 22, 21}, + {21, 21, 21, 21}, + {22, 21, 22, 21}, + }, + { + {21, 22, 21, 22}, + {22, 21, 22, 21}, + {21, 22, 21, 22}, + {22, 21, 22, 21}, + }, + { + {21, 22, 21, 22}, + {22, 22, 22, 22}, + {21, 22, 21, 22}, + {22, 22, 22, 22}, + }, + { + {22, 22, 22, 22}, + {22, 22, 22, 22}, + {22, 22, 22, 22}, + {22, 22, 22, 22}, + }, + { + {22, 22, 22, 22}, + {23, 22, 23, 22}, + {22, 22, 22, 22}, + {23, 22, 23, 22}, + }, + { + {22, 23, 22, 23}, + {23, 22, 23, 22}, + {22, 23, 22, 23}, + {23, 22, 23, 22}, + }, + { + {22, 23, 22, 23}, + {23, 23, 23, 23}, + {22, 23, 22, 23}, + {23, 23, 23, 23}, + }, + { + {23, 23, 23, 23}, + {23, 23, 23, 23}, + {23, 23, 23, 23}, + {23, 23, 23, 23}, + }, + { + {23, 23, 23, 23}, + {24, 23, 24, 23}, + {23, 23, 23, 23}, + {24, 23, 24, 23}, + }, + { + {23, 24, 23, 24}, + {24, 23, 24, 23}, + {23, 24, 23, 24}, + {24, 23, 24, 23}, + }, + { + {23, 24, 23, 24}, + {24, 23, 24, 24}, + {23, 24, 23, 24}, + {24, 24, 24, 24}, + }, + { + {23, 24, 24, 24}, + {24, 24, 24, 24}, + {24, 24, 24, 24}, + {24, 24, 24, 24}, + }, + { + {24, 24, 24, 24}, + {24, 24, 25, 24}, + {24, 24, 24, 24}, + {25, 24, 25, 24}, + }, + { + {24, 24, 24, 25}, + {25, 24, 25, 24}, + {24, 25, 24, 25}, + {25, 24, 25, 24}, + }, + { + {24, 25, 24, 25}, + {25, 24, 25, 25}, + {24, 25, 24, 25}, + {25, 25, 25, 25}, + }, + { + {24, 25, 25, 25}, + {25, 25, 25, 25}, + {25, 25, 25, 25}, + {25, 25, 25, 25}, + }, + { + {25, 25, 25, 25}, + {25, 25, 26, 25}, + {25, 25, 25, 25}, + {26, 25, 26, 25}, + }, + { + {25, 25, 25, 26}, + {26, 25, 26, 25}, + {25, 26, 25, 26}, + {26, 25, 26, 25}, + }, + { + {25, 26, 25, 26}, + {26, 25, 26, 26}, + {25, 26, 25, 26}, + {26, 26, 26, 26}, + }, + { + {25, 26, 26, 26}, + {26, 26, 26, 26}, + {26, 26, 26, 26}, + {26, 26, 26, 26}, + }, + { + {26, 26, 26, 26}, + {26, 26, 27, 26}, + {26, 26, 26, 26}, + {27, 26, 27, 26}, + }, + { + {26, 26, 26, 27}, + {27, 26, 27, 26}, + {26, 27, 26, 27}, + {27, 26, 27, 26}, + }, + { + {26, 27, 26, 27}, + {27, 26, 27, 27}, + {26, 27, 26, 27}, + {27, 27, 27, 27}, + }, + { + {26, 27, 27, 27}, + {27, 27, 27, 27}, + {27, 27, 27, 27}, + {27, 27, 27, 27}, + }, + { + {27, 27, 27, 27}, + {27, 27, 28, 27}, + {27, 27, 27, 27}, + {28, 27, 28, 27}, + }, + { + {27, 27, 27, 28}, + {28, 27, 28, 27}, + {27, 28, 27, 28}, + {28, 27, 28, 27}, + }, + { + {27, 28, 27, 28}, + {28, 27, 28, 28}, + {27, 28, 27, 28}, + {28, 28, 28, 27}, + }, + { + {27, 28, 28, 28}, + {28, 28, 28, 28}, + {28, 28, 27, 28}, + {28, 28, 28, 28}, + }, + { + {28, 28, 28, 28}, + {28, 28, 29, 28}, + {28, 28, 28, 28}, + {29, 28, 28, 28}, + }, + { + {28, 28, 28, 29}, + {29, 28, 29, 28}, + {28, 29, 28, 28}, + {29, 28, 29, 28}, + }, + { + {28, 29, 28, 29}, + {29, 28, 29, 29}, + {28, 29, 28, 29}, + {29, 29, 29, 28}, + }, + { + {28, 29, 29, 29}, + {29, 29, 29, 29}, + {29, 29, 28, 29}, + {29, 29, 29, 29}, + }, + { + {29, 29, 29, 29}, + {29, 29, 30, 29}, + {29, 29, 29, 29}, + {30, 29, 29, 29}, + }, + { + {29, 29, 29, 30}, + {30, 29, 30, 29}, + {29, 30, 29, 29}, + {30, 29, 30, 29}, + }, + { + {29, 30, 29, 30}, + {30, 29, 30, 30}, + {29, 30, 29, 30}, + {30, 30, 30, 29}, + }, + { + {29, 30, 30, 30}, + {30, 30, 30, 30}, + {30, 30, 29, 30}, + {30, 30, 30, 30}, + }, + { + {30, 30, 30, 30}, + {30, 30, 31, 30}, + {30, 30, 30, 30}, + {31, 30, 30, 30}, + }, + { + {30, 30, 30, 31}, + {31, 30, 31, 30}, + {30, 31, 30, 30}, + {31, 30, 31, 30}, + }, + { + {30, 31, 30, 31}, + {31, 30, 31, 31}, + {30, 31, 30, 31}, + {31, 31, 31, 30}, + }, + { + {30, 31, 31, 31}, + {31, 31, 31, 31}, + {31, 31, 30, 31}, + {31, 31, 31, 31}, + }, + { + {31, 31, 31, 31}, + {31, 31, 32, 31}, + {31, 31, 31, 31}, + {32, 31, 31, 31}, + }, + { + {31, 31, 31, 32}, + {32, 31, 32, 31}, + {31, 32, 31, 31}, + {32, 31, 32, 31}, + }, + { + {31, 32, 31, 32}, + {32, 31, 32, 32}, + {31, 32, 31, 32}, + {32, 32, 32, 31}, + }, + { + {31, 32, 32, 32}, + {32, 32, 32, 32}, + {32, 32, 31, 32}, + {32, 32, 32, 32}, + }, + { + {32, 32, 32, 32}, + {32, 32, 33, 32}, + {32, 32, 32, 32}, + {33, 32, 32, 32}, + }, + { + {32, 32, 32, 33}, + {33, 32, 33, 32}, + {32, 33, 32, 32}, + {33, 32, 33, 32}, + }, + { + {32, 33, 32, 33}, + {33, 32, 33, 33}, + {32, 33, 32, 33}, + {33, 33, 33, 32}, + }, + { + {32, 33, 33, 33}, + {33, 33, 33, 33}, + {33, 33, 32, 33}, + {33, 33, 33, 33}, + }, + { + {33, 33, 33, 33}, + {33, 33, 34, 33}, + {33, 33, 33, 33}, + {34, 33, 33, 33}, + }, + { + {33, 33, 33, 34}, + {34, 33, 34, 33}, + {33, 34, 33, 33}, + {34, 33, 34, 33}, + }, + { + {33, 34, 33, 34}, + {34, 33, 34, 34}, + {33, 34, 33, 34}, + {34, 34, 34, 33}, + }, + { + {33, 34, 34, 34}, + {34, 34, 34, 34}, + {34, 34, 33, 34}, + {34, 34, 34, 34}, + }, + { + {34, 34, 34, 34}, + {34, 34, 35, 34}, + {34, 34, 34, 34}, + {35, 34, 34, 34}, + }, + { + {34, 34, 34, 35}, + {35, 34, 35, 34}, + {34, 35, 34, 34}, + {35, 34, 35, 34}, + }, + { + {34, 35, 34, 35}, + {35, 34, 35, 35}, + {34, 35, 34, 35}, + {35, 35, 35, 34}, + }, + { + {34, 35, 35, 35}, + {35, 35, 35, 35}, + {35, 35, 34, 35}, + {35, 35, 35, 35}, + }, + { + {35, 35, 35, 35}, + {35, 35, 36, 35}, + {35, 35, 35, 35}, + {36, 35, 35, 35}, + }, + { + {35, 35, 35, 36}, + {36, 35, 36, 35}, + {35, 36, 35, 35}, + {36, 35, 36, 35}, + }, + { + {35, 36, 35, 36}, + {36, 35, 36, 35}, + {35, 36, 35, 36}, + {36, 36, 36, 35}, + }, + { + {35, 36, 35, 36}, + {36, 36, 36, 36}, + {36, 36, 35, 36}, + {36, 36, 36, 36}, + }, + { + {36, 36, 36, 36}, + {36, 36, 36, 36}, + {36, 36, 36, 36}, + {37, 36, 36, 36}, + }, + { + {36, 36, 36, 36}, + {37, 36, 37, 36}, + {36, 37, 36, 36}, + {37, 36, 37, 36}, + }, + { + {36, 37, 36, 37}, + {37, 36, 37, 36}, + {36, 37, 36, 37}, + {37, 37, 37, 36}, + }, + { + {36, 37, 36, 37}, + {37, 37, 37, 37}, + {37, 37, 36, 37}, + {37, 37, 37, 37}, + }, + { + {37, 37, 37, 37}, + {37, 37, 37, 37}, + {37, 37, 37, 37}, + {38, 37, 37, 37}, + }, + { + {37, 37, 37, 37}, + {38, 37, 38, 37}, + {37, 38, 37, 37}, + {38, 37, 38, 37}, + }, + { + {37, 38, 37, 38}, + {38, 37, 38, 37}, + {37, 38, 37, 38}, + {38, 38, 38, 37}, + }, + { + {37, 38, 37, 38}, + {38, 38, 38, 38}, + {38, 38, 37, 38}, + {38, 38, 38, 38}, + }, + { + {38, 38, 38, 38}, + {38, 38, 38, 38}, + {38, 38, 38, 38}, + {39, 38, 38, 38}, + }, + { + {38, 38, 38, 38}, + {39, 38, 39, 38}, + {38, 39, 38, 38}, + {39, 38, 39, 38}, + }, + { + {38, 39, 38, 39}, + {39, 38, 39, 38}, + {38, 39, 38, 39}, + {39, 39, 39, 38}, + }, + { + {38, 39, 38, 39}, + {39, 39, 39, 39}, + {39, 39, 38, 39}, + {39, 39, 39, 39}, + }, + { + {39, 39, 39, 39}, + {39, 39, 39, 39}, + {39, 39, 39, 39}, + {40, 39, 39, 39}, + }, + { + {39, 39, 39, 39}, + {40, 39, 40, 39}, + {39, 40, 39, 39}, + {40, 39, 40, 39}, + }, + { + {39, 40, 39, 40}, + {40, 39, 40, 39}, + {39, 40, 39, 40}, + {40, 39, 40, 39}, + }, + { + {39, 40, 39, 40}, + {40, 40, 40, 40}, + {39, 40, 39, 40}, + {40, 40, 40, 40}, + }, + { + {40, 40, 40, 40}, + {40, 40, 40, 40}, + {40, 40, 40, 40}, + {40, 40, 40, 40}, + }, + { + {40, 40, 40, 40}, + {41, 40, 41, 40}, + {40, 40, 40, 40}, + {41, 40, 41, 40}, + }, + { + {40, 41, 40, 41}, + {41, 40, 41, 40}, + {40, 41, 40, 41}, + {41, 40, 41, 40}, + }, + { + {40, 41, 40, 41}, + {41, 41, 41, 41}, + {40, 41, 40, 41}, + {41, 41, 41, 41}, + }, + { + {41, 41, 41, 41}, + {41, 41, 41, 41}, + {41, 41, 41, 41}, + {41, 41, 41, 41}, + }, + { + {41, 41, 41, 41}, + {42, 41, 42, 41}, + {41, 41, 41, 41}, + {42, 41, 42, 41}, + }, + { + {41, 42, 41, 42}, + {42, 41, 42, 41}, + {41, 42, 41, 42}, + {42, 41, 42, 41}, + }, + { + {41, 42, 41, 42}, + {42, 42, 42, 42}, + {41, 42, 41, 42}, + {42, 42, 42, 42}, + }, + { + {42, 42, 42, 42}, + {42, 42, 42, 42}, + {42, 42, 42, 42}, + {42, 42, 42, 42}, + }, + { + {42, 42, 42, 42}, + {43, 42, 43, 42}, + {42, 42, 42, 42}, + {43, 42, 43, 42}, + }, + { + {42, 43, 42, 43}, + {43, 42, 43, 42}, + {42, 43, 42, 43}, + {43, 42, 43, 42}, + }, + { + {42, 43, 42, 43}, + {43, 43, 43, 43}, + {42, 43, 42, 43}, + {43, 43, 43, 43}, + }, + { + {43, 43, 43, 43}, + {43, 43, 43, 43}, + {43, 43, 43, 43}, + {43, 43, 43, 43}, + }, + { + {43, 43, 43, 43}, + {44, 43, 44, 43}, + {43, 43, 43, 43}, + {44, 43, 44, 43}, + }, + { + {43, 43, 43, 44}, + {44, 43, 44, 43}, + {43, 44, 43, 44}, + {44, 43, 44, 43}, + }, + { + {43, 44, 43, 44}, + {44, 43, 44, 44}, + {43, 44, 43, 44}, + {44, 44, 44, 44}, + }, + { + {43, 44, 44, 44}, + {44, 44, 44, 44}, + {44, 44, 44, 44}, + {44, 44, 44, 44}, + }, + { + {44, 44, 44, 44}, + {44, 44, 45, 44}, + {44, 44, 44, 44}, + {45, 44, 45, 44}, + }, + { + {44, 44, 44, 45}, + {45, 44, 45, 44}, + {44, 45, 44, 45}, + {45, 44, 45, 44}, + }, + { + {44, 45, 44, 45}, + {45, 44, 45, 45}, + {44, 45, 44, 45}, + {45, 45, 45, 45}, + }, + { + {44, 45, 45, 45}, + {45, 45, 45, 45}, + {45, 45, 45, 45}, + {45, 45, 45, 45}, + }, + { + {45, 45, 45, 45}, + {45, 45, 46, 45}, + {45, 45, 45, 45}, + {46, 45, 46, 45}, + }, + { + {45, 45, 45, 46}, + {46, 45, 46, 45}, + {45, 46, 45, 46}, + {46, 45, 46, 45}, + }, + { + {45, 46, 45, 46}, + {46, 45, 46, 46}, + {45, 46, 45, 46}, + {46, 46, 46, 46}, + }, + { + {45, 46, 46, 46}, + {46, 46, 46, 46}, + {46, 46, 46, 46}, + {46, 46, 46, 46}, + }, + { + {46, 46, 46, 46}, + {46, 46, 47, 46}, + {46, 46, 46, 46}, + {47, 46, 47, 46}, + }, + { + {46, 46, 46, 47}, + {47, 46, 47, 46}, + {46, 47, 46, 47}, + {47, 46, 47, 46}, + }, + { + {46, 47, 46, 47}, + {47, 46, 47, 47}, + {46, 47, 46, 47}, + {47, 47, 47, 47}, + }, + { + {46, 47, 47, 47}, + {47, 47, 47, 47}, + {47, 47, 47, 47}, + {47, 47, 47, 47}, + }, + { + {47, 47, 47, 47}, + {47, 47, 48, 47}, + {47, 47, 47, 47}, + {48, 47, 48, 47}, + }, + { + {47, 47, 47, 48}, + {48, 47, 48, 47}, + {47, 48, 47, 48}, + {48, 47, 48, 47}, + }, + { + {47, 48, 47, 48}, + {48, 47, 48, 48}, + {47, 48, 47, 48}, + {48, 48, 48, 48}, + }, + { + {47, 48, 48, 48}, + {48, 48, 48, 48}, + {48, 48, 48, 48}, + {48, 48, 48, 48}, + }, + { + {48, 48, 48, 48}, + {48, 48, 49, 48}, + {48, 48, 48, 48}, + {49, 48, 49, 48}, + }, + { + {48, 48, 48, 49}, + {49, 48, 49, 48}, + {48, 49, 48, 49}, + {49, 48, 49, 48}, + }, + { + {48, 49, 48, 49}, + {49, 48, 49, 49}, + {48, 49, 48, 49}, + {49, 49, 49, 49}, + }, + { + {48, 49, 49, 49}, + {49, 49, 49, 49}, + {49, 49, 49, 49}, + {49, 49, 49, 49}, + }, + { + {49, 49, 49, 49}, + {49, 49, 50, 49}, + {49, 49, 49, 49}, + {50, 49, 50, 49}, + }, + { + {49, 49, 49, 50}, + {50, 49, 50, 49}, + {49, 50, 49, 50}, + {50, 49, 50, 49}, + }, + { + {49, 50, 49, 50}, + {50, 49, 50, 50}, + {49, 50, 49, 50}, + {50, 50, 50, 50}, + }, + { + {49, 50, 50, 50}, + {50, 50, 50, 50}, + {50, 50, 50, 50}, + {50, 50, 50, 50}, + }, + { + {50, 50, 50, 50}, + {50, 50, 51, 50}, + {50, 50, 50, 50}, + {51, 50, 51, 50}, + }, + { + {50, 50, 50, 51}, + {51, 50, 51, 50}, + {50, 51, 50, 51}, + {51, 50, 51, 50}, + }, + { + {50, 51, 50, 51}, + {51, 50, 51, 51}, + {50, 51, 50, 51}, + {51, 51, 51, 51}, + }, + { + {50, 51, 51, 51}, + {51, 51, 51, 51}, + {51, 51, 51, 51}, + {51, 51, 51, 51}, + }, + { + {51, 51, 51, 51}, + {51, 51, 52, 51}, + {51, 51, 51, 51}, + {52, 51, 52, 51}, + }, + { + {51, 51, 51, 52}, + {52, 51, 52, 51}, + {51, 52, 51, 51}, + {52, 51, 52, 51}, + }, + { + {51, 52, 51, 52}, + {52, 51, 52, 52}, + {51, 52, 51, 52}, + {52, 52, 52, 51}, + }, + { + {51, 52, 52, 52}, + {52, 52, 52, 52}, + {52, 52, 51, 52}, + {52, 52, 52, 52}, + }, + { + {52, 52, 52, 52}, + {52, 52, 53, 52}, + {52, 52, 52, 52}, + {53, 52, 52, 52}, + }, + { + {52, 52, 52, 53}, + {53, 52, 53, 52}, + {52, 53, 52, 52}, + {53, 52, 53, 52}, + }, + { + {52, 53, 52, 53}, + {53, 52, 53, 53}, + {52, 53, 52, 53}, + {53, 53, 53, 52}, + }, + { + {52, 53, 53, 53}, + {53, 53, 53, 53}, + {53, 53, 52, 53}, + {53, 53, 53, 53}, + }, + { + {53, 53, 53, 53}, + {53, 53, 54, 53}, + {53, 53, 53, 53}, + {54, 53, 53, 53}, + }, + { + {53, 53, 53, 54}, + {54, 53, 54, 53}, + {53, 54, 53, 53}, + {54, 53, 54, 53}, + }, + { + {53, 54, 53, 54}, + {54, 53, 54, 54}, + {53, 54, 53, 54}, + {54, 54, 54, 53}, + }, + { + {53, 54, 54, 54}, + {54, 54, 54, 54}, + {54, 54, 53, 54}, + {54, 54, 54, 54}, + }, + { + {54, 54, 54, 54}, + {54, 54, 55, 54}, + {54, 54, 54, 54}, + {55, 54, 54, 54}, + }, + { + {54, 54, 54, 55}, + {55, 54, 55, 54}, + {54, 55, 54, 54}, + {55, 54, 55, 54}, + }, + { + {54, 55, 54, 55}, + {55, 54, 55, 55}, + {54, 55, 54, 55}, + {55, 55, 55, 54}, + }, + { + {54, 55, 55, 55}, + {55, 55, 55, 55}, + {55, 55, 54, 55}, + {55, 55, 55, 55}, + }, + { + {55, 55, 55, 55}, + {55, 55, 56, 55}, + {55, 55, 55, 55}, + {56, 55, 55, 55}, + }, + { + {55, 55, 55, 55}, + {56, 55, 56, 55}, + {55, 56, 55, 55}, + {56, 55, 56, 55}, + }, + { + {55, 56, 55, 56}, + {56, 55, 56, 55}, + {55, 56, 55, 56}, + {56, 56, 56, 55}, + }, + { + {55, 56, 55, 56}, + {56, 56, 56, 56}, + {56, 56, 55, 56}, + {56, 56, 56, 56}, + }, + { + {56, 56, 56, 56}, + {56, 56, 56, 56}, + {56, 56, 56, 56}, + {57, 56, 56, 56}, + }, + { + {56, 56, 56, 56}, + {57, 56, 57, 56}, + {56, 57, 56, 56}, + {57, 56, 57, 56}, + }, + { + {56, 57, 56, 57}, + {57, 56, 57, 56}, + {56, 57, 56, 57}, + {57, 57, 57, 56}, + }, + { + {56, 57, 56, 57}, + {57, 57, 57, 57}, + {57, 57, 56, 57}, + {57, 57, 57, 57}, + }, + { + {57, 57, 57, 57}, + {57, 57, 57, 57}, + {57, 57, 57, 57}, + {58, 57, 57, 57}, + }, + { + {57, 57, 57, 57}, + {58, 57, 58, 57}, + {57, 58, 57, 57}, + {58, 57, 58, 57}, + }, + { + {57, 58, 57, 58}, + {58, 57, 58, 57}, + {57, 58, 57, 58}, + {58, 58, 58, 57}, + }, + { + {57, 58, 57, 58}, + {58, 58, 58, 58}, + {58, 58, 57, 58}, + {58, 58, 58, 58}, + }, + { + {58, 58, 58, 58}, + {58, 58, 58, 58}, + {58, 58, 58, 58}, + {59, 58, 58, 58}, + }, + { + {58, 58, 58, 58}, + {59, 58, 59, 58}, + {58, 59, 58, 58}, + {59, 58, 59, 58}, + }, + { + {58, 59, 58, 59}, + {59, 58, 59, 58}, + {58, 59, 58, 59}, + {59, 59, 59, 58}, + }, + { + {58, 59, 58, 59}, + {59, 59, 59, 59}, + {59, 59, 58, 59}, + {59, 59, 59, 59}, + }, + { + {59, 59, 59, 59}, + {59, 59, 59, 59}, + {59, 59, 59, 59}, + {60, 59, 59, 59}, + }, + { + {59, 59, 59, 59}, + {60, 59, 60, 59}, + {59, 59, 59, 59}, + {60, 59, 60, 59}, + }, + { + {59, 60, 59, 60}, + {60, 59, 60, 59}, + {59, 60, 59, 60}, + {60, 59, 60, 59}, + }, + { + {59, 60, 59, 60}, + {60, 60, 60, 60}, + {59, 60, 59, 60}, + {60, 60, 60, 60}, + }, + { + {60, 60, 60, 60}, + {60, 60, 60, 60}, + {60, 60, 60, 60}, + {60, 60, 60, 60}, + }, + { + {60, 60, 60, 60}, + {61, 60, 61, 60}, + {60, 60, 60, 60}, + {61, 60, 61, 60}, + }, + { + {60, 61, 60, 61}, + {61, 60, 61, 60}, + {60, 61, 60, 61}, + {61, 60, 61, 60}, + }, + { + {60, 61, 60, 61}, + {61, 61, 61, 61}, + {60, 61, 60, 61}, + {61, 61, 61, 61}, + }, + { + {61, 61, 61, 61}, + {61, 61, 61, 61}, + {61, 61, 61, 61}, + {61, 61, 61, 61}, + }, + { + {61, 61, 61, 61}, + {62, 61, 62, 61}, + {61, 61, 61, 61}, + {62, 61, 62, 61}, + }, + { + {61, 62, 61, 62}, + {62, 61, 62, 61}, + {61, 62, 61, 62}, + {62, 61, 62, 61}, + }, + { + {61, 62, 61, 62}, + {62, 62, 62, 62}, + {61, 62, 61, 62}, + {62, 62, 62, 62}, + }, + { + {62, 62, 62, 62}, + {62, 62, 62, 62}, + {62, 62, 62, 62}, + {62, 62, 62, 62}, + }, + { + {62, 62, 62, 62}, + {63, 62, 63, 62}, + {62, 62, 62, 62}, + {63, 62, 63, 62}, + }, + { + {62, 63, 62, 63}, + {63, 62, 63, 62}, + {62, 63, 62, 63}, + {63, 62, 63, 62}, + }, + { + {62, 63, 62, 63}, + {63, 63, 63, 63}, + {62, 63, 62, 63}, + {63, 63, 63, 63}, + }, + { + {63, 63, 63, 63}, + {63, 63, 63, 63}, + {63, 63, 63, 63}, + {63, 63, 63, 63}, + }, }; -static const uint8_t dither_rb2x2[256][2][2] = -{ - { - {0, 0}, - {0, 0}, - }, - { - {0, 0}, - {1, 0}, - }, - { - {0, 0}, - {1, 0}, - }, - { - {0, 1}, - {1, 0}, - }, - { - {0, 1}, - {1, 0}, - }, - { - {0, 1}, - {1, 1}, - }, - { - {0, 1}, - {1, 1}, - }, - { - {1, 1}, - {1, 1}, - }, - { - {1, 1}, - {1, 1}, - }, - { - {1, 1}, - {2, 1}, - }, - { - {1, 1}, - {2, 1}, - }, - { - {1, 2}, - {2, 1}, - }, - { - {1, 2}, - {2, 1}, - }, - { - {1, 2}, - {2, 2}, - }, - { - {1, 2}, - {2, 2}, - }, - { - {2, 2}, - {2, 2}, - }, - { - {2, 2}, - {2, 2}, - }, - { - {2, 2}, - {2, 2}, - }, - { - {2, 2}, - {3, 2}, - }, - { - {2, 2}, - {3, 2}, - }, - { - {2, 3}, - {3, 2}, - }, - { - {2, 3}, - {3, 2}, - }, - { - {2, 3}, - {3, 3}, - }, - { - {2, 3}, - {3, 3}, - }, - { - {3, 3}, - {3, 3}, - }, - { - {3, 3}, - {3, 3}, - }, - { - {3, 3}, - {4, 3}, - }, - { - {3, 3}, - {4, 3}, - }, - { - {3, 4}, - {4, 3}, - }, - { - {3, 4}, - {4, 3}, - }, - { - {3, 4}, - {4, 4}, - }, - { - {3, 4}, - {4, 4}, - }, - { - {4, 4}, - {4, 4}, - }, - { - {4, 4}, - {4, 4}, - }, - { - {4, 4}, - {5, 4}, - }, - { - {4, 4}, - {5, 4}, - }, - { - {4, 5}, - {5, 4}, - }, - { - {4, 5}, - {5, 4}, - }, - { - {4, 5}, - {5, 5}, - }, - { - {4, 5}, - {5, 5}, - }, - { - {5, 5}, - {5, 5}, - }, - { - {5, 5}, - {5, 5}, - }, - { - {5, 5}, - {6, 5}, - }, - { - {5, 5}, - {6, 5}, - }, - { - {5, 6}, - {6, 5}, - }, - { - {5, 6}, - {6, 5}, - }, - { - {5, 6}, - {6, 6}, - }, - { - {5, 6}, - {6, 6}, - }, - { - {5, 6}, - {6, 6}, - }, - { - {6, 6}, - {6, 6}, - }, - { - {6, 6}, - {6, 6}, - }, - { - {6, 6}, - {7, 6}, - }, - { - {6, 6}, - {7, 6}, - }, - { - {6, 7}, - {7, 6}, - }, - { - {6, 7}, - {7, 6}, - }, - { - {6, 7}, - {7, 7}, - }, - { - {6, 7}, - {7, 7}, - }, - { - {7, 7}, - {7, 7}, - }, - { - {7, 7}, - {7, 7}, - }, - { - {7, 7}, - {8, 7}, - }, - { - {7, 7}, - {8, 7}, - }, - { - {7, 8}, - {8, 7}, - }, - { - {7, 8}, - {8, 7}, - }, - { - {7, 8}, - {8, 8}, - }, - { - {7, 8}, - {8, 8}, - }, - { - {8, 8}, - {8, 8}, - }, - { - {8, 8}, - {8, 8}, - }, - { - {8, 8}, - {9, 8}, - }, - { - {8, 8}, - {9, 8}, - }, - { - {8, 9}, - {9, 8}, - }, - { - {8, 9}, - {9, 8}, - }, - { - {8, 9}, - {9, 9}, - }, - { - {8, 9}, - {9, 9}, - }, - { - {9, 9}, - {9, 9}, - }, - { - {9, 9}, - {9, 9}, - }, - { - {9, 9}, - {10, 9}, - }, - { - {9, 9}, - {10, 9}, - }, - { - {9, 10}, - {10, 9}, - }, - { - {9, 10}, - {10, 9}, - }, - { - {9, 10}, - {10, 10}, - }, - { - {9, 10}, - {10, 10}, - }, - { - {9, 10}, - {10, 10}, - }, - { - {10, 10}, - {10, 10}, - }, - { - {10, 10}, - {10, 10}, - }, - { - {10, 10}, - {11, 10}, - }, - { - {10, 10}, - {11, 10}, - }, - { - {10, 11}, - {11, 10}, - }, - { - {10, 11}, - {11, 10}, - }, - { - {10, 11}, - {11, 11}, - }, - { - {10, 11}, - {11, 11}, - }, - { - {11, 11}, - {11, 11}, - }, - { - {11, 11}, - {11, 11}, - }, - { - {11, 11}, - {12, 11}, - }, - { - {11, 11}, - {12, 11}, - }, - { - {11, 12}, - {12, 11}, - }, - { - {11, 12}, - {12, 11}, - }, - { - {11, 12}, - {12, 12}, - }, - { - {11, 12}, - {12, 12}, - }, - { - {12, 12}, - {12, 12}, - }, - { - {12, 12}, - {12, 12}, - }, - { - {12, 12}, - {13, 12}, - }, - { - {12, 12}, - {13, 12}, - }, - { - {12, 13}, - {13, 12}, - }, - { - {12, 13}, - {13, 12}, - }, - { - {12, 13}, - {13, 13}, - }, - { - {12, 13}, - {13, 13}, - }, - { - {13, 13}, - {13, 13}, - }, - { - {13, 13}, - {13, 13}, - }, - { - {13, 13}, - {14, 13}, - }, - { - {13, 13}, - {14, 13}, - }, - { - {13, 14}, - {14, 13}, - }, - { - {13, 14}, - {14, 13}, - }, - { - {13, 14}, - {14, 13}, - }, - { - {13, 14}, - {14, 14}, - }, - { - {13, 14}, - {14, 14}, - }, - { - {14, 14}, - {14, 14}, - }, - { - {14, 14}, - {14, 14}, - }, - { - {14, 14}, - {15, 14}, - }, - { - {14, 14}, - {15, 14}, - }, - { - {14, 15}, - {15, 14}, - }, - { - {14, 15}, - {15, 14}, - }, - { - {14, 15}, - {15, 15}, - }, - { - {14, 15}, - {15, 15}, - }, - { - {15, 15}, - {15, 15}, - }, - { - {15, 15}, - {15, 15}, - }, - { - {15, 15}, - {16, 15}, - }, - { - {15, 15}, - {16, 15}, - }, - { - {15, 16}, - {16, 15}, - }, - { - {15, 16}, - {16, 15}, - }, - { - {15, 16}, - {16, 16}, - }, - { - {15, 16}, - {16, 16}, - }, - { - {16, 16}, - {16, 16}, - }, - { - {16, 16}, - {16, 16}, - }, - { - {16, 16}, - {17, 16}, - }, - { - {16, 16}, - {17, 16}, - }, - { - {16, 17}, - {17, 16}, - }, - { - {16, 17}, - {17, 16}, - }, - { - {16, 17}, - {17, 17}, - }, - { - {16, 17}, - {17, 17}, - }, - { - {17, 17}, - {17, 17}, - }, - { - {17, 17}, - {17, 17}, - }, - { - {17, 17}, - {18, 17}, - }, - { - {17, 17}, - {18, 17}, - }, - { - {17, 18}, - {18, 17}, - }, - { - {17, 18}, - {18, 17}, - }, - { - {17, 18}, - {18, 18}, - }, - { - {17, 18}, - {18, 18}, - }, - { - {18, 18}, - {18, 18}, - }, - { - {18, 18}, - {18, 18}, - }, - { - {18, 18}, - {19, 18}, - }, - { - {18, 18}, - {19, 18}, - }, - { - {18, 19}, - {19, 18}, - }, - { - {18, 19}, - {19, 18}, - }, - { - {18, 19}, - {19, 19}, - }, - { - {18, 19}, - {19, 19}, - }, - { - {19, 19}, - {19, 19}, - }, - { - {19, 19}, - {19, 19}, - }, - { - {19, 19}, - {20, 19}, - }, - { - {19, 19}, - {20, 19}, - }, - { - {19, 20}, - {20, 19}, - }, - { - {19, 20}, - {20, 19}, - }, - { - {19, 20}, - {20, 19}, - }, - { - {19, 20}, - {20, 20}, - }, - { - {19, 20}, - {20, 20}, - }, - { - {20, 20}, - {20, 20}, - }, - { - {20, 20}, - {20, 20}, - }, - { - {20, 20}, - {21, 20}, - }, - { - {20, 20}, - {21, 20}, - }, - { - {20, 21}, - {21, 20}, - }, - { - {20, 21}, - {21, 20}, - }, - { - {20, 21}, - {21, 21}, - }, - { - {20, 21}, - {21, 21}, - }, - { - {21, 21}, - {21, 21}, - }, - { - {21, 21}, - {21, 21}, - }, - { - {21, 21}, - {22, 21}, - }, - { - {21, 21}, - {22, 21}, - }, - { - {21, 22}, - {22, 21}, - }, - { - {21, 22}, - {22, 21}, - }, - { - {21, 22}, - {22, 22}, - }, - { - {21, 22}, - {22, 22}, - }, - { - {22, 22}, - {22, 22}, - }, - { - {22, 22}, - {22, 22}, - }, - { - {22, 22}, - {23, 22}, - }, - { - {22, 22}, - {23, 22}, - }, - { - {22, 23}, - {23, 22}, - }, - { - {22, 23}, - {23, 22}, - }, - { - {22, 23}, - {23, 23}, - }, - { - {22, 23}, - {23, 23}, - }, - { - {23, 23}, - {23, 23}, - }, - { - {23, 23}, - {23, 23}, - }, - { - {23, 23}, - {24, 23}, - }, - { - {23, 23}, - {24, 23}, - }, - { - {23, 23}, - {24, 23}, - }, - { - {23, 24}, - {24, 23}, - }, - { - {23, 24}, - {24, 23}, - }, - { - {23, 24}, - {24, 24}, - }, - { - {23, 24}, - {24, 24}, - }, - { - {24, 24}, - {24, 24}, - }, - { - {24, 24}, - {24, 24}, - }, - { - {24, 24}, - {25, 24}, - }, - { - {24, 24}, - {25, 24}, - }, - { - {24, 25}, - {25, 24}, - }, - { - {24, 25}, - {25, 24}, - }, - { - {24, 25}, - {25, 25}, - }, - { - {24, 25}, - {25, 25}, - }, - { - {25, 25}, - {25, 25}, - }, - { - {25, 25}, - {25, 25}, - }, - { - {25, 25}, - {26, 25}, - }, - { - {25, 25}, - {26, 25}, - }, - { - {25, 26}, - {26, 25}, - }, - { - {25, 26}, - {26, 25}, - }, - { - {25, 26}, - {26, 26}, - }, - { - {25, 26}, - {26, 26}, - }, - { - {26, 26}, - {26, 26}, - }, - { - {26, 26}, - {26, 26}, - }, - { - {26, 26}, - {27, 26}, - }, - { - {26, 26}, - {27, 26}, - }, - { - {26, 27}, - {27, 26}, - }, - { - {26, 27}, - {27, 26}, - }, - { - {26, 27}, - {27, 27}, - }, - { - {26, 27}, - {27, 27}, - }, - { - {27, 27}, - {27, 27}, - }, - { - {27, 27}, - {27, 27}, - }, - { - {27, 27}, - {28, 27}, - }, - { - {27, 27}, - {28, 27}, - }, - { - {27, 27}, - {28, 27}, - }, - { - {27, 28}, - {28, 27}, - }, - { - {27, 28}, - {28, 27}, - }, - { - {27, 28}, - {28, 28}, - }, - { - {27, 28}, - {28, 28}, - }, - { - {28, 28}, - {28, 28}, - }, - { - {28, 28}, - {28, 28}, - }, - { - {28, 28}, - {29, 28}, - }, - { - {28, 28}, - {29, 28}, - }, - { - {28, 29}, - {29, 28}, - }, - { - {28, 29}, - {29, 28}, - }, - { - {28, 29}, - {29, 29}, - }, - { - {28, 29}, - {29, 29}, - }, - { - {29, 29}, - {29, 29}, - }, - { - {29, 29}, - {29, 29}, - }, - { - {29, 29}, - {30, 29}, - }, - { - {29, 29}, - {30, 29}, - }, - { - {29, 30}, - {30, 29}, - }, - { - {29, 30}, - {30, 29}, - }, - { - {29, 30}, - {30, 30}, - }, - { - {29, 30}, - {30, 30}, - }, - { - {30, 30}, - {30, 30}, - }, - { - {30, 30}, - {30, 30}, - }, - { - {30, 30}, - {31, 30}, - }, - { - {30, 30}, - {31, 30}, - }, - { - {30, 31}, - {31, 30}, - }, - { - {30, 31}, - {31, 30}, - }, - { - {30, 31}, - {31, 31}, - }, - { - {30, 31}, - {31, 31}, - }, - { - {31, 31}, - {31, 31}, - }, - { - {31, 31}, - {31, 31}, - }, +static const uint8_t dither_rb2x2[256][2][2] = { + { + {0, 0}, + {0, 0}, + }, + { + {0, 0}, + {1, 0}, + }, + { + {0, 0}, + {1, 0}, + }, + { + {0, 1}, + {1, 0}, + }, + { + {0, 1}, + {1, 0}, + }, + { + {0, 1}, + {1, 1}, + }, + { + {0, 1}, + {1, 1}, + }, + { + {1, 1}, + {1, 1}, + }, + { + {1, 1}, + {1, 1}, + }, + { + {1, 1}, + {2, 1}, + }, + { + {1, 1}, + {2, 1}, + }, + { + {1, 2}, + {2, 1}, + }, + { + {1, 2}, + {2, 1}, + }, + { + {1, 2}, + {2, 2}, + }, + { + {1, 2}, + {2, 2}, + }, + { + {2, 2}, + {2, 2}, + }, + { + {2, 2}, + {2, 2}, + }, + { + {2, 2}, + {2, 2}, + }, + { + {2, 2}, + {3, 2}, + }, + { + {2, 2}, + {3, 2}, + }, + { + {2, 3}, + {3, 2}, + }, + { + {2, 3}, + {3, 2}, + }, + { + {2, 3}, + {3, 3}, + }, + { + {2, 3}, + {3, 3}, + }, + { + {3, 3}, + {3, 3}, + }, + { + {3, 3}, + {3, 3}, + }, + { + {3, 3}, + {4, 3}, + }, + { + {3, 3}, + {4, 3}, + }, + { + {3, 4}, + {4, 3}, + }, + { + {3, 4}, + {4, 3}, + }, + { + {3, 4}, + {4, 4}, + }, + { + {3, 4}, + {4, 4}, + }, + { + {4, 4}, + {4, 4}, + }, + { + {4, 4}, + {4, 4}, + }, + { + {4, 4}, + {5, 4}, + }, + { + {4, 4}, + {5, 4}, + }, + { + {4, 5}, + {5, 4}, + }, + { + {4, 5}, + {5, 4}, + }, + { + {4, 5}, + {5, 5}, + }, + { + {4, 5}, + {5, 5}, + }, + { + {5, 5}, + {5, 5}, + }, + { + {5, 5}, + {5, 5}, + }, + { + {5, 5}, + {6, 5}, + }, + { + {5, 5}, + {6, 5}, + }, + { + {5, 6}, + {6, 5}, + }, + { + {5, 6}, + {6, 5}, + }, + { + {5, 6}, + {6, 6}, + }, + { + {5, 6}, + {6, 6}, + }, + { + {5, 6}, + {6, 6}, + }, + { + {6, 6}, + {6, 6}, + }, + { + {6, 6}, + {6, 6}, + }, + { + {6, 6}, + {7, 6}, + }, + { + {6, 6}, + {7, 6}, + }, + { + {6, 7}, + {7, 6}, + }, + { + {6, 7}, + {7, 6}, + }, + { + {6, 7}, + {7, 7}, + }, + { + {6, 7}, + {7, 7}, + }, + { + {7, 7}, + {7, 7}, + }, + { + {7, 7}, + {7, 7}, + }, + { + {7, 7}, + {8, 7}, + }, + { + {7, 7}, + {8, 7}, + }, + { + {7, 8}, + {8, 7}, + }, + { + {7, 8}, + {8, 7}, + }, + { + {7, 8}, + {8, 8}, + }, + { + {7, 8}, + {8, 8}, + }, + { + {8, 8}, + {8, 8}, + }, + { + {8, 8}, + {8, 8}, + }, + { + {8, 8}, + {9, 8}, + }, + { + {8, 8}, + {9, 8}, + }, + { + {8, 9}, + {9, 8}, + }, + { + {8, 9}, + {9, 8}, + }, + { + {8, 9}, + {9, 9}, + }, + { + {8, 9}, + {9, 9}, + }, + { + {9, 9}, + {9, 9}, + }, + { + {9, 9}, + {9, 9}, + }, + { + {9, 9}, + {10, 9}, + }, + { + {9, 9}, + {10, 9}, + }, + { + {9, 10}, + {10, 9}, + }, + { + {9, 10}, + {10, 9}, + }, + { + {9, 10}, + {10, 10}, + }, + { + {9, 10}, + {10, 10}, + }, + { + {9, 10}, + {10, 10}, + }, + { + {10, 10}, + {10, 10}, + }, + { + {10, 10}, + {10, 10}, + }, + { + {10, 10}, + {11, 10}, + }, + { + {10, 10}, + {11, 10}, + }, + { + {10, 11}, + {11, 10}, + }, + { + {10, 11}, + {11, 10}, + }, + { + {10, 11}, + {11, 11}, + }, + { + {10, 11}, + {11, 11}, + }, + { + {11, 11}, + {11, 11}, + }, + { + {11, 11}, + {11, 11}, + }, + { + {11, 11}, + {12, 11}, + }, + { + {11, 11}, + {12, 11}, + }, + { + {11, 12}, + {12, 11}, + }, + { + {11, 12}, + {12, 11}, + }, + { + {11, 12}, + {12, 12}, + }, + { + {11, 12}, + {12, 12}, + }, + { + {12, 12}, + {12, 12}, + }, + { + {12, 12}, + {12, 12}, + }, + { + {12, 12}, + {13, 12}, + }, + { + {12, 12}, + {13, 12}, + }, + { + {12, 13}, + {13, 12}, + }, + { + {12, 13}, + {13, 12}, + }, + { + {12, 13}, + {13, 13}, + }, + { + {12, 13}, + {13, 13}, + }, + { + {13, 13}, + {13, 13}, + }, + { + {13, 13}, + {13, 13}, + }, + { + {13, 13}, + {14, 13}, + }, + { + {13, 13}, + {14, 13}, + }, + { + {13, 14}, + {14, 13}, + }, + { + {13, 14}, + {14, 13}, + }, + { + {13, 14}, + {14, 13}, + }, + { + {13, 14}, + {14, 14}, + }, + { + {13, 14}, + {14, 14}, + }, + { + {14, 14}, + {14, 14}, + }, + { + {14, 14}, + {14, 14}, + }, + { + {14, 14}, + {15, 14}, + }, + { + {14, 14}, + {15, 14}, + }, + { + {14, 15}, + {15, 14}, + }, + { + {14, 15}, + {15, 14}, + }, + { + {14, 15}, + {15, 15}, + }, + { + {14, 15}, + {15, 15}, + }, + { + {15, 15}, + {15, 15}, + }, + { + {15, 15}, + {15, 15}, + }, + { + {15, 15}, + {16, 15}, + }, + { + {15, 15}, + {16, 15}, + }, + { + {15, 16}, + {16, 15}, + }, + { + {15, 16}, + {16, 15}, + }, + { + {15, 16}, + {16, 16}, + }, + { + {15, 16}, + {16, 16}, + }, + { + {16, 16}, + {16, 16}, + }, + { + {16, 16}, + {16, 16}, + }, + { + {16, 16}, + {17, 16}, + }, + { + {16, 16}, + {17, 16}, + }, + { + {16, 17}, + {17, 16}, + }, + { + {16, 17}, + {17, 16}, + }, + { + {16, 17}, + {17, 17}, + }, + { + {16, 17}, + {17, 17}, + }, + { + {17, 17}, + {17, 17}, + }, + { + {17, 17}, + {17, 17}, + }, + { + {17, 17}, + {18, 17}, + }, + { + {17, 17}, + {18, 17}, + }, + { + {17, 18}, + {18, 17}, + }, + { + {17, 18}, + {18, 17}, + }, + { + {17, 18}, + {18, 18}, + }, + { + {17, 18}, + {18, 18}, + }, + { + {18, 18}, + {18, 18}, + }, + { + {18, 18}, + {18, 18}, + }, + { + {18, 18}, + {19, 18}, + }, + { + {18, 18}, + {19, 18}, + }, + { + {18, 19}, + {19, 18}, + }, + { + {18, 19}, + {19, 18}, + }, + { + {18, 19}, + {19, 19}, + }, + { + {18, 19}, + {19, 19}, + }, + { + {19, 19}, + {19, 19}, + }, + { + {19, 19}, + {19, 19}, + }, + { + {19, 19}, + {20, 19}, + }, + { + {19, 19}, + {20, 19}, + }, + { + {19, 20}, + {20, 19}, + }, + { + {19, 20}, + {20, 19}, + }, + { + {19, 20}, + {20, 19}, + }, + { + {19, 20}, + {20, 20}, + }, + { + {19, 20}, + {20, 20}, + }, + { + {20, 20}, + {20, 20}, + }, + { + {20, 20}, + {20, 20}, + }, + { + {20, 20}, + {21, 20}, + }, + { + {20, 20}, + {21, 20}, + }, + { + {20, 21}, + {21, 20}, + }, + { + {20, 21}, + {21, 20}, + }, + { + {20, 21}, + {21, 21}, + }, + { + {20, 21}, + {21, 21}, + }, + { + {21, 21}, + {21, 21}, + }, + { + {21, 21}, + {21, 21}, + }, + { + {21, 21}, + {22, 21}, + }, + { + {21, 21}, + {22, 21}, + }, + { + {21, 22}, + {22, 21}, + }, + { + {21, 22}, + {22, 21}, + }, + { + {21, 22}, + {22, 22}, + }, + { + {21, 22}, + {22, 22}, + }, + { + {22, 22}, + {22, 22}, + }, + { + {22, 22}, + {22, 22}, + }, + { + {22, 22}, + {23, 22}, + }, + { + {22, 22}, + {23, 22}, + }, + { + {22, 23}, + {23, 22}, + }, + { + {22, 23}, + {23, 22}, + }, + { + {22, 23}, + {23, 23}, + }, + { + {22, 23}, + {23, 23}, + }, + { + {23, 23}, + {23, 23}, + }, + { + {23, 23}, + {23, 23}, + }, + { + {23, 23}, + {24, 23}, + }, + { + {23, 23}, + {24, 23}, + }, + { + {23, 23}, + {24, 23}, + }, + { + {23, 24}, + {24, 23}, + }, + { + {23, 24}, + {24, 23}, + }, + { + {23, 24}, + {24, 24}, + }, + { + {23, 24}, + {24, 24}, + }, + { + {24, 24}, + {24, 24}, + }, + { + {24, 24}, + {24, 24}, + }, + { + {24, 24}, + {25, 24}, + }, + { + {24, 24}, + {25, 24}, + }, + { + {24, 25}, + {25, 24}, + }, + { + {24, 25}, + {25, 24}, + }, + { + {24, 25}, + {25, 25}, + }, + { + {24, 25}, + {25, 25}, + }, + { + {25, 25}, + {25, 25}, + }, + { + {25, 25}, + {25, 25}, + }, + { + {25, 25}, + {26, 25}, + }, + { + {25, 25}, + {26, 25}, + }, + { + {25, 26}, + {26, 25}, + }, + { + {25, 26}, + {26, 25}, + }, + { + {25, 26}, + {26, 26}, + }, + { + {25, 26}, + {26, 26}, + }, + { + {26, 26}, + {26, 26}, + }, + { + {26, 26}, + {26, 26}, + }, + { + {26, 26}, + {27, 26}, + }, + { + {26, 26}, + {27, 26}, + }, + { + {26, 27}, + {27, 26}, + }, + { + {26, 27}, + {27, 26}, + }, + { + {26, 27}, + {27, 27}, + }, + { + {26, 27}, + {27, 27}, + }, + { + {27, 27}, + {27, 27}, + }, + { + {27, 27}, + {27, 27}, + }, + { + {27, 27}, + {28, 27}, + }, + { + {27, 27}, + {28, 27}, + }, + { + {27, 27}, + {28, 27}, + }, + { + {27, 28}, + {28, 27}, + }, + { + {27, 28}, + {28, 27}, + }, + { + {27, 28}, + {28, 28}, + }, + { + {27, 28}, + {28, 28}, + }, + { + {28, 28}, + {28, 28}, + }, + { + {28, 28}, + {28, 28}, + }, + { + {28, 28}, + {29, 28}, + }, + { + {28, 28}, + {29, 28}, + }, + { + {28, 29}, + {29, 28}, + }, + { + {28, 29}, + {29, 28}, + }, + { + {28, 29}, + {29, 29}, + }, + { + {28, 29}, + {29, 29}, + }, + { + {29, 29}, + {29, 29}, + }, + { + {29, 29}, + {29, 29}, + }, + { + {29, 29}, + {30, 29}, + }, + { + {29, 29}, + {30, 29}, + }, + { + {29, 30}, + {30, 29}, + }, + { + {29, 30}, + {30, 29}, + }, + { + {29, 30}, + {30, 30}, + }, + { + {29, 30}, + {30, 30}, + }, + { + {30, 30}, + {30, 30}, + }, + { + {30, 30}, + {30, 30}, + }, + { + {30, 30}, + {31, 30}, + }, + { + {30, 30}, + {31, 30}, + }, + { + {30, 31}, + {31, 30}, + }, + { + {30, 31}, + {31, 30}, + }, + { + {30, 31}, + {31, 31}, + }, + { + {30, 31}, + {31, 31}, + }, + { + {31, 31}, + {31, 31}, + }, + { + {31, 31}, + {31, 31}, + }, }; -static const uint8_t dither_g2x2[256][2][2] = -{ - { - {0, 0}, - {0, 0}, - }, - { - {0, 0}, - {1, 0}, - }, - { - {0, 1}, - {1, 0}, - }, - { - {0, 1}, - {1, 1}, - }, - { - {1, 1}, - {1, 1}, - }, - { - {1, 1}, - {2, 1}, - }, - { - {1, 2}, - {2, 1}, - }, - { - {1, 2}, - {2, 2}, - }, - { - {2, 2}, - {2, 2}, - }, - { - {2, 2}, - {3, 2}, - }, - { - {2, 3}, - {3, 2}, - }, - { - {2, 3}, - {3, 3}, - }, - { - {3, 3}, - {3, 3}, - }, - { - {3, 3}, - {4, 3}, - }, - { - {3, 4}, - {4, 3}, - }, - { - {3, 4}, - {4, 4}, - }, - { - {4, 4}, - {4, 4}, - }, - { - {4, 4}, - {5, 4}, - }, - { - {4, 5}, - {5, 4}, - }, - { - {4, 5}, - {5, 5}, - }, - { - {5, 5}, - {5, 5}, - }, - { - {5, 5}, - {6, 5}, - }, - { - {5, 6}, - {6, 5}, - }, - { - {5, 6}, - {6, 6}, - }, - { - {6, 6}, - {6, 6}, - }, - { - {6, 6}, - {7, 6}, - }, - { - {6, 7}, - {7, 6}, - }, - { - {6, 7}, - {7, 7}, - }, - { - {7, 7}, - {7, 7}, - }, - { - {7, 7}, - {8, 7}, - }, - { - {7, 8}, - {8, 7}, - }, - { - {7, 8}, - {8, 8}, - }, - { - {8, 8}, - {8, 8}, - }, - { - {8, 8}, - {9, 8}, - }, - { - {8, 9}, - {9, 8}, - }, - { - {8, 9}, - {9, 9}, - }, - { - {9, 9}, - {9, 9}, - }, - { - {9, 9}, - {10, 9}, - }, - { - {9, 10}, - {10, 9}, - }, - { - {9, 10}, - {10, 10}, - }, - { - {10, 10}, - {10, 10}, - }, - { - {10, 10}, - {11, 10}, - }, - { - {10, 11}, - {11, 10}, - }, - { - {10, 11}, - {11, 11}, - }, - { - {11, 11}, - {11, 11}, - }, - { - {11, 11}, - {12, 11}, - }, - { - {11, 12}, - {12, 11}, - }, - { - {11, 12}, - {12, 12}, - }, - { - {11, 12}, - {12, 12}, - }, - { - {12, 12}, - {12, 12}, - }, - { - {12, 12}, - {13, 12}, - }, - { - {12, 13}, - {13, 12}, - }, - { - {12, 13}, - {13, 13}, - }, - { - {13, 13}, - {13, 13}, - }, - { - {13, 13}, - {14, 13}, - }, - { - {13, 14}, - {14, 13}, - }, - { - {13, 14}, - {14, 14}, - }, - { - {14, 14}, - {14, 14}, - }, - { - {14, 14}, - {15, 14}, - }, - { - {14, 15}, - {15, 14}, - }, - { - {14, 15}, - {15, 15}, - }, - { - {15, 15}, - {15, 15}, - }, - { - {15, 15}, - {16, 15}, - }, - { - {15, 16}, - {16, 15}, - }, - { - {15, 16}, - {16, 16}, - }, - { - {16, 16}, - {16, 16}, - }, - { - {16, 16}, - {17, 16}, - }, - { - {16, 17}, - {17, 16}, - }, - { - {16, 17}, - {17, 17}, - }, - { - {17, 17}, - {17, 17}, - }, - { - {17, 17}, - {18, 17}, - }, - { - {17, 18}, - {18, 17}, - }, - { - {17, 18}, - {18, 18}, - }, - { - {18, 18}, - {18, 18}, - }, - { - {18, 18}, - {19, 18}, - }, - { - {18, 19}, - {19, 18}, - }, - { - {18, 19}, - {19, 19}, - }, - { - {19, 19}, - {19, 19}, - }, - { - {19, 19}, - {20, 19}, - }, - { - {19, 20}, - {20, 19}, - }, - { - {19, 20}, - {20, 20}, - }, - { - {20, 20}, - {20, 20}, - }, - { - {20, 20}, - {21, 20}, - }, - { - {20, 21}, - {21, 20}, - }, - { - {20, 21}, - {21, 21}, - }, - { - {21, 21}, - {21, 21}, - }, - { - {21, 21}, - {22, 21}, - }, - { - {21, 22}, - {22, 21}, - }, - { - {21, 22}, - {22, 22}, - }, - { - {22, 22}, - {22, 22}, - }, - { - {22, 22}, - {23, 22}, - }, - { - {22, 23}, - {23, 22}, - }, - { - {22, 23}, - {23, 23}, - }, - { - {23, 23}, - {23, 23}, - }, - { - {23, 23}, - {24, 23}, - }, - { - {23, 24}, - {24, 23}, - }, - { - {23, 24}, - {24, 24}, - }, - { - {24, 24}, - {24, 24}, - }, - { - {24, 24}, - {25, 24}, - }, - { - {24, 25}, - {25, 24}, - }, - { - {24, 25}, - {25, 25}, - }, - { - {25, 25}, - {25, 25}, - }, - { - {25, 25}, - {26, 25}, - }, - { - {25, 26}, - {26, 25}, - }, - { - {25, 26}, - {26, 26}, - }, - { - {26, 26}, - {26, 26}, - }, - { - {26, 26}, - {27, 26}, - }, - { - {26, 27}, - {27, 26}, - }, - { - {26, 27}, - {27, 27}, - }, - { - {27, 27}, - {27, 27}, - }, - { - {27, 27}, - {28, 27}, - }, - { - {27, 28}, - {28, 27}, - }, - { - {27, 28}, - {28, 28}, - }, - { - {28, 28}, - {28, 28}, - }, - { - {28, 28}, - {29, 28}, - }, - { - {28, 29}, - {29, 28}, - }, - { - {28, 29}, - {29, 29}, - }, - { - {29, 29}, - {29, 29}, - }, - { - {29, 29}, - {30, 29}, - }, - { - {29, 30}, - {30, 29}, - }, - { - {29, 30}, - {30, 30}, - }, - { - {30, 30}, - {30, 30}, - }, - { - {30, 30}, - {31, 30}, - }, - { - {30, 31}, - {31, 30}, - }, - { - {30, 31}, - {31, 31}, - }, - { - {31, 31}, - {31, 31}, - }, - { - {31, 31}, - {32, 31}, - }, - { - {31, 32}, - {32, 31}, - }, - { - {31, 32}, - {32, 32}, - }, - { - {32, 32}, - {32, 32}, - }, - { - {32, 32}, - {33, 32}, - }, - { - {32, 33}, - {33, 32}, - }, - { - {32, 33}, - {33, 33}, - }, - { - {33, 33}, - {33, 33}, - }, - { - {33, 33}, - {34, 33}, - }, - { - {33, 34}, - {34, 33}, - }, - { - {33, 34}, - {34, 34}, - }, - { - {34, 34}, - {34, 34}, - }, - { - {34, 34}, - {35, 34}, - }, - { - {34, 35}, - {35, 34}, - }, - { - {34, 35}, - {35, 35}, - }, - { - {35, 35}, - {35, 35}, - }, - { - {35, 35}, - {36, 35}, - }, - { - {35, 36}, - {36, 35}, - }, - { - {35, 36}, - {36, 35}, - }, - { - {35, 36}, - {36, 36}, - }, - { - {36, 36}, - {36, 36}, - }, - { - {36, 36}, - {37, 36}, - }, - { - {36, 37}, - {37, 36}, - }, - { - {36, 37}, - {37, 37}, - }, - { - {37, 37}, - {37, 37}, - }, - { - {37, 37}, - {38, 37}, - }, - { - {37, 38}, - {38, 37}, - }, - { - {37, 38}, - {38, 38}, - }, - { - {38, 38}, - {38, 38}, - }, - { - {38, 38}, - {39, 38}, - }, - { - {38, 39}, - {39, 38}, - }, - { - {38, 39}, - {39, 39}, - }, - { - {39, 39}, - {39, 39}, - }, - { - {39, 39}, - {40, 39}, - }, - { - {39, 40}, - {40, 39}, - }, - { - {39, 40}, - {40, 40}, - }, - { - {40, 40}, - {40, 40}, - }, - { - {40, 40}, - {41, 40}, - }, - { - {40, 41}, - {41, 40}, - }, - { - {40, 41}, - {41, 41}, - }, - { - {41, 41}, - {41, 41}, - }, - { - {41, 41}, - {42, 41}, - }, - { - {41, 42}, - {42, 41}, - }, - { - {41, 42}, - {42, 42}, - }, - { - {42, 42}, - {42, 42}, - }, - { - {42, 42}, - {43, 42}, - }, - { - {42, 43}, - {43, 42}, - }, - { - {42, 43}, - {43, 43}, - }, - { - {43, 43}, - {43, 43}, - }, - { - {43, 43}, - {44, 43}, - }, - { - {43, 44}, - {44, 43}, - }, - { - {43, 44}, - {44, 44}, - }, - { - {44, 44}, - {44, 44}, - }, - { - {44, 44}, - {45, 44}, - }, - { - {44, 45}, - {45, 44}, - }, - { - {44, 45}, - {45, 45}, - }, - { - {45, 45}, - {45, 45}, - }, - { - {45, 45}, - {46, 45}, - }, - { - {45, 46}, - {46, 45}, - }, - { - {45, 46}, - {46, 46}, - }, - { - {46, 46}, - {46, 46}, - }, - { - {46, 46}, - {47, 46}, - }, - { - {46, 47}, - {47, 46}, - }, - { - {46, 47}, - {47, 47}, - }, - { - {47, 47}, - {47, 47}, - }, - { - {47, 47}, - {48, 47}, - }, - { - {47, 48}, - {48, 47}, - }, - { - {47, 48}, - {48, 48}, - }, - { - {48, 48}, - {48, 48}, - }, - { - {48, 48}, - {49, 48}, - }, - { - {48, 49}, - {49, 48}, - }, - { - {48, 49}, - {49, 49}, - }, - { - {49, 49}, - {49, 49}, - }, - { - {49, 49}, - {50, 49}, - }, - { - {49, 50}, - {50, 49}, - }, - { - {49, 50}, - {50, 50}, - }, - { - {50, 50}, - {50, 50}, - }, - { - {50, 50}, - {51, 50}, - }, - { - {50, 51}, - {51, 50}, - }, - { - {50, 51}, - {51, 51}, - }, - { - {51, 51}, - {51, 51}, - }, - { - {51, 51}, - {52, 51}, - }, - { - {51, 52}, - {52, 51}, - }, - { - {51, 52}, - {52, 52}, - }, - { - {52, 52}, - {52, 52}, - }, - { - {52, 52}, - {53, 52}, - }, - { - {52, 53}, - {53, 52}, - }, - { - {52, 53}, - {53, 53}, - }, - { - {53, 53}, - {53, 53}, - }, - { - {53, 53}, - {54, 53}, - }, - { - {53, 54}, - {54, 53}, - }, - { - {53, 54}, - {54, 54}, - }, - { - {54, 54}, - {54, 54}, - }, - { - {54, 54}, - {55, 54}, - }, - { - {54, 55}, - {55, 54}, - }, - { - {54, 55}, - {55, 55}, - }, - { - {55, 55}, - {55, 55}, - }, - { - {55, 55}, - {56, 55}, - }, - { - {55, 55}, - {56, 55}, - }, - { - {55, 56}, - {56, 55}, - }, - { - {55, 56}, - {56, 56}, - }, - { - {56, 56}, - {56, 56}, - }, - { - {56, 56}, - {57, 56}, - }, - { - {56, 57}, - {57, 56}, - }, - { - {56, 57}, - {57, 57}, - }, - { - {57, 57}, - {57, 57}, - }, - { - {57, 57}, - {58, 57}, - }, - { - {57, 58}, - {58, 57}, - }, - { - {57, 58}, - {58, 58}, - }, - { - {58, 58}, - {58, 58}, - }, - { - {58, 58}, - {59, 58}, - }, - { - {58, 59}, - {59, 58}, - }, - { - {58, 59}, - {59, 59}, - }, - { - {59, 59}, - {59, 59}, - }, - { - {59, 59}, - {60, 59}, - }, - { - {59, 60}, - {60, 59}, - }, - { - {59, 60}, - {60, 60}, - }, - { - {60, 60}, - {60, 60}, - }, - { - {60, 60}, - {61, 60}, - }, - { - {60, 61}, - {61, 60}, - }, - { - {60, 61}, - {61, 61}, - }, - { - {61, 61}, - {61, 61}, - }, - { - {61, 61}, - {62, 61}, - }, - { - {61, 62}, - {62, 61}, - }, - { - {61, 62}, - {62, 62}, - }, - { - {62, 62}, - {62, 62}, - }, - { - {62, 62}, - {63, 62}, - }, - { - {62, 63}, - {63, 62}, - }, - { - {62, 63}, - {63, 63}, - }, - { - {63, 63}, - {63, 63}, - }, +static const uint8_t dither_g2x2[256][2][2] = { + { + {0, 0}, + {0, 0}, + }, + { + {0, 0}, + {1, 0}, + }, + { + {0, 1}, + {1, 0}, + }, + { + {0, 1}, + {1, 1}, + }, + { + {1, 1}, + {1, 1}, + }, + { + {1, 1}, + {2, 1}, + }, + { + {1, 2}, + {2, 1}, + }, + { + {1, 2}, + {2, 2}, + }, + { + {2, 2}, + {2, 2}, + }, + { + {2, 2}, + {3, 2}, + }, + { + {2, 3}, + {3, 2}, + }, + { + {2, 3}, + {3, 3}, + }, + { + {3, 3}, + {3, 3}, + }, + { + {3, 3}, + {4, 3}, + }, + { + {3, 4}, + {4, 3}, + }, + { + {3, 4}, + {4, 4}, + }, + { + {4, 4}, + {4, 4}, + }, + { + {4, 4}, + {5, 4}, + }, + { + {4, 5}, + {5, 4}, + }, + { + {4, 5}, + {5, 5}, + }, + { + {5, 5}, + {5, 5}, + }, + { + {5, 5}, + {6, 5}, + }, + { + {5, 6}, + {6, 5}, + }, + { + {5, 6}, + {6, 6}, + }, + { + {6, 6}, + {6, 6}, + }, + { + {6, 6}, + {7, 6}, + }, + { + {6, 7}, + {7, 6}, + }, + { + {6, 7}, + {7, 7}, + }, + { + {7, 7}, + {7, 7}, + }, + { + {7, 7}, + {8, 7}, + }, + { + {7, 8}, + {8, 7}, + }, + { + {7, 8}, + {8, 8}, + }, + { + {8, 8}, + {8, 8}, + }, + { + {8, 8}, + {9, 8}, + }, + { + {8, 9}, + {9, 8}, + }, + { + {8, 9}, + {9, 9}, + }, + { + {9, 9}, + {9, 9}, + }, + { + {9, 9}, + {10, 9}, + }, + { + {9, 10}, + {10, 9}, + }, + { + {9, 10}, + {10, 10}, + }, + { + {10, 10}, + {10, 10}, + }, + { + {10, 10}, + {11, 10}, + }, + { + {10, 11}, + {11, 10}, + }, + { + {10, 11}, + {11, 11}, + }, + { + {11, 11}, + {11, 11}, + }, + { + {11, 11}, + {12, 11}, + }, + { + {11, 12}, + {12, 11}, + }, + { + {11, 12}, + {12, 12}, + }, + { + {11, 12}, + {12, 12}, + }, + { + {12, 12}, + {12, 12}, + }, + { + {12, 12}, + {13, 12}, + }, + { + {12, 13}, + {13, 12}, + }, + { + {12, 13}, + {13, 13}, + }, + { + {13, 13}, + {13, 13}, + }, + { + {13, 13}, + {14, 13}, + }, + { + {13, 14}, + {14, 13}, + }, + { + {13, 14}, + {14, 14}, + }, + { + {14, 14}, + {14, 14}, + }, + { + {14, 14}, + {15, 14}, + }, + { + {14, 15}, + {15, 14}, + }, + { + {14, 15}, + {15, 15}, + }, + { + {15, 15}, + {15, 15}, + }, + { + {15, 15}, + {16, 15}, + }, + { + {15, 16}, + {16, 15}, + }, + { + {15, 16}, + {16, 16}, + }, + { + {16, 16}, + {16, 16}, + }, + { + {16, 16}, + {17, 16}, + }, + { + {16, 17}, + {17, 16}, + }, + { + {16, 17}, + {17, 17}, + }, + { + {17, 17}, + {17, 17}, + }, + { + {17, 17}, + {18, 17}, + }, + { + {17, 18}, + {18, 17}, + }, + { + {17, 18}, + {18, 18}, + }, + { + {18, 18}, + {18, 18}, + }, + { + {18, 18}, + {19, 18}, + }, + { + {18, 19}, + {19, 18}, + }, + { + {18, 19}, + {19, 19}, + }, + { + {19, 19}, + {19, 19}, + }, + { + {19, 19}, + {20, 19}, + }, + { + {19, 20}, + {20, 19}, + }, + { + {19, 20}, + {20, 20}, + }, + { + {20, 20}, + {20, 20}, + }, + { + {20, 20}, + {21, 20}, + }, + { + {20, 21}, + {21, 20}, + }, + { + {20, 21}, + {21, 21}, + }, + { + {21, 21}, + {21, 21}, + }, + { + {21, 21}, + {22, 21}, + }, + { + {21, 22}, + {22, 21}, + }, + { + {21, 22}, + {22, 22}, + }, + { + {22, 22}, + {22, 22}, + }, + { + {22, 22}, + {23, 22}, + }, + { + {22, 23}, + {23, 22}, + }, + { + {22, 23}, + {23, 23}, + }, + { + {23, 23}, + {23, 23}, + }, + { + {23, 23}, + {24, 23}, + }, + { + {23, 24}, + {24, 23}, + }, + { + {23, 24}, + {24, 24}, + }, + { + {24, 24}, + {24, 24}, + }, + { + {24, 24}, + {25, 24}, + }, + { + {24, 25}, + {25, 24}, + }, + { + {24, 25}, + {25, 25}, + }, + { + {25, 25}, + {25, 25}, + }, + { + {25, 25}, + {26, 25}, + }, + { + {25, 26}, + {26, 25}, + }, + { + {25, 26}, + {26, 26}, + }, + { + {26, 26}, + {26, 26}, + }, + { + {26, 26}, + {27, 26}, + }, + { + {26, 27}, + {27, 26}, + }, + { + {26, 27}, + {27, 27}, + }, + { + {27, 27}, + {27, 27}, + }, + { + {27, 27}, + {28, 27}, + }, + { + {27, 28}, + {28, 27}, + }, + { + {27, 28}, + {28, 28}, + }, + { + {28, 28}, + {28, 28}, + }, + { + {28, 28}, + {29, 28}, + }, + { + {28, 29}, + {29, 28}, + }, + { + {28, 29}, + {29, 29}, + }, + { + {29, 29}, + {29, 29}, + }, + { + {29, 29}, + {30, 29}, + }, + { + {29, 30}, + {30, 29}, + }, + { + {29, 30}, + {30, 30}, + }, + { + {30, 30}, + {30, 30}, + }, + { + {30, 30}, + {31, 30}, + }, + { + {30, 31}, + {31, 30}, + }, + { + {30, 31}, + {31, 31}, + }, + { + {31, 31}, + {31, 31}, + }, + { + {31, 31}, + {32, 31}, + }, + { + {31, 32}, + {32, 31}, + }, + { + {31, 32}, + {32, 32}, + }, + { + {32, 32}, + {32, 32}, + }, + { + {32, 32}, + {33, 32}, + }, + { + {32, 33}, + {33, 32}, + }, + { + {32, 33}, + {33, 33}, + }, + { + {33, 33}, + {33, 33}, + }, + { + {33, 33}, + {34, 33}, + }, + { + {33, 34}, + {34, 33}, + }, + { + {33, 34}, + {34, 34}, + }, + { + {34, 34}, + {34, 34}, + }, + { + {34, 34}, + {35, 34}, + }, + { + {34, 35}, + {35, 34}, + }, + { + {34, 35}, + {35, 35}, + }, + { + {35, 35}, + {35, 35}, + }, + { + {35, 35}, + {36, 35}, + }, + { + {35, 36}, + {36, 35}, + }, + { + {35, 36}, + {36, 35}, + }, + { + {35, 36}, + {36, 36}, + }, + { + {36, 36}, + {36, 36}, + }, + { + {36, 36}, + {37, 36}, + }, + { + {36, 37}, + {37, 36}, + }, + { + {36, 37}, + {37, 37}, + }, + { + {37, 37}, + {37, 37}, + }, + { + {37, 37}, + {38, 37}, + }, + { + {37, 38}, + {38, 37}, + }, + { + {37, 38}, + {38, 38}, + }, + { + {38, 38}, + {38, 38}, + }, + { + {38, 38}, + {39, 38}, + }, + { + {38, 39}, + {39, 38}, + }, + { + {38, 39}, + {39, 39}, + }, + { + {39, 39}, + {39, 39}, + }, + { + {39, 39}, + {40, 39}, + }, + { + {39, 40}, + {40, 39}, + }, + { + {39, 40}, + {40, 40}, + }, + { + {40, 40}, + {40, 40}, + }, + { + {40, 40}, + {41, 40}, + }, + { + {40, 41}, + {41, 40}, + }, + { + {40, 41}, + {41, 41}, + }, + { + {41, 41}, + {41, 41}, + }, + { + {41, 41}, + {42, 41}, + }, + { + {41, 42}, + {42, 41}, + }, + { + {41, 42}, + {42, 42}, + }, + { + {42, 42}, + {42, 42}, + }, + { + {42, 42}, + {43, 42}, + }, + { + {42, 43}, + {43, 42}, + }, + { + {42, 43}, + {43, 43}, + }, + { + {43, 43}, + {43, 43}, + }, + { + {43, 43}, + {44, 43}, + }, + { + {43, 44}, + {44, 43}, + }, + { + {43, 44}, + {44, 44}, + }, + { + {44, 44}, + {44, 44}, + }, + { + {44, 44}, + {45, 44}, + }, + { + {44, 45}, + {45, 44}, + }, + { + {44, 45}, + {45, 45}, + }, + { + {45, 45}, + {45, 45}, + }, + { + {45, 45}, + {46, 45}, + }, + { + {45, 46}, + {46, 45}, + }, + { + {45, 46}, + {46, 46}, + }, + { + {46, 46}, + {46, 46}, + }, + { + {46, 46}, + {47, 46}, + }, + { + {46, 47}, + {47, 46}, + }, + { + {46, 47}, + {47, 47}, + }, + { + {47, 47}, + {47, 47}, + }, + { + {47, 47}, + {48, 47}, + }, + { + {47, 48}, + {48, 47}, + }, + { + {47, 48}, + {48, 48}, + }, + { + {48, 48}, + {48, 48}, + }, + { + {48, 48}, + {49, 48}, + }, + { + {48, 49}, + {49, 48}, + }, + { + {48, 49}, + {49, 49}, + }, + { + {49, 49}, + {49, 49}, + }, + { + {49, 49}, + {50, 49}, + }, + { + {49, 50}, + {50, 49}, + }, + { + {49, 50}, + {50, 50}, + }, + { + {50, 50}, + {50, 50}, + }, + { + {50, 50}, + {51, 50}, + }, + { + {50, 51}, + {51, 50}, + }, + { + {50, 51}, + {51, 51}, + }, + { + {51, 51}, + {51, 51}, + }, + { + {51, 51}, + {52, 51}, + }, + { + {51, 52}, + {52, 51}, + }, + { + {51, 52}, + {52, 52}, + }, + { + {52, 52}, + {52, 52}, + }, + { + {52, 52}, + {53, 52}, + }, + { + {52, 53}, + {53, 52}, + }, + { + {52, 53}, + {53, 53}, + }, + { + {53, 53}, + {53, 53}, + }, + { + {53, 53}, + {54, 53}, + }, + { + {53, 54}, + {54, 53}, + }, + { + {53, 54}, + {54, 54}, + }, + { + {54, 54}, + {54, 54}, + }, + { + {54, 54}, + {55, 54}, + }, + { + {54, 55}, + {55, 54}, + }, + { + {54, 55}, + {55, 55}, + }, + { + {55, 55}, + {55, 55}, + }, + { + {55, 55}, + {56, 55}, + }, + { + {55, 55}, + {56, 55}, + }, + { + {55, 56}, + {56, 55}, + }, + { + {55, 56}, + {56, 56}, + }, + { + {56, 56}, + {56, 56}, + }, + { + {56, 56}, + {57, 56}, + }, + { + {56, 57}, + {57, 56}, + }, + { + {56, 57}, + {57, 57}, + }, + { + {57, 57}, + {57, 57}, + }, + { + {57, 57}, + {58, 57}, + }, + { + {57, 58}, + {58, 57}, + }, + { + {57, 58}, + {58, 58}, + }, + { + {58, 58}, + {58, 58}, + }, + { + {58, 58}, + {59, 58}, + }, + { + {58, 59}, + {59, 58}, + }, + { + {58, 59}, + {59, 59}, + }, + { + {59, 59}, + {59, 59}, + }, + { + {59, 59}, + {60, 59}, + }, + { + {59, 60}, + {60, 59}, + }, + { + {59, 60}, + {60, 60}, + }, + { + {60, 60}, + {60, 60}, + }, + { + {60, 60}, + {61, 60}, + }, + { + {60, 61}, + {61, 60}, + }, + { + {60, 61}, + {61, 61}, + }, + { + {61, 61}, + {61, 61}, + }, + { + {61, 61}, + {62, 61}, + }, + { + {61, 62}, + {62, 61}, + }, + { + {61, 62}, + {62, 62}, + }, + { + {62, 62}, + {62, 62}, + }, + { + {62, 62}, + {63, 62}, + }, + { + {62, 63}, + {63, 62}, + }, + { + {62, 63}, + {63, 63}, + }, + { + {63, 63}, + {63, 63}, + }, }; - - /* Dither subtraction */ -static const uint8_t dithersub_rb[256][4][4] = -{ - { - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - }, - { - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - }, - { - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - }, - { - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - }, - { - {9, 5, 8, 4}, - {3, 7, 2, 6}, - {7, 3, 8, 4}, - {1, 5, 2, 6}, - }, - { - {10, 6, 9, 5}, - {4, 8, 3, 7}, - {8, 4, 9, 5}, - {2, 6, 3, 7}, - }, - { - {11, 7, 10, 6}, - {5, 9, 4, 8}, - {9, 5, 10, 6}, - {3, 7, 4, 8}, - }, - { - {12, 8, 11, 7}, - {6, 10, 5, 9}, - {10, 6, 11, 7}, - {4, 8, 5, 9}, - }, - { - {13, 9, 12, 8}, - {7, 11, 6, 10}, - {11, 7, 12, 8}, - {5, 9, 6, 10}, - }, - { - {14, 10, 13, 9}, - {8, 12, 7, 11}, - {12, 8, 13, 9}, - {6, 10, 7, 11}, - }, - { - {15, 11, 14, 10}, - {9, 13, 8, 12}, - {13, 9, 14, 10}, - {7, 11, 8, 12}, - }, - { - {16, 12, 15, 11}, - {10, 14, 9, 13}, - {14, 10, 15, 11}, - {8, 12, 9, 13}, - }, - { - {17, 13, 16, 12}, - {11, 15, 10, 14}, - {15, 11, 16, 12}, - {9, 13, 10, 14}, - }, - { - {18, 14, 17, 13}, - {12, 16, 11, 15}, - {16, 12, 17, 13}, - {10, 14, 11, 15}, - }, - { - {19, 15, 18, 14}, - {13, 17, 12, 16}, - {17, 13, 18, 14}, - {11, 15, 12, 16}, - }, - { - {20, 16, 19, 15}, - {14, 18, 13, 17}, - {18, 14, 19, 15}, - {12, 16, 13, 17}, - }, - { - {21, 17, 20, 16}, - {15, 19, 14, 18}, - {19, 15, 20, 16}, - {13, 17, 14, 18}, - }, - { - {22, 18, 21, 17}, - {16, 20, 15, 19}, - {20, 16, 21, 17}, - {14, 18, 15, 19}, - }, - { - {23, 19, 22, 18}, - {17, 21, 16, 20}, - {21, 17, 22, 18}, - {15, 19, 16, 20}, - }, - { - {24, 20, 23, 19}, - {18, 22, 17, 21}, - {22, 18, 23, 19}, - {16, 20, 17, 21}, - }, - { - {25, 21, 24, 20}, - {19, 23, 18, 22}, - {23, 19, 24, 20}, - {17, 21, 18, 22}, - }, - { - {26, 22, 25, 21}, - {20, 24, 19, 23}, - {24, 20, 25, 21}, - {18, 22, 19, 23}, - }, - { - {27, 23, 26, 22}, - {21, 25, 20, 24}, - {25, 21, 26, 22}, - {19, 23, 20, 24}, - }, - { - {28, 24, 27, 23}, - {22, 26, 21, 25}, - {26, 22, 27, 23}, - {20, 24, 21, 25}, - }, - { - {29, 25, 28, 24}, - {23, 27, 22, 26}, - {27, 23, 28, 24}, - {21, 25, 22, 26}, - }, - { - {30, 26, 29, 25}, - {24, 28, 23, 27}, - {28, 24, 29, 25}, - {22, 26, 23, 27}, - }, - { - {31, 27, 30, 26}, - {25, 29, 24, 28}, - {29, 25, 30, 26}, - {23, 27, 24, 28}, - }, - { - {32, 28, 31, 27}, - {26, 30, 25, 29}, - {30, 26, 31, 27}, - {24, 28, 25, 29}, - }, - { - {33, 29, 32, 28}, - {27, 31, 26, 30}, - {31, 27, 32, 28}, - {25, 29, 26, 30}, - }, - { - {34, 30, 33, 29}, - {28, 32, 27, 31}, - {32, 28, 33, 29}, - {26, 30, 27, 31}, - }, - { - {35, 31, 34, 30}, - {29, 33, 28, 32}, - {33, 29, 34, 30}, - {27, 31, 28, 32}, - }, - { - {36, 32, 35, 31}, - {30, 34, 29, 33}, - {34, 30, 35, 31}, - {28, 32, 29, 33}, - }, - { - {37, 33, 36, 32}, - {31, 35, 30, 34}, - {35, 31, 36, 32}, - {29, 33, 30, 34}, - }, - { - {38, 34, 37, 33}, - {32, 36, 31, 35}, - {36, 32, 37, 33}, - {30, 34, 31, 35}, - }, - { - {39, 35, 38, 34}, - {33, 37, 32, 36}, - {37, 33, 38, 34}, - {31, 35, 32, 36}, - }, - { - {40, 36, 39, 35}, - {34, 38, 33, 37}, - {38, 34, 39, 35}, - {32, 36, 33, 37}, - }, - { - {41, 37, 40, 36}, - {35, 39, 34, 38}, - {39, 35, 40, 36}, - {33, 37, 34, 38}, - }, - { - {42, 38, 41, 37}, - {36, 40, 35, 39}, - {40, 36, 41, 37}, - {34, 38, 35, 39}, - }, - { - {43, 39, 42, 38}, - {37, 41, 36, 40}, - {41, 37, 42, 38}, - {35, 39, 36, 40}, - }, - { - {44, 40, 43, 39}, - {38, 42, 37, 41}, - {42, 38, 43, 39}, - {36, 40, 37, 41}, - }, - { - {45, 41, 44, 40}, - {39, 43, 38, 42}, - {43, 39, 44, 40}, - {37, 41, 38, 42}, - }, - { - {46, 42, 45, 41}, - {40, 44, 39, 43}, - {44, 40, 45, 41}, - {38, 42, 39, 43}, - }, - { - {47, 43, 46, 42}, - {41, 45, 40, 44}, - {45, 41, 46, 42}, - {39, 43, 40, 44}, - }, - { - {48, 44, 47, 43}, - {42, 46, 41, 45}, - {46, 42, 47, 43}, - {40, 44, 41, 45}, - }, - { - {49, 45, 48, 44}, - {43, 47, 42, 46}, - {47, 43, 48, 44}, - {41, 45, 42, 46}, - }, - { - {50, 46, 49, 45}, - {44, 48, 43, 47}, - {48, 44, 49, 45}, - {42, 46, 43, 47}, - }, - { - {51, 47, 50, 46}, - {45, 49, 44, 48}, - {49, 45, 50, 46}, - {43, 47, 44, 48}, - }, - { - {52, 48, 51, 47}, - {46, 50, 45, 49}, - {50, 46, 51, 47}, - {44, 48, 45, 49}, - }, - { - {53, 49, 52, 48}, - {47, 51, 46, 50}, - {51, 47, 52, 48}, - {45, 49, 46, 50}, - }, - { - {54, 50, 53, 49}, - {48, 52, 47, 51}, - {52, 48, 53, 49}, - {46, 50, 47, 51}, - }, - { - {55, 51, 54, 50}, - {49, 53, 48, 52}, - {53, 49, 54, 50}, - {47, 51, 48, 52}, - }, - { - {56, 52, 55, 51}, - {50, 54, 49, 53}, - {54, 50, 55, 51}, - {48, 52, 49, 53}, - }, - { - {57, 53, 56, 52}, - {51, 55, 50, 54}, - {55, 51, 56, 52}, - {49, 53, 50, 54}, - }, - { - {58, 54, 57, 53}, - {52, 56, 51, 55}, - {56, 52, 57, 53}, - {50, 54, 51, 55}, - }, - { - {59, 55, 58, 54}, - {53, 57, 52, 56}, - {57, 53, 58, 54}, - {51, 55, 52, 56}, - }, - { - {60, 56, 59, 55}, - {54, 58, 53, 57}, - {58, 54, 59, 55}, - {52, 56, 53, 57}, - }, - { - {61, 57, 60, 56}, - {55, 59, 54, 58}, - {59, 55, 60, 56}, - {53, 57, 54, 58}, - }, - { - {62, 58, 61, 57}, - {56, 60, 55, 59}, - {60, 56, 61, 57}, - {54, 58, 55, 59}, - }, - { - {63, 59, 62, 58}, - {57, 61, 56, 60}, - {61, 57, 62, 58}, - {55, 59, 56, 60}, - }, - { - {64, 60, 63, 59}, - {58, 62, 57, 61}, - {62, 58, 63, 59}, - {56, 60, 57, 61}, - }, - { - {65, 61, 64, 60}, - {59, 63, 58, 62}, - {63, 59, 64, 60}, - {57, 61, 58, 62}, - }, - { - {66, 62, 65, 61}, - {60, 64, 59, 63}, - {64, 60, 65, 61}, - {58, 62, 59, 63}, - }, - { - {67, 63, 66, 62}, - {61, 65, 60, 64}, - {65, 61, 66, 62}, - {59, 63, 60, 64}, - }, - { - {68, 64, 67, 63}, - {62, 66, 61, 65}, - {66, 62, 67, 63}, - {60, 64, 61, 65}, - }, - { - {69, 65, 68, 64}, - {63, 67, 62, 66}, - {67, 63, 68, 64}, - {61, 65, 62, 66}, - }, - { - {70, 66, 69, 65}, - {64, 68, 63, 67}, - {68, 64, 69, 65}, - {62, 66, 63, 67}, - }, - { - {71, 67, 70, 66}, - {65, 69, 64, 68}, - {69, 65, 70, 66}, - {63, 67, 64, 68}, - }, - { - {72, 68, 71, 67}, - {66, 70, 65, 69}, - {70, 66, 71, 67}, - {64, 68, 65, 69}, - }, - { - {73, 69, 72, 68}, - {67, 71, 66, 70}, - {71, 67, 72, 68}, - {65, 69, 66, 70}, - }, - { - {74, 70, 73, 69}, - {68, 72, 67, 71}, - {72, 68, 73, 69}, - {66, 70, 67, 71}, - }, - { - {75, 71, 74, 70}, - {69, 73, 68, 72}, - {73, 69, 74, 70}, - {67, 71, 68, 72}, - }, - { - {76, 72, 75, 71}, - {70, 74, 69, 73}, - {74, 70, 75, 71}, - {68, 72, 69, 73}, - }, - { - {77, 73, 76, 72}, - {71, 75, 70, 74}, - {75, 71, 76, 72}, - {69, 73, 70, 74}, - }, - { - {78, 74, 77, 73}, - {72, 76, 71, 75}, - {76, 72, 77, 73}, - {70, 74, 71, 75}, - }, - { - {79, 75, 78, 74}, - {73, 77, 72, 76}, - {77, 73, 78, 74}, - {71, 75, 72, 76}, - }, - { - {80, 76, 79, 75}, - {74, 78, 73, 77}, - {78, 74, 79, 75}, - {72, 76, 73, 77}, - }, - { - {81, 77, 80, 76}, - {75, 79, 74, 78}, - {79, 75, 80, 76}, - {73, 77, 74, 78}, - }, - { - {82, 78, 81, 77}, - {76, 80, 75, 79}, - {80, 76, 81, 77}, - {74, 78, 75, 79}, - }, - { - {83, 79, 82, 78}, - {77, 81, 76, 80}, - {81, 77, 82, 78}, - {75, 79, 76, 80}, - }, - { - {84, 80, 83, 79}, - {78, 82, 77, 81}, - {82, 78, 83, 79}, - {76, 80, 77, 81}, - }, - { - {85, 81, 84, 80}, - {79, 83, 78, 82}, - {83, 79, 84, 80}, - {77, 81, 78, 82}, - }, - { - {86, 82, 85, 81}, - {80, 84, 79, 83}, - {84, 80, 85, 81}, - {78, 82, 79, 83}, - }, - { - {87, 83, 86, 82}, - {81, 85, 80, 84}, - {85, 81, 86, 82}, - {79, 83, 80, 84}, - }, - { - {88, 84, 87, 83}, - {82, 86, 81, 85}, - {86, 82, 87, 83}, - {80, 84, 81, 85}, - }, - { - {89, 85, 88, 84}, - {83, 87, 82, 86}, - {87, 83, 88, 84}, - {81, 85, 82, 86}, - }, - { - {90, 86, 89, 85}, - {84, 88, 83, 87}, - {88, 84, 89, 85}, - {82, 86, 83, 87}, - }, - { - {91, 87, 90, 86}, - {85, 89, 84, 88}, - {89, 85, 90, 86}, - {83, 87, 84, 88}, - }, - { - {92, 88, 91, 87}, - {86, 90, 85, 89}, - {90, 86, 91, 87}, - {84, 88, 85, 89}, - }, - { - {93, 89, 92, 88}, - {87, 91, 86, 90}, - {91, 87, 92, 88}, - {85, 89, 86, 90}, - }, - { - {94, 90, 93, 89}, - {88, 92, 87, 91}, - {92, 88, 93, 89}, - {86, 90, 87, 91}, - }, - { - {95, 91, 94, 90}, - {89, 93, 88, 92}, - {93, 89, 94, 90}, - {87, 91, 88, 92}, - }, - { - {96, 92, 95, 91}, - {90, 94, 89, 93}, - {94, 90, 95, 91}, - {88, 92, 89, 93}, - }, - { - {97, 93, 96, 92}, - {91, 95, 90, 94}, - {95, 91, 96, 92}, - {89, 93, 90, 94}, - }, - { - {98, 94, 97, 93}, - {92, 96, 91, 95}, - {96, 92, 97, 93}, - {90, 94, 91, 95}, - }, - { - {99, 95, 98, 94}, - {93, 97, 92, 96}, - {97, 93, 98, 94}, - {91, 95, 92, 96}, - }, - { - {100, 96, 99, 95}, - {94, 98, 93, 97}, - {98, 94, 99, 95}, - {92, 96, 93, 97}, - }, - { - {101, 97, 100, 96}, - {95, 99, 94, 98}, - {99, 95, 100, 96}, - {93, 97, 94, 98}, - }, - { - {102, 98, 101, 97}, - {96, 100, 95, 99}, - {100, 96, 101, 97}, - {94, 98, 95, 99}, - }, - { - {103, 99, 102, 98}, - {97, 101, 96, 100}, - {101, 97, 102, 98}, - {95, 99, 96, 100}, - }, - { - {104, 100, 103, 99}, - {98, 102, 97, 101}, - {102, 98, 103, 99}, - {96, 100, 97, 101}, - }, - { - {105, 101, 104, 100}, - {99, 103, 98, 102}, - {103, 99, 104, 100}, - {97, 101, 98, 102}, - }, - { - {106, 102, 105, 101}, - {100, 104, 99, 103}, - {104, 100, 105, 101}, - {98, 102, 99, 103}, - }, - { - {107, 103, 106, 102}, - {101, 105, 100, 104}, - {105, 101, 106, 102}, - {99, 103, 100, 104}, - }, - { - {108, 104, 107, 103}, - {102, 106, 101, 105}, - {106, 102, 107, 103}, - {100, 104, 101, 105}, - }, - { - {109, 105, 108, 104}, - {103, 107, 102, 106}, - {107, 103, 108, 104}, - {101, 105, 102, 106}, - }, - { - {110, 106, 109, 105}, - {104, 108, 103, 107}, - {108, 104, 109, 105}, - {102, 106, 103, 107}, - }, - { - {111, 107, 110, 106}, - {105, 109, 104, 108}, - {109, 105, 110, 106}, - {103, 107, 104, 108}, - }, - { - {112, 108, 111, 107}, - {106, 110, 105, 109}, - {110, 106, 111, 107}, - {104, 108, 105, 109}, - }, - { - {113, 109, 112, 108}, - {107, 111, 106, 110}, - {111, 107, 112, 108}, - {105, 109, 106, 110}, - }, - { - {114, 110, 113, 109}, - {108, 112, 107, 111}, - {112, 108, 113, 109}, - {106, 110, 107, 111}, - }, - { - {115, 111, 114, 110}, - {109, 113, 108, 112}, - {113, 109, 114, 110}, - {107, 111, 108, 112}, - }, - { - {116, 112, 115, 111}, - {110, 114, 109, 113}, - {114, 110, 115, 111}, - {108, 112, 109, 113}, - }, - { - {117, 113, 116, 112}, - {111, 115, 110, 114}, - {115, 111, 116, 112}, - {109, 113, 110, 114}, - }, - { - {118, 114, 117, 113}, - {112, 116, 111, 115}, - {116, 112, 117, 113}, - {110, 114, 111, 115}, - }, - { - {119, 115, 118, 114}, - {113, 117, 112, 116}, - {117, 113, 118, 114}, - {111, 115, 112, 116}, - }, - { - {120, 116, 119, 115}, - {114, 118, 113, 117}, - {118, 114, 119, 115}, - {112, 116, 113, 117}, - }, - { - {121, 117, 120, 116}, - {115, 119, 114, 118}, - {119, 115, 120, 116}, - {113, 117, 114, 118}, - }, - { - {122, 118, 121, 117}, - {116, 120, 115, 119}, - {120, 116, 121, 117}, - {114, 118, 115, 119}, - }, - { - {123, 119, 122, 118}, - {117, 121, 116, 120}, - {121, 117, 122, 118}, - {115, 119, 116, 120}, - }, - { - {124, 120, 123, 119}, - {118, 122, 117, 121}, - {122, 118, 123, 119}, - {116, 120, 117, 121}, - }, - { - {125, 121, 124, 120}, - {119, 123, 118, 122}, - {123, 119, 124, 120}, - {117, 121, 118, 122}, - }, - { - {126, 122, 125, 121}, - {120, 124, 119, 123}, - {124, 120, 125, 121}, - {118, 122, 119, 123}, - }, - { - {127, 123, 126, 122}, - {121, 125, 120, 124}, - {125, 121, 126, 122}, - {119, 123, 120, 124}, - }, - { - {128, 124, 127, 123}, - {122, 126, 121, 125}, - {126, 122, 127, 123}, - {120, 124, 121, 125}, - }, - { - {129, 125, 128, 124}, - {123, 127, 122, 126}, - {127, 123, 128, 124}, - {121, 125, 122, 126}, - }, - { - {130, 126, 129, 125}, - {124, 128, 123, 127}, - {128, 124, 129, 125}, - {122, 126, 123, 127}, - }, - { - {131, 127, 130, 126}, - {125, 129, 124, 128}, - {129, 125, 130, 126}, - {123, 127, 124, 128}, - }, - { - {132, 128, 131, 127}, - {126, 130, 125, 129}, - {130, 126, 131, 127}, - {124, 128, 125, 129}, - }, - { - {133, 129, 132, 128}, - {127, 131, 126, 130}, - {131, 127, 132, 128}, - {125, 129, 126, 130}, - }, - { - {134, 130, 133, 129}, - {128, 132, 127, 131}, - {132, 128, 133, 129}, - {126, 130, 127, 131}, - }, - { - {135, 131, 134, 130}, - {129, 133, 128, 132}, - {133, 129, 134, 130}, - {127, 131, 128, 132}, - }, - { - {136, 132, 135, 131}, - {130, 134, 129, 133}, - {134, 130, 135, 131}, - {128, 132, 129, 133}, - }, - { - {137, 133, 136, 132}, - {131, 135, 130, 134}, - {135, 131, 136, 132}, - {129, 133, 130, 134}, - }, - { - {138, 134, 137, 133}, - {132, 136, 131, 135}, - {136, 132, 137, 133}, - {130, 134, 131, 135}, - }, - { - {139, 135, 138, 134}, - {133, 137, 132, 136}, - {137, 133, 138, 134}, - {131, 135, 132, 136}, - }, - { - {140, 136, 139, 135}, - {134, 138, 133, 137}, - {138, 134, 139, 135}, - {132, 136, 133, 137}, - }, - { - {141, 137, 140, 136}, - {135, 139, 134, 138}, - {139, 135, 140, 136}, - {133, 137, 134, 138}, - }, - { - {142, 138, 141, 137}, - {136, 140, 135, 139}, - {140, 136, 141, 137}, - {134, 138, 135, 139}, - }, - { - {143, 139, 142, 138}, - {137, 141, 136, 140}, - {141, 137, 142, 138}, - {135, 139, 136, 140}, - }, - { - {144, 140, 143, 139}, - {138, 142, 137, 141}, - {142, 138, 143, 139}, - {136, 140, 137, 141}, - }, - { - {145, 141, 144, 140}, - {139, 143, 138, 142}, - {143, 139, 144, 140}, - {137, 141, 138, 142}, - }, - { - {146, 142, 145, 141}, - {140, 144, 139, 143}, - {144, 140, 145, 141}, - {138, 142, 139, 143}, - }, - { - {147, 143, 146, 142}, - {141, 145, 140, 144}, - {145, 141, 146, 142}, - {139, 143, 140, 144}, - }, - { - {148, 144, 147, 143}, - {142, 146, 141, 145}, - {146, 142, 147, 143}, - {140, 144, 141, 145}, - }, - { - {149, 145, 148, 144}, - {143, 147, 142, 146}, - {147, 143, 148, 144}, - {141, 145, 142, 146}, - }, - { - {150, 146, 149, 145}, - {144, 148, 143, 147}, - {148, 144, 149, 145}, - {142, 146, 143, 147}, - }, - { - {151, 147, 150, 146}, - {145, 149, 144, 148}, - {149, 145, 150, 146}, - {143, 147, 144, 148}, - }, - { - {152, 148, 151, 147}, - {146, 150, 145, 149}, - {150, 146, 151, 147}, - {144, 148, 145, 149}, - }, - { - {153, 149, 152, 148}, - {147, 151, 146, 150}, - {151, 147, 152, 148}, - {145, 149, 146, 150}, - }, - { - {154, 150, 153, 149}, - {148, 152, 147, 151}, - {152, 148, 153, 149}, - {146, 150, 147, 151}, - }, - { - {155, 151, 154, 150}, - {149, 153, 148, 152}, - {153, 149, 154, 150}, - {147, 151, 148, 152}, - }, - { - {156, 152, 155, 151}, - {150, 154, 149, 153}, - {154, 150, 155, 151}, - {148, 152, 149, 153}, - }, - { - {157, 153, 156, 152}, - {151, 155, 150, 154}, - {155, 151, 156, 152}, - {149, 153, 150, 154}, - }, - { - {158, 154, 157, 153}, - {152, 156, 151, 155}, - {156, 152, 157, 153}, - {150, 154, 151, 155}, - }, - { - {159, 155, 158, 154}, - {153, 157, 152, 156}, - {157, 153, 158, 154}, - {151, 155, 152, 156}, - }, - { - {160, 156, 159, 155}, - {154, 158, 153, 157}, - {158, 154, 159, 155}, - {152, 156, 153, 157}, - }, - { - {161, 157, 160, 156}, - {155, 159, 154, 158}, - {159, 155, 160, 156}, - {153, 157, 154, 158}, - }, - { - {162, 158, 161, 157}, - {156, 160, 155, 159}, - {160, 156, 161, 157}, - {154, 158, 155, 159}, - }, - { - {163, 159, 162, 158}, - {157, 161, 156, 160}, - {161, 157, 162, 158}, - {155, 159, 156, 160}, - }, - { - {164, 160, 163, 159}, - {158, 162, 157, 161}, - {162, 158, 163, 159}, - {156, 160, 157, 161}, - }, - { - {165, 161, 164, 160}, - {159, 163, 158, 162}, - {163, 159, 164, 160}, - {157, 161, 158, 162}, - }, - { - {166, 162, 165, 161}, - {160, 164, 159, 163}, - {164, 160, 165, 161}, - {158, 162, 159, 163}, - }, - { - {167, 163, 166, 162}, - {161, 165, 160, 164}, - {165, 161, 166, 162}, - {159, 163, 160, 164}, - }, - { - {168, 164, 167, 163}, - {162, 166, 161, 165}, - {166, 162, 167, 163}, - {160, 164, 161, 165}, - }, - { - {169, 165, 168, 164}, - {163, 167, 162, 166}, - {167, 163, 168, 164}, - {161, 165, 162, 166}, - }, - { - {170, 166, 169, 165}, - {164, 168, 163, 167}, - {168, 164, 169, 165}, - {162, 166, 163, 167}, - }, - { - {171, 167, 170, 166}, - {165, 169, 164, 168}, - {169, 165, 170, 166}, - {163, 167, 164, 168}, - }, - { - {172, 168, 171, 167}, - {166, 170, 165, 169}, - {170, 166, 171, 167}, - {164, 168, 165, 169}, - }, - { - {173, 169, 172, 168}, - {167, 171, 166, 170}, - {171, 167, 172, 168}, - {165, 169, 166, 170}, - }, - { - {174, 170, 173, 169}, - {168, 172, 167, 171}, - {172, 168, 173, 169}, - {166, 170, 167, 171}, - }, - { - {175, 171, 174, 170}, - {169, 173, 168, 172}, - {173, 169, 174, 170}, - {167, 171, 168, 172}, - }, - { - {176, 172, 175, 171}, - {170, 174, 169, 173}, - {174, 170, 175, 171}, - {168, 172, 169, 173}, - }, - { - {177, 173, 176, 172}, - {171, 175, 170, 174}, - {175, 171, 176, 172}, - {169, 173, 170, 174}, - }, - { - {178, 174, 177, 173}, - {172, 176, 171, 175}, - {176, 172, 177, 173}, - {170, 174, 171, 175}, - }, - { - {179, 175, 178, 174}, - {173, 177, 172, 176}, - {177, 173, 178, 174}, - {171, 175, 172, 176}, - }, - { - {180, 176, 179, 175}, - {174, 178, 173, 177}, - {178, 174, 179, 175}, - {172, 176, 173, 177}, - }, - { - {181, 177, 180, 176}, - {175, 179, 174, 178}, - {179, 175, 180, 176}, - {173, 177, 174, 178}, - }, - { - {182, 178, 181, 177}, - {176, 180, 175, 179}, - {180, 176, 181, 177}, - {174, 178, 175, 179}, - }, - { - {183, 179, 182, 178}, - {177, 181, 176, 180}, - {181, 177, 182, 178}, - {175, 179, 176, 180}, - }, - { - {184, 180, 183, 179}, - {178, 182, 177, 181}, - {182, 178, 183, 179}, - {176, 180, 177, 181}, - }, - { - {185, 181, 184, 180}, - {179, 183, 178, 182}, - {183, 179, 184, 180}, - {177, 181, 178, 182}, - }, - { - {186, 182, 185, 181}, - {180, 184, 179, 183}, - {184, 180, 185, 181}, - {178, 182, 179, 183}, - }, - { - {187, 183, 186, 182}, - {181, 185, 180, 184}, - {185, 181, 186, 182}, - {179, 183, 180, 184}, - }, - { - {188, 184, 187, 183}, - {182, 186, 181, 185}, - {186, 182, 187, 183}, - {180, 184, 181, 185}, - }, - { - {189, 185, 188, 184}, - {183, 187, 182, 186}, - {187, 183, 188, 184}, - {181, 185, 182, 186}, - }, - { - {190, 186, 189, 185}, - {184, 188, 183, 187}, - {188, 184, 189, 185}, - {182, 186, 183, 187}, - }, - { - {191, 187, 190, 186}, - {185, 189, 184, 188}, - {189, 185, 190, 186}, - {183, 187, 184, 188}, - }, - { - {192, 188, 191, 187}, - {186, 190, 185, 189}, - {190, 186, 191, 187}, - {184, 188, 185, 189}, - }, - { - {193, 189, 192, 188}, - {187, 191, 186, 190}, - {191, 187, 192, 188}, - {185, 189, 186, 190}, - }, - { - {194, 190, 193, 189}, - {188, 192, 187, 191}, - {192, 188, 193, 189}, - {186, 190, 187, 191}, - }, - { - {195, 191, 194, 190}, - {189, 193, 188, 192}, - {193, 189, 194, 190}, - {187, 191, 188, 192}, - }, - { - {196, 192, 195, 191}, - {190, 194, 189, 193}, - {194, 190, 195, 191}, - {188, 192, 189, 193}, - }, - { - {197, 193, 196, 192}, - {191, 195, 190, 194}, - {195, 191, 196, 192}, - {189, 193, 190, 194}, - }, - { - {198, 194, 197, 193}, - {192, 196, 191, 195}, - {196, 192, 197, 193}, - {190, 194, 191, 195}, - }, - { - {199, 195, 198, 194}, - {193, 197, 192, 196}, - {197, 193, 198, 194}, - {191, 195, 192, 196}, - }, - { - {200, 196, 199, 195}, - {194, 198, 193, 197}, - {198, 194, 199, 195}, - {192, 196, 193, 197}, - }, - { - {201, 197, 200, 196}, - {195, 199, 194, 198}, - {199, 195, 200, 196}, - {193, 197, 194, 198}, - }, - { - {202, 198, 201, 197}, - {196, 200, 195, 199}, - {200, 196, 201, 197}, - {194, 198, 195, 199}, - }, - { - {203, 199, 202, 198}, - {197, 201, 196, 200}, - {201, 197, 202, 198}, - {195, 199, 196, 200}, - }, - { - {204, 200, 203, 199}, - {198, 202, 197, 201}, - {202, 198, 203, 199}, - {196, 200, 197, 201}, - }, - { - {205, 201, 204, 200}, - {199, 203, 198, 202}, - {203, 199, 204, 200}, - {197, 201, 198, 202}, - }, - { - {206, 202, 205, 201}, - {200, 204, 199, 203}, - {204, 200, 205, 201}, - {198, 202, 199, 203}, - }, - { - {207, 203, 206, 202}, - {201, 205, 200, 204}, - {205, 201, 206, 202}, - {199, 203, 200, 204}, - }, - { - {208, 204, 207, 203}, - {202, 206, 201, 205}, - {206, 202, 207, 203}, - {200, 204, 201, 205}, - }, - { - {209, 205, 208, 204}, - {203, 207, 202, 206}, - {207, 203, 208, 204}, - {201, 205, 202, 206}, - }, - { - {210, 206, 209, 205}, - {204, 208, 203, 207}, - {208, 204, 209, 205}, - {202, 206, 203, 207}, - }, - { - {211, 207, 210, 206}, - {205, 209, 204, 208}, - {209, 205, 210, 206}, - {203, 207, 204, 208}, - }, - { - {212, 208, 211, 207}, - {206, 210, 205, 209}, - {210, 206, 211, 207}, - {204, 208, 205, 209}, - }, - { - {213, 209, 212, 208}, - {207, 211, 206, 210}, - {211, 207, 212, 208}, - {205, 209, 206, 210}, - }, - { - {214, 210, 213, 209}, - {208, 212, 207, 211}, - {212, 208, 213, 209}, - {206, 210, 207, 211}, - }, - { - {215, 211, 214, 210}, - {209, 213, 208, 212}, - {213, 209, 214, 210}, - {207, 211, 208, 212}, - }, - { - {216, 212, 215, 211}, - {210, 214, 209, 213}, - {214, 210, 215, 211}, - {208, 212, 209, 213}, - }, - { - {217, 213, 216, 212}, - {211, 215, 210, 214}, - {215, 211, 216, 212}, - {209, 213, 210, 214}, - }, - { - {218, 214, 217, 213}, - {212, 216, 211, 215}, - {216, 212, 217, 213}, - {210, 214, 211, 215}, - }, - { - {219, 215, 218, 214}, - {213, 217, 212, 216}, - {217, 213, 218, 214}, - {211, 215, 212, 216}, - }, - { - {220, 216, 219, 215}, - {214, 218, 213, 217}, - {218, 214, 219, 215}, - {212, 216, 213, 217}, - }, - { - {221, 217, 220, 216}, - {215, 219, 214, 218}, - {219, 215, 220, 216}, - {213, 217, 214, 218}, - }, - { - {222, 218, 221, 217}, - {216, 220, 215, 219}, - {220, 216, 221, 217}, - {214, 218, 215, 219}, - }, - { - {223, 219, 222, 218}, - {217, 221, 216, 220}, - {221, 217, 222, 218}, - {215, 219, 216, 220}, - }, - { - {224, 220, 223, 219}, - {218, 222, 217, 221}, - {222, 218, 223, 219}, - {216, 220, 217, 221}, - }, - { - {225, 221, 224, 220}, - {219, 223, 218, 222}, - {223, 219, 224, 220}, - {217, 221, 218, 222}, - }, - { - {226, 222, 225, 221}, - {220, 224, 219, 223}, - {224, 220, 225, 221}, - {218, 222, 219, 223}, - }, - { - {227, 223, 226, 222}, - {221, 225, 220, 224}, - {225, 221, 226, 222}, - {219, 223, 220, 224}, - }, - { - {228, 224, 227, 223}, - {222, 226, 221, 225}, - {226, 222, 227, 223}, - {220, 224, 221, 225}, - }, - { - {229, 225, 228, 224}, - {223, 227, 222, 226}, - {227, 223, 228, 224}, - {221, 225, 222, 226}, - }, - { - {230, 226, 229, 225}, - {224, 228, 223, 227}, - {228, 224, 229, 225}, - {222, 226, 223, 227}, - }, - { - {231, 227, 230, 226}, - {225, 229, 224, 228}, - {229, 225, 230, 226}, - {223, 227, 224, 228}, - }, - { - {232, 228, 231, 227}, - {226, 230, 225, 229}, - {230, 226, 231, 227}, - {224, 228, 225, 229}, - }, - { - {233, 229, 232, 228}, - {227, 231, 226, 230}, - {231, 227, 232, 228}, - {225, 229, 226, 230}, - }, - { - {234, 230, 233, 229}, - {228, 232, 227, 231}, - {232, 228, 233, 229}, - {226, 230, 227, 231}, - }, - { - {235, 231, 234, 230}, - {229, 233, 228, 232}, - {233, 229, 234, 230}, - {227, 231, 228, 232}, - }, - { - {236, 232, 235, 231}, - {230, 234, 229, 233}, - {234, 230, 235, 231}, - {228, 232, 229, 233}, - }, - { - {237, 233, 236, 232}, - {231, 235, 230, 234}, - {235, 231, 236, 232}, - {229, 233, 230, 234}, - }, - { - {238, 234, 237, 233}, - {232, 236, 231, 235}, - {236, 232, 237, 233}, - {230, 234, 231, 235}, - }, - { - {239, 235, 238, 234}, - {233, 237, 232, 236}, - {237, 233, 238, 234}, - {231, 235, 232, 236}, - }, - { - {240, 236, 239, 235}, - {234, 238, 233, 237}, - {238, 234, 239, 235}, - {232, 236, 233, 237}, - }, - { - {241, 237, 240, 236}, - {235, 239, 234, 238}, - {239, 235, 240, 236}, - {233, 237, 234, 238}, - }, - { - {242, 238, 241, 237}, - {236, 240, 235, 239}, - {240, 236, 241, 237}, - {234, 238, 235, 239}, - }, - { - {243, 239, 242, 238}, - {237, 241, 236, 240}, - {241, 237, 242, 238}, - {235, 239, 236, 240}, - }, - { - {244, 240, 243, 239}, - {238, 242, 237, 241}, - {242, 238, 243, 239}, - {236, 240, 237, 241}, - }, - { - {245, 241, 244, 240}, - {239, 243, 238, 242}, - {243, 239, 244, 240}, - {237, 241, 238, 242}, - }, - { - {246, 242, 245, 241}, - {240, 244, 239, 243}, - {244, 240, 245, 241}, - {238, 242, 239, 243}, - }, - { - {247, 243, 246, 242}, - {241, 245, 240, 244}, - {245, 241, 246, 242}, - {239, 243, 240, 244}, - }, - { - {248, 244, 247, 243}, - {242, 246, 241, 245}, - {246, 242, 247, 243}, - {240, 244, 241, 245}, - }, - { - {249, 245, 248, 244}, - {243, 247, 242, 246}, - {247, 243, 248, 244}, - {241, 245, 242, 246}, - }, - { - {250, 246, 249, 245}, - {244, 248, 243, 247}, - {248, 244, 249, 245}, - {242, 246, 243, 247}, - }, - { - {251, 247, 250, 246}, - {245, 249, 244, 248}, - {249, 245, 250, 246}, - {243, 247, 244, 248}, - }, - { - {252, 248, 251, 247}, - {246, 250, 245, 249}, - {250, 246, 251, 247}, - {244, 248, 245, 249}, - }, - { - {253, 249, 252, 248}, - {247, 251, 246, 250}, - {251, 247, 252, 248}, - {245, 249, 246, 250}, - }, - { - {254, 250, 253, 249}, - {248, 252, 247, 251}, - {252, 248, 253, 249}, - {246, 250, 247, 251}, - }, - { - {255, 251, 254, 250}, - {249, 253, 248, 252}, - {253, 249, 254, 250}, - {247, 251, 248, 252}, - }, - { - {255, 252, 255, 251}, - {250, 254, 249, 253}, - {254, 250, 255, 251}, - {248, 252, 249, 253}, - }, - { - {255, 253, 255, 252}, - {251, 255, 250, 254}, - {255, 251, 255, 252}, - {249, 253, 250, 254}, - }, - { - {255, 254, 255, 253}, - {252, 255, 251, 255}, - {255, 252, 255, 253}, - {250, 254, 251, 255}, - }, - { - {255, 255, 255, 254}, - {253, 255, 252, 255}, - {255, 253, 255, 254}, - {251, 255, 252, 255}, - }, - { - {255, 255, 255, 255}, - {254, 255, 253, 255}, - {255, 254, 255, 255}, - {252, 255, 253, 255}, - }, +static const uint8_t dithersub_rb[256][4][4] = { + { + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + }, + { + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + }, + { + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + }, + { + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + }, + { + {9, 5, 8, 4}, + {3, 7, 2, 6}, + {7, 3, 8, 4}, + {1, 5, 2, 6}, + }, + { + {10, 6, 9, 5}, + {4, 8, 3, 7}, + {8, 4, 9, 5}, + {2, 6, 3, 7}, + }, + { + {11, 7, 10, 6}, + {5, 9, 4, 8}, + {9, 5, 10, 6}, + {3, 7, 4, 8}, + }, + { + {12, 8, 11, 7}, + {6, 10, 5, 9}, + {10, 6, 11, 7}, + {4, 8, 5, 9}, + }, + { + {13, 9, 12, 8}, + {7, 11, 6, 10}, + {11, 7, 12, 8}, + {5, 9, 6, 10}, + }, + { + {14, 10, 13, 9}, + {8, 12, 7, 11}, + {12, 8, 13, 9}, + {6, 10, 7, 11}, + }, + { + {15, 11, 14, 10}, + {9, 13, 8, 12}, + {13, 9, 14, 10}, + {7, 11, 8, 12}, + }, + { + {16, 12, 15, 11}, + {10, 14, 9, 13}, + {14, 10, 15, 11}, + {8, 12, 9, 13}, + }, + { + {17, 13, 16, 12}, + {11, 15, 10, 14}, + {15, 11, 16, 12}, + {9, 13, 10, 14}, + }, + { + {18, 14, 17, 13}, + {12, 16, 11, 15}, + {16, 12, 17, 13}, + {10, 14, 11, 15}, + }, + { + {19, 15, 18, 14}, + {13, 17, 12, 16}, + {17, 13, 18, 14}, + {11, 15, 12, 16}, + }, + { + {20, 16, 19, 15}, + {14, 18, 13, 17}, + {18, 14, 19, 15}, + {12, 16, 13, 17}, + }, + { + {21, 17, 20, 16}, + {15, 19, 14, 18}, + {19, 15, 20, 16}, + {13, 17, 14, 18}, + }, + { + {22, 18, 21, 17}, + {16, 20, 15, 19}, + {20, 16, 21, 17}, + {14, 18, 15, 19}, + }, + { + {23, 19, 22, 18}, + {17, 21, 16, 20}, + {21, 17, 22, 18}, + {15, 19, 16, 20}, + }, + { + {24, 20, 23, 19}, + {18, 22, 17, 21}, + {22, 18, 23, 19}, + {16, 20, 17, 21}, + }, + { + {25, 21, 24, 20}, + {19, 23, 18, 22}, + {23, 19, 24, 20}, + {17, 21, 18, 22}, + }, + { + {26, 22, 25, 21}, + {20, 24, 19, 23}, + {24, 20, 25, 21}, + {18, 22, 19, 23}, + }, + { + {27, 23, 26, 22}, + {21, 25, 20, 24}, + {25, 21, 26, 22}, + {19, 23, 20, 24}, + }, + { + {28, 24, 27, 23}, + {22, 26, 21, 25}, + {26, 22, 27, 23}, + {20, 24, 21, 25}, + }, + { + {29, 25, 28, 24}, + {23, 27, 22, 26}, + {27, 23, 28, 24}, + {21, 25, 22, 26}, + }, + { + {30, 26, 29, 25}, + {24, 28, 23, 27}, + {28, 24, 29, 25}, + {22, 26, 23, 27}, + }, + { + {31, 27, 30, 26}, + {25, 29, 24, 28}, + {29, 25, 30, 26}, + {23, 27, 24, 28}, + }, + { + {32, 28, 31, 27}, + {26, 30, 25, 29}, + {30, 26, 31, 27}, + {24, 28, 25, 29}, + }, + { + {33, 29, 32, 28}, + {27, 31, 26, 30}, + {31, 27, 32, 28}, + {25, 29, 26, 30}, + }, + { + {34, 30, 33, 29}, + {28, 32, 27, 31}, + {32, 28, 33, 29}, + {26, 30, 27, 31}, + }, + { + {35, 31, 34, 30}, + {29, 33, 28, 32}, + {33, 29, 34, 30}, + {27, 31, 28, 32}, + }, + { + {36, 32, 35, 31}, + {30, 34, 29, 33}, + {34, 30, 35, 31}, + {28, 32, 29, 33}, + }, + { + {37, 33, 36, 32}, + {31, 35, 30, 34}, + {35, 31, 36, 32}, + {29, 33, 30, 34}, + }, + { + {38, 34, 37, 33}, + {32, 36, 31, 35}, + {36, 32, 37, 33}, + {30, 34, 31, 35}, + }, + { + {39, 35, 38, 34}, + {33, 37, 32, 36}, + {37, 33, 38, 34}, + {31, 35, 32, 36}, + }, + { + {40, 36, 39, 35}, + {34, 38, 33, 37}, + {38, 34, 39, 35}, + {32, 36, 33, 37}, + }, + { + {41, 37, 40, 36}, + {35, 39, 34, 38}, + {39, 35, 40, 36}, + {33, 37, 34, 38}, + }, + { + {42, 38, 41, 37}, + {36, 40, 35, 39}, + {40, 36, 41, 37}, + {34, 38, 35, 39}, + }, + { + {43, 39, 42, 38}, + {37, 41, 36, 40}, + {41, 37, 42, 38}, + {35, 39, 36, 40}, + }, + { + {44, 40, 43, 39}, + {38, 42, 37, 41}, + {42, 38, 43, 39}, + {36, 40, 37, 41}, + }, + { + {45, 41, 44, 40}, + {39, 43, 38, 42}, + {43, 39, 44, 40}, + {37, 41, 38, 42}, + }, + { + {46, 42, 45, 41}, + {40, 44, 39, 43}, + {44, 40, 45, 41}, + {38, 42, 39, 43}, + }, + { + {47, 43, 46, 42}, + {41, 45, 40, 44}, + {45, 41, 46, 42}, + {39, 43, 40, 44}, + }, + { + {48, 44, 47, 43}, + {42, 46, 41, 45}, + {46, 42, 47, 43}, + {40, 44, 41, 45}, + }, + { + {49, 45, 48, 44}, + {43, 47, 42, 46}, + {47, 43, 48, 44}, + {41, 45, 42, 46}, + }, + { + {50, 46, 49, 45}, + {44, 48, 43, 47}, + {48, 44, 49, 45}, + {42, 46, 43, 47}, + }, + { + {51, 47, 50, 46}, + {45, 49, 44, 48}, + {49, 45, 50, 46}, + {43, 47, 44, 48}, + }, + { + {52, 48, 51, 47}, + {46, 50, 45, 49}, + {50, 46, 51, 47}, + {44, 48, 45, 49}, + }, + { + {53, 49, 52, 48}, + {47, 51, 46, 50}, + {51, 47, 52, 48}, + {45, 49, 46, 50}, + }, + { + {54, 50, 53, 49}, + {48, 52, 47, 51}, + {52, 48, 53, 49}, + {46, 50, 47, 51}, + }, + { + {55, 51, 54, 50}, + {49, 53, 48, 52}, + {53, 49, 54, 50}, + {47, 51, 48, 52}, + }, + { + {56, 52, 55, 51}, + {50, 54, 49, 53}, + {54, 50, 55, 51}, + {48, 52, 49, 53}, + }, + { + {57, 53, 56, 52}, + {51, 55, 50, 54}, + {55, 51, 56, 52}, + {49, 53, 50, 54}, + }, + { + {58, 54, 57, 53}, + {52, 56, 51, 55}, + {56, 52, 57, 53}, + {50, 54, 51, 55}, + }, + { + {59, 55, 58, 54}, + {53, 57, 52, 56}, + {57, 53, 58, 54}, + {51, 55, 52, 56}, + }, + { + {60, 56, 59, 55}, + {54, 58, 53, 57}, + {58, 54, 59, 55}, + {52, 56, 53, 57}, + }, + { + {61, 57, 60, 56}, + {55, 59, 54, 58}, + {59, 55, 60, 56}, + {53, 57, 54, 58}, + }, + { + {62, 58, 61, 57}, + {56, 60, 55, 59}, + {60, 56, 61, 57}, + {54, 58, 55, 59}, + }, + { + {63, 59, 62, 58}, + {57, 61, 56, 60}, + {61, 57, 62, 58}, + {55, 59, 56, 60}, + }, + { + {64, 60, 63, 59}, + {58, 62, 57, 61}, + {62, 58, 63, 59}, + {56, 60, 57, 61}, + }, + { + {65, 61, 64, 60}, + {59, 63, 58, 62}, + {63, 59, 64, 60}, + {57, 61, 58, 62}, + }, + { + {66, 62, 65, 61}, + {60, 64, 59, 63}, + {64, 60, 65, 61}, + {58, 62, 59, 63}, + }, + { + {67, 63, 66, 62}, + {61, 65, 60, 64}, + {65, 61, 66, 62}, + {59, 63, 60, 64}, + }, + { + {68, 64, 67, 63}, + {62, 66, 61, 65}, + {66, 62, 67, 63}, + {60, 64, 61, 65}, + }, + { + {69, 65, 68, 64}, + {63, 67, 62, 66}, + {67, 63, 68, 64}, + {61, 65, 62, 66}, + }, + { + {70, 66, 69, 65}, + {64, 68, 63, 67}, + {68, 64, 69, 65}, + {62, 66, 63, 67}, + }, + { + {71, 67, 70, 66}, + {65, 69, 64, 68}, + {69, 65, 70, 66}, + {63, 67, 64, 68}, + }, + { + {72, 68, 71, 67}, + {66, 70, 65, 69}, + {70, 66, 71, 67}, + {64, 68, 65, 69}, + }, + { + {73, 69, 72, 68}, + {67, 71, 66, 70}, + {71, 67, 72, 68}, + {65, 69, 66, 70}, + }, + { + {74, 70, 73, 69}, + {68, 72, 67, 71}, + {72, 68, 73, 69}, + {66, 70, 67, 71}, + }, + { + {75, 71, 74, 70}, + {69, 73, 68, 72}, + {73, 69, 74, 70}, + {67, 71, 68, 72}, + }, + { + {76, 72, 75, 71}, + {70, 74, 69, 73}, + {74, 70, 75, 71}, + {68, 72, 69, 73}, + }, + { + {77, 73, 76, 72}, + {71, 75, 70, 74}, + {75, 71, 76, 72}, + {69, 73, 70, 74}, + }, + { + {78, 74, 77, 73}, + {72, 76, 71, 75}, + {76, 72, 77, 73}, + {70, 74, 71, 75}, + }, + { + {79, 75, 78, 74}, + {73, 77, 72, 76}, + {77, 73, 78, 74}, + {71, 75, 72, 76}, + }, + { + {80, 76, 79, 75}, + {74, 78, 73, 77}, + {78, 74, 79, 75}, + {72, 76, 73, 77}, + }, + { + {81, 77, 80, 76}, + {75, 79, 74, 78}, + {79, 75, 80, 76}, + {73, 77, 74, 78}, + }, + { + {82, 78, 81, 77}, + {76, 80, 75, 79}, + {80, 76, 81, 77}, + {74, 78, 75, 79}, + }, + { + {83, 79, 82, 78}, + {77, 81, 76, 80}, + {81, 77, 82, 78}, + {75, 79, 76, 80}, + }, + { + {84, 80, 83, 79}, + {78, 82, 77, 81}, + {82, 78, 83, 79}, + {76, 80, 77, 81}, + }, + { + {85, 81, 84, 80}, + {79, 83, 78, 82}, + {83, 79, 84, 80}, + {77, 81, 78, 82}, + }, + { + {86, 82, 85, 81}, + {80, 84, 79, 83}, + {84, 80, 85, 81}, + {78, 82, 79, 83}, + }, + { + {87, 83, 86, 82}, + {81, 85, 80, 84}, + {85, 81, 86, 82}, + {79, 83, 80, 84}, + }, + { + {88, 84, 87, 83}, + {82, 86, 81, 85}, + {86, 82, 87, 83}, + {80, 84, 81, 85}, + }, + { + {89, 85, 88, 84}, + {83, 87, 82, 86}, + {87, 83, 88, 84}, + {81, 85, 82, 86}, + }, + { + {90, 86, 89, 85}, + {84, 88, 83, 87}, + {88, 84, 89, 85}, + {82, 86, 83, 87}, + }, + { + {91, 87, 90, 86}, + {85, 89, 84, 88}, + {89, 85, 90, 86}, + {83, 87, 84, 88}, + }, + { + {92, 88, 91, 87}, + {86, 90, 85, 89}, + {90, 86, 91, 87}, + {84, 88, 85, 89}, + }, + { + {93, 89, 92, 88}, + {87, 91, 86, 90}, + {91, 87, 92, 88}, + {85, 89, 86, 90}, + }, + { + {94, 90, 93, 89}, + {88, 92, 87, 91}, + {92, 88, 93, 89}, + {86, 90, 87, 91}, + }, + { + {95, 91, 94, 90}, + {89, 93, 88, 92}, + {93, 89, 94, 90}, + {87, 91, 88, 92}, + }, + { + {96, 92, 95, 91}, + {90, 94, 89, 93}, + {94, 90, 95, 91}, + {88, 92, 89, 93}, + }, + { + {97, 93, 96, 92}, + {91, 95, 90, 94}, + {95, 91, 96, 92}, + {89, 93, 90, 94}, + }, + { + {98, 94, 97, 93}, + {92, 96, 91, 95}, + {96, 92, 97, 93}, + {90, 94, 91, 95}, + }, + { + {99, 95, 98, 94}, + {93, 97, 92, 96}, + {97, 93, 98, 94}, + {91, 95, 92, 96}, + }, + { + {100, 96, 99, 95}, + {94, 98, 93, 97}, + {98, 94, 99, 95}, + {92, 96, 93, 97}, + }, + { + {101, 97, 100, 96}, + {95, 99, 94, 98}, + {99, 95, 100, 96}, + {93, 97, 94, 98}, + }, + { + {102, 98, 101, 97}, + {96, 100, 95, 99}, + {100, 96, 101, 97}, + {94, 98, 95, 99}, + }, + { + {103, 99, 102, 98}, + {97, 101, 96, 100}, + {101, 97, 102, 98}, + {95, 99, 96, 100}, + }, + { + {104, 100, 103, 99}, + {98, 102, 97, 101}, + {102, 98, 103, 99}, + {96, 100, 97, 101}, + }, + { + {105, 101, 104, 100}, + {99, 103, 98, 102}, + {103, 99, 104, 100}, + {97, 101, 98, 102}, + }, + { + {106, 102, 105, 101}, + {100, 104, 99, 103}, + {104, 100, 105, 101}, + {98, 102, 99, 103}, + }, + { + {107, 103, 106, 102}, + {101, 105, 100, 104}, + {105, 101, 106, 102}, + {99, 103, 100, 104}, + }, + { + {108, 104, 107, 103}, + {102, 106, 101, 105}, + {106, 102, 107, 103}, + {100, 104, 101, 105}, + }, + { + {109, 105, 108, 104}, + {103, 107, 102, 106}, + {107, 103, 108, 104}, + {101, 105, 102, 106}, + }, + { + {110, 106, 109, 105}, + {104, 108, 103, 107}, + {108, 104, 109, 105}, + {102, 106, 103, 107}, + }, + { + {111, 107, 110, 106}, + {105, 109, 104, 108}, + {109, 105, 110, 106}, + {103, 107, 104, 108}, + }, + { + {112, 108, 111, 107}, + {106, 110, 105, 109}, + {110, 106, 111, 107}, + {104, 108, 105, 109}, + }, + { + {113, 109, 112, 108}, + {107, 111, 106, 110}, + {111, 107, 112, 108}, + {105, 109, 106, 110}, + }, + { + {114, 110, 113, 109}, + {108, 112, 107, 111}, + {112, 108, 113, 109}, + {106, 110, 107, 111}, + }, + { + {115, 111, 114, 110}, + {109, 113, 108, 112}, + {113, 109, 114, 110}, + {107, 111, 108, 112}, + }, + { + {116, 112, 115, 111}, + {110, 114, 109, 113}, + {114, 110, 115, 111}, + {108, 112, 109, 113}, + }, + { + {117, 113, 116, 112}, + {111, 115, 110, 114}, + {115, 111, 116, 112}, + {109, 113, 110, 114}, + }, + { + {118, 114, 117, 113}, + {112, 116, 111, 115}, + {116, 112, 117, 113}, + {110, 114, 111, 115}, + }, + { + {119, 115, 118, 114}, + {113, 117, 112, 116}, + {117, 113, 118, 114}, + {111, 115, 112, 116}, + }, + { + {120, 116, 119, 115}, + {114, 118, 113, 117}, + {118, 114, 119, 115}, + {112, 116, 113, 117}, + }, + { + {121, 117, 120, 116}, + {115, 119, 114, 118}, + {119, 115, 120, 116}, + {113, 117, 114, 118}, + }, + { + {122, 118, 121, 117}, + {116, 120, 115, 119}, + {120, 116, 121, 117}, + {114, 118, 115, 119}, + }, + { + {123, 119, 122, 118}, + {117, 121, 116, 120}, + {121, 117, 122, 118}, + {115, 119, 116, 120}, + }, + { + {124, 120, 123, 119}, + {118, 122, 117, 121}, + {122, 118, 123, 119}, + {116, 120, 117, 121}, + }, + { + {125, 121, 124, 120}, + {119, 123, 118, 122}, + {123, 119, 124, 120}, + {117, 121, 118, 122}, + }, + { + {126, 122, 125, 121}, + {120, 124, 119, 123}, + {124, 120, 125, 121}, + {118, 122, 119, 123}, + }, + { + {127, 123, 126, 122}, + {121, 125, 120, 124}, + {125, 121, 126, 122}, + {119, 123, 120, 124}, + }, + { + {128, 124, 127, 123}, + {122, 126, 121, 125}, + {126, 122, 127, 123}, + {120, 124, 121, 125}, + }, + { + {129, 125, 128, 124}, + {123, 127, 122, 126}, + {127, 123, 128, 124}, + {121, 125, 122, 126}, + }, + { + {130, 126, 129, 125}, + {124, 128, 123, 127}, + {128, 124, 129, 125}, + {122, 126, 123, 127}, + }, + { + {131, 127, 130, 126}, + {125, 129, 124, 128}, + {129, 125, 130, 126}, + {123, 127, 124, 128}, + }, + { + {132, 128, 131, 127}, + {126, 130, 125, 129}, + {130, 126, 131, 127}, + {124, 128, 125, 129}, + }, + { + {133, 129, 132, 128}, + {127, 131, 126, 130}, + {131, 127, 132, 128}, + {125, 129, 126, 130}, + }, + { + {134, 130, 133, 129}, + {128, 132, 127, 131}, + {132, 128, 133, 129}, + {126, 130, 127, 131}, + }, + { + {135, 131, 134, 130}, + {129, 133, 128, 132}, + {133, 129, 134, 130}, + {127, 131, 128, 132}, + }, + { + {136, 132, 135, 131}, + {130, 134, 129, 133}, + {134, 130, 135, 131}, + {128, 132, 129, 133}, + }, + { + {137, 133, 136, 132}, + {131, 135, 130, 134}, + {135, 131, 136, 132}, + {129, 133, 130, 134}, + }, + { + {138, 134, 137, 133}, + {132, 136, 131, 135}, + {136, 132, 137, 133}, + {130, 134, 131, 135}, + }, + { + {139, 135, 138, 134}, + {133, 137, 132, 136}, + {137, 133, 138, 134}, + {131, 135, 132, 136}, + }, + { + {140, 136, 139, 135}, + {134, 138, 133, 137}, + {138, 134, 139, 135}, + {132, 136, 133, 137}, + }, + { + {141, 137, 140, 136}, + {135, 139, 134, 138}, + {139, 135, 140, 136}, + {133, 137, 134, 138}, + }, + { + {142, 138, 141, 137}, + {136, 140, 135, 139}, + {140, 136, 141, 137}, + {134, 138, 135, 139}, + }, + { + {143, 139, 142, 138}, + {137, 141, 136, 140}, + {141, 137, 142, 138}, + {135, 139, 136, 140}, + }, + { + {144, 140, 143, 139}, + {138, 142, 137, 141}, + {142, 138, 143, 139}, + {136, 140, 137, 141}, + }, + { + {145, 141, 144, 140}, + {139, 143, 138, 142}, + {143, 139, 144, 140}, + {137, 141, 138, 142}, + }, + { + {146, 142, 145, 141}, + {140, 144, 139, 143}, + {144, 140, 145, 141}, + {138, 142, 139, 143}, + }, + { + {147, 143, 146, 142}, + {141, 145, 140, 144}, + {145, 141, 146, 142}, + {139, 143, 140, 144}, + }, + { + {148, 144, 147, 143}, + {142, 146, 141, 145}, + {146, 142, 147, 143}, + {140, 144, 141, 145}, + }, + { + {149, 145, 148, 144}, + {143, 147, 142, 146}, + {147, 143, 148, 144}, + {141, 145, 142, 146}, + }, + { + {150, 146, 149, 145}, + {144, 148, 143, 147}, + {148, 144, 149, 145}, + {142, 146, 143, 147}, + }, + { + {151, 147, 150, 146}, + {145, 149, 144, 148}, + {149, 145, 150, 146}, + {143, 147, 144, 148}, + }, + { + {152, 148, 151, 147}, + {146, 150, 145, 149}, + {150, 146, 151, 147}, + {144, 148, 145, 149}, + }, + { + {153, 149, 152, 148}, + {147, 151, 146, 150}, + {151, 147, 152, 148}, + {145, 149, 146, 150}, + }, + { + {154, 150, 153, 149}, + {148, 152, 147, 151}, + {152, 148, 153, 149}, + {146, 150, 147, 151}, + }, + { + {155, 151, 154, 150}, + {149, 153, 148, 152}, + {153, 149, 154, 150}, + {147, 151, 148, 152}, + }, + { + {156, 152, 155, 151}, + {150, 154, 149, 153}, + {154, 150, 155, 151}, + {148, 152, 149, 153}, + }, + { + {157, 153, 156, 152}, + {151, 155, 150, 154}, + {155, 151, 156, 152}, + {149, 153, 150, 154}, + }, + { + {158, 154, 157, 153}, + {152, 156, 151, 155}, + {156, 152, 157, 153}, + {150, 154, 151, 155}, + }, + { + {159, 155, 158, 154}, + {153, 157, 152, 156}, + {157, 153, 158, 154}, + {151, 155, 152, 156}, + }, + { + {160, 156, 159, 155}, + {154, 158, 153, 157}, + {158, 154, 159, 155}, + {152, 156, 153, 157}, + }, + { + {161, 157, 160, 156}, + {155, 159, 154, 158}, + {159, 155, 160, 156}, + {153, 157, 154, 158}, + }, + { + {162, 158, 161, 157}, + {156, 160, 155, 159}, + {160, 156, 161, 157}, + {154, 158, 155, 159}, + }, + { + {163, 159, 162, 158}, + {157, 161, 156, 160}, + {161, 157, 162, 158}, + {155, 159, 156, 160}, + }, + { + {164, 160, 163, 159}, + {158, 162, 157, 161}, + {162, 158, 163, 159}, + {156, 160, 157, 161}, + }, + { + {165, 161, 164, 160}, + {159, 163, 158, 162}, + {163, 159, 164, 160}, + {157, 161, 158, 162}, + }, + { + {166, 162, 165, 161}, + {160, 164, 159, 163}, + {164, 160, 165, 161}, + {158, 162, 159, 163}, + }, + { + {167, 163, 166, 162}, + {161, 165, 160, 164}, + {165, 161, 166, 162}, + {159, 163, 160, 164}, + }, + { + {168, 164, 167, 163}, + {162, 166, 161, 165}, + {166, 162, 167, 163}, + {160, 164, 161, 165}, + }, + { + {169, 165, 168, 164}, + {163, 167, 162, 166}, + {167, 163, 168, 164}, + {161, 165, 162, 166}, + }, + { + {170, 166, 169, 165}, + {164, 168, 163, 167}, + {168, 164, 169, 165}, + {162, 166, 163, 167}, + }, + { + {171, 167, 170, 166}, + {165, 169, 164, 168}, + {169, 165, 170, 166}, + {163, 167, 164, 168}, + }, + { + {172, 168, 171, 167}, + {166, 170, 165, 169}, + {170, 166, 171, 167}, + {164, 168, 165, 169}, + }, + { + {173, 169, 172, 168}, + {167, 171, 166, 170}, + {171, 167, 172, 168}, + {165, 169, 166, 170}, + }, + { + {174, 170, 173, 169}, + {168, 172, 167, 171}, + {172, 168, 173, 169}, + {166, 170, 167, 171}, + }, + { + {175, 171, 174, 170}, + {169, 173, 168, 172}, + {173, 169, 174, 170}, + {167, 171, 168, 172}, + }, + { + {176, 172, 175, 171}, + {170, 174, 169, 173}, + {174, 170, 175, 171}, + {168, 172, 169, 173}, + }, + { + {177, 173, 176, 172}, + {171, 175, 170, 174}, + {175, 171, 176, 172}, + {169, 173, 170, 174}, + }, + { + {178, 174, 177, 173}, + {172, 176, 171, 175}, + {176, 172, 177, 173}, + {170, 174, 171, 175}, + }, + { + {179, 175, 178, 174}, + {173, 177, 172, 176}, + {177, 173, 178, 174}, + {171, 175, 172, 176}, + }, + { + {180, 176, 179, 175}, + {174, 178, 173, 177}, + {178, 174, 179, 175}, + {172, 176, 173, 177}, + }, + { + {181, 177, 180, 176}, + {175, 179, 174, 178}, + {179, 175, 180, 176}, + {173, 177, 174, 178}, + }, + { + {182, 178, 181, 177}, + {176, 180, 175, 179}, + {180, 176, 181, 177}, + {174, 178, 175, 179}, + }, + { + {183, 179, 182, 178}, + {177, 181, 176, 180}, + {181, 177, 182, 178}, + {175, 179, 176, 180}, + }, + { + {184, 180, 183, 179}, + {178, 182, 177, 181}, + {182, 178, 183, 179}, + {176, 180, 177, 181}, + }, + { + {185, 181, 184, 180}, + {179, 183, 178, 182}, + {183, 179, 184, 180}, + {177, 181, 178, 182}, + }, + { + {186, 182, 185, 181}, + {180, 184, 179, 183}, + {184, 180, 185, 181}, + {178, 182, 179, 183}, + }, + { + {187, 183, 186, 182}, + {181, 185, 180, 184}, + {185, 181, 186, 182}, + {179, 183, 180, 184}, + }, + { + {188, 184, 187, 183}, + {182, 186, 181, 185}, + {186, 182, 187, 183}, + {180, 184, 181, 185}, + }, + { + {189, 185, 188, 184}, + {183, 187, 182, 186}, + {187, 183, 188, 184}, + {181, 185, 182, 186}, + }, + { + {190, 186, 189, 185}, + {184, 188, 183, 187}, + {188, 184, 189, 185}, + {182, 186, 183, 187}, + }, + { + {191, 187, 190, 186}, + {185, 189, 184, 188}, + {189, 185, 190, 186}, + {183, 187, 184, 188}, + }, + { + {192, 188, 191, 187}, + {186, 190, 185, 189}, + {190, 186, 191, 187}, + {184, 188, 185, 189}, + }, + { + {193, 189, 192, 188}, + {187, 191, 186, 190}, + {191, 187, 192, 188}, + {185, 189, 186, 190}, + }, + { + {194, 190, 193, 189}, + {188, 192, 187, 191}, + {192, 188, 193, 189}, + {186, 190, 187, 191}, + }, + { + {195, 191, 194, 190}, + {189, 193, 188, 192}, + {193, 189, 194, 190}, + {187, 191, 188, 192}, + }, + { + {196, 192, 195, 191}, + {190, 194, 189, 193}, + {194, 190, 195, 191}, + {188, 192, 189, 193}, + }, + { + {197, 193, 196, 192}, + {191, 195, 190, 194}, + {195, 191, 196, 192}, + {189, 193, 190, 194}, + }, + { + {198, 194, 197, 193}, + {192, 196, 191, 195}, + {196, 192, 197, 193}, + {190, 194, 191, 195}, + }, + { + {199, 195, 198, 194}, + {193, 197, 192, 196}, + {197, 193, 198, 194}, + {191, 195, 192, 196}, + }, + { + {200, 196, 199, 195}, + {194, 198, 193, 197}, + {198, 194, 199, 195}, + {192, 196, 193, 197}, + }, + { + {201, 197, 200, 196}, + {195, 199, 194, 198}, + {199, 195, 200, 196}, + {193, 197, 194, 198}, + }, + { + {202, 198, 201, 197}, + {196, 200, 195, 199}, + {200, 196, 201, 197}, + {194, 198, 195, 199}, + }, + { + {203, 199, 202, 198}, + {197, 201, 196, 200}, + {201, 197, 202, 198}, + {195, 199, 196, 200}, + }, + { + {204, 200, 203, 199}, + {198, 202, 197, 201}, + {202, 198, 203, 199}, + {196, 200, 197, 201}, + }, + { + {205, 201, 204, 200}, + {199, 203, 198, 202}, + {203, 199, 204, 200}, + {197, 201, 198, 202}, + }, + { + {206, 202, 205, 201}, + {200, 204, 199, 203}, + {204, 200, 205, 201}, + {198, 202, 199, 203}, + }, + { + {207, 203, 206, 202}, + {201, 205, 200, 204}, + {205, 201, 206, 202}, + {199, 203, 200, 204}, + }, + { + {208, 204, 207, 203}, + {202, 206, 201, 205}, + {206, 202, 207, 203}, + {200, 204, 201, 205}, + }, + { + {209, 205, 208, 204}, + {203, 207, 202, 206}, + {207, 203, 208, 204}, + {201, 205, 202, 206}, + }, + { + {210, 206, 209, 205}, + {204, 208, 203, 207}, + {208, 204, 209, 205}, + {202, 206, 203, 207}, + }, + { + {211, 207, 210, 206}, + {205, 209, 204, 208}, + {209, 205, 210, 206}, + {203, 207, 204, 208}, + }, + { + {212, 208, 211, 207}, + {206, 210, 205, 209}, + {210, 206, 211, 207}, + {204, 208, 205, 209}, + }, + { + {213, 209, 212, 208}, + {207, 211, 206, 210}, + {211, 207, 212, 208}, + {205, 209, 206, 210}, + }, + { + {214, 210, 213, 209}, + {208, 212, 207, 211}, + {212, 208, 213, 209}, + {206, 210, 207, 211}, + }, + { + {215, 211, 214, 210}, + {209, 213, 208, 212}, + {213, 209, 214, 210}, + {207, 211, 208, 212}, + }, + { + {216, 212, 215, 211}, + {210, 214, 209, 213}, + {214, 210, 215, 211}, + {208, 212, 209, 213}, + }, + { + {217, 213, 216, 212}, + {211, 215, 210, 214}, + {215, 211, 216, 212}, + {209, 213, 210, 214}, + }, + { + {218, 214, 217, 213}, + {212, 216, 211, 215}, + {216, 212, 217, 213}, + {210, 214, 211, 215}, + }, + { + {219, 215, 218, 214}, + {213, 217, 212, 216}, + {217, 213, 218, 214}, + {211, 215, 212, 216}, + }, + { + {220, 216, 219, 215}, + {214, 218, 213, 217}, + {218, 214, 219, 215}, + {212, 216, 213, 217}, + }, + { + {221, 217, 220, 216}, + {215, 219, 214, 218}, + {219, 215, 220, 216}, + {213, 217, 214, 218}, + }, + { + {222, 218, 221, 217}, + {216, 220, 215, 219}, + {220, 216, 221, 217}, + {214, 218, 215, 219}, + }, + { + {223, 219, 222, 218}, + {217, 221, 216, 220}, + {221, 217, 222, 218}, + {215, 219, 216, 220}, + }, + { + {224, 220, 223, 219}, + {218, 222, 217, 221}, + {222, 218, 223, 219}, + {216, 220, 217, 221}, + }, + { + {225, 221, 224, 220}, + {219, 223, 218, 222}, + {223, 219, 224, 220}, + {217, 221, 218, 222}, + }, + { + {226, 222, 225, 221}, + {220, 224, 219, 223}, + {224, 220, 225, 221}, + {218, 222, 219, 223}, + }, + { + {227, 223, 226, 222}, + {221, 225, 220, 224}, + {225, 221, 226, 222}, + {219, 223, 220, 224}, + }, + { + {228, 224, 227, 223}, + {222, 226, 221, 225}, + {226, 222, 227, 223}, + {220, 224, 221, 225}, + }, + { + {229, 225, 228, 224}, + {223, 227, 222, 226}, + {227, 223, 228, 224}, + {221, 225, 222, 226}, + }, + { + {230, 226, 229, 225}, + {224, 228, 223, 227}, + {228, 224, 229, 225}, + {222, 226, 223, 227}, + }, + { + {231, 227, 230, 226}, + {225, 229, 224, 228}, + {229, 225, 230, 226}, + {223, 227, 224, 228}, + }, + { + {232, 228, 231, 227}, + {226, 230, 225, 229}, + {230, 226, 231, 227}, + {224, 228, 225, 229}, + }, + { + {233, 229, 232, 228}, + {227, 231, 226, 230}, + {231, 227, 232, 228}, + {225, 229, 226, 230}, + }, + { + {234, 230, 233, 229}, + {228, 232, 227, 231}, + {232, 228, 233, 229}, + {226, 230, 227, 231}, + }, + { + {235, 231, 234, 230}, + {229, 233, 228, 232}, + {233, 229, 234, 230}, + {227, 231, 228, 232}, + }, + { + {236, 232, 235, 231}, + {230, 234, 229, 233}, + {234, 230, 235, 231}, + {228, 232, 229, 233}, + }, + { + {237, 233, 236, 232}, + {231, 235, 230, 234}, + {235, 231, 236, 232}, + {229, 233, 230, 234}, + }, + { + {238, 234, 237, 233}, + {232, 236, 231, 235}, + {236, 232, 237, 233}, + {230, 234, 231, 235}, + }, + { + {239, 235, 238, 234}, + {233, 237, 232, 236}, + {237, 233, 238, 234}, + {231, 235, 232, 236}, + }, + { + {240, 236, 239, 235}, + {234, 238, 233, 237}, + {238, 234, 239, 235}, + {232, 236, 233, 237}, + }, + { + {241, 237, 240, 236}, + {235, 239, 234, 238}, + {239, 235, 240, 236}, + {233, 237, 234, 238}, + }, + { + {242, 238, 241, 237}, + {236, 240, 235, 239}, + {240, 236, 241, 237}, + {234, 238, 235, 239}, + }, + { + {243, 239, 242, 238}, + {237, 241, 236, 240}, + {241, 237, 242, 238}, + {235, 239, 236, 240}, + }, + { + {244, 240, 243, 239}, + {238, 242, 237, 241}, + {242, 238, 243, 239}, + {236, 240, 237, 241}, + }, + { + {245, 241, 244, 240}, + {239, 243, 238, 242}, + {243, 239, 244, 240}, + {237, 241, 238, 242}, + }, + { + {246, 242, 245, 241}, + {240, 244, 239, 243}, + {244, 240, 245, 241}, + {238, 242, 239, 243}, + }, + { + {247, 243, 246, 242}, + {241, 245, 240, 244}, + {245, 241, 246, 242}, + {239, 243, 240, 244}, + }, + { + {248, 244, 247, 243}, + {242, 246, 241, 245}, + {246, 242, 247, 243}, + {240, 244, 241, 245}, + }, + { + {249, 245, 248, 244}, + {243, 247, 242, 246}, + {247, 243, 248, 244}, + {241, 245, 242, 246}, + }, + { + {250, 246, 249, 245}, + {244, 248, 243, 247}, + {248, 244, 249, 245}, + {242, 246, 243, 247}, + }, + { + {251, 247, 250, 246}, + {245, 249, 244, 248}, + {249, 245, 250, 246}, + {243, 247, 244, 248}, + }, + { + {252, 248, 251, 247}, + {246, 250, 245, 249}, + {250, 246, 251, 247}, + {244, 248, 245, 249}, + }, + { + {253, 249, 252, 248}, + {247, 251, 246, 250}, + {251, 247, 252, 248}, + {245, 249, 246, 250}, + }, + { + {254, 250, 253, 249}, + {248, 252, 247, 251}, + {252, 248, 253, 249}, + {246, 250, 247, 251}, + }, + { + {255, 251, 254, 250}, + {249, 253, 248, 252}, + {253, 249, 254, 250}, + {247, 251, 248, 252}, + }, + { + {255, 252, 255, 251}, + {250, 254, 249, 253}, + {254, 250, 255, 251}, + {248, 252, 249, 253}, + }, + { + {255, 253, 255, 252}, + {251, 255, 250, 254}, + {255, 251, 255, 252}, + {249, 253, 250, 254}, + }, + { + {255, 254, 255, 253}, + {252, 255, 251, 255}, + {255, 252, 255, 253}, + {250, 254, 251, 255}, + }, + { + {255, 255, 255, 254}, + {253, 255, 252, 255}, + {255, 253, 255, 254}, + {251, 255, 252, 255}, + }, + { + {255, 255, 255, 255}, + {254, 255, 253, 255}, + {255, 254, 255, 255}, + {252, 255, 253, 255}, + }, }; -static const uint8_t dithersub_g[256][4][4] = -{ - { - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - }, - { - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - }, - { - {5, 3, 4, 2}, - {2, 4, 1, 3}, - {4, 2, 4, 2}, - {1, 3, 1, 3}, - }, - { - {6, 4, 5, 3}, - {3, 5, 2, 4}, - {5, 3, 5, 3}, - {2, 4, 2, 4}, - }, - { - {7, 5, 6, 4}, - {4, 6, 3, 5}, - {6, 4, 6, 4}, - {3, 5, 3, 5}, - }, - { - {8, 6, 7, 5}, - {5, 7, 4, 6}, - {7, 5, 7, 5}, - {4, 6, 4, 6}, - }, - { - {9, 7, 8, 6}, - {6, 8, 5, 7}, - {8, 6, 8, 6}, - {5, 7, 5, 7}, - }, - { - {10, 8, 9, 7}, - {7, 9, 6, 8}, - {9, 7, 9, 7}, - {6, 8, 6, 8}, - }, - { - {11, 9, 10, 8}, - {8, 10, 7, 9}, - {10, 8, 10, 8}, - {7, 9, 7, 9}, - }, - { - {12, 10, 11, 9}, - {9, 11, 8, 10}, - {11, 9, 11, 9}, - {8, 10, 8, 10}, - }, - { - {13, 11, 12, 10}, - {10, 12, 9, 11}, - {12, 10, 12, 10}, - {9, 11, 9, 11}, - }, - { - {14, 12, 13, 11}, - {11, 13, 10, 12}, - {13, 11, 13, 11}, - {10, 12, 10, 12}, - }, - { - {15, 13, 14, 12}, - {12, 14, 11, 13}, - {14, 12, 14, 12}, - {11, 13, 11, 13}, - }, - { - {16, 14, 15, 13}, - {13, 15, 12, 14}, - {15, 13, 15, 13}, - {12, 14, 12, 14}, - }, - { - {17, 15, 16, 14}, - {14, 16, 13, 15}, - {16, 14, 16, 14}, - {13, 15, 13, 15}, - }, - { - {18, 16, 17, 15}, - {15, 17, 14, 16}, - {17, 15, 17, 15}, - {14, 16, 14, 16}, - }, - { - {19, 17, 18, 16}, - {16, 18, 15, 17}, - {18, 16, 18, 16}, - {15, 17, 15, 17}, - }, - { - {20, 18, 19, 17}, - {17, 19, 16, 18}, - {19, 17, 19, 17}, - {16, 18, 16, 18}, - }, - { - {21, 19, 20, 18}, - {18, 20, 17, 19}, - {20, 18, 20, 18}, - {17, 19, 17, 19}, - }, - { - {22, 20, 21, 19}, - {19, 21, 18, 20}, - {21, 19, 21, 19}, - {18, 20, 18, 20}, - }, - { - {23, 21, 22, 20}, - {20, 22, 19, 21}, - {22, 20, 22, 20}, - {19, 21, 19, 21}, - }, - { - {24, 22, 23, 21}, - {21, 23, 20, 22}, - {23, 21, 23, 21}, - {20, 22, 20, 22}, - }, - { - {25, 23, 24, 22}, - {22, 24, 21, 23}, - {24, 22, 24, 22}, - {21, 23, 21, 23}, - }, - { - {26, 24, 25, 23}, - {23, 25, 22, 24}, - {25, 23, 25, 23}, - {22, 24, 22, 24}, - }, - { - {27, 25, 26, 24}, - {24, 26, 23, 25}, - {26, 24, 26, 24}, - {23, 25, 23, 25}, - }, - { - {28, 26, 27, 25}, - {25, 27, 24, 26}, - {27, 25, 27, 25}, - {24, 26, 24, 26}, - }, - { - {29, 27, 28, 26}, - {26, 28, 25, 27}, - {28, 26, 28, 26}, - {25, 27, 25, 27}, - }, - { - {30, 28, 29, 27}, - {27, 29, 26, 28}, - {29, 27, 29, 27}, - {26, 28, 26, 28}, - }, - { - {31, 29, 30, 28}, - {28, 30, 27, 29}, - {30, 28, 30, 28}, - {27, 29, 27, 29}, - }, - { - {32, 30, 31, 29}, - {29, 31, 28, 30}, - {31, 29, 31, 29}, - {28, 30, 28, 30}, - }, - { - {33, 31, 32, 30}, - {30, 32, 29, 31}, - {32, 30, 32, 30}, - {29, 31, 29, 31}, - }, - { - {34, 32, 33, 31}, - {31, 33, 30, 32}, - {33, 31, 33, 31}, - {30, 32, 30, 32}, - }, - { - {35, 33, 34, 32}, - {32, 34, 31, 33}, - {34, 32, 34, 32}, - {31, 33, 31, 33}, - }, - { - {36, 34, 35, 33}, - {33, 35, 32, 34}, - {35, 33, 35, 33}, - {32, 34, 32, 34}, - }, - { - {37, 35, 36, 34}, - {34, 36, 33, 35}, - {36, 34, 36, 34}, - {33, 35, 33, 35}, - }, - { - {38, 36, 37, 35}, - {35, 37, 34, 36}, - {37, 35, 37, 35}, - {34, 36, 34, 36}, - }, - { - {39, 37, 38, 36}, - {36, 38, 35, 37}, - {38, 36, 38, 36}, - {35, 37, 35, 37}, - }, - { - {40, 38, 39, 37}, - {37, 39, 36, 38}, - {39, 37, 39, 37}, - {36, 38, 36, 38}, - }, - { - {41, 39, 40, 38}, - {38, 40, 37, 39}, - {40, 38, 40, 38}, - {37, 39, 37, 39}, - }, - { - {42, 40, 41, 39}, - {39, 41, 38, 40}, - {41, 39, 41, 39}, - {38, 40, 38, 40}, - }, - { - {43, 41, 42, 40}, - {40, 42, 39, 41}, - {42, 40, 42, 40}, - {39, 41, 39, 41}, - }, - { - {44, 42, 43, 41}, - {41, 43, 40, 42}, - {43, 41, 43, 41}, - {40, 42, 40, 42}, - }, - { - {45, 43, 44, 42}, - {42, 44, 41, 43}, - {44, 42, 44, 42}, - {41, 43, 41, 43}, - }, - { - {46, 44, 45, 43}, - {43, 45, 42, 44}, - {45, 43, 45, 43}, - {42, 44, 42, 44}, - }, - { - {47, 45, 46, 44}, - {44, 46, 43, 45}, - {46, 44, 46, 44}, - {43, 45, 43, 45}, - }, - { - {48, 46, 47, 45}, - {45, 47, 44, 46}, - {47, 45, 47, 45}, - {44, 46, 44, 46}, - }, - { - {49, 47, 48, 46}, - {46, 48, 45, 47}, - {48, 46, 48, 46}, - {45, 47, 45, 47}, - }, - { - {50, 48, 49, 47}, - {47, 49, 46, 48}, - {49, 47, 49, 47}, - {46, 48, 46, 48}, - }, - { - {51, 49, 50, 48}, - {48, 50, 47, 49}, - {50, 48, 50, 48}, - {47, 49, 47, 49}, - }, - { - {52, 50, 51, 49}, - {49, 51, 48, 50}, - {51, 49, 51, 49}, - {48, 50, 48, 50}, - }, - { - {53, 51, 52, 50}, - {50, 52, 49, 51}, - {52, 50, 52, 50}, - {49, 51, 49, 51}, - }, - { - {54, 52, 53, 51}, - {51, 53, 50, 52}, - {53, 51, 53, 51}, - {50, 52, 50, 52}, - }, - { - {55, 53, 54, 52}, - {52, 54, 51, 53}, - {54, 52, 54, 52}, - {51, 53, 51, 53}, - }, - { - {56, 54, 55, 53}, - {53, 55, 52, 54}, - {55, 53, 55, 53}, - {52, 54, 52, 54}, - }, - { - {57, 55, 56, 54}, - {54, 56, 53, 55}, - {56, 54, 56, 54}, - {53, 55, 53, 55}, - }, - { - {58, 56, 57, 55}, - {55, 57, 54, 56}, - {57, 55, 57, 55}, - {54, 56, 54, 56}, - }, - { - {59, 57, 58, 56}, - {56, 58, 55, 57}, - {58, 56, 58, 56}, - {55, 57, 55, 57}, - }, - { - {60, 58, 59, 57}, - {57, 59, 56, 58}, - {59, 57, 59, 57}, - {56, 58, 56, 58}, - }, - { - {61, 59, 60, 58}, - {58, 60, 57, 59}, - {60, 58, 60, 58}, - {57, 59, 57, 59}, - }, - { - {62, 60, 61, 59}, - {59, 61, 58, 60}, - {61, 59, 61, 59}, - {58, 60, 58, 60}, - }, - { - {63, 61, 62, 60}, - {60, 62, 59, 61}, - {62, 60, 62, 60}, - {59, 61, 59, 61}, - }, - { - {64, 62, 63, 61}, - {61, 63, 60, 62}, - {63, 61, 63, 61}, - {60, 62, 60, 62}, - }, - { - {65, 63, 64, 62}, - {62, 64, 61, 63}, - {64, 62, 64, 62}, - {61, 63, 61, 63}, - }, - { - {66, 64, 65, 63}, - {63, 65, 62, 64}, - {65, 63, 65, 63}, - {62, 64, 62, 64}, - }, - { - {67, 65, 66, 64}, - {64, 66, 63, 65}, - {66, 64, 66, 64}, - {63, 65, 63, 65}, - }, - { - {68, 66, 67, 65}, - {65, 67, 64, 66}, - {67, 65, 67, 65}, - {64, 66, 64, 66}, - }, - { - {69, 67, 68, 66}, - {66, 68, 65, 67}, - {68, 66, 68, 66}, - {65, 67, 65, 67}, - }, - { - {70, 68, 69, 67}, - {67, 69, 66, 68}, - {69, 67, 69, 67}, - {66, 68, 66, 68}, - }, - { - {71, 69, 70, 68}, - {68, 70, 67, 69}, - {70, 68, 70, 68}, - {67, 69, 67, 69}, - }, - { - {72, 70, 71, 69}, - {69, 71, 68, 70}, - {71, 69, 71, 69}, - {68, 70, 68, 70}, - }, - { - {73, 71, 72, 70}, - {70, 72, 69, 71}, - {72, 70, 72, 70}, - {69, 71, 69, 71}, - }, - { - {74, 72, 73, 71}, - {71, 73, 70, 72}, - {73, 71, 73, 71}, - {70, 72, 70, 72}, - }, - { - {75, 73, 74, 72}, - {72, 74, 71, 73}, - {74, 72, 74, 72}, - {71, 73, 71, 73}, - }, - { - {76, 74, 75, 73}, - {73, 75, 72, 74}, - {75, 73, 75, 73}, - {72, 74, 72, 74}, - }, - { - {77, 75, 76, 74}, - {74, 76, 73, 75}, - {76, 74, 76, 74}, - {73, 75, 73, 75}, - }, - { - {78, 76, 77, 75}, - {75, 77, 74, 76}, - {77, 75, 77, 75}, - {74, 76, 74, 76}, - }, - { - {79, 77, 78, 76}, - {76, 78, 75, 77}, - {78, 76, 78, 76}, - {75, 77, 75, 77}, - }, - { - {80, 78, 79, 77}, - {77, 79, 76, 78}, - {79, 77, 79, 77}, - {76, 78, 76, 78}, - }, - { - {81, 79, 80, 78}, - {78, 80, 77, 79}, - {80, 78, 80, 78}, - {77, 79, 77, 79}, - }, - { - {82, 80, 81, 79}, - {79, 81, 78, 80}, - {81, 79, 81, 79}, - {78, 80, 78, 80}, - }, - { - {83, 81, 82, 80}, - {80, 82, 79, 81}, - {82, 80, 82, 80}, - {79, 81, 79, 81}, - }, - { - {84, 82, 83, 81}, - {81, 83, 80, 82}, - {83, 81, 83, 81}, - {80, 82, 80, 82}, - }, - { - {85, 83, 84, 82}, - {82, 84, 81, 83}, - {84, 82, 84, 82}, - {81, 83, 81, 83}, - }, - { - {86, 84, 85, 83}, - {83, 85, 82, 84}, - {85, 83, 85, 83}, - {82, 84, 82, 84}, - }, - { - {87, 85, 86, 84}, - {84, 86, 83, 85}, - {86, 84, 86, 84}, - {83, 85, 83, 85}, - }, - { - {88, 86, 87, 85}, - {85, 87, 84, 86}, - {87, 85, 87, 85}, - {84, 86, 84, 86}, - }, - { - {89, 87, 88, 86}, - {86, 88, 85, 87}, - {88, 86, 88, 86}, - {85, 87, 85, 87}, - }, - { - {90, 88, 89, 87}, - {87, 89, 86, 88}, - {89, 87, 89, 87}, - {86, 88, 86, 88}, - }, - { - {91, 89, 90, 88}, - {88, 90, 87, 89}, - {90, 88, 90, 88}, - {87, 89, 87, 89}, - }, - { - {92, 90, 91, 89}, - {89, 91, 88, 90}, - {91, 89, 91, 89}, - {88, 90, 88, 90}, - }, - { - {93, 91, 92, 90}, - {90, 92, 89, 91}, - {92, 90, 92, 90}, - {89, 91, 89, 91}, - }, - { - {94, 92, 93, 91}, - {91, 93, 90, 92}, - {93, 91, 93, 91}, - {90, 92, 90, 92}, - }, - { - {95, 93, 94, 92}, - {92, 94, 91, 93}, - {94, 92, 94, 92}, - {91, 93, 91, 93}, - }, - { - {96, 94, 95, 93}, - {93, 95, 92, 94}, - {95, 93, 95, 93}, - {92, 94, 92, 94}, - }, - { - {97, 95, 96, 94}, - {94, 96, 93, 95}, - {96, 94, 96, 94}, - {93, 95, 93, 95}, - }, - { - {98, 96, 97, 95}, - {95, 97, 94, 96}, - {97, 95, 97, 95}, - {94, 96, 94, 96}, - }, - { - {99, 97, 98, 96}, - {96, 98, 95, 97}, - {98, 96, 98, 96}, - {95, 97, 95, 97}, - }, - { - {100, 98, 99, 97}, - {97, 99, 96, 98}, - {99, 97, 99, 97}, - {96, 98, 96, 98}, - }, - { - {101, 99, 100, 98}, - {98, 100, 97, 99}, - {100, 98, 100, 98}, - {97, 99, 97, 99}, - }, - { - {102, 100, 101, 99}, - {99, 101, 98, 100}, - {101, 99, 101, 99}, - {98, 100, 98, 100}, - }, - { - {103, 101, 102, 100}, - {100, 102, 99, 101}, - {102, 100, 102, 100}, - {99, 101, 99, 101}, - }, - { - {104, 102, 103, 101}, - {101, 103, 100, 102}, - {103, 101, 103, 101}, - {100, 102, 100, 102}, - }, - { - {105, 103, 104, 102}, - {102, 104, 101, 103}, - {104, 102, 104, 102}, - {101, 103, 101, 103}, - }, - { - {106, 104, 105, 103}, - {103, 105, 102, 104}, - {105, 103, 105, 103}, - {102, 104, 102, 104}, - }, - { - {107, 105, 106, 104}, - {104, 106, 103, 105}, - {106, 104, 106, 104}, - {103, 105, 103, 105}, - }, - { - {108, 106, 107, 105}, - {105, 107, 104, 106}, - {107, 105, 107, 105}, - {104, 106, 104, 106}, - }, - { - {109, 107, 108, 106}, - {106, 108, 105, 107}, - {108, 106, 108, 106}, - {105, 107, 105, 107}, - }, - { - {110, 108, 109, 107}, - {107, 109, 106, 108}, - {109, 107, 109, 107}, - {106, 108, 106, 108}, - }, - { - {111, 109, 110, 108}, - {108, 110, 107, 109}, - {110, 108, 110, 108}, - {107, 109, 107, 109}, - }, - { - {112, 110, 111, 109}, - {109, 111, 108, 110}, - {111, 109, 111, 109}, - {108, 110, 108, 110}, - }, - { - {113, 111, 112, 110}, - {110, 112, 109, 111}, - {112, 110, 112, 110}, - {109, 111, 109, 111}, - }, - { - {114, 112, 113, 111}, - {111, 113, 110, 112}, - {113, 111, 113, 111}, - {110, 112, 110, 112}, - }, - { - {115, 113, 114, 112}, - {112, 114, 111, 113}, - {114, 112, 114, 112}, - {111, 113, 111, 113}, - }, - { - {116, 114, 115, 113}, - {113, 115, 112, 114}, - {115, 113, 115, 113}, - {112, 114, 112, 114}, - }, - { - {117, 115, 116, 114}, - {114, 116, 113, 115}, - {116, 114, 116, 114}, - {113, 115, 113, 115}, - }, - { - {118, 116, 117, 115}, - {115, 117, 114, 116}, - {117, 115, 117, 115}, - {114, 116, 114, 116}, - }, - { - {119, 117, 118, 116}, - {116, 118, 115, 117}, - {118, 116, 118, 116}, - {115, 117, 115, 117}, - }, - { - {120, 118, 119, 117}, - {117, 119, 116, 118}, - {119, 117, 119, 117}, - {116, 118, 116, 118}, - }, - { - {121, 119, 120, 118}, - {118, 120, 117, 119}, - {120, 118, 120, 118}, - {117, 119, 117, 119}, - }, - { - {122, 120, 121, 119}, - {119, 121, 118, 120}, - {121, 119, 121, 119}, - {118, 120, 118, 120}, - }, - { - {123, 121, 122, 120}, - {120, 122, 119, 121}, - {122, 120, 122, 120}, - {119, 121, 119, 121}, - }, - { - {124, 122, 123, 121}, - {121, 123, 120, 122}, - {123, 121, 123, 121}, - {120, 122, 120, 122}, - }, - { - {125, 123, 124, 122}, - {122, 124, 121, 123}, - {124, 122, 124, 122}, - {121, 123, 121, 123}, - }, - { - {126, 124, 125, 123}, - {123, 125, 122, 124}, - {125, 123, 125, 123}, - {122, 124, 122, 124}, - }, - { - {127, 125, 126, 124}, - {124, 126, 123, 125}, - {126, 124, 126, 124}, - {123, 125, 123, 125}, - }, - { - {128, 126, 127, 125}, - {125, 127, 124, 126}, - {127, 125, 127, 125}, - {124, 126, 124, 126}, - }, - { - {129, 127, 128, 126}, - {126, 128, 125, 127}, - {128, 126, 128, 126}, - {125, 127, 125, 127}, - }, - { - {130, 128, 129, 127}, - {127, 129, 126, 128}, - {129, 127, 129, 127}, - {126, 128, 126, 128}, - }, - { - {131, 129, 130, 128}, - {128, 130, 127, 129}, - {130, 128, 130, 128}, - {127, 129, 127, 129}, - }, - { - {132, 130, 131, 129}, - {129, 131, 128, 130}, - {131, 129, 131, 129}, - {128, 130, 128, 130}, - }, - { - {133, 131, 132, 130}, - {130, 132, 129, 131}, - {132, 130, 132, 130}, - {129, 131, 129, 131}, - }, - { - {134, 132, 133, 131}, - {131, 133, 130, 132}, - {133, 131, 133, 131}, - {130, 132, 130, 132}, - }, - { - {135, 133, 134, 132}, - {132, 134, 131, 133}, - {134, 132, 134, 132}, - {131, 133, 131, 133}, - }, - { - {136, 134, 135, 133}, - {133, 135, 132, 134}, - {135, 133, 135, 133}, - {132, 134, 132, 134}, - }, - { - {137, 135, 136, 134}, - {134, 136, 133, 135}, - {136, 134, 136, 134}, - {133, 135, 133, 135}, - }, - { - {138, 136, 137, 135}, - {135, 137, 134, 136}, - {137, 135, 137, 135}, - {134, 136, 134, 136}, - }, - { - {139, 137, 138, 136}, - {136, 138, 135, 137}, - {138, 136, 138, 136}, - {135, 137, 135, 137}, - }, - { - {140, 138, 139, 137}, - {137, 139, 136, 138}, - {139, 137, 139, 137}, - {136, 138, 136, 138}, - }, - { - {141, 139, 140, 138}, - {138, 140, 137, 139}, - {140, 138, 140, 138}, - {137, 139, 137, 139}, - }, - { - {142, 140, 141, 139}, - {139, 141, 138, 140}, - {141, 139, 141, 139}, - {138, 140, 138, 140}, - }, - { - {143, 141, 142, 140}, - {140, 142, 139, 141}, - {142, 140, 142, 140}, - {139, 141, 139, 141}, - }, - { - {144, 142, 143, 141}, - {141, 143, 140, 142}, - {143, 141, 143, 141}, - {140, 142, 140, 142}, - }, - { - {145, 143, 144, 142}, - {142, 144, 141, 143}, - {144, 142, 144, 142}, - {141, 143, 141, 143}, - }, - { - {146, 144, 145, 143}, - {143, 145, 142, 144}, - {145, 143, 145, 143}, - {142, 144, 142, 144}, - }, - { - {147, 145, 146, 144}, - {144, 146, 143, 145}, - {146, 144, 146, 144}, - {143, 145, 143, 145}, - }, - { - {148, 146, 147, 145}, - {145, 147, 144, 146}, - {147, 145, 147, 145}, - {144, 146, 144, 146}, - }, - { - {149, 147, 148, 146}, - {146, 148, 145, 147}, - {148, 146, 148, 146}, - {145, 147, 145, 147}, - }, - { - {150, 148, 149, 147}, - {147, 149, 146, 148}, - {149, 147, 149, 147}, - {146, 148, 146, 148}, - }, - { - {151, 149, 150, 148}, - {148, 150, 147, 149}, - {150, 148, 150, 148}, - {147, 149, 147, 149}, - }, - { - {152, 150, 151, 149}, - {149, 151, 148, 150}, - {151, 149, 151, 149}, - {148, 150, 148, 150}, - }, - { - {153, 151, 152, 150}, - {150, 152, 149, 151}, - {152, 150, 152, 150}, - {149, 151, 149, 151}, - }, - { - {154, 152, 153, 151}, - {151, 153, 150, 152}, - {153, 151, 153, 151}, - {150, 152, 150, 152}, - }, - { - {155, 153, 154, 152}, - {152, 154, 151, 153}, - {154, 152, 154, 152}, - {151, 153, 151, 153}, - }, - { - {156, 154, 155, 153}, - {153, 155, 152, 154}, - {155, 153, 155, 153}, - {152, 154, 152, 154}, - }, - { - {157, 155, 156, 154}, - {154, 156, 153, 155}, - {156, 154, 156, 154}, - {153, 155, 153, 155}, - }, - { - {158, 156, 157, 155}, - {155, 157, 154, 156}, - {157, 155, 157, 155}, - {154, 156, 154, 156}, - }, - { - {159, 157, 158, 156}, - {156, 158, 155, 157}, - {158, 156, 158, 156}, - {155, 157, 155, 157}, - }, - { - {160, 158, 159, 157}, - {157, 159, 156, 158}, - {159, 157, 159, 157}, - {156, 158, 156, 158}, - }, - { - {161, 159, 160, 158}, - {158, 160, 157, 159}, - {160, 158, 160, 158}, - {157, 159, 157, 159}, - }, - { - {162, 160, 161, 159}, - {159, 161, 158, 160}, - {161, 159, 161, 159}, - {158, 160, 158, 160}, - }, - { - {163, 161, 162, 160}, - {160, 162, 159, 161}, - {162, 160, 162, 160}, - {159, 161, 159, 161}, - }, - { - {164, 162, 163, 161}, - {161, 163, 160, 162}, - {163, 161, 163, 161}, - {160, 162, 160, 162}, - }, - { - {165, 163, 164, 162}, - {162, 164, 161, 163}, - {164, 162, 164, 162}, - {161, 163, 161, 163}, - }, - { - {166, 164, 165, 163}, - {163, 165, 162, 164}, - {165, 163, 165, 163}, - {162, 164, 162, 164}, - }, - { - {167, 165, 166, 164}, - {164, 166, 163, 165}, - {166, 164, 166, 164}, - {163, 165, 163, 165}, - }, - { - {168, 166, 167, 165}, - {165, 167, 164, 166}, - {167, 165, 167, 165}, - {164, 166, 164, 166}, - }, - { - {169, 167, 168, 166}, - {166, 168, 165, 167}, - {168, 166, 168, 166}, - {165, 167, 165, 167}, - }, - { - {170, 168, 169, 167}, - {167, 169, 166, 168}, - {169, 167, 169, 167}, - {166, 168, 166, 168}, - }, - { - {171, 169, 170, 168}, - {168, 170, 167, 169}, - {170, 168, 170, 168}, - {167, 169, 167, 169}, - }, - { - {172, 170, 171, 169}, - {169, 171, 168, 170}, - {171, 169, 171, 169}, - {168, 170, 168, 170}, - }, - { - {173, 171, 172, 170}, - {170, 172, 169, 171}, - {172, 170, 172, 170}, - {169, 171, 169, 171}, - }, - { - {174, 172, 173, 171}, - {171, 173, 170, 172}, - {173, 171, 173, 171}, - {170, 172, 170, 172}, - }, - { - {175, 173, 174, 172}, - {172, 174, 171, 173}, - {174, 172, 174, 172}, - {171, 173, 171, 173}, - }, - { - {176, 174, 175, 173}, - {173, 175, 172, 174}, - {175, 173, 175, 173}, - {172, 174, 172, 174}, - }, - { - {177, 175, 176, 174}, - {174, 176, 173, 175}, - {176, 174, 176, 174}, - {173, 175, 173, 175}, - }, - { - {178, 176, 177, 175}, - {175, 177, 174, 176}, - {177, 175, 177, 175}, - {174, 176, 174, 176}, - }, - { - {179, 177, 178, 176}, - {176, 178, 175, 177}, - {178, 176, 178, 176}, - {175, 177, 175, 177}, - }, - { - {180, 178, 179, 177}, - {177, 179, 176, 178}, - {179, 177, 179, 177}, - {176, 178, 176, 178}, - }, - { - {181, 179, 180, 178}, - {178, 180, 177, 179}, - {180, 178, 180, 178}, - {177, 179, 177, 179}, - }, - { - {182, 180, 181, 179}, - {179, 181, 178, 180}, - {181, 179, 181, 179}, - {178, 180, 178, 180}, - }, - { - {183, 181, 182, 180}, - {180, 182, 179, 181}, - {182, 180, 182, 180}, - {179, 181, 179, 181}, - }, - { - {184, 182, 183, 181}, - {181, 183, 180, 182}, - {183, 181, 183, 181}, - {180, 182, 180, 182}, - }, - { - {185, 183, 184, 182}, - {182, 184, 181, 183}, - {184, 182, 184, 182}, - {181, 183, 181, 183}, - }, - { - {186, 184, 185, 183}, - {183, 185, 182, 184}, - {185, 183, 185, 183}, - {182, 184, 182, 184}, - }, - { - {187, 185, 186, 184}, - {184, 186, 183, 185}, - {186, 184, 186, 184}, - {183, 185, 183, 185}, - }, - { - {188, 186, 187, 185}, - {185, 187, 184, 186}, - {187, 185, 187, 185}, - {184, 186, 184, 186}, - }, - { - {189, 187, 188, 186}, - {186, 188, 185, 187}, - {188, 186, 188, 186}, - {185, 187, 185, 187}, - }, - { - {190, 188, 189, 187}, - {187, 189, 186, 188}, - {189, 187, 189, 187}, - {186, 188, 186, 188}, - }, - { - {191, 189, 190, 188}, - {188, 190, 187, 189}, - {190, 188, 190, 188}, - {187, 189, 187, 189}, - }, - { - {192, 190, 191, 189}, - {189, 191, 188, 190}, - {191, 189, 191, 189}, - {188, 190, 188, 190}, - }, - { - {193, 191, 192, 190}, - {190, 192, 189, 191}, - {192, 190, 192, 190}, - {189, 191, 189, 191}, - }, - { - {194, 192, 193, 191}, - {191, 193, 190, 192}, - {193, 191, 193, 191}, - {190, 192, 190, 192}, - }, - { - {195, 193, 194, 192}, - {192, 194, 191, 193}, - {194, 192, 194, 192}, - {191, 193, 191, 193}, - }, - { - {196, 194, 195, 193}, - {193, 195, 192, 194}, - {195, 193, 195, 193}, - {192, 194, 192, 194}, - }, - { - {197, 195, 196, 194}, - {194, 196, 193, 195}, - {196, 194, 196, 194}, - {193, 195, 193, 195}, - }, - { - {198, 196, 197, 195}, - {195, 197, 194, 196}, - {197, 195, 197, 195}, - {194, 196, 194, 196}, - }, - { - {199, 197, 198, 196}, - {196, 198, 195, 197}, - {198, 196, 198, 196}, - {195, 197, 195, 197}, - }, - { - {200, 198, 199, 197}, - {197, 199, 196, 198}, - {199, 197, 199, 197}, - {196, 198, 196, 198}, - }, - { - {201, 199, 200, 198}, - {198, 200, 197, 199}, - {200, 198, 200, 198}, - {197, 199, 197, 199}, - }, - { - {202, 200, 201, 199}, - {199, 201, 198, 200}, - {201, 199, 201, 199}, - {198, 200, 198, 200}, - }, - { - {203, 201, 202, 200}, - {200, 202, 199, 201}, - {202, 200, 202, 200}, - {199, 201, 199, 201}, - }, - { - {204, 202, 203, 201}, - {201, 203, 200, 202}, - {203, 201, 203, 201}, - {200, 202, 200, 202}, - }, - { - {205, 203, 204, 202}, - {202, 204, 201, 203}, - {204, 202, 204, 202}, - {201, 203, 201, 203}, - }, - { - {206, 204, 205, 203}, - {203, 205, 202, 204}, - {205, 203, 205, 203}, - {202, 204, 202, 204}, - }, - { - {207, 205, 206, 204}, - {204, 206, 203, 205}, - {206, 204, 206, 204}, - {203, 205, 203, 205}, - }, - { - {208, 206, 207, 205}, - {205, 207, 204, 206}, - {207, 205, 207, 205}, - {204, 206, 204, 206}, - }, - { - {209, 207, 208, 206}, - {206, 208, 205, 207}, - {208, 206, 208, 206}, - {205, 207, 205, 207}, - }, - { - {210, 208, 209, 207}, - {207, 209, 206, 208}, - {209, 207, 209, 207}, - {206, 208, 206, 208}, - }, - { - {211, 209, 210, 208}, - {208, 210, 207, 209}, - {210, 208, 210, 208}, - {207, 209, 207, 209}, - }, - { - {212, 210, 211, 209}, - {209, 211, 208, 210}, - {211, 209, 211, 209}, - {208, 210, 208, 210}, - }, - { - {213, 211, 212, 210}, - {210, 212, 209, 211}, - {212, 210, 212, 210}, - {209, 211, 209, 211}, - }, - { - {214, 212, 213, 211}, - {211, 213, 210, 212}, - {213, 211, 213, 211}, - {210, 212, 210, 212}, - }, - { - {215, 213, 214, 212}, - {212, 214, 211, 213}, - {214, 212, 214, 212}, - {211, 213, 211, 213}, - }, - { - {216, 214, 215, 213}, - {213, 215, 212, 214}, - {215, 213, 215, 213}, - {212, 214, 212, 214}, - }, - { - {217, 215, 216, 214}, - {214, 216, 213, 215}, - {216, 214, 216, 214}, - {213, 215, 213, 215}, - }, - { - {218, 216, 217, 215}, - {215, 217, 214, 216}, - {217, 215, 217, 215}, - {214, 216, 214, 216}, - }, - { - {219, 217, 218, 216}, - {216, 218, 215, 217}, - {218, 216, 218, 216}, - {215, 217, 215, 217}, - }, - { - {220, 218, 219, 217}, - {217, 219, 216, 218}, - {219, 217, 219, 217}, - {216, 218, 216, 218}, - }, - { - {221, 219, 220, 218}, - {218, 220, 217, 219}, - {220, 218, 220, 218}, - {217, 219, 217, 219}, - }, - { - {222, 220, 221, 219}, - {219, 221, 218, 220}, - {221, 219, 221, 219}, - {218, 220, 218, 220}, - }, - { - {223, 221, 222, 220}, - {220, 222, 219, 221}, - {222, 220, 222, 220}, - {219, 221, 219, 221}, - }, - { - {224, 222, 223, 221}, - {221, 223, 220, 222}, - {223, 221, 223, 221}, - {220, 222, 220, 222}, - }, - { - {225, 223, 224, 222}, - {222, 224, 221, 223}, - {224, 222, 224, 222}, - {221, 223, 221, 223}, - }, - { - {226, 224, 225, 223}, - {223, 225, 222, 224}, - {225, 223, 225, 223}, - {222, 224, 222, 224}, - }, - { - {227, 225, 226, 224}, - {224, 226, 223, 225}, - {226, 224, 226, 224}, - {223, 225, 223, 225}, - }, - { - {228, 226, 227, 225}, - {225, 227, 224, 226}, - {227, 225, 227, 225}, - {224, 226, 224, 226}, - }, - { - {229, 227, 228, 226}, - {226, 228, 225, 227}, - {228, 226, 228, 226}, - {225, 227, 225, 227}, - }, - { - {230, 228, 229, 227}, - {227, 229, 226, 228}, - {229, 227, 229, 227}, - {226, 228, 226, 228}, - }, - { - {231, 229, 230, 228}, - {228, 230, 227, 229}, - {230, 228, 230, 228}, - {227, 229, 227, 229}, - }, - { - {232, 230, 231, 229}, - {229, 231, 228, 230}, - {231, 229, 231, 229}, - {228, 230, 228, 230}, - }, - { - {233, 231, 232, 230}, - {230, 232, 229, 231}, - {232, 230, 232, 230}, - {229, 231, 229, 231}, - }, - { - {234, 232, 233, 231}, - {231, 233, 230, 232}, - {233, 231, 233, 231}, - {230, 232, 230, 232}, - }, - { - {235, 233, 234, 232}, - {232, 234, 231, 233}, - {234, 232, 234, 232}, - {231, 233, 231, 233}, - }, - { - {236, 234, 235, 233}, - {233, 235, 232, 234}, - {235, 233, 235, 233}, - {232, 234, 232, 234}, - }, - { - {237, 235, 236, 234}, - {234, 236, 233, 235}, - {236, 234, 236, 234}, - {233, 235, 233, 235}, - }, - { - {238, 236, 237, 235}, - {235, 237, 234, 236}, - {237, 235, 237, 235}, - {234, 236, 234, 236}, - }, - { - {239, 237, 238, 236}, - {236, 238, 235, 237}, - {238, 236, 238, 236}, - {235, 237, 235, 237}, - }, - { - {240, 238, 239, 237}, - {237, 239, 236, 238}, - {239, 237, 239, 237}, - {236, 238, 236, 238}, - }, - { - {241, 239, 240, 238}, - {238, 240, 237, 239}, - {240, 238, 240, 238}, - {237, 239, 237, 239}, - }, - { - {242, 240, 241, 239}, - {239, 241, 238, 240}, - {241, 239, 241, 239}, - {238, 240, 238, 240}, - }, - { - {243, 241, 242, 240}, - {240, 242, 239, 241}, - {242, 240, 242, 240}, - {239, 241, 239, 241}, - }, - { - {244, 242, 243, 241}, - {241, 243, 240, 242}, - {243, 241, 243, 241}, - {240, 242, 240, 242}, - }, - { - {245, 243, 244, 242}, - {242, 244, 241, 243}, - {244, 242, 244, 242}, - {241, 243, 241, 243}, - }, - { - {246, 244, 245, 243}, - {243, 245, 242, 244}, - {245, 243, 245, 243}, - {242, 244, 242, 244}, - }, - { - {247, 245, 246, 244}, - {244, 246, 243, 245}, - {246, 244, 246, 244}, - {243, 245, 243, 245}, - }, - { - {248, 246, 247, 245}, - {245, 247, 244, 246}, - {247, 245, 247, 245}, - {244, 246, 244, 246}, - }, - { - {249, 247, 248, 246}, - {246, 248, 245, 247}, - {248, 246, 248, 246}, - {245, 247, 245, 247}, - }, - { - {250, 248, 249, 247}, - {247, 249, 246, 248}, - {249, 247, 249, 247}, - {246, 248, 246, 248}, - }, - { - {251, 249, 250, 248}, - {248, 250, 247, 249}, - {250, 248, 250, 248}, - {247, 249, 247, 249}, - }, - { - {252, 250, 251, 249}, - {249, 251, 248, 250}, - {251, 249, 251, 249}, - {248, 250, 248, 250}, - }, - { - {253, 251, 252, 250}, - {250, 252, 249, 251}, - {252, 250, 252, 250}, - {249, 251, 249, 251}, - }, - { - {254, 252, 253, 251}, - {251, 253, 250, 252}, - {253, 251, 253, 251}, - {250, 252, 250, 252}, - }, - { - {255, 253, 254, 252}, - {252, 254, 251, 253}, - {254, 252, 254, 252}, - {251, 253, 251, 253}, - }, - { - {255, 254, 255, 253}, - {253, 255, 252, 254}, - {255, 253, 255, 253}, - {252, 254, 252, 254}, - }, - { - {255, 255, 255, 254}, - {254, 255, 253, 255}, - {255, 254, 255, 254}, - {253, 255, 253, 255}, - }, - { - {255, 255, 255, 255}, - {255, 255, 254, 255}, - {255, 255, 255, 255}, - {254, 255, 254, 255}, - }, +static const uint8_t dithersub_g[256][4][4] = { + { + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + }, + { + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + }, + { + {5, 3, 4, 2}, + {2, 4, 1, 3}, + {4, 2, 4, 2}, + {1, 3, 1, 3}, + }, + { + {6, 4, 5, 3}, + {3, 5, 2, 4}, + {5, 3, 5, 3}, + {2, 4, 2, 4}, + }, + { + {7, 5, 6, 4}, + {4, 6, 3, 5}, + {6, 4, 6, 4}, + {3, 5, 3, 5}, + }, + { + {8, 6, 7, 5}, + {5, 7, 4, 6}, + {7, 5, 7, 5}, + {4, 6, 4, 6}, + }, + { + {9, 7, 8, 6}, + {6, 8, 5, 7}, + {8, 6, 8, 6}, + {5, 7, 5, 7}, + }, + { + {10, 8, 9, 7}, + {7, 9, 6, 8}, + {9, 7, 9, 7}, + {6, 8, 6, 8}, + }, + { + {11, 9, 10, 8}, + {8, 10, 7, 9}, + {10, 8, 10, 8}, + {7, 9, 7, 9}, + }, + { + {12, 10, 11, 9}, + {9, 11, 8, 10}, + {11, 9, 11, 9}, + {8, 10, 8, 10}, + }, + { + {13, 11, 12, 10}, + {10, 12, 9, 11}, + {12, 10, 12, 10}, + {9, 11, 9, 11}, + }, + { + {14, 12, 13, 11}, + {11, 13, 10, 12}, + {13, 11, 13, 11}, + {10, 12, 10, 12}, + }, + { + {15, 13, 14, 12}, + {12, 14, 11, 13}, + {14, 12, 14, 12}, + {11, 13, 11, 13}, + }, + { + {16, 14, 15, 13}, + {13, 15, 12, 14}, + {15, 13, 15, 13}, + {12, 14, 12, 14}, + }, + { + {17, 15, 16, 14}, + {14, 16, 13, 15}, + {16, 14, 16, 14}, + {13, 15, 13, 15}, + }, + { + {18, 16, 17, 15}, + {15, 17, 14, 16}, + {17, 15, 17, 15}, + {14, 16, 14, 16}, + }, + { + {19, 17, 18, 16}, + {16, 18, 15, 17}, + {18, 16, 18, 16}, + {15, 17, 15, 17}, + }, + { + {20, 18, 19, 17}, + {17, 19, 16, 18}, + {19, 17, 19, 17}, + {16, 18, 16, 18}, + }, + { + {21, 19, 20, 18}, + {18, 20, 17, 19}, + {20, 18, 20, 18}, + {17, 19, 17, 19}, + }, + { + {22, 20, 21, 19}, + {19, 21, 18, 20}, + {21, 19, 21, 19}, + {18, 20, 18, 20}, + }, + { + {23, 21, 22, 20}, + {20, 22, 19, 21}, + {22, 20, 22, 20}, + {19, 21, 19, 21}, + }, + { + {24, 22, 23, 21}, + {21, 23, 20, 22}, + {23, 21, 23, 21}, + {20, 22, 20, 22}, + }, + { + {25, 23, 24, 22}, + {22, 24, 21, 23}, + {24, 22, 24, 22}, + {21, 23, 21, 23}, + }, + { + {26, 24, 25, 23}, + {23, 25, 22, 24}, + {25, 23, 25, 23}, + {22, 24, 22, 24}, + }, + { + {27, 25, 26, 24}, + {24, 26, 23, 25}, + {26, 24, 26, 24}, + {23, 25, 23, 25}, + }, + { + {28, 26, 27, 25}, + {25, 27, 24, 26}, + {27, 25, 27, 25}, + {24, 26, 24, 26}, + }, + { + {29, 27, 28, 26}, + {26, 28, 25, 27}, + {28, 26, 28, 26}, + {25, 27, 25, 27}, + }, + { + {30, 28, 29, 27}, + {27, 29, 26, 28}, + {29, 27, 29, 27}, + {26, 28, 26, 28}, + }, + { + {31, 29, 30, 28}, + {28, 30, 27, 29}, + {30, 28, 30, 28}, + {27, 29, 27, 29}, + }, + { + {32, 30, 31, 29}, + {29, 31, 28, 30}, + {31, 29, 31, 29}, + {28, 30, 28, 30}, + }, + { + {33, 31, 32, 30}, + {30, 32, 29, 31}, + {32, 30, 32, 30}, + {29, 31, 29, 31}, + }, + { + {34, 32, 33, 31}, + {31, 33, 30, 32}, + {33, 31, 33, 31}, + {30, 32, 30, 32}, + }, + { + {35, 33, 34, 32}, + {32, 34, 31, 33}, + {34, 32, 34, 32}, + {31, 33, 31, 33}, + }, + { + {36, 34, 35, 33}, + {33, 35, 32, 34}, + {35, 33, 35, 33}, + {32, 34, 32, 34}, + }, + { + {37, 35, 36, 34}, + {34, 36, 33, 35}, + {36, 34, 36, 34}, + {33, 35, 33, 35}, + }, + { + {38, 36, 37, 35}, + {35, 37, 34, 36}, + {37, 35, 37, 35}, + {34, 36, 34, 36}, + }, + { + {39, 37, 38, 36}, + {36, 38, 35, 37}, + {38, 36, 38, 36}, + {35, 37, 35, 37}, + }, + { + {40, 38, 39, 37}, + {37, 39, 36, 38}, + {39, 37, 39, 37}, + {36, 38, 36, 38}, + }, + { + {41, 39, 40, 38}, + {38, 40, 37, 39}, + {40, 38, 40, 38}, + {37, 39, 37, 39}, + }, + { + {42, 40, 41, 39}, + {39, 41, 38, 40}, + {41, 39, 41, 39}, + {38, 40, 38, 40}, + }, + { + {43, 41, 42, 40}, + {40, 42, 39, 41}, + {42, 40, 42, 40}, + {39, 41, 39, 41}, + }, + { + {44, 42, 43, 41}, + {41, 43, 40, 42}, + {43, 41, 43, 41}, + {40, 42, 40, 42}, + }, + { + {45, 43, 44, 42}, + {42, 44, 41, 43}, + {44, 42, 44, 42}, + {41, 43, 41, 43}, + }, + { + {46, 44, 45, 43}, + {43, 45, 42, 44}, + {45, 43, 45, 43}, + {42, 44, 42, 44}, + }, + { + {47, 45, 46, 44}, + {44, 46, 43, 45}, + {46, 44, 46, 44}, + {43, 45, 43, 45}, + }, + { + {48, 46, 47, 45}, + {45, 47, 44, 46}, + {47, 45, 47, 45}, + {44, 46, 44, 46}, + }, + { + {49, 47, 48, 46}, + {46, 48, 45, 47}, + {48, 46, 48, 46}, + {45, 47, 45, 47}, + }, + { + {50, 48, 49, 47}, + {47, 49, 46, 48}, + {49, 47, 49, 47}, + {46, 48, 46, 48}, + }, + { + {51, 49, 50, 48}, + {48, 50, 47, 49}, + {50, 48, 50, 48}, + {47, 49, 47, 49}, + }, + { + {52, 50, 51, 49}, + {49, 51, 48, 50}, + {51, 49, 51, 49}, + {48, 50, 48, 50}, + }, + { + {53, 51, 52, 50}, + {50, 52, 49, 51}, + {52, 50, 52, 50}, + {49, 51, 49, 51}, + }, + { + {54, 52, 53, 51}, + {51, 53, 50, 52}, + {53, 51, 53, 51}, + {50, 52, 50, 52}, + }, + { + {55, 53, 54, 52}, + {52, 54, 51, 53}, + {54, 52, 54, 52}, + {51, 53, 51, 53}, + }, + { + {56, 54, 55, 53}, + {53, 55, 52, 54}, + {55, 53, 55, 53}, + {52, 54, 52, 54}, + }, + { + {57, 55, 56, 54}, + {54, 56, 53, 55}, + {56, 54, 56, 54}, + {53, 55, 53, 55}, + }, + { + {58, 56, 57, 55}, + {55, 57, 54, 56}, + {57, 55, 57, 55}, + {54, 56, 54, 56}, + }, + { + {59, 57, 58, 56}, + {56, 58, 55, 57}, + {58, 56, 58, 56}, + {55, 57, 55, 57}, + }, + { + {60, 58, 59, 57}, + {57, 59, 56, 58}, + {59, 57, 59, 57}, + {56, 58, 56, 58}, + }, + { + {61, 59, 60, 58}, + {58, 60, 57, 59}, + {60, 58, 60, 58}, + {57, 59, 57, 59}, + }, + { + {62, 60, 61, 59}, + {59, 61, 58, 60}, + {61, 59, 61, 59}, + {58, 60, 58, 60}, + }, + { + {63, 61, 62, 60}, + {60, 62, 59, 61}, + {62, 60, 62, 60}, + {59, 61, 59, 61}, + }, + { + {64, 62, 63, 61}, + {61, 63, 60, 62}, + {63, 61, 63, 61}, + {60, 62, 60, 62}, + }, + { + {65, 63, 64, 62}, + {62, 64, 61, 63}, + {64, 62, 64, 62}, + {61, 63, 61, 63}, + }, + { + {66, 64, 65, 63}, + {63, 65, 62, 64}, + {65, 63, 65, 63}, + {62, 64, 62, 64}, + }, + { + {67, 65, 66, 64}, + {64, 66, 63, 65}, + {66, 64, 66, 64}, + {63, 65, 63, 65}, + }, + { + {68, 66, 67, 65}, + {65, 67, 64, 66}, + {67, 65, 67, 65}, + {64, 66, 64, 66}, + }, + { + {69, 67, 68, 66}, + {66, 68, 65, 67}, + {68, 66, 68, 66}, + {65, 67, 65, 67}, + }, + { + {70, 68, 69, 67}, + {67, 69, 66, 68}, + {69, 67, 69, 67}, + {66, 68, 66, 68}, + }, + { + {71, 69, 70, 68}, + {68, 70, 67, 69}, + {70, 68, 70, 68}, + {67, 69, 67, 69}, + }, + { + {72, 70, 71, 69}, + {69, 71, 68, 70}, + {71, 69, 71, 69}, + {68, 70, 68, 70}, + }, + { + {73, 71, 72, 70}, + {70, 72, 69, 71}, + {72, 70, 72, 70}, + {69, 71, 69, 71}, + }, + { + {74, 72, 73, 71}, + {71, 73, 70, 72}, + {73, 71, 73, 71}, + {70, 72, 70, 72}, + }, + { + {75, 73, 74, 72}, + {72, 74, 71, 73}, + {74, 72, 74, 72}, + {71, 73, 71, 73}, + }, + { + {76, 74, 75, 73}, + {73, 75, 72, 74}, + {75, 73, 75, 73}, + {72, 74, 72, 74}, + }, + { + {77, 75, 76, 74}, + {74, 76, 73, 75}, + {76, 74, 76, 74}, + {73, 75, 73, 75}, + }, + { + {78, 76, 77, 75}, + {75, 77, 74, 76}, + {77, 75, 77, 75}, + {74, 76, 74, 76}, + }, + { + {79, 77, 78, 76}, + {76, 78, 75, 77}, + {78, 76, 78, 76}, + {75, 77, 75, 77}, + }, + { + {80, 78, 79, 77}, + {77, 79, 76, 78}, + {79, 77, 79, 77}, + {76, 78, 76, 78}, + }, + { + {81, 79, 80, 78}, + {78, 80, 77, 79}, + {80, 78, 80, 78}, + {77, 79, 77, 79}, + }, + { + {82, 80, 81, 79}, + {79, 81, 78, 80}, + {81, 79, 81, 79}, + {78, 80, 78, 80}, + }, + { + {83, 81, 82, 80}, + {80, 82, 79, 81}, + {82, 80, 82, 80}, + {79, 81, 79, 81}, + }, + { + {84, 82, 83, 81}, + {81, 83, 80, 82}, + {83, 81, 83, 81}, + {80, 82, 80, 82}, + }, + { + {85, 83, 84, 82}, + {82, 84, 81, 83}, + {84, 82, 84, 82}, + {81, 83, 81, 83}, + }, + { + {86, 84, 85, 83}, + {83, 85, 82, 84}, + {85, 83, 85, 83}, + {82, 84, 82, 84}, + }, + { + {87, 85, 86, 84}, + {84, 86, 83, 85}, + {86, 84, 86, 84}, + {83, 85, 83, 85}, + }, + { + {88, 86, 87, 85}, + {85, 87, 84, 86}, + {87, 85, 87, 85}, + {84, 86, 84, 86}, + }, + { + {89, 87, 88, 86}, + {86, 88, 85, 87}, + {88, 86, 88, 86}, + {85, 87, 85, 87}, + }, + { + {90, 88, 89, 87}, + {87, 89, 86, 88}, + {89, 87, 89, 87}, + {86, 88, 86, 88}, + }, + { + {91, 89, 90, 88}, + {88, 90, 87, 89}, + {90, 88, 90, 88}, + {87, 89, 87, 89}, + }, + { + {92, 90, 91, 89}, + {89, 91, 88, 90}, + {91, 89, 91, 89}, + {88, 90, 88, 90}, + }, + { + {93, 91, 92, 90}, + {90, 92, 89, 91}, + {92, 90, 92, 90}, + {89, 91, 89, 91}, + }, + { + {94, 92, 93, 91}, + {91, 93, 90, 92}, + {93, 91, 93, 91}, + {90, 92, 90, 92}, + }, + { + {95, 93, 94, 92}, + {92, 94, 91, 93}, + {94, 92, 94, 92}, + {91, 93, 91, 93}, + }, + { + {96, 94, 95, 93}, + {93, 95, 92, 94}, + {95, 93, 95, 93}, + {92, 94, 92, 94}, + }, + { + {97, 95, 96, 94}, + {94, 96, 93, 95}, + {96, 94, 96, 94}, + {93, 95, 93, 95}, + }, + { + {98, 96, 97, 95}, + {95, 97, 94, 96}, + {97, 95, 97, 95}, + {94, 96, 94, 96}, + }, + { + {99, 97, 98, 96}, + {96, 98, 95, 97}, + {98, 96, 98, 96}, + {95, 97, 95, 97}, + }, + { + {100, 98, 99, 97}, + {97, 99, 96, 98}, + {99, 97, 99, 97}, + {96, 98, 96, 98}, + }, + { + {101, 99, 100, 98}, + {98, 100, 97, 99}, + {100, 98, 100, 98}, + {97, 99, 97, 99}, + }, + { + {102, 100, 101, 99}, + {99, 101, 98, 100}, + {101, 99, 101, 99}, + {98, 100, 98, 100}, + }, + { + {103, 101, 102, 100}, + {100, 102, 99, 101}, + {102, 100, 102, 100}, + {99, 101, 99, 101}, + }, + { + {104, 102, 103, 101}, + {101, 103, 100, 102}, + {103, 101, 103, 101}, + {100, 102, 100, 102}, + }, + { + {105, 103, 104, 102}, + {102, 104, 101, 103}, + {104, 102, 104, 102}, + {101, 103, 101, 103}, + }, + { + {106, 104, 105, 103}, + {103, 105, 102, 104}, + {105, 103, 105, 103}, + {102, 104, 102, 104}, + }, + { + {107, 105, 106, 104}, + {104, 106, 103, 105}, + {106, 104, 106, 104}, + {103, 105, 103, 105}, + }, + { + {108, 106, 107, 105}, + {105, 107, 104, 106}, + {107, 105, 107, 105}, + {104, 106, 104, 106}, + }, + { + {109, 107, 108, 106}, + {106, 108, 105, 107}, + {108, 106, 108, 106}, + {105, 107, 105, 107}, + }, + { + {110, 108, 109, 107}, + {107, 109, 106, 108}, + {109, 107, 109, 107}, + {106, 108, 106, 108}, + }, + { + {111, 109, 110, 108}, + {108, 110, 107, 109}, + {110, 108, 110, 108}, + {107, 109, 107, 109}, + }, + { + {112, 110, 111, 109}, + {109, 111, 108, 110}, + {111, 109, 111, 109}, + {108, 110, 108, 110}, + }, + { + {113, 111, 112, 110}, + {110, 112, 109, 111}, + {112, 110, 112, 110}, + {109, 111, 109, 111}, + }, + { + {114, 112, 113, 111}, + {111, 113, 110, 112}, + {113, 111, 113, 111}, + {110, 112, 110, 112}, + }, + { + {115, 113, 114, 112}, + {112, 114, 111, 113}, + {114, 112, 114, 112}, + {111, 113, 111, 113}, + }, + { + {116, 114, 115, 113}, + {113, 115, 112, 114}, + {115, 113, 115, 113}, + {112, 114, 112, 114}, + }, + { + {117, 115, 116, 114}, + {114, 116, 113, 115}, + {116, 114, 116, 114}, + {113, 115, 113, 115}, + }, + { + {118, 116, 117, 115}, + {115, 117, 114, 116}, + {117, 115, 117, 115}, + {114, 116, 114, 116}, + }, + { + {119, 117, 118, 116}, + {116, 118, 115, 117}, + {118, 116, 118, 116}, + {115, 117, 115, 117}, + }, + { + {120, 118, 119, 117}, + {117, 119, 116, 118}, + {119, 117, 119, 117}, + {116, 118, 116, 118}, + }, + { + {121, 119, 120, 118}, + {118, 120, 117, 119}, + {120, 118, 120, 118}, + {117, 119, 117, 119}, + }, + { + {122, 120, 121, 119}, + {119, 121, 118, 120}, + {121, 119, 121, 119}, + {118, 120, 118, 120}, + }, + { + {123, 121, 122, 120}, + {120, 122, 119, 121}, + {122, 120, 122, 120}, + {119, 121, 119, 121}, + }, + { + {124, 122, 123, 121}, + {121, 123, 120, 122}, + {123, 121, 123, 121}, + {120, 122, 120, 122}, + }, + { + {125, 123, 124, 122}, + {122, 124, 121, 123}, + {124, 122, 124, 122}, + {121, 123, 121, 123}, + }, + { + {126, 124, 125, 123}, + {123, 125, 122, 124}, + {125, 123, 125, 123}, + {122, 124, 122, 124}, + }, + { + {127, 125, 126, 124}, + {124, 126, 123, 125}, + {126, 124, 126, 124}, + {123, 125, 123, 125}, + }, + { + {128, 126, 127, 125}, + {125, 127, 124, 126}, + {127, 125, 127, 125}, + {124, 126, 124, 126}, + }, + { + {129, 127, 128, 126}, + {126, 128, 125, 127}, + {128, 126, 128, 126}, + {125, 127, 125, 127}, + }, + { + {130, 128, 129, 127}, + {127, 129, 126, 128}, + {129, 127, 129, 127}, + {126, 128, 126, 128}, + }, + { + {131, 129, 130, 128}, + {128, 130, 127, 129}, + {130, 128, 130, 128}, + {127, 129, 127, 129}, + }, + { + {132, 130, 131, 129}, + {129, 131, 128, 130}, + {131, 129, 131, 129}, + {128, 130, 128, 130}, + }, + { + {133, 131, 132, 130}, + {130, 132, 129, 131}, + {132, 130, 132, 130}, + {129, 131, 129, 131}, + }, + { + {134, 132, 133, 131}, + {131, 133, 130, 132}, + {133, 131, 133, 131}, + {130, 132, 130, 132}, + }, + { + {135, 133, 134, 132}, + {132, 134, 131, 133}, + {134, 132, 134, 132}, + {131, 133, 131, 133}, + }, + { + {136, 134, 135, 133}, + {133, 135, 132, 134}, + {135, 133, 135, 133}, + {132, 134, 132, 134}, + }, + { + {137, 135, 136, 134}, + {134, 136, 133, 135}, + {136, 134, 136, 134}, + {133, 135, 133, 135}, + }, + { + {138, 136, 137, 135}, + {135, 137, 134, 136}, + {137, 135, 137, 135}, + {134, 136, 134, 136}, + }, + { + {139, 137, 138, 136}, + {136, 138, 135, 137}, + {138, 136, 138, 136}, + {135, 137, 135, 137}, + }, + { + {140, 138, 139, 137}, + {137, 139, 136, 138}, + {139, 137, 139, 137}, + {136, 138, 136, 138}, + }, + { + {141, 139, 140, 138}, + {138, 140, 137, 139}, + {140, 138, 140, 138}, + {137, 139, 137, 139}, + }, + { + {142, 140, 141, 139}, + {139, 141, 138, 140}, + {141, 139, 141, 139}, + {138, 140, 138, 140}, + }, + { + {143, 141, 142, 140}, + {140, 142, 139, 141}, + {142, 140, 142, 140}, + {139, 141, 139, 141}, + }, + { + {144, 142, 143, 141}, + {141, 143, 140, 142}, + {143, 141, 143, 141}, + {140, 142, 140, 142}, + }, + { + {145, 143, 144, 142}, + {142, 144, 141, 143}, + {144, 142, 144, 142}, + {141, 143, 141, 143}, + }, + { + {146, 144, 145, 143}, + {143, 145, 142, 144}, + {145, 143, 145, 143}, + {142, 144, 142, 144}, + }, + { + {147, 145, 146, 144}, + {144, 146, 143, 145}, + {146, 144, 146, 144}, + {143, 145, 143, 145}, + }, + { + {148, 146, 147, 145}, + {145, 147, 144, 146}, + {147, 145, 147, 145}, + {144, 146, 144, 146}, + }, + { + {149, 147, 148, 146}, + {146, 148, 145, 147}, + {148, 146, 148, 146}, + {145, 147, 145, 147}, + }, + { + {150, 148, 149, 147}, + {147, 149, 146, 148}, + {149, 147, 149, 147}, + {146, 148, 146, 148}, + }, + { + {151, 149, 150, 148}, + {148, 150, 147, 149}, + {150, 148, 150, 148}, + {147, 149, 147, 149}, + }, + { + {152, 150, 151, 149}, + {149, 151, 148, 150}, + {151, 149, 151, 149}, + {148, 150, 148, 150}, + }, + { + {153, 151, 152, 150}, + {150, 152, 149, 151}, + {152, 150, 152, 150}, + {149, 151, 149, 151}, + }, + { + {154, 152, 153, 151}, + {151, 153, 150, 152}, + {153, 151, 153, 151}, + {150, 152, 150, 152}, + }, + { + {155, 153, 154, 152}, + {152, 154, 151, 153}, + {154, 152, 154, 152}, + {151, 153, 151, 153}, + }, + { + {156, 154, 155, 153}, + {153, 155, 152, 154}, + {155, 153, 155, 153}, + {152, 154, 152, 154}, + }, + { + {157, 155, 156, 154}, + {154, 156, 153, 155}, + {156, 154, 156, 154}, + {153, 155, 153, 155}, + }, + { + {158, 156, 157, 155}, + {155, 157, 154, 156}, + {157, 155, 157, 155}, + {154, 156, 154, 156}, + }, + { + {159, 157, 158, 156}, + {156, 158, 155, 157}, + {158, 156, 158, 156}, + {155, 157, 155, 157}, + }, + { + {160, 158, 159, 157}, + {157, 159, 156, 158}, + {159, 157, 159, 157}, + {156, 158, 156, 158}, + }, + { + {161, 159, 160, 158}, + {158, 160, 157, 159}, + {160, 158, 160, 158}, + {157, 159, 157, 159}, + }, + { + {162, 160, 161, 159}, + {159, 161, 158, 160}, + {161, 159, 161, 159}, + {158, 160, 158, 160}, + }, + { + {163, 161, 162, 160}, + {160, 162, 159, 161}, + {162, 160, 162, 160}, + {159, 161, 159, 161}, + }, + { + {164, 162, 163, 161}, + {161, 163, 160, 162}, + {163, 161, 163, 161}, + {160, 162, 160, 162}, + }, + { + {165, 163, 164, 162}, + {162, 164, 161, 163}, + {164, 162, 164, 162}, + {161, 163, 161, 163}, + }, + { + {166, 164, 165, 163}, + {163, 165, 162, 164}, + {165, 163, 165, 163}, + {162, 164, 162, 164}, + }, + { + {167, 165, 166, 164}, + {164, 166, 163, 165}, + {166, 164, 166, 164}, + {163, 165, 163, 165}, + }, + { + {168, 166, 167, 165}, + {165, 167, 164, 166}, + {167, 165, 167, 165}, + {164, 166, 164, 166}, + }, + { + {169, 167, 168, 166}, + {166, 168, 165, 167}, + {168, 166, 168, 166}, + {165, 167, 165, 167}, + }, + { + {170, 168, 169, 167}, + {167, 169, 166, 168}, + {169, 167, 169, 167}, + {166, 168, 166, 168}, + }, + { + {171, 169, 170, 168}, + {168, 170, 167, 169}, + {170, 168, 170, 168}, + {167, 169, 167, 169}, + }, + { + {172, 170, 171, 169}, + {169, 171, 168, 170}, + {171, 169, 171, 169}, + {168, 170, 168, 170}, + }, + { + {173, 171, 172, 170}, + {170, 172, 169, 171}, + {172, 170, 172, 170}, + {169, 171, 169, 171}, + }, + { + {174, 172, 173, 171}, + {171, 173, 170, 172}, + {173, 171, 173, 171}, + {170, 172, 170, 172}, + }, + { + {175, 173, 174, 172}, + {172, 174, 171, 173}, + {174, 172, 174, 172}, + {171, 173, 171, 173}, + }, + { + {176, 174, 175, 173}, + {173, 175, 172, 174}, + {175, 173, 175, 173}, + {172, 174, 172, 174}, + }, + { + {177, 175, 176, 174}, + {174, 176, 173, 175}, + {176, 174, 176, 174}, + {173, 175, 173, 175}, + }, + { + {178, 176, 177, 175}, + {175, 177, 174, 176}, + {177, 175, 177, 175}, + {174, 176, 174, 176}, + }, + { + {179, 177, 178, 176}, + {176, 178, 175, 177}, + {178, 176, 178, 176}, + {175, 177, 175, 177}, + }, + { + {180, 178, 179, 177}, + {177, 179, 176, 178}, + {179, 177, 179, 177}, + {176, 178, 176, 178}, + }, + { + {181, 179, 180, 178}, + {178, 180, 177, 179}, + {180, 178, 180, 178}, + {177, 179, 177, 179}, + }, + { + {182, 180, 181, 179}, + {179, 181, 178, 180}, + {181, 179, 181, 179}, + {178, 180, 178, 180}, + }, + { + {183, 181, 182, 180}, + {180, 182, 179, 181}, + {182, 180, 182, 180}, + {179, 181, 179, 181}, + }, + { + {184, 182, 183, 181}, + {181, 183, 180, 182}, + {183, 181, 183, 181}, + {180, 182, 180, 182}, + }, + { + {185, 183, 184, 182}, + {182, 184, 181, 183}, + {184, 182, 184, 182}, + {181, 183, 181, 183}, + }, + { + {186, 184, 185, 183}, + {183, 185, 182, 184}, + {185, 183, 185, 183}, + {182, 184, 182, 184}, + }, + { + {187, 185, 186, 184}, + {184, 186, 183, 185}, + {186, 184, 186, 184}, + {183, 185, 183, 185}, + }, + { + {188, 186, 187, 185}, + {185, 187, 184, 186}, + {187, 185, 187, 185}, + {184, 186, 184, 186}, + }, + { + {189, 187, 188, 186}, + {186, 188, 185, 187}, + {188, 186, 188, 186}, + {185, 187, 185, 187}, + }, + { + {190, 188, 189, 187}, + {187, 189, 186, 188}, + {189, 187, 189, 187}, + {186, 188, 186, 188}, + }, + { + {191, 189, 190, 188}, + {188, 190, 187, 189}, + {190, 188, 190, 188}, + {187, 189, 187, 189}, + }, + { + {192, 190, 191, 189}, + {189, 191, 188, 190}, + {191, 189, 191, 189}, + {188, 190, 188, 190}, + }, + { + {193, 191, 192, 190}, + {190, 192, 189, 191}, + {192, 190, 192, 190}, + {189, 191, 189, 191}, + }, + { + {194, 192, 193, 191}, + {191, 193, 190, 192}, + {193, 191, 193, 191}, + {190, 192, 190, 192}, + }, + { + {195, 193, 194, 192}, + {192, 194, 191, 193}, + {194, 192, 194, 192}, + {191, 193, 191, 193}, + }, + { + {196, 194, 195, 193}, + {193, 195, 192, 194}, + {195, 193, 195, 193}, + {192, 194, 192, 194}, + }, + { + {197, 195, 196, 194}, + {194, 196, 193, 195}, + {196, 194, 196, 194}, + {193, 195, 193, 195}, + }, + { + {198, 196, 197, 195}, + {195, 197, 194, 196}, + {197, 195, 197, 195}, + {194, 196, 194, 196}, + }, + { + {199, 197, 198, 196}, + {196, 198, 195, 197}, + {198, 196, 198, 196}, + {195, 197, 195, 197}, + }, + { + {200, 198, 199, 197}, + {197, 199, 196, 198}, + {199, 197, 199, 197}, + {196, 198, 196, 198}, + }, + { + {201, 199, 200, 198}, + {198, 200, 197, 199}, + {200, 198, 200, 198}, + {197, 199, 197, 199}, + }, + { + {202, 200, 201, 199}, + {199, 201, 198, 200}, + {201, 199, 201, 199}, + {198, 200, 198, 200}, + }, + { + {203, 201, 202, 200}, + {200, 202, 199, 201}, + {202, 200, 202, 200}, + {199, 201, 199, 201}, + }, + { + {204, 202, 203, 201}, + {201, 203, 200, 202}, + {203, 201, 203, 201}, + {200, 202, 200, 202}, + }, + { + {205, 203, 204, 202}, + {202, 204, 201, 203}, + {204, 202, 204, 202}, + {201, 203, 201, 203}, + }, + { + {206, 204, 205, 203}, + {203, 205, 202, 204}, + {205, 203, 205, 203}, + {202, 204, 202, 204}, + }, + { + {207, 205, 206, 204}, + {204, 206, 203, 205}, + {206, 204, 206, 204}, + {203, 205, 203, 205}, + }, + { + {208, 206, 207, 205}, + {205, 207, 204, 206}, + {207, 205, 207, 205}, + {204, 206, 204, 206}, + }, + { + {209, 207, 208, 206}, + {206, 208, 205, 207}, + {208, 206, 208, 206}, + {205, 207, 205, 207}, + }, + { + {210, 208, 209, 207}, + {207, 209, 206, 208}, + {209, 207, 209, 207}, + {206, 208, 206, 208}, + }, + { + {211, 209, 210, 208}, + {208, 210, 207, 209}, + {210, 208, 210, 208}, + {207, 209, 207, 209}, + }, + { + {212, 210, 211, 209}, + {209, 211, 208, 210}, + {211, 209, 211, 209}, + {208, 210, 208, 210}, + }, + { + {213, 211, 212, 210}, + {210, 212, 209, 211}, + {212, 210, 212, 210}, + {209, 211, 209, 211}, + }, + { + {214, 212, 213, 211}, + {211, 213, 210, 212}, + {213, 211, 213, 211}, + {210, 212, 210, 212}, + }, + { + {215, 213, 214, 212}, + {212, 214, 211, 213}, + {214, 212, 214, 212}, + {211, 213, 211, 213}, + }, + { + {216, 214, 215, 213}, + {213, 215, 212, 214}, + {215, 213, 215, 213}, + {212, 214, 212, 214}, + }, + { + {217, 215, 216, 214}, + {214, 216, 213, 215}, + {216, 214, 216, 214}, + {213, 215, 213, 215}, + }, + { + {218, 216, 217, 215}, + {215, 217, 214, 216}, + {217, 215, 217, 215}, + {214, 216, 214, 216}, + }, + { + {219, 217, 218, 216}, + {216, 218, 215, 217}, + {218, 216, 218, 216}, + {215, 217, 215, 217}, + }, + { + {220, 218, 219, 217}, + {217, 219, 216, 218}, + {219, 217, 219, 217}, + {216, 218, 216, 218}, + }, + { + {221, 219, 220, 218}, + {218, 220, 217, 219}, + {220, 218, 220, 218}, + {217, 219, 217, 219}, + }, + { + {222, 220, 221, 219}, + {219, 221, 218, 220}, + {221, 219, 221, 219}, + {218, 220, 218, 220}, + }, + { + {223, 221, 222, 220}, + {220, 222, 219, 221}, + {222, 220, 222, 220}, + {219, 221, 219, 221}, + }, + { + {224, 222, 223, 221}, + {221, 223, 220, 222}, + {223, 221, 223, 221}, + {220, 222, 220, 222}, + }, + { + {225, 223, 224, 222}, + {222, 224, 221, 223}, + {224, 222, 224, 222}, + {221, 223, 221, 223}, + }, + { + {226, 224, 225, 223}, + {223, 225, 222, 224}, + {225, 223, 225, 223}, + {222, 224, 222, 224}, + }, + { + {227, 225, 226, 224}, + {224, 226, 223, 225}, + {226, 224, 226, 224}, + {223, 225, 223, 225}, + }, + { + {228, 226, 227, 225}, + {225, 227, 224, 226}, + {227, 225, 227, 225}, + {224, 226, 224, 226}, + }, + { + {229, 227, 228, 226}, + {226, 228, 225, 227}, + {228, 226, 228, 226}, + {225, 227, 225, 227}, + }, + { + {230, 228, 229, 227}, + {227, 229, 226, 228}, + {229, 227, 229, 227}, + {226, 228, 226, 228}, + }, + { + {231, 229, 230, 228}, + {228, 230, 227, 229}, + {230, 228, 230, 228}, + {227, 229, 227, 229}, + }, + { + {232, 230, 231, 229}, + {229, 231, 228, 230}, + {231, 229, 231, 229}, + {228, 230, 228, 230}, + }, + { + {233, 231, 232, 230}, + {230, 232, 229, 231}, + {232, 230, 232, 230}, + {229, 231, 229, 231}, + }, + { + {234, 232, 233, 231}, + {231, 233, 230, 232}, + {233, 231, 233, 231}, + {230, 232, 230, 232}, + }, + { + {235, 233, 234, 232}, + {232, 234, 231, 233}, + {234, 232, 234, 232}, + {231, 233, 231, 233}, + }, + { + {236, 234, 235, 233}, + {233, 235, 232, 234}, + {235, 233, 235, 233}, + {232, 234, 232, 234}, + }, + { + {237, 235, 236, 234}, + {234, 236, 233, 235}, + {236, 234, 236, 234}, + {233, 235, 233, 235}, + }, + { + {238, 236, 237, 235}, + {235, 237, 234, 236}, + {237, 235, 237, 235}, + {234, 236, 234, 236}, + }, + { + {239, 237, 238, 236}, + {236, 238, 235, 237}, + {238, 236, 238, 236}, + {235, 237, 235, 237}, + }, + { + {240, 238, 239, 237}, + {237, 239, 236, 238}, + {239, 237, 239, 237}, + {236, 238, 236, 238}, + }, + { + {241, 239, 240, 238}, + {238, 240, 237, 239}, + {240, 238, 240, 238}, + {237, 239, 237, 239}, + }, + { + {242, 240, 241, 239}, + {239, 241, 238, 240}, + {241, 239, 241, 239}, + {238, 240, 238, 240}, + }, + { + {243, 241, 242, 240}, + {240, 242, 239, 241}, + {242, 240, 242, 240}, + {239, 241, 239, 241}, + }, + { + {244, 242, 243, 241}, + {241, 243, 240, 242}, + {243, 241, 243, 241}, + {240, 242, 240, 242}, + }, + { + {245, 243, 244, 242}, + {242, 244, 241, 243}, + {244, 242, 244, 242}, + {241, 243, 241, 243}, + }, + { + {246, 244, 245, 243}, + {243, 245, 242, 244}, + {245, 243, 245, 243}, + {242, 244, 242, 244}, + }, + { + {247, 245, 246, 244}, + {244, 246, 243, 245}, + {246, 244, 246, 244}, + {243, 245, 243, 245}, + }, + { + {248, 246, 247, 245}, + {245, 247, 244, 246}, + {247, 245, 247, 245}, + {244, 246, 244, 246}, + }, + { + {249, 247, 248, 246}, + {246, 248, 245, 247}, + {248, 246, 248, 246}, + {245, 247, 245, 247}, + }, + { + {250, 248, 249, 247}, + {247, 249, 246, 248}, + {249, 247, 249, 247}, + {246, 248, 246, 248}, + }, + { + {251, 249, 250, 248}, + {248, 250, 247, 249}, + {250, 248, 250, 248}, + {247, 249, 247, 249}, + }, + { + {252, 250, 251, 249}, + {249, 251, 248, 250}, + {251, 249, 251, 249}, + {248, 250, 248, 250}, + }, + { + {253, 251, 252, 250}, + {250, 252, 249, 251}, + {252, 250, 252, 250}, + {249, 251, 249, 251}, + }, + { + {254, 252, 253, 251}, + {251, 253, 250, 252}, + {253, 251, 253, 251}, + {250, 252, 250, 252}, + }, + { + {255, 253, 254, 252}, + {252, 254, 251, 253}, + {254, 252, 254, 252}, + {251, 253, 251, 253}, + }, + { + {255, 254, 255, 253}, + {253, 255, 252, 254}, + {255, 253, 255, 253}, + {252, 254, 252, 254}, + }, + { + {255, 255, 255, 254}, + {254, 255, 253, 255}, + {255, 254, 255, 254}, + {253, 255, 253, 255}, + }, + { + {255, 255, 255, 255}, + {255, 255, 254, 255}, + {255, 255, 255, 255}, + {254, 255, 254, 255}, + }, }; - - - -static const uint8_t dithersub_g2x2[256][2][2] = -{ - { - {0, 0}, - {0, 0}, - }, - { - {0, 0}, - {0, 0}, - }, - { - {4, 2}, - {1, 3}, - }, - { - {5, 3}, - {2, 4}, - }, - { - {6, 4}, - {3, 5}, - }, - { - {7, 5}, - {4, 6}, - }, - { - {8, 6}, - {5, 7}, - }, - { - {9, 7}, - {6, 8}, - }, - { - {10, 8}, - {7, 9}, - }, - { - {11, 9}, - {8, 10}, - }, - { - {12, 10}, - {9, 11}, - }, - { - {13, 11}, - {10, 12}, - }, - { - {14, 12}, - {11, 13}, - }, - { - {15, 13}, - {12, 14}, - }, - { - {16, 14}, - {13, 15}, - }, - { - {17, 15}, - {14, 16}, - }, - { - {18, 16}, - {15, 17}, - }, - { - {19, 17}, - {16, 18}, - }, - { - {20, 18}, - {17, 19}, - }, - { - {21, 19}, - {18, 20}, - }, - { - {22, 20}, - {19, 21}, - }, - { - {23, 21}, - {20, 22}, - }, - { - {24, 22}, - {21, 23}, - }, - { - {25, 23}, - {22, 24}, - }, - { - {26, 24}, - {23, 25}, - }, - { - {27, 25}, - {24, 26}, - }, - { - {28, 26}, - {25, 27}, - }, - { - {29, 27}, - {26, 28}, - }, - { - {30, 28}, - {27, 29}, - }, - { - {31, 29}, - {28, 30}, - }, - { - {32, 30}, - {29, 31}, - }, - { - {33, 31}, - {30, 32}, - }, - { - {34, 32}, - {31, 33}, - }, - { - {35, 33}, - {32, 34}, - }, - { - {36, 34}, - {33, 35}, - }, - { - {37, 35}, - {34, 36}, - }, - { - {38, 36}, - {35, 37}, - }, - { - {39, 37}, - {36, 38}, - }, - { - {40, 38}, - {37, 39}, - }, - { - {41, 39}, - {38, 40}, - }, - { - {42, 40}, - {39, 41}, - }, - { - {43, 41}, - {40, 42}, - }, - { - {44, 42}, - {41, 43}, - }, - { - {45, 43}, - {42, 44}, - }, - { - {46, 44}, - {43, 45}, - }, - { - {47, 45}, - {44, 46}, - }, - { - {48, 46}, - {45, 47}, - }, - { - {49, 47}, - {46, 48}, - }, - { - {50, 48}, - {47, 49}, - }, - { - {51, 49}, - {48, 50}, - }, - { - {52, 50}, - {49, 51}, - }, - { - {53, 51}, - {50, 52}, - }, - { - {54, 52}, - {51, 53}, - }, - { - {55, 53}, - {52, 54}, - }, - { - {56, 54}, - {53, 55}, - }, - { - {57, 55}, - {54, 56}, - }, - { - {58, 56}, - {55, 57}, - }, - { - {59, 57}, - {56, 58}, - }, - { - {60, 58}, - {57, 59}, - }, - { - {61, 59}, - {58, 60}, - }, - { - {62, 60}, - {59, 61}, - }, - { - {63, 61}, - {60, 62}, - }, - { - {64, 62}, - {61, 63}, - }, - { - {65, 63}, - {62, 64}, - }, - { - {66, 64}, - {63, 65}, - }, - { - {67, 65}, - {64, 66}, - }, - { - {68, 66}, - {65, 67}, - }, - { - {69, 67}, - {66, 68}, - }, - { - {70, 68}, - {67, 69}, - }, - { - {71, 69}, - {68, 70}, - }, - { - {72, 70}, - {69, 71}, - }, - { - {73, 71}, - {70, 72}, - }, - { - {74, 72}, - {71, 73}, - }, - { - {75, 73}, - {72, 74}, - }, - { - {76, 74}, - {73, 75}, - }, - { - {77, 75}, - {74, 76}, - }, - { - {78, 76}, - {75, 77}, - }, - { - {79, 77}, - {76, 78}, - }, - { - {80, 78}, - {77, 79}, - }, - { - {81, 79}, - {78, 80}, - }, - { - {82, 80}, - {79, 81}, - }, - { - {83, 81}, - {80, 82}, - }, - { - {84, 82}, - {81, 83}, - }, - { - {85, 83}, - {82, 84}, - }, - { - {86, 84}, - {83, 85}, - }, - { - {87, 85}, - {84, 86}, - }, - { - {88, 86}, - {85, 87}, - }, - { - {89, 87}, - {86, 88}, - }, - { - {90, 88}, - {87, 89}, - }, - { - {91, 89}, - {88, 90}, - }, - { - {92, 90}, - {89, 91}, - }, - { - {93, 91}, - {90, 92}, - }, - { - {94, 92}, - {91, 93}, - }, - { - {95, 93}, - {92, 94}, - }, - { - {96, 94}, - {93, 95}, - }, - { - {97, 95}, - {94, 96}, - }, - { - {98, 96}, - {95, 97}, - }, - { - {99, 97}, - {96, 98}, - }, - { - {100, 98}, - {97, 99}, - }, - { - {101, 99}, - {98, 100}, - }, - { - {102, 100}, - {99, 101}, - }, - { - {103, 101}, - {100, 102}, - }, - { - {104, 102}, - {101, 103}, - }, - { - {105, 103}, - {102, 104}, - }, - { - {106, 104}, - {103, 105}, - }, - { - {107, 105}, - {104, 106}, - }, - { - {108, 106}, - {105, 107}, - }, - { - {109, 107}, - {106, 108}, - }, - { - {110, 108}, - {107, 109}, - }, - { - {111, 109}, - {108, 110}, - }, - { - {112, 110}, - {109, 111}, - }, - { - {113, 111}, - {110, 112}, - }, - { - {114, 112}, - {111, 113}, - }, - { - {115, 113}, - {112, 114}, - }, - { - {116, 114}, - {113, 115}, - }, - { - {117, 115}, - {114, 116}, - }, - { - {118, 116}, - {115, 117}, - }, - { - {119, 117}, - {116, 118}, - }, - { - {120, 118}, - {117, 119}, - }, - { - {121, 119}, - {118, 120}, - }, - { - {122, 120}, - {119, 121}, - }, - { - {123, 121}, - {120, 122}, - }, - { - {124, 122}, - {121, 123}, - }, - { - {125, 123}, - {122, 124}, - }, - { - {126, 124}, - {123, 125}, - }, - { - {127, 125}, - {124, 126}, - }, - { - {128, 126}, - {125, 127}, - }, - { - {129, 127}, - {126, 128}, - }, - { - {130, 128}, - {127, 129}, - }, - { - {131, 129}, - {128, 130}, - }, - { - {132, 130}, - {129, 131}, - }, - { - {133, 131}, - {130, 132}, - }, - { - {134, 132}, - {131, 133}, - }, - { - {135, 133}, - {132, 134}, - }, - { - {136, 134}, - {133, 135}, - }, - { - {137, 135}, - {134, 136}, - }, - { - {138, 136}, - {135, 137}, - }, - { - {139, 137}, - {136, 138}, - }, - { - {140, 138}, - {137, 139}, - }, - { - {141, 139}, - {138, 140}, - }, - { - {142, 140}, - {139, 141}, - }, - { - {143, 141}, - {140, 142}, - }, - { - {144, 142}, - {141, 143}, - }, - { - {145, 143}, - {142, 144}, - }, - { - {146, 144}, - {143, 145}, - }, - { - {147, 145}, - {144, 146}, - }, - { - {148, 146}, - {145, 147}, - }, - { - {149, 147}, - {146, 148}, - }, - { - {150, 148}, - {147, 149}, - }, - { - {151, 149}, - {148, 150}, - }, - { - {152, 150}, - {149, 151}, - }, - { - {153, 151}, - {150, 152}, - }, - { - {154, 152}, - {151, 153}, - }, - { - {155, 153}, - {152, 154}, - }, - { - {156, 154}, - {153, 155}, - }, - { - {157, 155}, - {154, 156}, - }, - { - {158, 156}, - {155, 157}, - }, - { - {159, 157}, - {156, 158}, - }, - { - {160, 158}, - {157, 159}, - }, - { - {161, 159}, - {158, 160}, - }, - { - {162, 160}, - {159, 161}, - }, - { - {163, 161}, - {160, 162}, - }, - { - {164, 162}, - {161, 163}, - }, - { - {165, 163}, - {162, 164}, - }, - { - {166, 164}, - {163, 165}, - }, - { - {167, 165}, - {164, 166}, - }, - { - {168, 166}, - {165, 167}, - }, - { - {169, 167}, - {166, 168}, - }, - { - {170, 168}, - {167, 169}, - }, - { - {171, 169}, - {168, 170}, - }, - { - {172, 170}, - {169, 171}, - }, - { - {173, 171}, - {170, 172}, - }, - { - {174, 172}, - {171, 173}, - }, - { - {175, 173}, - {172, 174}, - }, - { - {176, 174}, - {173, 175}, - }, - { - {177, 175}, - {174, 176}, - }, - { - {178, 176}, - {175, 177}, - }, - { - {179, 177}, - {176, 178}, - }, - { - {180, 178}, - {177, 179}, - }, - { - {181, 179}, - {178, 180}, - }, - { - {182, 180}, - {179, 181}, - }, - { - {183, 181}, - {180, 182}, - }, - { - {184, 182}, - {181, 183}, - }, - { - {185, 183}, - {182, 184}, - }, - { - {186, 184}, - {183, 185}, - }, - { - {187, 185}, - {184, 186}, - }, - { - {188, 186}, - {185, 187}, - }, - { - {189, 187}, - {186, 188}, - }, - { - {190, 188}, - {187, 189}, - }, - { - {191, 189}, - {188, 190}, - }, - { - {192, 190}, - {189, 191}, - }, - { - {193, 191}, - {190, 192}, - }, - { - {194, 192}, - {191, 193}, - }, - { - {195, 193}, - {192, 194}, - }, - { - {196, 194}, - {193, 195}, - }, - { - {197, 195}, - {194, 196}, - }, - { - {198, 196}, - {195, 197}, - }, - { - {199, 197}, - {196, 198}, - }, - { - {200, 198}, - {197, 199}, - }, - { - {201, 199}, - {198, 200}, - }, - { - {202, 200}, - {199, 201}, - }, - { - {203, 201}, - {200, 202}, - }, - { - {204, 202}, - {201, 203}, - }, - { - {205, 203}, - {202, 204}, - }, - { - {206, 204}, - {203, 205}, - }, - { - {207, 205}, - {204, 206}, - }, - { - {208, 206}, - {205, 207}, - }, - { - {209, 207}, - {206, 208}, - }, - { - {210, 208}, - {207, 209}, - }, - { - {211, 209}, - {208, 210}, - }, - { - {212, 210}, - {209, 211}, - }, - { - {213, 211}, - {210, 212}, - }, - { - {214, 212}, - {211, 213}, - }, - { - {215, 213}, - {212, 214}, - }, - { - {216, 214}, - {213, 215}, - }, - { - {217, 215}, - {214, 216}, - }, - { - {218, 216}, - {215, 217}, - }, - { - {219, 217}, - {216, 218}, - }, - { - {220, 218}, - {217, 219}, - }, - { - {221, 219}, - {218, 220}, - }, - { - {222, 220}, - {219, 221}, - }, - { - {223, 221}, - {220, 222}, - }, - { - {224, 222}, - {221, 223}, - }, - { - {225, 223}, - {222, 224}, - }, - { - {226, 224}, - {223, 225}, - }, - { - {227, 225}, - {224, 226}, - }, - { - {228, 226}, - {225, 227}, - }, - { - {229, 227}, - {226, 228}, - }, - { - {230, 228}, - {227, 229}, - }, - { - {231, 229}, - {228, 230}, - }, - { - {232, 230}, - {229, 231}, - }, - { - {233, 231}, - {230, 232}, - }, - { - {234, 232}, - {231, 233}, - }, - { - {235, 233}, - {232, 234}, - }, - { - {236, 234}, - {233, 235}, - }, - { - {237, 235}, - {234, 236}, - }, - { - {238, 236}, - {235, 237}, - }, - { - {239, 237}, - {236, 238}, - }, - { - {240, 238}, - {237, 239}, - }, - { - {241, 239}, - {238, 240}, - }, - { - {242, 240}, - {239, 241}, - }, - { - {243, 241}, - {240, 242}, - }, - { - {244, 242}, - {241, 243}, - }, - { - {245, 243}, - {242, 244}, - }, - { - {246, 244}, - {243, 245}, - }, - { - {247, 245}, - {244, 246}, - }, - { - {248, 246}, - {245, 247}, - }, - { - {249, 247}, - {246, 248}, - }, - { - {250, 248}, - {247, 249}, - }, - { - {251, 249}, - {248, 250}, - }, - { - {252, 250}, - {249, 251}, - }, - { - {253, 251}, - {250, 252}, - }, - { - {254, 252}, - {251, 253}, - }, - { - {255, 253}, - {252, 254}, - }, - { - {255, 254}, - {253, 255}, - }, - { - {255, 255}, - {254, 255}, - }, +static const uint8_t dithersub_g2x2[256][2][2] = { + { + {0, 0}, + {0, 0}, + }, + { + {0, 0}, + {0, 0}, + }, + { + {4, 2}, + {1, 3}, + }, + { + {5, 3}, + {2, 4}, + }, + { + {6, 4}, + {3, 5}, + }, + { + {7, 5}, + {4, 6}, + }, + { + {8, 6}, + {5, 7}, + }, + { + {9, 7}, + {6, 8}, + }, + { + {10, 8}, + {7, 9}, + }, + { + {11, 9}, + {8, 10}, + }, + { + {12, 10}, + {9, 11}, + }, + { + {13, 11}, + {10, 12}, + }, + { + {14, 12}, + {11, 13}, + }, + { + {15, 13}, + {12, 14}, + }, + { + {16, 14}, + {13, 15}, + }, + { + {17, 15}, + {14, 16}, + }, + { + {18, 16}, + {15, 17}, + }, + { + {19, 17}, + {16, 18}, + }, + { + {20, 18}, + {17, 19}, + }, + { + {21, 19}, + {18, 20}, + }, + { + {22, 20}, + {19, 21}, + }, + { + {23, 21}, + {20, 22}, + }, + { + {24, 22}, + {21, 23}, + }, + { + {25, 23}, + {22, 24}, + }, + { + {26, 24}, + {23, 25}, + }, + { + {27, 25}, + {24, 26}, + }, + { + {28, 26}, + {25, 27}, + }, + { + {29, 27}, + {26, 28}, + }, + { + {30, 28}, + {27, 29}, + }, + { + {31, 29}, + {28, 30}, + }, + { + {32, 30}, + {29, 31}, + }, + { + {33, 31}, + {30, 32}, + }, + { + {34, 32}, + {31, 33}, + }, + { + {35, 33}, + {32, 34}, + }, + { + {36, 34}, + {33, 35}, + }, + { + {37, 35}, + {34, 36}, + }, + { + {38, 36}, + {35, 37}, + }, + { + {39, 37}, + {36, 38}, + }, + { + {40, 38}, + {37, 39}, + }, + { + {41, 39}, + {38, 40}, + }, + { + {42, 40}, + {39, 41}, + }, + { + {43, 41}, + {40, 42}, + }, + { + {44, 42}, + {41, 43}, + }, + { + {45, 43}, + {42, 44}, + }, + { + {46, 44}, + {43, 45}, + }, + { + {47, 45}, + {44, 46}, + }, + { + {48, 46}, + {45, 47}, + }, + { + {49, 47}, + {46, 48}, + }, + { + {50, 48}, + {47, 49}, + }, + { + {51, 49}, + {48, 50}, + }, + { + {52, 50}, + {49, 51}, + }, + { + {53, 51}, + {50, 52}, + }, + { + {54, 52}, + {51, 53}, + }, + { + {55, 53}, + {52, 54}, + }, + { + {56, 54}, + {53, 55}, + }, + { + {57, 55}, + {54, 56}, + }, + { + {58, 56}, + {55, 57}, + }, + { + {59, 57}, + {56, 58}, + }, + { + {60, 58}, + {57, 59}, + }, + { + {61, 59}, + {58, 60}, + }, + { + {62, 60}, + {59, 61}, + }, + { + {63, 61}, + {60, 62}, + }, + { + {64, 62}, + {61, 63}, + }, + { + {65, 63}, + {62, 64}, + }, + { + {66, 64}, + {63, 65}, + }, + { + {67, 65}, + {64, 66}, + }, + { + {68, 66}, + {65, 67}, + }, + { + {69, 67}, + {66, 68}, + }, + { + {70, 68}, + {67, 69}, + }, + { + {71, 69}, + {68, 70}, + }, + { + {72, 70}, + {69, 71}, + }, + { + {73, 71}, + {70, 72}, + }, + { + {74, 72}, + {71, 73}, + }, + { + {75, 73}, + {72, 74}, + }, + { + {76, 74}, + {73, 75}, + }, + { + {77, 75}, + {74, 76}, + }, + { + {78, 76}, + {75, 77}, + }, + { + {79, 77}, + {76, 78}, + }, + { + {80, 78}, + {77, 79}, + }, + { + {81, 79}, + {78, 80}, + }, + { + {82, 80}, + {79, 81}, + }, + { + {83, 81}, + {80, 82}, + }, + { + {84, 82}, + {81, 83}, + }, + { + {85, 83}, + {82, 84}, + }, + { + {86, 84}, + {83, 85}, + }, + { + {87, 85}, + {84, 86}, + }, + { + {88, 86}, + {85, 87}, + }, + { + {89, 87}, + {86, 88}, + }, + { + {90, 88}, + {87, 89}, + }, + { + {91, 89}, + {88, 90}, + }, + { + {92, 90}, + {89, 91}, + }, + { + {93, 91}, + {90, 92}, + }, + { + {94, 92}, + {91, 93}, + }, + { + {95, 93}, + {92, 94}, + }, + { + {96, 94}, + {93, 95}, + }, + { + {97, 95}, + {94, 96}, + }, + { + {98, 96}, + {95, 97}, + }, + { + {99, 97}, + {96, 98}, + }, + { + {100, 98}, + {97, 99}, + }, + { + {101, 99}, + {98, 100}, + }, + { + {102, 100}, + {99, 101}, + }, + { + {103, 101}, + {100, 102}, + }, + { + {104, 102}, + {101, 103}, + }, + { + {105, 103}, + {102, 104}, + }, + { + {106, 104}, + {103, 105}, + }, + { + {107, 105}, + {104, 106}, + }, + { + {108, 106}, + {105, 107}, + }, + { + {109, 107}, + {106, 108}, + }, + { + {110, 108}, + {107, 109}, + }, + { + {111, 109}, + {108, 110}, + }, + { + {112, 110}, + {109, 111}, + }, + { + {113, 111}, + {110, 112}, + }, + { + {114, 112}, + {111, 113}, + }, + { + {115, 113}, + {112, 114}, + }, + { + {116, 114}, + {113, 115}, + }, + { + {117, 115}, + {114, 116}, + }, + { + {118, 116}, + {115, 117}, + }, + { + {119, 117}, + {116, 118}, + }, + { + {120, 118}, + {117, 119}, + }, + { + {121, 119}, + {118, 120}, + }, + { + {122, 120}, + {119, 121}, + }, + { + {123, 121}, + {120, 122}, + }, + { + {124, 122}, + {121, 123}, + }, + { + {125, 123}, + {122, 124}, + }, + { + {126, 124}, + {123, 125}, + }, + { + {127, 125}, + {124, 126}, + }, + { + {128, 126}, + {125, 127}, + }, + { + {129, 127}, + {126, 128}, + }, + { + {130, 128}, + {127, 129}, + }, + { + {131, 129}, + {128, 130}, + }, + { + {132, 130}, + {129, 131}, + }, + { + {133, 131}, + {130, 132}, + }, + { + {134, 132}, + {131, 133}, + }, + { + {135, 133}, + {132, 134}, + }, + { + {136, 134}, + {133, 135}, + }, + { + {137, 135}, + {134, 136}, + }, + { + {138, 136}, + {135, 137}, + }, + { + {139, 137}, + {136, 138}, + }, + { + {140, 138}, + {137, 139}, + }, + { + {141, 139}, + {138, 140}, + }, + { + {142, 140}, + {139, 141}, + }, + { + {143, 141}, + {140, 142}, + }, + { + {144, 142}, + {141, 143}, + }, + { + {145, 143}, + {142, 144}, + }, + { + {146, 144}, + {143, 145}, + }, + { + {147, 145}, + {144, 146}, + }, + { + {148, 146}, + {145, 147}, + }, + { + {149, 147}, + {146, 148}, + }, + { + {150, 148}, + {147, 149}, + }, + { + {151, 149}, + {148, 150}, + }, + { + {152, 150}, + {149, 151}, + }, + { + {153, 151}, + {150, 152}, + }, + { + {154, 152}, + {151, 153}, + }, + { + {155, 153}, + {152, 154}, + }, + { + {156, 154}, + {153, 155}, + }, + { + {157, 155}, + {154, 156}, + }, + { + {158, 156}, + {155, 157}, + }, + { + {159, 157}, + {156, 158}, + }, + { + {160, 158}, + {157, 159}, + }, + { + {161, 159}, + {158, 160}, + }, + { + {162, 160}, + {159, 161}, + }, + { + {163, 161}, + {160, 162}, + }, + { + {164, 162}, + {161, 163}, + }, + { + {165, 163}, + {162, 164}, + }, + { + {166, 164}, + {163, 165}, + }, + { + {167, 165}, + {164, 166}, + }, + { + {168, 166}, + {165, 167}, + }, + { + {169, 167}, + {166, 168}, + }, + { + {170, 168}, + {167, 169}, + }, + { + {171, 169}, + {168, 170}, + }, + { + {172, 170}, + {169, 171}, + }, + { + {173, 171}, + {170, 172}, + }, + { + {174, 172}, + {171, 173}, + }, + { + {175, 173}, + {172, 174}, + }, + { + {176, 174}, + {173, 175}, + }, + { + {177, 175}, + {174, 176}, + }, + { + {178, 176}, + {175, 177}, + }, + { + {179, 177}, + {176, 178}, + }, + { + {180, 178}, + {177, 179}, + }, + { + {181, 179}, + {178, 180}, + }, + { + {182, 180}, + {179, 181}, + }, + { + {183, 181}, + {180, 182}, + }, + { + {184, 182}, + {181, 183}, + }, + { + {185, 183}, + {182, 184}, + }, + { + {186, 184}, + {183, 185}, + }, + { + {187, 185}, + {184, 186}, + }, + { + {188, 186}, + {185, 187}, + }, + { + {189, 187}, + {186, 188}, + }, + { + {190, 188}, + {187, 189}, + }, + { + {191, 189}, + {188, 190}, + }, + { + {192, 190}, + {189, 191}, + }, + { + {193, 191}, + {190, 192}, + }, + { + {194, 192}, + {191, 193}, + }, + { + {195, 193}, + {192, 194}, + }, + { + {196, 194}, + {193, 195}, + }, + { + {197, 195}, + {194, 196}, + }, + { + {198, 196}, + {195, 197}, + }, + { + {199, 197}, + {196, 198}, + }, + { + {200, 198}, + {197, 199}, + }, + { + {201, 199}, + {198, 200}, + }, + { + {202, 200}, + {199, 201}, + }, + { + {203, 201}, + {200, 202}, + }, + { + {204, 202}, + {201, 203}, + }, + { + {205, 203}, + {202, 204}, + }, + { + {206, 204}, + {203, 205}, + }, + { + {207, 205}, + {204, 206}, + }, + { + {208, 206}, + {205, 207}, + }, + { + {209, 207}, + {206, 208}, + }, + { + {210, 208}, + {207, 209}, + }, + { + {211, 209}, + {208, 210}, + }, + { + {212, 210}, + {209, 211}, + }, + { + {213, 211}, + {210, 212}, + }, + { + {214, 212}, + {211, 213}, + }, + { + {215, 213}, + {212, 214}, + }, + { + {216, 214}, + {213, 215}, + }, + { + {217, 215}, + {214, 216}, + }, + { + {218, 216}, + {215, 217}, + }, + { + {219, 217}, + {216, 218}, + }, + { + {220, 218}, + {217, 219}, + }, + { + {221, 219}, + {218, 220}, + }, + { + {222, 220}, + {219, 221}, + }, + { + {223, 221}, + {220, 222}, + }, + { + {224, 222}, + {221, 223}, + }, + { + {225, 223}, + {222, 224}, + }, + { + {226, 224}, + {223, 225}, + }, + { + {227, 225}, + {224, 226}, + }, + { + {228, 226}, + {225, 227}, + }, + { + {229, 227}, + {226, 228}, + }, + { + {230, 228}, + {227, 229}, + }, + { + {231, 229}, + {228, 230}, + }, + { + {232, 230}, + {229, 231}, + }, + { + {233, 231}, + {230, 232}, + }, + { + {234, 232}, + {231, 233}, + }, + { + {235, 233}, + {232, 234}, + }, + { + {236, 234}, + {233, 235}, + }, + { + {237, 235}, + {234, 236}, + }, + { + {238, 236}, + {235, 237}, + }, + { + {239, 237}, + {236, 238}, + }, + { + {240, 238}, + {237, 239}, + }, + { + {241, 239}, + {238, 240}, + }, + { + {242, 240}, + {239, 241}, + }, + { + {243, 241}, + {240, 242}, + }, + { + {244, 242}, + {241, 243}, + }, + { + {245, 243}, + {242, 244}, + }, + { + {246, 244}, + {243, 245}, + }, + { + {247, 245}, + {244, 246}, + }, + { + {248, 246}, + {245, 247}, + }, + { + {249, 247}, + {246, 248}, + }, + { + {250, 248}, + {247, 249}, + }, + { + {251, 249}, + {248, 250}, + }, + { + {252, 250}, + {249, 251}, + }, + { + {253, 251}, + {250, 252}, + }, + { + {254, 252}, + {251, 253}, + }, + { + {255, 253}, + {252, 254}, + }, + { + {255, 254}, + {253, 255}, + }, + { + {255, 255}, + {254, 255}, + }, }; - -static const uint8_t dithersub_rb2x2[256][2][2] = -{ - { - {0, 0}, - {0, 0}, - }, - { - {0, 0}, - {0, 0}, - }, - { - {0, 0}, - {0, 0}, - }, - { - {0, 0}, - {0, 0}, - }, - { - {8, 4}, - {2, 6}, - }, - { - {9, 5}, - {3, 7}, - }, - { - {10, 6}, - {4, 8}, - }, - { - {11, 7}, - {5, 9}, - }, - { - {12, 8}, - {6, 10}, - }, - { - {13, 9}, - {7, 11}, - }, - { - {14, 10}, - {8, 12}, - }, - { - {15, 11}, - {9, 13}, - }, - { - {16, 12}, - {10, 14}, - }, - { - {17, 13}, - {11, 15}, - }, - { - {18, 14}, - {12, 16}, - }, - { - {19, 15}, - {13, 17}, - }, - { - {20, 16}, - {14, 18}, - }, - { - {21, 17}, - {15, 19}, - }, - { - {22, 18}, - {16, 20}, - }, - { - {23, 19}, - {17, 21}, - }, - { - {24, 20}, - {18, 22}, - }, - { - {25, 21}, - {19, 23}, - }, - { - {26, 22}, - {20, 24}, - }, - { - {27, 23}, - {21, 25}, - }, - { - {28, 24}, - {22, 26}, - }, - { - {29, 25}, - {23, 27}, - }, - { - {30, 26}, - {24, 28}, - }, - { - {31, 27}, - {25, 29}, - }, - { - {32, 28}, - {26, 30}, - }, - { - {33, 29}, - {27, 31}, - }, - { - {34, 30}, - {28, 32}, - }, - { - {35, 31}, - {29, 33}, - }, - { - {36, 32}, - {30, 34}, - }, - { - {37, 33}, - {31, 35}, - }, - { - {38, 34}, - {32, 36}, - }, - { - {39, 35}, - {33, 37}, - }, - { - {40, 36}, - {34, 38}, - }, - { - {41, 37}, - {35, 39}, - }, - { - {42, 38}, - {36, 40}, - }, - { - {43, 39}, - {37, 41}, - }, - { - {44, 40}, - {38, 42}, - }, - { - {45, 41}, - {39, 43}, - }, - { - {46, 42}, - {40, 44}, - }, - { - {47, 43}, - {41, 45}, - }, - { - {48, 44}, - {42, 46}, - }, - { - {49, 45}, - {43, 47}, - }, - { - {50, 46}, - {44, 48}, - }, - { - {51, 47}, - {45, 49}, - }, - { - {52, 48}, - {46, 50}, - }, - { - {53, 49}, - {47, 51}, - }, - { - {54, 50}, - {48, 52}, - }, - { - {55, 51}, - {49, 53}, - }, - { - {56, 52}, - {50, 54}, - }, - { - {57, 53}, - {51, 55}, - }, - { - {58, 54}, - {52, 56}, - }, - { - {59, 55}, - {53, 57}, - }, - { - {60, 56}, - {54, 58}, - }, - { - {61, 57}, - {55, 59}, - }, - { - {62, 58}, - {56, 60}, - }, - { - {63, 59}, - {57, 61}, - }, - { - {64, 60}, - {58, 62}, - }, - { - {65, 61}, - {59, 63}, - }, - { - {66, 62}, - {60, 64}, - }, - { - {67, 63}, - {61, 65}, - }, - { - {68, 64}, - {62, 66}, - }, - { - {69, 65}, - {63, 67}, - }, - { - {70, 66}, - {64, 68}, - }, - { - {71, 67}, - {65, 69}, - }, - { - {72, 68}, - {66, 70}, - }, - { - {73, 69}, - {67, 71}, - }, - { - {74, 70}, - {68, 72}, - }, - { - {75, 71}, - {69, 73}, - }, - { - {76, 72}, - {70, 74}, - }, - { - {77, 73}, - {71, 75}, - }, - { - {78, 74}, - {72, 76}, - }, - { - {79, 75}, - {73, 77}, - }, - { - {80, 76}, - {74, 78}, - }, - { - {81, 77}, - {75, 79}, - }, - { - {82, 78}, - {76, 80}, - }, - { - {83, 79}, - {77, 81}, - }, - { - {84, 80}, - {78, 82}, - }, - { - {85, 81}, - {79, 83}, - }, - { - {86, 82}, - {80, 84}, - }, - { - {87, 83}, - {81, 85}, - }, - { - {88, 84}, - {82, 86}, - }, - { - {89, 85}, - {83, 87}, - }, - { - {90, 86}, - {84, 88}, - }, - { - {91, 87}, - {85, 89}, - }, - { - {92, 88}, - {86, 90}, - }, - { - {93, 89}, - {87, 91}, - }, - { - {94, 90}, - {88, 92}, - }, - { - {95, 91}, - {89, 93}, - }, - { - {96, 92}, - {90, 94}, - }, - { - {97, 93}, - {91, 95}, - }, - { - {98, 94}, - {92, 96}, - }, - { - {99, 95}, - {93, 97}, - }, - { - {100, 96}, - {94, 98}, - }, - { - {101, 97}, - {95, 99}, - }, - { - {102, 98}, - {96, 100}, - }, - { - {103, 99}, - {97, 101}, - }, - { - {104, 100}, - {98, 102}, - }, - { - {105, 101}, - {99, 103}, - }, - { - {106, 102}, - {100, 104}, - }, - { - {107, 103}, - {101, 105}, - }, - { - {108, 104}, - {102, 106}, - }, - { - {109, 105}, - {103, 107}, - }, - { - {110, 106}, - {104, 108}, - }, - { - {111, 107}, - {105, 109}, - }, - { - {112, 108}, - {106, 110}, - }, - { - {113, 109}, - {107, 111}, - }, - { - {114, 110}, - {108, 112}, - }, - { - {115, 111}, - {109, 113}, - }, - { - {116, 112}, - {110, 114}, - }, - { - {117, 113}, - {111, 115}, - }, - { - {118, 114}, - {112, 116}, - }, - { - {119, 115}, - {113, 117}, - }, - { - {120, 116}, - {114, 118}, - }, - { - {121, 117}, - {115, 119}, - }, - { - {122, 118}, - {116, 120}, - }, - { - {123, 119}, - {117, 121}, - }, - { - {124, 120}, - {118, 122}, - }, - { - {125, 121}, - {119, 123}, - }, - { - {126, 122}, - {120, 124}, - }, - { - {127, 123}, - {121, 125}, - }, - { - {128, 124}, - {122, 126}, - }, - { - {129, 125}, - {123, 127}, - }, - { - {130, 126}, - {124, 128}, - }, - { - {131, 127}, - {125, 129}, - }, - { - {132, 128}, - {126, 130}, - }, - { - {133, 129}, - {127, 131}, - }, - { - {134, 130}, - {128, 132}, - }, - { - {135, 131}, - {129, 133}, - }, - { - {136, 132}, - {130, 134}, - }, - { - {137, 133}, - {131, 135}, - }, - { - {138, 134}, - {132, 136}, - }, - { - {139, 135}, - {133, 137}, - }, - { - {140, 136}, - {134, 138}, - }, - { - {141, 137}, - {135, 139}, - }, - { - {142, 138}, - {136, 140}, - }, - { - {143, 139}, - {137, 141}, - }, - { - {144, 140}, - {138, 142}, - }, - { - {145, 141}, - {139, 143}, - }, - { - {146, 142}, - {140, 144}, - }, - { - {147, 143}, - {141, 145}, - }, - { - {148, 144}, - {142, 146}, - }, - { - {149, 145}, - {143, 147}, - }, - { - {150, 146}, - {144, 148}, - }, - { - {151, 147}, - {145, 149}, - }, - { - {152, 148}, - {146, 150}, - }, - { - {153, 149}, - {147, 151}, - }, - { - {154, 150}, - {148, 152}, - }, - { - {155, 151}, - {149, 153}, - }, - { - {156, 152}, - {150, 154}, - }, - { - {157, 153}, - {151, 155}, - }, - { - {158, 154}, - {152, 156}, - }, - { - {159, 155}, - {153, 157}, - }, - { - {160, 156}, - {154, 158}, - }, - { - {161, 157}, - {155, 159}, - }, - { - {162, 158}, - {156, 160}, - }, - { - {163, 159}, - {157, 161}, - }, - { - {164, 160}, - {158, 162}, - }, - { - {165, 161}, - {159, 163}, - }, - { - {166, 162}, - {160, 164}, - }, - { - {167, 163}, - {161, 165}, - }, - { - {168, 164}, - {162, 166}, - }, - { - {169, 165}, - {163, 167}, - }, - { - {170, 166}, - {164, 168}, - }, - { - {171, 167}, - {165, 169}, - }, - { - {172, 168}, - {166, 170}, - }, - { - {173, 169}, - {167, 171}, - }, - { - {174, 170}, - {168, 172}, - }, - { - {175, 171}, - {169, 173}, - }, - { - {176, 172}, - {170, 174}, - }, - { - {177, 173}, - {171, 175}, - }, - { - {178, 174}, - {172, 176}, - }, - { - {179, 175}, - {173, 177}, - }, - { - {180, 176}, - {174, 178}, - }, - { - {181, 177}, - {175, 179}, - }, - { - {182, 178}, - {176, 180}, - }, - { - {183, 179}, - {177, 181}, - }, - { - {184, 180}, - {178, 182}, - }, - { - {185, 181}, - {179, 183}, - }, - { - {186, 182}, - {180, 184}, - }, - { - {187, 183}, - {181, 185}, - }, - { - {188, 184}, - {182, 186}, - }, - { - {189, 185}, - {183, 187}, - }, - { - {190, 186}, - {184, 188}, - }, - { - {191, 187}, - {185, 189}, - }, - { - {192, 188}, - {186, 190}, - }, - { - {193, 189}, - {187, 191}, - }, - { - {194, 190}, - {188, 192}, - }, - { - {195, 191}, - {189, 193}, - }, - { - {196, 192}, - {190, 194}, - }, - { - {197, 193}, - {191, 195}, - }, - { - {198, 194}, - {192, 196}, - }, - { - {199, 195}, - {193, 197}, - }, - { - {200, 196}, - {194, 198}, - }, - { - {201, 197}, - {195, 199}, - }, - { - {202, 198}, - {196, 200}, - }, - { - {203, 199}, - {197, 201}, - }, - { - {204, 200}, - {198, 202}, - }, - { - {205, 201}, - {199, 203}, - }, - { - {206, 202}, - {200, 204}, - }, - { - {207, 203}, - {201, 205}, - }, - { - {208, 204}, - {202, 206}, - }, - { - {209, 205}, - {203, 207}, - }, - { - {210, 206}, - {204, 208}, - }, - { - {211, 207}, - {205, 209}, - }, - { - {212, 208}, - {206, 210}, - }, - { - {213, 209}, - {207, 211}, - }, - { - {214, 210}, - {208, 212}, - }, - { - {215, 211}, - {209, 213}, - }, - { - {216, 212}, - {210, 214}, - }, - { - {217, 213}, - {211, 215}, - }, - { - {218, 214}, - {212, 216}, - }, - { - {219, 215}, - {213, 217}, - }, - { - {220, 216}, - {214, 218}, - }, - { - {221, 217}, - {215, 219}, - }, - { - {222, 218}, - {216, 220}, - }, - { - {223, 219}, - {217, 221}, - }, - { - {224, 220}, - {218, 222}, - }, - { - {225, 221}, - {219, 223}, - }, - { - {226, 222}, - {220, 224}, - }, - { - {227, 223}, - {221, 225}, - }, - { - {228, 224}, - {222, 226}, - }, - { - {229, 225}, - {223, 227}, - }, - { - {230, 226}, - {224, 228}, - }, - { - {231, 227}, - {225, 229}, - }, - { - {232, 228}, - {226, 230}, - }, - { - {233, 229}, - {227, 231}, - }, - { - {234, 230}, - {228, 232}, - }, - { - {235, 231}, - {229, 233}, - }, - { - {236, 232}, - {230, 234}, - }, - { - {237, 233}, - {231, 235}, - }, - { - {238, 234}, - {232, 236}, - }, - { - {239, 235}, - {233, 237}, - }, - { - {240, 236}, - {234, 238}, - }, - { - {241, 237}, - {235, 239}, - }, - { - {242, 238}, - {236, 240}, - }, - { - {243, 239}, - {237, 241}, - }, - { - {244, 240}, - {238, 242}, - }, - { - {245, 241}, - {239, 243}, - }, - { - {246, 242}, - {240, 244}, - }, - { - {247, 243}, - {241, 245}, - }, - { - {248, 244}, - {242, 246}, - }, - { - {249, 245}, - {243, 247}, - }, - { - {250, 246}, - {244, 248}, - }, - { - {251, 247}, - {245, 249}, - }, - { - {252, 248}, - {246, 250}, - }, - { - {253, 249}, - {247, 251}, - }, - { - {254, 250}, - {248, 252}, - }, - { - {255, 251}, - {249, 253}, - }, - { - {255, 252}, - {250, 254}, - }, - { - {255, 253}, - {251, 255}, - }, - { - {255, 254}, - {252, 255}, - }, - { - {255, 255}, - {253, 255}, - }, +static const uint8_t dithersub_rb2x2[256][2][2] = { + { + {0, 0}, + {0, 0}, + }, + { + {0, 0}, + {0, 0}, + }, + { + {0, 0}, + {0, 0}, + }, + { + {0, 0}, + {0, 0}, + }, + { + {8, 4}, + {2, 6}, + }, + { + {9, 5}, + {3, 7}, + }, + { + {10, 6}, + {4, 8}, + }, + { + {11, 7}, + {5, 9}, + }, + { + {12, 8}, + {6, 10}, + }, + { + {13, 9}, + {7, 11}, + }, + { + {14, 10}, + {8, 12}, + }, + { + {15, 11}, + {9, 13}, + }, + { + {16, 12}, + {10, 14}, + }, + { + {17, 13}, + {11, 15}, + }, + { + {18, 14}, + {12, 16}, + }, + { + {19, 15}, + {13, 17}, + }, + { + {20, 16}, + {14, 18}, + }, + { + {21, 17}, + {15, 19}, + }, + { + {22, 18}, + {16, 20}, + }, + { + {23, 19}, + {17, 21}, + }, + { + {24, 20}, + {18, 22}, + }, + { + {25, 21}, + {19, 23}, + }, + { + {26, 22}, + {20, 24}, + }, + { + {27, 23}, + {21, 25}, + }, + { + {28, 24}, + {22, 26}, + }, + { + {29, 25}, + {23, 27}, + }, + { + {30, 26}, + {24, 28}, + }, + { + {31, 27}, + {25, 29}, + }, + { + {32, 28}, + {26, 30}, + }, + { + {33, 29}, + {27, 31}, + }, + { + {34, 30}, + {28, 32}, + }, + { + {35, 31}, + {29, 33}, + }, + { + {36, 32}, + {30, 34}, + }, + { + {37, 33}, + {31, 35}, + }, + { + {38, 34}, + {32, 36}, + }, + { + {39, 35}, + {33, 37}, + }, + { + {40, 36}, + {34, 38}, + }, + { + {41, 37}, + {35, 39}, + }, + { + {42, 38}, + {36, 40}, + }, + { + {43, 39}, + {37, 41}, + }, + { + {44, 40}, + {38, 42}, + }, + { + {45, 41}, + {39, 43}, + }, + { + {46, 42}, + {40, 44}, + }, + { + {47, 43}, + {41, 45}, + }, + { + {48, 44}, + {42, 46}, + }, + { + {49, 45}, + {43, 47}, + }, + { + {50, 46}, + {44, 48}, + }, + { + {51, 47}, + {45, 49}, + }, + { + {52, 48}, + {46, 50}, + }, + { + {53, 49}, + {47, 51}, + }, + { + {54, 50}, + {48, 52}, + }, + { + {55, 51}, + {49, 53}, + }, + { + {56, 52}, + {50, 54}, + }, + { + {57, 53}, + {51, 55}, + }, + { + {58, 54}, + {52, 56}, + }, + { + {59, 55}, + {53, 57}, + }, + { + {60, 56}, + {54, 58}, + }, + { + {61, 57}, + {55, 59}, + }, + { + {62, 58}, + {56, 60}, + }, + { + {63, 59}, + {57, 61}, + }, + { + {64, 60}, + {58, 62}, + }, + { + {65, 61}, + {59, 63}, + }, + { + {66, 62}, + {60, 64}, + }, + { + {67, 63}, + {61, 65}, + }, + { + {68, 64}, + {62, 66}, + }, + { + {69, 65}, + {63, 67}, + }, + { + {70, 66}, + {64, 68}, + }, + { + {71, 67}, + {65, 69}, + }, + { + {72, 68}, + {66, 70}, + }, + { + {73, 69}, + {67, 71}, + }, + { + {74, 70}, + {68, 72}, + }, + { + {75, 71}, + {69, 73}, + }, + { + {76, 72}, + {70, 74}, + }, + { + {77, 73}, + {71, 75}, + }, + { + {78, 74}, + {72, 76}, + }, + { + {79, 75}, + {73, 77}, + }, + { + {80, 76}, + {74, 78}, + }, + { + {81, 77}, + {75, 79}, + }, + { + {82, 78}, + {76, 80}, + }, + { + {83, 79}, + {77, 81}, + }, + { + {84, 80}, + {78, 82}, + }, + { + {85, 81}, + {79, 83}, + }, + { + {86, 82}, + {80, 84}, + }, + { + {87, 83}, + {81, 85}, + }, + { + {88, 84}, + {82, 86}, + }, + { + {89, 85}, + {83, 87}, + }, + { + {90, 86}, + {84, 88}, + }, + { + {91, 87}, + {85, 89}, + }, + { + {92, 88}, + {86, 90}, + }, + { + {93, 89}, + {87, 91}, + }, + { + {94, 90}, + {88, 92}, + }, + { + {95, 91}, + {89, 93}, + }, + { + {96, 92}, + {90, 94}, + }, + { + {97, 93}, + {91, 95}, + }, + { + {98, 94}, + {92, 96}, + }, + { + {99, 95}, + {93, 97}, + }, + { + {100, 96}, + {94, 98}, + }, + { + {101, 97}, + {95, 99}, + }, + { + {102, 98}, + {96, 100}, + }, + { + {103, 99}, + {97, 101}, + }, + { + {104, 100}, + {98, 102}, + }, + { + {105, 101}, + {99, 103}, + }, + { + {106, 102}, + {100, 104}, + }, + { + {107, 103}, + {101, 105}, + }, + { + {108, 104}, + {102, 106}, + }, + { + {109, 105}, + {103, 107}, + }, + { + {110, 106}, + {104, 108}, + }, + { + {111, 107}, + {105, 109}, + }, + { + {112, 108}, + {106, 110}, + }, + { + {113, 109}, + {107, 111}, + }, + { + {114, 110}, + {108, 112}, + }, + { + {115, 111}, + {109, 113}, + }, + { + {116, 112}, + {110, 114}, + }, + { + {117, 113}, + {111, 115}, + }, + { + {118, 114}, + {112, 116}, + }, + { + {119, 115}, + {113, 117}, + }, + { + {120, 116}, + {114, 118}, + }, + { + {121, 117}, + {115, 119}, + }, + { + {122, 118}, + {116, 120}, + }, + { + {123, 119}, + {117, 121}, + }, + { + {124, 120}, + {118, 122}, + }, + { + {125, 121}, + {119, 123}, + }, + { + {126, 122}, + {120, 124}, + }, + { + {127, 123}, + {121, 125}, + }, + { + {128, 124}, + {122, 126}, + }, + { + {129, 125}, + {123, 127}, + }, + { + {130, 126}, + {124, 128}, + }, + { + {131, 127}, + {125, 129}, + }, + { + {132, 128}, + {126, 130}, + }, + { + {133, 129}, + {127, 131}, + }, + { + {134, 130}, + {128, 132}, + }, + { + {135, 131}, + {129, 133}, + }, + { + {136, 132}, + {130, 134}, + }, + { + {137, 133}, + {131, 135}, + }, + { + {138, 134}, + {132, 136}, + }, + { + {139, 135}, + {133, 137}, + }, + { + {140, 136}, + {134, 138}, + }, + { + {141, 137}, + {135, 139}, + }, + { + {142, 138}, + {136, 140}, + }, + { + {143, 139}, + {137, 141}, + }, + { + {144, 140}, + {138, 142}, + }, + { + {145, 141}, + {139, 143}, + }, + { + {146, 142}, + {140, 144}, + }, + { + {147, 143}, + {141, 145}, + }, + { + {148, 144}, + {142, 146}, + }, + { + {149, 145}, + {143, 147}, + }, + { + {150, 146}, + {144, 148}, + }, + { + {151, 147}, + {145, 149}, + }, + { + {152, 148}, + {146, 150}, + }, + { + {153, 149}, + {147, 151}, + }, + { + {154, 150}, + {148, 152}, + }, + { + {155, 151}, + {149, 153}, + }, + { + {156, 152}, + {150, 154}, + }, + { + {157, 153}, + {151, 155}, + }, + { + {158, 154}, + {152, 156}, + }, + { + {159, 155}, + {153, 157}, + }, + { + {160, 156}, + {154, 158}, + }, + { + {161, 157}, + {155, 159}, + }, + { + {162, 158}, + {156, 160}, + }, + { + {163, 159}, + {157, 161}, + }, + { + {164, 160}, + {158, 162}, + }, + { + {165, 161}, + {159, 163}, + }, + { + {166, 162}, + {160, 164}, + }, + { + {167, 163}, + {161, 165}, + }, + { + {168, 164}, + {162, 166}, + }, + { + {169, 165}, + {163, 167}, + }, + { + {170, 166}, + {164, 168}, + }, + { + {171, 167}, + {165, 169}, + }, + { + {172, 168}, + {166, 170}, + }, + { + {173, 169}, + {167, 171}, + }, + { + {174, 170}, + {168, 172}, + }, + { + {175, 171}, + {169, 173}, + }, + { + {176, 172}, + {170, 174}, + }, + { + {177, 173}, + {171, 175}, + }, + { + {178, 174}, + {172, 176}, + }, + { + {179, 175}, + {173, 177}, + }, + { + {180, 176}, + {174, 178}, + }, + { + {181, 177}, + {175, 179}, + }, + { + {182, 178}, + {176, 180}, + }, + { + {183, 179}, + {177, 181}, + }, + { + {184, 180}, + {178, 182}, + }, + { + {185, 181}, + {179, 183}, + }, + { + {186, 182}, + {180, 184}, + }, + { + {187, 183}, + {181, 185}, + }, + { + {188, 184}, + {182, 186}, + }, + { + {189, 185}, + {183, 187}, + }, + { + {190, 186}, + {184, 188}, + }, + { + {191, 187}, + {185, 189}, + }, + { + {192, 188}, + {186, 190}, + }, + { + {193, 189}, + {187, 191}, + }, + { + {194, 190}, + {188, 192}, + }, + { + {195, 191}, + {189, 193}, + }, + { + {196, 192}, + {190, 194}, + }, + { + {197, 193}, + {191, 195}, + }, + { + {198, 194}, + {192, 196}, + }, + { + {199, 195}, + {193, 197}, + }, + { + {200, 196}, + {194, 198}, + }, + { + {201, 197}, + {195, 199}, + }, + { + {202, 198}, + {196, 200}, + }, + { + {203, 199}, + {197, 201}, + }, + { + {204, 200}, + {198, 202}, + }, + { + {205, 201}, + {199, 203}, + }, + { + {206, 202}, + {200, 204}, + }, + { + {207, 203}, + {201, 205}, + }, + { + {208, 204}, + {202, 206}, + }, + { + {209, 205}, + {203, 207}, + }, + { + {210, 206}, + {204, 208}, + }, + { + {211, 207}, + {205, 209}, + }, + { + {212, 208}, + {206, 210}, + }, + { + {213, 209}, + {207, 211}, + }, + { + {214, 210}, + {208, 212}, + }, + { + {215, 211}, + {209, 213}, + }, + { + {216, 212}, + {210, 214}, + }, + { + {217, 213}, + {211, 215}, + }, + { + {218, 214}, + {212, 216}, + }, + { + {219, 215}, + {213, 217}, + }, + { + {220, 216}, + {214, 218}, + }, + { + {221, 217}, + {215, 219}, + }, + { + {222, 218}, + {216, 220}, + }, + { + {223, 219}, + {217, 221}, + }, + { + {224, 220}, + {218, 222}, + }, + { + {225, 221}, + {219, 223}, + }, + { + {226, 222}, + {220, 224}, + }, + { + {227, 223}, + {221, 225}, + }, + { + {228, 224}, + {222, 226}, + }, + { + {229, 225}, + {223, 227}, + }, + { + {230, 226}, + {224, 228}, + }, + { + {231, 227}, + {225, 229}, + }, + { + {232, 228}, + {226, 230}, + }, + { + {233, 229}, + {227, 231}, + }, + { + {234, 230}, + {228, 232}, + }, + { + {235, 231}, + {229, 233}, + }, + { + {236, 232}, + {230, 234}, + }, + { + {237, 233}, + {231, 235}, + }, + { + {238, 234}, + {232, 236}, + }, + { + {239, 235}, + {233, 237}, + }, + { + {240, 236}, + {234, 238}, + }, + { + {241, 237}, + {235, 239}, + }, + { + {242, 238}, + {236, 240}, + }, + { + {243, 239}, + {237, 241}, + }, + { + {244, 240}, + {238, 242}, + }, + { + {245, 241}, + {239, 243}, + }, + { + {246, 242}, + {240, 244}, + }, + { + {247, 243}, + {241, 245}, + }, + { + {248, 244}, + {242, 246}, + }, + { + {249, 245}, + {243, 247}, + }, + { + {250, 246}, + {244, 248}, + }, + { + {251, 247}, + {245, 249}, + }, + { + {252, 248}, + {246, 250}, + }, + { + {253, 249}, + {247, 251}, + }, + { + {254, 250}, + {248, 252}, + }, + { + {255, 251}, + {249, 253}, + }, + { + {255, 252}, + {250, 254}, + }, + { + {255, 253}, + {251, 255}, + }, + { + {255, 254}, + {252, 255}, + }, + { + {255, 255}, + {253, 255}, + }, }; - - #endif /* _VID_VOODOO_DITHER_H_ */ diff --git a/includes/private/video/vid_voodoo_fb.h b/includes/private/video/vid_voodoo_fb.h index c1c8b4fd..82bbd2b7 100644 --- a/includes/private/video/vid_voodoo_fb.h +++ b/includes/private/video/vid_voodoo_fb.h @@ -5,5 +5,4 @@ uint32_t voodoo_fb_readl(uint32_t addr, void *p); void voodoo_fb_writew(uint32_t addr, uint16_t val, void *p); void voodoo_fb_writel(uint32_t addr, uint32_t val, void *p); - #endif /* _VID_VOODOO_FB_H_ */ diff --git a/includes/private/video/vid_voodoo_fifo.h b/includes/private/video/vid_voodoo_fifo.h index c2f1601e..dc2c6142 100644 --- a/includes/private/video/vid_voodoo_fifo.h +++ b/includes/private/video/vid_voodoo_fifo.h @@ -9,5 +9,4 @@ void voodoo_wake_fifo_threads(voodoo_set_t *set, voodoo_t *voodoo); void voodoo_wait_for_swap_complete(voodoo_t *voodoo); void voodoo_fifo_thread(void *param); - #endif /* _VID_VOODOO_FIFO_H_ */ diff --git a/includes/private/video/vid_voodoo_reg.h b/includes/private/video/vid_voodoo_reg.h index 2c6a5aad..815901af 100644 --- a/includes/private/video/vid_voodoo_reg.h +++ b/includes/private/video/vid_voodoo_reg.h @@ -2,5 +2,4 @@ #define _VID_VOODOO_REG_H_ void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p); - #endif /* _VID_VOODOO_REG_H_ */ diff --git a/includes/private/video/vid_voodoo_regs.h b/includes/private/video/vid_voodoo_regs.h index 45405c6a..62699201 100644 --- a/includes/private/video/vid_voodoo_regs.h +++ b/includes/private/video/vid_voodoo_regs.h @@ -1,7 +1,6 @@ #ifndef _VID_VOODOO_REGS_H_ #define _VID_VOODOO_REGS_H_ -enum -{ +enum { SST_status = 0x000, SST_intrCtrl = 0x004, @@ -12,32 +11,32 @@ enum SST_vertexCx = 0x018, SST_vertexCy = 0x01c, - SST_startR = 0x0020, - SST_startG = 0x0024, - SST_startB = 0x0028, - SST_startZ = 0x002c, - SST_startA = 0x0030, - SST_startS = 0x0034, - SST_startT = 0x0038, - SST_startW = 0x003c, + SST_startR = 0x0020, + SST_startG = 0x0024, + SST_startB = 0x0028, + SST_startZ = 0x002c, + SST_startA = 0x0030, + SST_startS = 0x0034, + SST_startT = 0x0038, + SST_startW = 0x003c, - SST_dRdX = 0x0040, - SST_dGdX = 0x0044, - SST_dBdX = 0x0048, - SST_dZdX = 0x004c, - SST_dAdX = 0x0050, - SST_dSdX = 0x0054, - SST_dTdX = 0x0058, - SST_dWdX = 0x005c, + SST_dRdX = 0x0040, + SST_dGdX = 0x0044, + SST_dBdX = 0x0048, + SST_dZdX = 0x004c, + SST_dAdX = 0x0050, + SST_dSdX = 0x0054, + SST_dTdX = 0x0058, + SST_dWdX = 0x005c, - SST_dRdY = 0x0060, - SST_dGdY = 0x0064, - SST_dBdY = 0x0068, - SST_dZdY = 0x006c, - SST_dAdY = 0x0070, - SST_dSdY = 0x0074, - SST_dTdY = 0x0078, - SST_dWdY = 0x007c, + SST_dRdY = 0x0060, + SST_dGdY = 0x0064, + SST_dBdY = 0x0068, + SST_dZdY = 0x006c, + SST_dAdY = 0x0070, + SST_dSdY = 0x0074, + SST_dTdY = 0x0078, + SST_dWdY = 0x007c, SST_triangleCMD = 0x0080, @@ -48,32 +47,32 @@ enum SST_fvertexCx = 0x098, SST_fvertexCy = 0x09c, - SST_fstartR = 0x00a0, - SST_fstartG = 0x00a4, - SST_fstartB = 0x00a8, - SST_fstartZ = 0x00ac, - SST_fstartA = 0x00b0, - SST_fstartS = 0x00b4, - SST_fstartT = 0x00b8, - SST_fstartW = 0x00bc, + SST_fstartR = 0x00a0, + SST_fstartG = 0x00a4, + SST_fstartB = 0x00a8, + SST_fstartZ = 0x00ac, + SST_fstartA = 0x00b0, + SST_fstartS = 0x00b4, + SST_fstartT = 0x00b8, + SST_fstartW = 0x00bc, - SST_fdRdX = 0x00c0, - SST_fdGdX = 0x00c4, - SST_fdBdX = 0x00c8, - SST_fdZdX = 0x00cc, - SST_fdAdX = 0x00d0, - SST_fdSdX = 0x00d4, - SST_fdTdX = 0x00d8, - SST_fdWdX = 0x00dc, + SST_fdRdX = 0x00c0, + SST_fdGdX = 0x00c4, + SST_fdBdX = 0x00c8, + SST_fdZdX = 0x00cc, + SST_fdAdX = 0x00d0, + SST_fdSdX = 0x00d4, + SST_fdTdX = 0x00d8, + SST_fdWdX = 0x00dc, - SST_fdRdY = 0x00e0, - SST_fdGdY = 0x00e4, - SST_fdBdY = 0x00e8, - SST_fdZdY = 0x00ec, - SST_fdAdY = 0x00f0, - SST_fdSdY = 0x00f4, - SST_fdTdY = 0x00f8, - SST_fdWdY = 0x00fc, + SST_fdRdY = 0x00e0, + SST_fdGdY = 0x00e4, + SST_fdBdY = 0x00e8, + SST_fdZdY = 0x00ec, + SST_fdAdY = 0x00f0, + SST_fdSdY = 0x00f4, + SST_fdTdY = 0x00f8, + SST_fdWdY = 0x00fc, SST_ftriangleCMD = 0x0100, @@ -146,7 +145,7 @@ enum SST_cmdFifoAMax = 0x1f0, SST_cmdFifoDepth = 0x1f4, SST_cmdFifoHoles = 0x1f8, - + SST_colBufferAddr = 0x1ec, /*Banshee*/ SST_colBufferStride = 0x1f0, /*Banshee*/ SST_auxBufferAddr = 0x1f4, /*Banshee*/ @@ -168,32 +167,32 @@ enum SST_clutData = 0x228, SST_dacData = 0x22c, - SST_scrFilter = 0x230, + SST_scrFilter = 0x230, SST_hvRetrace = 0x240, SST_fbiInit5 = 0x244, SST_fbiInit6 = 0x248, SST_fbiInit7 = 0x24c, - - SST_swapPending = 0x24c, /*Banshee*/ + + SST_swapPending = 0x24c, /*Banshee*/ SST_leftOverlayBuf = 0x250, /*Banshee*/ - + SST_sSetupMode = 0x260, - SST_sVx = 0x264, - SST_sVy = 0x268, - SST_sARGB = 0x26c, - SST_sRed = 0x270, + SST_sVx = 0x264, + SST_sVy = 0x268, + SST_sARGB = 0x26c, + SST_sRed = 0x270, SST_sGreen = 0x274, - SST_sBlue = 0x278, + SST_sBlue = 0x278, SST_sAlpha = 0x27c, - SST_sVz = 0x280, - SST_sWb = 0x284, - SST_sW0 = 0x288, - SST_sS0 = 0x28c, - SST_sT0 = 0x290, - SST_sW1 = 0x294, - SST_sS1 = 0x298, - SST_sT1 = 0x29c, + SST_sVz = 0x280, + SST_sWb = 0x284, + SST_sW0 = 0x288, + SST_sS0 = 0x28c, + SST_sT0 = 0x290, + SST_sW1 = 0x294, + SST_sS1 = 0x298, + SST_sT1 = 0x29c, SST_sDrawTriCMD = 0x2a0, SST_sBeginTriCMD = 0x2a4, @@ -260,32 +259,32 @@ enum SST_remap_vertexCx = 0x018 | 0x400, SST_remap_vertexCy = 0x01c | 0x400, - SST_remap_startR = 0x0020 | 0x400, - SST_remap_startG = 0x002c | 0x400, - SST_remap_startB = 0x0038 | 0x400, - SST_remap_startZ = 0x0044 | 0x400, - SST_remap_startA = 0x0050 | 0x400, - SST_remap_startS = 0x005c | 0x400, - SST_remap_startT = 0x0068 | 0x400, - SST_remap_startW = 0x0074 | 0x400, + SST_remap_startR = 0x0020 | 0x400, + SST_remap_startG = 0x002c | 0x400, + SST_remap_startB = 0x0038 | 0x400, + SST_remap_startZ = 0x0044 | 0x400, + SST_remap_startA = 0x0050 | 0x400, + SST_remap_startS = 0x005c | 0x400, + SST_remap_startT = 0x0068 | 0x400, + SST_remap_startW = 0x0074 | 0x400, - SST_remap_dRdX = 0x0024 | 0x400, - SST_remap_dGdX = 0x0030 | 0x400, - SST_remap_dBdX = 0x003c | 0x400, - SST_remap_dZdX = 0x0048 | 0x400, - SST_remap_dAdX = 0x0054 | 0x400, - SST_remap_dSdX = 0x0060 | 0x400, - SST_remap_dTdX = 0x006c | 0x400, - SST_remap_dWdX = 0x0078 | 0x400, + SST_remap_dRdX = 0x0024 | 0x400, + SST_remap_dGdX = 0x0030 | 0x400, + SST_remap_dBdX = 0x003c | 0x400, + SST_remap_dZdX = 0x0048 | 0x400, + SST_remap_dAdX = 0x0054 | 0x400, + SST_remap_dSdX = 0x0060 | 0x400, + SST_remap_dTdX = 0x006c | 0x400, + SST_remap_dWdX = 0x0078 | 0x400, - SST_remap_dRdY = 0x0028 | 0x400, - SST_remap_dGdY = 0x0034 | 0x400, - SST_remap_dBdY = 0x0040 | 0x400, - SST_remap_dZdY = 0x004c | 0x400, - SST_remap_dAdY = 0x0058 | 0x400, - SST_remap_dSdY = 0x0064 | 0x400, - SST_remap_dTdY = 0x0070 | 0x400, - SST_remap_dWdY = 0x007c | 0x400, + SST_remap_dRdY = 0x0028 | 0x400, + SST_remap_dGdY = 0x0034 | 0x400, + SST_remap_dBdY = 0x0040 | 0x400, + SST_remap_dZdY = 0x004c | 0x400, + SST_remap_dAdY = 0x0058 | 0x400, + SST_remap_dSdY = 0x0064 | 0x400, + SST_remap_dTdY = 0x0070 | 0x400, + SST_remap_dWdY = 0x007c | 0x400, SST_remap_triangleCMD = 0x0080 | 0x400, @@ -296,51 +295,39 @@ enum SST_remap_fvertexCx = 0x098 | 0x400, SST_remap_fvertexCy = 0x09c | 0x400, - SST_remap_fstartR = 0x00a0 | 0x400, - SST_remap_fstartG = 0x00ac | 0x400, - SST_remap_fstartB = 0x00b8 | 0x400, - SST_remap_fstartZ = 0x00c4 | 0x400, - SST_remap_fstartA = 0x00d0 | 0x400, - SST_remap_fstartS = 0x00dc | 0x400, - SST_remap_fstartT = 0x00e8 | 0x400, - SST_remap_fstartW = 0x00f4 | 0x400, + SST_remap_fstartR = 0x00a0 | 0x400, + SST_remap_fstartG = 0x00ac | 0x400, + SST_remap_fstartB = 0x00b8 | 0x400, + SST_remap_fstartZ = 0x00c4 | 0x400, + SST_remap_fstartA = 0x00d0 | 0x400, + SST_remap_fstartS = 0x00dc | 0x400, + SST_remap_fstartT = 0x00e8 | 0x400, + SST_remap_fstartW = 0x00f4 | 0x400, - SST_remap_fdRdX = 0x00a4 | 0x400, - SST_remap_fdGdX = 0x00b0 | 0x400, - SST_remap_fdBdX = 0x00bc | 0x400, - SST_remap_fdZdX = 0x00c8 | 0x400, - SST_remap_fdAdX = 0x00d4 | 0x400, - SST_remap_fdSdX = 0x00e0 | 0x400, - SST_remap_fdTdX = 0x00ec | 0x400, - SST_remap_fdWdX = 0x00f8 | 0x400, + SST_remap_fdRdX = 0x00a4 | 0x400, + SST_remap_fdGdX = 0x00b0 | 0x400, + SST_remap_fdBdX = 0x00bc | 0x400, + SST_remap_fdZdX = 0x00c8 | 0x400, + SST_remap_fdAdX = 0x00d4 | 0x400, + SST_remap_fdSdX = 0x00e0 | 0x400, + SST_remap_fdTdX = 0x00ec | 0x400, + SST_remap_fdWdX = 0x00f8 | 0x400, - SST_remap_fdRdY = 0x00a8 | 0x400, - SST_remap_fdGdY = 0x00b4 | 0x400, - SST_remap_fdBdY = 0x00c0 | 0x400, - SST_remap_fdZdY = 0x00cc | 0x400, - SST_remap_fdAdY = 0x00d8 | 0x400, - SST_remap_fdSdY = 0x00e4 | 0x400, - SST_remap_fdTdY = 0x00f0 | 0x400, - SST_remap_fdWdY = 0x00fc | 0x400, + SST_remap_fdRdY = 0x00a8 | 0x400, + SST_remap_fdGdY = 0x00b4 | 0x400, + SST_remap_fdBdY = 0x00c0 | 0x400, + SST_remap_fdZdY = 0x00cc | 0x400, + SST_remap_fdAdY = 0x00d8 | 0x400, + SST_remap_fdSdY = 0x00e4 | 0x400, + SST_remap_fdTdY = 0x00f0 | 0x400, + SST_remap_fdWdY = 0x00fc | 0x400, }; -enum -{ - LFB_WRITE_FRONT = 0x0000, - LFB_WRITE_BACK = 0x0010, - LFB_WRITE_MASK = 0x0030 -}; +enum { LFB_WRITE_FRONT = 0x0000, LFB_WRITE_BACK = 0x0010, LFB_WRITE_MASK = 0x0030 }; -enum -{ - LFB_READ_FRONT = 0x0000, - LFB_READ_BACK = 0x0040, - LFB_READ_AUX = 0x0080, - LFB_READ_MASK = 0x00c0 -}; +enum { LFB_READ_FRONT = 0x0000, LFB_READ_BACK = 0x0040, LFB_READ_AUX = 0x0080, LFB_READ_MASK = 0x00c0 }; -enum -{ +enum { LFB_FORMAT_RGB565 = 0, LFB_FORMAT_RGB555 = 1, LFB_FORMAT_ARGB1555 = 2, @@ -349,37 +336,31 @@ enum LFB_FORMAT_MASK = 15 }; -enum -{ - LFB_WRITE_COLOUR = 1, - LFB_WRITE_DEPTH = 2 -}; +enum { LFB_WRITE_COLOUR = 1, LFB_WRITE_DEPTH = 2 }; -enum -{ +enum { FBZ_CHROMAKEY = (1 << 1), FBZ_W_BUFFER = (1 << 3), FBZ_DEPTH_ENABLE = (1 << 4), - FBZ_DITHER = (1 << 8), - FBZ_RGB_WMASK = (1 << 9), + FBZ_DITHER = (1 << 8), + FBZ_RGB_WMASK = (1 << 9), FBZ_DEPTH_WMASK = (1 << 10), - FBZ_DITHER_2x2 = (1 << 11), + FBZ_DITHER_2x2 = (1 << 11), FBZ_DRAW_FRONT = 0x0000, - FBZ_DRAW_BACK = 0x4000, - FBZ_DRAW_MASK = 0xc000, + FBZ_DRAW_BACK = 0x4000, + FBZ_DRAW_MASK = 0xc000, FBZ_DEPTH_BIAS = (1 << 16), - FBZ_DITHER_SUB = (1 << 19), + FBZ_DITHER_SUB = (1 << 19), FBZ_DEPTH_SOURCE = (1 << 20), FBZ_PARAM_ADJUST = (1 << 26) }; -enum -{ +enum { TEX_RGB332 = 0x0, TEX_Y4I2Q2 = 0x1, TEX_A8 = 0x2, @@ -396,139 +377,78 @@ enum TEX_APAL88 = 0xe }; -enum -{ +enum { TEXTUREMODE_NCC_SEL = (1 << 5), TEXTUREMODE_TCLAMPS = (1 << 6), TEXTUREMODE_TCLAMPT = (1 << 7), TEXTUREMODE_TRILINEAR = (1 << 30) }; -enum -{ - FBIINIT0_VGA_PASS = 1, - FBIINIT0_GRAPHICS_RESET = (1 << 1) -}; +enum { FBIINIT0_VGA_PASS = 1, FBIINIT0_GRAPHICS_RESET = (1 << 1) }; -enum -{ +enum { FBIINIT1_MULTI_SST = (1 << 2), /*Voodoo Graphics only*/ FBIINIT1_VIDEO_RESET = (1 << 8), FBIINIT1_SLI_ENABLE = (1 << 23) }; -enum -{ - FBIINIT2_SWAP_ALGORITHM_MASK = (3 << 9) -}; +enum { FBIINIT2_SWAP_ALGORITHM_MASK = (3 << 9) }; -enum -{ - FBIINIT2_SWAP_ALGORITHM_DAC_VSYNC = (0 << 9), - FBIINIT2_SWAP_ALGORITHM_DAC_DATA = (1 << 9), +enum { + FBIINIT2_SWAP_ALGORITHM_DAC_VSYNC = (0 << 9), + FBIINIT2_SWAP_ALGORITHM_DAC_DATA = (1 << 9), FBIINIT2_SWAP_ALGORITHM_PCI_FIFO_STALL = (2 << 9), - FBIINIT2_SWAP_ALGORITHM_SLI_SYNC = (3 << 9) + FBIINIT2_SWAP_ALGORITHM_SLI_SYNC = (3 << 9) }; -enum -{ - FBIINIT3_REMAP = 1 -}; +enum { FBIINIT3_REMAP = 1 }; -enum -{ - FBIINIT5_MULTI_CVG = (1 << 14) -}; +enum { FBIINIT5_MULTI_CVG = (1 << 14) }; -enum -{ - FBIINIT7_CMDFIFO_ENABLE = (1 << 8) -}; +enum { FBIINIT7_CMDFIFO_ENABLE = (1 << 8) }; -enum -{ - CC_LOCALSELECT_ITER_RGB = 0, - CC_LOCALSELECT_TEX = 1, - CC_LOCALSELECT_COLOR1 = 2, - CC_LOCALSELECT_LFB = 3 -}; +enum { CC_LOCALSELECT_ITER_RGB = 0, CC_LOCALSELECT_TEX = 1, CC_LOCALSELECT_COLOR1 = 2, CC_LOCALSELECT_LFB = 3 }; -enum -{ - CCA_LOCALSELECT_ITER_A = 0, - CCA_LOCALSELECT_COLOR0 = 1, - CCA_LOCALSELECT_ITER_Z = 2 -}; +enum { CCA_LOCALSELECT_ITER_A = 0, CCA_LOCALSELECT_COLOR0 = 1, CCA_LOCALSELECT_ITER_Z = 2 }; -enum -{ - C_SEL_ITER_RGB = 0, - C_SEL_TEX = 1, - C_SEL_COLOR1 = 2, - C_SEL_LFB = 3 -}; +enum { C_SEL_ITER_RGB = 0, C_SEL_TEX = 1, C_SEL_COLOR1 = 2, C_SEL_LFB = 3 }; -enum -{ - A_SEL_ITER_A = 0, - A_SEL_TEX = 1, - A_SEL_COLOR1 = 2, - A_SEL_LFB = 3 -}; +enum { A_SEL_ITER_A = 0, A_SEL_TEX = 1, A_SEL_COLOR1 = 2, A_SEL_LFB = 3 }; -enum -{ - CC_MSELECT_ZERO = 0, +enum { + CC_MSELECT_ZERO = 0, CC_MSELECT_CLOCAL = 1, CC_MSELECT_AOTHER = 2, CC_MSELECT_ALOCAL = 3, - CC_MSELECT_TEX = 4, + CC_MSELECT_TEX = 4, CC_MSELECT_TEXRGB = 5 }; -enum -{ - CCA_MSELECT_ZERO = 0, - CCA_MSELECT_ALOCAL = 1, - CCA_MSELECT_AOTHER = 2, - CCA_MSELECT_ALOCAL2 = 3, - CCA_MSELECT_TEX = 4 -}; +enum { CCA_MSELECT_ZERO = 0, CCA_MSELECT_ALOCAL = 1, CCA_MSELECT_AOTHER = 2, CCA_MSELECT_ALOCAL2 = 3, CCA_MSELECT_TEX = 4 }; -enum -{ - TC_MSELECT_ZERO = 0, - TC_MSELECT_CLOCAL = 1, - TC_MSELECT_AOTHER = 2, - TC_MSELECT_ALOCAL = 3, - TC_MSELECT_DETAIL = 4, +enum { + TC_MSELECT_ZERO = 0, + TC_MSELECT_CLOCAL = 1, + TC_MSELECT_AOTHER = 2, + TC_MSELECT_ALOCAL = 3, + TC_MSELECT_DETAIL = 4, TC_MSELECT_LOD_FRAC = 5 }; -enum -{ - TCA_MSELECT_ZERO = 0, - TCA_MSELECT_CLOCAL = 1, - TCA_MSELECT_AOTHER = 2, - TCA_MSELECT_ALOCAL = 3, - TCA_MSELECT_DETAIL = 4, +enum { + TCA_MSELECT_ZERO = 0, + TCA_MSELECT_CLOCAL = 1, + TCA_MSELECT_AOTHER = 2, + TCA_MSELECT_ALOCAL = 3, + TCA_MSELECT_DETAIL = 4, TCA_MSELECT_LOD_FRAC = 5 }; -enum -{ - CC_ADD_CLOCAL = 1, - CC_ADD_ALOCAL = 2 -}; +enum { CC_ADD_CLOCAL = 1, CC_ADD_ALOCAL = 2 }; -enum -{ - CCA_ADD_CLOCAL = 1, - CCA_ADD_ALOCAL = 2 -}; +enum { CCA_ADD_CLOCAL = 1, CCA_ADD_ALOCAL = 2 }; -enum -{ +enum { AFUNC_AZERO = 0x0, AFUNC_ASRC_ALPHA = 0x1, AFUNC_A_COLOR = 0x2, @@ -540,14 +460,10 @@ enum AFUNC_ASATURATE = 0xf }; -enum -{ - AFUNC_ACOLORBEFOREFOG = 0xf -}; +enum { AFUNC_ACOLORBEFOREFOG = 0xf }; -enum -{ - AFUNC_NEVER = 0, +enum { + AFUNC_NEVER = 0, AFUNC_LESSTHAN = 1, AFUNC_EQUAL = 2, AFUNC_LESSTHANEQUAL = 3, @@ -557,9 +473,8 @@ enum AFUNC_ALWAYS = 7 }; -enum -{ - DEPTHOP_NEVER = 0, +enum { + DEPTHOP_NEVER = 0, DEPTHOP_LESSTHAN = 1, DEPTHOP_EQUAL = 2, DEPTHOP_LESSTHANEQUAL = 3, @@ -569,59 +484,32 @@ enum DEPTHOP_ALWAYS = 7 }; -enum -{ - FOG_ENABLE = 0x01, - FOG_ADD = 0x02, - FOG_MULT = 0x04, - FOG_ALPHA = 0x08, - FOG_Z = 0x10, - FOG_W = 0x18, - FOG_CONSTANT = 0x20 -}; +enum { FOG_ENABLE = 0x01, FOG_ADD = 0x02, FOG_MULT = 0x04, FOG_ALPHA = 0x08, FOG_Z = 0x10, FOG_W = 0x18, FOG_CONSTANT = 0x20 }; -enum -{ - LOD_ODD = (1 << 18), - LOD_SPLIT = (1 << 19), - LOD_S_IS_WIDER = (1 << 20), +enum { + LOD_ODD = (1 << 18), + LOD_SPLIT = (1 << 19), + LOD_S_IS_WIDER = (1 << 20), LOD_TMULTIBASEADDR = (1 << 24), - LOD_TMIRROR_S = (1 << 28), - LOD_TMIRROR_T = (1 << 29) -}; -enum -{ - CMD_INVALID = 0, - CMD_DRAWTRIANGLE, - CMD_FASTFILL, - CMD_SWAPBUF + LOD_TMIRROR_S = (1 << 28), + LOD_TMIRROR_T = (1 << 29) }; +enum { CMD_INVALID = 0, CMD_DRAWTRIANGLE, CMD_FASTFILL, CMD_SWAPBUF }; -enum -{ - FBZCP_TEXTURE_ENABLED = (1 << 27) -}; +enum { FBZCP_TEXTURE_ENABLED = (1 << 27) }; -enum -{ - BLTCMD_SRC_TILED = (1 << 14), - BLTCMD_DST_TILED = (1 << 15) -}; +enum { BLTCMD_SRC_TILED = (1 << 14), BLTCMD_DST_TILED = (1 << 15) }; -enum -{ - INITENABLE_SLI_MASTER_SLAVE = (1 << 11) -}; +enum { INITENABLE_SLI_MASTER_SLAVE = (1 << 11) }; -enum -{ - SETUPMODE_RGB = (1 << 0), +enum { + SETUPMODE_RGB = (1 << 0), SETUPMODE_ALPHA = (1 << 1), - SETUPMODE_Z = (1 << 2), - SETUPMODE_Wb = (1 << 3), - SETUPMODE_W0 = (1 << 4), + SETUPMODE_Z = (1 << 2), + SETUPMODE_Wb = (1 << 3), + SETUPMODE_W0 = (1 << 4), SETUPMODE_S0_T0 = (1 << 5), - SETUPMODE_W1 = (1 << 6), + SETUPMODE_W1 = (1 << 6), SETUPMODE_S1_T1 = (1 << 7), SETUPMODE_STRIP_MODE = (1 << 16), @@ -634,66 +522,62 @@ enum #define TEXTUREMODE_PASSTHROUGH 0 #define TEXTUREMODE_LOCAL_MASK 0x00643000 -#define TEXTUREMODE_LOCAL 0x00241000 - +#define TEXTUREMODE_LOCAL 0x00241000 #define SLI_ENABLED (voodoo->fbiInit1 & FBIINIT1_SLI_ENABLE) #define TRIPLE_BUFFER ((voodoo->fbiInit2 & 0x10) || (voodoo->fbiInit5 & 0x600) == 0x400) - -#define _rgb_sel ( params->fbzColorPath & 3) -#define a_sel ( (params->fbzColorPath >> 2) & 3) -#define cc_localselect ( params->fbzColorPath & (1 << 4)) -#define cca_localselect ( (params->fbzColorPath >> 5) & 3) -#define cc_localselect_override ( params->fbzColorPath & (1 << 7)) -#define cc_zero_other ( params->fbzColorPath & (1 << 8)) -#define cc_sub_clocal ( params->fbzColorPath & (1 << 9)) -#define cc_mselect ( (params->fbzColorPath >> 10) & 7) -#define cc_reverse_blend ( params->fbzColorPath & (1 << 13)) -#define cc_add ( (params->fbzColorPath >> 14) & 3) -#define cc_add_alocal ( params->fbzColorPath & (1 << 15)) -#define cc_invert_output ( params->fbzColorPath & (1 << 16)) -#define cca_zero_other ( params->fbzColorPath & (1 << 17)) -#define cca_sub_clocal ( params->fbzColorPath & (1 << 18)) -#define cca_mselect ( (params->fbzColorPath >> 19) & 7) -#define cca_reverse_blend ( params->fbzColorPath & (1 << 22)) -#define cca_add ( (params->fbzColorPath >> 23) & 3) -#define cca_invert_output ( params->fbzColorPath & (1 << 25)) +#define _rgb_sel (params->fbzColorPath & 3) +#define a_sel ((params->fbzColorPath >> 2) & 3) +#define cc_localselect (params->fbzColorPath & (1 << 4)) +#define cca_localselect ((params->fbzColorPath >> 5) & 3) +#define cc_localselect_override (params->fbzColorPath & (1 << 7)) +#define cc_zero_other (params->fbzColorPath & (1 << 8)) +#define cc_sub_clocal (params->fbzColorPath & (1 << 9)) +#define cc_mselect ((params->fbzColorPath >> 10) & 7) +#define cc_reverse_blend (params->fbzColorPath & (1 << 13)) +#define cc_add ((params->fbzColorPath >> 14) & 3) +#define cc_add_alocal (params->fbzColorPath & (1 << 15)) +#define cc_invert_output (params->fbzColorPath & (1 << 16)) +#define cca_zero_other (params->fbzColorPath & (1 << 17)) +#define cca_sub_clocal (params->fbzColorPath & (1 << 18)) +#define cca_mselect ((params->fbzColorPath >> 19) & 7) +#define cca_reverse_blend (params->fbzColorPath & (1 << 22)) +#define cca_add ((params->fbzColorPath >> 23) & 3) +#define cca_invert_output (params->fbzColorPath & (1 << 25)) #define tc_zero_other (params->textureMode[0] & (1 << 12)) #define tc_sub_clocal (params->textureMode[0] & (1 << 13)) -#define tc_mselect ((params->textureMode[0] >> 14) & 7) +#define tc_mselect ((params->textureMode[0] >> 14) & 7) #define tc_reverse_blend (params->textureMode[0] & (1 << 17)) #define tc_add_clocal (params->textureMode[0] & (1 << 18)) #define tc_add_alocal (params->textureMode[0] & (1 << 19)) #define tc_invert_output (params->textureMode[0] & (1 << 20)) #define tca_zero_other (params->textureMode[0] & (1 << 21)) #define tca_sub_clocal (params->textureMode[0] & (1 << 22)) -#define tca_mselect ((params->textureMode[0] >> 23) & 7) +#define tca_mselect ((params->textureMode[0] >> 23) & 7) #define tca_reverse_blend (params->textureMode[0] & (1 << 26)) #define tca_add_clocal (params->textureMode[0] & (1 << 27)) #define tca_add_alocal (params->textureMode[0] & (1 << 28)) #define tca_invert_output (params->textureMode[0] & (1 << 29)) #define tc_sub_clocal_1 (params->textureMode[1] & (1 << 13)) -#define tc_mselect_1 ((params->textureMode[1] >> 14) & 7) +#define tc_mselect_1 ((params->textureMode[1] >> 14) & 7) #define tc_reverse_blend_1 (params->textureMode[1] & (1 << 17)) #define tc_add_clocal_1 (params->textureMode[1] & (1 << 18)) #define tc_add_alocal_1 (params->textureMode[1] & (1 << 19)) #define tca_sub_clocal_1 (params->textureMode[1] & (1 << 22)) -#define tca_mselect_1 ((params->textureMode[1] >> 23) & 7) +#define tca_mselect_1 ((params->textureMode[1] >> 23) & 7) #define tca_reverse_blend_1 (params->textureMode[1] & (1 << 26)) #define tca_add_clocal_1 (params->textureMode[1] & (1 << 27)) #define tca_add_alocal_1 (params->textureMode[1] & (1 << 28)) -#define src_afunc ( (params->alphaMode >> 8) & 0xf) -#define dest_afunc ( (params->alphaMode >> 12) & 0xf) -#define alpha_func ( (params->alphaMode >> 1) & 7) -#define a_ref ( params->alphaMode >> 24) -#define depth_op ( (params->fbzMode >> 5) & 7) -#define dither ( params->fbzMode & FBZ_DITHER) +#define src_afunc ((params->alphaMode >> 8) & 0xf) +#define dest_afunc ((params->alphaMode >> 12) & 0xf) +#define alpha_func ((params->alphaMode >> 1) & 7) +#define a_ref (params->alphaMode >> 24) +#define depth_op ((params->fbzMode >> 5) & 7) +#define dither (params->fbzMode & FBZ_DITHER) #define dither2x2 (params->fbzMode & FBZ_DITHER_2x2) #define dithersub (params->fbzMode & FBZ_DITHER_SUB) - - #endif /* _VID_VOODOO_REGS_H_ */ diff --git a/includes/private/video/vid_voodoo_render.h b/includes/private/video/vid_voodoo_render.h index c7cbf37c..c658b418 100644 --- a/includes/private/video/vid_voodoo_render.h +++ b/includes/private/video/vid_voodoo_render.h @@ -9,295 +9,263 @@ void voodoo_codegen_init(voodoo_t *voodoo); void voodoo_codegen_close(voodoo_t *voodoo); #endif -#define DEPTH_TEST(comp_depth) \ - do \ - { \ - switch (depth_op) \ - { \ - case DEPTHOP_NEVER: \ - voodoo->fbiZFuncFail++; \ - goto skip_pixel; \ - case DEPTHOP_LESSTHAN: \ - if (!(comp_depth < old_depth)) \ - { \ - voodoo->fbiZFuncFail++; \ - goto skip_pixel; \ - } \ - break; \ - case DEPTHOP_EQUAL: \ - if (!(comp_depth == old_depth)) \ - { \ - voodoo->fbiZFuncFail++; \ - goto skip_pixel; \ - } \ - break; \ - case DEPTHOP_LESSTHANEQUAL: \ - if (!(comp_depth <= old_depth)) \ - { \ - voodoo->fbiZFuncFail++; \ - goto skip_pixel; \ - } \ - break; \ - case DEPTHOP_GREATERTHAN: \ - if (!(comp_depth > old_depth)) \ - { \ - voodoo->fbiZFuncFail++; \ - goto skip_pixel; \ - } \ - break; \ - case DEPTHOP_NOTEQUAL: \ - if (!(comp_depth != old_depth)) \ - { \ - voodoo->fbiZFuncFail++; \ - goto skip_pixel; \ - } \ - break; \ - case DEPTHOP_GREATERTHANEQUAL: \ - if (!(comp_depth >= old_depth)) \ - { \ - voodoo->fbiZFuncFail++; \ - goto skip_pixel; \ - } \ - break; \ - case DEPTHOP_ALWAYS: \ - break; \ - } \ +#define DEPTH_TEST(comp_depth) \ + do { \ + switch (depth_op) { \ + case DEPTHOP_NEVER: \ + voodoo->fbiZFuncFail++; \ + goto skip_pixel; \ + case DEPTHOP_LESSTHAN: \ + if (!(comp_depth < old_depth)) { \ + voodoo->fbiZFuncFail++; \ + goto skip_pixel; \ + } \ + break; \ + case DEPTHOP_EQUAL: \ + if (!(comp_depth == old_depth)) { \ + voodoo->fbiZFuncFail++; \ + goto skip_pixel; \ + } \ + break; \ + case DEPTHOP_LESSTHANEQUAL: \ + if (!(comp_depth <= old_depth)) { \ + voodoo->fbiZFuncFail++; \ + goto skip_pixel; \ + } \ + break; \ + case DEPTHOP_GREATERTHAN: \ + if (!(comp_depth > old_depth)) { \ + voodoo->fbiZFuncFail++; \ + goto skip_pixel; \ + } \ + break; \ + case DEPTHOP_NOTEQUAL: \ + if (!(comp_depth != old_depth)) { \ + voodoo->fbiZFuncFail++; \ + goto skip_pixel; \ + } \ + break; \ + case DEPTHOP_GREATERTHANEQUAL: \ + if (!(comp_depth >= old_depth)) { \ + voodoo->fbiZFuncFail++; \ + goto skip_pixel; \ + } \ + break; \ + case DEPTHOP_ALWAYS: \ + break; \ + } \ } while (0) -#define APPLY_FOG(src_r, src_g, src_b, z, ia, w) \ - do \ - { \ - if (params->fogMode & FOG_CONSTANT) \ - { \ - src_r += params->fogColor.r; \ - src_g += params->fogColor.g; \ - src_b += params->fogColor.b; \ - } \ - else \ - { \ - int fog_r, fog_g, fog_b, fog_a = 0; \ - int fog_idx; \ - \ - if (!(params->fogMode & FOG_ADD)) \ - { \ - fog_r = params->fogColor.r; \ - fog_g = params->fogColor.g; \ - fog_b = params->fogColor.b; \ - } \ - else \ - fog_r = fog_g = fog_b = 0; \ - \ - if (!(params->fogMode & FOG_MULT)) \ - { \ - fog_r -= src_r; \ - fog_g -= src_g; \ - fog_b -= src_b; \ - } \ - \ - switch (params->fogMode & (FOG_Z|FOG_ALPHA)) \ - { \ - case 0: \ - fog_idx = (w_depth >> 10) & 0x3f; \ - \ - fog_a = params->fogTable[fog_idx].fog; \ - fog_a += (params->fogTable[fog_idx].dfog * ((w_depth >> 2) & 0xff)) >> 10; \ - break; \ - case FOG_Z: \ - fog_a = (z >> 20) & 0xff; \ - break; \ - case FOG_ALPHA: \ - fog_a = CLAMP(ia >> 12); \ - break; \ - case FOG_W: \ - fog_a = CLAMP((w >> 32) & 0xff); \ - break; \ - } \ - fog_a++; \ - \ - fog_r = (fog_r * fog_a) >> 8; \ - fog_g = (fog_g * fog_a) >> 8; \ - fog_b = (fog_b * fog_a) >> 8; \ - \ - if (params->fogMode & FOG_MULT) \ - { \ - src_r = fog_r; \ - src_g = fog_g; \ - src_b = fog_b; \ - } \ - else \ - { \ - src_r += fog_r; \ - src_g += fog_g; \ - src_b += fog_b; \ - } \ - } \ - \ - src_r = CLAMP(src_r); \ - src_g = CLAMP(src_g); \ - src_b = CLAMP(src_b); \ +#define APPLY_FOG(src_r, src_g, src_b, z, ia, w) \ + do { \ + if (params->fogMode & FOG_CONSTANT) { \ + src_r += params->fogColor.r; \ + src_g += params->fogColor.g; \ + src_b += params->fogColor.b; \ + } else { \ + int fog_r, fog_g, fog_b, fog_a = 0; \ + int fog_idx; \ + \ + if (!(params->fogMode & FOG_ADD)) { \ + fog_r = params->fogColor.r; \ + fog_g = params->fogColor.g; \ + fog_b = params->fogColor.b; \ + } else \ + fog_r = fog_g = fog_b = 0; \ + \ + if (!(params->fogMode & FOG_MULT)) { \ + fog_r -= src_r; \ + fog_g -= src_g; \ + fog_b -= src_b; \ + } \ + \ + switch (params->fogMode & (FOG_Z | FOG_ALPHA)) { \ + case 0: \ + fog_idx = (w_depth >> 10) & 0x3f; \ + \ + fog_a = params->fogTable[fog_idx].fog; \ + fog_a += (params->fogTable[fog_idx].dfog * ((w_depth >> 2) & 0xff)) >> 10; \ + break; \ + case FOG_Z: \ + fog_a = (z >> 20) & 0xff; \ + break; \ + case FOG_ALPHA: \ + fog_a = CLAMP(ia >> 12); \ + break; \ + case FOG_W: \ + fog_a = CLAMP((w >> 32) & 0xff); \ + break; \ + } \ + fog_a++; \ + \ + fog_r = (fog_r * fog_a) >> 8; \ + fog_g = (fog_g * fog_a) >> 8; \ + fog_b = (fog_b * fog_a) >> 8; \ + \ + if (params->fogMode & FOG_MULT) { \ + src_r = fog_r; \ + src_g = fog_g; \ + src_b = fog_b; \ + } else { \ + src_r += fog_r; \ + src_g += fog_g; \ + src_b += fog_b; \ + } \ + } \ + \ + src_r = CLAMP(src_r); \ + src_g = CLAMP(src_g); \ + src_b = CLAMP(src_b); \ } while (0) -#define ALPHA_TEST(src_a) \ - do \ - { \ - switch (alpha_func) \ - { \ - case AFUNC_NEVER: \ - voodoo->fbiAFuncFail++; \ - goto skip_pixel; \ - case AFUNC_LESSTHAN: \ - if (!(src_a < a_ref)) \ - { \ - voodoo->fbiAFuncFail++; \ - goto skip_pixel; \ - } \ - break; \ - case AFUNC_EQUAL: \ - if (!(src_a == a_ref)) \ - { \ - voodoo->fbiAFuncFail++; \ - goto skip_pixel; \ - } \ - break; \ - case AFUNC_LESSTHANEQUAL: \ - if (!(src_a <= a_ref)) \ - { \ - voodoo->fbiAFuncFail++; \ - goto skip_pixel; \ - } \ - break; \ - case AFUNC_GREATERTHAN: \ - if (!(src_a > a_ref)) \ - { \ - voodoo->fbiAFuncFail++; \ - goto skip_pixel; \ - } \ - break; \ - case AFUNC_NOTEQUAL: \ - if (!(src_a != a_ref)) \ - { \ - voodoo->fbiAFuncFail++; \ - goto skip_pixel; \ - } \ - break; \ - case AFUNC_GREATERTHANEQUAL: \ - if (!(src_a >= a_ref)) \ - { \ - voodoo->fbiAFuncFail++; \ - goto skip_pixel; \ - } \ - break; \ - case AFUNC_ALWAYS: \ - break; \ - } \ +#define ALPHA_TEST(src_a) \ + do { \ + switch (alpha_func) { \ + case AFUNC_NEVER: \ + voodoo->fbiAFuncFail++; \ + goto skip_pixel; \ + case AFUNC_LESSTHAN: \ + if (!(src_a < a_ref)) { \ + voodoo->fbiAFuncFail++; \ + goto skip_pixel; \ + } \ + break; \ + case AFUNC_EQUAL: \ + if (!(src_a == a_ref)) { \ + voodoo->fbiAFuncFail++; \ + goto skip_pixel; \ + } \ + break; \ + case AFUNC_LESSTHANEQUAL: \ + if (!(src_a <= a_ref)) { \ + voodoo->fbiAFuncFail++; \ + goto skip_pixel; \ + } \ + break; \ + case AFUNC_GREATERTHAN: \ + if (!(src_a > a_ref)) { \ + voodoo->fbiAFuncFail++; \ + goto skip_pixel; \ + } \ + break; \ + case AFUNC_NOTEQUAL: \ + if (!(src_a != a_ref)) { \ + voodoo->fbiAFuncFail++; \ + goto skip_pixel; \ + } \ + break; \ + case AFUNC_GREATERTHANEQUAL: \ + if (!(src_a >= a_ref)) { \ + voodoo->fbiAFuncFail++; \ + goto skip_pixel; \ + } \ + break; \ + case AFUNC_ALWAYS: \ + break; \ + } \ } while (0) -#define ALPHA_BLEND(src_r, src_g, src_b, src_a) \ - do \ - { \ - int _a; \ - int newdest_r = 0, newdest_g = 0, newdest_b = 0; \ - \ - switch (dest_afunc) \ - { \ - case AFUNC_AZERO: \ - newdest_r = newdest_g = newdest_b = 0; \ - break; \ - case AFUNC_ASRC_ALPHA: \ - newdest_r = (dest_r * src_a) / 255; \ - newdest_g = (dest_g * src_a) / 255; \ - newdest_b = (dest_b * src_a) / 255; \ - break; \ - case AFUNC_A_COLOR: \ - newdest_r = (dest_r * src_r) / 255; \ - newdest_g = (dest_g * src_g) / 255; \ - newdest_b = (dest_b * src_b) / 255; \ - break; \ - case AFUNC_ADST_ALPHA: \ - newdest_r = (dest_r * dest_a) / 255; \ - newdest_g = (dest_g * dest_a) / 255; \ - newdest_b = (dest_b * dest_a) / 255; \ - break; \ - case AFUNC_AONE: \ - newdest_r = dest_r; \ - newdest_g = dest_g; \ - newdest_b = dest_b; \ - break; \ - case AFUNC_AOMSRC_ALPHA: \ - newdest_r = (dest_r * (255-src_a)) / 255; \ - newdest_g = (dest_g * (255-src_a)) / 255; \ - newdest_b = (dest_b * (255-src_a)) / 255; \ - break; \ - case AFUNC_AOM_COLOR: \ - newdest_r = (dest_r * (255-src_r)) / 255; \ - newdest_g = (dest_g * (255-src_g)) / 255; \ - newdest_b = (dest_b * (255-src_b)) / 255; \ - break; \ - case AFUNC_AOMDST_ALPHA: \ - newdest_r = (dest_r * (255-dest_a)) / 255; \ - newdest_g = (dest_g * (255-dest_a)) / 255; \ - newdest_b = (dest_b * (255-dest_a)) / 255; \ - break; \ - case AFUNC_ASATURATE: \ - _a = MIN(src_a, 1-dest_a); \ - newdest_r = (dest_r * _a) / 255; \ - newdest_g = (dest_g * _a) / 255; \ - newdest_b = (dest_b * _a) / 255; \ - break; \ - } \ - \ - switch (src_afunc) \ - { \ - case AFUNC_AZERO: \ - src_r = src_g = src_b = 0; \ - break; \ - case AFUNC_ASRC_ALPHA: \ - src_r = (src_r * src_a) / 255; \ - src_g = (src_g * src_a) / 255; \ - src_b = (src_b * src_a) / 255; \ - break; \ - case AFUNC_A_COLOR: \ - src_r = (src_r * dest_r) / 255; \ - src_g = (src_g * dest_g) / 255; \ - src_b = (src_b * dest_b) / 255; \ - break; \ - case AFUNC_ADST_ALPHA: \ - src_r = (src_r * dest_a) / 255; \ - src_g = (src_g * dest_a) / 255; \ - src_b = (src_b * dest_a) / 255; \ - break; \ - case AFUNC_AONE: \ - break; \ - case AFUNC_AOMSRC_ALPHA: \ - src_r = (src_r * (255-src_a)) / 255; \ - src_g = (src_g * (255-src_a)) / 255; \ - src_b = (src_b * (255-src_a)) / 255; \ - break; \ - case AFUNC_AOM_COLOR: \ - src_r = (src_r * (255-dest_r)) / 255; \ - src_g = (src_g * (255-dest_g)) / 255; \ - src_b = (src_b * (255-dest_b)) / 255; \ - break; \ - case AFUNC_AOMDST_ALPHA: \ - src_r = (src_r * (255-dest_a)) / 255; \ - src_g = (src_g * (255-dest_a)) / 255; \ - src_b = (src_b * (255-dest_a)) / 255; \ - break; \ - case AFUNC_ACOLORBEFOREFOG: \ - fatal("AFUNC_ACOLORBEFOREFOG\n"); \ - break; \ - } \ - \ - src_r += newdest_r; \ - src_g += newdest_g; \ - src_b += newdest_b; \ - \ - src_r = CLAMP(src_r); \ - src_g = CLAMP(src_g); \ - src_b = CLAMP(src_b); \ - } while(0) - - +#define ALPHA_BLEND(src_r, src_g, src_b, src_a) \ + do { \ + int _a; \ + int newdest_r = 0, newdest_g = 0, newdest_b = 0; \ + \ + switch (dest_afunc) { \ + case AFUNC_AZERO: \ + newdest_r = newdest_g = newdest_b = 0; \ + break; \ + case AFUNC_ASRC_ALPHA: \ + newdest_r = (dest_r * src_a) / 255; \ + newdest_g = (dest_g * src_a) / 255; \ + newdest_b = (dest_b * src_a) / 255; \ + break; \ + case AFUNC_A_COLOR: \ + newdest_r = (dest_r * src_r) / 255; \ + newdest_g = (dest_g * src_g) / 255; \ + newdest_b = (dest_b * src_b) / 255; \ + break; \ + case AFUNC_ADST_ALPHA: \ + newdest_r = (dest_r * dest_a) / 255; \ + newdest_g = (dest_g * dest_a) / 255; \ + newdest_b = (dest_b * dest_a) / 255; \ + break; \ + case AFUNC_AONE: \ + newdest_r = dest_r; \ + newdest_g = dest_g; \ + newdest_b = dest_b; \ + break; \ + case AFUNC_AOMSRC_ALPHA: \ + newdest_r = (dest_r * (255 - src_a)) / 255; \ + newdest_g = (dest_g * (255 - src_a)) / 255; \ + newdest_b = (dest_b * (255 - src_a)) / 255; \ + break; \ + case AFUNC_AOM_COLOR: \ + newdest_r = (dest_r * (255 - src_r)) / 255; \ + newdest_g = (dest_g * (255 - src_g)) / 255; \ + newdest_b = (dest_b * (255 - src_b)) / 255; \ + break; \ + case AFUNC_AOMDST_ALPHA: \ + newdest_r = (dest_r * (255 - dest_a)) / 255; \ + newdest_g = (dest_g * (255 - dest_a)) / 255; \ + newdest_b = (dest_b * (255 - dest_a)) / 255; \ + break; \ + case AFUNC_ASATURATE: \ + _a = MIN(src_a, 1 - dest_a); \ + newdest_r = (dest_r * _a) / 255; \ + newdest_g = (dest_g * _a) / 255; \ + newdest_b = (dest_b * _a) / 255; \ + break; \ + } \ + \ + switch (src_afunc) { \ + case AFUNC_AZERO: \ + src_r = src_g = src_b = 0; \ + break; \ + case AFUNC_ASRC_ALPHA: \ + src_r = (src_r * src_a) / 255; \ + src_g = (src_g * src_a) / 255; \ + src_b = (src_b * src_a) / 255; \ + break; \ + case AFUNC_A_COLOR: \ + src_r = (src_r * dest_r) / 255; \ + src_g = (src_g * dest_g) / 255; \ + src_b = (src_b * dest_b) / 255; \ + break; \ + case AFUNC_ADST_ALPHA: \ + src_r = (src_r * dest_a) / 255; \ + src_g = (src_g * dest_a) / 255; \ + src_b = (src_b * dest_a) / 255; \ + break; \ + case AFUNC_AONE: \ + break; \ + case AFUNC_AOMSRC_ALPHA: \ + src_r = (src_r * (255 - src_a)) / 255; \ + src_g = (src_g * (255 - src_a)) / 255; \ + src_b = (src_b * (255 - src_a)) / 255; \ + break; \ + case AFUNC_AOM_COLOR: \ + src_r = (src_r * (255 - dest_r)) / 255; \ + src_g = (src_g * (255 - dest_g)) / 255; \ + src_b = (src_b * (255 - dest_b)) / 255; \ + break; \ + case AFUNC_AOMDST_ALPHA: \ + src_r = (src_r * (255 - dest_a)) / 255; \ + src_g = (src_g * (255 - dest_a)) / 255; \ + src_b = (src_b * (255 - dest_a)) / 255; \ + break; \ + case AFUNC_ACOLORBEFOREFOG: \ + fatal("AFUNC_ACOLORBEFOREFOG\n"); \ + break; \ + } \ + \ + src_r += newdest_r; \ + src_g += newdest_g; \ + src_b += newdest_b; \ + \ + src_r = CLAMP(src_r); \ + src_g = CLAMP(src_g); \ + src_b = CLAMP(src_b); \ + } while (0) void voodoo_render_thread_1(void *param); void voodoo_render_thread_2(void *param); @@ -308,25 +276,21 @@ void voodoo_queue_triangle(voodoo_t *voodoo, voodoo_params_t *params); extern int voodoo_recomp; extern int tris; -static inline void voodoo_wake_render_thread(voodoo_t *voodoo) -{ +static inline void voodoo_wake_render_thread(voodoo_t *voodoo) { thread_set_event(voodoo->wake_render_thread[0]); /*Wake up render thread if moving from idle*/ if (voodoo->render_threads >= 2) thread_set_event(voodoo->wake_render_thread[1]); /*Wake up render thread if moving from idle*/ - if (voodoo->render_threads == 4) - { + if (voodoo->render_threads == 4) { thread_set_event(voodoo->wake_render_thread[2]); /*Wake up render thread if moving from idle*/ thread_set_event(voodoo->wake_render_thread[3]); /*Wake up render thread if moving from idle*/ } } -static inline void voodoo_wait_for_render_thread_idle(voodoo_t *voodoo) -{ +static inline void voodoo_wait_for_render_thread_idle(voodoo_t *voodoo) { while (!PARAM_EMPTY(0) || (voodoo->render_threads >= 2 && !PARAM_EMPTY(1)) || - (voodoo->render_threads == 4 && (!PARAM_EMPTY(2) || !PARAM_EMPTY(3))) || - voodoo->render_voodoo_busy[0] || (voodoo->render_threads >= 2 && voodoo->render_voodoo_busy[1]) || - (voodoo->render_threads == 4 && (voodoo->render_voodoo_busy[2] || voodoo->render_voodoo_busy[3]))) - { + (voodoo->render_threads == 4 && (!PARAM_EMPTY(2) || !PARAM_EMPTY(3))) || voodoo->render_voodoo_busy[0] || + (voodoo->render_threads >= 2 && voodoo->render_voodoo_busy[1]) || + (voodoo->render_threads == 4 && (voodoo->render_voodoo_busy[2] || voodoo->render_voodoo_busy[3]))) { voodoo_wake_render_thread(voodoo); if (!PARAM_EMPTY(0) || voodoo->render_voodoo_busy[0]) thread_wait_event(voodoo->render_not_full_event[0], 1); @@ -339,5 +303,4 @@ static inline void voodoo_wait_for_render_thread_idle(voodoo_t *voodoo) } } - #endif /* _VID_VOODOO_RENDER_H_ */ diff --git a/includes/private/video/vid_voodoo_setup.h b/includes/private/video/vid_voodoo_setup.h index 1e10a019..7a790793 100644 --- a/includes/private/video/vid_voodoo_setup.h +++ b/includes/private/video/vid_voodoo_setup.h @@ -2,5 +2,4 @@ #define _VID_VOODOO_SETUP_H_ void voodoo_triangle_setup(voodoo_t *voodoo); - #endif /* _VID_VOODOO_SETUP_H_ */ diff --git a/includes/private/video/vid_voodoo_texture.h b/includes/private/video/vid_voodoo_texture.h index 5bf52cf1..78fc864e 100644 --- a/includes/private/video/vid_voodoo_texture.h +++ b/includes/private/video/vid_voodoo_texture.h @@ -1,24 +1,21 @@ #ifndef _VID_VOODOO_TEXTURE_H_ #define _VID_VOODOO_TEXTURE_H_ -static const uint32_t texture_offset[LOD_MAX+3] = -{ +static const uint32_t texture_offset[LOD_MAX + 3] = { 0, - 256*256, - 256*256 + 128*128, - 256*256 + 128*128 + 64*64, - 256*256 + 128*128 + 64*64 + 32*32, - 256*256 + 128*128 + 64*64 + 32*32 + 16*16, - 256*256 + 128*128 + 64*64 + 32*32 + 16*16 + 8*8, - 256*256 + 128*128 + 64*64 + 32*32 + 16*16 + 8*8 + 4*4, - 256*256 + 128*128 + 64*64 + 32*32 + 16*16 + 8*8 + 4*4 + 2*2, - 256*256 + 128*128 + 64*64 + 32*32 + 16*16 + 8*8 + 4*4 + 2*2 + 1*1, - 256*256 + 128*128 + 64*64 + 32*32 + 16*16 + 8*8 + 4*4 + 2*2 + 1*1 + 1 -}; + 256 * 256, + 256 * 256 + 128 * 128, + 256 * 256 + 128 * 128 + 64 * 64, + 256 * 256 + 128 * 128 + 64 * 64 + 32 * 32, + 256 * 256 + 128 * 128 + 64 * 64 + 32 * 32 + 16 * 16, + 256 * 256 + 128 * 128 + 64 * 64 + 32 * 32 + 16 * 16 + 8 * 8, + 256 * 256 + 128 * 128 + 64 * 64 + 32 * 32 + 16 * 16 + 8 * 8 + 4 * 4, + 256 * 256 + 128 * 128 + 64 * 64 + 32 * 32 + 16 * 16 + 8 * 8 + 4 * 4 + 2 * 2, + 256 * 256 + 128 * 128 + 64 * 64 + 32 * 32 + 16 * 16 + 8 * 8 + 4 * 4 + 2 * 2 + 1 * 1, + 256 * 256 + 128 * 128 + 64 * 64 + 32 * 32 + 16 * 16 + 8 * 8 + 4 * 4 + 2 * 2 + 1 * 1 + 1}; void voodoo_recalc_tex(voodoo_t *voodoo, int tmu); void voodoo_use_texture(voodoo_t *voodoo, voodoo_params_t *params, int tmu); void voodoo_tex_writel(uint32_t addr, uint32_t val, void *p); void flush_texture_cache(voodoo_t *voodoo, uint32_t dirty_addr, int tmu); - #endif /* _VID_VOODOO_TEXTURE_H_ */ diff --git a/includes/private/video/vid_wy700.h b/includes/private/video/vid_wy700.h index d404ff44..9d1e283b 100644 --- a/includes/private/video/vid_wy700.h +++ b/includes/private/video/vid_wy700.h @@ -2,5 +2,4 @@ #define _VID_WY700_H_ extern device_t wy700_device; - #endif /* _VID_WY700_H_ */ diff --git a/includes/private/video/video.h b/includes/private/video/video.h index 09dc4f7b..01bd5f8f 100644 --- a/includes/private/video/video.h +++ b/includes/private/video/video.h @@ -1,8 +1,7 @@ #ifndef _VIDEO_H_ #define _VIDEO_H_ -typedef struct -{ +typedef struct { int w, h; uint8_t *dat; uint8_t *line[0]; @@ -12,15 +11,14 @@ extern BITMAP *screen; BITMAP *create_bitmap(int w, int h); -typedef struct -{ +typedef struct { uint8_t r, g, b; } RGB; - + typedef RGB PALETTE[256]; -#define makecol(r, g, b) ((b) | ((g) << 8) | ((r) << 16)) -#define makecol32(r, g, b) ((b) | ((g) << 8) | ((r) << 16)) +#define makecol(r, g, b) ((b) | ((g) << 8) | ((r) << 16)) +#define makecol32(r, g, b) ((b) | ((g) << 8) | ((r) << 16)) extern BITMAP *buffer32; @@ -41,15 +39,9 @@ extern int video_fullscreen, video_fullscreen_scale, video_fullscreen_first; extern int video_force_aspect_ration; extern int vid_disc_indicator; -enum -{ - FULLSCR_SCALE_FULL = 0, - FULLSCR_SCALE_43, - FULLSCR_SCALE_SQ, - FULLSCR_SCALE_INT -}; +enum { FULLSCR_SCALE_FULL = 0, FULLSCR_SCALE_43, FULLSCR_SCALE_SQ, FULLSCR_SCALE_INT }; -extern int egareads,egawrites; +extern int egareads, egawrites; extern int fullchange; extern int changeframecount; @@ -61,7 +53,7 @@ extern uint8_t fontdatksc5601_user[192][32]; extern uint32_t *video_15to32, *video_16to32; -extern int xsize,ysize; +extern int xsize, ysize; extern float cpuclock; @@ -86,17 +78,16 @@ extern int vid_resize; void video_wait_for_blit(); void video_wait_for_buffer(); -typedef enum -{ - FONT_MDA, /* MDA 8x14 */ - FONT_PC200, /* MDA 8x14 and CGA 8x8, four fonts */ - FONT_CGA, /* CGA 8x8, two fonts */ - FONT_WY700, /* Wy700 16x16, two fonts */ - FONT_MDSI, /* MDSI Genius 8x12 */ - FONT_T3100E, /* Toshiba T3100e, four fonts */ - FONT_KSC5601, /* Korean KSC-5601 */ - FONT_SIGMA400, /* Sigma Color 400, 8x8 and 8x16 */ - FONT_IM1024, /* Image Manager 1024 */ +typedef enum { + FONT_MDA, /* MDA 8x14 */ + FONT_PC200, /* MDA 8x14 and CGA 8x8, four fonts */ + FONT_CGA, /* CGA 8x8, two fonts */ + FONT_WY700, /* Wy700 16x16, two fonts */ + FONT_MDSI, /* MDSI Genius 8x12 */ + FONT_T3100E, /* Toshiba T3100e, four fonts */ + FONT_KSC5601, /* Korean KSC-5601 */ + FONT_SIGMA400, /* Sigma Color 400, 8x8 and 8x16 */ + FONT_IM1024, /* Image Manager 1024 */ } fontformat_t; void loadfont(char *s, fontformat_t format); diff --git a/includes/private/wx-ui/wx-app.h b/includes/private/wx-ui/wx-app.h index 9c30ae7b..e5ae8db8 100644 --- a/includes/private/wx-ui/wx-app.h +++ b/includes/private/wx-ui/wx-app.h @@ -22,151 +22,136 @@ wxDECLARE_EVENT(WX_POPUP_MENU_EVENT, PopupMenuEvent); #ifdef _WIN32 class WinSendMessageEvent; wxDECLARE_EVENT(WX_WIN_SEND_MESSAGE_EVENT, WinSendMessageEvent); -class WinSendMessageEvent: public wxCommandEvent -{ -public: - WinSendMessageEvent(void* hwnd, int message, INT_PARAM wParam, LONG_PARAM lParam) : wxCommandEvent(WX_WIN_SEND_MESSAGE_EVENT) - { +class WinSendMessageEvent : public wxCommandEvent { + public: + WinSendMessageEvent(void *hwnd, int message, INT_PARAM wParam, LONG_PARAM lParam) + : wxCommandEvent(WX_WIN_SEND_MESSAGE_EVENT) { this->hwnd = hwnd; this->message = message; this->wParam = wParam; this->lParam = lParam; } - WinSendMessageEvent(const WinSendMessageEvent& event) : wxCommandEvent(event) - { + WinSendMessageEvent(const WinSendMessageEvent &event) : wxCommandEvent(event) { this->hwnd = event.GetHWND(); this->message = event.GetMessage(); this->wParam = event.GetWParam(); this->lParam = event.GetLParam(); } - wxEvent* Clone() const { return new WinSendMessageEvent(*this); } + wxEvent *Clone() const { return new WinSendMessageEvent(*this); } - void* GetHWND() const { return hwnd; } + void *GetHWND() const { return hwnd; } int GetMessage() const { return message; } INT_PARAM GetWParam() const { return wParam; } LONG_PARAM GetLParam() const { return lParam; } -private: - void* hwnd; + private: + void *hwnd; int message; INT_PARAM wParam; LONG_PARAM lParam; }; #endif -class CallbackEvent: public wxCommandEvent -{ -public: - CallbackEvent(WX_CALLBACK callback, void* data) : wxCommandEvent(WX_CALLBACK_EVENT) - { +class CallbackEvent : public wxCommandEvent { + public: + CallbackEvent(WX_CALLBACK callback, void *data) : wxCommandEvent(WX_CALLBACK_EVENT) { this->callback = callback; this->data = data; } - CallbackEvent(const CallbackEvent& event) : wxCommandEvent(event) - { + CallbackEvent(const CallbackEvent &event) : wxCommandEvent(event) { this->callback = event.GetCallback(); this->data = event.GetData(); } - wxEvent* Clone() const { return new CallbackEvent(*this); } + wxEvent *Clone() const { return new CallbackEvent(*this); } WX_CALLBACK GetCallback() const { return callback; } - void* GetData() const { return data; } + void *GetData() const { return data; } -private: + private: WX_CALLBACK callback; - void* data; - - + void *data; }; -class PopupMenuEvent: public wxCommandEvent -{ -public: - PopupMenuEvent(wxWindow* window, wxMenu* menu, int* x, int* y) : wxCommandEvent(WX_POPUP_MENU_EVENT) - { +class PopupMenuEvent : public wxCommandEvent { + public: + PopupMenuEvent(wxWindow *window, wxMenu *menu, int *x, int *y) : wxCommandEvent(WX_POPUP_MENU_EVENT) { this->window = window; this->menu = menu; this->x = x; this->y = y; } - PopupMenuEvent(const PopupMenuEvent& event) : wxCommandEvent(event) - { + PopupMenuEvent(const PopupMenuEvent &event) : wxCommandEvent(event) { this->window = event.GetWindow(); this->menu = event.GetMenu(); this->x = event.GetX(); this->y = event.GetY(); } - wxEvent* Clone() const { return new PopupMenuEvent(*this); } + wxEvent *Clone() const { return new PopupMenuEvent(*this); } - wxWindow* GetWindow() const { return window; } - wxMenu* GetMenu() const { return menu; } - int* GetX() const { return x; } - int* GetY() const { return y; } + wxWindow *GetWindow() const { return window; } + wxMenu *GetMenu() const { return menu; } + int *GetX() const { return x; } + int *GetY() const { return y; } -private: - int* x; - int* y; - wxMenu* menu; - wxWindow* window; + private: + int *x; + int *y; + wxMenu *menu; + wxWindow *window; }; class Frame; -class App: public wxApp -{ -public: +class App : public wxApp { + public: App(); virtual bool OnInit(); virtual int OnRun(); - Frame* GetFrame() - { - return frame; - } -private: - Frame* frame; + Frame *GetFrame() { return frame; } + + private: + Frame *frame; }; -class CExitThread: public wxThread -{ -public: - CExitThread(Frame* frame); - virtual ~CExitThread() {} -private: - wxThread::ExitCode Entry(); - Frame* frame; +class CExitThread : public wxThread { + public: + CExitThread(Frame *frame); + virtual ~CExitThread() {} + + private: + wxThread::ExitCode Entry(); + Frame *frame; }; -class Frame: public wxFrame -{ -public: - Frame(App* app, const wxString& title, const wxPoint& pos, - const wxSize& size); +class Frame : public wxFrame { + public: + Frame(App *app, const wxString &title, const wxPoint &pos, const wxSize &size); virtual ~Frame() {} void Start(); - wxMenu* GetMenu(); + wxMenu *GetMenu(); -private: - void OnCommand(wxCommandEvent& event); - void OnExitEvent(wxCommandEvent& event); - void OnExitCompleteEvent(wxCommandEvent& event); - void OnStopEmulationEvent(wxCommandEvent& event); - void OnStopEmulationNowEvent(wxCommandEvent& event); - void OnShowWindowEvent(wxCommandEvent& event); - void OnPopupMenuEvent(PopupMenuEvent& event); - void OnCallbackEvent(CallbackEvent& event); - void OnClose(wxCloseEvent& event); + private: + void OnCommand(wxCommandEvent &event); + void OnExitEvent(wxCommandEvent &event); + void OnExitCompleteEvent(wxCommandEvent &event); + void OnStopEmulationEvent(wxCommandEvent &event); + void OnStopEmulationNowEvent(wxCommandEvent &event); + void OnShowWindowEvent(wxCommandEvent &event); + void OnPopupMenuEvent(PopupMenuEvent &event); + void OnCallbackEvent(CallbackEvent &event); + void OnClose(wxCloseEvent &event); #ifdef _WIN32 - void OnWinSendMessageEvent(WinSendMessageEvent& event); + void OnWinSendMessageEvent(WinSendMessageEvent &event); #endif void ShowConfigSelection(); - wxMenu* menu; + wxMenu *menu; bool closing; diff --git a/includes/private/wx-ui/wx-common.h b/includes/private/wx-ui/wx-common.h index 788d6f94..b7d4295e 100644 --- a/includes/private/wx-ui/wx-common.h +++ b/includes/private/wx-ui/wx-common.h @@ -27,5 +27,4 @@ typedef struct drive_info_t { int readflash; } drive_info_t; - #endif /* _WX_COMMON_H_ */ diff --git a/includes/private/wx-ui/wx-deviceconfig.h b/includes/private/wx-ui/wx-deviceconfig.h index 0c208115..20f59e89 100644 --- a/includes/private/wx-ui/wx-deviceconfig.h +++ b/includes/private/wx-ui/wx-deviceconfig.h @@ -4,7 +4,7 @@ extern "C" { #include #include "device.h" -void deviceconfig_open(void* hwnd, device_t *device); +void deviceconfig_open(void *hwnd, device_t *device); } #endif /* SRC_WX_DEVICECONFIG_H_ */ diff --git a/includes/private/wx-ui/wx-dialogbox.h b/includes/private/wx-ui/wx-dialogbox.h index b8179dc2..2cfb1e40 100644 --- a/includes/private/wx-ui/wx-dialogbox.h +++ b/includes/private/wx-ui/wx-dialogbox.h @@ -5,20 +5,22 @@ #include "wx-utils.h" -class PCemDialogBox: public wxDialog { -public: - PCemDialogBox(wxWindow* parent, int(*callback)(void* window, int message, INT_PARAM param1, LONG_PARAM param2)); - PCemDialogBox(wxWindow* parent, const char* name, int(*callback)(void* window, int message, INT_PARAM param1, LONG_PARAM param2)); - virtual ~PCemDialogBox() {} - void OnInit(); -private: - void OnNotebookChanged(wxCommandEvent& event); - void OnCommand(wxCommandEvent& event); - int processEvent(int message, INT_PARAM param1, LONG_PARAM param2); - int(*callback)(void* window, int message, INT_PARAM param1, LONG_PARAM param2); - bool commandActive; +class PCemDialogBox : public wxDialog { + public: + PCemDialogBox(wxWindow *parent, int (*callback)(void *window, int message, INT_PARAM param1, LONG_PARAM param2)); + PCemDialogBox(wxWindow *parent, const char *name, + int (*callback)(void *window, int message, INT_PARAM param1, LONG_PARAM param2)); + virtual ~PCemDialogBox() {} + void OnInit(); - DECLARE_EVENT_TABLE() + private: + void OnNotebookChanged(wxCommandEvent &event); + void OnCommand(wxCommandEvent &event); + int processEvent(int message, INT_PARAM param1, LONG_PARAM param2); + int (*callback)(void *window, int message, INT_PARAM param1, LONG_PARAM param2); + bool commandActive; + + DECLARE_EVENT_TABLE() }; #endif /* SRC_WX_PCEMDIALOGBOX_H_ */ diff --git a/includes/private/wx-ui/wx-display.h b/includes/private/wx-ui/wx-display.h index 864ac89b..8cddc7e9 100644 --- a/includes/private/wx-ui/wx-display.h +++ b/includes/private/wx-ui/wx-display.h @@ -7,7 +7,7 @@ extern "C" { int display_init(); void display_close(); -void display_start(void* hwnd); +void display_start(void *hwnd); void display_stop(); void display_resize(int width, int height); diff --git a/includes/private/wx-ui/wx-glsl.h b/includes/private/wx-ui/wx-glsl.h index 8ec3047e..8fae0e5f 100644 --- a/includes/private/wx-ui/wx-glsl.h +++ b/includes/private/wx-ui/wx-glsl.h @@ -39,7 +39,7 @@ struct shader_texture { int min_filter; int mag_filter; int wrap_mode; - void* data; + void *data; int mipmap; }; @@ -133,7 +133,7 @@ struct glsl_shader { struct shader_parameter parameters[MAX_PARAMETERS]; struct shader_pass prev_scene; - struct shader_prev prev[MAX_PREV+1]; + struct shader_prev prev[MAX_PREV + 1]; int last_prev_update; int has_prev; diff --git a/includes/private/wx-ui/wx-glslp-parser.h b/includes/private/wx-ui/wx-glslp-parser.h index 3d54c0eb..8c687f56 100644 --- a/includes/private/wx-ui/wx-glslp-parser.h +++ b/includes/private/wx-ui/wx-glslp-parser.h @@ -23,7 +23,7 @@ struct texture { struct shader { char shader_fn[1024]; - char* shader_program; + char *shader_program; char alias[64]; int filter_linear; int float_framebuffer; @@ -49,8 +49,8 @@ typedef struct glslp_t { int input_filter_linear; } glslp_t; -void get_glslp_name(const char* f, char* s, int size); -glslp_t* glslp_parse(const char* f); -void glslp_free(glslp_t* p); +void get_glslp_name(const char *f, char *s, int size); +glslp_t *glslp_parse(const char *f); +void glslp_free(glslp_t *p); #endif /* SRC_WX_GLSLP_PARSER_H_ */ diff --git a/includes/private/wx-ui/wx-hostconfig.h b/includes/private/wx-ui/wx-hostconfig.h index 3b606d3a..31891866 100644 --- a/includes/private/wx-ui/wx-hostconfig.h +++ b/includes/private/wx-ui/wx-hostconfig.h @@ -2,5 +2,4 @@ #define _WX_HOSTCONFIG_H_ int hostconfig_open(void *hwnd); - #endif /* _WX_HOSTCONFIG_H_ */ diff --git a/includes/private/wx-ui/wx-sdl2-glw.h b/includes/private/wx-ui/wx-sdl2-glw.h index 9e9d007f..fac2b2ea 100644 --- a/includes/private/wx-ui/wx-sdl2-glw.h +++ b/includes/private/wx-ui/wx-sdl2-glw.h @@ -41,9 +41,8 @@ typedef struct glw_t { PFNGLBUFFERSUBDATAPROC glBufferSubData; } glw_t; -glw_t* glw_init() -{ - glw_t* glw = malloc(sizeof(glw_t)); +glw_t *glw_init() { + glw_t *glw = malloc(sizeof(glw_t)); glw->glActiveTexture = SDL_GL_GetProcAddress("glActiveTexture"); glw->glCreateShader = SDL_GL_GetProcAddress("glCreateShader"); glw->glShaderSource = SDL_GL_GetProcAddress("glShaderSource"); @@ -84,9 +83,6 @@ glw_t* glw_init() return glw; } -void glw_free(glw_t* glw) -{ - free(glw); -} +void glw_free(glw_t *glw) { free(glw); } #endif /* _WX_SDL2_GLW_H_ */ diff --git a/includes/private/wx-ui/wx-sdl2-video-gl3.h b/includes/private/wx-ui/wx-sdl2-video-gl3.h index a262381d..a015ab33 100644 --- a/includes/private/wx-ui/wx-sdl2-video-gl3.h +++ b/includes/private/wx-ui/wx-sdl2-video-gl3.h @@ -1,8 +1,7 @@ #ifndef _WX_SDL2_VIDEO_GL3_H_ #define _WX_SDL2_VIDEO_GL3_H_ -sdl_renderer_t* gl3_renderer_create(); -void gl3_renderer_close(sdl_renderer_t* renderer); -int gl3_renderer_available(struct sdl_render_driver* driver); - +sdl_renderer_t *gl3_renderer_create(); +void gl3_renderer_close(sdl_renderer_t *renderer); +int gl3_renderer_available(struct sdl_render_driver *driver); #endif /* _WX_SDL2_VIDEO_GL3_H_ */ diff --git a/includes/private/wx-ui/wx-sdl2-video-renderer.h b/includes/private/wx-ui/wx-sdl2-video-renderer.h index c9d34290..fde425cb 100644 --- a/includes/private/wx-ui/wx-sdl2-video-renderer.h +++ b/includes/private/wx-ui/wx-sdl2-video-renderer.h @@ -1,8 +1,7 @@ #ifndef _WX_SDL2_VIDEO_RENDERER_H_ #define _WX_SDL2_VIDEO_RENDERER_H_ -sdl_renderer_t* sdl2_renderer_create(); -void sdl2_renderer_close(sdl_renderer_t* renderer); -int sdl2_renderer_available(struct sdl_render_driver* driver); - +sdl_renderer_t *sdl2_renderer_create(); +void sdl2_renderer_close(sdl_renderer_t *renderer); +int sdl2_renderer_available(struct sdl_render_driver *driver); #endif /* _WX_SDL2_VIDEO_RENDERER_H_ */ diff --git a/includes/private/wx-ui/wx-sdl2-video.h b/includes/private/wx-ui/wx-sdl2-video.h index bf0a2d32..7c2dd7b9 100644 --- a/includes/private/wx-ui/wx-sdl2-video.h +++ b/includes/private/wx-ui/wx-sdl2-video.h @@ -11,21 +11,21 @@ struct sdl_render_driver; typedef struct sdl_renderer_t { - int (*init)(SDL_Window* window, struct sdl_render_driver driver, SDL_Rect screen); + int (*init)(SDL_Window *window, struct sdl_render_driver driver, SDL_Rect screen); void (*close)(); - void (*update)(SDL_Window* window, SDL_Rect updated_rect, BITMAP* screen); - void (*present)(SDL_Window* window, SDL_Rect texture_rect, SDL_Rect window_rect, SDL_Rect screen); + void (*update)(SDL_Window *window, SDL_Rect updated_rect, BITMAP *screen); + void (*present)(SDL_Window *window, SDL_Rect texture_rect, SDL_Rect window_rect, SDL_Rect screen); int always_update; } sdl_renderer_t; typedef struct sdl_render_driver { int id; - const char* sdl_id; - const char* name; + const char *sdl_id; + const char *name; int sdl_window_params; - sdl_renderer_t* (*renderer_create)(); - void (*renderer_close)(sdl_renderer_t* renderer); - int (*renderer_available)(struct sdl_render_driver* driver); + sdl_renderer_t *(*renderer_create)(); + void (*renderer_close)(sdl_renderer_t *renderer); + int (*renderer_available)(struct sdl_render_driver *driver); } sdl_render_driver; typedef float (*FLASH_FUNC)(float v); @@ -46,17 +46,17 @@ extern "C" { #endif int sdl_video_init(); void sdl_video_close(); -int sdl_renderer_init(SDL_Window* window); +int sdl_renderer_init(SDL_Window *window); void sdl_renderer_close(); -int sdl_renderer_update(SDL_Window* window); -void sdl_renderer_present(SDL_Window* window); -void sdl_scale(int scale, SDL_Rect src, SDL_Rect* dst, int w, int h); -int sdl_is_fullscreen(SDL_Window* window); +int sdl_renderer_update(SDL_Window *window); +void sdl_renderer_present(SDL_Window *window); +void sdl_scale(int scale, SDL_Rect src, SDL_Rect *dst, int w, int h); +int sdl_is_fullscreen(SDL_Window *window); -sdl_render_driver* sdl_get_render_drivers(int* num_renderers); +sdl_render_driver *sdl_get_render_drivers(int *num_renderers); sdl_render_driver sdl_get_render_driver_by_id(int id, int def); -sdl_render_driver sdl_get_render_driver_by_name(const char* name, int def); -sdl_render_driver* sdl_get_render_driver_by_name_ptr(const char* name); +sdl_render_driver sdl_get_render_driver_by_name(const char *name, int def); +sdl_render_driver *sdl_get_render_driver_by_name_ptr(const char *name); void color_flash(FLASH_FUNC func, int time_ms, char r, char g, char b, char a); @@ -70,5 +70,4 @@ extern char current_render_driver_name[50]; extern int custom_resolution_width; extern int custom_resolution_height; - #endif /* _WX_SDL2_VIDEO_H_ */ diff --git a/includes/private/wx-ui/wx-sdl2.h b/includes/private/wx-ui/wx-sdl2.h index cf44c8ba..e55e4eb6 100644 --- a/includes/private/wx-ui/wx-sdl2.h +++ b/includes/private/wx-ui/wx-sdl2.h @@ -5,10 +5,10 @@ extern "C" { #endif void leave_fullscreen(); -int getfile(void* hwnd, char *f, char *fn); -int getsfile(void* hwnd, char *f, char *fn, char *dir, char *ext); -int getfilewithcaption(void* hwnd, char *f, char *fn, char *caption); -void screenshot_taken(unsigned char* rgb, int width, int height); +int getfile(void *hwnd, char *f, char *fn); +int getsfile(void *hwnd, char *f, char *fn, char *dir, char *ext); +int getfilewithcaption(void *hwnd, char *f, char *fn, char *caption); +void screenshot_taken(unsigned char *rgb, int width, int height); #ifdef __cplusplus } @@ -20,5 +20,4 @@ extern int pause; extern int take_screenshot; - #endif /* _WX_SDL2_H_ */ diff --git a/includes/private/wx-ui/wx-shaderconfig.h b/includes/private/wx-ui/wx-shaderconfig.h index 279409c3..63ea0faa 100644 --- a/includes/private/wx-ui/wx-shaderconfig.h +++ b/includes/private/wx-ui/wx-shaderconfig.h @@ -4,10 +4,9 @@ #ifdef __cplusplus extern "C" { #endif -void shaderconfig_open(void* hwnd, struct glslp_t* glsl); +void shaderconfig_open(void *hwnd, struct glslp_t *glsl); #ifdef __cplusplus } #endif - #endif /* SRC_WX_SHADERCONFIG_H_ */ diff --git a/includes/private/wx-ui/wx-status.h b/includes/private/wx-ui/wx-status.h index 87e5fe5e..ff8b8d8d 100644 --- a/includes/private/wx-ui/wx-status.h +++ b/includes/private/wx-ui/wx-status.h @@ -11,60 +11,59 @@ class StatusPane; -class StatusTimer : public wxTimer -{ -public: - StatusTimer(StatusPane* pane); - virtual ~StatusTimer() {}; +class StatusTimer : public wxTimer { + public: + StatusTimer(StatusPane *pane); + virtual ~StatusTimer(){}; void Notify(); void Start(); -private: - StatusPane* pane; + + private: + StatusPane *pane; }; -class StatusPane : public wxPanel -{ +class StatusPane : public wxPanel { -public: - StatusPane(wxFrame* parent); - virtual ~StatusPane(); + public: + StatusPane(wxFrame *parent); + virtual ~StatusPane(); - void PaintEvent(wxPaintEvent& evt); - void PaintNow(); - void Render( wxDC& dc ); + void PaintEvent(wxPaintEvent &evt); + void PaintNow(); + void Render(wxDC &dc); -private: - char machineInfoText[4096]; - char statusMachineText[4096]; - char statusDeviceText[4096]; - wxLongLong lastSpeedUpdate; - char speedHistory[SPEED_HISTORY_LENGTH]; + private: + char machineInfoText[4096]; + char statusMachineText[4096]; + char statusDeviceText[4096]; + wxLongLong lastSpeedUpdate; + char speedHistory[SPEED_HISTORY_LENGTH]; - wxBitmap bitmapFDD[2]; - wxBitmap bitmapCDROM[2]; - wxBitmap bitmapHDD[2]; + wxBitmap bitmapFDD[2]; + wxBitmap bitmapCDROM[2]; + wxBitmap bitmapHDD[2]; - DECLARE_EVENT_TABLE() + DECLARE_EVENT_TABLE() }; #define STATUS_WINDOW_ID 1000 class StatusFrame : public wxFrame { -public: - StatusFrame(wxWindow* parent); + public: + StatusFrame(wxWindow *parent); virtual ~StatusFrame(); void OnQuit(); -private: + + private: void OnCommand(wxCommandEvent &event); - void OnMoveWindow(wxMoveEvent& event); - StatusPane* statusPane; - StatusTimer* statusTimer; + void OnMoveWindow(wxMoveEvent &event); + StatusPane *statusPane; + StatusTimer *statusTimer; void UpdateToolbar(); DECLARE_EVENT_TABLE() - }; #endif /* _WX_STATUS_H_ */ diff --git a/includes/private/wx-ui/wx-utils.h b/includes/private/wx-ui/wx-utils.h index 40a25d28..938d0e8f 100644 --- a/includes/private/wx-ui/wx-utils.h +++ b/includes/private/wx-ui/wx-utils.h @@ -10,109 +10,112 @@ #define INT_PARAM wxInt32 #endif -typedef int (*WX_CALLBACK)(void* data); +typedef int (*WX_CALLBACK)(void *data); #ifdef __cplusplus extern "C" { #endif - int wx_messagebox(void* nothing, const char* message, const char* title, int style); - void wx_simple_messagebox(const char* title, const char *format, ...); +int wx_messagebox(void *nothing, const char *message, const char *title, int style); +void wx_simple_messagebox(const char *title, const char *format, ...); - int wx_xrcid(const char* s); - int wx_filedialog(void* window, const char* title, const char* path, const char* extensions, const char* extension, int open, char* file); - void wx_checkmenuitem(void* window, int id, int checked); - void wx_enablemenuitem(void* menu, int id, int enable); - void* wx_getmenu(void* window); - void* wx_getmenubar(void* window); - void wx_enabletoolbaritem(void* toolbar, int id, int enable); - void* wx_gettoolbar(void* window); +int wx_xrcid(const char *s); +int wx_filedialog(void *window, const char *title, const char *path, const char *extensions, const char *extension, int open, + char *file); +void wx_checkmenuitem(void *window, int id, int checked); +void wx_enablemenuitem(void *menu, int id, int enable); +void *wx_getmenu(void *window); +void *wx_getmenubar(void *window); +void wx_enabletoolbaritem(void *toolbar, int id, int enable); +void *wx_gettoolbar(void *window); - void* wx_getsubmenu(void* window, int id); - void wx_appendmenu(void* sub_menu, int id, const char* title, enum wxItemKind type); - void* wx_getnativemenu(void* menu); +void *wx_getsubmenu(void *window, int id); +void wx_appendmenu(void *sub_menu, int id, const char *title, enum wxItemKind type); +void *wx_getnativemenu(void *menu); - int wx_textentrydialog(void* window, const char* message, const char* title, const char* value, unsigned int min_length, unsigned int max_length, LONG_PARAM result); +int wx_textentrydialog(void *window, const char *message, const char *title, const char *value, unsigned int min_length, + unsigned int max_length, LONG_PARAM result); - int wx_dlgdirlist(void* window, const char* path, int id, int static_path, int file_type); - int wx_dlgdirselectex(void* window, LONG_PARAM path, int count, int id); +int wx_dlgdirlist(void *window, const char *path, int id, int static_path, int file_type); +int wx_dlgdirselectex(void *window, LONG_PARAM path, int count, int id); - void wx_setwindowtitle(void* window, char* s); - int wx_sendmessage(void* window, int type, LONG_PARAM param1, LONG_PARAM param2); - void* wx_getdlgitem(void* window, int id); - void wx_setdlgitemtext(void* window, int id, char* str); - void wx_enablewindow(void* window, int enabled); - void wx_showwindow(void* window, int show); - int wx_iswindowvisible(void* window); - void* wx_getnativewindow(void* window); - void wx_callback(void* window, WX_CALLBACK callback, void* data); - void wx_togglewindow(void* window); - int wx_progressdialog(void* window, const char* title, const char* message, WX_CALLBACK callback, void* data, int range, volatile int *pos); +void wx_setwindowtitle(void *window, char *s); +int wx_sendmessage(void *window, int type, LONG_PARAM param1, LONG_PARAM param2); +void *wx_getdlgitem(void *window, int id); +void wx_setdlgitemtext(void *window, int id, char *str); +void wx_enablewindow(void *window, int enabled); +void wx_showwindow(void *window, int show); +int wx_iswindowvisible(void *window); +void *wx_getnativewindow(void *window); +void wx_callback(void *window, WX_CALLBACK callback, void *data); +void wx_togglewindow(void *window); +int wx_progressdialog(void *window, const char *title, const char *message, WX_CALLBACK callback, void *data, int range, + volatile int *pos); - void wx_enddialog(void* window, int ret_code); +void wx_enddialog(void *window, int ret_code); - int wx_dialogbox(void* window, const char* name, int(*callback)(void* window, int message, INT_PARAM param1, LONG_PARAM param2)); +int wx_dialogbox(void *window, const char *name, int (*callback)(void *window, int message, INT_PARAM param1, LONG_PARAM param2)); - void wx_exit(void* window, int value); - void wx_stop_emulation(void* window); - void wx_stop_emulation_now(void* window); +void wx_exit(void *window, int value); +void wx_stop_emulation(void *window); +void wx_stop_emulation_now(void *window); - void* wx_createtimer(void (*fn)()); - void wx_starttimer(void* timer, int milliseconds, int once); - void wx_stoptimer(void* timer); - void wx_destroytimer(void* timer); +void *wx_createtimer(void (*fn)()); +void wx_starttimer(void *timer, int milliseconds, int once); +void wx_stoptimer(void *timer); +void wx_destroytimer(void *timer); - void wx_popupmenu(void* window, void* menu, int* x, int* y); +void wx_popupmenu(void *window, void *menu, int *x, int *y); - void* wx_create_status_frame(void* window); - void wx_destroy_status_frame(void* window); +void *wx_create_status_frame(void *window); +void wx_destroy_status_frame(void *window); - int wx_yield(); +int wx_yield(); - void wx_setwindowposition(void* window, int x, int y); - void wx_setwindowsize(void* window, int width, int height); +void wx_setwindowposition(void *window, int x, int y); +void wx_setwindowsize(void *window, int width, int height); - void wx_show_status(void* window); - void wx_close_status(void* window); +void wx_show_status(void *window); +void wx_close_status(void *window); - void wx_get_home_directory(char* path); - int wx_create_directory(char* path); +void wx_get_home_directory(char *path); +int wx_create_directory(char *path); - int wx_setup(char* path); - int wx_file_exists(char* path); - int wx_dir_exists(char* path); - int wx_copy_file(char* from, char* to, int overwrite); +int wx_setup(char *path); +int wx_file_exists(char *path); +int wx_dir_exists(char *path); +int wx_copy_file(char *from, char *to, int overwrite); - void wx_date_format(char* s, const char* format); +void wx_date_format(char *s, const char *format); - int wx_image_save(const char* path, const char* name, const char* format, unsigned char* rgba, int width, int height, int alpha); +int wx_image_save(const char *path, const char *name, const char *format, unsigned char *rgba, int width, int height, int alpha); - void* wx_image_load(const char* path); - void wx_image_rescale(void* image, int width, int height); - void wx_image_get_size(void* image, int* width, int* height); - unsigned char* wx_image_get_data(void* image); - unsigned char* wx_image_get_alpha(void* image); - void wx_image_free(void* image); +void *wx_image_load(const char *path); +void wx_image_rescale(void *image, int width, int height); +void wx_image_get_size(void *image, int *width, int *height); +unsigned char *wx_image_get_data(void *image); +unsigned char *wx_image_get_alpha(void *image); +void wx_image_free(void *image); - void* wx_config_load(const char* path); - int wx_config_get_string(void* config, const char* name, char* dst, int size, const char* defVal); - int wx_config_get_int(void* config, const char* name, int* dst, int defVal); - int wx_config_get_float(void* config, const char* name, float* dst, float defVal); - int wx_config_get_bool(void* config, const char* name, int* dst, int defVal); - int wx_config_has_entry(void* config, const char* name); - void wx_config_free(void* config); +void *wx_config_load(const char *path); +int wx_config_get_string(void *config, const char *name, char *dst, int size, const char *defVal); +int wx_config_get_int(void *config, const char *name, int *dst, int defVal); +int wx_config_get_float(void *config, const char *name, float *dst, float defVal); +int wx_config_get_bool(void *config, const char *name, int *dst, int defVal); +int wx_config_has_entry(void *config, const char *name); +void wx_config_free(void *config); - int confirm(); +int confirm(); #ifdef _WIN32 - void wx_winsendmessage(void* window, int msg, INT_PARAM wParam, LONG_PARAM lParam); +void wx_winsendmessage(void *window, int msg, INT_PARAM wParam, LONG_PARAM lParam); #endif #ifdef __cplusplus } #endif -extern int (*wx_keydown_func)(void* window, void* event, int keycode, int modifiers); -extern int (*wx_keyup_func)(void* window, void* event, int keycode, int modifiers); -extern void (*wx_idle_func)(void* window, void* event); +extern int (*wx_keydown_func)(void *window, void *event, int keycode, int modifiers); +extern int (*wx_keyup_func)(void *window, void *event, int keycode, int modifiers); +extern void (*wx_idle_func)(void *window, void *event); #define WX_ID wx_xrcid @@ -163,8 +166,8 @@ extern void (*wx_idle_func)(void* window, void* event); #define WX_MB_YES wxYES #define WX_MB_OK wxOK -#define WX_MB_OKCANCEL wxOK|wxCANCEL -#define WX_MB_NODEFAULT wxYES_NO|wxNO_DEFAULT +#define WX_MB_OKCANCEL wxOK | wxCANCEL +#define WX_MB_NODEFAULT wxYES_NO | wxNO_DEFAULT #define WX_IDOK wxOK #define IMAGE_JPG "jpg" @@ -177,5 +180,4 @@ extern int has_been_inited; #define ID_IS(s) wParam == wx_xrcid(s) #define ID_RANGE(a, b) wParam >= wx_xrcid(a) && wParam <= wx_xrcid(b) - #endif /* _WX_UTILS_H_ */ diff --git a/includes/public/pcem/config.h b/includes/public/pcem/config.h index 5fe3e531..d4091425 100644 --- a/includes/public/pcem/config.h +++ b/includes/public/pcem/config.h @@ -4,7 +4,7 @@ #include #define CFG_MACHINE 0 -#define CFG_GLOBAL 1 +#define CFG_GLOBAL 1 extern float config_get_float(int is_global, char *head, char *name, float def); extern int config_get_int(int is_global, char *head, char *name, int def); @@ -13,6 +13,6 @@ extern void config_set_float(int is_global, char *head, char *name, float val); extern void config_set_int(int is_global, char *head, char *name, int val); extern void config_set_string(int is_global, char *head, char *name, char *val); extern int config_free_section(int is_global, char *head); -extern void add_config_callback(void(*loadconfig)(), void(*saveconfig)(), void(*onloaded)()); +extern void add_config_callback(void (*loadconfig)(), void (*saveconfig)(), void (*onloaded)()); #endif /* _PCEM_CONFIG_H_ */ diff --git a/includes/public/pcem/cpu.h b/includes/public/pcem/cpu.h index ef405ca8..71c7ebe4 100644 --- a/includes/public/pcem/cpu.h +++ b/includes/public/pcem/cpu.h @@ -4,26 +4,26 @@ #include typedef struct FPU { - const char *name; - const char *internal_name; - const int type; + const char *name; + const char *internal_name; + const int type; } FPU; typedef struct CPU { - char name[32]; - int cpu_type; - const FPU *fpus; - 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; + char name[32]; + int cpu_type; + const FPU *fpus; + 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 FPU fpus_none[]; diff --git a/includes/public/pcem/defines.h b/includes/public/pcem/defines.h index 5bcaa89e..8fb3e59b 100644 --- a/includes/public/pcem/defines.h +++ b/includes/public/pcem/defines.h @@ -2,13 +2,13 @@ #define _PCEM_DEFINES_H_ // Devices should never be more then DEV_MAX. -#define DEV_MAX 256 -#define ROM_MAX 256 -#define GFX_MAX 256 -#define SOUND_MAX 256 +#define DEV_MAX 256 +#define ROM_MAX 256 +#define GFX_MAX 256 +#define SOUND_MAX 256 #define HDDCONTROLLERS_MAX 256 -#define NETWORK_CARD_MAX 256 -#define LPT_MAX 256 -#define CALLBACK_MAX 256 +#define NETWORK_CARD_MAX 256 +#define LPT_MAX 256 +#define CALLBACK_MAX 256 #endif /* _PCEM_DEFINES_H_ */ diff --git a/includes/public/pcem/devices.h b/includes/public/pcem/devices.h index 116b4412..5dca197a 100644 --- a/includes/public/pcem/devices.h +++ b/includes/public/pcem/devices.h @@ -10,109 +10,109 @@ #define CONFIG_MIDI 4 enum { - DEVICE_NOT_WORKING = 1, /*Device does not currently work correctly and will be disabled in a release build*/ - DEVICE_AT = 2, /*Device requires an AT-compatible system*/ - DEVICE_MCA = 0x20, /*Device requires an MCA system*/ - DEVICE_PCI = 0x40, /*Device requires a PCI system*/ - DEVICE_PS1 = 0x80 /*Device is only for IBM PS/1 Model 2011*/ + DEVICE_NOT_WORKING = 1, /*Device does not currently work correctly and will be disabled in a release build*/ + DEVICE_AT = 2, /*Device requires an AT-compatible system*/ + DEVICE_MCA = 0x20, /*Device requires an MCA system*/ + DEVICE_PCI = 0x40, /*Device requires a PCI system*/ + DEVICE_PS1 = 0x80 /*Device is only for IBM PS/1 Model 2011*/ }; typedef struct device_config_selection_t { - char description[256]; - int value; + char description[256]; + int value; } device_config_selection_t; typedef struct device_config_t { - char name[256]; - char description[256]; - int type; - char default_string[256]; - int default_int; - device_config_selection_t selection[30]; + char name[256]; + char description[256]; + int type; + char default_string[256]; + int default_int; + device_config_selection_t selection[30]; } device_config_t; typedef struct device_t { - char name[50]; - uint32_t flags; - void *(*init)(); - void (*close)(void *p); - int (*available)(); - void (*speed_changed)(void *p); - void (*force_redraw)(void *p); - void (*add_status_info)(char *s, int max_len, void *p); - device_config_t *config; + char name[50]; + uint32_t flags; + void *(*init)(); + void (*close)(void *p); + int (*available)(); + void (*speed_changed)(void *p); + void (*force_redraw)(void *p); + void (*add_status_info)(char *s, int max_len, void *p); + device_config_t *config; } device_t; typedef struct SOUND_CARD { - char name[64]; - char internal_name[24]; - device_t *device; + char name[64]; + char internal_name[24]; + device_t *device; } SOUND_CARD; typedef struct video_timings_t { - int type; - int write_b, write_w, write_l; - int read_b, read_w, read_l; + int type; + int write_b, write_w, write_l; + int read_b, read_w, read_l; } video_timings_t; typedef struct VIDEO_CARD { - char name[64]; - char internal_name[24]; - device_t *device; - int legacy_id; - int flags; - video_timings_t timing; + char name[64]; + char internal_name[24]; + device_t *device; + int legacy_id; + int flags; + video_timings_t timing; } VIDEO_CARD; typedef struct MODEL { - char name[64]; - int id; - char internal_name[24]; - struct { - char name[8]; - CPU *cpus; - } cpu[5]; - int flags; - int min_ram, max_ram; - int ram_granularity; - void (*init)(); - struct device_t *device; + char name[64]; + int id; + char internal_name[24]; + struct { + char name[8]; + CPU *cpus; + } cpu[5]; + int flags; + int min_ram, max_ram; + int ram_granularity; + void (*init)(); + struct device_t *device; } MODEL; typedef struct HDD_CONTROLLER { - char name[50]; - char internal_name[16]; - device_t *device; - int is_mfm; - int is_ide; - int is_scsi; + char name[50]; + char internal_name[16]; + device_t *device; + int is_mfm; + int is_ide; + int is_scsi; } HDD_CONTROLLER; typedef struct NETWORK_CARD { - char name[32]; - char internal_name[24]; - device_t *device; + char name[32]; + char internal_name[24]; + device_t *device; } NETWORK_CARD; typedef struct lpt_device_t { - char name[50]; - uint32_t flags; - void *(*init)(); - void (*close)(void *p); - int (*available)(); - void (*speed_changed)(void *p); - void (*force_redraw)(void *p); - void (*add_status_info)(char *s, int max_len, void *p); - device_config_t *config; - void (*write_data)(uint8_t val, void *p); - void (*write_ctrl)(uint8_t val, void *p); - uint8_t (*read_status)(void *p); + char name[50]; + uint32_t flags; + void *(*init)(); + void (*close)(void *p); + int (*available)(); + void (*speed_changed)(void *p); + void (*force_redraw)(void *p); + void (*add_status_info)(char *s, int max_len, void *p); + device_config_t *config; + 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; typedef struct LPT_DEVICE { - char name[64]; - char internal_name[16]; - lpt_device_t *device; + char name[64]; + char internal_name[16]; + lpt_device_t *device; } LPT_DEVICE; extern void pcem_add_model(MODEL *model); diff --git a/includes/public/pcem/plugin.h b/includes/public/pcem/plugin.h index 559d18a8..b9b8af6b 100644 --- a/includes/public/pcem/plugin.h +++ b/includes/public/pcem/plugin.h @@ -2,13 +2,13 @@ #define _PCEM_PLUGIN_H_ #if defined(linux) -#define PLUGIN_INIT(name) \ - const char *plugin_name = #name; \ - void init_plugin() +#define PLUGIN_INIT(name) \ + const char *plugin_name = #name; \ + void init_plugin() #elif defined(WIN32) -#define PLUGIN_INIT(name) \ - const char *plugin_name = #name; \ - void __declspec(dllexport) __stdcall init_plugin() +#define PLUGIN_INIT(name) \ + const char *plugin_name = #name; \ + void __declspec(dllexport) __stdcall init_plugin() #endif #endif /* _PCEM_PLUGIN_H_ */ \ No newline at end of file diff --git a/src/bus/mca.c b/src/bus/mca.c index e60a2f0b..c2f740ce 100644 --- a/src/bus/mca.c +++ b/src/bus/mca.c @@ -12,59 +12,58 @@ static int mca_index; static int mca_nr_cards; void mca_init(int nr_cards) { - int c; + int c; - MCA = 1; + MCA = 1; - for (c = 0; c < 8; c++) { - mca_card_read[c] = NULL; - mca_card_write[c] = NULL; - mca_card_reset[c] = NULL; - mca_priv[c] = NULL; - } + for (c = 0; c < 8; c++) { + mca_card_read[c] = NULL; + mca_card_write[c] = NULL; + mca_card_reset[c] = NULL; + mca_priv[c] = NULL; + } - mca_index = 0; - mca_nr_cards = nr_cards; + mca_index = 0; + mca_nr_cards = nr_cards; } -void mca_set_index(int index) { - mca_index = index; -} +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]); + 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]); + 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_reset(void) { - int c; + int c; - for (c = 0; c < 8; c++) { - if (mca_card_reset[c]) - mca_card_reset[c](mca_priv[c]); - } + for (c = 0; c < 8; c++) { + if (mca_card_reset[c]) + mca_card_reset[c](mca_priv[c]); + } } -void mca_add(uint8_t (*read)(int addr, void *priv), void (*write)(int addr, uint8_t val, void *priv), void (*reset)(void *priv), void *priv) { - int c; +void mca_add(uint8_t (*read)(int addr, void *priv), void (*write)(int addr, uint8_t val, void *priv), void (*reset)(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_card_reset[c] = reset; - mca_priv[c] = priv; - return; - } - } + 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_card_reset[c] = reset; + mca_priv[c] = priv; + return; + } + } } diff --git a/src/bus/pci.c b/src/bus/pci.c index be6e63ae..a99f7102 100644 --- a/src/bus/pci.c +++ b/src/bus/pci.c @@ -18,185 +18,189 @@ static int pci_index, pci_func, pci_card, pci_bus, pci_enable, pci_key; int pci_burst_time, pci_nonburst_time; 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; + pci_index = val & 0xff; + pci_func = (val >> 8) & 7; + pci_card = (val >> 11) & 31; + pci_bus = (val >> 16) & 0xff; + pci_enable = (val >> 31) & 1; } 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); + return pci_index | (pci_func << 8) | (pci_card << 11) | (pci_bus << 16) | (pci_enable << 31); } void pci_write(uint16_t port, uint8_t val, void *priv) { -// pclog("pci_write: port=%04x val=%02x %08x:%08x\n", port, val, cs, pc); - switch (port) { - case 0xcfc: - case 0xcfd: - case 0xcfe: - case 0xcff: - if (!pci_enable) - return; + // pclog("pci_write: port=%04x val=%02x %08x:%08x\n", port, val, cs, pc); + switch (port) { + case 0xcfc: + case 0xcfd: + case 0xcfe: + case 0xcff: + if (!pci_enable) + return; -// pclog("PCI write bus %i card %i func %i index %02X val %02X %04X:%04X\n", pci_bus, pci_card, pci_func, pci_index | (port & 3), val, CS, pc); + // pclog("PCI write bus %i card %i func %i index %02X val %02X %04X:%04X\n", pci_bus, pci_card, + // pci_func, pci_index | (port & 3), val, CS, pc); - if (!pci_bus && pci_card_write[pci_card]) - pci_card_write[pci_card](pci_func, pci_index | (port & 3), val, pci_priv[pci_card]); + if (!pci_bus && pci_card_write[pci_card]) + pci_card_write[pci_card](pci_func, pci_index | (port & 3), val, pci_priv[pci_card]); - break; - } + break; + } } uint8_t pci_read(uint16_t port, void *priv) { -// pclog("pci_read: port=%04x %08x:%08x\n", port, cs, pc); - switch (port) { - case 0xcfc: - case 0xcfd: - case 0xcfe: - case 0xcff: - if (!pci_enable) - return 0xff; + // pclog("pci_read: port=%04x %08x:%08x\n", port, cs, pc); + switch (port) { + case 0xcfc: + case 0xcfd: + case 0xcfe: + case 0xcff: + if (!pci_enable) + return 0xff; -// pclog("PCI read bus %i card %i func %i index %02X\n", pci_bus, pci_card, pci_func, pci_index | (port & 3)); + // pclog("PCI read bus %i card %i func %i index %02X\n", pci_bus, pci_card, pci_func, pci_index | + // (port & 3)); - if (!pci_bus && pci_card_read[pci_card]) - return pci_card_read[pci_card](pci_func, pci_index | (port & 3), pci_priv[pci_card]); + if (!pci_bus && pci_card_read[pci_card]) + return pci_card_read[pci_card](pci_func, pci_index | (port & 3), pci_priv[pci_card]); - return 0xff; - } - return 0xff; + return 0xff; + } + return 0xff; } void pci_type2_write(uint16_t port, uint8_t val, void *priv); uint8_t pci_type2_read(uint16_t port, void *priv); void pci_type2_write(uint16_t port, uint8_t val, void *priv) { -// pclog("pci_type2_write: port=%04x val=%02x %08x:%08x\n", port, val, cs, pc); - 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; + // pclog("pci_type2_write: port=%04x val=%02x %08x:%08x\n", port, val, cs, pc); + 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; -// pclog("PCI write bus %i card %i func %i index %02X val %02X %04X:%04X\n", pci_bus, pci_card, pci_func, pci_index | (port & 3), val, CS, pc); + // pclog("PCI write bus %i card %i func %i index %02X val %02X %04X:%04X\n", pci_bus, pci_card, + // pci_func, pci_index | (port & 3), val, CS, pc); - if (!pci_bus && pci_card_write[pci_card]) - pci_card_write[pci_card](pci_func, pci_index | (port & 3), val, pci_priv[pci_card]); - } + if (!pci_bus && pci_card_write[pci_card]) + pci_card_write[pci_card](pci_func, pci_index | (port & 3), val, pci_priv[pci_card]); + } } uint8_t pci_type2_read(uint16_t port, void *priv) { -// pclog("pci_type2_read: port=%04x %08x:%08x\n", port, cs, pc); - 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; + // pclog("pci_type2_read: port=%04x %08x:%08x\n", port, cs, pc); + 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; -// pclog("PCI read bus %i card %i func %i index %02X %04X:%04X\n", pci_bus, pci_card, pci_func, pci_index | (port & 3), CS, pc); + // pclog("PCI read bus %i card %i func %i index %02X %04X:%04X\n", pci_bus, pci_card, + // pci_func, pci_index | (port & 3), CS, pc); - if (!pci_bus && pci_card_write[pci_card]) - return pci_card_read[pci_card](pci_func, pci_index | (port & 3), pci_priv[pci_card]); - } - return 0xff; + if (!pci_bus && pci_card_write[pci_card]) + return pci_card_read[pci_card](pci_func, pci_index | (port & 3), pci_priv[pci_card]); + } + return 0xff; } void pci_set_irq_routing(int pci_int, int irq) { - pci_irqs[pci_int - 1] = irq; -// pclog("pci_set_irq_routing: pci_int=%i irq=%i\n", pci_int, irq); + pci_irqs[pci_int - 1] = irq; + // pclog("pci_set_irq_routing: pci_int=%i irq=%i\n", pci_int, irq); } void pci_set_card_routing(int card, int pci_int) { - pci_irq_routing[card] = pci_int; -// pclog("pci_irq_routing: card=%i pci_int=%i\n", card, pci_int); + pci_irq_routing[card] = pci_int; + // pclog("pci_irq_routing: card=%i pci_int=%i\n", card, pci_int); } void pci_set_irq(int card, int pci_int) { -// pclog("pci_set_irq: card=%i irq_routing=%i\n", card, pci_irq_routing[card]); - if (pci_irq_routing[card]) { - int irq = ((pci_int - PCI_INTA) + (pci_irq_routing[card] - PCI_INTA)) & 3; -// pclog(" irq=%i pci_irqs=%i active=%i\n", irq, pci_irqs[irq], pci_irq_active[card]); - if (pci_irqs[irq] != PCI_IRQ_DISABLED && !pci_irq_active[card]) - picint(1 << pci_irqs[irq]); - pci_irq_active[card] = 1; - } + // pclog("pci_set_irq: card=%i irq_routing=%i\n", card, pci_irq_routing[card]); + if (pci_irq_routing[card]) { + int irq = ((pci_int - PCI_INTA) + (pci_irq_routing[card] - PCI_INTA)) & 3; + // pclog(" irq=%i pci_irqs=%i active=%i\n", irq, pci_irqs[irq], pci_irq_active[card]); + if (pci_irqs[irq] != PCI_IRQ_DISABLED && !pci_irq_active[card]) + picint(1 << pci_irqs[irq]); + pci_irq_active[card] = 1; + } } void pci_clear_irq(int card, int pci_int) { -// pclog("pci_clear_irq: card=%i irq_routing=%i\n", card, pci_irq_routing[card]); - if (pci_irq_routing[card]) { - int irq = ((pci_int - PCI_INTA) + (pci_irq_routing[card] - PCI_INTA)) & 3; -// pclog(" irq=%i pci_irqs=%i active=%i\n", irq, pci_irqs[irq], pci_irq_active[card]); - if (pci_irqs[irq] != PCI_IRQ_DISABLED && pci_irq_active[card]) - picintc(1 << pci_irqs[irq]); - pci_irq_active[card] = 0; - } + // pclog("pci_clear_irq: card=%i irq_routing=%i\n", card, pci_irq_routing[card]); + if (pci_irq_routing[card]) { + int irq = ((pci_int - PCI_INTA) + (pci_irq_routing[card] - PCI_INTA)) & 3; + // pclog(" irq=%i pci_irqs=%i active=%i\n", irq, pci_irqs[irq], pci_irq_active[card]); + if (pci_irqs[irq] != PCI_IRQ_DISABLED && pci_irq_active[card]) + picintc(1 << pci_irqs[irq]); + pci_irq_active[card] = 0; + } } void pci_init(int type) { - int c; + int c; - PCI = 1; + PCI = 1; - 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); - } + 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 < 32; c++) { - pci_card_read[c] = NULL; - pci_card_write[c] = NULL; - pci_priv[c] = NULL; - pci_irq_routing[c] = 0; - pci_irq_active[c] = 0; - pci_card_valid[c] = 0; - } + for (c = 0; c < 32; c++) { + pci_card_read[c] = NULL; + pci_card_write[c] = NULL; + pci_priv[c] = NULL; + pci_irq_routing[c] = 0; + pci_irq_active[c] = 0; + pci_card_valid[c] = 0; + } - for (c = 0; c < 4; c++) - pci_irqs[c] = PCI_IRQ_DISABLED; + for (c = 0; c < 4; c++) + pci_irqs[c] = PCI_IRQ_DISABLED; } -void pci_slot(int card) { - pci_card_valid[card] = 1; +void pci_slot(int card) { pci_card_valid[card] = 1; } + +void pci_add_specific(int card, uint8_t (*read)(int func, int addr, void *priv), + void (*write)(int func, int addr, uint8_t val, void *priv), void *priv) { + pci_card_read[card] = read; + pci_card_write[card] = write; + pci_priv[card] = priv; } -void pci_add_specific(int card, uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv) { - pci_card_read[card] = read; - pci_card_write[card] = write; - pci_priv[card] = priv; -} - -int pci_add(uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv) { - int c; - - if (!PCI) - return -1; - - for (c = 0; c < 32; c++) { - if (pci_card_valid[c] && !pci_card_read[c] && !pci_card_write[c]) { - pci_card_read[c] = read; - pci_card_write[c] = write; - pci_priv[c] = priv; - return c; - } - } - - if (current_device_name) - warning("Failed to initialise PCI device '%s' due to insufficient available slots", current_device_name); - else - warning("Failed to initialise PCI device due to insufficient available slots"); - return -1; +int pci_add(uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), + void *priv) { + int c; + + if (!PCI) + return -1; + + for (c = 0; c < 32; c++) { + if (pci_card_valid[c] && !pci_card_read[c] && !pci_card_write[c]) { + pci_card_read[c] = read; + pci_card_write[c] = write; + pci_priv[c] = priv; + return c; + } + } + + if (current_device_name) + warning("Failed to initialise PCI device '%s' due to insufficient available slots", current_device_name); + else + warning("Failed to initialise PCI device due to insufficient available slots"); + return -1; } diff --git a/src/cdrom/cdrom-image.cc b/src/cdrom/cdrom-image.cc index 4f8e6426..875115be 100644 --- a/src/cdrom/cdrom-image.cc +++ b/src/cdrom/cdrom-image.cc @@ -2,8 +2,7 @@ #include "cdrom-image.h" #include "dosbox/cdrom.h" -extern "C" -{ +extern "C" { #include "ibm.h" #include "ide.h" } @@ -15,15 +14,11 @@ extern ATAPI image_atapi; CDROM_Interface_Image *cdrom = NULL; -#define MSFtoLBA(m, s, f) (((((m*60)+s)*75)+f)) +#define MSFtoLBA(m, s, f) (((((m * 60) + s) * 75) + f)) static uint32_t cdrom_capacity = 0; -enum { - CD_STOPPED = 0, - CD_PLAYING, - CD_PAUSED -}; +enum { CD_STOPPED = 0, CD_PLAYING, CD_PAUSED }; static int image_cd_state = CD_STOPPED; static uint32_t image_cd_pos = 0, image_cd_end = 0; @@ -33,474 +28,473 @@ static int16_t cd_buffer[BUF_SIZE]; static int cd_buflen = 0; void image_audio_callback(int16_t *output, int len) { - if (image_cd_state != CD_PLAYING) - return; - while (cd_buflen < len) { - if (image_cd_pos < image_cd_end) { -// pclog("Read to %i\n", cd_buflen); - if (!cdrom->ReadSector((unsigned char *)&cd_buffer[cd_buflen], true, image_cd_pos - 150)) { -// pclog("DeviceIoControl returned false\n"); - memset(&cd_buffer[cd_buflen], 0, (BUF_SIZE - cd_buflen) * 2); - image_cd_state = CD_STOPPED; - cd_buflen = len; - } else { -// pclog("DeviceIoControl returned true\n"); - image_cd_pos++; - cd_buflen += (RAW_SECTOR_SIZE / 2); - } - } else { - memset(&cd_buffer[cd_buflen], 0, (BUF_SIZE - cd_buflen) * 2); - image_cd_state = CD_STOPPED; - cd_buflen = len; - } - } - memcpy(output, cd_buffer, len * 2); - memmove(cd_buffer, &cd_buffer[len], (BUF_SIZE - len) * 2); - cd_buflen -= len; + if (image_cd_state != CD_PLAYING) + return; + while (cd_buflen < len) { + if (image_cd_pos < image_cd_end) { + // pclog("Read to %i\n", cd_buflen); + if (!cdrom->ReadSector((unsigned char *)&cd_buffer[cd_buflen], true, image_cd_pos - 150)) { + // pclog("DeviceIoControl returned false\n"); + memset(&cd_buffer[cd_buflen], 0, (BUF_SIZE - cd_buflen) * 2); + image_cd_state = CD_STOPPED; + cd_buflen = len; + } else { + // pclog("DeviceIoControl returned true\n"); + image_cd_pos++; + cd_buflen += (RAW_SECTOR_SIZE / 2); + } + } else { + memset(&cd_buffer[cd_buflen], 0, (BUF_SIZE - cd_buflen) * 2); + image_cd_state = CD_STOPPED; + cd_buflen = len; + } + } + memcpy(output, cd_buffer, len * 2); + memmove(cd_buffer, &cd_buffer[len], (BUF_SIZE - len) * 2); + cd_buflen -= len; } -void image_audio_stop() { - image_cd_state = CD_STOPPED; -} +void image_audio_stop() { image_cd_state = CD_STOPPED; } static int image_is_track_audio(uint32_t pos, int ismsf) { - if (!cdrom) - return 0; - if (ismsf) { - int m = (pos >> 16) & 0xff; - int s = (pos >> 8) & 0xff; - int f = pos & 0xff; - pos = MSF_TO_FRAMES(m, s, f); - } + if (!cdrom) + return 0; + if (ismsf) { + int m = (pos >> 16) & 0xff; + int s = (pos >> 8) & 0xff; + int f = pos & 0xff; + pos = MSF_TO_FRAMES(m, s, f); + } - unsigned char attr; - TMSF tmsf; - int number; - cdrom->GetAudioTrackInfo(cdrom->GetTrack(pos), number, tmsf, attr); + unsigned char attr; + TMSF tmsf; + int number; + cdrom->GetAudioTrackInfo(cdrom->GetTrack(pos), number, tmsf, attr); - return attr == AUDIO_TRACK; + return attr == AUDIO_TRACK; } static void image_playaudio(uint32_t pos, uint32_t len, int ismsf) { - if (!cdrom) - return; - int number; - unsigned char attr; - TMSF tmsf; - cdrom->GetAudioTrackInfo(cdrom->GetTrack(pos), number, tmsf, attr); - if (attr == DATA_TRACK) { - pclog("Can't play data track\n"); - image_cd_pos = 0; - image_cd_state = CD_STOPPED; - return; - } - pclog("Play audio - %08X %08X %i\n", pos, len, ismsf); - if (ismsf) { - int m, s, f; - m = (pos >> 16) & 0xff; - s = (pos >> 8) & 0xff; - f = pos & 0xff; - pos = MSFtoLBA(m, s, f); + if (!cdrom) + return; + int number; + unsigned char attr; + TMSF tmsf; + cdrom->GetAudioTrackInfo(cdrom->GetTrack(pos), number, tmsf, attr); + if (attr == DATA_TRACK) { + pclog("Can't play data track\n"); + image_cd_pos = 0; + image_cd_state = CD_STOPPED; + return; + } + pclog("Play audio - %08X %08X %i\n", pos, len, ismsf); + if (ismsf) { + int m, s, f; + m = (pos >> 16) & 0xff; + s = (pos >> 8) & 0xff; + f = pos & 0xff; + pos = MSFtoLBA(m, s, f); - m = (len >> 16) & 0xff; - s = (len >> 8) & 0xff; - f = len & 0xff; - len = MSFtoLBA(m, s, f); + m = (len >> 16) & 0xff; + s = (len >> 8) & 0xff; + f = len & 0xff; + len = MSFtoLBA(m, s, f); - pclog("MSF - pos = %08X len = %08X\n", pos, len); - } else - len += pos; - image_cd_pos = pos;// + 150; - image_cd_end = len;// + 150; - image_cd_state = CD_PLAYING; - if (image_cd_pos < 150) - image_cd_pos = 150; - cd_buflen = 0; - pclog("Audio start %08X %08X %i %i %i\n", image_cd_pos, image_cd_end, image_cd_state, cd_buflen, len); + pclog("MSF - pos = %08X len = %08X\n", pos, len); + } else + len += pos; + image_cd_pos = pos; // + 150; + image_cd_end = len; // + 150; + image_cd_state = CD_PLAYING; + if (image_cd_pos < 150) + image_cd_pos = 150; + cd_buflen = 0; + pclog("Audio start %08X %08X %i %i %i\n", image_cd_pos, image_cd_end, image_cd_state, cd_buflen, len); } static void image_pause(void) { - if (!cdrom) - return; - if (image_cd_state == CD_PLAYING) - image_cd_state = CD_PAUSED; + if (!cdrom) + return; + if (image_cd_state == CD_PLAYING) + image_cd_state = CD_PAUSED; } static void image_resume(void) { - if (!cdrom) - return; - if (image_cd_state == CD_PAUSED) - image_cd_state = CD_PLAYING; + if (!cdrom) + return; + if (image_cd_state == CD_PAUSED) + image_cd_state = CD_PLAYING; } static void image_stop(void) { - if (!cdrom) - return; - image_cd_state = CD_STOPPED; + if (!cdrom) + return; + image_cd_state = CD_STOPPED; } static void image_seek(uint32_t pos) { - if (!cdrom) - return; - image_cd_pos = pos; - image_cd_state = CD_STOPPED; + if (!cdrom) + return; + image_cd_pos = pos; + image_cd_state = CD_STOPPED; } static int image_ready(void) { - if (!cdrom) - return 0; + if (!cdrom) + return 0; - if (strlen(image_path) == 0) - return 0; + if (strlen(image_path) == 0) + return 0; - if (image_changed) - image_changed = 0; + if (image_changed) + image_changed = 0; - return 1; + return 1; } static int image_get_last_block(unsigned char starttrack, int msf, int maxlen, int single) { - int c; - uint32_t lb = 0; + int c; + uint32_t lb = 0; - if (!cdrom) - return 0; + if (!cdrom) + return 0; - int first_track; - int last_track; - int number; - unsigned char attr; - TMSF tmsf; - cdrom->GetAudioTracks(first_track, last_track, tmsf); + int first_track; + int last_track; + int number; + unsigned char attr; + TMSF tmsf; + cdrom->GetAudioTracks(first_track, last_track, tmsf); - for (c = 0; c <= last_track; c++) { - uint32_t address; - cdrom->GetAudioTrackInfo(c + 1, number, tmsf, attr); - address = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr) - 150; - if (address > lb) - lb = address; - } - return lb; + for (c = 0; c <= last_track; c++) { + uint32_t address; + cdrom->GetAudioTrackInfo(c + 1, number, tmsf, attr); + address = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr) - 150; + if (address > lb) + lb = address; + } + return lb; } static int image_medium_changed(void) { - if (!cdrom) - return 0; + if (!cdrom) + return 0; - if (strlen(image_path) == 0) - return 0; + if (strlen(image_path) == 0) + return 0; - if (old_cdrom_drive != cdrom_drive) { - old_cdrom_drive = cdrom_drive; - return 1; - } + if (old_cdrom_drive != cdrom_drive) { + old_cdrom_drive = cdrom_drive; + return 1; + } - if (image_changed) { - image_changed = 0; - return 1; - } - return 0; + if (image_changed) { + image_changed = 0; + return 1; + } + return 0; } static uint8_t image_getcurrentsubchannel(uint8_t *b, int msf) { - if (!cdrom) - return 0; - uint8_t ret; - int pos = 0; + if (!cdrom) + return 0; + uint8_t ret; + int pos = 0; - uint32_t cdpos = image_cd_pos; - if (cdpos >= 150) - cdpos -= 150; - TMSF relPos, absPos; - unsigned char attr, track, index; - cdrom->GetAudioSub(cdpos, attr, track, index, relPos, absPos); + uint32_t cdpos = image_cd_pos; + if (cdpos >= 150) + cdpos -= 150; + TMSF relPos, absPos; + unsigned char attr, track, index; + cdrom->GetAudioSub(cdpos, attr, track, index, relPos, absPos); - if (image_cd_state == CD_PLAYING) - ret = 0x11; - else if (image_cd_state == CD_PAUSED) - ret = 0x12; - else - ret = 0x13; + if (image_cd_state == CD_PLAYING) + ret = 0x11; + else if (image_cd_state == CD_PAUSED) + ret = 0x12; + else + ret = 0x13; - b[pos++] = attr; - b[pos++] = track; - b[pos++] = index; + b[pos++] = attr; + b[pos++] = track; + b[pos++] = index; - if (msf) { - uint32_t dat = MSFtoLBA(absPos.min, absPos.sec, absPos.fr); - b[pos + 3] = (uint8_t)(dat % 75); - dat /= 75; - b[pos + 2] = (uint8_t)(dat % 60); - dat /= 60; - b[pos + 1] = (uint8_t)dat; - b[pos] = 0; - pos += 4; - dat = MSFtoLBA(relPos.min, relPos.sec, relPos.fr); - b[pos + 3] = (uint8_t)(dat % 75); - dat /= 75; - b[pos + 2] = (uint8_t)(dat % 60); - dat /= 60; - b[pos + 1] = (uint8_t)dat; - b[pos] = 0; - pos += 4; - } else { - uint32_t dat = MSFtoLBA(absPos.min, absPos.sec, absPos.fr); - 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; - } + if (msf) { + uint32_t dat = MSFtoLBA(absPos.min, absPos.sec, absPos.fr); + b[pos + 3] = (uint8_t)(dat % 75); + dat /= 75; + b[pos + 2] = (uint8_t)(dat % 60); + dat /= 60; + b[pos + 1] = (uint8_t)dat; + b[pos] = 0; + pos += 4; + dat = MSFtoLBA(relPos.min, relPos.sec, relPos.fr); + b[pos + 3] = (uint8_t)(dat % 75); + dat /= 75; + b[pos + 2] = (uint8_t)(dat % 60); + dat /= 60; + b[pos + 1] = (uint8_t)dat; + b[pos] = 0; + pos += 4; + } else { + uint32_t dat = MSFtoLBA(absPos.min, absPos.sec, absPos.fr); + 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; + return ret; } -static void image_eject(void) { -} +static void image_eject(void) {} -static void image_load(void) { -} +static void image_load(void) {} static int image_readsector(uint8_t *b, int sector, int count) { - if (!cdrom) - return -1; - return !cdrom->ReadSectors((PhysPt)b, false, sector, count); + if (!cdrom) + return -1; + return !cdrom->ReadSectors((PhysPt)b, false, sector, count); } static void image_readsector_raw(uint8_t *b, int sector) { - if (!cdrom) - return; - cdrom->ReadSector(b, true, sector); + if (!cdrom) + return; + cdrom->ReadSector(b, true, sector); } static int image_readtoc(unsigned char *b, unsigned char starttrack, int msf, int maxlen, int single) { - if (!cdrom) - return 0; - int len = 4; - int c, d; - uint32_t temp; + if (!cdrom) + return 0; + int len = 4; + int c, d; + uint32_t temp; - int first_track; - int last_track; - int number; - unsigned char attr; - TMSF tmsf; - cdrom->GetAudioTracks(first_track, last_track, tmsf); + int first_track; + int last_track; + int number; + unsigned char attr; + TMSF tmsf; + cdrom->GetAudioTracks(first_track, last_track, tmsf); - b[2] = first_track; - b[3] = last_track; + b[2] = first_track; + b[3] = last_track; - d = 0; - for (c = 0; c <= last_track; c++) { - cdrom->GetAudioTrackInfo(c + 1, number, tmsf, attr); - if (number >= starttrack) { - d = c; - break; - } - } - cdrom->GetAudioTrackInfo(c + 1, number, tmsf, attr); - b[2] = number; + d = 0; + for (c = 0; c <= last_track; c++) { + cdrom->GetAudioTrackInfo(c + 1, number, tmsf, attr); + if (number >= starttrack) { + d = c; + break; + } + } + cdrom->GetAudioTrackInfo(c + 1, number, tmsf, attr); + b[2] = number; - for (c = d; c <= last_track; c++) { - if ((len + 8) > maxlen) - break; - cdrom->GetAudioTrackInfo(c + 1, number, tmsf, attr); + for (c = d; c <= last_track; c++) { + if ((len + 8) > maxlen) + break; + cdrom->GetAudioTrackInfo(c + 1, number, tmsf, attr); -// pclog("Len %i max %i Track %02X - %02X %02X %02i:%02i:%02i %08X\n",len,maxlen,toc[c].cdte_track,toc[c].cdte_adr,toc[c].cdte_ctrl,toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame,MSFtoLBA(toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame)); - b[len++] = 0; /* reserved */ - b[len++] = attr; - b[len++] = number; /* track number */ - b[len++] = 0; /* reserved */ + // pclog("Len %i max %i Track %02X - %02X %02X %02i:%02i:%02i + // %08X\n",len,maxlen,toc[c].cdte_track,toc[c].cdte_adr,toc[c].cdte_ctrl,toc[c].cdte_addr.msf.minute, + // toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame,MSFtoLBA(toc[c].cdte_addr.msf.minute, + // toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame)); + 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); - /* - pclog("Table of Contents:\n"); - pclog("First track - %02X\n", first_track); - pclog("Last track - %02X\n", last_track); - for (c = 0; c <= last_track; c++) - { - cdrom->GetAudioTrackInfo(c+1, number, tmsf, attr); - pclog("Track %02X - number %02X control %02X adr %02X address %02X %02X %02X %02X\n", c, number, attr, 0, 0, tmsf.min, tmsf.sec, tmsf.fr); - } - for (c = 0;c <= last_track; c++) { - cdrom->GetAudioTrackInfo(c+1, number, tmsf, attr); - pclog("Track %02X - number %02X control %02X adr %02X address %06X\n", c, number, attr, 0, MSF_TO_FRAMES(tmsf.min, tmsf.sec, tmsf.fr)); - } - */ - return len; + 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); + /* + pclog("Table of Contents:\n"); + pclog("First track - %02X\n", first_track); + pclog("Last track - %02X\n", last_track); + for (c = 0; c <= last_track; c++) + { + cdrom->GetAudioTrackInfo(c+1, number, tmsf, attr); + pclog("Track %02X - number %02X control %02X adr %02X address %02X %02X %02X %02X\n", c, number, attr, 0, 0, + tmsf.min, tmsf.sec, tmsf.fr); + } + for (c = 0;c <= last_track; c++) { + cdrom->GetAudioTrackInfo(c+1, number, tmsf, attr); + pclog("Track %02X - number %02X control %02X adr %02X address %06X\n", c, number, attr, 0, MSF_TO_FRAMES(tmsf.min, + tmsf.sec, tmsf.fr)); + } + */ + return len; } static int image_readtoc_session(unsigned char *b, int msf, int maxlen) { - if (!cdrom) - return 0; - int len = 4; + if (!cdrom) + return 0; + int len = 4; - int number; - TMSF tmsf; - unsigned char attr; - cdrom->GetAudioTrackInfo(1, number, tmsf, attr); + int number; + TMSF tmsf; + unsigned char attr; + cdrom->GetAudioTrackInfo(1, number, tmsf, attr); -// pclog("Read TOC session - %i %02X %02X %i %i %02X %02X %02X\n",0, 0, 0,1,1,attr,0,number); + // pclog("Read TOC session - %i %02X %02X %i %i %02X %02X %02X\n",0, 0, 0,1,1,attr,0,number); - b[2] = 1; - 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 { - uint32_t temp = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr) - 150; - b[len++] = temp >> 24; - b[len++] = temp >> 16; - b[len++] = temp >> 8; - b[len++] = temp; - } + b[2] = 1; + 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 { + uint32_t temp = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr) - 150; + b[len++] = temp >> 24; + b[len++] = temp >> 16; + b[len++] = temp >> 8; + b[len++] = temp; + } - return len; + return len; } static int image_readtoc_raw(unsigned char *b, int maxlen) { - if (!cdrom) - return 0; + if (!cdrom) + return 0; - int track; - int len = 4; + int track; + int len = 4; - int first_track; - int last_track; - int number; - unsigned char attr; - TMSF tmsf; - cdrom->GetAudioTracks(first_track, last_track, tmsf); + int first_track; + int last_track; + int number; + unsigned char attr; + TMSF tmsf; + cdrom->GetAudioTracks(first_track, last_track, tmsf); - b[2] = first_track; - b[3] = last_track; + b[2] = first_track; + b[3] = last_track; - for (track = first_track; track <= last_track; track++) { - if ((len + 11) > maxlen) { - pclog("image_readtocraw: This iteration would fill the buffer beyond the bounds, aborting...\n"); - return len; - } + for (track = first_track; track <= last_track; track++) { + if ((len + 11) > maxlen) { + pclog("image_readtocraw: This iteration would fill the buffer beyond the bounds, aborting...\n"); + return len; + } - cdrom->GetAudioTrackInfo(track, number, tmsf, attr); + cdrom->GetAudioTrackInfo(track, number, tmsf, attr); -// pclog("read_toc: Track %02X - number %02X control %02X adr %02X address %02X %02X %02X %02X\n", track, toc[track].cdte_track, toc[track].cdte_ctrl, toc[track].cdte_adr, 0, toc[track].cdte_addr.msf.minute, toc[track].cdte_addr.msf.second, toc[track].cdte_addr.msf.frame); + // pclog("read_toc: Track %02X - number %02X control %02X adr %02X address %02X %02X %02X %02X\n", + // track, toc[track].cdte_track, toc[track].cdte_ctrl, toc[track].cdte_adr, 0, + // toc[track].cdte_addr.msf.minute, toc[track].cdte_addr.msf.second, toc[track].cdte_addr.msf.frame); - 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; + 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 uint32_t image_size() { - return cdrom_capacity; -} +static uint32_t image_size() { return cdrom_capacity; } static int image_status() { - if (!cdrom) - return CD_STATUS_EMPTY; - if (cdrom->HasAudioTracks()) { - switch (image_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() { + if (!cdrom) + return CD_STATUS_EMPTY; + if (cdrom->HasAudioTracks()) { + switch (image_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() {} void image_close(void) { - image_cd_state = CD_STOPPED; - if (cdrom) { - delete cdrom; - cdrom = NULL; - } -// memset(image_path, 0, 1024); + image_cd_state = CD_STOPPED; + if (cdrom) { + delete cdrom; + cdrom = NULL; + } + // memset(image_path, 0, 1024); } int image_open(char *fn) { - if (strcmp(fn, image_path) != 0) - image_changed = 1; + if (strcmp(fn, image_path) != 0) + image_changed = 1; - /* Make sure image_changed stays when changing from an image to another image. */ - if (cdrom_drive != CDROM_IMAGE) - image_changed = 1; - /* strcpy fails on OSX if both parameters are pointing to the same address */ - if (image_path != fn) - strcpy(image_path, fn); + /* Make sure image_changed stays when changing from an image to another image. */ + if (cdrom_drive != CDROM_IMAGE) + image_changed = 1; + /* strcpy fails on OSX if both parameters are pointing to the same address */ + if (image_path != fn) + strcpy(image_path, fn); - cdrom = new CDROM_Interface_Image(); - if (!cdrom->SetDevice(fn, false)) { - image_close(); - return 1; - } - image_cd_state = CD_STOPPED; - image_cd_pos = 0; - cd_buflen = 0; - cdrom_capacity = image_get_last_block(0, 0, 4096, 0) + 1; - atapi = &image_atapi; - return 0; + cdrom = new CDROM_Interface_Image(); + if (!cdrom->SetDevice(fn, false)) { + image_close(); + return 1; + } + image_cd_state = CD_STOPPED; + image_cd_pos = 0; + cd_buflen = 0; + cdrom_capacity = image_get_last_block(0, 0, 4096, 0) + 1; + atapi = &image_atapi; + return 0; } -static void image_exit(void) { -} +static void image_exit(void) {} -ATAPI image_atapi = - { - image_ready, - image_medium_changed, - image_readtoc, - image_readtoc_session, - image_readtoc_raw, - image_getcurrentsubchannel, - image_readsector, - image_readsector_raw, - image_playaudio, - image_seek, - image_load, - image_eject, - image_pause, - image_resume, - image_size, - image_status, - image_is_track_audio, - image_stop, - image_exit - }; +ATAPI image_atapi = {image_ready, + image_medium_changed, + image_readtoc, + image_readtoc_session, + image_readtoc_raw, + image_getcurrentsubchannel, + image_readsector, + image_readsector_raw, + image_playaudio, + image_seek, + image_load, + image_eject, + image_pause, + image_resume, + image_size, + image_status, + image_is_track_audio, + image_stop, + image_exit}; diff --git a/src/cdrom/cdrom-ioctl-dummy.c b/src/cdrom/cdrom-ioctl-dummy.c index 92b30203..c904e912 100644 --- a/src/cdrom/cdrom-ioctl-dummy.c +++ b/src/cdrom/cdrom-ioctl-dummy.c @@ -4,21 +4,14 @@ int old_cdrom_drive; -void ioctl_audio_callback(int16_t *output, int len) { -} +void ioctl_audio_callback(int16_t *output, int len) {} -void ioctl_audio_stop() { -} +void ioctl_audio_stop() {} -void ioctl_reset() { -} +void ioctl_reset() {} -void ioctl_set_drive(char d) { -} +void ioctl_set_drive(char d) {} -int ioctl_open(char d) { - return 0; -} +int ioctl_open(char d) { return 0; } -void ioctl_close(void) { -} +void ioctl_close(void) {} diff --git a/src/cdrom/cdrom-ioctl-linux.c b/src/cdrom/cdrom-ioctl-linux.c index 3f2afd72..ff9c7c15 100644 --- a/src/cdrom/cdrom-ioctl-linux.c +++ b/src/cdrom/cdrom-ioctl-linux.c @@ -22,13 +22,9 @@ static int ioctl_fd = 0; int old_cdrom_drive; -#define MSFtoLBA(m, s, f) (((((m*60)+s)*75)+f)-150) +#define MSFtoLBA(m, s, f) (((((m * 60) + s) * 75) + f) - 150) -enum { - CD_STOPPED = 0, - CD_PLAYING, - CD_PAUSED -}; +enum { CD_STOPPED = 0, CD_PLAYING, CD_PAUSED }; static int ioctl_cd_state = CD_STOPPED; static uint32_t ioctl_cd_pos = 0, ioctl_cd_end = 0; @@ -36,610 +32,610 @@ static uint32_t ioctl_cd_pos = 0, ioctl_cd_end = 0; static int16_t cd_buffer[BUF_SIZE]; static int cd_buflen = 0; void ioctl_audio_callback(int16_t *output, int len) { - struct cdrom_read_audio read_audio; + struct cdrom_read_audio read_audio; -// pclog("Audio callback %08X %08X %i %i %i %04X %i\n", ioctl_cd_pos, ioctl_cd_end, ioctl_cd_state, cd_buflen, len, cd_buffer[4], GetTickCount()); - if (ioctl_cd_state != CD_PLAYING) { - memset(output, 0, len * 2); - return; - } + // pclog("Audio callback %08X %08X %i %i %i %04X %i\n", ioctl_cd_pos, ioctl_cd_end, ioctl_cd_state, cd_buflen, len, + // cd_buffer[4], GetTickCount()); + if (ioctl_cd_state != CD_PLAYING) { + memset(output, 0, len * 2); + return; + } - if (ioctl_fd <= 0) { - memset(output, 0, len * 2); - return; - } + if (ioctl_fd <= 0) { + memset(output, 0, len * 2); + return; + } - while (cd_buflen < len) { - if (ioctl_cd_pos < ioctl_cd_end) { - read_audio.addr.lba = ioctl_cd_pos - 150; - read_audio.addr_format = CDROM_LBA; - read_audio.nframes = 1; - read_audio.buf = (__u8 * ) & cd_buffer[cd_buflen]; + while (cd_buflen < len) { + if (ioctl_cd_pos < ioctl_cd_end) { + read_audio.addr.lba = ioctl_cd_pos - 150; + read_audio.addr_format = CDROM_LBA; + read_audio.nframes = 1; + read_audio.buf = (__u8 *)&cd_buffer[cd_buflen]; - if (ioctl(ioctl_fd, CDROMREADAUDIO, &read_audio) < 0) { -// pclog("DeviceIoControl returned false\n"); - memset(&cd_buffer[cd_buflen], 0, (BUF_SIZE - cd_buflen) * 2); - ioctl_cd_state = CD_STOPPED; - cd_buflen = len; - } else { -// pclog("DeviceIoControl returned true\n"); - ioctl_cd_pos++; - cd_buflen += (2352 / 2); - } - } else { - memset(&cd_buffer[cd_buflen], 0, (BUF_SIZE - cd_buflen) * 2); - ioctl_cd_state = CD_STOPPED; - cd_buflen = len; - } - } + if (ioctl(ioctl_fd, CDROMREADAUDIO, &read_audio) < 0) { + // pclog("DeviceIoControl returned false\n"); + memset(&cd_buffer[cd_buflen], 0, (BUF_SIZE - cd_buflen) * 2); + ioctl_cd_state = CD_STOPPED; + cd_buflen = len; + } else { + // pclog("DeviceIoControl returned true\n"); + ioctl_cd_pos++; + cd_buflen += (2352 / 2); + } + } else { + memset(&cd_buffer[cd_buflen], 0, (BUF_SIZE - cd_buflen) * 2); + ioctl_cd_state = CD_STOPPED; + cd_buflen = len; + } + } - memcpy(output, cd_buffer, len * 2); -// for (c = 0; c < BUF_SIZE - len; c++) -// cd_buffer[c] = cd_buffer[c + cd_buflen]; - memcpy(&cd_buffer[0], &cd_buffer[len], (BUF_SIZE - len) * 2); - cd_buflen -= len; -// pclog("Done %i\n", GetTickCount()); + memcpy(output, cd_buffer, len * 2); + // for (c = 0; c < BUF_SIZE - len; c++) + // cd_buffer[c] = cd_buffer[c + cd_buflen]; + memcpy(&cd_buffer[0], &cd_buffer[len], (BUF_SIZE - len) * 2); + cd_buflen -= len; + // pclog("Done %i\n", GetTickCount()); } -void ioctl_audio_stop() { - ioctl_cd_state = CD_STOPPED; -} +void ioctl_audio_stop() { ioctl_cd_state = CD_STOPPED; } static int get_track_nr(uint32_t pos) { - int c; - int track = 0; + int c; + int track = 0; - if (!tocvalid) - return 0; + if (!tocvalid) + return 0; - for (c = first_track; c < last_track; c++) { - uint32_t track_address = toc[c].cdte_addr.msf.frame + - (toc[c].cdte_addr.msf.second * 75) + - (toc[c].cdte_addr.msf.minute * 75 * 60); -//pclog("get_track_nr: track=%i pos=%x track_address=%x\n", c, pos, track_address); - if (track_address <= pos) - track = c; - } - return track; + for (c = first_track; c < last_track; c++) { + uint32_t track_address = + toc[c].cdte_addr.msf.frame + (toc[c].cdte_addr.msf.second * 75) + (toc[c].cdte_addr.msf.minute * 75 * 60); + // pclog("get_track_nr: track=%i pos=%x track_address=%x\n", c, pos, track_address); + if (track_address <= pos) + track = c; + } + return track; } static int is_track_audio(uint32_t pos) { - int c; - int control = 0; + int c; + int control = 0; - if (!tocvalid) - return 0; + if (!tocvalid) + return 0; - for (c = first_track; c < last_track; c++) { - uint32_t track_address = toc[c].cdte_addr.msf.frame + - (toc[c].cdte_addr.msf.second * 75) + - (toc[c].cdte_addr.msf.minute * 75 * 60); -//pclog("get_track_nr: track=%i pos=%x track_address=%x\n", c, pos, track_address); - if (track_address <= pos) - control = toc[c].cdte_ctrl; - } - return (control & 4) ? 0 : 1; + for (c = first_track; c < last_track; c++) { + uint32_t track_address = + toc[c].cdte_addr.msf.frame + (toc[c].cdte_addr.msf.second * 75) + (toc[c].cdte_addr.msf.minute * 75 * 60); + // pclog("get_track_nr: track=%i pos=%x track_address=%x\n", c, pos, track_address); + if (track_address <= pos) + control = toc[c].cdte_ctrl; + } + return (control & 4) ? 0 : 1; } static int ioctl_is_track_audio(uint32_t pos, int ismsf) { - if (ismsf) { - int m = (pos >> 16) & 0xff; - int s = (pos >> 8) & 0xff; - int f = pos & 0xff; - pos = MSFtoLBA(m, s, f); - } - return is_track_audio(pos); + if (ismsf) { + int m = (pos >> 16) & 0xff; + int s = (pos >> 8) & 0xff; + int f = pos & 0xff; + pos = MSFtoLBA(m, s, f); + } + return is_track_audio(pos); } static void ioctl_playaudio(uint32_t pos, uint32_t len, int ismsf) { -// pclog("Play audio - %08X %08X %i\n", pos, len, ismsf); - if (ismsf) { - pos = (pos & 0xff) + (((pos >> 8) & 0xff) * 75) + (((pos >> 16) & 0xff) * 75 * 60); - len = (len & 0xff) + (((len >> 8) & 0xff) * 75) + (((len >> 16) & 0xff) * 75 * 60); -// pclog("MSF - pos = %08X len = %08X\n", pos, len); - } else - len += pos; - ioctl_cd_pos = pos;// + 150; - ioctl_cd_end = pos + len;// + 150; - ioctl_cd_state = CD_PLAYING; - if (ioctl_cd_pos < 150) - ioctl_cd_pos = 150; -// pclog("Audio start %08X %08X %i %i %i\n", ioctl_cd_pos, ioctl_cd_end, ioctl_cd_state, 0, len); + // pclog("Play audio - %08X %08X %i\n", pos, len, ismsf); + if (ismsf) { + pos = (pos & 0xff) + (((pos >> 8) & 0xff) * 75) + (((pos >> 16) & 0xff) * 75 * 60); + len = (len & 0xff) + (((len >> 8) & 0xff) * 75) + (((len >> 16) & 0xff) * 75 * 60); + // pclog("MSF - pos = %08X len = %08X\n", pos, len); + } else + len += pos; + ioctl_cd_pos = pos; // + 150; + ioctl_cd_end = pos + len; // + 150; + ioctl_cd_state = CD_PLAYING; + if (ioctl_cd_pos < 150) + ioctl_cd_pos = 150; + // pclog("Audio start %08X %08X %i %i %i\n", ioctl_cd_pos, ioctl_cd_end, ioctl_cd_state, 0, len); } static void ioctl_pause(void) { - if (ioctl_cd_state == CD_PLAYING) - ioctl_cd_state = CD_PAUSED; + if (ioctl_cd_state == CD_PLAYING) + ioctl_cd_state = CD_PAUSED; } static void ioctl_resume(void) { - if (ioctl_cd_state == CD_PAUSED) - ioctl_cd_state = CD_PLAYING; + if (ioctl_cd_state == CD_PAUSED) + ioctl_cd_state = CD_PLAYING; } -static void ioctl_stop(void) { - ioctl_cd_state = CD_STOPPED; -} +static void ioctl_stop(void) { ioctl_cd_state = CD_STOPPED; } static void ioctl_seek(uint32_t pos) { -// pclog("Seek %08X\n", pos); - ioctl_cd_pos = pos; - ioctl_cd_state = CD_STOPPED; + // pclog("Seek %08X\n", pos); + ioctl_cd_pos = pos; + ioctl_cd_state = CD_STOPPED; } static int read_toc(int fd, struct cdrom_tocentry *btoc) { - struct cdrom_tochdr toc_hdr; - int track, err; - int c; -//pclog("read_toc\n"); - err = ioctl(fd, CDROMREADTOCHDR, &toc_hdr); - if (err == -1) { - pclog("read_toc: CDROMREADTOCHDR failed\n"); - return 0; - } + struct cdrom_tochdr toc_hdr; + int track, err; + int c; + // pclog("read_toc\n"); + err = ioctl(fd, CDROMREADTOCHDR, &toc_hdr); + if (err == -1) { + pclog("read_toc: CDROMREADTOCHDR failed\n"); + return 0; + } - first_track = toc_hdr.cdth_trk0; - last_track = toc_hdr.cdth_trk1; -//pclog("read_toc: first_track=%i last_track=%i\n", first_track, last_track); - memset(btoc, 0, sizeof(struct cdrom_tocentry)); + first_track = toc_hdr.cdth_trk0; + last_track = toc_hdr.cdth_trk1; + // pclog("read_toc: first_track=%i last_track=%i\n", first_track, last_track); + memset(btoc, 0, sizeof(struct cdrom_tocentry)); - c = 0; - for (track = 0; track < 256; track++) { - btoc[c].cdte_track = track; - btoc[c].cdte_format = CDROM_MSF; - err = ioctl(fd, CDROMREADTOCENTRY, &btoc[c]); - if (err == -1) { -// pclog("read_toc: CDROMREADTOCENTRY failed on track %i\n", track); - continue; - } - c++; -// pclog("read_toc: %i Track %02X - number %02X control %02X adr %02X address %02X %02X %02X %02X\n", c, track, btoc[c].cdte_track, btoc[c].cdte_ctrl, btoc[c].cdte_adr, 0, btoc[c].cdte_addr.msf.minute, btoc[c].cdte_addr.msf.second, btoc[c].cdte_addr.msf.frame); - } + c = 0; + for (track = 0; track < 256; track++) { + btoc[c].cdte_track = track; + btoc[c].cdte_format = CDROM_MSF; + err = ioctl(fd, CDROMREADTOCENTRY, &btoc[c]); + if (err == -1) { + // pclog("read_toc: CDROMREADTOCENTRY failed on track %i\n", track); + continue; + } + c++; + // pclog("read_toc: %i Track %02X - number %02X control %02X adr %02X address %02X %02X %02X %02X\n", + //c, track, btoc[c].cdte_track, btoc[c].cdte_ctrl, btoc[c].cdte_adr, 0, btoc[c].cdte_addr.msf.minute, + //btoc[c].cdte_addr.msf.second, btoc[c].cdte_addr.msf.frame); + } - toc_tracks = c; + toc_tracks = c; - return 1; + return 1; } static int ioctl_ready(void) { - struct cdrom_tochdr toc_hdr; - struct cdrom_tocentry toc_entry; - int err; + struct cdrom_tochdr toc_hdr; + struct cdrom_tocentry toc_entry; + int err; - if (ioctl_fd <= 0) - return 0; + if (ioctl_fd <= 0) + return 0; - err = ioctl(ioctl_fd, CDROM_MEDIA_CHANGED, 0); - if (err) - tocvalid = 0; + err = ioctl(ioctl_fd, CDROM_MEDIA_CHANGED, 0); + if (err) + tocvalid = 0; - if (tocvalid) - return 1; + if (tocvalid) + return 1; - err = ioctl(ioctl_fd, CDROMREADTOCHDR, &toc_hdr); - if (err == -1) - return 0; + err = ioctl(ioctl_fd, CDROMREADTOCHDR, &toc_hdr); + if (err == -1) + return 0; -// pclog("CDROMREADTOCHDR: start track=%i end track=%i\n", toc_hdr.cdth_trk0, toc_hdr.cdth_trk1); - toc_entry.cdte_track = toc_hdr.cdth_trk1; - toc_entry.cdte_format = CDROM_MSF; - err = ioctl(ioctl_fd, CDROMREADTOCENTRY, &toc_entry); - if (err == -1) - return 0; + // pclog("CDROMREADTOCHDR: start track=%i end track=%i\n", toc_hdr.cdth_trk0, toc_hdr.cdth_trk1); + toc_entry.cdte_track = toc_hdr.cdth_trk1; + toc_entry.cdte_format = CDROM_MSF; + err = ioctl(ioctl_fd, CDROMREADTOCENTRY, &toc_entry); + if (err == -1) + return 0; -// pclog("CDROMREADTOCENTRY: addr=%02i:%02i:%02i\n", toc_entry.cdte_addr.msf.minute, toc_entry.cdte_addr.msf.second, toc_entry.cdte_addr.msf.frame); - if ((toc_entry.cdte_addr.msf.minute != toc[toc_hdr.cdth_trk1].cdte_addr.msf.minute) || - (toc_entry.cdte_addr.msf.second != toc[toc_hdr.cdth_trk1].cdte_addr.msf.second) || - (toc_entry.cdte_addr.msf.frame != toc[toc_hdr.cdth_trk1].cdte_addr.msf.frame) || - !tocvalid) { - ioctl_cd_state = CD_STOPPED; + // pclog("CDROMREADTOCENTRY: addr=%02i:%02i:%02i\n", toc_entry.cdte_addr.msf.minute, toc_entry.cdte_addr.msf.second, + //toc_entry.cdte_addr.msf.frame); + if ((toc_entry.cdte_addr.msf.minute != toc[toc_hdr.cdth_trk1].cdte_addr.msf.minute) || + (toc_entry.cdte_addr.msf.second != toc[toc_hdr.cdth_trk1].cdte_addr.msf.second) || + (toc_entry.cdte_addr.msf.frame != toc[toc_hdr.cdth_trk1].cdte_addr.msf.frame) || !tocvalid) { + ioctl_cd_state = CD_STOPPED; - tocvalid = read_toc(ioctl_fd, toc); - } + tocvalid = read_toc(ioctl_fd, toc); + } - return 1; + return 1; } static int ioctl_get_last_block(unsigned char starttrack, int msf, int maxlen, int single) { - int c; - int lb = 0; - int tv = 0; - struct cdrom_tocentry lbtoc[100]; + int c; + int lb = 0; + int tv = 0; + struct cdrom_tocentry lbtoc[100]; - if (ioctl_fd <= 0) - return 0; + if (ioctl_fd <= 0) + return 0; - ioctl_cd_state = CD_STOPPED; + ioctl_cd_state = CD_STOPPED; - if (!tocvalid) - tv = read_toc(ioctl_fd, lbtoc); + if (!tocvalid) + tv = read_toc(ioctl_fd, lbtoc); - if (!tv) - return 0; + if (!tv) + return 0; - last_block = 0; - for (c = 0; c <= last_track; c++) { - uint32_t address; - address = MSFtoLBA(toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame); - if (address > last_block) - lb = address; - } - return lb; + last_block = 0; + for (c = 0; c <= last_track; c++) { + uint32_t address; + address = MSFtoLBA(toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame); + if (address > last_block) + lb = address; + } + return lb; } static int ioctl_medium_changed(void) { - struct cdrom_tochdr toc_hdr; - struct cdrom_tocentry toc_entry; - int err; + struct cdrom_tochdr toc_hdr; + struct cdrom_tocentry toc_entry; + int err; - if (ioctl_fd <= 0) - return 0; + if (ioctl_fd <= 0) + return 0; - err = ioctl(ioctl_fd, CDROMREADTOCHDR, &toc_hdr); - if (err == -1) - return 0; + err = ioctl(ioctl_fd, CDROMREADTOCHDR, &toc_hdr); + if (err == -1) + return 0; - toc_entry.cdte_track = toc_hdr.cdth_trk1; - toc_entry.cdte_format = CDROM_MSF; - err = ioctl(ioctl_fd, CDROMREADTOCENTRY, &toc_entry); - if (err == -1) - return 0; + toc_entry.cdte_track = toc_hdr.cdth_trk1; + toc_entry.cdte_format = CDROM_MSF; + err = ioctl(ioctl_fd, CDROMREADTOCENTRY, &toc_entry); + if (err == -1) + return 0; -// pclog("CDROMREADTOCENTRY: addr=%02i:%02i:%02i\n", toc_entry.cdte_addr.msf.minute, toc_entry.cdte_addr.msf.second, toc_entry.cdte_addr.msf.frame); - if ((toc_entry.cdte_addr.msf.minute != toc[toc_hdr.cdth_trk1].cdte_addr.msf.minute) || - (toc_entry.cdte_addr.msf.second != toc[toc_hdr.cdth_trk1].cdte_addr.msf.second) || - (toc_entry.cdte_addr.msf.frame != toc[toc_hdr.cdth_trk1].cdte_addr.msf.frame)) { - cdrom_capacity = ioctl_get_last_block(0, 0, 4096, 0); - return 1; - } - return 0; + // pclog("CDROMREADTOCENTRY: addr=%02i:%02i:%02i\n", toc_entry.cdte_addr.msf.minute, toc_entry.cdte_addr.msf.second, + //toc_entry.cdte_addr.msf.frame); + if ((toc_entry.cdte_addr.msf.minute != toc[toc_hdr.cdth_trk1].cdte_addr.msf.minute) || + (toc_entry.cdte_addr.msf.second != toc[toc_hdr.cdth_trk1].cdte_addr.msf.second) || + (toc_entry.cdte_addr.msf.frame != toc[toc_hdr.cdth_trk1].cdte_addr.msf.frame)) { + cdrom_capacity = ioctl_get_last_block(0, 0, 4096, 0); + return 1; + } + return 0; } static uint8_t ioctl_getcurrentsubchannel(uint8_t *b, int msf) { - uint32_t cdpos = ioctl_cd_pos; - int track = get_track_nr(cdpos); - uint32_t track_address = toc[track].cdte_addr.msf.frame + - (toc[track].cdte_addr.msf.second * 75) + - (toc[track].cdte_addr.msf.minute * 75 * 60); - int pos = 0; - uint8_t ret; -//pclog("ioctl_getsubchannel: cdpos=%x track_address=%x track=%i\n", cdpos, track_address, track); - if (ioctl_cd_state == CD_PLAYING) - ret = 0x11; - else if (ioctl_cd_state == CD_PAUSED) - ret = 0x12; - else - ret = 0x13; + uint32_t cdpos = ioctl_cd_pos; + int track = get_track_nr(cdpos); + uint32_t track_address = toc[track].cdte_addr.msf.frame + (toc[track].cdte_addr.msf.second * 75) + + (toc[track].cdte_addr.msf.minute * 75 * 60); + int pos = 0; + uint8_t ret; + // pclog("ioctl_getsubchannel: cdpos=%x track_address=%x track=%i\n", cdpos, track_address, track); + if (ioctl_cd_state == CD_PLAYING) + ret = 0x11; + else if (ioctl_cd_state == CD_PAUSED) + ret = 0x12; + else + ret = 0x13; - b[pos++] = (toc[track].cdte_adr << 4) | toc[track].cdte_ctrl; - b[pos++] = track; - b[pos++] = 0; + b[pos++] = (toc[track].cdte_adr << 4) | toc[track].cdte_ctrl; + b[pos++] = track; + b[pos++] = 0; - if (msf) { - uint32_t dat = cdpos; - b[pos + 3] = (uint8_t)(dat % 75); - dat /= 75; - b[pos + 2] = (uint8_t)(dat % 60); - dat /= 60; - b[pos + 1] = (uint8_t)dat; - b[pos] = 0; - pos += 4; - dat = cdpos - track_address; - b[pos + 3] = (uint8_t)(dat % 75); - dat /= 75; - b[pos + 2] = (uint8_t)(dat % 60); - dat /= 60; - b[pos + 1] = (uint8_t)dat; - b[pos] = 0; - pos += 4; - } else { - b[pos++] = (cdpos >> 24) & 0xff; - b[pos++] = (cdpos >> 16) & 0xff; - b[pos++] = (cdpos >> 8) & 0xff; - b[pos++] = cdpos & 0xff; - cdpos -= track_address; - b[pos++] = (cdpos >> 24) & 0xff; - b[pos++] = (cdpos >> 16) & 0xff; - b[pos++] = (cdpos >> 8) & 0xff; - b[pos++] = cdpos & 0xff; - } + if (msf) { + uint32_t dat = cdpos; + b[pos + 3] = (uint8_t)(dat % 75); + dat /= 75; + b[pos + 2] = (uint8_t)(dat % 60); + dat /= 60; + b[pos + 1] = (uint8_t)dat; + b[pos] = 0; + pos += 4; + dat = cdpos - track_address; + b[pos + 3] = (uint8_t)(dat % 75); + dat /= 75; + b[pos + 2] = (uint8_t)(dat % 60); + dat /= 60; + b[pos + 1] = (uint8_t)dat; + b[pos] = 0; + pos += 4; + } else { + b[pos++] = (cdpos >> 24) & 0xff; + b[pos++] = (cdpos >> 16) & 0xff; + b[pos++] = (cdpos >> 8) & 0xff; + b[pos++] = cdpos & 0xff; + cdpos -= track_address; + b[pos++] = (cdpos >> 24) & 0xff; + b[pos++] = (cdpos >> 16) & 0xff; + b[pos++] = (cdpos >> 8) & 0xff; + b[pos++] = cdpos & 0xff; + } - return ret; + return ret; } static void ioctl_eject(void) { - if (ioctl_fd <= 0) - return; + if (ioctl_fd <= 0) + return; - ioctl(ioctl_fd, CDROMEJECT); + ioctl(ioctl_fd, CDROMEJECT); } static void ioctl_load(void) { - if (ioctl_fd <= 0) - return; + if (ioctl_fd <= 0) + return; - ioctl(ioctl_fd, CDROMEJECT); + ioctl(ioctl_fd, CDROMEJECT); - cdrom_capacity = ioctl_get_last_block(0, 0, 4096, 0); + cdrom_capacity = ioctl_get_last_block(0, 0, 4096, 0); } static int ioctl_readsector(uint8_t *b, int sector, int count) { - if (ioctl_fd <= 0) - return -1; + if (ioctl_fd <= 0) + return -1; - lseek(ioctl_fd, sector * 2048, SEEK_SET); - read(ioctl_fd, b, count * 2048); + lseek(ioctl_fd, sector * 2048, SEEK_SET); + read(ioctl_fd, b, count * 2048); - return 0; + return 0; } union { - struct cdrom_msf *msf; - char b[CD_FRAMESIZE_RAW]; + struct cdrom_msf *msf; + char b[CD_FRAMESIZE_RAW]; } raw_read_params; -static int lba_to_msf(int lba) { - return (((lba / 75) / 60) << 16) + (((lba / 75) % 60) << 8) + (lba % 75); -} +static int lba_to_msf(int lba) { return (((lba / 75) / 60) << 16) + (((lba / 75) % 60) << 8) + (lba % 75); } static void ioctl_readsector_raw(uint8_t *b, int sector) { - int err; - int imsf = lba_to_msf(sector); + int err; + int imsf = lba_to_msf(sector); - if (ioctl_fd <= 0) - return; + if (ioctl_fd <= 0) + return; - raw_read_params.msf = malloc(sizeof(struct cdrom_msf)); - raw_read_params.msf->cdmsf_frame0 = imsf & 0xff; - raw_read_params.msf->cdmsf_sec0 = (imsf >> 8) & 0xff; - raw_read_params.msf->cdmsf_min0 = (imsf >> 16) & 0xff; + raw_read_params.msf = malloc(sizeof(struct cdrom_msf)); + raw_read_params.msf->cdmsf_frame0 = imsf & 0xff; + raw_read_params.msf->cdmsf_sec0 = (imsf >> 8) & 0xff; + raw_read_params.msf->cdmsf_min0 = (imsf >> 16) & 0xff; - /* This will read the actual raw sectors from the disc. */ - err = ioctl(ioctl_fd, CDROMREADRAW, (void *)&raw_read_params); - if (err == -1) { - pclog("read_toc: CDROMREADTOCHDR failed\n"); - return; - } + /* This will read the actual raw sectors from the disc. */ + err = ioctl(ioctl_fd, CDROMREADRAW, (void *)&raw_read_params); + if (err == -1) { + pclog("read_toc: CDROMREADTOCHDR failed\n"); + return; + } - memcpy(b, raw_read_params.b, 2352); + memcpy(b, raw_read_params.b, 2352); - free(raw_read_params.msf); + free(raw_read_params.msf); } static int ioctl_readtoc(unsigned char *b, unsigned char starttrack, int msf, int maxlen, int single) { - int len = 4; - int c, d; - uint32_t temp; - uint32_t last_address = 0; + int len = 4; + int c, d; + uint32_t temp; + uint32_t last_address = 0; - if (ioctl_fd <= 0) - return 0; + if (ioctl_fd <= 0) + return 0; - ioctl_cd_state = CD_STOPPED; + ioctl_cd_state = CD_STOPPED; - if (!tocvalid) - tocvalid = read_toc(ioctl_fd, toc); + if (!tocvalid) + tocvalid = read_toc(ioctl_fd, toc); - if (!tocvalid) - return 4; + if (!tocvalid) + return 4; -// pclog("Read TOC done! %i\n",single); - b[2] = first_track; - b[3] = last_track; - d = 0; -//pclog("Read TOC starttrack=%i\n", starttrack); - for (c = 0; c <= toc_tracks; c++) { - if (toc[c].cdte_track && toc[c].cdte_track >= starttrack) { - d = c; - break; - } - } - b[2] = toc[c].cdte_track; - last_block = 0; + // pclog("Read TOC done! %i\n",single); + b[2] = first_track; + b[3] = last_track; + d = 0; + // pclog("Read TOC starttrack=%i\n", starttrack); + for (c = 0; c <= toc_tracks; c++) { + if (toc[c].cdte_track && toc[c].cdte_track >= starttrack) { + d = c; + break; + } + } + b[2] = toc[c].cdte_track; + last_block = 0; - for (c = d; c <= toc_tracks; c++) { - uint32_t address; - if ((len + 8) > maxlen) - break; -// pclog("Len %i max %i Track %02X - %02X %02X %02i:%02i:%02i %08X\n",len,maxlen,toc[c].cdte_track,toc[c].cdte_adr,toc[c].cdte_ctrl,toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame,MSFtoLBA(toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame)); - address = MSFtoLBA(toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame); - if (address < last_address) - continue; - last_address = address; - b[len++] = 0; /*Reserved*/ - b[len++] = (toc[c].cdte_adr << 4) | toc[c].cdte_ctrl; - b[len++] = toc[c].cdte_track; - b[len++] = 0; /*Reserved*/ - if (address > last_block) - last_block = address; + for (c = d; c <= toc_tracks; c++) { + uint32_t address; + if ((len + 8) > maxlen) + break; + // pclog("Len %i max %i Track %02X - %02X %02X %02i:%02i:%02i + // %08X\n",len,maxlen,toc[c].cdte_track,toc[c].cdte_adr,toc[c].cdte_ctrl,toc[c].cdte_addr.msf.minute, + // toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame,MSFtoLBA(toc[c].cdte_addr.msf.minute, + // toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame)); + address = MSFtoLBA(toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame); + if (address < last_address) + continue; + last_address = address; + b[len++] = 0; /*Reserved*/ + b[len++] = (toc[c].cdte_adr << 4) | toc[c].cdte_ctrl; + b[len++] = toc[c].cdte_track; + b[len++] = 0; /*Reserved*/ + if (address > last_block) + last_block = address; - if (msf) { - b[len++] = 0; - b[len++] = toc[c].cdte_addr.msf.minute; - b[len++] = toc[c].cdte_addr.msf.second; - b[len++] = toc[c].cdte_addr.msf.frame; - } else { - temp = MSFtoLBA(toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame); - b[len++] = temp >> 24; - b[len++] = temp >> 16; - b[len++] = temp >> 8; - b[len++] = temp; - } - if (single) - break; - } + if (msf) { + b[len++] = 0; + b[len++] = toc[c].cdte_addr.msf.minute; + b[len++] = toc[c].cdte_addr.msf.second; + b[len++] = toc[c].cdte_addr.msf.frame; + } else { + temp = MSFtoLBA(toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame); + 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); -/* pclog("Table of Contents (%i bytes) : \n", size); - pclog("First track - %02X\n", first_track); - pclog("Last track - %02X\n", last_track); - for (c = 0; c <= last_track; c++) - pclog("Track %02X - number %02X control %02X adr %02X address %02X %02X %02X %02X\n", c, toc[c].cdte_track, toc[c].cdte_ctrl, toc[c].cdte_adr, 0, toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame); - for (c = 0;c <= last_track; c++) - pclog("Track %02X - number %02X control %02X adr %02X address %06X\n", c, toc[c].cdte_track, toc[c].cdte_ctrl, toc[c].cdte_adr, MSFtoLBA(toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame));*/ - return len; + b[0] = (uint8_t)(((len - 2) >> 8) & 0xff); + b[1] = (uint8_t)((len - 2) & 0xff); + /* pclog("Table of Contents (%i bytes) : \n", size); + pclog("First track - %02X\n", first_track); + pclog("Last track - %02X\n", last_track); + for (c = 0; c <= last_track; c++) + pclog("Track %02X - number %02X control %02X adr %02X address %02X %02X %02X %02X\n", c, toc[c].cdte_track, + toc[c].cdte_ctrl, toc[c].cdte_adr, 0, toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, + toc[c].cdte_addr.msf.frame); for (c = 0;c <= last_track; c++) pclog("Track %02X - number %02X control %02X adr %02X + address %06X\n", c, toc[c].cdte_track, toc[c].cdte_ctrl, toc[c].cdte_adr, MSFtoLBA(toc[c].cdte_addr.msf.minute, + toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame));*/ + return len; } static int ioctl_readtoc_session(unsigned char *b, int msf, int maxlen) { - struct cdrom_multisession session; - int len = 4; - int err; + struct cdrom_multisession session; + int len = 4; + int err; - if (ioctl_fd <= 0) - return 0; + if (ioctl_fd <= 0) + return 0; - session.addr_format = CDROM_MSF; - err = ioctl(ioctl_fd, CDROMMULTISESSION, &session); + session.addr_format = CDROM_MSF; + err = ioctl(ioctl_fd, CDROMMULTISESSION, &session); - if (err == -1) - return 0; + if (err == -1) + return 0; - b[2] = 1; - b[3] = 1; - b[len++] = 0; /*Reserved*/ - b[len++] = (toc[first_track].cdte_adr << 4) | toc[first_track].cdte_ctrl; - b[len++] = toc[first_track].cdte_track; - b[len++] = 0; /*Reserved*/ - if (msf) { - b[len++] = 0; - b[len++] = session.addr.msf.minute; - b[len++] = session.addr.msf.second; - b[len++] = session.addr.msf.frame; - } else { - uint32_t temp = MSFtoLBA(session.addr.msf.minute, session.addr.msf.second, session.addr.msf.frame); - b[len++] = temp >> 24; - b[len++] = temp >> 16; - b[len++] = temp >> 8; - b[len++] = temp; - } + b[2] = 1; + b[3] = 1; + b[len++] = 0; /*Reserved*/ + b[len++] = (toc[first_track].cdte_adr << 4) | toc[first_track].cdte_ctrl; + b[len++] = toc[first_track].cdte_track; + b[len++] = 0; /*Reserved*/ + if (msf) { + b[len++] = 0; + b[len++] = session.addr.msf.minute; + b[len++] = session.addr.msf.second; + b[len++] = session.addr.msf.frame; + } else { + uint32_t temp = MSFtoLBA(session.addr.msf.minute, session.addr.msf.second, session.addr.msf.frame); + b[len++] = temp >> 24; + b[len++] = temp >> 16; + b[len++] = temp >> 8; + b[len++] = temp; + } - return len; + return len; } static int ioctl_readtoc_raw(unsigned char *b, int maxlen) { - struct cdrom_tochdr toc_hdr; - struct cdrom_tocentry toc2[100]; - int track, err; - int len = 4; + struct cdrom_tochdr toc_hdr; + struct cdrom_tocentry toc2[100]; + int track, err; + int len = 4; -//pclog("read_toc\n"); - if (ioctl_fd <= 0) - return 0; + // pclog("read_toc\n"); + if (ioctl_fd <= 0) + return 0; - err = ioctl(ioctl_fd, CDROMREADTOCHDR, &toc_hdr); + err = ioctl(ioctl_fd, CDROMREADTOCHDR, &toc_hdr); - if (err == -1) { - pclog("read_toc: CDROMREADTOCHDR failed\n"); - return 0; - } + if (err == -1) { + pclog("read_toc: CDROMREADTOCHDR failed\n"); + return 0; + } - b[2] = toc_hdr.cdth_trk0; - b[3] = toc_hdr.cdth_trk1; + b[2] = toc_hdr.cdth_trk0; + b[3] = toc_hdr.cdth_trk1; - //pclog("read_toc: first_track=%i last_track=%i\n", first_track, last_track); - memset(toc, 0, sizeof(toc)); + // pclog("read_toc: first_track=%i last_track=%i\n", first_track, last_track); + memset(toc, 0, sizeof(toc)); - for (track = toc_hdr.cdth_trk0; track <= toc_hdr.cdth_trk1; track++) { - if ((len + 11) > maxlen) { - pclog("ioctl_readtocraw: This iteration would fill the buffer beyond the bounds, aborting...\n"); - return len; - } + for (track = toc_hdr.cdth_trk0; track <= toc_hdr.cdth_trk1; track++) { + if ((len + 11) > maxlen) { + pclog("ioctl_readtocraw: This iteration would fill the buffer beyond the bounds, aborting...\n"); + return len; + } - toc2[track].cdte_track = track; - toc2[track].cdte_format = CDROM_MSF; - err = ioctl(ioctl_fd, CDROMREADTOCENTRY, &toc2[track]); - if (err == -1) - return 0; + toc2[track].cdte_track = track; + toc2[track].cdte_format = CDROM_MSF; + err = ioctl(ioctl_fd, CDROMREADTOCENTRY, &toc2[track]); + if (err == -1) + return 0; -// pclog("read_toc: Track %02X - number %02X control %02X adr %02X address %02X %02X %02X %02X\n", track, toc[track].cdte_track, toc[track].cdte_ctrl, toc[track].cdte_adr, 0, toc[track].cdte_addr.msf.minute, toc[track].cdte_addr.msf.second, toc[track].cdte_addr.msf.frame); + // pclog("read_toc: Track %02X - number %02X control %02X adr %02X address %02X %02X %02X %02X\n", + //track, toc[track].cdte_track, toc[track].cdte_ctrl, toc[track].cdte_adr, 0, toc[track].cdte_addr.msf.minute, + //toc[track].cdte_addr.msf.second, toc[track].cdte_addr.msf.frame); - b[len++] = toc2[track].cdte_track; - b[len++] = (toc2[track].cdte_adr << 4) | toc[track].cdte_ctrl; - b[len++] = 0; - b[len++] = 0; - b[len++] = 0; - b[len++] = 0; - b[len++] = 0; - b[len++] = 0; - b[len++] = toc2[track].cdte_addr.msf.minute; - b[len++] = toc2[track].cdte_addr.msf.second; - b[len++] = toc2[track].cdte_addr.msf.frame; - } + b[len++] = toc2[track].cdte_track; + b[len++] = (toc2[track].cdte_adr << 4) | toc[track].cdte_ctrl; + b[len++] = 0; + b[len++] = 0; + b[len++] = 0; + b[len++] = 0; + b[len++] = 0; + b[len++] = 0; + b[len++] = toc2[track].cdte_addr.msf.minute; + b[len++] = toc2[track].cdte_addr.msf.second; + b[len++] = toc2[track].cdte_addr.msf.frame; + } - return len; + return len; } -static uint32_t ioctl_size() { - return cdrom_capacity; -} +static uint32_t ioctl_size() { return cdrom_capacity; } static int ioctl_status() { - if (!ioctl_ready() && (cdrom_drive <= 0)) - return CD_STATUS_EMPTY; + if (!ioctl_ready() && (cdrom_drive <= 0)) + return CD_STATUS_EMPTY; - switch (ioctl_cd_state) { - case CD_PLAYING:return CD_STATUS_PLAYING; - case CD_PAUSED:return CD_STATUS_PAUSED; - case CD_STOPPED: - default:return CD_STATUS_STOPPED; - } + switch (ioctl_cd_state) { + case CD_PLAYING: + return CD_STATUS_PLAYING; + case CD_PAUSED: + return CD_STATUS_PAUSED; + case CD_STOPPED: + default: + return CD_STATUS_STOPPED; + } } void ioctl_reset() { -//pclog("ioctl_reset: fd=%i\n", fd); - tocvalid = 0; + // pclog("ioctl_reset: fd=%i\n", fd); + tocvalid = 0; - if (ioctl_fd <= 0) - return; + if (ioctl_fd <= 0) + return; - tocvalid = read_toc(ioctl_fd, toc); + tocvalid = read_toc(ioctl_fd, toc); } void ioctl_set_drive(char d) { - ioctl_close(); - atapi = &ioctl_atapi; - ioctl_open(d); + ioctl_close(); + atapi = &ioctl_atapi; + ioctl_open(d); } int ioctl_open(char d) { - atapi = &ioctl_atapi; - ioctl_fd = open("/dev/cdrom", O_RDONLY | O_NONBLOCK); + atapi = &ioctl_atapi; + ioctl_fd = open("/dev/cdrom", O_RDONLY | O_NONBLOCK); - return 0; + return 0; } void ioctl_close(void) { - if (ioctl_fd) { - close(ioctl_fd); - ioctl_fd = 0; - } + if (ioctl_fd) { + close(ioctl_fd); + ioctl_fd = 0; + } } static void ioctl_exit(void) { - ioctl_stop(); - ioctl_inited = 0; - tocvalid = 0; + ioctl_stop(); + ioctl_inited = 0; + tocvalid = 0; } -static ATAPI ioctl_atapi = - { - ioctl_ready, - ioctl_medium_changed, - ioctl_readtoc, - ioctl_readtoc_session, - ioctl_readtoc_raw, - ioctl_getcurrentsubchannel, - ioctl_readsector, - ioctl_readsector_raw, - ioctl_playaudio, - ioctl_seek, - ioctl_load, - ioctl_eject, - ioctl_pause, - ioctl_resume, - ioctl_size, - ioctl_status, - ioctl_is_track_audio, - ioctl_stop, - ioctl_exit - }; +static ATAPI ioctl_atapi = {ioctl_ready, + ioctl_medium_changed, + ioctl_readtoc, + ioctl_readtoc_session, + ioctl_readtoc_raw, + ioctl_getcurrentsubchannel, + ioctl_readsector, + ioctl_readsector_raw, + ioctl_playaudio, + ioctl_seek, + ioctl_load, + ioctl_eject, + ioctl_pause, + ioctl_resume, + ioctl_size, + ioctl_status, + ioctl_is_track_audio, + ioctl_stop, + ioctl_exit}; diff --git a/src/cdrom/cdrom-ioctl-osx.c b/src/cdrom/cdrom-ioctl-osx.c index f9552a36..15a07a9d 100644 --- a/src/cdrom/cdrom-ioctl-osx.c +++ b/src/cdrom/cdrom-ioctl-osx.c @@ -25,15 +25,9 @@ static CDTOC *toc = NULL; static CDDiscInfo disc_info; static int track_addr[256]; -static int msf_to_lba(CDMSF *msf) { - return msf->frame + (msf->second * 75) + (msf->minute * 60 * 75); -} +static int msf_to_lba(CDMSF *msf) { return msf->frame + (msf->second * 75) + (msf->minute * 60 * 75); } -enum { - CD_STOPPED = 0, - CD_PLAYING, - CD_PAUSED -}; +enum { CD_STOPPED = 0, CD_PLAYING, CD_PAUSED }; static int ioctl_cd_state = CD_STOPPED; static uint32_t ioctl_cd_pos = 0, ioctl_cd_end = 0; @@ -43,662 +37,653 @@ static int cd_buflen = 0; static int cd_drive = -1; static int cd_open() { - char s[80]; + char s[80]; - if (cd_drive < 0) - return 0; + if (cd_drive < 0) + return 0; - sprintf(s, "disk%i", cd_drive); - return opendev(s, O_RDONLY, 0, NULL); -} -static void cd_close(int fd) { - close(fd); + sprintf(s, "disk%i", cd_drive); + return opendev(s, O_RDONLY, 0, NULL); } +static void cd_close(int fd) { close(fd); } void ioctl_audio_callback(int16_t *output, int len) { - int ioctl_fd; + int ioctl_fd; -// pclog("Audio callback %08X %08X %i %i %i %04X %i\n", ioctl_cd_pos, ioctl_cd_end, ioctl_cd_state, cd_buflen, len, cd_buffer[4], GetTickCount()); - if (ioctl_cd_state != CD_PLAYING) { - memset(output, 0, len * 2); - return; - } + // pclog("Audio callback %08X %08X %i %i %i %04X %i\n", ioctl_cd_pos, ioctl_cd_end, ioctl_cd_state, cd_buflen, len, + // cd_buffer[4], GetTickCount()); + if (ioctl_cd_state != CD_PLAYING) { + memset(output, 0, len * 2); + return; + } - ioctl_fd = cd_open(); - if (ioctl_fd <= 0) { - memset(output, 0, len * 2); - return; - } + ioctl_fd = cd_open(); + if (ioctl_fd <= 0) { + memset(output, 0, len * 2); + return; + } - while (cd_buflen < len) { - if (ioctl_cd_pos < ioctl_cd_end) { - dk_cd_read_t cd_read; + while (cd_buflen < len) { + if (ioctl_cd_pos < ioctl_cd_end) { + dk_cd_read_t cd_read; - bzero(&cd_read, sizeof(cd_read)); + bzero(&cd_read, sizeof(cd_read)); - cd_read.offset = (ioctl_cd_pos - 150) * kCDSectorSizeCDDA; - cd_read.buffer = &cd_buffer[cd_buflen]; - cd_read.bufferLength = kCDSectorSizeCDDA; - cd_read.sectorType = kCDSectorTypeCDDA; - cd_read.sectorArea = kCDSectorAreaUser; - //pclog("CDDA read %llx %d %d\n", cd_read.offset, cd_read.bufferLength, ioctl_cd_pos); + cd_read.offset = (ioctl_cd_pos - 150) * kCDSectorSizeCDDA; + cd_read.buffer = &cd_buffer[cd_buflen]; + cd_read.bufferLength = kCDSectorSizeCDDA; + cd_read.sectorType = kCDSectorTypeCDDA; + cd_read.sectorArea = kCDSectorAreaUser; + // pclog("CDDA read %llx %d %d\n", cd_read.offset, cd_read.bufferLength, ioctl_cd_pos); - if (ioctl(ioctl_fd, DKIOCCDREAD, &cd_read) < 0) { - //pclog("DeviceIoControl returned false %d\n", errno); - memset(&cd_buffer[cd_buflen], 0, (BUF_SIZE - cd_buflen) * 2); - ioctl_cd_state = CD_STOPPED; - cd_buflen = len; - } else { - //pclog("DeviceIoControl returned true\n"); - ioctl_cd_pos++; - cd_buflen += (2352 / 2); - } - } else { - memset(&cd_buffer[cd_buflen], 0, (BUF_SIZE - cd_buflen) * 2); - ioctl_cd_state = CD_STOPPED; - cd_buflen = len; - } - } + if (ioctl(ioctl_fd, DKIOCCDREAD, &cd_read) < 0) { + // pclog("DeviceIoControl returned false %d\n", errno); + memset(&cd_buffer[cd_buflen], 0, (BUF_SIZE - cd_buflen) * 2); + ioctl_cd_state = CD_STOPPED; + cd_buflen = len; + } else { + // pclog("DeviceIoControl returned true\n"); + ioctl_cd_pos++; + cd_buflen += (2352 / 2); + } + } else { + memset(&cd_buffer[cd_buflen], 0, (BUF_SIZE - cd_buflen) * 2); + ioctl_cd_state = CD_STOPPED; + cd_buflen = len; + } + } - cd_close(ioctl_fd); + cd_close(ioctl_fd); - memcpy(output, cd_buffer, len * 2); -// for (c = 0; c < BUF_SIZE - len; c++) -// cd_buffer[c] = cd_buffer[c + cd_buflen]; - memcpy(&cd_buffer[0], &cd_buffer[len], (BUF_SIZE - len) * 2); - cd_buflen -= len; -// pclog("Done %i\n", GetTickCount()); + memcpy(output, cd_buffer, len * 2); + // for (c = 0; c < BUF_SIZE - len; c++) + // cd_buffer[c] = cd_buffer[c + cd_buflen]; + memcpy(&cd_buffer[0], &cd_buffer[len], (BUF_SIZE - len) * 2); + cd_buflen -= len; + // pclog("Done %i\n", GetTickCount()); } -void ioctl_audio_stop() { - ioctl_cd_state = CD_STOPPED; -} +void ioctl_audio_stop() { ioctl_cd_state = CD_STOPPED; } static int get_track_nr(uint32_t pos) { - int c; - int track = 0; + int c; + int track = 0; - if (!tocvalid) - return 0; + if (!tocvalid) + return 0; - for (c = first_track; c < last_track; c++) { - uint32_t track_address = toc->descriptors[c].p.frame + - (toc->descriptors[c].p.second * 75) + - (toc->descriptors[c].p.minute * 75 * 60); -//pclog("get_track_nr: track=%i pos=%x track_address=%x\n", c, pos, track_address); - if (track_address <= pos) - track = c; - } - return track; + for (c = first_track; c < last_track; c++) { + uint32_t track_address = toc->descriptors[c].p.frame + (toc->descriptors[c].p.second * 75) + + (toc->descriptors[c].p.minute * 75 * 60); + // pclog("get_track_nr: track=%i pos=%x track_address=%x\n", c, pos, track_address); + if (track_address <= pos) + track = c; + } + return track; } static int is_track_audio(uint32_t pos) { - int c; - int control = 0; - //pclog("is_track_audio: %08x %i\n", pos, tocvalid); - if (!tocvalid) - return 0; - //pclog(" scan tracks %i-%i\n", first_track, last_track); - for (c = first_track; c < last_track; c++) { - uint32_t track_address = toc->descriptors[c].p.frame + - (toc->descriptors[c].p.second * 75) + - (toc->descriptors[c].p.minute * 75 * 60); -//pclog("get_track_nr: track=%i pos=%x track_address=%x\n", c, pos, track_address); - if (track_address <= pos) - control = toc->descriptors[c].control; - } - return (control & 4) ? 0 : 1; + int c; + int control = 0; + // pclog("is_track_audio: %08x %i\n", pos, tocvalid); + if (!tocvalid) + return 0; + // pclog(" scan tracks %i-%i\n", first_track, last_track); + for (c = first_track; c < last_track; c++) { + uint32_t track_address = toc->descriptors[c].p.frame + (toc->descriptors[c].p.second * 75) + + (toc->descriptors[c].p.minute * 75 * 60); + // pclog("get_track_nr: track=%i pos=%x track_address=%x\n", c, pos, track_address); + if (track_address <= pos) + control = toc->descriptors[c].control; + } + return (control & 4) ? 0 : 1; } static int ioctl_is_track_audio(uint32_t pos, int ismsf) { - if (ismsf) { - CDMSF msf; - msf.minute = (pos >> 16) & 0xff; - msf.second = (pos >> 8) & 0xff; - msf.frame = pos & 0xff; - pos = msf_to_lba(&msf); - } - return is_track_audio(pos); + if (ismsf) { + CDMSF msf; + msf.minute = (pos >> 16) & 0xff; + msf.second = (pos >> 8) & 0xff; + msf.frame = pos & 0xff; + pos = msf_to_lba(&msf); + } + return is_track_audio(pos); } static void ioctl_playaudio(uint32_t pos, uint32_t len, int ismsf) { - //pclog("Play audio - %08X %08X %i\n", pos, len, ismsf); - if (ismsf) { - pos = (pos & 0xff) + (((pos >> 8) & 0xff) * 75) + (((pos >> 16) & 0xff) * 75 * 60); - len = (len & 0xff) + (((len >> 8) & 0xff) * 75) + (((len >> 16) & 0xff) * 75 * 60); - //pclog("MSF - pos = %08X len = %08X\n", pos, len); - } else - len += pos; - ioctl_cd_pos = pos;// + 150; - ioctl_cd_end = pos + len;// + 150; - ioctl_cd_state = CD_PLAYING; - if (ioctl_cd_pos < 150) - ioctl_cd_pos = 150; -// pclog("Audio start %08X %08X %i %i %i\n", ioctl_cd_pos, ioctl_cd_end, ioctl_cd_state, 0, len); + // pclog("Play audio - %08X %08X %i\n", pos, len, ismsf); + if (ismsf) { + pos = (pos & 0xff) + (((pos >> 8) & 0xff) * 75) + (((pos >> 16) & 0xff) * 75 * 60); + len = (len & 0xff) + (((len >> 8) & 0xff) * 75) + (((len >> 16) & 0xff) * 75 * 60); + // pclog("MSF - pos = %08X len = %08X\n", pos, len); + } else + len += pos; + ioctl_cd_pos = pos; // + 150; + ioctl_cd_end = pos + len; // + 150; + ioctl_cd_state = CD_PLAYING; + if (ioctl_cd_pos < 150) + ioctl_cd_pos = 150; + // pclog("Audio start %08X %08X %i %i %i\n", ioctl_cd_pos, ioctl_cd_end, ioctl_cd_state, 0, len); } static void ioctl_pause(void) { - if (ioctl_cd_state == CD_PLAYING) - ioctl_cd_state = CD_PAUSED; + if (ioctl_cd_state == CD_PLAYING) + ioctl_cd_state = CD_PAUSED; } static void ioctl_resume(void) { - if (ioctl_cd_state == CD_PAUSED) - ioctl_cd_state = CD_PLAYING; + if (ioctl_cd_state == CD_PAUSED) + ioctl_cd_state = CD_PLAYING; } -static void ioctl_stop(void) { - ioctl_cd_state = CD_STOPPED; -} +static void ioctl_stop(void) { ioctl_cd_state = CD_STOPPED; } static void ioctl_seek(uint32_t pos) { -// pclog("Seek %08X\n", pos); - ioctl_cd_pos = pos; - ioctl_cd_state = CD_STOPPED; + // pclog("Seek %08X\n", pos); + ioctl_cd_pos = pos; + ioctl_cd_state = CD_STOPPED; } static int read_toc(int fd) { - dk_cd_read_toc_t cd_read_toc; - dk_cd_read_disc_info_t cd_read_disc_info; - int result; - int c; + dk_cd_read_toc_t cd_read_toc; + dk_cd_read_disc_info_t cd_read_disc_info; + int result; + int c; - bzero(&cd_read_toc, sizeof(cd_read_toc)); - bzero(&cd_read_disc_info, sizeof(cd_read_disc_info)); - bzero(toc, sizeof(CDTOC) + sizeof(CDTOCDescriptor) * 100); + bzero(&cd_read_toc, sizeof(cd_read_toc)); + bzero(&cd_read_disc_info, sizeof(cd_read_disc_info)); + bzero(toc, sizeof(CDTOC) + sizeof(CDTOCDescriptor) * 100); - cd_read_toc.format = kCDTOCFormatTOC; - cd_read_toc.buffer = toc; - cd_read_toc.bufferLength = 2048;//sizeof(CDTOC) + sizeof(CDTOCDescriptor)*100; - //pclog("buffer=%p bufferLength=%u\n", cd_read_toc.buffer, cd_read_toc.bufferLength); - result = ioctl(fd, DKIOCCDREADTOC, &cd_read_toc); + cd_read_toc.format = kCDTOCFormatTOC; + cd_read_toc.buffer = toc; + cd_read_toc.bufferLength = 2048; // sizeof(CDTOC) + sizeof(CDTOCDescriptor)*100; + // pclog("buffer=%p bufferLength=%u\n", cd_read_toc.buffer, cd_read_toc.bufferLength); + result = ioctl(fd, DKIOCCDREADTOC, &cd_read_toc); - //pclog("Read_toc - fd=%d result=%d errno=%d toc=%p\n", fd, result, errno, toc); - if (result < 0) { - //pclog("read_toc: DKIOCCDREADTOC failed\n"); - return 0; - } + // pclog("Read_toc - fd=%d result=%d errno=%d toc=%p\n", fd, result, errno, toc); + if (result < 0) { + // pclog("read_toc: DKIOCCDREADTOC failed\n"); + return 0; + } - //pclog("toc length=%u first=%u last=%u\n", toc->length, toc->sessionFirst, toc->sessionFirst); - first_track = 1; - last_track = 0; - toc_tracks = CDTOCGetDescriptorCount(toc); + // pclog("toc length=%u first=%u last=%u\n", toc->length, toc->sessionFirst, toc->sessionFirst); + first_track = 1; + last_track = 0; + toc_tracks = CDTOCGetDescriptorCount(toc); - for (c = 0; c < toc_tracks; c++) { - if (toc->descriptors[c].session > 1) - continue; - track_addr[c] = msf_to_lba(&toc->descriptors[c].p); - //pclog("Track %i %02x addr %08x\n", c, toc->descriptors[c].point, track_addr[c]); - if (toc->descriptors[c].point <= 99 && toc->descriptors[c].adr == 1) - last_track++; - } + for (c = 0; c < toc_tracks; c++) { + if (toc->descriptors[c].session > 1) + continue; + track_addr[c] = msf_to_lba(&toc->descriptors[c].p); + // pclog("Track %i %02x addr %08x\n", c, toc->descriptors[c].point, track_addr[c]); + if (toc->descriptors[c].point <= 99 && toc->descriptors[c].adr == 1) + last_track++; + } - //pclog("Tracks %i %i %i\n", first_track, last_track, toc_tracks); + // pclog("Tracks %i %i %i\n", first_track, last_track, toc_tracks); - cd_read_disc_info.buffer = &disc_info; - cd_read_disc_info.bufferLength = sizeof(disc_info); - result = ioctl(fd, DKIOCCDREADDISCINFO, &cd_read_disc_info); - if (result < 0) { - //pclog("read_toc: DKIOCCDREADDISCINFO failed\n"); - return 0; - } + cd_read_disc_info.buffer = &disc_info; + cd_read_disc_info.bufferLength = sizeof(disc_info); + result = ioctl(fd, DKIOCCDREADDISCINFO, &cd_read_disc_info); + if (result < 0) { + // pclog("read_toc: DKIOCCDREADDISCINFO failed\n"); + return 0; + } - return 1; + return 1; } static int ioctl_ready(void) { - int ioctl_fd = cd_open(); - //pclog("ioctl_ready - %d %d\n", ioctl_fd, tocvalid); - if (ioctl_fd <= 0) - return 0; - cd_close(ioctl_fd); + int ioctl_fd = cd_open(); + // pclog("ioctl_ready - %d %d\n", ioctl_fd, tocvalid); + if (ioctl_fd <= 0) + return 0; + cd_close(ioctl_fd); - if (tocvalid) - return 1; + if (tocvalid) + return 1; - return 0; + return 0; } static int ioctl_get_last_block(unsigned char starttrack, int msf, int maxlen, int single) { - int c; - int lb = 0; - int tv = 0; - int ioctl_fd; + int c; + int lb = 0; + int tv = 0; + int ioctl_fd; - ioctl_fd = cd_open(); - if (ioctl_fd <= 0) - return 0; + ioctl_fd = cd_open(); + if (ioctl_fd <= 0) + return 0; - //ioctl_cd_state = CD_STOPPED; + // ioctl_cd_state = CD_STOPPED; - if (!tocvalid) - tv = read_toc(ioctl_fd); + if (!tocvalid) + tv = read_toc(ioctl_fd); - cd_close(ioctl_fd); + cd_close(ioctl_fd); - if (!tv) - return 0; + if (!tv) + return 0; - for (c = 0; c <= toc_tracks; c++) { - if (track_addr[c] > lb) - lb = track_addr[c]; - } - return lb; + for (c = 0; c <= toc_tracks; c++) { + if (track_addr[c] > lb) + lb = track_addr[c]; + } + return lb; } static int ioctl_medium_changed(void) { - dk_cd_read_disc_info_t cd_read_disc_info; - CDDiscInfo new_disc_info; - int result; - int ioctl_fd; + dk_cd_read_disc_info_t cd_read_disc_info; + CDDiscInfo new_disc_info; + int result; + int ioctl_fd; - ioctl_fd = cd_open(); - if (ioctl_fd <= 0) - return 1; + ioctl_fd = cd_open(); + if (ioctl_fd <= 0) + return 1; - bzero(&cd_read_disc_info, sizeof(cd_read_disc_info)); - cd_read_disc_info.buffer = &new_disc_info; - cd_read_disc_info.bufferLength = sizeof(new_disc_info); - result = ioctl(ioctl_fd, DKIOCCDREADDISCINFO, &cd_read_disc_info); - if (result < 0) { - //pclog("medium_changed: DKIOCCDREADDISCINFO failed\n"); - ioctl_cd_state = CD_STOPPED; - tocvalid = 0; - cd_close(ioctl_fd); - return 1; - } + bzero(&cd_read_disc_info, sizeof(cd_read_disc_info)); + cd_read_disc_info.buffer = &new_disc_info; + cd_read_disc_info.bufferLength = sizeof(new_disc_info); + result = ioctl(ioctl_fd, DKIOCCDREADDISCINFO, &cd_read_disc_info); + if (result < 0) { + // pclog("medium_changed: DKIOCCDREADDISCINFO failed\n"); + ioctl_cd_state = CD_STOPPED; + tocvalid = 0; + cd_close(ioctl_fd); + return 1; + } - if (memcmp(&disc_info, &new_disc_info, sizeof(CDDiscInfo))) { - //pclog("medium_changed: disc changed\n"); - ioctl_cd_state = CD_STOPPED; - tocvalid = read_toc(ioctl_fd); - cd_close(ioctl_fd); - return 1; - } + if (memcmp(&disc_info, &new_disc_info, sizeof(CDDiscInfo))) { + // pclog("medium_changed: disc changed\n"); + ioctl_cd_state = CD_STOPPED; + tocvalid = read_toc(ioctl_fd); + cd_close(ioctl_fd); + return 1; + } - cd_close(ioctl_fd); - return 0; + cd_close(ioctl_fd); + return 0; } static uint8_t ioctl_getcurrentsubchannel(uint8_t *b, int msf) { - uint32_t cdpos = ioctl_cd_pos; - int track = get_track_nr(cdpos); - uint32_t track_address = track_addr[track]; - long size; - int pos = 0; - int err; - uint8_t ret; + uint32_t cdpos = ioctl_cd_pos; + int track = get_track_nr(cdpos); + uint32_t track_address = track_addr[track]; + long size; + int pos = 0; + int err; + uint8_t ret; - if (ioctl_cd_state == CD_PLAYING) - ret = 0x11; - else if (ioctl_cd_state == CD_PAUSED) - ret = 0x12; - else - ret = 0x13; + if (ioctl_cd_state == CD_PLAYING) + ret = 0x11; + else if (ioctl_cd_state == CD_PAUSED) + ret = 0x12; + else + ret = 0x13; - b[pos++] = (toc->descriptors[track].adr << 4) | toc->descriptors[track].control; - b[pos++] = toc->descriptors[track].point; - b[pos++] = 0; + b[pos++] = (toc->descriptors[track].adr << 4) | toc->descriptors[track].control; + b[pos++] = toc->descriptors[track].point; + b[pos++] = 0; - if (msf) { - uint32_t dat = cdpos; - b[pos + 3] = (uint8_t)(dat % 75); - dat /= 75; - b[pos + 2] = (uint8_t)(dat % 60); - dat /= 60; - b[pos + 1] = (uint8_t)dat; - b[pos] = 0; - pos += 4; - dat = cdpos - track_address; - b[pos + 3] = (uint8_t)(dat % 75); - dat /= 75; - b[pos + 2] = (uint8_t)(dat % 60); - dat /= 60; - b[pos + 1] = (uint8_t)dat; - b[pos] = 0; - pos += 4; - } else { - b[pos++] = (cdpos >> 24) & 0xff; - b[pos++] = (cdpos >> 16) & 0xff; - b[pos++] = (cdpos >> 8) & 0xff; - b[pos++] = cdpos & 0xff; - cdpos -= track_address; - b[pos++] = (cdpos >> 24) & 0xff; - b[pos++] = (cdpos >> 16) & 0xff; - b[pos++] = (cdpos >> 8) & 0xff; - b[pos++] = cdpos & 0xff; - } + if (msf) { + uint32_t dat = cdpos; + b[pos + 3] = (uint8_t)(dat % 75); + dat /= 75; + b[pos + 2] = (uint8_t)(dat % 60); + dat /= 60; + b[pos + 1] = (uint8_t)dat; + b[pos] = 0; + pos += 4; + dat = cdpos - track_address; + b[pos + 3] = (uint8_t)(dat % 75); + dat /= 75; + b[pos + 2] = (uint8_t)(dat % 60); + dat /= 60; + b[pos + 1] = (uint8_t)dat; + b[pos] = 0; + pos += 4; + } else { + b[pos++] = (cdpos >> 24) & 0xff; + b[pos++] = (cdpos >> 16) & 0xff; + b[pos++] = (cdpos >> 8) & 0xff; + b[pos++] = cdpos & 0xff; + cdpos -= track_address; + b[pos++] = (cdpos >> 24) & 0xff; + b[pos++] = (cdpos >> 16) & 0xff; + b[pos++] = (cdpos >> 8) & 0xff; + b[pos++] = cdpos & 0xff; + } - //pclog("ioctl_getsubchannel: cdpos=%x track_address=%x track=%i state=%i ret=%02x\n", cdpos, track_address, track, ioctl_cd_state, ret); + // pclog("ioctl_getsubchannel: cdpos=%x track_address=%x track=%i state=%i ret=%02x\n", cdpos, track_address, track, + // ioctl_cd_state, ret); - return ret; + return ret; } -static void ioctl_eject(void) { -} +static void ioctl_eject(void) {} -static void ioctl_load(void) { -} +static void ioctl_load(void) {} static int ioctl_readsector(uint8_t *b, int sector, int count) { - dk_cd_read_t cd_read; - int res; - int ioctl_fd; + dk_cd_read_t cd_read; + int res; + int ioctl_fd; - ioctl_fd = cd_open(); - if (ioctl_fd <= 0) - return -1; - //pclog("Read sector %x %i\n", sector, count); + ioctl_fd = cd_open(); + if (ioctl_fd <= 0) + return -1; + // pclog("Read sector %x %i\n", sector, count); - bzero(&cd_read, sizeof(cd_read)); + bzero(&cd_read, sizeof(cd_read)); - cd_read.offset = sector * 2048; - cd_read.buffer = b; - cd_read.bufferLength = count * 2048; - cd_read.sectorType = kCDSectorTypeMode1; - cd_read.sectorArea = kCDSectorAreaUser; + cd_read.offset = sector * 2048; + cd_read.buffer = b; + cd_read.bufferLength = count * 2048; + cd_read.sectorType = kCDSectorTypeMode1; + cd_read.sectorArea = kCDSectorAreaUser; - res = ioctl(ioctl_fd, DKIOCCDREAD, &cd_read); - //pclog("read res = %i %i %i\n", res, cd_read.bufferLength, errno); + res = ioctl(ioctl_fd, DKIOCCDREAD, &cd_read); + // pclog("read res = %i %i %i\n", res, cd_read.bufferLength, errno); - cd_close(ioctl_fd); + cd_close(ioctl_fd); - return 0; + return 0; } static void ioctl_readsector_raw(uint8_t *b, int sector) { - dk_cd_read_t cd_read; - int res; - int ioctl_fd; + dk_cd_read_t cd_read; + int res; + int ioctl_fd; - ioctl_fd = cd_open(); - if (ioctl_fd <= 0) - return; - //pclog("Read sector %x %i\n", sector, count); + ioctl_fd = cd_open(); + if (ioctl_fd <= 0) + return; + // pclog("Read sector %x %i\n", sector, count); - bzero(&cd_read, sizeof(cd_read)); + bzero(&cd_read, sizeof(cd_read)); - cd_read.offset = sector * kCDSectorSizeWhole; - cd_read.buffer = b; - cd_read.bufferLength = kCDSectorSizeWhole; - cd_read.sectorType = kCDSectorTypeUnknown; - cd_read.sectorArea = kCDSectorAreaUser; + cd_read.offset = sector * kCDSectorSizeWhole; + cd_read.buffer = b; + cd_read.bufferLength = kCDSectorSizeWhole; + cd_read.sectorType = kCDSectorTypeUnknown; + cd_read.sectorArea = kCDSectorAreaUser; - res = ioctl(ioctl_fd, DKIOCCDREAD, &cd_read); - //pclog("read res = %i %i %i\n", res, cd_read.bufferLength, errno); + res = ioctl(ioctl_fd, DKIOCCDREAD, &cd_read); + // pclog("read res = %i %i %i\n", res, cd_read.bufferLength, errno); - cd_close(ioctl_fd); + cd_close(ioctl_fd); } static int ioctl_readtoc(unsigned char *b, unsigned char starttrack, int msf, int maxlen, int single) { - int len = 4; - int c, d; - uint32_t temp; - uint32_t last_address = 0; - int seenAA = 0; + int len = 4; + int c, d; + uint32_t temp; + uint32_t last_address = 0; + int seenAA = 0; - pclog("ioctl_readtoc\n"); - //ioctl_cd_state = CD_STOPPED; + pclog("ioctl_readtoc\n"); + // ioctl_cd_state = CD_STOPPED; - if (!tocvalid) { - int ioctl_fd = cd_open(); + if (!tocvalid) { + int ioctl_fd = cd_open(); - if (ioctl_fd <= 0) - return 4; + if (ioctl_fd <= 0) + return 4; - tocvalid = read_toc(ioctl_fd); - cd_close(ioctl_fd); - } - if (!tocvalid) - return 4; + tocvalid = read_toc(ioctl_fd); + cd_close(ioctl_fd); + } + if (!tocvalid) + return 4; - //pclog("Read TOC done! %i\n",single); - b[2] = first_track; - b[3] = last_track; - d = 0; - //pclog("Read TOC starttrack=%i\n", starttrack); - for (c = 0; c <= toc_tracks; c++) { - if (toc->descriptors[c].point && toc->descriptors[c].point >= starttrack && toc->descriptors[c].point <= 99) { - d = c; - break; - } - } - //pclog("Start from track %i\n",d); - b[2] = toc->descriptors[c].point; - //last_block = 0; + // pclog("Read TOC done! %i\n",single); + b[2] = first_track; + b[3] = last_track; + d = 0; + // pclog("Read TOC starttrack=%i\n", starttrack); + for (c = 0; c <= toc_tracks; c++) { + if (toc->descriptors[c].point && toc->descriptors[c].point >= starttrack && toc->descriptors[c].point <= 99) { + d = c; + break; + } + } + // pclog("Start from track %i\n",d); + b[2] = toc->descriptors[c].point; + // last_block = 0; - for (c = d; c <= toc_tracks; c++) { - uint32_t address; - if ((len + 8) > maxlen) - break; - //pclog("Len %i max %i Track %02X - %02X %02X %02i:%02i:%02i %08X\n",len,maxlen,toc->descriptors[c].point,toc->descriptors[c].adr,toc->descriptors[c].control,toc->descriptors[c].p.minute, toc->descriptors[c].p.second, toc->descriptors[c].p.frame,track_addr[c]); - address = track_addr[c]; - if (address < last_address) - continue; - if (toc->descriptors[c].point == 0xaa) - seenAA = 1; - last_address = address; - b[len++] = 0; /*Reserved*/ - b[len++] = (toc->descriptors[c].adr << 4) | toc->descriptors[c].control; - b[len++] = toc->descriptors[c].point; - b[len++] = 0; /*Reserved*/ - //if (address > last_block) - // last_block = address; + for (c = d; c <= toc_tracks; c++) { + uint32_t address; + if ((len + 8) > maxlen) + break; + // pclog("Len %i max %i Track %02X - %02X %02X %02i:%02i:%02i + // %08X\n",len,maxlen,toc->descriptors[c].point,toc->descriptors[c].adr,toc->descriptors[c].control,toc->descriptors[c].p.minute, + // toc->descriptors[c].p.second, toc->descriptors[c].p.frame,track_addr[c]); + address = track_addr[c]; + if (address < last_address) + continue; + if (toc->descriptors[c].point == 0xaa) + seenAA = 1; + last_address = address; + b[len++] = 0; /*Reserved*/ + b[len++] = (toc->descriptors[c].adr << 4) | toc->descriptors[c].control; + b[len++] = toc->descriptors[c].point; + b[len++] = 0; /*Reserved*/ + // if (address > last_block) + // last_block = address; - if (msf) { - b[len++] = 0; - b[len++] = toc->descriptors[c].p.minute; - b[len++] = toc->descriptors[c].p.second; - b[len++] = toc->descriptors[c].p.frame; - } else { - temp = track_addr[c]; - b[len++] = temp >> 24; - b[len++] = temp >> 16; - b[len++] = temp >> 8; - b[len++] = temp; - } - if (single) - break; - } + if (msf) { + b[len++] = 0; + b[len++] = toc->descriptors[c].p.minute; + b[len++] = toc->descriptors[c].p.second; + b[len++] = toc->descriptors[c].p.frame; + } else { + temp = track_addr[c]; + b[len++] = temp >> 24; + b[len++] = temp >> 16; + b[len++] = temp >> 8; + b[len++] = temp; + } + if (single) + break; + } - if (!seenAA && !single) { - uint32_t lb = 0; + if (!seenAA && !single) { + uint32_t lb = 0; - for (c = 0; c <= toc_tracks; c++) { - if (track_addr[c] > lb) - lb = track_addr[c]; - } - //pclog("Track AA - %08x %i\n", lb, len); - b[len++] = 0; /*Reserved*/ - b[len++] = (1 << 4) | 1; - b[len++] = 0xaa; - b[len++] = 0; /*Reserved*/ + for (c = 0; c <= toc_tracks; c++) { + if (track_addr[c] > lb) + lb = track_addr[c]; + } + // pclog("Track AA - %08x %i\n", lb, len); + b[len++] = 0; /*Reserved*/ + b[len++] = (1 << 4) | 1; + b[len++] = 0xaa; + b[len++] = 0; /*Reserved*/ - if (msf) { - b[len++] = 0; - b[len++] = (lb / 60) / 75; - b[len++] = (lb / 75) % 60; - b[len++] = lb % 75; - } else { - temp = track_addr[c]; - b[len++] = lb >> 24; - b[len++] = lb >> 16; - b[len++] = lb >> 8; - b[len++] = lb; - } - } + if (msf) { + b[len++] = 0; + b[len++] = (lb / 60) / 75; + b[len++] = (lb / 75) % 60; + b[len++] = lb % 75; + } else { + temp = track_addr[c]; + b[len++] = lb >> 24; + b[len++] = lb >> 16; + b[len++] = lb >> 8; + b[len++] = lb; + } + } - b[0] = (uint8_t)(((len - 2) >> 8) & 0xff); - b[1] = (uint8_t)((len - 2) & 0xff); -/* pclog("Table of Contents (%i bytes) : \n", size); - pclog("First track - %02X\n", first_track); - pclog("Last track - %02X\n", last_track); - for (c = 0; c <= last_track; c++) - pclog("Track %02X - number %02X control %02X adr %02X address %02X %02X %02X %02X\n", c, toc[c].cdte_track, toc[c].cdte_ctrl, toc[c].cdte_adr, 0, toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame); - for (c = 0;c <= last_track; c++) - pclog("Track %02X - number %02X control %02X adr %02X address %06X\n", c, toc[c].cdte_track, toc[c].cdte_ctrl, toc[c].cdte_adr, MSFtoLBA(toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame));*/ - return len; + b[0] = (uint8_t)(((len - 2) >> 8) & 0xff); + b[1] = (uint8_t)((len - 2) & 0xff); + /* pclog("Table of Contents (%i bytes) : \n", size); + pclog("First track - %02X\n", first_track); + pclog("Last track - %02X\n", last_track); + for (c = 0; c <= last_track; c++) + pclog("Track %02X - number %02X control %02X adr %02X address %02X %02X %02X %02X\n", c, toc[c].cdte_track, + toc[c].cdte_ctrl, toc[c].cdte_adr, 0, toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, + toc[c].cdte_addr.msf.frame); for (c = 0;c <= last_track; c++) pclog("Track %02X - number %02X control %02X adr %02X + address %06X\n", c, toc[c].cdte_track, toc[c].cdte_ctrl, toc[c].cdte_adr, MSFtoLBA(toc[c].cdte_addr.msf.minute, + toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame));*/ + return len; } static int ioctl_readtoc_session(unsigned char *b, int msf, int maxlen) { - int len = 4; - int session = 0, first_track_nr = 0; - int c, d; + int len = 4; + int session = 0, first_track_nr = 0; + int c, d; - if (!tocvalid) { - int ioctl_fd = cd_open(); + if (!tocvalid) { + int ioctl_fd = cd_open(); - if (ioctl_fd <= 0) - return 4; + if (ioctl_fd <= 0) + return 4; - tocvalid = read_toc(ioctl_fd); - cd_close(ioctl_fd); - } + tocvalid = read_toc(ioctl_fd); + cd_close(ioctl_fd); + } - if (!tocvalid) - return 4; + if (!tocvalid) + return 4; - for (c = 0; c <= toc_tracks; c++) { - if (toc->descriptors[c].point && toc->descriptors[c].point <= 99) { - if (toc->descriptors[c].session > session || (toc->descriptors[c].session == session && toc->descriptors[c].point < first_track_nr)) { - session = toc->descriptors[c].session; - first_track_nr = toc->descriptors[c].point; - d = c; - } - } - } + for (c = 0; c <= toc_tracks; c++) { + if (toc->descriptors[c].point && toc->descriptors[c].point <= 99) { + if (toc->descriptors[c].session > session || + (toc->descriptors[c].session == session && toc->descriptors[c].point < first_track_nr)) { + session = toc->descriptors[c].session; + first_track_nr = toc->descriptors[c].point; + d = c; + } + } + } - b[2] = toc->sessionFirst; - b[3] = toc->sessionLast; - b[len++] = 0; /*Reserved*/ - b[len++] = (toc->descriptors[d].adr << 4) | toc->descriptors[d].control; - b[len++] = toc->descriptors[d].point; - b[len++] = 0; /*Reserved*/ - if (msf) { - b[len++] = 0; - b[len++] = toc->descriptors[d].p.minute; - b[len++] = toc->descriptors[d].p.second; - b[len++] = toc->descriptors[d].p.frame; - } else { - uint32_t temp = track_addr[d]; - b[len++] = temp >> 24; - b[len++] = temp >> 16; - b[len++] = temp >> 8; - b[len++] = temp; - } + b[2] = toc->sessionFirst; + b[3] = toc->sessionLast; + b[len++] = 0; /*Reserved*/ + b[len++] = (toc->descriptors[d].adr << 4) | toc->descriptors[d].control; + b[len++] = toc->descriptors[d].point; + b[len++] = 0; /*Reserved*/ + if (msf) { + b[len++] = 0; + b[len++] = toc->descriptors[d].p.minute; + b[len++] = toc->descriptors[d].p.second; + b[len++] = toc->descriptors[d].p.frame; + } else { + uint32_t temp = track_addr[d]; + b[len++] = temp >> 24; + b[len++] = temp >> 16; + b[len++] = temp >> 8; + b[len++] = temp; + } - return len; + return len; } static int ioctl_readtoc_raw(unsigned char *b, int maxlen) { - int len = 4; - int ioctl_fd; - int track; + int len = 4; + int ioctl_fd; + int track; -//pclog("read_toc\n"); - if (!tocvalid) - return 0; + // pclog("read_toc\n"); + if (!tocvalid) + return 0; - ioctl_fd = cd_open(); - if (ioctl_fd <= 0) - return 0; - cd_close(ioctl_fd); + ioctl_fd = cd_open(); + if (ioctl_fd <= 0) + return 0; + cd_close(ioctl_fd); - b[2] = toc->sessionFirst; - b[3] = toc->sessionLast; + b[2] = toc->sessionFirst; + b[3] = toc->sessionLast; - for (track = 0; track <= toc_tracks; track++) { - if ((len + 11) > maxlen) { - pclog("ioctl_readtocraw: This iteration would fill the buffer beyond the bounds, aborting...\n"); - return len; - } + for (track = 0; track <= toc_tracks; track++) { + if ((len + 11) > maxlen) { + pclog("ioctl_readtocraw: This iteration would fill the buffer beyond the bounds, aborting...\n"); + return len; + } + // pclog("read_toc: Track %02X - number %02X control %02X adr %02X address %02X %02X %02X %02X\n", + //track, toc[track].cdte_track, toc[track].cdte_ctrl, toc[track].cdte_adr, 0, toc[track].cdte_addr.msf.minute, + //toc[track].cdte_addr.msf.second, toc[track].cdte_addr.msf.frame); -// pclog("read_toc: Track %02X - number %02X control %02X adr %02X address %02X %02X %02X %02X\n", track, toc[track].cdte_track, toc[track].cdte_ctrl, toc[track].cdte_adr, 0, toc[track].cdte_addr.msf.minute, toc[track].cdte_addr.msf.second, toc[track].cdte_addr.msf.frame); + b[len++] = toc->descriptors[track].session; + b[len++] = (toc->descriptors[track].adr << 4) | toc->descriptors[track].control; + b[len++] = toc->descriptors[track].tno; + b[len++] = toc->descriptors[track].point; + b[len++] = toc->descriptors[track].address.minute; + b[len++] = toc->descriptors[track].address.second; + b[len++] = toc->descriptors[track].address.frame; + b[len++] = toc->descriptors[track].zero; + b[len++] = toc->descriptors[track].p.minute; + b[len++] = toc->descriptors[track].p.second; + b[len++] = toc->descriptors[track].p.frame; + } - b[len++] = toc->descriptors[track].session; - b[len++] = (toc->descriptors[track].adr << 4) | toc->descriptors[track].control; - b[len++] = toc->descriptors[track].tno; - b[len++] = toc->descriptors[track].point; - b[len++] = toc->descriptors[track].address.minute; - b[len++] = toc->descriptors[track].address.second; - b[len++] = toc->descriptors[track].address.frame; - b[len++] = toc->descriptors[track].zero; - b[len++] = toc->descriptors[track].p.minute; - b[len++] = toc->descriptors[track].p.second; - b[len++] = toc->descriptors[track].p.frame; - } - - return len; + return len; } -static uint32_t ioctl_size() { - return cdrom_capacity; -} +static uint32_t ioctl_size() { return cdrom_capacity; } static int ioctl_status() { - if (!ioctl_ready) - return CD_STATUS_EMPTY; - return CD_STATUS_STOPPED; + if (!ioctl_ready) + return CD_STATUS_EMPTY; + return CD_STATUS_STOPPED; } void ioctl_reset() { - int ioctl_fd; + int ioctl_fd; - tocvalid = 0; + tocvalid = 0; - ioctl_fd = cd_open(); - if (ioctl_fd <= 0) - return; + ioctl_fd = cd_open(); + if (ioctl_fd <= 0) + return; - tocvalid = read_toc(ioctl_fd); - cd_close(ioctl_fd); + tocvalid = read_toc(ioctl_fd); + cd_close(ioctl_fd); } void ioctl_set_drive(char d) { - ioctl_close(); - atapi = &ioctl_atapi; - ioctl_open(d); + ioctl_close(); + atapi = &ioctl_atapi; + ioctl_open(d); } int ioctl_open(char d) { - atapi = &ioctl_atapi; + atapi = &ioctl_atapi; - toc = malloc(2048); + toc = malloc(2048); - cd_drive = d; - return 0; + cd_drive = d; + return 0; } void ioctl_close(void) { - if (toc) { - free(toc); - toc = NULL; - } + if (toc) { + free(toc); + toc = NULL; + } } -static void ioctl_exit(void) { +static void ioctl_exit(void) {} -} - -static ATAPI ioctl_atapi = - { - ioctl_ready, - ioctl_medium_changed, - ioctl_readtoc, - ioctl_readtoc_session, - ioctl_readtoc_raw, - ioctl_getcurrentsubchannel, - ioctl_readsector, - ioctl_readsector_raw, - ioctl_playaudio, - ioctl_seek, - ioctl_load, - ioctl_eject, - ioctl_pause, - ioctl_resume, - ioctl_size, - ioctl_status, - ioctl_is_track_audio, - ioctl_stop, - ioctl_exit - }; +static ATAPI ioctl_atapi = {ioctl_ready, + ioctl_medium_changed, + ioctl_readtoc, + ioctl_readtoc_session, + ioctl_readtoc_raw, + ioctl_getcurrentsubchannel, + ioctl_readsector, + ioctl_readsector_raw, + ioctl_playaudio, + ioctl_seek, + ioctl_load, + ioctl_eject, + ioctl_pause, + ioctl_resume, + ioctl_size, + ioctl_status, + ioctl_is_track_audio, + ioctl_stop, + ioctl_exit}; diff --git a/src/cdrom/cdrom-ioctl.c b/src/cdrom/cdrom-ioctl.c index 72e079d0..aab995db 100644 --- a/src/cdrom/cdrom-ioctl.c +++ b/src/cdrom/cdrom-ioctl.c @@ -17,13 +17,12 @@ int cdrom_drive; int old_cdrom_drive; #ifndef __MINGW64_VERSION_MAJOR -typedef struct _CDROM_TOC_SESSION_DATA -{ - UCHAR Length[2]; - UCHAR FirstCompleteSession; - UCHAR LastCompleteSession; - TRACK_DATA TrackData[1]; -} CDROM_TOC_SESSION_DATA, * PCDROM_TOC_SESSION_DATA; +typedef struct _CDROM_TOC_SESSION_DATA { + UCHAR Length[2]; + UCHAR FirstCompleteSession; + UCHAR LastCompleteSession; + TRACK_DATA TrackData[1]; +} CDROM_TOC_SESSION_DATA, *PCDROM_TOC_SESSION_DATA; #endif static ATAPI ioctl_atapi; @@ -36,13 +35,9 @@ static HANDLE hIOCTL; static CDROM_TOC toc; static int tocvalid = 0; -#define MSFtoLBA(m, s, f) ((((m*60)+s)*75)+f) +#define MSFtoLBA(m, s, f) ((((m * 60) + s) * 75) + f) -enum { - CD_STOPPED = 0, - CD_PLAYING, - CD_PAUSED -}; +enum { CD_STOPPED = 0, CD_PLAYING, CD_PAUSED }; static int ioctl_cd_state = CD_STOPPED; static uint32_t ioctl_cd_pos = 0, ioctl_cd_end = 0; @@ -51,712 +46,713 @@ static uint32_t ioctl_cd_pos = 0, ioctl_cd_end = 0; static int16_t cd_buffer[BUF_SIZE]; static int cd_buflen = 0; void ioctl_audio_callback(int16_t *output, int len) { - RAW_READ_INFO in; - DWORD count; + RAW_READ_INFO in; + DWORD count; -// return; -// pclog("Audio callback %08X %08X %i %i %i %04X %i\n", ioctl_cd_pos, ioctl_cd_end, ioctl_cd_state, cd_buflen, len, cd_buffer[4], GetTickCount()); - if (ioctl_cd_state != CD_PLAYING) - return; - while (cd_buflen < len) { - if (ioctl_cd_pos < ioctl_cd_end) { - in.DiskOffset.LowPart = (ioctl_cd_pos - 150) * 2048; - in.DiskOffset.HighPart = 0; - in.SectorCount = 1; - in.TrackMode = CDDA; - ioctl_open(0); -// pclog("Read to %i\n", cd_buflen); - if (!DeviceIoControl(hIOCTL, IOCTL_CDROM_RAW_READ, &in, sizeof(in), &cd_buffer[cd_buflen], 2352, &count, NULL)) { -// pclog("DeviceIoControl returned false\n"); - memset(&cd_buffer[cd_buflen], 0, (BUF_SIZE - cd_buflen) * 2); - ioctl_cd_state = CD_STOPPED; - cd_buflen = len; - } else { -// pclog("DeviceIoControl returned true\n"); - ioctl_cd_pos++; - cd_buflen += (2352 / 2); - } - ioctl_close(); - } else { - memset(&cd_buffer[cd_buflen], 0, (BUF_SIZE - cd_buflen) * 2); - ioctl_cd_state = CD_STOPPED; - cd_buflen = len; - } - } - memcpy(output, cd_buffer, len * 2); -// for (c = 0; c < BUF_SIZE - len; c++) -// cd_buffer[c] = cd_buffer[c + cd_buflen]; - memcpy(&cd_buffer[0], &cd_buffer[len], (BUF_SIZE - len) * 2); - cd_buflen -= len; -// pclog("Done %i\n", GetTickCount()); + // return; + // pclog("Audio callback %08X %08X %i %i %i %04X %i\n", ioctl_cd_pos, ioctl_cd_end, ioctl_cd_state, cd_buflen, len, + // cd_buffer[4], GetTickCount()); + if (ioctl_cd_state != CD_PLAYING) + return; + while (cd_buflen < len) { + if (ioctl_cd_pos < ioctl_cd_end) { + in.DiskOffset.LowPart = (ioctl_cd_pos - 150) * 2048; + in.DiskOffset.HighPart = 0; + in.SectorCount = 1; + in.TrackMode = CDDA; + ioctl_open(0); + // pclog("Read to %i\n", cd_buflen); + if (!DeviceIoControl(hIOCTL, IOCTL_CDROM_RAW_READ, &in, sizeof(in), &cd_buffer[cd_buflen], 2352, &count, + NULL)) { + // pclog("DeviceIoControl returned false\n"); + memset(&cd_buffer[cd_buflen], 0, (BUF_SIZE - cd_buflen) * 2); + ioctl_cd_state = CD_STOPPED; + cd_buflen = len; + } else { + // pclog("DeviceIoControl returned true\n"); + ioctl_cd_pos++; + cd_buflen += (2352 / 2); + } + ioctl_close(); + } else { + memset(&cd_buffer[cd_buflen], 0, (BUF_SIZE - cd_buflen) * 2); + ioctl_cd_state = CD_STOPPED; + cd_buflen = len; + } + } + memcpy(output, cd_buffer, len * 2); + // for (c = 0; c < BUF_SIZE - len; c++) + // cd_buffer[c] = cd_buffer[c + cd_buflen]; + memcpy(&cd_buffer[0], &cd_buffer[len], (BUF_SIZE - len) * 2); + cd_buflen -= len; + // pclog("Done %i\n", GetTickCount()); } -void ioctl_audio_stop() { - ioctl_cd_state = CD_STOPPED; -} +void ioctl_audio_stop() { ioctl_cd_state = CD_STOPPED; } static int get_track_nr(uint32_t pos) { - int c; - int track = 0; + int c; + int track = 0; - if (!tocvalid) - return 0; + if (!tocvalid) + return 0; - for (c = toc.FirstTrack; c < toc.LastTrack; c++) { - uint32_t track_address = toc.TrackData[c].Address[3] + - (toc.TrackData[c].Address[2] * 75) + - (toc.TrackData[c].Address[1] * 75 * 60); + for (c = toc.FirstTrack; c < toc.LastTrack; c++) { + uint32_t track_address = toc.TrackData[c].Address[3] + (toc.TrackData[c].Address[2] * 75) + + (toc.TrackData[c].Address[1] * 75 * 60); - if (track_address <= pos) - track = c; - } - return track; + if (track_address <= pos) + track = c; + } + return track; } static void ioctl_playaudio(uint32_t pos, uint32_t len, int ismsf) { - if (!cdrom_drive) - return; - pclog("Play audio - %08X %08X %i\n", pos, len, ismsf); - if (ismsf) { - int m = (pos >> 16) & 0xff; - int s = (pos >> 8) & 0xff; - int f = pos & 0xff; - pos = MSFtoLBA(m, s, f); - m = (len >> 16) & 0xff; - s = (len >> 8) & 0xff; - f = len & 0xff; - len = MSFtoLBA(m, s, f); - pclog("MSF - pos = %08X len = %08X\n", pos, len); - } else - len += pos; - ioctl_cd_pos = pos;// + 150; - ioctl_cd_end = len;// + 150; - ioctl_cd_state = CD_PLAYING; - if (ioctl_cd_pos < 150) - ioctl_cd_pos = 150; - pclog("Audio start %08X %08X %i %i %i\n", ioctl_cd_pos, ioctl_cd_end, ioctl_cd_state, cd_buflen, len); -/* CDROM_PLAY_AUDIO_MSF msf; - long size; - BOOL b; - if (ismsf) - { - msf.StartingF=pos&0xFF; - msf.StartingS=(pos>>8)&0xFF; - msf.StartingM=(pos>>16)&0xFF; - msf.EndingF=len&0xFF; - msf.EndingS=(len>>8)&0xFF; - msf.EndingM=(len>>16)&0xFF; - } - else - { - msf.StartingF=(uint8_t)(addr%75); addr/=75; - msf.StartingS=(uint8_t)(addr%60); addr/=60; - msf.StartingM=(uint8_t)(addr); - addr=pos+len+150; - msf.EndingF=(uint8_t)(addr%75); addr/=75; - msf.EndingS=(uint8_t)(addr%60); addr/=60; - msf.EndingM=(uint8_t)(addr); - } - ioctl_open(0); - b = DeviceIoControl(hIOCTL,IOCTL_CDROM_PLAY_AUDIO_MSF,&msf,sizeof(msf),NULL,0,&size,NULL); - pclog("DeviceIoControl returns %i\n", (int) b); - ioctl_close();*/ + if (!cdrom_drive) + return; + pclog("Play audio - %08X %08X %i\n", pos, len, ismsf); + if (ismsf) { + int m = (pos >> 16) & 0xff; + int s = (pos >> 8) & 0xff; + int f = pos & 0xff; + pos = MSFtoLBA(m, s, f); + m = (len >> 16) & 0xff; + s = (len >> 8) & 0xff; + f = len & 0xff; + len = MSFtoLBA(m, s, f); + pclog("MSF - pos = %08X len = %08X\n", pos, len); + } else + len += pos; + ioctl_cd_pos = pos; // + 150; + ioctl_cd_end = len; // + 150; + ioctl_cd_state = CD_PLAYING; + if (ioctl_cd_pos < 150) + ioctl_cd_pos = 150; + pclog("Audio start %08X %08X %i %i %i\n", ioctl_cd_pos, ioctl_cd_end, ioctl_cd_state, cd_buflen, len); + /* CDROM_PLAY_AUDIO_MSF msf; + long size; + BOOL b; + if (ismsf) + { + msf.StartingF=pos&0xFF; + msf.StartingS=(pos>>8)&0xFF; + msf.StartingM=(pos>>16)&0xFF; + msf.EndingF=len&0xFF; + msf.EndingS=(len>>8)&0xFF; + msf.EndingM=(len>>16)&0xFF; + } + else + { + msf.StartingF=(uint8_t)(addr%75); addr/=75; + msf.StartingS=(uint8_t)(addr%60); addr/=60; + msf.StartingM=(uint8_t)(addr); + addr=pos+len+150; + msf.EndingF=(uint8_t)(addr%75); addr/=75; + msf.EndingS=(uint8_t)(addr%60); addr/=60; + msf.EndingM=(uint8_t)(addr); + } + ioctl_open(0); + b = DeviceIoControl(hIOCTL,IOCTL_CDROM_PLAY_AUDIO_MSF,&msf,sizeof(msf),NULL,0,&size,NULL); + pclog("DeviceIoControl returns %i\n", (int) b); + ioctl_close();*/ } static void ioctl_pause(void) { - if (!cdrom_drive) - return; - if (ioctl_cd_state == CD_PLAYING) - ioctl_cd_state = CD_PAUSED; -// ioctl_open(0); -// DeviceIoControl(hIOCTL,IOCTL_CDROM_PAUSE_AUDIO,NULL,0,NULL,0,&size,NULL); -// ioctl_close(); + if (!cdrom_drive) + return; + if (ioctl_cd_state == CD_PLAYING) + ioctl_cd_state = CD_PAUSED; + // ioctl_open(0); + // DeviceIoControl(hIOCTL,IOCTL_CDROM_PAUSE_AUDIO,NULL,0,NULL,0,&size,NULL); + // ioctl_close(); } static void ioctl_resume(void) { - if (!cdrom_drive) - return; - if (ioctl_cd_state == CD_PAUSED) - ioctl_cd_state = CD_PLAYING; -// ioctl_open(0); -// DeviceIoControl(hIOCTL,IOCTL_CDROM_RESUME_AUDIO,NULL,0,NULL,0,&size,NULL); -// ioctl_close(); + if (!cdrom_drive) + return; + if (ioctl_cd_state == CD_PAUSED) + ioctl_cd_state = CD_PLAYING; + // ioctl_open(0); + // DeviceIoControl(hIOCTL,IOCTL_CDROM_RESUME_AUDIO,NULL,0,NULL,0,&size,NULL); + // ioctl_close(); } static void ioctl_stop(void) { - if (!cdrom_drive) - return; - ioctl_cd_state = CD_STOPPED; -// ioctl_open(0); -// DeviceIoControl(hIOCTL,IOCTL_CDROM_STOP_AUDIO,NULL,0,NULL,0,&size,NULL); -// ioctl_close(); + if (!cdrom_drive) + return; + ioctl_cd_state = CD_STOPPED; + // ioctl_open(0); + // DeviceIoControl(hIOCTL,IOCTL_CDROM_STOP_AUDIO,NULL,0,NULL,0,&size,NULL); + // ioctl_close(); } static void ioctl_seek(uint32_t pos) { - if (!cdrom_drive) - return; - // ioctl_cd_state = CD_STOPPED; - pclog("Seek %08X\n", pos); - ioctl_cd_pos = pos; - ioctl_cd_state = CD_STOPPED; -/* pos+=150; - CDROM_SEEK_AUDIO_MSF msf; - msf.F=(uint8_t)(pos%75); pos/=75; - msf.S=(uint8_t)(pos%60); pos/=60; - msf.M=(uint8_t)(pos); -// pclog("Seek to %02i:%02i:%02i\n",msf.M,msf.S,msf.F); - ioctl_open(0); - DeviceIoControl(hIOCTL,IOCTL_CDROM_SEEK_AUDIO_MSF,&msf,sizeof(msf),NULL,0,&size,NULL); - ioctl_close();*/ + if (!cdrom_drive) + return; + // ioctl_cd_state = CD_STOPPED; + pclog("Seek %08X\n", pos); + ioctl_cd_pos = pos; + ioctl_cd_state = CD_STOPPED; + /* pos+=150; + CDROM_SEEK_AUDIO_MSF msf; + msf.F=(uint8_t)(pos%75); pos/=75; + msf.S=(uint8_t)(pos%60); pos/=60; + msf.M=(uint8_t)(pos); + // pclog("Seek to %02i:%02i:%02i\n",msf.M,msf.S,msf.F); + ioctl_open(0); + DeviceIoControl(hIOCTL,IOCTL_CDROM_SEEK_AUDIO_MSF,&msf,sizeof(msf),NULL,0,&size,NULL); + ioctl_close();*/ } static int ioctl_ready(void) { - long size; - int temp; - CDROM_TOC ltoc; -// pclog("Ready? %i\n",cdrom_drive); - if (!cdrom_drive) - return 0; - ioctl_open(0); - temp = DeviceIoControl(hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, <oc, sizeof(ltoc), (LPDWORD)&size, NULL); - ioctl_close(); - if (!temp) - return 0; - //pclog("ioctl_ready(): Drive opened successfully\n"); - //if ((cdrom_drive != old_cdrom_drive)) pclog("Drive has changed\n"); - if ((ltoc.TrackData[ltoc.LastTrack].Address[1] != toc.TrackData[toc.LastTrack].Address[1]) || - (ltoc.TrackData[ltoc.LastTrack].Address[2] != toc.TrackData[toc.LastTrack].Address[2]) || - (ltoc.TrackData[ltoc.LastTrack].Address[3] != toc.TrackData[toc.LastTrack].Address[3]) || - !tocvalid || (cdrom_drive != old_cdrom_drive)) { - //pclog("ioctl_ready(): Disc or drive changed\n"); - ioctl_cd_state = CD_STOPPED; - /* pclog("Not ready %02X %02X %02X %02X %02X %02X %i\n",ltoc.TrackData[ltoc.LastTrack].Address[1],ltoc.TrackData[ltoc.LastTrack].Address[2],ltoc.TrackData[ltoc.LastTrack].Address[3], - toc.TrackData[ltoc.LastTrack].Address[1], toc.TrackData[ltoc.LastTrack].Address[2], toc.TrackData[ltoc.LastTrack].Address[3],tocvalid);*/ - // atapi_discchanged(); -/* ioctl_open(0); - temp=DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_TOC, NULL,0,&toc,sizeof(toc),&size,NULL); - ioctl_close();*/ - if (cdrom_drive != old_cdrom_drive) - old_cdrom_drive = cdrom_drive; - return 1; - } -// pclog("IOCTL says ready\n"); -// pclog("ioctl_ready(): All is good\n"); - return 1; + long size; + int temp; + CDROM_TOC ltoc; + // pclog("Ready? %i\n",cdrom_drive); + if (!cdrom_drive) + return 0; + ioctl_open(0); + temp = DeviceIoControl(hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, <oc, sizeof(ltoc), (LPDWORD)&size, NULL); + ioctl_close(); + if (!temp) + return 0; + // pclog("ioctl_ready(): Drive opened successfully\n"); + // if ((cdrom_drive != old_cdrom_drive)) pclog("Drive has changed\n"); + if ((ltoc.TrackData[ltoc.LastTrack].Address[1] != toc.TrackData[toc.LastTrack].Address[1]) || + (ltoc.TrackData[ltoc.LastTrack].Address[2] != toc.TrackData[toc.LastTrack].Address[2]) || + (ltoc.TrackData[ltoc.LastTrack].Address[3] != toc.TrackData[toc.LastTrack].Address[3]) || !tocvalid || + (cdrom_drive != old_cdrom_drive)) { + // pclog("ioctl_ready(): Disc or drive changed\n"); + ioctl_cd_state = CD_STOPPED; + /* pclog("Not ready %02X %02X %02X %02X %02X %02X + %i\n",ltoc.TrackData[ltoc.LastTrack].Address[1],ltoc.TrackData[ltoc.LastTrack].Address[2],ltoc.TrackData[ltoc.LastTrack].Address[3], + toc.TrackData[ltoc.LastTrack].Address[1], + toc.TrackData[ltoc.LastTrack].Address[2], toc.TrackData[ltoc.LastTrack].Address[3],tocvalid);*/ + // atapi_discchanged(); + /* ioctl_open(0); + temp=DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_TOC, NULL,0,&toc,sizeof(toc),&size,NULL); + ioctl_close();*/ + if (cdrom_drive != old_cdrom_drive) + old_cdrom_drive = cdrom_drive; + return 1; + } + // pclog("IOCTL says ready\n"); + // pclog("ioctl_ready(): All is good\n"); + return 1; } static int ioctl_get_last_block(unsigned char starttrack, int msf, int maxlen, int single) { - long size; - int c; - CDROM_TOC lbtoc; - int lb = 0; + long size; + int c; + CDROM_TOC lbtoc; + int lb = 0; - if (!cdrom_drive) - return 0; + if (!cdrom_drive) + return 0; - ioctl_cd_state = CD_STOPPED; + ioctl_cd_state = CD_STOPPED; - ioctl_open(0); - DeviceIoControl(hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, &lbtoc, sizeof(lbtoc), (LPDWORD)&size, NULL); - ioctl_close(); - tocvalid = 1; - for (c = 0; c <= lbtoc.LastTrack; c++) { - uint32_t address; - address = MSFtoLBA(toc.TrackData[c].Address[1], toc.TrackData[c].Address[2], toc.TrackData[c].Address[3]); - if (address > lb) - lb = address; - } - return lb; + ioctl_open(0); + DeviceIoControl(hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, &lbtoc, sizeof(lbtoc), (LPDWORD)&size, NULL); + ioctl_close(); + tocvalid = 1; + for (c = 0; c <= lbtoc.LastTrack; c++) { + uint32_t address; + address = MSFtoLBA(toc.TrackData[c].Address[1], toc.TrackData[c].Address[2], toc.TrackData[c].Address[3]); + if (address > lb) + lb = address; + } + return lb; } static int ioctl_medium_changed(void) { - long size; - int temp; - CDROM_TOC ltoc; - if (!cdrom_drive) - return 0; /* This will be handled by the not ready handler instead. */ - ioctl_open(0); - temp = DeviceIoControl(hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, <oc, sizeof(ltoc), (LPDWORD)&size, NULL); - ioctl_close(); - if (!temp) - return 0; /* Drive empty, a not ready handler matter, not disc change. */ - if (!tocvalid || (cdrom_drive != old_cdrom_drive)) { - ioctl_cd_state = CD_STOPPED; - toc = ltoc; - tocvalid = 1; - if (cdrom_drive != old_cdrom_drive) - old_cdrom_drive = cdrom_drive; - cdrom_capacity = ioctl_get_last_block(0, 0, 4096, 0); - return 0; - } - if ((ltoc.TrackData[ltoc.LastTrack].Address[1] != toc.TrackData[toc.LastTrack].Address[1]) || - (ltoc.TrackData[ltoc.LastTrack].Address[2] != toc.TrackData[toc.LastTrack].Address[2]) || - (ltoc.TrackData[ltoc.LastTrack].Address[3] != toc.TrackData[toc.LastTrack].Address[3])) { - ioctl_cd_state = CD_STOPPED; - toc = ltoc; - cdrom_capacity = ioctl_get_last_block(0, 0, 4096, 0); - return 1; /* TOC mismatches. */ - } - return 0; /* None of the above, return 0. */ + long size; + int temp; + CDROM_TOC ltoc; + if (!cdrom_drive) + return 0; /* This will be handled by the not ready handler instead. */ + ioctl_open(0); + temp = DeviceIoControl(hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, <oc, sizeof(ltoc), (LPDWORD)&size, NULL); + ioctl_close(); + if (!temp) + return 0; /* Drive empty, a not ready handler matter, not disc change. */ + if (!tocvalid || (cdrom_drive != old_cdrom_drive)) { + ioctl_cd_state = CD_STOPPED; + toc = ltoc; + tocvalid = 1; + if (cdrom_drive != old_cdrom_drive) + old_cdrom_drive = cdrom_drive; + cdrom_capacity = ioctl_get_last_block(0, 0, 4096, 0); + return 0; + } + if ((ltoc.TrackData[ltoc.LastTrack].Address[1] != toc.TrackData[toc.LastTrack].Address[1]) || + (ltoc.TrackData[ltoc.LastTrack].Address[2] != toc.TrackData[toc.LastTrack].Address[2]) || + (ltoc.TrackData[ltoc.LastTrack].Address[3] != toc.TrackData[toc.LastTrack].Address[3])) { + ioctl_cd_state = CD_STOPPED; + toc = ltoc; + cdrom_capacity = ioctl_get_last_block(0, 0, 4096, 0); + return 1; /* TOC mismatches. */ + } + return 0; /* None of the above, return 0. */ } static uint8_t ioctl_getcurrentsubchannel(uint8_t *b, int msf) { - CDROM_SUB_Q_DATA_FORMAT insub; - SUB_Q_CHANNEL_DATA sub; - long size; - int pos = 0; - if (!cdrom_drive) - return 0; + CDROM_SUB_Q_DATA_FORMAT insub; + SUB_Q_CHANNEL_DATA sub; + long size; + int pos = 0; + if (!cdrom_drive) + return 0; - insub.Format = IOCTL_CDROM_CURRENT_POSITION; - ioctl_open(0); - DeviceIoControl(hIOCTL, IOCTL_CDROM_READ_Q_CHANNEL, &insub, sizeof(insub), &sub, sizeof(sub), (LPDWORD)&size, NULL); - ioctl_close(); + insub.Format = IOCTL_CDROM_CURRENT_POSITION; + ioctl_open(0); + DeviceIoControl(hIOCTL, IOCTL_CDROM_READ_Q_CHANNEL, &insub, sizeof(insub), &sub, sizeof(sub), (LPDWORD)&size, NULL); + ioctl_close(); - if (ioctl_cd_state == CD_PLAYING || ioctl_cd_state == CD_PAUSED) { - uint32_t cdpos = ioctl_cd_pos; - int track = get_track_nr(cdpos); - uint32_t track_address = toc.TrackData[track].Address[3] + - (toc.TrackData[track].Address[2] * 75) + - (toc.TrackData[track].Address[1] * 75 * 60); + if (ioctl_cd_state == CD_PLAYING || ioctl_cd_state == CD_PAUSED) { + uint32_t cdpos = ioctl_cd_pos; + int track = get_track_nr(cdpos); + uint32_t track_address = toc.TrackData[track].Address[3] + (toc.TrackData[track].Address[2] * 75) + + (toc.TrackData[track].Address[1] * 75 * 60); - b[pos++] = sub.CurrentPosition.Control; - b[pos++] = track + 1; - b[pos++] = sub.CurrentPosition.IndexNumber; + b[pos++] = sub.CurrentPosition.Control; + b[pos++] = track + 1; + b[pos++] = sub.CurrentPosition.IndexNumber; - if (msf) { - uint32_t dat = cdpos; - b[pos + 3] = (uint8_t)(dat % 75); - dat /= 75; - b[pos + 2] = (uint8_t)(dat % 60); - dat /= 60; - b[pos + 1] = (uint8_t)dat; - b[pos] = 0; - pos += 4; - dat = cdpos - track_address; - b[pos + 3] = (uint8_t)(dat % 75); - dat /= 75; - b[pos + 2] = (uint8_t)(dat % 60); - dat /= 60; - b[pos + 1] = (uint8_t)dat; - b[pos] = 0; - pos += 4; - } else { - b[pos++] = (cdpos >> 24) & 0xff; - b[pos++] = (cdpos >> 16) & 0xff; - b[pos++] = (cdpos >> 8) & 0xff; - b[pos++] = cdpos & 0xff; - cdpos -= track_address; - b[pos++] = (cdpos >> 24) & 0xff; - b[pos++] = (cdpos >> 16) & 0xff; - b[pos++] = (cdpos >> 8) & 0xff; - b[pos++] = cdpos & 0xff; - } + if (msf) { + uint32_t dat = cdpos; + b[pos + 3] = (uint8_t)(dat % 75); + dat /= 75; + b[pos + 2] = (uint8_t)(dat % 60); + dat /= 60; + b[pos + 1] = (uint8_t)dat; + b[pos] = 0; + pos += 4; + dat = cdpos - track_address; + b[pos + 3] = (uint8_t)(dat % 75); + dat /= 75; + b[pos + 2] = (uint8_t)(dat % 60); + dat /= 60; + b[pos + 1] = (uint8_t)dat; + b[pos] = 0; + pos += 4; + } else { + b[pos++] = (cdpos >> 24) & 0xff; + b[pos++] = (cdpos >> 16) & 0xff; + b[pos++] = (cdpos >> 8) & 0xff; + b[pos++] = cdpos & 0xff; + cdpos -= track_address; + b[pos++] = (cdpos >> 24) & 0xff; + b[pos++] = (cdpos >> 16) & 0xff; + b[pos++] = (cdpos >> 8) & 0xff; + b[pos++] = cdpos & 0xff; + } - if (ioctl_cd_state == CD_PLAYING) - return 0x11; - return 0x12; - } + if (ioctl_cd_state == CD_PLAYING) + return 0x11; + return 0x12; + } - b[pos++] = sub.CurrentPosition.Control; - b[pos++] = sub.CurrentPosition.TrackNumber; - b[pos++] = sub.CurrentPosition.IndexNumber; + b[pos++] = sub.CurrentPosition.Control; + b[pos++] = sub.CurrentPosition.TrackNumber; + b[pos++] = sub.CurrentPosition.IndexNumber; - if (msf) { - int c; - for (c = 0; c < 4; c++) - b[pos++] = sub.CurrentPosition.AbsoluteAddress[c]; - for (c = 0; c < 4; c++) - b[pos++] = sub.CurrentPosition.TrackRelativeAddress[c]; - } else { - uint32_t temp = MSFtoLBA(sub.CurrentPosition.AbsoluteAddress[1], sub.CurrentPosition.AbsoluteAddress[2], sub.CurrentPosition.AbsoluteAddress[3]); - b[pos++] = temp >> 24; - b[pos++] = temp >> 16; - b[pos++] = temp >> 8; - b[pos++] = temp; - temp = MSFtoLBA(sub.CurrentPosition.TrackRelativeAddress[1], sub.CurrentPosition.TrackRelativeAddress[2], sub.CurrentPosition.TrackRelativeAddress[3]); - b[pos++] = temp >> 24; - b[pos++] = temp >> 16; - b[pos++] = temp >> 8; - b[pos++] = temp; - } + if (msf) { + int c; + for (c = 0; c < 4; c++) + b[pos++] = sub.CurrentPosition.AbsoluteAddress[c]; + for (c = 0; c < 4; c++) + b[pos++] = sub.CurrentPosition.TrackRelativeAddress[c]; + } else { + uint32_t temp = MSFtoLBA(sub.CurrentPosition.AbsoluteAddress[1], sub.CurrentPosition.AbsoluteAddress[2], + sub.CurrentPosition.AbsoluteAddress[3]); + b[pos++] = temp >> 24; + b[pos++] = temp >> 16; + b[pos++] = temp >> 8; + b[pos++] = temp; + temp = MSFtoLBA(sub.CurrentPosition.TrackRelativeAddress[1], sub.CurrentPosition.TrackRelativeAddress[2], + sub.CurrentPosition.TrackRelativeAddress[3]); + b[pos++] = temp >> 24; + b[pos++] = temp >> 16; + b[pos++] = temp >> 8; + b[pos++] = temp; + } - return 0x13; + return 0x13; } static void ioctl_eject(void) { - long size; - if (!cdrom_drive) - return; - ioctl_cd_state = CD_STOPPED; - ioctl_open(0); - DeviceIoControl(hIOCTL, IOCTL_STORAGE_EJECT_MEDIA, NULL, 0, NULL, 0, (LPDWORD)&size, NULL); - ioctl_close(); + long size; + if (!cdrom_drive) + return; + ioctl_cd_state = CD_STOPPED; + ioctl_open(0); + DeviceIoControl(hIOCTL, IOCTL_STORAGE_EJECT_MEDIA, NULL, 0, NULL, 0, (LPDWORD)&size, NULL); + ioctl_close(); } static void ioctl_load(void) { - long size; - if (!cdrom_drive) - return; - ioctl_cd_state = CD_STOPPED; - ioctl_open(0); - DeviceIoControl(hIOCTL, IOCTL_STORAGE_LOAD_MEDIA, NULL, 0, NULL, 0, (LPDWORD)&size, NULL); - ioctl_close(); - cdrom_capacity = ioctl_get_last_block(0, 0, 4096, 0); + long size; + if (!cdrom_drive) + return; + ioctl_cd_state = CD_STOPPED; + ioctl_open(0); + DeviceIoControl(hIOCTL, IOCTL_STORAGE_LOAD_MEDIA, NULL, 0, NULL, 0, (LPDWORD)&size, NULL); + ioctl_close(); + cdrom_capacity = ioctl_get_last_block(0, 0, 4096, 0); } #define IOCTL_DATA_BUFFER 8192 typedef struct _SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER { - SCSI_PASS_THROUGH_DIRECT spt; - ULONG Filler; - UCHAR SenseBuf[32]; + SCSI_PASS_THROUGH_DIRECT spt; + ULONG Filler; + UCHAR SenseBuf[32]; } SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER; static int ioctl_readsector(uint8_t *b, int sector, int count) { - LARGE_INTEGER pos; - BOOL status; - long size = 0; + LARGE_INTEGER pos; + BOOL status; + long size = 0; - if (!cdrom_drive) - return -1; + if (!cdrom_drive) + return -1; - if (ioctl_cd_state == CD_PLAYING) - return -1; + if (ioctl_cd_state == CD_PLAYING) + return -1; - ioctl_cd_state = CD_STOPPED; - pos.QuadPart = sector * 2048; - ioctl_open(0); - SetFilePointer(hIOCTL, pos.LowPart, &pos.HighPart, FILE_BEGIN); - status = ReadFile(hIOCTL, b, count * 2048, (LPDWORD)&size, NULL); - ioctl_close(); + ioctl_cd_state = CD_STOPPED; + pos.QuadPart = sector * 2048; + ioctl_open(0); + SetFilePointer(hIOCTL, pos.LowPart, &pos.HighPart, FILE_BEGIN); + status = ReadFile(hIOCTL, b, count * 2048, (LPDWORD)&size, NULL); + ioctl_close(); - /*If the read 'succeeded' but didn't read all required data, try again using SPTI*/ - if (status && size != count * 2048) { - uint8_t cmd[12] = {0xbe, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0}; - SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER swb; - DWORD returned; - uint8_t *data_buffer;//[IOCTL_DATA_BUFFER]; + /*If the read 'succeeded' but didn't read all required data, try again using SPTI*/ + if (status && size != count * 2048) { + uint8_t cmd[12] = {0xbe, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0}; + SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER swb; + DWORD returned; + uint8_t *data_buffer; //[IOCTL_DATA_BUFFER]; - data_buffer = malloc(count * IOCTL_DATA_BUFFER); + data_buffer = malloc(count * IOCTL_DATA_BUFFER); - ioctl_open(0); + ioctl_open(0); - cmd[9] |= 1 << 4; // userdata + cmd[9] |= 1 << 4; // userdata - cmd[3] = (uint8_t)(sector >> 16); - cmd[4] = (uint8_t)(sector >> 8); - cmd[5] = (uint8_t)(sector >> 0); - cmd[6] = (uint8_t)(count >> 16); - cmd[7] = (uint8_t)(count >> 8); - cmd[8] = (uint8_t)(count >> 0); + cmd[3] = (uint8_t)(sector >> 16); + cmd[4] = (uint8_t)(sector >> 8); + cmd[5] = (uint8_t)(sector >> 0); + cmd[6] = (uint8_t)(count >> 16); + cmd[7] = (uint8_t)(count >> 8); + cmd[8] = (uint8_t)(count >> 0); - memset(&swb, 0, sizeof(swb)); - memcpy(swb.spt.Cdb, cmd, 12); + memset(&swb, 0, sizeof(swb)); + memcpy(swb.spt.Cdb, cmd, 12); - swb.spt.Length = sizeof(SCSI_PASS_THROUGH); - swb.spt.CdbLength = 12; - swb.spt.DataIn = SCSI_IOCTL_DATA_IN; - swb.spt.DataTransferLength = count * IOCTL_DATA_BUFFER; - swb.spt.DataBuffer = data_buffer; - memset(data_buffer, 0, count * IOCTL_DATA_BUFFER); - swb.spt.TimeOutValue = 80 * 60; - swb.spt.SenseInfoOffset = (uintptr_t)&swb.SenseBuf - (uintptr_t)&swb;//offsetof(swb, SenseBuf); - swb.spt.SenseInfoLength = 32; + swb.spt.Length = sizeof(SCSI_PASS_THROUGH); + swb.spt.CdbLength = 12; + swb.spt.DataIn = SCSI_IOCTL_DATA_IN; + swb.spt.DataTransferLength = count * IOCTL_DATA_BUFFER; + swb.spt.DataBuffer = data_buffer; + memset(data_buffer, 0, count * IOCTL_DATA_BUFFER); + swb.spt.TimeOutValue = 80 * 60; + swb.spt.SenseInfoOffset = (uintptr_t)&swb.SenseBuf - (uintptr_t)&swb; // offsetof(swb, SenseBuf); + swb.spt.SenseInfoLength = 32; - if (DeviceIoControl(hIOCTL, IOCTL_SCSI_PASS_THROUGH_DIRECT, - &swb, sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER), - &swb, sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER), - &returned, NULL)) { - memcpy(b, data_buffer, count * 2048); - status = 1; - } else - status = 0; + if (DeviceIoControl(hIOCTL, IOCTL_SCSI_PASS_THROUGH_DIRECT, &swb, sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER), + &swb, sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER), &returned, NULL)) { + memcpy(b, data_buffer, count * 2048); + status = 1; + } else + status = 0; - ioctl_close(); + ioctl_close(); - free(data_buffer); - } + free(data_buffer); + } - return !status; + return !status; } static int is_track_audio(uint32_t pos) { - int c; - int control = 0; + int c; + int control = 0; - if (!tocvalid) - return 0; + if (!tocvalid) + return 0; - for (c = 0; toc.TrackData[c].TrackNumber != 0xaa; c++) { - uint32_t track_address = toc.TrackData[c].Address[3] + - (toc.TrackData[c].Address[2] * 75) + - (toc.TrackData[c].Address[1] * 75 * 60); + for (c = 0; toc.TrackData[c].TrackNumber != 0xaa; c++) { + uint32_t track_address = toc.TrackData[c].Address[3] + (toc.TrackData[c].Address[2] * 75) + + (toc.TrackData[c].Address[1] * 75 * 60); - if (toc.TrackData[c].TrackNumber >= toc.FirstTrack && - toc.TrackData[c].TrackNumber <= toc.LastTrack && - track_address >= pos) { - control = toc.TrackData[c].Control; - break; - } - } - return (control & 4) ? 0 : 1; + if (toc.TrackData[c].TrackNumber >= toc.FirstTrack && toc.TrackData[c].TrackNumber <= toc.LastTrack && + track_address >= pos) { + control = toc.TrackData[c].Control; + break; + } + } + return (control & 4) ? 0 : 1; } static int ioctl_is_track_audio(uint32_t pos, int ismsf) { - if (ismsf) { - int m = (pos >> 16) & 0xff; - int s = (pos >> 8) & 0xff; - int f = pos & 0xff; - pos = MSFtoLBA(m, s, f); - } - return is_track_audio(pos); + if (ismsf) { + int m = (pos >> 16) & 0xff; + int s = (pos >> 8) & 0xff; + int f = pos & 0xff; + pos = MSFtoLBA(m, s, f); + } + return is_track_audio(pos); } static void ioctl_readsector_raw(uint8_t *b, int sector) { - long size; + long size; - if (!cdrom_drive) - return; - if (ioctl_cd_state == CD_PLAYING) - return; + if (!cdrom_drive) + return; + if (ioctl_cd_state == CD_PLAYING) + return; - ioctl_cd_state = CD_STOPPED; - ioctl_open(0); - DeviceIoControl(hIOCTL, IOCTL_CDROM_RAW_READ, NULL, 0, b, 1, (LPDWORD)&size, NULL); - ioctl_close(); + ioctl_cd_state = CD_STOPPED; + ioctl_open(0); + DeviceIoControl(hIOCTL, IOCTL_CDROM_RAW_READ, NULL, 0, b, 1, (LPDWORD)&size, NULL); + ioctl_close(); } static int ioctl_readtoc(unsigned char *b, unsigned char starttrack, int msf, int maxlen, int single) { - int len = 4; - long size; - int c, d; - uint32_t temp; - if (!cdrom_drive) - return 0; - ioctl_cd_state = CD_STOPPED; - ioctl_open(0); - DeviceIoControl(hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, &toc, sizeof(toc), (LPDWORD)&size, NULL); - ioctl_close(); - tocvalid = 1; -// pclog("Read TOC done! %i\n",single); - b[2] = toc.FirstTrack; - b[3] = toc.LastTrack; - d = 0; - for (c = 0; c <= toc.LastTrack; c++) { - if (toc.TrackData[c].TrackNumber >= starttrack) { - d = c; - break; - } - } - last_block = 0; - for (c = d; c <= toc.LastTrack; c++) { - uint32_t address; - if ((len + 8) > maxlen) - break; -// pclog("Len %i max %i Track %02X - %02X %02X %i %i %i %i %08X\n",len,maxlen,toc.TrackData[c].TrackNumber,toc.TrackData[c].Adr,toc.TrackData[c].Control,toc.TrackData[c].Address[0],toc.TrackData[c].Address[1],toc.TrackData[c].Address[2],toc.TrackData[c].Address[3],MSFtoLBA(toc.TrackData[c].Address[1],toc.TrackData[c].Address[2],toc.TrackData[c].Address[3])); - b[len++] = 0; /*Reserved*/ - b[len++] = (toc.TrackData[c].Adr << 4) | toc.TrackData[c].Control; - b[len++] = toc.TrackData[c].TrackNumber; - b[len++] = 0; /*Reserved*/ - address = MSFtoLBA(toc.TrackData[c].Address[1], toc.TrackData[c].Address[2], toc.TrackData[c].Address[3]); - if (address > last_block) - last_block = address; + int len = 4; + long size; + int c, d; + uint32_t temp; + if (!cdrom_drive) + return 0; + ioctl_cd_state = CD_STOPPED; + ioctl_open(0); + DeviceIoControl(hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, &toc, sizeof(toc), (LPDWORD)&size, NULL); + ioctl_close(); + tocvalid = 1; + // pclog("Read TOC done! %i\n",single); + b[2] = toc.FirstTrack; + b[3] = toc.LastTrack; + d = 0; + for (c = 0; c <= toc.LastTrack; c++) { + if (toc.TrackData[c].TrackNumber >= starttrack) { + d = c; + break; + } + } + last_block = 0; + for (c = d; c <= toc.LastTrack; c++) { + uint32_t address; + if ((len + 8) > maxlen) + break; + // pclog("Len %i max %i Track %02X - %02X %02X %i %i %i %i + // %08X\n",len,maxlen,toc.TrackData[c].TrackNumber,toc.TrackData[c].Adr,toc.TrackData[c].Control,toc.TrackData[c].Address[0],toc.TrackData[c].Address[1],toc.TrackData[c].Address[2],toc.TrackData[c].Address[3],MSFtoLBA(toc.TrackData[c].Address[1],toc.TrackData[c].Address[2],toc.TrackData[c].Address[3])); + b[len++] = 0; /*Reserved*/ + b[len++] = (toc.TrackData[c].Adr << 4) | toc.TrackData[c].Control; + b[len++] = toc.TrackData[c].TrackNumber; + b[len++] = 0; /*Reserved*/ + address = MSFtoLBA(toc.TrackData[c].Address[1], toc.TrackData[c].Address[2], toc.TrackData[c].Address[3]); + if (address > last_block) + last_block = address; - if (msf) { - b[len++] = toc.TrackData[c].Address[0]; - b[len++] = toc.TrackData[c].Address[1]; - b[len++] = toc.TrackData[c].Address[2]; - b[len++] = toc.TrackData[c].Address[3]; - } else { - temp = MSFtoLBA(toc.TrackData[c].Address[1], toc.TrackData[c].Address[2], toc.TrackData[c].Address[3]); - 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); -/* pclog("Table of Contents (%i bytes) : \n",size); - pclog("First track - %02X\n",toc.FirstTrack); - pclog("Last track - %02X\n",toc.LastTrack); - for (c=0;c<=toc.LastTrack;c++) - pclog("Track %02X - number %02X control %02X adr %02X address %02X %02X %02X %02X\n",c,toc.TrackData[c].TrackNumber,toc.TrackData[c].Control,toc.TrackData[c].Adr,toc.TrackData[c].Address[0],toc.TrackData[c].Address[1],toc.TrackData[c].Address[2],toc.TrackData[c].Address[3]); - for (c=0;c<=toc.LastTrack;c++) - pclog("Track %02X - number %02X control %02X adr %02X address %06X\n",c,toc.TrackData[c].TrackNumber,toc.TrackData[c].Control,toc.TrackData[c].Adr,MSFtoLBA(toc.TrackData[c].Address[1],toc.TrackData[c].Address[2],toc.TrackData[c].Address[3]));*/ - return len; + if (msf) { + b[len++] = toc.TrackData[c].Address[0]; + b[len++] = toc.TrackData[c].Address[1]; + b[len++] = toc.TrackData[c].Address[2]; + b[len++] = toc.TrackData[c].Address[3]; + } else { + temp = MSFtoLBA(toc.TrackData[c].Address[1], toc.TrackData[c].Address[2], toc.TrackData[c].Address[3]); + 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); + /* pclog("Table of Contents (%i bytes) : \n",size); + pclog("First track - %02X\n",toc.FirstTrack); + pclog("Last track - %02X\n",toc.LastTrack); + for (c=0;c<=toc.LastTrack;c++) + pclog("Track %02X - number %02X control %02X adr %02X address %02X %02X %02X + %02X\n",c,toc.TrackData[c].TrackNumber,toc.TrackData[c].Control,toc.TrackData[c].Adr,toc.TrackData[c].Address[0],toc.TrackData[c].Address[1],toc.TrackData[c].Address[2],toc.TrackData[c].Address[3]); + for (c=0;c<=toc.LastTrack;c++) + pclog("Track %02X - number %02X control %02X adr %02X address + %06X\n",c,toc.TrackData[c].TrackNumber,toc.TrackData[c].Control,toc.TrackData[c].Adr,MSFtoLBA(toc.TrackData[c].Address[1],toc.TrackData[c].Address[2],toc.TrackData[c].Address[3]));*/ + return len; } static int ioctl_readtoc_session(unsigned char *b, int msf, int maxlen) { - int len = 4; - int size; - uint32_t temp; - CDROM_READ_TOC_EX toc_ex; - CDROM_TOC_SESSION_DATA toc; - if (!cdrom_drive) - return 0; - ioctl_cd_state = CD_STOPPED; - memset(&toc_ex, 0, sizeof(toc_ex)); - memset(&toc, 0, sizeof(toc)); - toc_ex.Format = CDROM_READ_TOC_EX_FORMAT_SESSION; - toc_ex.Msf = msf; - toc_ex.SessionTrack = 0; - ioctl_open(0); - DeviceIoControl(hIOCTL, IOCTL_CDROM_READ_TOC_EX, &toc_ex, sizeof(toc_ex), &toc, sizeof(toc), (PDWORD)&size, NULL); - ioctl_close(); -// pclog("Read TOC session - %i %02X %02X %i %i %02X %02X %02X\n",size,toc.Length[0],toc.Length[1],toc.FirstCompleteSession,toc.LastCompleteSession,toc.TrackData[0].Adr,toc.TrackData[0].Control,toc.TrackData[0].TrackNumber); - b[2] = toc.FirstCompleteSession; - b[3] = toc.LastCompleteSession; - b[len++] = 0; /*Reserved*/ - b[len++] = (toc.TrackData[0].Adr << 4) | toc.TrackData[0].Control; - b[len++] = toc.TrackData[0].TrackNumber; - b[len++] = 0; /*Reserved*/ - if (msf) { - b[len++] = toc.TrackData[0].Address[0]; - b[len++] = toc.TrackData[0].Address[1]; - b[len++] = toc.TrackData[0].Address[2]; - b[len++] = toc.TrackData[0].Address[3]; - } else { - temp = MSFtoLBA(toc.TrackData[0].Address[1], toc.TrackData[0].Address[2], toc.TrackData[0].Address[3]); - b[len++] = temp >> 24; - b[len++] = temp >> 16; - b[len++] = temp >> 8; - b[len++] = temp; - } + int len = 4; + int size; + uint32_t temp; + CDROM_READ_TOC_EX toc_ex; + CDROM_TOC_SESSION_DATA toc; + if (!cdrom_drive) + return 0; + ioctl_cd_state = CD_STOPPED; + memset(&toc_ex, 0, sizeof(toc_ex)); + memset(&toc, 0, sizeof(toc)); + toc_ex.Format = CDROM_READ_TOC_EX_FORMAT_SESSION; + toc_ex.Msf = msf; + toc_ex.SessionTrack = 0; + ioctl_open(0); + DeviceIoControl(hIOCTL, IOCTL_CDROM_READ_TOC_EX, &toc_ex, sizeof(toc_ex), &toc, sizeof(toc), (PDWORD)&size, NULL); + ioctl_close(); + // pclog("Read TOC session - %i %02X %02X %i %i %02X %02X + // %02X\n",size,toc.Length[0],toc.Length[1],toc.FirstCompleteSession,toc.LastCompleteSession,toc.TrackData[0].Adr,toc.TrackData[0].Control,toc.TrackData[0].TrackNumber); + b[2] = toc.FirstCompleteSession; + b[3] = toc.LastCompleteSession; + b[len++] = 0; /*Reserved*/ + b[len++] = (toc.TrackData[0].Adr << 4) | toc.TrackData[0].Control; + b[len++] = toc.TrackData[0].TrackNumber; + b[len++] = 0; /*Reserved*/ + if (msf) { + b[len++] = toc.TrackData[0].Address[0]; + b[len++] = toc.TrackData[0].Address[1]; + b[len++] = toc.TrackData[0].Address[2]; + b[len++] = toc.TrackData[0].Address[3]; + } else { + temp = MSFtoLBA(toc.TrackData[0].Address[1], toc.TrackData[0].Address[2], toc.TrackData[0].Address[3]); + b[len++] = temp >> 24; + b[len++] = temp >> 16; + b[len++] = temp >> 8; + b[len++] = temp; + } - return len; + return len; } static int ioctl_readtoc_raw(unsigned char *b, int maxlen) { - int len = 4; - int size; - int i; - CDROM_READ_TOC_EX toc_ex; - CDROM_TOC_FULL_TOC_DATA toc; - if (!cdrom_drive) - return 0; - ioctl_cd_state = CD_STOPPED; - memset(&toc_ex, 0, sizeof(toc_ex)); - memset(&toc, 0, sizeof(toc)); - toc_ex.Format = CDROM_READ_TOC_EX_FORMAT_FULL_TOC; - toc_ex.Msf = 1; - toc_ex.SessionTrack = 0; - ioctl_open(0); - DeviceIoControl(hIOCTL, IOCTL_CDROM_READ_TOC_EX, &toc_ex, sizeof(toc_ex), &toc, sizeof(toc), (PDWORD)&size, NULL); - ioctl_close(); -// pclog("Read TOC session - %i %02X %02X %i %i %02X %02X %02X\n",size,toc.Length[0],toc.Length[1],toc.FirstCompleteSession,toc.LastCompleteSession,toc.TrackData[0].Adr,toc.TrackData[0].Control,toc.TrackData[0].TrackNumber); - b[2] = toc.FirstCompleteSession; - b[3] = toc.LastCompleteSession; + int len = 4; + int size; + int i; + CDROM_READ_TOC_EX toc_ex; + CDROM_TOC_FULL_TOC_DATA toc; + if (!cdrom_drive) + return 0; + ioctl_cd_state = CD_STOPPED; + memset(&toc_ex, 0, sizeof(toc_ex)); + memset(&toc, 0, sizeof(toc)); + toc_ex.Format = CDROM_READ_TOC_EX_FORMAT_FULL_TOC; + toc_ex.Msf = 1; + toc_ex.SessionTrack = 0; + ioctl_open(0); + DeviceIoControl(hIOCTL, IOCTL_CDROM_READ_TOC_EX, &toc_ex, sizeof(toc_ex), &toc, sizeof(toc), (PDWORD)&size, NULL); + ioctl_close(); + // pclog("Read TOC session - %i %02X %02X %i %i %02X %02X + // %02X\n",size,toc.Length[0],toc.Length[1],toc.FirstCompleteSession,toc.LastCompleteSession,toc.TrackData[0].Adr,toc.TrackData[0].Control,toc.TrackData[0].TrackNumber); + b[2] = toc.FirstCompleteSession; + b[3] = toc.LastCompleteSession; - size -= sizeof(CDROM_TOC_FULL_TOC_DATA); - size /= sizeof(toc.Descriptors[0]); + size -= sizeof(CDROM_TOC_FULL_TOC_DATA); + size /= sizeof(toc.Descriptors[0]); - for (i = 0; i <= size; i++) { - b[len++] = toc.Descriptors[i].SessionNumber; - b[len++] = (toc.Descriptors[i].Adr << 4) | toc.Descriptors[i].Control; - b[len++] = 0; - b[len++] = toc.Descriptors[i].Reserved1; /*Reserved*/ - b[len++] = toc.Descriptors[i].MsfExtra[0]; - b[len++] = toc.Descriptors[i].MsfExtra[1]; - b[len++] = toc.Descriptors[i].MsfExtra[2]; - b[len++] = toc.Descriptors[i].Zero; - b[len++] = toc.Descriptors[i].Msf[0]; - b[len++] = toc.Descriptors[i].Msf[1]; - b[len++] = toc.Descriptors[i].Msf[2]; - } + for (i = 0; i <= size; i++) { + b[len++] = toc.Descriptors[i].SessionNumber; + b[len++] = (toc.Descriptors[i].Adr << 4) | toc.Descriptors[i].Control; + b[len++] = 0; + b[len++] = toc.Descriptors[i].Reserved1; /*Reserved*/ + b[len++] = toc.Descriptors[i].MsfExtra[0]; + b[len++] = toc.Descriptors[i].MsfExtra[1]; + b[len++] = toc.Descriptors[i].MsfExtra[2]; + b[len++] = toc.Descriptors[i].Zero; + b[len++] = toc.Descriptors[i].Msf[0]; + b[len++] = toc.Descriptors[i].Msf[1]; + b[len++] = toc.Descriptors[i].Msf[2]; + } - return len; + return len; } -static uint32_t ioctl_size() { - return cdrom_capacity; -} +static uint32_t ioctl_size() { return cdrom_capacity; } static int ioctl_status() { - if (!(ioctl_ready()) && (cdrom_drive <= 0)) - return CD_STATUS_EMPTY; + if (!(ioctl_ready()) && (cdrom_drive <= 0)) + return CD_STATUS_EMPTY; - switch (ioctl_cd_state) { - case CD_PLAYING:return CD_STATUS_PLAYING; - case CD_PAUSED:return CD_STATUS_PAUSED; - case CD_STOPPED:return CD_STATUS_STOPPED; - } - return CD_STATUS_STOPPED; + switch (ioctl_cd_state) { + case CD_PLAYING: + return CD_STATUS_PLAYING; + case CD_PAUSED: + return CD_STATUS_PAUSED; + case CD_STOPPED: + return CD_STATUS_STOPPED; + } + return CD_STATUS_STOPPED; } void ioctl_reset() { - CDROM_TOC ltoc; - long size; + CDROM_TOC ltoc; + long size; - if (!cdrom_drive) { - tocvalid = 0; - return; - } + if (!cdrom_drive) { + tocvalid = 0; + return; + } - ioctl_open(0); - DeviceIoControl(hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, <oc, sizeof(ltoc), (LPDWORD)&size, NULL); - ioctl_close(); + ioctl_open(0); + DeviceIoControl(hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, <oc, sizeof(ltoc), (LPDWORD)&size, NULL); + ioctl_close(); - toc = ltoc; - tocvalid = 1; + toc = ltoc; + tocvalid = 1; } void ioctl_set_drive(char d) { - ioctl_close(); + ioctl_close(); - sprintf(ioctl_path, "\\\\.\\%c:", d); - pclog("Path is %s\n", ioctl_path); - tocvalid = 0; - atapi = &ioctl_atapi; + sprintf(ioctl_path, "\\\\.\\%c:", d); + pclog("Path is %s\n", ioctl_path); + tocvalid = 0; + atapi = &ioctl_atapi; - ioctl_open(d); + ioctl_open(d); } int ioctl_open(char d) { - if (hIOCTL) - ioctl_close(); - hIOCTL = CreateFile(ioctl_path, GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); - if (!hIOCTL) { - //fatal("IOCTL"); - } - return 0; + if (hIOCTL) + ioctl_close(); + hIOCTL = CreateFile(ioctl_path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, + NULL); + if (!hIOCTL) { + // fatal("IOCTL"); + } + return 0; } void ioctl_close(void) { - if (hIOCTL) { - CloseHandle(hIOCTL); - hIOCTL = NULL; - } + if (hIOCTL) { + CloseHandle(hIOCTL); + hIOCTL = NULL; + } } static void ioctl_exit(void) { - ioctl_stop(); - tocvalid = 0; + ioctl_stop(); + tocvalid = 0; } -static ATAPI ioctl_atapi = - { - ioctl_ready, - ioctl_medium_changed, - ioctl_readtoc, - ioctl_readtoc_session, - ioctl_readtoc_raw, - ioctl_getcurrentsubchannel, - ioctl_readsector, - ioctl_readsector_raw, - ioctl_playaudio, - ioctl_seek, - ioctl_load, - ioctl_eject, - ioctl_pause, - ioctl_resume, - ioctl_size, - ioctl_status, - ioctl_is_track_audio, - ioctl_stop, - ioctl_exit - }; +static ATAPI ioctl_atapi = {ioctl_ready, + ioctl_medium_changed, + ioctl_readtoc, + ioctl_readtoc_session, + ioctl_readtoc_raw, + ioctl_getcurrentsubchannel, + ioctl_readsector, + ioctl_readsector_raw, + ioctl_playaudio, + ioctl_seek, + ioctl_load, + ioctl_eject, + ioctl_pause, + ioctl_resume, + ioctl_size, + ioctl_status, + ioctl_is_track_audio, + ioctl_stop, + ioctl_exit}; diff --git a/src/cdrom/cdrom-null.c b/src/cdrom/cdrom-null.c index c7161edc..16f8d32c 100644 --- a/src/cdrom/cdrom-null.c +++ b/src/cdrom/cdrom-null.c @@ -6,111 +6,74 @@ int cdrom_drive; static ATAPI null_atapi; -void cdrom_null_audio_callback(int16_t *output, int len) { - memset(output, 0, len * 2); -} +void cdrom_null_audio_callback(int16_t *output, int len) { memset(output, 0, len * 2); } -void cdrom_null_audio_stop() { -} +void cdrom_null_audio_stop() {} -static void null_playaudio(uint32_t pos, uint32_t len, int ismsf) { -} +static void null_playaudio(uint32_t pos, uint32_t len, int ismsf) {} -static void null_pause(void) { -} +static void null_pause(void) {} -static void null_resume(void) { -} +static void null_resume(void) {} -static void null_stop(void) { -} +static void null_stop(void) {} -static void null_seek(uint32_t pos) { -} +static void null_seek(uint32_t pos) {} -static int null_ready(void) { - return 0; -} +static int null_ready(void) { return 0; } /* Always return 0, the contents of a null CD-ROM drive never change. */ -static int null_medium_changed(void) { - return 0; -} +static int null_medium_changed(void) { return 0; } -static uint8_t null_getcurrentsubchannel(uint8_t *b, int msf) { - return 0x13; -} +static uint8_t null_getcurrentsubchannel(uint8_t *b, int msf) { return 0x13; } -static void null_eject(void) { -} +static void null_eject(void) {} -static void null_load(void) { -} +static void null_load(void) {} -static int null_readsector(uint8_t *b, int sector, int count) { - return 0; -} +static int null_readsector(uint8_t *b, int sector, int count) { return 0; } -static void null_readsector_raw(uint8_t *b, int sector) { -} +static void null_readsector_raw(uint8_t *b, int sector) {} -static int null_readtoc(unsigned char *b, unsigned char starttrack, int msf, int maxlen, int single) { - return 0; -} +static int null_readtoc(unsigned char *b, unsigned char starttrack, int msf, int maxlen, int single) { return 0; } -static int null_readtoc_session(unsigned char *b, int msf, int maxlen) { - return 0; -} +static int null_readtoc_session(unsigned char *b, int msf, int maxlen) { return 0; } -static int null_readtoc_raw(unsigned char *b, int maxlen) { - return 0; -} +static int null_readtoc_raw(unsigned char *b, int maxlen) { return 0; } -static uint32_t null_size() { - return 0; -} +static uint32_t null_size() { return 0; } -static int null_status() { - return CD_STATUS_EMPTY; -} +static int null_status() { return CD_STATUS_EMPTY; } -void cdrom_null_reset() { -} +void cdrom_null_reset() {} int cdrom_null_open(char d) { - atapi = &null_atapi; - return 0; + atapi = &null_atapi; + return 0; } -void null_close(void) { -} +void null_close(void) {} -static void null_exit(void) { -} +static void null_exit(void) {} -static int null_is_track_audio(uint32_t pos, int ismsf) { - return 0; -} +static int null_is_track_audio(uint32_t pos, int ismsf) { return 0; } -static ATAPI null_atapi = - { - null_ready, - null_medium_changed, - null_readtoc, - null_readtoc_session, - null_readtoc_raw, - null_getcurrentsubchannel, - null_readsector, - null_readsector_raw, - null_playaudio, - null_seek, - null_load, - null_eject, - null_pause, - null_resume, - null_size, - null_status, - null_is_track_audio, - null_stop, - null_exit - }; +static ATAPI null_atapi = {null_ready, + null_medium_changed, + null_readtoc, + null_readtoc_session, + null_readtoc_raw, + null_getcurrentsubchannel, + null_readsector, + null_readsector_raw, + null_playaudio, + null_seek, + null_load, + null_eject, + null_pause, + null_resume, + null_size, + null_status, + null_is_track_audio, + null_stop, + null_exit}; diff --git a/src/codegen/arm32/codegen_backend_arm.c b/src/codegen/arm32/codegen_backend_arm.c index a9a7208f..ce86bebc 100644 --- a/src/codegen/arm32/codegen_backend_arm.c +++ b/src/codegen/arm32/codegen_backend_arm.c @@ -38,331 +38,297 @@ void *codegen_fp_round; void *codegen_gpf_rout; void *codegen_exit_rout; -host_reg_def_t codegen_host_reg_list[CODEGEN_HOST_REGS] = -{ - {REG_R4, 0}, - {REG_R5, 0}, - {REG_R6, 0}, - {REG_R7, 0}, - {REG_R8, 0}, - {REG_R9, 0}, - {REG_R11, 0} -}; +host_reg_def_t codegen_host_reg_list[CODEGEN_HOST_REGS] = {{REG_R4, 0}, {REG_R5, 0}, {REG_R6, 0}, {REG_R7, 0}, + {REG_R8, 0}, {REG_R9, 0}, {REG_R11, 0}}; -host_reg_def_t codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] = -{ - {REG_D8, 0}, - {REG_D9, 0}, - {REG_D10, 0}, - {REG_D11, 0}, - {REG_D12, 0}, - {REG_D13, 0}, - {REG_D14, 0}, - {REG_D15, 0} -}; +host_reg_def_t codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] = {{REG_D8, 0}, {REG_D9, 0}, {REG_D10, 0}, {REG_D11, 0}, + {REG_D12, 0}, {REG_D13, 0}, {REG_D14, 0}, {REG_D15, 0}}; -static void build_load_routine(codeblock_t *block, int size, int is_float) -{ - uint32_t *branch_offset; - uint32_t *misaligned_offset; +static void build_load_routine(codeblock_t *block, int size, int is_float) { + uint32_t *branch_offset; + uint32_t *misaligned_offset; - /*In - R0 = address - Out - R0 = data, R1 = abrt*/ - /*MOV R1, R0, LSR #12 - MOV R2, #readlookup2 - LDR R1, [R2, R1, LSL #2] - CMP R1, #-1 - BNE + - LDRB R0, [R1, R0] - MOV R1, #0 - MOV PC, LR - * STR LR, [SP, -4]! - BL readmembl - LDRB R1, cpu_state.abrt - LDR PC, [SP], #4 - */ - codegen_alloc(block, 80); - host_arm_MOV_REG_LSR(block, REG_R1, REG_R0, 12); - host_arm_MOV_IMM(block, REG_R2, (uint32_t)readlookup2); - host_arm_LDR_REG_LSL(block, REG_R1, REG_R2, REG_R1, 2); - if (size != 1) - { - host_arm_TST_IMM(block, REG_R0, size-1); - misaligned_offset = host_arm_BNE_(block); - } - host_arm_CMP_IMM(block, REG_R1, -1); - branch_offset = host_arm_BEQ_(block); - if (size == 1 && !is_float) - host_arm_LDRB_REG(block, REG_R0, REG_R1, REG_R0); - else if (size == 2 && !is_float) - host_arm_LDRH_REG(block, REG_R0, REG_R1, REG_R0); - else if (size == 4 && !is_float) - host_arm_LDR_REG(block, REG_R0, REG_R1, REG_R0); - else if (size == 4 && is_float) - { - host_arm_ADD_REG(block, REG_R0, REG_R0, REG_R1); - host_arm_VLDR_S(block, REG_D_TEMP, REG_R0, 0); - } - else if (size == 8) - { - host_arm_ADD_REG(block, REG_R0, REG_R0, REG_R1); - host_arm_VLDR_D(block, REG_D_TEMP, REG_R0, 0); - } - host_arm_MOV_IMM(block, REG_R1, 0); - host_arm_MOV_REG(block, REG_PC, REG_LR); + /*In - R0 = address + Out - R0 = data, R1 = abrt*/ + /*MOV R1, R0, LSR #12 + MOV R2, #readlookup2 + LDR R1, [R2, R1, LSL #2] + CMP R1, #-1 + BNE + + LDRB R0, [R1, R0] + MOV R1, #0 + MOV PC, LR + * STR LR, [SP, -4]! + BL readmembl + LDRB R1, cpu_state.abrt + LDR PC, [SP], #4 + */ + codegen_alloc(block, 80); + host_arm_MOV_REG_LSR(block, REG_R1, REG_R0, 12); + host_arm_MOV_IMM(block, REG_R2, (uint32_t)readlookup2); + host_arm_LDR_REG_LSL(block, REG_R1, REG_R2, REG_R1, 2); + if (size != 1) { + host_arm_TST_IMM(block, REG_R0, size - 1); + misaligned_offset = host_arm_BNE_(block); + } + host_arm_CMP_IMM(block, REG_R1, -1); + branch_offset = host_arm_BEQ_(block); + if (size == 1 && !is_float) + host_arm_LDRB_REG(block, REG_R0, REG_R1, REG_R0); + else if (size == 2 && !is_float) + host_arm_LDRH_REG(block, REG_R0, REG_R1, REG_R0); + else if (size == 4 && !is_float) + host_arm_LDR_REG(block, REG_R0, REG_R1, REG_R0); + else if (size == 4 && is_float) { + host_arm_ADD_REG(block, REG_R0, REG_R0, REG_R1); + host_arm_VLDR_S(block, REG_D_TEMP, REG_R0, 0); + } else if (size == 8) { + host_arm_ADD_REG(block, REG_R0, REG_R0, REG_R1); + host_arm_VLDR_D(block, REG_D_TEMP, REG_R0, 0); + } + host_arm_MOV_IMM(block, REG_R1, 0); + host_arm_MOV_REG(block, REG_PC, REG_LR); - *branch_offset |= ((((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 8) & 0x3fffffc) >> 2; - if (size != 1) - *misaligned_offset |= ((((uintptr_t)&block_write_data[block_pos] - (uintptr_t)misaligned_offset) - 8) & 0x3fffffc) >> 2; - host_arm_STR_IMM_WB(block, REG_LR, REG_HOST_SP, -4); - if (size == 1) - host_arm_BL(block, (uintptr_t)readmembl); - else if (size == 2) - host_arm_BL(block, (uintptr_t)readmemwl); - else if (size == 4) - host_arm_BL(block, (uintptr_t)readmemll); - else if (size == 8) - host_arm_BL(block, (uintptr_t)readmemql); - else - fatal("build_load_routine - unknown size %i\n", size); - if (size == 4 && is_float) - host_arm_VMOV_S_32(block, REG_D_TEMP, REG_R0); - else if (size == 8) - host_arm_VMOV_D_64(block, REG_D_TEMP, REG_R0, REG_R1); - host_arm_LDRB_ABS(block, REG_R1, &cpu_state.abrt); - host_arm_LDR_IMM_POST(block, REG_PC, REG_HOST_SP, 4); + *branch_offset |= ((((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 8) & 0x3fffffc) >> 2; + if (size != 1) + *misaligned_offset |= + ((((uintptr_t)&block_write_data[block_pos] - (uintptr_t)misaligned_offset) - 8) & 0x3fffffc) >> 2; + host_arm_STR_IMM_WB(block, REG_LR, REG_HOST_SP, -4); + if (size == 1) + host_arm_BL(block, (uintptr_t)readmembl); + else if (size == 2) + host_arm_BL(block, (uintptr_t)readmemwl); + else if (size == 4) + host_arm_BL(block, (uintptr_t)readmemll); + else if (size == 8) + host_arm_BL(block, (uintptr_t)readmemql); + else + fatal("build_load_routine - unknown size %i\n", size); + if (size == 4 && is_float) + host_arm_VMOV_S_32(block, REG_D_TEMP, REG_R0); + else if (size == 8) + host_arm_VMOV_D_64(block, REG_D_TEMP, REG_R0, REG_R1); + host_arm_LDRB_ABS(block, REG_R1, &cpu_state.abrt); + host_arm_LDR_IMM_POST(block, REG_PC, REG_HOST_SP, 4); } -static void build_store_routine(codeblock_t *block, int size, int is_float) -{ - uint32_t *branch_offset; - uint32_t *misaligned_offset; +static void build_store_routine(codeblock_t *block, int size, int is_float) { + uint32_t *branch_offset; + uint32_t *misaligned_offset; - /*In - R0 = address - Out - R0 = data, R1 = abrt*/ - /*MOV R1, R0, LSR #12 - MOV R2, #readlookup2 - LDR R1, [R2, R1, LSL #2] - CMP R1, #-1 - BNE + - LDRB R0, [R1, R0] - MOV R1, #0 - MOV PC, LR - * STR LR, [SP, -4]! - BL readmembl - LDRB R1, cpu_state.abrt - LDR PC, [SP], #4 - */ - codegen_alloc(block, 80); - host_arm_MOV_REG_LSR(block, REG_R2, REG_R0, 12); - host_arm_MOV_IMM(block, REG_R3, (uint32_t)writelookup2); - host_arm_LDR_REG_LSL(block, REG_R2, REG_R3, REG_R2, 2); - if (size != 1) - { - host_arm_TST_IMM(block, REG_R0, size-1); - misaligned_offset = host_arm_BNE_(block); - } - host_arm_CMP_IMM(block, REG_R2, -1); - branch_offset = host_arm_BEQ_(block); - if (size == 1 && !is_float) - host_arm_STRB_REG(block, REG_R1, REG_R2, REG_R0); - else if (size == 2 && !is_float) - host_arm_STRH_REG(block, REG_R1, REG_R2, REG_R0); - else if (size == 4 && !is_float) - host_arm_STR_REG(block, REG_R1, REG_R2, REG_R0); - else if (size == 4 && is_float) - { - host_arm_ADD_REG(block, REG_R0, REG_R0, REG_R2); - host_arm_VSTR_S(block, REG_D_TEMP, REG_R0, 0); - } - else if (size == 8) - { - host_arm_ADD_REG(block, REG_R0, REG_R0, REG_R2); - host_arm_VSTR_D(block, REG_D_TEMP, REG_R0, 0); - } - host_arm_MOV_IMM(block, REG_R1, 0); - host_arm_MOV_REG(block, REG_PC, REG_LR); + /*In - R0 = address + Out - R0 = data, R1 = abrt*/ + /*MOV R1, R0, LSR #12 + MOV R2, #readlookup2 + LDR R1, [R2, R1, LSL #2] + CMP R1, #-1 + BNE + + LDRB R0, [R1, R0] + MOV R1, #0 + MOV PC, LR + * STR LR, [SP, -4]! + BL readmembl + LDRB R1, cpu_state.abrt + LDR PC, [SP], #4 + */ + codegen_alloc(block, 80); + host_arm_MOV_REG_LSR(block, REG_R2, REG_R0, 12); + host_arm_MOV_IMM(block, REG_R3, (uint32_t)writelookup2); + host_arm_LDR_REG_LSL(block, REG_R2, REG_R3, REG_R2, 2); + if (size != 1) { + host_arm_TST_IMM(block, REG_R0, size - 1); + misaligned_offset = host_arm_BNE_(block); + } + host_arm_CMP_IMM(block, REG_R2, -1); + branch_offset = host_arm_BEQ_(block); + if (size == 1 && !is_float) + host_arm_STRB_REG(block, REG_R1, REG_R2, REG_R0); + else if (size == 2 && !is_float) + host_arm_STRH_REG(block, REG_R1, REG_R2, REG_R0); + else if (size == 4 && !is_float) + host_arm_STR_REG(block, REG_R1, REG_R2, REG_R0); + else if (size == 4 && is_float) { + host_arm_ADD_REG(block, REG_R0, REG_R0, REG_R2); + host_arm_VSTR_S(block, REG_D_TEMP, REG_R0, 0); + } else if (size == 8) { + host_arm_ADD_REG(block, REG_R0, REG_R0, REG_R2); + host_arm_VSTR_D(block, REG_D_TEMP, REG_R0, 0); + } + host_arm_MOV_IMM(block, REG_R1, 0); + host_arm_MOV_REG(block, REG_PC, REG_LR); - *branch_offset |= ((((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 8) & 0x3fffffc) >> 2; - if (size != 1) - *misaligned_offset |= ((((uintptr_t)&block_write_data[block_pos] - (uintptr_t)misaligned_offset) - 8) & 0x3fffffc) >> 2; - host_arm_STR_IMM_WB(block, REG_LR, REG_HOST_SP, -4); - if (size == 4 && is_float) - host_arm_VMOV_32_S(block, REG_R1, REG_D_TEMP); - else if (size == 8) - host_arm_VMOV_64_D(block, REG_R2, REG_R3, REG_D_TEMP); - if (size == 1) - host_arm_BL(block, (uintptr_t)writemembl); - else if (size == 2) - host_arm_BL(block, (uintptr_t)writememwl); - else if (size == 4) - host_arm_BL(block, (uintptr_t)writememll); - else if (size == 8) - host_arm_BL_r1(block, (uintptr_t)writememql); - else - fatal("build_store_routine - unknown size %i\n", size); - host_arm_LDRB_ABS(block, REG_R1, &cpu_state.abrt); - host_arm_LDR_IMM_POST(block, REG_PC, REG_HOST_SP, 4); + *branch_offset |= ((((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 8) & 0x3fffffc) >> 2; + if (size != 1) + *misaligned_offset |= + ((((uintptr_t)&block_write_data[block_pos] - (uintptr_t)misaligned_offset) - 8) & 0x3fffffc) >> 2; + host_arm_STR_IMM_WB(block, REG_LR, REG_HOST_SP, -4); + if (size == 4 && is_float) + host_arm_VMOV_32_S(block, REG_R1, REG_D_TEMP); + else if (size == 8) + host_arm_VMOV_64_D(block, REG_R2, REG_R3, REG_D_TEMP); + if (size == 1) + host_arm_BL(block, (uintptr_t)writemembl); + else if (size == 2) + host_arm_BL(block, (uintptr_t)writememwl); + else if (size == 4) + host_arm_BL(block, (uintptr_t)writememll); + else if (size == 8) + host_arm_BL_r1(block, (uintptr_t)writememql); + else + fatal("build_store_routine - unknown size %i\n", size); + host_arm_LDRB_ABS(block, REG_R1, &cpu_state.abrt); + host_arm_LDR_IMM_POST(block, REG_PC, REG_HOST_SP, 4); } -static void build_loadstore_routines(codeblock_t *block) -{ - codegen_mem_load_byte = &block_write_data[block_pos]; - build_load_routine(block, 1, 0); - codegen_mem_load_word = &block_write_data[block_pos]; - build_load_routine(block, 2, 0); - codegen_mem_load_long = &block_write_data[block_pos]; - build_load_routine(block, 4, 0); - codegen_mem_load_quad = &block_write_data[block_pos]; - build_load_routine(block, 8, 0); - codegen_mem_load_single = &block_write_data[block_pos]; - build_load_routine(block, 4, 1); - codegen_mem_load_double = &block_write_data[block_pos]; - build_load_routine(block, 8, 1); +static void build_loadstore_routines(codeblock_t *block) { + codegen_mem_load_byte = &block_write_data[block_pos]; + build_load_routine(block, 1, 0); + codegen_mem_load_word = &block_write_data[block_pos]; + build_load_routine(block, 2, 0); + codegen_mem_load_long = &block_write_data[block_pos]; + build_load_routine(block, 4, 0); + codegen_mem_load_quad = &block_write_data[block_pos]; + build_load_routine(block, 8, 0); + codegen_mem_load_single = &block_write_data[block_pos]; + build_load_routine(block, 4, 1); + codegen_mem_load_double = &block_write_data[block_pos]; + build_load_routine(block, 8, 1); - codegen_mem_store_byte = &block_write_data[block_pos]; - build_store_routine(block, 1, 0); - codegen_mem_store_word = &block_write_data[block_pos]; - build_store_routine(block, 2, 0); - codegen_mem_store_long = &block_write_data[block_pos]; - build_store_routine(block, 4, 0); - codegen_mem_store_quad = &block_write_data[block_pos]; - build_store_routine(block, 8, 0); - codegen_mem_store_single = &block_write_data[block_pos]; - build_store_routine(block, 4, 1); - codegen_mem_store_double = &block_write_data[block_pos]; - build_store_routine(block, 8, 1); + codegen_mem_store_byte = &block_write_data[block_pos]; + build_store_routine(block, 1, 0); + codegen_mem_store_word = &block_write_data[block_pos]; + build_store_routine(block, 2, 0); + codegen_mem_store_long = &block_write_data[block_pos]; + build_store_routine(block, 4, 0); + codegen_mem_store_quad = &block_write_data[block_pos]; + build_store_routine(block, 8, 0); + codegen_mem_store_single = &block_write_data[block_pos]; + build_store_routine(block, 4, 1); + codegen_mem_store_double = &block_write_data[block_pos]; + build_store_routine(block, 8, 1); } /*VFP has a specific round-to-zero instruction, and the default rounding mode is nearest. For round up/down, temporarily change the rounding mode in FPCSR*/ #define FPCSR_ROUNDING_MASK (3 << 22) -#define FPCSR_ROUNDING_UP (1 << 22) +#define FPCSR_ROUNDING_UP (1 << 22) #define FPCSR_ROUNDING_DOWN (2 << 22) -static void build_fp_round_routine(codeblock_t *block) -{ - uint32_t *jump_table; +static void build_fp_round_routine(codeblock_t *block) { + uint32_t *jump_table; - codegen_alloc(block, 80); + codegen_alloc(block, 80); - host_arm_MOV_REG(block, REG_TEMP2, REG_LR); - host_arm_MOV_REG(block, REG_LR, REG_TEMP2); - host_arm_LDR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.new_fp_control - (uintptr_t)&cpu_state); - host_arm_LDR_REG(block, REG_PC, REG_PC, REG_TEMP); - host_arm_NOP(block); + host_arm_MOV_REG(block, REG_TEMP2, REG_LR); + host_arm_MOV_REG(block, REG_LR, REG_TEMP2); + host_arm_LDR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.new_fp_control - (uintptr_t)&cpu_state); + host_arm_LDR_REG(block, REG_PC, REG_PC, REG_TEMP); + host_arm_NOP(block); - jump_table = (uint32_t *)&block_write_data[block_pos]; - host_arm_NOP(block); - host_arm_NOP(block); - host_arm_NOP(block); - host_arm_NOP(block); + jump_table = (uint32_t *)&block_write_data[block_pos]; + host_arm_NOP(block); + host_arm_NOP(block); + host_arm_NOP(block); + host_arm_NOP(block); - jump_table[X87_ROUNDING_NEAREST] = (uint64_t)(uintptr_t)&block_write_data[block_pos]; //tie even - host_arm_VCVTR_IS_D(block, REG_D_TEMP, REG_D_TEMP); - host_arm_MOV_REG(block, REG_PC, REG_LR); + jump_table[X87_ROUNDING_NEAREST] = (uint64_t)(uintptr_t)&block_write_data[block_pos]; // tie even + host_arm_VCVTR_IS_D(block, REG_D_TEMP, REG_D_TEMP); + host_arm_MOV_REG(block, REG_PC, REG_LR); - jump_table[X87_ROUNDING_UP] = (uint64_t)(uintptr_t)&block_write_data[block_pos]; //pos inf - host_arm_LDR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.old_fp_control - (uintptr_t)&cpu_state); - host_arm_BIC_IMM(block, REG_TEMP2, REG_TEMP, FPCSR_ROUNDING_MASK); - host_arm_ORR_IMM(block, REG_TEMP2, REG_TEMP2, FPCSR_ROUNDING_UP); - host_arm_VMSR_FPSCR(block, REG_TEMP2); - host_arm_VCVTR_IS_D(block, REG_D_TEMP, REG_D_TEMP); - host_arm_VMSR_FPSCR(block, REG_TEMP); - host_arm_MOV_REG(block, REG_PC, REG_LR); + jump_table[X87_ROUNDING_UP] = (uint64_t)(uintptr_t)&block_write_data[block_pos]; // pos inf + host_arm_LDR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.old_fp_control - (uintptr_t)&cpu_state); + host_arm_BIC_IMM(block, REG_TEMP2, REG_TEMP, FPCSR_ROUNDING_MASK); + host_arm_ORR_IMM(block, REG_TEMP2, REG_TEMP2, FPCSR_ROUNDING_UP); + host_arm_VMSR_FPSCR(block, REG_TEMP2); + host_arm_VCVTR_IS_D(block, REG_D_TEMP, REG_D_TEMP); + host_arm_VMSR_FPSCR(block, REG_TEMP); + host_arm_MOV_REG(block, REG_PC, REG_LR); - jump_table[X87_ROUNDING_DOWN] = (uint64_t)(uintptr_t)&block_write_data[block_pos]; //neg inf - host_arm_LDR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.old_fp_control - (uintptr_t)&cpu_state); - host_arm_BIC_IMM(block, REG_TEMP2, REG_TEMP, FPCSR_ROUNDING_MASK); - host_arm_ORR_IMM(block, REG_TEMP2, REG_TEMP, FPCSR_ROUNDING_DOWN); - host_arm_VMSR_FPSCR(block, REG_TEMP2); - host_arm_VCVTR_IS_D(block, REG_D_TEMP, REG_D_TEMP); - host_arm_VMSR_FPSCR(block, REG_TEMP); - host_arm_MOV_REG(block, REG_PC, REG_LR); + jump_table[X87_ROUNDING_DOWN] = (uint64_t)(uintptr_t)&block_write_data[block_pos]; // neg inf + host_arm_LDR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.old_fp_control - (uintptr_t)&cpu_state); + host_arm_BIC_IMM(block, REG_TEMP2, REG_TEMP, FPCSR_ROUNDING_MASK); + host_arm_ORR_IMM(block, REG_TEMP2, REG_TEMP, FPCSR_ROUNDING_DOWN); + host_arm_VMSR_FPSCR(block, REG_TEMP2); + host_arm_VCVTR_IS_D(block, REG_D_TEMP, REG_D_TEMP); + host_arm_VMSR_FPSCR(block, REG_TEMP); + host_arm_MOV_REG(block, REG_PC, REG_LR); - jump_table[X87_ROUNDING_CHOP] = (uint64_t)(uintptr_t)&block_write_data[block_pos]; //zero - host_arm_VCVT_IS_D(block, REG_D_TEMP, REG_D_TEMP); - host_arm_MOV_REG(block, REG_PC, REG_LR); + jump_table[X87_ROUNDING_CHOP] = (uint64_t)(uintptr_t)&block_write_data[block_pos]; // zero + host_arm_VCVT_IS_D(block, REG_D_TEMP, REG_D_TEMP); + host_arm_MOV_REG(block, REG_PC, REG_LR); } -void codegen_backend_init() -{ - codeblock_t *block; - int c; +void codegen_backend_init() { + codeblock_t *block; + int c; - codeblock = malloc(BLOCK_SIZE * sizeof(codeblock_t)); - codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); + codeblock = malloc(BLOCK_SIZE * sizeof(codeblock_t)); + 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 *)); + 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].pc = BLOCK_PC_INVALID; + for (c = 0; c < BLOCK_SIZE; c++) + codeblock[c].pc = BLOCK_PC_INVALID; -// pclog("Codegen is %p\n", (void *)pages[0xfab12 >> 12].block); + // pclog("Codegen is %p\n", (void *)pages[0xfab12 >> 12].block); - block_current = 0; - block_pos = 0; - block = &codeblock[block_current]; - block->head_mem_block = codegen_allocator_allocate(NULL, block_current); - block->data = codeblock_allocator_get_ptr(block->head_mem_block); - block_write_data = block->data; - build_loadstore_routines(&codeblock[block_current]); -printf("block_pos=%i\n", block_pos); + block_current = 0; + block_pos = 0; + block = &codeblock[block_current]; + block->head_mem_block = codegen_allocator_allocate(NULL, block_current); + block->data = codeblock_allocator_get_ptr(block->head_mem_block); + block_write_data = block->data; + build_loadstore_routines(&codeblock[block_current]); + printf("block_pos=%i\n", block_pos); - codegen_fp_round = &block_write_data[block_pos]; - build_fp_round_routine(&codeblock[block_current]); + codegen_fp_round = &block_write_data[block_pos]; + build_fp_round_routine(&codeblock[block_current]); - codegen_alloc(block, 80); - codegen_gpf_rout = &block_write_data[block_pos]; - host_arm_MOV_IMM(block, REG_R0, 0); - host_arm_MOV_IMM(block, REG_R1, 0); - host_arm_call(block, x86gpf); + codegen_alloc(block, 80); + codegen_gpf_rout = &block_write_data[block_pos]; + host_arm_MOV_IMM(block, REG_R0, 0); + host_arm_MOV_IMM(block, REG_R1, 0); + host_arm_call(block, x86gpf); - codegen_exit_rout = &block_write_data[block_pos]; - host_arm_ADD_IMM(block, REG_HOST_SP, REG_HOST_SP, 0x40); - host_arm_LDMIA_WB(block, REG_HOST_SP, REG_MASK_LOCAL | REG_MASK_PC); + codegen_exit_rout = &block_write_data[block_pos]; + host_arm_ADD_IMM(block, REG_HOST_SP, REG_HOST_SP, 0x40); + host_arm_LDMIA_WB(block, REG_HOST_SP, REG_MASK_LOCAL | REG_MASK_PC); - block_write_data = NULL; -//fatal("block_pos=%i\n", block_pos); - asm("vmrs %0, fpscr\n" - : "=r" (cpu_state.old_fp_control) - ); - if ((cpu_state.old_fp_control >> 22) & 3) - fatal("VFP not in nearest rounding mode\n"); + block_write_data = NULL; + // fatal("block_pos=%i\n", block_pos); + asm("vmrs %0, fpscr\n" : "=r"(cpu_state.old_fp_control)); + if ((cpu_state.old_fp_control >> 22) & 3) + fatal("VFP not in nearest rounding mode\n"); } -void codegen_set_rounding_mode(int mode) -{ - if (mode < 0 || mode > 3) - fatal("codegen_set_rounding_mode - invalid mode\n"); - cpu_state.new_fp_control = mode << 2; +void codegen_set_rounding_mode(int mode) { + if (mode < 0 || mode > 3) + fatal("codegen_set_rounding_mode - invalid mode\n"); + cpu_state.new_fp_control = mode << 2; } /*R10 - cpu_state*/ -void codegen_backend_prologue(codeblock_t *block) -{ - block_pos = BLOCK_START; +void codegen_backend_prologue(codeblock_t *block) { + block_pos = BLOCK_START; - /*Entry code*/ + /*Entry code*/ - host_arm_STMDB_WB(block, REG_HOST_SP, REG_MASK_LOCAL | REG_MASK_LR); - host_arm_SUB_IMM(block, REG_HOST_SP, REG_HOST_SP, 0x40); - host_arm_MOV_IMM(block, REG_CPUSTATE, (uint32_t)&cpu_state); - if (block->flags & CODEBLOCK_HAS_FPU) - { - host_arm_LDR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.TOP - (uintptr_t)&cpu_state); - host_arm_SUB_IMM(block, REG_TEMP, REG_TEMP, block->TOP); - host_arm_STR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset); - } + host_arm_STMDB_WB(block, REG_HOST_SP, REG_MASK_LOCAL | REG_MASK_LR); + host_arm_SUB_IMM(block, REG_HOST_SP, REG_HOST_SP, 0x40); + host_arm_MOV_IMM(block, REG_CPUSTATE, (uint32_t)&cpu_state); + if (block->flags & CODEBLOCK_HAS_FPU) { + host_arm_LDR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.TOP - (uintptr_t)&cpu_state); + host_arm_SUB_IMM(block, REG_TEMP, REG_TEMP, block->TOP); + host_arm_STR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset); + } } -void codegen_backend_epilogue(codeblock_t *block) -{ - host_arm_ADD_IMM(block, REG_HOST_SP, REG_HOST_SP, 0x40); - host_arm_LDMIA_WB(block, REG_HOST_SP, REG_MASK_LOCAL | REG_MASK_PC); +void codegen_backend_epilogue(codeblock_t *block) { + host_arm_ADD_IMM(block, REG_HOST_SP, REG_HOST_SP, 0x40); + host_arm_LDMIA_WB(block, REG_HOST_SP, REG_MASK_LOCAL | REG_MASK_PC); - codegen_allocator_clean_blocks(block->head_mem_block); + codegen_allocator_clean_blocks(block->head_mem_block); } #endif diff --git a/src/codegen/arm32/codegen_backend_arm_ops.c b/src/codegen/arm32/codegen_backend_arm_ops.c index aeb3a81f..1d08eb27 100644 --- a/src/codegen/arm32/codegen_backend_arm_ops.c +++ b/src/codegen/arm32/codegen_backend_arm_ops.c @@ -7,102 +7,102 @@ #include "codegen_backend_arm_defs.h" #include "codegen_backend_arm_ops.h" -#define Rm(x) (x) -#define Rs(x) ((x) << 8) -#define Rd(x) ((x) << 12) -#define Rt(x) ((x) << 12) -#define Rn(x) ((x) << 16) +#define Rm(x) (x) +#define Rs(x) ((x) << 8) +#define Rd(x) ((x) << 12) +#define Rt(x) ((x) << 12) +#define Rn(x) ((x) << 16) #define Rt2(x) ((x) << 16) -#define Vm(x) (x) -#define Vd(x) ((x) << 12) -#define Vn(x) ((x) << 16) +#define Vm(x) (x) +#define Vd(x) ((x) << 12) +#define Vn(x) ((x) << 16) -#define DATA_OFFSET_UP (1 << 23) +#define DATA_OFFSET_UP (1 << 23) #define DATA_OFFSET_DOWN (0 << 23) #define OPCODE_SHIFT 20 -#define OPCODE_ADD_IMM (0x28 << OPCODE_SHIFT) -#define OPCODE_ADD_REG (0x08 << OPCODE_SHIFT) -#define OPCODE_AND_IMM (0x20 << OPCODE_SHIFT) -#define OPCODE_AND_REG (0x00 << OPCODE_SHIFT) -#define OPCODE_B (0xa0 << OPCODE_SHIFT) -#define OPCODE_BIC_IMM (0x3c << OPCODE_SHIFT) -#define OPCODE_BIC_REG (0x1c << OPCODE_SHIFT) -#define OPCODE_BL (0xb0 << OPCODE_SHIFT) -#define OPCODE_CMN_IMM (0x37 << OPCODE_SHIFT) -#define OPCODE_CMN_REG (0x17 << OPCODE_SHIFT) -#define OPCODE_CMP_IMM (0x35 << OPCODE_SHIFT) -#define OPCODE_CMP_REG (0x15 << OPCODE_SHIFT) -#define OPCODE_EOR_IMM (0x22 << OPCODE_SHIFT) -#define OPCODE_EOR_REG (0x02 << OPCODE_SHIFT) +#define OPCODE_ADD_IMM (0x28 << OPCODE_SHIFT) +#define OPCODE_ADD_REG (0x08 << OPCODE_SHIFT) +#define OPCODE_AND_IMM (0x20 << OPCODE_SHIFT) +#define OPCODE_AND_REG (0x00 << OPCODE_SHIFT) +#define OPCODE_B (0xa0 << OPCODE_SHIFT) +#define OPCODE_BIC_IMM (0x3c << OPCODE_SHIFT) +#define OPCODE_BIC_REG (0x1c << OPCODE_SHIFT) +#define OPCODE_BL (0xb0 << OPCODE_SHIFT) +#define OPCODE_CMN_IMM (0x37 << OPCODE_SHIFT) +#define OPCODE_CMN_REG (0x17 << OPCODE_SHIFT) +#define OPCODE_CMP_IMM (0x35 << OPCODE_SHIFT) +#define OPCODE_CMP_REG (0x15 << OPCODE_SHIFT) +#define OPCODE_EOR_IMM (0x22 << OPCODE_SHIFT) +#define OPCODE_EOR_REG (0x02 << OPCODE_SHIFT) #define OPCODE_LDMIA_WB (0x8b << OPCODE_SHIFT) -#define OPCODE_LDR_IMM (0x51 << OPCODE_SHIFT) -#define OPCODE_LDR_IMM_POST (0x41 << OPCODE_SHIFT) -#define OPCODE_LDR_REG (0x79 << OPCODE_SHIFT) +#define OPCODE_LDR_IMM (0x51 << OPCODE_SHIFT) +#define OPCODE_LDR_IMM_POST (0x41 << OPCODE_SHIFT) +#define OPCODE_LDR_REG (0x79 << OPCODE_SHIFT) #define OPCODE_LDRB_IMM (0x55 << OPCODE_SHIFT) #define OPCODE_LDRB_REG (0x7d << OPCODE_SHIFT) -#define OPCODE_MOV_IMM (0x3a << OPCODE_SHIFT) +#define OPCODE_MOV_IMM (0x3a << OPCODE_SHIFT) #define OPCODE_MOVT_IMM (0x34 << OPCODE_SHIFT) #define OPCODE_MOVW_IMM (0x30 << OPCODE_SHIFT) -#define OPCODE_MOV_REG (0x1a << OPCODE_SHIFT) -#define OPCODE_MVN_REG (0x1e << OPCODE_SHIFT) -#define OPCODE_ORR_IMM (0x38 << OPCODE_SHIFT) -#define OPCODE_ORR_REG (0x18 << OPCODE_SHIFT) -#define OPCODE_RSB_IMM (0x26 << OPCODE_SHIFT) -#define OPCODE_RSB_REG (0x06 << OPCODE_SHIFT) +#define OPCODE_MOV_REG (0x1a << OPCODE_SHIFT) +#define OPCODE_MVN_REG (0x1e << OPCODE_SHIFT) +#define OPCODE_ORR_IMM (0x38 << OPCODE_SHIFT) +#define OPCODE_ORR_REG (0x18 << OPCODE_SHIFT) +#define OPCODE_RSB_IMM (0x26 << OPCODE_SHIFT) +#define OPCODE_RSB_REG (0x06 << OPCODE_SHIFT) #define OPCODE_STMDB_WB (0x92 << OPCODE_SHIFT) -#define OPCODE_STR_IMM (0x50 << OPCODE_SHIFT) -#define OPCODE_STR_IMM_WB (0x52 << OPCODE_SHIFT) -#define OPCODE_STR_REG (0x78 << OPCODE_SHIFT) +#define OPCODE_STR_IMM (0x50 << OPCODE_SHIFT) +#define OPCODE_STR_IMM_WB (0x52 << OPCODE_SHIFT) +#define OPCODE_STR_REG (0x78 << OPCODE_SHIFT) #define OPCODE_STRB_IMM (0x54 << OPCODE_SHIFT) #define OPCODE_STRB_REG (0x7c << OPCODE_SHIFT) -#define OPCODE_SUB_IMM (0x24 << OPCODE_SHIFT) -#define OPCODE_SUB_REG (0x04 << OPCODE_SHIFT) -#define OPCODE_TST_IMM (0x31 << OPCODE_SHIFT) -#define OPCODE_TST_REG (0x11 << OPCODE_SHIFT) +#define OPCODE_SUB_IMM (0x24 << OPCODE_SHIFT) +#define OPCODE_SUB_REG (0x04 << OPCODE_SHIFT) +#define OPCODE_TST_IMM (0x31 << OPCODE_SHIFT) +#define OPCODE_TST_REG (0x11 << OPCODE_SHIFT) -#define OPCODE_BFI 0xe7c00010 -#define OPCODE_BLX 0xe12fff30 -#define OPCODE_BX 0xe12fff10 +#define OPCODE_BFI 0xe7c00010 +#define OPCODE_BLX 0xe12fff30 +#define OPCODE_BX 0xe12fff10 #define OPCODE_LDRH_IMM 0xe1d000b0 #define OPCODE_LDRH_REG 0xe19000b0 #define OPCODE_STRH_IMM 0xe1c000b0 #define OPCODE_STRH_REG 0xe18000b0 -#define OPCODE_SXTB 0xe6af0070 -#define OPCODE_SXTH 0xe6bf0070 -#define OPCODE_UADD8 0xe6500f90 +#define OPCODE_SXTB 0xe6af0070 +#define OPCODE_SXTH 0xe6bf0070 +#define OPCODE_UADD8 0xe6500f90 #define OPCODE_UADD16 0xe6500f10 -#define OPCODE_USUB8 0xe6500ff0 +#define OPCODE_USUB8 0xe6500ff0 #define OPCODE_USUB16 0xe6500f70 -#define OPCODE_UXTB 0xe6ef0070 -#define OPCODE_UXTH 0xe6ff0070 +#define OPCODE_UXTB 0xe6ef0070 +#define OPCODE_UXTH 0xe6ff0070 #define OPCODE_VABS_D 0xeeb00bc0 -#define OPCODE_VADD 0xee300b00 -#define OPCODE_VADD_I8 0xf2000800 +#define OPCODE_VADD 0xee300b00 +#define OPCODE_VADD_I8 0xf2000800 #define OPCODE_VADD_I16 0xf2100800 #define OPCODE_VADD_I32 0xf2200800 #define OPCODE_VADD_F32 0xf2000d00 #define OPCODE_VAND_D 0xf2000110 #define OPCODE_VBIC_D 0xf2100110 #define OPCODE_VCEQ_F32 0xf2000e00 -#define OPCODE_VCEQ_I8 0xf3000810 +#define OPCODE_VCEQ_I8 0xf3000810 #define OPCODE_VCEQ_I16 0xf3100810 #define OPCODE_VCEQ_I32 0xf3200810 #define OPCODE_VCGE_F32 0xf3000e00 #define OPCODE_VCGT_F32 0xf3200e00 -#define OPCODE_VCGT_S8 0xf2000300 +#define OPCODE_VCGT_S8 0xf2000300 #define OPCODE_VCGT_S16 0xf2100300 #define OPCODE_VCGT_S32 0xf2200300 #define OPCODE_VCMP_D 0xeeb40b40 -#define OPCODE_VCVT_D_IS 0xeeb80bc0 -#define OPCODE_VCVT_D_S 0xeeb70ac0 +#define OPCODE_VCVT_D_IS 0xeeb80bc0 +#define OPCODE_VCVT_D_S 0xeeb70ac0 #define OPCODE_VCVT_F32_S32 0xf3bb0700 -#define OPCODE_VCVT_IS_D 0xeebd0bc0 +#define OPCODE_VCVT_IS_D 0xeebd0bc0 #define OPCODE_VCVT_S32_F32 0xf3bb0600 -#define OPCODE_VCVT_S_D 0xeeb70bc0 +#define OPCODE_VCVT_S_D 0xeeb70bc0 #define OPCODE_VCVTR_IS_D 0xeebd0b40 -#define OPCODE_VDIV 0xee800b00 +#define OPCODE_VDIV 0xee800b00 #define OPCODE_VDIV_S 0xee800a00 #define OPCODE_VDUP_32 0xf3b40c00 #define OPCODE_VEOR_D 0xf3000110 @@ -114,52 +114,52 @@ #define OPCODE_VMOV_64_D 0xec500b10 #define OPCODE_VMOV_D_64 0xec400b10 #define OPCODE_VMOV_S_32 0xee000a10 -#define OPCODE_VMOV_D_D 0xeeb00b40 +#define OPCODE_VMOV_D_D 0xeeb00b40 #define OPCODE_VMOVN_I32 0xf3b60200 #define OPCODE_VMOVN_I64 0xf3ba0200 #define OPCODE_VMOV_F32_ONE 0xf2870f10 #define OPCODE_VMRS_APSR 0xeef1fa10 #define OPCODE_VMSR_FPSCR 0xeee10a10 -#define OPCODE_VMUL 0xee200b00 +#define OPCODE_VMUL 0xee200b00 #define OPCODE_VMUL_F32 0xf3000d10 -#define OPCODE_VMUL_S16 0xf2100910 +#define OPCODE_VMUL_S16 0xf2100910 #define OPCODE_VMULL_S16 0xf2900c00 #define OPCODE_VNEG_D 0xeeb10b40 #define OPCODE_VORR_D 0xf2200110 #define OPCODE_VPADDL_S16 0xf3b40200 #define OPCODE_VPADDL_S32 0xf3b80200 #define OPCODE_VPADDL_Q_S32 0xf3b80240 -#define OPCODE_VQADD_S8 0xf2000010 +#define OPCODE_VQADD_S8 0xf2000010 #define OPCODE_VQADD_S16 0xf2100010 -#define OPCODE_VQADD_U8 0xf3000010 +#define OPCODE_VQADD_U8 0xf3000010 #define OPCODE_VQADD_U16 0xf3100010 #define OPCODE_VQMOVN_S16 0xf3b20280 #define OPCODE_VQMOVN_S32 0xf3b60280 #define OPCODE_VQMOVN_U16 0xf3b202c0 -#define OPCODE_VQSUB_S8 0xf2000210 +#define OPCODE_VQSUB_S8 0xf2000210 #define OPCODE_VQSUB_S16 0xf2100210 -#define OPCODE_VQSUB_U8 0xf3000210 +#define OPCODE_VQSUB_U8 0xf3000210 #define OPCODE_VQSUB_U16 0xf3100210 #define OPCODE_VSHL_D_IMM_16 0xf2900510 #define OPCODE_VSHL_D_IMM_32 0xf2a00510 #define OPCODE_VSHL_D_IMM_64 0xf2800590 -#define OPCODE_VSHR_D_S16 0xf2900010 -#define OPCODE_VSHR_D_S32 0xf2a00010 -#define OPCODE_VSHR_D_S64 0xf2800090 -#define OPCODE_VSHR_D_U16 0xf3900010 -#define OPCODE_VSHR_D_U32 0xf3a00010 -#define OPCODE_VSHR_D_U64 0xf3800090 -#define OPCODE_VSHRN 0xf2800810 +#define OPCODE_VSHR_D_S16 0xf2900010 +#define OPCODE_VSHR_D_S32 0xf2a00010 +#define OPCODE_VSHR_D_S64 0xf2800090 +#define OPCODE_VSHR_D_U16 0xf3900010 +#define OPCODE_VSHR_D_U32 0xf3a00010 +#define OPCODE_VSHR_D_U64 0xf3800090 +#define OPCODE_VSHRN 0xf2800810 #define OPCODE_VSQRT_D 0xeeb10bc0 #define OPCODE_VSQRT_S 0xeeb10ac0 #define OPCODE_VSTR_D 0xed800b00 #define OPCODE_VSTR_S 0xed800a00 -#define OPCODE_VSUB 0xee300b40 -#define OPCODE_VSUB_I8 0xf3000800 +#define OPCODE_VSUB 0xee300b40 +#define OPCODE_VSUB_I8 0xf3000800 #define OPCODE_VSUB_I16 0xf3100800 #define OPCODE_VSUB_I32 0xf3200800 #define OPCODE_VSUB_F32 0xf3000d00 -#define OPCODE_VZIP_D8 0xf3b20180 +#define OPCODE_VZIP_D8 0xf3b20180 #define OPCODE_VZIP_D16 0xf3b60180 #define OPCODE_VZIP_D32 0xf3ba0080 @@ -190,10 +190,10 @@ #define UXTB_ROTATE(rotate) (((rotate) >> 3) << 10) -#define MOVT_IMM(imm) (((imm) & 0xfff) | (((imm) & 0xf000) << 4)) -#define MOVW_IMM(imm) (((imm) & 0xfff) | (((imm) & 0xf000) << 4)) +#define MOVT_IMM(imm) (((imm)&0xfff) | (((imm)&0xf000) << 4)) +#define MOVW_IMM(imm) (((imm)&0xfff) | (((imm)&0xf000) << 4)) -#define LDRH_IMM(imm) (((imm) & 0xf) | (((imm) & 0xf0) << 4)) +#define LDRH_IMM(imm) (((imm)&0xf) | (((imm)&0xf0) << 4)) #define STRH_IMM(imm) LDRH_IMM(imm) #define VSHIFT_IMM(shift) ((shift) << 16) @@ -204,1069 +204,830 @@ static void codegen_allocate_new_block(codeblock_t *block); -static inline void codegen_addlong(codeblock_t *block, uint32_t val) -{ - if (block_pos >= (BLOCK_MAX-4)) - codegen_allocate_new_block(block); - *(uint32_t *)&block_write_data[block_pos] = val; - block_pos += 4; +static inline void codegen_addlong(codeblock_t *block, uint32_t val) { + if (block_pos >= (BLOCK_MAX - 4)) + codegen_allocate_new_block(block); + *(uint32_t *)&block_write_data[block_pos] = val; + block_pos += 4; } -static void codegen_allocate_new_block(codeblock_t *block) -{ - /*Current block is full. Allocate a new block*/ - struct mem_block_t *new_block = codegen_allocator_allocate(block->head_mem_block, get_block_nr(block)); - uint8_t *new_ptr = codeblock_allocator_get_ptr(new_block); - uint32_t offset = ((uintptr_t)new_ptr - (uintptr_t)&block_write_data[block_pos]) - 8; +static void codegen_allocate_new_block(codeblock_t *block) { + /*Current block is full. Allocate a new block*/ + struct mem_block_t *new_block = codegen_allocator_allocate(block->head_mem_block, get_block_nr(block)); + uint8_t *new_ptr = codeblock_allocator_get_ptr(new_block); + uint32_t offset = ((uintptr_t)new_ptr - (uintptr_t)&block_write_data[block_pos]) - 8; - /*Add a jump instruction to the new block*/ - *(uint32_t *)&block_write_data[block_pos] = COND_AL | OPCODE_B | B_OFFSET(offset); + /*Add a jump instruction to the new block*/ + *(uint32_t *)&block_write_data[block_pos] = COND_AL | OPCODE_B | B_OFFSET(offset); - /*Set write address to start of new block*/ - block_pos = 0; - block_write_data = new_ptr; + /*Set write address to start of new block*/ + block_pos = 0; + block_write_data = new_ptr; } -static inline void codegen_alloc_4(codeblock_t *block) -{ - if (block_pos >= (BLOCK_MAX-4)) - codegen_allocate_new_block(block); +static inline void codegen_alloc_4(codeblock_t *block) { + if (block_pos >= (BLOCK_MAX - 4)) + codegen_allocate_new_block(block); } -void codegen_alloc(codeblock_t *block, int size) -{ - if (block_pos >= (BLOCK_MAX-size)) - codegen_allocate_new_block(block); +void codegen_alloc(codeblock_t *block, int size) { + if (block_pos >= (BLOCK_MAX - size)) + codegen_allocate_new_block(block); } -static inline uint32_t arm_data_offset(int offset) -{ - if (offset < -0xffc || offset > 0xffc) - fatal("arm_data_offset out of range - %i\n", offset); +static inline uint32_t arm_data_offset(int offset) { + if (offset < -0xffc || offset > 0xffc) + fatal("arm_data_offset out of range - %i\n", offset); - if (offset >= 0) - return offset | DATA_OFFSET_UP; - return (-offset) | DATA_OFFSET_DOWN; + if (offset >= 0) + return offset | DATA_OFFSET_UP; + return (-offset) | DATA_OFFSET_DOWN; } -static inline int get_arm_imm(uint32_t imm_data, uint32_t *arm_imm) -{ - int shift = 0; -//pclog("get_arm_imm - imm_data=%08x\n", imm_data); - if (!(imm_data & 0xffff)) - { - shift += 16; - imm_data >>= 16; - } - if (!(imm_data & 0xff)) - { - shift += 8; - imm_data >>= 8; - } - if (!(imm_data & 0xf)) - { - shift += 4; - imm_data >>= 4; - } - if (!(imm_data & 0x3)) - { - shift += 2; - imm_data >>= 2; - } - if (imm_data > 0xff) /*Note - should handle rotation round the word*/ - return 0; -//pclog(" imm_data=%02x shift=%i\n", imm_data, shift); - *arm_imm = imm_data | ((((32 - shift) >> 1) & 15) << 8); - return 1; +static inline int get_arm_imm(uint32_t imm_data, uint32_t *arm_imm) { + int shift = 0; + // pclog("get_arm_imm - imm_data=%08x\n", imm_data); + if (!(imm_data & 0xffff)) { + shift += 16; + imm_data >>= 16; + } + if (!(imm_data & 0xff)) { + shift += 8; + imm_data >>= 8; + } + if (!(imm_data & 0xf)) { + shift += 4; + imm_data >>= 4; + } + if (!(imm_data & 0x3)) { + shift += 2; + imm_data >>= 2; + } + if (imm_data > 0xff) /*Note - should handle rotation round the word*/ + return 0; + // pclog(" imm_data=%02x shift=%i\n", imm_data, shift); + *arm_imm = imm_data | ((((32 - shift) >> 1) & 15) << 8); + return 1; } -static inline int in_range(void *addr, void *base) -{ - int diff = (uintptr_t)addr - (uintptr_t)base; +static inline int in_range(void *addr, void *base) { + int diff = (uintptr_t)addr - (uintptr_t)base; - if (diff < -4095 || diff > 4095) - return 0; - return 1; + if (diff < -4095 || diff > 4095) + return 0; + return 1; } void host_arm_ADD_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); void host_arm_AND_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); void host_arm_EOR_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); -//void host_arm_ORR_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); +// void host_arm_ORR_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); void host_arm_SUB_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); -void host_arm_ADD_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) -{ - uint32_t arm_imm; - - if ((int32_t)imm < 0 && imm != 0x80000000) - { - host_arm_SUB_IMM(block, dst_reg, src_reg, -(int32_t)imm); - } - else if (get_arm_imm(imm, &arm_imm)) - { - codegen_addlong(block, COND_AL | OPCODE_ADD_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); - } - else - { - host_arm_MOV_IMM(block, REG_TEMP, imm); - host_arm_ADD_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); - } -} - -void host_arm_ADD_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) -{ - codegen_addlong(block, COND_AL | OPCODE_ADD_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); -} -void host_arm_ADD_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) -{ - codegen_addlong(block, COND_AL | OPCODE_ADD_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSR_IMM(shift)); -} - -void host_arm_AND_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) -{ - uint32_t arm_imm; - - if (get_arm_imm(imm, &arm_imm)) - { - codegen_addlong(block, COND_AL | OPCODE_AND_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); - } - else if (get_arm_imm(~imm, &arm_imm)) - { - codegen_addlong(block, COND_AL | OPCODE_BIC_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); - } - else - { - host_arm_MOV_IMM(block, REG_TEMP, imm); - host_arm_AND_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); - } -} - -void host_arm_AND_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) -{ - codegen_addlong(block, COND_AL | OPCODE_AND_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); -} -void host_arm_AND_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) -{ - codegen_addlong(block, COND_AL | OPCODE_AND_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSR_IMM(shift)); -} - -void host_arm_B(codeblock_t *block, uintptr_t dest_addr) -{ - uint32_t offset; - - codegen_alloc_4(block); - offset = (dest_addr - (uintptr_t)&block_write_data[block_pos]) - 8; - - if ((offset & 0xfe000000) && (offset & 0xfe000000) != 0xfe000000) - { - host_arm_MOV_IMM(block, REG_R3, dest_addr); - host_arm_BX(block, REG_R3); - } - else - codegen_addlong(block, COND_AL | OPCODE_B | B_OFFSET(offset)); -} - -void host_arm_BFI(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width) -{ - codegen_addlong(block, OPCODE_BFI | Rd(dst_reg) | Rm(src_reg) | BFI_lsb(lsb) | BFI_msb((lsb + width) - 1)); -} - -void host_arm_BIC_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) -{ - uint32_t arm_imm; +void host_arm_ADD_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) { + uint32_t arm_imm; - if (get_arm_imm(imm, &arm_imm)) - { - codegen_addlong(block, COND_AL | OPCODE_BIC_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); - } - else if (get_arm_imm(~imm, &arm_imm)) - { - codegen_addlong(block, COND_AL | OPCODE_AND_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); - } - else - { - host_arm_MOV_IMM(block, REG_TEMP, imm); - host_arm_BIC_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); - } + if ((int32_t)imm < 0 && imm != 0x80000000) { + host_arm_SUB_IMM(block, dst_reg, src_reg, -(int32_t)imm); + } else if (get_arm_imm(imm, &arm_imm)) { + codegen_addlong(block, COND_AL | OPCODE_ADD_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); + } else { + host_arm_MOV_IMM(block, REG_TEMP, imm); + host_arm_ADD_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); + } } -void host_arm_BIC_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) -{ - codegen_addlong(block, COND_AL | OPCODE_BIC_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); + +void host_arm_ADD_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) { + codegen_addlong(block, COND_AL | OPCODE_ADD_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); } -void host_arm_BIC_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) -{ - codegen_addlong(block, COND_AL | OPCODE_BIC_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSR_IMM(shift)); +void host_arm_ADD_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) { + codegen_addlong(block, COND_AL | OPCODE_ADD_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSR_IMM(shift)); } -void host_arm_BL(codeblock_t *block, uintptr_t dest_addr) -{ - uint32_t offset; +void host_arm_AND_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) { + uint32_t arm_imm; - codegen_alloc_4(block); - offset = (dest_addr - (uintptr_t)&block_write_data[block_pos]) - 8; + if (get_arm_imm(imm, &arm_imm)) { + codegen_addlong(block, COND_AL | OPCODE_AND_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); + } else if (get_arm_imm(~imm, &arm_imm)) { + codegen_addlong(block, COND_AL | OPCODE_BIC_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); + } else { + host_arm_MOV_IMM(block, REG_TEMP, imm); + host_arm_AND_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); + } +} - if ((offset & 0xfe000000) && (offset & 0xfe000000) != 0xfe000000) - { - host_arm_MOV_IMM(block, REG_R3, dest_addr); - host_arm_BLX(block, REG_R3); - } - else - codegen_addlong(block, COND_AL | OPCODE_BL | B_OFFSET(offset)); +void host_arm_AND_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) { + codegen_addlong(block, COND_AL | OPCODE_AND_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); +} +void host_arm_AND_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) { + codegen_addlong(block, COND_AL | OPCODE_AND_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSR_IMM(shift)); } -void host_arm_BL_r1(codeblock_t *block, uintptr_t dest_addr) -{ - uint32_t offset; - codegen_alloc_4(block); - offset = (dest_addr - (uintptr_t)&block_write_data[block_pos]) - 8; +void host_arm_B(codeblock_t *block, uintptr_t dest_addr) { + uint32_t offset; - if ((offset & 0xfe000000) && (offset & 0xfe000000) != 0xfe000000) - { - host_arm_MOV_IMM(block, REG_R1, dest_addr); - host_arm_BLX(block, REG_R1); - } - else - codegen_addlong(block, COND_AL | OPCODE_BL | B_OFFSET(offset)); + codegen_alloc_4(block); + offset = (dest_addr - (uintptr_t)&block_write_data[block_pos]) - 8; + + if ((offset & 0xfe000000) && (offset & 0xfe000000) != 0xfe000000) { + host_arm_MOV_IMM(block, REG_R3, dest_addr); + host_arm_BX(block, REG_R3); + } else + codegen_addlong(block, COND_AL | OPCODE_B | B_OFFSET(offset)); } -void host_arm_BLX(codeblock_t *block, int addr_reg) -{ - codegen_addlong(block, OPCODE_BLX | Rm(addr_reg)); + +void host_arm_BFI(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width) { + codegen_addlong(block, OPCODE_BFI | Rd(dst_reg) | Rm(src_reg) | BFI_lsb(lsb) | BFI_msb((lsb + width) - 1)); } -uint32_t *host_arm_BCC_(codeblock_t *block) -{ - codegen_addlong(block, COND_CC | OPCODE_B); +void host_arm_BIC_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) { + uint32_t arm_imm; - return (uint32_t *)&block_write_data[block_pos - 4]; + if (get_arm_imm(imm, &arm_imm)) { + codegen_addlong(block, COND_AL | OPCODE_BIC_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); + } else if (get_arm_imm(~imm, &arm_imm)) { + codegen_addlong(block, COND_AL | OPCODE_AND_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); + } else { + host_arm_MOV_IMM(block, REG_TEMP, imm); + host_arm_BIC_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); + } } -uint32_t *host_arm_BCS_(codeblock_t *block) -{ - codegen_addlong(block, COND_CS | OPCODE_B); - - return (uint32_t *)&block_write_data[block_pos - 4]; +void host_arm_BIC_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) { + codegen_addlong(block, COND_AL | OPCODE_BIC_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); } -uint32_t *host_arm_BEQ_(codeblock_t *block) -{ - codegen_addlong(block, COND_EQ | OPCODE_B); +void host_arm_BIC_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) { + codegen_addlong(block, COND_AL | OPCODE_BIC_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSR_IMM(shift)); +} + +void host_arm_BL(codeblock_t *block, uintptr_t dest_addr) { + uint32_t offset; + + codegen_alloc_4(block); + offset = (dest_addr - (uintptr_t)&block_write_data[block_pos]) - 8; - return (uint32_t *)&block_write_data[block_pos - 4]; + if ((offset & 0xfe000000) && (offset & 0xfe000000) != 0xfe000000) { + host_arm_MOV_IMM(block, REG_R3, dest_addr); + host_arm_BLX(block, REG_R3); + } else + codegen_addlong(block, COND_AL | OPCODE_BL | B_OFFSET(offset)); } -uint32_t *host_arm_BGE_(codeblock_t *block) -{ - codegen_addlong(block, COND_GE | OPCODE_B); +void host_arm_BL_r1(codeblock_t *block, uintptr_t dest_addr) { + uint32_t offset; - return (uint32_t *)&block_write_data[block_pos - 4]; + codegen_alloc_4(block); + offset = (dest_addr - (uintptr_t)&block_write_data[block_pos]) - 8; + + if ((offset & 0xfe000000) && (offset & 0xfe000000) != 0xfe000000) { + host_arm_MOV_IMM(block, REG_R1, dest_addr); + host_arm_BLX(block, REG_R1); + } else + codegen_addlong(block, COND_AL | OPCODE_BL | B_OFFSET(offset)); } -uint32_t *host_arm_BGT_(codeblock_t *block) -{ - codegen_addlong(block, COND_GT | OPCODE_B); +void host_arm_BLX(codeblock_t *block, int addr_reg) { codegen_addlong(block, OPCODE_BLX | Rm(addr_reg)); } + +uint32_t *host_arm_BCC_(codeblock_t *block) { + codegen_addlong(block, COND_CC | OPCODE_B); - return (uint32_t *)&block_write_data[block_pos - 4]; + return (uint32_t *)&block_write_data[block_pos - 4]; } -uint32_t *host_arm_BHI_(codeblock_t *block) -{ - codegen_addlong(block, COND_HI | OPCODE_B); +uint32_t *host_arm_BCS_(codeblock_t *block) { + codegen_addlong(block, COND_CS | OPCODE_B); - return (uint32_t *)&block_write_data[block_pos - 4]; + return (uint32_t *)&block_write_data[block_pos - 4]; } -uint32_t *host_arm_BLE_(codeblock_t *block) -{ - codegen_addlong(block, COND_LE | OPCODE_B); +uint32_t *host_arm_BEQ_(codeblock_t *block) { + codegen_addlong(block, COND_EQ | OPCODE_B); - return (uint32_t *)&block_write_data[block_pos - 4]; + return (uint32_t *)&block_write_data[block_pos - 4]; } -uint32_t *host_arm_BLS_(codeblock_t *block) -{ - codegen_addlong(block, COND_LS | OPCODE_B); +uint32_t *host_arm_BGE_(codeblock_t *block) { + codegen_addlong(block, COND_GE | OPCODE_B); - return (uint32_t *)&block_write_data[block_pos - 4]; + return (uint32_t *)&block_write_data[block_pos - 4]; } -uint32_t *host_arm_BLT_(codeblock_t *block) -{ - codegen_addlong(block, COND_LT | OPCODE_B); +uint32_t *host_arm_BGT_(codeblock_t *block) { + codegen_addlong(block, COND_GT | OPCODE_B); - return (uint32_t *)&block_write_data[block_pos - 4]; + return (uint32_t *)&block_write_data[block_pos - 4]; } -uint32_t *host_arm_BMI_(codeblock_t *block) -{ - codegen_addlong(block, COND_MI | OPCODE_B); +uint32_t *host_arm_BHI_(codeblock_t *block) { + codegen_addlong(block, COND_HI | OPCODE_B); - return (uint32_t *)&block_write_data[block_pos - 4]; + return (uint32_t *)&block_write_data[block_pos - 4]; } -uint32_t *host_arm_BNE_(codeblock_t *block) -{ - codegen_addlong(block, COND_NE | OPCODE_B); +uint32_t *host_arm_BLE_(codeblock_t *block) { + codegen_addlong(block, COND_LE | OPCODE_B); - return (uint32_t *)&block_write_data[block_pos - 4]; + return (uint32_t *)&block_write_data[block_pos - 4]; } -uint32_t *host_arm_BPL_(codeblock_t *block) -{ - codegen_addlong(block, COND_PL | OPCODE_B); +uint32_t *host_arm_BLS_(codeblock_t *block) { + codegen_addlong(block, COND_LS | OPCODE_B); - return (uint32_t *)&block_write_data[block_pos - 4]; + return (uint32_t *)&block_write_data[block_pos - 4]; } -uint32_t *host_arm_BVC_(codeblock_t *block) -{ - codegen_addlong(block, COND_VC | OPCODE_B); +uint32_t *host_arm_BLT_(codeblock_t *block) { + codegen_addlong(block, COND_LT | OPCODE_B); - return (uint32_t *)&block_write_data[block_pos - 4]; + return (uint32_t *)&block_write_data[block_pos - 4]; } -uint32_t *host_arm_BVS_(codeblock_t *block) -{ - codegen_addlong(block, COND_VS | OPCODE_B); +uint32_t *host_arm_BMI_(codeblock_t *block) { + codegen_addlong(block, COND_MI | OPCODE_B); - return (uint32_t *)&block_write_data[block_pos - 4]; + return (uint32_t *)&block_write_data[block_pos - 4]; } +uint32_t *host_arm_BNE_(codeblock_t *block) { + codegen_addlong(block, COND_NE | OPCODE_B); -void host_arm_BEQ(codeblock_t *block, uintptr_t dest_addr) -{ - uint32_t offset; + return (uint32_t *)&block_write_data[block_pos - 4]; +} +uint32_t *host_arm_BPL_(codeblock_t *block) { + codegen_addlong(block, COND_PL | OPCODE_B); - codegen_alloc_4(block); - offset = (dest_addr - (uintptr_t)&block_write_data[block_pos]) - 8; + return (uint32_t *)&block_write_data[block_pos - 4]; +} +uint32_t *host_arm_BVC_(codeblock_t *block) { + codegen_addlong(block, COND_VC | OPCODE_B); - if ((offset & 0xfe000000) && (offset & 0xfe000000) != 0xfe000000) - fatal("host_arm_BEQ - out of range %08x %i\n", offset, offset); + return (uint32_t *)&block_write_data[block_pos - 4]; +} +uint32_t *host_arm_BVS_(codeblock_t *block) { + codegen_addlong(block, COND_VS | OPCODE_B); - codegen_addlong(block, COND_EQ | OPCODE_B | B_OFFSET(offset)); + return (uint32_t *)&block_write_data[block_pos - 4]; } -void host_arm_BNE(codeblock_t *block, uintptr_t dest_addr) -{ - uint32_t offset; - codegen_alloc_4(block); - offset = (dest_addr - (uintptr_t)&block_write_data[block_pos]) - 8; +void host_arm_BEQ(codeblock_t *block, uintptr_t dest_addr) { + uint32_t offset; - if ((offset & 0xfe000000) && (offset & 0xfe000000) != 0xfe000000) - fatal("host_arm_BNE - out of range %08x %i\n", offset, offset); + codegen_alloc_4(block); + offset = (dest_addr - (uintptr_t)&block_write_data[block_pos]) - 8; - codegen_addlong(block, COND_NE | OPCODE_B | B_OFFSET(offset)); + if ((offset & 0xfe000000) && (offset & 0xfe000000) != 0xfe000000) + fatal("host_arm_BEQ - out of range %08x %i\n", offset, offset); + + codegen_addlong(block, COND_EQ | OPCODE_B | B_OFFSET(offset)); } +void host_arm_BNE(codeblock_t *block, uintptr_t dest_addr) { + uint32_t offset; + + codegen_alloc_4(block); + offset = (dest_addr - (uintptr_t)&block_write_data[block_pos]) - 8; -void host_arm_BX(codeblock_t *block, int addr_reg) -{ - codegen_addlong(block, OPCODE_BLX | Rm(addr_reg)); + if ((offset & 0xfe000000) && (offset & 0xfe000000) != 0xfe000000) + fatal("host_arm_BNE - out of range %08x %i\n", offset, offset); + + codegen_addlong(block, COND_NE | OPCODE_B | B_OFFSET(offset)); } -void host_arm_CMN_IMM(codeblock_t *block, int src_reg, uint32_t imm) -{ - uint32_t arm_imm; +void host_arm_BX(codeblock_t *block, int addr_reg) { codegen_addlong(block, OPCODE_BLX | Rm(addr_reg)); } + +void host_arm_CMN_IMM(codeblock_t *block, int src_reg, uint32_t imm) { + uint32_t arm_imm; - if ((int32_t)imm < 0 && imm != 0x80000000) - { - host_arm_CMP_IMM(block, src_reg, -(int32_t)imm); - } - else if (get_arm_imm(imm, &arm_imm)) - { - codegen_addlong(block, COND_AL | OPCODE_CMN_IMM | Rn(src_reg) | arm_imm); - } - else - { - host_arm_MOV_IMM(block, REG_TEMP, imm); - host_arm_CMN_REG_LSL(block, src_reg, REG_TEMP, 0); - } + if ((int32_t)imm < 0 && imm != 0x80000000) { + host_arm_CMP_IMM(block, src_reg, -(int32_t)imm); + } else if (get_arm_imm(imm, &arm_imm)) { + codegen_addlong(block, COND_AL | OPCODE_CMN_IMM | Rn(src_reg) | arm_imm); + } else { + host_arm_MOV_IMM(block, REG_TEMP, imm); + host_arm_CMN_REG_LSL(block, src_reg, REG_TEMP, 0); + } } -void host_arm_CMN_REG_LSL(codeblock_t *block, int src_reg_n, int src_reg_m, int shift) -{ - codegen_addlong(block, COND_AL | OPCODE_CMN_REG | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); +void host_arm_CMN_REG_LSL(codeblock_t *block, int src_reg_n, int src_reg_m, int shift) { + codegen_addlong(block, COND_AL | OPCODE_CMN_REG | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); } -void host_arm_CMP_IMM(codeblock_t *block, int src_reg, uint32_t imm) -{ - uint32_t arm_imm; +void host_arm_CMP_IMM(codeblock_t *block, int src_reg, uint32_t imm) { + uint32_t arm_imm; - if ((int32_t)imm < 0 && imm != 0x80000000) - { - host_arm_CMN_IMM(block, src_reg, -(int32_t)imm); - } - else if (get_arm_imm(imm, &arm_imm)) - { - codegen_addlong(block, COND_AL | OPCODE_CMP_IMM | Rn(src_reg) | arm_imm); - } - else - { - host_arm_MOV_IMM(block, REG_TEMP, imm); - host_arm_CMP_REG_LSL(block, src_reg, REG_TEMP, 0); - } + if ((int32_t)imm < 0 && imm != 0x80000000) { + host_arm_CMN_IMM(block, src_reg, -(int32_t)imm); + } else if (get_arm_imm(imm, &arm_imm)) { + codegen_addlong(block, COND_AL | OPCODE_CMP_IMM | Rn(src_reg) | arm_imm); + } else { + host_arm_MOV_IMM(block, REG_TEMP, imm); + host_arm_CMP_REG_LSL(block, src_reg, REG_TEMP, 0); + } } -void host_arm_CMP_REG_LSL(codeblock_t *block, int src_reg_n, int src_reg_m, int shift) -{ - codegen_addlong(block, COND_AL | OPCODE_CMP_REG | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); +void host_arm_CMP_REG_LSL(codeblock_t *block, int src_reg_n, int src_reg_m, int shift) { + codegen_addlong(block, COND_AL | OPCODE_CMP_REG | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); } -void host_arm_EOR_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) -{ - uint32_t arm_imm; +void host_arm_EOR_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) { + uint32_t arm_imm; - if (get_arm_imm(imm, &arm_imm)) - { - codegen_addlong(block, COND_AL | OPCODE_EOR_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); - } - else - { - host_arm_MOV_IMM(block, REG_TEMP, imm); - host_arm_EOR_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); - } + if (get_arm_imm(imm, &arm_imm)) { + codegen_addlong(block, COND_AL | OPCODE_EOR_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); + } else { + host_arm_MOV_IMM(block, REG_TEMP, imm); + host_arm_EOR_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); + } } -void host_arm_EOR_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) -{ - codegen_addlong(block, COND_AL | OPCODE_EOR_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); +void host_arm_EOR_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) { + codegen_addlong(block, COND_AL | OPCODE_EOR_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); } -void host_arm_LDMIA_WB(codeblock_t *block, int addr_reg, uint32_t reg_mask) -{ - codegen_addlong(block, COND_AL | OPCODE_LDMIA_WB | Rn(addr_reg) | reg_mask); +void host_arm_LDMIA_WB(codeblock_t *block, int addr_reg, uint32_t reg_mask) { + codegen_addlong(block, COND_AL | OPCODE_LDMIA_WB | Rn(addr_reg) | reg_mask); } -void host_arm_LDR_IMM(codeblock_t *block, int dst_reg, int addr_reg, int offset) -{ - codegen_addlong(block, COND_AL | OPCODE_LDR_IMM | Rn(addr_reg) | Rd(dst_reg) | arm_data_offset(offset)); +void host_arm_LDR_IMM(codeblock_t *block, int dst_reg, int addr_reg, int offset) { + codegen_addlong(block, COND_AL | OPCODE_LDR_IMM | Rn(addr_reg) | Rd(dst_reg) | arm_data_offset(offset)); } -void host_arm_LDR_IMM_POST(codeblock_t *block, int dst_reg, int addr_reg, int offset) -{ - codegen_addlong(block, COND_AL | OPCODE_LDR_IMM_POST | Rn(addr_reg) | Rd(dst_reg) | arm_data_offset(offset)); +void host_arm_LDR_IMM_POST(codeblock_t *block, int dst_reg, int addr_reg, int offset) { + codegen_addlong(block, COND_AL | OPCODE_LDR_IMM_POST | Rn(addr_reg) | Rd(dst_reg) | arm_data_offset(offset)); } -void host_arm_LDR_REG_LSL(codeblock_t *block, int dst_reg, int addr_reg, int offset_reg, int shift) -{ - codegen_addlong(block, COND_AL | OPCODE_LDR_REG | Rn(addr_reg) | Rd(dst_reg) | Rm(offset_reg) | SHIFT_LSL_IMM(shift)); +void host_arm_LDR_REG_LSL(codeblock_t *block, int dst_reg, int addr_reg, int offset_reg, int shift) { + codegen_addlong(block, COND_AL | OPCODE_LDR_REG | Rn(addr_reg) | Rd(dst_reg) | Rm(offset_reg) | SHIFT_LSL_IMM(shift)); } -void host_arm_LDRB_ABS(codeblock_t *block, int dst_reg, void *p) -{ - if (in_range(p, &cpu_state)) - host_arm_LDRB_IMM(block, dst_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - fatal("LDRB_ABS - not in range\n"); +void host_arm_LDRB_ABS(codeblock_t *block, int dst_reg, void *p) { + if (in_range(p, &cpu_state)) + host_arm_LDRB_IMM(block, dst_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); + else + fatal("LDRB_ABS - not in range\n"); +} +void host_arm_LDRB_IMM(codeblock_t *block, int dst_reg, int addr_reg, int offset) { + codegen_addlong(block, COND_AL | OPCODE_LDRB_IMM | Rn(addr_reg) | Rd(dst_reg) | arm_data_offset(offset)); } -void host_arm_LDRB_IMM(codeblock_t *block, int dst_reg, int addr_reg, int offset) -{ - codegen_addlong(block, COND_AL | OPCODE_LDRB_IMM | Rn(addr_reg) | Rd(dst_reg) | arm_data_offset(offset)); +void host_arm_LDRB_REG_LSL(codeblock_t *block, int dst_reg, int addr_reg, int offset_reg, int shift) { + codegen_addlong(block, COND_AL | OPCODE_LDRB_REG | Rn(addr_reg) | Rd(dst_reg) | Rm(offset_reg) | SHIFT_LSL_IMM(shift)); +} + +void host_arm_LDRH_IMM(codeblock_t *block, int dst_reg, int addr_reg, int offset) { + codegen_addlong(block, COND_AL | OPCODE_LDRH_IMM | Rn(addr_reg) | Rd(dst_reg) | LDRH_IMM(offset)); } -void host_arm_LDRB_REG_LSL(codeblock_t *block, int dst_reg, int addr_reg, int offset_reg, int shift) -{ - codegen_addlong(block, COND_AL | OPCODE_LDRB_REG | Rn(addr_reg) | Rd(dst_reg) | Rm(offset_reg) | SHIFT_LSL_IMM(shift)); +void host_arm_LDRH_REG(codeblock_t *block, int dst_reg, int addr_reg, int offset_reg) { + codegen_addlong(block, COND_AL | OPCODE_LDRH_REG | Rn(addr_reg) | Rd(dst_reg) | Rm(offset_reg)); } -void host_arm_LDRH_IMM(codeblock_t *block, int dst_reg, int addr_reg, int offset) -{ - codegen_addlong(block, COND_AL | OPCODE_LDRH_IMM | Rn(addr_reg) | Rd(dst_reg) | LDRH_IMM(offset)); -} -void host_arm_LDRH_REG(codeblock_t *block, int dst_reg, int addr_reg, int offset_reg) -{ - codegen_addlong(block, COND_AL | OPCODE_LDRH_REG | Rn(addr_reg) | Rd(dst_reg) | Rm(offset_reg)); -} - -void host_arm_MOV_IMM(codeblock_t *block, int dst_reg, uint32_t imm) -{ - uint32_t arm_imm; +void host_arm_MOV_IMM(codeblock_t *block, int dst_reg, uint32_t imm) { + uint32_t arm_imm; - if (get_arm_imm(imm, &arm_imm)) - { - codegen_addlong(block, COND_AL | OPCODE_MOV_IMM | Rd(dst_reg) | arm_imm); - } - else - { - host_arm_MOVW_IMM(block, dst_reg, imm & 0xffff); - if (imm >> 16) - host_arm_MOVT_IMM(block, dst_reg, imm >> 16); - } + if (get_arm_imm(imm, &arm_imm)) { + codegen_addlong(block, COND_AL | OPCODE_MOV_IMM | Rd(dst_reg) | arm_imm); + } else { + host_arm_MOVW_IMM(block, dst_reg, imm & 0xffff); + if (imm >> 16) + host_arm_MOVT_IMM(block, dst_reg, imm >> 16); + } } -void host_arm_MOV_REG_ASR(codeblock_t *block, int dst_reg, int src_reg, int shift) -{ - codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_ASR_IMM(shift)); +void host_arm_MOV_REG_ASR(codeblock_t *block, int dst_reg, int src_reg, int shift) { + codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_ASR_IMM(shift)); } -void host_arm_MOV_REG_ASR_REG(codeblock_t *block, int dst_reg, int src_reg, int shift_reg) -{ - codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_ASR_REG(shift_reg)); +void host_arm_MOV_REG_ASR_REG(codeblock_t *block, int dst_reg, int src_reg, int shift_reg) { + codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_ASR_REG(shift_reg)); } -void host_arm_MOV_REG_LSL(codeblock_t *block, int dst_reg, int src_reg, int shift) -{ - codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_LSL_IMM(shift)); +void host_arm_MOV_REG_LSL(codeblock_t *block, int dst_reg, int src_reg, int shift) { + codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_LSL_IMM(shift)); } -void host_arm_MOV_REG_LSL_REG(codeblock_t *block, int dst_reg, int src_reg, int shift_reg) -{ - codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_LSL_REG(shift_reg)); +void host_arm_MOV_REG_LSL_REG(codeblock_t *block, int dst_reg, int src_reg, int shift_reg) { + codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_LSL_REG(shift_reg)); } -void host_arm_MOV_REG_LSR(codeblock_t *block, int dst_reg, int src_reg, int shift) -{ - codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_LSR_IMM(shift)); +void host_arm_MOV_REG_LSR(codeblock_t *block, int dst_reg, int src_reg, int shift) { + codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_LSR_IMM(shift)); } -void host_arm_MOV_REG_LSR_REG(codeblock_t *block, int dst_reg, int src_reg, int shift_reg) -{ - codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_LSR_REG(shift_reg)); +void host_arm_MOV_REG_LSR_REG(codeblock_t *block, int dst_reg, int src_reg, int shift_reg) { + codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_LSR_REG(shift_reg)); } -void host_arm_MOV_REG_ROR(codeblock_t *block, int dst_reg, int src_reg, int shift) -{ - codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_ROR_IMM(shift)); +void host_arm_MOV_REG_ROR(codeblock_t *block, int dst_reg, int src_reg, int shift) { + codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_ROR_IMM(shift)); } -void host_arm_MOV_REG_ROR_REG(codeblock_t *block, int dst_reg, int src_reg, int shift_reg) -{ - codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_ROR_REG(shift_reg)); +void host_arm_MOV_REG_ROR_REG(codeblock_t *block, int dst_reg, int src_reg, int shift_reg) { + codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_ROR_REG(shift_reg)); } -void host_arm_MOVT_IMM(codeblock_t *block, int dst_reg, uint16_t imm) -{ - codegen_addlong(block, COND_AL | OPCODE_MOVT_IMM | Rd(dst_reg) | MOVT_IMM(imm)); +void host_arm_MOVT_IMM(codeblock_t *block, int dst_reg, uint16_t imm) { + codegen_addlong(block, COND_AL | OPCODE_MOVT_IMM | Rd(dst_reg) | MOVT_IMM(imm)); } -void host_arm_MOVW_IMM(codeblock_t *block, int dst_reg, uint16_t imm) -{ - codegen_addlong(block, COND_AL | OPCODE_MOVW_IMM | Rd(dst_reg) | MOVW_IMM(imm)); +void host_arm_MOVW_IMM(codeblock_t *block, int dst_reg, uint16_t imm) { + codegen_addlong(block, COND_AL | OPCODE_MOVW_IMM | Rd(dst_reg) | MOVW_IMM(imm)); } -void host_arm_MVN_REG_LSL(codeblock_t *block, int dst_reg, int src_reg, int shift) -{ - codegen_addlong(block, COND_AL | OPCODE_MVN_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_LSL_IMM(shift)); +void host_arm_MVN_REG_LSL(codeblock_t *block, int dst_reg, int src_reg, int shift) { + codegen_addlong(block, COND_AL | OPCODE_MVN_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_LSL_IMM(shift)); } -void host_arm_ORR_IMM_cond(codeblock_t *block, uint32_t cond, int dst_reg, int src_reg, uint32_t imm) -{ - uint32_t arm_imm; +void host_arm_ORR_IMM_cond(codeblock_t *block, uint32_t cond, int dst_reg, int src_reg, uint32_t imm) { + uint32_t arm_imm; - if (get_arm_imm(imm, &arm_imm)) - { - codegen_addlong(block, cond | OPCODE_ORR_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); - } - else - { - host_arm_MOV_IMM(block, REG_TEMP, imm); - host_arm_ORR_REG_LSL_cond(block, cond, dst_reg, src_reg, REG_TEMP, 0); - } + if (get_arm_imm(imm, &arm_imm)) { + codegen_addlong(block, cond | OPCODE_ORR_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); + } else { + host_arm_MOV_IMM(block, REG_TEMP, imm); + host_arm_ORR_REG_LSL_cond(block, cond, dst_reg, src_reg, REG_TEMP, 0); + } } -void host_arm_ORR_REG_LSL_cond(codeblock_t *block, uint32_t cond, int dst_reg, int src_reg_n, int src_reg_m, int shift) -{ - codegen_addlong(block, cond | OPCODE_ORR_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); +void host_arm_ORR_REG_LSL_cond(codeblock_t *block, uint32_t cond, int dst_reg, int src_reg_n, int src_reg_m, int shift) { + codegen_addlong(block, cond | OPCODE_ORR_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); } -void host_arm_RSB_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) -{ - uint32_t arm_imm; +void host_arm_RSB_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) { + uint32_t arm_imm; - if (get_arm_imm(imm, &arm_imm)) - { - codegen_addlong(block, COND_AL | OPCODE_RSB_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); - } - else - { - host_arm_MOV_IMM(block, REG_TEMP, imm); - host_arm_RSB_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); - } + if (get_arm_imm(imm, &arm_imm)) { + codegen_addlong(block, COND_AL | OPCODE_RSB_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); + } else { + host_arm_MOV_IMM(block, REG_TEMP, imm); + host_arm_RSB_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); + } } -void host_arm_RSB_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) -{ - codegen_addlong(block, COND_AL | OPCODE_RSB_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); +void host_arm_RSB_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) { + codegen_addlong(block, COND_AL | OPCODE_RSB_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); } -void host_arm_RSB_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) -{ - codegen_addlong(block, COND_AL | OPCODE_RSB_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSR_IMM(shift)); +void host_arm_RSB_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) { + codegen_addlong(block, COND_AL | OPCODE_RSB_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSR_IMM(shift)); } -void host_arm_STMDB_WB(codeblock_t *block, int addr_reg, uint32_t reg_mask) -{ - codegen_addlong(block, COND_AL | OPCODE_STMDB_WB | Rn(addr_reg) | reg_mask); +void host_arm_STMDB_WB(codeblock_t *block, int addr_reg, uint32_t reg_mask) { + codegen_addlong(block, COND_AL | OPCODE_STMDB_WB | Rn(addr_reg) | reg_mask); } -void host_arm_STR_IMM(codeblock_t *block, int src_reg, int addr_reg, int offset) -{ - codegen_addlong(block, COND_AL | OPCODE_STR_IMM | Rn(addr_reg) | Rd(src_reg) | arm_data_offset(offset)); +void host_arm_STR_IMM(codeblock_t *block, int src_reg, int addr_reg, int offset) { + codegen_addlong(block, COND_AL | OPCODE_STR_IMM | Rn(addr_reg) | Rd(src_reg) | arm_data_offset(offset)); } -void host_arm_STR_IMM_WB(codeblock_t *block, int src_reg, int addr_reg, int offset) -{ - codegen_addlong(block, COND_AL | OPCODE_STR_IMM_WB | Rn(addr_reg) | Rd(src_reg) | arm_data_offset(offset)); +void host_arm_STR_IMM_WB(codeblock_t *block, int src_reg, int addr_reg, int offset) { + codegen_addlong(block, COND_AL | OPCODE_STR_IMM_WB | Rn(addr_reg) | Rd(src_reg) | arm_data_offset(offset)); } -void host_arm_STR_REG_LSL(codeblock_t *block, int src_reg, int addr_reg, int offset_reg, int shift) -{ - codegen_addlong(block, COND_AL | OPCODE_STR_REG | Rn(addr_reg) | Rd(src_reg) | Rm(offset_reg) | SHIFT_LSL_IMM(shift)); +void host_arm_STR_REG_LSL(codeblock_t *block, int src_reg, int addr_reg, int offset_reg, int shift) { + codegen_addlong(block, COND_AL | OPCODE_STR_REG | Rn(addr_reg) | Rd(src_reg) | Rm(offset_reg) | SHIFT_LSL_IMM(shift)); } -void host_arm_STRB_IMM(codeblock_t *block, int src_reg, int addr_reg, int offset) -{ - codegen_addlong(block, COND_AL | OPCODE_STRB_IMM | Rn(addr_reg) | Rd(src_reg) | arm_data_offset(offset)); +void host_arm_STRB_IMM(codeblock_t *block, int src_reg, int addr_reg, int offset) { + codegen_addlong(block, COND_AL | OPCODE_STRB_IMM | Rn(addr_reg) | Rd(src_reg) | arm_data_offset(offset)); } -void host_arm_STRB_REG_LSL(codeblock_t *block, int src_reg, int addr_reg, int offset_reg, int shift) -{ - codegen_addlong(block, COND_AL | OPCODE_STRB_REG | Rn(addr_reg) | Rd(src_reg) | Rm(offset_reg) | SHIFT_LSL_IMM(shift)); +void host_arm_STRB_REG_LSL(codeblock_t *block, int src_reg, int addr_reg, int offset_reg, int shift) { + codegen_addlong(block, COND_AL | OPCODE_STRB_REG | Rn(addr_reg) | Rd(src_reg) | Rm(offset_reg) | SHIFT_LSL_IMM(shift)); } -void host_arm_STRH_IMM(codeblock_t *block, int dst_reg, int addr_reg, int offset) -{ - codegen_addlong(block, COND_AL | OPCODE_STRH_IMM | Rn(addr_reg) | Rd(dst_reg) | STRH_IMM(offset)); +void host_arm_STRH_IMM(codeblock_t *block, int dst_reg, int addr_reg, int offset) { + codegen_addlong(block, COND_AL | OPCODE_STRH_IMM | Rn(addr_reg) | Rd(dst_reg) | STRH_IMM(offset)); } -void host_arm_STRH_REG(codeblock_t *block, int src_reg, int addr_reg, int offset_reg) -{ - codegen_addlong(block, COND_AL | OPCODE_STRH_REG | Rn(addr_reg) | Rd(src_reg) | Rm(offset_reg)); +void host_arm_STRH_REG(codeblock_t *block, int src_reg, int addr_reg, int offset_reg) { + codegen_addlong(block, COND_AL | OPCODE_STRH_REG | Rn(addr_reg) | Rd(src_reg) | Rm(offset_reg)); } -void host_arm_SUB_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) -{ - uint32_t arm_imm; +void host_arm_SUB_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) { + uint32_t arm_imm; - if ((int32_t)imm < 0 && imm != 0x80000000) - { - host_arm_ADD_IMM(block, dst_reg, src_reg, -(int32_t)imm); - } - else if (get_arm_imm(imm, &arm_imm)) - { - codegen_addlong(block, COND_AL | OPCODE_SUB_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); - } - else - { - host_arm_MOV_IMM(block, REG_TEMP, imm); - host_arm_SUB_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); - } + if ((int32_t)imm < 0 && imm != 0x80000000) { + host_arm_ADD_IMM(block, dst_reg, src_reg, -(int32_t)imm); + } else if (get_arm_imm(imm, &arm_imm)) { + codegen_addlong(block, COND_AL | OPCODE_SUB_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); + } else { + host_arm_MOV_IMM(block, REG_TEMP, imm); + host_arm_SUB_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); + } } -void host_arm_SUB_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) -{ - codegen_addlong(block, COND_AL | OPCODE_SUB_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); +void host_arm_SUB_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) { + codegen_addlong(block, COND_AL | OPCODE_SUB_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); } -void host_arm_SUB_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) -{ - codegen_addlong(block, COND_AL | OPCODE_SUB_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSR_IMM(shift)); +void host_arm_SUB_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) { + codegen_addlong(block, COND_AL | OPCODE_SUB_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSR_IMM(shift)); } -void host_arm_SXTB(codeblock_t *block, int dst_reg, int src_reg, int rotate) -{ - codegen_addlong(block, OPCODE_SXTB | Rd(dst_reg) | Rm(src_reg) | UXTB_ROTATE(rotate)); +void host_arm_SXTB(codeblock_t *block, int dst_reg, int src_reg, int rotate) { + codegen_addlong(block, OPCODE_SXTB | Rd(dst_reg) | Rm(src_reg) | UXTB_ROTATE(rotate)); } -void host_arm_SXTH(codeblock_t *block, int dst_reg, int src_reg, int rotate) -{ - codegen_addlong(block, OPCODE_SXTH | Rd(dst_reg) | Rm(src_reg) | UXTB_ROTATE(rotate)); +void host_arm_SXTH(codeblock_t *block, int dst_reg, int src_reg, int rotate) { + codegen_addlong(block, OPCODE_SXTH | Rd(dst_reg) | Rm(src_reg) | UXTB_ROTATE(rotate)); } -void host_arm_TST_IMM(codeblock_t *block, int src_reg, uint32_t imm) -{ - uint32_t arm_imm; +void host_arm_TST_IMM(codeblock_t *block, int src_reg, uint32_t imm) { + uint32_t arm_imm; - if (get_arm_imm(imm, &arm_imm)) - { - codegen_addlong(block, COND_AL | OPCODE_TST_IMM | Rn(src_reg) | arm_imm); - } - else - { - host_arm_MOV_IMM(block, REG_TEMP, imm); - host_arm_TST_REG(block, src_reg, REG_TEMP); - } + if (get_arm_imm(imm, &arm_imm)) { + codegen_addlong(block, COND_AL | OPCODE_TST_IMM | Rn(src_reg) | arm_imm); + } else { + host_arm_MOV_IMM(block, REG_TEMP, imm); + host_arm_TST_REG(block, src_reg, REG_TEMP); + } } -void host_arm_TST_REG(codeblock_t *block, int src_reg1, int src_reg2) -{ - codegen_addlong(block, COND_AL | OPCODE_TST_REG | Rn(src_reg1) | Rm(src_reg2)); +void host_arm_TST_REG(codeblock_t *block, int src_reg1, int src_reg2) { + codegen_addlong(block, COND_AL | OPCODE_TST_REG | Rn(src_reg1) | Rm(src_reg2)); } -void host_arm_UADD8(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) -{ - codegen_addlong(block, COND_AL | OPCODE_UADD8 | Rd(dst_reg) | Rn(src_reg_a) | Rm(src_reg_b)); +void host_arm_UADD8(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) { + codegen_addlong(block, COND_AL | OPCODE_UADD8 | Rd(dst_reg) | Rn(src_reg_a) | Rm(src_reg_b)); } -void host_arm_UADD16(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) -{ - codegen_addlong(block, COND_AL | OPCODE_UADD16 | Rd(dst_reg) | Rn(src_reg_a) | Rm(src_reg_b)); +void host_arm_UADD16(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) { + codegen_addlong(block, COND_AL | OPCODE_UADD16 | Rd(dst_reg) | Rn(src_reg_a) | Rm(src_reg_b)); } -void host_arm_USUB8(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) -{ - codegen_addlong(block, COND_AL | OPCODE_USUB8 | Rd(dst_reg) | Rn(src_reg_a) | Rm(src_reg_b)); +void host_arm_USUB8(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) { + codegen_addlong(block, COND_AL | OPCODE_USUB8 | Rd(dst_reg) | Rn(src_reg_a) | Rm(src_reg_b)); } -void host_arm_USUB16(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) -{ - codegen_addlong(block, COND_AL | OPCODE_USUB16 | Rd(dst_reg) | Rn(src_reg_a) | Rm(src_reg_b)); +void host_arm_USUB16(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) { + codegen_addlong(block, COND_AL | OPCODE_USUB16 | Rd(dst_reg) | Rn(src_reg_a) | Rm(src_reg_b)); } -void host_arm_UXTB(codeblock_t *block, int dst_reg, int src_reg, int rotate) -{ - codegen_addlong(block, OPCODE_UXTB | Rd(dst_reg) | Rm(src_reg) | UXTB_ROTATE(rotate)); +void host_arm_UXTB(codeblock_t *block, int dst_reg, int src_reg, int rotate) { + codegen_addlong(block, OPCODE_UXTB | Rd(dst_reg) | Rm(src_reg) | UXTB_ROTATE(rotate)); } -void host_arm_UXTH(codeblock_t *block, int dst_reg, int src_reg, int rotate) -{ - codegen_addlong(block, OPCODE_UXTH | Rd(dst_reg) | Rm(src_reg) | UXTB_ROTATE(rotate)); +void host_arm_UXTH(codeblock_t *block, int dst_reg, int src_reg, int rotate) { + codegen_addlong(block, OPCODE_UXTH | Rd(dst_reg) | Rm(src_reg) | UXTB_ROTATE(rotate)); } -void host_arm_VABS_D(codeblock_t *block, int dest_reg, int src_reg) -{ - codegen_addlong(block, COND_AL | OPCODE_VABS_D | Vd(dest_reg) | Vm(src_reg)); +void host_arm_VABS_D(codeblock_t *block, int dest_reg, int src_reg) { + codegen_addlong(block, COND_AL | OPCODE_VABS_D | Vd(dest_reg) | Vm(src_reg)); } -void host_arm_VADD_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) -{ - codegen_addlong(block, COND_AL | OPCODE_VADD | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +void host_arm_VADD_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { + codegen_addlong(block, COND_AL | OPCODE_VADD | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VADD_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) -{ - codegen_addlong(block, COND_AL | OPCODE_VADD_F32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +void host_arm_VADD_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { + codegen_addlong(block, COND_AL | OPCODE_VADD_F32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VADD_I8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) -{ - codegen_addlong(block, OPCODE_VADD_I8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +void host_arm_VADD_I8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { + codegen_addlong(block, OPCODE_VADD_I8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VADD_I16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) -{ - codegen_addlong(block, OPCODE_VADD_I16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +void host_arm_VADD_I16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { + codegen_addlong(block, OPCODE_VADD_I16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VADD_I32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) -{ - codegen_addlong(block, OPCODE_VADD_I32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +void host_arm_VADD_I32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { + codegen_addlong(block, OPCODE_VADD_I32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VAND_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) -{ - codegen_addlong(block, OPCODE_VAND_D | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +void host_arm_VAND_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { + codegen_addlong(block, OPCODE_VAND_D | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VBIC_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) -{ - codegen_addlong(block, OPCODE_VBIC_D | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +void host_arm_VBIC_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { + codegen_addlong(block, OPCODE_VBIC_D | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VCMP_D(codeblock_t *block, int src_reg_d, int src_reg_m) -{ - codegen_addlong(block, COND_AL | OPCODE_VCMP_D | Rd(src_reg_d) | Rm(src_reg_m)); +void host_arm_VCMP_D(codeblock_t *block, int src_reg_d, int src_reg_m) { + codegen_addlong(block, COND_AL | OPCODE_VCMP_D | Rd(src_reg_d) | Rm(src_reg_m)); } -void host_arm_VCEQ_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) -{ - codegen_addlong(block, OPCODE_VCEQ_F32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +void host_arm_VCEQ_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { + codegen_addlong(block, OPCODE_VCEQ_F32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VCEQ_I8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) -{ - codegen_addlong(block, OPCODE_VCEQ_I8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +void host_arm_VCEQ_I8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { + codegen_addlong(block, OPCODE_VCEQ_I8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VCEQ_I16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) -{ - codegen_addlong(block, OPCODE_VCEQ_I16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +void host_arm_VCEQ_I16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { + codegen_addlong(block, OPCODE_VCEQ_I16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VCEQ_I32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) -{ - codegen_addlong(block, OPCODE_VCEQ_I32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +void host_arm_VCEQ_I32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { + codegen_addlong(block, OPCODE_VCEQ_I32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VCGE_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) -{ - codegen_addlong(block, OPCODE_VCGE_F32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +void host_arm_VCGE_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { + codegen_addlong(block, OPCODE_VCGE_F32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VCGT_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) -{ - codegen_addlong(block, OPCODE_VCGT_F32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +void host_arm_VCGT_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { + codegen_addlong(block, OPCODE_VCGT_F32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VCGT_S8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) -{ - codegen_addlong(block, OPCODE_VCGT_S8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +void host_arm_VCGT_S8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { + codegen_addlong(block, OPCODE_VCGT_S8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VCGT_S16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) -{ - codegen_addlong(block, OPCODE_VCGT_S16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +void host_arm_VCGT_S16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { + codegen_addlong(block, OPCODE_VCGT_S16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VCGT_S32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) -{ - codegen_addlong(block, OPCODE_VCGT_S32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +void host_arm_VCGT_S32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { + codegen_addlong(block, OPCODE_VCGT_S32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VCVT_D_IS(codeblock_t *block, int dest_reg, int src_reg) -{ - codegen_addlong(block, COND_AL | OPCODE_VCVT_D_IS | Vd(dest_reg) | Vm(src_reg)); +void host_arm_VCVT_D_IS(codeblock_t *block, int dest_reg, int src_reg) { + codegen_addlong(block, COND_AL | OPCODE_VCVT_D_IS | Vd(dest_reg) | Vm(src_reg)); } -void host_arm_VCVT_D_S(codeblock_t *block, int dest_reg, int src_reg) -{ - codegen_addlong(block, COND_AL | OPCODE_VCVT_D_S | Vd(dest_reg) | Vm(src_reg)); +void host_arm_VCVT_D_S(codeblock_t *block, int dest_reg, int src_reg) { + codegen_addlong(block, COND_AL | OPCODE_VCVT_D_S | Vd(dest_reg) | Vm(src_reg)); } -void host_arm_VCVT_F32_S32(codeblock_t *block, int dest_reg, int src_reg) -{ - codegen_addlong(block, COND_AL | OPCODE_VCVT_F32_S32 | Vd(dest_reg) | Vm(src_reg)); +void host_arm_VCVT_F32_S32(codeblock_t *block, int dest_reg, int src_reg) { + codegen_addlong(block, COND_AL | OPCODE_VCVT_F32_S32 | Vd(dest_reg) | Vm(src_reg)); } -void host_arm_VCVT_IS_D(codeblock_t *block, int dest_reg, int src_reg) -{ - codegen_addlong(block, COND_AL | OPCODE_VCVT_IS_D | Vd(dest_reg) | Vm(src_reg)); +void host_arm_VCVT_IS_D(codeblock_t *block, int dest_reg, int src_reg) { + codegen_addlong(block, COND_AL | OPCODE_VCVT_IS_D | Vd(dest_reg) | Vm(src_reg)); } -void host_arm_VCVT_S32_F32(codeblock_t *block, int dest_reg, int src_reg) -{ - codegen_addlong(block, COND_AL | OPCODE_VCVT_S32_F32 | Vd(dest_reg) | Vm(src_reg)); +void host_arm_VCVT_S32_F32(codeblock_t *block, int dest_reg, int src_reg) { + codegen_addlong(block, COND_AL | OPCODE_VCVT_S32_F32 | Vd(dest_reg) | Vm(src_reg)); } -void host_arm_VCVT_S_D(codeblock_t *block, int dest_reg, int src_reg) -{ - codegen_addlong(block, COND_AL | OPCODE_VCVT_S_D | Vd(dest_reg) | Vm(src_reg)); +void host_arm_VCVT_S_D(codeblock_t *block, int dest_reg, int src_reg) { + codegen_addlong(block, COND_AL | OPCODE_VCVT_S_D | Vd(dest_reg) | Vm(src_reg)); } -void host_arm_VCVTR_IS_D(codeblock_t *block, int dest_reg, int src_reg) -{ - codegen_addlong(block, COND_AL | OPCODE_VCVTR_IS_D | Vd(dest_reg) | Vm(src_reg)); +void host_arm_VCVTR_IS_D(codeblock_t *block, int dest_reg, int src_reg) { + codegen_addlong(block, COND_AL | OPCODE_VCVTR_IS_D | Vd(dest_reg) | Vm(src_reg)); } -void host_arm_VDIV_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) -{ - codegen_addlong(block, COND_AL | OPCODE_VDIV | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +void host_arm_VDIV_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { + codegen_addlong(block, COND_AL | OPCODE_VDIV | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VDIV_S(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) -{ - codegen_addlong(block, COND_AL | OPCODE_VDIV_S | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +void host_arm_VDIV_S(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { + codegen_addlong(block, COND_AL | OPCODE_VDIV_S | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VDUP_32(codeblock_t *block, int dst_reg, int src_reg_m, int imm) -{ - codegen_addlong(block, COND_AL | OPCODE_VDUP_32 | Rd(dst_reg) | Rm(src_reg_m) | VDUP_32_IMM(imm)); +void host_arm_VDUP_32(codeblock_t *block, int dst_reg, int src_reg_m, int imm) { + codegen_addlong(block, COND_AL | OPCODE_VDUP_32 | Rd(dst_reg) | Rm(src_reg_m) | VDUP_32_IMM(imm)); } -void host_arm_VEOR_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) -{ - codegen_addlong(block, OPCODE_VEOR_D | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +void host_arm_VEOR_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { + codegen_addlong(block, OPCODE_VEOR_D | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VLDR_D(codeblock_t *block, int dest_reg, int base_reg, int offset) -{ - if ((offset > 1020) || (offset & 3)) - fatal("VLDR_D bad offset %i\n", offset); - codegen_addlong(block, COND_AL | OPCODE_VLDR_D | Rd(dest_reg) | Rn(base_reg) | (offset >> 2)); +void host_arm_VLDR_D(codeblock_t *block, int dest_reg, int base_reg, int offset) { + if ((offset > 1020) || (offset & 3)) + fatal("VLDR_D bad offset %i\n", offset); + codegen_addlong(block, COND_AL | OPCODE_VLDR_D | Rd(dest_reg) | Rn(base_reg) | (offset >> 2)); } -void host_arm_VLDR_S(codeblock_t *block, int dest_reg, int base_reg, int offset) -{ - if ((offset > 1020) || (offset & 3)) - fatal("VLDR_S bad offset %i\n", offset); - codegen_addlong(block, COND_AL | OPCODE_VLDR_S | Rd(dest_reg) | Rn(base_reg) | (offset >> 2)); +void host_arm_VLDR_S(codeblock_t *block, int dest_reg, int base_reg, int offset) { + if ((offset > 1020) || (offset & 3)) + fatal("VLDR_S bad offset %i\n", offset); + codegen_addlong(block, COND_AL | OPCODE_VLDR_S | Rd(dest_reg) | Rn(base_reg) | (offset >> 2)); } -void host_arm_VMOV_32_S(codeblock_t *block, int dest_reg, int src_reg) -{ - codegen_addlong(block, COND_AL | OPCODE_VMOV_32_S | Rt(dest_reg) | Vn(src_reg)); +void host_arm_VMOV_32_S(codeblock_t *block, int dest_reg, int src_reg) { + codegen_addlong(block, COND_AL | OPCODE_VMOV_32_S | Rt(dest_reg) | Vn(src_reg)); } -void host_arm_VMOV_64_D(codeblock_t *block, int dest_reg_low, int dest_reg_high, int src_reg) -{ - codegen_addlong(block, COND_AL | OPCODE_VMOV_64_D | Rt(dest_reg_low) | Rt2(dest_reg_high) | Vm(src_reg)); +void host_arm_VMOV_64_D(codeblock_t *block, int dest_reg_low, int dest_reg_high, int src_reg) { + codegen_addlong(block, COND_AL | OPCODE_VMOV_64_D | Rt(dest_reg_low) | Rt2(dest_reg_high) | Vm(src_reg)); } -void host_arm_VMOV_D_64(codeblock_t *block, int dest_reg, int src_reg_low, int src_reg_high) -{ - codegen_addlong(block, COND_AL | OPCODE_VMOV_D_64 | Vm(dest_reg) | Rt(src_reg_low) | Rt2(src_reg_high)); +void host_arm_VMOV_D_64(codeblock_t *block, int dest_reg, int src_reg_low, int src_reg_high) { + codegen_addlong(block, COND_AL | OPCODE_VMOV_D_64 | Vm(dest_reg) | Rt(src_reg_low) | Rt2(src_reg_high)); } -void host_arm_VMOV_S_32(codeblock_t *block, int dest_reg, int src_reg) -{ - codegen_addlong(block, COND_AL | OPCODE_VMOV_S_32 | Vn(dest_reg) | Rt(src_reg)); +void host_arm_VMOV_S_32(codeblock_t *block, int dest_reg, int src_reg) { + codegen_addlong(block, COND_AL | OPCODE_VMOV_S_32 | Vn(dest_reg) | Rt(src_reg)); } -void host_arm_VMOV_D_D(codeblock_t *block, int dest_reg, int src_reg) -{ - codegen_addlong(block, COND_AL | OPCODE_VMOV_D_D | Vd(dest_reg) | Vm(src_reg)); +void host_arm_VMOV_D_D(codeblock_t *block, int dest_reg, int src_reg) { + codegen_addlong(block, COND_AL | OPCODE_VMOV_D_D | Vd(dest_reg) | Vm(src_reg)); } -void host_arm_VMOVN_I32(codeblock_t *block, int dest_reg, int src_reg) -{ - codegen_addlong(block, OPCODE_VMOVN_I32 | Vd(dest_reg) | Vm(src_reg)); +void host_arm_VMOVN_I32(codeblock_t *block, int dest_reg, int src_reg) { + codegen_addlong(block, OPCODE_VMOVN_I32 | Vd(dest_reg) | Vm(src_reg)); } -void host_arm_VMOVN_I64(codeblock_t *block, int dest_reg, int src_reg) -{ - codegen_addlong(block, OPCODE_VMOVN_I64 | Vd(dest_reg) | Vm(src_reg)); +void host_arm_VMOVN_I64(codeblock_t *block, int dest_reg, int src_reg) { + codegen_addlong(block, OPCODE_VMOVN_I64 | Vd(dest_reg) | Vm(src_reg)); } -void host_arm_VMOV_F32_ONE(codeblock_t *block, int dst_reg) -{ - codegen_addlong(block, COND_AL | OPCODE_VMOV_F32_ONE | Rd(dst_reg)); -} -void host_arm_VMSR_FPSCR(codeblock_t *block, int src_reg) -{ - codegen_addlong(block, COND_AL | OPCODE_VMSR_FPSCR | Rd(src_reg)); -} -void host_arm_VMRS_APSR(codeblock_t *block) -{ - codegen_addlong(block, COND_AL | OPCODE_VMRS_APSR); +void host_arm_VMOV_F32_ONE(codeblock_t *block, int dst_reg) { + codegen_addlong(block, COND_AL | OPCODE_VMOV_F32_ONE | Rd(dst_reg)); } +void host_arm_VMSR_FPSCR(codeblock_t *block, int src_reg) { codegen_addlong(block, COND_AL | OPCODE_VMSR_FPSCR | Rd(src_reg)); } +void host_arm_VMRS_APSR(codeblock_t *block) { codegen_addlong(block, COND_AL | OPCODE_VMRS_APSR); } -void host_arm_VMAX_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) -{ - codegen_addlong(block, OPCODE_VMAX_F32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +void host_arm_VMAX_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { + codegen_addlong(block, OPCODE_VMAX_F32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VMIN_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) -{ - codegen_addlong(block, OPCODE_VMIN_F32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +void host_arm_VMIN_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { + codegen_addlong(block, OPCODE_VMIN_F32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VMUL_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) -{ - codegen_addlong(block, COND_AL | OPCODE_VMUL | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +void host_arm_VMUL_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { + codegen_addlong(block, COND_AL | OPCODE_VMUL | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VMUL_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) -{ - codegen_addlong(block, COND_AL | OPCODE_VMUL_F32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +void host_arm_VMUL_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { + codegen_addlong(block, COND_AL | OPCODE_VMUL_F32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VMUL_S16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) -{ - codegen_addlong(block, OPCODE_VMUL_S16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +void host_arm_VMUL_S16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { + codegen_addlong(block, OPCODE_VMUL_S16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VMULL_S16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) -{ - codegen_addlong(block, OPCODE_VMULL_S16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +void host_arm_VMULL_S16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { + codegen_addlong(block, OPCODE_VMULL_S16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VNEG_D(codeblock_t *block, int dest_reg, int src_reg) -{ - codegen_addlong(block, COND_AL | OPCODE_VNEG_D | Vd(dest_reg) | Vm(src_reg)); +void host_arm_VNEG_D(codeblock_t *block, int dest_reg, int src_reg) { + codegen_addlong(block, COND_AL | OPCODE_VNEG_D | Vd(dest_reg) | Vm(src_reg)); } -void host_arm_VORR_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) -{ - codegen_addlong(block, OPCODE_VORR_D | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +void host_arm_VORR_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { + codegen_addlong(block, OPCODE_VORR_D | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VPADDL_S16(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_addlong(block, OPCODE_VPADDL_S16 | Vd(dst_reg) | Vm(src_reg)); +void host_arm_VPADDL_S16(codeblock_t *block, int dst_reg, int src_reg) { + codegen_addlong(block, OPCODE_VPADDL_S16 | Vd(dst_reg) | Vm(src_reg)); } -void host_arm_VPADDL_S32(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_addlong(block, OPCODE_VPADDL_S32 | Vd(dst_reg) | Vm(src_reg)); +void host_arm_VPADDL_S32(codeblock_t *block, int dst_reg, int src_reg) { + codegen_addlong(block, OPCODE_VPADDL_S32 | Vd(dst_reg) | Vm(src_reg)); } -void host_arm_VPADDL_Q_S32(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_addlong(block, OPCODE_VPADDL_Q_S32 | Vd(dst_reg) | Vm(src_reg)); +void host_arm_VPADDL_Q_S32(codeblock_t *block, int dst_reg, int src_reg) { + codegen_addlong(block, OPCODE_VPADDL_Q_S32 | Vd(dst_reg) | Vm(src_reg)); } -void host_arm_VQADD_S8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) -{ - codegen_addlong(block, OPCODE_VQADD_S8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +void host_arm_VQADD_S8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { + codegen_addlong(block, OPCODE_VQADD_S8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +} +void host_arm_VQADD_S16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { + codegen_addlong(block, OPCODE_VQADD_S16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +} +void host_arm_VQADD_U8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { + codegen_addlong(block, OPCODE_VQADD_U8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +} +void host_arm_VQADD_U16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { + codegen_addlong(block, OPCODE_VQADD_U16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VQADD_S16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) -{ - codegen_addlong(block, OPCODE_VQADD_S16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +void host_arm_VQSUB_S8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { + codegen_addlong(block, OPCODE_VQSUB_S8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VQADD_U8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) -{ - codegen_addlong(block, OPCODE_VQADD_U8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +void host_arm_VQSUB_S16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { + codegen_addlong(block, OPCODE_VQSUB_S16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VQADD_U16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) -{ - codegen_addlong(block, OPCODE_VQADD_U16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +void host_arm_VQSUB_U8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { + codegen_addlong(block, OPCODE_VQSUB_U8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VQSUB_S8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) -{ - codegen_addlong(block, OPCODE_VQSUB_S8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +void host_arm_VQSUB_U16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { + codegen_addlong(block, OPCODE_VQSUB_U16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VQSUB_S16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) -{ - codegen_addlong(block, OPCODE_VQSUB_S16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + +void host_arm_VQMOVN_S16(codeblock_t *block, int dst_reg, int src_reg) { + codegen_addlong(block, OPCODE_VQMOVN_S16 | Vd(dst_reg) | Vm(src_reg)); } -void host_arm_VQSUB_U8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) -{ - codegen_addlong(block, OPCODE_VQSUB_U8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +void host_arm_VQMOVN_S32(codeblock_t *block, int dst_reg, int src_reg) { + codegen_addlong(block, OPCODE_VQMOVN_S32 | Vd(dst_reg) | Vm(src_reg)); } -void host_arm_VQSUB_U16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) -{ - codegen_addlong(block, OPCODE_VQSUB_U16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +void host_arm_VQMOVN_U16(codeblock_t *block, int dst_reg, int src_reg) { + codegen_addlong(block, OPCODE_VQMOVN_U16 | Vd(dst_reg) | Vm(src_reg)); } -void host_arm_VQMOVN_S16(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_addlong(block, OPCODE_VQMOVN_S16 | Vd(dst_reg) | Vm(src_reg)); +void host_arm_VSHL_D_IMM_16(codeblock_t *block, int dst_reg, int src_reg, int shift) { + if (shift > 15) + fatal("host_arm_VSHL_D_IMM_16 : shift > 15\n"); + codegen_addlong(block, OPCODE_VSHL_D_IMM_16 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(shift)); +} +void host_arm_VSHL_D_IMM_32(codeblock_t *block, int dst_reg, int src_reg, int shift) { + if (shift > 31) + fatal("host_arm_VSHL_D_IMM_32 : shift > 31\n"); + codegen_addlong(block, OPCODE_VSHL_D_IMM_32 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(shift)); +} +void host_arm_VSHL_D_IMM_64(codeblock_t *block, int dst_reg, int src_reg, int shift) { + if (shift > 63) + fatal("host_arm_VSHL_D_IMM_64 : shift > 63\n"); + codegen_addlong(block, OPCODE_VSHL_D_IMM_64 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(shift)); +} +void host_arm_VSHR_D_S16(codeblock_t *block, int dst_reg, int src_reg, int shift) { + if (shift > 15) + fatal("host_arm_VSHR_SD_IMM_16 : shift > 15\n"); + codegen_addlong(block, OPCODE_VSHR_D_S16 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(16 - shift)); +} +void host_arm_VSHR_D_S32(codeblock_t *block, int dst_reg, int src_reg, int shift) { + if (shift > 31) + fatal("host_arm_VSHR_SD_IMM_32 : shift > 31\n"); + codegen_addlong(block, OPCODE_VSHR_D_S32 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(32 - shift)); } -void host_arm_VQMOVN_S32(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_addlong(block, OPCODE_VQMOVN_S32 | Vd(dst_reg) | Vm(src_reg)); +void host_arm_VSHR_D_S64(codeblock_t *block, int dst_reg, int src_reg, int shift) { + if (shift > 63) + fatal("host_arm_VSHR_SD_IMM_64 : shift > 63\n"); + codegen_addlong(block, OPCODE_VSHR_D_S64 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(64 - shift)); } -void host_arm_VQMOVN_U16(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_addlong(block, OPCODE_VQMOVN_U16 | Vd(dst_reg) | Vm(src_reg)); +void host_arm_VSHR_D_U16(codeblock_t *block, int dst_reg, int src_reg, int shift) { + if (shift > 15) + fatal("host_arm_VSHR_UD_IMM_16 : shift > 15\n"); + codegen_addlong(block, OPCODE_VSHR_D_U16 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(16 - shift)); +} +void host_arm_VSHR_D_U32(codeblock_t *block, int dst_reg, int src_reg, int shift) { + if (shift > 31) + fatal("host_arm_VSHR_UD_IMM_32 : shift > 31\n"); + codegen_addlong(block, OPCODE_VSHR_D_U32 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(32 - shift)); +} +void host_arm_VSHR_D_U64(codeblock_t *block, int dst_reg, int src_reg, int shift) { + if (shift > 63) + fatal("host_arm_VSHR_UD_IMM_64 : shift > 63\n"); + codegen_addlong(block, OPCODE_VSHR_D_U64 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(64 - shift)); +} +void host_arm_VSHRN_32(codeblock_t *block, int dst_reg, int src_reg, int shift) { + if (shift > 16) + fatal("host_arm_VSHRN_32 : shift > 16\n"); + codegen_addlong(block, OPCODE_VSHRN | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM_32(16 - shift)); +} + +void host_arm_VSQRT_D(codeblock_t *block, int dest_reg, int src_reg) { + codegen_addlong(block, COND_AL | OPCODE_VSQRT_D | Vd(dest_reg) | Vm(src_reg)); +} +void host_arm_VSQRT_S(codeblock_t *block, int dest_reg, int src_reg) { + codegen_addlong(block, COND_AL | OPCODE_VSQRT_S | Vd(dest_reg) | Vm(src_reg)); } -void host_arm_VSHL_D_IMM_16(codeblock_t *block, int dst_reg, int src_reg, int shift) -{ - if (shift > 15) - fatal("host_arm_VSHL_D_IMM_16 : shift > 15\n"); - codegen_addlong(block, OPCODE_VSHL_D_IMM_16 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(shift)); +void host_arm_VSTR_D(codeblock_t *block, int src_reg, int base_reg, int offset) { + if ((offset > 1020) || (offset & 3)) + fatal("VSTR_D bad offset %i\n", offset); + codegen_addlong(block, COND_AL | OPCODE_VSTR_D | Rd(src_reg) | Rn(base_reg) | (offset >> 2)); +} +void host_arm_VSTR_S(codeblock_t *block, int src_reg, int base_reg, int offset) { + if ((offset > 1020) || (offset & 3)) + fatal("VSTR_S bad offset %i\n", offset); + codegen_addlong(block, COND_AL | OPCODE_VSTR_S | Rd(src_reg) | Rn(base_reg) | (offset >> 2)); +} +void host_arm_VSUB_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { + codegen_addlong(block, COND_AL | OPCODE_VSUB | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VSHL_D_IMM_32(codeblock_t *block, int dst_reg, int src_reg, int shift) -{ - if (shift > 31) - fatal("host_arm_VSHL_D_IMM_32 : shift > 31\n"); - codegen_addlong(block, OPCODE_VSHL_D_IMM_32 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(shift)); +void host_arm_VSUB_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { + codegen_addlong(block, COND_AL | OPCODE_VSUB_F32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VSHL_D_IMM_64(codeblock_t *block, int dst_reg, int src_reg, int shift) -{ - if (shift > 63) - fatal("host_arm_VSHL_D_IMM_64 : shift > 63\n"); - codegen_addlong(block, OPCODE_VSHL_D_IMM_64 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(shift)); +void host_arm_VSUB_I8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { + codegen_addlong(block, OPCODE_VSUB_I8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VSHR_D_S16(codeblock_t *block, int dst_reg, int src_reg, int shift) -{ - if (shift > 15) - fatal("host_arm_VSHR_SD_IMM_16 : shift > 15\n"); - codegen_addlong(block, OPCODE_VSHR_D_S16 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(16-shift)); +void host_arm_VSUB_I16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { + codegen_addlong(block, OPCODE_VSUB_I16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VSHR_D_S32(codeblock_t *block, int dst_reg, int src_reg, int shift) -{ - if (shift > 31) - fatal("host_arm_VSHR_SD_IMM_32 : shift > 31\n"); - codegen_addlong(block, OPCODE_VSHR_D_S32 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(32-shift)); +void host_arm_VSUB_I32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { + codegen_addlong(block, OPCODE_VSUB_I32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); +} + +void host_arm_VZIP_D8(codeblock_t *block, int d_reg, int m_reg) { + codegen_addlong(block, OPCODE_VZIP_D8 | Vd(d_reg) | Vm(m_reg)); } -void host_arm_VSHR_D_S64(codeblock_t *block, int dst_reg, int src_reg, int shift) -{ - if (shift > 63) - fatal("host_arm_VSHR_SD_IMM_64 : shift > 63\n"); - codegen_addlong(block, OPCODE_VSHR_D_S64 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(64-shift)); +void host_arm_VZIP_D16(codeblock_t *block, int d_reg, int m_reg) { + codegen_addlong(block, OPCODE_VZIP_D16 | Vd(d_reg) | Vm(m_reg)); } -void host_arm_VSHR_D_U16(codeblock_t *block, int dst_reg, int src_reg, int shift) -{ - if (shift > 15) - fatal("host_arm_VSHR_UD_IMM_16 : shift > 15\n"); - codegen_addlong(block, OPCODE_VSHR_D_U16 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(16-shift)); -} -void host_arm_VSHR_D_U32(codeblock_t *block, int dst_reg, int src_reg, int shift) -{ - if (shift > 31) - fatal("host_arm_VSHR_UD_IMM_32 : shift > 31\n"); - codegen_addlong(block, OPCODE_VSHR_D_U32 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(32-shift)); -} -void host_arm_VSHR_D_U64(codeblock_t *block, int dst_reg, int src_reg, int shift) -{ - if (shift > 63) - fatal("host_arm_VSHR_UD_IMM_64 : shift > 63\n"); - codegen_addlong(block, OPCODE_VSHR_D_U64 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(64-shift)); -} -void host_arm_VSHRN_32(codeblock_t *block, int dst_reg, int src_reg, int shift) -{ - if (shift > 16) - fatal("host_arm_VSHRN_32 : shift > 16\n"); - codegen_addlong(block, OPCODE_VSHRN | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM_32(16-shift)); -} - -void host_arm_VSQRT_D(codeblock_t *block, int dest_reg, int src_reg) -{ - codegen_addlong(block, COND_AL | OPCODE_VSQRT_D | Vd(dest_reg) | Vm(src_reg)); -} -void host_arm_VSQRT_S(codeblock_t *block, int dest_reg, int src_reg) -{ - codegen_addlong(block, COND_AL | OPCODE_VSQRT_S | Vd(dest_reg) | Vm(src_reg)); -} - -void host_arm_VSTR_D(codeblock_t *block, int src_reg, int base_reg, int offset) -{ - if ((offset > 1020) || (offset & 3)) - fatal("VSTR_D bad offset %i\n", offset); - codegen_addlong(block, COND_AL | OPCODE_VSTR_D | Rd(src_reg) | Rn(base_reg) | (offset >> 2)); -} -void host_arm_VSTR_S(codeblock_t *block, int src_reg, int base_reg, int offset) -{ - if ((offset > 1020) || (offset & 3)) - fatal("VSTR_S bad offset %i\n", offset); - codegen_addlong(block, COND_AL | OPCODE_VSTR_S | Rd(src_reg) | Rn(base_reg) | (offset >> 2)); -} -void host_arm_VSUB_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) -{ - codegen_addlong(block, COND_AL | OPCODE_VSUB | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); -} -void host_arm_VSUB_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) -{ - codegen_addlong(block, COND_AL | OPCODE_VSUB_F32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); -} -void host_arm_VSUB_I8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) -{ - codegen_addlong(block, OPCODE_VSUB_I8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); -} -void host_arm_VSUB_I16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) -{ - codegen_addlong(block, OPCODE_VSUB_I16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); -} -void host_arm_VSUB_I32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) -{ - codegen_addlong(block, OPCODE_VSUB_I32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); -} - -void host_arm_VZIP_D8(codeblock_t *block, int d_reg, int m_reg) -{ - codegen_addlong(block, OPCODE_VZIP_D8 | Vd(d_reg) | Vm(m_reg)); -} -void host_arm_VZIP_D16(codeblock_t *block, int d_reg, int m_reg) -{ - codegen_addlong(block, OPCODE_VZIP_D16 | Vd(d_reg) | Vm(m_reg)); -} -void host_arm_VZIP_D32(codeblock_t *block, int d_reg, int m_reg) -{ - codegen_addlong(block, OPCODE_VZIP_D32 | Vd(d_reg) | Vm(m_reg)); +void host_arm_VZIP_D32(codeblock_t *block, int d_reg, int m_reg) { + codegen_addlong(block, OPCODE_VZIP_D32 | Vd(d_reg) | Vm(m_reg)); } #endif diff --git a/src/codegen/arm32/codegen_backend_arm_uops.c b/src/codegen/arm32/codegen_backend_arm_uops.c index 8fb3eec3..3cb3c88a 100644 --- a/src/codegen/arm32/codegen_backend_arm_uops.c +++ b/src/codegen/arm32/codegen_backend_arm_uops.c @@ -12,65 +12,54 @@ #include "codegen_backend_arm_ops.h" #include "codegen_ir_defs.h" -static inline int get_arm_imm(uint32_t imm_data, uint32_t *arm_imm) -{ - int shift = 0; -//pclog("get_arm_imm - imm_data=%08x\n", imm_data); - if (!(imm_data & 0xffff)) - { - shift += 16; - imm_data >>= 16; - } - if (!(imm_data & 0xff)) - { - shift += 8; - imm_data >>= 8; - } - if (!(imm_data & 0xf)) - { - shift += 4; - imm_data >>= 4; - } - if (!(imm_data & 0x3)) - { - shift += 2; - imm_data >>= 2; - } - if (imm_data > 0xff) /*Note - should handle rotation round the word*/ - return 0; -//pclog(" imm_data=%02x shift=%i\n", imm_data, shift); - *arm_imm = imm_data | ((((32 - shift) >> 1) & 15) << 8); - return 1; +static inline int get_arm_imm(uint32_t imm_data, uint32_t *arm_imm) { + int shift = 0; + // pclog("get_arm_imm - imm_data=%08x\n", imm_data); + if (!(imm_data & 0xffff)) { + shift += 16; + imm_data >>= 16; + } + if (!(imm_data & 0xff)) { + shift += 8; + imm_data >>= 8; + } + if (!(imm_data & 0xf)) { + shift += 4; + imm_data >>= 4; + } + if (!(imm_data & 0x3)) { + shift += 2; + imm_data >>= 2; + } + if (imm_data > 0xff) /*Note - should handle rotation round the word*/ + return 0; + // pclog(" imm_data=%02x shift=%i\n", imm_data, shift); + *arm_imm = imm_data | ((((32 - shift) >> 1) & 15) << 8); + return 1; } -static inline int in_range(void *addr, void *base) -{ - int diff = (uintptr_t)addr - (uintptr_t)base; +static inline int in_range(void *addr, void *base) { + int diff = (uintptr_t)addr - (uintptr_t)base; - if (diff < -4095 || diff > 4095) - return 0; - return 1; + if (diff < -4095 || diff > 4095) + return 0; + return 1; } -static inline int in_range_h(void *addr, void *base) -{ - int diff = (uintptr_t)addr - (uintptr_t)base; +static inline int in_range_h(void *addr, void *base) { + int diff = (uintptr_t)addr - (uintptr_t)base; - if (diff < 0 || diff > 255) - return 0; - return 1; + if (diff < 0 || diff > 255) + return 0; + return 1; } -void host_arm_call(codeblock_t *block, void *dst_addr) -{ - host_arm_MOV_IMM(block, REG_R3, (uintptr_t)dst_addr); - host_arm_BLX(block, REG_R3); +void host_arm_call(codeblock_t *block, void *dst_addr) { + host_arm_MOV_IMM(block, REG_R3, (uintptr_t)dst_addr); + host_arm_BLX(block, REG_R3); } -void host_arm_nop(codeblock_t *block) -{ - host_arm_MOV_REG_LSL(block, REG_R0, REG_R0, 0); -} +void host_arm_nop(codeblock_t *block) { host_arm_MOV_REG_LSL(block, REG_R0, REG_R0, 0); } #define HOST_REG_GET(reg) (IREG_GET_REG(reg) & 0xf) @@ -81,3420 +70,2771 @@ void host_arm_nop(codeblock_t *block) #define REG_IS_D(size) (size == IREG_SIZE_D) #define REG_IS_Q(size) (size == IREG_SIZE_Q) -static int codegen_ADD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_ADD_REG_LSL(block, dest_reg, src_reg_a, src_reg_b, 0); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm_ADD_REG(block, REG_TEMP, src_reg_a, src_reg_b); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm_ADD_REG(block, REG_TEMP, src_reg_a, src_reg_b); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) - { - host_arm_UXTB(block, REG_TEMP, src_reg_b, 8); - host_arm_UADD8(block, dest_reg, src_reg_a, REG_TEMP); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b)) - { - host_arm_ADD_REG_LSR(block, REG_TEMP, src_reg_a, src_reg_b, 8); - host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) - { - host_arm_UXTB(block, REG_TEMP, src_reg_b, 0); - host_arm_MOV_REG_LSL(block, REG_TEMP, REG_TEMP, 8); - host_arm_UADD8(block, dest_reg, src_reg_a, REG_TEMP); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) - { - host_arm_AND_IMM(block, REG_TEMP, src_reg_b, 0x0000ff00); - host_arm_UADD8(block, dest_reg, src_reg_a, REG_TEMP); - } - else - fatal("ADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_ADD_IMM(codeblock_t *block, uop_t *uop) -{ -// host_arm_ADD_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); -// return 0; - - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm_ADD_IMM(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm_ADD_IMM(block, REG_TEMP, src_reg, uop->imm_data); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm_ADD_IMM(block, REG_TEMP, src_reg, uop->imm_data); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size) && src_reg == dest_reg) - { - host_arm_MOV_IMM(block, REG_TEMP, uop->imm_data << 8); - host_arm_UADD8(block, dest_reg, src_reg, REG_TEMP); - } - else - fatal("ADD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; - -} -static int codegen_ADD_LSHIFT(codeblock_t *block, uop_t *uop) -{ - host_arm_ADD_REG_LSL(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, uop->imm_data); - return 0; -} - -static int codegen_AND(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VAND_D(block, dest_reg, src_reg_a, src_reg_b); - } - else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_AND_REG_LSL(block, dest_reg, src_reg_a, src_reg_b, 0); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b) && dest_reg == src_reg_a) - { - host_arm_MVN_REG_LSL(block, REG_TEMP, src_reg_b, 16); - host_arm_BIC_REG_LSR(block, dest_reg, src_reg_a, REG_TEMP, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) - { - host_arm_MVN_REG_LSL(block, REG_TEMP, src_reg_b, 24); - host_arm_BIC_REG_LSR(block, dest_reg, src_reg_a, REG_TEMP, 24); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) - { - host_arm_MVN_REG_LSL(block, REG_TEMP, src_reg_b, 16); - host_arm_BIC_REG_LSR(block, dest_reg, src_reg_a, REG_TEMP, 24); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) - { - host_arm_MVN_REG_LSL(block, REG_TEMP, src_reg_b, 8); - host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 0x0000ff00); - host_arm_BIC_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) - { - host_arm_MVN_REG_LSL(block, REG_TEMP, src_reg_b, 0); - host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 0x0000ff00); - host_arm_BIC_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm_AND_REG_LSL(block, REG_TEMP, src_reg_a, src_reg_b, 0); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm_AND_REG_LSL(block, REG_TEMP, src_reg_a, src_reg_b, 0); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b)) - { - host_arm_AND_REG_LSR(block, REG_TEMP, src_reg_a, src_reg_b, 8); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm_AND_REG_LSR(block, REG_TEMP, src_reg_b, src_reg_a, 8); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b)) - { - host_arm_AND_REG_LSL(block, REG_TEMP, src_reg_a, src_reg_b, 0); - host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else - fatal("AND %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm_AND_IMM(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size) && dest_reg == src_reg) - { - host_arm_AND_IMM(block, dest_reg, src_reg, uop->imm_data | 0xffff0000); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size) && dest_reg == src_reg) - { - host_arm_AND_IMM(block, dest_reg, src_reg, uop->imm_data | 0xffffff00); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size) && dest_reg == src_reg) - { - host_arm_AND_IMM(block, dest_reg, src_reg, (uop->imm_data << 8) | 0xffff00ff); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm_AND_IMM(block, REG_TEMP, src_reg, uop->imm_data); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm_AND_IMM(block, REG_TEMP, src_reg, uop->imm_data); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_BH(src_size)) - { - host_arm_MOV_REG_LSR(block, REG_TEMP, src_reg, 8); - host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, uop->imm_data); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else - fatal("AND_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_ANDN(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VBIC_D(block, dest_reg, src_reg_b, src_reg_a); - } - else - fatal("ANDN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} - -static int codegen_CALL_FUNC(codeblock_t *block, uop_t *uop) -{ - host_arm_call(block, uop->p); - - return 0; -} - -static int codegen_CALL_FUNC_RESULT(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (!REG_IS_L(dest_size)) - fatal("CALL_FUNC_RESULT %02x\n", uop->dest_reg_a_real); - host_arm_call(block, uop->p); - host_arm_MOV_REG(block, dest_reg, REG_R0); - - return 0; -} - -static int codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop) -{ - host_arm_call(block, uop->p); - host_arm_TST_REG(block, REG_R0, REG_R0); - host_arm_BNE(block, (uintptr_t)codegen_exit_rout); - - return 0; -} - -static int codegen_CMP_IMM_JZ(codeblock_t *block, uop_t *uop) -{ - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(src_size)) - { - host_arm_CMP_IMM(block, src_reg, uop->imm_data); - } - else - fatal("CMP_IMM_JZ %02x\n", uop->src_reg_a_real); - host_arm_BEQ(block, (uintptr_t)uop->p); - - return 0; -} - -static int codegen_CMP_IMM_JNZ_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(src_size)) - { - host_arm_CMP_IMM(block, src_reg, uop->imm_data); - } - else if (REG_IS_W(src_size)) - { - host_arm_UXTH(block, REG_TEMP, src_reg, 0); - host_arm_CMP_IMM(block, REG_TEMP, uop->imm_data); - } - else - fatal("CMP_IMM_JNZ_DEST %02x\n", uop->src_reg_a_real); - - uop->p = host_arm_BNE_(block); - - return 0; -} -static int codegen_CMP_IMM_JZ_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(src_size)) - { - host_arm_CMP_IMM(block, src_reg, uop->imm_data); - } - else if (REG_IS_W(src_size)) - { - host_arm_UXTH(block, REG_TEMP, src_reg, 0); - host_arm_CMP_IMM(block, REG_TEMP, uop->imm_data); - } - else - fatal("CMP_IMM_JZ_DEST %02x\n", uop->src_reg_a_real); - - uop->p = host_arm_BEQ_(block); - - return 0; -} - -static int codegen_CMP_JB(codeblock_t *block, uop_t *uop) -{ - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - uint32_t *jump_p; - - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_CMP_REG(block, src_reg_a, src_reg_b); - } - else - fatal("CMP_JB %02x\n", uop->src_reg_a_real); - - jump_p = host_arm_BCC_(block); - *jump_p |= ((((uintptr_t)uop->p - (uintptr_t)jump_p) - 8) & 0x3fffffc) >> 2; - - return 0; -} -static int codegen_CMP_JNBE(codeblock_t *block, uop_t *uop) -{ - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - uint32_t *jump_p; - - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_CMP_REG(block, src_reg_a, src_reg_b); - } - else - fatal("CMP_JNBE %02x\n", uop->src_reg_a_real); - - jump_p = host_arm_BHI_(block); - *jump_p |= ((((uintptr_t)uop->p - (uintptr_t)jump_p) - 8) & 0x3fffffc) >> 2; - - return 0; -} - -static int codegen_CMP_JNB_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JNB_DEST %02x\n", uop->src_reg_a_real); - - uop->p = host_arm_BCS_(block); - - return 0; -} -static int codegen_CMP_JNBE_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JNBE_DEST %02x\n", uop->src_reg_a_real); - - uop->p = host_arm_BHI_(block); - - return 0; -} -static int codegen_CMP_JNL_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JNL_DEST %02x\n", uop->src_reg_a_real); - - uop->p = host_arm_BGE_(block); - - return 0; -} -static int codegen_CMP_JNLE_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JNLE_DEST %02x\n", uop->src_reg_a_real); - - uop->p = host_arm_BGT_(block); - - return 0; -} -static int codegen_CMP_JNO_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JNO_DEST %02x\n", uop->src_reg_a_real); - - uop->p = host_arm_BVC_(block); - - return 0; -} -static int codegen_CMP_JNZ_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JNZ_DEST %02x\n", uop->src_reg_a_real); - - uop->p = host_arm_BNE_(block); - - return 0; -} -static int codegen_CMP_JB_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JB_DEST %02x\n", uop->src_reg_a_real); - - uop->p = host_arm_BCC_(block); - - return 0; -} -static int codegen_CMP_JBE_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JBE_DEST %02x\n", uop->src_reg_a_real); - - uop->p = host_arm_BLS_(block); - - return 0; -} -static int codegen_CMP_JL_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JL_DEST %02x\n", uop->src_reg_a_real); - - uop->p = host_arm_BLT_(block); - - return 0; -} -static int codegen_CMP_JLE_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JLE_DEST %02x\n", uop->src_reg_a_real); - - uop->p = host_arm_BLE_(block); - - return 0; -} -static int codegen_CMP_JO_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JO_DEST %02x\n", uop->src_reg_a_real); - - uop->p = host_arm_BVS_(block); - - return 0; -} -static int codegen_CMP_JZ_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JZ_DEST %02x\n", uop->src_reg_a_real); - - uop->p = host_arm_BEQ_(block); - - return 0; -} - -static int codegen_FABS(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) - { - host_arm_VABS_D(block, dest_reg, src_reg_a); - } - else - fatal("codegen_FABS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_FCHS(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) - { - host_arm_VNEG_D(block, dest_reg, src_reg_a); - } - else - fatal("codegen_FCHS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_FSQRT(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) - { - host_arm_VSQRT_D(block, dest_reg, src_reg_a); - } - else - fatal("codegen_FSQRT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_FTST(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_W(dest_size) && REG_IS_D(src_size_a)) - { - host_arm_VSUB_D(block, REG_D_TEMP, REG_D_TEMP, REG_D_TEMP); - host_arm_VCMP_D(block, src_reg_a, REG_D_TEMP); - host_arm_MOV_IMM(block, dest_reg, 0); - host_arm_VMRS_APSR(block); - host_arm_ORREQ_IMM(block, dest_reg, dest_reg, C3); - host_arm_ORRCC_IMM(block, dest_reg, dest_reg, C0); - host_arm_ORRVS_IMM(block, dest_reg, dest_reg, C0|C2|C3); - } - else - fatal("codegen_FTST %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} - -static int codegen_FADD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) - { - host_arm_VADD_D(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("codegen_FADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_FCOM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_W(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) - { - host_arm_VCMP_D(block, src_reg_a, src_reg_b); - host_arm_MOV_IMM(block, dest_reg, 0); - host_arm_VMRS_APSR(block); - host_arm_ORREQ_IMM(block, dest_reg, dest_reg, C3); - host_arm_ORRCC_IMM(block, dest_reg, dest_reg, C0); - host_arm_ORRVS_IMM(block, dest_reg, dest_reg, C0|C2|C3); - } - else - fatal("codegen_FCOM %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_FDIV(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) - { - host_arm_VDIV_D(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("codegen_FDIV %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_FMUL(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) - { - host_arm_VMUL_D(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("codegen_FMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_FSUB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) - { - host_arm_VSUB_D(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("codegen_FSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} - -static int codegen_FP_ENTER(codeblock_t *block, uop_t *uop) -{ - uint32_t *branch_ptr; - - if (!in_range(&cr0, &cpu_state)) - fatal("codegen_FP_ENTER - out of range\n"); - - host_arm_LDR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cr0 - (uintptr_t)&cpu_state); - host_arm_TST_IMM(block, REG_TEMP, 0xc); - branch_ptr = host_arm_BEQ_(block); - - host_arm_MOV_IMM(block, REG_TEMP, uop->imm_data); - host_arm_STR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.oldpc - (uintptr_t)&cpu_state); - host_arm_MOV_IMM(block, REG_ARG0, 7); - host_arm_call(block, x86_int); - host_arm_B(block, (uintptr_t)codegen_exit_rout); - - *branch_ptr |= ((((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_ptr) - 8) & 0x3fffffc) >> 2; - - return 0; +static int codegen_ADD(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_ADD_REG_LSL(block, dest_reg, src_reg_a, src_reg_b, 0); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm_ADD_REG(block, REG_TEMP, src_reg_a, src_reg_b); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm_ADD_REG(block, REG_TEMP, src_reg_a, src_reg_b); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) { + host_arm_UXTB(block, REG_TEMP, src_reg_b, 8); + host_arm_UADD8(block, dest_reg, src_reg_a, REG_TEMP); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b)) { + host_arm_ADD_REG_LSR(block, REG_TEMP, src_reg_a, src_reg_b, 8); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) { + host_arm_UXTB(block, REG_TEMP, src_reg_b, 0); + host_arm_MOV_REG_LSL(block, REG_TEMP, REG_TEMP, 8); + host_arm_UADD8(block, dest_reg, src_reg_a, REG_TEMP); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) { + host_arm_AND_IMM(block, REG_TEMP, src_reg_b, 0x0000ff00); + host_arm_UADD8(block, dest_reg, src_reg_a, REG_TEMP); + } else + fatal("ADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_ADD_IMM(codeblock_t *block, uop_t *uop) { + // host_arm_ADD_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); + // return 0; + + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm_ADD_IMM(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm_ADD_IMM(block, REG_TEMP, src_reg, uop->imm_data); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm_ADD_IMM(block, REG_TEMP, src_reg, uop->imm_data); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size) && src_reg == dest_reg) { + host_arm_MOV_IMM(block, REG_TEMP, uop->imm_data << 8); + host_arm_UADD8(block, dest_reg, src_reg, REG_TEMP); + } else + fatal("ADD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_ADD_LSHIFT(codeblock_t *block, uop_t *uop) { + host_arm_ADD_REG_LSL(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, uop->imm_data); + return 0; +} + +static int codegen_AND(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VAND_D(block, dest_reg, src_reg_a, src_reg_b); + } else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_AND_REG_LSL(block, dest_reg, src_reg_a, src_reg_b, 0); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b) && dest_reg == src_reg_a) { + host_arm_MVN_REG_LSL(block, REG_TEMP, src_reg_b, 16); + host_arm_BIC_REG_LSR(block, dest_reg, src_reg_a, REG_TEMP, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) { + host_arm_MVN_REG_LSL(block, REG_TEMP, src_reg_b, 24); + host_arm_BIC_REG_LSR(block, dest_reg, src_reg_a, REG_TEMP, 24); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) { + host_arm_MVN_REG_LSL(block, REG_TEMP, src_reg_b, 16); + host_arm_BIC_REG_LSR(block, dest_reg, src_reg_a, REG_TEMP, 24); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) { + host_arm_MVN_REG_LSL(block, REG_TEMP, src_reg_b, 8); + host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 0x0000ff00); + host_arm_BIC_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) { + host_arm_MVN_REG_LSL(block, REG_TEMP, src_reg_b, 0); + host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 0x0000ff00); + host_arm_BIC_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm_AND_REG_LSL(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm_AND_REG_LSL(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b)) { + host_arm_AND_REG_LSR(block, REG_TEMP, src_reg_a, src_reg_b, 8); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b)) { + host_arm_AND_REG_LSR(block, REG_TEMP, src_reg_b, src_reg_a, 8); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b)) { + host_arm_AND_REG_LSL(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else + fatal("AND %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm_AND_IMM(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size) && dest_reg == src_reg) { + host_arm_AND_IMM(block, dest_reg, src_reg, uop->imm_data | 0xffff0000); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size) && dest_reg == src_reg) { + host_arm_AND_IMM(block, dest_reg, src_reg, uop->imm_data | 0xffffff00); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size) && dest_reg == src_reg) { + host_arm_AND_IMM(block, dest_reg, src_reg, (uop->imm_data << 8) | 0xffff00ff); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm_AND_IMM(block, REG_TEMP, src_reg, uop->imm_data); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm_AND_IMM(block, REG_TEMP, src_reg, uop->imm_data); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_B(dest_size) && REG_IS_BH(src_size)) { + host_arm_MOV_REG_LSR(block, REG_TEMP, src_reg, 8); + host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else + fatal("AND_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_ANDN(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VBIC_D(block, dest_reg, src_reg_b, src_reg_a); + } else + fatal("ANDN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + +static int codegen_CALL_FUNC(codeblock_t *block, uop_t *uop) { + host_arm_call(block, uop->p); + + return 0; +} + +static int codegen_CALL_FUNC_RESULT(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (!REG_IS_L(dest_size)) + fatal("CALL_FUNC_RESULT %02x\n", uop->dest_reg_a_real); + host_arm_call(block, uop->p); + host_arm_MOV_REG(block, dest_reg, REG_R0); + + return 0; +} + +static int codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop) { + host_arm_call(block, uop->p); + host_arm_TST_REG(block, REG_R0, REG_R0); + host_arm_BNE(block, (uintptr_t)codegen_exit_rout); + + return 0; +} + +static int codegen_CMP_IMM_JZ(codeblock_t *block, uop_t *uop) { + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(src_size)) { + host_arm_CMP_IMM(block, src_reg, uop->imm_data); + } else + fatal("CMP_IMM_JZ %02x\n", uop->src_reg_a_real); + host_arm_BEQ(block, (uintptr_t)uop->p); + + return 0; +} + +static int codegen_CMP_IMM_JNZ_DEST(codeblock_t *block, uop_t *uop) { + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(src_size)) { + host_arm_CMP_IMM(block, src_reg, uop->imm_data); + } else if (REG_IS_W(src_size)) { + host_arm_UXTH(block, REG_TEMP, src_reg, 0); + host_arm_CMP_IMM(block, REG_TEMP, uop->imm_data); + } else + fatal("CMP_IMM_JNZ_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BNE_(block); + + return 0; +} +static int codegen_CMP_IMM_JZ_DEST(codeblock_t *block, uop_t *uop) { + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(src_size)) { + host_arm_CMP_IMM(block, src_reg, uop->imm_data); + } else if (REG_IS_W(src_size)) { + host_arm_UXTH(block, REG_TEMP, src_reg, 0); + host_arm_CMP_IMM(block, REG_TEMP, uop->imm_data); + } else + fatal("CMP_IMM_JZ_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BEQ_(block); + + return 0; +} + +static int codegen_CMP_JB(codeblock_t *block, uop_t *uop) { + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + uint32_t *jump_p; + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_CMP_REG(block, src_reg_a, src_reg_b); + } else + fatal("CMP_JB %02x\n", uop->src_reg_a_real); + + jump_p = host_arm_BCC_(block); + *jump_p |= ((((uintptr_t)uop->p - (uintptr_t)jump_p) - 8) & 0x3fffffc) >> 2; + + return 0; +} +static int codegen_CMP_JNBE(codeblock_t *block, uop_t *uop) { + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + uint32_t *jump_p; + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_CMP_REG(block, src_reg_a, src_reg_b); + } else + fatal("CMP_JNBE %02x\n", uop->src_reg_a_real); + + jump_p = host_arm_BHI_(block); + *jump_p |= ((((uintptr_t)uop->p - (uintptr_t)jump_p) - 8) & 0x3fffffc) >> 2; + + return 0; +} + +static int codegen_CMP_JNB_DEST(codeblock_t *block, uop_t *uop) { + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JNB_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BCS_(block); + + return 0; +} +static int codegen_CMP_JNBE_DEST(codeblock_t *block, uop_t *uop) { + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JNBE_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BHI_(block); + + return 0; +} +static int codegen_CMP_JNL_DEST(codeblock_t *block, uop_t *uop) { + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JNL_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BGE_(block); + + return 0; +} +static int codegen_CMP_JNLE_DEST(codeblock_t *block, uop_t *uop) { + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JNLE_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BGT_(block); + + return 0; +} +static int codegen_CMP_JNO_DEST(codeblock_t *block, uop_t *uop) { + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JNO_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BVC_(block); + + return 0; +} +static int codegen_CMP_JNZ_DEST(codeblock_t *block, uop_t *uop) { + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JNZ_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BNE_(block); + + return 0; +} +static int codegen_CMP_JB_DEST(codeblock_t *block, uop_t *uop) { + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JB_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BCC_(block); + + return 0; +} +static int codegen_CMP_JBE_DEST(codeblock_t *block, uop_t *uop) { + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JBE_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BLS_(block); + + return 0; +} +static int codegen_CMP_JL_DEST(codeblock_t *block, uop_t *uop) { + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JL_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BLT_(block); + + return 0; +} +static int codegen_CMP_JLE_DEST(codeblock_t *block, uop_t *uop) { + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JLE_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BLE_(block); + + return 0; +} +static int codegen_CMP_JO_DEST(codeblock_t *block, uop_t *uop) { + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JO_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BVS_(block); + + return 0; +} +static int codegen_CMP_JZ_DEST(codeblock_t *block, uop_t *uop) { + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JZ_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BEQ_(block); + + return 0; +} + +static int codegen_FABS(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) { + host_arm_VABS_D(block, dest_reg, src_reg_a); + } else + fatal("codegen_FABS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_FCHS(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) { + host_arm_VNEG_D(block, dest_reg, src_reg_a); + } else + fatal("codegen_FCHS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_FSQRT(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) { + host_arm_VSQRT_D(block, dest_reg, src_reg_a); + } else + fatal("codegen_FSQRT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_FTST(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_W(dest_size) && REG_IS_D(src_size_a)) { + host_arm_VSUB_D(block, REG_D_TEMP, REG_D_TEMP, REG_D_TEMP); + host_arm_VCMP_D(block, src_reg_a, REG_D_TEMP); + host_arm_MOV_IMM(block, dest_reg, 0); + host_arm_VMRS_APSR(block); + host_arm_ORREQ_IMM(block, dest_reg, dest_reg, C3); + host_arm_ORRCC_IMM(block, dest_reg, dest_reg, C0); + host_arm_ORRVS_IMM(block, dest_reg, dest_reg, C0 | C2 | C3); + } else + fatal("codegen_FTST %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + +static int codegen_FADD(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { + host_arm_VADD_D(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("codegen_FADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_FCOM(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_W(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { + host_arm_VCMP_D(block, src_reg_a, src_reg_b); + host_arm_MOV_IMM(block, dest_reg, 0); + host_arm_VMRS_APSR(block); + host_arm_ORREQ_IMM(block, dest_reg, dest_reg, C3); + host_arm_ORRCC_IMM(block, dest_reg, dest_reg, C0); + host_arm_ORRVS_IMM(block, dest_reg, dest_reg, C0 | C2 | C3); + } else + fatal("codegen_FCOM %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_FDIV(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { + host_arm_VDIV_D(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("codegen_FDIV %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; } -static int codegen_MMX_ENTER(codeblock_t *block, uop_t *uop) -{ - uint32_t *branch_ptr; - - if (!in_range(&cr0, &cpu_state)) - fatal("codegen_MMX_ENTER - out of range\n"); - - host_arm_LDR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cr0 - (uintptr_t)&cpu_state); - host_arm_TST_IMM(block, REG_TEMP, 0xc); - branch_ptr = host_arm_BEQ_(block); - - host_arm_MOV_IMM(block, REG_TEMP, uop->imm_data); - host_arm_STR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.oldpc - (uintptr_t)&cpu_state); - host_arm_MOV_IMM(block, REG_ARG0, 7); - host_arm_call(block, x86_int); - host_arm_B(block, (uintptr_t)codegen_exit_rout); - - *branch_ptr |= ((((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_ptr) - 8) & 0x3fffffc) >> 2; - - host_arm_MOV_IMM(block, REG_TEMP, 0x01010101); - host_arm_STR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.tag[0] - (uintptr_t)&cpu_state); - host_arm_STR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.tag[4] - (uintptr_t)&cpu_state); - host_arm_MOV_IMM(block, REG_TEMP, 0); - host_arm_STR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.TOP - (uintptr_t)&cpu_state); - host_arm_STRB_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.ismmx - (uintptr_t)&cpu_state); - - return 0; -} - -static int codegen_JMP(codeblock_t *block, uop_t *uop) -{ - host_arm_B(block, (uintptr_t)uop->p); - - return 0; -} - -static int codegen_LOAD_FUNC_ARG0(codeblock_t *block, uop_t *uop) -{ - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_W(src_size)) - { - host_arm_UXTH(block, REG_ARG0, src_reg, 0); - } - else - fatal("codegen_LOAD_FUNC_ARG0 %02x\n", uop->src_reg_a_real); - - return 0; -} -static int codegen_LOAD_FUNC_ARG1(codeblock_t *block, uop_t *uop) -{ - fatal("codegen_LOAD_FUNC_ARG1 %02x\n", uop->src_reg_a_real); - return 0; -} -static int codegen_LOAD_FUNC_ARG2(codeblock_t *block, uop_t *uop) -{ - fatal("codegen_LOAD_FUNC_ARG2 %02x\n", uop->src_reg_a_real); - return 0; -} -static int codegen_LOAD_FUNC_ARG3(codeblock_t *block, uop_t *uop) -{ - fatal("codegen_LOAD_FUNC_ARG3 %02x\n", uop->src_reg_a_real); - return 0; -} - -static int codegen_LOAD_FUNC_ARG0_IMM(codeblock_t *block, uop_t *uop) -{ - host_arm_MOV_IMM(block, REG_ARG0, uop->imm_data); - return 0; -} -static int codegen_LOAD_FUNC_ARG1_IMM(codeblock_t *block, uop_t *uop) -{ - host_arm_MOV_IMM(block, REG_ARG1, uop->imm_data); - return 0; -} -static int codegen_LOAD_FUNC_ARG2_IMM(codeblock_t *block, uop_t *uop) -{ - host_arm_MOV_IMM(block, REG_ARG2, uop->imm_data); - return 0; -} -static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop) -{ - host_arm_MOV_IMM(block, REG_ARG3, uop->imm_data); - return 0; -} - -static int codegen_LOAD_SEG(codeblock_t *block, uop_t *uop) -{ - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (!REG_IS_W(src_size)) - fatal("LOAD_SEG %02x %p\n", uop->src_reg_a_real, uop->p); - host_arm_UXTH(block, REG_ARG0, src_reg, 0); - host_arm_MOV_IMM(block, REG_ARG1, (uint32_t)uop->p); - host_arm_call(block, loadseg); - host_arm_TST_REG(block, REG_R0, REG_R0); - host_arm_BNE(block, (uintptr_t)codegen_exit_rout); - - return 0; -} - -static int codegen_MEM_LOAD_ABS(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - host_arm_ADD_IMM(block, REG_R0, seg_reg, uop->imm_data); - if (REG_IS_B(dest_size) || REG_IS_BH(dest_size)) - { - host_arm_BL(block, (uintptr_t)codegen_mem_load_byte); - } - else if (REG_IS_W(dest_size)) - { - host_arm_BL(block, (uintptr_t)codegen_mem_load_word); - } - else if (REG_IS_L(dest_size)) - { - host_arm_BL(block, (uintptr_t)codegen_mem_load_long); - } - else - fatal("MEM_LOAD_ABS - %02x\n", uop->dest_reg_a_real); - host_arm_TST_REG(block, REG_R1, REG_R1); - host_arm_BNE(block, (uintptr_t)codegen_exit_rout); - if (REG_IS_B(dest_size)) - { - host_arm_BFI(block, dest_reg, REG_R0, 0, 8); - } - else if (REG_IS_BH(dest_size)) - { - host_arm_BFI(block, dest_reg, REG_R0, 8, 8); - } - else if (REG_IS_W(dest_size)) - { - host_arm_BFI(block, dest_reg, REG_R0, 0, 16); - } - else if (REG_IS_L(dest_size)) - { - host_arm_MOV_REG(block, dest_reg, REG_R0); - } - - return 0; -} - -static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); - if (uop->imm_data) - host_arm_ADD_IMM(block, REG_R0, REG_R0, uop->imm_data); - if (REG_IS_B(dest_size) || REG_IS_BH(dest_size)) - { - host_arm_BL(block, (uintptr_t)codegen_mem_load_byte); - } - else if (REG_IS_W(dest_size)) - { - host_arm_BL(block, (uintptr_t)codegen_mem_load_word); - } - else if (REG_IS_L(dest_size)) - { - host_arm_BL(block, (uintptr_t)codegen_mem_load_long); - } - else if (REG_IS_Q(dest_size)) - { - host_arm_BL(block, (uintptr_t)codegen_mem_load_quad); - } - else - fatal("MEM_LOAD_REG - %02x\n", uop->dest_reg_a_real); - host_arm_TST_REG(block, REG_R1, REG_R1); - host_arm_BNE(block, (uintptr_t)codegen_exit_rout); - if (REG_IS_B(dest_size)) - { - host_arm_BFI(block, dest_reg, REG_R0, 0, 8); - } - else if (REG_IS_BH(dest_size)) - { - host_arm_BFI(block, dest_reg, REG_R0, 8, 8); - } - else if (REG_IS_W(dest_size)) - { - host_arm_BFI(block, dest_reg, REG_R0, 0, 16); - } - else if (REG_IS_L(dest_size)) - { - host_arm_MOV_REG(block, dest_reg, REG_R0); - } - else if (REG_IS_Q(dest_size)) - { - host_arm_VMOV_D_D(block, dest_reg, REG_D_TEMP); - } - - return 0; -} -static int codegen_MEM_LOAD_SINGLE(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (!REG_IS_D(dest_size)) - fatal("MEM_LOAD_SINGLE - %02x\n", uop->dest_reg_a_real); - - host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); - if (uop->imm_data) - host_arm_ADD_IMM(block, REG_R0, REG_R0, uop->imm_data); - host_arm_BL(block, (uintptr_t)codegen_mem_load_single); - host_arm_TST_REG(block, REG_R1, REG_R1); - host_arm_BNE(block, (uintptr_t)codegen_exit_rout); - host_arm_VCVT_D_S(block, dest_reg, REG_D_TEMP); - - return 0; -} -static int codegen_MEM_LOAD_DOUBLE(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (!REG_IS_D(dest_size)) - fatal("MEM_LOAD_DOUBLE - %02x\n", uop->dest_reg_a_real); - - host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); - if (uop->imm_data) - host_arm_ADD_IMM(block, REG_R0, REG_R0, uop->imm_data); - host_arm_BL(block, (uintptr_t)codegen_mem_load_double); - host_arm_TST_REG(block, REG_R1, REG_R1); - host_arm_BNE(block, (uintptr_t)codegen_exit_rout); - host_arm_VMOV_D_D(block, dest_reg, REG_D_TEMP); - - return 0; -} - -static int codegen_MEM_STORE_ABS(codeblock_t *block, uop_t *uop) -{ - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_b_real); - int src_size = IREG_GET_SIZE(uop->src_reg_b_real); - - host_arm_ADD_IMM(block, REG_R0, seg_reg, uop->imm_data); - if (REG_IS_B(src_size)) - { - host_arm_MOV_REG(block, REG_R1, src_reg); - host_arm_BL(block, (uintptr_t)codegen_mem_store_byte); - } - else if (REG_IS_W(src_size)) - { - host_arm_MOV_REG(block, REG_R1, src_reg); - host_arm_BL(block, (uintptr_t)codegen_mem_store_word); - } - else if (REG_IS_L(src_size)) - { - host_arm_MOV_REG(block, REG_R1, src_reg); - host_arm_BL(block, (uintptr_t)codegen_mem_store_long); - } - else - fatal("MEM_STORE_ABS - %02x\n", uop->src_reg_b_real); - host_arm_TST_REG(block, REG_R1, REG_R1); - host_arm_BNE(block, (uintptr_t)codegen_exit_rout); - - return 0; -} - -static int codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop) -{ - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); - int src_size = IREG_GET_SIZE(uop->src_reg_c_real); - - host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); - if (uop->imm_data) - host_arm_ADD_IMM(block, REG_R0, REG_R0, uop->imm_data); - if (REG_IS_B(src_size)) - { - host_arm_MOV_REG(block, REG_R1, src_reg); - host_arm_BL(block, (uintptr_t)codegen_mem_store_byte); - } - else if (REG_IS_BH(src_size)) - { - host_arm_MOV_REG_LSR(block, REG_R1, src_reg, 8); - host_arm_BL(block, (uintptr_t)codegen_mem_store_byte); - } - else if (REG_IS_W(src_size)) - { - host_arm_MOV_REG(block, REG_R1, src_reg); - host_arm_BL(block, (uintptr_t)codegen_mem_store_word); - } - else if (REG_IS_L(src_size)) - { - host_arm_MOV_REG(block, REG_R1, src_reg); - host_arm_BL(block, (uintptr_t)codegen_mem_store_long); - } - else if (REG_IS_Q(src_size)) - { - host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg); - host_arm_BL(block, (uintptr_t)codegen_mem_store_quad); - } - else - fatal("MEM_STORE_REG - %02x\n", uop->src_reg_c_real); - host_arm_TST_REG(block, REG_R1, REG_R1); - host_arm_BNE(block, (uintptr_t)codegen_exit_rout); - - return 0; -} - -static int codegen_MEM_STORE_IMM_8(codeblock_t *block, uop_t *uop) -{ - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - - host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); - host_arm_MOV_IMM(block, REG_R1, uop->imm_data); - host_arm_BL(block, (uintptr_t)codegen_mem_store_byte); - host_arm_TST_REG(block, REG_R1, REG_R1); - host_arm_BNE(block, (uintptr_t)codegen_exit_rout); - - return 0; -} -static int codegen_MEM_STORE_IMM_16(codeblock_t *block, uop_t *uop) -{ - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - - host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); - host_arm_MOV_IMM(block, REG_R1, uop->imm_data); - host_arm_BL(block, (uintptr_t)codegen_mem_store_word); - host_arm_TST_REG(block, REG_R1, REG_R1); - host_arm_BNE(block, (uintptr_t)codegen_exit_rout); - - return 0; -} -static int codegen_MEM_STORE_IMM_32(codeblock_t *block, uop_t *uop) -{ - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - - host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); - host_arm_MOV_IMM(block, REG_R1, uop->imm_data); - host_arm_BL(block, (uintptr_t)codegen_mem_store_long); - host_arm_TST_REG(block, REG_R1, REG_R1); - host_arm_BNE(block, (uintptr_t)codegen_exit_rout); - - return 0; -} -static int codegen_MEM_STORE_SINGLE(codeblock_t *block, uop_t *uop) -{ - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); - int src_size = IREG_GET_SIZE(uop->src_reg_c_real); - - if (!REG_IS_D(src_size)) - fatal("MEM_STORE_REG - %02x\n", uop->dest_reg_a_real); - - host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); - if (uop->imm_data) - host_arm_ADD_IMM(block, REG_R0, REG_R0, uop->imm_data); - host_arm_VCVT_S_D(block, REG_D_TEMP, src_reg); - host_arm_BL(block, (uintptr_t)codegen_mem_store_single); - host_arm_TST_REG(block, REG_R1, REG_R1); - host_arm_BNE(block, (uintptr_t)codegen_exit_rout); - - return 0; -} -static int codegen_MEM_STORE_DOUBLE(codeblock_t *block, uop_t *uop) -{ - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); - int src_size = IREG_GET_SIZE(uop->src_reg_c_real); - - if (!REG_IS_D(src_size)) - fatal("MEM_STORE_REG - %02x\n", uop->dest_reg_a_real); - - host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); - if (uop->imm_data) - host_arm_ADD_IMM(block, REG_R0, REG_R0, uop->imm_data); - host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg); - host_arm_BL(block, (uintptr_t)codegen_mem_store_double); - host_arm_TST_REG(block, REG_R1, REG_R1); - host_arm_BNE(block, (uintptr_t)codegen_exit_rout); - - return 0; -} - -static int codegen_MOV(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm_MOV_REG_LSL(block, dest_reg, src_reg, 0); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm_BFI(block, dest_reg, src_reg, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm_BFI(block, dest_reg, src_reg, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_B(src_size)) - { - host_arm_BFI(block, dest_reg, src_reg, 8, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_BH(src_size)) - { - host_arm_MOV_REG_LSR(block, REG_TEMP, src_reg, 8); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm_MOV_REG_LSR(block, REG_TEMP, src_reg, 8); - host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else if (REG_IS_D(dest_size) && REG_IS_D(src_size)) - { - host_arm_VMOV_D_D(block, dest_reg, src_reg); - } - else if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - host_arm_VMOV_D_D(block, dest_reg, src_reg); - } - else - fatal("MOV %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} - -static int codegen_MOV_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_L(dest_size)) - { - host_arm_MOV_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size)) - { - host_arm_MOVW_IMM(block, REG_TEMP, uop->imm_data); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size)) - { - host_arm_AND_IMM(block, dest_reg, dest_reg, ~0x000000ff); - host_arm_ORR_IMM(block, dest_reg, dest_reg, uop->imm_data); - } - else if (REG_IS_BH(dest_size)) - { - host_arm_AND_IMM(block, dest_reg, dest_reg, ~0x0000ff00); - host_arm_ORR_IMM(block, dest_reg, dest_reg, uop->imm_data << 8); - } - else - fatal("MOV_IMM %02x\n", uop->dest_reg_a_real); - - return 0; -} -static int codegen_MOV_PTR(codeblock_t *block, uop_t *uop) -{ - host_arm_MOV_IMM(block, uop->dest_reg_a_real, (uintptr_t)uop->p); - - return 0; -} - -static int codegen_MOVSX(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_B(src_size)) - { - host_arm_SXTB(block, dest_reg, src_reg, 0); - } - else if (REG_IS_L(dest_size) && REG_IS_BH(src_size)) - { - host_arm_SXTB(block, dest_reg, src_reg, 8); - } - else if (REG_IS_L(dest_size) && REG_IS_W(src_size)) - { - host_arm_SXTH(block, dest_reg, src_reg, 0); - } - else if (REG_IS_W(dest_size) && REG_IS_B(src_size)) - { - host_arm_SXTB(block, REG_TEMP, src_reg, 0); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_W(dest_size) && REG_IS_BH(src_size)) - { - host_arm_SXTB(block, REG_TEMP, src_reg, 8); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else - fatal("MOVSX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_MOVZX(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_L(src_size)) - { - host_arm_MOV_IMM(block, REG_TEMP, 0); - host_arm_VMOV_D_64(block, dest_reg, src_reg, REG_TEMP); - } - else if (REG_IS_L(dest_size) && REG_IS_Q(src_size)) - { - host_arm_VMOV_32_S(block, dest_reg, src_reg); - } - else if (REG_IS_L(dest_size) && REG_IS_B(src_size)) - { - host_arm_UXTB(block, dest_reg, src_reg, 0); - } - else if (REG_IS_L(dest_size) && REG_IS_BH(src_size)) - { - host_arm_UXTB(block, dest_reg, src_reg, 8); - } - else if (REG_IS_L(dest_size) && REG_IS_W(src_size)) - { - host_arm_UXTH(block, dest_reg, src_reg, 0); - } - else if (REG_IS_W(dest_size) && REG_IS_B(src_size)) - { - if (src_reg == dest_reg) - host_arm_BIC_IMM(block, dest_reg, dest_reg, 0xff00); - else - { - host_arm_UXTB(block, REG_TEMP, src_reg, 0); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - } - else if (REG_IS_W(dest_size) && REG_IS_BH(src_size)) - { - host_arm_MOV_REG_LSR(block, REG_TEMP, src_reg, 8); - host_arm_BIC_IMM(block, dest_reg, dest_reg, 0xff00); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else - fatal("MOVZX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static double int64_to_double(int64_t a) -{ - return (double)a; -} -static int codegen_MOV_DOUBLE_INT(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_D(dest_size) && REG_IS_L(src_size)) - { - host_arm_VMOV_S_32(block, REG_D_TEMP, src_reg); - host_arm_VCVT_D_IS(block, dest_reg, REG_D_TEMP); - } - else if (REG_IS_D(dest_size) && REG_IS_W(src_size)) - { - host_arm_SXTH(block, REG_TEMP, src_reg, 0); - host_arm_VMOV_S_32(block, REG_D_TEMP, REG_TEMP); - host_arm_VCVT_D_IS(block, dest_reg, REG_D_TEMP); - } - else if (REG_IS_D(dest_size) && REG_IS_Q(src_size)) - { - /*ARMv7 has no instructions to convert a 64-bit integer to a double. - For simplicity, call a C function and let the compiler do it.*/ - host_arm_VMOV_64_D(block, REG_R0, REG_R1, src_reg); - host_arm_BL(block, (uintptr_t)int64_to_double); /*Input - R0/R1, Output - D0*/ - host_arm_VMOV_D_D(block, dest_reg, REG_D0); - } - else - fatal("MOV_DOUBLE_INT %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_MOV_INT_DOUBLE(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_D(src_size)) - { - host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg); - host_arm_BL(block, (uintptr_t)codegen_fp_round); - host_arm_VMOV_32_S(block, dest_reg, REG_D_TEMP); - } - else if (REG_IS_W(dest_size) && REG_IS_D(src_size)) - { - host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg); - host_arm_BL(block, (uintptr_t)codegen_fp_round); - host_arm_VMOV_32_S(block, REG_TEMP, REG_D_TEMP); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else - fatal("MOV_INT_DOUBLE %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int64_t x87_fround64(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 int codegen_MOV_INT_DOUBLE_64(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), src_64_reg = HOST_REG_GET(uop->src_reg_b_real), tag_reg = HOST_REG_GET(uop->src_reg_c_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real), src_64_size = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_D(src_size) && REG_IS_Q(src_64_size)) - { - uint32_t *branch_offset; - - /*If TAG_UINT64 is set then the source is MM[]. Otherwise it is a double in ST()*/ - host_arm_VMOV_D_D(block, dest_reg, src_64_reg); - host_arm_TST_IMM(block, tag_reg, TAG_UINT64); - branch_offset = host_arm_BNE_(block); - - /*VFP/NEON has no instructions to convert a float to 64-bit integer, - so call out to C.*/ - host_arm_VMOV_D_D(block, REG_D0, src_reg); - host_arm_call(block, x87_fround64); - host_arm_VMOV_D_64(block, REG_D_TEMP, REG_R0, REG_R1); - - *branch_offset |= ((((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 8) & 0x3fffffc) >> 2; - } - else - fatal("MOV_INT_DOUBLE_64 %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_MOV_REG_PTR(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - host_arm_MOV_IMM(block, REG_TEMP, (uintptr_t)uop->p); - if (REG_IS_L(dest_size)) - { - host_arm_LDR_IMM(block, dest_reg, REG_TEMP, 0); - } - else - fatal("MOV_REG_PTR %02x\n", uop->dest_reg_a_real); - - return 0; -} -static int codegen_MOVZX_REG_PTR_8(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - host_arm_MOV_IMM(block, REG_TEMP, (uintptr_t)uop->p); - if (REG_IS_L(dest_size)) - { - host_arm_LDRB_IMM(block, dest_reg, REG_TEMP, 0); - } - else if (REG_IS_W(dest_size)) - { - host_arm_LDRB_IMM(block, REG_TEMP, REG_TEMP, 0); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size)) - { - host_arm_LDRB_IMM(block, REG_TEMP, REG_TEMP, 0); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else - fatal("MOVZX_REG_PTR_8 %02x\n", uop->dest_reg_a_real); - - return 0; -} -static int codegen_MOVZX_REG_PTR_16(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - host_arm_MOV_IMM(block, REG_TEMP, (uintptr_t)uop->p); - if (REG_IS_L(dest_size)) - { - host_arm_LDRH_IMM(block, dest_reg, REG_TEMP, 0); - } - else if (REG_IS_W(dest_size)) - { - host_arm_LDRH_IMM(block, REG_TEMP, REG_TEMP, 0); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else - fatal("MOVZX_REG_PTR_16 %02x\n", uop->dest_reg_a_real); - - return 0; -} - -static int codegen_NOP(codeblock_t *block, uop_t *uop) -{ - return 0; -} - -static int codegen_OR(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VORR_D(block, dest_reg, src_reg_a, src_reg_b); - } - else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_ORR_REG_LSL(block, dest_reg, src_reg_a, src_reg_b, 0); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm_ORR_REG_LSL(block, REG_TEMP, src_reg_a, src_reg_b, 0); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) - { - host_arm_UXTB(block, REG_TEMP, src_reg_b, 0); - host_arm_ORR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) - { - host_arm_UXTB(block, REG_TEMP, src_reg_b, 8); - host_arm_ORR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) - { - host_arm_UXTB(block, REG_TEMP, src_reg_b, 0); - host_arm_ORR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) - { - host_arm_UXTB(block, REG_TEMP, src_reg_b, 8); - host_arm_ORR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 8); - } - else - fatal("OR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_OR_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm_ORR_IMM(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size) && dest_reg == src_reg) - { - host_arm_ORR_IMM(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size) && dest_reg == src_reg) - { - host_arm_ORR_IMM(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size) && dest_reg == src_reg) - { - host_arm_ORR_IMM(block, dest_reg, src_reg, uop->imm_data << 8); - } - else - fatal("OR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} - -static int codegen_PACKSSWB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VMOV_D_D(block, REG_Q_TEMP, src_reg_a); - host_arm_VMOV_D_D(block, REG_Q_TEMP_2, src_reg_b); - host_arm_VQMOVN_S16(block, dest_reg, REG_Q_TEMP); - host_arm_VQMOVN_S16(block, REG_D_TEMP, REG_Q_TEMP_2); - host_arm_VZIP_D32(block, dest_reg, REG_D_TEMP); - } - else - fatal("PACKSSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PACKSSDW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VMOV_D_D(block, REG_Q_TEMP, src_reg_a); - host_arm_VMOV_D_D(block, REG_Q_TEMP_2, src_reg_b); - host_arm_VQMOVN_S32(block, dest_reg, REG_Q_TEMP); - host_arm_VQMOVN_S32(block, REG_D_TEMP, REG_Q_TEMP_2); - host_arm_VZIP_D32(block, dest_reg, REG_D_TEMP); - } - else - fatal("PACKSSDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PACKUSWB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VMOV_D_D(block, REG_Q_TEMP, src_reg_a); - host_arm_VMOV_D_D(block, REG_Q_TEMP_2, src_reg_b); - host_arm_VQMOVN_U16(block, dest_reg, REG_Q_TEMP); - host_arm_VQMOVN_U16(block, REG_D_TEMP, REG_Q_TEMP_2); - host_arm_VZIP_D32(block, dest_reg, REG_D_TEMP); - } - else - fatal("PACKUSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} - -static int codegen_PADDB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VADD_I8(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PADDB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PADDW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VADD_I16(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PADDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PADDD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VADD_I32(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PADDD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PADDSB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VQADD_S8(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PADDSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PADDSW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VQADD_S16(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PADDSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PADDUSB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VQADD_U8(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PADDUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PADDUSW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VQADD_U16(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PADDUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} - -static int codegen_PCMPEQB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VCEQ_I8(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PCMPEQB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PCMPEQW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VCEQ_I16(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PCMPEQW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PCMPEQD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VCEQ_I32(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PCMPEQD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PCMPGTB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VCGT_S8(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PCMPGTB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PCMPGTW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VCGT_S16(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PCMPGTW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PCMPGTD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VCGT_S32(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PCMPGTD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} - -static int codegen_PF2ID(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) - { - host_arm_VCVT_S32_F32(block, dest_reg, src_reg_a); - } - else - fatal("PF2ID %02x %02x\n", uop->dest_reg_a_real); - - return 0; -} -static int codegen_PFADD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VADD_F32(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PFADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PFCMPEQ(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VCEQ_F32(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PFCMPEQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PFCMPGE(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VCGE_F32(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PFCMPGE %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PFCMPGT(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VCGT_F32(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PFCMPGT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PFMAX(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VMAX_F32(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PFMAX %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PFMIN(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VMIN_F32(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PFMIN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PFMUL(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VMUL_F32(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PFMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PFRCP(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) - { - /*TODO: This could be improved (use VRECPE/VRECPS)*/ - host_arm_VMOV_F32_ONE(block, REG_D_TEMP); - host_arm_VDIV_S(block, dest_reg, REG_D_TEMP, src_reg_a); - host_arm_VDUP_32(block, dest_reg, dest_reg, 0); - } - else - fatal("PFRCP %02x %02x\n", uop->dest_reg_a_real); - - return 0; -} -static int codegen_PFRSQRT(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) - { - /*TODO: This could be improved (use VRSQRTE/VRSQRTS)*/ - host_arm_VSQRT_S(block, REG_D_TEMP, src_reg_a); - host_arm_VMOV_F32_ONE(block, REG_D_TEMP); - host_arm_VDIV_S(block, dest_reg, dest_reg, REG_D_TEMP); - host_arm_VDUP_32(block, dest_reg, dest_reg, 0); - } - else - fatal("PFRSQRT %02x %02x\n", uop->dest_reg_a_real); - - return 0; -} -static int codegen_PFSUB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VSUB_F32(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PFSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PI2FD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) - { - host_arm_VCVT_F32_S32(block, dest_reg, src_reg_a); - } - else - fatal("PI2FD %02x %02x\n", uop->dest_reg_a_real); - - return 0; -} - -static int codegen_PMADDWD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VMULL_S16(block, REG_Q_TEMP, src_reg_a, src_reg_b); - host_arm_VPADDL_Q_S32(block, REG_Q_TEMP, REG_Q_TEMP); - host_arm_VMOVN_I64(block, dest_reg, REG_Q_TEMP); - } - else - fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PMULHW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VMULL_S16(block, REG_Q_TEMP, src_reg_a, src_reg_b); - host_arm_VSHRN_32(block, dest_reg, REG_Q_TEMP, 16); - } - else - fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PMULLW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VMUL_S16(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PMULLW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} - -static int codegen_PSLLW_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - if (uop->imm_data == 0) - host_arm_VMOV_D_D(block, dest_reg, src_reg); - else if (uop->imm_data > 15) - host_arm_VEOR_D(block, dest_reg, dest_reg, dest_reg); - else - host_arm_VSHL_D_IMM_16(block, dest_reg, src_reg, uop->imm_data); - } - else - fatal("PSLLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_PSLLD_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - if (uop->imm_data == 0) - host_arm_VMOV_D_D(block, dest_reg, src_reg); - else if (uop->imm_data > 31) - host_arm_VEOR_D(block, dest_reg, dest_reg, dest_reg); - else - host_arm_VSHL_D_IMM_32(block, dest_reg, src_reg, uop->imm_data); - } - else - fatal("PSLLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_PSLLQ_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - if (uop->imm_data == 0) - host_arm_VMOV_D_D(block, dest_reg, src_reg); - else if (uop->imm_data > 63) - host_arm_VEOR_D(block, dest_reg, dest_reg, dest_reg); - else - host_arm_VSHL_D_IMM_64(block, dest_reg, src_reg, uop->imm_data); - } - else - fatal("PSLLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_PSRAW_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - if (uop->imm_data == 0) - host_arm_VMOV_D_D(block, dest_reg, src_reg); - else if (uop->imm_data > 15) - host_arm_VSHR_D_S16(block, dest_reg, src_reg, 15); - else - host_arm_VSHR_D_S16(block, dest_reg, src_reg, uop->imm_data); - } - else - fatal("PSRAW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_PSRAD_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - if (uop->imm_data == 0) - host_arm_VMOV_D_D(block, dest_reg, src_reg); - else if (uop->imm_data > 31) - host_arm_VSHR_D_S32(block, dest_reg, src_reg, 31); - else - host_arm_VSHR_D_S32(block, dest_reg, src_reg, uop->imm_data); - } - else - fatal("PSRAD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_PSRAQ_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - if (uop->imm_data == 0) - host_arm_VMOV_D_D(block, dest_reg, src_reg); - else if (uop->imm_data > 63) - host_arm_VSHR_D_S64(block, dest_reg, src_reg, 63); - else - host_arm_VSHR_D_S64(block, dest_reg, src_reg, uop->imm_data); - } - else - fatal("PSRAQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_PSRLW_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - if (uop->imm_data == 0) - host_arm_VMOV_D_D(block, dest_reg, src_reg); - else if (uop->imm_data > 15) - host_arm_VEOR_D(block, dest_reg, dest_reg, dest_reg); - else - host_arm_VSHR_D_U16(block, dest_reg, src_reg, uop->imm_data); - } - else - fatal("PSRLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_PSRLD_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - if (uop->imm_data == 0) - host_arm_VMOV_D_D(block, dest_reg, src_reg); - else if (uop->imm_data > 31) - host_arm_VEOR_D(block, dest_reg, dest_reg, dest_reg); - else - host_arm_VSHR_D_U32(block, dest_reg, src_reg, uop->imm_data); - } - else - fatal("PSRLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_PSRLQ_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - if (uop->imm_data == 0) - host_arm_VMOV_D_D(block, dest_reg, src_reg); - else if (uop->imm_data > 63) - host_arm_VEOR_D(block, dest_reg, dest_reg, dest_reg); - else - host_arm_VSHR_D_U64(block, dest_reg, src_reg, uop->imm_data); - } - else - fatal("PSRLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} - -static int codegen_PSUBB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VSUB_I8(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PSUBB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PSUBW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VSUB_I16(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PSUBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PSUBD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VSUB_I32(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PSUBD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PSUBSB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VQSUB_S8(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PSUBSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PSUBSW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VQSUB_S16(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PSUBSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PSUBUSB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VQSUB_U8(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PSUBUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PSUBUSW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VQSUB_U16(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PSUBUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} - -static int codegen_PUNPCKHBW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg_b); - if (dest_reg != src_reg_a) - host_arm_VMOV_D_D(block, dest_reg, src_reg_a); - host_arm_VZIP_D8(block, dest_reg, REG_D_TEMP); - host_arm_VMOV_D_D(block, dest_reg, REG_D_TEMP); - } - else - fatal("PUNPCKHBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PUNPCKHWD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg_b); - if (dest_reg != src_reg_a) - host_arm_VMOV_D_D(block, dest_reg, src_reg_a); - host_arm_VZIP_D16(block, dest_reg, REG_D_TEMP); - host_arm_VMOV_D_D(block, dest_reg, REG_D_TEMP); - } - else - fatal("PUNPCKHWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PUNPCKHDQ(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg_b); - if (dest_reg != src_reg_a) - host_arm_VMOV_D_D(block, dest_reg, src_reg_a); - host_arm_VZIP_D32(block, dest_reg, REG_D_TEMP); - host_arm_VMOV_D_D(block, dest_reg, REG_D_TEMP); - } - else - fatal("PUNPCKHDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PUNPCKLBW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg_b); - if (dest_reg != src_reg_a) - host_arm_VMOV_D_D(block, dest_reg, src_reg_a); - host_arm_VZIP_D8(block, dest_reg, REG_D_TEMP); - } - else - fatal("PUNPCKLBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PUNPCKLWD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg_b); - if (dest_reg != src_reg_a) - host_arm_VMOV_D_D(block, dest_reg, src_reg_a); - host_arm_VZIP_D16(block, dest_reg, REG_D_TEMP); - } - else - fatal("PUNPCKLWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PUNPCKLDQ(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg_b); - if (dest_reg != src_reg_a) - host_arm_VMOV_D_D(block, dest_reg, src_reg_a); - host_arm_VZIP_D32(block, dest_reg, REG_D_TEMP); - } - else - fatal("PUNPCKLDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} - -static int codegen_ROL(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm_RSB_IMM(block, REG_TEMP2, shift_reg, 32); - host_arm_MOV_REG_ROR_REG(block, dest_reg, src_reg, REG_TEMP2); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm_UXTH(block, REG_TEMP, src_reg, 0); - host_arm_RSB_IMM(block, REG_TEMP2, shift_reg, 16); - host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 16); - host_arm_MOV_REG_ROR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP2); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm_RSB_IMM(block, REG_TEMP2, shift_reg, 8); - host_arm_UXTB(block, REG_TEMP, src_reg, 0); - host_arm_AND_IMM(block, REG_TEMP2, REG_TEMP2, 7); - host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); - host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP2); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm_RSB_IMM(block, REG_TEMP2, shift_reg, 8); - host_arm_UXTB(block, REG_TEMP, src_reg, 8); - host_arm_AND_IMM(block, REG_TEMP2, REG_TEMP2, 7); - host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); - host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP2); - host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("ROL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_ROL_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (!(uop->imm_data & 31)) - { - if (src_reg != dest_reg) - host_arm_MOV_REG(block, dest_reg, src_reg); - } - else - { - host_arm_MOV_REG_ROR(block, dest_reg, src_reg, 32 - (uop->imm_data & 31)); - } - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if ((uop->imm_data & 15) == 0) - { - if (src_reg != dest_reg) - host_arm_BFI(block, dest_reg, src_reg, 0, 16); - } - else - { - host_arm_UXTH(block, REG_TEMP, src_reg, 0); - host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 16); - host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 16-(uop->imm_data & 15)); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if ((uop->imm_data & 7) == 0) - { - if (src_reg != dest_reg) - host_arm_BFI(block, dest_reg, src_reg, 0, 8); - } - else - { - host_arm_UXTB(block, REG_TEMP, src_reg, 0); - host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); - host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8-(uop->imm_data & 7)); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - if ((uop->imm_data & 7) == 0) - { - if (src_reg != dest_reg) - fatal("ROL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - } - else - { - host_arm_UXTB(block, REG_TEMP, src_reg, 8); - host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); - host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8-(uop->imm_data & 7)); - host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - } - else - fatal("ROL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_ROR(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm_MOV_REG_ROR_REG(block, dest_reg, src_reg, shift_reg); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm_UXTH(block, REG_TEMP, src_reg, 0); - host_arm_AND_IMM(block, REG_TEMP2, shift_reg, 15); - host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 16); - host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP2); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm_UXTB(block, REG_TEMP, src_reg, 0); - host_arm_AND_IMM(block, REG_TEMP2, shift_reg, 7); - host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); - host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP2); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm_UXTB(block, REG_TEMP, src_reg, 8); - host_arm_AND_IMM(block, REG_TEMP2, shift_reg, 7); - host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); - host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP2); - host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("ROR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_ROR_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (!(uop->imm_data & 31)) - { - if (src_reg != dest_reg) - host_arm_MOV_REG(block, dest_reg, src_reg); - } - else - { - host_arm_MOV_REG_ROR(block, dest_reg, src_reg, uop->imm_data & 31); - } - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if ((uop->imm_data & 15) == 0) - { - if (src_reg != dest_reg) - fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - } - else - { - host_arm_UXTH(block, REG_TEMP, src_reg, 0); - host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 16); - host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data & 15); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if ((uop->imm_data & 7) == 0) - { - if (src_reg != dest_reg) - fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - } - else - { - host_arm_UXTB(block, REG_TEMP, src_reg, 0); - host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); - host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data & 7); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - if ((uop->imm_data & 7) == 0) - { - if (src_reg != dest_reg) - fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - } - else - { - host_arm_UXTB(block, REG_TEMP, src_reg, 8); - host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); - host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data & 7); - host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - } - else - fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} - -static int codegen_SAR(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm_MOV_REG_ASR_REG(block, dest_reg, src_reg, shift_reg); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, 16); - host_arm_MOV_REG_ASR_REG(block, REG_TEMP, REG_TEMP, shift_reg); - host_arm_UXTH(block, REG_TEMP, REG_TEMP, 16); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, 24); - host_arm_MOV_REG_ASR_REG(block, REG_TEMP, REG_TEMP, shift_reg); - host_arm_UXTB(block, REG_TEMP, REG_TEMP, 24); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, 16); - host_arm_MOV_REG_ASR_REG(block, REG_TEMP, REG_TEMP, shift_reg); - host_arm_UXTB(block, REG_TEMP, REG_TEMP, 24); - host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("SAR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_SAR_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm_MOV_REG_ASR(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, 16); - host_arm_MOV_REG_ASR(block, REG_TEMP, REG_TEMP, uop->imm_data); - host_arm_UXTH(block, REG_TEMP, REG_TEMP, 16); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, 24); - host_arm_MOV_REG_ASR(block, REG_TEMP, REG_TEMP, uop->imm_data); - host_arm_UXTB(block, REG_TEMP, REG_TEMP, 24); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, 16); - host_arm_MOV_REG_ASR(block, REG_TEMP, REG_TEMP, uop->imm_data); - host_arm_UXTB(block, REG_TEMP, REG_TEMP, 24); - host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("SAR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_SHL(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm_MOV_REG_LSL_REG(block, dest_reg, src_reg, shift_reg); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm_MOV_REG_LSL_REG(block, REG_TEMP, src_reg, shift_reg); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm_MOV_REG_LSL_REG(block, REG_TEMP, src_reg, shift_reg); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm_UXTB(block, REG_TEMP, src_reg, 8); - host_arm_MOV_REG_LSL_REG(block, REG_TEMP, REG_TEMP, shift_reg); - host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("SHL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_SHL_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm_MOV_REG_LSL(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, uop->imm_data); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, uop->imm_data); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm_UXTB(block, REG_TEMP, src_reg, 8); - host_arm_MOV_REG_LSL(block, REG_TEMP, REG_TEMP, uop->imm_data); - host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("SHL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_SHR(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm_MOV_REG_LSR_REG(block, dest_reg, src_reg, shift_reg); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm_UXTH(block, REG_TEMP, src_reg, 0); - host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, shift_reg); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm_UXTB(block, REG_TEMP, src_reg, 0); - host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, shift_reg); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm_UXTB(block, REG_TEMP, src_reg, 8); - host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, shift_reg); - host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("SHR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_SHR_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm_MOV_REG_LSR(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm_UXTH(block, REG_TEMP, src_reg, 0); - host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm_UXTB(block, REG_TEMP, src_reg, 0); - host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm_UXTB(block, REG_TEMP, src_reg, 8); - host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data); - host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("SHR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} - -static int codegen_STORE_PTR_IMM(codeblock_t *block, uop_t *uop) -{ - host_arm_MOV_IMM(block, REG_R0, uop->imm_data); - - if (in_range(uop->p, &cpu_state)) - host_arm_STR_IMM(block, REG_R0, REG_CPUSTATE, (uintptr_t)uop->p - (uintptr_t)&cpu_state); - else - fatal("codegen_STORE_PTR_IMM - not in range\n"); - - return 0; -} -static int codegen_STORE_PTR_IMM_8(codeblock_t *block, uop_t *uop) -{ - host_arm_MOV_IMM(block, REG_R0, uop->imm_data); - if (in_range(uop->p, &cpu_state)) - host_arm_STRB_IMM(block, REG_R0, REG_CPUSTATE, (uintptr_t)uop->p - (uintptr_t)&cpu_state); - else - fatal("codegen_STORE_PTR_IMM - not in range\n"); - - return 0; -} - -static int codegen_SUB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_SUB_REG_LSL(block, dest_reg, src_reg_a, src_reg_b, 0); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm_SUB_REG_LSL(block, REG_TEMP, src_reg_a, src_reg_b, 0); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm_SUB_REG_LSL(block, REG_TEMP, src_reg_a, src_reg_b, 0); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b)) - { - host_arm_SUB_REG_LSR(block, REG_TEMP, src_reg_a, src_reg_b, 8); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm_RSB_REG_LSR(block, REG_TEMP, src_reg_b, src_reg_a, 8); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b)) - { - host_arm_SUB_REG_LSL(block, REG_TEMP, src_reg_a, src_reg_b, 0); - host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm_RSB_REG_LSR(block, REG_TEMP, src_reg_b, src_reg_a, 8); - host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b)) - { - host_arm_MOV_REG_LSR(block, REG_TEMP, src_reg_a, 8); - host_arm_SUB_REG_LSR(block, REG_TEMP, REG_TEMP, src_reg_b, 8); - host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("SUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; - -// host_arm_SUB_REG_LSL(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, 0); -// return 0; -} -static int codegen_SUB_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm_SUB_IMM(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_BH(src_size)) - { - host_arm_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data << 8); - host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data << 8); - host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); - host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("SUB_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} - -static int codegen_TEST_JNS_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(src_size)) - { - host_arm_TST_IMM(block, src_reg, 1 << 31); - } - else if (REG_IS_W(src_size)) - { - host_arm_TST_IMM(block, src_reg, 1 << 15); - } - else if (REG_IS_B(src_size)) - { - host_arm_TST_IMM(block, src_reg, 1 << 7); - } - else - fatal("TEST_JNS_DEST %02x\n", uop->src_reg_a_real); - - uop->p = host_arm_BEQ_(block); - - return 0; -} -static int codegen_TEST_JS_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(src_size)) - { - host_arm_TST_IMM(block, src_reg, 1 << 31); - } - else if (REG_IS_W(src_size)) - { - host_arm_TST_IMM(block, src_reg, 1 << 15); - } - else if (REG_IS_B(src_size)) - { - host_arm_TST_IMM(block, src_reg, 1 << 7); - } - else - fatal("TEST_JS_DEST %02x\n", uop->src_reg_a_real); - - uop->p = host_arm_BNE_(block); - - return 0; -} - -static int codegen_XOR(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VEOR_D(block, dest_reg, src_reg_a, src_reg_b); - } - else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_EOR_REG_LSL(block, dest_reg, src_reg_a, src_reg_b, 0); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b) && dest_reg == src_reg_a) - { - host_arm_UXTH(block, REG_TEMP, src_reg_b, 0); - host_arm_EOR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) - { - host_arm_UXTB(block, REG_TEMP, src_reg_b, 0); - host_arm_EOR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) - { - host_arm_UXTB(block, REG_TEMP, src_reg_b, 8); - host_arm_EOR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) - { - host_arm_UXTB(block, REG_TEMP, src_reg_b, 0); - host_arm_EOR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) - { - host_arm_UXTB(block, REG_TEMP, src_reg_b, 8); - host_arm_EOR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 8); - } - else - fatal("XOR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm_EOR_IMM(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size) && dest_reg == src_reg) - { - host_arm_EOR_IMM(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size) && dest_reg == src_reg) - { - host_arm_EOR_IMM(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size) && dest_reg == src_reg) - { - host_arm_EOR_IMM(block, dest_reg, src_reg, uop->imm_data << 8); - } - else - fatal("XOR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} - -const uOpFn uop_handlers[UOP_MAX] = -{ - [UOP_CALL_FUNC & UOP_MASK] = codegen_CALL_FUNC, - [UOP_CALL_FUNC_RESULT & UOP_MASK] = codegen_CALL_FUNC_RESULT, - [UOP_CALL_INSTRUCTION_FUNC & UOP_MASK] = codegen_CALL_INSTRUCTION_FUNC, - - [UOP_JMP & UOP_MASK] = codegen_JMP, - - [UOP_LOAD_SEG & UOP_MASK] = codegen_LOAD_SEG, - - [UOP_LOAD_FUNC_ARG_0 & UOP_MASK] = codegen_LOAD_FUNC_ARG0, - [UOP_LOAD_FUNC_ARG_1 & UOP_MASK] = codegen_LOAD_FUNC_ARG1, - [UOP_LOAD_FUNC_ARG_2 & UOP_MASK] = codegen_LOAD_FUNC_ARG2, - [UOP_LOAD_FUNC_ARG_3 & UOP_MASK] = codegen_LOAD_FUNC_ARG3, - - [UOP_LOAD_FUNC_ARG_0_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG0_IMM, - [UOP_LOAD_FUNC_ARG_1_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG1_IMM, - [UOP_LOAD_FUNC_ARG_2_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG2_IMM, - [UOP_LOAD_FUNC_ARG_3_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG3_IMM, - - [UOP_STORE_P_IMM & UOP_MASK] = codegen_STORE_PTR_IMM, - [UOP_STORE_P_IMM_8 & UOP_MASK] = codegen_STORE_PTR_IMM_8, - - [UOP_MEM_LOAD_ABS & UOP_MASK] = codegen_MEM_LOAD_ABS, - [UOP_MEM_LOAD_REG & UOP_MASK] = codegen_MEM_LOAD_REG, - [UOP_MEM_LOAD_SINGLE & UOP_MASK] = codegen_MEM_LOAD_SINGLE, - [UOP_MEM_LOAD_DOUBLE & UOP_MASK] = codegen_MEM_LOAD_DOUBLE, - - [UOP_MEM_STORE_ABS & UOP_MASK] = codegen_MEM_STORE_ABS, - [UOP_MEM_STORE_REG & UOP_MASK] = codegen_MEM_STORE_REG, - [UOP_MEM_STORE_IMM_8 & UOP_MASK] = codegen_MEM_STORE_IMM_8, - [UOP_MEM_STORE_IMM_16 & UOP_MASK] = codegen_MEM_STORE_IMM_16, - [UOP_MEM_STORE_IMM_32 & UOP_MASK] = codegen_MEM_STORE_IMM_32, - [UOP_MEM_STORE_SINGLE & UOP_MASK] = codegen_MEM_STORE_SINGLE, - [UOP_MEM_STORE_DOUBLE & UOP_MASK] = codegen_MEM_STORE_DOUBLE, - - [UOP_MOV & UOP_MASK] = codegen_MOV, - [UOP_MOV_PTR & UOP_MASK] = codegen_MOV_PTR, - [UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM, - [UOP_MOVSX & UOP_MASK] = codegen_MOVSX, - [UOP_MOVZX & UOP_MASK] = codegen_MOVZX, - [UOP_MOV_DOUBLE_INT & UOP_MASK] = codegen_MOV_DOUBLE_INT, - [UOP_MOV_INT_DOUBLE & UOP_MASK] = codegen_MOV_INT_DOUBLE, - [UOP_MOV_INT_DOUBLE_64 & UOP_MASK] = codegen_MOV_INT_DOUBLE_64, - [UOP_MOV_REG_PTR & UOP_MASK] = codegen_MOV_REG_PTR, - [UOP_MOVZX_REG_PTR_8 & UOP_MASK] = codegen_MOVZX_REG_PTR_8, - [UOP_MOVZX_REG_PTR_16 & UOP_MASK] = codegen_MOVZX_REG_PTR_16, - - [UOP_ADD & UOP_MASK] = codegen_ADD, - [UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM, - [UOP_ADD_LSHIFT & UOP_MASK] = codegen_ADD_LSHIFT, - [UOP_AND & UOP_MASK] = codegen_AND, - [UOP_AND_IMM & UOP_MASK] = codegen_AND_IMM, - [UOP_ANDN & UOP_MASK] = codegen_ANDN, - [UOP_OR & UOP_MASK] = codegen_OR, - [UOP_OR_IMM & UOP_MASK] = codegen_OR_IMM, - [UOP_SUB & UOP_MASK] = codegen_SUB, - [UOP_SUB_IMM & UOP_MASK] = codegen_SUB_IMM, - [UOP_XOR & UOP_MASK] = codegen_XOR, - [UOP_XOR_IMM & UOP_MASK] = codegen_XOR_IMM, - - [UOP_SAR & UOP_MASK] = codegen_SAR, - [UOP_SAR_IMM & UOP_MASK] = codegen_SAR_IMM, - [UOP_SHL & UOP_MASK] = codegen_SHL, - [UOP_SHL_IMM & UOP_MASK] = codegen_SHL_IMM, - [UOP_SHR & UOP_MASK] = codegen_SHR, - [UOP_SHR_IMM & UOP_MASK] = codegen_SHR_IMM, - [UOP_ROL & UOP_MASK] = codegen_ROL, - [UOP_ROL_IMM & UOP_MASK] = codegen_ROL_IMM, - [UOP_ROR & UOP_MASK] = codegen_ROR, - [UOP_ROR_IMM & UOP_MASK] = codegen_ROR_IMM, - - [UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ, - - [UOP_CMP_JB & UOP_MASK] = codegen_CMP_JB, - [UOP_CMP_JNBE & UOP_MASK] = codegen_CMP_JNBE, - - [UOP_CMP_JNB_DEST & UOP_MASK] = codegen_CMP_JNB_DEST, - [UOP_CMP_JNBE_DEST & UOP_MASK] = codegen_CMP_JNBE_DEST, - [UOP_CMP_JNL_DEST & UOP_MASK] = codegen_CMP_JNL_DEST, - [UOP_CMP_JNLE_DEST & UOP_MASK] = codegen_CMP_JNLE_DEST, - [UOP_CMP_JNO_DEST & UOP_MASK] = codegen_CMP_JNO_DEST, - [UOP_CMP_JNZ_DEST & UOP_MASK] = codegen_CMP_JNZ_DEST, - [UOP_CMP_JB_DEST & UOP_MASK] = codegen_CMP_JB_DEST, - [UOP_CMP_JBE_DEST & UOP_MASK] = codegen_CMP_JBE_DEST, - [UOP_CMP_JL_DEST & UOP_MASK] = codegen_CMP_JL_DEST, - [UOP_CMP_JLE_DEST & UOP_MASK] = codegen_CMP_JLE_DEST, - [UOP_CMP_JO_DEST & UOP_MASK] = codegen_CMP_JO_DEST, - [UOP_CMP_JZ_DEST & UOP_MASK] = codegen_CMP_JZ_DEST, - - [UOP_CMP_IMM_JNZ_DEST & UOP_MASK] = codegen_CMP_IMM_JNZ_DEST, - [UOP_CMP_IMM_JZ_DEST & UOP_MASK] = codegen_CMP_IMM_JZ_DEST, - - [UOP_TEST_JNS_DEST & UOP_MASK] = codegen_TEST_JNS_DEST, - [UOP_TEST_JS_DEST & UOP_MASK] = codegen_TEST_JS_DEST, - - [UOP_FP_ENTER & UOP_MASK] = codegen_FP_ENTER, - [UOP_MMX_ENTER & UOP_MASK] = codegen_MMX_ENTER, - - [UOP_FADD & UOP_MASK] = codegen_FADD, - [UOP_FCOM & UOP_MASK] = codegen_FCOM, - [UOP_FDIV & UOP_MASK] = codegen_FDIV, - [UOP_FMUL & UOP_MASK] = codegen_FMUL, - [UOP_FSUB & UOP_MASK] = codegen_FSUB, - - [UOP_FABS & UOP_MASK] = codegen_FABS, - [UOP_FCHS & UOP_MASK] = codegen_FCHS, - [UOP_FSQRT & UOP_MASK] = codegen_FSQRT, - [UOP_FTST & UOP_MASK] = codegen_FTST, - - [UOP_PACKSSWB & UOP_MASK] = codegen_PACKSSWB, - [UOP_PACKSSDW & UOP_MASK] = codegen_PACKSSDW, - [UOP_PACKUSWB & UOP_MASK] = codegen_PACKUSWB, - - [UOP_PADDB & UOP_MASK] = codegen_PADDB, - [UOP_PADDW & UOP_MASK] = codegen_PADDW, - [UOP_PADDD & UOP_MASK] = codegen_PADDD, - [UOP_PADDSB & UOP_MASK] = codegen_PADDSB, - [UOP_PADDSW & UOP_MASK] = codegen_PADDSW, - [UOP_PADDUSB & UOP_MASK] = codegen_PADDUSB, - [UOP_PADDUSW & UOP_MASK] = codegen_PADDUSW, - - [UOP_PCMPEQB & UOP_MASK] = codegen_PCMPEQB, - [UOP_PCMPEQW & UOP_MASK] = codegen_PCMPEQW, - [UOP_PCMPEQD & UOP_MASK] = codegen_PCMPEQD, - [UOP_PCMPGTB & UOP_MASK] = codegen_PCMPGTB, - [UOP_PCMPGTW & UOP_MASK] = codegen_PCMPGTW, - [UOP_PCMPGTD & UOP_MASK] = codegen_PCMPGTD, - - [UOP_PF2ID & UOP_MASK] = codegen_PF2ID, - [UOP_PFADD & UOP_MASK] = codegen_PFADD, - [UOP_PFCMPEQ & UOP_MASK] = codegen_PFCMPEQ, - [UOP_PFCMPGE & UOP_MASK] = codegen_PFCMPGE, - [UOP_PFCMPGT & UOP_MASK] = codegen_PFCMPGT, - [UOP_PFMAX & UOP_MASK] = codegen_PFMAX, - [UOP_PFMIN & UOP_MASK] = codegen_PFMIN, - [UOP_PFMUL & UOP_MASK] = codegen_PFMUL, - [UOP_PFRCP & UOP_MASK] = codegen_PFRCP, - [UOP_PFRSQRT & UOP_MASK] = codegen_PFRSQRT, - [UOP_PFSUB & UOP_MASK] = codegen_PFSUB, - [UOP_PI2FD & UOP_MASK] = codegen_PI2FD, - - [UOP_PMADDWD & UOP_MASK] = codegen_PMADDWD, - [UOP_PMULHW & UOP_MASK] = codegen_PMULHW, - [UOP_PMULLW & UOP_MASK] = codegen_PMULLW, - - [UOP_PSLLW_IMM & UOP_MASK] = codegen_PSLLW_IMM, - [UOP_PSLLD_IMM & UOP_MASK] = codegen_PSLLD_IMM, - [UOP_PSLLQ_IMM & UOP_MASK] = codegen_PSLLQ_IMM, - [UOP_PSRAW_IMM & UOP_MASK] = codegen_PSRAW_IMM, - [UOP_PSRAD_IMM & UOP_MASK] = codegen_PSRAD_IMM, - [UOP_PSRAQ_IMM & UOP_MASK] = codegen_PSRAQ_IMM, - [UOP_PSRLW_IMM & UOP_MASK] = codegen_PSRLW_IMM, - [UOP_PSRLD_IMM & UOP_MASK] = codegen_PSRLD_IMM, - [UOP_PSRLQ_IMM & UOP_MASK] = codegen_PSRLQ_IMM, - - [UOP_PSUBB & UOP_MASK] = codegen_PSUBB, - [UOP_PSUBW & UOP_MASK] = codegen_PSUBW, - [UOP_PSUBD & UOP_MASK] = codegen_PSUBD, - [UOP_PSUBSB & UOP_MASK] = codegen_PSUBSB, - [UOP_PSUBSW & UOP_MASK] = codegen_PSUBSW, - [UOP_PSUBUSB & UOP_MASK] = codegen_PSUBUSB, - [UOP_PSUBUSW & UOP_MASK] = codegen_PSUBUSW, - - [UOP_PUNPCKHBW & UOP_MASK] = codegen_PUNPCKHBW, - [UOP_PUNPCKHWD & UOP_MASK] = codegen_PUNPCKHWD, - [UOP_PUNPCKHDQ & UOP_MASK] = codegen_PUNPCKHDQ, - [UOP_PUNPCKLBW & UOP_MASK] = codegen_PUNPCKLBW, - [UOP_PUNPCKLWD & UOP_MASK] = codegen_PUNPCKLWD, - [UOP_PUNPCKLDQ & UOP_MASK] = codegen_PUNPCKLDQ, - - [UOP_NOP_BARRIER & UOP_MASK] = codegen_NOP -}; - -void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p) -{ - if (in_range_h(p, &cpu_state)) - host_arm_LDRB_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - fatal("codegen_direct_read_8 - not in range\n"); -} -void codegen_direct_read_16(codeblock_t *block, int host_reg, void *p) -{ - if (in_range_h(p, &cpu_state)) - host_arm_LDRH_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - { - host_arm_MOV_IMM(block, REG_R3, (uintptr_t)p - (uintptr_t)&cpu_state); - host_arm_LDRH_REG(block, host_reg, REG_CPUSTATE, REG_R3); - } -} -void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) -{ - if (in_range(p, &cpu_state)) - host_arm_LDR_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - fatal("codegen_direct_read_32 - not in range\n"); -} -void codegen_direct_read_pointer(codeblock_t *block, int host_reg, void *p) -{ - codegen_direct_read_32(block, host_reg, p); -} -void codegen_direct_read_64(codeblock_t *block, int host_reg, void *p) -{ - host_arm_VLDR_D(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); -} -void codegen_direct_read_double(codeblock_t *block, int host_reg, void *p) -{ - host_arm_VLDR_D(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); -} -void codegen_direct_read_st_8(codeblock_t *block, int host_reg, void *base, int reg_idx) -{ - host_arm_LDR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset); - host_arm_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); - host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 7); - host_arm_ADD_REG_LSL(block, REG_TEMP, REG_CPUSTATE, REG_TEMP, 3); - host_arm_LDRB_IMM(block, host_reg, REG_TEMP, (uintptr_t)base - (uintptr_t)&cpu_state); -} -void codegen_direct_read_st_64(codeblock_t *block, int host_reg, void *base, int reg_idx) -{ - host_arm_LDR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset); - host_arm_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); - host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 7); - host_arm_ADD_REG_LSL(block, REG_TEMP, REG_CPUSTATE, REG_TEMP, 3); - host_arm_VLDR_D(block, host_reg, REG_TEMP, (uintptr_t)base - (uintptr_t)&cpu_state); -} -void codegen_direct_read_st_double(codeblock_t *block, int host_reg, void *base, int reg_idx) -{ - host_arm_LDR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset); - host_arm_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); - host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 7); - host_arm_ADD_REG_LSL(block, REG_TEMP, REG_CPUSTATE, REG_TEMP, 3); - host_arm_VLDR_D(block, host_reg, REG_TEMP, (uintptr_t)base - (uintptr_t)&cpu_state); -} - -void codegen_direct_write_8(codeblock_t *block, void *p, int host_reg) -{ - if (in_range(p, &cpu_state)) - host_arm_STRB_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - fatal("codegen_direct_write_8 - not in range\n"); -} -void codegen_direct_write_16(codeblock_t *block, void *p, int host_reg) -{ - if (in_range_h(p, &cpu_state)) - host_arm_STRH_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - { - host_arm_MOV_IMM(block, REG_R3, (uintptr_t)p - (uintptr_t)&cpu_state); - host_arm_STRH_REG(block, host_reg, REG_CPUSTATE, REG_R3); - } -} -void codegen_direct_write_32(codeblock_t *block, void *p, int host_reg) -{ - if (in_range(p, &cpu_state)) - host_arm_STR_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - fatal("codegen_direct_write_32 - not in range\n"); -} -void codegen_direct_write_64(codeblock_t *block, void *p, int host_reg) -{ - host_arm_VSTR_D(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); -} -void codegen_direct_write_double(codeblock_t *block, void *p, int host_reg) -{ - host_arm_VSTR_D(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); -} -void codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int host_reg) -{ - host_arm_LDR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset); - host_arm_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); - host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 7); - host_arm_ADD_REG_LSL(block, REG_TEMP, REG_CPUSTATE, REG_TEMP, 3); - host_arm_STRB_IMM(block, host_reg, REG_TEMP, (uintptr_t)base - (uintptr_t)&cpu_state); -} -void codegen_direct_write_st_64(codeblock_t *block, void *base, int reg_idx, int host_reg) -{ - host_arm_LDR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset); - host_arm_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); - host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 7); - host_arm_ADD_REG_LSL(block, REG_TEMP, REG_CPUSTATE, REG_TEMP, 3); - host_arm_VSTR_D(block, host_reg, REG_TEMP, (uintptr_t)base - (uintptr_t)&cpu_state); -} -void codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx, int host_reg) -{ - host_arm_LDR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset); - host_arm_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); - host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 7); - host_arm_ADD_REG_LSL(block, REG_TEMP, REG_CPUSTATE, REG_TEMP, 3); - host_arm_VSTR_D(block, host_reg, REG_TEMP, (uintptr_t)base - (uintptr_t)&cpu_state); -} - -void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg) -{ - if (in_range(p, &cpu_state)) - host_arm_STR_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - fatal("codegen_direct_write_ptr - not in range\n"); -} - -void codegen_direct_read_16_stack(codeblock_t *block, int host_reg, int stack_offset) -{ - if (stack_offset >= 0 && stack_offset < 256) - host_arm_LDRH_IMM(block, host_reg, REG_HOST_SP, stack_offset); - else - fatal("codegen_direct_read_32 - not in range\n"); -} -void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_offset) -{ - if (stack_offset >= 0 && stack_offset < 4096) - host_arm_LDR_IMM(block, host_reg, REG_HOST_SP, stack_offset); - else - fatal("codegen_direct_read_32 - not in range\n"); -} -void codegen_direct_read_pointer_stack(codeblock_t *block, int host_reg, int stack_offset) -{ - codegen_direct_read_32_stack(block, host_reg, stack_offset); -} -void codegen_direct_read_64_stack(codeblock_t *block, int host_reg, int stack_offset) -{ - host_arm_VLDR_D(block, host_reg, REG_HOST_SP, stack_offset); -} -void codegen_direct_read_double_stack(codeblock_t *block, int host_reg, int stack_offset) -{ - host_arm_VLDR_D(block, host_reg, REG_HOST_SP, stack_offset); -} - -void codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int host_reg) -{ - if (stack_offset >= 0 && stack_offset < 4096) - host_arm_STR_IMM(block, host_reg, REG_HOST_SP, stack_offset); - else - fatal("codegen_direct_write_32 - not in range\n"); -} -void codegen_direct_write_64_stack(codeblock_t *block, int stack_offset, int host_reg) -{ - host_arm_VSTR_D(block, host_reg, REG_HOST_SP, stack_offset); -} -void codegen_direct_write_double_stack(codeblock_t *block, int stack_offset, int host_reg) -{ - host_arm_VSTR_D(block, host_reg, REG_HOST_SP, stack_offset); -} - -void codegen_set_jump_dest(codeblock_t *block, void *p) -{ - *(uint32_t *)p |= ((((uintptr_t)&block_write_data[block_pos] - (uintptr_t)p) - 8) & 0x3fffffc) >> 2; +static int codegen_FMUL(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { + host_arm_VMUL_D(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("codegen_FMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_FSUB(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { + host_arm_VSUB_D(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("codegen_FSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + +static int codegen_FP_ENTER(codeblock_t *block, uop_t *uop) { + uint32_t *branch_ptr; + + if (!in_range(&cr0, &cpu_state)) + fatal("codegen_FP_ENTER - out of range\n"); + + host_arm_LDR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cr0 - (uintptr_t)&cpu_state); + host_arm_TST_IMM(block, REG_TEMP, 0xc); + branch_ptr = host_arm_BEQ_(block); + + host_arm_MOV_IMM(block, REG_TEMP, uop->imm_data); + host_arm_STR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.oldpc - (uintptr_t)&cpu_state); + host_arm_MOV_IMM(block, REG_ARG0, 7); + host_arm_call(block, x86_int); + host_arm_B(block, (uintptr_t)codegen_exit_rout); + + *branch_ptr |= ((((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_ptr) - 8) & 0x3fffffc) >> 2; + + return 0; +} +static int codegen_MMX_ENTER(codeblock_t *block, uop_t *uop) { + uint32_t *branch_ptr; + + if (!in_range(&cr0, &cpu_state)) + fatal("codegen_MMX_ENTER - out of range\n"); + + host_arm_LDR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cr0 - (uintptr_t)&cpu_state); + host_arm_TST_IMM(block, REG_TEMP, 0xc); + branch_ptr = host_arm_BEQ_(block); + + host_arm_MOV_IMM(block, REG_TEMP, uop->imm_data); + host_arm_STR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.oldpc - (uintptr_t)&cpu_state); + host_arm_MOV_IMM(block, REG_ARG0, 7); + host_arm_call(block, x86_int); + host_arm_B(block, (uintptr_t)codegen_exit_rout); + + *branch_ptr |= ((((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_ptr) - 8) & 0x3fffffc) >> 2; + + host_arm_MOV_IMM(block, REG_TEMP, 0x01010101); + host_arm_STR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.tag[0] - (uintptr_t)&cpu_state); + host_arm_STR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.tag[4] - (uintptr_t)&cpu_state); + host_arm_MOV_IMM(block, REG_TEMP, 0); + host_arm_STR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.TOP - (uintptr_t)&cpu_state); + host_arm_STRB_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.ismmx - (uintptr_t)&cpu_state); + + return 0; +} + +static int codegen_JMP(codeblock_t *block, uop_t *uop) { + host_arm_B(block, (uintptr_t)uop->p); + + return 0; +} + +static int codegen_LOAD_FUNC_ARG0(codeblock_t *block, uop_t *uop) { + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_W(src_size)) { + host_arm_UXTH(block, REG_ARG0, src_reg, 0); + } else + fatal("codegen_LOAD_FUNC_ARG0 %02x\n", uop->src_reg_a_real); + + return 0; +} +static int codegen_LOAD_FUNC_ARG1(codeblock_t *block, uop_t *uop) { + fatal("codegen_LOAD_FUNC_ARG1 %02x\n", uop->src_reg_a_real); + return 0; +} +static int codegen_LOAD_FUNC_ARG2(codeblock_t *block, uop_t *uop) { + fatal("codegen_LOAD_FUNC_ARG2 %02x\n", uop->src_reg_a_real); + return 0; +} +static int codegen_LOAD_FUNC_ARG3(codeblock_t *block, uop_t *uop) { + fatal("codegen_LOAD_FUNC_ARG3 %02x\n", uop->src_reg_a_real); + return 0; +} + +static int codegen_LOAD_FUNC_ARG0_IMM(codeblock_t *block, uop_t *uop) { + host_arm_MOV_IMM(block, REG_ARG0, uop->imm_data); + return 0; +} +static int codegen_LOAD_FUNC_ARG1_IMM(codeblock_t *block, uop_t *uop) { + host_arm_MOV_IMM(block, REG_ARG1, uop->imm_data); + return 0; +} +static int codegen_LOAD_FUNC_ARG2_IMM(codeblock_t *block, uop_t *uop) { + host_arm_MOV_IMM(block, REG_ARG2, uop->imm_data); + return 0; +} +static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop) { + host_arm_MOV_IMM(block, REG_ARG3, uop->imm_data); + return 0; +} + +static int codegen_LOAD_SEG(codeblock_t *block, uop_t *uop) { + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (!REG_IS_W(src_size)) + fatal("LOAD_SEG %02x %p\n", uop->src_reg_a_real, uop->p); + host_arm_UXTH(block, REG_ARG0, src_reg, 0); + host_arm_MOV_IMM(block, REG_ARG1, (uint32_t)uop->p); + host_arm_call(block, loadseg); + host_arm_TST_REG(block, REG_R0, REG_R0); + host_arm_BNE(block, (uintptr_t)codegen_exit_rout); + + return 0; +} + +static int codegen_MEM_LOAD_ABS(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + host_arm_ADD_IMM(block, REG_R0, seg_reg, uop->imm_data); + if (REG_IS_B(dest_size) || REG_IS_BH(dest_size)) { + host_arm_BL(block, (uintptr_t)codegen_mem_load_byte); + } else if (REG_IS_W(dest_size)) { + host_arm_BL(block, (uintptr_t)codegen_mem_load_word); + } else if (REG_IS_L(dest_size)) { + host_arm_BL(block, (uintptr_t)codegen_mem_load_long); + } else + fatal("MEM_LOAD_ABS - %02x\n", uop->dest_reg_a_real); + host_arm_TST_REG(block, REG_R1, REG_R1); + host_arm_BNE(block, (uintptr_t)codegen_exit_rout); + if (REG_IS_B(dest_size)) { + host_arm_BFI(block, dest_reg, REG_R0, 0, 8); + } else if (REG_IS_BH(dest_size)) { + host_arm_BFI(block, dest_reg, REG_R0, 8, 8); + } else if (REG_IS_W(dest_size)) { + host_arm_BFI(block, dest_reg, REG_R0, 0, 16); + } else if (REG_IS_L(dest_size)) { + host_arm_MOV_REG(block, dest_reg, REG_R0); + } + + return 0; +} + +static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), + addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); + if (uop->imm_data) + host_arm_ADD_IMM(block, REG_R0, REG_R0, uop->imm_data); + if (REG_IS_B(dest_size) || REG_IS_BH(dest_size)) { + host_arm_BL(block, (uintptr_t)codegen_mem_load_byte); + } else if (REG_IS_W(dest_size)) { + host_arm_BL(block, (uintptr_t)codegen_mem_load_word); + } else if (REG_IS_L(dest_size)) { + host_arm_BL(block, (uintptr_t)codegen_mem_load_long); + } else if (REG_IS_Q(dest_size)) { + host_arm_BL(block, (uintptr_t)codegen_mem_load_quad); + } else + fatal("MEM_LOAD_REG - %02x\n", uop->dest_reg_a_real); + host_arm_TST_REG(block, REG_R1, REG_R1); + host_arm_BNE(block, (uintptr_t)codegen_exit_rout); + if (REG_IS_B(dest_size)) { + host_arm_BFI(block, dest_reg, REG_R0, 0, 8); + } else if (REG_IS_BH(dest_size)) { + host_arm_BFI(block, dest_reg, REG_R0, 8, 8); + } else if (REG_IS_W(dest_size)) { + host_arm_BFI(block, dest_reg, REG_R0, 0, 16); + } else if (REG_IS_L(dest_size)) { + host_arm_MOV_REG(block, dest_reg, REG_R0); + } else if (REG_IS_Q(dest_size)) { + host_arm_VMOV_D_D(block, dest_reg, REG_D_TEMP); + } + + return 0; +} +static int codegen_MEM_LOAD_SINGLE(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), + addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (!REG_IS_D(dest_size)) + fatal("MEM_LOAD_SINGLE - %02x\n", uop->dest_reg_a_real); + + host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); + if (uop->imm_data) + host_arm_ADD_IMM(block, REG_R0, REG_R0, uop->imm_data); + host_arm_BL(block, (uintptr_t)codegen_mem_load_single); + host_arm_TST_REG(block, REG_R1, REG_R1); + host_arm_BNE(block, (uintptr_t)codegen_exit_rout); + host_arm_VCVT_D_S(block, dest_reg, REG_D_TEMP); + + return 0; +} +static int codegen_MEM_LOAD_DOUBLE(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), + addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (!REG_IS_D(dest_size)) + fatal("MEM_LOAD_DOUBLE - %02x\n", uop->dest_reg_a_real); + + host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); + if (uop->imm_data) + host_arm_ADD_IMM(block, REG_R0, REG_R0, uop->imm_data); + host_arm_BL(block, (uintptr_t)codegen_mem_load_double); + host_arm_TST_REG(block, REG_R1, REG_R1); + host_arm_BNE(block, (uintptr_t)codegen_exit_rout); + host_arm_VMOV_D_D(block, dest_reg, REG_D_TEMP); + + return 0; +} + +static int codegen_MEM_STORE_ABS(codeblock_t *block, uop_t *uop) { + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_b_real); + int src_size = IREG_GET_SIZE(uop->src_reg_b_real); + + host_arm_ADD_IMM(block, REG_R0, seg_reg, uop->imm_data); + if (REG_IS_B(src_size)) { + host_arm_MOV_REG(block, REG_R1, src_reg); + host_arm_BL(block, (uintptr_t)codegen_mem_store_byte); + } else if (REG_IS_W(src_size)) { + host_arm_MOV_REG(block, REG_R1, src_reg); + host_arm_BL(block, (uintptr_t)codegen_mem_store_word); + } else if (REG_IS_L(src_size)) { + host_arm_MOV_REG(block, REG_R1, src_reg); + host_arm_BL(block, (uintptr_t)codegen_mem_store_long); + } else + fatal("MEM_STORE_ABS - %02x\n", uop->src_reg_b_real); + host_arm_TST_REG(block, REG_R1, REG_R1); + host_arm_BNE(block, (uintptr_t)codegen_exit_rout); + + return 0; +} + +static int codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop) { + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), + src_reg = HOST_REG_GET(uop->src_reg_c_real); + int src_size = IREG_GET_SIZE(uop->src_reg_c_real); + + host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); + if (uop->imm_data) + host_arm_ADD_IMM(block, REG_R0, REG_R0, uop->imm_data); + if (REG_IS_B(src_size)) { + host_arm_MOV_REG(block, REG_R1, src_reg); + host_arm_BL(block, (uintptr_t)codegen_mem_store_byte); + } else if (REG_IS_BH(src_size)) { + host_arm_MOV_REG_LSR(block, REG_R1, src_reg, 8); + host_arm_BL(block, (uintptr_t)codegen_mem_store_byte); + } else if (REG_IS_W(src_size)) { + host_arm_MOV_REG(block, REG_R1, src_reg); + host_arm_BL(block, (uintptr_t)codegen_mem_store_word); + } else if (REG_IS_L(src_size)) { + host_arm_MOV_REG(block, REG_R1, src_reg); + host_arm_BL(block, (uintptr_t)codegen_mem_store_long); + } else if (REG_IS_Q(src_size)) { + host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg); + host_arm_BL(block, (uintptr_t)codegen_mem_store_quad); + } else + fatal("MEM_STORE_REG - %02x\n", uop->src_reg_c_real); + host_arm_TST_REG(block, REG_R1, REG_R1); + host_arm_BNE(block, (uintptr_t)codegen_exit_rout); + + return 0; +} + +static int codegen_MEM_STORE_IMM_8(codeblock_t *block, uop_t *uop) { + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + + host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); + host_arm_MOV_IMM(block, REG_R1, uop->imm_data); + host_arm_BL(block, (uintptr_t)codegen_mem_store_byte); + host_arm_TST_REG(block, REG_R1, REG_R1); + host_arm_BNE(block, (uintptr_t)codegen_exit_rout); + + return 0; +} +static int codegen_MEM_STORE_IMM_16(codeblock_t *block, uop_t *uop) { + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + + host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); + host_arm_MOV_IMM(block, REG_R1, uop->imm_data); + host_arm_BL(block, (uintptr_t)codegen_mem_store_word); + host_arm_TST_REG(block, REG_R1, REG_R1); + host_arm_BNE(block, (uintptr_t)codegen_exit_rout); + + return 0; +} +static int codegen_MEM_STORE_IMM_32(codeblock_t *block, uop_t *uop) { + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + + host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); + host_arm_MOV_IMM(block, REG_R1, uop->imm_data); + host_arm_BL(block, (uintptr_t)codegen_mem_store_long); + host_arm_TST_REG(block, REG_R1, REG_R1); + host_arm_BNE(block, (uintptr_t)codegen_exit_rout); + + return 0; +} +static int codegen_MEM_STORE_SINGLE(codeblock_t *block, uop_t *uop) { + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), + src_reg = HOST_REG_GET(uop->src_reg_c_real); + int src_size = IREG_GET_SIZE(uop->src_reg_c_real); + + if (!REG_IS_D(src_size)) + fatal("MEM_STORE_REG - %02x\n", uop->dest_reg_a_real); + + host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); + if (uop->imm_data) + host_arm_ADD_IMM(block, REG_R0, REG_R0, uop->imm_data); + host_arm_VCVT_S_D(block, REG_D_TEMP, src_reg); + host_arm_BL(block, (uintptr_t)codegen_mem_store_single); + host_arm_TST_REG(block, REG_R1, REG_R1); + host_arm_BNE(block, (uintptr_t)codegen_exit_rout); + + return 0; +} +static int codegen_MEM_STORE_DOUBLE(codeblock_t *block, uop_t *uop) { + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), + src_reg = HOST_REG_GET(uop->src_reg_c_real); + int src_size = IREG_GET_SIZE(uop->src_reg_c_real); + + if (!REG_IS_D(src_size)) + fatal("MEM_STORE_REG - %02x\n", uop->dest_reg_a_real); + + host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); + if (uop->imm_data) + host_arm_ADD_IMM(block, REG_R0, REG_R0, uop->imm_data); + host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg); + host_arm_BL(block, (uintptr_t)codegen_mem_store_double); + host_arm_TST_REG(block, REG_R1, REG_R1); + host_arm_BNE(block, (uintptr_t)codegen_exit_rout); + + return 0; +} + +static int codegen_MOV(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm_MOV_REG_LSL(block, dest_reg, src_reg, 0); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm_BFI(block, dest_reg, src_reg, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm_BFI(block, dest_reg, src_reg, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_B(src_size)) { + host_arm_BFI(block, dest_reg, src_reg, 8, 8); + } else if (REG_IS_B(dest_size) && REG_IS_BH(src_size)) { + host_arm_MOV_REG_LSR(block, REG_TEMP, src_reg, 8); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm_MOV_REG_LSR(block, REG_TEMP, src_reg, 8); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else if (REG_IS_D(dest_size) && REG_IS_D(src_size)) { + host_arm_VMOV_D_D(block, dest_reg, src_reg); + } else if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + host_arm_VMOV_D_D(block, dest_reg, src_reg); + } else + fatal("MOV %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} + +static int codegen_MOV_IMM(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_L(dest_size)) { + host_arm_MOV_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size)) { + host_arm_MOVW_IMM(block, REG_TEMP, uop->imm_data); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size)) { + host_arm_AND_IMM(block, dest_reg, dest_reg, ~0x000000ff); + host_arm_ORR_IMM(block, dest_reg, dest_reg, uop->imm_data); + } else if (REG_IS_BH(dest_size)) { + host_arm_AND_IMM(block, dest_reg, dest_reg, ~0x0000ff00); + host_arm_ORR_IMM(block, dest_reg, dest_reg, uop->imm_data << 8); + } else + fatal("MOV_IMM %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int codegen_MOV_PTR(codeblock_t *block, uop_t *uop) { + host_arm_MOV_IMM(block, uop->dest_reg_a_real, (uintptr_t)uop->p); + + return 0; +} + +static int codegen_MOVSX(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_B(src_size)) { + host_arm_SXTB(block, dest_reg, src_reg, 0); + } else if (REG_IS_L(dest_size) && REG_IS_BH(src_size)) { + host_arm_SXTB(block, dest_reg, src_reg, 8); + } else if (REG_IS_L(dest_size) && REG_IS_W(src_size)) { + host_arm_SXTH(block, dest_reg, src_reg, 0); + } else if (REG_IS_W(dest_size) && REG_IS_B(src_size)) { + host_arm_SXTB(block, REG_TEMP, src_reg, 0); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_W(dest_size) && REG_IS_BH(src_size)) { + host_arm_SXTB(block, REG_TEMP, src_reg, 8); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else + fatal("MOVSX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_MOVZX(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_L(src_size)) { + host_arm_MOV_IMM(block, REG_TEMP, 0); + host_arm_VMOV_D_64(block, dest_reg, src_reg, REG_TEMP); + } else if (REG_IS_L(dest_size) && REG_IS_Q(src_size)) { + host_arm_VMOV_32_S(block, dest_reg, src_reg); + } else if (REG_IS_L(dest_size) && REG_IS_B(src_size)) { + host_arm_UXTB(block, dest_reg, src_reg, 0); + } else if (REG_IS_L(dest_size) && REG_IS_BH(src_size)) { + host_arm_UXTB(block, dest_reg, src_reg, 8); + } else if (REG_IS_L(dest_size) && REG_IS_W(src_size)) { + host_arm_UXTH(block, dest_reg, src_reg, 0); + } else if (REG_IS_W(dest_size) && REG_IS_B(src_size)) { + if (src_reg == dest_reg) + host_arm_BIC_IMM(block, dest_reg, dest_reg, 0xff00); + else { + host_arm_UXTB(block, REG_TEMP, src_reg, 0); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } + } else if (REG_IS_W(dest_size) && REG_IS_BH(src_size)) { + host_arm_MOV_REG_LSR(block, REG_TEMP, src_reg, 8); + host_arm_BIC_IMM(block, dest_reg, dest_reg, 0xff00); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else + fatal("MOVZX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static double int64_to_double(int64_t a) { return (double)a; } +static int codegen_MOV_DOUBLE_INT(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_D(dest_size) && REG_IS_L(src_size)) { + host_arm_VMOV_S_32(block, REG_D_TEMP, src_reg); + host_arm_VCVT_D_IS(block, dest_reg, REG_D_TEMP); + } else if (REG_IS_D(dest_size) && REG_IS_W(src_size)) { + host_arm_SXTH(block, REG_TEMP, src_reg, 0); + host_arm_VMOV_S_32(block, REG_D_TEMP, REG_TEMP); + host_arm_VCVT_D_IS(block, dest_reg, REG_D_TEMP); + } else if (REG_IS_D(dest_size) && REG_IS_Q(src_size)) { + /*ARMv7 has no instructions to convert a 64-bit integer to a double. + For simplicity, call a C function and let the compiler do it.*/ + host_arm_VMOV_64_D(block, REG_R0, REG_R1, src_reg); + host_arm_BL(block, (uintptr_t)int64_to_double); /*Input - R0/R1, Output - D0*/ + host_arm_VMOV_D_D(block, dest_reg, REG_D0); + } else + fatal("MOV_DOUBLE_INT %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_MOV_INT_DOUBLE(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_D(src_size)) { + host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg); + host_arm_BL(block, (uintptr_t)codegen_fp_round); + host_arm_VMOV_32_S(block, dest_reg, REG_D_TEMP); + } else if (REG_IS_W(dest_size) && REG_IS_D(src_size)) { + host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg); + host_arm_BL(block, (uintptr_t)codegen_fp_round); + host_arm_VMOV_32_S(block, REG_TEMP, REG_D_TEMP); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else + fatal("MOV_INT_DOUBLE %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int64_t x87_fround64(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 int codegen_MOV_INT_DOUBLE_64(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), + src_64_reg = HOST_REG_GET(uop->src_reg_b_real), tag_reg = HOST_REG_GET(uop->src_reg_c_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real), + src_64_size = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_D(src_size) && REG_IS_Q(src_64_size)) { + uint32_t *branch_offset; + + /*If TAG_UINT64 is set then the source is MM[]. Otherwise it is a double in ST()*/ + host_arm_VMOV_D_D(block, dest_reg, src_64_reg); + host_arm_TST_IMM(block, tag_reg, TAG_UINT64); + branch_offset = host_arm_BNE_(block); + + /*VFP/NEON has no instructions to convert a float to 64-bit integer, + so call out to C.*/ + host_arm_VMOV_D_D(block, REG_D0, src_reg); + host_arm_call(block, x87_fround64); + host_arm_VMOV_D_64(block, REG_D_TEMP, REG_R0, REG_R1); + + *branch_offset |= ((((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 8) & 0x3fffffc) >> 2; + } else + fatal("MOV_INT_DOUBLE_64 %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_MOV_REG_PTR(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + host_arm_MOV_IMM(block, REG_TEMP, (uintptr_t)uop->p); + if (REG_IS_L(dest_size)) { + host_arm_LDR_IMM(block, dest_reg, REG_TEMP, 0); + } else + fatal("MOV_REG_PTR %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int codegen_MOVZX_REG_PTR_8(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + host_arm_MOV_IMM(block, REG_TEMP, (uintptr_t)uop->p); + if (REG_IS_L(dest_size)) { + host_arm_LDRB_IMM(block, dest_reg, REG_TEMP, 0); + } else if (REG_IS_W(dest_size)) { + host_arm_LDRB_IMM(block, REG_TEMP, REG_TEMP, 0); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size)) { + host_arm_LDRB_IMM(block, REG_TEMP, REG_TEMP, 0); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else + fatal("MOVZX_REG_PTR_8 %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int codegen_MOVZX_REG_PTR_16(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + host_arm_MOV_IMM(block, REG_TEMP, (uintptr_t)uop->p); + if (REG_IS_L(dest_size)) { + host_arm_LDRH_IMM(block, dest_reg, REG_TEMP, 0); + } else if (REG_IS_W(dest_size)) { + host_arm_LDRH_IMM(block, REG_TEMP, REG_TEMP, 0); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else + fatal("MOVZX_REG_PTR_16 %02x\n", uop->dest_reg_a_real); + + return 0; +} + +static int codegen_NOP(codeblock_t *block, uop_t *uop) { return 0; } + +static int codegen_OR(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VORR_D(block, dest_reg, src_reg_a, src_reg_b); + } else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_ORR_REG_LSL(block, dest_reg, src_reg_a, src_reg_b, 0); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm_ORR_REG_LSL(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) { + host_arm_UXTB(block, REG_TEMP, src_reg_b, 0); + host_arm_ORR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) { + host_arm_UXTB(block, REG_TEMP, src_reg_b, 8); + host_arm_ORR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) { + host_arm_UXTB(block, REG_TEMP, src_reg_b, 0); + host_arm_ORR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) { + host_arm_UXTB(block, REG_TEMP, src_reg_b, 8); + host_arm_ORR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 8); + } else + fatal("OR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_OR_IMM(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm_ORR_IMM(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size) && dest_reg == src_reg) { + host_arm_ORR_IMM(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size) && dest_reg == src_reg) { + host_arm_ORR_IMM(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size) && dest_reg == src_reg) { + host_arm_ORR_IMM(block, dest_reg, src_reg, uop->imm_data << 8); + } else + fatal("OR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} + +static int codegen_PACKSSWB(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VMOV_D_D(block, REG_Q_TEMP, src_reg_a); + host_arm_VMOV_D_D(block, REG_Q_TEMP_2, src_reg_b); + host_arm_VQMOVN_S16(block, dest_reg, REG_Q_TEMP); + host_arm_VQMOVN_S16(block, REG_D_TEMP, REG_Q_TEMP_2); + host_arm_VZIP_D32(block, dest_reg, REG_D_TEMP); + } else + fatal("PACKSSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PACKSSDW(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VMOV_D_D(block, REG_Q_TEMP, src_reg_a); + host_arm_VMOV_D_D(block, REG_Q_TEMP_2, src_reg_b); + host_arm_VQMOVN_S32(block, dest_reg, REG_Q_TEMP); + host_arm_VQMOVN_S32(block, REG_D_TEMP, REG_Q_TEMP_2); + host_arm_VZIP_D32(block, dest_reg, REG_D_TEMP); + } else + fatal("PACKSSDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PACKUSWB(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VMOV_D_D(block, REG_Q_TEMP, src_reg_a); + host_arm_VMOV_D_D(block, REG_Q_TEMP_2, src_reg_b); + host_arm_VQMOVN_U16(block, dest_reg, REG_Q_TEMP); + host_arm_VQMOVN_U16(block, REG_D_TEMP, REG_Q_TEMP_2); + host_arm_VZIP_D32(block, dest_reg, REG_D_TEMP); + } else + fatal("PACKUSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + +static int codegen_PADDB(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VADD_I8(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PADDB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PADDW(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VADD_I16(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PADDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PADDD(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VADD_I32(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PADDD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PADDSB(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VQADD_S8(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PADDSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PADDSW(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VQADD_S16(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PADDSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PADDUSB(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VQADD_U8(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PADDUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PADDUSW(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VQADD_U16(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PADDUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + +static int codegen_PCMPEQB(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VCEQ_I8(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PCMPEQB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PCMPEQW(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VCEQ_I16(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PCMPEQW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PCMPEQD(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VCEQ_I32(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PCMPEQD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PCMPGTB(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VCGT_S8(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PCMPGTB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PCMPGTW(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VCGT_S16(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PCMPGTW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PCMPGTD(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VCGT_S32(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PCMPGTD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + +static int codegen_PF2ID(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { + host_arm_VCVT_S32_F32(block, dest_reg, src_reg_a); + } else + fatal("PF2ID %02x %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int codegen_PFADD(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VADD_F32(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PFADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PFCMPEQ(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VCEQ_F32(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PFCMPEQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PFCMPGE(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VCGE_F32(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PFCMPGE %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PFCMPGT(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VCGT_F32(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PFCMPGT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PFMAX(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VMAX_F32(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PFMAX %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PFMIN(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VMIN_F32(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PFMIN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PFMUL(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VMUL_F32(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PFMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PFRCP(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { + /*TODO: This could be improved (use VRECPE/VRECPS)*/ + host_arm_VMOV_F32_ONE(block, REG_D_TEMP); + host_arm_VDIV_S(block, dest_reg, REG_D_TEMP, src_reg_a); + host_arm_VDUP_32(block, dest_reg, dest_reg, 0); + } else + fatal("PFRCP %02x %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int codegen_PFRSQRT(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { + /*TODO: This could be improved (use VRSQRTE/VRSQRTS)*/ + host_arm_VSQRT_S(block, REG_D_TEMP, src_reg_a); + host_arm_VMOV_F32_ONE(block, REG_D_TEMP); + host_arm_VDIV_S(block, dest_reg, dest_reg, REG_D_TEMP); + host_arm_VDUP_32(block, dest_reg, dest_reg, 0); + } else + fatal("PFRSQRT %02x %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int codegen_PFSUB(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VSUB_F32(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PFSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PI2FD(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { + host_arm_VCVT_F32_S32(block, dest_reg, src_reg_a); + } else + fatal("PI2FD %02x %02x\n", uop->dest_reg_a_real); + + return 0; +} + +static int codegen_PMADDWD(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VMULL_S16(block, REG_Q_TEMP, src_reg_a, src_reg_b); + host_arm_VPADDL_Q_S32(block, REG_Q_TEMP, REG_Q_TEMP); + host_arm_VMOVN_I64(block, dest_reg, REG_Q_TEMP); + } else + fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PMULHW(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VMULL_S16(block, REG_Q_TEMP, src_reg_a, src_reg_b); + host_arm_VSHRN_32(block, dest_reg, REG_Q_TEMP, 16); + } else + fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PMULLW(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VMUL_S16(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PMULLW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + +static int codegen_PSLLW_IMM(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + if (uop->imm_data == 0) + host_arm_VMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 15) + host_arm_VEOR_D(block, dest_reg, dest_reg, dest_reg); + else + host_arm_VSHL_D_IMM_16(block, dest_reg, src_reg, uop->imm_data); + } else + fatal("PSLLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_PSLLD_IMM(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + if (uop->imm_data == 0) + host_arm_VMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 31) + host_arm_VEOR_D(block, dest_reg, dest_reg, dest_reg); + else + host_arm_VSHL_D_IMM_32(block, dest_reg, src_reg, uop->imm_data); + } else + fatal("PSLLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_PSLLQ_IMM(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + if (uop->imm_data == 0) + host_arm_VMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 63) + host_arm_VEOR_D(block, dest_reg, dest_reg, dest_reg); + else + host_arm_VSHL_D_IMM_64(block, dest_reg, src_reg, uop->imm_data); + } else + fatal("PSLLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_PSRAW_IMM(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + if (uop->imm_data == 0) + host_arm_VMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 15) + host_arm_VSHR_D_S16(block, dest_reg, src_reg, 15); + else + host_arm_VSHR_D_S16(block, dest_reg, src_reg, uop->imm_data); + } else + fatal("PSRAW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_PSRAD_IMM(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + if (uop->imm_data == 0) + host_arm_VMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 31) + host_arm_VSHR_D_S32(block, dest_reg, src_reg, 31); + else + host_arm_VSHR_D_S32(block, dest_reg, src_reg, uop->imm_data); + } else + fatal("PSRAD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_PSRAQ_IMM(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + if (uop->imm_data == 0) + host_arm_VMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 63) + host_arm_VSHR_D_S64(block, dest_reg, src_reg, 63); + else + host_arm_VSHR_D_S64(block, dest_reg, src_reg, uop->imm_data); + } else + fatal("PSRAQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_PSRLW_IMM(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + if (uop->imm_data == 0) + host_arm_VMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 15) + host_arm_VEOR_D(block, dest_reg, dest_reg, dest_reg); + else + host_arm_VSHR_D_U16(block, dest_reg, src_reg, uop->imm_data); + } else + fatal("PSRLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_PSRLD_IMM(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + if (uop->imm_data == 0) + host_arm_VMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 31) + host_arm_VEOR_D(block, dest_reg, dest_reg, dest_reg); + else + host_arm_VSHR_D_U32(block, dest_reg, src_reg, uop->imm_data); + } else + fatal("PSRLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_PSRLQ_IMM(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + if (uop->imm_data == 0) + host_arm_VMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 63) + host_arm_VEOR_D(block, dest_reg, dest_reg, dest_reg); + else + host_arm_VSHR_D_U64(block, dest_reg, src_reg, uop->imm_data); + } else + fatal("PSRLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} + +static int codegen_PSUBB(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VSUB_I8(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PSUBB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PSUBW(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VSUB_I16(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PSUBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PSUBD(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VSUB_I32(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PSUBD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PSUBSB(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VQSUB_S8(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PSUBSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PSUBSW(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VQSUB_S16(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PSUBSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PSUBUSB(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VQSUB_U8(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PSUBUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PSUBUSW(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VQSUB_U16(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PSUBUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + +static int codegen_PUNPCKHBW(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg_b); + if (dest_reg != src_reg_a) + host_arm_VMOV_D_D(block, dest_reg, src_reg_a); + host_arm_VZIP_D8(block, dest_reg, REG_D_TEMP); + host_arm_VMOV_D_D(block, dest_reg, REG_D_TEMP); + } else + fatal("PUNPCKHBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PUNPCKHWD(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg_b); + if (dest_reg != src_reg_a) + host_arm_VMOV_D_D(block, dest_reg, src_reg_a); + host_arm_VZIP_D16(block, dest_reg, REG_D_TEMP); + host_arm_VMOV_D_D(block, dest_reg, REG_D_TEMP); + } else + fatal("PUNPCKHWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PUNPCKHDQ(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg_b); + if (dest_reg != src_reg_a) + host_arm_VMOV_D_D(block, dest_reg, src_reg_a); + host_arm_VZIP_D32(block, dest_reg, REG_D_TEMP); + host_arm_VMOV_D_D(block, dest_reg, REG_D_TEMP); + } else + fatal("PUNPCKHDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PUNPCKLBW(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg_b); + if (dest_reg != src_reg_a) + host_arm_VMOV_D_D(block, dest_reg, src_reg_a); + host_arm_VZIP_D8(block, dest_reg, REG_D_TEMP); + } else + fatal("PUNPCKLBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PUNPCKLWD(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg_b); + if (dest_reg != src_reg_a) + host_arm_VMOV_D_D(block, dest_reg, src_reg_a); + host_arm_VZIP_D16(block, dest_reg, REG_D_TEMP); + } else + fatal("PUNPCKLWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PUNPCKLDQ(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg_b); + if (dest_reg != src_reg_a) + host_arm_VMOV_D_D(block, dest_reg, src_reg_a); + host_arm_VZIP_D32(block, dest_reg, REG_D_TEMP); + } else + fatal("PUNPCKLDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + +static int codegen_ROL(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), + shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm_RSB_IMM(block, REG_TEMP2, shift_reg, 32); + host_arm_MOV_REG_ROR_REG(block, dest_reg, src_reg, REG_TEMP2); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm_UXTH(block, REG_TEMP, src_reg, 0); + host_arm_RSB_IMM(block, REG_TEMP2, shift_reg, 16); + host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 16); + host_arm_MOV_REG_ROR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP2); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm_RSB_IMM(block, REG_TEMP2, shift_reg, 8); + host_arm_UXTB(block, REG_TEMP, src_reg, 0); + host_arm_AND_IMM(block, REG_TEMP2, REG_TEMP2, 7); + host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP2); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm_RSB_IMM(block, REG_TEMP2, shift_reg, 8); + host_arm_UXTB(block, REG_TEMP, src_reg, 8); + host_arm_AND_IMM(block, REG_TEMP2, REG_TEMP2, 7); + host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP2); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("ROL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_ROL_IMM(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (!(uop->imm_data & 31)) { + if (src_reg != dest_reg) + host_arm_MOV_REG(block, dest_reg, src_reg); + } else { + host_arm_MOV_REG_ROR(block, dest_reg, src_reg, 32 - (uop->imm_data & 31)); + } + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if ((uop->imm_data & 15) == 0) { + if (src_reg != dest_reg) + host_arm_BFI(block, dest_reg, src_reg, 0, 16); + } else { + host_arm_UXTH(block, REG_TEMP, src_reg, 0); + host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 16); + host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 16 - (uop->imm_data & 15)); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if ((uop->imm_data & 7) == 0) { + if (src_reg != dest_reg) + host_arm_BFI(block, dest_reg, src_reg, 0, 8); + } else { + host_arm_UXTB(block, REG_TEMP, src_reg, 0); + host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8 - (uop->imm_data & 7)); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + if ((uop->imm_data & 7) == 0) { + if (src_reg != dest_reg) + fatal("ROL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + } else { + host_arm_UXTB(block, REG_TEMP, src_reg, 8); + host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8 - (uop->imm_data & 7)); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } + } else + fatal("ROL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_ROR(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), + shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm_MOV_REG_ROR_REG(block, dest_reg, src_reg, shift_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm_UXTH(block, REG_TEMP, src_reg, 0); + host_arm_AND_IMM(block, REG_TEMP2, shift_reg, 15); + host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 16); + host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP2); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm_UXTB(block, REG_TEMP, src_reg, 0); + host_arm_AND_IMM(block, REG_TEMP2, shift_reg, 7); + host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP2); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm_UXTB(block, REG_TEMP, src_reg, 8); + host_arm_AND_IMM(block, REG_TEMP2, shift_reg, 7); + host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP2); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("ROR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_ROR_IMM(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (!(uop->imm_data & 31)) { + if (src_reg != dest_reg) + host_arm_MOV_REG(block, dest_reg, src_reg); + } else { + host_arm_MOV_REG_ROR(block, dest_reg, src_reg, uop->imm_data & 31); + } + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if ((uop->imm_data & 15) == 0) { + if (src_reg != dest_reg) + fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + } else { + host_arm_UXTH(block, REG_TEMP, src_reg, 0); + host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 16); + host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data & 15); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if ((uop->imm_data & 7) == 0) { + if (src_reg != dest_reg) + fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + } else { + host_arm_UXTB(block, REG_TEMP, src_reg, 0); + host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data & 7); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + if ((uop->imm_data & 7) == 0) { + if (src_reg != dest_reg) + fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + } else { + host_arm_UXTB(block, REG_TEMP, src_reg, 8); + host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data & 7); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } + } else + fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} + +static int codegen_SAR(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), + shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm_MOV_REG_ASR_REG(block, dest_reg, src_reg, shift_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, 16); + host_arm_MOV_REG_ASR_REG(block, REG_TEMP, REG_TEMP, shift_reg); + host_arm_UXTH(block, REG_TEMP, REG_TEMP, 16); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, 24); + host_arm_MOV_REG_ASR_REG(block, REG_TEMP, REG_TEMP, shift_reg); + host_arm_UXTB(block, REG_TEMP, REG_TEMP, 24); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, 16); + host_arm_MOV_REG_ASR_REG(block, REG_TEMP, REG_TEMP, shift_reg); + host_arm_UXTB(block, REG_TEMP, REG_TEMP, 24); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("SAR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_SAR_IMM(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm_MOV_REG_ASR(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, 16); + host_arm_MOV_REG_ASR(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm_UXTH(block, REG_TEMP, REG_TEMP, 16); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, 24); + host_arm_MOV_REG_ASR(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm_UXTB(block, REG_TEMP, REG_TEMP, 24); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, 16); + host_arm_MOV_REG_ASR(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm_UXTB(block, REG_TEMP, REG_TEMP, 24); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("SAR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_SHL(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), + shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm_MOV_REG_LSL_REG(block, dest_reg, src_reg, shift_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm_MOV_REG_LSL_REG(block, REG_TEMP, src_reg, shift_reg); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm_MOV_REG_LSL_REG(block, REG_TEMP, src_reg, shift_reg); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm_UXTB(block, REG_TEMP, src_reg, 8); + host_arm_MOV_REG_LSL_REG(block, REG_TEMP, REG_TEMP, shift_reg); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("SHL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_SHL_IMM(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm_MOV_REG_LSL(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, uop->imm_data); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, uop->imm_data); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm_UXTB(block, REG_TEMP, src_reg, 8); + host_arm_MOV_REG_LSL(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("SHL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_SHR(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), + shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm_MOV_REG_LSR_REG(block, dest_reg, src_reg, shift_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm_UXTH(block, REG_TEMP, src_reg, 0); + host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, shift_reg); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm_UXTB(block, REG_TEMP, src_reg, 0); + host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, shift_reg); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm_UXTB(block, REG_TEMP, src_reg, 8); + host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, shift_reg); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("SHR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_SHR_IMM(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm_MOV_REG_LSR(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm_UXTH(block, REG_TEMP, src_reg, 0); + host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm_UXTB(block, REG_TEMP, src_reg, 0); + host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm_UXTB(block, REG_TEMP, src_reg, 8); + host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("SHR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} + +static int codegen_STORE_PTR_IMM(codeblock_t *block, uop_t *uop) { + host_arm_MOV_IMM(block, REG_R0, uop->imm_data); + + if (in_range(uop->p, &cpu_state)) + host_arm_STR_IMM(block, REG_R0, REG_CPUSTATE, (uintptr_t)uop->p - (uintptr_t)&cpu_state); + else + fatal("codegen_STORE_PTR_IMM - not in range\n"); + + return 0; +} +static int codegen_STORE_PTR_IMM_8(codeblock_t *block, uop_t *uop) { + host_arm_MOV_IMM(block, REG_R0, uop->imm_data); + if (in_range(uop->p, &cpu_state)) + host_arm_STRB_IMM(block, REG_R0, REG_CPUSTATE, (uintptr_t)uop->p - (uintptr_t)&cpu_state); + else + fatal("codegen_STORE_PTR_IMM - not in range\n"); + + return 0; +} + +static int codegen_SUB(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_SUB_REG_LSL(block, dest_reg, src_reg_a, src_reg_b, 0); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm_SUB_REG_LSL(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm_SUB_REG_LSL(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b)) { + host_arm_SUB_REG_LSR(block, REG_TEMP, src_reg_a, src_reg_b, 8); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b)) { + host_arm_RSB_REG_LSR(block, REG_TEMP, src_reg_b, src_reg_a, 8); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b)) { + host_arm_SUB_REG_LSL(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b)) { + host_arm_RSB_REG_LSR(block, REG_TEMP, src_reg_b, src_reg_a, 8); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b)) { + host_arm_MOV_REG_LSR(block, REG_TEMP, src_reg_a, 8); + host_arm_SUB_REG_LSR(block, REG_TEMP, REG_TEMP, src_reg_b, 8); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("SUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; + + // host_arm_SUB_REG_LSL(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, 0); + // return 0; +} +static int codegen_SUB_IMM(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm_SUB_IMM(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_B(dest_size) && REG_IS_BH(src_size)) { + host_arm_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data << 8); + host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data << 8); + host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("SUB_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} + +static int codegen_TEST_JNS_DEST(codeblock_t *block, uop_t *uop) { + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(src_size)) { + host_arm_TST_IMM(block, src_reg, 1 << 31); + } else if (REG_IS_W(src_size)) { + host_arm_TST_IMM(block, src_reg, 1 << 15); + } else if (REG_IS_B(src_size)) { + host_arm_TST_IMM(block, src_reg, 1 << 7); + } else + fatal("TEST_JNS_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BEQ_(block); + + return 0; +} +static int codegen_TEST_JS_DEST(codeblock_t *block, uop_t *uop) { + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(src_size)) { + host_arm_TST_IMM(block, src_reg, 1 << 31); + } else if (REG_IS_W(src_size)) { + host_arm_TST_IMM(block, src_reg, 1 << 15); + } else if (REG_IS_B(src_size)) { + host_arm_TST_IMM(block, src_reg, 1 << 7); + } else + fatal("TEST_JS_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BNE_(block); + + return 0; +} + +static int codegen_XOR(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VEOR_D(block, dest_reg, src_reg_a, src_reg_b); + } else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_EOR_REG_LSL(block, dest_reg, src_reg_a, src_reg_b, 0); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b) && dest_reg == src_reg_a) { + host_arm_UXTH(block, REG_TEMP, src_reg_b, 0); + host_arm_EOR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) { + host_arm_UXTB(block, REG_TEMP, src_reg_b, 0); + host_arm_EOR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) { + host_arm_UXTB(block, REG_TEMP, src_reg_b, 8); + host_arm_EOR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) { + host_arm_UXTB(block, REG_TEMP, src_reg_b, 0); + host_arm_EOR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) { + host_arm_UXTB(block, REG_TEMP, src_reg_b, 8); + host_arm_EOR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 8); + } else + fatal("XOR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm_EOR_IMM(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size) && dest_reg == src_reg) { + host_arm_EOR_IMM(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size) && dest_reg == src_reg) { + host_arm_EOR_IMM(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size) && dest_reg == src_reg) { + host_arm_EOR_IMM(block, dest_reg, src_reg, uop->imm_data << 8); + } else + fatal("XOR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} + +const uOpFn uop_handlers[UOP_MAX] = {[UOP_CALL_FUNC & UOP_MASK] = codegen_CALL_FUNC, + [UOP_CALL_FUNC_RESULT & UOP_MASK] = codegen_CALL_FUNC_RESULT, + [UOP_CALL_INSTRUCTION_FUNC & UOP_MASK] = codegen_CALL_INSTRUCTION_FUNC, + + [UOP_JMP & UOP_MASK] = codegen_JMP, + + [UOP_LOAD_SEG & UOP_MASK] = codegen_LOAD_SEG, + + [UOP_LOAD_FUNC_ARG_0 & UOP_MASK] = codegen_LOAD_FUNC_ARG0, + [UOP_LOAD_FUNC_ARG_1 & UOP_MASK] = codegen_LOAD_FUNC_ARG1, + [UOP_LOAD_FUNC_ARG_2 & UOP_MASK] = codegen_LOAD_FUNC_ARG2, + [UOP_LOAD_FUNC_ARG_3 & UOP_MASK] = codegen_LOAD_FUNC_ARG3, + + [UOP_LOAD_FUNC_ARG_0_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG0_IMM, + [UOP_LOAD_FUNC_ARG_1_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG1_IMM, + [UOP_LOAD_FUNC_ARG_2_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG2_IMM, + [UOP_LOAD_FUNC_ARG_3_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG3_IMM, + + [UOP_STORE_P_IMM & UOP_MASK] = codegen_STORE_PTR_IMM, + [UOP_STORE_P_IMM_8 & UOP_MASK] = codegen_STORE_PTR_IMM_8, + + [UOP_MEM_LOAD_ABS & UOP_MASK] = codegen_MEM_LOAD_ABS, + [UOP_MEM_LOAD_REG & UOP_MASK] = codegen_MEM_LOAD_REG, + [UOP_MEM_LOAD_SINGLE & UOP_MASK] = codegen_MEM_LOAD_SINGLE, + [UOP_MEM_LOAD_DOUBLE & UOP_MASK] = codegen_MEM_LOAD_DOUBLE, + + [UOP_MEM_STORE_ABS & UOP_MASK] = codegen_MEM_STORE_ABS, + [UOP_MEM_STORE_REG & UOP_MASK] = codegen_MEM_STORE_REG, + [UOP_MEM_STORE_IMM_8 & UOP_MASK] = codegen_MEM_STORE_IMM_8, + [UOP_MEM_STORE_IMM_16 & UOP_MASK] = codegen_MEM_STORE_IMM_16, + [UOP_MEM_STORE_IMM_32 & UOP_MASK] = codegen_MEM_STORE_IMM_32, + [UOP_MEM_STORE_SINGLE & UOP_MASK] = codegen_MEM_STORE_SINGLE, + [UOP_MEM_STORE_DOUBLE & UOP_MASK] = codegen_MEM_STORE_DOUBLE, + + [UOP_MOV & UOP_MASK] = codegen_MOV, + [UOP_MOV_PTR & UOP_MASK] = codegen_MOV_PTR, + [UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM, + [UOP_MOVSX & UOP_MASK] = codegen_MOVSX, + [UOP_MOVZX & UOP_MASK] = codegen_MOVZX, + [UOP_MOV_DOUBLE_INT & UOP_MASK] = codegen_MOV_DOUBLE_INT, + [UOP_MOV_INT_DOUBLE & UOP_MASK] = codegen_MOV_INT_DOUBLE, + [UOP_MOV_INT_DOUBLE_64 & UOP_MASK] = codegen_MOV_INT_DOUBLE_64, + [UOP_MOV_REG_PTR & UOP_MASK] = codegen_MOV_REG_PTR, + [UOP_MOVZX_REG_PTR_8 & UOP_MASK] = codegen_MOVZX_REG_PTR_8, + [UOP_MOVZX_REG_PTR_16 & UOP_MASK] = codegen_MOVZX_REG_PTR_16, + + [UOP_ADD & UOP_MASK] = codegen_ADD, + [UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM, + [UOP_ADD_LSHIFT & UOP_MASK] = codegen_ADD_LSHIFT, + [UOP_AND & UOP_MASK] = codegen_AND, + [UOP_AND_IMM & UOP_MASK] = codegen_AND_IMM, + [UOP_ANDN & UOP_MASK] = codegen_ANDN, + [UOP_OR & UOP_MASK] = codegen_OR, + [UOP_OR_IMM & UOP_MASK] = codegen_OR_IMM, + [UOP_SUB & UOP_MASK] = codegen_SUB, + [UOP_SUB_IMM & UOP_MASK] = codegen_SUB_IMM, + [UOP_XOR & UOP_MASK] = codegen_XOR, + [UOP_XOR_IMM & UOP_MASK] = codegen_XOR_IMM, + + [UOP_SAR & UOP_MASK] = codegen_SAR, + [UOP_SAR_IMM & UOP_MASK] = codegen_SAR_IMM, + [UOP_SHL & UOP_MASK] = codegen_SHL, + [UOP_SHL_IMM & UOP_MASK] = codegen_SHL_IMM, + [UOP_SHR & UOP_MASK] = codegen_SHR, + [UOP_SHR_IMM & UOP_MASK] = codegen_SHR_IMM, + [UOP_ROL & UOP_MASK] = codegen_ROL, + [UOP_ROL_IMM & UOP_MASK] = codegen_ROL_IMM, + [UOP_ROR & UOP_MASK] = codegen_ROR, + [UOP_ROR_IMM & UOP_MASK] = codegen_ROR_IMM, + + [UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ, + + [UOP_CMP_JB & UOP_MASK] = codegen_CMP_JB, + [UOP_CMP_JNBE & UOP_MASK] = codegen_CMP_JNBE, + + [UOP_CMP_JNB_DEST & UOP_MASK] = codegen_CMP_JNB_DEST, + [UOP_CMP_JNBE_DEST & UOP_MASK] = codegen_CMP_JNBE_DEST, + [UOP_CMP_JNL_DEST & UOP_MASK] = codegen_CMP_JNL_DEST, + [UOP_CMP_JNLE_DEST & UOP_MASK] = codegen_CMP_JNLE_DEST, + [UOP_CMP_JNO_DEST & UOP_MASK] = codegen_CMP_JNO_DEST, + [UOP_CMP_JNZ_DEST & UOP_MASK] = codegen_CMP_JNZ_DEST, + [UOP_CMP_JB_DEST & UOP_MASK] = codegen_CMP_JB_DEST, + [UOP_CMP_JBE_DEST & UOP_MASK] = codegen_CMP_JBE_DEST, + [UOP_CMP_JL_DEST & UOP_MASK] = codegen_CMP_JL_DEST, + [UOP_CMP_JLE_DEST & UOP_MASK] = codegen_CMP_JLE_DEST, + [UOP_CMP_JO_DEST & UOP_MASK] = codegen_CMP_JO_DEST, + [UOP_CMP_JZ_DEST & UOP_MASK] = codegen_CMP_JZ_DEST, + + [UOP_CMP_IMM_JNZ_DEST & UOP_MASK] = codegen_CMP_IMM_JNZ_DEST, + [UOP_CMP_IMM_JZ_DEST & UOP_MASK] = codegen_CMP_IMM_JZ_DEST, + + [UOP_TEST_JNS_DEST & UOP_MASK] = codegen_TEST_JNS_DEST, + [UOP_TEST_JS_DEST & UOP_MASK] = codegen_TEST_JS_DEST, + + [UOP_FP_ENTER & UOP_MASK] = codegen_FP_ENTER, + [UOP_MMX_ENTER & UOP_MASK] = codegen_MMX_ENTER, + + [UOP_FADD & UOP_MASK] = codegen_FADD, + [UOP_FCOM & UOP_MASK] = codegen_FCOM, + [UOP_FDIV & UOP_MASK] = codegen_FDIV, + [UOP_FMUL & UOP_MASK] = codegen_FMUL, + [UOP_FSUB & UOP_MASK] = codegen_FSUB, + + [UOP_FABS & UOP_MASK] = codegen_FABS, + [UOP_FCHS & UOP_MASK] = codegen_FCHS, + [UOP_FSQRT & UOP_MASK] = codegen_FSQRT, + [UOP_FTST & UOP_MASK] = codegen_FTST, + + [UOP_PACKSSWB & UOP_MASK] = codegen_PACKSSWB, + [UOP_PACKSSDW & UOP_MASK] = codegen_PACKSSDW, + [UOP_PACKUSWB & UOP_MASK] = codegen_PACKUSWB, + + [UOP_PADDB & UOP_MASK] = codegen_PADDB, + [UOP_PADDW & UOP_MASK] = codegen_PADDW, + [UOP_PADDD & UOP_MASK] = codegen_PADDD, + [UOP_PADDSB & UOP_MASK] = codegen_PADDSB, + [UOP_PADDSW & UOP_MASK] = codegen_PADDSW, + [UOP_PADDUSB & UOP_MASK] = codegen_PADDUSB, + [UOP_PADDUSW & UOP_MASK] = codegen_PADDUSW, + + [UOP_PCMPEQB & UOP_MASK] = codegen_PCMPEQB, + [UOP_PCMPEQW & UOP_MASK] = codegen_PCMPEQW, + [UOP_PCMPEQD & UOP_MASK] = codegen_PCMPEQD, + [UOP_PCMPGTB & UOP_MASK] = codegen_PCMPGTB, + [UOP_PCMPGTW & UOP_MASK] = codegen_PCMPGTW, + [UOP_PCMPGTD & UOP_MASK] = codegen_PCMPGTD, + + [UOP_PF2ID & UOP_MASK] = codegen_PF2ID, + [UOP_PFADD & UOP_MASK] = codegen_PFADD, + [UOP_PFCMPEQ & UOP_MASK] = codegen_PFCMPEQ, + [UOP_PFCMPGE & UOP_MASK] = codegen_PFCMPGE, + [UOP_PFCMPGT & UOP_MASK] = codegen_PFCMPGT, + [UOP_PFMAX & UOP_MASK] = codegen_PFMAX, + [UOP_PFMIN & UOP_MASK] = codegen_PFMIN, + [UOP_PFMUL & UOP_MASK] = codegen_PFMUL, + [UOP_PFRCP & UOP_MASK] = codegen_PFRCP, + [UOP_PFRSQRT & UOP_MASK] = codegen_PFRSQRT, + [UOP_PFSUB & UOP_MASK] = codegen_PFSUB, + [UOP_PI2FD & UOP_MASK] = codegen_PI2FD, + + [UOP_PMADDWD & UOP_MASK] = codegen_PMADDWD, + [UOP_PMULHW & UOP_MASK] = codegen_PMULHW, + [UOP_PMULLW & UOP_MASK] = codegen_PMULLW, + + [UOP_PSLLW_IMM & UOP_MASK] = codegen_PSLLW_IMM, + [UOP_PSLLD_IMM & UOP_MASK] = codegen_PSLLD_IMM, + [UOP_PSLLQ_IMM & UOP_MASK] = codegen_PSLLQ_IMM, + [UOP_PSRAW_IMM & UOP_MASK] = codegen_PSRAW_IMM, + [UOP_PSRAD_IMM & UOP_MASK] = codegen_PSRAD_IMM, + [UOP_PSRAQ_IMM & UOP_MASK] = codegen_PSRAQ_IMM, + [UOP_PSRLW_IMM & UOP_MASK] = codegen_PSRLW_IMM, + [UOP_PSRLD_IMM & UOP_MASK] = codegen_PSRLD_IMM, + [UOP_PSRLQ_IMM & UOP_MASK] = codegen_PSRLQ_IMM, + + [UOP_PSUBB & UOP_MASK] = codegen_PSUBB, + [UOP_PSUBW & UOP_MASK] = codegen_PSUBW, + [UOP_PSUBD & UOP_MASK] = codegen_PSUBD, + [UOP_PSUBSB & UOP_MASK] = codegen_PSUBSB, + [UOP_PSUBSW & UOP_MASK] = codegen_PSUBSW, + [UOP_PSUBUSB & UOP_MASK] = codegen_PSUBUSB, + [UOP_PSUBUSW & UOP_MASK] = codegen_PSUBUSW, + + [UOP_PUNPCKHBW & UOP_MASK] = codegen_PUNPCKHBW, + [UOP_PUNPCKHWD & UOP_MASK] = codegen_PUNPCKHWD, + [UOP_PUNPCKHDQ & UOP_MASK] = codegen_PUNPCKHDQ, + [UOP_PUNPCKLBW & UOP_MASK] = codegen_PUNPCKLBW, + [UOP_PUNPCKLWD & UOP_MASK] = codegen_PUNPCKLWD, + [UOP_PUNPCKLDQ & UOP_MASK] = codegen_PUNPCKLDQ, + + [UOP_NOP_BARRIER & UOP_MASK] = codegen_NOP}; + +void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p) { + if (in_range_h(p, &cpu_state)) + host_arm_LDRB_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); + else + fatal("codegen_direct_read_8 - not in range\n"); +} +void codegen_direct_read_16(codeblock_t *block, int host_reg, void *p) { + if (in_range_h(p, &cpu_state)) + host_arm_LDRH_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); + else { + host_arm_MOV_IMM(block, REG_R3, (uintptr_t)p - (uintptr_t)&cpu_state); + host_arm_LDRH_REG(block, host_reg, REG_CPUSTATE, REG_R3); + } +} +void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) { + if (in_range(p, &cpu_state)) + host_arm_LDR_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); + else + fatal("codegen_direct_read_32 - not in range\n"); +} +void codegen_direct_read_pointer(codeblock_t *block, int host_reg, void *p) { codegen_direct_read_32(block, host_reg, p); } +void codegen_direct_read_64(codeblock_t *block, int host_reg, void *p) { + host_arm_VLDR_D(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); +} +void codegen_direct_read_double(codeblock_t *block, int host_reg, void *p) { + host_arm_VLDR_D(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); +} +void codegen_direct_read_st_8(codeblock_t *block, int host_reg, void *base, int reg_idx) { + host_arm_LDR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset); + host_arm_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); + host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 7); + host_arm_ADD_REG_LSL(block, REG_TEMP, REG_CPUSTATE, REG_TEMP, 3); + host_arm_LDRB_IMM(block, host_reg, REG_TEMP, (uintptr_t)base - (uintptr_t)&cpu_state); +} +void codegen_direct_read_st_64(codeblock_t *block, int host_reg, void *base, int reg_idx) { + host_arm_LDR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset); + host_arm_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); + host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 7); + host_arm_ADD_REG_LSL(block, REG_TEMP, REG_CPUSTATE, REG_TEMP, 3); + host_arm_VLDR_D(block, host_reg, REG_TEMP, (uintptr_t)base - (uintptr_t)&cpu_state); +} +void codegen_direct_read_st_double(codeblock_t *block, int host_reg, void *base, int reg_idx) { + host_arm_LDR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset); + host_arm_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); + host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 7); + host_arm_ADD_REG_LSL(block, REG_TEMP, REG_CPUSTATE, REG_TEMP, 3); + host_arm_VLDR_D(block, host_reg, REG_TEMP, (uintptr_t)base - (uintptr_t)&cpu_state); +} + +void codegen_direct_write_8(codeblock_t *block, void *p, int host_reg) { + if (in_range(p, &cpu_state)) + host_arm_STRB_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); + else + fatal("codegen_direct_write_8 - not in range\n"); +} +void codegen_direct_write_16(codeblock_t *block, void *p, int host_reg) { + if (in_range_h(p, &cpu_state)) + host_arm_STRH_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); + else { + host_arm_MOV_IMM(block, REG_R3, (uintptr_t)p - (uintptr_t)&cpu_state); + host_arm_STRH_REG(block, host_reg, REG_CPUSTATE, REG_R3); + } +} +void codegen_direct_write_32(codeblock_t *block, void *p, int host_reg) { + if (in_range(p, &cpu_state)) + host_arm_STR_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); + else + fatal("codegen_direct_write_32 - not in range\n"); +} +void codegen_direct_write_64(codeblock_t *block, void *p, int host_reg) { + host_arm_VSTR_D(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); +} +void codegen_direct_write_double(codeblock_t *block, void *p, int host_reg) { + host_arm_VSTR_D(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); +} +void codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int host_reg) { + host_arm_LDR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset); + host_arm_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); + host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 7); + host_arm_ADD_REG_LSL(block, REG_TEMP, REG_CPUSTATE, REG_TEMP, 3); + host_arm_STRB_IMM(block, host_reg, REG_TEMP, (uintptr_t)base - (uintptr_t)&cpu_state); +} +void codegen_direct_write_st_64(codeblock_t *block, void *base, int reg_idx, int host_reg) { + host_arm_LDR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset); + host_arm_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); + host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 7); + host_arm_ADD_REG_LSL(block, REG_TEMP, REG_CPUSTATE, REG_TEMP, 3); + host_arm_VSTR_D(block, host_reg, REG_TEMP, (uintptr_t)base - (uintptr_t)&cpu_state); +} +void codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx, int host_reg) { + host_arm_LDR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset); + host_arm_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); + host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 7); + host_arm_ADD_REG_LSL(block, REG_TEMP, REG_CPUSTATE, REG_TEMP, 3); + host_arm_VSTR_D(block, host_reg, REG_TEMP, (uintptr_t)base - (uintptr_t)&cpu_state); +} + +void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg) { + if (in_range(p, &cpu_state)) + host_arm_STR_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); + else + fatal("codegen_direct_write_ptr - not in range\n"); +} + +void codegen_direct_read_16_stack(codeblock_t *block, int host_reg, int stack_offset) { + if (stack_offset >= 0 && stack_offset < 256) + host_arm_LDRH_IMM(block, host_reg, REG_HOST_SP, stack_offset); + else + fatal("codegen_direct_read_32 - not in range\n"); +} +void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_offset) { + if (stack_offset >= 0 && stack_offset < 4096) + host_arm_LDR_IMM(block, host_reg, REG_HOST_SP, stack_offset); + else + fatal("codegen_direct_read_32 - not in range\n"); +} +void codegen_direct_read_pointer_stack(codeblock_t *block, int host_reg, int stack_offset) { + codegen_direct_read_32_stack(block, host_reg, stack_offset); +} +void codegen_direct_read_64_stack(codeblock_t *block, int host_reg, int stack_offset) { + host_arm_VLDR_D(block, host_reg, REG_HOST_SP, stack_offset); +} +void codegen_direct_read_double_stack(codeblock_t *block, int host_reg, int stack_offset) { + host_arm_VLDR_D(block, host_reg, REG_HOST_SP, stack_offset); +} + +void codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int host_reg) { + if (stack_offset >= 0 && stack_offset < 4096) + host_arm_STR_IMM(block, host_reg, REG_HOST_SP, stack_offset); + else + fatal("codegen_direct_write_32 - not in range\n"); +} +void codegen_direct_write_64_stack(codeblock_t *block, int stack_offset, int host_reg) { + host_arm_VSTR_D(block, host_reg, REG_HOST_SP, stack_offset); +} +void codegen_direct_write_double_stack(codeblock_t *block, int stack_offset, int host_reg) { + host_arm_VSTR_D(block, host_reg, REG_HOST_SP, stack_offset); +} + +void codegen_set_jump_dest(codeblock_t *block, void *p) { + *(uint32_t *)p |= ((((uintptr_t)&block_write_data[block_pos] - (uintptr_t)p) - 8) & 0x3fffffc) >> 2; } #endif diff --git a/src/codegen/arm64/codegen_backend_arm64.c b/src/codegen/arm64/codegen_backend_arm64.c index d165bec1..9f4f3ee3 100644 --- a/src/codegen/arm64/codegen_backend_arm64.c +++ b/src/codegen/arm64/codegen_backend_arm64.c @@ -39,344 +39,310 @@ void *codegen_fp_round_quad; void *codegen_gpf_rout; void *codegen_exit_rout; -host_reg_def_t codegen_host_reg_list[CODEGEN_HOST_REGS] = -{ - {REG_X19, 0}, - {REG_X20, 0}, - {REG_X21, 0}, - {REG_X22, 0}, - {REG_X23, 0}, - {REG_X24, 0}, - {REG_X25, 0}, - {REG_X26, 0}, - {REG_X27, 0}, - {REG_X28, 0} -}; +host_reg_def_t codegen_host_reg_list[CODEGEN_HOST_REGS] = {{REG_X19, 0}, {REG_X20, 0}, {REG_X21, 0}, {REG_X22, 0}, {REG_X23, 0}, + {REG_X24, 0}, {REG_X25, 0}, {REG_X26, 0}, {REG_X27, 0}, {REG_X28, 0}}; -host_reg_def_t codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] = -{ - {REG_V8, 0}, - {REG_V9, 0}, - {REG_V10, 0}, - {REG_V11, 0}, - {REG_V12, 0}, - {REG_V13, 0}, - {REG_V14, 0}, - {REG_V15, 0} -}; +host_reg_def_t codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] = {{REG_V8, 0}, {REG_V9, 0}, {REG_V10, 0}, {REG_V11, 0}, + {REG_V12, 0}, {REG_V13, 0}, {REG_V14, 0}, {REG_V15, 0}}; -static void build_load_routine(codeblock_t *block, int size, int is_float) -{ - uint32_t *branch_offset; - uint32_t *misaligned_offset; - int offset; +static void build_load_routine(codeblock_t *block, int size, int is_float) { + uint32_t *branch_offset; + uint32_t *misaligned_offset; + int offset; - /*In - W0 = address - Out - W0 = data, W1 = abrt*/ - /*MOV W1, W0, LSR #12 - MOV X2, #readlookup2 - LDR X1, [X2, X1, LSL #3] - CMP X1, #-1 - BEQ + - LDRB W0, [X1, X0] - MOV W1, #0 - RET - * STP X29, X30, [SP, #-16] - BL readmembl - LDRB R1, cpu_state.abrt - LDP X29, X30, [SP, #-16] - RET - */ - codegen_alloc(block, 80); - host_arm64_MOV_REG_LSR(block, REG_W1, REG_W0, 12); - host_arm64_MOVX_IMM(block, REG_X2, (uint64_t)readlookup2); - host_arm64_LDRX_REG_LSL3(block, REG_X1, REG_X2, REG_X1); - if (size != 1) - { - host_arm64_TST_IMM(block, REG_W0, size-1); - misaligned_offset = host_arm64_BNE_(block); - } - host_arm64_CMPX_IMM(block, REG_X1, -1); - branch_offset = host_arm64_BEQ_(block); - if (size == 1 && !is_float) - host_arm64_LDRB_REG(block, REG_W0, REG_W1, REG_W0); - else if (size == 2 && !is_float) - host_arm64_LDRH_REG(block, REG_W0, REG_W1, REG_W0); - else if (size == 4 && !is_float) - host_arm64_LDR_REG(block, REG_W0, REG_W1, REG_W0); - else if (size == 4 && is_float) - host_arm64_LDR_REG_F32(block, REG_V_TEMP, REG_W1, REG_W0); - else if (size == 8) - host_arm64_LDR_REG_F64(block, REG_V_TEMP, REG_W1, REG_W0); - host_arm64_MOVZ_IMM(block, REG_W1, 0); - host_arm64_RET(block, REG_X30); + /*In - W0 = address + Out - W0 = data, W1 = abrt*/ + /*MOV W1, W0, LSR #12 + MOV X2, #readlookup2 + LDR X1, [X2, X1, LSL #3] + CMP X1, #-1 + BEQ + + LDRB W0, [X1, X0] + MOV W1, #0 + RET + * STP X29, X30, [SP, #-16] + BL readmembl + LDRB R1, cpu_state.abrt + LDP X29, X30, [SP, #-16] + RET + */ + codegen_alloc(block, 80); + host_arm64_MOV_REG_LSR(block, REG_W1, REG_W0, 12); + host_arm64_MOVX_IMM(block, REG_X2, (uint64_t)readlookup2); + host_arm64_LDRX_REG_LSL3(block, REG_X1, REG_X2, REG_X1); + if (size != 1) { + host_arm64_TST_IMM(block, REG_W0, size - 1); + misaligned_offset = host_arm64_BNE_(block); + } + host_arm64_CMPX_IMM(block, REG_X1, -1); + branch_offset = host_arm64_BEQ_(block); + if (size == 1 && !is_float) + host_arm64_LDRB_REG(block, REG_W0, REG_W1, REG_W0); + else if (size == 2 && !is_float) + host_arm64_LDRH_REG(block, REG_W0, REG_W1, REG_W0); + else if (size == 4 && !is_float) + host_arm64_LDR_REG(block, REG_W0, REG_W1, REG_W0); + else if (size == 4 && is_float) + host_arm64_LDR_REG_F32(block, REG_V_TEMP, REG_W1, REG_W0); + else if (size == 8) + host_arm64_LDR_REG_F64(block, REG_V_TEMP, REG_W1, REG_W0); + host_arm64_MOVZ_IMM(block, REG_W1, 0); + host_arm64_RET(block, REG_X30); - host_arm64_branch_set_offset(branch_offset, &block_write_data[block_pos]); - if (size != 1) - host_arm64_branch_set_offset(misaligned_offset, &block_write_data[block_pos]); - host_arm64_STP_PREIDX_X(block, REG_X29, REG_X30, REG_XSP, -16); - if (size == 1) - host_arm64_call(block, (void *)readmembl); - else if (size == 2) - host_arm64_call(block, (void *)readmemwl); - else if (size == 4) - host_arm64_call(block, (void *)readmemll); - else if (size == 8) - host_arm64_call(block, (void *)readmemql); - else - fatal("build_load_routine - unknown size %i\n", size); - codegen_direct_read_8(block, REG_W1, &cpu_state.abrt); - if (size == 4 && is_float) - host_arm64_FMOV_S_W(block, REG_V_TEMP, REG_W0); - else if (size == 8) - host_arm64_FMOV_D_Q(block, REG_V_TEMP, REG_X0); - host_arm64_LDP_POSTIDX_X(block, REG_X29, REG_X30, REG_XSP, 16); - host_arm64_RET(block, REG_X30); + host_arm64_branch_set_offset(branch_offset, &block_write_data[block_pos]); + if (size != 1) + host_arm64_branch_set_offset(misaligned_offset, &block_write_data[block_pos]); + host_arm64_STP_PREIDX_X(block, REG_X29, REG_X30, REG_XSP, -16); + if (size == 1) + host_arm64_call(block, (void *)readmembl); + else if (size == 2) + host_arm64_call(block, (void *)readmemwl); + else if (size == 4) + host_arm64_call(block, (void *)readmemll); + else if (size == 8) + host_arm64_call(block, (void *)readmemql); + else + fatal("build_load_routine - unknown size %i\n", size); + codegen_direct_read_8(block, REG_W1, &cpu_state.abrt); + if (size == 4 && is_float) + host_arm64_FMOV_S_W(block, REG_V_TEMP, REG_W0); + else if (size == 8) + host_arm64_FMOV_D_Q(block, REG_V_TEMP, REG_X0); + host_arm64_LDP_POSTIDX_X(block, REG_X29, REG_X30, REG_XSP, 16); + host_arm64_RET(block, REG_X30); } -static void build_store_routine(codeblock_t *block, int size, int is_float) -{ - uint32_t *branch_offset; - uint32_t *misaligned_offset; - int offset; +static void build_store_routine(codeblock_t *block, int size, int is_float) { + uint32_t *branch_offset; + uint32_t *misaligned_offset; + int offset; - /*In - R0 = address, R1 = data - Out - R1 = abrt*/ - /*MOV W2, W0, LSR #12 - MOV X3, #writelookup2 - LDR X2, [X3, X2, LSL #3] - CMP X2, #-1 - BEQ + - STRB W1, [X2, X0] - MOV W1, #0 - RET - * STP X29, X30, [SP, #-16] - BL writemembl - LDRB R1, cpu_state.abrt - LDP X29, X30, [SP, #-16] - RET - */ - codegen_alloc(block, 80); - host_arm64_MOV_REG_LSR(block, REG_W2, REG_W0, 12); - host_arm64_MOVX_IMM(block, REG_X3, (uint64_t)writelookup2); - host_arm64_LDRX_REG_LSL3(block, REG_X2, REG_X3, REG_X2); - if (size != 1) - { - host_arm64_TST_IMM(block, REG_W0, size-1); - misaligned_offset = host_arm64_BNE_(block); - } - host_arm64_CMPX_IMM(block, REG_X2, -1); - branch_offset = host_arm64_BEQ_(block); - if (size == 1 && !is_float) - host_arm64_STRB_REG(block, REG_X1, REG_X2, REG_X0); - else if (size == 2 && !is_float) - host_arm64_STRH_REG(block, REG_X1, REG_X2, REG_X0); - else if (size == 4 && !is_float) - host_arm64_STR_REG(block, REG_X1, REG_X2, REG_X0); - else if (size == 4 && is_float) - host_arm64_STR_REG_F32(block, REG_V_TEMP, REG_X2, REG_X0); - else if (size == 8) - host_arm64_STR_REG_F64(block, REG_V_TEMP, REG_X2, REG_X0); - host_arm64_MOVZ_IMM(block, REG_X1, 0); - host_arm64_RET(block, REG_X30); + /*In - R0 = address, R1 = data + Out - R1 = abrt*/ + /*MOV W2, W0, LSR #12 + MOV X3, #writelookup2 + LDR X2, [X3, X2, LSL #3] + CMP X2, #-1 + BEQ + + STRB W1, [X2, X0] + MOV W1, #0 + RET + * STP X29, X30, [SP, #-16] + BL writemembl + LDRB R1, cpu_state.abrt + LDP X29, X30, [SP, #-16] + RET + */ + codegen_alloc(block, 80); + host_arm64_MOV_REG_LSR(block, REG_W2, REG_W0, 12); + host_arm64_MOVX_IMM(block, REG_X3, (uint64_t)writelookup2); + host_arm64_LDRX_REG_LSL3(block, REG_X2, REG_X3, REG_X2); + if (size != 1) { + host_arm64_TST_IMM(block, REG_W0, size - 1); + misaligned_offset = host_arm64_BNE_(block); + } + host_arm64_CMPX_IMM(block, REG_X2, -1); + branch_offset = host_arm64_BEQ_(block); + if (size == 1 && !is_float) + host_arm64_STRB_REG(block, REG_X1, REG_X2, REG_X0); + else if (size == 2 && !is_float) + host_arm64_STRH_REG(block, REG_X1, REG_X2, REG_X0); + else if (size == 4 && !is_float) + host_arm64_STR_REG(block, REG_X1, REG_X2, REG_X0); + else if (size == 4 && is_float) + host_arm64_STR_REG_F32(block, REG_V_TEMP, REG_X2, REG_X0); + else if (size == 8) + host_arm64_STR_REG_F64(block, REG_V_TEMP, REG_X2, REG_X0); + host_arm64_MOVZ_IMM(block, REG_X1, 0); + host_arm64_RET(block, REG_X30); - host_arm64_branch_set_offset(branch_offset, &block_write_data[block_pos]); - if (size != 1) - host_arm64_branch_set_offset(misaligned_offset, &block_write_data[block_pos]); - host_arm64_STP_PREIDX_X(block, REG_X29, REG_X30, REG_XSP, -16); - if (size == 4 && is_float) - host_arm64_FMOV_W_S(block, REG_W1, REG_V_TEMP); - else if (size == 8) - host_arm64_FMOV_Q_D(block, REG_X1, REG_V_TEMP); - if (size == 1) - host_arm64_call(block, (void *)writemembl); - else if (size == 2) - host_arm64_call(block, (void *)writememwl); - else if (size == 4) - host_arm64_call(block, (void *)writememll); - else if (size == 8) - host_arm64_call(block, (void *)writememql); - else - fatal("build_store_routine - unknown size %i\n", size); - codegen_direct_read_8(block, REG_W1, &cpu_state.abrt); - host_arm64_LDP_POSTIDX_X(block, REG_X29, REG_X30, REG_XSP, 16); - host_arm64_RET(block, REG_X30); + host_arm64_branch_set_offset(branch_offset, &block_write_data[block_pos]); + if (size != 1) + host_arm64_branch_set_offset(misaligned_offset, &block_write_data[block_pos]); + host_arm64_STP_PREIDX_X(block, REG_X29, REG_X30, REG_XSP, -16); + if (size == 4 && is_float) + host_arm64_FMOV_W_S(block, REG_W1, REG_V_TEMP); + else if (size == 8) + host_arm64_FMOV_Q_D(block, REG_X1, REG_V_TEMP); + if (size == 1) + host_arm64_call(block, (void *)writemembl); + else if (size == 2) + host_arm64_call(block, (void *)writememwl); + else if (size == 4) + host_arm64_call(block, (void *)writememll); + else if (size == 8) + host_arm64_call(block, (void *)writememql); + else + fatal("build_store_routine - unknown size %i\n", size); + codegen_direct_read_8(block, REG_W1, &cpu_state.abrt); + host_arm64_LDP_POSTIDX_X(block, REG_X29, REG_X30, REG_XSP, 16); + host_arm64_RET(block, REG_X30); } -static void build_loadstore_routines(codeblock_t *block) -{ - codegen_mem_load_byte = &block_write_data[block_pos]; - build_load_routine(block, 1, 0); - codegen_mem_load_word = &block_write_data[block_pos]; - build_load_routine(block, 2, 0); - codegen_mem_load_long = &block_write_data[block_pos]; - build_load_routine(block, 4, 0); - codegen_mem_load_quad = &block_write_data[block_pos]; - build_load_routine(block, 8, 0); - codegen_mem_load_single = &block_write_data[block_pos]; - build_load_routine(block, 4, 1); - codegen_mem_load_double = &block_write_data[block_pos]; - build_load_routine(block, 8, 1); +static void build_loadstore_routines(codeblock_t *block) { + codegen_mem_load_byte = &block_write_data[block_pos]; + build_load_routine(block, 1, 0); + codegen_mem_load_word = &block_write_data[block_pos]; + build_load_routine(block, 2, 0); + codegen_mem_load_long = &block_write_data[block_pos]; + build_load_routine(block, 4, 0); + codegen_mem_load_quad = &block_write_data[block_pos]; + build_load_routine(block, 8, 0); + codegen_mem_load_single = &block_write_data[block_pos]; + build_load_routine(block, 4, 1); + codegen_mem_load_double = &block_write_data[block_pos]; + build_load_routine(block, 8, 1); - codegen_mem_store_byte = &block_write_data[block_pos]; - build_store_routine(block, 1, 0); - codegen_mem_store_word = &block_write_data[block_pos]; - build_store_routine(block, 2, 0); - codegen_mem_store_long = &block_write_data[block_pos]; - build_store_routine(block, 4, 0); - codegen_mem_store_quad = &block_write_data[block_pos]; - build_store_routine(block, 8, 0); - codegen_mem_store_single = &block_write_data[block_pos]; - build_store_routine(block, 4, 1); - codegen_mem_store_double = &block_write_data[block_pos]; - build_store_routine(block, 8, 1); + codegen_mem_store_byte = &block_write_data[block_pos]; + build_store_routine(block, 1, 0); + codegen_mem_store_word = &block_write_data[block_pos]; + build_store_routine(block, 2, 0); + codegen_mem_store_long = &block_write_data[block_pos]; + build_store_routine(block, 4, 0); + codegen_mem_store_quad = &block_write_data[block_pos]; + build_store_routine(block, 8, 0); + codegen_mem_store_single = &block_write_data[block_pos]; + build_store_routine(block, 4, 1); + codegen_mem_store_double = &block_write_data[block_pos]; + build_store_routine(block, 8, 1); } -static void build_fp_round_routine(codeblock_t *block, int is_quad) -{ - uint64_t *jump_table; +static void build_fp_round_routine(codeblock_t *block, int is_quad) { + uint64_t *jump_table; - codegen_alloc(block, 80); - host_arm64_LDR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.new_fp_control - (uintptr_t)&cpu_state); - host_arm64_ADR(block, REG_TEMP2, 12); - host_arm64_LDR_REG_X(block, REG_TEMP2, REG_TEMP2, REG_TEMP); - host_arm64_BR(block, REG_TEMP2); + codegen_alloc(block, 80); + host_arm64_LDR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.new_fp_control - (uintptr_t)&cpu_state); + host_arm64_ADR(block, REG_TEMP2, 12); + host_arm64_LDR_REG_X(block, REG_TEMP2, REG_TEMP2, REG_TEMP); + host_arm64_BR(block, REG_TEMP2); - jump_table = (uint64_t *)&block_write_data[block_pos]; - block_pos += 4*8; + jump_table = (uint64_t *)&block_write_data[block_pos]; + block_pos += 4 * 8; - jump_table[X87_ROUNDING_NEAREST] = (uint64_t)(uintptr_t)&block_write_data[block_pos]; //tie even - if (is_quad) - host_arm64_FCVTNS_X_D(block, REG_TEMP, REG_V_TEMP); - else - host_arm64_FCVTNS_W_D(block, REG_TEMP, REG_V_TEMP); - host_arm64_RET(block, REG_X30); + jump_table[X87_ROUNDING_NEAREST] = (uint64_t)(uintptr_t)&block_write_data[block_pos]; // tie even + if (is_quad) + host_arm64_FCVTNS_X_D(block, REG_TEMP, REG_V_TEMP); + else + host_arm64_FCVTNS_W_D(block, REG_TEMP, REG_V_TEMP); + host_arm64_RET(block, REG_X30); - jump_table[X87_ROUNDING_UP] = (uint64_t)(uintptr_t)&block_write_data[block_pos]; //pos inf - if (is_quad) - host_arm64_FCVTPS_X_D(block, REG_TEMP, REG_V_TEMP); - else - host_arm64_FCVTPS_W_D(block, REG_TEMP, REG_V_TEMP); - host_arm64_RET(block, REG_X30); + jump_table[X87_ROUNDING_UP] = (uint64_t)(uintptr_t)&block_write_data[block_pos]; // pos inf + if (is_quad) + host_arm64_FCVTPS_X_D(block, REG_TEMP, REG_V_TEMP); + else + host_arm64_FCVTPS_W_D(block, REG_TEMP, REG_V_TEMP); + host_arm64_RET(block, REG_X30); - jump_table[X87_ROUNDING_DOWN] = (uint64_t)(uintptr_t)&block_write_data[block_pos]; //neg inf - if (is_quad) - host_arm64_FCVTMS_X_D(block, REG_TEMP, REG_V_TEMP); - else - host_arm64_FCVTMS_W_D(block, REG_TEMP, REG_V_TEMP); - host_arm64_RET(block, REG_X30); + jump_table[X87_ROUNDING_DOWN] = (uint64_t)(uintptr_t)&block_write_data[block_pos]; // neg inf + if (is_quad) + host_arm64_FCVTMS_X_D(block, REG_TEMP, REG_V_TEMP); + else + host_arm64_FCVTMS_W_D(block, REG_TEMP, REG_V_TEMP); + host_arm64_RET(block, REG_X30); - jump_table[X87_ROUNDING_CHOP] = (uint64_t)(uintptr_t)&block_write_data[block_pos]; //zero - if (is_quad) - host_arm64_FCVTZS_X_D(block, REG_TEMP, REG_V_TEMP); - else - host_arm64_FCVTZS_W_D(block, REG_TEMP, REG_V_TEMP); - host_arm64_RET(block, REG_X30); + jump_table[X87_ROUNDING_CHOP] = (uint64_t)(uintptr_t)&block_write_data[block_pos]; // zero + if (is_quad) + host_arm64_FCVTZS_X_D(block, REG_TEMP, REG_V_TEMP); + else + host_arm64_FCVTZS_W_D(block, REG_TEMP, REG_V_TEMP); + host_arm64_RET(block, REG_X30); } -void codegen_backend_init() -{ - codeblock_t *block; - int c; +void codegen_backend_init() { + codeblock_t *block; + int c; #if defined(__linux__) || defined(__APPLE__) - void *start; - size_t len; - long pagesize = sysconf(_SC_PAGESIZE); - long pagemask = ~(pagesize - 1); + void *start; + size_t len; + long pagesize = sysconf(_SC_PAGESIZE); + long pagemask = ~(pagesize - 1); #endif - codeblock = malloc(BLOCK_SIZE * sizeof(codeblock_t)); - codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); + codeblock = malloc(BLOCK_SIZE * sizeof(codeblock_t)); + 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 *)); + 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].pc = BLOCK_PC_INVALID; - } + for (c = 0; c < BLOCK_SIZE; c++) { + codeblock[c].pc = BLOCK_PC_INVALID; + } -// pclog("Codegen is %p\n", (void *)pages[0xfab12 >> 12].block); + // pclog("Codegen is %p\n", (void *)pages[0xfab12 >> 12].block); - block_current = 0; - block_pos = 0; - block = &codeblock[block_current]; - block->head_mem_block = codegen_allocator_allocate(NULL, block_current); - block->data = codeblock_allocator_get_ptr(block->head_mem_block); - block_write_data = block->data; - build_loadstore_routines(block); + block_current = 0; + block_pos = 0; + block = &codeblock[block_current]; + block->head_mem_block = codegen_allocator_allocate(NULL, block_current); + block->data = codeblock_allocator_get_ptr(block->head_mem_block); + block_write_data = block->data; + build_loadstore_routines(block); - codegen_fp_round = &block_write_data[block_pos]; - build_fp_round_routine(block, 0); - codegen_fp_round_quad = &block_write_data[block_pos]; - build_fp_round_routine(block, 1); + codegen_fp_round = &block_write_data[block_pos]; + build_fp_round_routine(block, 0); + codegen_fp_round_quad = &block_write_data[block_pos]; + build_fp_round_routine(block, 1); - codegen_alloc(block, 80); - codegen_gpf_rout = &block_write_data[block_pos]; - host_arm64_mov_imm(block, REG_ARG0, 0); - host_arm64_mov_imm(block, REG_ARG1, 0); - host_arm64_call(block, (void *)x86gpf); + codegen_alloc(block, 80); + codegen_gpf_rout = &block_write_data[block_pos]; + host_arm64_mov_imm(block, REG_ARG0, 0); + host_arm64_mov_imm(block, REG_ARG1, 0); + host_arm64_call(block, (void *)x86gpf); - codegen_exit_rout = &block_write_data[block_pos]; - host_arm64_LDP_POSTIDX_X(block, REG_X19, REG_X20, REG_XSP, 64); - host_arm64_LDP_POSTIDX_X(block, REG_X21, REG_X22, REG_XSP, 16); - host_arm64_LDP_POSTIDX_X(block, REG_X23, REG_X24, REG_XSP, 16); - host_arm64_LDP_POSTIDX_X(block, REG_X25, REG_X26, REG_XSP, 16); - host_arm64_LDP_POSTIDX_X(block, REG_X27, REG_X28, REG_XSP, 16); - host_arm64_LDP_POSTIDX_X(block, REG_X29, REG_X30, REG_XSP, 16); - host_arm64_RET(block, REG_X30); + codegen_exit_rout = &block_write_data[block_pos]; + host_arm64_LDP_POSTIDX_X(block, REG_X19, REG_X20, REG_XSP, 64); + host_arm64_LDP_POSTIDX_X(block, REG_X21, REG_X22, REG_XSP, 16); + host_arm64_LDP_POSTIDX_X(block, REG_X23, REG_X24, REG_XSP, 16); + host_arm64_LDP_POSTIDX_X(block, REG_X25, REG_X26, REG_XSP, 16); + host_arm64_LDP_POSTIDX_X(block, REG_X27, REG_X28, REG_XSP, 16); + host_arm64_LDP_POSTIDX_X(block, REG_X29, REG_X30, REG_XSP, 16); + host_arm64_RET(block, REG_X30); - block_write_data = NULL; + block_write_data = NULL; - codegen_allocator_clean_blocks(block->head_mem_block); + codegen_allocator_clean_blocks(block->head_mem_block); - asm("mrs %0, fpcr\n" - : "=r" (cpu_state.old_fp_control) - ); + asm("mrs %0, fpcr\n" : "=r"(cpu_state.old_fp_control)); } -void codegen_set_rounding_mode(int mode) -{ - if (mode < 0 || mode > 3) - fatal("codegen_set_rounding_mode - invalid mode\n"); - cpu_state.new_fp_control = mode << 3; +void codegen_set_rounding_mode(int mode) { + if (mode < 0 || mode > 3) + fatal("codegen_set_rounding_mode - invalid mode\n"); + cpu_state.new_fp_control = mode << 3; } /*R10 - cpu_state*/ -void codegen_backend_prologue(codeblock_t *block) -{ - block_pos = BLOCK_START; +void codegen_backend_prologue(codeblock_t *block) { + block_pos = BLOCK_START; - /*Entry code*/ + /*Entry code*/ - host_arm64_STP_PREIDX_X(block, REG_X29, REG_X30, REG_XSP, -16); - host_arm64_STP_PREIDX_X(block, REG_X27, REG_X28, REG_XSP, -16); - host_arm64_STP_PREIDX_X(block, REG_X25, REG_X26, REG_XSP, -16); - host_arm64_STP_PREIDX_X(block, REG_X23, REG_X24, REG_XSP, -16); - host_arm64_STP_PREIDX_X(block, REG_X21, REG_X22, REG_XSP, -16); - host_arm64_STP_PREIDX_X(block, REG_X19, REG_X20, REG_XSP, -64); + host_arm64_STP_PREIDX_X(block, REG_X29, REG_X30, REG_XSP, -16); + host_arm64_STP_PREIDX_X(block, REG_X27, REG_X28, REG_XSP, -16); + host_arm64_STP_PREIDX_X(block, REG_X25, REG_X26, REG_XSP, -16); + host_arm64_STP_PREIDX_X(block, REG_X23, REG_X24, REG_XSP, -16); + host_arm64_STP_PREIDX_X(block, REG_X21, REG_X22, REG_XSP, -16); + host_arm64_STP_PREIDX_X(block, REG_X19, REG_X20, REG_XSP, -64); - host_arm64_MOVX_IMM(block, REG_CPUSTATE, (uint64_t)&cpu_state); + host_arm64_MOVX_IMM(block, REG_CPUSTATE, (uint64_t)&cpu_state); - if (block->flags & CODEBLOCK_HAS_FPU) - { - host_arm64_LDR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.TOP - (uintptr_t)&cpu_state); - host_arm64_SUB_IMM(block, REG_TEMP, REG_TEMP, block->TOP); - host_arm64_STR_IMM_W(block, REG_TEMP, REG_XSP, IREG_TOP_diff_stack_offset); - } + if (block->flags & CODEBLOCK_HAS_FPU) { + host_arm64_LDR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.TOP - (uintptr_t)&cpu_state); + host_arm64_SUB_IMM(block, REG_TEMP, REG_TEMP, block->TOP); + host_arm64_STR_IMM_W(block, REG_TEMP, REG_XSP, IREG_TOP_diff_stack_offset); + } } -void codegen_backend_epilogue(codeblock_t *block) -{ - host_arm64_LDP_POSTIDX_X(block, REG_X19, REG_X20, REG_XSP, 64); - host_arm64_LDP_POSTIDX_X(block, REG_X21, REG_X22, REG_XSP, 16); - host_arm64_LDP_POSTIDX_X(block, REG_X23, REG_X24, REG_XSP, 16); - host_arm64_LDP_POSTIDX_X(block, REG_X25, REG_X26, REG_XSP, 16); - host_arm64_LDP_POSTIDX_X(block, REG_X27, REG_X28, REG_XSP, 16); - host_arm64_LDP_POSTIDX_X(block, REG_X29, REG_X30, REG_XSP, 16); - host_arm64_RET(block, REG_X30); +void codegen_backend_epilogue(codeblock_t *block) { + host_arm64_LDP_POSTIDX_X(block, REG_X19, REG_X20, REG_XSP, 64); + host_arm64_LDP_POSTIDX_X(block, REG_X21, REG_X22, REG_XSP, 16); + host_arm64_LDP_POSTIDX_X(block, REG_X23, REG_X24, REG_XSP, 16); + host_arm64_LDP_POSTIDX_X(block, REG_X25, REG_X26, REG_XSP, 16); + host_arm64_LDP_POSTIDX_X(block, REG_X27, REG_X28, REG_XSP, 16); + host_arm64_LDP_POSTIDX_X(block, REG_X29, REG_X30, REG_XSP, 16); + host_arm64_RET(block, REG_X30); - codegen_allocator_clean_blocks(block->head_mem_block); + codegen_allocator_clean_blocks(block->head_mem_block); } #endif diff --git a/src/codegen/arm64/codegen_backend_arm64_imm.c b/src/codegen/arm64/codegen_backend_arm64_imm.c index fcf9ab3a..530caff8 100644 --- a/src/codegen/arm64/codegen_backend_arm64_imm.c +++ b/src/codegen/arm64/codegen_backend_arm64_imm.c @@ -5,1324 +5,282 @@ All valid values are in the table below, which we perform a binary search over*/ #define IMM_NR 1302 -static uint32_t imm_table[][2] = - { - {0x800, 0x00000001}, - {0xfc0, 0x00000002}, - {0x801, 0x00000003}, - {0xf80, 0x00000004}, - {0xfc1, 0x00000006}, - {0x802, 0x00000007}, - {0xf40, 0x00000008}, - {0xf81, 0x0000000c}, - {0xfc2, 0x0000000e}, - {0x803, 0x0000000f}, - {0xf00, 0x00000010}, - {0xf41, 0x00000018}, - {0xf82, 0x0000001c}, - {0xfc3, 0x0000001e}, - {0x804, 0x0000001f}, - {0xec0, 0x00000020}, - {0xf01, 0x00000030}, - {0xf42, 0x00000038}, - {0xf83, 0x0000003c}, - {0xfc4, 0x0000003e}, - {0x805, 0x0000003f}, - {0xe80, 0x00000040}, - {0xec1, 0x00000060}, - {0xf02, 0x00000070}, - {0xf43, 0x00000078}, - {0xf84, 0x0000007c}, - {0xfc5, 0x0000007e}, - {0x806, 0x0000007f}, - {0xe40, 0x00000080}, - {0xe81, 0x000000c0}, - {0xec2, 0x000000e0}, - {0xf03, 0x000000f0}, - {0xf44, 0x000000f8}, - {0xf85, 0x000000fc}, - {0xfc6, 0x000000fe}, - {0x807, 0x000000ff}, - {0xe00, 0x00000100}, - {0xe41, 0x00000180}, - {0xe82, 0x000001c0}, - {0xec3, 0x000001e0}, - {0xf04, 0x000001f0}, - {0xf45, 0x000001f8}, - {0xf86, 0x000001fc}, - {0xfc7, 0x000001fe}, - {0x808, 0x000001ff}, - {0xdc0, 0x00000200}, - {0xe01, 0x00000300}, - {0xe42, 0x00000380}, - {0xe83, 0x000003c0}, - {0xec4, 0x000003e0}, - {0xf05, 0x000003f0}, - {0xf46, 0x000003f8}, - {0xf87, 0x000003fc}, - {0xfc8, 0x000003fe}, - {0x809, 0x000003ff}, - {0xd80, 0x00000400}, - {0xdc1, 0x00000600}, - {0xe02, 0x00000700}, - {0xe43, 0x00000780}, - {0xe84, 0x000007c0}, - {0xec5, 0x000007e0}, - {0xf06, 0x000007f0}, - {0xf47, 0x000007f8}, - {0xf88, 0x000007fc}, - {0xfc9, 0x000007fe}, - {0x80a, 0x000007ff}, - {0xd40, 0x00000800}, - {0xd81, 0x00000c00}, - {0xdc2, 0x00000e00}, - {0xe03, 0x00000f00}, - {0xe44, 0x00000f80}, - {0xe85, 0x00000fc0}, - {0xec6, 0x00000fe0}, - {0xf07, 0x00000ff0}, - {0xf48, 0x00000ff8}, - {0xf89, 0x00000ffc}, - {0xfca, 0x00000ffe}, - {0x80b, 0x00000fff}, - {0xd00, 0x00001000}, - {0xd41, 0x00001800}, - {0xd82, 0x00001c00}, - {0xdc3, 0x00001e00}, - {0xe04, 0x00001f00}, - {0xe45, 0x00001f80}, - {0xe86, 0x00001fc0}, - {0xec7, 0x00001fe0}, - {0xf08, 0x00001ff0}, - {0xf49, 0x00001ff8}, - {0xf8a, 0x00001ffc}, - {0xfcb, 0x00001ffe}, - {0x80c, 0x00001fff}, - {0xcc0, 0x00002000}, - {0xd01, 0x00003000}, - {0xd42, 0x00003800}, - {0xd83, 0x00003c00}, - {0xdc4, 0x00003e00}, - {0xe05, 0x00003f00}, - {0xe46, 0x00003f80}, - {0xe87, 0x00003fc0}, - {0xec8, 0x00003fe0}, - {0xf09, 0x00003ff0}, - {0xf4a, 0x00003ff8}, - {0xf8b, 0x00003ffc}, - {0xfcc, 0x00003ffe}, - {0x80d, 0x00003fff}, - {0xc80, 0x00004000}, - {0xcc1, 0x00006000}, - {0xd02, 0x00007000}, - {0xd43, 0x00007800}, - {0xd84, 0x00007c00}, - {0xdc5, 0x00007e00}, - {0xe06, 0x00007f00}, - {0xe47, 0x00007f80}, - {0xe88, 0x00007fc0}, - {0xec9, 0x00007fe0}, - {0xf0a, 0x00007ff0}, - {0xf4b, 0x00007ff8}, - {0xf8c, 0x00007ffc}, - {0xfcd, 0x00007ffe}, - {0x80e, 0x00007fff}, - {0xc40, 0x00008000}, - {0xc81, 0x0000c000}, - {0xcc2, 0x0000e000}, - {0xd03, 0x0000f000}, - {0xd44, 0x0000f800}, - {0xd85, 0x0000fc00}, - {0xdc6, 0x0000fe00}, - {0xe07, 0x0000ff00}, - {0xe48, 0x0000ff80}, - {0xe89, 0x0000ffc0}, - {0xeca, 0x0000ffe0}, - {0xf0b, 0x0000fff0}, - {0xf4c, 0x0000fff8}, - {0xf8d, 0x0000fffc}, - {0xfce, 0x0000fffe}, - {0x80f, 0x0000ffff}, - {0xc00, 0x00010000}, - {0xc20, 0x00010001}, - {0xc41, 0x00018000}, - {0xc82, 0x0001c000}, - {0xcc3, 0x0001e000}, - {0xd04, 0x0001f000}, - {0xd45, 0x0001f800}, - {0xd86, 0x0001fc00}, - {0xdc7, 0x0001fe00}, - {0xe08, 0x0001ff00}, - {0xe49, 0x0001ff80}, - {0xe8a, 0x0001ffc0}, - {0xecb, 0x0001ffe0}, - {0xf0c, 0x0001fff0}, - {0xf4d, 0x0001fff8}, - {0xf8e, 0x0001fffc}, - {0xfcf, 0x0001fffe}, - {0x810, 0x0001ffff}, - {0xbc0, 0x00020000}, - {0xfe0, 0x00020002}, - {0xc01, 0x00030000}, - {0xc21, 0x00030003}, - {0xc42, 0x00038000}, - {0xc83, 0x0003c000}, - {0xcc4, 0x0003e000}, - {0xd05, 0x0003f000}, - {0xd46, 0x0003f800}, - {0xd87, 0x0003fc00}, - {0xdc8, 0x0003fe00}, - {0xe09, 0x0003ff00}, - {0xe4a, 0x0003ff80}, - {0xe8b, 0x0003ffc0}, - {0xecc, 0x0003ffe0}, - {0xf0d, 0x0003fff0}, - {0xf4e, 0x0003fff8}, - {0xf8f, 0x0003fffc}, - {0xfd0, 0x0003fffe}, - {0x811, 0x0003ffff}, - {0xb80, 0x00040000}, - {0xfa0, 0x00040004}, - {0xbc1, 0x00060000}, - {0xfe1, 0x00060006}, - {0xc02, 0x00070000}, - {0xc22, 0x00070007}, - {0xc43, 0x00078000}, - {0xc84, 0x0007c000}, - {0xcc5, 0x0007e000}, - {0xd06, 0x0007f000}, - {0xd47, 0x0007f800}, - {0xd88, 0x0007fc00}, - {0xdc9, 0x0007fe00}, - {0xe0a, 0x0007ff00}, - {0xe4b, 0x0007ff80}, - {0xe8c, 0x0007ffc0}, - {0xecd, 0x0007ffe0}, - {0xf0e, 0x0007fff0}, - {0xf4f, 0x0007fff8}, - {0xf90, 0x0007fffc}, - {0xfd1, 0x0007fffe}, - {0x812, 0x0007ffff}, - {0xb40, 0x00080000}, - {0xf60, 0x00080008}, - {0xb81, 0x000c0000}, - {0xfa1, 0x000c000c}, - {0xbc2, 0x000e0000}, - {0xfe2, 0x000e000e}, - {0xc03, 0x000f0000}, - {0xc23, 0x000f000f}, - {0xc44, 0x000f8000}, - {0xc85, 0x000fc000}, - {0xcc6, 0x000fe000}, - {0xd07, 0x000ff000}, - {0xd48, 0x000ff800}, - {0xd89, 0x000ffc00}, - {0xdca, 0x000ffe00}, - {0xe0b, 0x000fff00}, - {0xe4c, 0x000fff80}, - {0xe8d, 0x000fffc0}, - {0xece, 0x000fffe0}, - {0xf0f, 0x000ffff0}, - {0xf50, 0x000ffff8}, - {0xf91, 0x000ffffc}, - {0xfd2, 0x000ffffe}, - {0x813, 0x000fffff}, - {0xb00, 0x00100000}, - {0xf20, 0x00100010}, - {0xb41, 0x00180000}, - {0xf61, 0x00180018}, - {0xb82, 0x001c0000}, - {0xfa2, 0x001c001c}, - {0xbc3, 0x001e0000}, - {0xfe3, 0x001e001e}, - {0xc04, 0x001f0000}, - {0xc24, 0x001f001f}, - {0xc45, 0x001f8000}, - {0xc86, 0x001fc000}, - {0xcc7, 0x001fe000}, - {0xd08, 0x001ff000}, - {0xd49, 0x001ff800}, - {0xd8a, 0x001ffc00}, - {0xdcb, 0x001ffe00}, - {0xe0c, 0x001fff00}, - {0xe4d, 0x001fff80}, - {0xe8e, 0x001fffc0}, - {0xecf, 0x001fffe0}, - {0xf10, 0x001ffff0}, - {0xf51, 0x001ffff8}, - {0xf92, 0x001ffffc}, - {0xfd3, 0x001ffffe}, - {0x814, 0x001fffff}, - {0xac0, 0x00200000}, - {0xee0, 0x00200020}, - {0xb01, 0x00300000}, - {0xf21, 0x00300030}, - {0xb42, 0x00380000}, - {0xf62, 0x00380038}, - {0xb83, 0x003c0000}, - {0xfa3, 0x003c003c}, - {0xbc4, 0x003e0000}, - {0xfe4, 0x003e003e}, - {0xc05, 0x003f0000}, - {0xc25, 0x003f003f}, - {0xc46, 0x003f8000}, - {0xc87, 0x003fc000}, - {0xcc8, 0x003fe000}, - {0xd09, 0x003ff000}, - {0xd4a, 0x003ff800}, - {0xd8b, 0x003ffc00}, - {0xdcc, 0x003ffe00}, - {0xe0d, 0x003fff00}, - {0xe4e, 0x003fff80}, - {0xe8f, 0x003fffc0}, - {0xed0, 0x003fffe0}, - {0xf11, 0x003ffff0}, - {0xf52, 0x003ffff8}, - {0xf93, 0x003ffffc}, - {0xfd4, 0x003ffffe}, - {0x815, 0x003fffff}, - {0xa80, 0x00400000}, - {0xea0, 0x00400040}, - {0xac1, 0x00600000}, - {0xee1, 0x00600060}, - {0xb02, 0x00700000}, - {0xf22, 0x00700070}, - {0xb43, 0x00780000}, - {0xf63, 0x00780078}, - {0xb84, 0x007c0000}, - {0xfa4, 0x007c007c}, - {0xbc5, 0x007e0000}, - {0xfe5, 0x007e007e}, - {0xc06, 0x007f0000}, - {0xc26, 0x007f007f}, - {0xc47, 0x007f8000}, - {0xc88, 0x007fc000}, - {0xcc9, 0x007fe000}, - {0xd0a, 0x007ff000}, - {0xd4b, 0x007ff800}, - {0xd8c, 0x007ffc00}, - {0xdcd, 0x007ffe00}, - {0xe0e, 0x007fff00}, - {0xe4f, 0x007fff80}, - {0xe90, 0x007fffc0}, - {0xed1, 0x007fffe0}, - {0xf12, 0x007ffff0}, - {0xf53, 0x007ffff8}, - {0xf94, 0x007ffffc}, - {0xfd5, 0x007ffffe}, - {0x816, 0x007fffff}, - {0xa40, 0x00800000}, - {0xe60, 0x00800080}, - {0xa81, 0x00c00000}, - {0xea1, 0x00c000c0}, - {0xac2, 0x00e00000}, - {0xee2, 0x00e000e0}, - {0xb03, 0x00f00000}, - {0xf23, 0x00f000f0}, - {0xb44, 0x00f80000}, - {0xf64, 0x00f800f8}, - {0xb85, 0x00fc0000}, - {0xfa5, 0x00fc00fc}, - {0xbc6, 0x00fe0000}, - {0xfe6, 0x00fe00fe}, - {0xc07, 0x00ff0000}, - {0xc27, 0x00ff00ff}, - {0xc48, 0x00ff8000}, - {0xc89, 0x00ffc000}, - {0xcca, 0x00ffe000}, - {0xd0b, 0x00fff000}, - {0xd4c, 0x00fff800}, - {0xd8d, 0x00fffc00}, - {0xdce, 0x00fffe00}, - {0xe0f, 0x00ffff00}, - {0xe50, 0x00ffff80}, - {0xe91, 0x00ffffc0}, - {0xed2, 0x00ffffe0}, - {0xf13, 0x00fffff0}, - {0xf54, 0x00fffff8}, - {0xf95, 0x00fffffc}, - {0xfd6, 0x00fffffe}, - {0x817, 0x00ffffff}, - {0xa00, 0x01000000}, - {0xe20, 0x01000100}, - {0xe30, 0x01010101}, - {0xa41, 0x01800000}, - {0xe61, 0x01800180}, - {0xa82, 0x01c00000}, - {0xea2, 0x01c001c0}, - {0xac3, 0x01e00000}, - {0xee3, 0x01e001e0}, - {0xb04, 0x01f00000}, - {0xf24, 0x01f001f0}, - {0xb45, 0x01f80000}, - {0xf65, 0x01f801f8}, - {0xb86, 0x01fc0000}, - {0xfa6, 0x01fc01fc}, - {0xbc7, 0x01fe0000}, - {0xfe7, 0x01fe01fe}, - {0xc08, 0x01ff0000}, - {0xc28, 0x01ff01ff}, - {0xc49, 0x01ff8000}, - {0xc8a, 0x01ffc000}, - {0xccb, 0x01ffe000}, - {0xd0c, 0x01fff000}, - {0xd4d, 0x01fff800}, - {0xd8e, 0x01fffc00}, - {0xdcf, 0x01fffe00}, - {0xe10, 0x01ffff00}, - {0xe51, 0x01ffff80}, - {0xe92, 0x01ffffc0}, - {0xed3, 0x01ffffe0}, - {0xf14, 0x01fffff0}, - {0xf55, 0x01fffff8}, - {0xf96, 0x01fffffc}, - {0xfd7, 0x01fffffe}, - {0x818, 0x01ffffff}, - {0x9c0, 0x02000000}, - {0xde0, 0x02000200}, - {0xff0, 0x02020202}, - {0xa01, 0x03000000}, - {0xe21, 0x03000300}, - {0xe31, 0x03030303}, - {0xa42, 0x03800000}, - {0xe62, 0x03800380}, - {0xa83, 0x03c00000}, - {0xea3, 0x03c003c0}, - {0xac4, 0x03e00000}, - {0xee4, 0x03e003e0}, - {0xb05, 0x03f00000}, - {0xf25, 0x03f003f0}, - {0xb46, 0x03f80000}, - {0xf66, 0x03f803f8}, - {0xb87, 0x03fc0000}, - {0xfa7, 0x03fc03fc}, - {0xbc8, 0x03fe0000}, - {0xfe8, 0x03fe03fe}, - {0xc09, 0x03ff0000}, - {0xc29, 0x03ff03ff}, - {0xc4a, 0x03ff8000}, - {0xc8b, 0x03ffc000}, - {0xccc, 0x03ffe000}, - {0xd0d, 0x03fff000}, - {0xd4e, 0x03fff800}, - {0xd8f, 0x03fffc00}, - {0xdd0, 0x03fffe00}, - {0xe11, 0x03ffff00}, - {0xe52, 0x03ffff80}, - {0xe93, 0x03ffffc0}, - {0xed4, 0x03ffffe0}, - {0xf15, 0x03fffff0}, - {0xf56, 0x03fffff8}, - {0xf97, 0x03fffffc}, - {0xfd8, 0x03fffffe}, - {0x819, 0x03ffffff}, - {0x980, 0x04000000}, - {0xda0, 0x04000400}, - {0xfb0, 0x04040404}, - {0x9c1, 0x06000000}, - {0xde1, 0x06000600}, - {0xff1, 0x06060606}, - {0xa02, 0x07000000}, - {0xe22, 0x07000700}, - {0xe32, 0x07070707}, - {0xa43, 0x07800000}, - {0xe63, 0x07800780}, - {0xa84, 0x07c00000}, - {0xea4, 0x07c007c0}, - {0xac5, 0x07e00000}, - {0xee5, 0x07e007e0}, - {0xb06, 0x07f00000}, - {0xf26, 0x07f007f0}, - {0xb47, 0x07f80000}, - {0xf67, 0x07f807f8}, - {0xb88, 0x07fc0000}, - {0xfa8, 0x07fc07fc}, - {0xbc9, 0x07fe0000}, - {0xfe9, 0x07fe07fe}, - {0xc0a, 0x07ff0000}, - {0xc2a, 0x07ff07ff}, - {0xc4b, 0x07ff8000}, - {0xc8c, 0x07ffc000}, - {0xccd, 0x07ffe000}, - {0xd0e, 0x07fff000}, - {0xd4f, 0x07fff800}, - {0xd90, 0x07fffc00}, - {0xdd1, 0x07fffe00}, - {0xe12, 0x07ffff00}, - {0xe53, 0x07ffff80}, - {0xe94, 0x07ffffc0}, - {0xed5, 0x07ffffe0}, - {0xf16, 0x07fffff0}, - {0xf57, 0x07fffff8}, - {0xf98, 0x07fffffc}, - {0xfd9, 0x07fffffe}, - {0x81a, 0x07ffffff}, - {0x940, 0x08000000}, - {0xd60, 0x08000800}, - {0xf70, 0x08080808}, - {0x981, 0x0c000000}, - {0xda1, 0x0c000c00}, - {0xfb1, 0x0c0c0c0c}, - {0x9c2, 0x0e000000}, - {0xde2, 0x0e000e00}, - {0xff2, 0x0e0e0e0e}, - {0xa03, 0x0f000000}, - {0xe23, 0x0f000f00}, - {0xe33, 0x0f0f0f0f}, - {0xa44, 0x0f800000}, - {0xe64, 0x0f800f80}, - {0xa85, 0x0fc00000}, - {0xea5, 0x0fc00fc0}, - {0xac6, 0x0fe00000}, - {0xee6, 0x0fe00fe0}, - {0xb07, 0x0ff00000}, - {0xf27, 0x0ff00ff0}, - {0xb48, 0x0ff80000}, - {0xf68, 0x0ff80ff8}, - {0xb89, 0x0ffc0000}, - {0xfa9, 0x0ffc0ffc}, - {0xbca, 0x0ffe0000}, - {0xfea, 0x0ffe0ffe}, - {0xc0b, 0x0fff0000}, - {0xc2b, 0x0fff0fff}, - {0xc4c, 0x0fff8000}, - {0xc8d, 0x0fffc000}, - {0xcce, 0x0fffe000}, - {0xd0f, 0x0ffff000}, - {0xd50, 0x0ffff800}, - {0xd91, 0x0ffffc00}, - {0xdd2, 0x0ffffe00}, - {0xe13, 0x0fffff00}, - {0xe54, 0x0fffff80}, - {0xe95, 0x0fffffc0}, - {0xed6, 0x0fffffe0}, - {0xf17, 0x0ffffff0}, - {0xf58, 0x0ffffff8}, - {0xf99, 0x0ffffffc}, - {0xfda, 0x0ffffffe}, - {0x81b, 0x0fffffff}, - {0x900, 0x10000000}, - {0xd20, 0x10001000}, - {0xf30, 0x10101010}, - {0xf38, 0x11111111}, - {0x941, 0x18000000}, - {0xd61, 0x18001800}, - {0xf71, 0x18181818}, - {0x982, 0x1c000000}, - {0xda2, 0x1c001c00}, - {0xfb2, 0x1c1c1c1c}, - {0x9c3, 0x1e000000}, - {0xde3, 0x1e001e00}, - {0xff3, 0x1e1e1e1e}, - {0xa04, 0x1f000000}, - {0xe24, 0x1f001f00}, - {0xe34, 0x1f1f1f1f}, - {0xa45, 0x1f800000}, - {0xe65, 0x1f801f80}, - {0xa86, 0x1fc00000}, - {0xea6, 0x1fc01fc0}, - {0xac7, 0x1fe00000}, - {0xee7, 0x1fe01fe0}, - {0xb08, 0x1ff00000}, - {0xf28, 0x1ff01ff0}, - {0xb49, 0x1ff80000}, - {0xf69, 0x1ff81ff8}, - {0xb8a, 0x1ffc0000}, - {0xfaa, 0x1ffc1ffc}, - {0xbcb, 0x1ffe0000}, - {0xfeb, 0x1ffe1ffe}, - {0xc0c, 0x1fff0000}, - {0xc2c, 0x1fff1fff}, - {0xc4d, 0x1fff8000}, - {0xc8e, 0x1fffc000}, - {0xccf, 0x1fffe000}, - {0xd10, 0x1ffff000}, - {0xd51, 0x1ffff800}, - {0xd92, 0x1ffffc00}, - {0xdd3, 0x1ffffe00}, - {0xe14, 0x1fffff00}, - {0xe55, 0x1fffff80}, - {0xe96, 0x1fffffc0}, - {0xed7, 0x1fffffe0}, - {0xf18, 0x1ffffff0}, - {0xf59, 0x1ffffff8}, - {0xf9a, 0x1ffffffc}, - {0xfdb, 0x1ffffffe}, - {0x81c, 0x1fffffff}, - {0x8c0, 0x20000000}, - {0xce0, 0x20002000}, - {0xef0, 0x20202020}, - {0xff8, 0x22222222}, - {0x901, 0x30000000}, - {0xd21, 0x30003000}, - {0xf31, 0x30303030}, - {0xf39, 0x33333333}, - {0x942, 0x38000000}, - {0xd62, 0x38003800}, - {0xf72, 0x38383838}, - {0x983, 0x3c000000}, - {0xda3, 0x3c003c00}, - {0xfb3, 0x3c3c3c3c}, - {0x9c4, 0x3e000000}, - {0xde4, 0x3e003e00}, - {0xff4, 0x3e3e3e3e}, - {0xa05, 0x3f000000}, - {0xe25, 0x3f003f00}, - {0xe35, 0x3f3f3f3f}, - {0xa46, 0x3f800000}, - {0xe66, 0x3f803f80}, - {0xa87, 0x3fc00000}, - {0xea7, 0x3fc03fc0}, - {0xac8, 0x3fe00000}, - {0xee8, 0x3fe03fe0}, - {0xb09, 0x3ff00000}, - {0xf29, 0x3ff03ff0}, - {0xb4a, 0x3ff80000}, - {0xf6a, 0x3ff83ff8}, - {0xb8b, 0x3ffc0000}, - {0xfab, 0x3ffc3ffc}, - {0xbcc, 0x3ffe0000}, - {0xfec, 0x3ffe3ffe}, - {0xc0d, 0x3fff0000}, - {0xc2d, 0x3fff3fff}, - {0xc4e, 0x3fff8000}, - {0xc8f, 0x3fffc000}, - {0xcd0, 0x3fffe000}, - {0xd11, 0x3ffff000}, - {0xd52, 0x3ffff800}, - {0xd93, 0x3ffffc00}, - {0xdd4, 0x3ffffe00}, - {0xe15, 0x3fffff00}, - {0xe56, 0x3fffff80}, - {0xe97, 0x3fffffc0}, - {0xed8, 0x3fffffe0}, - {0xf19, 0x3ffffff0}, - {0xf5a, 0x3ffffff8}, - {0xf9b, 0x3ffffffc}, - {0xfdc, 0x3ffffffe}, - {0x81d, 0x3fffffff}, - {0x880, 0x40000000}, - {0xca0, 0x40004000}, - {0xeb0, 0x40404040}, - {0xfb8, 0x44444444}, - {0xfbc, 0x55555555}, - {0x8c1, 0x60000000}, - {0xce1, 0x60006000}, - {0xef1, 0x60606060}, - {0xff9, 0x66666666}, - {0x902, 0x70000000}, - {0xd22, 0x70007000}, - {0xf32, 0x70707070}, - {0xf3a, 0x77777777}, - {0x943, 0x78000000}, - {0xd63, 0x78007800}, - {0xf73, 0x78787878}, - {0x984, 0x7c000000}, - {0xda4, 0x7c007c00}, - {0xfb4, 0x7c7c7c7c}, - {0x9c5, 0x7e000000}, - {0xde5, 0x7e007e00}, - {0xff5, 0x7e7e7e7e}, - {0xa06, 0x7f000000}, - {0xe26, 0x7f007f00}, - {0xe36, 0x7f7f7f7f}, - {0xa47, 0x7f800000}, - {0xe67, 0x7f807f80}, - {0xa88, 0x7fc00000}, - {0xea8, 0x7fc07fc0}, - {0xac9, 0x7fe00000}, - {0xee9, 0x7fe07fe0}, - {0xb0a, 0x7ff00000}, - {0xf2a, 0x7ff07ff0}, - {0xb4b, 0x7ff80000}, - {0xf6b, 0x7ff87ff8}, - {0xb8c, 0x7ffc0000}, - {0xfac, 0x7ffc7ffc}, - {0xbcd, 0x7ffe0000}, - {0xfed, 0x7ffe7ffe}, - {0xc0e, 0x7fff0000}, - {0xc2e, 0x7fff7fff}, - {0xc4f, 0x7fff8000}, - {0xc90, 0x7fffc000}, - {0xcd1, 0x7fffe000}, - {0xd12, 0x7ffff000}, - {0xd53, 0x7ffff800}, - {0xd94, 0x7ffffc00}, - {0xdd5, 0x7ffffe00}, - {0xe16, 0x7fffff00}, - {0xe57, 0x7fffff80}, - {0xe98, 0x7fffffc0}, - {0xed9, 0x7fffffe0}, - {0xf1a, 0x7ffffff0}, - {0xf5b, 0x7ffffff8}, - {0xf9c, 0x7ffffffc}, - {0xfdd, 0x7ffffffe}, - {0x81e, 0x7fffffff}, - {0x840, 0x80000000}, - {0x841, 0x80000001}, - {0x842, 0x80000003}, - {0x843, 0x80000007}, - {0x844, 0x8000000f}, - {0x845, 0x8000001f}, - {0x846, 0x8000003f}, - {0x847, 0x8000007f}, - {0x848, 0x800000ff}, - {0x849, 0x800001ff}, - {0x84a, 0x800003ff}, - {0x84b, 0x800007ff}, - {0x84c, 0x80000fff}, - {0x84d, 0x80001fff}, - {0x84e, 0x80003fff}, - {0x84f, 0x80007fff}, - {0xc60, 0x80008000}, - {0x850, 0x8000ffff}, - {0xc61, 0x80018001}, - {0x851, 0x8001ffff}, - {0xc62, 0x80038003}, - {0x852, 0x8003ffff}, - {0xc63, 0x80078007}, - {0x853, 0x8007ffff}, - {0xc64, 0x800f800f}, - {0x854, 0x800fffff}, - {0xc65, 0x801f801f}, - {0x855, 0x801fffff}, - {0xc66, 0x803f803f}, - {0x856, 0x803fffff}, - {0xc67, 0x807f807f}, - {0x857, 0x807fffff}, - {0xe70, 0x80808080}, - {0xc68, 0x80ff80ff}, - {0x858, 0x80ffffff}, - {0xe71, 0x81818181}, - {0xc69, 0x81ff81ff}, - {0x859, 0x81ffffff}, - {0xe72, 0x83838383}, - {0xc6a, 0x83ff83ff}, - {0x85a, 0x83ffffff}, - {0xe73, 0x87878787}, - {0xc6b, 0x87ff87ff}, - {0x85b, 0x87ffffff}, - {0xf78, 0x88888888}, - {0xe74, 0x8f8f8f8f}, - {0xc6c, 0x8fff8fff}, - {0x85c, 0x8fffffff}, - {0xf79, 0x99999999}, - {0xe75, 0x9f9f9f9f}, - {0xc6d, 0x9fff9fff}, - {0x85d, 0x9fffffff}, - {0xffc, 0xaaaaaaaa}, - {0xf7a, 0xbbbbbbbb}, - {0xe76, 0xbfbfbfbf}, - {0xc6e, 0xbfffbfff}, - {0x85e, 0xbfffffff}, - {0x881, 0xc0000000}, - {0x882, 0xc0000001}, - {0x883, 0xc0000003}, - {0x884, 0xc0000007}, - {0x885, 0xc000000f}, - {0x886, 0xc000001f}, - {0x887, 0xc000003f}, - {0x888, 0xc000007f}, - {0x889, 0xc00000ff}, - {0x88a, 0xc00001ff}, - {0x88b, 0xc00003ff}, - {0x88c, 0xc00007ff}, - {0x88d, 0xc0000fff}, - {0x88e, 0xc0001fff}, - {0x88f, 0xc0003fff}, - {0x890, 0xc0007fff}, - {0xca1, 0xc000c000}, - {0x891, 0xc000ffff}, - {0xca2, 0xc001c001}, - {0x892, 0xc001ffff}, - {0xca3, 0xc003c003}, - {0x893, 0xc003ffff}, - {0xca4, 0xc007c007}, - {0x894, 0xc007ffff}, - {0xca5, 0xc00fc00f}, - {0x895, 0xc00fffff}, - {0xca6, 0xc01fc01f}, - {0x896, 0xc01fffff}, - {0xca7, 0xc03fc03f}, - {0x897, 0xc03fffff}, - {0xca8, 0xc07fc07f}, - {0x898, 0xc07fffff}, - {0xeb1, 0xc0c0c0c0}, - {0xca9, 0xc0ffc0ff}, - {0x899, 0xc0ffffff}, - {0xeb2, 0xc1c1c1c1}, - {0xcaa, 0xc1ffc1ff}, - {0x89a, 0xc1ffffff}, - {0xeb3, 0xc3c3c3c3}, - {0xcab, 0xc3ffc3ff}, - {0x89b, 0xc3ffffff}, - {0xeb4, 0xc7c7c7c7}, - {0xcac, 0xc7ffc7ff}, - {0x89c, 0xc7ffffff}, - {0xfb9, 0xcccccccc}, - {0xeb5, 0xcfcfcfcf}, - {0xcad, 0xcfffcfff}, - {0x89d, 0xcfffffff}, - {0xfba, 0xdddddddd}, - {0xeb6, 0xdfdfdfdf}, - {0xcae, 0xdfffdfff}, - {0x89e, 0xdfffffff}, - {0x8c2, 0xe0000000}, - {0x8c3, 0xe0000001}, - {0x8c4, 0xe0000003}, - {0x8c5, 0xe0000007}, - {0x8c6, 0xe000000f}, - {0x8c7, 0xe000001f}, - {0x8c8, 0xe000003f}, - {0x8c9, 0xe000007f}, - {0x8ca, 0xe00000ff}, - {0x8cb, 0xe00001ff}, - {0x8cc, 0xe00003ff}, - {0x8cd, 0xe00007ff}, - {0x8ce, 0xe0000fff}, - {0x8cf, 0xe0001fff}, - {0x8d0, 0xe0003fff}, - {0x8d1, 0xe0007fff}, - {0xce2, 0xe000e000}, - {0x8d2, 0xe000ffff}, - {0xce3, 0xe001e001}, - {0x8d3, 0xe001ffff}, - {0xce4, 0xe003e003}, - {0x8d4, 0xe003ffff}, - {0xce5, 0xe007e007}, - {0x8d5, 0xe007ffff}, - {0xce6, 0xe00fe00f}, - {0x8d6, 0xe00fffff}, - {0xce7, 0xe01fe01f}, - {0x8d7, 0xe01fffff}, - {0xce8, 0xe03fe03f}, - {0x8d8, 0xe03fffff}, - {0xce9, 0xe07fe07f}, - {0x8d9, 0xe07fffff}, - {0xef2, 0xe0e0e0e0}, - {0xcea, 0xe0ffe0ff}, - {0x8da, 0xe0ffffff}, - {0xef3, 0xe1e1e1e1}, - {0xceb, 0xe1ffe1ff}, - {0x8db, 0xe1ffffff}, - {0xef4, 0xe3e3e3e3}, - {0xcec, 0xe3ffe3ff}, - {0x8dc, 0xe3ffffff}, - {0xef5, 0xe7e7e7e7}, - {0xced, 0xe7ffe7ff}, - {0x8dd, 0xe7ffffff}, - {0xffa, 0xeeeeeeee}, - {0xef6, 0xefefefef}, - {0xcee, 0xefffefff}, - {0x8de, 0xefffffff}, - {0x903, 0xf0000000}, - {0x904, 0xf0000001}, - {0x905, 0xf0000003}, - {0x906, 0xf0000007}, - {0x907, 0xf000000f}, - {0x908, 0xf000001f}, - {0x909, 0xf000003f}, - {0x90a, 0xf000007f}, - {0x90b, 0xf00000ff}, - {0x90c, 0xf00001ff}, - {0x90d, 0xf00003ff}, - {0x90e, 0xf00007ff}, - {0x90f, 0xf0000fff}, - {0x910, 0xf0001fff}, - {0x911, 0xf0003fff}, - {0x912, 0xf0007fff}, - {0xd23, 0xf000f000}, - {0x913, 0xf000ffff}, - {0xd24, 0xf001f001}, - {0x914, 0xf001ffff}, - {0xd25, 0xf003f003}, - {0x915, 0xf003ffff}, - {0xd26, 0xf007f007}, - {0x916, 0xf007ffff}, - {0xd27, 0xf00ff00f}, - {0x917, 0xf00fffff}, - {0xd28, 0xf01ff01f}, - {0x918, 0xf01fffff}, - {0xd29, 0xf03ff03f}, - {0x919, 0xf03fffff}, - {0xd2a, 0xf07ff07f}, - {0x91a, 0xf07fffff}, - {0xf33, 0xf0f0f0f0}, - {0xd2b, 0xf0fff0ff}, - {0x91b, 0xf0ffffff}, - {0xf34, 0xf1f1f1f1}, - {0xd2c, 0xf1fff1ff}, - {0x91c, 0xf1ffffff}, - {0xf35, 0xf3f3f3f3}, - {0xd2d, 0xf3fff3ff}, - {0x91d, 0xf3ffffff}, - {0xf36, 0xf7f7f7f7}, - {0xd2e, 0xf7fff7ff}, - {0x91e, 0xf7ffffff}, - {0x944, 0xf8000000}, - {0x945, 0xf8000001}, - {0x946, 0xf8000003}, - {0x947, 0xf8000007}, - {0x948, 0xf800000f}, - {0x949, 0xf800001f}, - {0x94a, 0xf800003f}, - {0x94b, 0xf800007f}, - {0x94c, 0xf80000ff}, - {0x94d, 0xf80001ff}, - {0x94e, 0xf80003ff}, - {0x94f, 0xf80007ff}, - {0x950, 0xf8000fff}, - {0x951, 0xf8001fff}, - {0x952, 0xf8003fff}, - {0x953, 0xf8007fff}, - {0xd64, 0xf800f800}, - {0x954, 0xf800ffff}, - {0xd65, 0xf801f801}, - {0x955, 0xf801ffff}, - {0xd66, 0xf803f803}, - {0x956, 0xf803ffff}, - {0xd67, 0xf807f807}, - {0x957, 0xf807ffff}, - {0xd68, 0xf80ff80f}, - {0x958, 0xf80fffff}, - {0xd69, 0xf81ff81f}, - {0x959, 0xf81fffff}, - {0xd6a, 0xf83ff83f}, - {0x95a, 0xf83fffff}, - {0xd6b, 0xf87ff87f}, - {0x95b, 0xf87fffff}, - {0xf74, 0xf8f8f8f8}, - {0xd6c, 0xf8fff8ff}, - {0x95c, 0xf8ffffff}, - {0xf75, 0xf9f9f9f9}, - {0xd6d, 0xf9fff9ff}, - {0x95d, 0xf9ffffff}, - {0xf76, 0xfbfbfbfb}, - {0xd6e, 0xfbfffbff}, - {0x95e, 0xfbffffff}, - {0x985, 0xfc000000}, - {0x986, 0xfc000001}, - {0x987, 0xfc000003}, - {0x988, 0xfc000007}, - {0x989, 0xfc00000f}, - {0x98a, 0xfc00001f}, - {0x98b, 0xfc00003f}, - {0x98c, 0xfc00007f}, - {0x98d, 0xfc0000ff}, - {0x98e, 0xfc0001ff}, - {0x98f, 0xfc0003ff}, - {0x990, 0xfc0007ff}, - {0x991, 0xfc000fff}, - {0x992, 0xfc001fff}, - {0x993, 0xfc003fff}, - {0x994, 0xfc007fff}, - {0xda5, 0xfc00fc00}, - {0x995, 0xfc00ffff}, - {0xda6, 0xfc01fc01}, - {0x996, 0xfc01ffff}, - {0xda7, 0xfc03fc03}, - {0x997, 0xfc03ffff}, - {0xda8, 0xfc07fc07}, - {0x998, 0xfc07ffff}, - {0xda9, 0xfc0ffc0f}, - {0x999, 0xfc0fffff}, - {0xdaa, 0xfc1ffc1f}, - {0x99a, 0xfc1fffff}, - {0xdab, 0xfc3ffc3f}, - {0x99b, 0xfc3fffff}, - {0xdac, 0xfc7ffc7f}, - {0x99c, 0xfc7fffff}, - {0xfb5, 0xfcfcfcfc}, - {0xdad, 0xfcfffcff}, - {0x99d, 0xfcffffff}, - {0xfb6, 0xfdfdfdfd}, - {0xdae, 0xfdfffdff}, - {0x99e, 0xfdffffff}, - {0x9c6, 0xfe000000}, - {0x9c7, 0xfe000001}, - {0x9c8, 0xfe000003}, - {0x9c9, 0xfe000007}, - {0x9ca, 0xfe00000f}, - {0x9cb, 0xfe00001f}, - {0x9cc, 0xfe00003f}, - {0x9cd, 0xfe00007f}, - {0x9ce, 0xfe0000ff}, - {0x9cf, 0xfe0001ff}, - {0x9d0, 0xfe0003ff}, - {0x9d1, 0xfe0007ff}, - {0x9d2, 0xfe000fff}, - {0x9d3, 0xfe001fff}, - {0x9d4, 0xfe003fff}, - {0x9d5, 0xfe007fff}, - {0xde6, 0xfe00fe00}, - {0x9d6, 0xfe00ffff}, - {0xde7, 0xfe01fe01}, - {0x9d7, 0xfe01ffff}, - {0xde8, 0xfe03fe03}, - {0x9d8, 0xfe03ffff}, - {0xde9, 0xfe07fe07}, - {0x9d9, 0xfe07ffff}, - {0xdea, 0xfe0ffe0f}, - {0x9da, 0xfe0fffff}, - {0xdeb, 0xfe1ffe1f}, - {0x9db, 0xfe1fffff}, - {0xdec, 0xfe3ffe3f}, - {0x9dc, 0xfe3fffff}, - {0xded, 0xfe7ffe7f}, - {0x9dd, 0xfe7fffff}, - {0xff6, 0xfefefefe}, - {0xdee, 0xfefffeff}, - {0x9de, 0xfeffffff}, - {0xa07, 0xff000000}, - {0xa08, 0xff000001}, - {0xa09, 0xff000003}, - {0xa0a, 0xff000007}, - {0xa0b, 0xff00000f}, - {0xa0c, 0xff00001f}, - {0xa0d, 0xff00003f}, - {0xa0e, 0xff00007f}, - {0xa0f, 0xff0000ff}, - {0xa10, 0xff0001ff}, - {0xa11, 0xff0003ff}, - {0xa12, 0xff0007ff}, - {0xa13, 0xff000fff}, - {0xa14, 0xff001fff}, - {0xa15, 0xff003fff}, - {0xa16, 0xff007fff}, - {0xe27, 0xff00ff00}, - {0xa17, 0xff00ffff}, - {0xe28, 0xff01ff01}, - {0xa18, 0xff01ffff}, - {0xe29, 0xff03ff03}, - {0xa19, 0xff03ffff}, - {0xe2a, 0xff07ff07}, - {0xa1a, 0xff07ffff}, - {0xe2b, 0xff0fff0f}, - {0xa1b, 0xff0fffff}, - {0xe2c, 0xff1fff1f}, - {0xa1c, 0xff1fffff}, - {0xe2d, 0xff3fff3f}, - {0xa1d, 0xff3fffff}, - {0xe2e, 0xff7fff7f}, - {0xa1e, 0xff7fffff}, - {0xa48, 0xff800000}, - {0xa49, 0xff800001}, - {0xa4a, 0xff800003}, - {0xa4b, 0xff800007}, - {0xa4c, 0xff80000f}, - {0xa4d, 0xff80001f}, - {0xa4e, 0xff80003f}, - {0xa4f, 0xff80007f}, - {0xa50, 0xff8000ff}, - {0xa51, 0xff8001ff}, - {0xa52, 0xff8003ff}, - {0xa53, 0xff8007ff}, - {0xa54, 0xff800fff}, - {0xa55, 0xff801fff}, - {0xa56, 0xff803fff}, - {0xa57, 0xff807fff}, - {0xe68, 0xff80ff80}, - {0xa58, 0xff80ffff}, - {0xe69, 0xff81ff81}, - {0xa59, 0xff81ffff}, - {0xe6a, 0xff83ff83}, - {0xa5a, 0xff83ffff}, - {0xe6b, 0xff87ff87}, - {0xa5b, 0xff87ffff}, - {0xe6c, 0xff8fff8f}, - {0xa5c, 0xff8fffff}, - {0xe6d, 0xff9fff9f}, - {0xa5d, 0xff9fffff}, - {0xe6e, 0xffbfffbf}, - {0xa5e, 0xffbfffff}, - {0xa89, 0xffc00000}, - {0xa8a, 0xffc00001}, - {0xa8b, 0xffc00003}, - {0xa8c, 0xffc00007}, - {0xa8d, 0xffc0000f}, - {0xa8e, 0xffc0001f}, - {0xa8f, 0xffc0003f}, - {0xa90, 0xffc0007f}, - {0xa91, 0xffc000ff}, - {0xa92, 0xffc001ff}, - {0xa93, 0xffc003ff}, - {0xa94, 0xffc007ff}, - {0xa95, 0xffc00fff}, - {0xa96, 0xffc01fff}, - {0xa97, 0xffc03fff}, - {0xa98, 0xffc07fff}, - {0xea9, 0xffc0ffc0}, - {0xa99, 0xffc0ffff}, - {0xeaa, 0xffc1ffc1}, - {0xa9a, 0xffc1ffff}, - {0xeab, 0xffc3ffc3}, - {0xa9b, 0xffc3ffff}, - {0xeac, 0xffc7ffc7}, - {0xa9c, 0xffc7ffff}, - {0xead, 0xffcfffcf}, - {0xa9d, 0xffcfffff}, - {0xeae, 0xffdfffdf}, - {0xa9e, 0xffdfffff}, - {0xaca, 0xffe00000}, - {0xacb, 0xffe00001}, - {0xacc, 0xffe00003}, - {0xacd, 0xffe00007}, - {0xace, 0xffe0000f}, - {0xacf, 0xffe0001f}, - {0xad0, 0xffe0003f}, - {0xad1, 0xffe0007f}, - {0xad2, 0xffe000ff}, - {0xad3, 0xffe001ff}, - {0xad4, 0xffe003ff}, - {0xad5, 0xffe007ff}, - {0xad6, 0xffe00fff}, - {0xad7, 0xffe01fff}, - {0xad8, 0xffe03fff}, - {0xad9, 0xffe07fff}, - {0xeea, 0xffe0ffe0}, - {0xada, 0xffe0ffff}, - {0xeeb, 0xffe1ffe1}, - {0xadb, 0xffe1ffff}, - {0xeec, 0xffe3ffe3}, - {0xadc, 0xffe3ffff}, - {0xeed, 0xffe7ffe7}, - {0xadd, 0xffe7ffff}, - {0xeee, 0xffefffef}, - {0xade, 0xffefffff}, - {0xb0b, 0xfff00000}, - {0xb0c, 0xfff00001}, - {0xb0d, 0xfff00003}, - {0xb0e, 0xfff00007}, - {0xb0f, 0xfff0000f}, - {0xb10, 0xfff0001f}, - {0xb11, 0xfff0003f}, - {0xb12, 0xfff0007f}, - {0xb13, 0xfff000ff}, - {0xb14, 0xfff001ff}, - {0xb15, 0xfff003ff}, - {0xb16, 0xfff007ff}, - {0xb17, 0xfff00fff}, - {0xb18, 0xfff01fff}, - {0xb19, 0xfff03fff}, - {0xb1a, 0xfff07fff}, - {0xf2b, 0xfff0fff0}, - {0xb1b, 0xfff0ffff}, - {0xf2c, 0xfff1fff1}, - {0xb1c, 0xfff1ffff}, - {0xf2d, 0xfff3fff3}, - {0xb1d, 0xfff3ffff}, - {0xf2e, 0xfff7fff7}, - {0xb1e, 0xfff7ffff}, - {0xb4c, 0xfff80000}, - {0xb4d, 0xfff80001}, - {0xb4e, 0xfff80003}, - {0xb4f, 0xfff80007}, - {0xb50, 0xfff8000f}, - {0xb51, 0xfff8001f}, - {0xb52, 0xfff8003f}, - {0xb53, 0xfff8007f}, - {0xb54, 0xfff800ff}, - {0xb55, 0xfff801ff}, - {0xb56, 0xfff803ff}, - {0xb57, 0xfff807ff}, - {0xb58, 0xfff80fff}, - {0xb59, 0xfff81fff}, - {0xb5a, 0xfff83fff}, - {0xb5b, 0xfff87fff}, - {0xf6c, 0xfff8fff8}, - {0xb5c, 0xfff8ffff}, - {0xf6d, 0xfff9fff9}, - {0xb5d, 0xfff9ffff}, - {0xf6e, 0xfffbfffb}, - {0xb5e, 0xfffbffff}, - {0xb8d, 0xfffc0000}, - {0xb8e, 0xfffc0001}, - {0xb8f, 0xfffc0003}, - {0xb90, 0xfffc0007}, - {0xb91, 0xfffc000f}, - {0xb92, 0xfffc001f}, - {0xb93, 0xfffc003f}, - {0xb94, 0xfffc007f}, - {0xb95, 0xfffc00ff}, - {0xb96, 0xfffc01ff}, - {0xb97, 0xfffc03ff}, - {0xb98, 0xfffc07ff}, - {0xb99, 0xfffc0fff}, - {0xb9a, 0xfffc1fff}, - {0xb9b, 0xfffc3fff}, - {0xb9c, 0xfffc7fff}, - {0xfad, 0xfffcfffc}, - {0xb9d, 0xfffcffff}, - {0xfae, 0xfffdfffd}, - {0xb9e, 0xfffdffff}, - {0xbce, 0xfffe0000}, - {0xbcf, 0xfffe0001}, - {0xbd0, 0xfffe0003}, - {0xbd1, 0xfffe0007}, - {0xbd2, 0xfffe000f}, - {0xbd3, 0xfffe001f}, - {0xbd4, 0xfffe003f}, - {0xbd5, 0xfffe007f}, - {0xbd6, 0xfffe00ff}, - {0xbd7, 0xfffe01ff}, - {0xbd8, 0xfffe03ff}, - {0xbd9, 0xfffe07ff}, - {0xbda, 0xfffe0fff}, - {0xbdb, 0xfffe1fff}, - {0xbdc, 0xfffe3fff}, - {0xbdd, 0xfffe7fff}, - {0xfee, 0xfffefffe}, - {0xbde, 0xfffeffff}, - {0xc0f, 0xffff0000}, - {0xc10, 0xffff0001}, - {0xc11, 0xffff0003}, - {0xc12, 0xffff0007}, - {0xc13, 0xffff000f}, - {0xc14, 0xffff001f}, - {0xc15, 0xffff003f}, - {0xc16, 0xffff007f}, - {0xc17, 0xffff00ff}, - {0xc18, 0xffff01ff}, - {0xc19, 0xffff03ff}, - {0xc1a, 0xffff07ff}, - {0xc1b, 0xffff0fff}, - {0xc1c, 0xffff1fff}, - {0xc1d, 0xffff3fff}, - {0xc1e, 0xffff7fff}, - {0xc50, 0xffff8000}, - {0xc51, 0xffff8001}, - {0xc52, 0xffff8003}, - {0xc53, 0xffff8007}, - {0xc54, 0xffff800f}, - {0xc55, 0xffff801f}, - {0xc56, 0xffff803f}, - {0xc57, 0xffff807f}, - {0xc58, 0xffff80ff}, - {0xc59, 0xffff81ff}, - {0xc5a, 0xffff83ff}, - {0xc5b, 0xffff87ff}, - {0xc5c, 0xffff8fff}, - {0xc5d, 0xffff9fff}, - {0xc5e, 0xffffbfff}, - {0xc91, 0xffffc000}, - {0xc92, 0xffffc001}, - {0xc93, 0xffffc003}, - {0xc94, 0xffffc007}, - {0xc95, 0xffffc00f}, - {0xc96, 0xffffc01f}, - {0xc97, 0xffffc03f}, - {0xc98, 0xffffc07f}, - {0xc99, 0xffffc0ff}, - {0xc9a, 0xffffc1ff}, - {0xc9b, 0xffffc3ff}, - {0xc9c, 0xffffc7ff}, - {0xc9d, 0xffffcfff}, - {0xc9e, 0xffffdfff}, - {0xcd2, 0xffffe000}, - {0xcd3, 0xffffe001}, - {0xcd4, 0xffffe003}, - {0xcd5, 0xffffe007}, - {0xcd6, 0xffffe00f}, - {0xcd7, 0xffffe01f}, - {0xcd8, 0xffffe03f}, - {0xcd9, 0xffffe07f}, - {0xcda, 0xffffe0ff}, - {0xcdb, 0xffffe1ff}, - {0xcdc, 0xffffe3ff}, - {0xcdd, 0xffffe7ff}, - {0xcde, 0xffffefff}, - {0xd13, 0xfffff000}, - {0xd14, 0xfffff001}, - {0xd15, 0xfffff003}, - {0xd16, 0xfffff007}, - {0xd17, 0xfffff00f}, - {0xd18, 0xfffff01f}, - {0xd19, 0xfffff03f}, - {0xd1a, 0xfffff07f}, - {0xd1b, 0xfffff0ff}, - {0xd1c, 0xfffff1ff}, - {0xd1d, 0xfffff3ff}, - {0xd1e, 0xfffff7ff}, - {0xd54, 0xfffff800}, - {0xd55, 0xfffff801}, - {0xd56, 0xfffff803}, - {0xd57, 0xfffff807}, - {0xd58, 0xfffff80f}, - {0xd59, 0xfffff81f}, - {0xd5a, 0xfffff83f}, - {0xd5b, 0xfffff87f}, - {0xd5c, 0xfffff8ff}, - {0xd5d, 0xfffff9ff}, - {0xd5e, 0xfffffbff}, - {0xd95, 0xfffffc00}, - {0xd96, 0xfffffc01}, - {0xd97, 0xfffffc03}, - {0xd98, 0xfffffc07}, - {0xd99, 0xfffffc0f}, - {0xd9a, 0xfffffc1f}, - {0xd9b, 0xfffffc3f}, - {0xd9c, 0xfffffc7f}, - {0xd9d, 0xfffffcff}, - {0xd9e, 0xfffffdff}, - {0xdd6, 0xfffffe00}, - {0xdd7, 0xfffffe01}, - {0xdd8, 0xfffffe03}, - {0xdd9, 0xfffffe07}, - {0xdda, 0xfffffe0f}, - {0xddb, 0xfffffe1f}, - {0xddc, 0xfffffe3f}, - {0xddd, 0xfffffe7f}, - {0xdde, 0xfffffeff}, - {0xe17, 0xffffff00}, - {0xe18, 0xffffff01}, - {0xe19, 0xffffff03}, - {0xe1a, 0xffffff07}, - {0xe1b, 0xffffff0f}, - {0xe1c, 0xffffff1f}, - {0xe1d, 0xffffff3f}, - {0xe1e, 0xffffff7f}, - {0xe58, 0xffffff80}, - {0xe59, 0xffffff81}, - {0xe5a, 0xffffff83}, - {0xe5b, 0xffffff87}, - {0xe5c, 0xffffff8f}, - {0xe5d, 0xffffff9f}, - {0xe5e, 0xffffffbf}, - {0xe99, 0xffffffc0}, - {0xe9a, 0xffffffc1}, - {0xe9b, 0xffffffc3}, - {0xe9c, 0xffffffc7}, - {0xe9d, 0xffffffcf}, - {0xe9e, 0xffffffdf}, - {0xeda, 0xffffffe0}, - {0xedb, 0xffffffe1}, - {0xedc, 0xffffffe3}, - {0xedd, 0xffffffe7}, - {0xede, 0xffffffef}, - {0xf1b, 0xfffffff0}, - {0xf1c, 0xfffffff1}, - {0xf1d, 0xfffffff3}, - {0xf1e, 0xfffffff7}, - {0xf5c, 0xfffffff8}, - {0xf5d, 0xfffffff9}, - {0xf5e, 0xfffffffb}, - {0xf9d, 0xfffffffc}, - {0xf9e, 0xfffffffd}, - {0xfde, 0xfffffffe}, - }; +static uint32_t imm_table[][2] = { + {0x800, 0x00000001}, {0xfc0, 0x00000002}, {0x801, 0x00000003}, {0xf80, 0x00000004}, {0xfc1, 0x00000006}, + {0x802, 0x00000007}, {0xf40, 0x00000008}, {0xf81, 0x0000000c}, {0xfc2, 0x0000000e}, {0x803, 0x0000000f}, + {0xf00, 0x00000010}, {0xf41, 0x00000018}, {0xf82, 0x0000001c}, {0xfc3, 0x0000001e}, {0x804, 0x0000001f}, + {0xec0, 0x00000020}, {0xf01, 0x00000030}, {0xf42, 0x00000038}, {0xf83, 0x0000003c}, {0xfc4, 0x0000003e}, + {0x805, 0x0000003f}, {0xe80, 0x00000040}, {0xec1, 0x00000060}, {0xf02, 0x00000070}, {0xf43, 0x00000078}, + {0xf84, 0x0000007c}, {0xfc5, 0x0000007e}, {0x806, 0x0000007f}, {0xe40, 0x00000080}, {0xe81, 0x000000c0}, + {0xec2, 0x000000e0}, {0xf03, 0x000000f0}, {0xf44, 0x000000f8}, {0xf85, 0x000000fc}, {0xfc6, 0x000000fe}, + {0x807, 0x000000ff}, {0xe00, 0x00000100}, {0xe41, 0x00000180}, {0xe82, 0x000001c0}, {0xec3, 0x000001e0}, + {0xf04, 0x000001f0}, {0xf45, 0x000001f8}, {0xf86, 0x000001fc}, {0xfc7, 0x000001fe}, {0x808, 0x000001ff}, + {0xdc0, 0x00000200}, {0xe01, 0x00000300}, {0xe42, 0x00000380}, {0xe83, 0x000003c0}, {0xec4, 0x000003e0}, + {0xf05, 0x000003f0}, {0xf46, 0x000003f8}, {0xf87, 0x000003fc}, {0xfc8, 0x000003fe}, {0x809, 0x000003ff}, + {0xd80, 0x00000400}, {0xdc1, 0x00000600}, {0xe02, 0x00000700}, {0xe43, 0x00000780}, {0xe84, 0x000007c0}, + {0xec5, 0x000007e0}, {0xf06, 0x000007f0}, {0xf47, 0x000007f8}, {0xf88, 0x000007fc}, {0xfc9, 0x000007fe}, + {0x80a, 0x000007ff}, {0xd40, 0x00000800}, {0xd81, 0x00000c00}, {0xdc2, 0x00000e00}, {0xe03, 0x00000f00}, + {0xe44, 0x00000f80}, {0xe85, 0x00000fc0}, {0xec6, 0x00000fe0}, {0xf07, 0x00000ff0}, {0xf48, 0x00000ff8}, + {0xf89, 0x00000ffc}, {0xfca, 0x00000ffe}, {0x80b, 0x00000fff}, {0xd00, 0x00001000}, {0xd41, 0x00001800}, + {0xd82, 0x00001c00}, {0xdc3, 0x00001e00}, {0xe04, 0x00001f00}, {0xe45, 0x00001f80}, {0xe86, 0x00001fc0}, + {0xec7, 0x00001fe0}, {0xf08, 0x00001ff0}, {0xf49, 0x00001ff8}, {0xf8a, 0x00001ffc}, {0xfcb, 0x00001ffe}, + {0x80c, 0x00001fff}, {0xcc0, 0x00002000}, {0xd01, 0x00003000}, {0xd42, 0x00003800}, {0xd83, 0x00003c00}, + {0xdc4, 0x00003e00}, {0xe05, 0x00003f00}, {0xe46, 0x00003f80}, {0xe87, 0x00003fc0}, {0xec8, 0x00003fe0}, + {0xf09, 0x00003ff0}, {0xf4a, 0x00003ff8}, {0xf8b, 0x00003ffc}, {0xfcc, 0x00003ffe}, {0x80d, 0x00003fff}, + {0xc80, 0x00004000}, {0xcc1, 0x00006000}, {0xd02, 0x00007000}, {0xd43, 0x00007800}, {0xd84, 0x00007c00}, + {0xdc5, 0x00007e00}, {0xe06, 0x00007f00}, {0xe47, 0x00007f80}, {0xe88, 0x00007fc0}, {0xec9, 0x00007fe0}, + {0xf0a, 0x00007ff0}, {0xf4b, 0x00007ff8}, {0xf8c, 0x00007ffc}, {0xfcd, 0x00007ffe}, {0x80e, 0x00007fff}, + {0xc40, 0x00008000}, {0xc81, 0x0000c000}, {0xcc2, 0x0000e000}, {0xd03, 0x0000f000}, {0xd44, 0x0000f800}, + {0xd85, 0x0000fc00}, {0xdc6, 0x0000fe00}, {0xe07, 0x0000ff00}, {0xe48, 0x0000ff80}, {0xe89, 0x0000ffc0}, + {0xeca, 0x0000ffe0}, {0xf0b, 0x0000fff0}, {0xf4c, 0x0000fff8}, {0xf8d, 0x0000fffc}, {0xfce, 0x0000fffe}, + {0x80f, 0x0000ffff}, {0xc00, 0x00010000}, {0xc20, 0x00010001}, {0xc41, 0x00018000}, {0xc82, 0x0001c000}, + {0xcc3, 0x0001e000}, {0xd04, 0x0001f000}, {0xd45, 0x0001f800}, {0xd86, 0x0001fc00}, {0xdc7, 0x0001fe00}, + {0xe08, 0x0001ff00}, {0xe49, 0x0001ff80}, {0xe8a, 0x0001ffc0}, {0xecb, 0x0001ffe0}, {0xf0c, 0x0001fff0}, + {0xf4d, 0x0001fff8}, {0xf8e, 0x0001fffc}, {0xfcf, 0x0001fffe}, {0x810, 0x0001ffff}, {0xbc0, 0x00020000}, + {0xfe0, 0x00020002}, {0xc01, 0x00030000}, {0xc21, 0x00030003}, {0xc42, 0x00038000}, {0xc83, 0x0003c000}, + {0xcc4, 0x0003e000}, {0xd05, 0x0003f000}, {0xd46, 0x0003f800}, {0xd87, 0x0003fc00}, {0xdc8, 0x0003fe00}, + {0xe09, 0x0003ff00}, {0xe4a, 0x0003ff80}, {0xe8b, 0x0003ffc0}, {0xecc, 0x0003ffe0}, {0xf0d, 0x0003fff0}, + {0xf4e, 0x0003fff8}, {0xf8f, 0x0003fffc}, {0xfd0, 0x0003fffe}, {0x811, 0x0003ffff}, {0xb80, 0x00040000}, + {0xfa0, 0x00040004}, {0xbc1, 0x00060000}, {0xfe1, 0x00060006}, {0xc02, 0x00070000}, {0xc22, 0x00070007}, + {0xc43, 0x00078000}, {0xc84, 0x0007c000}, {0xcc5, 0x0007e000}, {0xd06, 0x0007f000}, {0xd47, 0x0007f800}, + {0xd88, 0x0007fc00}, {0xdc9, 0x0007fe00}, {0xe0a, 0x0007ff00}, {0xe4b, 0x0007ff80}, {0xe8c, 0x0007ffc0}, + {0xecd, 0x0007ffe0}, {0xf0e, 0x0007fff0}, {0xf4f, 0x0007fff8}, {0xf90, 0x0007fffc}, {0xfd1, 0x0007fffe}, + {0x812, 0x0007ffff}, {0xb40, 0x00080000}, {0xf60, 0x00080008}, {0xb81, 0x000c0000}, {0xfa1, 0x000c000c}, + {0xbc2, 0x000e0000}, {0xfe2, 0x000e000e}, {0xc03, 0x000f0000}, {0xc23, 0x000f000f}, {0xc44, 0x000f8000}, + {0xc85, 0x000fc000}, {0xcc6, 0x000fe000}, {0xd07, 0x000ff000}, {0xd48, 0x000ff800}, {0xd89, 0x000ffc00}, + {0xdca, 0x000ffe00}, {0xe0b, 0x000fff00}, {0xe4c, 0x000fff80}, {0xe8d, 0x000fffc0}, {0xece, 0x000fffe0}, + {0xf0f, 0x000ffff0}, {0xf50, 0x000ffff8}, {0xf91, 0x000ffffc}, {0xfd2, 0x000ffffe}, {0x813, 0x000fffff}, + {0xb00, 0x00100000}, {0xf20, 0x00100010}, {0xb41, 0x00180000}, {0xf61, 0x00180018}, {0xb82, 0x001c0000}, + {0xfa2, 0x001c001c}, {0xbc3, 0x001e0000}, {0xfe3, 0x001e001e}, {0xc04, 0x001f0000}, {0xc24, 0x001f001f}, + {0xc45, 0x001f8000}, {0xc86, 0x001fc000}, {0xcc7, 0x001fe000}, {0xd08, 0x001ff000}, {0xd49, 0x001ff800}, + {0xd8a, 0x001ffc00}, {0xdcb, 0x001ffe00}, {0xe0c, 0x001fff00}, {0xe4d, 0x001fff80}, {0xe8e, 0x001fffc0}, + {0xecf, 0x001fffe0}, {0xf10, 0x001ffff0}, {0xf51, 0x001ffff8}, {0xf92, 0x001ffffc}, {0xfd3, 0x001ffffe}, + {0x814, 0x001fffff}, {0xac0, 0x00200000}, {0xee0, 0x00200020}, {0xb01, 0x00300000}, {0xf21, 0x00300030}, + {0xb42, 0x00380000}, {0xf62, 0x00380038}, {0xb83, 0x003c0000}, {0xfa3, 0x003c003c}, {0xbc4, 0x003e0000}, + {0xfe4, 0x003e003e}, {0xc05, 0x003f0000}, {0xc25, 0x003f003f}, {0xc46, 0x003f8000}, {0xc87, 0x003fc000}, + {0xcc8, 0x003fe000}, {0xd09, 0x003ff000}, {0xd4a, 0x003ff800}, {0xd8b, 0x003ffc00}, {0xdcc, 0x003ffe00}, + {0xe0d, 0x003fff00}, {0xe4e, 0x003fff80}, {0xe8f, 0x003fffc0}, {0xed0, 0x003fffe0}, {0xf11, 0x003ffff0}, + {0xf52, 0x003ffff8}, {0xf93, 0x003ffffc}, {0xfd4, 0x003ffffe}, {0x815, 0x003fffff}, {0xa80, 0x00400000}, + {0xea0, 0x00400040}, {0xac1, 0x00600000}, {0xee1, 0x00600060}, {0xb02, 0x00700000}, {0xf22, 0x00700070}, + {0xb43, 0x00780000}, {0xf63, 0x00780078}, {0xb84, 0x007c0000}, {0xfa4, 0x007c007c}, {0xbc5, 0x007e0000}, + {0xfe5, 0x007e007e}, {0xc06, 0x007f0000}, {0xc26, 0x007f007f}, {0xc47, 0x007f8000}, {0xc88, 0x007fc000}, + {0xcc9, 0x007fe000}, {0xd0a, 0x007ff000}, {0xd4b, 0x007ff800}, {0xd8c, 0x007ffc00}, {0xdcd, 0x007ffe00}, + {0xe0e, 0x007fff00}, {0xe4f, 0x007fff80}, {0xe90, 0x007fffc0}, {0xed1, 0x007fffe0}, {0xf12, 0x007ffff0}, + {0xf53, 0x007ffff8}, {0xf94, 0x007ffffc}, {0xfd5, 0x007ffffe}, {0x816, 0x007fffff}, {0xa40, 0x00800000}, + {0xe60, 0x00800080}, {0xa81, 0x00c00000}, {0xea1, 0x00c000c0}, {0xac2, 0x00e00000}, {0xee2, 0x00e000e0}, + {0xb03, 0x00f00000}, {0xf23, 0x00f000f0}, {0xb44, 0x00f80000}, {0xf64, 0x00f800f8}, {0xb85, 0x00fc0000}, + {0xfa5, 0x00fc00fc}, {0xbc6, 0x00fe0000}, {0xfe6, 0x00fe00fe}, {0xc07, 0x00ff0000}, {0xc27, 0x00ff00ff}, + {0xc48, 0x00ff8000}, {0xc89, 0x00ffc000}, {0xcca, 0x00ffe000}, {0xd0b, 0x00fff000}, {0xd4c, 0x00fff800}, + {0xd8d, 0x00fffc00}, {0xdce, 0x00fffe00}, {0xe0f, 0x00ffff00}, {0xe50, 0x00ffff80}, {0xe91, 0x00ffffc0}, + {0xed2, 0x00ffffe0}, {0xf13, 0x00fffff0}, {0xf54, 0x00fffff8}, {0xf95, 0x00fffffc}, {0xfd6, 0x00fffffe}, + {0x817, 0x00ffffff}, {0xa00, 0x01000000}, {0xe20, 0x01000100}, {0xe30, 0x01010101}, {0xa41, 0x01800000}, + {0xe61, 0x01800180}, {0xa82, 0x01c00000}, {0xea2, 0x01c001c0}, {0xac3, 0x01e00000}, {0xee3, 0x01e001e0}, + {0xb04, 0x01f00000}, {0xf24, 0x01f001f0}, {0xb45, 0x01f80000}, {0xf65, 0x01f801f8}, {0xb86, 0x01fc0000}, + {0xfa6, 0x01fc01fc}, {0xbc7, 0x01fe0000}, {0xfe7, 0x01fe01fe}, {0xc08, 0x01ff0000}, {0xc28, 0x01ff01ff}, + {0xc49, 0x01ff8000}, {0xc8a, 0x01ffc000}, {0xccb, 0x01ffe000}, {0xd0c, 0x01fff000}, {0xd4d, 0x01fff800}, + {0xd8e, 0x01fffc00}, {0xdcf, 0x01fffe00}, {0xe10, 0x01ffff00}, {0xe51, 0x01ffff80}, {0xe92, 0x01ffffc0}, + {0xed3, 0x01ffffe0}, {0xf14, 0x01fffff0}, {0xf55, 0x01fffff8}, {0xf96, 0x01fffffc}, {0xfd7, 0x01fffffe}, + {0x818, 0x01ffffff}, {0x9c0, 0x02000000}, {0xde0, 0x02000200}, {0xff0, 0x02020202}, {0xa01, 0x03000000}, + {0xe21, 0x03000300}, {0xe31, 0x03030303}, {0xa42, 0x03800000}, {0xe62, 0x03800380}, {0xa83, 0x03c00000}, + {0xea3, 0x03c003c0}, {0xac4, 0x03e00000}, {0xee4, 0x03e003e0}, {0xb05, 0x03f00000}, {0xf25, 0x03f003f0}, + {0xb46, 0x03f80000}, {0xf66, 0x03f803f8}, {0xb87, 0x03fc0000}, {0xfa7, 0x03fc03fc}, {0xbc8, 0x03fe0000}, + {0xfe8, 0x03fe03fe}, {0xc09, 0x03ff0000}, {0xc29, 0x03ff03ff}, {0xc4a, 0x03ff8000}, {0xc8b, 0x03ffc000}, + {0xccc, 0x03ffe000}, {0xd0d, 0x03fff000}, {0xd4e, 0x03fff800}, {0xd8f, 0x03fffc00}, {0xdd0, 0x03fffe00}, + {0xe11, 0x03ffff00}, {0xe52, 0x03ffff80}, {0xe93, 0x03ffffc0}, {0xed4, 0x03ffffe0}, {0xf15, 0x03fffff0}, + {0xf56, 0x03fffff8}, {0xf97, 0x03fffffc}, {0xfd8, 0x03fffffe}, {0x819, 0x03ffffff}, {0x980, 0x04000000}, + {0xda0, 0x04000400}, {0xfb0, 0x04040404}, {0x9c1, 0x06000000}, {0xde1, 0x06000600}, {0xff1, 0x06060606}, + {0xa02, 0x07000000}, {0xe22, 0x07000700}, {0xe32, 0x07070707}, {0xa43, 0x07800000}, {0xe63, 0x07800780}, + {0xa84, 0x07c00000}, {0xea4, 0x07c007c0}, {0xac5, 0x07e00000}, {0xee5, 0x07e007e0}, {0xb06, 0x07f00000}, + {0xf26, 0x07f007f0}, {0xb47, 0x07f80000}, {0xf67, 0x07f807f8}, {0xb88, 0x07fc0000}, {0xfa8, 0x07fc07fc}, + {0xbc9, 0x07fe0000}, {0xfe9, 0x07fe07fe}, {0xc0a, 0x07ff0000}, {0xc2a, 0x07ff07ff}, {0xc4b, 0x07ff8000}, + {0xc8c, 0x07ffc000}, {0xccd, 0x07ffe000}, {0xd0e, 0x07fff000}, {0xd4f, 0x07fff800}, {0xd90, 0x07fffc00}, + {0xdd1, 0x07fffe00}, {0xe12, 0x07ffff00}, {0xe53, 0x07ffff80}, {0xe94, 0x07ffffc0}, {0xed5, 0x07ffffe0}, + {0xf16, 0x07fffff0}, {0xf57, 0x07fffff8}, {0xf98, 0x07fffffc}, {0xfd9, 0x07fffffe}, {0x81a, 0x07ffffff}, + {0x940, 0x08000000}, {0xd60, 0x08000800}, {0xf70, 0x08080808}, {0x981, 0x0c000000}, {0xda1, 0x0c000c00}, + {0xfb1, 0x0c0c0c0c}, {0x9c2, 0x0e000000}, {0xde2, 0x0e000e00}, {0xff2, 0x0e0e0e0e}, {0xa03, 0x0f000000}, + {0xe23, 0x0f000f00}, {0xe33, 0x0f0f0f0f}, {0xa44, 0x0f800000}, {0xe64, 0x0f800f80}, {0xa85, 0x0fc00000}, + {0xea5, 0x0fc00fc0}, {0xac6, 0x0fe00000}, {0xee6, 0x0fe00fe0}, {0xb07, 0x0ff00000}, {0xf27, 0x0ff00ff0}, + {0xb48, 0x0ff80000}, {0xf68, 0x0ff80ff8}, {0xb89, 0x0ffc0000}, {0xfa9, 0x0ffc0ffc}, {0xbca, 0x0ffe0000}, + {0xfea, 0x0ffe0ffe}, {0xc0b, 0x0fff0000}, {0xc2b, 0x0fff0fff}, {0xc4c, 0x0fff8000}, {0xc8d, 0x0fffc000}, + {0xcce, 0x0fffe000}, {0xd0f, 0x0ffff000}, {0xd50, 0x0ffff800}, {0xd91, 0x0ffffc00}, {0xdd2, 0x0ffffe00}, + {0xe13, 0x0fffff00}, {0xe54, 0x0fffff80}, {0xe95, 0x0fffffc0}, {0xed6, 0x0fffffe0}, {0xf17, 0x0ffffff0}, + {0xf58, 0x0ffffff8}, {0xf99, 0x0ffffffc}, {0xfda, 0x0ffffffe}, {0x81b, 0x0fffffff}, {0x900, 0x10000000}, + {0xd20, 0x10001000}, {0xf30, 0x10101010}, {0xf38, 0x11111111}, {0x941, 0x18000000}, {0xd61, 0x18001800}, + {0xf71, 0x18181818}, {0x982, 0x1c000000}, {0xda2, 0x1c001c00}, {0xfb2, 0x1c1c1c1c}, {0x9c3, 0x1e000000}, + {0xde3, 0x1e001e00}, {0xff3, 0x1e1e1e1e}, {0xa04, 0x1f000000}, {0xe24, 0x1f001f00}, {0xe34, 0x1f1f1f1f}, + {0xa45, 0x1f800000}, {0xe65, 0x1f801f80}, {0xa86, 0x1fc00000}, {0xea6, 0x1fc01fc0}, {0xac7, 0x1fe00000}, + {0xee7, 0x1fe01fe0}, {0xb08, 0x1ff00000}, {0xf28, 0x1ff01ff0}, {0xb49, 0x1ff80000}, {0xf69, 0x1ff81ff8}, + {0xb8a, 0x1ffc0000}, {0xfaa, 0x1ffc1ffc}, {0xbcb, 0x1ffe0000}, {0xfeb, 0x1ffe1ffe}, {0xc0c, 0x1fff0000}, + {0xc2c, 0x1fff1fff}, {0xc4d, 0x1fff8000}, {0xc8e, 0x1fffc000}, {0xccf, 0x1fffe000}, {0xd10, 0x1ffff000}, + {0xd51, 0x1ffff800}, {0xd92, 0x1ffffc00}, {0xdd3, 0x1ffffe00}, {0xe14, 0x1fffff00}, {0xe55, 0x1fffff80}, + {0xe96, 0x1fffffc0}, {0xed7, 0x1fffffe0}, {0xf18, 0x1ffffff0}, {0xf59, 0x1ffffff8}, {0xf9a, 0x1ffffffc}, + {0xfdb, 0x1ffffffe}, {0x81c, 0x1fffffff}, {0x8c0, 0x20000000}, {0xce0, 0x20002000}, {0xef0, 0x20202020}, + {0xff8, 0x22222222}, {0x901, 0x30000000}, {0xd21, 0x30003000}, {0xf31, 0x30303030}, {0xf39, 0x33333333}, + {0x942, 0x38000000}, {0xd62, 0x38003800}, {0xf72, 0x38383838}, {0x983, 0x3c000000}, {0xda3, 0x3c003c00}, + {0xfb3, 0x3c3c3c3c}, {0x9c4, 0x3e000000}, {0xde4, 0x3e003e00}, {0xff4, 0x3e3e3e3e}, {0xa05, 0x3f000000}, + {0xe25, 0x3f003f00}, {0xe35, 0x3f3f3f3f}, {0xa46, 0x3f800000}, {0xe66, 0x3f803f80}, {0xa87, 0x3fc00000}, + {0xea7, 0x3fc03fc0}, {0xac8, 0x3fe00000}, {0xee8, 0x3fe03fe0}, {0xb09, 0x3ff00000}, {0xf29, 0x3ff03ff0}, + {0xb4a, 0x3ff80000}, {0xf6a, 0x3ff83ff8}, {0xb8b, 0x3ffc0000}, {0xfab, 0x3ffc3ffc}, {0xbcc, 0x3ffe0000}, + {0xfec, 0x3ffe3ffe}, {0xc0d, 0x3fff0000}, {0xc2d, 0x3fff3fff}, {0xc4e, 0x3fff8000}, {0xc8f, 0x3fffc000}, + {0xcd0, 0x3fffe000}, {0xd11, 0x3ffff000}, {0xd52, 0x3ffff800}, {0xd93, 0x3ffffc00}, {0xdd4, 0x3ffffe00}, + {0xe15, 0x3fffff00}, {0xe56, 0x3fffff80}, {0xe97, 0x3fffffc0}, {0xed8, 0x3fffffe0}, {0xf19, 0x3ffffff0}, + {0xf5a, 0x3ffffff8}, {0xf9b, 0x3ffffffc}, {0xfdc, 0x3ffffffe}, {0x81d, 0x3fffffff}, {0x880, 0x40000000}, + {0xca0, 0x40004000}, {0xeb0, 0x40404040}, {0xfb8, 0x44444444}, {0xfbc, 0x55555555}, {0x8c1, 0x60000000}, + {0xce1, 0x60006000}, {0xef1, 0x60606060}, {0xff9, 0x66666666}, {0x902, 0x70000000}, {0xd22, 0x70007000}, + {0xf32, 0x70707070}, {0xf3a, 0x77777777}, {0x943, 0x78000000}, {0xd63, 0x78007800}, {0xf73, 0x78787878}, + {0x984, 0x7c000000}, {0xda4, 0x7c007c00}, {0xfb4, 0x7c7c7c7c}, {0x9c5, 0x7e000000}, {0xde5, 0x7e007e00}, + {0xff5, 0x7e7e7e7e}, {0xa06, 0x7f000000}, {0xe26, 0x7f007f00}, {0xe36, 0x7f7f7f7f}, {0xa47, 0x7f800000}, + {0xe67, 0x7f807f80}, {0xa88, 0x7fc00000}, {0xea8, 0x7fc07fc0}, {0xac9, 0x7fe00000}, {0xee9, 0x7fe07fe0}, + {0xb0a, 0x7ff00000}, {0xf2a, 0x7ff07ff0}, {0xb4b, 0x7ff80000}, {0xf6b, 0x7ff87ff8}, {0xb8c, 0x7ffc0000}, + {0xfac, 0x7ffc7ffc}, {0xbcd, 0x7ffe0000}, {0xfed, 0x7ffe7ffe}, {0xc0e, 0x7fff0000}, {0xc2e, 0x7fff7fff}, + {0xc4f, 0x7fff8000}, {0xc90, 0x7fffc000}, {0xcd1, 0x7fffe000}, {0xd12, 0x7ffff000}, {0xd53, 0x7ffff800}, + {0xd94, 0x7ffffc00}, {0xdd5, 0x7ffffe00}, {0xe16, 0x7fffff00}, {0xe57, 0x7fffff80}, {0xe98, 0x7fffffc0}, + {0xed9, 0x7fffffe0}, {0xf1a, 0x7ffffff0}, {0xf5b, 0x7ffffff8}, {0xf9c, 0x7ffffffc}, {0xfdd, 0x7ffffffe}, + {0x81e, 0x7fffffff}, {0x840, 0x80000000}, {0x841, 0x80000001}, {0x842, 0x80000003}, {0x843, 0x80000007}, + {0x844, 0x8000000f}, {0x845, 0x8000001f}, {0x846, 0x8000003f}, {0x847, 0x8000007f}, {0x848, 0x800000ff}, + {0x849, 0x800001ff}, {0x84a, 0x800003ff}, {0x84b, 0x800007ff}, {0x84c, 0x80000fff}, {0x84d, 0x80001fff}, + {0x84e, 0x80003fff}, {0x84f, 0x80007fff}, {0xc60, 0x80008000}, {0x850, 0x8000ffff}, {0xc61, 0x80018001}, + {0x851, 0x8001ffff}, {0xc62, 0x80038003}, {0x852, 0x8003ffff}, {0xc63, 0x80078007}, {0x853, 0x8007ffff}, + {0xc64, 0x800f800f}, {0x854, 0x800fffff}, {0xc65, 0x801f801f}, {0x855, 0x801fffff}, {0xc66, 0x803f803f}, + {0x856, 0x803fffff}, {0xc67, 0x807f807f}, {0x857, 0x807fffff}, {0xe70, 0x80808080}, {0xc68, 0x80ff80ff}, + {0x858, 0x80ffffff}, {0xe71, 0x81818181}, {0xc69, 0x81ff81ff}, {0x859, 0x81ffffff}, {0xe72, 0x83838383}, + {0xc6a, 0x83ff83ff}, {0x85a, 0x83ffffff}, {0xe73, 0x87878787}, {0xc6b, 0x87ff87ff}, {0x85b, 0x87ffffff}, + {0xf78, 0x88888888}, {0xe74, 0x8f8f8f8f}, {0xc6c, 0x8fff8fff}, {0x85c, 0x8fffffff}, {0xf79, 0x99999999}, + {0xe75, 0x9f9f9f9f}, {0xc6d, 0x9fff9fff}, {0x85d, 0x9fffffff}, {0xffc, 0xaaaaaaaa}, {0xf7a, 0xbbbbbbbb}, + {0xe76, 0xbfbfbfbf}, {0xc6e, 0xbfffbfff}, {0x85e, 0xbfffffff}, {0x881, 0xc0000000}, {0x882, 0xc0000001}, + {0x883, 0xc0000003}, {0x884, 0xc0000007}, {0x885, 0xc000000f}, {0x886, 0xc000001f}, {0x887, 0xc000003f}, + {0x888, 0xc000007f}, {0x889, 0xc00000ff}, {0x88a, 0xc00001ff}, {0x88b, 0xc00003ff}, {0x88c, 0xc00007ff}, + {0x88d, 0xc0000fff}, {0x88e, 0xc0001fff}, {0x88f, 0xc0003fff}, {0x890, 0xc0007fff}, {0xca1, 0xc000c000}, + {0x891, 0xc000ffff}, {0xca2, 0xc001c001}, {0x892, 0xc001ffff}, {0xca3, 0xc003c003}, {0x893, 0xc003ffff}, + {0xca4, 0xc007c007}, {0x894, 0xc007ffff}, {0xca5, 0xc00fc00f}, {0x895, 0xc00fffff}, {0xca6, 0xc01fc01f}, + {0x896, 0xc01fffff}, {0xca7, 0xc03fc03f}, {0x897, 0xc03fffff}, {0xca8, 0xc07fc07f}, {0x898, 0xc07fffff}, + {0xeb1, 0xc0c0c0c0}, {0xca9, 0xc0ffc0ff}, {0x899, 0xc0ffffff}, {0xeb2, 0xc1c1c1c1}, {0xcaa, 0xc1ffc1ff}, + {0x89a, 0xc1ffffff}, {0xeb3, 0xc3c3c3c3}, {0xcab, 0xc3ffc3ff}, {0x89b, 0xc3ffffff}, {0xeb4, 0xc7c7c7c7}, + {0xcac, 0xc7ffc7ff}, {0x89c, 0xc7ffffff}, {0xfb9, 0xcccccccc}, {0xeb5, 0xcfcfcfcf}, {0xcad, 0xcfffcfff}, + {0x89d, 0xcfffffff}, {0xfba, 0xdddddddd}, {0xeb6, 0xdfdfdfdf}, {0xcae, 0xdfffdfff}, {0x89e, 0xdfffffff}, + {0x8c2, 0xe0000000}, {0x8c3, 0xe0000001}, {0x8c4, 0xe0000003}, {0x8c5, 0xe0000007}, {0x8c6, 0xe000000f}, + {0x8c7, 0xe000001f}, {0x8c8, 0xe000003f}, {0x8c9, 0xe000007f}, {0x8ca, 0xe00000ff}, {0x8cb, 0xe00001ff}, + {0x8cc, 0xe00003ff}, {0x8cd, 0xe00007ff}, {0x8ce, 0xe0000fff}, {0x8cf, 0xe0001fff}, {0x8d0, 0xe0003fff}, + {0x8d1, 0xe0007fff}, {0xce2, 0xe000e000}, {0x8d2, 0xe000ffff}, {0xce3, 0xe001e001}, {0x8d3, 0xe001ffff}, + {0xce4, 0xe003e003}, {0x8d4, 0xe003ffff}, {0xce5, 0xe007e007}, {0x8d5, 0xe007ffff}, {0xce6, 0xe00fe00f}, + {0x8d6, 0xe00fffff}, {0xce7, 0xe01fe01f}, {0x8d7, 0xe01fffff}, {0xce8, 0xe03fe03f}, {0x8d8, 0xe03fffff}, + {0xce9, 0xe07fe07f}, {0x8d9, 0xe07fffff}, {0xef2, 0xe0e0e0e0}, {0xcea, 0xe0ffe0ff}, {0x8da, 0xe0ffffff}, + {0xef3, 0xe1e1e1e1}, {0xceb, 0xe1ffe1ff}, {0x8db, 0xe1ffffff}, {0xef4, 0xe3e3e3e3}, {0xcec, 0xe3ffe3ff}, + {0x8dc, 0xe3ffffff}, {0xef5, 0xe7e7e7e7}, {0xced, 0xe7ffe7ff}, {0x8dd, 0xe7ffffff}, {0xffa, 0xeeeeeeee}, + {0xef6, 0xefefefef}, {0xcee, 0xefffefff}, {0x8de, 0xefffffff}, {0x903, 0xf0000000}, {0x904, 0xf0000001}, + {0x905, 0xf0000003}, {0x906, 0xf0000007}, {0x907, 0xf000000f}, {0x908, 0xf000001f}, {0x909, 0xf000003f}, + {0x90a, 0xf000007f}, {0x90b, 0xf00000ff}, {0x90c, 0xf00001ff}, {0x90d, 0xf00003ff}, {0x90e, 0xf00007ff}, + {0x90f, 0xf0000fff}, {0x910, 0xf0001fff}, {0x911, 0xf0003fff}, {0x912, 0xf0007fff}, {0xd23, 0xf000f000}, + {0x913, 0xf000ffff}, {0xd24, 0xf001f001}, {0x914, 0xf001ffff}, {0xd25, 0xf003f003}, {0x915, 0xf003ffff}, + {0xd26, 0xf007f007}, {0x916, 0xf007ffff}, {0xd27, 0xf00ff00f}, {0x917, 0xf00fffff}, {0xd28, 0xf01ff01f}, + {0x918, 0xf01fffff}, {0xd29, 0xf03ff03f}, {0x919, 0xf03fffff}, {0xd2a, 0xf07ff07f}, {0x91a, 0xf07fffff}, + {0xf33, 0xf0f0f0f0}, {0xd2b, 0xf0fff0ff}, {0x91b, 0xf0ffffff}, {0xf34, 0xf1f1f1f1}, {0xd2c, 0xf1fff1ff}, + {0x91c, 0xf1ffffff}, {0xf35, 0xf3f3f3f3}, {0xd2d, 0xf3fff3ff}, {0x91d, 0xf3ffffff}, {0xf36, 0xf7f7f7f7}, + {0xd2e, 0xf7fff7ff}, {0x91e, 0xf7ffffff}, {0x944, 0xf8000000}, {0x945, 0xf8000001}, {0x946, 0xf8000003}, + {0x947, 0xf8000007}, {0x948, 0xf800000f}, {0x949, 0xf800001f}, {0x94a, 0xf800003f}, {0x94b, 0xf800007f}, + {0x94c, 0xf80000ff}, {0x94d, 0xf80001ff}, {0x94e, 0xf80003ff}, {0x94f, 0xf80007ff}, {0x950, 0xf8000fff}, + {0x951, 0xf8001fff}, {0x952, 0xf8003fff}, {0x953, 0xf8007fff}, {0xd64, 0xf800f800}, {0x954, 0xf800ffff}, + {0xd65, 0xf801f801}, {0x955, 0xf801ffff}, {0xd66, 0xf803f803}, {0x956, 0xf803ffff}, {0xd67, 0xf807f807}, + {0x957, 0xf807ffff}, {0xd68, 0xf80ff80f}, {0x958, 0xf80fffff}, {0xd69, 0xf81ff81f}, {0x959, 0xf81fffff}, + {0xd6a, 0xf83ff83f}, {0x95a, 0xf83fffff}, {0xd6b, 0xf87ff87f}, {0x95b, 0xf87fffff}, {0xf74, 0xf8f8f8f8}, + {0xd6c, 0xf8fff8ff}, {0x95c, 0xf8ffffff}, {0xf75, 0xf9f9f9f9}, {0xd6d, 0xf9fff9ff}, {0x95d, 0xf9ffffff}, + {0xf76, 0xfbfbfbfb}, {0xd6e, 0xfbfffbff}, {0x95e, 0xfbffffff}, {0x985, 0xfc000000}, {0x986, 0xfc000001}, + {0x987, 0xfc000003}, {0x988, 0xfc000007}, {0x989, 0xfc00000f}, {0x98a, 0xfc00001f}, {0x98b, 0xfc00003f}, + {0x98c, 0xfc00007f}, {0x98d, 0xfc0000ff}, {0x98e, 0xfc0001ff}, {0x98f, 0xfc0003ff}, {0x990, 0xfc0007ff}, + {0x991, 0xfc000fff}, {0x992, 0xfc001fff}, {0x993, 0xfc003fff}, {0x994, 0xfc007fff}, {0xda5, 0xfc00fc00}, + {0x995, 0xfc00ffff}, {0xda6, 0xfc01fc01}, {0x996, 0xfc01ffff}, {0xda7, 0xfc03fc03}, {0x997, 0xfc03ffff}, + {0xda8, 0xfc07fc07}, {0x998, 0xfc07ffff}, {0xda9, 0xfc0ffc0f}, {0x999, 0xfc0fffff}, {0xdaa, 0xfc1ffc1f}, + {0x99a, 0xfc1fffff}, {0xdab, 0xfc3ffc3f}, {0x99b, 0xfc3fffff}, {0xdac, 0xfc7ffc7f}, {0x99c, 0xfc7fffff}, + {0xfb5, 0xfcfcfcfc}, {0xdad, 0xfcfffcff}, {0x99d, 0xfcffffff}, {0xfb6, 0xfdfdfdfd}, {0xdae, 0xfdfffdff}, + {0x99e, 0xfdffffff}, {0x9c6, 0xfe000000}, {0x9c7, 0xfe000001}, {0x9c8, 0xfe000003}, {0x9c9, 0xfe000007}, + {0x9ca, 0xfe00000f}, {0x9cb, 0xfe00001f}, {0x9cc, 0xfe00003f}, {0x9cd, 0xfe00007f}, {0x9ce, 0xfe0000ff}, + {0x9cf, 0xfe0001ff}, {0x9d0, 0xfe0003ff}, {0x9d1, 0xfe0007ff}, {0x9d2, 0xfe000fff}, {0x9d3, 0xfe001fff}, + {0x9d4, 0xfe003fff}, {0x9d5, 0xfe007fff}, {0xde6, 0xfe00fe00}, {0x9d6, 0xfe00ffff}, {0xde7, 0xfe01fe01}, + {0x9d7, 0xfe01ffff}, {0xde8, 0xfe03fe03}, {0x9d8, 0xfe03ffff}, {0xde9, 0xfe07fe07}, {0x9d9, 0xfe07ffff}, + {0xdea, 0xfe0ffe0f}, {0x9da, 0xfe0fffff}, {0xdeb, 0xfe1ffe1f}, {0x9db, 0xfe1fffff}, {0xdec, 0xfe3ffe3f}, + {0x9dc, 0xfe3fffff}, {0xded, 0xfe7ffe7f}, {0x9dd, 0xfe7fffff}, {0xff6, 0xfefefefe}, {0xdee, 0xfefffeff}, + {0x9de, 0xfeffffff}, {0xa07, 0xff000000}, {0xa08, 0xff000001}, {0xa09, 0xff000003}, {0xa0a, 0xff000007}, + {0xa0b, 0xff00000f}, {0xa0c, 0xff00001f}, {0xa0d, 0xff00003f}, {0xa0e, 0xff00007f}, {0xa0f, 0xff0000ff}, + {0xa10, 0xff0001ff}, {0xa11, 0xff0003ff}, {0xa12, 0xff0007ff}, {0xa13, 0xff000fff}, {0xa14, 0xff001fff}, + {0xa15, 0xff003fff}, {0xa16, 0xff007fff}, {0xe27, 0xff00ff00}, {0xa17, 0xff00ffff}, {0xe28, 0xff01ff01}, + {0xa18, 0xff01ffff}, {0xe29, 0xff03ff03}, {0xa19, 0xff03ffff}, {0xe2a, 0xff07ff07}, {0xa1a, 0xff07ffff}, + {0xe2b, 0xff0fff0f}, {0xa1b, 0xff0fffff}, {0xe2c, 0xff1fff1f}, {0xa1c, 0xff1fffff}, {0xe2d, 0xff3fff3f}, + {0xa1d, 0xff3fffff}, {0xe2e, 0xff7fff7f}, {0xa1e, 0xff7fffff}, {0xa48, 0xff800000}, {0xa49, 0xff800001}, + {0xa4a, 0xff800003}, {0xa4b, 0xff800007}, {0xa4c, 0xff80000f}, {0xa4d, 0xff80001f}, {0xa4e, 0xff80003f}, + {0xa4f, 0xff80007f}, {0xa50, 0xff8000ff}, {0xa51, 0xff8001ff}, {0xa52, 0xff8003ff}, {0xa53, 0xff8007ff}, + {0xa54, 0xff800fff}, {0xa55, 0xff801fff}, {0xa56, 0xff803fff}, {0xa57, 0xff807fff}, {0xe68, 0xff80ff80}, + {0xa58, 0xff80ffff}, {0xe69, 0xff81ff81}, {0xa59, 0xff81ffff}, {0xe6a, 0xff83ff83}, {0xa5a, 0xff83ffff}, + {0xe6b, 0xff87ff87}, {0xa5b, 0xff87ffff}, {0xe6c, 0xff8fff8f}, {0xa5c, 0xff8fffff}, {0xe6d, 0xff9fff9f}, + {0xa5d, 0xff9fffff}, {0xe6e, 0xffbfffbf}, {0xa5e, 0xffbfffff}, {0xa89, 0xffc00000}, {0xa8a, 0xffc00001}, + {0xa8b, 0xffc00003}, {0xa8c, 0xffc00007}, {0xa8d, 0xffc0000f}, {0xa8e, 0xffc0001f}, {0xa8f, 0xffc0003f}, + {0xa90, 0xffc0007f}, {0xa91, 0xffc000ff}, {0xa92, 0xffc001ff}, {0xa93, 0xffc003ff}, {0xa94, 0xffc007ff}, + {0xa95, 0xffc00fff}, {0xa96, 0xffc01fff}, {0xa97, 0xffc03fff}, {0xa98, 0xffc07fff}, {0xea9, 0xffc0ffc0}, + {0xa99, 0xffc0ffff}, {0xeaa, 0xffc1ffc1}, {0xa9a, 0xffc1ffff}, {0xeab, 0xffc3ffc3}, {0xa9b, 0xffc3ffff}, + {0xeac, 0xffc7ffc7}, {0xa9c, 0xffc7ffff}, {0xead, 0xffcfffcf}, {0xa9d, 0xffcfffff}, {0xeae, 0xffdfffdf}, + {0xa9e, 0xffdfffff}, {0xaca, 0xffe00000}, {0xacb, 0xffe00001}, {0xacc, 0xffe00003}, {0xacd, 0xffe00007}, + {0xace, 0xffe0000f}, {0xacf, 0xffe0001f}, {0xad0, 0xffe0003f}, {0xad1, 0xffe0007f}, {0xad2, 0xffe000ff}, + {0xad3, 0xffe001ff}, {0xad4, 0xffe003ff}, {0xad5, 0xffe007ff}, {0xad6, 0xffe00fff}, {0xad7, 0xffe01fff}, + {0xad8, 0xffe03fff}, {0xad9, 0xffe07fff}, {0xeea, 0xffe0ffe0}, {0xada, 0xffe0ffff}, {0xeeb, 0xffe1ffe1}, + {0xadb, 0xffe1ffff}, {0xeec, 0xffe3ffe3}, {0xadc, 0xffe3ffff}, {0xeed, 0xffe7ffe7}, {0xadd, 0xffe7ffff}, + {0xeee, 0xffefffef}, {0xade, 0xffefffff}, {0xb0b, 0xfff00000}, {0xb0c, 0xfff00001}, {0xb0d, 0xfff00003}, + {0xb0e, 0xfff00007}, {0xb0f, 0xfff0000f}, {0xb10, 0xfff0001f}, {0xb11, 0xfff0003f}, {0xb12, 0xfff0007f}, + {0xb13, 0xfff000ff}, {0xb14, 0xfff001ff}, {0xb15, 0xfff003ff}, {0xb16, 0xfff007ff}, {0xb17, 0xfff00fff}, + {0xb18, 0xfff01fff}, {0xb19, 0xfff03fff}, {0xb1a, 0xfff07fff}, {0xf2b, 0xfff0fff0}, {0xb1b, 0xfff0ffff}, + {0xf2c, 0xfff1fff1}, {0xb1c, 0xfff1ffff}, {0xf2d, 0xfff3fff3}, {0xb1d, 0xfff3ffff}, {0xf2e, 0xfff7fff7}, + {0xb1e, 0xfff7ffff}, {0xb4c, 0xfff80000}, {0xb4d, 0xfff80001}, {0xb4e, 0xfff80003}, {0xb4f, 0xfff80007}, + {0xb50, 0xfff8000f}, {0xb51, 0xfff8001f}, {0xb52, 0xfff8003f}, {0xb53, 0xfff8007f}, {0xb54, 0xfff800ff}, + {0xb55, 0xfff801ff}, {0xb56, 0xfff803ff}, {0xb57, 0xfff807ff}, {0xb58, 0xfff80fff}, {0xb59, 0xfff81fff}, + {0xb5a, 0xfff83fff}, {0xb5b, 0xfff87fff}, {0xf6c, 0xfff8fff8}, {0xb5c, 0xfff8ffff}, {0xf6d, 0xfff9fff9}, + {0xb5d, 0xfff9ffff}, {0xf6e, 0xfffbfffb}, {0xb5e, 0xfffbffff}, {0xb8d, 0xfffc0000}, {0xb8e, 0xfffc0001}, + {0xb8f, 0xfffc0003}, {0xb90, 0xfffc0007}, {0xb91, 0xfffc000f}, {0xb92, 0xfffc001f}, {0xb93, 0xfffc003f}, + {0xb94, 0xfffc007f}, {0xb95, 0xfffc00ff}, {0xb96, 0xfffc01ff}, {0xb97, 0xfffc03ff}, {0xb98, 0xfffc07ff}, + {0xb99, 0xfffc0fff}, {0xb9a, 0xfffc1fff}, {0xb9b, 0xfffc3fff}, {0xb9c, 0xfffc7fff}, {0xfad, 0xfffcfffc}, + {0xb9d, 0xfffcffff}, {0xfae, 0xfffdfffd}, {0xb9e, 0xfffdffff}, {0xbce, 0xfffe0000}, {0xbcf, 0xfffe0001}, + {0xbd0, 0xfffe0003}, {0xbd1, 0xfffe0007}, {0xbd2, 0xfffe000f}, {0xbd3, 0xfffe001f}, {0xbd4, 0xfffe003f}, + {0xbd5, 0xfffe007f}, {0xbd6, 0xfffe00ff}, {0xbd7, 0xfffe01ff}, {0xbd8, 0xfffe03ff}, {0xbd9, 0xfffe07ff}, + {0xbda, 0xfffe0fff}, {0xbdb, 0xfffe1fff}, {0xbdc, 0xfffe3fff}, {0xbdd, 0xfffe7fff}, {0xfee, 0xfffefffe}, + {0xbde, 0xfffeffff}, {0xc0f, 0xffff0000}, {0xc10, 0xffff0001}, {0xc11, 0xffff0003}, {0xc12, 0xffff0007}, + {0xc13, 0xffff000f}, {0xc14, 0xffff001f}, {0xc15, 0xffff003f}, {0xc16, 0xffff007f}, {0xc17, 0xffff00ff}, + {0xc18, 0xffff01ff}, {0xc19, 0xffff03ff}, {0xc1a, 0xffff07ff}, {0xc1b, 0xffff0fff}, {0xc1c, 0xffff1fff}, + {0xc1d, 0xffff3fff}, {0xc1e, 0xffff7fff}, {0xc50, 0xffff8000}, {0xc51, 0xffff8001}, {0xc52, 0xffff8003}, + {0xc53, 0xffff8007}, {0xc54, 0xffff800f}, {0xc55, 0xffff801f}, {0xc56, 0xffff803f}, {0xc57, 0xffff807f}, + {0xc58, 0xffff80ff}, {0xc59, 0xffff81ff}, {0xc5a, 0xffff83ff}, {0xc5b, 0xffff87ff}, {0xc5c, 0xffff8fff}, + {0xc5d, 0xffff9fff}, {0xc5e, 0xffffbfff}, {0xc91, 0xffffc000}, {0xc92, 0xffffc001}, {0xc93, 0xffffc003}, + {0xc94, 0xffffc007}, {0xc95, 0xffffc00f}, {0xc96, 0xffffc01f}, {0xc97, 0xffffc03f}, {0xc98, 0xffffc07f}, + {0xc99, 0xffffc0ff}, {0xc9a, 0xffffc1ff}, {0xc9b, 0xffffc3ff}, {0xc9c, 0xffffc7ff}, {0xc9d, 0xffffcfff}, + {0xc9e, 0xffffdfff}, {0xcd2, 0xffffe000}, {0xcd3, 0xffffe001}, {0xcd4, 0xffffe003}, {0xcd5, 0xffffe007}, + {0xcd6, 0xffffe00f}, {0xcd7, 0xffffe01f}, {0xcd8, 0xffffe03f}, {0xcd9, 0xffffe07f}, {0xcda, 0xffffe0ff}, + {0xcdb, 0xffffe1ff}, {0xcdc, 0xffffe3ff}, {0xcdd, 0xffffe7ff}, {0xcde, 0xffffefff}, {0xd13, 0xfffff000}, + {0xd14, 0xfffff001}, {0xd15, 0xfffff003}, {0xd16, 0xfffff007}, {0xd17, 0xfffff00f}, {0xd18, 0xfffff01f}, + {0xd19, 0xfffff03f}, {0xd1a, 0xfffff07f}, {0xd1b, 0xfffff0ff}, {0xd1c, 0xfffff1ff}, {0xd1d, 0xfffff3ff}, + {0xd1e, 0xfffff7ff}, {0xd54, 0xfffff800}, {0xd55, 0xfffff801}, {0xd56, 0xfffff803}, {0xd57, 0xfffff807}, + {0xd58, 0xfffff80f}, {0xd59, 0xfffff81f}, {0xd5a, 0xfffff83f}, {0xd5b, 0xfffff87f}, {0xd5c, 0xfffff8ff}, + {0xd5d, 0xfffff9ff}, {0xd5e, 0xfffffbff}, {0xd95, 0xfffffc00}, {0xd96, 0xfffffc01}, {0xd97, 0xfffffc03}, + {0xd98, 0xfffffc07}, {0xd99, 0xfffffc0f}, {0xd9a, 0xfffffc1f}, {0xd9b, 0xfffffc3f}, {0xd9c, 0xfffffc7f}, + {0xd9d, 0xfffffcff}, {0xd9e, 0xfffffdff}, {0xdd6, 0xfffffe00}, {0xdd7, 0xfffffe01}, {0xdd8, 0xfffffe03}, + {0xdd9, 0xfffffe07}, {0xdda, 0xfffffe0f}, {0xddb, 0xfffffe1f}, {0xddc, 0xfffffe3f}, {0xddd, 0xfffffe7f}, + {0xdde, 0xfffffeff}, {0xe17, 0xffffff00}, {0xe18, 0xffffff01}, {0xe19, 0xffffff03}, {0xe1a, 0xffffff07}, + {0xe1b, 0xffffff0f}, {0xe1c, 0xffffff1f}, {0xe1d, 0xffffff3f}, {0xe1e, 0xffffff7f}, {0xe58, 0xffffff80}, + {0xe59, 0xffffff81}, {0xe5a, 0xffffff83}, {0xe5b, 0xffffff87}, {0xe5c, 0xffffff8f}, {0xe5d, 0xffffff9f}, + {0xe5e, 0xffffffbf}, {0xe99, 0xffffffc0}, {0xe9a, 0xffffffc1}, {0xe9b, 0xffffffc3}, {0xe9c, 0xffffffc7}, + {0xe9d, 0xffffffcf}, {0xe9e, 0xffffffdf}, {0xeda, 0xffffffe0}, {0xedb, 0xffffffe1}, {0xedc, 0xffffffe3}, + {0xedd, 0xffffffe7}, {0xede, 0xffffffef}, {0xf1b, 0xfffffff0}, {0xf1c, 0xfffffff1}, {0xf1d, 0xfffffff3}, + {0xf1e, 0xfffffff7}, {0xf5c, 0xfffffff8}, {0xf5d, 0xfffffff9}, {0xf5e, 0xfffffffb}, {0xf9d, 0xfffffffc}, + {0xf9e, 0xfffffffd}, {0xfde, 0xfffffffe}, +}; uint32_t host_arm64_find_imm(uint32_t data) { - int l = 0, r = IMM_NR - 1; + int l = 0, r = IMM_NR - 1; - while (l <= r) { - int m = (l + r) >> 1; + while (l <= r) { + int m = (l + r) >> 1; - if (imm_table[m][1] < data) - l = m + 1; - else if (imm_table[m][1] > data) - r = m - 1; - else - return imm_table[m][0]; - } - return 0; + if (imm_table[m][1] < data) + l = m + 1; + else if (imm_table[m][1] > data) + r = m - 1; + else + return imm_table[m][0]; + } + return 0; } diff --git a/src/codegen/arm64/codegen_backend_arm64_ops.c b/src/codegen/arm64/codegen_backend_arm64_ops.c index 2f337605..082601bd 100644 --- a/src/codegen/arm64/codegen_backend_arm64_ops.c +++ b/src/codegen/arm64/codegen_backend_arm64_ops.c @@ -7,16 +7,15 @@ #include "codegen_backend_arm64_defs.h" #include "codegen_backend_arm64_ops.h" - -#define Rt(x) (x) -#define Rd(x) (x) -#define Rn(x) ((x) << 5) +#define Rt(x) (x) +#define Rd(x) (x) +#define Rn(x) ((x) << 5) #define Rt2(x) ((x) << 10) -#define Rm(x) ((x) << 16) +#define Rm(x) ((x) << 16) #define shift_imm6(x) ((x) << 10) -#define DATA_OFFSET_UP (1 << 23) +#define DATA_OFFSET_UP (1 << 23) #define DATA_OFFSET_DOWN (0 << 23) #define COND_EQ (0x0) @@ -37,180 +36,180 @@ #define CSEL_COND(cond) ((cond) << 12) #define OPCODE_SHIFT 24 -#define OPCODE_ADD_IMM (0x11 << OPCODE_SHIFT) -#define OPCODE_ADDX_IMM (0x91 << OPCODE_SHIFT) -#define OPCODE_ADR (0x10 << OPCODE_SHIFT) -#define OPCODE_B (0x14 << OPCODE_SHIFT) -#define OPCODE_BCOND (0x54 << OPCODE_SHIFT) -#define OPCODE_CBNZ (0xb5 << OPCODE_SHIFT) -#define OPCODE_CBZ (0xb4 << OPCODE_SHIFT) -#define OPCODE_CMN_IMM (0x31 << OPCODE_SHIFT) -#define OPCODE_CMNX_IMM (0xb1 << OPCODE_SHIFT) -#define OPCODE_CMP_IMM (0x71 << OPCODE_SHIFT) -#define OPCODE_CMPX_IMM (0xf1 << OPCODE_SHIFT) -#define OPCODE_SUB_IMM (0x51 << OPCODE_SHIFT) -#define OPCODE_SUBX_IMM (0xd1 << OPCODE_SHIFT) -#define OPCODE_TBNZ (0x37 << OPCODE_SHIFT) -#define OPCODE_TBZ (0x36 << OPCODE_SHIFT) +#define OPCODE_ADD_IMM (0x11 << OPCODE_SHIFT) +#define OPCODE_ADDX_IMM (0x91 << OPCODE_SHIFT) +#define OPCODE_ADR (0x10 << OPCODE_SHIFT) +#define OPCODE_B (0x14 << OPCODE_SHIFT) +#define OPCODE_BCOND (0x54 << OPCODE_SHIFT) +#define OPCODE_CBNZ (0xb5 << OPCODE_SHIFT) +#define OPCODE_CBZ (0xb4 << OPCODE_SHIFT) +#define OPCODE_CMN_IMM (0x31 << OPCODE_SHIFT) +#define OPCODE_CMNX_IMM (0xb1 << OPCODE_SHIFT) +#define OPCODE_CMP_IMM (0x71 << OPCODE_SHIFT) +#define OPCODE_CMPX_IMM (0xf1 << OPCODE_SHIFT) +#define OPCODE_SUB_IMM (0x51 << OPCODE_SHIFT) +#define OPCODE_SUBX_IMM (0xd1 << OPCODE_SHIFT) +#define OPCODE_TBNZ (0x37 << OPCODE_SHIFT) +#define OPCODE_TBZ (0x36 << OPCODE_SHIFT) -#define OPCODE_AND_IMM (0x024 << 23) -#define OPCODE_ANDS_IMM (0x0e4 << 23) -#define OPCODE_EOR_IMM (0x0a4 << 23) -#define OPCODE_MOVK_W (0x0e5 << 23) -#define OPCODE_MOVK_X (0x1e5 << 23) -#define OPCODE_MOVZ_W (0x0a5 << 23) -#define OPCODE_MOVZ_X (0x1a5 << 23) -#define OPCODE_ORR_IMM (0x064 << 23) +#define OPCODE_AND_IMM (0x024 << 23) +#define OPCODE_ANDS_IMM (0x0e4 << 23) +#define OPCODE_EOR_IMM (0x0a4 << 23) +#define OPCODE_MOVK_W (0x0e5 << 23) +#define OPCODE_MOVK_X (0x1e5 << 23) +#define OPCODE_MOVZ_W (0x0a5 << 23) +#define OPCODE_MOVZ_X (0x1a5 << 23) +#define OPCODE_ORR_IMM (0x064 << 23) -#define OPCODE_BFI (0x0cc << 22) -#define OPCODE_LDR_IMM_W (0x2e5 << 22) -#define OPCODE_LDR_IMM_X (0x3e5 << 22) -#define OPCODE_LDR_IMM_F64 (0x3f5 << 22) -#define OPCODE_LDRB_IMM_W (0x0e5 << 22) -#define OPCODE_LDRH_IMM (0x1e5 << 22) +#define OPCODE_BFI (0x0cc << 22) +#define OPCODE_LDR_IMM_W (0x2e5 << 22) +#define OPCODE_LDR_IMM_X (0x3e5 << 22) +#define OPCODE_LDR_IMM_F64 (0x3f5 << 22) +#define OPCODE_LDRB_IMM_W (0x0e5 << 22) +#define OPCODE_LDRH_IMM (0x1e5 << 22) #define OPCODE_LDP_POSTIDX_X (0x2a3 << 22) -#define OPCODE_SBFX (0x04c << 22) -#define OPCODE_STP_PREIDX_X (0x2a6 << 22) -#define OPCODE_STR_IMM_W (0x2e4 << 22) -#define OPCODE_STR_IMM_Q (0x3e4 << 22) -#define OPCODE_STR_IMM_F64 (0x3f4 << 22) -#define OPCODE_STRB_IMM (0x0e4 << 22) -#define OPCODE_STRH_IMM (0x1e4 << 22) -#define OPCODE_UBFX (0x14c << 22) +#define OPCODE_SBFX (0x04c << 22) +#define OPCODE_STP_PREIDX_X (0x2a6 << 22) +#define OPCODE_STR_IMM_W (0x2e4 << 22) +#define OPCODE_STR_IMM_Q (0x3e4 << 22) +#define OPCODE_STR_IMM_F64 (0x3f4 << 22) +#define OPCODE_STRB_IMM (0x0e4 << 22) +#define OPCODE_STRH_IMM (0x1e4 << 22) +#define OPCODE_UBFX (0x14c << 22) -#define OPCODE_ADD_LSL (0x058 << 21) -#define OPCODE_ADD_LSR (0x05a << 21) -#define OPCODE_ADDX_LSL (0x458 << 21) -#define OPCODE_AND_ASR (0x054 << 21) -#define OPCODE_AND_LSL (0x050 << 21) -#define OPCODE_AND_ROR (0x056 << 21) -#define OPCODE_ANDS_LSL (0x350 << 21) -#define OPCODE_CMP_LSL (0x358 << 21) -#define OPCODE_CSEL (0x0d4 << 21) -#define OPCODE_EOR_LSL (0x250 << 21) -#define OPCODE_ORR_ASR (0x154 << 21) -#define OPCODE_ORR_LSL (0x150 << 21) -#define OPCODE_ORR_LSR (0x152 << 21) -#define OPCODE_ORR_ROR (0x156 << 21) -#define OPCODE_ORRX_LSL (0x550 << 21) -#define OPCODE_SUB_LSL (0x258 << 21) -#define OPCODE_SUB_LSR (0x25a << 21) -#define OPCODE_SUBX_LSL (0x658 << 21) +#define OPCODE_ADD_LSL (0x058 << 21) +#define OPCODE_ADD_LSR (0x05a << 21) +#define OPCODE_ADDX_LSL (0x458 << 21) +#define OPCODE_AND_ASR (0x054 << 21) +#define OPCODE_AND_LSL (0x050 << 21) +#define OPCODE_AND_ROR (0x056 << 21) +#define OPCODE_ANDS_LSL (0x350 << 21) +#define OPCODE_CMP_LSL (0x358 << 21) +#define OPCODE_CSEL (0x0d4 << 21) +#define OPCODE_EOR_LSL (0x250 << 21) +#define OPCODE_ORR_ASR (0x154 << 21) +#define OPCODE_ORR_LSL (0x150 << 21) +#define OPCODE_ORR_LSR (0x152 << 21) +#define OPCODE_ORR_ROR (0x156 << 21) +#define OPCODE_ORRX_LSL (0x550 << 21) +#define OPCODE_SUB_LSL (0x258 << 21) +#define OPCODE_SUB_LSR (0x25a << 21) +#define OPCODE_SUBX_LSL (0x658 << 21) -#define OPCODE_ADD_V8B (0x0e208400) -#define OPCODE_ADD_V4H (0x0e608400) -#define OPCODE_ADD_V2S (0x0ea08400) -#define OPCODE_ADDP_V4S (0x4ea0bc00) -#define OPCODE_AND_V (0x0e201c00) -#define OPCODE_ASR (0x1ac02800) -#define OPCODE_BIC_V (0x0e601c00) -#define OPCODE_BLR (0xd63f0000) -#define OPCODE_BR (0xd61f0000) -#define OPCODE_CMEQ_V8B (0x2e208c00) -#define OPCODE_CMEQ_V4H (0x2e608c00) -#define OPCODE_CMEQ_V2S (0x2ea08c00) -#define OPCODE_CMGT_V8B (0x0e203400) -#define OPCODE_CMGT_V4H (0x0e603400) -#define OPCODE_CMGT_V2S (0x0ea03400) -#define OPCODE_DUP_V2S (0x0e040400) -#define OPCODE_EOR_V (0x2e201c00) -#define OPCODE_FABS_D (0x1e60c000) -#define OPCODE_FADD_D (0x1e602800) -#define OPCODE_FADD_V2S (0x0e20d400) -#define OPCODE_FCMEQ_V2S (0x0e20e400) -#define OPCODE_FCMGE_V2S (0x2e20e400) -#define OPCODE_FCMGT_V2S (0x2ea0e400) -#define OPCODE_FCMP_D (0x1e602000) -#define OPCODE_FCVT_D_S (0x1e22c000) -#define OPCODE_FCVT_S_D (0x1e624000) -#define OPCODE_FCVTMS_W_D (0x1e700000) -#define OPCODE_FCVTMS_X_D (0x9e700000) -#define OPCODE_FCVTNS_W_D (0x1e600000) -#define OPCODE_FCVTNS_X_D (0x9e600000) -#define OPCODE_FCVTPS_W_D (0x1e680000) -#define OPCODE_FCVTPS_X_D (0x9e680000) -#define OPCODE_FCVTZS_W_D (0x1e780000) -#define OPCODE_FCVTZS_X_D (0x9e780000) -#define OPCODE_FCVTZS_V2S (0x0ea1b800) -#define OPCODE_FDIV_D (0x1e601800) -#define OPCODE_FDIV_S (0x1e201800) -#define OPCODE_FMAX_V2S (0x0e20f400) -#define OPCODE_FMIN_V2S (0x0ea0f400) -#define OPCODE_FMOV_D_D (0x1e604000) -#define OPCODE_FMOV_D_Q (0x9e670000) -#define OPCODE_FMOV_Q_D (0x9e660000) -#define OPCODE_FMOV_S_W (0x1e270000) -#define OPCODE_FMOV_W_S (0x1e260000) -#define OPCODE_FMOV_S_ONE (0x1e2e1000) -#define OPCODE_FMUL_D (0x1e600800) -#define OPCODE_FMUL_V2S (0x2e20dc00) -#define OPCODE_FNEG_D (0x1e614000) -#define OPCODE_FRINTX_D (0x1e674000) -#define OPCODE_FSQRT_D (0x1e61c000) -#define OPCODE_FSQRT_S (0x1e21c000) -#define OPCODE_FSUB_D (0x1e603800) -#define OPCODE_FSUB_V2S (0x0ea0d400) -#define OPCODE_LDR_REG (0xb8606800) -#define OPCODE_LDRX_REG (0xf8606800) -#define OPCODE_LDRB_REG (0x38606800) -#define OPCODE_LDRH_REG (0x78606800) +#define OPCODE_ADD_V8B (0x0e208400) +#define OPCODE_ADD_V4H (0x0e608400) +#define OPCODE_ADD_V2S (0x0ea08400) +#define OPCODE_ADDP_V4S (0x4ea0bc00) +#define OPCODE_AND_V (0x0e201c00) +#define OPCODE_ASR (0x1ac02800) +#define OPCODE_BIC_V (0x0e601c00) +#define OPCODE_BLR (0xd63f0000) +#define OPCODE_BR (0xd61f0000) +#define OPCODE_CMEQ_V8B (0x2e208c00) +#define OPCODE_CMEQ_V4H (0x2e608c00) +#define OPCODE_CMEQ_V2S (0x2ea08c00) +#define OPCODE_CMGT_V8B (0x0e203400) +#define OPCODE_CMGT_V4H (0x0e603400) +#define OPCODE_CMGT_V2S (0x0ea03400) +#define OPCODE_DUP_V2S (0x0e040400) +#define OPCODE_EOR_V (0x2e201c00) +#define OPCODE_FABS_D (0x1e60c000) +#define OPCODE_FADD_D (0x1e602800) +#define OPCODE_FADD_V2S (0x0e20d400) +#define OPCODE_FCMEQ_V2S (0x0e20e400) +#define OPCODE_FCMGE_V2S (0x2e20e400) +#define OPCODE_FCMGT_V2S (0x2ea0e400) +#define OPCODE_FCMP_D (0x1e602000) +#define OPCODE_FCVT_D_S (0x1e22c000) +#define OPCODE_FCVT_S_D (0x1e624000) +#define OPCODE_FCVTMS_W_D (0x1e700000) +#define OPCODE_FCVTMS_X_D (0x9e700000) +#define OPCODE_FCVTNS_W_D (0x1e600000) +#define OPCODE_FCVTNS_X_D (0x9e600000) +#define OPCODE_FCVTPS_W_D (0x1e680000) +#define OPCODE_FCVTPS_X_D (0x9e680000) +#define OPCODE_FCVTZS_W_D (0x1e780000) +#define OPCODE_FCVTZS_X_D (0x9e780000) +#define OPCODE_FCVTZS_V2S (0x0ea1b800) +#define OPCODE_FDIV_D (0x1e601800) +#define OPCODE_FDIV_S (0x1e201800) +#define OPCODE_FMAX_V2S (0x0e20f400) +#define OPCODE_FMIN_V2S (0x0ea0f400) +#define OPCODE_FMOV_D_D (0x1e604000) +#define OPCODE_FMOV_D_Q (0x9e670000) +#define OPCODE_FMOV_Q_D (0x9e660000) +#define OPCODE_FMOV_S_W (0x1e270000) +#define OPCODE_FMOV_W_S (0x1e260000) +#define OPCODE_FMOV_S_ONE (0x1e2e1000) +#define OPCODE_FMUL_D (0x1e600800) +#define OPCODE_FMUL_V2S (0x2e20dc00) +#define OPCODE_FNEG_D (0x1e614000) +#define OPCODE_FRINTX_D (0x1e674000) +#define OPCODE_FSQRT_D (0x1e61c000) +#define OPCODE_FSQRT_S (0x1e21c000) +#define OPCODE_FSUB_D (0x1e603800) +#define OPCODE_FSUB_V2S (0x0ea0d400) +#define OPCODE_LDR_REG (0xb8606800) +#define OPCODE_LDRX_REG (0xf8606800) +#define OPCODE_LDRB_REG (0x38606800) +#define OPCODE_LDRH_REG (0x78606800) #define OPCODE_LDRX_REG_LSL3 (0xf8607800) -#define OPCODE_LDR_REG_F32 (0xbc606800) -#define OPCODE_LDR_REG_F64 (0xfc606800) +#define OPCODE_LDR_REG_F32 (0xbc606800) +#define OPCODE_LDR_REG_F64 (0xfc606800) #define OPCODE_LDR_REG_F64_S (0xfc607800) -#define OPCODE_LSL (0x1ac02000) -#define OPCODE_LSR (0x1ac02400) -#define OPCODE_MSR_FPCR (0xd51b4400) -#define OPCODE_MUL_V4H (0x0e609c00) -#define OPCODE_NOP (0xd503201f) -#define OPCODE_ORR_V (0x0ea01c00) -#define OPCODE_RET (0xd65f0000) -#define OPCODE_ROR (0x1ac02c00) +#define OPCODE_LSL (0x1ac02000) +#define OPCODE_LSR (0x1ac02400) +#define OPCODE_MSR_FPCR (0xd51b4400) +#define OPCODE_MUL_V4H (0x0e609c00) +#define OPCODE_NOP (0xd503201f) +#define OPCODE_ORR_V (0x0ea01c00) +#define OPCODE_RET (0xd65f0000) +#define OPCODE_ROR (0x1ac02c00) #define OPCODE_SADDLP_V2S_4H (0x0e602800) -#define OPCODE_SCVTF_D_Q (0x9e620000) -#define OPCODE_SCVTF_D_W (0x1e620000) -#define OPCODE_SCVTF_V2S (0x0e21d800) -#define OPCODE_SQADD_V8B (0x0e200c00) -#define OPCODE_SQADD_V4H (0x0e600c00) -#define OPCODE_SQSUB_V8B (0x0e202c00) -#define OPCODE_SQSUB_V4H (0x0e602c00) -#define OPCODE_SQXTN_V8B_8H (0x0e214800) -#define OPCODE_SQXTN_V4H_4S (0x0e614800) -#define OPCODE_SHL_VD (0x0f005400) -#define OPCODE_SHL_VQ (0x4f005400) -#define OPCODE_SHRN (0x0f008400) -#define OPCODE_SMULL_V4S_4H (0x0e60c000) -#define OPCODE_SSHR_VD (0x0f000400) -#define OPCODE_SSHR_VQ (0x4f000400) -#define OPCODE_STR_REG (0xb8206800) -#define OPCODE_STRB_REG (0x38206800) -#define OPCODE_STRH_REG (0x78206800) -#define OPCODE_STR_REG_F32 (0xbc206800) -#define OPCODE_STR_REG_F64 (0xfc206800) +#define OPCODE_SCVTF_D_Q (0x9e620000) +#define OPCODE_SCVTF_D_W (0x1e620000) +#define OPCODE_SCVTF_V2S (0x0e21d800) +#define OPCODE_SQADD_V8B (0x0e200c00) +#define OPCODE_SQADD_V4H (0x0e600c00) +#define OPCODE_SQSUB_V8B (0x0e202c00) +#define OPCODE_SQSUB_V4H (0x0e602c00) +#define OPCODE_SQXTN_V8B_8H (0x0e214800) +#define OPCODE_SQXTN_V4H_4S (0x0e614800) +#define OPCODE_SHL_VD (0x0f005400) +#define OPCODE_SHL_VQ (0x4f005400) +#define OPCODE_SHRN (0x0f008400) +#define OPCODE_SMULL_V4S_4H (0x0e60c000) +#define OPCODE_SSHR_VD (0x0f000400) +#define OPCODE_SSHR_VQ (0x4f000400) +#define OPCODE_STR_REG (0xb8206800) +#define OPCODE_STRB_REG (0x38206800) +#define OPCODE_STRH_REG (0x78206800) +#define OPCODE_STR_REG_F32 (0xbc206800) +#define OPCODE_STR_REG_F64 (0xfc206800) #define OPCODE_STR_REG_F64_S (0xfc207800) -#define OPCODE_SUB_V8B (0x2e208400) -#define OPCODE_SUB_V4H (0x2e608400) -#define OPCODE_SUB_V2S (0x2ea08400) -#define OPCODE_UQADD_V8B (0x2e200c00) -#define OPCODE_UQADD_V4H (0x2e600c00) -#define OPCODE_UQSUB_V8B (0x2e202c00) -#define OPCODE_UQSUB_V4H (0x2e602c00) -#define OPCODE_UQXTN_V8B_8H (0x2e214800) -#define OPCODE_UQXTN_V4H_4S (0x2e614800) -#define OPCODE_USHR_VD (0x2f000400) -#define OPCODE_USHR_VQ (0x6f000400) -#define OPCODE_ZIP1_V8B (0x0e003800) -#define OPCODE_ZIP1_V4H (0x0e403800) -#define OPCODE_ZIP1_V2S (0x0e803800) -#define OPCODE_ZIP2_V8B (0x0e007800) -#define OPCODE_ZIP2_V4H (0x0e407800) -#define OPCODE_ZIP2_V2S (0x0e807800) +#define OPCODE_SUB_V8B (0x2e208400) +#define OPCODE_SUB_V4H (0x2e608400) +#define OPCODE_SUB_V2S (0x2ea08400) +#define OPCODE_UQADD_V8B (0x2e200c00) +#define OPCODE_UQADD_V4H (0x2e600c00) +#define OPCODE_UQSUB_V8B (0x2e202c00) +#define OPCODE_UQSUB_V4H (0x2e602c00) +#define OPCODE_UQXTN_V8B_8H (0x2e214800) +#define OPCODE_UQXTN_V4H_4S (0x2e614800) +#define OPCODE_USHR_VD (0x2f000400) +#define OPCODE_USHR_VQ (0x6f000400) +#define OPCODE_ZIP1_V8B (0x0e003800) +#define OPCODE_ZIP1_V4H (0x0e403800) +#define OPCODE_ZIP1_V2S (0x0e803800) +#define OPCODE_ZIP2_V8B (0x0e007800) +#define OPCODE_ZIP2_V4H (0x0e407800) +#define OPCODE_ZIP2_V2S (0x0e807800) #define DATPROC_SHIFT(sh) (sh << 10) #define DATPROC_IMM_SHIFT(sh) (sh << 22) #define MOV_WIDE_HW(hw) (hw << 21) -#define IMM7_X(imm_data) (((imm_data >> 3) & 0x7f) << 15) +#define IMM7_X(imm_data) (((imm_data >> 3) & 0x7f) << 15) #define IMM12(imm_data) ((imm_data) << 10) #define IMM16(imm_data) ((imm_data) << 5) @@ -220,14 +219,14 @@ #define IMM_LOGICAL(imm) ((imm) << 10) -#define BIT_TBxZ(bit) ((((bit) & 0x1f) << 19) | (((bit) & 0x20) ? (1 << 31) : 0)) +#define BIT_TBxZ(bit) ((((bit)&0x1f) << 19) | (((bit)&0x20) ? (1 << 31) : 0)) #define OFFSET14(offset) (((offset >> 2) << 5) & 0x0007ffe0) #define OFFSET19(offset) (((offset >> 2) << 5) & 0x00ffffe0) -#define OFFSET20(offset) (((offset & 3) << 29) | ((((offset) & 0x1fffff) >> 2) << 5)) +#define OFFSET20(offset) (((offset & 3) << 29) | ((((offset)&0x1fffff) >> 2) << 5)) #define OFFSET26(offset) ((offset >> 2) & 0x03ffffff) -#define OFFSET12_B(offset) (offset << 10) +#define OFFSET12_B(offset) (offset << 10) #define OFFSET12_H(offset) ((offset >> 1) << 10) #define OFFSET12_W(offset) ((offset >> 2) << 10) #define OFFSET12_Q(offset) ((offset >> 3) << 10) @@ -241,1142 +240,905 @@ #define DUP_ELEMENT(element) ((element) << 19) /*Returns true if offset fits into 19 bits*/ -static int offset_is_19bit(int offset) -{ - if (offset >= (1 << (18+2))) - return 0; - if (offset < -(1 << (18+2))) - return 0; - return 1; +static int offset_is_19bit(int offset) { + if (offset >= (1 << (18 + 2))) + return 0; + if (offset < -(1 << (18 + 2))) + return 0; + return 1; } /*Returns true if offset fits into 26 bits*/ -static int offset_is_26bit(int offset) -{ - if (offset >= (1 << (25+2))) - return 0; - if (offset < -(1 << (25+2))) - return 0; - return 1; +static int offset_is_26bit(int offset) { + if (offset >= (1 << (25 + 2))) + return 0; + if (offset < -(1 << (25 + 2))) + return 0; + return 1; } -static inline int imm_is_imm16(uint32_t imm_data) -{ - if (!(imm_data & 0xffff0000) || !(imm_data & 0x0000ffff)) - return 1; - return 0; +static inline int imm_is_imm16(uint32_t imm_data) { + if (!(imm_data & 0xffff0000) || !(imm_data & 0x0000ffff)) + return 1; + return 0; } -static inline int imm_is_imm12(uint32_t imm_data) -{ - if (!(imm_data & 0xfffff000) || !(imm_data & 0xff000fff)) - return 1; - return 0; +static inline int imm_is_imm12(uint32_t imm_data) { + if (!(imm_data & 0xfffff000) || !(imm_data & 0xff000fff)) + return 1; + return 0; } static void codegen_allocate_new_block(codeblock_t *block); -static inline void codegen_addlong(codeblock_t *block, uint32_t val) -{ - if (block_pos >= (BLOCK_MAX-4)) - codegen_allocate_new_block(block); - *(uint32_t *)&block_write_data[block_pos] = val; - block_pos += 4; -} - -static void codegen_allocate_new_block(codeblock_t *block) -{ - /*Current block is full. Allocate a new block*/ - struct mem_block_t *new_block = codegen_allocator_allocate(block->head_mem_block, get_block_nr(block)); - uint8_t *new_ptr = codeblock_allocator_get_ptr(new_block); - uint32_t offset = (uintptr_t)new_ptr - (uintptr_t)&block_write_data[block_pos]; - - if (!offset_is_26bit(offset)) - fatal("codegen_allocate_new_block - offset out of range %x\n", offset); - /*Add a jump instruction to the new block*/ - *(uint32_t *)&block_write_data[block_pos] = OPCODE_B | OFFSET26(offset); - - /*Set write address to start of new block*/ - block_pos = 0; - block_write_data = new_ptr; -} - -void codegen_alloc(codeblock_t *block, int size) -{ - if (block_pos >= (BLOCK_MAX-size)) - codegen_allocate_new_block(block); -} - -void host_arm64_ADD_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) -{ - if (!imm_data) - host_arm64_MOV_REG(block, dst_reg, src_n_reg, 0); - else if ((int32_t)imm_data < 0 && imm_data != 0x80000000) - { - host_arm64_SUB_IMM(block, dst_reg, src_n_reg, -(int32_t)imm_data); - } - else if (!(imm_data & 0xff000000)) - { - if (imm_data & 0xfff) - { - codegen_addlong(block, OPCODE_ADD_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); - if (imm_data & 0xfff000) - codegen_addlong(block, OPCODE_ADD_IMM | Rd(dst_reg) | Rn(dst_reg) | IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1)); - } - else if (imm_data & 0xfff000) - codegen_addlong(block, OPCODE_ADD_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1)); - } - else - { - host_arm64_MOVZ_IMM(block, REG_W16, imm_data & 0xffff); - host_arm64_MOVK_IMM(block, REG_W16, imm_data & 0xffff0000); - codegen_addlong(block, OPCODE_ADD_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); - } -} -void host_arm64_ADDX_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint64_t imm_data) -{ - if (!(imm_data & ~0xffffffull)) - { - if (imm_data & 0xfff) - { - codegen_addlong(block, OPCODE_ADDX_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); - if (imm_data & 0xfff000) - codegen_addlong(block, OPCODE_ADDX_IMM | Rd(dst_reg) | Rn(dst_reg) | IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1)); - } - else if (imm_data & 0xfff000) - codegen_addlong(block, OPCODE_ADDX_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1)); - } - else - fatal("ADD_IMM_X %016llx\n", imm_data); -} -void host_arm64_ADD_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) -{ - codegen_addlong(block, OPCODE_ADD_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); -} -void host_arm64_ADD_REG_LSR(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) -{ - codegen_addlong(block, OPCODE_ADD_LSR | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); -} -void host_arm64_ADD_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) -{ - codegen_addlong(block, OPCODE_ADD_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); -} -void host_arm64_ADD_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) -{ - codegen_addlong(block, OPCODE_ADD_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); -} -void host_arm64_ADD_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) -{ - codegen_addlong(block, OPCODE_ADD_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); -} - -void host_arm64_ADDP_V4S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) -{ - codegen_addlong(block, OPCODE_ADDP_V4S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); -} - -void host_arm64_ADR(codeblock_t *block, int dst_reg, int offset) -{ - codegen_addlong(block, OPCODE_ADR | Rd(dst_reg) | OFFSET20(offset)); -} - -void host_arm64_AND_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) -{ - uint32_t imm_encoding = host_arm64_find_imm(imm_data); - - if (imm_encoding) - { - codegen_addlong(block, OPCODE_AND_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM_LOGICAL(imm_encoding)); - } - else - { - host_arm64_mov_imm(block, REG_W16, imm_data); - codegen_addlong(block, OPCODE_AND_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); - } -} -void host_arm64_AND_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) -{ - codegen_addlong(block, OPCODE_AND_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); -} -void host_arm64_AND_REG_ASR(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) -{ - codegen_addlong(block, OPCODE_AND_ASR | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); -} -void host_arm64_AND_REG_ROR(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) -{ - codegen_addlong(block, OPCODE_AND_ROR | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); -} -void host_arm64_AND_REG_V(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) -{ - codegen_addlong(block, OPCODE_AND_V | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); -} - -void host_arm64_ANDS_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) -{ - uint32_t imm_encoding = host_arm64_find_imm(imm_data); - - if (imm_encoding) - { - codegen_addlong(block, OPCODE_ANDS_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM_LOGICAL(imm_encoding)); - } - else - { - host_arm64_mov_imm(block, REG_W16, imm_data); - codegen_addlong(block, OPCODE_ANDS_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); - } -} - -void host_arm64_ASR(codeblock_t *block, int dst_reg, int src_n_reg, int shift_reg) -{ - codegen_addlong(block, OPCODE_ASR | Rd(dst_reg) | Rn(src_n_reg) | Rm(shift_reg)); -} - -void host_arm64_B(codeblock_t *block, void *dest) -{ - int offset; - - codegen_alloc(block, 4); - offset = (uintptr_t)dest - (uintptr_t)&block_write_data[block_pos]; - - if (!offset_is_26bit(offset)) - fatal("host_arm64_B - offset out of range %x\n", offset); - codegen_addlong(block, OPCODE_B | OFFSET26(offset)); -} - -void host_arm64_BFI(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width) -{ - codegen_addlong(block, OPCODE_BFI | Rd(dst_reg) | Rn(src_reg) | IMMN(0) | IMMR((32 - lsb) & 31) | IMMS((width-1) & 31)); -} - -void host_arm64_BLR(codeblock_t *block, int addr_reg) -{ - codegen_addlong(block, OPCODE_BLR | Rn(addr_reg)); -} - -uint32_t *host_arm64_BCC_(codeblock_t *block) -{ - codegen_alloc(block, 12); - codegen_addlong(block, OPCODE_BCOND | COND_CS | OFFSET19(8)); - codegen_addlong(block, OPCODE_B); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_arm64_BCS_(codeblock_t *block) -{ - codegen_alloc(block, 12); - codegen_addlong(block, OPCODE_BCOND | COND_CC | OFFSET19(8)); - codegen_addlong(block, OPCODE_B); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_arm64_BEQ_(codeblock_t *block) -{ - codegen_alloc(block, 12); - codegen_addlong(block, OPCODE_BCOND | COND_NE | OFFSET19(8)); - codegen_addlong(block, OPCODE_B); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_arm64_BGE_(codeblock_t *block) -{ - codegen_alloc(block, 12); - codegen_addlong(block, OPCODE_BCOND | COND_LT | OFFSET19(8)); - codegen_addlong(block, OPCODE_B); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_arm64_BGT_(codeblock_t *block) -{ - codegen_alloc(block, 12); - codegen_addlong(block, OPCODE_BCOND | COND_LE | OFFSET19(8)); - codegen_addlong(block, OPCODE_B); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_arm64_BHI_(codeblock_t *block) -{ - codegen_alloc(block, 12); - codegen_addlong(block, OPCODE_BCOND | COND_LS | OFFSET19(8)); - codegen_addlong(block, OPCODE_B); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_arm64_BLE_(codeblock_t *block) -{ - codegen_alloc(block, 12); - codegen_addlong(block, OPCODE_BCOND | COND_GT | OFFSET19(8)); - codegen_addlong(block, OPCODE_B); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_arm64_BLS_(codeblock_t *block) -{ - codegen_alloc(block, 12); - codegen_addlong(block, OPCODE_BCOND | COND_HI | OFFSET19(8)); - codegen_addlong(block, OPCODE_B); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_arm64_BLT_(codeblock_t *block) -{ - codegen_alloc(block, 12); - codegen_addlong(block, OPCODE_BCOND | COND_GE | OFFSET19(8)); - codegen_addlong(block, OPCODE_B); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_arm64_BMI_(codeblock_t *block) -{ - codegen_alloc(block, 12); - codegen_addlong(block, OPCODE_BCOND | COND_PL | OFFSET19(8)); - codegen_addlong(block, OPCODE_B); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_arm64_BNE_(codeblock_t *block) -{ - codegen_alloc(block, 12); - codegen_addlong(block, OPCODE_BCOND | COND_EQ | OFFSET19(8)); - codegen_addlong(block, OPCODE_B); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_arm64_BPL_(codeblock_t *block) -{ - codegen_alloc(block, 12); - codegen_addlong(block, OPCODE_BCOND | COND_MI | OFFSET19(8)); - codegen_addlong(block, OPCODE_B); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_arm64_BVC_(codeblock_t *block) -{ - codegen_alloc(block, 12); - codegen_addlong(block, OPCODE_BCOND | COND_VS | OFFSET19(8)); - codegen_addlong(block, OPCODE_B); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_arm64_BVS_(codeblock_t *block) -{ - codegen_alloc(block, 12); - codegen_addlong(block, OPCODE_BCOND | COND_VC | OFFSET19(8)); - codegen_addlong(block, OPCODE_B); - return (uint32_t *)&block_write_data[block_pos-4]; -} - -void host_arm64_branch_set_offset(uint32_t *opcode, void *dest) -{ - int offset = (uintptr_t)dest - (uintptr_t)opcode; - *opcode |= OFFSET26(offset); -} - -void host_arm64_BR(codeblock_t *block, int addr_reg) -{ - codegen_addlong(block, OPCODE_BR | Rn(addr_reg)); -} - -void host_arm64_BEQ(codeblock_t *block, void *dest) -{ - uint32_t *opcode = host_arm64_BEQ_(block); - host_arm64_branch_set_offset(opcode, dest); -} - -void host_arm64_BIC_REG_V(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) -{ - codegen_addlong(block, OPCODE_BIC_V | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); -} - -void host_arm64_CBNZ(codeblock_t *block, int reg, uintptr_t dest) -{ - int offset; - - codegen_alloc(block, 4); - offset = dest - (uintptr_t)&block_write_data[block_pos]; - if (offset_is_19bit(offset)) - { - codegen_addlong(block, OPCODE_CBNZ | OFFSET19(offset) | Rt(reg)); - } - else - { - codegen_alloc(block, 12); - codegen_addlong(block, OPCODE_CBZ | OFFSET19(8) | Rt(reg)); - offset = (uintptr_t)dest - (uintptr_t)&block_write_data[block_pos]; - codegen_addlong(block, OPCODE_B | OFFSET26(offset)); - } -} - -void host_arm64_CMEQ_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) -{ - codegen_addlong(block, OPCODE_CMEQ_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); -} -void host_arm64_CMEQ_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) -{ - codegen_addlong(block, OPCODE_CMEQ_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); -} -void host_arm64_CMEQ_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) -{ - codegen_addlong(block, OPCODE_CMEQ_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); -} -void host_arm64_CMGT_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) -{ - codegen_addlong(block, OPCODE_CMGT_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); -} -void host_arm64_CMGT_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) -{ - codegen_addlong(block, OPCODE_CMGT_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); -} -void host_arm64_CMGT_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) -{ - codegen_addlong(block, OPCODE_CMGT_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); -} - -void host_arm64_CMN_IMM(codeblock_t *block, int src_n_reg, uint32_t imm_data) -{ - if ((int32_t)imm_data < 0 && imm_data != (1ull << 31)) - { - host_arm64_CMP_IMM(block, src_n_reg, -(int32_t)imm_data); - } - else if (!(imm_data & 0xfffff000)) - { - codegen_addlong(block, OPCODE_CMN_IMM | Rd(REG_WZR) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); - } - else - fatal("CMN_IMM %08x\n", imm_data); -} -void host_arm64_CMNX_IMM(codeblock_t *block, int src_n_reg, uint64_t imm_data) -{ - if ((int64_t)imm_data < 0 && imm_data != (1ull << 63)) - { - host_arm64_CMPX_IMM(block, src_n_reg, -(int64_t)imm_data); - } - else if (!(imm_data & 0xfffffffffffff000ull)) - { - codegen_addlong(block, OPCODE_CMNX_IMM | Rd(REG_XZR) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); - } - else - fatal("CMNX_IMM %08x\n", imm_data); -} - -void host_arm64_CMP_IMM(codeblock_t *block, int src_n_reg, uint32_t imm_data) -{ - if ((int32_t)imm_data < 0 && imm_data != (1ull << 31)) - { - host_arm64_CMN_IMM(block, src_n_reg, -(int32_t)imm_data); - } - else if (!(imm_data & 0xfffff000)) - { - codegen_addlong(block, OPCODE_CMP_IMM | Rd(REG_WZR) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); - } - else - fatal("CMP_IMM %08x\n", imm_data); -} -void host_arm64_CMPX_IMM(codeblock_t *block, int src_n_reg, uint64_t imm_data) -{ - if ((int64_t)imm_data < 0 && imm_data != (1ull << 63)) - { - host_arm64_CMNX_IMM(block, src_n_reg, -(int64_t)imm_data); - } - else if (!(imm_data & 0xfffffffffffff000ull)) - { - codegen_addlong(block, OPCODE_CMPX_IMM | Rd(REG_XZR) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); - } - else - fatal("CMPX_IMM %08x\n", imm_data); -} - -void host_arm64_CMP_REG_LSL(codeblock_t *block, int src_n_reg, int src_m_reg, int shift) -{ - codegen_addlong(block, OPCODE_CMP_LSL | Rd(0x1f) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); -} - -void host_arm64_CSEL_CC(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) -{ - codegen_addlong(block, OPCODE_CSEL | CSEL_COND(COND_CC) | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); -} -void host_arm64_CSEL_EQ(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) -{ - codegen_addlong(block, OPCODE_CSEL | CSEL_COND(COND_EQ) | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); -} -void host_arm64_CSEL_VS(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) -{ - codegen_addlong(block, OPCODE_CSEL | CSEL_COND(COND_VS) | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); -} - -void host_arm64_DUP_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int element) -{ - codegen_addlong(block, OPCODE_DUP_V2S | Rd(dst_reg) | Rn(src_n_reg) | DUP_ELEMENT(element)); -} - -void host_arm64_EOR_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) -{ - uint32_t imm_encoding = host_arm64_find_imm(imm_data); - - if (imm_encoding) - { - codegen_addlong(block, OPCODE_EOR_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM_LOGICAL(imm_encoding)); - } - else - { - host_arm64_mov_imm(block, REG_W16, imm_data); - codegen_addlong(block, OPCODE_EOR_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); - } +static inline void codegen_addlong(codeblock_t *block, uint32_t val) { + if (block_pos >= (BLOCK_MAX - 4)) + codegen_allocate_new_block(block); + *(uint32_t *)&block_write_data[block_pos] = val; + block_pos += 4; +} + +static void codegen_allocate_new_block(codeblock_t *block) { + /*Current block is full. Allocate a new block*/ + struct mem_block_t *new_block = codegen_allocator_allocate(block->head_mem_block, get_block_nr(block)); + uint8_t *new_ptr = codeblock_allocator_get_ptr(new_block); + uint32_t offset = (uintptr_t)new_ptr - (uintptr_t)&block_write_data[block_pos]; + + if (!offset_is_26bit(offset)) + fatal("codegen_allocate_new_block - offset out of range %x\n", offset); + /*Add a jump instruction to the new block*/ + *(uint32_t *)&block_write_data[block_pos] = OPCODE_B | OFFSET26(offset); + + /*Set write address to start of new block*/ + block_pos = 0; + block_write_data = new_ptr; +} + +void codegen_alloc(codeblock_t *block, int size) { + if (block_pos >= (BLOCK_MAX - size)) + codegen_allocate_new_block(block); +} + +void host_arm64_ADD_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) { + if (!imm_data) + host_arm64_MOV_REG(block, dst_reg, src_n_reg, 0); + else if ((int32_t)imm_data < 0 && imm_data != 0x80000000) { + host_arm64_SUB_IMM(block, dst_reg, src_n_reg, -(int32_t)imm_data); + } else if (!(imm_data & 0xff000000)) { + if (imm_data & 0xfff) { + codegen_addlong(block, OPCODE_ADD_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | + DATPROC_IMM_SHIFT(0)); + if (imm_data & 0xfff000) + codegen_addlong(block, OPCODE_ADD_IMM | Rd(dst_reg) | Rn(dst_reg) | + IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1)); + } else if (imm_data & 0xfff000) + codegen_addlong(block, OPCODE_ADD_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12((imm_data >> 12) & 0xfff) | + DATPROC_IMM_SHIFT(1)); + } else { + host_arm64_MOVZ_IMM(block, REG_W16, imm_data & 0xffff); + host_arm64_MOVK_IMM(block, REG_W16, imm_data & 0xffff0000); + codegen_addlong(block, OPCODE_ADD_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); + } +} +void host_arm64_ADDX_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint64_t imm_data) { + if (!(imm_data & ~0xffffffull)) { + if (imm_data & 0xfff) { + codegen_addlong(block, OPCODE_ADDX_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | + DATPROC_IMM_SHIFT(0)); + if (imm_data & 0xfff000) + codegen_addlong(block, OPCODE_ADDX_IMM | Rd(dst_reg) | Rn(dst_reg) | + IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1)); + } else if (imm_data & 0xfff000) + codegen_addlong(block, OPCODE_ADDX_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12((imm_data >> 12) & 0xfff) | + DATPROC_IMM_SHIFT(1)); + } else + fatal("ADD_IMM_X %016llx\n", imm_data); } -void host_arm64_EOR_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) -{ - codegen_addlong(block, OPCODE_EOR_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +void host_arm64_ADD_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) { + codegen_addlong(block, OPCODE_ADD_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } -void host_arm64_EOR_REG_V(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) -{ - codegen_addlong(block, OPCODE_EOR_V | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +void host_arm64_ADD_REG_LSR(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) { + codegen_addlong(block, OPCODE_ADD_LSR | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +} +void host_arm64_ADD_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { + codegen_addlong(block, OPCODE_ADD_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} +void host_arm64_ADD_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { + codegen_addlong(block, OPCODE_ADD_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} +void host_arm64_ADD_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { + codegen_addlong(block, OPCODE_ADD_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_FABS_D(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_addlong(block, OPCODE_FABS_D | Rd(dst_reg) | Rn(src_reg)); +void host_arm64_ADDP_V4S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { + codegen_addlong(block, OPCODE_ADDP_V4S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_FADD_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) -{ - codegen_addlong(block, OPCODE_FADD_D | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +void host_arm64_ADR(codeblock_t *block, int dst_reg, int offset) { + codegen_addlong(block, OPCODE_ADR | Rd(dst_reg) | OFFSET20(offset)); +} + +void host_arm64_AND_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) { + uint32_t imm_encoding = host_arm64_find_imm(imm_data); + + if (imm_encoding) { + codegen_addlong(block, OPCODE_AND_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM_LOGICAL(imm_encoding)); + } else { + host_arm64_mov_imm(block, REG_W16, imm_data); + codegen_addlong(block, OPCODE_AND_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); + } +} +void host_arm64_AND_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) { + codegen_addlong(block, OPCODE_AND_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +} +void host_arm64_AND_REG_ASR(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) { + codegen_addlong(block, OPCODE_AND_ASR | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +} +void host_arm64_AND_REG_ROR(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) { + codegen_addlong(block, OPCODE_AND_ROR | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +} +void host_arm64_AND_REG_V(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { + codegen_addlong(block, OPCODE_AND_V | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} + +void host_arm64_ANDS_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) { + uint32_t imm_encoding = host_arm64_find_imm(imm_data); + + if (imm_encoding) { + codegen_addlong(block, OPCODE_ANDS_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM_LOGICAL(imm_encoding)); + } else { + host_arm64_mov_imm(block, REG_W16, imm_data); + codegen_addlong(block, OPCODE_ANDS_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); + } +} + +void host_arm64_ASR(codeblock_t *block, int dst_reg, int src_n_reg, int shift_reg) { + codegen_addlong(block, OPCODE_ASR | Rd(dst_reg) | Rn(src_n_reg) | Rm(shift_reg)); +} + +void host_arm64_B(codeblock_t *block, void *dest) { + int offset; + + codegen_alloc(block, 4); + offset = (uintptr_t)dest - (uintptr_t)&block_write_data[block_pos]; + + if (!offset_is_26bit(offset)) + fatal("host_arm64_B - offset out of range %x\n", offset); + codegen_addlong(block, OPCODE_B | OFFSET26(offset)); +} + +void host_arm64_BFI(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width) { + codegen_addlong(block, OPCODE_BFI | Rd(dst_reg) | Rn(src_reg) | IMMN(0) | IMMR((32 - lsb) & 31) | IMMS((width - 1) & 31)); +} + +void host_arm64_BLR(codeblock_t *block, int addr_reg) { codegen_addlong(block, OPCODE_BLR | Rn(addr_reg)); } + +uint32_t *host_arm64_BCC_(codeblock_t *block) { + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_BCOND | COND_CS | OFFSET19(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *)&block_write_data[block_pos - 4]; +} +uint32_t *host_arm64_BCS_(codeblock_t *block) { + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_BCOND | COND_CC | OFFSET19(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *)&block_write_data[block_pos - 4]; +} +uint32_t *host_arm64_BEQ_(codeblock_t *block) { + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_BCOND | COND_NE | OFFSET19(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *)&block_write_data[block_pos - 4]; +} +uint32_t *host_arm64_BGE_(codeblock_t *block) { + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_BCOND | COND_LT | OFFSET19(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *)&block_write_data[block_pos - 4]; +} +uint32_t *host_arm64_BGT_(codeblock_t *block) { + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_BCOND | COND_LE | OFFSET19(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *)&block_write_data[block_pos - 4]; +} +uint32_t *host_arm64_BHI_(codeblock_t *block) { + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_BCOND | COND_LS | OFFSET19(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *)&block_write_data[block_pos - 4]; +} +uint32_t *host_arm64_BLE_(codeblock_t *block) { + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_BCOND | COND_GT | OFFSET19(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *)&block_write_data[block_pos - 4]; +} +uint32_t *host_arm64_BLS_(codeblock_t *block) { + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_BCOND | COND_HI | OFFSET19(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *)&block_write_data[block_pos - 4]; +} +uint32_t *host_arm64_BLT_(codeblock_t *block) { + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_BCOND | COND_GE | OFFSET19(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *)&block_write_data[block_pos - 4]; } -void host_arm64_FADD_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) -{ - codegen_addlong(block, OPCODE_FADD_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +uint32_t *host_arm64_BMI_(codeblock_t *block) { + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_BCOND | COND_PL | OFFSET19(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *)&block_write_data[block_pos - 4]; } -void host_arm64_FCMEQ_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) -{ - codegen_addlong(block, OPCODE_FCMEQ_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +uint32_t *host_arm64_BNE_(codeblock_t *block) { + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_BCOND | COND_EQ | OFFSET19(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *)&block_write_data[block_pos - 4]; } -void host_arm64_FCMGE_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) -{ - codegen_addlong(block, OPCODE_FCMGE_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +uint32_t *host_arm64_BPL_(codeblock_t *block) { + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_BCOND | COND_MI | OFFSET19(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *)&block_write_data[block_pos - 4]; +} +uint32_t *host_arm64_BVC_(codeblock_t *block) { + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_BCOND | COND_VS | OFFSET19(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *)&block_write_data[block_pos - 4]; } -void host_arm64_FCMGT_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) -{ - codegen_addlong(block, OPCODE_FCMGT_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +uint32_t *host_arm64_BVS_(codeblock_t *block) { + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_BCOND | COND_VC | OFFSET19(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *)&block_write_data[block_pos - 4]; +} + +void host_arm64_branch_set_offset(uint32_t *opcode, void *dest) { + int offset = (uintptr_t)dest - (uintptr_t)opcode; + *opcode |= OFFSET26(offset); } -void host_arm64_FCMP_D(codeblock_t *block, int src_n_reg, int src_m_reg) -{ - codegen_addlong(block, OPCODE_FCMP_D | Rn(src_n_reg) | Rm(src_m_reg)); +void host_arm64_BR(codeblock_t *block, int addr_reg) { codegen_addlong(block, OPCODE_BR | Rn(addr_reg)); } + +void host_arm64_BEQ(codeblock_t *block, void *dest) { + uint32_t *opcode = host_arm64_BEQ_(block); + host_arm64_branch_set_offset(opcode, dest); +} + +void host_arm64_BIC_REG_V(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { + codegen_addlong(block, OPCODE_BIC_V | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} + +void host_arm64_CBNZ(codeblock_t *block, int reg, uintptr_t dest) { + int offset; + + codegen_alloc(block, 4); + offset = dest - (uintptr_t)&block_write_data[block_pos]; + if (offset_is_19bit(offset)) { + codegen_addlong(block, OPCODE_CBNZ | OFFSET19(offset) | Rt(reg)); + } else { + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_CBZ | OFFSET19(8) | Rt(reg)); + offset = (uintptr_t)dest - (uintptr_t)&block_write_data[block_pos]; + codegen_addlong(block, OPCODE_B | OFFSET26(offset)); + } } -void host_arm64_FCVT_D_S(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_addlong(block, OPCODE_FCVT_D_S | Rd(dst_reg) | Rn(src_reg)); +void host_arm64_CMEQ_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { + codegen_addlong(block, OPCODE_CMEQ_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} +void host_arm64_CMEQ_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { + codegen_addlong(block, OPCODE_CMEQ_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} +void host_arm64_CMEQ_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { + codegen_addlong(block, OPCODE_CMEQ_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} +void host_arm64_CMGT_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { + codegen_addlong(block, OPCODE_CMGT_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_FCVT_S_D(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_addlong(block, OPCODE_FCVT_S_D | Rd(dst_reg) | Rn(src_reg)); +void host_arm64_CMGT_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { + codegen_addlong(block, OPCODE_CMGT_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} +void host_arm64_CMGT_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { + codegen_addlong(block, OPCODE_CMGT_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_FCVTMS_W_D(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_addlong(block, OPCODE_FCVTMS_W_D | Rd(dst_reg) | Rn(src_reg)); +void host_arm64_CMN_IMM(codeblock_t *block, int src_n_reg, uint32_t imm_data) { + if ((int32_t)imm_data < 0 && imm_data != (1ull << 31)) { + host_arm64_CMP_IMM(block, src_n_reg, -(int32_t)imm_data); + } else if (!(imm_data & 0xfffff000)) { + codegen_addlong(block, + OPCODE_CMN_IMM | Rd(REG_WZR) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); + } else + fatal("CMN_IMM %08x\n", imm_data); } -void host_arm64_FCVTMS_X_D(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_addlong(block, OPCODE_FCVTMS_X_D | Rd(dst_reg) | Rn(src_reg)); +void host_arm64_CMNX_IMM(codeblock_t *block, int src_n_reg, uint64_t imm_data) { + if ((int64_t)imm_data < 0 && imm_data != (1ull << 63)) { + host_arm64_CMPX_IMM(block, src_n_reg, -(int64_t)imm_data); + } else if (!(imm_data & 0xfffffffffffff000ull)) { + codegen_addlong(block, + OPCODE_CMNX_IMM | Rd(REG_XZR) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); + } else + fatal("CMNX_IMM %08x\n", imm_data); } -void host_arm64_FCVTNS_W_D(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_addlong(block, OPCODE_FCVTNS_W_D | Rd(dst_reg) | Rn(src_reg)); + +void host_arm64_CMP_IMM(codeblock_t *block, int src_n_reg, uint32_t imm_data) { + if ((int32_t)imm_data < 0 && imm_data != (1ull << 31)) { + host_arm64_CMN_IMM(block, src_n_reg, -(int32_t)imm_data); + } else if (!(imm_data & 0xfffff000)) { + codegen_addlong(block, + OPCODE_CMP_IMM | Rd(REG_WZR) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); + } else + fatal("CMP_IMM %08x\n", imm_data); } -void host_arm64_FCVTNS_X_D(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_addlong(block, OPCODE_FCVTNS_X_D | Rd(dst_reg) | Rn(src_reg)); +void host_arm64_CMPX_IMM(codeblock_t *block, int src_n_reg, uint64_t imm_data) { + if ((int64_t)imm_data < 0 && imm_data != (1ull << 63)) { + host_arm64_CMNX_IMM(block, src_n_reg, -(int64_t)imm_data); + } else if (!(imm_data & 0xfffffffffffff000ull)) { + codegen_addlong(block, + OPCODE_CMPX_IMM | Rd(REG_XZR) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); + } else + fatal("CMPX_IMM %08x\n", imm_data); } -void host_arm64_FCVTPS_W_D(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_addlong(block, OPCODE_FCVTPS_W_D | Rd(dst_reg) | Rn(src_reg)); + +void host_arm64_CMP_REG_LSL(codeblock_t *block, int src_n_reg, int src_m_reg, int shift) { + codegen_addlong(block, OPCODE_CMP_LSL | Rd(0x1f) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } -void host_arm64_FCVTPS_X_D(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_addlong(block, OPCODE_FCVTPS_X_D | Rd(dst_reg) | Rn(src_reg)); + +void host_arm64_CSEL_CC(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { + codegen_addlong(block, OPCODE_CSEL | CSEL_COND(COND_CC) | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_FCVTZS_W_D(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_addlong(block, OPCODE_FCVTZS_W_D | Rd(dst_reg) | Rn(src_reg)); +void host_arm64_CSEL_EQ(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { + codegen_addlong(block, OPCODE_CSEL | CSEL_COND(COND_EQ) | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_FCVTZS_X_D(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_addlong(block, OPCODE_FCVTZS_X_D | Rd(dst_reg) | Rn(src_reg)); +void host_arm64_CSEL_VS(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { + codegen_addlong(block, OPCODE_CSEL | CSEL_COND(COND_VS) | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_FCVTZS_V2S(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_addlong(block, OPCODE_FCVTZS_V2S | Rd(dst_reg) | Rn(src_reg)); + +void host_arm64_DUP_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int element) { + codegen_addlong(block, OPCODE_DUP_V2S | Rd(dst_reg) | Rn(src_n_reg) | DUP_ELEMENT(element)); } -void host_arm64_FDIV_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) -{ - codegen_addlong(block, OPCODE_FDIV_D | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +void host_arm64_EOR_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) { + uint32_t imm_encoding = host_arm64_find_imm(imm_data); + + if (imm_encoding) { + codegen_addlong(block, OPCODE_EOR_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM_LOGICAL(imm_encoding)); + } else { + host_arm64_mov_imm(block, REG_W16, imm_data); + codegen_addlong(block, OPCODE_EOR_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); + } +} +void host_arm64_EOR_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) { + codegen_addlong(block, OPCODE_EOR_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +} +void host_arm64_EOR_REG_V(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { + codegen_addlong(block, OPCODE_EOR_V | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_FDIV_S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) -{ - codegen_addlong(block, OPCODE_FDIV_S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + +void host_arm64_FABS_D(codeblock_t *block, int dst_reg, int src_reg) { + codegen_addlong(block, OPCODE_FABS_D | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_FMAX_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) -{ - codegen_addlong(block, OPCODE_FMAX_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +void host_arm64_FADD_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { + codegen_addlong(block, OPCODE_FADD_D | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} +void host_arm64_FADD_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { + codegen_addlong(block, OPCODE_FADD_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} +void host_arm64_FCMEQ_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { + codegen_addlong(block, OPCODE_FCMEQ_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_FMIN_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) -{ - codegen_addlong(block, OPCODE_FMIN_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +void host_arm64_FCMGE_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { + codegen_addlong(block, OPCODE_FCMGE_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} +void host_arm64_FCMGT_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { + codegen_addlong(block, OPCODE_FCMGT_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} + +void host_arm64_FCMP_D(codeblock_t *block, int src_n_reg, int src_m_reg) { + codegen_addlong(block, OPCODE_FCMP_D | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_FMUL_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) -{ - codegen_addlong(block, OPCODE_FMUL_D | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +void host_arm64_FCVT_D_S(codeblock_t *block, int dst_reg, int src_reg) { + codegen_addlong(block, OPCODE_FCVT_D_S | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_FMUL_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) -{ - codegen_addlong(block, OPCODE_FMUL_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +void host_arm64_FCVT_S_D(codeblock_t *block, int dst_reg, int src_reg) { + codegen_addlong(block, OPCODE_FCVT_S_D | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_FSUB_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) -{ - codegen_addlong(block, OPCODE_FSUB_D | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +void host_arm64_FCVTMS_W_D(codeblock_t *block, int dst_reg, int src_reg) { + codegen_addlong(block, OPCODE_FCVTMS_W_D | Rd(dst_reg) | Rn(src_reg)); +} +void host_arm64_FCVTMS_X_D(codeblock_t *block, int dst_reg, int src_reg) { + codegen_addlong(block, OPCODE_FCVTMS_X_D | Rd(dst_reg) | Rn(src_reg)); +} +void host_arm64_FCVTNS_W_D(codeblock_t *block, int dst_reg, int src_reg) { + codegen_addlong(block, OPCODE_FCVTNS_W_D | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_FSUB_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) -{ - codegen_addlong(block, OPCODE_FSUB_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +void host_arm64_FCVTNS_X_D(codeblock_t *block, int dst_reg, int src_reg) { + codegen_addlong(block, OPCODE_FCVTNS_X_D | Rd(dst_reg) | Rn(src_reg)); +} +void host_arm64_FCVTPS_W_D(codeblock_t *block, int dst_reg, int src_reg) { + codegen_addlong(block, OPCODE_FCVTPS_W_D | Rd(dst_reg) | Rn(src_reg)); +} +void host_arm64_FCVTPS_X_D(codeblock_t *block, int dst_reg, int src_reg) { + codegen_addlong(block, OPCODE_FCVTPS_X_D | Rd(dst_reg) | Rn(src_reg)); +} +void host_arm64_FCVTZS_W_D(codeblock_t *block, int dst_reg, int src_reg) { + codegen_addlong(block, OPCODE_FCVTZS_W_D | Rd(dst_reg) | Rn(src_reg)); +} +void host_arm64_FCVTZS_X_D(codeblock_t *block, int dst_reg, int src_reg) { + codegen_addlong(block, OPCODE_FCVTZS_X_D | Rd(dst_reg) | Rn(src_reg)); +} +void host_arm64_FCVTZS_V2S(codeblock_t *block, int dst_reg, int src_reg) { + codegen_addlong(block, OPCODE_FCVTZS_V2S | Rd(dst_reg) | Rn(src_reg)); +} + +void host_arm64_FDIV_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { + codegen_addlong(block, OPCODE_FDIV_D | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} +void host_arm64_FDIV_S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { + codegen_addlong(block, OPCODE_FDIV_S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} + +void host_arm64_FMAX_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { + codegen_addlong(block, OPCODE_FMAX_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} +void host_arm64_FMIN_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { + codegen_addlong(block, OPCODE_FMIN_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_FMOV_D_D(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_addlong(block, OPCODE_FMOV_D_D | Rd(dst_reg) | Rn(src_reg)); +void host_arm64_FMUL_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { + codegen_addlong(block, OPCODE_FMUL_D | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_FMOV_D_Q(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_addlong(block, OPCODE_FMOV_D_Q | Rd(dst_reg) | Rn(src_reg)); +void host_arm64_FMUL_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { + codegen_addlong(block, OPCODE_FMUL_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_FMOV_Q_D(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_addlong(block, OPCODE_FMOV_Q_D | Rd(dst_reg) | Rn(src_reg)); + +void host_arm64_FSUB_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { + codegen_addlong(block, OPCODE_FSUB_D | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} +void host_arm64_FSUB_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { + codegen_addlong(block, OPCODE_FSUB_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} + +void host_arm64_FMOV_D_D(codeblock_t *block, int dst_reg, int src_reg) { + codegen_addlong(block, OPCODE_FMOV_D_D | Rd(dst_reg) | Rn(src_reg)); +} +void host_arm64_FMOV_D_Q(codeblock_t *block, int dst_reg, int src_reg) { + codegen_addlong(block, OPCODE_FMOV_D_Q | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_FMOV_S_W(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_addlong(block, OPCODE_FMOV_S_W | Rd(dst_reg) | Rn(src_reg)); +void host_arm64_FMOV_Q_D(codeblock_t *block, int dst_reg, int src_reg) { + codegen_addlong(block, OPCODE_FMOV_Q_D | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_FMOV_W_S(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_addlong(block, OPCODE_FMOV_W_S | Rd(dst_reg) | Rn(src_reg)); +void host_arm64_FMOV_S_W(codeblock_t *block, int dst_reg, int src_reg) { + codegen_addlong(block, OPCODE_FMOV_S_W | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_FMOV_S_ONE(codeblock_t *block, int dst_reg) -{ - codegen_addlong(block, OPCODE_FMOV_S_ONE | Rd(dst_reg)); +void host_arm64_FMOV_W_S(codeblock_t *block, int dst_reg, int src_reg) { + codegen_addlong(block, OPCODE_FMOV_W_S | Rd(dst_reg) | Rn(src_reg)); } +void host_arm64_FMOV_S_ONE(codeblock_t *block, int dst_reg) { codegen_addlong(block, OPCODE_FMOV_S_ONE | Rd(dst_reg)); } -void host_arm64_FNEG_D(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_addlong(block, OPCODE_FNEG_D | Rd(dst_reg) | Rn(src_reg)); +void host_arm64_FNEG_D(codeblock_t *block, int dst_reg, int src_reg) { + codegen_addlong(block, OPCODE_FNEG_D | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_FRINTX_D(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_addlong(block, OPCODE_FRINTX_D | Rd(dst_reg) | Rn(src_reg)); +void host_arm64_FRINTX_D(codeblock_t *block, int dst_reg, int src_reg) { + codegen_addlong(block, OPCODE_FRINTX_D | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_FSQRT_D(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_addlong(block, OPCODE_FSQRT_D | Rd(dst_reg) | Rn(src_reg)); +void host_arm64_FSQRT_D(codeblock_t *block, int dst_reg, int src_reg) { + codegen_addlong(block, OPCODE_FSQRT_D | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_FSQRT_S(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_addlong(block, OPCODE_FSQRT_S | Rd(dst_reg) | Rn(src_reg)); +void host_arm64_FSQRT_S(codeblock_t *block, int dst_reg, int src_reg) { + codegen_addlong(block, OPCODE_FSQRT_S | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_LDP_POSTIDX_X(codeblock_t *block, int src_reg1, int src_reg2, int base_reg, int offset) -{ - if (!in_range7_x(offset)) - fatal("host_arm64_LDP_POSTIDX out of range7 %i\n", offset); - codegen_addlong(block, OPCODE_LDP_POSTIDX_X | IMM7_X(offset) | Rn(base_reg) | Rt(src_reg1) | Rt2(src_reg2)); +void host_arm64_LDP_POSTIDX_X(codeblock_t *block, int src_reg1, int src_reg2, int base_reg, int offset) { + if (!in_range7_x(offset)) + fatal("host_arm64_LDP_POSTIDX out of range7 %i\n", offset); + codegen_addlong(block, OPCODE_LDP_POSTIDX_X | IMM7_X(offset) | Rn(base_reg) | Rt(src_reg1) | Rt2(src_reg2)); } -void host_arm64_LDR_IMM_W(codeblock_t *block, int dest_reg, int base_reg, int offset) -{ - if (!in_range12_w(offset)) - fatal("host_arm64_LDR_IMM_W out of range12 %i\n", offset); - codegen_addlong(block, OPCODE_LDR_IMM_W | OFFSET12_W(offset) | Rn(base_reg) | Rt(dest_reg)); +void host_arm64_LDR_IMM_W(codeblock_t *block, int dest_reg, int base_reg, int offset) { + if (!in_range12_w(offset)) + fatal("host_arm64_LDR_IMM_W out of range12 %i\n", offset); + codegen_addlong(block, OPCODE_LDR_IMM_W | OFFSET12_W(offset) | Rn(base_reg) | Rt(dest_reg)); } -void host_arm64_LDR_IMM_X(codeblock_t *block, int dest_reg, int base_reg, int offset) -{ - if (!in_range12_q(offset)) - fatal("host_arm64_LDR_IMM_X out of range12 %i\n", offset); - codegen_addlong(block, OPCODE_LDR_IMM_X | OFFSET12_Q(offset) | Rn(base_reg) | Rt(dest_reg)); +void host_arm64_LDR_IMM_X(codeblock_t *block, int dest_reg, int base_reg, int offset) { + if (!in_range12_q(offset)) + fatal("host_arm64_LDR_IMM_X out of range12 %i\n", offset); + codegen_addlong(block, OPCODE_LDR_IMM_X | OFFSET12_Q(offset) | Rn(base_reg) | Rt(dest_reg)); } -void host_arm64_LDR_REG(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) -{ - codegen_addlong(block, OPCODE_LDR_REG | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); +void host_arm64_LDR_REG(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) { + codegen_addlong(block, OPCODE_LDR_REG | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); } -void host_arm64_LDR_REG_X(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) -{ - codegen_addlong(block, OPCODE_LDRX_REG | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); +void host_arm64_LDR_REG_X(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) { + codegen_addlong(block, OPCODE_LDRX_REG | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); } -void host_arm64_LDR_REG_F32(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) -{ - codegen_addlong(block, OPCODE_LDR_REG_F32 | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); +void host_arm64_LDR_REG_F32(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) { + codegen_addlong(block, OPCODE_LDR_REG_F32 | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); } -void host_arm64_LDR_IMM_F64(codeblock_t *block, int dest_reg, int base_reg, int offset) -{ - codegen_addlong(block, OPCODE_LDR_IMM_F64 | OFFSET12_Q(offset) | Rn(base_reg) | Rt(dest_reg)); +void host_arm64_LDR_IMM_F64(codeblock_t *block, int dest_reg, int base_reg, int offset) { + codegen_addlong(block, OPCODE_LDR_IMM_F64 | OFFSET12_Q(offset) | Rn(base_reg) | Rt(dest_reg)); } -void host_arm64_LDR_REG_F64(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) -{ - codegen_addlong(block, OPCODE_LDR_REG_F64 | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); +void host_arm64_LDR_REG_F64(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) { + codegen_addlong(block, OPCODE_LDR_REG_F64 | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); } -void host_arm64_LDR_REG_F64_S(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) -{ - codegen_addlong(block, OPCODE_LDR_REG_F64_S | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); +void host_arm64_LDR_REG_F64_S(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) { + codegen_addlong(block, OPCODE_LDR_REG_F64_S | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); } -void host_arm64_LDRB_IMM_W(codeblock_t *block, int dest_reg, int base_reg, int offset) -{ - if (!in_range12_b(offset)) - fatal("host_arm64_LDRB_IMM_W out of range12 %i\n", offset); - codegen_addlong(block, OPCODE_LDRB_IMM_W | OFFSET12_B(offset) | Rn(base_reg) | Rt(dest_reg)); +void host_arm64_LDRB_IMM_W(codeblock_t *block, int dest_reg, int base_reg, int offset) { + if (!in_range12_b(offset)) + fatal("host_arm64_LDRB_IMM_W out of range12 %i\n", offset); + codegen_addlong(block, OPCODE_LDRB_IMM_W | OFFSET12_B(offset) | Rn(base_reg) | Rt(dest_reg)); } -void host_arm64_LDRB_REG(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) -{ - codegen_addlong(block, OPCODE_LDRB_REG | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); +void host_arm64_LDRB_REG(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) { + codegen_addlong(block, OPCODE_LDRB_REG | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); } -void host_arm64_LDRH_IMM(codeblock_t *block, int dest_reg, int base_reg, int offset) -{ - if (!in_range12_h(offset)) - fatal("host_arm64_LDRH_IMM out of range12 %i\n", offset); - codegen_addlong(block, OPCODE_LDRH_IMM | OFFSET12_H(offset) | Rn(base_reg) | Rt(dest_reg)); +void host_arm64_LDRH_IMM(codeblock_t *block, int dest_reg, int base_reg, int offset) { + if (!in_range12_h(offset)) + fatal("host_arm64_LDRH_IMM out of range12 %i\n", offset); + codegen_addlong(block, OPCODE_LDRH_IMM | OFFSET12_H(offset) | Rn(base_reg) | Rt(dest_reg)); } -void host_arm64_LDRH_REG(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) -{ - codegen_addlong(block, OPCODE_LDRH_REG | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); +void host_arm64_LDRH_REG(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) { + codegen_addlong(block, OPCODE_LDRH_REG | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); } -void host_arm64_LDRX_REG_LSL3(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) -{ - codegen_addlong(block, OPCODE_LDRX_REG_LSL3 | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); +void host_arm64_LDRX_REG_LSL3(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) { + codegen_addlong(block, OPCODE_LDRX_REG_LSL3 | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); } -void host_arm64_LSL(codeblock_t *block, int dst_reg, int src_n_reg, int shift_reg) -{ - codegen_addlong(block, OPCODE_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(shift_reg)); +void host_arm64_LSL(codeblock_t *block, int dst_reg, int src_n_reg, int shift_reg) { + codegen_addlong(block, OPCODE_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(shift_reg)); } -void host_arm64_LSR(codeblock_t *block, int dst_reg, int src_n_reg, int shift_reg) -{ - codegen_addlong(block, OPCODE_LSR | Rd(dst_reg) | Rn(src_n_reg) | Rm(shift_reg)); +void host_arm64_LSR(codeblock_t *block, int dst_reg, int src_n_reg, int shift_reg) { + codegen_addlong(block, OPCODE_LSR | Rd(dst_reg) | Rn(src_n_reg) | Rm(shift_reg)); } -void host_arm64_MOV_REG_ASR(codeblock_t *block, int dst_reg, int src_m_reg, int shift) -{ - codegen_addlong(block, OPCODE_ORR_ASR | Rd(dst_reg) | Rn(REG_WZR) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +void host_arm64_MOV_REG_ASR(codeblock_t *block, int dst_reg, int src_m_reg, int shift) { + codegen_addlong(block, OPCODE_ORR_ASR | Rd(dst_reg) | Rn(REG_WZR) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } -void host_arm64_MOV_REG(codeblock_t *block, int dst_reg, int src_m_reg, int shift) -{ - if (dst_reg != src_m_reg || shift) - codegen_addlong(block, OPCODE_ORR_LSL | Rd(dst_reg) | Rn(REG_WZR) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +void host_arm64_MOV_REG(codeblock_t *block, int dst_reg, int src_m_reg, int shift) { + if (dst_reg != src_m_reg || shift) + codegen_addlong(block, OPCODE_ORR_LSL | Rd(dst_reg) | Rn(REG_WZR) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } -void host_arm64_MOV_REG_LSR(codeblock_t *block, int dst_reg, int src_m_reg, int shift) -{ - codegen_addlong(block, OPCODE_ORR_LSR | Rd(dst_reg) | Rn(REG_WZR) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +void host_arm64_MOV_REG_LSR(codeblock_t *block, int dst_reg, int src_m_reg, int shift) { + codegen_addlong(block, OPCODE_ORR_LSR | Rd(dst_reg) | Rn(REG_WZR) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } -void host_arm64_MOV_REG_ROR(codeblock_t *block, int dst_reg, int src_m_reg, int shift) -{ - codegen_addlong(block, OPCODE_ORR_ROR | Rd(dst_reg) | Rn(REG_WZR) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +void host_arm64_MOV_REG_ROR(codeblock_t *block, int dst_reg, int src_m_reg, int shift) { + codegen_addlong(block, OPCODE_ORR_ROR | Rd(dst_reg) | Rn(REG_WZR) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } -void host_arm64_MOVX_IMM(codeblock_t *block, int reg, uint64_t imm_data) -{ - codegen_addlong(block, OPCODE_MOVZ_X | MOV_WIDE_HW(0) | IMM16(imm_data & 0xffff) | Rd(reg)); - if ((imm_data >> 16) & 0xffff) - codegen_addlong(block, OPCODE_MOVK_X | MOV_WIDE_HW(1) | IMM16((imm_data >> 16) & 0xffff) | Rd(reg)); - if ((imm_data >> 32) & 0xffff) - codegen_addlong(block, OPCODE_MOVK_X | MOV_WIDE_HW(2) | IMM16((imm_data >> 32) & 0xffff) | Rd(reg)); - if ((imm_data >> 48) & 0xffff) - codegen_addlong(block, OPCODE_MOVK_X | MOV_WIDE_HW(3) | IMM16((imm_data >> 48) & 0xffff) | Rd(reg)); +void host_arm64_MOVX_IMM(codeblock_t *block, int reg, uint64_t imm_data) { + codegen_addlong(block, OPCODE_MOVZ_X | MOV_WIDE_HW(0) | IMM16(imm_data & 0xffff) | Rd(reg)); + if ((imm_data >> 16) & 0xffff) + codegen_addlong(block, OPCODE_MOVK_X | MOV_WIDE_HW(1) | IMM16((imm_data >> 16) & 0xffff) | Rd(reg)); + if ((imm_data >> 32) & 0xffff) + codegen_addlong(block, OPCODE_MOVK_X | MOV_WIDE_HW(2) | IMM16((imm_data >> 32) & 0xffff) | Rd(reg)); + if ((imm_data >> 48) & 0xffff) + codegen_addlong(block, OPCODE_MOVK_X | MOV_WIDE_HW(3) | IMM16((imm_data >> 48) & 0xffff) | Rd(reg)); } -void host_arm64_MOVX_REG(codeblock_t *block, int dst_reg, int src_m_reg, int shift) -{ - if (dst_reg != src_m_reg) - codegen_addlong(block, OPCODE_ORRX_LSL | Rd(dst_reg) | Rn(REG_XZR) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +void host_arm64_MOVX_REG(codeblock_t *block, int dst_reg, int src_m_reg, int shift) { + if (dst_reg != src_m_reg) + codegen_addlong(block, OPCODE_ORRX_LSL | Rd(dst_reg) | Rn(REG_XZR) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } -void host_arm64_MOVZ_IMM(codeblock_t *block, int reg, uint32_t imm_data) -{ - int hw; +void host_arm64_MOVZ_IMM(codeblock_t *block, int reg, uint32_t imm_data) { + int hw; - if (!imm_is_imm16(imm_data)) - fatal("MOVZ_IMM - imm not representable %08x\n", imm_data); + if (!imm_is_imm16(imm_data)) + fatal("MOVZ_IMM - imm not representable %08x\n", imm_data); - hw = (imm_data & 0xffff0000) ? 1 : 0; - if (hw) - imm_data >>= 16; + hw = (imm_data & 0xffff0000) ? 1 : 0; + if (hw) + imm_data >>= 16; - codegen_addlong(block, OPCODE_MOVZ_W | MOV_WIDE_HW(hw) | IMM16(imm_data) | Rd(reg)); + codegen_addlong(block, OPCODE_MOVZ_W | MOV_WIDE_HW(hw) | IMM16(imm_data) | Rd(reg)); } -void host_arm64_MOVK_IMM(codeblock_t *block, int reg, uint32_t imm_data) -{ - int hw; +void host_arm64_MOVK_IMM(codeblock_t *block, int reg, uint32_t imm_data) { + int hw; - if (!imm_is_imm16(imm_data)) - fatal("MOVK_IMM - imm not representable %08x\n", imm_data); + if (!imm_is_imm16(imm_data)) + fatal("MOVK_IMM - imm not representable %08x\n", imm_data); - hw = (imm_data & 0xffff0000) ? 1 : 0; - if (hw) - imm_data >>= 16; + hw = (imm_data & 0xffff0000) ? 1 : 0; + if (hw) + imm_data >>= 16; - codegen_addlong(block, OPCODE_MOVK_W | MOV_WIDE_HW(hw) | IMM16(imm_data) | Rd(reg)); + codegen_addlong(block, OPCODE_MOVK_W | MOV_WIDE_HW(hw) | IMM16(imm_data) | Rd(reg)); } -void host_arm64_MSR_FPCR(codeblock_t *block, int src_reg) -{ - codegen_addlong(block, OPCODE_MSR_FPCR | Rd(src_reg)); -} +void host_arm64_MSR_FPCR(codeblock_t *block, int src_reg) { codegen_addlong(block, OPCODE_MSR_FPCR | Rd(src_reg)); } -void host_arm64_MUL_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) -{ - codegen_addlong(block, OPCODE_MUL_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +void host_arm64_MUL_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { + codegen_addlong(block, OPCODE_MUL_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_NOP(codeblock_t *block) -{ - codegen_addlong(block, OPCODE_NOP); -} +void host_arm64_NOP(codeblock_t *block) { codegen_addlong(block, OPCODE_NOP); } -void host_arm64_ORR_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) -{ - uint32_t imm_encoding = host_arm64_find_imm(imm_data); +void host_arm64_ORR_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) { + uint32_t imm_encoding = host_arm64_find_imm(imm_data); - if (imm_encoding) - { - codegen_addlong(block, OPCODE_ORR_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM_LOGICAL(imm_encoding)); - } - else - { - host_arm64_mov_imm(block, REG_W16, imm_data); - codegen_addlong(block, OPCODE_ORR_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); - } + if (imm_encoding) { + codegen_addlong(block, OPCODE_ORR_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM_LOGICAL(imm_encoding)); + } else { + host_arm64_mov_imm(block, REG_W16, imm_data); + codegen_addlong(block, OPCODE_ORR_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); + } } -void host_arm64_ORR_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) -{ - codegen_addlong(block, OPCODE_ORR_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +void host_arm64_ORR_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) { + codegen_addlong(block, OPCODE_ORR_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } -void host_arm64_ORR_REG_V(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) -{ - codegen_addlong(block, OPCODE_ORR_V | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +void host_arm64_ORR_REG_V(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { + codegen_addlong(block, OPCODE_ORR_V | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_RET(codeblock_t *block, int reg) -{ - codegen_addlong(block, OPCODE_RET | Rn(reg)); -} +void host_arm64_RET(codeblock_t *block, int reg) { codegen_addlong(block, OPCODE_RET | Rn(reg)); } -void host_arm64_ROR(codeblock_t *block, int dst_reg, int src_n_reg, int shift_reg) -{ - codegen_addlong(block, OPCODE_ROR | Rd(dst_reg) | Rn(src_n_reg) | Rm(shift_reg)); +void host_arm64_ROR(codeblock_t *block, int dst_reg, int src_n_reg, int shift_reg) { + codegen_addlong(block, OPCODE_ROR | Rd(dst_reg) | Rn(src_n_reg) | Rm(shift_reg)); } -void host_arm64_SADDLP_V2S_4H(codeblock_t *block, int dst_reg, int src_n_reg) -{ - codegen_addlong(block, OPCODE_SADDLP_V2S_4H | Rd(dst_reg) | Rn(src_n_reg)); +void host_arm64_SADDLP_V2S_4H(codeblock_t *block, int dst_reg, int src_n_reg) { + codegen_addlong(block, OPCODE_SADDLP_V2S_4H | Rd(dst_reg) | Rn(src_n_reg)); } -void host_arm64_SBFX(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width) -{ - codegen_addlong(block, OPCODE_SBFX | Rd(dst_reg) | Rn(src_reg) | IMMN(0) | IMMR(lsb) | IMMS((lsb+width-1) & 31)); +void host_arm64_SBFX(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width) { + codegen_addlong(block, OPCODE_SBFX | Rd(dst_reg) | Rn(src_reg) | IMMN(0) | IMMR(lsb) | IMMS((lsb + width - 1) & 31)); } -void host_arm64_SCVTF_D_Q(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_addlong(block, OPCODE_SCVTF_D_Q | Rd(dst_reg) | Rn(src_reg)); +void host_arm64_SCVTF_D_Q(codeblock_t *block, int dst_reg, int src_reg) { + codegen_addlong(block, OPCODE_SCVTF_D_Q | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_SCVTF_D_W(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_addlong(block, OPCODE_SCVTF_D_W | Rd(dst_reg) | Rn(src_reg)); +void host_arm64_SCVTF_D_W(codeblock_t *block, int dst_reg, int src_reg) { + codegen_addlong(block, OPCODE_SCVTF_D_W | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_SCVTF_V2S(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_addlong(block, OPCODE_SCVTF_V2S | Rd(dst_reg) | Rn(src_reg)); +void host_arm64_SCVTF_V2S(codeblock_t *block, int dst_reg, int src_reg) { + codegen_addlong(block, OPCODE_SCVTF_V2S | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_SHRN_V4H_4S(codeblock_t *block, int dst_reg, int src_n_reg, int shift) -{ - if (shift > 16) - fatal("host_arm64_SHRN_V4H_4S : shift > 16\n"); - codegen_addlong(block, OPCODE_SHRN | Rd(dst_reg) | Rn(src_n_reg) | SHRN_SHIFT_IMM_V4S(16-shift)); +void host_arm64_SHRN_V4H_4S(codeblock_t *block, int dst_reg, int src_n_reg, int shift) { + if (shift > 16) + fatal("host_arm64_SHRN_V4H_4S : shift > 16\n"); + codegen_addlong(block, OPCODE_SHRN | Rd(dst_reg) | Rn(src_n_reg) | SHRN_SHIFT_IMM_V4S(16 - shift)); } -void host_arm64_SMULL_V4S_4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) -{ - codegen_addlong(block, OPCODE_SMULL_V4S_4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +void host_arm64_SMULL_V4S_4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { + codegen_addlong(block, OPCODE_SMULL_V4S_4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} + +void host_arm64_SQADD_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { + codegen_addlong(block, OPCODE_SQADD_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} +void host_arm64_SQADD_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { + codegen_addlong(block, OPCODE_SQADD_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} +void host_arm64_SQSUB_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { + codegen_addlong(block, OPCODE_SQSUB_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} +void host_arm64_SQSUB_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { + codegen_addlong(block, OPCODE_SQSUB_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_SQADD_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) -{ - codegen_addlong(block, OPCODE_SQADD_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +void host_arm64_SQXTN_V8B_8H(codeblock_t *block, int dst_reg, int src_reg) { + codegen_addlong(block, OPCODE_SQXTN_V8B_8H | Rd(dst_reg) | Rn(src_reg)); +} +void host_arm64_SQXTN_V4H_4S(codeblock_t *block, int dst_reg, int src_reg) { + codegen_addlong(block, OPCODE_SQXTN_V4H_4S | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_SQADD_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) -{ - codegen_addlong(block, OPCODE_SQADD_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + +void host_arm64_SHL_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int shift) { + codegen_addlong(block, OPCODE_SHL_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V4H(shift)); } -void host_arm64_SQSUB_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) -{ - codegen_addlong(block, OPCODE_SQSUB_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +void host_arm64_SHL_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int shift) { + codegen_addlong(block, OPCODE_SHL_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2S(shift)); } -void host_arm64_SQSUB_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) -{ - codegen_addlong(block, OPCODE_SQSUB_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +void host_arm64_SHL_V2D(codeblock_t *block, int dst_reg, int src_n_reg, int shift) { + codegen_addlong(block, OPCODE_SHL_VQ | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2D(shift)); } -void host_arm64_SQXTN_V8B_8H(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_addlong(block, OPCODE_SQXTN_V8B_8H | Rd(dst_reg) | Rn(src_reg)); +void host_arm64_SSHR_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int shift) { + if (shift > 16) + fatal("host_arm_USHR_V4H : shift > 16\n"); + codegen_addlong(block, OPCODE_SSHR_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V4H(16 - shift)); +} +void host_arm64_SSHR_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int shift) { + if (shift > 32) + fatal("host_arm_SSHR_V2S : shift > 32\n"); + codegen_addlong(block, OPCODE_SSHR_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2S(32 - shift)); } -void host_arm64_SQXTN_V4H_4S(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_addlong(block, OPCODE_SQXTN_V4H_4S | Rd(dst_reg) | Rn(src_reg)); +void host_arm64_SSHR_V2D(codeblock_t *block, int dst_reg, int src_n_reg, int shift) { + if (shift > 64) + fatal("host_arm_SSHR_V2D : shift > 64\n"); + codegen_addlong(block, OPCODE_SSHR_VQ | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2D(64 - shift)); } -void host_arm64_SHL_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int shift) -{ - codegen_addlong(block, OPCODE_SHL_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V4H(shift)); +void host_arm64_STP_PREIDX_X(codeblock_t *block, int src_reg1, int src_reg2, int base_reg, int offset) { + if (!in_range7_x(offset)) + fatal("host_arm64_STP_PREIDX out of range7 %i\n", offset); + codegen_addlong(block, OPCODE_STP_PREIDX_X | IMM7_X(offset) | Rn(base_reg) | Rt(src_reg1) | Rt2(src_reg2)); } -void host_arm64_SHL_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int shift) -{ - codegen_addlong(block, OPCODE_SHL_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2S(shift)); + +void host_arm64_STR_IMM_W(codeblock_t *block, int dest_reg, int base_reg, int offset) { + if (!in_range12_w(offset)) + fatal("host_arm64_STR_IMM_W out of range12 %i\n", offset); + codegen_addlong(block, OPCODE_STR_IMM_W | OFFSET12_W(offset) | Rn(base_reg) | Rt(dest_reg)); } -void host_arm64_SHL_V2D(codeblock_t *block, int dst_reg, int src_n_reg, int shift) -{ - codegen_addlong(block, OPCODE_SHL_VQ | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2D(shift)); +void host_arm64_STR_IMM_Q(codeblock_t *block, int dest_reg, int base_reg, int offset) { + if (!in_range12_q(offset)) + fatal("host_arm64_STR_IMM_W out of range12 %i\n", offset); + codegen_addlong(block, OPCODE_STR_IMM_Q | OFFSET12_Q(offset) | Rn(base_reg) | Rt(dest_reg)); +} +void host_arm64_STR_REG(codeblock_t *block, int src_reg, int base_reg, int offset_reg) { + codegen_addlong(block, OPCODE_STR_REG | Rn(base_reg) | Rm(offset_reg) | Rt(src_reg)); } -void host_arm64_SSHR_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int shift) -{ - if (shift > 16) - fatal("host_arm_USHR_V4H : shift > 16\n"); - codegen_addlong(block, OPCODE_SSHR_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V4H(16-shift)); +void host_arm64_STR_REG_F32(codeblock_t *block, int src_reg, int base_reg, int offset_reg) { + codegen_addlong(block, OPCODE_STR_REG_F32 | Rn(base_reg) | Rm(offset_reg) | Rt(src_reg)); +} +void host_arm64_STR_IMM_F64(codeblock_t *block, int src_reg, int base_reg, int offset) { + codegen_addlong(block, OPCODE_STR_IMM_F64 | OFFSET12_Q(offset) | Rn(base_reg) | Rt(src_reg)); +} +void host_arm64_STR_REG_F64(codeblock_t *block, int src_reg, int base_reg, int offset_reg) { + codegen_addlong(block, OPCODE_STR_REG_F64 | Rn(base_reg) | Rm(offset_reg) | Rt(src_reg)); } -void host_arm64_SSHR_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int shift) -{ - if (shift > 32) - fatal("host_arm_SSHR_V2S : shift > 32\n"); - codegen_addlong(block, OPCODE_SSHR_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2S(32-shift)); +void host_arm64_STR_REG_F64_S(codeblock_t *block, int src_reg, int base_reg, int offset_reg) { + codegen_addlong(block, OPCODE_STR_REG_F64_S | Rn(base_reg) | Rm(offset_reg) | Rt(src_reg)); +} + +void host_arm64_STRB_IMM(codeblock_t *block, int dest_reg, int base_reg, int offset) { + if (!in_range12_b(offset)) + fatal("host_arm64_STRB_IMM out of range12 %i\n", offset); + codegen_addlong(block, OPCODE_STRB_IMM | OFFSET12_B(offset) | Rn(base_reg) | Rt(dest_reg)); } -void host_arm64_SSHR_V2D(codeblock_t *block, int dst_reg, int src_n_reg, int shift) -{ - if (shift > 64) - fatal("host_arm_SSHR_V2D : shift > 64\n"); - codegen_addlong(block, OPCODE_SSHR_VQ | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2D(64-shift)); +void host_arm64_STRB_REG(codeblock_t *block, int src_reg, int base_reg, int offset_reg) { + codegen_addlong(block, OPCODE_STRB_REG | Rn(base_reg) | Rm(offset_reg) | Rt(src_reg)); } -void host_arm64_STP_PREIDX_X(codeblock_t *block, int src_reg1, int src_reg2, int base_reg, int offset) -{ - if (!in_range7_x(offset)) - fatal("host_arm64_STP_PREIDX out of range7 %i\n", offset); - codegen_addlong(block, OPCODE_STP_PREIDX_X | IMM7_X(offset) | Rn(base_reg) | Rt(src_reg1) | Rt2(src_reg2)); +void host_arm64_STRH_IMM(codeblock_t *block, int dest_reg, int base_reg, int offset) { + if (!in_range12_h(offset)) + fatal("host_arm64_STRH_IMM out of range12 %i\n", offset); + codegen_addlong(block, OPCODE_STRH_IMM | OFFSET12_H(offset) | Rn(base_reg) | Rt(dest_reg)); +} +void host_arm64_STRH_REG(codeblock_t *block, int src_reg, int base_reg, int offset_reg) { + codegen_addlong(block, OPCODE_STRH_REG | Rn(base_reg) | Rm(offset_reg) | Rt(src_reg)); } -void host_arm64_STR_IMM_W(codeblock_t *block, int dest_reg, int base_reg, int offset) -{ - if (!in_range12_w(offset)) - fatal("host_arm64_STR_IMM_W out of range12 %i\n", offset); - codegen_addlong(block, OPCODE_STR_IMM_W | OFFSET12_W(offset) | Rn(base_reg) | Rt(dest_reg)); +void host_arm64_SUB_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) { + if (!imm_data) + host_arm64_MOV_REG(block, dst_reg, src_n_reg, 0); + else if ((int32_t)imm_data < 0 && imm_data != 0x80000000) { + host_arm64_ADD_IMM(block, dst_reg, src_n_reg, -(int32_t)imm_data); + } else if (!(imm_data & 0xff000000)) { + if (imm_data & 0xfff) { + codegen_addlong(block, OPCODE_SUB_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | + DATPROC_IMM_SHIFT(0)); + if (imm_data & 0xfff000) + codegen_addlong(block, OPCODE_SUB_IMM | Rd(dst_reg) | Rn(dst_reg) | + IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1)); + } else if (imm_data & 0xfff000) + codegen_addlong(block, OPCODE_SUB_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12((imm_data >> 12) & 0xfff) | + DATPROC_IMM_SHIFT(1)); + } else { + host_arm64_MOVZ_IMM(block, REG_W16, imm_data & 0xffff); + host_arm64_MOVK_IMM(block, REG_W16, imm_data & 0xffff0000); + codegen_addlong(block, OPCODE_SUB_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); + } +} +void host_arm64_SUB_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) { + codegen_addlong(block, OPCODE_SUB_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +} +void host_arm64_SUB_REG_LSR(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) { + codegen_addlong(block, OPCODE_SUB_LSR | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } -void host_arm64_STR_IMM_Q(codeblock_t *block, int dest_reg, int base_reg, int offset) -{ - if (!in_range12_q(offset)) - fatal("host_arm64_STR_IMM_W out of range12 %i\n", offset); - codegen_addlong(block, OPCODE_STR_IMM_Q | OFFSET12_Q(offset) | Rn(base_reg) | Rt(dest_reg)); +void host_arm64_SUB_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { + codegen_addlong(block, OPCODE_SUB_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_STR_REG(codeblock_t *block, int src_reg, int base_reg, int offset_reg) -{ - codegen_addlong(block, OPCODE_STR_REG | Rn(base_reg) | Rm(offset_reg) | Rt(src_reg)); +void host_arm64_SUB_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { + codegen_addlong(block, OPCODE_SUB_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} +void host_arm64_SUB_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { + codegen_addlong(block, OPCODE_SUB_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_STR_REG_F32(codeblock_t *block, int src_reg, int base_reg, int offset_reg) -{ - codegen_addlong(block, OPCODE_STR_REG_F32 | Rn(base_reg) | Rm(offset_reg) | Rt(src_reg)); +uint32_t *host_arm64_TBNZ(codeblock_t *block, int reg, int bit) { + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_TBZ | Rt(reg) | BIT_TBxZ(bit) | OFFSET14(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *)&block_write_data[block_pos - 4]; } -void host_arm64_STR_IMM_F64(codeblock_t *block, int src_reg, int base_reg, int offset) -{ - codegen_addlong(block, OPCODE_STR_IMM_F64 | OFFSET12_Q(offset) | Rn(base_reg) | Rt(src_reg)); + +void host_arm64_UBFX(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width) { + codegen_addlong(block, OPCODE_UBFX | Rd(dst_reg) | Rn(src_reg) | IMMN(0) | IMMR(lsb) | IMMS((lsb + width - 1) & 31)); } -void host_arm64_STR_REG_F64(codeblock_t *block, int src_reg, int base_reg, int offset_reg) -{ - codegen_addlong(block, OPCODE_STR_REG_F64 | Rn(base_reg) | Rm(offset_reg) | Rt(src_reg)); + +void host_arm64_UQADD_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { + codegen_addlong(block, OPCODE_UQADD_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_STR_REG_F64_S(codeblock_t *block, int src_reg, int base_reg, int offset_reg) -{ - codegen_addlong(block, OPCODE_STR_REG_F64_S | Rn(base_reg) | Rm(offset_reg) | Rt(src_reg)); +void host_arm64_UQADD_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { + codegen_addlong(block, OPCODE_UQADD_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} +void host_arm64_UQSUB_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { + codegen_addlong(block, OPCODE_UQSUB_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} +void host_arm64_UQSUB_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { + codegen_addlong(block, OPCODE_UQSUB_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_STRB_IMM(codeblock_t *block, int dest_reg, int base_reg, int offset) -{ - if (!in_range12_b(offset)) - fatal("host_arm64_STRB_IMM out of range12 %i\n", offset); - codegen_addlong(block, OPCODE_STRB_IMM | OFFSET12_B(offset) | Rn(base_reg) | Rt(dest_reg)); -} -void host_arm64_STRB_REG(codeblock_t *block, int src_reg, int base_reg, int offset_reg) -{ - codegen_addlong(block, OPCODE_STRB_REG | Rn(base_reg) | Rm(offset_reg) | Rt(src_reg)); +void host_arm64_UQXTN_V8B_8H(codeblock_t *block, int dst_reg, int src_reg) { + codegen_addlong(block, OPCODE_UQXTN_V8B_8H | Rd(dst_reg) | Rn(src_reg)); +} +void host_arm64_UQXTN_V4H_4S(codeblock_t *block, int dst_reg, int src_reg) { + codegen_addlong(block, OPCODE_UQXTN_V4H_4S | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_STRH_IMM(codeblock_t *block, int dest_reg, int base_reg, int offset) -{ - if (!in_range12_h(offset)) - fatal("host_arm64_STRH_IMM out of range12 %i\n", offset); - codegen_addlong(block, OPCODE_STRH_IMM | OFFSET12_H(offset) | Rn(base_reg) | Rt(dest_reg)); +void host_arm64_USHR_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int shift) { + if (shift > 16) + fatal("host_arm_USHR_V4H : shift > 16\n"); + codegen_addlong(block, OPCODE_USHR_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V4H(16 - shift)); } -void host_arm64_STRH_REG(codeblock_t *block, int src_reg, int base_reg, int offset_reg) -{ - codegen_addlong(block, OPCODE_STRH_REG | Rn(base_reg) | Rm(offset_reg) | Rt(src_reg)); -} - -void host_arm64_SUB_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) -{ - if (!imm_data) - host_arm64_MOV_REG(block, dst_reg, src_n_reg, 0); - else if ((int32_t)imm_data < 0 && imm_data != 0x80000000) - { - host_arm64_ADD_IMM(block, dst_reg, src_n_reg, -(int32_t)imm_data); - } - else if (!(imm_data & 0xff000000)) - { - if (imm_data & 0xfff) - { - codegen_addlong(block, OPCODE_SUB_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); - if (imm_data & 0xfff000) - codegen_addlong(block, OPCODE_SUB_IMM | Rd(dst_reg) | Rn(dst_reg) | IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1)); - } - else if (imm_data & 0xfff000) - codegen_addlong(block, OPCODE_SUB_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1)); - } - else - { - host_arm64_MOVZ_IMM(block, REG_W16, imm_data & 0xffff); - host_arm64_MOVK_IMM(block, REG_W16, imm_data & 0xffff0000); - codegen_addlong(block, OPCODE_SUB_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); - } -} -void host_arm64_SUB_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) -{ - codegen_addlong(block, OPCODE_SUB_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); +void host_arm64_USHR_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int shift) { + if (shift > 32) + fatal("host_arm_USHR_V4S : shift > 32\n"); + codegen_addlong(block, OPCODE_USHR_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2S(32 - shift)); } -void host_arm64_SUB_REG_LSR(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) -{ - codegen_addlong(block, OPCODE_SUB_LSR | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); -} -void host_arm64_SUB_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) -{ - codegen_addlong(block, OPCODE_SUB_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); -} -void host_arm64_SUB_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) -{ - codegen_addlong(block, OPCODE_SUB_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +void host_arm64_USHR_V2D(codeblock_t *block, int dst_reg, int src_n_reg, int shift) { + if (shift > 64) + fatal("host_arm_USHR_V2D : shift > 64\n"); + codegen_addlong(block, OPCODE_USHR_VQ | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2D(64 - shift)); +} + +void host_arm64_ZIP1_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { + codegen_addlong(block, OPCODE_ZIP1_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_SUB_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) -{ - codegen_addlong(block, OPCODE_SUB_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); -} - -uint32_t *host_arm64_TBNZ(codeblock_t *block, int reg, int bit) -{ - codegen_alloc(block, 12); - codegen_addlong(block, OPCODE_TBZ | Rt(reg) | BIT_TBxZ(bit) | OFFSET14(8)); - codegen_addlong(block, OPCODE_B); - return (uint32_t *)&block_write_data[block_pos-4]; -} - -void host_arm64_UBFX(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width) -{ - codegen_addlong(block, OPCODE_UBFX | Rd(dst_reg) | Rn(src_reg) | IMMN(0) | IMMR(lsb) | IMMS((lsb+width-1) & 31)); -} - -void host_arm64_UQADD_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) -{ - codegen_addlong(block, OPCODE_UQADD_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); -} -void host_arm64_UQADD_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) -{ - codegen_addlong(block, OPCODE_UQADD_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); -} -void host_arm64_UQSUB_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) -{ - codegen_addlong(block, OPCODE_UQSUB_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); -} -void host_arm64_UQSUB_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) -{ - codegen_addlong(block, OPCODE_UQSUB_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); -} - -void host_arm64_UQXTN_V8B_8H(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_addlong(block, OPCODE_UQXTN_V8B_8H | Rd(dst_reg) | Rn(src_reg)); -} -void host_arm64_UQXTN_V4H_4S(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_addlong(block, OPCODE_UQXTN_V4H_4S | Rd(dst_reg) | Rn(src_reg)); -} - -void host_arm64_USHR_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int shift) -{ - if (shift > 16) - fatal("host_arm_USHR_V4H : shift > 16\n"); - codegen_addlong(block, OPCODE_USHR_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V4H(16-shift)); -} -void host_arm64_USHR_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int shift) -{ - if (shift > 32) - fatal("host_arm_USHR_V4S : shift > 32\n"); - codegen_addlong(block, OPCODE_USHR_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2S(32-shift)); -} -void host_arm64_USHR_V2D(codeblock_t *block, int dst_reg, int src_n_reg, int shift) -{ - if (shift > 64) - fatal("host_arm_USHR_V2D : shift > 64\n"); - codegen_addlong(block, OPCODE_USHR_VQ | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2D(64-shift)); -} - -void host_arm64_ZIP1_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) -{ - codegen_addlong(block, OPCODE_ZIP1_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); -} -void host_arm64_ZIP1_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) -{ - codegen_addlong(block, OPCODE_ZIP1_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +void host_arm64_ZIP1_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { + codegen_addlong(block, OPCODE_ZIP1_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_ZIP1_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) -{ - codegen_addlong(block, OPCODE_ZIP1_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +void host_arm64_ZIP1_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { + codegen_addlong(block, OPCODE_ZIP1_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_ZIP2_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) -{ - codegen_addlong(block, OPCODE_ZIP2_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +void host_arm64_ZIP2_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { + codegen_addlong(block, OPCODE_ZIP2_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_ZIP2_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) -{ - codegen_addlong(block, OPCODE_ZIP2_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +void host_arm64_ZIP2_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { + codegen_addlong(block, OPCODE_ZIP2_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_ZIP2_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) -{ - codegen_addlong(block, OPCODE_ZIP2_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +void host_arm64_ZIP2_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { + codegen_addlong(block, OPCODE_ZIP2_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_call(codeblock_t *block, void *dst_addr) -{ - host_arm64_MOVX_IMM(block, REG_X16, (uint64_t)dst_addr); - host_arm64_BLR(block, REG_X16); +void host_arm64_call(codeblock_t *block, void *dst_addr) { + host_arm64_MOVX_IMM(block, REG_X16, (uint64_t)dst_addr); + host_arm64_BLR(block, REG_X16); } -void host_arm64_jump(codeblock_t *block, uintptr_t dst_addr) -{ - host_arm64_MOVX_IMM(block, REG_X16, (uint64_t)dst_addr); - host_arm64_BR(block, REG_X16); +void host_arm64_jump(codeblock_t *block, uintptr_t dst_addr) { + host_arm64_MOVX_IMM(block, REG_X16, (uint64_t)dst_addr); + host_arm64_BR(block, REG_X16); } -void host_arm64_mov_imm(codeblock_t *block, int reg, uint32_t imm_data) -{ - if (imm_is_imm16(imm_data)) - host_arm64_MOVZ_IMM(block, reg, imm_data); - else - { - host_arm64_MOVZ_IMM(block, reg, imm_data & 0xffff); - host_arm64_MOVK_IMM(block, reg, imm_data & 0xffff0000); - } +void host_arm64_mov_imm(codeblock_t *block, int reg, uint32_t imm_data) { + if (imm_is_imm16(imm_data)) + host_arm64_MOVZ_IMM(block, reg, imm_data); + else { + host_arm64_MOVZ_IMM(block, reg, imm_data & 0xffff); + host_arm64_MOVK_IMM(block, reg, imm_data & 0xffff0000); + } } #endif diff --git a/src/codegen/arm64/codegen_backend_arm64_uops.c b/src/codegen/arm64/codegen_backend_arm64_uops.c index 4b41942c..cba22be5 100644 --- a/src/codegen/arm64/codegen_backend_arm64_uops.c +++ b/src/codegen/arm64/codegen_backend_arm64_uops.c @@ -21,3348 +21,2706 @@ #define REG_IS_D(size) (size == IREG_SIZE_D) #define REG_IS_Q(size) (size == IREG_SIZE_Q) -static int codegen_ADD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_ADD_REG(block, dest_reg, src_reg_a, src_reg_b, 0); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm64_ADD_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_ADD_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b)) - { - host_arm64_ADD_REG_LSR(block, REG_TEMP, src_reg_a, src_reg_b, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_ADD_REG_LSR(block, REG_TEMP, src_reg_b, src_reg_a, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b)) - { - host_arm64_AND_IMM(block, REG_TEMP, src_reg_a, 0x0000ff00); - host_arm64_ADD_REG(block, REG_TEMP, REG_TEMP, src_reg_b, 0); - host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("ADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} - -static int codegen_ADD_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm64_ADD_IMM(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm64_ADD_IMM(block, REG_TEMP, src_reg, uop->imm_data); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm64_ADD_IMM(block, REG_TEMP, src_reg, uop->imm_data); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_ADD_IMM(block, REG_TEMP, src_reg, uop->imm_data << 8); - host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("ADD_IMM %x %x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} - -static int codegen_ADD_LSHIFT(codeblock_t *block, uop_t *uop) -{ - host_arm64_ADD_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, uop->imm_data); - return 0; -} - -static int codegen_AND(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_AND_REG_V(block, dest_reg, src_reg_a, src_reg_b); - } - else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_AND_REG(block, dest_reg, src_reg_a, src_reg_b, 0); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b) && dest_reg == src_reg_a) - { - host_arm64_ORR_IMM(block, REG_TEMP, src_reg_b, 0xffff0000); - host_arm64_AND_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) - { - host_arm64_ORR_IMM(block, REG_TEMP, src_reg_b, 0xffffff00); - host_arm64_AND_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) - { - host_arm64_ORR_IMM(block, REG_TEMP, src_reg_b, 0xffff00ff); - host_arm64_AND_REG_ASR(block, dest_reg, src_reg_a, REG_TEMP, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) - { - host_arm64_ORR_IMM(block, REG_TEMP, src_reg_b, 0xffffff00); - host_arm64_AND_REG_ROR(block, dest_reg, src_reg_a, REG_TEMP, 24); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) - { - host_arm64_ORR_IMM(block, REG_TEMP, src_reg_b, 0xffff00ff); - host_arm64_AND_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm64_AND_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_AND_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b)) - { - host_arm64_ORR_IMM(block, REG_TEMP, src_reg_b, 0xffff00ff); - host_arm64_AND_REG_ROR(block, REG_TEMP, src_reg_a, REG_TEMP, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_ORR_IMM(block, REG_TEMP, src_reg_a, 0xffff00ff); - host_arm64_AND_REG_ROR(block, REG_TEMP, src_reg_b, REG_TEMP, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b)) - { - host_arm64_AND_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0); - host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else - fatal("AND %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm64_AND_IMM(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm64_AND_IMM(block, dest_reg, src_reg, uop->imm_data | 0xffff0000); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm64_AND_IMM(block, dest_reg, src_reg, uop->imm_data | 0xffffff00); - } - else if (REG_IS_B(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_MOV_REG_LSR(block, REG_TEMP, src_reg, 8); - host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, uop->imm_data); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_AND_IMM(block, dest_reg, src_reg, (uop->imm_data << 8) | 0xffff00ff); - } - else - fatal("AND_IMM %x %x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} - -static int codegen_ANDN(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_BIC_REG_V(block, dest_reg, src_reg_b, src_reg_a); - } - else - fatal("ANDN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} - -static int codegen_CALL_FUNC(codeblock_t *block, uop_t *uop) -{ - host_arm64_call(block, uop->p); - - return 0; -} - -static int codegen_CALL_FUNC_RESULT(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (!REG_IS_L(dest_size)) - fatal("CALL_FUNC_RESULT %02x\n", uop->dest_reg_a_real); - host_arm64_call(block, uop->p); - host_arm64_MOV_REG(block, dest_reg, REG_W0, 0); - - return 0; -} - -static int codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop) -{ - host_arm64_call(block, uop->p); - host_arm64_CBNZ(block, REG_X0, (uintptr_t)codegen_exit_rout); - - return 0; -} - -static int codegen_CMP_IMM_JZ(codeblock_t *block, uop_t *uop) -{ - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(src_size)) - { - host_arm64_CMP_IMM(block, src_reg, uop->imm_data); - } - else - fatal("CMP_IMM_JZ %02x\n", uop->src_reg_a_real); - host_arm64_BEQ(block, uop->p); - - return 0; -} - -static int codegen_CMP_IMM_JNZ_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(src_size)) - { - host_arm64_CMP_IMM(block, src_reg, uop->imm_data); - } - else if (REG_IS_W(src_size)) - { - host_arm64_AND_IMM(block, REG_TEMP, src_reg, 0xffff); - host_arm64_CMP_IMM(block, REG_TEMP, uop->imm_data); - } - else - fatal("CMP_IMM_JNZ_DEST %02x\n", uop->src_reg_a_real); - - uop->p = host_arm64_BNE_(block); - - return 0; -} -static int codegen_CMP_IMM_JZ_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(src_size)) - { - host_arm64_CMP_IMM(block, src_reg, uop->imm_data); - } - else if (REG_IS_W(src_size)) - { - host_arm64_AND_IMM(block, REG_TEMP, src_reg, 0xffff); - host_arm64_CMP_IMM(block, REG_TEMP, uop->imm_data); - } - else - fatal("CMP_IMM_JZ_DEST %02x\n", uop->src_reg_a_real); - - uop->p = host_arm64_BEQ_(block); - - return 0; -} - -static int codegen_CMP_JB(codeblock_t *block, uop_t *uop) -{ - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - uint32_t *jump_p; - - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_CMP_REG(block, src_reg_a, src_reg_b); - } - else - fatal("CMP_JB %02x\n", uop->src_reg_a_real); - - jump_p = host_arm64_BCC_(block); - host_arm64_branch_set_offset(jump_p, uop->p); - - return 0; -} -static int codegen_CMP_JNBE(codeblock_t *block, uop_t *uop) -{ - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - uint32_t *jump_p; - - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_CMP_REG(block, src_reg_a, src_reg_b); - } - else - fatal("CMP_JNBE %02x\n", uop->src_reg_a_real); - - jump_p = host_arm64_BHI_(block); - host_arm64_branch_set_offset(jump_p, uop->p); - - return 0; -} - -static int codegen_CMP_JNB_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JNB_DEST %02x\n", uop->src_reg_a_real); - - uop->p = host_arm64_BCS_(block); - - return 0; -} -static int codegen_CMP_JNBE_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JNBE_DEST %02x\n", uop->src_reg_a_real); - - uop->p = host_arm64_BHI_(block); - - return 0; -} -static int codegen_CMP_JNL_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JNL_DEST %02x\n", uop->src_reg_a_real); - - uop->p = host_arm64_BGE_(block); - - return 0; -} -static int codegen_CMP_JNLE_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JNLE_DEST %02x\n", uop->src_reg_a_real); - - uop->p = host_arm64_BGT_(block); - - return 0; -} -static int codegen_CMP_JNO_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JNO_DEST %02x\n", uop->src_reg_a_real); - - uop->p = host_arm64_BVC_(block); - - return 0; -} -static int codegen_CMP_JNZ_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JNZ_DEST %02x\n", uop->src_reg_a_real); - - uop->p = host_arm64_BNE_(block); - - return 0; -} -static int codegen_CMP_JB_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JB_DEST %02x\n", uop->src_reg_a_real); - - uop->p = host_arm64_BCC_(block); - - return 0; -} -static int codegen_CMP_JBE_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JBE_DEST %02x\n", uop->src_reg_a_real); - - uop->p = host_arm64_BLS_(block); - - return 0; -} -static int codegen_CMP_JL_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JL_DEST %02x\n", uop->src_reg_a_real); - - uop->p = host_arm64_BLT_(block); - - return 0; -} -static int codegen_CMP_JLE_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JLE_DEST %02x\n", uop->src_reg_a_real); - - uop->p = host_arm64_BLE_(block); - - return 0; -} -static int codegen_CMP_JO_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JO_DEST %02x\n", uop->src_reg_a_real); - - uop->p = host_arm64_BVS_(block); - - return 0; -} -static int codegen_CMP_JZ_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JZ_DEST %02x\n", uop->src_reg_a_real); - - uop->p = host_arm64_BEQ_(block); - - return 0; -} - -static int codegen_FABS(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) - { - host_arm64_FABS_D(block, dest_reg, src_reg_a); - } - else - fatal("codegen_FABS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_FCHS(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) - { - host_arm64_FNEG_D(block, dest_reg, src_reg_a); - } - else - fatal("codegen_FCHS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_FSQRT(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) - { - host_arm64_FSQRT_D(block, dest_reg, src_reg_a); - } - else - fatal("codegen_FSQRT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_FTST(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_W(dest_size) && REG_IS_D(src_size_a)) - { - host_arm64_FSUB_D(block, REG_V_TEMP, REG_V_TEMP, REG_V_TEMP); - host_arm64_MOVZ_IMM(block, dest_reg, 0); - host_arm64_FCMP_D(block, src_reg_a, REG_V_TEMP); - host_arm64_ORR_IMM(block, REG_TEMP, dest_reg, C3); - host_arm64_ORR_IMM(block, REG_TEMP2, dest_reg, C0); - host_arm64_CSEL_EQ(block, dest_reg, REG_TEMP, dest_reg); - host_arm64_ORR_IMM(block, REG_TEMP, dest_reg, C0|C2|C3); - host_arm64_CSEL_CC(block, dest_reg, REG_TEMP2, dest_reg); - host_arm64_CSEL_VS(block, dest_reg, REG_TEMP, dest_reg); - } - else - fatal("codegen_FTST %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} - -static int codegen_FADD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) - { - host_arm64_FADD_D(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("codegen_FADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_FCOM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_W(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) - { - host_arm64_MOVZ_IMM(block, dest_reg, 0); - host_arm64_FCMP_D(block, src_reg_a, src_reg_b); - host_arm64_ORR_IMM(block, REG_TEMP, dest_reg, C3); - host_arm64_ORR_IMM(block, REG_TEMP2, dest_reg, C0); - host_arm64_CSEL_EQ(block, dest_reg, REG_TEMP, dest_reg); - host_arm64_ORR_IMM(block, REG_TEMP, dest_reg, C0|C2|C3); - host_arm64_CSEL_CC(block, dest_reg, REG_TEMP2, dest_reg); - host_arm64_CSEL_VS(block, dest_reg, REG_TEMP, dest_reg); - } - else - fatal("codegen_FCOM %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_FDIV(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) - { - host_arm64_FDIV_D(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("codegen_FDIV %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_FMUL(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) - { - host_arm64_FMUL_D(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("codegen_FMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_FSUB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) - { - host_arm64_FSUB_D(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("codegen_FSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} - -static int codegen_FP_ENTER(codeblock_t *block, uop_t *uop) -{ - uint32_t *branch_ptr; +static int codegen_ADD(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_ADD_REG(block, dest_reg, src_reg_a, src_reg_b, 0); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm64_ADD_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_ADD_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b)) { + host_arm64_ADD_REG_LSR(block, REG_TEMP, src_reg_a, src_reg_b, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_ADD_REG_LSR(block, REG_TEMP, src_reg_b, src_reg_a, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b)) { + host_arm64_AND_IMM(block, REG_TEMP, src_reg_a, 0x0000ff00); + host_arm64_ADD_REG(block, REG_TEMP, REG_TEMP, src_reg_b, 0); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("ADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + +static int codegen_ADD_IMM(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm64_ADD_IMM(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm64_ADD_IMM(block, REG_TEMP, src_reg, uop->imm_data); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm64_ADD_IMM(block, REG_TEMP, src_reg, uop->imm_data); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm64_ADD_IMM(block, REG_TEMP, src_reg, uop->imm_data << 8); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("ADD_IMM %x %x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} + +static int codegen_ADD_LSHIFT(codeblock_t *block, uop_t *uop) { + host_arm64_ADD_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, uop->imm_data); + return 0; +} + +static int codegen_AND(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_AND_REG_V(block, dest_reg, src_reg_a, src_reg_b); + } else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_AND_REG(block, dest_reg, src_reg_a, src_reg_b, 0); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b) && dest_reg == src_reg_a) { + host_arm64_ORR_IMM(block, REG_TEMP, src_reg_b, 0xffff0000); + host_arm64_AND_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) { + host_arm64_ORR_IMM(block, REG_TEMP, src_reg_b, 0xffffff00); + host_arm64_AND_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) { + host_arm64_ORR_IMM(block, REG_TEMP, src_reg_b, 0xffff00ff); + host_arm64_AND_REG_ASR(block, dest_reg, src_reg_a, REG_TEMP, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) { + host_arm64_ORR_IMM(block, REG_TEMP, src_reg_b, 0xffffff00); + host_arm64_AND_REG_ROR(block, dest_reg, src_reg_a, REG_TEMP, 24); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) { + host_arm64_ORR_IMM(block, REG_TEMP, src_reg_b, 0xffff00ff); + host_arm64_AND_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm64_AND_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_AND_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b)) { + host_arm64_ORR_IMM(block, REG_TEMP, src_reg_b, 0xffff00ff); + host_arm64_AND_REG_ROR(block, REG_TEMP, src_reg_a, REG_TEMP, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_ORR_IMM(block, REG_TEMP, src_reg_a, 0xffff00ff); + host_arm64_AND_REG_ROR(block, REG_TEMP, src_reg_b, REG_TEMP, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b)) { + host_arm64_AND_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else + fatal("AND %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm64_AND_IMM(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm64_AND_IMM(block, dest_reg, src_reg, uop->imm_data | 0xffff0000); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm64_AND_IMM(block, dest_reg, src_reg, uop->imm_data | 0xffffff00); + } else if (REG_IS_B(dest_size) && REG_IS_BH(src_size)) { + host_arm64_MOV_REG_LSR(block, REG_TEMP, src_reg, 8); + host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm64_AND_IMM(block, dest_reg, src_reg, (uop->imm_data << 8) | 0xffff00ff); + } else + fatal("AND_IMM %x %x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} + +static int codegen_ANDN(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_BIC_REG_V(block, dest_reg, src_reg_b, src_reg_a); + } else + fatal("ANDN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + +static int codegen_CALL_FUNC(codeblock_t *block, uop_t *uop) { + host_arm64_call(block, uop->p); + + return 0; +} + +static int codegen_CALL_FUNC_RESULT(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (!REG_IS_L(dest_size)) + fatal("CALL_FUNC_RESULT %02x\n", uop->dest_reg_a_real); + host_arm64_call(block, uop->p); + host_arm64_MOV_REG(block, dest_reg, REG_W0, 0); + + return 0; +} + +static int codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop) { + host_arm64_call(block, uop->p); + host_arm64_CBNZ(block, REG_X0, (uintptr_t)codegen_exit_rout); + + return 0; +} + +static int codegen_CMP_IMM_JZ(codeblock_t *block, uop_t *uop) { + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(src_size)) { + host_arm64_CMP_IMM(block, src_reg, uop->imm_data); + } else + fatal("CMP_IMM_JZ %02x\n", uop->src_reg_a_real); + host_arm64_BEQ(block, uop->p); + + return 0; +} + +static int codegen_CMP_IMM_JNZ_DEST(codeblock_t *block, uop_t *uop) { + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (!in_range12_w((uintptr_t)&cr0 - (uintptr_t)&cpu_state)) - fatal("codegen_FP_ENTER - out of range\n"); - - host_arm64_LDR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cr0 - (uintptr_t)&cpu_state); - host_arm64_TST_IMM(block, REG_TEMP, 0xc); - branch_ptr = host_arm64_BEQ_(block); + if (REG_IS_L(src_size)) { + host_arm64_CMP_IMM(block, src_reg, uop->imm_data); + } else if (REG_IS_W(src_size)) { + host_arm64_AND_IMM(block, REG_TEMP, src_reg, 0xffff); + host_arm64_CMP_IMM(block, REG_TEMP, uop->imm_data); + } else + fatal("CMP_IMM_JNZ_DEST %02x\n", uop->src_reg_a_real); - host_arm64_mov_imm(block, REG_TEMP, uop->imm_data); - host_arm64_STR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.oldpc - (uintptr_t)&cpu_state); - host_arm64_mov_imm(block, REG_ARG0, 7); - host_arm64_call(block, x86_int); - host_arm64_B(block, codegen_exit_rout); + uop->p = host_arm64_BNE_(block); - host_arm64_branch_set_offset(branch_ptr, &block_write_data[block_pos]); + return 0; +} +static int codegen_CMP_IMM_JZ_DEST(codeblock_t *block, uop_t *uop) { + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(src_size)) { + host_arm64_CMP_IMM(block, src_reg, uop->imm_data); + } else if (REG_IS_W(src_size)) { + host_arm64_AND_IMM(block, REG_TEMP, src_reg, 0xffff); + host_arm64_CMP_IMM(block, REG_TEMP, uop->imm_data); + } else + fatal("CMP_IMM_JZ_DEST %02x\n", uop->src_reg_a_real); - return 0; + uop->p = host_arm64_BEQ_(block); + + return 0; } -static int codegen_MMX_ENTER(codeblock_t *block, uop_t *uop) -{ - uint32_t *branch_ptr; - if (!in_range12_w((uintptr_t)&cr0 - (uintptr_t)&cpu_state)) - fatal("codegen_MMX_ENTER - out of range\n"); +static int codegen_CMP_JB(codeblock_t *block, uop_t *uop) { + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + uint32_t *jump_p; + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_CMP_REG(block, src_reg_a, src_reg_b); + } else + fatal("CMP_JB %02x\n", uop->src_reg_a_real); - host_arm64_LDR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cr0 - (uintptr_t)&cpu_state); - host_arm64_TST_IMM(block, REG_TEMP, 0xc); - branch_ptr = host_arm64_BEQ_(block); + jump_p = host_arm64_BCC_(block); + host_arm64_branch_set_offset(jump_p, uop->p); - host_arm64_mov_imm(block, REG_TEMP, uop->imm_data); - host_arm64_STR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.oldpc - (uintptr_t)&cpu_state); - host_arm64_mov_imm(block, REG_ARG0, 7); - host_arm64_call(block, x86_int); - host_arm64_B(block, codegen_exit_rout); + return 0; +} +static int codegen_CMP_JNBE(codeblock_t *block, uop_t *uop) { + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + uint32_t *jump_p; + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_CMP_REG(block, src_reg_a, src_reg_b); + } else + fatal("CMP_JNBE %02x\n", uop->src_reg_a_real); - host_arm64_branch_set_offset(branch_ptr, &block->data[block_pos]); + jump_p = host_arm64_BHI_(block); + host_arm64_branch_set_offset(jump_p, uop->p); + + return 0; +} + +static int codegen_CMP_JNB_DEST(codeblock_t *block, uop_t *uop) { + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JNB_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm64_BCS_(block); + + return 0; +} +static int codegen_CMP_JNBE_DEST(codeblock_t *block, uop_t *uop) { + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JNBE_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm64_BHI_(block); + + return 0; +} +static int codegen_CMP_JNL_DEST(codeblock_t *block, uop_t *uop) { + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JNL_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm64_BGE_(block); + + return 0; +} +static int codegen_CMP_JNLE_DEST(codeblock_t *block, uop_t *uop) { + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JNLE_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm64_BGT_(block); + + return 0; +} +static int codegen_CMP_JNO_DEST(codeblock_t *block, uop_t *uop) { + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JNO_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm64_BVC_(block); + + return 0; +} +static int codegen_CMP_JNZ_DEST(codeblock_t *block, uop_t *uop) { + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JNZ_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm64_BNE_(block); + + return 0; +} +static int codegen_CMP_JB_DEST(codeblock_t *block, uop_t *uop) { + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JB_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm64_BCC_(block); + + return 0; +} +static int codegen_CMP_JBE_DEST(codeblock_t *block, uop_t *uop) { + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JBE_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm64_BLS_(block); + + return 0; +} +static int codegen_CMP_JL_DEST(codeblock_t *block, uop_t *uop) { + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JL_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm64_BLT_(block); + + return 0; +} +static int codegen_CMP_JLE_DEST(codeblock_t *block, uop_t *uop) { + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JLE_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm64_BLE_(block); + + return 0; +} +static int codegen_CMP_JO_DEST(codeblock_t *block, uop_t *uop) { + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JO_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm64_BVS_(block); + + return 0; +} +static int codegen_CMP_JZ_DEST(codeblock_t *block, uop_t *uop) { + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JZ_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm64_BEQ_(block); + + return 0; +} + +static int codegen_FABS(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) { + host_arm64_FABS_D(block, dest_reg, src_reg_a); + } else + fatal("codegen_FABS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_FCHS(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) { + host_arm64_FNEG_D(block, dest_reg, src_reg_a); + } else + fatal("codegen_FCHS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_FSQRT(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) { + host_arm64_FSQRT_D(block, dest_reg, src_reg_a); + } else + fatal("codegen_FSQRT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_FTST(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_W(dest_size) && REG_IS_D(src_size_a)) { + host_arm64_FSUB_D(block, REG_V_TEMP, REG_V_TEMP, REG_V_TEMP); + host_arm64_MOVZ_IMM(block, dest_reg, 0); + host_arm64_FCMP_D(block, src_reg_a, REG_V_TEMP); + host_arm64_ORR_IMM(block, REG_TEMP, dest_reg, C3); + host_arm64_ORR_IMM(block, REG_TEMP2, dest_reg, C0); + host_arm64_CSEL_EQ(block, dest_reg, REG_TEMP, dest_reg); + host_arm64_ORR_IMM(block, REG_TEMP, dest_reg, C0 | C2 | C3); + host_arm64_CSEL_CC(block, dest_reg, REG_TEMP2, dest_reg); + host_arm64_CSEL_VS(block, dest_reg, REG_TEMP, dest_reg); + } else + fatal("codegen_FTST %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + +static int codegen_FADD(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { + host_arm64_FADD_D(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("codegen_FADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_FCOM(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_W(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { + host_arm64_MOVZ_IMM(block, dest_reg, 0); + host_arm64_FCMP_D(block, src_reg_a, src_reg_b); + host_arm64_ORR_IMM(block, REG_TEMP, dest_reg, C3); + host_arm64_ORR_IMM(block, REG_TEMP2, dest_reg, C0); + host_arm64_CSEL_EQ(block, dest_reg, REG_TEMP, dest_reg); + host_arm64_ORR_IMM(block, REG_TEMP, dest_reg, C0 | C2 | C3); + host_arm64_CSEL_CC(block, dest_reg, REG_TEMP2, dest_reg); + host_arm64_CSEL_VS(block, dest_reg, REG_TEMP, dest_reg); + } else + fatal("codegen_FCOM %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_FDIV(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - host_arm64_mov_imm(block, REG_TEMP, 0x01010101); - host_arm64_STR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.tag[0] - (uintptr_t)&cpu_state); - host_arm64_STR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.tag[4] - (uintptr_t)&cpu_state); - host_arm64_STR_IMM_W(block, REG_WZR, REG_CPUSTATE, (uintptr_t)&cpu_state.TOP - (uintptr_t)&cpu_state); - host_arm64_STRB_IMM(block, REG_WZR, REG_CPUSTATE, (uintptr_t)&cpu_state.ismmx - (uintptr_t)&cpu_state); + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { + host_arm64_FDIV_D(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("codegen_FDIV %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; } +static int codegen_FMUL(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); -static int codegen_JMP(codeblock_t *block, uop_t *uop) -{ - host_arm64_jump(block, (uintptr_t)uop->p); + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { + host_arm64_FMUL_D(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("codegen_FMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; } +static int codegen_FSUB(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { + host_arm64_FSUB_D(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("codegen_FSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + +static int codegen_FP_ENTER(codeblock_t *block, uop_t *uop) { + uint32_t *branch_ptr; + + if (!in_range12_w((uintptr_t)&cr0 - (uintptr_t)&cpu_state)) + fatal("codegen_FP_ENTER - out of range\n"); + + host_arm64_LDR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cr0 - (uintptr_t)&cpu_state); + host_arm64_TST_IMM(block, REG_TEMP, 0xc); + branch_ptr = host_arm64_BEQ_(block); + + host_arm64_mov_imm(block, REG_TEMP, uop->imm_data); + host_arm64_STR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.oldpc - (uintptr_t)&cpu_state); + host_arm64_mov_imm(block, REG_ARG0, 7); + host_arm64_call(block, x86_int); + host_arm64_B(block, codegen_exit_rout); + + host_arm64_branch_set_offset(branch_ptr, &block_write_data[block_pos]); + + return 0; +} +static int codegen_MMX_ENTER(codeblock_t *block, uop_t *uop) { + uint32_t *branch_ptr; + + if (!in_range12_w((uintptr_t)&cr0 - (uintptr_t)&cpu_state)) + fatal("codegen_MMX_ENTER - out of range\n"); + + host_arm64_LDR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cr0 - (uintptr_t)&cpu_state); + host_arm64_TST_IMM(block, REG_TEMP, 0xc); + branch_ptr = host_arm64_BEQ_(block); + + host_arm64_mov_imm(block, REG_TEMP, uop->imm_data); + host_arm64_STR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.oldpc - (uintptr_t)&cpu_state); + host_arm64_mov_imm(block, REG_ARG0, 7); + host_arm64_call(block, x86_int); + host_arm64_B(block, codegen_exit_rout); + + host_arm64_branch_set_offset(branch_ptr, &block->data[block_pos]); -static int codegen_LOAD_FUNC_ARG0(codeblock_t *block, uop_t *uop) -{ - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_W(src_size)) - { - host_arm64_AND_IMM(block, REG_ARG0, src_reg, 0xffff); - } - else - fatal("codegen_LOAD_FUNC_ARG0 %02x\n", uop->src_reg_a_real); + host_arm64_mov_imm(block, REG_TEMP, 0x01010101); + host_arm64_STR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.tag[0] - (uintptr_t)&cpu_state); + host_arm64_STR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.tag[4] - (uintptr_t)&cpu_state); + host_arm64_STR_IMM_W(block, REG_WZR, REG_CPUSTATE, (uintptr_t)&cpu_state.TOP - (uintptr_t)&cpu_state); + host_arm64_STRB_IMM(block, REG_WZR, REG_CPUSTATE, (uintptr_t)&cpu_state.ismmx - (uintptr_t)&cpu_state); - return 0; -} -static int codegen_LOAD_FUNC_ARG1(codeblock_t *block, uop_t *uop) -{ - fatal("codegen_LOAD_FUNC_ARG1 %02x\n", uop->src_reg_a_real); - return 0; -} -static int codegen_LOAD_FUNC_ARG2(codeblock_t *block, uop_t *uop) -{ - fatal("codegen_LOAD_FUNC_ARG2 %02x\n", uop->src_reg_a_real); - return 0; -} -static int codegen_LOAD_FUNC_ARG3(codeblock_t *block, uop_t *uop) -{ - fatal("codegen_LOAD_FUNC_ARG3 %02x\n", uop->src_reg_a_real); - return 0; -} - -static int codegen_LOAD_FUNC_ARG0_IMM(codeblock_t *block, uop_t *uop) -{ - host_arm64_mov_imm(block, REG_ARG0, uop->imm_data); - - return 0; -} -static int codegen_LOAD_FUNC_ARG1_IMM(codeblock_t *block, uop_t *uop) -{ - host_arm64_mov_imm(block, REG_ARG1, uop->imm_data); - - return 0; -} -static int codegen_LOAD_FUNC_ARG2_IMM(codeblock_t *block, uop_t *uop) -{ - host_arm64_mov_imm(block, REG_ARG2, uop->imm_data); - - return 0; -} -static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop) -{ - host_arm64_mov_imm(block, REG_ARG3, uop->imm_data); - - return 0; -} - -static int codegen_LOAD_SEG(codeblock_t *block, uop_t *uop) -{ - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (!REG_IS_W(src_size)) - fatal("LOAD_SEG %02x %p\n", uop->src_reg_a_real, uop->p); - - host_arm64_MOVX_IMM(block, REG_ARG1, (uint64_t)uop->p); - host_arm64_AND_IMM(block, REG_ARG0, src_reg, 0xffff); - host_arm64_call(block, (void *)loadseg); - host_arm64_CBNZ(block, REG_X0, (uintptr_t)codegen_exit_rout); - - return 0; -} - -static int codegen_MEM_LOAD_ABS(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - host_arm64_ADD_IMM(block, REG_X0, seg_reg, uop->imm_data); - if (REG_IS_B(dest_size) || REG_IS_BH(dest_size)) - { - host_arm64_call(block, codegen_mem_load_byte); - } - else if (REG_IS_W(dest_size)) - { - host_arm64_call(block, codegen_mem_load_word); - } - else if (REG_IS_L(dest_size)) - { - host_arm64_call(block, codegen_mem_load_long); - } - else - fatal("MEM_LOAD_ABS - %02x\n", uop->dest_reg_a_real); - host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout); - if (REG_IS_B(dest_size)) - { - host_arm64_BFI(block, dest_reg, REG_X0, 0, 8); - } - else if (REG_IS_BH(dest_size)) - { - host_arm64_BFI(block, dest_reg, REG_X0, 8, 8); - } - else if (REG_IS_W(dest_size)) - { - host_arm64_BFI(block, dest_reg, REG_X0, 0, 16); - } - else if (REG_IS_L(dest_size)) - { - host_arm64_MOV_REG(block, dest_reg, REG_X0, 0); - } - - return 0; -} -static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - host_arm64_ADD_REG(block, REG_X0, seg_reg, addr_reg, 0); - if (uop->imm_data) - host_arm64_ADD_IMM(block, REG_X0, REG_X0, uop->imm_data); - if (REG_IS_B(dest_size) || REG_IS_BH(dest_size)) - { - host_arm64_call(block, codegen_mem_load_byte); - } - else if (REG_IS_W(dest_size)) - { - host_arm64_call(block, codegen_mem_load_word); - } - else if (REG_IS_L(dest_size)) - { - host_arm64_call(block, codegen_mem_load_long); - } - else if (REG_IS_Q(dest_size)) - { - host_arm64_call(block, codegen_mem_load_quad); - } - else - fatal("MEM_LOAD_REG - %02x\n", uop->dest_reg_a_real); - host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout); - if (REG_IS_B(dest_size)) - { - host_arm64_BFI(block, dest_reg, REG_X0, 0, 8); - } - else if (REG_IS_BH(dest_size)) - { - host_arm64_BFI(block, dest_reg, REG_X0, 8, 8); - } - else if (REG_IS_W(dest_size)) - { - host_arm64_BFI(block, dest_reg, REG_X0, 0, 16); - } - else if (REG_IS_L(dest_size)) - { - host_arm64_MOV_REG(block, dest_reg, REG_X0, 0); - } - else if (REG_IS_Q(dest_size)) - { - host_arm64_FMOV_D_D(block, dest_reg, REG_V_TEMP); - } - - return 0; -} -static int codegen_MEM_LOAD_DOUBLE(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (!REG_IS_D(dest_size)) - fatal("MEM_LOAD_DOUBLE - %02x\n", uop->dest_reg_a_real); - - host_arm64_ADD_REG(block, REG_X0, seg_reg, addr_reg, 0); - if (uop->imm_data) - host_arm64_ADD_IMM(block, REG_X0, REG_X0, uop->imm_data); - host_arm64_call(block, codegen_mem_load_double); - host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout); - host_arm64_FMOV_D_D(block, dest_reg, REG_V_TEMP); - - return 0; -} -static int codegen_MEM_LOAD_SINGLE(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (!REG_IS_D(dest_size)) - fatal("MEM_LOAD_DOUBLE - %02x\n", uop->dest_reg_a_real); - - host_arm64_ADD_REG(block, REG_X0, seg_reg, addr_reg, 0); - if (uop->imm_data) - host_arm64_ADD_IMM(block, REG_X0, REG_X0, uop->imm_data); - host_arm64_call(block, codegen_mem_load_single); - host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout); - host_arm64_FCVT_D_S(block, dest_reg, REG_V_TEMP); - - return 0; -} - -static int codegen_MEM_STORE_ABS(codeblock_t *block, uop_t *uop) -{ - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_b_real); - int src_size = IREG_GET_SIZE(uop->src_reg_b_real); - - host_arm64_ADD_IMM(block, REG_W0, seg_reg, uop->imm_data); - if (REG_IS_B(src_size)) - { - host_arm64_AND_IMM(block, REG_W1, src_reg, 0xff); - host_arm64_call(block, codegen_mem_store_byte); - } - else if (REG_IS_BH(src_size)) - { - host_arm64_UBFX(block, REG_W1, src_reg, 8, 8); - host_arm64_call(block, codegen_mem_store_byte); - } - else if (REG_IS_W(src_size)) - { - host_arm64_AND_IMM(block, REG_W1, src_reg, 0xffff); - host_arm64_call(block, codegen_mem_store_word); - } - else if (REG_IS_L(src_size)) - { - host_arm64_MOV_REG(block, REG_W1, src_reg, 0); - host_arm64_call(block, codegen_mem_store_long); - } - else - fatal("MEM_STORE_ABS - %02x\n", uop->dest_reg_a_real); - host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout); - - return 0; -} -static int codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop) -{ - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); - int src_size = IREG_GET_SIZE(uop->src_reg_c_real); - - host_arm64_ADD_REG(block, REG_W0, seg_reg, addr_reg, 0); - if (uop->imm_data) - host_arm64_ADD_IMM(block, REG_X0, REG_X0, uop->imm_data); - if (REG_IS_B(src_size)) - { - host_arm64_AND_IMM(block, REG_W1, src_reg, 0xff); - host_arm64_call(block, codegen_mem_store_byte); - } - else if (REG_IS_BH(src_size)) - { - host_arm64_UBFX(block, REG_W1, src_reg, 8, 8); - host_arm64_call(block, codegen_mem_store_byte); - } - else if (REG_IS_W(src_size)) - { - host_arm64_AND_IMM(block, REG_W1, src_reg, 0xffff); - host_arm64_call(block, codegen_mem_store_word); - } - else if (REG_IS_L(src_size)) - { - host_arm64_MOV_REG(block, REG_W1, src_reg, 0); - host_arm64_call(block, codegen_mem_store_long); - } - else if (REG_IS_Q(src_size)) - { - host_arm64_FMOV_D_D(block, REG_V_TEMP, src_reg); - host_arm64_call(block, codegen_mem_store_quad); - } - else - fatal("MEM_STORE_REG - %02x\n", uop->src_reg_c_real); - host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout); - - return 0; -} - -static int codegen_MEM_STORE_IMM_8(codeblock_t *block, uop_t *uop) -{ - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - - host_arm64_ADD_REG(block, REG_W0, seg_reg, addr_reg, 0); - host_arm64_mov_imm(block, REG_W1, uop->imm_data); - host_arm64_call(block, codegen_mem_store_byte); - host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout); - - return 0; -} -static int codegen_MEM_STORE_IMM_16(codeblock_t *block, uop_t *uop) -{ - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - - host_arm64_ADD_REG(block, REG_W0, seg_reg, addr_reg, 0); - host_arm64_mov_imm(block, REG_W1, uop->imm_data); - host_arm64_call(block, codegen_mem_store_word); - host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout); - - return 0; -} -static int codegen_MEM_STORE_IMM_32(codeblock_t *block, uop_t *uop) -{ - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - - host_arm64_ADD_REG(block, REG_W0, seg_reg, addr_reg, 0); - host_arm64_mov_imm(block, REG_W1, uop->imm_data); - host_arm64_call(block, codegen_mem_store_long); - host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout); - - return 0; -} - -static int codegen_MEM_STORE_SINGLE(codeblock_t *block, uop_t *uop) -{ - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); - int src_size = IREG_GET_SIZE(uop->src_reg_c_real); - - if (!REG_IS_D(src_size)) - fatal("MEM_STORE_REG - %02x\n", uop->dest_reg_a_real); - - host_arm64_ADD_REG(block, REG_W0, seg_reg, addr_reg, 0); - if (uop->imm_data) - host_arm64_ADD_IMM(block, REG_X0, REG_X0, uop->imm_data); - host_arm64_FCVT_S_D(block, REG_V_TEMP, src_reg); - host_arm64_call(block, codegen_mem_store_single); - host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout); - - return 0; -} -static int codegen_MEM_STORE_DOUBLE(codeblock_t *block, uop_t *uop) -{ - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); - int src_size = IREG_GET_SIZE(uop->src_reg_c_real); - - if (!REG_IS_D(src_size)) - fatal("MEM_STORE_REG - %02x\n", uop->dest_reg_a_real); - - host_arm64_ADD_REG(block, REG_W0, seg_reg, addr_reg, 0); - if (uop->imm_data) - host_arm64_ADD_IMM(block, REG_X0, REG_X0, uop->imm_data); - host_arm64_FMOV_D_D(block, REG_V_TEMP, src_reg); - host_arm64_call(block, codegen_mem_store_double); - host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout); - - return 0; -} - -static int codegen_MOV(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm64_MOV_REG(block, dest_reg, src_reg, 0); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm64_BFI(block, dest_reg, src_reg, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm64_BFI(block, dest_reg, src_reg, 0, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_MOV_REG_LSR(block, REG_TEMP, src_reg, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_B(src_size)) - { - host_arm64_BFI(block, dest_reg, src_reg, 8, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_MOV_REG_LSR(block, REG_TEMP, src_reg, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else if (REG_IS_D(dest_size) && REG_IS_D(src_size)) - { - host_arm64_FMOV_D_D(block, dest_reg, src_reg); - } - else if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - host_arm64_FMOV_D_D(block, dest_reg, src_reg); - } - else - fatal("MOV %x %x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_MOV_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_L(dest_size)) - { - host_arm64_mov_imm(block, dest_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size)) - { - host_arm64_MOVK_IMM(block, dest_reg, uop->imm_data & 0xffff); - } - else if (REG_IS_B(dest_size)) - { - host_arm64_MOVZ_IMM(block, REG_TEMP, uop->imm_data & 0xff); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size)) - { - host_arm64_MOVZ_IMM(block, REG_TEMP, uop->imm_data & 0xff); - host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("MOV_IMM %x\n", uop->dest_reg_a_real); - - return 0; -} -static int codegen_MOV_PTR(codeblock_t *block, uop_t *uop) -{ - host_arm64_MOVX_IMM(block, uop->dest_reg_a_real, (uint64_t)uop->p); - - return 0; -} - -static int codegen_MOVSX(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_B(src_size)) - { - host_arm64_SBFX(block, dest_reg, src_reg, 0, 8); - } - else if (REG_IS_L(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_SBFX(block, dest_reg, src_reg, 8, 8); - } - else if (REG_IS_L(dest_size) && REG_IS_W(src_size)) - { - host_arm64_SBFX(block, dest_reg, src_reg, 0, 16); - } - else if (REG_IS_W(dest_size) && REG_IS_B(src_size)) - { - host_arm64_SBFX(block, REG_TEMP, src_reg, 0, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_W(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_SBFX(block, REG_TEMP, src_reg, 8, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else - fatal("MOVSX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_MOVZX(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_L(src_size)) - { - host_arm64_FMOV_D_Q(block, dest_reg, src_reg); - } - else if (REG_IS_L(dest_size) && REG_IS_Q(src_size)) - { - host_arm64_FMOV_W_S(block, dest_reg, src_reg); - } - else if (REG_IS_L(dest_size) && REG_IS_B(src_size)) - { - host_arm64_AND_IMM(block, dest_reg, src_reg, 0xff); - } - else if (REG_IS_L(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_UBFX(block, dest_reg, src_reg, 8, 8); - } - else if (REG_IS_L(dest_size) && REG_IS_W(src_size)) - { - host_arm64_AND_IMM(block, dest_reg, src_reg, 0xffff); - } - else if (REG_IS_W(dest_size) && REG_IS_B(src_size)) - { - host_arm64_AND_IMM(block, REG_TEMP, src_reg, 0xff); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_W(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else - fatal("MOVZX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} - -static int codegen_MOV_DOUBLE_INT(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_D(dest_size) && REG_IS_L(src_size)) - { - host_arm64_SCVTF_D_W(block, dest_reg, src_reg); - } - else if (REG_IS_D(dest_size) && REG_IS_W(src_size)) - { - host_arm64_SBFX(block, REG_TEMP, src_reg, 0, 16); - host_arm64_SCVTF_D_W(block, dest_reg, REG_TEMP); - } - else if (REG_IS_D(dest_size) && REG_IS_Q(src_size)) - { - host_arm64_FMOV_Q_D(block, REG_TEMP, src_reg); - host_arm64_SCVTF_D_Q(block, dest_reg, REG_TEMP); - } - else - fatal("MOV_DOUBLE_INT %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_MOV_INT_DOUBLE(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_D(src_size)) - { - host_arm64_FMOV_D_D(block, REG_V_TEMP, src_reg); - host_arm64_call(block, codegen_fp_round); - host_arm64_MOV_REG(block, dest_reg, REG_TEMP, 0); - } - else if (REG_IS_W(dest_size) && REG_IS_D(src_size)) - { - host_arm64_FMOV_D_D(block, REG_V_TEMP, src_reg); - host_arm64_call(block, codegen_fp_round); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else - fatal("MOV_INT_DOUBLE %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_MOV_INT_DOUBLE_64(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), src_64_reg = HOST_REG_GET(uop->src_reg_b_real), tag_reg = HOST_REG_GET(uop->src_reg_c_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real), src_64_size = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_D(src_size) && REG_IS_Q(src_64_size)) - { - uint32_t *branch_offset; - - /*If TAG_UINT64 is set then the source is MM[]. Otherwise it is a double in ST()*/ - host_arm64_FMOV_D_D(block, dest_reg, src_64_reg); - branch_offset = host_arm64_TBNZ(block, tag_reg, 7); - - host_arm64_FMOV_D_D(block, REG_V_TEMP, src_reg); - host_arm64_call(block, codegen_fp_round_quad); - host_arm64_FMOV_D_Q(block, dest_reg, REG_TEMP); - - host_arm64_branch_set_offset(branch_offset, &block_write_data[block_pos]); - } - else - fatal("MOV_INT_DOUBLE_64 %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_MOV_REG_PTR(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - host_arm64_MOVX_IMM(block, REG_TEMP, (uint64_t)uop->p); - if (REG_IS_L(dest_size)) - { - host_arm64_LDR_IMM_W(block, dest_reg, REG_TEMP, 0); - } - else - fatal("MOV_REG_PTR %02x\n", uop->dest_reg_a_real); - - return 0; -} -static int codegen_MOVZX_REG_PTR_8(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - host_arm64_MOVX_IMM(block, REG_TEMP, (uint64_t)uop->p); - if (REG_IS_L(dest_size)) - { - host_arm64_LDRB_IMM_W(block, dest_reg, REG_TEMP, 0); - } - else if (REG_IS_W(dest_size)) - { - host_arm64_LDRB_IMM_W(block, REG_TEMP, REG_TEMP, 0); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size)) - { - host_arm64_LDRB_IMM_W(block, REG_TEMP, REG_TEMP, 0); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else - fatal("MOVZX_REG_PTR_8 %02x\n", uop->dest_reg_a_real); - - return 0; -} -static int codegen_MOVZX_REG_PTR_16(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - host_arm64_MOVX_IMM(block, REG_TEMP, (uint64_t)uop->p); - if (REG_IS_L(dest_size)) - { - host_arm64_LDRH_IMM(block, dest_reg, REG_TEMP, 0); - } - else if (REG_IS_W(dest_size)) - { - host_arm64_LDRH_IMM(block, REG_TEMP, REG_TEMP, 0); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else - fatal("MOVZX_REG_PTR_16 %02x\n", uop->dest_reg_a_real); - - return 0; -} - -static int codegen_NOP(codeblock_t *block, uop_t *uop) -{ - return 0; -} - -static int codegen_OR(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_ORR_REG_V(block, dest_reg, src_reg_a, src_reg_b); - } - else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_ORR_REG(block, dest_reg, src_reg_a, src_reg_b, 0); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm64_ORR_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) - { - host_arm64_AND_IMM(block, REG_TEMP, src_reg_b, 0xff); - host_arm64_ORR_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) - { - host_arm64_UBFX(block, REG_TEMP, src_reg_b, 8, 8); - host_arm64_ORR_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) - { - host_arm64_AND_IMM(block, REG_TEMP, src_reg_b, 0xff); - host_arm64_ORR_REG(block, dest_reg, src_reg_a, REG_TEMP, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) - { - host_arm64_UBFX(block, REG_TEMP, src_reg_b, 8, 8); - host_arm64_ORR_REG(block, dest_reg, src_reg_a, REG_TEMP, 8); - } - else - fatal("OR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_OR_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm64_ORR_IMM(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size) && dest_reg == src_reg) - { - host_arm64_ORR_IMM(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size) && dest_reg == src_reg) - { - host_arm64_ORR_IMM(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size) && dest_reg == src_reg) - { - host_arm64_ORR_IMM(block, dest_reg, src_reg, uop->imm_data << 8); - } - else - fatal("OR_IMM %x %x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} - -static int codegen_PACKSSWB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_arm64_SQXTN_V8B_8H(block, REG_V_TEMP, src_reg_b); - host_arm64_SQXTN_V8B_8H(block, dest_reg, dest_reg); - host_arm64_ZIP1_V2S(block, dest_reg, dest_reg, REG_V_TEMP); - } - else - fatal("PACKSSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PACKSSDW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_arm64_SQXTN_V4H_4S(block, REG_V_TEMP, src_reg_b); - host_arm64_SQXTN_V4H_4S(block, dest_reg, dest_reg); - host_arm64_ZIP1_V2S(block, dest_reg, dest_reg, REG_V_TEMP); - } - else - fatal("PACKSSDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PACKUSWB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_arm64_UQXTN_V8B_8H(block, REG_V_TEMP, src_reg_b); - host_arm64_UQXTN_V8B_8H(block, dest_reg, dest_reg); - host_arm64_ZIP1_V2S(block, dest_reg, dest_reg, REG_V_TEMP); - } - else - fatal("PACKUSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} - -static int codegen_PADDB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_ADD_V8B(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PADDB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PADDW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_ADD_V4H(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PADDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PADDD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_ADD_V2S(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PADDD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PADDSB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_SQADD_V8B(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PADDSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PADDSW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_SQADD_V4H(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PADDSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PADDUSB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_UQADD_V8B(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PADDUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PADDUSW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_UQADD_V4H(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PADDUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} - -static int codegen_PCMPEQB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_CMEQ_V8B(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PCMPEQB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PCMPEQW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_CMEQ_V4H(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PCMPEQW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PCMPEQD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_CMEQ_V2S(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PCMPEQD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PCMPGTB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_CMGT_V8B(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PCMPGTB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PCMPGTW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_CMGT_V4H(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PCMPGTW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PCMPGTD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_CMGT_V2S(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PCMPGTD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} - -static int codegen_PF2ID(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) - { - host_arm64_FCVTZS_V2S(block, dest_reg, src_reg_a); - } - else - fatal("PF2ID %02x %02x\n", uop->dest_reg_a_real); - - return 0; -} -static int codegen_PFADD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_FADD_V2S(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PFADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PFCMPEQ(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_FCMEQ_V2S(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PFCMPEQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PFCMPGE(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_FCMGE_V2S(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PFCMPGE %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PFCMPGT(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_FCMGT_V2S(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PFCMPGT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PFMAX(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_FMAX_V2S(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PFMAX %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PFMIN(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_FMIN_V2S(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PFMIN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PFMUL(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_FMUL_V2S(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PFMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PFRCP(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) - { - /*TODO: This could be improved (use VRECPE/VRECPS)*/ - host_arm64_FMOV_S_ONE(block, REG_V_TEMP); - host_arm64_FDIV_S(block, dest_reg, REG_V_TEMP, src_reg_a); - host_arm64_DUP_V2S(block, dest_reg, dest_reg, 0); - } - else - fatal("PFRCP %02x %02x\n", uop->dest_reg_a_real); - - return 0; -} -static int codegen_PFRSQRT(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) - { - /*TODO: This could be improved (use VRSQRTE/VRSQRTS)*/ - host_arm64_FSQRT_S(block, REG_V_TEMP, src_reg_a); - host_arm64_FMOV_S_ONE(block, REG_V_TEMP); - host_arm64_FDIV_S(block, dest_reg, dest_reg, REG_V_TEMP); - host_arm64_DUP_V2S(block, dest_reg, dest_reg, 0); - } - else - fatal("PFRSQRT %02x %02x\n", uop->dest_reg_a_real); - - return 0; -} -static int codegen_PFSUB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_FSUB_V2S(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PFSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PI2FD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) - { - host_arm64_SCVTF_V2S(block, dest_reg, src_reg_a); - } - else - fatal("PI2FD %02x %02x\n", uop->dest_reg_a_real); - - return 0; -} - -static int codegen_PMADDWD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_SMULL_V4S_4H(block, REG_V_TEMP, src_reg_a, src_reg_b); - host_arm64_ADDP_V4S(block, dest_reg, REG_V_TEMP, REG_V_TEMP); - } - else - fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PMULHW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_SMULL_V4S_4H(block, dest_reg, src_reg_a, src_reg_b); - host_arm64_SHRN_V4H_4S(block, dest_reg, dest_reg, 16); - } - else - fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PMULLW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_MUL_V4H(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PMULLW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} - -static int codegen_PSLLW_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - if (uop->imm_data == 0) - host_arm64_FMOV_D_D(block, dest_reg, src_reg); - else if (uop->imm_data > 15) - host_arm64_EOR_REG_V(block, dest_reg, dest_reg, dest_reg); - else - host_arm64_SHL_V4H(block, dest_reg, src_reg, uop->imm_data); - } - else - fatal("PSLLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_PSLLD_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - if (uop->imm_data == 0) - host_arm64_FMOV_D_D(block, dest_reg, src_reg); - else if (uop->imm_data > 31) - host_arm64_EOR_REG_V(block, dest_reg, dest_reg, dest_reg); - else - host_arm64_SHL_V2S(block, dest_reg, src_reg, uop->imm_data); - } - else - fatal("PSLLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_PSLLQ_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - if (uop->imm_data == 0) - host_arm64_FMOV_D_D(block, dest_reg, src_reg); - else if (uop->imm_data > 63) - host_arm64_EOR_REG_V(block, dest_reg, dest_reg, dest_reg); - else - host_arm64_SHL_V2D(block, dest_reg, src_reg, uop->imm_data); - } - else - fatal("PSLLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_PSRAW_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - if (uop->imm_data == 0) - host_arm64_FMOV_D_D(block, dest_reg, src_reg); - else if (uop->imm_data > 15) - host_arm64_SSHR_V4H(block, dest_reg, src_reg, 15); - else - host_arm64_SSHR_V4H(block, dest_reg, src_reg, uop->imm_data); - } - else - fatal("PSRAW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_PSRAD_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - if (uop->imm_data == 0) - host_arm64_FMOV_D_D(block, dest_reg, src_reg); - else if (uop->imm_data > 31) - host_arm64_SSHR_V2S(block, dest_reg, src_reg, 31); - else - host_arm64_SSHR_V2S(block, dest_reg, src_reg, uop->imm_data); - } - else - fatal("PSRAD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_PSRAQ_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - if (uop->imm_data == 0) - host_arm64_FMOV_D_D(block, dest_reg, src_reg); - else if (uop->imm_data > 63) - host_arm64_SSHR_V2D(block, dest_reg, src_reg, 63); - else - host_arm64_SSHR_V2D(block, dest_reg, src_reg, uop->imm_data); - } - else - fatal("PSRAQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_PSRLW_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - if (uop->imm_data == 0) - host_arm64_FMOV_D_D(block, dest_reg, src_reg); - else if (uop->imm_data > 15) - host_arm64_EOR_REG_V(block, dest_reg, dest_reg, dest_reg); - else - host_arm64_USHR_V4H(block, dest_reg, src_reg, uop->imm_data); - } - else - fatal("PSRLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_PSRLD_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - if (uop->imm_data == 0) - host_arm64_FMOV_D_D(block, dest_reg, src_reg); - else if (uop->imm_data > 31) - host_arm64_EOR_REG_V(block, dest_reg, dest_reg, dest_reg); - else - host_arm64_USHR_V2S(block, dest_reg, src_reg, uop->imm_data); - } - else - fatal("PSRLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_PSRLQ_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - if (uop->imm_data == 0) - host_arm64_FMOV_D_D(block, dest_reg, src_reg); - else if (uop->imm_data > 63) - host_arm64_EOR_REG_V(block, dest_reg, dest_reg, dest_reg); - else - host_arm64_USHR_V2D(block, dest_reg, src_reg, uop->imm_data); - } - else - fatal("PSRLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} - -static int codegen_PSUBB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_SUB_V8B(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PSUBB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PSUBW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_SUB_V4H(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PSUBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PSUBD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_SUB_V2S(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PSUBD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PSUBSB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_SQSUB_V8B(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PSUBSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PSUBSW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_SQSUB_V4H(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PSUBSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PSUBUSB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_UQSUB_V8B(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PSUBUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PSUBUSW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_UQSUB_V4H(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PSUBUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} - -static int codegen_PUNPCKHBW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_ZIP2_V8B(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PUNPCKHBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PUNPCKHWD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_ZIP2_V4H(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PUNPCKHWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PUNPCKHDQ(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_ZIP2_V2S(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PUNPCKHDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PUNPCKLBW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_ZIP1_V8B(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PUNPCKLBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PUNPCKLWD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_ZIP1_V4H(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PUNPCKLWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PUNPCKLDQ(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_ZIP1_V2S(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PUNPCKLDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} - -static int codegen_ROL(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm64_mov_imm(block, REG_TEMP2, 32); - host_arm64_SUB_REG(block, REG_TEMP2, REG_TEMP2, shift_reg, 0); - host_arm64_ROR(block, dest_reg, src_reg, REG_TEMP2); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm64_mov_imm(block, REG_TEMP2, 16); - host_arm64_UBFX(block, REG_TEMP, src_reg, 0, 16); - host_arm64_SUB_REG(block, REG_TEMP2, REG_TEMP2, shift_reg, 0); - host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 16); - host_arm64_ROR(block, REG_TEMP, REG_TEMP, REG_TEMP2); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - cs = cs; - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm64_mov_imm(block, REG_TEMP2, 8); - host_arm64_SUB_REG(block, REG_TEMP2, REG_TEMP2, shift_reg, 0); - host_arm64_UBFX(block, REG_TEMP, src_reg, 0, 8); - host_arm64_AND_IMM(block, REG_TEMP2, REG_TEMP2, 7); - host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); - host_arm64_LSR(block, REG_TEMP, REG_TEMP, REG_TEMP2); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_mov_imm(block, REG_TEMP2, 8); - host_arm64_SUB_REG(block, REG_TEMP2, REG_TEMP2, shift_reg, 0); - host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); - host_arm64_AND_IMM(block, REG_TEMP2, REG_TEMP2, 7); - host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); - host_arm64_LSR(block, REG_TEMP, REG_TEMP, REG_TEMP2); - host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("ROL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_ROL_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (!(uop->imm_data & 31)) - { - if (src_reg != dest_reg) - host_arm64_MOV_REG(block, dest_reg, src_reg, 0); - } - else - { - host_arm64_MOV_REG_ROR(block, dest_reg, src_reg, 32 - (uop->imm_data & 31)); - } - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if ((uop->imm_data & 15) == 0) - { - if (src_reg != dest_reg) - host_arm64_BFI(block, dest_reg, src_reg, 0, 16); - } - else - { - host_arm64_UBFX(block, REG_TEMP, src_reg, 0, 16); - host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 16); - host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 16-(uop->imm_data & 15)); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if ((uop->imm_data & 7) == 0) - { - if (src_reg != dest_reg) - host_arm64_BFI(block, dest_reg, src_reg, 0, 8); - } - else - { - host_arm64_UBFX(block, REG_TEMP, src_reg, 0, 8); - host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); - host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8-(uop->imm_data & 7)); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - if ((uop->imm_data & 7) == 0) - { - if (src_reg != dest_reg) - fatal("ROL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - } - else - { - host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); - host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); - host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8-(uop->imm_data & 7)); - host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - } - else - fatal("ROL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_ROR(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm64_ROR(block, dest_reg, src_reg, shift_reg); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm64_UBFX(block, REG_TEMP, src_reg, 0, 16); - host_arm64_AND_IMM(block, REG_TEMP2, shift_reg, 15); - host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 16); - host_arm64_LSR(block, REG_TEMP, REG_TEMP, REG_TEMP2); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm64_UBFX(block, REG_TEMP, src_reg, 0, 8); - host_arm64_AND_IMM(block, REG_TEMP2, shift_reg, 7); - host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); - host_arm64_LSR(block, REG_TEMP, REG_TEMP, REG_TEMP2); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); - host_arm64_AND_IMM(block, REG_TEMP2, shift_reg, 7); - host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); - host_arm64_LSR(block, REG_TEMP, REG_TEMP, REG_TEMP2); - host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("ROR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_ROR_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (!(uop->imm_data & 31)) - { - if (src_reg != dest_reg) - host_arm64_MOV_REG(block, dest_reg, src_reg, 0); - } - else - { - host_arm64_MOV_REG_ROR(block, dest_reg, src_reg, uop->imm_data & 31); - } - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if ((uop->imm_data & 15) == 0) - { - if (src_reg != dest_reg) - fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - } - else - { - host_arm64_UBFX(block, REG_TEMP, src_reg, 0, 16); - host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 16); - host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data & 15); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if ((uop->imm_data & 7) == 0) - { - if (src_reg != dest_reg) - fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - } - else - { - host_arm64_UBFX(block, REG_TEMP, src_reg, 0, 8); - host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); - host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data & 7); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - if ((uop->imm_data & 7) == 0) - { - if (src_reg != dest_reg) - fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - } - else - { - host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); - host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); - host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data & 7); - host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - } - else - fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} - -static int codegen_SAR(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm64_ASR(block, dest_reg, src_reg, shift_reg); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg, 16); - host_arm64_ASR(block, REG_TEMP, REG_TEMP, shift_reg); - host_arm64_UBFX(block, REG_TEMP, REG_TEMP, 16, 16); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg, 24); - host_arm64_ASR(block, REG_TEMP, REG_TEMP, shift_reg); - host_arm64_UBFX(block, REG_TEMP, REG_TEMP, 24, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg, 16); - host_arm64_ASR(block, REG_TEMP, REG_TEMP, shift_reg); - host_arm64_UBFX(block, REG_TEMP, REG_TEMP, 24, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("SAR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_SAR_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm64_MOV_REG_ASR(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg, 16); - host_arm64_MOV_REG_ASR(block, REG_TEMP, REG_TEMP, uop->imm_data); - host_arm64_UBFX(block, REG_TEMP, REG_TEMP, 16, 16); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg, 24); - host_arm64_MOV_REG_ASR(block, REG_TEMP, REG_TEMP, uop->imm_data); - host_arm64_UBFX(block, REG_TEMP, REG_TEMP, 24, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg, 16); - host_arm64_MOV_REG_ASR(block, REG_TEMP, REG_TEMP, uop->imm_data); - host_arm64_UBFX(block, REG_TEMP, REG_TEMP, 24, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("SAR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_SHL(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm64_LSL(block, dest_reg, src_reg, shift_reg); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm64_LSL(block, REG_TEMP, src_reg, shift_reg); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm64_LSL(block, REG_TEMP, src_reg, shift_reg); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); - host_arm64_LSL(block, REG_TEMP, REG_TEMP, shift_reg); - host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("SHL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_SHL_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm64_MOV_REG(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg, uop->imm_data); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg, uop->imm_data); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); - host_arm64_MOV_REG(block, REG_TEMP, REG_TEMP, uop->imm_data); - host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("SHL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_SHR(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm64_LSR(block, dest_reg, src_reg, shift_reg); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm64_AND_IMM(block, REG_TEMP, src_reg, 0xffff); - host_arm64_LSR(block, REG_TEMP, REG_TEMP, shift_reg); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm64_AND_IMM(block, REG_TEMP, src_reg, 0xff); - host_arm64_LSR(block, REG_TEMP, REG_TEMP, shift_reg); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); - host_arm64_LSR(block, REG_TEMP, REG_TEMP, shift_reg); - host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("SHR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_SHR_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm64_MOV_REG_LSR(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm64_AND_IMM(block, REG_TEMP, src_reg, 0xffff); - host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm64_AND_IMM(block, REG_TEMP, src_reg, 0xff); - host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); - host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data); - host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("SHR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} - -static int codegen_STORE_PTR_IMM(codeblock_t *block, uop_t *uop) -{ - host_arm64_mov_imm(block, REG_W16, uop->imm_data); - - if (in_range12_w((uintptr_t)uop->p - (uintptr_t)&cpu_state)) - host_arm64_STR_IMM_W(block, REG_W16, REG_CPUSTATE, (uintptr_t)uop->p - (uintptr_t)&cpu_state); - else - fatal("codegen_STORE_PTR_IMM - not in range\n"); - - return 0; -} -static int codegen_STORE_PTR_IMM_8(codeblock_t *block, uop_t *uop) -{ - host_arm64_mov_imm(block, REG_W16, uop->imm_data); - - if (in_range12_b((uintptr_t)uop->p - (uintptr_t)&cpu_state)) - host_arm64_STRB_IMM(block, REG_W16, REG_CPUSTATE, (uintptr_t)uop->p - (uintptr_t)&cpu_state); - else - fatal("codegen_STORE_PTR_IMM - not in range\n"); - - return 0; -} - -static int codegen_SUB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_SUB_REG(block, dest_reg, src_reg_a, src_reg_b, 0); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm64_SUB_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_SUB_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b)) - { - host_arm64_SUB_REG_LSR(block, REG_TEMP, src_reg_a, src_reg_b, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_SUB_REG(block, REG_TEMP, src_reg_a, src_reg_b, 8); - host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b)) - { - host_arm64_MOV_REG_LSR(block, REG_TEMP, src_reg_a, 8); - host_arm64_SUB_REG_LSR(block, REG_TEMP, REG_TEMP, src_reg_b, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_SUB_REG(block, REG_TEMP, src_reg_a, src_reg_b, 8); - host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b)) - { - host_arm64_MOV_REG_LSR(block, REG_TEMP, src_reg_a, 8); - host_arm64_SUB_REG_LSR(block, REG_TEMP, REG_TEMP, src_reg_b, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("SUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_SUB_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm64_SUB_IMM(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm64_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm64_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data << 8); - host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data << 8); - host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("SUB_IMM %x %x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} - -static int codegen_TEST_JNS_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(src_size)) - { - host_arm64_TST_IMM(block, src_reg, 1 << 31); - } - else if (REG_IS_W(src_size)) - { - host_arm64_TST_IMM(block, src_reg, 1 << 15); - } - else if (REG_IS_B(src_size)) - { - host_arm64_TST_IMM(block, src_reg, 1 << 7); - } - else - fatal("TEST_JNS_DEST %02x\n", uop->src_reg_a_real); - - uop->p = host_arm64_BEQ_(block); - - return 0; -} -static int codegen_TEST_JS_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(src_size)) - { - host_arm64_TST_IMM(block, src_reg, 1 << 31); - } - else if (REG_IS_W(src_size)) - { - host_arm64_TST_IMM(block, src_reg, 1 << 15); - } - else if (REG_IS_B(src_size)) - { - host_arm64_TST_IMM(block, src_reg, 1 << 7); - } - else - fatal("TEST_JS_DEST %02x\n", uop->src_reg_a_real); - - uop->p = host_arm64_BNE_(block); - - return 0; -} - -static int codegen_XOR(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_EOR_REG_V(block, dest_reg, src_reg_a, src_reg_b); - } - else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_EOR_REG(block, dest_reg, src_reg_a, src_reg_b, 0); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b) && dest_reg == src_reg_a) - { - host_arm64_AND_IMM(block, REG_TEMP, src_reg_b, 0xffff); - host_arm64_EOR_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) - { - host_arm64_AND_IMM(block, REG_TEMP, src_reg_b, 0xff); - host_arm64_EOR_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) - { - host_arm64_UBFX(block, REG_TEMP, src_reg_b, 8, 8); - host_arm64_EOR_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) - { - host_arm64_AND_IMM(block, REG_TEMP, src_reg_b, 0xff); - host_arm64_EOR_REG(block, dest_reg, src_reg_a, REG_TEMP, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) - { - host_arm64_UBFX(block, REG_TEMP, src_reg_b, 8, 8); - host_arm64_EOR_REG(block, dest_reg, src_reg_a, REG_TEMP, 8); - } - else - fatal("XOR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm64_EOR_IMM(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size) && dest_reg == src_reg) - { - host_arm64_EOR_IMM(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size) && dest_reg == src_reg) - { - host_arm64_EOR_IMM(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size) && dest_reg == src_reg) - { - host_arm64_EOR_IMM(block, dest_reg, src_reg, uop->imm_data << 8); - } - else - fatal("XOR_IMM %x %x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} - -const uOpFn uop_handlers[UOP_MAX] = -{ - [UOP_CALL_FUNC & UOP_MASK] = codegen_CALL_FUNC, - [UOP_CALL_FUNC_RESULT & UOP_MASK] = codegen_CALL_FUNC_RESULT, - [UOP_CALL_INSTRUCTION_FUNC & UOP_MASK] = codegen_CALL_INSTRUCTION_FUNC, - - [UOP_JMP & UOP_MASK] = codegen_JMP, - - [UOP_LOAD_SEG & UOP_MASK] = codegen_LOAD_SEG, - - [UOP_LOAD_FUNC_ARG_0 & UOP_MASK] = codegen_LOAD_FUNC_ARG0, - [UOP_LOAD_FUNC_ARG_1 & UOP_MASK] = codegen_LOAD_FUNC_ARG1, - [UOP_LOAD_FUNC_ARG_2 & UOP_MASK] = codegen_LOAD_FUNC_ARG2, - [UOP_LOAD_FUNC_ARG_3 & UOP_MASK] = codegen_LOAD_FUNC_ARG3, - - [UOP_LOAD_FUNC_ARG_0_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG0_IMM, - [UOP_LOAD_FUNC_ARG_1_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG1_IMM, - [UOP_LOAD_FUNC_ARG_2_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG2_IMM, - [UOP_LOAD_FUNC_ARG_3_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG3_IMM, - - [UOP_STORE_P_IMM & UOP_MASK] = codegen_STORE_PTR_IMM, - [UOP_STORE_P_IMM_8 & UOP_MASK] = codegen_STORE_PTR_IMM_8, - - [UOP_MEM_LOAD_ABS & UOP_MASK] = codegen_MEM_LOAD_ABS, - [UOP_MEM_LOAD_REG & UOP_MASK] = codegen_MEM_LOAD_REG, - [UOP_MEM_LOAD_SINGLE & UOP_MASK] = codegen_MEM_LOAD_SINGLE, - [UOP_MEM_LOAD_DOUBLE & UOP_MASK] = codegen_MEM_LOAD_DOUBLE, - - [UOP_MEM_STORE_ABS & UOP_MASK] = codegen_MEM_STORE_ABS, - [UOP_MEM_STORE_REG & UOP_MASK] = codegen_MEM_STORE_REG, - [UOP_MEM_STORE_IMM_8 & UOP_MASK] = codegen_MEM_STORE_IMM_8, - [UOP_MEM_STORE_IMM_16 & UOP_MASK] = codegen_MEM_STORE_IMM_16, - [UOP_MEM_STORE_IMM_32 & UOP_MASK] = codegen_MEM_STORE_IMM_32, - [UOP_MEM_STORE_SINGLE & UOP_MASK] = codegen_MEM_STORE_SINGLE, - [UOP_MEM_STORE_DOUBLE & UOP_MASK] = codegen_MEM_STORE_DOUBLE, - - [UOP_MOV & UOP_MASK] = codegen_MOV, - [UOP_MOV_PTR & UOP_MASK] = codegen_MOV_PTR, - [UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM, - [UOP_MOVSX & UOP_MASK] = codegen_MOVSX, - [UOP_MOVZX & UOP_MASK] = codegen_MOVZX, - [UOP_MOV_DOUBLE_INT & UOP_MASK] = codegen_MOV_DOUBLE_INT, - [UOP_MOV_INT_DOUBLE & UOP_MASK] = codegen_MOV_INT_DOUBLE, - [UOP_MOV_INT_DOUBLE_64 & UOP_MASK] = codegen_MOV_INT_DOUBLE_64, - [UOP_MOV_REG_PTR & UOP_MASK] = codegen_MOV_REG_PTR, - [UOP_MOVZX_REG_PTR_8 & UOP_MASK] = codegen_MOVZX_REG_PTR_8, - [UOP_MOVZX_REG_PTR_16 & UOP_MASK] = codegen_MOVZX_REG_PTR_16, - - [UOP_ADD & UOP_MASK] = codegen_ADD, - [UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM, - [UOP_ADD_LSHIFT & UOP_MASK] = codegen_ADD_LSHIFT, - [UOP_AND & UOP_MASK] = codegen_AND, - [UOP_AND_IMM & UOP_MASK] = codegen_AND_IMM, - [UOP_ANDN & UOP_MASK] = codegen_ANDN, - [UOP_OR & UOP_MASK] = codegen_OR, - [UOP_OR_IMM & UOP_MASK] = codegen_OR_IMM, - [UOP_SUB & UOP_MASK] = codegen_SUB, - [UOP_SUB_IMM & UOP_MASK] = codegen_SUB_IMM, - [UOP_XOR & UOP_MASK] = codegen_XOR, - [UOP_XOR_IMM & UOP_MASK] = codegen_XOR_IMM, - - [UOP_SAR & UOP_MASK] = codegen_SAR, - [UOP_SAR_IMM & UOP_MASK] = codegen_SAR_IMM, - [UOP_SHL & UOP_MASK] = codegen_SHL, - [UOP_SHL_IMM & UOP_MASK] = codegen_SHL_IMM, - [UOP_SHR & UOP_MASK] = codegen_SHR, - [UOP_SHR_IMM & UOP_MASK] = codegen_SHR_IMM, - [UOP_ROL & UOP_MASK] = codegen_ROL, - [UOP_ROL_IMM & UOP_MASK] = codegen_ROL_IMM, - [UOP_ROR & UOP_MASK] = codegen_ROR, - [UOP_ROR_IMM & UOP_MASK] = codegen_ROR_IMM, - - [UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ, - - [UOP_CMP_JB & UOP_MASK] = codegen_CMP_JB, - [UOP_CMP_JNBE & UOP_MASK] = codegen_CMP_JNBE, - - [UOP_CMP_JNB_DEST & UOP_MASK] = codegen_CMP_JNB_DEST, - [UOP_CMP_JNBE_DEST & UOP_MASK] = codegen_CMP_JNBE_DEST, - [UOP_CMP_JNL_DEST & UOP_MASK] = codegen_CMP_JNL_DEST, - [UOP_CMP_JNLE_DEST & UOP_MASK] = codegen_CMP_JNLE_DEST, - [UOP_CMP_JNO_DEST & UOP_MASK] = codegen_CMP_JNO_DEST, - [UOP_CMP_JNZ_DEST & UOP_MASK] = codegen_CMP_JNZ_DEST, - [UOP_CMP_JB_DEST & UOP_MASK] = codegen_CMP_JB_DEST, - [UOP_CMP_JBE_DEST & UOP_MASK] = codegen_CMP_JBE_DEST, - [UOP_CMP_JL_DEST & UOP_MASK] = codegen_CMP_JL_DEST, - [UOP_CMP_JLE_DEST & UOP_MASK] = codegen_CMP_JLE_DEST, - [UOP_CMP_JO_DEST & UOP_MASK] = codegen_CMP_JO_DEST, - [UOP_CMP_JZ_DEST & UOP_MASK] = codegen_CMP_JZ_DEST, - - [UOP_CMP_IMM_JNZ_DEST & UOP_MASK] = codegen_CMP_IMM_JNZ_DEST, - [UOP_CMP_IMM_JZ_DEST & UOP_MASK] = codegen_CMP_IMM_JZ_DEST, - - [UOP_TEST_JNS_DEST & UOP_MASK] = codegen_TEST_JNS_DEST, - [UOP_TEST_JS_DEST & UOP_MASK] = codegen_TEST_JS_DEST, - - [UOP_FP_ENTER & UOP_MASK] = codegen_FP_ENTER, - [UOP_MMX_ENTER & UOP_MASK] = codegen_MMX_ENTER, - - [UOP_FADD & UOP_MASK] = codegen_FADD, - [UOP_FCOM & UOP_MASK] = codegen_FCOM, - [UOP_FDIV & UOP_MASK] = codegen_FDIV, - [UOP_FMUL & UOP_MASK] = codegen_FMUL, - [UOP_FSUB & UOP_MASK] = codegen_FSUB, - - [UOP_FABS & UOP_MASK] = codegen_FABS, - [UOP_FCHS & UOP_MASK] = codegen_FCHS, - [UOP_FSQRT & UOP_MASK] = codegen_FSQRT, - [UOP_FTST & UOP_MASK] = codegen_FTST, - - [UOP_PACKSSWB & UOP_MASK] = codegen_PACKSSWB, - [UOP_PACKSSDW & UOP_MASK] = codegen_PACKSSDW, - [UOP_PACKUSWB & UOP_MASK] = codegen_PACKUSWB, - - [UOP_PADDB & UOP_MASK] = codegen_PADDB, - [UOP_PADDW & UOP_MASK] = codegen_PADDW, - [UOP_PADDD & UOP_MASK] = codegen_PADDD, - [UOP_PADDSB & UOP_MASK] = codegen_PADDSB, - [UOP_PADDSW & UOP_MASK] = codegen_PADDSW, - [UOP_PADDUSB & UOP_MASK] = codegen_PADDUSB, - [UOP_PADDUSW & UOP_MASK] = codegen_PADDUSW, - - [UOP_PCMPEQB & UOP_MASK] = codegen_PCMPEQB, - [UOP_PCMPEQW & UOP_MASK] = codegen_PCMPEQW, - [UOP_PCMPEQD & UOP_MASK] = codegen_PCMPEQD, - [UOP_PCMPGTB & UOP_MASK] = codegen_PCMPGTB, - [UOP_PCMPGTW & UOP_MASK] = codegen_PCMPGTW, - [UOP_PCMPGTD & UOP_MASK] = codegen_PCMPGTD, - - [UOP_PF2ID & UOP_MASK] = codegen_PF2ID, - [UOP_PFADD & UOP_MASK] = codegen_PFADD, - [UOP_PFCMPEQ & UOP_MASK] = codegen_PFCMPEQ, - [UOP_PFCMPGE & UOP_MASK] = codegen_PFCMPGE, - [UOP_PFCMPGT & UOP_MASK] = codegen_PFCMPGT, - [UOP_PFMAX & UOP_MASK] = codegen_PFMAX, - [UOP_PFMIN & UOP_MASK] = codegen_PFMIN, - [UOP_PFMUL & UOP_MASK] = codegen_PFMUL, - [UOP_PFRCP & UOP_MASK] = codegen_PFRCP, - [UOP_PFRSQRT & UOP_MASK] = codegen_PFRSQRT, - [UOP_PFSUB & UOP_MASK] = codegen_PFSUB, - [UOP_PI2FD & UOP_MASK] = codegen_PI2FD, - - [UOP_PMADDWD & UOP_MASK] = codegen_PMADDWD, - [UOP_PMULHW & UOP_MASK] = codegen_PMULHW, - [UOP_PMULLW & UOP_MASK] = codegen_PMULLW, - - [UOP_PSLLW_IMM & UOP_MASK] = codegen_PSLLW_IMM, - [UOP_PSLLD_IMM & UOP_MASK] = codegen_PSLLD_IMM, - [UOP_PSLLQ_IMM & UOP_MASK] = codegen_PSLLQ_IMM, - [UOP_PSRAW_IMM & UOP_MASK] = codegen_PSRAW_IMM, - [UOP_PSRAD_IMM & UOP_MASK] = codegen_PSRAD_IMM, - [UOP_PSRAQ_IMM & UOP_MASK] = codegen_PSRAQ_IMM, - [UOP_PSRLW_IMM & UOP_MASK] = codegen_PSRLW_IMM, - [UOP_PSRLD_IMM & UOP_MASK] = codegen_PSRLD_IMM, - [UOP_PSRLQ_IMM & UOP_MASK] = codegen_PSRLQ_IMM, - - [UOP_PSUBB & UOP_MASK] = codegen_PSUBB, - [UOP_PSUBW & UOP_MASK] = codegen_PSUBW, - [UOP_PSUBD & UOP_MASK] = codegen_PSUBD, - [UOP_PSUBSB & UOP_MASK] = codegen_PSUBSB, - [UOP_PSUBSW & UOP_MASK] = codegen_PSUBSW, - [UOP_PSUBUSB & UOP_MASK] = codegen_PSUBUSB, - [UOP_PSUBUSW & UOP_MASK] = codegen_PSUBUSW, - - [UOP_PUNPCKHBW & UOP_MASK] = codegen_PUNPCKHBW, - [UOP_PUNPCKHWD & UOP_MASK] = codegen_PUNPCKHWD, - [UOP_PUNPCKHDQ & UOP_MASK] = codegen_PUNPCKHDQ, - [UOP_PUNPCKLBW & UOP_MASK] = codegen_PUNPCKLBW, - [UOP_PUNPCKLWD & UOP_MASK] = codegen_PUNPCKLWD, - [UOP_PUNPCKLDQ & UOP_MASK] = codegen_PUNPCKLDQ, - - [UOP_NOP_BARRIER & UOP_MASK] = codegen_NOP -}; - -void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p) -{ - if (in_range12_b((uintptr_t)p - (uintptr_t)&cpu_state)) - host_arm64_LDRB_IMM_W(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - fatal("codegen_direct_read_8 - not in range\n"); -} -void codegen_direct_read_16(codeblock_t *block, int host_reg, void *p) -{ - if (in_range12_h((uintptr_t)p - (uintptr_t)&cpu_state)) - host_arm64_LDRH_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - fatal("codegen_direct_read_16 - not in range\n"); -} -void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) -{ - if (in_range12_w((uintptr_t)p - (uintptr_t)&cpu_state)) - host_arm64_LDR_IMM_W(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - fatal("codegen_direct_read_32 - not in range\n"); -} -void codegen_direct_read_64(codeblock_t *block, int host_reg, void *p) -{ - if (in_range12_q((uintptr_t)p - (uintptr_t)&cpu_state)) - host_arm64_LDR_IMM_F64(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - fatal("codegen_direct_read_double - not in range\n"); -} -void codegen_direct_read_pointer(codeblock_t *block, int host_reg, void *p) -{ - if (in_range12_q((uintptr_t)p - (uintptr_t)&cpu_state)) - host_arm64_LDR_IMM_X(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - fatal("codegen_direct_read_pointer - not in range\n"); -} -void codegen_direct_read_double(codeblock_t *block, int host_reg, void *p) -{ - if (in_range12_q((uintptr_t)p - (uintptr_t)&cpu_state)) - host_arm64_LDR_IMM_F64(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - fatal("codegen_direct_read_double - not in range\n"); -} -void codegen_direct_read_st_8(codeblock_t *block, int host_reg, void *base, int reg_idx) -{ - host_arm64_LDR_IMM_W(block, REG_TEMP, REG_XSP, IREG_TOP_diff_stack_offset); - host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); - host_arm64_ADDX_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t)base - (uintptr_t)&cpu_state); - host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7); - host_arm64_LDRB_REG(block, host_reg, REG_TEMP2, REG_TEMP); -} -void codegen_direct_read_st_64(codeblock_t *block, int host_reg, void *base, int reg_idx) -{ - host_arm64_LDR_IMM_W(block, REG_TEMP, REG_XSP, IREG_TOP_diff_stack_offset); - host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); - host_arm64_ADDX_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t)base - (uintptr_t)&cpu_state); - host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7); - host_arm64_LDR_REG_F64_S(block, host_reg, REG_TEMP2, REG_TEMP); -} -void codegen_direct_read_st_double(codeblock_t *block, int host_reg, void *base, int reg_idx) -{ - host_arm64_LDR_IMM_W(block, REG_TEMP, REG_XSP, IREG_TOP_diff_stack_offset); - host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); - host_arm64_ADDX_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t)base - (uintptr_t)&cpu_state); - host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7); - host_arm64_LDR_REG_F64_S(block, host_reg, REG_TEMP2, REG_TEMP); -} - -void codegen_direct_write_8(codeblock_t *block, void *p, int host_reg) -{ - if (in_range12_b((uintptr_t)p - (uintptr_t)&cpu_state)) - host_arm64_STRB_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - fatal("codegen_direct_write_8 - not in range\n"); -} -void codegen_direct_write_16(codeblock_t *block, void *p, int host_reg) -{ - if (in_range12_h((uintptr_t)p - (uintptr_t)&cpu_state)) - host_arm64_STRH_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - fatal("codegen_direct_write_16 - not in range\n"); -} -void codegen_direct_write_32(codeblock_t *block, void *p, int host_reg) -{ - if (in_range12_w((uintptr_t)p - (uintptr_t)&cpu_state)) - host_arm64_STR_IMM_W(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - fatal("codegen_direct_write_32 - not in range\n"); -} -void codegen_direct_write_64(codeblock_t *block, void *p, int host_reg) -{ - if (in_range12_q((uintptr_t)p - (uintptr_t)&cpu_state)) - host_arm64_STR_IMM_F64(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - fatal("codegen_direct_write_double - not in range\n"); -} -void codegen_direct_write_double(codeblock_t *block, void *p, int host_reg) -{ - if (in_range12_q((uintptr_t)p - (uintptr_t)&cpu_state)) - host_arm64_STR_IMM_F64(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - fatal("codegen_direct_write_double - not in range\n"); -} -void codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int host_reg) -{ - host_arm64_LDR_IMM_W(block, REG_TEMP, REG_XSP, IREG_TOP_diff_stack_offset); - host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); - host_arm64_ADDX_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t)base - (uintptr_t)&cpu_state); - host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7); - host_arm64_STRB_REG(block, host_reg, REG_TEMP2, REG_TEMP); -} -void codegen_direct_write_st_64(codeblock_t *block, void *base, int reg_idx, int host_reg) -{ - host_arm64_LDR_IMM_W(block, REG_TEMP, REG_XSP, IREG_TOP_diff_stack_offset); - host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); - host_arm64_ADDX_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t)base - (uintptr_t)&cpu_state); - host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7); - host_arm64_STR_REG_F64_S(block, host_reg, REG_TEMP2, REG_TEMP); -} -void codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx, int host_reg) -{ - host_arm64_LDR_IMM_W(block, REG_TEMP, REG_XSP, IREG_TOP_diff_stack_offset); - host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); - host_arm64_ADDX_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t)base - (uintptr_t)&cpu_state); - host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7); - host_arm64_STR_REG_F64_S(block, host_reg, REG_TEMP2, REG_TEMP); -} - -void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg) -{ - if (in_range12_q((uintptr_t)p - (uintptr_t)&cpu_state)) - host_arm64_STR_IMM_Q(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - fatal("codegen_direct_write_ptr - not in range\n"); -} - -void codegen_direct_read_16_stack(codeblock_t *block, int host_reg, int stack_offset) -{ - if (in_range12_h(stack_offset)) - host_arm64_LDRH_IMM(block, host_reg, REG_XSP, stack_offset); - else - fatal("codegen_direct_read_32_stack - not in range\n"); -} -void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_offset) -{ - if (in_range12_w(stack_offset)) - host_arm64_LDR_IMM_W(block, host_reg, REG_XSP, stack_offset); - else - fatal("codegen_direct_read_32_stack - not in range\n"); -} -void codegen_direct_read_pointer_stack(codeblock_t *block, int host_reg, int stack_offset) -{ - if (in_range12_q(stack_offset)) - host_arm64_LDR_IMM_X(block, host_reg, REG_XSP, stack_offset); - else - fatal("codegen_direct_read_pointer_stack - not in range\n"); -} -void codegen_direct_read_64_stack(codeblock_t *block, int host_reg, int stack_offset) -{ - host_arm64_LDR_IMM_F64(block, host_reg, REG_XSP, stack_offset); -} -void codegen_direct_read_double_stack(codeblock_t *block, int host_reg, int stack_offset) -{ - host_arm64_LDR_IMM_F64(block, host_reg, REG_XSP, stack_offset); -} - -void codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int host_reg) -{ - if (in_range12_w(stack_offset)) - host_arm64_STR_IMM_W(block, host_reg, REG_XSP, stack_offset); - else - fatal("codegen_direct_write_32_stack - not in range\n"); -} -void codegen_direct_write_64_stack(codeblock_t *block, int stack_offset, int host_reg) -{ - host_arm64_STR_IMM_F64(block, host_reg, REG_XSP, stack_offset); -} -void codegen_direct_write_double_stack(codeblock_t *block, int stack_offset, int host_reg) -{ - host_arm64_STR_IMM_F64(block, host_reg, REG_XSP, stack_offset); -} - -void codegen_set_jump_dest(codeblock_t *block, void *p) -{ - host_arm64_branch_set_offset(p, &block_write_data[block_pos]); + return 0; } + +static int codegen_JMP(codeblock_t *block, uop_t *uop) { + host_arm64_jump(block, (uintptr_t)uop->p); + + return 0; +} + +static int codegen_LOAD_FUNC_ARG0(codeblock_t *block, uop_t *uop) { + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_W(src_size)) { + host_arm64_AND_IMM(block, REG_ARG0, src_reg, 0xffff); + } else + fatal("codegen_LOAD_FUNC_ARG0 %02x\n", uop->src_reg_a_real); + + return 0; +} +static int codegen_LOAD_FUNC_ARG1(codeblock_t *block, uop_t *uop) { + fatal("codegen_LOAD_FUNC_ARG1 %02x\n", uop->src_reg_a_real); + return 0; +} +static int codegen_LOAD_FUNC_ARG2(codeblock_t *block, uop_t *uop) { + fatal("codegen_LOAD_FUNC_ARG2 %02x\n", uop->src_reg_a_real); + return 0; +} +static int codegen_LOAD_FUNC_ARG3(codeblock_t *block, uop_t *uop) { + fatal("codegen_LOAD_FUNC_ARG3 %02x\n", uop->src_reg_a_real); + return 0; +} + +static int codegen_LOAD_FUNC_ARG0_IMM(codeblock_t *block, uop_t *uop) { + host_arm64_mov_imm(block, REG_ARG0, uop->imm_data); + + return 0; +} +static int codegen_LOAD_FUNC_ARG1_IMM(codeblock_t *block, uop_t *uop) { + host_arm64_mov_imm(block, REG_ARG1, uop->imm_data); + + return 0; +} +static int codegen_LOAD_FUNC_ARG2_IMM(codeblock_t *block, uop_t *uop) { + host_arm64_mov_imm(block, REG_ARG2, uop->imm_data); + + return 0; +} +static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop) { + host_arm64_mov_imm(block, REG_ARG3, uop->imm_data); + + return 0; +} + +static int codegen_LOAD_SEG(codeblock_t *block, uop_t *uop) { + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (!REG_IS_W(src_size)) + fatal("LOAD_SEG %02x %p\n", uop->src_reg_a_real, uop->p); + + host_arm64_MOVX_IMM(block, REG_ARG1, (uint64_t)uop->p); + host_arm64_AND_IMM(block, REG_ARG0, src_reg, 0xffff); + host_arm64_call(block, (void *)loadseg); + host_arm64_CBNZ(block, REG_X0, (uintptr_t)codegen_exit_rout); + + return 0; +} + +static int codegen_MEM_LOAD_ABS(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + host_arm64_ADD_IMM(block, REG_X0, seg_reg, uop->imm_data); + if (REG_IS_B(dest_size) || REG_IS_BH(dest_size)) { + host_arm64_call(block, codegen_mem_load_byte); + } else if (REG_IS_W(dest_size)) { + host_arm64_call(block, codegen_mem_load_word); + } else if (REG_IS_L(dest_size)) { + host_arm64_call(block, codegen_mem_load_long); + } else + fatal("MEM_LOAD_ABS - %02x\n", uop->dest_reg_a_real); + host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout); + if (REG_IS_B(dest_size)) { + host_arm64_BFI(block, dest_reg, REG_X0, 0, 8); + } else if (REG_IS_BH(dest_size)) { + host_arm64_BFI(block, dest_reg, REG_X0, 8, 8); + } else if (REG_IS_W(dest_size)) { + host_arm64_BFI(block, dest_reg, REG_X0, 0, 16); + } else if (REG_IS_L(dest_size)) { + host_arm64_MOV_REG(block, dest_reg, REG_X0, 0); + } + + return 0; +} +static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), + addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + host_arm64_ADD_REG(block, REG_X0, seg_reg, addr_reg, 0); + if (uop->imm_data) + host_arm64_ADD_IMM(block, REG_X0, REG_X0, uop->imm_data); + if (REG_IS_B(dest_size) || REG_IS_BH(dest_size)) { + host_arm64_call(block, codegen_mem_load_byte); + } else if (REG_IS_W(dest_size)) { + host_arm64_call(block, codegen_mem_load_word); + } else if (REG_IS_L(dest_size)) { + host_arm64_call(block, codegen_mem_load_long); + } else if (REG_IS_Q(dest_size)) { + host_arm64_call(block, codegen_mem_load_quad); + } else + fatal("MEM_LOAD_REG - %02x\n", uop->dest_reg_a_real); + host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout); + if (REG_IS_B(dest_size)) { + host_arm64_BFI(block, dest_reg, REG_X0, 0, 8); + } else if (REG_IS_BH(dest_size)) { + host_arm64_BFI(block, dest_reg, REG_X0, 8, 8); + } else if (REG_IS_W(dest_size)) { + host_arm64_BFI(block, dest_reg, REG_X0, 0, 16); + } else if (REG_IS_L(dest_size)) { + host_arm64_MOV_REG(block, dest_reg, REG_X0, 0); + } else if (REG_IS_Q(dest_size)) { + host_arm64_FMOV_D_D(block, dest_reg, REG_V_TEMP); + } + + return 0; +} +static int codegen_MEM_LOAD_DOUBLE(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), + addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (!REG_IS_D(dest_size)) + fatal("MEM_LOAD_DOUBLE - %02x\n", uop->dest_reg_a_real); + + host_arm64_ADD_REG(block, REG_X0, seg_reg, addr_reg, 0); + if (uop->imm_data) + host_arm64_ADD_IMM(block, REG_X0, REG_X0, uop->imm_data); + host_arm64_call(block, codegen_mem_load_double); + host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout); + host_arm64_FMOV_D_D(block, dest_reg, REG_V_TEMP); + + return 0; +} +static int codegen_MEM_LOAD_SINGLE(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), + addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (!REG_IS_D(dest_size)) + fatal("MEM_LOAD_DOUBLE - %02x\n", uop->dest_reg_a_real); + + host_arm64_ADD_REG(block, REG_X0, seg_reg, addr_reg, 0); + if (uop->imm_data) + host_arm64_ADD_IMM(block, REG_X0, REG_X0, uop->imm_data); + host_arm64_call(block, codegen_mem_load_single); + host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout); + host_arm64_FCVT_D_S(block, dest_reg, REG_V_TEMP); + + return 0; +} + +static int codegen_MEM_STORE_ABS(codeblock_t *block, uop_t *uop) { + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_b_real); + int src_size = IREG_GET_SIZE(uop->src_reg_b_real); + + host_arm64_ADD_IMM(block, REG_W0, seg_reg, uop->imm_data); + if (REG_IS_B(src_size)) { + host_arm64_AND_IMM(block, REG_W1, src_reg, 0xff); + host_arm64_call(block, codegen_mem_store_byte); + } else if (REG_IS_BH(src_size)) { + host_arm64_UBFX(block, REG_W1, src_reg, 8, 8); + host_arm64_call(block, codegen_mem_store_byte); + } else if (REG_IS_W(src_size)) { + host_arm64_AND_IMM(block, REG_W1, src_reg, 0xffff); + host_arm64_call(block, codegen_mem_store_word); + } else if (REG_IS_L(src_size)) { + host_arm64_MOV_REG(block, REG_W1, src_reg, 0); + host_arm64_call(block, codegen_mem_store_long); + } else + fatal("MEM_STORE_ABS - %02x\n", uop->dest_reg_a_real); + host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout); + + return 0; +} +static int codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop) { + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), + src_reg = HOST_REG_GET(uop->src_reg_c_real); + int src_size = IREG_GET_SIZE(uop->src_reg_c_real); + + host_arm64_ADD_REG(block, REG_W0, seg_reg, addr_reg, 0); + if (uop->imm_data) + host_arm64_ADD_IMM(block, REG_X0, REG_X0, uop->imm_data); + if (REG_IS_B(src_size)) { + host_arm64_AND_IMM(block, REG_W1, src_reg, 0xff); + host_arm64_call(block, codegen_mem_store_byte); + } else if (REG_IS_BH(src_size)) { + host_arm64_UBFX(block, REG_W1, src_reg, 8, 8); + host_arm64_call(block, codegen_mem_store_byte); + } else if (REG_IS_W(src_size)) { + host_arm64_AND_IMM(block, REG_W1, src_reg, 0xffff); + host_arm64_call(block, codegen_mem_store_word); + } else if (REG_IS_L(src_size)) { + host_arm64_MOV_REG(block, REG_W1, src_reg, 0); + host_arm64_call(block, codegen_mem_store_long); + } else if (REG_IS_Q(src_size)) { + host_arm64_FMOV_D_D(block, REG_V_TEMP, src_reg); + host_arm64_call(block, codegen_mem_store_quad); + } else + fatal("MEM_STORE_REG - %02x\n", uop->src_reg_c_real); + host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout); + + return 0; +} + +static int codegen_MEM_STORE_IMM_8(codeblock_t *block, uop_t *uop) { + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + + host_arm64_ADD_REG(block, REG_W0, seg_reg, addr_reg, 0); + host_arm64_mov_imm(block, REG_W1, uop->imm_data); + host_arm64_call(block, codegen_mem_store_byte); + host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout); + + return 0; +} +static int codegen_MEM_STORE_IMM_16(codeblock_t *block, uop_t *uop) { + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + + host_arm64_ADD_REG(block, REG_W0, seg_reg, addr_reg, 0); + host_arm64_mov_imm(block, REG_W1, uop->imm_data); + host_arm64_call(block, codegen_mem_store_word); + host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout); + + return 0; +} +static int codegen_MEM_STORE_IMM_32(codeblock_t *block, uop_t *uop) { + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + + host_arm64_ADD_REG(block, REG_W0, seg_reg, addr_reg, 0); + host_arm64_mov_imm(block, REG_W1, uop->imm_data); + host_arm64_call(block, codegen_mem_store_long); + host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout); + + return 0; +} + +static int codegen_MEM_STORE_SINGLE(codeblock_t *block, uop_t *uop) { + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), + src_reg = HOST_REG_GET(uop->src_reg_c_real); + int src_size = IREG_GET_SIZE(uop->src_reg_c_real); + + if (!REG_IS_D(src_size)) + fatal("MEM_STORE_REG - %02x\n", uop->dest_reg_a_real); + + host_arm64_ADD_REG(block, REG_W0, seg_reg, addr_reg, 0); + if (uop->imm_data) + host_arm64_ADD_IMM(block, REG_X0, REG_X0, uop->imm_data); + host_arm64_FCVT_S_D(block, REG_V_TEMP, src_reg); + host_arm64_call(block, codegen_mem_store_single); + host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout); + + return 0; +} +static int codegen_MEM_STORE_DOUBLE(codeblock_t *block, uop_t *uop) { + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), + src_reg = HOST_REG_GET(uop->src_reg_c_real); + int src_size = IREG_GET_SIZE(uop->src_reg_c_real); + + if (!REG_IS_D(src_size)) + fatal("MEM_STORE_REG - %02x\n", uop->dest_reg_a_real); + + host_arm64_ADD_REG(block, REG_W0, seg_reg, addr_reg, 0); + if (uop->imm_data) + host_arm64_ADD_IMM(block, REG_X0, REG_X0, uop->imm_data); + host_arm64_FMOV_D_D(block, REG_V_TEMP, src_reg); + host_arm64_call(block, codegen_mem_store_double); + host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout); + + return 0; +} + +static int codegen_MOV(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm64_MOV_REG(block, dest_reg, src_reg, 0); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm64_BFI(block, dest_reg, src_reg, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm64_BFI(block, dest_reg, src_reg, 0, 8); + } else if (REG_IS_B(dest_size) && REG_IS_BH(src_size)) { + host_arm64_MOV_REG_LSR(block, REG_TEMP, src_reg, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_B(src_size)) { + host_arm64_BFI(block, dest_reg, src_reg, 8, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm64_MOV_REG_LSR(block, REG_TEMP, src_reg, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else if (REG_IS_D(dest_size) && REG_IS_D(src_size)) { + host_arm64_FMOV_D_D(block, dest_reg, src_reg); + } else if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + host_arm64_FMOV_D_D(block, dest_reg, src_reg); + } else + fatal("MOV %x %x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_MOV_IMM(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_L(dest_size)) { + host_arm64_mov_imm(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size)) { + host_arm64_MOVK_IMM(block, dest_reg, uop->imm_data & 0xffff); + } else if (REG_IS_B(dest_size)) { + host_arm64_MOVZ_IMM(block, REG_TEMP, uop->imm_data & 0xff); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size)) { + host_arm64_MOVZ_IMM(block, REG_TEMP, uop->imm_data & 0xff); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("MOV_IMM %x\n", uop->dest_reg_a_real); + + return 0; +} +static int codegen_MOV_PTR(codeblock_t *block, uop_t *uop) { + host_arm64_MOVX_IMM(block, uop->dest_reg_a_real, (uint64_t)uop->p); + + return 0; +} + +static int codegen_MOVSX(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_B(src_size)) { + host_arm64_SBFX(block, dest_reg, src_reg, 0, 8); + } else if (REG_IS_L(dest_size) && REG_IS_BH(src_size)) { + host_arm64_SBFX(block, dest_reg, src_reg, 8, 8); + } else if (REG_IS_L(dest_size) && REG_IS_W(src_size)) { + host_arm64_SBFX(block, dest_reg, src_reg, 0, 16); + } else if (REG_IS_W(dest_size) && REG_IS_B(src_size)) { + host_arm64_SBFX(block, REG_TEMP, src_reg, 0, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_W(dest_size) && REG_IS_BH(src_size)) { + host_arm64_SBFX(block, REG_TEMP, src_reg, 8, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else + fatal("MOVSX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_MOVZX(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_L(src_size)) { + host_arm64_FMOV_D_Q(block, dest_reg, src_reg); + } else if (REG_IS_L(dest_size) && REG_IS_Q(src_size)) { + host_arm64_FMOV_W_S(block, dest_reg, src_reg); + } else if (REG_IS_L(dest_size) && REG_IS_B(src_size)) { + host_arm64_AND_IMM(block, dest_reg, src_reg, 0xff); + } else if (REG_IS_L(dest_size) && REG_IS_BH(src_size)) { + host_arm64_UBFX(block, dest_reg, src_reg, 8, 8); + } else if (REG_IS_L(dest_size) && REG_IS_W(src_size)) { + host_arm64_AND_IMM(block, dest_reg, src_reg, 0xffff); + } else if (REG_IS_W(dest_size) && REG_IS_B(src_size)) { + host_arm64_AND_IMM(block, REG_TEMP, src_reg, 0xff); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_W(dest_size) && REG_IS_BH(src_size)) { + host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else + fatal("MOVZX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} + +static int codegen_MOV_DOUBLE_INT(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_D(dest_size) && REG_IS_L(src_size)) { + host_arm64_SCVTF_D_W(block, dest_reg, src_reg); + } else if (REG_IS_D(dest_size) && REG_IS_W(src_size)) { + host_arm64_SBFX(block, REG_TEMP, src_reg, 0, 16); + host_arm64_SCVTF_D_W(block, dest_reg, REG_TEMP); + } else if (REG_IS_D(dest_size) && REG_IS_Q(src_size)) { + host_arm64_FMOV_Q_D(block, REG_TEMP, src_reg); + host_arm64_SCVTF_D_Q(block, dest_reg, REG_TEMP); + } else + fatal("MOV_DOUBLE_INT %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_MOV_INT_DOUBLE(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_D(src_size)) { + host_arm64_FMOV_D_D(block, REG_V_TEMP, src_reg); + host_arm64_call(block, codegen_fp_round); + host_arm64_MOV_REG(block, dest_reg, REG_TEMP, 0); + } else if (REG_IS_W(dest_size) && REG_IS_D(src_size)) { + host_arm64_FMOV_D_D(block, REG_V_TEMP, src_reg); + host_arm64_call(block, codegen_fp_round); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else + fatal("MOV_INT_DOUBLE %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_MOV_INT_DOUBLE_64(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), + src_64_reg = HOST_REG_GET(uop->src_reg_b_real), tag_reg = HOST_REG_GET(uop->src_reg_c_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real), + src_64_size = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_D(src_size) && REG_IS_Q(src_64_size)) { + uint32_t *branch_offset; + + /*If TAG_UINT64 is set then the source is MM[]. Otherwise it is a double in ST()*/ + host_arm64_FMOV_D_D(block, dest_reg, src_64_reg); + branch_offset = host_arm64_TBNZ(block, tag_reg, 7); + + host_arm64_FMOV_D_D(block, REG_V_TEMP, src_reg); + host_arm64_call(block, codegen_fp_round_quad); + host_arm64_FMOV_D_Q(block, dest_reg, REG_TEMP); + + host_arm64_branch_set_offset(branch_offset, &block_write_data[block_pos]); + } else + fatal("MOV_INT_DOUBLE_64 %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_MOV_REG_PTR(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + host_arm64_MOVX_IMM(block, REG_TEMP, (uint64_t)uop->p); + if (REG_IS_L(dest_size)) { + host_arm64_LDR_IMM_W(block, dest_reg, REG_TEMP, 0); + } else + fatal("MOV_REG_PTR %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int codegen_MOVZX_REG_PTR_8(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + host_arm64_MOVX_IMM(block, REG_TEMP, (uint64_t)uop->p); + if (REG_IS_L(dest_size)) { + host_arm64_LDRB_IMM_W(block, dest_reg, REG_TEMP, 0); + } else if (REG_IS_W(dest_size)) { + host_arm64_LDRB_IMM_W(block, REG_TEMP, REG_TEMP, 0); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size)) { + host_arm64_LDRB_IMM_W(block, REG_TEMP, REG_TEMP, 0); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else + fatal("MOVZX_REG_PTR_8 %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int codegen_MOVZX_REG_PTR_16(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + host_arm64_MOVX_IMM(block, REG_TEMP, (uint64_t)uop->p); + if (REG_IS_L(dest_size)) { + host_arm64_LDRH_IMM(block, dest_reg, REG_TEMP, 0); + } else if (REG_IS_W(dest_size)) { + host_arm64_LDRH_IMM(block, REG_TEMP, REG_TEMP, 0); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else + fatal("MOVZX_REG_PTR_16 %02x\n", uop->dest_reg_a_real); + + return 0; +} + +static int codegen_NOP(codeblock_t *block, uop_t *uop) { return 0; } + +static int codegen_OR(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_ORR_REG_V(block, dest_reg, src_reg_a, src_reg_b); + } else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_ORR_REG(block, dest_reg, src_reg_a, src_reg_b, 0); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm64_ORR_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) { + host_arm64_AND_IMM(block, REG_TEMP, src_reg_b, 0xff); + host_arm64_ORR_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) { + host_arm64_UBFX(block, REG_TEMP, src_reg_b, 8, 8); + host_arm64_ORR_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) { + host_arm64_AND_IMM(block, REG_TEMP, src_reg_b, 0xff); + host_arm64_ORR_REG(block, dest_reg, src_reg_a, REG_TEMP, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) { + host_arm64_UBFX(block, REG_TEMP, src_reg_b, 8, 8); + host_arm64_ORR_REG(block, dest_reg, src_reg_a, REG_TEMP, 8); + } else + fatal("OR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_OR_IMM(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm64_ORR_IMM(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size) && dest_reg == src_reg) { + host_arm64_ORR_IMM(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size) && dest_reg == src_reg) { + host_arm64_ORR_IMM(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size) && dest_reg == src_reg) { + host_arm64_ORR_IMM(block, dest_reg, src_reg, uop->imm_data << 8); + } else + fatal("OR_IMM %x %x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} + +static int codegen_PACKSSWB(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_arm64_SQXTN_V8B_8H(block, REG_V_TEMP, src_reg_b); + host_arm64_SQXTN_V8B_8H(block, dest_reg, dest_reg); + host_arm64_ZIP1_V2S(block, dest_reg, dest_reg, REG_V_TEMP); + } else + fatal("PACKSSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PACKSSDW(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_arm64_SQXTN_V4H_4S(block, REG_V_TEMP, src_reg_b); + host_arm64_SQXTN_V4H_4S(block, dest_reg, dest_reg); + host_arm64_ZIP1_V2S(block, dest_reg, dest_reg, REG_V_TEMP); + } else + fatal("PACKSSDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PACKUSWB(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_arm64_UQXTN_V8B_8H(block, REG_V_TEMP, src_reg_b); + host_arm64_UQXTN_V8B_8H(block, dest_reg, dest_reg); + host_arm64_ZIP1_V2S(block, dest_reg, dest_reg, REG_V_TEMP); + } else + fatal("PACKUSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + +static int codegen_PADDB(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_ADD_V8B(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PADDB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PADDW(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_ADD_V4H(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PADDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PADDD(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_ADD_V2S(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PADDD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PADDSB(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_SQADD_V8B(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PADDSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PADDSW(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_SQADD_V4H(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PADDSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PADDUSB(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_UQADD_V8B(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PADDUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PADDUSW(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_UQADD_V4H(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PADDUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + +static int codegen_PCMPEQB(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_CMEQ_V8B(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PCMPEQB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PCMPEQW(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_CMEQ_V4H(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PCMPEQW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PCMPEQD(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_CMEQ_V2S(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PCMPEQD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PCMPGTB(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_CMGT_V8B(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PCMPGTB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PCMPGTW(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_CMGT_V4H(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PCMPGTW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PCMPGTD(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_CMGT_V2S(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PCMPGTD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + +static int codegen_PF2ID(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { + host_arm64_FCVTZS_V2S(block, dest_reg, src_reg_a); + } else + fatal("PF2ID %02x %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int codegen_PFADD(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_FADD_V2S(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PFADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PFCMPEQ(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_FCMEQ_V2S(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PFCMPEQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PFCMPGE(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_FCMGE_V2S(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PFCMPGE %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PFCMPGT(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_FCMGT_V2S(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PFCMPGT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PFMAX(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_FMAX_V2S(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PFMAX %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PFMIN(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_FMIN_V2S(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PFMIN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PFMUL(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_FMUL_V2S(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PFMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PFRCP(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { + /*TODO: This could be improved (use VRECPE/VRECPS)*/ + host_arm64_FMOV_S_ONE(block, REG_V_TEMP); + host_arm64_FDIV_S(block, dest_reg, REG_V_TEMP, src_reg_a); + host_arm64_DUP_V2S(block, dest_reg, dest_reg, 0); + } else + fatal("PFRCP %02x %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int codegen_PFRSQRT(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { + /*TODO: This could be improved (use VRSQRTE/VRSQRTS)*/ + host_arm64_FSQRT_S(block, REG_V_TEMP, src_reg_a); + host_arm64_FMOV_S_ONE(block, REG_V_TEMP); + host_arm64_FDIV_S(block, dest_reg, dest_reg, REG_V_TEMP); + host_arm64_DUP_V2S(block, dest_reg, dest_reg, 0); + } else + fatal("PFRSQRT %02x %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int codegen_PFSUB(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_FSUB_V2S(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PFSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PI2FD(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { + host_arm64_SCVTF_V2S(block, dest_reg, src_reg_a); + } else + fatal("PI2FD %02x %02x\n", uop->dest_reg_a_real); + + return 0; +} + +static int codegen_PMADDWD(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_SMULL_V4S_4H(block, REG_V_TEMP, src_reg_a, src_reg_b); + host_arm64_ADDP_V4S(block, dest_reg, REG_V_TEMP, REG_V_TEMP); + } else + fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PMULHW(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_SMULL_V4S_4H(block, dest_reg, src_reg_a, src_reg_b); + host_arm64_SHRN_V4H_4S(block, dest_reg, dest_reg, 16); + } else + fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PMULLW(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_MUL_V4H(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PMULLW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + +static int codegen_PSLLW_IMM(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + if (uop->imm_data == 0) + host_arm64_FMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 15) + host_arm64_EOR_REG_V(block, dest_reg, dest_reg, dest_reg); + else + host_arm64_SHL_V4H(block, dest_reg, src_reg, uop->imm_data); + } else + fatal("PSLLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_PSLLD_IMM(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + if (uop->imm_data == 0) + host_arm64_FMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 31) + host_arm64_EOR_REG_V(block, dest_reg, dest_reg, dest_reg); + else + host_arm64_SHL_V2S(block, dest_reg, src_reg, uop->imm_data); + } else + fatal("PSLLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_PSLLQ_IMM(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + if (uop->imm_data == 0) + host_arm64_FMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 63) + host_arm64_EOR_REG_V(block, dest_reg, dest_reg, dest_reg); + else + host_arm64_SHL_V2D(block, dest_reg, src_reg, uop->imm_data); + } else + fatal("PSLLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_PSRAW_IMM(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + if (uop->imm_data == 0) + host_arm64_FMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 15) + host_arm64_SSHR_V4H(block, dest_reg, src_reg, 15); + else + host_arm64_SSHR_V4H(block, dest_reg, src_reg, uop->imm_data); + } else + fatal("PSRAW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_PSRAD_IMM(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + if (uop->imm_data == 0) + host_arm64_FMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 31) + host_arm64_SSHR_V2S(block, dest_reg, src_reg, 31); + else + host_arm64_SSHR_V2S(block, dest_reg, src_reg, uop->imm_data); + } else + fatal("PSRAD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_PSRAQ_IMM(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + if (uop->imm_data == 0) + host_arm64_FMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 63) + host_arm64_SSHR_V2D(block, dest_reg, src_reg, 63); + else + host_arm64_SSHR_V2D(block, dest_reg, src_reg, uop->imm_data); + } else + fatal("PSRAQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_PSRLW_IMM(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + if (uop->imm_data == 0) + host_arm64_FMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 15) + host_arm64_EOR_REG_V(block, dest_reg, dest_reg, dest_reg); + else + host_arm64_USHR_V4H(block, dest_reg, src_reg, uop->imm_data); + } else + fatal("PSRLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_PSRLD_IMM(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + if (uop->imm_data == 0) + host_arm64_FMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 31) + host_arm64_EOR_REG_V(block, dest_reg, dest_reg, dest_reg); + else + host_arm64_USHR_V2S(block, dest_reg, src_reg, uop->imm_data); + } else + fatal("PSRLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_PSRLQ_IMM(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + if (uop->imm_data == 0) + host_arm64_FMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 63) + host_arm64_EOR_REG_V(block, dest_reg, dest_reg, dest_reg); + else + host_arm64_USHR_V2D(block, dest_reg, src_reg, uop->imm_data); + } else + fatal("PSRLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} + +static int codegen_PSUBB(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_SUB_V8B(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PSUBB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PSUBW(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_SUB_V4H(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PSUBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PSUBD(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_SUB_V2S(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PSUBD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PSUBSB(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_SQSUB_V8B(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PSUBSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PSUBSW(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_SQSUB_V4H(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PSUBSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PSUBUSB(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_UQSUB_V8B(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PSUBUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PSUBUSW(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_UQSUB_V4H(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PSUBUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + +static int codegen_PUNPCKHBW(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_ZIP2_V8B(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PUNPCKHBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PUNPCKHWD(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_ZIP2_V4H(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PUNPCKHWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PUNPCKHDQ(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_ZIP2_V2S(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PUNPCKHDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PUNPCKLBW(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_ZIP1_V8B(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PUNPCKLBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PUNPCKLWD(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_ZIP1_V4H(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PUNPCKLWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_PUNPCKLDQ(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_ZIP1_V2S(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PUNPCKLDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + +static int codegen_ROL(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), + shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm64_mov_imm(block, REG_TEMP2, 32); + host_arm64_SUB_REG(block, REG_TEMP2, REG_TEMP2, shift_reg, 0); + host_arm64_ROR(block, dest_reg, src_reg, REG_TEMP2); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm64_mov_imm(block, REG_TEMP2, 16); + host_arm64_UBFX(block, REG_TEMP, src_reg, 0, 16); + host_arm64_SUB_REG(block, REG_TEMP2, REG_TEMP2, shift_reg, 0); + host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 16); + host_arm64_ROR(block, REG_TEMP, REG_TEMP, REG_TEMP2); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + cs = cs; + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm64_mov_imm(block, REG_TEMP2, 8); + host_arm64_SUB_REG(block, REG_TEMP2, REG_TEMP2, shift_reg, 0); + host_arm64_UBFX(block, REG_TEMP, src_reg, 0, 8); + host_arm64_AND_IMM(block, REG_TEMP2, REG_TEMP2, 7); + host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm64_LSR(block, REG_TEMP, REG_TEMP, REG_TEMP2); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm64_mov_imm(block, REG_TEMP2, 8); + host_arm64_SUB_REG(block, REG_TEMP2, REG_TEMP2, shift_reg, 0); + host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); + host_arm64_AND_IMM(block, REG_TEMP2, REG_TEMP2, 7); + host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm64_LSR(block, REG_TEMP, REG_TEMP, REG_TEMP2); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("ROL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_ROL_IMM(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (!(uop->imm_data & 31)) { + if (src_reg != dest_reg) + host_arm64_MOV_REG(block, dest_reg, src_reg, 0); + } else { + host_arm64_MOV_REG_ROR(block, dest_reg, src_reg, 32 - (uop->imm_data & 31)); + } + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if ((uop->imm_data & 15) == 0) { + if (src_reg != dest_reg) + host_arm64_BFI(block, dest_reg, src_reg, 0, 16); + } else { + host_arm64_UBFX(block, REG_TEMP, src_reg, 0, 16); + host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 16); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 16 - (uop->imm_data & 15)); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if ((uop->imm_data & 7) == 0) { + if (src_reg != dest_reg) + host_arm64_BFI(block, dest_reg, src_reg, 0, 8); + } else { + host_arm64_UBFX(block, REG_TEMP, src_reg, 0, 8); + host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8 - (uop->imm_data & 7)); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + if ((uop->imm_data & 7) == 0) { + if (src_reg != dest_reg) + fatal("ROL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + } else { + host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); + host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8 - (uop->imm_data & 7)); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } + } else + fatal("ROL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_ROR(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), + shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm64_ROR(block, dest_reg, src_reg, shift_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm64_UBFX(block, REG_TEMP, src_reg, 0, 16); + host_arm64_AND_IMM(block, REG_TEMP2, shift_reg, 15); + host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 16); + host_arm64_LSR(block, REG_TEMP, REG_TEMP, REG_TEMP2); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm64_UBFX(block, REG_TEMP, src_reg, 0, 8); + host_arm64_AND_IMM(block, REG_TEMP2, shift_reg, 7); + host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm64_LSR(block, REG_TEMP, REG_TEMP, REG_TEMP2); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); + host_arm64_AND_IMM(block, REG_TEMP2, shift_reg, 7); + host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm64_LSR(block, REG_TEMP, REG_TEMP, REG_TEMP2); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("ROR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_ROR_IMM(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (!(uop->imm_data & 31)) { + if (src_reg != dest_reg) + host_arm64_MOV_REG(block, dest_reg, src_reg, 0); + } else { + host_arm64_MOV_REG_ROR(block, dest_reg, src_reg, uop->imm_data & 31); + } + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if ((uop->imm_data & 15) == 0) { + if (src_reg != dest_reg) + fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + } else { + host_arm64_UBFX(block, REG_TEMP, src_reg, 0, 16); + host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 16); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data & 15); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if ((uop->imm_data & 7) == 0) { + if (src_reg != dest_reg) + fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + } else { + host_arm64_UBFX(block, REG_TEMP, src_reg, 0, 8); + host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data & 7); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + if ((uop->imm_data & 7) == 0) { + if (src_reg != dest_reg) + fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + } else { + host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); + host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data & 7); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } + } else + fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} + +static int codegen_SAR(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), + shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm64_ASR(block, dest_reg, src_reg, shift_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg, 16); + host_arm64_ASR(block, REG_TEMP, REG_TEMP, shift_reg); + host_arm64_UBFX(block, REG_TEMP, REG_TEMP, 16, 16); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg, 24); + host_arm64_ASR(block, REG_TEMP, REG_TEMP, shift_reg); + host_arm64_UBFX(block, REG_TEMP, REG_TEMP, 24, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg, 16); + host_arm64_ASR(block, REG_TEMP, REG_TEMP, shift_reg); + host_arm64_UBFX(block, REG_TEMP, REG_TEMP, 24, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("SAR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_SAR_IMM(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm64_MOV_REG_ASR(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg, 16); + host_arm64_MOV_REG_ASR(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm64_UBFX(block, REG_TEMP, REG_TEMP, 16, 16); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg, 24); + host_arm64_MOV_REG_ASR(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm64_UBFX(block, REG_TEMP, REG_TEMP, 24, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg, 16); + host_arm64_MOV_REG_ASR(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm64_UBFX(block, REG_TEMP, REG_TEMP, 24, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("SAR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_SHL(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), + shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm64_LSL(block, dest_reg, src_reg, shift_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm64_LSL(block, REG_TEMP, src_reg, shift_reg); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm64_LSL(block, REG_TEMP, src_reg, shift_reg); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); + host_arm64_LSL(block, REG_TEMP, REG_TEMP, shift_reg); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("SHL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_SHL_IMM(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm64_MOV_REG(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg, uop->imm_data); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg, uop->imm_data); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); + host_arm64_MOV_REG(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("SHL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_SHR(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), + shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm64_LSR(block, dest_reg, src_reg, shift_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm64_AND_IMM(block, REG_TEMP, src_reg, 0xffff); + host_arm64_LSR(block, REG_TEMP, REG_TEMP, shift_reg); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm64_AND_IMM(block, REG_TEMP, src_reg, 0xff); + host_arm64_LSR(block, REG_TEMP, REG_TEMP, shift_reg); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); + host_arm64_LSR(block, REG_TEMP, REG_TEMP, shift_reg); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("SHR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int codegen_SHR_IMM(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm64_MOV_REG_LSR(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm64_AND_IMM(block, REG_TEMP, src_reg, 0xffff); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm64_AND_IMM(block, REG_TEMP, src_reg, 0xff); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("SHR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} + +static int codegen_STORE_PTR_IMM(codeblock_t *block, uop_t *uop) { + host_arm64_mov_imm(block, REG_W16, uop->imm_data); + + if (in_range12_w((uintptr_t)uop->p - (uintptr_t)&cpu_state)) + host_arm64_STR_IMM_W(block, REG_W16, REG_CPUSTATE, (uintptr_t)uop->p - (uintptr_t)&cpu_state); + else + fatal("codegen_STORE_PTR_IMM - not in range\n"); + + return 0; +} +static int codegen_STORE_PTR_IMM_8(codeblock_t *block, uop_t *uop) { + host_arm64_mov_imm(block, REG_W16, uop->imm_data); + + if (in_range12_b((uintptr_t)uop->p - (uintptr_t)&cpu_state)) + host_arm64_STRB_IMM(block, REG_W16, REG_CPUSTATE, (uintptr_t)uop->p - (uintptr_t)&cpu_state); + else + fatal("codegen_STORE_PTR_IMM - not in range\n"); + + return 0; +} + +static int codegen_SUB(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_SUB_REG(block, dest_reg, src_reg_a, src_reg_b, 0); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm64_SUB_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_SUB_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b)) { + host_arm64_SUB_REG_LSR(block, REG_TEMP, src_reg_a, src_reg_b, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_SUB_REG(block, REG_TEMP, src_reg_a, src_reg_b, 8); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b)) { + host_arm64_MOV_REG_LSR(block, REG_TEMP, src_reg_a, 8); + host_arm64_SUB_REG_LSR(block, REG_TEMP, REG_TEMP, src_reg_b, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_SUB_REG(block, REG_TEMP, src_reg_a, src_reg_b, 8); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b)) { + host_arm64_MOV_REG_LSR(block, REG_TEMP, src_reg_a, 8); + host_arm64_SUB_REG_LSR(block, REG_TEMP, REG_TEMP, src_reg_b, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("SUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_SUB_IMM(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm64_SUB_IMM(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm64_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm64_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_B(dest_size) && REG_IS_BH(src_size)) { + host_arm64_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data << 8); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm64_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data << 8); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("SUB_IMM %x %x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} + +static int codegen_TEST_JNS_DEST(codeblock_t *block, uop_t *uop) { + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(src_size)) { + host_arm64_TST_IMM(block, src_reg, 1 << 31); + } else if (REG_IS_W(src_size)) { + host_arm64_TST_IMM(block, src_reg, 1 << 15); + } else if (REG_IS_B(src_size)) { + host_arm64_TST_IMM(block, src_reg, 1 << 7); + } else + fatal("TEST_JNS_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm64_BEQ_(block); + + return 0; +} +static int codegen_TEST_JS_DEST(codeblock_t *block, uop_t *uop) { + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(src_size)) { + host_arm64_TST_IMM(block, src_reg, 1 << 31); + } else if (REG_IS_W(src_size)) { + host_arm64_TST_IMM(block, src_reg, 1 << 15); + } else if (REG_IS_B(src_size)) { + host_arm64_TST_IMM(block, src_reg, 1 << 7); + } else + fatal("TEST_JS_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm64_BNE_(block); + + return 0; +} + +static int codegen_XOR(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_EOR_REG_V(block, dest_reg, src_reg_a, src_reg_b); + } else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_EOR_REG(block, dest_reg, src_reg_a, src_reg_b, 0); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b) && dest_reg == src_reg_a) { + host_arm64_AND_IMM(block, REG_TEMP, src_reg_b, 0xffff); + host_arm64_EOR_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) { + host_arm64_AND_IMM(block, REG_TEMP, src_reg_b, 0xff); + host_arm64_EOR_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) { + host_arm64_UBFX(block, REG_TEMP, src_reg_b, 8, 8); + host_arm64_EOR_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) { + host_arm64_AND_IMM(block, REG_TEMP, src_reg_b, 0xff); + host_arm64_EOR_REG(block, dest_reg, src_reg_a, REG_TEMP, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) { + host_arm64_UBFX(block, REG_TEMP, src_reg_b, 8, 8); + host_arm64_EOR_REG(block, dest_reg, src_reg_a, REG_TEMP, 8); + } else + fatal("XOR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop) { + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm64_EOR_IMM(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size) && dest_reg == src_reg) { + host_arm64_EOR_IMM(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size) && dest_reg == src_reg) { + host_arm64_EOR_IMM(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size) && dest_reg == src_reg) { + host_arm64_EOR_IMM(block, dest_reg, src_reg, uop->imm_data << 8); + } else + fatal("XOR_IMM %x %x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} + +const uOpFn uop_handlers[UOP_MAX] = {[UOP_CALL_FUNC & UOP_MASK] = codegen_CALL_FUNC, + [UOP_CALL_FUNC_RESULT & UOP_MASK] = codegen_CALL_FUNC_RESULT, + [UOP_CALL_INSTRUCTION_FUNC & UOP_MASK] = codegen_CALL_INSTRUCTION_FUNC, + + [UOP_JMP & UOP_MASK] = codegen_JMP, + + [UOP_LOAD_SEG & UOP_MASK] = codegen_LOAD_SEG, + + [UOP_LOAD_FUNC_ARG_0 & UOP_MASK] = codegen_LOAD_FUNC_ARG0, + [UOP_LOAD_FUNC_ARG_1 & UOP_MASK] = codegen_LOAD_FUNC_ARG1, + [UOP_LOAD_FUNC_ARG_2 & UOP_MASK] = codegen_LOAD_FUNC_ARG2, + [UOP_LOAD_FUNC_ARG_3 & UOP_MASK] = codegen_LOAD_FUNC_ARG3, + + [UOP_LOAD_FUNC_ARG_0_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG0_IMM, + [UOP_LOAD_FUNC_ARG_1_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG1_IMM, + [UOP_LOAD_FUNC_ARG_2_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG2_IMM, + [UOP_LOAD_FUNC_ARG_3_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG3_IMM, + + [UOP_STORE_P_IMM & UOP_MASK] = codegen_STORE_PTR_IMM, + [UOP_STORE_P_IMM_8 & UOP_MASK] = codegen_STORE_PTR_IMM_8, + + [UOP_MEM_LOAD_ABS & UOP_MASK] = codegen_MEM_LOAD_ABS, + [UOP_MEM_LOAD_REG & UOP_MASK] = codegen_MEM_LOAD_REG, + [UOP_MEM_LOAD_SINGLE & UOP_MASK] = codegen_MEM_LOAD_SINGLE, + [UOP_MEM_LOAD_DOUBLE & UOP_MASK] = codegen_MEM_LOAD_DOUBLE, + + [UOP_MEM_STORE_ABS & UOP_MASK] = codegen_MEM_STORE_ABS, + [UOP_MEM_STORE_REG & UOP_MASK] = codegen_MEM_STORE_REG, + [UOP_MEM_STORE_IMM_8 & UOP_MASK] = codegen_MEM_STORE_IMM_8, + [UOP_MEM_STORE_IMM_16 & UOP_MASK] = codegen_MEM_STORE_IMM_16, + [UOP_MEM_STORE_IMM_32 & UOP_MASK] = codegen_MEM_STORE_IMM_32, + [UOP_MEM_STORE_SINGLE & UOP_MASK] = codegen_MEM_STORE_SINGLE, + [UOP_MEM_STORE_DOUBLE & UOP_MASK] = codegen_MEM_STORE_DOUBLE, + + [UOP_MOV & UOP_MASK] = codegen_MOV, + [UOP_MOV_PTR & UOP_MASK] = codegen_MOV_PTR, + [UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM, + [UOP_MOVSX & UOP_MASK] = codegen_MOVSX, + [UOP_MOVZX & UOP_MASK] = codegen_MOVZX, + [UOP_MOV_DOUBLE_INT & UOP_MASK] = codegen_MOV_DOUBLE_INT, + [UOP_MOV_INT_DOUBLE & UOP_MASK] = codegen_MOV_INT_DOUBLE, + [UOP_MOV_INT_DOUBLE_64 & UOP_MASK] = codegen_MOV_INT_DOUBLE_64, + [UOP_MOV_REG_PTR & UOP_MASK] = codegen_MOV_REG_PTR, + [UOP_MOVZX_REG_PTR_8 & UOP_MASK] = codegen_MOVZX_REG_PTR_8, + [UOP_MOVZX_REG_PTR_16 & UOP_MASK] = codegen_MOVZX_REG_PTR_16, + + [UOP_ADD & UOP_MASK] = codegen_ADD, + [UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM, + [UOP_ADD_LSHIFT & UOP_MASK] = codegen_ADD_LSHIFT, + [UOP_AND & UOP_MASK] = codegen_AND, + [UOP_AND_IMM & UOP_MASK] = codegen_AND_IMM, + [UOP_ANDN & UOP_MASK] = codegen_ANDN, + [UOP_OR & UOP_MASK] = codegen_OR, + [UOP_OR_IMM & UOP_MASK] = codegen_OR_IMM, + [UOP_SUB & UOP_MASK] = codegen_SUB, + [UOP_SUB_IMM & UOP_MASK] = codegen_SUB_IMM, + [UOP_XOR & UOP_MASK] = codegen_XOR, + [UOP_XOR_IMM & UOP_MASK] = codegen_XOR_IMM, + + [UOP_SAR & UOP_MASK] = codegen_SAR, + [UOP_SAR_IMM & UOP_MASK] = codegen_SAR_IMM, + [UOP_SHL & UOP_MASK] = codegen_SHL, + [UOP_SHL_IMM & UOP_MASK] = codegen_SHL_IMM, + [UOP_SHR & UOP_MASK] = codegen_SHR, + [UOP_SHR_IMM & UOP_MASK] = codegen_SHR_IMM, + [UOP_ROL & UOP_MASK] = codegen_ROL, + [UOP_ROL_IMM & UOP_MASK] = codegen_ROL_IMM, + [UOP_ROR & UOP_MASK] = codegen_ROR, + [UOP_ROR_IMM & UOP_MASK] = codegen_ROR_IMM, + + [UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ, + + [UOP_CMP_JB & UOP_MASK] = codegen_CMP_JB, + [UOP_CMP_JNBE & UOP_MASK] = codegen_CMP_JNBE, + + [UOP_CMP_JNB_DEST & UOP_MASK] = codegen_CMP_JNB_DEST, + [UOP_CMP_JNBE_DEST & UOP_MASK] = codegen_CMP_JNBE_DEST, + [UOP_CMP_JNL_DEST & UOP_MASK] = codegen_CMP_JNL_DEST, + [UOP_CMP_JNLE_DEST & UOP_MASK] = codegen_CMP_JNLE_DEST, + [UOP_CMP_JNO_DEST & UOP_MASK] = codegen_CMP_JNO_DEST, + [UOP_CMP_JNZ_DEST & UOP_MASK] = codegen_CMP_JNZ_DEST, + [UOP_CMP_JB_DEST & UOP_MASK] = codegen_CMP_JB_DEST, + [UOP_CMP_JBE_DEST & UOP_MASK] = codegen_CMP_JBE_DEST, + [UOP_CMP_JL_DEST & UOP_MASK] = codegen_CMP_JL_DEST, + [UOP_CMP_JLE_DEST & UOP_MASK] = codegen_CMP_JLE_DEST, + [UOP_CMP_JO_DEST & UOP_MASK] = codegen_CMP_JO_DEST, + [UOP_CMP_JZ_DEST & UOP_MASK] = codegen_CMP_JZ_DEST, + + [UOP_CMP_IMM_JNZ_DEST & UOP_MASK] = codegen_CMP_IMM_JNZ_DEST, + [UOP_CMP_IMM_JZ_DEST & UOP_MASK] = codegen_CMP_IMM_JZ_DEST, + + [UOP_TEST_JNS_DEST & UOP_MASK] = codegen_TEST_JNS_DEST, + [UOP_TEST_JS_DEST & UOP_MASK] = codegen_TEST_JS_DEST, + + [UOP_FP_ENTER & UOP_MASK] = codegen_FP_ENTER, + [UOP_MMX_ENTER & UOP_MASK] = codegen_MMX_ENTER, + + [UOP_FADD & UOP_MASK] = codegen_FADD, + [UOP_FCOM & UOP_MASK] = codegen_FCOM, + [UOP_FDIV & UOP_MASK] = codegen_FDIV, + [UOP_FMUL & UOP_MASK] = codegen_FMUL, + [UOP_FSUB & UOP_MASK] = codegen_FSUB, + + [UOP_FABS & UOP_MASK] = codegen_FABS, + [UOP_FCHS & UOP_MASK] = codegen_FCHS, + [UOP_FSQRT & UOP_MASK] = codegen_FSQRT, + [UOP_FTST & UOP_MASK] = codegen_FTST, + + [UOP_PACKSSWB & UOP_MASK] = codegen_PACKSSWB, + [UOP_PACKSSDW & UOP_MASK] = codegen_PACKSSDW, + [UOP_PACKUSWB & UOP_MASK] = codegen_PACKUSWB, + + [UOP_PADDB & UOP_MASK] = codegen_PADDB, + [UOP_PADDW & UOP_MASK] = codegen_PADDW, + [UOP_PADDD & UOP_MASK] = codegen_PADDD, + [UOP_PADDSB & UOP_MASK] = codegen_PADDSB, + [UOP_PADDSW & UOP_MASK] = codegen_PADDSW, + [UOP_PADDUSB & UOP_MASK] = codegen_PADDUSB, + [UOP_PADDUSW & UOP_MASK] = codegen_PADDUSW, + + [UOP_PCMPEQB & UOP_MASK] = codegen_PCMPEQB, + [UOP_PCMPEQW & UOP_MASK] = codegen_PCMPEQW, + [UOP_PCMPEQD & UOP_MASK] = codegen_PCMPEQD, + [UOP_PCMPGTB & UOP_MASK] = codegen_PCMPGTB, + [UOP_PCMPGTW & UOP_MASK] = codegen_PCMPGTW, + [UOP_PCMPGTD & UOP_MASK] = codegen_PCMPGTD, + + [UOP_PF2ID & UOP_MASK] = codegen_PF2ID, + [UOP_PFADD & UOP_MASK] = codegen_PFADD, + [UOP_PFCMPEQ & UOP_MASK] = codegen_PFCMPEQ, + [UOP_PFCMPGE & UOP_MASK] = codegen_PFCMPGE, + [UOP_PFCMPGT & UOP_MASK] = codegen_PFCMPGT, + [UOP_PFMAX & UOP_MASK] = codegen_PFMAX, + [UOP_PFMIN & UOP_MASK] = codegen_PFMIN, + [UOP_PFMUL & UOP_MASK] = codegen_PFMUL, + [UOP_PFRCP & UOP_MASK] = codegen_PFRCP, + [UOP_PFRSQRT & UOP_MASK] = codegen_PFRSQRT, + [UOP_PFSUB & UOP_MASK] = codegen_PFSUB, + [UOP_PI2FD & UOP_MASK] = codegen_PI2FD, + + [UOP_PMADDWD & UOP_MASK] = codegen_PMADDWD, + [UOP_PMULHW & UOP_MASK] = codegen_PMULHW, + [UOP_PMULLW & UOP_MASK] = codegen_PMULLW, + + [UOP_PSLLW_IMM & UOP_MASK] = codegen_PSLLW_IMM, + [UOP_PSLLD_IMM & UOP_MASK] = codegen_PSLLD_IMM, + [UOP_PSLLQ_IMM & UOP_MASK] = codegen_PSLLQ_IMM, + [UOP_PSRAW_IMM & UOP_MASK] = codegen_PSRAW_IMM, + [UOP_PSRAD_IMM & UOP_MASK] = codegen_PSRAD_IMM, + [UOP_PSRAQ_IMM & UOP_MASK] = codegen_PSRAQ_IMM, + [UOP_PSRLW_IMM & UOP_MASK] = codegen_PSRLW_IMM, + [UOP_PSRLD_IMM & UOP_MASK] = codegen_PSRLD_IMM, + [UOP_PSRLQ_IMM & UOP_MASK] = codegen_PSRLQ_IMM, + + [UOP_PSUBB & UOP_MASK] = codegen_PSUBB, + [UOP_PSUBW & UOP_MASK] = codegen_PSUBW, + [UOP_PSUBD & UOP_MASK] = codegen_PSUBD, + [UOP_PSUBSB & UOP_MASK] = codegen_PSUBSB, + [UOP_PSUBSW & UOP_MASK] = codegen_PSUBSW, + [UOP_PSUBUSB & UOP_MASK] = codegen_PSUBUSB, + [UOP_PSUBUSW & UOP_MASK] = codegen_PSUBUSW, + + [UOP_PUNPCKHBW & UOP_MASK] = codegen_PUNPCKHBW, + [UOP_PUNPCKHWD & UOP_MASK] = codegen_PUNPCKHWD, + [UOP_PUNPCKHDQ & UOP_MASK] = codegen_PUNPCKHDQ, + [UOP_PUNPCKLBW & UOP_MASK] = codegen_PUNPCKLBW, + [UOP_PUNPCKLWD & UOP_MASK] = codegen_PUNPCKLWD, + [UOP_PUNPCKLDQ & UOP_MASK] = codegen_PUNPCKLDQ, + + [UOP_NOP_BARRIER & UOP_MASK] = codegen_NOP}; + +void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p) { + if (in_range12_b((uintptr_t)p - (uintptr_t)&cpu_state)) + host_arm64_LDRB_IMM_W(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); + else + fatal("codegen_direct_read_8 - not in range\n"); +} +void codegen_direct_read_16(codeblock_t *block, int host_reg, void *p) { + if (in_range12_h((uintptr_t)p - (uintptr_t)&cpu_state)) + host_arm64_LDRH_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); + else + fatal("codegen_direct_read_16 - not in range\n"); +} +void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) { + if (in_range12_w((uintptr_t)p - (uintptr_t)&cpu_state)) + host_arm64_LDR_IMM_W(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); + else + fatal("codegen_direct_read_32 - not in range\n"); +} +void codegen_direct_read_64(codeblock_t *block, int host_reg, void *p) { + if (in_range12_q((uintptr_t)p - (uintptr_t)&cpu_state)) + host_arm64_LDR_IMM_F64(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); + else + fatal("codegen_direct_read_double - not in range\n"); +} +void codegen_direct_read_pointer(codeblock_t *block, int host_reg, void *p) { + if (in_range12_q((uintptr_t)p - (uintptr_t)&cpu_state)) + host_arm64_LDR_IMM_X(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); + else + fatal("codegen_direct_read_pointer - not in range\n"); +} +void codegen_direct_read_double(codeblock_t *block, int host_reg, void *p) { + if (in_range12_q((uintptr_t)p - (uintptr_t)&cpu_state)) + host_arm64_LDR_IMM_F64(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); + else + fatal("codegen_direct_read_double - not in range\n"); +} +void codegen_direct_read_st_8(codeblock_t *block, int host_reg, void *base, int reg_idx) { + host_arm64_LDR_IMM_W(block, REG_TEMP, REG_XSP, IREG_TOP_diff_stack_offset); + host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); + host_arm64_ADDX_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t)base - (uintptr_t)&cpu_state); + host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7); + host_arm64_LDRB_REG(block, host_reg, REG_TEMP2, REG_TEMP); +} +void codegen_direct_read_st_64(codeblock_t *block, int host_reg, void *base, int reg_idx) { + host_arm64_LDR_IMM_W(block, REG_TEMP, REG_XSP, IREG_TOP_diff_stack_offset); + host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); + host_arm64_ADDX_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t)base - (uintptr_t)&cpu_state); + host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7); + host_arm64_LDR_REG_F64_S(block, host_reg, REG_TEMP2, REG_TEMP); +} +void codegen_direct_read_st_double(codeblock_t *block, int host_reg, void *base, int reg_idx) { + host_arm64_LDR_IMM_W(block, REG_TEMP, REG_XSP, IREG_TOP_diff_stack_offset); + host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); + host_arm64_ADDX_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t)base - (uintptr_t)&cpu_state); + host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7); + host_arm64_LDR_REG_F64_S(block, host_reg, REG_TEMP2, REG_TEMP); +} + +void codegen_direct_write_8(codeblock_t *block, void *p, int host_reg) { + if (in_range12_b((uintptr_t)p - (uintptr_t)&cpu_state)) + host_arm64_STRB_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); + else + fatal("codegen_direct_write_8 - not in range\n"); +} +void codegen_direct_write_16(codeblock_t *block, void *p, int host_reg) { + if (in_range12_h((uintptr_t)p - (uintptr_t)&cpu_state)) + host_arm64_STRH_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); + else + fatal("codegen_direct_write_16 - not in range\n"); +} +void codegen_direct_write_32(codeblock_t *block, void *p, int host_reg) { + if (in_range12_w((uintptr_t)p - (uintptr_t)&cpu_state)) + host_arm64_STR_IMM_W(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); + else + fatal("codegen_direct_write_32 - not in range\n"); +} +void codegen_direct_write_64(codeblock_t *block, void *p, int host_reg) { + if (in_range12_q((uintptr_t)p - (uintptr_t)&cpu_state)) + host_arm64_STR_IMM_F64(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); + else + fatal("codegen_direct_write_double - not in range\n"); +} +void codegen_direct_write_double(codeblock_t *block, void *p, int host_reg) { + if (in_range12_q((uintptr_t)p - (uintptr_t)&cpu_state)) + host_arm64_STR_IMM_F64(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); + else + fatal("codegen_direct_write_double - not in range\n"); +} +void codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int host_reg) { + host_arm64_LDR_IMM_W(block, REG_TEMP, REG_XSP, IREG_TOP_diff_stack_offset); + host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); + host_arm64_ADDX_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t)base - (uintptr_t)&cpu_state); + host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7); + host_arm64_STRB_REG(block, host_reg, REG_TEMP2, REG_TEMP); +} +void codegen_direct_write_st_64(codeblock_t *block, void *base, int reg_idx, int host_reg) { + host_arm64_LDR_IMM_W(block, REG_TEMP, REG_XSP, IREG_TOP_diff_stack_offset); + host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); + host_arm64_ADDX_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t)base - (uintptr_t)&cpu_state); + host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7); + host_arm64_STR_REG_F64_S(block, host_reg, REG_TEMP2, REG_TEMP); +} +void codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx, int host_reg) { + host_arm64_LDR_IMM_W(block, REG_TEMP, REG_XSP, IREG_TOP_diff_stack_offset); + host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); + host_arm64_ADDX_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t)base - (uintptr_t)&cpu_state); + host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7); + host_arm64_STR_REG_F64_S(block, host_reg, REG_TEMP2, REG_TEMP); +} + +void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg) { + if (in_range12_q((uintptr_t)p - (uintptr_t)&cpu_state)) + host_arm64_STR_IMM_Q(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); + else + fatal("codegen_direct_write_ptr - not in range\n"); +} + +void codegen_direct_read_16_stack(codeblock_t *block, int host_reg, int stack_offset) { + if (in_range12_h(stack_offset)) + host_arm64_LDRH_IMM(block, host_reg, REG_XSP, stack_offset); + else + fatal("codegen_direct_read_32_stack - not in range\n"); +} +void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_offset) { + if (in_range12_w(stack_offset)) + host_arm64_LDR_IMM_W(block, host_reg, REG_XSP, stack_offset); + else + fatal("codegen_direct_read_32_stack - not in range\n"); +} +void codegen_direct_read_pointer_stack(codeblock_t *block, int host_reg, int stack_offset) { + if (in_range12_q(stack_offset)) + host_arm64_LDR_IMM_X(block, host_reg, REG_XSP, stack_offset); + else + fatal("codegen_direct_read_pointer_stack - not in range\n"); +} +void codegen_direct_read_64_stack(codeblock_t *block, int host_reg, int stack_offset) { + host_arm64_LDR_IMM_F64(block, host_reg, REG_XSP, stack_offset); +} +void codegen_direct_read_double_stack(codeblock_t *block, int host_reg, int stack_offset) { + host_arm64_LDR_IMM_F64(block, host_reg, REG_XSP, stack_offset); +} + +void codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int host_reg) { + if (in_range12_w(stack_offset)) + host_arm64_STR_IMM_W(block, host_reg, REG_XSP, stack_offset); + else + fatal("codegen_direct_write_32_stack - not in range\n"); +} +void codegen_direct_write_64_stack(codeblock_t *block, int stack_offset, int host_reg) { + host_arm64_STR_IMM_F64(block, host_reg, REG_XSP, stack_offset); +} +void codegen_direct_write_double_stack(codeblock_t *block, int stack_offset, int host_reg) { + host_arm64_STR_IMM_F64(block, host_reg, REG_XSP, stack_offset); +} + +void codegen_set_jump_dest(codeblock_t *block, void *p) { host_arm64_branch_set_offset(p, &block_write_data[block_pos]); } #endif diff --git a/src/codegen/codegen.c b/src/codegen/codegen.c index 7cd76b08..fec6cd15 100644 --- a/src/codegen/codegen.c +++ b/src/codegen/codegen.c @@ -16,33 +16,33 @@ #define MAX_INSTRUCTION_COUNT 50 static struct { - uint32_t pc; - int op_ssegs; - x86seg *op_ea_seg; - uint32_t op_32; - int first_uop; - int TOP; + uint32_t pc; + int op_ssegs; + x86seg *op_ea_seg; + uint32_t op_32; + int first_uop; + int TOP; } codegen_instructions[MAX_INSTRUCTION_COUNT]; int codegen_get_instruction_uop(codeblock_t *block, uint32_t pc, int *first_instruction, int *TOP) { - int c; + int c; - for (c = 0; c <= block->ins; c++) { - if (codegen_instructions[c].pc == pc) { - *first_instruction = c; - *TOP = codegen_instructions[c].TOP; - return codegen_instructions[c].first_uop; - } - } + for (c = 0; c <= block->ins; c++) { + if (codegen_instructions[c].pc == pc) { + *first_instruction = c; + *TOP = codegen_instructions[c].TOP; + return codegen_instructions[c].first_uop; + } + } - *first_instruction = block->ins; - return -1; + *first_instruction = block->ins; + return -1; } void codegen_set_loop_start(ir_data_t *ir, int first_instruction) { - uop_MOV_IMM(ir, IREG_op32, codegen_instructions[first_instruction].op_32); - uop_MOV_PTR(ir, IREG_ea_seg, (void *)codegen_instructions[first_instruction].op_ea_seg); - uop_MOV_IMM(ir, IREG_ssegs, codegen_instructions[first_instruction].op_ssegs); + uop_MOV_IMM(ir, IREG_op32, codegen_instructions[first_instruction].op_32); + uop_MOV_PTR(ir, IREG_ea_seg, (void *)codegen_instructions[first_instruction].op_ea_seg); + uop_MOV_IMM(ir, IREG_ssegs, codegen_instructions[first_instruction].op_ssegs); } int has_ea; @@ -58,12 +58,12 @@ void (*codegen_timing_block_end)(); int (*codegen_timing_jump_cycles)(); 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; - codegen_timing_jump_cycles = timing->jump_cycles; + 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; + codegen_timing_jump_cycles = timing->jump_cycles; } int codegen_in_recompile; @@ -73,628 +73,639 @@ static x86seg *last_op_ea_seg; static uint32_t last_op_32; void codegen_generate_reset() { - last_op_ssegs = -1; - last_op_ea_seg = NULL; - last_op_32 = -1; - has_ea = 0; + last_op_ssegs = -1; + last_op_ea_seg = NULL; + last_op_32 = -1; + has_ea = 0; } void codegen_check_seg_read(codeblock_t *block, ir_data_t *ir, x86seg *seg) { - /*Segments always valid in real/V86 mode*/ - if (!(cr0 & 1) || (cpu_state.eflags & VM_FLAG)) - return; - /*CS and SS must always be valid*/ - if (seg == &cpu_state.seg_cs || seg == &cpu_state.seg_ss) - return; - if (seg->checked) - return; - if (seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) - return; + /*Segments always valid in real/V86 mode*/ + if (!(cr0 & 1) || (cpu_state.eflags & VM_FLAG)) + return; + /*CS and SS must always be valid*/ + if (seg == &cpu_state.seg_cs || seg == &cpu_state.seg_ss) + return; + if (seg->checked) + return; + if (seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) + return; - uop_CMP_IMM_JZ(ir, ireg_seg_base(seg), (uint32_t)-1, codegen_gpf_rout); + uop_CMP_IMM_JZ(ir, ireg_seg_base(seg), (uint32_t)-1, codegen_gpf_rout); - seg->checked = 1; + seg->checked = 1; } void codegen_check_seg_write(codeblock_t *block, ir_data_t *ir, x86seg *seg) { - /*Segments always valid in real/V86 mode*/ - if (!(cr0 & 1) || (cpu_state.eflags & VM_FLAG)) - return; - /*CS and SS must always be valid*/ - if (seg == &cpu_state.seg_cs || seg == &cpu_state.seg_ss) - return; - if (seg->checked) - return; - if (seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) - return; + /*Segments always valid in real/V86 mode*/ + if (!(cr0 & 1) || (cpu_state.eflags & VM_FLAG)) + return; + /*CS and SS must always be valid*/ + if (seg == &cpu_state.seg_cs || seg == &cpu_state.seg_ss) + return; + if (seg->checked) + return; + if (seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) + return; - uop_CMP_IMM_JZ(ir, ireg_seg_base(seg), (uint32_t)-1, codegen_gpf_rout); + uop_CMP_IMM_JZ(ir, ireg_seg_base(seg), (uint32_t)-1, codegen_gpf_rout); - seg->checked = 1; + seg->checked = 1; } static x86seg *codegen_generate_ea_16_long(ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc) { - uint32_t old_pc = (*op_pc) + 1; -// pclog("codegen - mod=%i rm=%i reg=%i fetchdat=%08x\n", cpu_mod, cpu_rm, cpu_reg, fetchdat); - if (!cpu_mod && cpu_rm == 6) { - uint16_t addr = (fetchdat >> 8) & 0xffff; - uop_MOV_IMM(ir, IREG_eaaddr, addr); - (*op_pc) += 2; - } else { - int base_reg, index_reg, offset; + uint32_t old_pc = (*op_pc) + 1; + // pclog("codegen - mod=%i rm=%i reg=%i fetchdat=%08x\n", cpu_mod, cpu_rm, cpu_reg, fetchdat); + if (!cpu_mod && cpu_rm == 6) { + uint16_t addr = (fetchdat >> 8) & 0xffff; + uop_MOV_IMM(ir, IREG_eaaddr, addr); + (*op_pc) += 2; + } else { + int base_reg, index_reg, offset; - switch (cpu_rm & 7) { - case 0: - case 1: - case 7:base_reg = IREG_EBX; - break; - case 2: - case 3: - case 6:base_reg = IREG_EBP; - break; - case 4:base_reg = IREG_ESI; - break; - case 5:base_reg = IREG_EDI; - break; - } - uop_MOV(ir, IREG_eaaddr, base_reg); + switch (cpu_rm & 7) { + case 0: + case 1: + case 7: + base_reg = IREG_EBX; + break; + case 2: + case 3: + case 6: + base_reg = IREG_EBP; + break; + case 4: + base_reg = IREG_ESI; + break; + case 5: + base_reg = IREG_EDI; + break; + } + uop_MOV(ir, IREG_eaaddr, base_reg); - if (!(cpu_rm & 4)) { - if (!(cpu_rm & 1)) - index_reg = IREG_ESI; - else - index_reg = IREG_EDI; + if (!(cpu_rm & 4)) { + if (!(cpu_rm & 1)) + index_reg = IREG_ESI; + else + index_reg = IREG_EDI; - uop_ADD(ir, IREG_eaaddr, IREG_eaaddr, index_reg); - } + uop_ADD(ir, IREG_eaaddr, IREG_eaaddr, index_reg); + } - switch (cpu_mod) { - case 1:offset = (int)(int8_t)((fetchdat >> 8) & 0xff); - uop_ADD_IMM(ir, IREG_eaaddr, IREG_eaaddr, offset); - (*op_pc)++; - break; - case 2:offset = (fetchdat >> 8) & 0xffff; - uop_ADD_IMM(ir, IREG_eaaddr, IREG_eaaddr, offset); - (*op_pc) += 2; - break; - } + switch (cpu_mod) { + case 1: + offset = (int)(int8_t)((fetchdat >> 8) & 0xff); + uop_ADD_IMM(ir, IREG_eaaddr, IREG_eaaddr, offset); + (*op_pc)++; + break; + case 2: + offset = (fetchdat >> 8) & 0xffff; + uop_ADD_IMM(ir, IREG_eaaddr, IREG_eaaddr, offset); + (*op_pc) += 2; + break; + } - uop_AND_IMM(ir, IREG_eaaddr, IREG_eaaddr, 0xffff); + uop_AND_IMM(ir, IREG_eaaddr, IREG_eaaddr, 0xffff); - if (mod1seg[cpu_rm] == &ss && !op_ssegs) { - op_ea_seg = &cpu_state.seg_ss; - } - } + if (mod1seg[cpu_rm] == &ss && !op_ssegs) { + op_ea_seg = &cpu_state.seg_ss; + } + } - codegen_mark_code_present(ir->block, cs + old_pc, ((*op_pc) + 1) - old_pc); - return op_ea_seg; + codegen_mark_code_present(ir->block, cs + old_pc, ((*op_pc) + 1) - old_pc); + return op_ea_seg; } -static x86seg *codegen_generate_ea_32_long(ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, int stack_offset) { - codeblock_t *block = ir->block; - uint32_t old_pc = (*op_pc) + 1; - uint32_t new_eaaddr; - int extra_bytes = 0; +static x86seg *codegen_generate_ea_32_long(ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, + int stack_offset) { + codeblock_t *block = ir->block; + uint32_t old_pc = (*op_pc) + 1; + uint32_t new_eaaddr; + int extra_bytes = 0; - if (cpu_rm == 4) { - uint8_t sib = fetchdat >> 8; - (*op_pc)++; + if (cpu_rm == 4) { + uint8_t sib = fetchdat >> 8; + (*op_pc)++; - switch (cpu_mod) { - case 0: - if ((sib & 7) == 5) { - if (block->flags & CODEBLOCK_NO_IMMEDIATES) { - LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_eaaddr, cs + (*op_pc) + 1); - extra_bytes = 1; - } else { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - uop_MOV_IMM(ir, IREG_eaaddr, new_eaaddr); - extra_bytes = 5; - } - (*op_pc) += 4; - } else { - uop_MOV(ir, IREG_eaaddr, sib & 7); - extra_bytes = 1; - } - break; - case 1:new_eaaddr = (uint32_t)(int8_t)((fetchdat >> 16) & 0xff); - uop_MOV_IMM(ir, IREG_eaaddr, new_eaaddr); - uop_ADD(ir, IREG_eaaddr, IREG_eaaddr, sib & 7); - (*op_pc)++; - extra_bytes = 2; - break; - case 2: - if (block->flags & CODEBLOCK_NO_IMMEDIATES) { - LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_eaaddr, cs + (*op_pc) + 1); - extra_bytes = 1; - } else { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - uop_MOV_IMM(ir, IREG_eaaddr, new_eaaddr); - extra_bytes = 5; - } - (*op_pc) += 4; - uop_ADD(ir, IREG_eaaddr, IREG_eaaddr, sib & 7); - break; - } - if (stack_offset && (sib & 7) == 4 && (cpu_mod || (sib & 7) != 5)) /*ESP*/ - { - uop_ADD_IMM(ir, IREG_eaaddr, IREG_eaaddr, stack_offset); -// addbyte(0x05); -// addlong(stack_offset); - } - if (((sib & 7) == 4 || (cpu_mod && (sib & 7) == 5)) && !op_ssegs) - op_ea_seg = &cpu_state.seg_ss; - if (((sib >> 3) & 7) != 4) { - switch (sib >> 6) { - case 0:uop_ADD(ir, IREG_eaaddr, IREG_eaaddr, (sib >> 3) & 7); - break; - case 1:uop_ADD_LSHIFT(ir, IREG_eaaddr, IREG_eaaddr, (sib >> 3) & 7, 1); - break; - case 2:uop_ADD_LSHIFT(ir, IREG_eaaddr, IREG_eaaddr, (sib >> 3) & 7, 2); - break; - case 3:uop_ADD_LSHIFT(ir, IREG_eaaddr, IREG_eaaddr, (sib >> 3) & 7, 3); - break; - } - } - } else { - if (!cpu_mod && cpu_rm == 5) { - if (block->flags & CODEBLOCK_NO_IMMEDIATES) { - LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_eaaddr, cs + (*op_pc) + 1); - } else { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - uop_MOV_IMM(ir, IREG_eaaddr, new_eaaddr); - extra_bytes = 4; - } + switch (cpu_mod) { + case 0: + if ((sib & 7) == 5) { + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_eaaddr, cs + (*op_pc) + 1); + extra_bytes = 1; + } else { + new_eaaddr = fastreadl(cs + (*op_pc) + 1); + uop_MOV_IMM(ir, IREG_eaaddr, new_eaaddr); + extra_bytes = 5; + } + (*op_pc) += 4; + } else { + uop_MOV(ir, IREG_eaaddr, sib & 7); + extra_bytes = 1; + } + break; + case 1: + new_eaaddr = (uint32_t)(int8_t)((fetchdat >> 16) & 0xff); + uop_MOV_IMM(ir, IREG_eaaddr, new_eaaddr); + uop_ADD(ir, IREG_eaaddr, IREG_eaaddr, sib & 7); + (*op_pc)++; + extra_bytes = 2; + break; + case 2: + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_eaaddr, cs + (*op_pc) + 1); + extra_bytes = 1; + } else { + new_eaaddr = fastreadl(cs + (*op_pc) + 1); + uop_MOV_IMM(ir, IREG_eaaddr, new_eaaddr); + extra_bytes = 5; + } + (*op_pc) += 4; + uop_ADD(ir, IREG_eaaddr, IREG_eaaddr, sib & 7); + break; + } + if (stack_offset && (sib & 7) == 4 && (cpu_mod || (sib & 7) != 5)) /*ESP*/ + { + uop_ADD_IMM(ir, IREG_eaaddr, IREG_eaaddr, stack_offset); + // addbyte(0x05); + // addlong(stack_offset); + } + if (((sib & 7) == 4 || (cpu_mod && (sib & 7) == 5)) && !op_ssegs) + op_ea_seg = &cpu_state.seg_ss; + if (((sib >> 3) & 7) != 4) { + switch (sib >> 6) { + case 0: + uop_ADD(ir, IREG_eaaddr, IREG_eaaddr, (sib >> 3) & 7); + break; + case 1: + uop_ADD_LSHIFT(ir, IREG_eaaddr, IREG_eaaddr, (sib >> 3) & 7, 1); + break; + case 2: + uop_ADD_LSHIFT(ir, IREG_eaaddr, IREG_eaaddr, (sib >> 3) & 7, 2); + break; + case 3: + uop_ADD_LSHIFT(ir, IREG_eaaddr, IREG_eaaddr, (sib >> 3) & 7, 3); + break; + } + } + } else { + if (!cpu_mod && cpu_rm == 5) { + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_eaaddr, cs + (*op_pc) + 1); + } else { + new_eaaddr = fastreadl(cs + (*op_pc) + 1); + uop_MOV_IMM(ir, IREG_eaaddr, new_eaaddr); + extra_bytes = 4; + } - (*op_pc) += 4; - } else { - uop_MOV(ir, IREG_eaaddr, cpu_rm); - if (cpu_mod) { - if (cpu_rm == 5 && !op_ssegs) - op_ea_seg = &cpu_state.seg_ss; - if (cpu_mod == 1) { - uop_ADD_IMM(ir, IREG_eaaddr, IREG_eaaddr, (uint32_t)(int8_t)(fetchdat >> 8)); - (*op_pc)++; - extra_bytes = 1; - } else { - if (block->flags & CODEBLOCK_NO_IMMEDIATES) { - LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + (*op_pc) + 1); - uop_ADD(ir, IREG_eaaddr, IREG_eaaddr, IREG_temp0); - } else { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - uop_ADD_IMM(ir, IREG_eaaddr, IREG_eaaddr, new_eaaddr); - extra_bytes = 4; - } - (*op_pc) += 4; - } - } - } - } + (*op_pc) += 4; + } else { + uop_MOV(ir, IREG_eaaddr, cpu_rm); + if (cpu_mod) { + if (cpu_rm == 5 && !op_ssegs) + op_ea_seg = &cpu_state.seg_ss; + if (cpu_mod == 1) { + uop_ADD_IMM(ir, IREG_eaaddr, IREG_eaaddr, (uint32_t)(int8_t)(fetchdat >> 8)); + (*op_pc)++; + extra_bytes = 1; + } else { + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + (*op_pc) + 1); + uop_ADD(ir, IREG_eaaddr, IREG_eaaddr, IREG_temp0); + } else { + new_eaaddr = fastreadl(cs + (*op_pc) + 1); + uop_ADD_IMM(ir, IREG_eaaddr, IREG_eaaddr, new_eaaddr); + extra_bytes = 4; + } + (*op_pc) += 4; + } + } + } + } - if (extra_bytes) - codegen_mark_code_present(ir->block, cs + old_pc, extra_bytes); + if (extra_bytes) + codegen_mark_code_present(ir->block, cs + old_pc, extra_bytes); - return op_ea_seg; + return op_ea_seg; } -x86seg *codegen_generate_ea(ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, uint32_t op_32, int stack_offset) { - cpu_mod = (fetchdat >> 6) & 3; - cpu_reg = (fetchdat >> 3) & 7; - cpu_rm = fetchdat & 7; +x86seg *codegen_generate_ea(ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, uint32_t op_32, + int stack_offset) { + cpu_mod = (fetchdat >> 6) & 3; + cpu_reg = (fetchdat >> 3) & 7; + cpu_rm = fetchdat & 7; - if ((fetchdat & 0xc0) == 0xc0) - return NULL; - if (op_32 & 0x200) - return codegen_generate_ea_32_long(ir, op_ea_seg, fetchdat, op_ssegs, op_pc, stack_offset); + if ((fetchdat & 0xc0) == 0xc0) + return NULL; + if (op_32 & 0x200) + return codegen_generate_ea_32_long(ir, op_ea_seg, fetchdat, op_ssegs, op_pc, stack_offset); - return codegen_generate_ea_16_long(ir, op_ea_seg, fetchdat, op_ssegs, op_pc); + return codegen_generate_ea_16_long(ir, op_ea_seg, fetchdat, op_ssegs, op_pc); } -static uint8_t 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*/ +static uint8_t 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*/ + 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, 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*/ - }; -static uint8_t opcode_0f_modrm[256] = - { - 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, /*00*/ - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, /*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, 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*/ +}; +static uint8_t opcode_0f_modrm[256] = { + 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, /*00*/ + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, /*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*/ + 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, 0, 1, /*a0*/ - 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, /*b0*/ + 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, 0, 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*/ - }; + 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_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_pc, uint32_t old_pc) { - codeblock_t *block = &codeblock[block_current]; - ir_data_t *ir = codegen_get_ir_data(); - 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; - uint32_t recomp_opcode_mask = 0x1ff; - uint32_t op_32 = use32; - int over = 0; - int test_modrm = 1; - int pc_off = 0; - uint32_t next_pc = 0; + codeblock_t *block = &codeblock[block_current]; + ir_data_t *ir = codegen_get_ir_data(); + 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; + uint32_t recomp_opcode_mask = 0x1ff; + uint32_t op_32 = use32; + int over = 0; + int test_modrm = 1; + int pc_off = 0; + uint32_t next_pc = 0; #ifdef DEBUG_EXTRA - uint8_t last_prefix = 0; + uint8_t last_prefix = 0; #endif - op_ea_seg = &cpu_state.seg_ds; - op_ssegs = 0; + op_ea_seg = &cpu_state.seg_ds; + op_ssegs = 0; - codegen_timing_start(); + codegen_timing_start(); - while (!over) { - switch (opcode) { - case 0x0f: + while (!over) { + switch (opcode) { + case 0x0f: #ifdef DEBUG_EXTRA - last_prefix = 0x0f; + last_prefix = 0x0f; #endif - op_table = x86_dynarec_opcodes_0f; - recomp_op_table = recomp_opcodes_0f; - over = 1; - break; + op_table = x86_dynarec_opcodes_0f; + recomp_op_table = recomp_opcodes_0f; + over = 1; + break; - case 0x26: /*ES:*/ - op_ea_seg = &cpu_state.seg_es; - op_ssegs = 1; - break; - case 0x2e: /*CS:*/ - op_ea_seg = &cpu_state.seg_cs; - op_ssegs = 1; - break; - case 0x36: /*SS:*/ - op_ea_seg = &cpu_state.seg_ss; - op_ssegs = 1; - break; - case 0x3e: /*DS:*/ - op_ea_seg = &cpu_state.seg_ds; - op_ssegs = 1; - break; - case 0x64: /*FS:*/ - op_ea_seg = &cpu_state.seg_fs; - op_ssegs = 1; - break; - case 0x65: /*GS:*/ - op_ea_seg = &cpu_state.seg_gs; - op_ssegs = 1; - break; + case 0x26: /*ES:*/ + op_ea_seg = &cpu_state.seg_es; + op_ssegs = 1; + break; + case 0x2e: /*CS:*/ + op_ea_seg = &cpu_state.seg_cs; + op_ssegs = 1; + break; + case 0x36: /*SS:*/ + op_ea_seg = &cpu_state.seg_ss; + op_ssegs = 1; + break; + case 0x3e: /*DS:*/ + op_ea_seg = &cpu_state.seg_ds; + op_ssegs = 1; + break; + case 0x64: /*FS:*/ + op_ea_seg = &cpu_state.seg_fs; + op_ssegs = 1; + break; + case 0x65: /*GS:*/ + op_ea_seg = &cpu_state.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 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: + case 0xd8: #ifdef DEBUG_EXTRA - last_prefix = 0xd8; + last_prefix = 0xd8; #endif - 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_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: #ifdef DEBUG_EXTRA - last_prefix = 0xd9; + last_prefix = 0xd9; #endif - 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_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: #ifdef DEBUG_EXTRA - last_prefix = 0xda; + last_prefix = 0xda; #endif - 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_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: #ifdef DEBUG_EXTRA - last_prefix = 0xdb; + last_prefix = 0xdb; #endif - 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_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: #ifdef DEBUG_EXTRA - last_prefix = 0xdc; + last_prefix = 0xdc; #endif - 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_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: #ifdef DEBUG_EXTRA - last_prefix = 0xdd; + last_prefix = 0xdd; #endif - 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_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: #ifdef DEBUG_EXTRA - last_prefix = 0xde; + last_prefix = 0xde; #endif - 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_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: #ifdef DEBUG_EXTRA - last_prefix = 0xdf; + last_prefix = 0xdf; #endif - 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; + 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 0xf0: /*LOCK*/ + break; - case 0xf2: /*REPNE*/ + case 0xf2: /*REPNE*/ #ifdef DEBUG_EXTRA - last_prefix = 0xf2; + last_prefix = 0xf2; #endif - op_table = x86_dynarec_opcodes_REPNE; - recomp_op_table = NULL;//recomp_opcodes_REPNE; - break; - case 0xf3: /*REPE*/ + op_table = x86_dynarec_opcodes_REPNE; + recomp_op_table = NULL; // recomp_opcodes_REPNE; + break; + case 0xf3: /*REPE*/ #ifdef DEBUG_EXTRA - last_prefix = 0xf3; + last_prefix = 0xf3; #endif - op_table = x86_dynarec_opcodes_REPE; - recomp_op_table = NULL;//recomp_opcodes_REPE; - break; + op_table = x86_dynarec_opcodes_REPE; + recomp_op_table = NULL; // 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; + 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++; - } + op_pc++; + } - generate_call: - codegen_instructions[block->ins].pc = cpu_state.oldpc; - codegen_instructions[block->ins].op_ssegs = last_op_ssegs; - codegen_instructions[block->ins].op_ea_seg = last_op_ea_seg; - codegen_instructions[block->ins].op_32 = last_op_32; - codegen_instructions[block->ins].TOP = cpu_state.TOP; - codegen_instructions[block->ins].first_uop = ir->wr_pos; +generate_call: + codegen_instructions[block->ins].pc = cpu_state.oldpc; + codegen_instructions[block->ins].op_ssegs = last_op_ssegs; + codegen_instructions[block->ins].op_ea_seg = last_op_ea_seg; + codegen_instructions[block->ins].op_32 = last_op_32; + codegen_instructions[block->ins].TOP = cpu_state.TOP; + codegen_instructions[block->ins].first_uop = ir->wr_pos; - codegen_timing_opcode(opcode, fetchdat, op_32, op_pc); + codegen_timing_opcode(opcode, fetchdat, op_32, op_pc); - codegen_accumulate(ACCREG_ins, 1); - codegen_accumulate(ACCREG_cycles, -codegen_block_cycles); - codegen_block_cycles = 0; + codegen_accumulate(ACCREG_ins, 1); + codegen_accumulate(ACCREG_cycles, -codegen_block_cycles); + codegen_block_cycles = 0; - 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))) { - /*On some CPUs (eg K6), a jump/branch instruction may be able to pair with - subsequent instructions, so no cycles may have been deducted for it yet. - To prevent having zero cycle blocks (eg with a jump instruction pointing - to itself), apply the cycles that would be taken if this jump is taken, - then reverse it for subsequent instructions if the jump is not taken*/ - int jump_cycles = codegen_timing_jump_cycles(); + 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))) { + /*On some CPUs (eg K6), a jump/branch instruction may be able to pair with + subsequent instructions, so no cycles may have been deducted for it yet. + To prevent having zero cycle blocks (eg with a jump instruction pointing + to itself), apply the cycles that would be taken if this jump is taken, + then reverse it for subsequent instructions if the jump is not taken*/ + int jump_cycles = codegen_timing_jump_cycles(); - if (jump_cycles) - codegen_accumulate(ACCREG_cycles, -jump_cycles); - codegen_accumulate_flush(ir); - if (jump_cycles) - codegen_accumulate(ACCREG_cycles, jump_cycles); - } + if (jump_cycles) + codegen_accumulate(ACCREG_cycles, -jump_cycles); + codegen_accumulate_flush(ir); + if (jump_cycles) + codegen_accumulate(ACCREG_cycles, jump_cycles); + } - if (op_table == x86_dynarec_opcodes_0f && opcode == 0x0f) { - /*3DNow opcodes are stored after ModR/M, SIB and any offset*/ - uint8_t modrm = fetchdat & 0xff; - uint8_t sib = (fetchdat >> 8) & 0xff; - uint32_t opcode_pc = op_pc + 1; - uint8_t opcode_3dnow; + if (op_table == x86_dynarec_opcodes_0f && opcode == 0x0f) { + /*3DNow opcodes are stored after ModR/M, SIB and any offset*/ + uint8_t modrm = fetchdat & 0xff; + uint8_t sib = (fetchdat >> 8) & 0xff; + uint32_t opcode_pc = op_pc + 1; + uint8_t opcode_3dnow; - if ((modrm & 0xc0) != 0xc0) { - if (op_32 & 0x200) { - if ((modrm & 7) == 4) { - /* Has SIB*/ - opcode_pc++; - if ((modrm & 0xc0) == 0x40) - opcode_pc++; - else if ((modrm & 0xc0) == 0x80) - opcode_pc += 4; - else if ((sib & 0x07) == 0x05) - opcode_pc += 4; - } else { - if ((modrm & 0xc0) == 0x40) - opcode_pc++; - else if ((modrm & 0xc0) == 0x80) - opcode_pc += 4; - else if ((modrm & 0xc7) == 0x05) - opcode_pc += 4; - } - } else { - if ((modrm & 0xc0) == 0x40) - opcode_pc++; - else if ((modrm & 0xc0) == 0x80) - opcode_pc += 2; - else if ((modrm & 0xc7) == 0x06) - opcode_pc += 2; - } - } + if ((modrm & 0xc0) != 0xc0) { + if (op_32 & 0x200) { + if ((modrm & 7) == 4) { + /* Has SIB*/ + opcode_pc++; + if ((modrm & 0xc0) == 0x40) + opcode_pc++; + else if ((modrm & 0xc0) == 0x80) + opcode_pc += 4; + else if ((sib & 0x07) == 0x05) + opcode_pc += 4; + } else { + if ((modrm & 0xc0) == 0x40) + opcode_pc++; + else if ((modrm & 0xc0) == 0x80) + opcode_pc += 4; + else if ((modrm & 0xc7) == 0x05) + opcode_pc += 4; + } + } else { + if ((modrm & 0xc0) == 0x40) + opcode_pc++; + else if ((modrm & 0xc0) == 0x80) + opcode_pc += 2; + else if ((modrm & 0xc7) == 0x06) + opcode_pc += 2; + } + } - opcode_3dnow = fastreadb(cs + opcode_pc); -// pclog("recomp_opcodes_3DNOW[%02x]=%p\n", opcode, recomp_opcodes_3DNOW[opcode]); - if (recomp_opcodes_3DNOW[opcode_3dnow]) { - next_pc = opcode_pc + 1; + opcode_3dnow = fastreadb(cs + opcode_pc); + // pclog("recomp_opcodes_3DNOW[%02x]=%p\n", opcode, recomp_opcodes_3DNOW[opcode]); + if (recomp_opcodes_3DNOW[opcode_3dnow]) { + next_pc = opcode_pc + 1; - op_table = x86_dynarec_opcodes_3DNOW; - recomp_op_table = recomp_opcodes_3DNOW; - opcode = opcode_3dnow; - recomp_opcode_mask = 0xff; - opcode_mask = 0xff; - } - } - codegen_mark_code_present(block, cs + old_pc, (op_pc - old_pc) - pc_off); -// pclog("%04x:%08x : %02x\n", CS, new_pc, opcode); - if (recomp_op_table && recomp_op_table[(opcode | op_32) & recomp_opcode_mask]) { - uint32_t new_pc = recomp_op_table[(opcode | op_32) & recomp_opcode_mask](block, ir, opcode, fetchdat, op_32, op_pc); - if (new_pc) { - if (new_pc != -1) - uop_MOV_IMM(ir, IREG_pc, new_pc); + op_table = x86_dynarec_opcodes_3DNOW; + recomp_op_table = recomp_opcodes_3DNOW; + opcode = opcode_3dnow; + recomp_opcode_mask = 0xff; + opcode_mask = 0xff; + } + } + codegen_mark_code_present(block, cs + old_pc, (op_pc - old_pc) - pc_off); + // pclog("%04x:%08x : %02x\n", CS, new_pc, opcode); + if (recomp_op_table && recomp_op_table[(opcode | op_32) & recomp_opcode_mask]) { + uint32_t new_pc = + recomp_op_table[(opcode | op_32) & recomp_opcode_mask](block, ir, opcode, fetchdat, op_32, op_pc); + if (new_pc) { + if (new_pc != -1) + uop_MOV_IMM(ir, IREG_pc, new_pc); - codegen_endpc = (cs + cpu_state.pc) + 8; + codegen_endpc = (cs + cpu_state.pc) + 8; - block->ins++; + block->ins++; - if (block->ins >= MAX_INSTRUCTION_COUNT) - CPU_BLOCK_END(); + if (block->ins >= MAX_INSTRUCTION_COUNT) + CPU_BLOCK_END(); - return; - } - } + return; + } + } - 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 ((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; + } - op = op_table[((opcode >> opcode_shift) | op_32) & opcode_mask]; + op = op_table[((opcode >> opcode_shift) | op_32) & opcode_mask]; - if (!test_modrm || - (op_table == x86_dynarec_opcodes && opcode_modrm[opcode]) || - (op_table == x86_dynarec_opcodes_0f && opcode_0f_modrm[opcode]) || - (op_table == x86_dynarec_opcodes_3DNOW)) { - int stack_offset = 0; + if (!test_modrm || (op_table == x86_dynarec_opcodes && opcode_modrm[opcode]) || + (op_table == x86_dynarec_opcodes_0f && opcode_0f_modrm[opcode]) || (op_table == x86_dynarec_opcodes_3DNOW)) { + int stack_offset = 0; - if (op_table == x86_dynarec_opcodes && opcode == 0x8f) /*POP*/ - stack_offset = (op_32 & 0x100) ? 4 : 2; + 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; + cpu_mod = (fetchdat >> 6) & 3; + cpu_reg = (fetchdat >> 3) & 7; + cpu_rm = fetchdat & 7; - uop_MOV_IMM(ir, IREG_rm_mod_reg, cpu_rm | (cpu_mod << 8) | (cpu_reg << 16)); + uop_MOV_IMM(ir, IREG_rm_mod_reg, 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(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc); -// has_ea = 1; - } - if (cpu_mod != 3 && (op_32 & 0x200)) { - op_ea_seg = codegen_generate_ea_32_long(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, stack_offset); -// has_ea = 1; - } -// op_ea_seg = codegen_generate_ea_32_long(op_ea_seg, fetchdat, op_ssegs, &op_pc, stack_offset); - op_pc -= pc_off; - } + op_pc += pc_off; + if (cpu_mod != 3 && !(op_32 & 0x200)) { + op_ea_seg = codegen_generate_ea_16_long(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc); + // has_ea = 1; + } + if (cpu_mod != 3 && (op_32 & 0x200)) { + op_ea_seg = codegen_generate_ea_32_long(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, stack_offset); + // has_ea = 1; + } + // op_ea_seg = codegen_generate_ea_32_long(op_ea_seg, fetchdat, op_ssegs, &op_pc, + // stack_offset); + op_pc -= pc_off; + } #ifdef DEBUG_EXTRA - uop_LOG_INSTR(ir, opcode | (last_prefix << 8)); + uop_LOG_INSTR(ir, opcode | (last_prefix << 8)); #endif - codegen_accumulate_flush(ir); - if (op_table == x86_dynarec_opcodes_3DNOW) - uop_MOV_IMM(ir, IREG_pc, next_pc); - else - uop_MOV_IMM(ir, IREG_pc, op_pc + pc_off); - uop_MOV_IMM(ir, IREG_oldpc, old_pc); - if (op_32 != last_op_32) - uop_MOV_IMM(ir, IREG_op32, op_32); - if (op_ea_seg != last_op_ea_seg) - uop_MOV_PTR(ir, IREG_ea_seg, (void *)op_ea_seg); - if (op_ssegs != last_op_ssegs) - uop_MOV_IMM(ir, IREG_ssegs, op_ssegs); - uop_LOAD_FUNC_ARG_IMM(ir, 0, fetchdat); - uop_CALL_INSTRUCTION_FUNC(ir, op); - codegen_mark_code_present(block, cs + cpu_state.pc, 8); + codegen_accumulate_flush(ir); + if (op_table == x86_dynarec_opcodes_3DNOW) + uop_MOV_IMM(ir, IREG_pc, next_pc); + else + uop_MOV_IMM(ir, IREG_pc, op_pc + pc_off); + uop_MOV_IMM(ir, IREG_oldpc, old_pc); + if (op_32 != last_op_32) + uop_MOV_IMM(ir, IREG_op32, op_32); + if (op_ea_seg != last_op_ea_seg) + uop_MOV_PTR(ir, IREG_ea_seg, (void *)op_ea_seg); + if (op_ssegs != last_op_ssegs) + uop_MOV_IMM(ir, IREG_ssegs, op_ssegs); + uop_LOAD_FUNC_ARG_IMM(ir, 0, fetchdat); + uop_CALL_INSTRUCTION_FUNC(ir, op); + codegen_mark_code_present(block, cs + cpu_state.pc, 8); - last_op_32 = op_32; - last_op_ea_seg = op_ea_seg; - last_op_ssegs = op_ssegs; - //codegen_block_ins++; + last_op_32 = op_32; + last_op_ea_seg = op_ea_seg; + last_op_ssegs = op_ssegs; + // codegen_block_ins++; - block->ins++; + block->ins++; - if (block->ins >= MAX_INSTRUCTION_COUNT) - CPU_BLOCK_END(); + if (block->ins >= MAX_INSTRUCTION_COUNT) + CPU_BLOCK_END(); - codegen_endpc = (cs + cpu_state.pc) + 8; + codegen_endpc = (cs + cpu_state.pc) + 8; -// if (has_ea) -// fatal("Has EA\n"); + // if (has_ea) + // fatal("Has EA\n"); } diff --git a/src/codegen/codegen_accumulate.c b/src/codegen/codegen_accumulate.c index 1f3da394..beefb704 100644 --- a/src/codegen/codegen_accumulate.c +++ b/src/codegen/codegen_accumulate.c @@ -4,40 +4,40 @@ #include "codegen_ir.h" static struct { - int count; - int dest_reg; -} acc_regs[] = - { - [ACCREG_ins] = {0, IREG_ins}, - [ACCREG_cycles] = {0, IREG_cycles}, - }; + int count; + int dest_reg; +} acc_regs[] = { + [ACCREG_ins] = {0, IREG_ins}, + [ACCREG_cycles] = {0, IREG_cycles}, +}; void codegen_accumulate(int acc_reg, int delta) { - if (acc_reg == ACCREG_cycles) { -// pclog("cycles %04x:%04x %i\n", CS, cpu_state.pc, delta); -// if (CS == 0x1000 && cpu_state.pc == 0x863) -// fatal("Here\n"); - } - acc_regs[acc_reg].count += delta; + if (acc_reg == ACCREG_cycles) { + // pclog("cycles %04x:%04x %i\n", CS, cpu_state.pc, delta); + // if (CS == 0x1000 && cpu_state.pc == 0x863) + // fatal("Here\n"); + } + acc_regs[acc_reg].count += delta; } void codegen_accumulate_flush(ir_data_t *ir) { - int c; + int c; - for (c = 0; c < ACCREG_COUNT; c++) { - if (acc_regs[c].count) { -// if (c == ACCREG_cycles) -// pclog("accumulate %i %i %i\n", c, acc_regs[c].dest_reg, acc_regs[c].count); - uop_ADD_IMM(ir, acc_regs[c].dest_reg, acc_regs[c].dest_reg, acc_regs[c].count); - } + for (c = 0; c < ACCREG_COUNT; c++) { + if (acc_regs[c].count) { + // if (c == ACCREG_cycles) + // pclog("accumulate %i %i %i\n", c, acc_regs[c].dest_reg, + // acc_regs[c].count); + uop_ADD_IMM(ir, acc_regs[c].dest_reg, acc_regs[c].dest_reg, acc_regs[c].count); + } - acc_regs[c].count = 0; - } + acc_regs[c].count = 0; + } } void codegen_accumulate_reset() { - int c; + int c; - for (c = 0; c < ACCREG_COUNT; c++) - acc_regs[c].count = 0; + for (c = 0; c < ACCREG_COUNT; c++) + acc_regs[c].count = 0; } diff --git a/src/codegen/codegen_allocator.c b/src/codegen/codegen_allocator.c index 198ad38c..49d3f910 100644 --- a/src/codegen/codegen_allocator.c +++ b/src/codegen/codegen_allocator.c @@ -12,9 +12,9 @@ #include "codegen_allocator.h" typedef struct mem_block_t { - uint32_t offset; /*Offset into mem_block_alloc*/ - uint32_t next; - uint16_t code_block; + uint32_t offset; /*Offset into mem_block_alloc*/ + uint32_t next; + uint16_t code_block; } mem_block_t; static mem_block_t mem_blocks[MEM_BLOCK_NR]; @@ -24,97 +24,95 @@ static uint8_t *mem_block_alloc = NULL; int codegen_allocator_usage = 0; void codegen_allocator_init() { - int c; + int c; #if defined WIN32 || defined _WIN32 || defined _WIN32 - mem_block_alloc = VirtualAlloc(NULL, MEM_BLOCK_NR * MEM_BLOCK_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE); - /* TODO: check deployment target: older Intel-based versions of macOS don't play - nice with MAP_JIT. */ + mem_block_alloc = VirtualAlloc(NULL, MEM_BLOCK_NR * MEM_BLOCK_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE); + /* TODO: check deployment target: older Intel-based versions of macOS don't play + nice with MAP_JIT. */ #elif defined(__APPLE__) && defined(MAP_JIT) - mem_block_alloc = mmap(0, MEM_BLOCK_NR * MEM_BLOCK_SIZE, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE|MAP_JIT, 0, 0); + mem_block_alloc = mmap(0, MEM_BLOCK_NR * MEM_BLOCK_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_ANON | MAP_PRIVATE | MAP_JIT, 0, 0); #else - mem_block_alloc = mmap(0, MEM_BLOCK_NR * MEM_BLOCK_SIZE, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, 0, 0); + mem_block_alloc = + mmap(0, MEM_BLOCK_NR * MEM_BLOCK_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE, 0, 0); #endif - for (c = 0; c < MEM_BLOCK_NR; c++) { - mem_blocks[c].offset = c * MEM_BLOCK_SIZE; - mem_blocks[c].code_block = BLOCK_INVALID; - if (c < MEM_BLOCK_NR - 1) - mem_blocks[c].next = c + 2; - else - mem_blocks[c].next = 0; - } - mem_block_free_list = 1; + for (c = 0; c < MEM_BLOCK_NR; c++) { + mem_blocks[c].offset = c * MEM_BLOCK_SIZE; + mem_blocks[c].code_block = BLOCK_INVALID; + if (c < MEM_BLOCK_NR - 1) + mem_blocks[c].next = c + 2; + else + mem_blocks[c].next = 0; + } + mem_block_free_list = 1; } mem_block_t *codegen_allocator_allocate(mem_block_t *parent, int code_block) { - mem_block_t *block; - uint32_t block_nr; + mem_block_t *block; + uint32_t block_nr; - while (!mem_block_free_list) { - /*Pick a random memory block and free the owning code block*/ - block_nr = rand() & MEM_BLOCK_MASK; - block = &mem_blocks[block_nr]; + while (!mem_block_free_list) { + /*Pick a random memory block and free the owning code block*/ + block_nr = rand() & MEM_BLOCK_MASK; + block = &mem_blocks[block_nr]; - if (block->code_block && block->code_block != code_block) - codegen_delete_block(&codeblock[block->code_block]); - } -// fatal("codegen_allocator_allocate: free list empty!\n"); + if (block->code_block && block->code_block != code_block) + codegen_delete_block(&codeblock[block->code_block]); + } + // fatal("codegen_allocator_allocate: free list empty!\n"); - /*Remove from free list*/ - block_nr = mem_block_free_list; - block = &mem_blocks[block_nr - 1]; - mem_block_free_list = block->next; + /*Remove from free list*/ + block_nr = mem_block_free_list; + block = &mem_blocks[block_nr - 1]; + mem_block_free_list = block->next; - block->code_block = code_block; - if (parent) { - /*Add to parent list*/ - block->next = parent->next; - parent->next = block_nr; - } else - block->next = 0; + block->code_block = code_block; + if (parent) { + /*Add to parent list*/ + block->next = parent->next; + parent->next = block_nr; + } else + block->next = 0; - codegen_allocator_usage++; -/* if (parent) - pclog("codegen_allocator_allocate with parent: %p %i %i %p\n", block, block_nr, codegen_allocator_usage, parent); - else - pclog("codegen_allocator_allocate: %p %i %i\n", block, block_nr, codegen_allocator_usage);*/ - return block; + codegen_allocator_usage++; + /* if (parent) + pclog("codegen_allocator_allocate with parent: %p %i %i %p\n", block, block_nr, codegen_allocator_usage, + parent); else pclog("codegen_allocator_allocate: %p %i %i\n", block, block_nr, codegen_allocator_usage);*/ + return block; } void codegen_allocator_free(mem_block_t *block) { - int block_nr = (((uintptr_t)block - (uintptr_t)mem_blocks) / sizeof(mem_block_t)) + 1; + int block_nr = (((uintptr_t)block - (uintptr_t)mem_blocks) / sizeof(mem_block_t)) + 1; -// pclog("codegen_allocator_free: %p %i %i %i\n", block, block_nr, codegen_allocator_usage, block->next); - while (1) { - int next_block_nr = block->next; -// pclog(" free next=%i\n", next_block_nr); - codegen_allocator_usage--; + // pclog("codegen_allocator_free: %p %i %i %i\n", block, block_nr, codegen_allocator_usage, block->next); + while (1) { + int next_block_nr = block->next; + // pclog(" free next=%i\n", next_block_nr); + codegen_allocator_usage--; - block->next = mem_block_free_list; - block->code_block = BLOCK_INVALID; - mem_block_free_list = block_nr; - block_nr = next_block_nr; + block->next = mem_block_free_list; + block->code_block = BLOCK_INVALID; + mem_block_free_list = block_nr; + block_nr = next_block_nr; - if (block_nr) - block = &mem_blocks[block_nr - 1]; - else - break; - } + if (block_nr) + block = &mem_blocks[block_nr - 1]; + else + break; + } } -uint8_t *codeblock_allocator_get_ptr(mem_block_t *block) { - return &mem_block_alloc[block->offset]; -} +uint8_t *codeblock_allocator_get_ptr(mem_block_t *block) { return &mem_block_alloc[block->offset]; } void codegen_allocator_clean_blocks(struct mem_block_t *block) { #if defined __ARM_EABI__ || defined __aarch64__ - while (1) - { - __clear_cache(&mem_block_alloc[block->offset], &mem_block_alloc[block->offset + MEM_BLOCK_SIZE]); - if (block->next) - block = &mem_blocks[block->next - 1]; - else - break; - } + while (1) { + __clear_cache(&mem_block_alloc[block->offset], &mem_block_alloc[block->offset + MEM_BLOCK_SIZE]); + if (block->next) + block = &mem_blocks[block->next - 1]; + else + break; + } #endif } diff --git a/src/codegen/codegen_block.c b/src/codegen/codegen_block.c index 9177565e..20bc7b1e 100644 --- a/src/codegen/codegen_block.c +++ b/src/codegen/codegen_block.c @@ -50,7 +50,7 @@ static x86seg *last_ea_seg; static int last_ssegs; #ifdef DEBUG_EXTRA -uint32_t instr_counts[256*256]; +uint32_t instr_counts[256 * 256]; #endif static uint16_t block_free_list; @@ -60,7 +60,7 @@ static void delete_dirty_block(codeblock_t *block); /*Temporary list of code blocks that have recently been evicted. This allows for some historical state to be kept when a block is the target of self-modifying code. - + The size of this list is limited to DIRTY_LIST_MAX_SIZE blocks. When this is exceeded the oldest entry will be moved to the free list.*/ static uint16_t block_dirty_list_head, block_dirty_list_tail; @@ -69,765 +69,765 @@ static int dirty_list_size = 0; static void block_free_list_add(codeblock_t *block) { #ifndef RELEASE_BUILD - if (block->flags & CODEBLOCK_IN_DIRTY_LIST) - fatal("block_free_list_add: block=%p in dirty list\n", block); + if (block->flags & CODEBLOCK_IN_DIRTY_LIST) + fatal("block_free_list_add: block=%p in dirty list\n", block); #endif - if (block_free_list) - block->next = block_free_list; - else - block->next = 0; - block_free_list = get_block_nr(block); - block->flags = CODEBLOCK_IN_FREE_LIST; -// pclog("block_free_list_add: %p %p\n", block, block->next); + if (block_free_list) + block->next = block_free_list; + else + block->next = 0; + block_free_list = get_block_nr(block); + block->flags = CODEBLOCK_IN_FREE_LIST; + // pclog("block_free_list_add: %p %p\n", block, block->next); } static void block_dirty_list_add(codeblock_t *block) { #ifndef RELEASE_BUILD - if (block->flags & CODEBLOCK_IN_DIRTY_LIST) - fatal("block_dirty_list_add: block=%p already in dirty list\n", block); + if (block->flags & CODEBLOCK_IN_DIRTY_LIST) + fatal("block_dirty_list_add: block=%p already in dirty list\n", block); #endif -// pclog("block_dirty_list_add: block=%i size=%i %i head=%i tail=%i\n", get_block_nr(block), dirty_list_size, dirty_list_check_size(), block_dirty_list_head, block_dirty_list_tail); - if (block_dirty_list_head != BLOCK_INVALID) { - codeblock_t *old_head = &codeblock[block_dirty_list_head]; + // pclog("block_dirty_list_add: block=%i size=%i %i head=%i tail=%i\n", get_block_nr(block), dirty_list_size, + // dirty_list_check_size(), block_dirty_list_head, block_dirty_list_tail); + if (block_dirty_list_head != BLOCK_INVALID) { + codeblock_t *old_head = &codeblock[block_dirty_list_head]; - block->next = block_dirty_list_head; - block->prev = BLOCK_INVALID; - block_dirty_list_head = old_head->prev = get_block_nr(block); -// pclog(" next=%p,%i prev=%i\n", old_head, block->next, old_head->prev); - } else { - /*List empty*/ - block->prev = block->next = BLOCK_INVALID; - block_dirty_list_head = block_dirty_list_tail = get_block_nr(block); - } - block->flags |= CODEBLOCK_IN_DIRTY_LIST; -// pclog(" block_dirty_list_add: %p flags = %x\n", block, block->flags); - dirty_list_size++; - if (dirty_list_size > DIRTY_LIST_MAX_SIZE) { - /*Evict oldest block to the free list*/ - codeblock_t *evict_block = &codeblock[block_dirty_list_tail]; + block->next = block_dirty_list_head; + block->prev = BLOCK_INVALID; + block_dirty_list_head = old_head->prev = get_block_nr(block); + // pclog(" next=%p,%i prev=%i\n", old_head, block->next, old_head->prev); + } else { + /*List empty*/ + block->prev = block->next = BLOCK_INVALID; + block_dirty_list_head = block_dirty_list_tail = get_block_nr(block); + } + block->flags |= CODEBLOCK_IN_DIRTY_LIST; + // pclog(" block_dirty_list_add: %p flags = %x\n", block, block->flags); + dirty_list_size++; + if (dirty_list_size > DIRTY_LIST_MAX_SIZE) { + /*Evict oldest block to the free list*/ + codeblock_t *evict_block = &codeblock[block_dirty_list_tail]; #ifndef RELEASE_BUILD - if (!(evict_block->flags & CODEBLOCK_IN_DIRTY_LIST)) - fatal("block_dirty_list_add: evict_block=%p %x %x not in dirty list\n", evict_block, evict_block->phys, evict_block->flags); - if (!block_dirty_list_tail) - fatal("block_dirty_list_add - !block_dirty_list_tail\n"); - if (evict_block->prev == BLOCK_INVALID) - fatal("block_dirty_list_add - evict_block->prev == BLOCK_INVALID\n"); + if (!(evict_block->flags & CODEBLOCK_IN_DIRTY_LIST)) + fatal("block_dirty_list_add: evict_block=%p %x %x not in dirty list\n", evict_block, evict_block->phys, + evict_block->flags); + if (!block_dirty_list_tail) + fatal("block_dirty_list_add - !block_dirty_list_tail\n"); + if (evict_block->prev == BLOCK_INVALID) + fatal("block_dirty_list_add - evict_block->prev == BLOCK_INVALID\n"); #endif - block_dirty_list_tail = evict_block->prev; - codeblock[evict_block->prev].next = BLOCK_INVALID; + block_dirty_list_tail = evict_block->prev; + codeblock[evict_block->prev].next = BLOCK_INVALID; - dirty_list_size--; - evict_block->flags &= ~CODEBLOCK_IN_DIRTY_LIST; -// pclog(" block_dirty_list_add: %p flags = %x\n", evict_block, evict_block->flags); - delete_dirty_block(evict_block); - } + dirty_list_size--; + evict_block->flags &= ~CODEBLOCK_IN_DIRTY_LIST; + // pclog(" block_dirty_list_add: %p flags = %x\n", evict_block, evict_block->flags); + delete_dirty_block(evict_block); + } -// pclog("block_free_list_add: %p %p\n", block, block->next); + // pclog("block_free_list_add: %p %p\n", block, block->next); } static void block_dirty_list_remove(codeblock_t *block) { - codeblock_t *prev_block = &codeblock[block->prev]; - codeblock_t *next_block = &codeblock[block->next]; + codeblock_t *prev_block = &codeblock[block->prev]; + codeblock_t *next_block = &codeblock[block->next]; #ifndef RELEASE_BUILD - if (!(block->flags & CODEBLOCK_IN_DIRTY_LIST)) - fatal("block_dirty_list_remove: block=%p not in dirty list\n", block); + if (!(block->flags & CODEBLOCK_IN_DIRTY_LIST)) + fatal("block_dirty_list_remove: block=%p not in dirty list\n", block); #endif - /*Is block head of list*/ - if (block->prev == BLOCK_INVALID) - block_dirty_list_head = block->next; - else - prev_block->next = block->next; + /*Is block head of list*/ + if (block->prev == BLOCK_INVALID) + block_dirty_list_head = block->next; + else + prev_block->next = block->next; - /*Is block tail of list?*/ - if (block->next == BLOCK_INVALID) - block_dirty_list_tail = block->prev; - else - next_block->prev = block->prev; + /*Is block tail of list?*/ + if (block->next == BLOCK_INVALID) + block_dirty_list_tail = block->prev; + else + next_block->prev = block->prev; - dirty_list_size--; + dirty_list_size--; #ifndef RELEASE_BUILD - if (dirty_list_size < 0) - fatal("remove - dirty_list_size < 0!\n"); + if (dirty_list_size < 0) + fatal("remove - dirty_list_size < 0!\n"); #endif - block->flags &= ~CODEBLOCK_IN_DIRTY_LIST; -// pclog(" block_dirty_list_remove: %p flags = %x\n", block, block->flags); + block->flags &= ~CODEBLOCK_IN_DIRTY_LIST; + // pclog(" block_dirty_list_remove: %p flags = %x\n", block, block->flags); } int codegen_purge_purgable_list() { - if (purgable_page_list_head) { - page_t *page = &pages[purgable_page_list_head]; + if (purgable_page_list_head) { + page_t *page = &pages[purgable_page_list_head]; - if (page->code_present_mask & page->dirty_mask) { - codegen_check_flush(page, page->dirty_mask, purgable_page_list_head << 12); + if (page->code_present_mask & page->dirty_mask) { + codegen_check_flush(page, page->dirty_mask, purgable_page_list_head << 12); - if (block_free_list) - return 1; - } - } - return 0; + if (block_free_list) + return 1; + } + } + return 0; } static codeblock_t *block_free_list_get() { - codeblock_t *block = NULL; + codeblock_t *block = NULL; - while (!block_free_list) { - /*Free list is empty, check the dirty list*/ - if (block_dirty_list_tail) { + while (!block_free_list) { + /*Free list is empty, check the dirty list*/ + if (block_dirty_list_tail) { #ifndef RELEASE_BUILD - if (dirty_list_size <= 0) - fatal("get - dirty_list_size <= 0!\n"); + if (dirty_list_size <= 0) + fatal("get - dirty_list_size <= 0!\n"); #endif - /*Reuse oldest block*/ - block = &codeblock[block_dirty_list_tail]; + /*Reuse oldest block*/ + block = &codeblock[block_dirty_list_tail]; -// pclog("block_free_list_get: remove block=%p size=%i\n", block, dirty_list_size); - block_dirty_list_tail = block->prev; - if (block->prev == BLOCK_INVALID) - block_dirty_list_head = BLOCK_INVALID; - else - codeblock[block->prev].next = BLOCK_INVALID; - dirty_list_size--; - block->flags &= ~CODEBLOCK_IN_DIRTY_LIST; - delete_dirty_block(block); - block_free_list = get_block_nr(block); - break; - } - /*Free list is empty - free up a block*/ - if (!codegen_purge_purgable_list()) - codegen_delete_random_block(0); - } + // pclog("block_free_list_get: remove block=%p size=%i\n", block, dirty_list_size); + block_dirty_list_tail = block->prev; + if (block->prev == BLOCK_INVALID) + block_dirty_list_head = BLOCK_INVALID; + else + codeblock[block->prev].next = BLOCK_INVALID; + dirty_list_size--; + block->flags &= ~CODEBLOCK_IN_DIRTY_LIST; + delete_dirty_block(block); + block_free_list = get_block_nr(block); + break; + } + /*Free list is empty - free up a block*/ + if (!codegen_purge_purgable_list()) + codegen_delete_random_block(0); + } - block = &codeblock[block_free_list]; - block_free_list = block->next; - block->flags &= ~CODEBLOCK_IN_FREE_LIST; -// pclog(" block_free_list_get: %p flags = %x\n", block, block->flags); - block->next = 0; -// pclog("block_free_list_get: %p %p\n", block, block_free_list); - return block; + block = &codeblock[block_free_list]; + block_free_list = block->next; + block->flags &= ~CODEBLOCK_IN_FREE_LIST; + // pclog(" block_free_list_get: %p flags = %x\n", block, block->flags); + block->next = 0; + // pclog("block_free_list_get: %p %p\n", block, block_free_list); + return block; } void codegen_init() { - int c; + int c; - codegen_allocator_init(); + codegen_allocator_init(); - codegen_backend_init(); - block_free_list = 0; - for (c = 0; c < BLOCK_SIZE; c++) - block_free_list_add(&codeblock[c]); - block_dirty_list_head = block_dirty_list_tail = 0; - dirty_list_size = 0; + codegen_backend_init(); + block_free_list = 0; + for (c = 0; c < BLOCK_SIZE; c++) + block_free_list_add(&codeblock[c]); + block_dirty_list_head = block_dirty_list_tail = 0; + dirty_list_size = 0; #ifdef DEBUG_EXTRA - memset(instr_counts, 0, sizeof(instr_counts)); + memset(instr_counts, 0, sizeof(instr_counts)); #endif } void codegen_close() { #ifdef DEBUG_EXTRA - pclog("Instruction counts :\n"); - while (1) - { - int c; - uint32_t highest_num = 0, highest_idx = 0; + pclog("Instruction counts :\n"); + while (1) { + int c; + uint32_t highest_num = 0, highest_idx = 0; - for (c = 0; c < 256*256; c++) - { - if (instr_counts[c] > highest_num) - { - highest_num = instr_counts[c]; - highest_idx = c; - } - } - if (!highest_num) - break; + for (c = 0; c < 256 * 256; c++) { + if (instr_counts[c] > highest_num) { + highest_num = instr_counts[c]; + highest_idx = c; + } + } + if (!highest_num) + break; - instr_counts[highest_idx] = 0; - if (highest_idx > 256) - pclog(" %02x %02x = %u\n", highest_idx >> 8, highest_idx & 0xff, highest_num); - else - pclog(" %02x = %u\n", highest_idx & 0xff, highest_num); - } + instr_counts[highest_idx] = 0; + if (highest_idx > 256) + pclog(" %02x %02x = %u\n", highest_idx >> 8, highest_idx & 0xff, highest_num); + else + pclog(" %02x = %u\n", highest_idx & 0xff, highest_num); + } #endif } void codegen_reset() { - int c; + int c; - for (c = 1; c < BLOCK_SIZE; c++) { - codeblock_t *block = &codeblock[c]; + for (c = 1; c < BLOCK_SIZE; c++) { + codeblock_t *block = &codeblock[c]; - if (block->pc != BLOCK_PC_INVALID) { - block->phys = 0; - block->phys_2 = 0; - delete_block(block); - } - } + if (block->pc != BLOCK_PC_INVALID) { + block->phys = 0; + block->phys_2 = 0; + delete_block(block); + } + } - memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); - memset(codeblock_hash, 0, HASH_SIZE * sizeof(uint16_t)); - mem_reset_page_blocks(); + memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); + memset(codeblock_hash, 0, HASH_SIZE * sizeof(uint16_t)); + mem_reset_page_blocks(); - block_free_list = 0; - for (c = 0; c < BLOCK_SIZE; c++) { - codeblock[c].pc = BLOCK_PC_INVALID; - block_free_list_add(&codeblock[c]); - } + block_free_list = 0; + for (c = 0; c < BLOCK_SIZE; c++) { + codeblock[c].pc = BLOCK_PC_INVALID; + block_free_list_add(&codeblock[c]); + } } void dump_block() { -/* codeblock_t *block = pages[0x119000 >> 12].block; + /* codeblock_t *block = pages[0x119000 >> 12].block; - pclog("dump_block:\n"); - while (block) - { - uint32_t start_pc = (block->pc & 0xffc) | (block->phys & ~0xfff); - uint32_t end_pc = (block->endpc & 0xffc) | (block->phys & ~0xfff); - pclog(" %p : %08x-%08x %08x-%08x %p %p\n", (void *)block, start_pc, end_pc, block->pc, block->endpc, (void *)block->prev, (void *)block->next); - if (!block->pc) - fatal("Dead PC=0\n"); - - block = block->next; - } - pclog("dump_block done\n");*/ + pclog("dump_block:\n"); + while (block) + { + uint32_t start_pc = (block->pc & 0xffc) | (block->phys & ~0xfff); + uint32_t end_pc = (block->endpc & 0xffc) | (block->phys & ~0xfff); + pclog(" %p : %08x-%08x %08x-%08x %p %p\n", (void *)block, start_pc, end_pc, block->pc, block->endpc, + (void *)block->prev, (void *)block->next); if (!block->pc) fatal("Dead PC=0\n"); + + block = block->next; + } + pclog("dump_block done\n");*/ } static void add_to_block_list(codeblock_t *block) { - uint16_t block_prev_nr = pages[block->phys >> 12].block; - uint16_t block_nr = get_block_nr(block); -//pclog("Add to block list %p %08x %llx %x\n", block, block->phys, block->page_mask2, block->flags); + uint16_t block_prev_nr = pages[block->phys >> 12].block; + uint16_t block_nr = get_block_nr(block); + // pclog("Add to block list %p %08x %llx %x\n", block, block->phys, block->page_mask2, block->flags); #ifndef RELEASE_BUILD - if (!block->page_mask) - fatal("add_to_block_list - mask = 0 %llx %llx\n", block->page_mask, block->page_mask2); + if (!block->page_mask) + fatal("add_to_block_list - mask = 0 %llx %llx\n", block->page_mask, block->page_mask2); #endif - if (block_prev_nr) { - block->next = block_prev_nr; - codeblock[block_prev_nr].prev = block_nr; - pages[block->phys >> 12].block = block_nr; - } else { - block->next = BLOCK_INVALID; - pages[block->phys >> 12].block = block_nr; - } + if (block_prev_nr) { + block->next = block_prev_nr; + codeblock[block_prev_nr].prev = block_nr; + pages[block->phys >> 12].block = block_nr; + } else { + block->next = BLOCK_INVALID; + pages[block->phys >> 12].block = block_nr; + } - if (block->next) { + if (block->next) { #ifndef RELEASE_BUILD - if (codeblock[block->next].pc == BLOCK_PC_INVALID) - fatal("block->next->pc=BLOCK_PC_INVALID %p %p %x %x\n", (void *)&codeblock[block->next], (void *)codeblock, block_current, block_pos); + if (codeblock[block->next].pc == BLOCK_PC_INVALID) + fatal("block->next->pc=BLOCK_PC_INVALID %p %p %x %x\n", (void *)&codeblock[block->next], + (void *)codeblock, block_current, block_pos); #endif - } + } - if (block->page_mask2) { - block->flags |= CODEBLOCK_HAS_PAGE2; + if (block->page_mask2) { + block->flags |= CODEBLOCK_HAS_PAGE2; - block_prev_nr = pages[block->phys_2 >> 12].block_2; + block_prev_nr = pages[block->phys_2 >> 12].block_2; - if (block_prev_nr) { - block->next_2 = block_prev_nr; - codeblock[block_prev_nr].prev_2 = block_nr; - pages[block->phys_2 >> 12].block_2 = block_nr; - } else { - block->next_2 = BLOCK_INVALID; - pages[block->phys_2 >> 12].block_2 = block_nr; - } - } -// pclog(" add_to_block_list: %p flags = %x\n", block, block->flags); + if (block_prev_nr) { + block->next_2 = block_prev_nr; + codeblock[block_prev_nr].prev_2 = block_nr; + pages[block->phys_2 >> 12].block_2 = block_nr; + } else { + block->next_2 = BLOCK_INVALID; + pages[block->phys_2 >> 12].block_2 = block_nr; + } + } + // pclog(" add_to_block_list: %p flags = %x\n", block, block->flags); } static void remove_from_block_list(codeblock_t *block, uint32_t pc) { - if (!block->page_mask) - return; + if (!block->page_mask) + return; #ifndef RELEASE_BUILD - if (block->flags & CODEBLOCK_IN_DIRTY_LIST) - fatal("remove_from_block_list: in dirty list\n"); + if (block->flags & CODEBLOCK_IN_DIRTY_LIST) + fatal("remove_from_block_list: in dirty list\n"); #endif - if (block->prev) { - codeblock[block->prev].next = block->next; - if (block->next) - codeblock[block->next].prev = block->prev; - } else { - pages[block->phys >> 12].block = block->next; - if (block->next) - codeblock[block->next].prev = BLOCK_INVALID; - else - mem_flush_write_page(block->phys, 0); - } + if (block->prev) { + codeblock[block->prev].next = block->next; + if (block->next) + codeblock[block->next].prev = block->prev; + } else { + pages[block->phys >> 12].block = block->next; + if (block->next) + codeblock[block->next].prev = BLOCK_INVALID; + else + mem_flush_write_page(block->phys, 0); + } - if (!(block->flags & CODEBLOCK_HAS_PAGE2)) { + if (!(block->flags & CODEBLOCK_HAS_PAGE2)) { #ifndef RELEASE_BUILD - if (block->prev_2 || block->next_2) - fatal("Invalid block_2 %x %p %08x\n", block->flags, block, block->phys); + if (block->prev_2 || block->next_2) + fatal("Invalid block_2 %x %p %08x\n", block->flags, block, block->phys); #endif - return; - } - block->flags &= ~CODEBLOCK_HAS_PAGE2; -// pclog(" remove_from_block_list: %p flags = %x\n", block, block->flags); + return; + } + block->flags &= ~CODEBLOCK_HAS_PAGE2; + // pclog(" remove_from_block_list: %p flags = %x\n", block, block->flags); - if (block->prev_2) { - codeblock[block->prev_2].next_2 = block->next_2; - if (block->next_2) - codeblock[block->next_2].prev_2 = block->prev_2; - } else { -// pclog(" pages.block_2=%p 3 %p %p\n", (void *)block->next_2, (void *)block, (void *)pages[block->phys_2 >> 12].block_2); - pages[block->phys_2 >> 12].block_2 = block->next_2; - if (block->next_2) - codeblock[block->next_2].prev_2 = BLOCK_INVALID; - else - mem_flush_write_page(block->phys_2, 0); - } + if (block->prev_2) { + codeblock[block->prev_2].next_2 = block->next_2; + if (block->next_2) + codeblock[block->next_2].prev_2 = block->prev_2; + } else { + // pclog(" pages.block_2=%p 3 %p %p\n", (void *)block->next_2, (void *)block, (void + // *)pages[block->phys_2 >> 12].block_2); + pages[block->phys_2 >> 12].block_2 = block->next_2; + if (block->next_2) + codeblock[block->next_2].prev_2 = BLOCK_INVALID; + else + mem_flush_write_page(block->phys_2, 0); + } } static void invalidate_block(codeblock_t *block) { - uint32_t old_pc = block->pc; + uint32_t old_pc = block->pc; #ifndef RELEASE_BUILD - if (block->flags & CODEBLOCK_IN_DIRTY_LIST) - fatal("invalidate_block: already in dirty list\n"); - if (block->pc == BLOCK_PC_INVALID) - fatal("Invalidating deleted block\n"); + if (block->flags & CODEBLOCK_IN_DIRTY_LIST) + fatal("invalidate_block: already in dirty list\n"); + if (block->pc == BLOCK_PC_INVALID) + fatal("Invalidating deleted block\n"); #endif - remove_from_block_list(block, old_pc); - block_dirty_list_add(block); - if (block->head_mem_block) - codegen_allocator_free(block->head_mem_block); - block->head_mem_block = NULL; + remove_from_block_list(block, old_pc); + block_dirty_list_add(block); + if (block->head_mem_block) + codegen_allocator_free(block->head_mem_block); + block->head_mem_block = NULL; } static void delete_block(codeblock_t *block) { - uint32_t old_pc = block->pc; + uint32_t old_pc = block->pc; - if (block == &codeblock[codeblock_hash[HASH(block->phys)]]) - codeblock_hash[HASH(block->phys)] = BLOCK_INVALID; + if (block == &codeblock[codeblock_hash[HASH(block->phys)]]) + codeblock_hash[HASH(block->phys)] = BLOCK_INVALID; #ifndef RELEASE_BUILD - if (block->pc == BLOCK_PC_INVALID) - fatal("Deleting deleted block\n"); + if (block->pc == BLOCK_PC_INVALID) + fatal("Deleting deleted block\n"); #endif - block->pc = BLOCK_PC_INVALID; + block->pc = BLOCK_PC_INVALID; - codeblock_tree_delete(block); - if (block->flags & CODEBLOCK_IN_DIRTY_LIST) - block_dirty_list_remove(block); - else - remove_from_block_list(block, old_pc); - if (block->head_mem_block) - codegen_allocator_free(block->head_mem_block); - block->head_mem_block = NULL; - block_free_list_add(block); + codeblock_tree_delete(block); + if (block->flags & CODEBLOCK_IN_DIRTY_LIST) + block_dirty_list_remove(block); + else + remove_from_block_list(block, old_pc); + if (block->head_mem_block) + codegen_allocator_free(block->head_mem_block); + block->head_mem_block = NULL; + block_free_list_add(block); } static void delete_dirty_block(codeblock_t *block) { - if (block == &codeblock[codeblock_hash[HASH(block->phys)]]) - codeblock_hash[HASH(block->phys)] = BLOCK_INVALID; + if (block == &codeblock[codeblock_hash[HASH(block->phys)]]) + codeblock_hash[HASH(block->phys)] = BLOCK_INVALID; #ifndef RELEASE_BUILD - if (block->pc == BLOCK_PC_INVALID) - fatal("Deleting deleted block\n"); + if (block->pc == BLOCK_PC_INVALID) + fatal("Deleting deleted block\n"); #endif - block->pc = BLOCK_PC_INVALID; + block->pc = BLOCK_PC_INVALID; - codeblock_tree_delete(block); - block_free_list_add(block); + codeblock_tree_delete(block); + block_free_list_add(block); } void codegen_delete_block(codeblock_t *block) { - if (block->pc != BLOCK_PC_INVALID) - delete_block(block); + if (block->pc != BLOCK_PC_INVALID) + delete_block(block); } void codegen_delete_random_block(int required_mem_block) { - int block_nr = rand() & BLOCK_MASK; + int block_nr = rand() & BLOCK_MASK; - while (1) { - if (block_nr && block_nr != block_current) { - codeblock_t *block = &codeblock[block_nr]; + while (1) { + if (block_nr && block_nr != block_current) { + codeblock_t *block = &codeblock[block_nr]; - if (block->pc != BLOCK_PC_INVALID && (!required_mem_block || block->head_mem_block)) { - delete_block(block); - return; - } - } - block_nr = (block_nr + 1) & BLOCK_MASK; - } + if (block->pc != BLOCK_PC_INVALID && (!required_mem_block || block->head_mem_block)) { + delete_block(block); + return; + } + } + block_nr = (block_nr + 1) & BLOCK_MASK; + } } void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr) { - uint16_t block_nr = page->block; - int remove_from_evict_list = 0; - int c; + uint16_t block_nr = page->block; + int remove_from_evict_list = 0; + int c; - while (block_nr) { - codeblock_t *block = &codeblock[block_nr]; - uint16_t next_block = block->next; + while (block_nr) { + codeblock_t *block = &codeblock[block_nr]; + uint16_t next_block = block->next; - if (*block->dirty_mask & block->page_mask) { -// pclog("Delete block from codegen_check_flush %08x %08x %016llx %016llx %016llx %02x\n", phys_addr, block->pc, *block->dirty_mask, block->page_mask, *block->dirty_mask & block->page_mask, block->flags); - invalidate_block(block); - cpu_recomp_evicted++; - } + if (*block->dirty_mask & block->page_mask) { + // pclog("Delete block from codegen_check_flush %08x %08x %016llx %016llx %016llx + // %02x\n", phys_addr, block->pc, *block->dirty_mask, block->page_mask, + // *block->dirty_mask & block->page_mask, block->flags); + invalidate_block(block); + cpu_recomp_evicted++; + } #ifndef RELEASE_BUILD - if (block_nr == next_block) - fatal("Broken 1\n"); + if (block_nr == next_block) + fatal("Broken 1\n"); #endif - block_nr = next_block; - } + block_nr = next_block; + } - block_nr = page->block_2; + block_nr = page->block_2; - while (block_nr) { - codeblock_t *block = &codeblock[block_nr]; - uint16_t next_block = block->next_2; + while (block_nr) { + codeblock_t *block = &codeblock[block_nr]; + uint16_t next_block = block->next_2; - if (*block->dirty_mask2 & block->page_mask2) { -// pclog("Delete block from codegen_check_flush2 %08x %08x\n", phys_addr, block->pc);*/ - invalidate_block(block); - cpu_recomp_evicted++; - } + if (*block->dirty_mask2 & block->page_mask2) { + // pclog("Delete block from codegen_check_flush2 %08x %08x\n", phys_addr, + // block->pc);*/ + invalidate_block(block); + cpu_recomp_evicted++; + } #ifndef RELEASE_BUILD - if (block_nr == next_block) - fatal("Broken 2\n"); + if (block_nr == next_block) + fatal("Broken 2\n"); #endif - block_nr = next_block; - } + block_nr = next_block; + } - if (page->code_present_mask & page->dirty_mask) - remove_from_evict_list = 1; - page->code_present_mask &= ~page->dirty_mask; - page->dirty_mask = 0; + if (page->code_present_mask & page->dirty_mask) + remove_from_evict_list = 1; + page->code_present_mask &= ~page->dirty_mask; + page->dirty_mask = 0; - for (c = 0; c < 64; c++) { - if (page->byte_code_present_mask[c] & page->byte_dirty_mask[c]) - remove_from_evict_list = 0; - page->byte_code_present_mask[c] &= ~page->byte_dirty_mask[c]; - page->byte_dirty_mask[c] = 0; - } - if (remove_from_evict_list) - page_remove_from_evict_list(page); + for (c = 0; c < 64; c++) { + if (page->byte_code_present_mask[c] & page->byte_dirty_mask[c]) + remove_from_evict_list = 0; + page->byte_code_present_mask[c] &= ~page->byte_dirty_mask[c]; + page->byte_dirty_mask[c] = 0; + } + if (remove_from_evict_list) + page_remove_from_evict_list(page); } void codegen_block_init(uint32_t phys_addr) { - codeblock_t *block; - page_t *page = &pages[phys_addr >> 12]; + codeblock_t *block; + page_t *page = &pages[phys_addr >> 12]; - if (!page->block) - mem_flush_write_page(phys_addr, cs + cpu_state.pc); - block = block_free_list_get(); + if (!page->block) + mem_flush_write_page(phys_addr, cs + cpu_state.pc); + block = block_free_list_get(); #ifndef RELEASE_BUILD - if (!block) - fatal("codegen_block_init: block_free_list_get() returned NULL\n"); + if (!block) + fatal("codegen_block_init: block_free_list_get() returned NULL\n"); #endif - block_current = get_block_nr(block); + block_current = get_block_nr(block); - block_num = HASH(phys_addr); - codeblock_hash[block_num] = block_current; + block_num = HASH(phys_addr); + codeblock_hash[block_num] = block_current; - block->ins = 0; - block->pc = cs + cpu_state.pc; - block->_cs = cs; - block->phys = phys_addr; - block->dirty_mask = &page->dirty_mask; - block->dirty_mask2 = NULL; - block->next = block->prev = BLOCK_INVALID; - block->next_2 = block->prev_2 = BLOCK_INVALID; - block->page_mask = block->page_mask2 = 0; - block->flags = CODEBLOCK_STATIC_TOP; -// pclog(" block_init: %p flags = %x\n", block, block->flags); - block->status = cpu_cur_status; + block->ins = 0; + block->pc = cs + cpu_state.pc; + block->_cs = cs; + block->phys = phys_addr; + block->dirty_mask = &page->dirty_mask; + block->dirty_mask2 = NULL; + block->next = block->prev = BLOCK_INVALID; + block->next_2 = block->prev_2 = BLOCK_INVALID; + block->page_mask = block->page_mask2 = 0; + block->flags = CODEBLOCK_STATIC_TOP; + // pclog(" block_init: %p flags = %x\n", block, block->flags); + block->status = cpu_cur_status; - recomp_page = block->phys & ~0xfff; -// pclog("codegen_block_init: %08x\n", block->pc); - codeblock_tree_add(block); + recomp_page = block->phys & ~0xfff; + // pclog("codegen_block_init: %08x\n", block->pc); + codeblock_tree_add(block); } static ir_data_t *ir_data; -ir_data_t *codegen_get_ir_data() { - return ir_data; -} +ir_data_t *codegen_get_ir_data() { return ir_data; } void codegen_block_start_recompile(codeblock_t *block) { - page_t *page = &pages[block->phys >> 12]; + page_t *page = &pages[block->phys >> 12]; - if (!page->block) - mem_flush_write_page(block->phys, cs + cpu_state.pc); + if (!page->block) + mem_flush_write_page(block->phys, cs + cpu_state.pc); - block_num = HASH(block->phys); - block_current = get_block_nr(block);//block->pnt; + block_num = HASH(block->phys); + block_current = get_block_nr(block); // block->pnt; #ifndef RELEASE_BUILD - if (block->pc != cs + cpu_state.pc || (block->flags & CODEBLOCK_WAS_RECOMPILED)) - fatal("Recompile to used block!\n"); + if (block->pc != cs + cpu_state.pc || (block->flags & CODEBLOCK_WAS_RECOMPILED)) + fatal("Recompile to used block!\n"); #endif - block->head_mem_block = codegen_allocator_allocate(NULL, block_current); - block->data = codeblock_allocator_get_ptr(block->head_mem_block); + block->head_mem_block = codegen_allocator_allocate(NULL, block_current); + block->data = codeblock_allocator_get_ptr(block->head_mem_block); - block->status = cpu_cur_status; + block->status = cpu_cur_status; - block->page_mask = block->page_mask2 = 0; - block->ins = 0; + block->page_mask = block->page_mask2 = 0; + block->ins = 0; - cpu_block_end = 0; + cpu_block_end = 0; -// pclog("New block %i for %08X %03x\n", block_current, cs+pc, block_num); + // pclog("New block %i for %08X %03x\n", block_current, cs+pc, block_num); - last_op32 = -1; - last_ea_seg = NULL; - last_ssegs = -1; + last_op32 = -1; + last_ea_seg = NULL; + last_ssegs = -1; - codegen_block_cycles = 0; - codegen_timing_block_start(); + codegen_block_cycles = 0; + codegen_timing_block_start(); - codegen_block_ins = 0; - codegen_block_full_ins = 0; + codegen_block_ins = 0; + codegen_block_full_ins = 0; - recomp_page = block->phys & ~0xfff; + recomp_page = block->phys & ~0xfff; - codegen_flags_changed = 0; - codegen_fpu_entered = 0; - codegen_mmx_entered = 0; + 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; + 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; - cpu_state.seg_ds.checked = cpu_state.seg_es.checked = cpu_state.seg_fs.checked = cpu_state.seg_gs.checked = (cr0 & 1) ? 0 : 1; + cpu_state.seg_ds.checked = cpu_state.seg_es.checked = cpu_state.seg_fs.checked = cpu_state.seg_gs.checked = + (cr0 & 1) ? 0 : 1; - block->TOP = cpu_state.TOP & 7; - block->flags |= CODEBLOCK_WAS_RECOMPILED; + block->TOP = cpu_state.TOP & 7; + block->flags |= CODEBLOCK_WAS_RECOMPILED; - codegen_flat_ds = !(cpu_cur_status & CPU_STATUS_NOTFLATDS); - codegen_flat_ss = !(cpu_cur_status & CPU_STATUS_NOTFLATSS); + codegen_flat_ds = !(cpu_cur_status & CPU_STATUS_NOTFLATDS); + codegen_flat_ss = !(cpu_cur_status & CPU_STATUS_NOTFLATSS); - if (block->flags & CODEBLOCK_BYTE_MASK) { - block->dirty_mask = &page->byte_dirty_mask[(block->phys >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK]; - block->dirty_mask2 = NULL; - } + if (block->flags & CODEBLOCK_BYTE_MASK) { + block->dirty_mask = &page->byte_dirty_mask[(block->phys >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK]; + block->dirty_mask2 = NULL; + } - ir_data = codegen_ir_init(); - ir_data->block = block; - codegen_reg_reset(); - codegen_accumulate_reset(); - codegen_generate_reset(); + ir_data = codegen_ir_init(); + ir_data->block = block; + codegen_reg_reset(); + codegen_accumulate_reset(); + codegen_generate_reset(); } void codegen_block_remove() { - codeblock_t *block = &codeblock[block_current]; + codeblock_t *block = &codeblock[block_current]; - delete_block(block); - cpu_recomp_removed++; + delete_block(block); + cpu_recomp_removed++; - recomp_page = -1; + recomp_page = -1; } void codegen_block_generate_end_mask_recompile() { - codeblock_t *block = &codeblock[block_current]; - page_t *p; -//pclog("gen_end_mask: %08x %08x %016llx %016llx\n", block->pc, codegen_endpc, block->page_mask,block->page_mask2); + codeblock_t *block = &codeblock[block_current]; + page_t *p; + // pclog("gen_end_mask: %08x %08x %016llx %016llx\n", block->pc, codegen_endpc, block->page_mask,block->page_mask2); - p = &pages[block->phys >> 12]; - if (block->flags & CODEBLOCK_BYTE_MASK) { - int offset = (block->phys >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; + p = &pages[block->phys >> 12]; + if (block->flags & CODEBLOCK_BYTE_MASK) { + int offset = (block->phys >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; - p->byte_code_present_mask[offset] |= block->page_mask; - } else - p->code_present_mask |= block->page_mask; + p->byte_code_present_mask[offset] |= block->page_mask; + } else + p->code_present_mask |= block->page_mask; - if ((*(block->dirty_mask) & block->page_mask) && !page_in_evict_list(p)) - page_add_to_evict_list(p); + if ((*(block->dirty_mask) & block->page_mask) && !page_in_evict_list(p)) + page_add_to_evict_list(p); - block->phys_2 = -1; - block->next_2 = block->prev_2 = BLOCK_INVALID; - if (block->page_mask2) { - block->phys_2 = get_phys_noabrt(codegen_endpc); - if (block->phys_2 != -1) { - page_t *page_2 = &pages[block->phys_2 >> 12]; + block->phys_2 = -1; + block->next_2 = block->prev_2 = BLOCK_INVALID; + if (block->page_mask2) { + block->phys_2 = get_phys_noabrt(codegen_endpc); + if (block->phys_2 != -1) { + page_t *page_2 = &pages[block->phys_2 >> 12]; - if (block->flags & CODEBLOCK_BYTE_MASK) { - int offset = (block->phys_2 >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; + if (block->flags & CODEBLOCK_BYTE_MASK) { + int offset = (block->phys_2 >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; - page_2->byte_code_present_mask[offset] |= block->page_mask2; - block->dirty_mask2 = &page_2->byte_dirty_mask[offset]; - } else { - page_2->code_present_mask |= block->page_mask2; - block->dirty_mask2 = &page_2->dirty_mask; - } - if (((*block->dirty_mask2) & block->page_mask2) && !page_in_evict_list(page_2)) - page_add_to_evict_list(page_2); + page_2->byte_code_present_mask[offset] |= block->page_mask2; + block->dirty_mask2 = &page_2->byte_dirty_mask[offset]; + } else { + page_2->code_present_mask |= block->page_mask2; + block->dirty_mask2 = &page_2->dirty_mask; + } + if (((*block->dirty_mask2) & block->page_mask2) && !page_in_evict_list(page_2)) + page_add_to_evict_list(page_2); - if (!pages[block->phys_2 >> 12].block_2) - mem_flush_write_page(block->phys_2, codegen_endpc); + if (!pages[block->phys_2 >> 12].block_2) + mem_flush_write_page(block->phys_2, codegen_endpc); #ifndef RELEASE_BUILD - if (!block->page_mask2) - fatal("!page_mask2\n"); - if (block->next_2) { -// pclog(" next_2->pc=%08x\n", block->next_2->pc); - if (codeblock[block->next_2].pc == BLOCK_PC_INVALID) - fatal("block->next_2->pc=BLOCK_PC_INVALID %p\n", (void *)&codeblock[block->next_2]); - } + if (!block->page_mask2) + fatal("!page_mask2\n"); + if (block->next_2) { + // pclog(" next_2->pc=%08x\n", block->next_2->pc); + if (codeblock[block->next_2].pc == BLOCK_PC_INVALID) + fatal("block->next_2->pc=BLOCK_PC_INVALID %p\n", (void *)&codeblock[block->next_2]); + } #endif - } else { - /*Second page not present. page_mask2 is most likely set only because - the recompiler didn't know how long the last instruction was, so - clear it*/ - block->page_mask2 = 0; - } - } + } else { + /*Second page not present. page_mask2 is most likely set only because + the recompiler didn't know how long the last instruction was, so + clear it*/ + block->page_mask2 = 0; + } + } -// pclog("block_end: %08x %08x %016llx\n", block->pc, codegen_endpc, block->page_mask); - recomp_page = -1; + // pclog("block_end: %08x %08x %016llx\n", block->pc, codegen_endpc, block->page_mask); + recomp_page = -1; } void codegen_block_generate_end_mask_mark() { - codeblock_t *block = &codeblock[block_current]; - uint32_t start_pc; - uint32_t end_pc; - page_t *p; + codeblock_t *block = &codeblock[block_current]; + uint32_t start_pc; + uint32_t end_pc; + page_t *p; #ifndef RELEASE_BUILD - if (block->flags & CODEBLOCK_BYTE_MASK) - fatal("codegen_block_generate_end_mask2() - BYTE_MASK\n"); + if (block->flags & CODEBLOCK_BYTE_MASK) + fatal("codegen_block_generate_end_mask2() - BYTE_MASK\n"); #endif - block->page_mask = 0; - start_pc = (block->pc & 0xfff) & ~63; - if ((block->pc ^ codegen_endpc) & ~0xfff) - end_pc = 0xfff & ~63; - else - end_pc = (codegen_endpc & 0xfff) & ~63; - if (end_pc < start_pc) - end_pc = 0xfff; - start_pc >>= PAGE_MASK_SHIFT; - end_pc >>= PAGE_MASK_SHIFT; + block->page_mask = 0; + start_pc = (block->pc & 0xfff) & ~63; + if ((block->pc ^ codegen_endpc) & ~0xfff) + end_pc = 0xfff & ~63; + else + end_pc = (codegen_endpc & 0xfff) & ~63; + if (end_pc < start_pc) + end_pc = 0xfff; + start_pc >>= PAGE_MASK_SHIFT; + end_pc >>= PAGE_MASK_SHIFT; -// pclog("block_end: %08x %08x\n", start_pc, end_pc); - for (; start_pc <= end_pc; start_pc++) { - block->page_mask |= ((uint64_t)1 << start_pc); -// pclog(" %08x %llx\n", start_pc, block->page_mask); - } + // pclog("block_end: %08x %08x\n", start_pc, end_pc); + for (; start_pc <= end_pc; start_pc++) { + block->page_mask |= ((uint64_t)1 << start_pc); + // pclog(" %08x %llx\n", start_pc, block->page_mask); + } - p = &pages[block->phys >> 12]; - p->code_present_mask |= block->page_mask; - if ((p->dirty_mask & block->page_mask) && !page_in_evict_list(p)) - page_add_to_evict_list(p); + p = &pages[block->phys >> 12]; + p->code_present_mask |= block->page_mask; + if ((p->dirty_mask & block->page_mask) && !page_in_evict_list(p)) + page_add_to_evict_list(p); - block->phys_2 = -1; - block->page_mask2 = 0; - block->next_2 = block->prev_2 = BLOCK_INVALID; - if ((block->pc ^ codegen_endpc) & ~0xfff) { - block->phys_2 = get_phys_noabrt(codegen_endpc); - if (block->phys_2 != -1) { - page_t *page_2 = &pages[block->phys_2 >> 12]; + block->phys_2 = -1; + block->page_mask2 = 0; + block->next_2 = block->prev_2 = BLOCK_INVALID; + if ((block->pc ^ codegen_endpc) & ~0xfff) { + block->phys_2 = get_phys_noabrt(codegen_endpc); + if (block->phys_2 != -1) { + page_t *page_2 = &pages[block->phys_2 >> 12]; - start_pc = 0; - end_pc = (codegen_endpc & 0xfff) >> PAGE_MASK_SHIFT; - for (; start_pc <= end_pc; start_pc++) - block->page_mask2 |= ((uint64_t)1 << start_pc); + start_pc = 0; + end_pc = (codegen_endpc & 0xfff) >> PAGE_MASK_SHIFT; + for (; start_pc <= end_pc; start_pc++) + block->page_mask2 |= ((uint64_t)1 << start_pc); - page_2->code_present_mask |= block->page_mask2; - if ((page_2->dirty_mask & block->page_mask2) && !page_in_evict_list(page_2)) - page_add_to_evict_list(page_2); + page_2->code_present_mask |= block->page_mask2; + if ((page_2->dirty_mask & block->page_mask2) && !page_in_evict_list(page_2)) + page_add_to_evict_list(page_2); - if (!pages[block->phys_2 >> 12].block_2) - mem_flush_write_page(block->phys_2, codegen_endpc); + if (!pages[block->phys_2 >> 12].block_2) + mem_flush_write_page(block->phys_2, codegen_endpc); #ifndef RELEASE_BUILD - if (!block->page_mask2) - fatal("!page_mask2\n"); - if (block->next_2) { -// pclog(" next_2->pc=%08x\n", block->next_2->pc); - if (codeblock[block->next_2].pc == BLOCK_PC_INVALID) - fatal("block->next_2->pc=BLOCK_PC_INVALID %p\n", (void *)&codeblock[block->next_2]); - } + if (!block->page_mask2) + fatal("!page_mask2\n"); + if (block->next_2) { + // pclog(" next_2->pc=%08x\n", block->next_2->pc); + if (codeblock[block->next_2].pc == BLOCK_PC_INVALID) + fatal("block->next_2->pc=BLOCK_PC_INVALID %p\n", (void *)&codeblock[block->next_2]); + } #endif - block->dirty_mask2 = &page_2->dirty_mask; - } else { - /*Second page not present. page_mask2 is most likely set only because - the recompiler didn't know how long the last instruction was, so - clear it*/ - block->page_mask2 = 0; - } - } + block->dirty_mask2 = &page_2->dirty_mask; + } else { + /*Second page not present. page_mask2 is most likely set only because + the recompiler didn't know how long the last instruction was, so + clear it*/ + block->page_mask2 = 0; + } + } -// pclog("block_end: %08x %08x %016llx\n", block->pc, codegen_endpc, block->page_mask); - recomp_page = -1; + // pclog("block_end: %08x %08x %016llx\n", block->pc, codegen_endpc, block->page_mask); + recomp_page = -1; } void codegen_block_end() { - codeblock_t *block = &codeblock[block_current]; + codeblock_t *block = &codeblock[block_current]; - codegen_block_generate_end_mask_mark(); - add_to_block_list(block); + codegen_block_generate_end_mask_mark(); + add_to_block_list(block); } void codegen_block_end_recompile(codeblock_t *block) { - codegen_timing_block_end(); - codegen_accumulate(ACCREG_cycles, -codegen_block_cycles); + codegen_timing_block_end(); + codegen_accumulate(ACCREG_cycles, -codegen_block_cycles); - if (block->flags & CODEBLOCK_IN_DIRTY_LIST) - block_dirty_list_remove(block); - else - remove_from_block_list(block, block->pc); - block->next = block->prev = BLOCK_INVALID; - block->next_2 = block->prev_2 = BLOCK_INVALID; - codegen_block_generate_end_mask_recompile(); - add_to_block_list(block); -// pclog("End block %i\n", block_num); + if (block->flags & CODEBLOCK_IN_DIRTY_LIST) + block_dirty_list_remove(block); + else + remove_from_block_list(block, block->pc); + block->next = block->prev = BLOCK_INVALID; + block->next_2 = block->prev_2 = BLOCK_INVALID; + codegen_block_generate_end_mask_recompile(); + add_to_block_list(block); + // pclog("End block %i\n", block_num); - if (!(block->flags & CODEBLOCK_HAS_FPU)) - block->flags &= ~CODEBLOCK_STATIC_TOP; + if (!(block->flags & CODEBLOCK_HAS_FPU)) + block->flags &= ~CODEBLOCK_STATIC_TOP; - codegen_accumulate_flush(ir_data); - codegen_ir_compile(ir_data, block); + codegen_accumulate_flush(ir_data); + codegen_ir_compile(ir_data, block); } -void codegen_flush() { - return; -} +void codegen_flush() { return; } void codegen_mark_code_present_multibyte(codeblock_t *block, uint32_t start_pc, int len) { - if (len) { - uint32_t end_pc = start_pc + (len - 1); + if (len) { + uint32_t end_pc = start_pc + (len - 1); - if (block->flags & CODEBLOCK_BYTE_MASK) { - uint32_t start_pc_masked = start_pc & PAGE_MASK_MASK; - uint32_t end_pc_masked = end_pc & PAGE_MASK_MASK; + if (block->flags & CODEBLOCK_BYTE_MASK) { + uint32_t start_pc_masked = start_pc & PAGE_MASK_MASK; + uint32_t end_pc_masked = end_pc & PAGE_MASK_MASK; - if ((start_pc ^ block->pc) & ~0x3f) /*Starts in second page*/ - { - for (; start_pc_masked <= end_pc_masked; start_pc_masked++) - block->page_mask2 |= ((uint64_t)1 << start_pc_masked); - } else if (((start_pc + (len - 1)) ^ block->pc) & ~0x3f) /*Crosses both pages*/ - { - for (; start_pc_masked <= 63; start_pc_masked++) - block->page_mask |= ((uint64_t)1 << start_pc_masked); - for (start_pc_masked = 0; start_pc_masked <= end_pc_masked; start_pc_masked++) - block->page_mask2 |= ((uint64_t)1 << start_pc_masked); - } else /*First page only*/ - { - for (; start_pc_masked <= end_pc_masked; start_pc_masked++) - block->page_mask |= ((uint64_t)1 << start_pc_masked); - } - } else { - uint32_t start_pc_shifted = start_pc >> PAGE_MASK_SHIFT; - uint32_t end_pc_shifted = end_pc >> PAGE_MASK_SHIFT; - start_pc_shifted &= PAGE_MASK_MASK; - end_pc_shifted &= PAGE_MASK_MASK; + if ((start_pc ^ block->pc) & ~0x3f) /*Starts in second page*/ + { + for (; start_pc_masked <= end_pc_masked; start_pc_masked++) + block->page_mask2 |= ((uint64_t)1 << start_pc_masked); + } else if (((start_pc + (len - 1)) ^ block->pc) & ~0x3f) /*Crosses both pages*/ + { + for (; start_pc_masked <= 63; start_pc_masked++) + block->page_mask |= ((uint64_t)1 << start_pc_masked); + for (start_pc_masked = 0; start_pc_masked <= end_pc_masked; start_pc_masked++) + block->page_mask2 |= ((uint64_t)1 << start_pc_masked); + } else /*First page only*/ + { + for (; start_pc_masked <= end_pc_masked; start_pc_masked++) + block->page_mask |= ((uint64_t)1 << start_pc_masked); + } + } else { + uint32_t start_pc_shifted = start_pc >> PAGE_MASK_SHIFT; + uint32_t end_pc_shifted = end_pc >> PAGE_MASK_SHIFT; + start_pc_shifted &= PAGE_MASK_MASK; + end_pc_shifted &= PAGE_MASK_MASK; - if ((start_pc ^ block->pc) & ~0xfff) /*Starts in second page*/ - { - for (; start_pc_shifted <= end_pc_shifted; start_pc_shifted++) - block->page_mask2 |= ((uint64_t)1 << start_pc_shifted); - } else if (((start_pc + (len - 1)) ^ block->pc) & ~0xfff) /*Crosses both pages*/ - { - for (; start_pc_shifted <= 63; start_pc_shifted++) - block->page_mask |= ((uint64_t)1 << start_pc_shifted); - for (start_pc_shifted = 0; start_pc_shifted <= end_pc_shifted; start_pc_shifted++) - block->page_mask2 |= ((uint64_t)1 << start_pc_shifted); - } else /*First page only*/ - { - for (; start_pc_shifted <= end_pc_shifted; start_pc_shifted++) - block->page_mask |= ((uint64_t)1 << start_pc_shifted); - } - } - } + if ((start_pc ^ block->pc) & ~0xfff) /*Starts in second page*/ + { + for (; start_pc_shifted <= end_pc_shifted; start_pc_shifted++) + block->page_mask2 |= ((uint64_t)1 << start_pc_shifted); + } else if (((start_pc + (len - 1)) ^ block->pc) & ~0xfff) /*Crosses both pages*/ + { + for (; start_pc_shifted <= 63; start_pc_shifted++) + block->page_mask |= ((uint64_t)1 << start_pc_shifted); + for (start_pc_shifted = 0; start_pc_shifted <= end_pc_shifted; start_pc_shifted++) + block->page_mask2 |= ((uint64_t)1 << start_pc_shifted); + } else /*First page only*/ + { + for (; start_pc_shifted <= end_pc_shifted; start_pc_shifted++) + block->page_mask |= ((uint64_t)1 << start_pc_shifted); + } + } + } } diff --git a/src/codegen/codegen_ir.c b/src/codegen/codegen_ir.c index 0d7014eb..652bb54c 100644 --- a/src/codegen/codegen_ir.c +++ b/src/codegen/codegen_ir.c @@ -12,175 +12,178 @@ static int codegen_unroll_start, codegen_unroll_count; static int codegen_unroll_first_instruction; ir_data_t *codegen_ir_init() { - ir_block.wr_pos = 0; -// pclog("codegen_ir_init %04x:%04x\n", CS,cpu_state.pc); + ir_block.wr_pos = 0; + // pclog("codegen_ir_init %04x:%04x\n", CS,cpu_state.pc); - codegen_unroll_count = 0; + codegen_unroll_count = 0; - return &ir_block; + return &ir_block; } void codegen_ir_set_unroll(int count, int start, int first_instruction) { - codegen_unroll_count = count; - codegen_unroll_start = start; - codegen_unroll_first_instruction = first_instruction; + codegen_unroll_count = count; + codegen_unroll_start = start; + codegen_unroll_first_instruction = first_instruction; } static void duplicate_uop(ir_data_t *ir, uop_t *uop, int offset) { - uop_t *new_uop = uop_alloc(ir, uop->type); + uop_t *new_uop = uop_alloc(ir, uop->type); -// pclog(" uop type %08x\n", uop->type); - if (!ir_reg_is_invalid(uop->src_reg_a)) - new_uop->src_reg_a = codegen_reg_read(uop->src_reg_a.reg); - if (!ir_reg_is_invalid(uop->src_reg_b)) - new_uop->src_reg_b = codegen_reg_read(uop->src_reg_b.reg); - if (!ir_reg_is_invalid(uop->src_reg_c)) - new_uop->src_reg_c = codegen_reg_read(uop->src_reg_c.reg); - if (!ir_reg_is_invalid(uop->dest_reg_a)) - new_uop->dest_reg_a = codegen_reg_write(uop->dest_reg_a.reg, ir->wr_pos - 1); + // pclog(" uop type %08x\n", uop->type); + if (!ir_reg_is_invalid(uop->src_reg_a)) + new_uop->src_reg_a = codegen_reg_read(uop->src_reg_a.reg); + if (!ir_reg_is_invalid(uop->src_reg_b)) + new_uop->src_reg_b = codegen_reg_read(uop->src_reg_b.reg); + if (!ir_reg_is_invalid(uop->src_reg_c)) + new_uop->src_reg_c = codegen_reg_read(uop->src_reg_c.reg); + if (!ir_reg_is_invalid(uop->dest_reg_a)) + new_uop->dest_reg_a = codegen_reg_write(uop->dest_reg_a.reg, ir->wr_pos - 1); - new_uop->type = uop->type; - new_uop->imm_data = uop->imm_data; - new_uop->p = uop->p; - new_uop->pc = uop->pc; + new_uop->type = uop->type; + new_uop->imm_data = uop->imm_data; + new_uop->p = uop->p; + new_uop->pc = uop->pc; - if (uop->jump_dest_uop != -1) { - new_uop->jump_dest_uop = uop->jump_dest_uop + offset; - } + if (uop->jump_dest_uop != -1) { + new_uop->jump_dest_uop = uop->jump_dest_uop + offset; + } } void codegen_ir_compile(ir_data_t *ir, codeblock_t *block) { - int jump_target_at_end = -1; - int c; + int jump_target_at_end = -1; + int c; - if (codegen_unroll_count) { - int unroll_count; - int unroll_end; + if (codegen_unroll_count) { + int unroll_count; + int unroll_end; - codegen_set_loop_start(ir, codegen_unroll_first_instruction); - unroll_end = ir->wr_pos; + codegen_set_loop_start(ir, codegen_unroll_first_instruction); + unroll_end = ir->wr_pos; - for (unroll_count = 1; unroll_count < codegen_unroll_count; unroll_count++) { - int offset = ir->wr_pos - codegen_unroll_start; -// pclog("Unroll from %i to %i, offset %i - iteration %i\n", codegen_unroll_start, ir->wr_pos, offset, unroll_count); - for (c = codegen_unroll_start; c < unroll_end; c++) { -// pclog(" Duplicate uop %i\n", c); - duplicate_uop(ir, &ir->uops[c], offset); - } - } - } + for (unroll_count = 1; unroll_count < codegen_unroll_count; unroll_count++) { + int offset = ir->wr_pos - codegen_unroll_start; + // pclog("Unroll from %i to %i, offset %i - iteration %i\n", codegen_unroll_start, + // ir->wr_pos, offset, unroll_count); + for (c = codegen_unroll_start; c < unroll_end; c++) { + // pclog(" Duplicate uop %i\n", c); + duplicate_uop(ir, &ir->uops[c], offset); + } + } + } - codegen_reg_mark_as_required(); - codegen_reg_process_dead_list(ir); - block_write_data = codeblock_allocator_get_ptr(block->head_mem_block); - block_pos = 0; - codegen_backend_prologue(block); + codegen_reg_mark_as_required(); + codegen_reg_process_dead_list(ir); + block_write_data = codeblock_allocator_get_ptr(block->head_mem_block); + block_pos = 0; + codegen_backend_prologue(block); - for (c = 0; c < ir->wr_pos; c++) { - uop_t *uop = &ir->uops[c]; + for (c = 0; c < ir->wr_pos; c++) { + uop_t *uop = &ir->uops[c]; -// pclog("uOP %i : %08x\n", c, uop->type); + // pclog("uOP %i : %08x\n", c, uop->type); - if (uop->type & UOP_TYPE_BARRIER) - codegen_reg_flush_invalidate(ir, block); + if (uop->type & UOP_TYPE_BARRIER) + codegen_reg_flush_invalidate(ir, block); - if (uop->type & UOP_TYPE_JUMP_DEST) { - uop_t *uop_dest = uop; + if (uop->type & UOP_TYPE_JUMP_DEST) { + uop_t *uop_dest = uop; - while (uop_dest->jump_list_next != -1) { - uop_dest = &ir->uops[uop_dest->jump_list_next]; - codegen_set_jump_dest(block, uop_dest->p); - } - } + while (uop_dest->jump_list_next != -1) { + uop_dest = &ir->uops[uop_dest->jump_list_next]; + codegen_set_jump_dest(block, uop_dest->p); + } + } - if ((uop->type & UOP_MASK) == UOP_INVALID) - continue; + if ((uop->type & UOP_MASK) == UOP_INVALID) + continue; #ifdef CODEGEN_BACKEND_HAS_MOV_IMM - if ((uop->type & UOP_MASK) == (UOP_MOV_IMM & UOP_MASK) && reg_is_native_size(uop->dest_reg_a) && !codegen_reg_is_loaded(uop->dest_reg_a) - && reg_version[IREG_GET_REG(uop->dest_reg_a.reg)][uop->dest_reg_a.version].refcount <= 0) { - /*Special case for UOP_MOV_IMM - if destination not already in host register - and won't be used again then just store directly to memory*/ - codegen_reg_write_imm(block, uop->dest_reg_a, uop->imm_data); - } else + if ((uop->type & UOP_MASK) == (UOP_MOV_IMM & UOP_MASK) && reg_is_native_size(uop->dest_reg_a) && + !codegen_reg_is_loaded(uop->dest_reg_a) && + reg_version[IREG_GET_REG(uop->dest_reg_a.reg)][uop->dest_reg_a.version].refcount <= 0) { + /*Special case for UOP_MOV_IMM - if destination not already in host register + and won't be used again then just store directly to memory*/ + codegen_reg_write_imm(block, uop->dest_reg_a, uop->imm_data); + } else #endif - if ((uop->type & UOP_MASK) == (UOP_MOV & UOP_MASK) && reg_version[IREG_GET_REG(uop->src_reg_a.reg)][uop->src_reg_a.version].refcount <= 1 && - reg_is_native_size(uop->src_reg_a) && reg_is_native_size(uop->dest_reg_a)) { - /*Special case for UOP_MOV - if source register won't be used again then - just rename it to dest register instead of moving*/ - codegen_reg_alloc_register(invalid_ir_reg, uop->src_reg_a, invalid_ir_reg, invalid_ir_reg); - uop->src_reg_a_real = codegen_reg_alloc_read_reg(block, uop->src_reg_a, NULL); - codegen_reg_rename(block, uop->src_reg_a, uop->dest_reg_a); - if (uop->type & UOP_TYPE_ORDER_BARRIER) - codegen_reg_flush(ir, block); - } else { - if (uop->type & UOP_TYPE_PARAMS_REGS) { - codegen_reg_alloc_register(uop->dest_reg_a, uop->src_reg_a, uop->src_reg_b, uop->src_reg_c); - if (uop->src_reg_a.reg != IREG_INVALID) { - uop->src_reg_a_real = codegen_reg_alloc_read_reg(block, uop->src_reg_a, NULL); - } - if (uop->src_reg_b.reg != IREG_INVALID) { - uop->src_reg_b_real = codegen_reg_alloc_read_reg(block, uop->src_reg_b, NULL); - } - if (uop->src_reg_c.reg != IREG_INVALID) { - uop->src_reg_c_real = codegen_reg_alloc_read_reg(block, uop->src_reg_c, NULL); - } - } + if ((uop->type & UOP_MASK) == (UOP_MOV & UOP_MASK) && + reg_version[IREG_GET_REG(uop->src_reg_a.reg)][uop->src_reg_a.version].refcount <= 1 && + reg_is_native_size(uop->src_reg_a) && reg_is_native_size(uop->dest_reg_a)) { + /*Special case for UOP_MOV - if source register won't be used again then + just rename it to dest register instead of moving*/ + codegen_reg_alloc_register(invalid_ir_reg, uop->src_reg_a, invalid_ir_reg, invalid_ir_reg); + uop->src_reg_a_real = codegen_reg_alloc_read_reg(block, uop->src_reg_a, NULL); + codegen_reg_rename(block, uop->src_reg_a, uop->dest_reg_a); + if (uop->type & UOP_TYPE_ORDER_BARRIER) + codegen_reg_flush(ir, block); + } else { + if (uop->type & UOP_TYPE_PARAMS_REGS) { + codegen_reg_alloc_register(uop->dest_reg_a, uop->src_reg_a, uop->src_reg_b, uop->src_reg_c); + if (uop->src_reg_a.reg != IREG_INVALID) { + uop->src_reg_a_real = codegen_reg_alloc_read_reg(block, uop->src_reg_a, NULL); + } + if (uop->src_reg_b.reg != IREG_INVALID) { + uop->src_reg_b_real = codegen_reg_alloc_read_reg(block, uop->src_reg_b, NULL); + } + if (uop->src_reg_c.reg != IREG_INVALID) { + uop->src_reg_c_real = codegen_reg_alloc_read_reg(block, uop->src_reg_c, NULL); + } + } - if (uop->type & UOP_TYPE_ORDER_BARRIER) - codegen_reg_flush(ir, block); + if (uop->type & UOP_TYPE_ORDER_BARRIER) + codegen_reg_flush(ir, block); - if (uop->type & UOP_TYPE_PARAMS_REGS) { - if (uop->dest_reg_a.reg != IREG_INVALID) { - uop->dest_reg_a_real = codegen_reg_alloc_write_reg(block, uop->dest_reg_a); - } - } + if (uop->type & UOP_TYPE_PARAMS_REGS) { + if (uop->dest_reg_a.reg != IREG_INVALID) { + uop->dest_reg_a_real = codegen_reg_alloc_write_reg(block, uop->dest_reg_a); + } + } #ifndef RELEASE_BUILD - if (!uop_handlers[uop->type & UOP_MASK]) - fatal("!uop_handlers[uop->type & UOP_MASK] %08x\n", uop->type); + if (!uop_handlers[uop->type & UOP_MASK]) + fatal("!uop_handlers[uop->type & UOP_MASK] %08x\n", uop->type); #endif - uop_handlers[uop->type & UOP_MASK](block, uop); - } + uop_handlers[uop->type & UOP_MASK](block, uop); + } - if (uop->type & UOP_TYPE_JUMP) { - if (uop->jump_dest_uop == ir->wr_pos) { - if (jump_target_at_end == -1) - jump_target_at_end = c; - else { - uop_t *uop_dest = &ir->uops[jump_target_at_end]; + if (uop->type & UOP_TYPE_JUMP) { + if (uop->jump_dest_uop == ir->wr_pos) { + if (jump_target_at_end == -1) + jump_target_at_end = c; + else { + uop_t *uop_dest = &ir->uops[jump_target_at_end]; - while (uop_dest->jump_list_next != -1) - uop_dest = &ir->uops[uop_dest->jump_list_next]; + while (uop_dest->jump_list_next != -1) + uop_dest = &ir->uops[uop_dest->jump_list_next]; - uop_dest->jump_list_next = c; - } - } else { - uop_t *uop_dest = &ir->uops[uop->jump_dest_uop]; + uop_dest->jump_list_next = c; + } + } else { + uop_t *uop_dest = &ir->uops[uop->jump_dest_uop]; - while (uop_dest->jump_list_next != -1) - uop_dest = &ir->uops[uop_dest->jump_list_next]; + while (uop_dest->jump_list_next != -1) + uop_dest = &ir->uops[uop_dest->jump_list_next]; - uop_dest->jump_list_next = c; - ir->uops[uop->jump_dest_uop].type |= UOP_TYPE_JUMP_DEST; - } - } - } + uop_dest->jump_list_next = c; + ir->uops[uop->jump_dest_uop].type |= UOP_TYPE_JUMP_DEST; + } + } + } - codegen_reg_flush_invalidate(ir, block); + codegen_reg_flush_invalidate(ir, block); - if (jump_target_at_end != -1) { - uop_t *uop_dest = &ir->uops[jump_target_at_end]; + if (jump_target_at_end != -1) { + uop_t *uop_dest = &ir->uops[jump_target_at_end]; - while (1) { - codegen_set_jump_dest(block, uop_dest->p); - if (uop_dest->jump_list_next == -1) - break; - uop_dest = &ir->uops[uop_dest->jump_list_next]; - } - } + while (1) { + codegen_set_jump_dest(block, uop_dest->p); + if (uop_dest->jump_list_next == -1) + break; + uop_dest = &ir->uops[uop_dest->jump_list_next]; + } + } - codegen_backend_epilogue(block); - block_write_data = NULL; -// if (has_ea) -// fatal("IR compilation complete\n"); + codegen_backend_epilogue(block); + block_write_data = NULL; + // if (has_ea) + // fatal("IR compilation complete\n"); } diff --git a/src/codegen/codegen_ops.c b/src/codegen/codegen_ops.c index c944cbf4..c1a9dd44 100644 --- a/src/codegen/codegen_ops.c +++ b/src/codegen/codegen_ops.c @@ -22,508 +22,5098 @@ #include "codegen_ops_shift.h" #include "codegen_ops_stack.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*/ ropADC_b_rmw, ropADC_w_rmw, ropADC_b_rm, ropADC_w_rm, ropADC_AL_imm, ropADC_AX_imm, ropPUSH_SS_16, NULL, ropSBB_b_rmw, ropSBB_w_rmw, ropSBB_b_rm, ropSBB_w_rm, ropSBB_AL_imm, ropSBB_AX_imm, - 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_r16, ropINC_r16, ropINC_r16, ropINC_r16, ropINC_r16, ropINC_r16, ropINC_r16, ropINC_r16, ropDEC_r16, ropDEC_r16, ropDEC_r16, ropDEC_r16, ropDEC_r16, ropDEC_r16, ropDEC_r16, ropDEC_r16, -/*50*/ ropPUSH_r16, ropPUSH_r16, ropPUSH_r16, ropPUSH_r16, ropPUSH_r16, ropPUSH_r16, ropPUSH_r16, ropPUSH_r16, ropPOP_r16, ropPOP_r16, ropPOP_r16, ropPOP_r16, ropPOP_r16, ropPOP_r16, ropPOP_r16, - ropPOP_r16, -/*60*/ ropPUSHA_16, ropPOPA_16, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_imm_16, NULL, ropPUSH_imm_16_8, NULL, NULL, NULL, NULL, NULL, -/*70*/ ropJO_8, ropJNO_8, ropJB_8, ropJNB_8, ropJE_8, ropJNE_8, ropJBE_8, ropJNBE_8, ropJS_8, ropJNS_8, ropJP_8, ropJNP_8, ropJL_8, ropJNL_8, ropJLE_8, ropJNLE_8, - -/*80*/ rop80, rop81_w, rop80, rop83_w, ropTEST_b_rm, ropTEST_w_rm, ropXCHG_8, ropXCHG_16, ropMOV_b_r, ropMOV_w_r, ropMOV_r_b, ropMOV_r_w, ropMOV_w_seg, ropLEA_16, ropMOV_seg_w, ropPOP_W, -/*90*/ ropNOP, ropXCHG_AX, ropXCHG_AX, ropXCHG_AX, ropXCHG_AX, ropXCHG_AX, ropXCHG_AX, ropXCHG_AX, ropCBW, ropCWD, NULL, NULL, ropPUSHF, NULL, NULL, NULL, -/*a0*/ ropMOV_AL_abs, ropMOV_AX_abs, ropMOV_abs_AL, ropMOV_abs_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_16, ropLDS_16, ropMOV_b_imm, ropMOV_w_imm, NULL, ropLEAVE_16, ropRETF_imm_16, ropRETF_16, NULL, NULL, NULL, NULL, -/*d0*/ ropD0, ropD1_w, ropD2, ropD3_w, NULL, NULL, NULL, ropXLAT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ ropLOOPNE, ropLOOPE, ropLOOP, ropJCXZ, NULL, NULL, NULL, NULL, ropCALL_r16, ropJMP_r16, ropJMP_far_16, ropJMP_r8, NULL, NULL, NULL, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, ropCMC, ropF6, ropF7_16, ropCLC, ropSTC, ropCLI, ropSTI, ropCLD, ropSTD, ropINCDEC, 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*/ ropADC_b_rmw, ropADC_l_rmw, ropADC_b_rm, ropADC_l_rm, ropADC_AL_imm, ropADC_EAX_imm, ropPUSH_SS_32, NULL, ropSBB_b_rmw, ropSBB_l_rmw, ropSBB_b_rm, ropSBB_l_rm, ropSBB_AL_imm, ropSBB_EAX_imm, - 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_r32, ropINC_r32, ropINC_r32, ropINC_r32, ropINC_r32, ropINC_r32, ropINC_r32, ropINC_r32, ropDEC_r32, ropDEC_r32, ropDEC_r32, ropDEC_r32, ropDEC_r32, ropDEC_r32, ropDEC_r32, ropDEC_r32, -/*50*/ ropPUSH_r32, ropPUSH_r32, ropPUSH_r32, ropPUSH_r32, ropPUSH_r32, ropPUSH_r32, ropPUSH_r32, ropPUSH_r32, ropPOP_r32, ropPOP_r32, ropPOP_r32, ropPOP_r32, ropPOP_r32, ropPOP_r32, ropPOP_r32, - ropPOP_r32, -/*60*/ ropPUSHA_32, ropPOPA_32, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_imm_32, NULL, ropPUSH_imm_32_8, NULL, NULL, NULL, NULL, NULL, -/*70*/ ropJO_8, ropJNO_8, ropJB_8, ropJNB_8, ropJE_8, ropJNE_8, ropJBE_8, ropJNBE_8, ropJS_8, ropJNS_8, ropJP_8, ropJNP_8, ropJL_8, ropJNL_8, ropJLE_8, ropJNLE_8, - -/*80*/ rop80, rop81_l, rop80, rop83_l, ropTEST_b_rm, ropTEST_l_rm, ropXCHG_8, ropXCHG_32, ropMOV_b_r, ropMOV_l_r, ropMOV_r_b, ropMOV_r_l, ropMOV_l_seg, ropLEA_32, ropMOV_seg_w, ropPOP_L, -/*90*/ ropNOP, ropXCHG_EAX, ropXCHG_EAX, ropXCHG_EAX, ropXCHG_EAX, ropXCHG_EAX, ropXCHG_EAX, ropXCHG_EAX, ropCWDE, ropCDQ, NULL, NULL, ropPUSHFD, NULL, NULL, NULL, -/*a0*/ ropMOV_AL_abs, ropMOV_EAX_abs, ropMOV_abs_AL, ropMOV_abs_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_32, ropLDS_32, ropMOV_b_imm, ropMOV_l_imm, NULL, ropLEAVE_32, ropRETF_imm_32, ropRETF_32, NULL, NULL, NULL, NULL, -/*d0*/ ropD0, ropD1_l, ropD2, ropD3_l, NULL, NULL, NULL, ropXLAT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ ropLOOPNE, ropLOOPE, ropLOOP, ropJCXZ, NULL, NULL, NULL, NULL, ropCALL_r32, ropJMP_r32, ropJMP_far_32, ropJMP_r8, NULL, NULL, NULL, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, ropCMC, ropF6, ropF7_32, ropCLC, ropSTC, ropCLI, ropSTI, ropCLD, ropSTD, ropINCDEC, 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*/ ropPUNPCKLBW, ropPUNPCKLWD, ropPUNPCKLDQ, ropPACKSSWB, ropPCMPGTB, ropPCMPGTW, ropPCMPGTD, ropPACKUSWB, ropPUNPCKHBW, ropPUNPCKHWD, ropPUNPCKHDQ, ropPACKSSDW, NULL, NULL, ropMOVD_r_d, - ropMOVQ_r_q, -/*70*/ NULL, ropPSxxW_imm, ropPSxxD_imm, ropPSxxQ_imm, ropPCMPEQB, ropPCMPEQW, ropPCMPEQD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVD_d_r, ropMOVQ_q_r, - -/*80*/ ropJO_16, ropJNO_16, ropJB_16, ropJNB_16, ropJE_16, ropJNE_16, ropJBE_16, ropJNBE_16, ropJS_16, ropJNS_16, ropJP_16, ropJNP_16, ropJL_16, ropJNL_16, ropJLE_16, ropJNLE_16, -/*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, ropSHLD_16_imm, NULL, NULL, NULL, ropPUSH_GS_16, ropPOP_GS_16, NULL, NULL, ropSHRD_16_imm, NULL, NULL, NULL, -/*b0*/ NULL, NULL, ropLSS_16, NULL, ropLFS_16, ropLGS_16, ropMOVZX_16_8, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVSX_16_8, NULL, - -/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*d0*/ NULL, NULL, NULL, NULL, NULL, ropPMULLW, NULL, NULL, ropPSUBUSB, ropPSUBUSW, NULL, ropPAND, ropPADDUSB, ropPADDUSW, NULL, ropPANDN, -/*e0*/ NULL, NULL, NULL, NULL, NULL, ropPMULHW, NULL, NULL, ropPSUBSB, ropPSUBSW, NULL, ropPOR, ropPADDSB, ropPADDSW, NULL, ropPXOR, -/*f0*/ NULL, NULL, NULL, NULL, NULL, ropPMADDWD, NULL, NULL, ropPSUBB, ropPSUBW, ropPSUBD, NULL, ropPADDB, ropPADDW, ropPADDD, 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_r_d, - ropMOVQ_r_q, -/*70*/ NULL, ropPSxxW_imm, ropPSxxD_imm, ropPSxxQ_imm, ropPCMPEQB, ropPCMPEQW, ropPCMPEQD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVD_d_r, ropMOVQ_q_r, - -/*80*/ ropJO_32, ropJNO_32, ropJB_32, ropJNB_32, ropJE_32, ropJNE_32, ropJBE_32, ropJNBE_32, ropJS_32, ropJNS_32, ropJP_32, ropJNP_32, ropJL_32, ropJNL_32, ropJLE_32, ropJNLE_32, -/*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, ropSHLD_32_imm, NULL, NULL, NULL, ropPUSH_GS_32, ropPOP_GS_32, NULL, NULL, ropSHRD_32_imm, NULL, NULL, NULL, -/*b0*/ NULL, NULL, ropLSS_32, NULL, ropLFS_32, ropLGS_32, ropMOVZX_32_8, ropMOVZX_32_16, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVSX_32_8, ropMOVSX_32_16, - -/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*d0*/ NULL, NULL, NULL, NULL, NULL, ropPMULLW, NULL, NULL, ropPSUBUSB, ropPSUBUSW, NULL, ropPAND, ropPADDUSB, ropPADDUSW, NULL, ropPANDN, -/*e0*/ NULL, NULL, NULL, NULL, NULL, ropPMULHW, NULL, NULL, ropPSUBSB, ropPSUBSW, NULL, ropPOR, ropPADDSB, ropPADDSW, NULL, ropPXOR, -/*f0*/ NULL, NULL, NULL, NULL, NULL, ropPMADDWD, NULL, NULL, ropPSUBB, ropPSUBW, ropPSUBD, NULL, ropPADDB, ropPADDW, ropPADDD, NULL, - }; - -RecompOpFn recomp_opcodes_3DNOW[256] = - { -/* 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, ropPI2FD, NULL, NULL, -/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPF2ID, 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*/ ropPFCMPGE, NULL, NULL, NULL, ropPFMIN, NULL, ropPFRCP, ropPFRSQRT, NULL, NULL, ropPFSUB, NULL, NULL, NULL, ropPFADD, NULL, -/*a0*/ ropPFCMPGT, NULL, NULL, NULL, ropPFMAX, NULL, ropPFRCPIT, ropPFRSQIT1, NULL, NULL, ropPFSUBR, NULL, NULL, NULL, NULL, NULL, -/*b0*/ ropPFCMPEQ, NULL, NULL, NULL, ropPFMUL, NULL, ropPFRCPIT, 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_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, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*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, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*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, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*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, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, -/*e0*/ ropFCHS, ropFABS, NULL, NULL, ropFTST, NULL, NULL, NULL, ropFLD1, NULL, NULL, NULL, NULL, NULL, ropFLDZ, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSQRT, 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, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*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, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*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, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*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, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, -/*e0*/ ropFCHS, ropFABS, NULL, NULL, ropFTST, NULL, NULL, NULL, ropFLD1, NULL, NULL, NULL, NULL, NULL, ropFLDZ, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSQRT, 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*/ ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, -/*10*/ ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, -/*20*/ ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, -/*30*/ ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, - -/*40*/ ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, -/*50*/ ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, -/*60*/ ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, -/*70*/ ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, - -/*80*/ ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, -/*90*/ ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, -/*a0*/ ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, -/*b0*/ ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, - -/*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, ropFUCOMPP, 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*/ ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, -/*10*/ ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, -/*20*/ ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, -/*30*/ ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, - -/*40*/ ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, -/*50*/ ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, -/*60*/ ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, -/*70*/ ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, - -/*80*/ ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, -/*90*/ ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, ropFICOMPl, -/*a0*/ ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, ropFISUBRl, -/*b0*/ ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, ropFIDIVRl, - -/*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, ropFUCOMPP, 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*/ -/*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, - }; - -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, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, - -/*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, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, - -/*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, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, - -/*c0*/ ropFFREE, ropFFREE, ropFFREE, ropFFREE, ropFFREE, ropFFREE, ropFFREE, ropFFREE, 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*/ ropFUCOM, ropFUCOM, ropFUCOM, ropFUCOM, ropFUCOM, ropFUCOM, ropFUCOM, ropFUCOM, ropFUCOMP, ropFUCOMP, ropFUCOMP, ropFUCOMP, ropFUCOMP, ropFUCOMP, ropFUCOMP, ropFUCOMP, -/*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, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, - -/*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, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, - -/*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, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, ropFSTSW, - -/*c0*/ ropFFREE, ropFFREE, ropFFREE, ropFFREE, ropFFREE, ropFFREE, ropFFREE, ropFFREE, 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*/ ropFUCOM, ropFUCOM, ropFUCOM, ropFUCOM, ropFUCOM, ropFUCOM, ropFUCOM, ropFUCOM, ropFUCOMP, ropFUCOMP, ropFUCOMP, ropFUCOMP, ropFUCOMP, ropFUCOMP, ropFUCOMP, ropFUCOMP, -/*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*/ ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, -/*10*/ ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, -/*20*/ ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, -/*30*/ ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, - -/*40*/ ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, -/*50*/ ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, -/*60*/ ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, -/*70*/ ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, - -/*80*/ ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, -/*90*/ ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, -/*a0*/ ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, -/*b0*/ ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, - -/*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*/ ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, -/*10*/ ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, -/*20*/ ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, -/*30*/ ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, - -/*40*/ ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, -/*50*/ ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, -/*60*/ ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, -/*70*/ ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, - -/*80*/ ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, -/*90*/ ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, ropFICOMPw, -/*a0*/ ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, ropFISUBRw, -/*b0*/ ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, ropFIDIVRw, - -/*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[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*/ ropADC_b_rmw, ropADC_w_rmw, ropADC_b_rm, ropADC_w_rm, ropADC_AL_imm, ropADC_AX_imm, ropPUSH_SS_16, NULL, + ropSBB_b_rmw, ropSBB_w_rmw, ropSBB_b_rm, ropSBB_w_rm, ropSBB_AL_imm, ropSBB_AX_imm, 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_r16, ropINC_r16, ropINC_r16, ropINC_r16, ropINC_r16, ropINC_r16, ropINC_r16, ropINC_r16, ropDEC_r16, + ropDEC_r16, ropDEC_r16, ropDEC_r16, ropDEC_r16, ropDEC_r16, ropDEC_r16, ropDEC_r16, + /*50*/ ropPUSH_r16, ropPUSH_r16, ropPUSH_r16, ropPUSH_r16, ropPUSH_r16, ropPUSH_r16, ropPUSH_r16, ropPUSH_r16, ropPOP_r16, + ropPOP_r16, ropPOP_r16, ropPOP_r16, ropPOP_r16, ropPOP_r16, ropPOP_r16, ropPOP_r16, + /*60*/ ropPUSHA_16, ropPOPA_16, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_imm_16, NULL, ropPUSH_imm_16_8, NULL, NULL, + NULL, NULL, NULL, + /*70*/ ropJO_8, ropJNO_8, ropJB_8, ropJNB_8, ropJE_8, ropJNE_8, ropJBE_8, ropJNBE_8, ropJS_8, ropJNS_8, ropJP_8, ropJNP_8, + ropJL_8, ropJNL_8, ropJLE_8, ropJNLE_8, + + /*80*/ rop80, rop81_w, rop80, rop83_w, ropTEST_b_rm, ropTEST_w_rm, ropXCHG_8, ropXCHG_16, ropMOV_b_r, ropMOV_w_r, + ropMOV_r_b, ropMOV_r_w, ropMOV_w_seg, ropLEA_16, ropMOV_seg_w, ropPOP_W, + /*90*/ ropNOP, ropXCHG_AX, ropXCHG_AX, ropXCHG_AX, ropXCHG_AX, ropXCHG_AX, ropXCHG_AX, ropXCHG_AX, ropCBW, ropCWD, NULL, + NULL, ropPUSHF, NULL, NULL, NULL, + /*a0*/ ropMOV_AL_abs, ropMOV_AX_abs, ropMOV_abs_AL, ropMOV_abs_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_16, ropLDS_16, ropMOV_b_imm, ropMOV_w_imm, NULL, ropLEAVE_16, + ropRETF_imm_16, ropRETF_16, NULL, NULL, NULL, NULL, + /*d0*/ ropD0, ropD1_w, ropD2, ropD3_w, NULL, NULL, NULL, ropXLAT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + /*e0*/ ropLOOPNE, ropLOOPE, ropLOOP, ropJCXZ, NULL, NULL, NULL, NULL, ropCALL_r16, ropJMP_r16, ropJMP_far_16, ropJMP_r8, + NULL, NULL, NULL, NULL, + /*f0*/ NULL, NULL, NULL, NULL, NULL, ropCMC, ropF6, ropF7_16, ropCLC, ropSTC, ropCLI, ropSTI, ropCLD, ropSTD, ropINCDEC, + 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*/ ropADC_b_rmw, ropADC_l_rmw, ropADC_b_rm, ropADC_l_rm, ropADC_AL_imm, ropADC_EAX_imm, ropPUSH_SS_32, NULL, + ropSBB_b_rmw, ropSBB_l_rmw, ropSBB_b_rm, ropSBB_l_rm, ropSBB_AL_imm, ropSBB_EAX_imm, 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_r32, ropINC_r32, ropINC_r32, ropINC_r32, ropINC_r32, ropINC_r32, ropINC_r32, ropINC_r32, ropDEC_r32, + ropDEC_r32, ropDEC_r32, ropDEC_r32, ropDEC_r32, ropDEC_r32, ropDEC_r32, ropDEC_r32, + /*50*/ ropPUSH_r32, ropPUSH_r32, ropPUSH_r32, ropPUSH_r32, ropPUSH_r32, ropPUSH_r32, ropPUSH_r32, ropPUSH_r32, ropPOP_r32, + ropPOP_r32, ropPOP_r32, ropPOP_r32, ropPOP_r32, ropPOP_r32, ropPOP_r32, ropPOP_r32, + /*60*/ ropPUSHA_32, ropPOPA_32, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_imm_32, NULL, ropPUSH_imm_32_8, NULL, NULL, + NULL, NULL, NULL, + /*70*/ ropJO_8, ropJNO_8, ropJB_8, ropJNB_8, ropJE_8, ropJNE_8, ropJBE_8, ropJNBE_8, ropJS_8, ropJNS_8, ropJP_8, ropJNP_8, + ropJL_8, ropJNL_8, ropJLE_8, ropJNLE_8, + + /*80*/ rop80, rop81_l, rop80, rop83_l, ropTEST_b_rm, ropTEST_l_rm, ropXCHG_8, ropXCHG_32, ropMOV_b_r, ropMOV_l_r, + ropMOV_r_b, ropMOV_r_l, ropMOV_l_seg, ropLEA_32, ropMOV_seg_w, ropPOP_L, + /*90*/ ropNOP, ropXCHG_EAX, ropXCHG_EAX, ropXCHG_EAX, ropXCHG_EAX, ropXCHG_EAX, ropXCHG_EAX, ropXCHG_EAX, ropCWDE, ropCDQ, + NULL, NULL, ropPUSHFD, NULL, NULL, NULL, + /*a0*/ ropMOV_AL_abs, ropMOV_EAX_abs, ropMOV_abs_AL, ropMOV_abs_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_32, ropLDS_32, ropMOV_b_imm, ropMOV_l_imm, NULL, ropLEAVE_32, + ropRETF_imm_32, ropRETF_32, NULL, NULL, NULL, NULL, + /*d0*/ ropD0, ropD1_l, ropD2, ropD3_l, NULL, NULL, NULL, ropXLAT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + /*e0*/ ropLOOPNE, ropLOOPE, ropLOOP, ropJCXZ, NULL, NULL, NULL, NULL, ropCALL_r32, ropJMP_r32, ropJMP_far_32, ropJMP_r8, + NULL, NULL, NULL, NULL, + /*f0*/ NULL, NULL, NULL, NULL, NULL, ropCMC, ropF6, ropF7_32, ropCLC, ropSTC, ropCLI, ropSTI, ropCLD, ropSTD, ropINCDEC, + 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*/ ropPUNPCKLBW, + ropPUNPCKLWD, + ropPUNPCKLDQ, + ropPACKSSWB, + ropPCMPGTB, + ropPCMPGTW, + ropPCMPGTD, + ropPACKUSWB, + ropPUNPCKHBW, + ropPUNPCKHWD, + ropPUNPCKHDQ, + ropPACKSSDW, + NULL, + NULL, + ropMOVD_r_d, + ropMOVQ_r_q, + /*70*/ NULL, + ropPSxxW_imm, + ropPSxxD_imm, + ropPSxxQ_imm, + ropPCMPEQB, + ropPCMPEQW, + ropPCMPEQD, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + ropMOVD_d_r, + ropMOVQ_q_r, + + /*80*/ ropJO_16, + ropJNO_16, + ropJB_16, + ropJNB_16, + ropJE_16, + ropJNE_16, + ropJBE_16, + ropJNBE_16, + ropJS_16, + ropJNS_16, + ropJP_16, + ropJNP_16, + ropJL_16, + ropJNL_16, + ropJLE_16, + ropJNLE_16, + /*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, + ropSHLD_16_imm, + NULL, + NULL, + NULL, + ropPUSH_GS_16, + ropPOP_GS_16, + NULL, + NULL, + ropSHRD_16_imm, + NULL, + NULL, + NULL, + /*b0*/ NULL, + NULL, + ropLSS_16, + NULL, + ropLFS_16, + ropLGS_16, + ropMOVZX_16_8, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + ropMOVSX_16_8, + NULL, + + /*c0*/ NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + /*d0*/ NULL, + NULL, + NULL, + NULL, + NULL, + ropPMULLW, + NULL, + NULL, + ropPSUBUSB, + ropPSUBUSW, + NULL, + ropPAND, + ropPADDUSB, + ropPADDUSW, + NULL, + ropPANDN, + /*e0*/ NULL, + NULL, + NULL, + NULL, + NULL, + ropPMULHW, + NULL, + NULL, + ropPSUBSB, + ropPSUBSW, + NULL, + ropPOR, + ropPADDSB, + ropPADDSW, + NULL, + ropPXOR, + /*f0*/ NULL, + NULL, + NULL, + NULL, + NULL, + ropPMADDWD, + NULL, + NULL, + ropPSUBB, + ropPSUBW, + ropPSUBD, + NULL, + ropPADDB, + ropPADDW, + ropPADDD, + 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_r_d, + ropMOVQ_r_q, + /*70*/ NULL, + ropPSxxW_imm, + ropPSxxD_imm, + ropPSxxQ_imm, + ropPCMPEQB, + ropPCMPEQW, + ropPCMPEQD, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + ropMOVD_d_r, + ropMOVQ_q_r, + + /*80*/ ropJO_32, + ropJNO_32, + ropJB_32, + ropJNB_32, + ropJE_32, + ropJNE_32, + ropJBE_32, + ropJNBE_32, + ropJS_32, + ropJNS_32, + ropJP_32, + ropJNP_32, + ropJL_32, + ropJNL_32, + ropJLE_32, + ropJNLE_32, + /*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, + ropSHLD_32_imm, + NULL, + NULL, + NULL, + ropPUSH_GS_32, + ropPOP_GS_32, + NULL, + NULL, + ropSHRD_32_imm, + NULL, + NULL, + NULL, + /*b0*/ NULL, + NULL, + ropLSS_32, + NULL, + ropLFS_32, + ropLGS_32, + ropMOVZX_32_8, + ropMOVZX_32_16, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + ropMOVSX_32_8, + ropMOVSX_32_16, + + /*c0*/ NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + /*d0*/ NULL, + NULL, + NULL, + NULL, + NULL, + ropPMULLW, + NULL, + NULL, + ropPSUBUSB, + ropPSUBUSW, + NULL, + ropPAND, + ropPADDUSB, + ropPADDUSW, + NULL, + ropPANDN, + /*e0*/ NULL, + NULL, + NULL, + NULL, + NULL, + ropPMULHW, + NULL, + NULL, + ropPSUBSB, + ropPSUBSW, + NULL, + ropPOR, + ropPADDSB, + ropPADDSW, + NULL, + ropPXOR, + /*f0*/ NULL, + NULL, + NULL, + NULL, + NULL, + ropPMADDWD, + NULL, + NULL, + ropPSUBB, + ropPSUBW, + ropPSUBD, + NULL, + ropPADDB, + ropPADDW, + ropPADDD, + NULL, +}; + +RecompOpFn recomp_opcodes_3DNOW[256] = { + /* 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, + ropPI2FD, + NULL, + NULL, + /*10*/ NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + ropPF2ID, + 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*/ ropPFCMPGE, + NULL, + NULL, + NULL, + ropPFMIN, + NULL, + ropPFRCP, + ropPFRSQRT, + NULL, + NULL, + ropPFSUB, + NULL, + NULL, + NULL, + ropPFADD, + NULL, + /*a0*/ ropPFCMPGT, + NULL, + NULL, + NULL, + ropPFMAX, + NULL, + ropPFRCPIT, + ropPFRSQIT1, + NULL, + NULL, + ropPFSUBR, + NULL, + NULL, + NULL, + NULL, + NULL, + /*b0*/ ropPFCMPEQ, + NULL, + NULL, + NULL, + ropPFMUL, + NULL, + ropPFRCPIT, + 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_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, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + /*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, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + /*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, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + /*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, + ropFSTP, + ropFSTP, + ropFSTP, + ropFSTP, + ropFSTP, + ropFSTP, + ropFSTP, + ropFSTP, + /*e0*/ ropFCHS, + ropFABS, + NULL, + NULL, + ropFTST, + NULL, + NULL, + NULL, + ropFLD1, + NULL, + NULL, + NULL, + NULL, + NULL, + ropFLDZ, + NULL, + /*f0*/ NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + ropFSQRT, + 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, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + /*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, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + /*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, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + /*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, + ropFSTP, + ropFSTP, + ropFSTP, + ropFSTP, + ropFSTP, + ropFSTP, + ropFSTP, + ropFSTP, + /*e0*/ ropFCHS, + ropFABS, + NULL, + NULL, + ropFTST, + NULL, + NULL, + NULL, + ropFLD1, + NULL, + NULL, + NULL, + NULL, + NULL, + ropFLDZ, + NULL, + /*f0*/ NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + ropFSQRT, + 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*/ ropFIADDl, + ropFIADDl, + ropFIADDl, + ropFIADDl, + ropFIADDl, + ropFIADDl, + ropFIADDl, + ropFIADDl, + ropFIMULl, + ropFIMULl, + ropFIMULl, + ropFIMULl, + ropFIMULl, + ropFIMULl, + ropFIMULl, + ropFIMULl, + /*10*/ ropFICOMl, + ropFICOMl, + ropFICOMl, + ropFICOMl, + ropFICOMl, + ropFICOMl, + ropFICOMl, + ropFICOMl, + ropFICOMPl, + ropFICOMPl, + ropFICOMPl, + ropFICOMPl, + ropFICOMPl, + ropFICOMPl, + ropFICOMPl, + ropFICOMPl, + /*20*/ ropFISUBl, + ropFISUBl, + ropFISUBl, + ropFISUBl, + ropFISUBl, + ropFISUBl, + ropFISUBl, + ropFISUBl, + ropFISUBRl, + ropFISUBRl, + ropFISUBRl, + ropFISUBRl, + ropFISUBRl, + ropFISUBRl, + ropFISUBRl, + ropFISUBRl, + /*30*/ ropFIDIVl, + ropFIDIVl, + ropFIDIVl, + ropFIDIVl, + ropFIDIVl, + ropFIDIVl, + ropFIDIVl, + ropFIDIVl, + ropFIDIVRl, + ropFIDIVRl, + ropFIDIVRl, + ropFIDIVRl, + ropFIDIVRl, + ropFIDIVRl, + ropFIDIVRl, + ropFIDIVRl, + + /*40*/ ropFIADDl, + ropFIADDl, + ropFIADDl, + ropFIADDl, + ropFIADDl, + ropFIADDl, + ropFIADDl, + ropFIADDl, + ropFIMULl, + ropFIMULl, + ropFIMULl, + ropFIMULl, + ropFIMULl, + ropFIMULl, + ropFIMULl, + ropFIMULl, + /*50*/ ropFICOMl, + ropFICOMl, + ropFICOMl, + ropFICOMl, + ropFICOMl, + ropFICOMl, + ropFICOMl, + ropFICOMl, + ropFICOMPl, + ropFICOMPl, + ropFICOMPl, + ropFICOMPl, + ropFICOMPl, + ropFICOMPl, + ropFICOMPl, + ropFICOMPl, + /*60*/ ropFISUBl, + ropFISUBl, + ropFISUBl, + ropFISUBl, + ropFISUBl, + ropFISUBl, + ropFISUBl, + ropFISUBl, + ropFISUBRl, + ropFISUBRl, + ropFISUBRl, + ropFISUBRl, + ropFISUBRl, + ropFISUBRl, + ropFISUBRl, + ropFISUBRl, + /*70*/ ropFIDIVl, + ropFIDIVl, + ropFIDIVl, + ropFIDIVl, + ropFIDIVl, + ropFIDIVl, + ropFIDIVl, + ropFIDIVl, + ropFIDIVRl, + ropFIDIVRl, + ropFIDIVRl, + ropFIDIVRl, + ropFIDIVRl, + ropFIDIVRl, + ropFIDIVRl, + ropFIDIVRl, + + /*80*/ ropFIADDl, + ropFIADDl, + ropFIADDl, + ropFIADDl, + ropFIADDl, + ropFIADDl, + ropFIADDl, + ropFIADDl, + ropFIMULl, + ropFIMULl, + ropFIMULl, + ropFIMULl, + ropFIMULl, + ropFIMULl, + ropFIMULl, + ropFIMULl, + /*90*/ ropFICOMl, + ropFICOMl, + ropFICOMl, + ropFICOMl, + ropFICOMl, + ropFICOMl, + ropFICOMl, + ropFICOMl, + ropFICOMPl, + ropFICOMPl, + ropFICOMPl, + ropFICOMPl, + ropFICOMPl, + ropFICOMPl, + ropFICOMPl, + ropFICOMPl, + /*a0*/ ropFISUBl, + ropFISUBl, + ropFISUBl, + ropFISUBl, + ropFISUBl, + ropFISUBl, + ropFISUBl, + ropFISUBl, + ropFISUBRl, + ropFISUBRl, + ropFISUBRl, + ropFISUBRl, + ropFISUBRl, + ropFISUBRl, + ropFISUBRl, + ropFISUBRl, + /*b0*/ ropFIDIVl, + ropFIDIVl, + ropFIDIVl, + ropFIDIVl, + ropFIDIVl, + ropFIDIVl, + ropFIDIVl, + ropFIDIVl, + ropFIDIVRl, + ropFIDIVRl, + ropFIDIVRl, + ropFIDIVRl, + ropFIDIVRl, + ropFIDIVRl, + ropFIDIVRl, + ropFIDIVRl, + + /*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, + ropFUCOMPP, + 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*/ ropFIADDl, + ropFIADDl, + ropFIADDl, + ropFIADDl, + ropFIADDl, + ropFIADDl, + ropFIADDl, + ropFIADDl, + ropFIMULl, + ropFIMULl, + ropFIMULl, + ropFIMULl, + ropFIMULl, + ropFIMULl, + ropFIMULl, + ropFIMULl, + /*10*/ ropFICOMl, + ropFICOMl, + ropFICOMl, + ropFICOMl, + ropFICOMl, + ropFICOMl, + ropFICOMl, + ropFICOMl, + ropFICOMPl, + ropFICOMPl, + ropFICOMPl, + ropFICOMPl, + ropFICOMPl, + ropFICOMPl, + ropFICOMPl, + ropFICOMPl, + /*20*/ ropFISUBl, + ropFISUBl, + ropFISUBl, + ropFISUBl, + ropFISUBl, + ropFISUBl, + ropFISUBl, + ropFISUBl, + ropFISUBRl, + ropFISUBRl, + ropFISUBRl, + ropFISUBRl, + ropFISUBRl, + ropFISUBRl, + ropFISUBRl, + ropFISUBRl, + /*30*/ ropFIDIVl, + ropFIDIVl, + ropFIDIVl, + ropFIDIVl, + ropFIDIVl, + ropFIDIVl, + ropFIDIVl, + ropFIDIVl, + ropFIDIVRl, + ropFIDIVRl, + ropFIDIVRl, + ropFIDIVRl, + ropFIDIVRl, + ropFIDIVRl, + ropFIDIVRl, + ropFIDIVRl, + + /*40*/ ropFIADDl, + ropFIADDl, + ropFIADDl, + ropFIADDl, + ropFIADDl, + ropFIADDl, + ropFIADDl, + ropFIADDl, + ropFIMULl, + ropFIMULl, + ropFIMULl, + ropFIMULl, + ropFIMULl, + ropFIMULl, + ropFIMULl, + ropFIMULl, + /*50*/ ropFICOMl, + ropFICOMl, + ropFICOMl, + ropFICOMl, + ropFICOMl, + ropFICOMl, + ropFICOMl, + ropFICOMl, + ropFICOMPl, + ropFICOMPl, + ropFICOMPl, + ropFICOMPl, + ropFICOMPl, + ropFICOMPl, + ropFICOMPl, + ropFICOMPl, + /*60*/ ropFISUBl, + ropFISUBl, + ropFISUBl, + ropFISUBl, + ropFISUBl, + ropFISUBl, + ropFISUBl, + ropFISUBl, + ropFISUBRl, + ropFISUBRl, + ropFISUBRl, + ropFISUBRl, + ropFISUBRl, + ropFISUBRl, + ropFISUBRl, + ropFISUBRl, + /*70*/ ropFIDIVl, + ropFIDIVl, + ropFIDIVl, + ropFIDIVl, + ropFIDIVl, + ropFIDIVl, + ropFIDIVl, + ropFIDIVl, + ropFIDIVRl, + ropFIDIVRl, + ropFIDIVRl, + ropFIDIVRl, + ropFIDIVRl, + ropFIDIVRl, + ropFIDIVRl, + ropFIDIVRl, + + /*80*/ ropFIADDl, + ropFIADDl, + ropFIADDl, + ropFIADDl, + ropFIADDl, + ropFIADDl, + ropFIADDl, + ropFIADDl, + ropFIMULl, + ropFIMULl, + ropFIMULl, + ropFIMULl, + ropFIMULl, + ropFIMULl, + ropFIMULl, + ropFIMULl, + /*90*/ ropFICOMl, + ropFICOMl, + ropFICOMl, + ropFICOMl, + ropFICOMl, + ropFICOMl, + ropFICOMl, + ropFICOMl, + ropFICOMPl, + ropFICOMPl, + ropFICOMPl, + ropFICOMPl, + ropFICOMPl, + ropFICOMPl, + ropFICOMPl, + ropFICOMPl, + /*a0*/ ropFISUBl, + ropFISUBl, + ropFISUBl, + ropFISUBl, + ropFISUBl, + ropFISUBl, + ropFISUBl, + ropFISUBl, + ropFISUBRl, + ropFISUBRl, + ropFISUBRl, + ropFISUBRl, + ropFISUBRl, + ropFISUBRl, + ropFISUBRl, + ropFISUBRl, + /*b0*/ ropFIDIVl, + ropFIDIVl, + ropFIDIVl, + ropFIDIVl, + ropFIDIVl, + ropFIDIVl, + ropFIDIVl, + ropFIDIVl, + ropFIDIVRl, + ropFIDIVRl, + ropFIDIVRl, + ropFIDIVRl, + ropFIDIVRl, + ropFIDIVRl, + ropFIDIVRl, + ropFIDIVRl, + + /*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, + ropFUCOMPP, + 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*/ + /*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, +}; + +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, + ropFSTSW, + ropFSTSW, + ropFSTSW, + ropFSTSW, + ropFSTSW, + ropFSTSW, + ropFSTSW, + ropFSTSW, + + /*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, + ropFSTSW, + ropFSTSW, + ropFSTSW, + ropFSTSW, + ropFSTSW, + ropFSTSW, + ropFSTSW, + ropFSTSW, + + /*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, + ropFSTSW, + ropFSTSW, + ropFSTSW, + ropFSTSW, + ropFSTSW, + ropFSTSW, + ropFSTSW, + ropFSTSW, + + /*c0*/ ropFFREE, + ropFFREE, + ropFFREE, + ropFFREE, + ropFFREE, + ropFFREE, + ropFFREE, + ropFFREE, + 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*/ ropFUCOM, + ropFUCOM, + ropFUCOM, + ropFUCOM, + ropFUCOM, + ropFUCOM, + ropFUCOM, + ropFUCOM, + ropFUCOMP, + ropFUCOMP, + ropFUCOMP, + ropFUCOMP, + ropFUCOMP, + ropFUCOMP, + ropFUCOMP, + ropFUCOMP, + /*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, + ropFSTSW, + ropFSTSW, + ropFSTSW, + ropFSTSW, + ropFSTSW, + ropFSTSW, + ropFSTSW, + ropFSTSW, + + /*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, + ropFSTSW, + ropFSTSW, + ropFSTSW, + ropFSTSW, + ropFSTSW, + ropFSTSW, + ropFSTSW, + ropFSTSW, + + /*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, + ropFSTSW, + ropFSTSW, + ropFSTSW, + ropFSTSW, + ropFSTSW, + ropFSTSW, + ropFSTSW, + ropFSTSW, + + /*c0*/ ropFFREE, + ropFFREE, + ropFFREE, + ropFFREE, + ropFFREE, + ropFFREE, + ropFFREE, + ropFFREE, + 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*/ ropFUCOM, + ropFUCOM, + ropFUCOM, + ropFUCOM, + ropFUCOM, + ropFUCOM, + ropFUCOM, + ropFUCOM, + ropFUCOMP, + ropFUCOMP, + ropFUCOMP, + ropFUCOMP, + ropFUCOMP, + ropFUCOMP, + ropFUCOMP, + ropFUCOMP, + /*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*/ ropFIADDw, + ropFIADDw, + ropFIADDw, + ropFIADDw, + ropFIADDw, + ropFIADDw, + ropFIADDw, + ropFIADDw, + ropFIMULw, + ropFIMULw, + ropFIMULw, + ropFIMULw, + ropFIMULw, + ropFIMULw, + ropFIMULw, + ropFIMULw, + /*10*/ ropFICOMw, + ropFICOMw, + ropFICOMw, + ropFICOMw, + ropFICOMw, + ropFICOMw, + ropFICOMw, + ropFICOMw, + ropFICOMPw, + ropFICOMPw, + ropFICOMPw, + ropFICOMPw, + ropFICOMPw, + ropFICOMPw, + ropFICOMPw, + ropFICOMPw, + /*20*/ ropFISUBw, + ropFISUBw, + ropFISUBw, + ropFISUBw, + ropFISUBw, + ropFISUBw, + ropFISUBw, + ropFISUBw, + ropFISUBRw, + ropFISUBRw, + ropFISUBRw, + ropFISUBRw, + ropFISUBRw, + ropFISUBRw, + ropFISUBRw, + ropFISUBRw, + /*30*/ ropFIDIVw, + ropFIDIVw, + ropFIDIVw, + ropFIDIVw, + ropFIDIVw, + ropFIDIVw, + ropFIDIVw, + ropFIDIVw, + ropFIDIVRw, + ropFIDIVRw, + ropFIDIVRw, + ropFIDIVRw, + ropFIDIVRw, + ropFIDIVRw, + ropFIDIVRw, + ropFIDIVRw, + + /*40*/ ropFIADDw, + ropFIADDw, + ropFIADDw, + ropFIADDw, + ropFIADDw, + ropFIADDw, + ropFIADDw, + ropFIADDw, + ropFIMULw, + ropFIMULw, + ropFIMULw, + ropFIMULw, + ropFIMULw, + ropFIMULw, + ropFIMULw, + ropFIMULw, + /*50*/ ropFICOMw, + ropFICOMw, + ropFICOMw, + ropFICOMw, + ropFICOMw, + ropFICOMw, + ropFICOMw, + ropFICOMw, + ropFICOMPw, + ropFICOMPw, + ropFICOMPw, + ropFICOMPw, + ropFICOMPw, + ropFICOMPw, + ropFICOMPw, + ropFICOMPw, + /*60*/ ropFISUBw, + ropFISUBw, + ropFISUBw, + ropFISUBw, + ropFISUBw, + ropFISUBw, + ropFISUBw, + ropFISUBw, + ropFISUBRw, + ropFISUBRw, + ropFISUBRw, + ropFISUBRw, + ropFISUBRw, + ropFISUBRw, + ropFISUBRw, + ropFISUBRw, + /*70*/ ropFIDIVw, + ropFIDIVw, + ropFIDIVw, + ropFIDIVw, + ropFIDIVw, + ropFIDIVw, + ropFIDIVw, + ropFIDIVw, + ropFIDIVRw, + ropFIDIVRw, + ropFIDIVRw, + ropFIDIVRw, + ropFIDIVRw, + ropFIDIVRw, + ropFIDIVRw, + ropFIDIVRw, + + /*80*/ ropFIADDw, + ropFIADDw, + ropFIADDw, + ropFIADDw, + ropFIADDw, + ropFIADDw, + ropFIADDw, + ropFIADDw, + ropFIMULw, + ropFIMULw, + ropFIMULw, + ropFIMULw, + ropFIMULw, + ropFIMULw, + ropFIMULw, + ropFIMULw, + /*90*/ ropFICOMw, + ropFICOMw, + ropFICOMw, + ropFICOMw, + ropFICOMw, + ropFICOMw, + ropFICOMw, + ropFICOMw, + ropFICOMPw, + ropFICOMPw, + ropFICOMPw, + ropFICOMPw, + ropFICOMPw, + ropFICOMPw, + ropFICOMPw, + ropFICOMPw, + /*a0*/ ropFISUBw, + ropFISUBw, + ropFISUBw, + ropFISUBw, + ropFISUBw, + ropFISUBw, + ropFISUBw, + ropFISUBw, + ropFISUBRw, + ropFISUBRw, + ropFISUBRw, + ropFISUBRw, + ropFISUBRw, + ropFISUBRw, + ropFISUBRw, + ropFISUBRw, + /*b0*/ ropFIDIVw, + ropFIDIVw, + ropFIDIVw, + ropFIDIVw, + ropFIDIVw, + ropFIDIVw, + ropFIDIVw, + ropFIDIVw, + ropFIDIVRw, + ropFIDIVRw, + ropFIDIVRw, + ropFIDIVRw, + ropFIDIVRw, + ropFIDIVRw, + ropFIDIVRw, + ropFIDIVRw, + + /*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*/ ropFIADDw, + ropFIADDw, + ropFIADDw, + ropFIADDw, + ropFIADDw, + ropFIADDw, + ropFIADDw, + ropFIADDw, + ropFIMULw, + ropFIMULw, + ropFIMULw, + ropFIMULw, + ropFIMULw, + ropFIMULw, + ropFIMULw, + ropFIMULw, + /*10*/ ropFICOMw, + ropFICOMw, + ropFICOMw, + ropFICOMw, + ropFICOMw, + ropFICOMw, + ropFICOMw, + ropFICOMw, + ropFICOMPw, + ropFICOMPw, + ropFICOMPw, + ropFICOMPw, + ropFICOMPw, + ropFICOMPw, + ropFICOMPw, + ropFICOMPw, + /*20*/ ropFISUBw, + ropFISUBw, + ropFISUBw, + ropFISUBw, + ropFISUBw, + ropFISUBw, + ropFISUBw, + ropFISUBw, + ropFISUBRw, + ropFISUBRw, + ropFISUBRw, + ropFISUBRw, + ropFISUBRw, + ropFISUBRw, + ropFISUBRw, + ropFISUBRw, + /*30*/ ropFIDIVw, + ropFIDIVw, + ropFIDIVw, + ropFIDIVw, + ropFIDIVw, + ropFIDIVw, + ropFIDIVw, + ropFIDIVw, + ropFIDIVRw, + ropFIDIVRw, + ropFIDIVRw, + ropFIDIVRw, + ropFIDIVRw, + ropFIDIVRw, + ropFIDIVRw, + ropFIDIVRw, + + /*40*/ ropFIADDw, + ropFIADDw, + ropFIADDw, + ropFIADDw, + ropFIADDw, + ropFIADDw, + ropFIADDw, + ropFIADDw, + ropFIMULw, + ropFIMULw, + ropFIMULw, + ropFIMULw, + ropFIMULw, + ropFIMULw, + ropFIMULw, + ropFIMULw, + /*50*/ ropFICOMw, + ropFICOMw, + ropFICOMw, + ropFICOMw, + ropFICOMw, + ropFICOMw, + ropFICOMw, + ropFICOMw, + ropFICOMPw, + ropFICOMPw, + ropFICOMPw, + ropFICOMPw, + ropFICOMPw, + ropFICOMPw, + ropFICOMPw, + ropFICOMPw, + /*60*/ ropFISUBw, + ropFISUBw, + ropFISUBw, + ropFISUBw, + ropFISUBw, + ropFISUBw, + ropFISUBw, + ropFISUBw, + ropFISUBRw, + ropFISUBRw, + ropFISUBRw, + ropFISUBRw, + ropFISUBRw, + ropFISUBRw, + ropFISUBRw, + ropFISUBRw, + /*70*/ ropFIDIVw, + ropFIDIVw, + ropFIDIVw, + ropFIDIVw, + ropFIDIVw, + ropFIDIVw, + ropFIDIVw, + ropFIDIVw, + ropFIDIVRw, + ropFIDIVRw, + ropFIDIVRw, + ropFIDIVRw, + ropFIDIVRw, + ropFIDIVRw, + ropFIDIVRw, + ropFIDIVRw, + + /*80*/ ropFIADDw, + ropFIADDw, + ropFIADDw, + ropFIADDw, + ropFIADDw, + ropFIADDw, + ropFIADDw, + ropFIADDw, + ropFIMULw, + ropFIMULw, + ropFIMULw, + ropFIMULw, + ropFIMULw, + ropFIMULw, + ropFIMULw, + ropFIMULw, + /*90*/ ropFICOMw, + ropFICOMw, + ropFICOMw, + ropFICOMw, + ropFICOMw, + ropFICOMw, + ropFICOMw, + ropFICOMw, + ropFICOMPw, + ropFICOMPw, + ropFICOMPw, + ropFICOMPw, + ropFICOMPw, + ropFICOMPw, + ropFICOMPw, + ropFICOMPw, + /*a0*/ ropFISUBw, + ropFISUBw, + ropFISUBw, + ropFISUBw, + ropFISUBw, + ropFISUBw, + ropFISUBw, + ropFISUBw, + ropFISUBRw, + ropFISUBRw, + ropFISUBRw, + ropFISUBRw, + ropFISUBRw, + ropFISUBRw, + ropFISUBRw, + ropFISUBRw, + /*b0*/ ropFIDIVw, + ropFIDIVw, + ropFIDIVw, + ropFIDIVw, + ropFIDIVw, + ropFIDIVw, + ropFIDIVw, + ropFIDIVw, + ropFIDIVRw, + ropFIDIVRw, + ropFIDIVRw, + ropFIDIVRw, + ropFIDIVRw, + ropFIDIVRw, + ropFIDIVRw, + ropFIDIVRw, + + /*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, +}; diff --git a/src/codegen/codegen_ops_3dnow.c b/src/codegen/codegen_ops_3dnow.c index 10eb26b6..8995a6bd 100644 --- a/src/codegen/codegen_ops_3dnow.c +++ b/src/codegen/codegen_ops_3dnow.c @@ -10,174 +10,166 @@ #include "codegen_ops_3dnow.h" #include "codegen_ops_helpers.h" -#define ropParith(func) \ -uint32_t rop ## func(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - int dest_reg = (fetchdat >> 3) & 7; \ - \ - uop_MMX_ENTER(ir); \ - codegen_mark_code_present(block, cs+op_pc, 1); \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - int src_reg = fetchdat & 7; \ - uop_ ## func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); \ - } \ - else \ - { \ - x86seg *target_seg; \ - \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_ ## func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); \ - } \ - \ - codegen_mark_code_present(block, cs+op_pc+1, 1); \ - return op_pc + 2; \ -} +#define ropParith(func) \ + uint32_t rop##func(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, \ + uint32_t op_pc) { \ + int dest_reg = (fetchdat >> 3) & 7; \ + \ + uop_MMX_ENTER(ir); \ + codegen_mark_code_present(block, cs + op_pc, 1); \ + if ((fetchdat & 0xc0) == 0xc0) { \ + int src_reg = fetchdat & 7; \ + uop_##func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); \ + } else { \ + x86seg *target_seg; \ + \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_##func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); \ + } \ + \ + codegen_mark_code_present(block, cs + op_pc + 1, 1); \ + return op_pc + 2; \ + } -ropParith(PFADD) -ropParith(PFCMPEQ) -ropParith(PFCMPGE) -ropParith(PFCMPGT) -ropParith(PFMAX) -ropParith(PFMIN) -ropParith(PFMUL) -ropParith(PFSUB) +ropParith(PFADD) ropParith(PFCMPEQ) ropParith(PFCMPGE) ropParith(PFCMPGT) ropParith(PFMAX) ropParith(PFMIN) ropParith(PFMUL) + ropParith(PFSUB) -uint32_t ropPF2ID(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + uint32_t + ropPF2ID(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { + int dest_reg = (fetchdat >> 3) & 7; - uop_MMX_ENTER(ir); - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int src_reg = fetchdat & 7; - uop_PF2ID(ir, IREG_MM(dest_reg), IREG_MM(src_reg)); - } else { - x86seg *target_seg; + uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_PF2ID(ir, IREG_MM(dest_reg), IREG_MM(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); - uop_PF2ID(ir, IREG_MM(dest_reg), IREG_temp0_Q); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); + uop_PF2ID(ir, IREG_MM(dest_reg), IREG_temp0_Q); + } - codegen_mark_code_present(block, cs + op_pc + 1, 1); - return op_pc + 2; + codegen_mark_code_present(block, cs + op_pc + 1, 1); + return op_pc + 2; } uint32_t ropPFSUBR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - uop_MMX_ENTER(ir); - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int src_reg = fetchdat & 7; - uop_PFSUB(ir, IREG_MM(dest_reg), IREG_MM(src_reg), IREG_MM(dest_reg)); - } else { - x86seg *target_seg; + uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_PFSUB(ir, IREG_MM(dest_reg), IREG_MM(src_reg), IREG_MM(dest_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); - uop_PFSUB(ir, IREG_MM(dest_reg), IREG_temp0_Q, IREG_MM(dest_reg)); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); + uop_PFSUB(ir, IREG_MM(dest_reg), IREG_temp0_Q, IREG_MM(dest_reg)); + } - codegen_mark_code_present(block, cs + op_pc + 1, 1); - return op_pc + 2; + codegen_mark_code_present(block, cs + op_pc + 1, 1); + return op_pc + 2; } uint32_t ropPI2FD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - uop_MMX_ENTER(ir); - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int src_reg = fetchdat & 7; - uop_PI2FD(ir, IREG_MM(dest_reg), IREG_MM(src_reg)); - } else { - x86seg *target_seg; + uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_PI2FD(ir, IREG_MM(dest_reg), IREG_MM(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); - uop_PI2FD(ir, IREG_MM(dest_reg), IREG_temp0_Q); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); + uop_PI2FD(ir, IREG_MM(dest_reg), IREG_temp0_Q); + } - codegen_mark_code_present(block, cs + op_pc + 1, 1); - return op_pc + 2; + codegen_mark_code_present(block, cs + op_pc + 1, 1); + return op_pc + 2; } uint32_t ropPFRCPIT(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - uop_MMX_ENTER(ir); - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int src_reg = fetchdat & 7; - uop_MOV(ir, IREG_MM(dest_reg), IREG_MM(src_reg)); - } else { - x86seg *target_seg; + uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_MOV(ir, IREG_MM(dest_reg), IREG_MM(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_MM(dest_reg), ireg_seg_base(target_seg), IREG_eaaddr); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_MM(dest_reg), ireg_seg_base(target_seg), IREG_eaaddr); + } - codegen_mark_code_present(block, cs + op_pc + 1, 1); - return op_pc + 2; + codegen_mark_code_present(block, cs + op_pc + 1, 1); + return op_pc + 2; } uint32_t ropPFRCP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - uop_MMX_ENTER(ir); - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int src_reg = fetchdat & 7; - uop_PFRCP(ir, IREG_MM(dest_reg), IREG_MM(src_reg)); - } else { - x86seg *target_seg; + uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_PFRCP(ir, IREG_MM(dest_reg), IREG_MM(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); - uop_PFRCP(ir, IREG_MM(dest_reg), IREG_temp0_Q); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); + uop_PFRCP(ir, IREG_MM(dest_reg), IREG_temp0_Q); + } - codegen_mark_code_present(block, cs + op_pc + 1, 1); - return op_pc + 2; + codegen_mark_code_present(block, cs + op_pc + 1, 1); + return op_pc + 2; } uint32_t ropPFRSQRT(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - uop_MMX_ENTER(ir); - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int src_reg = fetchdat & 7; - uop_PFRSQRT(ir, IREG_MM(dest_reg), IREG_MM(src_reg)); - } else { - x86seg *target_seg; + uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_PFRSQRT(ir, IREG_MM(dest_reg), IREG_MM(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); - uop_PFRSQRT(ir, IREG_MM(dest_reg), IREG_temp0_Q); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); + uop_PFRSQRT(ir, IREG_MM(dest_reg), IREG_temp0_Q); + } - codegen_mark_code_present(block, cs + op_pc + 1, 1); - return op_pc + 2; + codegen_mark_code_present(block, cs + op_pc + 1, 1); + return op_pc + 2; } uint32_t ropPFRSQIT1(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_MMX_ENTER(ir); + uop_MMX_ENTER(ir); - codegen_mark_code_present(block, cs + op_pc, 2); - return op_pc + 2; + codegen_mark_code_present(block, cs + op_pc, 2); + return op_pc + 2; } diff --git a/src/codegen/codegen_ops_arith.c b/src/codegen/codegen_ops_arith.c index 61b1c2cb..0c1da820 100644 --- a/src/codegen/codegen_ops_arith.c +++ b/src/codegen/codegen_ops_arith.c @@ -9,2253 +9,2262 @@ #include "codegen_ops_arith.h" #include "codegen_ops_helpers.h" -static inline void get_cf(ir_data_t *ir, int dest_reg) { - uop_CALL_FUNC_RESULT(ir, dest_reg, CF_SET); -} +static inline void get_cf(ir_data_t *ir, int dest_reg) { uop_CALL_FUNC_RESULT(ir, dest_reg, CF_SET); } uint32_t ropADC_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint8_t imm_data = fastreadb(cs + op_pc); + uint8_t imm_data = fastreadb(cs + op_pc); - get_cf(ir, IREG_temp0); - uop_MOVZX(ir, IREG_flags_op1, IREG_AL); - uop_ADD_IMM(ir, IREG_AL, IREG_AL, imm_data); - uop_MOV_IMM(ir, IREG_flags_op2, imm_data); - uop_ADD(ir, IREG_AL, IREG_AL, IREG_temp0_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC8); - uop_MOVZX(ir, IREG_flags_res, IREG_AL); + get_cf(ir, IREG_temp0); + uop_MOVZX(ir, IREG_flags_op1, IREG_AL); + uop_ADD_IMM(ir, IREG_AL, IREG_AL, imm_data); + uop_MOV_IMM(ir, IREG_flags_op2, imm_data); + uop_ADD(ir, IREG_AL, IREG_AL, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC8); + uop_MOVZX(ir, IREG_flags_res, IREG_AL); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs + op_pc, 1); - return op_pc + 1; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 1); + return op_pc + 1; } uint32_t ropADC_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint16_t imm_data = fastreadw(cs + op_pc); + uint16_t imm_data = fastreadw(cs + op_pc); - get_cf(ir, IREG_temp0); - uop_MOVZX(ir, IREG_flags_op1, IREG_AX); - uop_ADD_IMM(ir, IREG_AX, IREG_AX, imm_data); - uop_MOV_IMM(ir, IREG_flags_op2, imm_data); - uop_ADD(ir, IREG_AX, IREG_AX, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC16); - uop_MOVZX(ir, IREG_flags_res, IREG_AX); + get_cf(ir, IREG_temp0); + uop_MOVZX(ir, IREG_flags_op1, IREG_AX); + uop_ADD_IMM(ir, IREG_AX, IREG_AX, imm_data); + uop_MOV_IMM(ir, IREG_flags_op2, imm_data); + uop_ADD(ir, IREG_AX, IREG_AX, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC16); + uop_MOVZX(ir, IREG_flags_res, IREG_AX); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs + op_pc, 2); - return op_pc + 2; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 2); + return op_pc + 2; } uint32_t ropADC_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - fetchdat = fastreadl(cs + op_pc); + fetchdat = fastreadl(cs + op_pc); - get_cf(ir, IREG_temp0); - uop_MOV(ir, IREG_flags_op1, IREG_EAX); - uop_ADD_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); - uop_MOV_IMM(ir, IREG_flags_op2, fetchdat); - uop_ADD(ir, IREG_EAX, IREG_EAX, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC32); - uop_MOV(ir, IREG_flags_res, IREG_EAX); + get_cf(ir, IREG_temp0); + uop_MOV(ir, IREG_flags_op1, IREG_EAX); + uop_ADD_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); + uop_MOV_IMM(ir, IREG_flags_op2, fetchdat); + uop_ADD(ir, IREG_EAX, IREG_EAX, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC32); + uop_MOV(ir, IREG_flags_res, IREG_EAX); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs + op_pc, 4); - return op_pc + 4; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 4); + return op_pc + 4; } uint32_t ropADC_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - get_cf(ir, IREG_temp1); - if ((fetchdat & 0xc0) == 0xc0) { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + get_cf(ir, IREG_temp1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); - uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); - } else { - x86seg *target_seg; + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); - uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); + uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); + } - uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp1_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp1_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } uint32_t ropADC_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - get_cf(ir, IREG_temp1); - if ((fetchdat & 0xc0) == 0xc0) { - int dest_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + get_cf(ir, IREG_temp1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); - uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); - uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp1_B); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - } else { - x86seg *target_seg; + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_ADD(ir, IREG_temp2_B, IREG_temp0_B, IREG_8(src_reg)); - uop_ADD(ir, IREG_temp2_B, IREG_temp2_B, IREG_temp1_B); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp2_B); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); - uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); - uop_MOVZX(ir, IREG_flags_res, IREG_temp2_B); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC8); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_ADD(ir, IREG_temp2_B, IREG_temp0_B, IREG_8(src_reg)); + uop_ADD(ir, IREG_temp2_B, IREG_temp2_B, IREG_temp1_B); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp2_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_MOVZX(ir, IREG_flags_res, IREG_temp2_B); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC8); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } uint32_t ropADC_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - get_cf(ir, IREG_temp1); - if ((fetchdat & 0xc0) == 0xc0) { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + get_cf(ir, IREG_temp1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); - uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); - } else { - x86seg *target_seg; + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); - uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); + uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + } - uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } uint32_t ropADC_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - get_cf(ir, IREG_temp1); - if ((fetchdat & 0xc0) == 0xc0) { - int dest_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + get_cf(ir, IREG_temp1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); - uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); - uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - } else { - x86seg *target_seg; + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_ADD(ir, IREG_temp2_W, IREG_temp0_W, IREG_16(src_reg)); - uop_ADD(ir, IREG_temp2_W, IREG_temp2_W, IREG_temp1_W); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp2_W); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); - uop_MOVZX(ir, IREG_flags_res, IREG_temp2_W); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC16); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_ADD(ir, IREG_temp2_W, IREG_temp0_W, IREG_16(src_reg)); + uop_ADD(ir, IREG_temp2_W, IREG_temp2_W, IREG_temp1_W); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp2_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_MOVZX(ir, IREG_flags_res, IREG_temp2_W); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC16); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } uint32_t ropADC_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - get_cf(ir, IREG_temp1); - if ((fetchdat & 0xc0) == 0xc0) { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + get_cf(ir, IREG_temp1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); - uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); - } else { - x86seg *target_seg; + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_flags_op2, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_flags_op2); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_flags_op2, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_flags_op2); + } - uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } uint32_t ropADC_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - get_cf(ir, IREG_temp1); - if ((fetchdat & 0xc0) == 0xc0) { - int dest_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + get_cf(ir, IREG_temp1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); - uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); - uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - } else { - x86seg *target_seg; + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - uop_ADD(ir, IREG_temp2, IREG_temp0, IREG_32(src_reg)); - uop_ADD(ir, IREG_temp2, IREG_temp2, IREG_temp1); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp2); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); - uop_MOV(ir, IREG_flags_res, IREG_temp2); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC32); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_ADD(ir, IREG_temp2, IREG_temp0, IREG_32(src_reg)); + uop_ADD(ir, IREG_temp2, IREG_temp2, IREG_temp1); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp2); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_MOV(ir, IREG_flags_res, IREG_temp2); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC32); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } uint32_t ropADD_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint8_t imm_data = fastreadb(cs + op_pc); + uint8_t imm_data = fastreadb(cs + op_pc); - uop_MOVZX(ir, IREG_flags_op1, IREG_AL); - uop_ADD_IMM(ir, IREG_AL, IREG_AL, imm_data); - uop_MOV_IMM(ir, IREG_flags_op2, imm_data); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD8); - uop_MOVZX(ir, IREG_flags_res, IREG_AL); + uop_MOVZX(ir, IREG_flags_op1, IREG_AL); + uop_ADD_IMM(ir, IREG_AL, IREG_AL, imm_data); + uop_MOV_IMM(ir, IREG_flags_op2, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD8); + uop_MOVZX(ir, IREG_flags_res, IREG_AL); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs + op_pc, 1); - return op_pc + 1; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 1); + return op_pc + 1; } uint32_t ropADD_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint16_t imm_data = fastreadw(cs + op_pc); + uint16_t imm_data = fastreadw(cs + op_pc); - uop_MOVZX(ir, IREG_flags_op1, IREG_AX); - uop_ADD_IMM(ir, IREG_AX, IREG_AX, imm_data); - uop_MOV_IMM(ir, IREG_flags_op2, imm_data); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); - uop_MOVZX(ir, IREG_flags_res, IREG_AX); + uop_MOVZX(ir, IREG_flags_op1, IREG_AX); + uop_ADD_IMM(ir, IREG_AX, IREG_AX, imm_data); + uop_MOV_IMM(ir, IREG_flags_op2, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); + uop_MOVZX(ir, IREG_flags_res, IREG_AX); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs + op_pc, 2); - return op_pc + 2; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 2); + return op_pc + 2; } uint32_t ropADD_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_MOV(ir, IREG_flags_op1, IREG_EAX); + uop_MOV(ir, IREG_flags_op1, IREG_EAX); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) { - LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + op_pc); - uop_ADD(ir, IREG_EAX, IREG_EAX, IREG_temp0); - uop_MOV(ir, IREG_flags_op2, IREG_temp0); - } else { - fetchdat = fastreadl(cs + op_pc); - uop_ADD_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); - uop_MOV_IMM(ir, IREG_flags_op2, fetchdat); - codegen_mark_code_present(block, cs + op_pc, 4); - } + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + op_pc); + uop_ADD(ir, IREG_EAX, IREG_EAX, IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_temp0); + } else { + fetchdat = fastreadl(cs + op_pc); + uop_ADD_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); + uop_MOV_IMM(ir, IREG_flags_op2, fetchdat); + codegen_mark_code_present(block, cs + op_pc, 4); + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); - uop_MOV(ir, IREG_flags_res, IREG_EAX); - codegen_flags_changed = 1; - return op_pc + 4; + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); + uop_MOV(ir, IREG_flags_res, IREG_EAX); + codegen_flags_changed = 1; + return op_pc + 4; } uint32_t ropADD_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); - uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); - } else { - x86seg *target_seg; + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); - uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); + uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } uint32_t ropADD_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int dest_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); - uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - } else { - x86seg *target_seg; + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_ADD(ir, IREG_temp1_B, IREG_temp0_B, IREG_8(src_reg)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); - uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD8); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_ADD(ir, IREG_temp1_B, IREG_temp0_B, IREG_8(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD8); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } uint32_t ropADD_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); - uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); - } else { - x86seg *target_seg; + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); - uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); + uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } uint32_t ropADD_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int dest_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); - uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - } else { - x86seg *target_seg; + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_ADD(ir, IREG_temp1_W, IREG_temp0_W, IREG_16(src_reg)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_ADD(ir, IREG_temp1_W, IREG_temp0_W, IREG_16(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } uint32_t ropADD_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); - uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); - } else { - x86seg *target_seg; + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_flags_op2, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_flags_op2); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_flags_op2, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_flags_op2); + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } uint32_t ropADD_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int dest_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); - uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - } else { - x86seg *target_seg; + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - uop_ADD(ir, IREG_temp1, IREG_temp0, IREG_32(src_reg)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_ADD(ir, IREG_temp1, IREG_temp0, IREG_32(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } uint32_t ropCMP_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint8_t imm_data = fastreadb(cs + op_pc); + uint8_t imm_data = fastreadb(cs + op_pc); - uop_MOVZX(ir, IREG_flags_op1, IREG_AL); - uop_SUB_IMM(ir, IREG_flags_res_B, IREG_AL, imm_data); - uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B); - uop_MOV_IMM(ir, IREG_flags_op2, imm_data); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); + uop_MOVZX(ir, IREG_flags_op1, IREG_AL); + uop_SUB_IMM(ir, IREG_flags_res_B, IREG_AL, imm_data); + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B); + uop_MOV_IMM(ir, IREG_flags_op2, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs + op_pc, 1); - return op_pc + 1; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 1); + return op_pc + 1; } uint32_t ropCMP_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint16_t imm_data = fastreadw(cs + op_pc); + uint16_t imm_data = fastreadw(cs + op_pc); - uop_MOVZX(ir, IREG_flags_op1, IREG_AX); - uop_SUB_IMM(ir, IREG_flags_res_W, IREG_AX, imm_data); - uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); - uop_MOV_IMM(ir, IREG_flags_op2, imm_data); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + uop_MOVZX(ir, IREG_flags_op1, IREG_AX); + uop_SUB_IMM(ir, IREG_flags_res_W, IREG_AX, imm_data); + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); + uop_MOV_IMM(ir, IREG_flags_op2, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs + op_pc, 2); - return op_pc + 2; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 2); + return op_pc + 2; } uint32_t ropCMP_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - fetchdat = fastreadl(cs + op_pc); + fetchdat = fastreadl(cs + op_pc); - uop_MOV(ir, IREG_flags_op1, IREG_EAX); - uop_SUB_IMM(ir, IREG_flags_res, IREG_EAX, fetchdat); - uop_MOV_IMM(ir, IREG_flags_op2, fetchdat); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + uop_MOV(ir, IREG_flags_op1, IREG_EAX); + uop_SUB_IMM(ir, IREG_flags_res, IREG_EAX, fetchdat); + uop_MOV_IMM(ir, IREG_flags_op2, fetchdat); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs + op_pc, 4); - return op_pc + 4; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 4); + return op_pc + 4; } uint32_t ropCMP_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); - uop_SUB(ir, IREG_flags_res_B, IREG_8(dest_reg), IREG_8(src_reg)); - } else { - x86seg *target_seg; + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_SUB(ir, IREG_flags_res_B, IREG_8(dest_reg), IREG_8(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); - uop_SUB(ir, IREG_flags_res_B, IREG_8(dest_reg), IREG_temp0_B); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); + uop_SUB(ir, IREG_flags_res_B, IREG_8(dest_reg), IREG_temp0_B); + } - uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } uint32_t ropCMP_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int dest_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); - uop_SUB(ir, IREG_flags_res_B, IREG_8(dest_reg), IREG_8(src_reg)); - } else { - x86seg *target_seg; + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_SUB(ir, IREG_flags_res_B, IREG_8(dest_reg), IREG_8(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); - uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); - uop_SUB(ir, IREG_flags_res_B, IREG_temp0_B, IREG_8(src_reg)); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_SUB(ir, IREG_flags_res_B, IREG_temp0_B, IREG_8(src_reg)); + } - uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } uint32_t ropCMP_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); - uop_SUB(ir, IREG_flags_res_W, IREG_16(dest_reg), IREG_16(src_reg)); - } else { - x86seg *target_seg; + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_SUB(ir, IREG_flags_res_W, IREG_16(dest_reg), IREG_16(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); - uop_SUB(ir, IREG_flags_res_W, IREG_16(dest_reg), IREG_temp0_W); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); + uop_SUB(ir, IREG_flags_res_W, IREG_16(dest_reg), IREG_temp0_W); + } - uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } uint32_t ropCMP_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int dest_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); - uop_SUB(ir, IREG_flags_res_W, IREG_16(dest_reg), IREG_16(src_reg)); - } else { - x86seg *target_seg; + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_SUB(ir, IREG_flags_res_W, IREG_16(dest_reg), IREG_16(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); - uop_SUB(ir, IREG_flags_res_W, IREG_temp0_W, IREG_16(src_reg)); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_SUB(ir, IREG_flags_res_W, IREG_temp0_W, IREG_16(src_reg)); + } - uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } uint32_t ropCMP_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); - uop_SUB(ir, IREG_flags_res, IREG_32(dest_reg), IREG_32(src_reg)); - } else { - x86seg *target_seg; + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_SUB(ir, IREG_flags_res, IREG_32(dest_reg), IREG_32(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_MOV(ir, IREG_flags_op2, IREG_temp0); - uop_SUB(ir, IREG_flags_res, IREG_32(dest_reg), IREG_temp0); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op2, IREG_temp0); + uop_SUB(ir, IREG_flags_res, IREG_32(dest_reg), IREG_temp0); + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } uint32_t ropCMP_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int dest_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); - uop_SUB(ir, IREG_flags_res, IREG_32(dest_reg), IREG_32(src_reg)); - } else { - x86seg *target_seg; + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_SUB(ir, IREG_flags_res, IREG_32(dest_reg), IREG_32(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); - uop_SUB(ir, IREG_flags_res, IREG_temp0, IREG_32(src_reg)); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_SUB(ir, IREG_flags_res, IREG_temp0, IREG_32(src_reg)); + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } uint32_t ropSBB_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint8_t imm_data = fastreadb(cs + op_pc); + uint8_t imm_data = fastreadb(cs + op_pc); - get_cf(ir, IREG_temp0); - uop_MOVZX(ir, IREG_flags_op1, IREG_AL); - uop_SUB_IMM(ir, IREG_AL, IREG_AL, imm_data); - uop_MOV_IMM(ir, IREG_flags_op2, imm_data); - uop_SUB(ir, IREG_AL, IREG_AL, IREG_temp0_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC8); - uop_MOVZX(ir, IREG_flags_res, IREG_AL); + get_cf(ir, IREG_temp0); + uop_MOVZX(ir, IREG_flags_op1, IREG_AL); + uop_SUB_IMM(ir, IREG_AL, IREG_AL, imm_data); + uop_MOV_IMM(ir, IREG_flags_op2, imm_data); + uop_SUB(ir, IREG_AL, IREG_AL, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC8); + uop_MOVZX(ir, IREG_flags_res, IREG_AL); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs + op_pc, 1); - return op_pc + 1; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 1); + return op_pc + 1; } uint32_t ropSBB_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint16_t imm_data = fastreadw(cs + op_pc); + uint16_t imm_data = fastreadw(cs + op_pc); - get_cf(ir, IREG_temp0); - uop_MOVZX(ir, IREG_flags_op1, IREG_AX); - uop_SUB_IMM(ir, IREG_AX, IREG_AX, imm_data); - uop_MOV_IMM(ir, IREG_flags_op2, imm_data); - uop_SUB(ir, IREG_AX, IREG_AX, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC16); - uop_MOVZX(ir, IREG_flags_res, IREG_AX); + get_cf(ir, IREG_temp0); + uop_MOVZX(ir, IREG_flags_op1, IREG_AX); + uop_SUB_IMM(ir, IREG_AX, IREG_AX, imm_data); + uop_MOV_IMM(ir, IREG_flags_op2, imm_data); + uop_SUB(ir, IREG_AX, IREG_AX, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC16); + uop_MOVZX(ir, IREG_flags_res, IREG_AX); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs + op_pc, 2); - return op_pc + 2; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 2); + return op_pc + 2; } uint32_t ropSBB_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - fetchdat = fastreadl(cs + op_pc); + fetchdat = fastreadl(cs + op_pc); - get_cf(ir, IREG_temp0); - uop_MOV(ir, IREG_flags_op1, IREG_EAX); - uop_SUB_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); - uop_MOV_IMM(ir, IREG_flags_op2, fetchdat); - uop_SUB(ir, IREG_EAX, IREG_EAX, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC32); - uop_MOV(ir, IREG_flags_res, IREG_EAX); + get_cf(ir, IREG_temp0); + uop_MOV(ir, IREG_flags_op1, IREG_EAX); + uop_SUB_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); + uop_MOV_IMM(ir, IREG_flags_op2, fetchdat); + uop_SUB(ir, IREG_EAX, IREG_EAX, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC32); + uop_MOV(ir, IREG_flags_res, IREG_EAX); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs + op_pc, 4); - return op_pc + 4; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 4); + return op_pc + 4; } uint32_t ropSBB_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - get_cf(ir, IREG_temp1); - if ((fetchdat & 0xc0) == 0xc0) { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + get_cf(ir, IREG_temp1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); - uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); - } else { - x86seg *target_seg; + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); - uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); + uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); + } - uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp1_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp1_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } uint32_t ropSBB_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - get_cf(ir, IREG_temp1); - if ((fetchdat & 0xc0) == 0xc0) { - int dest_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + get_cf(ir, IREG_temp1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); - uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); - uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp1_B); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - } else { - x86seg *target_seg; + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_SUB(ir, IREG_temp2_B, IREG_temp0_B, IREG_8(src_reg)); - uop_SUB(ir, IREG_temp2_B, IREG_temp2_B, IREG_temp1_B); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp2_B); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); - uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); - uop_MOVZX(ir, IREG_flags_res, IREG_temp2_B); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC8); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_SUB(ir, IREG_temp2_B, IREG_temp0_B, IREG_8(src_reg)); + uop_SUB(ir, IREG_temp2_B, IREG_temp2_B, IREG_temp1_B); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp2_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_MOVZX(ir, IREG_flags_res, IREG_temp2_B); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC8); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } uint32_t ropSBB_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - get_cf(ir, IREG_temp1); - if ((fetchdat & 0xc0) == 0xc0) { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + get_cf(ir, IREG_temp1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); - uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); - } else { - x86seg *target_seg; + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); - uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); + uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + } - uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } uint32_t ropSBB_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - get_cf(ir, IREG_temp1); - if ((fetchdat & 0xc0) == 0xc0) { - int dest_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + get_cf(ir, IREG_temp1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); - uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); - uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - } else { - x86seg *target_seg; + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_SUB(ir, IREG_temp2_W, IREG_temp0_W, IREG_16(src_reg)); - uop_SUB(ir, IREG_temp2_W, IREG_temp2_W, IREG_temp1_W); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp2_W); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); - uop_MOVZX(ir, IREG_flags_res, IREG_temp2_W); - } + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_SUB(ir, IREG_temp2_W, IREG_temp0_W, IREG_16(src_reg)); + uop_SUB(ir, IREG_temp2_W, IREG_temp2_W, IREG_temp1_W); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp2_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_MOVZX(ir, IREG_flags_res, IREG_temp2_W); + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC16); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC16); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } uint32_t ropSBB_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - get_cf(ir, IREG_temp1); - if ((fetchdat & 0xc0) == 0xc0) { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + get_cf(ir, IREG_temp1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); - uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); - } else { - x86seg *target_seg; + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_flags_op2, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_flags_op2); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_flags_op2, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_flags_op2); + } - uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } uint32_t ropSBB_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - get_cf(ir, IREG_temp1); - if ((fetchdat & 0xc0) == 0xc0) { - int dest_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + get_cf(ir, IREG_temp1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); - uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); - uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - } else { - x86seg *target_seg; + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - uop_SUB(ir, IREG_temp2, IREG_temp0, IREG_32(src_reg)); - uop_SUB(ir, IREG_temp2, IREG_temp2, IREG_temp1); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp2); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); - uop_MOV(ir, IREG_flags_res, IREG_temp2); - } + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_SUB(ir, IREG_temp2, IREG_temp0, IREG_32(src_reg)); + uop_SUB(ir, IREG_temp2, IREG_temp2, IREG_temp1); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp2); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_MOV(ir, IREG_flags_res, IREG_temp2); + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC32); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC32); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } uint32_t ropSUB_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint8_t imm_data = fastreadb(cs + op_pc); + uint8_t imm_data = fastreadb(cs + op_pc); - uop_MOVZX(ir, IREG_flags_op1, IREG_AL); - uop_SUB_IMM(ir, IREG_AL, IREG_AL, imm_data); - uop_MOV_IMM(ir, IREG_flags_op2, imm_data); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); - uop_MOVZX(ir, IREG_flags_res, IREG_AL); + uop_MOVZX(ir, IREG_flags_op1, IREG_AL); + uop_SUB_IMM(ir, IREG_AL, IREG_AL, imm_data); + uop_MOV_IMM(ir, IREG_flags_op2, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); + uop_MOVZX(ir, IREG_flags_res, IREG_AL); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs + op_pc, 1); - return op_pc + 1; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 1); + return op_pc + 1; } uint32_t ropSUB_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint16_t imm_data = fastreadw(cs + op_pc); + uint16_t imm_data = fastreadw(cs + op_pc); - uop_MOVZX(ir, IREG_flags_op1, IREG_AX); - uop_SUB_IMM(ir, IREG_AX, IREG_AX, imm_data); - uop_MOV_IMM(ir, IREG_flags_op2, imm_data); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); - uop_MOVZX(ir, IREG_flags_res, IREG_AX); + uop_MOVZX(ir, IREG_flags_op1, IREG_AX); + uop_SUB_IMM(ir, IREG_AX, IREG_AX, imm_data); + uop_MOV_IMM(ir, IREG_flags_op2, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + uop_MOVZX(ir, IREG_flags_res, IREG_AX); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs + op_pc, 2); - return op_pc + 2; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 2); + return op_pc + 2; } uint32_t ropSUB_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_MOV(ir, IREG_flags_op1, IREG_EAX); + uop_MOV(ir, IREG_flags_op1, IREG_EAX); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) { - LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + op_pc); - uop_SUB(ir, IREG_EAX, IREG_EAX, IREG_temp0); - uop_MOV(ir, IREG_flags_op2, IREG_temp0); - } else { - fetchdat = fastreadl(cs + op_pc); - codegen_mark_code_present(block, cs + op_pc, 4); - uop_SUB_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); - uop_MOV_IMM(ir, IREG_flags_op2, fetchdat); - } + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + op_pc); + uop_SUB(ir, IREG_EAX, IREG_EAX, IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_temp0); + } else { + fetchdat = fastreadl(cs + op_pc); + codegen_mark_code_present(block, cs + op_pc, 4); + uop_SUB_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); + uop_MOV_IMM(ir, IREG_flags_op2, fetchdat); + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); - uop_MOV(ir, IREG_flags_res, IREG_EAX); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + uop_MOV(ir, IREG_flags_res, IREG_EAX); - codegen_flags_changed = 1; - return op_pc + 4; + codegen_flags_changed = 1; + return op_pc + 4; } uint32_t ropSUB_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); - uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); - } else { - x86seg *target_seg; + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); - uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); + uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } uint32_t ropSUB_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int dest_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); - uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - } else { - x86seg *target_seg; + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_SUB(ir, IREG_temp1_B, IREG_temp0_B, IREG_8(src_reg)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); - uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_SUB(ir, IREG_temp1_B, IREG_temp0_B, IREG_8(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } uint32_t ropSUB_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); - uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); - } else { - x86seg *target_seg; + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); - uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); + uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } uint32_t ropSUB_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int dest_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); - uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - } else { - x86seg *target_seg; + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_SUB(ir, IREG_temp1_W, IREG_temp0_W, IREG_16(src_reg)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - } + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_SUB(ir, IREG_temp1_W, IREG_temp0_W, IREG_16(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } uint32_t ropSUB_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); - uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); - } else { - x86seg *target_seg; + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_flags_op2, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_flags_op2); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_flags_op2, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_flags_op2); + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } uint32_t ropSUB_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int dest_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); - uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - } else { - x86seg *target_seg; + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - uop_SUB(ir, IREG_temp1, IREG_temp0, IREG_32(src_reg)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - } + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_SUB(ir, IREG_temp1, IREG_temp0, IREG_32(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } uint32_t rop80(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int skip_immediate = 0; + int skip_immediate = 0; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int dest_reg = fetchdat & 7; - uint8_t imm = fastreadb(cs + op_pc + 1); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + uint8_t imm = fastreadb(cs + op_pc + 1); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) { - skip_immediate = 1; - LOAD_IMMEDIATE_FROM_RAM_8(block, ir, IREG_temp0_B, cs + op_pc + 1); - } + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + skip_immediate = 1; + LOAD_IMMEDIATE_FROM_RAM_8(block, ir, IREG_temp0_B, cs + op_pc + 1); + } - switch (fetchdat & 0x38) { - case 0x00: /*ADD*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) { - uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); - } else { - uop_ADD_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - break; + switch (fetchdat & 0x38) { + case 0x00: /*ADD*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); + } else { + uop_ADD_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; - case 0x08: /*OR*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_OR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); - else - uop_OR_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - break; + case 0x08: /*OR*/ + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_OR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); + else + uop_OR_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; - case 0x10: /*ADC*/ - get_cf(ir, IREG_temp1); - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) { - uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); - } else { - uop_ADD_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - } - uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp1_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - break; + case 0x10: /*ADC*/ + get_cf(ir, IREG_temp1); + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); + } else { + uop_ADD_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } + uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp1_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; - case 0x18: /*SBB*/ - get_cf(ir, IREG_temp1); - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) { - uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); - } else { - uop_SUB_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - } - uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp1_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - break; + case 0x18: /*SBB*/ + get_cf(ir, IREG_temp1); + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); + } else { + uop_SUB_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } + uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp1_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; - case 0x20: /*AND*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_AND(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); - else - uop_AND_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - break; + case 0x20: /*AND*/ + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_AND(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); + else + uop_AND_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; - case 0x28: /*SUB*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) { - uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); - } else { - uop_SUB_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - break; + case 0x28: /*SUB*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); + } else { + uop_SUB_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; - case 0x30: /*XOR*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_XOR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); - else - uop_XOR_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - break; + case 0x30: /*XOR*/ + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_XOR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); + else + uop_XOR_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; - case 0x38: /*CMP*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) { - uop_SUB(ir, IREG_flags_res_B, IREG_8(dest_reg), IREG_temp0_B); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); - } else { - uop_SUB_IMM(ir, IREG_flags_res_B, IREG_8(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - } - uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); - break; + case 0x38: /*CMP*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + uop_SUB(ir, IREG_flags_res_B, IREG_8(dest_reg), IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); + } else { + uop_SUB_IMM(ir, IREG_flags_res_B, IREG_8(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); + break; - default:return 0; - } - } else { - x86seg *target_seg; - uint8_t imm; + default: + return 0; + } + } else { + x86seg *target_seg; + uint8_t imm; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - if ((fetchdat & 0x38) == 0x38) /*CMP*/ - codegen_check_seg_read(block, ir, target_seg); - else - codegen_check_seg_write(block, ir, target_seg); - imm = fastreadb(cs + op_pc + 1); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + if ((fetchdat & 0x38) == 0x38) /*CMP*/ + codegen_check_seg_read(block, ir, target_seg); + else + codegen_check_seg_write(block, ir, target_seg); + imm = fastreadb(cs + op_pc + 1); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - switch (fetchdat & 0x38) { - case 0x00: /*ADD*/ - uop_ADD_IMM(ir, IREG_temp1_B, IREG_temp0_B, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD8); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); - break; + switch (fetchdat & 0x38) { + case 0x00: /*ADD*/ + uop_ADD_IMM(ir, IREG_temp1_B, IREG_temp0_B, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD8); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + break; - case 0x08: /*OR*/ - uop_OR_IMM(ir, IREG_temp0_B, IREG_temp0_B, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); - break; + case 0x08: /*OR*/ + uop_OR_IMM(ir, IREG_temp0_B, IREG_temp0_B, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + break; - case 0x10: /*ADC*/ - get_cf(ir, IREG_temp2); - uop_ADD_IMM(ir, IREG_temp1_B, IREG_temp0_B, imm); - uop_ADD(ir, IREG_temp1_B, IREG_temp1_B, IREG_temp2_B); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC8); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); - break; + case 0x10: /*ADC*/ + get_cf(ir, IREG_temp2); + uop_ADD_IMM(ir, IREG_temp1_B, IREG_temp0_B, imm); + uop_ADD(ir, IREG_temp1_B, IREG_temp1_B, IREG_temp2_B); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC8); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + break; - case 0x18: /*SBB*/ - get_cf(ir, IREG_temp2); - uop_SUB_IMM(ir, IREG_temp1_B, IREG_temp0_B, imm); - uop_SUB(ir, IREG_temp1_B, IREG_temp1_B, IREG_temp2_B); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC8); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); - break; + case 0x18: /*SBB*/ + get_cf(ir, IREG_temp2); + uop_SUB_IMM(ir, IREG_temp1_B, IREG_temp0_B, imm); + uop_SUB(ir, IREG_temp1_B, IREG_temp1_B, IREG_temp2_B); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC8); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + break; - case 0x20: /*AND*/ - uop_AND_IMM(ir, IREG_temp0_B, IREG_temp0_B, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); - break; + case 0x20: /*AND*/ + uop_AND_IMM(ir, IREG_temp0_B, IREG_temp0_B, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + break; - case 0x28: /*SUB*/ - uop_SUB_IMM(ir, IREG_temp1_B, IREG_temp0_B, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); - break; + case 0x28: /*SUB*/ + uop_SUB_IMM(ir, IREG_temp1_B, IREG_temp0_B, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + break; - case 0x30: /*XOR*/ - uop_XOR_IMM(ir, IREG_temp0_B, IREG_temp0_B, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); - break; + case 0x30: /*XOR*/ + uop_XOR_IMM(ir, IREG_temp0_B, IREG_temp0_B, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + break; - case 0x38: /*CMP*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_SUB_IMM(ir, IREG_flags_res_B, IREG_temp0_B, imm); - uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); - break; + case 0x38: /*CMP*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_SUB_IMM(ir, IREG_flags_res_B, IREG_temp0_B, imm); + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); + break; - default:return 0; - } - } + default: + return 0; + } + } - codegen_flags_changed = 1; - if (!skip_immediate) - codegen_mark_code_present(block, cs + op_pc + 1, 1); - return op_pc + 2; + codegen_flags_changed = 1; + if (!skip_immediate) + codegen_mark_code_present(block, cs + op_pc + 1, 1); + return op_pc + 2; } uint32_t rop81_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int skip_immediate = 0; + int skip_immediate = 0; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int dest_reg = fetchdat & 7; - uint16_t imm = fastreadw(cs + op_pc + 1); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + uint16_t imm = fastreadw(cs + op_pc + 1); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) { - skip_immediate = 1; - LOAD_IMMEDIATE_FROM_RAM_16(block, ir, IREG_temp0_W, cs + op_pc + 1); - } + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + skip_immediate = 1; + LOAD_IMMEDIATE_FROM_RAM_16(block, ir, IREG_temp0_W, cs + op_pc + 1); + } - switch (fetchdat & 0x38) { - case 0x00: /*ADD*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) { - uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); - } else { - uop_ADD_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; + switch (fetchdat & 0x38) { + case 0x00: /*ADD*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); + } else { + uop_ADD_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; - case 0x08: /*OR*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_OR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); - else - uop_OR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; + case 0x08: /*OR*/ + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_OR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + else + uop_OR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; - case 0x10: /*ADC*/ - get_cf(ir, IREG_temp1); - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) { - uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); - } else { - uop_ADD_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - } - uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; + case 0x10: /*ADC*/ + get_cf(ir, IREG_temp1); + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); + } else { + uop_ADD_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } + uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; - case 0x18: /*SBB*/ - get_cf(ir, IREG_temp1); - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) { - uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); - } else { - uop_SUB_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - } - uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; + case 0x18: /*SBB*/ + get_cf(ir, IREG_temp1); + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); + } else { + uop_SUB_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } + uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; - case 0x20: /*AND*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_AND(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); - else - uop_AND_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; + case 0x20: /*AND*/ + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_AND(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + else + uop_AND_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; - case 0x28: /*SUB*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) { - uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); - } else { - uop_SUB_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; + case 0x28: /*SUB*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); + } else { + uop_SUB_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; - case 0x30: /*XOR*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_XOR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); - else - uop_XOR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; + case 0x30: /*XOR*/ + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_XOR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + else + uop_XOR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; - case 0x38: /*CMP*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) { - uop_SUB(ir, IREG_flags_res_W, IREG_16(dest_reg), IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); - } else { - uop_SUB_IMM(ir, IREG_flags_res_W, IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - } - uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); - break; + case 0x38: /*CMP*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + uop_SUB(ir, IREG_flags_res_W, IREG_16(dest_reg), IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); + } else { + uop_SUB_IMM(ir, IREG_flags_res_W, IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + break; - default:return 0; - } - } else { - x86seg *target_seg; - uint16_t imm; + default: + return 0; + } + } else { + x86seg *target_seg; + uint16_t imm; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - if ((fetchdat & 0x38) == 0x38) /*CMP*/ - codegen_check_seg_read(block, ir, target_seg); - else - codegen_check_seg_write(block, ir, target_seg); - imm = fastreadw(cs + op_pc + 1); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) { - skip_immediate = 1; - LOAD_IMMEDIATE_FROM_RAM_16(block, ir, IREG_temp2_W, cs + op_pc + 1); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + if ((fetchdat & 0x38) == 0x38) /*CMP*/ + codegen_check_seg_read(block, ir, target_seg); + else + codegen_check_seg_write(block, ir, target_seg); + imm = fastreadw(cs + op_pc + 1); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + skip_immediate = 1; + LOAD_IMMEDIATE_FROM_RAM_16(block, ir, IREG_temp2_W, cs + op_pc + 1); + } - switch (fetchdat & 0x38) { - case 0x00: /*ADD*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_ADD(ir, IREG_temp1_W, IREG_temp0_W, IREG_temp2_W); - else - uop_ADD_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_MOVZX(ir, IREG_flags_op2, IREG_temp2_W); - else - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - break; + switch (fetchdat & 0x38) { + case 0x00: /*ADD*/ + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_ADD(ir, IREG_temp1_W, IREG_temp0_W, IREG_temp2_W); + else + uop_ADD_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_MOVZX(ir, IREG_flags_op2, IREG_temp2_W); + else + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + break; - case 0x08: /*OR*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_OR(ir, IREG_temp0_W, IREG_temp0_W, IREG_temp2_W); - else - uop_OR_IMM(ir, IREG_temp0_W, IREG_temp0_W, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - break; + case 0x08: /*OR*/ + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_OR(ir, IREG_temp0_W, IREG_temp0_W, IREG_temp2_W); + else + uop_OR_IMM(ir, IREG_temp0_W, IREG_temp0_W, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + break; - case 0x10: /*ADC*/ - get_cf(ir, IREG_temp3); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_ADD(ir, IREG_temp1_W, IREG_temp0_W, IREG_temp2_W); - else - uop_ADD_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); - uop_ADD(ir, IREG_temp1_W, IREG_temp1_W, IREG_temp3_W); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_MOVZX(ir, IREG_flags_op2, IREG_temp2_W); - else - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC16); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - break; + case 0x10: /*ADC*/ + get_cf(ir, IREG_temp3); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_ADD(ir, IREG_temp1_W, IREG_temp0_W, IREG_temp2_W); + else + uop_ADD_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); + uop_ADD(ir, IREG_temp1_W, IREG_temp1_W, IREG_temp3_W); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_MOVZX(ir, IREG_flags_op2, IREG_temp2_W); + else + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + break; - case 0x18: /*SBB*/ - get_cf(ir, IREG_temp3); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_SUB(ir, IREG_temp1_W, IREG_temp0_W, IREG_temp2_W); - else - uop_SUB_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); - uop_SUB(ir, IREG_temp1_W, IREG_temp1_W, IREG_temp3_W); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_MOVZX(ir, IREG_flags_op2, IREG_temp2_W); - else - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC16); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - break; + case 0x18: /*SBB*/ + get_cf(ir, IREG_temp3); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_SUB(ir, IREG_temp1_W, IREG_temp0_W, IREG_temp2_W); + else + uop_SUB_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); + uop_SUB(ir, IREG_temp1_W, IREG_temp1_W, IREG_temp3_W); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_MOVZX(ir, IREG_flags_op2, IREG_temp2_W); + else + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + break; - case 0x20: /*AND*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_AND(ir, IREG_temp0_W, IREG_temp0_W, IREG_temp2_W); - else - uop_AND_IMM(ir, IREG_temp0_W, IREG_temp0_W, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - break; + case 0x20: /*AND*/ + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_AND(ir, IREG_temp0_W, IREG_temp0_W, IREG_temp2_W); + else + uop_AND_IMM(ir, IREG_temp0_W, IREG_temp0_W, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + break; - case 0x28: /*SUB*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_SUB(ir, IREG_temp1_W, IREG_temp0_W, IREG_temp2_W); - else - uop_SUB_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_MOVZX(ir, IREG_flags_op2, IREG_temp2_W); - else - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - break; + case 0x28: /*SUB*/ + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_SUB(ir, IREG_temp1_W, IREG_temp0_W, IREG_temp2_W); + else + uop_SUB_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_MOVZX(ir, IREG_flags_op2, IREG_temp2_W); + else + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + break; - case 0x30: /*XOR*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_XOR(ir, IREG_temp0_W, IREG_temp0_W, IREG_temp2_W); - else - uop_XOR_IMM(ir, IREG_temp0_W, IREG_temp0_W, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - break; + case 0x30: /*XOR*/ + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_XOR(ir, IREG_temp0_W, IREG_temp0_W, IREG_temp2_W); + else + uop_XOR_IMM(ir, IREG_temp0_W, IREG_temp0_W, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + break; - case 0x38: /*CMP*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) { - uop_MOVZX(ir, IREG_flags_op2, IREG_temp2_W); - uop_SUB(ir, IREG_flags_res_W, IREG_temp0_W, IREG_temp2_W); - } else { - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_SUB_IMM(ir, IREG_flags_res_W, IREG_temp0_W, imm); - } - uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); - break; + case 0x38: /*CMP*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + uop_MOVZX(ir, IREG_flags_op2, IREG_temp2_W); + uop_SUB(ir, IREG_flags_res_W, IREG_temp0_W, IREG_temp2_W); + } else { + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_SUB_IMM(ir, IREG_flags_res_W, IREG_temp0_W, imm); + } + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + break; - default:return 0; - } - } + default: + return 0; + } + } - codegen_flags_changed = 1; - if (!skip_immediate) - codegen_mark_code_present(block, cs + op_pc + 1, 2); - return op_pc + 3; + codegen_flags_changed = 1; + if (!skip_immediate) + codegen_mark_code_present(block, cs + op_pc + 1, 2); + return op_pc + 3; } uint32_t rop81_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int skip_immediate = 0; + int skip_immediate = 0; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int dest_reg = fetchdat & 7; - uint32_t imm = fastreadl(cs + op_pc + 1); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + uint32_t imm = fastreadl(cs + op_pc + 1); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) { - skip_immediate = 1; - LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + op_pc + 1); - } + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + skip_immediate = 1; + LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + op_pc + 1); + } - switch (fetchdat & 0x38) { - case 0x00: /*ADD*/ - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) { - uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); - uop_MOV(ir, IREG_flags_op2, IREG_temp0); - } else { - uop_ADD_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; + switch (fetchdat & 0x38) { + case 0x00: /*ADD*/ + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_temp0); + } else { + uop_ADD_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; - case 0x08: /*OR*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_OR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); - else - uop_OR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; + case 0x08: /*OR*/ + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_OR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); + else + uop_OR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; - case 0x10: /*ADC*/ - get_cf(ir, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) { - uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); - uop_MOV(ir, IREG_flags_op2, IREG_temp0); - } else { - uop_ADD_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - } - uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; + case 0x10: /*ADC*/ + get_cf(ir, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_temp0); + } else { + uop_ADD_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } + uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; - case 0x18: /*SBB*/ - get_cf(ir, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) { - uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); - uop_MOV(ir, IREG_flags_op2, IREG_temp0); - } else { - uop_SUB_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - } - uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; + case 0x18: /*SBB*/ + get_cf(ir, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_temp0); + } else { + uop_SUB_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } + uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; - case 0x20: /*AND*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_AND(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); - else - uop_AND_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; + case 0x20: /*AND*/ + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_AND(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); + else + uop_AND_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; - case 0x28: /*SUB*/ - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) { - uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); - uop_MOV(ir, IREG_flags_op2, IREG_temp0); - } else { - uop_SUB_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; + case 0x28: /*SUB*/ + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_temp0); + } else { + uop_SUB_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; - case 0x30: /*XOR*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_XOR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); - else - uop_XOR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; + case 0x30: /*XOR*/ + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_XOR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); + else + uop_XOR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; - case 0x38: /*CMP*/ - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) { - uop_SUB(ir, IREG_flags_res, IREG_32(dest_reg), IREG_temp0); - uop_MOV(ir, IREG_flags_op2, IREG_temp0); - } else { - uop_SUB_IMM(ir, IREG_flags_res, IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); - break; + case 0x38: /*CMP*/ + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + uop_SUB(ir, IREG_flags_res, IREG_32(dest_reg), IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_temp0); + } else { + uop_SUB_IMM(ir, IREG_flags_res, IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + break; - default:return 0; - } - } else { - x86seg *target_seg; - uint32_t imm; + default: + return 0; + } + } else { + x86seg *target_seg; + uint32_t imm; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - if ((fetchdat & 0x38) == 0x38) /*CMP*/ - codegen_check_seg_read(block, ir, target_seg); - else - codegen_check_seg_write(block, ir, target_seg); - imm = fastreadl(cs + op_pc + 1); - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + if ((fetchdat & 0x38) == 0x38) /*CMP*/ + codegen_check_seg_read(block, ir, target_seg); + else + codegen_check_seg_write(block, ir, target_seg); + imm = fastreadl(cs + op_pc + 1); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) { - skip_immediate = 1; - LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp2, cs + op_pc + 1); - } + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + skip_immediate = 1; + LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp2, cs + op_pc + 1); + } - switch (fetchdat & 0x38) { - case 0x00: /*ADD*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_ADD(ir, IREG_temp1, IREG_temp0, IREG_temp2); - else - uop_ADD_IMM(ir, IREG_temp1, IREG_temp0, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - else - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - break; + switch (fetchdat & 0x38) { + case 0x00: /*ADD*/ + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_ADD(ir, IREG_temp1, IREG_temp0, IREG_temp2); + else + uop_ADD_IMM(ir, IREG_temp1, IREG_temp0, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + else + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; - case 0x08: /*OR*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_OR(ir, IREG_temp0, IREG_temp0, IREG_temp2); - else - uop_OR_IMM(ir, IREG_temp0, IREG_temp0, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - uop_MOV(ir, IREG_flags_res, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - break; + case 0x08: /*OR*/ + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_OR(ir, IREG_temp0, IREG_temp0, IREG_temp2); + else + uop_OR_IMM(ir, IREG_temp0, IREG_temp0, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + break; - case 0x10: /*ADC*/ - get_cf(ir, IREG_temp3); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_ADD(ir, IREG_temp1, IREG_temp0, IREG_temp2); - else - uop_ADD_IMM(ir, IREG_temp1, IREG_temp0, imm); - uop_ADD(ir, IREG_temp1, IREG_temp1, IREG_temp3); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - else - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC32); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - break; + case 0x10: /*ADC*/ + get_cf(ir, IREG_temp3); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_ADD(ir, IREG_temp1, IREG_temp0, IREG_temp2); + else + uop_ADD_IMM(ir, IREG_temp1, IREG_temp0, imm); + uop_ADD(ir, IREG_temp1, IREG_temp1, IREG_temp3); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + else + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; - case 0x18: /*SBB*/ - get_cf(ir, IREG_temp3); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_SUB(ir, IREG_temp1, IREG_temp0, IREG_temp2); - else - uop_SUB_IMM(ir, IREG_temp1, IREG_temp0, imm); - uop_SUB(ir, IREG_temp1, IREG_temp1, IREG_temp3); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - else - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC32); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - break; + case 0x18: /*SBB*/ + get_cf(ir, IREG_temp3); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_SUB(ir, IREG_temp1, IREG_temp0, IREG_temp2); + else + uop_SUB_IMM(ir, IREG_temp1, IREG_temp0, imm); + uop_SUB(ir, IREG_temp1, IREG_temp1, IREG_temp3); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + else + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; - case 0x20: /*AND*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_AND(ir, IREG_temp0, IREG_temp0, IREG_temp2); - else - uop_AND_IMM(ir, IREG_temp0, IREG_temp0, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - uop_MOV(ir, IREG_flags_res, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - break; + case 0x20: /*AND*/ + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_AND(ir, IREG_temp0, IREG_temp0, IREG_temp2); + else + uop_AND_IMM(ir, IREG_temp0, IREG_temp0, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + break; - case 0x28: /*SUB*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_SUB(ir, IREG_temp1, IREG_temp0, IREG_temp2); - else - uop_SUB_IMM(ir, IREG_temp1, IREG_temp0, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - else - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - break; + case 0x28: /*SUB*/ + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_SUB(ir, IREG_temp1, IREG_temp0, IREG_temp2); + else + uop_SUB_IMM(ir, IREG_temp1, IREG_temp0, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + else + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; - case 0x30: /*XOR*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_XOR(ir, IREG_temp0, IREG_temp0, IREG_temp2); - else - uop_XOR_IMM(ir, IREG_temp0, IREG_temp0, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - uop_MOV(ir, IREG_flags_res, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - break; + case 0x30: /*XOR*/ + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_XOR(ir, IREG_temp0, IREG_temp0, IREG_temp2); + else + uop_XOR_IMM(ir, IREG_temp0, IREG_temp0, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + break; - case 0x38: /*CMP*/ - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) { - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_SUB(ir, IREG_flags_res, IREG_temp0, IREG_temp2); - } else { - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_SUB_IMM(ir, IREG_flags_res, IREG_temp0, imm); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); - break; + case 0x38: /*CMP*/ + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_SUB(ir, IREG_flags_res, IREG_temp0, IREG_temp2); + } else { + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_SUB_IMM(ir, IREG_flags_res, IREG_temp0, imm); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + break; - default:return 0; - } - } + default: + return 0; + } + } - codegen_flags_changed = 1; - if (!skip_immediate) - codegen_mark_code_present(block, cs + op_pc + 1, 4); - return op_pc + 5; + codegen_flags_changed = 1; + if (!skip_immediate) + codegen_mark_code_present(block, cs + op_pc + 1, 4); + return op_pc + 5; } uint32_t rop83_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int dest_reg = fetchdat & 7; - uint16_t imm = (int16_t)(int8_t)fastreadb(cs + op_pc + 1); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + uint16_t imm = (int16_t)(int8_t)fastreadb(cs + op_pc + 1); - switch (fetchdat & 0x38) { - case 0x00: /*ADD*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_ADD_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; + switch (fetchdat & 0x38) { + case 0x00: /*ADD*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_ADD_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; - case 0x08: /*OR*/ - uop_OR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; + case 0x08: /*OR*/ + uop_OR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; - case 0x10: /*ADC*/ - get_cf(ir, IREG_temp1); - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_ADD_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; + case 0x10: /*ADC*/ + get_cf(ir, IREG_temp1); + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_ADD_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; - case 0x18: /*SBB*/ - get_cf(ir, IREG_temp1); - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_SUB_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; + case 0x18: /*SBB*/ + get_cf(ir, IREG_temp1); + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_SUB_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; - case 0x20: /*AND*/ - uop_AND_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; + case 0x20: /*AND*/ + uop_AND_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; - case 0x28: /*SUB*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_SUB_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; + case 0x28: /*SUB*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_SUB_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; - case 0x30: /*XOR*/ - uop_XOR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; + case 0x30: /*XOR*/ + uop_XOR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; - case 0x38: /*CMP*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_SUB_IMM(ir, IREG_flags_res_W, IREG_16(dest_reg), imm); - uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); - break; + case 0x38: /*CMP*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_SUB_IMM(ir, IREG_flags_res_W, IREG_16(dest_reg), imm); + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + break; - default:return 0; - } - } else { - x86seg *target_seg; - uint16_t imm; + default: + return 0; + } + } else { + x86seg *target_seg; + uint16_t imm; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - if ((fetchdat & 0x38) == 0x38) /*CMP*/ - codegen_check_seg_read(block, ir, target_seg); - else - codegen_check_seg_write(block, ir, target_seg); - imm = (int16_t)(int8_t)fastreadb(cs + op_pc + 1); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + if ((fetchdat & 0x38) == 0x38) /*CMP*/ + codegen_check_seg_read(block, ir, target_seg); + else + codegen_check_seg_write(block, ir, target_seg); + imm = (int16_t)(int8_t)fastreadb(cs + op_pc + 1); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - switch (fetchdat & 0x38) { - case 0x00: /*ADD*/ - uop_ADD_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - break; + switch (fetchdat & 0x38) { + case 0x00: /*ADD*/ + uop_ADD_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + break; - case 0x08: /*OR*/ - uop_OR_IMM(ir, IREG_temp0_W, IREG_temp0_W, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - break; + case 0x08: /*OR*/ + uop_OR_IMM(ir, IREG_temp0_W, IREG_temp0_W, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + break; - case 0x10: /*ADC*/ - get_cf(ir, IREG_temp2); - uop_ADD_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); - uop_ADD(ir, IREG_temp1_W, IREG_temp1_W, IREG_temp2_W); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC16); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - break; + case 0x10: /*ADC*/ + get_cf(ir, IREG_temp2); + uop_ADD_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); + uop_ADD(ir, IREG_temp1_W, IREG_temp1_W, IREG_temp2_W); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + break; - case 0x18: /*SBB*/ - get_cf(ir, IREG_temp2); - uop_SUB_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); - uop_SUB(ir, IREG_temp1_W, IREG_temp1_W, IREG_temp2_W); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC16); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - break; + case 0x18: /*SBB*/ + get_cf(ir, IREG_temp2); + uop_SUB_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); + uop_SUB(ir, IREG_temp1_W, IREG_temp1_W, IREG_temp2_W); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + break; - case 0x20: /*AND*/ - uop_AND_IMM(ir, IREG_temp0_W, IREG_temp0_W, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - break; + case 0x20: /*AND*/ + uop_AND_IMM(ir, IREG_temp0_W, IREG_temp0_W, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + break; - case 0x28: /*SUB*/ - uop_SUB_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - break; + case 0x28: /*SUB*/ + uop_SUB_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + break; - case 0x30: /*XOR*/ - uop_XOR_IMM(ir, IREG_temp0_W, IREG_temp0_W, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - break; + case 0x30: /*XOR*/ + uop_XOR_IMM(ir, IREG_temp0_W, IREG_temp0_W, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + break; - case 0x38: /*CMP*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_SUB_IMM(ir, IREG_flags_res_W, IREG_temp0_W, imm); - uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); - break; + case 0x38: /*CMP*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_SUB_IMM(ir, IREG_flags_res_W, IREG_temp0_W, imm); + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + break; - default:return 0; - } - } + default: + return 0; + } + } - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs + op_pc + 1, 1); - return op_pc + 2; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc + 1, 1); + return op_pc + 2; } uint32_t rop83_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int dest_reg = fetchdat & 7; - uint32_t imm = (int32_t)(int8_t)fastreadb(cs + op_pc + 1); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + uint32_t imm = (int32_t)(int8_t)fastreadb(cs + op_pc + 1); - switch (fetchdat & 0x38) { - case 0x00: /*ADD*/ - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_ADD_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; + switch (fetchdat & 0x38) { + case 0x00: /*ADD*/ + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_ADD_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; - case 0x08: /*OR*/ - uop_OR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; + case 0x08: /*OR*/ + uop_OR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; - case 0x10: /*ADC*/ - get_cf(ir, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_ADD_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; + case 0x10: /*ADC*/ + get_cf(ir, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_ADD_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; - case 0x18: /*SBB*/ - get_cf(ir, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_SUB_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; + case 0x18: /*SBB*/ + get_cf(ir, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SUB_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; - case 0x20: /*AND*/ - uop_AND_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; + case 0x20: /*AND*/ + uop_AND_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; - case 0x28: /*SUB*/ - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_SUB_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; + case 0x28: /*SUB*/ + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SUB_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; - case 0x30: /*XOR*/ - uop_XOR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; + case 0x30: /*XOR*/ + uop_XOR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; - case 0x38: /*CMP*/ - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_SUB_IMM(ir, IREG_flags_res, IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); - break; + case 0x38: /*CMP*/ + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SUB_IMM(ir, IREG_flags_res, IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + break; - default:return 0; - } - } else { - x86seg *target_seg; - uint32_t imm; + default: + return 0; + } + } else { + x86seg *target_seg; + uint32_t imm; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - if ((fetchdat & 0x38) == 0x38) /*CMP*/ - codegen_check_seg_read(block, ir, target_seg); - else - codegen_check_seg_write(block, ir, target_seg); - imm = (int32_t)(int8_t)fastreadb(cs + op_pc + 1); - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + if ((fetchdat & 0x38) == 0x38) /*CMP*/ + codegen_check_seg_read(block, ir, target_seg); + else + codegen_check_seg_write(block, ir, target_seg); + imm = (int32_t)(int8_t)fastreadb(cs + op_pc + 1); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - switch (fetchdat & 0x38) { - case 0x00: /*ADD*/ - uop_ADD_IMM(ir, IREG_temp1, IREG_temp0, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - break; + switch (fetchdat & 0x38) { + case 0x00: /*ADD*/ + uop_ADD_IMM(ir, IREG_temp1, IREG_temp0, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; - case 0x08: /*OR*/ - uop_OR_IMM(ir, IREG_temp0, IREG_temp0, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - uop_MOV(ir, IREG_flags_res, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - break; + case 0x08: /*OR*/ + uop_OR_IMM(ir, IREG_temp0, IREG_temp0, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + break; - case 0x10: /*ADC*/ - get_cf(ir, IREG_temp2); - uop_ADD_IMM(ir, IREG_temp1, IREG_temp0, imm); - uop_ADD(ir, IREG_temp1, IREG_temp1, IREG_temp2); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC32); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - break; + case 0x10: /*ADC*/ + get_cf(ir, IREG_temp2); + uop_ADD_IMM(ir, IREG_temp1, IREG_temp0, imm); + uop_ADD(ir, IREG_temp1, IREG_temp1, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; - case 0x18: /*SBB*/ - get_cf(ir, IREG_temp2); - uop_SUB_IMM(ir, IREG_temp1, IREG_temp0, imm); - uop_SUB(ir, IREG_temp1, IREG_temp1, IREG_temp2); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC32); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - break; + case 0x18: /*SBB*/ + get_cf(ir, IREG_temp2); + uop_SUB_IMM(ir, IREG_temp1, IREG_temp0, imm); + uop_SUB(ir, IREG_temp1, IREG_temp1, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; - case 0x20: /*AND*/ - uop_AND_IMM(ir, IREG_temp0, IREG_temp0, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - uop_MOV(ir, IREG_flags_res, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - break; + case 0x20: /*AND*/ + uop_AND_IMM(ir, IREG_temp0, IREG_temp0, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + break; - case 0x28: /*SUB*/ - uop_SUB_IMM(ir, IREG_temp1, IREG_temp0, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - break; + case 0x28: /*SUB*/ + uop_SUB_IMM(ir, IREG_temp1, IREG_temp0, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; - case 0x30: /*XOR*/ - uop_XOR_IMM(ir, IREG_temp0, IREG_temp0, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - uop_MOV(ir, IREG_flags_res, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - break; + case 0x30: /*XOR*/ + uop_XOR_IMM(ir, IREG_temp0, IREG_temp0, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + break; - case 0x38: /*CMP*/ - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_SUB_IMM(ir, IREG_flags_res, IREG_temp0, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); - break; + case 0x38: /*CMP*/ + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_SUB_IMM(ir, IREG_flags_res, IREG_temp0, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + break; - default:return 0; - } - } + default: + return 0; + } + } - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs + op_pc + 1, 1); - return op_pc + 2; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc + 1, 1); + return op_pc + 2; } static void rebuild_c(ir_data_t *ir) { - int needs_rebuild = 1; + int needs_rebuild = 1; - if (codegen_flags_changed) { - switch (cpu_state.flags_op) { - case FLAGS_INC8: - case FLAGS_INC16: - case FLAGS_INC32: - case FLAGS_DEC8: - case FLAGS_DEC16: - case FLAGS_DEC32:needs_rebuild = 0; - break; - } - } + if (codegen_flags_changed) { + switch (cpu_state.flags_op) { + case FLAGS_INC8: + case FLAGS_INC16: + case FLAGS_INC32: + case FLAGS_DEC8: + case FLAGS_DEC16: + case FLAGS_DEC32: + needs_rebuild = 0; + break; + } + } - if (needs_rebuild) { - uop_CALL_FUNC(ir, flags_rebuild_c); - } + if (needs_rebuild) { + uop_CALL_FUNC(ir, flags_rebuild_c); + } } uint32_t ropINC_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - rebuild_c(ir); + rebuild_c(ir); - uop_MOVZX(ir, IREG_flags_op1, IREG_16(opcode & 7)); - uop_ADD_IMM(ir, IREG_16(opcode & 7), IREG_16(opcode & 7), 1); - uop_MOVZX(ir, IREG_flags_res, IREG_16(opcode & 7)); - uop_MOV_IMM(ir, IREG_flags_op2, 1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC16); - codegen_flags_changed = 1; + uop_MOVZX(ir, IREG_flags_op1, IREG_16(opcode & 7)); + uop_ADD_IMM(ir, IREG_16(opcode & 7), IREG_16(opcode & 7), 1); + uop_MOVZX(ir, IREG_flags_res, IREG_16(opcode & 7)); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC16); + codegen_flags_changed = 1; - return op_pc; + return op_pc; } uint32_t ropINC_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - rebuild_c(ir); + rebuild_c(ir); - uop_MOV(ir, IREG_flags_op1, IREG_32(opcode & 7)); - uop_ADD_IMM(ir, IREG_32(opcode & 7), IREG_32(opcode & 7), 1); - uop_MOV(ir, IREG_flags_res, IREG_32(opcode & 7)); - uop_MOV_IMM(ir, IREG_flags_op2, 1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC32); - codegen_flags_changed = 1; + uop_MOV(ir, IREG_flags_op1, IREG_32(opcode & 7)); + uop_ADD_IMM(ir, IREG_32(opcode & 7), IREG_32(opcode & 7), 1); + uop_MOV(ir, IREG_flags_res, IREG_32(opcode & 7)); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC32); + codegen_flags_changed = 1; - return op_pc; + return op_pc; } uint32_t ropDEC_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - rebuild_c(ir); + rebuild_c(ir); - uop_MOVZX(ir, IREG_flags_op1, IREG_16(opcode & 7)); - uop_SUB_IMM(ir, IREG_16(opcode & 7), IREG_16(opcode & 7), 1); - uop_MOVZX(ir, IREG_flags_res, IREG_16(opcode & 7)); - uop_MOV_IMM(ir, IREG_flags_op2, 1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC16); - codegen_flags_changed = 1; + uop_MOVZX(ir, IREG_flags_op1, IREG_16(opcode & 7)); + uop_SUB_IMM(ir, IREG_16(opcode & 7), IREG_16(opcode & 7), 1); + uop_MOVZX(ir, IREG_flags_res, IREG_16(opcode & 7)); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC16); + codegen_flags_changed = 1; - return op_pc; + return op_pc; } uint32_t ropDEC_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - rebuild_c(ir); + rebuild_c(ir); - uop_MOV(ir, IREG_flags_op1, IREG_32(opcode & 7)); - uop_SUB_IMM(ir, IREG_32(opcode & 7), IREG_32(opcode & 7), 1); - uop_MOV(ir, IREG_flags_res, IREG_32(opcode & 7)); - uop_MOV_IMM(ir, IREG_flags_op2, 1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC32); - codegen_flags_changed = 1; + uop_MOV(ir, IREG_flags_op1, IREG_32(opcode & 7)); + uop_SUB_IMM(ir, IREG_32(opcode & 7), IREG_32(opcode & 7), 1); + uop_MOV(ir, IREG_flags_res, IREG_32(opcode & 7)); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC32); + codegen_flags_changed = 1; - return op_pc; + return op_pc; } uint32_t ropINCDEC(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - codegen_mark_code_present(block, cs + op_pc, 1); - rebuild_c(ir); + codegen_mark_code_present(block, cs + op_pc, 1); + rebuild_c(ir); - if ((fetchdat & 0xc0) == 0xc0) { - uop_MOVZX(ir, IREG_flags_op1, IREG_8(fetchdat & 7)); - if (fetchdat & 0x38) { - uop_SUB_IMM(ir, IREG_8(fetchdat & 7), IREG_8(fetchdat & 7), 1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC8); - } else { - uop_ADD_IMM(ir, IREG_8(fetchdat & 7), IREG_8(fetchdat & 7), 1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC8); - } - uop_MOVZX(ir, IREG_flags_res, IREG_8(fetchdat & 7)); - uop_MOV_IMM(ir, IREG_flags_op2, 1); - } else { - x86seg *target_seg; + if ((fetchdat & 0xc0) == 0xc0) { + uop_MOVZX(ir, IREG_flags_op1, IREG_8(fetchdat & 7)); + if (fetchdat & 0x38) { + uop_SUB_IMM(ir, IREG_8(fetchdat & 7), IREG_8(fetchdat & 7), 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC8); + } else { + uop_ADD_IMM(ir, IREG_8(fetchdat & 7), IREG_8(fetchdat & 7), 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC8); + } + uop_MOVZX(ir, IREG_flags_res, IREG_8(fetchdat & 7)); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - if (fetchdat & 0x38) { - uop_SUB_IMM(ir, IREG_temp1_B, IREG_temp0_B, 1); - } else { - uop_ADD_IMM(ir, IREG_temp1_B, IREG_temp0_B, 1); - } - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); - uop_MOV_IMM(ir, IREG_flags_op2, 1); - if (fetchdat & 0x38) { - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC8); - } else { - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC8); - } - } + if (fetchdat & 0x38) { + uop_SUB_IMM(ir, IREG_temp1_B, IREG_temp0_B, 1); + } else { + uop_ADD_IMM(ir, IREG_temp1_B, IREG_temp0_B, 1); + } + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + if (fetchdat & 0x38) { + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC8); + } else { + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC8); + } + } - return op_pc + 1; + return op_pc + 1; } diff --git a/src/codegen/codegen_ops_branch.c b/src/codegen/codegen_ops_branch.c index d06986ca..bfe19f7f 100644 --- a/src/codegen/codegen_ops_branch.c +++ b/src/codegen/codegen_ops_branch.c @@ -10,920 +10,919 @@ #include "codegen_ops_helpers.h" #include "codegen_ops_mov.h" -static int NF_SET_01() { - return NF_SET() ? 1 : 0; -} -static int VF_SET_01() { - return VF_SET() ? 1 : 0; -} +static int NF_SET_01() { return NF_SET() ? 1 : 0; } +static int VF_SET_01() { return VF_SET() ? 1 : 0; } static int ropJO_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) { - int jump_uop; + int jump_uop; - switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { - case FLAGS_ZN8: - case FLAGS_ZN16: - case FLAGS_ZN32: - /*Overflow is always zero*/ - return 0; + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { + case FLAGS_ZN8: + case FLAGS_ZN16: + case FLAGS_ZN32: + /*Overflow is always zero*/ + return 0; - case FLAGS_SUB8: - case FLAGS_DEC8:jump_uop = uop_CMP_JNO_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); - break; + case FLAGS_SUB8: + case FLAGS_DEC8: + jump_uop = uop_CMP_JNO_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + break; - case FLAGS_SUB16: - case FLAGS_DEC16:jump_uop = uop_CMP_JNO_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); - break; + case FLAGS_SUB16: + case FLAGS_DEC16: + jump_uop = uop_CMP_JNO_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + break; - case FLAGS_SUB32: - case FLAGS_DEC32:jump_uop = uop_CMP_JNO_DEST(ir, IREG_flags_op1, IREG_flags_op2); - break; + case FLAGS_SUB32: + case FLAGS_DEC32: + jump_uop = uop_CMP_JNO_DEST(ir, IREG_flags_op1, IREG_flags_op2); + break; - case FLAGS_UNKNOWN: - default:uop_CALL_FUNC_RESULT(ir, IREG_temp0, VF_SET); - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); - break; - } - uop_MOV_IMM(ir, IREG_pc, dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - return 0; + case FLAGS_UNKNOWN: + default: + uop_CALL_FUNC_RESULT(ir, IREG_temp0, VF_SET); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); + break; + } + uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + return 0; } static int ropJNO_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) { - int jump_uop; + int jump_uop; - switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { - case FLAGS_ZN8: - case FLAGS_ZN16: - case FLAGS_ZN32: - /*Overflow is always zero*/ - uop_MOV_IMM(ir, IREG_pc, dest_addr); - uop_JMP(ir, codegen_exit_rout); - return 0; + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { + case FLAGS_ZN8: + case FLAGS_ZN16: + case FLAGS_ZN32: + /*Overflow is always zero*/ + uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_JMP(ir, codegen_exit_rout); + return 0; - case FLAGS_SUB8: - case FLAGS_DEC8:jump_uop = uop_CMP_JO_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); - break; + case FLAGS_SUB8: + case FLAGS_DEC8: + jump_uop = uop_CMP_JO_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + break; - case FLAGS_SUB16: - case FLAGS_DEC16:jump_uop = uop_CMP_JO_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); - break; + case FLAGS_SUB16: + case FLAGS_DEC16: + jump_uop = uop_CMP_JO_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + break; - case FLAGS_SUB32: - case FLAGS_DEC32:jump_uop = uop_CMP_JO_DEST(ir, IREG_flags_op1, IREG_flags_op2); - break; + case FLAGS_SUB32: + case FLAGS_DEC32: + jump_uop = uop_CMP_JO_DEST(ir, IREG_flags_op1, IREG_flags_op2); + break; - case FLAGS_UNKNOWN: - default:uop_CALL_FUNC_RESULT(ir, IREG_temp0, VF_SET); - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - break; - } - uop_MOV_IMM(ir, IREG_pc, dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - return 0; + case FLAGS_UNKNOWN: + default: + uop_CALL_FUNC_RESULT(ir, IREG_temp0, VF_SET); + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + break; + } + uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + return 0; } static int ropJB_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) { - int jump_uop; - int do_unroll = (CF_SET() && codegen_can_unroll(block, ir, next_pc, dest_addr)); + int jump_uop; + int do_unroll = (CF_SET() && codegen_can_unroll(block, ir, next_pc, dest_addr)); - switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { - case FLAGS_ZN8: - case FLAGS_ZN16: - case FLAGS_ZN32: - /*Carry is always zero*/ - return 0; + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { + case FLAGS_ZN8: + case FLAGS_ZN16: + case FLAGS_ZN32: + /*Carry is always zero*/ + return 0; - case FLAGS_SUB8: - if (do_unroll) - jump_uop = uop_CMP_JB_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); - else - jump_uop = uop_CMP_JNB_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); - break; + case FLAGS_SUB8: + if (do_unroll) + jump_uop = uop_CMP_JB_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + else + jump_uop = uop_CMP_JNB_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + break; - case FLAGS_SUB16: - if (do_unroll) - jump_uop = uop_CMP_JB_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); - else - jump_uop = uop_CMP_JNB_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); - break; + case FLAGS_SUB16: + if (do_unroll) + jump_uop = uop_CMP_JB_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + else + jump_uop = uop_CMP_JNB_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + break; - case FLAGS_SUB32: - if (do_unroll) - jump_uop = uop_CMP_JB_DEST(ir, IREG_flags_op1, IREG_flags_op2); - else - jump_uop = uop_CMP_JNB_DEST(ir, IREG_flags_op1, IREG_flags_op2); - break; + case FLAGS_SUB32: + if (do_unroll) + jump_uop = uop_CMP_JB_DEST(ir, IREG_flags_op1, IREG_flags_op2); + else + jump_uop = uop_CMP_JNB_DEST(ir, IREG_flags_op1, IREG_flags_op2); + break; - case FLAGS_UNKNOWN: - default:uop_CALL_FUNC_RESULT(ir, IREG_temp0, CF_SET); - if (do_unroll) - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - else - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); - break; - } - uop_MOV_IMM(ir, IREG_pc, do_unroll ? next_pc : dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - return do_unroll ? 1 : 0; + case FLAGS_UNKNOWN: + default: + uop_CALL_FUNC_RESULT(ir, IREG_temp0, CF_SET); + if (do_unroll) + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + else + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); + break; + } + uop_MOV_IMM(ir, IREG_pc, do_unroll ? next_pc : dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + return do_unroll ? 1 : 0; } static int ropJNB_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) { - int jump_uop; - int do_unroll = (!CF_SET() && codegen_can_unroll(block, ir, next_pc, dest_addr)); + int jump_uop; + int do_unroll = (!CF_SET() && codegen_can_unroll(block, ir, next_pc, dest_addr)); - switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { - case FLAGS_ZN8: - case FLAGS_ZN16: - case FLAGS_ZN32: - /*Carry is always zero*/ - uop_MOV_IMM(ir, IREG_pc, dest_addr); - uop_JMP(ir, codegen_exit_rout); - return 0; + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { + case FLAGS_ZN8: + case FLAGS_ZN16: + case FLAGS_ZN32: + /*Carry is always zero*/ + uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_JMP(ir, codegen_exit_rout); + return 0; - case FLAGS_SUB8: - if (do_unroll) - jump_uop = uop_CMP_JNB_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); - else - jump_uop = uop_CMP_JB_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); - break; + case FLAGS_SUB8: + if (do_unroll) + jump_uop = uop_CMP_JNB_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + else + jump_uop = uop_CMP_JB_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + break; - case FLAGS_SUB16: - if (do_unroll) - jump_uop = uop_CMP_JNB_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); - else - jump_uop = uop_CMP_JB_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); - break; + case FLAGS_SUB16: + if (do_unroll) + jump_uop = uop_CMP_JNB_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + else + jump_uop = uop_CMP_JB_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + break; - case FLAGS_SUB32: - if (do_unroll) - jump_uop = uop_CMP_JNB_DEST(ir, IREG_flags_op1, IREG_flags_op2); - else - jump_uop = uop_CMP_JB_DEST(ir, IREG_flags_op1, IREG_flags_op2); - break; + case FLAGS_SUB32: + if (do_unroll) + jump_uop = uop_CMP_JNB_DEST(ir, IREG_flags_op1, IREG_flags_op2); + else + jump_uop = uop_CMP_JB_DEST(ir, IREG_flags_op1, IREG_flags_op2); + break; - case FLAGS_UNKNOWN: - default:uop_CALL_FUNC_RESULT(ir, IREG_temp0, CF_SET); - if (do_unroll) - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); - else - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - break; - } - uop_MOV_IMM(ir, IREG_pc, do_unroll ? next_pc : dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - return do_unroll ? 1 : 0; + case FLAGS_UNKNOWN: + default: + uop_CALL_FUNC_RESULT(ir, IREG_temp0, CF_SET); + if (do_unroll) + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); + else + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + break; + } + uop_MOV_IMM(ir, IREG_pc, do_unroll ? next_pc : dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + return do_unroll ? 1 : 0; } static int ropJE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) { - int jump_uop; + int jump_uop; - if (ZF_SET() && codegen_can_unroll(block, ir, next_pc, dest_addr)) { - if (!codegen_flags_changed || !flags_res_valid()) { - uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - } else { - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_flags_res, 0); - } - uop_MOV_IMM(ir, IREG_pc, next_pc); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - return 1; - } else { - if (!codegen_flags_changed || !flags_res_valid()) { - uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); - } else { - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_flags_res, 0); - } - uop_MOV_IMM(ir, IREG_pc, dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - } - return 0; + if (ZF_SET() && codegen_can_unroll(block, ir, next_pc, dest_addr)) { + if (!codegen_flags_changed || !flags_res_valid()) { + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + } else { + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_flags_res, 0); + } + uop_MOV_IMM(ir, IREG_pc, next_pc); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + return 1; + } else { + if (!codegen_flags_changed || !flags_res_valid()) { + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); + } else { + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_flags_res, 0); + } + uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + } + return 0; } int ropJNE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) { - int jump_uop; + int jump_uop; - if (!ZF_SET() && codegen_can_unroll(block, ir, next_pc, dest_addr)) { - if (!codegen_flags_changed || !flags_res_valid()) { - uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); - } else { - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_flags_res, 0); - } - uop_MOV_IMM(ir, IREG_pc, next_pc); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - return 1; - } else { - if (!codegen_flags_changed || !flags_res_valid()) { - uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - } else { - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_flags_res, 0); - } - uop_MOV_IMM(ir, IREG_pc, dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - } - return 0; + if (!ZF_SET() && codegen_can_unroll(block, ir, next_pc, dest_addr)) { + if (!codegen_flags_changed || !flags_res_valid()) { + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); + } else { + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_flags_res, 0); + } + uop_MOV_IMM(ir, IREG_pc, next_pc); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + return 1; + } else { + if (!codegen_flags_changed || !flags_res_valid()) { + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + } else { + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_flags_res, 0); + } + uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + } + return 0; } static int ropJBE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) { - int jump_uop, jump_uop2 = -1; - int do_unroll = ((CF_SET() || ZF_SET()) && codegen_can_unroll(block, ir, next_pc, dest_addr)); + int jump_uop, jump_uop2 = -1; + int do_unroll = ((CF_SET() || ZF_SET()) && codegen_can_unroll(block, ir, next_pc, dest_addr)); - switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { - case FLAGS_ZN8: - case FLAGS_ZN16: - case FLAGS_ZN32: - /*Carry is always zero, so test zero only*/ - if (do_unroll) - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_flags_res, 0); - else - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_flags_res, 0); - break; + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { + case FLAGS_ZN8: + case FLAGS_ZN16: + case FLAGS_ZN32: + /*Carry is always zero, so test zero only*/ + if (do_unroll) + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_flags_res, 0); + else + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_flags_res, 0); + break; - case FLAGS_SUB8: - if (do_unroll) - jump_uop = uop_CMP_JBE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); - else - jump_uop = uop_CMP_JNBE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); - break; - case FLAGS_SUB16: - if (do_unroll) - jump_uop = uop_CMP_JBE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); - else - jump_uop = uop_CMP_JNBE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); - break; - case FLAGS_SUB32: - if (do_unroll) - jump_uop = uop_CMP_JBE_DEST(ir, IREG_flags_op1, IREG_flags_op2); - else - jump_uop = uop_CMP_JNBE_DEST(ir, IREG_flags_op1, IREG_flags_op2); - break; + case FLAGS_SUB8: + if (do_unroll) + jump_uop = uop_CMP_JBE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + else + jump_uop = uop_CMP_JNBE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + break; + case FLAGS_SUB16: + if (do_unroll) + jump_uop = uop_CMP_JBE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + else + jump_uop = uop_CMP_JNBE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + break; + case FLAGS_SUB32: + if (do_unroll) + jump_uop = uop_CMP_JBE_DEST(ir, IREG_flags_op1, IREG_flags_op2); + else + jump_uop = uop_CMP_JNBE_DEST(ir, IREG_flags_op1, IREG_flags_op2); + break; - case FLAGS_UNKNOWN: - default: - if (do_unroll) { - uop_CALL_FUNC_RESULT(ir, IREG_temp0, CF_SET); - jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - } else { - uop_CALL_FUNC_RESULT(ir, IREG_temp0, CF_SET); - jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); - } - break; - } - if (do_unroll) { - uop_MOV_IMM(ir, IREG_pc, next_pc); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - if (jump_uop2 != -1) - uop_set_jump_dest(ir, jump_uop2); - return 1; - } else { - if (jump_uop2 != -1) - uop_set_jump_dest(ir, jump_uop2); - uop_MOV_IMM(ir, IREG_pc, dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - return 0; - } + case FLAGS_UNKNOWN: + default: + if (do_unroll) { + uop_CALL_FUNC_RESULT(ir, IREG_temp0, CF_SET); + jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + } else { + uop_CALL_FUNC_RESULT(ir, IREG_temp0, CF_SET); + jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); + } + break; + } + if (do_unroll) { + uop_MOV_IMM(ir, IREG_pc, next_pc); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + if (jump_uop2 != -1) + uop_set_jump_dest(ir, jump_uop2); + return 1; + } else { + if (jump_uop2 != -1) + uop_set_jump_dest(ir, jump_uop2); + uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + return 0; + } } static int ropJNBE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) { - int jump_uop, jump_uop2 = -1; - int do_unroll = ((!CF_SET() && !ZF_SET()) && codegen_can_unroll(block, ir, next_pc, dest_addr)); + int jump_uop, jump_uop2 = -1; + int do_unroll = ((!CF_SET() && !ZF_SET()) && codegen_can_unroll(block, ir, next_pc, dest_addr)); - switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { - case FLAGS_ZN8: - case FLAGS_ZN16: - case FLAGS_ZN32: - /*Carry is always zero, so test zero only*/ - if (do_unroll) - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_flags_res, 0); - else - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_flags_res, 0); - break; + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { + case FLAGS_ZN8: + case FLAGS_ZN16: + case FLAGS_ZN32: + /*Carry is always zero, so test zero only*/ + if (do_unroll) + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_flags_res, 0); + else + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_flags_res, 0); + break; - case FLAGS_SUB8: - if (do_unroll) - jump_uop = uop_CMP_JNBE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); - else - jump_uop = uop_CMP_JBE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); - break; - case FLAGS_SUB16: - if (do_unroll) - jump_uop = uop_CMP_JNBE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); - else - jump_uop = uop_CMP_JBE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); - break; - case FLAGS_SUB32: - if (do_unroll) - jump_uop = uop_CMP_JNBE_DEST(ir, IREG_flags_op1, IREG_flags_op2); - else - jump_uop = uop_CMP_JBE_DEST(ir, IREG_flags_op1, IREG_flags_op2); - break; + case FLAGS_SUB8: + if (do_unroll) + jump_uop = uop_CMP_JNBE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + else + jump_uop = uop_CMP_JBE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + break; + case FLAGS_SUB16: + if (do_unroll) + jump_uop = uop_CMP_JNBE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + else + jump_uop = uop_CMP_JBE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + break; + case FLAGS_SUB32: + if (do_unroll) + jump_uop = uop_CMP_JNBE_DEST(ir, IREG_flags_op1, IREG_flags_op2); + else + jump_uop = uop_CMP_JBE_DEST(ir, IREG_flags_op1, IREG_flags_op2); + break; - case FLAGS_UNKNOWN: - default: - if (do_unroll) { - uop_CALL_FUNC_RESULT(ir, IREG_temp0, CF_SET); - jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); - } else { - uop_CALL_FUNC_RESULT(ir, IREG_temp0, CF_SET); - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); - jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - } - break; - } - if (do_unroll) { - if (jump_uop2 != -1) - uop_set_jump_dest(ir, jump_uop2); - uop_MOV_IMM(ir, IREG_pc, next_pc); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - return 1; - } else { - uop_MOV_IMM(ir, IREG_pc, dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - if (jump_uop2 != -1) - uop_set_jump_dest(ir, jump_uop2); - return 0; - } + case FLAGS_UNKNOWN: + default: + if (do_unroll) { + uop_CALL_FUNC_RESULT(ir, IREG_temp0, CF_SET); + jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); + } else { + uop_CALL_FUNC_RESULT(ir, IREG_temp0, CF_SET); + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + } + break; + } + if (do_unroll) { + if (jump_uop2 != -1) + uop_set_jump_dest(ir, jump_uop2); + uop_MOV_IMM(ir, IREG_pc, next_pc); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + return 1; + } else { + uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + if (jump_uop2 != -1) + uop_set_jump_dest(ir, jump_uop2); + return 0; + } } static int ropJS_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) { - int jump_uop; - int do_unroll = (NF_SET() && codegen_can_unroll(block, ir, next_pc, dest_addr)); + int jump_uop; + int do_unroll = (NF_SET() && codegen_can_unroll(block, ir, next_pc, dest_addr)); - 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: - if (do_unroll) - jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_B); - else - jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_B); - break; + 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: + if (do_unroll) + jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_B); + else + jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_B); + 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: - if (do_unroll) - jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_W); - else - jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_W); - 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: + if (do_unroll) + jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_W); + else + jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_W); + 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: - if (do_unroll) - jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res); - else - jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res); - 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: + if (do_unroll) + jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res); + else + jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res); + break; - case FLAGS_UNKNOWN: - default:uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET); - if (do_unroll) - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - else - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); - break; - } - uop_MOV_IMM(ir, IREG_pc, do_unroll ? next_pc : dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - return do_unroll ? 1 : 0; + case FLAGS_UNKNOWN: + default: + uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET); + if (do_unroll) + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + else + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); + break; + } + uop_MOV_IMM(ir, IREG_pc, do_unroll ? next_pc : dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + return do_unroll ? 1 : 0; } static int ropJNS_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) { - int jump_uop; - int do_unroll = (!NF_SET() && codegen_can_unroll(block, ir, next_pc, dest_addr)); + int jump_uop; + int do_unroll = (!NF_SET() && codegen_can_unroll(block, ir, next_pc, dest_addr)); - 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: - if (do_unroll) - jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_B); - else - jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_B); - break; + 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: + if (do_unroll) + jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_B); + else + jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_B); + 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: - if (do_unroll) - jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_W); - else - jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_W); - 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: + if (do_unroll) + jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_W); + else + jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_W); + 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: - if (do_unroll) - jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res); - else - jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res); - 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: + if (do_unroll) + jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res); + else + jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res); + break; - case FLAGS_UNKNOWN: - default:uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET); - if (do_unroll) - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); - else - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - break; - } - uop_MOV_IMM(ir, IREG_pc, do_unroll ? next_pc : dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - return do_unroll ? 1 : 0; + case FLAGS_UNKNOWN: + default: + uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET); + if (do_unroll) + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); + else + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + break; + } + uop_MOV_IMM(ir, IREG_pc, do_unroll ? next_pc : dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + return do_unroll ? 1 : 0; } static int ropJP_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) { - int jump_uop; + int jump_uop; - uop_CALL_FUNC_RESULT(ir, IREG_temp0, PF_SET); - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); - uop_MOV_IMM(ir, IREG_pc, dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - return 0; + uop_CALL_FUNC_RESULT(ir, IREG_temp0, PF_SET); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); + uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + return 0; } static int ropJNP_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) { - int jump_uop; + int jump_uop; - uop_CALL_FUNC_RESULT(ir, IREG_temp0, PF_SET); - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - uop_MOV_IMM(ir, IREG_pc, dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - return 0; + uop_CALL_FUNC_RESULT(ir, IREG_temp0, PF_SET); + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + return 0; } static int ropJL_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) { - int jump_uop; - int do_unroll = ((NF_SET() ? 1 : 0) != (VF_SET() ? 1 : 0) && codegen_can_unroll(block, ir, next_pc, dest_addr)); + int jump_uop; + int do_unroll = ((NF_SET() ? 1 : 0) != (VF_SET() ? 1 : 0) && codegen_can_unroll(block, ir, next_pc, dest_addr)); - switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { - case FLAGS_ZN8: - /*V flag is always clear. Condition is true if N is set*/ - if (do_unroll) - jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_B); - else - jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_B); - break; - case FLAGS_ZN16: - if (do_unroll) - jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_W); - else - jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_W); - break; - case FLAGS_ZN32: - if (do_unroll) - jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res); - else - jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res); - break; + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { + case FLAGS_ZN8: + /*V flag is always clear. Condition is true if N is set*/ + if (do_unroll) + jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_B); + else + jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_B); + break; + case FLAGS_ZN16: + if (do_unroll) + jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_W); + else + jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_W); + break; + case FLAGS_ZN32: + if (do_unroll) + jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res); + else + jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res); + break; - case FLAGS_SUB8: - case FLAGS_DEC8: - if (do_unroll) - jump_uop = uop_CMP_JL_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); - else - jump_uop = uop_CMP_JNL_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); - break; - case FLAGS_SUB16: - case FLAGS_DEC16: - if (do_unroll) - jump_uop = uop_CMP_JL_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); - else - jump_uop = uop_CMP_JNL_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); - break; - case FLAGS_SUB32: - case FLAGS_DEC32: - if (do_unroll) - jump_uop = uop_CMP_JL_DEST(ir, IREG_flags_op1, IREG_flags_op2); - else - jump_uop = uop_CMP_JNL_DEST(ir, IREG_flags_op1, IREG_flags_op2); - break; + case FLAGS_SUB8: + case FLAGS_DEC8: + if (do_unroll) + jump_uop = uop_CMP_JL_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + else + jump_uop = uop_CMP_JNL_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + break; + case FLAGS_SUB16: + case FLAGS_DEC16: + if (do_unroll) + jump_uop = uop_CMP_JL_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + else + jump_uop = uop_CMP_JNL_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + break; + case FLAGS_SUB32: + case FLAGS_DEC32: + if (do_unroll) + jump_uop = uop_CMP_JL_DEST(ir, IREG_flags_op1, IREG_flags_op2); + else + jump_uop = uop_CMP_JNL_DEST(ir, IREG_flags_op1, IREG_flags_op2); + break; - case FLAGS_UNKNOWN: - default:uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET_01); - uop_CALL_FUNC_RESULT(ir, IREG_temp1, VF_SET_01); - if (do_unroll) - jump_uop = uop_CMP_JNZ_DEST(ir, IREG_temp0, IREG_temp1); - else - jump_uop = uop_CMP_JZ_DEST(ir, IREG_temp0, IREG_temp1); - break; - } - if (do_unroll) - uop_MOV_IMM(ir, IREG_pc, next_pc); - else - uop_MOV_IMM(ir, IREG_pc, dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - return do_unroll ? 1 : 0; + case FLAGS_UNKNOWN: + default: + uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET_01); + uop_CALL_FUNC_RESULT(ir, IREG_temp1, VF_SET_01); + if (do_unroll) + jump_uop = uop_CMP_JNZ_DEST(ir, IREG_temp0, IREG_temp1); + else + jump_uop = uop_CMP_JZ_DEST(ir, IREG_temp0, IREG_temp1); + break; + } + if (do_unroll) + uop_MOV_IMM(ir, IREG_pc, next_pc); + else + uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + return do_unroll ? 1 : 0; } static int ropJNL_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) { - int jump_uop; - int do_unroll = ((NF_SET() ? 1 : 0) == (VF_SET() ? 1 : 0) && codegen_can_unroll(block, ir, next_pc, dest_addr)); + int jump_uop; + int do_unroll = ((NF_SET() ? 1 : 0) == (VF_SET() ? 1 : 0) && codegen_can_unroll(block, ir, next_pc, dest_addr)); - switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { - case FLAGS_ZN8: - /*V flag is always clear. Condition is true if N is set*/ - if (do_unroll) - jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_B); - else - jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_B); - break; - case FLAGS_ZN16: - if (do_unroll) - jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_W); - else - jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_W); - break; - case FLAGS_ZN32: - if (do_unroll) - jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res); - else - jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res); - break; + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { + case FLAGS_ZN8: + /*V flag is always clear. Condition is true if N is set*/ + if (do_unroll) + jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_B); + else + jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_B); + break; + case FLAGS_ZN16: + if (do_unroll) + jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_W); + else + jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_W); + break; + case FLAGS_ZN32: + if (do_unroll) + jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res); + else + jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res); + break; - case FLAGS_SUB8: - case FLAGS_DEC8: - if (do_unroll) - jump_uop = uop_CMP_JNL_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); - else - jump_uop = uop_CMP_JL_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); - break; - case FLAGS_SUB16: - case FLAGS_DEC16: - if (do_unroll) - jump_uop = uop_CMP_JNL_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); - else - jump_uop = uop_CMP_JL_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); - break; - case FLAGS_SUB32: - case FLAGS_DEC32: - if (do_unroll) - jump_uop = uop_CMP_JNL_DEST(ir, IREG_flags_op1, IREG_flags_op2); - else - jump_uop = uop_CMP_JL_DEST(ir, IREG_flags_op1, IREG_flags_op2); - break; + case FLAGS_SUB8: + case FLAGS_DEC8: + if (do_unroll) + jump_uop = uop_CMP_JNL_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + else + jump_uop = uop_CMP_JL_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + break; + case FLAGS_SUB16: + case FLAGS_DEC16: + if (do_unroll) + jump_uop = uop_CMP_JNL_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + else + jump_uop = uop_CMP_JL_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + break; + case FLAGS_SUB32: + case FLAGS_DEC32: + if (do_unroll) + jump_uop = uop_CMP_JNL_DEST(ir, IREG_flags_op1, IREG_flags_op2); + else + jump_uop = uop_CMP_JL_DEST(ir, IREG_flags_op1, IREG_flags_op2); + break; - case FLAGS_UNKNOWN: - default:uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET_01); - uop_CALL_FUNC_RESULT(ir, IREG_temp1, VF_SET_01); - if (do_unroll) - jump_uop = uop_CMP_JZ_DEST(ir, IREG_temp0, IREG_temp1); - else - jump_uop = uop_CMP_JNZ_DEST(ir, IREG_temp0, IREG_temp1); - break; - } - if (do_unroll) - uop_MOV_IMM(ir, IREG_pc, next_pc); - else - uop_MOV_IMM(ir, IREG_pc, dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - return do_unroll ? 1 : 0; + case FLAGS_UNKNOWN: + default: + uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET_01); + uop_CALL_FUNC_RESULT(ir, IREG_temp1, VF_SET_01); + if (do_unroll) + jump_uop = uop_CMP_JZ_DEST(ir, IREG_temp0, IREG_temp1); + else + jump_uop = uop_CMP_JNZ_DEST(ir, IREG_temp0, IREG_temp1); + break; + } + if (do_unroll) + uop_MOV_IMM(ir, IREG_pc, next_pc); + else + uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + return do_unroll ? 1 : 0; } static int ropJLE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) { - int jump_uop, jump_uop2 = -1; - int do_unroll = (((NF_SET() ? 1 : 0) != (VF_SET() ? 1 : 0) || ZF_SET()) && codegen_can_unroll(block, ir, next_pc, dest_addr)); + int jump_uop, jump_uop2 = -1; + int do_unroll = + (((NF_SET() ? 1 : 0) != (VF_SET() ? 1 : 0) || ZF_SET()) && codegen_can_unroll(block, ir, next_pc, dest_addr)); - switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { - case FLAGS_SUB8: - case FLAGS_DEC8: - if (do_unroll) - jump_uop = uop_CMP_JLE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); - else - jump_uop = uop_CMP_JNLE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); - break; - case FLAGS_SUB16: - case FLAGS_DEC16: - if (do_unroll) - jump_uop = uop_CMP_JLE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); - else - jump_uop = uop_CMP_JNLE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); - break; - case FLAGS_SUB32: - case FLAGS_DEC32: - if (do_unroll) - jump_uop = uop_CMP_JLE_DEST(ir, IREG_flags_op1, IREG_flags_op2); - else - jump_uop = uop_CMP_JNLE_DEST(ir, IREG_flags_op1, IREG_flags_op2); - break; + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { + case FLAGS_SUB8: + case FLAGS_DEC8: + if (do_unroll) + jump_uop = uop_CMP_JLE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + else + jump_uop = uop_CMP_JNLE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + break; + case FLAGS_SUB16: + case FLAGS_DEC16: + if (do_unroll) + jump_uop = uop_CMP_JLE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + else + jump_uop = uop_CMP_JNLE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + break; + case FLAGS_SUB32: + case FLAGS_DEC32: + if (do_unroll) + jump_uop = uop_CMP_JLE_DEST(ir, IREG_flags_op1, IREG_flags_op2); + else + jump_uop = uop_CMP_JNLE_DEST(ir, IREG_flags_op1, IREG_flags_op2); + break; - case FLAGS_UNKNOWN: - default: - if (do_unroll) { - uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); - jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET_01); - uop_CALL_FUNC_RESULT(ir, IREG_temp1, VF_SET_01); - jump_uop = uop_CMP_JNZ_DEST(ir, IREG_temp0, IREG_temp1); - } else { - uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); - jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET_01); - uop_CALL_FUNC_RESULT(ir, IREG_temp1, VF_SET_01); - jump_uop = uop_CMP_JZ_DEST(ir, IREG_temp0, IREG_temp1); - } - break; - } - if (do_unroll) { - uop_MOV_IMM(ir, IREG_pc, next_pc); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - if (jump_uop2 != -1) - uop_set_jump_dest(ir, jump_uop2); - return 1; - } else { - if (jump_uop2 != -1) - uop_set_jump_dest(ir, jump_uop2); - uop_MOV_IMM(ir, IREG_pc, dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - return 0; - } + case FLAGS_UNKNOWN: + default: + if (do_unroll) { + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET_01); + uop_CALL_FUNC_RESULT(ir, IREG_temp1, VF_SET_01); + jump_uop = uop_CMP_JNZ_DEST(ir, IREG_temp0, IREG_temp1); + } else { + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET_01); + uop_CALL_FUNC_RESULT(ir, IREG_temp1, VF_SET_01); + jump_uop = uop_CMP_JZ_DEST(ir, IREG_temp0, IREG_temp1); + } + break; + } + if (do_unroll) { + uop_MOV_IMM(ir, IREG_pc, next_pc); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + if (jump_uop2 != -1) + uop_set_jump_dest(ir, jump_uop2); + return 1; + } else { + if (jump_uop2 != -1) + uop_set_jump_dest(ir, jump_uop2); + uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + return 0; + } } static int ropJNLE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) { - int jump_uop, jump_uop2 = -1; - int do_unroll = ((NF_SET() ? 1 : 0) == (VF_SET() ? 1 : 0) && !ZF_SET() && codegen_can_unroll(block, ir, next_pc, dest_addr)); + int jump_uop, jump_uop2 = -1; + int do_unroll = + ((NF_SET() ? 1 : 0) == (VF_SET() ? 1 : 0) && !ZF_SET() && codegen_can_unroll(block, ir, next_pc, dest_addr)); - switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { - case FLAGS_SUB8: - case FLAGS_DEC8: - if (do_unroll) - jump_uop = uop_CMP_JNLE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); - else - jump_uop = uop_CMP_JLE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); - break; - case FLAGS_SUB16: - case FLAGS_DEC16: - if (do_unroll) - jump_uop = uop_CMP_JNLE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); - else - jump_uop = uop_CMP_JLE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); - break; - case FLAGS_SUB32: - case FLAGS_DEC32: - if (do_unroll) - jump_uop = uop_CMP_JNLE_DEST(ir, IREG_flags_op1, IREG_flags_op2); - else - jump_uop = uop_CMP_JLE_DEST(ir, IREG_flags_op1, IREG_flags_op2); - break; + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { + case FLAGS_SUB8: + case FLAGS_DEC8: + if (do_unroll) + jump_uop = uop_CMP_JNLE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + else + jump_uop = uop_CMP_JLE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + break; + case FLAGS_SUB16: + case FLAGS_DEC16: + if (do_unroll) + jump_uop = uop_CMP_JNLE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + else + jump_uop = uop_CMP_JLE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + break; + case FLAGS_SUB32: + case FLAGS_DEC32: + if (do_unroll) + jump_uop = uop_CMP_JNLE_DEST(ir, IREG_flags_op1, IREG_flags_op2); + else + jump_uop = uop_CMP_JLE_DEST(ir, IREG_flags_op1, IREG_flags_op2); + break; - case FLAGS_UNKNOWN: - default: - if (do_unroll) { - uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); - jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET_01); - uop_CALL_FUNC_RESULT(ir, IREG_temp1, VF_SET_01); - jump_uop = uop_CMP_JZ_DEST(ir, IREG_temp0, IREG_temp1); - } else { - uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); - jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET_01); - uop_CALL_FUNC_RESULT(ir, IREG_temp1, VF_SET_01); - jump_uop = uop_CMP_JNZ_DEST(ir, IREG_temp0, IREG_temp1); - } - break; - } - if (do_unroll) { - if (jump_uop2 != -1) - uop_set_jump_dest(ir, jump_uop2); - uop_MOV_IMM(ir, IREG_pc, next_pc); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - return 1; - } else { - uop_MOV_IMM(ir, IREG_pc, dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - if (jump_uop2 != -1) - uop_set_jump_dest(ir, jump_uop2); - return 0; - } + case FLAGS_UNKNOWN: + default: + if (do_unroll) { + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET_01); + uop_CALL_FUNC_RESULT(ir, IREG_temp1, VF_SET_01); + jump_uop = uop_CMP_JZ_DEST(ir, IREG_temp0, IREG_temp1); + } else { + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET_01); + uop_CALL_FUNC_RESULT(ir, IREG_temp1, VF_SET_01); + jump_uop = uop_CMP_JNZ_DEST(ir, IREG_temp0, IREG_temp1); + } + break; + } + if (do_unroll) { + if (jump_uop2 != -1) + uop_set_jump_dest(ir, jump_uop2); + uop_MOV_IMM(ir, IREG_pc, next_pc); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + return 1; + } else { + uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + if (jump_uop2 != -1) + uop_set_jump_dest(ir, jump_uop2); + return 0; + } } -#define ropJ(cond) \ -uint32_t ropJ ## cond ## _8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - uint32_t offset = (int32_t)(int8_t)fastreadb(cs + op_pc); \ - uint32_t dest_addr = op_pc + 1 + offset; \ - int ret; \ - \ - if (!(op_32 & 0x100)) \ - dest_addr &= 0xffff; \ - ret = ropJ ## cond ## _common(block, ir, dest_addr, op_pc+1); \ - \ - codegen_mark_code_present(block, cs+op_pc, 1); \ - return ret ? dest_addr : (op_pc+1); \ -} \ -uint32_t ropJ ## cond ## _16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - uint32_t offset = (int32_t)(int16_t)fastreadw(cs + op_pc); \ - uint32_t dest_addr = (op_pc + 2 + offset) & 0xffff; \ - int ret; \ - \ - ret = ropJ ## cond ## _common(block, ir, dest_addr, op_pc+2); \ - \ - codegen_mark_code_present(block, cs+op_pc, 2); \ - return ret ? dest_addr : (op_pc+2); \ -} \ -uint32_t ropJ ## cond ## _32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - uint32_t offset = fastreadl(cs + op_pc); \ - uint32_t dest_addr = op_pc + 4 + offset; \ - int ret; \ - \ - ret = ropJ ## cond ## _common(block, ir, dest_addr, op_pc+4); \ - \ - codegen_mark_code_present(block, cs+op_pc, 4); \ - return ret ? dest_addr : (op_pc+4); \ -} +#define ropJ(cond) \ + uint32_t ropJ##cond##_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, \ + uint32_t op_pc) { \ + uint32_t offset = (int32_t)(int8_t)fastreadb(cs + op_pc); \ + uint32_t dest_addr = op_pc + 1 + offset; \ + int ret; \ + \ + if (!(op_32 & 0x100)) \ + dest_addr &= 0xffff; \ + ret = ropJ##cond##_common(block, ir, dest_addr, op_pc + 1); \ + \ + codegen_mark_code_present(block, cs + op_pc, 1); \ + return ret ? dest_addr : (op_pc + 1); \ + } \ + uint32_t ropJ##cond##_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, \ + uint32_t op_pc) { \ + uint32_t offset = (int32_t)(int16_t)fastreadw(cs + op_pc); \ + uint32_t dest_addr = (op_pc + 2 + offset) & 0xffff; \ + int ret; \ + \ + ret = ropJ##cond##_common(block, ir, dest_addr, op_pc + 2); \ + \ + codegen_mark_code_present(block, cs + op_pc, 2); \ + return ret ? dest_addr : (op_pc + 2); \ + } \ + uint32_t ropJ##cond##_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, \ + uint32_t op_pc) { \ + uint32_t offset = fastreadl(cs + op_pc); \ + uint32_t dest_addr = op_pc + 4 + offset; \ + int ret; \ + \ + ret = ropJ##cond##_common(block, ir, dest_addr, op_pc + 4); \ + \ + codegen_mark_code_present(block, cs + op_pc, 4); \ + return ret ? dest_addr : (op_pc + 4); \ + } -ropJ(O) -ropJ(NO) -ropJ(B) -ropJ(NB) -ropJ(E) -ropJ(NE) -ropJ(BE) -ropJ(NBE) -ropJ(S) -ropJ(NS) -ropJ(P) -ropJ(NP) -ropJ(L) -ropJ(NL) -ropJ(LE) -ropJ(NLE) +ropJ(O) ropJ(NO) ropJ(B) ropJ(NB) ropJ(E) ropJ(NE) ropJ(BE) ropJ(NBE) ropJ(S) ropJ(NS) ropJ(P) ropJ(NP) ropJ(L) ropJ(NL) ropJ(LE) + ropJ(NLE) -uint32_t ropJCXZ(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint32_t offset = (int32_t)(int8_t)fastreadb(cs + op_pc); - uint32_t dest_addr = op_pc + 1 + offset; - int jump_uop; + uint32_t + ropJCXZ(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { + uint32_t offset = (int32_t)(int8_t)fastreadb(cs + op_pc); + uint32_t dest_addr = op_pc + 1 + offset; + int jump_uop; - if (!(op_32 & 0x100)) - dest_addr &= 0xffff; + if (!(op_32 & 0x100)) + dest_addr &= 0xffff; - if (op_32 & 0x200) - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_ECX, 0); - else - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_CX, 0); - uop_MOV_IMM(ir, IREG_pc, dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); + if (op_32 & 0x200) + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_ECX, 0); + else + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_CX, 0); + uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); - codegen_mark_code_present(block, cs + op_pc, 1); - return op_pc + 1; + codegen_mark_code_present(block, cs + op_pc, 1); + return op_pc + 1; } uint32_t ropLOOP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint32_t offset = (int32_t)(int8_t)fastreadb(cs + op_pc); - uint32_t dest_addr = op_pc + 1 + offset; - uint32_t ret_addr; - int jump_uop; + uint32_t offset = (int32_t)(int8_t)fastreadb(cs + op_pc); + uint32_t dest_addr = op_pc + 1 + offset; + uint32_t ret_addr; + int jump_uop; - if (!(op_32 & 0x100)) - dest_addr &= 0xffff; + if (!(op_32 & 0x100)) + dest_addr &= 0xffff; - if (((op_32 & 0x200) ? ECX : CX) != 1 && codegen_can_unroll(block, ir, op_pc + 1, dest_addr)) { - if (op_32 & 0x200) { - uop_SUB_IMM(ir, IREG_ECX, IREG_ECX, 1); - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_ECX, 0); - } else { - uop_SUB_IMM(ir, IREG_CX, IREG_CX, 1); - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_CX, 0); - } - uop_MOV_IMM(ir, IREG_pc, op_pc + 1); - ret_addr = dest_addr; - CPU_BLOCK_END(); - } else { - if (op_32 & 0x200) { - uop_SUB_IMM(ir, IREG_ECX, IREG_ECX, 1); - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_ECX, 0); - } else { - uop_SUB_IMM(ir, IREG_CX, IREG_CX, 1); - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_CX, 0); - } - uop_MOV_IMM(ir, IREG_pc, dest_addr); - ret_addr = op_pc + 1; - } - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); + if (((op_32 & 0x200) ? ECX : CX) != 1 && codegen_can_unroll(block, ir, op_pc + 1, dest_addr)) { + if (op_32 & 0x200) { + uop_SUB_IMM(ir, IREG_ECX, IREG_ECX, 1); + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_ECX, 0); + } else { + uop_SUB_IMM(ir, IREG_CX, IREG_CX, 1); + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_CX, 0); + } + uop_MOV_IMM(ir, IREG_pc, op_pc + 1); + ret_addr = dest_addr; + CPU_BLOCK_END(); + } else { + if (op_32 & 0x200) { + uop_SUB_IMM(ir, IREG_ECX, IREG_ECX, 1); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_ECX, 0); + } else { + uop_SUB_IMM(ir, IREG_CX, IREG_CX, 1); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_CX, 0); + } + uop_MOV_IMM(ir, IREG_pc, dest_addr); + ret_addr = op_pc + 1; + } + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); - codegen_mark_code_present(block, cs + op_pc, 1); - return ret_addr; + codegen_mark_code_present(block, cs + op_pc, 1); + return ret_addr; } uint32_t ropLOOPE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint32_t offset = (int32_t)(int8_t)fastreadb(cs + op_pc); - uint32_t dest_addr = op_pc + 1 + offset; - int jump_uop, jump_uop2; + uint32_t offset = (int32_t)(int8_t)fastreadb(cs + op_pc); + uint32_t dest_addr = op_pc + 1 + offset; + int jump_uop, jump_uop2; - if (!(op_32 & 0x100)) - dest_addr &= 0xffff; + if (!(op_32 & 0x100)) + dest_addr &= 0xffff; - if (op_32 & 0x200) { - uop_SUB_IMM(ir, IREG_ECX, IREG_ECX, 1); - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_ECX, 0); - } else { - uop_SUB_IMM(ir, IREG_CX, IREG_CX, 1); - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_CX, 0); - } - if (!codegen_flags_changed || !flags_res_valid()) { - uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); - jump_uop2 = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); - } else { - jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_flags_res, 0); - } - uop_MOV_IMM(ir, IREG_pc, dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_NOP_BARRIER(ir); - uop_set_jump_dest(ir, jump_uop); - uop_set_jump_dest(ir, jump_uop2); + if (op_32 & 0x200) { + uop_SUB_IMM(ir, IREG_ECX, IREG_ECX, 1); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_ECX, 0); + } else { + uop_SUB_IMM(ir, IREG_CX, IREG_CX, 1); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_CX, 0); + } + if (!codegen_flags_changed || !flags_res_valid()) { + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop2 = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); + } else { + jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_flags_res, 0); + } + uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_NOP_BARRIER(ir); + uop_set_jump_dest(ir, jump_uop); + uop_set_jump_dest(ir, jump_uop2); - codegen_mark_code_present(block, cs + op_pc, 1); - return op_pc + 1; + codegen_mark_code_present(block, cs + op_pc, 1); + return op_pc + 1; } uint32_t ropLOOPNE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint32_t offset = (int32_t)(int8_t)fastreadb(cs + op_pc); - uint32_t dest_addr = op_pc + 1 + offset; - int jump_uop, jump_uop2; + uint32_t offset = (int32_t)(int8_t)fastreadb(cs + op_pc); + uint32_t dest_addr = op_pc + 1 + offset; + int jump_uop, jump_uop2; - if (!(op_32 & 0x100)) - dest_addr &= 0xffff; + if (!(op_32 & 0x100)) + dest_addr &= 0xffff; - if (op_32 & 0x200) { - uop_SUB_IMM(ir, IREG_ECX, IREG_ECX, 1); - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_ECX, 0); - } else { - uop_SUB_IMM(ir, IREG_CX, IREG_CX, 1); - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_CX, 0); - } - if (!codegen_flags_changed || !flags_res_valid()) { - uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); - jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - } else { - jump_uop2 = uop_CMP_IMM_JZ_DEST(ir, IREG_flags_res, 0); - } - uop_MOV_IMM(ir, IREG_pc, dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_NOP_BARRIER(ir); - uop_set_jump_dest(ir, jump_uop); - uop_set_jump_dest(ir, jump_uop2); + if (op_32 & 0x200) { + uop_SUB_IMM(ir, IREG_ECX, IREG_ECX, 1); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_ECX, 0); + } else { + uop_SUB_IMM(ir, IREG_CX, IREG_CX, 1); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_CX, 0); + } + if (!codegen_flags_changed || !flags_res_valid()) { + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + } else { + jump_uop2 = uop_CMP_IMM_JZ_DEST(ir, IREG_flags_res, 0); + } + uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_NOP_BARRIER(ir); + uop_set_jump_dest(ir, jump_uop); + uop_set_jump_dest(ir, jump_uop2); - codegen_mark_code_present(block, cs + op_pc, 1); - return op_pc + 1; + codegen_mark_code_present(block, cs + op_pc, 1); + return op_pc + 1; } diff --git a/src/codegen/codegen_ops_fpu_arith.c b/src/codegen/codegen_ops_fpu_arith.c index 6b79c292..f2c94832 100644 --- a/src/codegen/codegen_ops_fpu_arith.c +++ b/src/codegen/codegen_ops_fpu_arith.c @@ -12,532 +12,531 @@ #include "codegen_ops_helpers.h" uint32_t ropFADD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = fetchdat & 7; + int src_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FADD(ir, IREG_ST(0), IREG_ST(0), IREG_ST(src_reg)); - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); + uop_FP_ENTER(ir); + uop_FADD(ir, IREG_ST(0), IREG_ST(0), IREG_ST(src_reg)); + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); - return op_pc; + return op_pc; } uint32_t ropFADDr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = fetchdat & 7; + int dest_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FADD(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); - uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); + uop_FP_ENTER(ir); + uop_FADD(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); - return op_pc; + return op_pc; } uint32_t ropFADDP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = fetchdat & 7; + int dest_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FADD(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); - uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); - fpu_POP(block, ir); + uop_FP_ENTER(ir); + uop_FADD(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); + fpu_POP(block, ir); - return op_pc; + return op_pc; } uint32_t ropFCOM(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = fetchdat & 7; + int src_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(src_reg)); - uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); - uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); + uop_FP_ENTER(ir); + uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(src_reg)); + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); + uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); - return op_pc; + return op_pc; } uint32_t ropFCOMP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = fetchdat & 7; + int src_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(src_reg)); - uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); - uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); - fpu_POP(block, ir); + uop_FP_ENTER(ir); + uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(src_reg)); + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); + uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); + fpu_POP(block, ir); - return op_pc; + return op_pc; } uint32_t ropFCOMPP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_FP_ENTER(ir); - uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(1)); - uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); - uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); - fpu_POP2(block, ir); + uop_FP_ENTER(ir); + uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(1)); + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); + uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); + fpu_POP2(block, ir); - return op_pc; + return op_pc; } uint32_t ropFDIV(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = fetchdat & 7; + int src_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FDIV(ir, IREG_ST(0), IREG_ST(0), IREG_ST(src_reg)); - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); + uop_FP_ENTER(ir); + uop_FDIV(ir, IREG_ST(0), IREG_ST(0), IREG_ST(src_reg)); + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); - return op_pc; + return op_pc; } uint32_t ropFDIVR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = fetchdat & 7; + int src_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FDIV(ir, IREG_ST(0), IREG_ST(src_reg), IREG_ST(0)); - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); + uop_FP_ENTER(ir); + uop_FDIV(ir, IREG_ST(0), IREG_ST(src_reg), IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); - return op_pc; + return op_pc; } uint32_t ropFDIVr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = fetchdat & 7; + int dest_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FDIV(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); - uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); + uop_FP_ENTER(ir); + uop_FDIV(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); - return op_pc; + return op_pc; } uint32_t ropFDIVRr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = fetchdat & 7; + int dest_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FDIV(ir, IREG_ST(dest_reg), IREG_ST(0), IREG_ST(dest_reg)); - uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); + uop_FP_ENTER(ir); + uop_FDIV(ir, IREG_ST(dest_reg), IREG_ST(0), IREG_ST(dest_reg)); + uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); - return op_pc; + return op_pc; } uint32_t ropFDIVP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = fetchdat & 7; + int dest_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FDIV(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); - uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); - fpu_POP(block, ir); + uop_FP_ENTER(ir); + uop_FDIV(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); + fpu_POP(block, ir); - return op_pc; + return op_pc; } uint32_t ropFDIVRP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = fetchdat & 7; + int dest_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FDIV(ir, IREG_ST(dest_reg), IREG_ST(0), IREG_ST(dest_reg)); - uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); - fpu_POP(block, ir); + uop_FP_ENTER(ir); + uop_FDIV(ir, IREG_ST(dest_reg), IREG_ST(0), IREG_ST(dest_reg)); + uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); + fpu_POP(block, ir); - return op_pc; + return op_pc; } uint32_t ropFMUL(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = fetchdat & 7; + int src_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FMUL(ir, IREG_ST(0), IREG_ST(0), IREG_ST(src_reg)); - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); + uop_FP_ENTER(ir); + uop_FMUL(ir, IREG_ST(0), IREG_ST(0), IREG_ST(src_reg)); + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); - return op_pc; + return op_pc; } uint32_t ropFMULr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = fetchdat & 7; + int dest_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FMUL(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); - uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); + uop_FP_ENTER(ir); + uop_FMUL(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); - return op_pc; + return op_pc; } uint32_t ropFMULP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = fetchdat & 7; + int dest_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FMUL(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); - uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); - fpu_POP(block, ir); + uop_FP_ENTER(ir); + uop_FMUL(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); + fpu_POP(block, ir); - return op_pc; + return op_pc; } uint32_t ropFSUB(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = fetchdat & 7; + int src_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FSUB(ir, IREG_ST(0), IREG_ST(0), IREG_ST(src_reg)); - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); + uop_FP_ENTER(ir); + uop_FSUB(ir, IREG_ST(0), IREG_ST(0), IREG_ST(src_reg)); + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); - return op_pc; + return op_pc; } uint32_t ropFSUBR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = fetchdat & 7; + int src_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FSUB(ir, IREG_ST(0), IREG_ST(src_reg), IREG_ST(0)); - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); + uop_FP_ENTER(ir); + uop_FSUB(ir, IREG_ST(0), IREG_ST(src_reg), IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); - return op_pc; + return op_pc; } uint32_t ropFSUBr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = fetchdat & 7; + int dest_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FSUB(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); - uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); + uop_FP_ENTER(ir); + uop_FSUB(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); - return op_pc; + return op_pc; } uint32_t ropFSUBRr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = fetchdat & 7; + int dest_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FSUB(ir, IREG_ST(dest_reg), IREG_ST(0), IREG_ST(dest_reg)); - uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); + uop_FP_ENTER(ir); + uop_FSUB(ir, IREG_ST(dest_reg), IREG_ST(0), IREG_ST(dest_reg)); + uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); - return op_pc; + return op_pc; } uint32_t ropFSUBP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = fetchdat & 7; + int dest_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FSUB(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); - uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); - fpu_POP(block, ir); + uop_FP_ENTER(ir); + uop_FSUB(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); + fpu_POP(block, ir); - return op_pc; + return op_pc; } uint32_t ropFSUBRP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = fetchdat & 7; + int dest_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FSUB(ir, IREG_ST(dest_reg), IREG_ST(0), IREG_ST(dest_reg)); - uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); - fpu_POP(block, ir); + uop_FP_ENTER(ir); + uop_FSUB(ir, IREG_ST(dest_reg), IREG_ST(0), IREG_ST(dest_reg)); + uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); + fpu_POP(block, ir); - return op_pc; + return op_pc; } uint32_t ropFUCOM(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = fetchdat & 7; + int src_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(src_reg)); - uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); - uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); + uop_FP_ENTER(ir); + uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(src_reg)); + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); + uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); - return op_pc; + return op_pc; } uint32_t ropFUCOMP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = fetchdat & 7; + int src_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(src_reg)); - uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); - uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); - fpu_POP(block, ir); + uop_FP_ENTER(ir); + uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(src_reg)); + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); + uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); + fpu_POP(block, ir); - return op_pc; + return op_pc; } uint32_t ropFUCOMPP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_FP_ENTER(ir); - uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(1)); - uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); - uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); - fpu_POP2(block, ir); + uop_FP_ENTER(ir); + uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(1)); + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); + uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); + fpu_POP2(block, ir); - return op_pc; + return op_pc; } -#define ropF_arith_mem(name, load_uop) \ -uint32_t ropFADD ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - x86seg *target_seg; \ - \ - if ((cpu_state.npxc >> 10) & 3) \ - return 0; \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_FADD(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ - \ - return op_pc+1; \ -} \ -uint32_t ropFCOM ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_FCOM(ir, IREG_temp1_W, IREG_ST(0), IREG_temp0_D); \ - uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0|C2|C3)); \ - uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp1_W); \ - \ - return op_pc+1; \ -} \ -uint32_t ropFCOMP ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_FCOM(ir, IREG_temp1_W, IREG_ST(0), IREG_temp0_D); \ - uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0|C2|C3)); \ - uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp1_W); \ - fpu_POP(block, ir); \ - \ - return op_pc+1; \ -} \ -uint32_t ropFDIV ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_FDIV(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ - \ - return op_pc+1; \ -} \ -uint32_t ropFDIVR ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_FDIV(ir, IREG_ST(0), IREG_temp0_D, IREG_ST(0)); \ - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ - \ - return op_pc+1; \ -} \ -uint32_t ropFMUL ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_FMUL(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ - \ - return op_pc+1; \ -} \ -uint32_t ropFSUB ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_FSUB(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ - \ - return op_pc+1; \ -} \ -uint32_t ropFSUBR ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_FSUB(ir, IREG_ST(0), IREG_temp0_D, IREG_ST(0)); \ - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ - \ - return op_pc+1; \ -} +#define ropF_arith_mem(name, load_uop) \ + uint32_t ropFADD##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, \ + uint32_t op_pc) { \ + x86seg *target_seg; \ + \ + if ((cpu_state.npxc >> 10) & 3) \ + return 0; \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_FADD(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc + 1; \ + } \ + uint32_t ropFCOM##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, \ + uint32_t op_pc) { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_FCOM(ir, IREG_temp1_W, IREG_ST(0), IREG_temp0_D); \ + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); \ + uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp1_W); \ + \ + return op_pc + 1; \ + } \ + uint32_t ropFCOMP##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, \ + uint32_t op_pc) { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_FCOM(ir, IREG_temp1_W, IREG_ST(0), IREG_temp0_D); \ + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); \ + uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp1_W); \ + fpu_POP(block, ir); \ + \ + return op_pc + 1; \ + } \ + uint32_t ropFDIV##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, \ + uint32_t op_pc) { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_FDIV(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc + 1; \ + } \ + uint32_t ropFDIVR##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, \ + uint32_t op_pc) { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_FDIV(ir, IREG_ST(0), IREG_temp0_D, IREG_ST(0)); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc + 1; \ + } \ + uint32_t ropFMUL##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, \ + uint32_t op_pc) { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_FMUL(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc + 1; \ + } \ + uint32_t ropFSUB##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, \ + uint32_t op_pc) { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_FSUB(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc + 1; \ + } \ + uint32_t ropFSUBR##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, \ + uint32_t op_pc) { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_FSUB(ir, IREG_ST(0), IREG_temp0_D, IREG_ST(0)); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc + 1; \ + } -ropF_arith_mem(s, uop_MEM_LOAD_SINGLE) -ropF_arith_mem(d, uop_MEM_LOAD_DOUBLE) +ropF_arith_mem(s, uop_MEM_LOAD_SINGLE) ropF_arith_mem(d, uop_MEM_LOAD_DOUBLE) -#define ropFI_arith_mem(name, temp_reg) \ -uint32_t ropFIADD ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ - uop_FADD(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ - \ - return op_pc+1; \ -} \ -uint32_t ropFICOM ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ - uop_FCOM(ir, IREG_temp1_W, IREG_ST(0), IREG_temp0_D); \ - uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0|C2|C3)); \ - uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp1_W); \ - \ - return op_pc+1; \ -} \ -uint32_t ropFICOMP ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ - uop_FCOM(ir, IREG_temp1_W, IREG_ST(0), IREG_temp0_D); \ - uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0|C2|C3)); \ - uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp1_W); \ - fpu_POP(block, ir); \ - \ - return op_pc+1; \ -} \ -uint32_t ropFIDIV ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ - uop_FDIV(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ - \ - return op_pc+1; \ -} \ -uint32_t ropFIDIVR ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)\ -{ \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ - uop_FDIV(ir, IREG_ST(0), IREG_temp0_D, IREG_ST(0)); \ - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ - \ - return op_pc+1; \ -} \ -uint32_t ropFIMUL ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ - uop_FMUL(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ - \ - return op_pc+1; \ -} \ -uint32_t ropFISUB ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ - uop_FSUB(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ - \ - return op_pc+1; \ -} \ -uint32_t ropFISUBR ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)\ -{ \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ - uop_FSUB(ir, IREG_ST(0), IREG_temp0_D, IREG_ST(0)); \ - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ - \ - return op_pc+1; \ -} +#define ropFI_arith_mem(name, temp_reg) \ + uint32_t ropFIADD##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, \ + uint32_t op_pc) { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ + uop_FADD(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc + 1; \ + } \ + uint32_t ropFICOM##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, \ + uint32_t op_pc) { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ + uop_FCOM(ir, IREG_temp1_W, IREG_ST(0), IREG_temp0_D); \ + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); \ + uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp1_W); \ + \ + return op_pc + 1; \ + } \ + uint32_t ropFICOMP##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, \ + uint32_t op_pc) { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ + uop_FCOM(ir, IREG_temp1_W, IREG_ST(0), IREG_temp0_D); \ + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); \ + uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp1_W); \ + fpu_POP(block, ir); \ + \ + return op_pc + 1; \ + } \ + uint32_t ropFIDIV##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, \ + uint32_t op_pc) { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ + uop_FDIV(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc + 1; \ + } \ + uint32_t ropFIDIVR##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, \ + uint32_t op_pc) { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ + uop_FDIV(ir, IREG_ST(0), IREG_temp0_D, IREG_ST(0)); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc + 1; \ + } \ + uint32_t ropFIMUL##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, \ + uint32_t op_pc) { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ + uop_FMUL(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc + 1; \ + } \ + uint32_t ropFISUB##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, \ + uint32_t op_pc) { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ + uop_FSUB(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc + 1; \ + } \ + uint32_t ropFISUBR##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, \ + uint32_t op_pc) { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ + uop_FSUB(ir, IREG_ST(0), IREG_temp0_D, IREG_ST(0)); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc + 1; \ + } -ropFI_arith_mem(l, IREG_temp0) -ropFI_arith_mem(w, IREG_temp0_W) + ropFI_arith_mem(l, IREG_temp0) ropFI_arith_mem(w, IREG_temp0_W) -uint32_t ropFABS(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_FP_ENTER(ir); - uop_FABS(ir, IREG_ST(0), IREG_ST(0)); - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); + uint32_t + ropFABS(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { + uop_FP_ENTER(ir); + uop_FABS(ir, IREG_ST(0), IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); - return op_pc; + return op_pc; } uint32_t ropFCHS(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_FP_ENTER(ir); - uop_FCHS(ir, IREG_ST(0), IREG_ST(0)); - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); + uop_FP_ENTER(ir); + uop_FCHS(ir, IREG_ST(0), IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); - return op_pc; + return op_pc; } uint32_t ropFSQRT(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_FP_ENTER(ir); - uop_FSQRT(ir, IREG_ST(0), IREG_ST(0)); - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); + uop_FP_ENTER(ir); + uop_FSQRT(ir, IREG_ST(0), IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); - return op_pc; + return op_pc; } uint32_t ropFTST(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_FP_ENTER(ir); - uop_FTST(ir, IREG_temp0_W, IREG_ST(0)); - uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); - uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); + uop_FP_ENTER(ir); + uop_FTST(ir, IREG_temp0_W, IREG_ST(0)); + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); + uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); - return op_pc; + return op_pc; } diff --git a/src/codegen/codegen_ops_fpu_constant.c b/src/codegen/codegen_ops_fpu_constant.c index e9eed69b..05c14342 100644 --- a/src/codegen/codegen_ops_fpu_constant.c +++ b/src/codegen/codegen_ops_fpu_constant.c @@ -12,20 +12,20 @@ #include "codegen_ops_helpers.h" uint32_t ropFLD1(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_FP_ENTER(ir); - uop_MOV_IMM(ir, IREG_temp0, 1); - uop_MOV_DOUBLE_INT(ir, IREG_ST(-1), IREG_temp0); - uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID); - fpu_PUSH(block, ir); + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_temp0, 1); + uop_MOV_DOUBLE_INT(ir, IREG_ST(-1), IREG_temp0); + uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID); + fpu_PUSH(block, ir); - return op_pc; + return op_pc; } uint32_t ropFLDZ(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_FP_ENTER(ir); - uop_MOV_IMM(ir, IREG_temp0, 0); - uop_MOV_DOUBLE_INT(ir, IREG_ST(-1), IREG_temp0); - uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID); - fpu_PUSH(block, ir); + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_temp0, 0); + uop_MOV_DOUBLE_INT(ir, IREG_ST(-1), IREG_temp0); + uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID); + fpu_PUSH(block, ir); - return op_pc; + return op_pc; } diff --git a/src/codegen/codegen_ops_fpu_loadstore.c b/src/codegen/codegen_ops_fpu_loadstore.c index 469ba199..6ff63bd2 100644 --- a/src/codegen/codegen_ops_fpu_loadstore.c +++ b/src/codegen/codegen_ops_fpu_loadstore.c @@ -12,205 +12,205 @@ #include "codegen_ops_helpers.h" uint32_t ropFLDs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg; + x86seg *target_seg; - uop_FP_ENTER(ir); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - op_pc--; - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_SINGLE(ir, IREG_ST(-1), ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID); - fpu_PUSH(block, ir); + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_SINGLE(ir, IREG_ST(-1), ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID); + fpu_PUSH(block, ir); - return op_pc + 1; + return op_pc + 1; } uint32_t ropFLDd(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg; + x86seg *target_seg; - uop_FP_ENTER(ir); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - op_pc--; - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_DOUBLE(ir, IREG_ST(-1), ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID); - fpu_PUSH(block, ir); + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_DOUBLE(ir, IREG_ST(-1), ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID); + fpu_PUSH(block, ir); - return op_pc + 1; + return op_pc + 1; } uint32_t ropFSTs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg; + x86seg *target_seg; - uop_FP_ENTER(ir); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - op_pc--; - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_STORE_SINGLE(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_ST(0)); + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_STORE_SINGLE(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_ST(0)); - return op_pc + 1; + return op_pc + 1; } uint32_t ropFSTPs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg; + x86seg *target_seg; - uop_FP_ENTER(ir); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - op_pc--; - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_STORE_SINGLE(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_ST(0)); - uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); - fpu_POP(block, ir); + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_STORE_SINGLE(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); + fpu_POP(block, ir); - return op_pc + 1; + return op_pc + 1; } uint32_t ropFSTd(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg; + x86seg *target_seg; - uop_FP_ENTER(ir); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - op_pc--; - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 7); - uop_MEM_STORE_DOUBLE(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_ST(0)); + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 7); + uop_MEM_STORE_DOUBLE(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_ST(0)); - return op_pc + 1; + return op_pc + 1; } uint32_t ropFSTPd(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg; + x86seg *target_seg; - uop_FP_ENTER(ir); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - op_pc--; - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 7); - uop_MEM_STORE_DOUBLE(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_ST(0)); - uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); - fpu_POP(block, ir); + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 7); + uop_MEM_STORE_DOUBLE(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); + fpu_POP(block, ir); - return op_pc + 1; + return op_pc + 1; } uint32_t ropFILDw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg; + x86seg *target_seg; - uop_FP_ENTER(ir); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - op_pc--; - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOV_DOUBLE_INT(ir, IREG_ST(-1), IREG_temp0_W); - uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID); - fpu_PUSH(block, ir); + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV_DOUBLE_INT(ir, IREG_ST(-1), IREG_temp0_W); + uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID); + fpu_PUSH(block, ir); - return op_pc + 1; + return op_pc + 1; } uint32_t ropFILDl(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg; + x86seg *target_seg; - uop_FP_ENTER(ir); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - op_pc--; - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOV_DOUBLE_INT(ir, IREG_ST(-1), IREG_temp0); - uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID); - fpu_PUSH(block, ir); + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV_DOUBLE_INT(ir, IREG_ST(-1), IREG_temp0); + uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID); + fpu_PUSH(block, ir); - return op_pc + 1; + return op_pc + 1; } uint32_t ropFILDq(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg; + x86seg *target_seg; - uop_FP_ENTER(ir); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - op_pc--; - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_ST_i64(-1), ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOV_DOUBLE_INT(ir, IREG_ST(-1), IREG_ST_i64(-1)); - uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID | TAG_UINT64); - fpu_PUSH(block, ir); + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_ST_i64(-1), ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV_DOUBLE_INT(ir, IREG_ST(-1), IREG_ST_i64(-1)); + uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID | TAG_UINT64); + fpu_PUSH(block, ir); - return op_pc + 1; + return op_pc + 1; } uint32_t ropFISTw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg; + x86seg *target_seg; - uop_FP_ENTER(ir); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - op_pc--; - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MOV_INT_DOUBLE(ir, IREG_temp0_W, IREG_ST(0)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MOV_INT_DOUBLE(ir, IREG_temp0_W, IREG_ST(0)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); - return op_pc + 1; + return op_pc + 1; } uint32_t ropFISTPw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg; + x86seg *target_seg; - uop_FP_ENTER(ir); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - op_pc--; - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MOV_INT_DOUBLE(ir, IREG_temp0_W, IREG_ST(0)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); - fpu_POP(block, ir); + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MOV_INT_DOUBLE(ir, IREG_temp0_W, IREG_ST(0)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); + fpu_POP(block, ir); - return op_pc + 1; + return op_pc + 1; } uint32_t ropFISTl(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg; + x86seg *target_seg; - uop_FP_ENTER(ir); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - op_pc--; - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MOV_INT_DOUBLE(ir, IREG_temp0, IREG_ST(0)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MOV_INT_DOUBLE(ir, IREG_temp0, IREG_ST(0)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); - return op_pc + 1; + return op_pc + 1; } uint32_t ropFISTPl(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg; + x86seg *target_seg; - uop_FP_ENTER(ir); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - op_pc--; - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MOV_INT_DOUBLE(ir, IREG_temp0, IREG_ST(0)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); - fpu_POP(block, ir); + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MOV_INT_DOUBLE(ir, IREG_temp0, IREG_ST(0)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); + fpu_POP(block, ir); - return op_pc + 1; + return op_pc + 1; } uint32_t ropFISTPq(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg; + x86seg *target_seg; - uop_FP_ENTER(ir); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - op_pc--; - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MOV_INT_DOUBLE_64(ir, IREG_temp0_Q, IREG_ST(0), IREG_ST_i64(0), IREG_tag(0)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_Q); - uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); - fpu_POP(block, ir); + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MOV_INT_DOUBLE_64(ir, IREG_temp0_Q, IREG_ST(0), IREG_ST_i64(0), IREG_tag(0)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_Q); + uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); + fpu_POP(block, ir); - return op_pc + 1; + return op_pc + 1; } diff --git a/src/codegen/codegen_ops_fpu_misc.c b/src/codegen/codegen_ops_fpu_misc.c index 7c11db02..6605002f 100644 --- a/src/codegen/codegen_ops_fpu_misc.c +++ b/src/codegen/codegen_ops_fpu_misc.c @@ -12,92 +12,92 @@ #include "codegen_ops_helpers.h" uint32_t ropFFREE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = fetchdat & 7; + int dest_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_MOV(ir, IREG_tag(dest_reg), TAG_EMPTY); + uop_FP_ENTER(ir); + uop_MOV(ir, IREG_tag(dest_reg), TAG_EMPTY); - return op_pc; + return op_pc; } uint32_t ropFLD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = fetchdat & 7; + int src_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_MOV(ir, IREG_ST(-1), IREG_ST(src_reg)); - uop_MOV(ir, IREG_ST_i64(-1), IREG_ST_i64(src_reg)); - uop_MOV(ir, IREG_tag(-1), IREG_tag(src_reg)); - fpu_PUSH(block, ir); + uop_FP_ENTER(ir); + uop_MOV(ir, IREG_ST(-1), IREG_ST(src_reg)); + uop_MOV(ir, IREG_ST_i64(-1), IREG_ST_i64(src_reg)); + uop_MOV(ir, IREG_tag(-1), IREG_tag(src_reg)); + fpu_PUSH(block, ir); - return op_pc; + return op_pc; } uint32_t ropFST(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = fetchdat & 7; + int dest_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_MOV(ir, IREG_ST(dest_reg), IREG_ST(0)); - uop_MOV(ir, IREG_ST_i64(dest_reg), IREG_ST_i64(0)); - uop_MOV(ir, IREG_tag(dest_reg), IREG_tag(0)); + uop_FP_ENTER(ir); + uop_MOV(ir, IREG_ST(dest_reg), IREG_ST(0)); + uop_MOV(ir, IREG_ST_i64(dest_reg), IREG_ST_i64(0)); + uop_MOV(ir, IREG_tag(dest_reg), IREG_tag(0)); - return op_pc; + return op_pc; } uint32_t ropFSTP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = fetchdat & 7; + int dest_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_MOV(ir, IREG_ST(dest_reg), IREG_ST(0)); - uop_MOV(ir, IREG_ST_i64(dest_reg), IREG_ST_i64(0)); - uop_MOV(ir, IREG_tag(dest_reg), IREG_tag(0)); - fpu_POP(block, ir); + uop_FP_ENTER(ir); + uop_MOV(ir, IREG_ST(dest_reg), IREG_ST(0)); + uop_MOV(ir, IREG_ST_i64(dest_reg), IREG_ST_i64(0)); + uop_MOV(ir, IREG_tag(dest_reg), IREG_tag(0)); + fpu_POP(block, ir); - return op_pc; + return op_pc; } uint32_t ropFSTCW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg; + x86seg *target_seg; - uop_FP_ENTER(ir); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - op_pc--; - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_NPXC); + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_NPXC); - return op_pc + 1; + return op_pc + 1; } uint32_t ropFSTSW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg; + x86seg *target_seg; - uop_FP_ENTER(ir); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - op_pc--; - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_NPXS); + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_NPXS); - return op_pc + 1; + return op_pc + 1; } uint32_t ropFSTSW_AX(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_FP_ENTER(ir); - uop_MOV(ir, IREG_AX, IREG_NPXS); + uop_FP_ENTER(ir); + uop_MOV(ir, IREG_AX, IREG_NPXS); - return op_pc; + return op_pc; } uint32_t ropFXCH(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = fetchdat & 7; + int dest_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_MOV(ir, IREG_temp0_D, IREG_ST(0)); - uop_MOV(ir, IREG_temp1_Q, IREG_ST_i64(0)); - uop_MOV(ir, IREG_temp2, IREG_tag(0)); - uop_MOV(ir, IREG_ST(0), IREG_ST(dest_reg)); - uop_MOV(ir, IREG_ST_i64(0), IREG_ST_i64(dest_reg)); - uop_MOV(ir, IREG_tag(0), IREG_tag(dest_reg)); - uop_MOV(ir, IREG_ST(dest_reg), IREG_temp0_D); - uop_MOV(ir, IREG_ST_i64(dest_reg), IREG_temp1_Q); - uop_MOV(ir, IREG_tag(dest_reg), IREG_temp2); + uop_FP_ENTER(ir); + uop_MOV(ir, IREG_temp0_D, IREG_ST(0)); + uop_MOV(ir, IREG_temp1_Q, IREG_ST_i64(0)); + uop_MOV(ir, IREG_temp2, IREG_tag(0)); + uop_MOV(ir, IREG_ST(0), IREG_ST(dest_reg)); + uop_MOV(ir, IREG_ST_i64(0), IREG_ST_i64(dest_reg)); + uop_MOV(ir, IREG_tag(0), IREG_tag(dest_reg)); + uop_MOV(ir, IREG_ST(dest_reg), IREG_temp0_D); + uop_MOV(ir, IREG_ST_i64(dest_reg), IREG_temp1_Q); + uop_MOV(ir, IREG_tag(dest_reg), IREG_temp2); - return op_pc; + return op_pc; } diff --git a/src/codegen/codegen_ops_helpers.c b/src/codegen/codegen_ops_helpers.c index af8d63ce..5e8d4eb7 100644 --- a/src/codegen/codegen_ops_helpers.c +++ b/src/codegen/codegen_ops_helpers.c @@ -8,58 +8,60 @@ #include "codegen_ops_helpers.h" void LOAD_IMMEDIATE_FROM_RAM_16_unaligned(codeblock_t *block, ir_data_t *ir, int dest_reg, uint32_t addr) { - /*Word access that crosses two pages. Perform reads from both pages, shift and combine*/ - uop_MOVZX_REG_PTR_8(ir, IREG_temp3_W, get_ram_ptr(addr)); - uop_MOVZX_REG_PTR_8(ir, dest_reg, get_ram_ptr(addr + 1)); - uop_SHL_IMM(ir, IREG_temp3_W, IREG_temp3_W, 8); - uop_OR(ir, dest_reg, dest_reg, IREG_temp3_W); + /*Word access that crosses two pages. Perform reads from both pages, shift and combine*/ + uop_MOVZX_REG_PTR_8(ir, IREG_temp3_W, get_ram_ptr(addr)); + uop_MOVZX_REG_PTR_8(ir, dest_reg, get_ram_ptr(addr + 1)); + uop_SHL_IMM(ir, IREG_temp3_W, IREG_temp3_W, 8); + uop_OR(ir, dest_reg, dest_reg, IREG_temp3_W); } void LOAD_IMMEDIATE_FROM_RAM_32_unaligned(codeblock_t *block, ir_data_t *ir, int dest_reg, uint32_t addr) { - /*Dword access that crosses two pages. Perform reads from both pages, shift and combine*/ - uop_MOV_REG_PTR(ir, dest_reg, get_ram_ptr(addr & ~3)); - uop_MOV_REG_PTR(ir, IREG_temp3, get_ram_ptr((addr + 4) & ~3)); - uop_SHR_IMM(ir, dest_reg, dest_reg, (addr & 3) * 8); - uop_SHL_IMM(ir, IREG_temp3, IREG_temp3, (4 - (addr & 3)) * 8); - uop_OR(ir, dest_reg, dest_reg, IREG_temp3); + /*Dword access that crosses two pages. Perform reads from both pages, shift and combine*/ + uop_MOV_REG_PTR(ir, dest_reg, get_ram_ptr(addr & ~3)); + uop_MOV_REG_PTR(ir, IREG_temp3, get_ram_ptr((addr + 4) & ~3)); + uop_SHR_IMM(ir, dest_reg, dest_reg, (addr & 3) * 8); + uop_SHL_IMM(ir, IREG_temp3, IREG_temp3, (4 - (addr & 3)) * 8); + uop_OR(ir, dest_reg, dest_reg, IREG_temp3); } #define UNROLL_MAX_REG_REFERENCES 200 #define UNROLL_MAX_UOPS 1000 #define UNROLL_MAX_COUNT 10 int codegen_can_unroll_full(codeblock_t *block, ir_data_t *ir, uint32_t next_pc, uint32_t dest_addr) { - int start; - int max_unroll; - int first_instruction; - int TOP = -1; + int start; + int max_unroll; + int first_instruction; + int TOP = -1; - /*Check that dest instruction was actually compiled into block*/ - start = codegen_get_instruction_uop(block, dest_addr, &first_instruction, &TOP); + /*Check that dest instruction was actually compiled into block*/ + start = codegen_get_instruction_uop(block, dest_addr, &first_instruction, &TOP); - /*Couldn't find any uOPs corresponding to the destination instruction*/ - if (start == -1) { - /*Is instruction jumping to itself?*/ - if (dest_addr != cpu_state.oldpc) { -// pclog("Couldn't find start. start_pc=%08x end_pc=%08x dest_pc=%08x wr_pos=%i loop_size=%i\n", block->pc-cs, next_pc, dest_addr, ir->wr_pos, ir->wr_pos-start); - return 0; - } else { - start = ir->wr_pos; - TOP = cpu_state.TOP; - } - } + /*Couldn't find any uOPs corresponding to the destination instruction*/ + if (start == -1) { + /*Is instruction jumping to itself?*/ + if (dest_addr != cpu_state.oldpc) { + // pclog("Couldn't find start. start_pc=%08x end_pc=%08x dest_pc=%08x wr_pos=%i + // loop_size=%i\n", block->pc-cs, next_pc, dest_addr, ir->wr_pos, + // ir->wr_pos-start); + return 0; + } else { + start = ir->wr_pos; + TOP = cpu_state.TOP; + } + } - if (TOP != cpu_state.TOP) - return 0; + if (TOP != cpu_state.TOP) + return 0; - max_unroll = UNROLL_MAX_UOPS / ((ir->wr_pos - start) + 6); - if (max_unroll > (UNROLL_MAX_REG_REFERENCES / max_version_refcount)) - max_unroll = (UNROLL_MAX_REG_REFERENCES / max_version_refcount); - if (max_unroll > UNROLL_MAX_COUNT) - max_unroll = UNROLL_MAX_COUNT; - if (max_unroll <= 1) - return 0; + max_unroll = UNROLL_MAX_UOPS / ((ir->wr_pos - start) + 6); + if (max_unroll > (UNROLL_MAX_REG_REFERENCES / max_version_refcount)) + max_unroll = (UNROLL_MAX_REG_REFERENCES / max_version_refcount); + if (max_unroll > UNROLL_MAX_COUNT) + max_unroll = UNROLL_MAX_COUNT; + if (max_unroll <= 1) + return 0; - codegen_ir_set_unroll(max_unroll, start, first_instruction); + codegen_ir_set_unroll(max_unroll, start, first_instruction); - return 1; + return 1; } diff --git a/src/codegen/codegen_ops_jump.c b/src/codegen/codegen_ops_jump.c index ffe7f3e9..ae56cac3 100644 --- a/src/codegen/codegen_ops_jump.c +++ b/src/codegen/codegen_ops_jump.c @@ -9,250 +9,250 @@ #include "codegen_ops_mov.h" uint32_t ropJMP_r8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint32_t offset = (int32_t)(int8_t)fastreadb(cs + op_pc); - uint32_t dest_addr = op_pc + 1 + offset; + uint32_t offset = (int32_t)(int8_t)fastreadb(cs + op_pc); + uint32_t dest_addr = op_pc + 1 + offset; - if (!(op_32 & 0x100)) - dest_addr &= 0xffff; + if (!(op_32 & 0x100)) + dest_addr &= 0xffff; - if (offset < 0) - codegen_can_unroll(block, ir, op_pc + 1, dest_addr); - codegen_mark_code_present(block, cs + op_pc, 1); - return dest_addr; + if (offset < 0) + codegen_can_unroll(block, ir, op_pc + 1, dest_addr); + codegen_mark_code_present(block, cs + op_pc, 1); + return dest_addr; } uint32_t ropJMP_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint32_t offset = (int32_t)(int16_t)fastreadw(cs + op_pc); - uint32_t dest_addr = op_pc + 2 + offset; + uint32_t offset = (int32_t)(int16_t)fastreadw(cs + op_pc); + uint32_t dest_addr = op_pc + 2 + offset; - dest_addr &= 0xffff; + dest_addr &= 0xffff; - if (offset < 0) - codegen_can_unroll(block, ir, op_pc + 1, dest_addr); - codegen_mark_code_present(block, cs + op_pc, 2); - return dest_addr; + if (offset < 0) + codegen_can_unroll(block, ir, op_pc + 1, dest_addr); + codegen_mark_code_present(block, cs + op_pc, 2); + return dest_addr; } uint32_t ropJMP_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint32_t offset = fastreadl(cs + op_pc); - uint32_t dest_addr = op_pc + 4 + offset; + uint32_t offset = fastreadl(cs + op_pc); + uint32_t dest_addr = op_pc + 4 + offset; - if (offset < 0) - codegen_can_unroll(block, ir, op_pc + 1, dest_addr); - codegen_mark_code_present(block, cs + op_pc, 4); - return dest_addr; + if (offset < 0) + codegen_can_unroll(block, ir, op_pc + 1, dest_addr); + codegen_mark_code_present(block, cs + op_pc, 4); + return dest_addr; } uint32_t ropJMP_far_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint16_t new_pc = fastreadw(cs + op_pc); - uint16_t new_cs = fastreadw(cs + op_pc + 2); + uint16_t new_pc = fastreadw(cs + op_pc); + uint16_t new_cs = fastreadw(cs + op_pc + 2); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - uop_MOV_IMM(ir, IREG_pc, new_pc); - uop_LOAD_FUNC_ARG_IMM(ir, 0, new_cs); - uop_LOAD_FUNC_ARG_IMM(ir, 1, op_pc + 4); - uop_CALL_FUNC(ir, loadcsjmp); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + uop_MOV_IMM(ir, IREG_pc, new_pc); + uop_LOAD_FUNC_ARG_IMM(ir, 0, new_cs); + uop_LOAD_FUNC_ARG_IMM(ir, 1, op_pc + 4); + uop_CALL_FUNC(ir, loadcsjmp); - codegen_mark_code_present(block, cs + op_pc, 4); - return -1; + codegen_mark_code_present(block, cs + op_pc, 4); + return -1; } uint32_t ropJMP_far_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint32_t new_pc = fastreadl(cs + op_pc); - uint16_t new_cs = fastreadw(cs + op_pc + 4); + uint32_t new_pc = fastreadl(cs + op_pc); + uint16_t new_cs = fastreadw(cs + op_pc + 4); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - uop_MOV_IMM(ir, IREG_pc, new_pc); - uop_LOAD_FUNC_ARG_IMM(ir, 0, new_cs); - uop_LOAD_FUNC_ARG_IMM(ir, 1, op_pc + 4); - uop_CALL_FUNC(ir, loadcsjmp); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + uop_MOV_IMM(ir, IREG_pc, new_pc); + uop_LOAD_FUNC_ARG_IMM(ir, 0, new_cs); + uop_LOAD_FUNC_ARG_IMM(ir, 1, op_pc + 4); + uop_CALL_FUNC(ir, loadcsjmp); - codegen_mark_code_present(block, cs + op_pc, 6); - return -1; + codegen_mark_code_present(block, cs + op_pc, 6); + return -1; } uint32_t ropCALL_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint32_t offset = (int32_t)(int16_t)fastreadw(cs + op_pc); - uint16_t ret_addr = op_pc + 2; - uint16_t dest_addr = ret_addr + offset; - int sp_reg; + uint32_t offset = (int32_t)(int16_t)fastreadw(cs + op_pc); + uint16_t ret_addr = op_pc + 2; + uint16_t dest_addr = ret_addr + offset; + int sp_reg; - dest_addr &= 0xffff; + dest_addr &= 0xffff; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); - uop_MEM_STORE_IMM_16(ir, IREG_SS_base, sp_reg, ret_addr); - SUB_SP(ir, 2); - uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); + uop_MEM_STORE_IMM_16(ir, IREG_SS_base, sp_reg, ret_addr); + SUB_SP(ir, 2); + uop_MOV_IMM(ir, IREG_pc, dest_addr); - codegen_mark_code_present(block, cs + op_pc, 2); - return -1; + codegen_mark_code_present(block, cs + op_pc, 2); + return -1; } uint32_t ropCALL_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint32_t offset = fastreadl(cs + op_pc); - uint32_t ret_addr = op_pc + 4; - uint32_t dest_addr = ret_addr + offset; - int sp_reg; + uint32_t offset = fastreadl(cs + op_pc); + uint32_t ret_addr = op_pc + 4; + uint32_t dest_addr = ret_addr + offset; + int sp_reg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); - uop_MEM_STORE_IMM_32(ir, IREG_SS_base, sp_reg, ret_addr); - SUB_SP(ir, 4); - uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); + uop_MEM_STORE_IMM_32(ir, IREG_SS_base, sp_reg, ret_addr); + SUB_SP(ir, 4); + uop_MOV_IMM(ir, IREG_pc, dest_addr); - codegen_mark_code_present(block, cs + op_pc, 4); - return -1; + codegen_mark_code_present(block, cs + op_pc, 4); + return -1; } uint32_t ropRET_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - if (stack32) - uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_ESP); - else { - uop_MOVZX(ir, IREG_eaaddr, IREG_SP); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr); - } - ADD_SP(ir, 2); - uop_MOVZX(ir, IREG_pc, IREG_temp0_W); + if (stack32) + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_ESP); + else { + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr); + } + ADD_SP(ir, 2); + uop_MOVZX(ir, IREG_pc, IREG_temp0_W); - return -1; + return -1; } uint32_t ropRET_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - if (stack32) - uop_MEM_LOAD_REG(ir, IREG_pc, IREG_SS_base, IREG_ESP); - else { - uop_MOVZX(ir, IREG_eaaddr, IREG_SP); - uop_MEM_LOAD_REG(ir, IREG_pc, IREG_SS_base, IREG_eaaddr); - } - ADD_SP(ir, 4); + if (stack32) + uop_MEM_LOAD_REG(ir, IREG_pc, IREG_SS_base, IREG_ESP); + else { + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); + uop_MEM_LOAD_REG(ir, IREG_pc, IREG_SS_base, IREG_eaaddr); + } + ADD_SP(ir, 4); - return -1; + return -1; } uint32_t ropRET_imm_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint16_t offset = fastreadw(cs + op_pc); + uint16_t offset = fastreadw(cs + op_pc); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - if (stack32) - uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_ESP); - else { - uop_MOVZX(ir, IREG_eaaddr, IREG_SP); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr); - } - ADD_SP(ir, 2 + offset); - uop_MOVZX(ir, IREG_pc, IREG_temp0_W); + if (stack32) + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_ESP); + else { + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr); + } + ADD_SP(ir, 2 + offset); + uop_MOVZX(ir, IREG_pc, IREG_temp0_W); - codegen_mark_code_present(block, cs + op_pc, 2); - return -1; + codegen_mark_code_present(block, cs + op_pc, 2); + return -1; } uint32_t ropRET_imm_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint16_t offset = fastreadw(cs + op_pc); + uint16_t offset = fastreadw(cs + op_pc); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - if (stack32) - uop_MEM_LOAD_REG(ir, IREG_pc, IREG_SS_base, IREG_ESP); - else { - uop_MOVZX(ir, IREG_eaaddr, IREG_SP); - uop_MEM_LOAD_REG(ir, IREG_pc, IREG_SS_base, IREG_eaaddr); - } - ADD_SP(ir, 4 + offset); + if (stack32) + uop_MEM_LOAD_REG(ir, IREG_pc, IREG_SS_base, IREG_ESP); + else { + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); + uop_MEM_LOAD_REG(ir, IREG_pc, IREG_SS_base, IREG_eaaddr); + } + ADD_SP(ir, 4 + offset); - codegen_mark_code_present(block, cs + op_pc, 2); - return -1; + codegen_mark_code_present(block, cs + op_pc, 2); + return -1; } uint32_t ropRETF_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) - return 0; + if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) + return 0; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - if (stack32) { - uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_ESP); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_ESP, 2); - } else { - uop_MOVZX(ir, IREG_eaaddr, IREG_SP); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_eaaddr, 2); - } - uop_MOVZX(ir, IREG_pc, IREG_temp0_W); - uop_LOAD_FUNC_ARG_REG(ir, 0, IREG_temp1_W); - uop_CALL_FUNC(ir, loadcs); - ADD_SP(ir, 4); + if (stack32) { + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_ESP); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_ESP, 2); + } else { + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_eaaddr, 2); + } + uop_MOVZX(ir, IREG_pc, IREG_temp0_W); + uop_LOAD_FUNC_ARG_REG(ir, 0, IREG_temp1_W); + uop_CALL_FUNC(ir, loadcs); + ADD_SP(ir, 4); - return -1; + return -1; } uint32_t ropRETF_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) - return 0; + if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) + return 0; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - if (stack32) { - uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_ESP); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_ESP, 4); - } else { - uop_MOVZX(ir, IREG_eaaddr, IREG_SP); - uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_eaaddr); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_eaaddr, 4); - } - uop_MOV(ir, IREG_pc, IREG_temp0); - uop_LOAD_FUNC_ARG_REG(ir, 0, IREG_temp1_W); - uop_CALL_FUNC(ir, loadcs); - ADD_SP(ir, 8); + if (stack32) { + uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_ESP); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_ESP, 4); + } else { + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); + uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_eaaddr); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_eaaddr, 4); + } + uop_MOV(ir, IREG_pc, IREG_temp0); + uop_LOAD_FUNC_ARG_REG(ir, 0, IREG_temp1_W); + uop_CALL_FUNC(ir, loadcs); + ADD_SP(ir, 8); - return -1; + return -1; } uint32_t ropRETF_imm_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint16_t offset; + uint16_t offset; - if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) - return 0; + if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) + return 0; - offset = fastreadw(cs + op_pc); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + offset = fastreadw(cs + op_pc); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - if (stack32) { - uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_ESP); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_ESP, 2); - } else { - uop_MOVZX(ir, IREG_eaaddr, IREG_SP); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_eaaddr, 2); - } - uop_MOVZX(ir, IREG_pc, IREG_temp0_W); - uop_LOAD_FUNC_ARG_REG(ir, 0, IREG_temp1_W); - uop_CALL_FUNC(ir, loadcs); - ADD_SP(ir, 4 + offset); + if (stack32) { + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_ESP); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_ESP, 2); + } else { + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_eaaddr, 2); + } + uop_MOVZX(ir, IREG_pc, IREG_temp0_W); + uop_LOAD_FUNC_ARG_REG(ir, 0, IREG_temp1_W); + uop_CALL_FUNC(ir, loadcs); + ADD_SP(ir, 4 + offset); - codegen_mark_code_present(block, cs + op_pc, 2); - return -1; + codegen_mark_code_present(block, cs + op_pc, 2); + return -1; } uint32_t ropRETF_imm_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint16_t offset; + uint16_t offset; - if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) - return 0; + if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) + return 0; - offset = fastreadw(cs + op_pc); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + offset = fastreadw(cs + op_pc); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - if (stack32) { - uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_ESP); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_ESP, 4); - } else { - uop_MOVZX(ir, IREG_eaaddr, IREG_SP); - uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_eaaddr); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_eaaddr, 4); - } - uop_MOV(ir, IREG_pc, IREG_temp0); - uop_LOAD_FUNC_ARG_REG(ir, 0, IREG_temp1_W); - uop_CALL_FUNC(ir, loadcs); - ADD_SP(ir, 8 + offset); + if (stack32) { + uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_ESP); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_ESP, 4); + } else { + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); + uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_eaaddr); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_eaaddr, 4); + } + uop_MOV(ir, IREG_pc, IREG_temp0); + uop_LOAD_FUNC_ARG_REG(ir, 0, IREG_temp1_W); + uop_CALL_FUNC(ir, loadcs); + ADD_SP(ir, 8 + offset); - codegen_mark_code_present(block, cs + op_pc, 2); - return -1; + codegen_mark_code_present(block, cs + op_pc, 2); + return -1; } diff --git a/src/codegen/codegen_ops_logic.c b/src/codegen/codegen_ops_logic.c index 91c56ccd..c12dab86 100644 --- a/src/codegen/codegen_ops_logic.c +++ b/src/codegen/codegen_ops_logic.c @@ -10,687 +10,687 @@ #include "codegen_ops_logic.h" uint32_t ropAND_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint8_t imm_data = fastreadb(cs + op_pc); + uint8_t imm_data = fastreadb(cs + op_pc); - uop_AND_IMM(ir, IREG_AL, IREG_AL, imm_data); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); - uop_MOVZX(ir, IREG_flags_res, IREG_AL); + uop_AND_IMM(ir, IREG_AL, IREG_AL, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_MOVZX(ir, IREG_flags_res, IREG_AL); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs + op_pc, 1); - return op_pc + 1; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 1); + return op_pc + 1; } uint32_t ropAND_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint16_t imm_data = fastreadw(cs + op_pc); + uint16_t imm_data = fastreadw(cs + op_pc); - uop_AND_IMM(ir, IREG_AX, IREG_AX, imm_data); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - uop_MOVZX(ir, IREG_flags_res, IREG_AX); + uop_AND_IMM(ir, IREG_AX, IREG_AX, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_AX); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs + op_pc, 2); - return op_pc + 2; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 2); + return op_pc + 2; } uint32_t ropAND_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - if (block->flags & CODEBLOCK_NO_IMMEDIATES) { - LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + op_pc); - uop_AND(ir, IREG_EAX, IREG_EAX, IREG_temp0); - } else { - fetchdat = fastreadl(cs + op_pc); - codegen_mark_code_present(block, cs + op_pc, 4); - uop_AND_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); - } + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + op_pc); + uop_AND(ir, IREG_EAX, IREG_EAX, IREG_temp0); + } else { + fetchdat = fastreadl(cs + op_pc); + codegen_mark_code_present(block, cs + op_pc, 4); + uop_AND_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - uop_MOV(ir, IREG_flags_res, IREG_EAX); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_EAX); - codegen_flags_changed = 1; - return op_pc + 4; + codegen_flags_changed = 1; + return op_pc + 4; } uint32_t ropAND_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_AND(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); - } else { - x86seg *target_seg; + uop_AND(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_AND(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_AND(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } uint32_t ropAND_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int dest_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - uop_AND(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - } else { - x86seg *target_seg; + uop_AND(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_AND(ir, IREG_temp0_B, IREG_temp0_B, IREG_8(src_reg)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); - } + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_AND(ir, IREG_temp0_B, IREG_temp0_B, IREG_8(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } uint32_t ropAND_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_AND(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); - } else { - x86seg *target_seg; + uop_AND(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_AND(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_AND(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } uint32_t ropAND_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int dest_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - uop_AND(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - } else { - x86seg *target_seg; + uop_AND(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_AND(ir, IREG_temp0_W, IREG_temp0_W, IREG_16(src_reg)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); - } + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_AND(ir, IREG_temp0_W, IREG_temp0_W, IREG_16(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } uint32_t ropAND_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_AND(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); - } else { - x86seg *target_seg; + uop_AND(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - uop_AND(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_AND(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } uint32_t ropAND_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int dest_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - uop_AND(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - } else { - x86seg *target_seg; + uop_AND(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - uop_AND(ir, IREG_temp0, IREG_temp0, IREG_32(src_reg)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - uop_MOV(ir, IREG_flags_res, IREG_temp0); - } + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_AND(ir, IREG_temp0, IREG_temp0, IREG_32(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } uint32_t ropOR_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint8_t imm_data = fastreadb(cs + op_pc); + uint8_t imm_data = fastreadb(cs + op_pc); - uop_OR_IMM(ir, IREG_AL, IREG_AL, imm_data); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); - uop_MOVZX(ir, IREG_flags_res, IREG_AL); + uop_OR_IMM(ir, IREG_AL, IREG_AL, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_MOVZX(ir, IREG_flags_res, IREG_AL); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs + op_pc, 1); - return op_pc + 1; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 1); + return op_pc + 1; } uint32_t ropOR_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint16_t imm_data = fastreadw(cs + op_pc); + uint16_t imm_data = fastreadw(cs + op_pc); - uop_OR_IMM(ir, IREG_AX, IREG_AX, imm_data); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - uop_MOVZX(ir, IREG_flags_res, IREG_AX); + uop_OR_IMM(ir, IREG_AX, IREG_AX, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_AX); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs + op_pc, 2); - return op_pc + 2; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 2); + return op_pc + 2; } uint32_t ropOR_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - if (block->flags & CODEBLOCK_NO_IMMEDIATES) { - LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + op_pc); - uop_OR(ir, IREG_EAX, IREG_EAX, IREG_temp0); - } else { - fetchdat = fastreadl(cs + op_pc); - codegen_mark_code_present(block, cs + op_pc, 4); - uop_OR_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); - } + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + op_pc); + uop_OR(ir, IREG_EAX, IREG_EAX, IREG_temp0); + } else { + fetchdat = fastreadl(cs + op_pc); + codegen_mark_code_present(block, cs + op_pc, 4); + uop_OR_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - uop_MOV(ir, IREG_flags_res, IREG_EAX); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_EAX); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs + op_pc, 4); - return op_pc + 4; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 4); + return op_pc + 4; } uint32_t ropOR_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_OR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); - } else { - x86seg *target_seg; + uop_OR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_OR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_OR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } uint32_t ropOR_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int dest_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - uop_OR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - } else { - x86seg *target_seg; + uop_OR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_OR(ir, IREG_temp0_B, IREG_temp0_B, IREG_8(src_reg)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); - } + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_OR(ir, IREG_temp0_B, IREG_temp0_B, IREG_8(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } uint32_t ropOR_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_OR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); - } else { - x86seg *target_seg; + uop_OR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_OR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_OR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } uint32_t ropOR_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int dest_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - uop_OR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - } else { - x86seg *target_seg; + uop_OR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_OR(ir, IREG_temp0_W, IREG_temp0_W, IREG_16(src_reg)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); - } + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_OR(ir, IREG_temp0_W, IREG_temp0_W, IREG_16(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } uint32_t ropOR_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_OR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); - } else { - x86seg *target_seg; + uop_OR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - uop_OR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_OR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - uop_MOV(ir, IREG_flags_res, dest_reg); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, dest_reg); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } uint32_t ropOR_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int dest_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - uop_OR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - } else { - x86seg *target_seg; + uop_OR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - uop_OR(ir, IREG_temp0, IREG_temp0, IREG_32(src_reg)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - uop_MOV(ir, IREG_flags_res, IREG_temp0); - } + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_OR(ir, IREG_temp0, IREG_temp0, IREG_32(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } uint32_t ropTEST_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint8_t imm_data = fastreadb(cs + op_pc); + uint8_t imm_data = fastreadb(cs + op_pc); - uop_AND_IMM(ir, IREG_flags_res, IREG_EAX, imm_data); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_AND_IMM(ir, IREG_flags_res, IREG_EAX, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs + op_pc, 1); - return op_pc + 1; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 1); + return op_pc + 1; } uint32_t ropTEST_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint16_t imm_data = fastreadw(cs + op_pc); + uint16_t imm_data = fastreadw(cs + op_pc); - uop_AND_IMM(ir, IREG_flags_res, IREG_EAX, imm_data); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_AND_IMM(ir, IREG_flags_res, IREG_EAX, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs + op_pc, 2); - return op_pc + 2; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 2); + return op_pc + 2; } uint32_t ropTEST_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - if (block->flags & CODEBLOCK_NO_IMMEDIATES) { - LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + op_pc); - uop_AND(ir, IREG_flags_res, IREG_EAX, IREG_temp0); - } else { - fetchdat = fastreadl(cs + op_pc); - codegen_mark_code_present(block, cs + op_pc, 4); - uop_AND_IMM(ir, IREG_flags_res, IREG_EAX, fetchdat); - } + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + op_pc); + uop_AND(ir, IREG_flags_res, IREG_EAX, IREG_temp0); + } else { + fetchdat = fastreadl(cs + op_pc); + codegen_mark_code_present(block, cs + op_pc, 4); + uop_AND_IMM(ir, IREG_flags_res, IREG_EAX, fetchdat); + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs + op_pc, 4); - return op_pc + 4; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 4); + return op_pc + 4; } uint32_t ropTEST_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_AND(ir, IREG_flags_res_B, IREG_8(dest_reg), IREG_8(src_reg)); - } else { - x86seg *target_seg; + uop_AND(ir, IREG_flags_res_B, IREG_8(dest_reg), IREG_8(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_AND(ir, IREG_flags_res_B, IREG_8(dest_reg), IREG_temp0_B); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_AND(ir, IREG_flags_res_B, IREG_8(dest_reg), IREG_temp0_B); + } - uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } uint32_t ropTEST_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_AND(ir, IREG_flags_res_W, IREG_16(dest_reg), IREG_16(src_reg)); - } else { - x86seg *target_seg; + uop_AND(ir, IREG_flags_res_W, IREG_16(dest_reg), IREG_16(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_AND(ir, IREG_flags_res_W, IREG_16(dest_reg), IREG_temp0_W); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_AND(ir, IREG_flags_res_W, IREG_16(dest_reg), IREG_temp0_W); + } - uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } uint32_t ropTEST_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_AND(ir, IREG_flags_res, IREG_32(dest_reg), IREG_32(src_reg)); - } else { - x86seg *target_seg; + uop_AND(ir, IREG_flags_res, IREG_32(dest_reg), IREG_32(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - uop_AND(ir, IREG_flags_res, IREG_32(dest_reg), IREG_temp0); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_AND(ir, IREG_flags_res, IREG_32(dest_reg), IREG_temp0); + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } uint32_t ropXOR_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint8_t imm_data = fastreadb(cs + op_pc); + uint8_t imm_data = fastreadb(cs + op_pc); - uop_XOR_IMM(ir, IREG_AL, IREG_AL, imm_data); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); - uop_MOVZX(ir, IREG_flags_res, IREG_AL); + uop_XOR_IMM(ir, IREG_AL, IREG_AL, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_MOVZX(ir, IREG_flags_res, IREG_AL); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs + op_pc, 1); - return op_pc + 1; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 1); + return op_pc + 1; } uint32_t ropXOR_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint16_t imm_data = fastreadw(cs + op_pc); + uint16_t imm_data = fastreadw(cs + op_pc); - uop_XOR_IMM(ir, IREG_AX, IREG_AX, imm_data); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - uop_MOVZX(ir, IREG_flags_res, IREG_AX); + uop_XOR_IMM(ir, IREG_AX, IREG_AX, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_AX); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs + op_pc, 2); - return op_pc + 2; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 2); + return op_pc + 2; } uint32_t ropXOR_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - if (block->flags & CODEBLOCK_NO_IMMEDIATES) { - LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + op_pc); - uop_XOR(ir, IREG_EAX, IREG_EAX, IREG_temp0); - } else { - fetchdat = fastreadl(cs + op_pc); - codegen_mark_code_present(block, cs + op_pc, 4); - uop_XOR_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); - } + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + op_pc); + uop_XOR(ir, IREG_EAX, IREG_EAX, IREG_temp0); + } else { + fetchdat = fastreadl(cs + op_pc); + codegen_mark_code_present(block, cs + op_pc, 4); + uop_XOR_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - uop_MOV(ir, IREG_flags_res, IREG_EAX); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_EAX); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs + op_pc, 4); - return op_pc + 4; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 4); + return op_pc + 4; } uint32_t ropXOR_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_XOR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); - } else { - x86seg *target_seg; + uop_XOR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_XOR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_XOR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } uint32_t ropXOR_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int dest_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - uop_XOR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - } else { - x86seg *target_seg; + uop_XOR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_XOR(ir, IREG_temp0_B, IREG_temp0_B, IREG_8(src_reg)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); - } + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_XOR(ir, IREG_temp0_B, IREG_temp0_B, IREG_8(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } uint32_t ropXOR_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_XOR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); - } else { - x86seg *target_seg; + uop_XOR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_XOR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_XOR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } uint32_t ropXOR_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int dest_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - uop_XOR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - } else { - x86seg *target_seg; + uop_XOR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_XOR(ir, IREG_temp0_W, IREG_temp0_W, IREG_16(src_reg)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); - } + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_XOR(ir, IREG_temp0_W, IREG_temp0_W, IREG_16(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } uint32_t ropXOR_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_XOR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); - } else { - x86seg *target_seg; + uop_XOR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - uop_XOR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_XOR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - uop_MOV(ir, IREG_flags_res, dest_reg); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, dest_reg); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } uint32_t ropXOR_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int dest_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - uop_XOR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - } else { - x86seg *target_seg; + uop_XOR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - uop_XOR(ir, IREG_temp0, IREG_temp0, IREG_32(src_reg)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - uop_MOV(ir, IREG_flags_res, IREG_temp0); - } + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_XOR(ir, IREG_temp0, IREG_temp0, IREG_32(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } diff --git a/src/codegen/codegen_ops_misc.c b/src/codegen/codegen_ops_misc.c index af1b4c43..e586458a 100644 --- a/src/codegen/codegen_ops_misc.c +++ b/src/codegen/codegen_ops_misc.c @@ -10,550 +10,551 @@ #include "codegen_ops_misc.h" uint32_t ropLEA_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - if ((fetchdat & 0xc0) == 0xc0) - return 0; + if ((fetchdat & 0xc0) == 0xc0) + return 0; - codegen_mark_code_present(block, cs + op_pc, 1); - codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - uop_MOV(ir, IREG_16(dest_reg), IREG_eaaddr_W); + codegen_mark_code_present(block, cs + op_pc, 1); + codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + uop_MOV(ir, IREG_16(dest_reg), IREG_eaaddr_W); - return op_pc + 1; + return op_pc + 1; } uint32_t ropLEA_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - if ((fetchdat & 0xc0) == 0xc0) - return 0; + if ((fetchdat & 0xc0) == 0xc0) + return 0; - codegen_mark_code_present(block, cs + op_pc, 1); - codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - uop_MOV(ir, IREG_32(dest_reg), IREG_eaaddr); + codegen_mark_code_present(block, cs + op_pc, 1); + codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + uop_MOV(ir, IREG_32(dest_reg), IREG_eaaddr); - return op_pc + 1; + return op_pc + 1; } uint32_t ropF6(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg = NULL; - uint8_t imm_data; - int reg; + x86seg *target_seg = NULL; + uint8_t imm_data; + int reg; - if (fetchdat & 0x20) - return 0; + if (fetchdat & 0x20) + return 0; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - reg = IREG_8(fetchdat & 7); - else { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - if ((fetchdat & 0x30) == 0x10) /*NEG/NOT*/ - codegen_check_seg_write(block, ir, target_seg); - else - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - reg = IREG_temp0_B; - } + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) + reg = IREG_8(fetchdat & 7); + else { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + if ((fetchdat & 0x30) == 0x10) /*NEG/NOT*/ + codegen_check_seg_write(block, ir, target_seg); + else + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + reg = IREG_temp0_B; + } - switch (fetchdat & 0x38) { - case 0x00: - case 0x08: /*TEST*/ - imm_data = fastreadb(cs + op_pc + 1); + switch (fetchdat & 0x38) { + case 0x00: + case 0x08: /*TEST*/ + imm_data = fastreadb(cs + op_pc + 1); - uop_AND_IMM(ir, IREG_flags_res_B, reg, imm_data); - uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_AND_IMM(ir, IREG_flags_res_B, reg, imm_data); + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs + op_pc + 1, 1); - return op_pc + 2; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc + 1, 1); + return op_pc + 2; - case 0x10: /*NOT*/ - uop_XOR_IMM(ir, reg, reg, 0xff); - if ((fetchdat & 0xc0) != 0xc0) - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, reg); + case 0x10: /*NOT*/ + uop_XOR_IMM(ir, reg, reg, 0xff); + if ((fetchdat & 0xc0) != 0xc0) + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, reg); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; - case 0x18: /*NEG*/ - uop_MOV_IMM(ir, IREG_temp1_B, 0); + case 0x18: /*NEG*/ + uop_MOV_IMM(ir, IREG_temp1_B, 0); - if ((fetchdat & 0xc0) == 0xc0) { - uop_MOVZX(ir, IREG_flags_op2, reg); - uop_SUB(ir, IREG_temp1_B, IREG_temp1_B, reg); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); - uop_MOV(ir, reg, IREG_temp1_B); - } else { - uop_SUB(ir, IREG_temp1_B, IREG_temp1_B, reg); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); - uop_MOV_IMM(ir, IREG_flags_op1, 0); + if ((fetchdat & 0xc0) == 0xc0) { + uop_MOVZX(ir, IREG_flags_op2, reg); + uop_SUB(ir, IREG_temp1_B, IREG_temp1_B, reg); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + uop_MOV(ir, reg, IREG_temp1_B); + } else { + uop_SUB(ir, IREG_temp1_B, IREG_temp1_B, reg); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); + uop_MOV_IMM(ir, IREG_flags_op1, 0); - codegen_flags_changed = 1; - return op_pc + 1; - } - return 0; + codegen_flags_changed = 1; + return op_pc + 1; + } + return 0; } uint32_t ropF7_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg = NULL; - uint16_t imm_data; - int reg; + x86seg *target_seg = NULL; + uint16_t imm_data; + int reg; - if (fetchdat & 0x20) - return 0; + if (fetchdat & 0x20) + return 0; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - reg = IREG_16(fetchdat & 7); - else { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - if ((fetchdat & 0x30) == 0x10) /*NEG/NOT*/ - codegen_check_seg_write(block, ir, target_seg); - else - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - reg = IREG_temp0_W; - } + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) + reg = IREG_16(fetchdat & 7); + else { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + if ((fetchdat & 0x30) == 0x10) /*NEG/NOT*/ + codegen_check_seg_write(block, ir, target_seg); + else + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + reg = IREG_temp0_W; + } - switch (fetchdat & 0x38) { - case 0x00: - case 0x08: /*TEST*/ - imm_data = fastreadw(cs + op_pc + 1); + switch (fetchdat & 0x38) { + case 0x00: + case 0x08: /*TEST*/ + imm_data = fastreadw(cs + op_pc + 1); - uop_AND_IMM(ir, IREG_flags_res_W, reg, imm_data); - uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_AND_IMM(ir, IREG_flags_res_W, reg, imm_data); + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs + op_pc + 1, 2); - return op_pc + 3; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc + 1, 2); + return op_pc + 3; - case 0x10: /*NOT*/ - uop_XOR_IMM(ir, reg, reg, 0xffff); - if ((fetchdat & 0xc0) != 0xc0) - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, reg); + case 0x10: /*NOT*/ + uop_XOR_IMM(ir, reg, reg, 0xffff); + if ((fetchdat & 0xc0) != 0xc0) + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, reg); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; - case 0x18: /*NEG*/ - uop_MOV_IMM(ir, IREG_temp1_W, 0); + case 0x18: /*NEG*/ + uop_MOV_IMM(ir, IREG_temp1_W, 0); - if ((fetchdat & 0xc0) == 0xc0) { - uop_MOVZX(ir, IREG_flags_op2, reg); - uop_SUB(ir, IREG_temp1_W, IREG_temp1_W, reg); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - uop_MOV(ir, reg, IREG_temp1_W); - } else { - uop_SUB(ir, IREG_temp1_W, IREG_temp1_W, reg); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); - uop_MOV_IMM(ir, IREG_flags_op1, 0); + if ((fetchdat & 0xc0) == 0xc0) { + uop_MOVZX(ir, IREG_flags_op2, reg); + uop_SUB(ir, IREG_temp1_W, IREG_temp1_W, reg); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + uop_MOV(ir, reg, IREG_temp1_W); + } else { + uop_SUB(ir, IREG_temp1_W, IREG_temp1_W, reg); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + uop_MOV_IMM(ir, IREG_flags_op1, 0); - codegen_flags_changed = 1; - return op_pc + 1; - } - return 0; + codegen_flags_changed = 1; + return op_pc + 1; + } + return 0; } uint32_t ropF7_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg = NULL; - uint32_t imm_data; - int reg; + x86seg *target_seg = NULL; + uint32_t imm_data; + int reg; - if (fetchdat & 0x20) - return 0; + if (fetchdat & 0x20) + return 0; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - reg = IREG_32(fetchdat & 7); - else { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - if ((fetchdat & 0x30) == 0x10) /*NEG/NOT*/ - codegen_check_seg_write(block, ir, target_seg); - else - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - reg = IREG_temp0; - } + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) + reg = IREG_32(fetchdat & 7); + else { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + if ((fetchdat & 0x30) == 0x10) /*NEG/NOT*/ + codegen_check_seg_write(block, ir, target_seg); + else + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + reg = IREG_temp0; + } - switch (fetchdat & 0x38) { - case 0x00: - case 0x08: /*TEST*/ - imm_data = fastreadl(cs + op_pc + 1); + switch (fetchdat & 0x38) { + case 0x00: + case 0x08: /*TEST*/ + imm_data = fastreadl(cs + op_pc + 1); - uop_AND_IMM(ir, IREG_flags_res, reg, imm_data); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_AND_IMM(ir, IREG_flags_res, reg, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs + op_pc + 1, 4); - return op_pc + 5; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc + 1, 4); + return op_pc + 5; - case 0x10: /*NOT*/ - uop_XOR_IMM(ir, reg, reg, 0xffffffff); - if ((fetchdat & 0xc0) != 0xc0) - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, reg); + case 0x10: /*NOT*/ + uop_XOR_IMM(ir, reg, reg, 0xffffffff); + if ((fetchdat & 0xc0) != 0xc0) + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, reg); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; - case 0x18: /*NEG*/ - uop_MOV_IMM(ir, IREG_temp1, 0); + case 0x18: /*NEG*/ + uop_MOV_IMM(ir, IREG_temp1, 0); - if ((fetchdat & 0xc0) == 0xc0) { - uop_MOV(ir, IREG_flags_op2, reg); - uop_SUB(ir, IREG_temp1, IREG_temp1, reg); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - uop_MOV(ir, reg, IREG_temp1); - } else { - uop_SUB(ir, IREG_temp1, IREG_temp1, reg); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op2, IREG_temp0); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); - uop_MOV_IMM(ir, IREG_flags_op1, 0); + if ((fetchdat & 0xc0) == 0xc0) { + uop_MOV(ir, IREG_flags_op2, reg); + uop_SUB(ir, IREG_temp1, IREG_temp1, reg); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + uop_MOV(ir, reg, IREG_temp1); + } else { + uop_SUB(ir, IREG_temp1, IREG_temp1, reg); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op2, IREG_temp0); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + uop_MOV_IMM(ir, IREG_flags_op1, 0); - codegen_flags_changed = 1; - return op_pc + 1; - } - return 0; + codegen_flags_changed = 1; + return op_pc + 1; + } + return 0; } static void rebuild_c(ir_data_t *ir) { - int needs_rebuild = 1; + int needs_rebuild = 1; - if (codegen_flags_changed) { - switch (cpu_state.flags_op) { - case FLAGS_INC8: - case FLAGS_INC16: - case FLAGS_INC32: - case FLAGS_DEC8: - case FLAGS_DEC16: - case FLAGS_DEC32:needs_rebuild = 0; - break; - } - } + if (codegen_flags_changed) { + switch (cpu_state.flags_op) { + case FLAGS_INC8: + case FLAGS_INC16: + case FLAGS_INC32: + case FLAGS_DEC8: + case FLAGS_DEC16: + case FLAGS_DEC32: + needs_rebuild = 0; + break; + } + } - if (needs_rebuild) { - uop_CALL_FUNC(ir, flags_rebuild_c); - } + if (needs_rebuild) { + uop_CALL_FUNC(ir, flags_rebuild_c); + } } uint32_t ropFF_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg = NULL; - int src_reg, sp_reg; + x86seg *target_seg = NULL; + int src_reg, sp_reg; - if ((fetchdat & 0x38) != 0x00 && (fetchdat & 0x38) != 0x08 && (fetchdat & 0x38) != 0x10 && (fetchdat & 0x38) != 0x20 && (fetchdat & 0x38) != 0x28 && (fetchdat & 0x38) != 0x30) - return 0; + if ((fetchdat & 0x38) != 0x00 && (fetchdat & 0x38) != 0x08 && (fetchdat & 0x38) != 0x10 && (fetchdat & 0x38) != 0x20 && + (fetchdat & 0x38) != 0x28 && (fetchdat & 0x38) != 0x30) + return 0; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - if ((fetchdat & 0x38) == 0x28) - return 0; - src_reg = IREG_16(fetchdat & 7); - } else { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - if (!(fetchdat & 0x30)) /*INC/DEC*/ - codegen_check_seg_write(block, ir, target_seg); - else - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - src_reg = IREG_temp0_W; - } + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + if ((fetchdat & 0x38) == 0x28) + return 0; + src_reg = IREG_16(fetchdat & 7); + } else { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + if (!(fetchdat & 0x30)) /*INC/DEC*/ + codegen_check_seg_write(block, ir, target_seg); + else + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + src_reg = IREG_temp0_W; + } - switch (fetchdat & 0x38) { - case 0x00: /*INC*/ - rebuild_c(ir); - codegen_flags_changed = 1; + switch (fetchdat & 0x38) { + case 0x00: /*INC*/ + rebuild_c(ir); + codegen_flags_changed = 1; - if ((fetchdat & 0xc0) == 0xc0) { - uop_MOVZX(ir, IREG_flags_op1, src_reg); - uop_ADD_IMM(ir, src_reg, src_reg, 1); - uop_MOVZX(ir, IREG_flags_res, src_reg); - uop_MOV_IMM(ir, IREG_flags_op2, 1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC16); - } else { - uop_ADD_IMM(ir, IREG_temp1_W, src_reg, 1); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_op1, src_reg); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - uop_MOV_IMM(ir, IREG_flags_op2, 1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC16); - } - return op_pc + 1; + if ((fetchdat & 0xc0) == 0xc0) { + uop_MOVZX(ir, IREG_flags_op1, src_reg); + uop_ADD_IMM(ir, src_reg, src_reg, 1); + uop_MOVZX(ir, IREG_flags_res, src_reg); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC16); + } else { + uop_ADD_IMM(ir, IREG_temp1_W, src_reg, 1); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, src_reg); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC16); + } + return op_pc + 1; - case 0x08: /*DEC*/ - rebuild_c(ir); - codegen_flags_changed = 1; + case 0x08: /*DEC*/ + rebuild_c(ir); + codegen_flags_changed = 1; - if ((fetchdat & 0xc0) == 0xc0) { - uop_MOVZX(ir, IREG_flags_op1, src_reg); - uop_SUB_IMM(ir, src_reg, src_reg, 1); - uop_MOVZX(ir, IREG_flags_res, src_reg); - uop_MOV_IMM(ir, IREG_flags_op2, 1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC16); - } else { - uop_SUB_IMM(ir, IREG_temp1_W, src_reg, 1); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_op1, src_reg); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - uop_MOV_IMM(ir, IREG_flags_op2, 1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC16); - } - return op_pc + 1; + if ((fetchdat & 0xc0) == 0xc0) { + uop_MOVZX(ir, IREG_flags_op1, src_reg); + uop_SUB_IMM(ir, src_reg, src_reg, 1); + uop_MOVZX(ir, IREG_flags_res, src_reg); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC16); + } else { + uop_SUB_IMM(ir, IREG_temp1_W, src_reg, 1); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, src_reg); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC16); + } + return op_pc + 1; - case 0x10: /*CALL*/ - if ((fetchdat & 0xc0) == 0xc0) - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); - uop_MEM_STORE_IMM_16(ir, IREG_SS_base, sp_reg, op_pc + 1); - SUB_SP(ir, 2); - uop_MOVZX(ir, IREG_pc, src_reg); - return -1; + case 0x10: /*CALL*/ + if ((fetchdat & 0xc0) == 0xc0) + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); + uop_MEM_STORE_IMM_16(ir, IREG_SS_base, sp_reg, op_pc + 1); + SUB_SP(ir, 2); + uop_MOVZX(ir, IREG_pc, src_reg); + return -1; - case 0x20: /*JMP*/ - uop_MOVZX(ir, IREG_pc, src_reg); - return -1; + case 0x20: /*JMP*/ + uop_MOVZX(ir, IREG_pc, src_reg); + return -1; - case 0x28: /*JMP far*/ - uop_MOVZX(ir, IREG_pc, src_reg); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, ireg_seg_base(target_seg), IREG_eaaddr, 2); - uop_LOAD_FUNC_ARG_REG(ir, 0, IREG_temp1_W); - uop_LOAD_FUNC_ARG_IMM(ir, 1, op_pc + 1); - uop_CALL_FUNC(ir, loadcsjmp); - return -1; + case 0x28: /*JMP far*/ + uop_MOVZX(ir, IREG_pc, src_reg); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, ireg_seg_base(target_seg), IREG_eaaddr, 2); + uop_LOAD_FUNC_ARG_REG(ir, 0, IREG_temp1_W); + uop_LOAD_FUNC_ARG_IMM(ir, 1, op_pc + 1); + uop_CALL_FUNC(ir, loadcsjmp); + return -1; - case 0x30: /*PUSH*/ - if ((fetchdat & 0xc0) == 0xc0) - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); - uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, src_reg); - SUB_SP(ir, 2); - return op_pc + 1; - } - return 0; + case 0x30: /*PUSH*/ + if ((fetchdat & 0xc0) == 0xc0) + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); + uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, src_reg); + SUB_SP(ir, 2); + return op_pc + 1; + } + return 0; } uint32_t ropFF_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg = NULL; - int src_reg, sp_reg; + x86seg *target_seg = NULL; + int src_reg, sp_reg; - if ((fetchdat & 0x38) != 0x00 && (fetchdat & 0x38) != 0x08 && (fetchdat & 0x38) != 0x10 && (fetchdat & 0x38) != 0x20 && (fetchdat & 0x38) != 0x28 && (fetchdat & 0x38) != 0x30) - return 0; + if ((fetchdat & 0x38) != 0x00 && (fetchdat & 0x38) != 0x08 && (fetchdat & 0x38) != 0x10 && (fetchdat & 0x38) != 0x20 && + (fetchdat & 0x38) != 0x28 && (fetchdat & 0x38) != 0x30) + return 0; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - if ((fetchdat & 0x38) == 0x28) - return 0; - src_reg = IREG_32(fetchdat & 7); - } else { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - if (!(fetchdat & 0x30)) /*INC/DEC*/ - codegen_check_seg_write(block, ir, target_seg); - else - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - src_reg = IREG_temp0; - } + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + if ((fetchdat & 0x38) == 0x28) + return 0; + src_reg = IREG_32(fetchdat & 7); + } else { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + if (!(fetchdat & 0x30)) /*INC/DEC*/ + codegen_check_seg_write(block, ir, target_seg); + else + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + src_reg = IREG_temp0; + } - switch (fetchdat & 0x38) { - case 0x00: /*INC*/ - rebuild_c(ir); - codegen_flags_changed = 1; + switch (fetchdat & 0x38) { + case 0x00: /*INC*/ + rebuild_c(ir); + codegen_flags_changed = 1; - if ((fetchdat & 0xc0) == 0xc0) { - uop_MOV(ir, IREG_flags_op1, src_reg); - uop_ADD_IMM(ir, src_reg, src_reg, 1); - uop_MOV(ir, IREG_flags_res, src_reg); - uop_MOV_IMM(ir, IREG_flags_op2, 1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC32); - } else { - uop_ADD_IMM(ir, IREG_temp1, src_reg, 1); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, src_reg); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - uop_MOV_IMM(ir, IREG_flags_op2, 1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC32); - } - return op_pc + 1; + if ((fetchdat & 0xc0) == 0xc0) { + uop_MOV(ir, IREG_flags_op1, src_reg); + uop_ADD_IMM(ir, src_reg, src_reg, 1); + uop_MOV(ir, IREG_flags_res, src_reg); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC32); + } else { + uop_ADD_IMM(ir, IREG_temp1, src_reg, 1); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, src_reg); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC32); + } + return op_pc + 1; - case 0x08: /*DEC*/ - rebuild_c(ir); - codegen_flags_changed = 1; + case 0x08: /*DEC*/ + rebuild_c(ir); + codegen_flags_changed = 1; - if ((fetchdat & 0xc0) == 0xc0) { - uop_MOV(ir, IREG_flags_op1, src_reg); - uop_SUB_IMM(ir, src_reg, src_reg, 1); - uop_MOV(ir, IREG_flags_res, src_reg); - uop_MOV_IMM(ir, IREG_flags_op2, 1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC32); - } else { - uop_SUB_IMM(ir, IREG_temp1, src_reg, 1); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, src_reg); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - uop_MOV_IMM(ir, IREG_flags_op2, 1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC32); - } - return op_pc + 1; + if ((fetchdat & 0xc0) == 0xc0) { + uop_MOV(ir, IREG_flags_op1, src_reg); + uop_SUB_IMM(ir, src_reg, src_reg, 1); + uop_MOV(ir, IREG_flags_res, src_reg); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC32); + } else { + uop_SUB_IMM(ir, IREG_temp1, src_reg, 1); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, src_reg); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC32); + } + return op_pc + 1; - case 0x10: /*CALL*/ - if ((fetchdat & 0xc0) == 0xc0) - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); - uop_MEM_STORE_IMM_32(ir, IREG_SS_base, sp_reg, op_pc + 1); - SUB_SP(ir, 4); - uop_MOV(ir, IREG_pc, src_reg); - return -1; + case 0x10: /*CALL*/ + if ((fetchdat & 0xc0) == 0xc0) + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); + uop_MEM_STORE_IMM_32(ir, IREG_SS_base, sp_reg, op_pc + 1); + SUB_SP(ir, 4); + uop_MOV(ir, IREG_pc, src_reg); + return -1; - case 0x20: /*JMP*/ - uop_MOV(ir, IREG_pc, src_reg); - return -1; + case 0x20: /*JMP*/ + uop_MOV(ir, IREG_pc, src_reg); + return -1; - case 0x28: /*JMP far*/ - uop_MOV(ir, IREG_pc, src_reg); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, ireg_seg_base(target_seg), IREG_eaaddr, 4); - uop_LOAD_FUNC_ARG_REG(ir, 0, IREG_temp1_W); - uop_LOAD_FUNC_ARG_IMM(ir, 1, op_pc + 1); - uop_CALL_FUNC(ir, loadcsjmp); - return -1; + case 0x28: /*JMP far*/ + uop_MOV(ir, IREG_pc, src_reg); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, ireg_seg_base(target_seg), IREG_eaaddr, 4); + uop_LOAD_FUNC_ARG_REG(ir, 0, IREG_temp1_W); + uop_LOAD_FUNC_ARG_IMM(ir, 1, op_pc + 1); + uop_CALL_FUNC(ir, loadcsjmp); + return -1; - case 0x30: /*PUSH*/ - if ((fetchdat & 0xc0) == 0xc0) - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); - uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, src_reg); - SUB_SP(ir, 4); - return op_pc + 1; - } - return 0; + case 0x30: /*PUSH*/ + if ((fetchdat & 0xc0) == 0xc0) + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); + uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, src_reg); + SUB_SP(ir, 4); + return op_pc + 1; + } + return 0; } uint32_t ropNOP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - return op_pc; + return op_pc; } uint32_t ropCBW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_MOVSX(ir, IREG_AX, IREG_AL); + uop_MOVSX(ir, IREG_AX, IREG_AL); - return op_pc; + return op_pc; } uint32_t ropCDQ(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_SAR_IMM(ir, IREG_EDX, IREG_EAX, 31); + uop_SAR_IMM(ir, IREG_EDX, IREG_EAX, 31); - return op_pc; + return op_pc; } uint32_t ropCWD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_SAR_IMM(ir, IREG_DX, IREG_AX, 15); + uop_SAR_IMM(ir, IREG_DX, IREG_AX, 15); - return op_pc; + return op_pc; } uint32_t ropCWDE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_MOVSX(ir, IREG_EAX, IREG_AX); + uop_MOVSX(ir, IREG_EAX, IREG_AX); - return op_pc; + return op_pc; } -#define ropLxS(name, seg) \ -uint32_t rop ## name ## _16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - x86seg *target_seg = NULL; \ - int dest_reg = (fetchdat >> 3) & 7; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - return 0; \ - \ - codegen_mark_code_present(block, cs+op_pc, 1); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, ireg_seg_base(target_seg), IREG_eaaddr, 2); \ - uop_LOAD_SEG(ir, seg, IREG_temp1_W); \ - uop_MOV(ir, IREG_16(dest_reg), IREG_temp0_W); \ - \ - if (seg == &cpu_state.seg_ss) \ - CPU_BLOCK_END(); \ - \ - return op_pc + 1; \ -} \ -uint32_t rop ## name ## _32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - x86seg *target_seg = NULL; \ - int dest_reg = (fetchdat >> 3) & 7; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - return 0; \ - \ - codegen_mark_code_present(block, cs+op_pc, 1); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, ireg_seg_base(target_seg), IREG_eaaddr, 4); \ - uop_LOAD_SEG(ir, seg, IREG_temp1_W); \ - uop_MOV(ir, IREG_32(dest_reg), IREG_temp0); \ - \ - if (seg == &cpu_state.seg_ss) \ - CPU_BLOCK_END(); \ - \ - return op_pc + 1; \ -} +#define ropLxS(name, seg) \ + uint32_t rop##name##_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, \ + uint32_t op_pc) { \ + x86seg *target_seg = NULL; \ + int dest_reg = (fetchdat >> 3) & 7; \ + \ + if ((fetchdat & 0xc0) == 0xc0) \ + return 0; \ + \ + codegen_mark_code_present(block, cs + op_pc, 1); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, ireg_seg_base(target_seg), IREG_eaaddr, 2); \ + uop_LOAD_SEG(ir, seg, IREG_temp1_W); \ + uop_MOV(ir, IREG_16(dest_reg), IREG_temp0_W); \ + \ + if (seg == &cpu_state.seg_ss) \ + CPU_BLOCK_END(); \ + \ + return op_pc + 1; \ + } \ + uint32_t rop##name##_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, \ + uint32_t op_pc) { \ + x86seg *target_seg = NULL; \ + int dest_reg = (fetchdat >> 3) & 7; \ + \ + if ((fetchdat & 0xc0) == 0xc0) \ + return 0; \ + \ + codegen_mark_code_present(block, cs + op_pc, 1); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, ireg_seg_base(target_seg), IREG_eaaddr, 4); \ + uop_LOAD_SEG(ir, seg, IREG_temp1_W); \ + uop_MOV(ir, IREG_32(dest_reg), IREG_temp0); \ + \ + if (seg == &cpu_state.seg_ss) \ + CPU_BLOCK_END(); \ + \ + return op_pc + 1; \ + } -ropLxS(LDS, &cpu_state.seg_ds) -ropLxS(LES, &cpu_state.seg_es) -ropLxS(LFS, &cpu_state.seg_fs) -ropLxS(LGS, &cpu_state.seg_gs) -ropLxS(LSS, &cpu_state.seg_ss) +ropLxS(LDS, &cpu_state.seg_ds) ropLxS(LES, &cpu_state.seg_es) ropLxS(LFS, &cpu_state.seg_fs) ropLxS(LGS, &cpu_state.seg_gs) + ropLxS(LSS, &cpu_state.seg_ss) -uint32_t ropCLC(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_CALL_FUNC(ir, flags_rebuild); - uop_AND_IMM(ir, IREG_flags, IREG_flags, ~C_FLAG); - return op_pc; + uint32_t + ropCLC(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { + uop_CALL_FUNC(ir, flags_rebuild); + uop_AND_IMM(ir, IREG_flags, IREG_flags, ~C_FLAG); + return op_pc; } uint32_t ropCMC(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_CALL_FUNC(ir, flags_rebuild); - uop_XOR_IMM(ir, IREG_flags, IREG_flags, C_FLAG); - return op_pc; + uop_CALL_FUNC(ir, flags_rebuild); + uop_XOR_IMM(ir, IREG_flags, IREG_flags, C_FLAG); + return op_pc; } uint32_t ropSTC(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_CALL_FUNC(ir, flags_rebuild); - uop_OR_IMM(ir, IREG_flags, IREG_flags, C_FLAG); - return op_pc; + uop_CALL_FUNC(ir, flags_rebuild); + uop_OR_IMM(ir, IREG_flags, IREG_flags, C_FLAG); + return op_pc; } uint32_t ropCLD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_AND_IMM(ir, IREG_flags, IREG_flags, ~D_FLAG); - return op_pc; + uop_AND_IMM(ir, IREG_flags, IREG_flags, ~D_FLAG); + return op_pc; } uint32_t ropSTD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_OR_IMM(ir, IREG_flags, IREG_flags, D_FLAG); - return op_pc; + uop_OR_IMM(ir, IREG_flags, IREG_flags, D_FLAG); + return op_pc; } uint32_t ropCLI(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - if (!IOPLp && (cr4 & (CR4_VME | CR4_PVI))) - return 0; + if (!IOPLp && (cr4 & (CR4_VME | CR4_PVI))) + return 0; - uop_AND_IMM(ir, IREG_flags, IREG_flags, ~I_FLAG); - return op_pc; + uop_AND_IMM(ir, IREG_flags, IREG_flags, ~I_FLAG); + return op_pc; } uint32_t ropSTI(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - if (!IOPLp && (cr4 & (CR4_VME | CR4_PVI))) - return 0; + if (!IOPLp && (cr4 & (CR4_VME | CR4_PVI))) + return 0; - uop_OR_IMM(ir, IREG_flags, IREG_flags, I_FLAG); - return op_pc; + uop_OR_IMM(ir, IREG_flags, IREG_flags, I_FLAG); + return op_pc; } diff --git a/src/codegen/codegen_ops_mmx_arith.c b/src/codegen/codegen_ops_mmx_arith.c index 1629fe6e..df252de2 100644 --- a/src/codegen/codegen_ops_mmx_arith.c +++ b/src/codegen/codegen_ops_mmx_arith.c @@ -10,48 +10,32 @@ #include "codegen_ops_mmx_arith.h" #include "codegen_ops_helpers.h" -#define ropParith(func) \ -uint32_t rop ## func(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - int dest_reg = (fetchdat >> 3) & 7; \ - \ - uop_MMX_ENTER(ir); \ - codegen_mark_code_present(block, cs+op_pc, 1); \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - int src_reg = fetchdat & 7; \ - uop_ ## func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); \ - } \ - else \ - { \ - x86seg *target_seg; \ - \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_ ## func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); \ - } \ - \ - return op_pc + 1; \ -} +#define ropParith(func) \ + uint32_t rop##func(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, \ + uint32_t op_pc) { \ + int dest_reg = (fetchdat >> 3) & 7; \ + \ + uop_MMX_ENTER(ir); \ + codegen_mark_code_present(block, cs + op_pc, 1); \ + if ((fetchdat & 0xc0) == 0xc0) { \ + int src_reg = fetchdat & 7; \ + uop_##func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); \ + } else { \ + x86seg *target_seg; \ + \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_##func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); \ + } \ + \ + return op_pc + 1; \ + } -ropParith(PADDB) -ropParith(PADDW) -ropParith(PADDD) -ropParith(PADDSB) -ropParith(PADDSW) -ropParith(PADDUSB) -ropParith(PADDUSW) +ropParith(PADDB) ropParith(PADDW) ropParith(PADDD) ropParith(PADDSB) ropParith(PADDSW) ropParith(PADDUSB) ropParith(PADDUSW) -ropParith(PSUBB) -ropParith(PSUBW) -ropParith(PSUBD) -ropParith(PSUBSB) -ropParith(PSUBSW) -ropParith(PSUBUSB) -ropParith(PSUBUSW) + ropParith(PSUBB) ropParith(PSUBW) ropParith(PSUBD) ropParith(PSUBSB) ropParith(PSUBSW) ropParith(PSUBUSB) + ropParith(PSUBUSW) -ropParith(PMADDWD) -ropParith(PMULHW) -ropParith(PMULLW) + ropParith(PMADDWD) ropParith(PMULHW) ropParith(PMULLW) diff --git a/src/codegen/codegen_ops_mmx_cmp.c b/src/codegen/codegen_ops_mmx_cmp.c index b7fe44d8..e30a1255 100644 --- a/src/codegen/codegen_ops_mmx_cmp.c +++ b/src/codegen/codegen_ops_mmx_cmp.c @@ -10,35 +10,27 @@ #include "codegen_ops_mmx_cmp.h" #include "codegen_ops_helpers.h" -#define ropPcmp(func) \ -uint32_t rop ## func(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - int dest_reg = (fetchdat >> 3) & 7; \ - \ - uop_MMX_ENTER(ir); \ - codegen_mark_code_present(block, cs+op_pc, 1); \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - int src_reg = fetchdat & 7; \ - uop_ ## func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); \ - } \ - else \ - { \ - x86seg *target_seg; \ - \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_ ## func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); \ - } \ - \ - return op_pc + 1; \ -} +#define ropPcmp(func) \ + uint32_t rop##func(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, \ + uint32_t op_pc) { \ + int dest_reg = (fetchdat >> 3) & 7; \ + \ + uop_MMX_ENTER(ir); \ + codegen_mark_code_present(block, cs + op_pc, 1); \ + if ((fetchdat & 0xc0) == 0xc0) { \ + int src_reg = fetchdat & 7; \ + uop_##func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); \ + } else { \ + x86seg *target_seg; \ + \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_##func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); \ + } \ + \ + return op_pc + 1; \ + } -ropPcmp(PCMPEQB) -ropPcmp(PCMPEQW) -ropPcmp(PCMPEQD) -ropPcmp(PCMPGTB) -ropPcmp(PCMPGTW) -ropPcmp(PCMPGTD) +ropPcmp(PCMPEQB) ropPcmp(PCMPEQW) ropPcmp(PCMPEQD) ropPcmp(PCMPGTB) ropPcmp(PCMPGTW) ropPcmp(PCMPGTD) diff --git a/src/codegen/codegen_ops_mmx_loadstore.c b/src/codegen/codegen_ops_mmx_loadstore.c index 671cbc27..1f8554d8 100644 --- a/src/codegen/codegen_ops_mmx_loadstore.c +++ b/src/codegen/codegen_ops_mmx_loadstore.c @@ -11,87 +11,87 @@ #include "codegen_ops_helpers.h" uint32_t ropMOVD_r_d(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - uop_MMX_ENTER(ir); - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int src_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_MM(dest_reg), IREG_32(src_reg)); - } else { - x86seg *target_seg; + uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_MOVZX(ir, IREG_MM(dest_reg), IREG_32(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVZX(ir, IREG_MM(dest_reg), IREG_temp0); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_MM(dest_reg), IREG_temp0); + } - return op_pc + 1; + return op_pc + 1; } uint32_t ropMOVD_d_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - if (cpu_iscyrix && (cpu_cur_status & CPU_STATUS_SMM)) - return 0; + if (cpu_iscyrix && (cpu_cur_status & CPU_STATUS_SMM)) + return 0; - uop_MMX_ENTER(ir); - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int dest_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_32(dest_reg), IREG_MM(src_reg)); - } else { - x86seg *target_seg; + uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + uop_MOVZX(ir, IREG_32(dest_reg), IREG_MM(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 3); - uop_MOVZX(ir, IREG_temp0, IREG_MM(src_reg)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 3); + uop_MOVZX(ir, IREG_temp0, IREG_MM(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + } - return op_pc + 1; + return op_pc + 1; } uint32_t ropMOVQ_r_q(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - uop_MMX_ENTER(ir); - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int src_reg = fetchdat & 7; - uop_MOV(ir, IREG_MM(dest_reg), IREG_MM(src_reg)); - } else { - x86seg *target_seg; + uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_MOV(ir, IREG_MM(dest_reg), IREG_MM(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_MM(dest_reg), ireg_seg_base(target_seg), IREG_eaaddr); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_MM(dest_reg), ireg_seg_base(target_seg), IREG_eaaddr); + } - return op_pc + 1; + return op_pc + 1; } uint32_t ropMOVQ_q_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - uop_MMX_ENTER(ir); - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int dest_reg = fetchdat & 7; - uop_MOV(ir, IREG_MM(dest_reg), IREG_MM(src_reg)); - } else { - x86seg *target_seg; + uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + uop_MOV(ir, IREG_MM(dest_reg), IREG_MM(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 7); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_MM(src_reg)); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 7); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_MM(src_reg)); + } - return op_pc + 1; + return op_pc + 1; } diff --git a/src/codegen/codegen_ops_mmx_logic.c b/src/codegen/codegen_ops_mmx_logic.c index 13214159..c4fb912a 100644 --- a/src/codegen/codegen_ops_mmx_logic.c +++ b/src/codegen/codegen_ops_mmx_logic.c @@ -11,82 +11,82 @@ #include "codegen_ops_helpers.h" uint32_t ropPAND(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - uop_MMX_ENTER(ir); - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int src_reg = fetchdat & 7; - uop_AND(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); - } else { - x86seg *target_seg; + uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_AND(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); - uop_AND(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); + uop_AND(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); + } - return op_pc + 1; + return op_pc + 1; } uint32_t ropPANDN(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - uop_MMX_ENTER(ir); - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int src_reg = fetchdat & 7; - uop_ANDN(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); - } else { - x86seg *target_seg; + uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_ANDN(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); - uop_ANDN(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); + uop_ANDN(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); + } - return op_pc + 1; + return op_pc + 1; } uint32_t ropPOR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - uop_MMX_ENTER(ir); - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int src_reg = fetchdat & 7; - uop_OR(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); - } else { - x86seg *target_seg; + uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_OR(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); - uop_OR(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); + uop_OR(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); + } - return op_pc + 1; + return op_pc + 1; } uint32_t ropPXOR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - uop_MMX_ENTER(ir); - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int src_reg = fetchdat & 7; - uop_XOR(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); - } else { - x86seg *target_seg; + uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_XOR(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); - uop_XOR(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); + uop_XOR(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); + } - return op_pc + 1; + return op_pc + 1; } diff --git a/src/codegen/codegen_ops_mmx_pack.c b/src/codegen/codegen_ops_mmx_pack.c index e625217c..6ba138dd 100644 --- a/src/codegen/codegen_ops_mmx_pack.c +++ b/src/codegen/codegen_ops_mmx_pack.c @@ -10,38 +10,28 @@ #include "codegen_ops_mmx_pack.h" #include "codegen_ops_helpers.h" -#define ropPpack(func) \ -uint32_t rop ## func(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - int dest_reg = (fetchdat >> 3) & 7; \ - \ - uop_MMX_ENTER(ir); \ - codegen_mark_code_present(block, cs+op_pc, 1); \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - int src_reg = fetchdat & 7; \ - uop_ ## func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); \ - } \ - else \ - { \ - x86seg *target_seg; \ - \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_ ## func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); \ - } \ - \ - return op_pc + 1; \ -} +#define ropPpack(func) \ + uint32_t rop##func(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, \ + uint32_t op_pc) { \ + int dest_reg = (fetchdat >> 3) & 7; \ + \ + uop_MMX_ENTER(ir); \ + codegen_mark_code_present(block, cs + op_pc, 1); \ + if ((fetchdat & 0xc0) == 0xc0) { \ + int src_reg = fetchdat & 7; \ + uop_##func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); \ + } else { \ + x86seg *target_seg; \ + \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_##func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); \ + } \ + \ + return op_pc + 1; \ + } -ropPpack(PACKSSWB) -ropPpack(PACKSSDW) -ropPpack(PACKUSWB) -ropPpack(PUNPCKLBW) -ropPpack(PUNPCKLWD) -ropPpack(PUNPCKLDQ) -ropPpack(PUNPCKHBW) -ropPpack(PUNPCKHWD) -ropPpack(PUNPCKHDQ) +ropPpack(PACKSSWB) ropPpack(PACKSSDW) ropPpack(PACKUSWB) ropPpack(PUNPCKLBW) ropPpack(PUNPCKLWD) ropPpack(PUNPCKLDQ) + ropPpack(PUNPCKHBW) ropPpack(PUNPCKHWD) ropPpack(PUNPCKHDQ) diff --git a/src/codegen/codegen_ops_mmx_shift.c b/src/codegen/codegen_ops_mmx_shift.c index 39f35c60..4da9d9ba 100644 --- a/src/codegen/codegen_ops_mmx_shift.c +++ b/src/codegen/codegen_ops_mmx_shift.c @@ -11,74 +11,74 @@ #include "codegen_ops_helpers.h" uint32_t ropPSxxW_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int reg = fetchdat & 7; - int op = fetchdat & 0x38; - int shift = fastreadb(cs + op_pc + 1); + int reg = fetchdat & 7; + int op = fetchdat & 0x38; + int shift = fastreadb(cs + op_pc + 1); - uop_MMX_ENTER(ir); - codegen_mark_code_present(block, cs + op_pc, 1); - switch (op) { - case 0x10: /*PSRLW*/ - uop_PSRLW_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); - break; - case 0x20: /*PSRAW*/ - uop_PSRAW_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); - break; - case 0x30: /*PSLLW*/ - uop_PSLLW_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); - break; - default:return 0; + uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs + op_pc, 1); + switch (op) { + case 0x10: /*PSRLW*/ + uop_PSRLW_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); + break; + case 0x20: /*PSRAW*/ + uop_PSRAW_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); + break; + case 0x30: /*PSLLW*/ + uop_PSLLW_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); + break; + default: + return 0; + } - } - - codegen_mark_code_present(block, cs + op_pc + 1, 1); - return op_pc + 2; + codegen_mark_code_present(block, cs + op_pc + 1, 1); + return op_pc + 2; } uint32_t ropPSxxD_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int reg = fetchdat & 7; - int op = fetchdat & 0x38; - int shift = fastreadb(cs + op_pc + 1); + int reg = fetchdat & 7; + int op = fetchdat & 0x38; + int shift = fastreadb(cs + op_pc + 1); - uop_MMX_ENTER(ir); - codegen_mark_code_present(block, cs + op_pc, 1); - switch (op) { - case 0x10: /*PSRLD*/ - uop_PSRLD_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); - break; - case 0x20: /*PSRAD*/ - uop_PSRAD_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); - break; - case 0x30: /*PSLLD*/ - uop_PSLLD_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); - break; - default:return 0; + uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs + op_pc, 1); + switch (op) { + case 0x10: /*PSRLD*/ + uop_PSRLD_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); + break; + case 0x20: /*PSRAD*/ + uop_PSRAD_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); + break; + case 0x30: /*PSLLD*/ + uop_PSLLD_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); + break; + default: + return 0; + } - } - - codegen_mark_code_present(block, cs + op_pc + 1, 1); - return op_pc + 2; + codegen_mark_code_present(block, cs + op_pc + 1, 1); + return op_pc + 2; } uint32_t ropPSxxQ_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int reg = fetchdat & 7; - int op = fetchdat & 0x38; - int shift = fastreadb(cs + op_pc + 1); + int reg = fetchdat & 7; + int op = fetchdat & 0x38; + int shift = fastreadb(cs + op_pc + 1); - uop_MMX_ENTER(ir); - codegen_mark_code_present(block, cs + op_pc, 1); - switch (op) { - case 0x10: /*PSRLQ*/ - uop_PSRLQ_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); - break; - case 0x20: /*PSRAQ*/ - uop_PSRAQ_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); - break; - case 0x30: /*PSLLQ*/ - uop_PSLLQ_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); - break; - default:return 0; + uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs + op_pc, 1); + switch (op) { + case 0x10: /*PSRLQ*/ + uop_PSRLQ_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); + break; + case 0x20: /*PSRAQ*/ + uop_PSRAQ_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); + break; + case 0x30: /*PSLLQ*/ + uop_PSLLQ_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); + break; + default: + return 0; + } - } - - codegen_mark_code_present(block, cs + op_pc + 1, 1); - return op_pc + 2; + codegen_mark_code_present(block, cs + op_pc + 1, 1); + return op_pc + 2; } diff --git a/src/codegen/codegen_ops_mov.c b/src/codegen/codegen_ops_mov.c index 739963f8..92886a8d 100644 --- a/src/codegen/codegen_ops_mov.c +++ b/src/codegen/codegen_ops_mov.c @@ -9,650 +9,653 @@ #include "codegen_ops_mov.h" uint32_t ropMOV_rb_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint8_t imm = fastreadb(cs + op_pc); + uint8_t imm = fastreadb(cs + op_pc); - uop_MOV_IMM(ir, IREG_8(opcode & 7), imm); + uop_MOV_IMM(ir, IREG_8(opcode & 7), imm); - codegen_mark_code_present(block, cs + op_pc, 1); - return op_pc + 1; + codegen_mark_code_present(block, cs + op_pc, 1); + return op_pc + 1; } uint32_t ropMOV_rw_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint16_t imm = fastreadw(cs + op_pc); + uint16_t imm = fastreadw(cs + op_pc); - uop_MOV_IMM(ir, IREG_16(opcode & 7), imm); + uop_MOV_IMM(ir, IREG_16(opcode & 7), imm); - codegen_mark_code_present(block, cs + op_pc, 2); - return op_pc + 2; + codegen_mark_code_present(block, cs + op_pc, 2); + return op_pc + 2; } uint32_t ropMOV_rl_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - if (block->flags & CODEBLOCK_NO_IMMEDIATES) { - LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_32(opcode & 7), cs + op_pc); - } else { - fetchdat = fastreadl(cs + op_pc); - uop_MOV_IMM(ir, IREG_32(opcode & 7), fetchdat); - codegen_mark_code_present(block, cs + op_pc, 4); - } - return op_pc + 4; + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_32(opcode & 7), cs + op_pc); + } else { + fetchdat = fastreadl(cs + op_pc); + uop_MOV_IMM(ir, IREG_32(opcode & 7), fetchdat); + codegen_mark_code_present(block, cs + op_pc, 4); + } + return op_pc + 4; } uint32_t ropMOV_b_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; -// if (block->phys == 0x49a400) -// pclog("ropMOVb_rmarkcode %08x 1\n", cs+op_pc); - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int dest_reg = fetchdat & 7; - uop_MOV(ir, IREG_8(dest_reg), IREG_8(src_reg)); - } else { - x86seg *target_seg; + // if (block->phys == 0x49a400) + // pclog("ropMOVb_rmarkcode %08x 1\n", cs+op_pc); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + uop_MOV(ir, IREG_8(dest_reg), IREG_8(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 0); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_8(src_reg)); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 0); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_8(src_reg)); + } - return op_pc + 1; + return op_pc + 1; } uint32_t ropMOV_w_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int dest_reg = fetchdat & 7; - uop_MOV(ir, IREG_16(dest_reg), IREG_16(src_reg)); - } else { - x86seg *target_seg; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + uop_MOV(ir, IREG_16(dest_reg), IREG_16(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 1); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_16(src_reg)); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 1); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_16(src_reg)); + } - return op_pc + 1; + return op_pc + 1; } uint32_t ropMOV_l_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int dest_reg = fetchdat & 7; - uop_MOV(ir, IREG_32(dest_reg), IREG_32(src_reg)); - } else { - x86seg *target_seg; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + uop_MOV(ir, IREG_32(dest_reg), IREG_32(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 3); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_32(src_reg)); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 3); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_32(src_reg)); + } - return op_pc + 1; + return op_pc + 1; } uint32_t ropMOV_r_b(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int src_reg = fetchdat & 7; - uop_MOV(ir, IREG_8(dest_reg), IREG_8(src_reg)); - } else { - x86seg *target_seg; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_MOV(ir, IREG_8(dest_reg), IREG_8(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_8(dest_reg), ireg_seg_base(target_seg), IREG_eaaddr); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_8(dest_reg), ireg_seg_base(target_seg), IREG_eaaddr); + } - return op_pc + 1; + return op_pc + 1; } uint32_t ropMOV_r_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int src_reg = fetchdat & 7; - uop_MOV(ir, IREG_16(dest_reg), IREG_16(src_reg)); - } else { - x86seg *target_seg; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_MOV(ir, IREG_16(dest_reg), IREG_16(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_16(dest_reg), ireg_seg_base(target_seg), IREG_eaaddr); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_16(dest_reg), ireg_seg_base(target_seg), IREG_eaaddr); + } - return op_pc + 1; + return op_pc + 1; } uint32_t ropMOV_r_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int src_reg = fetchdat & 7; - uop_MOV(ir, IREG_32(dest_reg), IREG_32(src_reg)); - } else { - x86seg *target_seg; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_MOV(ir, IREG_32(dest_reg), IREG_32(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_32(dest_reg), ireg_seg_base(target_seg), IREG_eaaddr); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_32(dest_reg), ireg_seg_base(target_seg), IREG_eaaddr); + } - return op_pc + 1; + return op_pc + 1; } uint32_t ropMOV_AL_abs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint32_t addr; + uint32_t addr; - if (op_32 & 0x200) - addr = fastreadl(cs + op_pc); - else - addr = fastreadw(cs + op_pc); + if (op_32 & 0x200) + addr = fastreadl(cs + op_pc); + else + addr = fastreadw(cs + op_pc); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - codegen_check_seg_read(block, ir, op_ea_seg); - uop_MEM_LOAD_ABS(ir, IREG_AL, ireg_seg_base(op_ea_seg), addr); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + codegen_check_seg_read(block, ir, op_ea_seg); + uop_MEM_LOAD_ABS(ir, IREG_AL, ireg_seg_base(op_ea_seg), addr); - codegen_mark_code_present(block, cs + op_pc, (op_32 & 0x200) ? 4 : 2); - return op_pc + ((op_32 & 0x200) ? 4 : 2); + codegen_mark_code_present(block, cs + op_pc, (op_32 & 0x200) ? 4 : 2); + return op_pc + ((op_32 & 0x200) ? 4 : 2); } uint32_t ropMOV_AX_abs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint32_t addr; + uint32_t addr; - if (op_32 & 0x200) - addr = fastreadl(cs + op_pc); - else - addr = fastreadw(cs + op_pc); + if (op_32 & 0x200) + addr = fastreadl(cs + op_pc); + else + addr = fastreadw(cs + op_pc); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - codegen_check_seg_read(block, ir, op_ea_seg); - uop_MEM_LOAD_ABS(ir, IREG_AX, ireg_seg_base(op_ea_seg), addr); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + codegen_check_seg_read(block, ir, op_ea_seg); + uop_MEM_LOAD_ABS(ir, IREG_AX, ireg_seg_base(op_ea_seg), addr); - codegen_mark_code_present(block, cs + op_pc, (op_32 & 0x200) ? 4 : 2); - return op_pc + ((op_32 & 0x200) ? 4 : 2); + codegen_mark_code_present(block, cs + op_pc, (op_32 & 0x200) ? 4 : 2); + return op_pc + ((op_32 & 0x200) ? 4 : 2); } uint32_t ropMOV_EAX_abs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint32_t addr = 0; + uint32_t addr = 0; - if (op_32 & 0x200) { - if (block->flags & CODEBLOCK_NO_IMMEDIATES) { - LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_eaaddr, cs + op_pc); - } else { - addr = fastreadl(cs + op_pc); - codegen_mark_code_present(block, cs + op_pc, 4); - } - } else { - addr = fastreadw(cs + op_pc); - codegen_mark_code_present(block, cs + op_pc, 2); - } + if (op_32 & 0x200) { + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_eaaddr, cs + op_pc); + } else { + addr = fastreadl(cs + op_pc); + codegen_mark_code_present(block, cs + op_pc, 4); + } + } else { + addr = fastreadw(cs + op_pc); + codegen_mark_code_present(block, cs + op_pc, 2); + } - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - codegen_check_seg_read(block, ir, op_ea_seg); - if ((block->flags & CODEBLOCK_NO_IMMEDIATES) && (op_32 & 0x200)) - uop_MEM_LOAD_REG(ir, IREG_EAX, ireg_seg_base(op_ea_seg), IREG_eaaddr); - else - uop_MEM_LOAD_ABS(ir, IREG_EAX, ireg_seg_base(op_ea_seg), addr); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + codegen_check_seg_read(block, ir, op_ea_seg); + if ((block->flags & CODEBLOCK_NO_IMMEDIATES) && (op_32 & 0x200)) + uop_MEM_LOAD_REG(ir, IREG_EAX, ireg_seg_base(op_ea_seg), IREG_eaaddr); + else + uop_MEM_LOAD_ABS(ir, IREG_EAX, ireg_seg_base(op_ea_seg), addr); - return op_pc + ((op_32 & 0x200) ? 4 : 2); + return op_pc + ((op_32 & 0x200) ? 4 : 2); } uint32_t ropMOV_abs_AL(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint32_t addr; + uint32_t addr; - if (op_32 & 0x200) - addr = fastreadl(cs + op_pc); - else - addr = fastreadw(cs + op_pc); + if (op_32 & 0x200) + addr = fastreadl(cs + op_pc); + else + addr = fastreadw(cs + op_pc); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - codegen_check_seg_write(block, ir, op_ea_seg); - uop_MEM_STORE_ABS(ir, ireg_seg_base(op_ea_seg), addr, IREG_AL); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + codegen_check_seg_write(block, ir, op_ea_seg); + uop_MEM_STORE_ABS(ir, ireg_seg_base(op_ea_seg), addr, IREG_AL); - codegen_mark_code_present(block, cs + op_pc, (op_32 & 0x200) ? 4 : 2); - return op_pc + ((op_32 & 0x200) ? 4 : 2); + codegen_mark_code_present(block, cs + op_pc, (op_32 & 0x200) ? 4 : 2); + return op_pc + ((op_32 & 0x200) ? 4 : 2); } uint32_t ropMOV_abs_AX(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint32_t addr; + uint32_t addr; - if (op_32 & 0x200) - addr = fastreadl(cs + op_pc); - else - addr = fastreadw(cs + op_pc); + if (op_32 & 0x200) + addr = fastreadl(cs + op_pc); + else + addr = fastreadw(cs + op_pc); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - codegen_check_seg_write(block, ir, op_ea_seg); - uop_MEM_STORE_ABS(ir, ireg_seg_base(op_ea_seg), addr, IREG_AX); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + codegen_check_seg_write(block, ir, op_ea_seg); + uop_MEM_STORE_ABS(ir, ireg_seg_base(op_ea_seg), addr, IREG_AX); - codegen_mark_code_present(block, cs + op_pc, (op_32 & 0x200) ? 4 : 2); - return op_pc + ((op_32 & 0x200) ? 4 : 2); + codegen_mark_code_present(block, cs + op_pc, (op_32 & 0x200) ? 4 : 2); + return op_pc + ((op_32 & 0x200) ? 4 : 2); } uint32_t ropMOV_abs_EAX(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint32_t addr; + uint32_t addr; - if (op_32 & 0x200) - addr = fastreadl(cs + op_pc); - else - addr = fastreadw(cs + op_pc); + if (op_32 & 0x200) + addr = fastreadl(cs + op_pc); + else + addr = fastreadw(cs + op_pc); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - codegen_check_seg_write(block, ir, op_ea_seg); - uop_MEM_STORE_ABS(ir, ireg_seg_base(op_ea_seg), addr, IREG_EAX); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + codegen_check_seg_write(block, ir, op_ea_seg); + uop_MEM_STORE_ABS(ir, ireg_seg_base(op_ea_seg), addr, IREG_EAX); - codegen_mark_code_present(block, cs + op_pc, (op_32 & 0x200) ? 4 : 2); - return op_pc + ((op_32 & 0x200) ? 4 : 2); + codegen_mark_code_present(block, cs + op_pc, (op_32 & 0x200) ? 4 : 2); + return op_pc + ((op_32 & 0x200) ? 4 : 2); } uint32_t ropMOV_b_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg; - uint8_t imm; + x86seg *target_seg; + uint8_t imm; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int dest_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - imm = fastreadb(cs + op_pc + 1); - uop_MOV_IMM(ir, IREG_8(dest_reg), imm); - } else { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - imm = fastreadb(cs + op_pc + 1); - uop_MEM_STORE_IMM_8(ir, ireg_seg_base(target_seg), IREG_eaaddr, imm); - } + imm = fastreadb(cs + op_pc + 1); + uop_MOV_IMM(ir, IREG_8(dest_reg), imm); + } else { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + imm = fastreadb(cs + op_pc + 1); + uop_MEM_STORE_IMM_8(ir, ireg_seg_base(target_seg), IREG_eaaddr, imm); + } - codegen_mark_code_present(block, cs + op_pc + 1, 1); - return op_pc + 2; + codegen_mark_code_present(block, cs + op_pc + 1, 1); + return op_pc + 2; } uint32_t ropMOV_w_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg; - uint16_t imm; + x86seg *target_seg; + uint16_t imm; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int dest_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - imm = fastreadw(cs + op_pc + 1); - uop_MOV_IMM(ir, IREG_16(dest_reg), imm); - } else { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - imm = fastreadw(cs + op_pc + 1); - uop_MEM_STORE_IMM_16(ir, ireg_seg_base(target_seg), IREG_eaaddr, imm); - } + imm = fastreadw(cs + op_pc + 1); + uop_MOV_IMM(ir, IREG_16(dest_reg), imm); + } else { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + imm = fastreadw(cs + op_pc + 1); + uop_MEM_STORE_IMM_16(ir, ireg_seg_base(target_seg), IREG_eaaddr, imm); + } - codegen_mark_code_present(block, cs + op_pc + 1, 2); - return op_pc + 3; + codegen_mark_code_present(block, cs + op_pc + 1, 2); + return op_pc + 3; } uint32_t ropMOV_l_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg; - uint32_t imm; + x86seg *target_seg; + uint32_t imm; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int dest_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - imm = fastreadl(cs + op_pc + 1); - uop_MOV_IMM(ir, IREG_32(dest_reg), imm); - } else { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - imm = fastreadl(cs + op_pc + 1); - uop_MEM_STORE_IMM_32(ir, ireg_seg_base(target_seg), IREG_eaaddr, imm); - } + imm = fastreadl(cs + op_pc + 1); + uop_MOV_IMM(ir, IREG_32(dest_reg), imm); + } else { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + imm = fastreadl(cs + op_pc + 1); + uop_MEM_STORE_IMM_32(ir, ireg_seg_base(target_seg), IREG_eaaddr, imm); + } - codegen_mark_code_present(block, cs + op_pc + 1, 4); - return op_pc + 5; + codegen_mark_code_present(block, cs + op_pc + 1, 4); + return op_pc + 5; } uint32_t ropMOV_w_seg(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg; + int src_reg; - codegen_mark_code_present(block, cs + op_pc, 1); - switch (fetchdat & 0x38) { - case 0x00: /*ES*/ - src_reg = IREG_ES_seg_W; - break; - case 0x08: /*CS*/ - src_reg = IREG_CS_seg_W; - break; - case 0x18: /*DS*/ - src_reg = IREG_DS_seg_W; - break; - case 0x10: /*SS*/ - src_reg = IREG_SS_seg_W; - break; - case 0x20: /*FS*/ - src_reg = IREG_FS_seg_W; - break; - case 0x28: /*GS*/ - src_reg = IREG_GS_seg_W; - break; - default:return 0; - } + codegen_mark_code_present(block, cs + op_pc, 1); + switch (fetchdat & 0x38) { + case 0x00: /*ES*/ + src_reg = IREG_ES_seg_W; + break; + case 0x08: /*CS*/ + src_reg = IREG_CS_seg_W; + break; + case 0x18: /*DS*/ + src_reg = IREG_DS_seg_W; + break; + case 0x10: /*SS*/ + src_reg = IREG_SS_seg_W; + break; + case 0x20: /*FS*/ + src_reg = IREG_FS_seg_W; + break; + case 0x28: /*GS*/ + src_reg = IREG_GS_seg_W; + break; + default: + return 0; + } - if ((fetchdat & 0xc0) == 0xc0) { - int dest_reg = fetchdat & 7; - uop_MOV(ir, IREG_16(dest_reg), src_reg); - } else { - x86seg *target_seg; + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + uop_MOV(ir, IREG_16(dest_reg), src_reg); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 1); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, src_reg); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 1); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, src_reg); + } - return op_pc + 1; + return op_pc + 1; } uint32_t ropMOV_l_seg(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg; + int src_reg; - codegen_mark_code_present(block, cs + op_pc, 1); - switch (fetchdat & 0x38) { - case 0x00: /*ES*/ - src_reg = IREG_ES_seg_W; - break; - case 0x08: /*CS*/ - src_reg = IREG_CS_seg_W; - break; - case 0x18: /*DS*/ - src_reg = IREG_DS_seg_W; - break; - case 0x10: /*SS*/ - src_reg = IREG_SS_seg_W; - break; - case 0x20: /*FS*/ - src_reg = IREG_FS_seg_W; - break; - case 0x28: /*GS*/ - src_reg = IREG_GS_seg_W; - break; - default:return 0; - } + codegen_mark_code_present(block, cs + op_pc, 1); + switch (fetchdat & 0x38) { + case 0x00: /*ES*/ + src_reg = IREG_ES_seg_W; + break; + case 0x08: /*CS*/ + src_reg = IREG_CS_seg_W; + break; + case 0x18: /*DS*/ + src_reg = IREG_DS_seg_W; + break; + case 0x10: /*SS*/ + src_reg = IREG_SS_seg_W; + break; + case 0x20: /*FS*/ + src_reg = IREG_FS_seg_W; + break; + case 0x28: /*GS*/ + src_reg = IREG_GS_seg_W; + break; + default: + return 0; + } - if ((fetchdat & 0xc0) == 0xc0) { - int dest_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_32(dest_reg), src_reg); - } else { - x86seg *target_seg; + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + uop_MOVZX(ir, IREG_32(dest_reg), src_reg); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, src_reg); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, src_reg); + } - return op_pc + 1; + return op_pc + 1; } uint32_t ropMOV_seg_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg; - x86seg *rseg; + int src_reg; + x86seg *rseg; - codegen_mark_code_present(block, cs + op_pc, 1); - switch (fetchdat & 0x38) { - case 0x00: /*ES*/ - rseg = &cpu_state.seg_es; - break; - case 0x18: /*DS*/ - rseg = &cpu_state.seg_ds; - break; - case 0x20: /*FS*/ - rseg = &cpu_state.seg_fs; - break; - case 0x28: /*GS*/ - rseg = &cpu_state.seg_gs; - break; - default:return 0; - } + codegen_mark_code_present(block, cs + op_pc, 1); + switch (fetchdat & 0x38) { + case 0x00: /*ES*/ + rseg = &cpu_state.seg_es; + break; + case 0x18: /*DS*/ + rseg = &cpu_state.seg_ds; + break; + case 0x20: /*FS*/ + rseg = &cpu_state.seg_fs; + break; + case 0x28: /*GS*/ + rseg = &cpu_state.seg_gs; + break; + default: + return 0; + } - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - if ((fetchdat & 0xc0) == 0xc0) { - uop_MOV(ir, IREG_temp0_W, IREG_16(fetchdat & 7)); - src_reg = IREG_temp0_W; - } else { - x86seg *target_seg; + if ((fetchdat & 0xc0) == 0xc0) { + uop_MOV(ir, IREG_temp0_W, IREG_16(fetchdat & 7)); + src_reg = IREG_temp0_W; + } else { + x86seg *target_seg; - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - src_reg = IREG_temp0_W; - } + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + src_reg = IREG_temp0_W; + } - uop_LOAD_SEG(ir, rseg, src_reg); + uop_LOAD_SEG(ir, rseg, src_reg); - return op_pc + 1; + return op_pc + 1; } uint32_t ropMOVSX_16_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int src_reg = fetchdat & 7; - uop_MOVSX(ir, IREG_16(dest_reg), IREG_8(src_reg)); - } else { - x86seg *target_seg; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_MOVSX(ir, IREG_16(dest_reg), IREG_8(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVSX(ir, IREG_16(dest_reg), IREG_temp0_B); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVSX(ir, IREG_16(dest_reg), IREG_temp0_B); + } - return op_pc + 1; + return op_pc + 1; } uint32_t ropMOVSX_32_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int src_reg = fetchdat & 7; - uop_MOVSX(ir, IREG_32(dest_reg), IREG_8(src_reg)); - } else { - x86seg *target_seg; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_MOVSX(ir, IREG_32(dest_reg), IREG_8(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVSX(ir, IREG_32(dest_reg), IREG_temp0_B); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVSX(ir, IREG_32(dest_reg), IREG_temp0_B); + } - return op_pc + 1; + return op_pc + 1; } uint32_t ropMOVSX_32_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int src_reg = fetchdat & 7; - uop_MOVSX(ir, IREG_32(dest_reg), IREG_16(src_reg)); - } else { - x86seg *target_seg; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_MOVSX(ir, IREG_32(dest_reg), IREG_16(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVSX(ir, IREG_32(dest_reg), IREG_temp0_W); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVSX(ir, IREG_32(dest_reg), IREG_temp0_W); + } - return op_pc + 1; + return op_pc + 1; } uint32_t ropMOVZX_16_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int src_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_16(dest_reg), IREG_8(src_reg)); - } else { - x86seg *target_seg; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_MOVZX(ir, IREG_16(dest_reg), IREG_8(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVZX(ir, IREG_16(dest_reg), IREG_temp0_B); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_16(dest_reg), IREG_temp0_B); + } - return op_pc + 1; + return op_pc + 1; } uint32_t ropMOVZX_32_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int src_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_32(dest_reg), IREG_8(src_reg)); - } else { - x86seg *target_seg; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_MOVZX(ir, IREG_32(dest_reg), IREG_8(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVZX(ir, IREG_32(dest_reg), IREG_temp0_B); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_32(dest_reg), IREG_temp0_B); + } - return op_pc + 1; + return op_pc + 1; } uint32_t ropMOVZX_32_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int src_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_32(dest_reg), IREG_16(src_reg)); - } else { - x86seg *target_seg; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_MOVZX(ir, IREG_32(dest_reg), IREG_16(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVZX(ir, IREG_32(dest_reg), IREG_temp0_W); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_32(dest_reg), IREG_temp0_W); + } - return op_pc + 1; + return op_pc + 1; } uint32_t ropXCHG_AX(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int reg2 = IREG_16(opcode & 7); + int reg2 = IREG_16(opcode & 7); - uop_MOV(ir, IREG_temp0_W, IREG_AX); - uop_MOV(ir, IREG_AX, reg2); - uop_MOV(ir, reg2, IREG_temp0_W); + uop_MOV(ir, IREG_temp0_W, IREG_AX); + uop_MOV(ir, IREG_AX, reg2); + uop_MOV(ir, reg2, IREG_temp0_W); - return op_pc; + return op_pc; } uint32_t ropXCHG_EAX(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int reg2 = IREG_32(opcode & 7); + int reg2 = IREG_32(opcode & 7); - uop_MOV(ir, IREG_temp0, IREG_EAX); - uop_MOV(ir, IREG_EAX, reg2); - uop_MOV(ir, reg2, IREG_temp0); + uop_MOV(ir, IREG_temp0, IREG_EAX); + uop_MOV(ir, IREG_EAX, reg2); + uop_MOV(ir, reg2, IREG_temp0); - return op_pc; + return op_pc; } uint32_t ropXCHG_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int reg1 = IREG_8((fetchdat >> 3) & 7); + int reg1 = IREG_8((fetchdat >> 3) & 7); - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int reg2 = IREG_8(fetchdat & 7); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int reg2 = IREG_8(fetchdat & 7); - uop_MOV(ir, IREG_temp0_B, reg1); - uop_MOV(ir, reg1, reg2); - uop_MOV(ir, reg2, IREG_temp0_B); - } else { - x86seg *target_seg; + uop_MOV(ir, IREG_temp0_B, reg1); + uop_MOV(ir, reg1, reg2); + uop_MOV(ir, reg2, IREG_temp0_B); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, reg1); - uop_MOV(ir, reg1, IREG_temp0_B); - } + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, reg1); + uop_MOV(ir, reg1, IREG_temp0_B); + } - return op_pc + 1; + return op_pc + 1; } uint32_t ropXCHG_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int reg1 = IREG_16((fetchdat >> 3) & 7); + int reg1 = IREG_16((fetchdat >> 3) & 7); - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int reg2 = IREG_16(fetchdat & 7); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int reg2 = IREG_16(fetchdat & 7); - uop_MOV(ir, IREG_temp0_W, reg1); - uop_MOV(ir, reg1, reg2); - uop_MOV(ir, reg2, IREG_temp0_W); - } else { - x86seg *target_seg; + uop_MOV(ir, IREG_temp0_W, reg1); + uop_MOV(ir, reg1, reg2); + uop_MOV(ir, reg2, IREG_temp0_W); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, reg1); - uop_MOV(ir, reg1, IREG_temp0_W); - } + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, reg1); + uop_MOV(ir, reg1, IREG_temp0_W); + } - return op_pc + 1; + return op_pc + 1; } uint32_t ropXCHG_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int reg1 = IREG_32((fetchdat >> 3) & 7); + int reg1 = IREG_32((fetchdat >> 3) & 7); - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int reg2 = IREG_32(fetchdat & 7); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int reg2 = IREG_32(fetchdat & 7); - uop_MOV(ir, IREG_temp0, reg1); - uop_MOV(ir, reg1, reg2); - uop_MOV(ir, reg2, IREG_temp0); - } else { - x86seg *target_seg; + uop_MOV(ir, IREG_temp0, reg1); + uop_MOV(ir, reg1, reg2); + uop_MOV(ir, reg2, IREG_temp0); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, reg1); - uop_MOV(ir, reg1, IREG_temp0); - } + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, reg1); + uop_MOV(ir, reg1, IREG_temp0); + } - return op_pc + 1; + return op_pc + 1; } uint32_t ropXLAT(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - uop_MOVZX(ir, IREG_eaaddr, IREG_AL); - uop_ADD(ir, IREG_eaaddr, IREG_eaaddr, IREG_EBX); - if (!(op_32 & 0x200)) - uop_AND_IMM(ir, IREG_eaaddr, IREG_eaaddr, 0xffff); + uop_MOVZX(ir, IREG_eaaddr, IREG_AL); + uop_ADD(ir, IREG_eaaddr, IREG_eaaddr, IREG_EBX); + if (!(op_32 & 0x200)) + uop_AND_IMM(ir, IREG_eaaddr, IREG_eaaddr, 0xffff); - uop_MEM_LOAD_REG(ir, IREG_AL, ireg_seg_base(op_ea_seg), IREG_eaaddr); + uop_MEM_LOAD_REG(ir, IREG_AL, ireg_seg_base(op_ea_seg), IREG_eaaddr); - return op_pc; + return op_pc; } diff --git a/src/codegen/codegen_ops_shift.c b/src/codegen/codegen_ops_shift.c index 2d142cba..ca0e59ab 100644 --- a/src/codegen/codegen_ops_shift.c +++ b/src/codegen/codegen_ops_shift.c @@ -11,1048 +11,1062 @@ #include "codegen_ops_shift.h" static uint32_t shift_common_8(ir_data_t *ir, uint32_t fetchdat, uint32_t op_pc, x86seg *target_seg, int count) { - if ((fetchdat & 0xc0) == 0xc0) { - int dest_reg = fetchdat & 7; + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - switch (fetchdat & 0x38) { - case 0x00: /*ROL*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROL_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - break; + switch (fetchdat & 0x38) { + case 0x00: /*ROL*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROL_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; - case 0x08: /*ROR*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROR_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - break; + case 0x08: /*ROR*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROR_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; - case 0x20: - case 0x30: /*SHL*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_SHL_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), count); - uop_MOV_IMM(ir, IREG_flags_op2, count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - break; + case 0x20: + case 0x30: /*SHL*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_SHL_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; - case 0x28: /*SHR*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_SHR_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), count); - uop_MOV_IMM(ir, IREG_flags_op2, count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - break; + case 0x28: /*SHR*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_SHR_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; - case 0x38: /*SAR*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_SAR_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), count); - uop_MOV_IMM(ir, IREG_flags_op2, count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - break; + case 0x38: /*SAR*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_SAR_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; - default:return 0; - } - } else { - switch (fetchdat & 0x38) { - case 0x00: /*ROL*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROL_IMM(ir, IREG_temp0_B, IREG_temp0_B, count); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL8); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); - break; + default: + return 0; + } + } else { + switch (fetchdat & 0x38) { + case 0x00: /*ROL*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROL_IMM(ir, IREG_temp0_B, IREG_temp0_B, count); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL8); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); + break; - case 0x08: /*ROR*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROR_IMM(ir, IREG_temp0_B, IREG_temp0_B, count); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR8); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); - break; + case 0x08: /*ROR*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROR_IMM(ir, IREG_temp0_B, IREG_temp0_B, count); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR8); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); + break; - case 0x20: - case 0x30: /*SHL*/ - uop_SHL_IMM(ir, IREG_temp1_B, IREG_temp0_B, count); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); - uop_MOV_IMM(ir, IREG_flags_op2, count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL8); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); - break; + case 0x20: + case 0x30: /*SHL*/ + uop_SHL_IMM(ir, IREG_temp1_B, IREG_temp0_B, count); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL8); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + break; - case 0x28: /*SHR*/ - uop_SHR_IMM(ir, IREG_temp1_B, IREG_temp0_B, count); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); - uop_MOV_IMM(ir, IREG_flags_op2, count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR8); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); - break; + case 0x28: /*SHR*/ + uop_SHR_IMM(ir, IREG_temp1_B, IREG_temp0_B, count); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR8); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + break; - case 0x38: /*SAR*/ - uop_SAR_IMM(ir, IREG_temp1_B, IREG_temp0_B, count); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); - uop_MOV_IMM(ir, IREG_flags_op2, count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR8); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); - break; + case 0x38: /*SAR*/ + uop_SAR_IMM(ir, IREG_temp1_B, IREG_temp0_B, count); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR8); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + break; - default:return 0; - } - } + default: + return 0; + } + } - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } static uint32_t shift_common_16(ir_data_t *ir, uint32_t fetchdat, uint32_t op_pc, x86seg *target_seg, int count) { - if ((fetchdat & 0xc0) == 0xc0) { - int dest_reg = fetchdat & 7; + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - switch (fetchdat & 0x38) { - case 0x00: /*ROL*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROL_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; + switch (fetchdat & 0x38) { + case 0x00: /*ROL*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROL_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; - case 0x08: /*ROR*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; + case 0x08: /*ROR*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; - case 0x20: - case 0x30: /*SHL*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_SHL_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), count); - uop_MOV_IMM(ir, IREG_flags_op2, count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; + case 0x20: + case 0x30: /*SHL*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_SHL_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; - case 0x28: /*SHR*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_SHR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), count); - uop_MOV_IMM(ir, IREG_flags_op2, count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; + case 0x28: /*SHR*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_SHR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; - case 0x38: /*SAR*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_SAR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), count); - uop_MOV_IMM(ir, IREG_flags_op2, count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; + case 0x38: /*SAR*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_SAR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; - default:return 0; - } - } else { - switch (fetchdat & 0x38) { - case 0x00: /*ROL*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROL_IMM(ir, IREG_temp0_W, IREG_temp0_W, count); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL16); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); - break; + default: + return 0; + } + } else { + switch (fetchdat & 0x38) { + case 0x00: /*ROL*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROL_IMM(ir, IREG_temp0_W, IREG_temp0_W, count); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + break; - case 0x08: /*ROR*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROR_IMM(ir, IREG_temp0_W, IREG_temp0_W, count); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR16); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); - break; + case 0x08: /*ROR*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROR_IMM(ir, IREG_temp0_W, IREG_temp0_W, count); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + break; - case 0x20: - case 0x30: /*SHL*/ - uop_SHL_IMM(ir, IREG_temp1_W, IREG_temp0_W, count); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op2, count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL16); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - break; + case 0x20: + case 0x30: /*SHL*/ + uop_SHL_IMM(ir, IREG_temp1_W, IREG_temp0_W, count); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + break; - case 0x28: /*SHR*/ - uop_SHR_IMM(ir, IREG_temp1_W, IREG_temp0_W, count); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op2, count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR16); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - break; + case 0x28: /*SHR*/ + uop_SHR_IMM(ir, IREG_temp1_W, IREG_temp0_W, count); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + break; - case 0x38: /*SAR*/ - uop_SAR_IMM(ir, IREG_temp1_W, IREG_temp0_W, count); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op2, count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR16); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - break; + case 0x38: /*SAR*/ + uop_SAR_IMM(ir, IREG_temp1_W, IREG_temp0_W, count); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + break; - default:return 0; - } - } + default: + return 0; + } + } - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } static uint32_t shift_common_32(ir_data_t *ir, uint32_t fetchdat, uint32_t op_pc, x86seg *target_seg, int count) { - if ((fetchdat & 0xc0) == 0xc0) { - int dest_reg = fetchdat & 7; + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - switch (fetchdat & 0x38) { - case 0x00: /*ROL*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROL_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; + switch (fetchdat & 0x38) { + case 0x00: /*ROL*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROL_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; - case 0x08: /*ROR*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; + case 0x08: /*ROR*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; - case 0x20: - case 0x30: /*SHL*/ - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_SHL_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), count); - uop_MOV_IMM(ir, IREG_flags_op2, count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; + case 0x20: + case 0x30: /*SHL*/ + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SHL_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; - case 0x28: /*SHR*/ - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_SHR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), count); - uop_MOV_IMM(ir, IREG_flags_op2, count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; + case 0x28: /*SHR*/ + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SHR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; - case 0x38: /*SAR*/ - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_SAR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), count); - uop_MOV_IMM(ir, IREG_flags_op2, count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; + case 0x38: /*SAR*/ + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SAR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; - default:return 0; - } - } else { - switch (fetchdat & 0x38) { - case 0x00: /*ROL*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROL_IMM(ir, IREG_temp0, IREG_temp0, count); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL32); - uop_MOV(ir, IREG_flags_res, IREG_temp0); - break; + default: + return 0; + } + } else { + switch (fetchdat & 0x38) { + case 0x00: /*ROL*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROL_IMM(ir, IREG_temp0, IREG_temp0, count); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL32); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + break; - case 0x08: /*ROR*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROR_IMM(ir, IREG_temp0, IREG_temp0, count); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR32); - uop_MOV(ir, IREG_flags_res, IREG_temp0); - break; + case 0x08: /*ROR*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROR_IMM(ir, IREG_temp0, IREG_temp0, count); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR32); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + break; - case 0x20: - case 0x30: /*SHL*/ - uop_SHL_IMM(ir, IREG_temp1, IREG_temp0, count); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op2, count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - break; + case 0x20: + case 0x30: /*SHL*/ + uop_SHL_IMM(ir, IREG_temp1, IREG_temp0, count); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; - case 0x28: /*SHR*/ - uop_SHR_IMM(ir, IREG_temp1, IREG_temp0, count); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op2, count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - break; + case 0x28: /*SHR*/ + uop_SHR_IMM(ir, IREG_temp1, IREG_temp0, count); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; - case 0x38: /*SAR*/ - uop_SAR_IMM(ir, IREG_temp1, IREG_temp0, count); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op2, count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR32); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - break; + case 0x38: /*SAR*/ + uop_SAR_IMM(ir, IREG_temp1, IREG_temp0, count); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; - default:return 0; - } - } + default: + return 0; + } + } - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } static uint32_t shift_common_variable_32(ir_data_t *ir, uint32_t fetchdat, uint32_t op_pc, x86seg *target_seg, int count_reg) { - if ((fetchdat & 0xc0) == 0xc0) { - int dest_reg = fetchdat & 7; + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - switch (fetchdat & 0x38) { - case 0x00: /*ROL*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROL(ir, IREG_32(dest_reg), IREG_32(dest_reg), count_reg); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; + switch (fetchdat & 0x38) { + case 0x00: /*ROL*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROL(ir, IREG_32(dest_reg), IREG_32(dest_reg), count_reg); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; - case 0x08: /*ROR*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROR(ir, IREG_32(dest_reg), IREG_32(dest_reg), count_reg); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; + case 0x08: /*ROR*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROR(ir, IREG_32(dest_reg), IREG_32(dest_reg), count_reg); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; - case 0x20: - case 0x30: /*SHL*/ - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_SHL(ir, IREG_32(dest_reg), IREG_32(dest_reg), count_reg); - uop_MOV(ir, IREG_flags_op2, count_reg); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; + case 0x20: + case 0x30: /*SHL*/ + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SHL(ir, IREG_32(dest_reg), IREG_32(dest_reg), count_reg); + uop_MOV(ir, IREG_flags_op2, count_reg); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; - case 0x28: /*SHR*/ - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_SHR(ir, IREG_32(dest_reg), IREG_32(dest_reg), count_reg); - uop_MOV(ir, IREG_flags_op2, count_reg); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; + case 0x28: /*SHR*/ + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SHR(ir, IREG_32(dest_reg), IREG_32(dest_reg), count_reg); + uop_MOV(ir, IREG_flags_op2, count_reg); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; - case 0x38: /*SAR*/ - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_SAR(ir, IREG_32(dest_reg), IREG_32(dest_reg), count_reg); - uop_MOV(ir, IREG_flags_op2, count_reg); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; + case 0x38: /*SAR*/ + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SAR(ir, IREG_32(dest_reg), IREG_32(dest_reg), count_reg); + uop_MOV(ir, IREG_flags_op2, count_reg); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; - default:return 0; - } - } else { - switch (fetchdat & 0x38) { - case 0x00: /*ROL*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROL(ir, IREG_temp0, IREG_temp0, count_reg); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL32); - uop_MOV(ir, IREG_flags_res, IREG_temp0); - break; + default: + return 0; + } + } else { + switch (fetchdat & 0x38) { + case 0x00: /*ROL*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROL(ir, IREG_temp0, IREG_temp0, count_reg); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL32); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + break; - case 0x08: /*ROR*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROR(ir, IREG_temp0, IREG_temp0, count_reg); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR32); - uop_MOV(ir, IREG_flags_res, IREG_temp0); - break; + case 0x08: /*ROR*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROR(ir, IREG_temp0, IREG_temp0, count_reg); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR32); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + break; - case 0x20: - case 0x30: /*SHL*/ - uop_SHL(ir, IREG_temp1, IREG_temp0, count_reg); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV(ir, IREG_flags_op2, count_reg); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - break; + case 0x20: + case 0x30: /*SHL*/ + uop_SHL(ir, IREG_temp1, IREG_temp0, count_reg); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV(ir, IREG_flags_op2, count_reg); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; - case 0x28: /*SHR*/ - uop_SHR(ir, IREG_temp1, IREG_temp0, count_reg); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV(ir, IREG_flags_op2, count_reg); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - break; + case 0x28: /*SHR*/ + uop_SHR(ir, IREG_temp1, IREG_temp0, count_reg); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV(ir, IREG_flags_op2, count_reg); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; - case 0x38: /*SAR*/ - uop_SAR(ir, IREG_temp1, IREG_temp0, count_reg); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV(ir, IREG_flags_op2, count_reg); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR32); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - break; + case 0x38: /*SAR*/ + uop_SAR(ir, IREG_temp1, IREG_temp0, count_reg); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV(ir, IREG_flags_op2, count_reg); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; - default:return 0; - } - } + default: + return 0; + } + } - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } uint32_t ropC0(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg = NULL; - uint8_t imm; + x86seg *target_seg = NULL; + uint8_t imm; - if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ - return 0; + if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ + return 0; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) != 0xc0) { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - } - imm = fastreadb(cs + op_pc + 1) & 0x1f; - codegen_mark_code_present(block, cs + op_pc + 1, 1); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) != 0xc0) { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + } + imm = fastreadb(cs + op_pc + 1) & 0x1f; + codegen_mark_code_present(block, cs + op_pc + 1, 1); - if (imm) - return shift_common_8(ir, fetchdat, op_pc, target_seg, imm) + 1; - return op_pc + 1; + if (imm) + return shift_common_8(ir, fetchdat, op_pc, target_seg, imm) + 1; + return op_pc + 1; } uint32_t ropC1_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg = NULL; - uint8_t imm; + x86seg *target_seg = NULL; + uint8_t imm; - if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ - return 0; + if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ + return 0; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) != 0xc0) { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - } - imm = fastreadb(cs + op_pc + 1) & 0x1f; - codegen_mark_code_present(block, cs + op_pc + 1, 1); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) != 0xc0) { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + } + imm = fastreadb(cs + op_pc + 1) & 0x1f; + codegen_mark_code_present(block, cs + op_pc + 1, 1); - if (imm) - return shift_common_16(ir, fetchdat, op_pc, target_seg, imm) + 1; - return op_pc + 1; + if (imm) + return shift_common_16(ir, fetchdat, op_pc, target_seg, imm) + 1; + return op_pc + 1; } uint32_t ropC1_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg = NULL; + x86seg *target_seg = NULL; - if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ - return 0; + if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ + return 0; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) != 0xc0) { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - } - if (block->flags & CODEBLOCK_NO_IMMEDIATES) { - uint32_t new_pc; - int jump_uop; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) != 0xc0) { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + } + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + uint32_t new_pc; + int jump_uop; - LOAD_IMMEDIATE_FROM_RAM_8(block, ir, IREG_temp2, cs + op_pc + 1); - uop_AND_IMM(ir, IREG_temp2, IREG_temp2, 0x1f); - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp2, 0); + LOAD_IMMEDIATE_FROM_RAM_8(block, ir, IREG_temp2, cs + op_pc + 1); + uop_AND_IMM(ir, IREG_temp2, IREG_temp2, 0x1f); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp2, 0); - new_pc = shift_common_variable_32(ir, fetchdat, op_pc, target_seg, IREG_temp2) + 1; - uop_NOP_BARRIER(ir); - uop_set_jump_dest(ir, jump_uop); - return new_pc; - } else { - uint8_t imm = fastreadb(cs + op_pc + 1) & 0x1f; - codegen_mark_code_present(block, cs + op_pc + 1, 1); + new_pc = shift_common_variable_32(ir, fetchdat, op_pc, target_seg, IREG_temp2) + 1; + uop_NOP_BARRIER(ir); + uop_set_jump_dest(ir, jump_uop); + return new_pc; + } else { + uint8_t imm = fastreadb(cs + op_pc + 1) & 0x1f; + codegen_mark_code_present(block, cs + op_pc + 1, 1); - if (imm) - return shift_common_32(ir, fetchdat, op_pc, target_seg, imm) + 1; - } - return op_pc + 1; + if (imm) + return shift_common_32(ir, fetchdat, op_pc, target_seg, imm) + 1; + } + return op_pc + 1; } uint32_t ropD0(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg = NULL; + x86seg *target_seg = NULL; - if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ - return 0; + if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ + return 0; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) != 0xc0) { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - } + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) != 0xc0) { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + } - return shift_common_8(ir, fetchdat, op_pc, target_seg, 1); + return shift_common_8(ir, fetchdat, op_pc, target_seg, 1); } uint32_t ropD1_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg = NULL; + x86seg *target_seg = NULL; - if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ - return 0; + if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ + return 0; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) != 0xc0) { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - } + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) != 0xc0) { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + } - return shift_common_16(ir, fetchdat, op_pc, target_seg, 1); + return shift_common_16(ir, fetchdat, op_pc, target_seg, 1); } uint32_t ropD1_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg = NULL; + x86seg *target_seg = NULL; - if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ - return 0; + if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ + return 0; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) != 0xc0) { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - } + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) != 0xc0) { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + } - return shift_common_32(ir, fetchdat, op_pc, target_seg, 1); + return shift_common_32(ir, fetchdat, op_pc, target_seg, 1); } uint32_t ropD2(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ - return 0; + if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ + return 0; - if (!(CL & 0x1f) || !block->ins) - return 0; + if (!(CL & 0x1f) || !block->ins) + return 0; - uop_AND_IMM(ir, IREG_temp2, REG_ECX, 0x1f); - uop_CMP_IMM_JZ(ir, IREG_temp2, 0, codegen_exit_rout); + uop_AND_IMM(ir, IREG_temp2, REG_ECX, 0x1f); + uop_CMP_IMM_JZ(ir, IREG_temp2, 0, codegen_exit_rout); - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int dest_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - switch (fetchdat & 0x38) { - case 0x00: /*ROL*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROL(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - break; + switch (fetchdat & 0x38) { + case 0x00: /*ROL*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROL(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; - case 0x08: /*ROR*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - break; + case 0x08: /*ROR*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; - case 0x20: - case 0x30: /*SHL*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_SHL(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp2); - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - break; + case 0x20: + case 0x30: /*SHL*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_SHL(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp2); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; - case 0x28: /*SHR*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_SHR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp2); - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - break; + case 0x28: /*SHR*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_SHR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp2); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; - case 0x38: /*SAR*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_SAR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp2); - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - break; + case 0x38: /*SAR*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_SAR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp2); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; - default:return 0; - } - } else { - x86seg *target_seg; + default: + return 0; + } + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - switch (fetchdat & 0x38) { - case 0x00: /*ROL*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROL(ir, IREG_temp0_B, IREG_temp0_B, IREG_temp2); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL8); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); - break; + switch (fetchdat & 0x38) { + case 0x00: /*ROL*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROL(ir, IREG_temp0_B, IREG_temp0_B, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL8); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); + break; - case 0x08: /*ROR*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROR(ir, IREG_temp0_B, IREG_temp0_B, IREG_temp2); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR8); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); - break; + case 0x08: /*ROR*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROR(ir, IREG_temp0_B, IREG_temp0_B, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR8); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); + break; - case 0x20: - case 0x30: /*SHL*/ - uop_SHL(ir, IREG_temp1_B, IREG_temp0_B, IREG_temp2); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL8); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); - break; + case 0x20: + case 0x30: /*SHL*/ + uop_SHL(ir, IREG_temp1_B, IREG_temp0_B, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL8); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + break; - case 0x28: /*SHR*/ - uop_SHR(ir, IREG_temp1_B, IREG_temp0_B, IREG_temp2); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR8); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); - break; + case 0x28: /*SHR*/ + uop_SHR(ir, IREG_temp1_B, IREG_temp0_B, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR8); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + break; - case 0x38: /*SAR*/ - uop_SAR(ir, IREG_temp1_B, IREG_temp0_B, IREG_temp2); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR8); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); - break; + case 0x38: /*SAR*/ + uop_SAR(ir, IREG_temp1_B, IREG_temp0_B, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR8); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + break; - default:return 0; - } - } + default: + return 0; + } + } - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } uint32_t ropD3_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ - return 0; + if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ + return 0; - if (!(CL & 0x1f) || !block->ins) - return 0; + if (!(CL & 0x1f) || !block->ins) + return 0; - uop_AND_IMM(ir, IREG_temp2, REG_ECX, 0x1f); - uop_CMP_IMM_JZ(ir, IREG_temp2, 0, codegen_exit_rout); + uop_AND_IMM(ir, IREG_temp2, REG_ECX, 0x1f); + uop_CMP_IMM_JZ(ir, IREG_temp2, 0, codegen_exit_rout); - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int dest_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - switch (fetchdat & 0x38) { - case 0x00: /*ROL*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROL(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; + switch (fetchdat & 0x38) { + case 0x00: /*ROL*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROL(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; - case 0x08: /*ROR*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; + case 0x08: /*ROR*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; - case 0x20: - case 0x30: /*SHL*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_SHL(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp2); - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; + case 0x20: + case 0x30: /*SHL*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_SHL(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp2); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; - case 0x28: /*SHR*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_SHR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp2); - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; + case 0x28: /*SHR*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_SHR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp2); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; - case 0x38: /*SAR*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_SAR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp2); - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; + case 0x38: /*SAR*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_SAR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp2); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; - default:return 0; - } - } else { - x86seg *target_seg; + default: + return 0; + } + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - switch (fetchdat & 0x38) { - case 0x00: /*ROL*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROL(ir, IREG_temp0_W, IREG_temp0_W, IREG_temp2); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL16); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); - break; + switch (fetchdat & 0x38) { + case 0x00: /*ROL*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROL(ir, IREG_temp0_W, IREG_temp0_W, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + break; - case 0x08: /*ROR*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROR(ir, IREG_temp0_W, IREG_temp0_W, IREG_temp2); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR16); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); - break; + case 0x08: /*ROR*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROR(ir, IREG_temp0_W, IREG_temp0_W, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + break; - case 0x20: - case 0x30: /*SHL*/ - uop_SHL(ir, IREG_temp1_W, IREG_temp0_W, IREG_temp2); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL16); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - break; + case 0x20: + case 0x30: /*SHL*/ + uop_SHL(ir, IREG_temp1_W, IREG_temp0_W, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + break; - case 0x28: /*SHR*/ - uop_SHR(ir, IREG_temp1_W, IREG_temp0_W, IREG_temp2); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR16); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - break; + case 0x28: /*SHR*/ + uop_SHR(ir, IREG_temp1_W, IREG_temp0_W, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + break; - case 0x38: /*SAR*/ - uop_SAR(ir, IREG_temp1_W, IREG_temp0_W, IREG_temp2); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR16); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - break; + case 0x38: /*SAR*/ + uop_SAR(ir, IREG_temp1_W, IREG_temp0_W, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + break; - default:return 0; - } - } + default: + return 0; + } + } - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } uint32_t ropD3_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ - return 0; + if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ + return 0; - if (!(CL & 0x1f) || !block->ins) - return 0; + if (!(CL & 0x1f) || !block->ins) + return 0; - uop_AND_IMM(ir, IREG_temp2, REG_ECX, 0x1f); - uop_CMP_IMM_JZ(ir, IREG_temp2, 0, codegen_exit_rout); + uop_AND_IMM(ir, IREG_temp2, REG_ECX, 0x1f); + uop_CMP_IMM_JZ(ir, IREG_temp2, 0, codegen_exit_rout); - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - int dest_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - switch (fetchdat & 0x38) { - case 0x00: /*ROL*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROL(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; + switch (fetchdat & 0x38) { + case 0x00: /*ROL*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROL(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; - case 0x08: /*ROR*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; + case 0x08: /*ROR*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; - case 0x20: - case 0x30: /*SHL*/ - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_SHL(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp2); - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; + case 0x20: + case 0x30: /*SHL*/ + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SHL(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp2); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; - case 0x28: /*SHR*/ - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_SHR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp2); - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; + case 0x28: /*SHR*/ + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SHR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp2); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; - case 0x38: /*SAR*/ - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_SAR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp2); - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; + case 0x38: /*SAR*/ + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SAR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp2); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; - default:return 0; - } - } else { - x86seg *target_seg; + default: + return 0; + } + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - switch (fetchdat & 0x38) { - case 0x00: /*ROL*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROL(ir, IREG_temp0, IREG_temp0, IREG_temp2); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL32); - uop_MOV(ir, IREG_flags_res, IREG_temp0); - break; + switch (fetchdat & 0x38) { + case 0x00: /*ROL*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROL(ir, IREG_temp0, IREG_temp0, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL32); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + break; - case 0x08: /*ROR*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROR(ir, IREG_temp0, IREG_temp0, IREG_temp2); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR32); - uop_MOV(ir, IREG_flags_res, IREG_temp0); - break; + case 0x08: /*ROR*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROR(ir, IREG_temp0, IREG_temp0, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR32); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + break; - case 0x20: - case 0x30: /*SHL*/ - uop_SHL(ir, IREG_temp1, IREG_temp0, IREG_temp2); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - break; + case 0x20: + case 0x30: /*SHL*/ + uop_SHL(ir, IREG_temp1, IREG_temp0, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; - case 0x28: /*SHR*/ - uop_SHR(ir, IREG_temp1, IREG_temp0, IREG_temp2); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - break; + case 0x28: /*SHR*/ + uop_SHR(ir, IREG_temp1, IREG_temp0, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; - case 0x38: /*SAR*/ - uop_SAR(ir, IREG_temp1, IREG_temp0, IREG_temp2); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR32); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - break; + case 0x38: /*SAR*/ + uop_SAR(ir, IREG_temp1, IREG_temp0, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; - default:return 0; - } - } + default: + return 0; + } + } - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } uint32_t ropSHLD_16_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg = NULL; - int src_reg = (fetchdat >> 3) & 7; - uint8_t imm; + x86seg *target_seg = NULL; + int src_reg = (fetchdat >> 3) & 7; + uint8_t imm; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) != 0xc0) { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - } - imm = fastreadb(cs + op_pc + 1) & 0x1f; - codegen_mark_code_present(block, cs + op_pc + 1, 1); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) != 0xc0) { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + } + imm = fastreadb(cs + op_pc + 1) & 0x1f; + codegen_mark_code_present(block, cs + op_pc + 1, 1); - if (!imm) - return op_pc + 2; + if (!imm) + return op_pc + 2; - if ((fetchdat & 0xc0) == 0xc0) { - int dest_reg = fetchdat & 7; + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_SHL_IMM(ir, IREG_temp0_W, IREG_16(dest_reg), imm); - uop_SHR_IMM(ir, IREG_temp1_W, IREG_16(src_reg), 16 - imm); - uop_OR(ir, IREG_16(dest_reg), IREG_temp0_W, IREG_temp1_W); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - } else { - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp2_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_SHL_IMM(ir, IREG_temp0_W, IREG_16(dest_reg), imm); + uop_SHR_IMM(ir, IREG_temp1_W, IREG_16(src_reg), 16 - imm); + uop_OR(ir, IREG_16(dest_reg), IREG_temp0_W, IREG_temp1_W); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + } else { + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp2_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_SHL_IMM(ir, IREG_temp0_W, IREG_temp2, imm); - uop_SHR_IMM(ir, IREG_temp1_W, IREG_16(src_reg), 16 - imm); - uop_OR(ir, IREG_temp0_W, IREG_temp0_W, IREG_temp1_W); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_SHL_IMM(ir, IREG_temp0_W, IREG_temp2, imm); + uop_SHR_IMM(ir, IREG_temp1_W, IREG_16(src_reg), 16 - imm); + uop_OR(ir, IREG_temp0_W, IREG_temp0_W, IREG_temp1_W); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp2_W); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL16); - } + uop_MOVZX(ir, IREG_flags_op1, IREG_temp2_W); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL16); + } - return op_pc + 2; + return op_pc + 2; } uint32_t ropSHLD_32_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg = NULL; - int src_reg = (fetchdat >> 3) & 7; - uint8_t imm; + x86seg *target_seg = NULL; + int src_reg = (fetchdat >> 3) & 7; + uint8_t imm; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) != 0xc0) { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - } - imm = fastreadb(cs + op_pc + 1) & 0x1f; - codegen_mark_code_present(block, cs + op_pc + 1, 1); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) != 0xc0) { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + } + imm = fastreadb(cs + op_pc + 1) & 0x1f; + codegen_mark_code_present(block, cs + op_pc + 1, 1); - if (!imm) - return op_pc + 2; + if (!imm) + return op_pc + 2; - if ((fetchdat & 0xc0) == 0xc0) { - int dest_reg = fetchdat & 7; + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_SHL_IMM(ir, IREG_temp0, IREG_32(dest_reg), imm); - uop_SHR_IMM(ir, IREG_temp1, IREG_32(src_reg), 32 - imm); - uop_OR(ir, IREG_32(dest_reg), IREG_temp0, IREG_temp1); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - } else { - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp2, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SHL_IMM(ir, IREG_temp0, IREG_32(dest_reg), imm); + uop_SHR_IMM(ir, IREG_temp1, IREG_32(src_reg), 32 - imm); + uop_OR(ir, IREG_32(dest_reg), IREG_temp0, IREG_temp1); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + } else { + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp2, ireg_seg_base(target_seg), IREG_eaaddr); - uop_SHL_IMM(ir, IREG_temp0, IREG_temp2, imm); - uop_SHR_IMM(ir, IREG_temp1, IREG_32(src_reg), 32 - imm); - uop_OR(ir, IREG_temp0, IREG_temp0, IREG_temp1); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_SHL_IMM(ir, IREG_temp0, IREG_temp2, imm); + uop_SHR_IMM(ir, IREG_temp1, IREG_32(src_reg), 32 - imm); + uop_OR(ir, IREG_temp0, IREG_temp0, IREG_temp1); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - uop_MOV(ir, IREG_flags_op1, IREG_temp2); - uop_MOV(ir, IREG_flags_res, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); - } + uop_MOV(ir, IREG_flags_op1, IREG_temp2); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); + } - return op_pc + 2; + return op_pc + 2; } uint32_t ropSHRD_16_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg = NULL; - int src_reg = (fetchdat >> 3) & 7; - uint8_t imm; + x86seg *target_seg = NULL; + int src_reg = (fetchdat >> 3) & 7; + uint8_t imm; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) != 0xc0) { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - } - imm = fastreadb(cs + op_pc + 1) & 0x1f; - codegen_mark_code_present(block, cs + op_pc + 1, 1); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) != 0xc0) { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + } + imm = fastreadb(cs + op_pc + 1) & 0x1f; + codegen_mark_code_present(block, cs + op_pc + 1, 1); - if (!imm) - return op_pc + 2; + if (!imm) + return op_pc + 2; - if ((fetchdat & 0xc0) == 0xc0) { - int dest_reg = fetchdat & 7; + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_SHR_IMM(ir, IREG_temp0_W, IREG_16(dest_reg), imm); - uop_SHL_IMM(ir, IREG_temp1_W, IREG_16(src_reg), 16 - imm); - uop_OR(ir, IREG_16(dest_reg), IREG_temp0_W, IREG_temp1_W); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - } else { - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp2_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_SHR_IMM(ir, IREG_temp0_W, IREG_16(dest_reg), imm); + uop_SHL_IMM(ir, IREG_temp1_W, IREG_16(src_reg), 16 - imm); + uop_OR(ir, IREG_16(dest_reg), IREG_temp0_W, IREG_temp1_W); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + } else { + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp2_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_SHR_IMM(ir, IREG_temp0_W, IREG_temp2, imm); - uop_SHL_IMM(ir, IREG_temp1_W, IREG_16(src_reg), 16 - imm); - uop_OR(ir, IREG_temp0_W, IREG_temp0_W, IREG_temp1_W); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_SHR_IMM(ir, IREG_temp0_W, IREG_temp2, imm); + uop_SHL_IMM(ir, IREG_temp1_W, IREG_16(src_reg), 16 - imm); + uop_OR(ir, IREG_temp0_W, IREG_temp0_W, IREG_temp1_W); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp2_W); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR16); - } + uop_MOVZX(ir, IREG_flags_op1, IREG_temp2_W); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR16); + } - return op_pc + 2; + return op_pc + 2; } uint32_t ropSHRD_32_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg = NULL; - int src_reg = (fetchdat >> 3) & 7; - uint8_t imm; + x86seg *target_seg = NULL; + int src_reg = (fetchdat >> 3) & 7; + uint8_t imm; - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) != 0xc0) { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - } - imm = fastreadb(cs + op_pc + 1) & 0x1f; - codegen_mark_code_present(block, cs + op_pc + 1, 1); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) != 0xc0) { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + } + imm = fastreadb(cs + op_pc + 1) & 0x1f; + codegen_mark_code_present(block, cs + op_pc + 1, 1); - if (!imm) - return op_pc + 2; + if (!imm) + return op_pc + 2; - if ((fetchdat & 0xc0) == 0xc0) { - int dest_reg = fetchdat & 7; + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_SHR_IMM(ir, IREG_temp0, IREG_32(dest_reg), imm); - uop_SHL_IMM(ir, IREG_temp1, IREG_32(src_reg), 32 - imm); - uop_OR(ir, IREG_32(dest_reg), IREG_temp0, IREG_temp1); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - } else { - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp2, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SHR_IMM(ir, IREG_temp0, IREG_32(dest_reg), imm); + uop_SHL_IMM(ir, IREG_temp1, IREG_32(src_reg), 32 - imm); + uop_OR(ir, IREG_32(dest_reg), IREG_temp0, IREG_temp1); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + } else { + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp2, ireg_seg_base(target_seg), IREG_eaaddr); - uop_SHR_IMM(ir, IREG_temp0, IREG_temp2, imm); - uop_SHL_IMM(ir, IREG_temp1, IREG_32(src_reg), 32 - imm); - uop_OR(ir, IREG_temp0, IREG_temp0, IREG_temp1); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_SHR_IMM(ir, IREG_temp0, IREG_temp2, imm); + uop_SHL_IMM(ir, IREG_temp1, IREG_32(src_reg), 32 - imm); + uop_OR(ir, IREG_temp0, IREG_temp0, IREG_temp1); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - uop_MOV(ir, IREG_flags_op1, IREG_temp2); - uop_MOV(ir, IREG_flags_res, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32); - } + uop_MOV(ir, IREG_flags_op1, IREG_temp2); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32); + } - return op_pc + 2; + return op_pc + 2; } diff --git a/src/codegen/codegen_ops_stack.c b/src/codegen/codegen_ops_stack.c index 13cb5f72..1c53873e 100644 --- a/src/codegen/codegen_ops_stack.c +++ b/src/codegen/codegen_ops_stack.c @@ -10,224 +10,222 @@ #include "codegen_ops_misc.h" uint32_t ropPUSH_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int sp_reg; + int sp_reg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); - uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_16(opcode & 7)); - SUB_SP(ir, 2); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); + uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_16(opcode & 7)); + SUB_SP(ir, 2); - return op_pc; + return op_pc; } uint32_t ropPUSH_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int sp_reg; + int sp_reg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); - uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_32(opcode & 7)); - SUB_SP(ir, 4); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); + uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_32(opcode & 7)); + SUB_SP(ir, 4); - return op_pc; + return op_pc; } uint32_t ropPOP_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - if (stack32) - uop_MEM_LOAD_REG(ir, IREG_16(opcode & 7), IREG_SS_base, IREG_ESP); - else { - uop_MOVZX(ir, IREG_eaaddr, IREG_SP); - uop_MEM_LOAD_REG(ir, IREG_16(opcode & 7), IREG_SS_base, IREG_eaaddr); - } - if ((opcode & 7) != REG_SP) - ADD_SP(ir, 2); + if (stack32) + uop_MEM_LOAD_REG(ir, IREG_16(opcode & 7), IREG_SS_base, IREG_ESP); + else { + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); + uop_MEM_LOAD_REG(ir, IREG_16(opcode & 7), IREG_SS_base, IREG_eaaddr); + } + if ((opcode & 7) != REG_SP) + ADD_SP(ir, 2); - return op_pc; + return op_pc; } uint32_t ropPOP_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - if (stack32) - uop_MEM_LOAD_REG(ir, IREG_32(opcode & 7), IREG_SS_base, IREG_ESP); - else { - uop_MOVZX(ir, IREG_eaaddr, IREG_SP); - uop_MEM_LOAD_REG(ir, IREG_32(opcode & 7), IREG_SS_base, IREG_eaaddr); - } - if ((opcode & 7) != REG_ESP) - ADD_SP(ir, 4); + if (stack32) + uop_MEM_LOAD_REG(ir, IREG_32(opcode & 7), IREG_SS_base, IREG_ESP); + else { + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); + uop_MEM_LOAD_REG(ir, IREG_32(opcode & 7), IREG_SS_base, IREG_eaaddr); + } + if ((opcode & 7) != REG_ESP) + ADD_SP(ir, 4); - return op_pc; + return op_pc; } uint32_t ropPUSH_imm_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint16_t imm = fastreadw(cs + op_pc); - int sp_reg; + uint16_t imm = fastreadw(cs + op_pc); + int sp_reg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); - uop_MEM_STORE_IMM_16(ir, IREG_SS_base, sp_reg, imm); - SUB_SP(ir, 2); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); + uop_MEM_STORE_IMM_16(ir, IREG_SS_base, sp_reg, imm); + SUB_SP(ir, 2); - codegen_mark_code_present(block, cs + op_pc, 2); - return op_pc + 2; + codegen_mark_code_present(block, cs + op_pc, 2); + return op_pc + 2; } uint32_t ropPUSH_imm_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint32_t imm = fastreadl(cs + op_pc); - int sp_reg; + uint32_t imm = fastreadl(cs + op_pc); + int sp_reg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); - uop_MEM_STORE_IMM_32(ir, IREG_SS_base, sp_reg, imm); - SUB_SP(ir, 4); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); + uop_MEM_STORE_IMM_32(ir, IREG_SS_base, sp_reg, imm); + SUB_SP(ir, 4); - codegen_mark_code_present(block, cs + op_pc, 4); - return op_pc + 4; + codegen_mark_code_present(block, cs + op_pc, 4); + return op_pc + 4; } uint32_t ropPUSH_imm_16_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint16_t imm = (int16_t)(int8_t)fastreadb(cs + op_pc); - int sp_reg; + uint16_t imm = (int16_t)(int8_t)fastreadb(cs + op_pc); + int sp_reg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); - uop_MEM_STORE_IMM_16(ir, IREG_SS_base, sp_reg, imm); - SUB_SP(ir, 2); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); + uop_MEM_STORE_IMM_16(ir, IREG_SS_base, sp_reg, imm); + SUB_SP(ir, 2); - codegen_mark_code_present(block, cs + op_pc, 1); - return op_pc + 1; + codegen_mark_code_present(block, cs + op_pc, 1); + return op_pc + 1; } uint32_t ropPUSH_imm_32_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint32_t imm = (int32_t)(int8_t)fastreadb(cs + op_pc); - int sp_reg; + uint32_t imm = (int32_t)(int8_t)fastreadb(cs + op_pc); + int sp_reg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); - uop_MEM_STORE_IMM_32(ir, IREG_SS_base, sp_reg, imm); - SUB_SP(ir, 4); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); + uop_MEM_STORE_IMM_32(ir, IREG_SS_base, sp_reg, imm); + SUB_SP(ir, 4); - codegen_mark_code_present(block, cs + op_pc, 1); - return op_pc + 1; + codegen_mark_code_present(block, cs + op_pc, 1); + return op_pc + 1; } uint32_t ropPOP_W(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - if (stack32) - uop_MEM_LOAD_REG(ir, IREG_16(fetchdat & 7), IREG_SS_base, IREG_ESP); - else { - uop_MOVZX(ir, IREG_eaaddr, IREG_SP); - uop_MEM_LOAD_REG(ir, IREG_16(fetchdat & 7), IREG_SS_base, IREG_eaaddr); - } - } else { - x86seg *target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 2); - codegen_check_seg_write(block, ir, target_seg); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + if (stack32) + uop_MEM_LOAD_REG(ir, IREG_16(fetchdat & 7), IREG_SS_base, IREG_ESP); + else { + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); + uop_MEM_LOAD_REG(ir, IREG_16(fetchdat & 7), IREG_SS_base, IREG_eaaddr); + } + } else { + x86seg *target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 2); + codegen_check_seg_write(block, ir, target_seg); - if (stack32) - uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_ESP); - else { - uop_MOVZX(ir, IREG_temp0, IREG_SP); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_temp0); - } + if (stack32) + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_ESP); + else { + uop_MOVZX(ir, IREG_temp0, IREG_SP); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_temp0); + } - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); - } + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + } - if ((fetchdat & 0xc7) != (0xc0 | REG_SP)) - ADD_SP(ir, 2); + if ((fetchdat & 0xc7) != (0xc0 | REG_SP)) + ADD_SP(ir, 2); - return op_pc + 1; + return op_pc + 1; } uint32_t ropPOP_L(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - codegen_mark_code_present(block, cs + op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) { - if (stack32) - uop_MEM_LOAD_REG(ir, IREG_32(fetchdat & 7), IREG_SS_base, IREG_ESP); - else { - uop_MOVZX(ir, IREG_eaaddr, IREG_SP); - uop_MEM_LOAD_REG(ir, IREG_32(fetchdat & 7), IREG_SS_base, IREG_eaaddr); - } - } else { - x86seg *target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 4); - codegen_check_seg_write(block, ir, target_seg); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + if (stack32) + uop_MEM_LOAD_REG(ir, IREG_32(fetchdat & 7), IREG_SS_base, IREG_ESP); + else { + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); + uop_MEM_LOAD_REG(ir, IREG_32(fetchdat & 7), IREG_SS_base, IREG_eaaddr); + } + } else { + x86seg *target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 4); + codegen_check_seg_write(block, ir, target_seg); - if (stack32) - uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_ESP); - else { - uop_MOVZX(ir, IREG_temp0, IREG_SP); - uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_temp0); - } + if (stack32) + uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_ESP); + else { + uop_MOVZX(ir, IREG_temp0, IREG_SP); + uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_temp0); + } - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - } + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + } - if ((fetchdat & 0xc7) != (0xc0 | REG_ESP)) - ADD_SP(ir, 4); + if ((fetchdat & 0xc7) != (0xc0 | REG_ESP)) + ADD_SP(ir, 4); - return op_pc + 1; + return op_pc + 1; } -#define ROP_PUSH_SEG(seg) \ -uint32_t ropPUSH_ ## seg ## _16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - int sp_reg; \ - \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); \ - uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_ ## seg ## _seg_W); \ - SUB_SP(ir, 2); \ - \ - return op_pc; \ -} \ -uint32_t ropPUSH_ ## seg ## _32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - int sp_reg; \ - \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); \ - uop_MOVZX(ir, IREG_temp0, IREG_ ## seg ## _seg_W); \ - uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_temp0); \ - SUB_SP(ir, 4); \ - \ - return op_pc; \ -} +#define ROP_PUSH_SEG(seg) \ + uint32_t ropPUSH_##seg##_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, \ + uint32_t op_pc) { \ + int sp_reg; \ + \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); \ + uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_##seg##_seg_W); \ + SUB_SP(ir, 2); \ + \ + return op_pc; \ + } \ + uint32_t ropPUSH_##seg##_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, \ + uint32_t op_pc) { \ + int sp_reg; \ + \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); \ + uop_MOVZX(ir, IREG_temp0, IREG_##seg##_seg_W); \ + uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_temp0); \ + SUB_SP(ir, 4); \ + \ + return op_pc; \ + } -#define ROP_POP_SEG(seg, rseg) \ -uint32_t ropPOP_ ## seg ## _16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - \ - if (stack32) \ - uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_ESP); \ - else \ - { \ - uop_MOVZX(ir, IREG_eaaddr, IREG_SP); \ - uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr); \ - } \ - uop_LOAD_SEG(ir, &rseg, IREG_temp0_W); \ - ADD_SP(ir, 2); \ - \ - return op_pc; \ -} \ -uint32_t ropPOP_ ## seg ## _32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - \ - if (stack32) \ - uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_ESP); \ - else \ - { \ - uop_MOVZX(ir, IREG_eaaddr, IREG_SP); \ - uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr); \ - } \ - uop_LOAD_SEG(ir, &rseg, IREG_temp0_W); \ - ADD_SP(ir, 4); \ - \ - return op_pc; \ -} +#define ROP_POP_SEG(seg, rseg) \ + uint32_t ropPOP_##seg##_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, \ + uint32_t op_pc) { \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + \ + if (stack32) \ + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_ESP); \ + else { \ + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); \ + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr); \ + } \ + uop_LOAD_SEG(ir, &rseg, IREG_temp0_W); \ + ADD_SP(ir, 2); \ + \ + return op_pc; \ + } \ + uint32_t ropPOP_##seg##_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, \ + uint32_t op_pc) { \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + \ + if (stack32) \ + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_ESP); \ + else { \ + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); \ + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr); \ + } \ + uop_LOAD_SEG(ir, &rseg, IREG_temp0_W); \ + ADD_SP(ir, 4); \ + \ + return op_pc; \ + } ROP_PUSH_SEG(CS) ROP_PUSH_SEG(DS) @@ -241,135 +239,135 @@ ROP_POP_SEG(FS, cpu_state.seg_fs) ROP_POP_SEG(GS, cpu_state.seg_gs) uint32_t ropLEAVE_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - if (stack32) - uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_EBP); - else { - uop_MOVZX(ir, IREG_eaaddr, IREG_BP); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr); - } - uop_ADD_IMM(ir, IREG_SP, IREG_BP, 2); - uop_MOV(ir, IREG_BP, IREG_temp0_W); + if (stack32) + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_EBP); + else { + uop_MOVZX(ir, IREG_eaaddr, IREG_BP); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr); + } + uop_ADD_IMM(ir, IREG_SP, IREG_BP, 2); + uop_MOV(ir, IREG_BP, IREG_temp0_W); - return op_pc; + return op_pc; } uint32_t ropLEAVE_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - if (stack32) - uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_EBP); - else { - uop_MOVZX(ir, IREG_eaaddr, IREG_BP); - uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_eaaddr); - } - uop_ADD_IMM(ir, IREG_ESP, IREG_EBP, 4); - uop_MOV(ir, IREG_EBP, IREG_temp0); + if (stack32) + uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_EBP); + else { + uop_MOVZX(ir, IREG_eaaddr, IREG_BP); + uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_eaaddr); + } + uop_ADD_IMM(ir, IREG_ESP, IREG_EBP, 4); + uop_MOV(ir, IREG_EBP, IREG_temp0); - return op_pc; + return op_pc; } uint32_t ropPUSHA_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int sp_reg; + int sp_reg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - sp_reg = LOAD_SP_WITH_OFFSET(ir, -16); - uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 14, IREG_AX); - uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 12, IREG_CX); - uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 10, IREG_DX); - uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 8, IREG_BX); - uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 6, IREG_SP); - uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 4, IREG_BP); - uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 2, IREG_SI); - uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_DI); - SUB_SP(ir, 16); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -16); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 14, IREG_AX); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 12, IREG_CX); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 10, IREG_DX); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 8, IREG_BX); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 6, IREG_SP); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 4, IREG_BP); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 2, IREG_SI); + uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_DI); + SUB_SP(ir, 16); - return op_pc; + return op_pc; } uint32_t ropPUSHA_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int sp_reg; + int sp_reg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - sp_reg = LOAD_SP_WITH_OFFSET(ir, -32); - uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 28, IREG_EAX); - uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 24, IREG_ECX); - uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 20, IREG_EDX); - uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 16, IREG_EBX); - uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 12, IREG_ESP); - uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 8, IREG_EBP); - uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 4, IREG_ESI); - uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_EDI); - SUB_SP(ir, 32); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -32); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 28, IREG_EAX); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 24, IREG_ECX); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 20, IREG_EDX); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 16, IREG_EBX); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 12, IREG_ESP); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 8, IREG_EBP); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 4, IREG_ESI); + uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_EDI); + SUB_SP(ir, 32); - return op_pc; + return op_pc; } uint32_t ropPOPA_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int sp_reg; + int sp_reg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - sp_reg = LOAD_SP(ir); - uop_MEM_LOAD_REG(ir, IREG_DI, IREG_SS_base, sp_reg); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_SI, IREG_SS_base, sp_reg, 2); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_BP, IREG_SS_base, sp_reg, 4); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_BX, IREG_SS_base, sp_reg, 8); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_DX, IREG_SS_base, sp_reg, 10); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_CX, IREG_SS_base, sp_reg, 12); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_AX, IREG_SS_base, sp_reg, 14); - ADD_SP(ir, 16); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP(ir); + uop_MEM_LOAD_REG(ir, IREG_DI, IREG_SS_base, sp_reg); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_SI, IREG_SS_base, sp_reg, 2); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_BP, IREG_SS_base, sp_reg, 4); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_BX, IREG_SS_base, sp_reg, 8); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_DX, IREG_SS_base, sp_reg, 10); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_CX, IREG_SS_base, sp_reg, 12); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_AX, IREG_SS_base, sp_reg, 14); + ADD_SP(ir, 16); - return op_pc; + return op_pc; } uint32_t ropPOPA_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int sp_reg; + int sp_reg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - sp_reg = LOAD_SP(ir); - uop_MEM_LOAD_REG(ir, IREG_EDI, IREG_SS_base, sp_reg); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_ESI, IREG_SS_base, sp_reg, 4); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_EBP, IREG_SS_base, sp_reg, 8); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_EBX, IREG_SS_base, sp_reg, 16); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_EDX, IREG_SS_base, sp_reg, 20); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_ECX, IREG_SS_base, sp_reg, 24); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_EAX, IREG_SS_base, sp_reg, 28); - ADD_SP(ir, 32); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP(ir); + uop_MEM_LOAD_REG(ir, IREG_EDI, IREG_SS_base, sp_reg); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_ESI, IREG_SS_base, sp_reg, 4); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_EBP, IREG_SS_base, sp_reg, 8); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_EBX, IREG_SS_base, sp_reg, 16); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_EDX, IREG_SS_base, sp_reg, 20); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_ECX, IREG_SS_base, sp_reg, 24); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_EAX, IREG_SS_base, sp_reg, 28); + ADD_SP(ir, 32); - return op_pc; + return op_pc; } uint32_t ropPUSHF(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int sp_reg; + int sp_reg; - if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) - return 0; + if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) + return 0; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - uop_CALL_FUNC(ir, flags_rebuild); - sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); - uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_flags); - SUB_SP(ir, 2); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + uop_CALL_FUNC(ir, flags_rebuild); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); + uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_flags); + SUB_SP(ir, 2); - return op_pc; + return op_pc; } uint32_t ropPUSHFD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int sp_reg; + int sp_reg; - if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) - return 0; + if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) + return 0; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - uop_CALL_FUNC(ir, flags_rebuild); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + uop_CALL_FUNC(ir, flags_rebuild); - if (cpu_CR4_mask & CR4_VME) - uop_AND_IMM(ir, IREG_temp0_W, IREG_eflags, 0x3c); - else if (CPUID) - uop_AND_IMM(ir, IREG_temp0_W, IREG_eflags, 0x24); - else - uop_AND_IMM(ir, IREG_temp0_W, IREG_eflags, 4); - sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); - uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_flags); - uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 2, IREG_temp0_W); - SUB_SP(ir, 4); + if (cpu_CR4_mask & CR4_VME) + uop_AND_IMM(ir, IREG_temp0_W, IREG_eflags, 0x3c); + else if (CPUID) + uop_AND_IMM(ir, IREG_temp0_W, IREG_eflags, 0x24); + else + uop_AND_IMM(ir, IREG_temp0_W, IREG_eflags, 4); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); + uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_flags); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 2, IREG_temp0_W); + SUB_SP(ir, 4); - return op_pc; + return op_pc; } diff --git a/src/codegen/codegen_reg.c b/src/codegen/codegen_reg.c index f6c88ccf..833b302e 100644 --- a/src/codegen/codegen_reg.c +++ b/src/codegen/codegen_reg.c @@ -19,835 +19,845 @@ ir_reg_t host_fp_regs[CODEGEN_HOST_FP_REGS]; static uint8_t host_fp_reg_dirty[CODEGEN_HOST_FP_REGS]; typedef struct host_reg_set_t { - ir_reg_t *regs; - uint8_t *dirty; - host_reg_def_t *reg_list; - uint16_t locked; - int nr_regs; + ir_reg_t *regs; + uint8_t *dirty; + host_reg_def_t *reg_list; + uint16_t locked; + int nr_regs; } host_reg_set_t; static host_reg_set_t host_reg_set, host_fp_reg_set; -enum { - REG_BYTE, - REG_WORD, - REG_DWORD, - REG_QWORD, - REG_POINTER, - REG_DOUBLE, - REG_FPU_ST_BYTE, - REG_FPU_ST_DOUBLE, - REG_FPU_ST_QWORD -}; +enum { REG_BYTE, REG_WORD, REG_DWORD, REG_QWORD, REG_POINTER, REG_DOUBLE, REG_FPU_ST_BYTE, REG_FPU_ST_DOUBLE, REG_FPU_ST_QWORD }; + +enum { REG_INTEGER, REG_FP }; enum { - REG_INTEGER, - REG_FP -}; - -enum { - /*Register may be accessed outside of code block, and must be written - back before any control transfers*/ - REG_PERMANENT = 0, - /*Register will not be accessed outside of code block, and does not need - to be written back if there are no readers remaining*/ - REG_VOLATILE = 1 + /*Register may be accessed outside of code block, and must be written + back before any control transfers*/ + REG_PERMANENT = 0, + /*Register will not be accessed outside of code block, and does not need + to be written back if there are no readers remaining*/ + REG_VOLATILE = 1 }; struct { - int native_size; - void *p; - int type; - int is_volatile; -} ireg_data[IREG_COUNT] = - { - [IREG_EAX] = {REG_DWORD, &EAX, REG_INTEGER, REG_PERMANENT}, - [IREG_ECX] = {REG_DWORD, &ECX, REG_INTEGER, REG_PERMANENT}, - [IREG_EDX] = {REG_DWORD, &EDX, REG_INTEGER, REG_PERMANENT}, - [IREG_EBX] = {REG_DWORD, &EBX, REG_INTEGER, REG_PERMANENT}, - [IREG_ESP] = {REG_DWORD, &ESP, REG_INTEGER, REG_PERMANENT}, - [IREG_EBP] = {REG_DWORD, &EBP, REG_INTEGER, REG_PERMANENT}, - [IREG_ESI] = {REG_DWORD, &ESI, REG_INTEGER, REG_PERMANENT}, - [IREG_EDI] = {REG_DWORD, &EDI, REG_INTEGER, REG_PERMANENT}, + int native_size; + void *p; + int type; + int is_volatile; +} ireg_data[IREG_COUNT] = { + [IREG_EAX] = {REG_DWORD, &EAX, REG_INTEGER, REG_PERMANENT}, + [IREG_ECX] = {REG_DWORD, &ECX, REG_INTEGER, REG_PERMANENT}, + [IREG_EDX] = {REG_DWORD, &EDX, REG_INTEGER, REG_PERMANENT}, + [IREG_EBX] = {REG_DWORD, &EBX, REG_INTEGER, REG_PERMANENT}, + [IREG_ESP] = {REG_DWORD, &ESP, REG_INTEGER, REG_PERMANENT}, + [IREG_EBP] = {REG_DWORD, &EBP, REG_INTEGER, REG_PERMANENT}, + [IREG_ESI] = {REG_DWORD, &ESI, REG_INTEGER, REG_PERMANENT}, + [IREG_EDI] = {REG_DWORD, &EDI, REG_INTEGER, REG_PERMANENT}, - [IREG_flags_op] = {REG_DWORD, &cpu_state.flags_op, REG_INTEGER, REG_PERMANENT}, - [IREG_flags_res] = {REG_DWORD, &cpu_state.flags_res, REG_INTEGER, REG_PERMANENT}, - [IREG_flags_op1] = {REG_DWORD, &cpu_state.flags_op1, REG_INTEGER, REG_PERMANENT}, - [IREG_flags_op2] = {REG_DWORD, &cpu_state.flags_op2, REG_INTEGER, REG_PERMANENT}, + [IREG_flags_op] = {REG_DWORD, &cpu_state.flags_op, REG_INTEGER, REG_PERMANENT}, + [IREG_flags_res] = {REG_DWORD, &cpu_state.flags_res, REG_INTEGER, REG_PERMANENT}, + [IREG_flags_op1] = {REG_DWORD, &cpu_state.flags_op1, REG_INTEGER, REG_PERMANENT}, + [IREG_flags_op2] = {REG_DWORD, &cpu_state.flags_op2, REG_INTEGER, REG_PERMANENT}, - [IREG_pc] = {REG_DWORD, &cpu_state.pc, REG_INTEGER, REG_PERMANENT}, - [IREG_oldpc] = {REG_DWORD, &cpu_state.oldpc, REG_INTEGER, REG_PERMANENT}, + [IREG_pc] = {REG_DWORD, &cpu_state.pc, REG_INTEGER, REG_PERMANENT}, + [IREG_oldpc] = {REG_DWORD, &cpu_state.oldpc, REG_INTEGER, REG_PERMANENT}, - [IREG_eaaddr] = {REG_DWORD, &cpu_state.eaaddr, REG_INTEGER, REG_PERMANENT}, - [IREG_ea_seg] = {REG_POINTER, &cpu_state.ea_seg, REG_INTEGER, REG_PERMANENT}, + [IREG_eaaddr] = {REG_DWORD, &cpu_state.eaaddr, REG_INTEGER, REG_PERMANENT}, + [IREG_ea_seg] = {REG_POINTER, &cpu_state.ea_seg, REG_INTEGER, REG_PERMANENT}, - [IREG_op32] = {REG_DWORD, &cpu_state.op32, REG_INTEGER, REG_PERMANENT}, - [IREG_ssegsx] = {REG_BYTE, &cpu_state.ssegs, REG_INTEGER, REG_PERMANENT}, + [IREG_op32] = {REG_DWORD, &cpu_state.op32, REG_INTEGER, REG_PERMANENT}, + [IREG_ssegsx] = {REG_BYTE, &cpu_state.ssegs, REG_INTEGER, REG_PERMANENT}, - [IREG_rm_mod_reg] = {REG_DWORD, &cpu_state.rm_data.rm_mod_reg_data, REG_INTEGER, REG_PERMANENT}, + [IREG_rm_mod_reg] = {REG_DWORD, &cpu_state.rm_data.rm_mod_reg_data, REG_INTEGER, REG_PERMANENT}, - [IREG_ins] = {REG_DWORD, &cpu_state.cpu_recomp_ins, REG_INTEGER, REG_PERMANENT}, - [IREG_cycles] = {REG_DWORD, &cpu_state._cycles, REG_INTEGER, REG_PERMANENT}, + [IREG_ins] = {REG_DWORD, &cpu_state.cpu_recomp_ins, REG_INTEGER, REG_PERMANENT}, + [IREG_cycles] = {REG_DWORD, &cpu_state._cycles, REG_INTEGER, REG_PERMANENT}, - [IREG_CS_base] = {REG_DWORD, &cpu_state.seg_cs.base, REG_INTEGER, REG_PERMANENT}, - [IREG_DS_base] = {REG_DWORD, &cpu_state.seg_ds.base, REG_INTEGER, REG_PERMANENT}, - [IREG_ES_base] = {REG_DWORD, &cpu_state.seg_es.base, REG_INTEGER, REG_PERMANENT}, - [IREG_FS_base] = {REG_DWORD, &cpu_state.seg_fs.base, REG_INTEGER, REG_PERMANENT}, - [IREG_GS_base] = {REG_DWORD, &cpu_state.seg_gs.base, REG_INTEGER, REG_PERMANENT}, - [IREG_SS_base] = {REG_DWORD, &cpu_state.seg_ss.base, REG_INTEGER, REG_PERMANENT}, + [IREG_CS_base] = {REG_DWORD, &cpu_state.seg_cs.base, REG_INTEGER, REG_PERMANENT}, + [IREG_DS_base] = {REG_DWORD, &cpu_state.seg_ds.base, REG_INTEGER, REG_PERMANENT}, + [IREG_ES_base] = {REG_DWORD, &cpu_state.seg_es.base, REG_INTEGER, REG_PERMANENT}, + [IREG_FS_base] = {REG_DWORD, &cpu_state.seg_fs.base, REG_INTEGER, REG_PERMANENT}, + [IREG_GS_base] = {REG_DWORD, &cpu_state.seg_gs.base, REG_INTEGER, REG_PERMANENT}, + [IREG_SS_base] = {REG_DWORD, &cpu_state.seg_ss.base, REG_INTEGER, REG_PERMANENT}, - [IREG_CS_seg] = {REG_WORD, &cpu_state.seg_cs.seg, REG_INTEGER, REG_PERMANENT}, - [IREG_DS_seg] = {REG_WORD, &cpu_state.seg_ds.seg, REG_INTEGER, REG_PERMANENT}, - [IREG_ES_seg] = {REG_WORD, &cpu_state.seg_es.seg, REG_INTEGER, REG_PERMANENT}, - [IREG_FS_seg] = {REG_WORD, &cpu_state.seg_fs.seg, REG_INTEGER, REG_PERMANENT}, - [IREG_GS_seg] = {REG_WORD, &cpu_state.seg_gs.seg, REG_INTEGER, REG_PERMANENT}, - [IREG_SS_seg] = {REG_WORD, &cpu_state.seg_ss.seg, REG_INTEGER, REG_PERMANENT}, + [IREG_CS_seg] = {REG_WORD, &cpu_state.seg_cs.seg, REG_INTEGER, REG_PERMANENT}, + [IREG_DS_seg] = {REG_WORD, &cpu_state.seg_ds.seg, REG_INTEGER, REG_PERMANENT}, + [IREG_ES_seg] = {REG_WORD, &cpu_state.seg_es.seg, REG_INTEGER, REG_PERMANENT}, + [IREG_FS_seg] = {REG_WORD, &cpu_state.seg_fs.seg, REG_INTEGER, REG_PERMANENT}, + [IREG_GS_seg] = {REG_WORD, &cpu_state.seg_gs.seg, REG_INTEGER, REG_PERMANENT}, + [IREG_SS_seg] = {REG_WORD, &cpu_state.seg_ss.seg, REG_INTEGER, REG_PERMANENT}, - [IREG_FPU_TOP] = {REG_DWORD, &cpu_state.TOP, REG_INTEGER, REG_PERMANENT}, + [IREG_FPU_TOP] = {REG_DWORD, &cpu_state.TOP, REG_INTEGER, REG_PERMANENT}, - [IREG_ST0] = {REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP, REG_PERMANENT}, - [IREG_ST1] = {REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP, REG_PERMANENT}, - [IREG_ST2] = {REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP, REG_PERMANENT}, - [IREG_ST3] = {REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP, REG_PERMANENT}, - [IREG_ST4] = {REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP, REG_PERMANENT}, - [IREG_ST5] = {REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP, REG_PERMANENT}, - [IREG_ST6] = {REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP, REG_PERMANENT}, - [IREG_ST7] = {REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP, REG_PERMANENT}, + [IREG_ST0] = {REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP, REG_PERMANENT}, + [IREG_ST1] = {REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP, REG_PERMANENT}, + [IREG_ST2] = {REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP, REG_PERMANENT}, + [IREG_ST3] = {REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP, REG_PERMANENT}, + [IREG_ST4] = {REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP, REG_PERMANENT}, + [IREG_ST5] = {REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP, REG_PERMANENT}, + [IREG_ST6] = {REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP, REG_PERMANENT}, + [IREG_ST7] = {REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP, REG_PERMANENT}, - [IREG_tag0] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER, REG_PERMANENT}, - [IREG_tag1] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER, REG_PERMANENT}, - [IREG_tag2] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER, REG_PERMANENT}, - [IREG_tag3] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER, REG_PERMANENT}, - [IREG_tag4] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER, REG_PERMANENT}, - [IREG_tag5] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER, REG_PERMANENT}, - [IREG_tag6] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER, REG_PERMANENT}, - [IREG_tag7] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER, REG_PERMANENT}, + [IREG_tag0] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER, REG_PERMANENT}, + [IREG_tag1] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER, REG_PERMANENT}, + [IREG_tag2] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER, REG_PERMANENT}, + [IREG_tag3] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER, REG_PERMANENT}, + [IREG_tag4] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER, REG_PERMANENT}, + [IREG_tag5] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER, REG_PERMANENT}, + [IREG_tag6] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER, REG_PERMANENT}, + [IREG_tag7] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER, REG_PERMANENT}, - [IREG_ST0_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, - [IREG_ST1_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, - [IREG_ST2_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, - [IREG_ST3_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, - [IREG_ST4_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, - [IREG_ST5_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, - [IREG_ST6_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, - [IREG_ST7_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, + [IREG_ST0_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, + [IREG_ST1_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, + [IREG_ST2_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, + [IREG_ST3_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, + [IREG_ST4_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, + [IREG_ST5_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, + [IREG_ST6_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, + [IREG_ST7_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, - [IREG_MM0x] = {REG_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, - [IREG_MM1x] = {REG_QWORD, &cpu_state.MM[1], REG_FP, REG_PERMANENT}, - [IREG_MM2x] = {REG_QWORD, &cpu_state.MM[2], REG_FP, REG_PERMANENT}, - [IREG_MM3x] = {REG_QWORD, &cpu_state.MM[3], REG_FP, REG_PERMANENT}, - [IREG_MM4x] = {REG_QWORD, &cpu_state.MM[4], REG_FP, REG_PERMANENT}, - [IREG_MM5x] = {REG_QWORD, &cpu_state.MM[5], REG_FP, REG_PERMANENT}, - [IREG_MM6x] = {REG_QWORD, &cpu_state.MM[6], REG_FP, REG_PERMANENT}, - [IREG_MM7x] = {REG_QWORD, &cpu_state.MM[7], REG_FP, REG_PERMANENT}, + [IREG_MM0x] = {REG_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, + [IREG_MM1x] = {REG_QWORD, &cpu_state.MM[1], REG_FP, REG_PERMANENT}, + [IREG_MM2x] = {REG_QWORD, &cpu_state.MM[2], REG_FP, REG_PERMANENT}, + [IREG_MM3x] = {REG_QWORD, &cpu_state.MM[3], REG_FP, REG_PERMANENT}, + [IREG_MM4x] = {REG_QWORD, &cpu_state.MM[4], REG_FP, REG_PERMANENT}, + [IREG_MM5x] = {REG_QWORD, &cpu_state.MM[5], REG_FP, REG_PERMANENT}, + [IREG_MM6x] = {REG_QWORD, &cpu_state.MM[6], REG_FP, REG_PERMANENT}, + [IREG_MM7x] = {REG_QWORD, &cpu_state.MM[7], REG_FP, REG_PERMANENT}, - [IREG_NPXCx] = {REG_WORD, &cpu_state.npxc, REG_INTEGER, REG_PERMANENT}, - [IREG_NPXSx] = {REG_WORD, &cpu_state.npxs, REG_INTEGER, REG_PERMANENT}, + [IREG_NPXCx] = {REG_WORD, &cpu_state.npxc, REG_INTEGER, REG_PERMANENT}, + [IREG_NPXSx] = {REG_WORD, &cpu_state.npxs, REG_INTEGER, REG_PERMANENT}, - [IREG_flagsx] = {REG_WORD, &cpu_state.flags, REG_INTEGER, REG_PERMANENT}, - [IREG_eflagsx] = {REG_WORD, &cpu_state.eflags, REG_INTEGER, REG_PERMANENT}, + [IREG_flagsx] = {REG_WORD, &cpu_state.flags, REG_INTEGER, REG_PERMANENT}, + [IREG_eflagsx] = {REG_WORD, &cpu_state.eflags, REG_INTEGER, REG_PERMANENT}, - [IREG_CS_limit_low] = {REG_DWORD, &cpu_state.seg_cs.limit_low, REG_INTEGER, REG_PERMANENT}, - [IREG_DS_limit_low] = {REG_DWORD, &cpu_state.seg_ds.limit_low, REG_INTEGER, REG_PERMANENT}, - [IREG_ES_limit_low] = {REG_DWORD, &cpu_state.seg_es.limit_low, REG_INTEGER, REG_PERMANENT}, - [IREG_FS_limit_low] = {REG_DWORD, &cpu_state.seg_fs.limit_low, REG_INTEGER, REG_PERMANENT}, - [IREG_GS_limit_low] = {REG_DWORD, &cpu_state.seg_gs.limit_low, REG_INTEGER, REG_PERMANENT}, - [IREG_SS_limit_low] = {REG_DWORD, &cpu_state.seg_ss.limit_low, REG_INTEGER, REG_PERMANENT}, + [IREG_CS_limit_low] = {REG_DWORD, &cpu_state.seg_cs.limit_low, REG_INTEGER, REG_PERMANENT}, + [IREG_DS_limit_low] = {REG_DWORD, &cpu_state.seg_ds.limit_low, REG_INTEGER, REG_PERMANENT}, + [IREG_ES_limit_low] = {REG_DWORD, &cpu_state.seg_es.limit_low, REG_INTEGER, REG_PERMANENT}, + [IREG_FS_limit_low] = {REG_DWORD, &cpu_state.seg_fs.limit_low, REG_INTEGER, REG_PERMANENT}, + [IREG_GS_limit_low] = {REG_DWORD, &cpu_state.seg_gs.limit_low, REG_INTEGER, REG_PERMANENT}, + [IREG_SS_limit_low] = {REG_DWORD, &cpu_state.seg_ss.limit_low, REG_INTEGER, REG_PERMANENT}, - [IREG_CS_limit_high] = {REG_DWORD, &cpu_state.seg_cs.limit_high, REG_INTEGER, REG_PERMANENT}, - [IREG_DS_limit_high] = {REG_DWORD, &cpu_state.seg_ds.limit_high, REG_INTEGER, REG_PERMANENT}, - [IREG_ES_limit_high] = {REG_DWORD, &cpu_state.seg_es.limit_high, REG_INTEGER, REG_PERMANENT}, - [IREG_FS_limit_high] = {REG_DWORD, &cpu_state.seg_fs.limit_high, REG_INTEGER, REG_PERMANENT}, - [IREG_GS_limit_high] = {REG_DWORD, &cpu_state.seg_gs.limit_high, REG_INTEGER, REG_PERMANENT}, - [IREG_SS_limit_high] = {REG_DWORD, &cpu_state.seg_ss.limit_high, REG_INTEGER, REG_PERMANENT}, + [IREG_CS_limit_high] = {REG_DWORD, &cpu_state.seg_cs.limit_high, REG_INTEGER, REG_PERMANENT}, + [IREG_DS_limit_high] = {REG_DWORD, &cpu_state.seg_ds.limit_high, REG_INTEGER, REG_PERMANENT}, + [IREG_ES_limit_high] = {REG_DWORD, &cpu_state.seg_es.limit_high, REG_INTEGER, REG_PERMANENT}, + [IREG_FS_limit_high] = {REG_DWORD, &cpu_state.seg_fs.limit_high, REG_INTEGER, REG_PERMANENT}, + [IREG_GS_limit_high] = {REG_DWORD, &cpu_state.seg_gs.limit_high, REG_INTEGER, REG_PERMANENT}, + [IREG_SS_limit_high] = {REG_DWORD, &cpu_state.seg_ss.limit_high, REG_INTEGER, REG_PERMANENT}, - /*Temporary registers are stored on the stack, and are not guaranteed to - be preserved across uOPs. They will not be written back if they will - not be read again.*/ - [IREG_temp0] = {REG_DWORD, (void *)16, REG_INTEGER, REG_VOLATILE}, - [IREG_temp1] = {REG_DWORD, (void *)20, REG_INTEGER, REG_VOLATILE}, - [IREG_temp2] = {REG_DWORD, (void *)24, REG_INTEGER, REG_VOLATILE}, - [IREG_temp3] = {REG_DWORD, (void *)28, REG_INTEGER, REG_VOLATILE}, + /*Temporary registers are stored on the stack, and are not guaranteed to + be preserved across uOPs. They will not be written back if they will + not be read again.*/ + [IREG_temp0] = {REG_DWORD, (void *)16, REG_INTEGER, REG_VOLATILE}, + [IREG_temp1] = {REG_DWORD, (void *)20, REG_INTEGER, REG_VOLATILE}, + [IREG_temp2] = {REG_DWORD, (void *)24, REG_INTEGER, REG_VOLATILE}, + [IREG_temp3] = {REG_DWORD, (void *)28, REG_INTEGER, REG_VOLATILE}, - [IREG_temp0d] = {REG_DOUBLE, (void *)40, REG_FP, REG_VOLATILE}, - [IREG_temp1d] = {REG_DOUBLE, (void *)48, REG_FP, REG_VOLATILE}, - }; + [IREG_temp0d] = {REG_DOUBLE, (void *)40, REG_FP, REG_VOLATILE}, + [IREG_temp1d] = {REG_DOUBLE, (void *)48, REG_FP, REG_VOLATILE}, +}; void codegen_reg_mark_as_required() { - int reg; + int reg; - for (reg = 0; reg < IREG_COUNT; reg++) { - int last_version = reg_last_version[reg]; + for (reg = 0; reg < IREG_COUNT; reg++) { + int last_version = reg_last_version[reg]; - if (last_version > 0 && ireg_data[reg].is_volatile == REG_PERMANENT) - reg_version[reg][last_version].flags |= REG_FLAGS_REQUIRED; - } + if (last_version > 0 && ireg_data[reg].is_volatile == REG_PERMANENT) + reg_version[reg][last_version].flags |= REG_FLAGS_REQUIRED; + } } int reg_is_native_size(ir_reg_t ir_reg) { - int native_size = ireg_data[IREG_GET_REG(ir_reg.reg)].native_size; - int requested_size = IREG_GET_SIZE(ir_reg.reg); + int native_size = ireg_data[IREG_GET_REG(ir_reg.reg)].native_size; + int requested_size = IREG_GET_SIZE(ir_reg.reg); - switch (native_size) { - case REG_BYTE: - case REG_FPU_ST_BYTE:return (requested_size == IREG_SIZE_B); - case REG_WORD:return (requested_size == IREG_SIZE_W); - case REG_DWORD:return (requested_size == IREG_SIZE_L); - case REG_QWORD: - case REG_FPU_ST_QWORD: - case REG_DOUBLE: - case REG_FPU_ST_DOUBLE:return ((requested_size == IREG_SIZE_D) || (requested_size == IREG_SIZE_Q)); - case REG_POINTER: - if (sizeof(void *) == 4) - return (requested_size == IREG_SIZE_L); - return (requested_size == IREG_SIZE_Q); + switch (native_size) { + case REG_BYTE: + case REG_FPU_ST_BYTE: + return (requested_size == IREG_SIZE_B); + case REG_WORD: + return (requested_size == IREG_SIZE_W); + case REG_DWORD: + return (requested_size == IREG_SIZE_L); + case REG_QWORD: + case REG_FPU_ST_QWORD: + case REG_DOUBLE: + case REG_FPU_ST_DOUBLE: + return ((requested_size == IREG_SIZE_D) || (requested_size == IREG_SIZE_Q)); + case REG_POINTER: + if (sizeof(void *) == 4) + return (requested_size == IREG_SIZE_L); + return (requested_size == IREG_SIZE_Q); - default:fatal("get_reg_is_native_size: unknown native size %i\n", native_size); - } + default: + fatal("get_reg_is_native_size: unknown native size %i\n", native_size); + } - return 0; + return 0; } void codegen_reg_reset() { - int c; + int c; - host_reg_set.regs = _host_regs; - host_reg_set.dirty = _host_reg_dirty; - host_reg_set.reg_list = codegen_host_reg_list; - host_reg_set.locked = 0; - host_reg_set.nr_regs = CODEGEN_HOST_REGS; - host_fp_reg_set.regs = host_fp_regs; - host_fp_reg_set.dirty = host_fp_reg_dirty; - host_fp_reg_set.reg_list = codegen_host_fp_reg_list; - host_fp_reg_set.locked = 0; - host_fp_reg_set.nr_regs = CODEGEN_HOST_FP_REGS; + host_reg_set.regs = _host_regs; + host_reg_set.dirty = _host_reg_dirty; + host_reg_set.reg_list = codegen_host_reg_list; + host_reg_set.locked = 0; + host_reg_set.nr_regs = CODEGEN_HOST_REGS; + host_fp_reg_set.regs = host_fp_regs; + host_fp_reg_set.dirty = host_fp_reg_dirty; + host_fp_reg_set.reg_list = codegen_host_fp_reg_list; + host_fp_reg_set.locked = 0; + host_fp_reg_set.nr_regs = CODEGEN_HOST_FP_REGS; - for (c = 0; c < IREG_COUNT; c++) { - reg_last_version[c] = 0; - reg_version[c][0].refcount = 0; - } - for (c = 0; c < CODEGEN_HOST_REGS; c++) { - host_reg_set.regs[c] = invalid_ir_reg; - host_reg_set.dirty[c] = 0; - } - for (c = 0; c < CODEGEN_HOST_FP_REGS; c++) { - host_fp_reg_set.regs[c] = invalid_ir_reg; - host_fp_reg_set.dirty[c] = 0; - } + for (c = 0; c < IREG_COUNT; c++) { + reg_last_version[c] = 0; + reg_version[c][0].refcount = 0; + } + for (c = 0; c < CODEGEN_HOST_REGS; c++) { + host_reg_set.regs[c] = invalid_ir_reg; + host_reg_set.dirty[c] = 0; + } + for (c = 0; c < CODEGEN_HOST_FP_REGS; c++) { + host_fp_reg_set.regs[c] = invalid_ir_reg; + host_fp_reg_set.dirty[c] = 0; + } - reg_dead_list = 0; - max_version_refcount = 0; + reg_dead_list = 0; + max_version_refcount = 0; } -static inline int ir_get_refcount(ir_reg_t ir_reg) { - return reg_version[IREG_GET_REG(ir_reg.reg)][ir_reg.version].refcount; -} +static inline int ir_get_refcount(ir_reg_t ir_reg) { return reg_version[IREG_GET_REG(ir_reg.reg)][ir_reg.version].refcount; } static inline host_reg_set_t *get_reg_set(ir_reg_t ir_reg) { - if (ireg_data[IREG_GET_REG(ir_reg.reg)].type == REG_INTEGER) - return &host_reg_set; - else - return &host_fp_reg_set; + if (ireg_data[IREG_GET_REG(ir_reg.reg)].type == REG_INTEGER) + return &host_reg_set; + else + return &host_fp_reg_set; } static void codegen_reg_load(host_reg_set_t *reg_set, codeblock_t *block, int c, ir_reg_t ir_reg) { - switch (ireg_data[IREG_GET_REG(ir_reg.reg)].native_size) { - case REG_WORD: + switch (ireg_data[IREG_GET_REG(ir_reg.reg)].native_size) { + case REG_WORD: #ifndef RELEASE_BUILD - if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_INTEGER) - fatal("codegen_reg_load - REG_WORD !REG_INTEGER\n"); + if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_INTEGER) + fatal("codegen_reg_load - REG_WORD !REG_INTEGER\n"); #endif - if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) - codegen_direct_read_16_stack(block, reg_set->reg_list[c].reg, (intptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p); - else - codegen_direct_read_16(block, reg_set->reg_list[c].reg, ireg_data[IREG_GET_REG(ir_reg.reg)].p); - break; + if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) + codegen_direct_read_16_stack(block, reg_set->reg_list[c].reg, + (intptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p); + else + codegen_direct_read_16(block, reg_set->reg_list[c].reg, ireg_data[IREG_GET_REG(ir_reg.reg)].p); + break; - case REG_DWORD: + case REG_DWORD: #ifndef RELEASE_BUILD - if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_INTEGER) - fatal("codegen_reg_load - REG_DWORD !REG_INTEGER\n"); + if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_INTEGER) + fatal("codegen_reg_load - REG_DWORD !REG_INTEGER\n"); #endif - if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) - codegen_direct_read_32_stack(block, reg_set->reg_list[c].reg, (intptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p); - else - codegen_direct_read_32(block, reg_set->reg_list[c].reg, ireg_data[IREG_GET_REG(ir_reg.reg)].p); - break; + if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) + codegen_direct_read_32_stack(block, reg_set->reg_list[c].reg, + (intptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p); + else + codegen_direct_read_32(block, reg_set->reg_list[c].reg, ireg_data[IREG_GET_REG(ir_reg.reg)].p); + break; - case REG_QWORD: + case REG_QWORD: #ifndef RELEASE_BUILD - if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP) - fatal("codegen_reg_load - REG_QWORD !REG_FP\n"); + if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP) + fatal("codegen_reg_load - REG_QWORD !REG_FP\n"); #endif - if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) - codegen_direct_read_64_stack(block, reg_set->reg_list[c].reg, (intptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p); - else - codegen_direct_read_64(block, reg_set->reg_list[c].reg, ireg_data[IREG_GET_REG(ir_reg.reg)].p); - break; + if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) + codegen_direct_read_64_stack(block, reg_set->reg_list[c].reg, + (intptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p); + else + codegen_direct_read_64(block, reg_set->reg_list[c].reg, ireg_data[IREG_GET_REG(ir_reg.reg)].p); + break; - case REG_POINTER: + case REG_POINTER: #ifndef RELEASE_BUILD - if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_INTEGER) - fatal("codegen_reg_load - REG_POINTER !REG_INTEGER\n"); + if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_INTEGER) + fatal("codegen_reg_load - REG_POINTER !REG_INTEGER\n"); #endif - if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) - codegen_direct_read_pointer_stack(block, reg_set->reg_list[c].reg, (intptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p); - else - codegen_direct_read_pointer(block, reg_set->reg_list[c].reg, ireg_data[IREG_GET_REG(ir_reg.reg)].p); - break; + if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) + codegen_direct_read_pointer_stack(block, reg_set->reg_list[c].reg, + (intptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p); + else + codegen_direct_read_pointer(block, reg_set->reg_list[c].reg, ireg_data[IREG_GET_REG(ir_reg.reg)].p); + break; - case REG_DOUBLE: + case REG_DOUBLE: #ifndef RELEASE_BUILD - if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP) - fatal("codegen_reg_load - REG_DOUBLE !REG_FP\n"); + if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP) + fatal("codegen_reg_load - REG_DOUBLE !REG_FP\n"); #endif - if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) - codegen_direct_read_double_stack(block, reg_set->reg_list[c].reg, (intptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p); - else - codegen_direct_read_double(block, reg_set->reg_list[c].reg, ireg_data[IREG_GET_REG(ir_reg.reg)].p); - break; + if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) + codegen_direct_read_double_stack(block, reg_set->reg_list[c].reg, + (intptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p); + else + codegen_direct_read_double(block, reg_set->reg_list[c].reg, ireg_data[IREG_GET_REG(ir_reg.reg)].p); + break; - case REG_FPU_ST_BYTE: + case REG_FPU_ST_BYTE: #ifndef RELEASE_BUILD - if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_INTEGER) - fatal("codegen_reg_load - REG_FPU_ST_BYTE !REG_INTEGER\n"); + if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_INTEGER) + fatal("codegen_reg_load - REG_FPU_ST_BYTE !REG_INTEGER\n"); #endif - if (block->flags & CODEBLOCK_STATIC_TOP) - codegen_direct_read_8(block, reg_set->reg_list[c].reg, &cpu_state.tag[ir_reg.reg & 7]); - else - codegen_direct_read_st_8(block, reg_set->reg_list[c].reg, &cpu_state.tag[0], ir_reg.reg & 7); - break; + if (block->flags & CODEBLOCK_STATIC_TOP) + codegen_direct_read_8(block, reg_set->reg_list[c].reg, &cpu_state.tag[ir_reg.reg & 7]); + else + codegen_direct_read_st_8(block, reg_set->reg_list[c].reg, &cpu_state.tag[0], ir_reg.reg & 7); + break; - case REG_FPU_ST_QWORD: + case REG_FPU_ST_QWORD: #ifndef RELEASE_BUILD - if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP) - fatal("codegen_reg_load - REG_FPU_ST_QWORD !REG_FP\n"); + if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP) + fatal("codegen_reg_load - REG_FPU_ST_QWORD !REG_FP\n"); #endif - if (block->flags & CODEBLOCK_STATIC_TOP) - codegen_direct_read_64(block, reg_set->reg_list[c].reg, &cpu_state.MM[ir_reg.reg & 7]); - else - codegen_direct_read_st_64(block, reg_set->reg_list[c].reg, &cpu_state.MM[0], ir_reg.reg & 7); - break; + if (block->flags & CODEBLOCK_STATIC_TOP) + codegen_direct_read_64(block, reg_set->reg_list[c].reg, &cpu_state.MM[ir_reg.reg & 7]); + else + codegen_direct_read_st_64(block, reg_set->reg_list[c].reg, &cpu_state.MM[0], ir_reg.reg & 7); + break; - case REG_FPU_ST_DOUBLE: + case REG_FPU_ST_DOUBLE: #ifndef RELEASE_BUILD - if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP) - fatal("codegen_reg_load - REG_FPU_ST_DOUBLE !REG_FP\n"); + if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP) + fatal("codegen_reg_load - REG_FPU_ST_DOUBLE !REG_FP\n"); #endif - if (block->flags & CODEBLOCK_STATIC_TOP) - codegen_direct_read_double(block, reg_set->reg_list[c].reg, &cpu_state.ST[ir_reg.reg & 7]); - else - codegen_direct_read_st_double(block, reg_set->reg_list[c].reg, &cpu_state.ST[0], ir_reg.reg & 7); - break; + if (block->flags & CODEBLOCK_STATIC_TOP) + codegen_direct_read_double(block, reg_set->reg_list[c].reg, &cpu_state.ST[ir_reg.reg & 7]); + else + codegen_direct_read_st_double(block, reg_set->reg_list[c].reg, &cpu_state.ST[0], ir_reg.reg & 7); + break; - default:fatal("codegen_reg_load - native_size=%i reg=%i\n", ireg_data[IREG_GET_REG(ir_reg.reg)].native_size, IREG_GET_REG(ir_reg.reg)); - } + default: + fatal("codegen_reg_load - native_size=%i reg=%i\n", ireg_data[IREG_GET_REG(ir_reg.reg)].native_size, + IREG_GET_REG(ir_reg.reg)); + } - reg_set->regs[c] = ir_reg; + reg_set->regs[c] = ir_reg; -//pclog(" codegen_reg_load: c=%i reg=%02x.%i\n", c, host_regs[c].reg,host_regs[c].version); + // pclog(" codegen_reg_load: c=%i reg=%02x.%i\n", c, host_regs[c].reg,host_regs[c].version); } static void codegen_reg_writeback(host_reg_set_t *reg_set, codeblock_t *block, int c, int invalidate) { - int ir_reg = IREG_GET_REG(reg_set->regs[c].reg); - void *p = ireg_data[ir_reg].p; + int ir_reg = IREG_GET_REG(reg_set->regs[c].reg); + void *p = ireg_data[ir_reg].p; - if (!reg_version[ir_reg][reg_set->regs[c].version].refcount && - ireg_data[ir_reg].is_volatile) - return; + if (!reg_version[ir_reg][reg_set->regs[c].version].refcount && ireg_data[ir_reg].is_volatile) + return; - switch (ireg_data[ir_reg].native_size) { - case REG_BYTE: + switch (ireg_data[ir_reg].native_size) { + case REG_BYTE: #ifndef RELEASE_BUILD - if (ireg_data[ir_reg].type != REG_INTEGER) - fatal("codegen_reg_writeback - REG_BYTE !REG_INTEGER\n"); - if ((uintptr_t)p < 256) - fatal("codegen_reg_writeback - REG_BYTE %p\n", p); + if (ireg_data[ir_reg].type != REG_INTEGER) + fatal("codegen_reg_writeback - REG_BYTE !REG_INTEGER\n"); + if ((uintptr_t)p < 256) + fatal("codegen_reg_writeback - REG_BYTE %p\n", p); #endif - codegen_direct_write_8(block, p, reg_set->reg_list[c].reg); - break; + codegen_direct_write_8(block, p, reg_set->reg_list[c].reg); + break; - case REG_WORD: + case REG_WORD: #ifndef RELEASE_BUILD - if (ireg_data[ir_reg].type != REG_INTEGER) - fatal("codegen_reg_writeback - REG_WORD !REG_INTEGER\n"); - if ((uintptr_t)p < 256) - fatal("codegen_reg_writeback - REG_WORD %p\n", p); + if (ireg_data[ir_reg].type != REG_INTEGER) + fatal("codegen_reg_writeback - REG_WORD !REG_INTEGER\n"); + if ((uintptr_t)p < 256) + fatal("codegen_reg_writeback - REG_WORD %p\n", p); #endif - codegen_direct_write_16(block, p, reg_set->reg_list[c].reg); - break; + codegen_direct_write_16(block, p, reg_set->reg_list[c].reg); + break; - case REG_DWORD: + case REG_DWORD: #ifndef RELEASE_BUILD - if (ireg_data[ir_reg].type != REG_INTEGER) - fatal("codegen_reg_writeback - REG_DWORD !REG_INTEGER\n"); + if (ireg_data[ir_reg].type != REG_INTEGER) + fatal("codegen_reg_writeback - REG_DWORD !REG_INTEGER\n"); #endif - if ((uintptr_t)p < 256) - codegen_direct_write_32_stack(block, (intptr_t)p, reg_set->reg_list[c].reg); - else - codegen_direct_write_32(block, p, reg_set->reg_list[c].reg); - break; + if ((uintptr_t)p < 256) + codegen_direct_write_32_stack(block, (intptr_t)p, reg_set->reg_list[c].reg); + else + codegen_direct_write_32(block, p, reg_set->reg_list[c].reg); + break; - case REG_QWORD: + case REG_QWORD: #ifndef RELEASE_BUILD - if (ireg_data[ir_reg].type != REG_FP) - fatal("codegen_reg_writeback - REG_QWORD !REG_FP\n"); + if (ireg_data[ir_reg].type != REG_FP) + fatal("codegen_reg_writeback - REG_QWORD !REG_FP\n"); #endif - if ((uintptr_t)p < 256) - codegen_direct_write_64_stack(block, (intptr_t)p, reg_set->reg_list[c].reg); - else - codegen_direct_write_64(block, p, reg_set->reg_list[c].reg); - break; + if ((uintptr_t)p < 256) + codegen_direct_write_64_stack(block, (intptr_t)p, reg_set->reg_list[c].reg); + else + codegen_direct_write_64(block, p, reg_set->reg_list[c].reg); + break; - case REG_POINTER: + case REG_POINTER: #ifndef RELEASE_BUILD - if (ireg_data[ir_reg].type != REG_INTEGER) - fatal("codegen_reg_writeback - REG_POINTER !REG_INTEGER\n"); - if ((uintptr_t)p < 256) - fatal("codegen_reg_writeback - REG_POINTER %p\n", p); + if (ireg_data[ir_reg].type != REG_INTEGER) + fatal("codegen_reg_writeback - REG_POINTER !REG_INTEGER\n"); + if ((uintptr_t)p < 256) + fatal("codegen_reg_writeback - REG_POINTER %p\n", p); #endif - codegen_direct_write_ptr(block, p, reg_set->reg_list[c].reg); - break; + codegen_direct_write_ptr(block, p, reg_set->reg_list[c].reg); + break; - case REG_DOUBLE: + case REG_DOUBLE: #ifndef RELEASE_BUILD - if (ireg_data[ir_reg].type != REG_FP) - fatal("codegen_reg_writeback - REG_DOUBLE !REG_FP\n"); + if (ireg_data[ir_reg].type != REG_FP) + fatal("codegen_reg_writeback - REG_DOUBLE !REG_FP\n"); #endif - if ((uintptr_t)p < 256) - codegen_direct_write_double_stack(block, (intptr_t)p, reg_set->reg_list[c].reg); - else - codegen_direct_write_double(block, p, reg_set->reg_list[c].reg); - break; + if ((uintptr_t)p < 256) + codegen_direct_write_double_stack(block, (intptr_t)p, reg_set->reg_list[c].reg); + else + codegen_direct_write_double(block, p, reg_set->reg_list[c].reg); + break; - case REG_FPU_ST_BYTE: + case REG_FPU_ST_BYTE: #ifndef RELEASE_BUILD - if (ireg_data[ir_reg].type != REG_INTEGER) - fatal("codegen_reg_writeback - REG_FPU_ST_BYTE !REG_INTEGER\n"); + if (ireg_data[ir_reg].type != REG_INTEGER) + fatal("codegen_reg_writeback - REG_FPU_ST_BYTE !REG_INTEGER\n"); #endif - if (block->flags & CODEBLOCK_STATIC_TOP) - codegen_direct_write_8(block, &cpu_state.tag[reg_set->regs[c].reg & 7], reg_set->reg_list[c].reg); - else - codegen_direct_write_st_8(block, &cpu_state.tag[0], reg_set->regs[c].reg & 7, reg_set->reg_list[c].reg); - break; + if (block->flags & CODEBLOCK_STATIC_TOP) + codegen_direct_write_8(block, &cpu_state.tag[reg_set->regs[c].reg & 7], reg_set->reg_list[c].reg); + else + codegen_direct_write_st_8(block, &cpu_state.tag[0], reg_set->regs[c].reg & 7, reg_set->reg_list[c].reg); + break; - case REG_FPU_ST_QWORD: + case REG_FPU_ST_QWORD: #ifndef RELEASE_BUILD - if (ireg_data[ir_reg].type != REG_FP) - fatal("codegen_reg_writeback - REG_FPU_ST_QWORD !REG_FP\n"); + if (ireg_data[ir_reg].type != REG_FP) + fatal("codegen_reg_writeback - REG_FPU_ST_QWORD !REG_FP\n"); #endif - if (block->flags & CODEBLOCK_STATIC_TOP) - codegen_direct_write_64(block, &cpu_state.MM[reg_set->regs[c].reg & 7], reg_set->reg_list[c].reg); - else - codegen_direct_write_st_64(block, &cpu_state.MM[0], reg_set->regs[c].reg & 7, reg_set->reg_list[c].reg); - break; + if (block->flags & CODEBLOCK_STATIC_TOP) + codegen_direct_write_64(block, &cpu_state.MM[reg_set->regs[c].reg & 7], reg_set->reg_list[c].reg); + else + codegen_direct_write_st_64(block, &cpu_state.MM[0], reg_set->regs[c].reg & 7, reg_set->reg_list[c].reg); + break; - case REG_FPU_ST_DOUBLE: + case REG_FPU_ST_DOUBLE: #ifndef RELEASE_BUILD - if (ireg_data[ir_reg].type != REG_FP) - fatal("codegen_reg_writeback - REG_FPU_ST_DOUBLE !REG_FP\n"); + if (ireg_data[ir_reg].type != REG_FP) + fatal("codegen_reg_writeback - REG_FPU_ST_DOUBLE !REG_FP\n"); #endif - if (block->flags & CODEBLOCK_STATIC_TOP) - codegen_direct_write_double(block, &cpu_state.ST[reg_set->regs[c].reg & 7], reg_set->reg_list[c].reg); - else - codegen_direct_write_st_double(block, &cpu_state.ST[0], reg_set->regs[c].reg & 7, reg_set->reg_list[c].reg); - break; + if (block->flags & CODEBLOCK_STATIC_TOP) + codegen_direct_write_double(block, &cpu_state.ST[reg_set->regs[c].reg & 7], reg_set->reg_list[c].reg); + else + codegen_direct_write_st_double(block, &cpu_state.ST[0], reg_set->regs[c].reg & 7, + reg_set->reg_list[c].reg); + break; - default:fatal("codegen_reg_flush - native_size=%i\n", ireg_data[ir_reg].native_size); - } + default: + fatal("codegen_reg_flush - native_size=%i\n", ireg_data[ir_reg].native_size); + } - if (invalidate) - reg_set->regs[c] = invalid_ir_reg; - reg_set->dirty[c] = 0; + if (invalidate) + reg_set->regs[c] = invalid_ir_reg; + reg_set->dirty[c] = 0; } #ifdef CODEGEN_BACKEND_HAS_MOV_IMM void codegen_reg_write_imm(codeblock_t *block, ir_reg_t ir_reg, uint32_t imm_data) { - int reg_idx = IREG_GET_REG(ir_reg.reg); - void *p = ireg_data[reg_idx].p; + int reg_idx = IREG_GET_REG(ir_reg.reg); + void *p = ireg_data[reg_idx].p; - switch (ireg_data[reg_idx].native_size) { - case REG_BYTE: + switch (ireg_data[reg_idx].native_size) { + case REG_BYTE: #ifndef RELEASE_BUILD - if ((uintptr_t)p < 256) - fatal("codegen_reg_write_imm - REG_BYTE %p\n", p); + if ((uintptr_t)p < 256) + fatal("codegen_reg_write_imm - REG_BYTE %p\n", p); #endif - codegen_direct_write_8_imm(block, p, imm_data); - break; + codegen_direct_write_8_imm(block, p, imm_data); + break; - case REG_WORD: + case REG_WORD: #ifndef RELEASE_BUILD - if ((uintptr_t)p < 256) - fatal("codegen_reg_write_imm - REG_WORD %p\n", p); + if ((uintptr_t)p < 256) + fatal("codegen_reg_write_imm - REG_WORD %p\n", p); #endif - codegen_direct_write_16_imm(block, p, imm_data); - break; + codegen_direct_write_16_imm(block, p, imm_data); + break; - case REG_DWORD: - if ((uintptr_t)p < 256) - codegen_direct_write_32_imm_stack(block, (intptr_t)p, imm_data); - else - codegen_direct_write_32_imm(block, p, imm_data); - break; + case REG_DWORD: + if ((uintptr_t)p < 256) + codegen_direct_write_32_imm_stack(block, (intptr_t)p, imm_data); + else + codegen_direct_write_32_imm(block, p, imm_data); + break; - case REG_POINTER: - case REG_QWORD: - case REG_DOUBLE: - case REG_FPU_ST_BYTE: - case REG_FPU_ST_QWORD: - case REG_FPU_ST_DOUBLE: - default:fatal("codegen_reg_write_imm - native_size=%i\n", ireg_data[reg_idx].native_size); - } + case REG_POINTER: + case REG_QWORD: + case REG_DOUBLE: + case REG_FPU_ST_BYTE: + case REG_FPU_ST_QWORD: + case REG_FPU_ST_DOUBLE: + default: + fatal("codegen_reg_write_imm - native_size=%i\n", ireg_data[reg_idx].native_size); + } } #endif static void alloc_reg(ir_reg_t ir_reg) { - host_reg_set_t *reg_set = get_reg_set(ir_reg); - int nr_regs = (reg_set == &host_reg_set) ? CODEGEN_HOST_REGS : CODEGEN_HOST_FP_REGS; - int c; + host_reg_set_t *reg_set = get_reg_set(ir_reg); + int nr_regs = (reg_set == &host_reg_set) ? CODEGEN_HOST_REGS : CODEGEN_HOST_FP_REGS; + int c; - for (c = 0; c < nr_regs; c++) { - if (IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg)) { + for (c = 0; c < nr_regs; c++) { + if (IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg)) { #ifndef RELEASE_BUILD - if (reg_set->regs[c].version != ir_reg.version) - fatal("alloc_reg - host_regs[c].version != ir_reg.version %i %p %p %i %i\n", c, reg_set, &host_reg_set, reg_set->regs[c].reg, ir_reg.reg); + if (reg_set->regs[c].version != ir_reg.version) + fatal("alloc_reg - host_regs[c].version != ir_reg.version %i %p %p %i %i\n", c, reg_set, + &host_reg_set, reg_set->regs[c].reg, ir_reg.reg); #endif - reg_set->locked |= (1 << c); - return; - } - } + reg_set->locked |= (1 << c); + return; + } + } } static void alloc_dest_reg(ir_reg_t ir_reg, int dest_reference) { - host_reg_set_t *reg_set = get_reg_set(ir_reg); - int nr_regs = (reg_set == &host_reg_set) ? CODEGEN_HOST_REGS : CODEGEN_HOST_FP_REGS; - int c; + host_reg_set_t *reg_set = get_reg_set(ir_reg); + int nr_regs = (reg_set == &host_reg_set) ? CODEGEN_HOST_REGS : CODEGEN_HOST_FP_REGS; + int c; - for (c = 0; c < nr_regs; c++) { - if (IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg)) { - if (reg_set->regs[c].version == ir_reg.version) { - reg_set->locked |= (1 << c); - } else { - /*The immediate prior version may have been - optimised out, so search backwards to find the - last valid version*/ - int prev_version = ir_reg.version - 1; -// pclog("prev_version search from %i\n", prev_version); - while (prev_version >= 0) { - reg_version_t *regv = ®_version[IREG_GET_REG(reg_set->regs[c].reg)][prev_version]; + for (c = 0; c < nr_regs; c++) { + if (IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg)) { + if (reg_set->regs[c].version == ir_reg.version) { + reg_set->locked |= (1 << c); + } else { + /*The immediate prior version may have been + optimised out, so search backwards to find the + last valid version*/ + int prev_version = ir_reg.version - 1; + // pclog("prev_version search from %i\n", prev_version); + while (prev_version >= 0) { + reg_version_t *regv = ®_version[IREG_GET_REG(reg_set->regs[c].reg)][prev_version]; - if (!(regv->flags & REG_FLAGS_DEAD) && regv->refcount == dest_reference) { - reg_set->locked |= (1 << c); - return; - } - prev_version--; - } - fatal("codegen_reg_alloc_register - host_regs[c].version != dest_reg_a.version %i,%i %i\n", reg_set->regs[c].version, ir_reg.version, dest_reference); - } - return; - } - } + if (!(regv->flags & REG_FLAGS_DEAD) && regv->refcount == dest_reference) { + reg_set->locked |= (1 << c); + return; + } + prev_version--; + } + fatal("codegen_reg_alloc_register - host_regs[c].version != dest_reg_a.version %i,%i %i\n", + reg_set->regs[c].version, ir_reg.version, dest_reference); + } + return; + } + } } void codegen_reg_alloc_register(ir_reg_t dest_reg_a, ir_reg_t src_reg_a, ir_reg_t src_reg_b, ir_reg_t src_reg_c) { - int dest_reference = 0; + int dest_reference = 0; - host_reg_set.locked = 0; - host_fp_reg_set.locked = 0; + host_reg_set.locked = 0; + host_fp_reg_set.locked = 0; -/* pclog("alloc_register: dst=%i.%i src_a=%i.%i src_b=%i.%i\n", dest_reg_a.reg, dest_reg_a.version, - src_reg_a.reg, src_reg_a.version, - src_reg_b.reg, src_reg_b.version);*/ + /* pclog("alloc_register: dst=%i.%i src_a=%i.%i src_b=%i.%i\n", dest_reg_a.reg, dest_reg_a.version, + src_reg_a.reg, src_reg_a.version, + src_reg_b.reg, src_reg_b.version);*/ - if (!ir_reg_is_invalid(dest_reg_a)) { - if (!ir_reg_is_invalid(src_reg_a) && IREG_GET_REG(src_reg_a.reg) == IREG_GET_REG(dest_reg_a.reg) && src_reg_a.version == dest_reg_a.version - 1) - dest_reference++; - if (!ir_reg_is_invalid(src_reg_b) && IREG_GET_REG(src_reg_b.reg) == IREG_GET_REG(dest_reg_a.reg) && src_reg_b.version == dest_reg_a.version - 1) - dest_reference++; - if (!ir_reg_is_invalid(src_reg_c) && IREG_GET_REG(src_reg_c.reg) == IREG_GET_REG(dest_reg_a.reg) && src_reg_c.version == dest_reg_a.version - 1) - dest_reference++; - } - if (!ir_reg_is_invalid(src_reg_a)) - alloc_reg(src_reg_a); - if (!ir_reg_is_invalid(src_reg_b)) - alloc_reg(src_reg_b); - if (!ir_reg_is_invalid(src_reg_c)) - alloc_reg(src_reg_c); - if (!ir_reg_is_invalid(dest_reg_a)) - alloc_dest_reg(dest_reg_a, dest_reference); + if (!ir_reg_is_invalid(dest_reg_a)) { + if (!ir_reg_is_invalid(src_reg_a) && IREG_GET_REG(src_reg_a.reg) == IREG_GET_REG(dest_reg_a.reg) && + src_reg_a.version == dest_reg_a.version - 1) + dest_reference++; + if (!ir_reg_is_invalid(src_reg_b) && IREG_GET_REG(src_reg_b.reg) == IREG_GET_REG(dest_reg_a.reg) && + src_reg_b.version == dest_reg_a.version - 1) + dest_reference++; + if (!ir_reg_is_invalid(src_reg_c) && IREG_GET_REG(src_reg_c.reg) == IREG_GET_REG(dest_reg_a.reg) && + src_reg_c.version == dest_reg_a.version - 1) + dest_reference++; + } + if (!ir_reg_is_invalid(src_reg_a)) + alloc_reg(src_reg_a); + if (!ir_reg_is_invalid(src_reg_b)) + alloc_reg(src_reg_b); + if (!ir_reg_is_invalid(src_reg_c)) + alloc_reg(src_reg_c); + if (!ir_reg_is_invalid(dest_reg_a)) + alloc_dest_reg(dest_reg_a, dest_reference); } ir_host_reg_t codegen_reg_alloc_read_reg(codeblock_t *block, ir_reg_t ir_reg, int *host_reg_idx) { - host_reg_set_t *reg_set = get_reg_set(ir_reg); - int c; + host_reg_set_t *reg_set = get_reg_set(ir_reg); + int c; - /*Search for required register*/ - for (c = 0; c < reg_set->nr_regs; c++) { - if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg) && reg_set->regs[c].version == ir_reg.version) - break; + /*Search for required register*/ + for (c = 0; c < reg_set->nr_regs; c++) { + if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg) && + reg_set->regs[c].version == ir_reg.version) + break; - if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg) && reg_set->regs[c].version <= ir_reg.version) { - reg_version[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version].refcount++; - break; - } + if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg) && + reg_set->regs[c].version <= ir_reg.version) { + reg_version[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version].refcount++; + break; + } #ifndef RELEASE_BUILD - if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg) - && reg_version[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version].refcount) - fatal("codegen_reg_alloc_read_reg - version mismatch!\n"); + if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg) && + reg_version[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version].refcount) + fatal("codegen_reg_alloc_read_reg - version mismatch!\n"); #endif - } + } - if (c == reg_set->nr_regs) { - /*No unused registers. Search for an unlocked register with no pending reads*/ - for (c = 0; c < reg_set->nr_regs; c++) { - if (!(reg_set->locked & (1 << c)) && IREG_GET_REG(reg_set->regs[c].reg) != IREG_INVALID && !ir_get_refcount(reg_set->regs[c])) - break; - } - if (c == reg_set->nr_regs) { - /*Search for any unlocked register*/ - for (c = 0; c < reg_set->nr_regs; c++) { - if (!(reg_set->locked & (1 << c))) - break; - } + if (c == reg_set->nr_regs) { + /*No unused registers. Search for an unlocked register with no pending reads*/ + for (c = 0; c < reg_set->nr_regs; c++) { + if (!(reg_set->locked & (1 << c)) && IREG_GET_REG(reg_set->regs[c].reg) != IREG_INVALID && + !ir_get_refcount(reg_set->regs[c])) + break; + } + if (c == reg_set->nr_regs) { + /*Search for any unlocked register*/ + for (c = 0; c < reg_set->nr_regs; c++) { + if (!(reg_set->locked & (1 << c))) + break; + } #ifndef RELEASE_BUILD - if (c == reg_set->nr_regs) - fatal("codegen_reg_alloc_read_reg - out of registers\n"); + if (c == reg_set->nr_regs) + fatal("codegen_reg_alloc_read_reg - out of registers\n"); #endif - } - if (reg_set->dirty[c]) - codegen_reg_writeback(reg_set, block, c, 1); -// pclog(" load %i\n", c); - codegen_reg_load(reg_set, block, c, ir_reg); -// fatal("codegen_reg_alloc_read_reg - read %i.%i to %i\n", ir_reg.reg,ir_reg.version, c); - reg_set->locked |= (1 << c); -// codegen_reg_writeback(block, c); - reg_set->dirty[c] = 0; - } -// else -// pclog(" already loaded %i\n", c); + } + if (reg_set->dirty[c]) + codegen_reg_writeback(reg_set, block, c, 1); + // pclog(" load %i\n", c); + codegen_reg_load(reg_set, block, c, ir_reg); + // fatal("codegen_reg_alloc_read_reg - read %i.%i to %i\n", ir_reg.reg,ir_reg.version, c); + reg_set->locked |= (1 << c); + // codegen_reg_writeback(block, c); + reg_set->dirty[c] = 0; + } + // else + // pclog(" already loaded %i\n", c); - reg_version[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version].refcount--; + reg_version[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version].refcount--; #ifndef RELEASE_BUILD - if (reg_version[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version].refcount == (uint8_t)-1) - fatal("codegen_reg_alloc_read_reg - refcount < 0\n"); + if (reg_version[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version].refcount == (uint8_t)-1) + fatal("codegen_reg_alloc_read_reg - refcount < 0\n"); #endif - if (host_reg_idx) - *host_reg_idx = c; -// pclog(" codegen_reg_alloc_read_reg: %i.%i %i %02x.%i %i\n", ir_reg.reg, ir_reg.version, codegen_host_reg_list[c], reg_set->regs[c].reg,reg_set->regs[c].version, c); - return reg_set->reg_list[c].reg | IREG_GET_SIZE(ir_reg.reg); + if (host_reg_idx) + *host_reg_idx = c; + // pclog(" codegen_reg_alloc_read_reg: %i.%i %i %02x.%i %i\n", ir_reg.reg, ir_reg.version, + // codegen_host_reg_list[c], reg_set->regs[c].reg,reg_set->regs[c].version, c); + return reg_set->reg_list[c].reg | IREG_GET_SIZE(ir_reg.reg); } ir_host_reg_t codegen_reg_alloc_write_reg(codeblock_t *block, ir_reg_t ir_reg) { - host_reg_set_t *reg_set = get_reg_set(ir_reg); - int c; + host_reg_set_t *reg_set = get_reg_set(ir_reg); + int c; - if (!reg_is_native_size(ir_reg)) { - /*Read in parent register so we can do partial accesses to it*/ - ir_reg_t parent_reg; + if (!reg_is_native_size(ir_reg)) { + /*Read in parent register so we can do partial accesses to it*/ + ir_reg_t parent_reg; - parent_reg.reg = IREG_GET_REG(ir_reg.reg) | IREG_SIZE_L; - parent_reg.version = ir_reg.version - 1; - reg_version[IREG_GET_REG(ir_reg.reg)][ir_reg.version - 1].refcount++; + parent_reg.reg = IREG_GET_REG(ir_reg.reg) | IREG_SIZE_L; + parent_reg.version = ir_reg.version - 1; + reg_version[IREG_GET_REG(ir_reg.reg)][ir_reg.version - 1].refcount++; - codegen_reg_alloc_read_reg(block, parent_reg, &c); + codegen_reg_alloc_read_reg(block, parent_reg, &c); #ifndef RELEASE_BUILD - if (IREG_GET_REG(reg_set->regs[c].reg) != IREG_GET_REG(ir_reg.reg) || reg_set->regs[c].version > ir_reg.version - 1) - fatal("codegen_reg_alloc_write_reg sub_reg - doesn't match %i %02x.%i %02x.%i\n", c, - reg_set->regs[c].reg, reg_set->regs[c].version, - ir_reg.reg, ir_reg.version); + if (IREG_GET_REG(reg_set->regs[c].reg) != IREG_GET_REG(ir_reg.reg) || + reg_set->regs[c].version > ir_reg.version - 1) + fatal("codegen_reg_alloc_write_reg sub_reg - doesn't match %i %02x.%i %02x.%i\n", c, + reg_set->regs[c].reg, reg_set->regs[c].version, ir_reg.reg, ir_reg.version); #endif - reg_set->regs[c].reg = ir_reg.reg; - reg_set->regs[c].version = ir_reg.version; - reg_set->dirty[c] = 1; -// pclog(" codegen_reg_alloc_write_reg: partial %i.%i %i\n", ir_reg.reg, ir_reg.version, codegen_host_reg_list[c]); - return reg_set->reg_list[c].reg | IREG_GET_SIZE(ir_reg.reg); - } + reg_set->regs[c].reg = ir_reg.reg; + reg_set->regs[c].version = ir_reg.version; + reg_set->dirty[c] = 1; + // pclog(" codegen_reg_alloc_write_reg: partial %i.%i %i\n", ir_reg.reg, ir_reg.version, + // codegen_host_reg_list[c]); + return reg_set->reg_list[c].reg | IREG_GET_SIZE(ir_reg.reg); + } - /*Search for previous version in host register*/ - for (c = 0; c < reg_set->nr_regs; c++) { - if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg)) { - if (reg_set->regs[c].version <= ir_reg.version - 1) { + /*Search for previous version in host register*/ + for (c = 0; c < reg_set->nr_regs; c++) { + if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg)) { + if (reg_set->regs[c].version <= ir_reg.version - 1) { #ifndef RELEASE_BUILD - if (reg_version[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version].refcount != 0) - fatal("codegen_reg_alloc_write_reg - previous version refcount != 0\n"); + if (reg_version[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version].refcount != 0) + fatal("codegen_reg_alloc_write_reg - previous version refcount != 0\n"); #endif - break; - } - } - } + break; + } + } + } - if (c == reg_set->nr_regs) { - /*Search for unused registers*/ - for (c = 0; c < reg_set->nr_regs; c++) { - if (ir_reg_is_invalid(reg_set->regs[c])) - break; - } + if (c == reg_set->nr_regs) { + /*Search for unused registers*/ + for (c = 0; c < reg_set->nr_regs; c++) { + if (ir_reg_is_invalid(reg_set->regs[c])) + break; + } - if (c == reg_set->nr_regs) { - /*No unused registers. Search for an unlocked register*/ - for (c = 0; c < reg_set->nr_regs; c++) { - if (!(reg_set->locked & (1 << c))) - break; - } + if (c == reg_set->nr_regs) { + /*No unused registers. Search for an unlocked register*/ + for (c = 0; c < reg_set->nr_regs; c++) { + if (!(reg_set->locked & (1 << c))) + break; + } #ifndef RELEASE_BUILD - if (c == reg_set->nr_regs) - fatal("codegen_reg_alloc_write_reg - out of registers\n"); + if (c == reg_set->nr_regs) + fatal("codegen_reg_alloc_write_reg - out of registers\n"); #endif - if (reg_set->dirty[c]) - codegen_reg_writeback(reg_set, block, c, 1); - } - } + if (reg_set->dirty[c]) + codegen_reg_writeback(reg_set, block, c, 1); + } + } - reg_set->regs[c].reg = ir_reg.reg; - reg_set->regs[c].version = ir_reg.version; - reg_set->dirty[c] = 1; -// pclog(" codegen_reg_alloc_write_reg: %i.%i %i\n", ir_reg.reg, ir_reg.version, codegen_host_reg_list[c]); - return reg_set->reg_list[c].reg | IREG_GET_SIZE(ir_reg.reg); + reg_set->regs[c].reg = ir_reg.reg; + reg_set->regs[c].version = ir_reg.version; + reg_set->dirty[c] = 1; + // pclog(" codegen_reg_alloc_write_reg: %i.%i %i\n", ir_reg.reg, ir_reg.version, codegen_host_reg_list[c]); + return reg_set->reg_list[c].reg | IREG_GET_SIZE(ir_reg.reg); } #ifdef CODEGEN_BACKEND_HAS_MOV_IMM int codegen_reg_is_loaded(ir_reg_t ir_reg) { - host_reg_set_t *reg_set = get_reg_set(ir_reg); - int c; + host_reg_set_t *reg_set = get_reg_set(ir_reg); + int c; - /*Search for previous version in host register*/ - for (c = 0; c < reg_set->nr_regs; c++) { - if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg)) { - if (reg_set->regs[c].version <= ir_reg.version - 1) { + /*Search for previous version in host register*/ + for (c = 0; c < reg_set->nr_regs; c++) { + if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg)) { + if (reg_set->regs[c].version <= ir_reg.version - 1) { #ifndef RELEASE_BUILD - if (reg_version[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version].refcount != 0) - fatal("codegen_reg_alloc_write_reg - previous version refcount != 0\n"); + if (reg_version[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version].refcount != 0) + fatal("codegen_reg_alloc_write_reg - previous version refcount != 0\n"); #endif - return 1; - } - } - } - return 0; + return 1; + } + } + } + return 0; } #endif void codegen_reg_rename(codeblock_t *block, ir_reg_t src, ir_reg_t dst) { - host_reg_set_t *reg_set = get_reg_set(src); - int c; - int target; + host_reg_set_t *reg_set = get_reg_set(src); + int c; + int target; -// pclog("rename: %i.%i -> %i.%i\n", src.reg,src.version, dst.reg, dst.version); - /*Search for required register*/ - for (c = 0; c < reg_set->nr_regs; c++) { - if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(src.reg) && reg_set->regs[c].version == src.version) - break; - } + // pclog("rename: %i.%i -> %i.%i\n", src.reg,src.version, dst.reg, dst.version); + /*Search for required register*/ + for (c = 0; c < reg_set->nr_regs; c++) { + if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(src.reg) && + reg_set->regs[c].version == src.version) + break; + } #ifndef RELEASE_BUILD - if (c == reg_set->nr_regs) - fatal("codegen_reg_rename: Can't find register to rename\n"); + if (c == reg_set->nr_regs) + fatal("codegen_reg_rename: Can't find register to rename\n"); #endif - target = c; - if (reg_set->dirty[target]) - codegen_reg_writeback(reg_set, block, target, 0); - reg_set->regs[target] = dst; - reg_set->dirty[target] = 1; -// pclog("renamed reg %i dest=%i.%i\n", target, dst.reg, dst.version); + target = c; + if (reg_set->dirty[target]) + codegen_reg_writeback(reg_set, block, target, 0); + reg_set->regs[target] = dst; + reg_set->dirty[target] = 1; + // pclog("renamed reg %i dest=%i.%i\n", target, dst.reg, dst.version); - /*Invalidate any stale copies of the dest register*/ - for (c = 0; c < reg_set->nr_regs; c++) { - if (c == target) - continue; - if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(dst.reg)) { - reg_set->regs[c] = invalid_ir_reg; - reg_set->dirty[c] = 0; - } - } + /*Invalidate any stale copies of the dest register*/ + for (c = 0; c < reg_set->nr_regs; c++) { + if (c == target) + continue; + if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(dst.reg)) { + reg_set->regs[c] = invalid_ir_reg; + reg_set->dirty[c] = 0; + } + } } void codegen_reg_flush(ir_data_t *ir, codeblock_t *block) { - host_reg_set_t *reg_set; - int c; + host_reg_set_t *reg_set; + int c; - reg_set = &host_reg_set; - for (c = 0; c < reg_set->nr_regs; c++) { - if (!ir_reg_is_invalid(reg_set->regs[c]) && reg_set->dirty[c]) { - codegen_reg_writeback(reg_set, block, c, 0); - } - if (reg_set->reg_list[c].flags & HOST_REG_FLAG_VOLATILE) { - reg_set->regs[c] = invalid_ir_reg; - reg_set->dirty[c] = 0; - } - } + reg_set = &host_reg_set; + for (c = 0; c < reg_set->nr_regs; c++) { + if (!ir_reg_is_invalid(reg_set->regs[c]) && reg_set->dirty[c]) { + codegen_reg_writeback(reg_set, block, c, 0); + } + if (reg_set->reg_list[c].flags & HOST_REG_FLAG_VOLATILE) { + reg_set->regs[c] = invalid_ir_reg; + reg_set->dirty[c] = 0; + } + } - reg_set = &host_fp_reg_set; - for (c = 0; c < reg_set->nr_regs; c++) { - if (!ir_reg_is_invalid(reg_set->regs[c]) && reg_set->dirty[c]) { - codegen_reg_writeback(reg_set, block, c, 0); - } - if (reg_set->reg_list[c].flags & HOST_REG_FLAG_VOLATILE) { - reg_set->regs[c] = invalid_ir_reg; - reg_set->dirty[c] = 0; - } - } + reg_set = &host_fp_reg_set; + for (c = 0; c < reg_set->nr_regs; c++) { + if (!ir_reg_is_invalid(reg_set->regs[c]) && reg_set->dirty[c]) { + codegen_reg_writeback(reg_set, block, c, 0); + } + if (reg_set->reg_list[c].flags & HOST_REG_FLAG_VOLATILE) { + reg_set->regs[c] = invalid_ir_reg; + reg_set->dirty[c] = 0; + } + } } void codegen_reg_flush_invalidate(ir_data_t *ir, codeblock_t *block) { - host_reg_set_t *reg_set; - int c; + host_reg_set_t *reg_set; + int c; - reg_set = &host_reg_set; - for (c = 0; c < reg_set->nr_regs; c++) { - if (!ir_reg_is_invalid(reg_set->regs[c]) && reg_set->dirty[c]) { - codegen_reg_writeback(reg_set, block, c, 1); - } - reg_set->regs[c] = invalid_ir_reg; - reg_set->dirty[c] = 0; - } + reg_set = &host_reg_set; + for (c = 0; c < reg_set->nr_regs; c++) { + if (!ir_reg_is_invalid(reg_set->regs[c]) && reg_set->dirty[c]) { + codegen_reg_writeback(reg_set, block, c, 1); + } + reg_set->regs[c] = invalid_ir_reg; + reg_set->dirty[c] = 0; + } - reg_set = &host_fp_reg_set; - for (c = 0; c < reg_set->nr_regs; c++) { - if (!ir_reg_is_invalid(reg_set->regs[c]) && reg_set->dirty[c]) { - codegen_reg_writeback(reg_set, block, c, 1); - } - reg_set->regs[c] = invalid_ir_reg; - reg_set->dirty[c] = 0; - } + reg_set = &host_fp_reg_set; + for (c = 0; c < reg_set->nr_regs; c++) { + if (!ir_reg_is_invalid(reg_set->regs[c]) && reg_set->dirty[c]) { + codegen_reg_writeback(reg_set, block, c, 1); + } + reg_set->regs[c] = invalid_ir_reg; + reg_set->dirty[c] = 0; + } } /*Process dead register list, and optimise out register versions and uOPs where possible*/ void codegen_reg_process_dead_list(ir_data_t *ir) { - while (reg_dead_list) { - int version = reg_dead_list & 0xff; - int reg = reg_dead_list >> 8; - reg_version_t *regv = ®_version[reg][version]; - uop_t *uop = &ir->uops[regv->parent_uop]; + while (reg_dead_list) { + int version = reg_dead_list & 0xff; + int reg = reg_dead_list >> 8; + reg_version_t *regv = ®_version[reg][version]; + uop_t *uop = &ir->uops[regv->parent_uop]; - /*Barrier uOPs should be preserved*/ - if (!(uop->type & (UOP_TYPE_BARRIER | UOP_TYPE_ORDER_BARRIER))) { -// pclog(" codegen_process_dead_list: reg=%i version=%i uop=%i\n", reg, version, regv->parent_uop); - uop->type = UOP_INVALID; - /*Adjust refcounts on source registers. If these drop to - zero then those registers can be considered for removal*/ - if (uop->src_reg_a.reg != IREG_INVALID) { - reg_version_t *src_regv = ®_version[IREG_GET_REG(uop->src_reg_a.reg)][uop->src_reg_a.version]; - src_regv->refcount--; - if (!src_regv->refcount) - add_to_dead_list(src_regv, IREG_GET_REG(uop->src_reg_a.reg), uop->src_reg_a.version); - } - if (uop->src_reg_b.reg != IREG_INVALID) { - reg_version_t *src_regv = ®_version[IREG_GET_REG(uop->src_reg_b.reg)][uop->src_reg_b.version]; - src_regv->refcount--; - if (!src_regv->refcount) - add_to_dead_list(src_regv, IREG_GET_REG(uop->src_reg_b.reg), uop->src_reg_b.version); - } - if (uop->src_reg_c.reg != IREG_INVALID) { - reg_version_t *src_regv = ®_version[IREG_GET_REG(uop->src_reg_c.reg)][uop->src_reg_c.version]; - src_regv->refcount--; - if (!src_regv->refcount) - add_to_dead_list(src_regv, IREG_GET_REG(uop->src_reg_c.reg), uop->src_reg_c.version); - } - regv->flags |= REG_FLAGS_DEAD; - } + /*Barrier uOPs should be preserved*/ + if (!(uop->type & (UOP_TYPE_BARRIER | UOP_TYPE_ORDER_BARRIER))) { + // pclog(" codegen_process_dead_list: reg=%i version=%i uop=%i\n", reg, version, + // regv->parent_uop); + uop->type = UOP_INVALID; + /*Adjust refcounts on source registers. If these drop to + zero then those registers can be considered for removal*/ + if (uop->src_reg_a.reg != IREG_INVALID) { + reg_version_t *src_regv = ®_version[IREG_GET_REG(uop->src_reg_a.reg)][uop->src_reg_a.version]; + src_regv->refcount--; + if (!src_regv->refcount) + add_to_dead_list(src_regv, IREG_GET_REG(uop->src_reg_a.reg), uop->src_reg_a.version); + } + if (uop->src_reg_b.reg != IREG_INVALID) { + reg_version_t *src_regv = ®_version[IREG_GET_REG(uop->src_reg_b.reg)][uop->src_reg_b.version]; + src_regv->refcount--; + if (!src_regv->refcount) + add_to_dead_list(src_regv, IREG_GET_REG(uop->src_reg_b.reg), uop->src_reg_b.version); + } + if (uop->src_reg_c.reg != IREG_INVALID) { + reg_version_t *src_regv = ®_version[IREG_GET_REG(uop->src_reg_c.reg)][uop->src_reg_c.version]; + src_regv->refcount--; + if (!src_regv->refcount) + add_to_dead_list(src_regv, IREG_GET_REG(uop->src_reg_c.reg), uop->src_reg_c.version); + } + regv->flags |= REG_FLAGS_DEAD; + } - reg_dead_list = regv->next; - } + reg_dead_list = regv->next; + } } diff --git a/src/codegen/codegen_timing_486.c b/src/codegen/codegen_timing_486.c index e3a90ed2..25120370 100644 --- a/src/codegen/codegen_timing_486.c +++ b/src/codegen/codegen_timing_486.c @@ -11,412 +11,1368 @@ #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), +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, + /*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, + /*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 - }; + /*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), +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, + /*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, + /*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 - }; + /*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, +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, + /*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), + /*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, + /*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, + /*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), + /*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, - }; + /*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_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_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_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_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_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_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[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) - }; + { + /* 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_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_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_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 *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; + 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_block_start() { regmask_modified = 0; } void codegen_timing_486_start() { - timing_count = 0; - last_prefix = 0; + 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; + timing_count += COUNT(opcode_timings[prefix], 0); + last_prefix = prefix; } void codegen_timing_486_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc) { - int **timings; - uint64_t *deps; - int mod3 = ((fetchdat & 0xc0) == 0xc0); - int bit8 = !(opcode & 1); + 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; -// pclog("timings 0f\n"); - break; + switch (last_prefix) { + case 0x0f: + timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; + deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; + // pclog("timings 0f\n"); + 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; -// pclog("timings d8\n"); - 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; -// pclog("timings d9\n"); - 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; -// pclog("timings da\n"); - 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; -// pclog("timings db\n"); - 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; -// pclog("timings dc\n"); - 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; -// pclog("timings dd\n"); - 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; -// pclog("timings de\n"); - 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; -// pclog("timings df\n"); - 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; + // pclog("timings d8\n"); + 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; + // pclog("timings d9\n"); + 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; + // pclog("timings da\n"); + 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; + // pclog("timings db\n"); + 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; + // pclog("timings dc\n"); + 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; + // pclog("timings dd\n"); + 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; + // pclog("timings de\n"); + 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; + // pclog("timings df\n"); + 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; -// pclog("timings 80 %p %p %p\n", (void *)timings, (void *)opcode_timings_mod3, (void *)opcode_timings_8x); - 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; -// pclog("timings 80 %p %p %p\n", (void *)timings, (void *)opcode_timings_mod3, (void *)opcode_timings_8x); - 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; + // pclog("timings 80 %p %p %p\n", (void *)timings, (void *)opcode_timings_mod3, + // (void *)opcode_timings_8x); + 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; + // pclog("timings 80 %p %p %p\n", (void *)timings, (void *)opcode_timings_mod3, + // (void *)opcode_timings_8x); + 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; -// pclog("timings c0\n"); - 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; + // pclog("timings c0\n"); + 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; -// pclog("timings f6\n"); - 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; -// pclog("timings f7\n"); - 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; -// pclog("timings ff\n"); - 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; + // pclog("timings f6\n"); + 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; + // pclog("timings f7\n"); + 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; + // pclog("timings ff\n"); + break; - default:timings = mod3 ? opcode_timings_mod3 : opcode_timings; - deps = mod3 ? opcode_deps_mod3 : opcode_deps; -// pclog("timings normal\n"); - break; - } - } + default: + timings = mod3 ? opcode_timings_mod3 : opcode_timings; + deps = mod3 ? opcode_deps_mod3 : opcode_deps; + // pclog("timings normal\n"); + 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; + 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); + regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8); } -void codegen_timing_486_block_end() { -} +void codegen_timing_486_block_end() {} -int codegen_timing_486_jump_cycles() { - return 0; -} +int codegen_timing_486_jump_cycles() { return 0; } -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, - codegen_timing_486_jump_cycles - }; +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, codegen_timing_486_jump_cycles}; diff --git a/src/codegen/codegen_timing_686.c b/src/codegen/codegen_timing_686.c index a923c68e..ab904baf 100644 --- a/src/codegen/codegen_timing_686.c +++ b/src/codegen/codegen_timing_686.c @@ -29,7 +29,7 @@ /*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_RM (1 << 0) #define CYCLES_RMW (1 << 0) #define CYCLES_BRANCH (1 << 0) @@ -38,9 +38,9 @@ /*Instruction does not pair*/ #define PAIR_NP (0 << 29) /*Instruction pairs in X pipe only*/ -#define PAIR_X (1 << 29) +#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) +#define PAIR_X_BRANCH (2 << 29) /*Instruction pairs in both X and Y pipes*/ #define PAIR_XY (3 << 29) @@ -59,984 +59,1375 @@ 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 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; + 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; + return c & CYCLES_MASK; } void codegen_timing_686_block_start() { - prev_full = decode_delay = 0; - regmask_modified = last_regmask_modified = 0; + prev_full = decode_delay = 0; + regmask_modified = last_regmask_modified = 0; } void codegen_timing_686_start() { - decode_delay = 0; - last_prefix = 0; + 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; - } + 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; + /*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); + uint32_t addr_regmask = get_addr_regmask(deps[opcode], fetchdat, op_32); - if (addr_regmask & IMPL_ESP) - addr_regmask |= (1 << REG_ESP); + if (addr_regmask & IMPL_ESP) + addr_regmask |= (1 << REG_ESP); - if (regmask_modified & addr_regmask) { - regmask_modified = 0; - return 2; - } + if (regmask_modified & addr_regmask) { + regmask_modified = 0; + return 2; + } - if (last_regmask_modified & addr_regmask) - return 1; + if (last_regmask_modified & addr_regmask) + return 1; - return 0; + return 0; } void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc) { - uint32_t *timings; - uint64_t *deps; - int mod3 = ((fetchdat & 0xc0) == 0xc0); - int bit8 = !(opcode & 1); + 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; -// pclog("timings 0f\n"); - break; + switch (last_prefix) { + case 0x0f: + timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; + deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; + // pclog("timings 0f\n"); + 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; -// pclog("timings d8\n"); - 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; -// pclog("timings d9\n"); - 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; -// pclog("timings da\n"); - 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; -// pclog("timings db\n"); - 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; -// pclog("timings dc\n"); - 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; -// pclog("timings dd\n"); - 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; -// pclog("timings de\n"); - 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; -// pclog("timings df\n"); - 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; + // pclog("timings d8\n"); + 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; + // pclog("timings d9\n"); + 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; + // pclog("timings da\n"); + 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; + // pclog("timings db\n"); + 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; + // pclog("timings dc\n"); + 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; + // pclog("timings dd\n"); + 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; + // pclog("timings de\n"); + 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; + // pclog("timings df\n"); + 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; -// pclog("timings 80 %p %p %p\n", (void *)timings, (void *)opcode_timings_mod3, (void *)opcode_timings_8x); - 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; -// pclog("timings 80 %p %p %p\n", (void *)timings, (void *)opcode_timings_mod3, (void *)opcode_timings_8x); - 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; + // pclog("timings 80 %p %p %p\n", (void *)timings, (void *)opcode_timings_mod3, + // (void *)opcode_timings_8x); + 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; + // pclog("timings 80 %p %p %p\n", (void *)timings, (void *)opcode_timings_mod3, + // (void *)opcode_timings_8x); + 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; -// pclog("timings c0\n"); - 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; + // pclog("timings c0\n"); + 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; -// pclog("timings d0\n"); - 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; + // pclog("timings d0\n"); + 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; -// pclog("timings d2\n"); - 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; + // pclog("timings d2\n"); + 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; -// pclog("timings f6\n"); - 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; -// pclog("timings f7\n"); - 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; -// pclog("timings ff\n"); - 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; + // pclog("timings f6\n"); + 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; + // pclog("timings f7\n"); + 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; + // pclog("timings ff\n"); + break; - default:timings = mod3 ? opcode_timings_mod3 : opcode_timings; - deps = mod3 ? opcode_deps_mod3 : opcode_deps; -// pclog("timings normal\n"); - break; - } - } + default: + timings = mod3 ? opcode_timings_mod3 : opcode_timings; + deps = mod3 ? opcode_deps_mod3 : opcode_deps; + // pclog("timings normal\n"); + break; + } + } - /*One prefix per instruction is free*/ - decode_delay--; - if (decode_delay < 0) - decode_delay = 0; + /*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 (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; + if (regmask & IMPL_ESP) + regmask |= SRCDEP_ESP | DSTDEP_ESP; - agi_stall = check_agi(prev_deps, prev_opcode, prev_fetchdat, prev_op_32); + 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; -// pclog("Not pairable %i\n", COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay); - } 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; -// pclog("Not pairable %i\n", COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay); - } 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; -// pclog("Not pairable %i\n", COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay); - } 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; + /*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; + // pclog("Not pairable %i\n", COUNT(prev_timings[prev_opcode], prev_op_32) + + // decode_delay); + } 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; + // pclog("Not pairable %i\n", COUNT(prev_timings[prev_opcode], prev_op_32) + + // decode_delay); + } 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; + // pclog("Not pairable %i\n", COUNT(prev_timings[prev_opcode], prev_op_32) + + // decode_delay); + } 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); + if (!t_pair) + fatal("Pairable 0 cycles! %02x %02x\n", opcode, prev_opcode); - agi_stall = check_agi(deps, opcode, fetchdat, op_32); + agi_stall = check_agi(deps, opcode, fetchdat, op_32); - codegen_block_cycles += t_pair + agi_stall; - decode_delay = (-t_pair) + 1 + agi_stall; + 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; -// pclog("Pairable %i %i %i %02x %02x\n", t_pair, t1, t2, opcode, prev_opcode); - return; - } - } + last_regmask_modified = regmask_modified; + regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8) | prev_regmask; + prev_full = 0; + // pclog("Pairable %i %i %i %02x %02x\n", t_pair, t1, t2, opcode, prev_opcode); + 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; + 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); + 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); -// pclog("Not pairable %i\n", COUNT(timings[opcode], op_32) + decode_delay); - } else { - /*Instruction might pair with next*/ -// pclog("Might pair - %02x %02x %08x %08x %08x %p %p %p\n", last_prefix, opcode, timings[opcode], timings[opcode] & PAIR_MASK, PAIR_X_BRANCH, timings, opcode_timings_0f, opcode_timings_0f_mod3); - 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; - } - } + 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); + // pclog("Not pairable %i\n", COUNT(timings[opcode], op_32) + decode_delay); + } else { + /*Instruction might pair with next*/ + // pclog("Might pair - %02x %02x %08x %08x %08x %p %p %p\n", last_prefix, opcode, + // timings[opcode], timings[opcode] & PAIR_MASK, PAIR_X_BRANCH, timings, + // opcode_timings_0f, opcode_timings_0f_mod3); + 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; - } + if (prev_full) { + /*Run previous now*/ + codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay; + prev_full = 0; + } } -int codegen_timing_686_jump_cycles() { - return 0; -} +int codegen_timing_686_jump_cycles() { return 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, - codegen_timing_686_jump_cycles - }; +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, codegen_timing_686_jump_cycles}; diff --git a/src/codegen/codegen_timing_common.c b/src/codegen/codegen_timing_common.c index 1bcb965f..cd90248d 100644 --- a/src/codegen/codegen_timing_common.c +++ b/src/codegen/codegen_timing_common.c @@ -1,847 +1,1162 @@ #include "ibm.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 | HAS_IMM8, SRCDEP_EAX | DSTDEP_EAX | HAS_IMM1632, 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 | HAS_IMM8, SRCDEP_EAX | DSTDEP_EAX | HAS_IMM1632, 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 | HAS_IMM8, SRCDEP_EAX | DSTDEP_EAX | HAS_IMM1632, 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 | HAS_IMM8, SRCDEP_EAX | DSTDEP_EAX | HAS_IMM1632, 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 | HAS_IMM8, SRCDEP_EAX | DSTDEP_EAX | HAS_IMM1632, 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 | HAS_IMM8, SRCDEP_EAX | DSTDEP_EAX | HAS_IMM1632, 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 | HAS_IMM8, SRCDEP_EAX | DSTDEP_EAX | HAS_IMM1632, 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 | HAS_IMM8, SRCDEP_EAX | HAS_IMM1632, 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 | HAS_IMM1632, DSTDEP_REG | MODRM, IMPL_ESP | HAS_IMM8, 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 | HAS_IMM8, DSTDEP_ECX | HAS_IMM8, DSTDEP_EDX | HAS_IMM8, DSTDEP_EBX | HAS_IMM8, - DSTDEP_EAX | HAS_IMM8, DSTDEP_ECX | HAS_IMM8, DSTDEP_EDX | HAS_IMM8, DSTDEP_EBX | HAS_IMM8, - DSTDEP_EAX | HAS_IMM1632, DSTDEP_ECX | HAS_IMM1632, DSTDEP_EDX | HAS_IMM1632, DSTDEP_EBX | HAS_IMM1632, - DSTDEP_ESP | HAS_IMM1632, DSTDEP_EBP | HAS_IMM1632, DSTDEP_ESI | HAS_IMM1632, DSTDEP_EDI | HAS_IMM1632, - -/* RET imm RET*/ -/*c0*/ 0, 0, SRCDEP_ESP | DSTDEP_ESP, IMPL_ESP, -/* LES LDS MOV MOV*/ - DSTDEP_REG | MODRM, DSTDEP_REG | MODRM, MODRM | HAS_IMM8, MODRM | HAS_IMM1632, -/* 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 | HAS_IMM8, SRCDEP_EAX | DSTDEP_EAX | HAS_IMM1632, 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 | HAS_IMM8, SRCDEP_EAX | DSTDEP_EAX | HAS_IMM1632, 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 | HAS_IMM8, SRCDEP_EAX | DSTDEP_EAX | HAS_IMM1632, 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 | HAS_IMM8, SRCDEP_EAX | DSTDEP_EAX | HAS_IMM1632, 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 | HAS_IMM8, SRCDEP_EAX | DSTDEP_EAX | HAS_IMM1632, 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 | HAS_IMM8, SRCDEP_EAX | DSTDEP_EAX | HAS_IMM1632, 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 | HAS_IMM8, SRCDEP_EAX | DSTDEP_EAX | HAS_IMM1632, 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 | HAS_IMM8, SRCDEP_EAX | HAS_IMM1632, 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 | HAS_IMM1632, DSTDEP_REG | SRCDEP_RM | MODRM, IMPL_ESP | HAS_IMM8, 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 | HAS_IMM8, DSTDEP_ECX | HAS_IMM8, DSTDEP_EDX | HAS_IMM8, DSTDEP_EBX | HAS_IMM8, - DSTDEP_EAX | HAS_IMM8, DSTDEP_ECX | HAS_IMM8, DSTDEP_EDX | HAS_IMM8, DSTDEP_EBX | HAS_IMM8, - DSTDEP_EAX | HAS_IMM1632, DSTDEP_ECX | HAS_IMM1632, DSTDEP_EDX | HAS_IMM1632, DSTDEP_EBX | HAS_IMM1632, - DSTDEP_ESP | HAS_IMM1632, DSTDEP_EBP | HAS_IMM1632, DSTDEP_ESI | HAS_IMM1632, DSTDEP_EDI | HAS_IMM1632, - -/* 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 | HAS_IMM8, DSTDEP_RM | MODRM | HAS_IMM1632, -/* 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, MODRM, 0, MODRM, - -/*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, MODRM, 0, MODRM, - -/*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_0f0f[256] = - { -/*00*/ 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, MODRM, 0, 0, - -/*10*/ 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, MODRM, 0, 0, - -/*20*/ 0, 0, 0, 0, - 0, 0, 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*/ 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/*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*/ MODRM, 0, 0, 0, - MODRM, 0, MODRM, MODRM, - 0, 0, MODRM, 0, - 0, 0, MODRM, 0, - -/*a0*/ MODRM, 0, 0, 0, - MODRM, 0, MODRM, MODRM, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/*b0*/ MODRM, 0, 0, 0, - MODRM, 0, MODRM, MODRM, - 0, 0, 0, 0, - 0, 0, 0, MODRM, - -/*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, - }; -uint64_t opcode_deps_0f0f_mod3[256] = - { -/*00*/ 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, MODRM, 0, 0, - -/*10*/ 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, MODRM, 0, 0, - -/*20*/ 0, 0, 0, 0, - 0, 0, 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*/ 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/*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*/ MODRM, 0, 0, 0, - MODRM, 0, MODRM, MODRM, - 0, 0, MODRM, 0, - 0, 0, MODRM, 0, - -/*a0*/ MODRM, 0, 0, 0, - MODRM, 0, MODRM, MODRM, - 0, 0, 0, 0, - 0, 0, 0, 0, - -/*b0*/ MODRM, 0, 0, 0, - MODRM, 0, MODRM, MODRM, - 0, 0, 0, 0, - 0, 0, 0, MODRM, - -/*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, - }; - -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 | HAS_IMM1632, MODRM | HAS_IMM1632, MODRM | HAS_IMM1632, MODRM | HAS_IMM1632, - MODRM | HAS_IMM1632, MODRM | HAS_IMM1632, MODRM | HAS_IMM1632, MODRM | HAS_IMM1632 - }; -uint64_t opcode_deps_81_mod3[8] = - { - SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, - SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, SRCDEP_RM | MODRM | HAS_IMM1632 - }; -uint64_t opcode_deps_8x[8] = - { - MODRM | HAS_IMM8, MODRM | HAS_IMM8, MODRM | HAS_IMM8, MODRM | HAS_IMM8, - MODRM | HAS_IMM8, MODRM | HAS_IMM8, MODRM | HAS_IMM8, MODRM | HAS_IMM8 - }; -uint64_t opcode_deps_8x_mod3[8] = - { - SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, - SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, SRCDEP_RM | MODRM | HAS_IMM8 - }; +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 | HAS_IMM8, SRCDEP_EAX | DSTDEP_EAX | HAS_IMM1632, 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 | HAS_IMM8, SRCDEP_EAX | DSTDEP_EAX | HAS_IMM1632, 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 | HAS_IMM8, SRCDEP_EAX | DSTDEP_EAX | HAS_IMM1632, 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 | HAS_IMM8, SRCDEP_EAX | DSTDEP_EAX | HAS_IMM1632, 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 | HAS_IMM8, SRCDEP_EAX | DSTDEP_EAX | HAS_IMM1632, 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 | HAS_IMM8, SRCDEP_EAX | DSTDEP_EAX | HAS_IMM1632, 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 | HAS_IMM8, SRCDEP_EAX | DSTDEP_EAX | HAS_IMM1632, 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 | HAS_IMM8, SRCDEP_EAX | HAS_IMM1632, 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 | HAS_IMM1632, DSTDEP_REG | MODRM, IMPL_ESP | HAS_IMM8, 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 | HAS_IMM8, DSTDEP_ECX | HAS_IMM8, DSTDEP_EDX | HAS_IMM8, DSTDEP_EBX | HAS_IMM8, + DSTDEP_EAX | HAS_IMM8, DSTDEP_ECX | HAS_IMM8, DSTDEP_EDX | HAS_IMM8, DSTDEP_EBX | HAS_IMM8, + DSTDEP_EAX | HAS_IMM1632, DSTDEP_ECX | HAS_IMM1632, DSTDEP_EDX | HAS_IMM1632, DSTDEP_EBX | HAS_IMM1632, + DSTDEP_ESP | HAS_IMM1632, DSTDEP_EBP | HAS_IMM1632, DSTDEP_ESI | HAS_IMM1632, DSTDEP_EDI | HAS_IMM1632, + + /* RET imm RET*/ + /*c0*/ 0, 0, SRCDEP_ESP | DSTDEP_ESP, IMPL_ESP, + /* LES LDS MOV MOV*/ + DSTDEP_REG | MODRM, DSTDEP_REG | MODRM, MODRM | HAS_IMM8, MODRM | HAS_IMM1632, + /* 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 | HAS_IMM8, SRCDEP_EAX | DSTDEP_EAX | HAS_IMM1632, 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 | HAS_IMM8, SRCDEP_EAX | DSTDEP_EAX | HAS_IMM1632, 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 | HAS_IMM8, SRCDEP_EAX | DSTDEP_EAX | HAS_IMM1632, 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 | HAS_IMM8, SRCDEP_EAX | DSTDEP_EAX | HAS_IMM1632, 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 | HAS_IMM8, SRCDEP_EAX | DSTDEP_EAX | HAS_IMM1632, 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 | HAS_IMM8, SRCDEP_EAX | DSTDEP_EAX | HAS_IMM1632, 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 | HAS_IMM8, SRCDEP_EAX | DSTDEP_EAX | HAS_IMM1632, 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 | HAS_IMM8, SRCDEP_EAX | HAS_IMM1632, 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 | HAS_IMM1632, DSTDEP_REG | SRCDEP_RM | MODRM, IMPL_ESP | HAS_IMM8, + 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 | HAS_IMM8, DSTDEP_ECX | HAS_IMM8, DSTDEP_EDX | HAS_IMM8, DSTDEP_EBX | HAS_IMM8, + DSTDEP_EAX | HAS_IMM8, DSTDEP_ECX | HAS_IMM8, DSTDEP_EDX | HAS_IMM8, DSTDEP_EBX | HAS_IMM8, + DSTDEP_EAX | HAS_IMM1632, DSTDEP_ECX | HAS_IMM1632, DSTDEP_EDX | HAS_IMM1632, + DSTDEP_EBX | HAS_IMM1632, DSTDEP_ESP | HAS_IMM1632, DSTDEP_EBP | HAS_IMM1632, + DSTDEP_ESI | HAS_IMM1632, DSTDEP_EDI | HAS_IMM1632, + + /* 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 | HAS_IMM8, + DSTDEP_RM | MODRM | HAS_IMM1632, + /* 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, + MODRM, + 0, + MODRM, + + /*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, + MODRM, + 0, + MODRM, + + /*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_0f0f[256] = { + /*00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MODRM, 0, 0, + + /*10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MODRM, 0, 0, + + /*20*/ 0, 0, 0, 0, 0, 0, 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*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + /*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*/ MODRM, 0, 0, 0, MODRM, 0, MODRM, MODRM, 0, 0, MODRM, 0, 0, 0, MODRM, 0, + + /*a0*/ MODRM, 0, 0, 0, MODRM, 0, MODRM, MODRM, 0, 0, 0, 0, 0, 0, 0, 0, + + /*b0*/ MODRM, 0, 0, 0, MODRM, 0, MODRM, MODRM, 0, 0, 0, 0, 0, 0, 0, MODRM, + + /*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, +}; +uint64_t opcode_deps_0f0f_mod3[256] = { + /*00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MODRM, 0, 0, + + /*10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MODRM, 0, 0, + + /*20*/ 0, 0, 0, 0, 0, 0, 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*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + /*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*/ MODRM, 0, 0, 0, MODRM, 0, MODRM, MODRM, 0, 0, MODRM, 0, 0, 0, MODRM, 0, + + /*a0*/ MODRM, 0, 0, 0, MODRM, 0, MODRM, MODRM, 0, 0, 0, 0, 0, 0, 0, 0, + + /*b0*/ MODRM, 0, 0, 0, MODRM, 0, MODRM, MODRM, 0, 0, 0, 0, 0, 0, 0, MODRM, + + /*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, +}; + +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 | HAS_IMM1632, MODRM | HAS_IMM1632, MODRM | HAS_IMM1632, MODRM | HAS_IMM1632, + MODRM | HAS_IMM1632, MODRM | HAS_IMM1632, MODRM | HAS_IMM1632, MODRM | HAS_IMM1632}; +uint64_t opcode_deps_81_mod3[8] = {SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, + SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, + SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, + SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM1632, SRCDEP_RM | MODRM | HAS_IMM1632}; +uint64_t opcode_deps_8x[8] = {MODRM | HAS_IMM8, MODRM | HAS_IMM8, MODRM | HAS_IMM8, MODRM | HAS_IMM8, + MODRM | HAS_IMM8, MODRM | HAS_IMM8, MODRM | HAS_IMM8, MODRM | HAS_IMM8}; +uint64_t opcode_deps_8x_mod3[8] = {SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, + SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, + SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, + SRCDEP_RM | DSTDEP_RM | MODRM | HAS_IMM8, SRCDEP_RM | MODRM | HAS_IMM8}; diff --git a/src/codegen/codegen_timing_cyrixiii.c b/src/codegen/codegen_timing_cyrixiii.c index 8e30c890..2f1f5de6 100644 --- a/src/codegen/codegen_timing_cyrixiii.c +++ b/src/codegen/codegen_timing_cyrixiii.c @@ -26,15 +26,15 @@ #define CYCLES_FPU (1 << 30) -#define CYCLES_IS_MMX_MUL (1 << 29) +#define CYCLES_IS_MMX_MUL (1 << 29) #define CYCLES_IS_MMX_SHIFT (1 << 28) -#define CYCLES_IS_MMX_ANY (1 << 27) -#define CYCLES_IS_3DNOW (1 << 26) +#define CYCLES_IS_MMX_ANY (1 << 27) +#define CYCLES_IS_3DNOW (1 << 26) -#define CYCLES_MMX_MUL(c) (CYCLES_IS_MMX_MUL | c) +#define CYCLES_MMX_MUL(c) (CYCLES_IS_MMX_MUL | c) #define CYCLES_MMX_SHIFT(c) (CYCLES_IS_MMX_SHIFT | c) -#define CYCLES_MMX_ANY(c) (CYCLES_IS_MMX_ANY | c) -#define CYCLES_3DNOW(c) (CYCLES_IS_3DNOW | c) +#define CYCLES_MMX_ANY(c) (CYCLES_IS_MMX_ANY | c) +#define CYCLES_3DNOW(c) (CYCLES_IS_3DNOW | c) #define CYCLES_IS_MMX (CYCLES_IS_MMX_MUL | CYCLES_IS_MMX_SHIFT | CYCLES_IS_MMX_ANY | CYCLES_IS_3DNOW) @@ -60,320 +60,803 @@ #define INVALID 0 -static uint32_t opcode_timings[256] = - { -/*00*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), INVALID, -/*10*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), -/*20*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(3), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(3), -/*30*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), +static uint32_t opcode_timings[256] = { + /*00*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), + CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), INVALID, + /*10*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), + CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), + /*20*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(3), + CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(3), + /*30*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), + CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), -/*40*/ 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), -/*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(1), CYCLES(1), CYCLES(1), CYCLES2(17, 25), CYCLES(1), CYCLES2(17, 20), CYCLES(17), CYCLES(17), CYCLES(17), CYCLES(17), -/*70*/ 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), + /*40*/ 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), + /*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(1), CYCLES(1), + CYCLES(1), CYCLES2(17, 25), CYCLES(1), CYCLES2(17, 20), CYCLES(17), CYCLES(17), CYCLES(17), CYCLES(17), + /*70*/ 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), -/*80*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(2), 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*/ 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), + /*80*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(2), 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*/ 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), -/*c0*/ CYCLES(1), CYCLES(1), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6), CYCLES(1), CYCLES(1), CYCLES(14), CYCLES(5), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(3), CYCLES(0), -/*d0*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(15), CYCLES(14), CYCLES(2), CYCLES(4), INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, -/*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), INVALID, INVALID, CYCLES(2), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(3), INVALID - }; + /*c0*/ CYCLES(1), CYCLES(1), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6), CYCLES(1), CYCLES(1), + CYCLES(14), CYCLES(5), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(3), CYCLES(0), + /*d0*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(15), CYCLES(14), CYCLES(2), CYCLES(4), + INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, + /*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), INVALID, INVALID, + CYCLES(2), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(3), INVALID}; -static uint32_t opcode_timings_mod3[256] = - { -/*00*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), INVALID, -/*10*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), -/*20*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(3), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(3), -/*30*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), +static uint32_t opcode_timings_mod3[256] = { + /*00*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), + CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), INVALID, + /*10*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), + CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), + /*20*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(3), + CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(3), + /*30*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), + CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), -/*40*/ 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), -/*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(1), CYCLES(1), CYCLES(1), CYCLES2(14, 25), CYCLES(1), CYCLES2(17, 20), CYCLES(17), CYCLES(17), CYCLES(17), CYCLES(17), -/*70*/ 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), + /*40*/ 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), + /*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(1), CYCLES(1), + CYCLES(1), CYCLES2(14, 25), CYCLES(1), CYCLES2(17, 20), CYCLES(17), CYCLES(17), CYCLES(17), CYCLES(17), + /*70*/ 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), -/*80*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), 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*/ 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), + /*80*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), 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*/ 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), -/*c0*/ CYCLES(1), CYCLES(1), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6), CYCLES(1), CYCLES(1), CYCLES(14), CYCLES(5), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(3), CYCLES(0), -/*d0*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(15), CYCLES(14), CYCLES(2), CYCLES(4), INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, -/*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), INVALID, INVALID, CYCLES(2), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(3), INVALID, - }; + /*c0*/ CYCLES(1), CYCLES(1), CYCLES(5), CYCLES(5), CYCLES(6), CYCLES(6), CYCLES(1), CYCLES(1), + CYCLES(14), CYCLES(5), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(0), CYCLES(3), CYCLES(0), + /*d0*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(15), CYCLES(14), CYCLES(2), CYCLES(4), + INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, + /*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), INVALID, INVALID, + CYCLES(2), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(3), INVALID, +}; -static uint32_t opcode_timings_0f[256] = - { -/*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), INVALID, CYCLES(195), CYCLES(7), INVALID, CYCLES(1000), CYCLES(10000), INVALID, INVALID, INVALID, CYCLES_3DNOW(1), CYCLES(1), CYCLES_3DNOW(1), -/*10*/ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, -/*20*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, -/*30*/ CYCLES(9), CYCLES(1), CYCLES(9), INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, +static uint32_t opcode_timings_0f[256] = { + /*00*/ CYCLES(20), + CYCLES(11), + CYCLES(11), + CYCLES(10), + INVALID, + CYCLES(195), + CYCLES(7), + INVALID, + CYCLES(1000), + CYCLES(10000), + INVALID, + INVALID, + INVALID, + CYCLES_3DNOW(1), + CYCLES(1), + CYCLES_3DNOW(1), + /*10*/ INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + /*20*/ CYCLES(6), + CYCLES(6), + CYCLES(6), + CYCLES(6), + CYCLES(6), + CYCLES(6), + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + /*30*/ CYCLES(9), + CYCLES(1), + 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*/ CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), - CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), INVALID, INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), -/*70*/ INVALID, CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES(100), INVALID, INVALID, INVALID, INVALID, INVALID, - INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), + /*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*/ CYCLES_MMX_SHIFT(1), + CYCLES_MMX_SHIFT(1), + CYCLES_MMX_SHIFT(1), + CYCLES_MMX_SHIFT(1), + CYCLES_MMX_ANY(1), + CYCLES_MMX_ANY(1), + CYCLES_MMX_ANY(1), + CYCLES_MMX_SHIFT(1), + CYCLES_MMX_SHIFT(1), + CYCLES_MMX_SHIFT(1), + CYCLES_MMX_SHIFT(1), + CYCLES_MMX_SHIFT(1), + INVALID, + INVALID, + CYCLES_MMX_ANY(1), + CYCLES_MMX_ANY(1), + /*70*/ INVALID, + CYCLES_MMX_SHIFT(1), + CYCLES_MMX_SHIFT(1), + CYCLES_MMX_SHIFT(1), + CYCLES_MMX_ANY(1), + CYCLES_MMX_ANY(1), + CYCLES_MMX_ANY(1), + CYCLES(100), + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + CYCLES_MMX_ANY(1), + CYCLES_MMX_ANY(1), -/*80*/ 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), -/*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), INVALID, INVALID, CYCLES(3), CYCLES(3), INVALID, CYCLES(13), CYCLES(3), CYCLES(3), INVALID, CYCLES2(18, 30), -/*b0*/ CYCLES(10), CYCLES(10), CYCLES(6), CYCLES(13), CYCLES(6), CYCLES(6), CYCLES(3), CYCLES(3), INVALID, INVALID, CYCLES(6), CYCLES(13), CYCLES(7), CYCLES(7), CYCLES(3), CYCLES(3), + /*80*/ 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), + /*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), + INVALID, + INVALID, + CYCLES(3), + CYCLES(3), + INVALID, + CYCLES(13), + CYCLES(3), + CYCLES(3), + INVALID, + CYCLES2(18, 30), + /*b0*/ CYCLES(10), + CYCLES(10), + CYCLES(6), + CYCLES(13), + CYCLES(6), + CYCLES(6), + CYCLES(3), + CYCLES(3), + INVALID, + INVALID, + CYCLES(6), + CYCLES(13), + CYCLES(7), + CYCLES(7), + CYCLES(3), + CYCLES(3), -/*c0*/ CYCLES(4), CYCLES(4), INVALID, INVALID, INVALID, INVALID, INVALID, CYCLES(3), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), -/*d0*/ INVALID, CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), INVALID, CYCLES_MMX_MUL(1), INVALID, INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), INVALID, CYCLES_MMX_ANY(1), - CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), INVALID, CYCLES_MMX_ANY(1), -/*e0*/ INVALID, CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), INVALID, INVALID, CYCLES_MMX_MUL(1), INVALID, INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), - CYCLES_MMX_ANY(1), INVALID, CYCLES_MMX_ANY(1), -/*f0*/ INVALID, CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), INVALID, CYCLES_MMX_MUL(1), INVALID, INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), INVALID, - CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(2), INVALID, - }; -static uint32_t opcode_timings_0f_mod3[256] = - { -/*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), INVALID, CYCLES(195), CYCLES(7), INVALID, CYCLES(1000), CYCLES(10000), INVALID, INVALID, INVALID, CYCLES_3DNOW(1), CYCLES(1), CYCLES_3DNOW(1), -/*10*/ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, -/*20*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, -/*30*/ CYCLES(9), CYCLES(1), CYCLES(9), INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, + /*c0*/ CYCLES(4), + CYCLES(4), + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + CYCLES(3), + CYCLES(1), + CYCLES(1), + CYCLES(1), + CYCLES(1), + CYCLES(1), + CYCLES(1), + CYCLES(1), + CYCLES(1), + /*d0*/ INVALID, + CYCLES_MMX_SHIFT(1), + CYCLES_MMX_SHIFT(1), + CYCLES_MMX_SHIFT(1), + INVALID, + CYCLES_MMX_MUL(1), + INVALID, + INVALID, + CYCLES_MMX_ANY(1), + CYCLES_MMX_ANY(1), + INVALID, + CYCLES_MMX_ANY(1), + CYCLES_MMX_ANY(1), + CYCLES_MMX_ANY(1), + INVALID, + CYCLES_MMX_ANY(1), + /*e0*/ INVALID, + CYCLES_MMX_SHIFT(1), + CYCLES_MMX_SHIFT(1), + INVALID, + INVALID, + CYCLES_MMX_MUL(1), + INVALID, + INVALID, + CYCLES_MMX_ANY(1), + CYCLES_MMX_ANY(1), + INVALID, + CYCLES_MMX_ANY(1), + CYCLES_MMX_ANY(1), + CYCLES_MMX_ANY(1), + INVALID, + CYCLES_MMX_ANY(1), + /*f0*/ INVALID, + CYCLES_MMX_SHIFT(1), + CYCLES_MMX_SHIFT(1), + CYCLES_MMX_SHIFT(1), + INVALID, + CYCLES_MMX_MUL(1), + INVALID, + INVALID, + CYCLES_MMX_ANY(1), + CYCLES_MMX_ANY(1), + CYCLES_MMX_ANY(1), + INVALID, + CYCLES_MMX_ANY(1), + CYCLES_MMX_ANY(1), + CYCLES_MMX_ANY(2), + INVALID, +}; +static uint32_t opcode_timings_0f_mod3[256] = { + /*00*/ CYCLES(20), + CYCLES(11), + CYCLES(11), + CYCLES(10), + INVALID, + CYCLES(195), + CYCLES(7), + INVALID, + CYCLES(1000), + CYCLES(10000), + INVALID, + INVALID, + INVALID, + CYCLES_3DNOW(1), + CYCLES(1), + CYCLES_3DNOW(1), + /*10*/ INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + /*20*/ CYCLES(6), + CYCLES(6), + CYCLES(6), + CYCLES(6), + CYCLES(6), + CYCLES(6), + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + /*30*/ CYCLES(9), + CYCLES(1), + 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*/ CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), - CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), INVALID, INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), -/*70*/ INVALID, CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES(100), INVALID, INVALID, INVALID, INVALID, INVALID, - INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), + /*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*/ CYCLES_MMX_SHIFT(1), + CYCLES_MMX_SHIFT(1), + CYCLES_MMX_SHIFT(1), + CYCLES_MMX_SHIFT(1), + CYCLES_MMX_ANY(1), + CYCLES_MMX_ANY(1), + CYCLES_MMX_ANY(1), + CYCLES_MMX_SHIFT(1), + CYCLES_MMX_SHIFT(1), + CYCLES_MMX_SHIFT(1), + CYCLES_MMX_SHIFT(1), + CYCLES_MMX_SHIFT(1), + INVALID, + INVALID, + CYCLES_MMX_ANY(1), + CYCLES_MMX_ANY(1), + /*70*/ INVALID, + CYCLES_MMX_SHIFT(1), + CYCLES_MMX_SHIFT(1), + CYCLES_MMX_SHIFT(1), + CYCLES_MMX_ANY(1), + CYCLES_MMX_ANY(1), + CYCLES_MMX_ANY(1), + CYCLES(100), + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + CYCLES_MMX_ANY(1), + CYCLES_MMX_ANY(1), -/*80*/ 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), -/*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), INVALID, INVALID, CYCLES(3), CYCLES(3), INVALID, CYCLES(13), CYCLES(3), CYCLES(3), INVALID, CYCLES2(18, 30), -/*b0*/ CYCLES(10), CYCLES(10), CYCLES(6), CYCLES(13), CYCLES(6), CYCLES(6), CYCLES(3), CYCLES(3), INVALID, INVALID, CYCLES(6), CYCLES(13), CYCLES(7), CYCLES(7), CYCLES(3), CYCLES(3), + /*80*/ 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), + /*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), + INVALID, + INVALID, + CYCLES(3), + CYCLES(3), + INVALID, + CYCLES(13), + CYCLES(3), + CYCLES(3), + INVALID, + CYCLES2(18, 30), + /*b0*/ CYCLES(10), + CYCLES(10), + CYCLES(6), + CYCLES(13), + CYCLES(6), + CYCLES(6), + CYCLES(3), + CYCLES(3), + INVALID, + INVALID, + CYCLES(6), + CYCLES(13), + CYCLES(7), + CYCLES(7), + CYCLES(3), + CYCLES(3), -/*c0*/ CYCLES(4), CYCLES(4), INVALID, INVALID, INVALID, INVALID, INVALID, CYCLES(3), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), -/*d0*/ INVALID, CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), INVALID, CYCLES_MMX_MUL(1), INVALID, INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), INVALID, CYCLES_MMX_ANY(1), - CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), INVALID, CYCLES_MMX_ANY(1), -/*e0*/ INVALID, CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), INVALID, INVALID, CYCLES_MMX_MUL(1), INVALID, INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), - CYCLES_MMX_ANY(1), INVALID, CYCLES_MMX_ANY(1), -/*f0*/ INVALID, CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), INVALID, CYCLES_MMX_MUL(1), INVALID, INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), INVALID, - CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), INVALID, - }; + /*c0*/ CYCLES(4), + CYCLES(4), + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + CYCLES(3), + CYCLES(1), + CYCLES(1), + CYCLES(1), + CYCLES(1), + CYCLES(1), + CYCLES(1), + CYCLES(1), + CYCLES(1), + /*d0*/ INVALID, + CYCLES_MMX_SHIFT(1), + CYCLES_MMX_SHIFT(1), + CYCLES_MMX_SHIFT(1), + INVALID, + CYCLES_MMX_MUL(1), + INVALID, + INVALID, + CYCLES_MMX_ANY(1), + CYCLES_MMX_ANY(1), + INVALID, + CYCLES_MMX_ANY(1), + CYCLES_MMX_ANY(1), + CYCLES_MMX_ANY(1), + INVALID, + CYCLES_MMX_ANY(1), + /*e0*/ INVALID, + CYCLES_MMX_SHIFT(1), + CYCLES_MMX_SHIFT(1), + INVALID, + INVALID, + CYCLES_MMX_MUL(1), + INVALID, + INVALID, + CYCLES_MMX_ANY(1), + CYCLES_MMX_ANY(1), + INVALID, + CYCLES_MMX_ANY(1), + CYCLES_MMX_ANY(1), + CYCLES_MMX_ANY(1), + INVALID, + CYCLES_MMX_ANY(1), + /*f0*/ INVALID, + CYCLES_MMX_SHIFT(1), + CYCLES_MMX_SHIFT(1), + CYCLES_MMX_SHIFT(1), + INVALID, + CYCLES_MMX_MUL(1), + INVALID, + INVALID, + CYCLES_MMX_ANY(1), + CYCLES_MMX_ANY(1), + CYCLES_MMX_ANY(1), + INVALID, + CYCLES_MMX_ANY(1), + CYCLES_MMX_ANY(1), + CYCLES_MMX_ANY(1), + INVALID, +}; -static uint32_t opcode_timings_shift[8] = - { - CYCLES(7), CYCLES(7), CYCLES(10), CYCLES(10), CYCLES(7), CYCLES(7), CYCLES(7), CYCLES(7) - }; -static uint32_t opcode_timings_shift_mod3[8] = - { - CYCLES(3), CYCLES(3), CYCLES(9), CYCLES(9), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3) - }; +static uint32_t opcode_timings_shift[8] = {CYCLES(7), CYCLES(7), CYCLES(10), CYCLES(10), + CYCLES(7), CYCLES(7), CYCLES(7), CYCLES(7)}; +static uint32_t opcode_timings_shift_mod3[8] = {CYCLES(3), CYCLES(3), CYCLES(9), CYCLES(9), + CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3)}; -static uint32_t opcode_timings_f6[8] = - { - CYCLES(2), INVALID, CYCLES(2), CYCLES(2), CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19) - }; -static uint32_t opcode_timings_f6_mod3[8] = - { - CYCLES(1), INVALID, CYCLES(1), CYCLES(1), CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19) - }; -static uint32_t opcode_timings_f7[8] = - { - CYCLES(2), INVALID, CYCLES(2), CYCLES(2), CYCLES(21), CYCLES2(22, 38), CYCLES2(24, 40), CYCLES2(27, 43) - }; -static uint32_t opcode_timings_f7_mod3[8] = - { - CYCLES(1), INVALID, CYCLES(1), CYCLES(1), CYCLES(21), CYCLES2(22, 38), CYCLES2(24, 40), CYCLES2(27, 43) - }; -static uint32_t opcode_timings_ff[8] = - { - CYCLES(2), CYCLES(2), CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), INVALID - }; -static uint32_t opcode_timings_ff_mod3[8] = - { - CYCLES(1), CYCLES(1), CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), INVALID - }; +static uint32_t opcode_timings_f6[8] = {CYCLES(2), INVALID, CYCLES(2), CYCLES(2), CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19)}; +static uint32_t opcode_timings_f6_mod3[8] = {CYCLES(1), INVALID, CYCLES(1), CYCLES(1), + CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19)}; +static uint32_t opcode_timings_f7[8] = {CYCLES(2), INVALID, CYCLES(2), CYCLES(2), + CYCLES(21), CYCLES2(22, 38), CYCLES2(24, 40), CYCLES2(27, 43)}; +static uint32_t opcode_timings_f7_mod3[8] = {CYCLES(1), INVALID, CYCLES(1), CYCLES(1), + CYCLES(21), CYCLES2(22, 38), CYCLES2(24, 40), CYCLES2(27, 43)}; +static uint32_t opcode_timings_ff[8] = {CYCLES(2), CYCLES(2), CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), INVALID}; +static uint32_t opcode_timings_ff_mod3[8] = {CYCLES(1), CYCLES(1), CYCLES(5), CYCLES(0), + CYCLES(5), CYCLES(0), CYCLES(5), INVALID}; -static uint32_t opcode_timings_d8[8] = - { -/* FADDs FMULs FCOMs FCOMPs*/ - FPU_CYCLES(4, 2, 2), FPU_CYCLES(4, 2, 2), FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), -/* FSUBs FSUBRs FDIVs FDIVRs*/ - FPU_CYCLES(4, 2, 2), FPU_CYCLES(4, 2, 2), FPU_CYCLES(39, 38, 2), FPU_CYCLES(39, 38, 2) - }; -static uint32_t opcode_timings_d8_mod3[8] = - { -/* FADD FMUL FCOM FCOMP*/ - FPU_CYCLES(4, 2, 2), FPU_CYCLES(4, 2, 2), FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), -/* FSUB FSUBR FDIV FDIVR*/ - FPU_CYCLES(4, 2, 2), FPU_CYCLES(4, 2, 2), FPU_CYCLES(39, 38, 2), FPU_CYCLES(39, 38, 2) - }; +static uint32_t opcode_timings_d8[8] = { + /* FADDs FMULs FCOMs FCOMPs*/ + FPU_CYCLES(4, 2, 2), FPU_CYCLES(4, 2, 2), FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), + /* FSUBs FSUBRs FDIVs FDIVRs*/ + FPU_CYCLES(4, 2, 2), FPU_CYCLES(4, 2, 2), FPU_CYCLES(39, 38, 2), FPU_CYCLES(39, 38, 2)}; +static uint32_t opcode_timings_d8_mod3[8] = { + /* FADD FMUL FCOM FCOMP*/ + FPU_CYCLES(4, 2, 2), FPU_CYCLES(4, 2, 2), FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), + /* FSUB FSUBR FDIV FDIVR*/ + FPU_CYCLES(4, 2, 2), FPU_CYCLES(4, 2, 2), FPU_CYCLES(39, 38, 2), FPU_CYCLES(39, 38, 2)}; -static uint32_t opcode_timings_d9[8] = - { -/* FLDs FSTs FSTPs*/ - FPU_CYCLES(2, 0, 0), INVALID, FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), -/* FLDENV FLDCW FSTENV FSTCW*/ - FPU_CYCLES(32, 0, 0), FPU_CYCLES(8, 0, 0), FPU_CYCLES(48, 0, 0), FPU_CYCLES(2, 0, 0) - }; -static uint32_t opcode_timings_d9_mod3[64] = - { - /*FLD*/ - FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), - FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), - /*FXCH*/ - FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), - FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), - /*FNOP*/ - FPU_CYCLES(3, 0, 0), INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - /*FSTP*/ - FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), - FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), -/* opFCHS opFABS*/ - FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), INVALID, INVALID, -/* opFTST opFXAM*/ - FPU_CYCLES(2, 0, 0), FPU_CYCLES(21, 4, 0), INVALID, INVALID, -/* opFLD1 opFLDL2T opFLDL2E opFLDPI*/ - FPU_CYCLES(2, 0, 0), FPU_CYCLES(5, 2, 2), FPU_CYCLES(5, 2, 2), FPU_CYCLES(5, 2, 2), -/* opFLDEG2 opFLDLN2 opFLDZ*/ - FPU_CYCLES(5, 2, 2), FPU_CYCLES(5, 2, 2), FPU_CYCLES(2, 0, 0), INVALID, -/* opF2XM1 opFYL2X opFPTAN opFPATAN*/ - FPU_CYCLES(53, 2, 2), FPU_CYCLES(103, 2, 2), FPU_CYCLES(120, 36, 0), FPU_CYCLES(112, 2, 2), -/* opFDECSTP opFINCSTP,*/ - INVALID, INVALID, FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), -/* opFPREM opFSQRT opFSINCOS*/ - FPU_CYCLES(64, 2, 2), INVALID, FPU_CYCLES(70, 69, 2), FPU_CYCLES(89, 2, 2), -/* opFRNDINT opFSCALE opFSIN opFCOS*/ - FPU_CYCLES(9, 0, 0), FPU_CYCLES(20, 5, 0), FPU_CYCLES(65, 2, 2), FPU_CYCLES(65, 2, 2) - }; +static uint32_t opcode_timings_d9[8] = { + /* FLDs FSTs FSTPs*/ + FPU_CYCLES(2, 0, 0), INVALID, FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), + /* FLDENV FLDCW FSTENV FSTCW*/ + FPU_CYCLES(32, 0, 0), FPU_CYCLES(8, 0, 0), FPU_CYCLES(48, 0, 0), FPU_CYCLES(2, 0, 0)}; +static uint32_t opcode_timings_d9_mod3[64] = { + /*FLD*/ + FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), + FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), + /*FXCH*/ + FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), + FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), + /*FNOP*/ + FPU_CYCLES(3, 0, 0), INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, + /*FSTP*/ + FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), + FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), + /* opFCHS opFABS*/ + FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), INVALID, INVALID, + /* opFTST opFXAM*/ + FPU_CYCLES(2, 0, 0), FPU_CYCLES(21, 4, 0), INVALID, INVALID, + /* opFLD1 opFLDL2T opFLDL2E opFLDPI*/ + FPU_CYCLES(2, 0, 0), FPU_CYCLES(5, 2, 2), FPU_CYCLES(5, 2, 2), FPU_CYCLES(5, 2, 2), + /* opFLDEG2 opFLDLN2 opFLDZ*/ + FPU_CYCLES(5, 2, 2), FPU_CYCLES(5, 2, 2), FPU_CYCLES(2, 0, 0), INVALID, + /* opF2XM1 opFYL2X opFPTAN opFPATAN*/ + FPU_CYCLES(53, 2, 2), FPU_CYCLES(103, 2, 2), FPU_CYCLES(120, 36, 0), FPU_CYCLES(112, 2, 2), + /* opFDECSTP opFINCSTP,*/ + INVALID, INVALID, FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), + /* opFPREM opFSQRT opFSINCOS*/ + FPU_CYCLES(64, 2, 2), INVALID, FPU_CYCLES(70, 69, 2), FPU_CYCLES(89, 2, 2), + /* opFRNDINT opFSCALE opFSIN opFCOS*/ + FPU_CYCLES(9, 0, 0), FPU_CYCLES(20, 5, 0), FPU_CYCLES(65, 2, 2), FPU_CYCLES(65, 2, 2)}; -static uint32_t opcode_timings_da[8] = - { -/* FIADDl FIMULl FICOMl FICOMPl*/ - FPU_CYCLES(6, 2, 2), FPU_CYCLES(6, 2, 2), FPU_CYCLES(4, 0, 0), FPU_CYCLES(4, 0, 0), -/* FISUBl FISUBRl FIDIVl FIDIVRl*/ - FPU_CYCLES(6, 2, 2), FPU_CYCLES(6, 2, 2), FPU_CYCLES(42, 38, 2), FPU_CYCLES(42, 38, 2) - }; -static uint32_t opcode_timings_da_mod3[8] = - { - INVALID, INVALID, INVALID, INVALID, -/* FCOMPP*/ - INVALID, FPU_CYCLES(2, 0, 0), INVALID, INVALID - }; +static uint32_t opcode_timings_da[8] = { + /* FIADDl FIMULl FICOMl FICOMPl*/ + FPU_CYCLES(6, 2, 2), FPU_CYCLES(6, 2, 2), FPU_CYCLES(4, 0, 0), FPU_CYCLES(4, 0, 0), + /* FISUBl FISUBRl FIDIVl FIDIVRl*/ + FPU_CYCLES(6, 2, 2), FPU_CYCLES(6, 2, 2), FPU_CYCLES(42, 38, 2), FPU_CYCLES(42, 38, 2)}; +static uint32_t opcode_timings_da_mod3[8] = {INVALID, INVALID, INVALID, INVALID, + /* FCOMPP*/ + INVALID, FPU_CYCLES(2, 0, 0), INVALID, INVALID}; -static uint32_t opcode_timings_db[8] = - { -/* FLDil FSTil FSTPil*/ - FPU_CYCLES(3, 2, 2), INVALID, FPU_CYCLES(6, 0, 0), FPU_CYCLES(6, 0, 0), -/* FLDe FSTPe*/ - INVALID, FPU_CYCLES(3, 0, 0), INVALID, FPU_CYCLES(3, 0, 0) - }; -static uint32_t opcode_timings_db_mod3[64] = - { - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, +static uint32_t opcode_timings_db[8] = { + /* FLDil FSTil FSTPil*/ + FPU_CYCLES(3, 2, 2), INVALID, FPU_CYCLES(6, 0, 0), FPU_CYCLES(6, 0, 0), + /* FLDe FSTPe*/ + INVALID, FPU_CYCLES(3, 0, 0), INVALID, FPU_CYCLES(3, 0, 0)}; +static uint32_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, + 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, FPU_CYCLES(2, 0, 0), FPU_CYCLES(7, 0, 0), FPU_CYCLES(17, 0, 0), -/* opFNOP opFNOP*/ - FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), INVALID, INVALID, + /* opFNOP opFCLEX opFINIT*/ + INVALID, + FPU_CYCLES(2, 0, 0), + FPU_CYCLES(7, 0, 0), + FPU_CYCLES(17, 0, 0), + /* opFNOP opFNOP*/ + FPU_CYCLES(2, 0, 0), + FPU_CYCLES(2, 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, + 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*/ - FPU_CYCLES(4, 2, 2), FPU_CYCLES(4, 2, 2), FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), -/* FSUBd FSUBRd FDIVd FDIVRd*/ - FPU_CYCLES(4, 2, 2), FPU_CYCLES(4, 2, 2), FPU_CYCLES(39, 38, 2), FPU_CYCLES(39, 38, 2) - }; -static uint32_t opcode_timings_dc_mod3[8] = - { -/* opFADDr opFMULr*/ - FPU_CYCLES(4, 2, 2), FPU_CYCLES(4, 2, 2), INVALID, INVALID, -/* opFSUBRr opFSUBr opFDIVRr opFDIVr*/ - FPU_CYCLES(4, 2, 2), FPU_CYCLES(4, 2, 2), FPU_CYCLES(39, 38, 2), FPU_CYCLES(39, 38, 2) - }; +static uint32_t opcode_timings_dc[8] = { + /* FADDd FMULd FCOMd FCOMPd*/ + FPU_CYCLES(4, 2, 2), FPU_CYCLES(4, 2, 2), FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), + /* FSUBd FSUBRd FDIVd FDIVRd*/ + FPU_CYCLES(4, 2, 2), FPU_CYCLES(4, 2, 2), FPU_CYCLES(39, 38, 2), FPU_CYCLES(39, 38, 2)}; +static uint32_t opcode_timings_dc_mod3[8] = { + /* opFADDr opFMULr*/ + FPU_CYCLES(4, 2, 2), FPU_CYCLES(4, 2, 2), INVALID, INVALID, + /* opFSUBRr opFSUBr opFDIVRr opFDIVr*/ + FPU_CYCLES(4, 2, 2), FPU_CYCLES(4, 2, 2), FPU_CYCLES(39, 38, 2), FPU_CYCLES(39, 38, 2)}; -static uint32_t opcode_timings_dd[8] = - { -/* FLDd FSTd FSTPd*/ - FPU_CYCLES(2, 0, 0), INVALID, FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), -/* FRSTOR FSAVE FSTSW*/ - FPU_CYCLES(70, 0, 0), INVALID, FPU_CYCLES(127, 0, 0), FPU_CYCLES(6, 0, 0) - }; -static uint32_t opcode_timings_dd_mod3[8] = - { -/* FFFREE FST FSTP*/ - FPU_CYCLES(2, 0, 0), INVALID, FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), -/* FUCOM FUCOMP*/ - FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), INVALID, INVALID - }; +static uint32_t opcode_timings_dd[8] = { + /* FLDd FSTd FSTPd*/ + FPU_CYCLES(2, 0, 0), INVALID, FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), + /* FRSTOR FSAVE FSTSW*/ + FPU_CYCLES(70, 0, 0), INVALID, FPU_CYCLES(127, 0, 0), FPU_CYCLES(6, 0, 0)}; +static uint32_t opcode_timings_dd_mod3[8] = { + /* FFFREE FST FSTP*/ + FPU_CYCLES(2, 0, 0), INVALID, FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), + /* FUCOM FUCOMP*/ + FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), INVALID, INVALID}; -static uint32_t opcode_timings_de[8] = - { -/* FIADDw FIMULw FICOMw FICOMPw*/ - FPU_CYCLES(6, 2, 2), FPU_CYCLES(6, 2, 2), FPU_CYCLES(4, 0, 0), FPU_CYCLES(4, 0, 0), -/* FISUBw FISUBRw FIDIVw FIDIVRw*/ - FPU_CYCLES(6, 2, 2), FPU_CYCLES(6, 2, 2), FPU_CYCLES(42, 38, 2), FPU_CYCLES(42, 38, 2) - }; -static uint32_t opcode_timings_de_mod3[8] = - { -/* FADDP FMULP FCOMPP*/ - FPU_CYCLES(4, 2, 2), FPU_CYCLES(4, 2, 2), INVALID, FPU_CYCLES(2, 0, 0), -/* FSUBP FSUBRP FDIVP FDIVRP*/ - FPU_CYCLES(4, 2, 2), FPU_CYCLES(4, 2, 2), FPU_CYCLES(39, 38, 2), FPU_CYCLES(39, 38, 2) - }; +static uint32_t opcode_timings_de[8] = { + /* FIADDw FIMULw FICOMw FICOMPw*/ + FPU_CYCLES(6, 2, 2), FPU_CYCLES(6, 2, 2), FPU_CYCLES(4, 0, 0), FPU_CYCLES(4, 0, 0), + /* FISUBw FISUBRw FIDIVw FIDIVRw*/ + FPU_CYCLES(6, 2, 2), FPU_CYCLES(6, 2, 2), FPU_CYCLES(42, 38, 2), FPU_CYCLES(42, 38, 2)}; +static uint32_t opcode_timings_de_mod3[8] = { + /* FADDP FMULP FCOMPP*/ + FPU_CYCLES(4, 2, 2), FPU_CYCLES(4, 2, 2), INVALID, FPU_CYCLES(2, 0, 0), + /* FSUBP FSUBRP FDIVP FDIVRP*/ + FPU_CYCLES(4, 2, 2), FPU_CYCLES(4, 2, 2), FPU_CYCLES(39, 38, 2), FPU_CYCLES(39, 38, 2)}; -static uint32_t opcode_timings_df[8] = - { -/* FILDiw FISTiw FISTPiw*/ - FPU_CYCLES(3, 2, 2), INVALID, FPU_CYCLES(6, 0, 0), FPU_CYCLES(6, 0, 0), -/* FILDiq FBSTP FISTPiq*/ - INVALID, FPU_CYCLES(3, 2, 2), FPU_CYCLES(148, 0, 0), FPU_CYCLES(6, 0, 0) - }; -static uint32_t opcode_timings_df_mod3[8] = - { - INVALID, INVALID, INVALID, INVALID, -/* FSTSW AX*/ - FPU_CYCLES(6, 0, 0), INVALID, INVALID, INVALID - }; +static uint32_t opcode_timings_df[8] = { + /* FILDiw FISTiw FISTPiw*/ + FPU_CYCLES(3, 2, 2), INVALID, FPU_CYCLES(6, 0, 0), FPU_CYCLES(6, 0, 0), + /* FILDiq FBSTP FISTPiq*/ + INVALID, FPU_CYCLES(3, 2, 2), FPU_CYCLES(148, 0, 0), FPU_CYCLES(6, 0, 0)}; +static uint32_t opcode_timings_df_mod3[8] = {INVALID, INVALID, INVALID, INVALID, + /* FSTSW AX*/ + FPU_CYCLES(6, 0, 0), INVALID, INVALID, INVALID}; -static uint32_t opcode_timings_8x[8] = - { - CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2) - }; -static uint32_t opcode_timings_8x_mod3[8] = - { - CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2) - }; -static uint32_t opcode_timings_81[8] = - { - CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2) - }; -static uint32_t opcode_timings_81_mod3[8] = - { - CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2) - }; +static uint32_t opcode_timings_8x[8] = {CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2)}; +static uint32_t opcode_timings_8x_mod3[8] = {CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), + CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2)}; +static uint32_t opcode_timings_81[8] = {CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2)}; +static uint32_t opcode_timings_81_mod3[8] = {CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), + CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2)}; static int timing_count; static uint8_t last_prefix; @@ -383,273 +866,282 @@ static int fpu_latency; static int fpu_st_latency[8]; static inline int COUNT(uint32_t c, int op_32) { - if (c & CYCLES_FPU) - return FPU_I_LATENCY(c); - if (c & CYCLES_HAS_MULTI) { - if (op_32 & 0x100) - return (c >> 8) & 0xff; - return c & 0xff; - } - return GET_CYCLES(c); + if (c & CYCLES_FPU) + return FPU_I_LATENCY(c); + if (c & CYCLES_HAS_MULTI) { + if (op_32 & 0x100) + return (c >> 8) & 0xff; + return c & 0xff; + } + return GET_CYCLES(c); } 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); + 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); + /*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; + return (regmask_modified & addr_regmask) & ~REGMASK_IMPL_ESP; } static int codegen_fpu_latencies(uint64_t deps, int reg) { - int latency = fpu_latency; + 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]; + 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; + return latency; } -#define SUB_AND_CLAMP(latency, count) \ - latency -= count; \ - if (latency < 0) \ - latency = 0 +#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); + 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 void codegen_instruction(uint32_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; +static void codegen_instruction(uint32_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] & CYCLES_FPU) && !(deps[opcode] & FPU_FXCH)) - instr_cycles = latency = codegen_fpu_latencies(deps[opcode], fetchdat & 7); - else - instr_cycles = 0; + if ((timings[opcode] & CYCLES_FPU) && !(deps[opcode] & FPU_FXCH)) + instr_cycles = latency = codegen_fpu_latencies(deps[opcode], fetchdat & 7); + else + 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], 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 ((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], 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; + 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 < 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] & CYCLES_FPU) { - /* if (fpu_latency) - fatal("Bad latency FPU\n");*/ - fpu_latency = FPU_F_LATENCY(timings[opcode]); - } + 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] & CYCLES_FPU) { + /* if (fpu_latency) + fatal("Bad latency FPU\n");*/ + fpu_latency = FPU_F_LATENCY(timings[opcode]); + } - if (deps[opcode] & FPU_PUSH) { - int c; + 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]); - } - } + 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]); + } + } } static void codegen_timing_cyrixiii_block_start() { - regmask_modified = 0; - decode_delay = decode_delay_offset = 0; + regmask_modified = 0; + decode_delay = decode_delay_offset = 0; } static void codegen_timing_cyrixiii_start() { - timing_count = 0; - last_prefix = 0; + timing_count = 0; + last_prefix = 0; } static void codegen_timing_cyrixiii_prefix(uint8_t prefix, uint32_t fetchdat) { - if (prefix == 0x0f) { - /*0fh prefix is 'free'*/ - last_prefix = prefix; - return; - } - /*On C3 all prefixes take 1 cycle to decode. Decode may be shadowed - by execution of previous instructions*/ - decode_delay_offset++; - last_prefix = prefix; + if (prefix == 0x0f) { + /*0fh prefix is 'free'*/ + last_prefix = prefix; + return; + } + /*On C3 all prefixes take 1 cycle to decode. Decode may be shadowed + by execution of previous instructions*/ + decode_delay_offset++; + last_prefix = prefix; } static void codegen_timing_cyrixiii_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc) { - uint32_t *timings; - uint64_t *deps; - int mod3 = ((fetchdat & 0xc0) == 0xc0); - int bit8 = !(opcode & 1); - int agi_stall = 0; + uint32_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; -// pclog("timings 0f\n"); - break; + switch (last_prefix) { + case 0x0f: + timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; + deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; + // pclog("timings 0f\n"); + 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; -// pclog("timings d8\n"); - 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; -// pclog("timings d9\n"); - 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; -// pclog("timings da\n"); - 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; -// pclog("timings db\n"); - 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; -// pclog("timings dc\n"); - 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; -// pclog("timings dd\n"); - 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; -// pclog("timings de\n"); - 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; -// pclog("timings df\n"); - 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; + // pclog("timings d8\n"); + 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; + // pclog("timings d9\n"); + 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; + // pclog("timings da\n"); + 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; + // pclog("timings db\n"); + 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; + // pclog("timings dc\n"); + 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; + // pclog("timings dd\n"); + 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; + // pclog("timings de\n"); + 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; + // pclog("timings df\n"); + 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; -// pclog("timings 80 %p %p %p\n", (void *)timings, (void *)opcode_timings_mod3, (void *)opcode_timings_8x); - 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; -// pclog("timings 80 %p %p %p\n", (void *)timings, (void *)opcode_timings_mod3, (void *)opcode_timings_8x); - 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; + // pclog("timings 80 %p %p %p\n", (void *)timings, (void *)opcode_timings_mod3, + // (void *)opcode_timings_8x); + 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; + // pclog("timings 80 %p %p %p\n", (void *)timings, (void *)opcode_timings_mod3, + // (void *)opcode_timings_8x); + 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; -// pclog("timings c0\n"); - 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; + // pclog("timings c0\n"); + 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; -// pclog("timings f6\n"); - 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; -// pclog("timings f7\n"); - 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; -// pclog("timings ff\n"); - 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; + // pclog("timings f6\n"); + 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; + // pclog("timings f7\n"); + 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; + // pclog("timings ff\n"); + break; - default:timings = mod3 ? opcode_timings_mod3 : opcode_timings; - deps = mod3 ? opcode_deps_mod3 : opcode_deps; -// pclog("timings normal\n"); - break; - } - } + default: + timings = mod3 ? opcode_timings_mod3 : opcode_timings; + deps = mod3 ? opcode_deps_mod3 : opcode_deps; + // pclog("timings normal\n"); + break; + } + } - 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); + 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); } -static void codegen_timing_cyrixiii_block_end() { -} +static void codegen_timing_cyrixiii_block_end() {} -int codegen_timing_cyrixiii_jump_cycles() { - return 0; -} +int codegen_timing_cyrixiii_jump_cycles() { return 0; } -codegen_timing_t codegen_timing_cyrixiii = - { - codegen_timing_cyrixiii_start, - codegen_timing_cyrixiii_prefix, - codegen_timing_cyrixiii_opcode, - codegen_timing_cyrixiii_block_start, - codegen_timing_cyrixiii_block_end, - codegen_timing_cyrixiii_jump_cycles - }; +codegen_timing_t codegen_timing_cyrixiii = {codegen_timing_cyrixiii_start, codegen_timing_cyrixiii_prefix, + codegen_timing_cyrixiii_opcode, codegen_timing_cyrixiii_block_start, + codegen_timing_cyrixiii_block_end, codegen_timing_cyrixiii_jump_cycles}; diff --git a/src/codegen/codegen_timing_k6.c b/src/codegen/codegen_timing_k6.c index 74436998..8b1abf72 100644 --- a/src/codegen/codegen_timing_k6.c +++ b/src/codegen/codegen_timing_k6.c @@ -13,1708 +13,1919 @@ #include "codegen_timing_common.h" typedef enum uop_type_t { - UOP_ALU = 0, /*Executes in Integer X or Y units*/ - UOP_ALUX, /*Executes in Integer X unit*/ - UOP_LOAD, /*Executes in Load unit*/ - UOP_STORE, /*Executes in Store unit*/ - UOP_FLOAD, /*Executes in Load unit*/ - UOP_FSTORE, /*Executes in Store unit*/ - UOP_MLOAD, /*Executes in Load unit*/ - UOP_MSTORE, /*Executes in Store unit*/ - UOP_FLOAT, /*Executes in Floating Point unit*/ - UOP_MEU, /*Executes in Multimedia unit*/ - UOP_MEU_SHIFT, /*Executes in Multimedia unit or ALU X/Y. Uses MMX shifter*/ - UOP_MEU_MUL, /*Executes in Multimedia unit or ALU X/Y. Uses MMX/3DNow multiplier*/ - UOP_MEU_3DN, /*Executes in Multimedia unit or ALU X/Y. Uses 3DNow ALU*/ - UOP_BRANCH, /*Executes in Branch unit*/ - UOP_LIMM /*Does not require an execution unit*/ + UOP_ALU = 0, /*Executes in Integer X or Y units*/ + UOP_ALUX, /*Executes in Integer X unit*/ + UOP_LOAD, /*Executes in Load unit*/ + UOP_STORE, /*Executes in Store unit*/ + UOP_FLOAD, /*Executes in Load unit*/ + UOP_FSTORE, /*Executes in Store unit*/ + UOP_MLOAD, /*Executes in Load unit*/ + UOP_MSTORE, /*Executes in Store unit*/ + UOP_FLOAT, /*Executes in Floating Point unit*/ + UOP_MEU, /*Executes in Multimedia unit*/ + UOP_MEU_SHIFT, /*Executes in Multimedia unit or ALU X/Y. Uses MMX shifter*/ + UOP_MEU_MUL, /*Executes in Multimedia unit or ALU X/Y. Uses MMX/3DNow multiplier*/ + UOP_MEU_3DN, /*Executes in Multimedia unit or ALU X/Y. Uses 3DNow ALU*/ + UOP_BRANCH, /*Executes in Branch unit*/ + UOP_LIMM /*Does not require an execution unit*/ } uop_type_t; -typedef enum decode_type_t { - DECODE_SHORT, - DECODE_LONG, - DECODE_VECTOR -} decode_type_t; +typedef enum decode_type_t { DECODE_SHORT, DECODE_LONG, DECODE_VECTOR } decode_type_t; #define MAX_UOPS 10 typedef struct risc86_uop_t { - uop_type_t type; - int throughput; - int latency; + uop_type_t type; + int throughput; + int latency; } risc86_uop_t; typedef struct risc86_instruction_t { - int nr_uops; - decode_type_t decode_type; - risc86_uop_t uop[MAX_UOPS]; + int nr_uops; + decode_type_t decode_type; + risc86_uop_t uop[MAX_UOPS]; } risc86_instruction_t; -static const risc86_instruction_t alu_op = - { - .nr_uops = 1, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t alux_op = - { - .nr_uops = 1, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t load_alu_op = - { - .nr_uops = 2, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t load_alux_op = - { - .nr_uops = 2, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t alu_store_op = - { - .nr_uops = 3, - .decode_type = DECODE_LONG, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_STORE, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t alux_store_op = - { - .nr_uops = 3, - .decode_type = DECODE_LONG, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_STORE, .throughput = 1, .latency = 1} - }; +static const risc86_instruction_t alu_op = { + .nr_uops = 1, .decode_type = DECODE_SHORT, .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t alux_op = { + .nr_uops = 1, .decode_type = DECODE_SHORT, .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t load_alu_op = {.nr_uops = 2, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t load_alux_op = {.nr_uops = 2, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t alu_store_op = {.nr_uops = 3, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_STORE, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t alux_store_op = {.nr_uops = 3, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_STORE, .throughput = 1, .latency = 1}}; -static const risc86_instruction_t branch_op = - { - .nr_uops = 1, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_BRANCH, .throughput = 1, .latency = 1} - }; +static const risc86_instruction_t branch_op = { + .nr_uops = 1, .decode_type = DECODE_SHORT, .uop[0] = {.type = UOP_BRANCH, .throughput = 1, .latency = 1}}; -static const risc86_instruction_t limm_op = - { - .nr_uops = 1, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_LIMM, .throughput = 1, .latency = 1} - }; +static const risc86_instruction_t limm_op = { + .nr_uops = 1, .decode_type = DECODE_SHORT, .uop[0] = {.type = UOP_LIMM, .throughput = 1, .latency = 1}}; -static const risc86_instruction_t load_op = - { - .nr_uops = 1, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2} - }; +static const risc86_instruction_t load_op = { + .nr_uops = 1, .decode_type = DECODE_SHORT, .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}}; -static const risc86_instruction_t store_op = - { - .nr_uops = 1, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_STORE, .throughput = 1, .latency = 1} - }; +static const risc86_instruction_t store_op = { + .nr_uops = 1, .decode_type = DECODE_SHORT, .uop[0] = {.type = UOP_STORE, .throughput = 1, .latency = 1}}; -static const risc86_instruction_t bswap_op = - { - .nr_uops = 1, - .decode_type = DECODE_LONG, - .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t leave_op = - { - .nr_uops = 3, - .decode_type = DECODE_LONG, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t lods_op = - { - .nr_uops = 2, - .decode_type = DECODE_LONG, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t loop_op = - { - .nr_uops = 2, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_BRANCH, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t mov_reg_seg_op = - { - .nr_uops = 1, - .decode_type = DECODE_LONG, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - }; -static const risc86_instruction_t movs_op = - { - .nr_uops = 4, - .decode_type = DECODE_LONG, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_ALU, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t pop_reg_op = - { - .nr_uops = 2, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t pop_mem_op = - { - .nr_uops = 3, - .decode_type = DECODE_LONG, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t push_imm_op = - { - .nr_uops = 1, - .decode_type = DECODE_LONG, - .uop[0] = {.type = UOP_STORE, .throughput = 1, .latency = 2}, - }; -static const risc86_instruction_t push_mem_op = - { - .nr_uops = 2, - .decode_type = DECODE_LONG, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t push_seg_op = - { - .nr_uops = 2, - .decode_type = DECODE_LONG, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t stos_op = - { - .nr_uops = 2, - .decode_type = DECODE_LONG, - .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_ALU, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t test_reg_op = - { - .nr_uops = 1, - .decode_type = DECODE_LONG, - .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t test_reg_b_op = - { - .nr_uops = 1, - .decode_type = DECODE_LONG, - .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t test_mem_imm_op = - { - .nr_uops = 2, - .decode_type = DECODE_LONG, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t test_mem_imm_b_op = - { - .nr_uops = 2, - .decode_type = DECODE_LONG, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t xchg_op = - { - .nr_uops = 3, - .decode_type = DECODE_LONG, - .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1} - }; +static const risc86_instruction_t bswap_op = { + .nr_uops = 1, .decode_type = DECODE_LONG, .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t leave_op = {.nr_uops = 3, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t lods_op = {.nr_uops = 2, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t loop_op = {.nr_uops = 2, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_BRANCH, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t mov_reg_seg_op = { + .nr_uops = 1, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, +}; +static const risc86_instruction_t movs_op = {.nr_uops = 4, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_ALU, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t pop_reg_op = {.nr_uops = 2, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t pop_mem_op = {.nr_uops = 3, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t push_imm_op = { + .nr_uops = 1, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_STORE, .throughput = 1, .latency = 2}, +}; +static const risc86_instruction_t push_mem_op = {.nr_uops = 2, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t push_seg_op = {.nr_uops = 2, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t stos_op = {.nr_uops = 2, + .decode_type = DECODE_LONG, + .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_ALU, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t test_reg_op = { + .nr_uops = 1, .decode_type = DECODE_LONG, .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t test_reg_b_op = { + .nr_uops = 1, .decode_type = DECODE_LONG, .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t test_mem_imm_op = {.nr_uops = 2, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t test_mem_imm_b_op = {.nr_uops = 2, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t xchg_op = {.nr_uops = 3, + .decode_type = DECODE_LONG, + .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1}}; -static const risc86_instruction_t m3dn_op = - { - .nr_uops = 1, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_MEU_3DN, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t mmx_op = - { - .nr_uops = 1, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_MEU, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t mmx_mul_op = - { - .nr_uops = 1, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_MEU_MUL, .throughput = 1, .latency = 2} - }; -static const risc86_instruction_t mmx_shift_op = - { - .nr_uops = 1, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_MEU_SHIFT, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t load_3dn_op = - { - .nr_uops = 2, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_MEU_3DN, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t load_mmx_op = - { - .nr_uops = 2, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_MEU, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t load_mmx_mul_op = - { - .nr_uops = 2, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_MEU_MUL, .throughput = 1, .latency = 2} - }; -static const risc86_instruction_t load_mmx_shift_op = - { - .nr_uops = 2, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_MEU_SHIFT, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t mload_op = - { - .nr_uops = 1, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_MLOAD, .throughput = 1, .latency = 2} - }; +static const risc86_instruction_t m3dn_op = { + .nr_uops = 1, .decode_type = DECODE_SHORT, .uop[0] = {.type = UOP_MEU_3DN, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t mmx_op = { + .nr_uops = 1, .decode_type = DECODE_SHORT, .uop[0] = {.type = UOP_MEU, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t mmx_mul_op = { + .nr_uops = 1, .decode_type = DECODE_SHORT, .uop[0] = {.type = UOP_MEU_MUL, .throughput = 1, .latency = 2}}; +static const risc86_instruction_t mmx_shift_op = { + .nr_uops = 1, .decode_type = DECODE_SHORT, .uop[0] = {.type = UOP_MEU_SHIFT, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t load_3dn_op = {.nr_uops = 2, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_MEU_3DN, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t load_mmx_op = {.nr_uops = 2, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_MEU, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t load_mmx_mul_op = {.nr_uops = 2, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_MEU_MUL, .throughput = 1, .latency = 2}}; +static const risc86_instruction_t load_mmx_shift_op = {.nr_uops = 2, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_MEU_SHIFT, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t mload_op = { + .nr_uops = 1, .decode_type = DECODE_SHORT, .uop[0] = {.type = UOP_MLOAD, .throughput = 1, .latency = 2}}; -static const risc86_instruction_t mstore_op = - { - .nr_uops = 1, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_MSTORE, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t pmul_op = - { - .nr_uops = 1, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_MEU_MUL, .throughput = 1, .latency = 2} - }; -static const risc86_instruction_t pmul_mem_op = - { - .nr_uops = 2, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_MEU_MUL, .throughput = 1, .latency = 2} - }; +static const risc86_instruction_t mstore_op = { + .nr_uops = 1, .decode_type = DECODE_SHORT, .uop[0] = {.type = UOP_MSTORE, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t pmul_op = { + .nr_uops = 1, .decode_type = DECODE_SHORT, .uop[0] = {.type = UOP_MEU_MUL, .throughput = 1, .latency = 2}}; +static const risc86_instruction_t pmul_mem_op = {.nr_uops = 2, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_MEU_MUL, .throughput = 1, .latency = 2}}; -static const risc86_instruction_t float_op = - { - .nr_uops = 1, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_FLOAT, .throughput = 2, .latency = 2} - }; -static const risc86_instruction_t load_float_op = - { - .nr_uops = 2, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_FLOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_FLOAT, .throughput = 2, .latency = 2} - }; -static const risc86_instruction_t fstore_op = - { - .nr_uops = 1, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_FSTORE, .throughput = 1, .latency = 1} - }; +static const risc86_instruction_t float_op = { + .nr_uops = 1, .decode_type = DECODE_SHORT, .uop[0] = {.type = UOP_FLOAT, .throughput = 2, .latency = 2}}; +static const risc86_instruction_t load_float_op = {.nr_uops = 2, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_FLOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_FLOAT, .throughput = 2, .latency = 2}}; +static const risc86_instruction_t fstore_op = { + .nr_uops = 1, .decode_type = DECODE_SHORT, .uop[0] = {.type = UOP_FSTORE, .throughput = 1, .latency = 1}}; -static const risc86_instruction_t fdiv_op = - { - .nr_uops = 1, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_FLOAT, .throughput = 40, .latency = 40} - }; -static const risc86_instruction_t fdiv_mem_op = - { - .nr_uops = 2, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_FLOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_FLOAT, .throughput = 40, .latency = 40} - }; -static const risc86_instruction_t fsin_op = - { - .nr_uops = 1, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_FLOAT, .throughput = 62, .latency = 62} - }; -static const risc86_instruction_t fsqrt_op = - { - .nr_uops = 1, - .decode_type = DECODE_SHORT, - .uop[0] = {.type = UOP_FLOAT, .throughput = 41, .latency = 41} - }; +static const risc86_instruction_t fdiv_op = { + .nr_uops = 1, .decode_type = DECODE_SHORT, .uop[0] = {.type = UOP_FLOAT, .throughput = 40, .latency = 40}}; +static const risc86_instruction_t fdiv_mem_op = {.nr_uops = 2, + .decode_type = DECODE_SHORT, + .uop[0] = {.type = UOP_FLOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_FLOAT, .throughput = 40, .latency = 40}}; +static const risc86_instruction_t fsin_op = { + .nr_uops = 1, .decode_type = DECODE_SHORT, .uop[0] = {.type = UOP_FLOAT, .throughput = 62, .latency = 62}}; +static const risc86_instruction_t fsqrt_op = { + .nr_uops = 1, .decode_type = DECODE_SHORT, .uop[0] = {.type = UOP_FLOAT, .throughput = 41, .latency = 41}}; -static const risc86_instruction_t vector_fldcw_op = - { - .nr_uops = 1, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_FLOAT, .throughput = 8, .latency = 8} - }; -static const risc86_instruction_t vector_float_op = - { - .nr_uops = 1, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_FLOAT, .throughput = 2, .latency = 2} - }; -static const risc86_instruction_t vector_float_l_op = - { - .nr_uops = 1, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_FLOAT, .throughput = 50, .latency = 50} - }; -static const risc86_instruction_t vector_flde_op = - { - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_FLOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_FLOAD, .throughput = 1, .latency = 2}, - .uop[2] = {.type = UOP_FLOAT, .throughput = 2, .latency = 2} - }; -static const risc86_instruction_t vector_fste_op = - { - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_FLOAT, .throughput = 2, .latency = 2}, - .uop[1] = {.type = UOP_FSTORE, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_FSTORE, .throughput = 1, .latency = 1} - }; +static const risc86_instruction_t vector_fldcw_op = { + .nr_uops = 1, .decode_type = DECODE_VECTOR, .uop[0] = {.type = UOP_FLOAT, .throughput = 8, .latency = 8}}; +static const risc86_instruction_t vector_float_op = { + .nr_uops = 1, .decode_type = DECODE_VECTOR, .uop[0] = {.type = UOP_FLOAT, .throughput = 2, .latency = 2}}; +static const risc86_instruction_t vector_float_l_op = { + .nr_uops = 1, .decode_type = DECODE_VECTOR, .uop[0] = {.type = UOP_FLOAT, .throughput = 50, .latency = 50}}; +static const risc86_instruction_t vector_flde_op = {.nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_FLOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_FLOAD, .throughput = 1, .latency = 2}, + .uop[2] = {.type = UOP_FLOAT, .throughput = 2, .latency = 2}}; +static const risc86_instruction_t vector_fste_op = {.nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_FLOAT, .throughput = 2, .latency = 2}, + .uop[1] = {.type = UOP_FSTORE, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_FSTORE, .throughput = 1, .latency = 1}}; -static const risc86_instruction_t vector_alu1_op = - { - .nr_uops = 1, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t vector_alu2_op = - { - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t vector_alu3_op = - { - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t vector_alu6_op = - { - .nr_uops = 6, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[4] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[5] = {.type = UOP_ALU, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t vector_alux1_op = - { - .nr_uops = 1, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t vector_alux3_op = - { - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t vector_alux6_op = - { - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[4] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[5] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t vector_alu_store_op = - { - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_STORE, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t vector_alux_store_op = - { - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_STORE, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t vector_arpl_op = - { - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALU, .throughput = 3, .latency = 3}, - .uop[1] = {.type = UOP_ALU, .throughput = 3, .latency = 3} - }; -static const risc86_instruction_t vector_bound_op = - { - .nr_uops = 4, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_ALU, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t vector_bsx_op = - { - .nr_uops = 1, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALU, .throughput = 10, .latency = 10} - }; -static const risc86_instruction_t vector_call_far_op = - { - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALU, .throughput = 3, .latency = 3}, - .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_BRANCH, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t vector_cli_sti_op = - { - .nr_uops = 1, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALU, .throughput = 7, .latency = 7} - }; -static const risc86_instruction_t vector_cmps_op = - { - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t vector_cmpsb_op = - { - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t vector_cmpxchg_op = - { - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, - }; -static const risc86_instruction_t vector_cmpxchg_b_op = - { - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, - }; -static const risc86_instruction_t vector_cpuid_op = - { - .nr_uops = 1, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALU, .throughput = 22, .latency = 22} - }; -static const risc86_instruction_t vector_div16_op = - { - .nr_uops = 1, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALUX, .throughput = 10, .latency = 10} - }; -static const risc86_instruction_t vector_div16_mem_op = - { - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALUX, .throughput = 10, .latency = 10} - }; -static const risc86_instruction_t vector_div32_op = - { - .nr_uops = 1, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALUX, .throughput = 18, .latency = 18} - }; -static const risc86_instruction_t vector_div32_mem_op = - { - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALUX, .throughput = 18, .latency = 18} - }; -static const risc86_instruction_t vector_emms_op = - { - .nr_uops = 1, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALU, .throughput = 25, .latency = 25} - }; -static const risc86_instruction_t vector_enter_op = - { - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_STORE, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU, .throughput = 10, .latency = 10} - }; -static const risc86_instruction_t vector_femms_op = - { - .nr_uops = 1, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALU, .throughput = 6, .latency = 6} - }; -static const risc86_instruction_t vector_in_op = - { - .nr_uops = 1, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 10, .latency = 11} - }; -static const risc86_instruction_t vector_ins_op = - { - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 10, .latency = 11}, - .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t vector_int_op = - { - .nr_uops = 5, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALU, .throughput = 20, .latency = 20}, - .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, - .uop[4] = {.type = UOP_BRANCH, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t vector_iret_op = - { - .nr_uops = 5, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[2] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[3] = {.type = UOP_ALU, .throughput = 20, .latency = 20}, - .uop[4] = {.type = UOP_BRANCH, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t vector_invd_op = - { - .nr_uops = 1, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALU, .throughput = 1000, .latency = 1000} - }; -static const risc86_instruction_t vector_jmp_far_op = - { - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALU, .throughput = 3, .latency = 3}, - .uop[1] = {.type = UOP_BRANCH, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t vector_load_alu_op = - { - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t vector_load_alux_op = - { - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t vector_loop_op = - { - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_BRANCH, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t vector_lss_op = - { - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[2] = {.type = UOP_ALU, .throughput = 3, .latency = 3} - }; -static const risc86_instruction_t vector_mov_mem_seg_op = - { - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t vector_mov_seg_mem_op = - { - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU, .throughput = 3, .latency = 3} - }; -static const risc86_instruction_t vector_mov_seg_reg_op = - { - .nr_uops = 1, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALU, .throughput = 3, .latency = 3} - }; -static const risc86_instruction_t vector_mul_op = - { - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t vector_mul_mem_op = - { - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t vector_mul64_op = - { - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t vector_mul64_mem_op = - { - .nr_uops = 4, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t vector_out_op = - { - .nr_uops = 1, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_STORE, .throughput = 10, .latency = 10} - }; -static const risc86_instruction_t vector_outs_op = - { - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_STORE, .throughput = 10, .latency = 10}, - .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t vector_pusha_op = - { - .nr_uops = 8, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, - .uop[4] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, - .uop[5] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, - .uop[6] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, - .uop[7] = {.type = UOP_STORE, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t vector_popa_op = - { - .nr_uops = 8, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, - .uop[4] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, - .uop[5] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, - .uop[6] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, - .uop[7] = {.type = UOP_LOAD, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t vector_popf_op = - { - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALUX, .throughput = 17, .latency = 17} - }; -static const risc86_instruction_t vector_push_mem_op = - { - .nr_uops = 1, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_STORE, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t vector_pushf_op = - { - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t vector_ret_op = - { - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_BRANCH, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t vector_retf_op = - { - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU, .throughput = 3, .latency = 3}, - .uop[2] = {.type = UOP_BRANCH, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t vector_scas_op = - { - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t vector_scasb_op = - { - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t vector_setcc_mem_op = - { - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_FSTORE, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t vector_setcc_reg_op = - { - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t vector_test_mem_op = - { - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t vector_test_mem_b_op = - { - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t vector_xchg_mem_op = - { - .nr_uops = 3, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1} - }; -static const risc86_instruction_t vector_xlat_op = - { - .nr_uops = 2, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 2} - }; -static const risc86_instruction_t vector_wbinvd_op = - { - .nr_uops = 1, - .decode_type = DECODE_VECTOR, - .uop[0] = {.type = UOP_ALU, .throughput = 10000, .latency = 10000} - }; +static const risc86_instruction_t vector_alu1_op = { + .nr_uops = 1, .decode_type = DECODE_VECTOR, .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t vector_alu2_op = {.nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t vector_alu3_op = {.nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t vector_alu6_op = {.nr_uops = 6, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[5] = {.type = UOP_ALU, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t vector_alux1_op = { + .nr_uops = 1, .decode_type = DECODE_VECTOR, .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t vector_alux3_op = {.nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t vector_alux6_op = {.nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[5] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t vector_alu_store_op = {.nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_STORE, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t vector_alux_store_op = {.nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_STORE, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t vector_arpl_op = {.nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 3, .latency = 3}, + .uop[1] = {.type = UOP_ALU, .throughput = 3, .latency = 3}}; +static const risc86_instruction_t vector_bound_op = {.nr_uops = 4, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_ALU, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t vector_bsx_op = { + .nr_uops = 1, .decode_type = DECODE_VECTOR, .uop[0] = {.type = UOP_ALU, .throughput = 10, .latency = 10}}; +static const risc86_instruction_t vector_call_far_op = {.nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 3, .latency = 3}, + .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_BRANCH, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t vector_cli_sti_op = { + .nr_uops = 1, .decode_type = DECODE_VECTOR, .uop[0] = {.type = UOP_ALU, .throughput = 7, .latency = 7}}; +static const risc86_instruction_t vector_cmps_op = {.nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t vector_cmpsb_op = {.nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t vector_cmpxchg_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, +}; +static const risc86_instruction_t vector_cmpxchg_b_op = { + .nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, +}; +static const risc86_instruction_t vector_cpuid_op = { + .nr_uops = 1, .decode_type = DECODE_VECTOR, .uop[0] = {.type = UOP_ALU, .throughput = 22, .latency = 22}}; +static const risc86_instruction_t vector_div16_op = { + .nr_uops = 1, .decode_type = DECODE_VECTOR, .uop[0] = {.type = UOP_ALUX, .throughput = 10, .latency = 10}}; +static const risc86_instruction_t vector_div16_mem_op = {.nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALUX, .throughput = 10, .latency = 10}}; +static const risc86_instruction_t vector_div32_op = { + .nr_uops = 1, .decode_type = DECODE_VECTOR, .uop[0] = {.type = UOP_ALUX, .throughput = 18, .latency = 18}}; +static const risc86_instruction_t vector_div32_mem_op = {.nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALUX, .throughput = 18, .latency = 18}}; +static const risc86_instruction_t vector_emms_op = { + .nr_uops = 1, .decode_type = DECODE_VECTOR, .uop[0] = {.type = UOP_ALU, .throughput = 25, .latency = 25}}; +static const risc86_instruction_t vector_enter_op = {.nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_STORE, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU, .throughput = 10, .latency = 10}}; +static const risc86_instruction_t vector_femms_op = { + .nr_uops = 1, .decode_type = DECODE_VECTOR, .uop[0] = {.type = UOP_ALU, .throughput = 6, .latency = 6}}; +static const risc86_instruction_t vector_in_op = { + .nr_uops = 1, .decode_type = DECODE_VECTOR, .uop[0] = {.type = UOP_LOAD, .throughput = 10, .latency = 11}}; +static const risc86_instruction_t vector_ins_op = {.nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 10, .latency = 11}, + .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t vector_int_op = {.nr_uops = 5, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 20, .latency = 20}, + .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_BRANCH, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t vector_iret_op = {.nr_uops = 5, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[2] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[3] = {.type = UOP_ALU, .throughput = 20, .latency = 20}, + .uop[4] = {.type = UOP_BRANCH, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t vector_invd_op = { + .nr_uops = 1, .decode_type = DECODE_VECTOR, .uop[0] = {.type = UOP_ALU, .throughput = 1000, .latency = 1000}}; +static const risc86_instruction_t vector_jmp_far_op = {.nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 3, .latency = 3}, + .uop[1] = {.type = UOP_BRANCH, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t vector_load_alu_op = {.nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t vector_load_alux_op = {.nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t vector_loop_op = {.nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_BRANCH, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t vector_lss_op = {.nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[2] = {.type = UOP_ALU, .throughput = 3, .latency = 3}}; +static const risc86_instruction_t vector_mov_mem_seg_op = {.nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t vector_mov_seg_mem_op = {.nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU, .throughput = 3, .latency = 3}}; +static const risc86_instruction_t vector_mov_seg_reg_op = { + .nr_uops = 1, .decode_type = DECODE_VECTOR, .uop[0] = {.type = UOP_ALU, .throughput = 3, .latency = 3}}; +static const risc86_instruction_t vector_mul_op = {.nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t vector_mul_mem_op = {.nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t vector_mul64_op = {.nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t vector_mul64_mem_op = {.nr_uops = 4, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t vector_out_op = { + .nr_uops = 1, .decode_type = DECODE_VECTOR, .uop[0] = {.type = UOP_STORE, .throughput = 10, .latency = 10}}; +static const risc86_instruction_t vector_outs_op = {.nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_STORE, .throughput = 10, .latency = 10}, + .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t vector_pusha_op = {.nr_uops = 8, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[5] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[6] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[7] = {.type = UOP_STORE, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t vector_popa_op = {.nr_uops = 8, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[5] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[6] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[7] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t vector_popf_op = {.nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALUX, .throughput = 17, .latency = 17}}; +static const risc86_instruction_t vector_push_mem_op = { + .nr_uops = 1, .decode_type = DECODE_VECTOR, .uop[0] = {.type = UOP_STORE, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t vector_pushf_op = {.nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t vector_ret_op = {.nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_BRANCH, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t vector_retf_op = {.nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU, .throughput = 3, .latency = 3}, + .uop[2] = {.type = UOP_BRANCH, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t vector_scas_op = {.nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t vector_scasb_op = {.nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t vector_setcc_mem_op = {.nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_FSTORE, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t vector_setcc_reg_op = {.nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t vector_test_mem_op = {.nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t vector_test_mem_b_op = {.nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALUX, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t vector_xchg_mem_op = {.nr_uops = 3, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_STORE, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU, .throughput = 1, .latency = 1}}; +static const risc86_instruction_t vector_xlat_op = {.nr_uops = 2, + .decode_type = DECODE_VECTOR, + .uop[0] = {.type = UOP_ALU, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}}; +static const risc86_instruction_t vector_wbinvd_op = { + .nr_uops = 1, .decode_type = DECODE_VECTOR, .uop[0] = {.type = UOP_ALU, .throughput = 10000, .latency = 10000}}; #define INVALID NULL -static const risc86_instruction_t *opcode_timings[256] = - { -/* ADD ADD ADD ADD*/ -/*00*/ &alux_store_op, &alu_store_op, &load_alux_op, &load_alu_op, -/* ADD ADD PUSH ES POP ES*/ - &alux_op, &alu_op, &push_seg_op, &vector_mov_seg_mem_op, -/* OR OR OR OR*/ - &alux_store_op, &alu_store_op, &load_alux_op, &load_alu_op, -/* OR OR PUSH CS */ - &alux_op, &alu_op, &push_seg_op, INVALID, - -/* ADC ADC ADC ADC*/ -/*10*/ &vector_alux_store_op, &vector_alu_store_op, &vector_load_alux_op, &vector_load_alu_op, -/* ADC ADC PUSH SS POP SS*/ - &vector_alux1_op, &vector_alu1_op, &push_seg_op, &vector_mov_seg_mem_op, -/* SBB SBB SBB SBB*/ -/*10*/ &vector_alux_store_op, &vector_alu_store_op, &vector_load_alux_op, &vector_load_alu_op, -/* SBB SBB PUSH DS POP DS*/ - &vector_alux1_op, &vector_alu1_op, &push_seg_op, &vector_mov_seg_mem_op, - -/* AND AND AND AND*/ -/*20*/ &alux_store_op, &alu_store_op, &load_alux_op, &load_alu_op, -/* AND AND DAA*/ - &alux_op, &alu_op, INVALID, &vector_alux1_op, -/* SUB SUB SUB SUB*/ - &alux_store_op, &alu_store_op, &load_alux_op, &load_alu_op, -/* SUB SUB DAS*/ - &alux_op, &alu_op, INVALID, &vector_alux1_op, - -/* XOR XOR XOR XOR*/ -/*30*/ &alux_store_op, &alu_store_op, &load_alux_op, &load_alu_op, -/* XOR XOR AAA*/ - &alux_op, &alu_op, INVALID, &vector_alux6_op, -/* CMP CMP CMP CMP*/ - &load_alux_op, &load_alu_op, &load_alux_op, &load_alu_op, -/* CMP CMP AAS*/ - &alux_op, &alu_op, INVALID, &vector_alux6_op, - -/* INC EAX INC ECX INC EDX INC EBX*/ -/*40*/ &alu_op, &alu_op, &alu_op, &alu_op, -/* INC ESP INC EBP INC ESI INC EDI*/ - &alu_op, &alu_op, &alu_op, &alu_op, -/* DEC EAX DEC ECX DEC EDX DEC EBX*/ - &alu_op, &alu_op, &alu_op, &alu_op, -/* DEC ESP DEC EBP DEC ESI DEC EDI*/ - &alu_op, &alu_op, &alu_op, &alu_op, - -/* PUSH EAX PUSH ECX PUSH EDX PUSH EBX*/ -/*50*/ &store_op, &store_op, &store_op, &store_op, -/* PUSH ESP PUSH EBP PUSH ESI PUSH EDI*/ - &store_op, &store_op, &store_op, &store_op, -/* POP EAX POP ECX POP EDX POP EBX*/ - &pop_reg_op, &pop_reg_op, &pop_reg_op, &pop_reg_op, -/* POP ESP POP EBP POP ESI POP EDI*/ - &pop_reg_op, &pop_reg_op, &pop_reg_op, &pop_reg_op, - -/* PUSHA POPA BOUND ARPL*/ -/*60*/ &vector_pusha_op, &vector_popa_op, &vector_bound_op, &vector_arpl_op, - INVALID, INVALID, INVALID, INVALID, -/* PUSH imm IMUL PUSH imm IMUL*/ - &push_imm_op, &vector_mul_op, &push_imm_op, &vector_mul_op, -/* INSB INSW OUTSB OUTSW*/ - &vector_ins_op, &vector_ins_op, &vector_outs_op, &vector_outs_op, - -/* Jxx*/ -/*70*/ &branch_op, &branch_op, &branch_op, &branch_op, - &branch_op, &branch_op, &branch_op, &branch_op, - &branch_op, &branch_op, &branch_op, &branch_op, - &branch_op, &branch_op, &branch_op, &branch_op, - -/*80*/ INVALID, INVALID, INVALID, INVALID, -/* TEST TEST XCHG XCHG*/ - &vector_test_mem_b_op, &vector_test_mem_op, &vector_xchg_mem_op, &vector_xchg_mem_op, -/* MOV MOV MOV MOV*/ - &store_op, &store_op, &load_op, &load_op, -/* MOV from seg LEA MOV to seg POP*/ - &vector_mov_mem_seg_op, &store_op, &vector_mov_seg_mem_op, &pop_mem_op, - -/* NOP XCHG XCHG XCHG*/ -/*90*/ &limm_op, &xchg_op, &xchg_op, &xchg_op, -/* XCHG XCHG XCHG XCHG*/ - &xchg_op, &xchg_op, &xchg_op, &xchg_op, -/* CBW CWD CALL far WAIT*/ - &vector_alu1_op, &vector_alu1_op, &vector_call_far_op, &limm_op, -/* PUSHF POPF SAHF LAHF*/ - &vector_pushf_op, &vector_popf_op, &vector_alux1_op, &vector_alux1_op, - -/* MOV MOV MOV MOV*/ -/*a0*/ &load_op, &load_op, &store_op, &store_op, -/* MOVSB MOVSW CMPSB CMPSW*/ - &movs_op, &movs_op, &vector_cmpsb_op, &vector_cmps_op, -/* TEST TEST STOSB STOSW*/ - &test_reg_b_op, &test_reg_op, &stos_op, &stos_op, -/* LODSB LODSW SCASB SCASW*/ - &lods_op, &lods_op, &vector_scasb_op, &vector_scas_op, - -/* MOV*/ -/*b0*/ &limm_op, &limm_op, &limm_op, &limm_op, - &limm_op, &limm_op, &limm_op, &limm_op, - &limm_op, &limm_op, &limm_op, &limm_op, - &limm_op, &limm_op, &limm_op, &limm_op, - -/* RET imm RET*/ -/*c0*/ INVALID, INVALID, &vector_ret_op, &vector_ret_op, -/* LES LDS MOV MOV*/ - &vector_lss_op, &vector_lss_op, &store_op, &store_op, -/* ENTER LEAVE RETF RETF*/ - &vector_enter_op, &leave_op, &vector_retf_op, &vector_retf_op, -/* INT3 INT INTO IRET*/ - &vector_int_op, &vector_int_op, &vector_int_op, &vector_iret_op, - - -/*d0*/ INVALID, INVALID, INVALID, INVALID, -/* AAM AAD SETALC XLAT*/ - &vector_alux6_op, &vector_alux3_op, &vector_alux1_op, &vector_xlat_op, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, -/* LOOPNE LOOPE LOOP JCXZ*/ -/*e0*/ &vector_loop_op, &vector_loop_op, &loop_op, &vector_loop_op, -/* IN AL IN AX OUT_AL OUT_AX*/ - &vector_in_op, &vector_in_op, &vector_out_op, &vector_out_op, -/* CALL JMP JMP JMP*/ - &store_op, &branch_op, &vector_jmp_far_op, &branch_op, -/* IN AL IN AX OUT_AL OUT_AX*/ - &vector_in_op, &vector_in_op, &vector_out_op, &vector_out_op, - -/* REPNE REPE*/ -/*f0*/ INVALID, INVALID, INVALID, INVALID, -/* HLT CMC*/ - &vector_alux1_op, &vector_alu2_op, INVALID, INVALID, -/* CLC STC CLI STI*/ - &vector_alu1_op, &vector_alu1_op, &vector_cli_sti_op, &vector_cli_sti_op, -/* CLD STD INCDEC*/ - &vector_alu1_op, &vector_alu1_op, &alux_store_op, INVALID - }; - -static const risc86_instruction_t *opcode_timings_mod3[256] = - { -/* ADD ADD ADD ADD*/ -/*00*/ &alux_op, &alu_op, &alux_op, &alu_op, -/* ADD ADD PUSH ES POP ES*/ - &alux_op, &alu_op, &push_seg_op, &vector_mov_seg_mem_op, -/* OR OR OR OR*/ - &alux_op, &alu_op, &alux_op, &alu_op, -/* OR OR PUSH CS */ - &alux_op, &alu_op, &push_seg_op, INVALID, - -/* ADC ADC ADC ADC*/ -/*10*/ &vector_alux1_op, &vector_alu1_op, &vector_alux1_op, &vector_alu1_op, -/* ADC ADC PUSH SS POP SS*/ - &vector_alux1_op, &vector_alu1_op, &push_seg_op, &vector_mov_seg_mem_op, -/* SBB SBB SBB SBB*/ - &vector_alux1_op, &vector_alu1_op, &vector_alux1_op, &vector_alu1_op, -/* SBB SBB PUSH DS POP DS*/ - &vector_alux1_op, &vector_alu1_op, &push_seg_op, &vector_mov_seg_mem_op, - -/* AND AND AND AND*/ -/*20*/ &alux_op, &alu_op, &alux_op, &alu_op, -/* AND AND DAA*/ - &alux_op, &alu_op, INVALID, &vector_alux1_op, -/* SUB SUB SUB SUB*/ - &alux_op, &alu_op, &alux_op, &alu_op, -/* SUB SUB DAS*/ - &alux_op, &alu_op, INVALID, &vector_alux1_op, - -/* XOR XOR XOR XOR*/ -/*30*/ &alux_op, &alu_op, &alux_op, &alu_op, -/* XOR XOR AAA*/ - &alux_op, &alu_op, INVALID, &vector_alux6_op, -/* CMP CMP CMP CMP*/ - &alux_op, &alu_op, &alux_op, &alu_op, -/* CMP CMP AAS*/ - &alux_op, &alu_op, INVALID, &vector_alux6_op, - -/* INC EAX INC ECX INC EDX INC EBX*/ -/*40*/ &alu_op, &alu_op, &alu_op, &alu_op, -/* INC ESP INC EBP INC ESI INC EDI*/ - &alu_op, &alu_op, &alu_op, &alu_op, -/* DEC EAX DEC ECX DEC EDX DEC EBX*/ - &alu_op, &alu_op, &alu_op, &alu_op, -/* DEC ESP DEC EBP DEC ESI DEC EDI*/ - &alu_op, &alu_op, &alu_op, &alu_op, - -/* PUSH EAX PUSH ECX PUSH EDX PUSH EBX*/ -/*50*/ &store_op, &store_op, &store_op, &store_op, -/* PUSH ESP PUSH EBP PUSH ESI PUSH EDI*/ - &store_op, &store_op, &store_op, &store_op, -/* POP EAX POP ECX POP EDX POP EBX*/ - &pop_reg_op, &pop_reg_op, &pop_reg_op, &pop_reg_op, -/* POP ESP POP EBP POP ESI POP EDI*/ - &pop_reg_op, &pop_reg_op, &pop_reg_op, &pop_reg_op, - -/* PUSHA POPA BOUND ARPL*/ -/*60*/ &vector_pusha_op, &vector_popa_op, &vector_bound_op, &vector_arpl_op, - INVALID, INVALID, INVALID, INVALID, -/* PUSH imm IMUL PUSH imm IMUL*/ - &push_imm_op, &vector_mul_op, &push_imm_op, &vector_mul_op, -/* INSB INSW OUTSB OUTSW*/ - &vector_ins_op, &vector_ins_op, &vector_outs_op, &vector_outs_op, - -/* Jxx*/ -/*70*/ &branch_op, &branch_op, &branch_op, &branch_op, - &branch_op, &branch_op, &branch_op, &branch_op, - &branch_op, &branch_op, &branch_op, &branch_op, - &branch_op, &branch_op, &branch_op, &branch_op, - -/*80*/ INVALID, INVALID, INVALID, INVALID, -/* TEST TEST XCHG XCHG*/ - &vector_alu1_op, &vector_alu1_op, &vector_alu3_op, &vector_alu3_op, -/* MOV MOV MOV MOV*/ - &store_op, &store_op, &load_op, &load_op, -/* MOV from seg LEA MOV to seg POP*/ - &mov_reg_seg_op, &store_op, &vector_mov_seg_reg_op, &pop_reg_op, - -/* NOP XCHG XCHG XCHG*/ -/*90*/ &limm_op, &xchg_op, &xchg_op, &xchg_op, -/* XCHG XCHG XCHG XCHG*/ - &xchg_op, &xchg_op, &xchg_op, &xchg_op, -/* CBW CWD CALL far WAIT*/ - &vector_alu1_op, &vector_alu1_op, &vector_call_far_op, &limm_op, -/* PUSHF POPF SAHF LAHF*/ - &vector_pushf_op, &vector_popf_op, &vector_alux1_op, &vector_alux1_op, - -/* MOV MOV MOV MOV*/ -/*a0*/ &load_op, &load_op, &store_op, &store_op, -/* MOVSB MOVSW CMPSB CMPSW*/ - &movs_op, &movs_op, &vector_cmpsb_op, &vector_cmps_op, -/* TEST TEST STOSB STOSW*/ - &test_reg_b_op, &test_reg_op, &stos_op, &stos_op, -/* LODSB LODSW SCASB SCASW*/ - &lods_op, &lods_op, &vector_scasb_op, &vector_scas_op, - -/* MOV*/ -/*b0*/ &limm_op, &limm_op, &limm_op, &limm_op, - &limm_op, &limm_op, &limm_op, &limm_op, - &limm_op, &limm_op, &limm_op, &limm_op, - &limm_op, &limm_op, &limm_op, &limm_op, - -/* RET imm RET*/ -/*c0*/ INVALID, INVALID, &vector_ret_op, &vector_ret_op, -/* LES LDS MOV MOV*/ - &vector_lss_op, &vector_lss_op, &store_op, &store_op, -/* ENTER LEAVE RETF RETF*/ - &vector_enter_op, &leave_op, &vector_retf_op, &vector_retf_op, -/* INT3 INT INTO IRET*/ - &vector_int_op, &vector_int_op, &vector_int_op, &vector_iret_op, - - -/*d0*/ INVALID, INVALID, INVALID, INVALID, -/* AAM AAD SETALC XLAT*/ - &vector_alux6_op, &vector_alux3_op, &vector_alux1_op, &vector_xlat_op, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, -/* LOOPNE LOOPE LOOP JCXZ*/ -/*e0*/ &vector_loop_op, &vector_loop_op, &loop_op, &vector_loop_op, -/* IN AL IN AX OUT_AL OUT_AX*/ - &vector_in_op, &vector_in_op, &vector_out_op, &vector_out_op, -/* CALL JMP JMP JMP*/ - &store_op, &branch_op, &vector_jmp_far_op, &branch_op, -/* IN AL IN AX OUT_AL OUT_AX*/ - &vector_in_op, &vector_in_op, &vector_out_op, &vector_out_op, - -/* REPNE REPE*/ -/*f0*/ INVALID, INVALID, INVALID, INVALID, -/* HLT CMC*/ - &vector_alux1_op, &vector_alu2_op, INVALID, INVALID, -/* CLC STC CLI STI*/ - &vector_alu1_op, &vector_alu1_op, &vector_cli_sti_op, &vector_cli_sti_op, -/* CLD STD INCDEC*/ - &vector_alu1_op, &vector_alu1_op, &vector_alux1_op, INVALID - }; - -static const risc86_instruction_t *opcode_timings_0f[256] = - { -/*00*/ &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, - INVALID, &vector_alu6_op, &vector_alu6_op, INVALID, - &vector_invd_op, &vector_wbinvd_op, INVALID, INVALID, - INVALID, &load_op, &vector_femms_op, &load_3dn_op, - -/*10*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*20*/ &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, - &vector_alu6_op, &vector_alu6_op, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*30*/ &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, 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*/ &load_mmx_op, &load_mmx_op, &load_mmx_op, &load_mmx_op, - &load_mmx_op, &load_mmx_op, &load_mmx_op, &load_mmx_op, - &load_mmx_op, &load_mmx_op, &load_mmx_op, &load_mmx_op, - INVALID, INVALID, &mload_op, &mload_op, - -/*70*/ INVALID, &load_mmx_shift_op, &load_mmx_shift_op, &load_mmx_shift_op, - &load_mmx_op, &load_mmx_op, &load_mmx_op, &vector_emms_op, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, &mstore_op, &mstore_op, - -/*80*/ &branch_op, &branch_op, &branch_op, &branch_op, - &branch_op, &branch_op, &branch_op, &branch_op, - &branch_op, &branch_op, &branch_op, &branch_op, - &branch_op, &branch_op, &branch_op, &branch_op, - -/*90*/ &vector_setcc_reg_op, &vector_setcc_reg_op, &vector_setcc_reg_op, &vector_setcc_reg_op, - &vector_setcc_reg_op, &vector_setcc_reg_op, &vector_setcc_reg_op, &vector_setcc_reg_op, - &vector_setcc_reg_op, &vector_setcc_reg_op, &vector_setcc_reg_op, &vector_setcc_reg_op, - &vector_setcc_reg_op, &vector_setcc_reg_op, &vector_setcc_reg_op, &vector_setcc_reg_op, - -/*a0*/ &push_seg_op, &vector_mov_seg_mem_op, &vector_cpuid_op, &vector_load_alu_op, - &vector_alu_store_op, &vector_alu_store_op, INVALID, INVALID, - &push_seg_op, &vector_mov_seg_mem_op, INVALID, &vector_load_alu_op, - &vector_alu_store_op, &vector_alu_store_op, INVALID, &vector_mul_op, - -/*b0*/ &vector_cmpxchg_b_op, &vector_cmpxchg_op, &vector_lss_op, &vector_load_alu_op, - &vector_lss_op, &vector_lss_op, &load_alux_op, &load_alu_op, - INVALID, INVALID, &vector_load_alu_op, &vector_load_alu_op, - &vector_bsx_op, &vector_bsx_op, &load_alux_op, &load_alu_op, - -/*c0*/ &vector_alux_store_op, &vector_alu_store_op, INVALID, INVALID, - INVALID, INVALID, INVALID, &vector_cmpxchg_op, - &bswap_op, &bswap_op, &bswap_op, &bswap_op, - &bswap_op, &bswap_op, &bswap_op, &bswap_op, - -/*d0*/ INVALID, &load_mmx_shift_op, &load_mmx_shift_op, &load_mmx_shift_op, - INVALID, &load_mmx_mul_op, INVALID, INVALID, - &load_mmx_op, &load_mmx_op, INVALID, &load_mmx_op, - &load_mmx_op, &load_mmx_op, INVALID, &load_mmx_op, - -/*e0*/ &load_mmx_op, &load_mmx_shift_op, &load_mmx_shift_op, INVALID, - INVALID, &pmul_mem_op, INVALID, INVALID, - &load_mmx_op, &load_mmx_op, INVALID, &load_mmx_op, - &load_mmx_op, &load_mmx_op, INVALID, &load_mmx_op, - -/*f0*/ INVALID, &load_mmx_shift_op, &load_mmx_shift_op, &load_mmx_shift_op, - INVALID, &pmul_mem_op, INVALID, INVALID, - &load_mmx_op, &load_mmx_op, &load_mmx_op, INVALID, - &load_mmx_op, &load_mmx_op, &load_mmx_op, INVALID, - }; -static const risc86_instruction_t *opcode_timings_0f_mod3[256] = - { -/*00*/ &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, - INVALID, &vector_alu6_op, &vector_alu6_op, INVALID, - &vector_invd_op, &vector_wbinvd_op, INVALID, INVALID, - INVALID, INVALID, &vector_femms_op, &m3dn_op, - -/*10*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*20*/ &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, - &vector_alu6_op, &vector_alu6_op, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*30*/ &vector_alu6_op, &vector_alu6_op, &vector_alu6_op, 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*/ &mmx_op, &mmx_op, &mmx_op, &mmx_op, - &mmx_op, &mmx_op, &mmx_op, &mmx_op, - &mmx_op, &mmx_op, &mmx_op, &mmx_op, - INVALID, INVALID, &mmx_op, &mmx_op, - -/*70*/ INVALID, &mmx_shift_op, &mmx_shift_op, &mmx_shift_op, - &mmx_op, &mmx_op, &mmx_op, &vector_emms_op, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, &mmx_op, &mmx_op, - -/*80*/ &branch_op, &branch_op, &branch_op, &branch_op, - &branch_op, &branch_op, &branch_op, &branch_op, - &branch_op, &branch_op, &branch_op, &branch_op, - &branch_op, &branch_op, &branch_op, &branch_op, - -/*90*/ &vector_setcc_mem_op, &vector_setcc_mem_op, &vector_setcc_mem_op, &vector_setcc_mem_op, - &vector_setcc_mem_op, &vector_setcc_mem_op, &vector_setcc_mem_op, &vector_setcc_mem_op, - &vector_setcc_mem_op, &vector_setcc_mem_op, &vector_setcc_mem_op, &vector_setcc_mem_op, - &vector_setcc_mem_op, &vector_setcc_mem_op, &vector_setcc_mem_op, &vector_setcc_mem_op, - -/*a0*/ &push_seg_op, &vector_mov_seg_mem_op, &vector_cpuid_op, &vector_alu1_op, - &vector_alu1_op, &vector_alu1_op, INVALID, INVALID, - &push_seg_op, &vector_mov_seg_mem_op, INVALID, &vector_alu1_op, - &vector_alu1_op, &vector_alu1_op, INVALID, &vector_mul_op, - -/*b0*/ &vector_cmpxchg_b_op, &vector_cmpxchg_op, &vector_lss_op, &vector_alu1_op, - &vector_lss_op, &vector_lss_op, &alux_op, &alu_op, - INVALID, INVALID, &vector_alu1_op, &vector_alu1_op, - &vector_bsx_op, &vector_bsx_op, &alux_op, &alu_op, - -/*c0*/ &vector_alux1_op, &vector_alu1_op, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - &bswap_op, &bswap_op, &bswap_op, &bswap_op, - &bswap_op, &bswap_op, &bswap_op, &bswap_op, - -/*d0*/ INVALID, &mmx_shift_op, &mmx_shift_op, &mmx_shift_op, - INVALID, &mmx_mul_op, INVALID, INVALID, - &mmx_op, &mmx_op, INVALID, &mmx_op, - &mmx_op, &mmx_op, INVALID, &mmx_op, - -/*e0*/ &mmx_op, &mmx_shift_op, &mmx_shift_op, INVALID, - INVALID, &pmul_op, INVALID, INVALID, - &mmx_op, &mmx_op, INVALID, &mmx_op, - &mmx_op, &mmx_op, INVALID, &mmx_op, - -/*f0*/ INVALID, &mmx_shift_op, &mmx_shift_op, &mmx_shift_op, - INVALID, &pmul_op, INVALID, INVALID, - &mmx_op, &mmx_op, &mmx_op, INVALID, - &mmx_op, &mmx_op, &mmx_op, INVALID, - }; - -static const risc86_instruction_t *opcode_timings_0f0f[256] = - { -/*00*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, &load_3dn_op, INVALID, INVALID, - -/*10*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, &load_3dn_op, INVALID, INVALID, - -/*20*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*30*/ INVALID, INVALID, INVALID, 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*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*70*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*80*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*90*/ &load_3dn_op, INVALID, INVALID, INVALID, - &load_3dn_op, INVALID, &load_3dn_op, &load_3dn_op, - INVALID, INVALID, &load_3dn_op, INVALID, - INVALID, INVALID, &load_3dn_op, INVALID, - -/*a0*/ &load_3dn_op, INVALID, INVALID, INVALID, - &load_3dn_op, INVALID, &load_mmx_mul_op, &load_mmx_mul_op, - INVALID, INVALID, &load_3dn_op, INVALID, - INVALID, INVALID, &load_3dn_op, INVALID, - -/*b0*/ &load_3dn_op, INVALID, INVALID, INVALID, - &load_mmx_mul_op, INVALID, &load_mmx_mul_op, &load_mmx_mul_op, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, &load_mmx_op, - -/*c0*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*d0*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*e0*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*f0*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - - }; -static const risc86_instruction_t *opcode_timings_0f0f_mod3[256] = - { -/*00*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, &m3dn_op, INVALID, INVALID, - -/*10*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, &m3dn_op, INVALID, INVALID, - -/*20*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*30*/ INVALID, INVALID, INVALID, 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*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*70*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*80*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*90*/ &m3dn_op, INVALID, INVALID, INVALID, - &m3dn_op, INVALID, &m3dn_op, &m3dn_op, - INVALID, INVALID, &m3dn_op, INVALID, - INVALID, INVALID, &m3dn_op, INVALID, - -/*a0*/ &m3dn_op, INVALID, INVALID, INVALID, - &m3dn_op, INVALID, &mmx_mul_op, &mmx_mul_op, - INVALID, INVALID, &m3dn_op, INVALID, - INVALID, INVALID, &m3dn_op, INVALID, - -/*b0*/ &m3dn_op, INVALID, INVALID, INVALID, - &mmx_mul_op, INVALID, &mmx_mul_op, &mmx_mul_op, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, &mmx_op, - -/*c0*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*d0*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*e0*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*f0*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - - }; - -static const risc86_instruction_t *opcode_timings_shift[8] = - { - &vector_alu_store_op, &vector_alu_store_op, &vector_alu_store_op, &vector_alu_store_op, - &vector_alu_store_op, &vector_alu_store_op, &vector_alu_store_op, &vector_alu_store_op - }; -static const risc86_instruction_t *opcode_timings_shift_b[8] = - { - &vector_alux_store_op, &vector_alux_store_op, &vector_alux_store_op, &vector_alux_store_op, - &vector_alux_store_op, &vector_alux_store_op, &vector_alux_store_op, &vector_alux_store_op - }; -static const risc86_instruction_t *opcode_timings_shift_mod3[8] = - { - &vector_alu1_op, &vector_alu1_op, &vector_alu1_op, &vector_alu1_op, - &alu_op, &alu_op, &alu_op, &alu_op - }; -static const risc86_instruction_t *opcode_timings_shift_b_mod3[8] = - { - &vector_alux1_op, &vector_alux1_op, &vector_alux1_op, &vector_alux1_op, - &alux_op, &alux_op, &alux_op, &alux_op - }; - -static const risc86_instruction_t *opcode_timings_80[8] = - { - &alux_store_op, &alux_store_op, &vector_alux_store_op, &vector_alux_store_op, - &alux_store_op, &alux_store_op, &alux_store_op, &alux_store_op, - }; -static const risc86_instruction_t *opcode_timings_80_mod3[8] = - { - &alux_op, &alux_op, &alux_store_op, &alux_store_op, - &alux_op, &alux_op, &alux_op, &alux_op, - }; -static const risc86_instruction_t *opcode_timings_8x[8] = - { - &alu_store_op, &alu_store_op, &vector_alu_store_op, &vector_alu_store_op, - &alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op, - }; -static const risc86_instruction_t *opcode_timings_8x_mod3[8] = - { - &alu_op, &alu_op, &alu_store_op, &alu_store_op, - &alu_op, &alu_op, &alu_op, &alu_op, - }; - -static const risc86_instruction_t *opcode_timings_f6[8] = - { -/* TST NOT NEG*/ - &test_mem_imm_b_op, INVALID, &vector_alux_store_op, &vector_alux_store_op, -/* MUL IMUL DIV IDIV*/ - &vector_mul_mem_op, &vector_mul_mem_op, &vector_div16_mem_op, &vector_div16_mem_op, - }; -static const risc86_instruction_t *opcode_timings_f6_mod3[8] = - { -/* TST NOT NEG*/ - &test_reg_b_op, INVALID, &alux_op, &alux_op, -/* MUL IMUL DIV IDIV*/ - &vector_mul_op, &vector_mul_op, &vector_div16_op, &vector_div16_op, - }; -static const risc86_instruction_t *opcode_timings_f7[8] = - { -/* TST NOT NEG*/ - &test_mem_imm_op, INVALID, &vector_alu_store_op, &vector_alu_store_op, -/* MUL IMUL DIV IDIV*/ - &vector_mul64_mem_op, &vector_mul64_mem_op, &vector_div32_mem_op, &vector_div32_mem_op, - }; -static const risc86_instruction_t *opcode_timings_f7_mod3[8] = - { -/* TST NOT NEG*/ - &test_reg_op, INVALID, &alu_op, &alu_op, -/* MUL IMUL DIV IDIV*/ - &vector_mul64_op, &vector_mul64_op, &vector_div32_op, &vector_div32_op, - }; -static const risc86_instruction_t *opcode_timings_ff[8] = - { -/* INC DEC CALL CALL far*/ - &alu_store_op, &alu_store_op, &store_op, &vector_call_far_op, -/* JMP JMP far PUSH*/ - &branch_op, &vector_jmp_far_op, &push_mem_op, INVALID - }; -static const risc86_instruction_t *opcode_timings_ff_mod3[8] = - { -/* INC DEC CALL CALL far*/ - &vector_alu1_op, &vector_alu1_op, &store_op, &vector_call_far_op, -/* JMP JMP far PUSH*/ - &branch_op, &vector_jmp_far_op, &vector_push_mem_op, INVALID - }; - -static const risc86_instruction_t *opcode_timings_d8[8] = - { -/* FADDs FMULs FCOMs FCOMPs*/ - &load_float_op, &load_float_op, &load_float_op, &load_float_op, -/* FSUBs FSUBRs FDIVs FDIVRs*/ - &load_float_op, &load_float_op, &fdiv_mem_op, &fdiv_mem_op, - }; -static const risc86_instruction_t *opcode_timings_d8_mod3[8] = - { -/* FADD FMUL FCOM FCOMP*/ - &float_op, &float_op, &float_op, &float_op, -/* FSUB FSUBR FDIV FDIVR*/ - &float_op, &float_op, &fdiv_op, &fdiv_op, - }; - -static const risc86_instruction_t *opcode_timings_d9[8] = - { -/* FLDs FSTs FSTPs*/ - &load_float_op, INVALID, &fstore_op, &fstore_op, -/* FLDENV FLDCW FSTENV FSTCW*/ - &vector_float_l_op, &vector_fldcw_op, &vector_float_l_op, &vector_float_op - }; -static const risc86_instruction_t *opcode_timings_d9_mod3[64] = - { - /*FLD*/ - &float_op, &float_op, &float_op, &float_op, - &float_op, &float_op, &float_op, &float_op, - /*FXCH*/ - &float_op, &float_op, &float_op, &float_op, - &float_op, &float_op, &float_op, &float_op, - /*FNOP*/ - &float_op, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - /*FSTP*/ - &float_op, &float_op, &float_op, &float_op, - &float_op, &float_op, &float_op, &float_op, -/* opFCHS opFABS*/ - &float_op, &float_op, INVALID, INVALID, -/* opFTST opFXAM*/ - &float_op, &float_op, INVALID, INVALID, -/* opFLD1 opFLDL2T opFLDL2E opFLDPI*/ - &float_op, &float_op, &float_op, &float_op, -/* opFLDEG2 opFLDLN2 opFLDZ*/ - &float_op, &float_op, &float_op, INVALID, -/* opF2XM1 opFYL2X opFPTAN opFPATAN*/ - &fsin_op, &fsin_op, &fsin_op, &fsin_op, -/* opFDECSTP opFINCSTP,*/ - INVALID, INVALID, &float_op, &float_op, -/* opFPREM opFSQRT opFSINCOS*/ - &fdiv_op, INVALID, &fsqrt_op, &fsin_op, -/* opFRNDINT opFSCALE opFSIN opFCOS*/ - &float_op, &fdiv_op, &fsin_op, &fsin_op - }; - -static const risc86_instruction_t *opcode_timings_da[8] = - { -/* FIADDl FIMULl FICOMl FICOMPl*/ - &load_float_op, &load_float_op, &load_float_op, &load_float_op, -/* FISUBl FISUBRl FIDIVl FIDIVRl*/ - &load_float_op, &load_float_op, &fdiv_mem_op, &fdiv_mem_op, - }; -static const risc86_instruction_t *opcode_timings_da_mod3[8] = - { - INVALID, INVALID, INVALID, INVALID, -/* FCOMPP*/ - INVALID, &float_op, INVALID, INVALID - }; - -static const risc86_instruction_t *opcode_timings_db[8] = - { -/* FLDil FSTil FSTPil*/ - &load_float_op, INVALID, &fstore_op, &fstore_op, -/* FLDe FSTPe*/ - INVALID, &vector_flde_op, INVALID, &vector_fste_op - }; -static const risc86_instruction_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, &float_op, &float_op, &float_op, -/* opFNOP opFNOP*/ - &float_op, &float_op, 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 const risc86_instruction_t *opcode_timings_dc[8] = - { -/* FADDd FMULd FCOMd FCOMPd*/ - &load_float_op, &load_float_op, &load_float_op, &load_float_op, -/* FSUBd FSUBRd FDIVd FDIVRd*/ - &load_float_op, &load_float_op, &fdiv_mem_op, &fdiv_mem_op, - }; -static const risc86_instruction_t *opcode_timings_dc_mod3[8] = - { -/* opFADDr opFMULr*/ - &float_op, &float_op, INVALID, INVALID, -/* opFSUBRr opFSUBr opFDIVRr opFDIVr*/ - &float_op, &float_op, &fdiv_op, &fdiv_op - }; - -static const risc86_instruction_t *opcode_timings_dd[8] = - { -/* FLDd FSTd FSTPd*/ - &load_float_op, INVALID, &fstore_op, &fstore_op, -/* FRSTOR FSAVE FSTSW*/ - &vector_float_l_op, INVALID, &vector_float_l_op, &vector_float_l_op - }; -static const risc86_instruction_t *opcode_timings_dd_mod3[8] = - { -/* FFFREE FST FSTP*/ - &float_op, INVALID, &float_op, &float_op, -/* FUCOM FUCOMP*/ - &float_op, &float_op, INVALID, INVALID - }; - -static const risc86_instruction_t *opcode_timings_de[8] = - { -/* FIADDw FIMULw FICOMw FICOMPw*/ - &load_float_op, &load_float_op, &load_float_op, &load_float_op, -/* FISUBw FISUBRw FIDIVw FIDIVRw*/ - &load_float_op, &load_float_op, &fdiv_mem_op, &fdiv_mem_op, - }; -static const risc86_instruction_t *opcode_timings_de_mod3[8] = - { -/* FADDP FMULP FCOMPP*/ - &float_op, &float_op, INVALID, &float_op, -/* FSUBP FSUBRP FDIVP FDIVRP*/ - &float_op, &float_op, &fdiv_op, &fdiv_op, - }; - -static const risc86_instruction_t *opcode_timings_df[8] = - { -/* FILDiw FISTiw FISTPiw*/ - &load_float_op, INVALID, &fstore_op, &fstore_op, -/* FILDiq FBSTP FISTPiq*/ - INVALID, &load_float_op, &vector_float_l_op, &fstore_op, - }; -static const risc86_instruction_t *opcode_timings_df_mod3[8] = - { - INVALID, INVALID, INVALID, INVALID, -/* FSTSW AX*/ - &float_op, INVALID, INVALID, INVALID - }; +static const risc86_instruction_t *opcode_timings[256] = { + /* ADD ADD ADD ADD*/ + /*00*/ &alux_store_op, &alu_store_op, &load_alux_op, &load_alu_op, + /* ADD ADD PUSH ES POP ES*/ + &alux_op, &alu_op, &push_seg_op, &vector_mov_seg_mem_op, + /* OR OR OR OR*/ + &alux_store_op, &alu_store_op, &load_alux_op, &load_alu_op, + /* OR OR PUSH CS */ + &alux_op, &alu_op, &push_seg_op, INVALID, + + /* ADC ADC ADC ADC*/ + /*10*/ &vector_alux_store_op, &vector_alu_store_op, &vector_load_alux_op, &vector_load_alu_op, + /* ADC ADC PUSH SS POP SS*/ + &vector_alux1_op, &vector_alu1_op, &push_seg_op, &vector_mov_seg_mem_op, + /* SBB SBB SBB SBB*/ + /*10*/ &vector_alux_store_op, &vector_alu_store_op, &vector_load_alux_op, &vector_load_alu_op, + /* SBB SBB PUSH DS POP DS*/ + &vector_alux1_op, &vector_alu1_op, &push_seg_op, &vector_mov_seg_mem_op, + + /* AND AND AND AND*/ + /*20*/ &alux_store_op, &alu_store_op, &load_alux_op, &load_alu_op, + /* AND AND DAA*/ + &alux_op, &alu_op, INVALID, &vector_alux1_op, + /* SUB SUB SUB SUB*/ + &alux_store_op, &alu_store_op, &load_alux_op, &load_alu_op, + /* SUB SUB DAS*/ + &alux_op, &alu_op, INVALID, &vector_alux1_op, + + /* XOR XOR XOR XOR*/ + /*30*/ &alux_store_op, &alu_store_op, &load_alux_op, &load_alu_op, + /* XOR XOR AAA*/ + &alux_op, &alu_op, INVALID, &vector_alux6_op, + /* CMP CMP CMP CMP*/ + &load_alux_op, &load_alu_op, &load_alux_op, &load_alu_op, + /* CMP CMP AAS*/ + &alux_op, &alu_op, INVALID, &vector_alux6_op, + + /* INC EAX INC ECX INC EDX INC EBX*/ + /*40*/ &alu_op, &alu_op, &alu_op, &alu_op, + /* INC ESP INC EBP INC ESI INC EDI*/ + &alu_op, &alu_op, &alu_op, &alu_op, + /* DEC EAX DEC ECX DEC EDX DEC EBX*/ + &alu_op, &alu_op, &alu_op, &alu_op, + /* DEC ESP DEC EBP DEC ESI DEC EDI*/ + &alu_op, &alu_op, &alu_op, &alu_op, + + /* PUSH EAX PUSH ECX PUSH EDX PUSH EBX*/ + /*50*/ &store_op, &store_op, &store_op, &store_op, + /* PUSH ESP PUSH EBP PUSH ESI PUSH EDI*/ + &store_op, &store_op, &store_op, &store_op, + /* POP EAX POP ECX POP EDX POP EBX*/ + &pop_reg_op, &pop_reg_op, &pop_reg_op, &pop_reg_op, + /* POP ESP POP EBP POP ESI POP EDI*/ + &pop_reg_op, &pop_reg_op, &pop_reg_op, &pop_reg_op, + + /* PUSHA POPA BOUND ARPL*/ + /*60*/ &vector_pusha_op, &vector_popa_op, &vector_bound_op, &vector_arpl_op, INVALID, INVALID, INVALID, INVALID, + /* PUSH imm IMUL PUSH imm IMUL*/ + &push_imm_op, &vector_mul_op, &push_imm_op, &vector_mul_op, + /* INSB INSW OUTSB OUTSW*/ + &vector_ins_op, &vector_ins_op, &vector_outs_op, &vector_outs_op, + + /* Jxx*/ + /*70*/ &branch_op, &branch_op, &branch_op, &branch_op, &branch_op, &branch_op, &branch_op, &branch_op, &branch_op, + &branch_op, &branch_op, &branch_op, &branch_op, &branch_op, &branch_op, &branch_op, + + /*80*/ INVALID, INVALID, INVALID, INVALID, + /* TEST TEST XCHG XCHG*/ + &vector_test_mem_b_op, &vector_test_mem_op, &vector_xchg_mem_op, &vector_xchg_mem_op, + /* MOV MOV MOV MOV*/ + &store_op, &store_op, &load_op, &load_op, + /* MOV from seg LEA MOV to seg POP*/ + &vector_mov_mem_seg_op, &store_op, &vector_mov_seg_mem_op, &pop_mem_op, + + /* NOP XCHG XCHG XCHG*/ + /*90*/ &limm_op, &xchg_op, &xchg_op, &xchg_op, + /* XCHG XCHG XCHG XCHG*/ + &xchg_op, &xchg_op, &xchg_op, &xchg_op, + /* CBW CWD CALL far WAIT*/ + &vector_alu1_op, &vector_alu1_op, &vector_call_far_op, &limm_op, + /* PUSHF POPF SAHF LAHF*/ + &vector_pushf_op, &vector_popf_op, &vector_alux1_op, &vector_alux1_op, + + /* MOV MOV MOV MOV*/ + /*a0*/ &load_op, &load_op, &store_op, &store_op, + /* MOVSB MOVSW CMPSB CMPSW*/ + &movs_op, &movs_op, &vector_cmpsb_op, &vector_cmps_op, + /* TEST TEST STOSB STOSW*/ + &test_reg_b_op, &test_reg_op, &stos_op, &stos_op, + /* LODSB LODSW SCASB SCASW*/ + &lods_op, &lods_op, &vector_scasb_op, &vector_scas_op, + + /* MOV*/ + /*b0*/ &limm_op, &limm_op, &limm_op, &limm_op, &limm_op, &limm_op, &limm_op, &limm_op, &limm_op, &limm_op, &limm_op, + &limm_op, &limm_op, &limm_op, &limm_op, &limm_op, + + /* RET imm RET*/ + /*c0*/ INVALID, INVALID, &vector_ret_op, &vector_ret_op, + /* LES LDS MOV MOV*/ + &vector_lss_op, &vector_lss_op, &store_op, &store_op, + /* ENTER LEAVE RETF RETF*/ + &vector_enter_op, &leave_op, &vector_retf_op, &vector_retf_op, + /* INT3 INT INTO IRET*/ + &vector_int_op, &vector_int_op, &vector_int_op, &vector_iret_op, + + /*d0*/ INVALID, INVALID, INVALID, INVALID, + /* AAM AAD SETALC XLAT*/ + &vector_alux6_op, &vector_alux3_op, &vector_alux1_op, &vector_xlat_op, INVALID, INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, + /* LOOPNE LOOPE LOOP JCXZ*/ + /*e0*/ &vector_loop_op, &vector_loop_op, &loop_op, &vector_loop_op, + /* IN AL IN AX OUT_AL OUT_AX*/ + &vector_in_op, &vector_in_op, &vector_out_op, &vector_out_op, + /* CALL JMP JMP JMP*/ + &store_op, &branch_op, &vector_jmp_far_op, &branch_op, + /* IN AL IN AX OUT_AL OUT_AX*/ + &vector_in_op, &vector_in_op, &vector_out_op, &vector_out_op, + + /* REPNE REPE*/ + /*f0*/ INVALID, INVALID, INVALID, INVALID, + /* HLT CMC*/ + &vector_alux1_op, &vector_alu2_op, INVALID, INVALID, + /* CLC STC CLI STI*/ + &vector_alu1_op, &vector_alu1_op, &vector_cli_sti_op, &vector_cli_sti_op, + /* CLD STD INCDEC*/ + &vector_alu1_op, &vector_alu1_op, &alux_store_op, INVALID}; + +static const risc86_instruction_t *opcode_timings_mod3[256] = { + /* ADD ADD ADD ADD*/ + /*00*/ &alux_op, &alu_op, &alux_op, &alu_op, + /* ADD ADD PUSH ES POP ES*/ + &alux_op, &alu_op, &push_seg_op, &vector_mov_seg_mem_op, + /* OR OR OR OR*/ + &alux_op, &alu_op, &alux_op, &alu_op, + /* OR OR PUSH CS */ + &alux_op, &alu_op, &push_seg_op, INVALID, + + /* ADC ADC ADC ADC*/ + /*10*/ &vector_alux1_op, &vector_alu1_op, &vector_alux1_op, &vector_alu1_op, + /* ADC ADC PUSH SS POP SS*/ + &vector_alux1_op, &vector_alu1_op, &push_seg_op, &vector_mov_seg_mem_op, + /* SBB SBB SBB SBB*/ + &vector_alux1_op, &vector_alu1_op, &vector_alux1_op, &vector_alu1_op, + /* SBB SBB PUSH DS POP DS*/ + &vector_alux1_op, &vector_alu1_op, &push_seg_op, &vector_mov_seg_mem_op, + + /* AND AND AND AND*/ + /*20*/ &alux_op, &alu_op, &alux_op, &alu_op, + /* AND AND DAA*/ + &alux_op, &alu_op, INVALID, &vector_alux1_op, + /* SUB SUB SUB SUB*/ + &alux_op, &alu_op, &alux_op, &alu_op, + /* SUB SUB DAS*/ + &alux_op, &alu_op, INVALID, &vector_alux1_op, + + /* XOR XOR XOR XOR*/ + /*30*/ &alux_op, &alu_op, &alux_op, &alu_op, + /* XOR XOR AAA*/ + &alux_op, &alu_op, INVALID, &vector_alux6_op, + /* CMP CMP CMP CMP*/ + &alux_op, &alu_op, &alux_op, &alu_op, + /* CMP CMP AAS*/ + &alux_op, &alu_op, INVALID, &vector_alux6_op, + + /* INC EAX INC ECX INC EDX INC EBX*/ + /*40*/ &alu_op, &alu_op, &alu_op, &alu_op, + /* INC ESP INC EBP INC ESI INC EDI*/ + &alu_op, &alu_op, &alu_op, &alu_op, + /* DEC EAX DEC ECX DEC EDX DEC EBX*/ + &alu_op, &alu_op, &alu_op, &alu_op, + /* DEC ESP DEC EBP DEC ESI DEC EDI*/ + &alu_op, &alu_op, &alu_op, &alu_op, + + /* PUSH EAX PUSH ECX PUSH EDX PUSH EBX*/ + /*50*/ &store_op, &store_op, &store_op, &store_op, + /* PUSH ESP PUSH EBP PUSH ESI PUSH EDI*/ + &store_op, &store_op, &store_op, &store_op, + /* POP EAX POP ECX POP EDX POP EBX*/ + &pop_reg_op, &pop_reg_op, &pop_reg_op, &pop_reg_op, + /* POP ESP POP EBP POP ESI POP EDI*/ + &pop_reg_op, &pop_reg_op, &pop_reg_op, &pop_reg_op, + + /* PUSHA POPA BOUND ARPL*/ + /*60*/ &vector_pusha_op, &vector_popa_op, &vector_bound_op, &vector_arpl_op, INVALID, INVALID, INVALID, INVALID, + /* PUSH imm IMUL PUSH imm IMUL*/ + &push_imm_op, &vector_mul_op, &push_imm_op, &vector_mul_op, + /* INSB INSW OUTSB OUTSW*/ + &vector_ins_op, &vector_ins_op, &vector_outs_op, &vector_outs_op, + + /* Jxx*/ + /*70*/ &branch_op, &branch_op, &branch_op, &branch_op, &branch_op, &branch_op, &branch_op, &branch_op, &branch_op, + &branch_op, &branch_op, &branch_op, &branch_op, &branch_op, &branch_op, &branch_op, + + /*80*/ INVALID, INVALID, INVALID, INVALID, + /* TEST TEST XCHG XCHG*/ + &vector_alu1_op, &vector_alu1_op, &vector_alu3_op, &vector_alu3_op, + /* MOV MOV MOV MOV*/ + &store_op, &store_op, &load_op, &load_op, + /* MOV from seg LEA MOV to seg POP*/ + &mov_reg_seg_op, &store_op, &vector_mov_seg_reg_op, &pop_reg_op, + + /* NOP XCHG XCHG XCHG*/ + /*90*/ &limm_op, &xchg_op, &xchg_op, &xchg_op, + /* XCHG XCHG XCHG XCHG*/ + &xchg_op, &xchg_op, &xchg_op, &xchg_op, + /* CBW CWD CALL far WAIT*/ + &vector_alu1_op, &vector_alu1_op, &vector_call_far_op, &limm_op, + /* PUSHF POPF SAHF LAHF*/ + &vector_pushf_op, &vector_popf_op, &vector_alux1_op, &vector_alux1_op, + + /* MOV MOV MOV MOV*/ + /*a0*/ &load_op, &load_op, &store_op, &store_op, + /* MOVSB MOVSW CMPSB CMPSW*/ + &movs_op, &movs_op, &vector_cmpsb_op, &vector_cmps_op, + /* TEST TEST STOSB STOSW*/ + &test_reg_b_op, &test_reg_op, &stos_op, &stos_op, + /* LODSB LODSW SCASB SCASW*/ + &lods_op, &lods_op, &vector_scasb_op, &vector_scas_op, + + /* MOV*/ + /*b0*/ &limm_op, &limm_op, &limm_op, &limm_op, &limm_op, &limm_op, &limm_op, &limm_op, &limm_op, &limm_op, &limm_op, + &limm_op, &limm_op, &limm_op, &limm_op, &limm_op, + + /* RET imm RET*/ + /*c0*/ INVALID, INVALID, &vector_ret_op, &vector_ret_op, + /* LES LDS MOV MOV*/ + &vector_lss_op, &vector_lss_op, &store_op, &store_op, + /* ENTER LEAVE RETF RETF*/ + &vector_enter_op, &leave_op, &vector_retf_op, &vector_retf_op, + /* INT3 INT INTO IRET*/ + &vector_int_op, &vector_int_op, &vector_int_op, &vector_iret_op, + + /*d0*/ INVALID, INVALID, INVALID, INVALID, + /* AAM AAD SETALC XLAT*/ + &vector_alux6_op, &vector_alux3_op, &vector_alux1_op, &vector_xlat_op, INVALID, INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, + /* LOOPNE LOOPE LOOP JCXZ*/ + /*e0*/ &vector_loop_op, &vector_loop_op, &loop_op, &vector_loop_op, + /* IN AL IN AX OUT_AL OUT_AX*/ + &vector_in_op, &vector_in_op, &vector_out_op, &vector_out_op, + /* CALL JMP JMP JMP*/ + &store_op, &branch_op, &vector_jmp_far_op, &branch_op, + /* IN AL IN AX OUT_AL OUT_AX*/ + &vector_in_op, &vector_in_op, &vector_out_op, &vector_out_op, + + /* REPNE REPE*/ + /*f0*/ INVALID, INVALID, INVALID, INVALID, + /* HLT CMC*/ + &vector_alux1_op, &vector_alu2_op, INVALID, INVALID, + /* CLC STC CLI STI*/ + &vector_alu1_op, &vector_alu1_op, &vector_cli_sti_op, &vector_cli_sti_op, + /* CLD STD INCDEC*/ + &vector_alu1_op, &vector_alu1_op, &vector_alux1_op, INVALID}; + +static const risc86_instruction_t *opcode_timings_0f[256] = { + /*00*/ &vector_alu6_op, + &vector_alu6_op, + &vector_alu6_op, + &vector_alu6_op, + INVALID, + &vector_alu6_op, + &vector_alu6_op, + INVALID, + &vector_invd_op, + &vector_wbinvd_op, + INVALID, + INVALID, + INVALID, + &load_op, + &vector_femms_op, + &load_3dn_op, + + /*10*/ INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + + /*20*/ &vector_alu6_op, + &vector_alu6_op, + &vector_alu6_op, + &vector_alu6_op, + &vector_alu6_op, + &vector_alu6_op, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + + /*30*/ &vector_alu6_op, + &vector_alu6_op, + &vector_alu6_op, + 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*/ &load_mmx_op, + &load_mmx_op, + &load_mmx_op, + &load_mmx_op, + &load_mmx_op, + &load_mmx_op, + &load_mmx_op, + &load_mmx_op, + &load_mmx_op, + &load_mmx_op, + &load_mmx_op, + &load_mmx_op, + INVALID, + INVALID, + &mload_op, + &mload_op, + + /*70*/ INVALID, + &load_mmx_shift_op, + &load_mmx_shift_op, + &load_mmx_shift_op, + &load_mmx_op, + &load_mmx_op, + &load_mmx_op, + &vector_emms_op, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + &mstore_op, + &mstore_op, + + /*80*/ &branch_op, + &branch_op, + &branch_op, + &branch_op, + &branch_op, + &branch_op, + &branch_op, + &branch_op, + &branch_op, + &branch_op, + &branch_op, + &branch_op, + &branch_op, + &branch_op, + &branch_op, + &branch_op, + + /*90*/ &vector_setcc_reg_op, + &vector_setcc_reg_op, + &vector_setcc_reg_op, + &vector_setcc_reg_op, + &vector_setcc_reg_op, + &vector_setcc_reg_op, + &vector_setcc_reg_op, + &vector_setcc_reg_op, + &vector_setcc_reg_op, + &vector_setcc_reg_op, + &vector_setcc_reg_op, + &vector_setcc_reg_op, + &vector_setcc_reg_op, + &vector_setcc_reg_op, + &vector_setcc_reg_op, + &vector_setcc_reg_op, + + /*a0*/ &push_seg_op, + &vector_mov_seg_mem_op, + &vector_cpuid_op, + &vector_load_alu_op, + &vector_alu_store_op, + &vector_alu_store_op, + INVALID, + INVALID, + &push_seg_op, + &vector_mov_seg_mem_op, + INVALID, + &vector_load_alu_op, + &vector_alu_store_op, + &vector_alu_store_op, + INVALID, + &vector_mul_op, + + /*b0*/ &vector_cmpxchg_b_op, + &vector_cmpxchg_op, + &vector_lss_op, + &vector_load_alu_op, + &vector_lss_op, + &vector_lss_op, + &load_alux_op, + &load_alu_op, + INVALID, + INVALID, + &vector_load_alu_op, + &vector_load_alu_op, + &vector_bsx_op, + &vector_bsx_op, + &load_alux_op, + &load_alu_op, + + /*c0*/ &vector_alux_store_op, + &vector_alu_store_op, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + &vector_cmpxchg_op, + &bswap_op, + &bswap_op, + &bswap_op, + &bswap_op, + &bswap_op, + &bswap_op, + &bswap_op, + &bswap_op, + + /*d0*/ INVALID, + &load_mmx_shift_op, + &load_mmx_shift_op, + &load_mmx_shift_op, + INVALID, + &load_mmx_mul_op, + INVALID, + INVALID, + &load_mmx_op, + &load_mmx_op, + INVALID, + &load_mmx_op, + &load_mmx_op, + &load_mmx_op, + INVALID, + &load_mmx_op, + + /*e0*/ &load_mmx_op, + &load_mmx_shift_op, + &load_mmx_shift_op, + INVALID, + INVALID, + &pmul_mem_op, + INVALID, + INVALID, + &load_mmx_op, + &load_mmx_op, + INVALID, + &load_mmx_op, + &load_mmx_op, + &load_mmx_op, + INVALID, + &load_mmx_op, + + /*f0*/ INVALID, + &load_mmx_shift_op, + &load_mmx_shift_op, + &load_mmx_shift_op, + INVALID, + &pmul_mem_op, + INVALID, + INVALID, + &load_mmx_op, + &load_mmx_op, + &load_mmx_op, + INVALID, + &load_mmx_op, + &load_mmx_op, + &load_mmx_op, + INVALID, +}; +static const risc86_instruction_t *opcode_timings_0f_mod3[256] = { + /*00*/ &vector_alu6_op, + &vector_alu6_op, + &vector_alu6_op, + &vector_alu6_op, + INVALID, + &vector_alu6_op, + &vector_alu6_op, + INVALID, + &vector_invd_op, + &vector_wbinvd_op, + INVALID, + INVALID, + INVALID, + INVALID, + &vector_femms_op, + &m3dn_op, + + /*10*/ INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + + /*20*/ &vector_alu6_op, + &vector_alu6_op, + &vector_alu6_op, + &vector_alu6_op, + &vector_alu6_op, + &vector_alu6_op, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + + /*30*/ &vector_alu6_op, + &vector_alu6_op, + &vector_alu6_op, + 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*/ &mmx_op, + &mmx_op, + &mmx_op, + &mmx_op, + &mmx_op, + &mmx_op, + &mmx_op, + &mmx_op, + &mmx_op, + &mmx_op, + &mmx_op, + &mmx_op, + INVALID, + INVALID, + &mmx_op, + &mmx_op, + + /*70*/ INVALID, + &mmx_shift_op, + &mmx_shift_op, + &mmx_shift_op, + &mmx_op, + &mmx_op, + &mmx_op, + &vector_emms_op, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + &mmx_op, + &mmx_op, + + /*80*/ &branch_op, + &branch_op, + &branch_op, + &branch_op, + &branch_op, + &branch_op, + &branch_op, + &branch_op, + &branch_op, + &branch_op, + &branch_op, + &branch_op, + &branch_op, + &branch_op, + &branch_op, + &branch_op, + + /*90*/ &vector_setcc_mem_op, + &vector_setcc_mem_op, + &vector_setcc_mem_op, + &vector_setcc_mem_op, + &vector_setcc_mem_op, + &vector_setcc_mem_op, + &vector_setcc_mem_op, + &vector_setcc_mem_op, + &vector_setcc_mem_op, + &vector_setcc_mem_op, + &vector_setcc_mem_op, + &vector_setcc_mem_op, + &vector_setcc_mem_op, + &vector_setcc_mem_op, + &vector_setcc_mem_op, + &vector_setcc_mem_op, + + /*a0*/ &push_seg_op, + &vector_mov_seg_mem_op, + &vector_cpuid_op, + &vector_alu1_op, + &vector_alu1_op, + &vector_alu1_op, + INVALID, + INVALID, + &push_seg_op, + &vector_mov_seg_mem_op, + INVALID, + &vector_alu1_op, + &vector_alu1_op, + &vector_alu1_op, + INVALID, + &vector_mul_op, + + /*b0*/ &vector_cmpxchg_b_op, + &vector_cmpxchg_op, + &vector_lss_op, + &vector_alu1_op, + &vector_lss_op, + &vector_lss_op, + &alux_op, + &alu_op, + INVALID, + INVALID, + &vector_alu1_op, + &vector_alu1_op, + &vector_bsx_op, + &vector_bsx_op, + &alux_op, + &alu_op, + + /*c0*/ &vector_alux1_op, + &vector_alu1_op, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + &bswap_op, + &bswap_op, + &bswap_op, + &bswap_op, + &bswap_op, + &bswap_op, + &bswap_op, + &bswap_op, + + /*d0*/ INVALID, + &mmx_shift_op, + &mmx_shift_op, + &mmx_shift_op, + INVALID, + &mmx_mul_op, + INVALID, + INVALID, + &mmx_op, + &mmx_op, + INVALID, + &mmx_op, + &mmx_op, + &mmx_op, + INVALID, + &mmx_op, + + /*e0*/ &mmx_op, + &mmx_shift_op, + &mmx_shift_op, + INVALID, + INVALID, + &pmul_op, + INVALID, + INVALID, + &mmx_op, + &mmx_op, + INVALID, + &mmx_op, + &mmx_op, + &mmx_op, + INVALID, + &mmx_op, + + /*f0*/ INVALID, + &mmx_shift_op, + &mmx_shift_op, + &mmx_shift_op, + INVALID, + &pmul_op, + INVALID, + INVALID, + &mmx_op, + &mmx_op, + &mmx_op, + INVALID, + &mmx_op, + &mmx_op, + &mmx_op, + INVALID, +}; + +static const risc86_instruction_t *opcode_timings_0f0f[256] = { + /*00*/ INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + &load_3dn_op, + INVALID, + INVALID, + + /*10*/ INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + &load_3dn_op, + INVALID, + INVALID, + + /*20*/ INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + + /*30*/ INVALID, + INVALID, + INVALID, + 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*/ INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + + /*70*/ INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + + /*80*/ INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + + /*90*/ &load_3dn_op, + INVALID, + INVALID, + INVALID, + &load_3dn_op, + INVALID, + &load_3dn_op, + &load_3dn_op, + INVALID, + INVALID, + &load_3dn_op, + INVALID, + INVALID, + INVALID, + &load_3dn_op, + INVALID, + + /*a0*/ &load_3dn_op, + INVALID, + INVALID, + INVALID, + &load_3dn_op, + INVALID, + &load_mmx_mul_op, + &load_mmx_mul_op, + INVALID, + INVALID, + &load_3dn_op, + INVALID, + INVALID, + INVALID, + &load_3dn_op, + INVALID, + + /*b0*/ &load_3dn_op, + INVALID, + INVALID, + INVALID, + &load_mmx_mul_op, + INVALID, + &load_mmx_mul_op, + &load_mmx_mul_op, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + &load_mmx_op, + + /*c0*/ INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + + /*d0*/ INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + + /*e0*/ INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + + /*f0*/ INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + +}; +static const risc86_instruction_t *opcode_timings_0f0f_mod3[256] = { + /*00*/ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, INVALID, &m3dn_op, INVALID, INVALID, + + /*10*/ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, INVALID, &m3dn_op, INVALID, INVALID, + + /*20*/ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, + + /*30*/ INVALID, INVALID, INVALID, 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*/ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, + + /*70*/ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, + + /*80*/ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, + + /*90*/ &m3dn_op, INVALID, INVALID, INVALID, &m3dn_op, INVALID, &m3dn_op, &m3dn_op, + INVALID, INVALID, &m3dn_op, INVALID, INVALID, INVALID, &m3dn_op, INVALID, + + /*a0*/ &m3dn_op, INVALID, INVALID, INVALID, &m3dn_op, INVALID, &mmx_mul_op, &mmx_mul_op, + INVALID, INVALID, &m3dn_op, INVALID, INVALID, INVALID, &m3dn_op, INVALID, + + /*b0*/ &m3dn_op, INVALID, INVALID, INVALID, &mmx_mul_op, INVALID, &mmx_mul_op, &mmx_mul_op, + INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, &mmx_op, + + /*c0*/ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, + + /*d0*/ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, + + /*e0*/ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, + + /*f0*/ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, + +}; + +static const risc86_instruction_t *opcode_timings_shift[8] = {&vector_alu_store_op, &vector_alu_store_op, &vector_alu_store_op, + &vector_alu_store_op, &vector_alu_store_op, &vector_alu_store_op, + &vector_alu_store_op, &vector_alu_store_op}; +static const risc86_instruction_t *opcode_timings_shift_b[8] = { + &vector_alux_store_op, &vector_alux_store_op, &vector_alux_store_op, &vector_alux_store_op, + &vector_alux_store_op, &vector_alux_store_op, &vector_alux_store_op, &vector_alux_store_op}; +static const risc86_instruction_t *opcode_timings_shift_mod3[8] = { + &vector_alu1_op, &vector_alu1_op, &vector_alu1_op, &vector_alu1_op, &alu_op, &alu_op, &alu_op, &alu_op}; +static const risc86_instruction_t *opcode_timings_shift_b_mod3[8] = { + &vector_alux1_op, &vector_alux1_op, &vector_alux1_op, &vector_alux1_op, &alux_op, &alux_op, &alux_op, &alux_op}; + +static const risc86_instruction_t *opcode_timings_80[8] = { + &alux_store_op, &alux_store_op, &vector_alux_store_op, &vector_alux_store_op, + &alux_store_op, &alux_store_op, &alux_store_op, &alux_store_op, +}; +static const risc86_instruction_t *opcode_timings_80_mod3[8] = { + &alux_op, &alux_op, &alux_store_op, &alux_store_op, &alux_op, &alux_op, &alux_op, &alux_op, +}; +static const risc86_instruction_t *opcode_timings_8x[8] = { + &alu_store_op, &alu_store_op, &vector_alu_store_op, &vector_alu_store_op, + &alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op, +}; +static const risc86_instruction_t *opcode_timings_8x_mod3[8] = { + &alu_op, &alu_op, &alu_store_op, &alu_store_op, &alu_op, &alu_op, &alu_op, &alu_op, +}; + +static const risc86_instruction_t *opcode_timings_f6[8] = { + /* TST NOT NEG*/ + &test_mem_imm_b_op, + INVALID, + &vector_alux_store_op, + &vector_alux_store_op, + /* MUL IMUL DIV IDIV*/ + &vector_mul_mem_op, + &vector_mul_mem_op, + &vector_div16_mem_op, + &vector_div16_mem_op, +}; +static const risc86_instruction_t *opcode_timings_f6_mod3[8] = { + /* TST NOT NEG*/ + &test_reg_b_op, + INVALID, + &alux_op, + &alux_op, + /* MUL IMUL DIV IDIV*/ + &vector_mul_op, + &vector_mul_op, + &vector_div16_op, + &vector_div16_op, +}; +static const risc86_instruction_t *opcode_timings_f7[8] = { + /* TST NOT NEG*/ + &test_mem_imm_op, + INVALID, + &vector_alu_store_op, + &vector_alu_store_op, + /* MUL IMUL DIV IDIV*/ + &vector_mul64_mem_op, + &vector_mul64_mem_op, + &vector_div32_mem_op, + &vector_div32_mem_op, +}; +static const risc86_instruction_t *opcode_timings_f7_mod3[8] = { + /* TST NOT NEG*/ + &test_reg_op, + INVALID, + &alu_op, + &alu_op, + /* MUL IMUL DIV IDIV*/ + &vector_mul64_op, + &vector_mul64_op, + &vector_div32_op, + &vector_div32_op, +}; +static const risc86_instruction_t *opcode_timings_ff[8] = { + /* INC DEC CALL CALL far*/ + &alu_store_op, &alu_store_op, &store_op, &vector_call_far_op, + /* JMP JMP far PUSH*/ + &branch_op, &vector_jmp_far_op, &push_mem_op, INVALID}; +static const risc86_instruction_t *opcode_timings_ff_mod3[8] = { + /* INC DEC CALL CALL far*/ + &vector_alu1_op, &vector_alu1_op, &store_op, &vector_call_far_op, + /* JMP JMP far PUSH*/ + &branch_op, &vector_jmp_far_op, &vector_push_mem_op, INVALID}; + +static const risc86_instruction_t *opcode_timings_d8[8] = { + /* FADDs FMULs FCOMs FCOMPs*/ + &load_float_op, + &load_float_op, + &load_float_op, + &load_float_op, + /* FSUBs FSUBRs FDIVs FDIVRs*/ + &load_float_op, + &load_float_op, + &fdiv_mem_op, + &fdiv_mem_op, +}; +static const risc86_instruction_t *opcode_timings_d8_mod3[8] = { + /* FADD FMUL FCOM FCOMP*/ + &float_op, + &float_op, + &float_op, + &float_op, + /* FSUB FSUBR FDIV FDIVR*/ + &float_op, + &float_op, + &fdiv_op, + &fdiv_op, +}; + +static const risc86_instruction_t *opcode_timings_d9[8] = { + /* FLDs FSTs FSTPs*/ + &load_float_op, INVALID, &fstore_op, &fstore_op, + /* FLDENV FLDCW FSTENV FSTCW*/ + &vector_float_l_op, &vector_fldcw_op, &vector_float_l_op, &vector_float_op}; +static const risc86_instruction_t *opcode_timings_d9_mod3[64] = { + /*FLD*/ + &float_op, &float_op, &float_op, &float_op, &float_op, &float_op, &float_op, &float_op, + /*FXCH*/ + &float_op, &float_op, &float_op, &float_op, &float_op, &float_op, &float_op, &float_op, + /*FNOP*/ + &float_op, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, + /*FSTP*/ + &float_op, &float_op, &float_op, &float_op, &float_op, &float_op, &float_op, &float_op, + /* opFCHS opFABS*/ + &float_op, &float_op, INVALID, INVALID, + /* opFTST opFXAM*/ + &float_op, &float_op, INVALID, INVALID, + /* opFLD1 opFLDL2T opFLDL2E opFLDPI*/ + &float_op, &float_op, &float_op, &float_op, + /* opFLDEG2 opFLDLN2 opFLDZ*/ + &float_op, &float_op, &float_op, INVALID, + /* opF2XM1 opFYL2X opFPTAN opFPATAN*/ + &fsin_op, &fsin_op, &fsin_op, &fsin_op, + /* opFDECSTP opFINCSTP,*/ + INVALID, INVALID, &float_op, &float_op, + /* opFPREM opFSQRT opFSINCOS*/ + &fdiv_op, INVALID, &fsqrt_op, &fsin_op, + /* opFRNDINT opFSCALE opFSIN opFCOS*/ + &float_op, &fdiv_op, &fsin_op, &fsin_op}; + +static const risc86_instruction_t *opcode_timings_da[8] = { + /* FIADDl FIMULl FICOMl FICOMPl*/ + &load_float_op, + &load_float_op, + &load_float_op, + &load_float_op, + /* FISUBl FISUBRl FIDIVl FIDIVRl*/ + &load_float_op, + &load_float_op, + &fdiv_mem_op, + &fdiv_mem_op, +}; +static const risc86_instruction_t *opcode_timings_da_mod3[8] = {INVALID, INVALID, INVALID, INVALID, + /* FCOMPP*/ + INVALID, &float_op, INVALID, INVALID}; + +static const risc86_instruction_t *opcode_timings_db[8] = { + /* FLDil FSTil FSTPil*/ + &load_float_op, INVALID, &fstore_op, &fstore_op, + /* FLDe FSTPe*/ + INVALID, &vector_flde_op, INVALID, &vector_fste_op}; +static const risc86_instruction_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, + &float_op, + &float_op, + &float_op, + /* opFNOP opFNOP*/ + &float_op, + &float_op, + 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 const risc86_instruction_t *opcode_timings_dc[8] = { + /* FADDd FMULd FCOMd FCOMPd*/ + &load_float_op, + &load_float_op, + &load_float_op, + &load_float_op, + /* FSUBd FSUBRd FDIVd FDIVRd*/ + &load_float_op, + &load_float_op, + &fdiv_mem_op, + &fdiv_mem_op, +}; +static const risc86_instruction_t *opcode_timings_dc_mod3[8] = { + /* opFADDr opFMULr*/ + &float_op, &float_op, INVALID, INVALID, + /* opFSUBRr opFSUBr opFDIVRr opFDIVr*/ + &float_op, &float_op, &fdiv_op, &fdiv_op}; + +static const risc86_instruction_t *opcode_timings_dd[8] = { + /* FLDd FSTd FSTPd*/ + &load_float_op, INVALID, &fstore_op, &fstore_op, + /* FRSTOR FSAVE FSTSW*/ + &vector_float_l_op, INVALID, &vector_float_l_op, &vector_float_l_op}; +static const risc86_instruction_t *opcode_timings_dd_mod3[8] = { + /* FFFREE FST FSTP*/ + &float_op, INVALID, &float_op, &float_op, + /* FUCOM FUCOMP*/ + &float_op, &float_op, INVALID, INVALID}; + +static const risc86_instruction_t *opcode_timings_de[8] = { + /* FIADDw FIMULw FICOMw FICOMPw*/ + &load_float_op, + &load_float_op, + &load_float_op, + &load_float_op, + /* FISUBw FISUBRw FIDIVw FIDIVRw*/ + &load_float_op, + &load_float_op, + &fdiv_mem_op, + &fdiv_mem_op, +}; +static const risc86_instruction_t *opcode_timings_de_mod3[8] = { + /* FADDP FMULP FCOMPP*/ + &float_op, + &float_op, + INVALID, + &float_op, + /* FSUBP FSUBRP FDIVP FDIVRP*/ + &float_op, + &float_op, + &fdiv_op, + &fdiv_op, +}; + +static const risc86_instruction_t *opcode_timings_df[8] = { + /* FILDiw FISTiw FISTPiw*/ + &load_float_op, + INVALID, + &fstore_op, + &fstore_op, + /* FILDiq FBSTP FISTPiq*/ + INVALID, + &load_float_op, + &vector_float_l_op, + &fstore_op, +}; +static const risc86_instruction_t *opcode_timings_df_mod3[8] = {INVALID, INVALID, INVALID, INVALID, + /* FSTSW AX*/ + &float_op, INVALID, INVALID, INVALID}; static uint8_t last_prefix; static int prefixes; @@ -1723,39 +1934,37 @@ static int decode_timestamp; static int last_complete_timestamp; typedef struct k6_unit_t { - uint32_t uop_mask; - int first_available_cycle; + uint32_t uop_mask; + int first_available_cycle; } k6_unit_t; static int nr_units; static k6_unit_t *units; /*K6 has dedicated MMX unit*/ -static k6_unit_t k6_units[] = - { - {.uop_mask = (1 << UOP_ALU) | (1 << UOP_ALUX)}, /*Integer X*/ - {.uop_mask = (1 << UOP_ALU)}, /*Integer Y*/ - {.uop_mask = (1 << UOP_MEU) | (1 << UOP_MEU_SHIFT) | (1 << UOP_MEU_MUL)}, /*Multimedia*/ - {.uop_mask = (1 << UOP_FLOAT)}, /*Floating point*/ - {.uop_mask = (1 << UOP_LOAD) | (1 << UOP_FLOAD) | (1 << UOP_MLOAD)}, /*Load*/ - {.uop_mask = (1 << UOP_STORE) | (1 << UOP_FSTORE) | (1 << UOP_MSTORE)}, /*Store*/ - {.uop_mask = (1 << UOP_BRANCH)} /*Branch*/ - }; +static k6_unit_t k6_units[] = { + {.uop_mask = (1 << UOP_ALU) | (1 << UOP_ALUX)}, /*Integer X*/ + {.uop_mask = (1 << UOP_ALU)}, /*Integer Y*/ + {.uop_mask = (1 << UOP_MEU) | (1 << UOP_MEU_SHIFT) | (1 << UOP_MEU_MUL)}, /*Multimedia*/ + {.uop_mask = (1 << UOP_FLOAT)}, /*Floating point*/ + {.uop_mask = (1 << UOP_LOAD) | (1 << UOP_FLOAD) | (1 << UOP_MLOAD)}, /*Load*/ + {.uop_mask = (1 << UOP_STORE) | (1 << UOP_FSTORE) | (1 << UOP_MSTORE)}, /*Store*/ + {.uop_mask = (1 << UOP_BRANCH)} /*Branch*/ +}; #define NR_K6_UNITS (sizeof(k6_units) / sizeof(k6_unit_t)) /*K6-2 and later integrate MMX into ALU X & Y, sharing multiplier, shifter and 3DNow ALU between two execution units*/ -static k6_unit_t k6_2_units[] = - { - {.uop_mask = (1 << UOP_ALU) | (1 << UOP_ALUX) | (1 << UOP_MEU) | /*Integer X*/ - (1 << UOP_MEU_SHIFT) | (1 << UOP_MEU_MUL) | (1 << UOP_MEU_3DN)}, - {.uop_mask = (1 << UOP_ALU) | (1 << UOP_MEU) | /*Integer Y*/ - (1 << UOP_MEU_SHIFT) | (1 << UOP_MEU_MUL) | (1 << UOP_MEU_3DN)}, - {.uop_mask = (1 << UOP_FLOAT)}, /*Floating point*/ - {.uop_mask = (1 << UOP_LOAD) | (1 << UOP_FLOAD) | (1 << UOP_MLOAD)}, /*Load*/ - {.uop_mask = (1 << UOP_STORE) | (1 << UOP_FSTORE) | (1 << UOP_MSTORE)}, /*Store*/ - {.uop_mask = (1 << UOP_BRANCH)} /*Branch*/ - }; +static k6_unit_t k6_2_units[] = { + {.uop_mask = (1 << UOP_ALU) | (1 << UOP_ALUX) | (1 << UOP_MEU) | /*Integer X*/ + (1 << UOP_MEU_SHIFT) | (1 << UOP_MEU_MUL) | (1 << UOP_MEU_3DN)}, + {.uop_mask = (1 << UOP_ALU) | (1 << UOP_MEU) | /*Integer Y*/ + (1 << UOP_MEU_SHIFT) | (1 << UOP_MEU_MUL) | (1 << UOP_MEU_3DN)}, + {.uop_mask = (1 << UOP_FLOAT)}, /*Floating point*/ + {.uop_mask = (1 << UOP_LOAD) | (1 << UOP_FLOAD) | (1 << UOP_MLOAD)}, /*Load*/ + {.uop_mask = (1 << UOP_STORE) | (1 << UOP_FSTORE) | (1 << UOP_MSTORE)}, /*Store*/ + {.uop_mask = (1 << UOP_BRANCH)} /*Branch*/ +}; #define NR_K6_2_UNITS (sizeof(k6_2_units) / sizeof(k6_unit_t)) /*First available cycles of shared execution units. Each of these can be submitted @@ -1765,50 +1974,50 @@ static int shift_first_available_cycle; static int m3dnow_first_available_cycle; static int uop_run(const risc86_uop_t *uop, int decode_time) { - int c; - k6_unit_t *best_unit = NULL; - int best_start_cycle = 99999; + int c; + k6_unit_t *best_unit = NULL; + int best_start_cycle = 99999; - /*UOP_LIMM does not require execution*/ - if (uop->type == UOP_LIMM) - return decode_time; + /*UOP_LIMM does not require execution*/ + if (uop->type == UOP_LIMM) + return decode_time; - /*Handle shared units on K6-2 and later*/ - if (units == k6_2_units) { - if (uop->type == UOP_MEU_MUL && decode_time < mul_first_available_cycle) - decode_time = mul_first_available_cycle; - else if (uop->type == UOP_MEU_SHIFT && decode_time < mul_first_available_cycle) - decode_time = shift_first_available_cycle; - else if (uop->type == UOP_MEU_3DN && decode_time < mul_first_available_cycle) - decode_time = m3dnow_first_available_cycle; - } + /*Handle shared units on K6-2 and later*/ + if (units == k6_2_units) { + if (uop->type == UOP_MEU_MUL && decode_time < mul_first_available_cycle) + decode_time = mul_first_available_cycle; + else if (uop->type == UOP_MEU_SHIFT && decode_time < mul_first_available_cycle) + decode_time = shift_first_available_cycle; + else if (uop->type == UOP_MEU_3DN && decode_time < mul_first_available_cycle) + decode_time = m3dnow_first_available_cycle; + } - /*Find execution unit for this uOP*/ - for (c = 0; c < nr_units; c++) { - if (units[c].uop_mask & (1 << uop->type)) { - if (units[c].first_available_cycle < best_start_cycle) { - best_unit = &units[c]; - best_start_cycle = units[c].first_available_cycle; - } - } - } - if (!best_unit) - fatal("uop_run: can not find execution unit\n"); + /*Find execution unit for this uOP*/ + for (c = 0; c < nr_units; c++) { + if (units[c].uop_mask & (1 << uop->type)) { + if (units[c].first_available_cycle < best_start_cycle) { + best_unit = &units[c]; + best_start_cycle = units[c].first_available_cycle; + } + } + } + if (!best_unit) + fatal("uop_run: can not find execution unit\n"); - if (best_start_cycle < decode_time) - best_start_cycle = decode_time; - best_unit->first_available_cycle = best_start_cycle + uop->throughput; + if (best_start_cycle < decode_time) + best_start_cycle = decode_time; + best_unit->first_available_cycle = best_start_cycle + uop->throughput; - if (units == k6_2_units) { - if (uop->type == UOP_MEU_MUL) - mul_first_available_cycle = best_start_cycle + uop->throughput; - else if (uop->type == UOP_MEU_SHIFT) - shift_first_available_cycle = best_start_cycle + uop->throughput; - else if (uop->type == UOP_MEU_3DN) - m3dnow_first_available_cycle = best_start_cycle + uop->throughput; - } + if (units == k6_2_units) { + if (uop->type == UOP_MEU_MUL) + mul_first_available_cycle = best_start_cycle + uop->throughput; + else if (uop->type == UOP_MEU_SHIFT) + shift_first_available_cycle = best_start_cycle + uop->throughput; + else if (uop->type == UOP_MEU_3DN) + m3dnow_first_available_cycle = best_start_cycle + uop->throughput; + } - return best_start_cycle + uop->throughput; + return best_start_cycle + uop->throughput; } /*The K6 decoder can decode, per clock : @@ -1817,12 +2026,12 @@ static int uop_run(const risc86_uop_t *uop, int decode_time) { - 1 'vector' instruction, up to 4 uOPs per cycle, plus (I think) 1 cycle startup delay) */ static struct { - int nr_uops; - const risc86_uop_t *uops[4]; - /*Earliest time a uop can start. If the timestamp is -1, then the uop is + int nr_uops; + const risc86_uop_t *uops[4]; + /*Earliest time a uop can start. If the timestamp is -1, then the uop is part of a dependency chain and the start time is the completion time of the previous uop*/ - int earliest_start[4]; + int earliest_start[4]; } decode_buffer; #define NR_OPQUADS 6 @@ -1841,450 +2050,459 @@ static int fpu_st_timestamp[8]; static int last_uop_timestamp = 0; void decode_flush() { - int c; - int uop_timestamp = 0; + int c; + int uop_timestamp = 0; - /*Decoded opquad can not be submitted if there are no free spaces in the + /*Decoded opquad can not be submitted if there are no free spaces in the opquad buffer*/ - if (decode_timestamp < opquad_completion_timestamp[next_opquad]) - decode_timestamp = opquad_completion_timestamp[next_opquad]; + if (decode_timestamp < opquad_completion_timestamp[next_opquad]) + decode_timestamp = opquad_completion_timestamp[next_opquad]; - /*Ensure that uops can not be submitted before they have been decoded*/ - if (decode_timestamp > last_uop_timestamp) - last_uop_timestamp = decode_timestamp; + /*Ensure that uops can not be submitted before they have been decoded*/ + if (decode_timestamp > last_uop_timestamp) + last_uop_timestamp = decode_timestamp; - /*Submit uops to execution units, and determine the latest completion time*/ - for (c = 0; c < decode_buffer.nr_uops; c++) { - int start_timestamp; + /*Submit uops to execution units, and determine the latest completion time*/ + for (c = 0; c < decode_buffer.nr_uops; c++) { + int start_timestamp; - if (decode_buffer.earliest_start[c] == -1) - start_timestamp = last_uop_timestamp; - else - start_timestamp = decode_buffer.earliest_start[c]; + if (decode_buffer.earliest_start[c] == -1) + start_timestamp = last_uop_timestamp; + else + start_timestamp = decode_buffer.earliest_start[c]; - last_uop_timestamp = uop_run(decode_buffer.uops[c], start_timestamp); - if (last_uop_timestamp > uop_timestamp) - uop_timestamp = last_uop_timestamp; - } + last_uop_timestamp = uop_run(decode_buffer.uops[c], start_timestamp); + if (last_uop_timestamp > uop_timestamp) + uop_timestamp = last_uop_timestamp; + } - /*Calculate opquad completion time. Since opquads complete in order, it + /*Calculate opquad completion time. Since opquads complete in order, it must be after the last completion.*/ - if (uop_timestamp <= last_complete_timestamp) - last_complete_timestamp = last_complete_timestamp + 1; - else - last_complete_timestamp = uop_timestamp; + if (uop_timestamp <= last_complete_timestamp) + last_complete_timestamp = last_complete_timestamp + 1; + else + last_complete_timestamp = uop_timestamp; - /*Advance to next opquad in buffer*/ - opquad_completion_timestamp[next_opquad] = last_complete_timestamp; - next_opquad++; - if (next_opquad == NR_OPQUADS) - next_opquad = 0; + /*Advance to next opquad in buffer*/ + opquad_completion_timestamp[next_opquad] = last_complete_timestamp; + next_opquad++; + if (next_opquad == NR_OPQUADS) + next_opquad = 0; - decode_timestamp++; - decode_buffer.nr_uops = 0; + decode_timestamp++; + decode_buffer.nr_uops = 0; } /*The instruction is only of interest here if it's longer than 7 bytes, as that's the limit on K6 short decoding*/ static int codegen_timing_instr_length(uint64_t deps, uint32_t fetchdat, int op_32) { - int len = prefixes + 1; /*Opcode*/ - if (deps & MODRM) { - len++; /*ModR/M*/ - if (deps & HAS_IMM8) - len++; - if (deps & HAS_IMM1632) - len += (op_32 & 0x100) ? 4 : 2; + int len = prefixes + 1; /*Opcode*/ + if (deps & MODRM) { + len++; /*ModR/M*/ + if (deps & HAS_IMM8) + len++; + if (deps & HAS_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; - } - } + 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; + return len; } static void decode_instruction(const risc86_instruction_t *ins, uint64_t deps, uint32_t fetchdat, int op_32, int bit8) { - uint32_t regmask_required; - uint32_t regmask_modified; - int c, d; - int earliest_start = 0; - decode_type_t decode_type = ins->decode_type; - int instr_length = codegen_timing_instr_length(deps, fetchdat, op_32); + uint32_t regmask_required; + uint32_t regmask_modified; + int c, d; + int earliest_start = 0; + decode_type_t decode_type = ins->decode_type; + int instr_length = codegen_timing_instr_length(deps, fetchdat, op_32); - /*Generate input register mask, and determine the earliest time this + /*Generate input register mask, and determine the earliest time this instruction can start. This is not accurate, as this is calculated per x86 instruction when it should be handled per uop*/ - regmask_required = get_dstdep_mask(deps, fetchdat, bit8); - regmask_required |= get_addr_regmask(deps, fetchdat, op_32); - for (c = 0; c < 8; c++) { - if (regmask_required & (1 << c)) { - if (reg_available_timestamp[c] > decode_timestamp) - earliest_start = reg_available_timestamp[c]; - } - } - if ((deps & FPU_RW_ST0) && fpu_st_timestamp[0] > decode_timestamp) - earliest_start = fpu_st_timestamp[0]; - if ((deps & FPU_RW_ST1) && fpu_st_timestamp[1] > decode_timestamp) - earliest_start = fpu_st_timestamp[1]; - if ((deps & FPU_RW_STREG)) { - int reg = fetchdat & 7; + regmask_required = get_dstdep_mask(deps, fetchdat, bit8); + regmask_required |= get_addr_regmask(deps, fetchdat, op_32); + for (c = 0; c < 8; c++) { + if (regmask_required & (1 << c)) { + if (reg_available_timestamp[c] > decode_timestamp) + earliest_start = reg_available_timestamp[c]; + } + } + if ((deps & FPU_RW_ST0) && fpu_st_timestamp[0] > decode_timestamp) + earliest_start = fpu_st_timestamp[0]; + if ((deps & FPU_RW_ST1) && fpu_st_timestamp[1] > decode_timestamp) + earliest_start = fpu_st_timestamp[1]; + if ((deps & FPU_RW_STREG)) { + int reg = fetchdat & 7; - if (fpu_st_timestamp[reg] > decode_timestamp) - earliest_start = fpu_st_timestamp[reg]; - } + if (fpu_st_timestamp[reg] > decode_timestamp) + earliest_start = fpu_st_timestamp[reg]; + } - /*Short decoders are limited to 7 bytes*/ - if (decode_type == DECODE_SHORT && instr_length > 7) - decode_type = DECODE_LONG; - /*Long decoder is limited to 11 bytes*/ - else if (instr_length > 11) - decode_type = DECODE_VECTOR; + /*Short decoders are limited to 7 bytes*/ + if (decode_type == DECODE_SHORT && instr_length > 7) + decode_type = DECODE_LONG; + /*Long decoder is limited to 11 bytes*/ + else if (instr_length > 11) + decode_type = DECODE_VECTOR; - switch (decode_type) { - case DECODE_SHORT: - if (decode_buffer.nr_uops) { - decode_buffer.uops[decode_buffer.nr_uops] = &ins->uop[0]; - decode_buffer.earliest_start[decode_buffer.nr_uops] = earliest_start; - if (ins->nr_uops > 1) { - decode_buffer.uops[decode_buffer.nr_uops + 1] = &ins->uop[1]; - decode_buffer.earliest_start[decode_buffer.nr_uops + 1] = -1; - } - decode_buffer.nr_uops += ins->nr_uops; + switch (decode_type) { + case DECODE_SHORT: + if (decode_buffer.nr_uops) { + decode_buffer.uops[decode_buffer.nr_uops] = &ins->uop[0]; + decode_buffer.earliest_start[decode_buffer.nr_uops] = earliest_start; + if (ins->nr_uops > 1) { + decode_buffer.uops[decode_buffer.nr_uops + 1] = &ins->uop[1]; + decode_buffer.earliest_start[decode_buffer.nr_uops + 1] = -1; + } + decode_buffer.nr_uops += ins->nr_uops; - decode_flush(); - } else { - decode_buffer.nr_uops = ins->nr_uops; - decode_buffer.uops[0] = &ins->uop[0]; - decode_buffer.earliest_start[0] = earliest_start; - if (ins->nr_uops > 1) { - decode_buffer.uops[1] = &ins->uop[1]; - decode_buffer.earliest_start[1] = -1; - } - } - break; + decode_flush(); + } else { + decode_buffer.nr_uops = ins->nr_uops; + decode_buffer.uops[0] = &ins->uop[0]; + decode_buffer.earliest_start[0] = earliest_start; + if (ins->nr_uops > 1) { + decode_buffer.uops[1] = &ins->uop[1]; + decode_buffer.earliest_start[1] = -1; + } + } + break; - case DECODE_LONG: - if (decode_buffer.nr_uops) - decode_flush(); + case DECODE_LONG: + if (decode_buffer.nr_uops) + decode_flush(); - decode_buffer.nr_uops = ins->nr_uops; - for (c = 0; c < ins->nr_uops; c++) { - decode_buffer.uops[c] = &ins->uop[c]; - if (c == 0) - decode_buffer.earliest_start[c] = earliest_start; - else - decode_buffer.earliest_start[c] = -1; - } - decode_flush(); - break; + decode_buffer.nr_uops = ins->nr_uops; + for (c = 0; c < ins->nr_uops; c++) { + decode_buffer.uops[c] = &ins->uop[c]; + if (c == 0) + decode_buffer.earliest_start[c] = earliest_start; + else + decode_buffer.earliest_start[c] = -1; + } + decode_flush(); + break; - case DECODE_VECTOR: - if (decode_buffer.nr_uops) - decode_flush(); + case DECODE_VECTOR: + if (decode_buffer.nr_uops) + decode_flush(); - decode_timestamp++; - d = 0; + decode_timestamp++; + d = 0; - for (c = 0; c < ins->nr_uops; c++) { - decode_buffer.uops[d] = &ins->uop[c]; - if (c == 0) - decode_buffer.earliest_start[d] = earliest_start; - else - decode_buffer.earliest_start[d] = -1; - d++; + for (c = 0; c < ins->nr_uops; c++) { + decode_buffer.uops[d] = &ins->uop[c]; + if (c == 0) + decode_buffer.earliest_start[d] = earliest_start; + else + decode_buffer.earliest_start[d] = -1; + d++; - if (d == 4) { - d = 0; - decode_buffer.nr_uops = 4; - decode_flush(); - } - } - if (d) { - decode_buffer.nr_uops = d; - decode_flush(); - } - break; - } + if (d == 4) { + d = 0; + decode_buffer.nr_uops = 4; + decode_flush(); + } + } + if (d) { + decode_buffer.nr_uops = d; + decode_flush(); + } + break; + } - /*Update write timestamps for any output registers*/ - regmask_modified = get_dstdep_mask(deps, fetchdat, bit8); - for (c = 0; c < 8; c++) { - if (regmask_modified & (1 << c)) - reg_available_timestamp[c] = last_complete_timestamp; - } - if (deps & FPU_POP) { - for (c = 0; c < 7; c++) - fpu_st_timestamp[c] = fpu_st_timestamp[c + 1]; - fpu_st_timestamp[7] = 0; - } - if (deps & FPU_POP2) { - for (c = 0; c < 6; c++) - fpu_st_timestamp[c] = fpu_st_timestamp[c + 2]; - fpu_st_timestamp[6] = fpu_st_timestamp[7] = 0; - } - if (deps & FPU_PUSH) { - for (c = 0; c < 7; c++) - fpu_st_timestamp[c + 1] = fpu_st_timestamp[c]; - fpu_st_timestamp[0] = 0; - } - if (deps & FPU_WRITE_ST0) - fpu_st_timestamp[0] = last_complete_timestamp; - if (deps & FPU_WRITE_ST1) - fpu_st_timestamp[1] = last_complete_timestamp; - if (deps & FPU_WRITE_STREG) { - int reg = fetchdat & 7; - if (deps & FPU_POP) - reg--; - if (reg >= 0 && - !(reg == 0 && (deps & FPU_WRITE_ST0)) && - !(reg == 1 && (deps & FPU_WRITE_ST1))) - fpu_st_timestamp[reg] = last_complete_timestamp; - } + /*Update write timestamps for any output registers*/ + regmask_modified = get_dstdep_mask(deps, fetchdat, bit8); + for (c = 0; c < 8; c++) { + if (regmask_modified & (1 << c)) + reg_available_timestamp[c] = last_complete_timestamp; + } + if (deps & FPU_POP) { + for (c = 0; c < 7; c++) + fpu_st_timestamp[c] = fpu_st_timestamp[c + 1]; + fpu_st_timestamp[7] = 0; + } + if (deps & FPU_POP2) { + for (c = 0; c < 6; c++) + fpu_st_timestamp[c] = fpu_st_timestamp[c + 2]; + fpu_st_timestamp[6] = fpu_st_timestamp[7] = 0; + } + if (deps & FPU_PUSH) { + for (c = 0; c < 7; c++) + fpu_st_timestamp[c + 1] = fpu_st_timestamp[c]; + fpu_st_timestamp[0] = 0; + } + if (deps & FPU_WRITE_ST0) + fpu_st_timestamp[0] = last_complete_timestamp; + if (deps & FPU_WRITE_ST1) + fpu_st_timestamp[1] = last_complete_timestamp; + if (deps & FPU_WRITE_STREG) { + int reg = fetchdat & 7; + if (deps & FPU_POP) + reg--; + if (reg >= 0 && !(reg == 0 && (deps & FPU_WRITE_ST0)) && !(reg == 1 && (deps & FPU_WRITE_ST1))) + fpu_st_timestamp[reg] = last_complete_timestamp; + } } void codegen_timing_k6_block_start() { - int c; + int c; - for (c = 0; c < nr_units; c++) - units[c].first_available_cycle = 0; + for (c = 0; c < nr_units; c++) + units[c].first_available_cycle = 0; - mul_first_available_cycle = 0; - shift_first_available_cycle = 0; - m3dnow_first_available_cycle = 0; + mul_first_available_cycle = 0; + shift_first_available_cycle = 0; + m3dnow_first_available_cycle = 0; - decode_timestamp = 0; - last_complete_timestamp = 0; + decode_timestamp = 0; + last_complete_timestamp = 0; - for (c = 0; c < NR_OPQUADS; c++) - opquad_completion_timestamp[c] = 0; - next_opquad = 0; + for (c = 0; c < NR_OPQUADS; c++) + opquad_completion_timestamp[c] = 0; + next_opquad = 0; - for (c = 0; c < NR_REGS; c++) - reg_available_timestamp[c] = 0; - for (c = 0; c < 8; c++) - fpu_st_timestamp[c] = 0; + for (c = 0; c < NR_REGS; c++) + reg_available_timestamp[c] = 0; + for (c = 0; c < 8; c++) + fpu_st_timestamp[c] = 0; } void codegen_timing_k6_start() { - if (models[model]->cpu[cpu_manufacturer].cpus[cpu].cpu_type == CPU_K6) { - units = k6_units; - nr_units = NR_K6_UNITS; - } else { - units = k6_2_units; - nr_units = NR_K6_2_UNITS; - } - last_prefix = 0; - prefixes = 0; + if (models[model]->cpu[cpu_manufacturer].cpus[cpu].cpu_type == CPU_K6) { + units = k6_units; + nr_units = NR_K6_UNITS; + } else { + units = k6_2_units; + nr_units = NR_K6_2_UNITS; + } + last_prefix = 0; + prefixes = 0; } void codegen_timing_k6_prefix(uint8_t prefix, uint32_t fetchdat) { - if (prefix != 0x0f) - decode_timestamp++; + if (prefix != 0x0f) + decode_timestamp++; - last_prefix = prefix; - prefixes++; + last_prefix = prefix; + prefixes++; } void codegen_timing_k6_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc) { - const risc86_instruction_t **ins_table; - uint64_t *deps; - int mod3 = ((fetchdat & 0xc0) == 0xc0); - int old_last_complete_timestamp = last_complete_timestamp; - int bit8 = !(opcode & 1); + const risc86_instruction_t **ins_table; + uint64_t *deps; + int mod3 = ((fetchdat & 0xc0) == 0xc0); + int old_last_complete_timestamp = last_complete_timestamp; + int bit8 = !(opcode & 1); - switch (last_prefix) { - case 0x0f: - if (opcode == 0x0f) { - /*3DNow has the actual opcode after ModR/M, SIB and any offset*/ - uint32_t opcode_pc = op_pc + 1; /*Byte after ModR/M*/ - uint8_t modrm = fetchdat & 0xff; - uint8_t sib = (fetchdat >> 8) & 0xff; + switch (last_prefix) { + case 0x0f: + if (opcode == 0x0f) { + /*3DNow has the actual opcode after ModR/M, SIB and any offset*/ + uint32_t opcode_pc = op_pc + 1; /*Byte after ModR/M*/ + uint8_t modrm = fetchdat & 0xff; + uint8_t sib = (fetchdat >> 8) & 0xff; - if ((modrm & 0xc0) != 0xc0) { - if (op_32 & 0x200) { - if ((modrm & 7) == 4) { - /* Has SIB*/ - opcode_pc++; - if ((modrm & 0xc0) == 0x40) - opcode_pc++; - else if ((modrm & 0xc0) == 0x80) - opcode_pc += 4; - else if ((sib & 0x07) == 0x05) - opcode_pc += 4; - } else { - if ((modrm & 0xc0) == 0x40) - opcode_pc++; - else if ((modrm & 0xc0) == 0x80) - opcode_pc += 4; - else if ((modrm & 0xc7) == 0x05) - opcode_pc += 4; - } - } else { - if ((modrm & 0xc0) == 0x40) - opcode_pc++; - else if ((modrm & 0xc0) == 0x80) - opcode_pc += 2; - else if ((modrm & 0xc7) == 0x06) - opcode_pc += 2; - } - } + if ((modrm & 0xc0) != 0xc0) { + if (op_32 & 0x200) { + if ((modrm & 7) == 4) { + /* Has SIB*/ + opcode_pc++; + if ((modrm & 0xc0) == 0x40) + opcode_pc++; + else if ((modrm & 0xc0) == 0x80) + opcode_pc += 4; + else if ((sib & 0x07) == 0x05) + opcode_pc += 4; + } else { + if ((modrm & 0xc0) == 0x40) + opcode_pc++; + else if ((modrm & 0xc0) == 0x80) + opcode_pc += 4; + else if ((modrm & 0xc7) == 0x05) + opcode_pc += 4; + } + } else { + if ((modrm & 0xc0) == 0x40) + opcode_pc++; + else if ((modrm & 0xc0) == 0x80) + opcode_pc += 2; + else if ((modrm & 0xc7) == 0x06) + opcode_pc += 2; + } + } - opcode = fastreadb(cs + opcode_pc); + opcode = fastreadb(cs + opcode_pc); - ins_table = mod3 ? opcode_timings_0f0f_mod3 : opcode_timings_0f0f; - deps = mod3 ? opcode_deps_0f0f_mod3 : opcode_deps_0f0f; - } else { - ins_table = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; - deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; - } -// pclog("timings 0f\n"); - break; + ins_table = mod3 ? opcode_timings_0f0f_mod3 : opcode_timings_0f0f; + deps = mod3 ? opcode_deps_0f0f_mod3 : opcode_deps_0f0f; + } else { + ins_table = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; + deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; + } + // pclog("timings 0f\n"); + break; - case 0xd8:ins_table = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8; - deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8; - opcode = (opcode >> 3) & 7; -// pclog("timings d8\n"); - break; - case 0xd9:ins_table = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9; - deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9; - opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; -// pclog("timings d9\n"); - break; - case 0xda:ins_table = mod3 ? opcode_timings_da_mod3 : opcode_timings_da; - deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da; - opcode = (opcode >> 3) & 7; -// pclog("timings da\n"); - break; - case 0xdb:ins_table = mod3 ? opcode_timings_db_mod3 : opcode_timings_db; - deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db; - opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; -// pclog("timings db\n"); - break; - case 0xdc:ins_table = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc; - deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc; - opcode = (opcode >> 3) & 7; -// pclog("timings dc\n"); - break; - case 0xdd:ins_table = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd; - deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd; - opcode = (opcode >> 3) & 7; -// pclog("timings dd\n"); - break; - case 0xde:ins_table = mod3 ? opcode_timings_de_mod3 : opcode_timings_de; - deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de; - opcode = (opcode >> 3) & 7; -// pclog("timings de\n"); - break; - case 0xdf:ins_table = mod3 ? opcode_timings_df_mod3 : opcode_timings_df; - deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df; - opcode = (opcode >> 3) & 7; -// pclog("timings df\n"); - break; + case 0xd8: + ins_table = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8; + deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8; + opcode = (opcode >> 3) & 7; + // pclog("timings d8\n"); + break; + case 0xd9: + ins_table = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9; + deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9; + opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; + // pclog("timings d9\n"); + break; + case 0xda: + ins_table = mod3 ? opcode_timings_da_mod3 : opcode_timings_da; + deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da; + opcode = (opcode >> 3) & 7; + // pclog("timings da\n"); + break; + case 0xdb: + ins_table = mod3 ? opcode_timings_db_mod3 : opcode_timings_db; + deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db; + opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; + // pclog("timings db\n"); + break; + case 0xdc: + ins_table = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc; + deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc; + opcode = (opcode >> 3) & 7; + // pclog("timings dc\n"); + break; + case 0xdd: + ins_table = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd; + deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd; + opcode = (opcode >> 3) & 7; + // pclog("timings dd\n"); + break; + case 0xde: + ins_table = mod3 ? opcode_timings_de_mod3 : opcode_timings_de; + deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de; + opcode = (opcode >> 3) & 7; + // pclog("timings de\n"); + break; + case 0xdf: + ins_table = mod3 ? opcode_timings_df_mod3 : opcode_timings_df; + deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df; + opcode = (opcode >> 3) & 7; + // pclog("timings df\n"); + break; - default: - switch (opcode) { - case 0x80: - case 0x82:ins_table = mod3 ? opcode_timings_80_mod3 : opcode_timings_80; - deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x; - opcode = (fetchdat >> 3) & 7; -// pclog("timings 80 %p %p %p\n", (void *)timings, (void *)opcode_timings_mod3, (void *)opcode_timings_8x); - break; - case 0x81: - case 0x83:ins_table = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x; - deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x; - opcode = (fetchdat >> 3) & 7; -// pclog("timings 80 %p %p %p\n", (void *)timings, (void *)opcode_timings_mod3, (void *)opcode_timings_8x); - break; + default: + switch (opcode) { + case 0x80: + case 0x82: + ins_table = mod3 ? opcode_timings_80_mod3 : opcode_timings_80; + deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x; + opcode = (fetchdat >> 3) & 7; + // pclog("timings 80 %p %p %p\n", (void *)timings, (void *)opcode_timings_mod3, + // (void *)opcode_timings_8x); + break; + case 0x81: + case 0x83: + ins_table = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x; + deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x; + opcode = (fetchdat >> 3) & 7; + // pclog("timings 80 %p %p %p\n", (void *)timings, (void *)opcode_timings_mod3, + // (void *)opcode_timings_8x); + break; - case 0xc0: - case 0xd0: - case 0xd2:ins_table = mod3 ? opcode_timings_shift_b_mod3 : opcode_timings_shift_b; - deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; - opcode = (fetchdat >> 3) & 7; -// pclog("timings c0\n"); - break; + case 0xc0: + case 0xd0: + case 0xd2: + ins_table = mod3 ? opcode_timings_shift_b_mod3 : opcode_timings_shift_b; + deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; + opcode = (fetchdat >> 3) & 7; + // pclog("timings c0\n"); + break; - case 0xc1: - case 0xd1: - case 0xd3:ins_table = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; - deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; - opcode = (fetchdat >> 3) & 7; -// pclog("timings c1\n"); - break; + case 0xc1: + case 0xd1: + case 0xd3: + ins_table = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; + deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; + opcode = (fetchdat >> 3) & 7; + // pclog("timings c1\n"); + break; - case 0xf6:ins_table = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6; - deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6; - opcode = (fetchdat >> 3) & 7; -// pclog("timings f6\n"); - break; - case 0xf7:ins_table = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7; - deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7; - opcode = (fetchdat >> 3) & 7; -// pclog("timings f7\n"); - break; - case 0xff:ins_table = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff; - deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff; - opcode = (fetchdat >> 3) & 7; -// pclog("timings ff\n"); - break; + case 0xf6: + ins_table = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6; + deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6; + opcode = (fetchdat >> 3) & 7; + // pclog("timings f6\n"); + break; + case 0xf7: + ins_table = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7; + deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7; + opcode = (fetchdat >> 3) & 7; + // pclog("timings f7\n"); + break; + case 0xff: + ins_table = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff; + deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff; + opcode = (fetchdat >> 3) & 7; + // pclog("timings ff\n"); + break; - default:ins_table = mod3 ? opcode_timings_mod3 : opcode_timings; - deps = mod3 ? opcode_deps_mod3 : opcode_deps; -// pclog("timings normal\n"); - break; - } - } + default: + ins_table = mod3 ? opcode_timings_mod3 : opcode_timings; + deps = mod3 ? opcode_deps_mod3 : opcode_deps; + // pclog("timings normal\n"); + break; + } + } - if (ins_table[opcode]) - decode_instruction(ins_table[opcode], deps[opcode], fetchdat, op_32, bit8); - else - decode_instruction(&vector_alu1_op, 0, fetchdat, op_32, bit8); - codegen_block_cycles += (last_complete_timestamp - old_last_complete_timestamp); + if (ins_table[opcode]) + decode_instruction(ins_table[opcode], deps[opcode], fetchdat, op_32, bit8); + else + decode_instruction(&vector_alu1_op, 0, fetchdat, op_32, bit8); + codegen_block_cycles += (last_complete_timestamp - old_last_complete_timestamp); } void codegen_timing_k6_block_end() { - if (decode_buffer.nr_uops) { - int old_last_complete_timestamp = last_complete_timestamp; - decode_flush(); - codegen_block_cycles += (last_complete_timestamp - old_last_complete_timestamp); - } + if (decode_buffer.nr_uops) { + int old_last_complete_timestamp = last_complete_timestamp; + decode_flush(); + codegen_block_cycles += (last_complete_timestamp - old_last_complete_timestamp); + } } int codegen_timing_k6_jump_cycles() { - if (decode_buffer.nr_uops) - return 1; - return 0; + if (decode_buffer.nr_uops) + return 1; + return 0; } -codegen_timing_t codegen_timing_k6 = - { - codegen_timing_k6_start, - codegen_timing_k6_prefix, - codegen_timing_k6_opcode, - codegen_timing_k6_block_start, - codegen_timing_k6_block_end, - codegen_timing_k6_jump_cycles - }; +codegen_timing_t codegen_timing_k6 = {codegen_timing_k6_start, codegen_timing_k6_prefix, codegen_timing_k6_opcode, + codegen_timing_k6_block_start, codegen_timing_k6_block_end, codegen_timing_k6_jump_cycles}; diff --git a/src/codegen/codegen_timing_p6.c b/src/codegen/codegen_timing_p6.c index 949c10f6..aa7e9744 100644 --- a/src/codegen/codegen_timing_p6.c +++ b/src/codegen/codegen_timing_p6.c @@ -11,550 +11,323 @@ #include "codegen_timing_common.h" typedef enum uop_type_t { - UOP_ALU0 = 0, /*Executes in port 0 ALU*/ - UOP_ALU1, /*Executes in port 1 ALU*/ - UOP_ALU01, /*Executes in either port 0 or 1 ALU*/ - UOP_BRANCH, /*Executes in port 1 branch*/ - UOP_LOAD, /*Executes in port 2 Load unit*/ - UOP_STOREADDR, /*Executes in port 3 Store Address unit*/ - UOP_STOREDATA, /*Executes in port 4 Store Data unit*/ - UOP_FLOAT, /*Executes in port 0 Floating Point unit*/ - UOP_ALU0_SEG /*Executes in port 0 ALU, loads segment, causing pipeline flush on PPro*/ + UOP_ALU0 = 0, /*Executes in port 0 ALU*/ + UOP_ALU1, /*Executes in port 1 ALU*/ + UOP_ALU01, /*Executes in either port 0 or 1 ALU*/ + UOP_BRANCH, /*Executes in port 1 branch*/ + UOP_LOAD, /*Executes in port 2 Load unit*/ + UOP_STOREADDR, /*Executes in port 3 Store Address unit*/ + UOP_STOREDATA, /*Executes in port 4 Store Data unit*/ + UOP_FLOAT, /*Executes in port 0 Floating Point unit*/ + UOP_ALU0_SEG /*Executes in port 0 ALU, loads segment, causing pipeline flush on PPro*/ } uop_type_t; #define MAX_UOPS 300 typedef struct p6_uop_t { - uop_type_t type; - int throughput; - int latency; + uop_type_t type; + int throughput; + int latency; } p6_uop_t; typedef struct p6_instruction_t { - int nr_uops; - p6_uop_t uop[MAX_UOPS]; + int nr_uops; + p6_uop_t uop[MAX_UOPS]; } p6_instruction_t; -static const p6_instruction_t alu_op = - { - .nr_uops = 1, - .uop[0] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} - }; -static const p6_instruction_t alu0_op = - { - .nr_uops = 1, - .uop[0] = {.type = UOP_ALU0, .throughput = 1, .latency = 1} - }; -static const p6_instruction_t alu1_op = - { - .nr_uops = 1, - .uop[0] = {.type = UOP_ALU1, .throughput = 1, .latency = 1} - }; -static const p6_instruction_t alu01_op = - { - .nr_uops = 1, - .uop[0] = {.type = UOP_ALU0, .throughput = 1, .latency = 1} - }; -static const p6_instruction_t alu4_op = - { - .nr_uops = 4, - .uop[0] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} - }; -static const p6_instruction_t alu6_op = - { - .nr_uops = 6, - .uop[0] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[4] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[5] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} - }; -static const p6_instruction_t aluc_op = - { - .nr_uops = 2, - .uop[0] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[0] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} - }; -static const p6_instruction_t load_alu_op = - { - .nr_uops = 2, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} - }; -static const p6_instruction_t load_aluc_op = - { - .nr_uops = 3, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} - }; -static const p6_instruction_t alu_store_op = - { - .nr_uops = 4, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1} - }; -static const p6_instruction_t alu0_store_op = - { - .nr_uops = 4, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1} - }; -static const p6_instruction_t aluc_store_op = - { - .nr_uops = 6, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[4] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, - .uop[5] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1} - }; +static const p6_instruction_t alu_op = {.nr_uops = 1, .uop[0] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}}; +static const p6_instruction_t alu0_op = {.nr_uops = 1, .uop[0] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}}; +static const p6_instruction_t alu1_op = {.nr_uops = 1, .uop[0] = {.type = UOP_ALU1, .throughput = 1, .latency = 1}}; +static const p6_instruction_t alu01_op = {.nr_uops = 1, .uop[0] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}}; +static const p6_instruction_t alu4_op = {.nr_uops = 4, + .uop[0] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}}; +static const p6_instruction_t alu6_op = {.nr_uops = 6, + .uop[0] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[5] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}}; +static const p6_instruction_t aluc_op = {.nr_uops = 2, + .uop[0] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[0] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}}; +static const p6_instruction_t load_alu_op = {.nr_uops = 2, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}}; +static const p6_instruction_t load_aluc_op = {.nr_uops = 3, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}}; +static const p6_instruction_t alu_store_op = {.nr_uops = 4, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}}; +static const p6_instruction_t alu0_store_op = {.nr_uops = 4, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}}; +static const p6_instruction_t aluc_store_op = {.nr_uops = 6, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[5] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}}; -static const p6_instruction_t branch_op = - { - .nr_uops = 1, - .uop[0] = {.type = UOP_BRANCH, .throughput = 1, .latency = 1} - }; +static const p6_instruction_t branch_op = {.nr_uops = 1, .uop[0] = {.type = UOP_BRANCH, .throughput = 1, .latency = 1}}; -static const p6_instruction_t load_op = - { - .nr_uops = 1, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2} - }; +static const p6_instruction_t load_op = {.nr_uops = 1, .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}}; -static const p6_instruction_t store_op = - { - .nr_uops = 2, - .uop[0] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1} - }; +static const p6_instruction_t store_op = {.nr_uops = 2, + .uop[0] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}}; -static const p6_instruction_t bswap_op = - { - .nr_uops = 2, - .uop[0] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - .uop[0] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} - }; -static const p6_instruction_t leave_op = - { - .nr_uops = 3, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} - }; -static const p6_instruction_t lods_op = - { - .nr_uops = 2, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 1} - }; -static const p6_instruction_t loop_op = - { - .nr_uops = 11, - .uop[0] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU1, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[4] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[5] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[6] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[7] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[8] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[9] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[10] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - }; -static const p6_instruction_t movs_op = - { - .nr_uops = 6, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, - .uop[4] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, - .uop[5] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - }; -static const p6_instruction_t pop_reg_op = - { - .nr_uops = 2, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} - }; -static const p6_instruction_t pop_mem_op = - { - .nr_uops = 8, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[4] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[5] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, - .uop[6] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, - .uop[7] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} - }; -static const p6_instruction_t push_imm_op = - { - .nr_uops = 3, - .uop[0] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1} - }; -static const p6_instruction_t push_mem_op = - { - .nr_uops = 4, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, - }; -static const p6_instruction_t push_seg_op = - { - .nr_uops = 4, - .uop[0] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1} - }; -static const p6_instruction_t rcx_op = - { - .nr_uops = 8, - .uop[0] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - .uop[4] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[5] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - .uop[6] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[7] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - }; -static const p6_instruction_t rcx_store_op = - { - .nr_uops = 11, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[4] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - .uop[5] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[6] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - .uop[7] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[8] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - .uop[9] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, - .uop[10] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1} - }; -static const p6_instruction_t stos_op = - { - .nr_uops = 3, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1} - }; -static const p6_instruction_t xchg_op = - { - .nr_uops = 3, - .uop[0] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} - }; +static const p6_instruction_t bswap_op = {.nr_uops = 2, + .uop[0] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[0] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}}; +static const p6_instruction_t leave_op = {.nr_uops = 3, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}}; +static const p6_instruction_t lods_op = {.nr_uops = 2, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}}; +static const p6_instruction_t loop_op = { + .nr_uops = 11, + .uop[0] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU1, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[5] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[6] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[7] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[8] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[9] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[10] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, +}; +static const p6_instruction_t movs_op = { + .nr_uops = 6, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, + .uop[5] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, +}; +static const p6_instruction_t pop_reg_op = {.nr_uops = 2, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}}; +static const p6_instruction_t pop_mem_op = {.nr_uops = 8, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[5] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[6] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, + .uop[7] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}}; +static const p6_instruction_t push_imm_op = {.nr_uops = 3, + .uop[0] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}}; +static const p6_instruction_t push_mem_op = { + .nr_uops = 4, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, +}; +static const p6_instruction_t push_seg_op = {.nr_uops = 4, + .uop[0] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}}; +static const p6_instruction_t rcx_op = { + .nr_uops = 8, + .uop[0] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[5] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[6] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[7] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, +}; +static const p6_instruction_t rcx_store_op = {.nr_uops = 11, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[5] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[6] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[7] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[8] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[9] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[10] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}}; +static const p6_instruction_t stos_op = {.nr_uops = 3, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}}; +static const p6_instruction_t xchg_op = {.nr_uops = 3, + .uop[0] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}}; -static const p6_instruction_t mmx_op = - { - .nr_uops = 1, - .uop[0] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} - }; -static const p6_instruction_t mmx_mul_op = - { - .nr_uops = 1, - .uop[0] = {.type = UOP_ALU0, .throughput = 1, .latency = 3} - }; -static const p6_instruction_t mmx_shift_op = - { - .nr_uops = 1, - .uop[0] = {.type = UOP_ALU1, .throughput = 1, .latency = 1} - }; -static const p6_instruction_t load_mmx_op = - { - .nr_uops = 2, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} - }; -static const p6_instruction_t load_mmx_mul_op = - { - .nr_uops = 2, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU0, .throughput = 1, .latency = 1} - }; -static const p6_instruction_t load_mmx_shift_op = - { - .nr_uops = 2, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU1, .throughput = 1, .latency = 1} - }; +static const p6_instruction_t mmx_op = {.nr_uops = 1, .uop[0] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}}; +static const p6_instruction_t mmx_mul_op = {.nr_uops = 1, .uop[0] = {.type = UOP_ALU0, .throughput = 1, .latency = 3}}; +static const p6_instruction_t mmx_shift_op = {.nr_uops = 1, .uop[0] = {.type = UOP_ALU1, .throughput = 1, .latency = 1}}; +static const p6_instruction_t load_mmx_op = {.nr_uops = 2, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}}; +static const p6_instruction_t load_mmx_mul_op = {.nr_uops = 2, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}}; +static const p6_instruction_t load_mmx_shift_op = {.nr_uops = 2, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU1, .throughput = 1, .latency = 1}}; -static const p6_instruction_t faddsub_op = - { - .nr_uops = 1, - .uop[0] = {.type = UOP_FLOAT, .throughput = 1, .latency = 3} - }; -static const p6_instruction_t load_faddsub_op = - { - .nr_uops = 2, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_FLOAT, .throughput = 1, .latency = 3} - }; -static const p6_instruction_t fbstp_op = - { - .nr_uops = 5, - .uop[0] = {.type = UOP_FLOAT, .throughput = 165, .latency = 165}, - .uop[1] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, - .uop[4] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1} - }; -static const p6_instruction_t fcom_op = - { - .nr_uops = 1, - .uop[0] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1} - }; -static const p6_instruction_t load_fcom_op = - { - .nr_uops = 2, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1} - }; -static const p6_instruction_t fcompp_op = - { - .nr_uops = 1, - .uop[0] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} - }; -static const p6_instruction_t fild_op = - { - .nr_uops = 4, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1} - }; -static const p6_instruction_t load_fi_op = - { - .nr_uops = 7, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1}, - .uop[4] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1}, - .uop[5] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1}, - .uop[6] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1} - }; -static const p6_instruction_t fmul_op = - { - .nr_uops = 1, - .uop[0] = {.type = UOP_FLOAT, .throughput = 1, .latency = 5} - }; -static const p6_instruction_t load_fmul_op = - { - .nr_uops = 2, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_FLOAT, .throughput = 1, .latency = 5} - }; +static const p6_instruction_t faddsub_op = {.nr_uops = 1, .uop[0] = {.type = UOP_FLOAT, .throughput = 1, .latency = 3}}; +static const p6_instruction_t load_faddsub_op = {.nr_uops = 2, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_FLOAT, .throughput = 1, .latency = 3}}; +static const p6_instruction_t fbstp_op = {.nr_uops = 5, + .uop[0] = {.type = UOP_FLOAT, .throughput = 165, .latency = 165}, + .uop[1] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}}; +static const p6_instruction_t fcom_op = {.nr_uops = 1, .uop[0] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1}}; +static const p6_instruction_t load_fcom_op = {.nr_uops = 2, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1}}; +static const p6_instruction_t fcompp_op = {.nr_uops = 1, + .uop[0] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}}; +static const p6_instruction_t fild_op = {.nr_uops = 4, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1}}; +static const p6_instruction_t load_fi_op = {.nr_uops = 7, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1}, + .uop[5] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1}, + .uop[6] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1}}; +static const p6_instruction_t fmul_op = {.nr_uops = 1, .uop[0] = {.type = UOP_FLOAT, .throughput = 1, .latency = 5}}; +static const p6_instruction_t load_fmul_op = {.nr_uops = 2, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_FLOAT, .throughput = 1, .latency = 5}}; -static const p6_instruction_t fxch_op = - { - .nr_uops = 0 - }; +static const p6_instruction_t fxch_op = {.nr_uops = 0}; -static const p6_instruction_t fist_op = - { - .nr_uops = 4, - .uop[0] = {.type = UOP_FLOAT, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1} - }; +static const p6_instruction_t fist_op = {.nr_uops = 4, + .uop[0] = {.type = UOP_FLOAT, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}}; -static const p6_instruction_t fdiv_op = - { - .nr_uops = 1, - .uop[0] = {.type = UOP_FLOAT, .throughput = 37, .latency = 38} - }; -static const p6_instruction_t fdiv_mem_op = - { - .nr_uops = 2, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_FLOAT, .throughput = 37, .latency = 38} - }; -static const p6_instruction_t fsin_op = - { - .nr_uops = 1, - .uop[0] = {.type = UOP_FLOAT, .throughput = 62, .latency = 62} - }; -static const p6_instruction_t fsqrt_op = - { - .nr_uops = 1, - .uop[0] = {.type = UOP_FLOAT, .throughput = 69, .latency = 69} - }; +static const p6_instruction_t fdiv_op = {.nr_uops = 1, .uop[0] = {.type = UOP_FLOAT, .throughput = 37, .latency = 38}}; +static const p6_instruction_t fdiv_mem_op = {.nr_uops = 2, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_FLOAT, .throughput = 37, .latency = 38}}; +static const p6_instruction_t fsin_op = {.nr_uops = 1, .uop[0] = {.type = UOP_FLOAT, .throughput = 62, .latency = 62}}; +static const p6_instruction_t fsqrt_op = {.nr_uops = 1, .uop[0] = {.type = UOP_FLOAT, .throughput = 69, .latency = 69}}; -static const p6_instruction_t float_op = - { - .nr_uops = 1, - .uop[0] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1} - }; +static const p6_instruction_t float_op = {.nr_uops = 1, .uop[0] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1}}; -static const p6_instruction_t fldcw_op = - { - .nr_uops = 3, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_FLOAT, .throughput = 7, .latency = 7}, - }; -static const p6_instruction_t flde_op = - { - .nr_uops = 4, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[2] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1} - }; -static const p6_instruction_t frstor_op = - { - .nr_uops = 1, - .uop[0] = {.type = UOP_FLOAT, .throughput = 72, .latency = 72} - }; -static const p6_instruction_t fsave_op = - { - .nr_uops = 1, - .uop[0] = {.type = UOP_FLOAT, .throughput = 141, .latency = 141} - }; -static const p6_instruction_t fste_op = - { - .nr_uops = 6, - .uop[0] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, - .uop[4] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, - .uop[5] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1} - }; -static const p6_instruction_t fstsw_ax_op = - { - .nr_uops = 3, - .uop[0] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU0, .throughput = 1, .latency = 1} - }; -static const p6_instruction_t fstsw_mem_op = - { - .nr_uops = 3, - .uop[0] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1} - }; +static const p6_instruction_t fldcw_op = { + .nr_uops = 3, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_FLOAT, .throughput = 7, .latency = 7}, +}; +static const p6_instruction_t flde_op = {.nr_uops = 4, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[2] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1}}; +static const p6_instruction_t frstor_op = {.nr_uops = 1, .uop[0] = {.type = UOP_FLOAT, .throughput = 72, .latency = 72}}; +static const p6_instruction_t fsave_op = {.nr_uops = 1, .uop[0] = {.type = UOP_FLOAT, .throughput = 141, .latency = 141}}; +static const p6_instruction_t fste_op = {.nr_uops = 6, + .uop[0] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[5] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}}; +static const p6_instruction_t fstsw_ax_op = {.nr_uops = 3, + .uop[0] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}}; +static const p6_instruction_t fstsw_mem_op = {.nr_uops = 3, + .uop[0] = {.type = UOP_FLOAT, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}}; -static const p6_instruction_t aad_op = - { - .nr_uops = 3, - .uop[0] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_ALU0, .throughput = 1, .latency = 4}, - .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} - }; -static const p6_instruction_t aam_op = - { - .nr_uops = 3, - .uop[0] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_ALU0, .throughput = 1, .latency = 4}, - .uop[2] = {.type = UOP_ALU1, .throughput = 1, .latency = 9}, - .uop[3] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} - }; -static const p6_instruction_t arpl_op = - { - .nr_uops = 2, - .uop[0] = {.type = UOP_ALU01, .throughput = 3, .latency = 3}, - .uop[1] = {.type = UOP_ALU01, .throughput = 3, .latency = 3} - }; -static const p6_instruction_t bound_op = - { - .nr_uops = 4, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[2] = {.type = UOP_ALU0, .throughput = 7, .latency = 7}, - .uop[3] = {.type = UOP_ALU01, .throughput = 6, .latency = 6} - }; -static const p6_instruction_t bsx_op = - { - .nr_uops = 2, - .uop[0] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_ALU1, .throughput = 1, .latency = 1} - }; -static const p6_instruction_t load_bsx_op = - { - .nr_uops = 3, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU1, .throughput = 1, .latency = 1} - }; -static const p6_instruction_t call_far_op = - { - .nr_uops = 6, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, - .uop[4] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, - .uop[5] = {.type = UOP_ALU0_SEG, .throughput = 28, .latency = 28} - }; -static const p6_instruction_t load_call_far_op = - { - .nr_uops = 7, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[2] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, - .uop[4] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, - .uop[5] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, - .uop[6] = {.type = UOP_ALU0_SEG, .throughput = 28, .latency = 28} - }; -static const p6_instruction_t cli_op = - { - .nr_uops = 1, - .uop[0] = {.type = UOP_ALU01, .throughput = 9, .latency = 9} - }; -static const p6_instruction_t sti_op = - { - .nr_uops = 1, - .uop[0] = {.type = UOP_ALU01, .throughput = 17, .latency = 17} - }; -static const p6_instruction_t cmps_op = - { - .nr_uops = 6, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[4] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[5] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} - }; -static const p6_instruction_t cmpxchg_op = - { - .nr_uops = 4, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1} - }; -static const p6_instruction_t cpuid_op = - { - .nr_uops = 1, - .uop[0] = {.type = UOP_ALU0, .throughput = 48, .latency = 48} - }; +static const p6_instruction_t aad_op = {.nr_uops = 3, + .uop[0] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_ALU0, .throughput = 1, .latency = 4}, + .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}}; +static const p6_instruction_t aam_op = {.nr_uops = 3, + .uop[0] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_ALU0, .throughput = 1, .latency = 4}, + .uop[2] = {.type = UOP_ALU1, .throughput = 1, .latency = 9}, + .uop[3] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}}; +static const p6_instruction_t arpl_op = {.nr_uops = 2, + .uop[0] = {.type = UOP_ALU01, .throughput = 3, .latency = 3}, + .uop[1] = {.type = UOP_ALU01, .throughput = 3, .latency = 3}}; +static const p6_instruction_t bound_op = {.nr_uops = 4, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[2] = {.type = UOP_ALU0, .throughput = 7, .latency = 7}, + .uop[3] = {.type = UOP_ALU01, .throughput = 6, .latency = 6}}; +static const p6_instruction_t bsx_op = {.nr_uops = 2, + .uop[0] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_ALU1, .throughput = 1, .latency = 1}}; +static const p6_instruction_t load_bsx_op = {.nr_uops = 3, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU1, .throughput = 1, .latency = 1}}; +static const p6_instruction_t call_far_op = {.nr_uops = 6, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, + .uop[5] = {.type = UOP_ALU0_SEG, .throughput = 28, .latency = 28}}; +static const p6_instruction_t load_call_far_op = {.nr_uops = 7, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[2] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[5] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, + .uop[6] = {.type = UOP_ALU0_SEG, .throughput = 28, .latency = 28}}; +static const p6_instruction_t cli_op = {.nr_uops = 1, .uop[0] = {.type = UOP_ALU01, .throughput = 9, .latency = 9}}; +static const p6_instruction_t sti_op = {.nr_uops = 1, .uop[0] = {.type = UOP_ALU01, .throughput = 17, .latency = 17}}; +static const p6_instruction_t cmps_op = {.nr_uops = 6, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[5] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}}; +static const p6_instruction_t cmpxchg_op = {.nr_uops = 4, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}}; +static const p6_instruction_t cpuid_op = {.nr_uops = 1, .uop[0] = {.type = UOP_ALU0, .throughput = 48, .latency = 48}}; /*static const p6_instruction_t div8_op = { .nr_uops = 3, @@ -570,134 +343,94 @@ static const p6_instruction_t cpuid_op = .uop[1] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} };*/ -static const p6_instruction_t div16_op = - { - .nr_uops = 3, - .uop[0] = {.type = UOP_ALU0, .throughput = 21, .latency = 21}, - .uop[1] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} - }; -static const p6_instruction_t div16_mem_op = - { - .nr_uops = 4, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[0] = {.type = UOP_ALU0, .throughput = 21, .latency = 21}, - .uop[1] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} - }; -static const p6_instruction_t div32_op = - { - .nr_uops = 3, - .uop[0] = {.type = UOP_ALU0, .throughput = 35, .latency = 35}, - .uop[1] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} - }; -static const p6_instruction_t div32_mem_op = - { - .nr_uops = 4, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[0] = {.type = UOP_ALU0, .throughput = 35, .latency = 35}, - .uop[1] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} - }; -static const p6_instruction_t emms_op = - { - .nr_uops = 11, - .uop[0] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - .uop[4] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - .uop[5] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - .uop[6] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - .uop[7] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - .uop[8] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - .uop[9] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - .uop[10] = {.type = UOP_ALU0, .throughput = 1, .latency = 1} - }; -static const p6_instruction_t enter_op = - { - .nr_uops = 14, - .uop[0] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[4] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[5] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[6] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[7] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[8] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[9] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[10] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[11] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, - .uop[12] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, - .uop[13] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} - }; -static const p6_instruction_t io_op = - { - .nr_uops = 1, - .uop[0] = {.type = UOP_LOAD, .throughput = 18, .latency = 18} - }; -static const p6_instruction_t ins_op = - { - .nr_uops = 4, - .uop[0] = {.type = UOP_ALU0, .throughput = 18, .latency = 18}, - .uop[1] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} - }; -static const p6_instruction_t int_op = - { - .nr_uops = 7, - .uop[0] = {.type = UOP_ALU0, .throughput = 20, .latency = 20}, - .uop[1] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, - .uop[4] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, - .uop[5] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, - .uop[6] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, - }; -static const p6_instruction_t iret_op = - { - .nr_uops = 4, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[2] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[3] = {.type = UOP_ALU01, .throughput = 20, .latency = 20}, - }; -static const p6_instruction_t invd_op = - { - .nr_uops = 1, - .uop[0] = {.type = UOP_ALU01, .throughput = 1000, .latency = 1000} - }; -static const p6_instruction_t jmp_far_op = - { - .nr_uops = 2, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU0_SEG, .throughput = 21, .latency = 21} - }; -static const p6_instruction_t load_jmp_far_op = - { - .nr_uops = 3, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[2] = {.type = UOP_ALU0_SEG, .throughput = 21, .latency = 21} - }; -static const p6_instruction_t lss_op = - { - .nr_uops = 11, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[2] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[3] = {.type = UOP_ALU0_SEG, .throughput = 1, .latency = 1}, - .uop[4] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[5] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[6] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[7] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[8] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[9] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[10] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} - }; +static const p6_instruction_t div16_op = {.nr_uops = 3, + .uop[0] = {.type = UOP_ALU0, .throughput = 21, .latency = 21}, + .uop[1] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}}; +static const p6_instruction_t div16_mem_op = {.nr_uops = 4, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[0] = {.type = UOP_ALU0, .throughput = 21, .latency = 21}, + .uop[1] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}}; +static const p6_instruction_t div32_op = {.nr_uops = 3, + .uop[0] = {.type = UOP_ALU0, .throughput = 35, .latency = 35}, + .uop[1] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}}; +static const p6_instruction_t div32_mem_op = {.nr_uops = 4, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[0] = {.type = UOP_ALU0, .throughput = 35, .latency = 35}, + .uop[1] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}}; +static const p6_instruction_t emms_op = {.nr_uops = 11, + .uop[0] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[5] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[6] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[7] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[8] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[9] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[10] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}}; +static const p6_instruction_t enter_op = {.nr_uops = 14, + .uop[0] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[5] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[6] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[7] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[8] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[9] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[10] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[11] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[12] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, + .uop[13] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}}; +static const p6_instruction_t io_op = {.nr_uops = 1, .uop[0] = {.type = UOP_LOAD, .throughput = 18, .latency = 18}}; +static const p6_instruction_t ins_op = {.nr_uops = 4, + .uop[0] = {.type = UOP_ALU0, .throughput = 18, .latency = 18}, + .uop[1] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}}; +static const p6_instruction_t int_op = { + .nr_uops = 7, + .uop[0] = {.type = UOP_ALU0, .throughput = 20, .latency = 20}, + .uop[1] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, + .uop[5] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[6] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, +}; +static const p6_instruction_t iret_op = { + .nr_uops = 4, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[2] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[3] = {.type = UOP_ALU01, .throughput = 20, .latency = 20}, +}; +static const p6_instruction_t invd_op = {.nr_uops = 1, .uop[0] = {.type = UOP_ALU01, .throughput = 1000, .latency = 1000}}; +static const p6_instruction_t jmp_far_op = {.nr_uops = 2, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU0_SEG, .throughput = 21, .latency = 21}}; +static const p6_instruction_t load_jmp_far_op = {.nr_uops = 3, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[2] = {.type = UOP_ALU0_SEG, .throughput = 21, .latency = 21}}; +static const p6_instruction_t lss_op = {.nr_uops = 11, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[2] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[3] = {.type = UOP_ALU0_SEG, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[5] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[6] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[7] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[8] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[9] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[10] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}}; /*static const p6_instruction_t mov_mem_seg_op = { .nr_uops = 3, @@ -705,847 +438,1229 @@ static const p6_instruction_t lss_op = .uop[1] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, .uop[2] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, };*/ -static const p6_instruction_t mov_seg_mem_op = - { - .nr_uops = 9, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU0_SEG, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - .uop[4] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - .uop[5] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - .uop[6] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - .uop[7] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - .uop[8] = {.type = UOP_ALU0, .throughput = 1, .latency = 1} - }; -static const p6_instruction_t mov_seg_reg_op = - { - .nr_uops = 8, - .uop[0] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_ALU0_SEG, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - .uop[4] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - .uop[5] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - .uop[6] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - .uop[7] = {.type = UOP_ALU0, .throughput = 1, .latency = 1} - }; -static const p6_instruction_t mul_op = - { - .nr_uops = 1, - .uop[0] = {.type = UOP_ALU0, .throughput = 1, .latency = 4} - }; -static const p6_instruction_t mul_mem_op = - { - .nr_uops = 2, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU0, .throughput = 1, .latency = 4} - }; -static const p6_instruction_t outs_op = - { - .nr_uops = 3, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_ALU0, .throughput = 18, .latency = 18}, - .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} - }; -static const p6_instruction_t pusha_op = - { - .nr_uops = 18, - .uop[0] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, - .uop[4] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, - .uop[5] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, - .uop[6] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, - .uop[7] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, - .uop[8] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, - .uop[9] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, - .uop[10] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, - .uop[11] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, - .uop[12] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, - .uop[13] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, - .uop[14] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, - .uop[15] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, - .uop[16] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[17] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} - }; -static const p6_instruction_t popa_op = - { - .nr_uops = 10, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, - .uop[4] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, - .uop[5] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, - .uop[6] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, - .uop[7] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, - .uop[8] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[9] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} - }; -static const p6_instruction_t popf_op = - { - .nr_uops = 17, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - .uop[4] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[5] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - .uop[6] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[7] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - .uop[8] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[9] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - .uop[10] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[11] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - .uop[12] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[13] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - .uop[14] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - .uop[15] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - .uop[16] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - }; -static const p6_instruction_t pushf_op = - { - .nr_uops = 16, - .uop[0] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - .uop[4] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[5] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - .uop[6] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[7] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - .uop[8] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[9] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - .uop[10] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[11] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - .uop[12] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - .uop[13] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, - .uop[14] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, - .uop[15] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1} - }; -static const p6_instruction_t ret_op = - { - .nr_uops = 4, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_ALU1, .throughput = 1, .latency = 1} - }; -static const p6_instruction_t reti_op = - { - .nr_uops = 5, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[4] = {.type = UOP_ALU1, .throughput = 1, .latency = 1} - }; -static const p6_instruction_t retf_op = - { - .nr_uops = 4, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[2] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[3] = {.type = UOP_ALU0, .throughput = 23, .latency = 23}, - }; -static const p6_instruction_t scas_op = - { - .nr_uops = 3, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, - .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} - }; -static const p6_instruction_t xchg_mem_op = - { - .nr_uops = 7, - .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[3] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[4] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, - .uop[5] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, - .uop[6] = {.type = UOP_ALU01, .throughput = 1, .latency = 1} - }; -static const p6_instruction_t xlat_op = - { - .nr_uops = 2, - .uop[0] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, - .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 2} - }; -static const p6_instruction_t wbinvd_op = - { - .nr_uops = 1, - .uop[0] = {.type = UOP_ALU0, .throughput = 10000, .latency = 10000} - }; +static const p6_instruction_t mov_seg_mem_op = {.nr_uops = 9, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU0_SEG, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[5] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[6] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[7] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[8] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}}; +static const p6_instruction_t mov_seg_reg_op = {.nr_uops = 8, + .uop[0] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_ALU0_SEG, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[5] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[6] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[7] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}}; +static const p6_instruction_t mul_op = {.nr_uops = 1, .uop[0] = {.type = UOP_ALU0, .throughput = 1, .latency = 4}}; +static const p6_instruction_t mul_mem_op = {.nr_uops = 2, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU0, .throughput = 1, .latency = 4}}; +static const p6_instruction_t outs_op = {.nr_uops = 3, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_ALU0, .throughput = 18, .latency = 18}, + .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}}; +static const p6_instruction_t pusha_op = {.nr_uops = 18, + .uop[0] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[5] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, + .uop[6] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[7] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, + .uop[8] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[9] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, + .uop[10] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[11] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, + .uop[12] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[13] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, + .uop[14] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[15] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, + .uop[16] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[17] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}}; +static const p6_instruction_t popa_op = {.nr_uops = 10, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[5] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[6] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[7] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[8] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[9] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}}; +static const p6_instruction_t popf_op = { + .nr_uops = 17, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[5] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[6] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[7] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[8] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[9] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[10] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[11] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[12] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[13] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[14] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[15] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[16] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, +}; +static const p6_instruction_t pushf_op = {.nr_uops = 16, + .uop[0] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[5] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[6] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[7] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[8] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[9] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[10] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[11] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[12] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[13] = {.type = UOP_ALU0, .throughput = 1, .latency = 1}, + .uop[14] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[15] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}}; +static const p6_instruction_t ret_op = {.nr_uops = 4, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_ALU1, .throughput = 1, .latency = 1}}; +static const p6_instruction_t reti_op = {.nr_uops = 5, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_ALU1, .throughput = 1, .latency = 1}}; +static const p6_instruction_t retf_op = { + .nr_uops = 4, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[2] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[3] = {.type = UOP_ALU0, .throughput = 23, .latency = 23}, +}; +static const p6_instruction_t scas_op = {.nr_uops = 3, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}, + .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}}; +static const p6_instruction_t xchg_mem_op = {.nr_uops = 7, + .uop[0] = {.type = UOP_LOAD, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[2] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[3] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[4] = {.type = UOP_STOREADDR, .throughput = 1, .latency = 1}, + .uop[5] = {.type = UOP_STOREDATA, .throughput = 1, .latency = 1}, + .uop[6] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}}; +static const p6_instruction_t xlat_op = {.nr_uops = 2, + .uop[0] = {.type = UOP_ALU01, .throughput = 1, .latency = 1}, + .uop[1] = {.type = UOP_LOAD, .throughput = 1, .latency = 2}}; +static const p6_instruction_t wbinvd_op = {.nr_uops = 1, .uop[0] = {.type = UOP_ALU0, .throughput = 10000, .latency = 10000}}; #define INVALID NULL -static const p6_instruction_t *opcode_timings[256] = - { -/* ADD ADD ADD ADD*/ -/*00*/ &alu_store_op, &alu_store_op, &load_alu_op, &load_alu_op, -/* ADD ADD PUSH ES POP ES*/ - &alu_op, &alu_op, &push_seg_op, &mov_seg_mem_op, -/* OR OR OR OR*/ - &alu_store_op, &alu_store_op, &load_alu_op, &load_alu_op, -/* OR OR PUSH CS */ - &alu_op, &alu_op, &push_seg_op, INVALID, - -/* ADC ADC ADC ADC*/ -/*10*/ &aluc_store_op, &aluc_store_op, &load_aluc_op, &load_aluc_op, -/* ADC ADC PUSH SS POP SS*/ - &aluc_op, &aluc_op, &push_seg_op, &mov_seg_mem_op, -/* SBB SBB SBB SBB*/ -/*10*/ &aluc_store_op, &aluc_store_op, &load_aluc_op, &load_aluc_op, -/* SBB SBB PUSH DS POP DS*/ - &aluc_op, &aluc_op, &push_seg_op, &mov_seg_mem_op, - -/* AND AND AND AND*/ -/*20*/ &alu_store_op, &alu_store_op, &load_alu_op, &load_alu_op, -/* AND AND DAA*/ - &alu_op, &alu_op, INVALID, &alu1_op, -/* SUB SUB SUB SUB*/ - &alu_store_op, &alu_store_op, &load_alu_op, &load_alu_op, -/* SUB SUB DAS*/ - &alu_op, &alu_op, INVALID, &alu1_op, - -/* XOR XOR XOR XOR*/ -/*30*/ &alu_store_op, &alu_store_op, &load_alu_op, &load_alu_op, -/* XOR XOR AAA*/ - &alu_op, &alu_op, INVALID, &alu1_op, -/* CMP CMP CMP CMP*/ - &load_alu_op, &load_alu_op, &load_alu_op, &load_alu_op, -/* CMP CMP AAS*/ - &alu_op, &alu_op, INVALID, &alu1_op, - -/* INC EAX INC ECX INC EDX INC EBX*/ -/*40*/ &alu_op, &alu_op, &alu_op, &alu_op, -/* INC ESP INC EBP INC ESI INC EDI*/ - &alu_op, &alu_op, &alu_op, &alu_op, -/* DEC EAX DEC ECX DEC EDX DEC EBX*/ - &alu_op, &alu_op, &alu_op, &alu_op, -/* DEC ESP DEC EBP DEC ESI DEC EDI*/ - &alu_op, &alu_op, &alu_op, &alu_op, - -/* PUSH EAX PUSH ECX PUSH EDX PUSH EBX*/ -/*50*/ &store_op, &store_op, &store_op, &store_op, -/* PUSH ESP PUSH EBP PUSH ESI PUSH EDI*/ - &store_op, &store_op, &store_op, &store_op, -/* POP EAX POP ECX POP EDX POP EBX*/ - &pop_reg_op, &pop_reg_op, &pop_reg_op, &pop_reg_op, -/* POP ESP POP EBP POP ESI POP EDI*/ - &pop_reg_op, &pop_reg_op, &pop_reg_op, &pop_reg_op, - -/* PUSHA POPA BOUND ARPL*/ -/*60*/ &pusha_op, &popa_op, &bound_op, &arpl_op, - INVALID, INVALID, INVALID, INVALID, -/* PUSH imm IMUL PUSH imm IMUL*/ - &push_imm_op, &mul_op, &push_imm_op, &mul_op, -/* INSB INSW OUTSB OUTSW*/ - &ins_op, &ins_op, &outs_op, &outs_op, - -/* Jxx*/ -/*70*/ &branch_op, &branch_op, &branch_op, &branch_op, - &branch_op, &branch_op, &branch_op, &branch_op, - &branch_op, &branch_op, &branch_op, &branch_op, - &branch_op, &branch_op, &branch_op, &branch_op, - -/*80*/ INVALID, INVALID, INVALID, INVALID, -/* TEST TEST XCHG XCHG*/ - &load_alu_op, &load_alu_op, &xchg_mem_op, &xchg_mem_op, -/* MOV MOV MOV MOV*/ - &store_op, &store_op, &load_op, &load_op, -/* MOV from seg LEA MOV to seg POP*/ - &store_op, &alu0_op, &mov_seg_mem_op, &pop_mem_op, - -/* NOP XCHG XCHG XCHG*/ -/*90*/ &alu_op, &xchg_op, &xchg_op, &xchg_op, -/* XCHG XCHG XCHG XCHG*/ - &xchg_op, &xchg_op, &xchg_op, &xchg_op, -/* CBW CWD CALL far WAIT*/ - &alu_op, &alu0_op, &call_far_op, &alu_op, -/* PUSHF POPF SAHF LAHF*/ - &pushf_op, &popf_op, &alu_op, &alu_op, - -/* MOV MOV MOV MOV*/ -/*a0*/ &load_op, &load_op, &store_op, &store_op, -/* MOVSB MOVSW CMPSB CMPSW*/ - &movs_op, &movs_op, &cmps_op, &cmps_op, -/* TEST TEST STOSB STOSW*/ - &load_alu_op, &load_alu_op, &stos_op, &stos_op, -/* LODSB LODSW SCASB SCASW*/ - &lods_op, &lods_op, &scas_op, &scas_op, - -/* MOV*/ -/*b0*/ &alu_op, &alu_op, &alu_op, &alu_op, - &alu_op, &alu_op, &alu_op, &alu_op, - &alu_op, &alu_op, &alu_op, &alu_op, - &alu_op, &alu_op, &alu_op, &alu_op, - -/* RET imm RET*/ -/*c0*/ INVALID, INVALID, &reti_op, &ret_op, -/* LES LDS MOV MOV*/ - &lss_op, &lss_op, &store_op, &store_op, -/* ENTER LEAVE RETF RETF*/ - &enter_op, &leave_op, &retf_op, &retf_op, -/* INT3 INT INTO IRET*/ - &int_op, &int_op, &int_op, &iret_op, - - -/*d0*/ INVALID, INVALID, INVALID, INVALID, -/* AAM AAD SETALC XLAT*/ - &aam_op, &aad_op, &alu_op, &xlat_op, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, -/* LOOPNE LOOPE LOOP JCXZ*/ -/*e0*/ &loop_op, &loop_op, &loop_op, &loop_op, -/* IN AL IN AX OUT_AL OUT_AX*/ - &io_op, &io_op, &io_op, &io_op, -/* CALL JMP JMP JMP*/ - &store_op, &branch_op, &jmp_far_op, &branch_op, -/* IN AL IN AX OUT_AL OUT_AX*/ - &io_op, &io_op, &io_op, &io_op, - -/* REPNE REPE*/ -/*f0*/ INVALID, INVALID, INVALID, INVALID, -/* HLT CMC*/ - &alu4_op, &alu_op, INVALID, INVALID, -/* CLC STC CLI STI*/ - &alu_op, &alu_op, &cli_op, &sti_op, -/* CLD STD INCDEC*/ - &alu4_op, &alu4_op, &store_op, INVALID - }; - -static const p6_instruction_t *opcode_timings_mod3[256] = - { -/* ADD ADD ADD ADD*/ -/*00*/ &alu_op, &alu_op, &alu_op, &alu_op, -/* ADD ADD PUSH ES POP ES*/ - &alu_op, &alu_op, &push_seg_op, &mov_seg_mem_op, -/* OR OR OR OR*/ - &alu_op, &alu_op, &alu_op, &alu_op, -/* OR OR PUSH CS */ - &alu_op, &alu_op, &push_seg_op, INVALID, - -/* ADC ADC ADC ADC*/ -/*10*/ &aluc_op, &aluc_op, &aluc_op, &aluc_op, -/* ADC ADC PUSH SS POP SS*/ - &aluc_op, &aluc_op, &push_seg_op, &mov_seg_mem_op, -/* SBB SBB SBB SBB*/ - &aluc_op, &aluc_op, &aluc_op, &aluc_op, -/* SBB SBB PUSH DS POP DS*/ - &aluc_op, &aluc_op, &push_seg_op, &mov_seg_mem_op, - -/* AND AND AND AND*/ -/*20*/ &alu_op, &alu_op, &alu_op, &alu_op, -/* AND AND DAA*/ - &alu_op, &alu_op, INVALID, &alu1_op, -/* SUB SUB SUB SUB*/ - &alu_op, &alu_op, &alu_op, &alu_op, -/* SUB SUB DAS*/ - &alu_op, &alu_op, INVALID, &alu1_op, - -/* XOR XOR XOR XOR*/ -/*30*/ &alu_op, &alu_op, &alu_op, &alu_op, -/* XOR XOR AAA*/ - &alu_op, &alu_op, INVALID, &alu1_op, -/* CMP CMP CMP CMP*/ - &alu_op, &alu_op, &alu_op, &alu_op, -/* CMP CMP AAS*/ - &alu_op, &alu_op, INVALID, &alu1_op, - -/* INC EAX INC ECX INC EDX INC EBX*/ -/*40*/ &alu_op, &alu_op, &alu_op, &alu_op, -/* INC ESP INC EBP INC ESI INC EDI*/ - &alu_op, &alu_op, &alu_op, &alu_op, -/* DEC EAX DEC ECX DEC EDX DEC EBX*/ - &alu_op, &alu_op, &alu_op, &alu_op, -/* DEC ESP DEC EBP DEC ESI DEC EDI*/ - &alu_op, &alu_op, &alu_op, &alu_op, - -/* PUSH EAX PUSH ECX PUSH EDX PUSH EBX*/ -/*50*/ &store_op, &store_op, &store_op, &store_op, -/* PUSH ESP PUSH EBP PUSH ESI PUSH EDI*/ - &store_op, &store_op, &store_op, &store_op, -/* POP EAX POP ECX POP EDX POP EBX*/ - &pop_reg_op, &pop_reg_op, &pop_reg_op, &pop_reg_op, -/* POP ESP POP EBP POP ESI POP EDI*/ - &pop_reg_op, &pop_reg_op, &pop_reg_op, &pop_reg_op, - -/* PUSHA POPA BOUND ARPL*/ -/*60*/ &pusha_op, &popa_op, &bound_op, &arpl_op, - INVALID, INVALID, INVALID, INVALID, -/* PUSH imm IMUL PUSH imm IMUL*/ - &push_imm_op, &mul_op, &push_imm_op, &mul_op, -/* INSB INSW OUTSB OUTSW*/ - &ins_op, &ins_op, &outs_op, &outs_op, - -/* Jxx*/ -/*70*/ &branch_op, &branch_op, &branch_op, &branch_op, - &branch_op, &branch_op, &branch_op, &branch_op, - &branch_op, &branch_op, &branch_op, &branch_op, - &branch_op, &branch_op, &branch_op, &branch_op, - -/*80*/ INVALID, INVALID, INVALID, INVALID, -/* TEST TEST XCHG XCHG*/ - &alu_op, &alu_op, &xchg_op, &xchg_op, -/* MOV MOV MOV MOV*/ - &store_op, &store_op, &load_op, &load_op, -/* MOV from seg LEA MOV to seg POP*/ - &alu_op, &alu0_op, &mov_seg_reg_op, &pop_reg_op, - -/* NOP XCHG XCHG XCHG*/ -/*90*/ &alu_op, &xchg_op, &xchg_op, &xchg_op, -/* XCHG XCHG XCHG XCHG*/ - &xchg_op, &xchg_op, &xchg_op, &xchg_op, -/* CBW CWD CALL far WAIT*/ - &alu_op, &alu0_op, &call_far_op, &alu_op, -/* PUSHF POPF SAHF LAHF*/ - &pushf_op, &popf_op, &alu_op, &alu_op, - -/* MOV MOV MOV MOV*/ -/*a0*/ &load_op, &load_op, &store_op, &store_op, -/* MOVSB MOVSW CMPSB CMPSW*/ - &movs_op, &movs_op, &cmps_op, &cmps_op, -/* TEST TEST STOSB STOSW*/ - &alu_op, &alu_op, &stos_op, &stos_op, -/* LODSB LODSW SCASB SCASW*/ - &lods_op, &lods_op, &scas_op, &scas_op, - -/* MOV*/ -/*b0*/ &alu_op, &alu_op, &alu_op, &alu_op, - &alu_op, &alu_op, &alu_op, &alu_op, - &alu_op, &alu_op, &alu_op, &alu_op, - &alu_op, &alu_op, &alu_op, &alu_op, - -/* RET imm RET*/ -/*c0*/ INVALID, INVALID, &reti_op, &ret_op, -/* LES LDS MOV MOV*/ - &lss_op, &lss_op, &store_op, &store_op, -/* ENTER LEAVE RETF RETF*/ - &enter_op, &leave_op, &retf_op, &retf_op, -/* INT3 INT INTO IRET*/ - &int_op, &int_op, &int_op, &iret_op, - - -/*d0*/ INVALID, INVALID, INVALID, INVALID, -/* AAM AAD SETALC XLAT*/ - &aam_op, &aad_op, &alu_op, &xlat_op, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, -/* LOOPNE LOOPE LOOP JCXZ*/ -/*e0*/ &loop_op, &loop_op, &loop_op, &loop_op, -/* IN AL IN AX OUT_AL OUT_AX*/ - &io_op, &io_op, &io_op, &io_op, -/* CALL JMP JMP JMP*/ - &store_op, &branch_op, &jmp_far_op, &branch_op, -/* IN AL IN AX OUT_AL OUT_AX*/ - &io_op, &io_op, &io_op, &io_op, - -/* REPNE REPE*/ -/*f0*/ INVALID, INVALID, INVALID, INVALID, -/* HLT CMC*/ - &alu4_op, &alu_op, INVALID, INVALID, -/* CLC STC CLI STI*/ - &alu_op, &alu_op, &cli_op, &sti_op, -/* CLD STD INCDEC*/ - &alu4_op, &alu4_op, &alu_op, INVALID - }; - -static const p6_instruction_t *opcode_timings_0f[256] = - { -/*00*/ &alu6_op, &alu6_op, &alu6_op, &alu6_op, - INVALID, &alu6_op, &alu6_op, INVALID, - &invd_op, &wbinvd_op, INVALID, INVALID, - INVALID, &load_op, INVALID, INVALID, - -/*10*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*20*/ &alu6_op, &alu6_op, &alu6_op, &alu6_op, - &alu6_op, &alu6_op, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*30*/ &alu6_op, &alu6_op, &alu6_op, 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*/ &load_mmx_op, &load_mmx_op, &load_mmx_op, &load_mmx_op, - &load_mmx_op, &load_mmx_op, &load_mmx_op, &load_mmx_op, - &load_mmx_op, &load_mmx_op, &load_mmx_op, &load_mmx_op, - INVALID, INVALID, &load_op, &load_op, - -/*70*/ INVALID, &load_mmx_shift_op, &load_mmx_shift_op, &load_mmx_shift_op, - &load_mmx_op, &load_mmx_op, &load_mmx_op, &emms_op, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, &store_op, &store_op, - -/*80*/ &branch_op, &branch_op, &branch_op, &branch_op, - &branch_op, &branch_op, &branch_op, &branch_op, - &branch_op, &branch_op, &branch_op, &branch_op, - &branch_op, &branch_op, &branch_op, &branch_op, - -/*90*/ &alu_op, &alu_op, &alu_op, &alu_op, - &alu_op, &alu_op, &alu_op, &alu_op, - &alu_op, &alu_op, &alu_op, &alu_op, - &alu_op, &alu_op, &alu_op, &alu_op, - -/*a0*/ &push_seg_op, &mov_seg_mem_op, &cpuid_op, &load_alu_op, - &alu_store_op, &alu_store_op, INVALID, INVALID, - &push_seg_op, &mov_seg_mem_op, INVALID, &load_alu_op, - &alu_store_op, &alu_store_op, INVALID, &mul_op, - -/*b0*/ &cmpxchg_op, &cmpxchg_op, &lss_op, &load_alu_op, - &lss_op, &lss_op, &load_alu_op, &load_alu_op, - INVALID, INVALID, &load_alu_op, &load_alu_op, - &load_bsx_op, &load_bsx_op, &load_alu_op, &load_alu_op, - -/*c0*/ &alu_store_op, &alu_store_op, INVALID, INVALID, - INVALID, INVALID, INVALID, &cmpxchg_op, - &bswap_op, &bswap_op, &bswap_op, &bswap_op, - &bswap_op, &bswap_op, &bswap_op, &bswap_op, - -/*d0*/ INVALID, &load_mmx_shift_op, &load_mmx_shift_op, &load_mmx_shift_op, - INVALID, &load_mmx_mul_op, INVALID, INVALID, - &load_mmx_op, &load_mmx_op, INVALID, &load_mmx_op, - &load_mmx_op, &load_mmx_op, INVALID, &load_mmx_op, - -/*e0*/ &load_mmx_op, &load_mmx_shift_op, &load_mmx_shift_op, INVALID, - INVALID, &load_mmx_mul_op, INVALID, INVALID, - &load_mmx_op, &load_mmx_op, INVALID, &load_mmx_op, - &load_mmx_op, &load_mmx_op, INVALID, &load_mmx_op, - -/*f0*/ INVALID, &load_mmx_shift_op, &load_mmx_shift_op, &load_mmx_shift_op, - INVALID, &load_mmx_mul_op, INVALID, INVALID, - &load_mmx_op, &load_mmx_op, &load_mmx_op, INVALID, - &load_mmx_op, &load_mmx_op, &load_mmx_op, INVALID, - }; -static const p6_instruction_t *opcode_timings_0f_mod3[256] = - { -/*00*/ &alu6_op, &alu6_op, &alu6_op, &alu6_op, - INVALID, &alu6_op, &alu6_op, INVALID, - &invd_op, &wbinvd_op, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*10*/ INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*20*/ &alu6_op, &alu6_op, &alu6_op, &alu6_op, - &alu6_op, &alu6_op, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - -/*30*/ &alu6_op, &alu6_op, &alu6_op, 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*/ &mmx_op, &mmx_op, &mmx_op, &mmx_op, - &mmx_op, &mmx_op, &mmx_op, &mmx_op, - &mmx_op, &mmx_op, &mmx_op, &mmx_op, - INVALID, INVALID, &mmx_op, &mmx_op, - -/*70*/ INVALID, &mmx_shift_op, &mmx_shift_op, &mmx_shift_op, - &mmx_op, &mmx_op, &mmx_op, &emms_op, - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, &mmx_op, &mmx_op, - -/*80*/ &branch_op, &branch_op, &branch_op, &branch_op, - &branch_op, &branch_op, &branch_op, &branch_op, - &branch_op, &branch_op, &branch_op, &branch_op, - &branch_op, &branch_op, &branch_op, &branch_op, - -/*90*/ &alu_op, &alu_op, &alu_op, &alu_op, - &alu_op, &alu_op, &alu_op, &alu_op, - &alu_op, &alu_op, &alu_op, &alu_op, - &alu_op, &alu_op, &alu_op, &alu_op, - -/*a0*/ &push_seg_op, &mov_seg_mem_op, &cpuid_op, &alu_op, - &alu_op, &alu_op, INVALID, INVALID, - &push_seg_op, &mov_seg_mem_op, INVALID, &alu_op, - &alu_op, &alu_op, INVALID, &mul_op, - -/*b0*/ &cmpxchg_op, &cmpxchg_op, &lss_op, &alu_op, - &lss_op, &lss_op, &alu_op, &alu_op, - INVALID, INVALID, &alu_op, &alu_op, - &bsx_op, &bsx_op, &alu_op, &alu_op, - -/*c0*/ &alu_op, &alu_op, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - &bswap_op, &bswap_op, &bswap_op, &bswap_op, - &bswap_op, &bswap_op, &bswap_op, &bswap_op, - -/*d0*/ INVALID, &mmx_shift_op, &mmx_shift_op, &mmx_shift_op, - INVALID, &mmx_mul_op, INVALID, INVALID, - &mmx_op, &mmx_op, INVALID, &mmx_op, - &mmx_op, &mmx_op, INVALID, &mmx_op, - -/*e0*/ &mmx_op, &mmx_shift_op, &mmx_shift_op, INVALID, - INVALID, &mmx_mul_op, INVALID, INVALID, - &mmx_op, &mmx_op, INVALID, &mmx_op, - &mmx_op, &mmx_op, INVALID, &mmx_op, - -/*f0*/ INVALID, &mmx_shift_op, &mmx_shift_op, &mmx_shift_op, - INVALID, &mmx_mul_op, INVALID, INVALID, - &mmx_op, &mmx_op, &mmx_op, INVALID, - &mmx_op, &mmx_op, &mmx_op, INVALID, - }; - -static const p6_instruction_t *opcode_timings_shift[8] = - { - &alu0_store_op, &alu0_store_op, &rcx_store_op, &rcx_store_op, - &alu0_store_op, &alu0_store_op, &alu0_store_op, &alu0_store_op - }; -static const p6_instruction_t *opcode_timings_shift_mod3[8] = - { - &alu0_op, &alu0_op, &rcx_op, &rcx_op, - &alu0_op, &alu0_op, &alu0_op, &alu0_op - }; - -static const p6_instruction_t *opcode_timings_8x[8] = - { - &alu_store_op, &alu_store_op, &aluc_store_op, &aluc_store_op, - &alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op, - }; -static const p6_instruction_t *opcode_timings_8x_mod3[8] = - { - &alu_op, &alu_op, &aluc_op, &aluc_op, - &alu_op, &alu_op, &alu_op, &alu_op, - }; - -static const p6_instruction_t *opcode_timings_f6[8] = - { -/* TST NOT NEG*/ - &load_alu_op, INVALID, &alu_store_op, &alu_store_op, -/* MUL IMUL DIV IDIV*/ - &mul_mem_op, &mul_mem_op, &div16_mem_op, &div16_mem_op, - }; -static const p6_instruction_t *opcode_timings_f6_mod3[8] = - { -/* TST NOT NEG*/ - &alu_op, INVALID, &alu_op, &alu_op, -/* MUL IMUL DIV IDIV*/ - &mul_op, &mul_op, &div16_op, &div16_op, - }; -static const p6_instruction_t *opcode_timings_f7[8] = - { -/* TST NOT NEG*/ - &load_alu_op, INVALID, &alu_store_op, &alu_store_op, -/* MUL IMUL DIV IDIV*/ - &mul_mem_op, &mul_mem_op, &div32_mem_op, &div32_mem_op, - }; -static const p6_instruction_t *opcode_timings_f7_mod3[8] = - { -/* TST NOT NEG*/ - &alu_op, INVALID, &alu_op, &alu_op, -/* MUL IMUL DIV IDIV*/ - &mul_op, &mul_op, &div32_op, &div32_op, - }; -static const p6_instruction_t *opcode_timings_ff[8] = - { -/* INC DEC CALL CALL far*/ - &alu_store_op, &alu_store_op, &store_op, &load_call_far_op, -/* JMP JMP far PUSH*/ - &branch_op, &load_jmp_far_op, &push_mem_op, INVALID - }; -static const p6_instruction_t *opcode_timings_ff_mod3[8] = - { -/* INC DEC CALL CALL far*/ - &alu_op, &alu_op, &store_op, &call_far_op, -/* JMP JMP far PUSH*/ - &branch_op, &load_jmp_far_op, &push_mem_op, INVALID - }; - -static const p6_instruction_t *opcode_timings_d8[8] = - { -/* FADDs FMULs FCOMs FCOMPs*/ - &load_faddsub_op, &load_fmul_op, &fcom_op, &load_fcom_op, -/* FSUBs FSUBRs FDIVs FDIVRs*/ - &load_faddsub_op, &load_faddsub_op, &fdiv_mem_op, &fdiv_mem_op, - }; -static const p6_instruction_t *opcode_timings_d8_mod3[8] = - { -/* FADD FMUL FCOM FCOMP*/ - &faddsub_op, &fmul_op, &fcom_op, &fcom_op, -/* FSUB FSUBR FDIV FDIVR*/ - &faddsub_op, &faddsub_op, &fdiv_op, &fdiv_op, - }; - -static const p6_instruction_t *opcode_timings_d9[8] = - { -/* FLDs FSTs FSTPs*/ - &load_op, INVALID, &store_op, &store_op, -/* FLDENV FLDCW FSTENV FSTCW*/ - &flde_op, &fldcw_op, &fste_op, &fstsw_mem_op - }; -static const p6_instruction_t *opcode_timings_d9_mod3[64] = - { - /*FLD*/ - &float_op, &float_op, &float_op, &float_op, - &float_op, &float_op, &float_op, &float_op, - /*FXCH*/ - &fxch_op, &fxch_op, &fxch_op, &fxch_op, - &fxch_op, &fxch_op, &fxch_op, &fxch_op, - /*FNOP*/ - &float_op, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - /*FSTP*/ - &float_op, &float_op, &float_op, &float_op, - &float_op, &float_op, &float_op, &float_op, -/* opFCHS opFABS*/ - &float_op, &float_op, INVALID, INVALID, -/* opFTST opFXAM*/ - &float_op, &float_op, INVALID, INVALID, -/* opFLD1 opFLDL2T opFLDL2E opFLDPI*/ - &float_op, &float_op, &float_op, &float_op, -/* opFLDEG2 opFLDLN2 opFLDZ*/ - &float_op, &float_op, &float_op, INVALID, -/* opF2XM1 opFYL2X opFPTAN opFPATAN*/ - &fsin_op, &fsin_op, &fsin_op, &fsin_op, -/* opFDECSTP opFINCSTP,*/ - INVALID, INVALID, &float_op, &float_op, -/* opFPREM opFSQRT opFSINCOS*/ - &fdiv_op, INVALID, &fsqrt_op, &fsin_op, -/* opFRNDINT opFSCALE opFSIN opFCOS*/ - &float_op, &fdiv_op, &fsin_op, &fsin_op - }; - -static const p6_instruction_t *opcode_timings_da[8] = - { -/* FIADDl FIMULl FICOMl FICOMPl*/ - &load_fi_op, &load_fi_op, &load_fcom_op, &load_fcom_op, -/* FISUBl FISUBRl FIDIVl FIDIVRl*/ - &load_fi_op, &load_fi_op, &load_fi_op, &load_fi_op, - }; -static const p6_instruction_t *opcode_timings_da_mod3[8] = - { - INVALID, INVALID, INVALID, INVALID, -/* FCOMPP*/ - INVALID, &fcompp_op, INVALID, INVALID - }; - -static const p6_instruction_t *opcode_timings_db[8] = - { -/* FLDil FSTil FSTPil*/ - &fild_op, INVALID, &fist_op, &fist_op, -/* FLDe FSTPe*/ - INVALID, &flde_op, INVALID, &fste_op - }; -static const p6_instruction_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, &float_op, &float_op, &float_op, -/* opFNOP opFNOP*/ - &float_op, &float_op, 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 const p6_instruction_t *opcode_timings_dc[8] = - { -/* FADDd FMULd FCOMd FCOMPd*/ - &load_faddsub_op, &load_fmul_op, &load_fcom_op, &load_fcom_op, -/* FSUBd FSUBRd FDIVd FDIVRd*/ - &load_faddsub_op, &load_faddsub_op, &fdiv_mem_op, &fdiv_mem_op, - }; -static const p6_instruction_t *opcode_timings_dc_mod3[8] = - { -/* opFADDr opFMULr*/ - &faddsub_op, &fmul_op, INVALID, INVALID, -/* opFSUBRr opFSUBr opFDIVRr opFDIVr*/ - &faddsub_op, &faddsub_op, &fdiv_op, &fdiv_op - }; - -static const p6_instruction_t *opcode_timings_dd[8] = - { -/* FLDd FSTd FSTPd*/ - &load_op, INVALID, &store_op, &store_op, -/* FRSTOR FSAVE FSTSW*/ - &frstor_op, INVALID, &fsave_op, &fstsw_mem_op - }; -static const p6_instruction_t *opcode_timings_dd_mod3[8] = - { -/* FFFREE FST FSTP*/ - &float_op, INVALID, &float_op, &float_op, -/* FUCOM FUCOMP*/ - &float_op, &float_op, INVALID, INVALID - }; - -static const p6_instruction_t *opcode_timings_de[8] = - { -/* FIADDw FIMULw FICOMw FICOMPw*/ - &load_fi_op, &load_fi_op, &load_fcom_op, &load_fcom_op, -/* FISUBw FISUBRw FIDIVw FIDIVRw*/ - &load_fi_op, &load_fi_op, &load_fi_op, &load_fi_op, - }; -static const p6_instruction_t *opcode_timings_de_mod3[8] = - { -/* FADDP FMULP FCOMPP*/ - &faddsub_op, &fmul_op, INVALID, &fcompp_op, -/* FSUBP FSUBRP FDIVP FDIVRP*/ - &faddsub_op, &faddsub_op, &fdiv_op, &fdiv_op, - }; - -static const p6_instruction_t *opcode_timings_df[8] = - { -/* FILDiw FISTiw FISTPiw*/ - &fild_op, INVALID, &fist_op, &fist_op, -/* FILDiq FBSTP FISTPiq*/ - INVALID, &fild_op, &fbstp_op, &fist_op, - }; -static const p6_instruction_t *opcode_timings_df_mod3[8] = - { - INVALID, INVALID, INVALID, INVALID, -/* FSTSW AX*/ - &fstsw_ax_op, INVALID, INVALID, INVALID - }; +static const p6_instruction_t *opcode_timings[256] = { + /* ADD ADD ADD ADD*/ + /*00*/ &alu_store_op, &alu_store_op, &load_alu_op, &load_alu_op, + /* ADD ADD PUSH ES POP ES*/ + &alu_op, &alu_op, &push_seg_op, &mov_seg_mem_op, + /* OR OR OR OR*/ + &alu_store_op, &alu_store_op, &load_alu_op, &load_alu_op, + /* OR OR PUSH CS */ + &alu_op, &alu_op, &push_seg_op, INVALID, + + /* ADC ADC ADC ADC*/ + /*10*/ &aluc_store_op, &aluc_store_op, &load_aluc_op, &load_aluc_op, + /* ADC ADC PUSH SS POP SS*/ + &aluc_op, &aluc_op, &push_seg_op, &mov_seg_mem_op, + /* SBB SBB SBB SBB*/ + /*10*/ &aluc_store_op, &aluc_store_op, &load_aluc_op, &load_aluc_op, + /* SBB SBB PUSH DS POP DS*/ + &aluc_op, &aluc_op, &push_seg_op, &mov_seg_mem_op, + + /* AND AND AND AND*/ + /*20*/ &alu_store_op, &alu_store_op, &load_alu_op, &load_alu_op, + /* AND AND DAA*/ + &alu_op, &alu_op, INVALID, &alu1_op, + /* SUB SUB SUB SUB*/ + &alu_store_op, &alu_store_op, &load_alu_op, &load_alu_op, + /* SUB SUB DAS*/ + &alu_op, &alu_op, INVALID, &alu1_op, + + /* XOR XOR XOR XOR*/ + /*30*/ &alu_store_op, &alu_store_op, &load_alu_op, &load_alu_op, + /* XOR XOR AAA*/ + &alu_op, &alu_op, INVALID, &alu1_op, + /* CMP CMP CMP CMP*/ + &load_alu_op, &load_alu_op, &load_alu_op, &load_alu_op, + /* CMP CMP AAS*/ + &alu_op, &alu_op, INVALID, &alu1_op, + + /* INC EAX INC ECX INC EDX INC EBX*/ + /*40*/ &alu_op, &alu_op, &alu_op, &alu_op, + /* INC ESP INC EBP INC ESI INC EDI*/ + &alu_op, &alu_op, &alu_op, &alu_op, + /* DEC EAX DEC ECX DEC EDX DEC EBX*/ + &alu_op, &alu_op, &alu_op, &alu_op, + /* DEC ESP DEC EBP DEC ESI DEC EDI*/ + &alu_op, &alu_op, &alu_op, &alu_op, + + /* PUSH EAX PUSH ECX PUSH EDX PUSH EBX*/ + /*50*/ &store_op, &store_op, &store_op, &store_op, + /* PUSH ESP PUSH EBP PUSH ESI PUSH EDI*/ + &store_op, &store_op, &store_op, &store_op, + /* POP EAX POP ECX POP EDX POP EBX*/ + &pop_reg_op, &pop_reg_op, &pop_reg_op, &pop_reg_op, + /* POP ESP POP EBP POP ESI POP EDI*/ + &pop_reg_op, &pop_reg_op, &pop_reg_op, &pop_reg_op, + + /* PUSHA POPA BOUND ARPL*/ + /*60*/ &pusha_op, &popa_op, &bound_op, &arpl_op, INVALID, INVALID, INVALID, INVALID, + /* PUSH imm IMUL PUSH imm IMUL*/ + &push_imm_op, &mul_op, &push_imm_op, &mul_op, + /* INSB INSW OUTSB OUTSW*/ + &ins_op, &ins_op, &outs_op, &outs_op, + + /* Jxx*/ + /*70*/ &branch_op, &branch_op, &branch_op, &branch_op, &branch_op, &branch_op, &branch_op, &branch_op, &branch_op, + &branch_op, &branch_op, &branch_op, &branch_op, &branch_op, &branch_op, &branch_op, + + /*80*/ INVALID, INVALID, INVALID, INVALID, + /* TEST TEST XCHG XCHG*/ + &load_alu_op, &load_alu_op, &xchg_mem_op, &xchg_mem_op, + /* MOV MOV MOV MOV*/ + &store_op, &store_op, &load_op, &load_op, + /* MOV from seg LEA MOV to seg POP*/ + &store_op, &alu0_op, &mov_seg_mem_op, &pop_mem_op, + + /* NOP XCHG XCHG XCHG*/ + /*90*/ &alu_op, &xchg_op, &xchg_op, &xchg_op, + /* XCHG XCHG XCHG XCHG*/ + &xchg_op, &xchg_op, &xchg_op, &xchg_op, + /* CBW CWD CALL far WAIT*/ + &alu_op, &alu0_op, &call_far_op, &alu_op, + /* PUSHF POPF SAHF LAHF*/ + &pushf_op, &popf_op, &alu_op, &alu_op, + + /* MOV MOV MOV MOV*/ + /*a0*/ &load_op, &load_op, &store_op, &store_op, + /* MOVSB MOVSW CMPSB CMPSW*/ + &movs_op, &movs_op, &cmps_op, &cmps_op, + /* TEST TEST STOSB STOSW*/ + &load_alu_op, &load_alu_op, &stos_op, &stos_op, + /* LODSB LODSW SCASB SCASW*/ + &lods_op, &lods_op, &scas_op, &scas_op, + + /* MOV*/ + /*b0*/ &alu_op, &alu_op, &alu_op, &alu_op, &alu_op, &alu_op, &alu_op, &alu_op, &alu_op, &alu_op, &alu_op, &alu_op, + &alu_op, &alu_op, &alu_op, &alu_op, + + /* RET imm RET*/ + /*c0*/ INVALID, INVALID, &reti_op, &ret_op, + /* LES LDS MOV MOV*/ + &lss_op, &lss_op, &store_op, &store_op, + /* ENTER LEAVE RETF RETF*/ + &enter_op, &leave_op, &retf_op, &retf_op, + /* INT3 INT INTO IRET*/ + &int_op, &int_op, &int_op, &iret_op, + + /*d0*/ INVALID, INVALID, INVALID, INVALID, + /* AAM AAD SETALC XLAT*/ + &aam_op, &aad_op, &alu_op, &xlat_op, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, + /* LOOPNE LOOPE LOOP JCXZ*/ + /*e0*/ &loop_op, &loop_op, &loop_op, &loop_op, + /* IN AL IN AX OUT_AL OUT_AX*/ + &io_op, &io_op, &io_op, &io_op, + /* CALL JMP JMP JMP*/ + &store_op, &branch_op, &jmp_far_op, &branch_op, + /* IN AL IN AX OUT_AL OUT_AX*/ + &io_op, &io_op, &io_op, &io_op, + + /* REPNE REPE*/ + /*f0*/ INVALID, INVALID, INVALID, INVALID, + /* HLT CMC*/ + &alu4_op, &alu_op, INVALID, INVALID, + /* CLC STC CLI STI*/ + &alu_op, &alu_op, &cli_op, &sti_op, + /* CLD STD INCDEC*/ + &alu4_op, &alu4_op, &store_op, INVALID}; + +static const p6_instruction_t *opcode_timings_mod3[256] = { + /* ADD ADD ADD ADD*/ + /*00*/ &alu_op, &alu_op, &alu_op, &alu_op, + /* ADD ADD PUSH ES POP ES*/ + &alu_op, &alu_op, &push_seg_op, &mov_seg_mem_op, + /* OR OR OR OR*/ + &alu_op, &alu_op, &alu_op, &alu_op, + /* OR OR PUSH CS */ + &alu_op, &alu_op, &push_seg_op, INVALID, + + /* ADC ADC ADC ADC*/ + /*10*/ &aluc_op, &aluc_op, &aluc_op, &aluc_op, + /* ADC ADC PUSH SS POP SS*/ + &aluc_op, &aluc_op, &push_seg_op, &mov_seg_mem_op, + /* SBB SBB SBB SBB*/ + &aluc_op, &aluc_op, &aluc_op, &aluc_op, + /* SBB SBB PUSH DS POP DS*/ + &aluc_op, &aluc_op, &push_seg_op, &mov_seg_mem_op, + + /* AND AND AND AND*/ + /*20*/ &alu_op, &alu_op, &alu_op, &alu_op, + /* AND AND DAA*/ + &alu_op, &alu_op, INVALID, &alu1_op, + /* SUB SUB SUB SUB*/ + &alu_op, &alu_op, &alu_op, &alu_op, + /* SUB SUB DAS*/ + &alu_op, &alu_op, INVALID, &alu1_op, + + /* XOR XOR XOR XOR*/ + /*30*/ &alu_op, &alu_op, &alu_op, &alu_op, + /* XOR XOR AAA*/ + &alu_op, &alu_op, INVALID, &alu1_op, + /* CMP CMP CMP CMP*/ + &alu_op, &alu_op, &alu_op, &alu_op, + /* CMP CMP AAS*/ + &alu_op, &alu_op, INVALID, &alu1_op, + + /* INC EAX INC ECX INC EDX INC EBX*/ + /*40*/ &alu_op, &alu_op, &alu_op, &alu_op, + /* INC ESP INC EBP INC ESI INC EDI*/ + &alu_op, &alu_op, &alu_op, &alu_op, + /* DEC EAX DEC ECX DEC EDX DEC EBX*/ + &alu_op, &alu_op, &alu_op, &alu_op, + /* DEC ESP DEC EBP DEC ESI DEC EDI*/ + &alu_op, &alu_op, &alu_op, &alu_op, + + /* PUSH EAX PUSH ECX PUSH EDX PUSH EBX*/ + /*50*/ &store_op, &store_op, &store_op, &store_op, + /* PUSH ESP PUSH EBP PUSH ESI PUSH EDI*/ + &store_op, &store_op, &store_op, &store_op, + /* POP EAX POP ECX POP EDX POP EBX*/ + &pop_reg_op, &pop_reg_op, &pop_reg_op, &pop_reg_op, + /* POP ESP POP EBP POP ESI POP EDI*/ + &pop_reg_op, &pop_reg_op, &pop_reg_op, &pop_reg_op, + + /* PUSHA POPA BOUND ARPL*/ + /*60*/ &pusha_op, &popa_op, &bound_op, &arpl_op, INVALID, INVALID, INVALID, INVALID, + /* PUSH imm IMUL PUSH imm IMUL*/ + &push_imm_op, &mul_op, &push_imm_op, &mul_op, + /* INSB INSW OUTSB OUTSW*/ + &ins_op, &ins_op, &outs_op, &outs_op, + + /* Jxx*/ + /*70*/ &branch_op, &branch_op, &branch_op, &branch_op, &branch_op, &branch_op, &branch_op, &branch_op, &branch_op, + &branch_op, &branch_op, &branch_op, &branch_op, &branch_op, &branch_op, &branch_op, + + /*80*/ INVALID, INVALID, INVALID, INVALID, + /* TEST TEST XCHG XCHG*/ + &alu_op, &alu_op, &xchg_op, &xchg_op, + /* MOV MOV MOV MOV*/ + &store_op, &store_op, &load_op, &load_op, + /* MOV from seg LEA MOV to seg POP*/ + &alu_op, &alu0_op, &mov_seg_reg_op, &pop_reg_op, + + /* NOP XCHG XCHG XCHG*/ + /*90*/ &alu_op, &xchg_op, &xchg_op, &xchg_op, + /* XCHG XCHG XCHG XCHG*/ + &xchg_op, &xchg_op, &xchg_op, &xchg_op, + /* CBW CWD CALL far WAIT*/ + &alu_op, &alu0_op, &call_far_op, &alu_op, + /* PUSHF POPF SAHF LAHF*/ + &pushf_op, &popf_op, &alu_op, &alu_op, + + /* MOV MOV MOV MOV*/ + /*a0*/ &load_op, &load_op, &store_op, &store_op, + /* MOVSB MOVSW CMPSB CMPSW*/ + &movs_op, &movs_op, &cmps_op, &cmps_op, + /* TEST TEST STOSB STOSW*/ + &alu_op, &alu_op, &stos_op, &stos_op, + /* LODSB LODSW SCASB SCASW*/ + &lods_op, &lods_op, &scas_op, &scas_op, + + /* MOV*/ + /*b0*/ &alu_op, &alu_op, &alu_op, &alu_op, &alu_op, &alu_op, &alu_op, &alu_op, &alu_op, &alu_op, &alu_op, &alu_op, + &alu_op, &alu_op, &alu_op, &alu_op, + + /* RET imm RET*/ + /*c0*/ INVALID, INVALID, &reti_op, &ret_op, + /* LES LDS MOV MOV*/ + &lss_op, &lss_op, &store_op, &store_op, + /* ENTER LEAVE RETF RETF*/ + &enter_op, &leave_op, &retf_op, &retf_op, + /* INT3 INT INTO IRET*/ + &int_op, &int_op, &int_op, &iret_op, + + /*d0*/ INVALID, INVALID, INVALID, INVALID, + /* AAM AAD SETALC XLAT*/ + &aam_op, &aad_op, &alu_op, &xlat_op, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, + /* LOOPNE LOOPE LOOP JCXZ*/ + /*e0*/ &loop_op, &loop_op, &loop_op, &loop_op, + /* IN AL IN AX OUT_AL OUT_AX*/ + &io_op, &io_op, &io_op, &io_op, + /* CALL JMP JMP JMP*/ + &store_op, &branch_op, &jmp_far_op, &branch_op, + /* IN AL IN AX OUT_AL OUT_AX*/ + &io_op, &io_op, &io_op, &io_op, + + /* REPNE REPE*/ + /*f0*/ INVALID, INVALID, INVALID, INVALID, + /* HLT CMC*/ + &alu4_op, &alu_op, INVALID, INVALID, + /* CLC STC CLI STI*/ + &alu_op, &alu_op, &cli_op, &sti_op, + /* CLD STD INCDEC*/ + &alu4_op, &alu4_op, &alu_op, INVALID}; + +static const p6_instruction_t *opcode_timings_0f[256] = { + /*00*/ &alu6_op, + &alu6_op, + &alu6_op, + &alu6_op, + INVALID, + &alu6_op, + &alu6_op, + INVALID, + &invd_op, + &wbinvd_op, + INVALID, + INVALID, + INVALID, + &load_op, + INVALID, + INVALID, + + /*10*/ INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + + /*20*/ &alu6_op, + &alu6_op, + &alu6_op, + &alu6_op, + &alu6_op, + &alu6_op, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + + /*30*/ &alu6_op, + &alu6_op, + &alu6_op, + 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*/ &load_mmx_op, + &load_mmx_op, + &load_mmx_op, + &load_mmx_op, + &load_mmx_op, + &load_mmx_op, + &load_mmx_op, + &load_mmx_op, + &load_mmx_op, + &load_mmx_op, + &load_mmx_op, + &load_mmx_op, + INVALID, + INVALID, + &load_op, + &load_op, + + /*70*/ INVALID, + &load_mmx_shift_op, + &load_mmx_shift_op, + &load_mmx_shift_op, + &load_mmx_op, + &load_mmx_op, + &load_mmx_op, + &emms_op, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + &store_op, + &store_op, + + /*80*/ &branch_op, + &branch_op, + &branch_op, + &branch_op, + &branch_op, + &branch_op, + &branch_op, + &branch_op, + &branch_op, + &branch_op, + &branch_op, + &branch_op, + &branch_op, + &branch_op, + &branch_op, + &branch_op, + + /*90*/ &alu_op, + &alu_op, + &alu_op, + &alu_op, + &alu_op, + &alu_op, + &alu_op, + &alu_op, + &alu_op, + &alu_op, + &alu_op, + &alu_op, + &alu_op, + &alu_op, + &alu_op, + &alu_op, + + /*a0*/ &push_seg_op, + &mov_seg_mem_op, + &cpuid_op, + &load_alu_op, + &alu_store_op, + &alu_store_op, + INVALID, + INVALID, + &push_seg_op, + &mov_seg_mem_op, + INVALID, + &load_alu_op, + &alu_store_op, + &alu_store_op, + INVALID, + &mul_op, + + /*b0*/ &cmpxchg_op, + &cmpxchg_op, + &lss_op, + &load_alu_op, + &lss_op, + &lss_op, + &load_alu_op, + &load_alu_op, + INVALID, + INVALID, + &load_alu_op, + &load_alu_op, + &load_bsx_op, + &load_bsx_op, + &load_alu_op, + &load_alu_op, + + /*c0*/ &alu_store_op, + &alu_store_op, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + &cmpxchg_op, + &bswap_op, + &bswap_op, + &bswap_op, + &bswap_op, + &bswap_op, + &bswap_op, + &bswap_op, + &bswap_op, + + /*d0*/ INVALID, + &load_mmx_shift_op, + &load_mmx_shift_op, + &load_mmx_shift_op, + INVALID, + &load_mmx_mul_op, + INVALID, + INVALID, + &load_mmx_op, + &load_mmx_op, + INVALID, + &load_mmx_op, + &load_mmx_op, + &load_mmx_op, + INVALID, + &load_mmx_op, + + /*e0*/ &load_mmx_op, + &load_mmx_shift_op, + &load_mmx_shift_op, + INVALID, + INVALID, + &load_mmx_mul_op, + INVALID, + INVALID, + &load_mmx_op, + &load_mmx_op, + INVALID, + &load_mmx_op, + &load_mmx_op, + &load_mmx_op, + INVALID, + &load_mmx_op, + + /*f0*/ INVALID, + &load_mmx_shift_op, + &load_mmx_shift_op, + &load_mmx_shift_op, + INVALID, + &load_mmx_mul_op, + INVALID, + INVALID, + &load_mmx_op, + &load_mmx_op, + &load_mmx_op, + INVALID, + &load_mmx_op, + &load_mmx_op, + &load_mmx_op, + INVALID, +}; +static const p6_instruction_t *opcode_timings_0f_mod3[256] = { + /*00*/ &alu6_op, + &alu6_op, + &alu6_op, + &alu6_op, + INVALID, + &alu6_op, + &alu6_op, + INVALID, + &invd_op, + &wbinvd_op, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + + /*10*/ INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + + /*20*/ &alu6_op, + &alu6_op, + &alu6_op, + &alu6_op, + &alu6_op, + &alu6_op, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + + /*30*/ &alu6_op, + &alu6_op, + &alu6_op, + 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*/ &mmx_op, + &mmx_op, + &mmx_op, + &mmx_op, + &mmx_op, + &mmx_op, + &mmx_op, + &mmx_op, + &mmx_op, + &mmx_op, + &mmx_op, + &mmx_op, + INVALID, + INVALID, + &mmx_op, + &mmx_op, + + /*70*/ INVALID, + &mmx_shift_op, + &mmx_shift_op, + &mmx_shift_op, + &mmx_op, + &mmx_op, + &mmx_op, + &emms_op, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + &mmx_op, + &mmx_op, + + /*80*/ &branch_op, + &branch_op, + &branch_op, + &branch_op, + &branch_op, + &branch_op, + &branch_op, + &branch_op, + &branch_op, + &branch_op, + &branch_op, + &branch_op, + &branch_op, + &branch_op, + &branch_op, + &branch_op, + + /*90*/ &alu_op, + &alu_op, + &alu_op, + &alu_op, + &alu_op, + &alu_op, + &alu_op, + &alu_op, + &alu_op, + &alu_op, + &alu_op, + &alu_op, + &alu_op, + &alu_op, + &alu_op, + &alu_op, + + /*a0*/ &push_seg_op, + &mov_seg_mem_op, + &cpuid_op, + &alu_op, + &alu_op, + &alu_op, + INVALID, + INVALID, + &push_seg_op, + &mov_seg_mem_op, + INVALID, + &alu_op, + &alu_op, + &alu_op, + INVALID, + &mul_op, + + /*b0*/ &cmpxchg_op, + &cmpxchg_op, + &lss_op, + &alu_op, + &lss_op, + &lss_op, + &alu_op, + &alu_op, + INVALID, + INVALID, + &alu_op, + &alu_op, + &bsx_op, + &bsx_op, + &alu_op, + &alu_op, + + /*c0*/ &alu_op, + &alu_op, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + &bswap_op, + &bswap_op, + &bswap_op, + &bswap_op, + &bswap_op, + &bswap_op, + &bswap_op, + &bswap_op, + + /*d0*/ INVALID, + &mmx_shift_op, + &mmx_shift_op, + &mmx_shift_op, + INVALID, + &mmx_mul_op, + INVALID, + INVALID, + &mmx_op, + &mmx_op, + INVALID, + &mmx_op, + &mmx_op, + &mmx_op, + INVALID, + &mmx_op, + + /*e0*/ &mmx_op, + &mmx_shift_op, + &mmx_shift_op, + INVALID, + INVALID, + &mmx_mul_op, + INVALID, + INVALID, + &mmx_op, + &mmx_op, + INVALID, + &mmx_op, + &mmx_op, + &mmx_op, + INVALID, + &mmx_op, + + /*f0*/ INVALID, + &mmx_shift_op, + &mmx_shift_op, + &mmx_shift_op, + INVALID, + &mmx_mul_op, + INVALID, + INVALID, + &mmx_op, + &mmx_op, + &mmx_op, + INVALID, + &mmx_op, + &mmx_op, + &mmx_op, + INVALID, +}; + +static const p6_instruction_t *opcode_timings_shift[8] = {&alu0_store_op, &alu0_store_op, &rcx_store_op, &rcx_store_op, + &alu0_store_op, &alu0_store_op, &alu0_store_op, &alu0_store_op}; +static const p6_instruction_t *opcode_timings_shift_mod3[8] = {&alu0_op, &alu0_op, &rcx_op, &rcx_op, + &alu0_op, &alu0_op, &alu0_op, &alu0_op}; + +static const p6_instruction_t *opcode_timings_8x[8] = { + &alu_store_op, &alu_store_op, &aluc_store_op, &aluc_store_op, &alu_store_op, &alu_store_op, &alu_store_op, &alu_store_op, +}; +static const p6_instruction_t *opcode_timings_8x_mod3[8] = { + &alu_op, &alu_op, &aluc_op, &aluc_op, &alu_op, &alu_op, &alu_op, &alu_op, +}; + +static const p6_instruction_t *opcode_timings_f6[8] = { + /* TST NOT NEG*/ + &load_alu_op, + INVALID, + &alu_store_op, + &alu_store_op, + /* MUL IMUL DIV IDIV*/ + &mul_mem_op, + &mul_mem_op, + &div16_mem_op, + &div16_mem_op, +}; +static const p6_instruction_t *opcode_timings_f6_mod3[8] = { + /* TST NOT NEG*/ + &alu_op, + INVALID, + &alu_op, + &alu_op, + /* MUL IMUL DIV IDIV*/ + &mul_op, + &mul_op, + &div16_op, + &div16_op, +}; +static const p6_instruction_t *opcode_timings_f7[8] = { + /* TST NOT NEG*/ + &load_alu_op, + INVALID, + &alu_store_op, + &alu_store_op, + /* MUL IMUL DIV IDIV*/ + &mul_mem_op, + &mul_mem_op, + &div32_mem_op, + &div32_mem_op, +}; +static const p6_instruction_t *opcode_timings_f7_mod3[8] = { + /* TST NOT NEG*/ + &alu_op, + INVALID, + &alu_op, + &alu_op, + /* MUL IMUL DIV IDIV*/ + &mul_op, + &mul_op, + &div32_op, + &div32_op, +}; +static const p6_instruction_t *opcode_timings_ff[8] = { + /* INC DEC CALL CALL far*/ + &alu_store_op, &alu_store_op, &store_op, &load_call_far_op, + /* JMP JMP far PUSH*/ + &branch_op, &load_jmp_far_op, &push_mem_op, INVALID}; +static const p6_instruction_t *opcode_timings_ff_mod3[8] = { + /* INC DEC CALL CALL far*/ + &alu_op, &alu_op, &store_op, &call_far_op, + /* JMP JMP far PUSH*/ + &branch_op, &load_jmp_far_op, &push_mem_op, INVALID}; + +static const p6_instruction_t *opcode_timings_d8[8] = { + /* FADDs FMULs FCOMs FCOMPs*/ + &load_faddsub_op, + &load_fmul_op, + &fcom_op, + &load_fcom_op, + /* FSUBs FSUBRs FDIVs FDIVRs*/ + &load_faddsub_op, + &load_faddsub_op, + &fdiv_mem_op, + &fdiv_mem_op, +}; +static const p6_instruction_t *opcode_timings_d8_mod3[8] = { + /* FADD FMUL FCOM FCOMP*/ + &faddsub_op, + &fmul_op, + &fcom_op, + &fcom_op, + /* FSUB FSUBR FDIV FDIVR*/ + &faddsub_op, + &faddsub_op, + &fdiv_op, + &fdiv_op, +}; + +static const p6_instruction_t *opcode_timings_d9[8] = { + /* FLDs FSTs FSTPs*/ + &load_op, INVALID, &store_op, &store_op, + /* FLDENV FLDCW FSTENV FSTCW*/ + &flde_op, &fldcw_op, &fste_op, &fstsw_mem_op}; +static const p6_instruction_t *opcode_timings_d9_mod3[64] = { + /*FLD*/ + &float_op, &float_op, &float_op, &float_op, &float_op, &float_op, &float_op, &float_op, + /*FXCH*/ + &fxch_op, &fxch_op, &fxch_op, &fxch_op, &fxch_op, &fxch_op, &fxch_op, &fxch_op, + /*FNOP*/ + &float_op, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, + /*FSTP*/ + &float_op, &float_op, &float_op, &float_op, &float_op, &float_op, &float_op, &float_op, + /* opFCHS opFABS*/ + &float_op, &float_op, INVALID, INVALID, + /* opFTST opFXAM*/ + &float_op, &float_op, INVALID, INVALID, + /* opFLD1 opFLDL2T opFLDL2E opFLDPI*/ + &float_op, &float_op, &float_op, &float_op, + /* opFLDEG2 opFLDLN2 opFLDZ*/ + &float_op, &float_op, &float_op, INVALID, + /* opF2XM1 opFYL2X opFPTAN opFPATAN*/ + &fsin_op, &fsin_op, &fsin_op, &fsin_op, + /* opFDECSTP opFINCSTP,*/ + INVALID, INVALID, &float_op, &float_op, + /* opFPREM opFSQRT opFSINCOS*/ + &fdiv_op, INVALID, &fsqrt_op, &fsin_op, + /* opFRNDINT opFSCALE opFSIN opFCOS*/ + &float_op, &fdiv_op, &fsin_op, &fsin_op}; + +static const p6_instruction_t *opcode_timings_da[8] = { + /* FIADDl FIMULl FICOMl FICOMPl*/ + &load_fi_op, + &load_fi_op, + &load_fcom_op, + &load_fcom_op, + /* FISUBl FISUBRl FIDIVl FIDIVRl*/ + &load_fi_op, + &load_fi_op, + &load_fi_op, + &load_fi_op, +}; +static const p6_instruction_t *opcode_timings_da_mod3[8] = {INVALID, INVALID, INVALID, INVALID, + /* FCOMPP*/ + INVALID, &fcompp_op, INVALID, INVALID}; + +static const p6_instruction_t *opcode_timings_db[8] = { + /* FLDil FSTil FSTPil*/ + &fild_op, INVALID, &fist_op, &fist_op, + /* FLDe FSTPe*/ + INVALID, &flde_op, INVALID, &fste_op}; +static const p6_instruction_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, + &float_op, + &float_op, + &float_op, + /* opFNOP opFNOP*/ + &float_op, + &float_op, + 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 const p6_instruction_t *opcode_timings_dc[8] = { + /* FADDd FMULd FCOMd FCOMPd*/ + &load_faddsub_op, + &load_fmul_op, + &load_fcom_op, + &load_fcom_op, + /* FSUBd FSUBRd FDIVd FDIVRd*/ + &load_faddsub_op, + &load_faddsub_op, + &fdiv_mem_op, + &fdiv_mem_op, +}; +static const p6_instruction_t *opcode_timings_dc_mod3[8] = { + /* opFADDr opFMULr*/ + &faddsub_op, &fmul_op, INVALID, INVALID, + /* opFSUBRr opFSUBr opFDIVRr opFDIVr*/ + &faddsub_op, &faddsub_op, &fdiv_op, &fdiv_op}; + +static const p6_instruction_t *opcode_timings_dd[8] = { + /* FLDd FSTd FSTPd*/ + &load_op, INVALID, &store_op, &store_op, + /* FRSTOR FSAVE FSTSW*/ + &frstor_op, INVALID, &fsave_op, &fstsw_mem_op}; +static const p6_instruction_t *opcode_timings_dd_mod3[8] = { + /* FFFREE FST FSTP*/ + &float_op, INVALID, &float_op, &float_op, + /* FUCOM FUCOMP*/ + &float_op, &float_op, INVALID, INVALID}; + +static const p6_instruction_t *opcode_timings_de[8] = { + /* FIADDw FIMULw FICOMw FICOMPw*/ + &load_fi_op, + &load_fi_op, + &load_fcom_op, + &load_fcom_op, + /* FISUBw FISUBRw FIDIVw FIDIVRw*/ + &load_fi_op, + &load_fi_op, + &load_fi_op, + &load_fi_op, +}; +static const p6_instruction_t *opcode_timings_de_mod3[8] = { + /* FADDP FMULP FCOMPP*/ + &faddsub_op, + &fmul_op, + INVALID, + &fcompp_op, + /* FSUBP FSUBRP FDIVP FDIVRP*/ + &faddsub_op, + &faddsub_op, + &fdiv_op, + &fdiv_op, +}; + +static const p6_instruction_t *opcode_timings_df[8] = { + /* FILDiw FISTiw FISTPiw*/ + &fild_op, + INVALID, + &fist_op, + &fist_op, + /* FILDiq FBSTP FISTPiq*/ + INVALID, + &fild_op, + &fbstp_op, + &fist_op, +}; +static const p6_instruction_t *opcode_timings_df_mod3[8] = {INVALID, INVALID, INVALID, INVALID, + /* FSTSW AX*/ + &fstsw_ax_op, INVALID, INVALID, INVALID}; static uint8_t last_prefix; static int prefixes; @@ -1554,116 +1669,99 @@ static int decode_timestamp; static int last_complete_timestamp; typedef struct p6_unit_t { - const uint32_t uop_mask; - const int port; - int first_available_cycle; + const uint32_t uop_mask; + const int port; + int first_available_cycle; } p6_unit_t; -enum { - UNIT_INT0 = 0, - UNIT_INT1, - UNIT_FPU, - UNIT_MMX_ADD, - UNIT_MMX_MUL, - UNIT_JUMP, - UNIT_LOAD, - UNIT_STORE_ADDR, - UNIT_STORE_DATA -}; +enum { UNIT_INT0 = 0, UNIT_INT1, UNIT_FPU, UNIT_MMX_ADD, UNIT_MMX_MUL, UNIT_JUMP, UNIT_LOAD, UNIT_STORE_ADDR, UNIT_STORE_DATA }; /*Each port can only be used once per clock*/ typedef struct p6_port_t { - uint32_t unit_mask; + uint32_t unit_mask; } p6_port_t; static int port_last_timestamps[5]; -static const p6_port_t ports[] = - { - {UNIT_INT0 | UNIT_FPU | UNIT_MMX_MUL}, - {UNIT_INT1 | UNIT_MMX_ADD | UNIT_JUMP}, - {UNIT_LOAD}, - {UNIT_STORE_ADDR}, - {UNIT_STORE_DATA} - }; +static const p6_port_t ports[] = {{UNIT_INT0 | UNIT_FPU | UNIT_MMX_MUL}, + {UNIT_INT1 | UNIT_MMX_ADD | UNIT_JUMP}, + {UNIT_LOAD}, + {UNIT_STORE_ADDR}, + {UNIT_STORE_DATA}}; const int nr_ports = (sizeof(ports) / sizeof(p6_port_t)); -static p6_unit_t units[] = - { - [UNIT_INT0] = {.uop_mask = (1 << UOP_ALU0) | (1 << UOP_ALU0_SEG) | (1 << UOP_ALU01), .port = 0}, /*Integer 0*/ - [UNIT_INT1] = {.uop_mask = (1 << UOP_ALU1) | (1 << UOP_ALU01), .port = 1}, /*Integer 1*/ - [UNIT_FPU] = {.uop_mask = 1 << UOP_FLOAT, .port = 0}, - [UNIT_MMX_ADD] = {.uop_mask = 0, .port = 1}, - [UNIT_MMX_MUL] = {.uop_mask = 0, .port = 0}, - [UNIT_JUMP] = {.uop_mask = 1 << UOP_BRANCH, .port = 1}, - [UNIT_LOAD] = {.uop_mask = 1 << UOP_LOAD, .port = 2}, - [UNIT_STORE_ADDR] = {.uop_mask = 1 << UOP_STOREADDR, .port = 3}, - [UNIT_STORE_DATA] = {.uop_mask = 1 << UOP_STOREDATA, .port = 4} - }; +static p6_unit_t units[] = { + [UNIT_INT0] = {.uop_mask = (1 << UOP_ALU0) | (1 << UOP_ALU0_SEG) | (1 << UOP_ALU01), .port = 0}, /*Integer 0*/ + [UNIT_INT1] = {.uop_mask = (1 << UOP_ALU1) | (1 << UOP_ALU01), .port = 1}, /*Integer 1*/ + [UNIT_FPU] = {.uop_mask = 1 << UOP_FLOAT, .port = 0}, + [UNIT_MMX_ADD] = {.uop_mask = 0, .port = 1}, + [UNIT_MMX_MUL] = {.uop_mask = 0, .port = 0}, + [UNIT_JUMP] = {.uop_mask = 1 << UOP_BRANCH, .port = 1}, + [UNIT_LOAD] = {.uop_mask = 1 << UOP_LOAD, .port = 2}, + [UNIT_STORE_ADDR] = {.uop_mask = 1 << UOP_STOREADDR, .port = 3}, + [UNIT_STORE_DATA] = {.uop_mask = 1 << UOP_STOREDATA, .port = 4}}; const int nr_units = (sizeof(units) / sizeof(p6_unit_t)); static int rat_timestamp = 0; static int rat_uops = 0; static int uop_run(const p6_uop_t *uop, int decode_time) { - int c; - p6_unit_t *best_unit = NULL; - int best_start_cycle = 99999; + int c; + p6_unit_t *best_unit = NULL; + int best_start_cycle = 99999; - /*Peak of 3 uOPs from decode to RAT per cycle*/ - if (decode_time < rat_timestamp) - decode_time = rat_timestamp; - else if (decode_time > rat_timestamp) { - rat_timestamp = decode_time; - rat_uops = 0; - } + /*Peak of 3 uOPs from decode to RAT per cycle*/ + if (decode_time < rat_timestamp) + decode_time = rat_timestamp; + else if (decode_time > rat_timestamp) { + rat_timestamp = decode_time; + rat_uops = 0; + } - rat_uops++; - if (rat_uops == 3) { - rat_timestamp++; - rat_uops = 0; - } + rat_uops++; + if (rat_uops == 3) { + rat_timestamp++; + rat_uops = 0; + } + /*Find execution unit for this uOP*/ + for (c = 0; c < nr_units; c++) { + p6_unit_t *unit = &units[c]; + if (unit->uop_mask & (1 << uop->type)) { + int start_cycle = MAX(unit->first_available_cycle, port_last_timestamps[units[c].port]); - /*Find execution unit for this uOP*/ - for (c = 0; c < nr_units; c++) { - p6_unit_t *unit = &units[c]; - if (unit->uop_mask & (1 << uop->type)) { - int start_cycle = MAX(unit->first_available_cycle, - port_last_timestamps[units[c].port]); + if (start_cycle < best_start_cycle) { + best_unit = unit; + best_start_cycle = start_cycle; + } + } + } + if (!best_unit) + fatal("uop_run: can not find execution unit %x\n", uop->type); - if (start_cycle < best_start_cycle) { - best_unit = unit; - best_start_cycle = start_cycle; - } - } - } - if (!best_unit) - fatal("uop_run: can not find execution unit %x\n", uop->type); + if (cpu_s->cpu_type == CPU_PENTIUMPRO && uop->type == UOP_ALU0_SEG) { + /*Pentium Pro will flush pipeline on a segment load. Find last + execution unit to complete, then set earliest start times on + _all_ execution units to after this point*/ + int last_start_cycle = 0; - if (cpu_s->cpu_type == CPU_PENTIUMPRO && uop->type == UOP_ALU0_SEG) { - /*Pentium Pro will flush pipeline on a segment load. Find last - execution unit to complete, then set earliest start times on - _all_ execution units to after this point*/ - int last_start_cycle = 0; + for (c = 0; c < nr_units; c++) { + p6_unit_t *unit = &units[c]; + int start_cycle = unit->first_available_cycle; - for (c = 0; c < nr_units; c++) { - p6_unit_t *unit = &units[c]; - int start_cycle = unit->first_available_cycle; + if (start_cycle > last_start_cycle) + last_start_cycle = start_cycle; + } + for (c = 0; c < nr_units; c++) + units[c].first_available_cycle = last_start_cycle + 1; + } + if (best_start_cycle < decode_time) + best_start_cycle = decode_time; + best_unit->first_available_cycle = best_start_cycle + uop->throughput; + port_last_timestamps[best_unit->port] = best_start_cycle + 1; - if (start_cycle > last_start_cycle) - last_start_cycle = start_cycle; - } - for (c = 0; c < nr_units; c++) - units[c].first_available_cycle = last_start_cycle + 1; - } - if (best_start_cycle < decode_time) - best_start_cycle = decode_time; - best_unit->first_available_cycle = best_start_cycle + uop->throughput; - port_last_timestamps[best_unit->port] = best_start_cycle + 1; - - return best_start_cycle + uop->throughput; -// return decode_time+1; + return best_start_cycle + uop->throughput; + // return decode_time+1; } /*The P6 decoder can decode up to three instructions per clock @@ -1675,13 +1773,13 @@ static int uop_run(const p6_uop_t *uop, int decode_time) { 0x67 causes delays if modr/m present (and mod != 3) */ static struct { - int nr_ins; - int nr_uops; - const p6_uop_t *uops[6]; - /*Earliest time a uop can start. If the timestamp is -1, then the uop is - part of a dependency chain and the start time is the completion time of - the previous uop*/ - int earliest_start[6]; + int nr_ins; + int nr_uops; + const p6_uop_t *uops[6]; + /*Earliest time a uop can start. If the timestamp is -1, then the uop is + part of a dependency chain and the start time is the completion time of + the previous uop*/ + int earliest_start[6]; } decode_buffer; #define NR_REGS 8 @@ -1697,248 +1795,248 @@ static int ifetch_length = 0; static int has_66_prefix, has_67_prefix; static void decode_flush() { - int c; - int uop_timestamp = 0; + int c; + int uop_timestamp = 0; - /*Ensure that uops can not be submitted before they have been decoded*/ - if (decode_timestamp > last_uop_timestamp) - last_uop_timestamp = decode_timestamp; + /*Ensure that uops can not be submitted before they have been decoded*/ + if (decode_timestamp > last_uop_timestamp) + last_uop_timestamp = decode_timestamp; - /*Submit uops to execution units, and determine the latest completion time*/ - for (c = 0; c < decode_buffer.nr_uops; c++) { - int start_timestamp; + /*Submit uops to execution units, and determine the latest completion time*/ + for (c = 0; c < decode_buffer.nr_uops; c++) { + int start_timestamp; -// pclog("uOP %i, %p\n", c, decode_buffer.uops[c]); + // pclog("uOP %i, %p\n", c, decode_buffer.uops[c]); - if (decode_buffer.earliest_start[c] == -1) - start_timestamp = last_uop_timestamp; - else - start_timestamp = decode_buffer.earliest_start[c]; + if (decode_buffer.earliest_start[c] == -1) + start_timestamp = last_uop_timestamp; + else + start_timestamp = decode_buffer.earliest_start[c]; - last_uop_timestamp = uop_run(decode_buffer.uops[c], start_timestamp); - if (last_uop_timestamp > uop_timestamp) - uop_timestamp = last_uop_timestamp; - } + last_uop_timestamp = uop_run(decode_buffer.uops[c], start_timestamp); + if (last_uop_timestamp > uop_timestamp) + uop_timestamp = last_uop_timestamp; + } - /*Calculate opquad completion time. Since opquads complete in order, it - must be after the last completion.*/ - if (uop_timestamp <= last_complete_timestamp) - last_complete_timestamp = last_complete_timestamp + 1; - else - last_complete_timestamp = uop_timestamp; + /*Calculate opquad completion time. Since opquads complete in order, it + must be after the last completion.*/ + if (uop_timestamp <= last_complete_timestamp) + last_complete_timestamp = last_complete_timestamp + 1; + else + last_complete_timestamp = uop_timestamp; - decode_timestamp++; - decode_buffer.nr_uops = 0; - decode_buffer.nr_ins = 0; - ifetch_length = 0; + decode_timestamp++; + decode_buffer.nr_uops = 0; + decode_buffer.nr_ins = 0; + ifetch_length = 0; } /*The instruction is only of interest here if it's longer than 8 bytes, as that's the limit on P6 short decoding*/ static int codegen_timing_instr_length(uint64_t deps, uint32_t fetchdat, int op_32) { - int len = prefixes + 1; /*Opcode*/ - if (deps & MODRM) { - len++; /*ModR/M*/ - if (deps & HAS_IMM8) - len++; - if (deps & HAS_IMM1632) - len += (op_32 & 0x100) ? 4 : 2; + int len = prefixes + 1; /*Opcode*/ + if (deps & MODRM) { + len++; /*ModR/M*/ + if (deps & HAS_IMM8) + len++; + if (deps & HAS_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; - } - } + 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; + return len; } -static void decode_instruction(const p6_instruction_t *ins, uint64_t deps, uint32_t fetchdat, int op_32, uint32_t op_pc, int bit8) { - uint32_t regmask_required; - uint32_t regmask_modified; - int c, d; - int earliest_start; - int instr_length = codegen_timing_instr_length(deps, fetchdat, op_32); +static void decode_instruction(const p6_instruction_t *ins, uint64_t deps, uint32_t fetchdat, int op_32, uint32_t op_pc, + int bit8) { + uint32_t regmask_required; + uint32_t regmask_modified; + int c, d; + int earliest_start; + int instr_length = codegen_timing_instr_length(deps, fetchdat, op_32); - if (has_66_prefix && (deps & HAS_IMM1632)) - decode_timestamp += 2; - if (has_67_prefix && (deps & MODRM)) - decode_timestamp += 4; + if (has_66_prefix && (deps & HAS_IMM1632)) + decode_timestamp += 2; + if (has_67_prefix && (deps & MODRM)) + decode_timestamp += 4; - earliest_start = decode_timestamp; + earliest_start = decode_timestamp; - /*Generate input register mask, and determine the earliest time this - instruction can start. This is not accurate, as this is calculated per - x86 instruction when it should be handled per uop*/ - regmask_required = get_dstdep_mask(deps, fetchdat, bit8); - regmask_required |= get_addr_regmask(deps, fetchdat, op_32); - for (c = 0; c < 8; c++) { - if (regmask_required & (1 << c)) { - if (reg_available_timestamp[c] > decode_timestamp) - earliest_start = reg_available_timestamp[c]; - } - } - if ((deps & FPU_RW_ST0) && fpu_st_timestamp[0] > decode_timestamp) - earliest_start = fpu_st_timestamp[0]; - if ((deps & FPU_RW_ST1) && fpu_st_timestamp[1] > decode_timestamp) - earliest_start = fpu_st_timestamp[1]; - if ((deps & FPU_RW_STREG)) { - int reg = fetchdat & 7; + /*Generate input register mask, and determine the earliest time this + instruction can start. This is not accurate, as this is calculated per + x86 instruction when it should be handled per uop*/ + regmask_required = get_dstdep_mask(deps, fetchdat, bit8); + regmask_required |= get_addr_regmask(deps, fetchdat, op_32); + for (c = 0; c < 8; c++) { + if (regmask_required & (1 << c)) { + if (reg_available_timestamp[c] > decode_timestamp) + earliest_start = reg_available_timestamp[c]; + } + } + if ((deps & FPU_RW_ST0) && fpu_st_timestamp[0] > decode_timestamp) + earliest_start = fpu_st_timestamp[0]; + if ((deps & FPU_RW_ST1) && fpu_st_timestamp[1] > decode_timestamp) + earliest_start = fpu_st_timestamp[1]; + if ((deps & FPU_RW_STREG)) { + int reg = fetchdat & 7; - if (fpu_st_timestamp[reg] > decode_timestamp) - earliest_start = fpu_st_timestamp[reg]; - } + if (fpu_st_timestamp[reg] > decode_timestamp) + earliest_start = fpu_st_timestamp[reg]; + } -// pclog("ins->nr_uops=%i decode_buffer.nr_uops=%i decode_buffer.nr_ins=%i instr_length=%i\n", ins->nr_uops, decode_buffer.nr_uops, decode_buffer.nr_ins, instr_length); + // pclog("ins->nr_uops=%i decode_buffer.nr_uops=%i decode_buffer.nr_ins=%i instr_length=%i\n", ins->nr_uops, + // decode_buffer.nr_uops, decode_buffer.nr_ins, instr_length); - /*Can only decode 16 bytes per cycle*/ - if ((ifetch_length + instr_length) > 16) - decode_flush(); - else - ifetch_length += instr_length; + /*Can only decode 16 bytes per cycle*/ + if ((ifetch_length + instr_length) > 16) + decode_flush(); + else + ifetch_length += instr_length; - if (ins->nr_uops > 4) { -// pclog("Long decode\n"); - /*Multi-cycle decode (> 4 uOPs) instruction*/ - if (decode_buffer.nr_ins) - decode_flush(); + if (ins->nr_uops > 4) { + // pclog("Long decode\n"); + /*Multi-cycle decode (> 4 uOPs) instruction*/ + if (decode_buffer.nr_ins) + decode_flush(); - d = 0; + d = 0; - for (c = 0; c < ins->nr_uops; c++) { - decode_buffer.uops[d] = &ins->uop[c]; - if (c == 0) - decode_buffer.earliest_start[d] = earliest_start; - else - decode_buffer.earliest_start[d] = -1; - d++; + for (c = 0; c < ins->nr_uops; c++) { + decode_buffer.uops[d] = &ins->uop[c]; + if (c == 0) + decode_buffer.earliest_start[d] = earliest_start; + else + decode_buffer.earliest_start[d] = -1; + d++; - if (d == 4) { - d = 0; - decode_buffer.nr_uops = 4; - decode_flush(); - } - } - if (d) { - decode_buffer.nr_uops = d; - decode_flush(); - } - } else if (ins->nr_uops > 1 || instr_length > 8) { -// pclog("Mid decode\n"); - /*Long (> 1 uOPs) instruction*/ - if (decode_buffer.nr_ins) - decode_flush(); + if (d == 4) { + d = 0; + decode_buffer.nr_uops = 4; + decode_flush(); + } + } + if (d) { + decode_buffer.nr_uops = d; + decode_flush(); + } + } else if (ins->nr_uops > 1 || instr_length > 8) { + // pclog("Mid decode\n"); + /*Long (> 1 uOPs) instruction*/ + if (decode_buffer.nr_ins) + decode_flush(); - decode_buffer.nr_uops = ins->nr_uops; + decode_buffer.nr_uops = ins->nr_uops; - for (c = 0; c < ins->nr_uops; c++) { - decode_buffer.uops[c] = &ins->uop[c]; - if (c == 0) - decode_buffer.earliest_start[c] = earliest_start; - else - decode_buffer.earliest_start[c] = -1; - } - decode_buffer.nr_ins++; - } else if (ins->nr_uops == 1) { -// pclog("Short decode\n"); - /*Short (1 uOP) instruction*/ - decode_buffer.uops[decode_buffer.nr_uops] = &ins->uop[0]; - decode_buffer.earliest_start[decode_buffer.nr_uops] = earliest_start; - decode_buffer.nr_ins++; - decode_buffer.nr_uops++; + for (c = 0; c < ins->nr_uops; c++) { + decode_buffer.uops[c] = &ins->uop[c]; + if (c == 0) + decode_buffer.earliest_start[c] = earliest_start; + else + decode_buffer.earliest_start[c] = -1; + } + decode_buffer.nr_ins++; + } else if (ins->nr_uops == 1) { + // pclog("Short decode\n"); + /*Short (1 uOP) instruction*/ + decode_buffer.uops[decode_buffer.nr_uops] = &ins->uop[0]; + decode_buffer.earliest_start[decode_buffer.nr_uops] = earliest_start; + decode_buffer.nr_ins++; + decode_buffer.nr_uops++; - if (decode_buffer.nr_ins == 3) - decode_flush(); - } + if (decode_buffer.nr_ins == 3) + decode_flush(); + } - /*Update write timestamps for any output registers*/ - regmask_modified = get_dstdep_mask(deps, fetchdat, bit8); - for (c = 0; c < 8; c++) { - if (regmask_modified & (1 << c)) - reg_available_timestamp[c] = last_complete_timestamp; - } - if (deps & FPU_POP) { - for (c = 0; c < 7; c++) - fpu_st_timestamp[c] = fpu_st_timestamp[c + 1]; - fpu_st_timestamp[7] = 0; - } - if (deps & FPU_POP2) { - for (c = 0; c < 6; c++) - fpu_st_timestamp[c] = fpu_st_timestamp[c + 2]; - fpu_st_timestamp[6] = fpu_st_timestamp[7] = 0; - } - if (deps & FPU_PUSH) { - for (c = 0; c < 7; c++) - fpu_st_timestamp[c + 1] = fpu_st_timestamp[c]; - fpu_st_timestamp[0] = 0; - } - if (deps & FPU_WRITE_ST0) - fpu_st_timestamp[0] = last_complete_timestamp; - if (deps & FPU_WRITE_ST1) - fpu_st_timestamp[1] = last_complete_timestamp; - if (deps & FPU_WRITE_STREG) { - int reg = fetchdat & 7; - if (deps & FPU_POP) - reg--; - if (reg >= 0 && - !(reg == 0 && (deps & FPU_WRITE_ST0)) && - !(reg == 1 && (deps & FPU_WRITE_ST1))) - fpu_st_timestamp[reg] = last_complete_timestamp; - } + /*Update write timestamps for any output registers*/ + regmask_modified = get_dstdep_mask(deps, fetchdat, bit8); + for (c = 0; c < 8; c++) { + if (regmask_modified & (1 << c)) + reg_available_timestamp[c] = last_complete_timestamp; + } + if (deps & FPU_POP) { + for (c = 0; c < 7; c++) + fpu_st_timestamp[c] = fpu_st_timestamp[c + 1]; + fpu_st_timestamp[7] = 0; + } + if (deps & FPU_POP2) { + for (c = 0; c < 6; c++) + fpu_st_timestamp[c] = fpu_st_timestamp[c + 2]; + fpu_st_timestamp[6] = fpu_st_timestamp[7] = 0; + } + if (deps & FPU_PUSH) { + for (c = 0; c < 7; c++) + fpu_st_timestamp[c + 1] = fpu_st_timestamp[c]; + fpu_st_timestamp[0] = 0; + } + if (deps & FPU_WRITE_ST0) + fpu_st_timestamp[0] = last_complete_timestamp; + if (deps & FPU_WRITE_ST1) + fpu_st_timestamp[1] = last_complete_timestamp; + if (deps & FPU_WRITE_STREG) { + int reg = fetchdat & 7; + if (deps & FPU_POP) + reg--; + if (reg >= 0 && !(reg == 0 && (deps & FPU_WRITE_ST0)) && !(reg == 1 && (deps & FPU_WRITE_ST1))) + fpu_st_timestamp[reg] = last_complete_timestamp; + } } void codegen_timing_p6_block_start() { - int c; + int c; - for (c = 0; c < nr_units; c++) - units[c].first_available_cycle = 0; + for (c = 0; c < nr_units; c++) + units[c].first_available_cycle = 0; - decode_timestamp = 0; - last_complete_timestamp = 0; + decode_timestamp = 0; + last_complete_timestamp = 0; - rat_timestamp = 0; - rat_uops = 0; + rat_timestamp = 0; + rat_uops = 0; - for (c = 0; c < 5; c++) - port_last_timestamps[c] = 0; + for (c = 0; c < 5; c++) + port_last_timestamps[c] = 0; - for (c = 0; c < NR_REGS; c++) - reg_available_timestamp[c] = 0; - for (c = 0; c < 8; c++) - fpu_st_timestamp[c] = 0; + for (c = 0; c < NR_REGS; c++) + reg_available_timestamp[c] = 0; + for (c = 0; c < 8; c++) + fpu_st_timestamp[c] = 0; - ifetch_length = 0; + ifetch_length = 0; } void codegen_timing_p6_start() { -// units = p6_units; -// nr_units = NR_P6_UNITS; - last_prefix = 0; - prefixes = 0; - has_66_prefix = 0; - has_67_prefix = 0; + // units = p6_units; + // nr_units = NR_P6_UNITS; + last_prefix = 0; + prefixes = 0; + has_66_prefix = 0; + has_67_prefix = 0; } /*Prefixes : @@ -1947,146 +2045,154 @@ void codegen_timing_p6_start() { 32 bit immediate - address size prefix has penalty if instruction has explicit memory operand*/ void codegen_timing_p6_prefix(uint8_t prefix, uint32_t fetchdat) { - if (last_prefix) /*First prefix is free*/ - decode_timestamp++; - if (prefix == 0x66) - has_66_prefix = 1; - if (prefix == 0x67) - has_67_prefix = 1; + if (last_prefix) /*First prefix is free*/ + decode_timestamp++; + if (prefix == 0x66) + has_66_prefix = 1; + if (prefix == 0x67) + has_67_prefix = 1; - last_prefix = prefix; - prefixes++; + last_prefix = prefix; + prefixes++; } void codegen_timing_p6_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc) { - const p6_instruction_t **ins_table; - uint64_t *deps; - int mod3 = ((fetchdat & 0xc0) == 0xc0); - int old_last_complete_timestamp = last_complete_timestamp; - int bit8 = !(opcode & 1); + const p6_instruction_t **ins_table; + uint64_t *deps; + int mod3 = ((fetchdat & 0xc0) == 0xc0); + int old_last_complete_timestamp = last_complete_timestamp; + int bit8 = !(opcode & 1); -// pclog("timing_opcode %02x\n", opcode); - switch (last_prefix) { - case 0x0f:ins_table = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; - deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; -// pclog("timings 0f\n"); - break; + // pclog("timing_opcode %02x\n", opcode); + switch (last_prefix) { + case 0x0f: + ins_table = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; + deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; + // pclog("timings 0f\n"); + break; - case 0xd8:ins_table = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8; - deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8; - opcode = (opcode >> 3) & 7; -// pclog("timings d8\n"); - break; - case 0xd9:ins_table = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9; - deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9; - opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; -// pclog("timings d9\n"); - break; - case 0xda:ins_table = mod3 ? opcode_timings_da_mod3 : opcode_timings_da; - deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da; - opcode = (opcode >> 3) & 7; -// pclog("timings da\n"); - break; - case 0xdb:ins_table = mod3 ? opcode_timings_db_mod3 : opcode_timings_db; - deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db; - opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; -// pclog("timings db\n"); - break; - case 0xdc:ins_table = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc; - deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc; - opcode = (opcode >> 3) & 7; -// pclog("timings dc\n"); - break; - case 0xdd:ins_table = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd; - deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd; - opcode = (opcode >> 3) & 7; -// pclog("timings dd\n"); - break; - case 0xde:ins_table = mod3 ? opcode_timings_de_mod3 : opcode_timings_de; - deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de; - opcode = (opcode >> 3) & 7; -// pclog("timings de\n"); - break; - case 0xdf:ins_table = mod3 ? opcode_timings_df_mod3 : opcode_timings_df; - deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df; - opcode = (opcode >> 3) & 7; -// pclog("timings df\n"); - break; + case 0xd8: + ins_table = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8; + deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8; + opcode = (opcode >> 3) & 7; + // pclog("timings d8\n"); + break; + case 0xd9: + ins_table = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9; + deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9; + opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; + // pclog("timings d9\n"); + break; + case 0xda: + ins_table = mod3 ? opcode_timings_da_mod3 : opcode_timings_da; + deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da; + opcode = (opcode >> 3) & 7; + // pclog("timings da\n"); + break; + case 0xdb: + ins_table = mod3 ? opcode_timings_db_mod3 : opcode_timings_db; + deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db; + opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; + // pclog("timings db\n"); + break; + case 0xdc: + ins_table = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc; + deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc; + opcode = (opcode >> 3) & 7; + // pclog("timings dc\n"); + break; + case 0xdd: + ins_table = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd; + deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd; + opcode = (opcode >> 3) & 7; + // pclog("timings dd\n"); + break; + case 0xde: + ins_table = mod3 ? opcode_timings_de_mod3 : opcode_timings_de; + deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de; + opcode = (opcode >> 3) & 7; + // pclog("timings de\n"); + break; + case 0xdf: + ins_table = mod3 ? opcode_timings_df_mod3 : opcode_timings_df; + deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df; + opcode = (opcode >> 3) & 7; + // pclog("timings df\n"); + break; - default: - switch (opcode) { - case 0x80: - case 0x81: - case 0x82: - case 0x83:ins_table = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x; - deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x; - opcode = (fetchdat >> 3) & 7; -// pclog("timings 80 %p %p %p\n", (void *)timings, (void *)opcode_timings_mod3, (void *)opcode_timings_8x); - break; + default: + switch (opcode) { + case 0x80: + case 0x81: + case 0x82: + case 0x83: + ins_table = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x; + deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x; + opcode = (fetchdat >> 3) & 7; + // pclog("timings 80 %p %p %p\n", (void *)timings, (void *)opcode_timings_mod3, + // (void *)opcode_timings_8x); + break; - case 0xc0: - case 0xd0: - case 0xd2: - case 0xc1: - case 0xd1: - case 0xd3:ins_table = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; - deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; - opcode = (fetchdat >> 3) & 7; -// pclog("timings c1\n"); - break; + case 0xc0: + case 0xd0: + case 0xd2: + case 0xc1: + case 0xd1: + case 0xd3: + ins_table = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; + deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift; + opcode = (fetchdat >> 3) & 7; + // pclog("timings c1\n"); + break; - case 0xf6:ins_table = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6; - deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6; - opcode = (fetchdat >> 3) & 7; -// pclog("timings f6\n"); - break; - case 0xf7:ins_table = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7; - deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7; - opcode = (fetchdat >> 3) & 7; -// pclog("timings f7\n"); - break; - case 0xff:ins_table = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff; - deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff; - opcode = (fetchdat >> 3) & 7; -// pclog("timings ff\n"); - break; + case 0xf6: + ins_table = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6; + deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6; + opcode = (fetchdat >> 3) & 7; + // pclog("timings f6\n"); + break; + case 0xf7: + ins_table = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7; + deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7; + opcode = (fetchdat >> 3) & 7; + // pclog("timings f7\n"); + break; + case 0xff: + ins_table = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff; + deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff; + opcode = (fetchdat >> 3) & 7; + // pclog("timings ff\n"); + break; - default:ins_table = mod3 ? opcode_timings_mod3 : opcode_timings; - deps = mod3 ? opcode_deps_mod3 : opcode_deps; -// pclog("timings normal\n"); - break; - } - } + default: + ins_table = mod3 ? opcode_timings_mod3 : opcode_timings; + deps = mod3 ? opcode_deps_mod3 : opcode_deps; + // pclog("timings normal\n"); + break; + } + } - if (ins_table[opcode]) - decode_instruction(ins_table[opcode], deps[opcode], fetchdat, op_32, op_pc, bit8); - else - decode_instruction(&alu01_op, 0, fetchdat, op_32, op_pc, bit8); - codegen_block_cycles += (last_complete_timestamp - old_last_complete_timestamp); + if (ins_table[opcode]) + decode_instruction(ins_table[opcode], deps[opcode], fetchdat, op_32, op_pc, bit8); + else + decode_instruction(&alu01_op, 0, fetchdat, op_32, op_pc, bit8); + codegen_block_cycles += (last_complete_timestamp - old_last_complete_timestamp); } void codegen_timing_p6_block_end() { - if (decode_buffer.nr_ins) { - int old_last_complete_timestamp = last_complete_timestamp; - decode_flush(); - codegen_block_cycles += (last_complete_timestamp - old_last_complete_timestamp); - } -// pclog("codegen_block_cycles=%i\n", codegen_block_cycles); + if (decode_buffer.nr_ins) { + int old_last_complete_timestamp = last_complete_timestamp; + decode_flush(); + codegen_block_cycles += (last_complete_timestamp - old_last_complete_timestamp); + } + // pclog("codegen_block_cycles=%i\n", codegen_block_cycles); } int codegen_timing_p6_jump_cycles() { - if (decode_buffer.nr_uops) - return 1; - return 0; + if (decode_buffer.nr_uops) + return 1; + return 0; } -codegen_timing_t codegen_timing_p6 = - { - codegen_timing_p6_start, - codegen_timing_p6_prefix, - codegen_timing_p6_opcode, - codegen_timing_p6_block_start, - codegen_timing_p6_block_end, - codegen_timing_p6_jump_cycles - }; - +codegen_timing_t codegen_timing_p6 = {codegen_timing_p6_start, codegen_timing_p6_prefix, codegen_timing_p6_opcode, + codegen_timing_p6_block_start, codegen_timing_p6_block_end, codegen_timing_p6_jump_cycles}; diff --git a/src/codegen/codegen_timing_pentium.c b/src/codegen/codegen_timing_pentium.c index 5e498d85..5ef53b04 100644 --- a/src/codegen/codegen_timing_pentium.c +++ b/src/codegen/codegen_timing_pentium.c @@ -20,8 +20,6 @@ #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) @@ -30,36 +28,33 @@ /*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} - }; +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_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_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) +#define PAIR_U (1ull << 29) /*Instruction pairs in V pipe only*/ -#define PAIR_V (2ull << 29) +#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*/ @@ -71,11 +66,11 @@ static int pair_timings[4][4] = #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_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) @@ -105,1172 +100,1581 @@ 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 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_has_feature(CPU_FEATURE_MMX) ? 1 : 2; - } + 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_has_feature(CPU_FEATURE_MMX) ? 1 : 2; + } - fatal("Illegal COUNT %016llx\n", timings); + fatal("Illegal COUNT %016llx\n", timings); - return timings; + return timings; } static int codegen_fpu_latencies(uint64_t deps, int reg) { - int latency = fpu_latency; + 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]; + 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; + return latency; } -#define SUB_AND_CLAMP(latency, count) \ - latency -= count; \ - if (latency < 0) \ - latency = 0 +#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); + 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; + 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; + 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; - } - } + 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; + return len; } -void codegen_timing_pentium_block_start() { - u_pipe_full = decode_delay = decode_delay_offset = 0; -} +void codegen_timing_pentium_block_start() { u_pipe_full = decode_delay = decode_delay_offset = 0; } void codegen_timing_pentium_start() { -// decode_delay = 0; - last_prefix = 0; - prefixes = 0; + // decode_delay = 0; + 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_has_feature(CPU_FEATURE_MMX) && prefix == 0x0f) { - /*On Pentium MMX 0fh prefix is 'free'*/ - last_prefix = prefix; - return; - } - if (cpu_has_feature(CPU_FEATURE_MMX) && (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; + prefixes++; + if ((prefix & 0xf8) == 0xd8) { + last_prefix = prefix; + return; + } + if (cpu_has_feature(CPU_FEATURE_MMX) && prefix == 0x0f) { + /*On Pentium MMX 0fh prefix is 'free'*/ + last_prefix = prefix; + return; + } + if (cpu_has_feature(CPU_FEATURE_MMX) && (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); + 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); + /*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; + 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; +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 ((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; + 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; + decode_delay = (-instr_cycles) + 1; - if (deps[opcode] & FPU_POP) { - int c; + 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 < 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]); - } + 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; + 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]); - } - } + 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, uint32_t op_pc) { - uint64_t *timings; - uint64_t *deps; - int mod3 = ((fetchdat & 0xc0) == 0xc0); - int bit8 = !(opcode & 1); - int agi_stall = 0; + 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; -// pclog("timings 0f\n"); - break; + switch (last_prefix) { + case 0x0f: + timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; + deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; + // pclog("timings 0f\n"); + 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; -// pclog("timings d8\n"); - break; - case 0xd9:timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9; - deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9; -// pclog("timings d9\n"); - 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; -// pclog("timings da\n"); - 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; -// pclog("timings db\n"); - 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; -// pclog("timings dc\n"); - 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; -// pclog("timings dd\n"); - 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; -// pclog("timings de\n"); - 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; -// pclog("timings df\n"); - 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; + // pclog("timings d8\n"); + break; + case 0xd9: + timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9; + deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9; + // pclog("timings d9\n"); + 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; + // pclog("timings da\n"); + 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; + // pclog("timings db\n"); + 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; + // pclog("timings dc\n"); + 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; + // pclog("timings dd\n"); + 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; + // pclog("timings de\n"); + 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; + // pclog("timings df\n"); + 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; -// pclog("timings 80 %p %p %p\n", (void *)timings, (void *)opcode_timings_mod3, (void *)opcode_timings_8x); - 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; -// pclog("timings 80 %p %p %p\n", (void *)timings, (void *)opcode_timings_mod3, (void *)opcode_timings_8x); - 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; + // pclog("timings 80 %p %p %p\n", (void *)timings, (void *)opcode_timings_mod3, + // (void *)opcode_timings_8x); + 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; + // pclog("timings 80 %p %p %p\n", (void *)timings, (void *)opcode_timings_mod3, + // (void *)opcode_timings_8x); + 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; -// pclog("timings c0\n"); - 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; + // pclog("timings c0\n"); + 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; -// pclog("timings d2\n"); - 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; + // pclog("timings d2\n"); + 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; -// pclog("timings f6\n"); - 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; -// pclog("timings f7\n"); - 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; -// pclog("timings ff\n"); - 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; + // pclog("timings f6\n"); + 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; + // pclog("timings f7\n"); + 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; + // pclog("timings ff\n"); + break; - default:timings = mod3 ? opcode_timings_mod3 : opcode_timings; - deps = mod3 ? opcode_deps_mod3 : opcode_deps; -// pclog("timings normal\n"); - break; - } - } + default: + timings = mod3 ? opcode_timings_mod3 : opcode_timings; + deps = mod3 ? opcode_deps_mod3 : opcode_deps; + // pclog("timings normal\n"); + break; + } + } - if (u_pipe_full) { - uint8_t regmask = get_srcdep_mask(deps[opcode], fetchdat, bit8, u_pipe_op_32); + 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 ((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 ((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 ((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; + 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); + 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; + 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; - } + 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] & 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 (timings[opcode] & CYCLES_HASIMM) + has_displacement = codegen_timing_has_displacement(fetchdat, op_32); + else + has_displacement = 0; - if (!has_displacement && (!cpu_has_feature(CPU_FEATURE_MMX) || 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 (!has_displacement && (!cpu_has_feature(CPU_FEATURE_MMX) || + 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 (!(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"); + 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); + 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; + /*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; - } + 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] & 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 (timings[opcode] & CYCLES_HASIMM) + has_displacement = codegen_timing_has_displacement(fetchdat, op_32); + else + has_displacement = 0; - if ((!has_displacement || cpu_has_feature(CPU_FEATURE_MMX)) && (!cpu_has_feature(CPU_FEATURE_MMX) || 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; + if ((!has_displacement || cpu_has_feature(CPU_FEATURE_MMX)) && + (!cpu_has_feature(CPU_FEATURE_MMX) || 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; - } + 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; + } } -int codegen_timing_pentium_jump_cycles() { - return 0; -} +int codegen_timing_pentium_jump_cycles() { return 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, - codegen_timing_pentium_jump_cycles - }; +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, codegen_timing_pentium_jump_cycles}; diff --git a/src/codegen/codegen_timing_winchip.c b/src/codegen/codegen_timing_winchip.c index 4b6a82d3..52a52c02 100644 --- a/src/codegen/codegen_timing_winchip.c +++ b/src/codegen/codegen_timing_winchip.c @@ -11,412 +11,1368 @@ #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), +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, + /*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, + /*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 - }; + /*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), +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, + /*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, + /*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 - }; + /*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, +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, + /*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), + /*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, + /*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, + /*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), + /*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, - }; + /*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_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_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_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_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_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_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[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) - }; + { + /* 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_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_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_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 *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; + 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_block_start() { regmask_modified = 0; } void codegen_timing_winchip_start() { - timing_count = 0; - last_prefix = 0; + 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; + timing_count += COUNT(opcode_timings[prefix], 0); + last_prefix = prefix; } void codegen_timing_winchip_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc) { - int **timings; - uint64_t *deps; - int mod3 = ((fetchdat & 0xc0) == 0xc0); - int bit8 = !(opcode & 1); + 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; -// pclog("timings 0f\n"); - break; + switch (last_prefix) { + case 0x0f: + timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; + deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; + // pclog("timings 0f\n"); + 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; -// pclog("timings d8\n"); - 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; -// pclog("timings d9\n"); - 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; -// pclog("timings da\n"); - 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; -// pclog("timings db\n"); - 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; -// pclog("timings dc\n"); - 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; -// pclog("timings dd\n"); - 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; -// pclog("timings de\n"); - 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; -// pclog("timings df\n"); - 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; + // pclog("timings d8\n"); + 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; + // pclog("timings d9\n"); + 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; + // pclog("timings da\n"); + 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; + // pclog("timings db\n"); + 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; + // pclog("timings dc\n"); + 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; + // pclog("timings dd\n"); + 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; + // pclog("timings de\n"); + 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; + // pclog("timings df\n"); + 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; -// pclog("timings 80 %p %p %p\n", (void *)timings, (void *)opcode_timings_mod3, (void *)opcode_timings_8x); - 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; -// pclog("timings 80 %p %p %p\n", (void *)timings, (void *)opcode_timings_mod3, (void *)opcode_timings_8x); - 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; + // pclog("timings 80 %p %p %p\n", (void *)timings, (void *)opcode_timings_mod3, + // (void *)opcode_timings_8x); + 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; + // pclog("timings 80 %p %p %p\n", (void *)timings, (void *)opcode_timings_mod3, + // (void *)opcode_timings_8x); + 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; -// pclog("timings c0\n"); - 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; + // pclog("timings c0\n"); + 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; -// pclog("timings f6\n"); - 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; -// pclog("timings f7\n"); - 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; -// pclog("timings ff\n"); - 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; + // pclog("timings f6\n"); + 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; + // pclog("timings f7\n"); + 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; + // pclog("timings ff\n"); + break; - default:timings = mod3 ? opcode_timings_mod3 : opcode_timings; - deps = mod3 ? opcode_deps_mod3 : opcode_deps; -// pclog("timings normal\n"); - break; - } - } + default: + timings = mod3 ? opcode_timings_mod3 : opcode_timings; + deps = mod3 ? opcode_deps_mod3 : opcode_deps; + // pclog("timings normal\n"); + 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; + 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); + regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8); } -void codegen_timing_winchip_block_end() { -} +void codegen_timing_winchip_block_end() {} -int codegen_timing_winchip_jump_cycles() { - return 0; -} +int codegen_timing_winchip_jump_cycles() { return 0; } -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, - codegen_timing_winchip_jump_cycles - }; +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, codegen_timing_winchip_jump_cycles}; diff --git a/src/codegen/codegen_timing_winchip2.c b/src/codegen/codegen_timing_winchip2.c index a107c840..df621720 100644 --- a/src/codegen/codegen_timing_winchip2.c +++ b/src/codegen/codegen_timing_winchip2.c @@ -22,15 +22,15 @@ #define CYCLES_FPU (1 << 30) -#define CYCLES_IS_MMX_MUL (1 << 29) +#define CYCLES_IS_MMX_MUL (1 << 29) #define CYCLES_IS_MMX_SHIFT (1 << 28) -#define CYCLES_IS_MMX_ANY (1 << 27) -#define CYCLES_IS_3DNOW (1 << 26) +#define CYCLES_IS_MMX_ANY (1 << 27) +#define CYCLES_IS_3DNOW (1 << 26) -#define CYCLES_MMX_MUL(c) (CYCLES_IS_MMX_MUL | c) +#define CYCLES_MMX_MUL(c) (CYCLES_IS_MMX_MUL | c) #define CYCLES_MMX_SHIFT(c) (CYCLES_IS_MMX_SHIFT | c) -#define CYCLES_MMX_ANY(c) (CYCLES_IS_MMX_ANY | c) -#define CYCLES_3DNOW(c) (CYCLES_IS_3DNOW | c) +#define CYCLES_MMX_ANY(c) (CYCLES_IS_MMX_ANY | c) +#define CYCLES_3DNOW(c) (CYCLES_IS_3DNOW | c) #define CYCLES_IS_MMX (CYCLES_IS_MMX_MUL | CYCLES_IS_MMX_SHIFT | CYCLES_IS_MMX_ANY | CYCLES_IS_3DNOW) @@ -56,320 +56,803 @@ #define INVALID 0 -static uint32_t opcode_timings[256] = - { -/*00*/ CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(2), INVALID, -/*10*/ CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), -/*20*/ CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(3), -/*30*/ CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), +static uint32_t opcode_timings[256] = { + /*00*/ CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), + CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(2), INVALID, + /*10*/ CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), + CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), + /*20*/ CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(3), + CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(3), + /*30*/ CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), + CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), -/*40*/ 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), -/*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(1), CYCLES(1), CYCLES(1), CYCLES2(17, 25), CYCLES(1), CYCLES2(17, 20), CYCLES(17), CYCLES(17), CYCLES(17), CYCLES(17), -/*70*/ 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), + /*40*/ 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), + /*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(1), CYCLES(1), + CYCLES(1), CYCLES2(17, 25), CYCLES(1), CYCLES2(17, 20), CYCLES(17), CYCLES(17), CYCLES(17), CYCLES(17), + /*70*/ 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), -/*80*/ CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), 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*/ 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), + /*80*/ CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), 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*/ 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), -/*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), CYCLES(0), CYCLES(0), CYCLES(3), CYCLES(0), -/*d0*/ CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(15), CYCLES(14), CYCLES(2), CYCLES(4), INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, -/*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), INVALID, INVALID, CYCLES(2), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(3), INVALID - }; + /*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), CYCLES(0), CYCLES(0), CYCLES(3), CYCLES(0), + /*d0*/ CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(15), CYCLES(14), CYCLES(2), CYCLES(4), + INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, + /*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), INVALID, INVALID, + CYCLES(2), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(3), INVALID}; -static uint32_t opcode_timings_mod3[256] = - { -/*00*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), INVALID, -/*10*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), -/*20*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(3), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(3), -/*30*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), +static uint32_t opcode_timings_mod3[256] = { + /*00*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), + CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), INVALID, + /*10*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), + CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), CYCLES(3), + /*20*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(3), + CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(3), + /*30*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), + CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(2), -/*40*/ 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), -/*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(1), CYCLES(1), CYCLES(1), CYCLES2(14, 25), CYCLES(1), CYCLES2(17, 20), CYCLES(17), CYCLES(17), CYCLES(17), CYCLES(17), -/*70*/ 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), + /*40*/ 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), + /*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(1), CYCLES(1), + CYCLES(1), CYCLES2(14, 25), CYCLES(1), CYCLES2(17, 20), CYCLES(17), CYCLES(17), CYCLES(17), CYCLES(17), + /*70*/ 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), -/*80*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), 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*/ 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), + /*80*/ CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), 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*/ 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), -/*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), CYCLES(0), CYCLES(0), CYCLES(3), CYCLES(0), -/*d0*/ CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(15), CYCLES(14), CYCLES(2), CYCLES(4), INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, -/*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), INVALID, INVALID, CYCLES(2), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(3), INVALID, - }; + /*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), CYCLES(0), CYCLES(0), CYCLES(3), CYCLES(0), + /*d0*/ CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(4), CYCLES(15), CYCLES(14), CYCLES(2), CYCLES(4), + INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, + /*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), INVALID, INVALID, + CYCLES(2), CYCLES(2), CYCLES(3), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(3), INVALID, +}; -static uint32_t opcode_timings_0f[256] = - { -/*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), INVALID, CYCLES(195), CYCLES(7), INVALID, CYCLES(1000), CYCLES(10000), INVALID, INVALID, INVALID, CYCLES_3DNOW(1), CYCLES(1), CYCLES_3DNOW(1), -/*10*/ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, -/*20*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, -/*30*/ CYCLES(9), CYCLES(1), CYCLES(9), INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, +static uint32_t opcode_timings_0f[256] = { + /*00*/ CYCLES(20), + CYCLES(11), + CYCLES(11), + CYCLES(10), + INVALID, + CYCLES(195), + CYCLES(7), + INVALID, + CYCLES(1000), + CYCLES(10000), + INVALID, + INVALID, + INVALID, + CYCLES_3DNOW(1), + CYCLES(1), + CYCLES_3DNOW(1), + /*10*/ INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + /*20*/ CYCLES(6), + CYCLES(6), + CYCLES(6), + CYCLES(6), + CYCLES(6), + CYCLES(6), + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + /*30*/ CYCLES(9), + CYCLES(1), + 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*/ CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), - CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), INVALID, INVALID, CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), -/*70*/ INVALID, CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), CYCLES(100), INVALID, INVALID, INVALID, INVALID, INVALID, - INVALID, CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), + /*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*/ CYCLES_MMX_SHIFT(2), + CYCLES_MMX_SHIFT(2), + CYCLES_MMX_SHIFT(2), + CYCLES_MMX_SHIFT(2), + CYCLES_MMX_ANY(2), + CYCLES_MMX_ANY(2), + CYCLES_MMX_ANY(2), + CYCLES_MMX_SHIFT(2), + CYCLES_MMX_SHIFT(2), + CYCLES_MMX_SHIFT(2), + CYCLES_MMX_SHIFT(2), + CYCLES_MMX_SHIFT(2), + INVALID, + INVALID, + CYCLES_MMX_ANY(2), + CYCLES_MMX_ANY(2), + /*70*/ INVALID, + CYCLES_MMX_SHIFT(2), + CYCLES_MMX_SHIFT(2), + CYCLES_MMX_SHIFT(2), + CYCLES_MMX_ANY(2), + CYCLES_MMX_ANY(2), + CYCLES_MMX_ANY(2), + CYCLES(100), + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + CYCLES_MMX_ANY(2), + CYCLES_MMX_ANY(2), -/*80*/ 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), -/*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), INVALID, INVALID, CYCLES(3), CYCLES(3), INVALID, CYCLES(13), CYCLES(3), CYCLES(3), INVALID, CYCLES2(18, 30), -/*b0*/ CYCLES(10), CYCLES(10), CYCLES(6), CYCLES(13), CYCLES(6), CYCLES(6), CYCLES(3), CYCLES(3), INVALID, INVALID, CYCLES(6), CYCLES(13), CYCLES(7), CYCLES(7), CYCLES(3), CYCLES(3), + /*80*/ 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), + /*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), + INVALID, + INVALID, + CYCLES(3), + CYCLES(3), + INVALID, + CYCLES(13), + CYCLES(3), + CYCLES(3), + INVALID, + CYCLES2(18, 30), + /*b0*/ CYCLES(10), + CYCLES(10), + CYCLES(6), + CYCLES(13), + CYCLES(6), + CYCLES(6), + CYCLES(3), + CYCLES(3), + INVALID, + INVALID, + CYCLES(6), + CYCLES(13), + CYCLES(7), + CYCLES(7), + CYCLES(3), + CYCLES(3), -/*c0*/ CYCLES(4), CYCLES(4), INVALID, INVALID, INVALID, INVALID, INVALID, CYCLES(3), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), -/*d0*/ INVALID, CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), INVALID, CYCLES_MMX_MUL(2), INVALID, INVALID, CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), INVALID, CYCLES_MMX_ANY(2), - CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), INVALID, CYCLES_MMX_ANY(2), -/*e0*/ INVALID, CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), INVALID, INVALID, CYCLES_MMX_MUL(2), INVALID, INVALID, CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), INVALID, CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), - CYCLES_MMX_ANY(2), INVALID, CYCLES_MMX_ANY(2), -/*f0*/ INVALID, CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), CYCLES_MMX_SHIFT(2), INVALID, CYCLES_MMX_MUL(2), INVALID, INVALID, CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), INVALID, - CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), CYCLES_MMX_ANY(2), INVALID, - }; -static uint32_t opcode_timings_0f_mod3[256] = - { -/*00*/ CYCLES(20), CYCLES(11), CYCLES(11), CYCLES(10), INVALID, CYCLES(195), CYCLES(7), INVALID, CYCLES(1000), CYCLES(10000), INVALID, INVALID, INVALID, CYCLES_3DNOW(1), CYCLES(1), CYCLES_3DNOW(1), -/*10*/ INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, -/*20*/ CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), CYCLES(6), INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, -/*30*/ CYCLES(9), CYCLES(1), CYCLES(9), INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, + /*c0*/ CYCLES(4), + CYCLES(4), + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + CYCLES(3), + CYCLES(1), + CYCLES(1), + CYCLES(1), + CYCLES(1), + CYCLES(1), + CYCLES(1), + CYCLES(1), + CYCLES(1), + /*d0*/ INVALID, + CYCLES_MMX_SHIFT(2), + CYCLES_MMX_SHIFT(2), + CYCLES_MMX_SHIFT(2), + INVALID, + CYCLES_MMX_MUL(2), + INVALID, + INVALID, + CYCLES_MMX_ANY(2), + CYCLES_MMX_ANY(2), + INVALID, + CYCLES_MMX_ANY(2), + CYCLES_MMX_ANY(2), + CYCLES_MMX_ANY(2), + INVALID, + CYCLES_MMX_ANY(2), + /*e0*/ INVALID, + CYCLES_MMX_SHIFT(2), + CYCLES_MMX_SHIFT(2), + INVALID, + INVALID, + CYCLES_MMX_MUL(2), + INVALID, + INVALID, + CYCLES_MMX_ANY(2), + CYCLES_MMX_ANY(2), + INVALID, + CYCLES_MMX_ANY(2), + CYCLES_MMX_ANY(2), + CYCLES_MMX_ANY(2), + INVALID, + CYCLES_MMX_ANY(2), + /*f0*/ INVALID, + CYCLES_MMX_SHIFT(2), + CYCLES_MMX_SHIFT(2), + CYCLES_MMX_SHIFT(2), + INVALID, + CYCLES_MMX_MUL(2), + INVALID, + INVALID, + CYCLES_MMX_ANY(2), + CYCLES_MMX_ANY(2), + CYCLES_MMX_ANY(2), + INVALID, + CYCLES_MMX_ANY(2), + CYCLES_MMX_ANY(2), + CYCLES_MMX_ANY(2), + INVALID, +}; +static uint32_t opcode_timings_0f_mod3[256] = { + /*00*/ CYCLES(20), + CYCLES(11), + CYCLES(11), + CYCLES(10), + INVALID, + CYCLES(195), + CYCLES(7), + INVALID, + CYCLES(1000), + CYCLES(10000), + INVALID, + INVALID, + INVALID, + CYCLES_3DNOW(1), + CYCLES(1), + CYCLES_3DNOW(1), + /*10*/ INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + /*20*/ CYCLES(6), + CYCLES(6), + CYCLES(6), + CYCLES(6), + CYCLES(6), + CYCLES(6), + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + /*30*/ CYCLES(9), + CYCLES(1), + 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*/ CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), - CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), INVALID, INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), -/*70*/ INVALID, CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES(100), INVALID, INVALID, INVALID, INVALID, INVALID, - INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), + /*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*/ CYCLES_MMX_SHIFT(1), + CYCLES_MMX_SHIFT(1), + CYCLES_MMX_SHIFT(1), + CYCLES_MMX_SHIFT(1), + CYCLES_MMX_ANY(1), + CYCLES_MMX_ANY(1), + CYCLES_MMX_ANY(1), + CYCLES_MMX_SHIFT(1), + CYCLES_MMX_SHIFT(1), + CYCLES_MMX_SHIFT(1), + CYCLES_MMX_SHIFT(1), + CYCLES_MMX_SHIFT(1), + INVALID, + INVALID, + CYCLES_MMX_ANY(1), + CYCLES_MMX_ANY(1), + /*70*/ INVALID, + CYCLES_MMX_SHIFT(1), + CYCLES_MMX_SHIFT(1), + CYCLES_MMX_SHIFT(1), + CYCLES_MMX_ANY(1), + CYCLES_MMX_ANY(1), + CYCLES_MMX_ANY(1), + CYCLES(100), + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + CYCLES_MMX_ANY(1), + CYCLES_MMX_ANY(1), -/*80*/ 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), -/*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), INVALID, INVALID, CYCLES(3), CYCLES(3), INVALID, CYCLES(13), CYCLES(3), CYCLES(3), INVALID, CYCLES2(18, 30), -/*b0*/ CYCLES(10), CYCLES(10), CYCLES(6), CYCLES(13), CYCLES(6), CYCLES(6), CYCLES(3), CYCLES(3), INVALID, INVALID, CYCLES(6), CYCLES(13), CYCLES(7), CYCLES(7), CYCLES(3), CYCLES(3), + /*80*/ 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), + /*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), + INVALID, + INVALID, + CYCLES(3), + CYCLES(3), + INVALID, + CYCLES(13), + CYCLES(3), + CYCLES(3), + INVALID, + CYCLES2(18, 30), + /*b0*/ CYCLES(10), + CYCLES(10), + CYCLES(6), + CYCLES(13), + CYCLES(6), + CYCLES(6), + CYCLES(3), + CYCLES(3), + INVALID, + INVALID, + CYCLES(6), + CYCLES(13), + CYCLES(7), + CYCLES(7), + CYCLES(3), + CYCLES(3), -/*c0*/ CYCLES(4), CYCLES(4), INVALID, INVALID, INVALID, INVALID, INVALID, CYCLES(3), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), -/*d0*/ INVALID, CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), INVALID, CYCLES_MMX_MUL(1), INVALID, INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), INVALID, CYCLES_MMX_ANY(1), - CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), INVALID, CYCLES_MMX_ANY(1), -/*e0*/ INVALID, CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), INVALID, INVALID, CYCLES_MMX_MUL(1), INVALID, INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), - CYCLES_MMX_ANY(1), INVALID, CYCLES_MMX_ANY(1), -/*f0*/ INVALID, CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), CYCLES_MMX_SHIFT(1), INVALID, CYCLES_MMX_MUL(1), INVALID, INVALID, CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), INVALID, - CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), CYCLES_MMX_ANY(1), INVALID, - }; + /*c0*/ CYCLES(4), + CYCLES(4), + INVALID, + INVALID, + INVALID, + INVALID, + INVALID, + CYCLES(3), + CYCLES(1), + CYCLES(1), + CYCLES(1), + CYCLES(1), + CYCLES(1), + CYCLES(1), + CYCLES(1), + CYCLES(1), + /*d0*/ INVALID, + CYCLES_MMX_SHIFT(1), + CYCLES_MMX_SHIFT(1), + CYCLES_MMX_SHIFT(1), + INVALID, + CYCLES_MMX_MUL(1), + INVALID, + INVALID, + CYCLES_MMX_ANY(1), + CYCLES_MMX_ANY(1), + INVALID, + CYCLES_MMX_ANY(1), + CYCLES_MMX_ANY(1), + CYCLES_MMX_ANY(1), + INVALID, + CYCLES_MMX_ANY(1), + /*e0*/ INVALID, + CYCLES_MMX_SHIFT(1), + CYCLES_MMX_SHIFT(1), + INVALID, + INVALID, + CYCLES_MMX_MUL(1), + INVALID, + INVALID, + CYCLES_MMX_ANY(1), + CYCLES_MMX_ANY(1), + INVALID, + CYCLES_MMX_ANY(1), + CYCLES_MMX_ANY(1), + CYCLES_MMX_ANY(1), + INVALID, + CYCLES_MMX_ANY(1), + /*f0*/ INVALID, + CYCLES_MMX_SHIFT(1), + CYCLES_MMX_SHIFT(1), + CYCLES_MMX_SHIFT(1), + INVALID, + CYCLES_MMX_MUL(1), + INVALID, + INVALID, + CYCLES_MMX_ANY(1), + CYCLES_MMX_ANY(1), + CYCLES_MMX_ANY(1), + INVALID, + CYCLES_MMX_ANY(1), + CYCLES_MMX_ANY(1), + CYCLES_MMX_ANY(1), + INVALID, +}; -static uint32_t opcode_timings_shift[8] = - { - CYCLES(7), CYCLES(7), CYCLES(10), CYCLES(10), CYCLES(7), CYCLES(7), CYCLES(7), CYCLES(7) - }; -static uint32_t opcode_timings_shift_mod3[8] = - { - CYCLES(3), CYCLES(3), CYCLES(9), CYCLES(9), CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3) - }; +static uint32_t opcode_timings_shift[8] = {CYCLES(7), CYCLES(7), CYCLES(10), CYCLES(10), + CYCLES(7), CYCLES(7), CYCLES(7), CYCLES(7)}; +static uint32_t opcode_timings_shift_mod3[8] = {CYCLES(3), CYCLES(3), CYCLES(9), CYCLES(9), + CYCLES(3), CYCLES(3), CYCLES(3), CYCLES(3)}; -static uint32_t opcode_timings_f6[8] = - { - CYCLES(2), INVALID, CYCLES(2), CYCLES(2), CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19) - }; -static uint32_t opcode_timings_f6_mod3[8] = - { - CYCLES(1), INVALID, CYCLES(1), CYCLES(1), CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19) - }; -static uint32_t opcode_timings_f7[8] = - { - CYCLES(2), INVALID, CYCLES(2), CYCLES(2), CYCLES(21), CYCLES2(22, 38), CYCLES2(24, 40), CYCLES2(27, 43) - }; -static uint32_t opcode_timings_f7_mod3[8] = - { - CYCLES(1), INVALID, CYCLES(1), CYCLES(1), CYCLES(21), CYCLES2(22, 38), CYCLES2(24, 40), CYCLES2(27, 43) - }; -static uint32_t opcode_timings_ff[8] = - { - CYCLES(2), CYCLES(2), CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), INVALID - }; -static uint32_t opcode_timings_ff_mod3[8] = - { - CYCLES(1), CYCLES(1), CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), INVALID - }; +static uint32_t opcode_timings_f6[8] = {CYCLES(2), INVALID, CYCLES(2), CYCLES(2), CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19)}; +static uint32_t opcode_timings_f6_mod3[8] = {CYCLES(1), INVALID, CYCLES(1), CYCLES(1), + CYCLES(13), CYCLES(14), CYCLES(16), CYCLES(19)}; +static uint32_t opcode_timings_f7[8] = {CYCLES(2), INVALID, CYCLES(2), CYCLES(2), + CYCLES(21), CYCLES2(22, 38), CYCLES2(24, 40), CYCLES2(27, 43)}; +static uint32_t opcode_timings_f7_mod3[8] = {CYCLES(1), INVALID, CYCLES(1), CYCLES(1), + CYCLES(21), CYCLES2(22, 38), CYCLES2(24, 40), CYCLES2(27, 43)}; +static uint32_t opcode_timings_ff[8] = {CYCLES(2), CYCLES(2), CYCLES(5), CYCLES(0), CYCLES(5), CYCLES(0), CYCLES(5), INVALID}; +static uint32_t opcode_timings_ff_mod3[8] = {CYCLES(1), CYCLES(1), CYCLES(5), CYCLES(0), + CYCLES(5), CYCLES(0), CYCLES(5), INVALID}; -static uint32_t opcode_timings_d8[8] = - { -/* FADDs FMULs FCOMs FCOMPs*/ - FPU_CYCLES(3, 2, 2), FPU_CYCLES(3, 2, 2), FPU_CYCLES(1, 0, 0), FPU_CYCLES(1, 0, 0), -/* FSUBs FSUBRs FDIVs FDIVRs*/ - FPU_CYCLES(3, 2, 2), FPU_CYCLES(3, 2, 2), FPU_CYCLES(39, 38, 2), FPU_CYCLES(39, 38, 2) - }; -static uint32_t opcode_timings_d8_mod3[8] = - { -/* FADD FMUL FCOM FCOMP*/ - FPU_CYCLES(3, 2, 2), FPU_CYCLES(3, 2, 2), FPU_CYCLES(1, 0, 0), FPU_CYCLES(1, 0, 0), -/* FSUB FSUBR FDIV FDIVR*/ - FPU_CYCLES(3, 2, 2), FPU_CYCLES(3, 2, 2), FPU_CYCLES(39, 38, 2), FPU_CYCLES(39, 38, 2) - }; +static uint32_t opcode_timings_d8[8] = { + /* FADDs FMULs FCOMs FCOMPs*/ + FPU_CYCLES(3, 2, 2), FPU_CYCLES(3, 2, 2), FPU_CYCLES(1, 0, 0), FPU_CYCLES(1, 0, 0), + /* FSUBs FSUBRs FDIVs FDIVRs*/ + FPU_CYCLES(3, 2, 2), FPU_CYCLES(3, 2, 2), FPU_CYCLES(39, 38, 2), FPU_CYCLES(39, 38, 2)}; +static uint32_t opcode_timings_d8_mod3[8] = { + /* FADD FMUL FCOM FCOMP*/ + FPU_CYCLES(3, 2, 2), FPU_CYCLES(3, 2, 2), FPU_CYCLES(1, 0, 0), FPU_CYCLES(1, 0, 0), + /* FSUB FSUBR FDIV FDIVR*/ + FPU_CYCLES(3, 2, 2), FPU_CYCLES(3, 2, 2), FPU_CYCLES(39, 38, 2), FPU_CYCLES(39, 38, 2)}; -static uint32_t opcode_timings_d9[8] = - { -/* FLDs FSTs FSTPs*/ - FPU_CYCLES(1, 0, 0), INVALID, FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), -/* FLDENV FLDCW FSTENV FSTCW*/ - FPU_CYCLES(32, 0, 0), FPU_CYCLES(8, 0, 0), FPU_CYCLES(48, 0, 0), FPU_CYCLES(2, 0, 0) - }; -static uint32_t opcode_timings_d9_mod3[64] = - { - /*FLD*/ - FPU_CYCLES(1, 0, 0), FPU_CYCLES(1, 0, 0), FPU_CYCLES(1, 0, 0), FPU_CYCLES(1, 0, 0), - FPU_CYCLES(1, 0, 0), FPU_CYCLES(1, 0, 0), FPU_CYCLES(1, 0, 0), FPU_CYCLES(1, 0, 0), - /*FXCH*/ - FPU_CYCLES(1, 0, 0), FPU_CYCLES(1, 0, 0), FPU_CYCLES(1, 0, 0), FPU_CYCLES(1, 0, 0), - FPU_CYCLES(1, 0, 0), FPU_CYCLES(1, 0, 0), FPU_CYCLES(1, 0, 0), FPU_CYCLES(1, 0, 0), - /*FNOP*/ - FPU_CYCLES(3, 0, 0), INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, - /*FSTP*/ - FPU_CYCLES(1, 0, 0), FPU_CYCLES(1, 0, 0), FPU_CYCLES(1, 0, 0), FPU_CYCLES(1, 0, 0), - FPU_CYCLES(1, 0, 0), FPU_CYCLES(1, 0, 0), FPU_CYCLES(1, 0, 0), FPU_CYCLES(1, 0, 0), -/* opFCHS opFABS*/ - FPU_CYCLES(1, 0, 0), FPU_CYCLES(1, 0, 0), INVALID, INVALID, -/* opFTST opFXAM*/ - FPU_CYCLES(1, 0, 0), FPU_CYCLES(21, 4, 0), INVALID, INVALID, -/* opFLD1 opFLDL2T opFLDL2E opFLDPI*/ - FPU_CYCLES(2, 0, 0), FPU_CYCLES(5, 2, 2), FPU_CYCLES(5, 2, 2), FPU_CYCLES(5, 2, 2), -/* opFLDEG2 opFLDLN2 opFLDZ*/ - FPU_CYCLES(5, 2, 2), FPU_CYCLES(5, 2, 2), FPU_CYCLES(2, 0, 0), INVALID, -/* opF2XM1 opFYL2X opFPTAN opFPATAN*/ - FPU_CYCLES(53, 2, 2), FPU_CYCLES(103, 2, 2), FPU_CYCLES(120, 36, 0), FPU_CYCLES(112, 2, 2), -/* opFDECSTP opFINCSTP,*/ - INVALID, INVALID, FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), -/* opFPREM opFSQRT opFSINCOS*/ - FPU_CYCLES(64, 2, 2), INVALID, FPU_CYCLES(70, 69, 2), FPU_CYCLES(89, 2, 2), -/* opFRNDINT opFSCALE opFSIN opFCOS*/ - FPU_CYCLES(9, 0, 0), FPU_CYCLES(20, 5, 0), FPU_CYCLES(65, 2, 2), FPU_CYCLES(65, 2, 2) - }; +static uint32_t opcode_timings_d9[8] = { + /* FLDs FSTs FSTPs*/ + FPU_CYCLES(1, 0, 0), INVALID, FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), + /* FLDENV FLDCW FSTENV FSTCW*/ + FPU_CYCLES(32, 0, 0), FPU_CYCLES(8, 0, 0), FPU_CYCLES(48, 0, 0), FPU_CYCLES(2, 0, 0)}; +static uint32_t opcode_timings_d9_mod3[64] = { + /*FLD*/ + FPU_CYCLES(1, 0, 0), FPU_CYCLES(1, 0, 0), FPU_CYCLES(1, 0, 0), FPU_CYCLES(1, 0, 0), FPU_CYCLES(1, 0, 0), + FPU_CYCLES(1, 0, 0), FPU_CYCLES(1, 0, 0), FPU_CYCLES(1, 0, 0), + /*FXCH*/ + FPU_CYCLES(1, 0, 0), FPU_CYCLES(1, 0, 0), FPU_CYCLES(1, 0, 0), FPU_CYCLES(1, 0, 0), FPU_CYCLES(1, 0, 0), + FPU_CYCLES(1, 0, 0), FPU_CYCLES(1, 0, 0), FPU_CYCLES(1, 0, 0), + /*FNOP*/ + FPU_CYCLES(3, 0, 0), INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, + /*FSTP*/ + FPU_CYCLES(1, 0, 0), FPU_CYCLES(1, 0, 0), FPU_CYCLES(1, 0, 0), FPU_CYCLES(1, 0, 0), FPU_CYCLES(1, 0, 0), + FPU_CYCLES(1, 0, 0), FPU_CYCLES(1, 0, 0), FPU_CYCLES(1, 0, 0), + /* opFCHS opFABS*/ + FPU_CYCLES(1, 0, 0), FPU_CYCLES(1, 0, 0), INVALID, INVALID, + /* opFTST opFXAM*/ + FPU_CYCLES(1, 0, 0), FPU_CYCLES(21, 4, 0), INVALID, INVALID, + /* opFLD1 opFLDL2T opFLDL2E opFLDPI*/ + FPU_CYCLES(2, 0, 0), FPU_CYCLES(5, 2, 2), FPU_CYCLES(5, 2, 2), FPU_CYCLES(5, 2, 2), + /* opFLDEG2 opFLDLN2 opFLDZ*/ + FPU_CYCLES(5, 2, 2), FPU_CYCLES(5, 2, 2), FPU_CYCLES(2, 0, 0), INVALID, + /* opF2XM1 opFYL2X opFPTAN opFPATAN*/ + FPU_CYCLES(53, 2, 2), FPU_CYCLES(103, 2, 2), FPU_CYCLES(120, 36, 0), FPU_CYCLES(112, 2, 2), + /* opFDECSTP opFINCSTP,*/ + INVALID, INVALID, FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), + /* opFPREM opFSQRT opFSINCOS*/ + FPU_CYCLES(64, 2, 2), INVALID, FPU_CYCLES(70, 69, 2), FPU_CYCLES(89, 2, 2), + /* opFRNDINT opFSCALE opFSIN opFCOS*/ + FPU_CYCLES(9, 0, 0), FPU_CYCLES(20, 5, 0), FPU_CYCLES(65, 2, 2), FPU_CYCLES(65, 2, 2)}; -static uint32_t opcode_timings_da[8] = - { -/* FIADDl FIMULl FICOMl FICOMPl*/ - FPU_CYCLES(6, 2, 2), FPU_CYCLES(6, 2, 2), FPU_CYCLES(4, 0, 0), FPU_CYCLES(4, 0, 0), -/* FISUBl FISUBRl FIDIVl FIDIVRl*/ - FPU_CYCLES(6, 2, 2), FPU_CYCLES(6, 2, 2), FPU_CYCLES(42, 38, 2), FPU_CYCLES(42, 38, 2) - }; -static uint32_t opcode_timings_da_mod3[8] = - { - INVALID, INVALID, INVALID, INVALID, -/* FCOMPP*/ - INVALID, FPU_CYCLES(1, 0, 0), INVALID, INVALID - }; +static uint32_t opcode_timings_da[8] = { + /* FIADDl FIMULl FICOMl FICOMPl*/ + FPU_CYCLES(6, 2, 2), FPU_CYCLES(6, 2, 2), FPU_CYCLES(4, 0, 0), FPU_CYCLES(4, 0, 0), + /* FISUBl FISUBRl FIDIVl FIDIVRl*/ + FPU_CYCLES(6, 2, 2), FPU_CYCLES(6, 2, 2), FPU_CYCLES(42, 38, 2), FPU_CYCLES(42, 38, 2)}; +static uint32_t opcode_timings_da_mod3[8] = {INVALID, INVALID, INVALID, INVALID, + /* FCOMPP*/ + INVALID, FPU_CYCLES(1, 0, 0), INVALID, INVALID}; -static uint32_t opcode_timings_db[8] = - { -/* FLDil FSTil FSTPil*/ - FPU_CYCLES(3, 2, 2), INVALID, FPU_CYCLES(6, 0, 0), FPU_CYCLES(6, 0, 0), -/* FLDe FSTPe*/ - INVALID, FPU_CYCLES(3, 0, 0), INVALID, FPU_CYCLES(3, 0, 0) - }; -static uint32_t opcode_timings_db_mod3[64] = - { - INVALID, INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, +static uint32_t opcode_timings_db[8] = { + /* FLDil FSTil FSTPil*/ + FPU_CYCLES(3, 2, 2), INVALID, FPU_CYCLES(6, 0, 0), FPU_CYCLES(6, 0, 0), + /* FLDe FSTPe*/ + INVALID, FPU_CYCLES(3, 0, 0), INVALID, FPU_CYCLES(3, 0, 0)}; +static uint32_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, + 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, FPU_CYCLES(1, 0, 0), FPU_CYCLES(7, 0, 0), FPU_CYCLES(17, 0, 0), -/* opFNOP opFNOP*/ - FPU_CYCLES(1, 0, 0), FPU_CYCLES(1, 0, 0), INVALID, INVALID, + /* opFNOP opFCLEX opFINIT*/ + INVALID, + FPU_CYCLES(1, 0, 0), + FPU_CYCLES(7, 0, 0), + FPU_CYCLES(17, 0, 0), + /* opFNOP opFNOP*/ + FPU_CYCLES(1, 0, 0), + 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, + 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*/ - FPU_CYCLES(3, 2, 2), FPU_CYCLES(3, 2, 2), FPU_CYCLES(1, 0, 0), FPU_CYCLES(1, 0, 0), -/* FSUBd FSUBRd FDIVd FDIVRd*/ - FPU_CYCLES(3, 2, 2), FPU_CYCLES(3, 2, 2), FPU_CYCLES(39, 38, 2), FPU_CYCLES(39, 38, 2) - }; -static uint32_t opcode_timings_dc_mod3[8] = - { -/* opFADDr opFMULr*/ - FPU_CYCLES(3, 2, 2), FPU_CYCLES(3, 2, 2), INVALID, INVALID, -/* opFSUBRr opFSUBr opFDIVRr opFDIVr*/ - FPU_CYCLES(3, 2, 2), FPU_CYCLES(3, 2, 2), FPU_CYCLES(39, 38, 2), FPU_CYCLES(39, 38, 2) - }; +static uint32_t opcode_timings_dc[8] = { + /* FADDd FMULd FCOMd FCOMPd*/ + FPU_CYCLES(3, 2, 2), FPU_CYCLES(3, 2, 2), FPU_CYCLES(1, 0, 0), FPU_CYCLES(1, 0, 0), + /* FSUBd FSUBRd FDIVd FDIVRd*/ + FPU_CYCLES(3, 2, 2), FPU_CYCLES(3, 2, 2), FPU_CYCLES(39, 38, 2), FPU_CYCLES(39, 38, 2)}; +static uint32_t opcode_timings_dc_mod3[8] = { + /* opFADDr opFMULr*/ + FPU_CYCLES(3, 2, 2), FPU_CYCLES(3, 2, 2), INVALID, INVALID, + /* opFSUBRr opFSUBr opFDIVRr opFDIVr*/ + FPU_CYCLES(3, 2, 2), FPU_CYCLES(3, 2, 2), FPU_CYCLES(39, 38, 2), FPU_CYCLES(39, 38, 2)}; -static uint32_t opcode_timings_dd[8] = - { -/* FLDd FSTd FSTPd*/ - FPU_CYCLES(1, 0, 0), INVALID, FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), -/* FRSTOR FSAVE FSTSW*/ - FPU_CYCLES(70, 0, 0), INVALID, FPU_CYCLES(127, 0, 0), FPU_CYCLES(6, 0, 0) - }; -static uint32_t opcode_timings_dd_mod3[8] = - { -/* FFFREE FST FSTP*/ - FPU_CYCLES(2, 0, 0), INVALID, FPU_CYCLES(1, 0, 0), FPU_CYCLES(1, 0, 0), -/* FUCOM FUCOMP*/ - FPU_CYCLES(1, 0, 0), FPU_CYCLES(1, 0, 0), INVALID, INVALID - }; +static uint32_t opcode_timings_dd[8] = { + /* FLDd FSTd FSTPd*/ + FPU_CYCLES(1, 0, 0), INVALID, FPU_CYCLES(2, 0, 0), FPU_CYCLES(2, 0, 0), + /* FRSTOR FSAVE FSTSW*/ + FPU_CYCLES(70, 0, 0), INVALID, FPU_CYCLES(127, 0, 0), FPU_CYCLES(6, 0, 0)}; +static uint32_t opcode_timings_dd_mod3[8] = { + /* FFFREE FST FSTP*/ + FPU_CYCLES(2, 0, 0), INVALID, FPU_CYCLES(1, 0, 0), FPU_CYCLES(1, 0, 0), + /* FUCOM FUCOMP*/ + FPU_CYCLES(1, 0, 0), FPU_CYCLES(1, 0, 0), INVALID, INVALID}; -static uint32_t opcode_timings_de[8] = - { -/* FIADDw FIMULw FICOMw FICOMPw*/ - FPU_CYCLES(6, 2, 2), FPU_CYCLES(6, 2, 2), FPU_CYCLES(4, 0, 0), FPU_CYCLES(4, 0, 0), -/* FISUBw FISUBRw FIDIVw FIDIVRw*/ - FPU_CYCLES(6, 2, 2), FPU_CYCLES(6, 2, 2), FPU_CYCLES(42, 38, 2), FPU_CYCLES(42, 38, 2) - }; -static uint32_t opcode_timings_de_mod3[8] = - { -/* FADDP FMULP FCOMPP*/ - FPU_CYCLES(3, 2, 2), FPU_CYCLES(3, 2, 2), INVALID, FPU_CYCLES(1, 0, 0), -/* FSUBP FSUBRP FDIVP FDIVRP*/ - FPU_CYCLES(3, 2, 2), FPU_CYCLES(3, 2, 2), FPU_CYCLES(39, 38, 2), FPU_CYCLES(39, 38, 2) - }; +static uint32_t opcode_timings_de[8] = { + /* FIADDw FIMULw FICOMw FICOMPw*/ + FPU_CYCLES(6, 2, 2), FPU_CYCLES(6, 2, 2), FPU_CYCLES(4, 0, 0), FPU_CYCLES(4, 0, 0), + /* FISUBw FISUBRw FIDIVw FIDIVRw*/ + FPU_CYCLES(6, 2, 2), FPU_CYCLES(6, 2, 2), FPU_CYCLES(42, 38, 2), FPU_CYCLES(42, 38, 2)}; +static uint32_t opcode_timings_de_mod3[8] = { + /* FADDP FMULP FCOMPP*/ + FPU_CYCLES(3, 2, 2), FPU_CYCLES(3, 2, 2), INVALID, FPU_CYCLES(1, 0, 0), + /* FSUBP FSUBRP FDIVP FDIVRP*/ + FPU_CYCLES(3, 2, 2), FPU_CYCLES(3, 2, 2), FPU_CYCLES(39, 38, 2), FPU_CYCLES(39, 38, 2)}; -static uint32_t opcode_timings_df[8] = - { -/* FILDiw FISTiw FISTPiw*/ - FPU_CYCLES(3, 2, 2), INVALID, FPU_CYCLES(6, 0, 0), FPU_CYCLES(6, 0, 0), -/* FILDiq FBSTP FISTPiq*/ - INVALID, FPU_CYCLES(3, 2, 2), FPU_CYCLES(148, 0, 0), FPU_CYCLES(6, 0, 0) - }; -static uint32_t opcode_timings_df_mod3[8] = - { - INVALID, INVALID, INVALID, INVALID, -/* FSTSW AX*/ - FPU_CYCLES(6, 0, 0), INVALID, INVALID, INVALID - }; +static uint32_t opcode_timings_df[8] = { + /* FILDiw FISTiw FISTPiw*/ + FPU_CYCLES(3, 2, 2), INVALID, FPU_CYCLES(6, 0, 0), FPU_CYCLES(6, 0, 0), + /* FILDiq FBSTP FISTPiq*/ + INVALID, FPU_CYCLES(3, 2, 2), FPU_CYCLES(148, 0, 0), FPU_CYCLES(6, 0, 0)}; +static uint32_t opcode_timings_df_mod3[8] = {INVALID, INVALID, INVALID, INVALID, + /* FSTSW AX*/ + FPU_CYCLES(6, 0, 0), INVALID, INVALID, INVALID}; -static uint32_t opcode_timings_8x[8] = - { - CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2) - }; -static uint32_t opcode_timings_8x_mod3[8] = - { - CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2) - }; -static uint32_t opcode_timings_81[8] = - { - CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2) - }; -static uint32_t opcode_timings_81_mod3[8] = - { - CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2) - }; +static uint32_t opcode_timings_8x[8] = {CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2)}; +static uint32_t opcode_timings_8x_mod3[8] = {CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), + CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2)}; +static uint32_t opcode_timings_81[8] = {CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2)}; +static uint32_t opcode_timings_81_mod3[8] = {CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2), + CYCLES(2), CYCLES(2), CYCLES(2), CYCLES(2)}; static int timing_count; static uint8_t last_prefix; @@ -388,342 +871,355 @@ static int u_pipe_decode_delay_offset; static uint64_t *u_pipe_deps; int can_pair(uint32_t timing_a, uint32_t timing_b, uint8_t regmask_b) { - /*Only MMX/3DNow instructions can pair*/ - if (!(timing_b & CYCLES_IS_MMX)) - return 0; - /*Only one MMX multiply per cycle*/ - if ((timing_a & CYCLES_IS_MMX_MUL) && (timing_b & CYCLES_IS_MMX_MUL)) - return 0; - /*Only one MMX shift/pack per cycle*/ - if ((timing_a & CYCLES_IS_MMX_SHIFT) && (timing_b & CYCLES_IS_MMX_SHIFT)) - return 0; - /*Second instruction can not access registers written by first*/ - if (u_pipe_regmask & regmask_b) - return 0; - /*Must have had enough time to decode prefixes*/ - if ((decode_delay + decode_delay_offset + u_pipe_decode_delay_offset) > 0) - return 0; + /*Only MMX/3DNow instructions can pair*/ + if (!(timing_b & CYCLES_IS_MMX)) + return 0; + /*Only one MMX multiply per cycle*/ + if ((timing_a & CYCLES_IS_MMX_MUL) && (timing_b & CYCLES_IS_MMX_MUL)) + return 0; + /*Only one MMX shift/pack per cycle*/ + if ((timing_a & CYCLES_IS_MMX_SHIFT) && (timing_b & CYCLES_IS_MMX_SHIFT)) + return 0; + /*Second instruction can not access registers written by first*/ + if (u_pipe_regmask & regmask_b) + return 0; + /*Must have had enough time to decode prefixes*/ + if ((decode_delay + decode_delay_offset + u_pipe_decode_delay_offset) > 0) + return 0; - return 1; + return 1; } static inline int COUNT(uint32_t c, int op_32) { - if (c & CYCLES_FPU) - return FPU_I_LATENCY(c); - if (c & CYCLES_HAS_MULTI) { - if (op_32 & 0x100) - return (c >> 8) & 0xff; - return c & 0xff; - } - return GET_CYCLES(c); + if (c & CYCLES_FPU) + return FPU_I_LATENCY(c); + if (c & CYCLES_HAS_MULTI) { + if (op_32 & 0x100) + return (c >> 8) & 0xff; + return c & 0xff; + } + return GET_CYCLES(c); } 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); + 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); + /*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; + return (regmask_modified & addr_regmask) & ~REGMASK_IMPL_ESP; } static int codegen_fpu_latencies(uint64_t deps, int reg) { - int latency = fpu_latency; + 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]; + 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; + return latency; } -#define SUB_AND_CLAMP(latency, count) \ - latency -= count; \ - if (latency < 0) \ - latency = 0 +#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); + 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 void codegen_instruction(uint32_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; +static void codegen_instruction(uint32_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] & CYCLES_FPU) && !(deps[opcode] & FPU_FXCH)) - instr_cycles = latency = codegen_fpu_latencies(deps[opcode], fetchdat & 7); - else - instr_cycles = 0; + if ((timings[opcode] & CYCLES_FPU) && !(deps[opcode] & FPU_FXCH)) + instr_cycles = latency = codegen_fpu_latencies(deps[opcode], fetchdat & 7); + else + 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], 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 ((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], 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; + 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 < 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] & CYCLES_FPU) { - /* if (fpu_latency) - fatal("Bad latency FPU\n");*/ - fpu_latency = FPU_F_LATENCY(timings[opcode]); - } + 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] & CYCLES_FPU) { + /* if (fpu_latency) + fatal("Bad latency FPU\n");*/ + fpu_latency = FPU_F_LATENCY(timings[opcode]); + } - if (deps[opcode] & FPU_PUSH) { - int c; + 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]); - } - } + 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]); + } + } } static void codegen_timing_winchip2_block_start() { - regmask_modified = 0; - decode_delay = decode_delay_offset = 0; - u_pipe_full = 0; + regmask_modified = 0; + decode_delay = decode_delay_offset = 0; + u_pipe_full = 0; } static void codegen_timing_winchip2_start() { - timing_count = 0; - last_prefix = 0; + timing_count = 0; + last_prefix = 0; } static void codegen_timing_winchip2_prefix(uint8_t prefix, uint32_t fetchdat) { - if (prefix == 0x0f) { - /*0fh prefix is 'free'*/ - last_prefix = prefix; - return; - } - /*On WinChip all prefixes take 1 cycle to decode. Decode may be shadowed - by execution of previous instructions*/ - decode_delay_offset++; - last_prefix = prefix; + if (prefix == 0x0f) { + /*0fh prefix is 'free'*/ + last_prefix = prefix; + return; + } + /*On WinChip all prefixes take 1 cycle to decode. Decode may be shadowed + by execution of previous instructions*/ + decode_delay_offset++; + last_prefix = prefix; } static void codegen_timing_winchip2_opcode(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc) { - uint32_t *timings; - uint64_t *deps; - int mod3 = ((fetchdat & 0xc0) == 0xc0); - int bit8 = !(opcode & 1); - int agi_stall = 0; + uint32_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; -// pclog("timings 0f\n"); - break; + switch (last_prefix) { + case 0x0f: + timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; + deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f; + // pclog("timings 0f\n"); + 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; -// pclog("timings d8\n"); - 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; -// pclog("timings d9\n"); - 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; -// pclog("timings da\n"); - 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; -// pclog("timings db\n"); - 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; -// pclog("timings dc\n"); - 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; -// pclog("timings dd\n"); - 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; -// pclog("timings de\n"); - 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; -// pclog("timings df\n"); - 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; + // pclog("timings d8\n"); + 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; + // pclog("timings d9\n"); + 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; + // pclog("timings da\n"); + 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; + // pclog("timings db\n"); + 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; + // pclog("timings dc\n"); + 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; + // pclog("timings dd\n"); + 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; + // pclog("timings de\n"); + 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; + // pclog("timings df\n"); + 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; -// pclog("timings 80 %p %p %p\n", (void *)timings, (void *)opcode_timings_mod3, (void *)opcode_timings_8x); - 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; -// pclog("timings 80 %p %p %p\n", (void *)timings, (void *)opcode_timings_mod3, (void *)opcode_timings_8x); - 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; + // pclog("timings 80 %p %p %p\n", (void *)timings, (void *)opcode_timings_mod3, + // (void *)opcode_timings_8x); + 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; + // pclog("timings 80 %p %p %p\n", (void *)timings, (void *)opcode_timings_mod3, + // (void *)opcode_timings_8x); + 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; -// pclog("timings c0\n"); - 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; + // pclog("timings c0\n"); + 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; -// pclog("timings f6\n"); - 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; -// pclog("timings f7\n"); - 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; -// pclog("timings ff\n"); - 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; + // pclog("timings f6\n"); + 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; + // pclog("timings f7\n"); + 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; + // pclog("timings ff\n"); + break; - default:timings = mod3 ? opcode_timings_mod3 : opcode_timings; - deps = mod3 ? opcode_deps_mod3 : opcode_deps; -// pclog("timings normal\n"); - break; - } - } + default: + timings = mod3 ? opcode_timings_mod3 : opcode_timings; + deps = mod3 ? opcode_deps_mod3 : opcode_deps; + // pclog("timings normal\n"); + break; + } + } - if (u_pipe_full) { - uint8_t regmask = get_srcdep_mask(deps[opcode], fetchdat, bit8, u_pipe_op_32); + if (u_pipe_full) { + uint8_t regmask = get_srcdep_mask(deps[opcode], fetchdat, bit8, u_pipe_op_32); - if (can_pair(u_pipe_timings[u_pipe_opcode], timings[opcode], regmask)) { - int cycles_a = u_pipe_timings[u_pipe_opcode] & 0xff; - int cycles_b = timings[opcode] & 0xff; - uint32_t timing = (cycles_a > cycles_b) ? u_pipe_timings[u_pipe_opcode] : timings[opcode]; - uint64_t temp_deps = 0; + if (can_pair(u_pipe_timings[u_pipe_opcode], timings[opcode], regmask)) { + int cycles_a = u_pipe_timings[u_pipe_opcode] & 0xff; + int cycles_b = timings[opcode] & 0xff; + uint32_t timing = (cycles_a > cycles_b) ? u_pipe_timings[u_pipe_opcode] : timings[opcode]; + uint64_t temp_deps = 0; - 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; + 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(&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; - return; - } else { - /*No pairing, run first instruction 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; - } - } - if (timings[opcode] & CYCLES_IS_MMX) { - /*Might pair with next instruction*/ - 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; - } + codegen_instruction(&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; + return; + } else { + /*No pairing, run first instruction 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; + } + } + if (timings[opcode] & CYCLES_IS_MMX) { + /*Might pair with next instruction*/ + 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; + } - 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); + 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); } static void codegen_timing_winchip2_block_end() { - if (u_pipe_full) { - int agi_stall = 0; + if (u_pipe_full) { + int agi_stall = 0; - 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; - } + 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; + } } -int codegen_timing_winchip2_jump_cycles() { - return 0; -} +int codegen_timing_winchip2_jump_cycles() { return 0; } -codegen_timing_t codegen_timing_winchip2 = - { - codegen_timing_winchip2_start, - codegen_timing_winchip2_prefix, - codegen_timing_winchip2_opcode, - codegen_timing_winchip2_block_start, - codegen_timing_winchip2_block_end, - codegen_timing_winchip2_jump_cycles - }; +codegen_timing_t codegen_timing_winchip2 = {codegen_timing_winchip2_start, codegen_timing_winchip2_prefix, + codegen_timing_winchip2_opcode, codegen_timing_winchip2_block_start, + codegen_timing_winchip2_block_end, codegen_timing_winchip2_jump_cycles}; diff --git a/src/codegen/codegen_x86-64.c b/src/codegen/codegen_x86-64.c index bc9680ef..5a2ff1d2 100644 --- a/src/codegen/codegen_x86-64.c +++ b/src/codegen/codegen_x86-64.c @@ -60,410 +60,410 @@ static x86seg *last_ea_seg; static int last_ssegs; void codegen_init() { - int c; + int c; #if defined(__linux__) || defined(__APPLE__) - void *start; - size_t len; - long pagesize = sysconf(_SC_PAGESIZE); - long pagemask = ~(pagesize - 1); + 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); + codeblock = VirtualAlloc(NULL, BLOCK_SIZE * sizeof(codeblock_t), MEM_COMMIT, PAGE_EXECUTE_READWRITE); #else - codeblock = malloc(BLOCK_SIZE * sizeof(codeblock_t)); + codeblock = malloc(BLOCK_SIZE * sizeof(codeblock_t)); #endif - codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); + 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 *)); + 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].pc = BLOCK_PC_INVALID; + for (c = 0; c < BLOCK_SIZE; c++) + codeblock[c].pc = BLOCK_PC_INVALID; #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); - } + 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 -// pclog("Codegen is %p\n", (void *)pages[0xfab12 >> 12].block); + // pclog("Codegen is %p\n", (void *)pages[0xfab12 >> 12].block); } void codegen_reset() { - int c; + int c; - memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); - memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); - mem_reset_page_blocks(); + 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].pc = BLOCK_PC_INVALID; + for (c = 0; c < BLOCK_SIZE; c++) + codeblock[c].pc = BLOCK_PC_INVALID; } void dump_block() { -/* codeblock_t *block = pages[0x119000 >> 12].block; + /* codeblock_t *block = pages[0x119000 >> 12].block; - pclog("dump_block:\n"); - while (block) - { - uint32_t start_pc = (block->pc & 0xffc) | (block->phys & ~0xfff); - uint32_t end_pc = (block->endpc & 0xffc) | (block->phys & ~0xfff); - pclog(" %p : %08x-%08x %08x-%08x %p %p\n", (void *)block, start_pc, end_pc, block->pc, block->endpc, (void *)block->prev, (void *)block->next); - if (!block->pc) - fatal("Dead PC=0\n"); - - block = block->next; - } - pclog("dump_block done\n");*/ + pclog("dump_block:\n"); + while (block) + { + uint32_t start_pc = (block->pc & 0xffc) | (block->phys & ~0xfff); + uint32_t end_pc = (block->endpc & 0xffc) | (block->phys & ~0xfff); + pclog(" %p : %08x-%08x %08x-%08x %p %p\n", (void *)block, start_pc, end_pc, block->pc, block->endpc, + (void *)block->prev, (void *)block->next); if (!block->pc) fatal("Dead PC=0\n"); + + block = block->next; + } + pclog("dump_block done\n");*/ } static void add_to_block_list(codeblock_t *block) { - codeblock_t *block_prev = pages[block->phys >> 12].block[(block->phys >> 10) & 3]; + 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->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_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->pc == BLOCK_PC_INVALID) - fatal("block->next->pc=BLOCK_PC_INVALID %p %p %x %x\n", (void *)block->next, (void *)codeblock, block_current, block_pos); - } + if (block->next) { + if (block->next->pc == BLOCK_PC_INVALID) + fatal("block->next->pc=BLOCK_PC_INVALID %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->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; - } - } + 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->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) { + 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 { -// pclog(" pages.block_2=%p 3 %p %p\n", (void *)block->next_2, (void *)block, (void *)pages[block->phys_2 >> 12].block_2); - 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); - } + 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 { + // pclog(" pages.block_2=%p 3 %p %p\n", (void *)block->next_2, (void *)block, (void + // *)pages[block->phys_2 >> 12].block_2); + 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; + uint32_t old_pc = block->pc; - if (block == codeblock_hash[HASH(block->phys)]) - codeblock_hash[HASH(block->phys)] = NULL; + if (block == codeblock_hash[HASH(block->phys)]) + codeblock_hash[HASH(block->phys)] = NULL; - if (block->pc == BLOCK_PC_INVALID) - fatal("Deleting deleted block\n"); - block->pc = BLOCK_PC_INVALID; + if (block->pc == BLOCK_PC_INVALID) + fatal("Deleting deleted block\n"); + block->pc = BLOCK_PC_INVALID; - codeblock_tree_delete(block); - remove_from_block_list(block, old_pc); + 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]; + 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; - } + 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]; + 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; - } + 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]; + 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); + 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]; + block_current = (block_current + 1) & BLOCK_MASK; + block = &codeblock[block_current]; -// if (block->pc == 0xb00b4ff5) -// pclog("Init target block\n"); - if (block->pc != BLOCK_PC_INVALID) { -// pclog("Reuse block : was %08x now %08x\n", block->pc, cs+pc); - delete_block(block); - cpu_recomp_reuse++; - } - block_num = HASH(phys_addr); - codeblock_hash[block_num] = &codeblock[block_current]; + // if (block->pc == 0xb00b4ff5) + // pclog("Init target block\n"); + if (block->pc != BLOCK_PC_INVALID) { + // pclog("Reuse block : was %08x now %08x\n", block->pc, cs+pc); + delete_block(block); + cpu_recomp_reuse++; + } + block_num = HASH(phys_addr); + codeblock_hash[block_num] = &codeblock[block_current]; - 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->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; + block->was_recompiled = 0; - recomp_page = block->phys & ~0xfff; + recomp_page = block->phys & ~0xfff; - codeblock_tree_add(block); + codeblock_tree_add(block); } void codegen_block_start_recompile(codeblock_t *block) { - page_t *page = &pages[block->phys >> 12]; + page_t *page = &pages[block->phys >> 12]; - if (!page->block[(block->phys >> 10) & 3]) - mem_flush_write_page(block->phys, cs + cpu_state.pc); + 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; + 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"); + if (block->pc != cs + cpu_state.pc || block->was_recompiled) + fatal("Recompile to used block!\n"); - block->status = cpu_cur_status; + block->status = cpu_cur_status; - block_pos = BLOCK_GPF_OFFSET; + block_pos = BLOCK_GPF_OFFSET; #if WIN64 - addbyte(0x48); /*XOR RCX, RCX*/ - addbyte(0x31); - addbyte(0xc9); - addbyte(0x31); /*XOR EDX, EDX*/ - addbyte(0xd2); + 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); + 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); + 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); -// pclog("New block %i for %08X %03x\n", block_current, cs+pc, block_num); + // pclog("New block %i for %08X %03x\n", block_current, cs+pc, block_num); - last_op32 = -1; - last_ea_seg = NULL; - last_ssegs = -1; + last_op32 = -1; + last_ea_seg = NULL; + last_ssegs = -1; - codegen_block_cycles = 0; - codegen_timing_block_start(); + codegen_block_cycles = 0; + codegen_timing_block_start(); - codegen_block_ins = 0; - codegen_block_full_ins = 0; + codegen_block_ins = 0; + codegen_block_full_ins = 0; - recomp_page = block->phys & ~0xfff; + recomp_page = block->phys & ~0xfff; - codegen_flags_changed = 0; - codegen_fpu_entered = 0; - codegen_mmx_entered = 0; + 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; + 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; + _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; + 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; + block->was_recompiled = 1; - codegen_flat_ds = !(cpu_cur_status & CPU_STATUS_NOTFLATDS); - codegen_flat_ss = !(cpu_cur_status & CPU_STATUS_NOTFLATSS); + 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]; + codeblock_t *block = &codeblock[block_current]; - delete_block(block); - cpu_recomp_removed++; + delete_block(block); + cpu_recomp_removed++; - recomp_page = -1; + recomp_page = -1; } void codegen_block_generate_end_mask() { - codeblock_t *block = &codeblock[block_current]; - uint32_t start_pc; - uint32_t end_pc; + codeblock_t *block = &codeblock[block_current]; + uint32_t start_pc; + uint32_t end_pc; - block->endpc = codegen_endpc; + 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; + 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; -// pclog("block_end: %08x %08x\n", start_pc, end_pc); - for (; start_pc <= end_pc; start_pc++) { - block->page_mask |= ((uint64_t)1 << start_pc); -// pclog(" %08x %llx\n", start_pc, block->page_mask); - } + // pclog("block_end: %08x %08x\n", start_pc, end_pc); + for (; start_pc <= end_pc; start_pc++) { + block->page_mask |= ((uint64_t)1 << start_pc); + // pclog(" %08x %llx\n", start_pc, block->page_mask); + } - pages[block->phys >> 12].code_present_mask[(block->phys >> 10) & 3] |= block->page_mask; + 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]; + 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; + 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 (!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) { -// pclog(" next_2->pc=%08x\n", block->next_2->pc); - if (block->next_2->pc == BLOCK_PC_INVALID) - fatal("block->next_2->pc=BLOCK_PC_INVALID %p\n", (void *)block->next_2); - } + if (!block->page_mask2) + fatal("!page_mask2\n"); + if (block->next_2) { + // pclog(" next_2->pc=%08x\n", block->next_2->pc); + if (block->next_2->pc == BLOCK_PC_INVALID) + fatal("block->next_2->pc=BLOCK_PC_INVALID %p\n", (void *)block->next_2); + } - block->dirty_mask2 = &page_2->dirty_mask[(block->phys_2 >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK]; - } - } + block->dirty_mask2 = &page_2->dirty_mask[(block->phys_2 >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK]; + } + } -// pclog("block_end: %08x %08x %016llx\n", block->pc, block->endpc, block->page_mask); - recomp_page = -1; + // pclog("block_end: %08x %08x %016llx\n", block->pc, block->endpc, block->page_mask); + recomp_page = -1; } void codegen_block_end() { - codeblock_t *block = &codeblock[block_current]; + codeblock_t *block = &codeblock[block_current]; - codegen_block_generate_end_mask(); - add_to_block_list(block); + codegen_block_generate_end_mask(); + add_to_block_list(block); } void codegen_block_end_recompile(codeblock_t *block) { - codegen_timing_block_end(); + 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 (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) { @@ -474,535 +474,549 @@ void codegen_block_end_recompile(codeblock_t *block) { 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*/ + 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"); + 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); -// pclog("End block %i\n", block_num); + 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); + // pclog("End block %i\n", block_num); } -void codegen_flush() { - return; -} +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*/ +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*/ + 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, 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, 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*/ + 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, 0, 1, /*a0*/ - 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, /*b0*/ + 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, 0, 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*/ - }; + 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() { - if (output) { - pclog("At %04x(%08x):%04x %04x(%08x):%04x es=%08x EAX=%08x BX=%04x ECX=%08x BP=%04x EDX=%08x EDI=%08x\n", CS, cs, cpu_state.pc, SS, ss, ESP, es, EAX, BX, ECX, BP, EDX, EDI); - } + if (output) { + pclog("At %04x(%08x):%04x %04x(%08x):%04x es=%08x EAX=%08x BX=%04x ECX=%08x BP=%04x EDX=%08x EDI=%08x\n", CS, + cs, cpu_state.pc, SS, ss, ESP, es, EAX, BX, ECX, BP, EDX, EDI); + } } 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; + 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_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; + 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 (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 (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; +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; + if (cpu_rm == 4) { + uint8_t sib = fetchdat >> 8; + int base_reg = -1, index_reg = -1; - (*op_pc)++; + (*op_pc)++; - if (cpu_mod || (sib & 7) != 5) - base_reg = LOAD_REG_L(sib & 7) & 7; + 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 (((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; + 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; + 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; + 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; + 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; + 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; + 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(); + codegen_timing_start(); - while (!over) { - switch (opcode) { - case 0x0f:op_table = x86_dynarec_opcodes_0f; - recomp_op_table = recomp_opcodes_0f; - over = 1; - break; + 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 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 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 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 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; + 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++; - } + 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); +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 && ((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 0 if (codegen_block_full_ins) { @@ -1014,104 +1028,105 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t 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 ((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); + 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; + codegen_block_ins++; + block->ins++; + codegen_block_full_ins++; + codegen_endpc = (cs + cpu_state.pc) + 8; - return; - } - } + return; + } + } - op = op_table[((opcode >> opcode_shift) | op_32) & opcode_mask]; -// if (output) -// pclog("Generate call at %08X %02X %08X %02X %08X %08X %08X %08X %08X %02X %02X %02X %02X\n", &codeblock[block_current][block_pos], opcode, new_pc, ram[old_pc], EAX, EBX, ECX, EDX, ESI, ram[0x7bd2+6],ram[0x7bd2+7],ram[0x7bd2+8],ram[0x7bd2+9]); - 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 0 - 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; + op = op_table[((opcode >> opcode_shift) | op_32) & opcode_mask]; + // if (output) + // pclog("Generate call at %08X %02X %08X %02X %08X %08X %08X %08X %08X %02X %02X %02X %02X\n", + // &codeblock[block_current][block_pos], opcode, new_pc, ram[old_pc], EAX, EBX, ECX, EDX, ESI, + // ram[0x7bd2+6],ram[0x7bd2+7],ram[0x7bd2+8],ram[0x7bd2+9]); + 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 0 + 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; + 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; + 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)); + 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; - } -//#endif - 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)(uintptr_t)op_ea_seg); - } + 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; + } + //#endif + 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)(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); - } + 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); + load_param_1_32(block, fetchdat); + call(block, (uintptr_t)op); - codegen_block_ins++; + codegen_block_ins++; - 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])); + 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])); -// call(block, codegen_debug); + // call(block, codegen_debug); - codegen_endpc = (cs + cpu_state.pc) + 8; + codegen_endpc = (cs + cpu_state.pc) + 8; } #endif diff --git a/src/codegen/x86-64/codegen_backend_x86-64.c b/src/codegen/x86-64/codegen_backend_x86-64.c index 936e0f2c..a662705f 100644 --- a/src/codegen/x86-64/codegen_backend_x86-64.c +++ b/src/codegen/x86-64/codegen_backend_x86-64.c @@ -36,329 +36,319 @@ void *codegen_mem_store_double; void *codegen_gpf_rout; void *codegen_exit_rout; -host_reg_def_t codegen_host_reg_list[CODEGEN_HOST_REGS] = - { - /*Note: while EAX and EDX are normally volatile registers under x86 - calling conventions, the recompiler will explicitly save and restore - them across funcion calls*/ - {REG_EAX, 0}, - {REG_EBX, 0}, - {REG_EDX, 0} - }; +host_reg_def_t codegen_host_reg_list[CODEGEN_HOST_REGS] = { + /*Note: while EAX and EDX are normally volatile registers under x86 + calling conventions, the recompiler will explicitly save and restore + them across funcion calls*/ + {REG_EAX, 0}, + {REG_EBX, 0}, + {REG_EDX, 0}}; -host_reg_def_t codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] = - { +host_reg_def_t codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] = { #if WIN64 - /*Windows x86-64 calling convention preserves XMM6-XMM15*/ - {REG_XMM6, 0}, - {REG_XMM7, 0}, + /*Windows x86-64 calling convention preserves XMM6-XMM15*/ + {REG_XMM6, 0}, + {REG_XMM7, 0}, #else - /*System V AMD64 calling convention does not preserve any XMM registers*/ - {REG_XMM6, HOST_REG_FLAG_VOLATILE}, - {REG_XMM7, HOST_REG_FLAG_VOLATILE}, + /*System V AMD64 calling convention does not preserve any XMM registers*/ + {REG_XMM6, HOST_REG_FLAG_VOLATILE}, {REG_XMM7, HOST_REG_FLAG_VOLATILE}, #endif - {REG_XMM1, HOST_REG_FLAG_VOLATILE}, - {REG_XMM2, HOST_REG_FLAG_VOLATILE}, - {REG_XMM3, HOST_REG_FLAG_VOLATILE}, - {REG_XMM4, HOST_REG_FLAG_VOLATILE}, - {REG_XMM5, HOST_REG_FLAG_VOLATILE} - }; + {REG_XMM1, HOST_REG_FLAG_VOLATILE}, + {REG_XMM2, HOST_REG_FLAG_VOLATILE}, + {REG_XMM3, HOST_REG_FLAG_VOLATILE}, + {REG_XMM4, HOST_REG_FLAG_VOLATILE}, + {REG_XMM5, HOST_REG_FLAG_VOLATILE}}; static void build_load_routine(codeblock_t *block, int size, int is_float) { - uint8_t *branch_offset; - uint8_t *misaligned_offset; + uint8_t *branch_offset; + uint8_t *misaligned_offset; - /*In - ESI = address - Out - ECX = data, ESI = abrt*/ - /*MOV ECX, ESI - SHR ESI, 12 - MOV RSI, [readlookup2+ESI*4] - CMP ESI, -1 - JNZ + - MOVZX ECX, B[RSI+RCX] - XOR ESI,ESI - RET - * PUSH EAX - PUSH EDX - PUSH ECX - CALL readmembl - POP ECX - POP EDX - POP EAX - MOVZX ECX, AL - RET - */ - host_x86_MOV32_REG_REG(block, REG_ECX, REG_ESI); - host_x86_SHR32_IMM(block, REG_ESI, 12); - host_x86_MOV64_REG_IMM(block, REG_RDI, (uint64_t)(uintptr_t)readlookup2); - host_x86_MOV64_REG_BASE_INDEX_SHIFT(block, REG_RSI, REG_RDI, REG_RSI, 3); - if (size != 1) { - host_x86_TEST32_REG_IMM(block, REG_ECX, size - 1); - misaligned_offset = host_x86_JNZ_short(block); - } - host_x86_CMP64_REG_IMM(block, REG_RSI, (uint32_t)-1); - branch_offset = host_x86_JZ_short(block); - if (size == 1 && !is_float) - host_x86_MOVZX_BASE_INDEX_32_8(block, REG_ECX, REG_RSI, REG_RCX); - else if (size == 2 && !is_float) - host_x86_MOVZX_BASE_INDEX_32_16(block, REG_ECX, REG_RSI, REG_RCX); - else if (size == 4 && !is_float) - host_x86_MOV32_REG_BASE_INDEX(block, REG_ECX, REG_RSI, REG_RCX); - else if (size == 4 && is_float) - host_x86_CVTSS2SD_XREG_BASE_INDEX(block, REG_XMM_TEMP, REG_RSI, REG_RCX); - else if (size == 8) - host_x86_MOVQ_XREG_BASE_INDEX(block, REG_XMM_TEMP, REG_RSI, REG_RCX); - else - fatal("build_load_routine: size=%i\n", size); - host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI); - host_x86_RET(block); + /*In - ESI = address + Out - ECX = data, ESI = abrt*/ + /*MOV ECX, ESI + SHR ESI, 12 + MOV RSI, [readlookup2+ESI*4] + CMP ESI, -1 + JNZ + + MOVZX ECX, B[RSI+RCX] + XOR ESI,ESI + RET + * PUSH EAX + PUSH EDX + PUSH ECX + CALL readmembl + POP ECX + POP EDX + POP EAX + MOVZX ECX, AL + RET + */ + host_x86_MOV32_REG_REG(block, REG_ECX, REG_ESI); + host_x86_SHR32_IMM(block, REG_ESI, 12); + host_x86_MOV64_REG_IMM(block, REG_RDI, (uint64_t)(uintptr_t)readlookup2); + host_x86_MOV64_REG_BASE_INDEX_SHIFT(block, REG_RSI, REG_RDI, REG_RSI, 3); + if (size != 1) { + host_x86_TEST32_REG_IMM(block, REG_ECX, size - 1); + misaligned_offset = host_x86_JNZ_short(block); + } + host_x86_CMP64_REG_IMM(block, REG_RSI, (uint32_t)-1); + branch_offset = host_x86_JZ_short(block); + if (size == 1 && !is_float) + host_x86_MOVZX_BASE_INDEX_32_8(block, REG_ECX, REG_RSI, REG_RCX); + else if (size == 2 && !is_float) + host_x86_MOVZX_BASE_INDEX_32_16(block, REG_ECX, REG_RSI, REG_RCX); + else if (size == 4 && !is_float) + host_x86_MOV32_REG_BASE_INDEX(block, REG_ECX, REG_RSI, REG_RCX); + else if (size == 4 && is_float) + host_x86_CVTSS2SD_XREG_BASE_INDEX(block, REG_XMM_TEMP, REG_RSI, REG_RCX); + else if (size == 8) + host_x86_MOVQ_XREG_BASE_INDEX(block, REG_XMM_TEMP, REG_RSI, REG_RCX); + else + fatal("build_load_routine: size=%i\n", size); + host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI); + host_x86_RET(block); - *branch_offset = (uint8_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 1; - if (size != 1) - *misaligned_offset = (uint8_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)misaligned_offset) - 1; - host_x86_PUSH(block, REG_RAX); - host_x86_PUSH(block, REG_RDX); + *branch_offset = (uint8_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 1; + if (size != 1) + *misaligned_offset = (uint8_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)misaligned_offset) - 1; + host_x86_PUSH(block, REG_RAX); + host_x86_PUSH(block, REG_RDX); #if WIN64 - host_x86_SUB64_REG_IMM(block, REG_RSP, 0x20); - //host_x86_MOV32_REG_REG(block, REG_ECX, uop->imm_data); + host_x86_SUB64_REG_IMM(block, REG_RSP, 0x20); + // host_x86_MOV32_REG_REG(block, REG_ECX, uop->imm_data); #else - host_x86_MOV32_REG_REG(block, REG_EDI, REG_ECX); + host_x86_MOV32_REG_REG(block, REG_EDI, REG_ECX); #endif - if (size == 1 && !is_float) { - host_x86_CALL(block, (void *)readmembl); - host_x86_MOVZX_REG_32_8(block, REG_ECX, REG_EAX); - } else if (size == 2 && !is_float) { - host_x86_CALL(block, (void *)readmemwl); - host_x86_MOVZX_REG_32_16(block, REG_ECX, REG_EAX); - } else if (size == 4 && !is_float) { - host_x86_CALL(block, (void *)readmemll); - host_x86_MOV32_REG_REG(block, REG_ECX, REG_EAX); - } else if (size == 4 && is_float) { - host_x86_CALL(block, (void *)readmemll); - host_x86_MOVD_XREG_REG(block, REG_XMM_TEMP, REG_EAX); - host_x86_CVTSS2SD_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP); - } else if (size == 8) { - host_x86_CALL(block, (void *)readmemql); - host_x86_MOVQ_XREG_REG(block, REG_XMM_TEMP, REG_RAX); - } + if (size == 1 && !is_float) { + host_x86_CALL(block, (void *)readmembl); + host_x86_MOVZX_REG_32_8(block, REG_ECX, REG_EAX); + } else if (size == 2 && !is_float) { + host_x86_CALL(block, (void *)readmemwl); + host_x86_MOVZX_REG_32_16(block, REG_ECX, REG_EAX); + } else if (size == 4 && !is_float) { + host_x86_CALL(block, (void *)readmemll); + host_x86_MOV32_REG_REG(block, REG_ECX, REG_EAX); + } else if (size == 4 && is_float) { + host_x86_CALL(block, (void *)readmemll); + host_x86_MOVD_XREG_REG(block, REG_XMM_TEMP, REG_EAX); + host_x86_CVTSS2SD_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP); + } else if (size == 8) { + host_x86_CALL(block, (void *)readmemql); + host_x86_MOVQ_XREG_REG(block, REG_XMM_TEMP, REG_RAX); + } #if WIN64 - host_x86_ADD64_REG_IMM(block, REG_RSP, 0x20); + host_x86_ADD64_REG_IMM(block, REG_RSP, 0x20); #endif - host_x86_POP(block, REG_RDX); - host_x86_POP(block, REG_RAX); - host_x86_MOVZX_REG_ABS_32_8(block, REG_ESI, &cpu_state.abrt); - host_x86_RET(block); + host_x86_POP(block, REG_RDX); + host_x86_POP(block, REG_RAX); + host_x86_MOVZX_REG_ABS_32_8(block, REG_ESI, &cpu_state.abrt); + host_x86_RET(block); } static void build_store_routine(codeblock_t *block, int size, int is_float) { - uint8_t *branch_offset; - uint8_t *misaligned_offset; + uint8_t *branch_offset; + uint8_t *misaligned_offset; - /*In - ECX = data, ESI = address - Out - ESI = abrt - Corrupts EDI*/ - /*MOV EDI, ESI - SHR ESI, 12 - MOV ESI, [writelookup2+ESI*4] - CMP ESI, -1 - JNZ + - MOV [RSI+RDI], ECX - XOR ESI,ESI - RET - * PUSH EAX - PUSH EDX - PUSH ECX - CALL writemembl - POP ECX - POP EDX - POP EAX - MOVZX ECX, AL - RET - */ - host_x86_MOV32_REG_REG(block, REG_EDI, REG_ESI); - host_x86_SHR32_IMM(block, REG_ESI, 12); - host_x86_MOV64_REG_IMM(block, REG_R8, (uint64_t)(uintptr_t)writelookup2); - host_x86_MOV64_REG_BASE_INDEX_SHIFT(block, REG_RSI, REG_R8, REG_RSI, 3); - if (size != 1) { - host_x86_TEST32_REG_IMM(block, REG_EDI, size - 1); - misaligned_offset = host_x86_JNZ_short(block); - } - host_x86_CMP64_REG_IMM(block, REG_RSI, (uint32_t)-1); - branch_offset = host_x86_JZ_short(block); - if (size == 1 && !is_float) - host_x86_MOV8_BASE_INDEX_REG(block, REG_RSI, REG_RDI, REG_ECX); - else if (size == 2 && !is_float) - host_x86_MOV16_BASE_INDEX_REG(block, REG_RSI, REG_RDI, REG_ECX); - else if (size == 4 && !is_float) - host_x86_MOV32_BASE_INDEX_REG(block, REG_RSI, REG_RDI, REG_ECX); - else if (size == 4 && is_float) - host_x86_MOVD_BASE_INDEX_XREG(block, REG_RSI, REG_RDI, REG_XMM_TEMP); - else if (size == 8) - host_x86_MOVQ_BASE_INDEX_XREG(block, REG_RSI, REG_RDI, REG_XMM_TEMP); - else - fatal("build_store_routine: size=%i\n", size); - host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI); - host_x86_RET(block); + /*In - ECX = data, ESI = address + Out - ESI = abrt + Corrupts EDI*/ + /*MOV EDI, ESI + SHR ESI, 12 + MOV ESI, [writelookup2+ESI*4] + CMP ESI, -1 + JNZ + + MOV [RSI+RDI], ECX + XOR ESI,ESI + RET + * PUSH EAX + PUSH EDX + PUSH ECX + CALL writemembl + POP ECX + POP EDX + POP EAX + MOVZX ECX, AL + RET + */ + host_x86_MOV32_REG_REG(block, REG_EDI, REG_ESI); + host_x86_SHR32_IMM(block, REG_ESI, 12); + host_x86_MOV64_REG_IMM(block, REG_R8, (uint64_t)(uintptr_t)writelookup2); + host_x86_MOV64_REG_BASE_INDEX_SHIFT(block, REG_RSI, REG_R8, REG_RSI, 3); + if (size != 1) { + host_x86_TEST32_REG_IMM(block, REG_EDI, size - 1); + misaligned_offset = host_x86_JNZ_short(block); + } + host_x86_CMP64_REG_IMM(block, REG_RSI, (uint32_t)-1); + branch_offset = host_x86_JZ_short(block); + if (size == 1 && !is_float) + host_x86_MOV8_BASE_INDEX_REG(block, REG_RSI, REG_RDI, REG_ECX); + else if (size == 2 && !is_float) + host_x86_MOV16_BASE_INDEX_REG(block, REG_RSI, REG_RDI, REG_ECX); + else if (size == 4 && !is_float) + host_x86_MOV32_BASE_INDEX_REG(block, REG_RSI, REG_RDI, REG_ECX); + else if (size == 4 && is_float) + host_x86_MOVD_BASE_INDEX_XREG(block, REG_RSI, REG_RDI, REG_XMM_TEMP); + else if (size == 8) + host_x86_MOVQ_BASE_INDEX_XREG(block, REG_RSI, REG_RDI, REG_XMM_TEMP); + else + fatal("build_store_routine: size=%i\n", size); + host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI); + host_x86_RET(block); - *branch_offset = (uint8_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 1; - if (size != 1) - *misaligned_offset = (uint8_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)misaligned_offset) - 1; - host_x86_PUSH(block, REG_RAX); - host_x86_PUSH(block, REG_RDX); + *branch_offset = (uint8_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 1; + if (size != 1) + *misaligned_offset = (uint8_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)misaligned_offset) - 1; + host_x86_PUSH(block, REG_RAX); + host_x86_PUSH(block, REG_RDX); #if WIN64 - host_x86_SUB64_REG_IMM(block, REG_RSP, 0x28); - if (size == 4 && is_float) - host_x86_MOVD_REG_XREG(block, REG_EDX, REG_XMM_TEMP); //data - else if (size == 8) - host_x86_MOVQ_REG_XREG(block, REG_RDX, REG_XMM_TEMP); //data - else - host_x86_MOV32_REG_REG(block, REG_EDX, REG_ECX); //data - host_x86_MOV32_REG_REG(block, REG_ECX, REG_EDI); //address + host_x86_SUB64_REG_IMM(block, REG_RSP, 0x28); + if (size == 4 && is_float) + host_x86_MOVD_REG_XREG(block, REG_EDX, REG_XMM_TEMP); // data + else if (size == 8) + host_x86_MOVQ_REG_XREG(block, REG_RDX, REG_XMM_TEMP); // data + else + host_x86_MOV32_REG_REG(block, REG_EDX, REG_ECX); // data + host_x86_MOV32_REG_REG(block, REG_ECX, REG_EDI); // address #else - host_x86_SUB64_REG_IMM(block, REG_RSP, 0x8); - //host_x86_MOV32_REG_REG(block, REG_EDI, REG_ECX); //address - if (size == 4 && is_float) - host_x86_MOVD_REG_XREG(block, REG_ESI, REG_XMM_TEMP); //data - else if (size == 8) - host_x86_MOVQ_REG_XREG(block, REG_RSI, REG_XMM_TEMP); //data - else - host_x86_MOV32_REG_REG(block, REG_ESI, REG_ECX); //data + host_x86_SUB64_REG_IMM(block, REG_RSP, 0x8); + // host_x86_MOV32_REG_REG(block, REG_EDI, REG_ECX); //address + if (size == 4 && is_float) + host_x86_MOVD_REG_XREG(block, REG_ESI, REG_XMM_TEMP); // data + else if (size == 8) + host_x86_MOVQ_REG_XREG(block, REG_RSI, REG_XMM_TEMP); // data + else + host_x86_MOV32_REG_REG(block, REG_ESI, REG_ECX); // data #endif - if (size == 1) - host_x86_CALL(block, (void *)writemembl); - else if (size == 2) - host_x86_CALL(block, (void *)writememwl); - else if (size == 4) - host_x86_CALL(block, (void *)writememll); - else if (size == 8) - host_x86_CALL(block, (void *)writememql); + if (size == 1) + host_x86_CALL(block, (void *)writemembl); + else if (size == 2) + host_x86_CALL(block, (void *)writememwl); + else if (size == 4) + host_x86_CALL(block, (void *)writememll); + else if (size == 8) + host_x86_CALL(block, (void *)writememql); #if WIN64 - host_x86_ADD64_REG_IMM(block, REG_RSP, 0x28); + host_x86_ADD64_REG_IMM(block, REG_RSP, 0x28); #else - host_x86_ADD64_REG_IMM(block, REG_RSP, 0x8); + host_x86_ADD64_REG_IMM(block, REG_RSP, 0x8); #endif - host_x86_POP(block, REG_RDX); - host_x86_POP(block, REG_RAX); - host_x86_MOVZX_REG_ABS_32_8(block, REG_ESI, &cpu_state.abrt); - host_x86_RET(block); + host_x86_POP(block, REG_RDX); + host_x86_POP(block, REG_RAX); + host_x86_MOVZX_REG_ABS_32_8(block, REG_ESI, &cpu_state.abrt); + host_x86_RET(block); } static void build_loadstore_routines(codeblock_t *block) { - codegen_mem_load_byte = &codeblock[block_current].data[block_pos]; - build_load_routine(block, 1, 0); - codegen_mem_load_word = &codeblock[block_current].data[block_pos]; - build_load_routine(block, 2, 0); - codegen_mem_load_long = &codeblock[block_current].data[block_pos]; - build_load_routine(block, 4, 0); - codegen_mem_load_quad = &codeblock[block_current].data[block_pos]; - build_load_routine(block, 8, 0); - codegen_mem_load_single = &codeblock[block_current].data[block_pos]; - build_load_routine(block, 4, 1); - codegen_mem_load_double = &codeblock[block_current].data[block_pos]; - build_load_routine(block, 8, 1); + codegen_mem_load_byte = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 1, 0); + codegen_mem_load_word = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 2, 0); + codegen_mem_load_long = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 4, 0); + codegen_mem_load_quad = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 8, 0); + codegen_mem_load_single = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 4, 1); + codegen_mem_load_double = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 8, 1); - codegen_mem_store_byte = &codeblock[block_current].data[block_pos]; - build_store_routine(block, 1, 0); - codegen_mem_store_word = &codeblock[block_current].data[block_pos]; - build_store_routine(block, 2, 0); - codegen_mem_store_long = &codeblock[block_current].data[block_pos]; - build_store_routine(block, 4, 0); - codegen_mem_store_quad = &codeblock[block_current].data[block_pos]; - build_store_routine(block, 8, 0); - codegen_mem_store_single = &codeblock[block_current].data[block_pos]; - build_store_routine(block, 4, 1); - codegen_mem_store_double = &codeblock[block_current].data[block_pos]; - build_store_routine(block, 8, 1); + codegen_mem_store_byte = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 1, 0); + codegen_mem_store_word = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 2, 0); + codegen_mem_store_long = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 4, 0); + codegen_mem_store_quad = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 8, 0); + codegen_mem_store_single = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 4, 1); + codegen_mem_store_double = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 8, 1); } void codegen_backend_init() { - codeblock_t *block; - int c; + codeblock_t *block; + int c; - codeblock = malloc(BLOCK_SIZE * sizeof(codeblock_t)); - codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); + codeblock = malloc(BLOCK_SIZE * sizeof(codeblock_t)); + 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 *)); + 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].pc = BLOCK_PC_INVALID; + for (c = 0; c < BLOCK_SIZE; c++) + codeblock[c].pc = BLOCK_PC_INVALID; -// pclog("Codegen is %p\n", (void *)pages[0xfab12 >> 12].block); + // pclog("Codegen is %p\n", (void *)pages[0xfab12 >> 12].block); - block_current = 0; - block_pos = 0; - block = &codeblock[block_current]; - codeblock[block_current].head_mem_block = codegen_allocator_allocate(NULL, block_current); - codeblock[block_current].data = codeblock_allocator_get_ptr(codeblock[block_current].head_mem_block); - block_write_data = codeblock[block_current].data; - build_loadstore_routines(&codeblock[block_current]); + block_current = 0; + block_pos = 0; + block = &codeblock[block_current]; + codeblock[block_current].head_mem_block = codegen_allocator_allocate(NULL, block_current); + codeblock[block_current].data = codeblock_allocator_get_ptr(codeblock[block_current].head_mem_block); + block_write_data = codeblock[block_current].data; + build_loadstore_routines(&codeblock[block_current]); - codegen_gpf_rout = &codeblock[block_current].data[block_pos]; + codegen_gpf_rout = &codeblock[block_current].data[block_pos]; #if WIN64 - host_x86_XOR32_REG_REG(block, REG_ECX, REG_ECX); - host_x86_XOR32_REG_REG(block, REG_EDX, REG_EDX); + host_x86_XOR32_REG_REG(block, REG_ECX, REG_ECX); + host_x86_XOR32_REG_REG(block, REG_EDX, REG_EDX); #else - host_x86_XOR32_REG_REG(block, REG_EDI, REG_EDI); - host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI); + host_x86_XOR32_REG_REG(block, REG_EDI, REG_EDI); + host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI); #endif - host_x86_CALL(block, (void *)x86gpf); - codegen_exit_rout = &codeblock[block_current].data[block_pos]; - host_x86_ADD64_REG_IMM(block, REG_RSP, 0x38); - host_x86_POP(block, REG_R15); - host_x86_POP(block, REG_R14); - host_x86_POP(block, REG_R13); - host_x86_POP(block, REG_R12); - host_x86_POP(block, REG_RDI); - host_x86_POP(block, REG_RSI); - host_x86_POP(block, REG_RBP); - host_x86_POP(block, REG_RDX); - host_x86_RET(block); + host_x86_CALL(block, (void *)x86gpf); + codegen_exit_rout = &codeblock[block_current].data[block_pos]; + host_x86_ADD64_REG_IMM(block, REG_RSP, 0x38); + host_x86_POP(block, REG_R15); + host_x86_POP(block, REG_R14); + host_x86_POP(block, REG_R13); + host_x86_POP(block, REG_R12); + host_x86_POP(block, REG_RDI); + host_x86_POP(block, REG_RSI); + host_x86_POP(block, REG_RBP); + host_x86_POP(block, REG_RDX); + host_x86_RET(block); - block_write_data = NULL; + block_write_data = NULL; - asm( - "stmxcsr %0\n" - : "=m" (cpu_state.old_fp_control) - ); - cpu_state.trunc_fp_control = cpu_state.old_fp_control | 0x6000; + asm("stmxcsr %0\n" : "=m"(cpu_state.old_fp_control)); + cpu_state.trunc_fp_control = cpu_state.old_fp_control | 0x6000; } -void codegen_set_rounding_mode(int mode) { - cpu_state.new_fp_control = (cpu_state.old_fp_control & ~0x6000) | (mode << 13); -} +void codegen_set_rounding_mode(int mode) { cpu_state.new_fp_control = (cpu_state.old_fp_control & ~0x6000) | (mode << 13); } void codegen_backend_prologue(codeblock_t *block) { - block_pos = BLOCK_START; /*Entry code*/ - host_x86_PUSH(block, REG_RBX); - host_x86_PUSH(block, REG_RBP); - host_x86_PUSH(block, REG_RSI); - host_x86_PUSH(block, REG_RDI); - host_x86_PUSH(block, REG_R12); - host_x86_PUSH(block, REG_R13); - host_x86_PUSH(block, REG_R14); - host_x86_PUSH(block, REG_R15); - host_x86_SUB64_REG_IMM(block, REG_RSP, 0x38); - host_x86_MOV64_REG_IMM(block, REG_RBP, ((uintptr_t)&cpu_state) + 128); - if (block->flags & CODEBLOCK_HAS_FPU) { - host_x86_MOV32_REG_ABS(block, REG_EAX, &cpu_state.TOP); - host_x86_SUB32_REG_IMM(block, REG_EAX, block->TOP); - host_x86_MOV32_BASE_OFFSET_REG(block, REG_RSP, IREG_TOP_diff_stack_offset, REG_EAX); - } - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - host_x86_MOV64_REG_IMM(block, REG_R12, (uintptr_t)ram); + block_pos = BLOCK_START; /*Entry code*/ + host_x86_PUSH(block, REG_RBX); + host_x86_PUSH(block, REG_RBP); + host_x86_PUSH(block, REG_RSI); + host_x86_PUSH(block, REG_RDI); + host_x86_PUSH(block, REG_R12); + host_x86_PUSH(block, REG_R13); + host_x86_PUSH(block, REG_R14); + host_x86_PUSH(block, REG_R15); + host_x86_SUB64_REG_IMM(block, REG_RSP, 0x38); + host_x86_MOV64_REG_IMM(block, REG_RBP, ((uintptr_t)&cpu_state) + 128); + if (block->flags & CODEBLOCK_HAS_FPU) { + host_x86_MOV32_REG_ABS(block, REG_EAX, &cpu_state.TOP); + host_x86_SUB32_REG_IMM(block, REG_EAX, block->TOP); + host_x86_MOV32_BASE_OFFSET_REG(block, REG_RSP, IREG_TOP_diff_stack_offset, REG_EAX); + } + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + host_x86_MOV64_REG_IMM(block, REG_R12, (uintptr_t)ram); } void codegen_backend_epilogue(codeblock_t *block) { - host_x86_ADD64_REG_IMM(block, REG_RSP, 0x38); - host_x86_POP(block, REG_R15); - host_x86_POP(block, REG_R14); - host_x86_POP(block, REG_R13); - host_x86_POP(block, REG_R12); - host_x86_POP(block, REG_RDI); - host_x86_POP(block, REG_RSI); - host_x86_POP(block, REG_RBP); - host_x86_POP(block, REG_RDX); - host_x86_RET(block); + host_x86_ADD64_REG_IMM(block, REG_RSP, 0x38); + host_x86_POP(block, REG_R15); + host_x86_POP(block, REG_R14); + host_x86_POP(block, REG_R13); + host_x86_POP(block, REG_R12); + host_x86_POP(block, REG_RDI); + host_x86_POP(block, REG_RSI); + host_x86_POP(block, REG_RBP); + host_x86_POP(block, REG_RDX); + host_x86_RET(block); } #endif diff --git a/src/codegen/x86-64/codegen_backend_x86-64_ops.c b/src/codegen/x86-64/codegen_backend_x86-64_ops.c index a8d15dc3..3d064f47 100644 --- a/src/codegen/x86-64/codegen_backend_x86-64_ops.c +++ b/src/codegen/x86-64/codegen_backend_x86-64_ops.c @@ -9,7 +9,7 @@ #include "codegen_backend_x86-64_ops_helpers.h" #define RM_OP_ADD 0x00 -#define RM_OP_OR 0x08 +#define RM_OP_OR 0x08 #define RM_OP_AND 0x20 #define RM_OP_SUB 0x28 #define RM_OP_XOR 0x30 @@ -22,1449 +22,1457 @@ #define RM_OP_SAR 0x38 static inline void call(codeblock_t *block, uintptr_t func) { - uintptr_t diff; + uintptr_t diff; - codegen_alloc_bytes(block, 5); - diff = func - (uintptr_t)&block_write_data[block_pos + 5]; + codegen_alloc_bytes(block, 5); + diff = func - (uintptr_t)&block_write_data[block_pos + 5]; - if (diff >= -0x80000000 && diff < 0x7fffffff) { - codegen_addbyte(block, 0xE8); /*CALL*/ - codegen_addlong(block, (uint32_t)diff); - } else { - codegen_alloc_bytes(block, 13); - codegen_addbyte2(block, 0x49, 0xb9); /*MOV R9, func*/ - codegen_addquad(block, func); - codegen_addbyte3(block, 0x41, 0xff, 0xd1); /*CALL R9*/ - } + if (diff >= -0x80000000 && diff < 0x7fffffff) { + codegen_addbyte(block, 0xE8); /*CALL*/ + codegen_addlong(block, (uint32_t)diff); + } else { + codegen_alloc_bytes(block, 13); + codegen_addbyte2(block, 0x49, 0xb9); /*MOV R9, func*/ + codegen_addquad(block, func); + codegen_addbyte3(block, 0x41, 0xff, 0xd1); /*CALL R9*/ + } } static inline void jmp(codeblock_t *block, uintptr_t func) { - uintptr_t diff; + uintptr_t diff; - codegen_alloc_bytes(block, 5); - diff = func - (uintptr_t)&block_write_data[block_pos + 5]; + codegen_alloc_bytes(block, 5); + diff = func - (uintptr_t)&block_write_data[block_pos + 5]; - if (diff >= -0x80000000 && diff < 0x7fffffff) { - codegen_addbyte(block, 0xe9); /*JMP*/ - codegen_addlong(block, (uint32_t)diff); - } else { - codegen_alloc_bytes(block, 13); - codegen_addbyte2(block, 0x49, 0xb9); /*MOV R9, func*/ - codegen_addquad(block, func); - codegen_addbyte3(block, 0x41, 0xff, 0xe1); /*JMP R9*/ - } + if (diff >= -0x80000000 && diff < 0x7fffffff) { + codegen_addbyte(block, 0xe9); /*JMP*/ + codegen_addlong(block, (uint32_t)diff); + } else { + codegen_alloc_bytes(block, 13); + codegen_addbyte2(block, 0x49, 0xb9); /*MOV R9, func*/ + codegen_addquad(block, func); + codegen_addbyte3(block, 0x41, 0xff, 0xe1); /*JMP R9*/ + } } void host_x86_ADD8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) { - if (dst_reg & 8) - fatal("host_x86_ADD8_REG_IMM - dst_reg & 8\n"); + if (dst_reg & 8) + fatal("host_x86_ADD8_REG_IMM - dst_reg & 8\n"); - if (dst_reg == REG_EAX) { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x04, imm_data); /*ADD EAX, imm_data*/ - } else { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_ADD | (dst_reg & 7), imm_data); /*ADD dst_reg, imm_data*/ - } + if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x04, imm_data); /*ADD EAX, imm_data*/ + } else { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_ADD | (dst_reg & 7), imm_data); /*ADD dst_reg, imm_data*/ + } } void host_x86_ADD16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) { - if (dst_reg & 8) - fatal("host_x86_ADD16_REG_IMM - dst_reg & 8\n"); + if (dst_reg & 8) + fatal("host_x86_ADD16_REG_IMM - dst_reg & 8\n"); - if (is_imm8(imm_data)) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_ADD | (dst_reg & 7), imm_data & 0xff); /*ADD dst_reg, imm_data*/ - } else if (dst_reg == REG_EAX) { - codegen_alloc_bytes(block, 4); - codegen_addbyte2(block, 0x66, 0x05); /*AND AX, imm_data*/ - codegen_addword(block, imm_data); - } else { - codegen_alloc_bytes(block, 5); - codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_ADD | (dst_reg & 7)); /*ADD dst_reg, imm_data*/ - codegen_addword(block, imm_data); - } + if (is_imm8(imm_data)) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_ADD | (dst_reg & 7), imm_data & 0xff); /*ADD dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 4); + codegen_addbyte2(block, 0x66, 0x05); /*AND AX, imm_data*/ + codegen_addword(block, imm_data); + } else { + codegen_alloc_bytes(block, 5); + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_ADD | (dst_reg & 7)); /*ADD dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } } void host_x86_ADD32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) { - if (dst_reg & 8) - fatal("host_x86_ADD32_REG_IMM - dst_reg & 8\n"); + if (dst_reg & 8) + fatal("host_x86_ADD32_REG_IMM - dst_reg & 8\n"); - if (is_imm8(imm_data)) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_ADD | (dst_reg & 7), imm_data & 0xff); /*ADD dst_reg, imm_data*/ - } else if (dst_reg == REG_EAX) { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x05); /*ADD EAX, imm_data*/ - codegen_addlong(block, imm_data); - } else { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_ADD | (dst_reg & 7)); /*ADD dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } + if (is_imm8(imm_data)) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_ADD | (dst_reg & 7), imm_data & 0xff); /*ADD dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x05); /*ADD EAX, imm_data*/ + codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_ADD | (dst_reg & 7)); /*ADD dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } } void host_x86_ADD64_REG_IMM(codeblock_t *block, int dst_reg, uint64_t imm_data) { - if (dst_reg & 8) - fatal("host_x86_ADD64_REG_IMM - dst_reg & 8\n"); + if (dst_reg & 8) + fatal("host_x86_ADD64_REG_IMM - dst_reg & 8\n"); - if (is_imm8(imm_data)) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x48, 0x83, 0xc0 | RM_OP_ADD | (dst_reg & 7), imm_data & 0xff); /*ADD dst_reg, imm_data*/ - } else - fatal("ADD64_REG_IMM !is_imm8 %016llx\n", imm_data); + if (is_imm8(imm_data)) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x48, 0x83, 0xc0 | RM_OP_ADD | (dst_reg & 7), imm_data & 0xff); /*ADD dst_reg, imm_data*/ + } else + fatal("ADD64_REG_IMM !is_imm8 %016llx\n", imm_data); } void host_x86_ADD8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_ADD8_REG_REG - dst_reg & 8\n"); + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_ADD8_REG_REG - dst_reg & 8\n"); - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x00, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*ADD dst_reg, src_reg*/ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x00, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*ADD dst_reg, src_reg*/ } void host_x86_ADD16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_ADD16_REG_REG - dst_reg & 8\n"); + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_ADD16_REG_REG - dst_reg & 8\n"); - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x01, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*ADD dst_reg, src_reg*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0x01, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*ADD dst_reg, src_reg*/ } void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_ADD32_REG_REG - dst_reg & 8\n"); + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_ADD32_REG_REG - dst_reg & 8\n"); - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x01, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*ADD dst_reg, src_reg*/ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x01, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*ADD dst_reg, src_reg*/ } void host_x86_AND8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) { - if (dst_reg & 8) - fatal("host_x86_AND8_REG_IMM - dst_reg & 8\n"); + if (dst_reg & 8) + fatal("host_x86_AND8_REG_IMM - dst_reg & 8\n"); - if (dst_reg == REG_EAX) { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x24, imm_data); /*AND EAX, imm_data*/ - } else { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_AND | (dst_reg & 7), imm_data); /*AND dst_reg, imm_data*/ - } + if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x24, imm_data); /*AND EAX, imm_data*/ + } else { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_AND | (dst_reg & 7), imm_data); /*AND dst_reg, imm_data*/ + } } void host_x86_AND16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) { - if (dst_reg & 8) - fatal("host_x86_AND16_REG_IMM - dst_reg & 8\n"); + if (dst_reg & 8) + fatal("host_x86_AND16_REG_IMM - dst_reg & 8\n"); - if (is_imm8(imm_data)) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_AND | (dst_reg & 7), imm_data & 0xff); /*AND dst_reg, imm_data*/ - } else if (dst_reg == REG_EAX) { - codegen_alloc_bytes(block, 4); - codegen_addbyte2(block, 0x66, 0x25); /*AND AX, imm_data*/ - codegen_addword(block, imm_data); - } else { - codegen_alloc_bytes(block, 5); - codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_AND | (dst_reg & 7)); /*AND dst_reg, imm_data*/ - codegen_addword(block, imm_data); - } + if (is_imm8(imm_data)) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_AND | (dst_reg & 7), imm_data & 0xff); /*AND dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 4); + codegen_addbyte2(block, 0x66, 0x25); /*AND AX, imm_data*/ + codegen_addword(block, imm_data); + } else { + codegen_alloc_bytes(block, 5); + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_AND | (dst_reg & 7)); /*AND dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } } void host_x86_AND32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) { - if (dst_reg & 8) - fatal("host_x86_AND32_REG_IMM - dst_reg & 8\n"); + if (dst_reg & 8) + fatal("host_x86_AND32_REG_IMM - dst_reg & 8\n"); - if (is_imm8(imm_data)) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_AND | (dst_reg & 7), imm_data & 0xff); /*AND dst_reg, imm_data*/ - } else if (dst_reg == REG_EAX) { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x25); /*AND EAX, imm_data*/ - codegen_addlong(block, imm_data); - } else { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_AND | (dst_reg & 7)); /*AND dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } + if (is_imm8(imm_data)) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_AND | (dst_reg & 7), imm_data & 0xff); /*AND dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x25); /*AND EAX, imm_data*/ + codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_AND | (dst_reg & 7)); /*AND dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } } void host_x86_AND8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_AND8_REG_REG - dst_reg & 8\n"); + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_AND8_REG_REG - dst_reg & 8\n"); - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x20, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*AND dst_reg, src_reg*/ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x20, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*AND dst_reg, src_reg*/ } void host_x86_AND16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_AND16_REG_REG - dst_reg & 8\n"); + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_AND16_REG_REG - dst_reg & 8\n"); - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x21, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*AND dst_reg, src_reg*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0x21, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*AND dst_reg, src_reg*/ } void host_x86_AND32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_AND32_REG_REG - dst_reg & 8\n"); + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_AND32_REG_REG - dst_reg & 8\n"); - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x21, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*AND dst_reg, src_reg*/ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x21, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*AND dst_reg, src_reg*/ } -void host_x86_CALL(codeblock_t *block, void *p) { - call(block, (uintptr_t)p); -} +void host_x86_CALL(codeblock_t *block, void *p) { call(block, (uintptr_t)p); } void host_x86_CMP16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) { - if (is_imm8(imm_data)) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_CMP | dst_reg, imm_data & 0xff); /*CMP dst_reg, imm_data*/ - } else if (dst_reg == REG_EAX) { - codegen_alloc_bytes(block, 4); - codegen_addbyte2(block, 0x66, 0x3d); /*CMP AX, imm_data*/ - codegen_addword(block, imm_data); - } else { - codegen_alloc_bytes(block, 5); - codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_CMP | dst_reg); /*CMP dst_reg, imm_data*/ - codegen_addword(block, imm_data); - } + if (is_imm8(imm_data)) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_CMP | dst_reg, imm_data & 0xff); /*CMP dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 4); + codegen_addbyte2(block, 0x66, 0x3d); /*CMP AX, imm_data*/ + codegen_addword(block, imm_data); + } else { + codegen_alloc_bytes(block, 5); + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_CMP | dst_reg); /*CMP dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } } void host_x86_CMP32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) { - if (is_imm8(imm_data)) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_CMP | dst_reg, imm_data & 0xff); /*CMP dst_reg, imm_data*/ - } else if (dst_reg == REG_EAX) { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x3d); /*CMP EAX, imm_data*/ - codegen_addlong(block, imm_data); - } else { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_CMP | dst_reg); /*CMP dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } + if (is_imm8(imm_data)) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_CMP | dst_reg, imm_data & 0xff); /*CMP dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x3d); /*CMP EAX, imm_data*/ + codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_CMP | dst_reg); /*CMP dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } } void host_x86_CMP64_REG_IMM(codeblock_t *block, int dst_reg, uint64_t imm_data) { - if (is_imm8(imm_data)) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x48, 0x83, 0xc0 | RM_OP_CMP | dst_reg, imm_data & 0xff); /*CMP dst_reg, imm_data*/ - } else - fatal("CMP64_REG_IMM not 8-bit imm\n"); + if (is_imm8(imm_data)) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x48, 0x83, 0xc0 | RM_OP_CMP | dst_reg, imm_data & 0xff); /*CMP dst_reg, imm_data*/ + } else + fatal("CMP64_REG_IMM not 8-bit imm\n"); } void host_x86_CMP8_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b) { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x38, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x38, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ } void host_x86_CMP16_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x39, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0x39, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ } void host_x86_CMP32_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b) { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x39, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x39, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ } -void host_x86_JMP(codeblock_t *block, void *p) { - jmp(block, (uintptr_t)p); -} +void host_x86_JMP(codeblock_t *block, void *p) { jmp(block, (uintptr_t)p); } void host_x86_JNZ(codeblock_t *block, void *p) { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x85); /*JNZ*/ - codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block_write_data[block_pos + 4]); + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x85); /*JNZ*/ + codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block_write_data[block_pos + 4]); } void host_x86_JZ(codeblock_t *block, void *p) { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x84); /*JZ*/ - codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block_write_data[block_pos + 4]); + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x84); /*JZ*/ + codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block_write_data[block_pos + 4]); } uint8_t *host_x86_JNZ_short(codeblock_t *block) { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x75, 0); /*JNZ*/ - return &block_write_data[block_pos - 1]; + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x75, 0); /*JNZ*/ + return &block_write_data[block_pos - 1]; } uint8_t *host_x86_JS_short(codeblock_t *block) { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x78, 0); /*JS*/ - return &block_write_data[block_pos - 1]; + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x78, 0); /*JS*/ + return &block_write_data[block_pos - 1]; } uint8_t *host_x86_JZ_short(codeblock_t *block) { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x74, 0); /*JZ*/ - return &block_write_data[block_pos - 1]; + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x74, 0); /*JZ*/ + return &block_write_data[block_pos - 1]; } uint32_t *host_x86_JNB_long(codeblock_t *block) { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x83); /*JNB*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos - 4]; + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x83); /*JNB*/ + codegen_addlong(block, 0); + return (uint32_t *)&block_write_data[block_pos - 4]; } uint32_t *host_x86_JNBE_long(codeblock_t *block) { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x87); /*JNBE*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos - 4]; + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x87); /*JNBE*/ + codegen_addlong(block, 0); + return (uint32_t *)&block_write_data[block_pos - 4]; } uint32_t *host_x86_JNL_long(codeblock_t *block) { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x8d); /*JNL*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos - 4]; + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x8d); /*JNL*/ + codegen_addlong(block, 0); + return (uint32_t *)&block_write_data[block_pos - 4]; } uint32_t *host_x86_JNLE_long(codeblock_t *block) { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x8f); /*JNLE*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos - 4]; + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x8f); /*JNLE*/ + codegen_addlong(block, 0); + return (uint32_t *)&block_write_data[block_pos - 4]; } uint32_t *host_x86_JNO_long(codeblock_t *block) { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x81); /*JNO*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos - 4]; + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x81); /*JNO*/ + codegen_addlong(block, 0); + return (uint32_t *)&block_write_data[block_pos - 4]; } uint32_t *host_x86_JNS_long(codeblock_t *block) { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x89); /*JNS*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos - 4]; + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x89); /*JNS*/ + codegen_addlong(block, 0); + return (uint32_t *)&block_write_data[block_pos - 4]; } uint32_t *host_x86_JNZ_long(codeblock_t *block) { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x85); /*JNZ*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos - 4]; + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x85); /*JNZ*/ + codegen_addlong(block, 0); + return (uint32_t *)&block_write_data[block_pos - 4]; } uint32_t *host_x86_JB_long(codeblock_t *block) { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x82); /*JB*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos - 4]; + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x82); /*JB*/ + codegen_addlong(block, 0); + return (uint32_t *)&block_write_data[block_pos - 4]; } uint32_t *host_x86_JBE_long(codeblock_t *block) { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x86); /*JBE*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos - 4]; + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x86); /*JBE*/ + codegen_addlong(block, 0); + return (uint32_t *)&block_write_data[block_pos - 4]; } uint32_t *host_x86_JL_long(codeblock_t *block) { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x8c); /*JL*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos - 4]; + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x8c); /*JL*/ + codegen_addlong(block, 0); + return (uint32_t *)&block_write_data[block_pos - 4]; } uint32_t *host_x86_JLE_long(codeblock_t *block) { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x8e); /*JLE*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos - 4]; + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x8e); /*JLE*/ + codegen_addlong(block, 0); + return (uint32_t *)&block_write_data[block_pos - 4]; } uint32_t *host_x86_JO_long(codeblock_t *block) { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x80); /*JO*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos - 4]; + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x80); /*JO*/ + codegen_addlong(block, 0); + return (uint32_t *)&block_write_data[block_pos - 4]; } uint32_t *host_x86_JS_long(codeblock_t *block) { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x88); /*JS*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos - 4]; + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x88); /*JS*/ + codegen_addlong(block, 0); + return (uint32_t *)&block_write_data[block_pos - 4]; } uint32_t *host_x86_JZ_long(codeblock_t *block) { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x84); /*JZ*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos - 4]; + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x84); /*JZ*/ + codegen_addlong(block, 0); + return (uint32_t *)&block_write_data[block_pos - 4]; } void host_x86_LAHF(codeblock_t *block) { - codegen_alloc_bytes(block, 1); - codegen_addbyte(block, 0x9f); /*LAHF*/ + codegen_alloc_bytes(block, 1); + codegen_addbyte(block, 0x9f); /*LAHF*/ } void host_x86_LEA_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t offset) { - if (offset) { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x8d, 0x80 | (dst_reg << 3) | src_reg); /*LEA dst_reg, [offset+src_reg]*/ - codegen_addlong(block, offset); - } else { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x8d, 0x00 | (dst_reg << 3) | src_reg); /*LEA dst_reg, [src_reg]*/ - } + if (offset) { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x8d, 0x80 | (dst_reg << 3) | src_reg); /*LEA dst_reg, [offset+src_reg]*/ + codegen_addlong(block, offset); + } else { + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x8d, 0x00 | (dst_reg << 3) | src_reg); /*LEA dst_reg, [src_reg]*/ + } } void host_x86_LEA_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) { - if ((dst_reg & 8) || (src_reg_a & 8) || (src_reg_b & 8)) - fatal("host_x86_LEA_REG_REG - bad reg\n"); + if ((dst_reg & 8) || (src_reg_a & 8) || (src_reg_b & 8)) + fatal("host_x86_LEA_REG_REG - bad reg\n"); - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x8d, 0x04 | ((dst_reg & 7) << 3), /*LEA dst_reg, [Rsrc_reg_a + Rsrc_reg_b]*/ - ((src_reg_b & 7) << 3) | (src_reg_a & 7)); + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x8d, 0x04 | ((dst_reg & 7) << 3), /*LEA dst_reg, [Rsrc_reg_a + Rsrc_reg_b]*/ + ((src_reg_b & 7) << 3) | (src_reg_a & 7)); } void host_x86_LEA_REG_REG_SHIFT(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b, int shift) { - if ((dst_reg & 8) || (src_reg_a & 8) || (src_reg_b & 8)) - fatal("host_x86_LEA_REG_REG_SHIFT - bad reg\n"); + if ((dst_reg & 8) || (src_reg_a & 8) || (src_reg_b & 8)) + fatal("host_x86_LEA_REG_REG_SHIFT - bad reg\n"); - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x8d, 0x04 | ((dst_reg & 7) << 3), /*LEA dst_reg, [Rsrc_reg_a + Rsrc_reg_b * (1 << shift)]*/ - (shift << 6) | ((src_reg_b & 7) << 3) | (src_reg_a & 7)); + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x8d, 0x04 | ((dst_reg & 7) << 3), /*LEA dst_reg, [Rsrc_reg_a + Rsrc_reg_b * (1 << shift)]*/ + (shift << 6) | ((src_reg_b & 7) << 3) | (src_reg_a & 7)); } void host_x86_MOV8_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) { - int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - if (offset >= -128 && offset < 127) { - codegen_alloc_bytes(block, 4); - codegen_addbyte3(block, 0xc6, 0x45, offset); /*MOVB offset[RBP], imm_data*/ - codegen_addbyte(block, imm_data); - } else { - if ((uintptr_t)p >> 32) - fatal("host_x86_MOV8_ABS_IMM - out of range %p\n", p); - codegen_alloc_bytes(block, 8); - codegen_addbyte3(block, 0xc6, 0x04, 0x25); /*MOVB p, imm_data*/ - codegen_addlong(block, (uint32_t)(uintptr_t)p); - codegen_addbyte(block, imm_data); - } + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 4); + codegen_addbyte3(block, 0xc6, 0x45, offset); /*MOVB offset[RBP], imm_data*/ + codegen_addbyte(block, imm_data); + } else { + if ((uintptr_t)p >> 32) + fatal("host_x86_MOV8_ABS_IMM - out of range %p\n", p); + codegen_alloc_bytes(block, 8); + codegen_addbyte3(block, 0xc6, 0x04, 0x25); /*MOVB p, imm_data*/ + codegen_addlong(block, (uint32_t)(uintptr_t)p); + codegen_addbyte(block, imm_data); + } } void host_x86_MOV16_ABS_IMM(codeblock_t *block, void *p, uint16_t imm_data) { - int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - if (offset >= -128 && offset < 127) { - codegen_alloc_bytes(block, 6); - codegen_addbyte4(block, 0x66, 0xc7, 0x45, offset); /*MOV offset[RBP], imm_data*/ - codegen_addword(block, imm_data); - } else { - if ((uintptr_t)p >> 32) - fatal("host_x86_MOV32_ABS_IMM - out of range %p\n", p); - codegen_alloc_bytes(block, 10); - codegen_addbyte4(block, 0x66, 0xc7, 0x04, 0x25); /*MOV p, imm_data*/ - codegen_addlong(block, (uint32_t)(uintptr_t)p); - codegen_addword(block, imm_data); - } + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 6); + codegen_addbyte4(block, 0x66, 0xc7, 0x45, offset); /*MOV offset[RBP], imm_data*/ + codegen_addword(block, imm_data); + } else { + if ((uintptr_t)p >> 32) + fatal("host_x86_MOV32_ABS_IMM - out of range %p\n", p); + codegen_alloc_bytes(block, 10); + codegen_addbyte4(block, 0x66, 0xc7, 0x04, 0x25); /*MOV p, imm_data*/ + codegen_addlong(block, (uint32_t)(uintptr_t)p); + codegen_addword(block, imm_data); + } } void host_x86_MOV32_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) { - int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - if (offset >= -128 && offset < 127) { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0xc7, 0x45, offset); /*MOV offset[RBP], imm_data*/ - codegen_addlong(block, imm_data); - } else { - if ((uintptr_t)p >> 32) - fatal("host_x86_MOV32_ABS_IMM - out of range %p\n", p); - codegen_alloc_bytes(block, 11); - codegen_addbyte3(block, 0xc7, 0x04, 0x25); /*MOV p, imm_data*/ - codegen_addlong(block, (uint32_t)(uintptr_t)p); - codegen_addlong(block, imm_data); - } + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0xc7, 0x45, offset); /*MOV offset[RBP], imm_data*/ + codegen_addlong(block, imm_data); + } else { + if ((uintptr_t)p >> 32) + fatal("host_x86_MOV32_ABS_IMM - out of range %p\n", p); + codegen_alloc_bytes(block, 11); + codegen_addbyte3(block, 0xc7, 0x04, 0x25); /*MOV p, imm_data*/ + codegen_addlong(block, (uint32_t)(uintptr_t)p); + codegen_addlong(block, imm_data); + } } void host_x86_MOV8_ABS_REG(codeblock_t *block, void *p, int src_reg) { - int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - if (src_reg & 8) - fatal("host_x86_MOV8_ABS_REG - bad reg\n"); + if (src_reg & 8) + fatal("host_x86_MOV8_ABS_REG - bad reg\n"); - if (offset >= -128 && offset < 127) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x88, 0x45 | ((src_reg & 7) << 3), offset); /*MOVB offset[RBP], src_reg*/ - } else { - if ((uintptr_t)p >> 32) - fatal("host_x86_MOV8_ABS_REG - out of range %p\n", p); - codegen_alloc_bytes(block, 6); - codegen_addbyte(block, 0x88); /*MOVB [p], src_reg*/ - codegen_addbyte(block, 0x05 | ((src_reg & 7) << 3)); - codegen_addlong(block, (uint32_t)(uintptr_t)p); - } + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x88, 0x45 | ((src_reg & 7) << 3), offset); /*MOVB offset[RBP], src_reg*/ + } else { + if ((uintptr_t)p >> 32) + fatal("host_x86_MOV8_ABS_REG - out of range %p\n", p); + codegen_alloc_bytes(block, 6); + codegen_addbyte(block, 0x88); /*MOVB [p], src_reg*/ + codegen_addbyte(block, 0x05 | ((src_reg & 7) << 3)); + codegen_addlong(block, (uint32_t)(uintptr_t)p); + } } void host_x86_MOV16_ABS_REG(codeblock_t *block, void *p, int src_reg) { - int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - if (src_reg & 8) - fatal("host_x86_MOV16_ABS_REG - bad reg\n"); + if (src_reg & 8) + fatal("host_x86_MOV16_ABS_REG - bad reg\n"); - if (offset >= -128 && offset < 127) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x89, 0x45 | ((src_reg & 7) << 3), offset); /*MOV offset[RBP], src_reg*/ - } else if (offset < (1ull << 32)) { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0x66, 0x89, 0x85 | ((src_reg & 7) << 3)); /*MOV offset[RBP], src_reg*/ - codegen_addlong(block, offset); - } else { - if ((uintptr_t)p >> 32) - fatal("host_x86_MOV32_ABS_REG - out of range %p\n", p); - } + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x89, 0x45 | ((src_reg & 7) << 3), offset); /*MOV offset[RBP], src_reg*/ + } else if (offset < (1ull << 32)) { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0x66, 0x89, 0x85 | ((src_reg & 7) << 3)); /*MOV offset[RBP], src_reg*/ + codegen_addlong(block, offset); + } else { + if ((uintptr_t)p >> 32) + fatal("host_x86_MOV32_ABS_REG - out of range %p\n", p); + } } void host_x86_MOV32_ABS_REG(codeblock_t *block, void *p, int src_reg) { - int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - if (src_reg & 8) - fatal("host_x86_MOV32_ABS_REG - bad reg\n"); + if (src_reg & 8) + fatal("host_x86_MOV32_ABS_REG - bad reg\n"); - if (offset >= -128 && offset < 127) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x89, 0x45 | ((src_reg & 7) << 3), offset); /*MOV offset[RBP], src_reg*/ - } else if (offset < (1ull << 32)) { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x89, 0x85 | ((src_reg & 7) << 3)); /*MOV offset[RBP], src_reg*/ - codegen_addlong(block, offset); - } else { - if ((uintptr_t)p >> 32) - fatal("host_x86_MOV32_ABS_REG - out of range %p\n", p); - codegen_alloc_bytes(block, 6); - codegen_addbyte(block, 0x89); /*MOV [p], src_reg*/ - codegen_addbyte(block, 0x05 | ((src_reg & 7) << 3)); - codegen_addlong(block, (uint32_t)(uintptr_t)p); - } + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x89, 0x45 | ((src_reg & 7) << 3), offset); /*MOV offset[RBP], src_reg*/ + } else if (offset < (1ull << 32)) { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x89, 0x85 | ((src_reg & 7) << 3)); /*MOV offset[RBP], src_reg*/ + codegen_addlong(block, offset); + } else { + if ((uintptr_t)p >> 32) + fatal("host_x86_MOV32_ABS_REG - out of range %p\n", p); + codegen_alloc_bytes(block, 6); + codegen_addbyte(block, 0x89); /*MOV [p], src_reg*/ + codegen_addbyte(block, 0x05 | ((src_reg & 7) << 3)); + codegen_addlong(block, (uint32_t)(uintptr_t)p); + } } void host_x86_MOV64_ABS_REG(codeblock_t *block, void *p, int src_reg) { - int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - if (src_reg & 8) - fatal("host_x86_MOV64_ABS_REG - bad reg\n"); + if (src_reg & 8) + fatal("host_x86_MOV64_ABS_REG - bad reg\n"); - if (offset >= -128 && offset < 127) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x48, 0x89, 0x45 | ((src_reg & 7) << 3), offset); /*MOV offset[RBP], src_reg*/ - } else { - if ((uintptr_t)p >> 32) - fatal("host_x86_MOV64_ABS_REG - out of range %p\n", p); - codegen_alloc_bytes(block, 8); - codegen_addbyte4(block, 0x48, 0x89, 0x04 | ((src_reg & 7) << 3), 0x25); /*MOV [p], src_reg*/ - codegen_addlong(block, (uint32_t)(uintptr_t)p); - } + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x48, 0x89, 0x45 | ((src_reg & 7) << 3), offset); /*MOV offset[RBP], src_reg*/ + } else { + if ((uintptr_t)p >> 32) + fatal("host_x86_MOV64_ABS_REG - out of range %p\n", p); + codegen_alloc_bytes(block, 8); + codegen_addbyte4(block, 0x48, 0x89, 0x04 | ((src_reg & 7) << 3), 0x25); /*MOV [p], src_reg*/ + codegen_addlong(block, (uint32_t)(uintptr_t)p); + } } void host_x86_MOV8_ABS_REG_REG_SHIFT_REG(codeblock_t *block, uint32_t addr, int base_reg, int index_reg, int shift, int src_reg) { - if ((src_reg & 8) || (base_reg & 8) | (index_reg & 8)) - fatal("host_x86_MOV8_BASE_INDEX_REG reg & 8\n"); - if (addr < 0x80 || addr >= 0xffffff80) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x88, 0x44 | (src_reg << 3), base_reg | (index_reg << 3) | (shift << 6), addr & 0xff); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ - } else { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0x88, 0x84 | (src_reg << 3), base_reg | (index_reg << 3) | (shift << 6)); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ - codegen_addlong(block, addr); - } + if ((src_reg & 8) || (base_reg & 8) | (index_reg & 8)) + fatal("host_x86_MOV8_BASE_INDEX_REG reg & 8\n"); + if (addr < 0x80 || addr >= 0xffffff80) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x88, 0x44 | (src_reg << 3), base_reg | (index_reg << 3) | (shift << 6), + addr & 0xff); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ + } else { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0x88, 0x84 | (src_reg << 3), + base_reg | (index_reg << 3) | (shift << 6)); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ + codegen_addlong(block, addr); + } } void host_x86_MOV8_BASE_INDEX_REG(codeblock_t *block, int base_reg, int index_reg, int src_reg) { - if ((src_reg & 8) || (base_reg & 8) | (index_reg & 8)) - fatal("host_x86_MOV8_BASE_INDEX_REG reg & 8\n"); - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x88, 0x04 | (src_reg << 3), (index_reg << 3) | base_reg); /*MOV B[base_reg + index_reg], src_reg*/ + if ((src_reg & 8) || (base_reg & 8) | (index_reg & 8)) + fatal("host_x86_MOV8_BASE_INDEX_REG reg & 8\n"); + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x88, 0x04 | (src_reg << 3), + (index_reg << 3) | base_reg); /*MOV B[base_reg + index_reg], src_reg*/ } void host_x86_MOV16_BASE_INDEX_REG(codeblock_t *block, int base_reg, int index_reg, int src_reg) { - if ((src_reg & 8) || (base_reg & 8) | (index_reg & 8)) - fatal("host_x86_MOV8_BASE_INDEX_REG reg & 8\n"); - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x89, 0x04 | (src_reg << 3), (index_reg << 3) | base_reg); /*MOV W[base_reg + index_reg], src_reg*/ + if ((src_reg & 8) || (base_reg & 8) | (index_reg & 8)) + fatal("host_x86_MOV8_BASE_INDEX_REG reg & 8\n"); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x89, 0x04 | (src_reg << 3), + (index_reg << 3) | base_reg); /*MOV W[base_reg + index_reg], src_reg*/ } void host_x86_MOV32_BASE_INDEX_REG(codeblock_t *block, int base_reg, int index_reg, int src_reg) { - if ((src_reg & 8) || (base_reg & 8) | (index_reg & 8)) - fatal("host_x86_MOV8_BASE_INDEX_REG reg & 8\n"); - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x89, 0x04 | (src_reg << 3), (index_reg << 3) | base_reg); /*MOV L[base_reg + index_reg], src_reg*/ + if ((src_reg & 8) || (base_reg & 8) | (index_reg & 8)) + fatal("host_x86_MOV8_BASE_INDEX_REG reg & 8\n"); + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x89, 0x04 | (src_reg << 3), + (index_reg << 3) | base_reg); /*MOV L[base_reg + index_reg], src_reg*/ } void host_x86_MOV8_REG_ABS(codeblock_t *block, int dst_reg, void *p) { - int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - int64_t ram_offset = (uintptr_t)p - (uintptr_t)ram; + int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + int64_t ram_offset = (uintptr_t)p - (uintptr_t)ram; - if (dst_reg & 8) - fatal("host_x86_MOV8_REG_ABS reg & 8\n"); + if (dst_reg & 8) + fatal("host_x86_MOV8_REG_ABS reg & 8\n"); - if (offset >= -128 && offset < 127) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x8a, 0x45 | ((dst_reg & 7) << 3), offset); /*MOV dst_reg, offset[RBP]*/ - } else if (offset < (1ull << 32)) { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x8a, 0x85 | ((dst_reg & 7) << 3)); /*MOV dst_reg, offset[RBP]*/ - codegen_addlong(block, offset); - } else if ((ram_offset < (1ull << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) { - codegen_alloc_bytes(block, 8); - codegen_addbyte4(block, 0x41, 0x8a, 0x84 | ((dst_reg & 7) << 3), 0x24); /*MOV dst_reg, ram_offset[R12]*/ - codegen_addlong(block, ram_offset); - } else { - fatal("host_x86_MOV8_REG_ABS - out of range\n"); - } + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x8a, 0x45 | ((dst_reg & 7) << 3), offset); /*MOV dst_reg, offset[RBP]*/ + } else if (offset < (1ull << 32)) { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x8a, 0x85 | ((dst_reg & 7) << 3)); /*MOV dst_reg, offset[RBP]*/ + codegen_addlong(block, offset); + } else if ((ram_offset < (1ull << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) { + codegen_alloc_bytes(block, 8); + codegen_addbyte4(block, 0x41, 0x8a, 0x84 | ((dst_reg & 7) << 3), 0x24); /*MOV dst_reg, ram_offset[R12]*/ + codegen_addlong(block, ram_offset); + } else { + fatal("host_x86_MOV8_REG_ABS - out of range\n"); + } } void host_x86_MOV16_REG_ABS(codeblock_t *block, int dst_reg, void *p) { - int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - int64_t ram_offset = (uintptr_t)p - (uintptr_t)ram; + int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + int64_t ram_offset = (uintptr_t)p - (uintptr_t)ram; - if (dst_reg & 8) - fatal("host_x86_MOV16_REG_ABS reg & 8\n"); + if (dst_reg & 8) + fatal("host_x86_MOV16_REG_ABS reg & 8\n"); - if (offset >= -128 && offset < 127) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x8b, 0x45 | ((dst_reg & 7) << 3), offset); /*MOV dst_reg, offset[RBP]*/ - } else if (offset < (1ull << 32)) { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0x66, 0x8b, 0x85 | ((dst_reg & 7) << 3)); /*MOV dst_reg, offset[RBP]*/ - codegen_addlong(block, offset); - } else if ((ram_offset < (1ull << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) { - codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0x66, 0x41, 0x8b, 0x84 | ((dst_reg & 7) << 3)); /*MOV dst_reg, ram_offset[R12]*/ - codegen_addbyte(block, 0x24); - codegen_addlong(block, ram_offset); - } else { - fatal("host_x86_MOV16_REG_ABS - out of range\n"); - codegen_alloc_bytes(block, 10); - codegen_addbyte2(block, 0x49, 0xb9); /*MOV R9, p*/ - codegen_addquad(block, (uintptr_t)p); - codegen_alloc_bytes(block, 1); - codegen_addbyte4(block, 0x66, 0x41, 0x8b, 0x01 | ((dst_reg & 7) << 3)); /*MOV dst_reg, [r9]*/ - } + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x8b, 0x45 | ((dst_reg & 7) << 3), offset); /*MOV dst_reg, offset[RBP]*/ + } else if (offset < (1ull << 32)) { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0x66, 0x8b, 0x85 | ((dst_reg & 7) << 3)); /*MOV dst_reg, offset[RBP]*/ + codegen_addlong(block, offset); + } else if ((ram_offset < (1ull << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) { + codegen_alloc_bytes(block, 9); + codegen_addbyte4(block, 0x66, 0x41, 0x8b, 0x84 | ((dst_reg & 7) << 3)); /*MOV dst_reg, ram_offset[R12]*/ + codegen_addbyte(block, 0x24); + codegen_addlong(block, ram_offset); + } else { + fatal("host_x86_MOV16_REG_ABS - out of range\n"); + codegen_alloc_bytes(block, 10); + codegen_addbyte2(block, 0x49, 0xb9); /*MOV R9, p*/ + codegen_addquad(block, (uintptr_t)p); + codegen_alloc_bytes(block, 1); + codegen_addbyte4(block, 0x66, 0x41, 0x8b, 0x01 | ((dst_reg & 7) << 3)); /*MOV dst_reg, [r9]*/ + } } void host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p) { - int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - int64_t ram_offset = (uintptr_t)p - (uintptr_t)ram; + int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + int64_t ram_offset = (uintptr_t)p - (uintptr_t)ram; - if (dst_reg & 8) - fatal("host_x86_MOV32_REG_ABS reg & 8\n"); + if (dst_reg & 8) + fatal("host_x86_MOV32_REG_ABS reg & 8\n"); - if (offset >= -128 && offset < 127) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x8b, 0x45 | ((dst_reg & 7) << 3), offset); /*MOV dst_reg, offset[RBP]*/ - } else if (offset < (1ull << 32)) { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x8b, 0x85 | ((dst_reg & 7) << 3)); /*MOV dst_reg, offset[RBP]*/ - codegen_addlong(block, offset); - } else if ((ram_offset < (1ull << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) { - codegen_alloc_bytes(block, 8); - codegen_addbyte4(block, 0x41, 0x8b, 0x84 | ((dst_reg & 7) << 3), 0x24); /*MOV dst_reg, ram_offset[R12]*/ - codegen_addlong(block, ram_offset); - } else { - fatal("host_x86_MOV32_REG_ABS - out of range\n"); - codegen_alloc_bytes(block, 6); - codegen_addbyte(block, 0x8b); /*MOV [p], src_reg*/ - codegen_addbyte(block, 0x05 | ((dst_reg & 7) << 3)); - codegen_addlong(block, (uint32_t)(uintptr_t)p); - } + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x8b, 0x45 | ((dst_reg & 7) << 3), offset); /*MOV dst_reg, offset[RBP]*/ + } else if (offset < (1ull << 32)) { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x8b, 0x85 | ((dst_reg & 7) << 3)); /*MOV dst_reg, offset[RBP]*/ + codegen_addlong(block, offset); + } else if ((ram_offset < (1ull << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) { + codegen_alloc_bytes(block, 8); + codegen_addbyte4(block, 0x41, 0x8b, 0x84 | ((dst_reg & 7) << 3), 0x24); /*MOV dst_reg, ram_offset[R12]*/ + codegen_addlong(block, ram_offset); + } else { + fatal("host_x86_MOV32_REG_ABS - out of range\n"); + codegen_alloc_bytes(block, 6); + codegen_addbyte(block, 0x8b); /*MOV [p], src_reg*/ + codegen_addbyte(block, 0x05 | ((dst_reg & 7) << 3)); + codegen_addlong(block, (uint32_t)(uintptr_t)p); + } } void host_x86_MOV64_REG_ABS(codeblock_t *block, int dst_reg, void *p) { - int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - if (dst_reg & 8) - fatal("host_x86_MOV64_REG_ABS reg & 8\n"); + if (dst_reg & 8) + fatal("host_x86_MOV64_REG_ABS reg & 8\n"); - if (offset >= -128 && offset < 127) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x48, 0x8b, 0x45 | ((dst_reg & 7) << 3), offset); /*MOV dst_reg, offset[RBP]*/ - } else if (offset < (1ull << 32)) { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0x48, 0x8b, 0x85 | ((dst_reg & 7) << 3)); /*MOV dst_reg, offset[RBP]*/ - codegen_addlong(block, offset); - } else - fatal("host_x86_MOV64_REG_ABS - out of range\n"); + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x48, 0x8b, 0x45 | ((dst_reg & 7) << 3), offset); /*MOV dst_reg, offset[RBP]*/ + } else if (offset < (1ull << 32)) { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0x48, 0x8b, 0x85 | ((dst_reg & 7) << 3)); /*MOV dst_reg, offset[RBP]*/ + codegen_addlong(block, offset); + } else + fatal("host_x86_MOV64_REG_ABS - out of range\n"); } void host_x86_MOV8_REG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int base_reg, int index_reg, int shift) { - if ((dst_reg & 8) || (base_reg & 8) | (index_reg & 8)) - fatal("host_x86_MOV8_REG_ABS_REG_REG_SHIFT reg & 8\n"); - if (addr < 0x80 || addr >= 0xffffff80) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x8a, 0x44 | (dst_reg << 3), base_reg | (index_reg << 3) | (shift << 6), addr & 0xff); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ - } else { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0x8a, 0x84 | (dst_reg << 3), base_reg | (index_reg << 3) | (shift << 6)); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ - codegen_addlong(block, addr); - } + if ((dst_reg & 8) || (base_reg & 8) | (index_reg & 8)) + fatal("host_x86_MOV8_REG_ABS_REG_REG_SHIFT reg & 8\n"); + if (addr < 0x80 || addr >= 0xffffff80) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x8a, 0x44 | (dst_reg << 3), base_reg | (index_reg << 3) | (shift << 6), + addr & 0xff); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ + } else { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0x8a, 0x84 | (dst_reg << 3), + base_reg | (index_reg << 3) | (shift << 6)); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ + codegen_addlong(block, addr); + } } void host_x86_MOV32_REG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int index_reg) { - if ((dst_reg & 8) || (base_reg & 8) | (index_reg & 8)) - fatal("host_x86_MOV32_REG_BASE_INDEX reg & 8\n"); - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x8b, 0x04 | (dst_reg << 3), (index_reg << 3) | base_reg); /*MOV dst_reg, Q[base_reg + index_reg]*/ + if ((dst_reg & 8) || (base_reg & 8) | (index_reg & 8)) + fatal("host_x86_MOV32_REG_BASE_INDEX reg & 8\n"); + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x8b, 0x04 | (dst_reg << 3), + (index_reg << 3) | base_reg); /*MOV dst_reg, Q[base_reg + index_reg]*/ } void host_x86_MOV64_REG_BASE_INDEX_SHIFT(codeblock_t *block, int dst_reg, int base_reg, int index_reg, int scale) { - if ((dst_reg & 8) || (index_reg & 8)) - fatal("host_x86_MOV64_REG_BASE_INDEX_SHIFT reg & 8\n"); - codegen_alloc_bytes(block, 4); - if (base_reg & 8) - codegen_addbyte4(block, 0x49, 0x8b, 0x04 | ((dst_reg & 7) << 3), (scale << 6) | ((index_reg & 7) << 3) | (base_reg & 7)); /*MOV dst_reg, Q[base_reg + index_reg << scale]*/ - else - codegen_addbyte4(block, 0x48, 0x8b, 0x04 | ((dst_reg & 7) << 3), (scale << 6) | ((index_reg & 7) << 3) | (base_reg & 7)); /*MOV dst_reg, Q[base_reg + index_reg << scale]*/ + if ((dst_reg & 8) || (index_reg & 8)) + fatal("host_x86_MOV64_REG_BASE_INDEX_SHIFT reg & 8\n"); + codegen_alloc_bytes(block, 4); + if (base_reg & 8) + codegen_addbyte4(block, 0x49, 0x8b, 0x04 | ((dst_reg & 7) << 3), + (scale << 6) | ((index_reg & 7) << 3) | + (base_reg & 7)); /*MOV dst_reg, Q[base_reg + index_reg << scale]*/ + else + codegen_addbyte4(block, 0x48, 0x8b, 0x04 | ((dst_reg & 7) << 3), + (scale << 6) | ((index_reg & 7) << 3) | + (base_reg & 7)); /*MOV dst_reg, Q[base_reg + index_reg << scale]*/ } void host_x86_MOV16_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset) { - if ((dst_reg & 8) || (base_reg & 8)) - fatal("host_x86_MOV16_REG_BASE_OFFSET reg & 8\n"); + if ((dst_reg & 8) || (base_reg & 8)) + fatal("host_x86_MOV16_REG_BASE_OFFSET reg & 8\n"); - if (offset >= -128 && offset < 127) { - if (base_reg == REG_RSP) { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x66); - codegen_addbyte4(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), 0x24, offset); - } else { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x8b, 0x40 | base_reg | (dst_reg << 3), offset); - } - } else - fatal("MOV16_REG_BASE_OFFSET - offset %i\n", offset); + if (offset >= -128 && offset < 127) { + if (base_reg == REG_RSP) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x66); + codegen_addbyte4(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), 0x24, offset); + } else { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x8b, 0x40 | base_reg | (dst_reg << 3), offset); + } + } else + fatal("MOV16_REG_BASE_OFFSET - offset %i\n", offset); } void host_x86_MOV32_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset) { - if ((dst_reg & 8) || (base_reg & 8)) - fatal("host_x86_MOV32_REG_BASE_OFFSET reg & 8\n"); + if ((dst_reg & 8) || (base_reg & 8)) + fatal("host_x86_MOV32_REG_BASE_OFFSET reg & 8\n"); - if (offset >= -128 && offset < 127) { - if (base_reg == REG_RSP) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), 0x24, offset); - } else { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), offset); - } - } else - fatal("MOV32_REG_BASE_OFFSET - offset %i\n", offset); + if (offset >= -128 && offset < 127) { + if (base_reg == REG_RSP) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), 0x24, offset); + } else { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), offset); + } + } else + fatal("MOV32_REG_BASE_OFFSET - offset %i\n", offset); } void host_x86_MOV64_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset) { - if ((dst_reg & 8) || (base_reg & 8)) - fatal("host_x86_MOV64_REG_BASE_OFFSET reg & 8\n"); + if ((dst_reg & 8) || (base_reg & 8)) + fatal("host_x86_MOV64_REG_BASE_OFFSET reg & 8\n"); - if (offset >= -128 && offset < 127) { - if (base_reg == REG_RSP) { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x48); - codegen_addbyte4(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), 0x24, offset); - } else { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x48, 0x8b, 0x40 | base_reg | (dst_reg << 3), offset); - } - } else - fatal("MOV32_REG_BASE_OFFSET - offset %i\n", offset); + if (offset >= -128 && offset < 127) { + if (base_reg == REG_RSP) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x48); + codegen_addbyte4(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), 0x24, offset); + } else { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x48, 0x8b, 0x40 | base_reg | (dst_reg << 3), offset); + } + } else + fatal("MOV32_REG_BASE_OFFSET - offset %i\n", offset); } void host_x86_MOV32_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int src_reg) { - if ((src_reg & 8) || (base_reg & 8)) - fatal("host_x86_MOV32_BASE_OFFSET_REG reg & 8\n"); + if ((src_reg & 8) || (base_reg & 8)) + fatal("host_x86_MOV32_BASE_OFFSET_REG reg & 8\n"); - if (offset >= -128 && offset < 127) { - if (base_reg == REG_RSP) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x89, 0x40 | base_reg | (src_reg << 3), 0x24, offset); - } else { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x89, 0x40 | base_reg | (src_reg << 3), offset); - } - } else - fatal("MOV32_BASE_OFFSET_REG - offset %i\n", offset); + if (offset >= -128 && offset < 127) { + if (base_reg == REG_RSP) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x89, 0x40 | base_reg | (src_reg << 3), 0x24, offset); + } else { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x89, 0x40 | base_reg | (src_reg << 3), offset); + } + } else + fatal("MOV32_BASE_OFFSET_REG - offset %i\n", offset); } void host_x86_MOV64_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int src_reg) { - if ((src_reg & 8) || (base_reg & 8)) - fatal("host_x86_MOV64_BASE_OFFSET_REG reg & 8\n"); + if ((src_reg & 8) || (base_reg & 8)) + fatal("host_x86_MOV64_BASE_OFFSET_REG reg & 8\n"); - if (offset >= -128 && offset < 127) { - if (base_reg == REG_RSP) { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x48); - codegen_addbyte4(block, 0x89, 0x40 | base_reg | (src_reg << 3), 0x24, offset); - } else { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x48, 0x89, 0x40 | base_reg | (src_reg << 3), offset); - } - } else - fatal("MOV64_BASE_OFFSET_REG - offset %i\n", offset); + if (offset >= -128 && offset < 127) { + if (base_reg == REG_RSP) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x48); + codegen_addbyte4(block, 0x89, 0x40 | base_reg | (src_reg << 3), 0x24, offset); + } else { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x48, 0x89, 0x40 | base_reg | (src_reg << 3), offset); + } + } else + fatal("MOV64_BASE_OFFSET_REG - offset %i\n", offset); } void host_x86_MOV32_BASE_OFFSET_IMM(codeblock_t *block, int base_reg, int offset, uint32_t imm_data) { - if (base_reg & 8) - fatal("host_x86_MOV32_BASE_OFFSET_IMM reg & 8\n"); + if (base_reg & 8) + fatal("host_x86_MOV32_BASE_OFFSET_IMM reg & 8\n"); - if (offset >= -128 && offset < 127) { - if (base_reg == REG_RSP) { - codegen_alloc_bytes(block, 8); - codegen_addbyte4(block, 0xc7, 0x40 | base_reg, 0x24, offset); - codegen_addlong(block, imm_data); - } else { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0xc7, 0x40 | base_reg, offset); - codegen_addlong(block, imm_data); - } - } else - fatal("MOV32_BASE_OFFSET_IMM - offset %i\n", offset); + if (offset >= -128 && offset < 127) { + if (base_reg == REG_RSP) { + codegen_alloc_bytes(block, 8); + codegen_addbyte4(block, 0xc7, 0x40 | base_reg, 0x24, offset); + codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0xc7, 0x40 | base_reg, offset); + codegen_addlong(block, imm_data); + } + } else + fatal("MOV32_BASE_OFFSET_IMM - offset %i\n", offset); } void host_x86_MOV8_REG_IMM(codeblock_t *block, int reg, uint16_t imm_data) { - if (reg >= 8) - fatal("host_x86_MOV8_REG_IMM reg >= 4\n"); - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xb0 | reg, imm_data); /*MOV reg, imm_data*/ + if (reg >= 8) + fatal("host_x86_MOV8_REG_IMM reg >= 4\n"); + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xb0 | reg, imm_data); /*MOV reg, imm_data*/ } void host_x86_MOV16_REG_IMM(codeblock_t *block, int reg, uint16_t imm_data) { - if (reg & 8) - fatal("host_x86_MOV16_REG_IMM reg & 8\n"); - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x66, 0xb8 | (reg & 7)); /*MOV reg, imm_data*/ - codegen_addword(block, imm_data); + if (reg & 8) + fatal("host_x86_MOV16_REG_IMM reg & 8\n"); + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x66, 0xb8 | (reg & 7)); /*MOV reg, imm_data*/ + codegen_addword(block, imm_data); } void host_x86_MOV32_REG_IMM(codeblock_t *block, int reg, uint32_t imm_data) { - if (reg & 8) - fatal("host_x86_MOV32_REG_IMM reg & 8\n"); - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0xb8 | (reg & 7)); /*MOV reg, imm_data*/ - codegen_addlong(block, imm_data); + if (reg & 8) + fatal("host_x86_MOV32_REG_IMM reg & 8\n"); + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0xb8 | (reg & 7)); /*MOV reg, imm_data*/ + codegen_addlong(block, imm_data); } void host_x86_MOV64_REG_IMM(codeblock_t *block, int reg, uint64_t imm_data) { - if (reg & 8) { - codegen_alloc_bytes(block, 10); - codegen_addbyte2(block, 0x49, 0xb8 | (reg & 7)); /*MOVQ reg, imm_data*/ - codegen_addquad(block, imm_data); - } else { - codegen_alloc_bytes(block, 10); - codegen_addbyte2(block, 0x48, 0xb8 | (reg & 7)); /*MOVQ reg, imm_data*/ - codegen_addquad(block, imm_data); - } + if (reg & 8) { + codegen_alloc_bytes(block, 10); + codegen_addbyte2(block, 0x49, 0xb8 | (reg & 7)); /*MOVQ reg, imm_data*/ + codegen_addquad(block, imm_data); + } else { + codegen_alloc_bytes(block, 10); + codegen_addbyte2(block, 0x48, 0xb8 | (reg & 7)); /*MOVQ reg, imm_data*/ + codegen_addquad(block, imm_data); + } } void host_x86_MOV8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_MOV8_REG_REG - bad reg\n"); + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_MOV8_REG_REG - bad reg\n"); - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x88, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x88, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); } void host_x86_MOV16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_MOV16_REG_REG - bad reg\n"); + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_MOV16_REG_REG - bad reg\n"); - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x89, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0x89, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); } void host_x86_MOV32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_MOV32_REG_REG - bad reg\n"); + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_MOV32_REG_REG - bad reg\n"); - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x89, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x89, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); } void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_t imm_data) { - if (!offset) { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0xc7, 0x04, 0x24); /*MOV [ESP], imm_data*/ - codegen_addlong(block, imm_data); - } else if (offset >= -0x80 && offset < 0x80) { - codegen_alloc_bytes(block, 8); - codegen_addbyte4(block, 0xc7, 0x44, 0x24, offset & 0xff); /*MOV offset[ESP], imm_data*/ - codegen_addlong(block, imm_data); - } else { - codegen_alloc_bytes(block, 11); - codegen_addbyte3(block, 0xc7, 0x84, 0x24); /*MOV offset[ESP], imm_data*/ - codegen_addlong(block, offset); - codegen_addlong(block, imm_data); - } + if (!offset) { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0xc7, 0x04, 0x24); /*MOV [ESP], imm_data*/ + codegen_addlong(block, imm_data); + } else if (offset >= -0x80 && offset < 0x80) { + codegen_alloc_bytes(block, 8); + codegen_addbyte4(block, 0xc7, 0x44, 0x24, offset & 0xff); /*MOV offset[ESP], imm_data*/ + codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 11); + codegen_addbyte3(block, 0xc7, 0x84, 0x24); /*MOV offset[ESP], imm_data*/ + codegen_addlong(block, offset); + codegen_addlong(block, imm_data); + } } void host_x86_MOVSX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xbe, 0xc0 | (dst_reg << 3) | src_reg); /*MOVSX dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xbe, 0xc0 | (dst_reg << 3) | src_reg); /*MOVSX dst_reg, src_reg*/ } void host_x86_MOVSX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0xbe, 0xc0 | (dst_reg << 3) | src_reg); /*MOVSX dst_reg, src_reg*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0xbe, 0xc0 | (dst_reg << 3) | src_reg); /*MOVSX dst_reg, src_reg*/ } void host_x86_MOVSX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0xbf, 0xc0 | (dst_reg << 3) | src_reg); /*MOVSX dst_reg, src_reg*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0xbf, 0xc0 | (dst_reg << 3) | src_reg); /*MOVSX dst_reg, src_reg*/ } void host_x86_MOVZX_BASE_INDEX_32_8(codeblock_t *block, int dst_reg, int base_reg, int index_reg) { - if ((dst_reg & 8) || (base_reg & 8) | (index_reg & 8)) - fatal("host_x86_MOVZX_BASE_INDEX_32_8 reg & 8\n"); + if ((dst_reg & 8) || (base_reg & 8) | (index_reg & 8)) + fatal("host_x86_MOVZX_BASE_INDEX_32_8 reg & 8\n"); - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x0f, 0xb6, 0x04 | (dst_reg << 3), (index_reg << 3) | base_reg); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x0f, 0xb6, 0x04 | (dst_reg << 3), (index_reg << 3) | base_reg); } void host_x86_MOVZX_BASE_INDEX_32_16(codeblock_t *block, int dst_reg, int base_reg, int index_reg) { - if ((dst_reg & 8) || (base_reg & 8) | (index_reg & 8)) - fatal("host_x86_MOVZX_BASE_INDEX_32_16 reg & 8\n"); + if ((dst_reg & 8) || (base_reg & 8) | (index_reg & 8)) + fatal("host_x86_MOVZX_BASE_INDEX_32_16 reg & 8\n"); - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x0f, 0xb7, 0x04 | (dst_reg << 3), (index_reg << 3) | base_reg); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x0f, 0xb7, 0x04 | (dst_reg << 3), (index_reg << 3) | base_reg); } void host_x86_MOVZX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg) { - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_MOVZX_REG_16_8 - bad reg\n"); + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_MOVZX_REG_16_8 - bad reg\n"); - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xb6, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xb6, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ } void host_x86_MOVZX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg) { - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_MOVZX_REG_32_8 - bad reg\n"); + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_MOVZX_REG_32_8 - bad reg\n"); - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0xb6, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0xb6, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ } void host_x86_MOVZX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg) { - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_MOVZX_REG_16_8 - bad reg\n"); + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_MOVZX_REG_16_8 - bad reg\n"); - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0xb7, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0xb7, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ } void host_x86_MOVZX_REG_ABS_16_8(codeblock_t *block, int dst_reg, void *p) { - int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - int64_t ram_offset = (uintptr_t)p - (uintptr_t)ram; + int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + int64_t ram_offset = (uintptr_t)p - (uintptr_t)ram; - if (dst_reg & 8) - fatal("host_x86_MOVZX_REG_ABS_16_8 - bad reg\n"); + if (dst_reg & 8) + fatal("host_x86_MOVZX_REG_ABS_16_8 - bad reg\n"); - if (offset >= -128 && offset < 127) { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x66); - codegen_addbyte4(block, 0x0f, 0xb6, 0x45 | ((dst_reg & 7) << 3), offset); /*MOVZX dst_reg, offset[RBP]*/ - } else if ((ram_offset < (1ull << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) { - codegen_alloc_bytes(block, 10); - codegen_addbyte2(block, 0x66, 0x41); - codegen_addbyte4(block, 0x0f, 0xb6, 0x84 | ((dst_reg & 7) << 3), 0x24); /*MOVZX dst_reg, ram_offset[R12]*/ - codegen_addlong(block, ram_offset); - } else { - codegen_alloc_bytes(block, 10); - codegen_addbyte2(block, 0x49, 0xb9); /*MOV R9, p*/ - codegen_addquad(block, (uintptr_t)p); - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x66); - codegen_addbyte4(block, 0x41, 0x0f, 0xb6, 0x01 | ((dst_reg & 7) << 3)); /*MOVZX dst_reg, [r9]*/ - } + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x66); + codegen_addbyte4(block, 0x0f, 0xb6, 0x45 | ((dst_reg & 7) << 3), offset); /*MOVZX dst_reg, offset[RBP]*/ + } else if ((ram_offset < (1ull << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) { + codegen_alloc_bytes(block, 10); + codegen_addbyte2(block, 0x66, 0x41); + codegen_addbyte4(block, 0x0f, 0xb6, 0x84 | ((dst_reg & 7) << 3), 0x24); /*MOVZX dst_reg, ram_offset[R12]*/ + codegen_addlong(block, ram_offset); + } else { + codegen_alloc_bytes(block, 10); + codegen_addbyte2(block, 0x49, 0xb9); /*MOV R9, p*/ + codegen_addquad(block, (uintptr_t)p); + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x66); + codegen_addbyte4(block, 0x41, 0x0f, 0xb6, 0x01 | ((dst_reg & 7) << 3)); /*MOVZX dst_reg, [r9]*/ + } } void host_x86_MOVZX_REG_ABS_32_8(codeblock_t *block, int dst_reg, void *p) { - int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - int64_t ram_offset = (uintptr_t)p - (uintptr_t)ram; + int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + int64_t ram_offset = (uintptr_t)p - (uintptr_t)ram; -// if (dst_reg & 8) -// fatal("host_x86_MOVZX_REG_ABS_32_8 - bad reg\n"); + // if (dst_reg & 8) + // fatal("host_x86_MOVZX_REG_ABS_32_8 - bad reg\n"); - if (offset >= -128 && offset < 127) { - if (dst_reg & 8) { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x44); - codegen_addbyte4(block, 0x0f, 0xb6, 0x45 | ((dst_reg & 7) << 3), offset); /*MOVZX dst_reg, offset[RBP]*/ - } else { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x0f, 0xb6, 0x45 | ((dst_reg & 7) << 3), offset); /*MOVZX dst_reg, offset[RBP]*/ - } - } else if ((ram_offset < (1ull << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) { - if (dst_reg & 8) - fatal("host_x86_MOVZX_REG_ABS_32_8 - bad reg\n"); + if (offset >= -128 && offset < 127) { + if (dst_reg & 8) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x44); + codegen_addbyte4(block, 0x0f, 0xb6, 0x45 | ((dst_reg & 7) << 3), offset); /*MOVZX dst_reg, offset[RBP]*/ + } else { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x0f, 0xb6, 0x45 | ((dst_reg & 7) << 3), offset); /*MOVZX dst_reg, offset[RBP]*/ + } + } else if ((ram_offset < (1ull << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) { + if (dst_reg & 8) + fatal("host_x86_MOVZX_REG_ABS_32_8 - bad reg\n"); - codegen_alloc_bytes(block, 9); - codegen_addbyte(block, 0x41); - codegen_addbyte4(block, 0x0f, 0xb6, 0x84 | ((dst_reg & 7) << 3), 0x24); /*MOVZX dst_reg, ram_offset[R12]*/ - codegen_addlong(block, ram_offset); - } else { - if (dst_reg & 8) - fatal("host_x86_MOVZX_REG_ABS_32_8 - bad reg\n"); + codegen_alloc_bytes(block, 9); + codegen_addbyte(block, 0x41); + codegen_addbyte4(block, 0x0f, 0xb6, 0x84 | ((dst_reg & 7) << 3), 0x24); /*MOVZX dst_reg, ram_offset[R12]*/ + codegen_addlong(block, ram_offset); + } else { + if (dst_reg & 8) + fatal("host_x86_MOVZX_REG_ABS_32_8 - bad reg\n"); - codegen_alloc_bytes(block, 10); - codegen_addbyte2(block, 0x49, 0xb9); /*MOV R9, p*/ - codegen_addquad(block, (uintptr_t)p); - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x41, 0x0f, 0xb6, 0x01 | ((dst_reg & 7) << 3)); /*MOVZX dst_reg, [r9]*/ - } + codegen_alloc_bytes(block, 10); + codegen_addbyte2(block, 0x49, 0xb9); /*MOV R9, p*/ + codegen_addquad(block, (uintptr_t)p); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x41, 0x0f, 0xb6, 0x01 | ((dst_reg & 7) << 3)); /*MOVZX dst_reg, [r9]*/ + } } void host_x86_MOVZX_REG_ABS_32_16(codeblock_t *block, int dst_reg, void *p) { - int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - int64_t ram_offset = (uintptr_t)p - (uintptr_t)ram; + int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + int64_t ram_offset = (uintptr_t)p - (uintptr_t)ram; - if (dst_reg & 8) - fatal("host_x86_MOVZX_REG_ABS_32_16 - bad reg\n"); + if (dst_reg & 8) + fatal("host_x86_MOVZX_REG_ABS_32_16 - bad reg\n"); - if (offset >= -128 && offset < 127) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x0f, 0xb7, 0x45 | ((dst_reg & 7) << 3), offset); /*MOVZX dst_reg, offset[RBP]*/ - } else if ((ram_offset < (1ull << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) { - codegen_alloc_bytes(block, 9); - codegen_addbyte(block, 0x41); - codegen_addbyte4(block, 0x0f, 0xb7, 0x84 | ((dst_reg & 7) << 3), 0x24); /*MOVZX dst_reg, ram_offset[R12]*/ - codegen_addlong(block, ram_offset); - } else { - codegen_alloc_bytes(block, 10); - codegen_addbyte2(block, 0x49, 0xb9); /*MOV R9, p*/ - codegen_addquad(block, (uintptr_t)p); - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x41, 0x0f, 0xb7, 0x01 | ((dst_reg & 7) << 3)); /*MOVZX dst_reg, [r9]*/ - } + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x0f, 0xb7, 0x45 | ((dst_reg & 7) << 3), offset); /*MOVZX dst_reg, offset[RBP]*/ + } else if ((ram_offset < (1ull << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) { + codegen_alloc_bytes(block, 9); + codegen_addbyte(block, 0x41); + codegen_addbyte4(block, 0x0f, 0xb7, 0x84 | ((dst_reg & 7) << 3), 0x24); /*MOVZX dst_reg, ram_offset[R12]*/ + codegen_addlong(block, ram_offset); + } else { + codegen_alloc_bytes(block, 10); + codegen_addbyte2(block, 0x49, 0xb9); /*MOV R9, p*/ + codegen_addquad(block, (uintptr_t)p); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x41, 0x0f, 0xb7, 0x01 | ((dst_reg & 7) << 3)); /*MOVZX dst_reg, [r9]*/ + } } void host_x86_NOP(codeblock_t *block) { - codegen_alloc_bytes(block, 1); - codegen_addbyte(block, 0x90); /*NOP*/ + codegen_alloc_bytes(block, 1); + codegen_addbyte(block, 0x90); /*NOP*/ } void host_x86_OR8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) { - if (dst_reg & 8) - fatal("host_x86_OR8_REG_IMM - dst_reg & 8\n"); + if (dst_reg & 8) + fatal("host_x86_OR8_REG_IMM - dst_reg & 8\n"); - if (dst_reg == REG_EAX) { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x0c, imm_data); /*OR EAX, imm_data*/ - } else { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_OR | (dst_reg & 7), imm_data); /*OR dst_reg, imm_data*/ - } + if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x0c, imm_data); /*OR EAX, imm_data*/ + } else { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_OR | (dst_reg & 7), imm_data); /*OR dst_reg, imm_data*/ + } } void host_x86_OR16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) { - if (dst_reg & 8) - fatal("host_x86_OR16_REG_IMM - dst_reg & 8\n"); + if (dst_reg & 8) + fatal("host_x86_OR16_REG_IMM - dst_reg & 8\n"); - if (is_imm8(imm_data)) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_OR | (dst_reg & 7), imm_data & 0xff); /*OR dst_reg, imm_data*/ - } else if (dst_reg == REG_EAX) { - codegen_alloc_bytes(block, 4); - codegen_addbyte2(block, 0x66, 0x0d); /*OR AX, imm_data*/ - codegen_addword(block, imm_data); - } else { - codegen_alloc_bytes(block, 5); - codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_OR | (dst_reg & 7)); /*OR dst_reg, imm_data*/ - codegen_addword(block, imm_data); - } + if (is_imm8(imm_data)) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_OR | (dst_reg & 7), imm_data & 0xff); /*OR dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 4); + codegen_addbyte2(block, 0x66, 0x0d); /*OR AX, imm_data*/ + codegen_addword(block, imm_data); + } else { + codegen_alloc_bytes(block, 5); + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_OR | (dst_reg & 7)); /*OR dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } } void host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) { - if (dst_reg & 8) - fatal("host_x86_OR32_REG_IMM - dst_reg & 8\n"); + if (dst_reg & 8) + fatal("host_x86_OR32_REG_IMM - dst_reg & 8\n"); - if (is_imm8(imm_data)) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_OR | (dst_reg & 7), imm_data & 0xff); /*OR dst_reg, imm_data*/ - } else if (dst_reg == REG_EAX) { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x0d); /*OR EAX, imm_data*/ - codegen_addlong(block, imm_data); - } else { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_OR | (dst_reg & 7)); /*OR dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } + if (is_imm8(imm_data)) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_OR | (dst_reg & 7), imm_data & 0xff); /*OR dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x0d); /*OR EAX, imm_data*/ + codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_OR | (dst_reg & 7)); /*OR dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } } void host_x86_OR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_OR8_REG_IMM - dst_reg & 8\n"); + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_OR8_REG_IMM - dst_reg & 8\n"); - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x08, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*OR dst_reg, src_reg*/ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x08, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*OR dst_reg, src_reg*/ } void host_x86_OR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_OR16_REG_IMM - dst_reg & 8\n"); + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_OR16_REG_IMM - dst_reg & 8\n"); - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x09, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*OR dst_reg, src_reg*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0x09, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*OR dst_reg, src_reg*/ } void host_x86_OR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_OR32_REG_IMM - dst_reg & 8\n"); + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_OR32_REG_IMM - dst_reg & 8\n"); - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x09, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*OR dst_reg, src_reg*/ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x09, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*OR dst_reg, src_reg*/ } void host_x86_POP(codeblock_t *block, int dst_reg) { - if (dst_reg & 8) { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x41, 0x58 | (dst_reg & 7)); /*POP reg*/ - } else { - codegen_alloc_bytes(block, 1); - codegen_addbyte(block, 0x58 | dst_reg); /*POP reg*/ - } + if (dst_reg & 8) { + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x41, 0x58 | (dst_reg & 7)); /*POP reg*/ + } else { + codegen_alloc_bytes(block, 1); + codegen_addbyte(block, 0x58 | dst_reg); /*POP reg*/ + } } void host_x86_PUSH(codeblock_t *block, int src_reg) { - if (src_reg & 8) { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x41, 0x50 | (src_reg & 7)); /*PUSH reg*/ - } else { - codegen_alloc_bytes(block, 1); - codegen_addbyte(block, 0x50 | src_reg); /*PUSH reg*/ - } + if (src_reg & 8) { + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x41, 0x50 | (src_reg & 7)); /*PUSH reg*/ + } else { + codegen_alloc_bytes(block, 1); + codegen_addbyte(block, 0x50 | src_reg); /*PUSH reg*/ + } } void host_x86_RET(codeblock_t *block) { - codegen_alloc_bytes(block, 1); - codegen_addbyte(block, 0xc3); /*RET*/ + codegen_alloc_bytes(block, 1); + codegen_addbyte(block, 0xc3); /*RET*/ } void host_x86_ROL8_CL(codeblock_t *block, int dst_reg) { - if (dst_reg & 8) - fatal("ROL8 CL & 8\n"); - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_ROL | dst_reg); /*SHL dst_reg, CL*/ + if (dst_reg & 8) + fatal("ROL8 CL & 8\n"); + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_ROL | dst_reg); /*SHL dst_reg, CL*/ } void host_x86_ROL16_CL(codeblock_t *block, int dst_reg) { - if (dst_reg & 8) - fatal("ROL16 CL & 8\n"); - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_ROL | dst_reg); /*SHL dst_reg, CL*/ + if (dst_reg & 8) + fatal("ROL16 CL & 8\n"); + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_ROL | dst_reg); /*SHL dst_reg, CL*/ } void host_x86_ROL32_CL(codeblock_t *block, int dst_reg) { - if (dst_reg & 8) - fatal("ROL32 CL & 8\n"); - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_ROL | dst_reg); /*SHL dst_reg, CL*/ + if (dst_reg & 8) + fatal("ROL32 CL & 8\n"); + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_ROL | dst_reg); /*SHL dst_reg, CL*/ } void host_x86_ROL8_IMM(codeblock_t *block, int dst_reg, int shift) { - if (dst_reg & 8) - fatal("ROL8 imm & 8\n"); - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_ROL | dst_reg, shift); /*SHL dst_reg, shift*/ + if (dst_reg & 8) + fatal("ROL8 imm & 8\n"); + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_ROL | dst_reg, shift); /*SHL dst_reg, shift*/ } void host_x86_ROL16_IMM(codeblock_t *block, int dst_reg, int shift) { - if (dst_reg & 8) - fatal("ROL16 imm & 8\n"); - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_ROL | dst_reg, shift); /*SHL dst_reg, shift*/ + if (dst_reg & 8) + fatal("ROL16 imm & 8\n"); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_ROL | dst_reg, shift); /*SHL dst_reg, shift*/ } void host_x86_ROL32_IMM(codeblock_t *block, int dst_reg, int shift) { - if (dst_reg & 8) - fatal("ROL32 imm & 8\n"); - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_ROL | dst_reg, shift); /*SHL dst_reg, shift*/ + if (dst_reg & 8) + fatal("ROL32 imm & 8\n"); + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_ROL | dst_reg, shift); /*SHL dst_reg, shift*/ } void host_x86_ROR8_CL(codeblock_t *block, int dst_reg) { - if (dst_reg & 8) - fatal("ROR8 CL & 8\n"); - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_ROR | dst_reg); /*SHR dst_reg, CL*/ + if (dst_reg & 8) + fatal("ROR8 CL & 8\n"); + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_ROR | dst_reg); /*SHR dst_reg, CL*/ } void host_x86_ROR16_CL(codeblock_t *block, int dst_reg) { - if (dst_reg & 8) - fatal("ROR16 CL & 8\n"); - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_ROR | dst_reg); /*SHR dst_reg, CL*/ + if (dst_reg & 8) + fatal("ROR16 CL & 8\n"); + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_ROR | dst_reg); /*SHR dst_reg, CL*/ } void host_x86_ROR32_CL(codeblock_t *block, int dst_reg) { - if (dst_reg & 8) - fatal("ROR32 CL & 8\n"); - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_ROR | dst_reg); /*SHR dst_reg, CL*/ + if (dst_reg & 8) + fatal("ROR32 CL & 8\n"); + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_ROR | dst_reg); /*SHR dst_reg, CL*/ } void host_x86_ROR8_IMM(codeblock_t *block, int dst_reg, int shift) { - if (dst_reg & 8) - fatal("ROR8 imm & 8\n"); - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_ROR | dst_reg, shift); /*SHR dst_reg, shift*/ + if (dst_reg & 8) + fatal("ROR8 imm & 8\n"); + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_ROR | dst_reg, shift); /*SHR dst_reg, shift*/ } void host_x86_ROR16_IMM(codeblock_t *block, int dst_reg, int shift) { - if (dst_reg & 8) - fatal("ROR16 imm & 8\n"); - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_ROR | dst_reg, shift); /*SHR dst_reg, shift*/ + if (dst_reg & 8) + fatal("ROR16 imm & 8\n"); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_ROR | dst_reg, shift); /*SHR dst_reg, shift*/ } void host_x86_ROR32_IMM(codeblock_t *block, int dst_reg, int shift) { - if (dst_reg & 8) - fatal("ROR32 im & 8\n"); - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_ROR | dst_reg, shift); /*SHR dst_reg, shift*/ + if (dst_reg & 8) + fatal("ROR32 im & 8\n"); + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_ROR | dst_reg, shift); /*SHR dst_reg, shift*/ } void host_x86_SAR8_CL(codeblock_t *block, int dst_reg) { - if (dst_reg & 8) - fatal("SAR8 CL & 8\n"); + if (dst_reg & 8) + fatal("SAR8 CL & 8\n"); - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/ } void host_x86_SAR16_CL(codeblock_t *block, int dst_reg) { - if (dst_reg & 8) - fatal("SAR16 CL & 8\n"); + if (dst_reg & 8) + fatal("SAR16 CL & 8\n"); - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/ } void host_x86_SAR32_CL(codeblock_t *block, int dst_reg) { - if (dst_reg & 8) - fatal("SAR32 CL & 8\n"); + if (dst_reg & 8) + fatal("SAR32 CL & 8\n"); - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/ } void host_x86_SAR8_IMM(codeblock_t *block, int dst_reg, int shift) { - if (dst_reg & 8) - fatal("SAR8 imm & 8\n"); + if (dst_reg & 8) + fatal("SAR8 imm & 8\n"); - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/ } void host_x86_SAR16_IMM(codeblock_t *block, int dst_reg, int shift) { - if (dst_reg & 8) - fatal("SAR16 imm & 8\n"); + if (dst_reg & 8) + fatal("SAR16 imm & 8\n"); - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/ } void host_x86_SAR32_IMM(codeblock_t *block, int dst_reg, int shift) { - if (dst_reg & 8) - fatal("SAR32 imm & 8\n"); - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/ + if (dst_reg & 8) + fatal("SAR32 imm & 8\n"); + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/ } void host_x86_SHL8_CL(codeblock_t *block, int dst_reg) { - if (dst_reg & 8) - fatal("SHL8 CL & 8\n"); + if (dst_reg & 8) + fatal("SHL8 CL & 8\n"); - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/ } void host_x86_SHL16_CL(codeblock_t *block, int dst_reg) { - if (dst_reg & 8) - fatal("SHL16 CL & 8\n"); + if (dst_reg & 8) + fatal("SHL16 CL & 8\n"); - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/ } void host_x86_SHL32_CL(codeblock_t *block, int dst_reg) { - if (dst_reg & 8) - fatal("SHL32 CL & 8\n"); + if (dst_reg & 8) + fatal("SHL32 CL & 8\n"); - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/ } void host_x86_SHL8_IMM(codeblock_t *block, int dst_reg, int shift) { - if (dst_reg & 8) - fatal("SHL8 imm & 8\n"); + if (dst_reg & 8) + fatal("SHL8 imm & 8\n"); - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/ } void host_x86_SHL16_IMM(codeblock_t *block, int dst_reg, int shift) { - if (dst_reg & 8) - fatal("SHL16 imm & 8\n"); + if (dst_reg & 8) + fatal("SHL16 imm & 8\n"); - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/ } void host_x86_SHL32_IMM(codeblock_t *block, int dst_reg, int shift) { - if (dst_reg & 8) - fatal("SHL32 imm & 8\n"); + if (dst_reg & 8) + fatal("SHL32 imm & 8\n"); - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/ } void host_x86_SHR8_CL(codeblock_t *block, int dst_reg) { - if (dst_reg & 8) - fatal("SHR8 CL & 8\n"); + if (dst_reg & 8) + fatal("SHR8 CL & 8\n"); - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/ } void host_x86_SHR16_CL(codeblock_t *block, int dst_reg) { - if (dst_reg & 8) - fatal("SHR16 CL & 8\n"); + if (dst_reg & 8) + fatal("SHR16 CL & 8\n"); - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/ } void host_x86_SHR32_CL(codeblock_t *block, int dst_reg) { - if (dst_reg & 8) - fatal("SHR32 CL & 8\n"); + if (dst_reg & 8) + fatal("SHR32 CL & 8\n"); - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/ } void host_x86_SHR8_IMM(codeblock_t *block, int dst_reg, int shift) { - if (dst_reg & 8) - fatal("SHR8 imm & 8\n"); + if (dst_reg & 8) + fatal("SHR8 imm & 8\n"); - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ } void host_x86_SHR16_IMM(codeblock_t *block, int dst_reg, int shift) { - if (dst_reg & 8) - fatal("SHR16 imm & 8\n"); + if (dst_reg & 8) + fatal("SHR16 imm & 8\n"); - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ } void host_x86_SHR32_IMM(codeblock_t *block, int dst_reg, int shift) { - if (dst_reg & 8) - fatal("SHR32 imm & 8\n"); - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ + if (dst_reg & 8) + fatal("SHR32 imm & 8\n"); + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ } void host_x86_SUB8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) { - if (dst_reg & 8) - fatal("host_x86_SUB8_REG_IMM - dst_reg & 8\n"); + if (dst_reg & 8) + fatal("host_x86_SUB8_REG_IMM - dst_reg & 8\n"); - if (dst_reg == REG_EAX) { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x2c, imm_data); /*SUB EAX, imm_data*/ - } else { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_SUB | (dst_reg & 7), imm_data); /*SUB dst_reg, imm_data*/ - } + if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x2c, imm_data); /*SUB EAX, imm_data*/ + } else { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_SUB | (dst_reg & 7), imm_data); /*SUB dst_reg, imm_data*/ + } } void host_x86_SUB16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) { - if (dst_reg & 8) - fatal("host_x86_SUB16_REG_IMM - dst_reg & 8\n"); + if (dst_reg & 8) + fatal("host_x86_SUB16_REG_IMM - dst_reg & 8\n"); - if (is_imm8(imm_data)) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_SUB | (dst_reg & 7), imm_data & 0xff); /*SUB dst_reg, imm_data*/ - } else if (dst_reg == REG_EAX) { - codegen_alloc_bytes(block, 4); - codegen_addbyte2(block, 0x66, 0x2d); /*SUB AX, imm_data*/ - codegen_addword(block, imm_data); - } else { - codegen_alloc_bytes(block, 5); - codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_SUB | (dst_reg & 7)); /*SUB dst_reg, imm_data*/ - codegen_addword(block, imm_data); - } + if (is_imm8(imm_data)) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_SUB | (dst_reg & 7), imm_data & 0xff); /*SUB dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 4); + codegen_addbyte2(block, 0x66, 0x2d); /*SUB AX, imm_data*/ + codegen_addword(block, imm_data); + } else { + codegen_alloc_bytes(block, 5); + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_SUB | (dst_reg & 7)); /*SUB dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } } void host_x86_SUB32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) { - if (dst_reg & 8) - fatal("host_x86_SUB32_REG_IMM - dst_reg & 8\n"); + if (dst_reg & 8) + fatal("host_x86_SUB32_REG_IMM - dst_reg & 8\n"); - if (is_imm8(imm_data)) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_SUB | (dst_reg & 7), imm_data & 0xff); /*SUB dst_reg, imm_data*/ - } else if (dst_reg == REG_EAX) { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x2d); /*SUB EAX, imm_data*/ - codegen_addlong(block, imm_data); - } else { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_SUB | (dst_reg & 7)); /*SUB dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } + if (is_imm8(imm_data)) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_SUB | (dst_reg & 7), imm_data & 0xff); /*SUB dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x2d); /*SUB EAX, imm_data*/ + codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_SUB | (dst_reg & 7)); /*SUB dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } } void host_x86_SUB64_REG_IMM(codeblock_t *block, int dst_reg, uint64_t imm_data) { - if (dst_reg & 8) - fatal("host_x86_SUB64_REG_IMM - dst_reg & 8\n"); + if (dst_reg & 8) + fatal("host_x86_SUB64_REG_IMM - dst_reg & 8\n"); - if (is_imm8(imm_data)) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x48, 0x83, 0xc0 | RM_OP_SUB | (dst_reg & 7), imm_data & 0xff); /*SUB dst_reg, imm_data*/ - } else - fatal("SUB64_REG_IMM !is_imm8 %016llx\n", imm_data); + if (is_imm8(imm_data)) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x48, 0x83, 0xc0 | RM_OP_SUB | (dst_reg & 7), imm_data & 0xff); /*SUB dst_reg, imm_data*/ + } else + fatal("SUB64_REG_IMM !is_imm8 %016llx\n", imm_data); } void host_x86_SUB8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_SUB8_REG_REG - dst_reg & 8\n"); + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_SUB8_REG_REG - dst_reg & 8\n"); - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x28, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*SUB dst_reg, src_reg*/ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x28, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*SUB dst_reg, src_reg*/ } void host_x86_SUB16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_SUB16_REG_REG - dst_reg & 8\n"); + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_SUB16_REG_REG - dst_reg & 8\n"); - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x29, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*SUB dst_reg, src_reg*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0x29, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*SUB dst_reg, src_reg*/ } void host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_SUB32_REG_REG - dst_reg & 8\n"); + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_SUB32_REG_REG - dst_reg & 8\n"); - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x29, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*SUB dst_reg, src_reg*/ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x29, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*SUB dst_reg, src_reg*/ } #define MODRM_MOD_REG(rm, reg) (0xc0 | reg | (rm << 3)) void host_x86_TEST8_REG(codeblock_t *block, int src_host_reg, int dst_host_reg) { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x84, MODRM_MOD_REG(dst_host_reg, src_host_reg)); /*TEST dst_host_reg, src_host_reg*/ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x84, MODRM_MOD_REG(dst_host_reg, src_host_reg)); /*TEST dst_host_reg, src_host_reg*/ } void host_x86_TEST16_REG(codeblock_t *block, int src_host_reg, int dst_host_reg) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x85, MODRM_MOD_REG(dst_host_reg, src_host_reg)); /*TEST dst_host_reg, src_host_reg*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0x85, MODRM_MOD_REG(dst_host_reg, src_host_reg)); /*TEST dst_host_reg, src_host_reg*/ } void host_x86_TEST32_REG(codeblock_t *block, int src_reg, int dst_reg) { - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_TEST32_REG - bad reg\n"); + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_TEST32_REG - bad reg\n"); - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x85, MODRM_MOD_REG(dst_reg, src_reg)); /*TEST dst_host_reg, src_host_reg*/ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x85, MODRM_MOD_REG(dst_reg, src_reg)); /*TEST dst_host_reg, src_host_reg*/ } void host_x86_TEST32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) { - if (dst_reg & 8) - fatal("TEST32_REG_IMM reg & 8\n"); - if (dst_reg == REG_EAX) { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0xa9); /*TEST EAX, imm_data*/ - codegen_addlong(block, imm_data); - } else { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0xf7, 0xc0 | dst_reg); /*TEST dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } + if (dst_reg & 8) + fatal("TEST32_REG_IMM reg & 8\n"); + if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0xa9); /*TEST EAX, imm_data*/ + codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0xf7, 0xc0 | dst_reg); /*TEST dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } } void host_x86_XOR8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) { - if (dst_reg & 8) - fatal("host_x86_XOR8_REG_IMM - dst_reg & 8\n"); + if (dst_reg & 8) + fatal("host_x86_XOR8_REG_IMM - dst_reg & 8\n"); - if (dst_reg == REG_EAX) { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x34, imm_data); /*XOR EAX, imm_data*/ - } else { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_XOR | (dst_reg & 7), imm_data); /*XOR dst_reg, imm_data*/ - } + if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x34, imm_data); /*XOR EAX, imm_data*/ + } else { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_XOR | (dst_reg & 7), imm_data); /*XOR dst_reg, imm_data*/ + } } void host_x86_XOR16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) { - if (dst_reg & 8) - fatal("host_x86_XOR16_REG_IMM - dst_reg & 8\n"); + if (dst_reg & 8) + fatal("host_x86_XOR16_REG_IMM - dst_reg & 8\n"); - if (is_imm8(imm_data)) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_XOR | (dst_reg & 7), imm_data & 0xff); /*XOR dst_reg, imm_data*/ - } else if (dst_reg == REG_EAX) { - codegen_alloc_bytes(block, 4); - codegen_addbyte2(block, 0x66, 0x35); /*XOR AX, imm_data*/ - codegen_addword(block, imm_data); - } else { - codegen_alloc_bytes(block, 5); - codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_XOR | (dst_reg & 7)); /*XOR dst_reg, imm_data*/ - codegen_addword(block, imm_data); - } + if (is_imm8(imm_data)) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_XOR | (dst_reg & 7), imm_data & 0xff); /*XOR dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 4); + codegen_addbyte2(block, 0x66, 0x35); /*XOR AX, imm_data*/ + codegen_addword(block, imm_data); + } else { + codegen_alloc_bytes(block, 5); + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_XOR | (dst_reg & 7)); /*XOR dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } } void host_x86_XOR32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) { - if (dst_reg & 8) - fatal("host_x86_XOR32_REG_IMM - dst_reg & 8\n"); + if (dst_reg & 8) + fatal("host_x86_XOR32_REG_IMM - dst_reg & 8\n"); - if (is_imm8(imm_data)) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_XOR | (dst_reg & 7), imm_data & 0xff); /*XOR dst_reg, imm_data*/ - } else if (dst_reg == REG_EAX) { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x35); /*XOR EAX, imm_data*/ - codegen_addlong(block, imm_data); - } else { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_XOR | (dst_reg & 7)); /*XOR dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } + if (is_imm8(imm_data)) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_XOR | (dst_reg & 7), imm_data & 0xff); /*XOR dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x35); /*XOR EAX, imm_data*/ + codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_XOR | (dst_reg & 7)); /*XOR dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } } void host_x86_XOR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_XOR8_REG_IMM - dst_reg & 8\n"); + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_XOR8_REG_IMM - dst_reg & 8\n"); - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x30, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*XOR dst_reg, src_reg*/ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x30, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*XOR dst_reg, src_reg*/ } void host_x86_XOR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_XOR16_REG_IMM - dst_reg & 8\n"); + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_XOR16_REG_IMM - dst_reg & 8\n"); - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x31, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*XOR dst_reg, src_reg*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0x31, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*XOR dst_reg, src_reg*/ } void host_x86_XOR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_XOR32_REG_IMM - dst_reg & 8\n"); + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_XOR32_REG_IMM - dst_reg & 8\n"); - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x31, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*XOR dst_reg, src_reg*/ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x31, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*XOR dst_reg, src_reg*/ } #endif diff --git a/src/codegen/x86-64/codegen_backend_x86-64_ops_sse.c b/src/codegen/x86-64/codegen_backend_x86-64_ops_sse.c index 04bef6b0..5fa9c744 100644 --- a/src/codegen/x86-64/codegen_backend_x86-64_ops_sse.c +++ b/src/codegen/x86-64/codegen_backend_x86-64_ops_sse.c @@ -9,492 +9,502 @@ #include "codegen_backend_x86-64_ops_helpers.h" void host_x86_ADDPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0x58, 0xc0 | src_reg | (dst_reg << 3)); /*ADDPS dst_reg, src_reg*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0x58, 0xc0 | src_reg | (dst_reg << 3)); /*ADDPS dst_reg, src_reg*/ } void host_x86_ADDSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x58, 0xc0 | src_reg | (dst_reg << 3)); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x58, 0xc0 | src_reg | (dst_reg << 3)); } void host_x86_CMPPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg, int type) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x0f, 0xc2, 0xc0 | src_reg | (dst_reg << 3), type); /*CMPPS dst_reg, src_reg, type*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x0f, 0xc2, 0xc0 | src_reg | (dst_reg << 3), type); /*CMPPS dst_reg, src_reg, type*/ } void host_x86_COMISD_XREG_XREG(codeblock_t *block, int src_reg_a, int src_reg_b) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x2e, 0xc0 | src_reg_b | (src_reg_a << 3)); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x2e, 0xc0 | src_reg_b | (src_reg_a << 3)); } void host_x86_CVTDQ2PS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0x5b, 0xc0 | src_reg | (dst_reg << 3)); /*CVTDQ2PS dst_reg, src_reg*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0x5b, 0xc0 | src_reg | (dst_reg << 3)); /*CVTDQ2PS dst_reg, src_reg*/ } void host_x86_CVTPS2DQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x5b, 0xc0 | src_reg | (dst_reg << 3)); /*CVTPS2DQ dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x5b, 0xc0 | src_reg | (dst_reg << 3)); /*CVTPS2DQ dst_reg, src_reg*/ } void host_x86_CVTSD2SI_REG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x2d, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSD2SI dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x2d, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSD2SI dst_reg, src_reg*/ } void host_x86_CVTSD2SI_REG64_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0xf2, 0x48, 0x0f, 0x2d); /*CVTSD2SI dst_reg, src_reg*/ - codegen_addbyte(block, 0xc0 | src_reg | (dst_reg << 3)); + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0xf2, 0x48, 0x0f, 0x2d); /*CVTSD2SI dst_reg, src_reg*/ + codegen_addbyte(block, 0xc0 | src_reg | (dst_reg << 3)); } void host_x86_CVTSD2SS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x5a, 0xc0 | src_reg | (dst_reg << 3)); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x5a, 0xc0 | src_reg | (dst_reg << 3)); } void host_x86_CVTSI2SD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x2a, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSI2SD dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x2a, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSI2SD dst_reg, src_reg*/ } void host_x86_CVTSI2SS_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf3, 0x0f, 0x2a, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSI2SD dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf3, 0x0f, 0x2a, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSI2SD dst_reg, src_reg*/ } void host_x86_CVTSI2SD_XREG_REG64(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0xf2, 0x48, 0x0f, 0x2a); /*CVTSI2SD dst_reg, src_reg*/ - codegen_addbyte(block, 0xc0 | src_reg | (dst_reg << 3)); + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0xf2, 0x48, 0x0f, 0x2a); /*CVTSI2SD dst_reg, src_reg*/ + codegen_addbyte(block, 0xc0 | src_reg | (dst_reg << 3)); } void host_x86_CVTSS2SD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf3, 0x0f, 0x5a, 0xc0 | src_reg | (dst_reg << 3)); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf3, 0x0f, 0x5a, 0xc0 | src_reg | (dst_reg << 3)); } void host_x86_CVTSS2SD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf3, 0x0f, 0x5a, 0x04 | (dst_reg << 3)); /*CVTSS2SD XMMx, [base_reg + idx_reg]*/ - codegen_addbyte(block, base_reg | (idx_reg << 3)); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf3, 0x0f, 0x5a, 0x04 | (dst_reg << 3)); /*CVTSS2SD XMMx, [base_reg + idx_reg]*/ + codegen_addbyte(block, base_reg | (idx_reg << 3)); } void host_x86_DIVSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x5e, 0xc0 | src_reg | (dst_reg << 3)); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x5e, 0xc0 | src_reg | (dst_reg << 3)); } void host_x86_DIVSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf3, 0x0f, 0x5e, 0xc0 | src_reg | (dst_reg << 3)); /*DIVSS dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf3, 0x0f, 0x5e, 0xc0 | src_reg | (dst_reg << 3)); /*DIVSS dst_reg, src_reg*/ } void host_x86_LDMXCSR(codeblock_t *block, void *p) { - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - if (offset >= -128 && offset < 127) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x0f, 0xae, 0x50 | REG_EBP, offset); /*LDMXCSR offset[EBP]*/ - } else if (offset < (1ull << 32)) { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0x0f, 0xae, 0x90 | REG_EBP); /*LDMXCSR offset[EBP]*/ - codegen_addlong(block, offset); - } else { - fatal("host_x86_LDMXCSR - out of range %p\n", p); - } + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x0f, 0xae, 0x50 | REG_EBP, offset); /*LDMXCSR offset[EBP]*/ + } else if (offset < (1ull << 32)) { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0x0f, 0xae, 0x90 | REG_EBP); /*LDMXCSR offset[EBP]*/ + codegen_addlong(block, offset); + } else { + fatal("host_x86_LDMXCSR - out of range %p\n", p); + } } void host_x86_MAXSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x5f, 0xc0 | src_reg | (dst_reg << 3)); /*MAXSD dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x5f, 0xc0 | src_reg | (dst_reg << 3)); /*MAXSD dst_reg, src_reg*/ } void host_x86_MOVD_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x7e, 0x04 | (src_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/ - codegen_addbyte(block, base_reg | (idx_reg << 3)); + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x7e, 0x04 | (src_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/ + codegen_addbyte(block, base_reg | (idx_reg << 3)); } void host_x86_MOVD_REG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x7e, 0xc0 | dst_reg | (src_reg << 3)); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x7e, 0xc0 | dst_reg | (src_reg << 3)); } void host_x86_MOVD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x6e, 0x04 | (dst_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/ - codegen_addbyte(block, base_reg | (idx_reg << 3)); + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x6e, 0x04 | (dst_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/ + codegen_addbyte(block, base_reg | (idx_reg << 3)); } void host_x86_MOVD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x6e, 0xc0 | src_reg | (dst_reg << 3)); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x6e, 0xc0 | src_reg | (dst_reg << 3)); } void host_x86_MOVQ_ABS_XREG(codeblock_t *block, void *p, int src_reg) { - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - if (src_reg & 8) - fatal("host_x86_MOVQ_ABS_REG reg & 8\n"); + if (src_reg & 8) + fatal("host_x86_MOVQ_ABS_REG reg & 8\n"); - if (offset >= -128 && offset < 127) { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x45 | (src_reg << 3)); /*MOVQ offset[EBP], src_reg*/ - codegen_addbyte(block, offset); - } else { - if ((uintptr_t)p >> 32) - fatal("host_x86_MOVQ_ABS_REG - out of range %p\n", p); - codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x04 | (src_reg << 3)); /*MOVQ [p], src_reg*/ - codegen_addbyte(block, 0x25); - codegen_addlong(block, (uint32_t)(uintptr_t)p); - } + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x45 | (src_reg << 3)); /*MOVQ offset[EBP], src_reg*/ + codegen_addbyte(block, offset); + } else { + if ((uintptr_t)p >> 32) + fatal("host_x86_MOVQ_ABS_REG - out of range %p\n", p); + codegen_alloc_bytes(block, 9); + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x04 | (src_reg << 3)); /*MOVQ [p], src_reg*/ + codegen_addbyte(block, 0x25); + codegen_addlong(block, (uint32_t)(uintptr_t)p); + } } -void host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(codeblock_t *block, uint32_t addr, int src_reg_a, int src_reg_b, int shift, int src_reg) { - if ((src_reg & 8) || (src_reg_a & 8) || (src_reg_b & 8)) - fatal("host_x86_MOVQ_ABS_REG_REG_SHIFT_REG - bad reg\n"); +void host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(codeblock_t *block, uint32_t addr, int src_reg_a, int src_reg_b, int shift, + int src_reg) { + if ((src_reg & 8) || (src_reg_a & 8) || (src_reg_b & 8)) + fatal("host_x86_MOVQ_ABS_REG_REG_SHIFT_REG - bad reg\n"); - if (addr < 0x80 || addr >= 0xffffff80) { - codegen_alloc_bytes(block, 6); - codegen_addbyte3(block, 0x66, 0x0f, 0xd6); /*MOVQ addr[src_reg_a + src_reg_b << shift], XMMx*/ - codegen_addbyte3(block, 0x44 | (src_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6), addr & 0xff); - } else { - codegen_alloc_bytes(block, 9); - codegen_addbyte3(block, 0x66, 0x0f, 0xd6); /*MOVQ addr[src_reg_a + src_reg_b << shift], XMMx*/ - codegen_addbyte2(block, 0x84 | (src_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6)); - codegen_addlong(block, addr); - } + if (addr < 0x80 || addr >= 0xffffff80) { + codegen_alloc_bytes(block, 6); + codegen_addbyte3(block, 0x66, 0x0f, 0xd6); /*MOVQ addr[src_reg_a + src_reg_b << shift], XMMx*/ + codegen_addbyte3(block, 0x44 | (src_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6), addr & 0xff); + } else { + codegen_alloc_bytes(block, 9); + codegen_addbyte3(block, 0x66, 0x0f, 0xd6); /*MOVQ addr[src_reg_a + src_reg_b << shift], XMMx*/ + codegen_addbyte2(block, 0x84 | (src_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6)); + codegen_addlong(block, addr); + } } void host_x86_MOVQ_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x04 | (src_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/ - codegen_addbyte(block, base_reg | (idx_reg << 3)); + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x04 | (src_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/ + codegen_addbyte(block, base_reg | (idx_reg << 3)); } void host_x86_MOVQ_BASE_OFFSET_XREG(codeblock_t *block, int base_reg, int offset, int src_reg) { - if (offset >= -128 && offset < 127) { - if (base_reg == REG_RSP) { - codegen_alloc_bytes(block, 6); - codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x44 | (src_reg << 3)); /*MOVQ [RSP + offset], XMMx*/ - codegen_addbyte2(block, 0x24, offset); - } else { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x40 | base_reg | (src_reg << 3)); /*MOVQ [base_reg + offset], XMMx*/ - codegen_addbyte(block, offset); - } - } else - fatal("MOVQ_BASE_OFFSET_XREG - offset %i\n", offset); + if (offset >= -128 && offset < 127) { + if (base_reg == REG_RSP) { + codegen_alloc_bytes(block, 6); + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x44 | (src_reg << 3)); /*MOVQ [RSP + offset], XMMx*/ + codegen_addbyte2(block, 0x24, offset); + } else { + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, + 0x40 | base_reg | (src_reg << 3)); /*MOVQ [base_reg + offset], XMMx*/ + codegen_addbyte(block, offset); + } + } else + fatal("MOVQ_BASE_OFFSET_XREG - offset %i\n", offset); } void host_x86_MOVQ_XREG_ABS(codeblock_t *block, int dst_reg, void *p) { - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - if (dst_reg & 8) - fatal("host_x86_MOVQ_REG_ABS reg & 8\n"); + if (dst_reg & 8) + fatal("host_x86_MOVQ_REG_ABS reg & 8\n"); - if (offset >= -128 && offset < 127) { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x45 | (dst_reg << 3)); /*MOVQ offset[EBP], src_reg*/ - codegen_addbyte(block, offset); - } else { - if ((uintptr_t)p >> 32) - fatal("host_x86_MOVQ_REG_ABS - out of range %p\n", p); - codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x04 | (dst_reg << 3)); /*MOVQ [p], src_reg*/ - codegen_addbyte(block, 0x25); - codegen_addlong(block, (uint32_t)(uintptr_t)p); - } + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x45 | (dst_reg << 3)); /*MOVQ offset[EBP], src_reg*/ + codegen_addbyte(block, offset); + } else { + if ((uintptr_t)p >> 32) + fatal("host_x86_MOVQ_REG_ABS - out of range %p\n", p); + codegen_alloc_bytes(block, 9); + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x04 | (dst_reg << 3)); /*MOVQ [p], src_reg*/ + codegen_addbyte(block, 0x25); + codegen_addlong(block, (uint32_t)(uintptr_t)p); + } } -void host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int src_reg_a, int src_reg_b, int shift) { - if ((dst_reg & 8) || (src_reg_a & 8) || (src_reg_b & 8)) - fatal("host_x86_MOVQ_REG_ABS_REG_REG_SHIFT - bad reg\n"); +void host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int src_reg_a, int src_reg_b, + int shift) { + if ((dst_reg & 8) || (src_reg_a & 8) || (src_reg_b & 8)) + fatal("host_x86_MOVQ_REG_ABS_REG_REG_SHIFT - bad reg\n"); - if (addr < 0x80 || addr >= 0xffffff80) { - codegen_alloc_bytes(block, 6); - codegen_addbyte3(block, 0xf3, 0x0f, 0x7e); /*MOVQ XMMx, addr[src_reg_a + src_reg_b << shift]*/ - codegen_addbyte3(block, 0x44 | (dst_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6), addr & 0xff); - } else { - codegen_alloc_bytes(block, 9); - codegen_addbyte3(block, 0xf3, 0x0f, 0x7e); /*MOVQ XMMx, addr[src_reg_a + src_reg_b << shift]*/ - codegen_addbyte2(block, 0x84 | (dst_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6)); - codegen_addlong(block, addr); - } + if (addr < 0x80 || addr >= 0xffffff80) { + codegen_alloc_bytes(block, 6); + codegen_addbyte3(block, 0xf3, 0x0f, 0x7e); /*MOVQ XMMx, addr[src_reg_a + src_reg_b << shift]*/ + codegen_addbyte3(block, 0x44 | (dst_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6), addr & 0xff); + } else { + codegen_alloc_bytes(block, 9); + codegen_addbyte3(block, 0xf3, 0x0f, 0x7e); /*MOVQ XMMx, addr[src_reg_a + src_reg_b << shift]*/ + codegen_addbyte2(block, 0x84 | (dst_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6)); + codegen_addlong(block, addr); + } } void host_x86_MOVQ_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x04 | (dst_reg << 3)); /*MOVQ XMMx, [base_reg + idx_reg]*/ - codegen_addbyte(block, base_reg | (idx_reg << 3)); + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x04 | (dst_reg << 3)); /*MOVQ XMMx, [base_reg + idx_reg]*/ + codegen_addbyte(block, base_reg | (idx_reg << 3)); } void host_x86_MOVQ_XREG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset) { - if (offset >= -128 && offset < 127) { - if (base_reg == REG_ESP) { - codegen_alloc_bytes(block, 6); - codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x44 | (dst_reg << 3)); /*MOVQ XMMx, [ESP + offset]*/ - codegen_addbyte2(block, 0x24, offset); - } else { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x40 | base_reg | (dst_reg << 3)); /*MOVQ XMMx, [base_reg + offset]*/ - codegen_addbyte(block, offset); - } - } else - fatal("MOVQ_REG_BASE_OFFSET - offset %i\n", offset); + if (offset >= -128 && offset < 127) { + if (base_reg == REG_ESP) { + codegen_alloc_bytes(block, 6); + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x44 | (dst_reg << 3)); /*MOVQ XMMx, [ESP + offset]*/ + codegen_addbyte2(block, 0x24, offset); + } else { + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, + 0x40 | base_reg | (dst_reg << 3)); /*MOVQ XMMx, [base_reg + offset]*/ + codegen_addbyte(block, offset); + } + } else + fatal("MOVQ_REG_BASE_OFFSET - offset %i\n", offset); } void host_x86_MOVQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0xc0 | src_reg | (dst_reg << 3)); /*MOVQ dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0xc0 | src_reg | (dst_reg << 3)); /*MOVQ dst_reg, src_reg*/ } void host_x86_MOVQ_REG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x48, 0x0f, 0x7e); /*MOVQ dst_reg, src_reg*/ - codegen_addbyte(block, 0xc0 | dst_reg | (src_reg << 3)); + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x48, 0x0f, 0x7e); /*MOVQ dst_reg, src_reg*/ + codegen_addbyte(block, 0xc0 | dst_reg | (src_reg << 3)); } void host_x86_MOVQ_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x48, 0x0f, 0x6e); /*MOVQ dst_reg, src_reg*/ - codegen_addbyte(block, 0xc0 | src_reg | (dst_reg << 3)); + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x48, 0x0f, 0x6e); /*MOVQ dst_reg, src_reg*/ + codegen_addbyte(block, 0xc0 | src_reg | (dst_reg << 3)); } void host_x86_MAXPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0x5f, 0xc0 | src_reg | (dst_reg << 3)); /*MAXPS dst_reg, src_reg*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0x5f, 0xc0 | src_reg | (dst_reg << 3)); /*MAXPS dst_reg, src_reg*/ } void host_x86_MINPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0x5d, 0xc0 | src_reg | (dst_reg << 3)); /*MINPS dst_reg, src_reg*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0x5d, 0xc0 | src_reg | (dst_reg << 3)); /*MINPS dst_reg, src_reg*/ } void host_x86_MULPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0x59, 0xc0 | src_reg | (dst_reg << 3)); /*MULPS dst_reg, src_reg*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0x59, 0xc0 | src_reg | (dst_reg << 3)); /*MULPS dst_reg, src_reg*/ } void host_x86_MULSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x59, 0xc0 | src_reg | (dst_reg << 3)); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x59, 0xc0 | src_reg | (dst_reg << 3)); } void host_x86_PACKSSWB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0x66, 0x0f, 0x63, 0xc0 | src_reg | (dst_reg << 3)); /*PACKSSWB dst_reg, src_reg*/ - codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ - codegen_addbyte(block, 0x88); + codegen_alloc_bytes(block, 9); + codegen_addbyte4(block, 0x66, 0x0f, 0x63, 0xc0 | src_reg | (dst_reg << 3)); /*PACKSSWB dst_reg, src_reg*/ + codegen_addbyte4(block, 0x66, 0x0f, 0x70, + 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ + codegen_addbyte(block, 0x88); } void host_x86_PACKSSDW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0x66, 0x0f, 0x6b, 0xc0 | src_reg | (dst_reg << 3)); /*PACKSSDW dst_reg, src_reg*/ - codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ - codegen_addbyte(block, 0x88); + codegen_alloc_bytes(block, 9); + codegen_addbyte4(block, 0x66, 0x0f, 0x6b, 0xc0 | src_reg | (dst_reg << 3)); /*PACKSSDW dst_reg, src_reg*/ + codegen_addbyte4(block, 0x66, 0x0f, 0x70, + 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ + codegen_addbyte(block, 0x88); } void host_x86_PACKUSWB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0x66, 0x0f, 0x67, 0xc0 | src_reg | (dst_reg << 3)); /*PACKUSWB dst_reg, src_reg*/ - codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ - codegen_addbyte(block, 0x88); + codegen_alloc_bytes(block, 9); + codegen_addbyte4(block, 0x66, 0x0f, 0x67, 0xc0 | src_reg | (dst_reg << 3)); /*PACKUSWB dst_reg, src_reg*/ + codegen_addbyte4(block, 0x66, 0x0f, 0x70, + 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ + codegen_addbyte(block, 0x88); } void host_x86_PADDB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xfc, 0xc0 | src_reg | (dst_reg << 3)); /*PADDB dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xfc, 0xc0 | src_reg | (dst_reg << 3)); /*PADDB dst_reg, src_reg*/ } void host_x86_PADDW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xfd, 0xc0 | src_reg | (dst_reg << 3)); /*PADDW dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xfd, 0xc0 | src_reg | (dst_reg << 3)); /*PADDW dst_reg, src_reg*/ } void host_x86_PADDD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xfe, 0xc0 | src_reg | (dst_reg << 3)); /*PADDD dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xfe, 0xc0 | src_reg | (dst_reg << 3)); /*PADDD dst_reg, src_reg*/ } void host_x86_PADDSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xec, 0xc0 | src_reg | (dst_reg << 3)); /*PADDSB dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xec, 0xc0 | src_reg | (dst_reg << 3)); /*PADDSB dst_reg, src_reg*/ } void host_x86_PADDSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xed, 0xc0 | src_reg | (dst_reg << 3)); /*PADDSW dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xed, 0xc0 | src_reg | (dst_reg << 3)); /*PADDSW dst_reg, src_reg*/ } void host_x86_PADDUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xdc, 0xc0 | src_reg | (dst_reg << 3)); /*PADDUSB dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xdc, 0xc0 | src_reg | (dst_reg << 3)); /*PADDUSB dst_reg, src_reg*/ } void host_x86_PADDUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xdd, 0xc0 | src_reg | (dst_reg << 3)); /*PADDUSW dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xdd, 0xc0 | src_reg | (dst_reg << 3)); /*PADDUSW dst_reg, src_reg*/ } void host_x86_PAND_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xdb, 0xc0 | src_reg | (dst_reg << 3)); /*PAND dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xdb, 0xc0 | src_reg | (dst_reg << 3)); /*PAND dst_reg, src_reg*/ } void host_x86_PANDN_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xdf, 0xc0 | src_reg | (dst_reg << 3)); /*PANDN dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xdf, 0xc0 | src_reg | (dst_reg << 3)); /*PANDN dst_reg, src_reg*/ } void host_x86_POR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xeb, 0xc0 | src_reg | (dst_reg << 3)); /*POR dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xeb, 0xc0 | src_reg | (dst_reg << 3)); /*POR dst_reg, src_reg*/ } void host_x86_PXOR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xef, 0xc0 | src_reg | (dst_reg << 3)); /*PXOR dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xef, 0xc0 | src_reg | (dst_reg << 3)); /*PXOR dst_reg, src_reg*/ } void host_x86_PCMPEQB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x74, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQB dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x74, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQB dst_reg, src_reg*/ } void host_x86_PCMPEQW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x75, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQW dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x75, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQW dst_reg, src_reg*/ } void host_x86_PCMPEQD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x76, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQD dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x76, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQD dst_reg, src_reg*/ } void host_x86_PCMPGTB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x64, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTB dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x64, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTB dst_reg, src_reg*/ } void host_x86_PCMPGTW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x65, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTW dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x65, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTW dst_reg, src_reg*/ } void host_x86_PCMPGTD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x66, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTD dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x66, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTD dst_reg, src_reg*/ } void host_x86_PMADDWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xf5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xf5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ } void host_x86_PMULHW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xe5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xe5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ } void host_x86_PMULLW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xd5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xd5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ } void host_x86_PSLLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x30 | dst_reg); /*PSLLW dst_reg, imm*/ - codegen_addbyte(block, shift); + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x30 | dst_reg); /*PSLLW dst_reg, imm*/ + codegen_addbyte(block, shift); } void host_x86_PSLLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift) { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x30 | dst_reg); /*PSLLD dst_reg, imm*/ - codegen_addbyte(block, shift); + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x30 | dst_reg); /*PSLLD dst_reg, imm*/ + codegen_addbyte(block, shift); } void host_x86_PSLLQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift) { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x30 | dst_reg); /*PSLLD dst_reg, imm*/ - codegen_addbyte(block, shift); + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x30 | dst_reg); /*PSLLD dst_reg, imm*/ + codegen_addbyte(block, shift); } void host_x86_PSRAW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x20 | dst_reg); /*PSRAW dst_reg, imm*/ - codegen_addbyte(block, shift); + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x20 | dst_reg); /*PSRAW dst_reg, imm*/ + codegen_addbyte(block, shift); } void host_x86_PSRAD_XREG_IMM(codeblock_t *block, int dst_reg, int shift) { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x20 | dst_reg); /*PSRAD dst_reg, imm*/ - codegen_addbyte(block, shift); + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x20 | dst_reg); /*PSRAD dst_reg, imm*/ + codegen_addbyte(block, shift); } void host_x86_PSRAQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift) { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x20 | dst_reg); /*PSRAD dst_reg, imm*/ - codegen_addbyte(block, shift); + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x20 | dst_reg); /*PSRAD dst_reg, imm*/ + codegen_addbyte(block, shift); } void host_x86_PSRLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x10 | dst_reg); /*PSRLW dst_reg, imm*/ - codegen_addbyte(block, shift); + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x10 | dst_reg); /*PSRLW dst_reg, imm*/ + codegen_addbyte(block, shift); } void host_x86_PSRLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift) { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x10 | dst_reg); /*PSRLD dst_reg, imm*/ - codegen_addbyte(block, shift); + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x10 | dst_reg); /*PSRLD dst_reg, imm*/ + codegen_addbyte(block, shift); } void host_x86_PSRLQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift) { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x10 | dst_reg); /*PSRLD dst_reg, imm*/ - codegen_addbyte(block, shift); + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x10 | dst_reg); /*PSRLD dst_reg, imm*/ + codegen_addbyte(block, shift); } void host_x86_PSUBB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xf8, 0xc0 | src_reg | (dst_reg << 3)); /*PADDB dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xf8, 0xc0 | src_reg | (dst_reg << 3)); /*PADDB dst_reg, src_reg*/ } void host_x86_PSUBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xf9, 0xc0 | src_reg | (dst_reg << 3)); /*PADDW dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xf9, 0xc0 | src_reg | (dst_reg << 3)); /*PADDW dst_reg, src_reg*/ } void host_x86_PSUBD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xfa, 0xc0 | src_reg | (dst_reg << 3)); /*PADDD dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xfa, 0xc0 | src_reg | (dst_reg << 3)); /*PADDD dst_reg, src_reg*/ } void host_x86_PSUBSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xe8, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBSB dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xe8, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBSB dst_reg, src_reg*/ } void host_x86_PSUBSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xe9, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBSW dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xe9, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBSW dst_reg, src_reg*/ } void host_x86_PSUBUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xd8, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBUSB dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xd8, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBUSB dst_reg, src_reg*/ } void host_x86_PSUBUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xd9, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBUSW dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xd9, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBUSW dst_reg, src_reg*/ } void host_x86_PUNPCKHBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0x66, 0x0f, 0x60, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLBW dst_reg, src_reg*/ - codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0xee (move top 64-bits to low 64-bits)*/ - codegen_addbyte(block, 0xee); + codegen_alloc_bytes(block, 9); + codegen_addbyte4(block, 0x66, 0x0f, 0x60, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLBW dst_reg, src_reg*/ + codegen_addbyte4(block, 0x66, 0x0f, 0x70, + 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0xee (move top 64-bits to low 64-bits)*/ + codegen_addbyte(block, 0xee); } void host_x86_PUNPCKHWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0x66, 0x0f, 0x61, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLWD dst_reg, src_reg*/ - codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0xee (move top 64-bits to low 64-bits)*/ - codegen_addbyte(block, 0xee); + codegen_alloc_bytes(block, 9); + codegen_addbyte4(block, 0x66, 0x0f, 0x61, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLWD dst_reg, src_reg*/ + codegen_addbyte4(block, 0x66, 0x0f, 0x70, + 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0xee (move top 64-bits to low 64-bits)*/ + codegen_addbyte(block, 0xee); } void host_x86_PUNPCKHDQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0x66, 0x0f, 0x62, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLDQ dst_reg, src_reg*/ - codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0xee (move top 64-bits to low 64-bits)*/ - codegen_addbyte(block, 0xee); + codegen_alloc_bytes(block, 9); + codegen_addbyte4(block, 0x66, 0x0f, 0x62, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLDQ dst_reg, src_reg*/ + codegen_addbyte4(block, 0x66, 0x0f, 0x70, + 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0xee (move top 64-bits to low 64-bits)*/ + codegen_addbyte(block, 0xee); } void host_x86_PUNPCKLBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x60, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLBW dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x60, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLBW dst_reg, src_reg*/ } void host_x86_PUNPCKLWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x61, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLWD dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x61, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLWD dst_reg, src_reg*/ } void host_x86_PUNPCKLDQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x62, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLDQ dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x62, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLDQ dst_reg, src_reg*/ } void host_x86_SQRTSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x51, 0xc0 | src_reg | (dst_reg << 3)); /*SQRTSD dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x51, 0xc0 | src_reg | (dst_reg << 3)); /*SQRTSD dst_reg, src_reg*/ } void host_x86_SQRTSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf3, 0x0f, 0x51, 0xc0 | src_reg | (dst_reg << 3)); /*SQRTSS dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf3, 0x0f, 0x51, 0xc0 | src_reg | (dst_reg << 3)); /*SQRTSS dst_reg, src_reg*/ } void host_x86_SUBPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0x5c, 0xc0 | src_reg | (dst_reg << 3)); /*SUBPS dst_reg, src_reg*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0x5c, 0xc0 | src_reg | (dst_reg << 3)); /*SUBPS dst_reg, src_reg*/ } void host_x86_SUBSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x5c, 0xc0 | src_reg | (dst_reg << 3)); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x5c, 0xc0 | src_reg | (dst_reg << 3)); } void host_x86_UNPCKLPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0x14, 0xc0 | src_reg | (dst_reg << 3)); + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0x14, 0xc0 | src_reg | (dst_reg << 3)); } #endif diff --git a/src/codegen/x86-64/codegen_backend_x86-64_uops.c b/src/codegen/x86-64/codegen_backend_x86-64_uops.c index 1c1bc5ed..120d6876 100644 --- a/src/codegen/x86-64/codegen_backend_x86-64_uops.c +++ b/src/codegen/x86-64/codegen_backend_x86-64_uops.c @@ -16,7 +16,7 @@ #define STACK_ARG2 (8) #define STACK_ARG3 (12) -#define HOST_REG_GET(reg) ((IREG_GET_SIZE(reg) == IREG_SIZE_BH) ? (IREG_GET_REG((reg) & 3) | 4) : (IREG_GET_REG(reg) & 7)) +#define HOST_REG_GET(reg) ((IREG_GET_SIZE(reg) == IREG_SIZE_BH) ? (IREG_GET_REG((reg)&3) | 4) : (IREG_GET_REG(reg) & 7)) #define REG_IS_L(size) (size == IREG_SIZE_L) #define REG_IS_W(size) (size == IREG_SIZE_W) @@ -26,2616 +26,2618 @@ #define REG_IS_Q(size) (size == IREG_SIZE_Q) static int codegen_ADD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { - if (dest_reg != src_reg_a) - host_x86_LEA_REG_REG(block, dest_reg, src_reg_a, src_reg_b); - else - host_x86_ADD32_REG_REG(block, dest_reg, src_reg_b); - } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { - if (dest_reg != src_reg_a) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); - host_x86_ADD16_REG_REG(block, dest_reg, src_reg_b); - } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { - if (dest_reg != src_reg_a) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); - host_x86_ADD8_REG_REG(block, dest_reg, src_reg_b); - } + if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + if (dest_reg != src_reg_a) + host_x86_LEA_REG_REG(block, dest_reg, src_reg_a, src_reg_b); + else + host_x86_ADD32_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + if (dest_reg != src_reg_a) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); + host_x86_ADD16_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + if (dest_reg != src_reg_a) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); + host_x86_ADD8_REG_REG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("ADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("ADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_ADD_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { - if (dest_reg != src_reg) - host_x86_LEA_REG_IMM(block, dest_reg, src_reg, uop->imm_data); - else - host_x86_ADD32_REG_IMM(block, dest_reg, uop->imm_data); - } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { - if (dest_reg != src_reg) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_ADD16_REG_IMM(block, dest_reg, uop->imm_data); - } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { - if (dest_reg != src_reg) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_ADD8_REG_IMM(block, dest_reg, uop->imm_data); - } + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (dest_reg != src_reg) + host_x86_LEA_REG_IMM(block, dest_reg, src_reg, uop->imm_data); + else + host_x86_ADD32_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (dest_reg != src_reg) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_ADD16_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (dest_reg != src_reg) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_ADD8_REG_IMM(block, dest_reg, uop->imm_data); + } #ifdef RECOMPILER_DEBUG - else - fatal("ADD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("ADD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_ADD_LSHIFT(codeblock_t *block, uop_t *uop) { - if (!uop->imm_data) { - if (uop->dest_reg_a_real == uop->src_reg_a_real) - host_x86_ADD32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_b_real); - else - host_x86_LEA_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - } else if (uop->imm_data < 4) - host_x86_LEA_REG_REG_SHIFT(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, uop->imm_data); + if (!uop->imm_data) { + if (uop->dest_reg_a_real == uop->src_reg_a_real) + host_x86_ADD32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_b_real); + else + host_x86_LEA_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + } else if (uop->imm_data < 4) + host_x86_LEA_REG_REG_SHIFT(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, uop->imm_data); #ifdef RECOMPILER_DEBUG - else - fatal("codegen_ADD_LSHIFT - shift out of range %i\n", uop->imm_data); + else + fatal("codegen_ADD_LSHIFT - shift out of range %i\n", uop->imm_data); #endif - return 0; + return 0; } static int codegen_AND(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PAND_XREG_XREG(block, dest_reg, src_reg_b); - } else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { - if (dest_reg != src_reg_a) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a); - host_x86_AND32_REG_REG(block, dest_reg, src_reg_b); - } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { - if (dest_reg != src_reg_a) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); - host_x86_AND16_REG_REG(block, dest_reg, src_reg_b); - } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { - if (dest_reg != src_reg_a) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); - host_x86_AND8_REG_REG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PAND_XREG_XREG(block, dest_reg, src_reg_b); + } else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + if (dest_reg != src_reg_a) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a); + host_x86_AND32_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + if (dest_reg != src_reg_a) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); + host_x86_AND16_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + if (dest_reg != src_reg_a) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); + host_x86_AND8_REG_REG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("AND %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("AND %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { - if (dest_reg != src_reg) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_AND32_REG_IMM(block, dest_reg, uop->imm_data); - } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { - if (dest_reg != src_reg) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_AND16_REG_IMM(block, dest_reg, uop->imm_data); - } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { - if (dest_reg != src_reg) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_AND8_REG_IMM(block, dest_reg, uop->imm_data); - } + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (dest_reg != src_reg) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_AND32_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (dest_reg != src_reg) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_AND16_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (dest_reg != src_reg) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_AND8_REG_IMM(block, dest_reg, uop->imm_data); + } #ifdef RECOMPILER_DEBUG - else - fatal("AND_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("AND_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_ANDN(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), /*src_reg_a = HOST_REG_GET(uop->src_reg_a_real), */src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), + /*src_reg_a = HOST_REG_GET(uop->src_reg_a_real), */ src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PANDN_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PANDN_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("ANDN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("ANDN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_CALL_FUNC(codeblock_t *block, uop_t *uop) { - host_x86_CALL(block, uop->p); + host_x86_CALL(block, uop->p); - return 0; + return 0; } static int codegen_CALL_FUNC_RESULT(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); #ifdef RECOMPILER_DEBUG - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - if (!REG_IS_L(dest_size)) - fatal("CALL_FUNC_RESULT %02x\n", uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + if (!REG_IS_L(dest_size)) + fatal("CALL_FUNC_RESULT %02x\n", uop->dest_reg_a_real); #endif - host_x86_CALL(block, uop->p); - host_x86_MOV32_REG_REG(block, dest_reg, REG_EAX); + host_x86_CALL(block, uop->p); + host_x86_MOV32_REG_REG(block, dest_reg, REG_EAX); - return 0; + return 0; } static int codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop) { - host_x86_CALL(block, uop->p); - host_x86_TEST32_REG(block, REG_EAX, REG_EAX); - host_x86_JNZ(block, codegen_exit_rout); + host_x86_CALL(block, uop->p); + host_x86_TEST32_REG(block, REG_EAX, REG_EAX); + host_x86_JNZ(block, codegen_exit_rout); - return 0; + return 0; } static int codegen_CMP_IMM_JZ(codeblock_t *block, uop_t *uop) { - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(src_size)) { - host_x86_CMP32_REG_IMM(block, src_reg, uop->imm_data); - } + if (REG_IS_L(src_size)) { + host_x86_CMP32_REG_IMM(block, src_reg, uop->imm_data); + } #ifdef RECOMPILER_DEBUG - else - fatal("CMP_IMM_JZ %02x\n", uop->src_reg_a_real); + else + fatal("CMP_IMM_JZ %02x\n", uop->src_reg_a_real); #endif - host_x86_JZ(block, uop->p); + host_x86_JZ(block, uop->p); - return 0; + return 0; } static int codegen_CMP_IMM_JNZ_DEST(codeblock_t *block, uop_t *uop) { - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(src_size)) { - host_x86_CMP32_REG_IMM(block, src_reg, uop->imm_data); - } else if (REG_IS_W(src_size)) { - host_x86_CMP16_REG_IMM(block, src_reg, uop->imm_data); - } + if (REG_IS_L(src_size)) { + host_x86_CMP32_REG_IMM(block, src_reg, uop->imm_data); + } else if (REG_IS_W(src_size)) { + host_x86_CMP16_REG_IMM(block, src_reg, uop->imm_data); + } #ifdef RECOMPILER_DEBUG - else - fatal("CMP_IMM_JNZ_DEST %02x\n", uop->src_reg_a_real); + else + fatal("CMP_IMM_JNZ_DEST %02x\n", uop->src_reg_a_real); #endif - uop->p = host_x86_JNZ_long(block); + uop->p = host_x86_JNZ_long(block); - return 0; + return 0; } static int codegen_CMP_IMM_JZ_DEST(codeblock_t *block, uop_t *uop) { - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(src_size)) { - host_x86_CMP32_REG_IMM(block, src_reg, uop->imm_data); - } else if (REG_IS_W(src_size)) { - host_x86_CMP16_REG_IMM(block, src_reg, uop->imm_data); - } + if (REG_IS_L(src_size)) { + host_x86_CMP32_REG_IMM(block, src_reg, uop->imm_data); + } else if (REG_IS_W(src_size)) { + host_x86_CMP16_REG_IMM(block, src_reg, uop->imm_data); + } #ifdef RECOMPILER_DEBUG - else - fatal("CMP_IMM_JZ_DEST %02x\n", uop->src_reg_a_real); + else + fatal("CMP_IMM_JZ_DEST %02x\n", uop->src_reg_a_real); #endif - uop->p = host_x86_JZ_long(block); + uop->p = host_x86_JZ_long(block); - return 0; + return 0; } static int codegen_CMP_JB(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - uint32_t *jump_p; + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + uint32_t *jump_p; - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("CMP_JB %02x\n", uop->src_reg_a_real); + else + fatal("CMP_JB %02x\n", uop->src_reg_a_real); #endif - jump_p = host_x86_JB_long(block); - *jump_p = (uintptr_t)uop->p - ((uintptr_t)jump_p + 4); + jump_p = host_x86_JB_long(block); + *jump_p = (uintptr_t)uop->p - ((uintptr_t)jump_p + 4); - return 0; + return 0; } static int codegen_CMP_JNBE(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - uint32_t *jump_p; + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + uint32_t *jump_p; - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("CMP_JNBE %02x\n", uop->src_reg_a_real); + else + fatal("CMP_JNBE %02x\n", uop->src_reg_a_real); #endif - jump_p = host_x86_JNBE_long(block); - *jump_p = (uintptr_t)uop->p - ((uintptr_t)jump_p + 4); + jump_p = host_x86_JNBE_long(block); + *jump_p = (uintptr_t)uop->p - ((uintptr_t)jump_p + 4); - return 0; + return 0; } static int codegen_CMP_JNB_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("CMP_JNB_DEST %02x\n", uop->src_reg_a_real); + else + fatal("CMP_JNB_DEST %02x\n", uop->src_reg_a_real); #endif - uop->p = host_x86_JNB_long(block); + uop->p = host_x86_JNB_long(block); - return 0; + return 0; } static int codegen_CMP_JNBE_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("CMP_JNBE_DEST %02x\n", uop->src_reg_a_real); + else + fatal("CMP_JNBE_DEST %02x\n", uop->src_reg_a_real); #endif - uop->p = host_x86_JNBE_long(block); + uop->p = host_x86_JNBE_long(block); - return 0; + return 0; } static int codegen_CMP_JNL_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("CMP_JNL_DEST %02x\n", uop->src_reg_a_real); + else + fatal("CMP_JNL_DEST %02x\n", uop->src_reg_a_real); #endif - uop->p = host_x86_JNL_long(block); + uop->p = host_x86_JNL_long(block); - return 0; + return 0; } static int codegen_CMP_JNLE_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("CMP_JNLE_DEST %02x\n", uop->src_reg_a_real); + else + fatal("CMP_JNLE_DEST %02x\n", uop->src_reg_a_real); #endif - uop->p = host_x86_JNLE_long(block); + uop->p = host_x86_JNLE_long(block); - return 0; + return 0; } static int codegen_CMP_JNO_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("CMP_JNO_DEST %02x\n", uop->src_reg_a_real); + else + fatal("CMP_JNO_DEST %02x\n", uop->src_reg_a_real); #endif - uop->p = host_x86_JNO_long(block); + uop->p = host_x86_JNO_long(block); - return 0; + return 0; } static int codegen_CMP_JNZ_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("CMP_JNZ_DEST %02x\n", uop->src_reg_a_real); + else + fatal("CMP_JNZ_DEST %02x\n", uop->src_reg_a_real); #endif - uop->p = host_x86_JNZ_long(block); + uop->p = host_x86_JNZ_long(block); - return 0; + return 0; } static int codegen_CMP_JB_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("CMP_JB_DEST %02x\n", uop->src_reg_a_real); + else + fatal("CMP_JB_DEST %02x\n", uop->src_reg_a_real); #endif - uop->p = host_x86_JB_long(block); + uop->p = host_x86_JB_long(block); - return 0; + return 0; } static int codegen_CMP_JBE_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("CMP_JBE_DEST %02x\n", uop->src_reg_a_real); + else + fatal("CMP_JBE_DEST %02x\n", uop->src_reg_a_real); #endif - uop->p = host_x86_JBE_long(block); + uop->p = host_x86_JBE_long(block); - return 0; + return 0; } static int codegen_CMP_JL_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("CMP_JL_DEST %02x\n", uop->src_reg_a_real); + else + fatal("CMP_JL_DEST %02x\n", uop->src_reg_a_real); #endif - uop->p = host_x86_JL_long(block); + uop->p = host_x86_JL_long(block); - return 0; + return 0; } static int codegen_CMP_JLE_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("CMP_JLE_DEST %02x\n", uop->src_reg_a_real); + else + fatal("CMP_JLE_DEST %02x\n", uop->src_reg_a_real); #endif - uop->p = host_x86_JLE_long(block); + uop->p = host_x86_JLE_long(block); - return 0; + return 0; } static int codegen_CMP_JO_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("CMP_JO_DEST %02x\n", uop->src_reg_a_real); + else + fatal("CMP_JO_DEST %02x\n", uop->src_reg_a_real); #endif - uop->p = host_x86_JO_long(block); + uop->p = host_x86_JO_long(block); - return 0; + return 0; } static int codegen_CMP_JZ_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("CMP_JZ_DEST %02x\n", uop->src_reg_a_real); + else + fatal("CMP_JZ_DEST %02x\n", uop->src_reg_a_real); #endif - uop->p = host_x86_JZ_long(block); + uop->p = host_x86_JZ_long(block); - return 0; + return 0; } static int codegen_FABS(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && dest_reg == src_reg_a) { - host_x86_PXOR_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP); - host_x86_SUBSD_XREG_XREG(block, REG_XMM_TEMP, dest_reg); - host_x86_MAXSD_XREG_XREG(block, dest_reg, REG_XMM_TEMP); - } + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && dest_reg == src_reg_a) { + host_x86_PXOR_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP); + host_x86_SUBSD_XREG_XREG(block, REG_XMM_TEMP, dest_reg); + host_x86_MAXSD_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + } #ifdef RECOMPILER_DEBUG - else - fatal("codegen_FABS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("codegen_FABS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_FCHS(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) { - host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); - host_x86_PXOR_XREG_XREG(block, dest_reg, dest_reg); - host_x86_SUBSD_XREG_XREG(block, dest_reg, REG_XMM_TEMP); - } + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) { + host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); + host_x86_PXOR_XREG_XREG(block, dest_reg, dest_reg); + host_x86_SUBSD_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + } #ifdef RECOMPILER_DEBUG - else - fatal("codegen_FCHS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("codegen_FCHS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_FSQRT(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) { - host_x86_SQRTSD_XREG_XREG(block, dest_reg, src_reg_a); - } + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) { + host_x86_SQRTSD_XREG_XREG(block, dest_reg, src_reg_a); + } #ifdef RECOMPILER_DEBUG - else - fatal("codegen_FSQRT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("codegen_FSQRT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_FTST(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_W(dest_size) && REG_IS_D(src_size_a)) { - host_x86_PXOR_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP); - if (dest_reg != REG_EAX) - host_x86_MOV32_REG_REG(block, REG_ECX, REG_EAX); - host_x86_XOR32_REG_REG(block, REG_EAX, REG_EAX); - host_x86_COMISD_XREG_XREG(block, src_reg_a, REG_XMM_TEMP); - host_x86_LAHF(block); - host_x86_AND16_REG_IMM(block, REG_EAX, C0 | C2 | C3); - if (dest_reg != REG_EAX) { - host_x86_MOV16_REG_REG(block, dest_reg, REG_EAX); - host_x86_MOV32_REG_REG(block, REG_EAX, REG_ECX); - } - } + if (REG_IS_W(dest_size) && REG_IS_D(src_size_a)) { + host_x86_PXOR_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP); + if (dest_reg != REG_EAX) + host_x86_MOV32_REG_REG(block, REG_ECX, REG_EAX); + host_x86_XOR32_REG_REG(block, REG_EAX, REG_EAX); + host_x86_COMISD_XREG_XREG(block, src_reg_a, REG_XMM_TEMP); + host_x86_LAHF(block); + host_x86_AND16_REG_IMM(block, REG_EAX, C0 | C2 | C3); + if (dest_reg != REG_EAX) { + host_x86_MOV16_REG_REG(block, dest_reg, REG_EAX); + host_x86_MOV32_REG_REG(block, REG_EAX, REG_ECX); + } + } #ifdef RECOMPILER_DEBUG - else - fatal("codegen_FTST %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("codegen_FTST %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_FADD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) { - host_x86_ADDSD_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) { + host_x86_ADDSD_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("codegen_FADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("codegen_FADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_FCOM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_W(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { - if (dest_reg != REG_EAX) - host_x86_MOV32_REG_REG(block, REG_ECX, REG_EAX); - host_x86_XOR32_REG_REG(block, REG_EAX, REG_EAX); - host_x86_COMISD_XREG_XREG(block, src_reg_a, src_reg_b); - host_x86_LAHF(block); - host_x86_AND16_REG_IMM(block, REG_EAX, C0 | C2 | C3); - if (dest_reg != REG_EAX) { - host_x86_MOV16_REG_REG(block, dest_reg, REG_EAX); - host_x86_MOV32_REG_REG(block, REG_EAX, REG_ECX); - } - } + if (REG_IS_W(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { + if (dest_reg != REG_EAX) + host_x86_MOV32_REG_REG(block, REG_ECX, REG_EAX); + host_x86_XOR32_REG_REG(block, REG_EAX, REG_EAX); + host_x86_COMISD_XREG_XREG(block, src_reg_a, src_reg_b); + host_x86_LAHF(block); + host_x86_AND16_REG_IMM(block, REG_EAX, C0 | C2 | C3); + if (dest_reg != REG_EAX) { + host_x86_MOV16_REG_REG(block, dest_reg, REG_EAX); + host_x86_MOV32_REG_REG(block, REG_EAX, REG_ECX); + } + } #ifdef RECOMPILER_DEBUG - else - fatal("codegen_FCOM %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("codegen_FCOM %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_FDIV(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) { - host_x86_DIVSD_XREG_XREG(block, dest_reg, src_reg_b); - } else if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { - host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); - host_x86_DIVSD_XREG_XREG(block, REG_XMM_TEMP, src_reg_b); - host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); - } + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) { + host_x86_DIVSD_XREG_XREG(block, dest_reg, src_reg_b); + } else if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { + host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); + host_x86_DIVSD_XREG_XREG(block, REG_XMM_TEMP, src_reg_b); + host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + } #ifdef RECOMPILER_DEBUG - else - fatal("codegen_FDIV %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("codegen_FDIV %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_FMUL(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) { - host_x86_MULSD_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) { + host_x86_MULSD_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("codegen_FMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("codegen_FMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_FSUB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) { - host_x86_SUBSD_XREG_XREG(block, dest_reg, src_reg_b); - } else if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { - host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); - host_x86_SUBSD_XREG_XREG(block, REG_XMM_TEMP, src_reg_b); - host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); - } + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) { + host_x86_SUBSD_XREG_XREG(block, dest_reg, src_reg_b); + } else if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { + host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); + host_x86_SUBSD_XREG_XREG(block, REG_XMM_TEMP, src_reg_b); + host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + } #ifdef RECOMPILER_DEBUG - else - fatal("codegen_FSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("codegen_FSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_FP_ENTER(codeblock_t *block, uop_t *uop) { - uint32_t *branch_offset; + uint32_t *branch_offset; - host_x86_MOV32_REG_ABS(block, REG_ECX, &cr0); - host_x86_TEST32_REG_IMM(block, REG_ECX, 0xc); - branch_offset = host_x86_JZ_long(block); - host_x86_MOV32_ABS_IMM(block, &cpu_state.oldpc, uop->imm_data); + host_x86_MOV32_REG_ABS(block, REG_ECX, &cr0); + host_x86_TEST32_REG_IMM(block, REG_ECX, 0xc); + branch_offset = host_x86_JZ_long(block); + host_x86_MOV32_ABS_IMM(block, &cpu_state.oldpc, uop->imm_data); #if WIN64 - host_x86_MOV32_REG_IMM(block, REG_ECX, 7); + host_x86_MOV32_REG_IMM(block, REG_ECX, 7); #else - host_x86_MOV32_REG_IMM(block, REG_EDI, 7); + host_x86_MOV32_REG_IMM(block, REG_EDI, 7); #endif - host_x86_CALL(block, x86_int); - host_x86_JMP(block, codegen_exit_rout); - *branch_offset = (uint32_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 4; + host_x86_CALL(block, x86_int); + host_x86_JMP(block, codegen_exit_rout); + *branch_offset = (uint32_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 4; - return 0; + return 0; } static int codegen_MMX_ENTER(codeblock_t *block, uop_t *uop) { - uint32_t *branch_offset; + uint32_t *branch_offset; - host_x86_MOV32_REG_ABS(block, REG_ECX, &cr0); - host_x86_TEST32_REG_IMM(block, REG_ECX, 0xc); - branch_offset = host_x86_JZ_long(block); - host_x86_MOV32_ABS_IMM(block, &cpu_state.oldpc, uop->imm_data); + host_x86_MOV32_REG_ABS(block, REG_ECX, &cr0); + host_x86_TEST32_REG_IMM(block, REG_ECX, 0xc); + branch_offset = host_x86_JZ_long(block); + host_x86_MOV32_ABS_IMM(block, &cpu_state.oldpc, uop->imm_data); #if WIN64 - host_x86_MOV32_REG_IMM(block, REG_ECX, 7); + host_x86_MOV32_REG_IMM(block, REG_ECX, 7); #else - host_x86_MOV32_REG_IMM(block, REG_EDI, 7); + host_x86_MOV32_REG_IMM(block, REG_EDI, 7); #endif - host_x86_CALL(block, x86_int); - host_x86_JMP(block, codegen_exit_rout); - *branch_offset = (uint32_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 4; - host_x86_MOV32_ABS_IMM(block, &cpu_state.tag[0], 0x01010101); - host_x86_MOV32_ABS_IMM(block, &cpu_state.tag[4], 0x01010101); - host_x86_MOV32_ABS_IMM(block, &cpu_state.TOP, 0); - host_x86_MOV8_ABS_IMM(block, &cpu_state.ismmx, 1); + host_x86_CALL(block, x86_int); + host_x86_JMP(block, codegen_exit_rout); + *branch_offset = (uint32_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 4; + host_x86_MOV32_ABS_IMM(block, &cpu_state.tag[0], 0x01010101); + host_x86_MOV32_ABS_IMM(block, &cpu_state.tag[4], 0x01010101); + host_x86_MOV32_ABS_IMM(block, &cpu_state.TOP, 0); + host_x86_MOV8_ABS_IMM(block, &cpu_state.ismmx, 1); - return 0; + return 0; } static int codegen_JMP(codeblock_t *block, uop_t *uop) { - host_x86_JMP(block, uop->p); + host_x86_JMP(block, uop->p); - return 0; + return 0; } static int codegen_LOAD_FUNC_ARG0(codeblock_t *block, uop_t *uop) { - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_W(src_size)) { + if (REG_IS_W(src_size)) { #if WIN64 - host_x86_MOVZX_REG_32_16(block, REG_ECX, src_reg); + host_x86_MOVZX_REG_32_16(block, REG_ECX, src_reg); #else - host_x86_MOVZX_REG_32_16(block, REG_EDI, src_reg); + host_x86_MOVZX_REG_32_16(block, REG_EDI, src_reg); #endif - } + } #ifdef RECOMPILER_DEBUG - else - fatal("codegen_LOAD_FUNC_ARG0 %02x\n", uop->src_reg_a_real); + else + fatal("codegen_LOAD_FUNC_ARG0 %02x\n", uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_LOAD_FUNC_ARG1(codeblock_t *block, uop_t *uop) { #ifdef RECOMPILER_DEBUG - fatal("codegen_LOAD_FUNC_ARG1 %02x\n", uop->src_reg_a_real); + fatal("codegen_LOAD_FUNC_ARG1 %02x\n", uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_LOAD_FUNC_ARG2(codeblock_t *block, uop_t *uop) { #ifdef RECOMPILER_DEBUG - fatal("codegen_LOAD_FUNC_ARG2 %02x\n", uop->src_reg_a_real); + fatal("codegen_LOAD_FUNC_ARG2 %02x\n", uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_LOAD_FUNC_ARG3(codeblock_t *block, uop_t *uop) { #ifdef RECOMPILER_DEBUG - fatal("codegen_LOAD_FUNC_ARG3 %02x\n", uop->src_reg_a_real); + fatal("codegen_LOAD_FUNC_ARG3 %02x\n", uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_LOAD_FUNC_ARG0_IMM(codeblock_t *block, uop_t *uop) { #if WIN64 - host_x86_MOV32_REG_IMM(block, REG_ECX, uop->imm_data); + host_x86_MOV32_REG_IMM(block, REG_ECX, uop->imm_data); #else - host_x86_MOV32_REG_IMM(block, REG_EDI, uop->imm_data); + host_x86_MOV32_REG_IMM(block, REG_EDI, uop->imm_data); #endif - return 0; + return 0; } static int codegen_LOAD_FUNC_ARG1_IMM(codeblock_t *block, uop_t *uop) { #if WIN64 - host_x86_MOV32_REG_IMM(block, REG_EDX, uop->imm_data); + host_x86_MOV32_REG_IMM(block, REG_EDX, uop->imm_data); #else - host_x86_MOV32_REG_IMM(block, REG_ESI, uop->imm_data); + host_x86_MOV32_REG_IMM(block, REG_ESI, uop->imm_data); #endif - return 0; + return 0; } static int codegen_LOAD_FUNC_ARG2_IMM(codeblock_t *block, uop_t *uop) { #ifdef RECOMPILER_DEBUG - fatal("codegen_LOAD_FUNC_ARG2_IMM\n"); + fatal("codegen_LOAD_FUNC_ARG2_IMM\n"); #endif - return 0; + return 0; } static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop) { #ifdef RECOMPILER_DEBUG - fatal("codegen_LOAD_FUNC_ARG3_IMM\n"); + fatal("codegen_LOAD_FUNC_ARG3_IMM\n"); #endif - return 0; + return 0; } static int codegen_LOAD_SEG(codeblock_t *block, uop_t *uop) { - int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); #ifdef RECOMPILER_DEBUG - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (!REG_IS_W(src_size)) - fatal("LOAD_SEG %02x %p\n", uop->src_reg_a_real, uop->p); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + if (!REG_IS_W(src_size)) + fatal("LOAD_SEG %02x %p\n", uop->src_reg_a_real, uop->p); #endif #if WIN64 - host_x86_MOV16_REG_REG(block, REG_CX, src_reg); - host_x86_MOV64_REG_IMM(block, REG_EDX, (uint64_t)uop->p); + host_x86_MOV16_REG_REG(block, REG_CX, src_reg); + host_x86_MOV64_REG_IMM(block, REG_EDX, (uint64_t)uop->p); #else - host_x86_MOV16_REG_REG(block, REG_DI, src_reg); - host_x86_MOV64_REG_IMM(block, REG_ESI, (uint64_t)uop->p); + host_x86_MOV16_REG_REG(block, REG_DI, src_reg); + host_x86_MOV64_REG_IMM(block, REG_ESI, (uint64_t)uop->p); #endif - host_x86_CALL(block, (void *)loadseg); - host_x86_TEST32_REG(block, REG_EAX, REG_EAX); - host_x86_JNZ(block, codegen_exit_rout); + host_x86_CALL(block, (void *)loadseg); + host_x86_TEST32_REG(block, REG_EAX, REG_EAX); + host_x86_JNZ(block, codegen_exit_rout); - return 0; + return 0; } static int codegen_MEM_LOAD_ABS(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - host_x86_LEA_REG_IMM(block, REG_ESI, seg_reg, uop->imm_data); - if (REG_IS_B(dest_size)) { - host_x86_CALL(block, codegen_mem_load_byte); - } else if (REG_IS_W(dest_size)) { - host_x86_CALL(block, codegen_mem_load_word); - } else if (REG_IS_L(dest_size)) { - host_x86_CALL(block, codegen_mem_load_long); - } + host_x86_LEA_REG_IMM(block, REG_ESI, seg_reg, uop->imm_data); + if (REG_IS_B(dest_size)) { + host_x86_CALL(block, codegen_mem_load_byte); + } else if (REG_IS_W(dest_size)) { + host_x86_CALL(block, codegen_mem_load_word); + } else if (REG_IS_L(dest_size)) { + host_x86_CALL(block, codegen_mem_load_long); + } #ifdef RECOMPILER_DEBUG - else - fatal("MEM_LOAD_ABS - %02x\n", uop->dest_reg_a_real); + else + fatal("MEM_LOAD_ABS - %02x\n", uop->dest_reg_a_real); #endif - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); - if (REG_IS_B(dest_size)) { - host_x86_MOV8_REG_REG(block, dest_reg, REG_ECX); - } else if (REG_IS_W(dest_size)) { - host_x86_MOV16_REG_REG(block, dest_reg, REG_ECX); - } else if (REG_IS_L(dest_size)) { - host_x86_MOV32_REG_REG(block, dest_reg, REG_ECX); - } + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); + if (REG_IS_B(dest_size)) { + host_x86_MOV8_REG_REG(block, dest_reg, REG_ECX); + } else if (REG_IS_W(dest_size)) { + host_x86_MOV16_REG_REG(block, dest_reg, REG_ECX); + } else if (REG_IS_L(dest_size)) { + host_x86_MOV32_REG_REG(block, dest_reg, REG_ECX); + } - return 0; + return 0; } static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), + addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); - if (uop->imm_data) - host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); - if (REG_IS_B(dest_size)) { - host_x86_CALL(block, codegen_mem_load_byte); - } else if (REG_IS_W(dest_size)) { - host_x86_CALL(block, codegen_mem_load_word); - } else if (REG_IS_L(dest_size)) { - host_x86_CALL(block, codegen_mem_load_long); - } else if (REG_IS_Q(dest_size)) { - host_x86_CALL(block, codegen_mem_load_quad); - } + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + if (uop->imm_data) + host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); + if (REG_IS_B(dest_size)) { + host_x86_CALL(block, codegen_mem_load_byte); + } else if (REG_IS_W(dest_size)) { + host_x86_CALL(block, codegen_mem_load_word); + } else if (REG_IS_L(dest_size)) { + host_x86_CALL(block, codegen_mem_load_long); + } else if (REG_IS_Q(dest_size)) { + host_x86_CALL(block, codegen_mem_load_quad); + } #ifdef RECOMPILER_DEBUG - else - fatal("MEM_LOAD_REG - %02x\n", uop->dest_reg_a_real); + else + fatal("MEM_LOAD_REG - %02x\n", uop->dest_reg_a_real); #endif - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); - if (REG_IS_B(dest_size)) { - host_x86_MOV8_REG_REG(block, dest_reg, REG_ECX); - } else if (REG_IS_W(dest_size)) { - host_x86_MOV16_REG_REG(block, dest_reg, REG_ECX); - } else if (REG_IS_L(dest_size)) { - host_x86_MOV32_REG_REG(block, dest_reg, REG_ECX); - } else if (REG_IS_Q(dest_size)) { - host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); - } + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); + if (REG_IS_B(dest_size)) { + host_x86_MOV8_REG_REG(block, dest_reg, REG_ECX); + } else if (REG_IS_W(dest_size)) { + host_x86_MOV16_REG_REG(block, dest_reg, REG_ECX); + } else if (REG_IS_L(dest_size)) { + host_x86_MOV32_REG_REG(block, dest_reg, REG_ECX); + } else if (REG_IS_Q(dest_size)) { + host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + } - return 0; + return 0; } static int codegen_MEM_LOAD_SINGLE(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), + addr_reg = HOST_REG_GET(uop->src_reg_b_real); #ifdef RECOMPILER_DEBUG - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - if (!REG_IS_D(dest_size)) - fatal("MEM_LOAD_SINGLE - %02x\n", uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + if (!REG_IS_D(dest_size)) + fatal("MEM_LOAD_SINGLE - %02x\n", uop->dest_reg_a_real); #endif - host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); - if (uop->imm_data) - host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); - host_x86_CALL(block, codegen_mem_load_single); - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); - host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + if (uop->imm_data) + host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); + host_x86_CALL(block, codegen_mem_load_single); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); + host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); - return 0; + return 0; } static int codegen_MEM_LOAD_DOUBLE(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), + addr_reg = HOST_REG_GET(uop->src_reg_b_real); #ifdef RECOMPILER_DEBUG - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - if (!REG_IS_D(dest_size)) - fatal("MEM_LOAD_DOUBLE - %02x\n", uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + if (!REG_IS_D(dest_size)) + fatal("MEM_LOAD_DOUBLE - %02x\n", uop->dest_reg_a_real); #endif - host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); - if (uop->imm_data) - host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); - host_x86_CALL(block, codegen_mem_load_double); - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); - host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + if (uop->imm_data) + host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); + host_x86_CALL(block, codegen_mem_load_double); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); + host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); - return 0; + return 0; } static int codegen_MEM_STORE_ABS(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_b_real); - int src_size = IREG_GET_SIZE(uop->src_reg_b_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_b_real); + int src_size = IREG_GET_SIZE(uop->src_reg_b_real); - host_x86_LEA_REG_IMM(block, REG_ESI, seg_reg, uop->imm_data); - if (REG_IS_B(src_size)) { - host_x86_MOV8_REG_REG(block, REG_ECX, src_reg); - host_x86_CALL(block, codegen_mem_store_byte); - } else if (REG_IS_W(src_size)) { - host_x86_MOV16_REG_REG(block, REG_ECX, src_reg); - host_x86_CALL(block, codegen_mem_store_word); - } else if (REG_IS_L(src_size)) { - host_x86_MOV32_REG_REG(block, REG_ECX, src_reg); - host_x86_CALL(block, codegen_mem_store_long); - } + host_x86_LEA_REG_IMM(block, REG_ESI, seg_reg, uop->imm_data); + if (REG_IS_B(src_size)) { + host_x86_MOV8_REG_REG(block, REG_ECX, src_reg); + host_x86_CALL(block, codegen_mem_store_byte); + } else if (REG_IS_W(src_size)) { + host_x86_MOV16_REG_REG(block, REG_ECX, src_reg); + host_x86_CALL(block, codegen_mem_store_word); + } else if (REG_IS_L(src_size)) { + host_x86_MOV32_REG_REG(block, REG_ECX, src_reg); + host_x86_CALL(block, codegen_mem_store_long); + } #ifdef RECOMPILER_DEBUG - else - fatal("MEM_STORE_ABS - %02x\n", uop->src_reg_b_real); + else + fatal("MEM_STORE_ABS - %02x\n", uop->src_reg_b_real); #endif - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); - return 0; + return 0; } static int codegen_MEM_STORE_IMM_8(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); - host_x86_MOV8_REG_IMM(block, REG_ECX, uop->imm_data); - host_x86_CALL(block, codegen_mem_store_byte); - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + host_x86_MOV8_REG_IMM(block, REG_ECX, uop->imm_data); + host_x86_CALL(block, codegen_mem_store_byte); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); - return 0; + return 0; } static int codegen_MEM_STORE_IMM_16(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); - host_x86_MOV16_REG_IMM(block, REG_ECX, uop->imm_data); - host_x86_CALL(block, codegen_mem_store_word); - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + host_x86_MOV16_REG_IMM(block, REG_ECX, uop->imm_data); + host_x86_CALL(block, codegen_mem_store_word); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); - return 0; + return 0; } static int codegen_MEM_STORE_IMM_32(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); - host_x86_MOV32_REG_IMM(block, REG_ECX, uop->imm_data); - host_x86_CALL(block, codegen_mem_store_long); - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + host_x86_MOV32_REG_IMM(block, REG_ECX, uop->imm_data); + host_x86_CALL(block, codegen_mem_store_long); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); - return 0; + return 0; } static int codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); - int src_size = IREG_GET_SIZE(uop->src_reg_c_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), + src_reg = HOST_REG_GET(uop->src_reg_c_real); + int src_size = IREG_GET_SIZE(uop->src_reg_c_real); - host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); - if (uop->imm_data) - host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); - if (REG_IS_B(src_size)) { - host_x86_MOV8_REG_REG(block, REG_ECX, src_reg); - host_x86_CALL(block, codegen_mem_store_byte); - } else if (REG_IS_W(src_size)) { - host_x86_MOV16_REG_REG(block, REG_ECX, src_reg); - host_x86_CALL(block, codegen_mem_store_word); - } else if (REG_IS_L(src_size)) { - host_x86_MOV32_REG_REG(block, REG_ECX, src_reg); - host_x86_CALL(block, codegen_mem_store_long); - } else if (REG_IS_Q(src_size)) { - host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg); - host_x86_CALL(block, codegen_mem_store_quad); - } + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + if (uop->imm_data) + host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); + if (REG_IS_B(src_size)) { + host_x86_MOV8_REG_REG(block, REG_ECX, src_reg); + host_x86_CALL(block, codegen_mem_store_byte); + } else if (REG_IS_W(src_size)) { + host_x86_MOV16_REG_REG(block, REG_ECX, src_reg); + host_x86_CALL(block, codegen_mem_store_word); + } else if (REG_IS_L(src_size)) { + host_x86_MOV32_REG_REG(block, REG_ECX, src_reg); + host_x86_CALL(block, codegen_mem_store_long); + } else if (REG_IS_Q(src_size)) { + host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg); + host_x86_CALL(block, codegen_mem_store_quad); + } #ifdef RECOMPILER_DEBUG - else - fatal("MEM_STORE_REG - %02x\n", uop->src_reg_b_real); + else + fatal("MEM_STORE_REG - %02x\n", uop->src_reg_b_real); #endif - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); - return 0; + return 0; } static int codegen_MEM_STORE_SINGLE(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), + src_reg = HOST_REG_GET(uop->src_reg_c_real); #ifdef RECOMPILER_DEBUG - int src_size = IREG_GET_SIZE(uop->src_reg_c_real); - if (!REG_IS_D(src_size)) - fatal("MEM_STORE_SINGLE - %02x\n", uop->src_reg_b_real); + int src_size = IREG_GET_SIZE(uop->src_reg_c_real); + if (!REG_IS_D(src_size)) + fatal("MEM_STORE_SINGLE - %02x\n", uop->src_reg_b_real); #endif - host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); - if (uop->imm_data) - host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); - host_x86_CVTSD2SS_XREG_XREG(block, REG_XMM_TEMP, src_reg); - host_x86_CALL(block, codegen_mem_store_single); - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + if (uop->imm_data) + host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); + host_x86_CVTSD2SS_XREG_XREG(block, REG_XMM_TEMP, src_reg); + host_x86_CALL(block, codegen_mem_store_single); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); - return 0; + return 0; } static int codegen_MEM_STORE_DOUBLE(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), + src_reg = HOST_REG_GET(uop->src_reg_c_real); #ifdef RECOMPILER_DEBUG - int src_size = IREG_GET_SIZE(uop->src_reg_c_real); - if (!REG_IS_D(src_size)) - fatal("MEM_STORE_DOUBLE - %02x\n", uop->src_reg_b_real); + int src_size = IREG_GET_SIZE(uop->src_reg_c_real); + if (!REG_IS_D(src_size)) + fatal("MEM_STORE_DOUBLE - %02x\n", uop->src_reg_b_real); #endif - host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); - if (uop->imm_data) - host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); - host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg); - host_x86_CALL(block, codegen_mem_store_double); - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + if (uop->imm_data) + host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); + host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg); + host_x86_CALL(block, codegen_mem_store_double); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); - return 0; + return 0; } static int codegen_MOV(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - } else if (REG_IS_D(dest_size) && REG_IS_D(src_size)) { - host_x86_MOVQ_XREG_XREG(block, dest_reg, src_reg); - } else if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { - host_x86_MOVQ_XREG_XREG(block, dest_reg, src_reg); - } + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + } else if (REG_IS_D(dest_size) && REG_IS_D(src_size)) { + host_x86_MOVQ_XREG_XREG(block, dest_reg, src_reg); + } else if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + host_x86_MOVQ_XREG_XREG(block, dest_reg, src_reg); + } #ifdef RECOMPILER_DEBUG - else - fatal("MOV %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("MOV %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_MOV_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - if (REG_IS_L(dest_size)) { - host_x86_MOV32_REG_IMM(block, dest_reg, uop->imm_data); - } else if (REG_IS_W(dest_size)) { - host_x86_MOV16_REG_IMM(block, dest_reg, uop->imm_data); - } else if (REG_IS_B(dest_size)) { - host_x86_MOV8_REG_IMM(block, dest_reg, uop->imm_data); - } + if (REG_IS_L(dest_size)) { + host_x86_MOV32_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size)) { + host_x86_MOV16_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size)) { + host_x86_MOV8_REG_IMM(block, dest_reg, uop->imm_data); + } #ifdef RECOMPILER_DEBUG - else - fatal("MOV_IMM %02x\n", uop->dest_reg_a_real); + else + fatal("MOV_IMM %02x\n", uop->dest_reg_a_real); #endif - return 0; + return 0; } static int codegen_MOV_PTR(codeblock_t *block, uop_t *uop) { - host_x86_MOV64_REG_IMM(block, uop->dest_reg_a_real, (uint64_t)uop->p); - return 0; + host_x86_MOV64_REG_IMM(block, uop->dest_reg_a_real, (uint64_t)uop->p); + return 0; } static int codegen_MOV_REG_PTR(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - if (REG_IS_L(dest_size)) { - host_x86_MOV32_REG_ABS(block, dest_reg, uop->p); - } else - fatal("MOV_REG_PTR %02x\n", uop->dest_reg_a_real); + if (REG_IS_L(dest_size)) { + host_x86_MOV32_REG_ABS(block, dest_reg, uop->p); + } else + fatal("MOV_REG_PTR %02x\n", uop->dest_reg_a_real); - return 0; + return 0; } static int codegen_MOVZX_REG_PTR_8(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - if (REG_IS_L(dest_size)) { - host_x86_MOVZX_REG_ABS_32_8(block, dest_reg, uop->p); - } else if (REG_IS_W(dest_size)) { - host_x86_MOVZX_REG_ABS_16_8(block, dest_reg, uop->p); - } else if (REG_IS_B(dest_size)) { - host_x86_MOV8_REG_ABS(block, dest_reg, uop->p); - } else - fatal("MOVZX_REG_PTR_8 %02x\n", uop->dest_reg_a_real); + if (REG_IS_L(dest_size)) { + host_x86_MOVZX_REG_ABS_32_8(block, dest_reg, uop->p); + } else if (REG_IS_W(dest_size)) { + host_x86_MOVZX_REG_ABS_16_8(block, dest_reg, uop->p); + } else if (REG_IS_B(dest_size)) { + host_x86_MOV8_REG_ABS(block, dest_reg, uop->p); + } else + fatal("MOVZX_REG_PTR_8 %02x\n", uop->dest_reg_a_real); - return 0; + return 0; } static int codegen_MOVZX_REG_PTR_16(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - if (REG_IS_L(dest_size)) { - host_x86_MOVZX_REG_ABS_32_16(block, dest_reg, uop->p); - } else if (REG_IS_W(dest_size)) { - host_x86_MOV16_REG_ABS(block, dest_reg, uop->p); - } else - fatal("MOVZX_REG_PTR_16 %02x\n", uop->dest_reg_a_real); + if (REG_IS_L(dest_size)) { + host_x86_MOVZX_REG_ABS_32_16(block, dest_reg, uop->p); + } else if (REG_IS_W(dest_size)) { + host_x86_MOV16_REG_ABS(block, dest_reg, uop->p); + } else + fatal("MOVZX_REG_PTR_16 %02x\n", uop->dest_reg_a_real); - return 0; + return 0; } static int codegen_MOVSX(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_W(src_size)) { - host_x86_MOVSX_REG_32_16(block, dest_reg, src_reg); - } else if (REG_IS_L(dest_size) && REG_IS_B(src_size)) { - host_x86_MOVSX_REG_32_8(block, dest_reg, src_reg); - } else if (REG_IS_W(dest_size) && REG_IS_B(src_size)) { - host_x86_MOVSX_REG_16_8(block, dest_reg, src_reg); - } + if (REG_IS_L(dest_size) && REG_IS_W(src_size)) { + host_x86_MOVSX_REG_32_16(block, dest_reg, src_reg); + } else if (REG_IS_L(dest_size) && REG_IS_B(src_size)) { + host_x86_MOVSX_REG_32_8(block, dest_reg, src_reg); + } else if (REG_IS_W(dest_size) && REG_IS_B(src_size)) { + host_x86_MOVSX_REG_16_8(block, dest_reg, src_reg); + } #ifdef RECOMPILER_DEBUG - else - fatal("MOVSX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("MOVSX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_MOVZX(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_Q(dest_size) && REG_IS_L(src_size)) { - host_x86_MOVD_XREG_REG(block, dest_reg, src_reg); - } else if (REG_IS_L(dest_size) && REG_IS_Q(src_size)) { - host_x86_MOVD_REG_XREG(block, dest_reg, src_reg); - } else if (REG_IS_L(dest_size) && REG_IS_W(src_size)) { - host_x86_MOVZX_REG_32_16(block, dest_reg, src_reg); - } else if (REG_IS_L(dest_size) && REG_IS_B(src_size)) { - host_x86_MOVZX_REG_32_8(block, dest_reg, src_reg); - } else if (REG_IS_W(dest_size) && REG_IS_B(src_size)) { - host_x86_MOVZX_REG_16_8(block, dest_reg, src_reg); - } + if (REG_IS_Q(dest_size) && REG_IS_L(src_size)) { + host_x86_MOVD_XREG_REG(block, dest_reg, src_reg); + } else if (REG_IS_L(dest_size) && REG_IS_Q(src_size)) { + host_x86_MOVD_REG_XREG(block, dest_reg, src_reg); + } else if (REG_IS_L(dest_size) && REG_IS_W(src_size)) { + host_x86_MOVZX_REG_32_16(block, dest_reg, src_reg); + } else if (REG_IS_L(dest_size) && REG_IS_B(src_size)) { + host_x86_MOVZX_REG_32_8(block, dest_reg, src_reg); + } else if (REG_IS_W(dest_size) && REG_IS_B(src_size)) { + host_x86_MOVZX_REG_16_8(block, dest_reg, src_reg); + } #ifdef RECOMPILER_DEBUG - else - fatal("MOVZX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("MOVZX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_MOV_DOUBLE_INT(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_D(dest_size) && REG_IS_L(src_size)) { - host_x86_CVTSI2SD_XREG_REG(block, dest_reg, src_reg); - } else if (REG_IS_D(dest_size) && REG_IS_W(src_size)) { - host_x86_MOVSX_REG_32_16(block, REG_ECX, src_reg); - host_x86_CVTSI2SD_XREG_REG(block, dest_reg, REG_ECX); - } else if (REG_IS_D(dest_size) && REG_IS_Q(src_size)) { - host_x86_MOVQ_REG_XREG(block, REG_RCX, src_reg); - host_x86_CVTSI2SD_XREG_REG64(block, dest_reg, REG_RCX); - } + if (REG_IS_D(dest_size) && REG_IS_L(src_size)) { + host_x86_CVTSI2SD_XREG_REG(block, dest_reg, src_reg); + } else if (REG_IS_D(dest_size) && REG_IS_W(src_size)) { + host_x86_MOVSX_REG_32_16(block, REG_ECX, src_reg); + host_x86_CVTSI2SD_XREG_REG(block, dest_reg, REG_ECX); + } else if (REG_IS_D(dest_size) && REG_IS_Q(src_size)) { + host_x86_MOVQ_REG_XREG(block, REG_RCX, src_reg); + host_x86_CVTSI2SD_XREG_REG64(block, dest_reg, REG_RCX); + } #ifdef RECOMPILER_DEBUG - else - fatal("MOV_DOUBLE_INT %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("MOV_DOUBLE_INT %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_MOV_INT_DOUBLE(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_D(src_size)) { - host_x86_LDMXCSR(block, &cpu_state.new_fp_control); - host_x86_CVTSD2SI_REG_XREG(block, dest_reg, src_reg); - host_x86_LDMXCSR(block, &cpu_state.old_fp_control); - } else if (REG_IS_W(dest_size) && REG_IS_D(src_size)) { - host_x86_LDMXCSR(block, &cpu_state.new_fp_control); - host_x86_CVTSD2SI_REG_XREG(block, REG_ECX, src_reg); - host_x86_MOV16_REG_REG(block, dest_reg, REG_ECX); - host_x86_LDMXCSR(block, &cpu_state.old_fp_control); - } + if (REG_IS_L(dest_size) && REG_IS_D(src_size)) { + host_x86_LDMXCSR(block, &cpu_state.new_fp_control); + host_x86_CVTSD2SI_REG_XREG(block, dest_reg, src_reg); + host_x86_LDMXCSR(block, &cpu_state.old_fp_control); + } else if (REG_IS_W(dest_size) && REG_IS_D(src_size)) { + host_x86_LDMXCSR(block, &cpu_state.new_fp_control); + host_x86_CVTSD2SI_REG_XREG(block, REG_ECX, src_reg); + host_x86_MOV16_REG_REG(block, dest_reg, REG_ECX); + host_x86_LDMXCSR(block, &cpu_state.old_fp_control); + } #ifdef RECOMPILER_DEBUG - else - fatal("MOV_INT_DOUBLE %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("MOV_INT_DOUBLE %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_MOV_INT_DOUBLE_64(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), src_64_reg = HOST_REG_GET(uop->src_reg_b_real), tag_reg = HOST_REG_GET(uop->src_reg_c_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real), src_64_size = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), + src_64_reg = HOST_REG_GET(uop->src_reg_b_real), tag_reg = HOST_REG_GET(uop->src_reg_c_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real), + src_64_size = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_D(src_size) && REG_IS_Q(src_64_size)) { - uint32_t *branch_offset; + if (REG_IS_Q(dest_size) && REG_IS_D(src_size) && REG_IS_Q(src_64_size)) { + uint32_t *branch_offset; - /*If TAG_UINT64 is set then the source is MM[]. Otherwise it is a double in ST()*/ - host_x86_MOVQ_XREG_XREG(block, dest_reg, src_64_reg); - host_x86_TEST8_REG(block, tag_reg, tag_reg); - branch_offset = host_x86_JS_long(block); + /*If TAG_UINT64 is set then the source is MM[]. Otherwise it is a double in ST()*/ + host_x86_MOVQ_XREG_XREG(block, dest_reg, src_64_reg); + host_x86_TEST8_REG(block, tag_reg, tag_reg); + branch_offset = host_x86_JS_long(block); - host_x86_LDMXCSR(block, &cpu_state.new_fp_control); - host_x86_CVTSD2SI_REG64_XREG(block, REG_RCX, src_reg); - host_x86_LDMXCSR(block, &cpu_state.old_fp_control); - host_x86_MOVQ_XREG_REG(block, dest_reg, REG_RCX); + host_x86_LDMXCSR(block, &cpu_state.new_fp_control); + host_x86_CVTSD2SI_REG64_XREG(block, REG_RCX, src_reg); + host_x86_LDMXCSR(block, &cpu_state.old_fp_control); + host_x86_MOVQ_XREG_REG(block, dest_reg, REG_RCX); - *branch_offset = (uint32_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 4; - } + *branch_offset = (uint32_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 4; + } #ifdef RECOMPILER_DEBUG - else - fatal("MOV_INT_DOUBLE_64 %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("MOV_INT_DOUBLE_64 %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } -static int codegen_NOP(codeblock_t *block, uop_t *uop) { - return 0; -} +static int codegen_NOP(codeblock_t *block, uop_t *uop) { return 0; } static int codegen_OR(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_POR_XREG_XREG(block, dest_reg, src_reg_b); - } else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { - if (dest_reg != src_reg_a) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a); - host_x86_OR32_REG_REG(block, dest_reg, src_reg_b); - } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { - if (dest_reg != src_reg_a) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); - host_x86_OR16_REG_REG(block, dest_reg, src_reg_b); - } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { - if (dest_reg != src_reg_a) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); - host_x86_OR8_REG_REG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_POR_XREG_XREG(block, dest_reg, src_reg_b); + } else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + if (dest_reg != src_reg_a) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a); + host_x86_OR32_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + if (dest_reg != src_reg_a) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); + host_x86_OR16_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + if (dest_reg != src_reg_a) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); + host_x86_OR8_REG_REG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("OR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("OR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_OR_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { - host_x86_OR32_REG_IMM(block, dest_reg, uop->imm_data); - } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { - host_x86_OR16_REG_IMM(block, dest_reg, uop->imm_data); - } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { - host_x86_OR8_REG_IMM(block, dest_reg, uop->imm_data); - } + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_x86_OR32_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_x86_OR16_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_x86_OR8_REG_IMM(block, dest_reg, uop->imm_data); + } #ifdef RECOMPILER_DEBUG - else - fatal("OR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("OR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_PACKSSWB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PACKSSWB_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PACKSSWB_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PACKSSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PACKSSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PACKSSDW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PACKSSDW_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PACKSSDW_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PACKSSDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PACKSSDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PACKUSWB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PACKUSWB_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PACKUSWB_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PACKUSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PACKUSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PADDB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PADDB_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PADDB_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PADDB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PADDB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PADDW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PADDW_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PADDW_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PADDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PADDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PADDD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PADDD_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PADDD_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PADDD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PADDD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PADDSB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PADDSB_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PADDSB_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PADDSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PADDSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PADDSW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PADDSW_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PADDSW_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PADDSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PADDSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PADDUSB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PADDUSB_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PADDUSB_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PADDUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PADDUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PADDUSW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PADDUSW_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PADDUSW_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PADDUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PADDUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PCMPEQB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PCMPEQB_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PCMPEQB_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PCMPEQB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PCMPEQB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PCMPEQW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PCMPEQW_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PCMPEQW_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PCMPEQW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PCMPEQW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PCMPEQD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PCMPEQD_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PCMPEQD_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PCMPEQD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PCMPEQD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PCMPGTB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PCMPGTB_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PCMPGTB_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PCMPGTB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PCMPGTB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PCMPGTW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PCMPGTW_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PCMPGTW_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PCMPGTW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PCMPGTW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PCMPGTD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PCMPGTD_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PCMPGTD_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PCMPGTD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PCMPGTD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PF2ID(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { - host_x86_LDMXCSR(block, &cpu_state.trunc_fp_control); - host_x86_CVTPS2DQ_XREG_XREG(block, dest_reg, src_reg_a); - host_x86_LDMXCSR(block, &cpu_state.old_fp_control); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { + host_x86_LDMXCSR(block, &cpu_state.trunc_fp_control); + host_x86_CVTPS2DQ_XREG_XREG(block, dest_reg, src_reg_a); + host_x86_LDMXCSR(block, &cpu_state.old_fp_control); + } #ifdef RECOMPILER_DEBUG - else - fatal("PF2ID %02x %02x\n", uop->dest_reg_a_real); + else + fatal("PF2ID %02x %02x\n", uop->dest_reg_a_real); #endif - return 0; + return 0; } static int codegen_PFADD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_ADDPS_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_ADDPS_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PFADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PFADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PFCMPEQ(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_CMPPS_XREG_XREG(block, dest_reg, src_reg_b, CMPPS_EQ); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_CMPPS_XREG_XREG(block, dest_reg, src_reg_b, CMPPS_EQ); + } #ifdef RECOMPILER_DEBUG - else - fatal("PFCMPEQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PFCMPEQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PFCMPGE(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_CMPPS_XREG_XREG(block, dest_reg, src_reg_b, CMPPS_NLT); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_CMPPS_XREG_XREG(block, dest_reg, src_reg_b, CMPPS_NLT); + } #ifdef RECOMPILER_DEBUG - else - fatal("PFCMPGE %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PFCMPGE %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PFCMPGT(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_CMPPS_XREG_XREG(block, dest_reg, src_reg_b, CMPPS_NLE); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_CMPPS_XREG_XREG(block, dest_reg, src_reg_b, CMPPS_NLE); + } #ifdef RECOMPILER_DEBUG - else - fatal("PFCMPGT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PFCMPGT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PFMAX(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_MAXPS_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_MAXPS_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PFMAX %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PFMAX %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PFMIN(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_MINPS_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_MINPS_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PFMIN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PFMIN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PFMUL(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_MULPS_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_MULPS_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PFMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PFMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PFRCP(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { - /*TODO: This could be improved (use RCPSS + iteration)*/ - host_x86_MOV32_REG_IMM(block, REG_ECX, 1); - host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); - host_x86_CVTSI2SS_XREG_REG(block, dest_reg, REG_ECX); - host_x86_DIVSS_XREG_XREG(block, dest_reg, REG_XMM_TEMP); - host_x86_UNPCKLPS_XREG_XREG(block, dest_reg, dest_reg); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { + /*TODO: This could be improved (use RCPSS + iteration)*/ + host_x86_MOV32_REG_IMM(block, REG_ECX, 1); + host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); + host_x86_CVTSI2SS_XREG_REG(block, dest_reg, REG_ECX); + host_x86_DIVSS_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + host_x86_UNPCKLPS_XREG_XREG(block, dest_reg, dest_reg); + } #ifdef RECOMPILER_DEBUG - else - fatal("PFRCP %02x %02x\n", uop->dest_reg_a_real); + else + fatal("PFRCP %02x %02x\n", uop->dest_reg_a_real); #endif - return 0; + return 0; } static int codegen_PFRSQRT(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { - /*TODO: This could be improved (use RSQRTSS + iteration)*/ - host_x86_SQRTSS_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); - host_x86_MOV32_REG_IMM(block, REG_ECX, 1); - host_x86_CVTSI2SS_XREG_REG(block, dest_reg, REG_ECX); - host_x86_DIVSS_XREG_XREG(block, dest_reg, REG_XMM_TEMP); - host_x86_UNPCKLPS_XREG_XREG(block, dest_reg, dest_reg); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { + /*TODO: This could be improved (use RSQRTSS + iteration)*/ + host_x86_SQRTSS_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); + host_x86_MOV32_REG_IMM(block, REG_ECX, 1); + host_x86_CVTSI2SS_XREG_REG(block, dest_reg, REG_ECX); + host_x86_DIVSS_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + host_x86_UNPCKLPS_XREG_XREG(block, dest_reg, dest_reg); + } #ifdef RECOMPILER_DEBUG - else - fatal("PFRSQRT %02x %02x\n", uop->dest_reg_a_real); + else + fatal("PFRSQRT %02x %02x\n", uop->dest_reg_a_real); #endif - return 0; + return 0; } static int codegen_PFSUB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_SUBPS_XREG_XREG(block, dest_reg, src_reg_b); - } else if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { - host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); - host_x86_SUBPS_XREG_XREG(block, REG_XMM_TEMP, src_reg_b); - host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_SUBPS_XREG_XREG(block, dest_reg, src_reg_b); + } else if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); + host_x86_SUBPS_XREG_XREG(block, REG_XMM_TEMP, src_reg_b); + host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + } #ifdef RECOMPILER_DEBUG - else - fatal("PFSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PFSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PI2FD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { - host_x86_CVTDQ2PS_XREG_XREG(block, dest_reg, src_reg_a); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { + host_x86_CVTDQ2PS_XREG_XREG(block, dest_reg, src_reg_a); + } #ifdef RECOMPILER_DEBUG - else - fatal("PI2FD %02x %02x\n", uop->dest_reg_a_real); + else + fatal("PI2FD %02x %02x\n", uop->dest_reg_a_real); #endif - return 0; + return 0; } static int codegen_PMADDWD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PMADDWD_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PMADDWD_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PMULHW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PMULHW_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PMULHW_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PMULLW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PMULLW_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PMULLW_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PMULLW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PMULLW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PSLLW_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PSLLW_XREG_IMM(block, dest_reg, uop->imm_data); - } + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSLLW_XREG_IMM(block, dest_reg, uop->imm_data); + } #ifdef RECOMPILER_DEBUG - else - fatal("PSLLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("PSLLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_PSLLD_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PSLLD_XREG_IMM(block, dest_reg, uop->imm_data); - } + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSLLD_XREG_IMM(block, dest_reg, uop->imm_data); + } #ifdef RECOMPILER_DEBUG - else - fatal("PSLLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("PSLLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_PSLLQ_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PSLLQ_XREG_IMM(block, dest_reg, uop->imm_data); - } + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSLLQ_XREG_IMM(block, dest_reg, uop->imm_data); + } #ifdef RECOMPILER_DEBUG - else - fatal("PSLLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("PSLLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_PSRAW_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PSRAW_XREG_IMM(block, dest_reg, uop->imm_data); - } + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSRAW_XREG_IMM(block, dest_reg, uop->imm_data); + } #ifdef RECOMPILER_DEBUG - else - fatal("PSRAW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("PSRAW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_PSRAD_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PSRAD_XREG_IMM(block, dest_reg, uop->imm_data); - } + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSRAD_XREG_IMM(block, dest_reg, uop->imm_data); + } #ifdef RECOMPILER_DEBUG - else - fatal("PSRAD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("PSRAD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_PSRAQ_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PSRAQ_XREG_IMM(block, dest_reg, uop->imm_data); - } + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSRAQ_XREG_IMM(block, dest_reg, uop->imm_data); + } #ifdef RECOMPILER_DEBUG - else - fatal("PSRAQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("PSRAQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_PSRLW_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PSRLW_XREG_IMM(block, dest_reg, uop->imm_data); - } + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSRLW_XREG_IMM(block, dest_reg, uop->imm_data); + } #ifdef RECOMPILER_DEBUG - else - fatal("PSRLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("PSRLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_PSRLD_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PSRLD_XREG_IMM(block, dest_reg, uop->imm_data); - } + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSRLD_XREG_IMM(block, dest_reg, uop->imm_data); + } #ifdef RECOMPILER_DEBUG - else - fatal("PSRLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("PSRLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_PSRLQ_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PSRLQ_XREG_IMM(block, dest_reg, uop->imm_data); - } + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSRLQ_XREG_IMM(block, dest_reg, uop->imm_data); + } #ifdef RECOMPILER_DEBUG - else - fatal("PSRLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("PSRLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_PSUBB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PSUBB_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSUBB_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PSUBB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PSUBB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PSUBW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PSUBW_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSUBW_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PSUBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PSUBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PSUBD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PSUBD_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSUBD_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PSUBD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PSUBD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PSUBSB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PSUBSB_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSUBSB_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PSUBSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PSUBSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PSUBSW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PSUBSW_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSUBSW_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PSUBSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PSUBSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PSUBUSB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PSUBUSB_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSUBUSB_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PSUBUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PSUBUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PSUBUSW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PSUBUSW_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSUBUSW_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PSUBUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PSUBUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PUNPCKHBW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PUNPCKHBW_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PUNPCKHBW_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PUNPCKHBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PUNPCKHBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PUNPCKHWD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PUNPCKHWD_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PUNPCKHWD_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PUNPCKHWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PUNPCKHWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PUNPCKHDQ(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PUNPCKHDQ_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PUNPCKHDQ_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PUNPCKHDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PUNPCKHDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PUNPCKLBW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PUNPCKLBW_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PUNPCKLBW_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PUNPCKLBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PUNPCKLBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PUNPCKLWD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PUNPCKLWD_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PUNPCKLWD_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PUNPCKLWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PUNPCKLWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PUNPCKLDQ(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PUNPCKLDQ_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PUNPCKLDQ_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PUNPCKLDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PUNPCKLDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_ROL(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), + shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_ROL32_CL(block, dest_reg); - } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_ROL16_CL(block, dest_reg); - } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_ROL8_CL(block, dest_reg); - } + host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_ROL32_CL(block, dest_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_ROL16_CL(block, dest_reg); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_ROL8_CL(block, dest_reg); + } #ifdef RECOMPILER_DEBUG - else - fatal("ROL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("ROL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_ROL_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_ROL32_IMM(block, dest_reg, uop->imm_data); - } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_ROL16_IMM(block, dest_reg, uop->imm_data); - } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_ROL8_IMM(block, dest_reg, uop->imm_data); - } + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_ROL32_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_ROL16_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_ROL8_IMM(block, dest_reg, uop->imm_data); + } #ifdef RECOMPILER_DEBUG - else - fatal("ROL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("ROL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_ROR(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), + shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_ROR32_CL(block, dest_reg); - } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_ROR16_CL(block, dest_reg); - } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_ROR8_CL(block, dest_reg); - } + host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_ROR32_CL(block, dest_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_ROR16_CL(block, dest_reg); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_ROR8_CL(block, dest_reg); + } #ifdef RECOMPILER_DEBUG - else - fatal("ROR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("ROR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_ROR_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_ROR32_IMM(block, dest_reg, uop->imm_data); - } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_ROR16_IMM(block, dest_reg, uop->imm_data); - } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_ROR8_IMM(block, dest_reg, uop->imm_data); - } + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_ROR32_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_ROR16_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_ROR8_IMM(block, dest_reg, uop->imm_data); + } #ifdef RECOMPILER_DEBUG - else - fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_SAR(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), + shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_SAR32_CL(block, dest_reg); - } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_SAR16_CL(block, dest_reg); - } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_SAR8_CL(block, dest_reg); - } + host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_SAR32_CL(block, dest_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_SAR16_CL(block, dest_reg); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_SAR8_CL(block, dest_reg); + } #ifdef RECOMPILER_DEBUG - else - fatal("SAR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("SAR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_SAR_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_SAR32_IMM(block, dest_reg, uop->imm_data); - } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_SAR16_IMM(block, dest_reg, uop->imm_data); - } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_SAR8_IMM(block, dest_reg, uop->imm_data); - } + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_SAR32_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_SAR16_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_SAR8_IMM(block, dest_reg, uop->imm_data); + } #ifdef RECOMPILER_DEBUG - else - fatal("SAR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("SAR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_SHL(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), + shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_SHL32_CL(block, dest_reg); - } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_SHL16_CL(block, dest_reg); - } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_SHL8_CL(block, dest_reg); - } + host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_SHL32_CL(block, dest_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_SHL16_CL(block, dest_reg); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_SHL8_CL(block, dest_reg); + } #ifdef RECOMPILER_DEBUG - else - fatal("SHL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("SHL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_SHL_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_SHL32_IMM(block, dest_reg, uop->imm_data); - } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_SHL16_IMM(block, dest_reg, uop->imm_data); - } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_SHL8_IMM(block, dest_reg, uop->imm_data); - } + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_SHL32_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_SHL16_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_SHL8_IMM(block, dest_reg, uop->imm_data); + } #ifdef RECOMPILER_DEBUG - else - fatal("SHL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("SHL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_SHR(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), + shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_SHR32_CL(block, dest_reg); - } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_SHR16_CL(block, dest_reg); - } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_SHR8_CL(block, dest_reg); - } + host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_SHR32_CL(block, dest_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_SHR16_CL(block, dest_reg); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_SHR8_CL(block, dest_reg); + } #ifdef RECOMPILER_DEBUG - else - fatal("SHR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("SHR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_SHR_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_SHR32_IMM(block, dest_reg, uop->imm_data); - } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_SHR16_IMM(block, dest_reg, uop->imm_data); - } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_SHR8_IMM(block, dest_reg, uop->imm_data); - } + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_SHR32_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_SHR16_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_SHR8_IMM(block, dest_reg, uop->imm_data); + } #ifdef RECOMPILER_DEBUG - else - fatal("SHR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("SHR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_STORE_PTR_IMM(codeblock_t *block, uop_t *uop) { #ifdef RECOMPILER_DEBUG - if (((uintptr_t)uop->p) >> 32) - fatal("STORE_PTR_IMM 64-bit addr\n"); + if (((uintptr_t)uop->p) >> 32) + fatal("STORE_PTR_IMM 64-bit addr\n"); #endif - host_x86_MOV32_ABS_IMM(block, uop->p, uop->imm_data); - return 0; + host_x86_MOV32_ABS_IMM(block, uop->p, uop->imm_data); + return 0; } static int codegen_STORE_PTR_IMM_8(codeblock_t *block, uop_t *uop) { #ifdef RECOMPILER_DEBUG - if (((uintptr_t)uop->p) >> 32) - fatal("STORE_PTR_IMM_8 64-bit addr\n"); + if (((uintptr_t)uop->p) >> 32) + fatal("STORE_PTR_IMM_8 64-bit addr\n"); #endif - host_x86_MOV8_ABS_IMM(block, uop->p, uop->imm_data); - return 0; + host_x86_MOV8_ABS_IMM(block, uop->p, uop->imm_data); + return 0; } static int codegen_SUB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { - if (dest_reg != src_reg_a) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a); - host_x86_SUB32_REG_REG(block, dest_reg, src_reg_b); - } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { - if (dest_reg != src_reg_a) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); - host_x86_SUB16_REG_REG(block, dest_reg, src_reg_b); - } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { - if (dest_reg != src_reg_a) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); - host_x86_SUB8_REG_REG(block, dest_reg, src_reg_b); - } + if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + if (dest_reg != src_reg_a) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a); + host_x86_SUB32_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + if (dest_reg != src_reg_a) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); + host_x86_SUB16_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + if (dest_reg != src_reg_a) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); + host_x86_SUB8_REG_REG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("SUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("SUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_SUB_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { - if (dest_reg != src_reg) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_SUB32_REG_IMM(block, dest_reg, uop->imm_data); - } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { - if (dest_reg != src_reg) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_SUB16_REG_IMM(block, dest_reg, uop->imm_data); - } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { - if (dest_reg != src_reg) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_SUB8_REG_IMM(block, dest_reg, uop->imm_data); - } + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (dest_reg != src_reg) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_SUB32_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (dest_reg != src_reg) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_SUB16_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (dest_reg != src_reg) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_SUB8_REG_IMM(block, dest_reg, uop->imm_data); + } #ifdef RECOMPILER_DEBUG - else - fatal("SUB_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("SUB_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_TEST_JNS_DEST(codeblock_t *block, uop_t *uop) { - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(src_size)) { - host_x86_TEST32_REG(block, src_reg, src_reg); - } else if (REG_IS_W(src_size)) { - host_x86_TEST16_REG(block, src_reg, src_reg); - } else if (REG_IS_B(src_size)) { - host_x86_TEST8_REG(block, src_reg, src_reg); - } + if (REG_IS_L(src_size)) { + host_x86_TEST32_REG(block, src_reg, src_reg); + } else if (REG_IS_W(src_size)) { + host_x86_TEST16_REG(block, src_reg, src_reg); + } else if (REG_IS_B(src_size)) { + host_x86_TEST8_REG(block, src_reg, src_reg); + } #ifdef RECOMPILER_DEBUG - else - fatal("TEST_JNS_DEST %02x\n", uop->src_reg_a_real); + else + fatal("TEST_JNS_DEST %02x\n", uop->src_reg_a_real); #endif - uop->p = host_x86_JNS_long(block); + uop->p = host_x86_JNS_long(block); - return 0; + return 0; } static int codegen_TEST_JS_DEST(codeblock_t *block, uop_t *uop) { - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(src_size)) { - host_x86_TEST32_REG(block, src_reg, src_reg); - } else if (REG_IS_W(src_size)) { - host_x86_TEST16_REG(block, src_reg, src_reg); - } else if (REG_IS_B(src_size)) { - host_x86_TEST8_REG(block, src_reg, src_reg); - } + if (REG_IS_L(src_size)) { + host_x86_TEST32_REG(block, src_reg, src_reg); + } else if (REG_IS_W(src_size)) { + host_x86_TEST16_REG(block, src_reg, src_reg); + } else if (REG_IS_B(src_size)) { + host_x86_TEST8_REG(block, src_reg, src_reg); + } #ifdef RECOMPILER_DEBUG - else - fatal("TEST_JS_DEST %02x\n", uop->src_reg_a_real); + else + fatal("TEST_JS_DEST %02x\n", uop->src_reg_a_real); #endif - uop->p = host_x86_JS_long(block); + uop->p = host_x86_JS_long(block); - return 0; + return 0; } static int codegen_XOR(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PXOR_XREG_XREG(block, dest_reg, src_reg_b); - } else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_XOR32_REG_REG(block, dest_reg, src_reg_b); - } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_XOR16_REG_REG(block, dest_reg, src_reg_b); - } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_XOR8_REG_REG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PXOR_XREG_XREG(block, dest_reg, src_reg_b); + } else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b) && + uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_XOR32_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b) && + uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_XOR16_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && + uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_XOR8_REG_REG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("XOR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("XOR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { - host_x86_XOR32_REG_IMM(block, dest_reg, uop->imm_data); - } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { - host_x86_XOR16_REG_IMM(block, dest_reg, uop->imm_data); - } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { - host_x86_XOR8_REG_IMM(block, dest_reg, uop->imm_data); - } + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_x86_XOR32_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_x86_XOR16_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_x86_XOR8_REG_IMM(block, dest_reg, uop->imm_data); + } #ifdef RECOMPILER_DEBUG - else - fatal("XOR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("XOR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } -const uOpFn uop_handlers[UOP_MAX] = - { - [UOP_CALL_FUNC & UOP_MASK] = codegen_CALL_FUNC, - [UOP_CALL_FUNC_RESULT & UOP_MASK] = codegen_CALL_FUNC_RESULT, - [UOP_CALL_INSTRUCTION_FUNC & UOP_MASK] = codegen_CALL_INSTRUCTION_FUNC, +const uOpFn uop_handlers[UOP_MAX] = {[UOP_CALL_FUNC & UOP_MASK] = codegen_CALL_FUNC, + [UOP_CALL_FUNC_RESULT & UOP_MASK] = codegen_CALL_FUNC_RESULT, + [UOP_CALL_INSTRUCTION_FUNC & UOP_MASK] = codegen_CALL_INSTRUCTION_FUNC, - [UOP_JMP & UOP_MASK] = codegen_JMP, + [UOP_JMP & UOP_MASK] = codegen_JMP, - [UOP_LOAD_SEG & UOP_MASK] = codegen_LOAD_SEG, + [UOP_LOAD_SEG & UOP_MASK] = codegen_LOAD_SEG, - [UOP_LOAD_FUNC_ARG_0 & UOP_MASK] = codegen_LOAD_FUNC_ARG0, - [UOP_LOAD_FUNC_ARG_1 & UOP_MASK] = codegen_LOAD_FUNC_ARG1, - [UOP_LOAD_FUNC_ARG_2 & UOP_MASK] = codegen_LOAD_FUNC_ARG2, - [UOP_LOAD_FUNC_ARG_3 & UOP_MASK] = codegen_LOAD_FUNC_ARG3, + [UOP_LOAD_FUNC_ARG_0 & UOP_MASK] = codegen_LOAD_FUNC_ARG0, + [UOP_LOAD_FUNC_ARG_1 & UOP_MASK] = codegen_LOAD_FUNC_ARG1, + [UOP_LOAD_FUNC_ARG_2 & UOP_MASK] = codegen_LOAD_FUNC_ARG2, + [UOP_LOAD_FUNC_ARG_3 & UOP_MASK] = codegen_LOAD_FUNC_ARG3, - [UOP_LOAD_FUNC_ARG_0_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG0_IMM, - [UOP_LOAD_FUNC_ARG_1_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG1_IMM, - [UOP_LOAD_FUNC_ARG_2_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG2_IMM, - [UOP_LOAD_FUNC_ARG_3_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG3_IMM, + [UOP_LOAD_FUNC_ARG_0_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG0_IMM, + [UOP_LOAD_FUNC_ARG_1_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG1_IMM, + [UOP_LOAD_FUNC_ARG_2_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG2_IMM, + [UOP_LOAD_FUNC_ARG_3_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG3_IMM, - [UOP_STORE_P_IMM & UOP_MASK] = codegen_STORE_PTR_IMM, - [UOP_STORE_P_IMM_8 & UOP_MASK] = codegen_STORE_PTR_IMM_8, + [UOP_STORE_P_IMM & UOP_MASK] = codegen_STORE_PTR_IMM, + [UOP_STORE_P_IMM_8 & UOP_MASK] = codegen_STORE_PTR_IMM_8, - [UOP_MEM_LOAD_ABS & UOP_MASK] = codegen_MEM_LOAD_ABS, - [UOP_MEM_LOAD_REG & UOP_MASK] = codegen_MEM_LOAD_REG, - [UOP_MEM_LOAD_SINGLE & UOP_MASK] = codegen_MEM_LOAD_SINGLE, - [UOP_MEM_LOAD_DOUBLE & UOP_MASK] = codegen_MEM_LOAD_DOUBLE, + [UOP_MEM_LOAD_ABS & UOP_MASK] = codegen_MEM_LOAD_ABS, + [UOP_MEM_LOAD_REG & UOP_MASK] = codegen_MEM_LOAD_REG, + [UOP_MEM_LOAD_SINGLE & UOP_MASK] = codegen_MEM_LOAD_SINGLE, + [UOP_MEM_LOAD_DOUBLE & UOP_MASK] = codegen_MEM_LOAD_DOUBLE, - [UOP_MEM_STORE_ABS & UOP_MASK] = codegen_MEM_STORE_ABS, - [UOP_MEM_STORE_REG & UOP_MASK] = codegen_MEM_STORE_REG, - [UOP_MEM_STORE_IMM_8 & UOP_MASK] = codegen_MEM_STORE_IMM_8, - [UOP_MEM_STORE_IMM_16 & UOP_MASK] = codegen_MEM_STORE_IMM_16, - [UOP_MEM_STORE_IMM_32 & UOP_MASK] = codegen_MEM_STORE_IMM_32, - [UOP_MEM_STORE_SINGLE & UOP_MASK] = codegen_MEM_STORE_SINGLE, - [UOP_MEM_STORE_DOUBLE & UOP_MASK] = codegen_MEM_STORE_DOUBLE, + [UOP_MEM_STORE_ABS & UOP_MASK] = codegen_MEM_STORE_ABS, + [UOP_MEM_STORE_REG & UOP_MASK] = codegen_MEM_STORE_REG, + [UOP_MEM_STORE_IMM_8 & UOP_MASK] = codegen_MEM_STORE_IMM_8, + [UOP_MEM_STORE_IMM_16 & UOP_MASK] = codegen_MEM_STORE_IMM_16, + [UOP_MEM_STORE_IMM_32 & UOP_MASK] = codegen_MEM_STORE_IMM_32, + [UOP_MEM_STORE_SINGLE & UOP_MASK] = codegen_MEM_STORE_SINGLE, + [UOP_MEM_STORE_DOUBLE & UOP_MASK] = codegen_MEM_STORE_DOUBLE, - [UOP_MOV & UOP_MASK] = codegen_MOV, - [UOP_MOV_PTR & UOP_MASK] = codegen_MOV_PTR, - [UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM, - [UOP_MOVSX & UOP_MASK] = codegen_MOVSX, - [UOP_MOVZX & UOP_MASK] = codegen_MOVZX, - [UOP_MOV_DOUBLE_INT & UOP_MASK] = codegen_MOV_DOUBLE_INT, - [UOP_MOV_INT_DOUBLE & UOP_MASK] = codegen_MOV_INT_DOUBLE, - [UOP_MOV_INT_DOUBLE_64 & UOP_MASK] = codegen_MOV_INT_DOUBLE_64, - [UOP_MOV_REG_PTR & UOP_MASK] = codegen_MOV_REG_PTR, - [UOP_MOVZX_REG_PTR_8 & UOP_MASK] = codegen_MOVZX_REG_PTR_8, - [UOP_MOVZX_REG_PTR_16 & UOP_MASK] = codegen_MOVZX_REG_PTR_16, + [UOP_MOV & UOP_MASK] = codegen_MOV, + [UOP_MOV_PTR & UOP_MASK] = codegen_MOV_PTR, + [UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM, + [UOP_MOVSX & UOP_MASK] = codegen_MOVSX, + [UOP_MOVZX & UOP_MASK] = codegen_MOVZX, + [UOP_MOV_DOUBLE_INT & UOP_MASK] = codegen_MOV_DOUBLE_INT, + [UOP_MOV_INT_DOUBLE & UOP_MASK] = codegen_MOV_INT_DOUBLE, + [UOP_MOV_INT_DOUBLE_64 & UOP_MASK] = codegen_MOV_INT_DOUBLE_64, + [UOP_MOV_REG_PTR & UOP_MASK] = codegen_MOV_REG_PTR, + [UOP_MOVZX_REG_PTR_8 & UOP_MASK] = codegen_MOVZX_REG_PTR_8, + [UOP_MOVZX_REG_PTR_16 & UOP_MASK] = codegen_MOVZX_REG_PTR_16, - [UOP_ADD & UOP_MASK] = codegen_ADD, - [UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM, - [UOP_ADD_LSHIFT & UOP_MASK] = codegen_ADD_LSHIFT, - [UOP_AND & UOP_MASK] = codegen_AND, - [UOP_ANDN & UOP_MASK] = codegen_ANDN, - [UOP_AND_IMM & UOP_MASK] = codegen_AND_IMM, - [UOP_OR & UOP_MASK] = codegen_OR, - [UOP_OR_IMM & UOP_MASK] = codegen_OR_IMM, - [UOP_SUB & UOP_MASK] = codegen_SUB, - [UOP_SUB_IMM & UOP_MASK] = codegen_SUB_IMM, - [UOP_XOR & UOP_MASK] = codegen_XOR, - [UOP_XOR_IMM & UOP_MASK] = codegen_XOR_IMM, + [UOP_ADD & UOP_MASK] = codegen_ADD, + [UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM, + [UOP_ADD_LSHIFT & UOP_MASK] = codegen_ADD_LSHIFT, + [UOP_AND & UOP_MASK] = codegen_AND, + [UOP_ANDN & UOP_MASK] = codegen_ANDN, + [UOP_AND_IMM & UOP_MASK] = codegen_AND_IMM, + [UOP_OR & UOP_MASK] = codegen_OR, + [UOP_OR_IMM & UOP_MASK] = codegen_OR_IMM, + [UOP_SUB & UOP_MASK] = codegen_SUB, + [UOP_SUB_IMM & UOP_MASK] = codegen_SUB_IMM, + [UOP_XOR & UOP_MASK] = codegen_XOR, + [UOP_XOR_IMM & UOP_MASK] = codegen_XOR_IMM, - [UOP_SAR & UOP_MASK] = codegen_SAR, - [UOP_SAR_IMM & UOP_MASK] = codegen_SAR_IMM, - [UOP_SHL & UOP_MASK] = codegen_SHL, - [UOP_SHL_IMM & UOP_MASK] = codegen_SHL_IMM, - [UOP_SHR & UOP_MASK] = codegen_SHR, - [UOP_SHR_IMM & UOP_MASK] = codegen_SHR_IMM, - [UOP_ROL & UOP_MASK] = codegen_ROL, - [UOP_ROL_IMM & UOP_MASK] = codegen_ROL_IMM, - [UOP_ROR & UOP_MASK] = codegen_ROR, - [UOP_ROR_IMM & UOP_MASK] = codegen_ROR_IMM, + [UOP_SAR & UOP_MASK] = codegen_SAR, + [UOP_SAR_IMM & UOP_MASK] = codegen_SAR_IMM, + [UOP_SHL & UOP_MASK] = codegen_SHL, + [UOP_SHL_IMM & UOP_MASK] = codegen_SHL_IMM, + [UOP_SHR & UOP_MASK] = codegen_SHR, + [UOP_SHR_IMM & UOP_MASK] = codegen_SHR_IMM, + [UOP_ROL & UOP_MASK] = codegen_ROL, + [UOP_ROL_IMM & UOP_MASK] = codegen_ROL_IMM, + [UOP_ROR & UOP_MASK] = codegen_ROR, + [UOP_ROR_IMM & UOP_MASK] = codegen_ROR_IMM, - [UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ, + [UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ, - [UOP_CMP_JB & UOP_MASK] = codegen_CMP_JB, - [UOP_CMP_JNBE & UOP_MASK] = codegen_CMP_JNBE, + [UOP_CMP_JB & UOP_MASK] = codegen_CMP_JB, + [UOP_CMP_JNBE & UOP_MASK] = codegen_CMP_JNBE, - [UOP_CMP_JNB_DEST & UOP_MASK] = codegen_CMP_JNB_DEST, - [UOP_CMP_JNBE_DEST & UOP_MASK] = codegen_CMP_JNBE_DEST, - [UOP_CMP_JNL_DEST & UOP_MASK] = codegen_CMP_JNL_DEST, - [UOP_CMP_JNLE_DEST & UOP_MASK] = codegen_CMP_JNLE_DEST, - [UOP_CMP_JNO_DEST & UOP_MASK] = codegen_CMP_JNO_DEST, - [UOP_CMP_JNZ_DEST & UOP_MASK] = codegen_CMP_JNZ_DEST, - [UOP_CMP_JB_DEST & UOP_MASK] = codegen_CMP_JB_DEST, - [UOP_CMP_JBE_DEST & UOP_MASK] = codegen_CMP_JBE_DEST, - [UOP_CMP_JL_DEST & UOP_MASK] = codegen_CMP_JL_DEST, - [UOP_CMP_JLE_DEST & UOP_MASK] = codegen_CMP_JLE_DEST, - [UOP_CMP_JO_DEST & UOP_MASK] = codegen_CMP_JO_DEST, - [UOP_CMP_JZ_DEST & UOP_MASK] = codegen_CMP_JZ_DEST, + [UOP_CMP_JNB_DEST & UOP_MASK] = codegen_CMP_JNB_DEST, + [UOP_CMP_JNBE_DEST & UOP_MASK] = codegen_CMP_JNBE_DEST, + [UOP_CMP_JNL_DEST & UOP_MASK] = codegen_CMP_JNL_DEST, + [UOP_CMP_JNLE_DEST & UOP_MASK] = codegen_CMP_JNLE_DEST, + [UOP_CMP_JNO_DEST & UOP_MASK] = codegen_CMP_JNO_DEST, + [UOP_CMP_JNZ_DEST & UOP_MASK] = codegen_CMP_JNZ_DEST, + [UOP_CMP_JB_DEST & UOP_MASK] = codegen_CMP_JB_DEST, + [UOP_CMP_JBE_DEST & UOP_MASK] = codegen_CMP_JBE_DEST, + [UOP_CMP_JL_DEST & UOP_MASK] = codegen_CMP_JL_DEST, + [UOP_CMP_JLE_DEST & UOP_MASK] = codegen_CMP_JLE_DEST, + [UOP_CMP_JO_DEST & UOP_MASK] = codegen_CMP_JO_DEST, + [UOP_CMP_JZ_DEST & UOP_MASK] = codegen_CMP_JZ_DEST, - [UOP_CMP_IMM_JNZ_DEST & UOP_MASK] = codegen_CMP_IMM_JNZ_DEST, - [UOP_CMP_IMM_JZ_DEST & UOP_MASK] = codegen_CMP_IMM_JZ_DEST, + [UOP_CMP_IMM_JNZ_DEST & UOP_MASK] = codegen_CMP_IMM_JNZ_DEST, + [UOP_CMP_IMM_JZ_DEST & UOP_MASK] = codegen_CMP_IMM_JZ_DEST, - [UOP_TEST_JNS_DEST & UOP_MASK] = codegen_TEST_JNS_DEST, - [UOP_TEST_JS_DEST & UOP_MASK] = codegen_TEST_JS_DEST, + [UOP_TEST_JNS_DEST & UOP_MASK] = codegen_TEST_JNS_DEST, + [UOP_TEST_JS_DEST & UOP_MASK] = codegen_TEST_JS_DEST, - [UOP_FP_ENTER & UOP_MASK] = codegen_FP_ENTER, - [UOP_MMX_ENTER & UOP_MASK] = codegen_MMX_ENTER, + [UOP_FP_ENTER & UOP_MASK] = codegen_FP_ENTER, + [UOP_MMX_ENTER & UOP_MASK] = codegen_MMX_ENTER, - [UOP_FADD & UOP_MASK] = codegen_FADD, - [UOP_FCOM & UOP_MASK] = codegen_FCOM, - [UOP_FDIV & UOP_MASK] = codegen_FDIV, - [UOP_FMUL & UOP_MASK] = codegen_FMUL, - [UOP_FSUB & UOP_MASK] = codegen_FSUB, + [UOP_FADD & UOP_MASK] = codegen_FADD, + [UOP_FCOM & UOP_MASK] = codegen_FCOM, + [UOP_FDIV & UOP_MASK] = codegen_FDIV, + [UOP_FMUL & UOP_MASK] = codegen_FMUL, + [UOP_FSUB & UOP_MASK] = codegen_FSUB, - [UOP_FABS & UOP_MASK] = codegen_FABS, - [UOP_FCHS & UOP_MASK] = codegen_FCHS, - [UOP_FSQRT & UOP_MASK] = codegen_FSQRT, - [UOP_FTST & UOP_MASK] = codegen_FTST, + [UOP_FABS & UOP_MASK] = codegen_FABS, + [UOP_FCHS & UOP_MASK] = codegen_FCHS, + [UOP_FSQRT & UOP_MASK] = codegen_FSQRT, + [UOP_FTST & UOP_MASK] = codegen_FTST, - [UOP_PACKSSWB & UOP_MASK] = codegen_PACKSSWB, - [UOP_PACKSSDW & UOP_MASK] = codegen_PACKSSDW, - [UOP_PACKUSWB & UOP_MASK] = codegen_PACKUSWB, + [UOP_PACKSSWB & UOP_MASK] = codegen_PACKSSWB, + [UOP_PACKSSDW & UOP_MASK] = codegen_PACKSSDW, + [UOP_PACKUSWB & UOP_MASK] = codegen_PACKUSWB, - [UOP_PADDB & UOP_MASK] = codegen_PADDB, - [UOP_PADDW & UOP_MASK] = codegen_PADDW, - [UOP_PADDD & UOP_MASK] = codegen_PADDD, - [UOP_PADDSB & UOP_MASK] = codegen_PADDSB, - [UOP_PADDSW & UOP_MASK] = codegen_PADDSW, - [UOP_PADDUSB & UOP_MASK] = codegen_PADDUSB, - [UOP_PADDUSW & UOP_MASK] = codegen_PADDUSW, + [UOP_PADDB & UOP_MASK] = codegen_PADDB, + [UOP_PADDW & UOP_MASK] = codegen_PADDW, + [UOP_PADDD & UOP_MASK] = codegen_PADDD, + [UOP_PADDSB & UOP_MASK] = codegen_PADDSB, + [UOP_PADDSW & UOP_MASK] = codegen_PADDSW, + [UOP_PADDUSB & UOP_MASK] = codegen_PADDUSB, + [UOP_PADDUSW & UOP_MASK] = codegen_PADDUSW, - [UOP_PCMPEQB & UOP_MASK] = codegen_PCMPEQB, - [UOP_PCMPEQW & UOP_MASK] = codegen_PCMPEQW, - [UOP_PCMPEQD & UOP_MASK] = codegen_PCMPEQD, - [UOP_PCMPGTB & UOP_MASK] = codegen_PCMPGTB, - [UOP_PCMPGTW & UOP_MASK] = codegen_PCMPGTW, - [UOP_PCMPGTD & UOP_MASK] = codegen_PCMPGTD, + [UOP_PCMPEQB & UOP_MASK] = codegen_PCMPEQB, + [UOP_PCMPEQW & UOP_MASK] = codegen_PCMPEQW, + [UOP_PCMPEQD & UOP_MASK] = codegen_PCMPEQD, + [UOP_PCMPGTB & UOP_MASK] = codegen_PCMPGTB, + [UOP_PCMPGTW & UOP_MASK] = codegen_PCMPGTW, + [UOP_PCMPGTD & UOP_MASK] = codegen_PCMPGTD, - [UOP_PF2ID & UOP_MASK] = codegen_PF2ID, - [UOP_PFADD & UOP_MASK] = codegen_PFADD, - [UOP_PFCMPEQ & UOP_MASK] = codegen_PFCMPEQ, - [UOP_PFCMPGE & UOP_MASK] = codegen_PFCMPGE, - [UOP_PFCMPGT & UOP_MASK] = codegen_PFCMPGT, - [UOP_PFMAX & UOP_MASK] = codegen_PFMAX, - [UOP_PFMIN & UOP_MASK] = codegen_PFMIN, - [UOP_PFMUL & UOP_MASK] = codegen_PFMUL, - [UOP_PFRCP & UOP_MASK] = codegen_PFRCP, - [UOP_PFRSQRT & UOP_MASK] = codegen_PFRSQRT, - [UOP_PFSUB & UOP_MASK] = codegen_PFSUB, - [UOP_PI2FD & UOP_MASK] = codegen_PI2FD, + [UOP_PF2ID & UOP_MASK] = codegen_PF2ID, + [UOP_PFADD & UOP_MASK] = codegen_PFADD, + [UOP_PFCMPEQ & UOP_MASK] = codegen_PFCMPEQ, + [UOP_PFCMPGE & UOP_MASK] = codegen_PFCMPGE, + [UOP_PFCMPGT & UOP_MASK] = codegen_PFCMPGT, + [UOP_PFMAX & UOP_MASK] = codegen_PFMAX, + [UOP_PFMIN & UOP_MASK] = codegen_PFMIN, + [UOP_PFMUL & UOP_MASK] = codegen_PFMUL, + [UOP_PFRCP & UOP_MASK] = codegen_PFRCP, + [UOP_PFRSQRT & UOP_MASK] = codegen_PFRSQRT, + [UOP_PFSUB & UOP_MASK] = codegen_PFSUB, + [UOP_PI2FD & UOP_MASK] = codegen_PI2FD, - [UOP_PMADDWD & UOP_MASK] = codegen_PMADDWD, - [UOP_PMULHW & UOP_MASK] = codegen_PMULHW, - [UOP_PMULLW & UOP_MASK] = codegen_PMULLW, + [UOP_PMADDWD & UOP_MASK] = codegen_PMADDWD, + [UOP_PMULHW & UOP_MASK] = codegen_PMULHW, + [UOP_PMULLW & UOP_MASK] = codegen_PMULLW, - [UOP_PSLLW_IMM & UOP_MASK] = codegen_PSLLW_IMM, - [UOP_PSLLD_IMM & UOP_MASK] = codegen_PSLLD_IMM, - [UOP_PSLLQ_IMM & UOP_MASK] = codegen_PSLLQ_IMM, - [UOP_PSRAW_IMM & UOP_MASK] = codegen_PSRAW_IMM, - [UOP_PSRAD_IMM & UOP_MASK] = codegen_PSRAD_IMM, - [UOP_PSRAQ_IMM & UOP_MASK] = codegen_PSRAQ_IMM, - [UOP_PSRLW_IMM & UOP_MASK] = codegen_PSRLW_IMM, - [UOP_PSRLD_IMM & UOP_MASK] = codegen_PSRLD_IMM, - [UOP_PSRLQ_IMM & UOP_MASK] = codegen_PSRLQ_IMM, + [UOP_PSLLW_IMM & UOP_MASK] = codegen_PSLLW_IMM, + [UOP_PSLLD_IMM & UOP_MASK] = codegen_PSLLD_IMM, + [UOP_PSLLQ_IMM & UOP_MASK] = codegen_PSLLQ_IMM, + [UOP_PSRAW_IMM & UOP_MASK] = codegen_PSRAW_IMM, + [UOP_PSRAD_IMM & UOP_MASK] = codegen_PSRAD_IMM, + [UOP_PSRAQ_IMM & UOP_MASK] = codegen_PSRAQ_IMM, + [UOP_PSRLW_IMM & UOP_MASK] = codegen_PSRLW_IMM, + [UOP_PSRLD_IMM & UOP_MASK] = codegen_PSRLD_IMM, + [UOP_PSRLQ_IMM & UOP_MASK] = codegen_PSRLQ_IMM, - [UOP_PSUBB & UOP_MASK] = codegen_PSUBB, - [UOP_PSUBW & UOP_MASK] = codegen_PSUBW, - [UOP_PSUBD & UOP_MASK] = codegen_PSUBD, - [UOP_PSUBSB & UOP_MASK] = codegen_PSUBSB, - [UOP_PSUBSW & UOP_MASK] = codegen_PSUBSW, - [UOP_PSUBUSB & UOP_MASK] = codegen_PSUBUSB, - [UOP_PSUBUSW & UOP_MASK] = codegen_PSUBUSW, + [UOP_PSUBB & UOP_MASK] = codegen_PSUBB, + [UOP_PSUBW & UOP_MASK] = codegen_PSUBW, + [UOP_PSUBD & UOP_MASK] = codegen_PSUBD, + [UOP_PSUBSB & UOP_MASK] = codegen_PSUBSB, + [UOP_PSUBSW & UOP_MASK] = codegen_PSUBSW, + [UOP_PSUBUSB & UOP_MASK] = codegen_PSUBUSB, + [UOP_PSUBUSW & UOP_MASK] = codegen_PSUBUSW, - [UOP_PUNPCKHBW & UOP_MASK] = codegen_PUNPCKHBW, - [UOP_PUNPCKHWD & UOP_MASK] = codegen_PUNPCKHWD, - [UOP_PUNPCKHDQ & UOP_MASK] = codegen_PUNPCKHDQ, - [UOP_PUNPCKLBW & UOP_MASK] = codegen_PUNPCKLBW, - [UOP_PUNPCKLWD & UOP_MASK] = codegen_PUNPCKLWD, - [UOP_PUNPCKLDQ & UOP_MASK] = codegen_PUNPCKLDQ, + [UOP_PUNPCKHBW & UOP_MASK] = codegen_PUNPCKHBW, + [UOP_PUNPCKHWD & UOP_MASK] = codegen_PUNPCKHWD, + [UOP_PUNPCKHDQ & UOP_MASK] = codegen_PUNPCKHDQ, + [UOP_PUNPCKLBW & UOP_MASK] = codegen_PUNPCKLBW, + [UOP_PUNPCKLWD & UOP_MASK] = codegen_PUNPCKLWD, + [UOP_PUNPCKLDQ & UOP_MASK] = codegen_PUNPCKLDQ, - [UOP_NOP_BARRIER & UOP_MASK] = codegen_NOP - }; + [UOP_NOP_BARRIER & UOP_MASK] = codegen_NOP}; -void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p) { - host_x86_MOV8_REG_ABS(block, host_reg, p); -} -void codegen_direct_read_16(codeblock_t *block, int host_reg, void *p) { - host_x86_MOV16_REG_ABS(block, host_reg, p); -} -void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) { - host_x86_MOV32_REG_ABS(block, host_reg, p); -} -void codegen_direct_read_64(codeblock_t *block, int host_reg, void *p) { - host_x86_MOVQ_XREG_ABS(block, host_reg, p); -} -void codegen_direct_read_pointer(codeblock_t *block, int host_reg, void *p) { - host_x86_MOV64_REG_ABS(block, host_reg, p); -} -void codegen_direct_read_double(codeblock_t *block, int host_reg, void *p) { - host_x86_MOVQ_XREG_ABS(block, host_reg, p); -} +void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p) { host_x86_MOV8_REG_ABS(block, host_reg, p); } +void codegen_direct_read_16(codeblock_t *block, int host_reg, void *p) { host_x86_MOV16_REG_ABS(block, host_reg, p); } +void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) { host_x86_MOV32_REG_ABS(block, host_reg, p); } +void codegen_direct_read_64(codeblock_t *block, int host_reg, void *p) { host_x86_MOVQ_XREG_ABS(block, host_reg, p); } +void codegen_direct_read_pointer(codeblock_t *block, int host_reg, void *p) { host_x86_MOV64_REG_ABS(block, host_reg, p); } +void codegen_direct_read_double(codeblock_t *block, int host_reg, void *p) { host_x86_MOVQ_XREG_ABS(block, host_reg, p); } void codegen_direct_read_st_8(codeblock_t *block, int host_reg, void *base, int reg_idx) { - int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); - host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_RSP, IREG_TOP_diff_stack_offset); - host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); - host_x86_AND32_REG_IMM(block, REG_ECX, 7); - host_x86_MOV8_REG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_RBP, REG_ECX, 0); + host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_RSP, IREG_TOP_diff_stack_offset); + host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, 7); + host_x86_MOV8_REG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_RBP, REG_ECX, 0); } void codegen_direct_read_st_64(codeblock_t *block, int host_reg, void *base, int reg_idx) { - int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); - host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_RSP, IREG_TOP_diff_stack_offset); - host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); - host_x86_AND32_REG_IMM(block, REG_ECX, 7); - host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_RBP, REG_ECX, 3); + host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_RSP, IREG_TOP_diff_stack_offset); + host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, 7); + host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_RBP, REG_ECX, 3); } void codegen_direct_read_st_double(codeblock_t *block, int host_reg, void *base, int reg_idx) { - int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); - host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_RSP, IREG_TOP_diff_stack_offset); - host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); - host_x86_AND32_REG_IMM(block, REG_ECX, 7); - host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_RBP, REG_ECX, 3); + host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_RSP, IREG_TOP_diff_stack_offset); + host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, 7); + host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_RBP, REG_ECX, 3); } -void codegen_direct_write_8(codeblock_t *block, void *p, int host_reg) { - host_x86_MOV8_ABS_REG(block, p, host_reg); -} -void codegen_direct_write_16(codeblock_t *block, void *p, int host_reg) { - host_x86_MOV16_ABS_REG(block, p, host_reg); -} -void codegen_direct_write_32(codeblock_t *block, void *p, int host_reg) { - host_x86_MOV32_ABS_REG(block, p, host_reg); -} -void codegen_direct_write_64(codeblock_t *block, void *p, int host_reg) { - host_x86_MOVQ_ABS_XREG(block, p, host_reg); -} -void codegen_direct_write_pointer(codeblock_t *block, void *p, int host_reg) { - host_x86_MOV64_ABS_REG(block, p, host_reg); -} -void codegen_direct_write_double(codeblock_t *block, void *p, int host_reg) { - host_x86_MOVQ_ABS_XREG(block, p, host_reg); -} +void codegen_direct_write_8(codeblock_t *block, void *p, int host_reg) { host_x86_MOV8_ABS_REG(block, p, host_reg); } +void codegen_direct_write_16(codeblock_t *block, void *p, int host_reg) { host_x86_MOV16_ABS_REG(block, p, host_reg); } +void codegen_direct_write_32(codeblock_t *block, void *p, int host_reg) { host_x86_MOV32_ABS_REG(block, p, host_reg); } +void codegen_direct_write_64(codeblock_t *block, void *p, int host_reg) { host_x86_MOVQ_ABS_XREG(block, p, host_reg); } +void codegen_direct_write_pointer(codeblock_t *block, void *p, int host_reg) { host_x86_MOV64_ABS_REG(block, p, host_reg); } +void codegen_direct_write_double(codeblock_t *block, void *p, int host_reg) { host_x86_MOVQ_ABS_XREG(block, p, host_reg); } void codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int host_reg) { - int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); - host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_RSP, IREG_TOP_diff_stack_offset); - host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); - host_x86_AND32_REG_IMM(block, REG_ECX, 7); - host_x86_MOV8_ABS_REG_REG_SHIFT_REG(block, offset, REG_RBP, REG_ECX, 0, host_reg); + host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_RSP, IREG_TOP_diff_stack_offset); + host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, 7); + host_x86_MOV8_ABS_REG_REG_SHIFT_REG(block, offset, REG_RBP, REG_ECX, 0, host_reg); } void codegen_direct_write_st_64(codeblock_t *block, void *base, int reg_idx, int host_reg) { - int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); - host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_RSP, IREG_TOP_diff_stack_offset); - host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); - host_x86_AND32_REG_IMM(block, REG_ECX, 7); - host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(block, offset, REG_RBP, REG_ECX, 3, host_reg); + host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_RSP, IREG_TOP_diff_stack_offset); + host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, 7); + host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(block, offset, REG_RBP, REG_ECX, 3, host_reg); } void codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx, int host_reg) { - int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); - host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_RSP, IREG_TOP_diff_stack_offset); - host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); - host_x86_AND32_REG_IMM(block, REG_ECX, 7); - host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(block, offset, REG_RBP, REG_ECX, 3, host_reg); + host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_RSP, IREG_TOP_diff_stack_offset); + host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, 7); + host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(block, offset, REG_RBP, REG_ECX, 3, host_reg); } -void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg) { - host_x86_MOV64_ABS_REG(block, p, host_reg); -} +void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg) { host_x86_MOV64_ABS_REG(block, p, host_reg); } void codegen_direct_read_16_stack(codeblock_t *block, int host_reg, int stack_offset) { - host_x86_MOV16_REG_BASE_OFFSET(block, host_reg, REG_ESP, stack_offset); + host_x86_MOV16_REG_BASE_OFFSET(block, host_reg, REG_ESP, stack_offset); } void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_offset) { - host_x86_MOV32_REG_BASE_OFFSET(block, host_reg, REG_RSP, stack_offset); + host_x86_MOV32_REG_BASE_OFFSET(block, host_reg, REG_RSP, stack_offset); } void codegen_direct_read_64_stack(codeblock_t *block, int host_reg, int stack_offset) { - host_x86_MOVQ_XREG_BASE_OFFSET(block, host_reg, REG_RSP, stack_offset); + host_x86_MOVQ_XREG_BASE_OFFSET(block, host_reg, REG_RSP, stack_offset); } void codegen_direct_read_pointer_stack(codeblock_t *block, int host_reg, int stack_offset) { - host_x86_MOV64_REG_BASE_OFFSET(block, host_reg, REG_RSP, stack_offset); + host_x86_MOV64_REG_BASE_OFFSET(block, host_reg, REG_RSP, stack_offset); } void codegen_direct_read_double_stack(codeblock_t *block, int host_reg, int stack_offset) { - host_x86_MOVQ_XREG_BASE_OFFSET(block, host_reg, REG_RSP, stack_offset); + host_x86_MOVQ_XREG_BASE_OFFSET(block, host_reg, REG_RSP, stack_offset); } void codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int host_reg) { - host_x86_MOV32_BASE_OFFSET_REG(block, REG_RSP, stack_offset, host_reg); + host_x86_MOV32_BASE_OFFSET_REG(block, REG_RSP, stack_offset, host_reg); } void codegen_direct_write_64_stack(codeblock_t *block, int stack_offset, int host_reg) { - host_x86_MOVQ_BASE_OFFSET_XREG(block, REG_RSP, stack_offset, host_reg); + host_x86_MOVQ_BASE_OFFSET_XREG(block, REG_RSP, stack_offset, host_reg); } void codegen_direct_write_pointer_stack(codeblock_t *block, int stack_offset, int host_reg) { - host_x86_MOV64_BASE_OFFSET_REG(block, REG_RSP, stack_offset, host_reg); + host_x86_MOV64_BASE_OFFSET_REG(block, REG_RSP, stack_offset, host_reg); } void codegen_direct_write_double_stack(codeblock_t *block, int stack_offset, int host_reg) { - host_x86_MOVQ_BASE_OFFSET_XREG(block, REG_RSP, stack_offset, host_reg); + host_x86_MOVQ_BASE_OFFSET_XREG(block, REG_RSP, stack_offset, host_reg); } void codegen_set_jump_dest(codeblock_t *block, void *p) { - *(uint32_t *)p = (uintptr_t)&block_write_data[block_pos] - ((uintptr_t)p + 4); + *(uint32_t *)p = (uintptr_t)&block_write_data[block_pos] - ((uintptr_t)p + 4); } -void codegen_direct_write_8_imm(codeblock_t *block, void *p, uint8_t imm_data) { - host_x86_MOV8_ABS_IMM(block, p, imm_data); -} -void codegen_direct_write_16_imm(codeblock_t *block, void *p, uint16_t imm_data) { - host_x86_MOV16_ABS_IMM(block, p, imm_data); -} -void codegen_direct_write_32_imm(codeblock_t *block, void *p, uint32_t imm_data) { - host_x86_MOV32_ABS_IMM(block, p, imm_data); -} +void codegen_direct_write_8_imm(codeblock_t *block, void *p, uint8_t imm_data) { host_x86_MOV8_ABS_IMM(block, p, imm_data); } +void codegen_direct_write_16_imm(codeblock_t *block, void *p, uint16_t imm_data) { host_x86_MOV16_ABS_IMM(block, p, imm_data); } +void codegen_direct_write_32_imm(codeblock_t *block, void *p, uint32_t imm_data) { host_x86_MOV32_ABS_IMM(block, p, imm_data); } void codegen_direct_write_32_imm_stack(codeblock_t *block, int stack_offset, uint32_t imm_data) { - host_x86_MOV32_BASE_OFFSET_IMM(block, REG_ESP, stack_offset, imm_data); + host_x86_MOV32_BASE_OFFSET_IMM(block, REG_ESP, stack_offset, imm_data); } #endif diff --git a/src/codegen/x86/codegen_backend_x86.c b/src/codegen/x86/codegen_backend_x86.c index 9bfb0cf5..c13f29c5 100644 --- a/src/codegen/x86/codegen_backend_x86.c +++ b/src/codegen/x86/codegen_backend_x86.c @@ -36,320 +36,309 @@ void *codegen_mem_store_double; void *codegen_gpf_rout; void *codegen_exit_rout; -host_reg_def_t codegen_host_reg_list[CODEGEN_HOST_REGS] = - { - /*Note: while EAX and EDX are normally volatile registers under x86 - calling conventions, the recompiler will explicitly save and restore - them across funcion calls*/ - {REG_EAX, 0}, - {REG_EBX, 0}, - {REG_EDX, 0} - }; +host_reg_def_t codegen_host_reg_list[CODEGEN_HOST_REGS] = { + /*Note: while EAX and EDX are normally volatile registers under x86 + calling conventions, the recompiler will explicitly save and restore + them across funcion calls*/ + {REG_EAX, 0}, + {REG_EBX, 0}, + {REG_EDX, 0}}; -host_reg_def_t codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] = - { - {REG_XMM0, HOST_REG_FLAG_VOLATILE}, - {REG_XMM1, HOST_REG_FLAG_VOLATILE}, - {REG_XMM2, HOST_REG_FLAG_VOLATILE}, - {REG_XMM3, HOST_REG_FLAG_VOLATILE}, - {REG_XMM4, HOST_REG_FLAG_VOLATILE}, - {REG_XMM5, HOST_REG_FLAG_VOLATILE} - }; +host_reg_def_t codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] = { + {REG_XMM0, HOST_REG_FLAG_VOLATILE}, {REG_XMM1, HOST_REG_FLAG_VOLATILE}, {REG_XMM2, HOST_REG_FLAG_VOLATILE}, + {REG_XMM3, HOST_REG_FLAG_VOLATILE}, {REG_XMM4, HOST_REG_FLAG_VOLATILE}, {REG_XMM5, HOST_REG_FLAG_VOLATILE}}; static void build_load_routine(codeblock_t *block, int size, int is_float) { - uint8_t *branch_offset; - uint8_t *misaligned_offset = NULL; + uint8_t *branch_offset; + uint8_t *misaligned_offset = NULL; - /*In - ESI = address - Out - ECX = data, ESI = abrt*/ - /*MOV ECX, ESI - SHR ESI, 12 - MOV ESI, [readlookup2+ESI*4] - CMP ESI, -1 - JNZ + - MOVZX ECX, B[ESI+ECX] - XOR ESI,ESI - RET - * PUSH EAX - PUSH EDX - PUSH ECX - CALL readmembl - POP ECX - POP EDX - POP EAX - MOVZX ECX, AL - RET - */ - host_x86_MOV32_REG_REG(block, REG_ECX, REG_ESI); - host_x86_SHR32_IMM(block, REG_ESI, 12); - host_x86_MOV32_REG_ABS_INDEX_SHIFT(block, REG_ESI, readlookup2, REG_ESI, 2); - if (size != 1) { - host_x86_TEST32_REG_IMM(block, REG_ECX, size - 1); - misaligned_offset = host_x86_JNZ_short(block); - } - host_x86_CMP32_REG_IMM(block, REG_ESI, (uint32_t)-1); - branch_offset = host_x86_JZ_short(block); - if (size == 1 && !is_float) - host_x86_MOVZX_BASE_INDEX_32_8(block, REG_ECX, REG_ESI, REG_ECX); - else if (size == 2 && !is_float) - host_x86_MOVZX_BASE_INDEX_32_16(block, REG_ECX, REG_ESI, REG_ECX); - else if (size == 4 && !is_float) - host_x86_MOV32_REG_BASE_INDEX(block, REG_ECX, REG_ESI, REG_ECX); - else if (size == 4 && is_float) - host_x86_CVTSS2SD_XREG_BASE_INDEX(block, REG_XMM_TEMP, REG_ESI, REG_ECX); - else if (size == 8) - host_x86_MOVQ_XREG_BASE_INDEX(block, REG_XMM_TEMP, REG_ESI, REG_ECX); - else - fatal("build_load_routine: size=%i\n", size); - host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI); - host_x86_RET(block); + /*In - ESI = address + Out - ECX = data, ESI = abrt*/ + /*MOV ECX, ESI + SHR ESI, 12 + MOV ESI, [readlookup2+ESI*4] + CMP ESI, -1 + JNZ + + MOVZX ECX, B[ESI+ECX] + XOR ESI,ESI + RET + * PUSH EAX + PUSH EDX + PUSH ECX + CALL readmembl + POP ECX + POP EDX + POP EAX + MOVZX ECX, AL + RET + */ + host_x86_MOV32_REG_REG(block, REG_ECX, REG_ESI); + host_x86_SHR32_IMM(block, REG_ESI, 12); + host_x86_MOV32_REG_ABS_INDEX_SHIFT(block, REG_ESI, readlookup2, REG_ESI, 2); + if (size != 1) { + host_x86_TEST32_REG_IMM(block, REG_ECX, size - 1); + misaligned_offset = host_x86_JNZ_short(block); + } + host_x86_CMP32_REG_IMM(block, REG_ESI, (uint32_t)-1); + branch_offset = host_x86_JZ_short(block); + if (size == 1 && !is_float) + host_x86_MOVZX_BASE_INDEX_32_8(block, REG_ECX, REG_ESI, REG_ECX); + else if (size == 2 && !is_float) + host_x86_MOVZX_BASE_INDEX_32_16(block, REG_ECX, REG_ESI, REG_ECX); + else if (size == 4 && !is_float) + host_x86_MOV32_REG_BASE_INDEX(block, REG_ECX, REG_ESI, REG_ECX); + else if (size == 4 && is_float) + host_x86_CVTSS2SD_XREG_BASE_INDEX(block, REG_XMM_TEMP, REG_ESI, REG_ECX); + else if (size == 8) + host_x86_MOVQ_XREG_BASE_INDEX(block, REG_XMM_TEMP, REG_ESI, REG_ECX); + else + fatal("build_load_routine: size=%i\n", size); + host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI); + host_x86_RET(block); - *branch_offset = (uint8_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 1; - if (size != 1) - *misaligned_offset = (uint8_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)misaligned_offset) - 1; - host_x86_PUSH(block, REG_EAX); - host_x86_PUSH(block, REG_EDX); - host_x86_PUSH(block, REG_ECX); - if (size == 1) - host_x86_CALL(block, (void *)readmembl); - else if (size == 2) - host_x86_CALL(block, (void *)readmemwl); - else if (size == 4) - host_x86_CALL(block, (void *)readmemll); - else if (size == 8) - host_x86_CALL(block, (void *)readmemql); - host_x86_POP(block, REG_ECX); - if (size == 1 && !is_float) - host_x86_MOVZX_REG_32_8(block, REG_ECX, REG_EAX); - else if (size == 2 && !is_float) - host_x86_MOVZX_REG_32_16(block, REG_ECX, REG_EAX); - else if (size == 4 && !is_float) - host_x86_MOV32_REG_REG(block, REG_ECX, REG_EAX); - else if (size == 4 && is_float) { - host_x86_MOVD_XREG_REG(block, REG_XMM_TEMP, REG_EAX); - host_x86_CVTSS2SD_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP); - } else if (size == 8) { - host_x86_MOVD_XREG_REG(block, REG_XMM_TEMP, REG_EAX); - host_x86_MOVD_XREG_REG(block, REG_XMM_TEMP2, REG_EDX); - host_x86_UNPCKLPS_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP2); - } - host_x86_POP(block, REG_EDX); - host_x86_POP(block, REG_EAX); - host_x86_MOVZX_REG_ABS_32_8(block, REG_ESI, &cpu_state.abrt); - host_x86_RET(block); - block_pos = (block_pos + 63) & ~63; + *branch_offset = (uint8_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 1; + if (size != 1) + *misaligned_offset = (uint8_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)misaligned_offset) - 1; + host_x86_PUSH(block, REG_EAX); + host_x86_PUSH(block, REG_EDX); + host_x86_PUSH(block, REG_ECX); + if (size == 1) + host_x86_CALL(block, (void *)readmembl); + else if (size == 2) + host_x86_CALL(block, (void *)readmemwl); + else if (size == 4) + host_x86_CALL(block, (void *)readmemll); + else if (size == 8) + host_x86_CALL(block, (void *)readmemql); + host_x86_POP(block, REG_ECX); + if (size == 1 && !is_float) + host_x86_MOVZX_REG_32_8(block, REG_ECX, REG_EAX); + else if (size == 2 && !is_float) + host_x86_MOVZX_REG_32_16(block, REG_ECX, REG_EAX); + else if (size == 4 && !is_float) + host_x86_MOV32_REG_REG(block, REG_ECX, REG_EAX); + else if (size == 4 && is_float) { + host_x86_MOVD_XREG_REG(block, REG_XMM_TEMP, REG_EAX); + host_x86_CVTSS2SD_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP); + } else if (size == 8) { + host_x86_MOVD_XREG_REG(block, REG_XMM_TEMP, REG_EAX); + host_x86_MOVD_XREG_REG(block, REG_XMM_TEMP2, REG_EDX); + host_x86_UNPCKLPS_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP2); + } + host_x86_POP(block, REG_EDX); + host_x86_POP(block, REG_EAX); + host_x86_MOVZX_REG_ABS_32_8(block, REG_ESI, &cpu_state.abrt); + host_x86_RET(block); + block_pos = (block_pos + 63) & ~63; } static void build_store_routine(codeblock_t *block, int size, int is_float) { - uint8_t *branch_offset; - uint8_t *misaligned_offset = NULL; + uint8_t *branch_offset; + uint8_t *misaligned_offset = NULL; - /*In - ECX = data, ESI = address - Out - ESI = abrt - Corrupts EDI*/ - /*MOV EDI, ESI - SHR ESI, 12 - MOV ESI, [writelookup2+ESI*4] - CMP ESI, -1 - JNZ + - MOV [ESI+EDI], ECX - XOR ESI,ESI - RET - * PUSH EAX - PUSH EDX - PUSH ECX - CALL writemembl - POP ECX - POP EDX - POP EAX - MOVZX ECX, AL - RET - */ - host_x86_MOV32_REG_REG(block, REG_EDI, REG_ESI); - host_x86_SHR32_IMM(block, REG_ESI, 12); - host_x86_MOV32_REG_ABS_INDEX_SHIFT(block, REG_ESI, writelookup2, REG_ESI, 2); - if (size != 1) { - host_x86_TEST32_REG_IMM(block, REG_EDI, size - 1); - misaligned_offset = host_x86_JNZ_short(block); - } - host_x86_CMP32_REG_IMM(block, REG_ESI, (uint32_t)-1); - branch_offset = host_x86_JZ_short(block); - if (size == 1 && !is_float) - host_x86_MOV8_BASE_INDEX_REG(block, REG_ESI, REG_EDI, REG_ECX); - else if (size == 2 && !is_float) - host_x86_MOV16_BASE_INDEX_REG(block, REG_ESI, REG_EDI, REG_ECX); - else if (size == 4 && !is_float) - host_x86_MOV32_BASE_INDEX_REG(block, REG_ESI, REG_EDI, REG_ECX); - else if (size == 4 && is_float) - host_x86_MOVD_BASE_INDEX_XREG(block, REG_ESI, REG_EDI, REG_XMM_TEMP); - else if (size == 8) - host_x86_MOVQ_BASE_INDEX_XREG(block, REG_ESI, REG_EDI, REG_XMM_TEMP); - else - fatal("build_store_routine: size=%i is_float=%i\n", size, is_float); - host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI); - host_x86_RET(block); + /*In - ECX = data, ESI = address + Out - ESI = abrt + Corrupts EDI*/ + /*MOV EDI, ESI + SHR ESI, 12 + MOV ESI, [writelookup2+ESI*4] + CMP ESI, -1 + JNZ + + MOV [ESI+EDI], ECX + XOR ESI,ESI + RET + * PUSH EAX + PUSH EDX + PUSH ECX + CALL writemembl + POP ECX + POP EDX + POP EAX + MOVZX ECX, AL + RET + */ + host_x86_MOV32_REG_REG(block, REG_EDI, REG_ESI); + host_x86_SHR32_IMM(block, REG_ESI, 12); + host_x86_MOV32_REG_ABS_INDEX_SHIFT(block, REG_ESI, writelookup2, REG_ESI, 2); + if (size != 1) { + host_x86_TEST32_REG_IMM(block, REG_EDI, size - 1); + misaligned_offset = host_x86_JNZ_short(block); + } + host_x86_CMP32_REG_IMM(block, REG_ESI, (uint32_t)-1); + branch_offset = host_x86_JZ_short(block); + if (size == 1 && !is_float) + host_x86_MOV8_BASE_INDEX_REG(block, REG_ESI, REG_EDI, REG_ECX); + else if (size == 2 && !is_float) + host_x86_MOV16_BASE_INDEX_REG(block, REG_ESI, REG_EDI, REG_ECX); + else if (size == 4 && !is_float) + host_x86_MOV32_BASE_INDEX_REG(block, REG_ESI, REG_EDI, REG_ECX); + else if (size == 4 && is_float) + host_x86_MOVD_BASE_INDEX_XREG(block, REG_ESI, REG_EDI, REG_XMM_TEMP); + else if (size == 8) + host_x86_MOVQ_BASE_INDEX_XREG(block, REG_ESI, REG_EDI, REG_XMM_TEMP); + else + fatal("build_store_routine: size=%i is_float=%i\n", size, is_float); + host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI); + host_x86_RET(block); - *branch_offset = (uint8_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 1; - if (size != 1) - *misaligned_offset = (uint8_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)misaligned_offset) - 1; - if (size == 4 && is_float) - host_x86_MOVD_REG_XREG(block, REG_ECX, REG_XMM_TEMP); - host_x86_PUSH(block, REG_EAX); - host_x86_PUSH(block, REG_EDX); - host_x86_PUSH(block, REG_ECX); - if (size == 8) { - host_x86_MOVQ_STACK_OFFSET_XREG(block, -8, REG_XMM_TEMP); - host_x86_SUB32_REG_IMM(block, REG_ESP, 8); - } - host_x86_PUSH(block, REG_EDI); - if (size == 1) - host_x86_CALL(block, (void *)writemembl); - else if (size == 2) - host_x86_CALL(block, (void *)writememwl); - else if (size == 4) - host_x86_CALL(block, (void *)writememll); - else if (size == 8) - host_x86_CALL(block, (void *)writememql); - host_x86_POP(block, REG_EDI); - if (size == 8) - host_x86_ADD32_REG_IMM(block, REG_ESP, 8); - host_x86_POP(block, REG_ECX); - host_x86_POP(block, REG_EDX); - host_x86_POP(block, REG_EAX); - host_x86_MOVZX_REG_ABS_32_8(block, REG_ESI, &cpu_state.abrt); - host_x86_RET(block); - block_pos = (block_pos + 63) & ~63; + *branch_offset = (uint8_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 1; + if (size != 1) + *misaligned_offset = (uint8_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)misaligned_offset) - 1; + if (size == 4 && is_float) + host_x86_MOVD_REG_XREG(block, REG_ECX, REG_XMM_TEMP); + host_x86_PUSH(block, REG_EAX); + host_x86_PUSH(block, REG_EDX); + host_x86_PUSH(block, REG_ECX); + if (size == 8) { + host_x86_MOVQ_STACK_OFFSET_XREG(block, -8, REG_XMM_TEMP); + host_x86_SUB32_REG_IMM(block, REG_ESP, 8); + } + host_x86_PUSH(block, REG_EDI); + if (size == 1) + host_x86_CALL(block, (void *)writemembl); + else if (size == 2) + host_x86_CALL(block, (void *)writememwl); + else if (size == 4) + host_x86_CALL(block, (void *)writememll); + else if (size == 8) + host_x86_CALL(block, (void *)writememql); + host_x86_POP(block, REG_EDI); + if (size == 8) + host_x86_ADD32_REG_IMM(block, REG_ESP, 8); + host_x86_POP(block, REG_ECX); + host_x86_POP(block, REG_EDX); + host_x86_POP(block, REG_EAX); + host_x86_MOVZX_REG_ABS_32_8(block, REG_ESI, &cpu_state.abrt); + host_x86_RET(block); + block_pos = (block_pos + 63) & ~63; } static void build_loadstore_routines(codeblock_t *block) { - codegen_mem_load_byte = &codeblock[block_current].data[block_pos]; - build_load_routine(block, 1, 0); - codegen_mem_load_word = &codeblock[block_current].data[block_pos]; - build_load_routine(block, 2, 0); - codegen_mem_load_long = &codeblock[block_current].data[block_pos]; - build_load_routine(block, 4, 0); - codegen_mem_load_quad = &codeblock[block_current].data[block_pos]; - build_load_routine(block, 8, 0); - codegen_mem_load_single = &codeblock[block_current].data[block_pos]; - build_load_routine(block, 4, 1); - codegen_mem_load_double = &codeblock[block_current].data[block_pos]; - build_load_routine(block, 8, 1); + codegen_mem_load_byte = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 1, 0); + codegen_mem_load_word = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 2, 0); + codegen_mem_load_long = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 4, 0); + codegen_mem_load_quad = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 8, 0); + codegen_mem_load_single = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 4, 1); + codegen_mem_load_double = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 8, 1); - codegen_mem_store_byte = &codeblock[block_current].data[block_pos]; - build_store_routine(block, 1, 0); - codegen_mem_store_word = &codeblock[block_current].data[block_pos]; - build_store_routine(block, 2, 0); - codegen_mem_store_long = &codeblock[block_current].data[block_pos]; - build_store_routine(block, 4, 0); - codegen_mem_store_quad = &codeblock[block_current].data[block_pos]; - build_store_routine(block, 8, 0); - codegen_mem_store_single = &codeblock[block_current].data[block_pos]; - build_store_routine(block, 4, 1); - codegen_mem_store_double = &codeblock[block_current].data[block_pos]; - build_store_routine(block, 8, 1); + codegen_mem_store_byte = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 1, 0); + codegen_mem_store_word = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 2, 0); + codegen_mem_store_long = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 4, 0); + codegen_mem_store_quad = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 8, 0); + codegen_mem_store_single = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 4, 1); + codegen_mem_store_double = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 8, 1); } void codegen_backend_init() { - codeblock_t *block; - int c; + codeblock_t *block; + int c; #if defined(__linux__) || defined(__APPLE__) - void *start; - size_t len; - long pagesize = sysconf(_SC_PAGESIZE); - long pagemask = ~(pagesize - 1); + void *start; + size_t len; + long pagesize = sysconf(_SC_PAGESIZE); + long pagemask = ~(pagesize - 1); #endif - pclog("sizeof(codeblock_t)=%i\n", sizeof(codeblock_t)); - pclog(" offsetof(codeblock_t, pc)=%i\n", offsetof(codeblock_t, pc)); - pclog(" offsetof(codeblock_t, _cs)=%i\n", offsetof(codeblock_t, _cs)); - pclog(" offsetof(codeblock_t, phys)=%i\n", offsetof(codeblock_t, phys)); - pclog(" offsetof(codeblock_t, phys_2)=%i\n", offsetof(codeblock_t, phys_2)); - pclog(" offsetof(codeblock_t, status)=%i\n", offsetof(codeblock_t, status)); - pclog(" offsetof(codeblock_t, flags)=%i\n", offsetof(codeblock_t, flags)); - pclog(" offsetof(codeblock_t, ins)=%i\n", offsetof(codeblock_t, ins)); - pclog(" offsetof(codeblock_t, TOP)=%i\n", offsetof(codeblock_t, TOP)); - pclog(" offsetof(codeblock_t, parent)=%i\n", offsetof(codeblock_t, parent)); - pclog(" offsetof(codeblock_t, left)=%i\n", offsetof(codeblock_t, left)); - pclog(" offsetof(codeblock_t, right)=%i\n", offsetof(codeblock_t, right)); - pclog(" offsetof(codeblock_t, data)=%i\n", offsetof(codeblock_t, data)); - pclog(" offsetof(codeblock_t, page_mask)=%i\n", offsetof(codeblock_t, page_mask)); - pclog(" offsetof(codeblock_t, page_mask2)=%i\n", offsetof(codeblock_t, page_mask2)); - pclog(" offsetof(codeblock_t, dirty_mask)=%i\n", offsetof(codeblock_t, dirty_mask)); - pclog(" offsetof(codeblock_t, dirty_mask2)=%i\n", offsetof(codeblock_t, dirty_mask2)); - pclog(" offsetof(codeblock_t, prev)=%i\n", offsetof(codeblock_t, prev)); - pclog(" offsetof(codeblock_t, next)=%i\n", offsetof(codeblock_t, next)); - pclog(" offsetof(codeblock_t, prev_2)=%i\n", offsetof(codeblock_t, prev_2)); - pclog(" offsetof(codeblock_t, next_2)=%i\n", offsetof(codeblock_t, next_2)); - codeblock = malloc(BLOCK_SIZE * sizeof(codeblock_t)); - codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); + pclog("sizeof(codeblock_t)=%i\n", sizeof(codeblock_t)); + pclog(" offsetof(codeblock_t, pc)=%i\n", offsetof(codeblock_t, pc)); + pclog(" offsetof(codeblock_t, _cs)=%i\n", offsetof(codeblock_t, _cs)); + pclog(" offsetof(codeblock_t, phys)=%i\n", offsetof(codeblock_t, phys)); + pclog(" offsetof(codeblock_t, phys_2)=%i\n", offsetof(codeblock_t, phys_2)); + pclog(" offsetof(codeblock_t, status)=%i\n", offsetof(codeblock_t, status)); + pclog(" offsetof(codeblock_t, flags)=%i\n", offsetof(codeblock_t, flags)); + pclog(" offsetof(codeblock_t, ins)=%i\n", offsetof(codeblock_t, ins)); + pclog(" offsetof(codeblock_t, TOP)=%i\n", offsetof(codeblock_t, TOP)); + pclog(" offsetof(codeblock_t, parent)=%i\n", offsetof(codeblock_t, parent)); + pclog(" offsetof(codeblock_t, left)=%i\n", offsetof(codeblock_t, left)); + pclog(" offsetof(codeblock_t, right)=%i\n", offsetof(codeblock_t, right)); + pclog(" offsetof(codeblock_t, data)=%i\n", offsetof(codeblock_t, data)); + pclog(" offsetof(codeblock_t, page_mask)=%i\n", offsetof(codeblock_t, page_mask)); + pclog(" offsetof(codeblock_t, page_mask2)=%i\n", offsetof(codeblock_t, page_mask2)); + pclog(" offsetof(codeblock_t, dirty_mask)=%i\n", offsetof(codeblock_t, dirty_mask)); + pclog(" offsetof(codeblock_t, dirty_mask2)=%i\n", offsetof(codeblock_t, dirty_mask2)); + pclog(" offsetof(codeblock_t, prev)=%i\n", offsetof(codeblock_t, prev)); + pclog(" offsetof(codeblock_t, next)=%i\n", offsetof(codeblock_t, next)); + pclog(" offsetof(codeblock_t, prev_2)=%i\n", offsetof(codeblock_t, prev_2)); + pclog(" offsetof(codeblock_t, next_2)=%i\n", offsetof(codeblock_t, next_2)); + codeblock = malloc(BLOCK_SIZE * sizeof(codeblock_t)); + 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 *)); + 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].pc = BLOCK_PC_INVALID; + for (c = 0; c < BLOCK_SIZE; c++) + codeblock[c].pc = BLOCK_PC_INVALID; -// pclog("Codegen is %p\n", (void *)pages[0xfab12 >> 12].block); + // pclog("Codegen is %p\n", (void *)pages[0xfab12 >> 12].block); - block_current = 0; - block_pos = 0; - block = &codeblock[block_current]; - block->head_mem_block = codegen_allocator_allocate(NULL, block_current); - block->data = codeblock_allocator_get_ptr(block->head_mem_block); - block_write_data = block->data; - build_loadstore_routines(block); + block_current = 0; + block_pos = 0; + block = &codeblock[block_current]; + block->head_mem_block = codegen_allocator_allocate(NULL, block_current); + block->data = codeblock_allocator_get_ptr(block->head_mem_block); + block_write_data = block->data; + build_loadstore_routines(block); - codegen_gpf_rout = &codeblock[block_current].data[block_pos]; - host_x86_MOV32_STACK_IMM(block, STACK_ARG0, 0); - host_x86_MOV32_STACK_IMM(block, STACK_ARG1, 0); - host_x86_CALL(block, (void *)x86gpf); - codegen_exit_rout = &codeblock[block_current].data[block_pos]; - host_x86_ADD32_REG_IMM(block, REG_ESP, 64); - host_x86_POP(block, REG_EDI); - host_x86_POP(block, REG_ESI); - host_x86_POP(block, REG_EBP); - host_x86_POP(block, REG_EDX); - host_x86_RET(block); - block_write_data = NULL; + codegen_gpf_rout = &codeblock[block_current].data[block_pos]; + host_x86_MOV32_STACK_IMM(block, STACK_ARG0, 0); + host_x86_MOV32_STACK_IMM(block, STACK_ARG1, 0); + host_x86_CALL(block, (void *)x86gpf); + codegen_exit_rout = &codeblock[block_current].data[block_pos]; + host_x86_ADD32_REG_IMM(block, REG_ESP, 64); + host_x86_POP(block, REG_EDI); + host_x86_POP(block, REG_ESI); + host_x86_POP(block, REG_EBP); + host_x86_POP(block, REG_EDX); + host_x86_RET(block); + block_write_data = NULL; - cpu_state.old_fp_control = 0; - asm( - "fstcw %0\n" - "stmxcsr %1\n" - : "=m" (cpu_state.old_fp_control2), - "=m" (cpu_state.old_fp_control) - ); - cpu_state.trunc_fp_control = cpu_state.old_fp_control | 0x6000; + cpu_state.old_fp_control = 0; + asm("fstcw %0\n" + "stmxcsr %1\n" + : "=m"(cpu_state.old_fp_control2), "=m"(cpu_state.old_fp_control)); + cpu_state.trunc_fp_control = cpu_state.old_fp_control | 0x6000; } void codegen_set_rounding_mode(int mode) { - /*SSE*/ - cpu_state.new_fp_control = (cpu_state.old_fp_control & ~0x6000) | (mode << 13); - /*x87 - used for double -> i64 conversions*/ - cpu_state.new_fp_control2 = (cpu_state.old_fp_control2 & ~0x0c00) | (mode << 10); + /*SSE*/ + cpu_state.new_fp_control = (cpu_state.old_fp_control & ~0x6000) | (mode << 13); + /*x87 - used for double -> i64 conversions*/ + cpu_state.new_fp_control2 = (cpu_state.old_fp_control2 & ~0x0c00) | (mode << 10); } void codegen_backend_prologue(codeblock_t *block) { - block_pos = BLOCK_START; /*Entry code*/ - host_x86_PUSH(block, REG_EBX); - host_x86_PUSH(block, REG_EBP); - host_x86_PUSH(block, REG_ESI); - host_x86_PUSH(block, REG_EDI); - host_x86_SUB32_REG_IMM(block, REG_ESP, 64); - host_x86_MOV32_REG_IMM(block, REG_EBP, ((uintptr_t)&cpu_state) + 128); - if (block->flags & CODEBLOCK_HAS_FPU) { - host_x86_MOV32_REG_ABS(block, REG_EAX, &cpu_state.TOP); - host_x86_SUB32_REG_IMM(block, REG_EAX, block->TOP); - host_x86_MOV32_BASE_OFFSET_REG(block, REG_ESP, IREG_TOP_diff_stack_offset, REG_EAX); - } + block_pos = BLOCK_START; /*Entry code*/ + host_x86_PUSH(block, REG_EBX); + host_x86_PUSH(block, REG_EBP); + host_x86_PUSH(block, REG_ESI); + host_x86_PUSH(block, REG_EDI); + host_x86_SUB32_REG_IMM(block, REG_ESP, 64); + host_x86_MOV32_REG_IMM(block, REG_EBP, ((uintptr_t)&cpu_state) + 128); + if (block->flags & CODEBLOCK_HAS_FPU) { + host_x86_MOV32_REG_ABS(block, REG_EAX, &cpu_state.TOP); + host_x86_SUB32_REG_IMM(block, REG_EAX, block->TOP); + host_x86_MOV32_BASE_OFFSET_REG(block, REG_ESP, IREG_TOP_diff_stack_offset, REG_EAX); + } } void codegen_backend_epilogue(codeblock_t *block) { - host_x86_ADD32_REG_IMM(block, REG_ESP, 64); - host_x86_POP(block, REG_EDI); - host_x86_POP(block, REG_ESI); - host_x86_POP(block, REG_EBP); - host_x86_POP(block, REG_EDX); - host_x86_RET(block); + host_x86_ADD32_REG_IMM(block, REG_ESP, 64); + host_x86_POP(block, REG_EDI); + host_x86_POP(block, REG_ESI); + host_x86_POP(block, REG_EBP); + host_x86_POP(block, REG_EDX); + host_x86_RET(block); } #endif diff --git a/src/codegen/x86/codegen_backend_x86_ops.c b/src/codegen/x86/codegen_backend_x86_ops.c index b5076d65..80493268 100644 --- a/src/codegen/x86/codegen_backend_x86_ops.c +++ b/src/codegen/x86/codegen_backend_x86_ops.c @@ -9,7 +9,7 @@ #include "codegen_backend_x86_ops_helpers.h" #define RM_OP_ADD 0x00 -#define RM_OP_OR 0x08 +#define RM_OP_OR 0x08 #define RM_OP_AND 0x20 #define RM_OP_SUB 0x28 #define RM_OP_XOR 0x30 @@ -22,1008 +22,1018 @@ #define RM_OP_SAR 0x38 void host_x86_ADD32_REG_ABS(codeblock_t *block, int dst_reg, void *p) { - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - if (offset >= -128 && offset < 127) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x03, 0x45 | (dst_reg << 3), offset); /*MOV offset[EBP], src_reg*/ - } else { - codegen_alloc_bytes(block, 6); - codegen_addbyte(block, 0x03); /*MOV [p], src_reg*/ - codegen_addbyte(block, 0x05 | (dst_reg << 3)); - codegen_addlong(block, (uint32_t)p); - } + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x03, 0x45 | (dst_reg << 3), offset); /*MOV offset[EBP], src_reg*/ + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte(block, 0x03); /*MOV [p], src_reg*/ + codegen_addbyte(block, 0x05 | (dst_reg << 3)); + codegen_addlong(block, (uint32_t)p); + } } void host_x86_ADD8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) { - if (dst_reg == REG_EAX) { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x04, imm_data); /*ADD AL, imm_data*/ - } else { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_ADD | dst_reg, imm_data); /*ADD dst_reg, imm_data*/ - } + if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x04, imm_data); /*ADD AL, imm_data*/ + } else { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_ADD | dst_reg, imm_data); /*ADD dst_reg, imm_data*/ + } } void host_x86_ADD16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) { - if (is_imm8(imm_data)) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_ADD | dst_reg, imm_data & 0xff); /*ADD dst_reg, imm_data*/ - } else if (dst_reg == REG_EAX) { - codegen_alloc_bytes(block, 4); - codegen_addbyte2(block, 0x66, 0x05); /*ADD AX, imm_data*/ - codegen_addword(block, imm_data); - } else { - codegen_alloc_bytes(block, 5); - codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_ADD | dst_reg); /*ADD dst_reg, imm_data*/ - codegen_addword(block, imm_data); - } + if (is_imm8(imm_data)) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_ADD | dst_reg, imm_data & 0xff); /*ADD dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 4); + codegen_addbyte2(block, 0x66, 0x05); /*ADD AX, imm_data*/ + codegen_addword(block, imm_data); + } else { + codegen_alloc_bytes(block, 5); + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_ADD | dst_reg); /*ADD dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } } void host_x86_ADD32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) { - if (is_imm8(imm_data)) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_ADD | dst_reg, imm_data & 0xff); /*ADD dst_reg, imm_data*/ - } else if (dst_reg == REG_EAX) { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x05); /*ADD EAX, imm_data*/ - codegen_addlong(block, imm_data); - } else { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_ADD | dst_reg); /*ADD dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } + if (is_imm8(imm_data)) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_ADD | dst_reg, imm_data & 0xff); /*ADD dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x05); /*ADD EAX, imm_data*/ + codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_ADD | dst_reg); /*ADD dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } } void host_x86_ADD8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x00, 0xc0 | dst_reg | (src_reg << 3)); /*ADD dst_reg, src_reg*/ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x00, 0xc0 | dst_reg | (src_reg << 3)); /*ADD dst_reg, src_reg*/ } void host_x86_ADD16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x01, 0xc0 | dst_reg | (src_reg << 3)); /*ADD dst_reg, src_reg*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0x01, 0xc0 | dst_reg | (src_reg << 3)); /*ADD dst_reg, src_reg*/ } void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 3); - codegen_addbyte2(block, 0x01, 0xc0 | dst_reg | (src_reg << 3)); /*ADD dst_reg, src_reg*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte2(block, 0x01, 0xc0 | dst_reg | (src_reg << 3)); /*ADD dst_reg, src_reg*/ } void host_x86_AND8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) { - if (dst_reg == REG_EAX) { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x24, imm_data); /*AND AL, imm_data*/ - } else { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_AND | dst_reg, imm_data); /*AND dst_reg, imm_data*/ - } + if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x24, imm_data); /*AND AL, imm_data*/ + } else { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_AND | dst_reg, imm_data); /*AND dst_reg, imm_data*/ + } } void host_x86_AND16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) { - if (is_imm8(imm_data)) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_AND | dst_reg, imm_data & 0xff); /*AND dst_reg, imm_data*/ - } else if (dst_reg == REG_EAX) { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x66, 0x25); /*AND AX, imm_data*/ - codegen_addword(block, imm_data); - } else { - codegen_alloc_bytes(block, 5); - codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_AND | dst_reg); /*AND dst_reg, imm_data*/ - codegen_addword(block, imm_data); - } + if (is_imm8(imm_data)) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_AND | dst_reg, imm_data & 0xff); /*AND dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x66, 0x25); /*AND AX, imm_data*/ + codegen_addword(block, imm_data); + } else { + codegen_alloc_bytes(block, 5); + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_AND | dst_reg); /*AND dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } } void host_x86_AND32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) { - if (is_imm8(imm_data)) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_AND | dst_reg, imm_data & 0xff); /*AND dst_reg, imm_data*/ - } else if (dst_reg == REG_EAX) { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x25); /*AND EAX, imm_data*/ - codegen_addlong(block, imm_data); - } else { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_AND | dst_reg); /*AND dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } + if (is_imm8(imm_data)) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_AND | dst_reg, imm_data & 0xff); /*AND dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x25); /*AND EAX, imm_data*/ + codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_AND | dst_reg); /*AND dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } } void host_x86_AND8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x20, 0xc0 | dst_reg | (src_reg << 3)); /*AND dst_reg, src_reg_b*/ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x20, 0xc0 | dst_reg | (src_reg << 3)); /*AND dst_reg, src_reg_b*/ } void host_x86_AND16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x21, 0xc0 | dst_reg | (src_reg << 3)); /*AND dst_reg, src_reg_b*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0x21, 0xc0 | dst_reg | (src_reg << 3)); /*AND dst_reg, src_reg_b*/ } void host_x86_AND32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x21, 0xc0 | dst_reg | (src_reg << 3)); /*AND dst_reg, src_reg_b*/ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x21, 0xc0 | dst_reg | (src_reg << 3)); /*AND dst_reg, src_reg_b*/ } void host_x86_CALL(codeblock_t *block, void *p) { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0xe8); /*CALL*/ - codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block_write_data[block_pos + 4]); + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0xe8); /*CALL*/ + codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block_write_data[block_pos + 4]); } void host_x86_CMP16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) { - if (is_imm8(imm_data)) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_CMP | dst_reg, imm_data & 0xff); /*CMP dst_reg, imm_data*/ - } else if (dst_reg == REG_EAX) { - codegen_alloc_bytes(block, 4); - codegen_addbyte2(block, 0x66, 0x3d); /*CMP AX, imm_data*/ - codegen_addword(block, imm_data); - } else { - codegen_alloc_bytes(block, 5); - codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_CMP | dst_reg); /*CMP dst_reg, imm_data*/ - codegen_addword(block, imm_data); - } + if (is_imm8(imm_data)) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_CMP | dst_reg, imm_data & 0xff); /*CMP dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 4); + codegen_addbyte2(block, 0x66, 0x3d); /*CMP AX, imm_data*/ + codegen_addword(block, imm_data); + } else { + codegen_alloc_bytes(block, 5); + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_CMP | dst_reg); /*CMP dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } } void host_x86_CMP32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) { - if (is_imm8(imm_data)) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_CMP | dst_reg, imm_data & 0xff); /*CMP dst_reg, imm_data*/ - } else if (dst_reg == REG_EAX) { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x3d); /*CMP EAX, imm_data*/ - codegen_addlong(block, imm_data); - } else { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_CMP | dst_reg); /*CMP dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } + if (is_imm8(imm_data)) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_CMP | dst_reg, imm_data & 0xff); /*CMP dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x3d); /*CMP EAX, imm_data*/ + codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_CMP | dst_reg); /*CMP dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } } void host_x86_CMP8_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b) { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x38, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x38, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ } void host_x86_CMP16_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x39, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0x39, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ } void host_x86_CMP32_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b) { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x39, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x39, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ } void host_x86_INC32_ABS(codeblock_t *block, void *p) { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0xff, 0x05); /*INC p*/ - codegen_addlong(block, (uint32_t)p); + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0xff, 0x05); /*INC p*/ + codegen_addlong(block, (uint32_t)p); } void host_x86_JMP(codeblock_t *block, void *p) { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0xe9); /*JMP*/ - codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block_write_data[block_pos + 4]); + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0xe9); /*JMP*/ + codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block_write_data[block_pos + 4]); } uint32_t *host_x86_JMP_long(codeblock_t *block) { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0xe9); /*JMP*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos - 4]; + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0xe9); /*JMP*/ + codegen_addlong(block, 0); + return (uint32_t *)&block_write_data[block_pos - 4]; } void host_x86_JNZ(codeblock_t *block, void *p) { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x85); /*JNZ*/ - codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block_write_data[block_pos + 4]); + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x85); /*JNZ*/ + codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block_write_data[block_pos + 4]); } void host_x86_JZ(codeblock_t *block, void *p) { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x84); /*JZ*/ - codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block_write_data[block_pos + 4]); + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x84); /*JZ*/ + codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block_write_data[block_pos + 4]); } uint8_t *host_x86_JNZ_short(codeblock_t *block) { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x75, 0); /*JNZ*/ - return &block_write_data[block_pos - 1]; + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x75, 0); /*JNZ*/ + return &block_write_data[block_pos - 1]; } uint8_t *host_x86_JS_short(codeblock_t *block) { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x78, 0); /*JS*/ - return &block_write_data[block_pos - 1]; + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x78, 0); /*JS*/ + return &block_write_data[block_pos - 1]; } uint8_t *host_x86_JZ_short(codeblock_t *block) { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x74, 0); /*JZ*/ - return &block_write_data[block_pos - 1]; + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x74, 0); /*JZ*/ + return &block_write_data[block_pos - 1]; } uint32_t *host_x86_JNB_long(codeblock_t *block) { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x83); /*JNB*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos - 4]; + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x83); /*JNB*/ + codegen_addlong(block, 0); + return (uint32_t *)&block_write_data[block_pos - 4]; } uint32_t *host_x86_JNBE_long(codeblock_t *block) { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x87); /*JNBE*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos - 4]; + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x87); /*JNBE*/ + codegen_addlong(block, 0); + return (uint32_t *)&block_write_data[block_pos - 4]; } uint32_t *host_x86_JNL_long(codeblock_t *block) { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x8d); /*JNL*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos - 4]; + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x8d); /*JNL*/ + codegen_addlong(block, 0); + return (uint32_t *)&block_write_data[block_pos - 4]; } uint32_t *host_x86_JNLE_long(codeblock_t *block) { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x8f); /*JNLE*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos - 4]; + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x8f); /*JNLE*/ + codegen_addlong(block, 0); + return (uint32_t *)&block_write_data[block_pos - 4]; } uint32_t *host_x86_JNO_long(codeblock_t *block) { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x81); /*JNO*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos - 4]; + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x81); /*JNO*/ + codegen_addlong(block, 0); + return (uint32_t *)&block_write_data[block_pos - 4]; } uint32_t *host_x86_JNS_long(codeblock_t *block) { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x89); /*JNS*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos - 4]; + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x89); /*JNS*/ + codegen_addlong(block, 0); + return (uint32_t *)&block_write_data[block_pos - 4]; } uint32_t *host_x86_JNZ_long(codeblock_t *block) { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x85); /*JNZ*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos - 4]; + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x85); /*JNZ*/ + codegen_addlong(block, 0); + return (uint32_t *)&block_write_data[block_pos - 4]; } uint32_t *host_x86_JB_long(codeblock_t *block) { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x82); /*JB*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos - 4]; + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x82); /*JB*/ + codegen_addlong(block, 0); + return (uint32_t *)&block_write_data[block_pos - 4]; } uint32_t *host_x86_JBE_long(codeblock_t *block) { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x86); /*JBE*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos - 4]; + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x86); /*JBE*/ + codegen_addlong(block, 0); + return (uint32_t *)&block_write_data[block_pos - 4]; } uint32_t *host_x86_JL_long(codeblock_t *block) { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x8c); /*JL*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos - 4]; + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x8c); /*JL*/ + codegen_addlong(block, 0); + return (uint32_t *)&block_write_data[block_pos - 4]; } uint32_t *host_x86_JLE_long(codeblock_t *block) { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x8e); /*JLE*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos - 4]; + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x8e); /*JLE*/ + codegen_addlong(block, 0); + return (uint32_t *)&block_write_data[block_pos - 4]; } uint32_t *host_x86_JO_long(codeblock_t *block) { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x80); /*JO*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos - 4]; + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x80); /*JO*/ + codegen_addlong(block, 0); + return (uint32_t *)&block_write_data[block_pos - 4]; } uint32_t *host_x86_JS_long(codeblock_t *block) { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x88); /*JS*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos - 4]; + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x88); /*JS*/ + codegen_addlong(block, 0); + return (uint32_t *)&block_write_data[block_pos - 4]; } uint32_t *host_x86_JZ_long(codeblock_t *block) { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x84); /*JZ*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos - 4]; + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x84); /*JZ*/ + codegen_addlong(block, 0); + return (uint32_t *)&block_write_data[block_pos - 4]; } void host_x86_LAHF(codeblock_t *block) { - codegen_alloc_bytes(block, 1); - codegen_addbyte(block, 0x9f); /*LAHF*/ + codegen_alloc_bytes(block, 1); + codegen_addbyte(block, 0x9f); /*LAHF*/ } void host_x86_LEA_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t offset) { - if (offset) { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x8d, 0x80 | (dst_reg << 3) | src_reg); /*LEA dst_reg, [offset+src_reg]*/ - codegen_addlong(block, offset); - } else { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x8d, 0x00 | (dst_reg << 3) | src_reg); /*LEA dst_reg, [src_reg]*/ - } + if (offset) { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x8d, 0x80 | (dst_reg << 3) | src_reg); /*LEA dst_reg, [offset+src_reg]*/ + codegen_addlong(block, offset); + } else { + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x8d, 0x00 | (dst_reg << 3) | src_reg); /*LEA dst_reg, [src_reg]*/ + } } void host_x86_LEA_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x8d, 0x04 | (dst_reg << 3), (src_reg_b << 3) | src_reg_a); /*LEA dst_reg, [src_reg_a + src_reg_b]*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x8d, 0x04 | (dst_reg << 3), + (src_reg_b << 3) | src_reg_a); /*LEA dst_reg, [src_reg_a + src_reg_b]*/ } void host_x86_LEA_REG_REG_SHIFT(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b, int shift) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x8d, 0x04 | (dst_reg << 3), (shift << 6) | (src_reg_b << 3) | src_reg_a); /*LEA dst_reg, [src_reg_a + src_reg_b * (1 << shift)]*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x8d, 0x04 | (dst_reg << 3), + (shift << 6) | (src_reg_b << 3) | src_reg_a); /*LEA dst_reg, [src_reg_a + src_reg_b * (1 << shift)]*/ } void host_x86_MOV8_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) { - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - if (offset >= -128 && offset < 127) { - codegen_alloc_bytes(block, 4); - codegen_addbyte3(block, 0xc6, 0x45, offset); /*MOVB offset[EBP], imm_data*/ - codegen_addbyte(block, imm_data); - } else { - codegen_alloc_bytes(block, 7); - codegen_addbyte2(block, 0xc6, 0x05); /*MOVB p, imm_data*/ - codegen_addlong(block, (uint32_t)p); - codegen_addbyte(block, imm_data); - } + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 4); + codegen_addbyte3(block, 0xc6, 0x45, offset); /*MOVB offset[EBP], imm_data*/ + codegen_addbyte(block, imm_data); + } else { + codegen_alloc_bytes(block, 7); + codegen_addbyte2(block, 0xc6, 0x05); /*MOVB p, imm_data*/ + codegen_addlong(block, (uint32_t)p); + codegen_addbyte(block, imm_data); + } } void host_x86_MOV16_ABS_IMM(codeblock_t *block, void *p, uint16_t imm_data) { - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - if (offset >= -128 && offset < 127) { - codegen_alloc_bytes(block, 6); - codegen_addbyte4(block, 0x66, 0xc7, 0x45, offset); /*MOV offset[EBP], imm_data*/ - codegen_addword(block, imm_data); - } else { - codegen_alloc_bytes(block, 9); - codegen_addbyte3(block, 0x66, 0xc7, 0x05); /*MOV p, imm_data*/ - codegen_addlong(block, (uint32_t)p); - codegen_addword(block, imm_data); - } + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 6); + codegen_addbyte4(block, 0x66, 0xc7, 0x45, offset); /*MOV offset[EBP], imm_data*/ + codegen_addword(block, imm_data); + } else { + codegen_alloc_bytes(block, 9); + codegen_addbyte3(block, 0x66, 0xc7, 0x05); /*MOV p, imm_data*/ + codegen_addlong(block, (uint32_t)p); + codegen_addword(block, imm_data); + } } void host_x86_MOV32_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) { - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - if (offset >= -128 && offset < 127) { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0xc7, 0x45, offset); /*MOV offset[EBP], imm_data*/ - codegen_addlong(block, imm_data); - } else { - codegen_alloc_bytes(block, 10); - codegen_addbyte2(block, 0xc7, 0x05); /*MOV p, imm_data*/ - codegen_addlong(block, (uint32_t)p); - codegen_addlong(block, imm_data); - } + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0xc7, 0x45, offset); /*MOV offset[EBP], imm_data*/ + codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 10); + codegen_addbyte2(block, 0xc7, 0x05); /*MOV p, imm_data*/ + codegen_addlong(block, (uint32_t)p); + codegen_addlong(block, imm_data); + } } void host_x86_MOV8_ABS_REG(codeblock_t *block, void *p, int src_reg) { - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - if (offset >= -128 && offset < 127) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x88, 0x45 | (src_reg << 3), offset); /*MOVB offset[EBP], src_reg*/ - } else { - codegen_alloc_bytes(block, 6); - codegen_addbyte(block, 0x88); /*MOVB [p], src_reg*/ - codegen_addbyte(block, 0x05 | (src_reg << 3)); - codegen_addlong(block, (uint32_t)p); - } + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x88, 0x45 | (src_reg << 3), offset); /*MOVB offset[EBP], src_reg*/ + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte(block, 0x88); /*MOVB [p], src_reg*/ + codegen_addbyte(block, 0x05 | (src_reg << 3)); + codegen_addlong(block, (uint32_t)p); + } } void host_x86_MOV16_ABS_REG(codeblock_t *block, void *p, int src_reg) { - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - if (offset >= -128 && offset < 127) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x89, 0x45 | (src_reg << 3), offset); /*MOV offset[EBP], src_reg*/ - } else { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0x66, 0x89, 0x05 | (src_reg << 3)); /*MOV [p], src_reg*/ - codegen_addlong(block, (uint32_t)p); - } + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x89, 0x45 | (src_reg << 3), offset); /*MOV offset[EBP], src_reg*/ + } else { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0x66, 0x89, 0x05 | (src_reg << 3)); /*MOV [p], src_reg*/ + codegen_addlong(block, (uint32_t)p); + } } void host_x86_MOV32_ABS_REG(codeblock_t *block, void *p, int src_reg) { - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - if (offset >= -128 && offset < 127) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x89, 0x45 | (src_reg << 3), offset); /*MOV offset[EBP], src_reg*/ - } else { - codegen_alloc_bytes(block, 6); - codegen_addbyte(block, 0x89); /*MOV [p], src_reg*/ - codegen_addbyte(block, 0x05 | (src_reg << 3)); - codegen_addlong(block, (uint32_t)p); - } + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x89, 0x45 | (src_reg << 3), offset); /*MOV offset[EBP], src_reg*/ + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte(block, 0x89); /*MOV [p], src_reg*/ + codegen_addbyte(block, 0x05 | (src_reg << 3)); + codegen_addlong(block, (uint32_t)p); + } } void host_x86_MOV8_ABS_REG_REG_SHIFT_REG(codeblock_t *block, uint32_t addr, int base_reg, int idx_reg, int shift, int src_reg) { - if (addr < 0x80 || addr >= 0xffffff80) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x88, 0x44 | (src_reg << 3), base_reg | (idx_reg << 3) | (shift << 6), addr & 0xff); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ - } else { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0x88, 0x84 | (src_reg << 3), base_reg | (idx_reg << 3) | (shift << 6)); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ - codegen_addlong(block, addr); - } + if (addr < 0x80 || addr >= 0xffffff80) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x88, 0x44 | (src_reg << 3), base_reg | (idx_reg << 3) | (shift << 6), + addr & 0xff); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ + } else { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0x88, 0x84 | (src_reg << 3), + base_reg | (idx_reg << 3) | (shift << 6)); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ + codegen_addlong(block, addr); + } } void host_x86_MOV8_BASE_INDEX_REG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x88, 0x04 | (src_reg << 3), base_reg | (idx_reg << 3)); /*MOV B[base_reg + idx_reg], src_reg*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x88, 0x04 | (src_reg << 3), base_reg | (idx_reg << 3)); /*MOV B[base_reg + idx_reg], src_reg*/ } void host_x86_MOV16_BASE_INDEX_REG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x89, 0x04 | (src_reg << 3), base_reg | (idx_reg << 3)); /*MOV W[base_reg + idx_reg], src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x89, 0x04 | (src_reg << 3), + base_reg | (idx_reg << 3)); /*MOV W[base_reg + idx_reg], src_reg*/ } void host_x86_MOV32_BASE_INDEX_REG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x89, 0x04 | (src_reg << 3), base_reg | (idx_reg << 3)); /*MOV L[base_reg + idx_reg], src_reg*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x89, 0x04 | (src_reg << 3), base_reg | (idx_reg << 3)); /*MOV L[base_reg + idx_reg], src_reg*/ } void host_x86_MOV8_REG_ABS(codeblock_t *block, int dst_reg, void *p) { - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - if (offset >= -128 && offset < 127) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x8a, 0x45 | (dst_reg << 3), offset); /*MOV offset[EBP], src_reg*/ - } else { - codegen_alloc_bytes(block, 6); - codegen_addbyte(block, 0x8a); /*MOV [p], src_reg*/ - codegen_addbyte(block, 0x05 | (dst_reg << 3)); - codegen_addlong(block, (uint32_t)p); - } + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x8a, 0x45 | (dst_reg << 3), offset); /*MOV offset[EBP], src_reg*/ + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte(block, 0x8a); /*MOV [p], src_reg*/ + codegen_addbyte(block, 0x05 | (dst_reg << 3)); + codegen_addlong(block, (uint32_t)p); + } } void host_x86_MOV16_REG_ABS(codeblock_t *block, int dst_reg, void *p) { - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - if (offset >= -128 && offset < 127) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x8b, 0x45 | (dst_reg << 3), offset); /*MOV offset[EBP], src_reg*/ - } else { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0x66, 0x8b, 0x05 | (dst_reg << 3)); /*MOV [p], src_reg*/ - codegen_addlong(block, (uint32_t)p); - } + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x8b, 0x45 | (dst_reg << 3), offset); /*MOV offset[EBP], src_reg*/ + } else { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0x66, 0x8b, 0x05 | (dst_reg << 3)); /*MOV [p], src_reg*/ + codegen_addlong(block, (uint32_t)p); + } } void host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p) { - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - if (offset >= -128 && offset < 127) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x8b, 0x45 | (dst_reg << 3), offset); /*MOV offset[EBP], src_reg*/ - } else { - codegen_alloc_bytes(block, 6); - codegen_addbyte(block, 0x8b); /*MOV [p], src_reg*/ - codegen_addbyte(block, 0x05 | (dst_reg << 3)); - codegen_addlong(block, (uint32_t)p); - } + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x8b, 0x45 | (dst_reg << 3), offset); /*MOV offset[EBP], src_reg*/ + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte(block, 0x8b); /*MOV [p], src_reg*/ + codegen_addbyte(block, 0x05 | (dst_reg << 3)); + codegen_addlong(block, (uint32_t)p); + } } void host_x86_MOV32_REG_ABS_INDEX_SHIFT(codeblock_t *block, int dst_reg, void *p, int idx_reg, int shift) { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0x8b, 0x04 | (dst_reg << 3), (shift << 6) | (idx_reg << 3) | 0x05); /*MOV dst_reg, [p + idx_reg << shift]*/ - codegen_addlong(block, (uint32_t)p); + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0x8b, 0x04 | (dst_reg << 3), + (shift << 6) | (idx_reg << 3) | 0x05); /*MOV dst_reg, [p + idx_reg << shift]*/ + codegen_addlong(block, (uint32_t)p); } void host_x86_MOV8_REG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int base_reg, int idx_reg, int shift) { - if (addr < 0x80 || addr >= 0xffffff80) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x8a, 0x44 | (dst_reg << 3), base_reg | (idx_reg << 3) | (shift << 6), addr & 0xff); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ - } else { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0x8a, 0x84 | (dst_reg << 3), base_reg | (idx_reg << 3) | (shift << 6)); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ - codegen_addlong(block, addr); - } + if (addr < 0x80 || addr >= 0xffffff80) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x8a, 0x44 | (dst_reg << 3), base_reg | (idx_reg << 3) | (shift << 6), + addr & 0xff); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ + } else { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0x8a, 0x84 | (dst_reg << 3), + base_reg | (idx_reg << 3) | (shift << 6)); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ + codegen_addlong(block, addr); + } } void host_x86_MOV32_REG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x8b, 0x04 | (dst_reg << 3), base_reg | (idx_reg << 3)); /*MOV dst_reg, L[base_reg + idx_reg]*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x8b, 0x04 | (dst_reg << 3), base_reg | (idx_reg << 3)); /*MOV dst_reg, L[base_reg + idx_reg]*/ } void host_x86_MOV16_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset) { - if (offset >= -128 && offset < 127) { - if (base_reg == REG_ESP) { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x66); - codegen_addbyte4(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), 0x24, offset); - } else { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x8b, 0x40 | base_reg | (dst_reg << 3), offset); - } - } else - fatal("MOV16_REG_BASE_OFFSET - offset %i\n", offset); + if (offset >= -128 && offset < 127) { + if (base_reg == REG_ESP) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x66); + codegen_addbyte4(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), 0x24, offset); + } else { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x8b, 0x40 | base_reg | (dst_reg << 3), offset); + } + } else + fatal("MOV16_REG_BASE_OFFSET - offset %i\n", offset); } void host_x86_MOV32_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset) { - if (offset >= -128 && offset < 127) { - if (base_reg == REG_ESP) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), 0x24, offset); - } else { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), offset); - } - } else - fatal("MOV32_REG_BASE_OFFSET - offset %i\n", offset); + if (offset >= -128 && offset < 127) { + if (base_reg == REG_ESP) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), 0x24, offset); + } else { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), offset); + } + } else + fatal("MOV32_REG_BASE_OFFSET - offset %i\n", offset); } void host_x86_MOV16_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int src_reg) { - if (offset >= -128 && offset < 127) { - if (base_reg == REG_ESP) { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x66); - codegen_addbyte4(block, 0x89, 0x40 | base_reg | (src_reg << 3), 0x24, offset); - } else { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x89, 0x40 | base_reg | (src_reg << 3), offset); - } - } else - fatal("MOV16_BASE_OFFSET_REG - offset %i\n", offset); + if (offset >= -128 && offset < 127) { + if (base_reg == REG_ESP) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x66); + codegen_addbyte4(block, 0x89, 0x40 | base_reg | (src_reg << 3), 0x24, offset); + } else { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x89, 0x40 | base_reg | (src_reg << 3), offset); + } + } else + fatal("MOV16_BASE_OFFSET_REG - offset %i\n", offset); } void host_x86_MOV32_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int src_reg) { - if (offset >= -128 && offset < 127) { - if (base_reg == REG_ESP) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x89, 0x40 | base_reg | (src_reg << 3), 0x24, offset); - } else { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x89, 0x40 | base_reg | (src_reg << 3), offset); - } - } else - fatal("MOV32_BASE_OFFSET_REG - offset %i\n", offset); + if (offset >= -128 && offset < 127) { + if (base_reg == REG_ESP) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x89, 0x40 | base_reg | (src_reg << 3), 0x24, offset); + } else { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x89, 0x40 | base_reg | (src_reg << 3), offset); + } + } else + fatal("MOV32_BASE_OFFSET_REG - offset %i\n", offset); } void host_x86_MOV32_BASE_OFFSET_IMM(codeblock_t *block, int base_reg, int offset, uint32_t imm_data) { - if (offset >= -128 && offset < 127) { - if (base_reg == REG_ESP) { - codegen_alloc_bytes(block, 8); - codegen_addbyte4(block, 0xc7, 0x40 | base_reg, 0x24, offset); - codegen_addlong(block, imm_data); - } else { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0xc7, 0x40 | base_reg, offset); - codegen_addlong(block, imm_data); - } - } else - fatal("MOV32_BASE_OFFSET_IMM - offset %i\n", offset); + if (offset >= -128 && offset < 127) { + if (base_reg == REG_ESP) { + codegen_alloc_bytes(block, 8); + codegen_addbyte4(block, 0xc7, 0x40 | base_reg, 0x24, offset); + codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0xc7, 0x40 | base_reg, offset); + codegen_addlong(block, imm_data); + } + } else + fatal("MOV32_BASE_OFFSET_IMM - offset %i\n", offset); } void host_x86_MOV8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xb0 + dst_reg, imm_data); /*MOV reg, imm_data*/ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xb0 + dst_reg, imm_data); /*MOV reg, imm_data*/ } void host_x86_MOV16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) { - if (!imm_data) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x31, 0xc0 | dst_reg | (dst_reg << 3)); /*XOR dst_reg, dst_reg*/ - } else { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x66, 0xb8 + dst_reg); /*MOV reg, imm_data*/ - codegen_addword(block, imm_data); - } + if (!imm_data) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0x31, 0xc0 | dst_reg | (dst_reg << 3)); /*XOR dst_reg, dst_reg*/ + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x66, 0xb8 + dst_reg); /*MOV reg, imm_data*/ + codegen_addword(block, imm_data); + } } void host_x86_MOV32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) { - if (!imm_data) { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x31, 0xc0 | dst_reg | (dst_reg << 3)); /*XOR dst_reg, dst_reg*/ - } else { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0xb8 + dst_reg); /*MOV reg, imm_data*/ - codegen_addlong(block, imm_data); - } + if (!imm_data) { + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x31, 0xc0 | dst_reg | (dst_reg << 3)); /*XOR dst_reg, dst_reg*/ + } else { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0xb8 + dst_reg); /*MOV reg, imm_data*/ + codegen_addlong(block, imm_data); + } } void host_x86_MOV8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x88, 0xc0 | dst_reg | (src_reg << 3)); + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x88, 0xc0 | dst_reg | (src_reg << 3)); } void host_x86_MOV16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x89, 0xc0 | dst_reg | (src_reg << 3)); + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0x89, 0xc0 | dst_reg | (src_reg << 3)); } void host_x86_MOV32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x89, 0xc0 | dst_reg | (src_reg << 3)); + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x89, 0xc0 | dst_reg | (src_reg << 3)); } void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_t imm_data) { - if (!offset) { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0xc7, 0x04, 0x24); /*MOV [ESP], imm_data*/ - codegen_addlong(block, imm_data); - } else if (offset >= -0x80 && offset < 0x80) { - codegen_alloc_bytes(block, 8); - codegen_addbyte4(block, 0xc7, 0x44, 0x24, offset & 0xff); /*MOV offset[ESP], imm_data*/ - codegen_addlong(block, imm_data); - } else { - codegen_alloc_bytes(block, 11); - codegen_addbyte3(block, 0xc7, 0x84, 0x24); /*MOV offset[ESP], imm_data*/ - codegen_addlong(block, offset); - codegen_addlong(block, imm_data); - } + if (!offset) { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0xc7, 0x04, 0x24); /*MOV [ESP], imm_data*/ + codegen_addlong(block, imm_data); + } else if (offset >= -0x80 && offset < 0x80) { + codegen_alloc_bytes(block, 8); + codegen_addbyte4(block, 0xc7, 0x44, 0x24, offset & 0xff); /*MOV offset[ESP], imm_data*/ + codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 11); + codegen_addbyte3(block, 0xc7, 0x84, 0x24); /*MOV offset[ESP], imm_data*/ + codegen_addlong(block, offset); + codegen_addlong(block, imm_data); + } } void host_x86_MOVSX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xbe, 0xc0 | (dst_reg << 3) | src_reg); /*MOVSX dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xbe, 0xc0 | (dst_reg << 3) | src_reg); /*MOVSX dst_reg, src_reg*/ } void host_x86_MOVSX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0xbe, 0xc0 | (dst_reg << 3) | src_reg); /*MOVSX dst_reg, src_reg*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0xbe, 0xc0 | (dst_reg << 3) | src_reg); /*MOVSX dst_reg, src_reg*/ } void host_x86_MOVSX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0xbf, 0xc0 | (dst_reg << 3) | src_reg); /*MOVSX dst_reg, src_reg*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0xbf, 0xc0 | (dst_reg << 3) | src_reg); /*MOVSX dst_reg, src_reg*/ } void host_x86_MOVZX_REG_ABS_16_8(codeblock_t *block, int dst_reg, void *p) { - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - if (offset >= -128 && offset < 127) { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x66); - codegen_addbyte4(block, 0x0f, 0xb6, 0x45 | (dst_reg << 3), offset); /*MOV dest_reg, [EBP+offset]*/ - } else { - codegen_alloc_bytes(block, 8); - codegen_addbyte4(block, 0x66, 0x0f, 0xb6, 0x05 | (dst_reg << 3)); /*MOVZX dst_reg, [p]*/ - codegen_addlong(block, (uint32_t)p); - } + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x66); + codegen_addbyte4(block, 0x0f, 0xb6, 0x45 | (dst_reg << 3), offset); /*MOV dest_reg, [EBP+offset]*/ + } else { + codegen_alloc_bytes(block, 8); + codegen_addbyte4(block, 0x66, 0x0f, 0xb6, 0x05 | (dst_reg << 3)); /*MOVZX dst_reg, [p]*/ + codegen_addlong(block, (uint32_t)p); + } } void host_x86_MOVZX_REG_ABS_32_8(codeblock_t *block, int dst_reg, void *p) { - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - if (offset >= -128 && offset < 127) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x0f, 0xb6, 0x45 | (dst_reg << 3), offset); /*MOV dest_reg, [EBP+offset]*/ - } else { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0x0f, 0xb6, 0x05 | (dst_reg << 3)); /*MOVZX dst_reg, [p]*/ - codegen_addlong(block, (uint32_t)p); - } + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x0f, 0xb6, 0x45 | (dst_reg << 3), offset); /*MOV dest_reg, [EBP+offset]*/ + } else { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0x0f, 0xb6, 0x05 | (dst_reg << 3)); /*MOVZX dst_reg, [p]*/ + codegen_addlong(block, (uint32_t)p); + } } void host_x86_MOVZX_REG_ABS_32_16(codeblock_t *block, int dst_reg, void *p) { - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - if (offset >= -128 && offset < 127) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x0f, 0xb7, 0x45 | (dst_reg << 3), offset); /*MOV dest_reg, [EBP+offset]*/ - } else { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0x0f, 0xb7, 0x05 | (dst_reg << 3)); /*MOVZX dst_reg, [p]*/ - codegen_addlong(block, (uint32_t)p); - } + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x0f, 0xb7, 0x45 | (dst_reg << 3), offset); /*MOV dest_reg, [EBP+offset]*/ + } else { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0x0f, 0xb7, 0x05 | (dst_reg << 3)); /*MOVZX dst_reg, [p]*/ + codegen_addlong(block, (uint32_t)p); + } } void host_x86_MOVZX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xb6, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xb6, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ } void host_x86_MOVZX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0xb6, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0xb6, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ } void host_x86_MOVZX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0xb7, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0xb7, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ } void host_x86_MOVZX_BASE_INDEX_32_8(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x0f, 0xb6, 0x04 | (dst_reg << 3), base_reg | (idx_reg << 3)); /*MOVZX dst_reg, B[base_reg + idx_reg]*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x0f, 0xb6, 0x04 | (dst_reg << 3), + base_reg | (idx_reg << 3)); /*MOVZX dst_reg, B[base_reg + idx_reg]*/ } void host_x86_MOVZX_BASE_INDEX_32_16(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x0f, 0xb7, 0x04 | (dst_reg << 3), base_reg | (idx_reg << 3)); /*MOVZX dst_reg, W[base_reg + idx_reg]*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x0f, 0xb7, 0x04 | (dst_reg << 3), + base_reg | (idx_reg << 3)); /*MOVZX dst_reg, W[base_reg + idx_reg]*/ } void host_x86_OR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x08, 0xc0 | dst_reg | (src_reg << 3)); /*OR dst_reg, src_reg_b*/ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x08, 0xc0 | dst_reg | (src_reg << 3)); /*OR dst_reg, src_reg_b*/ } void host_x86_OR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x09, 0xc0 | dst_reg | (src_reg << 3)); /*OR dst_reg, src_reg_b*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0x09, 0xc0 | dst_reg | (src_reg << 3)); /*OR dst_reg, src_reg_b*/ } void host_x86_OR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x09, 0xc0 | dst_reg | (src_reg << 3)); /*OR dst_reg, src_reg_b*/ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x09, 0xc0 | dst_reg | (src_reg << 3)); /*OR dst_reg, src_reg_b*/ } void host_x86_OR8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) { - if (dst_reg == REG_EAX) { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x0c, imm_data); /*OR AL, imm_data*/ - } else { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_OR | dst_reg, imm_data); /*OR dst_reg, imm_data*/ - } + if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x0c, imm_data); /*OR AL, imm_data*/ + } else { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_OR | dst_reg, imm_data); /*OR dst_reg, imm_data*/ + } } void host_x86_OR16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) { - if (is_imm8(imm_data)) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_OR | dst_reg, imm_data & 0xff); /*OR dst_reg, imm_data*/ - } else if (dst_reg == REG_EAX) { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x66, 0x0d); /*OR AX, imm_data*/ - codegen_addword(block, imm_data); - } else { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_OR | dst_reg); /*OR dst_reg, imm_data*/ - codegen_addword(block, imm_data); - } + if (is_imm8(imm_data)) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_OR | dst_reg, imm_data & 0xff); /*OR dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x66, 0x0d); /*OR AX, imm_data*/ + codegen_addword(block, imm_data); + } else { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_OR | dst_reg); /*OR dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } } void host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) { - if (is_imm8(imm_data)) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_OR | dst_reg, imm_data & 0xff); /*OR dst_reg, imm_data*/ - } else if (dst_reg == REG_EAX) { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x0d); /*OR EAX, imm_data*/ - codegen_addlong(block, imm_data); - } else { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_OR | dst_reg); /*OR dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } + if (is_imm8(imm_data)) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_OR | dst_reg, imm_data & 0xff); /*OR dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x0d); /*OR EAX, imm_data*/ + codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_OR | dst_reg); /*OR dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } } void host_x86_POP(codeblock_t *block, int src_reg) { - codegen_alloc_bytes(block, 1); - codegen_addbyte(block, 0x58 | src_reg); /*POP reg*/ + codegen_alloc_bytes(block, 1); + codegen_addbyte(block, 0x58 | src_reg); /*POP reg*/ } void host_x86_PUSH(codeblock_t *block, int src_reg) { - codegen_alloc_bytes(block, 1); - codegen_addbyte(block, 0x50 | src_reg); /*PUSH reg*/ + codegen_alloc_bytes(block, 1); + codegen_addbyte(block, 0x50 | src_reg); /*PUSH reg*/ } void host_x86_RET(codeblock_t *block) { - codegen_alloc_bytes(block, 1); - codegen_addbyte(block, 0xc3); /*RET*/ + codegen_alloc_bytes(block, 1); + codegen_addbyte(block, 0xc3); /*RET*/ } void host_x86_ROL8_CL(codeblock_t *block, int dst_reg) { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_ROL | dst_reg); /*SHL dst_reg, CL*/ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_ROL | dst_reg); /*SHL dst_reg, CL*/ } void host_x86_ROL16_CL(codeblock_t *block, int dst_reg) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_ROL | dst_reg); /*SHL dst_reg, CL*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_ROL | dst_reg); /*SHL dst_reg, CL*/ } void host_x86_ROL32_CL(codeblock_t *block, int dst_reg) { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_ROL | dst_reg); /*SHL dst_reg, CL*/ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_ROL | dst_reg); /*SHL dst_reg, CL*/ } void host_x86_ROL8_IMM(codeblock_t *block, int dst_reg, int shift) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_ROL | dst_reg, shift); /*SHL dst_reg, shift*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_ROL | dst_reg, shift); /*SHL dst_reg, shift*/ } void host_x86_ROL16_IMM(codeblock_t *block, int dst_reg, int shift) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_ROL | dst_reg, shift); /*SHL dst_reg, shift*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_ROL | dst_reg, shift); /*SHL dst_reg, shift*/ } void host_x86_ROL32_IMM(codeblock_t *block, int dst_reg, int shift) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_ROL | dst_reg, shift); /*SHL dst_reg, shift*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_ROL | dst_reg, shift); /*SHL dst_reg, shift*/ } void host_x86_ROR8_CL(codeblock_t *block, int dst_reg) { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_ROR | dst_reg); /*SHR dst_reg, CL*/ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_ROR | dst_reg); /*SHR dst_reg, CL*/ } void host_x86_ROR16_CL(codeblock_t *block, int dst_reg) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_ROR | dst_reg); /*SHR dst_reg, CL*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_ROR | dst_reg); /*SHR dst_reg, CL*/ } void host_x86_ROR32_CL(codeblock_t *block, int dst_reg) { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_ROR | dst_reg); /*SHR dst_reg, CL*/ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_ROR | dst_reg); /*SHR dst_reg, CL*/ } void host_x86_ROR8_IMM(codeblock_t *block, int dst_reg, int shift) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_ROR | dst_reg, shift); /*SHR dst_reg, shift*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_ROR | dst_reg, shift); /*SHR dst_reg, shift*/ } void host_x86_ROR16_IMM(codeblock_t *block, int dst_reg, int shift) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_ROR | dst_reg, shift); /*SHR dst_reg, shift*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_ROR | dst_reg, shift); /*SHR dst_reg, shift*/ } void host_x86_ROR32_IMM(codeblock_t *block, int dst_reg, int shift) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_ROR | dst_reg, shift); /*SHR dst_reg, shift*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_ROR | dst_reg, shift); /*SHR dst_reg, shift*/ } #define MODRM_MOD_REG(rm, reg) (0xc0 | reg | (rm << 3)) void host_x86_SAR8_CL(codeblock_t *block, int dst_reg) { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/ } void host_x86_SAR16_CL(codeblock_t *block, int dst_reg) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/ } void host_x86_SAR32_CL(codeblock_t *block, int dst_reg) { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/ } void host_x86_SAR8_IMM(codeblock_t *block, int dst_reg, int shift) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/ } void host_x86_SAR16_IMM(codeblock_t *block, int dst_reg, int shift) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/ } void host_x86_SAR32_IMM(codeblock_t *block, int dst_reg, int shift) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/ } void host_x86_SHL8_CL(codeblock_t *block, int dst_reg) { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/ } void host_x86_SHL16_CL(codeblock_t *block, int dst_reg) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/ } void host_x86_SHL32_CL(codeblock_t *block, int dst_reg) { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/ } void host_x86_SHL8_IMM(codeblock_t *block, int dst_reg, int shift) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/ } void host_x86_SHL16_IMM(codeblock_t *block, int dst_reg, int shift) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/ } void host_x86_SHL32_IMM(codeblock_t *block, int dst_reg, int shift) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/ } void host_x86_SHR8_CL(codeblock_t *block, int dst_reg) { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/ } void host_x86_SHR16_CL(codeblock_t *block, int dst_reg) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/ } void host_x86_SHR32_CL(codeblock_t *block, int dst_reg) { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/ } void host_x86_SHR8_IMM(codeblock_t *block, int dst_reg, int shift) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ } void host_x86_SHR16_IMM(codeblock_t *block, int dst_reg, int shift) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ } void host_x86_SHR32_IMM(codeblock_t *block, int dst_reg, int shift) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ } void host_x86_SUB8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) { - if (dst_reg == REG_EAX) { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x2c, imm_data); /*SUB AL, imm_data*/ - } else { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_SUB | dst_reg, imm_data); /*SUB dst_reg, imm_data*/ - } + if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x2c, imm_data); /*SUB AL, imm_data*/ + } else { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_SUB | dst_reg, imm_data); /*SUB dst_reg, imm_data*/ + } } void host_x86_SUB16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) { - if (is_imm8(imm_data)) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_SUB | dst_reg, imm_data & 0xff); /*SUB dst_reg, imm_data*/ - } else if (dst_reg == REG_EAX) { - codegen_alloc_bytes(block, 4); - codegen_addbyte2(block, 0x66, 0x2d); /*SUB AX, imm_data*/ - codegen_addword(block, imm_data); - } else { - codegen_alloc_bytes(block, 5); - codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_SUB | dst_reg); /*SUB dst_reg, imm_data*/ - codegen_addword(block, imm_data); - } + if (is_imm8(imm_data)) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_SUB | dst_reg, imm_data & 0xff); /*SUB dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 4); + codegen_addbyte2(block, 0x66, 0x2d); /*SUB AX, imm_data*/ + codegen_addword(block, imm_data); + } else { + codegen_alloc_bytes(block, 5); + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_SUB | dst_reg); /*SUB dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } } void host_x86_SUB32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) { - if (is_imm8(imm_data)) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_SUB | dst_reg, imm_data & 0xff); /*SUB dst_reg, imm_data*/ - } else if (dst_reg == REG_EAX) { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x2d); /*SUB EAX, imm_data*/ - codegen_addlong(block, imm_data); - } else { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_SUB | dst_reg); /*SUB dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } + if (is_imm8(imm_data)) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_SUB | dst_reg, imm_data & 0xff); /*SUB dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x2d); /*SUB EAX, imm_data*/ + codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_SUB | dst_reg); /*SUB dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } } void host_x86_SUB8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x28, 0xc0 | dst_reg | (src_reg << 3)); /*SUB dst_reg, src_reg*/ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x28, 0xc0 | dst_reg | (src_reg << 3)); /*SUB dst_reg, src_reg*/ } void host_x86_SUB16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x29, 0xc0 | dst_reg | (src_reg << 3)); /*SUB dst_reg, src_reg*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0x29, 0xc0 | dst_reg | (src_reg << 3)); /*SUB dst_reg, src_reg*/ } void host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x29, 0xc0 | dst_reg | (src_reg << 3)); /*SUB dst_reg, src_reg*/ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x29, 0xc0 | dst_reg | (src_reg << 3)); /*SUB dst_reg, src_reg*/ } void host_x86_TEST8_REG(codeblock_t *block, int src_host_reg, int dst_host_reg) { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x84, MODRM_MOD_REG(dst_host_reg, src_host_reg)); /*TEST dst_host_reg, src_host_reg*/ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x84, MODRM_MOD_REG(dst_host_reg, src_host_reg)); /*TEST dst_host_reg, src_host_reg*/ } void host_x86_TEST16_REG(codeblock_t *block, int src_host_reg, int dst_host_reg) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x85, MODRM_MOD_REG(dst_host_reg, src_host_reg)); /*TEST dst_host_reg, src_host_reg*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0x85, MODRM_MOD_REG(dst_host_reg, src_host_reg)); /*TEST dst_host_reg, src_host_reg*/ } void host_x86_TEST32_REG(codeblock_t *block, int src_host_reg, int dst_host_reg) { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x85, MODRM_MOD_REG(dst_host_reg, src_host_reg)); /*TEST dst_host_reg, src_host_reg*/ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x85, MODRM_MOD_REG(dst_host_reg, src_host_reg)); /*TEST dst_host_reg, src_host_reg*/ } void host_x86_TEST32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) { - if (dst_reg == REG_EAX) { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0xa9); /*TEST EAX, imm_data*/ - codegen_addlong(block, imm_data); - } else { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0xf7, 0xc0 | dst_reg); /*TEST dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } + if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0xa9); /*TEST EAX, imm_data*/ + codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0xf7, 0xc0 | dst_reg); /*TEST dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } } void host_x86_XOR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x30, 0xc0 | dst_reg | (src_reg << 3)); /*XOR dst_reg, src_reg*/ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x30, 0xc0 | dst_reg | (src_reg << 3)); /*XOR dst_reg, src_reg*/ } void host_x86_XOR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x31, 0xc0 | dst_reg | (src_reg << 3)); /*XOR dst_reg, src_reg*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0x31, 0xc0 | dst_reg | (src_reg << 3)); /*XOR dst_reg, src_reg*/ } void host_x86_XOR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x31, 0xc0 | dst_reg | (src_reg << 3)); /*XOR dst_reg, src_reg*/ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x31, 0xc0 | dst_reg | (src_reg << 3)); /*XOR dst_reg, src_reg*/ } void host_x86_XOR8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) { - if (dst_reg == REG_EAX) { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x34, imm_data); /*XOR AL, imm_data*/ - } else { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_XOR | dst_reg, imm_data); /*XOR dst_reg, imm_data*/ - } + if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x34, imm_data); /*XOR AL, imm_data*/ + } else { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_XOR | dst_reg, imm_data); /*XOR dst_reg, imm_data*/ + } } void host_x86_XOR16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) { - if (is_imm8(imm_data)) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_XOR | dst_reg, imm_data & 0xff); /*XOR dst_reg, imm_data*/ - } else if (dst_reg == REG_EAX) { - codegen_alloc_bytes(block, 4); - codegen_addbyte2(block, 0x66, 0x35); /*XOR AX, imm_data*/ - codegen_addword(block, imm_data); - } else { - codegen_alloc_bytes(block, 5); - codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_XOR | dst_reg); /*XOR dst_reg, imm_data*/ - codegen_addword(block, imm_data); - } + if (is_imm8(imm_data)) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_XOR | dst_reg, imm_data & 0xff); /*XOR dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 4); + codegen_addbyte2(block, 0x66, 0x35); /*XOR AX, imm_data*/ + codegen_addword(block, imm_data); + } else { + codegen_alloc_bytes(block, 5); + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_XOR | dst_reg); /*XOR dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } } void host_x86_XOR32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) { - if (is_imm8(imm_data)) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_XOR | dst_reg, imm_data & 0xff); /*XOR dst_reg, imm_data*/ - } else if (dst_reg == REG_EAX) { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x35); /*XOR EAX, imm_data*/ - codegen_addlong(block, imm_data); - } else { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_XOR | dst_reg); /*XOR dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } + if (is_imm8(imm_data)) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_XOR | dst_reg, imm_data & 0xff); /*XOR dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x35); /*XOR EAX, imm_data*/ + codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_XOR | dst_reg); /*XOR dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } } #endif diff --git a/src/codegen/x86/codegen_backend_x86_ops_fpu.c b/src/codegen/x86/codegen_backend_x86_ops_fpu.c index 84df42bd..043662b5 100644 --- a/src/codegen/x86/codegen_backend_x86_ops_fpu.c +++ b/src/codegen/x86/codegen_backend_x86_ops_fpu.c @@ -9,52 +9,52 @@ #include "codegen_backend_x86_ops_helpers.h" void host_x87_FILDq_BASE(codeblock_t *block, int base_reg) { - if (base_reg == REG_ESP) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xdf, 0x2c, 0x24); /*FILDq [ESP]*/ - } else { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xdf, 0x28 | base_reg); /*FILDq [base_reg]*/ - } + if (base_reg == REG_ESP) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xdf, 0x2c, 0x24); /*FILDq [ESP]*/ + } else { + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xdf, 0x28 | base_reg); /*FILDq [base_reg]*/ + } } void host_x87_FISTPq_BASE(codeblock_t *block, int base_reg) { - if (base_reg == REG_ESP) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xdf, 0x3c, 0x24); /*FISTPq [ESP]*/ - } else { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xdf, 0x38 | base_reg); /*FISTPq [base_reg]*/ - } + if (base_reg == REG_ESP) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xdf, 0x3c, 0x24); /*FISTPq [ESP]*/ + } else { + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xdf, 0x38 | base_reg); /*FISTPq [base_reg]*/ + } } void host_x87_FLDCW(codeblock_t *block, void *p) { - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - if (offset >= -128 && offset < 127) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xd9, 0x68 | REG_EBP, offset); /*FLDCW offset[EBP]*/ - } else { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0xd9, 0x2d); /*FLDCW [p]*/ - codegen_addlong(block, (uint32_t)p); - } + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xd9, 0x68 | REG_EBP, offset); /*FLDCW offset[EBP]*/ + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0xd9, 0x2d); /*FLDCW [p]*/ + codegen_addlong(block, (uint32_t)p); + } } void host_x87_FLDd_BASE(codeblock_t *block, int base_reg) { - if (base_reg == REG_ESP) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xdd, 0x04, 0x24); /*FILDq [ESP]*/ - } else { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xdd, 0x08 | base_reg); /*FILDq [base_reg]*/ - } + if (base_reg == REG_ESP) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xdd, 0x04, 0x24); /*FILDq [ESP]*/ + } else { + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xdd, 0x08 | base_reg); /*FILDq [base_reg]*/ + } } void host_x87_FSTPd_BASE(codeblock_t *block, int base_reg) { - if (base_reg == REG_ESP) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xdd, 0x1c, 0x24); /*FILDq [ESP]*/ - } else { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xdd, 0x18 | base_reg); /*FILDq [base_reg]*/ - } + if (base_reg == REG_ESP) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xdd, 0x1c, 0x24); /*FILDq [ESP]*/ + } else { + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xdd, 0x18 | base_reg); /*FILDq [base_reg]*/ + } } #endif diff --git a/src/codegen/x86/codegen_backend_x86_ops_sse.c b/src/codegen/x86/codegen_backend_x86_ops_sse.c index 4e7163dc..270818e7 100644 --- a/src/codegen/x86/codegen_backend_x86_ops_sse.c +++ b/src/codegen/x86/codegen_backend_x86_ops_sse.c @@ -9,454 +9,461 @@ #include "codegen_backend_x86_ops_helpers.h" void host_x86_ADDPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0x58, 0xc0 | src_reg | (dst_reg << 3)); /*ADDPS dst_reg, src_reg*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0x58, 0xc0 | src_reg | (dst_reg << 3)); /*ADDPS dst_reg, src_reg*/ } void host_x86_ADDSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x58, 0xc0 | src_reg | (dst_reg << 3)); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x58, 0xc0 | src_reg | (dst_reg << 3)); } void host_x86_CMPPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg, int type) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x0f, 0xc2, 0xc0 | src_reg | (dst_reg << 3), type); /*CMPPS dst_reg, src_reg, type*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x0f, 0xc2, 0xc0 | src_reg | (dst_reg << 3), type); /*CMPPS dst_reg, src_reg, type*/ } void host_x86_COMISD_XREG_XREG(codeblock_t *block, int src_reg_a, int src_reg_b) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x2e, 0xc0 | src_reg_b | (src_reg_a << 3)); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x2e, 0xc0 | src_reg_b | (src_reg_a << 3)); } void host_x86_CVTDQ2PS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0x5b, 0xc0 | src_reg | (dst_reg << 3)); /*CVTDQ2PS dst_reg, src_reg*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0x5b, 0xc0 | src_reg | (dst_reg << 3)); /*CVTDQ2PS dst_reg, src_reg*/ } void host_x86_CVTPS2DQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x5b, 0xc0 | src_reg | (dst_reg << 3)); /*CVTPS2DQ dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x5b, 0xc0 | src_reg | (dst_reg << 3)); /*CVTPS2DQ dst_reg, src_reg*/ } void host_x86_CVTSD2SI_REG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x2d, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSD2SI dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x2d, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSD2SI dst_reg, src_reg*/ } void host_x86_CVTSD2SS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x5a, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSD2SS dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x5a, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSD2SS dst_reg, src_reg*/ } void host_x86_CVTSI2SD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x2a, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSI2SD dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x2a, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSI2SD dst_reg, src_reg*/ } void host_x86_CVTSI2SS_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf3, 0x0f, 0x2a, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSI2SD dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf3, 0x0f, 0x2a, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSI2SD dst_reg, src_reg*/ } void host_x86_CVTSS2SD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf3, 0x0f, 0x5a, 0xc0 | src_reg | (dst_reg << 3)); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf3, 0x0f, 0x5a, 0xc0 | src_reg | (dst_reg << 3)); } void host_x86_CVTSS2SD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0xf3, 0x0f, 0x5a, 0x04 | (dst_reg << 3)); /*CVTSS2SD XMMx, [base_reg + idx_reg]*/ - codegen_addbyte(block, base_reg | (idx_reg << 3)); + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0xf3, 0x0f, 0x5a, 0x04 | (dst_reg << 3)); /*CVTSS2SD XMMx, [base_reg + idx_reg]*/ + codegen_addbyte(block, base_reg | (idx_reg << 3)); } void host_x86_DIVSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x5e, 0xc0 | src_reg | (dst_reg << 3)); /*DIVSD dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x5e, 0xc0 | src_reg | (dst_reg << 3)); /*DIVSD dst_reg, src_reg*/ } void host_x86_DIVSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf3, 0x0f, 0x5e, 0xc0 | src_reg | (dst_reg << 3)); /*DIVSS dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf3, 0x0f, 0x5e, 0xc0 | src_reg | (dst_reg << 3)); /*DIVSS dst_reg, src_reg*/ } void host_x86_LDMXCSR(codeblock_t *block, void *p) { - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - if (offset >= -128 && offset < 127) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x0f, 0xae, 0x50 | REG_EBP, offset); /*LDMXCSR offset[EBP]*/ - } else { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0x0f, 0xae, 0x15); /*LDMXCSR [p]*/ - codegen_addlong(block, (uint32_t)p); - } + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x0f, 0xae, 0x50 | REG_EBP, offset); /*LDMXCSR offset[EBP]*/ + } else { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0x0f, 0xae, 0x15); /*LDMXCSR [p]*/ + codegen_addlong(block, (uint32_t)p); + } } void host_x86_MAXSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x5f, 0xc0 | src_reg | (dst_reg << 3)); /*MAXSD dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x5f, 0xc0 | src_reg | (dst_reg << 3)); /*MAXSD dst_reg, src_reg*/ } void host_x86_MOVD_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x7e, 0x04 | (src_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/ - codegen_addbyte(block, base_reg | (idx_reg << 3)); + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x7e, 0x04 | (src_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/ + codegen_addbyte(block, base_reg | (idx_reg << 3)); } void host_x86_MOVD_REG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x7e, 0xc0 | dst_reg | (src_reg << 3)); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x7e, 0xc0 | dst_reg | (src_reg << 3)); } void host_x86_MOVD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x6e, 0x04 | (dst_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/ - codegen_addbyte(block, base_reg | (idx_reg << 3)); + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x6e, 0x04 | (dst_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/ + codegen_addbyte(block, base_reg | (idx_reg << 3)); } void host_x86_MOVD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x6e, 0xc0 | src_reg | (dst_reg << 3)); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x6e, 0xc0 | src_reg | (dst_reg << 3)); } void host_x86_MOVQ_ABS_XREG(codeblock_t *block, void *p, int src_reg) { - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - if (offset >= -128 && offset < 127) { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x45 | (src_reg << 3)); /*MOVQ offset[EBP], src_reg*/ - codegen_addbyte(block, offset); - } else { - codegen_alloc_bytes(block, 8); - codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x05 | (src_reg << 3)); /*MOVQ [p], src_reg*/ - codegen_addlong(block, (uint32_t)p); - } + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x45 | (src_reg << 3)); /*MOVQ offset[EBP], src_reg*/ + codegen_addbyte(block, offset); + } else { + codegen_alloc_bytes(block, 8); + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x05 | (src_reg << 3)); /*MOVQ [p], src_reg*/ + codegen_addlong(block, (uint32_t)p); + } } -void host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(codeblock_t *block, uint32_t addr, int src_reg_a, int src_reg_b, int shift, int src_reg) { - if (addr < 0x80 || addr >= 0xffffff80) { - codegen_alloc_bytes(block, 6); - codegen_addbyte3(block, 0x66, 0x0f, 0xd6); /*MOVQ addr[src_reg_a + src_reg_b << shift], XMMx*/ - codegen_addbyte3(block, 0x44 | (src_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6), addr & 0xff); - } else { - codegen_alloc_bytes(block, 9); - codegen_addbyte3(block, 0x66, 0x0f, 0xd6); /*MOVQ addr[src_reg_a + src_reg_b << shift], XMMx*/ - codegen_addbyte2(block, 0x84 | (src_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6)); - codegen_addlong(block, addr); - } +void host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(codeblock_t *block, uint32_t addr, int src_reg_a, int src_reg_b, int shift, + int src_reg) { + if (addr < 0x80 || addr >= 0xffffff80) { + codegen_alloc_bytes(block, 6); + codegen_addbyte3(block, 0x66, 0x0f, 0xd6); /*MOVQ addr[src_reg_a + src_reg_b << shift], XMMx*/ + codegen_addbyte3(block, 0x44 | (src_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6), addr & 0xff); + } else { + codegen_alloc_bytes(block, 9); + codegen_addbyte3(block, 0x66, 0x0f, 0xd6); /*MOVQ addr[src_reg_a + src_reg_b << shift], XMMx*/ + codegen_addbyte2(block, 0x84 | (src_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6)); + codegen_addlong(block, addr); + } } void host_x86_MOVQ_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x04 | (src_reg << 3)); /*MOVQ XMMx, [base_reg + idx_reg]*/ - codegen_addbyte(block, base_reg | (idx_reg << 3)); + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x04 | (src_reg << 3)); /*MOVQ XMMx, [base_reg + idx_reg]*/ + codegen_addbyte(block, base_reg | (idx_reg << 3)); } void host_x86_MOVQ_BASE_OFFSET_XREG(codeblock_t *block, int base_reg, int offset, int src_reg) { - if (offset >= -128 && offset < 127) { - if (base_reg == REG_ESP) { - codegen_alloc_bytes(block, 6); - codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x44 | (src_reg << 3)); /*MOVQ [ESP + offset], XMMx*/ - codegen_addbyte2(block, 0x24, offset); - } else { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x40 | base_reg | (src_reg << 3)); /*MOVQ [base_reg + offset], XMMx*/ - codegen_addbyte(block, offset); - } - } else - fatal("MOVQ_BASE_OFFSET_XREG - offset %i\n", offset); + if (offset >= -128 && offset < 127) { + if (base_reg == REG_ESP) { + codegen_alloc_bytes(block, 6); + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x44 | (src_reg << 3)); /*MOVQ [ESP + offset], XMMx*/ + codegen_addbyte2(block, 0x24, offset); + } else { + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, + 0x40 | base_reg | (src_reg << 3)); /*MOVQ [base_reg + offset], XMMx*/ + codegen_addbyte(block, offset); + } + } else + fatal("MOVQ_BASE_OFFSET_XREG - offset %i\n", offset); } void host_x86_MOVQ_STACK_OFFSET_XREG(codeblock_t *block, int offset, int src_reg) { - if (!offset) { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x04 | (src_reg << 3)); /*MOVQ [ESP], src_reg*/ - codegen_addbyte(block, 0x24); - } else if (offset >= -0x80 && offset < 0x80) { - codegen_alloc_bytes(block, 6); - codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x44 | (src_reg << 3)); /*MOVQ offset[ESP], src_reg*/ - codegen_addbyte2(block, 0x24, offset & 0xff); - } else { - codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x84 | (src_reg << 3)); /*MOVQ offset[ESP], src_reg*/ - codegen_addbyte(block, 0x24); - codegen_addlong(block, offset); - } - + if (!offset) { + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x04 | (src_reg << 3)); /*MOVQ [ESP], src_reg*/ + codegen_addbyte(block, 0x24); + } else if (offset >= -0x80 && offset < 0x80) { + codegen_alloc_bytes(block, 6); + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x44 | (src_reg << 3)); /*MOVQ offset[ESP], src_reg*/ + codegen_addbyte2(block, 0x24, offset & 0xff); + } else { + codegen_alloc_bytes(block, 9); + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x84 | (src_reg << 3)); /*MOVQ offset[ESP], src_reg*/ + codegen_addbyte(block, 0x24); + codegen_addlong(block, offset); + } } void host_x86_MOVQ_XREG_ABS(codeblock_t *block, int dst_reg, void *p) { - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - if (offset >= -128 && offset < 127) { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x45 | (dst_reg << 3)); /*MOVQ offset[EBP], src_reg*/ - codegen_addbyte(block, offset); - } else { - codegen_alloc_bytes(block, 8); - codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x05 | (dst_reg << 3)); /*MOVQ [p], src_reg*/ - codegen_addlong(block, (uint32_t)p); - } + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x45 | (dst_reg << 3)); /*MOVQ offset[EBP], src_reg*/ + codegen_addbyte(block, offset); + } else { + codegen_alloc_bytes(block, 8); + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x05 | (dst_reg << 3)); /*MOVQ [p], src_reg*/ + codegen_addlong(block, (uint32_t)p); + } } -void host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int src_reg_a, int src_reg_b, int shift) { - if (addr < 0x80 || addr >= 0xffffff80) { - codegen_alloc_bytes(block, 6); - codegen_addbyte3(block, 0xf3, 0x0f, 0x7e); /*MOVQ XMMx, addr[src_reg_a + src_reg_b << shift]*/ - codegen_addbyte3(block, 0x44 | (dst_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6), addr & 0xff); - } else { - codegen_alloc_bytes(block, 9); - codegen_addbyte3(block, 0xf3, 0x0f, 0x7e); /*MOVQ XMMx, addr[src_reg_a + src_reg_b << shift]*/ - codegen_addbyte2(block, 0x84 | (dst_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6)); - codegen_addlong(block, addr); - } +void host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int src_reg_a, int src_reg_b, + int shift) { + if (addr < 0x80 || addr >= 0xffffff80) { + codegen_alloc_bytes(block, 6); + codegen_addbyte3(block, 0xf3, 0x0f, 0x7e); /*MOVQ XMMx, addr[src_reg_a + src_reg_b << shift]*/ + codegen_addbyte3(block, 0x44 | (dst_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6), addr & 0xff); + } else { + codegen_alloc_bytes(block, 9); + codegen_addbyte3(block, 0xf3, 0x0f, 0x7e); /*MOVQ XMMx, addr[src_reg_a + src_reg_b << shift]*/ + codegen_addbyte2(block, 0x84 | (dst_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6)); + codegen_addlong(block, addr); + } } void host_x86_MOVQ_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x04 | (dst_reg << 3)); /*MOVQ XMMx, [base_reg + idx_reg]*/ - codegen_addbyte(block, base_reg | (idx_reg << 3)); + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x04 | (dst_reg << 3)); /*MOVQ XMMx, [base_reg + idx_reg]*/ + codegen_addbyte(block, base_reg | (idx_reg << 3)); } void host_x86_MOVQ_XREG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset) { - if (offset >= -128 && offset < 127) { - if (base_reg == REG_ESP) { - codegen_alloc_bytes(block, 6); - codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x44 | (dst_reg << 3)); /*MOVQ XMMx, [ESP + offset]*/ - codegen_addbyte2(block, 0x24, offset); - } else { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x40 | base_reg | (dst_reg << 3)); /*MOVQ XMMx, [base_reg + offset]*/ - codegen_addbyte(block, offset); - } - } else - fatal("MOVQ_REG_BASE_OFFSET - offset %i\n", offset); + if (offset >= -128 && offset < 127) { + if (base_reg == REG_ESP) { + codegen_alloc_bytes(block, 6); + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x44 | (dst_reg << 3)); /*MOVQ XMMx, [ESP + offset]*/ + codegen_addbyte2(block, 0x24, offset); + } else { + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, + 0x40 | base_reg | (dst_reg << 3)); /*MOVQ XMMx, [base_reg + offset]*/ + codegen_addbyte(block, offset); + } + } else + fatal("MOVQ_REG_BASE_OFFSET - offset %i\n", offset); } void host_x86_MOVQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0xc0 | src_reg | (dst_reg << 3)); /*MOVQ dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0xc0 | src_reg | (dst_reg << 3)); /*MOVQ dst_reg, src_reg*/ } void host_x86_MAXPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0x5f, 0xc0 | src_reg | (dst_reg << 3)); /*MAXPS dst_reg, src_reg*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0x5f, 0xc0 | src_reg | (dst_reg << 3)); /*MAXPS dst_reg, src_reg*/ } void host_x86_MINPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0x5d, 0xc0 | src_reg | (dst_reg << 3)); /*MINPS dst_reg, src_reg*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0x5d, 0xc0 | src_reg | (dst_reg << 3)); /*MINPS dst_reg, src_reg*/ } void host_x86_MULPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0x59, 0xc0 | src_reg | (dst_reg << 3)); /*MULPS dst_reg, src_reg*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0x59, 0xc0 | src_reg | (dst_reg << 3)); /*MULPS dst_reg, src_reg*/ } void host_x86_MULSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x59, 0xc0 | src_reg | (dst_reg << 3)); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x59, 0xc0 | src_reg | (dst_reg << 3)); } void host_x86_PACKSSWB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0x66, 0x0f, 0x63, 0xc0 | src_reg | (dst_reg << 3)); /*PACKSSWB dst_reg, src_reg*/ - codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ - codegen_addbyte(block, 0x88); + codegen_alloc_bytes(block, 9); + codegen_addbyte4(block, 0x66, 0x0f, 0x63, 0xc0 | src_reg | (dst_reg << 3)); /*PACKSSWB dst_reg, src_reg*/ + codegen_addbyte4(block, 0x66, 0x0f, 0x70, + 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ + codegen_addbyte(block, 0x88); } void host_x86_PACKSSDW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0x66, 0x0f, 0x6b, 0xc0 | src_reg | (dst_reg << 3)); /*PACKSSDW dst_reg, src_reg*/ - codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ - codegen_addbyte(block, 0x88); + codegen_alloc_bytes(block, 9); + codegen_addbyte4(block, 0x66, 0x0f, 0x6b, 0xc0 | src_reg | (dst_reg << 3)); /*PACKSSDW dst_reg, src_reg*/ + codegen_addbyte4(block, 0x66, 0x0f, 0x70, + 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ + codegen_addbyte(block, 0x88); } void host_x86_PACKUSWB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0x66, 0x0f, 0x67, 0xc0 | src_reg | (dst_reg << 3)); /*PACKUSWB dst_reg, src_reg*/ - codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ - codegen_addbyte(block, 0x88); + codegen_alloc_bytes(block, 9); + codegen_addbyte4(block, 0x66, 0x0f, 0x67, 0xc0 | src_reg | (dst_reg << 3)); /*PACKUSWB dst_reg, src_reg*/ + codegen_addbyte4(block, 0x66, 0x0f, 0x70, + 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ + codegen_addbyte(block, 0x88); } void host_x86_PADDB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xfc, 0xc0 | src_reg | (dst_reg << 3)); /*PADDB dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xfc, 0xc0 | src_reg | (dst_reg << 3)); /*PADDB dst_reg, src_reg*/ } void host_x86_PADDW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xfd, 0xc0 | src_reg | (dst_reg << 3)); /*PADDW dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xfd, 0xc0 | src_reg | (dst_reg << 3)); /*PADDW dst_reg, src_reg*/ } void host_x86_PADDD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xfe, 0xc0 | src_reg | (dst_reg << 3)); /*PADDD dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xfe, 0xc0 | src_reg | (dst_reg << 3)); /*PADDD dst_reg, src_reg*/ } void host_x86_PADDSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xec, 0xc0 | src_reg | (dst_reg << 3)); /*PADDSB dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xec, 0xc0 | src_reg | (dst_reg << 3)); /*PADDSB dst_reg, src_reg*/ } void host_x86_PADDSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xed, 0xc0 | src_reg | (dst_reg << 3)); /*PADDSW dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xed, 0xc0 | src_reg | (dst_reg << 3)); /*PADDSW dst_reg, src_reg*/ } void host_x86_PADDUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xdc, 0xc0 | src_reg | (dst_reg << 3)); /*PADDUSB dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xdc, 0xc0 | src_reg | (dst_reg << 3)); /*PADDUSB dst_reg, src_reg*/ } void host_x86_PADDUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xdd, 0xc0 | src_reg | (dst_reg << 3)); /*PADDUSW dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xdd, 0xc0 | src_reg | (dst_reg << 3)); /*PADDUSW dst_reg, src_reg*/ } void host_x86_PAND_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xdb, 0xc0 | src_reg | (dst_reg << 3)); /*PAND dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xdb, 0xc0 | src_reg | (dst_reg << 3)); /*PAND dst_reg, src_reg*/ } void host_x86_PANDN_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xdf, 0xc0 | src_reg | (dst_reg << 3)); /*PANDN dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xdf, 0xc0 | src_reg | (dst_reg << 3)); /*PANDN dst_reg, src_reg*/ } void host_x86_POR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xeb, 0xc0 | src_reg | (dst_reg << 3)); /*POR dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xeb, 0xc0 | src_reg | (dst_reg << 3)); /*POR dst_reg, src_reg*/ } void host_x86_PXOR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xef, 0xc0 | src_reg | (dst_reg << 3)); /*PXOR dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xef, 0xc0 | src_reg | (dst_reg << 3)); /*PXOR dst_reg, src_reg*/ } void host_x86_PCMPEQB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x74, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQB dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x74, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQB dst_reg, src_reg*/ } void host_x86_PCMPEQW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x75, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQW dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x75, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQW dst_reg, src_reg*/ } void host_x86_PCMPEQD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x76, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQD dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x76, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQD dst_reg, src_reg*/ } void host_x86_PCMPGTB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x64, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTB dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x64, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTB dst_reg, src_reg*/ } void host_x86_PCMPGTW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x65, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTW dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x65, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTW dst_reg, src_reg*/ } void host_x86_PCMPGTD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x66, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTD dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x66, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTD dst_reg, src_reg*/ } void host_x86_PMADDWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xf5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xf5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ } void host_x86_PMULHW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xe5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xe5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ } void host_x86_PMULLW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xd5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xd5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ } void host_x86_PSHUFD_XREG_XREG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t shuffle) { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | src_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0xee (move top 64-bits to low 64-bits)*/ - codegen_addbyte(block, shuffle); + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x70, + 0xc0 | src_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0xee (move top 64-bits to low 64-bits)*/ + codegen_addbyte(block, shuffle); } void host_x86_PSLLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x30 | dst_reg); /*PSLLW dst_reg, imm*/ - codegen_addbyte(block, shift); + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x30 | dst_reg); /*PSLLW dst_reg, imm*/ + codegen_addbyte(block, shift); } void host_x86_PSLLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift) { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x30 | dst_reg); /*PSLLD dst_reg, imm*/ - codegen_addbyte(block, shift); + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x30 | dst_reg); /*PSLLD dst_reg, imm*/ + codegen_addbyte(block, shift); } void host_x86_PSLLQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift) { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x30 | dst_reg); /*PSLLD dst_reg, imm*/ - codegen_addbyte(block, shift); + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x30 | dst_reg); /*PSLLD dst_reg, imm*/ + codegen_addbyte(block, shift); } void host_x86_PSRAW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x20 | dst_reg); /*PSRAW dst_reg, imm*/ - codegen_addbyte(block, shift); + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x20 | dst_reg); /*PSRAW dst_reg, imm*/ + codegen_addbyte(block, shift); } void host_x86_PSRAD_XREG_IMM(codeblock_t *block, int dst_reg, int shift) { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x20 | dst_reg); /*PSRAD dst_reg, imm*/ - codegen_addbyte(block, shift); + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x20 | dst_reg); /*PSRAD dst_reg, imm*/ + codegen_addbyte(block, shift); } void host_x86_PSRAQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift) { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x20 | dst_reg); /*PSRAD dst_reg, imm*/ - codegen_addbyte(block, shift); + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x20 | dst_reg); /*PSRAD dst_reg, imm*/ + codegen_addbyte(block, shift); } void host_x86_PSRLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x10 | dst_reg); /*PSRLW dst_reg, imm*/ - codegen_addbyte(block, shift); + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x10 | dst_reg); /*PSRLW dst_reg, imm*/ + codegen_addbyte(block, shift); } void host_x86_PSRLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift) { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x10 | dst_reg); /*PSRLD dst_reg, imm*/ - codegen_addbyte(block, shift); + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x10 | dst_reg); /*PSRLD dst_reg, imm*/ + codegen_addbyte(block, shift); } void host_x86_PSRLQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift) { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x10 | dst_reg); /*PSRLD dst_reg, imm*/ - codegen_addbyte(block, shift); + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x10 | dst_reg); /*PSRLD dst_reg, imm*/ + codegen_addbyte(block, shift); } void host_x86_PSUBB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xf8, 0xc0 | src_reg | (dst_reg << 3)); /*PADDB dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xf8, 0xc0 | src_reg | (dst_reg << 3)); /*PADDB dst_reg, src_reg*/ } void host_x86_PSUBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xf9, 0xc0 | src_reg | (dst_reg << 3)); /*PADDW dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xf9, 0xc0 | src_reg | (dst_reg << 3)); /*PADDW dst_reg, src_reg*/ } void host_x86_PSUBD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xfa, 0xc0 | src_reg | (dst_reg << 3)); /*PADDD dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xfa, 0xc0 | src_reg | (dst_reg << 3)); /*PADDD dst_reg, src_reg*/ } void host_x86_PSUBSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xe8, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBSB dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xe8, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBSB dst_reg, src_reg*/ } void host_x86_PSUBSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xe9, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBSW dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xe9, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBSW dst_reg, src_reg*/ } void host_x86_PSUBUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xd8, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBUSB dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xd8, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBUSB dst_reg, src_reg*/ } void host_x86_PSUBUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xd9, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBUSW dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xd9, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBUSW dst_reg, src_reg*/ } void host_x86_PUNPCKLBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x60, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLBW dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x60, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLBW dst_reg, src_reg*/ } void host_x86_PUNPCKLWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x61, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLWD dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x61, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLWD dst_reg, src_reg*/ } void host_x86_PUNPCKLDQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x62, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLDQ dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x62, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLDQ dst_reg, src_reg*/ } void host_x86_SQRTSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x51, 0xc0 | src_reg | (dst_reg << 3)); /*SQRTSD dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x51, 0xc0 | src_reg | (dst_reg << 3)); /*SQRTSD dst_reg, src_reg*/ } void host_x86_SQRTSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf3, 0x0f, 0x51, 0xc0 | src_reg | (dst_reg << 3)); /*SQRTSS dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf3, 0x0f, 0x51, 0xc0 | src_reg | (dst_reg << 3)); /*SQRTSS dst_reg, src_reg*/ } void host_x86_SUBPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0x5c, 0xc0 | src_reg | (dst_reg << 3)); /*SUBPS dst_reg, src_reg*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0x5c, 0xc0 | src_reg | (dst_reg << 3)); /*SUBPS dst_reg, src_reg*/ } void host_x86_SUBSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x5c, 0xc0 | src_reg | (dst_reg << 3)); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x5c, 0xc0 | src_reg | (dst_reg << 3)); } void host_x86_UNPCKLPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0x14, 0xc0 | src_reg | (dst_reg << 3)); + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0x14, 0xc0 | src_reg | (dst_reg << 3)); } #endif diff --git a/src/codegen/x86/codegen_backend_x86_uops.c b/src/codegen/x86/codegen_backend_x86_uops.c index 4acab300..4ba2bd85 100644 --- a/src/codegen/x86/codegen_backend_x86_uops.c +++ b/src/codegen/x86/codegen_backend_x86_uops.c @@ -18,12 +18,12 @@ pclog(" %04x:%04x : %08x %08x %08x %08x\n", CS, cpu_state.pc, AX, BX, CX, DX); }*/ -#define HOST_REG_IS_L(reg) (IREG_GET_SIZE(reg) == IREG_SIZE_L) -#define HOST_REG_IS_W(reg) (IREG_GET_SIZE(reg) == IREG_SIZE_W) -#define HOST_REG_IS_B(reg) (IREG_GET_SIZE(reg) == IREG_SIZE_B && IREG_GET_REG(reg) < 4) +#define HOST_REG_IS_L(reg) (IREG_GET_SIZE(reg) == IREG_SIZE_L) +#define HOST_REG_IS_W(reg) (IREG_GET_SIZE(reg) == IREG_SIZE_W) +#define HOST_REG_IS_B(reg) (IREG_GET_SIZE(reg) == IREG_SIZE_B && IREG_GET_REG(reg) < 4) #define HOST_REG_IS_BH(reg) (IREG_GET_SIZE(reg) == IREG_SIZE_BH && IREG_GET_REG(reg) < 4) -#define HOST_REG_GET(reg) ((IREG_GET_SIZE(reg) == IREG_SIZE_BH) ? (IREG_GET_REG((reg) & 3) | 4) : (IREG_GET_REG(reg) & 7)) +#define HOST_REG_GET(reg) ((IREG_GET_SIZE(reg) == IREG_SIZE_BH) ? (IREG_GET_REG((reg)&3) | 4) : (IREG_GET_REG(reg) & 7)) #define REG_IS_L(size) (size == IREG_SIZE_L) #define REG_IS_W(size) (size == IREG_SIZE_W) @@ -33,2613 +33,2617 @@ #define REG_IS_Q(size) (size == IREG_SIZE_Q) static int codegen_ADD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_LEA_REG_REG(block, dest_reg, src_reg_a, src_reg_b); - else - host_x86_ADD32_REG_REG(block, dest_reg, src_reg_b); - } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); - host_x86_ADD16_REG_REG(block, dest_reg, src_reg_b); - } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); - host_x86_ADD8_REG_REG(block, dest_reg, src_reg_b); - } + if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_LEA_REG_REG(block, dest_reg, src_reg_a, src_reg_b); + else + host_x86_ADD32_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); + host_x86_ADD16_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); + host_x86_ADD8_REG_REG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("ADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("ADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_ADD_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_LEA_REG_IMM(block, dest_reg, src_reg, uop->imm_data); - else - host_x86_ADD32_REG_IMM(block, dest_reg, uop->imm_data); - } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_ADD16_REG_IMM(block, dest_reg, uop->imm_data); - } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_ADD8_REG_IMM(block, dest_reg, uop->imm_data); - } + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_LEA_REG_IMM(block, dest_reg, src_reg, uop->imm_data); + else + host_x86_ADD32_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_ADD16_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_ADD8_REG_IMM(block, dest_reg, uop->imm_data); + } #ifdef RECOMPILER_DEBUG - else - fatal("ADD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("ADD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_ADD_LSHIFT(codeblock_t *block, uop_t *uop) { - if (!uop->imm_data) { - if (uop->dest_reg_a_real == uop->src_reg_a_real) - host_x86_ADD32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_b_real); - else - host_x86_LEA_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - } else if (uop->imm_data < 4) - host_x86_LEA_REG_REG_SHIFT(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, uop->imm_data); + if (!uop->imm_data) { + if (uop->dest_reg_a_real == uop->src_reg_a_real) + host_x86_ADD32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_b_real); + else + host_x86_LEA_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + } else if (uop->imm_data < 4) + host_x86_LEA_REG_REG_SHIFT(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, uop->imm_data); #ifdef RECOMPILER_DEBUG - else - fatal("codegen_ADD_LSHIFT - shift out of range %i\n", uop->imm_data); + else + fatal("codegen_ADD_LSHIFT - shift out of range %i\n", uop->imm_data); #endif - return 0; + return 0; } static int codegen_AND(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PAND_XREG_XREG(block, dest_reg, src_reg_b); - } else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a); - host_x86_AND32_REG_REG(block, dest_reg, src_reg_b); - } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); - host_x86_AND16_REG_REG(block, dest_reg, src_reg_b); - } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); - host_x86_AND8_REG_REG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PAND_XREG_XREG(block, dest_reg, src_reg_b); + } else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a); + host_x86_AND32_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); + host_x86_AND16_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); + host_x86_AND8_REG_REG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("AND %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("AND %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_AND32_REG_IMM(block, dest_reg, uop->imm_data); - } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_AND16_REG_IMM(block, dest_reg, uop->imm_data); - } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_AND8_REG_IMM(block, dest_reg, uop->imm_data); - } + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_AND32_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_AND16_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_AND8_REG_IMM(block, dest_reg, uop->imm_data); + } #ifdef RECOMPILER_DEBUG - else - fatal("AND_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("AND_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_ANDN(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), /*src_reg_a = HOST_REG_GET(uop->src_reg_a_real), */src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), + /*src_reg_a = HOST_REG_GET(uop->src_reg_a_real), */ src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PANDN_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PANDN_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("ANDN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("ANDN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_CALL_FUNC(codeblock_t *block, uop_t *uop) { - host_x86_CALL(block, uop->p); + host_x86_CALL(block, uop->p); - return 0; + return 0; } static int codegen_CALL_FUNC_RESULT(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); #ifdef RECOMPILER_DEBUG - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - if (!REG_IS_L(dest_size)) - fatal("CALL_FUNC_RESULT %02x\n", uop->dest_reg_a_real); + if (!REG_IS_L(dest_size)) + fatal("CALL_FUNC_RESULT %02x\n", uop->dest_reg_a_real); #endif - host_x86_CALL(block, uop->p); - host_x86_MOV32_REG_REG(block, dest_reg, REG_EAX); + host_x86_CALL(block, uop->p); + host_x86_MOV32_REG_REG(block, dest_reg, REG_EAX); - return 0; + return 0; } static int codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop) { - host_x86_CALL(block, uop->p); - host_x86_TEST32_REG(block, REG_EAX, REG_EAX); - host_x86_JNZ(block, codegen_exit_rout); -// host_x86_CALL(block, codegen_debug); + host_x86_CALL(block, uop->p); + host_x86_TEST32_REG(block, REG_EAX, REG_EAX); + host_x86_JNZ(block, codegen_exit_rout); + // host_x86_CALL(block, codegen_debug); - return 0; + return 0; } static int codegen_CMP_IMM_JZ(codeblock_t *block, uop_t *uop) { - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(src_size)) { - host_x86_CMP32_REG_IMM(block, src_reg, uop->imm_data); - } + if (REG_IS_L(src_size)) { + host_x86_CMP32_REG_IMM(block, src_reg, uop->imm_data); + } #ifdef RECOMPILER_DEBUG - else - fatal("CMP_IMM_JZ %02x\n", uop->src_reg_a_real); + else + fatal("CMP_IMM_JZ %02x\n", uop->src_reg_a_real); #endif - host_x86_JZ(block, uop->p); + host_x86_JZ(block, uop->p); - return 0; + return 0; } static int codegen_CMP_IMM_JNZ_DEST(codeblock_t *block, uop_t *uop) { - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(src_size)) { - host_x86_CMP32_REG_IMM(block, src_reg, uop->imm_data); - } else if (REG_IS_W(src_size)) { - host_x86_CMP16_REG_IMM(block, src_reg, uop->imm_data); - } + if (REG_IS_L(src_size)) { + host_x86_CMP32_REG_IMM(block, src_reg, uop->imm_data); + } else if (REG_IS_W(src_size)) { + host_x86_CMP16_REG_IMM(block, src_reg, uop->imm_data); + } #ifdef RECOMPILER_DEBUG - else - fatal("CMP_IMM_JNZ_DEST %02x\n", uop->src_reg_a_real); + else + fatal("CMP_IMM_JNZ_DEST %02x\n", uop->src_reg_a_real); #endif - uop->p = host_x86_JNZ_long(block); + uop->p = host_x86_JNZ_long(block); - return 0; + return 0; } static int codegen_CMP_IMM_JZ_DEST(codeblock_t *block, uop_t *uop) { - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(src_size)) { - host_x86_CMP32_REG_IMM(block, src_reg, uop->imm_data); - } else if (REG_IS_W(src_size)) { - host_x86_CMP16_REG_IMM(block, src_reg, uop->imm_data); - } + if (REG_IS_L(src_size)) { + host_x86_CMP32_REG_IMM(block, src_reg, uop->imm_data); + } else if (REG_IS_W(src_size)) { + host_x86_CMP16_REG_IMM(block, src_reg, uop->imm_data); + } #ifdef RECOMPILER_DEBUG - else - fatal("CMP_IMM_JZ_DEST %02x\n", uop->src_reg_a_real); + else + fatal("CMP_IMM_JZ_DEST %02x\n", uop->src_reg_a_real); #endif - uop->p = host_x86_JZ_long(block); + uop->p = host_x86_JZ_long(block); - return 0; + return 0; } static int codegen_CMP_JB(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - uint32_t *jump_p; + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + uint32_t *jump_p; - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("CMP_JB %02x\n", uop->src_reg_a_real); + else + fatal("CMP_JB %02x\n", uop->src_reg_a_real); #endif - jump_p = host_x86_JB_long(block); - *jump_p = (uintptr_t)uop->p - ((uintptr_t)jump_p + 4); + jump_p = host_x86_JB_long(block); + *jump_p = (uintptr_t)uop->p - ((uintptr_t)jump_p + 4); - return 0; + return 0; } static int codegen_CMP_JNBE(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - uint32_t *jump_p; + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + uint32_t *jump_p; - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("CMP_JNBE %02x\n", uop->src_reg_a_real); + else + fatal("CMP_JNBE %02x\n", uop->src_reg_a_real); #endif - jump_p = host_x86_JNBE_long(block); - *jump_p = (uintptr_t)uop->p - ((uintptr_t)jump_p + 4); + jump_p = host_x86_JNBE_long(block); + *jump_p = (uintptr_t)uop->p - ((uintptr_t)jump_p + 4); - return 0; + return 0; } static int codegen_CMP_JNB_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("CMP_JNB_DEST %02x\n", uop->src_reg_a_real); + else + fatal("CMP_JNB_DEST %02x\n", uop->src_reg_a_real); #endif - uop->p = host_x86_JNB_long(block); + uop->p = host_x86_JNB_long(block); - return 0; + return 0; } static int codegen_CMP_JNBE_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("CMP_JNBE_DEST %02x\n", uop->src_reg_a_real); + else + fatal("CMP_JNBE_DEST %02x\n", uop->src_reg_a_real); #endif - uop->p = host_x86_JNBE_long(block); + uop->p = host_x86_JNBE_long(block); - return 0; + return 0; } static int codegen_CMP_JNL_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("CMP_JNL_DEST %02x\n", uop->src_reg_a_real); + else + fatal("CMP_JNL_DEST %02x\n", uop->src_reg_a_real); #endif - uop->p = host_x86_JNL_long(block); + uop->p = host_x86_JNL_long(block); - return 0; + return 0; } static int codegen_CMP_JNLE_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("CMP_JNLE_DEST %02x\n", uop->src_reg_a_real); + else + fatal("CMP_JNLE_DEST %02x\n", uop->src_reg_a_real); #endif - uop->p = host_x86_JNLE_long(block); + uop->p = host_x86_JNLE_long(block); - return 0; + return 0; } static int codegen_CMP_JNO_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("CMP_JNO_DEST %02x\n", uop->src_reg_a_real); + else + fatal("CMP_JNO_DEST %02x\n", uop->src_reg_a_real); #endif - uop->p = host_x86_JNO_long(block); + uop->p = host_x86_JNO_long(block); - return 0; + return 0; } static int codegen_CMP_JNZ_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("CMP_JNZ_DEST %02x\n", uop->src_reg_a_real); + else + fatal("CMP_JNZ_DEST %02x\n", uop->src_reg_a_real); #endif - uop->p = host_x86_JNZ_long(block); + uop->p = host_x86_JNZ_long(block); - return 0; + return 0; } static int codegen_CMP_JB_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("CMP_JB_DEST %02x\n", uop->src_reg_a_real); + else + fatal("CMP_JB_DEST %02x\n", uop->src_reg_a_real); #endif - uop->p = host_x86_JB_long(block); + uop->p = host_x86_JB_long(block); - return 0; + return 0; } static int codegen_CMP_JBE_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("CMP_JBE_DEST %02x\n", uop->src_reg_a_real); + else + fatal("CMP_JBE_DEST %02x\n", uop->src_reg_a_real); #endif - uop->p = host_x86_JBE_long(block); + uop->p = host_x86_JBE_long(block); - return 0; + return 0; } static int codegen_CMP_JL_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("CMP_JL_DEST %02x\n", uop->src_reg_a_real); + else + fatal("CMP_JL_DEST %02x\n", uop->src_reg_a_real); #endif - uop->p = host_x86_JL_long(block); + uop->p = host_x86_JL_long(block); - return 0; + return 0; } static int codegen_CMP_JLE_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("CMP_JLE_DEST %02x\n", uop->src_reg_a_real); + else + fatal("CMP_JLE_DEST %02x\n", uop->src_reg_a_real); #endif - uop->p = host_x86_JLE_long(block); + uop->p = host_x86_JLE_long(block); - return 0; + return 0; } static int codegen_CMP_JO_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("CMP_JO_DEST %02x\n", uop->src_reg_a_real); + else + fatal("CMP_JO_DEST %02x\n", uop->src_reg_a_real); #endif - uop->p = host_x86_JO_long(block); + uop->p = host_x86_JO_long(block); - return 0; + return 0; } static int codegen_CMP_JZ_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("CMP_JZ_DEST %02x\n", uop->src_reg_a_real); + else + fatal("CMP_JZ_DEST %02x\n", uop->src_reg_a_real); #endif - uop->p = host_x86_JZ_long(block); + uop->p = host_x86_JZ_long(block); - return 0; + return 0; } static int codegen_FABS(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && dest_reg == src_reg_a) { - host_x86_PXOR_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP); - host_x86_SUBSD_XREG_XREG(block, REG_XMM_TEMP, dest_reg); - host_x86_MAXSD_XREG_XREG(block, dest_reg, REG_XMM_TEMP); - } + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && dest_reg == src_reg_a) { + host_x86_PXOR_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP); + host_x86_SUBSD_XREG_XREG(block, REG_XMM_TEMP, dest_reg); + host_x86_MAXSD_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + } #ifdef RECOMPILER_DEBUG - else - fatal("codegen_FABS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("codegen_FABS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_FCHS(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) { - host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); - host_x86_PXOR_XREG_XREG(block, dest_reg, dest_reg); - host_x86_SUBSD_XREG_XREG(block, dest_reg, REG_XMM_TEMP); - } + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) { + host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); + host_x86_PXOR_XREG_XREG(block, dest_reg, dest_reg); + host_x86_SUBSD_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + } #ifdef RECOMPILER_DEBUG - else - fatal("codegen_FCHS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("codegen_FCHS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_FSQRT(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) { - host_x86_SQRTSD_XREG_XREG(block, dest_reg, src_reg_a); - } + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) { + host_x86_SQRTSD_XREG_XREG(block, dest_reg, src_reg_a); + } #ifdef RECOMPILER_DEBUG - else - fatal("codegen_FSQRT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("codegen_FSQRT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_FTST(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_W(dest_size) && REG_IS_D(src_size_a)) { - host_x86_PXOR_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP); - if (dest_reg != REG_EAX) - host_x86_MOV32_REG_REG(block, REG_ECX, REG_EAX); - host_x86_XOR32_REG_REG(block, REG_EAX, REG_EAX); - host_x86_COMISD_XREG_XREG(block, src_reg_a, REG_XMM_TEMP); - host_x86_LAHF(block); - host_x86_AND16_REG_IMM(block, REG_EAX, C0 | C2 | C3); - if (dest_reg != REG_EAX) { - host_x86_MOV16_REG_REG(block, dest_reg, REG_EAX); - host_x86_MOV32_REG_REG(block, REG_EAX, REG_ECX); - } - } + if (REG_IS_W(dest_size) && REG_IS_D(src_size_a)) { + host_x86_PXOR_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP); + if (dest_reg != REG_EAX) + host_x86_MOV32_REG_REG(block, REG_ECX, REG_EAX); + host_x86_XOR32_REG_REG(block, REG_EAX, REG_EAX); + host_x86_COMISD_XREG_XREG(block, src_reg_a, REG_XMM_TEMP); + host_x86_LAHF(block); + host_x86_AND16_REG_IMM(block, REG_EAX, C0 | C2 | C3); + if (dest_reg != REG_EAX) { + host_x86_MOV16_REG_REG(block, dest_reg, REG_EAX); + host_x86_MOV32_REG_REG(block, REG_EAX, REG_ECX); + } + } #ifdef RECOMPILER_DEBUG - else - fatal("codegen_FTST %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("codegen_FTST %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_FADD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) { - host_x86_ADDSD_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) { + host_x86_ADDSD_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("codegen_FADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("codegen_FADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_FCOM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_W(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { - if (dest_reg != REG_EAX) - host_x86_MOV32_REG_REG(block, REG_ECX, REG_EAX); - host_x86_XOR32_REG_REG(block, REG_EAX, REG_EAX); - host_x86_COMISD_XREG_XREG(block, src_reg_a, src_reg_b); - host_x86_LAHF(block); - host_x86_AND16_REG_IMM(block, REG_EAX, C0 | C2 | C3); - if (dest_reg != REG_EAX) { - host_x86_MOV16_REG_REG(block, dest_reg, REG_EAX); - host_x86_MOV32_REG_REG(block, REG_EAX, REG_ECX); - } - } + if (REG_IS_W(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { + if (dest_reg != REG_EAX) + host_x86_MOV32_REG_REG(block, REG_ECX, REG_EAX); + host_x86_XOR32_REG_REG(block, REG_EAX, REG_EAX); + host_x86_COMISD_XREG_XREG(block, src_reg_a, src_reg_b); + host_x86_LAHF(block); + host_x86_AND16_REG_IMM(block, REG_EAX, C0 | C2 | C3); + if (dest_reg != REG_EAX) { + host_x86_MOV16_REG_REG(block, dest_reg, REG_EAX); + host_x86_MOV32_REG_REG(block, REG_EAX, REG_ECX); + } + } #ifdef RECOMPILER_DEBUG - else - fatal("codegen_FCOM %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("codegen_FCOM %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_FDIV(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) { - host_x86_DIVSD_XREG_XREG(block, dest_reg, src_reg_b); - } else if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { - host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); - host_x86_DIVSD_XREG_XREG(block, REG_XMM_TEMP, src_reg_b); - host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); - } + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) { + host_x86_DIVSD_XREG_XREG(block, dest_reg, src_reg_b); + } else if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { + host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); + host_x86_DIVSD_XREG_XREG(block, REG_XMM_TEMP, src_reg_b); + host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + } #ifdef RECOMPILER_DEBUG - else - fatal("codegen_FDIV %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("codegen_FDIV %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_FMUL(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) { - host_x86_MULSD_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) { + host_x86_MULSD_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("codegen_FMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("codegen_FMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_FSUB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) { - host_x86_SUBSD_XREG_XREG(block, dest_reg, src_reg_b); - } else if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { - host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); - host_x86_SUBSD_XREG_XREG(block, REG_XMM_TEMP, src_reg_b); - host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); - } + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) { + host_x86_SUBSD_XREG_XREG(block, dest_reg, src_reg_b); + } else if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { + host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); + host_x86_SUBSD_XREG_XREG(block, REG_XMM_TEMP, src_reg_b); + host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + } #ifdef RECOMPILER_DEBUG - else - fatal("codegen_FSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("codegen_FSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_FP_ENTER(codeblock_t *block, uop_t *uop) { - uint32_t *branch_offset; + uint32_t *branch_offset; - host_x86_MOV32_REG_ABS(block, REG_ECX, &cr0); - host_x86_TEST32_REG_IMM(block, REG_ECX, 0xc); - branch_offset = host_x86_JZ_long(block); - host_x86_MOV32_ABS_IMM(block, &cpu_state.oldpc, uop->imm_data); - host_x86_MOV32_STACK_IMM(block, STACK_ARG0, 7); - host_x86_CALL(block, x86_int); - host_x86_JMP(block, codegen_exit_rout); - *branch_offset = (uint32_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 4; + host_x86_MOV32_REG_ABS(block, REG_ECX, &cr0); + host_x86_TEST32_REG_IMM(block, REG_ECX, 0xc); + branch_offset = host_x86_JZ_long(block); + host_x86_MOV32_ABS_IMM(block, &cpu_state.oldpc, uop->imm_data); + host_x86_MOV32_STACK_IMM(block, STACK_ARG0, 7); + host_x86_CALL(block, x86_int); + host_x86_JMP(block, codegen_exit_rout); + *branch_offset = (uint32_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 4; - return 0; + return 0; } static int codegen_MMX_ENTER(codeblock_t *block, uop_t *uop) { - uint32_t *branch_offset; + uint32_t *branch_offset; - host_x86_MOV32_REG_ABS(block, REG_ECX, &cr0); - host_x86_TEST32_REG_IMM(block, REG_ECX, 0xc); - branch_offset = host_x86_JZ_long(block); - host_x86_MOV32_ABS_IMM(block, &cpu_state.oldpc, uop->imm_data); - host_x86_MOV32_STACK_IMM(block, STACK_ARG0, 7); - host_x86_CALL(block, x86_int); - host_x86_JMP(block, codegen_exit_rout); - *branch_offset = (uint32_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 4; - host_x86_MOV32_ABS_IMM(block, &cpu_state.tag[0], 0x01010101); - host_x86_MOV32_ABS_IMM(block, &cpu_state.tag[4], 0x01010101); - host_x86_MOV32_ABS_IMM(block, &cpu_state.TOP, 0); - host_x86_MOV8_ABS_IMM(block, &cpu_state.ismmx, 1); + host_x86_MOV32_REG_ABS(block, REG_ECX, &cr0); + host_x86_TEST32_REG_IMM(block, REG_ECX, 0xc); + branch_offset = host_x86_JZ_long(block); + host_x86_MOV32_ABS_IMM(block, &cpu_state.oldpc, uop->imm_data); + host_x86_MOV32_STACK_IMM(block, STACK_ARG0, 7); + host_x86_CALL(block, x86_int); + host_x86_JMP(block, codegen_exit_rout); + *branch_offset = (uint32_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 4; + host_x86_MOV32_ABS_IMM(block, &cpu_state.tag[0], 0x01010101); + host_x86_MOV32_ABS_IMM(block, &cpu_state.tag[4], 0x01010101); + host_x86_MOV32_ABS_IMM(block, &cpu_state.TOP, 0); + host_x86_MOV8_ABS_IMM(block, &cpu_state.ismmx, 1); - return 0; + return 0; } static int codegen_JMP(codeblock_t *block, uop_t *uop) { - host_x86_JMP(block, uop->p); + host_x86_JMP(block, uop->p); - return 0; + return 0; } static int codegen_JMP_DEST(codeblock_t *block, uop_t *uop) { - uop->p = host_x86_JMP_long(block); + uop->p = host_x86_JMP_long(block); - return 0; + return 0; } static int codegen_LOAD_FUNC_ARG0(codeblock_t *block, uop_t *uop) { - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_W(src_size)) { - host_x86_MOV16_STACK_REG(block, STACK_ARG0, src_reg); - } + if (REG_IS_W(src_size)) { + host_x86_MOV16_STACK_REG(block, STACK_ARG0, src_reg); + } #ifdef RECOMPILER_DEBUG - else - fatal("codegen_LOAD_FUNC_ARG0 %02x\n", uop->src_reg_a_real); + else + fatal("codegen_LOAD_FUNC_ARG0 %02x\n", uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_LOAD_FUNC_ARG1(codeblock_t *block, uop_t *uop) { #ifdef RECOMPILER_DEBUG - fatal("codegen_LOAD_FUNC_ARG1 %02x\n", uop->src_reg_a_real); + fatal("codegen_LOAD_FUNC_ARG1 %02x\n", uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_LOAD_FUNC_ARG2(codeblock_t *block, uop_t *uop) { #ifdef RECOMPILER_DEBUG - fatal("codegen_LOAD_FUNC_ARG2 %02x\n", uop->src_reg_a_real); + fatal("codegen_LOAD_FUNC_ARG2 %02x\n", uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_LOAD_FUNC_ARG3(codeblock_t *block, uop_t *uop) { #ifdef RECOMPILER_DEBUG - fatal("codegen_LOAD_FUNC_ARG3 %02x\n", uop->src_reg_a_real); + fatal("codegen_LOAD_FUNC_ARG3 %02x\n", uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_LOAD_FUNC_ARG0_IMM(codeblock_t *block, uop_t *uop) { - host_x86_MOV32_STACK_IMM(block, STACK_ARG0, uop->imm_data); - return 0; + host_x86_MOV32_STACK_IMM(block, STACK_ARG0, uop->imm_data); + return 0; } static int codegen_LOAD_FUNC_ARG1_IMM(codeblock_t *block, uop_t *uop) { - host_x86_MOV32_STACK_IMM(block, STACK_ARG1, uop->imm_data); - return 0; + host_x86_MOV32_STACK_IMM(block, STACK_ARG1, uop->imm_data); + return 0; } static int codegen_LOAD_FUNC_ARG2_IMM(codeblock_t *block, uop_t *uop) { - host_x86_MOV32_STACK_IMM(block, STACK_ARG2, uop->imm_data); - return 0; + host_x86_MOV32_STACK_IMM(block, STACK_ARG2, uop->imm_data); + return 0; } static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop) { - host_x86_MOV32_STACK_IMM(block, STACK_ARG3, uop->imm_data); - return 0; + host_x86_MOV32_STACK_IMM(block, STACK_ARG3, uop->imm_data); + return 0; } static int codegen_LOAD_SEG(codeblock_t *block, uop_t *uop) { - int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); #ifdef RECOMPILER_DEBUG - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (!REG_IS_W(src_size)) - fatal("LOAD_SEG %02x %p\n", uop->src_reg_a_real, uop->p); + if (!REG_IS_W(src_size)) + fatal("LOAD_SEG %02x %p\n", uop->src_reg_a_real, uop->p); #endif - host_x86_MOV16_STACK_REG(block, STACK_ARG0, src_reg); - host_x86_MOV32_STACK_IMM(block, STACK_ARG1, (uint32_t)uop->p); - host_x86_CALL(block, loadseg); - host_x86_TEST32_REG(block, REG_EAX, REG_EAX); - host_x86_JNZ(block, codegen_exit_rout); + host_x86_MOV16_STACK_REG(block, STACK_ARG0, src_reg); + host_x86_MOV32_STACK_IMM(block, STACK_ARG1, (uint32_t)uop->p); + host_x86_CALL(block, loadseg); + host_x86_TEST32_REG(block, REG_EAX, REG_EAX); + host_x86_JNZ(block, codegen_exit_rout); - return 0; + return 0; } static int codegen_MEM_LOAD_ABS(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - host_x86_LEA_REG_IMM(block, REG_ESI, seg_reg, uop->imm_data); - if (REG_IS_B(dest_size)) { - host_x86_CALL(block, codegen_mem_load_byte); - } else if (REG_IS_W(dest_size)) { - host_x86_CALL(block, codegen_mem_load_word); - } else if (REG_IS_L(dest_size)) { - host_x86_CALL(block, codegen_mem_load_long); - } + host_x86_LEA_REG_IMM(block, REG_ESI, seg_reg, uop->imm_data); + if (REG_IS_B(dest_size)) { + host_x86_CALL(block, codegen_mem_load_byte); + } else if (REG_IS_W(dest_size)) { + host_x86_CALL(block, codegen_mem_load_word); + } else if (REG_IS_L(dest_size)) { + host_x86_CALL(block, codegen_mem_load_long); + } #ifdef RECOMPILER_DEBUG - else - fatal("MEM_LOAD_ABS - %02x\n", uop->dest_reg_a_real); + else + fatal("MEM_LOAD_ABS - %02x\n", uop->dest_reg_a_real); #endif - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); - if (REG_IS_B(dest_size)) { - host_x86_MOV8_REG_REG(block, dest_reg, REG_ECX); - } else if (REG_IS_W(dest_size)) { - host_x86_MOV16_REG_REG(block, dest_reg, REG_ECX); - } else if (REG_IS_L(dest_size)) { - host_x86_MOV32_REG_REG(block, dest_reg, REG_ECX); - } + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); + if (REG_IS_B(dest_size)) { + host_x86_MOV8_REG_REG(block, dest_reg, REG_ECX); + } else if (REG_IS_W(dest_size)) { + host_x86_MOV16_REG_REG(block, dest_reg, REG_ECX); + } else if (REG_IS_L(dest_size)) { + host_x86_MOV32_REG_REG(block, dest_reg, REG_ECX); + } - return 0; + return 0; } static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), + addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); - if (uop->imm_data) - host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); - if (REG_IS_B(dest_size)) { - host_x86_CALL(block, codegen_mem_load_byte); - } else if (REG_IS_W(dest_size)) { - host_x86_CALL(block, codegen_mem_load_word); - } else if (REG_IS_L(dest_size)) { - host_x86_CALL(block, codegen_mem_load_long); - } else if (REG_IS_Q(dest_size)) { - host_x86_CALL(block, codegen_mem_load_quad); - } + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + if (uop->imm_data) + host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); + if (REG_IS_B(dest_size)) { + host_x86_CALL(block, codegen_mem_load_byte); + } else if (REG_IS_W(dest_size)) { + host_x86_CALL(block, codegen_mem_load_word); + } else if (REG_IS_L(dest_size)) { + host_x86_CALL(block, codegen_mem_load_long); + } else if (REG_IS_Q(dest_size)) { + host_x86_CALL(block, codegen_mem_load_quad); + } #ifdef RECOMPILER_DEBUG - else - fatal("MEM_LOAD_REG - %02x\n", uop->dest_reg_a_real); + else + fatal("MEM_LOAD_REG - %02x\n", uop->dest_reg_a_real); #endif - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); - if (REG_IS_B(dest_size)) { - host_x86_MOV8_REG_REG(block, dest_reg, REG_ECX); - } else if (REG_IS_W(dest_size)) { - host_x86_MOV16_REG_REG(block, dest_reg, REG_ECX); - } else if (REG_IS_L(dest_size)) { - host_x86_MOV32_REG_REG(block, dest_reg, REG_ECX); - } else if (REG_IS_Q(dest_size)) { - host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); - } + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); + if (REG_IS_B(dest_size)) { + host_x86_MOV8_REG_REG(block, dest_reg, REG_ECX); + } else if (REG_IS_W(dest_size)) { + host_x86_MOV16_REG_REG(block, dest_reg, REG_ECX); + } else if (REG_IS_L(dest_size)) { + host_x86_MOV32_REG_REG(block, dest_reg, REG_ECX); + } else if (REG_IS_Q(dest_size)) { + host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + } - return 0; + return 0; } static int codegen_MEM_LOAD_SINGLE(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), + addr_reg = HOST_REG_GET(uop->src_reg_b_real); #ifdef RECOMPILER_DEBUG - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - if (!REG_IS_D(dest_size)) - fatal("MEM_LOAD_SINGLE - %02x\n", uop->dest_reg_a_real); + if (!REG_IS_D(dest_size)) + fatal("MEM_LOAD_SINGLE - %02x\n", uop->dest_reg_a_real); #endif - host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); - if (uop->imm_data) - host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); - host_x86_CALL(block, codegen_mem_load_single); - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); - host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + if (uop->imm_data) + host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); + host_x86_CALL(block, codegen_mem_load_single); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); + host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); - return 0; + return 0; } static int codegen_MEM_LOAD_DOUBLE(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), + addr_reg = HOST_REG_GET(uop->src_reg_b_real); #ifdef RECOMPILER_DEBUG - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - if (!REG_IS_D(dest_size)) - fatal("MEM_LOAD_DOUBLE - %02x\n", uop->dest_reg_a_real); + if (!REG_IS_D(dest_size)) + fatal("MEM_LOAD_DOUBLE - %02x\n", uop->dest_reg_a_real); #endif - host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); - if (uop->imm_data) - host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); - host_x86_CALL(block, codegen_mem_load_double); - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); - host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + if (uop->imm_data) + host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); + host_x86_CALL(block, codegen_mem_load_double); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); + host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); - return 0; + return 0; } static int codegen_MEM_STORE_ABS(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_b_real); - int src_size = IREG_GET_SIZE(uop->src_reg_b_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_b_real); + int src_size = IREG_GET_SIZE(uop->src_reg_b_real); - host_x86_LEA_REG_IMM(block, REG_ESI, seg_reg, uop->imm_data); - if (REG_IS_B(src_size)) { - host_x86_MOV8_REG_REG(block, REG_ECX, src_reg); - host_x86_CALL(block, codegen_mem_store_byte); - } else if (REG_IS_W(src_size)) { - host_x86_MOV16_REG_REG(block, REG_ECX, src_reg); - host_x86_CALL(block, codegen_mem_store_word); - } else if (REG_IS_L(src_size)) { - host_x86_MOV32_REG_REG(block, REG_ECX, src_reg); - host_x86_CALL(block, codegen_mem_store_long); - } + host_x86_LEA_REG_IMM(block, REG_ESI, seg_reg, uop->imm_data); + if (REG_IS_B(src_size)) { + host_x86_MOV8_REG_REG(block, REG_ECX, src_reg); + host_x86_CALL(block, codegen_mem_store_byte); + } else if (REG_IS_W(src_size)) { + host_x86_MOV16_REG_REG(block, REG_ECX, src_reg); + host_x86_CALL(block, codegen_mem_store_word); + } else if (REG_IS_L(src_size)) { + host_x86_MOV32_REG_REG(block, REG_ECX, src_reg); + host_x86_CALL(block, codegen_mem_store_long); + } #ifdef RECOMPILER_DEBUG - else - fatal("MEM_STORE_ABS - %02x\n", uop->src_reg_b_real); + else + fatal("MEM_STORE_ABS - %02x\n", uop->src_reg_b_real); #endif - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); - return 0; + return 0; } static int codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); - int src_size = IREG_GET_SIZE(uop->src_reg_c_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), + src_reg = HOST_REG_GET(uop->src_reg_c_real); + int src_size = IREG_GET_SIZE(uop->src_reg_c_real); - host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); - if (uop->imm_data) - host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); - if (REG_IS_B(src_size)) { - host_x86_MOV8_REG_REG(block, REG_ECX, src_reg); - host_x86_CALL(block, codegen_mem_store_byte); - } else if (REG_IS_W(src_size)) { - host_x86_MOV16_REG_REG(block, REG_ECX, src_reg); - host_x86_CALL(block, codegen_mem_store_word); - } else if (REG_IS_L(src_size)) { - host_x86_MOV32_REG_REG(block, REG_ECX, src_reg); - host_x86_CALL(block, codegen_mem_store_long); - } else if (REG_IS_Q(src_size)) { - host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg); - host_x86_CALL(block, codegen_mem_store_quad); - } + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + if (uop->imm_data) + host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); + if (REG_IS_B(src_size)) { + host_x86_MOV8_REG_REG(block, REG_ECX, src_reg); + host_x86_CALL(block, codegen_mem_store_byte); + } else if (REG_IS_W(src_size)) { + host_x86_MOV16_REG_REG(block, REG_ECX, src_reg); + host_x86_CALL(block, codegen_mem_store_word); + } else if (REG_IS_L(src_size)) { + host_x86_MOV32_REG_REG(block, REG_ECX, src_reg); + host_x86_CALL(block, codegen_mem_store_long); + } else if (REG_IS_Q(src_size)) { + host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg); + host_x86_CALL(block, codegen_mem_store_quad); + } #ifdef RECOMPILER_DEBUG - else - fatal("MEM_STORE_REG - %02x\n", uop->src_reg_b_real); + else + fatal("MEM_STORE_REG - %02x\n", uop->src_reg_b_real); #endif - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); - return 0; + return 0; } static int codegen_MEM_STORE_IMM_8(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); - host_x86_MOV8_REG_IMM(block, REG_ECX, uop->imm_data); - host_x86_CALL(block, codegen_mem_store_byte); - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + host_x86_MOV8_REG_IMM(block, REG_ECX, uop->imm_data); + host_x86_CALL(block, codegen_mem_store_byte); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); - return 0; + return 0; } static int codegen_MEM_STORE_IMM_16(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); - host_x86_MOV16_REG_IMM(block, REG_ECX, uop->imm_data); - host_x86_CALL(block, codegen_mem_store_word); - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + host_x86_MOV16_REG_IMM(block, REG_ECX, uop->imm_data); + host_x86_CALL(block, codegen_mem_store_word); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); - return 0; + return 0; } static int codegen_MEM_STORE_IMM_32(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); - host_x86_MOV32_REG_IMM(block, REG_ECX, uop->imm_data); - host_x86_CALL(block, codegen_mem_store_long); - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + host_x86_MOV32_REG_IMM(block, REG_ECX, uop->imm_data); + host_x86_CALL(block, codegen_mem_store_long); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); - return 0; + return 0; } static int codegen_MEM_STORE_SINGLE(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), + src_reg = HOST_REG_GET(uop->src_reg_c_real); #ifdef RECOMPILER_DEBUG - int src_size = IREG_GET_SIZE(uop->src_reg_c_real); + int src_size = IREG_GET_SIZE(uop->src_reg_c_real); - if (!REG_IS_D(src_size)) - fatal("MEM_STORE_SINGLE - %02x\n", uop->src_reg_b_real); + if (!REG_IS_D(src_size)) + fatal("MEM_STORE_SINGLE - %02x\n", uop->src_reg_b_real); #endif - host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); - if (uop->imm_data) - host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); - host_x86_CVTSD2SS_XREG_XREG(block, REG_XMM_TEMP, src_reg); - host_x86_CALL(block, codegen_mem_store_single); - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + if (uop->imm_data) + host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); + host_x86_CVTSD2SS_XREG_XREG(block, REG_XMM_TEMP, src_reg); + host_x86_CALL(block, codegen_mem_store_single); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); - return 0; + return 0; } static int codegen_MEM_STORE_DOUBLE(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), + src_reg = HOST_REG_GET(uop->src_reg_c_real); #ifdef RECOMPILER_DEBUG - int src_size = IREG_GET_SIZE(uop->src_reg_c_real); + int src_size = IREG_GET_SIZE(uop->src_reg_c_real); - if (!REG_IS_D(src_size)) - fatal("MEM_STORE_DOUBLE - %02x\n", uop->src_reg_b_real); + if (!REG_IS_D(src_size)) + fatal("MEM_STORE_DOUBLE - %02x\n", uop->src_reg_b_real); #endif - host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); - if (uop->imm_data) - host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); - host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg); - host_x86_CALL(block, codegen_mem_store_double); - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + if (uop->imm_data) + host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); + host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg); + host_x86_CALL(block, codegen_mem_store_double); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); - return 0; + return 0; } static int codegen_MOV(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - } else if (REG_IS_D(dest_size) && REG_IS_D(src_size)) { - host_x86_MOVQ_XREG_XREG(block, dest_reg, src_reg); - } else if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { - host_x86_MOVQ_XREG_XREG(block, dest_reg, src_reg); - } + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + } else if (REG_IS_D(dest_size) && REG_IS_D(src_size)) { + host_x86_MOVQ_XREG_XREG(block, dest_reg, src_reg); + } else if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + host_x86_MOVQ_XREG_XREG(block, dest_reg, src_reg); + } #ifdef RECOMPILER_DEBUG - else - fatal("MOV %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("MOV %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_MOV_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - if (REG_IS_L(dest_size)) { - host_x86_MOV32_REG_IMM(block, dest_reg, uop->imm_data); - } else if (REG_IS_W(dest_size)) { - host_x86_MOV16_REG_IMM(block, dest_reg, uop->imm_data); - } else if (REG_IS_B(dest_size)) { - host_x86_MOV8_REG_IMM(block, dest_reg, uop->imm_data); - } + if (REG_IS_L(dest_size)) { + host_x86_MOV32_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size)) { + host_x86_MOV16_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size)) { + host_x86_MOV8_REG_IMM(block, dest_reg, uop->imm_data); + } #ifdef RECOMPILER_DEBUG - else - fatal("MOV_IMM %02x\n", uop->dest_reg_a_real); + else + fatal("MOV_IMM %02x\n", uop->dest_reg_a_real); #endif - return 0; + return 0; } static int codegen_MOV_PTR(codeblock_t *block, uop_t *uop) { - host_x86_MOV32_REG_IMM(block, uop->dest_reg_a_real, (uint32_t)uop->p); - return 0; + host_x86_MOV32_REG_IMM(block, uop->dest_reg_a_real, (uint32_t)uop->p); + return 0; } static int codegen_MOV_REG_PTR(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - if (REG_IS_L(dest_size)) { - host_x86_MOV32_REG_ABS(block, dest_reg, uop->p); - } else - fatal("MOV_REG_PTR %02x\n", uop->dest_reg_a_real); + if (REG_IS_L(dest_size)) { + host_x86_MOV32_REG_ABS(block, dest_reg, uop->p); + } else + fatal("MOV_REG_PTR %02x\n", uop->dest_reg_a_real); - return 0; + return 0; } static int codegen_MOVZX_REG_PTR_8(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - if (REG_IS_L(dest_size)) { - host_x86_MOVZX_REG_ABS_32_8(block, dest_reg, uop->p); - } else if (REG_IS_W(dest_size)) { - host_x86_MOVZX_REG_ABS_16_8(block, dest_reg, uop->p); - } else if (REG_IS_B(dest_size)) { - host_x86_MOV8_REG_ABS(block, dest_reg, uop->p); - } else - fatal("MOVZX_REG_PTR_8 %02x\n", uop->dest_reg_a_real); + if (REG_IS_L(dest_size)) { + host_x86_MOVZX_REG_ABS_32_8(block, dest_reg, uop->p); + } else if (REG_IS_W(dest_size)) { + host_x86_MOVZX_REG_ABS_16_8(block, dest_reg, uop->p); + } else if (REG_IS_B(dest_size)) { + host_x86_MOV8_REG_ABS(block, dest_reg, uop->p); + } else + fatal("MOVZX_REG_PTR_8 %02x\n", uop->dest_reg_a_real); - return 0; + return 0; } static int codegen_MOVZX_REG_PTR_16(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - if (REG_IS_L(dest_size)) { - host_x86_MOVZX_REG_ABS_32_16(block, dest_reg, uop->p); - } else if (REG_IS_W(dest_size)) { - host_x86_MOV16_REG_ABS(block, dest_reg, uop->p); - } else - fatal("MOVZX_REG_PTR_16 %02x\n", uop->dest_reg_a_real); + if (REG_IS_L(dest_size)) { + host_x86_MOVZX_REG_ABS_32_16(block, dest_reg, uop->p); + } else if (REG_IS_W(dest_size)) { + host_x86_MOV16_REG_ABS(block, dest_reg, uop->p); + } else + fatal("MOVZX_REG_PTR_16 %02x\n", uop->dest_reg_a_real); - return 0; + return 0; } static int codegen_MOVSX(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_W(src_size)) { - host_x86_MOVSX_REG_32_16(block, dest_reg, src_reg); - } else if (REG_IS_L(dest_size) && REG_IS_B(src_size)) { - host_x86_MOVSX_REG_32_8(block, dest_reg, src_reg); - } else if (REG_IS_W(dest_size) && REG_IS_B(src_size)) { - host_x86_MOVSX_REG_16_8(block, dest_reg, src_reg); - } + if (REG_IS_L(dest_size) && REG_IS_W(src_size)) { + host_x86_MOVSX_REG_32_16(block, dest_reg, src_reg); + } else if (REG_IS_L(dest_size) && REG_IS_B(src_size)) { + host_x86_MOVSX_REG_32_8(block, dest_reg, src_reg); + } else if (REG_IS_W(dest_size) && REG_IS_B(src_size)) { + host_x86_MOVSX_REG_16_8(block, dest_reg, src_reg); + } #ifdef RECOMPILER_DEBUG - else - fatal("MOVSX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("MOVSX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_MOVZX(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_Q(dest_size) && REG_IS_L(src_size)) { - host_x86_MOVD_XREG_REG(block, dest_reg, src_reg); - } else if (REG_IS_L(dest_size) && REG_IS_Q(src_size)) { - host_x86_MOVD_REG_XREG(block, dest_reg, src_reg); - } else if (REG_IS_L(dest_size) && REG_IS_W(src_size)) { - host_x86_MOVZX_REG_32_16(block, dest_reg, src_reg); - } else if (REG_IS_L(dest_size) && REG_IS_B(src_size)) { - host_x86_MOVZX_REG_32_8(block, dest_reg, src_reg); - } else if (REG_IS_W(dest_size) && REG_IS_B(src_size)) { - host_x86_MOVZX_REG_16_8(block, dest_reg, src_reg); - } + if (REG_IS_Q(dest_size) && REG_IS_L(src_size)) { + host_x86_MOVD_XREG_REG(block, dest_reg, src_reg); + } else if (REG_IS_L(dest_size) && REG_IS_Q(src_size)) { + host_x86_MOVD_REG_XREG(block, dest_reg, src_reg); + } else if (REG_IS_L(dest_size) && REG_IS_W(src_size)) { + host_x86_MOVZX_REG_32_16(block, dest_reg, src_reg); + } else if (REG_IS_L(dest_size) && REG_IS_B(src_size)) { + host_x86_MOVZX_REG_32_8(block, dest_reg, src_reg); + } else if (REG_IS_W(dest_size) && REG_IS_B(src_size)) { + host_x86_MOVZX_REG_16_8(block, dest_reg, src_reg); + } #ifdef RECOMPILER_DEBUG - else - fatal("MOVZX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("MOVZX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_MOV_DOUBLE_INT(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_D(dest_size) && REG_IS_L(src_size)) { - host_x86_CVTSI2SD_XREG_REG(block, dest_reg, src_reg); - } else if (REG_IS_D(dest_size) && REG_IS_W(src_size)) { - host_x86_MOVSX_REG_32_16(block, REG_ECX, src_reg); - host_x86_CVTSI2SD_XREG_REG(block, dest_reg, REG_ECX); - } else if (REG_IS_D(dest_size) && REG_IS_Q(src_size)) { - /*There is no SSE instruction to convert a 64-bit integer to a floating point value. - Instead we have to bounce the integer through memory via x87.*/ - host_x86_MOVQ_BASE_OFFSET_XREG(block, REG_ESP, 0, src_reg); - host_x87_FILDq_BASE(block, REG_ESP); - host_x87_FSTPd_BASE(block, REG_ESP); - host_x86_MOVQ_XREG_BASE_OFFSET(block, dest_reg, REG_ESP, 0); - } + if (REG_IS_D(dest_size) && REG_IS_L(src_size)) { + host_x86_CVTSI2SD_XREG_REG(block, dest_reg, src_reg); + } else if (REG_IS_D(dest_size) && REG_IS_W(src_size)) { + host_x86_MOVSX_REG_32_16(block, REG_ECX, src_reg); + host_x86_CVTSI2SD_XREG_REG(block, dest_reg, REG_ECX); + } else if (REG_IS_D(dest_size) && REG_IS_Q(src_size)) { + /*There is no SSE instruction to convert a 64-bit integer to a floating point value. + Instead we have to bounce the integer through memory via x87.*/ + host_x86_MOVQ_BASE_OFFSET_XREG(block, REG_ESP, 0, src_reg); + host_x87_FILDq_BASE(block, REG_ESP); + host_x87_FSTPd_BASE(block, REG_ESP); + host_x86_MOVQ_XREG_BASE_OFFSET(block, dest_reg, REG_ESP, 0); + } #ifdef RECOMPILER_DEBUG - else - fatal("MOV_DOUBLE_INT %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("MOV_DOUBLE_INT %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_MOV_INT_DOUBLE(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_D(src_size)) { - host_x86_LDMXCSR(block, &cpu_state.new_fp_control); - host_x86_CVTSD2SI_REG_XREG(block, dest_reg, src_reg); - host_x86_LDMXCSR(block, &cpu_state.old_fp_control); - } else if (REG_IS_W(dest_size) && REG_IS_D(src_size)) { - host_x86_LDMXCSR(block, &cpu_state.new_fp_control); - host_x86_CVTSD2SI_REG_XREG(block, REG_ECX, src_reg); - host_x86_MOV16_REG_REG(block, dest_reg, REG_ECX); - host_x86_LDMXCSR(block, &cpu_state.old_fp_control); - } + if (REG_IS_L(dest_size) && REG_IS_D(src_size)) { + host_x86_LDMXCSR(block, &cpu_state.new_fp_control); + host_x86_CVTSD2SI_REG_XREG(block, dest_reg, src_reg); + host_x86_LDMXCSR(block, &cpu_state.old_fp_control); + } else if (REG_IS_W(dest_size) && REG_IS_D(src_size)) { + host_x86_LDMXCSR(block, &cpu_state.new_fp_control); + host_x86_CVTSD2SI_REG_XREG(block, REG_ECX, src_reg); + host_x86_MOV16_REG_REG(block, dest_reg, REG_ECX); + host_x86_LDMXCSR(block, &cpu_state.old_fp_control); + } #ifdef RECOMPILER_DEBUG - else - fatal("MOV_INT_DOUBLE %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("MOV_INT_DOUBLE %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_MOV_INT_DOUBLE_64(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), src_64_reg = HOST_REG_GET(uop->src_reg_b_real), tag_reg = HOST_REG_GET(uop->src_reg_c_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real), src_64_size = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), + src_64_reg = HOST_REG_GET(uop->src_reg_b_real), tag_reg = HOST_REG_GET(uop->src_reg_c_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real), + src_64_size = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_D(src_size) && REG_IS_Q(src_64_size)) { - uint32_t *branch_offset; + if (REG_IS_Q(dest_size) && REG_IS_D(src_size) && REG_IS_Q(src_64_size)) { + uint32_t *branch_offset; - /*If TAG_UINT64 is set then the source is MM[]. Otherwise it is a double in ST()*/ - host_x86_MOVQ_XREG_XREG(block, dest_reg, src_64_reg); - host_x86_TEST8_REG(block, tag_reg, tag_reg); - branch_offset = host_x86_JS_long(block); + /*If TAG_UINT64 is set then the source is MM[]. Otherwise it is a double in ST()*/ + host_x86_MOVQ_XREG_XREG(block, dest_reg, src_64_reg); + host_x86_TEST8_REG(block, tag_reg, tag_reg); + branch_offset = host_x86_JS_long(block); - /*There is no SSE instruction to convert a floating point value to a 64-bit integer. - Instead we have to bounce through memory via x87.*/ - host_x87_FLDCW(block, &cpu_state.new_fp_control2); - host_x86_MOVQ_BASE_OFFSET_XREG(block, REG_ESP, 0, src_reg); - host_x87_FLDd_BASE(block, REG_ESP); - host_x87_FISTPq_BASE(block, REG_ESP); - host_x86_MOVQ_XREG_BASE_OFFSET(block, dest_reg, REG_ESP, 0); - host_x87_FLDCW(block, &cpu_state.old_fp_control2); + /*There is no SSE instruction to convert a floating point value to a 64-bit integer. + Instead we have to bounce through memory via x87.*/ + host_x87_FLDCW(block, &cpu_state.new_fp_control2); + host_x86_MOVQ_BASE_OFFSET_XREG(block, REG_ESP, 0, src_reg); + host_x87_FLDd_BASE(block, REG_ESP); + host_x87_FISTPq_BASE(block, REG_ESP); + host_x86_MOVQ_XREG_BASE_OFFSET(block, dest_reg, REG_ESP, 0); + host_x87_FLDCW(block, &cpu_state.old_fp_control2); - *branch_offset = (uint32_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 4; - } + *branch_offset = (uint32_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 4; + } #ifdef RECOMPILER_DEBUG - else - fatal("MOV_INT_DOUBLE_64 %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("MOV_INT_DOUBLE_64 %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } -static int codegen_NOP(codeblock_t *block, uop_t *uop) { - return 0; -} +static int codegen_NOP(codeblock_t *block, uop_t *uop) { return 0; } static int codegen_OR(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_POR_XREG_XREG(block, dest_reg, src_reg_b); - } else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a); - host_x86_OR32_REG_REG(block, dest_reg, src_reg_b); - } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); - host_x86_OR16_REG_REG(block, dest_reg, src_reg_b); - } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); - host_x86_OR8_REG_REG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_POR_XREG_XREG(block, dest_reg, src_reg_b); + } else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a); + host_x86_OR32_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); + host_x86_OR16_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); + host_x86_OR8_REG_REG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("OR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("OR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_OR_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - if (REG_IS_L(dest_size) && dest_reg == src_reg) { - host_x86_OR32_REG_IMM(block, dest_reg, uop->imm_data); - } else if (REG_IS_W(dest_size) && dest_reg == src_reg) { - host_x86_OR16_REG_IMM(block, dest_reg, uop->imm_data); - } else if (REG_IS_B(dest_size) && dest_reg == src_reg) { - host_x86_OR8_REG_IMM(block, dest_reg, uop->imm_data); - } + if (REG_IS_L(dest_size) && dest_reg == src_reg) { + host_x86_OR32_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && dest_reg == src_reg) { + host_x86_OR16_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && dest_reg == src_reg) { + host_x86_OR8_REG_IMM(block, dest_reg, uop->imm_data); + } #ifdef RECOMPILER_DEBUG - else - fatal("OR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("OR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_PACKSSWB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PACKSSWB_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PACKSSWB_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PACKSSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PACKSSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PACKSSDW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PACKSSDW_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PACKSSDW_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PACKSSDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PACKSSDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PACKUSWB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PACKUSWB_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PACKUSWB_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PACKUSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PACKUSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PADDB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PADDB_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PADDB_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PADDB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PADDB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PADDW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PADDW_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PADDW_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PADDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PADDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PADDD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PADDD_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PADDD_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PADDD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PADDD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PADDSB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PADDSB_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PADDSB_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PADDSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PADDSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PADDSW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PADDSW_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PADDSW_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PADDSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PADDSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PADDUSB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PADDUSB_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PADDUSB_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PADDUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PADDUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PADDUSW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PADDUSW_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PADDUSW_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PADDUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PADDUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PCMPEQB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PCMPEQB_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PCMPEQB_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PCMPEQB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PCMPEQB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PCMPEQW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PCMPEQW_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PCMPEQW_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PCMPEQW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PCMPEQW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PCMPEQD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PCMPEQD_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PCMPEQD_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PCMPEQD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PCMPEQD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PCMPGTB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PCMPGTB_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PCMPGTB_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PCMPGTB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PCMPGTB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PCMPGTW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PCMPGTW_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PCMPGTW_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PCMPGTW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PCMPGTW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PCMPGTD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PCMPGTD_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PCMPGTD_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PCMPGTD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PCMPGTD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PF2ID(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { - host_x86_LDMXCSR(block, &cpu_state.trunc_fp_control); - host_x86_CVTPS2DQ_XREG_XREG(block, dest_reg, src_reg_a); - host_x86_LDMXCSR(block, &cpu_state.old_fp_control); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { + host_x86_LDMXCSR(block, &cpu_state.trunc_fp_control); + host_x86_CVTPS2DQ_XREG_XREG(block, dest_reg, src_reg_a); + host_x86_LDMXCSR(block, &cpu_state.old_fp_control); + } #ifdef RECOMPILER_DEBUG - else - fatal("PF2ID %02x %02x\n", uop->dest_reg_a_real); + else + fatal("PF2ID %02x %02x\n", uop->dest_reg_a_real); #endif - return 0; + return 0; } static int codegen_PFADD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_ADDPS_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_ADDPS_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PFADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PFADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PFCMPEQ(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_CMPPS_XREG_XREG(block, dest_reg, src_reg_b, CMPPS_EQ); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_CMPPS_XREG_XREG(block, dest_reg, src_reg_b, CMPPS_EQ); + } #ifdef RECOMPILER_DEBUG - else - fatal("PFCMPEQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PFCMPEQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PFCMPGE(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_CMPPS_XREG_XREG(block, dest_reg, src_reg_b, CMPPS_NLT); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_CMPPS_XREG_XREG(block, dest_reg, src_reg_b, CMPPS_NLT); + } #ifdef RECOMPILER_DEBUG - else - fatal("PFCMPGE %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PFCMPGE %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PFCMPGT(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_CMPPS_XREG_XREG(block, dest_reg, src_reg_b, CMPPS_NLE); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_CMPPS_XREG_XREG(block, dest_reg, src_reg_b, CMPPS_NLE); + } #ifdef RECOMPILER_DEBUG - else - fatal("PFCMPGT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PFCMPGT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PFMAX(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_MAXPS_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_MAXPS_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PFMAX %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PFMAX %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PFMIN(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_MINPS_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_MINPS_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PFMIN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PFMIN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PFMUL(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_MULPS_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_MULPS_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PFMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PFMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PFRCP(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { - /*TODO: This could be improved (use RCPSS + iteration)*/ - host_x86_MOV32_REG_IMM(block, REG_ECX, 1); - host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); - host_x86_CVTSI2SS_XREG_REG(block, dest_reg, REG_ECX); - host_x86_DIVSS_XREG_XREG(block, dest_reg, REG_XMM_TEMP); - host_x86_UNPCKLPS_XREG_XREG(block, dest_reg, dest_reg); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { + /*TODO: This could be improved (use RCPSS + iteration)*/ + host_x86_MOV32_REG_IMM(block, REG_ECX, 1); + host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); + host_x86_CVTSI2SS_XREG_REG(block, dest_reg, REG_ECX); + host_x86_DIVSS_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + host_x86_UNPCKLPS_XREG_XREG(block, dest_reg, dest_reg); + } #ifdef RECOMPILER_DEBUG - else - fatal("PFRCP %02x %02x\n", uop->dest_reg_a_real); + else + fatal("PFRCP %02x %02x\n", uop->dest_reg_a_real); #endif - return 0; + return 0; } static int codegen_PFRSQRT(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { - /*TODO: This could be improved (use RSQRTSS + iteration)*/ - host_x86_SQRTSS_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); - host_x86_MOV32_REG_IMM(block, REG_ECX, 1); - host_x86_CVTSI2SS_XREG_REG(block, dest_reg, REG_ECX); - host_x86_DIVSS_XREG_XREG(block, dest_reg, REG_XMM_TEMP); - host_x86_UNPCKLPS_XREG_XREG(block, dest_reg, dest_reg); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { + /*TODO: This could be improved (use RSQRTSS + iteration)*/ + host_x86_SQRTSS_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); + host_x86_MOV32_REG_IMM(block, REG_ECX, 1); + host_x86_CVTSI2SS_XREG_REG(block, dest_reg, REG_ECX); + host_x86_DIVSS_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + host_x86_UNPCKLPS_XREG_XREG(block, dest_reg, dest_reg); + } #ifdef RECOMPILER_DEBUG - else - fatal("PFRSQRT %02x %02x\n", uop->dest_reg_a_real); + else + fatal("PFRSQRT %02x %02x\n", uop->dest_reg_a_real); #endif - return 0; + return 0; } static int codegen_PFSUB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_SUBPS_XREG_XREG(block, dest_reg, src_reg_b); - } else if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { - host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); - host_x86_SUBPS_XREG_XREG(block, REG_XMM_TEMP, src_reg_b); - host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_SUBPS_XREG_XREG(block, dest_reg, src_reg_b); + } else if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); + host_x86_SUBPS_XREG_XREG(block, REG_XMM_TEMP, src_reg_b); + host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + } #ifdef RECOMPILER_DEBUG - else - fatal("PFSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PFSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PI2FD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { - host_x86_CVTDQ2PS_XREG_XREG(block, dest_reg, src_reg_a); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { + host_x86_CVTDQ2PS_XREG_XREG(block, dest_reg, src_reg_a); + } #ifdef RECOMPILER_DEBUG - else - fatal("PI2FD %02x %02x\n", uop->dest_reg_a_real); + else + fatal("PI2FD %02x %02x\n", uop->dest_reg_a_real); #endif - return 0; + return 0; } static int codegen_PMADDWD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PMADDWD_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PMADDWD_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PMULHW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PMULHW_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PMULHW_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PMULLW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PMULLW_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PMULLW_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PMULLW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PMULLW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PSLLW_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PSLLW_XREG_IMM(block, dest_reg, uop->imm_data); - } + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSLLW_XREG_IMM(block, dest_reg, uop->imm_data); + } #ifdef RECOMPILER_DEBUG - else - fatal("PSLLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("PSLLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_PSLLD_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PSLLD_XREG_IMM(block, dest_reg, uop->imm_data); - } + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSLLD_XREG_IMM(block, dest_reg, uop->imm_data); + } #ifdef RECOMPILER_DEBUG - else - fatal("PSLLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("PSLLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_PSLLQ_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PSLLQ_XREG_IMM(block, dest_reg, uop->imm_data); - } + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSLLQ_XREG_IMM(block, dest_reg, uop->imm_data); + } #ifdef RECOMPILER_DEBUG - else - fatal("PSLLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("PSLLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_PSRAW_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PSRAW_XREG_IMM(block, dest_reg, uop->imm_data); - } + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSRAW_XREG_IMM(block, dest_reg, uop->imm_data); + } #ifdef RECOMPILER_DEBUG - else - fatal("PSRAW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("PSRAW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_PSRAD_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PSRAD_XREG_IMM(block, dest_reg, uop->imm_data); - } + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSRAD_XREG_IMM(block, dest_reg, uop->imm_data); + } #ifdef RECOMPILER_DEBUG - else - fatal("PSRAD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("PSRAD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_PSRAQ_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PSRAQ_XREG_IMM(block, dest_reg, uop->imm_data); - } + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSRAQ_XREG_IMM(block, dest_reg, uop->imm_data); + } #ifdef RECOMPILER_DEBUG - else - fatal("PSRAQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("PSRAQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_PSRLW_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PSRLW_XREG_IMM(block, dest_reg, uop->imm_data); - } + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSRLW_XREG_IMM(block, dest_reg, uop->imm_data); + } #ifdef RECOMPILER_DEBUG - else - fatal("PSRLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("PSRLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_PSRLD_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PSRLD_XREG_IMM(block, dest_reg, uop->imm_data); - } + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSRLD_XREG_IMM(block, dest_reg, uop->imm_data); + } #ifdef RECOMPILER_DEBUG - else - fatal("PSRLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("PSRLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_PSRLQ_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PSRLQ_XREG_IMM(block, dest_reg, uop->imm_data); - } + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSRLQ_XREG_IMM(block, dest_reg, uop->imm_data); + } #ifdef RECOMPILER_DEBUG - else - fatal("PSRLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("PSRLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_PSUBB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PSUBB_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSUBB_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PSUBB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PSUBB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PSUBW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PSUBW_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSUBW_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PSUBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PSUBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PSUBD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PSUBD_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSUBD_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PSUBD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PSUBD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PSUBSB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PSUBSB_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSUBSB_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PSUBSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PSUBSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PSUBSW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PSUBSW_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSUBSW_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PSUBSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PSUBSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PSUBUSB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PSUBUSB_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSUBUSB_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PSUBUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PSUBUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PSUBUSW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PSUBUSW_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSUBUSW_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PSUBUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PSUBUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PUNPCKHBW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PUNPCKLBW_XREG_XREG(block, dest_reg, src_reg_b); - host_x86_PSHUFD_XREG_XREG_IMM(block, dest_reg, dest_reg, 0xee); /*0xee = move top 64-bits to low 64-bits*/ - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PUNPCKLBW_XREG_XREG(block, dest_reg, src_reg_b); + host_x86_PSHUFD_XREG_XREG_IMM(block, dest_reg, dest_reg, 0xee); /*0xee = move top 64-bits to low 64-bits*/ + } #ifdef RECOMPILER_DEBUG - else - fatal("PUNPCKHBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PUNPCKHBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PUNPCKHWD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PUNPCKLWD_XREG_XREG(block, dest_reg, src_reg_b); - host_x86_PSHUFD_XREG_XREG_IMM(block, dest_reg, dest_reg, 0xee); /*0xee = move top 64-bits to low 64-bits*/ - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PUNPCKLWD_XREG_XREG(block, dest_reg, src_reg_b); + host_x86_PSHUFD_XREG_XREG_IMM(block, dest_reg, dest_reg, 0xee); /*0xee = move top 64-bits to low 64-bits*/ + } #ifdef RECOMPILER_DEBUG - else - fatal("PUNPCKHWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PUNPCKHWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PUNPCKHDQ(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PUNPCKLDQ_XREG_XREG(block, dest_reg, src_reg_b); - host_x86_PSHUFD_XREG_XREG_IMM(block, dest_reg, dest_reg, 0xee); /*0xee = move top 64-bits to low 64-bits*/ - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PUNPCKLDQ_XREG_XREG(block, dest_reg, src_reg_b); + host_x86_PSHUFD_XREG_XREG_IMM(block, dest_reg, dest_reg, 0xee); /*0xee = move top 64-bits to low 64-bits*/ + } #ifdef RECOMPILER_DEBUG - else - fatal("PUNPCKHDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PUNPCKHDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PUNPCKLBW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PUNPCKLBW_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PUNPCKLBW_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PUNPCKLBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PUNPCKLBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PUNPCKLWD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PUNPCKLWD_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PUNPCKLWD_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PUNPCKLWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PUNPCKLWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_PUNPCKLDQ(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PUNPCKLDQ_XREG_XREG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PUNPCKLDQ_XREG_XREG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("PUNPCKLDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("PUNPCKLDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_ROL(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), + shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_ROL32_CL(block, dest_reg); - } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_ROL16_CL(block, dest_reg); - } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_ROL8_CL(block, dest_reg); - } + host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_ROL32_CL(block, dest_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_ROL16_CL(block, dest_reg); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_ROL8_CL(block, dest_reg); + } #ifdef RECOMPILER_DEBUG - else - fatal("ROL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("ROL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_ROL_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_ROL32_IMM(block, dest_reg, uop->imm_data); - } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_ROL16_IMM(block, dest_reg, uop->imm_data); - } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_ROL8_IMM(block, dest_reg, uop->imm_data); - } + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_ROL32_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_ROL16_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_ROL8_IMM(block, dest_reg, uop->imm_data); + } #ifdef RECOMPILER_DEBUG - else - fatal("ROL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("ROL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_ROR(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), + shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_ROR32_CL(block, dest_reg); - } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_ROR16_CL(block, dest_reg); - } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_ROR8_CL(block, dest_reg); - } + host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_ROR32_CL(block, dest_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_ROR16_CL(block, dest_reg); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_ROR8_CL(block, dest_reg); + } #ifdef RECOMPILER_DEBUG - else - fatal("ROR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("ROR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_ROR_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_ROR32_IMM(block, dest_reg, uop->imm_data); - } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_ROR16_IMM(block, dest_reg, uop->imm_data); - } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_ROR8_IMM(block, dest_reg, uop->imm_data); - } + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_ROR32_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_ROR16_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_ROR8_IMM(block, dest_reg, uop->imm_data); + } #ifdef RECOMPILER_DEBUG - else - fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_SAR(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), + shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_SAR32_CL(block, dest_reg); - } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_SAR16_CL(block, dest_reg); - } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_SAR8_CL(block, dest_reg); - } + host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_SAR32_CL(block, dest_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_SAR16_CL(block, dest_reg); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_SAR8_CL(block, dest_reg); + } #ifdef RECOMPILER_DEBUG - else - fatal("SAR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("SAR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_SAR_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_SAR32_IMM(block, dest_reg, uop->imm_data); - } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_SAR16_IMM(block, dest_reg, uop->imm_data); - } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_SAR8_IMM(block, dest_reg, uop->imm_data); - } + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_SAR32_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_SAR16_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_SAR8_IMM(block, dest_reg, uop->imm_data); + } #ifdef RECOMPILER_DEBUG - else - fatal("SAR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("SAR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_SHL(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), + shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_SHL32_CL(block, dest_reg); - } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_SHL16_CL(block, dest_reg); - } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_SHL8_CL(block, dest_reg); - } + host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_SHL32_CL(block, dest_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_SHL16_CL(block, dest_reg); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_SHL8_CL(block, dest_reg); + } #ifdef RECOMPILER_DEBUG - else - fatal("SHL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("SHL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_SHL_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_SHL32_IMM(block, dest_reg, uop->imm_data); - } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_SHL16_IMM(block, dest_reg, uop->imm_data); - } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_SHL8_IMM(block, dest_reg, uop->imm_data); - } + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_SHL32_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_SHL16_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_SHL8_IMM(block, dest_reg, uop->imm_data); + } #ifdef RECOMPILER_DEBUG - else - fatal("SHL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("SHL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_SHR(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), + shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_SHR32_CL(block, dest_reg); - } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_SHR16_CL(block, dest_reg); - } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_SHR8_CL(block, dest_reg); - } + host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_SHR32_CL(block, dest_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_SHR16_CL(block, dest_reg); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_SHR8_CL(block, dest_reg); + } #ifdef RECOMPILER_DEBUG - else - fatal("SHR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("SHR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_SHR_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_SHR32_IMM(block, dest_reg, uop->imm_data); - } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_SHR16_IMM(block, dest_reg, uop->imm_data); - } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_SHR8_IMM(block, dest_reg, uop->imm_data); - } + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_SHR32_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_SHR16_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_SHR8_IMM(block, dest_reg, uop->imm_data); + } #ifdef RECOMPILER_DEBUG - else - fatal("SHR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("SHR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_STORE_PTR_IMM(codeblock_t *block, uop_t *uop) { - host_x86_MOV32_ABS_IMM(block, uop->p, uop->imm_data); - return 0; + host_x86_MOV32_ABS_IMM(block, uop->p, uop->imm_data); + return 0; } static int codegen_STORE_PTR_IMM_8(codeblock_t *block, uop_t *uop) { - host_x86_MOV8_ABS_IMM(block, uop->p, uop->imm_data); - return 0; + host_x86_MOV8_ABS_IMM(block, uop->p, uop->imm_data); + return 0; } static int codegen_STORE_PTR_IMM_16(codeblock_t *block, uop_t *uop) { - host_x86_MOV16_ABS_IMM(block, uop->p, uop->imm_data); - return 0; + host_x86_MOV16_ABS_IMM(block, uop->p, uop->imm_data); + return 0; } static int codegen_SUB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), + src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a); - host_x86_SUB32_REG_REG(block, dest_reg, src_reg_b); - } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); - host_x86_SUB16_REG_REG(block, dest_reg, src_reg_b); - } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); - host_x86_SUB8_REG_REG(block, dest_reg, src_reg_b); - } + if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a); + host_x86_SUB32_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); + host_x86_SUB16_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); + host_x86_SUB8_REG_REG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("SUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("SUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_SUB_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { - if (dest_reg != src_reg) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_SUB32_REG_IMM(block, dest_reg, uop->imm_data); - } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { - if (dest_reg != src_reg) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_SUB16_REG_IMM(block, dest_reg, uop->imm_data); - } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { - if (dest_reg != src_reg) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_SUB8_REG_IMM(block, dest_reg, uop->imm_data); - } + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (dest_reg != src_reg) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_SUB32_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (dest_reg != src_reg) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_SUB16_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (dest_reg != src_reg) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_SUB8_REG_IMM(block, dest_reg, uop->imm_data); + } #ifdef RECOMPILER_DEBUG - else - fatal("SUB_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("SUB_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } static int codegen_TEST_JNS_DEST(codeblock_t *block, uop_t *uop) { - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(src_size)) { - host_x86_TEST32_REG(block, src_reg, src_reg); - } else if (REG_IS_W(src_size)) { - host_x86_TEST16_REG(block, src_reg, src_reg); - } else if (REG_IS_B(src_size)) { - host_x86_TEST8_REG(block, src_reg, src_reg); - } + if (REG_IS_L(src_size)) { + host_x86_TEST32_REG(block, src_reg, src_reg); + } else if (REG_IS_W(src_size)) { + host_x86_TEST16_REG(block, src_reg, src_reg); + } else if (REG_IS_B(src_size)) { + host_x86_TEST8_REG(block, src_reg, src_reg); + } #ifdef RECOMPILER_DEBUG - else - fatal("TEST_JNS_DEST %02x\n", uop->src_reg_a_real); + else + fatal("TEST_JNS_DEST %02x\n", uop->src_reg_a_real); #endif - uop->p = host_x86_JNS_long(block); + uop->p = host_x86_JNS_long(block); - return 0; + return 0; } static int codegen_TEST_JS_DEST(codeblock_t *block, uop_t *uop) { - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(src_size)) { - host_x86_TEST32_REG(block, src_reg, src_reg); - } else if (REG_IS_W(src_size)) { - host_x86_TEST16_REG(block, src_reg, src_reg); - } else if (REG_IS_B(src_size)) { - host_x86_TEST8_REG(block, src_reg, src_reg); - } + if (REG_IS_L(src_size)) { + host_x86_TEST32_REG(block, src_reg, src_reg); + } else if (REG_IS_W(src_size)) { + host_x86_TEST16_REG(block, src_reg, src_reg); + } else if (REG_IS_B(src_size)) { + host_x86_TEST8_REG(block, src_reg, src_reg); + } #ifdef RECOMPILER_DEBUG - else - fatal("TEST_JS_DEST %02x\n", uop->src_reg_a_real); + else + fatal("TEST_JS_DEST %02x\n", uop->src_reg_a_real); #endif - uop->p = host_x86_JS_long(block); + uop->p = host_x86_JS_long(block); - return 0; + return 0; } static int codegen_XOR(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), + src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_PXOR_XREG_XREG(block, dest_reg, src_reg_b); - } else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_XOR32_REG_REG(block, dest_reg, src_reg_b); - } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_XOR16_REG_REG(block, dest_reg, src_reg_b); - } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_XOR8_REG_REG(block, dest_reg, src_reg_b); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PXOR_XREG_XREG(block, dest_reg, src_reg_b); + } else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b) && + uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_XOR32_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b) && + uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_XOR16_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && + uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_XOR8_REG_REG(block, dest_reg, src_reg_b); + } #ifdef RECOMPILER_DEBUG - else - fatal("XOR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + else + fatal("XOR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); #endif - return 0; + return 0; } static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_XOR32_REG_IMM(block, dest_reg, uop->imm_data); - } else if (REG_IS_W(dest_size) && REG_IS_W(src_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_XOR16_REG_IMM(block, dest_reg, uop->imm_data); - } else if (REG_IS_B(dest_size) && REG_IS_B(src_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_x86_XOR8_REG_IMM(block, dest_reg, uop->imm_data); - } + if (REG_IS_L(dest_size) && REG_IS_L(src_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_XOR32_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_XOR16_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_XOR8_REG_IMM(block, dest_reg, uop->imm_data); + } #ifdef RECOMPILER_DEBUG - else - fatal("XOR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + else + fatal("XOR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); #endif - return 0; + return 0; } #ifdef DEBUG_EXTRA -static int codegen_LOG_INSTR(codeblock_t *block, uop_t *uop) -{ - if (uop->imm_data > 256*256) - fatal("LOG_INSTR %08x\n", uop->imm_data); - host_x86_INC32_ABS(block, &instr_counts[uop->imm_data]); - return 0; +static int codegen_LOG_INSTR(codeblock_t *block, uop_t *uop) { + if (uop->imm_data > 256 * 256) + fatal("LOG_INSTR %08x\n", uop->imm_data); + host_x86_INC32_ABS(block, &instr_counts[uop->imm_data]); + return 0; } #endif -const uOpFn uop_handlers[UOP_MAX] = - { - [UOP_CALL_FUNC & UOP_MASK] = codegen_CALL_FUNC, - [UOP_CALL_FUNC_RESULT & UOP_MASK] = codegen_CALL_FUNC_RESULT, - [UOP_CALL_INSTRUCTION_FUNC & UOP_MASK] = codegen_CALL_INSTRUCTION_FUNC, +const uOpFn uop_handlers[UOP_MAX] = {[UOP_CALL_FUNC & UOP_MASK] = codegen_CALL_FUNC, + [UOP_CALL_FUNC_RESULT & UOP_MASK] = codegen_CALL_FUNC_RESULT, + [UOP_CALL_INSTRUCTION_FUNC & UOP_MASK] = codegen_CALL_INSTRUCTION_FUNC, - [UOP_JMP & UOP_MASK] = codegen_JMP, - [UOP_JMP_DEST & UOP_MASK] = codegen_JMP_DEST, + [UOP_JMP & UOP_MASK] = codegen_JMP, + [UOP_JMP_DEST & UOP_MASK] = codegen_JMP_DEST, - [UOP_LOAD_SEG & UOP_MASK] = codegen_LOAD_SEG, + [UOP_LOAD_SEG & UOP_MASK] = codegen_LOAD_SEG, - [UOP_LOAD_FUNC_ARG_0 & UOP_MASK] = codegen_LOAD_FUNC_ARG0, - [UOP_LOAD_FUNC_ARG_1 & UOP_MASK] = codegen_LOAD_FUNC_ARG1, - [UOP_LOAD_FUNC_ARG_2 & UOP_MASK] = codegen_LOAD_FUNC_ARG2, - [UOP_LOAD_FUNC_ARG_3 & UOP_MASK] = codegen_LOAD_FUNC_ARG3, + [UOP_LOAD_FUNC_ARG_0 & UOP_MASK] = codegen_LOAD_FUNC_ARG0, + [UOP_LOAD_FUNC_ARG_1 & UOP_MASK] = codegen_LOAD_FUNC_ARG1, + [UOP_LOAD_FUNC_ARG_2 & UOP_MASK] = codegen_LOAD_FUNC_ARG2, + [UOP_LOAD_FUNC_ARG_3 & UOP_MASK] = codegen_LOAD_FUNC_ARG3, - [UOP_LOAD_FUNC_ARG_0_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG0_IMM, - [UOP_LOAD_FUNC_ARG_1_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG1_IMM, - [UOP_LOAD_FUNC_ARG_2_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG2_IMM, - [UOP_LOAD_FUNC_ARG_3_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG3_IMM, + [UOP_LOAD_FUNC_ARG_0_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG0_IMM, + [UOP_LOAD_FUNC_ARG_1_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG1_IMM, + [UOP_LOAD_FUNC_ARG_2_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG2_IMM, + [UOP_LOAD_FUNC_ARG_3_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG3_IMM, - [UOP_STORE_P_IMM & UOP_MASK] = codegen_STORE_PTR_IMM, - [UOP_STORE_P_IMM_8 & UOP_MASK] = codegen_STORE_PTR_IMM_8, - [UOP_STORE_P_IMM_16 & UOP_MASK] = codegen_STORE_PTR_IMM_16, + [UOP_STORE_P_IMM & UOP_MASK] = codegen_STORE_PTR_IMM, + [UOP_STORE_P_IMM_8 & UOP_MASK] = codegen_STORE_PTR_IMM_8, + [UOP_STORE_P_IMM_16 & UOP_MASK] = codegen_STORE_PTR_IMM_16, - [UOP_MEM_LOAD_ABS & UOP_MASK] = codegen_MEM_LOAD_ABS, - [UOP_MEM_LOAD_REG & UOP_MASK] = codegen_MEM_LOAD_REG, - [UOP_MEM_LOAD_SINGLE & UOP_MASK] = codegen_MEM_LOAD_SINGLE, - [UOP_MEM_LOAD_DOUBLE & UOP_MASK] = codegen_MEM_LOAD_DOUBLE, + [UOP_MEM_LOAD_ABS & UOP_MASK] = codegen_MEM_LOAD_ABS, + [UOP_MEM_LOAD_REG & UOP_MASK] = codegen_MEM_LOAD_REG, + [UOP_MEM_LOAD_SINGLE & UOP_MASK] = codegen_MEM_LOAD_SINGLE, + [UOP_MEM_LOAD_DOUBLE & UOP_MASK] = codegen_MEM_LOAD_DOUBLE, - [UOP_MEM_STORE_ABS & UOP_MASK] = codegen_MEM_STORE_ABS, - [UOP_MEM_STORE_REG & UOP_MASK] = codegen_MEM_STORE_REG, - [UOP_MEM_STORE_IMM_8 & UOP_MASK] = codegen_MEM_STORE_IMM_8, - [UOP_MEM_STORE_IMM_16 & UOP_MASK] = codegen_MEM_STORE_IMM_16, - [UOP_MEM_STORE_IMM_32 & UOP_MASK] = codegen_MEM_STORE_IMM_32, - [UOP_MEM_STORE_SINGLE & UOP_MASK] = codegen_MEM_STORE_SINGLE, - [UOP_MEM_STORE_DOUBLE & UOP_MASK] = codegen_MEM_STORE_DOUBLE, + [UOP_MEM_STORE_ABS & UOP_MASK] = codegen_MEM_STORE_ABS, + [UOP_MEM_STORE_REG & UOP_MASK] = codegen_MEM_STORE_REG, + [UOP_MEM_STORE_IMM_8 & UOP_MASK] = codegen_MEM_STORE_IMM_8, + [UOP_MEM_STORE_IMM_16 & UOP_MASK] = codegen_MEM_STORE_IMM_16, + [UOP_MEM_STORE_IMM_32 & UOP_MASK] = codegen_MEM_STORE_IMM_32, + [UOP_MEM_STORE_SINGLE & UOP_MASK] = codegen_MEM_STORE_SINGLE, + [UOP_MEM_STORE_DOUBLE & UOP_MASK] = codegen_MEM_STORE_DOUBLE, - [UOP_MOV & UOP_MASK] = codegen_MOV, - [UOP_MOV_PTR & UOP_MASK] = codegen_MOV_PTR, - [UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM, - [UOP_MOVSX & UOP_MASK] = codegen_MOVSX, - [UOP_MOVZX & UOP_MASK] = codegen_MOVZX, - [UOP_MOV_DOUBLE_INT & UOP_MASK] = codegen_MOV_DOUBLE_INT, - [UOP_MOV_INT_DOUBLE & UOP_MASK] = codegen_MOV_INT_DOUBLE, - [UOP_MOV_INT_DOUBLE_64 & UOP_MASK] = codegen_MOV_INT_DOUBLE_64, - [UOP_MOV_REG_PTR & UOP_MASK] = codegen_MOV_REG_PTR, - [UOP_MOVZX_REG_PTR_8 & UOP_MASK] = codegen_MOVZX_REG_PTR_8, - [UOP_MOVZX_REG_PTR_16 & UOP_MASK] = codegen_MOVZX_REG_PTR_16, + [UOP_MOV & UOP_MASK] = codegen_MOV, + [UOP_MOV_PTR & UOP_MASK] = codegen_MOV_PTR, + [UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM, + [UOP_MOVSX & UOP_MASK] = codegen_MOVSX, + [UOP_MOVZX & UOP_MASK] = codegen_MOVZX, + [UOP_MOV_DOUBLE_INT & UOP_MASK] = codegen_MOV_DOUBLE_INT, + [UOP_MOV_INT_DOUBLE & UOP_MASK] = codegen_MOV_INT_DOUBLE, + [UOP_MOV_INT_DOUBLE_64 & UOP_MASK] = codegen_MOV_INT_DOUBLE_64, + [UOP_MOV_REG_PTR & UOP_MASK] = codegen_MOV_REG_PTR, + [UOP_MOVZX_REG_PTR_8 & UOP_MASK] = codegen_MOVZX_REG_PTR_8, + [UOP_MOVZX_REG_PTR_16 & UOP_MASK] = codegen_MOVZX_REG_PTR_16, - [UOP_ADD & UOP_MASK] = codegen_ADD, - [UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM, - [UOP_ADD_LSHIFT & UOP_MASK] = codegen_ADD_LSHIFT, - [UOP_AND & UOP_MASK] = codegen_AND, - [UOP_AND_IMM & UOP_MASK] = codegen_AND_IMM, - [UOP_ANDN & UOP_MASK] = codegen_ANDN, - [UOP_OR & UOP_MASK] = codegen_OR, - [UOP_OR_IMM & UOP_MASK] = codegen_OR_IMM, - [UOP_SUB & UOP_MASK] = codegen_SUB, - [UOP_SUB_IMM & UOP_MASK] = codegen_SUB_IMM, - [UOP_XOR & UOP_MASK] = codegen_XOR, - [UOP_XOR_IMM & UOP_MASK] = codegen_XOR_IMM, + [UOP_ADD & UOP_MASK] = codegen_ADD, + [UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM, + [UOP_ADD_LSHIFT & UOP_MASK] = codegen_ADD_LSHIFT, + [UOP_AND & UOP_MASK] = codegen_AND, + [UOP_AND_IMM & UOP_MASK] = codegen_AND_IMM, + [UOP_ANDN & UOP_MASK] = codegen_ANDN, + [UOP_OR & UOP_MASK] = codegen_OR, + [UOP_OR_IMM & UOP_MASK] = codegen_OR_IMM, + [UOP_SUB & UOP_MASK] = codegen_SUB, + [UOP_SUB_IMM & UOP_MASK] = codegen_SUB_IMM, + [UOP_XOR & UOP_MASK] = codegen_XOR, + [UOP_XOR_IMM & UOP_MASK] = codegen_XOR_IMM, - [UOP_SAR & UOP_MASK] = codegen_SAR, - [UOP_SAR_IMM & UOP_MASK] = codegen_SAR_IMM, - [UOP_SHL & UOP_MASK] = codegen_SHL, - [UOP_SHL_IMM & UOP_MASK] = codegen_SHL_IMM, - [UOP_SHR & UOP_MASK] = codegen_SHR, - [UOP_SHR_IMM & UOP_MASK] = codegen_SHR_IMM, - [UOP_ROL & UOP_MASK] = codegen_ROL, - [UOP_ROL_IMM & UOP_MASK] = codegen_ROL_IMM, - [UOP_ROR & UOP_MASK] = codegen_ROR, - [UOP_ROR_IMM & UOP_MASK] = codegen_ROR_IMM, + [UOP_SAR & UOP_MASK] = codegen_SAR, + [UOP_SAR_IMM & UOP_MASK] = codegen_SAR_IMM, + [UOP_SHL & UOP_MASK] = codegen_SHL, + [UOP_SHL_IMM & UOP_MASK] = codegen_SHL_IMM, + [UOP_SHR & UOP_MASK] = codegen_SHR, + [UOP_SHR_IMM & UOP_MASK] = codegen_SHR_IMM, + [UOP_ROL & UOP_MASK] = codegen_ROL, + [UOP_ROL_IMM & UOP_MASK] = codegen_ROL_IMM, + [UOP_ROR & UOP_MASK] = codegen_ROR, + [UOP_ROR_IMM & UOP_MASK] = codegen_ROR_IMM, - [UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ, + [UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ, - [UOP_CMP_JB & UOP_MASK] = codegen_CMP_JB, - [UOP_CMP_JNBE & UOP_MASK] = codegen_CMP_JNBE, + [UOP_CMP_JB & UOP_MASK] = codegen_CMP_JB, + [UOP_CMP_JNBE & UOP_MASK] = codegen_CMP_JNBE, - [UOP_CMP_JNB_DEST & UOP_MASK] = codegen_CMP_JNB_DEST, - [UOP_CMP_JNBE_DEST & UOP_MASK] = codegen_CMP_JNBE_DEST, - [UOP_CMP_JNL_DEST & UOP_MASK] = codegen_CMP_JNL_DEST, - [UOP_CMP_JNLE_DEST & UOP_MASK] = codegen_CMP_JNLE_DEST, - [UOP_CMP_JNO_DEST & UOP_MASK] = codegen_CMP_JNO_DEST, - [UOP_CMP_JNZ_DEST & UOP_MASK] = codegen_CMP_JNZ_DEST, - [UOP_CMP_JB_DEST & UOP_MASK] = codegen_CMP_JB_DEST, - [UOP_CMP_JBE_DEST & UOP_MASK] = codegen_CMP_JBE_DEST, - [UOP_CMP_JL_DEST & UOP_MASK] = codegen_CMP_JL_DEST, - [UOP_CMP_JLE_DEST & UOP_MASK] = codegen_CMP_JLE_DEST, - [UOP_CMP_JO_DEST & UOP_MASK] = codegen_CMP_JO_DEST, - [UOP_CMP_JZ_DEST & UOP_MASK] = codegen_CMP_JZ_DEST, + [UOP_CMP_JNB_DEST & UOP_MASK] = codegen_CMP_JNB_DEST, + [UOP_CMP_JNBE_DEST & UOP_MASK] = codegen_CMP_JNBE_DEST, + [UOP_CMP_JNL_DEST & UOP_MASK] = codegen_CMP_JNL_DEST, + [UOP_CMP_JNLE_DEST & UOP_MASK] = codegen_CMP_JNLE_DEST, + [UOP_CMP_JNO_DEST & UOP_MASK] = codegen_CMP_JNO_DEST, + [UOP_CMP_JNZ_DEST & UOP_MASK] = codegen_CMP_JNZ_DEST, + [UOP_CMP_JB_DEST & UOP_MASK] = codegen_CMP_JB_DEST, + [UOP_CMP_JBE_DEST & UOP_MASK] = codegen_CMP_JBE_DEST, + [UOP_CMP_JL_DEST & UOP_MASK] = codegen_CMP_JL_DEST, + [UOP_CMP_JLE_DEST & UOP_MASK] = codegen_CMP_JLE_DEST, + [UOP_CMP_JO_DEST & UOP_MASK] = codegen_CMP_JO_DEST, + [UOP_CMP_JZ_DEST & UOP_MASK] = codegen_CMP_JZ_DEST, - [UOP_CMP_IMM_JNZ_DEST & UOP_MASK] = codegen_CMP_IMM_JNZ_DEST, - [UOP_CMP_IMM_JZ_DEST & UOP_MASK] = codegen_CMP_IMM_JZ_DEST, + [UOP_CMP_IMM_JNZ_DEST & UOP_MASK] = codegen_CMP_IMM_JNZ_DEST, + [UOP_CMP_IMM_JZ_DEST & UOP_MASK] = codegen_CMP_IMM_JZ_DEST, - [UOP_TEST_JNS_DEST & UOP_MASK] = codegen_TEST_JNS_DEST, - [UOP_TEST_JS_DEST & UOP_MASK] = codegen_TEST_JS_DEST, + [UOP_TEST_JNS_DEST & UOP_MASK] = codegen_TEST_JNS_DEST, + [UOP_TEST_JS_DEST & UOP_MASK] = codegen_TEST_JS_DEST, - [UOP_FP_ENTER & UOP_MASK] = codegen_FP_ENTER, - [UOP_MMX_ENTER & UOP_MASK] = codegen_MMX_ENTER, + [UOP_FP_ENTER & UOP_MASK] = codegen_FP_ENTER, + [UOP_MMX_ENTER & UOP_MASK] = codegen_MMX_ENTER, - [UOP_FADD & UOP_MASK] = codegen_FADD, - [UOP_FDIV & UOP_MASK] = codegen_FDIV, - [UOP_FMUL & UOP_MASK] = codegen_FMUL, - [UOP_FSUB & UOP_MASK] = codegen_FSUB, - [UOP_FCOM & UOP_MASK] = codegen_FCOM, + [UOP_FADD & UOP_MASK] = codegen_FADD, + [UOP_FDIV & UOP_MASK] = codegen_FDIV, + [UOP_FMUL & UOP_MASK] = codegen_FMUL, + [UOP_FSUB & UOP_MASK] = codegen_FSUB, + [UOP_FCOM & UOP_MASK] = codegen_FCOM, - [UOP_FABS & UOP_MASK] = codegen_FABS, - [UOP_FCHS & UOP_MASK] = codegen_FCHS, - [UOP_FSQRT & UOP_MASK] = codegen_FSQRT, - [UOP_FTST & UOP_MASK] = codegen_FTST, + [UOP_FABS & UOP_MASK] = codegen_FABS, + [UOP_FCHS & UOP_MASK] = codegen_FCHS, + [UOP_FSQRT & UOP_MASK] = codegen_FSQRT, + [UOP_FTST & UOP_MASK] = codegen_FTST, - [UOP_PACKSSWB & UOP_MASK] = codegen_PACKSSWB, - [UOP_PACKSSDW & UOP_MASK] = codegen_PACKSSDW, - [UOP_PACKUSWB & UOP_MASK] = codegen_PACKUSWB, + [UOP_PACKSSWB & UOP_MASK] = codegen_PACKSSWB, + [UOP_PACKSSDW & UOP_MASK] = codegen_PACKSSDW, + [UOP_PACKUSWB & UOP_MASK] = codegen_PACKUSWB, - [UOP_PADDB & UOP_MASK] = codegen_PADDB, - [UOP_PADDW & UOP_MASK] = codegen_PADDW, - [UOP_PADDD & UOP_MASK] = codegen_PADDD, - [UOP_PADDSB & UOP_MASK] = codegen_PADDSB, - [UOP_PADDSW & UOP_MASK] = codegen_PADDSW, - [UOP_PADDUSB & UOP_MASK] = codegen_PADDUSB, - [UOP_PADDUSW & UOP_MASK] = codegen_PADDUSW, + [UOP_PADDB & UOP_MASK] = codegen_PADDB, + [UOP_PADDW & UOP_MASK] = codegen_PADDW, + [UOP_PADDD & UOP_MASK] = codegen_PADDD, + [UOP_PADDSB & UOP_MASK] = codegen_PADDSB, + [UOP_PADDSW & UOP_MASK] = codegen_PADDSW, + [UOP_PADDUSB & UOP_MASK] = codegen_PADDUSB, + [UOP_PADDUSW & UOP_MASK] = codegen_PADDUSW, - [UOP_PCMPEQB & UOP_MASK] = codegen_PCMPEQB, - [UOP_PCMPEQW & UOP_MASK] = codegen_PCMPEQW, - [UOP_PCMPEQD & UOP_MASK] = codegen_PCMPEQD, - [UOP_PCMPGTB & UOP_MASK] = codegen_PCMPGTB, - [UOP_PCMPGTW & UOP_MASK] = codegen_PCMPGTW, - [UOP_PCMPGTD & UOP_MASK] = codegen_PCMPGTD, + [UOP_PCMPEQB & UOP_MASK] = codegen_PCMPEQB, + [UOP_PCMPEQW & UOP_MASK] = codegen_PCMPEQW, + [UOP_PCMPEQD & UOP_MASK] = codegen_PCMPEQD, + [UOP_PCMPGTB & UOP_MASK] = codegen_PCMPGTB, + [UOP_PCMPGTW & UOP_MASK] = codegen_PCMPGTW, + [UOP_PCMPGTD & UOP_MASK] = codegen_PCMPGTD, - [UOP_PF2ID & UOP_MASK] = codegen_PF2ID, - [UOP_PFADD & UOP_MASK] = codegen_PFADD, - [UOP_PFCMPEQ & UOP_MASK] = codegen_PFCMPEQ, - [UOP_PFCMPGE & UOP_MASK] = codegen_PFCMPGE, - [UOP_PFCMPGT & UOP_MASK] = codegen_PFCMPGT, - [UOP_PFMAX & UOP_MASK] = codegen_PFMAX, - [UOP_PFMIN & UOP_MASK] = codegen_PFMIN, - [UOP_PFMUL & UOP_MASK] = codegen_PFMUL, - [UOP_PFRCP & UOP_MASK] = codegen_PFRCP, - [UOP_PFRSQRT & UOP_MASK] = codegen_PFRSQRT, - [UOP_PFSUB & UOP_MASK] = codegen_PFSUB, - [UOP_PI2FD & UOP_MASK] = codegen_PI2FD, + [UOP_PF2ID & UOP_MASK] = codegen_PF2ID, + [UOP_PFADD & UOP_MASK] = codegen_PFADD, + [UOP_PFCMPEQ & UOP_MASK] = codegen_PFCMPEQ, + [UOP_PFCMPGE & UOP_MASK] = codegen_PFCMPGE, + [UOP_PFCMPGT & UOP_MASK] = codegen_PFCMPGT, + [UOP_PFMAX & UOP_MASK] = codegen_PFMAX, + [UOP_PFMIN & UOP_MASK] = codegen_PFMIN, + [UOP_PFMUL & UOP_MASK] = codegen_PFMUL, + [UOP_PFRCP & UOP_MASK] = codegen_PFRCP, + [UOP_PFRSQRT & UOP_MASK] = codegen_PFRSQRT, + [UOP_PFSUB & UOP_MASK] = codegen_PFSUB, + [UOP_PI2FD & UOP_MASK] = codegen_PI2FD, - [UOP_PMADDWD & UOP_MASK] = codegen_PMADDWD, - [UOP_PMULHW & UOP_MASK] = codegen_PMULHW, - [UOP_PMULLW & UOP_MASK] = codegen_PMULLW, + [UOP_PMADDWD & UOP_MASK] = codegen_PMADDWD, + [UOP_PMULHW & UOP_MASK] = codegen_PMULHW, + [UOP_PMULLW & UOP_MASK] = codegen_PMULLW, - [UOP_PSLLW_IMM & UOP_MASK] = codegen_PSLLW_IMM, - [UOP_PSLLD_IMM & UOP_MASK] = codegen_PSLLD_IMM, - [UOP_PSLLQ_IMM & UOP_MASK] = codegen_PSLLQ_IMM, - [UOP_PSRAW_IMM & UOP_MASK] = codegen_PSRAW_IMM, - [UOP_PSRAD_IMM & UOP_MASK] = codegen_PSRAD_IMM, - [UOP_PSRAQ_IMM & UOP_MASK] = codegen_PSRAQ_IMM, - [UOP_PSRLW_IMM & UOP_MASK] = codegen_PSRLW_IMM, - [UOP_PSRLD_IMM & UOP_MASK] = codegen_PSRLD_IMM, - [UOP_PSRLQ_IMM & UOP_MASK] = codegen_PSRLQ_IMM, + [UOP_PSLLW_IMM & UOP_MASK] = codegen_PSLLW_IMM, + [UOP_PSLLD_IMM & UOP_MASK] = codegen_PSLLD_IMM, + [UOP_PSLLQ_IMM & UOP_MASK] = codegen_PSLLQ_IMM, + [UOP_PSRAW_IMM & UOP_MASK] = codegen_PSRAW_IMM, + [UOP_PSRAD_IMM & UOP_MASK] = codegen_PSRAD_IMM, + [UOP_PSRAQ_IMM & UOP_MASK] = codegen_PSRAQ_IMM, + [UOP_PSRLW_IMM & UOP_MASK] = codegen_PSRLW_IMM, + [UOP_PSRLD_IMM & UOP_MASK] = codegen_PSRLD_IMM, + [UOP_PSRLQ_IMM & UOP_MASK] = codegen_PSRLQ_IMM, - [UOP_PSUBB & UOP_MASK] = codegen_PSUBB, - [UOP_PSUBW & UOP_MASK] = codegen_PSUBW, - [UOP_PSUBD & UOP_MASK] = codegen_PSUBD, - [UOP_PSUBSB & UOP_MASK] = codegen_PSUBSB, - [UOP_PSUBSW & UOP_MASK] = codegen_PSUBSW, - [UOP_PSUBUSB & UOP_MASK] = codegen_PSUBUSB, - [UOP_PSUBUSW & UOP_MASK] = codegen_PSUBUSW, + [UOP_PSUBB & UOP_MASK] = codegen_PSUBB, + [UOP_PSUBW & UOP_MASK] = codegen_PSUBW, + [UOP_PSUBD & UOP_MASK] = codegen_PSUBD, + [UOP_PSUBSB & UOP_MASK] = codegen_PSUBSB, + [UOP_PSUBSW & UOP_MASK] = codegen_PSUBSW, + [UOP_PSUBUSB & UOP_MASK] = codegen_PSUBUSB, + [UOP_PSUBUSW & UOP_MASK] = codegen_PSUBUSW, - [UOP_PUNPCKHBW & UOP_MASK] = codegen_PUNPCKHBW, - [UOP_PUNPCKHWD & UOP_MASK] = codegen_PUNPCKHWD, - [UOP_PUNPCKHDQ & UOP_MASK] = codegen_PUNPCKHDQ, - [UOP_PUNPCKLBW & UOP_MASK] = codegen_PUNPCKLBW, - [UOP_PUNPCKLWD & UOP_MASK] = codegen_PUNPCKLWD, - [UOP_PUNPCKLDQ & UOP_MASK] = codegen_PUNPCKLDQ, + [UOP_PUNPCKHBW & UOP_MASK] = codegen_PUNPCKHBW, + [UOP_PUNPCKHWD & UOP_MASK] = codegen_PUNPCKHWD, + [UOP_PUNPCKHDQ & UOP_MASK] = codegen_PUNPCKHDQ, + [UOP_PUNPCKLBW & UOP_MASK] = codegen_PUNPCKLBW, + [UOP_PUNPCKLWD & UOP_MASK] = codegen_PUNPCKLWD, + [UOP_PUNPCKLDQ & UOP_MASK] = codegen_PUNPCKLDQ, - [UOP_NOP_BARRIER & UOP_MASK] = codegen_NOP, + [UOP_NOP_BARRIER & UOP_MASK] = codegen_NOP, #ifdef DEBUG_EXTRA - [UOP_LOG_INSTR & UOP_MASK] = codegen_LOG_INSTR + [UOP_LOG_INSTR & UOP_MASK] = codegen_LOG_INSTR #endif - }; +}; -void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p) { - host_x86_MOV8_REG_ABS(block, host_reg, p); -} -void codegen_direct_read_16(codeblock_t *block, int host_reg, void *p) { - host_x86_MOV16_REG_ABS(block, host_reg, p); -} -void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) { - host_x86_MOV32_REG_ABS(block, host_reg, p); -} -void codegen_direct_read_pointer(codeblock_t *block, int host_reg, void *p) { - codegen_direct_read_32(block, host_reg, p); -} -void codegen_direct_read_64(codeblock_t *block, int host_reg, void *p) { - host_x86_MOVQ_XREG_ABS(block, host_reg, p); -} -void codegen_direct_read_double(codeblock_t *block, int host_reg, void *p) { - host_x86_MOVQ_XREG_ABS(block, host_reg, p); -} +void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p) { host_x86_MOV8_REG_ABS(block, host_reg, p); } +void codegen_direct_read_16(codeblock_t *block, int host_reg, void *p) { host_x86_MOV16_REG_ABS(block, host_reg, p); } +void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) { host_x86_MOV32_REG_ABS(block, host_reg, p); } +void codegen_direct_read_pointer(codeblock_t *block, int host_reg, void *p) { codegen_direct_read_32(block, host_reg, p); } +void codegen_direct_read_64(codeblock_t *block, int host_reg, void *p) { host_x86_MOVQ_XREG_ABS(block, host_reg, p); } +void codegen_direct_read_double(codeblock_t *block, int host_reg, void *p) { host_x86_MOVQ_XREG_ABS(block, host_reg, p); } void codegen_direct_read_st_8(codeblock_t *block, int host_reg, void *base, int reg_idx) { - int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); - host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_ESP, IREG_TOP_diff_stack_offset); - host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); - host_x86_AND32_REG_IMM(block, REG_ECX, 7); - host_x86_MOV8_REG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_EBP, REG_ECX, 0); + host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_ESP, IREG_TOP_diff_stack_offset); + host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, 7); + host_x86_MOV8_REG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_EBP, REG_ECX, 0); } void codegen_direct_read_st_64(codeblock_t *block, int host_reg, void *base, int reg_idx) { - int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); - host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_ESP, IREG_TOP_diff_stack_offset); - host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); - host_x86_AND32_REG_IMM(block, REG_ECX, 7); - host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_EBP, REG_ECX, 3); + host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_ESP, IREG_TOP_diff_stack_offset); + host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, 7); + host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_EBP, REG_ECX, 3); } void codegen_direct_read_st_double(codeblock_t *block, int host_reg, void *base, int reg_idx) { - int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); - host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_ESP, IREG_TOP_diff_stack_offset); - host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); - host_x86_AND32_REG_IMM(block, REG_ECX, 7); - host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_EBP, REG_ECX, 3); + host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_ESP, IREG_TOP_diff_stack_offset); + host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, 7); + host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_EBP, REG_ECX, 3); } -void codegen_direct_write_8(codeblock_t *block, void *p, int host_reg) { - host_x86_MOV8_ABS_REG(block, p, host_reg); -} -void codegen_direct_write_16(codeblock_t *block, void *p, int host_reg) { - host_x86_MOV16_ABS_REG(block, p, host_reg); -} -void codegen_direct_write_32(codeblock_t *block, void *p, int host_reg) { - host_x86_MOV32_ABS_REG(block, p, host_reg); -} -void codegen_direct_write_64(codeblock_t *block, void *p, int host_reg) { - host_x86_MOVQ_ABS_XREG(block, p, host_reg); -} -void codegen_direct_write_double(codeblock_t *block, void *p, int host_reg) { - host_x86_MOVQ_ABS_XREG(block, p, host_reg); -} +void codegen_direct_write_8(codeblock_t *block, void *p, int host_reg) { host_x86_MOV8_ABS_REG(block, p, host_reg); } +void codegen_direct_write_16(codeblock_t *block, void *p, int host_reg) { host_x86_MOV16_ABS_REG(block, p, host_reg); } +void codegen_direct_write_32(codeblock_t *block, void *p, int host_reg) { host_x86_MOV32_ABS_REG(block, p, host_reg); } +void codegen_direct_write_64(codeblock_t *block, void *p, int host_reg) { host_x86_MOVQ_ABS_XREG(block, p, host_reg); } +void codegen_direct_write_double(codeblock_t *block, void *p, int host_reg) { host_x86_MOVQ_ABS_XREG(block, p, host_reg); } void codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int host_reg) { - int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); - host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_ESP, IREG_TOP_diff_stack_offset); - host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); - host_x86_AND32_REG_IMM(block, REG_ECX, 7); - host_x86_MOV8_ABS_REG_REG_SHIFT_REG(block, offset, REG_EBP, REG_ECX, 0, host_reg); + host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_ESP, IREG_TOP_diff_stack_offset); + host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, 7); + host_x86_MOV8_ABS_REG_REG_SHIFT_REG(block, offset, REG_EBP, REG_ECX, 0, host_reg); } void codegen_direct_write_st_64(codeblock_t *block, void *base, int reg_idx, int host_reg) { - int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); - host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_ESP, IREG_TOP_diff_stack_offset); - host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); - host_x86_AND32_REG_IMM(block, REG_ECX, 7); - host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(block, offset, REG_EBP, REG_ECX, 3, host_reg); + host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_ESP, IREG_TOP_diff_stack_offset); + host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, 7); + host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(block, offset, REG_EBP, REG_ECX, 3, host_reg); } void codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx, int host_reg) { - int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); - host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_ESP, IREG_TOP_diff_stack_offset); - host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); - host_x86_AND32_REG_IMM(block, REG_ECX, 7); - host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(block, offset, REG_EBP, REG_ECX, 3, host_reg); + host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_ESP, IREG_TOP_diff_stack_offset); + host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, 7); + host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(block, offset, REG_EBP, REG_ECX, 3, host_reg); } -void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg) { - host_x86_MOV32_ABS_REG(block, p, host_reg); -} +void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg) { host_x86_MOV32_ABS_REG(block, p, host_reg); } void codegen_direct_read_16_stack(codeblock_t *block, int host_reg, int stack_offset) { - host_x86_MOV16_REG_BASE_OFFSET(block, host_reg, REG_ESP, stack_offset); + host_x86_MOV16_REG_BASE_OFFSET(block, host_reg, REG_ESP, stack_offset); } void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_offset) { - host_x86_MOV32_REG_BASE_OFFSET(block, host_reg, REG_ESP, stack_offset); + host_x86_MOV32_REG_BASE_OFFSET(block, host_reg, REG_ESP, stack_offset); } void codegen_direct_read_pointer_stack(codeblock_t *block, int host_reg, int stack_offset) { - codegen_direct_read_32_stack(block, host_reg, stack_offset); + codegen_direct_read_32_stack(block, host_reg, stack_offset); } void codegen_direct_read_64_stack(codeblock_t *block, int host_reg, int stack_offset) { - host_x86_MOVQ_XREG_BASE_OFFSET(block, host_reg, REG_ESP, stack_offset); + host_x86_MOVQ_XREG_BASE_OFFSET(block, host_reg, REG_ESP, stack_offset); } void codegen_direct_read_double_stack(codeblock_t *block, int host_reg, int stack_offset) { - host_x86_MOVQ_XREG_BASE_OFFSET(block, host_reg, REG_ESP, stack_offset); + host_x86_MOVQ_XREG_BASE_OFFSET(block, host_reg, REG_ESP, stack_offset); } void codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int host_reg) { - host_x86_MOV32_BASE_OFFSET_REG(block, REG_ESP, stack_offset, host_reg); + host_x86_MOV32_BASE_OFFSET_REG(block, REG_ESP, stack_offset, host_reg); } void codegen_direct_write_64_stack(codeblock_t *block, int stack_offset, int host_reg) { - host_x86_MOVQ_BASE_OFFSET_XREG(block, REG_ESP, stack_offset, host_reg); + host_x86_MOVQ_BASE_OFFSET_XREG(block, REG_ESP, stack_offset, host_reg); } void codegen_direct_write_double_stack(codeblock_t *block, int stack_offset, int host_reg) { - host_x86_MOVQ_BASE_OFFSET_XREG(block, REG_ESP, stack_offset, host_reg); + host_x86_MOVQ_BASE_OFFSET_XREG(block, REG_ESP, stack_offset, host_reg); } void codegen_set_jump_dest(codeblock_t *block, void *p) { - *(uint32_t *)p = (uintptr_t)&block_write_data[block_pos] - ((uintptr_t)p + 4); + *(uint32_t *)p = (uintptr_t)&block_write_data[block_pos] - ((uintptr_t)p + 4); } -void codegen_direct_write_8_imm(codeblock_t *block, void *p, uint8_t imm_data) { - host_x86_MOV8_ABS_IMM(block, p, imm_data); -} -void codegen_direct_write_16_imm(codeblock_t *block, void *p, uint16_t imm_data) { - host_x86_MOV16_ABS_IMM(block, p, imm_data); -} -void codegen_direct_write_32_imm(codeblock_t *block, void *p, uint32_t imm_data) { - host_x86_MOV32_ABS_IMM(block, p, imm_data); -} +void codegen_direct_write_8_imm(codeblock_t *block, void *p, uint8_t imm_data) { host_x86_MOV8_ABS_IMM(block, p, imm_data); } +void codegen_direct_write_16_imm(codeblock_t *block, void *p, uint16_t imm_data) { host_x86_MOV16_ABS_IMM(block, p, imm_data); } +void codegen_direct_write_32_imm(codeblock_t *block, void *p, uint32_t imm_data) { host_x86_MOV32_ABS_IMM(block, p, imm_data); } void codegen_direct_write_32_imm_stack(codeblock_t *block, int stack_offset, uint32_t imm_data) { - host_x86_MOV32_BASE_OFFSET_IMM(block, REG_ESP, stack_offset, imm_data); + host_x86_MOV32_BASE_OFFSET_IMM(block, REG_ESP, stack_offset, imm_data); } #endif diff --git a/src/cpu/386.c b/src/cpu/386.c index 68617920..db230a50 100644 --- a/src/cpu/386.c +++ b/src/cpu/386.c @@ -18,100 +18,132 @@ #define CPU_BLOCK_END() static inline void fetch_ea_32_long(uint32_t rmdat) { - eal_r = eal_w = NULL; - easeg = cpu_state.ea_seg->base; - if (cpu_rm == 4) { - uint8_t sib = rmdat >> 8; + eal_r = eal_w = NULL; + easeg = cpu_state.ea_seg->base; + if (cpu_rm == 4) { + uint8_t sib = rmdat >> 8; - switch (cpu_mod) { - case 0:cpu_state.eaaddr = cpu_state.regs[sib & 7].l; - cpu_state.pc++; - break; - case 1:cpu_state.pc++; - cpu_state.eaaddr = ((uint32_t)(int8_t)getbyte()) + cpu_state.regs[sib & 7].l; -// pc++; - break; - case 2:cpu_state.eaaddr = (fastreadl(cs + cpu_state.pc + 1)) + cpu_state.regs[sib & 7].l; - cpu_state.pc += 5; - break; - } - /*SIB byte present*/ - if ((sib & 7) == 5 && !cpu_mod) - cpu_state.eaaddr = getlong(); - else if ((sib & 6) == 4 && !cpu_state.ssegs) { - easeg = ss; - cpu_state.ea_seg = &cpu_state.seg_ss; - } - if (((sib >> 3) & 7) != 4) - cpu_state.eaaddr += cpu_state.regs[(sib >> 3) & 7].l << (sib >> 6); - } else { - cpu_state.eaaddr = cpu_state.regs[cpu_rm].l; - if (cpu_mod) { - if (cpu_rm == 5 && !cpu_state.ssegs) { - easeg = ss; - cpu_state.ea_seg = &cpu_state.seg_ss; - } - if (cpu_mod == 1) { - cpu_state.eaaddr += ((uint32_t)(int8_t)(rmdat >> 8)); - cpu_state.pc++; - } else { - cpu_state.eaaddr += getlong(); - } - } else if (cpu_rm == 5) { - cpu_state.eaaddr = getlong(); - } - } - if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) { - uint32_t addr = easeg + cpu_state.eaaddr; - if (readlookup2[addr >> 12] != -1) - eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); - if (writelookup2[addr >> 12] != -1) - eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); - } + switch (cpu_mod) { + case 0: + cpu_state.eaaddr = cpu_state.regs[sib & 7].l; + cpu_state.pc++; + break; + case 1: + cpu_state.pc++; + cpu_state.eaaddr = ((uint32_t)(int8_t)getbyte()) + cpu_state.regs[sib & 7].l; + // pc++; + break; + case 2: + cpu_state.eaaddr = (fastreadl(cs + cpu_state.pc + 1)) + cpu_state.regs[sib & 7].l; + cpu_state.pc += 5; + break; + } + /*SIB byte present*/ + if ((sib & 7) == 5 && !cpu_mod) + cpu_state.eaaddr = getlong(); + else if ((sib & 6) == 4 && !cpu_state.ssegs) { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + if (((sib >> 3) & 7) != 4) + cpu_state.eaaddr += cpu_state.regs[(sib >> 3) & 7].l << (sib >> 6); + } else { + cpu_state.eaaddr = cpu_state.regs[cpu_rm].l; + if (cpu_mod) { + if (cpu_rm == 5 && !cpu_state.ssegs) { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + if (cpu_mod == 1) { + cpu_state.eaaddr += ((uint32_t)(int8_t)(rmdat >> 8)); + cpu_state.pc++; + } else { + cpu_state.eaaddr += getlong(); + } + } else if (cpu_rm == 5) { + cpu_state.eaaddr = getlong(); + } + } + if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) { + uint32_t addr = easeg + cpu_state.eaaddr; + if (readlookup2[addr >> 12] != -1) + eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); + if (writelookup2[addr >> 12] != -1) + eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); + } } static inline void fetch_ea_16_long(uint32_t rmdat) { - eal_r = eal_w = NULL; - easeg = cpu_state.ea_seg->base; - if (!cpu_mod && cpu_rm == 6) { - cpu_state.eaaddr = getword(); - } else { - switch (cpu_mod) { - case 0:cpu_state.eaaddr = 0; - break; - case 1:cpu_state.eaaddr = (uint16_t)(int8_t)(rmdat >> 8); - cpu_state.pc++; - break; - case 2:cpu_state.eaaddr = getword(); - break; - } - cpu_state.eaaddr += (*mod1add[0][cpu_rm]) + (*mod1add[1][cpu_rm]); - if (mod1seg[cpu_rm] == &ss && !cpu_state.ssegs) { - easeg = ss; - cpu_state.ea_seg = &cpu_state.seg_ss; - } - cpu_state.eaaddr &= 0xFFFF; - } - if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) { - uint32_t addr = easeg + cpu_state.eaaddr; - if (readlookup2[addr >> 12] != -1) - eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); - if (writelookup2[addr >> 12] != -1) - eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); - } + eal_r = eal_w = NULL; + easeg = cpu_state.ea_seg->base; + if (!cpu_mod && cpu_rm == 6) { + cpu_state.eaaddr = getword(); + } else { + switch (cpu_mod) { + case 0: + cpu_state.eaaddr = 0; + break; + case 1: + cpu_state.eaaddr = (uint16_t)(int8_t)(rmdat >> 8); + cpu_state.pc++; + break; + case 2: + cpu_state.eaaddr = getword(); + break; + } + cpu_state.eaaddr += (*mod1add[0][cpu_rm]) + (*mod1add[1][cpu_rm]); + if (mod1seg[cpu_rm] == &ss && !cpu_state.ssegs) { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + cpu_state.eaaddr &= 0xFFFF; + } + if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) { + uint32_t addr = easeg + cpu_state.eaaddr; + if (readlookup2[addr >> 12] != -1) + eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); + if (writelookup2[addr >> 12] != -1) + eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); + } } -#define fetch_ea_16(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_16_long(rmdat); if (cpu_state.abrt) return 0; } -#define fetch_ea_32(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_32_long(rmdat); } if (cpu_state.abrt) return 0 +#define fetch_ea_16(rmdat) \ + cpu_state.pc++; \ + cpu_mod = (rmdat >> 6) & 3; \ + cpu_reg = (rmdat >> 3) & 7; \ + cpu_rm = rmdat & 7; \ + if (cpu_mod != 3) { \ + fetch_ea_16_long(rmdat); \ + if (cpu_state.abrt) \ + return 0; \ + } +#define fetch_ea_32(rmdat) \ + cpu_state.pc++; \ + cpu_mod = (rmdat >> 6) & 3; \ + cpu_reg = (rmdat >> 3) & 7; \ + cpu_rm = rmdat & 7; \ + if (cpu_mod != 3) { \ + fetch_ea_32_long(rmdat); \ + } \ + if (cpu_state.abrt) \ + return 0 #include "x86_flags.h" -#define getbytef() ((uint8_t)(fetchdat)); cpu_state.pc++ -#define getwordf() ((uint16_t)(fetchdat)); cpu_state.pc+=2 -#define getbyte2f() ((uint8_t)(fetchdat>>8)); cpu_state.pc++ -#define getword2f() ((uint16_t)(fetchdat>>8)); cpu_state.pc+=2 +#define getbytef() \ + ((uint8_t)(fetchdat)); \ + cpu_state.pc++ +#define getwordf() \ + ((uint16_t)(fetchdat)); \ + cpu_state.pc += 2 +#define getbyte2f() \ + ((uint8_t)(fetchdat >> 8)); \ + cpu_state.pc++ +#define getword2f() \ + ((uint16_t)(fetchdat >> 8)); \ + cpu_state.pc += 2 -#define OP_TABLE(name) ops_ ## name +#define OP_TABLE(name) ops_##name #define CLOCK_CYCLES(c) cycles -= (c) #define CLOCK_CYCLES_ALWAYS(c) cycles -= (c) @@ -119,169 +151,145 @@ static inline void fetch_ea_16_long(uint32_t rmdat) { #include "x86_ops.h" void exec386(int cycs) { - uint8_t temp; - uint32_t addr; - int tempi; - int cycdiff; - int oldcyc; + uint8_t temp; + uint32_t addr; + int tempi; + int cycdiff; + int oldcyc; - cycles += cycs; -// output=3; - while (cycles > 0) { - int cycle_period = (timer_target - (uint32_t)tsc) + 1; + cycles += cycs; + // output=3; + while (cycles > 0) { + int cycle_period = (timer_target - (uint32_t)tsc) + 1; - x86_was_reset = 0; - cycdiff = 0; - oldcyc = cycles; -// pclog("%i %02X\n", ins, ram[8]); - while (cycdiff < cycle_period) { - int ins_cycles = cycles; + x86_was_reset = 0; + cycdiff = 0; + oldcyc = cycles; + // pclog("%i %02X\n", ins, ram[8]); + while (cycdiff < cycle_period) { + int ins_cycles = cycles; - cpu_state.oldpc = cpu_state.pc; - cpu_state.op32 = use32; + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; - cpu_state.ea_seg = &cpu_state.seg_ds; - cpu_state.ssegs = 0; + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; - fetchdat = fastreadl(cs + cpu_state.pc); + fetchdat = fastreadl(cs + cpu_state.pc); - if (!cpu_state.abrt) { - uint8_t opcode = fetchdat & 0xFF; - fetchdat >>= 8; - trap = cpu_state.flags & T_FLAG; + if (!cpu_state.abrt) { + uint8_t opcode = fetchdat & 0xFF; + fetchdat >>= 8; + trap = cpu_state.flags & T_FLAG; - if (output == 3) { - pclog("%04X(%06X):%04X : %08X %08X %08X %08X %04X %04X %04X(%08X) %04X %04X %04X(%08X) %08X %08X %08X SP=%04X:%08X %02X %04X %i %08X %08X %i %i %02X %02X %02X %02X %02X\n", - CS, - cs, - cpu_state.pc, - EAX, - EBX, - ECX, - EDX, - CS, - DS, - ES, - es, - FS, - GS, - SS, - ss, - EDI, - ESI, - EBP, - SS, - ESP, - opcode, - cpu_state.flags, - ins, - 0, - ldt.base, - CPL, - stack32, - pic.pend, - pic.mask, - pic.mask2, - pic2.pend, - pic2.mask); - } - cpu_state.pc++; - x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); - if (x86_was_reset) - break; - } + if (output == 3) { + pclog("%04X(%06X):%04X : %08X %08X %08X %08X %04X %04X %04X(%08X) %04X %04X %04X(%08X) " + "%08X %08X %08X SP=%04X:%08X %02X %04X %i %08X %08X %i %i %02X %02X %02X %02X " + "%02X\n", + CS, cs, cpu_state.pc, EAX, EBX, ECX, EDX, CS, DS, ES, es, FS, GS, SS, ss, EDI, ESI, + EBP, SS, ESP, opcode, cpu_state.flags, ins, 0, ldt.base, CPL, stack32, pic.pend, + pic.mask, pic.mask2, pic2.pend, pic2.mask); + } + cpu_state.pc++; + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + if (x86_was_reset) + break; + } - if (cpu_state.abrt) { - flags_rebuild(); -// pclog("Abort\n"); -// if (CS == 0x228) pclog("Abort at %04X:%04X - %i %i %i\n",CS,pc,notpresent,nullseg,abrt); - tempi = cpu_state.abrt & ABRT_MASK; - cpu_state.abrt = 0; - x86_doabrt(tempi); - if (cpu_state.abrt) { - cpu_state.abrt = 0; - cpu_state.pc = cpu_state.oldpc; - pclog("Double fault %i\n", ins); - pmodeint(8, 0); - if (cpu_state.abrt) { - cpu_state.abrt = 0; - softresetx86(); - cpu_set_edx(); - pclog("Triple fault - reset\n"); - } - } - } + if (cpu_state.abrt) { + flags_rebuild(); + // pclog("Abort\n"); + // if (CS == 0x228) pclog("Abort at %04X:%04X - %i %i + // %i\n",CS,pc,notpresent,nullseg,abrt); + tempi = cpu_state.abrt & ABRT_MASK; + cpu_state.abrt = 0; + x86_doabrt(tempi); + if (cpu_state.abrt) { + cpu_state.abrt = 0; + cpu_state.pc = cpu_state.oldpc; + pclog("Double fault %i\n", ins); + pmodeint(8, 0); + if (cpu_state.abrt) { + cpu_state.abrt = 0; + softresetx86(); + cpu_set_edx(); + pclog("Triple fault - reset\n"); + } + } + } - if (cpu_state.smi_pending) { - cpu_state.smi_pending = 0; - x86_smi_enter(); - } else if (trap) { - flags_rebuild(); -// oldpc=pc; - if (msw & 1) { - pmodeint(1, 0); - } else { - writememw(ss, (SP - 2) & 0xFFFF, cpu_state.flags); - writememw(ss, (SP - 4) & 0xFFFF, CS); - writememw(ss, (SP - 6) & 0xFFFF, cpu_state.pc); - SP -= 6; - addr = (1 << 2) + idt.base; - cpu_state.flags &= ~I_FLAG; - cpu_state.flags &= ~T_FLAG; - cpu_state.pc = readmemw(0, addr); - loadcs(readmemw(0, addr + 2)); - } - } else if (nmi && nmi_enable && nmi_mask) { - cpu_state.oldpc = cpu_state.pc; -// pclog("NMI\n"); - x86_int(2); - nmi_enable = 0; - if (nmi_auto_clear) { - nmi_auto_clear = 0; - nmi = 0; - } - } else if ((cpu_state.flags & I_FLAG) && pic_intpending) { - temp = picinterrupt(); - if (temp != 0xFF) { -// if (temp == 0x54) pclog("Take int 54\n"); -// if (output) output=3; -// if (temp == 0xd) pclog("Hardware int %02X %i %04X(%08X):%08X\n",temp,ins, CS,cs,pc); -// if (temp==0x54) output=3; - flags_rebuild(); - if (msw & 1) { - pmodeint(temp, 0); - } else { - writememw(ss, (SP - 2) & 0xFFFF, cpu_state.flags); - writememw(ss, (SP - 4) & 0xFFFF, CS); - writememw(ss, (SP - 6) & 0xFFFF, cpu_state.pc); - SP -= 6; - addr = (temp << 2) + idt.base; - cpu_state.flags &= ~I_FLAG; - cpu_state.flags &= ~T_FLAG; - cpu_state.pc = readmemw(0, addr); - loadcs(readmemw(0, addr + 2)); -// if (temp==0x76) pclog("INT to %04X:%04X\n",CS,pc); - } -// pclog("Now at %04X(%08X):%08X\n", CS, cs, pc); - } - } + if (cpu_state.smi_pending) { + cpu_state.smi_pending = 0; + x86_smi_enter(); + } else if (trap) { + flags_rebuild(); + // oldpc=pc; + if (msw & 1) { + pmodeint(1, 0); + } else { + writememw(ss, (SP - 2) & 0xFFFF, cpu_state.flags); + writememw(ss, (SP - 4) & 0xFFFF, CS); + writememw(ss, (SP - 6) & 0xFFFF, cpu_state.pc); + SP -= 6; + addr = (1 << 2) + idt.base; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; + cpu_state.pc = readmemw(0, addr); + loadcs(readmemw(0, addr + 2)); + } + } else if (nmi && nmi_enable && nmi_mask) { + cpu_state.oldpc = cpu_state.pc; + // pclog("NMI\n"); + x86_int(2); + nmi_enable = 0; + if (nmi_auto_clear) { + nmi_auto_clear = 0; + nmi = 0; + } + } else if ((cpu_state.flags & I_FLAG) && pic_intpending) { + temp = picinterrupt(); + if (temp != 0xFF) { + // if (temp == 0x54) pclog("Take int 54\n"); + // if (output) output=3; + // if (temp == 0xd) pclog("Hardware int %02X %i + // %04X(%08X):%08X\n",temp,ins, CS,cs,pc); if (temp==0x54) + // output=3; + flags_rebuild(); + if (msw & 1) { + pmodeint(temp, 0); + } else { + writememw(ss, (SP - 2) & 0xFFFF, cpu_state.flags); + writememw(ss, (SP - 4) & 0xFFFF, CS); + writememw(ss, (SP - 6) & 0xFFFF, cpu_state.pc); + SP -= 6; + addr = (temp << 2) + idt.base; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; + cpu_state.pc = readmemw(0, addr); + loadcs(readmemw(0, addr + 2)); + // if (temp==0x76) pclog("INT to + // %04X:%04X\n",CS,pc); + } + // pclog("Now at %04X(%08X):%08X\n", CS, cs, pc); + } + } - ins++; - insc++; + ins++; + insc++; - ins_cycles -= cycles; - tsc += ins_cycles; + ins_cycles -= cycles; + tsc += ins_cycles; - cycdiff = oldcyc - cycles; + cycdiff = oldcyc - cycles; - if (timetolive) { - timetolive--; - if (!timetolive) - fatal("Life expired\n"); - } - } + if (timetolive) { + timetolive--; + if (!timetolive) + fatal("Life expired\n"); + } + } - if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc)) - timer_process(); - } + if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc)) + timer_process(); + } } diff --git a/src/cpu/386_common.c b/src/cpu/386_common.c index 0e27ada5..27111683 100644 --- a/src/cpu/386_common.c +++ b/src/cpu/386_common.c @@ -34,196 +34,193 @@ uint32_t pccache; uint8_t *pccache2; void x86_int(int num) { - uint32_t addr; -// pclog("x86_int %02x %04x:%04x\n", num, CS,pc); - flags_rebuild(); - cpu_state.pc = cpu_state.oldpc; - if (msw & 1) { - pmodeint(num, 0); - } else { - addr = (num << 2) + idt.base; + uint32_t addr; + // pclog("x86_int %02x %04x:%04x\n", num, CS,pc); + 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(); - pclog("Triple fault in real mode - reset\n"); - } else - x86_int(8); - } else { - if (stack32) { - writememw(ss, ESP - 2, cpu_state.flags); - writememw(ss, ESP - 4, CS); - writememw(ss, ESP - 6, cpu_state.pc); - ESP -= 6; - } else { - writememw(ss, ((SP - 2) & 0xFFFF), cpu_state.flags); - writememw(ss, ((SP - 4) & 0xFFFF), CS); - writememw(ss, ((SP - 6) & 0xFFFF), cpu_state.pc); - SP -= 6; - } + if ((num << 2) + 3 > idt.limit) { + if (idt.limit < 35) { + cpu_state.abrt = 0; + softresetx86(); + cpu_set_edx(); + pclog("Triple fault in real mode - reset\n"); + } else + x86_int(8); + } else { + if (stack32) { + writememw(ss, ESP - 2, cpu_state.flags); + writememw(ss, ESP - 4, CS); + writememw(ss, ESP - 6, cpu_state.pc); + ESP -= 6; + } else { + writememw(ss, ((SP - 2) & 0xFFFF), cpu_state.flags); + writememw(ss, ((SP - 4) & 0xFFFF), CS); + writememw(ss, ((SP - 6) & 0xFFFF), cpu_state.pc); + SP -= 6; + } - cpu_state.flags &= ~I_FLAG; - cpu_state.flags &= ~T_FLAG; - cpu_state.pc = readmemw(0, addr); - loadcs(readmemw(0, addr + 2)); - } - } - cycles -= 70; - CPU_BLOCK_END(); + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; + 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; -// pclog("x86_int_sw %02x %04x:%04x\n", num, CS,pc); -// pclog("x86_int\n"); - flags_rebuild(); - cycles -= timing_int; - if (msw & 1) { - pmodeint(num, 1); - } else { - addr = (num << 2) + idt.base; + uint32_t addr; + // pclog("x86_int_sw %02x %04x:%04x\n", num, CS,pc); + // pclog("x86_int\n"); + flags_rebuild(); + cycles -= timing_int; + if (msw & 1) { + pmodeint(num, 1); + } else { + addr = (num << 2) + idt.base; - if ((num << 2) + 3 > idt.limit) { - x86_int(13); - } else { - if (stack32) { - writememw(ss, ESP - 2, cpu_state.flags); - writememw(ss, ESP - 4, CS); - writememw(ss, ESP - 6, cpu_state.pc); - ESP -= 6; - } else { - writememw(ss, ((SP - 2) & 0xFFFF), cpu_state.flags); - writememw(ss, ((SP - 4) & 0xFFFF), CS); - writememw(ss, ((SP - 6) & 0xFFFF), cpu_state.pc); - SP -= 6; - } + if ((num << 2) + 3 > idt.limit) { + x86_int(13); + } else { + if (stack32) { + writememw(ss, ESP - 2, cpu_state.flags); + writememw(ss, ESP - 4, CS); + writememw(ss, ESP - 6, cpu_state.pc); + ESP -= 6; + } else { + writememw(ss, ((SP - 2) & 0xFFFF), cpu_state.flags); + writememw(ss, ((SP - 4) & 0xFFFF), CS); + writememw(ss, ((SP - 6) & 0xFFFF), cpu_state.pc); + SP -= 6; + } - cpu_state.flags &= ~I_FLAG; - cpu_state.flags &= ~T_FLAG; - cpu_state.pc = readmemw(0, addr); - loadcs(readmemw(0, addr + 2)); - cycles -= timing_int_rm; - } - } - trap = 0; - CPU_BLOCK_END(); + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; + 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; + uint32_t addr; + uint16_t new_pc, new_cs; - flags_rebuild(); - cycles -= timing_int; + flags_rebuild(); + cycles -= timing_int; - addr = num << 2; - new_pc = readmemw(0, addr); - new_cs = readmemw(0, addr + 2); + addr = num << 2; + new_pc = readmemw(0, addr); + new_cs = readmemw(0, addr + 2); - if (cpu_state.abrt) - return 1; + if (cpu_state.abrt) + return 1; - writememw(ss, ((SP - 2) & 0xFFFF), cpu_state.flags); - if (cpu_state.abrt) { - pclog("abrt5\n"); - return 1; - } - writememw(ss, ((SP - 4) & 0xFFFF), CS); - writememw(ss, ((SP - 6) & 0xFFFF), cpu_state.pc); - if (cpu_state.abrt) { - pclog("abrt6\n"); - return 1; - } - SP -= 6; + writememw(ss, ((SP - 2) & 0xFFFF), cpu_state.flags); + if (cpu_state.abrt) { + pclog("abrt5\n"); + return 1; + } + writememw(ss, ((SP - 4) & 0xFFFF), CS); + writememw(ss, ((SP - 6) & 0xFFFF), cpu_state.pc); + if (cpu_state.abrt) { + pclog("abrt6\n"); + return 1; + } + SP -= 6; - cpu_state.eflags &= ~VIF_FLAG; - cpu_state.flags &= ~T_FLAG; - cpu_state.pc = new_pc; - loadcs(new_cs); + cpu_state.eflags &= ~VIF_FLAG; + cpu_state.flags &= ~T_FLAG; + cpu_state.pc = new_pc; + loadcs(new_cs); - cycles -= timing_int_rm; - trap = 0; - CPU_BLOCK_END(); + cycles -= timing_int_rm; + trap = 0; + CPU_BLOCK_END(); - return 0; + return 0; } void x86illegal() { -// pclog("x86 illegal %04X %08X %04X:%08X %02X\n",msw,cr0,CS,pc,opcode); + // pclog("x86 illegal %04X %08X %04X:%08X %02X\n",msw,cr0,CS,pc,opcode); -// if (output) -// { -// dumpregs(); -// exit(-1); -// } - x86_int(6); + // if (output) + // { + // dumpregs(); + // exit(-1); + // } + x86_int(6); } int checkio(int port) { - uint16_t t; - uint8_t d; - cpl_override = 1; - t = readmemw(tr.base, 0x66); - cpl_override = 0; -// pclog("CheckIO 1 %08X %04x %02x\n",tr.base, eflags, _cs.access); - if (cpu_state.abrt) - return 0; -// pclog("CheckIO %04X %01X %01X %02X %04X %04X %08X ",CS,CPL,IOPL,port,t,t+(port>>3),tr.base+t+(port>>3)); - if ((t + (port >> 3)) > tr.limit) - return 1; - cpl_override = 1; - d = readmembl(tr.base + t + (port >> 3)); -// d=readmemb(tr.base,t+(port>>3)); - cpl_override = 0; -// pclog("%02X %02X\n",d,d&(1<<(port&7))); - return d & (1 << (port & 7)); + uint16_t t; + uint8_t d; + cpl_override = 1; + t = readmemw(tr.base, 0x66); + cpl_override = 0; + // pclog("CheckIO 1 %08X %04x %02x\n",tr.base, eflags, _cs.access); + if (cpu_state.abrt) + return 0; + // pclog("CheckIO %04X %01X %01X %02X %04X %04X %08X ",CS,CPL,IOPL,port,t,t+(port>>3),tr.base+t+(port>>3)); + if ((t + (port >> 3)) > tr.limit) + return 1; + cpl_override = 1; + d = readmembl(tr.base + t + (port >> 3)); + // d=readmemb(tr.base,t+(port>>3)); + cpl_override = 0; + // pclog("%02X %02X\n",d,d&(1<<(port&7))); + return d & (1 << (port & 7)); } -#define divexcp() { \ - pclog("Divide exception at %04X(%06X):%04X\n",CS,cs,cpu_state.pc); \ - x86_int(0); \ -} +#define divexcp() \ + { \ + pclog("Divide exception at %04X(%06X):%04X\n", CS, cs, cpu_state.pc); \ + x86_int(0); \ + } int divl(uint32_t val) { - if (val == 0) { - divexcp(); - return 1; - } - uint64_t num = (((uint64_t)EDX) << 32) | EAX; - uint64_t quo = num / val; - uint32_t rem = num % val; - uint32_t quo32 = (uint32_t)(quo & 0xFFFFFFFF); - if (quo != (uint64_t)quo32) { - divexcp(); - return 1; - } - EDX = rem; - EAX = quo32; - return 0; + if (val == 0) { + divexcp(); + return 1; + } + uint64_t num = (((uint64_t)EDX) << 32) | EAX; + uint64_t quo = num / val; + uint32_t rem = num % val; + uint32_t quo32 = (uint32_t)(quo & 0xFFFFFFFF); + if (quo != (uint64_t)quo32) { + divexcp(); + return 1; + } + EDX = rem; + EAX = quo32; + return 0; } int idivl(int32_t val) { - if (val == 0) { - divexcp(); - return 1; - } - int64_t num = (((uint64_t)EDX) << 32) | EAX; - int64_t quo = num / val; - int32_t rem = num % val; - int32_t quo32 = (int32_t)(quo & 0xFFFFFFFF); - if (quo != (int64_t)quo32) { - divexcp(); - return 1; - } - EDX = rem; - EAX = quo32; - return 0; + if (val == 0) { + divexcp(); + return 1; + } + int64_t num = (((uint64_t)EDX) << 32) | EAX; + int64_t quo = num / val; + int32_t rem = num % val; + int32_t 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(); -} +void cpu_386_flags_extract() { flags_extract(); } +void cpu_386_flags_rebuild() { flags_rebuild(); } diff --git a/src/cpu/386_dynarec.c b/src/cpu/386_dynarec.c index 2e1a82cc..e74da4e5 100644 --- a/src/cpu/386_dynarec.c +++ b/src/cpu/386_dynarec.c @@ -28,91 +28,115 @@ int cpu_recomp_blocks_latched, cpu_recomp_ins_latched, cpu_recomp_full_ins_latch int cpu_block_end = 0; static inline void fetch_ea_32_long(uint32_t rmdat) { - eal_r = eal_w = NULL; - easeg = cpu_state.ea_seg->base; - if (cpu_rm == 4) { - uint8_t sib = rmdat >> 8; + eal_r = eal_w = NULL; + easeg = cpu_state.ea_seg->base; + if (cpu_rm == 4) { + uint8_t sib = rmdat >> 8; - switch (cpu_mod) { - case 0:cpu_state.eaaddr = cpu_state.regs[sib & 7].l; - cpu_state.pc++; - break; - case 1:cpu_state.pc++; - cpu_state.eaaddr = ((uint32_t)(int8_t)getbyte()) + cpu_state.regs[sib & 7].l; -// cpu_state.pc++; - break; - case 2:cpu_state.eaaddr = (fastreadl(cs + cpu_state.pc + 1)) + cpu_state.regs[sib & 7].l; - cpu_state.pc += 5; - break; - } - /*SIB byte present*/ - if ((sib & 7) == 5 && !cpu_mod) - cpu_state.eaaddr = getlong(); - else if ((sib & 6) == 4 && !cpu_state.ssegs) { - easeg = ss; - cpu_state.ea_seg = &cpu_state.seg_ss; - } - if (((sib >> 3) & 7) != 4) - cpu_state.eaaddr += cpu_state.regs[(sib >> 3) & 7].l << (sib >> 6); - } else { - cpu_state.eaaddr = cpu_state.regs[cpu_rm].l; - if (cpu_mod) { - if (cpu_rm == 5 && !cpu_state.ssegs) { - easeg = ss; - cpu_state.ea_seg = &cpu_state.seg_ss; - } - if (cpu_mod == 1) { - cpu_state.eaaddr += ((uint32_t)(int8_t)(rmdat >> 8)); - cpu_state.pc++; - } else { - cpu_state.eaaddr += getlong(); - } - } else if (cpu_rm == 5) { - cpu_state.eaaddr = getlong(); - } - } - if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) { - uint32_t addr = easeg + cpu_state.eaaddr; - if (readlookup2[addr >> 12] != -1) - eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); - if (writelookup2[addr >> 12] != -1) - eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); - } + 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; + // cpu_state.pc++; + break; + case 2: + cpu_state.eaaddr = (fastreadl(cs + cpu_state.pc + 1)) + cpu_state.regs[sib & 7].l; + cpu_state.pc += 5; + break; + } + /*SIB byte present*/ + if ((sib & 7) == 5 && !cpu_mod) + cpu_state.eaaddr = getlong(); + else if ((sib & 6) == 4 && !cpu_state.ssegs) { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + if (((sib >> 3) & 7) != 4) + cpu_state.eaaddr += cpu_state.regs[(sib >> 3) & 7].l << (sib >> 6); + } else { + cpu_state.eaaddr = cpu_state.regs[cpu_rm].l; + if (cpu_mod) { + if (cpu_rm == 5 && !cpu_state.ssegs) { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + if (cpu_mod == 1) { + cpu_state.eaaddr += ((uint32_t)(int8_t)(rmdat >> 8)); + cpu_state.pc++; + } else { + cpu_state.eaaddr += getlong(); + } + } else if (cpu_rm == 5) { + cpu_state.eaaddr = getlong(); + } + } + if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) { + uint32_t addr = easeg + cpu_state.eaaddr; + if (readlookup2[addr >> 12] != -1) + eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); + if (writelookup2[addr >> 12] != -1) + eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); + } } static inline void fetch_ea_16_long(uint32_t rmdat) { - eal_r = eal_w = NULL; - easeg = cpu_state.ea_seg->base; - if (!cpu_mod && cpu_rm == 6) { - cpu_state.eaaddr = getword(); - } else { - switch (cpu_mod) { - case 0:cpu_state.eaaddr = 0; - break; - case 1:cpu_state.eaaddr = (uint16_t)(int8_t)(rmdat >> 8); - cpu_state.pc++; - break; - case 2:cpu_state.eaaddr = getword(); - break; - } - cpu_state.eaaddr += (*mod1add[0][cpu_rm]) + (*mod1add[1][cpu_rm]); - if (mod1seg[cpu_rm] == &ss && !cpu_state.ssegs) { - easeg = ss; - cpu_state.ea_seg = &cpu_state.seg_ss; - } - cpu_state.eaaddr &= 0xFFFF; - } - if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) { - uint32_t addr = easeg + cpu_state.eaaddr; - if (readlookup2[addr >> 12] != -1) - eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); - if (writelookup2[addr >> 12] != -1) - eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); - } + eal_r = eal_w = NULL; + easeg = cpu_state.ea_seg->base; + if (!cpu_mod && cpu_rm == 6) { + cpu_state.eaaddr = getword(); + } else { + switch (cpu_mod) { + case 0: + cpu_state.eaaddr = 0; + break; + case 1: + cpu_state.eaaddr = (uint16_t)(int8_t)(rmdat >> 8); + cpu_state.pc++; + break; + case 2: + cpu_state.eaaddr = getword(); + break; + } + cpu_state.eaaddr += (*mod1add[0][cpu_rm]) + (*mod1add[1][cpu_rm]); + if (mod1seg[cpu_rm] == &ss && !cpu_state.ssegs) { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + cpu_state.eaaddr &= 0xFFFF; + } + if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) { + uint32_t addr = easeg + cpu_state.eaaddr; + if (readlookup2[addr >> 12] != -1) + eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); + if (writelookup2[addr >> 12] != -1) + eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); + } } -#define fetch_ea_16(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_16_long(rmdat); if (cpu_state.abrt) return 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 +#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" @@ -129,68 +153,74 @@ 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; + 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; + 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); - } - } + 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; - } + /* 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; + /* 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; - } + while (instr_cycles >= cpu_prefetch_cycles) { + prefetch_bytes += cpu_prefetch_width; + instr_cycles -= cpu_prefetch_cycles; + } - prefetch_prefixes = 0; - if (prefetch_bytes > 16) - prefetch_bytes = 16; + prefetch_prefixes = 0; + if (prefetch_bytes > 16) + prefetch_bytes = 16; } -static void prefetch_flush() { - prefetch_bytes = 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_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_PREFIX() \ + do { \ + if (cpu_prefetch_cycles) \ + prefetch_prefixes++; \ + } while (0) #define PREFETCH_FLUSH() prefetch_flush() -#define OP_TABLE(name) ops_ ## name +#define OP_TABLE(name) ops_##name #define CLOCK_CYCLES(c) cycles -= (c) #define CLOCK_CYCLES_ALWAYS(c) cycles -= (c) @@ -202,58 +232,65 @@ static void prefetch_flush() { int cpu_end_block_after_ins = 0; static inline void exec_interpreter(void) { - cpu_block_end = 0; - x86_was_reset = 0; -// if (output) pclog("Interpret block at %04x:%04x %04x %04x %04x %04x %04x %04x %04x\n", CS, pc, AX, BX, CX, DX, SI, DI, SP); - while (!cpu_block_end) { - cpu_state.oldpc = cpu_state.pc; - cpu_state.op32 = use32; + cpu_block_end = 0; + x86_was_reset = 0; + // if (output) pclog("Interpret block at %04x:%04x %04x %04x %04x %04x %04x %04x %04x\n", CS, pc, AX, BX, CX, + // DX, SI, DI, SP); + while (!cpu_block_end) { + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; - cpu_state.ea_seg = &cpu_state.seg_ds; - cpu_state.ssegs = 0; + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; - fetchdat = fastreadl(cs + cpu_state.pc); + fetchdat = fastreadl(cs + cpu_state.pc); - if (!cpu_state.abrt) { - uint8_t opcode = fetchdat & 0xFF; - fetchdat >>= 8; - trap = cpu_state.flags & T_FLAG; + if (!cpu_state.abrt) { + uint8_t opcode = fetchdat & 0xFF; + fetchdat >>= 8; + trap = cpu_state.flags & T_FLAG; -// if (output == 3) -// pclog("int %04X(%06X):%04X : %08X %08X %08X %08X %04X %04X %04X(%08X) %04X %04X %04X(%08X) %08X %08X %08X SP=%04X:%08X %02X %04X %i %08X %08X %i %i %02X %02X %02X %02X %02X %f %02X%02X %02X%02X\n",CS,cs,pc,EAX,EBX,ECX,EDX,CS,DS,ES,es,FS,GS,SS,ss,EDI,ESI,EBP,SS,ESP,opcode,flags,ins,0, ldt.base, CPL, stack32, pic.pend, pic.mask, pic.mask2, pic2.pend, pic2.mask, pit.c[0], ram[0x8f13f], ram[0x8f13e], ram[0x8f141], ram[0x8f140]); + // if (output == 3) + // pclog("int %04X(%06X):%04X : %08X %08X %08X %08X %04X %04X %04X(%08X) + // %04X %04X %04X(%08X) %08X %08X %08X SP=%04X:%08X %02X %04X %i %08X %08X + // %i %i %02X %02X %02X %02X %02X %f %02X%02X + // %02X%02X\n",CS,cs,pc,EAX,EBX,ECX,EDX,CS,DS,ES,es,FS,GS,SS,ss,EDI,ESI,EBP,SS,ESP,opcode,flags,ins,0, + // ldt.base, CPL, stack32, pic.pend, pic.mask, pic.mask2, pic2.pend, + // pic2.mask, pit.c[0], ram[0x8f13f], ram[0x8f13e], ram[0x8f141], + // ram[0x8f140]); - cpu_state.pc++; - x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); - } + cpu_state.pc++; + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + } - if (((cs + cpu_state.pc) >> 12) != pccache) - CPU_BLOCK_END(); + if (((cs + cpu_state.pc) >> 12) != pccache) + CPU_BLOCK_END(); - if (cpu_state.abrt) - CPU_BLOCK_END(); - if (cpu_state.smi_pending) - CPU_BLOCK_END(); - if (trap) - CPU_BLOCK_END(); - if (nmi && nmi_enable && nmi_mask) - CPU_BLOCK_END(); - if (cpu_end_block_after_ins) { - cpu_end_block_after_ins--; - if (!cpu_end_block_after_ins) - CPU_BLOCK_END(); - } + if (cpu_state.abrt) + CPU_BLOCK_END(); + if (cpu_state.smi_pending) + CPU_BLOCK_END(); + if (trap) + CPU_BLOCK_END(); + if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); + if (cpu_end_block_after_ins) { + cpu_end_block_after_ins--; + if (!cpu_end_block_after_ins) + CPU_BLOCK_END(); + } - ins++; - insc++; - } + ins++; + insc++; + } - if (trap) { - trap = 0; - cpu_state.oldpc = cpu_state.pc; - x86_int(1); - } + if (trap) { + trap = 0; + cpu_state.oldpc = cpu_state.pc; + x86_int(1); + } - cpu_end_block_after_ins = 0; + cpu_end_block_after_ins = 0; } /* TODO: Look in deeper for why, but this is to fix crashing. Somehow a function is being optimized out, causing @@ -261,319 +298,346 @@ static inline void exec_interpreter(void) { */ static void __attribute__((noinline)) exec_recompiler(void) { - uint32_t phys_addr = get_phys(cs + cpu_state.pc); - int hash = HASH(phys_addr); - codeblock_t *block = &codeblock[codeblock_hash[hash]]; - int valid_block = 0; + uint32_t phys_addr = get_phys(cs + cpu_state.pc); + int hash = HASH(phys_addr); + codeblock_t *block = &codeblock[codeblock_hash[hash]]; + int valid_block = 0; - if (!cpu_state.abrt) { - page_t *page = &pages[phys_addr >> 12]; + if (!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); - int byte_offset = (phys_addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; - uint64_t byte_mask = 1ull << (PAGE_BYTE_MASK_MASK & 0x3f); + /*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); + int byte_offset = (phys_addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; + uint64_t byte_mask = 1ull << (PAGE_BYTE_MASK_MASK & 0x3f); - if ((page->code_present_mask & mask) || (page->byte_code_present_mask[byte_offset] & byte_mask)) { - /*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; - codeblock_hash[hash] = get_block_nr(block); - } - } - } - } + if ((page->code_present_mask & mask) || (page->byte_code_present_mask[byte_offset] & byte_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; + codeblock_hash[hash] = get_block_nr(block); + } + } + } + } - if (valid_block && (block->page_mask & *block->dirty_mask)) { - codegen_check_flush(page, page->dirty_mask, phys_addr); - if (block->pc == BLOCK_PC_INVALID) - valid_block = 0; - else if (block->flags & CODEBLOCK_IN_DIRTY_LIST) - block->flags &= ~CODEBLOCK_WAS_RECOMPILED; - } - 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->pc + ((block->flags & CODEBLOCK_BYTE_MASK) ? 0x40 : 0x400)); - 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); - if (block->pc == BLOCK_PC_INVALID) - valid_block = 0; - else if (block->flags & CODEBLOCK_IN_DIRTY_LIST) - block->flags &= ~CODEBLOCK_WAS_RECOMPILED; - } - } - if (valid_block && (block->flags & CODEBLOCK_IN_DIRTY_LIST)) { - block->flags &= ~CODEBLOCK_WAS_RECOMPILED; - if (block->flags & CODEBLOCK_BYTE_MASK) - block->flags |= CODEBLOCK_NO_IMMEDIATES; - else - block->flags |= CODEBLOCK_BYTE_MASK; - } - if (valid_block && (block->flags & CODEBLOCK_WAS_RECOMPILED) && (block->flags & CODEBLOCK_STATIC_TOP) && block->TOP != (cpu_state.TOP & 7)) { - /*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 | CODEBLOCK_WAS_RECOMPILED); - } - } + if (valid_block && (block->page_mask & *block->dirty_mask)) { + codegen_check_flush(page, page->dirty_mask, phys_addr); + if (block->pc == BLOCK_PC_INVALID) + valid_block = 0; + else if (block->flags & CODEBLOCK_IN_DIRTY_LIST) + block->flags &= ~CODEBLOCK_WAS_RECOMPILED; + } + 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->pc + ((block->flags & CODEBLOCK_BYTE_MASK) ? 0x40 : 0x400)); + 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); + if (block->pc == BLOCK_PC_INVALID) + valid_block = 0; + else if (block->flags & CODEBLOCK_IN_DIRTY_LIST) + block->flags &= ~CODEBLOCK_WAS_RECOMPILED; + } + } + if (valid_block && (block->flags & CODEBLOCK_IN_DIRTY_LIST)) { + block->flags &= ~CODEBLOCK_WAS_RECOMPILED; + if (block->flags & CODEBLOCK_BYTE_MASK) + block->flags |= CODEBLOCK_NO_IMMEDIATES; + else + block->flags |= CODEBLOCK_BYTE_MASK; + } + if (valid_block && (block->flags & CODEBLOCK_WAS_RECOMPILED) && (block->flags & CODEBLOCK_STATIC_TOP) && + block->TOP != (cpu_state.TOP & 7)) { + /*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 | CODEBLOCK_WAS_RECOMPILED); + } + } - if (valid_block && (block->flags & CODEBLOCK_WAS_RECOMPILED)) { - void (*code)() = (void *)&block->data[BLOCK_START]; // FIX: This seems to get optimized out, I tried making volatile but still segfaulted + if (valid_block && (block->flags & CODEBLOCK_WAS_RECOMPILED)) { + void (*code)() = (void *)&block->data[BLOCK_START]; // FIX: This seems to get optimized out, I tried making + // volatile but still segfaulted -// if (output) pclog("Run block at %04x:%04x %04x %04x %04x %04x %04x %04x ESP=%08x %04x %08x %08x %016llx %08x\n", CS, pc, AX, BX, CX, DX, SI, DI, ESP, BP, get_phys(cs+pc), block->phys, block->page_mask, block->endpc); + // if (output) pclog("Run block at %04x:%04x %04x %04x %04x %04x %04x %04x ESP=%08x %04x %08x + // %08x %016llx %08x\n", CS, pc, AX, BX, CX, DX, SI, DI, ESP, BP, get_phys(cs+pc), block->phys, + // block->page_mask, block->endpc); - inrecomp = 1; - code(); - inrecomp = 0; + inrecomp = 1; + code(); + inrecomp = 0; - cpu_recomp_blocks++; - } else if (valid_block && !cpu_state.abrt) { - uint32_t start_pc = cs + cpu_state.pc; - const int max_block_size = (block->flags & CODEBLOCK_BYTE_MASK) ? ((128 - 25) - (start_pc & 0x3f)) : 1000; + cpu_recomp_blocks++; + } else if (valid_block && !cpu_state.abrt) { + uint32_t start_pc = cs + cpu_state.pc; + const int max_block_size = (block->flags & CODEBLOCK_BYTE_MASK) ? ((128 - 25) - (start_pc & 0x3f)) : 1000; - cpu_block_end = 0; - x86_was_reset = 0; + cpu_block_end = 0; + x86_was_reset = 0; - cpu_new_blocks++; + cpu_new_blocks++; #if defined(__APPLE__) && defined(__aarch64__) - pthread_jit_write_protect_np(0); + pthread_jit_write_protect_np(0); #endif - codegen_block_start_recompile(block); - codegen_in_recompile = 1; + codegen_block_start_recompile(block); + codegen_in_recompile = 1; -// if (output) pclog("Recompile block at %04x:%04x %04x %04x %04x %04x %04x %04x ESP=%04x %04x %02x%02x:%02x%02x %02x%02x:%02x%02x %02x%02x:%02x%02x\n", CS, pc, AX, BX, CX, DX, SI, DI, ESP, BP, ram[0x116330+0x6df4+0xa+3], ram[0x116330+0x6df4+0xa+2], ram[0x116330+0x6df4+0xa+1], ram[0x116330+0x6df4+0xa+0], ram[0x11d136+3],ram[0x11d136+2],ram[0x11d136+1],ram[0x11d136+0], ram[(0x119abe)+0x3],ram[(0x119abe)+0x2],ram[(0x119abe)+0x1],ram[(0x119abe)+0x0]); - while (!cpu_block_end) { - cpu_state.oldpc = cpu_state.pc; - cpu_state.op32 = use32; + // if (output) pclog("Recompile block at %04x:%04x %04x %04x %04x %04x %04x %04x ESP=%04x %04x + // %02x%02x:%02x%02x %02x%02x:%02x%02x %02x%02x:%02x%02x\n", CS, pc, AX, BX, CX, DX, SI, DI, ESP, + // BP, ram[0x116330+0x6df4+0xa+3], ram[0x116330+0x6df4+0xa+2], ram[0x116330+0x6df4+0xa+1], + // ram[0x116330+0x6df4+0xa+0], ram[0x11d136+3],ram[0x11d136+2],ram[0x11d136+1],ram[0x11d136+0], + // ram[(0x119abe)+0x3],ram[(0x119abe)+0x2],ram[(0x119abe)+0x1],ram[(0x119abe)+0x0]); + while (!cpu_block_end) { + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; - cpu_state.ea_seg = &cpu_state.seg_ds; - cpu_state.ssegs = 0; + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; - fetchdat = fastreadl(cs + cpu_state.pc); + fetchdat = fastreadl(cs + cpu_state.pc); - if (!cpu_state.abrt) { - uint8_t opcode = fetchdat & 0xFF; - fetchdat >>= 8; + if (!cpu_state.abrt) { + uint8_t opcode = fetchdat & 0xFF; + fetchdat >>= 8; -// if (output == 3) -// pclog("%04X(%06X):%04X : %08X %08X %08X %08X %04X %04X %04X(%08X) %04X %04X %04X(%08X) %08X %08X %08X SP=%04X:%08X %02X %04X %i %08X %08X %i %i %02X %02X %02X %02X %02X %08x %08x\n",CS,cs,pc,EAX,EBX,ECX,EDX,CS,DS,ES,es,FS,GS,SS,ss,EDI,ESI,EBP,SS,ESP,opcode,flags,ins,0, ldt.base, CPL, stack32, pic.pend, pic.mask, pic.mask2, pic2.pend, pic2.mask, cs+pc, pccache); + // if (output == 3) + // pclog("%04X(%06X):%04X : %08X %08X %08X %08X %04X %04X + // %04X(%08X) %04X %04X %04X(%08X) %08X %08X %08X + // SP=%04X:%08X %02X %04X %i %08X %08X %i %i %02X %02X + // %02X %02X %02X %08x + // %08x\n",CS,cs,pc,EAX,EBX,ECX,EDX,CS,DS,ES,es,FS,GS,SS,ss,EDI,ESI,EBP,SS,ESP,opcode,flags,ins,0, + // ldt.base, CPL, stack32, pic.pend, pic.mask, pic.mask2, + // pic2.pend, pic2.mask, cs+pc, pccache); - cpu_state.pc++; + cpu_state.pc++; - codegen_generate_call(opcode, x86_opcodes[(opcode | cpu_state.op32) & 0x3ff], fetchdat, cpu_state.pc, cpu_state.pc - 1); + 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); + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); - if (x86_was_reset) - break; - } + if (x86_was_reset) + break; + } - /*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 (((cs + cpu_state.pc) - start_pc) >= max_block_size) - CPU_BLOCK_END(); - if (cpu_state.flags & T_FLAG) - CPU_BLOCK_END(); - if (cpu_state.smi_pending) - CPU_BLOCK_END(); - if (nmi && nmi_enable && nmi_mask) - CPU_BLOCK_END(); + /*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 (((cs + cpu_state.pc) - start_pc) >= max_block_size) + CPU_BLOCK_END(); + if (cpu_state.flags & T_FLAG) + CPU_BLOCK_END(); + if (cpu_state.smi_pending) + CPU_BLOCK_END(); + if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); - if (cpu_end_block_after_ins) { - cpu_end_block_after_ins--; - if (!cpu_end_block_after_ins) - CPU_BLOCK_END(); - } + if (cpu_end_block_after_ins) { + cpu_end_block_after_ins--; + if (!cpu_end_block_after_ins) + CPU_BLOCK_END(); + } - if (cpu_state.abrt) { - if (!(cpu_state.abrt & ABRT_EXPECTED)) - codegen_block_remove(); - CPU_BLOCK_END(); - } + if (cpu_state.abrt) { + if (!(cpu_state.abrt & ABRT_EXPECTED)) + codegen_block_remove(); + CPU_BLOCK_END(); + } - ins++; - insc++; - } - cpu_end_block_after_ins = 0; + ins++; + insc++; + } + cpu_end_block_after_ins = 0; - if ((!cpu_state.abrt || (cpu_state.abrt & ABRT_EXPECTED)) && !x86_was_reset) - codegen_block_end_recompile(block); + if ((!cpu_state.abrt || (cpu_state.abrt & ABRT_EXPECTED)) && !x86_was_reset) + codegen_block_end_recompile(block); - if (x86_was_reset) - codegen_reset(); + if (x86_was_reset) + codegen_reset(); - codegen_in_recompile = 0; + codegen_in_recompile = 0; #if defined(__APPLE__) && defined(__aarch64__) - pthread_jit_write_protect_np(1); + pthread_jit_write_protect_np(1); #endif - } else if (!cpu_state.abrt) { - /*Mark block but do not recompile*/ - uint32_t start_pc = cs + cpu_state.pc; - const int max_block_size = (block->flags & CODEBLOCK_BYTE_MASK) ? ((128 - 25) - (start_pc & 0x3f)) : 1000; + } else if (!cpu_state.abrt) { + /*Mark block but do not recompile*/ + uint32_t start_pc = cs + cpu_state.pc; + const int max_block_size = (block->flags & CODEBLOCK_BYTE_MASK) ? ((128 - 25) - (start_pc & 0x3f)) : 1000; - cpu_block_end = 0; - x86_was_reset = 0; + cpu_block_end = 0; + x86_was_reset = 0; - codegen_block_init(phys_addr); + codegen_block_init(phys_addr); -// if (output) pclog("Recompile block at %04x:%04x %04x %04x %04x %04x %04x %04x ESP=%04x %04x %02x%02x:%02x%02x %02x%02x:%02x%02x %02x%02x:%02x%02x\n", CS, pc, AX, BX, CX, DX, SI, DI, ESP, BP, ram[0x116330+0x6df4+0xa+3], ram[0x116330+0x6df4+0xa+2], ram[0x116330+0x6df4+0xa+1], ram[0x116330+0x6df4+0xa+0], ram[0x11d136+3],ram[0x11d136+2],ram[0x11d136+1],ram[0x11d136+0], ram[(0x119abe)+0x3],ram[(0x119abe)+0x2],ram[(0x119abe)+0x1],ram[(0x119abe)+0x0]); - while (!cpu_block_end) { - cpu_state.oldpc = cpu_state.pc; - cpu_state.op32 = use32; + // if (output) pclog("Recompile block at %04x:%04x %04x %04x %04x %04x %04x %04x ESP=%04x %04x + // %02x%02x:%02x%02x %02x%02x:%02x%02x %02x%02x:%02x%02x\n", CS, pc, AX, BX, CX, DX, SI, DI, ESP, + // BP, ram[0x116330+0x6df4+0xa+3], ram[0x116330+0x6df4+0xa+2], ram[0x116330+0x6df4+0xa+1], + // ram[0x116330+0x6df4+0xa+0], ram[0x11d136+3],ram[0x11d136+2],ram[0x11d136+1],ram[0x11d136+0], + // ram[(0x119abe)+0x3],ram[(0x119abe)+0x2],ram[(0x119abe)+0x1],ram[(0x119abe)+0x0]); + while (!cpu_block_end) { + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; - cpu_state.ea_seg = &cpu_state.seg_ds; - cpu_state.ssegs = 0; + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; - codegen_endpc = (cs + cpu_state.pc) + 8; - fetchdat = fastreadl(cs + cpu_state.pc); + codegen_endpc = (cs + cpu_state.pc) + 8; + fetchdat = fastreadl(cs + cpu_state.pc); - if (!cpu_state.abrt) { - uint8_t opcode = fetchdat & 0xFF; - fetchdat >>= 8; + if (!cpu_state.abrt) { + uint8_t opcode = fetchdat & 0xFF; + fetchdat >>= 8; -// if (output == 3) -// pclog("%04X(%06X):%04X : %08X %08X %08X %08X %04X %04X %04X(%08X) %04X %04X %04X(%08X) %08X %08X %08X SP=%04X:%08X %02X %04X %i %08X %08X %i %i %02X %02X %02X %02X %02X %08x %08x\n",CS,cs,pc,EAX,EBX,ECX,EDX,CS,DS,ES,es,FS,GS,SS,ss,EDI,ESI,EBP,SS,ESP,opcode,flags,ins,0, ldt.base, CPL, stack32, pic.pend, pic.mask, pic.mask2, pic2.pend, pic2.mask, cs+pc, pccache); + // if (output == 3) + // pclog("%04X(%06X):%04X : %08X %08X %08X %08X %04X %04X + // %04X(%08X) %04X %04X %04X(%08X) %08X %08X %08X + // SP=%04X:%08X %02X %04X %i %08X %08X %i %i %02X %02X + // %02X %02X %02X %08x + // %08x\n",CS,cs,pc,EAX,EBX,ECX,EDX,CS,DS,ES,es,FS,GS,SS,ss,EDI,ESI,EBP,SS,ESP,opcode,flags,ins,0, + // ldt.base, CPL, stack32, pic.pend, pic.mask, pic.mask2, + // pic2.pend, pic2.mask, cs+pc, pccache); - cpu_state.pc++; + cpu_state.pc++; - x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); - if (x86_was_reset) - break; - } + if (x86_was_reset) + break; + } - /*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 (((cs + cpu_state.pc) - start_pc) >= max_block_size) - CPU_BLOCK_END(); - if (cpu_state.flags & T_FLAG) - CPU_BLOCK_END(); - if (cpu_state.smi_pending) - CPU_BLOCK_END(); - if (nmi && nmi_enable && nmi_mask) - CPU_BLOCK_END(); + /*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 (((cs + cpu_state.pc) - start_pc) >= max_block_size) + CPU_BLOCK_END(); + if (cpu_state.flags & T_FLAG) + CPU_BLOCK_END(); + if (cpu_state.smi_pending) + CPU_BLOCK_END(); + if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); - if (cpu_end_block_after_ins) { - cpu_end_block_after_ins--; - if (!cpu_end_block_after_ins) - CPU_BLOCK_END(); - } + if (cpu_end_block_after_ins) { + cpu_end_block_after_ins--; + if (!cpu_end_block_after_ins) + CPU_BLOCK_END(); + } - if (cpu_state.abrt) { - if (!(cpu_state.abrt & ABRT_EXPECTED)) - codegen_block_remove(); - CPU_BLOCK_END(); - } + if (cpu_state.abrt) { + if (!(cpu_state.abrt & ABRT_EXPECTED)) + codegen_block_remove(); + CPU_BLOCK_END(); + } - ins++; - insc++; - } - cpu_end_block_after_ins = 0; + ins++; + insc++; + } + cpu_end_block_after_ins = 0; -// if (!cpu_state.abrt && !x86_was_reset) - if ((!cpu_state.abrt || (cpu_state.abrt & ABRT_EXPECTED)) && !x86_was_reset) - codegen_block_end(); - - if (x86_was_reset) - codegen_reset(); - } else - cpu_state.oldpc = cpu_state.pc; + // if (!cpu_state.abrt && !x86_was_reset) + if ((!cpu_state.abrt || (cpu_state.abrt & ABRT_EXPECTED)) && !x86_was_reset) + codegen_block_end(); + if (x86_was_reset) + codegen_reset(); + } else + cpu_state.oldpc = cpu_state.pc; } int cycles_main = 0; void exec386_dynarec(int cycs) { - uint8_t temp; - int tempi; - int cycdiff; - int oldcyc; - int cyc_period = cycs / 2000; /*5us*/ + uint8_t temp; + int tempi; + int cycdiff; + int oldcyc; + int cyc_period = cycs / 2000; /*5us*/ - cycles_main += cycs; - while (cycles_main > 0) { - int cycles_start; + cycles_main += cycs; + while (cycles_main > 0) { + int cycles_start; - cycles += cyc_period; - cycles_start = cycles; + cycles += cyc_period; + cycles_start = cycles; - while (cycles > 0) { - oldcyc = cycles; -// if (output && CACHE_ON()) pclog("Block %04x:%04x %04x:%08x\n", CS, pc, SS,ESP); - if (!CACHE_ON()) /*Interpret block*/ - exec_interpreter(); - else - exec_recompiler(); + while (cycles > 0) { + oldcyc = cycles; + // if (output && CACHE_ON()) pclog("Block %04x:%04x %04x:%08x\n", CS, pc, SS,ESP); + if (!CACHE_ON()) /*Interpret block*/ + exec_interpreter(); + else + exec_recompiler(); - if (cpu_state.abrt) { - flags_rebuild(); - tempi = cpu_state.abrt & ABRT_MASK; - cpu_state.abrt = 0; - x86_doabrt(tempi); - if (cpu_state.abrt) { - cpu_state.abrt = 0; - cpu_state.pc = cpu_state.oldpc; - pclog("Double fault %i\n", ins); - pmodeint(8, 0); - if (cpu_state.abrt) { - cpu_state.abrt = 0; - softresetx86(); - cpu_set_edx(); - pclog("Triple fault - reset\n"); - } - } - } + if (cpu_state.abrt) { + flags_rebuild(); + tempi = cpu_state.abrt & ABRT_MASK; + cpu_state.abrt = 0; + x86_doabrt(tempi); + if (cpu_state.abrt) { + cpu_state.abrt = 0; + cpu_state.pc = cpu_state.oldpc; + pclog("Double fault %i\n", ins); + pmodeint(8, 0); + if (cpu_state.abrt) { + cpu_state.abrt = 0; + softresetx86(); + cpu_set_edx(); + pclog("Triple fault - reset\n"); + } + } + } - if (cpu_state.smi_pending) { - cpu_state.smi_pending = 0; - x86_smi_enter(); - } else if (nmi && nmi_enable && nmi_mask) { - cpu_state.oldpc = cpu_state.pc; -// pclog("NMI\n"); - x86_int(2); - nmi_enable = 0; - if (nmi_auto_clear) { - nmi_auto_clear = 0; - nmi = 0; - } - } else if ((cpu_state.flags & I_FLAG) && pic_intpending) { - temp = picinterrupt(); - if (temp != 0xFF) { - cpu_state.oldpc = cpu_state.pc; - x86_int(temp); -// pclog("IRQ %02X %04X:%04X %04X:%04X\n", temp, SS, SP, CS, pc); - } - } + if (cpu_state.smi_pending) { + cpu_state.smi_pending = 0; + x86_smi_enter(); + } else if (nmi && nmi_enable && nmi_mask) { + cpu_state.oldpc = cpu_state.pc; + // pclog("NMI\n"); + x86_int(2); + nmi_enable = 0; + if (nmi_auto_clear) { + nmi_auto_clear = 0; + nmi = 0; + } + } else if ((cpu_state.flags & I_FLAG) && pic_intpending) { + temp = picinterrupt(); + if (temp != 0xFF) { + cpu_state.oldpc = cpu_state.pc; + x86_int(temp); + // pclog("IRQ %02X %04X:%04X %04X:%04X\n", temp, + // SS, SP, CS, pc); + } + } - cycdiff = oldcyc - cycles; - tsc += cycdiff; - } + cycdiff = oldcyc - cycles; + tsc += cycdiff; + } - if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc)) - timer_process(); - cycles_main -= (cycles_start - cycles); - } + if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc)) + timer_process(); + cycles_main -= (cycles_start - cycles); + } } diff --git a/src/cpu/386_dynarec_ops.c b/src/cpu/386_dynarec_ops.c index 1ffed7f9..110d32db 100644 --- a/src/cpu/386_dynarec_ops.c +++ b/src/cpu/386_dynarec_ops.c @@ -14,37 +14,43 @@ #include "386_common.h" static inline void fetch_ea_32_long(uint32_t rmdat) { - eal_r = eal_w = NULL; - easeg = cpu_state.ea_seg->base; - 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); - } + eal_r = eal_w = NULL; + easeg = cpu_state.ea_seg->base; + if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) { + uint32_t addr = easeg + cpu_state.eaaddr; + if (readlookup2[addr >> 12] != -1) + eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); + if (writelookup2[addr >> 12] != -1) + eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); + } } static inline void fetch_ea_16_long(uint32_t rmdat) { - eal_r = eal_w = NULL; - easeg = cpu_state.ea_seg->base; - if (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); - } + eal_r = eal_w = NULL; + easeg = cpu_state.ea_seg->base; + if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) { + uint32_t addr = easeg + cpu_state.eaaddr; + if (readlookup2[addr >> 12] != -1) + eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); + if (writelookup2[addr >> 12] != -1) + eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); + } } -#define fetch_ea_16(rmdat) cpu_state.pc++; if (cpu_mod != 3) fetch_ea_16_long(rmdat); -#define fetch_ea_32(rmdat) cpu_state.pc++; if (cpu_mod != 3) fetch_ea_32_long(rmdat); +#define fetch_ea_16(rmdat) \ + cpu_state.pc++; \ + if (cpu_mod != 3) \ + fetch_ea_16_long(rmdat); +#define fetch_ea_32(rmdat) \ + cpu_state.pc++; \ + if (cpu_mod != 3) \ + fetch_ea_32_long(rmdat); #define PREFETCH_RUN(instr_cycles, bytes, modrm, reads, read_ls, writes, write_ls, ea32) #define PREFETCH_PREFIX() #define PREFETCH_FLUSH() -#define OP_TABLE(name) dynarec_ops_ ## name +#define OP_TABLE(name) dynarec_ops_##name /*Temporary*/ #define CLOCK_CYCLES(c) #define CLOCK_CYCLES_ALWAYS(c) cycles -= (c) diff --git a/src/cpu/808x.c b/src/cpu/808x.c index 87e04209..ebf7c30e 100644 --- a/src/cpu/808x.c +++ b/src/cpu/808x.c @@ -1,5 +1,5 @@ -//1B64 - Vid_SetMode (Vid_Vesa.c) -//6689c - CONS_Printf +// 1B64 - Vid_SetMode (Vid_Vesa.c) +// 6689c - CONS_Printf /*SHR AX,1 4 clocks - fetch opcode @@ -49,60 +49,64 @@ static int memcycs; static int cycdiff; static void FETCHCOMPLETE(); -#define IRQTEST ((cpu_state.flags & I_FLAG) && (pic.pend&~pic.mask) && !noint) +#define IRQTEST ((cpu_state.flags & I_FLAG) && (pic.pend & ~pic.mask) && !noint) static uint8_t readmemb(uint32_t a) { - if (a != (cs + cpu_state.pc)) - memcycs += 4; - if (readlookup2[(a) >> 12] == -1) - return readmembl(a); - else - return *(uint8_t *)(readlookup2[(a) >> 12] + (a)); + if (a != (cs + cpu_state.pc)) + memcycs += 4; + if (readlookup2[(a) >> 12] == -1) + return readmembl(a); + else + return *(uint8_t *)(readlookup2[(a) >> 12] + (a)); } static uint8_t readmembf(uint32_t a) { - if (readlookup2[(a) >> 12] == -1) - return readmembl(a); - else - return *(uint8_t *)(readlookup2[(a) >> 12] + (a)); + if (readlookup2[(a) >> 12] == -1) + return readmembl(a); + else + return *(uint8_t *)(readlookup2[(a) >> 12] + (a)); } static uint16_t readmemw(uint32_t s, uint16_t a) { - if (a != (cs + cpu_state.pc)) - memcycs += (8 >> is8086); - if ((readlookup2[((s) + (a)) >> 12] == -1 || (s) == 0xFFFFFFFF)) - return readmemwl(s + a); - else - return *(uint16_t *)(readlookup2[(s + a) >> 12] + s + a); + if (a != (cs + cpu_state.pc)) + memcycs += (8 >> is8086); + if ((readlookup2[((s) + (a)) >> 12] == -1 || (s) == 0xFFFFFFFF)) + return readmemwl(s + a); + else + return *(uint16_t *)(readlookup2[(s + a) >> 12] + s + a); } -void refreshread() { /*pclog("Refreshread\n"); */FETCHCOMPLETE(); - memcycs += 4; +void refreshread() { /*pclog("Refreshread\n"); */ + 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(); } +#define fetchea() \ + { \ + rmdat = FETCH(); \ + cpu_reg = (rmdat >> 3) & 7; \ + cpu_mod = (rmdat >> 6) & 3; \ + cpu_rm = rmdat & 7; \ + if (cpu_mod != 3) \ + fetcheal(); \ + } static void writememb(uint32_t a, uint8_t v) { - memcycs += 4; - if (writelookup2[(a) >> 12] == -1) - writemembl(a, v); - else - *(uint8_t *)(writelookup2[a >> 12] + a) = v; + memcycs += 4; + if (writelookup2[(a) >> 12] == -1) + writemembl(a, v); + else + *(uint8_t *)(writelookup2[a >> 12] + a) = v; } static void writememw(uint32_t s, uint32_t a, uint16_t v) { - memcycs += (8 >> is8086); - if (writelookup2[((s) + (a)) >> 12] == -1 || (s) == 0xFFFFFFFF) - writememwl(s + a, v); - else - *(uint16_t *)(writelookup2[(s + a) >> 12] + s + a) = v; + memcycs += (8 >> is8086); + if (writelookup2[((s) + (a)) >> 12] == -1 || (s) == 0xFFFFFFFF) + writememwl(s + a, v); + else + *(uint16_t *)(writelookup2[(s + a) >> 12] + s + a) = v; } - //#define readmemb(a) (((a)<0xA0000)?ram[a]:readmembl(a)) static int fetchcycles = 0, fetchclocks; @@ -112,143 +116,146 @@ static uint16_t prefetchpc; static 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)) + 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++; + } + }*/ -// uint8_t temp=readmemb(cs+pc); -// if (output) printf("FETCH %04X %i\n",pc,fetchcycles); - if (prefetchw == 0) //(fetchcycles<4) - { - 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 (output) printf(" FETCH %04X:%04X %02X %04X %04X %i\n",CS,pc-1,temp,pc,prefetchpc,prefetchw); - if (is8086 && (cpu_state.pc & 1)) { - prefetchqueue[0] = readmembf(cs + cpu_state.pc); -// if (output) printf(" PREFETCHED from %04X:%04X %02X 8086\n",CS,prefetchpc,prefetchqueue[prefetchw]); - 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--; -// if (output) printf("PREFETCH %04X:%04X %02X %04X %04X %i\n",CS,pc,temp,pc,prefetchpc,prefetchw); - fetchcycles -= 4; -// fetchclocks+=4; - cpu_state.pc++; - } -// if (output) printf("%i\n",fetchcycles); - return temp; + // uint8_t temp=readmemb(cs+pc); + // if (output) printf("FETCH %04X %i\n",pc,fetchcycles); + if (prefetchw == 0) //(fetchcycles<4) + { + 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 (output) printf(" FETCH %04X:%04X %02X %04X %04X + // %i\n",CS,pc-1,temp,pc,prefetchpc,prefetchw); + if (is8086 && (cpu_state.pc & 1)) { + prefetchqueue[0] = readmembf(cs + cpu_state.pc); + // if (output) printf(" PREFETCHED from %04X:%04X %02X + // 8086\n",CS,prefetchpc,prefetchqueue[prefetchw]); + 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--; + // if (output) printf("PREFETCH %04X:%04X %02X %04X %04X %i\n",CS,pc,temp,pc,prefetchpc,prefetchw); + fetchcycles -= 4; + // fetchclocks+=4; + cpu_state.pc++; + } + // if (output) printf("%i\n",fetchcycles); + return temp; } static inline void FETCHADD(int c) { - int d; -// if (output) printf("FETCHADD %i\n",c); - 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); -// printf("PREFETCHED from %04X:%04X %02X 8086\n",CS,prefetchpc,prefetchqueue[prefetchw]); - prefetchpc++; - prefetchw++; - } - if (prefetchw < 6) { - prefetchqueue[prefetchw] = readmembf(cs + prefetchpc); -// printf("PREFETCHED from %04X:%04X %02X\n",CS,prefetchpc,prefetchqueue[prefetchw]); - prefetchpc++; - prefetchw++; - } - } - fetchcycles += c; - if (fetchcycles > 16) - fetchcycles = 16; -// if (fetchcycles>24) fetchcycles=24; + int d; + // if (output) printf("FETCHADD %i\n",c); + 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); + // printf("PREFETCHED from %04X:%04X %02X + // 8086\n",CS,prefetchpc,prefetchqueue[prefetchw]); + prefetchpc++; + prefetchw++; + } + if (prefetchw < 6) { + prefetchqueue[prefetchw] = readmembf(cs + prefetchpc); + // printf("PREFETCHED from %04X:%04X + // %02X\n",CS,prefetchpc,prefetchqueue[prefetchw]); + prefetchpc++; + prefetchw++; + } + } + fetchcycles += c; + if (fetchcycles > 16) + fetchcycles = 16; + // if (fetchcycles>24) fetchcycles=24; } static void FETCHCOMPLETE() { -// pclog("Fetchcomplete %i %i %i\n",fetchcycles&3,fetchcycles,prefetchw); - 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); -// printf("PREFETCHEDc from %04X:%04X %02X 8086\n",CS,prefetchpc,prefetchqueue[prefetchw]); - prefetchpc++; - prefetchw++; - } - if (prefetchw < 6) { - prefetchqueue[prefetchw] = readmembf(cs + prefetchpc); -// printf("PREFETCHEDc from %04X:%04X %02X\n",CS,prefetchpc,prefetchqueue[prefetchw]); - prefetchpc++; - prefetchw++; - } - fetchcycles += (4 - (fetchcycles & 3)); + // pclog("Fetchcomplete %i %i %i\n",fetchcycles&3,fetchcycles,prefetchw); + 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); + // printf("PREFETCHEDc from %04X:%04X %02X 8086\n",CS,prefetchpc,prefetchqueue[prefetchw]); + prefetchpc++; + prefetchw++; + } + if (prefetchw < 6) { + prefetchqueue[prefetchw] = readmembf(cs + prefetchpc); + // printf("PREFETCHEDc from %04X:%04X %02X\n",CS,prefetchpc,prefetchqueue[prefetchw]); + prefetchpc++; + prefetchw++; + } + fetchcycles += (4 - (fetchcycles & 3)); } static inline void FETCHCLEAR() { -/* int c; - fetchcycles=0; - prefetchpc=pc; - if (is8086 && (prefetchpc&1)) cycles-=4; - for (c=0;c<((is8086)?6:4);c++) - { - prefetchqueue[c]=readmembf(cs+prefetchpc); - if (!is8086 || !(prefetchpc&1)) cycles-=4; + /* int c; + fetchcycles=0; + prefetchpc=pc; + if (is8086 && (prefetchpc&1)) cycles-=4; + for (c=0;c<((is8086)?6:4);c++) + { + prefetchqueue[c]=readmembf(cs+prefetchpc); + if (!is8086 || !(prefetchpc&1)) cycles-=4; + prefetchpc++; + } + prefetchw=(is8086)?6:4;*/ + // fetchcycles=0; + prefetchpc = cpu_state.pc; + prefetchw = 0; + memcycs = cycdiff - cycles; + fetchclocks = 0; + // memcycs=cycles; + /* prefetchqueue[0]=readmembf(cs+prefetchpc); prefetchpc++; - } - prefetchw=(is8086)?6:4;*/ -// fetchcycles=0; - prefetchpc = cpu_state.pc; - prefetchw = 0; - memcycs = cycdiff - cycles; - fetchclocks = 0; -// memcycs=cycles; -/* prefetchqueue[0]=readmembf(cs+prefetchpc); - prefetchpc++; - prefetchw=1; - if (is8086 && prefetchpc&1) - { - prefetchqueue[1]=readmembf(cs+prefetchpc); - prefetchpc++; - }*/ + prefetchw=1; + if (is8086 && prefetchpc&1) + { + prefetchqueue[1]=readmembf(cs+prefetchpc); + prefetchpc++; + }*/ } static uint16_t getword() { - uint8_t temp = FETCH(); - return temp | (FETCH() << 8); + 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 @@ -338,106 +345,109 @@ 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; + 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; - } + 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; + } } 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); + 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; -// if (output==3) printf("GETEAW %04X:%08X\n",easeg,eaaddr); - return readmemw(easeg, cpu_state.eaaddr); + if (cpu_mod == 3) + return cpu_state.regs[cpu_rm].w; + // if (output==3) printf("GETEAW %04X:%08X\n",easeg,eaaddr); + return readmemw(easeg, cpu_state.eaaddr); } static inline uint16_t geteaw2() { - if (cpu_mod == 3) - return cpu_state.regs[cpu_rm].w; -// printf("Getting addr from %04X:%04X %05X\n",easeg,eaaddr+2,easeg+eaaddr+2); - return readmemw(easeg, (cpu_state.eaaddr + 2) & 0xFFFF); + if (cpu_mod == 3) + return cpu_state.regs[cpu_rm].w; + // printf("Getting addr from %04X:%04X %05X\n",easeg,eaaddr+2,easeg+eaaddr+2); + return readmemw(easeg, (cpu_state.eaaddr + 2) & 0xFFFF); } 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); - } + 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); -// writememb(easeg+eaaddr+1,val>>8); - } + if (cpu_mod == 3) + cpu_state.regs[cpu_rm].w = val; + else { + writememw(easeg, cpu_state.eaaddr, val); + // writememb(easeg+eaaddr+1,val>>8); + } } /*Flags*/ @@ -445,425 +455,422 @@ uint8_t znptable8[256]; static 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) - pclog("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) - pclog("znp16 b1 = %i %02X\n", d, znptable16[c]); - if (c == 0x65b1) - pclog("znp16 65b1 = %i %02X\n", d, znptable16[c]); - if (!c) - znptable16[c] |= Z_FLAG; - if (c & 0x8000) - znptable16[c] |= N_FLAG; - } + 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) + pclog("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) + pclog("znp16 b1 = %i %02X\n", d, znptable16[c]); + if (c == 0x65b1) + pclog("znp16 65b1 = %i %02X\n", d, znptable16[c]); + if (!c) + znptable16[c] |= Z_FLAG; + if (c & 0x8000) + znptable16[c] |= N_FLAG; + } -// makemod1table(); + // makemod1table(); } int indump = 0; void dumpregs() { - int c, d = 0, e = 0; + int c, d = 0, e = 0; #ifndef RELEASE_BUILD - FILE *f; - if (indump) - return; - indump = 1; -// return; - output = 0; -// return; -// savenvr(); -// return; - chdir(logs_path); -/* f=fopen("rram3.dmp","wb"); - for (c=0;c<0x8000000;c++) putc(readmemb(c+0x10000000),f); - fclose(f);*/ - f = fopen("ram.dmp", "wb"); - fwrite(ram, mem_size * 1024, 1, f); - fclose(f); -/* pclog("Dumping rram5.dmp\n"); - f=fopen("rram5.dmp","wb"); - for (c=0;c<0x1000000;c++) putc(readmemb(c+0x10150000),f); - fclose(f);*/ - pclog("Dumping rram.dmp\n"); - f = fopen("rram.dmp", "wb"); - for (c = 0; c < 0x1000000; c++) - putc(readmemb(c), f); - fclose(f); -/* f=fopen("rram2.dmp","wb"); - for (c=0;c<0x100000;c++) putc(readmemb(c+0xbff00000),f); - fclose(f); - f = fopen("stack.dmp","wb"); - for (c = 0; c < 0x6000; c++) putc(readmemb(c+0xFFDFA000), f); - fclose(f); - f = fopen("tempx.dmp","wb"); - for (c = 0; c < 0x10000; c++) putc(readmemb(c+0xFC816000), f); - fclose(f); - f = fopen("tempx2.dmp","wb"); - for (c = 0; c < 0x10000; c++) putc(readmemb(c+0xFDEF5000), f); - fclose(f);*/ - pclog("Dumping rram4.dmp\n"); - f = fopen("rram4.dmp", "wb"); - for (c = 0; c < 0x0050000; c++) { - cpu_state.abrt = 0; - putc(readmembl(c + 0x80000000), f); - } - fclose(f); - pclog("Dumping done\n"); + FILE *f; + if (indump) + return; + indump = 1; + // return; + output = 0; + // return; + // savenvr(); + // return; + chdir(logs_path); + /* f=fopen("rram3.dmp","wb"); + for (c=0;c<0x8000000;c++) putc(readmemb(c+0x10000000),f); + fclose(f);*/ + f = fopen("ram.dmp", "wb"); + fwrite(ram, mem_size * 1024, 1, f); + fclose(f); + /* pclog("Dumping rram5.dmp\n"); + f=fopen("rram5.dmp","wb"); + for (c=0;c<0x1000000;c++) putc(readmemb(c+0x10150000),f); + fclose(f);*/ + pclog("Dumping rram.dmp\n"); + f = fopen("rram.dmp", "wb"); + for (c = 0; c < 0x1000000; c++) + putc(readmemb(c), f); + fclose(f); + /* f=fopen("rram2.dmp","wb"); + for (c=0;c<0x100000;c++) putc(readmemb(c+0xbff00000),f); + fclose(f); + f = fopen("stack.dmp","wb"); + for (c = 0; c < 0x6000; c++) putc(readmemb(c+0xFFDFA000), f); + fclose(f); + f = fopen("tempx.dmp","wb"); + for (c = 0; c < 0x10000; c++) putc(readmemb(c+0xFC816000), f); + fclose(f); + f = fopen("tempx2.dmp","wb"); + for (c = 0; c < 0x10000; c++) putc(readmemb(c+0xFDEF5000), f); + fclose(f);*/ + pclog("Dumping rram4.dmp\n"); + f = fopen("rram4.dmp", "wb"); + for (c = 0; c < 0x0050000; c++) { + cpu_state.abrt = 0; + putc(readmembl(c + 0x80000000), f); + } + fclose(f); + pclog("Dumping done\n"); /* f=fopen("rram6.dmp","wb"); - for (c=0;c<0x1000000;c++) putc(readmemb(c+0xBF000000),f); - fclose(f);*/ + for (c=0;c<0x1000000;c++) putc(readmemb(c+0xBF000000),f); + fclose(f);*/ /* f=fopen("ram6.bin","wb"); - fwrite(ram+0x10100,0xA000,1,f); - fclose(f); - f=fopen("boot.bin","wb"); - fwrite(ram+0x7C00,0x200,1,f); - fclose(f); - f=fopen("ram7.bin","wb"); - fwrite(ram+0x11100,0x2000,1,f); - fclose(f); - f=fopen("ram8.bin","wb"); - fwrite(ram+0x3D210,0x200,1,f); - fclose(f); */ + fwrite(ram+0x10100,0xA000,1,f); + fclose(f); + f=fopen("boot.bin","wb"); + fwrite(ram+0x7C00,0x200,1,f); + fclose(f); + f=fopen("ram7.bin","wb"); + fwrite(ram+0x11100,0x2000,1,f); + fclose(f); + f=fopen("ram8.bin","wb"); + fwrite(ram+0x3D210,0x200,1,f); + fclose(f); */ /* f=fopen("bios.dmp","wb"); - fwrite(rom,0x20000,1,f); - fclose(f);*/ + fwrite(rom,0x20000,1,f); + fclose(f);*/ /* f=fopen("kernel.dmp","wb"); - for (c=0;c<0x200000;c++) putc(readmemb(c+0xC0000000),f); - fclose(f);*/ + for (c=0;c<0x200000;c++) putc(readmemb(c+0xC0000000),f); + fclose(f);*/ /* f=fopen("rram.dmp","wb"); - for (c=0;c<0x1500000;c++) putc(readmemb(c),f); - fclose(f); - if (!times) - { - f=fopen("thing.dmp","wb"); - fwrite(ram+0x11E50,0x1000,1,f); - fclose(f); - }*/ + for (c=0;c<0x1500000;c++) putc(readmemb(c),f); + fclose(f); + if (!times) + { + f=fopen("thing.dmp","wb"); + fwrite(ram+0x11E50,0x1000,1,f); + fclose(f); + }*/ #endif - if (is386) - printf("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 - printf("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); - printf("PC=%04X CS=%04X DS=%04X ES=%04X SS=%04X FLAGS=%04X\n", cpu_state.pc, CS, DS, ES, SS, cpu_state.flags); - printf("%04X\n", cpu_state.oldpc); - printf("%i ins\n", ins); - if (is386) - printf("In %s mode\n", (msw & 1) ? ((cpu_state.eflags & VM_FLAG) ? "V86" : "protected") : "real"); - else - printf("In %s mode\n", (msw & 1) ? "protected" : "real"); - printf("CS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n", cs, cpu_state.seg_cs.limit, cpu_state.seg_cs.access, cpu_state.seg_cs.limit_low, cpu_state.seg_cs.limit_high); - printf("DS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n", ds, cpu_state.seg_ds.limit, cpu_state.seg_ds.access, cpu_state.seg_ds.limit_low, cpu_state.seg_ds.limit_high); - printf("ES : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n", es, cpu_state.seg_es.limit, cpu_state.seg_es.access, cpu_state.seg_es.limit_low, cpu_state.seg_es.limit_high); - if (is386) { - printf("FS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n", - cpu_state.seg_fs.base, - cpu_state.seg_fs.limit, - cpu_state.seg_fs.access, - cpu_state.seg_fs.limit_low, - cpu_state.seg_fs.limit_high); - printf("GS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n", - gs, - cpu_state.seg_gs.limit, - cpu_state.seg_gs.access, - cpu_state.seg_gs.limit_low, - cpu_state.seg_gs.limit_high); - } - printf("SS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n", ss, cpu_state.seg_ss.limit, cpu_state.seg_ss.access, cpu_state.seg_ss.limit_low, cpu_state.seg_ss.limit_high); - printf("GDT : base=%06X limit=%04X\n", gdt.base, gdt.limit); - printf("LDT : base=%06X limit=%04X\n", ldt.base, ldt.limit); - printf("IDT : base=%06X limit=%04X\n", idt.base, idt.limit); - printf("TR : base=%06X limit=%04X\n", tr.base, tr.limit); - if (is386) { - printf("386 in %s mode stack in %s mode\n", (use32) ? "32-bit" : "16-bit", (stack32) ? "32-bit" : "16-bit"); - printf("CR0=%08X CR2=%08X CR3=%08X CR4=%08x\n", cr0, cr2, cr3, cr4); - pclog("SMBASE=%08x\n", cpu_state.smbase); - } - printf("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++; - } - printf("Entries in readlookup : %i writelookup : %i\n", d, e); - x87_dumpregs(); - indump = 0; + if (is386) + printf("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 + printf("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); + printf("PC=%04X CS=%04X DS=%04X ES=%04X SS=%04X FLAGS=%04X\n", cpu_state.pc, CS, DS, ES, SS, cpu_state.flags); + printf("%04X\n", cpu_state.oldpc); + printf("%i ins\n", ins); + if (is386) + printf("In %s mode\n", (msw & 1) ? ((cpu_state.eflags & VM_FLAG) ? "V86" : "protected") : "real"); + else + printf("In %s mode\n", (msw & 1) ? "protected" : "real"); + printf("CS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n", cs, cpu_state.seg_cs.limit, + cpu_state.seg_cs.access, cpu_state.seg_cs.limit_low, cpu_state.seg_cs.limit_high); + printf("DS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n", ds, cpu_state.seg_ds.limit, + cpu_state.seg_ds.access, cpu_state.seg_ds.limit_low, cpu_state.seg_ds.limit_high); + printf("ES : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n", es, cpu_state.seg_es.limit, + cpu_state.seg_es.access, cpu_state.seg_es.limit_low, cpu_state.seg_es.limit_high); + if (is386) { + printf("FS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n", cpu_state.seg_fs.base, + cpu_state.seg_fs.limit, cpu_state.seg_fs.access, cpu_state.seg_fs.limit_low, cpu_state.seg_fs.limit_high); + printf("GS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n", gs, cpu_state.seg_gs.limit, + cpu_state.seg_gs.access, cpu_state.seg_gs.limit_low, cpu_state.seg_gs.limit_high); + } + printf("SS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n", ss, cpu_state.seg_ss.limit, + cpu_state.seg_ss.access, cpu_state.seg_ss.limit_low, cpu_state.seg_ss.limit_high); + printf("GDT : base=%06X limit=%04X\n", gdt.base, gdt.limit); + printf("LDT : base=%06X limit=%04X\n", ldt.base, ldt.limit); + printf("IDT : base=%06X limit=%04X\n", idt.base, idt.limit); + printf("TR : base=%06X limit=%04X\n", tr.base, tr.limit); + if (is386) { + printf("386 in %s mode stack in %s mode\n", (use32) ? "32-bit" : "16-bit", (stack32) ? "32-bit" : "16-bit"); + printf("CR0=%08X CR2=%08X CR3=%08X CR4=%08x\n", cr0, cr2, cr3, cr4); + pclog("SMBASE=%08x\n", cpu_state.smbase); + } + printf("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++; + } + printf("Entries in readlookup : %i writelookup : %i\n", d, e); + x87_dumpregs(); + indump = 0; } int x86_was_reset = 0; void resetx86() { - pclog("x86 reset\n"); - ins = 0; - use32 = 0; - cpu_cur_status = 0; - stack32 = 0; -// i86_Reset(); -// cs=0xFFFF0; - msw = 0; - if (is486) - cr0 = 1 << 30; - else - cr0 = 0; - cpu_cache_int_enabled = 0; - cpu_update_waitstates(); - cr4 = 0; - cpu_state.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; - cpu_state.flags = 2; - EAX = EBX = ECX = EDX = ESI = EDI = EBP = ESP = 0; - makeznptable(); - resetreadlookup(); - makemod1table(); - FETCHCLEAR(); - x87_reset(); - cpu_set_edx(); - mmu_perm = 4; - x86seg_reset(); - codegen_reset(); - x86_was_reset = 1; - cpu_state.smbase = 0x30000; + pclog("x86 reset\n"); + ins = 0; + use32 = 0; + cpu_cur_status = 0; + stack32 = 0; + // i86_Reset(); + // cs=0xFFFF0; + msw = 0; + if (is486) + cr0 = 1 << 30; + else + cr0 = 0; + cpu_cache_int_enabled = 0; + cpu_update_waitstates(); + cr4 = 0; + cpu_state.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; + cpu_state.flags = 2; + EAX = EBX = ECX = EDX = ESI = EDI = EBP = ESP = 0; + makeznptable(); + resetreadlookup(); + makemod1table(); + FETCHCLEAR(); + x87_reset(); + cpu_set_edx(); + mmu_perm = 4; + x86seg_reset(); + codegen_reset(); + x86_was_reset = 1; + cpu_state.smbase = 0x30000; } void softresetx86() { -// dumpregs(); -// exit(-1); - use32 = 0; - stack32 = 0; - cpu_cur_status = 0; -// i86_Reset(); -// cs=0xFFFF0; - msw = 0; - if (is486) - cr0 = 1 << 30; - else - cr0 = 0; - cpu_cache_int_enabled = 0; - cpu_update_waitstates(); - cr4 = 0; - cpu_state.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; - } - //rammask=0xFFFFFFFF; - cpu_state.flags = 2; - idt.base = 0; - if (is386) { - idt.limit = 0x03FF; - EAX = EBX = ECX = EDX = ESI = EDI = EBP = ESP = 0; - } else { - idt.limit = 0xFFFF; - } - x86seg_reset(); - flushmmucache(); - x86_was_reset = 1; - FETCHCLEAR(); + // dumpregs(); + // exit(-1); + use32 = 0; + stack32 = 0; + cpu_cur_status = 0; + // i86_Reset(); + // cs=0xFFFF0; + msw = 0; + if (is486) + cr0 = 1 << 30; + else + cr0 = 0; + cpu_cache_int_enabled = 0; + cpu_update_waitstates(); + cr4 = 0; + cpu_state.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; + } + // rammask=0xFFFFFFFF; + cpu_state.flags = 2; + idt.base = 0; + if (is386) { + idt.limit = 0x03FF; + EAX = EBX = ECX = EDX = ESI = EDI = EBP = ESP = 0; + } else { + idt.limit = 0xFFFF; + } + x86seg_reset(); + flushmmucache(); + x86_was_reset = 1; + FETCHCLEAR(); } static void setznp8(uint8_t val) { - cpu_state.flags &= ~0xC4; - cpu_state.flags |= znptable8[val]; + cpu_state.flags &= ~0xC4; + cpu_state.flags |= znptable8[val]; } static void setznp16(uint16_t val) { - cpu_state.flags &= ~0xC4; - cpu_state.flags |= znptable16[val]; + cpu_state.flags &= ~0xC4; + cpu_state.flags |= znptable16[val]; } static void setadd8(uint8_t a, uint8_t b) { - uint16_t c = (uint16_t)a + (uint16_t)b; - cpu_state.flags &= ~0x8D5; - cpu_state.flags |= znptable8[c & 0xFF]; - if (c & 0x100) - cpu_state.flags |= C_FLAG; - if (!((a ^ b) & 0x80) && ((a ^ c) & 0x80)) - cpu_state.flags |= V_FLAG; - if (((a & 0xF) + (b & 0xF)) & 0x10) - cpu_state.flags |= A_FLAG; + uint16_t c = (uint16_t)a + (uint16_t)b; + cpu_state.flags &= ~0x8D5; + cpu_state.flags |= znptable8[c & 0xFF]; + if (c & 0x100) + cpu_state.flags |= C_FLAG; + if (!((a ^ b) & 0x80) && ((a ^ c) & 0x80)) + cpu_state.flags |= V_FLAG; + if (((a & 0xF) + (b & 0xF)) & 0x10) + cpu_state.flags |= A_FLAG; } static void setadd8nc(uint8_t a, uint8_t b) { - uint16_t c = (uint16_t)a + (uint16_t)b; - cpu_state.flags &= ~0x8D4; - cpu_state.flags |= znptable8[c & 0xFF]; - if (!((a ^ b) & 0x80) && ((a ^ c) & 0x80)) - cpu_state.flags |= V_FLAG; - if (((a & 0xF) + (b & 0xF)) & 0x10) - cpu_state.flags |= A_FLAG; + uint16_t c = (uint16_t)a + (uint16_t)b; + cpu_state.flags &= ~0x8D4; + cpu_state.flags |= znptable8[c & 0xFF]; + if (!((a ^ b) & 0x80) && ((a ^ c) & 0x80)) + cpu_state.flags |= V_FLAG; + if (((a & 0xF) + (b & 0xF)) & 0x10) + cpu_state.flags |= A_FLAG; } static void setadc8(uint8_t a, uint8_t b) { - uint16_t c = (uint16_t)a + (uint16_t)b + tempc; - cpu_state.flags &= ~0x8D5; - cpu_state.flags |= znptable8[c & 0xFF]; - if (c & 0x100) - cpu_state.flags |= C_FLAG; - if (!((a ^ b) & 0x80) && ((a ^ c) & 0x80)) - cpu_state.flags |= V_FLAG; - if (((a & 0xF) + (b & 0xF)) & 0x10) - cpu_state.flags |= A_FLAG; + uint16_t c = (uint16_t)a + (uint16_t)b + tempc; + cpu_state.flags &= ~0x8D5; + cpu_state.flags |= znptable8[c & 0xFF]; + if (c & 0x100) + cpu_state.flags |= C_FLAG; + if (!((a ^ b) & 0x80) && ((a ^ c) & 0x80)) + cpu_state.flags |= V_FLAG; + if (((a & 0xF) + (b & 0xF)) & 0x10) + cpu_state.flags |= A_FLAG; } static void setadd16(uint16_t a, uint16_t b) { - uint32_t c = (uint32_t)a + (uint32_t)b; - cpu_state.flags &= ~0x8D5; - cpu_state.flags |= znptable16[c & 0xFFFF]; - if (c & 0x10000) - cpu_state.flags |= C_FLAG; - if (!((a ^ b) & 0x8000) && ((a ^ c) & 0x8000)) - cpu_state.flags |= V_FLAG; - if (((a & 0xF) + (b & 0xF)) & 0x10) - cpu_state.flags |= A_FLAG; + uint32_t c = (uint32_t)a + (uint32_t)b; + cpu_state.flags &= ~0x8D5; + cpu_state.flags |= znptable16[c & 0xFFFF]; + if (c & 0x10000) + cpu_state.flags |= C_FLAG; + if (!((a ^ b) & 0x8000) && ((a ^ c) & 0x8000)) + cpu_state.flags |= V_FLAG; + if (((a & 0xF) + (b & 0xF)) & 0x10) + cpu_state.flags |= A_FLAG; } static void setadd16nc(uint16_t a, uint16_t b) { - uint32_t c = (uint32_t)a + (uint32_t)b; - cpu_state.flags &= ~0x8D4; - cpu_state.flags |= znptable16[c & 0xFFFF]; - if (!((a ^ b) & 0x8000) && ((a ^ c) & 0x8000)) - cpu_state.flags |= V_FLAG; - if (((a & 0xF) + (b & 0xF)) & 0x10) - cpu_state.flags |= A_FLAG; + uint32_t c = (uint32_t)a + (uint32_t)b; + cpu_state.flags &= ~0x8D4; + cpu_state.flags |= znptable16[c & 0xFFFF]; + if (!((a ^ b) & 0x8000) && ((a ^ c) & 0x8000)) + cpu_state.flags |= V_FLAG; + if (((a & 0xF) + (b & 0xF)) & 0x10) + cpu_state.flags |= A_FLAG; } static void setadc16(uint16_t a, uint16_t b) { - uint32_t c = (uint32_t)a + (uint32_t)b + tempc; - cpu_state.flags &= ~0x8D5; - cpu_state.flags |= znptable16[c & 0xFFFF]; - if (c & 0x10000) - cpu_state.flags |= C_FLAG; - if (!((a ^ b) & 0x8000) && ((a ^ c) & 0x8000)) - cpu_state.flags |= V_FLAG; - if (((a & 0xF) + (b & 0xF)) & 0x10) - cpu_state.flags |= A_FLAG; + uint32_t c = (uint32_t)a + (uint32_t)b + tempc; + cpu_state.flags &= ~0x8D5; + cpu_state.flags |= znptable16[c & 0xFFFF]; + if (c & 0x10000) + cpu_state.flags |= C_FLAG; + if (!((a ^ b) & 0x8000) && ((a ^ c) & 0x8000)) + cpu_state.flags |= V_FLAG; + if (((a & 0xF) + (b & 0xF)) & 0x10) + cpu_state.flags |= A_FLAG; } static void setsub8(uint8_t a, uint8_t b) { - uint16_t c = (uint16_t)a - (uint16_t)b; - cpu_state.flags &= ~0x8D5; - cpu_state.flags |= znptable8[c & 0xFF]; - if (c & 0x100) - cpu_state.flags |= C_FLAG; - if ((a ^ b) & (a ^ c) & 0x80) - cpu_state.flags |= V_FLAG; - if (((a & 0xF) - (b & 0xF)) & 0x10) - cpu_state.flags |= A_FLAG; + uint16_t c = (uint16_t)a - (uint16_t)b; + cpu_state.flags &= ~0x8D5; + cpu_state.flags |= znptable8[c & 0xFF]; + if (c & 0x100) + cpu_state.flags |= C_FLAG; + if ((a ^ b) & (a ^ c) & 0x80) + cpu_state.flags |= V_FLAG; + if (((a & 0xF) - (b & 0xF)) & 0x10) + cpu_state.flags |= A_FLAG; } static void setsub8nc(uint8_t a, uint8_t b) { - uint16_t c = (uint16_t)a - (uint16_t)b; - cpu_state.flags &= ~0x8D4; - cpu_state.flags |= znptable8[c & 0xFF]; - if ((a ^ b) & (a ^ c) & 0x80) - cpu_state.flags |= V_FLAG; - if (((a & 0xF) - (b & 0xF)) & 0x10) - cpu_state.flags |= A_FLAG; + uint16_t c = (uint16_t)a - (uint16_t)b; + cpu_state.flags &= ~0x8D4; + cpu_state.flags |= znptable8[c & 0xFF]; + if ((a ^ b) & (a ^ c) & 0x80) + cpu_state.flags |= V_FLAG; + if (((a & 0xF) - (b & 0xF)) & 0x10) + cpu_state.flags |= A_FLAG; } static void setsbc8(uint8_t a, uint8_t b) { - uint16_t c = (uint16_t)a - (((uint16_t)b) + tempc); - cpu_state.flags &= ~0x8D5; - cpu_state.flags |= znptable8[c & 0xFF]; - if (c & 0x100) - cpu_state.flags |= C_FLAG; - if ((a ^ b) & (a ^ c) & 0x80) - cpu_state.flags |= V_FLAG; - if (((a & 0xF) - (b & 0xF)) & 0x10) - cpu_state.flags |= A_FLAG; + uint16_t c = (uint16_t)a - (((uint16_t)b) + tempc); + cpu_state.flags &= ~0x8D5; + cpu_state.flags |= znptable8[c & 0xFF]; + if (c & 0x100) + cpu_state.flags |= C_FLAG; + if ((a ^ b) & (a ^ c) & 0x80) + cpu_state.flags |= V_FLAG; + if (((a & 0xF) - (b & 0xF)) & 0x10) + cpu_state.flags |= A_FLAG; } static void setsub16(uint16_t a, uint16_t b) { - uint32_t c = (uint32_t)a - (uint32_t)b; - cpu_state.flags &= ~0x8D5; - cpu_state.flags |= znptable16[c & 0xFFFF]; - if (c & 0x10000) - cpu_state.flags |= C_FLAG; - if ((a ^ b) & (a ^ c) & 0x8000) - cpu_state.flags |= V_FLAG; - if (((a & 0xF) - (b & 0xF)) & 0x10) - cpu_state.flags |= A_FLAG; + uint32_t c = (uint32_t)a - (uint32_t)b; + cpu_state.flags &= ~0x8D5; + cpu_state.flags |= znptable16[c & 0xFFFF]; + if (c & 0x10000) + cpu_state.flags |= C_FLAG; + if ((a ^ b) & (a ^ c) & 0x8000) + cpu_state.flags |= V_FLAG; + if (((a & 0xF) - (b & 0xF)) & 0x10) + cpu_state.flags |= A_FLAG; } static void setsub16nc(uint16_t a, uint16_t b) { - uint32_t c = (uint32_t)a - (uint32_t)b; - cpu_state.flags &= ~0x8D4; - cpu_state.flags |= (znptable16[c & 0xFFFF] & ~4); - cpu_state.flags |= (znptable8[c & 0xFF] & 4); - if ((a ^ b) & (a ^ c) & 0x8000) - cpu_state.flags |= V_FLAG; - if (((a & 0xF) - (b & 0xF)) & 0x10) - cpu_state.flags |= A_FLAG; + uint32_t c = (uint32_t)a - (uint32_t)b; + cpu_state.flags &= ~0x8D4; + cpu_state.flags |= (znptable16[c & 0xFFFF] & ~4); + cpu_state.flags |= (znptable8[c & 0xFF] & 4); + if ((a ^ b) & (a ^ c) & 0x8000) + cpu_state.flags |= V_FLAG; + if (((a & 0xF) - (b & 0xF)) & 0x10) + cpu_state.flags |= A_FLAG; } static void setsbc16(uint16_t a, uint16_t b) { - uint32_t c = (uint32_t)a - (((uint32_t)b) + tempc); - cpu_state.flags &= ~0x8D5; - cpu_state.flags |= (znptable16[c & 0xFFFF] & ~4); - cpu_state.flags |= (znptable8[c & 0xFF] & 4); - if (c & 0x10000) - cpu_state.flags |= C_FLAG; - if ((a ^ b) & (a ^ c) & 0x8000) - cpu_state.flags |= V_FLAG; - if (((a & 0xF) - (b & 0xF)) & 0x10) - cpu_state.flags |= A_FLAG; + uint32_t c = (uint32_t)a - (((uint32_t)b) + tempc); + cpu_state.flags &= ~0x8D5; + cpu_state.flags |= (znptable16[c & 0xFFFF] & ~4); + cpu_state.flags |= (znptable8[c & 0xFF] & 4); + if (c & 0x10000) + cpu_state.flags |= C_FLAG; + if ((a ^ b) & (a ^ c) & 0x8000) + cpu_state.flags |= V_FLAG; + if (((a & 0xF) - (b & 0xF)) & 0x10) + cpu_state.flags |= A_FLAG; } int current_diff = 0; @@ -874,16 +881,16 @@ int current_diff = 0; static uint64_t tsc_frac = 0; static void clockhardware() { - int diff = cycdiff - cycles - current_diff; + int diff = cycdiff - cycles - current_diff; - current_diff += diff; + current_diff += diff; - tsc_frac += (uint64_t)diff * xt_cpu_multi; + tsc_frac += (uint64_t)diff * xt_cpu_multi; - tsc += (tsc_frac >> 32); - tsc_frac &= 0xffffffff; - if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc)) - timer_process(); + tsc += (tsc_frac >> 32); + tsc_frac &= 0xffffffff; + if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc)) + timer_process(); } static int takeint = 0; @@ -891,305 +898,310 @@ static int takeint = 0; int firstrepcycle = 1; static void rep(int fv) { - uint8_t temp; - int c = CX; - uint8_t temp2; - uint16_t tempw, tempw2; - uint16_t ipc = cpu_state.oldpc;//pc-1; - int changeds = 0; - uint32_t oldds = ds; - startrep: - temp = FETCH(); + uint8_t temp; + int c = CX; + uint8_t temp2; + uint16_t tempw, tempw2; + uint16_t ipc = cpu_state.oldpc; // pc-1; + int changeds = 0; + uint32_t oldds = ds; +startrep: + temp = FETCH(); -// if (firstrepcycle && temp==0xA5) printf("REP MOVSW %06X:%04X %06X:%04X\n",ds,SI,es,DI); -// if (output) printf("REP %02X %04X\n",temp,ipc); - 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 (cpu_state.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 (output) printf("Moved %02X from %04X:%04X to %04X:%04X\n",temp2,ds>>4,SI,es>>4,DI); - if (cpu_state.flags & D_FLAG) { - DI--; - SI--; - } else { - DI++; - SI++; - } - c--; - cycles -= 17; - clockhardware(); - FETCHADD(17 - memcycs); - } - if (IRQTEST && c > 0) - cpu_state.pc = ipc; -// if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; FETCHCLEAR(); } -// else firstrepcycle=1; -// } - break; - case 0xA5: /*REP MOVSW*/ - while (c > 0 && !IRQTEST) { - memcycs = 0; - tempw = readmemw(ds, SI); - writememw(es, DI, tempw); - if (cpu_state.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; -// if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; FETCHCLEAR(); } -// else firstrepcycle=1; -// } - break; - case 0xA6: /*REP CMPSB*/ - if (fv) - cpu_state.flags |= Z_FLAG; - else - cpu_state.flags &= ~Z_FLAG; - while ((c > 0) && (fv == ((cpu_state.flags & Z_FLAG) ? 1 : 0)) && !IRQTEST) { - memcycs = 0; - temp = readmemb(ds + SI); - temp2 = readmemb(es + DI); -// printf("CMPSB %c %c %i %05X %05X %04X:%04X\n",temp,temp2,c,ds+SI,es+DI,cs>>4,pc); - if (cpu_state.flags & D_FLAG) { - DI--; - SI--; - } else { - DI++; - SI++; - } - c--; - cycles -= 30; - setsub8(temp, temp2); - clockhardware(); - FETCHADD(30 - memcycs); - } - if (IRQTEST && c > 0 && (fv == ((cpu_state.flags & Z_FLAG) ? 1 : 0))) - cpu_state.pc = ipc; -// if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; FETCHCLEAR(); } -// else firstrepcycle=1; - break; - case 0xA7: /*REP CMPSW*/ - if (fv) - cpu_state.flags |= Z_FLAG; - else - cpu_state.flags &= ~Z_FLAG; - while ((c > 0) && (fv == ((cpu_state.flags & Z_FLAG) ? 1 : 0)) && !IRQTEST) { - memcycs = 0; - tempw = readmemw(ds, SI); - tempw2 = readmemw(es, DI); - if (cpu_state.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 == ((cpu_state.flags & Z_FLAG) ? 1 : 0))) - cpu_state.pc = ipc; -// if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; FETCHCLEAR(); } -// else firstrepcycle=1; -// if (firstrepcycle) printf("REP CMPSW %06X:%04X %06X:%04X %04X %04X\n",ds,SI,es,DI,tempw,tempw2); - break; - case 0xAA: /*REP STOSB*/ - while (c > 0 && !IRQTEST) { - memcycs = 0; - writememb(es + DI, AL); - if (cpu_state.flags & D_FLAG) - DI--; - else - DI++; - c--; - cycles -= 10; - clockhardware(); - FETCHADD(10 - memcycs); - } - if (IRQTEST && c > 0) - cpu_state.pc = ipc; -// if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; FETCHCLEAR(); } -// else firstrepcycle=1; - break; - case 0xAB: /*REP STOSW*/ - while (c > 0 && !IRQTEST) { - memcycs = 0; - writememw(es, DI, AX); - if (cpu_state.flags & D_FLAG) - DI -= 2; - else - DI += 2; - c--; - cycles -= 10; - clockhardware(); - FETCHADD(10 - memcycs); - } - if (IRQTEST && c > 0) - cpu_state.pc = ipc; -// if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; FETCHCLEAR(); } -// else firstrepcycle=1; - break; - case 0xAC: /*REP LODSB*/ - if (c > 0) { - temp2 = readmemb(ds + SI); - if (cpu_state.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 (cpu_state.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) - cpu_state.flags |= Z_FLAG; - else - cpu_state.flags &= ~Z_FLAG; - if ((c > 0) && (fv == ((cpu_state.flags & Z_FLAG) ? 1 : 0))) { - temp2 = readmemb(es + DI); -// if (output) printf("SCASB %02X %c %02X %05X ",temp2,temp2,AL,es+DI); - setsub8(AL, temp2); -// if (output && flags&Z_FLAG) printf("Match %02X %02X\n",AL,temp2); - if (cpu_state.flags & D_FLAG) - DI--; - else - DI++; - c--; - cycles -= 15; - } -//if (output) printf("%i %i %i %i\n",c,(c>0),(fv==((flags&Z_FLAG)?1:0)),((c>0) && (fv==((flags&Z_FLAG)?1:0)))); - if ((c > 0) && (fv == ((cpu_state.flags & Z_FLAG) ? 1 : 0))) { - cpu_state.pc = ipc; - firstrepcycle = 0; - if (cpu_state.ssegs) - cpu_state.ssegs++; - FETCHCLEAR(); - } else - firstrepcycle = 1; -// cycles-=120; - break; - case 0xAF: /*REP SCASW*/ - if (fv) - cpu_state.flags |= Z_FLAG; - else - cpu_state.flags &= ~Z_FLAG; - if ((c > 0) && (fv == ((cpu_state.flags & Z_FLAG) ? 1 : 0))) { - tempw = readmemw(es, DI); - setsub16(AX, tempw); - if (cpu_state.flags & D_FLAG) - DI -= 2; - else - DI += 2; - c--; - cycles -= 15; - } - if ((c > 0) && (fv == ((cpu_state.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(); -// printf("Bad REP %02X\n",temp); -// dumpregs(); -// exit(-1); - } - CX = c; - if (changeds) - ds = oldds; - if (IRQTEST) - takeint = 1; -// if (pc==ipc) FETCHCLEAR(); + // if (firstrepcycle && temp==0xA5) printf("REP MOVSW %06X:%04X %06X:%04X\n",ds,SI,es,DI); + // if (output) printf("REP %02X %04X\n",temp,ipc); + 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 (cpu_state.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 (output) printf("Moved %02X from %04X:%04X to + // %04X:%04X\n",temp2,ds>>4,SI,es>>4,DI); + if (cpu_state.flags & D_FLAG) { + DI--; + SI--; + } else { + DI++; + SI++; + } + c--; + cycles -= 17; + clockhardware(); + FETCHADD(17 - memcycs); + } + if (IRQTEST && c > 0) + cpu_state.pc = ipc; + // if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; FETCHCLEAR(); } + // else firstrepcycle=1; + // } + break; + case 0xA5: /*REP MOVSW*/ + while (c > 0 && !IRQTEST) { + memcycs = 0; + tempw = readmemw(ds, SI); + writememw(es, DI, tempw); + if (cpu_state.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; + // if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; FETCHCLEAR(); } + // else firstrepcycle=1; + // } + break; + case 0xA6: /*REP CMPSB*/ + if (fv) + cpu_state.flags |= Z_FLAG; + else + cpu_state.flags &= ~Z_FLAG; + while ((c > 0) && (fv == ((cpu_state.flags & Z_FLAG) ? 1 : 0)) && !IRQTEST) { + memcycs = 0; + temp = readmemb(ds + SI); + temp2 = readmemb(es + DI); + // printf("CMPSB %c %c %i %05X %05X + // %04X:%04X\n",temp,temp2,c,ds+SI,es+DI,cs>>4,pc); + if (cpu_state.flags & D_FLAG) { + DI--; + SI--; + } else { + DI++; + SI++; + } + c--; + cycles -= 30; + setsub8(temp, temp2); + clockhardware(); + FETCHADD(30 - memcycs); + } + if (IRQTEST && c > 0 && (fv == ((cpu_state.flags & Z_FLAG) ? 1 : 0))) + cpu_state.pc = ipc; + // if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; + // FETCHCLEAR(); } else firstrepcycle=1; + break; + case 0xA7: /*REP CMPSW*/ + if (fv) + cpu_state.flags |= Z_FLAG; + else + cpu_state.flags &= ~Z_FLAG; + while ((c > 0) && (fv == ((cpu_state.flags & Z_FLAG) ? 1 : 0)) && !IRQTEST) { + memcycs = 0; + tempw = readmemw(ds, SI); + tempw2 = readmemw(es, DI); + if (cpu_state.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 == ((cpu_state.flags & Z_FLAG) ? 1 : 0))) + cpu_state.pc = ipc; + // if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) { pc=ipc; firstrepcycle=0; if (ssegs) ssegs++; + // FETCHCLEAR(); } else firstrepcycle=1; if (firstrepcycle) printf("REP CMPSW %06X:%04X %06X:%04X + // %04X %04X\n",ds,SI,es,DI,tempw,tempw2); + break; + case 0xAA: /*REP STOSB*/ + while (c > 0 && !IRQTEST) { + memcycs = 0; + writememb(es + DI, AL); + if (cpu_state.flags & D_FLAG) + DI--; + else + DI++; + c--; + cycles -= 10; + clockhardware(); + FETCHADD(10 - memcycs); + } + if (IRQTEST && c > 0) + cpu_state.pc = ipc; + // if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; FETCHCLEAR(); } + // else firstrepcycle=1; + break; + case 0xAB: /*REP STOSW*/ + while (c > 0 && !IRQTEST) { + memcycs = 0; + writememw(es, DI, AX); + if (cpu_state.flags & D_FLAG) + DI -= 2; + else + DI += 2; + c--; + cycles -= 10; + clockhardware(); + FETCHADD(10 - memcycs); + } + if (IRQTEST && c > 0) + cpu_state.pc = ipc; + // if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; FETCHCLEAR(); } + // else firstrepcycle=1; + break; + case 0xAC: /*REP LODSB*/ + if (c > 0) { + temp2 = readmemb(ds + SI); + if (cpu_state.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 (cpu_state.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) + cpu_state.flags |= Z_FLAG; + else + cpu_state.flags &= ~Z_FLAG; + if ((c > 0) && (fv == ((cpu_state.flags & Z_FLAG) ? 1 : 0))) { + temp2 = readmemb(es + DI); + // if (output) printf("SCASB %02X %c %02X %05X ",temp2,temp2,AL,es+DI); + setsub8(AL, temp2); + // if (output && flags&Z_FLAG) printf("Match %02X %02X\n",AL,temp2); + if (cpu_state.flags & D_FLAG) + DI--; + else + DI++; + c--; + cycles -= 15; + } + // if (output) printf("%i %i %i %i\n",c,(c>0),(fv==((flags&Z_FLAG)?1:0)),((c>0) && + // (fv==((flags&Z_FLAG)?1:0)))); + if ((c > 0) && (fv == ((cpu_state.flags & Z_FLAG) ? 1 : 0))) { + cpu_state.pc = ipc; + firstrepcycle = 0; + if (cpu_state.ssegs) + cpu_state.ssegs++; + FETCHCLEAR(); + } else + firstrepcycle = 1; + // cycles-=120; + break; + case 0xAF: /*REP SCASW*/ + if (fv) + cpu_state.flags |= Z_FLAG; + else + cpu_state.flags &= ~Z_FLAG; + if ((c > 0) && (fv == ((cpu_state.flags & Z_FLAG) ? 1 : 0))) { + tempw = readmemw(es, DI); + setsub16(AX, tempw); + if (cpu_state.flags & D_FLAG) + DI -= 2; + else + DI += 2; + c--; + cycles -= 15; + } + if ((c > 0) && (fv == ((cpu_state.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(); + // printf("Bad REP %02X\n",temp); + // dumpregs(); + // exit(-1); + } + CX = c; + if (changeds) + ds = oldds; + if (IRQTEST) + takeint = 1; + // if (pc==ipc) FETCHCLEAR(); } static int inhlt = 0; @@ -1198,2764 +1210,2777 @@ static int skipnextprint = 0; #include "8087.h" void execx86(int cycs) { - uint8_t temp, temp2; - uint16_t addr, tempw, tempw2, tempw3, tempw4; - int8_t offset; - int tempws; - uint32_t templ; - int c; - int tempi; - int trap; - -// printf("Run x86! %i %i\n",cycles,cycs); - cycles += cycs; -// i86_Execute(cycs); -// return; - while (cycles > 0) { - uint8_t opcode; - - cycdiff = cycles; - current_diff = 0; - cycles -= nextcyc; -// if (instime) pclog("Cycles %i %i\n",cycles,cycdiff); - nextcyc = 0; -// if (output) printf("CLOCK %i %i\n",cycdiff,cycles); - fetchclocks = 0; - cpu_state.oldpc = cpu_state.pc; - opcodestart: - opcode = FETCH(); - tempc = cpu_state.flags & C_FLAG; - trap = cpu_state.flags & T_FLAG; - cpu_state.pc--; -// output=1; -// if (output) printf("%04X:%04X : %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %02X %04X\n",cs>>4,pc,AX,BX,CX,DX,cs>>4,ds>>4,es>>4,ss>>4,DI,SI,BP,SP,opcode,flags&~0x200,rmdat); -//#if 0 - if (output) { -// if ((opcode!=0xF2 && opcode!=0xF3) || firstrepcycle) -// { - if (!skipnextprint) - printf("%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, - cpu_state.flags, - ins, - ram, - ram[0x1a925]); - skipnextprint = 0; -// ins++; -// } - } -//#endif - cpu_state.pc++; - inhlt = 0; -// if (ins==500000) { dumpregs(); exit(0); }*/ - switch (opcode) { - case 0x00: /*ADD 8,reg*/ - fetchea(); -/* if (!rmdat) pc--; - if (!rmdat) - { - fatal("Crashed\n"); -// clear_keybuf(); -// readkey(); - }*/ - 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; - cycles -= 14; - break; - case 0x07: /*POP ES*/ - if (cpu_state.ssegs) - ss = oldss; - tempw = readmemw(ss, SP); - loadseg(tempw, &cpu_state.seg_es); - SP += 2; - cycles -= 12; - break; - - case 0x08: /*OR 8,reg*/ - fetchea(); - temp = geteab(); - temp |= getr8(cpu_reg); - setznp8(temp); - cpu_state.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); - cpu_state.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); - cpu_state.flags &= ~(C_FLAG | V_FLAG | A_FLAG); - setr8(cpu_reg, temp); - cycles -= ((cpu_mod == 3) ? 3 : 13); - break; - case 0x0B: /*OR cpu_reg,16*/ - fetchea(); - tempw = geteaw(); - tempw |= cpu_state.regs[cpu_reg].w; - setznp16(tempw); - cpu_state.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); - cpu_state.flags &= ~(C_FLAG | V_FLAG | A_FLAG); - cycles -= 4; - break; - case 0x0D: /*OR AX,#16*/ - AX |= getword(); - setznp16(AX); - cpu_state.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; - cycles -= 14; - break; - case 0x0F: /*POP CS - 8088/8086 only*/ - if (cpu_state.ssegs) - ss = oldss; - tempw = readmemw(ss, SP); - loadseg(tempw, &cpu_state.seg_cs); - SP += 2; - 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); - 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; - break; - case 0x17: /*POP SS*/ - if (cpu_state.ssegs) - ss = oldss; - tempw = readmemw(ss, SP); - loadseg(tempw, &cpu_state.seg_ss); - SP += 2; - noint = 1; - cycles -= 12; -// output=1; - 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; -// printf("%04X:%04X SBB %04X-%04X,%i\n",cs>>4,pc,tempw,tempw2,tempc); - 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; -// printf("%04X:%04X SBB %04X-%04X,%i\n",cs>>4,pc,tempw,tempw2,tempc); - 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; - cycles -= 14; - break; - case 0x1F: /*POP DS*/ - if (cpu_state.ssegs) - ss = oldss; - tempw = readmemw(ss, SP); - loadseg(tempw, &cpu_state.seg_ds); - if (cpu_state.ssegs) - oldds = ds; - SP += 2; - cycles -= 12; - break; - - case 0x20: /*AND 8,reg*/ - fetchea(); - temp = geteab(); - temp &= getr8(cpu_reg); - setznp8(temp); - cpu_state.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); - cpu_state.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); - cpu_state.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); - cpu_state.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); - cpu_state.flags &= ~(C_FLAG | V_FLAG | A_FLAG); - cycles -= 4; - break; - case 0x25: /*AND AX,#16*/ - AX &= getword(); - setznp16(AX); - cpu_state.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; -// break; - - case 0x27: /*DAA*/ - if ((cpu_state.flags & A_FLAG) || ((AL & 0xF) > 9)) { - tempi = ((uint16_t)AL) + 6; - AL += 6; - cpu_state.flags |= A_FLAG; - if (tempi & 0x100) - cpu_state.flags |= C_FLAG; - } -// else -// flags&=~A_FLAG; - if ((cpu_state.flags & C_FLAG) || (AL > 0x9F)) { - AL += 0x60; - cpu_state.flags |= C_FLAG; - } -// else -// 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(); -// printf("%04X:%04X %04X-%04X\n",cs>>4,pc,tempw,cpu_state.regs[cpu_reg].w); - 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(); -// printf("%04X:%04X %04X-%04X\n",cs>>4,pc,cpu_state.regs[cpu_reg].w,tempw); - 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*/ -// printf("INS %i\n",ins); -// output=1; - 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 ((cpu_state.flags & A_FLAG) || ((AL & 0xF) > 9)) { - tempi = ((uint16_t)AL) - 6; - AL -= 6; - cpu_state.flags |= A_FLAG; - if (tempi & 0x100) - cpu_state.flags |= C_FLAG; - } -// else -// flags&=~A_FLAG; - if ((cpu_state.flags & C_FLAG) || (AL > 0x9F)) { - AL -= 0x60; - cpu_state.flags |= C_FLAG; - } -// else -// flags&=~C_FLAG; - setznp8(AL); - cycles -= 4; - break; - case 0x30: /*XOR 8,reg*/ - fetchea(); - temp = geteab(); - temp ^= getr8(cpu_reg); - setznp8(temp); - cpu_state.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); - cpu_state.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); - cpu_state.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); - cpu_state.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); - cpu_state.flags &= ~(C_FLAG | V_FLAG | A_FLAG); - cycles -= 4; - break; - case 0x35: /*XOR AX,#16*/ - AX ^= getword(); - setznp16(AX); - cpu_state.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; -// break; - - case 0x37: /*AAA*/ - if ((cpu_state.flags & A_FLAG) || ((AL & 0xF) > 9)) { - AL += 6; - AH++; - cpu_state.flags |= (A_FLAG | C_FLAG); - } else - cpu_state.flags &= ~(A_FLAG | C_FLAG); - AL &= 0xF; - cycles -= 8; - break; - - case 0x38: /*CMP 8,reg*/ - fetchea(); - temp = geteab(); -// if (output) printf("CMP %02X-%02X\n",temp,getr8(cpu_reg)); - setsub8(temp, getr8(cpu_reg)); - cycles -= ((cpu_mod == 3) ? 3 : 13); - break; - case 0x39: /*CMP 16,reg*/ - fetchea(); - tempw = geteaw(); -// if (output) printf("CMP %04X-%04X\n",tempw,cpu_state.regs[cpu_reg].w); - setsub16(tempw, cpu_state.regs[cpu_reg].w); - cycles -= ((cpu_mod == 3) ? 3 : 13); - break; - case 0x3A: /*CMP cpu_reg,8*/ - fetchea(); - temp = geteab(); -// if (output) printf("CMP %02X-%02X\n",getr8(cpu_reg),temp); - setsub8(getr8(cpu_reg), temp); - cycles -= ((cpu_mod == 3) ? 3 : 13); - break; - case 0x3B: /*CMP cpu_reg,16*/ - fetchea(); - tempw = geteaw(); -// printf("CMP %04X-%04X\n",cpu_state.regs[cpu_reg].w,tempw); - 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; -// break; - - case 0x3F: /*AAS*/ - if ((cpu_state.flags & A_FLAG) || ((AL & 0xF) > 9)) { - AL -= 6; - AH--; - cpu_state.flags |= (A_FLAG | C_FLAG); - } else - cpu_state.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; - 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.regs[opcode & 7].w = readmemw(ss, (SP - 2) & 0xFFFF); - cycles -= 12; - break; - - case 0x60: /*JO alias*/ - case 0x70: /*JO*/ - offset = (int8_t)FETCH(); - if (cpu_state.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 (!(cpu_state.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 (cpu_state.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 (!(cpu_state.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 (cpu_state.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 (!(cpu_state.flags & Z_FLAG)) { - cpu_state.pc += offset; - cycles -= 12; - FETCHCLEAR(); - } - break; - case 0x66: /*JBE alias*/ - case 0x76: /*JBE*/ - offset = (int8_t)FETCH(); - if (cpu_state.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 (!(cpu_state.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 (cpu_state.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 (!(cpu_state.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 (cpu_state.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 (!(cpu_state.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 = (cpu_state.flags & N_FLAG) ? 1 : 0; - temp2 = (cpu_state.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 = (cpu_state.flags & N_FLAG) ? 1 : 0; - temp2 = (cpu_state.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 = (cpu_state.flags & N_FLAG) ? 1 : 0; - temp2 = (cpu_state.flags & V_FLAG) ? 1 : 0; - if ((cpu_state.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 = (cpu_state.flags & N_FLAG) ? 1 : 0; - temp2 = (cpu_state.flags & V_FLAG) ? 1 : 0; - if (!((cpu_state.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); - cpu_state.flags &= ~(C_FLAG | V_FLAG | A_FLAG); - seteab(temp); - cycles -= ((cpu_mod == 3) ? 4 : 23); - break; - case 0x10: /*ADC b,#8*/ -// temp2+=(flags&C_FLAG); - setadc8(temp, temp2); - seteab(temp + temp2 + tempc); - cycles -= ((cpu_mod == 3) ? 4 : 23); - break; - case 0x18: /*SBB b,#8*/ -// temp2+=(flags&C_FLAG); - setsbc8(temp, temp2); - seteab(temp - (temp2 + tempc)); - cycles -= ((cpu_mod == 3) ? 4 : 23); - break; - case 0x20: /*AND b,#8*/ - temp &= temp2; - setznp8(temp); - cpu_state.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); - cpu_state.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; - -// default: -// printf("Bad 80 opcode %02X\n",rmdat&0x38); -// dumpregs(); -// exit(-1); - } - 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); - cpu_state.flags &= ~(C_FLAG | V_FLAG | A_FLAG); - seteaw(tempw); - cycles -= ((cpu_mod == 3) ? 4 : 23); - break; - case 0x10: /*ADC w,#16*/ -// tempw2+=(flags&C_FLAG); - setadc16(tempw, tempw2); - tempw += tempw2 + tempc; - seteaw(tempw); - cycles -= ((cpu_mod == 3) ? 4 : 23); - break; - case 0x20: /*AND w,#16*/ - tempw &= tempw2; - setznp16(tempw); - cpu_state.flags &= ~(C_FLAG | V_FLAG | A_FLAG); - seteaw(tempw); - cycles -= ((cpu_mod == 3) ? 4 : 23); - break; - case 0x18: /*SBB w,#16*/ -// tempw2+=(flags&C_FLAG); - 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); - cpu_state.flags &= ~(C_FLAG | V_FLAG | A_FLAG); - seteaw(tempw); - cycles -= ((cpu_mod == 3) ? 4 : 23); - break; - case 0x38: /*CMP w,#16*/ -// printf("CMP %04X %04X\n",tempw,tempw2); - setsub16(tempw, tempw2); - cycles -= ((cpu_mod == 3) ? 4 : 14); - break; - -// default: -// printf("Bad 81 opcode %02X\n",rmdat&0x38); -// dumpregs(); -// exit(-1); - } - 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); - cpu_state.flags &= ~(C_FLAG | A_FLAG | V_FLAG); - cycles -= ((cpu_mod == 3) ? 4 : 23); - break; - case 0x10: /*ADC w,#8*/ -// tempw2+=(flags&C_FLAG); - setadc16(tempw, tempw2); - tempw += tempw2 + tempc; - seteaw(tempw); - cycles -= ((cpu_mod == 3) ? 4 : 23); - break; - case 0x18: /*SBB w,#8*/ -// tempw2+=(flags&C_FLAG); - 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); - cpu_state.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); - cpu_state.flags &= ~(C_FLAG | A_FLAG | V_FLAG); - break; - case 0x38: /*CMP w,#8*/ - setsub16(tempw, tempw2); - cycles -= ((cpu_mod == 3) ? 4 : 14); - break; - -// default: -// printf("Bad 83 opcode %02X\n",rmdat&0x38); -// dumpregs(); -// exit(-1); - } - break; - - case 0x84: /*TEST b,reg*/ - fetchea(); - temp = geteab(); - temp2 = getr8(cpu_reg); - setznp8(temp & temp2); - cpu_state.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); - cpu_state.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_state.eaaddr; - cycles -= 2; - break; - - case 0x8E: /*MOV sreg,w*/ -// if (output) printf("MOV %04X ",pc); - fetchea(); -// if (output) printf("%04X %02X\n",pc,rmdat); - switch (rmdat & 0x38) { - case 0x00: /*ES*/ - tempw = geteaw(); - loadseg(tempw, &cpu_state.seg_es); - break; - case 0x08: /*CS - 8088/8086 only*/ - tempw = geteaw(); - loadseg(tempw, &cpu_state.seg_cs); - break; - case 0x18: /*DS*/ - tempw = geteaw(); - loadseg(tempw, &cpu_state.seg_ds); - if (cpu_state.ssegs) - oldds = ds; - break; - case 0x10: /*SS*/ - tempw = geteaw(); - loadseg(tempw, &cpu_state.seg_ss); - if (cpu_state.ssegs) - oldss = ss; -// printf("LOAD SS %04X %04X\n",tempw,SS); -// printf("SS loaded with %04X %04X:%04X %04X %04X %04X\n",ss>>4,cs>>4,pc,CX,DX,es>>4); - 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; - 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; -// printf("0x9a"); - loadcs(tempw2); - writememw(ss, (SP - 2) & 0xFFFF, tempw3); - writememw(ss, (SP - 4) & 0xFFFF, tempw4); - SP -= 4; - cycles -= 36; - FETCHCLEAR(); - break; - case 0x9B: /*WAIT*/ - cycles -= 4; - break; - case 0x9C: /*PUSHF*/ - if (cpu_state.ssegs) - ss = oldss; - writememw(ss, ((SP - 2) & 0xFFFF), cpu_state.flags | 0xF000); - SP -= 2; - cycles -= 14; - break; - case 0x9D: /*POPF*/ - if (cpu_state.ssegs) - ss = oldss; - cpu_state.flags = readmemw(ss, SP) & 0xFFF; - SP += 2; - cycles -= 12; - break; - case 0x9E: /*SAHF*/ - cpu_state.flags = (cpu_state.flags & 0xFF00) | AH; - cycles -= 4; - break; - case 0x9F: /*LAHF*/ - AH = cpu_state.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(); -// printf("Reading AX from %05X %04X:%04X\n",ds+addr,ds>>4,addr); - 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(); -// if (!addr) printf("Write !addr %04X:%04X\n",cs>>4,pc); - writememw(ds, addr, AX); - cycles -= 14; - break; - - case 0xA4: /*MOVSB*/ - temp = readmemb(ds + SI); - writememb(es + DI, temp); - if (cpu_state.flags & D_FLAG) { - DI--; - SI--; - } else { - DI++; - SI++; - } - cycles -= 18; - break; - case 0xA5: /*MOVSW*/ - tempw = readmemw(ds, SI); - writememw(es, DI, tempw); - if (cpu_state.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 (cpu_state.flags & D_FLAG) { - DI--; - SI--; - } else { - DI++; - SI++; - } - cycles -= 30; - break; - case 0xA7: /*CMPSW*/ - tempw = readmemw(ds, SI); - tempw2 = readmemw(es, DI); -// printf("CMPSW %04X %04X\n",tempw,tempw2); - setsub16(tempw, tempw2); - if (cpu_state.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); - cpu_state.flags &= ~(C_FLAG | V_FLAG | A_FLAG); - cycles -= 5; - break; - case 0xA9: /*TEST AX,#16*/ - tempw = getword(); - setznp16(AX & tempw); - cpu_state.flags &= ~(C_FLAG | V_FLAG | A_FLAG); - cycles -= 5; - break; - case 0xAA: /*STOSB*/ - writememb(es + DI, AL); - if (cpu_state.flags & D_FLAG) - DI--; - else - DI++; - cycles -= 11; - break; - case 0xAB: /*STOSW*/ - writememw(es, DI, AX); - if (cpu_state.flags & D_FLAG) - DI -= 2; - else - DI += 2; - cycles -= 11; - break; - case 0xAC: /*LODSB*/ - AL = readmemb(ds + SI); -// printf("LODSB %04X:%04X %02X %04X:%04X\n",cs>>4,pc,AL,ds>>4,SI); - if (cpu_state.flags & D_FLAG) - SI--; - else - SI++; - cycles -= 16; - break; - case 0xAD: /*LODSW*/ -// if (times) printf("LODSW %04X:%04X\n",cs>>4,pc); - AX = readmemw(ds, SI); - if (cpu_state.flags & D_FLAG) - SI -= 2; - else - SI += 2; - cycles -= 16; - break; - case 0xAE: /*SCASB*/ - temp = readmemb(es + DI); - setsub8(AL, temp); - if (cpu_state.flags & D_FLAG) - DI--; - else - DI++; - cycles -= 19; - break; - case 0xAF: /*SCASW*/ - tempw = readmemw(es, DI); - setsub16(AX, tempw); - if (cpu_state.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); -// printf("C2\n"); -// printf("RET to %04X\n",pc); - 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); -// printf("C3\n"); -// if (output) printf("RET to %04X %05X\n",pc,ss+SP); - SP += 2; - cycles -= 20; - FETCHCLEAR(); - break; - case 0xC4: /*LES*/ - fetchea(); - cpu_state.regs[cpu_reg].w = readmemw(easeg, cpu_state.eaaddr); //geteaw(); - tempw = readmemw(easeg, (cpu_state.eaaddr + 2) & 0xFFFF); //geteaw2(); - loadseg(tempw, &cpu_state.seg_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, &cpu_state.seg_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); -// printf("CA\n"); - 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); -// printf("CB\n"); - 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), cpu_state.flags | 0xF000); - writememw(ss, ((SP - 4) & 0xFFFF), CS); - writememw(ss, ((SP - 6) & 0xFFFF), cpu_state.pc); - SP -= 6; - addr = 3 << 2; - cpu_state.flags &= ~I_FLAG; - cpu_state.flags &= ~T_FLAG; -// printf("CC %04X:%04X ",CS,pc); - cpu_state.pc = readmemw(0, addr); - loadcs(readmemw(0, addr + 2)); - FETCHCLEAR(); -// printf("%04X:%04X\n",CS,pc); - cycles -= 72; - break; - case 0xCD: /*INT*/ - temp = FETCH(); - - if (cpu_state.ssegs) - ss = oldss; - writememw(ss, ((SP - 2) & 0xFFFF), cpu_state.flags | 0xF000); - writememw(ss, ((SP - 4) & 0xFFFF), CS); - writememw(ss, ((SP - 6) & 0xFFFF), cpu_state.pc); - cpu_state.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); -// printf("CF\n"); - loadcs(readmemw(ss, ((SP + 2) & 0xFFFF))); - cpu_state.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) - cpu_state.flags |= C_FLAG; - else - cpu_state.flags &= ~C_FLAG; - temp <<= 1; - if (cpu_state.flags & C_FLAG) - temp |= 1; - seteab(temp); -// setznp8(temp); - if ((cpu_state.flags & C_FLAG) ^ (temp >> 7)) - cpu_state.flags |= V_FLAG; - else - cpu_state.flags &= ~V_FLAG; - cycles -= ((cpu_mod == 3) ? 2 : 23); - break; - case 0x08: /*ROR b,1*/ - if (temp & 1) - cpu_state.flags |= C_FLAG; - else - cpu_state.flags &= ~C_FLAG; - temp >>= 1; - if (cpu_state.flags & C_FLAG) - temp |= 0x80; - seteab(temp); -// setznp8(temp); - if ((temp ^ (temp >> 1)) & 0x40) - cpu_state.flags |= V_FLAG; - else - cpu_state.flags &= ~V_FLAG; - cycles -= ((cpu_mod == 3) ? 2 : 23); - break; - case 0x10: /*RCL b,1*/ - temp2 = cpu_state.flags & C_FLAG; - if (temp & 0x80) - cpu_state.flags |= C_FLAG; - else - cpu_state.flags &= ~C_FLAG; - temp <<= 1; - if (temp2) - temp |= 1; - seteab(temp); -// setznp8(temp); - if ((cpu_state.flags & C_FLAG) ^ (temp >> 7)) - cpu_state.flags |= V_FLAG; - else - cpu_state.flags &= ~V_FLAG; - cycles -= ((cpu_mod == 3) ? 2 : 23); - break; - case 0x18: /*RCR b,1*/ - temp2 = cpu_state.flags & C_FLAG; - if (temp & 1) - cpu_state.flags |= C_FLAG; - else - cpu_state.flags &= ~C_FLAG; - temp >>= 1; - if (temp2) - temp |= 0x80; - seteab(temp); -// setznp8(temp); - if ((temp ^ (temp >> 1)) & 0x40) - cpu_state.flags |= V_FLAG; - else - cpu_state.flags &= ~V_FLAG; - cycles -= ((cpu_mod == 3) ? 2 : 23); - break; - case 0x20: - case 0x30: /*SHL b,1*/ - if (temp & 0x80) - cpu_state.flags |= C_FLAG; - else - cpu_state.flags &= ~C_FLAG; - if ((temp ^ (temp << 1)) & 0x80) - cpu_state.flags |= V_FLAG; - else - cpu_state.flags &= ~V_FLAG; - temp <<= 1; - seteab(temp); - setznp8(temp); - cycles -= ((cpu_mod == 3) ? 2 : 23); - cpu_state.flags |= A_FLAG; - break; - case 0x28: /*SHR b,1*/ - if (temp & 1) - cpu_state.flags |= C_FLAG; - else - cpu_state.flags &= ~C_FLAG; - if (temp & 0x80) - cpu_state.flags |= V_FLAG; - else - cpu_state.flags &= ~V_FLAG; - temp >>= 1; - seteab(temp); - setznp8(temp); - cycles -= ((cpu_mod == 3) ? 2 : 23); - cpu_state.flags |= A_FLAG; - break; - case 0x38: /*SAR b,1*/ - if (temp & 1) - cpu_state.flags |= C_FLAG; - else - cpu_state.flags &= ~C_FLAG; - temp >>= 1; - if (temp & 0x40) - temp |= 0x80; - seteab(temp); - setznp8(temp); - cycles -= ((cpu_mod == 3) ? 2 : 23); - cpu_state.flags |= A_FLAG; - cpu_state.flags &= ~V_FLAG; - break; - -// default: -// printf("Bad D0 opcode %02X\n",rmdat&0x38); -// dumpregs(); -// exit(-1); - } - break; - - case 0xD1: fetchea(); - tempw = geteaw(); - switch (rmdat & 0x38) { - case 0x00: /*ROL w,1*/ - if (tempw & 0x8000) - cpu_state.flags |= C_FLAG; - else - cpu_state.flags &= ~C_FLAG; - tempw <<= 1; - if (cpu_state.flags & C_FLAG) - tempw |= 1; - seteaw(tempw); -// setznp16(tempw); - if ((cpu_state.flags & C_FLAG) ^ (tempw >> 15)) - cpu_state.flags |= V_FLAG; - else - cpu_state.flags &= ~V_FLAG; - cycles -= ((cpu_mod == 3) ? 2 : 23); - break; - case 0x08: /*ROR w,1*/ - if (tempw & 1) - cpu_state.flags |= C_FLAG; - else - cpu_state.flags &= ~C_FLAG; - tempw >>= 1; - if (cpu_state.flags & C_FLAG) - tempw |= 0x8000; - seteaw(tempw); -// setznp16(tempw); - if ((tempw ^ (tempw >> 1)) & 0x4000) - cpu_state.flags |= V_FLAG; - else - cpu_state.flags &= ~V_FLAG; - cycles -= ((cpu_mod == 3) ? 2 : 23); - break; - case 0x10: /*RCL w,1*/ - temp2 = cpu_state.flags & C_FLAG; - if (tempw & 0x8000) - cpu_state.flags |= C_FLAG; - else - cpu_state.flags &= ~C_FLAG; - tempw <<= 1; - if (temp2) - tempw |= 1; - seteaw(tempw); - if ((cpu_state.flags & C_FLAG) ^ (tempw >> 15)) - cpu_state.flags |= V_FLAG; - else - cpu_state.flags &= ~V_FLAG; - cycles -= ((cpu_mod == 3) ? 2 : 23); - break; - case 0x18: /*RCR w,1*/ - temp2 = cpu_state.flags & C_FLAG; - if (tempw & 1) - cpu_state.flags |= C_FLAG; - else - cpu_state.flags &= ~C_FLAG; - tempw >>= 1; - if (temp2) - tempw |= 0x8000; - seteaw(tempw); -// setznp16(tempw); - if ((tempw ^ (tempw >> 1)) & 0x4000) - cpu_state.flags |= V_FLAG; - else - cpu_state.flags &= ~V_FLAG; - cycles -= ((cpu_mod == 3) ? 2 : 23); - break; - case 0x20: - case 0x30: /*SHL w,1*/ - if (tempw & 0x8000) - cpu_state.flags |= C_FLAG; - else - cpu_state.flags &= ~C_FLAG; - if ((tempw ^ (tempw << 1)) & 0x8000) - cpu_state.flags |= V_FLAG; - else - cpu_state.flags &= ~V_FLAG; - tempw <<= 1; - seteaw(tempw); - setznp16(tempw); - cycles -= ((cpu_mod == 3) ? 2 : 23); - cpu_state.flags |= A_FLAG; - break; - case 0x28: /*SHR w,1*/ - if (tempw & 1) - cpu_state.flags |= C_FLAG; - else - cpu_state.flags &= ~C_FLAG; - if (tempw & 0x8000) - cpu_state.flags |= V_FLAG; - else - cpu_state.flags &= ~V_FLAG; - tempw >>= 1; - seteaw(tempw); - setznp16(tempw); - cycles -= ((cpu_mod == 3) ? 2 : 23); - cpu_state.flags |= A_FLAG; - break; - - case 0x38: /*SAR w,1*/ - if (tempw & 1) - cpu_state.flags |= C_FLAG; - else - cpu_state.flags &= ~C_FLAG; - tempw >>= 1; - if (tempw & 0x4000) - tempw |= 0x8000; - seteaw(tempw); - setznp16(tempw); - cycles -= ((cpu_mod == 3) ? 2 : 23); - cpu_state.flags |= A_FLAG; - cpu_state.flags &= ~V_FLAG; - break; - -// default: -// printf("Bad D1 opcode %02X\n",rmdat&0x38); -// dumpregs(); -// exit(-1); - } - break; - - case 0xD2: fetchea(); - temp = geteab(); - c = CL; -// cycles-=c; - if (!c) - break; -// if (c>7) printf("Shiftb %i %02X\n",rmdat&0x38,c); - switch (rmdat & 0x38) { - case 0x00: /*ROL b,CL*/ - while (c > 0) { - temp2 = (temp & 0x80) ? 1 : 0; - temp = (temp << 1) | temp2; - c--; - cycles -= 4; - } - if (temp2) - cpu_state.flags |= C_FLAG; - else - cpu_state.flags &= ~C_FLAG; - seteab(temp); -// setznp8(temp); - if ((cpu_state.flags & C_FLAG) ^ (temp >> 7)) - cpu_state.flags |= V_FLAG; - else - cpu_state.flags &= ~V_FLAG; - cycles -= ((cpu_mod == 3) ? 8 : 28); - break; - case 0x08: /*ROR b,CL*/ - while (c > 0) { - temp2 = temp & 1; - temp >>= 1; - if (temp2) - temp |= 0x80; - c--; - cycles -= 4; - } - if (temp2) - cpu_state.flags |= C_FLAG; - else - cpu_state.flags &= ~C_FLAG; - seteab(temp); - if ((temp ^ (temp >> 1)) & 0x40) - cpu_state.flags |= V_FLAG; - else - cpu_state.flags &= ~V_FLAG; - cycles -= ((cpu_mod == 3) ? 8 : 28); - break; - case 0x10: /*RCL b,CL*/ -// printf("RCL %i %02X %02X\n",c,CL,temp); - while (c > 0) { - templ = cpu_state.flags & C_FLAG; - temp2 = temp & 0x80; - temp <<= 1; - if (temp2) - cpu_state.flags |= C_FLAG; - else - cpu_state.flags &= ~C_FLAG; - if (templ) - temp |= 1; - c--; - cycles -= 4; - } -// printf("Now %02X\n",temp); - seteab(temp); - if ((cpu_state.flags & C_FLAG) ^ (temp >> 7)) - cpu_state.flags |= V_FLAG; - else - cpu_state.flags &= ~V_FLAG; - cycles -= ((cpu_mod == 3) ? 8 : 28); - break; - case 0x18: /*RCR b,CL*/ - while (c > 0) { - templ = cpu_state.flags & C_FLAG; - temp2 = temp & 1; - temp >>= 1; - if (temp2) - cpu_state.flags |= C_FLAG; - else - cpu_state.flags &= ~C_FLAG; - if (templ) - temp |= 0x80; - c--; - cycles -= 4; - } -// if (temp2) flags|=C_FLAG; -// else flags&=~C_FLAG; - seteab(temp); - if ((temp ^ (temp >> 1)) & 0x40) - cpu_state.flags |= V_FLAG; - else - cpu_state.flags &= ~V_FLAG; - cycles -= ((cpu_mod == 3) ? 8 : 28); - break; - case 0x20: - case 0x30: /*SHL b,CL*/ - if (c > 8) { - temp = 0; - cpu_state.flags &= ~C_FLAG; - } else { - if ((temp << (c - 1)) & 0x80) - cpu_state.flags |= C_FLAG; - else - cpu_state.flags &= ~C_FLAG; - temp <<= c; - } - seteab(temp); - setznp8(temp); - cycles -= (c * 4); - cycles -= ((cpu_mod == 3) ? 8 : 28); - cpu_state.flags |= A_FLAG; - break; - case 0x28: /*SHR b,CL*/ - if (c > 8) { - temp = 0; - cpu_state.flags &= ~C_FLAG; - } else { - if ((temp >> (c - 1)) & 1) - cpu_state.flags |= C_FLAG; - else - cpu_state.flags &= ~C_FLAG; - temp >>= c; - } - seteab(temp); - setznp8(temp); - cycles -= (c * 4); - cycles -= ((cpu_mod == 3) ? 8 : 28); - cpu_state.flags |= A_FLAG; - break; - case 0x38: /*SAR b,CL*/ - if ((temp >> (c - 1)) & 1) - cpu_state.flags |= C_FLAG; - else - cpu_state.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); - cpu_state.flags |= A_FLAG; - break; - -// default: -// printf("Bad D2 opcode %02X\n",rmdat&0x38); -// dumpregs(); -// exit(-1); - } - break; - - case 0xD3: fetchea(); - tempw = geteaw(); - c = CL; -// cycles-=c; - if (!c) - break; -// if (c>15) printf("Shiftw %i %02X\n",rmdat&0x38,c); - 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) - cpu_state.flags |= C_FLAG; - else - cpu_state.flags &= ~C_FLAG; - seteaw(tempw); - if ((cpu_state.flags & C_FLAG) ^ (tempw >> 15)) - cpu_state.flags |= V_FLAG; - else - cpu_state.flags &= ~V_FLAG; - cycles -= ((cpu_mod == 3) ? 8 : 28); - break; - case 0x08: /*ROR w,CL*/ - while (c > 0) { - tempw2 = (tempw & 1) ? 0x8000 : 0; - tempw = (tempw >> 1) | tempw2; - c--; - cycles -= 4; - } - if (tempw2) - cpu_state.flags |= C_FLAG; - else - cpu_state.flags &= ~C_FLAG; - seteaw(tempw); - if ((tempw ^ (tempw >> 1)) & 0x4000) - cpu_state.flags |= V_FLAG; - else - cpu_state.flags &= ~V_FLAG; - cycles -= ((cpu_mod == 3) ? 8 : 28); - break; - case 0x10: /*RCL w,CL*/ - while (c > 0) { - templ = cpu_state.flags & C_FLAG; - if (tempw & 0x8000) - cpu_state.flags |= C_FLAG; - else - cpu_state.flags &= ~C_FLAG; - tempw = (tempw << 1) | templ; - c--; - cycles -= 4; - } - if (templ) - cpu_state.flags |= C_FLAG; - else - cpu_state.flags &= ~C_FLAG; - seteaw(tempw); - if ((cpu_state.flags & C_FLAG) ^ (tempw >> 15)) - cpu_state.flags |= V_FLAG; - else - cpu_state.flags &= ~V_FLAG; - cycles -= ((cpu_mod == 3) ? 8 : 28); - break; - case 0x18: /*RCR w,CL*/ - while (c > 0) { - templ = cpu_state.flags & C_FLAG; - tempw2 = (templ & 1) ? 0x8000 : 0; - if (tempw & 1) - cpu_state.flags |= C_FLAG; - else - cpu_state.flags &= ~C_FLAG; - tempw = (tempw >> 1) | tempw2; - c--; - cycles -= 4; - } - if (tempw2) - cpu_state.flags |= C_FLAG; - else - cpu_state.flags &= ~C_FLAG; - seteaw(tempw); - if ((tempw ^ (tempw >> 1)) & 0x4000) - cpu_state.flags |= V_FLAG; - else - cpu_state.flags &= ~V_FLAG; - cycles -= ((cpu_mod == 3) ? 8 : 28); - break; - - case 0x20: - case 0x30: /*SHL w,CL*/ - if (c > 16) { - tempw = 0; - cpu_state.flags &= ~C_FLAG; - } else { - if ((tempw << (c - 1)) & 0x8000) - cpu_state.flags |= C_FLAG; - else - cpu_state.flags &= ~C_FLAG; - tempw <<= c; - } - seteaw(tempw); - setznp16(tempw); - cycles -= (c * 4); - cycles -= ((cpu_mod == 3) ? 8 : 28); - cpu_state.flags |= A_FLAG; - break; - - case 0x28: /*SHR w,CL*/ - if (c > 16) { - tempw = 0; - cpu_state.flags &= ~C_FLAG; - } else { - if ((tempw >> (c - 1)) & 1) - cpu_state.flags |= C_FLAG; - else - cpu_state.flags &= ~C_FLAG; - tempw >>= c; - } - seteaw(tempw); - setznp16(tempw); - cycles -= (c * 4); - cycles -= ((cpu_mod == 3) ? 8 : 28); - cpu_state.flags |= A_FLAG; - break; - - case 0x38: /*SAR w,CL*/ - tempw2 = tempw & 0x8000; - if ((tempw >> (c - 1)) & 1) - cpu_state.flags |= C_FLAG; - else - cpu_state.flags &= ~C_FLAG; - while (c > 0) { - tempw = (tempw >> 1) | tempw2; - c--; - cycles -= 4; - } - seteaw(tempw); - setznp16(tempw); - cycles -= ((cpu_mod == 3) ? 8 : 28); - cpu_state.flags |= A_FLAG; - break; - -// default: -// printf("Bad D3 opcode %02X\n",rmdat&0x38); -// dumpregs(); -// exit(-1); - } - 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 = (cpu_state.flags & C_FLAG) ? 0xff : 0; - cycles -= 4; - break; - case 0xD7: /*XLAT*/ - addr = BX + AL; - AL = readmemb(ds + addr); - cycles -= 11; - break; - - case 0xd8: fetchea(); - if (hasfpu) { - uint16_t save_pc = cpu_state.pc; - ops_808x_fpu_d8_a16[rmdat >> 3](rmdat); - cpu_state.pc = save_pc; - } - break; - case 0xd9: fetchea(); - if (hasfpu) { - uint16_t save_pc = cpu_state.pc; - ops_808x_fpu_d9_a16[rmdat](rmdat); - cpu_state.pc = save_pc; - } - break; - case 0xda: fetchea(); - if (hasfpu) { - uint16_t save_pc = cpu_state.pc; - ops_808x_fpu_da_a16[rmdat](rmdat); - cpu_state.pc = save_pc; - } - break; - case 0xdb: fetchea(); - if (hasfpu) { - uint16_t save_pc = cpu_state.pc; - ops_808x_fpu_db_a16[rmdat](rmdat); - cpu_state.pc = save_pc; - } - break; - case 0xdc: fetchea(); - if (hasfpu) { - uint16_t save_pc = cpu_state.pc; - ops_808x_fpu_dc_a16[rmdat >> 3](rmdat); - cpu_state.pc = save_pc; - } - break; - case 0xdd: fetchea(); - if (hasfpu) { - uint16_t save_pc = cpu_state.pc; - ops_808x_fpu_dd_a16[rmdat](rmdat); - cpu_state.pc = save_pc; - } - break; - case 0xde: fetchea(); - if (hasfpu) { - uint16_t save_pc = cpu_state.pc; - ops_808x_fpu_de_a16[rmdat](rmdat); - cpu_state.pc = save_pc; - } - break; - case 0xdf: fetchea(); - if (hasfpu) { - uint16_t save_pc = cpu_state.pc; - ops_808x_fpu_df_a16[rmdat](rmdat); - cpu_state.pc = save_pc; - } - break; - - case 0xE0: /*LOOPNE*/ - offset = (int8_t)FETCH(); - CX--; - if (CX && !(cpu_state.flags & Z_FLAG)) { - cpu_state.pc += offset; - cycles -= 12; - FETCHCLEAR(); - } - cycles -= 6; - break; - case 0xE1: /*LOOPE*/ - offset = (int8_t)FETCH(); - CX--; - if (CX && (cpu_state.flags & Z_FLAG)) { - cpu_state.pc += offset; - cycles -= 12; - FETCHCLEAR(); - } - cycles -= 6; - break; - case 0xE2: /*LOOP*/ -// printf("LOOP start\n"); - offset = (int8_t)FETCH(); - CX--; - if (CX) { - cpu_state.pc += offset; - cycles -= 12; - FETCHCLEAR(); - } - cycles -= 5; -// printf("LOOP end!\n"); - 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; -// writememb(ss+((SP-1)&0xFFFF),pc>>8); - writememw(ss, ((SP - 2) & 0xFFFF), cpu_state.pc); - SP -= 2; - cpu_state.pc += tempw; - cycles -= 23; - FETCHCLEAR(); - break; - case 0xE9: /*JMP rel 16*/ -// pclog("PC was %04X\n",cpu_state.pc); - tempw = getword(); - cpu_state.pc += tempw; -// pclog("PC now %04X\n",cpu_state.pc); - cycles -= 15; - FETCHCLEAR(); - break; - case 0xEA: /*JMP far*/ - addr = getword(); - tempw = getword(); - cpu_state.pc = addr; -// printf("EA\n"); - loadcs(tempw); -// cs=loadcs(CS); -// cs=CS<<4; - 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*/ -// printf("IN HLT!!!! %04X %08X %08X %08X\n",oldpc,old8,old82,old83); -/* if (!(flags & I_FLAG)) - { - pclog("HLT\n"); - dumpregs(); - exit(-1); - }*/ - inhlt = 1; - cpu_state.pc--; - FETCHCLEAR(); - cycles -= 2; - break; - case 0xF5: /*CMC*/ - cpu_state.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); - cpu_state.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) - cpu_state.flags &= ~Z_FLAG; - else - cpu_state.flags |= Z_FLAG; - if (AH) - cpu_state.flags |= (C_FLAG | V_FLAG); - else - cpu_state.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) - cpu_state.flags &= ~Z_FLAG; - else - cpu_state.flags |= Z_FLAG; - if (AH) - cpu_state.flags |= (C_FLAG | V_FLAG); - else - cpu_state.flags &= ~(C_FLAG | V_FLAG); - cycles -= 80; - break; - case 0x30: /*DIV AL,b*/ - tempw = AX; - if (temp) { - tempw2 = tempw % temp; -/* if (!tempw) - { - writememw((ss+SP)-2,flags|0xF000); - writememw((ss+SP)-4,cs>>4); - writememw((ss+SP)-6,pc); - SP-=6; - flags&=~I_FLAG; - pc=readmemw(0); - cs=readmemw(2)<<4; - printf("Div by zero %04X:%04X\n",cs>>4,pc); -// dumpregs(); -// exit(-1); - } - else - {*/ - AH = tempw2; - tempw /= temp; - AL = tempw & 0xFF; -// } - } else { - printf("DIVb BY 0 %04X:%04X\n", cs >> 4, cpu_state.pc); - writememw(ss, (SP - 2) & 0xFFFF, cpu_state.flags | 0xF000); - writememw(ss, (SP - 4) & 0xFFFF, CS); - writememw(ss, (SP - 6) & 0xFFFF, cpu_state.pc); - SP -= 6; - cpu_state.flags &= ~I_FLAG; - cpu_state.flags &= ~T_FLAG; - cpu_state.pc = readmemw(0, 0); -// printf("F6 30\n"); - loadcs(readmemw(0, 2)); - FETCHCLEAR(); -// cs=loadcs(CS); -// cs=CS<<4; -// printf("Div by zero %04X:%04X %02X %02X\n",cs>>4,pc,0xf6,0x30); -// dumpregs(); -// exit(-1); - } - cycles -= 80; - break; - case 0x38: /*IDIV AL,b*/ - tempws = (int)AX; - if (temp) { - tempw2 = tempws % (int)((int8_t)temp); -/* if (!tempw) - { - writememw((ss+SP)-2,flags|0xF000); - writememw((ss+SP)-4,cs>>4); - writememw((ss+SP)-6,pc); - SP-=6; - flags&=~I_FLAG; - pc=readmemw(0); - cs=readmemw(2)<<4; - printf("Div by zero %04X:%04X\n",cs>>4,pc); - } - else - {*/ - AH = tempw2 & 0xFF; - tempws /= (int)((int8_t)temp); - AL = tempws & 0xFF; -// } - } else { - printf("IDIVb BY 0 %04X:%04X\n", cs >> 4, cpu_state.pc); - writememw(ss, (SP - 2) & 0xFFFF, cpu_state.flags | 0xF000); - writememw(ss, (SP - 4) & 0xFFFF, CS); - writememw(ss, (SP - 6) & 0xFFFF, cpu_state.pc); - SP -= 6; - cpu_state.flags &= ~I_FLAG; - cpu_state.flags &= ~T_FLAG; - cpu_state.pc = readmemw(0, 0); -// printf("F6 38\n"); - loadcs(readmemw(0, 2)); - FETCHCLEAR(); -// cs=loadcs(CS); -// cs=CS<<4; -// printf("Div by zero %04X:%04X %02X %02X\n",cs>>4,pc,0xf6,0x38); - } - cycles -= 101; - break; - -// default: -// printf("Bad F6 opcode %02X\n",rmdat&0x38); -// dumpregs(); -// exit(-1); - } - break; - - case 0xF7: fetchea(); - tempw = geteaw(); - switch (rmdat & 0x38) { - case 0x00: /*TEST w*/ - case 0x08:tempw2 = getword(); - setznp16(tempw & tempw2); - cpu_state.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; -// if (output) printf("%04X*%04X=%08X\n",AX,tempw,templ); - AX = templ & 0xFFFF; - DX = templ >> 16; - if (AX | DX) - cpu_state.flags &= ~Z_FLAG; - else - cpu_state.flags |= Z_FLAG; - if (DX) - cpu_state.flags |= (C_FLAG | V_FLAG); - else - cpu_state.flags &= ~(C_FLAG | V_FLAG); - cycles -= 118; - break; - case 0x28: /*IMUL AX,w*/ - setznp16(AX); -// printf("IMUL %i %i ",(int)((int16_t)AX),(int)((int16_t)tempw)); - tempws = (int)((int16_t)AX) * (int)((int16_t)tempw); - if ((tempws >> 15) && ((tempws >> 15) != -1)) - cpu_state.flags |= (C_FLAG | V_FLAG); - else - cpu_state.flags &= ~(C_FLAG | V_FLAG); -// printf("%i ",tempws); - AX = tempws & 0xFFFF; - tempws = (uint16_t)(tempws >> 16); - DX = tempws & 0xFFFF; -// printf("%04X %04X\n",AX,DX); -// dumpregs(); -// exit(-1); - if (AX | DX) - cpu_state.flags &= ~Z_FLAG; - else - cpu_state.flags |= Z_FLAG; - cycles -= 128; - break; - case 0x30: /*DIV AX,w*/ - templ = (DX << 16) | AX; -// printf("DIV %08X/%04X\n",templ,tempw); - if (tempw) { - tempw2 = templ % tempw; - DX = tempw2; - templ /= tempw; - AX = templ & 0xFFFF; - } else { - printf("DIVw BY 0 %04X:%04X\n", cs >> 4, cpu_state.pc); - writememw(ss, (SP - 2) & 0xFFFF, cpu_state.flags | 0xF000); - writememw(ss, (SP - 4) & 0xFFFF, CS); - writememw(ss, (SP - 6) & 0xFFFF, cpu_state.pc); - SP -= 6; - cpu_state.flags &= ~I_FLAG; - cpu_state.flags &= ~T_FLAG; - cpu_state.pc = readmemw(0, 0); -// printf("F7 30\n"); - loadcs(readmemw(0, 2)); - FETCHCLEAR(); - } - cycles -= 144; - break; - case 0x38: /*IDIV AX,w*/ - tempws = (int)((DX << 16) | AX); -// printf("IDIV %i %i ",tempws,tempw); - if (tempw) { - tempw2 = tempws % (int)((int16_t)tempw); -// printf("%04X ",tempw2); - DX = tempw2; - tempws /= (int)((int16_t)tempw); - AX = tempws & 0xFFFF; - } else { - printf("IDIVw BY 0 %04X:%04X\n", cs >> 4, cpu_state.pc); - writememw(ss, (SP - 2) & 0xFFFF, cpu_state.flags | 0xF000); - writememw(ss, (SP - 4) & 0xFFFF, CS); - writememw(ss, (SP - 6) & 0xFFFF, cpu_state.pc); - SP -= 6; - cpu_state.flags &= ~I_FLAG; - cpu_state.flags &= ~T_FLAG; - cpu_state.pc = readmemw(0, 0); -// printf("F7 38\n"); - loadcs(readmemw(0, 2)); - FETCHCLEAR(); - } - cycles -= 165; - break; - -// default: -// printf("Bad F7 opcode %02X\n",rmdat&0x38); -// dumpregs(); -// exit(-1); - } - break; - - case 0xF8: /*CLC*/ - cpu_state.flags &= ~C_FLAG; - cycles -= 2; - break; - case 0xF9: /*STC*/ -// printf("STC %04X\n",pc); - cpu_state.flags |= C_FLAG; - cycles -= 2; - break; - case 0xFA: /*CLI*/ - cpu_state.flags &= ~I_FLAG; -// printf("CLI at %04X:%04X\n",cs>>4,pc); - cycles -= 3; - break; - case 0xFB: /*STI*/ - cpu_state.flags |= I_FLAG; -// printf("STI at %04X:%04X\n",cs>>4,pc); - cycles -= 2; - break; - case 0xFC: /*CLD*/ - cpu_state.flags &= ~D_FLAG; - cycles -= 2; - break; - case 0xFD: /*STD*/ - cpu_state.flags |= D_FLAG; - cycles -= 2; - break; - - case 0xFE: /*INC/DEC b*/ - fetchea(); - temp = geteab(); - cpu_state.flags &= ~V_FLAG; - if (rmdat & 0x38) { - setsub8nc(temp, 1); - temp2 = temp - 1; - if ((temp & 0x80) && !(temp2 & 0x80)) - cpu_state.flags |= V_FLAG; - } else { - setadd8nc(temp, 1); - temp2 = temp + 1; - if ((temp2 & 0x80) && !(temp & 0x80)) - cpu_state.flags |= V_FLAG; - } -// setznp8(temp2); - seteab(temp2); - cycles -= ((cpu_mod == 3) ? 3 : 23); - break; - - case 0xFF: fetchea(); - switch (rmdat & 0x38) { - case 0x00: /*INC w*/ - tempw = geteaw(); - setadd16nc(tempw, 1); -// setznp16(tempw+1); - seteaw(tempw + 1); - cycles -= ((cpu_mod == 3) ? 3 : 23); - break; - case 0x08: /*DEC w*/ - tempw = geteaw(); -// setsub16(tempw,1); - setsub16nc(tempw, 1); -// setznp16(tempw-1); - seteaw(tempw - 1); -// if (output) printf("DEC - %04X\n",tempw); - 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.pc = tempw; -// printf("FF 10\n"); - 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); //geteaw2(); - tempw3 = CS; - tempw4 = cpu_state.pc; - if (cpu_state.ssegs) - ss = oldss; - cpu_state.pc = tempw; -// printf("FF 18\n"); - loadcs(tempw2); - writememw(ss, (SP - 2) & 0xFFFF, tempw3); - writememw(ss, ((SP - 4) & 0xFFFF), tempw4); - SP -= 4; - cycles -= 53; - FETCHCLEAR(); - break; - case 0x20: /*JMP*/ - cpu_state.pc = geteaw(); -// printf("FF 20\n"); - cycles -= ((cpu_mod == 3) ? 11 : 18); - FETCHCLEAR(); - break; - case 0x28: /*JMP far*/ - cpu_state.pc = readmemw(easeg, cpu_state.eaaddr); //geteaw(); -// printf("FF 28\n"); - loadcs(readmemw(easeg, (cpu_state.eaaddr + 2) & 0xFFFF)); //geteaw2(); -// cs=loadcs(CS); -// cs=CS<<4; - cycles -= 24; - FETCHCLEAR(); - break; - case 0x30: /*PUSH w*/ - tempw = geteaw(); -// if (output) printf("PUSH %04X %i %02X %04X %04X %02X %02X\n",tempw,cpu_rm,rmdat,easeg,eaaddr,ram[0x22340+0x5638],ram[0x22340+0x5639]); - if (cpu_state.ssegs) - ss = oldss; - writememw(ss, ((SP - 2) & 0xFFFF), tempw); - SP -= 2; - cycles -= ((cpu_mod == 3) ? 15 : 24); - break; - -// default: -// printf("Bad FF opcode %02X\n",rmdat&0x38); -// dumpregs(); -// exit(-1); - } - break; - - default:FETCH(); - cycles -= 8; - break; - -/* printf("Bad opcode %02X at %04X:%04X from %04X:%04X %08X\n",opcode,cs>>4,pc,old8>>16,old8&0xFFFF,old82); - dumpregs(); - exit(-1);*/ - } - cpu_state.pc &= 0xFFFF; - -/* if ((CS & 0xf000) == 0xa000) - { - dumpregs(); - exit(-1); - }*/ -// output = 3; -/* if (CS == 0xf000) - { - dumpregs(); - exit(-1); + uint8_t temp, temp2; + uint16_t addr, tempw, tempw2, tempw3, tempw4; + int8_t offset; + int tempws; + uint32_t templ; + int c; + int tempi; + int trap; + + // printf("Run x86! %i %i\n",cycles,cycs); + cycles += cycs; + // i86_Execute(cycs); + // return; + while (cycles > 0) { + uint8_t opcode; + + cycdiff = cycles; + current_diff = 0; + cycles -= nextcyc; + // if (instime) pclog("Cycles %i %i\n",cycles,cycdiff); + nextcyc = 0; + // if (output) printf("CLOCK %i %i\n",cycdiff,cycles); + fetchclocks = 0; + cpu_state.oldpc = cpu_state.pc; + opcodestart: + opcode = FETCH(); + tempc = cpu_state.flags & C_FLAG; + trap = cpu_state.flags & T_FLAG; + cpu_state.pc--; + // output=1; + // if (output) printf("%04X:%04X : %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %02X + // %04X\n",cs>>4,pc,AX,BX,CX,DX,cs>>4,ds>>4,es>>4,ss>>4,DI,SI,BP,SP,opcode,flags&~0x200,rmdat); + //#if 0 + if (output) { + // if ((opcode!=0xF2 && opcode!=0xF3) || firstrepcycle) + // { + if (!skipnextprint) + printf("%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, cpu_state.flags, + ins, ram, ram[0x1a925]); + skipnextprint = 0; + // ins++; + // } } - output = 3;*/ - if (cpu_state.ssegs) { - ds = oldds; - ss = oldss; - cpu_state.ssegs = 0; - } + //#endif + cpu_state.pc++; + inhlt = 0; + // if (ins==500000) { dumpregs(); exit(0); }*/ + switch (opcode) { + case 0x00: /*ADD 8,reg*/ + fetchea(); + /* if (!rmdat) pc--; + if (!rmdat) + { + fatal("Crashed\n"); + // clear_keybuf(); + // readkey(); + }*/ + 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; -// output = 3; - // if (instime) printf("%i %i %i %i\n",cycdiff,cycles,memcycs,fetchclocks); - FETCHADD(((cycdiff - cycles) - memcycs) - fetchclocks); - if ((cycdiff - cycles) < memcycs) - cycles -= (memcycs - (cycdiff - cycles)); - memcycs = 0; + case 0x06: /*PUSH ES*/ + if (cpu_state.ssegs) + ss = oldss; + writememw(ss, ((SP - 2) & 0xFFFF), ES); + SP -= 2; + cycles -= 14; + break; + case 0x07: /*POP ES*/ + if (cpu_state.ssegs) + ss = oldss; + tempw = readmemw(ss, SP); + loadseg(tempw, &cpu_state.seg_es); + SP += 2; + cycles -= 12; + break; - insc++; -// output=(CS==0xEB9); - clockhardware(); + case 0x08: /*OR 8,reg*/ + fetchea(); + temp = geteab(); + temp |= getr8(cpu_reg); + setznp8(temp); + cpu_state.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); + cpu_state.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); + cpu_state.flags &= ~(C_FLAG | V_FLAG | A_FLAG); + setr8(cpu_reg, temp); + cycles -= ((cpu_mod == 3) ? 3 : 13); + break; + case 0x0B: /*OR cpu_reg,16*/ + fetchea(); + tempw = geteaw(); + tempw |= cpu_state.regs[cpu_reg].w; + setznp16(tempw); + cpu_state.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); + cpu_state.flags &= ~(C_FLAG | V_FLAG | A_FLAG); + cycles -= 4; + break; + case 0x0D: /*OR AX,#16*/ + AX |= getword(); + setznp16(AX); + cpu_state.flags &= ~(C_FLAG | V_FLAG | A_FLAG); + cycles -= 4; + break; - if (trap && (cpu_state.flags & T_FLAG) && !noint) { -// printf("TRAP!!! %04X:%04X\n",CS,pc); - writememw(ss, (SP - 2) & 0xFFFF, cpu_state.flags | 0xF000); - writememw(ss, (SP - 4) & 0xFFFF, CS); - writememw(ss, (SP - 6) & 0xFFFF, cpu_state.pc); - SP -= 6; - addr = 1 << 2; - cpu_state.flags &= ~I_FLAG; - cpu_state.flags &= ~T_FLAG; - cpu_state.pc = readmemw(0, addr); - loadcs(readmemw(0, addr + 2)); - FETCHCLEAR(); - } else if (nmi && nmi_enable && nmi_mask) { -// output = 3; - writememw(ss, (SP - 2) & 0xFFFF, cpu_state.flags | 0xF000); - writememw(ss, (SP - 4) & 0xFFFF, CS); - writememw(ss, (SP - 6) & 0xFFFF, cpu_state.pc); - SP -= 6; - addr = 2 << 2; - cpu_state.flags &= ~I_FLAG; - cpu_state.flags &= ~T_FLAG; - cpu_state.pc = readmemw(0, addr); - loadcs(readmemw(0, addr + 2)); - FETCHCLEAR(); - nmi_enable = 0; - } else if (takeint && !cpu_state.ssegs && !noint) { - temp = picinterrupt(); - if (temp != 0xFF) { - if (inhlt) - cpu_state.pc++; - writememw(ss, (SP - 2) & 0xFFFF, cpu_state.flags | 0xF000); - writememw(ss, (SP - 4) & 0xFFFF, CS); - writememw(ss, (SP - 6) & 0xFFFF, cpu_state.pc); - SP -= 6; - addr = temp << 2; - cpu_state.flags &= ~I_FLAG; - cpu_state.flags &= ~T_FLAG; - cpu_state.pc = readmemw(0, addr); -// printf("INT INT INT\n"); - loadcs(readmemw(0, addr + 2)); - FETCHCLEAR(); -// printf("INTERRUPT\n"); - } - } - takeint = (cpu_state.flags & I_FLAG) && (pic.pend & ~pic.mask); + case 0x0E: /*PUSH CS*/ + if (cpu_state.ssegs) + ss = oldss; + writememw(ss, ((SP - 2) & 0xFFFF), CS); + SP -= 2; + cycles -= 14; + break; + case 0x0F: /*POP CS - 8088/8086 only*/ + if (cpu_state.ssegs) + ss = oldss; + tempw = readmemw(ss, SP); + loadseg(tempw, &cpu_state.seg_cs); + SP += 2; + cycles -= 12; + break; - if (noint) - noint = 0; - ins++; -/* if (timetolive) - { - timetolive--; - if (!timetolive) exit(-1); //output=0; - }*/ - } + 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); + 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; + break; + case 0x17: /*POP SS*/ + if (cpu_state.ssegs) + ss = oldss; + tempw = readmemw(ss, SP); + loadseg(tempw, &cpu_state.seg_ss); + SP += 2; + noint = 1; + cycles -= 12; + // output=1; + 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; + // printf("%04X:%04X SBB %04X-%04X,%i\n",cs>>4,pc,tempw,tempw2,tempc); + 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; + // printf("%04X:%04X SBB %04X-%04X,%i\n",cs>>4,pc,tempw,tempw2,tempc); + 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; + cycles -= 14; + break; + case 0x1F: /*POP DS*/ + if (cpu_state.ssegs) + ss = oldss; + tempw = readmemw(ss, SP); + loadseg(tempw, &cpu_state.seg_ds); + if (cpu_state.ssegs) + oldds = ds; + SP += 2; + cycles -= 12; + break; + + case 0x20: /*AND 8,reg*/ + fetchea(); + temp = geteab(); + temp &= getr8(cpu_reg); + setznp8(temp); + cpu_state.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); + cpu_state.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); + cpu_state.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); + cpu_state.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); + cpu_state.flags &= ~(C_FLAG | V_FLAG | A_FLAG); + cycles -= 4; + break; + case 0x25: /*AND AX,#16*/ + AX &= getword(); + setznp16(AX); + cpu_state.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; + // break; + + case 0x27: /*DAA*/ + if ((cpu_state.flags & A_FLAG) || ((AL & 0xF) > 9)) { + tempi = ((uint16_t)AL) + 6; + AL += 6; + cpu_state.flags |= A_FLAG; + if (tempi & 0x100) + cpu_state.flags |= C_FLAG; + } + // else + // flags&=~A_FLAG; + if ((cpu_state.flags & C_FLAG) || (AL > 0x9F)) { + AL += 0x60; + cpu_state.flags |= C_FLAG; + } + // else + // 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(); + // printf("%04X:%04X %04X-%04X\n",cs>>4,pc,tempw,cpu_state.regs[cpu_reg].w); + 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(); + // printf("%04X:%04X %04X-%04X\n",cs>>4,pc,cpu_state.regs[cpu_reg].w,tempw); + 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*/ + // printf("INS %i\n",ins); + // output=1; + 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 ((cpu_state.flags & A_FLAG) || ((AL & 0xF) > 9)) { + tempi = ((uint16_t)AL) - 6; + AL -= 6; + cpu_state.flags |= A_FLAG; + if (tempi & 0x100) + cpu_state.flags |= C_FLAG; + } + // else + // flags&=~A_FLAG; + if ((cpu_state.flags & C_FLAG) || (AL > 0x9F)) { + AL -= 0x60; + cpu_state.flags |= C_FLAG; + } + // else + // flags&=~C_FLAG; + setznp8(AL); + cycles -= 4; + break; + case 0x30: /*XOR 8,reg*/ + fetchea(); + temp = geteab(); + temp ^= getr8(cpu_reg); + setznp8(temp); + cpu_state.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); + cpu_state.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); + cpu_state.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); + cpu_state.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); + cpu_state.flags &= ~(C_FLAG | V_FLAG | A_FLAG); + cycles -= 4; + break; + case 0x35: /*XOR AX,#16*/ + AX ^= getword(); + setznp16(AX); + cpu_state.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; + // break; + + case 0x37: /*AAA*/ + if ((cpu_state.flags & A_FLAG) || ((AL & 0xF) > 9)) { + AL += 6; + AH++; + cpu_state.flags |= (A_FLAG | C_FLAG); + } else + cpu_state.flags &= ~(A_FLAG | C_FLAG); + AL &= 0xF; + cycles -= 8; + break; + + case 0x38: /*CMP 8,reg*/ + fetchea(); + temp = geteab(); + // if (output) printf("CMP %02X-%02X\n",temp,getr8(cpu_reg)); + setsub8(temp, getr8(cpu_reg)); + cycles -= ((cpu_mod == 3) ? 3 : 13); + break; + case 0x39: /*CMP 16,reg*/ + fetchea(); + tempw = geteaw(); + // if (output) printf("CMP %04X-%04X\n",tempw,cpu_state.regs[cpu_reg].w); + setsub16(tempw, cpu_state.regs[cpu_reg].w); + cycles -= ((cpu_mod == 3) ? 3 : 13); + break; + case 0x3A: /*CMP cpu_reg,8*/ + fetchea(); + temp = geteab(); + // if (output) printf("CMP %02X-%02X\n",getr8(cpu_reg),temp); + setsub8(getr8(cpu_reg), temp); + cycles -= ((cpu_mod == 3) ? 3 : 13); + break; + case 0x3B: /*CMP cpu_reg,16*/ + fetchea(); + tempw = geteaw(); + // printf("CMP %04X-%04X\n",cpu_state.regs[cpu_reg].w,tempw); + 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; + // break; + + case 0x3F: /*AAS*/ + if ((cpu_state.flags & A_FLAG) || ((AL & 0xF) > 9)) { + AL -= 6; + AH--; + cpu_state.flags |= (A_FLAG | C_FLAG); + } else + cpu_state.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; + 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.regs[opcode & 7].w = readmemw(ss, (SP - 2) & 0xFFFF); + cycles -= 12; + break; + + case 0x60: /*JO alias*/ + case 0x70: /*JO*/ + offset = (int8_t)FETCH(); + if (cpu_state.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 (!(cpu_state.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 (cpu_state.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 (!(cpu_state.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 (cpu_state.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 (!(cpu_state.flags & Z_FLAG)) { + cpu_state.pc += offset; + cycles -= 12; + FETCHCLEAR(); + } + break; + case 0x66: /*JBE alias*/ + case 0x76: /*JBE*/ + offset = (int8_t)FETCH(); + if (cpu_state.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 (!(cpu_state.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 (cpu_state.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 (!(cpu_state.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 (cpu_state.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 (!(cpu_state.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 = (cpu_state.flags & N_FLAG) ? 1 : 0; + temp2 = (cpu_state.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 = (cpu_state.flags & N_FLAG) ? 1 : 0; + temp2 = (cpu_state.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 = (cpu_state.flags & N_FLAG) ? 1 : 0; + temp2 = (cpu_state.flags & V_FLAG) ? 1 : 0; + if ((cpu_state.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 = (cpu_state.flags & N_FLAG) ? 1 : 0; + temp2 = (cpu_state.flags & V_FLAG) ? 1 : 0; + if (!((cpu_state.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); + cpu_state.flags &= ~(C_FLAG | V_FLAG | A_FLAG); + seteab(temp); + cycles -= ((cpu_mod == 3) ? 4 : 23); + break; + case 0x10: /*ADC b,#8*/ + // temp2+=(flags&C_FLAG); + setadc8(temp, temp2); + seteab(temp + temp2 + tempc); + cycles -= ((cpu_mod == 3) ? 4 : 23); + break; + case 0x18: /*SBB b,#8*/ + // temp2+=(flags&C_FLAG); + setsbc8(temp, temp2); + seteab(temp - (temp2 + tempc)); + cycles -= ((cpu_mod == 3) ? 4 : 23); + break; + case 0x20: /*AND b,#8*/ + temp &= temp2; + setznp8(temp); + cpu_state.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); + cpu_state.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; + + // default: + // printf("Bad 80 opcode %02X\n",rmdat&0x38); + // dumpregs(); + // exit(-1); + } + 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); + cpu_state.flags &= ~(C_FLAG | V_FLAG | A_FLAG); + seteaw(tempw); + cycles -= ((cpu_mod == 3) ? 4 : 23); + break; + case 0x10: /*ADC w,#16*/ + // tempw2+=(flags&C_FLAG); + setadc16(tempw, tempw2); + tempw += tempw2 + tempc; + seteaw(tempw); + cycles -= ((cpu_mod == 3) ? 4 : 23); + break; + case 0x20: /*AND w,#16*/ + tempw &= tempw2; + setznp16(tempw); + cpu_state.flags &= ~(C_FLAG | V_FLAG | A_FLAG); + seteaw(tempw); + cycles -= ((cpu_mod == 3) ? 4 : 23); + break; + case 0x18: /*SBB w,#16*/ + // tempw2+=(flags&C_FLAG); + 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); + cpu_state.flags &= ~(C_FLAG | V_FLAG | A_FLAG); + seteaw(tempw); + cycles -= ((cpu_mod == 3) ? 4 : 23); + break; + case 0x38: /*CMP w,#16*/ + // printf("CMP %04X %04X\n",tempw,tempw2); + setsub16(tempw, tempw2); + cycles -= ((cpu_mod == 3) ? 4 : 14); + break; + + // default: + // printf("Bad 81 opcode %02X\n",rmdat&0x38); + // dumpregs(); + // exit(-1); + } + 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); + cpu_state.flags &= ~(C_FLAG | A_FLAG | V_FLAG); + cycles -= ((cpu_mod == 3) ? 4 : 23); + break; + case 0x10: /*ADC w,#8*/ + // tempw2+=(flags&C_FLAG); + setadc16(tempw, tempw2); + tempw += tempw2 + tempc; + seteaw(tempw); + cycles -= ((cpu_mod == 3) ? 4 : 23); + break; + case 0x18: /*SBB w,#8*/ + // tempw2+=(flags&C_FLAG); + 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); + cpu_state.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); + cpu_state.flags &= ~(C_FLAG | A_FLAG | V_FLAG); + break; + case 0x38: /*CMP w,#8*/ + setsub16(tempw, tempw2); + cycles -= ((cpu_mod == 3) ? 4 : 14); + break; + + // default: + // printf("Bad 83 opcode %02X\n",rmdat&0x38); + // dumpregs(); + // exit(-1); + } + break; + + case 0x84: /*TEST b,reg*/ + fetchea(); + temp = geteab(); + temp2 = getr8(cpu_reg); + setznp8(temp & temp2); + cpu_state.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); + cpu_state.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_state.eaaddr; + cycles -= 2; + break; + + case 0x8E: /*MOV sreg,w*/ + // if (output) printf("MOV %04X ",pc); + fetchea(); + // if (output) printf("%04X %02X\n",pc,rmdat); + switch (rmdat & 0x38) { + case 0x00: /*ES*/ + tempw = geteaw(); + loadseg(tempw, &cpu_state.seg_es); + break; + case 0x08: /*CS - 8088/8086 only*/ + tempw = geteaw(); + loadseg(tempw, &cpu_state.seg_cs); + break; + case 0x18: /*DS*/ + tempw = geteaw(); + loadseg(tempw, &cpu_state.seg_ds); + if (cpu_state.ssegs) + oldds = ds; + break; + case 0x10: /*SS*/ + tempw = geteaw(); + loadseg(tempw, &cpu_state.seg_ss); + if (cpu_state.ssegs) + oldss = ss; + // printf("LOAD SS %04X %04X\n",tempw,SS); + // printf("SS loaded with %04X %04X:%04X %04X %04X + //%04X\n",ss>>4,cs>>4,pc,CX,DX,es>>4); + 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; + 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; + // printf("0x9a"); + loadcs(tempw2); + writememw(ss, (SP - 2) & 0xFFFF, tempw3); + writememw(ss, (SP - 4) & 0xFFFF, tempw4); + SP -= 4; + cycles -= 36; + FETCHCLEAR(); + break; + case 0x9B: /*WAIT*/ + cycles -= 4; + break; + case 0x9C: /*PUSHF*/ + if (cpu_state.ssegs) + ss = oldss; + writememw(ss, ((SP - 2) & 0xFFFF), cpu_state.flags | 0xF000); + SP -= 2; + cycles -= 14; + break; + case 0x9D: /*POPF*/ + if (cpu_state.ssegs) + ss = oldss; + cpu_state.flags = readmemw(ss, SP) & 0xFFF; + SP += 2; + cycles -= 12; + break; + case 0x9E: /*SAHF*/ + cpu_state.flags = (cpu_state.flags & 0xFF00) | AH; + cycles -= 4; + break; + case 0x9F: /*LAHF*/ + AH = cpu_state.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(); + // printf("Reading AX from %05X %04X:%04X\n",ds+addr,ds>>4,addr); + 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(); + // if (!addr) printf("Write !addr %04X:%04X\n",cs>>4,pc); + writememw(ds, addr, AX); + cycles -= 14; + break; + + case 0xA4: /*MOVSB*/ + temp = readmemb(ds + SI); + writememb(es + DI, temp); + if (cpu_state.flags & D_FLAG) { + DI--; + SI--; + } else { + DI++; + SI++; + } + cycles -= 18; + break; + case 0xA5: /*MOVSW*/ + tempw = readmemw(ds, SI); + writememw(es, DI, tempw); + if (cpu_state.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 (cpu_state.flags & D_FLAG) { + DI--; + SI--; + } else { + DI++; + SI++; + } + cycles -= 30; + break; + case 0xA7: /*CMPSW*/ + tempw = readmemw(ds, SI); + tempw2 = readmemw(es, DI); + // printf("CMPSW %04X %04X\n",tempw,tempw2); + setsub16(tempw, tempw2); + if (cpu_state.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); + cpu_state.flags &= ~(C_FLAG | V_FLAG | A_FLAG); + cycles -= 5; + break; + case 0xA9: /*TEST AX,#16*/ + tempw = getword(); + setznp16(AX & tempw); + cpu_state.flags &= ~(C_FLAG | V_FLAG | A_FLAG); + cycles -= 5; + break; + case 0xAA: /*STOSB*/ + writememb(es + DI, AL); + if (cpu_state.flags & D_FLAG) + DI--; + else + DI++; + cycles -= 11; + break; + case 0xAB: /*STOSW*/ + writememw(es, DI, AX); + if (cpu_state.flags & D_FLAG) + DI -= 2; + else + DI += 2; + cycles -= 11; + break; + case 0xAC: /*LODSB*/ + AL = readmemb(ds + SI); + // printf("LODSB %04X:%04X %02X %04X:%04X\n",cs>>4,pc,AL,ds>>4,SI); + if (cpu_state.flags & D_FLAG) + SI--; + else + SI++; + cycles -= 16; + break; + case 0xAD: /*LODSW*/ + // if (times) printf("LODSW %04X:%04X\n",cs>>4,pc); + AX = readmemw(ds, SI); + if (cpu_state.flags & D_FLAG) + SI -= 2; + else + SI += 2; + cycles -= 16; + break; + case 0xAE: /*SCASB*/ + temp = readmemb(es + DI); + setsub8(AL, temp); + if (cpu_state.flags & D_FLAG) + DI--; + else + DI++; + cycles -= 19; + break; + case 0xAF: /*SCASW*/ + tempw = readmemw(es, DI); + setsub16(AX, tempw); + if (cpu_state.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); + // printf("C2\n"); + // printf("RET to %04X\n",pc); + 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); + // printf("C3\n"); + // if (output) printf("RET to %04X %05X\n",pc,ss+SP); + SP += 2; + cycles -= 20; + FETCHCLEAR(); + break; + case 0xC4: /*LES*/ + fetchea(); + cpu_state.regs[cpu_reg].w = readmemw(easeg, cpu_state.eaaddr); // geteaw(); + tempw = readmemw(easeg, (cpu_state.eaaddr + 2) & 0xFFFF); // geteaw2(); + loadseg(tempw, &cpu_state.seg_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, &cpu_state.seg_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); + // printf("CA\n"); + 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); + // printf("CB\n"); + 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), cpu_state.flags | 0xF000); + writememw(ss, ((SP - 4) & 0xFFFF), CS); + writememw(ss, ((SP - 6) & 0xFFFF), cpu_state.pc); + SP -= 6; + addr = 3 << 2; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; + // printf("CC %04X:%04X ",CS,pc); + cpu_state.pc = readmemw(0, addr); + loadcs(readmemw(0, addr + 2)); + FETCHCLEAR(); + // printf("%04X:%04X\n",CS,pc); + cycles -= 72; + break; + case 0xCD: /*INT*/ + temp = FETCH(); + + if (cpu_state.ssegs) + ss = oldss; + writememw(ss, ((SP - 2) & 0xFFFF), cpu_state.flags | 0xF000); + writememw(ss, ((SP - 4) & 0xFFFF), CS); + writememw(ss, ((SP - 6) & 0xFFFF), cpu_state.pc); + cpu_state.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); + // printf("CF\n"); + loadcs(readmemw(ss, ((SP + 2) & 0xFFFF))); + cpu_state.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) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + temp <<= 1; + if (cpu_state.flags & C_FLAG) + temp |= 1; + seteab(temp); + // setznp8(temp); + if ((cpu_state.flags & C_FLAG) ^ (temp >> 7)) + cpu_state.flags |= V_FLAG; + else + cpu_state.flags &= ~V_FLAG; + cycles -= ((cpu_mod == 3) ? 2 : 23); + break; + case 0x08: /*ROR b,1*/ + if (temp & 1) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + temp >>= 1; + if (cpu_state.flags & C_FLAG) + temp |= 0x80; + seteab(temp); + // setznp8(temp); + if ((temp ^ (temp >> 1)) & 0x40) + cpu_state.flags |= V_FLAG; + else + cpu_state.flags &= ~V_FLAG; + cycles -= ((cpu_mod == 3) ? 2 : 23); + break; + case 0x10: /*RCL b,1*/ + temp2 = cpu_state.flags & C_FLAG; + if (temp & 0x80) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + temp <<= 1; + if (temp2) + temp |= 1; + seteab(temp); + // setznp8(temp); + if ((cpu_state.flags & C_FLAG) ^ (temp >> 7)) + cpu_state.flags |= V_FLAG; + else + cpu_state.flags &= ~V_FLAG; + cycles -= ((cpu_mod == 3) ? 2 : 23); + break; + case 0x18: /*RCR b,1*/ + temp2 = cpu_state.flags & C_FLAG; + if (temp & 1) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + temp >>= 1; + if (temp2) + temp |= 0x80; + seteab(temp); + // setznp8(temp); + if ((temp ^ (temp >> 1)) & 0x40) + cpu_state.flags |= V_FLAG; + else + cpu_state.flags &= ~V_FLAG; + cycles -= ((cpu_mod == 3) ? 2 : 23); + break; + case 0x20: + case 0x30: /*SHL b,1*/ + if (temp & 0x80) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + if ((temp ^ (temp << 1)) & 0x80) + cpu_state.flags |= V_FLAG; + else + cpu_state.flags &= ~V_FLAG; + temp <<= 1; + seteab(temp); + setznp8(temp); + cycles -= ((cpu_mod == 3) ? 2 : 23); + cpu_state.flags |= A_FLAG; + break; + case 0x28: /*SHR b,1*/ + if (temp & 1) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + if (temp & 0x80) + cpu_state.flags |= V_FLAG; + else + cpu_state.flags &= ~V_FLAG; + temp >>= 1; + seteab(temp); + setznp8(temp); + cycles -= ((cpu_mod == 3) ? 2 : 23); + cpu_state.flags |= A_FLAG; + break; + case 0x38: /*SAR b,1*/ + if (temp & 1) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + temp >>= 1; + if (temp & 0x40) + temp |= 0x80; + seteab(temp); + setznp8(temp); + cycles -= ((cpu_mod == 3) ? 2 : 23); + cpu_state.flags |= A_FLAG; + cpu_state.flags &= ~V_FLAG; + break; + + // default: + // printf("Bad D0 opcode %02X\n",rmdat&0x38); + // dumpregs(); + // exit(-1); + } + break; + + case 0xD1: + fetchea(); + tempw = geteaw(); + switch (rmdat & 0x38) { + case 0x00: /*ROL w,1*/ + if (tempw & 0x8000) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + tempw <<= 1; + if (cpu_state.flags & C_FLAG) + tempw |= 1; + seteaw(tempw); + // setznp16(tempw); + if ((cpu_state.flags & C_FLAG) ^ (tempw >> 15)) + cpu_state.flags |= V_FLAG; + else + cpu_state.flags &= ~V_FLAG; + cycles -= ((cpu_mod == 3) ? 2 : 23); + break; + case 0x08: /*ROR w,1*/ + if (tempw & 1) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + tempw >>= 1; + if (cpu_state.flags & C_FLAG) + tempw |= 0x8000; + seteaw(tempw); + // setznp16(tempw); + if ((tempw ^ (tempw >> 1)) & 0x4000) + cpu_state.flags |= V_FLAG; + else + cpu_state.flags &= ~V_FLAG; + cycles -= ((cpu_mod == 3) ? 2 : 23); + break; + case 0x10: /*RCL w,1*/ + temp2 = cpu_state.flags & C_FLAG; + if (tempw & 0x8000) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + tempw <<= 1; + if (temp2) + tempw |= 1; + seteaw(tempw); + if ((cpu_state.flags & C_FLAG) ^ (tempw >> 15)) + cpu_state.flags |= V_FLAG; + else + cpu_state.flags &= ~V_FLAG; + cycles -= ((cpu_mod == 3) ? 2 : 23); + break; + case 0x18: /*RCR w,1*/ + temp2 = cpu_state.flags & C_FLAG; + if (tempw & 1) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + tempw >>= 1; + if (temp2) + tempw |= 0x8000; + seteaw(tempw); + // setznp16(tempw); + if ((tempw ^ (tempw >> 1)) & 0x4000) + cpu_state.flags |= V_FLAG; + else + cpu_state.flags &= ~V_FLAG; + cycles -= ((cpu_mod == 3) ? 2 : 23); + break; + case 0x20: + case 0x30: /*SHL w,1*/ + if (tempw & 0x8000) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + if ((tempw ^ (tempw << 1)) & 0x8000) + cpu_state.flags |= V_FLAG; + else + cpu_state.flags &= ~V_FLAG; + tempw <<= 1; + seteaw(tempw); + setznp16(tempw); + cycles -= ((cpu_mod == 3) ? 2 : 23); + cpu_state.flags |= A_FLAG; + break; + case 0x28: /*SHR w,1*/ + if (tempw & 1) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + if (tempw & 0x8000) + cpu_state.flags |= V_FLAG; + else + cpu_state.flags &= ~V_FLAG; + tempw >>= 1; + seteaw(tempw); + setznp16(tempw); + cycles -= ((cpu_mod == 3) ? 2 : 23); + cpu_state.flags |= A_FLAG; + break; + + case 0x38: /*SAR w,1*/ + if (tempw & 1) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + tempw >>= 1; + if (tempw & 0x4000) + tempw |= 0x8000; + seteaw(tempw); + setznp16(tempw); + cycles -= ((cpu_mod == 3) ? 2 : 23); + cpu_state.flags |= A_FLAG; + cpu_state.flags &= ~V_FLAG; + break; + + // default: + // printf("Bad D1 opcode %02X\n",rmdat&0x38); + // dumpregs(); + // exit(-1); + } + break; + + case 0xD2: + fetchea(); + temp = geteab(); + c = CL; + // cycles-=c; + if (!c) + break; + // if (c>7) printf("Shiftb %i %02X\n",rmdat&0x38,c); + switch (rmdat & 0x38) { + case 0x00: /*ROL b,CL*/ + while (c > 0) { + temp2 = (temp & 0x80) ? 1 : 0; + temp = (temp << 1) | temp2; + c--; + cycles -= 4; + } + if (temp2) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + seteab(temp); + // setznp8(temp); + if ((cpu_state.flags & C_FLAG) ^ (temp >> 7)) + cpu_state.flags |= V_FLAG; + else + cpu_state.flags &= ~V_FLAG; + cycles -= ((cpu_mod == 3) ? 8 : 28); + break; + case 0x08: /*ROR b,CL*/ + while (c > 0) { + temp2 = temp & 1; + temp >>= 1; + if (temp2) + temp |= 0x80; + c--; + cycles -= 4; + } + if (temp2) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + seteab(temp); + if ((temp ^ (temp >> 1)) & 0x40) + cpu_state.flags |= V_FLAG; + else + cpu_state.flags &= ~V_FLAG; + cycles -= ((cpu_mod == 3) ? 8 : 28); + break; + case 0x10: /*RCL b,CL*/ + // printf("RCL %i %02X %02X\n",c,CL,temp); + while (c > 0) { + templ = cpu_state.flags & C_FLAG; + temp2 = temp & 0x80; + temp <<= 1; + if (temp2) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + if (templ) + temp |= 1; + c--; + cycles -= 4; + } + // printf("Now %02X\n",temp); + seteab(temp); + if ((cpu_state.flags & C_FLAG) ^ (temp >> 7)) + cpu_state.flags |= V_FLAG; + else + cpu_state.flags &= ~V_FLAG; + cycles -= ((cpu_mod == 3) ? 8 : 28); + break; + case 0x18: /*RCR b,CL*/ + while (c > 0) { + templ = cpu_state.flags & C_FLAG; + temp2 = temp & 1; + temp >>= 1; + if (temp2) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + if (templ) + temp |= 0x80; + c--; + cycles -= 4; + } + // if (temp2) flags|=C_FLAG; + // else flags&=~C_FLAG; + seteab(temp); + if ((temp ^ (temp >> 1)) & 0x40) + cpu_state.flags |= V_FLAG; + else + cpu_state.flags &= ~V_FLAG; + cycles -= ((cpu_mod == 3) ? 8 : 28); + break; + case 0x20: + case 0x30: /*SHL b,CL*/ + if (c > 8) { + temp = 0; + cpu_state.flags &= ~C_FLAG; + } else { + if ((temp << (c - 1)) & 0x80) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + temp <<= c; + } + seteab(temp); + setznp8(temp); + cycles -= (c * 4); + cycles -= ((cpu_mod == 3) ? 8 : 28); + cpu_state.flags |= A_FLAG; + break; + case 0x28: /*SHR b,CL*/ + if (c > 8) { + temp = 0; + cpu_state.flags &= ~C_FLAG; + } else { + if ((temp >> (c - 1)) & 1) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + temp >>= c; + } + seteab(temp); + setznp8(temp); + cycles -= (c * 4); + cycles -= ((cpu_mod == 3) ? 8 : 28); + cpu_state.flags |= A_FLAG; + break; + case 0x38: /*SAR b,CL*/ + if ((temp >> (c - 1)) & 1) + cpu_state.flags |= C_FLAG; + else + cpu_state.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); + cpu_state.flags |= A_FLAG; + break; + + // default: + // printf("Bad D2 opcode %02X\n",rmdat&0x38); + // dumpregs(); + // exit(-1); + } + break; + + case 0xD3: + fetchea(); + tempw = geteaw(); + c = CL; + // cycles-=c; + if (!c) + break; + // if (c>15) printf("Shiftw %i %02X\n",rmdat&0x38,c); + 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) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + seteaw(tempw); + if ((cpu_state.flags & C_FLAG) ^ (tempw >> 15)) + cpu_state.flags |= V_FLAG; + else + cpu_state.flags &= ~V_FLAG; + cycles -= ((cpu_mod == 3) ? 8 : 28); + break; + case 0x08: /*ROR w,CL*/ + while (c > 0) { + tempw2 = (tempw & 1) ? 0x8000 : 0; + tempw = (tempw >> 1) | tempw2; + c--; + cycles -= 4; + } + if (tempw2) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + seteaw(tempw); + if ((tempw ^ (tempw >> 1)) & 0x4000) + cpu_state.flags |= V_FLAG; + else + cpu_state.flags &= ~V_FLAG; + cycles -= ((cpu_mod == 3) ? 8 : 28); + break; + case 0x10: /*RCL w,CL*/ + while (c > 0) { + templ = cpu_state.flags & C_FLAG; + if (tempw & 0x8000) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + tempw = (tempw << 1) | templ; + c--; + cycles -= 4; + } + if (templ) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + seteaw(tempw); + if ((cpu_state.flags & C_FLAG) ^ (tempw >> 15)) + cpu_state.flags |= V_FLAG; + else + cpu_state.flags &= ~V_FLAG; + cycles -= ((cpu_mod == 3) ? 8 : 28); + break; + case 0x18: /*RCR w,CL*/ + while (c > 0) { + templ = cpu_state.flags & C_FLAG; + tempw2 = (templ & 1) ? 0x8000 : 0; + if (tempw & 1) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + tempw = (tempw >> 1) | tempw2; + c--; + cycles -= 4; + } + if (tempw2) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + seteaw(tempw); + if ((tempw ^ (tempw >> 1)) & 0x4000) + cpu_state.flags |= V_FLAG; + else + cpu_state.flags &= ~V_FLAG; + cycles -= ((cpu_mod == 3) ? 8 : 28); + break; + + case 0x20: + case 0x30: /*SHL w,CL*/ + if (c > 16) { + tempw = 0; + cpu_state.flags &= ~C_FLAG; + } else { + if ((tempw << (c - 1)) & 0x8000) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + tempw <<= c; + } + seteaw(tempw); + setznp16(tempw); + cycles -= (c * 4); + cycles -= ((cpu_mod == 3) ? 8 : 28); + cpu_state.flags |= A_FLAG; + break; + + case 0x28: /*SHR w,CL*/ + if (c > 16) { + tempw = 0; + cpu_state.flags &= ~C_FLAG; + } else { + if ((tempw >> (c - 1)) & 1) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + tempw >>= c; + } + seteaw(tempw); + setznp16(tempw); + cycles -= (c * 4); + cycles -= ((cpu_mod == 3) ? 8 : 28); + cpu_state.flags |= A_FLAG; + break; + + case 0x38: /*SAR w,CL*/ + tempw2 = tempw & 0x8000; + if ((tempw >> (c - 1)) & 1) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + while (c > 0) { + tempw = (tempw >> 1) | tempw2; + c--; + cycles -= 4; + } + seteaw(tempw); + setznp16(tempw); + cycles -= ((cpu_mod == 3) ? 8 : 28); + cpu_state.flags |= A_FLAG; + break; + + // default: + // printf("Bad D3 opcode %02X\n",rmdat&0x38); + // dumpregs(); + // exit(-1); + } + 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 = (cpu_state.flags & C_FLAG) ? 0xff : 0; + cycles -= 4; + break; + case 0xD7: /*XLAT*/ + addr = BX + AL; + AL = readmemb(ds + addr); + cycles -= 11; + break; + + case 0xd8: + fetchea(); + if (hasfpu) { + uint16_t save_pc = cpu_state.pc; + ops_808x_fpu_d8_a16[rmdat >> 3](rmdat); + cpu_state.pc = save_pc; + } + break; + case 0xd9: + fetchea(); + if (hasfpu) { + uint16_t save_pc = cpu_state.pc; + ops_808x_fpu_d9_a16[rmdat](rmdat); + cpu_state.pc = save_pc; + } + break; + case 0xda: + fetchea(); + if (hasfpu) { + uint16_t save_pc = cpu_state.pc; + ops_808x_fpu_da_a16[rmdat](rmdat); + cpu_state.pc = save_pc; + } + break; + case 0xdb: + fetchea(); + if (hasfpu) { + uint16_t save_pc = cpu_state.pc; + ops_808x_fpu_db_a16[rmdat](rmdat); + cpu_state.pc = save_pc; + } + break; + case 0xdc: + fetchea(); + if (hasfpu) { + uint16_t save_pc = cpu_state.pc; + ops_808x_fpu_dc_a16[rmdat >> 3](rmdat); + cpu_state.pc = save_pc; + } + break; + case 0xdd: + fetchea(); + if (hasfpu) { + uint16_t save_pc = cpu_state.pc; + ops_808x_fpu_dd_a16[rmdat](rmdat); + cpu_state.pc = save_pc; + } + break; + case 0xde: + fetchea(); + if (hasfpu) { + uint16_t save_pc = cpu_state.pc; + ops_808x_fpu_de_a16[rmdat](rmdat); + cpu_state.pc = save_pc; + } + break; + case 0xdf: + fetchea(); + if (hasfpu) { + uint16_t save_pc = cpu_state.pc; + ops_808x_fpu_df_a16[rmdat](rmdat); + cpu_state.pc = save_pc; + } + break; + + case 0xE0: /*LOOPNE*/ + offset = (int8_t)FETCH(); + CX--; + if (CX && !(cpu_state.flags & Z_FLAG)) { + cpu_state.pc += offset; + cycles -= 12; + FETCHCLEAR(); + } + cycles -= 6; + break; + case 0xE1: /*LOOPE*/ + offset = (int8_t)FETCH(); + CX--; + if (CX && (cpu_state.flags & Z_FLAG)) { + cpu_state.pc += offset; + cycles -= 12; + FETCHCLEAR(); + } + cycles -= 6; + break; + case 0xE2: /*LOOP*/ + // printf("LOOP start\n"); + offset = (int8_t)FETCH(); + CX--; + if (CX) { + cpu_state.pc += offset; + cycles -= 12; + FETCHCLEAR(); + } + cycles -= 5; + // printf("LOOP end!\n"); + 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; + // writememb(ss+((SP-1)&0xFFFF),pc>>8); + writememw(ss, ((SP - 2) & 0xFFFF), cpu_state.pc); + SP -= 2; + cpu_state.pc += tempw; + cycles -= 23; + FETCHCLEAR(); + break; + case 0xE9: /*JMP rel 16*/ + // pclog("PC was %04X\n",cpu_state.pc); + tempw = getword(); + cpu_state.pc += tempw; + // pclog("PC now %04X\n",cpu_state.pc); + cycles -= 15; + FETCHCLEAR(); + break; + case 0xEA: /*JMP far*/ + addr = getword(); + tempw = getword(); + cpu_state.pc = addr; + // printf("EA\n"); + loadcs(tempw); + // cs=loadcs(CS); + // cs=CS<<4; + 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*/ + // printf("IN HLT!!!! %04X %08X %08X %08X\n",oldpc,old8,old82,old83); + /* if (!(flags & I_FLAG)) + { + pclog("HLT\n"); + dumpregs(); + exit(-1); + }*/ + inhlt = 1; + cpu_state.pc--; + FETCHCLEAR(); + cycles -= 2; + break; + case 0xF5: /*CMC*/ + cpu_state.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); + cpu_state.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) + cpu_state.flags &= ~Z_FLAG; + else + cpu_state.flags |= Z_FLAG; + if (AH) + cpu_state.flags |= (C_FLAG | V_FLAG); + else + cpu_state.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) + cpu_state.flags &= ~Z_FLAG; + else + cpu_state.flags |= Z_FLAG; + if (AH) + cpu_state.flags |= (C_FLAG | V_FLAG); + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + cycles -= 80; + break; + case 0x30: /*DIV AL,b*/ + tempw = AX; + if (temp) { + tempw2 = tempw % temp; + /* if (!tempw) + { + writememw((ss+SP)-2,flags|0xF000); + writememw((ss+SP)-4,cs>>4); + writememw((ss+SP)-6,pc); + SP-=6; + flags&=~I_FLAG; + pc=readmemw(0); + cs=readmemw(2)<<4; + printf("Div by zero + %04X:%04X\n",cs>>4,pc); + // dumpregs(); + // exit(-1); + } + else + {*/ + AH = tempw2; + tempw /= temp; + AL = tempw & 0xFF; + // } + } else { + printf("DIVb BY 0 %04X:%04X\n", cs >> 4, cpu_state.pc); + writememw(ss, (SP - 2) & 0xFFFF, cpu_state.flags | 0xF000); + writememw(ss, (SP - 4) & 0xFFFF, CS); + writememw(ss, (SP - 6) & 0xFFFF, cpu_state.pc); + SP -= 6; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; + cpu_state.pc = readmemw(0, 0); + // printf("F6 30\n"); + loadcs(readmemw(0, 2)); + FETCHCLEAR(); + // cs=loadcs(CS); + // cs=CS<<4; + // printf("Div by zero %04X:%04X %02X + // %02X\n",cs>>4,pc,0xf6,0x30); dumpregs(); + // exit(-1); + } + cycles -= 80; + break; + case 0x38: /*IDIV AL,b*/ + tempws = (int)AX; + if (temp) { + tempw2 = tempws % (int)((int8_t)temp); + /* if (!tempw) + { + writememw((ss+SP)-2,flags|0xF000); + writememw((ss+SP)-4,cs>>4); + writememw((ss+SP)-6,pc); + SP-=6; + flags&=~I_FLAG; + pc=readmemw(0); + cs=readmemw(2)<<4; + printf("Div by zero + %04X:%04X\n",cs>>4,pc); + } + else + {*/ + AH = tempw2 & 0xFF; + tempws /= (int)((int8_t)temp); + AL = tempws & 0xFF; + // } + } else { + printf("IDIVb BY 0 %04X:%04X\n", cs >> 4, cpu_state.pc); + writememw(ss, (SP - 2) & 0xFFFF, cpu_state.flags | 0xF000); + writememw(ss, (SP - 4) & 0xFFFF, CS); + writememw(ss, (SP - 6) & 0xFFFF, cpu_state.pc); + SP -= 6; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; + cpu_state.pc = readmemw(0, 0); + // printf("F6 38\n"); + loadcs(readmemw(0, 2)); + FETCHCLEAR(); + // cs=loadcs(CS); + // cs=CS<<4; + // printf("Div by zero %04X:%04X %02X + // %02X\n",cs>>4,pc,0xf6,0x38); + } + cycles -= 101; + break; + + // default: + // printf("Bad F6 opcode %02X\n",rmdat&0x38); + // dumpregs(); + // exit(-1); + } + break; + + case 0xF7: + fetchea(); + tempw = geteaw(); + switch (rmdat & 0x38) { + case 0x00: /*TEST w*/ + case 0x08: + tempw2 = getword(); + setznp16(tempw & tempw2); + cpu_state.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; + // if (output) printf("%04X*%04X=%08X\n",AX,tempw,templ); + AX = templ & 0xFFFF; + DX = templ >> 16; + if (AX | DX) + cpu_state.flags &= ~Z_FLAG; + else + cpu_state.flags |= Z_FLAG; + if (DX) + cpu_state.flags |= (C_FLAG | V_FLAG); + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + cycles -= 118; + break; + case 0x28: /*IMUL AX,w*/ + setznp16(AX); + // printf("IMUL %i %i ",(int)((int16_t)AX),(int)((int16_t)tempw)); + tempws = (int)((int16_t)AX) * (int)((int16_t)tempw); + if ((tempws >> 15) && ((tempws >> 15) != -1)) + cpu_state.flags |= (C_FLAG | V_FLAG); + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + // printf("%i ",tempws); + AX = tempws & 0xFFFF; + tempws = (uint16_t)(tempws >> 16); + DX = tempws & 0xFFFF; + // printf("%04X %04X\n",AX,DX); + // dumpregs(); + // exit(-1); + if (AX | DX) + cpu_state.flags &= ~Z_FLAG; + else + cpu_state.flags |= Z_FLAG; + cycles -= 128; + break; + case 0x30: /*DIV AX,w*/ + templ = (DX << 16) | AX; + // printf("DIV %08X/%04X\n",templ,tempw); + if (tempw) { + tempw2 = templ % tempw; + DX = tempw2; + templ /= tempw; + AX = templ & 0xFFFF; + } else { + printf("DIVw BY 0 %04X:%04X\n", cs >> 4, cpu_state.pc); + writememw(ss, (SP - 2) & 0xFFFF, cpu_state.flags | 0xF000); + writememw(ss, (SP - 4) & 0xFFFF, CS); + writememw(ss, (SP - 6) & 0xFFFF, cpu_state.pc); + SP -= 6; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; + cpu_state.pc = readmemw(0, 0); + // printf("F7 30\n"); + loadcs(readmemw(0, 2)); + FETCHCLEAR(); + } + cycles -= 144; + break; + case 0x38: /*IDIV AX,w*/ + tempws = (int)((DX << 16) | AX); + // printf("IDIV %i %i ",tempws,tempw); + if (tempw) { + tempw2 = tempws % (int)((int16_t)tempw); + // printf("%04X ",tempw2); + DX = tempw2; + tempws /= (int)((int16_t)tempw); + AX = tempws & 0xFFFF; + } else { + printf("IDIVw BY 0 %04X:%04X\n", cs >> 4, cpu_state.pc); + writememw(ss, (SP - 2) & 0xFFFF, cpu_state.flags | 0xF000); + writememw(ss, (SP - 4) & 0xFFFF, CS); + writememw(ss, (SP - 6) & 0xFFFF, cpu_state.pc); + SP -= 6; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; + cpu_state.pc = readmemw(0, 0); + // printf("F7 38\n"); + loadcs(readmemw(0, 2)); + FETCHCLEAR(); + } + cycles -= 165; + break; + + // default: + // printf("Bad F7 opcode %02X\n",rmdat&0x38); + // dumpregs(); + // exit(-1); + } + break; + + case 0xF8: /*CLC*/ + cpu_state.flags &= ~C_FLAG; + cycles -= 2; + break; + case 0xF9: /*STC*/ + // printf("STC %04X\n",pc); + cpu_state.flags |= C_FLAG; + cycles -= 2; + break; + case 0xFA: /*CLI*/ + cpu_state.flags &= ~I_FLAG; + // printf("CLI at %04X:%04X\n",cs>>4,pc); + cycles -= 3; + break; + case 0xFB: /*STI*/ + cpu_state.flags |= I_FLAG; + // printf("STI at %04X:%04X\n",cs>>4,pc); + cycles -= 2; + break; + case 0xFC: /*CLD*/ + cpu_state.flags &= ~D_FLAG; + cycles -= 2; + break; + case 0xFD: /*STD*/ + cpu_state.flags |= D_FLAG; + cycles -= 2; + break; + + case 0xFE: /*INC/DEC b*/ + fetchea(); + temp = geteab(); + cpu_state.flags &= ~V_FLAG; + if (rmdat & 0x38) { + setsub8nc(temp, 1); + temp2 = temp - 1; + if ((temp & 0x80) && !(temp2 & 0x80)) + cpu_state.flags |= V_FLAG; + } else { + setadd8nc(temp, 1); + temp2 = temp + 1; + if ((temp2 & 0x80) && !(temp & 0x80)) + cpu_state.flags |= V_FLAG; + } + // setznp8(temp2); + seteab(temp2); + cycles -= ((cpu_mod == 3) ? 3 : 23); + break; + + case 0xFF: + fetchea(); + switch (rmdat & 0x38) { + case 0x00: /*INC w*/ + tempw = geteaw(); + setadd16nc(tempw, 1); + // setznp16(tempw+1); + seteaw(tempw + 1); + cycles -= ((cpu_mod == 3) ? 3 : 23); + break; + case 0x08: /*DEC w*/ + tempw = geteaw(); + // setsub16(tempw,1); + setsub16nc(tempw, 1); + // setznp16(tempw-1); + seteaw(tempw - 1); + // if (output) printf("DEC - %04X\n",tempw); + 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.pc = tempw; + // printf("FF 10\n"); + 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); // geteaw2(); + tempw3 = CS; + tempw4 = cpu_state.pc; + if (cpu_state.ssegs) + ss = oldss; + cpu_state.pc = tempw; + // printf("FF 18\n"); + loadcs(tempw2); + writememw(ss, (SP - 2) & 0xFFFF, tempw3); + writememw(ss, ((SP - 4) & 0xFFFF), tempw4); + SP -= 4; + cycles -= 53; + FETCHCLEAR(); + break; + case 0x20: /*JMP*/ + cpu_state.pc = geteaw(); + // printf("FF 20\n"); + cycles -= ((cpu_mod == 3) ? 11 : 18); + FETCHCLEAR(); + break; + case 0x28: /*JMP far*/ + cpu_state.pc = readmemw(easeg, cpu_state.eaaddr); // geteaw(); + // printf("FF 28\n"); + loadcs(readmemw(easeg, (cpu_state.eaaddr + 2) & 0xFFFF)); // geteaw2(); + // cs=loadcs(CS); + // cs=CS<<4; + cycles -= 24; + FETCHCLEAR(); + break; + case 0x30: /*PUSH w*/ + tempw = geteaw(); + // if (output) printf("PUSH %04X %i %02X %04X %04X %02X + // %02X\n",tempw,cpu_rm,rmdat,easeg,eaaddr,ram[0x22340+0x5638],ram[0x22340+0x5639]); + if (cpu_state.ssegs) + ss = oldss; + writememw(ss, ((SP - 2) & 0xFFFF), tempw); + SP -= 2; + cycles -= ((cpu_mod == 3) ? 15 : 24); + break; + + // default: + // printf("Bad FF opcode %02X\n",rmdat&0x38); + // dumpregs(); + // exit(-1); + } + break; + + default: + FETCH(); + cycles -= 8; + break; + + /* printf("Bad opcode %02X at %04X:%04X from %04X:%04X + %08X\n",opcode,cs>>4,pc,old8>>16,old8&0xFFFF,old82); dumpregs(); exit(-1);*/ + } + cpu_state.pc &= 0xFFFF; + + /* if ((CS & 0xf000) == 0xa000) + { + dumpregs(); + exit(-1); + }*/ + // output = 3; + /* if (CS == 0xf000) + { + dumpregs(); + exit(-1); + } + output = 3;*/ + if (cpu_state.ssegs) { + ds = oldds; + ss = oldss; + cpu_state.ssegs = 0; + } + + // output = 3; + // if (instime) printf("%i %i %i %i\n",cycdiff,cycles,memcycs,fetchclocks); + FETCHADD(((cycdiff - cycles) - memcycs) - fetchclocks); + if ((cycdiff - cycles) < memcycs) + cycles -= (memcycs - (cycdiff - cycles)); + memcycs = 0; + + insc++; + // output=(CS==0xEB9); + clockhardware(); + + if (trap && (cpu_state.flags & T_FLAG) && !noint) { + // printf("TRAP!!! %04X:%04X\n",CS,pc); + writememw(ss, (SP - 2) & 0xFFFF, cpu_state.flags | 0xF000); + writememw(ss, (SP - 4) & 0xFFFF, CS); + writememw(ss, (SP - 6) & 0xFFFF, cpu_state.pc); + SP -= 6; + addr = 1 << 2; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; + cpu_state.pc = readmemw(0, addr); + loadcs(readmemw(0, addr + 2)); + FETCHCLEAR(); + } else if (nmi && nmi_enable && nmi_mask) { + // output = 3; + writememw(ss, (SP - 2) & 0xFFFF, cpu_state.flags | 0xF000); + writememw(ss, (SP - 4) & 0xFFFF, CS); + writememw(ss, (SP - 6) & 0xFFFF, cpu_state.pc); + SP -= 6; + addr = 2 << 2; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; + cpu_state.pc = readmemw(0, addr); + loadcs(readmemw(0, addr + 2)); + FETCHCLEAR(); + nmi_enable = 0; + } else if (takeint && !cpu_state.ssegs && !noint) { + temp = picinterrupt(); + if (temp != 0xFF) { + if (inhlt) + cpu_state.pc++; + writememw(ss, (SP - 2) & 0xFFFF, cpu_state.flags | 0xF000); + writememw(ss, (SP - 4) & 0xFFFF, CS); + writememw(ss, (SP - 6) & 0xFFFF, cpu_state.pc); + SP -= 6; + addr = temp << 2; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; + cpu_state.pc = readmemw(0, addr); + // printf("INT INT INT\n"); + loadcs(readmemw(0, addr + 2)); + FETCHCLEAR(); + // printf("INTERRUPT\n"); + } + } + takeint = (cpu_state.flags & I_FLAG) && (pic.pend & ~pic.mask); + + if (noint) + noint = 0; + ins++; + /* if (timetolive) + { + timetolive--; + if (!timetolive) exit(-1); //output=0; + }*/ + } } - diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 0d173545..9d6b2cb2 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -63,21 +63,19 @@ OpFn *x86_opcodes_REPNE; OpFn *x86_opcodes_3DNOW; 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_SEP = (1 << 11), - CPUID_CMOV = (1 << 15), - CPUID_MMX = (1 << 23) + 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_SEP = (1 << 11), + CPUID_CMOV = (1 << 15), + CPUID_MMX = (1 << 23) }; /*Addition flags returned by CPUID function 0x80000001*/ -enum { - CPUID_3DNOW = (1 << 31) -}; +enum { CPUID_3DNOW = (1 << 31) }; int cpu = 3, cpu_manufacturer = 0; CPU *cpu_s; @@ -114,1861 +112,1967 @@ int timing_jmp_rm, timing_jmp_pm, timing_jmp_pm_gate; int timing_misaligned; static struct { - uint32_t tr1, tr12; - uint32_t cesr; - uint32_t fcr; - uint64_t fcr2, fcr3; + uint32_t tr1, tr12; + uint32_t cesr; + uint32_t fcr; + uint64_t fcr2, fcr3; } msr; -void cpu_set_edx() { - EDX = models[model]->cpu[cpu_manufacturer].cpus[cpu].edx_reset; -} +void cpu_set_edx() { EDX = models[model]->cpu[cpu_manufacturer].cpus[cpu].edx_reset; } int fpu_get_type(int model, int manu, int cpu, const char *internal_name) { - CPU *cpu_s = &models[model]->cpu[manu].cpus[cpu]; - const FPU *fpus = cpu_s->fpus; - int fpu_type = fpus[0].type; - int c = 0; + CPU *cpu_s = &models[model]->cpu[manu].cpus[cpu]; + const FPU *fpus = cpu_s->fpus; + int fpu_type = fpus[0].type; + int c = 0; - while (fpus[c].internal_name) { - if (!strcmp(internal_name, fpus[c].internal_name)) - fpu_type = fpus[c].type; - c++; - } + while (fpus[c].internal_name) { + if (!strcmp(internal_name, fpus[c].internal_name)) + fpu_type = fpus[c].type; + c++; + } - return fpu_type; + return fpu_type; } const char *fpu_get_internal_name(int model, int manu, int cpu, int type) { - CPU *cpu_s = &models[model]->cpu[manu].cpus[cpu]; - const FPU *fpus = cpu_s->fpus; - int c = 0; + CPU *cpu_s = &models[model]->cpu[manu].cpus[cpu]; + const FPU *fpus = cpu_s->fpus; + int c = 0; - while (fpus[c].internal_name) { - if (fpus[c].type == type) - return fpus[c].internal_name; - c++; - } + while (fpus[c].internal_name) { + if (fpus[c].type == type) + return fpus[c].internal_name; + c++; + } - return fpus[0].internal_name; + return fpus[0].internal_name; } const char *fpu_get_name_from_index(int model, int manu, int cpu, int c) { - CPU *cpu_s = &models[model]->cpu[manu].cpus[cpu]; - const FPU *fpus = cpu_s->fpus; + CPU *cpu_s = &models[model]->cpu[manu].cpus[cpu]; + const FPU *fpus = cpu_s->fpus; - return fpus[c].name; + return fpus[c].name; } int fpu_get_type_from_index(int model, int manu, int cpu, int c) { - CPU *cpu_s = &models[model]->cpu[manu].cpus[cpu]; - const FPU *fpus = cpu_s->fpus; + CPU *cpu_s = &models[model]->cpu[manu].cpus[cpu]; + const FPU *fpus = cpu_s->fpus; - return fpus[c].type; + return fpus[c].type; } CPU *cpu_s; void cpu_set() { - if (!models[model]->cpu[cpu_manufacturer].cpus) { - /*CPU is invalid, set to default*/ - cpu_manufacturer = 0; - cpu = 0; - } + if (!models[model]->cpu[cpu_manufacturer].cpus) { + /*CPU is invalid, set to default*/ + cpu_manufacturer = 0; + cpu = 0; + } - cpu_s = &models[model]->cpu[cpu_manufacturer].cpus[cpu]; + cpu_s = &models[model]->cpu[cpu_manufacturer].cpus[cpu]; - CPUID = cpu_s->cpuid_model; - cpuspeed = cpu_s->speed; - is8086 = (cpu_s->cpu_type > CPU_8088); - is386 = (cpu_s->cpu_type >= CPU_386SX); - is486 = (cpu_s->cpu_type >= CPU_i486SX) || (cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_486DLC); - hasfpu = (fpu_type != FPU_NONE); + CPUID = cpu_s->cpuid_model; + cpuspeed = cpu_s->speed; + is8086 = (cpu_s->cpu_type > CPU_8088); + is386 = (cpu_s->cpu_type >= CPU_386SX); + is486 = (cpu_s->cpu_type >= CPU_i486SX) || (cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_486DLC); + hasfpu = (fpu_type != FPU_NONE); - 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; - ccr0 = ccr1 = ccr2 = ccr3 = ccr4 = ccr5 = ccr6 = 0; - has_vlb = (cpu_s->cpu_type >= CPU_i486SX) && (cpu_s->cpu_type <= CPU_Cx5x86); + cpu_iscyrix = (cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_486DLC || cpu_s->cpu_type == CPU_Cx486S || + cpu_s->cpu_type == CPU_Cx486DX || cpu_s->cpu_type == CPU_Cx5x86 || 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; + ccr0 = ccr1 = ccr2 = ccr3 = ccr4 = ccr5 = ccr6 = 0; + has_vlb = (cpu_s->cpu_type >= CPU_i486SX) && (cpu_s->cpu_type <= CPU_Cx5x86); - cpu_turbo_speed = cpu_s->rspeed; - if (cpu_s->cpu_type < CPU_286) - cpu_nonturbo_speed = 4772728; - else if (cpu_s->rspeed < 8000000) - cpu_nonturbo_speed = cpu_s->rspeed; - else - cpu_nonturbo_speed = 8000000; - cpu_turbo = 1; + cpu_turbo_speed = cpu_s->rspeed; + if (cpu_s->cpu_type < CPU_286) + cpu_nonturbo_speed = 4772728; + else if (cpu_s->rspeed < 8000000) + cpu_nonturbo_speed = cpu_s->rspeed; + else + cpu_nonturbo_speed = 8000000; + cpu_turbo = 1; - cpu_update_waitstates(); + cpu_update_waitstates(); - isa_cycles = cpu_s->atclk_div; + 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->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; - } - pclog("PCI burst=%i nonburst=%i\n", pci_burst_time, pci_nonburst_time); + 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; + } + pclog("PCI burst=%i nonburst=%i\n", pci_burst_time, pci_nonburst_time); - 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); + 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); - pclog("hasfpu - %i\n", hasfpu); - pclog("is486 - %i %i\n", is486, cpu_s->cpu_type); + pclog("hasfpu - %i\n", hasfpu); + pclog("is486 - %i %i\n", is486, cpu_s->cpu_type); - x86_setopcodes(ops_386, ops_386_0f, dynarec_ops_386, dynarec_ops_386_0f); - x86_opcodes_REPE = ops_REPE; - x86_opcodes_REPNE = ops_REPNE; - x86_opcodes_3DNOW = ops_3DNOW; - x86_dynarec_opcodes_REPE = dynarec_ops_REPE; - x86_dynarec_opcodes_REPNE = dynarec_ops_REPNE; - x86_dynarec_opcodes_3DNOW = dynarec_ops_3DNOW; + x86_setopcodes(ops_386, ops_386_0f, dynarec_ops_386, dynarec_ops_386_0f); + x86_opcodes_REPE = ops_REPE; + x86_opcodes_REPNE = ops_REPNE; + x86_opcodes_3DNOW = ops_3DNOW; + x86_dynarec_opcodes_REPE = dynarec_ops_REPE; + x86_dynarec_opcodes_REPNE = dynarec_ops_REPNE; + x86_dynarec_opcodes_3DNOW = dynarec_ops_3DNOW; - 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); + 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); - 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; - } + 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)); + memset(&msr, 0, sizeof(msr)); - timing_misaligned = 0; - cpu_cyrix_alignment = 0; - cpu_CR4_mask = 0; + timing_misaligned = 0; + cpu_cyrix_alignment = 0; + cpu_CR4_mask = 0; - switch (cpu_s->cpu_type) { - case CPU_8088: - case CPU_8086:break; + switch (cpu_s->cpu_type) { + case CPU_8088: + case CPU_8086: + break; - case CPU_286:x86_setopcodes(ops_286, ops_286_0f, dynarec_ops_286, dynarec_ops_286_0f); - 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_286: + x86_setopcodes(ops_286, ops_286_0f, dynarec_ops_286, dynarec_ops_286_0f); + 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_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_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_486SLC: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_486SLC: + 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: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_486DLC: + 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_features = CPU_FEATURE_CR4 | CPU_FEATURE_VME; - cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_VME; - case CPU_i486SX: - case CPU_i486DX: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_iDX4: + cpu_features = CPU_FEATURE_CR4 | CPU_FEATURE_VME; + cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_VME; + case CPU_i486SX: + case CPU_i486DX: + 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*/ - 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*/ + 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: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_Cx486S: + case CPU_Cx486DX: + 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: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_Cx5x86: + 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:x86_setopcodes(ops_386, ops_winchip_0f, dynarec_ops_386, dynarec_ops_winchip_0f); - timing_rr = 1; /*register dest - register src*/ - timing_rm = 2; /*register dest - memory src*/ - timing_mr = 2; /*memory dest - register src*/ - timing_mm = 3; - timing_rml = 2; /*register dest - memory src long*/ - timing_mrl = 2; /*memory dest - register src long*/ - timing_mml = 3; - timing_bt = 3 - 1; /*branch taken*/ - timing_bnt = 1; /*branch not taken*/ - cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MMX | CPU_FEATURE_MSR | CPU_FEATURE_CR4; - msr.fcr = (1 << 8) | (1 << 16); - cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE; - /*unknown*/ - timing_int_rm = 26; - timing_int_v86 = 82; - timing_int_pm = 44; - timing_int_pm_outer = 71; - timing_iret_rm = 7; - timing_iret_v86 = 26; - timing_iret_pm = 10; - timing_iret_pm_outer = 26; - timing_call_rm = 4; - timing_call_pm = 15; - timing_call_pm_gate = 26; - timing_call_pm_gate_inner = 35; - timing_retf_rm = 4; - timing_retf_pm = 7; - timing_retf_pm_outer = 23; - timing_jmp_rm = 5; - timing_jmp_pm = 7; - timing_jmp_pm_gate = 17; - timing_misaligned = 2; - cpu_cyrix_alignment = 1; - codegen_timing_set(&codegen_timing_winchip); - break; + case CPU_WINCHIP: + x86_setopcodes(ops_386, ops_winchip_0f, dynarec_ops_386, dynarec_ops_winchip_0f); + timing_rr = 1; /*register dest - register src*/ + timing_rm = 2; /*register dest - memory src*/ + timing_mr = 2; /*memory dest - register src*/ + timing_mm = 3; + timing_rml = 2; /*register dest - memory src long*/ + timing_mrl = 2; /*memory dest - register src long*/ + timing_mml = 3; + timing_bt = 3 - 1; /*branch taken*/ + timing_bnt = 1; /*branch not taken*/ + cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MMX | CPU_FEATURE_MSR | CPU_FEATURE_CR4; + msr.fcr = (1 << 8) | (1 << 16); + cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE; + /*unknown*/ + timing_int_rm = 26; + timing_int_v86 = 82; + timing_int_pm = 44; + timing_int_pm_outer = 71; + timing_iret_rm = 7; + timing_iret_v86 = 26; + timing_iret_pm = 10; + timing_iret_pm_outer = 26; + timing_call_rm = 4; + timing_call_pm = 15; + timing_call_pm_gate = 26; + timing_call_pm_gate_inner = 35; + timing_retf_rm = 4; + timing_retf_pm = 7; + timing_retf_pm_outer = 23; + timing_jmp_rm = 5; + timing_jmp_pm = 7; + timing_jmp_pm_gate = 17; + timing_misaligned = 2; + cpu_cyrix_alignment = 1; + codegen_timing_set(&codegen_timing_winchip); + break; - case CPU_WINCHIP2:x86_setopcodes(ops_386, ops_winchip2_0f, dynarec_ops_386, dynarec_ops_winchip2_0f); - timing_rr = 1; /*register dest - register src*/ - timing_rm = 2; /*register dest - memory src*/ - timing_mr = 2; /*memory dest - register src*/ - timing_mm = 3; - timing_rml = 2; /*register dest - memory src long*/ - timing_mrl = 2; /*memory dest - register src long*/ - timing_mml = 3; - timing_bt = 3 - 1; /*branch taken*/ - timing_bnt = 1; /*branch not taken*/ - cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MMX | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_3DNOW; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 18) | (1 << 19) | (1 << 20) | (1 << 21); - cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE; - /*unknown*/ - timing_int_rm = 26; - timing_int_v86 = 82; - timing_int_pm = 44; - timing_int_pm_outer = 71; - timing_iret_rm = 7; - timing_iret_v86 = 26; - timing_iret_pm = 10; - timing_iret_pm_outer = 26; - timing_call_rm = 4; - timing_call_pm = 15; - timing_call_pm_gate = 26; - timing_call_pm_gate_inner = 35; - timing_retf_rm = 4; - timing_retf_pm = 7; - timing_retf_pm_outer = 23; - timing_jmp_rm = 5; - timing_jmp_pm = 7; - timing_jmp_pm_gate = 17; - timing_misaligned = 2; - cpu_cyrix_alignment = 1; - codegen_timing_set(&codegen_timing_winchip2); - break; + case CPU_WINCHIP2: + x86_setopcodes(ops_386, ops_winchip2_0f, dynarec_ops_386, dynarec_ops_winchip2_0f); + timing_rr = 1; /*register dest - register src*/ + timing_rm = 2; /*register dest - memory src*/ + timing_mr = 2; /*memory dest - register src*/ + timing_mm = 3; + timing_rml = 2; /*register dest - memory src long*/ + timing_mrl = 2; /*memory dest - register src long*/ + timing_mml = 3; + timing_bt = 3 - 1; /*branch taken*/ + timing_bnt = 1; /*branch not taken*/ + cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MMX | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_3DNOW; + msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 18) | (1 << 19) | (1 << 20) | (1 << 21); + cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE; + /*unknown*/ + timing_int_rm = 26; + timing_int_v86 = 82; + timing_int_pm = 44; + timing_int_pm_outer = 71; + timing_iret_rm = 7; + timing_iret_v86 = 26; + timing_iret_pm = 10; + timing_iret_pm_outer = 26; + timing_call_rm = 4; + timing_call_pm = 15; + timing_call_pm_gate = 26; + timing_call_pm_gate_inner = 35; + timing_retf_rm = 4; + timing_retf_pm = 7; + timing_retf_pm_outer = 23; + timing_jmp_rm = 5; + timing_jmp_pm = 7; + timing_jmp_pm_gate = 17; + timing_misaligned = 2; + cpu_cyrix_alignment = 1; + codegen_timing_set(&codegen_timing_winchip2); + break; - case CPU_PENTIUM:x86_setopcodes(ops_386, ops_pentium_0f, dynarec_ops_386, dynarec_ops_pentium_0f); - 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_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE; - codegen_timing_set(&codegen_timing_pentium); - break; + case CPU_PENTIUM: + x86_setopcodes(ops_386, ops_pentium_0f, dynarec_ops_386, dynarec_ops_pentium_0f); + 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_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME; + msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); + cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE; + codegen_timing_set(&codegen_timing_pentium); + break; - case CPU_PENTIUMMMX:x86_setopcodes(ops_386, ops_pentiummmx_0f, dynarec_ops_386, dynarec_ops_pentiummmx_0f); - timing_rr = 1; /*register dest - register src*/ - timing_rm = 2; /*register dest - memory src*/ - timing_mr = 3; /*memory dest - register src*/ - timing_mm = 3; - timing_rml = 2; /*register dest - memory src long*/ - timing_mrl = 3; /*memory dest - register src long*/ - timing_mml = 3; - timing_bt = 0; /*branch taken*/ - timing_bnt = 1; /*branch not taken*/ - timing_int = 6; - timing_int_rm = 11; - timing_int_v86 = 54; - timing_int_pm = 25; - timing_int_pm_outer = 42; - timing_iret_rm = 7; - timing_iret_v86 = 27; /*unknown*/ - timing_iret_pm = 10; - timing_iret_pm_outer = 27; - timing_call_rm = 4; - timing_call_pm = 4; - timing_call_pm_gate = 22; - timing_call_pm_gate_inner = 44; - timing_retf_rm = 4; - timing_retf_pm = 4; - timing_retf_pm_outer = 23; - timing_jmp_rm = 3; - timing_jmp_pm = 3; - timing_jmp_pm_gate = 18; - timing_misaligned = 3; - cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_MMX; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE; - codegen_timing_set(&codegen_timing_pentium); - break; + case CPU_PENTIUMMMX: + x86_setopcodes(ops_386, ops_pentiummmx_0f, dynarec_ops_386, dynarec_ops_pentiummmx_0f); + timing_rr = 1; /*register dest - register src*/ + timing_rm = 2; /*register dest - memory src*/ + timing_mr = 3; /*memory dest - register src*/ + timing_mm = 3; + timing_rml = 2; /*register dest - memory src long*/ + timing_mrl = 3; /*memory dest - register src long*/ + timing_mml = 3; + timing_bt = 0; /*branch taken*/ + timing_bnt = 1; /*branch not taken*/ + timing_int = 6; + timing_int_rm = 11; + timing_int_v86 = 54; + timing_int_pm = 25; + timing_int_pm_outer = 42; + timing_iret_rm = 7; + timing_iret_v86 = 27; /*unknown*/ + timing_iret_pm = 10; + timing_iret_pm_outer = 27; + timing_call_rm = 4; + timing_call_pm = 4; + timing_call_pm_gate = 22; + timing_call_pm_gate_inner = 44; + timing_retf_rm = 4; + timing_retf_pm = 4; + timing_retf_pm_outer = 23; + timing_jmp_rm = 3; + timing_jmp_pm = 3; + timing_jmp_pm_gate = 18; + timing_misaligned = 3; + cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_MMX; + msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); + cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE; + codegen_timing_set(&codegen_timing_pentium); + break; - case CPU_Cx6x86:x86_setopcodes(ops_386, ops_c6x86_0f, dynarec_ops_386, dynarec_ops_c6x86_0f); - 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_features = CPU_FEATURE_RDTSC; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - codegen_timing_set(&codegen_timing_686); - CPUID = 0; /*Disabled on powerup by default*/ - break; + case CPU_Cx6x86: + x86_setopcodes(ops_386, ops_c6x86_0f, dynarec_ops_386, dynarec_ops_c6x86_0f); + 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_features = CPU_FEATURE_RDTSC; + msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); + codegen_timing_set(&codegen_timing_686); + CPUID = 0; /*Disabled on powerup by default*/ + break; - case CPU_Cx6x86L:x86_setopcodes(ops_386, ops_pentium_0f, dynarec_ops_386, dynarec_ops_pentium_0f); - 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_features = CPU_FEATURE_RDTSC; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - codegen_timing_set(&codegen_timing_686); - ccr4 = 0x80; - break; + case CPU_Cx6x86L: + x86_setopcodes(ops_386, ops_pentium_0f, dynarec_ops_386, dynarec_ops_pentium_0f); + 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_features = CPU_FEATURE_RDTSC; + msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); + codegen_timing_set(&codegen_timing_686); + ccr4 = 0x80; + break; - case CPU_CxGX1:x86_setopcodes(ops_386, ops_pentium_0f, dynarec_ops_386, dynarec_ops_pentium_0f); - 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*/ - cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_PCE; - codegen_timing_set(&codegen_timing_686); - break; + case CPU_CxGX1: + x86_setopcodes(ops_386, ops_pentium_0f, dynarec_ops_386, dynarec_ops_pentium_0f); + 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*/ + cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4; + msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); + cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_PCE; + codegen_timing_set(&codegen_timing_686); + break; - case CPU_Cx6x86MX: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; - 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_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_MMX; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_PCE; - codegen_timing_set(&codegen_timing_686); - ccr4 = 0x80; - break; + case CPU_Cx6x86MX: + 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; + 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_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_MMX; + msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); + cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_PCE; + codegen_timing_set(&codegen_timing_686); + ccr4 = 0x80; + break; - case CPU_K6:x86_setopcodes(ops_386, ops_pentiummmx_0f, dynarec_ops_386, dynarec_ops_pentiummmx_0f); - timing_rr = 1; /*register dest - register src*/ - timing_rm = 2; /*register dest - memory src*/ - timing_mr = 3; /*memory dest - register src*/ - timing_mm = 3; - timing_rml = 2; /*register dest - memory src long*/ - timing_mrl = 3; /*memory dest - register src long*/ - timing_mml = 3; - timing_bt = 0; /*branch taken*/ - timing_bnt = 1; /*branch not taken*/ - timing_int = 6; - timing_int_rm = 11; - timing_int_v86 = 54; - timing_int_pm = 25; - timing_int_pm_outer = 42; - timing_iret_rm = 7; - timing_iret_v86 = 27; /*unknown*/ - timing_iret_pm = 10; - timing_iret_pm_outer = 27; - timing_call_rm = 4; - timing_call_pm = 4; - timing_call_pm_gate = 22; - timing_call_pm_gate_inner = 44; - timing_retf_rm = 4; - timing_retf_pm = 4; - timing_retf_pm_outer = 23; - timing_jmp_rm = 3; - timing_jmp_pm = 3; - timing_jmp_pm_gate = 18; - timing_misaligned = 3; - cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_MMX; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE; - codegen_timing_set(&codegen_timing_k6); - break; + case CPU_K6: + x86_setopcodes(ops_386, ops_pentiummmx_0f, dynarec_ops_386, dynarec_ops_pentiummmx_0f); + timing_rr = 1; /*register dest - register src*/ + timing_rm = 2; /*register dest - memory src*/ + timing_mr = 3; /*memory dest - register src*/ + timing_mm = 3; + timing_rml = 2; /*register dest - memory src long*/ + timing_mrl = 3; /*memory dest - register src long*/ + timing_mml = 3; + timing_bt = 0; /*branch taken*/ + timing_bnt = 1; /*branch not taken*/ + timing_int = 6; + timing_int_rm = 11; + timing_int_v86 = 54; + timing_int_pm = 25; + timing_int_pm_outer = 42; + timing_iret_rm = 7; + timing_iret_v86 = 27; /*unknown*/ + timing_iret_pm = 10; + timing_iret_pm_outer = 27; + timing_call_rm = 4; + timing_call_pm = 4; + timing_call_pm_gate = 22; + timing_call_pm_gate_inner = 44; + timing_retf_rm = 4; + timing_retf_pm = 4; + timing_retf_pm_outer = 23; + timing_jmp_rm = 3; + timing_jmp_pm = 3; + timing_jmp_pm_gate = 18; + timing_misaligned = 3; + cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_MMX; + msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); + cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE; + codegen_timing_set(&codegen_timing_k6); + break; - case CPU_K6_2: - case CPU_K6_3: - case CPU_K6_2P: - case CPU_K6_3P:x86_setopcodes(ops_386, ops_winchip2_0f, dynarec_ops_386, dynarec_ops_winchip2_0f); - timing_rr = 1; /*register dest - register src*/ - timing_rm = 2; /*register dest - memory src*/ - timing_mr = 3; /*memory dest - register src*/ - timing_mm = 3; - timing_rml = 2; /*register dest - memory src long*/ - timing_mrl = 3; /*memory dest - register src long*/ - timing_mml = 3; - timing_bt = 0; /*branch taken*/ - timing_bnt = 1; /*branch not taken*/ - timing_int = 6; - timing_int_rm = 11; - timing_int_v86 = 54; - timing_int_pm = 25; - timing_int_pm_outer = 42; - timing_iret_rm = 7; - timing_iret_v86 = 27; /*unknown*/ - timing_iret_pm = 10; - timing_iret_pm_outer = 27; - timing_call_rm = 4; - timing_call_pm = 4; - timing_call_pm_gate = 22; - timing_call_pm_gate_inner = 44; - timing_retf_rm = 4; - timing_retf_pm = 4; - timing_retf_pm_outer = 23; - timing_jmp_rm = 3; - timing_jmp_pm = 3; - timing_jmp_pm_gate = 18; - timing_misaligned = 3; - cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_MMX | CPU_FEATURE_3DNOW; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE; - codegen_timing_set(&codegen_timing_k6); - break; + case CPU_K6_2: + case CPU_K6_3: + case CPU_K6_2P: + case CPU_K6_3P: + x86_setopcodes(ops_386, ops_winchip2_0f, dynarec_ops_386, dynarec_ops_winchip2_0f); + timing_rr = 1; /*register dest - register src*/ + timing_rm = 2; /*register dest - memory src*/ + timing_mr = 3; /*memory dest - register src*/ + timing_mm = 3; + timing_rml = 2; /*register dest - memory src long*/ + timing_mrl = 3; /*memory dest - register src long*/ + timing_mml = 3; + timing_bt = 0; /*branch taken*/ + timing_bnt = 1; /*branch not taken*/ + timing_int = 6; + timing_int_rm = 11; + timing_int_v86 = 54; + timing_int_pm = 25; + timing_int_pm_outer = 42; + timing_iret_rm = 7; + timing_iret_v86 = 27; /*unknown*/ + timing_iret_pm = 10; + timing_iret_pm_outer = 27; + timing_call_rm = 4; + timing_call_pm = 4; + timing_call_pm_gate = 22; + timing_call_pm_gate_inner = 44; + timing_retf_rm = 4; + timing_retf_pm = 4; + timing_retf_pm_outer = 23; + timing_jmp_rm = 3; + timing_jmp_pm = 3; + timing_jmp_pm_gate = 18; + timing_misaligned = 3; + cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_MMX | + CPU_FEATURE_3DNOW; + msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); + cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE; + codegen_timing_set(&codegen_timing_k6); + break; - case CPU_PENTIUMPRO: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; - 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 = 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_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_CX8 | CPU_FEATURE_SYSCALL; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE; - codegen_timing_set(&codegen_timing_p6); - break; + case CPU_PENTIUMPRO: + 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; + 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 = 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_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_CX8 | + CPU_FEATURE_SYSCALL; + msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); + cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE; + codegen_timing_set(&codegen_timing_p6); + break; - case CPU_PENTIUM_2: - case CPU_CELERON: - case CPU_CELERON_A: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; - 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 = 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_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_CX8 | CPU_FEATURE_MMX | CPU_FEATURE_SYSCALL; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE; - codegen_timing_set(&codegen_timing_p6); - break; + case CPU_PENTIUM_2: + case CPU_CELERON: + case CPU_CELERON_A: + 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; + 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 = 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_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_CX8 | + CPU_FEATURE_MMX | CPU_FEATURE_SYSCALL; + msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); + cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE; + codegen_timing_set(&codegen_timing_p6); + break; - case CPU_CYRIX_III:x86_setopcodes(ops_386, ops_winchip2_0f, dynarec_ops_386, dynarec_ops_winchip2_0f); - 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 = 1; /*branch taken*/ - timing_bnt = 1; /*branch not taken*/ - cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MMX | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_3DNOW; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 18) | (1 << 19) | (1 << 20) | (1 << 21); - cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE; - /*unknown*/ - timing_int_rm = 26; - timing_int_v86 = 82; - timing_int_pm = 44; - timing_int_pm_outer = 71; - timing_iret_rm = 7; - timing_iret_v86 = 26; - timing_iret_pm = 10; - timing_iret_pm_outer = 26; - timing_call_rm = 4; - timing_call_pm = 15; - timing_call_pm_gate = 26; - timing_call_pm_gate_inner = 35; - timing_retf_rm = 4; - timing_retf_pm = 7; - timing_retf_pm_outer = 23; - timing_jmp_rm = 5; - timing_jmp_pm = 7; - timing_jmp_pm_gate = 17; - timing_misaligned = 2; - cpu_cyrix_alignment = 1; - codegen_timing_set(&codegen_timing_cyrixiii); - break; + case CPU_CYRIX_III: + x86_setopcodes(ops_386, ops_winchip2_0f, dynarec_ops_386, dynarec_ops_winchip2_0f); + 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 = 1; /*branch taken*/ + timing_bnt = 1; /*branch not taken*/ + cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MMX | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_3DNOW; + msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 18) | (1 << 19) | (1 << 20) | (1 << 21); + cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE; + /*unknown*/ + timing_int_rm = 26; + timing_int_v86 = 82; + timing_int_pm = 44; + timing_int_pm_outer = 71; + timing_iret_rm = 7; + timing_iret_v86 = 26; + timing_iret_pm = 10; + timing_iret_pm_outer = 26; + timing_call_rm = 4; + timing_call_pm = 15; + timing_call_pm_gate = 26; + timing_call_pm_gate_inner = 35; + timing_retf_rm = 4; + timing_retf_pm = 7; + timing_retf_pm_outer = 23; + timing_jmp_rm = 5; + timing_jmp_pm = 7; + timing_jmp_pm_gate = 17; + timing_misaligned = 2; + cpu_cyrix_alignment = 1; + codegen_timing_set(&codegen_timing_cyrixiii); + break; - default:fatal("cpu_set : unknown CPU type %i\n", cpu_s->cpu_type); - } + default: + fatal("cpu_set : unknown CPU type %i\n", cpu_s->cpu_type); + } - switch (fpu_type) { - case FPU_NONE:break; + switch (fpu_type) { + case FPU_NONE: + break; - case FPU_8087:x87_timings = x87_timings_8087; - break; + case FPU_8087: + x87_timings = x87_timings_8087; + break; - case FPU_287:x87_timings = x87_timings_287; - break; + case FPU_287: + x87_timings = x87_timings_287; + break; - case FPU_287XL: - case FPU_387:x87_timings = x87_timings_387; - break; + case FPU_287XL: + case FPU_387: + x87_timings = x87_timings_387; + break; - default:x87_timings = x87_timings_486; - break; - } + default: + x87_timings = x87_timings_486; + break; + } } void cpu_CPUID() { - switch (models[model]->cpu[cpu_manufacturer].cpus[cpu].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; + switch (models[model]->cpu[cpu_manufacturer].cpus[cpu].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_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_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_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 (cpu_has_feature(CPU_FEATURE_CX8)) - EDX |= CPUID_CMPXCHG8B; - if (msr.fcr & (1 << 9)) - EDX |= CPUID_MMX; - } 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 (cpu_has_feature(CPU_FEATURE_CX8)) + EDX |= CPUID_CMPXCHG8B; + if (msr.fcr & (1 << 9)) + EDX |= CPUID_MMX; + } else + EAX = EBX = ECX = EDX = 0; + break; - case CPU_WINCHIP2: - switch (EAX) { - case 0:EAX = 1; - if (msr.fcr2 & (1 << 14)) { - EBX = msr.fcr3 >> 32; - ECX = msr.fcr3 & 0xffffffff; - EDX = msr.fcr2 >> 32; - } else { - EBX = 0x746e6543; /*CentaurHauls*/ - ECX = 0x736c7561; - EDX = 0x48727561; - } - break; - case 1:EAX = 0x580; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR; - if (cpu_has_feature(CPU_FEATURE_CX8)) - EDX |= CPUID_CMPXCHG8B; - if (msr.fcr & (1 << 9)) - EDX |= CPUID_MMX; - break; - case 0x80000000:EAX = 0x80000005; - break; - case 0x80000001:EAX = 0x580; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR; - if (cpu_has_feature(CPU_FEATURE_CX8)) - EDX |= CPUID_CMPXCHG8B; - if (msr.fcr & (1 << 9)) - EDX |= CPUID_MMX; - if (cpu_has_feature(CPU_FEATURE_3DNOW)) - EDX |= CPUID_3DNOW; - break; + case CPU_WINCHIP2: + switch (EAX) { + case 0: + EAX = 1; + if (msr.fcr2 & (1 << 14)) { + EBX = msr.fcr3 >> 32; + ECX = msr.fcr3 & 0xffffffff; + EDX = msr.fcr2 >> 32; + } else { + EBX = 0x746e6543; /*CentaurHauls*/ + ECX = 0x736c7561; + EDX = 0x48727561; + } + break; + case 1: + EAX = 0x580; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR; + if (cpu_has_feature(CPU_FEATURE_CX8)) + EDX |= CPUID_CMPXCHG8B; + if (msr.fcr & (1 << 9)) + EDX |= CPUID_MMX; + break; + case 0x80000000: + EAX = 0x80000005; + break; + case 0x80000001: + EAX = 0x580; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR; + if (cpu_has_feature(CPU_FEATURE_CX8)) + EDX |= CPUID_CMPXCHG8B; + if (msr.fcr & (1 << 9)) + EDX |= CPUID_MMX; + if (cpu_has_feature(CPU_FEATURE_3DNOW)) + EDX |= CPUID_3DNOW; + break; - case 0x80000002: /*Processor name string*/ - EAX = 0x20544449; /*IDT WinChip 2-3D*/ - EBX = 0x436e6957; - ECX = 0x20706968; - EDX = 0x44332d32; - break; + case 0x80000002: /*Processor name string*/ + EAX = 0x20544449; /*IDT WinChip 2-3D*/ + EBX = 0x436e6957; + ECX = 0x20706968; + EDX = 0x44332d32; + break; - case 0x80000005: /*Cache information*/ - EBX = 0x08800880; /*TLBs*/ - ECX = 0x20040120; /*L1 data cache*/ - EDX = 0x20020120; /*L1 instruction cache*/ - break; + case 0x80000005: /*Cache information*/ + EBX = 0x08800880; /*TLBs*/ + ECX = 0x20040120; /*L1 data cache*/ + EDX = 0x20020120; /*L1 instruction cache*/ + break; - default:EAX = EBX = ECX = EDX = 0; - break; - } - break; + default: + EAX = EBX = ECX = EDX = 0; + break; + } + 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; + 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; - 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_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_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_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_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; + 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; - case CPU_K6: - switch (EAX) { - case 0:EAX = 1; - EBX = 0x68747541; /*AuthenticAMD*/ - ECX = 0x444d4163; - EDX = 0x69746e65; - break; - case 1:EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; - break; - case 0x80000000:EAX = 0x80000005; - break; - case 0x80000001:EAX = CPUID + 0x100; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; - break; + case CPU_K6: + switch (EAX) { + case 0: + EAX = 1; + EBX = 0x68747541; /*AuthenticAMD*/ + ECX = 0x444d4163; + EDX = 0x69746e65; + break; + case 1: + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; + break; + case 0x80000000: + EAX = 0x80000005; + break; + case 0x80000001: + EAX = CPUID + 0x100; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; + break; - case 0x80000002: /*Processor name string*/ - EAX = 0x2d444d41; /*AMD-K6tm w/ mult*/ - EBX = 0x6d74364b; - ECX = 0x202f7720; - EDX = 0x746c756d; - break; + case 0x80000002: /*Processor name string*/ + EAX = 0x2d444d41; /*AMD-K6tm w/ mult*/ + EBX = 0x6d74364b; + ECX = 0x202f7720; + EDX = 0x746c756d; + break; - case 0x80000003: /*Processor name string*/ - EAX = 0x64656d69; /*imedia extension*/ - EBX = 0x65206169; - ECX = 0x6e657478; - EDX = 0x6e6f6973; - break; + case 0x80000003: /*Processor name string*/ + EAX = 0x64656d69; /*imedia extension*/ + EBX = 0x65206169; + ECX = 0x6e657478; + EDX = 0x6e6f6973; + break; - case 0x80000004: /*Processor name string*/ - EAX = 0x00000073; /*s*/ - EBX = 0x00000000; - ECX = 0x00000000; - EDX = 0x00000000; - break; + case 0x80000004: /*Processor name string*/ + EAX = 0x00000073; /*s*/ + EBX = 0x00000000; + ECX = 0x00000000; + EDX = 0x00000000; + break; - case 0x80000005: /*Cache information*/ - EBX = 0x02800140; /*TLBs*/ - ECX = 0x20020220; /*L1 data cache*/ - EDX = 0x20020220; /*L1 instruction cache*/ - break; + case 0x80000005: /*Cache information*/ + EBX = 0x02800140; /*TLBs*/ + ECX = 0x20020220; /*L1 data cache*/ + EDX = 0x20020220; /*L1 instruction cache*/ + break; - default:EAX = EBX = ECX = EDX = 0; - break; - } - break; + default: + EAX = EBX = ECX = EDX = 0; + break; + } + break; - case CPU_K6_2: - switch (EAX) { - case 0:EAX = 1; - EBX = 0x68747541; /*AuthenticAMD*/ - ECX = 0x444d4163; - EDX = 0x69746e65; - break; - case 1:EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; - break; - case 0x80000000:EAX = 0x80000005; - break; - case 0x80000001:EAX = CPUID + 0x100; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_3DNOW; - break; + case CPU_K6_2: + switch (EAX) { + case 0: + EAX = 1; + EBX = 0x68747541; /*AuthenticAMD*/ + ECX = 0x444d4163; + EDX = 0x69746e65; + break; + case 1: + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; + break; + case 0x80000000: + EAX = 0x80000005; + break; + case 0x80000001: + EAX = CPUID + 0x100; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX | + CPUID_3DNOW; + break; - case 0x80000002: /*Processor name string*/ - EAX = 0x2d444d41; /*AMD-K6(tm) 3D pr*/ - EBX = 0x7428364b; - ECX = 0x3320296d; - EDX = 0x72702044; - break; + case 0x80000002: /*Processor name string*/ + EAX = 0x2d444d41; /*AMD-K6(tm) 3D pr*/ + EBX = 0x7428364b; + ECX = 0x3320296d; + EDX = 0x72702044; + break; - case 0x80000003: /*Processor name string*/ - EAX = 0x7365636f; /*ocessor*/ - EBX = 0x00726f73; - ECX = 0x00000000; - EDX = 0x00000000; - break; + case 0x80000003: /*Processor name string*/ + EAX = 0x7365636f; /*ocessor*/ + EBX = 0x00726f73; + ECX = 0x00000000; + EDX = 0x00000000; + break; - case 0x80000005: /*Cache information*/ - EBX = 0x02800140; /*TLBs*/ - ECX = 0x20020220; /*L1 data cache*/ - EDX = 0x20020220; /*L1 instruction cache*/ - break; + case 0x80000005: /*Cache information*/ + EBX = 0x02800140; /*TLBs*/ + ECX = 0x20020220; /*L1 data cache*/ + EDX = 0x20020220; /*L1 instruction cache*/ + break; - default:EAX = EBX = ECX = EDX = 0; - break; - } - break; + default: + EAX = EBX = ECX = EDX = 0; + break; + } + break; - case CPU_K6_3: - switch (EAX) { - case 0:EAX = 1; - EBX = 0x68747541; /*AuthenticAMD*/ - ECX = 0x444d4163; - EDX = 0x69746e65; - break; - case 1:EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; - break; - case 0x80000000:EAX = 0x80000006; - break; - case 0x80000001:EAX = CPUID + 0x100; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_3DNOW; - break; + case CPU_K6_3: + switch (EAX) { + case 0: + EAX = 1; + EBX = 0x68747541; /*AuthenticAMD*/ + ECX = 0x444d4163; + EDX = 0x69746e65; + break; + case 1: + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; + break; + case 0x80000000: + EAX = 0x80000006; + break; + case 0x80000001: + EAX = CPUID + 0x100; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX | + CPUID_3DNOW; + break; - case 0x80000002: /*Processor name string*/ - EAX = 0x2d444d41; /*AMD-K6(tm) 3D+ P*/ - EBX = 0x7428364b; - ECX = 0x3320296d; - EDX = 0x50202b44; - break; + case 0x80000002: /*Processor name string*/ + EAX = 0x2d444d41; /*AMD-K6(tm) 3D+ P*/ + EBX = 0x7428364b; + ECX = 0x3320296d; + EDX = 0x50202b44; + break; - case 0x80000003: /*Processor name string*/ - EAX = 0x65636f72; /*rocessor*/ - EBX = 0x726f7373; - ECX = 0x00000000; - EDX = 0x00000000; - break; + case 0x80000003: /*Processor name string*/ + EAX = 0x65636f72; /*rocessor*/ + EBX = 0x726f7373; + ECX = 0x00000000; + EDX = 0x00000000; + break; - case 0x80000005: /*Cache information*/ - EBX = 0x02800140; /*TLBs*/ - ECX = 0x20020220; /*L1 data cache*/ - EDX = 0x20020220; /*L1 instruction cache*/ - break; + case 0x80000005: /*Cache information*/ + EBX = 0x02800140; /*TLBs*/ + ECX = 0x20020220; /*L1 data cache*/ + EDX = 0x20020220; /*L1 instruction cache*/ + break; - case 0x80000006: /*L2 Cache information*/ - ECX = 0x01004220; - break; + case 0x80000006: /*L2 Cache information*/ + ECX = 0x01004220; + break; - default:EAX = EBX = ECX = EDX = 0; - break; - } - break; + default: + EAX = EBX = ECX = EDX = 0; + break; + } + break; - case CPU_K6_2P: - case CPU_K6_3P: - switch (EAX) { - case 0:EAX = 1; - EBX = 0x68747541; /*AuthenticAMD*/ - ECX = 0x444d4163; - EDX = 0x69746e65; - break; - case 1:EAX = CPUID; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; - break; - case 0x80000000:EAX = 0x80000007; - break; - case 0x80000001:EAX = CPUID + 0x100; - EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_3DNOW; - break; + case CPU_K6_2P: + case CPU_K6_3P: + switch (EAX) { + case 0: + EAX = 1; + EBX = 0x68747541; /*AuthenticAMD*/ + ECX = 0x444d4163; + EDX = 0x69746e65; + break; + case 1: + EAX = CPUID; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX; + break; + case 0x80000000: + EAX = 0x80000007; + break; + case 0x80000001: + EAX = CPUID + 0x100; + EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX | + CPUID_3DNOW; + break; - case 0x80000002: /*Processor name string*/ - EAX = 0x2d444d41; /*AMD-K6(tm)-III P*/ - EBX = 0x7428364b; - ECX = 0x492d296d; - EDX = 0x50204949; - break; + case 0x80000002: /*Processor name string*/ + EAX = 0x2d444d41; /*AMD-K6(tm)-III P*/ + EBX = 0x7428364b; + ECX = 0x492d296d; + EDX = 0x50204949; + break; - case 0x80000003: /*Processor name string*/ - EAX = 0x65636f72; /*rocessor*/ - EBX = 0x726f7373; - ECX = 0x00000000; - EDX = 0x00000000; - break; + case 0x80000003: /*Processor name string*/ + EAX = 0x65636f72; /*rocessor*/ + EBX = 0x726f7373; + ECX = 0x00000000; + EDX = 0x00000000; + break; - case 0x80000005: /*Cache information*/ - EBX = 0x02800140; /*TLBs*/ - ECX = 0x20020220; /*L1 data cache*/ - EDX = 0x20020220; /*L1 instruction cache*/ - break; + case 0x80000005: /*Cache information*/ + EBX = 0x02800140; /*TLBs*/ + ECX = 0x20020220; /*L1 data cache*/ + EDX = 0x20020220; /*L1 instruction cache*/ + break; - case 0x80000006: /*L2 Cache information*/ - if (models[model]->cpu[cpu_manufacturer].cpus[cpu].cpu_type == CPU_K6_3P) - ECX = 0x01004220; - else - ECX = 0x00804220; - break; + case 0x80000006: /*L2 Cache information*/ + if (models[model]->cpu[cpu_manufacturer].cpus[cpu].cpu_type == CPU_K6_3P) + ECX = 0x01004220; + else + ECX = 0x00804220; + break; - case 0x80000007: /*PowerNow information*/ - EDX = 7; - break; + case 0x80000007: /*PowerNow information*/ + EDX = 7; + break; - default:EAX = EBX = ECX = EDX = 0; - break; - } - break; + default: + EAX = EBX = ECX = EDX = 0; + break; + } + break; - 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_CMOV | CPUID_SEP; - } else if (EAX == 2) { - EAX = 0x03020101; - EBX = 0; - ECX = 0; - EDX = 0x06040a42; - } else - EAX = EBX = ECX = EDX = 0; - break; + 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_CMOV | + CPUID_SEP; + } else if (EAX == 2) { + EAX = 0x03020101; + EBX = 0; + ECX = 0; + EDX = 0x06040a42; + } else + EAX = EBX = ECX = EDX = 0; + break; - case CPU_PENTIUM_2: - case CPU_CELERON: - case CPU_CELERON_A: - 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_CMOV | CPUID_MMX | CPUID_SEP; - } else if (EAX == 2) { - EAX = 0x03020101; - EBX = 0; - ECX = 0; - if (models[model]->cpu[cpu_manufacturer].cpus[cpu].cpu_type == CPU_PENTIUM_2) - EDX = 0x08040c43; /*512kb L2 cache*/ - else if (models[model]->cpu[cpu_manufacturer].cpus[cpu].cpu_type == CPU_CELERON) - EDX = 0x08040c40; /*No L2 cache*/ - else - EDX = 0x08040c41; /*128kb L2 cache*/ - } else - EAX = EBX = ECX = EDX = 0; - break; + case CPU_PENTIUM_2: + case CPU_CELERON: + case CPU_CELERON_A: + 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_CMOV | + CPUID_MMX | CPUID_SEP; + } else if (EAX == 2) { + EAX = 0x03020101; + EBX = 0; + ECX = 0; + if (models[model]->cpu[cpu_manufacturer].cpus[cpu].cpu_type == CPU_PENTIUM_2) + EDX = 0x08040c43; /*512kb L2 cache*/ + else if (models[model]->cpu[cpu_manufacturer].cpus[cpu].cpu_type == CPU_CELERON) + EDX = 0x08040c40; /*No L2 cache*/ + else + EDX = 0x08040c41; /*128kb L2 cache*/ + } else + EAX = EBX = ECX = EDX = 0; + break; - case CPU_CYRIX_III: - switch (EAX) { - case 0:EAX = 1; - EBX = 0x746e6543; /*CentaurHauls*/ - ECX = 0x736c7561; - EDX = 0x48727561; - break; - case 1:EAX = models[model]->cpu[cpu_manufacturer].cpus[cpu].cpuid_model; - EBX = ECX = 0; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR; - if (cpu_has_feature(CPU_FEATURE_CX8)) - EDX |= CPUID_CMPXCHG8B; - if (msr.fcr & (1 << 9)) - EDX |= CPUID_MMX; - break; - case 0x80000000:EAX = 0x80000006; - break; - case 0x80000001:EAX = models[model]->cpu[cpu_manufacturer].cpus[cpu].edx_reset; - EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR; - if (cpu_has_feature(CPU_FEATURE_CX8)) - EDX |= CPUID_CMPXCHG8B; - if (msr.fcr & (1 << 9)) - EDX |= CPUID_MMX; - if (cpu_has_feature(CPU_FEATURE_3DNOW)) - EDX |= CPUID_3DNOW; - break; + case CPU_CYRIX_III: + switch (EAX) { + case 0: + EAX = 1; + EBX = 0x746e6543; /*CentaurHauls*/ + ECX = 0x736c7561; + EDX = 0x48727561; + break; + case 1: + EAX = models[model]->cpu[cpu_manufacturer].cpus[cpu].cpuid_model; + EBX = ECX = 0; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR; + if (cpu_has_feature(CPU_FEATURE_CX8)) + EDX |= CPUID_CMPXCHG8B; + if (msr.fcr & (1 << 9)) + EDX |= CPUID_MMX; + break; + case 0x80000000: + EAX = 0x80000006; + break; + case 0x80000001: + EAX = models[model]->cpu[cpu_manufacturer].cpus[cpu].edx_reset; + EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR; + if (cpu_has_feature(CPU_FEATURE_CX8)) + EDX |= CPUID_CMPXCHG8B; + if (msr.fcr & (1 << 9)) + EDX |= CPUID_MMX; + if (cpu_has_feature(CPU_FEATURE_3DNOW)) + EDX |= CPUID_3DNOW; + break; - case 0x80000002: /*Processor name string*/ - if (models[model]->cpu[cpu_manufacturer].cpus[cpu].cpuid_model >= 0x670) { - EAX = 0x20414956; /*VIA Samuel 2*/ - EBX = 0x756d6153; - ECX = 0x32206c65; - EDX = 0x00000000; - } else { - EAX = 0x20414956; /*VIA SamuelM*/ - EBX = 0x756d6153; - ECX = 0x004d6c65; - EDX = 0x00000000; - } - break; + case 0x80000002: /*Processor name string*/ + if (models[model]->cpu[cpu_manufacturer].cpus[cpu].cpuid_model >= 0x670) { + EAX = 0x20414956; /*VIA Samuel 2*/ + EBX = 0x756d6153; + ECX = 0x32206c65; + EDX = 0x00000000; + } else { + EAX = 0x20414956; /*VIA SamuelM*/ + EBX = 0x756d6153; + ECX = 0x004d6c65; + EDX = 0x00000000; + } + break; - case 0x80000005: /*Cache information*/ - EBX = 0x08800880; /*TLBs*/ - ECX = 0x40040120; /*L1 data cache*/ - EDX = 0x40020120; /*L1 instruction cache*/ - break; + case 0x80000005: /*Cache information*/ + EBX = 0x08800880; /*TLBs*/ + ECX = 0x40040120; /*L1 data cache*/ + EDX = 0x40020120; /*L1 instruction cache*/ + break; - case 0x80000006: /*L2 Cache information*/ - if (models[model]->cpu[cpu_manufacturer].cpus[cpu].cpuid_model >= 0x670) - ECX = 0x40040120; /*L2 cache*/ - else - ECX = 0; - EAX = EBX = EDX = 0; - break; + case 0x80000006: /*L2 Cache information*/ + if (models[model]->cpu[cpu_manufacturer].cpus[cpu].cpuid_model >= 0x670) + ECX = 0x40040120; /*L2 cache*/ + else + ECX = 0; + EAX = EBX = EDX = 0; + break; - default:EAX = EBX = ECX = EDX = 0; - break; - } - break; - } + default: + EAX = EBX = ECX = EDX = 0; + break; + } + break; + } } void cpu_RDMSR() { - switch (models[model]->cpu[cpu_manufacturer].cpus[cpu].cpu_type) { - case CPU_WINCHIP: - case CPU_WINCHIP2: - case CPU_CYRIX_III: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; + switch (models[model]->cpu[cpu_manufacturer].cpus[cpu].cpu_type) { + case CPU_WINCHIP: + case CPU_WINCHIP2: + case CPU_CYRIX_III: + 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; - 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; - case CPU_K6: - case CPU_K6_2: - case CPU_K6_3: - case CPU_K6_2P: - case CPU_K6_3P:EAX = EDX = 0; - switch (ECX) { - case 0x10:EAX = tsc & 0xffffffff; - EDX = tsc >> 32; - break; - } - break; - case CPU_PENTIUMPRO: - case CPU_PENTIUM_2: - case CPU_CELERON: - case CPU_CELERON_A:EAX = EDX = 0; - switch (ECX) { - case 0x10:EAX = tsc & 0xffffffff; - EDX = tsc >> 32; - break; + 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; + case CPU_K6: + case CPU_K6_2: + case CPU_K6_3: + case CPU_K6_2P: + case CPU_K6_3P: + EAX = EDX = 0; + switch (ECX) { + case 0x10: + EAX = tsc & 0xffffffff; + EDX = tsc >> 32; + break; + } + break; + case CPU_PENTIUMPRO: + case CPU_PENTIUM_2: + case CPU_CELERON: + case CPU_CELERON_A: + EAX = EDX = 0; + switch (ECX) { + case 0x10: + EAX = tsc & 0xffffffff; + EDX = tsc >> 32; + break; - case 0x174:EAX = sysenter_cs; - EDX = 0; - break; - case 0x175:EAX = sysenter_esp; - EDX = 0; - break; - case 0x176:EAX = sysenter_eip; - EDX = 0; - break; - } - break; - } + case 0x174: + EAX = sysenter_cs; + EDX = 0; + break; + case 0x175: + EAX = sysenter_esp; + EDX = 0; + break; + case 0x176: + EAX = sysenter_eip; + EDX = 0; + break; + } + break; + } } void cpu_WRMSR() { - switch (models[model]->cpu[cpu_manufacturer].cpus[cpu].cpu_type) { - case CPU_WINCHIP: - case CPU_WINCHIP2: - case CPU_CYRIX_III: - 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; - if (EAX & (1 << 9)) - cpu_features |= CPU_FEATURE_MMX; - else - cpu_features &= ~CPU_FEATURE_MMX; - if (EAX & (1 << 1)) - cpu_features |= CPU_FEATURE_CX8; - else - cpu_features &= ~CPU_FEATURE_CX8; - if ((EAX & (1 << 20)) && models[model]->cpu[cpu_manufacturer].cpus[cpu].cpu_type >= CPU_WINCHIP2) - cpu_features |= CPU_FEATURE_3DNOW; - else - cpu_features &= ~CPU_FEATURE_3DNOW; - if (EAX & (1 << 29)) - CPUID = 0; - else - CPUID = models[model]->cpu[cpu_manufacturer].cpus[cpu].cpuid_model; - break; - case 0x108:msr.fcr2 = EAX | ((uint64_t)EDX << 32); - break; - case 0x109:msr.fcr3 = EAX | ((uint64_t)EDX << 32); - break; - } - break; + switch (models[model]->cpu[cpu_manufacturer].cpus[cpu].cpu_type) { + case CPU_WINCHIP: + case CPU_WINCHIP2: + case CPU_CYRIX_III: + 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; + if (EAX & (1 << 9)) + cpu_features |= CPU_FEATURE_MMX; + else + cpu_features &= ~CPU_FEATURE_MMX; + if (EAX & (1 << 1)) + cpu_features |= CPU_FEATURE_CX8; + else + cpu_features &= ~CPU_FEATURE_CX8; + if ((EAX & (1 << 20)) && models[model]->cpu[cpu_manufacturer].cpus[cpu].cpu_type >= CPU_WINCHIP2) + cpu_features |= CPU_FEATURE_3DNOW; + else + cpu_features &= ~CPU_FEATURE_3DNOW; + if (EAX & (1 << 29)) + CPUID = 0; + else + CPUID = models[model]->cpu[cpu_manufacturer].cpus[cpu].cpuid_model; + break; + case 0x108: + msr.fcr2 = EAX | ((uint64_t)EDX << 32); + break; + case 0x109: + msr.fcr3 = EAX | ((uint64_t)EDX << 32); + break; + } + break; - 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; - case CPU_K6: - case CPU_K6_2: - case CPU_K6_3: - case CPU_K6_2P: - case CPU_K6_3P: - switch (ECX) { - case 0x10:tsc = EAX | ((uint64_t)EDX << 32); - break; - } - break; - case CPU_PENTIUMPRO: - case CPU_PENTIUM_2: - case CPU_CELERON: - case CPU_CELERON_A: - switch (ECX) { - case 0x10:tsc = EAX | ((uint64_t)EDX << 32); - break; + 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; + case CPU_K6: + case CPU_K6_2: + case CPU_K6_3: + case CPU_K6_2P: + case CPU_K6_3P: + switch (ECX) { + case 0x10: + tsc = EAX | ((uint64_t)EDX << 32); + break; + } + break; + case CPU_PENTIUMPRO: + case CPU_PENTIUM_2: + case CPU_CELERON: + case CPU_CELERON_A: + switch (ECX) { + case 0x10: + tsc = EAX | ((uint64_t)EDX << 32); + break; - case 0x174:sysenter_cs = EAX & 0xffff; - break; - case 0x175:sysenter_esp = EAX; - break; - case 0x176:sysenter_eip = EAX; - break; - } - break; - } + case 0x174: + sysenter_cs = EAX & 0xffff; + break; + case 0x175: + sysenter_esp = EAX; + break; + case 0x176: + sysenter_eip = EAX; + break; + } + break; + } } static int cyrix_addr; -#define CCR1_USE_SMI (1 << 1) -#define CCR1_SMAC (1 << 2) -#define CCR1_SM3 (1 << 7) +#define CCR1_USE_SMI (1 << 1) +#define CCR1_SMAC (1 << 2) +#define CCR1_SM3 (1 << 7) #define CCR3_SMI_LOCK (1 << 0) -#define CCR3_NMI_EN (1 << 1) +#define CCR3_NMI_EN (1 << 1) 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*/ - if ((ccr3 & CCR3_SMI_LOCK) && !(cpu_cur_status & CPU_STATUS_SMM)) - val = (val & ~(CCR1_USE_SMI | CCR1_SMAC | CCR1_SM3)) | (ccr1 & (CCR1_USE_SMI | CCR1_SMAC | CCR1_SM3)); - ccr1 = val; - break; - case 0xc2: /*CCR2*/ - ccr2 = val; - break; - case 0xc3: /*CCR3*/ - if ((ccr3 & CCR3_SMI_LOCK) && !(cpu_cur_status & CPU_STATUS_SMM)) - val = (val & ~(CCR3_NMI_EN)) | (ccr3 & CCR3_NMI_EN) | CCR3_SMI_LOCK; - ccr3 = val; - break; - case 0xcd: - if (!(ccr3 & CCR3_SMI_LOCK) || (cpu_cur_status & CPU_STATUS_SMM)) { - cyrix.arr[3].base = (cyrix.arr[3].base & ~0xff000000) | (val << 24); - cyrix.smhr &= ~SMHR_VALID; - } - break; - case 0xce: - if (!(ccr3 & CCR3_SMI_LOCK) || (cpu_cur_status & CPU_STATUS_SMM)) { - cyrix.arr[3].base = (cyrix.arr[3].base & ~0x00ff0000) | (val << 16); - cyrix.smhr &= ~SMHR_VALID; - } - break; - case 0xcf: - if (!(ccr3 & CCR3_SMI_LOCK) || (cpu_cur_status & CPU_STATUS_SMM)) { - cyrix.arr[3].base = (cyrix.arr[3].base & ~0x0000f000) | ((val & 0xf0) << 8); - if ((val & 0xf) == 0xf) - cyrix.arr[3].size = 1ull << 32; /*4 GB*/ - else if (val & 0xf) - cyrix.arr[3].size = 2048 << (val & 0xf); - else - cyrix.arr[3].size = 0; /*Disabled*/ - cyrix.smhr &= ~SMHR_VALID; - } - break; + if (!(addr & 1)) + cyrix_addr = val; + else + switch (cyrix_addr) { + case 0xc0: /*CCR0*/ + ccr0 = val; + break; + case 0xc1: /*CCR1*/ + if ((ccr3 & CCR3_SMI_LOCK) && !(cpu_cur_status & CPU_STATUS_SMM)) + val = (val & ~(CCR1_USE_SMI | CCR1_SMAC | CCR1_SM3)) | + (ccr1 & (CCR1_USE_SMI | CCR1_SMAC | CCR1_SM3)); + ccr1 = val; + break; + case 0xc2: /*CCR2*/ + ccr2 = val; + break; + case 0xc3: /*CCR3*/ + if ((ccr3 & CCR3_SMI_LOCK) && !(cpu_cur_status & CPU_STATUS_SMM)) + val = (val & ~(CCR3_NMI_EN)) | (ccr3 & CCR3_NMI_EN) | CCR3_SMI_LOCK; + ccr3 = val; + break; + case 0xcd: + if (!(ccr3 & CCR3_SMI_LOCK) || (cpu_cur_status & CPU_STATUS_SMM)) { + cyrix.arr[3].base = (cyrix.arr[3].base & ~0xff000000) | (val << 24); + cyrix.smhr &= ~SMHR_VALID; + } + break; + case 0xce: + if (!(ccr3 & CCR3_SMI_LOCK) || (cpu_cur_status & CPU_STATUS_SMM)) { + cyrix.arr[3].base = (cyrix.arr[3].base & ~0x00ff0000) | (val << 16); + cyrix.smhr &= ~SMHR_VALID; + } + break; + case 0xcf: + if (!(ccr3 & CCR3_SMI_LOCK) || (cpu_cur_status & CPU_STATUS_SMM)) { + cyrix.arr[3].base = (cyrix.arr[3].base & ~0x0000f000) | ((val & 0xf0) << 8); + if ((val & 0xf) == 0xf) + cyrix.arr[3].size = 1ull << 32; /*4 GB*/ + else if (val & 0xf) + cyrix.arr[3].size = 2048 << (val & 0xf); + else + cyrix.arr[3].size = 0; /*Disabled*/ + cyrix.smhr &= ~SMHR_VALID; + } + break; - case 0xe8: /*CCR4*/ - if ((ccr3 & 0xf0) == 0x10) { - ccr4 = val; - if (models[model]->cpu[cpu_manufacturer].cpus[cpu].cpu_type >= CPU_Cx6x86) { - if (val & 0x80) - CPUID = models[model]->cpu[cpu_manufacturer].cpus[cpu].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; - } + case 0xe8: /*CCR4*/ + if ((ccr3 & 0xf0) == 0x10) { + ccr4 = val; + if (models[model]->cpu[cpu_manufacturer].cpus[cpu].cpu_type >= CPU_Cx6x86) { + if (val & 0x80) + CPUID = models[model]->cpu[cpu_manufacturer].cpus[cpu].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 models[model]->cpu[cpu_manufacturer].cpus[cpu].cyrix_id & 0xff; - case 0xff:return models[model]->cpu[cpu_manufacturer].cpus[cpu].cyrix_id >> 8; - } - if (cyrix_addr == 0x20 && models[model]->cpu[cpu_manufacturer].cpus[cpu].cpu_type == CPU_Cx5x86) - return 0xff; - } - return 0xff; + 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 models[model]->cpu[cpu_manufacturer].cpus[cpu].cyrix_id & 0xff; + case 0xff: + return models[model]->cpu[cpu_manufacturer].cpus[cpu].cyrix_id >> 8; + } + if (cyrix_addr == 0x20 && models[model]->cpu[cpu_manufacturer].cpus[cpu].cpu_type == CPU_Cx5x86) + return 0xff; + } + return 0xff; } void x86_setopcodes(OpFn *opcodes, OpFn *opcodes_0f, OpFn *dynarec_opcodes, OpFn *dynarec_opcodes_0f) { - x86_opcodes = opcodes; - x86_opcodes_0f = opcodes_0f; - x86_dynarec_opcodes = dynarec_opcodes; - x86_dynarec_opcodes_0f = dynarec_opcodes_0f; + x86_opcodes = opcodes; + x86_opcodes_0f = opcodes_0f; + x86_dynarec_opcodes = dynarec_opcodes; + x86_dynarec_opcodes_0f = dynarec_opcodes_0f; } void cpu_update_waitstates() { - cpu_s = &models[model]->cpu[cpu_manufacturer].cpus[cpu]; + cpu_s = &models[model]->cpu[cpu_manufacturer].cpus[cpu]; - if (is486) - cpu_prefetch_width = 16; - else - cpu_prefetch_width = cpu_16bitbus ? 2 : 4; + 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; + 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; } void cpu_set_turbo(int turbo) { - if (cpu_turbo != turbo) { - cpu_turbo = turbo; + if (cpu_turbo != turbo) { + cpu_turbo = turbo; - cpu_s = &models[model]->cpu[cpu_manufacturer].cpus[cpu]; - if (cpu_s->cpu_type >= CPU_286) { - if (cpu_turbo) - setpitclock(cpu_turbo_speed); - else - setpitclock(cpu_nonturbo_speed); - } else - setpitclock(14318184.0); - } + cpu_s = &models[model]->cpu[cpu_manufacturer].cpus[cpu]; + if (cpu_s->cpu_type >= CPU_286) { + if (cpu_turbo) + setpitclock(cpu_turbo_speed); + else + setpitclock(cpu_nonturbo_speed); + } else + setpitclock(14318184.0); + } } -int cpu_get_turbo() { - return cpu_turbo; -} +int cpu_get_turbo() { return cpu_turbo; } int cpu_get_speed() { - if (cpu_turbo) - return cpu_turbo_speed; - return cpu_nonturbo_speed; + if (cpu_turbo) + return cpu_turbo_speed; + return cpu_nonturbo_speed; } void cpu_set_nonturbo_divider(int divider) { - if (divider < 2) - cpu_set_turbo(1); - else { - cpu_nonturbo_speed = cpu_turbo_speed / divider; - cpu_set_turbo(0); - } + if (divider < 2) + cpu_set_turbo(1); + else { + cpu_nonturbo_speed = cpu_turbo_speed / divider; + cpu_set_turbo(0); + } } diff --git a/src/cpu/cpu_tables.c b/src/cpu/cpu_tables.c index 9e677058..fc37ce83 100644 --- a/src/cpu/cpu_tables.c +++ b/src/cpu/cpu_tables.c @@ -22,532 +22,646 @@ 17 = 200 MHz */ -FPU fpus_none[] = - { - {"None", "none", FPU_NONE}, - {NULL, NULL, 0} - }; -FPU fpus_8088[] = - { - {"None", "none", FPU_NONE}, - {"8087", "8087", FPU_8087}, - {NULL, NULL, 0} - }; -FPU fpus_80286[] = - { - {"None", "none", FPU_NONE}, - {"287", "287", FPU_287}, - {"287XL", "287xl", FPU_287XL}, - {NULL, NULL, 0} - }; -FPU fpus_80386[] = - { - {"None", "none", FPU_NONE}, - {"387", "387", FPU_387}, - {NULL, NULL, 0} - }; -FPU fpus_builtin[] = - { - {"Built-in", "builtin", FPU_BUILTIN}, - {NULL, NULL, 0} - }; +FPU fpus_none[] = {{"None", "none", FPU_NONE}, {NULL, NULL, 0}}; +FPU fpus_8088[] = {{"None", "none", FPU_NONE}, {"8087", "8087", FPU_8087}, {NULL, NULL, 0}}; +FPU fpus_80286[] = {{"None", "none", FPU_NONE}, {"287", "287", FPU_287}, {"287XL", "287xl", FPU_287XL}, {NULL, NULL, 0}}; +FPU fpus_80386[] = {{"None", "none", FPU_NONE}, {"387", "387", FPU_387}, {NULL, NULL, 0}}; +FPU fpus_builtin[] = {{"Built-in", "builtin", FPU_BUILTIN}, {NULL, NULL, 0}}; -CPU cpus_8088[] = - { - /*8088 standard*/ - {"8088/4.77", CPU_8088, fpus_8088, 0, 4772728, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, - {"8088/7.16", CPU_8088, fpus_8088, 1, 14318184 / 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, - {"8088/8", CPU_8088, fpus_8088, 1, 8000000, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, - {"8088/10", CPU_8088, fpus_8088, 2, 10000000, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, - {"8088/12", CPU_8088, fpus_8088, 3, 12000000, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, - {"8088/16", CPU_8088, fpus_8088, 4, 16000000, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, - {"", -1, 0, 0, 0, 0} - }; +CPU cpus_8088[] = { + /*8088 standard*/ + {"8088/4.77", CPU_8088, fpus_8088, 0, 4772728, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, + {"8088/7.16", CPU_8088, fpus_8088, 1, 14318184 / 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, + {"8088/8", CPU_8088, fpus_8088, 1, 8000000, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, + {"8088/10", CPU_8088, fpus_8088, 2, 10000000, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, + {"8088/12", CPU_8088, fpus_8088, 3, 12000000, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, + {"8088/16", CPU_8088, fpus_8088, 4, 16000000, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, + {"", -1, 0, 0, 0, 0}}; -CPU cpus_pcjr[] = - { - /*8088 PCjr*/ - {"8088/4.77", CPU_8088, fpus_none, 0, 4772728, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, - {"", -1, 0, 0, 0, 0} - }; +CPU cpus_pcjr[] = { + /*8088 PCjr*/ + {"8088/4.77", CPU_8088, fpus_none, 0, 4772728, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, + {"", -1, 0, 0, 0, 0}}; -CPU cpus_europc[] = - { - /*8088 EuroPC*/ - {"8088/4.77", CPU_8088, fpus_8088, 0, 4772728, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, - {"8088/7.16", CPU_8088, fpus_8088, 1, 14318184 / 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, - {"8088/9.54", CPU_8088, fpus_8088, 1, 4772728 * 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, - {"", -1, 0, 0, 0, 0} - }; +CPU cpus_europc[] = { + /*8088 EuroPC*/ + {"8088/4.77", CPU_8088, fpus_8088, 0, 4772728, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, + {"8088/7.16", CPU_8088, fpus_8088, 1, 14318184 / 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, + {"8088/9.54", CPU_8088, fpus_8088, 1, 4772728 * 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, + {"", -1, 0, 0, 0, 0}}; -CPU cpus_8086[] = - { - /*8086 standard*/ - {"8086/7.16", CPU_8086, fpus_8088, 1, 14318184 / 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, - {"8086/8", CPU_8086, fpus_8088, 1, 8000000, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, - {"8086/9.54", CPU_8086, fpus_8088, 1, 4772728 * 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, - {"8086/10", CPU_8086, fpus_8088, 2, 10000000, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, - {"8086/12", CPU_8086, fpus_8088, 3, 12000000, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, - {"8086/16", CPU_8086, fpus_8088, 4, 16000000, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2}, - {"", -1, 0, 0, 0, 0} - }; +CPU cpus_8086[] = { + /*8086 standard*/ + {"8086/7.16", CPU_8086, fpus_8088, 1, 14318184 / 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, + {"8086/8", CPU_8086, fpus_8088, 1, 8000000, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, + {"8086/9.54", CPU_8086, fpus_8088, 1, 4772728 * 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, + {"8086/10", CPU_8086, fpus_8088, 2, 10000000, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, + {"8086/12", CPU_8086, fpus_8088, 3, 12000000, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, + {"8086/16", CPU_8086, fpus_8088, 4, 16000000, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2}, + {"", -1, 0, 0, 0, 0}}; -CPU cpus_pc1512[] = - { - /*8086 Amstrad*/ - {"8086/8", CPU_8086, fpus_8088, 1, 8000000, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, - {"", -1, 0, 0, 0, 0} - }; +CPU cpus_pc1512[] = { + /*8086 Amstrad*/ + {"8086/8", CPU_8086, fpus_8088, 1, 8000000, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, + {"", -1, 0, 0, 0, 0}}; -CPU cpus_286[] = - { - /*286*/ - {"286/6", CPU_286, fpus_80286, 0, 6000000, 1, 0, 0, 0, 0, 0, 2, 2, 2, 2, 1}, - {"286/8", CPU_286, fpus_80286, 1, 8000000, 1, 0, 0, 0, 0, 0, 2, 2, 2, 2, 1}, - {"286/10", CPU_286, fpus_80286, 2, 10000000, 1, 0, 0, 0, 0, 0, 2, 2, 2, 2, 1}, - {"286/12", CPU_286, fpus_80286, 3, 12000000, 1, 0, 0, 0, 0, 0, 3, 3, 3, 3, 2}, - {"286/16", CPU_286, fpus_80286, 4, 16000000, 1, 0, 0, 0, 0, 0, 3, 3, 3, 3, 2}, - {"286/20", CPU_286, fpus_80286, 5, 20000000, 1, 0, 0, 0, 0, 0, 4, 4, 4, 4, 3}, - {"286/25", CPU_286, fpus_80286, 6, 25000000, 1, 0, 0, 0, 0, 0, 4, 4, 4, 4, 3}, - {"", -1, 0, 0, 0, 0} - }; +CPU cpus_286[] = { + /*286*/ + {"286/6", CPU_286, fpus_80286, 0, 6000000, 1, 0, 0, 0, 0, 0, 2, 2, 2, 2, 1}, + {"286/8", CPU_286, fpus_80286, 1, 8000000, 1, 0, 0, 0, 0, 0, 2, 2, 2, 2, 1}, + {"286/10", CPU_286, fpus_80286, 2, 10000000, 1, 0, 0, 0, 0, 0, 2, 2, 2, 2, 1}, + {"286/12", CPU_286, fpus_80286, 3, 12000000, 1, 0, 0, 0, 0, 0, 3, 3, 3, 3, 2}, + {"286/16", CPU_286, fpus_80286, 4, 16000000, 1, 0, 0, 0, 0, 0, 3, 3, 3, 3, 2}, + {"286/20", CPU_286, fpus_80286, 5, 20000000, 1, 0, 0, 0, 0, 0, 4, 4, 4, 4, 3}, + {"286/25", CPU_286, fpus_80286, 6, 25000000, 1, 0, 0, 0, 0, 0, 4, 4, 4, 4, 3}, + {"", -1, 0, 0, 0, 0}}; -CPU cpus_super286tr[] = - { - /*286*/ - {"286/12", CPU_286, fpus_80286, 3, 12000000, 1, 0, 0, 0, 0, 0, 3, 3, 3, 3, 2}, - {"", -1, 0, 0, 0, 0} - }; +CPU cpus_super286tr[] = { + /*286*/ + {"286/12", CPU_286, fpus_80286, 3, 12000000, 1, 0, 0, 0, 0, 0, 3, 3, 3, 3, 2}, + {"", -1, 0, 0, 0, 0}}; -CPU cpus_ibmat[] = - { - /*286*/ - {"286/6", CPU_286, fpus_80286, 0, 6000000, 1, 0, 0, 0, 0, 0, 3, 3, 3, 3, 1}, - {"286/8", CPU_286, fpus_80286, 0, 8000000, 1, 0, 0, 0, 0, 0, 3, 3, 3, 3, 1}, - {"", -1, 0, 0, 0, 0} - }; +CPU cpus_ibmat[] = { + /*286*/ + {"286/6", CPU_286, fpus_80286, 0, 6000000, 1, 0, 0, 0, 0, 0, 3, 3, 3, 3, 1}, + {"286/8", CPU_286, fpus_80286, 0, 8000000, 1, 0, 0, 0, 0, 0, 3, 3, 3, 3, 1}, + {"", -1, 0, 0, 0, 0}}; -CPU cpus_ibmxt286[] = - { - /*286*/ - {"286/6", CPU_286, fpus_80286, 0, 6000000, 1, 0, 0, 0, 0, 0, 2, 2, 2, 2, 1}, - {"", -1, 0, 0, 0, 0} - }; +CPU cpus_ibmxt286[] = { + /*286*/ + {"286/6", CPU_286, fpus_80286, 0, 6000000, 1, 0, 0, 0, 0, 0, 2, 2, 2, 2, 1}, + {"", -1, 0, 0, 0, 0}}; -CPU cpus_ps1_m2011[] = - { - /*286*/ - {"286/10", CPU_286, fpus_80286, 2, 10000000, 1, 0, 0, 0, 0, 0, 2, 2, 2, 2, 1}, - {"", -1, 0, 0, 0, 0} - }; +CPU cpus_ps1_m2011[] = { + /*286*/ + {"286/10", CPU_286, fpus_80286, 2, 10000000, 1, 0, 0, 0, 0, 0, 2, 2, 2, 2, 1}, + {"", -1, 0, 0, 0, 0}}; -CPU cpus_ps2_m30_286[] = - { - /*286*/ - {"286/10", CPU_286, fpus_80286, 2, 10000000, 1, 0, 0, 0, 0, 0, 2, 2, 2, 2, 1}, - {"286/12", CPU_286, fpus_80286, 3, 12000000, 1, 0, 0, 0, 0, 0, 3, 3, 3, 3, 2}, - {"286/16", CPU_286, fpus_80286, 4, 16000000, 1, 0, 0, 0, 0, 0, 3, 3, 3, 3, 2}, - {"286/20", CPU_286, fpus_80286, 5, 20000000, 1, 0, 0, 0, 0, 0, 4, 4, 4, 4, 3}, - {"286/25", CPU_286, fpus_80286, 6, 25000000, 1, 0, 0, 0, 0, 0, 4, 4, 4, 4, 3}, - {"", -1, 0, 0, 0, 0} - }; +CPU cpus_ps2_m30_286[] = { + /*286*/ + {"286/10", CPU_286, fpus_80286, 2, 10000000, 1, 0, 0, 0, 0, 0, 2, 2, 2, 2, 1}, + {"286/12", CPU_286, fpus_80286, 3, 12000000, 1, 0, 0, 0, 0, 0, 3, 3, 3, 3, 2}, + {"286/16", CPU_286, fpus_80286, 4, 16000000, 1, 0, 0, 0, 0, 0, 3, 3, 3, 3, 2}, + {"286/20", CPU_286, fpus_80286, 5, 20000000, 1, 0, 0, 0, 0, 0, 4, 4, 4, 4, 3}, + {"286/25", CPU_286, fpus_80286, 6, 25000000, 1, 0, 0, 0, 0, 0, 4, 4, 4, 4, 3}, + {"", -1, 0, 0, 0, 0}}; -CPU cpus_i386SX[] = - { - /*i386SX*/ - {"i386SX/16", CPU_386SX, fpus_80386, 0, 16000000, 1, 0, 0x2308, 0, 0, 0, 3, 3, 3, 3, 2}, - {"i386SX/20", CPU_386SX, fpus_80386, 1, 20000000, 1, 0, 0x2308, 0, 0, 0, 4, 4, 3, 3, 3}, - {"i386SX/25", CPU_386SX, fpus_80386, 2, 25000000, 1, 0, 0x2308, 0, 0, 0, 4, 4, 3, 3, 3}, - {"i386SX/33", CPU_386SX, fpus_80386, 3, 33333333, 1, 0, 0x2308, 0, 0, 0, 6, 6, 3, 3, 4}, - {"", -1, 0, 0, 0} - }; +CPU cpus_i386SX[] = { + /*i386SX*/ + {"i386SX/16", CPU_386SX, fpus_80386, 0, 16000000, 1, 0, 0x2308, 0, 0, 0, 3, 3, 3, 3, 2}, + {"i386SX/20", CPU_386SX, fpus_80386, 1, 20000000, 1, 0, 0x2308, 0, 0, 0, 4, 4, 3, 3, 3}, + {"i386SX/25", CPU_386SX, fpus_80386, 2, 25000000, 1, 0, 0x2308, 0, 0, 0, 4, 4, 3, 3, 3}, + {"i386SX/33", CPU_386SX, fpus_80386, 3, 33333333, 1, 0, 0x2308, 0, 0, 0, 6, 6, 3, 3, 4}, + {"", -1, 0, 0, 0}}; -CPU cpus_i386DX[] = - { - /*i386DX*/ - {"i386DX/16", CPU_386DX, fpus_80386, 0, 16000000, 1, 0, 0x0308, 0, 0, 0, 3, 3, 3, 3, 2}, - {"i386DX/20", CPU_386DX, fpus_80386, 1, 20000000, 1, 0, 0x0308, 0, 0, 0, 4, 4, 3, 3, 3}, - {"i386DX/25", CPU_386DX, fpus_80386, 2, 25000000, 1, 0, 0x0308, 0, 0, 0, 4, 4, 3, 3, 3}, - {"i386DX/33", CPU_386DX, fpus_80386, 3, 33333333, 1, 0, 0x0308, 0, 0, 0, 6, 6, 3, 3, 4}, - {"", -1, 0, 0, 0} - }; +CPU cpus_i386DX[] = { + /*i386DX*/ + {"i386DX/16", CPU_386DX, fpus_80386, 0, 16000000, 1, 0, 0x0308, 0, 0, 0, 3, 3, 3, 3, 2}, + {"i386DX/20", CPU_386DX, fpus_80386, 1, 20000000, 1, 0, 0x0308, 0, 0, 0, 4, 4, 3, 3, 3}, + {"i386DX/25", CPU_386DX, fpus_80386, 2, 25000000, 1, 0, 0x0308, 0, 0, 0, 4, 4, 3, 3, 3}, + {"i386DX/33", CPU_386DX, fpus_80386, 3, 33333333, 1, 0, 0x0308, 0, 0, 0, 6, 6, 3, 3, 4}, + {"", -1, 0, 0, 0}}; -CPU cpus_acer[] = - { - /*i386SX*/ - {"i386SX/25", CPU_386SX, fpus_80386, 2, 25000000, 1, 0, 0x2308, 0, 0, 0, 4, 4, 4, 4, 3}, - {"", -1, 0, 0, 0} - }; +CPU cpus_acer[] = { + /*i386SX*/ + {"i386SX/25", CPU_386SX, fpus_80386, 2, 25000000, 1, 0, 0x2308, 0, 0, 0, 4, 4, 4, 4, 3}, + {"", -1, 0, 0, 0}}; -CPU cpus_Am386SX[] = - { - /*Am386*/ - {"Am386SX/16", CPU_386SX, fpus_80386, 0, 16000000, 1, 0, 0x2308, 0, 0, 0, 3, 3, 3, 3, 2}, - {"Am386SX/20", CPU_386SX, fpus_80386, 1, 20000000, 1, 0, 0x2308, 0, 0, 0, 4, 4, 3, 3, 3}, - {"Am386SX/25", CPU_386SX, fpus_80386, 2, 25000000, 1, 0, 0x2308, 0, 0, 0, 4, 4, 3, 3, 3}, - {"Am386SX/33", CPU_386SX, fpus_80386, 3, 33333333, 1, 0, 0x2308, 0, 0, 0, 6, 6, 3, 3, 4}, - {"Am386SX/40", CPU_386SX, fpus_80386, 4, 40000000, 1, 0, 0x2308, 0, 0, 0, 7, 7, 3, 3, 5}, - {"", -1, 0, 0, 0} - }; +CPU cpus_Am386SX[] = { + /*Am386*/ + {"Am386SX/16", CPU_386SX, fpus_80386, 0, 16000000, 1, 0, 0x2308, 0, 0, 0, 3, 3, 3, 3, 2}, + {"Am386SX/20", CPU_386SX, fpus_80386, 1, 20000000, 1, 0, 0x2308, 0, 0, 0, 4, 4, 3, 3, 3}, + {"Am386SX/25", CPU_386SX, fpus_80386, 2, 25000000, 1, 0, 0x2308, 0, 0, 0, 4, 4, 3, 3, 3}, + {"Am386SX/33", CPU_386SX, fpus_80386, 3, 33333333, 1, 0, 0x2308, 0, 0, 0, 6, 6, 3, 3, 4}, + {"Am386SX/40", CPU_386SX, fpus_80386, 4, 40000000, 1, 0, 0x2308, 0, 0, 0, 7, 7, 3, 3, 5}, + {"", -1, 0, 0, 0}}; -CPU cpus_Am386DX[] = - { - /*Am386*/ - {"Am386DX/25", CPU_386DX, fpus_80386, 2, 25000000, 1, 0, 0x0308, 0, 0, 0, 4, 4, 3, 3, 3}, - {"Am386DX/33", CPU_386DX, fpus_80386, 3, 33333333, 1, 0, 0x0308, 0, 0, 0, 6, 6, 3, 3, 4}, - {"Am386DX/40", CPU_386DX, fpus_80386, 4, 40000000, 1, 0, 0x0308, 0, 0, 0, 7, 7, 3, 3, 5}, - {"", -1, 0, 0, 0} - }; +CPU cpus_Am386DX[] = { + /*Am386*/ + {"Am386DX/25", CPU_386DX, fpus_80386, 2, 25000000, 1, 0, 0x0308, 0, 0, 0, 4, 4, 3, 3, 3}, + {"Am386DX/33", CPU_386DX, fpus_80386, 3, 33333333, 1, 0, 0x0308, 0, 0, 0, 6, 6, 3, 3, 4}, + {"Am386DX/40", CPU_386DX, fpus_80386, 4, 40000000, 1, 0, 0x0308, 0, 0, 0, 7, 7, 3, 3, 5}, + {"", -1, 0, 0, 0}}; -CPU cpus_486SLC[] = - { - /*Cx486SLC*/ - {"Cx486SLC/20", CPU_486SLC, fpus_80386, 1, 20000000, 1, 0, 0x400, 0, 0x0000, 0, 4, 4, 3, 3, 3}, - {"Cx486SLC/25", CPU_486SLC, fpus_80386, 2, 25000000, 1, 0, 0x400, 0, 0x0000, 0, 4, 4, 3, 3, 3}, - {"Cx486SLC/33", CPU_486SLC, fpus_80386, 3, 33333333, 1, 0, 0x400, 0, 0x0000, 0, 6, 6, 3, 3, 4}, - {"Cx486SRx2/32", CPU_486SLC, fpus_80386, 3, 32000000, 2, 0, 0x406, 0, 0x0006, 0, 6, 6, 6, 6, 2 * 2}, - {"Cx486SRx2/40", CPU_486SLC, fpus_80386, 4, 40000000, 2, 0, 0x406, 0, 0x0006, 0, 8, 8, 6, 6, 2 * 3}, - {"Cx486SRx2/50", CPU_486SLC, fpus_80386, 5, 50000000, 2, 0, 0x406, 0, 0x0006, 0, 8, 8, 6, 6, 2 * 3}, - {"", -1, 0, 0, 0} - }; +CPU cpus_486SLC[] = { + /*Cx486SLC*/ + {"Cx486SLC/20", CPU_486SLC, fpus_80386, 1, 20000000, 1, 0, 0x400, 0, 0x0000, 0, 4, 4, 3, 3, 3}, + {"Cx486SLC/25", CPU_486SLC, fpus_80386, 2, 25000000, 1, 0, 0x400, 0, 0x0000, 0, 4, 4, 3, 3, 3}, + {"Cx486SLC/33", CPU_486SLC, fpus_80386, 3, 33333333, 1, 0, 0x400, 0, 0x0000, 0, 6, 6, 3, 3, 4}, + {"Cx486SRx2/32", CPU_486SLC, fpus_80386, 3, 32000000, 2, 0, 0x406, 0, 0x0006, 0, 6, 6, 6, 6, 2 * 2}, + {"Cx486SRx2/40", CPU_486SLC, fpus_80386, 4, 40000000, 2, 0, 0x406, 0, 0x0006, 0, 8, 8, 6, 6, 2 * 3}, + {"Cx486SRx2/50", CPU_486SLC, fpus_80386, 5, 50000000, 2, 0, 0x406, 0, 0x0006, 0, 8, 8, 6, 6, 2 * 3}, + {"", -1, 0, 0, 0}}; -CPU cpus_486DLC[] = - { - /*Cx486DLC*/ - {"Cx486DLC/25", CPU_486DLC, fpus_80386, 2, 25000000, 1, 0, 0x401, 0, 0x0001, 0, 4, 4, 3, 3, 3}, - {"Cx486DLC/33", CPU_486DLC, fpus_80386, 3, 33333333, 1, 0, 0x401, 0, 0x0001, 0, 6, 6, 3, 3, 4}, - {"Cx486DLC/40", CPU_486DLC, fpus_80386, 4, 40000000, 1, 0, 0x401, 0, 0x0001, 0, 7, 7, 3, 3, 5}, - {"Cx486DRx2/32", CPU_486DLC, fpus_80386, 3, 32000000, 2, 0, 0x407, 0, 0x0007, 0, 6, 6, 6, 6, 2 * 2}, - {"Cx486DRx2/40", CPU_486DLC, fpus_80386, 4, 40000000, 2, 0, 0x407, 0, 0x0007, 0, 8, 8, 6, 6, 2 * 3}, - {"Cx486DRx2/50", CPU_486DLC, fpus_80386, 5, 50000000, 2, 0, 0x407, 0, 0x0007, 0, 8, 8, 6, 6, 2 * 3}, - {"Cx486DRx2/66", CPU_486DLC, fpus_80386, 6, 66666666, 2, 0, 0x407, 0, 0x0007, 0, 12, 12, 6, 6, 2 * 4}, - {"", -1, 0, 0, 0} - }; +CPU cpus_486DLC[] = { + /*Cx486DLC*/ + {"Cx486DLC/25", CPU_486DLC, fpus_80386, 2, 25000000, 1, 0, 0x401, 0, 0x0001, 0, 4, 4, 3, 3, 3}, + {"Cx486DLC/33", CPU_486DLC, fpus_80386, 3, 33333333, 1, 0, 0x401, 0, 0x0001, 0, 6, 6, 3, 3, 4}, + {"Cx486DLC/40", CPU_486DLC, fpus_80386, 4, 40000000, 1, 0, 0x401, 0, 0x0001, 0, 7, 7, 3, 3, 5}, + {"Cx486DRx2/32", CPU_486DLC, fpus_80386, 3, 32000000, 2, 0, 0x407, 0, 0x0007, 0, 6, 6, 6, 6, 2 * 2}, + {"Cx486DRx2/40", CPU_486DLC, fpus_80386, 4, 40000000, 2, 0, 0x407, 0, 0x0007, 0, 8, 8, 6, 6, 2 * 3}, + {"Cx486DRx2/50", CPU_486DLC, fpus_80386, 5, 50000000, 2, 0, 0x407, 0, 0x0007, 0, 8, 8, 6, 6, 2 * 3}, + {"Cx486DRx2/66", CPU_486DLC, fpus_80386, 6, 66666666, 2, 0, 0x407, 0, 0x0007, 0, 12, 12, 6, 6, 2 * 4}, + {"", -1, 0, 0, 0}}; -CPU cpus_i486[] = - { - /*i486*/ - {"i486SX/16", CPU_i486SX, fpus_none, 0, 16000000, 1, 16000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 3, 3, 3, 3, 2}, - {"i486SX/20", CPU_i486SX, fpus_none, 1, 20000000, 1, 20000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4, 3, 3, 3}, - {"i486SX/25", CPU_i486SX, fpus_none, 2, 25000000, 1, 25000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4, 3, 3, 3}, - {"i486SX/33", CPU_i486SX, fpus_none, 3, 33333333, 1, 33333333, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, - {"i486SX2/50", CPU_i486SX, fpus_none, 5, 50000000, 2, 25000000, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 2 * 3}, - {"i486DX/25", CPU_i486DX, fpus_builtin, 2, 25000000, 1, 25000000, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4, 3, 3, 3}, - {"i486DX/33", CPU_i486DX, fpus_builtin, 3, 33333333, 1, 33333333, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, - {"i486DX/50", CPU_i486DX, fpus_builtin, 5, 50000000, 1, 25000000, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 4, 4, 6}, - {"i486DX2/40", CPU_i486DX, fpus_builtin, 4, 40000000, 2, 20000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 2 * 3}, - {"i486DX2/50", CPU_i486DX, fpus_builtin, 5, 50000000, 2, 25000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 2 * 3}, - {"i486DX2/66", CPU_i486DX, fpus_builtin, 6, 66666666, 2, 33333333, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 12, 12, 6, 6, 2 * 4}, - {"iDX4/75", CPU_iDX4, fpus_builtin, 7, 75000000, 3, 25000000, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 12, 12, 9, 9, 3 * 3}, /*CPUID available on DX4, >= 75 MHz*/ - {"iDX4/100", CPU_iDX4, fpus_builtin, 10, 100000000, 3, 33333333, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, - 3 * 4}, /*Is on some real Intel DX2s, limit here is pretty arbitary*/ - {"Pentium OverDrive/63", CPU_PENTIUM, fpus_builtin, 6, 62500000, 3, 25000000, 0x1531, 0x1531, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10, 10, 7, 7, (5 * 3) / 2}, - {"Pentium OverDrive/83", CPU_PENTIUM, fpus_builtin, 8, 83333333, 3, 33333333, 0x1532, 0x1532, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15, 15, 8, 8, (5 * 4) / 2}, - {"", -1, 0, 0, 0} - }; +CPU cpus_i486[] = { + /*i486*/ + {"i486SX/16", CPU_i486SX, fpus_none, 0, 16000000, 1, 16000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 3, 3, 3, 3, 2}, + {"i486SX/20", CPU_i486SX, fpus_none, 1, 20000000, 1, 20000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4, 3, 3, 3}, + {"i486SX/25", CPU_i486SX, fpus_none, 2, 25000000, 1, 25000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4, 3, 3, 3}, + {"i486SX/33", CPU_i486SX, fpus_none, 3, 33333333, 1, 33333333, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, + {"i486SX2/50", CPU_i486SX, fpus_none, 5, 50000000, 2, 25000000, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 2 * 3}, + {"i486DX/25", CPU_i486DX, fpus_builtin, 2, 25000000, 1, 25000000, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4, 3, 3, 3}, + {"i486DX/33", CPU_i486DX, fpus_builtin, 3, 33333333, 1, 33333333, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, + {"i486DX/50", CPU_i486DX, fpus_builtin, 5, 50000000, 1, 25000000, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 4, 4, 6}, + {"i486DX2/40", CPU_i486DX, fpus_builtin, 4, 40000000, 2, 20000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 2 * 3}, + {"i486DX2/50", CPU_i486DX, fpus_builtin, 5, 50000000, 2, 25000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 2 * 3}, + {"i486DX2/66", CPU_i486DX, fpus_builtin, 6, 66666666, 2, 33333333, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 12, 12, 6, 6, + 2 * 4}, + {"iDX4/75", CPU_iDX4, fpus_builtin, 7, 75000000, 3, 25000000, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 12, 12, 9, 9, + 3 * 3}, /*CPUID available on DX4, >= 75 MHz*/ + {"iDX4/100", CPU_iDX4, fpus_builtin, 10, 100000000, 3, 33333333, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, + 3 * 4}, /*Is on some real Intel DX2s, limit here is pretty arbitary*/ + {"Pentium OverDrive/63", CPU_PENTIUM, fpus_builtin, 6, 62500000, 3, 25000000, 0x1531, 0x1531, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10, 10, 7, 7, (5 * 3) / 2}, + {"Pentium OverDrive/83", CPU_PENTIUM, fpus_builtin, 8, 83333333, 3, 33333333, 0x1532, 0x1532, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15, 15, 8, 8, (5 * 4) / 2}, + {"", -1, 0, 0, 0}}; -CPU cpus_Am486[] = - { - /*Am486/5x86*/ - {"Am486SX/33", CPU_Am486SX, fpus_none, 3, 33333333, 1, 33333333, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, - {"Am486SX/40", CPU_Am486SX, fpus_none, 4, 40000000, 1, 20000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5}, - {"Am486SX2/50", CPU_Am486SX, fpus_none, 5, 50000000, 2, 25000000, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 2 * 3}, /*CPUID available on SX2, DX2, DX4, 5x86, >= 50 MHz*/ - {"Am486SX2/66", CPU_Am486SX, fpus_none, 6, 66666666, 2, 33333333, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 12, 12, 6, 6, - 2 * 4}, /*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, fpus_builtin, 3, 33333333, 1, 33333333, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, - {"Am486DX/40", CPU_Am486DX, fpus_builtin, 4, 40000000, 1, 20000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5}, - {"Am486DX2/50", CPU_Am486DX, fpus_builtin, 5, 50000000, 2, 25000000, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 2 * 3}, - {"Am486DX2/66", CPU_Am486DX, fpus_builtin, 6, 66666666, 2, 33333333, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 12, 12, 6, 6, 2 * 4}, - {"Am486DX2/80", CPU_Am486DX, fpus_builtin, 8, 80000000, 2, 20000000, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 14, 14, 6, 6, 2 * 5}, - {"Am486DX4/75", CPU_Am486DX, fpus_builtin, 7, 75000000, 3, 25000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 12, 12, 9, 9, 3 * 3}, - {"Am486DX4/90", CPU_Am486DX, fpus_builtin, 9, 90000000, 3, 30000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 15, 15, 9, 9, 3 * 4}, - {"Am486DX4/100", CPU_Am486DX, fpus_builtin, 10, 100000000, 3, 33333333, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 15, 15, 9, 9, 3 * 4}, - {"Am486DX4/120", CPU_Am486DX, fpus_builtin, 11, 120000000, 3, 20000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 21, 21, 9, 9, 3 * 5}, - {"Am5x86/P75", CPU_Am486DX, fpus_builtin, 12, 133333333, 4, 33333333, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 4 * 4}, - {"Am5x86/P75+", CPU_Am486DX, fpus_builtin, 13, 160000000, 4, 20000000, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC, 28, 28, 12, 12, 4 * 5}, - {"", -1, 0, 0, 0} - }; +CPU cpus_Am486[] = { + /*Am486/5x86*/ + {"Am486SX/33", CPU_Am486SX, fpus_none, 3, 33333333, 1, 33333333, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, + {"Am486SX/40", CPU_Am486SX, fpus_none, 4, 40000000, 1, 20000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5}, + {"Am486SX2/50", CPU_Am486SX, fpus_none, 5, 50000000, 2, 25000000, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, + 2 * 3}, /*CPUID available on SX2, DX2, DX4, 5x86, >= 50 MHz*/ + {"Am486SX2/66", CPU_Am486SX, fpus_none, 6, 66666666, 2, 33333333, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 12, 12, 6, 6, + 2 * 4}, /*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, fpus_builtin, 3, 33333333, 1, 33333333, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, + {"Am486DX/40", CPU_Am486DX, fpus_builtin, 4, 40000000, 1, 20000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5}, + {"Am486DX2/50", CPU_Am486DX, fpus_builtin, 5, 50000000, 2, 25000000, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, + 2 * 3}, + {"Am486DX2/66", CPU_Am486DX, fpus_builtin, 6, 66666666, 2, 33333333, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 12, 12, 6, 6, + 2 * 4}, + {"Am486DX2/80", CPU_Am486DX, fpus_builtin, 8, 80000000, 2, 20000000, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 14, 14, 6, 6, + 2 * 5}, + {"Am486DX4/75", CPU_Am486DX, fpus_builtin, 7, 75000000, 3, 25000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 12, 12, 9, 9, + 3 * 3}, + {"Am486DX4/90", CPU_Am486DX, fpus_builtin, 9, 90000000, 3, 30000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 15, 15, 9, 9, + 3 * 4}, + {"Am486DX4/100", CPU_Am486DX, fpus_builtin, 10, 100000000, 3, 33333333, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 15, 15, 9, + 9, 3 * 4}, + {"Am486DX4/120", CPU_Am486DX, fpus_builtin, 11, 120000000, 3, 20000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 21, 21, 9, + 9, 3 * 5}, + {"Am5x86/P75", CPU_Am486DX, fpus_builtin, 12, 133333333, 4, 33333333, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, + 12, 4 * 4}, + {"Am5x86/P75+", CPU_Am486DX, fpus_builtin, 13, 160000000, 4, 20000000, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC, 28, 28, 12, + 12, 4 * 5}, + {"", -1, 0, 0, 0}}; -CPU cpus_Cx486[] = - { - /*Cx486/5x86*/ - {"Cx486S/25", CPU_Cx486S, fpus_none, 2, 25000000, 1, 25000000, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 4, 4, 3, 3, 3}, - {"Cx486S/33", CPU_Cx486S, fpus_none, 3, 33333333, 1, 33333333, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, - {"Cx486S/40", CPU_Cx486S, fpus_none, 4, 40000000, 1, 20000000, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5}, - {"Cx486DX/33", CPU_Cx486DX, fpus_builtin, 3, 33333333, 1, 33333333, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, - {"Cx486DX/40", CPU_Cx486DX, fpus_builtin, 4, 40000000, 1, 20000000, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5}, - {"Cx486DX2/50", CPU_Cx486DX, fpus_builtin, 5, 50000000, 2, 25000000, 0x430, 0, 0x081b, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 2 * 3}, - {"Cx486DX2/66", CPU_Cx486DX, fpus_builtin, 6, 66666666, 2, 33333333, 0x430, 0, 0x0b1b, CPU_SUPPORTS_DYNAREC, 12, 12, 6, 6, 2 * 4}, - {"Cx486DX2/80", CPU_Cx486DX, fpus_builtin, 8, 80000000, 2, 20000000, 0x430, 0, 0x311b, CPU_SUPPORTS_DYNAREC, 14, 14, 16, 16, 2 * 5}, - {"Cx486DX4/75", CPU_Cx486DX, fpus_builtin, 7, 75000000, 3, 25000000, 0x480, 0, 0x361f, CPU_SUPPORTS_DYNAREC, 12, 12, 9, 9, 3 * 3}, - {"Cx486DX4/100", CPU_Cx486DX, fpus_builtin, 10, 100000000, 3, 33333333, 0x480, 0, 0x361f, CPU_SUPPORTS_DYNAREC, 15, 15, 9, 9, 3 * 4}, - {"Cx5x86/100", CPU_Cx5x86, fpus_builtin, 10, 100000000, 3, 33333333, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 15, 15, 9, 9, 3 * 4}, - {"Cx5x86/120", CPU_Cx5x86, fpus_builtin, 11, 120000000, 3, 20000000, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 21, 21, 9, 9, 3 * 5}, - {"Cx5x86/133", CPU_Cx5x86, fpus_builtin, 12, 133333333, 4, 33333333, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 4 * 4}, - {"", -1, 0, 0, 0} - }; +CPU cpus_Cx486[] = { + /*Cx486/5x86*/ + {"Cx486S/25", CPU_Cx486S, fpus_none, 2, 25000000, 1, 25000000, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 4, 4, 3, 3, 3}, + {"Cx486S/33", CPU_Cx486S, fpus_none, 3, 33333333, 1, 33333333, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4}, + {"Cx486S/40", CPU_Cx486S, fpus_none, 4, 40000000, 1, 20000000, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5}, + {"Cx486DX/33", CPU_Cx486DX, fpus_builtin, 3, 33333333, 1, 33333333, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, + 4}, + {"Cx486DX/40", CPU_Cx486DX, fpus_builtin, 4, 40000000, 1, 20000000, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, + 5}, + {"Cx486DX2/50", CPU_Cx486DX, fpus_builtin, 5, 50000000, 2, 25000000, 0x430, 0, 0x081b, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, + 2 * 3}, + {"Cx486DX2/66", CPU_Cx486DX, fpus_builtin, 6, 66666666, 2, 33333333, 0x430, 0, 0x0b1b, CPU_SUPPORTS_DYNAREC, 12, 12, 6, 6, + 2 * 4}, + {"Cx486DX2/80", CPU_Cx486DX, fpus_builtin, 8, 80000000, 2, 20000000, 0x430, 0, 0x311b, CPU_SUPPORTS_DYNAREC, 14, 14, 16, + 16, 2 * 5}, + {"Cx486DX4/75", CPU_Cx486DX, fpus_builtin, 7, 75000000, 3, 25000000, 0x480, 0, 0x361f, CPU_SUPPORTS_DYNAREC, 12, 12, 9, 9, + 3 * 3}, + {"Cx486DX4/100", CPU_Cx486DX, fpus_builtin, 10, 100000000, 3, 33333333, 0x480, 0, 0x361f, CPU_SUPPORTS_DYNAREC, 15, 15, 9, + 9, 3 * 4}, + {"Cx5x86/100", CPU_Cx5x86, fpus_builtin, 10, 100000000, 3, 33333333, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 15, 15, 9, 9, + 3 * 4}, + {"Cx5x86/120", CPU_Cx5x86, fpus_builtin, 11, 120000000, 3, 20000000, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 21, 21, 9, 9, + 3 * 5}, + {"Cx5x86/133", CPU_Cx5x86, fpus_builtin, 12, 133333333, 4, 33333333, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 24, 24, 12, + 12, 4 * 4}, + {"", -1, 0, 0, 0}}; -CPU cpus_6x86[] = - { - /*Cyrix 6x86*/ - {"6x86-P90", CPU_Cx6x86, fpus_builtin, 17, 80000000, 3, 40000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8, 8, 6, 6, 2 * 5}, - {"6x86-PR120+", CPU_Cx6x86, fpus_builtin, 17, 100000000, 3, 25000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10, 10, 6, 6, 2 * 6}, - {"6x86-PR133+", CPU_Cx6x86, fpus_builtin, 17, 110000000, 3, 27500000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10, 10, 6, 6, 2 * 7}, - {"6x86-PR150+", CPU_Cx6x86, fpus_builtin, 17, 120000000, 3, 30000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12, 12, 6, 6, 2 * 7}, - {"6x86-PR166+", CPU_Cx6x86, fpus_builtin, 17, 133333333, 3, 33333333, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12, 12, 6, 6, 2 * 8}, - {"6x86-PR200+", CPU_Cx6x86, fpus_builtin, 17, 150000000, 3, 37500000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12, 12, 6, 6, 2 * 9}, +CPU cpus_6x86[] = { + /*Cyrix 6x86*/ + {"6x86-P90", CPU_Cx6x86, fpus_builtin, 17, 80000000, 3, 40000000, 0x520, 0x520, 0x1731, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8, 8, 6, 6, 2 * 5}, + {"6x86-PR120+", CPU_Cx6x86, fpus_builtin, 17, 100000000, 3, 25000000, 0x520, 0x520, 0x1731, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10, 10, 6, 6, 2 * 6}, + {"6x86-PR133+", CPU_Cx6x86, fpus_builtin, 17, 110000000, 3, 27500000, 0x520, 0x520, 0x1731, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10, 10, 6, 6, 2 * 7}, + {"6x86-PR150+", CPU_Cx6x86, fpus_builtin, 17, 120000000, 3, 30000000, 0x520, 0x520, 0x1731, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12, 12, 6, 6, 2 * 7}, + {"6x86-PR166+", CPU_Cx6x86, fpus_builtin, 17, 133333333, 3, 33333333, 0x520, 0x520, 0x1731, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12, 12, 6, 6, 2 * 8}, + {"6x86-PR200+", CPU_Cx6x86, fpus_builtin, 17, 150000000, 3, 37500000, 0x520, 0x520, 0x1731, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12, 12, 6, 6, 2 * 9}, - /*Cyrix 6x86L*/ - {"6x86L-PR133+", CPU_Cx6x86L, fpus_builtin, 19, 110000000, 3, 27500000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10, 10, 6, 6, 2 * 7}, - {"6x86L-PR150+", CPU_Cx6x86L, fpus_builtin, 19, 120000000, 3, 30000000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12, 12, 6, 6, 2 * 7}, - {"6x86L-PR166+", CPU_Cx6x86L, fpus_builtin, 19, 133333333, 3, 33333333, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12, 12, 6, 6, 2 * 8}, - {"6x86L-PR200+", CPU_Cx6x86L, fpus_builtin, 19, 150000000, 3, 37500000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12, 12, 6, 6, 2 * 9}, + /*Cyrix 6x86L*/ + {"6x86L-PR133+", CPU_Cx6x86L, fpus_builtin, 19, 110000000, 3, 27500000, 0x540, 0x540, 0x2231, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10, 10, 6, 6, 2 * 7}, + {"6x86L-PR150+", CPU_Cx6x86L, fpus_builtin, 19, 120000000, 3, 30000000, 0x540, 0x540, 0x2231, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12, 12, 6, 6, 2 * 7}, + {"6x86L-PR166+", CPU_Cx6x86L, fpus_builtin, 19, 133333333, 3, 33333333, 0x540, 0x540, 0x2231, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12, 12, 6, 6, 2 * 8}, + {"6x86L-PR200+", CPU_Cx6x86L, fpus_builtin, 19, 150000000, 3, 37500000, 0x540, 0x540, 0x2231, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12, 12, 6, 6, 2 * 9}, - /*Cyrix 6x86MX*/ - {"6x86MX-PR166", CPU_Cx6x86MX, fpus_builtin, 18, 133333333, 3, 33333333, 0x600, 0x600, 0x0451, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12, 12, 6, 6, 2 * 8}, - {"6x86MX-PR200", CPU_Cx6x86MX, fpus_builtin, 18, 166666666, 3, 33333333, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15, 15, 7, 7, (5 * 8) / 2}, - {"6x86MX-PR233", CPU_Cx6x86MX, fpus_builtin, 18, 188888888, 3, 37500000, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15, 15, 7, 7, (5 * 9) / 2}, - {"6x86MX-PR266", CPU_Cx6x86MX, fpus_builtin, 18, 207500000, 3, 41666667, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17, 17, 7, 7, (5 * 10) / 2}, + /*Cyrix 6x86MX*/ + {"6x86MX-PR166", CPU_Cx6x86MX, fpus_builtin, 18, 133333333, 3, 33333333, 0x600, 0x600, 0x0451, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12, 12, 6, 6, 2 * 8}, + {"6x86MX-PR200", CPU_Cx6x86MX, fpus_builtin, 18, 166666666, 3, 33333333, 0x600, 0x600, 0x0452, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15, 15, 7, 7, (5 * 8) / 2}, + {"6x86MX-PR233", CPU_Cx6x86MX, fpus_builtin, 18, 188888888, 3, 37500000, 0x600, 0x600, 0x0452, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15, 15, 7, 7, (5 * 9) / 2}, + {"6x86MX-PR266", CPU_Cx6x86MX, fpus_builtin, 18, 207500000, 3, 41666667, 0x600, 0x600, 0x0452, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17, 17, 7, 7, (5 * 10) / 2}, - /*Cyrix M II*/ - {"M II-200", CPU_Cx6x86MX, fpus_builtin, 18, 166666666, 3, 33333333, 0x600, 0x600, 0x0854, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15, 15, 7, 7, (5 * 8) / 2}, - {"M II-233", CPU_Cx6x86MX, fpus_builtin, 18, 188888888, 3, 37500000, 0x601, 0x601, 0x0854, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15, 15, 7, 7, (5 * 9) / 2}, - {"M II-266", CPU_Cx6x86MX, fpus_builtin, 18, 207500000, 3, 41666667, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17, 17, 7, 7, (5 * 10) / 2}, - {"M II-300", CPU_Cx6x86MX, fpus_builtin, 18, 233333333, 3, 33333333, 0x601, 0x601, 0x0852, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21, 21, 7, 7, (7 * 8) / 2}, - {"M II-333", CPU_Cx6x86MX, fpus_builtin, 18, 250000000, 3, 41666667, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 20, 20, 9, 9, 3 * 10}, + /*Cyrix M II*/ + {"M II-200", CPU_Cx6x86MX, fpus_builtin, 18, 166666666, 3, 33333333, 0x600, 0x600, 0x0854, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15, 15, 7, 7, (5 * 8) / 2}, + {"M II-233", CPU_Cx6x86MX, fpus_builtin, 18, 188888888, 3, 37500000, 0x601, 0x601, 0x0854, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15, 15, 7, 7, (5 * 9) / 2}, + {"M II-266", CPU_Cx6x86MX, fpus_builtin, 18, 207500000, 3, 41666667, 0x601, 0x601, 0x0853, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17, 17, 7, 7, (5 * 10) / 2}, + {"M II-300", CPU_Cx6x86MX, fpus_builtin, 18, 233333333, 3, 33333333, 0x601, 0x601, 0x0852, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21, 21, 7, 7, (7 * 8) / 2}, + {"M II-333", CPU_Cx6x86MX, fpus_builtin, 18, 250000000, 3, 41666667, 0x601, 0x601, 0x0853, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 20, 20, 9, 9, 3 * 10}, - {"", -1, 0, 0, 0} - }; + {"", -1, 0, 0, 0}}; -CPU cpus_6x86_SS7[] = - { - /*Cyrix 6x86*/ - {"6x86-P90", CPU_Cx6x86, fpus_builtin, 17, 80000000, 3, 40000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8, 8, 6, 6, 2 * 5}, - {"6x86-PR120+", CPU_Cx6x86, fpus_builtin, 17, 100000000, 3, 25000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10, 10, 6, 6, 2 * 6}, - {"6x86-PR133+", CPU_Cx6x86, fpus_builtin, 17, 110000000, 3, 27500000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10, 10, 6, 6, 2 * 7}, - {"6x86-PR150+", CPU_Cx6x86, fpus_builtin, 17, 120000000, 3, 30000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12, 12, 6, 6, 2 * 7}, - {"6x86-PR166+", CPU_Cx6x86, fpus_builtin, 17, 133333333, 3, 33333333, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12, 12, 6, 6, 2 * 8}, - {"6x86-PR200+", CPU_Cx6x86, fpus_builtin, 17, 150000000, 3, 37500000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12, 12, 6, 6, 2 * 9}, +CPU cpus_6x86_SS7[] = { + /*Cyrix 6x86*/ + {"6x86-P90", CPU_Cx6x86, fpus_builtin, 17, 80000000, 3, 40000000, 0x520, 0x520, 0x1731, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8, 8, 6, 6, 2 * 5}, + {"6x86-PR120+", CPU_Cx6x86, fpus_builtin, 17, 100000000, 3, 25000000, 0x520, 0x520, 0x1731, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10, 10, 6, 6, 2 * 6}, + {"6x86-PR133+", CPU_Cx6x86, fpus_builtin, 17, 110000000, 3, 27500000, 0x520, 0x520, 0x1731, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10, 10, 6, 6, 2 * 7}, + {"6x86-PR150+", CPU_Cx6x86, fpus_builtin, 17, 120000000, 3, 30000000, 0x520, 0x520, 0x1731, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12, 12, 6, 6, 2 * 7}, + {"6x86-PR166+", CPU_Cx6x86, fpus_builtin, 17, 133333333, 3, 33333333, 0x520, 0x520, 0x1731, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12, 12, 6, 6, 2 * 8}, + {"6x86-PR200+", CPU_Cx6x86, fpus_builtin, 17, 150000000, 3, 37500000, 0x520, 0x520, 0x1731, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12, 12, 6, 6, 2 * 9}, - /*Cyrix 6x86L*/ - {"6x86L-PR133+", CPU_Cx6x86L, fpus_builtin, 19, 110000000, 3, 27500000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10, 10, 6, 6, 2 * 7}, - {"6x86L-PR150+", CPU_Cx6x86L, fpus_builtin, 19, 120000000, 3, 30000000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12, 12, 6, 6, 2 * 7}, - {"6x86L-PR166+", CPU_Cx6x86L, fpus_builtin, 19, 133333333, 3, 33333333, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12, 12, 6, 6, 2 * 8}, - {"6x86L-PR200+", CPU_Cx6x86L, fpus_builtin, 19, 150000000, 3, 37500000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12, 12, 6, 6, 2 * 9}, + /*Cyrix 6x86L*/ + {"6x86L-PR133+", CPU_Cx6x86L, fpus_builtin, 19, 110000000, 3, 27500000, 0x540, 0x540, 0x2231, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10, 10, 6, 6, 2 * 7}, + {"6x86L-PR150+", CPU_Cx6x86L, fpus_builtin, 19, 120000000, 3, 30000000, 0x540, 0x540, 0x2231, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12, 12, 6, 6, 2 * 7}, + {"6x86L-PR166+", CPU_Cx6x86L, fpus_builtin, 19, 133333333, 3, 33333333, 0x540, 0x540, 0x2231, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12, 12, 6, 6, 2 * 8}, + {"6x86L-PR200+", CPU_Cx6x86L, fpus_builtin, 19, 150000000, 3, 37500000, 0x540, 0x540, 0x2231, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12, 12, 6, 6, 2 * 9}, - /*Cyrix 6x86MX*/ - {"6x86MX-PR166", CPU_Cx6x86MX, fpus_builtin, 18, 133333333, 3, 33333333, 0x600, 0x600, 0x0451, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12, 12, 6, 6, 2 * 8}, - {"6x86MX-PR200", CPU_Cx6x86MX, fpus_builtin, 18, 166666666, 3, 33333333, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15, 15, 7, 7, (5 * 8) / 2}, - {"6x86MX-PR233", CPU_Cx6x86MX, fpus_builtin, 18, 188888888, 3, 37500000, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15, 15, 7, 7, (5 * 9) / 2}, - {"6x86MX-PR266", CPU_Cx6x86MX, fpus_builtin, 18, 207500000, 3, 41666667, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17, 17, 7, 7, (5 * 10) / 2}, + /*Cyrix 6x86MX*/ + {"6x86MX-PR166", CPU_Cx6x86MX, fpus_builtin, 18, 133333333, 3, 33333333, 0x600, 0x600, 0x0451, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12, 12, 6, 6, 2 * 8}, + {"6x86MX-PR200", CPU_Cx6x86MX, fpus_builtin, 18, 166666666, 3, 33333333, 0x600, 0x600, 0x0452, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15, 15, 7, 7, (5 * 8) / 2}, + {"6x86MX-PR233", CPU_Cx6x86MX, fpus_builtin, 18, 188888888, 3, 37500000, 0x600, 0x600, 0x0452, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15, 15, 7, 7, (5 * 9) / 2}, + {"6x86MX-PR266", CPU_Cx6x86MX, fpus_builtin, 18, 207500000, 3, 41666667, 0x600, 0x600, 0x0452, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17, 17, 7, 7, (5 * 10) / 2}, - /*Cyrix M II*/ - {"M II-200", CPU_Cx6x86MX, fpus_builtin, 18, 166666666, 3, 33333333, 0x600, 0x600, 0x0854, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15, 15, 7, 7, (5 * 8) / 2}, - {"M II-233", CPU_Cx6x86MX, fpus_builtin, 18, 188888888, 3, 37500000, 0x601, 0x601, 0x0854, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15, 15, 7, 7, (5 * 9) / 2}, - {"M II-266", CPU_Cx6x86MX, fpus_builtin, 18, 207500000, 3, 41666667, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17, 17, 7, 7, (5 * 10) / 2}, - {"M II-300", CPU_Cx6x86MX, fpus_builtin, 18, 233333333, 3, 33333333, 0x601, 0x601, 0x0852, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21, 21, 7, 7, (7 * 8) / 2}, - {"M II-333", CPU_Cx6x86MX, fpus_builtin, 18, 250000000, 3, 41666667, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 20, 20, 9, 9, 3 * 10}, - {"M II-366", CPU_Cx6x86MX, fpus_builtin, 18, 250000000, 3, 33333333, 0x601, 0x601, 0x0852, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24, 24, 12, 12, 3 * 10}, - {"M II-400", CPU_Cx6x86MX, fpus_builtin, 18, 285000000, 3, 31666667, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 3 * 11}, - {"M II-433", CPU_Cx6x86MX, fpus_builtin, 18, 300000000, 3, 33333333, 0x601, 0x601, 0x0853, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 3 * 12}, - {"", -1, 0, 0, 0} - }; + /*Cyrix M II*/ + {"M II-200", CPU_Cx6x86MX, fpus_builtin, 18, 166666666, 3, 33333333, 0x600, 0x600, 0x0854, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15, 15, 7, 7, (5 * 8) / 2}, + {"M II-233", CPU_Cx6x86MX, fpus_builtin, 18, 188888888, 3, 37500000, 0x601, 0x601, 0x0854, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15, 15, 7, 7, (5 * 9) / 2}, + {"M II-266", CPU_Cx6x86MX, fpus_builtin, 18, 207500000, 3, 41666667, 0x601, 0x601, 0x0853, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17, 17, 7, 7, (5 * 10) / 2}, + {"M II-300", CPU_Cx6x86MX, fpus_builtin, 18, 233333333, 3, 33333333, 0x601, 0x601, 0x0852, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21, 21, 7, 7, (7 * 8) / 2}, + {"M II-333", CPU_Cx6x86MX, fpus_builtin, 18, 250000000, 3, 41666667, 0x601, 0x601, 0x0853, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 20, 20, 9, 9, 3 * 10}, + {"M II-366", CPU_Cx6x86MX, fpus_builtin, 18, 250000000, 3, 33333333, 0x601, 0x601, 0x0852, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24, 24, 12, 12, 3 * 10}, + {"M II-400", CPU_Cx6x86MX, fpus_builtin, 18, 285000000, 3, 31666667, 0x601, 0x601, 0x0853, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 3 * 11}, + {"M II-433", CPU_Cx6x86MX, fpus_builtin, 18, 300000000, 3, 33333333, 0x601, 0x601, 0x0853, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 3 * 12}, + {"", -1, 0, 0, 0}}; -CPU cpus_WinChip[] = - { - /*IDT WinChip*/ - {"WinChip 75", CPU_WINCHIP, fpus_builtin, 7, 75000000, 2, 25000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 4, 4, (3 * 6) / 2}, - {"WinChip 90", CPU_WINCHIP, fpus_builtin, 9, 90000000, 2, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9, 9, 4, 4, (3 * 7) / 2}, - {"WinChip 100", CPU_WINCHIP, fpus_builtin, 10, 100000000, 2, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9, 9, 4, 4, (3 * 8) / 2}, - {"WinChip 120", CPU_WINCHIP, fpus_builtin, 11, 120000000, 2, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12, 12, 6, 6, 2 * 7}, - {"WinChip 133", CPU_WINCHIP, fpus_builtin, 12, 133333333, 2, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12, 12, 6, 6, 2 * 8}, - {"WinChip 150", CPU_WINCHIP, fpus_builtin, 13, 150000000, 3, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15, 15, 7, 7, (5 * 7) / 2}, - {"WinChip 166", CPU_WINCHIP, fpus_builtin, 15, 166666666, 3, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15, 15, 7, 7, (5 * 8) / 2}, - {"WinChip 180", CPU_WINCHIP, fpus_builtin, 16, 180000000, 3, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 3 * 7}, - {"WinChip 200", CPU_WINCHIP, fpus_builtin, 17, 200000000, 3, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 3 * 8}, - {"WinChip 240", CPU_WINCHIP, fpus_builtin, 17, 240000000, 6, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 4 * 7}, - {"WinChip 2/200", CPU_WINCHIP2, fpus_builtin, 17, 200000000, 3, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 3 * 8}, - {"WinChip 2/240", CPU_WINCHIP2, fpus_builtin, 17, 240000000, 6, 30000000, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 30}, - {"WinChip 2A/200", CPU_WINCHIP2, fpus_builtin, 17, 200000000, 3, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 3 * 8}, - {"WinChip 2A/233", CPU_WINCHIP2, fpus_builtin, 17, 233333333, 3, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, (7 * 8) / 2}, - {"", -1, 0, 0, 0} - }; +CPU cpus_WinChip[] = { + /*IDT WinChip*/ + {"WinChip 75", CPU_WINCHIP, fpus_builtin, 7, 75000000, 2, 25000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 4, 4, + (3 * 6) / 2}, + {"WinChip 90", CPU_WINCHIP, fpus_builtin, 9, 90000000, 2, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9, 9, 4, 4, + (3 * 7) / 2}, + {"WinChip 100", CPU_WINCHIP, fpus_builtin, 10, 100000000, 2, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9, 9, 4, 4, + (3 * 8) / 2}, + {"WinChip 120", CPU_WINCHIP, fpus_builtin, 11, 120000000, 2, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12, 12, 6, + 6, 2 * 7}, + {"WinChip 133", CPU_WINCHIP, fpus_builtin, 12, 133333333, 2, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12, 12, 6, + 6, 2 * 8}, + {"WinChip 150", CPU_WINCHIP, fpus_builtin, 13, 150000000, 3, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15, 15, 7, + 7, (5 * 7) / 2}, + {"WinChip 166", CPU_WINCHIP, fpus_builtin, 15, 166666666, 3, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15, 15, 7, + 7, (5 * 8) / 2}, + {"WinChip 180", CPU_WINCHIP, fpus_builtin, 16, 180000000, 3, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, + 9, 3 * 7}, + {"WinChip 200", CPU_WINCHIP, fpus_builtin, 17, 200000000, 3, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, + 9, 3 * 8}, + {"WinChip 240", CPU_WINCHIP, fpus_builtin, 17, 240000000, 6, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, + 12, 4 * 7}, + {"WinChip 2/200", CPU_WINCHIP2, fpus_builtin, 17, 200000000, 3, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18, 18, + 9, 9, 3 * 8}, + {"WinChip 2/240", CPU_WINCHIP2, fpus_builtin, 17, 240000000, 6, 30000000, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24, 24, + 12, 12, 30}, + {"WinChip 2A/200", CPU_WINCHIP2, fpus_builtin, 17, 200000000, 3, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18, 18, + 9, 9, 3 * 8}, + {"WinChip 2A/233", CPU_WINCHIP2, fpus_builtin, 17, 233333333, 3, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18, 18, + 9, 9, (7 * 8) / 2}, + {"", -1, 0, 0, 0}}; -CPU cpus_WinChip_SS7[] = - { - /*IDT WinChip (Super Socket 7)*/ - {"WinChip 200", CPU_WINCHIP, fpus_builtin, 17, 200000000, 3, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 3 * 8}, - {"WinChip 225", CPU_WINCHIP, fpus_builtin, 17, 225000000, 3, 37500000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 3 * 9}, - {"WinChip 240", CPU_WINCHIP, fpus_builtin, 17, 240000000, 6, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 4 * 7}, - {"WinChip 2/200", CPU_WINCHIP2, fpus_builtin, 17, 200000000, 3, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 3 * 8}, - {"WinChip 2/225", CPU_WINCHIP2, fpus_builtin, 17, 225000000, 3, 37500000, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 3 * 9}, - {"WinChip 2/240", CPU_WINCHIP2, fpus_builtin, 17, 240000000, 6, 30000000, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 30}, - {"WinChip 2/250", CPU_WINCHIP2, fpus_builtin, 17, 250000000, 6, 41666667, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 30}, - {"WinChip 2A/200", CPU_WINCHIP2, fpus_builtin, 17, 200000000, 3, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 24}, - {"WinChip 2A/233", CPU_WINCHIP2, fpus_builtin, 17, 233333333, 3, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, 9, 28}, - {"WinChip 2A/266", CPU_WINCHIP2, fpus_builtin, 17, 233333333, 6, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 28}, - {"WinChip 2A/300", CPU_WINCHIP2, fpus_builtin, 17, 250000000, 6, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, 12, 30}, - {"", -1, 0, 0, 0} - }; +CPU cpus_WinChip_SS7[] = { + /*IDT WinChip (Super Socket 7)*/ + {"WinChip 200", CPU_WINCHIP, fpus_builtin, 17, 200000000, 3, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, + 9, 3 * 8}, + {"WinChip 225", CPU_WINCHIP, fpus_builtin, 17, 225000000, 3, 37500000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18, 18, 9, + 9, 3 * 9}, + {"WinChip 240", CPU_WINCHIP, fpus_builtin, 17, 240000000, 6, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 24, 24, 12, + 12, 4 * 7}, + {"WinChip 2/200", CPU_WINCHIP2, fpus_builtin, 17, 200000000, 3, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18, 18, + 9, 9, 3 * 8}, + {"WinChip 2/225", CPU_WINCHIP2, fpus_builtin, 17, 225000000, 3, 37500000, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 18, 18, + 9, 9, 3 * 9}, + {"WinChip 2/240", CPU_WINCHIP2, fpus_builtin, 17, 240000000, 6, 30000000, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24, 24, + 12, 12, 30}, + {"WinChip 2/250", CPU_WINCHIP2, fpus_builtin, 17, 250000000, 6, 41666667, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC, 24, 24, + 12, 12, 30}, + {"WinChip 2A/200", CPU_WINCHIP2, fpus_builtin, 17, 200000000, 3, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18, 18, + 9, 9, 24}, + {"WinChip 2A/233", CPU_WINCHIP2, fpus_builtin, 17, 233333333, 3, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 18, 18, + 9, 9, 28}, + {"WinChip 2A/266", CPU_WINCHIP2, fpus_builtin, 17, 233333333, 6, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 24, 24, + 12, 12, 28}, + {"WinChip 2A/300", CPU_WINCHIP2, fpus_builtin, 17, 250000000, 6, 33333333, 0x587, 0x587, 0, CPU_SUPPORTS_DYNAREC, 24, 24, + 12, 12, 30}, + {"", -1, 0, 0, 0}}; -CPU cpus_Pentium5V[] = - { - /*Intel Pentium (5V, socket 4)*/ - {"Pentium 60", CPU_PENTIUM, fpus_builtin, 6, 60000000, 1, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 7}, - {"Pentium 66", CPU_PENTIUM, fpus_builtin, 6, 66666666, 1, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 8}, - {"Pentium OverDrive 120", CPU_PENTIUM, fpus_builtin, 14, 120000000, 2, 30000000, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12, 12, 6, 6, 2 * 7}, - {"Pentium OverDrive 133", CPU_PENTIUM, fpus_builtin, 16, 133333333, 2, 33333333, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12, 12, 6, 6, 2 * 8}, - {"", -1, 0, 0, 0} - }; +CPU cpus_Pentium5V[] = { + /*Intel Pentium (5V, socket 4)*/ + {"Pentium 60", CPU_PENTIUM, fpus_builtin, 6, 60000000, 1, 30000000, 0x52c, 0x52c, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 7}, + {"Pentium 66", CPU_PENTIUM, fpus_builtin, 6, 66666666, 1, 33333333, 0x52c, 0x52c, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 8}, + {"Pentium OverDrive 120", CPU_PENTIUM, fpus_builtin, 14, 120000000, 2, 30000000, 0x51A, 0x51A, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12, 12, 6, 6, 2 * 7}, + {"Pentium OverDrive 133", CPU_PENTIUM, fpus_builtin, 16, 133333333, 2, 33333333, 0x51A, 0x51A, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12, 12, 6, 6, 2 * 8}, + {"", -1, 0, 0, 0}}; -CPU cpus_PentiumS5[] = - { - /*Intel Pentium (Socket 5)*/ - {"Pentium 75", CPU_PENTIUM, fpus_builtin, 9, 75000000, 2, 25000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, (3 * 6) / 2}, - {"Pentium 90", CPU_PENTIUM, fpus_builtin, 12, 90000000, 2, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, (3 * 7) / 2}, - {"Pentium 100/50", CPU_PENTIUM, fpus_builtin, 13, 100000000, 2, 25000000, 0x525, 0x525, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10, 10, 6, 6, 2 * 6}, - {"Pentium 100/66", CPU_PENTIUM, fpus_builtin, 13, 100000000, 2, 33333333, 0x525, 0x525, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, (3 * 8) / 2}, - {"Pentium 120", CPU_PENTIUM, fpus_builtin, 14, 120000000, 2, 30000000, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12, 12, 6, 6, 2 * 7}, - {"Pentium 133", CPU_PENTIUM, fpus_builtin, 16, 133333333, 2, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12, 12, 6, 6, 2 * 8}, - {"Pentium OverDrive 125", CPU_PENTIUM, fpus_builtin, 15, 125000000, 3, 25000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12, 12, 7, 7, (5 * 6) / 2}, - {"Pentium OverDrive 150", CPU_PENTIUM, fpus_builtin, 17, 150000000, 3, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15, 15, 7, 7, (5 * 7) / 2}, - {"Pentium OverDrive 166", CPU_PENTIUM, fpus_builtin, 17, 166666666, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15, 15, 7, 7, (5 * 8) / 2}, - {"Pentium OverDrive MMX 125", CPU_PENTIUMMMX, fpus_builtin, 15, 125000000, 3, 25000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12, 12, 7, 7, (5 * 6) / 2}, - {"Pentium OverDrive MMX 150/60", CPU_PENTIUMMMX, fpus_builtin, 17, 150000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15, 15, 7, 7, (5 * 7) / 2}, - {"Pentium OverDrive MMX 166", CPU_PENTIUMMMX, fpus_builtin, 19, 166000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15, 15, 7, 7, (5 * 8) / 2}, - {"Pentium OverDrive MMX 180", CPU_PENTIUMMMX, fpus_builtin, 20, 180000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 3 * 7}, - {"Pentium OverDrive MMX 200", CPU_PENTIUMMMX, fpus_builtin, 21, 200000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 3 * 8}, - {"", -1, 0, 0, 0} - }; +CPU cpus_PentiumS5[] = { + /*Intel Pentium (Socket 5)*/ + {"Pentium 75", CPU_PENTIUM, fpus_builtin, 9, 75000000, 2, 25000000, 0x524, 0x524, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, (3 * 6) / 2}, + {"Pentium 90", CPU_PENTIUM, fpus_builtin, 12, 90000000, 2, 30000000, 0x524, 0x524, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, (3 * 7) / 2}, + {"Pentium 100/50", CPU_PENTIUM, fpus_builtin, 13, 100000000, 2, 25000000, 0x525, 0x525, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10, 10, 6, 6, 2 * 6}, + {"Pentium 100/66", CPU_PENTIUM, fpus_builtin, 13, 100000000, 2, 33333333, 0x525, 0x525, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, (3 * 8) / 2}, + {"Pentium 120", CPU_PENTIUM, fpus_builtin, 14, 120000000, 2, 30000000, 0x526, 0x526, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12, 12, 6, 6, 2 * 7}, + {"Pentium 133", CPU_PENTIUM, fpus_builtin, 16, 133333333, 2, 33333333, 0x52c, 0x52c, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12, 12, 6, 6, 2 * 8}, + {"Pentium OverDrive 125", CPU_PENTIUM, fpus_builtin, 15, 125000000, 3, 25000000, 0x52c, 0x52c, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12, 12, 7, 7, (5 * 6) / 2}, + {"Pentium OverDrive 150", CPU_PENTIUM, fpus_builtin, 17, 150000000, 3, 30000000, 0x52c, 0x52c, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15, 15, 7, 7, (5 * 7) / 2}, + {"Pentium OverDrive 166", CPU_PENTIUM, fpus_builtin, 17, 166666666, 3, 33333333, 0x52c, 0x52c, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15, 15, 7, 7, (5 * 8) / 2}, + {"Pentium OverDrive MMX 125", CPU_PENTIUMMMX, fpus_builtin, 15, 125000000, 3, 25000000, 0x1542, 0x1542, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12, 12, 7, 7, (5 * 6) / 2}, + {"Pentium OverDrive MMX 150/60", CPU_PENTIUMMMX, fpus_builtin, 17, 150000000, 3, 30000000, 0x1542, 0x1542, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15, 15, 7, 7, (5 * 7) / 2}, + {"Pentium OverDrive MMX 166", CPU_PENTIUMMMX, fpus_builtin, 19, 166000000, 3, 33333333, 0x1542, 0x1542, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15, 15, 7, 7, (5 * 8) / 2}, + {"Pentium OverDrive MMX 180", CPU_PENTIUMMMX, fpus_builtin, 20, 180000000, 3, 30000000, 0x1542, 0x1542, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 3 * 7}, + {"Pentium OverDrive MMX 200", CPU_PENTIUMMMX, fpus_builtin, 21, 200000000, 3, 33333333, 0x1542, 0x1542, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 3 * 8}, + {"", -1, 0, 0, 0}}; -CPU cpus_Pentium[] = - { - /*Intel Pentium*/ - {"Pentium 75", CPU_PENTIUM, fpus_builtin, 9, 75000000, 2, 25000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, (3 * 6) / 2}, - {"Pentium 90", CPU_PENTIUM, fpus_builtin, 12, 90000000, 2, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, (3 * 7) / 2}, - {"Pentium 100/50", CPU_PENTIUM, fpus_builtin, 13, 100000000, 2, 25000000, 0x525, 0x525, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10, 10, 6, 6, 2 * 6}, - {"Pentium 100/66", CPU_PENTIUM, fpus_builtin, 13, 100000000, 2, 33333333, 0x525, 0x525, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, (3 * 8) / 2}, - {"Pentium 120", CPU_PENTIUM, fpus_builtin, 14, 120000000, 2, 30000000, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12, 12, 6, 6, 2 * 7}, - {"Pentium 133", CPU_PENTIUM, fpus_builtin, 16, 133333333, 2, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12, 12, 6, 6, 2 * 8}, - {"Pentium 150", CPU_PENTIUM, fpus_builtin, 17, 150000000, 3, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15, 15, 7, 7, (5 * 7) / 2}, - {"Pentium 166", CPU_PENTIUM, fpus_builtin, 19, 166666666, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15, 15, 7, 7, (5 * 8) / 2}, - {"Pentium 200", CPU_PENTIUM, fpus_builtin, 21, 200000000, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 3 * 8}, - {"Pentium MMX 166", CPU_PENTIUMMMX, fpus_builtin, 19, 166666666, 3, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15, 15, 7, 7, (5 * 8) / 2}, - {"Pentium MMX 200", CPU_PENTIUMMMX, fpus_builtin, 21, 200000000, 3, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 3 * 8}, - {"Pentium MMX 233", CPU_PENTIUMMMX, fpus_builtin, 24, 233333333, 4, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21, 21, 10, 10, (7 * 8) / 2}, - {"Mobile Pentium MMX 120", CPU_PENTIUMMMX, fpus_builtin, 14, 120000000, 2, 30000000, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12, 12, 6, 6, 2 * 7}, - {"Mobile Pentium MMX 133", CPU_PENTIUMMMX, fpus_builtin, 16, 133333333, 2, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12, 12, 6, 6, 2 * 8}, - {"Mobile Pentium MMX 150", CPU_PENTIUMMMX, fpus_builtin, 17, 150000000, 3, 30000000, 0x544, 0x544, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15, 15, 7, 7, (5 * 7) / 2}, - {"Mobile Pentium MMX 166", CPU_PENTIUMMMX, fpus_builtin, 19, 166666666, 3, 33333333, 0x544, 0x544, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15, 15, 7, 7, (5 * 8) / 2}, - {"Mobile Pentium MMX 200", CPU_PENTIUMMMX, fpus_builtin, 21, 200000000, 3, 33333333, 0x581, 0x581, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 3 * 8}, - {"Mobile Pentium MMX 233", CPU_PENTIUMMMX, fpus_builtin, 24, 233333333, 4, 33333333, 0x581, 0x581, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21, 21, 10, 10, (7 * 8) / 2}, - {"Mobile Pentium MMX 266", CPU_PENTIUMMMX, fpus_builtin, 26, 266666666, 4, 33333333, 0x582, 0x582, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24, 24, 12, 12, 4 * 8}, - {"Mobile Pentium MMX 300", CPU_PENTIUMMMX, fpus_builtin, 28, 300000000, 5, 33333333, 0x582, 0x582, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 13, 13, (9 * 8) / 2}, - {"Pentium OverDrive 125", CPU_PENTIUM, fpus_builtin, 15, 125000000, 3, 25000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12, 12, 7, 7, (5 * 6) / 2}, - {"Pentium OverDrive 150", CPU_PENTIUM, fpus_builtin, 17, 150000000, 3, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15, 15, 7, 7, (5 * 7) / 2}, - {"Pentium OverDrive 166", CPU_PENTIUM, fpus_builtin, 17, 166666666, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15, 15, 7, 7, (5 * 8) / 2}, - {"Pentium OverDrive MMX 125", CPU_PENTIUMMMX, fpus_builtin, 15, 125000000, 3, 25000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12, 12, 7, 7, (5 * 6) / 2}, - {"Pentium OverDrive MMX 150/60", CPU_PENTIUMMMX, fpus_builtin, 17, 150000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15, 15, 7, 7, (5 * 7) / 2}, - {"Pentium OverDrive MMX 166", CPU_PENTIUMMMX, fpus_builtin, 19, 166000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15, 15, 7, 7, (5 * 8) / 2}, - {"Pentium OverDrive MMX 180", CPU_PENTIUMMMX, fpus_builtin, 20, 180000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 3 * 7}, - {"Pentium OverDrive MMX 200", CPU_PENTIUMMMX, fpus_builtin, 21, 200000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 3 * 8}, - {"", -1, 0, 0, 0} - }; +CPU cpus_Pentium[] = { + /*Intel Pentium*/ + {"Pentium 75", CPU_PENTIUM, fpus_builtin, 9, 75000000, 2, 25000000, 0x524, 0x524, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, (3 * 6) / 2}, + {"Pentium 90", CPU_PENTIUM, fpus_builtin, 12, 90000000, 2, 30000000, 0x524, 0x524, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, (3 * 7) / 2}, + {"Pentium 100/50", CPU_PENTIUM, fpus_builtin, 13, 100000000, 2, 25000000, 0x525, 0x525, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10, 10, 6, 6, 2 * 6}, + {"Pentium 100/66", CPU_PENTIUM, fpus_builtin, 13, 100000000, 2, 33333333, 0x525, 0x525, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, (3 * 8) / 2}, + {"Pentium 120", CPU_PENTIUM, fpus_builtin, 14, 120000000, 2, 30000000, 0x526, 0x526, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12, 12, 6, 6, 2 * 7}, + {"Pentium 133", CPU_PENTIUM, fpus_builtin, 16, 133333333, 2, 33333333, 0x52c, 0x52c, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12, 12, 6, 6, 2 * 8}, + {"Pentium 150", CPU_PENTIUM, fpus_builtin, 17, 150000000, 3, 30000000, 0x52c, 0x52c, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15, 15, 7, 7, (5 * 7) / 2}, + {"Pentium 166", CPU_PENTIUM, fpus_builtin, 19, 166666666, 3, 33333333, 0x52c, 0x52c, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15, 15, 7, 7, (5 * 8) / 2}, + {"Pentium 200", CPU_PENTIUM, fpus_builtin, 21, 200000000, 3, 33333333, 0x52c, 0x52c, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 3 * 8}, + {"Pentium MMX 166", CPU_PENTIUMMMX, fpus_builtin, 19, 166666666, 3, 33333333, 0x543, 0x543, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15, 15, 7, 7, (5 * 8) / 2}, + {"Pentium MMX 200", CPU_PENTIUMMMX, fpus_builtin, 21, 200000000, 3, 33333333, 0x543, 0x543, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 3 * 8}, + {"Pentium MMX 233", CPU_PENTIUMMMX, fpus_builtin, 24, 233333333, 4, 33333333, 0x543, 0x543, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21, 21, 10, 10, (7 * 8) / 2}, + {"Mobile Pentium MMX 120", CPU_PENTIUMMMX, fpus_builtin, 14, 120000000, 2, 30000000, 0x543, 0x543, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12, 12, 6, 6, 2 * 7}, + {"Mobile Pentium MMX 133", CPU_PENTIUMMMX, fpus_builtin, 16, 133333333, 2, 33333333, 0x543, 0x543, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12, 12, 6, 6, 2 * 8}, + {"Mobile Pentium MMX 150", CPU_PENTIUMMMX, fpus_builtin, 17, 150000000, 3, 30000000, 0x544, 0x544, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15, 15, 7, 7, (5 * 7) / 2}, + {"Mobile Pentium MMX 166", CPU_PENTIUMMMX, fpus_builtin, 19, 166666666, 3, 33333333, 0x544, 0x544, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15, 15, 7, 7, (5 * 8) / 2}, + {"Mobile Pentium MMX 200", CPU_PENTIUMMMX, fpus_builtin, 21, 200000000, 3, 33333333, 0x581, 0x581, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 3 * 8}, + {"Mobile Pentium MMX 233", CPU_PENTIUMMMX, fpus_builtin, 24, 233333333, 4, 33333333, 0x581, 0x581, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21, 21, 10, 10, (7 * 8) / 2}, + {"Mobile Pentium MMX 266", CPU_PENTIUMMMX, fpus_builtin, 26, 266666666, 4, 33333333, 0x582, 0x582, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24, 24, 12, 12, 4 * 8}, + {"Mobile Pentium MMX 300", CPU_PENTIUMMMX, fpus_builtin, 28, 300000000, 5, 33333333, 0x582, 0x582, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 13, 13, (9 * 8) / 2}, + {"Pentium OverDrive 125", CPU_PENTIUM, fpus_builtin, 15, 125000000, 3, 25000000, 0x52c, 0x52c, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12, 12, 7, 7, (5 * 6) / 2}, + {"Pentium OverDrive 150", CPU_PENTIUM, fpus_builtin, 17, 150000000, 3, 30000000, 0x52c, 0x52c, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15, 15, 7, 7, (5 * 7) / 2}, + {"Pentium OverDrive 166", CPU_PENTIUM, fpus_builtin, 17, 166666666, 3, 33333333, 0x52c, 0x52c, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15, 15, 7, 7, (5 * 8) / 2}, + {"Pentium OverDrive MMX 125", CPU_PENTIUMMMX, fpus_builtin, 15, 125000000, 3, 25000000, 0x1542, 0x1542, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12, 12, 7, 7, (5 * 6) / 2}, + {"Pentium OverDrive MMX 150/60", CPU_PENTIUMMMX, fpus_builtin, 17, 150000000, 3, 30000000, 0x1542, 0x1542, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15, 15, 7, 7, (5 * 7) / 2}, + {"Pentium OverDrive MMX 166", CPU_PENTIUMMMX, fpus_builtin, 19, 166000000, 3, 33333333, 0x1542, 0x1542, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15, 15, 7, 7, (5 * 8) / 2}, + {"Pentium OverDrive MMX 180", CPU_PENTIUMMMX, fpus_builtin, 20, 180000000, 3, 30000000, 0x1542, 0x1542, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 3 * 7}, + {"Pentium OverDrive MMX 200", CPU_PENTIUMMMX, fpus_builtin, 21, 200000000, 3, 33333333, 0x1542, 0x1542, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 3 * 8}, + {"", -1, 0, 0, 0}}; -CPU cpus_K6_S7[] = - { - /*AMD K6*/ - {"K6/166", CPU_K6, fpus_builtin, 19, 166666666, 3, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15, 15, 7, 7, 20}, - {"K6/200", CPU_K6, fpus_builtin, 21, 200000000, 3, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 24}, - {"K6/233", CPU_K6, fpus_builtin, 24, 233333333, 4, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21, 21, 10, 10, 28}, - {"K6/266", CPU_K6, fpus_builtin, 26, 266666666, 4, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24, 24, 12, 12, 32}, - {"K6/300", CPU_K6, fpus_builtin, 28, 300000000, 5, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 13, 13, 36}, - {"K6-2/233", CPU_K6_2, fpus_builtin, 24, 233333333, 4, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21, 21, 10, 10, 28}, - {"K6-2/266", CPU_K6_2, fpus_builtin, 26, 266666666, 4, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24, 24, 12, 12, 32}, - {"K6-2/300 AFR-66", CPU_K6_2, fpus_builtin, 28, 300000000, 5, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 13, 13, 36}, - {"", -1, 0, 0, 0} - }; +CPU cpus_K6_S7[] = { + /*AMD K6*/ + {"K6/166", CPU_K6, fpus_builtin, 19, 166666666, 3, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, + 15, 15, 7, 7, 20}, + {"K6/200", CPU_K6, fpus_builtin, 21, 200000000, 3, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, + 18, 18, 9, 9, 24}, + {"K6/233", CPU_K6, fpus_builtin, 24, 233333333, 4, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, + 21, 21, 10, 10, 28}, + {"K6/266", CPU_K6, fpus_builtin, 26, 266666666, 4, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, + 24, 24, 12, 12, 32}, + {"K6/300", CPU_K6, fpus_builtin, 28, 300000000, 5, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, + 27, 27, 13, 13, 36}, + {"K6-2/233", CPU_K6_2, fpus_builtin, 24, 233333333, 4, 33333333, 0x580, 0x580, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21, 21, 10, 10, 28}, + {"K6-2/266", CPU_K6_2, fpus_builtin, 26, 266666666, 4, 33333333, 0x580, 0x580, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24, 24, 12, 12, 32}, + {"K6-2/300 AFR-66", CPU_K6_2, fpus_builtin, 28, 300000000, 5, 33333333, 0x580, 0x580, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 13, 13, 36}, + {"", -1, 0, 0, 0}}; -CPU cpus_K6_SS7[] = - { - /*AMD K6*/ - {"K6/166", CPU_K6, fpus_builtin, 19, 166666666, 3, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15, 15, 7, 7, 20}, - {"K6/200", CPU_K6, fpus_builtin, 21, 200000000, 3, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 24}, - {"K6/233", CPU_K6, fpus_builtin, 24, 233333333, 4, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21, 21, 10, 10, 28}, - {"K6/266", CPU_K6, fpus_builtin, 26, 266666666, 4, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24, 24, 12, 12, 32}, - {"K6/300", CPU_K6, fpus_builtin, 28, 300000000, 5, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 13, 13, 36}, - {"K6-2/233", CPU_K6_2, fpus_builtin, 24, 233333333, 4, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21, 21, 10, 10, 28}, - {"K6-2/266", CPU_K6_2, fpus_builtin, 26, 266666666, 4, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24, 24, 12, 12, 32}, - {"K6-2/300", CPU_K6_2, fpus_builtin, 28, 300000000, 5, 33333333, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 13, 13, 36}, - {"K6-2/333", CPU_K6_2, fpus_builtin, 28, 333333333, 5, 31666667, 0x580, 0x580, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 13, 13, 40}, - {"K6-2/350", CPU_K6_2, fpus_builtin, 28, 350000000, 5, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 13, 13, 42}, - {"K6-2/366", CPU_K6_2, fpus_builtin, 28, 366666666, 5, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 13, 13, 44}, - {"K6-2/380", CPU_K6_2, fpus_builtin, 28, 380000000, 5, 31666667, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 13, 13, 46}, - {"K6-2/400", CPU_K6_2, fpus_builtin, 28, 400000000, 5, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 13, 13, 48}, - {"K6-2/450", CPU_K6_2, fpus_builtin, 28, 450000000, 5, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 13, 13, 54}, - {"K6-2/475", CPU_K6_2, fpus_builtin, 28, 475000000, 5, 31666667, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 13, 13, 57}, - {"K6-2/500", CPU_K6_2, fpus_builtin, 28, 500000000, 5, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 13, 13, 60}, - {"K6-2/533", CPU_K6_2, fpus_builtin, 28, 533333333, 5, 31666667, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 13, 13, 64}, - {"K6-2/550", CPU_K6_2, fpus_builtin, 28, 550000000, 5, 33333333, 0x58c, 0x58c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 13, 13, 66}, - {"K6-2+/450", CPU_K6_2P, fpus_builtin, 28, 450000000, 5, 33333333, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 13, 13, 54}, - {"K6-2+/475", CPU_K6_2P, fpus_builtin, 28, 475000000, 5, 31666667, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 13, 13, 57}, - {"K6-2+/500", CPU_K6_2P, fpus_builtin, 28, 500000000, 5, 33333333, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 13, 13, 60}, - {"K6-2+/533", CPU_K6_2P, fpus_builtin, 28, 533333333, 5, 31666667, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 13, 13, 64}, - {"K6-2+/550", CPU_K6_2P, fpus_builtin, 28, 550000000, 5, 33333333, 0x5d4, 0x5d4, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 13, 13, 66}, - {"K6-III/400", CPU_K6_3, fpus_builtin, 28, 400000000, 5, 33333333, 0x591, 0x591, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 13, 13, 48}, - {"K6-III/450", CPU_K6_3, fpus_builtin, 28, 450000000, 5, 33333333, 0x591, 0x591, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 13, 13, 54}, - {"K6-III+/400", CPU_K6_3P, fpus_builtin, 28, 400000000, 5, 33333333, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 13, 13, 48}, - {"K6-III+/450", CPU_K6_3P, fpus_builtin, 28, 450000000, 5, 33333333, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 13, 13, 54}, - {"K6-III+/475", CPU_K6_3P, fpus_builtin, 28, 475000000, 5, 31666667, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 13, 13, 57}, - {"K6-III+/500", CPU_K6_3P, fpus_builtin, 28, 500000000, 5, 33333333, 0x5d0, 0x5d0, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 13, 13, 60}, - {"", -1, 0, 0, 0} - }; +CPU cpus_K6_SS7[] = { + /*AMD K6*/ + {"K6/166", CPU_K6, fpus_builtin, 19, 166666666, 3, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, + 15, 15, 7, 7, 20}, + {"K6/200", CPU_K6, fpus_builtin, 21, 200000000, 3, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, + 18, 18, 9, 9, 24}, + {"K6/233", CPU_K6, fpus_builtin, 24, 233333333, 4, 33333333, 0x561, 0x561, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, + 21, 21, 10, 10, 28}, + {"K6/266", CPU_K6, fpus_builtin, 26, 266666666, 4, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, + 24, 24, 12, 12, 32}, + {"K6/300", CPU_K6, fpus_builtin, 28, 300000000, 5, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, + 27, 27, 13, 13, 36}, + {"K6-2/233", CPU_K6_2, fpus_builtin, 24, 233333333, 4, 33333333, 0x580, 0x580, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21, 21, 10, 10, 28}, + {"K6-2/266", CPU_K6_2, fpus_builtin, 26, 266666666, 4, 33333333, 0x580, 0x580, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24, 24, 12, 12, 32}, + {"K6-2/300", CPU_K6_2, fpus_builtin, 28, 300000000, 5, 33333333, 0x580, 0x580, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 13, 13, 36}, + {"K6-2/333", CPU_K6_2, fpus_builtin, 28, 333333333, 5, 31666667, 0x580, 0x580, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 13, 13, 40}, + {"K6-2/350", CPU_K6_2, fpus_builtin, 28, 350000000, 5, 33333333, 0x58c, 0x58c, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 13, 13, 42}, + {"K6-2/366", CPU_K6_2, fpus_builtin, 28, 366666666, 5, 33333333, 0x58c, 0x58c, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 13, 13, 44}, + {"K6-2/380", CPU_K6_2, fpus_builtin, 28, 380000000, 5, 31666667, 0x58c, 0x58c, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 13, 13, 46}, + {"K6-2/400", CPU_K6_2, fpus_builtin, 28, 400000000, 5, 33333333, 0x58c, 0x58c, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 13, 13, 48}, + {"K6-2/450", CPU_K6_2, fpus_builtin, 28, 450000000, 5, 33333333, 0x58c, 0x58c, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 13, 13, 54}, + {"K6-2/475", CPU_K6_2, fpus_builtin, 28, 475000000, 5, 31666667, 0x58c, 0x58c, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 13, 13, 57}, + {"K6-2/500", CPU_K6_2, fpus_builtin, 28, 500000000, 5, 33333333, 0x58c, 0x58c, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 13, 13, 60}, + {"K6-2/533", CPU_K6_2, fpus_builtin, 28, 533333333, 5, 31666667, 0x58c, 0x58c, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 13, 13, 64}, + {"K6-2/550", CPU_K6_2, fpus_builtin, 28, 550000000, 5, 33333333, 0x58c, 0x58c, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 13, 13, 66}, + {"K6-2+/450", CPU_K6_2P, fpus_builtin, 28, 450000000, 5, 33333333, 0x5d4, 0x5d4, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 13, 13, 54}, + {"K6-2+/475", CPU_K6_2P, fpus_builtin, 28, 475000000, 5, 31666667, 0x5d4, 0x5d4, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 13, 13, 57}, + {"K6-2+/500", CPU_K6_2P, fpus_builtin, 28, 500000000, 5, 33333333, 0x5d4, 0x5d4, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 13, 13, 60}, + {"K6-2+/533", CPU_K6_2P, fpus_builtin, 28, 533333333, 5, 31666667, 0x5d4, 0x5d4, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 13, 13, 64}, + {"K6-2+/550", CPU_K6_2P, fpus_builtin, 28, 550000000, 5, 33333333, 0x5d4, 0x5d4, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 13, 13, 66}, + {"K6-III/400", CPU_K6_3, fpus_builtin, 28, 400000000, 5, 33333333, 0x591, 0x591, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 13, 13, 48}, + {"K6-III/450", CPU_K6_3, fpus_builtin, 28, 450000000, 5, 33333333, 0x591, 0x591, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 13, 13, 54}, + {"K6-III+/400", CPU_K6_3P, fpus_builtin, 28, 400000000, 5, 33333333, 0x5d0, 0x5d0, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 13, 13, 48}, + {"K6-III+/450", CPU_K6_3P, fpus_builtin, 28, 450000000, 5, 33333333, 0x5d0, 0x5d0, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 13, 13, 54}, + {"K6-III+/475", CPU_K6_3P, fpus_builtin, 28, 475000000, 5, 31666667, 0x5d0, 0x5d0, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 13, 13, 57}, + {"K6-III+/500", CPU_K6_3P, fpus_builtin, 28, 500000000, 5, 33333333, 0x5d0, 0x5d0, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27, 27, 13, 13, 60}, + {"", -1, 0, 0, 0}}; -CPU cpus_PentiumPro[] = - { - /*Intel Pentium Pro*/ - {"Pentium Pro 150", CPU_PENTIUMPRO, fpus_builtin, 17, 150000000, 3, 30000000, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15, 15, 7, 7, (5 * 7) / 2}, - {"Pentium Pro 166", CPU_PENTIUMPRO, fpus_builtin, 19, 166666666, 3, 33333333, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15, 15, 7, 7, (5 * 8) / 2}, - {"Pentium Pro 180", CPU_PENTIUMPRO, fpus_builtin, 20, 180000000, 3, 30000000, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 3 * 8}, - {"Pentium Pro 200", CPU_PENTIUMPRO, fpus_builtin, 21, 200000000, 3, 33333333, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 3 * 8}, - {"Pentium II Overdrive 300", CPU_PENTIUM_2, fpus_builtin, 20, 300000000, 3, 30000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 36}, - {"Pentium II Overdrive 333", CPU_PENTIUM_2, fpus_builtin, 21, 333333333, 3, 33333333, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 40}, - {"", -1, 0, 0, 0} - }; +CPU cpus_PentiumPro[] = { + /*Intel Pentium Pro*/ + {"Pentium Pro 150", CPU_PENTIUMPRO, fpus_builtin, 17, 150000000, 3, 30000000, 0x617, 0x617, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15, 15, 7, 7, (5 * 7) / 2}, + {"Pentium Pro 166", CPU_PENTIUMPRO, fpus_builtin, 19, 166666666, 3, 33333333, 0x617, 0x617, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15, 15, 7, 7, (5 * 8) / 2}, + {"Pentium Pro 180", CPU_PENTIUMPRO, fpus_builtin, 20, 180000000, 3, 30000000, 0x617, 0x617, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 3 * 8}, + {"Pentium Pro 200", CPU_PENTIUMPRO, fpus_builtin, 21, 200000000, 3, 33333333, 0x617, 0x617, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 3 * 8}, + {"Pentium II Overdrive 300", CPU_PENTIUM_2, fpus_builtin, 20, 300000000, 3, 30000000, 0x1632, 0x1632, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 36}, + {"Pentium II Overdrive 333", CPU_PENTIUM_2, fpus_builtin, 21, 333333333, 3, 33333333, 0x1632, 0x1632, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 40}, + {"", -1, 0, 0, 0}}; -CPU cpus_Slot1_100MHz[] = - { - /*Intel Pentium II*/ - {"Pentium II/233", CPU_PENTIUM_2, fpus_builtin, 20, 233333333, 3, 33333333, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 28}, - {"Pentium II/266", CPU_PENTIUM_2, fpus_builtin, 20, 266666666, 3, 33333333, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 32}, - {"Pentium II/300", CPU_PENTIUM_2, fpus_builtin, 20, 300000000, 3, 33333333, 0x634, 0x634, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 36}, - {"Pentium II/333", CPU_PENTIUM_2, fpus_builtin, 20, 333333333, 3, 33333333, 0x651, 0x651, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 40}, - {"Pentium II/350", CPU_PENTIUM_2, fpus_builtin, 20, 350000000, 3, 33333333, 0x651, 0x651, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 42}, - {"Pentium II/400", CPU_PENTIUM_2, fpus_builtin, 20, 400000000, 3, 33333333, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 48}, - {"Pentium II/450", CPU_PENTIUM_2, fpus_builtin, 20, 450000000, 3, 33333333, 0x652, 0x652, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 54}, - {"Celeron 266", CPU_CELERON, fpus_builtin, 20, 266666666, 3, 33333333, 0x650, 0x650, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 32}, - {"Celeron 300", CPU_CELERON, fpus_builtin, 20, 300000000, 3, 33333333, 0x650, 0x650, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 36}, - {"Celeron-A 300", CPU_CELERON_A, fpus_builtin, 20, 300000000, 3, 33333333, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 40}, - {"Celeron 333", CPU_CELERON_A, fpus_builtin, 20, 333333333, 3, 33333333, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 44}, - {"Celeron 366", CPU_CELERON_A, fpus_builtin, 20, 366666666, 3, 33333333, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 48}, - {"Celeron 400", CPU_CELERON_A, fpus_builtin, 20, 400000000, 3, 33333333, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 52}, - {"Celeron 433", CPU_CELERON_A, fpus_builtin, 20, 433333333, 3, 33333333, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 56}, - {"Celeron 466", CPU_CELERON_A, fpus_builtin, 20, 466666666, 3, 33333333, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 60}, - {"Celeron 500", CPU_CELERON_A, fpus_builtin, 20, 500000000, 3, 33333333, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 64}, - {"Celeron 533", CPU_CELERON_A, fpus_builtin, 20, 533333333, 3, 33333333, 0x660, 0x660, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 68}, - {"", -1, 0, 0, 0} - }; +CPU cpus_Slot1_100MHz[] = { + /*Intel Pentium II*/ + {"Pentium II/233", CPU_PENTIUM_2, fpus_builtin, 20, 233333333, 3, 33333333, 0x634, 0x634, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 28}, + {"Pentium II/266", CPU_PENTIUM_2, fpus_builtin, 20, 266666666, 3, 33333333, 0x634, 0x634, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 32}, + {"Pentium II/300", CPU_PENTIUM_2, fpus_builtin, 20, 300000000, 3, 33333333, 0x634, 0x634, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 36}, + {"Pentium II/333", CPU_PENTIUM_2, fpus_builtin, 20, 333333333, 3, 33333333, 0x651, 0x651, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 40}, + {"Pentium II/350", CPU_PENTIUM_2, fpus_builtin, 20, 350000000, 3, 33333333, 0x651, 0x651, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 42}, + {"Pentium II/400", CPU_PENTIUM_2, fpus_builtin, 20, 400000000, 3, 33333333, 0x652, 0x652, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 48}, + {"Pentium II/450", CPU_PENTIUM_2, fpus_builtin, 20, 450000000, 3, 33333333, 0x652, 0x652, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 54}, + {"Celeron 266", CPU_CELERON, fpus_builtin, 20, 266666666, 3, 33333333, 0x650, 0x650, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 32}, + {"Celeron 300", CPU_CELERON, fpus_builtin, 20, 300000000, 3, 33333333, 0x650, 0x650, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 36}, + {"Celeron-A 300", CPU_CELERON_A, fpus_builtin, 20, 300000000, 3, 33333333, 0x660, 0x660, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 40}, + {"Celeron 333", CPU_CELERON_A, fpus_builtin, 20, 333333333, 3, 33333333, 0x660, 0x660, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 44}, + {"Celeron 366", CPU_CELERON_A, fpus_builtin, 20, 366666666, 3, 33333333, 0x660, 0x660, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 48}, + {"Celeron 400", CPU_CELERON_A, fpus_builtin, 20, 400000000, 3, 33333333, 0x660, 0x660, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 52}, + {"Celeron 433", CPU_CELERON_A, fpus_builtin, 20, 433333333, 3, 33333333, 0x660, 0x660, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 56}, + {"Celeron 466", CPU_CELERON_A, fpus_builtin, 20, 466666666, 3, 33333333, 0x660, 0x660, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 60}, + {"Celeron 500", CPU_CELERON_A, fpus_builtin, 20, 500000000, 3, 33333333, 0x660, 0x660, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 64}, + {"Celeron 533", CPU_CELERON_A, fpus_builtin, 20, 533333333, 3, 33333333, 0x660, 0x660, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 68}, + {"", -1, 0, 0, 0}}; -CPU cpus_VIA_100MHz[] = - { - /*VIA Cyrix III*/ - {"Cyrix III/500", CPU_CYRIX_III, fpus_builtin, 20, 500000000, 3, 33333333, 0x663, 0x663, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 64}, -/*Below are disabled as Windows 98 won't boot. This is most likely a limitation of the timer system*/ -/* {"Cyrix III/550", CPU_CYRIX_III, fpus_builtin, 20, 550000000, 3, 33333333, 0x663, 0x663, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 70}, - {"Cyrix III/600", CPU_CYRIX_III, fpus_builtin, 20, 600000000, 3, 33333333, 0x663, 0x663, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 76}, - {"Cyrix III/650", CPU_CYRIX_III, fpus_builtin, 20, 650000000, 3, 33333333, 0x663, 0x663, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 82}, - {"Cyrix III/700", CPU_CYRIX_III, fpus_builtin, 20, 700000000, 3, 33333333, 0x663, 0x663, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 88}, - {"C3/750", CPU_CYRIX_III, fpus_builtin, 20, 750000000, 3, 33333333, 0x673, 0x673, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 94}, - {"C3/800", CPU_CYRIX_III, fpus_builtin, 20, 800000000, 3, 33333333, 0x673, 0x673, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 100},*/ - {"", -1, 0, 0, 0} - }; +CPU cpus_VIA_100MHz[] = { + /*VIA Cyrix III*/ + {"Cyrix III/500", CPU_CYRIX_III, fpus_builtin, 20, 500000000, 3, 33333333, 0x663, 0x663, 0, + CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18, 18, 9, 9, 64}, + /*Below are disabled as Windows 98 won't boot. This is most likely a limitation of the timer system*/ + /* {"Cyrix III/550", CPU_CYRIX_III, fpus_builtin, 20, 550000000, 3, 33333333, 0x663, 0x663, 0, CPU_SUPPORTS_DYNAREC + | CPU_REQUIRES_DYNAREC, 18,18,9,9, 70}, + {"Cyrix III/600", CPU_CYRIX_III, fpus_builtin, 20, 600000000, 3, 33333333, 0x663, 0x663, 0, CPU_SUPPORTS_DYNAREC | + CPU_REQUIRES_DYNAREC, 18,18,9,9, 76}, + {"Cyrix III/650", CPU_CYRIX_III, fpus_builtin, 20, 650000000, 3, 33333333, 0x663, 0x663, 0, CPU_SUPPORTS_DYNAREC | + CPU_REQUIRES_DYNAREC, 18,18,9,9, 82}, + {"Cyrix III/700", CPU_CYRIX_III, fpus_builtin, 20, 700000000, 3, 33333333, 0x663, 0x663, 0, CPU_SUPPORTS_DYNAREC | + CPU_REQUIRES_DYNAREC, 18,18,9,9, 88}, + {"C3/750", CPU_CYRIX_III, fpus_builtin, 20, 750000000, 3, 33333333, 0x673, 0x673, 0, CPU_SUPPORTS_DYNAREC | + CPU_REQUIRES_DYNAREC, 18,18,9,9, 94}, + {"C3/800", CPU_CYRIX_III, fpus_builtin, 20, 800000000, 3, 33333333, 0x673, 0x673, 0, CPU_SUPPORTS_DYNAREC | + CPU_REQUIRES_DYNAREC, 18,18,9,9, 100},*/ + {"", -1, 0, 0, 0}}; diff --git a/src/cpu/x86seg.c b/src/cpu/x86seg.c index 1361bc4f..3e404bb1 100644 --- a/src/cpu/x86seg.c +++ b/src/cpu/x86seg.c @@ -38,3101 +38,3150 @@ void taskswitch386(uint16_t seg, uint16_t *segdat); GPF is INT 0D*/ void x86abort(const char *format, ...) { - va_list ap; - va_start(ap, format); - error(format, ap); - va_end(ap); - dumpregs(); - pclog_end(); - exit(-1); + va_list ap; + va_start(ap, format); + error(format, ap); + va_end(ap); + dumpregs(); + pclog_end(); + exit(-1); } static void seg_reset(x86seg *s) { - s->access = (0 << 5) | 2; - s->access2 = 0; - s->limit = 0xFFFF; - s->limit_low = 0; - s->limit_high = 0xffff; - if (s == &cpu_state.seg_cs) { - // TODO - When the PC is reset, initialization of the CS descriptor must be like the annotated line below. - //s->base = AT ? (cpu_16bitbus ? 0xFF0000 : 0xFFFF0000) : 0xFFFF0; - s->base = AT ? 0xF0000 : 0xFFFF0; - s->seg = AT ? 0xF000 : 0xFFFF; - } else { - s->base = 0; - s->seg = 0; - } + s->access = (0 << 5) | 2; + s->access2 = 0; + s->limit = 0xFFFF; + s->limit_low = 0; + s->limit_high = 0xffff; + if (s == &cpu_state.seg_cs) { + // TODO - When the PC is reset, initialization of the CS descriptor must be like the annotated line below. + // s->base = AT ? (cpu_16bitbus ? 0xFF0000 : 0xFFFF0000) : 0xFFFF0; + s->base = AT ? 0xF0000 : 0xFFFF0; + s->seg = AT ? 0xF000 : 0xFFFF; + } else { + s->base = 0; + s->seg = 0; + } } void x86seg_reset() { - seg_reset(&cpu_state.seg_cs); - seg_reset(&cpu_state.seg_ds); - seg_reset(&cpu_state.seg_es); - seg_reset(&cpu_state.seg_fs); - seg_reset(&cpu_state.seg_gs); - seg_reset(&cpu_state.seg_ss); + seg_reset(&cpu_state.seg_cs); + seg_reset(&cpu_state.seg_ds); + seg_reset(&cpu_state.seg_es); + seg_reset(&cpu_state.seg_fs); + seg_reset(&cpu_state.seg_gs); + seg_reset(&cpu_state.seg_ss); } void x86_doabrt(int x86_abrt) { -// ingpf = 1; - cpu_state.pc = cpu_state.oldpc; - cpu_state.seg_cs.access = oldcpl << 5; -// pclog("x86_doabrt - %02X %08X %04X:%08X %i\n", x86_abrt, abrt_error, CS, pc, ins); + // ingpf = 1; + cpu_state.pc = cpu_state.oldpc; + cpu_state.seg_cs.access = oldcpl << 5; + // pclog("x86_doabrt - %02X %08X %04X:%08X %i\n", x86_abrt, abrt_error, CS, pc, ins); -/* if (CS == 0x3433 && pc == 0x000006B0) - { - pclog("Quit it\n"); - dumpregs(); - exit(-1); - }*/ -// pclog("GPF! - error %04X %04X(%08X):%08X %02X %02X %i %04X %i %i\n",error,CS,cs,pc,opcode,opcode2,ins,flags&I_FLAG,IOPL, dtimes); + /* if (CS == 0x3433 && pc == 0x000006B0) + { + pclog("Quit it\n"); + dumpregs(); + exit(-1); + }*/ + // pclog("GPF! - error %04X %04X(%08X):%08X %02X %02X %i %04X %i + // %i\n",error,CS,cs,pc,opcode,opcode2,ins,flags&I_FLAG,IOPL, dtimes); - if (msw & 1) - pmodeint(x86_abrt, 0); - else { - uint32_t addr = (x86_abrt << 2) + idt.base; - if (stack32) { - writememw(ss, ESP - 2, cpu_state.flags); - writememw(ss, ESP - 4, CS); - writememw(ss, ESP - 6, cpu_state.pc); - ESP -= 6; - } else { - writememw(ss, ((SP - 2) & 0xFFFF), cpu_state.flags); - writememw(ss, ((SP - 4) & 0xFFFF), CS); - writememw(ss, ((SP - 6) & 0xFFFF), cpu_state.pc); - SP -= 6; - } + if (msw & 1) + pmodeint(x86_abrt, 0); + else { + uint32_t addr = (x86_abrt << 2) + idt.base; + if (stack32) { + writememw(ss, ESP - 2, cpu_state.flags); + writememw(ss, ESP - 4, CS); + writememw(ss, ESP - 6, cpu_state.pc); + ESP -= 6; + } else { + writememw(ss, ((SP - 2) & 0xFFFF), cpu_state.flags); + writememw(ss, ((SP - 4) & 0xFFFF), CS); + writememw(ss, ((SP - 6) & 0xFFFF), cpu_state.pc); + SP -= 6; + } - cpu_state.flags &= ~I_FLAG; - cpu_state.flags &= ~T_FLAG; - cpu_state.pc = readmemw(0, addr); - loadcs(readmemw(0, addr + 2)); - return; - } + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; + cpu_state.pc = readmemw(0, addr); + loadcs(readmemw(0, addr + 2)); + return; + } - if (cpu_state.abrt || x86_was_reset) - 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; - } - } + 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) { -// pclog("GPF %04X %04x(%08x):%08x\n", error, CS,cs,cpu_state.pc); - cpu_state.abrt = ABRT_GPF; - abrt_error = error; + // pclog("GPF %04X %04x(%08x):%08x\n", error, CS,cs,cpu_state.pc); + cpu_state.abrt = ABRT_GPF; + abrt_error = error; } void x86gpf_expected(char *s, uint16_t error) { -// pclog("GPF_v86 %04X %04x(%08x):%08x\n", error, CS,cs,cpu_state.pc); - cpu_state.abrt = ABRT_GPF | ABRT_EXPECTED; - abrt_error = error; + // pclog("GPF_v86 %04X %04x(%08x):%08x\n", error, CS,cs,cpu_state.pc); + cpu_state.abrt = ABRT_GPF | ABRT_EXPECTED; + abrt_error = error; } void x86ss(char *s, uint16_t error) { -// pclog("SS %04X\n", error); - cpu_state.abrt = ABRT_SS; - abrt_error = error; + // pclog("SS %04X\n", error); + cpu_state.abrt = ABRT_SS; + abrt_error = error; } void x86ts(char *s, uint16_t error) { -// pclog("TS %04X\n", error); - cpu_state.abrt = ABRT_TS; - abrt_error = error; + // pclog("TS %04X\n", error); + cpu_state.abrt = ABRT_TS; + abrt_error = error; } void x86np(char *s, uint16_t error) { -// pclog("NP %04X : %s\n", error, s); - cpu_state.abrt = ABRT_NP; - abrt_error = error; + // pclog("NP %04X : %s\n", error, s); + 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; + 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; - } + if (u) { + use32 = 0x300; + cpu_cur_status |= CPU_STATUS_USE32; + } else { + use32 = 0; + cpu_cur_status &= ~CPU_STATUS_USE32; + } } static void do_seg_load(x86seg *s, uint16_t *segdat) { - s->limit = segdat[0] | ((segdat[3] & 0xF) << 16); - s->limit_raw = s->limit; - 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; - s->access2 = segdat[3] & 0xf0; + s->limit = segdat[0] | ((segdat[3] & 0xF) << 16); + s->limit_raw = s->limit; + 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; + s->access2 = segdat[3] & 0xf0; - 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 (output) pclog("SEG : base=%08x limit=%08x low=%08x high=%08x\n", s->base, s->limit, s->limit_low, s->limit_high); + 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 (output) pclog("SEG : base=%08x limit=%08x low=%08x high=%08x\n", s->base, s->limit, s->limit_low, + // s->limit_high); - if (s == &cpu_state.seg_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 == &cpu_state.seg_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; - } + if (s == &cpu_state.seg_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 == &cpu_state.seg_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; - s->access2 = 0; - s->limit = 0xffff; - s->limit_low = 0; - s->limit_high = 0xffff; + s->access = (3 << 5) | 2; + s->access2 = 0; + 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; + int dpl = (s->access >> 5) & 3; + int valid = 1; - if (s->seg & 4) { - if ((s->seg & ~7) >= ldt.limit) { -// pclog("Bigger than LDT limit %04X %04X %02X %02X %02X\n", s->seg, ldt.limit, opcode, opcode2, rmdat); - valid = 0; - } - } else { - if ((s->seg & ~7) >= gdt.limit) { -// pclog("Bigger than GDT limit %04X %04X\n", s->seg, gdt.limit); - valid = 0; - } - } + if (s->seg & 4) { + if ((s->seg & ~7) >= ldt.limit) { + // pclog("Bigger than LDT limit %04X %04X %02X %02X %02X\n", s->seg, ldt.limit, + // opcode, opcode2, rmdat); + valid = 0; + } + } else { + if ((s->seg & ~7) >= gdt.limit) { + // pclog("Bigger than GDT limit %04X %04X\n", s->seg, 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) { -// pclog("Data seg fail - %04X:%08X %04X %i\n", CS, pc, s->seg, dpl); - valid = 0; - break; - } - break; + 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) { + // pclog("Data seg fail - %04X:%08X %04X %i\n", CS, pc, s->seg, dpl); + valid = 0; + break; + } + break; - case 0x1E: - case 0x1F: /*Readable conforming code*/ - break; + case 0x1E: + case 0x1F: /*Readable conforming code*/ + break; - default:valid = 0; - break; - } + default: + valid = 0; + break; + } - if (!valid) - loadseg(0, s); + if (!valid) + loadseg(0, s); } int loadseg(uint16_t seg, x86seg *s) { - uint16_t segdat[4]; - uint32_t addr; - int dpl; + uint16_t segdat[4]; + uint32_t addr; + int dpl; - if (msw & 1 && !(cpu_state.eflags & VM_FLAG)) { -// intcount++; - if (!(seg & ~3)) { - if (s == &cpu_state.seg_ss) { - pclog("SS selector = NULL!\n"); - x86ss(NULL, 0); - return 1; -// dumpregs(); -// exit(-1); - } -// if (s->base!=-1) pclog("NEW! "); - s->seg = 0; - s->access = 0; - s->base = -1; - if (s == &cpu_state.seg_ds) - cpu_cur_status |= CPU_STATUS_NOTFLATDS; -// pclog("NULL selector %s%s%s%s %04X(%06X):%06X\n",(s==&_ds)?"DS":"",(s==&_es)?"ES":"",(s==&_fs)?"FS":"",(s==&_gs)?"GS":"",CS,cs,pc); - return 0; - } -// if (s==&_ss) pclog("Load SS %04X\n",seg); -// pclog("Protected mode seg load!\n"); - addr = seg & ~7; - if (seg & 4) { - if (addr >= ldt.limit) { - pclog("Bigger than LDT limit %04X %04X %02X\n", seg, ldt.limit, 0/*rmdat*/); -// dumppic(); -// dumpregs(); -// exit(-1); - x86gpf(NULL, seg & ~3); - return 1; - } - addr += ldt.base; - } else { - if (addr >= gdt.limit) { - pclog("Bigger than GDT limit %04X %04X 1\n", seg, gdt.limit); -// dumpregs(); -// exit(-1); - x86gpf(NULL, seg & ~3); - return 1; - } - 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 1; - dpl = (segdat[2] >> 13) & 3; - if (s == &cpu_state.seg_ss) { - if (!(seg & ~3)) { - pclog("Load SS null selector\n"); - x86gpf(NULL, seg & ~3); - return 1; - } - if ((seg & 3) != CPL || dpl != CPL) { - pclog("Invalid SS permiss\n"); - x86gpf(NULL, seg & ~3); -// x86abort("Invalid SS permiss for %04X!\n",seg&0xFFFC); - return 1; - } - switch ((segdat[2] >> 8) & 0x1F) { - case 0x12: - case 0x13: - case 0x16: - case 0x17: /*r/w*/ - break; - default:pclog("Invalid SS type\n"); - x86gpf(NULL, seg & ~3); -// x86abort("Invalid SS segment type for %04X!\n",seg&0xFFFC); - return 1; - } - if (!(segdat[2] & 0x8000)) { - pclog("Load SS not present!\n"); - x86ss(NULL, seg & ~3); - return 1; - } - set_stack32((segdat[3] & 0x40) ? 1 : 0); -// pclog("Load SS %04x %04x %04x %04x\n", segdat[0], segdat[1], segdat[2], segdat[3]); - } else if (s != &cpu_state.seg_cs) { - if (output) - pclog("Seg data %04X %04X %04X %04X\n", segdat[0], segdat[1], segdat[2], segdat[3]); - if (output) - pclog("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*/ -// pclog("Load seg %04X %i %i %04X:%08X\n",seg,dpl,CS&3,CS,pc); - if ((seg & 3) > dpl || (CPL) > dpl) { - pclog("Data seg fail - %04X:%08X %04X %i %04X\n", CS, cpu_state.pc, seg, dpl, segdat[2]); - x86gpf(NULL, seg & ~3); -// x86abort("Data segment load - level too low!\n",seg&0xFFFC); - return 1; - } - break; - case 0x1E: - case 0x1F: /*Readable conforming code*/ - break; - default:pclog("Invalid segment type for %04X! %04X\n", seg & 0xFFFC, segdat[2]); - x86gpf(NULL, seg & ~3); - return 1; - } - } + if (msw & 1 && !(cpu_state.eflags & VM_FLAG)) { + // intcount++; + if (!(seg & ~3)) { + if (s == &cpu_state.seg_ss) { + pclog("SS selector = NULL!\n"); + x86ss(NULL, 0); + return 1; + // dumpregs(); + // exit(-1); + } + // if (s->base!=-1) pclog("NEW! "); + s->seg = 0; + s->access = 0; + s->base = -1; + if (s == &cpu_state.seg_ds) + cpu_cur_status |= CPU_STATUS_NOTFLATDS; + // pclog("NULL selector %s%s%s%s + // %04X(%06X):%06X\n",(s==&_ds)?"DS":"",(s==&_es)?"ES":"",(s==&_fs)?"FS":"",(s==&_gs)?"GS":"",CS,cs,pc); + return 0; + } + // if (s==&_ss) pclog("Load SS %04X\n",seg); + // pclog("Protected mode seg load!\n"); + addr = seg & ~7; + if (seg & 4) { + if (addr >= ldt.limit) { + pclog("Bigger than LDT limit %04X %04X %02X\n", seg, ldt.limit, 0 /*rmdat*/); + // dumppic(); + // dumpregs(); + // exit(-1); + x86gpf(NULL, seg & ~3); + return 1; + } + addr += ldt.base; + } else { + if (addr >= gdt.limit) { + pclog("Bigger than GDT limit %04X %04X 1\n", seg, gdt.limit); + // dumpregs(); + // exit(-1); + x86gpf(NULL, seg & ~3); + return 1; + } + 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 1; + dpl = (segdat[2] >> 13) & 3; + if (s == &cpu_state.seg_ss) { + if (!(seg & ~3)) { + pclog("Load SS null selector\n"); + x86gpf(NULL, seg & ~3); + return 1; + } + if ((seg & 3) != CPL || dpl != CPL) { + pclog("Invalid SS permiss\n"); + x86gpf(NULL, seg & ~3); + // x86abort("Invalid SS permiss for %04X!\n",seg&0xFFFC); + return 1; + } + switch ((segdat[2] >> 8) & 0x1F) { + case 0x12: + case 0x13: + case 0x16: + case 0x17: /*r/w*/ + break; + default: + pclog("Invalid SS type\n"); + x86gpf(NULL, seg & ~3); + // x86abort("Invalid SS segment type for %04X!\n",seg&0xFFFC); + return 1; + } + if (!(segdat[2] & 0x8000)) { + pclog("Load SS not present!\n"); + x86ss(NULL, seg & ~3); + return 1; + } + set_stack32((segdat[3] & 0x40) ? 1 : 0); + // pclog("Load SS %04x %04x %04x %04x\n", segdat[0], segdat[1], segdat[2], + // segdat[3]); + } else if (s != &cpu_state.seg_cs) { + if (output) + pclog("Seg data %04X %04X %04X %04X\n", segdat[0], segdat[1], segdat[2], segdat[3]); + if (output) + pclog("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*/ + // pclog("Load seg %04X %i %i %04X:%08X\n",seg,dpl,CS&3,CS,pc); + if ((seg & 3) > dpl || (CPL) > dpl) { + pclog("Data seg fail - %04X:%08X %04X %i %04X\n", CS, cpu_state.pc, seg, dpl, segdat[2]); + x86gpf(NULL, seg & ~3); + // x86abort("Data segment load - level too + // low!\n",seg&0xFFFC); + return 1; + } + break; + case 0x1E: + case 0x1F: /*Readable conforming code*/ + break; + default: + pclog("Invalid segment type for %04X! %04X\n", seg & 0xFFFC, segdat[2]); + x86gpf(NULL, seg & ~3); + return 1; + } + } - if (!(segdat[2] & 0x8000)) { - x86np("Load data seg not present", seg & 0xfffc); - return 1; - } - s->seg = seg; - do_seg_load(s, segdat); + if (!(segdat[2] & 0x8000)) { + x86np("Load data seg not present", seg & 0xfffc); + return 1; + } + s->seg = seg; + do_seg_load(s, segdat); #ifndef CS_ACCESSED - if (s != &_cs) - { + if (s != &_cs) { #endif #ifdef SEL_ACCESSED - cpl_override = 1; - writememw(0, addr + 4, segdat[2] | 0x100); /*Set accessed bit*/ - cpl_override = 0; + cpl_override = 1; + writememw(0, addr + 4, segdat[2] | 0x100); /*Set accessed bit*/ + cpl_override = 0; #endif #ifndef CS_ACCESSED - } + } #endif - s->checked = 0; - if (s == &cpu_state.seg_ds) - codegen_flat_ds = 0; - if (s == &cpu_state.seg_ss) - codegen_flat_ss = 0; - } else { - s->access = (3 << 5) | 2; - s->access2 = 0; - s->base = seg << 4; - s->seg = seg; - s->checked = 1; - if (s == &cpu_state.seg_ds) - codegen_flat_ds = 0; - if (s == &cpu_state.seg_ss) - codegen_flat_ss = 0; - if (s == &cpu_state.seg_ss && (cpu_state.eflags & VM_FLAG)) - set_stack32(0); - } + s->checked = 0; + if (s == &cpu_state.seg_ds) + codegen_flat_ds = 0; + if (s == &cpu_state.seg_ss) + codegen_flat_ss = 0; + } else { + s->access = (3 << 5) | 2; + s->access2 = 0; + s->base = seg << 4; + s->seg = seg; + s->checked = 1; + if (s == &cpu_state.seg_ds) + codegen_flat_ds = 0; + if (s == &cpu_state.seg_ss) + codegen_flat_ss = 0; + if (s == &cpu_state.seg_ss && (cpu_state.eflags & VM_FLAG)) + set_stack32(0); + } - if (s == &cpu_state.seg_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 == &cpu_state.seg_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; - } + if (s == &cpu_state.seg_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 == &cpu_state.seg_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; + } - return cpu_state.abrt; + return cpu_state.abrt; } -#define DPL ((segdat[2]>>13)&3) -#define DPL2 ((segdat2[2]>>13)&3) -#define DPL3 ((segdat3[2]>>13)&3) +#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; - if (output) - pclog("Load CS %04X\n", seg); - if (msw & 1 && !(cpu_state.eflags & VM_FLAG)) { -// intcount++; -// flushmmucache(); -// pclog("Load CS %04X\n",seg); - if (!(seg & ~3)) { - pclog("Trying to load CS with NULL selector! lcs\n"); -// dumpregs(); -// exit(-1); - x86gpf(NULL, 0); - return; - } -// pclog("Protected mode CS load! %04X\n",seg); - addr = seg & ~7; - if (seg & 4) { - if (addr >= ldt.limit) { - pclog("Bigger than LDT limit %04X %04X CS\n", seg, ldt.limit); - x86gpf(NULL, seg & ~3); - return; - } - addr += ldt.base; - } else { - if (addr >= gdt.limit) { - pclog("Bigger than GDT limit %04X %04X CS\n", seg, 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 (optype == JMP) - pclog("Code seg - %04X - %04X %04X %04X %04X\n", seg, segdat[0], segdat[1], segdat[2], segdat[3]); -// if (!(segdat[2]&0x8000)) x86abort("Code segment not present!\n"); -// if (output) pclog("Segdat2 %04X\n",segdat[2]); - if (segdat[2] & 0x1000) /*Normal code segment*/ - { - if (!(segdat[2] & 0x400)) /*Not conforming*/ - { - if ((seg & 3) > CPL) { - x86gpf(NULL, seg & ~3); - pclog("loadcs RPL > CPL %04X %04X %i\n", segdat[2], seg, CPL); - return; - } - if (CPL != DPL) { - x86gpf(NULL, seg & ~3); - return; - } - } - if (CPL < DPL) { - x86gpf(NULL, 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(&cpu_state.seg_cs, segdat); - use32 = (segdat[3] & 0x40) ? 0x300 : 0; - if (CPL == 3 && oldcpl != 3) - flushmmucache_cr3(); - oldcpl = CPL; + uint16_t segdat[4]; + uint32_t addr; + if (output) + pclog("Load CS %04X\n", seg); + if (msw & 1 && !(cpu_state.eflags & VM_FLAG)) { + // intcount++; + // flushmmucache(); + // pclog("Load CS %04X\n",seg); + if (!(seg & ~3)) { + pclog("Trying to load CS with NULL selector! lcs\n"); + // dumpregs(); + // exit(-1); + x86gpf(NULL, 0); + return; + } + // pclog("Protected mode CS load! %04X\n",seg); + addr = seg & ~7; + if (seg & 4) { + if (addr >= ldt.limit) { + pclog("Bigger than LDT limit %04X %04X CS\n", seg, ldt.limit); + x86gpf(NULL, seg & ~3); + return; + } + addr += ldt.base; + } else { + if (addr >= gdt.limit) { + pclog("Bigger than GDT limit %04X %04X CS\n", seg, 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 (optype == JMP) + pclog("Code seg - %04X - %04X %04X %04X %04X\n", seg, segdat[0], segdat[1], segdat[2], segdat[3]); + // if (!(segdat[2]&0x8000)) x86abort("Code segment not present!\n"); + // if (output) pclog("Segdat2 %04X\n",segdat[2]); + if (segdat[2] & 0x1000) /*Normal code segment*/ + { + if (!(segdat[2] & 0x400)) /*Not conforming*/ + { + if ((seg & 3) > CPL) { + x86gpf(NULL, seg & ~3); + pclog("loadcs RPL > CPL %04X %04X %i\n", segdat[2], seg, CPL); + return; + } + if (CPL != DPL) { + x86gpf(NULL, seg & ~3); + return; + } + } + if (CPL < DPL) { + x86gpf(NULL, 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(&cpu_state.seg_cs, segdat); + use32 = (segdat[3] & 0x40) ? 0x300 : 0; + if (CPL == 3 && oldcpl != 3) + flushmmucache_cr3(); + oldcpl = CPL; #ifdef CS_ACCESSED - cpl_override = 1; - writememw(0, addr + 4, segdat[2] | 0x100); /*Set accessed bit*/ - cpl_override = 0; + cpl_override = 1; + writememw(0, addr + 4, segdat[2] | 0x100); /*Set accessed bit*/ + cpl_override = 0; #endif -// if (output) pclog("Load CS %08X\n",_cs.base); -// CS=(CS&0xFFFC)|((_cs.access>>5)&3); - } else /*System segment*/ - { - if (!(segdat[2] & 0x8000)) { - x86np("Load CS system seg not present\n", seg & 0xfffc); - return; - } - switch (segdat[2] & 0xF00) { - default:pclog("Bad CS %02X %i special descriptor %03X %04X\n", 0/*rmdat*/, optype, segdat[2] & 0xF00, seg); - x86gpf(NULL, seg & ~3); - return; - } - } -// pclog("CS = %04X base=%06X limit=%04X access=%02X %04X\n",CS,cs,_cs.limit,_cs.access,addr); -// dumpregs(); -// exit(-1); - } else { - cpu_state.seg_cs.base = seg << 4; - cpu_state.seg_cs.limit = 0xFFFF; - cpu_state.seg_cs.limit_low = 0; - cpu_state.seg_cs.limit_high = 0xffff; - CS = seg; - if (cpu_state.eflags & VM_FLAG) - cpu_state.seg_cs.access = (3 << 5) | 2; - else - cpu_state.seg_cs.access = (0 << 5) | 2; - if (CPL == 3 && oldcpl != 3) - flushmmucache_cr3(); - oldcpl = CPL; - } + // if (output) pclog("Load CS %08X\n",_cs.base); + // CS=(CS&0xFFFC)|((_cs.access>>5)&3); + } else /*System segment*/ + { + if (!(segdat[2] & 0x8000)) { + x86np("Load CS system seg not present\n", seg & 0xfffc); + return; + } + switch (segdat[2] & 0xF00) { + default: + pclog("Bad CS %02X %i special descriptor %03X %04X\n", 0 /*rmdat*/, optype, segdat[2] & 0xF00, + seg); + x86gpf(NULL, seg & ~3); + return; + } + } + // pclog("CS = %04X base=%06X limit=%04X access=%02X %04X\n",CS,cs,_cs.limit,_cs.access,addr); + // dumpregs(); + // exit(-1); + } else { + cpu_state.seg_cs.base = seg << 4; + cpu_state.seg_cs.limit = 0xFFFF; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.limit_high = 0xffff; + CS = seg; + if (cpu_state.eflags & VM_FLAG) + cpu_state.seg_cs.access = (3 << 5) | 2; + else + cpu_state.seg_cs.access = (0 << 5) | 2; + if (CPL == 3 && oldcpl != 3) + flushmmucache_cr3(); + oldcpl = CPL; + } } void loadcsjmp(uint16_t seg, uint32_t old_pc) { - uint16_t segdat[4]; - uint32_t addr; - uint16_t type, seg2; - uint32_t newpc; -// pclog("Load CS JMP %04X\n",seg); - if (msw & 1 && !(cpu_state.eflags & VM_FLAG)) { - if (!(seg & ~3)) { - pclog("Trying to load CS with NULL selector! lcsjmp\n"); - x86gpf(NULL, 0); - return; -// dumpregs(); -// exit(-1); - } - addr = seg & ~7; - if (seg & 4) { - if (addr >= ldt.limit) { - pclog("Bigger than LDT limit %04X %04X CS\n", seg, ldt.limit); - x86gpf(NULL, seg & ~3); - return; - } - addr += ldt.base; - } else { - if (addr >= gdt.limit) { - pclog("Bigger than GDT limit %04X %04X CS\n", seg, 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 (output) - pclog("%04X %04X %04X %04X\n", segdat[0], segdat[1], segdat[2], segdat[3]); - if (segdat[2] & 0x1000) /*Normal code segment*/ - { -// pclog("Normal CS\n"); - if (!(segdat[2] & 0x400)) /*Not conforming*/ - { - if ((seg & 3) > CPL) { - x86gpf(NULL, 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 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(&cpu_state.seg_cs, segdat); - if (CPL == 3 && oldcpl != 3) - flushmmucache_cr3(); - oldcpl = CPL; -/* if (segdat[3]&0x40) - { - use32=0x300; - cpu_cur_status |= CPU_STATUS_USE32; + uint16_t segdat[4]; + uint32_t addr; + uint16_t type, seg2; + uint32_t newpc; + // pclog("Load CS JMP %04X\n",seg); + if (msw & 1 && !(cpu_state.eflags & VM_FLAG)) { + if (!(seg & ~3)) { + pclog("Trying to load CS with NULL selector! lcsjmp\n"); + x86gpf(NULL, 0); + return; + // dumpregs(); + // exit(-1); + } + addr = seg & ~7; + if (seg & 4) { + if (addr >= ldt.limit) { + pclog("Bigger than LDT limit %04X %04X CS\n", seg, ldt.limit); + x86gpf(NULL, seg & ~3); + return; } - else + addr += ldt.base; + } else { + if (addr >= gdt.limit) { + pclog("Bigger than GDT limit %04X %04X CS\n", seg, 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 (output) + pclog("%04X %04X %04X %04X\n", segdat[0], segdat[1], segdat[2], segdat[3]); + if (segdat[2] & 0x1000) /*Normal code segment*/ + { + // pclog("Normal CS\n"); + if (!(segdat[2] & 0x400)) /*Not conforming*/ { - use32=0; - cpu_cur_status &= ~CPU_STATUS_USE32; - }*/ - cycles -= timing_jmp_pm; - } else /*System segment*/ - { -// pclog("System CS\n"); - 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: -// pclog("Call gate\n"); - cgate32 = (type & 0x800); - cgate16 = !cgate32; - cpu_state.oldpc = cpu_state.pc; - if ((DPL < CPL) || (DPL < (seg & 3))) { - x86gpf(NULL, 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)) { - pclog("Trying to load CS with NULL selector! lcsjmpcg\n"); - x86gpf(NULL, 0); - return; -// dumpregs(); -// exit(-1); - } - addr = seg2 & ~7; - if (seg2 & 4) { - if (addr >= ldt.limit) { - pclog("Bigger than LDT limit %04X %04X CSJ\n", seg2, gdt.limit); - x86gpf(NULL, seg2 & ~3); - return; - } - addr += ldt.base; - } else { - if (addr >= gdt.limit) { - pclog("Bigger than GDT limit %04X %04X CSJ\n", seg2, 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(NULL, 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) { - pclog("Call gate DPL > CPL"); - x86gpf(NULL, seg2 & ~3); - return; - } - case 0x1C00: - case 0x1D00: - case 0x1E00: - case 0x1F00: /*Conforming*/ - CS = seg2; - do_seg_load(&cpu_state.seg_cs, segdat); - if (CPL == 3 && oldcpl != 3) - flushmmucache_cr3(); - oldcpl = CPL; - set_use32(segdat[3] & 0x40); - cpu_state.pc = newpc; + if ((seg & 3) > CPL) { + x86gpf(NULL, 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 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; + cpl_override = 1; + writememw(0, addr + 4, segdat[2] | 0x100); /*Set accessed bit*/ + cpl_override = 0; #endif - break; - default:pclog("JMP Call gate bad segment type\n"); - x86gpf(NULL, seg2 & ~3); - return; - } - cycles -= timing_jmp_pm_gate; - break; + CS = (seg & ~3) | CPL; + segdat[2] = (segdat[2] & ~(3 << (5 + 8))) | (CPL << (5 + 8)); - case 0x100: /*286 Task gate*/ - case 0x900: /*386 Task gate*/ -// pclog("Task gate\n"); - cpu_state.pc = old_pc; - optype = JMP; - cpl_override = 1; - taskswitch286(seg, segdat, segdat[2] & 0x800); - cpu_state.flags &= ~NT_FLAG; - cpl_override = 0; -// case 0xB00: /*386 Busy task gate*/ -// if (optype==JMP) pclog("Task switch!\n"); -// taskswitch386(seg,segdat); - return; + do_seg_load(&cpu_state.seg_cs, segdat); + if (CPL == 3 && oldcpl != 3) + flushmmucache_cr3(); + oldcpl = CPL; + /* if (segdat[3]&0x40) + { + use32=0x300; + cpu_cur_status |= CPU_STATUS_USE32; + } + else + { + use32=0; + cpu_cur_status &= ~CPU_STATUS_USE32; + }*/ + cycles -= timing_jmp_pm; + } else /*System segment*/ + { + // pclog("System CS\n"); + 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: + // pclog("Call gate\n"); + cgate32 = (type & 0x800); + cgate16 = !cgate32; + cpu_state.oldpc = cpu_state.pc; + if ((DPL < CPL) || (DPL < (seg & 3))) { + x86gpf(NULL, seg & ~3); + return; + } + if (!(segdat[2] & 0x8000)) { + x86np("Load CS JMP call gate not present\n", seg & 0xfffc); + return; + } + seg2 = segdat[1]; - default:pclog("Bad JMP CS %02X %i special descriptor %03X %04X\n", 0/*rmdat*/, optype, segdat[2] & 0xF00, seg); - x86gpf(NULL, 0); - return; -// dumpregs(); -// exit(-1); - } - } -// pclog("CS = %04X base=%06X limit=%04X access=%02X %04X\n",CS,cs,_cs.limit,_cs.access,addr); -// dumpregs(); -// exit(-1); - } else { - cpu_state.seg_cs.base = seg << 4; - cpu_state.seg_cs.limit = 0xFFFF; - cpu_state.seg_cs.limit_low = 0; - cpu_state.seg_cs.limit_high = 0xffff; - CS = seg; - if (cpu_state.eflags & VM_FLAG) - cpu_state.seg_cs.access = (3 << 5) | 2; - else - cpu_state.seg_cs.access = (0 << 5) | 2; - if (CPL == 3 && oldcpl != 3) - flushmmucache_cr3(); - oldcpl = CPL; - cycles -= timing_jmp_rm; - } + if (!(seg2 & ~3)) { + pclog("Trying to load CS with NULL selector! lcsjmpcg\n"); + x86gpf(NULL, 0); + return; + // dumpregs(); + // exit(-1); + } + addr = seg2 & ~7; + if (seg2 & 4) { + if (addr >= ldt.limit) { + pclog("Bigger than LDT limit %04X %04X CSJ\n", seg2, gdt.limit); + x86gpf(NULL, seg2 & ~3); + return; + } + addr += ldt.base; + } else { + if (addr >= gdt.limit) { + pclog("Bigger than GDT limit %04X %04X CSJ\n", seg2, 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(NULL, 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) { + pclog("Call gate DPL > CPL"); + x86gpf(NULL, seg2 & ~3); + return; + } + case 0x1C00: + case 0x1D00: + case 0x1E00: + case 0x1F00: /*Conforming*/ + CS = seg2; + do_seg_load(&cpu_state.seg_cs, segdat); + if (CPL == 3 && oldcpl != 3) + flushmmucache_cr3(); + oldcpl = CPL; + 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: + pclog("JMP Call gate bad segment type\n"); + x86gpf(NULL, seg2 & ~3); + return; + } + cycles -= timing_jmp_pm_gate; + break; + + case 0x100: /*286 Task gate*/ + case 0x900: /*386 Task gate*/ + // pclog("Task gate\n"); + cpu_state.pc = old_pc; + optype = JMP; + cpl_override = 1; + taskswitch286(seg, segdat, segdat[2] & 0x800); + cpu_state.flags &= ~NT_FLAG; + cpl_override = 0; + // case 0xB00: /*386 Busy task gate*/ + // if (optype==JMP) pclog("Task switch!\n"); + // taskswitch386(seg,segdat); + return; + + default: + pclog("Bad JMP CS %02X %i special descriptor %03X %04X\n", 0 /*rmdat*/, optype, segdat[2] & 0xF00, + seg); + x86gpf(NULL, 0); + return; + // dumpregs(); + // exit(-1); + } + } + // pclog("CS = %04X base=%06X limit=%04X access=%02X %04X\n",CS,cs,_cs.limit,_cs.access,addr); + // dumpregs(); + // exit(-1); + } else { + cpu_state.seg_cs.base = seg << 4; + cpu_state.seg_cs.limit = 0xFFFF; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.limit_high = 0xffff; + CS = seg; + if (cpu_state.eflags & VM_FLAG) + cpu_state.seg_cs.access = (3 << 5) | 2; + else + cpu_state.seg_cs.access = (0 << 5) | 2; + if (CPL == 3 && oldcpl != 3) + flushmmucache_cr3(); + oldcpl = CPL; + cycles -= timing_jmp_rm; + } } void PUSHW(uint16_t v) { -// if (output==3) pclog("PUSHW %04X to %08X\n",v,ESP-4); - if (stack32) { - writememw(ss, ESP - 2, v); - if (cpu_state.abrt) - return; - ESP -= 2; - } else { -// pclog("Write %04X to %08X\n", v, ss+((SP-2)&0xFFFF)); - writememw(ss, ((SP - 2) & 0xFFFF), v); - if (cpu_state.abrt) - return; - SP -= 2; - } + // if (output==3) pclog("PUSHW %04X to %08X\n",v,ESP-4); + if (stack32) { + writememw(ss, ESP - 2, v); + if (cpu_state.abrt) + return; + ESP -= 2; + } else { + // pclog("Write %04X to %08X\n", v, ss+((SP-2)&0xFFFF)); + writememw(ss, ((SP - 2) & 0xFFFF), v); + if (cpu_state.abrt) + return; + SP -= 2; + } } void PUSHL(uint32_t v) { -// if (output==3) pclog("PUSHL %08X to %08X\n",v,ESP-4); - 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; - } + // if (output==3) pclog("PUSHL %08X to %08X\n",v,ESP-4); + 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; + 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; + 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, uint32_t old_pc) { - 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; + 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; + int csout = output; - if (msw & 1 && !(cpu_state.eflags & VM_FLAG)) { - //flushmmucache(); - if (csout) - pclog("Protected mode CS load! %04X\n", seg); - if (!(seg & ~3)) { - pclog("Trying to load CS with NULL selector! lcscall\n"); - x86gpf(NULL, 0); - return; -// dumpregs(); -// exit(-1); - } - addr = seg & ~7; - if (seg & 4) { - if (addr >= ldt.limit) { - pclog("Bigger than LDT limit %04X %04X CSC\n", seg, gdt.limit); - x86gpf(NULL, seg & ~3); - return; - } - addr += ldt.base; - } else { - if (addr >= gdt.limit) { - pclog("Bigger than GDT limit %04X %04X CSC\n", seg, 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 (msw & 1 && !(cpu_state.eflags & VM_FLAG)) { + // flushmmucache(); + if (csout) + pclog("Protected mode CS load! %04X\n", seg); + if (!(seg & ~3)) { + pclog("Trying to load CS with NULL selector! lcscall\n"); + x86gpf(NULL, 0); + return; + // dumpregs(); + // exit(-1); + } + addr = seg & ~7; + if (seg & 4) { + if (addr >= ldt.limit) { + pclog("Bigger than LDT limit %04X %04X CSC\n", seg, gdt.limit); + x86gpf(NULL, seg & ~3); + return; + } + addr += ldt.base; + } else { + if (addr >= gdt.limit) { + pclog("Bigger than GDT limit %04X %04X CSC\n", seg, 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) - pclog("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) { - if (csout) - pclog("Not conforming, RPL > CPL\n"); - x86gpf(NULL, seg & ~3); - return; - } - if (CPL != DPL) { - if (csout) - pclog("Not conforming, CPL != DPL (%i %i)\n", CPL, DPL); - x86gpf(NULL, seg & ~3); - return; - } - } - if (CPL < DPL) { - if (csout) - pclog("CPL < DPL\n"); - x86gpf(NULL, seg & ~3); - return; - } - if (!(segdat[2] & 0x8000)) { - if (csout) - pclog("Not present\n"); - x86np("Load CS call not present", seg & 0xfffc); - return; - } - set_use32(segdat[3] & 0x40); + if (csout) + pclog("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) { + if (csout) + pclog("Not conforming, RPL > CPL\n"); + x86gpf(NULL, seg & ~3); + return; + } + if (CPL != DPL) { + if (csout) + pclog("Not conforming, CPL != DPL (%i %i)\n", CPL, DPL); + x86gpf(NULL, seg & ~3); + return; + } + } + if (CPL < DPL) { + if (csout) + pclog("CPL < DPL\n"); + x86gpf(NULL, seg & ~3); + return; + } + if (!(segdat[2] & 0x8000)) { + if (csout) + pclog("Not present\n"); + 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; + 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(&cpu_state.seg_cs, segdat); - if (CPL == 3 && oldcpl != 3) - flushmmucache_cr3(); - oldcpl = CPL; -/* if (segdat[3]&0x40) - { - use32=0x300; - cpu_cur_status |= CPU_STATUS_USE32; - } - else - { - use32=0; - cpu_cur_status &= ~CPU_STATUS_USE32; - }*/ - if (csout) - pclog("Complete\n"); - cycles -= timing_call_pm; - } else { - type = segdat[2] & 0xF00; - if (csout) - pclog("Type %03X\n", type); - switch (type) { - case 0x400: /*Call gate*/ - case 0xC00: /*386 Call gate*/ - if (output) - pclog("Callgate %08X\n", cpu_state.pc); - cgate32 = (type & 0x800); - cgate16 = !cgate32; - count = segdat[2] & 31; - if ((DPL < CPL) || (DPL < (seg & 3))) { - x86gpf(NULL, seg & ~3); - return; - } - if (!(segdat[2] & 0x8000)) { - if (output) - pclog("Call gate not present %04X\n", seg); - x86np("Call gate not present\n", seg & 0xfffc); - return; - } - seg2 = segdat[1]; + /*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(&cpu_state.seg_cs, segdat); + if (CPL == 3 && oldcpl != 3) + flushmmucache_cr3(); + oldcpl = CPL; + /* if (segdat[3]&0x40) + { + use32=0x300; + cpu_cur_status |= CPU_STATUS_USE32; + } + else + { + use32=0; + cpu_cur_status &= ~CPU_STATUS_USE32; + }*/ + if (csout) + pclog("Complete\n"); + cycles -= timing_call_pm; + } else { + type = segdat[2] & 0xF00; + if (csout) + pclog("Type %03X\n", type); + switch (type) { + case 0x400: /*Call gate*/ + case 0xC00: /*386 Call gate*/ + if (output) + pclog("Callgate %08X\n", cpu_state.pc); + cgate32 = (type & 0x800); + cgate16 = !cgate32; + count = segdat[2] & 31; + if ((DPL < CPL) || (DPL < (seg & 3))) { + x86gpf(NULL, seg & ~3); + return; + } + if (!(segdat[2] & 0x8000)) { + if (output) + pclog("Call gate not present %04X\n", seg); + x86np("Call gate not present\n", seg & 0xfffc); + return; + } + seg2 = segdat[1]; - if (output) - pclog("New address : %04X:%08X\n", seg2, newpc); + if (output) + pclog("New address : %04X:%08X\n", seg2, newpc); - if (!(seg2 & ~3)) { - pclog("Trying to load CS with NULL selector! lcscallcg\n"); - x86gpf(NULL, 0); - return; -// dumpregs(); -// exit(-1); - } - addr = seg2 & ~7; - if (seg2 & 4) { - if (addr >= ldt.limit) { - pclog("Bigger than LDT limit %04X %04X CSC\n", seg2, gdt.limit); - x86gpf(NULL, seg2 & ~3); - return; - } - addr += ldt.base; - } else { - if (addr >= gdt.limit) { - pclog("Bigger than GDT limit %04X %04X CSC\n", seg2, 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 (!(seg2 & ~3)) { + pclog("Trying to load CS with NULL selector! lcscallcg\n"); + x86gpf(NULL, 0); + return; + // dumpregs(); + // exit(-1); + } + addr = seg2 & ~7; + if (seg2 & 4) { + if (addr >= ldt.limit) { + pclog("Bigger than LDT limit %04X %04X CSC\n", seg2, gdt.limit); + x86gpf(NULL, seg2 & ~3); + return; + } + addr += ldt.base; + } else { + if (addr >= gdt.limit) { + pclog("Bigger than GDT limit %04X %04X CSC\n", seg2, 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 (output) - pclog("Code seg2 call - %04X - %04X %04X %04X\n", seg2, segdat[0], segdat[1], segdat[2]); + if (output) + pclog("Code seg2 call - %04X - %04X %04X %04X\n", seg2, segdat[0], segdat[1], segdat[2]); - if (DPL > CPL) { - x86gpf(NULL, seg2 & ~3); - return; - } - if (!(segdat[2] & 0x8000)) { - if (output) - pclog("Call gate CS not present %04X\n", seg2); - x86np("Call gate CS not present", seg2 & 0xfffc); - return; - } + if (DPL > CPL) { + x86gpf(NULL, seg2 & ~3); + return; + } + if (!(segdat[2] & 0x8000)) { + if (output) + pclog("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) { - uint16_t oldcs = CS; - 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; - if (output) - pclog("New stack %04X:%08X\n", newss, newsp); - if (!(newss & ~3)) { - pclog("Call gate loading null SS\n"); - 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; - if (output) - pclog("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; - if (output) - pclog("Read stack seg done!\n"); - if (((newss & 3) != DPL) || (DPL2 != DPL)) { - pclog("Call gate loading SS with wrong permissions %04X %04X %i %i %04X %04X\n", newss, seg2, DPL, DPL2, segdat[2], segdat2[2]); -// dumpregs(); -// exit(-1); - x86ts(NULL, newss & ~3); - return; - } - if ((segdat2[2] & 0x1A00) != 0x1200) { - pclog("Call gate loading SS wrong type\n"); - x86ts(NULL, newss & ~3); - return; - } - if (!(segdat2[2] & 0x8000)) { - pclog("Call gate loading SS not present\n"); - 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; + switch (segdat[2] & 0x1F00) { + case 0x1800: + case 0x1900: + case 0x1A00: + case 0x1B00: /*Non-conforming code*/ + if (DPL < CPL) { + uint16_t oldcs = CS; + 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; + if (output) + pclog("New stack %04X:%08X\n", newss, newsp); + if (!(newss & ~3)) { + pclog("Call gate loading null SS\n"); + 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; + if (output) + pclog("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; + if (output) + pclog("Read stack seg done!\n"); + if (((newss & 3) != DPL) || (DPL2 != DPL)) { + pclog("Call gate loading SS with wrong permissions %04X %04X %i %i " + "%04X %04X\n", + newss, seg2, DPL, DPL2, segdat[2], segdat2[2]); + // dumpregs(); + // exit(-1); + x86ts(NULL, newss & ~3); + return; + } + if ((segdat2[2] & 0x1A00) != 0x1200) { + pclog("Call gate loading SS wrong type\n"); + x86ts(NULL, newss & ~3); + return; + } + if (!(segdat2[2] & 0x8000)) { + pclog("Call gate loading SS not present\n"); + 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(&cpu_state.seg_ss, segdat2); + do_seg_load(&cpu_state.seg_ss, segdat2); - if (output) - pclog("Set access 1\n"); + if (output) + pclog("Set access 1\n"); #ifdef SEL_ACCESSED - cpl_override = 1; - writememw(0, addr + 4, segdat2[2] | 0x100); /*Set accessed bit*/ - cpl_override = 0; + cpl_override = 1; + writememw(0, addr + 4, segdat2[2] | 0x100); /*Set accessed bit*/ + cpl_override = 0; #endif - CS = seg2; - do_seg_load(&cpu_state.seg_cs, segdat); - if (CPL == 3 && oldcpl != 3) - flushmmucache_cr3(); - oldcpl = CPL; - set_use32(segdat[3] & 0x40); - cpu_state.pc = newpc; + CS = seg2; + do_seg_load(&cpu_state.seg_cs, segdat); + if (CPL == 3 && oldcpl != 3) + flushmmucache_cr3(); + oldcpl = CPL; + set_use32(segdat[3] & 0x40); + cpu_state.pc = newpc; - if (output) - pclog("Set access 2\n"); + if (output) + pclog("Set access 2\n"); #ifdef CS_ACCESSED - cpl_override = 1; - writememw(0, oaddr + 4, segdat[2] | 0x100); /*Set accessed bit*/ - cpl_override = 0; + cpl_override = 1; + writememw(0, oaddr + 4, segdat[2] | 0x100); /*Set accessed bit*/ + cpl_override = 0; #endif - if (output) - pclog("Type %04X\n", type); - if (type == 0xC00) { - PUSHL(oldss); - PUSHL(oldsp2); - if (cpu_state.abrt) { - pclog("ABRT PUSHL\n"); - SS = oldss; - ESP = oldsp2; - CS = oldcs; - return; - } -// if (output) pclog("Stack now %04X:%08X\n",SS,ESP); - if (count) { - while (count) { - count--; - PUSHL(readmeml(oldssbase, oldsp + (count * 4))); - if (cpu_state.abrt) { - pclog("ABRT COPYL\n"); - SS = oldss; - ESP = oldsp2; - CS = oldcs; - return; - } - } - } -// x86abort("Call gate with count %i\n",count); - } else { - if (output) - pclog("Stack %04X\n", SP); - PUSHW(oldss); - if (output) - pclog("Write SS to %04X:%04X\n", SS, SP); - PUSHW(oldsp2); - if (cpu_state.abrt) { - pclog("ABRT PUSHW\n"); - SS = oldss; - ESP = oldsp2; - CS = oldcs; - return; - } - if (output) - pclog("Write SP to %04X:%04X\n", SS, SP); -// if (output) pclog("Stack %04X %i %04X:%04X\n",SP,count,oldssbase,oldsp); -// if (output) pclog("PUSH %04X %04X %i %i now %04X:%08X\n",oldss,oldsp,count,stack32,SS,ESP); - if (count) { - while (count) { - count--; - tempw = readmemw(oldssbase, (oldsp & 0xFFFF) + (count * 2)); - if (output) - pclog("PUSH %04X\n", tempw); - PUSHW(tempw); - if (cpu_state.abrt) { - pclog("ABRT COPYW\n"); - SS = oldss; - ESP = oldsp2; - CS = oldcs; - return; - } - } - } -// if (output) pclog("Stack %04X\n",SP); -// if (count) x86abort("Call gate with count\n"); - } - cycles -= timing_call_pm_gate_inner; - break; - } else if (DPL > CPL) { - pclog("Call gate DPL > CPL"); - x86gpf(NULL, seg2 & ~3); - return; - } - case 0x1C00: - case 0x1D00: - case 0x1E00: - case 0x1F00: /*Conforming*/ - CS = seg2; - do_seg_load(&cpu_state.seg_cs, segdat); - if (CPL == 3 && oldcpl != 3) - flushmmucache_cr3(); - oldcpl = CPL; - set_use32(segdat[3] & 0x40); - cpu_state.pc = newpc; + if (output) + pclog("Type %04X\n", type); + if (type == 0xC00) { + PUSHL(oldss); + PUSHL(oldsp2); + if (cpu_state.abrt) { + pclog("ABRT PUSHL\n"); + SS = oldss; + ESP = oldsp2; + CS = oldcs; + return; + } + // if (output) + // pclog("Stack now + // %04X:%08X\n",SS,ESP); + if (count) { + while (count) { + count--; + PUSHL(readmeml(oldssbase, oldsp + (count * 4))); + if (cpu_state.abrt) { + pclog("ABRT COPYL\n"); + SS = oldss; + ESP = oldsp2; + CS = oldcs; + return; + } + } + } + // x86abort("Call + // gate + // with + // count + // %i\n",count); + } else { + if (output) + pclog("Stack %04X\n", SP); + PUSHW(oldss); + if (output) + pclog("Write SS to %04X:%04X\n", SS, SP); + PUSHW(oldsp2); + if (cpu_state.abrt) { + pclog("ABRT PUSHW\n"); + SS = oldss; + ESP = oldsp2; + CS = oldcs; + return; + } + if (output) + pclog("Write SP to %04X:%04X\n", SS, SP); + // if (output) + // pclog("Stack + // %04X %i + // %04X:%04X\n",SP,count,oldssbase,oldsp); + // if (output) + // pclog("PUSH %04X + // %04X %i %i now + // %04X:%08X\n",oldss,oldsp,count,stack32,SS,ESP); + if (count) { + while (count) { + count--; + tempw = readmemw(oldssbase, + (oldsp & 0xFFFF) + (count * 2)); + if (output) + pclog("PUSH %04X\n", tempw); + PUSHW(tempw); + if (cpu_state.abrt) { + pclog("ABRT COPYW\n"); + SS = oldss; + ESP = oldsp2; + CS = oldcs; + return; + } + } + } + // if (output) + // pclog("Stack + // %04X\n",SP); if + // (count) + // x86abort("Call + // gate with + // count\n"); + } + cycles -= timing_call_pm_gate_inner; + break; + } else if (DPL > CPL) { + pclog("Call gate DPL > CPL"); + x86gpf(NULL, seg2 & ~3); + return; + } + case 0x1C00: + case 0x1D00: + case 0x1E00: + case 0x1F00: /*Conforming*/ + CS = seg2; + do_seg_load(&cpu_state.seg_cs, segdat); + if (CPL == 3 && oldcpl != 3) + flushmmucache_cr3(); + oldcpl = CPL; + 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; + cpl_override = 1; + writememw(0, addr + 4, segdat[2] | 0x100); /*Set accessed bit*/ + cpl_override = 0; #endif - cycles -= timing_call_pm_gate; - break; + cycles -= timing_call_pm_gate; + break; - default:pclog("Call gate bad segment type\n"); - x86gpf(NULL, seg2 & ~3); - return; - } - break; + default: + pclog("Call gate bad segment type\n"); + x86gpf(NULL, seg2 & ~3); + return; + } + break; - case 0x100: /*286 Task gate*/ - case 0x900: /*386 Task gate*/ -// pclog("Task gate\n"); - cpu_state.pc = old_pc; - cpl_override = 1; - taskswitch286(seg, segdat, segdat[2] & 0x800); - cpl_override = 0; - break; + case 0x100: /*286 Task gate*/ + case 0x900: /*386 Task gate*/ + // pclog("Task gate\n"); + cpu_state.pc = old_pc; + cpl_override = 1; + taskswitch286(seg, segdat, segdat[2] & 0x800); + cpl_override = 0; + break; - default:pclog("Bad CALL special descriptor %03X\n", segdat[2] & 0xF00); - x86gpf(NULL, seg & ~3); - return; -// dumpregs(); -// exit(-1); - } - } -// pclog("CS = %04X base=%06X limit=%04X access=%02X %04X\n",CS,cs,_cs.limit,_cs.access,addr); -// dumpregs(); -// exit(-1); - } else { - cpu_state.seg_cs.base = seg << 4; - cpu_state.seg_cs.limit = 0xFFFF; - cpu_state.seg_cs.limit_low = 0; - cpu_state.seg_cs.limit_high = 0xffff; - CS = seg; - if (cpu_state.eflags & VM_FLAG) - cpu_state.seg_cs.access = (3 << 5) | 2; - else - cpu_state.seg_cs.access = (0 << 5) | 2; - if (CPL == 3 && oldcpl != 3) - flushmmucache_cr3(); - oldcpl = CPL; - } + default: + pclog("Bad CALL special descriptor %03X\n", segdat[2] & 0xF00); + x86gpf(NULL, seg & ~3); + return; + // dumpregs(); + // exit(-1); + } + } + // pclog("CS = %04X base=%06X limit=%04X access=%02X %04X\n",CS,cs,_cs.limit,_cs.access,addr); + // dumpregs(); + // exit(-1); + } else { + cpu_state.seg_cs.base = seg << 4; + cpu_state.seg_cs.limit = 0xFFFF; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.limit_high = 0xffff; + CS = seg; + if (cpu_state.eflags & VM_FLAG) + cpu_state.seg_cs.access = (3 << 5) | 2; + else + cpu_state.seg_cs.access = (0 << 5) | 2; + if (CPL == 3 && oldcpl != 3) + flushmmucache_cr3(); + oldcpl = CPL; + } } 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; - if (output) - pclog("RETF %i %04X:%04X %08X %04X\n", is32, CS, cpu_state.pc, cr0, cpu_state.eflags); - if (is32) { - newpc = POPL(); - seg = POPL(); - if (cpu_state.abrt) - return; - } else { - if (output) - pclog("PC read from %04X:%04X\n", SS, SP); - newpc = POPW(); - if (output) - pclog("CS read from %04X:%04X\n", SS, SP); - seg = POPW(); - if (cpu_state.abrt) - return; - } - if (output) - pclog("Return to %04X:%08X\n", seg, newpc); - if ((seg & 3) < CPL) { - pclog("RETF RPL= ldt.limit) { - pclog("Bigger than LDT limit %04X %04X RETF\n", seg, ldt.limit); - x86gpf(NULL, seg & ~3); - return; - } - addr += ldt.base; - } else { - if (addr >= gdt.limit) { - pclog("Bigger than GDT limit %04X %04X RETF\n", seg, gdt.limit); - x86gpf(NULL, seg & ~3); -// dumpregs(); -// exit(-1); - 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; + uint32_t newpc; + uint32_t newsp; + uint32_t addr, oaddr; + uint16_t segdat[4], segdat2[4], seg, newss; + uint32_t oldsp = ESP; + if (output) + pclog("RETF %i %04X:%04X %08X %04X\n", is32, CS, cpu_state.pc, cr0, cpu_state.eflags); + if (is32) { + newpc = POPL(); + seg = POPL(); + if (cpu_state.abrt) + return; + } else { + if (output) + pclog("PC read from %04X:%04X\n", SS, SP); + newpc = POPW(); + if (output) + pclog("CS read from %04X:%04X\n", SS, SP); + seg = POPW(); + if (cpu_state.abrt) + return; + } + if (output) + pclog("Return to %04X:%08X\n", seg, newpc); + if ((seg & 3) < CPL) { + pclog("RETF RPL= ldt.limit) { + pclog("Bigger than LDT limit %04X %04X RETF\n", seg, ldt.limit); + x86gpf(NULL, seg & ~3); + return; + } + addr += ldt.base; + } else { + if (addr >= gdt.limit) { + pclog("Bigger than GDT limit %04X %04X RETF\n", seg, gdt.limit); + x86gpf(NULL, seg & ~3); + // dumpregs(); + // exit(-1); + 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; - if (output) - pclog("CPL %i RPL %i %i\n", CPL, seg & 3, is32); + if (output) + pclog("CPL %i RPL %i %i\n", CPL, seg & 3, is32); - if (stack32) - ESP += off; - else - SP += off; + if (stack32) + ESP += off; + else + SP += off; - if (CPL == (seg & 3)) { - if (output) - pclog("RETF CPL = RPL %04X\n", segdat[2]); - switch (segdat[2] & 0x1F00) { - case 0x1800: - case 0x1900: - case 0x1A00: - case 0x1B00: /*Non-conforming*/ - if (CPL != DPL) { - pclog("RETF non-conforming CPL != DPL\n"); - ESP = oldsp; - x86gpf(NULL, seg & ~3); - return; - } - break; - case 0x1C00: - case 0x1D00: - case 0x1E00: - case 0x1F00: /*Conforming*/ - if (CPL < DPL) { - pclog("RETF non-conforming CPL < DPL\n"); - ESP = oldsp; - x86gpf(NULL, seg & ~3); - return; - } - break; - default:pclog("RETF CS not code segment\n"); - x86gpf(NULL, seg & ~3); - return; - } - if (!(segdat[2] & 0x8000)) { - pclog("RETF CS not present %i %04X %04X %04X\n", ins, segdat[0], segdat[1], segdat[2]); - ESP = oldsp; - x86np("RETF CS not present\n", seg & 0xfffc); - return; - } + if (CPL == (seg & 3)) { + if (output) + pclog("RETF CPL = RPL %04X\n", segdat[2]); + switch (segdat[2] & 0x1F00) { + case 0x1800: + case 0x1900: + case 0x1A00: + case 0x1B00: /*Non-conforming*/ + if (CPL != DPL) { + pclog("RETF non-conforming CPL != DPL\n"); + ESP = oldsp; + x86gpf(NULL, seg & ~3); + return; + } + break; + case 0x1C00: + case 0x1D00: + case 0x1E00: + case 0x1F00: /*Conforming*/ + if (CPL < DPL) { + pclog("RETF non-conforming CPL < DPL\n"); + ESP = oldsp; + x86gpf(NULL, seg & ~3); + return; + } + break; + default: + pclog("RETF CS not code segment\n"); + x86gpf(NULL, seg & ~3); + return; + } + if (!(segdat[2] & 0x8000)) { + pclog("RETF CS not present %i %04X %04X %04X\n", ins, segdat[0], segdat[1], segdat[2]); + 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; + 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(&cpu_state.seg_cs, segdat); - cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~(3 << 5)) | ((CS & 3) << 5); - if (CPL == 3 && oldcpl != 3) - flushmmucache_cr3(); - oldcpl = CPL; - set_use32(segdat[3] & 0x40); + cpu_state.pc = newpc; + if (segdat[2] & 0x400) + segdat[2] = (segdat[2] & ~(3 << (5 + 8))) | ((seg & 3) << (5 + 8)); + CS = seg; + do_seg_load(&cpu_state.seg_cs, segdat); + cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~(3 << 5)) | ((CS & 3) << 5); + if (CPL == 3 && oldcpl != 3) + flushmmucache_cr3(); + oldcpl = CPL; + set_use32(segdat[3] & 0x40); -// pclog("CPL=RPL return to %04X:%08X\n",CS,pc); - cycles -= timing_retf_pm; - } else { - switch (segdat[2] & 0x1F00) { - case 0x1800: - case 0x1900: - case 0x1A00: - case 0x1B00: /*Non-conforming*/ - if ((seg & 3) != DPL) { - pclog("RETF non-conforming RPL != DPL\n"); - ESP = oldsp; - x86gpf(NULL, seg & ~3); - return; - } - if (output) - pclog("RETF non-conforming, %i %i\n", seg & 3, DPL); - break; - case 0x1C00: - case 0x1D00: - case 0x1E00: - case 0x1F00: /*Conforming*/ - if ((seg & 3) < DPL) { - pclog("RETF non-conforming RPL < DPL\n"); - ESP = oldsp; - x86gpf(NULL, seg & ~3); - return; - } - if (output) - pclog("RETF conforming, %i %i\n", seg & 3, DPL); - break; - default:pclog("RETF CS not code segment\n"); - ESP = oldsp; - x86gpf(NULL, seg & ~3); - return; - } - if (!(segdat[2] & 0x8000)) { - pclog("RETF CS not present! %i %04X %04X %04X\n", ins, segdat[0], segdat[1], segdat[2]); + // pclog("CPL=RPL return to %04X:%08X\n",CS,pc); + cycles -= timing_retf_pm; + } else { + switch (segdat[2] & 0x1F00) { + case 0x1800: + case 0x1900: + case 0x1A00: + case 0x1B00: /*Non-conforming*/ + if ((seg & 3) != DPL) { + pclog("RETF non-conforming RPL != DPL\n"); + ESP = oldsp; + x86gpf(NULL, seg & ~3); + return; + } + if (output) + pclog("RETF non-conforming, %i %i\n", seg & 3, DPL); + break; + case 0x1C00: + case 0x1D00: + case 0x1E00: + case 0x1F00: /*Conforming*/ + if ((seg & 3) < DPL) { + pclog("RETF non-conforming RPL < DPL\n"); + ESP = oldsp; + x86gpf(NULL, seg & ~3); + return; + } + if (output) + pclog("RETF conforming, %i %i\n", seg & 3, DPL); + break; + default: + pclog("RETF CS not code segment\n"); + ESP = oldsp; + x86gpf(NULL, seg & ~3); + return; + } + if (!(segdat[2] & 0x8000)) { + pclog("RETF CS not present! %i %04X %04X %04X\n", ins, segdat[0], segdat[1], segdat[2]); - ESP = oldsp; - x86np("RETF CS not present\n", seg & 0xfffc); - return; - } - if (is32) { - newsp = POPL(); - newss = POPL(); - if (cpu_state.abrt) - return; -// pclog("is32 new stack %04X:%04X\n",newss,newsp); - } else { - if (output) - pclog("SP read from %04X:%04X\n", SS, SP); - newsp = POPW(); - if (output) - pclog("SS read from %04X:%04X\n", SS, SP); - newss = POPW(); - if (cpu_state.abrt) - return; -// pclog("!is32 new stack %04X:%04X\n",newss,newsp); - } - if (output) - pclog("Read new stack : %04X:%04X (%08X)\n", newss, newsp, ldt.base); - if (!(newss & ~3)) { - pclog("RETF loading null SS\n"); - ESP = oldsp; - x86gpf(NULL, newss & ~3); - return; - } - addr = newss & ~7; - if (newss & 4) { - if (addr >= ldt.limit) { - pclog("Bigger than LDT limit %04X %04X RETF SS\n", newss, gdt.limit); - ESP = oldsp; - x86gpf(NULL, newss & ~3); - return; - } - addr += ldt.base; - } else { - if (addr >= gdt.limit) { - pclog("Bigger than GDT limit %04X %04X RETF SS\n", newss, 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 (output) - pclog("Segment data %04X %04X %04X %04X\n", segdat2[0], segdat2[1], segdat2[2], segdat2[3]); -// if (((newss & 3) != DPL) || (DPL2 != DPL)) - if ((newss & 3) != (seg & 3)) { - pclog("RETF loading SS with wrong permissions %i %i %04X %04X\n", newss & 3, seg & 3, newss, seg); - ESP = oldsp; -// output = 3; -// dumpregs(); -// exit(-1); - x86gpf(NULL, newss & ~3); - return; - } - if ((segdat2[2] & 0x1A00) != 0x1200) { - pclog("RETF loading SS wrong type\n"); - ESP = oldsp; -// dumpregs(); -// exit(-1); - x86gpf(NULL, newss & ~3); - return; - } - if (!(segdat2[2] & 0x8000)) { - pclog("RETF loading SS not present\n"); - ESP = oldsp; - x86np("RETF loading SS not present\n", newss & 0xfffc); - return; - } - if (DPL2 != (seg & 3)) { - pclog("RETF loading SS with wrong permissions2 %i %i %04X %04X\n", DPL2, seg & 3, newss, seg); - 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(&cpu_state.seg_ss, segdat2); + ESP = oldsp; + x86np("RETF CS not present\n", seg & 0xfffc); + return; + } + if (is32) { + newsp = POPL(); + newss = POPL(); + if (cpu_state.abrt) + return; + // pclog("is32 new stack %04X:%04X\n",newss,newsp); + } else { + if (output) + pclog("SP read from %04X:%04X\n", SS, SP); + newsp = POPW(); + if (output) + pclog("SS read from %04X:%04X\n", SS, SP); + newss = POPW(); + if (cpu_state.abrt) + return; + // pclog("!is32 new stack %04X:%04X\n",newss,newsp); + } + if (output) + pclog("Read new stack : %04X:%04X (%08X)\n", newss, newsp, ldt.base); + if (!(newss & ~3)) { + pclog("RETF loading null SS\n"); + ESP = oldsp; + x86gpf(NULL, newss & ~3); + return; + } + addr = newss & ~7; + if (newss & 4) { + if (addr >= ldt.limit) { + pclog("Bigger than LDT limit %04X %04X RETF SS\n", newss, gdt.limit); + ESP = oldsp; + x86gpf(NULL, newss & ~3); + return; + } + addr += ldt.base; + } else { + if (addr >= gdt.limit) { + pclog("Bigger than GDT limit %04X %04X RETF SS\n", newss, 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 (output) + pclog("Segment data %04X %04X %04X %04X\n", segdat2[0], segdat2[1], segdat2[2], segdat2[3]); + // if (((newss & 3) != DPL) || (DPL2 != DPL)) + if ((newss & 3) != (seg & 3)) { + pclog("RETF loading SS with wrong permissions %i %i %04X %04X\n", newss & 3, seg & 3, newss, seg); + ESP = oldsp; + // output = 3; + // dumpregs(); + // exit(-1); + x86gpf(NULL, newss & ~3); + return; + } + if ((segdat2[2] & 0x1A00) != 0x1200) { + pclog("RETF loading SS wrong type\n"); + ESP = oldsp; + // dumpregs(); + // exit(-1); + x86gpf(NULL, newss & ~3); + return; + } + if (!(segdat2[2] & 0x8000)) { + pclog("RETF loading SS not present\n"); + ESP = oldsp; + x86np("RETF loading SS not present\n", newss & 0xfffc); + return; + } + if (DPL2 != (seg & 3)) { + pclog("RETF loading SS with wrong permissions2 %i %i %04X %04X\n", DPL2, seg & 3, newss, seg); + 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(&cpu_state.seg_ss, segdat2); #ifdef SEL_ACCESSED - cpl_override = 1; - writememw(0, addr + 4, segdat2[2] | 0x100); /*Set accessed bit*/ + 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*/ + writememw(0, oaddr + 4, segdat[2] | 0x100); /*Set accessed bit*/ #endif - cpl_override = 0; + 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)); + /*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(&cpu_state.seg_cs, segdat); - if (CPL == 3 && oldcpl != 3) - flushmmucache_cr3(); - oldcpl = CPL; - set_use32(segdat[3] & 0x40); + cpu_state.pc = newpc; + CS = seg; + do_seg_load(&cpu_state.seg_cs, segdat); + if (CPL == 3 && oldcpl != 3) + flushmmucache_cr3(); + oldcpl = CPL; + set_use32(segdat[3] & 0x40); - if (stack32) - ESP += off; - else - SP += off; + if (stack32) + ESP += off; + else + SP += off; - check_seg_valid(&cpu_state.seg_ds); - check_seg_valid(&cpu_state.seg_es); - check_seg_valid(&cpu_state.seg_fs); - check_seg_valid(&cpu_state.seg_gs); -// pclog("CPL= idt.limit) { - if (num == 8) { - /*Triple fault - reset!*/ - pclog("Triple fault!\n"); -// output=1; - softresetx86(); - cpu_set_edx(); - } else if (num == 0xD) { - pclog("Double fault!\n"); - pmodeint(8, 0); - } else { - pclog("INT out of range\n"); - x86gpf(NULL, (num * 8) + 2 + (soft) ? 0 : 1); - } - if (output) - pclog("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) { - pclog("Abrt reading from %08X\n", addr); - return; - } - oaddr = addr; + // if (!num) pclog("Pmode int 0 at %04X(%06X):%08X\n",CS,cs,pc); + // pclog("Pmode int %02X %i %04X:%08X %04X:%08X %i\n",num,soft,CS,pc, SS, ESP, abrt); + if (cpu_state.eflags & VM_FLAG && IOPL != 3 && soft) { + if (output) + pclog("V86 banned int\n"); + pclog("V86 banned int!\n"); + x86gpf(NULL, 0); + return; + // dumpregs(); + // exit(-1); + } + addr = (num << 3); + if (addr >= idt.limit) { + if (num == 8) { + /*Triple fault - reset!*/ + pclog("Triple fault!\n"); + // output=1; + softresetx86(); + cpu_set_edx(); + } else if (num == 0xD) { + pclog("Double fault!\n"); + pmodeint(8, 0); + } else { + pclog("INT out of range\n"); + x86gpf(NULL, (num * 8) + 2 + (soft) ? 0 : 1); + } + if (output) + pclog("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) { + pclog("Abrt reading from %08X\n", addr); + return; + } + oaddr = addr; - if (output) - pclog("Addr %08X seg %04X %04X %04X %04X\n", addr, segdat[0], segdat[1], segdat[2], segdat[3]); - if (!(segdat[2] & 0x1F00)) { -// pclog("No seg\n"); - if (cpu_state.eflags & VM_FLAG) /*This fires on all V86 interrupts in EMM386. Mark as expected to prevent code churn*/ - x86gpf_expected(NULL, (num * 8) + 2); - else - x86gpf(NULL, (num * 8) + 2); - return; - } - if (DPL < CPL && soft) { - //pclog("INT : DPL= 0x800) ? 32 : 16; -// if (output) pclog("Int gate %04X %i oldpc %04X pc %04X\n",type,intgatesize,oldpc,pc); - if (!(segdat[2] & 0x8000)) { - pclog("Int gate not present\n"); - x86np("Int gate not present\n", (num << 3) | 2); - return; - } - seg = segdat[1]; - new_cpl = seg & 3; -// pclog("Interrupt gate : %04X:%04X%04X\n",seg,segdat[3],segdat[0]); + if (output) + pclog("Addr %08X seg %04X %04X %04X %04X\n", addr, segdat[0], segdat[1], segdat[2], segdat[3]); + if (!(segdat[2] & 0x1F00)) { + // pclog("No seg\n"); + if (cpu_state.eflags & + VM_FLAG) /*This fires on all V86 interrupts in EMM386. Mark as expected to prevent code churn*/ + x86gpf_expected(NULL, (num * 8) + 2); + else + x86gpf(NULL, (num * 8) + 2); + return; + } + if (DPL < CPL && soft) { + // pclog("INT : DPL= 0x800) ? 32 : 16; + // if (output) pclog("Int gate %04X %i oldpc %04X pc %04X\n",type,intgatesize,oldpc,pc); + if (!(segdat[2] & 0x8000)) { + pclog("Int gate not present\n"); + x86np("Int gate not present\n", (num << 3) | 2); + return; + } + seg = segdat[1]; + new_cpl = seg & 3; + // pclog("Interrupt gate : %04X:%04X%04X\n",seg,segdat[3],segdat[0]); - addr = seg & ~7; - if (seg & 4) { - if (addr >= ldt.limit) { - pclog("Bigger than LDT limit %04X %04X INT\n", seg, gdt.limit); - x86gpf(NULL, seg & ~3); - return; - } - addr += ldt.base; - } else { - if (addr >= gdt.limit) { - pclog("Bigger than GDT limit %04X %04X INT %i\n", seg, gdt.limit, ins); - x86gpf(NULL, seg & ~3); - return; - } - addr += gdt.base; - } -/* if ((seg&3) < CPL) - { - pclog("INT to higher level\n"); - x86gpf(NULL,seg&~3); + addr = seg & ~7; + if (seg & 4) { + if (addr >= ldt.limit) { + pclog("Bigger than LDT limit %04X %04X INT\n", seg, gdt.limit); + x86gpf(NULL, seg & ~3); return; - }*/ - 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; + } + addr += ldt.base; + } else { + if (addr >= gdt.limit) { + pclog("Bigger than GDT limit %04X %04X INT %i\n", seg, gdt.limit, ins); + x86gpf(NULL, seg & ~3); + return; + } + addr += gdt.base; + } + /* if ((seg&3) < CPL) + { + pclog("INT to higher level\n"); + x86gpf(NULL,seg&~3); + return; + }*/ + 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) { - pclog("INT to higher level 2\n"); - x86gpf(NULL, seg & ~3); - return; - } - //pclog("Type %04X\n",segdat2[2]); - switch (segdat2[2] & 0x1F00) { - case 0x1800: - case 0x1900: - case 0x1A00: - case 0x1B00: /*Non-conforming*/ - if (DPL2 < CPL) { - if (!(segdat2[2] & 0x8000)) { - pclog("Int gate CS not present\n"); - x86np("Int gate CS not present\n", segdat[1] & 0xfffc); - return; - } - if ((cpu_state.eflags & VM_FLAG) && DPL2) { - pclog("V86 calling int gate, DPL != 0\n"); - x86gpf(NULL, segdat[1] & 0xFFFC); - return; - } - /*Load new stack*/ - oldss = SS; - oldsp = ESP; - cpl_override = 1; - if (tr.access & 8) { - addr = 4 + tr.base + (DPL2 * 8); - newss = readmemw(0, addr + 4); - newsp = readmeml(0, addr); - } else { - addr = 2 + tr.base + (DPL2 * 4); - newss = readmemw(0, addr + 2); - newsp = readmemw(0, addr); - } - cpl_override = 0; - if (!(newss & ~3)) { - pclog("Int gate loading null SS\n"); - x86ss(NULL, newss & ~3); - return; - } - addr = newss & ~7; - if (newss & 4) { - if (addr >= ldt.limit) { - pclog("Bigger than LDT limit %04X %04X PMODEINT SS\n", newss, gdt.limit); - x86ss(NULL, newss & ~3); - return; - } - addr += ldt.base; - } else { - if (addr >= gdt.limit) { - pclog("Bigger than GDT limit %04X %04X CSC\n", newss, 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)) { - pclog("Int gate loading SS with wrong permissions\n"); - x86ss(NULL, newss & ~3); - return; - } - if ((segdat3[2] & 0x1A00) != 0x1200) { - pclog("Int gate loading SS wrong type\n"); - x86ss(NULL, newss & ~3); - return; - } - if (!(segdat3[2] & 0x8000)) { - pclog("Int gate loading SS not present\n"); - 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(&cpu_state.seg_ss, segdat3); + if (DPL2 > CPL) { + pclog("INT to higher level 2\n"); + x86gpf(NULL, seg & ~3); + return; + } + // pclog("Type %04X\n",segdat2[2]); + switch (segdat2[2] & 0x1F00) { + case 0x1800: + case 0x1900: + case 0x1A00: + case 0x1B00: /*Non-conforming*/ + if (DPL2 < CPL) { + if (!(segdat2[2] & 0x8000)) { + pclog("Int gate CS not present\n"); + x86np("Int gate CS not present\n", segdat[1] & 0xfffc); + return; + } + if ((cpu_state.eflags & VM_FLAG) && DPL2) { + pclog("V86 calling int gate, DPL != 0\n"); + x86gpf(NULL, segdat[1] & 0xFFFC); + return; + } + /*Load new stack*/ + oldss = SS; + oldsp = ESP; + cpl_override = 1; + if (tr.access & 8) { + addr = 4 + tr.base + (DPL2 * 8); + newss = readmemw(0, addr + 4); + newsp = readmeml(0, addr); + } else { + addr = 2 + tr.base + (DPL2 * 4); + newss = readmemw(0, addr + 2); + newsp = readmemw(0, addr); + } + cpl_override = 0; + if (!(newss & ~3)) { + pclog("Int gate loading null SS\n"); + x86ss(NULL, newss & ~3); + return; + } + addr = newss & ~7; + if (newss & 4) { + if (addr >= ldt.limit) { + pclog("Bigger than LDT limit %04X %04X PMODEINT SS\n", newss, gdt.limit); + x86ss(NULL, newss & ~3); + return; + } + addr += ldt.base; + } else { + if (addr >= gdt.limit) { + pclog("Bigger than GDT limit %04X %04X CSC\n", newss, 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)) { + pclog("Int gate loading SS with wrong permissions\n"); + x86ss(NULL, newss & ~3); + return; + } + if ((segdat3[2] & 0x1A00) != 0x1200) { + pclog("Int gate loading SS wrong type\n"); + x86ss(NULL, newss & ~3); + return; + } + if (!(segdat3[2] & 0x8000)) { + pclog("Int gate loading SS not present\n"); + 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(&cpu_state.seg_ss, segdat3); #ifdef CS_ACCESSED - cpl_override = 1; - writememw(0, addr + 4, segdat3[2] | 0x100); /*Set accessed bit*/ - cpl_override = 0; + cpl_override = 1; + writememw(0, addr + 4, segdat3[2] | 0x100); /*Set accessed bit*/ + cpl_override = 0; #endif - if (output) - pclog("New stack %04X:%08X\n", SS, ESP); - cpl_override = 1; - if (type >= 0x800) { -// if (output) pclog("Push 32 %i\n",eflags&VM_FLAG); - if (cpu_state.eflags & VM_FLAG) { - PUSHL(GS); - PUSHL(FS); - PUSHL(DS); - PUSHL(ES); - if (cpu_state.abrt) - return; - loadseg(0, &cpu_state.seg_ds); - loadseg(0, &cpu_state.seg_es); - loadseg(0, &cpu_state.seg_fs); - loadseg(0, &cpu_state.seg_gs); - } - PUSHL(oldss); - PUSHL(oldsp); - PUSHL(cpu_state.flags | (cpu_state.eflags << 16)); -// if (soft) pclog("Pushl CS %08X\n", CS); - PUSHL(CS); -// if (soft) pclog("Pushl PC %08X\n", pc); - PUSHL(cpu_state.pc); - if (cpu_state.abrt) - return; -// if (output) pclog("32Stack %04X:%08X\n",SS,ESP); - } else { -// if (output) pclog("Push 16\n"); - PUSHW(oldss); - PUSHW(oldsp); - PUSHW(cpu_state.flags); -// if (soft) pclog("Pushw CS %04X\n", CS); - PUSHW(CS); -// if (soft) pclog("Pushw pc %04X\n", pc); - PUSHW(cpu_state.pc); - if (cpu_state.abrt) - return; -// if (output) pclog("16Stack %04X:%08X\n",SS,ESP); - } - cpl_override = 0; - cpu_state.seg_cs.access = 0; - cycles -= timing_int_pm_outer - timing_int_pm; -// pclog("Non-confirming int gate, CS = %04X\n"); - break; - } else if (DPL2 != CPL) { - pclog("Non-conforming int gate DPL != CPL\n"); - x86gpf(NULL, seg & ~3); - return; - } - case 0x1C00: - case 0x1D00: - case 0x1E00: - case 0x1F00: /*Conforming*/ - if (!(segdat2[2] & 0x8000)) { - pclog("Int gate CS not present\n"); - x86np("Int gate CS not present\n", segdat[1] & 0xfffc); - return; - } - if ((cpu_state.eflags & VM_FLAG) && DPL2 < CPL) { - pclog("Int gate V86 mode DPL2 0x800) { - PUSHL(cpu_state.flags | (cpu_state.eflags << 16)); -// if (soft) pclog("Pushlc CS %08X\n", CS); - PUSHL(CS); -// if (soft) pclog("Pushlc PC %08X\n", pc); - PUSHL(cpu_state.pc); - if (cpu_state.abrt) - return; - } else { - PUSHW(cpu_state.flags); -// if (soft) pclog("Pushwc CS %04X\n", CS); - PUSHW(CS); -// if (soft) pclog("Pushwc PC %04X\n", pc); - PUSHW(cpu_state.pc); - if (cpu_state.abrt) - return; - } - new_cpl = CS & 3; - break; - default:pclog("Int gate CS not code segment - %04X %04X %04X %04X\n", segdat2[0], segdat2[1], segdat2[2], segdat2[3]); - x86gpf(NULL, seg & ~3); - return; - } - do_seg_load(&cpu_state.seg_cs, segdat2); - CS = (seg & ~3) | new_cpl; - cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~(3 << 5)) | (new_cpl << 5); -// pclog("New CS = %04X\n",CS); - if (CPL == 3 && oldcpl != 3) - flushmmucache_cr3(); - oldcpl = CPL; - if (type > 0x800) - cpu_state.pc = segdat[0] | (segdat[3] << 16); - else - cpu_state.pc = segdat[0]; - set_use32(segdat2[3] & 0x40); -// pclog("Int gate done!\n"); + if (output) + pclog("New stack %04X:%08X\n", SS, ESP); + cpl_override = 1; + if (type >= 0x800) { + // if (output) pclog("Push 32 + // %i\n",eflags&VM_FLAG); + if (cpu_state.eflags & VM_FLAG) { + PUSHL(GS); + PUSHL(FS); + PUSHL(DS); + PUSHL(ES); + if (cpu_state.abrt) + return; + loadseg(0, &cpu_state.seg_ds); + loadseg(0, &cpu_state.seg_es); + loadseg(0, &cpu_state.seg_fs); + loadseg(0, &cpu_state.seg_gs); + } + PUSHL(oldss); + PUSHL(oldsp); + PUSHL(cpu_state.flags | (cpu_state.eflags << 16)); + // if (soft) pclog("Pushl CS %08X\n", CS); + PUSHL(CS); + // if (soft) pclog("Pushl PC %08X\n", pc); + PUSHL(cpu_state.pc); + if (cpu_state.abrt) + return; + // if (output) pclog("32Stack + // %04X:%08X\n",SS,ESP); + } else { + // if (output) pclog("Push 16\n"); + PUSHW(oldss); + PUSHW(oldsp); + PUSHW(cpu_state.flags); + // if (soft) pclog("Pushw CS %04X\n", CS); + PUSHW(CS); + // if (soft) pclog("Pushw pc %04X\n", pc); + PUSHW(cpu_state.pc); + if (cpu_state.abrt) + return; + // if (output) pclog("16Stack + // %04X:%08X\n",SS,ESP); + } + cpl_override = 0; + cpu_state.seg_cs.access = 0; + cycles -= timing_int_pm_outer - timing_int_pm; + // pclog("Non-confirming int gate, CS = %04X\n"); + break; + } else if (DPL2 != CPL) { + pclog("Non-conforming int gate DPL != CPL\n"); + x86gpf(NULL, seg & ~3); + return; + } + case 0x1C00: + case 0x1D00: + case 0x1E00: + case 0x1F00: /*Conforming*/ + if (!(segdat2[2] & 0x8000)) { + pclog("Int gate CS not present\n"); + x86np("Int gate CS not present\n", segdat[1] & 0xfffc); + return; + } + if ((cpu_state.eflags & VM_FLAG) && DPL2 < CPL) { + pclog("Int gate V86 mode DPL2 0x800) { + PUSHL(cpu_state.flags | (cpu_state.eflags << 16)); + // if (soft) pclog("Pushlc CS %08X\n", CS); + PUSHL(CS); + // if (soft) pclog("Pushlc PC %08X\n", pc); + PUSHL(cpu_state.pc); + if (cpu_state.abrt) + return; + } else { + PUSHW(cpu_state.flags); + // if (soft) pclog("Pushwc CS %04X\n", CS); + PUSHW(CS); + // if (soft) pclog("Pushwc PC %04X\n", pc); + PUSHW(cpu_state.pc); + if (cpu_state.abrt) + return; + } + new_cpl = CS & 3; + break; + default: + pclog("Int gate CS not code segment - %04X %04X %04X %04X\n", segdat2[0], segdat2[1], segdat2[2], + segdat2[3]); + x86gpf(NULL, seg & ~3); + return; + } + do_seg_load(&cpu_state.seg_cs, segdat2); + CS = (seg & ~3) | new_cpl; + cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~(3 << 5)) | (new_cpl << 5); + // pclog("New CS = %04X\n",CS); + if (CPL == 3 && oldcpl != 3) + flushmmucache_cr3(); + oldcpl = CPL; + if (type > 0x800) + cpu_state.pc = segdat[0] | (segdat[3] << 16); + else + cpu_state.pc = segdat[0]; + set_use32(segdat2[3] & 0x40); + // pclog("Int gate done!\n"); #ifdef CS_ACCESSED - cpl_override = 1; - writememw(0, oaddr + 4, segdat2[2] | 0x100); /*Set accessed bit*/ - cpl_override = 0; + cpl_override = 1; + writememw(0, oaddr + 4, segdat2[2] | 0x100); /*Set accessed bit*/ + cpl_override = 0; #endif - cpu_state.eflags &= ~VM_FLAG; - cpu_cur_status &= ~CPU_STATUS_V86; - if (!(type & 0x100)) { - cpu_state.flags &= ~I_FLAG; -// pclog("INT %02X disabling interrupts %i\n",num,soft); - } - cpu_state.flags &= ~(T_FLAG | NT_FLAG); -// if (output) pclog("Final Stack %04X:%08X\n",SS,ESP); - cycles -= timing_int_pm; - break; + cpu_state.eflags &= ~VM_FLAG; + cpu_cur_status &= ~CPU_STATUS_V86; + if (!(type & 0x100)) { + cpu_state.flags &= ~I_FLAG; + // pclog("INT %02X disabling interrupts %i\n",num,soft); + } + cpu_state.flags &= ~(T_FLAG | NT_FLAG); + // if (output) pclog("Final Stack %04X:%08X\n",SS,ESP); + cycles -= timing_int_pm; + break; - case 0x500: /*Task gate*/ -// pclog("Task gate\n"); - seg = segdat[1]; - addr = seg & ~7; - if (seg & 4) { - if (addr >= ldt.limit) { - pclog("Bigger than LDT limit %04X %04X INT\n", seg, gdt.limit); - x86gpf(NULL, seg & ~3); - return; - } - addr += ldt.base; - } else { - if (addr >= gdt.limit) { - pclog("Bigger than GDT limit %04X %04X INT %i\n", seg, gdt.limit, ins); - 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)) { - pclog("Int task gate not present\n"); - 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; + case 0x500: /*Task gate*/ + // pclog("Task gate\n"); + seg = segdat[1]; + addr = seg & ~7; + if (seg & 4) { + if (addr >= ldt.limit) { + pclog("Bigger than LDT limit %04X %04X INT\n", seg, gdt.limit); + x86gpf(NULL, seg & ~3); + return; + } + addr += ldt.base; + } else { + if (addr >= gdt.limit) { + pclog("Bigger than GDT limit %04X %04X INT %i\n", seg, gdt.limit, ins); + 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)) { + pclog("Int task gate not present\n"); + 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:pclog("Bad int gate type %04X %04X %04X %04X %04X\n", segdat[2] & 0x1F00, segdat[0], segdat[1], segdat[2], segdat[3]); - x86gpf(NULL, seg & ~3); - return; - } + default: + pclog("Bad int gate type %04X %04X %04X %04X %04X\n", segdat[2] & 0x1F00, segdat[0], segdat[1], segdat[2], + segdat[3]); + 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 = 0; - uint32_t addr, oaddr; - uint32_t oldsp = ESP; - if (is386 && (cpu_state.eflags & VM_FLAG)) { -// if (output) pclog("V86 IRET\n"); - if (IOPL != 3) { - pclog("V86 IRET! IOPL!=3\n"); - x86gpf(NULL, 0); - return; - } - 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; - cpu_state.seg_cs.base = seg << 4; - cpu_state.seg_cs.limit = 0xFFFF; - cpu_state.seg_cs.limit_low = 0; - cpu_state.seg_cs.limit_high = 0xffff; - CS = seg; - cpu_state.flags = (cpu_state.flags & 0x3000) | (tempflags & 0xCFD5) | 2; - cycles -= timing_iret_rm; - return; - } + 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 = 0; + uint32_t addr, oaddr; + uint32_t oldsp = ESP; + if (is386 && (cpu_state.eflags & VM_FLAG)) { + // if (output) pclog("V86 IRET\n"); + if (IOPL != 3) { + pclog("V86 IRET! IOPL!=3\n"); + x86gpf(NULL, 0); + return; + } + 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; + cpu_state.seg_cs.base = seg << 4; + cpu_state.seg_cs.limit = 0xFFFF; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.limit_high = 0xffff; + CS = seg; + cpu_state.flags = (cpu_state.flags & 0x3000) | (tempflags & 0xCFD5) | 2; + cycles -= timing_iret_rm; + return; + } -// pclog("IRET %i\n",is32); - //flushmmucache(); -// if (output) pclog("Pmode IRET %04X:%04X ",CS,pc); + // pclog("IRET %i\n",is32); + // flushmmucache(); + // if (output) pclog("Pmode IRET %04X:%04X ",CS,pc); - if (cpu_state.flags & NT_FLAG) { -// pclog("NT IRET\n"); - seg = readmemw(tr.base, 0); - addr = seg & ~7; - if (seg & 4) { - pclog("TS LDT %04X %04X IRET\n", seg, gdt.limit); - x86ts(NULL, seg & ~3); - return; - } else { - if (addr >= gdt.limit) { - pclog("TS Bigger than GDT limit %04X %04X IRET\n", seg, 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; - } - flagmask = 0xFFFF; - if (CPL) - flagmask &= ~0x3000; - if (IOPL < CPL) - flagmask &= ~0x200; -// if (output) pclog("IRET %i %i %04X %i\n",CPL,IOPL,flagmask,is32); - if (is32) { -// pclog("POP\n"); - newpc = POPL(); - seg = POPL(); - tempflags = POPL(); - if (cpu_state.abrt) { - ESP = oldsp; - return; - } -// if (output) pclog("IRETD pop %08X %08X %08X\n",newpc,seg,tempflags); - if (is386 && ((tempflags >> 16) & VM_FLAG)) { -// pclog("IRETD to V86\n"); + if (cpu_state.flags & NT_FLAG) { + // pclog("NT IRET\n"); + seg = readmemw(tr.base, 0); + addr = seg & ~7; + if (seg & 4) { + pclog("TS LDT %04X %04X IRET\n", seg, gdt.limit); + x86ts(NULL, seg & ~3); + return; + } else { + if (addr >= gdt.limit) { + pclog("TS Bigger than GDT limit %04X %04X IRET\n", seg, 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; + } + flagmask = 0xFFFF; + if (CPL) + flagmask &= ~0x3000; + if (IOPL < CPL) + flagmask &= ~0x200; + // if (output) pclog("IRET %i %i %04X %i\n",CPL,IOPL,flagmask,is32); + if (is32) { + // pclog("POP\n"); + newpc = POPL(); + seg = POPL(); + tempflags = POPL(); + if (cpu_state.abrt) { + ESP = oldsp; + return; + } + // if (output) pclog("IRETD pop %08X %08X %08X\n",newpc,seg,tempflags); + if (is386 && ((tempflags >> 16) & VM_FLAG)) { + // pclog("IRETD to V86\n"); - newsp = POPL(); - newss = POPL(); - segs[0] = POPL(); - segs[1] = POPL(); - segs[2] = POPL(); - segs[3] = POPL(); - if (cpu_state.abrt) { - ESP = oldsp; - return; - } -// pclog("Pop stack %04X:%04X\n",newss,newsp); - cpu_state.eflags = tempflags >> 16; - cpu_cur_status |= CPU_STATUS_V86; - loadseg(segs[0], &cpu_state.seg_es); - do_seg_v86_init(&cpu_state.seg_es); - loadseg(segs[1], &cpu_state.seg_ds); - do_seg_v86_init(&cpu_state.seg_ds); - cpu_cur_status |= CPU_STATUS_NOTFLATDS; - loadseg(segs[2], &cpu_state.seg_fs); - do_seg_v86_init(&cpu_state.seg_fs); - loadseg(segs[3], &cpu_state.seg_gs); - do_seg_v86_init(&cpu_state.seg_gs); + newsp = POPL(); + newss = POPL(); + segs[0] = POPL(); + segs[1] = POPL(); + segs[2] = POPL(); + segs[3] = POPL(); + if (cpu_state.abrt) { + ESP = oldsp; + return; + } + // pclog("Pop stack %04X:%04X\n",newss,newsp); + cpu_state.eflags = tempflags >> 16; + cpu_cur_status |= CPU_STATUS_V86; + loadseg(segs[0], &cpu_state.seg_es); + do_seg_v86_init(&cpu_state.seg_es); + loadseg(segs[1], &cpu_state.seg_ds); + do_seg_v86_init(&cpu_state.seg_ds); + cpu_cur_status |= CPU_STATUS_NOTFLATDS; + loadseg(segs[2], &cpu_state.seg_fs); + do_seg_v86_init(&cpu_state.seg_fs); + loadseg(segs[3], &cpu_state.seg_gs); + do_seg_v86_init(&cpu_state.seg_gs); -// pclog("V86 IRET %04X:%08X\n",SS,ESP); -// output=3; + // pclog("V86 IRET %04X:%08X\n",SS,ESP); + // output=3; - cpu_state.pc = newpc & 0xffff; - cpu_state.seg_cs.base = seg << 4; - cpu_state.seg_cs.limit = 0xFFFF; - cpu_state.seg_cs.limit_low = 0; - cpu_state.seg_cs.limit_high = 0xffff; - CS = seg; - cpu_state.seg_cs.access = (3 << 5) | 2; - if (CPL == 3 && oldcpl != 3) - flushmmucache_cr3(); - oldcpl = CPL; + cpu_state.pc = newpc & 0xffff; + cpu_state.seg_cs.base = seg << 4; + cpu_state.seg_cs.limit = 0xFFFF; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.limit_high = 0xffff; + CS = seg; + cpu_state.seg_cs.access = (3 << 5) | 2; + if (CPL == 3 && oldcpl != 3) + flushmmucache_cr3(); + oldcpl = CPL; - ESP = newsp; - loadseg(newss, &cpu_state.seg_ss); - do_seg_v86_init(&cpu_state.seg_ss); - cpu_cur_status |= CPU_STATUS_NOTFLATSS; - use32 = 0; - cpu_cur_status &= ~CPU_STATUS_USE32; - cpu_state.flags = (tempflags & 0xFFD5) | 2; - cycles -= timing_iret_v86; -// pclog("V86 IRET to %04X:%04X %04X:%04X %04X %04X %04X %04X %i\n",CS,pc,SS,SP,DS,ES,FS,GS,abrt); - // if (CS==0xFFFF && pc==0xFFFFFFFF) timetolive=12; -/* { - dumpregs(); - exit(-1); - }*/ - return; - } - } else { - newpc = POPW(); - seg = POPW(); - tempflags = POPW(); - if (cpu_state.abrt) { - ESP = oldsp; - return; - } - } -// if (!is386) tempflags&=0xFFF; -// pclog("Returned to %04X:%08X %04X %04X %i\n",seg,newpc,flags,tempflags, ins); - if (!(seg & ~3)) { - pclog("IRET CS=0\n"); - ESP = oldsp; -// dumpregs(); -// exit(-1); - x86gpf(NULL, 0); - return; - } + ESP = newsp; + loadseg(newss, &cpu_state.seg_ss); + do_seg_v86_init(&cpu_state.seg_ss); + cpu_cur_status |= CPU_STATUS_NOTFLATSS; + use32 = 0; + cpu_cur_status &= ~CPU_STATUS_USE32; + cpu_state.flags = (tempflags & 0xFFD5) | 2; + cycles -= timing_iret_v86; + // pclog("V86 IRET to %04X:%04X %04X:%04X %04X %04X %04X %04X + // %i\n",CS,pc,SS,SP,DS,ES,FS,GS,abrt); + // if (CS==0xFFFF && pc==0xFFFFFFFF) timetolive=12; + /* { + dumpregs(); + exit(-1); + }*/ + return; + } + } else { + newpc = POPW(); + seg = POPW(); + tempflags = POPW(); + if (cpu_state.abrt) { + ESP = oldsp; + return; + } + } + // if (!is386) tempflags&=0xFFF; + // pclog("Returned to %04X:%08X %04X %04X %i\n",seg,newpc,flags,tempflags, ins); + if (!(seg & ~3)) { + pclog("IRET CS=0\n"); + ESP = oldsp; + // dumpregs(); + // exit(-1); + x86gpf(NULL, 0); + return; + } -// if (output) pclog("IRET %04X:%08X\n",seg,newpc); - addr = seg & ~7; - if (seg & 4) { - if (addr >= ldt.limit) { - pclog("Bigger than LDT limit %04X %04X IRET\n", seg, gdt.limit); - ESP = oldsp; - x86gpf(NULL, seg & ~3); - return; - } - addr += ldt.base; - } else { - if (addr >= gdt.limit) { - pclog("Bigger than GDT limit %04X %04X IRET\n", seg, gdt.limit); - ESP = oldsp; - x86gpf(NULL, seg & ~3); - return; - } - addr += gdt.base; - } - if ((seg & 3) < CPL) { - pclog("IRET to lower level\n"); - 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; - } -// pclog("Seg type %04X %04X\n",segdat[2]&0x1F00,segdat[2]); + // if (output) pclog("IRET %04X:%08X\n",seg,newpc); + addr = seg & ~7; + if (seg & 4) { + if (addr >= ldt.limit) { + pclog("Bigger than LDT limit %04X %04X IRET\n", seg, gdt.limit); + ESP = oldsp; + x86gpf(NULL, seg & ~3); + return; + } + addr += ldt.base; + } else { + if (addr >= gdt.limit) { + pclog("Bigger than GDT limit %04X %04X IRET\n", seg, gdt.limit); + ESP = oldsp; + x86gpf(NULL, seg & ~3); + return; + } + addr += gdt.base; + } + if ((seg & 3) < CPL) { + pclog("IRET to lower level\n"); + 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; + } + // pclog("Seg type %04X %04X\n",segdat[2]&0x1F00,segdat[2]); - switch (segdat[2] & 0x1F00) { - case 0x1800: - case 0x1900: - case 0x1A00: - case 0x1B00: /*Non-conforming code*/ - if ((seg & 3) != DPL) { - pclog("IRET NC DPL %04X %04X %04X %04X %04X\n", seg, segdat[0], segdat[1], segdat[2], segdat[3]); - ESP = oldsp; -// dumpregs(); -// exit(-1); - x86gpf(NULL, seg & ~3); - return; - } - break; - case 0x1C00: - case 0x1D00: - case 0x1E00: - case 0x1F00: /*Conforming code*/ - if ((seg & 3) < DPL) { - pclog("IRET C DPL\n"); - ESP = oldsp; - x86gpf(NULL, seg & ~3); - return; - } - break; - default:pclog("IRET CS != code seg\n"); - ESP = oldsp; - x86gpf(NULL, seg & ~3); -// dumpregs(); -// exit(-1); - return; - } - if (!(segdat[2] & 0x8000)) { - pclog("IRET CS not present %i %04X %04X %04X\n", ins, segdat[0], segdat[1], segdat[2]); - ESP = oldsp; - x86np("IRET CS not present\n", seg & 0xfffc); - return; - } -// pclog("Seg %04X CPL %04X\n",seg,CPL); - if ((seg & 3) == CPL) { -// pclog("Same level\n"); - CS = seg; - do_seg_load(&cpu_state.seg_cs, segdat); - cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~(3 << 5)) | ((CS & 3) << 5); - if (CPL == 3 && oldcpl != 3) - flushmmucache_cr3(); - oldcpl = CPL; - set_use32(segdat[3] & 0x40); + switch (segdat[2] & 0x1F00) { + case 0x1800: + case 0x1900: + case 0x1A00: + case 0x1B00: /*Non-conforming code*/ + if ((seg & 3) != DPL) { + pclog("IRET NC DPL %04X %04X %04X %04X %04X\n", seg, segdat[0], segdat[1], segdat[2], segdat[3]); + ESP = oldsp; + // dumpregs(); + // exit(-1); + x86gpf(NULL, seg & ~3); + return; + } + break; + case 0x1C00: + case 0x1D00: + case 0x1E00: + case 0x1F00: /*Conforming code*/ + if ((seg & 3) < DPL) { + pclog("IRET C DPL\n"); + ESP = oldsp; + x86gpf(NULL, seg & ~3); + return; + } + break; + default: + pclog("IRET CS != code seg\n"); + ESP = oldsp; + x86gpf(NULL, seg & ~3); + // dumpregs(); + // exit(-1); + return; + } + if (!(segdat[2] & 0x8000)) { + pclog("IRET CS not present %i %04X %04X %04X\n", ins, segdat[0], segdat[1], segdat[2]); + ESP = oldsp; + x86np("IRET CS not present\n", seg & 0xfffc); + return; + } + // pclog("Seg %04X CPL %04X\n",seg,CPL); + if ((seg & 3) == CPL) { + // pclog("Same level\n"); + CS = seg; + do_seg_load(&cpu_state.seg_cs, segdat); + cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~(3 << 5)) | ((CS & 3) << 5); + if (CPL == 3 && oldcpl != 3) + flushmmucache_cr3(); + oldcpl = CPL; + set_use32(segdat[3] & 0x40); #ifdef CS_ACCESSED - cpl_override = 1; - writememw(0, addr + 4, segdat[2] | 0x100); /*Set accessed bit*/ - cpl_override = 0; + 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; - if (output) - pclog("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; - } - } + cycles -= timing_iret_pm; + } else /*Return to outer level*/ + { + oaddr = addr; + if (output) + pclog("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; + } + } - if (output) - pclog("IRET load stack %04X:%04X\n", newss, newsp); + if (output) + pclog("IRET load stack %04X:%04X\n", newss, newsp); - if (!(newss & ~3)) { - pclog("IRET loading null SS\n"); - ESP = oldsp; - x86gpf(NULL, newss & ~3); - return; - } - addr = newss & ~7; - if (newss & 4) { - if (addr >= ldt.limit) { - pclog("Bigger than LDT limit %04X %04X PMODEIRET SS\n", newss, gdt.limit); - ESP = oldsp; - x86gpf(NULL, newss & ~3); - return; - } - addr += ldt.base; - } else { - if (addr >= gdt.limit) { - pclog("Bigger than GDT limit %04X %04X PMODEIRET\n", newss, 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; - } -// pclog("IRET SS sd2 %04X\n",segdat2[2]); -// if (((newss & 3) != DPL) || (DPL2 != DPL)) - if ((newss & 3) != (seg & 3)) { - pclog("IRET loading SS with wrong permissions %04X %04X\n", newss, seg); - ESP = oldsp; -// dumpregs(); -// exit(-1); - x86gpf(NULL, newss & ~3); - return; - } - if ((segdat2[2] & 0x1A00) != 0x1200) { - pclog("IRET loading SS wrong type\n"); - ESP = oldsp; - x86gpf(NULL, newss & ~3); - return; - } - if (DPL2 != (seg & 3)) { - pclog("IRET loading SS with wrong permissions2 %i %i %04X %04X\n", DPL2, seg & 3, newss, seg); - ESP = oldsp; - x86gpf(NULL, newss & ~3); - return; - } - if (!(segdat2[2] & 0x8000)) { - pclog("IRET loading SS not present\n"); - 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(&cpu_state.seg_ss, segdat2); + if (!(newss & ~3)) { + pclog("IRET loading null SS\n"); + ESP = oldsp; + x86gpf(NULL, newss & ~3); + return; + } + addr = newss & ~7; + if (newss & 4) { + if (addr >= ldt.limit) { + pclog("Bigger than LDT limit %04X %04X PMODEIRET SS\n", newss, gdt.limit); + ESP = oldsp; + x86gpf(NULL, newss & ~3); + return; + } + addr += ldt.base; + } else { + if (addr >= gdt.limit) { + pclog("Bigger than GDT limit %04X %04X PMODEIRET\n", newss, 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; + } + // pclog("IRET SS sd2 %04X\n",segdat2[2]); + // if (((newss & 3) != DPL) || (DPL2 != DPL)) + if ((newss & 3) != (seg & 3)) { + pclog("IRET loading SS with wrong permissions %04X %04X\n", newss, seg); + ESP = oldsp; + // dumpregs(); + // exit(-1); + x86gpf(NULL, newss & ~3); + return; + } + if ((segdat2[2] & 0x1A00) != 0x1200) { + pclog("IRET loading SS wrong type\n"); + ESP = oldsp; + x86gpf(NULL, newss & ~3); + return; + } + if (DPL2 != (seg & 3)) { + pclog("IRET loading SS with wrong permissions2 %i %i %04X %04X\n", DPL2, seg & 3, newss, seg); + ESP = oldsp; + x86gpf(NULL, newss & ~3); + return; + } + if (!(segdat2[2] & 0x8000)) { + pclog("IRET loading SS not present\n"); + 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(&cpu_state.seg_ss, segdat2); #ifdef SEL_ACCESSED - cpl_override = 1; - writememw(0, addr + 4, segdat2[2] | 0x100); /*Set accessed bit*/ + 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*/ + writememw(0, oaddr + 4, segdat[2] | 0x100); /*Set accessed bit*/ #endif - cpl_override = 0; + 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)); + /*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(&cpu_state.seg_cs, segdat); - cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~(3 << 5)) | ((CS & 3) << 5); - if (CPL == 3 && oldcpl != 3) - flushmmucache_cr3(); - oldcpl = CPL; - set_use32(segdat[3] & 0x40); + CS = seg; + do_seg_load(&cpu_state.seg_cs, segdat); + cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~(3 << 5)) | ((CS & 3) << 5); + if (CPL == 3 && oldcpl != 3) + flushmmucache_cr3(); + oldcpl = CPL; + set_use32(segdat[3] & 0x40); - check_seg_valid(&cpu_state.seg_ds); - check_seg_valid(&cpu_state.seg_es); - check_seg_valid(&cpu_state.seg_fs); - check_seg_valid(&cpu_state.seg_gs); - cycles -= timing_iret_pm_outer; - } - cpu_state.pc = newpc; - cpu_state.flags = (cpu_state.flags & ~flagmask) | (tempflags & flagmask & 0xFFD5) | 2; - if (is32) - cpu_state.eflags = tempflags >> 16; -// pclog("done\n"); + check_seg_valid(&cpu_state.seg_ds); + check_seg_valid(&cpu_state.seg_es); + check_seg_valid(&cpu_state.seg_fs); + check_seg_valid(&cpu_state.seg_gs); + cycles -= timing_iret_pm_outer; + } + cpu_state.pc = newpc; + cpu_state.flags = (cpu_state.flags & ~flagmask) | (tempflags & flagmask & 0xFFD5) | 2; + if (is32) + cpu_state.eflags = tempflags >> 16; + // pclog("done\n"); } void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) { - uint32_t base; - uint32_t limit; - uint32_t templ; - uint16_t tempw; + 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_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 new_eax, new_ebx, new_ecx, new_edx, new_esp, new_ebp, new_esi, new_edi, new_pc, new_flags; - uint32_t addr; + uint32_t addr; - uint16_t segdat2[4]; + uint16_t segdat2[4]; -//output=3; - base = segdat[1] | ((segdat[2] & 0xFF) << 16); - limit = segdat[0]; - if (is386) { - base |= (segdat[3] >> 8) << 24; - limit |= (segdat[3] & 0xF) << 16; - } -// pclog("286 Task switch! %04X:%04X\n",CS,pc); -/// pclog("TSS %04X base %08X limit %04X old TSS %04X %08X %i\n",seg,base,limit,tr.seg,tr.base,ins); -// / pclog("%04X %04X %04X %04X\n",segdat[0],segdat[1],segdat[2],segdat[3]); + // output=3; + base = segdat[1] | ((segdat[2] & 0xFF) << 16); + limit = segdat[0]; + if (is386) { + base |= (segdat[3] >> 8) << 24; + limit |= (segdat[3] & 0xF) << 16; + } + // pclog("286 Task switch! %04X:%04X\n",CS,pc); + /// pclog("TSS %04X base %08X limit %04X old TSS %04X %08X %i\n",seg,base,limit,tr.seg,tr.base,ins); + // / pclog("%04X %04X %04X %04X\n",segdat[0],segdat[1],segdat[2],segdat[3]); - if (is32) { -// if (output) pclog("32-bit TSS\n"); - if (limit < 103) { - pclog("32-bit TSS %04X limit less than 103.\n", seg); - x86ts(NULL, seg); - return; - } + if (is32) { + // if (output) pclog("32-bit TSS\n"); + if (limit < 103) { + pclog("32-bit TSS %04X limit less than 103.\n", seg); + 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 == 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) - cpu_state.flags &= ~NT_FLAG; + if (optype == IRET) + cpu_state.flags &= ~NT_FLAG; -// if (output) pclog("Write PC %08X %08X\n",tr.base,pc); - cpu_386_flags_rebuild(); - writememl(tr.base, 0x1C, cr3); - writememl(tr.base, 0x20, cpu_state.pc); - writememl(tr.base, 0x24, cpu_state.flags | (cpu_state.eflags << 16)); + // if (output) pclog("Write PC %08X %08X\n",tr.base,pc); + cpu_386_flags_rebuild(); + writememl(tr.base, 0x1C, cr3); + writememl(tr.base, 0x20, cpu_state.pc); + writememl(tr.base, 0x24, cpu_state.flags | (cpu_state.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, 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); -// if (output) pclog("Write CS %04X to %08X\n",CS,tr.base+0x4C); - 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); + writememl(tr.base, 0x48, ES); + // if (output) pclog("Write CS %04X to %08X\n",CS,tr.base+0x4C); + 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 == 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; - } + 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_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_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); -// if (output) pclog("Read CS from %08X\n",base+0x4C); - 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); + new_es = readmemw(base, 0x48); + // if (output) pclog("Read CS from %08X\n",base+0x4C); + 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; + cr0 |= 8; - cr3 = new_cr3; -// pclog("TS New CR3 %08X\n",cr3); - flushmmucache(); + cr3 = new_cr3; + // pclog("TS New CR3 %08X\n",cr3); + flushmmucache(); - cpu_state.pc = new_pc; -// if (output) pclog("New pc %08X\n",new_pc); - cpu_state.flags = new_flags; - cpu_state.eflags = new_flags >> 16; - cpu_386_flags_extract(); + cpu_state.pc = new_pc; + // if (output) pclog("New pc %08X\n",new_pc); + cpu_state.flags = new_flags; + cpu_state.eflags = new_flags >> 16; + cpu_386_flags_extract(); -// if (output) pclog("Load LDT %04X\n",new_ldt); - ldt.seg = new_ldt; - templ = (ldt.seg & ~7) + gdt.base; -// if (output) pclog("Load from %08X %08X\n",templ,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 (output) pclog("Limit %04X Base %08X\n",ldt.limit,ldt.base); + // if (output) pclog("Load LDT %04X\n",new_ldt); + ldt.seg = new_ldt; + templ = (ldt.seg & ~7) + gdt.base; + // if (output) pclog("Load from %08X %08X\n",templ,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 (output) pclog("Limit %04X Base %08X\n",ldt.limit,ldt.base); + if (cpu_state.eflags & VM_FLAG) { + loadcs(new_cs); + set_use32(0); + cpu_cur_status |= CPU_STATUS_V86; + } else { + if (!(new_cs & ~3)) { + pclog("TS loading null CS\n"); + x86ts(NULL, 0); + return; + } + addr = new_cs & ~7; + if (new_cs & 4) { + if (addr >= ldt.limit) { + pclog("Bigger than LDT limit %04X %04X %04X TS\n", new_cs, ldt.limit, addr); + x86ts(NULL, new_cs & ~3); + return; + } + addr += ldt.base; + } else { + if (addr >= gdt.limit) { + pclog("Bigger than GDT limit %04X %04X TS\n", new_cs, 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)) { + pclog("TS loading CS not present\n"); + 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) { + pclog("TS load CS non-conforming RPL != DPL"); + x86ts(NULL, new_cs & ~3); + return; + } + break; + case 0x1C00: + case 0x1D00: + case 0x1E00: + case 0x1F00: /*Conforming*/ + if ((new_cs & 3) < DPL2) { + pclog("TS load CS non-conforming RPL < DPL"); + x86ts(NULL, new_cs & ~3); + return; + } + break; + default: + pclog("TS load CS not code segment\n"); + x86ts(NULL, new_cs & ~3); + return; + } - if (cpu_state.eflags & VM_FLAG) { - loadcs(new_cs); - set_use32(0); - cpu_cur_status |= CPU_STATUS_V86; - } else { - if (!(new_cs & ~3)) { - pclog("TS loading null CS\n"); - x86ts(NULL, 0); - return; - } - addr = new_cs & ~7; - if (new_cs & 4) { - if (addr >= ldt.limit) { - pclog("Bigger than LDT limit %04X %04X %04X TS\n", new_cs, ldt.limit, addr); - x86ts(NULL, new_cs & ~3); - return; - } - addr += ldt.base; - } else { - if (addr >= gdt.limit) { - pclog("Bigger than GDT limit %04X %04X TS\n", new_cs, 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)) { - pclog("TS loading CS not present\n"); - 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) { - pclog("TS load CS non-conforming RPL != DPL"); - x86ts(NULL, new_cs & ~3); - return; - } - break; - case 0x1C00: - case 0x1D00: - case 0x1E00: - case 0x1F00: /*Conforming*/ - if ((new_cs & 3) < DPL2) { - pclog("TS load CS non-conforming RPL < DPL"); - x86ts(NULL, new_cs & ~3); - return; - } - break; - default:pclog("TS load CS not code segment\n"); - x86ts(NULL, new_cs & ~3); - return; - } + // if (output) pclog("new_cs %04X\n",new_cs); + CS = new_cs; + do_seg_load(&cpu_state.seg_cs, segdat2); + if (CPL == 3 && oldcpl != 3) + flushmmucache_cr3(); + oldcpl = CPL; + set_use32(segdat2[3] & 0x40); + cpu_cur_status &= ~CPU_STATUS_V86; + } -// if (output) pclog("new_cs %04X\n",new_cs); - CS = new_cs; - do_seg_load(&cpu_state.seg_cs, segdat2); - if (CPL == 3 && oldcpl != 3) - flushmmucache_cr3(); - oldcpl = CPL; - 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; - EAX = new_eax; - ECX = new_ecx; - EDX = new_edx; - EBX = new_ebx; - ESP = new_esp; - EBP = new_ebp; - ESI = new_esi; - EDI = new_edi; + if (output) + pclog("Load ES %04X\n", new_es); + loadseg(new_es, &cpu_state.seg_es); + if (output) + pclog("Load SS %04X\n", new_ss); + loadseg(new_ss, &cpu_state.seg_ss); + if (output) + pclog("Load DS %04X\n", new_ds); + loadseg(new_ds, &cpu_state.seg_ds); + if (output) + pclog("Load FS %04X\n", new_fs); + loadseg(new_fs, &cpu_state.seg_fs); + if (output) + pclog("Load GS %04X\n", new_gs); + loadseg(new_gs, &cpu_state.seg_gs); - if (output) - pclog("Load ES %04X\n", new_es); - loadseg(new_es, &cpu_state.seg_es); - if (output) - pclog("Load SS %04X\n", new_ss); - loadseg(new_ss, &cpu_state.seg_ss); - if (output) - pclog("Load DS %04X\n", new_ds); - loadseg(new_ds, &cpu_state.seg_ds); - if (output) - pclog("Load FS %04X\n", new_fs); - loadseg(new_fs, &cpu_state.seg_fs); - if (output) - pclog("Load GS %04X\n", new_gs); - loadseg(new_gs, &cpu_state.seg_gs); + if (output) + pclog("Resuming at %04X:%08X\n", CS, cpu_state.pc); + } else { + // pclog("16-bit TSS\n"); + // resetx86(); + if (limit < 43) { + pclog("16-bit TSS %04X limit less than 43.\n", seg); + x86ts(NULL, seg); + return; + } - if (output) - pclog("Resuming at %04X:%08X\n", CS, cpu_state.pc); - } else { -// pclog("16-bit TSS\n"); -// resetx86(); - if (limit < 43) { - pclog("16-bit TSS %04X limit less than 43.\n", seg); - 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 == 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) + cpu_state.flags &= ~NT_FLAG; - if (optype == IRET) - cpu_state.flags &= ~NT_FLAG; + // if (output) pclog("Write PC %08X %08X\n",tr.base,pc); + cpu_386_flags_rebuild(); + writememw(tr.base, 0x0E, cpu_state.pc); + writememw(tr.base, 0x10, cpu_state.flags); -// if (output) pclog("Write PC %08X %08X\n",tr.base,pc); - cpu_386_flags_rebuild(); - writememw(tr.base, 0x0E, cpu_state.pc); - writememw(tr.base, 0x10, cpu_state.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, 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); + // if (output) pclog("Write CS %04X to %08X\n",CS,tr.base+0x4C); + writememw(tr.base, 0x24, CS); + writememw(tr.base, 0x26, SS); + writememw(tr.base, 0x28, DS); - writememw(tr.base, 0x22, ES); -// if (output) pclog("Write CS %04X to %08X\n",CS,tr.base+0x4C); - 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 == 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; + } - 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_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_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); + // if (output) pclog("Read CS from %08X\n",base+0x4C); + new_cs = readmemw(base, 0x24); + new_ss = readmemw(base, 0x26); + new_ds = readmemw(base, 0x28); + new_ldt = readmemw(base, 0x2A); - new_es = readmemw(base, 0x22); -// if (output) pclog("Read CS from %08X\n",base+0x4C); - new_cs = readmemw(base, 0x24); - new_ss = readmemw(base, 0x26); - new_ds = readmemw(base, 0x28); - new_ldt = readmemw(base, 0x2A); + msw |= 8; - msw |= 8; + cpu_state.pc = new_pc; + // if (output) pclog("New pc %08X\n",new_pc); + cpu_state.flags = new_flags; + cpu_386_flags_extract(); - cpu_state.pc = new_pc; -// if (output) pclog("New pc %08X\n",new_pc); - cpu_state.flags = new_flags; - cpu_386_flags_extract(); + // if (output) pclog("Load LDT %04X\n",new_ldt); + ldt.seg = new_ldt; + templ = (ldt.seg & ~7) + gdt.base; + // if (output) pclog("Load from %08X %08X\n",templ,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 (output) pclog("Limit %04X Base %08X\n",ldt.limit,ldt.base); -// if (output) pclog("Load LDT %04X\n",new_ldt); - ldt.seg = new_ldt; - templ = (ldt.seg & ~7) + gdt.base; -// if (output) pclog("Load from %08X %08X\n",templ,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 (output) pclog("Limit %04X Base %08X\n",ldt.limit,ldt.base); + if (!(new_cs & ~3)) { + pclog("TS loading null CS\n"); + x86ts(NULL, 0); + return; + } + addr = new_cs & ~7; + if (new_cs & 4) { + if (addr >= ldt.limit) { + pclog("Bigger than LDT limit %04X %04X %04X TS\n", new_cs, ldt.limit, addr); + x86ts(NULL, new_cs & ~3); + return; + } + addr += ldt.base; + } else { + if (addr >= gdt.limit) { + pclog("Bigger than GDT limit %04X %04X TS\n", new_cs, 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)) { + pclog("TS loading CS not present\n"); + 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) { + pclog("TS load CS non-conforming RPL != DPL"); + x86ts(NULL, new_cs & ~3); + return; + } + break; + case 0x1C00: + case 0x1D00: + case 0x1E00: + case 0x1F00: /*Conforming*/ + if ((new_cs & 3) < DPL2) { + pclog("TS load CS non-conforming RPL < DPL"); + x86ts(NULL, new_cs & ~3); + return; + } + break; + default: + pclog("TS load CS not code segment\n"); + x86ts(NULL, new_cs & ~3); + return; + } + // if (output) pclog("new_cs %04X\n",new_cs); + CS = new_cs; + do_seg_load(&cpu_state.seg_cs, segdat2); + if (CPL == 3 && oldcpl != 3) + flushmmucache_cr3(); + oldcpl = CPL; + set_use32(0); - if (!(new_cs & ~3)) { - pclog("TS loading null CS\n"); - x86ts(NULL, 0); - return; - } - addr = new_cs & ~7; - if (new_cs & 4) { - if (addr >= ldt.limit) { - pclog("Bigger than LDT limit %04X %04X %04X TS\n", new_cs, ldt.limit, addr); - x86ts(NULL, new_cs & ~3); - return; - } - addr += ldt.base; - } else { - if (addr >= gdt.limit) { - pclog("Bigger than GDT limit %04X %04X TS\n", new_cs, 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)) { - pclog("TS loading CS not present\n"); - 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) { - pclog("TS load CS non-conforming RPL != DPL"); - x86ts(NULL, new_cs & ~3); - return; - } - break; - case 0x1C00: - case 0x1D00: - case 0x1E00: - case 0x1F00: /*Conforming*/ - if ((new_cs & 3) < DPL2) { - pclog("TS load CS non-conforming RPL < DPL"); - x86ts(NULL, new_cs & ~3); - return; - } - break; - default:pclog("TS load CS not code segment\n"); - x86ts(NULL, new_cs & ~3); - return; - } + 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; -// if (output) pclog("new_cs %04X\n",new_cs); - CS = new_cs; - do_seg_load(&cpu_state.seg_cs, segdat2); - if (CPL == 3 && oldcpl != 3) - flushmmucache_cr3(); - oldcpl = CPL; - set_use32(0); + if (output) + pclog("Load ES %04X\n", new_es); + loadseg(new_es, &cpu_state.seg_es); + if (output) + pclog("Load SS %04X\n", new_ss); + loadseg(new_ss, &cpu_state.seg_ss); + if (output) + pclog("Load DS %04X\n", new_ds); + loadseg(new_ds, &cpu_state.seg_ds); + if (is386) { + loadseg(0, &cpu_state.seg_fs); + loadseg(0, &cpu_state.seg_gs); + } - 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; + if (output) + pclog("Resuming at %04X:%08X\n", CS, cpu_state.pc); + // exit(-1); + } - if (output) - pclog("Load ES %04X\n", new_es); - loadseg(new_es, &cpu_state.seg_es); - if (output) - pclog("Load SS %04X\n", new_ss); - loadseg(new_ss, &cpu_state.seg_ss); - if (output) - pclog("Load DS %04X\n", new_ds); - loadseg(new_ds, &cpu_state.seg_ds); - if (is386) { - loadseg(0, &cpu_state.seg_fs); - loadseg(0, &cpu_state.seg_gs); - } - - if (output) - pclog("Resuming at %04X:%08X\n", CS, cpu_state.pc); - //exit(-1); - } - - tr.seg = seg; - tr.base = base; - tr.limit = limit; - tr.access = segdat[2] >> 8; + tr.seg = seg; + tr.base = base; + tr.limit = limit; + tr.access = segdat[2] >> 8; } void sysenter(void) { - cpu_state.eflags &= ~VM_FLAG; - cpu_state.flags &= ~I_FLAG; + cpu_state.eflags &= ~VM_FLAG; + cpu_state.flags &= ~I_FLAG; - ESP = sysenter_esp; - cpu_state.pc = sysenter_eip; + ESP = sysenter_esp; + cpu_state.pc = sysenter_eip; - cpu_state.seg_cs.seg = sysenter_cs & 0xfffc; - cpu_state.seg_cs.base = 0; - cpu_state.seg_cs.limit_low = 0; - cpu_state.seg_cs.limit = 0xffffffff; - cpu_state.seg_cs.limit_high = 0xffffffff; - cpu_state.seg_cs.access = 0x1b; - cpu_state.seg_cs.checked = 1; - oldcpl = 0; + cpu_state.seg_cs.seg = sysenter_cs & 0xfffc; + cpu_state.seg_cs.base = 0; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.limit = 0xffffffff; + cpu_state.seg_cs.limit_high = 0xffffffff; + cpu_state.seg_cs.access = 0x1b; + cpu_state.seg_cs.checked = 1; + oldcpl = 0; - cpu_state.seg_ss.seg = (sysenter_cs & 0xfffc) + 8; - cpu_state.seg_ss.base = 0; - cpu_state.seg_ss.limit_low = 0; - cpu_state.seg_ss.limit = 0xffffffff; - cpu_state.seg_ss.limit_high = 0xffffffff; - cpu_state.seg_ss.access = 0x13; - cpu_state.seg_ss.checked = 1; + cpu_state.seg_ss.seg = (sysenter_cs & 0xfffc) + 8; + cpu_state.seg_ss.base = 0; + cpu_state.seg_ss.limit_low = 0; + cpu_state.seg_ss.limit = 0xffffffff; + cpu_state.seg_ss.limit_high = 0xffffffff; + cpu_state.seg_ss.access = 0x13; + cpu_state.seg_ss.checked = 1; - cpu_cur_status &= ~(CPU_STATUS_NOTFLATSS | CPU_STATUS_V86); - cpu_cur_status |= (CPU_STATUS_USE32 | CPU_STATUS_STACK32 | CPU_STATUS_PMODE); - set_use32(1); - set_stack32(1); + cpu_cur_status &= ~(CPU_STATUS_NOTFLATSS | CPU_STATUS_V86); + cpu_cur_status |= (CPU_STATUS_USE32 | CPU_STATUS_STACK32 | CPU_STATUS_PMODE); + set_use32(1); + set_stack32(1); -// pclog("syscall to %04x:%08x %04x:%08x\n", CS, cpu_state.pc, SS, ESP); + // pclog("syscall to %04x:%08x %04x:%08x\n", CS, cpu_state.pc, SS, ESP); } void sysexit(void) { - ESP = ECX; - cpu_state.pc = EDX; + ESP = ECX; + cpu_state.pc = EDX; - cpu_state.seg_cs.seg = (sysenter_cs | 3) + 16; - cpu_state.seg_cs.base = 0; - cpu_state.seg_cs.limit_low = 0; - cpu_state.seg_cs.limit = 0xffffffff; - cpu_state.seg_cs.limit_high = 0xffffffff; - cpu_state.seg_cs.access = 0x7b; - cpu_state.seg_cs.checked = 1; - oldcpl = 3; + cpu_state.seg_cs.seg = (sysenter_cs | 3) + 16; + cpu_state.seg_cs.base = 0; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.limit = 0xffffffff; + cpu_state.seg_cs.limit_high = 0xffffffff; + cpu_state.seg_cs.access = 0x7b; + cpu_state.seg_cs.checked = 1; + oldcpl = 3; - cpu_state.seg_ss.seg = (sysenter_cs | 3) + 24; - cpu_state.seg_ss.base = 0; - cpu_state.seg_ss.limit_low = 0; - cpu_state.seg_ss.limit = 0xffffffff; - cpu_state.seg_ss.limit_high = 0xffffffff; - cpu_state.seg_ss.access = 0x73; - cpu_state.seg_ss.checked = 1; + cpu_state.seg_ss.seg = (sysenter_cs | 3) + 24; + cpu_state.seg_ss.base = 0; + cpu_state.seg_ss.limit_low = 0; + cpu_state.seg_ss.limit = 0xffffffff; + cpu_state.seg_ss.limit_high = 0xffffffff; + cpu_state.seg_ss.access = 0x73; + cpu_state.seg_ss.checked = 1; - cpu_cur_status &= ~(CPU_STATUS_NOTFLATSS | CPU_STATUS_V86); - cpu_cur_status |= (CPU_STATUS_USE32 | CPU_STATUS_STACK32 | CPU_STATUS_PMODE); - flushmmucache_cr3(); - set_use32(1); - set_stack32(1); + cpu_cur_status &= ~(CPU_STATUS_NOTFLATSS | CPU_STATUS_V86); + cpu_cur_status |= (CPU_STATUS_USE32 | CPU_STATUS_STACK32 | CPU_STATUS_PMODE); + flushmmucache_cr3(); + set_use32(1); + set_stack32(1); -// pclog("sysexit to %04x:%08x %04x:%08x\n", CS, cpu_state.pc, SS, ESP); + // pclog("sysexit to %04x:%08x %04x:%08x\n", CS, cpu_state.pc, SS, ESP); } -void x86_smi_trigger(void) { - cpu_state.smi_pending = 1; -} +void x86_smi_trigger(void) { cpu_state.smi_pending = 1; } static void smi_write_descriptor_cache(uint32_t addr, x86seg *seg) { - writememl(0, addr + 8, seg->seg | (seg->access << 16) | (seg->access2 << 24)); - writememl(0, addr + 4, seg->base); - writememl(0, addr, seg->limit); + writememl(0, addr + 8, seg->seg | (seg->access << 16) | (seg->access2 << 24)); + writememl(0, addr + 4, seg->base); + writememl(0, addr, seg->limit); } static void smi_load_descriptor_cache(uint32_t addr, x86seg *seg) { - uint32_t temp; + uint32_t temp; - temp = readmeml(0, addr + 8); - seg->base = readmeml(0, addr + 4); - seg->limit = readmeml(0, addr); - seg->seg = temp & 0xffff; - seg->access = temp >> 16; - seg->access2 = temp >> 24; - if ((seg->access & 0x18) != 0x10 || !(seg->access & (1 << 2))) /*expand-down*/ - { - seg->limit_high = seg->limit; - seg->limit_low = 0; - } else { - seg->limit_high = (seg->access2 & 0x40) ? 0xffffffff : 0xffff; - seg->limit_low = seg->limit + 1; - } + temp = readmeml(0, addr + 8); + seg->base = readmeml(0, addr + 4); + seg->limit = readmeml(0, addr); + seg->seg = temp & 0xffff; + seg->access = temp >> 16; + seg->access2 = temp >> 24; + if ((seg->access & 0x18) != 0x10 || !(seg->access & (1 << 2))) /*expand-down*/ + { + seg->limit_high = seg->limit; + seg->limit_low = 0; + } else { + seg->limit_high = (seg->access2 & 0x40) ? 0xffffffff : 0xffff; + seg->limit_low = seg->limit + 1; + } } static void smi_load_smi_selector(x86seg *seg) { - seg->seg = 0; - seg->base = 0; - seg->limit = 0xffffffff; - seg->limit_low = 0; - seg->limit_high = 0xffffffff; - seg->access = (3 << 5) | 2; - seg->access2 = 0; + seg->seg = 0; + seg->base = 0; + seg->limit = 0xffffffff; + seg->limit_low = 0; + seg->limit_high = 0xffffffff; + seg->access = (3 << 5) | 2; + seg->access2 = 0; } void cyrix_write_seg_descriptor(uint32_t addr, x86seg *seg) { - writememl(0, addr, (seg->limit_raw & 0xffff) | (seg->base << 16)); - writememl(0, addr + 4, ((seg->base >> 16) & 0xff) | - (seg->access << 8) | - (seg->limit_raw & 0xf0000) | - (seg->access2 << 16) | - (seg->base & 0xff000000)); + writememl(0, addr, (seg->limit_raw & 0xffff) | (seg->base << 16)); + writememl(0, addr + 4, + ((seg->base >> 16) & 0xff) | (seg->access << 8) | (seg->limit_raw & 0xf0000) | (seg->access2 << 16) | + (seg->base & 0xff000000)); } void cyrix_load_seg_descriptor(uint32_t addr, x86seg *seg) { - uint16_t segdat[4], selector; + uint16_t segdat[4], selector; - segdat[0] = readmemw(0, addr); - segdat[1] = readmemw(0, addr + 2); - segdat[2] = readmemw(0, addr + 4); - segdat[3] = readmemw(0, addr + 6); - selector = readmemw(0, addr + 8); + segdat[0] = readmemw(0, addr); + segdat[1] = readmemw(0, addr + 2); + segdat[2] = readmemw(0, addr + 4); + segdat[3] = readmemw(0, addr + 6); + selector = readmemw(0, addr + 8); - if (!cpu_state.abrt) { - do_seg_load(seg, segdat); - seg->seg = selector; - seg->checked = 0; - if (seg == &cpu_state.seg_ds) { - if (seg->base == 0 && seg->limit_low == 0 && seg->limit_high == 0xffffffff) - cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; - else - cpu_cur_status |= CPU_STATUS_NOTFLATDS; - codegen_flat_ds = 0; - } - if (seg == &cpu_state.seg_ss) { - if (seg->base == 0 && seg->limit_low == 0 && seg->limit_high == 0xffffffff) - cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; - else - cpu_cur_status |= CPU_STATUS_NOTFLATSS; - set_stack32((segdat[3] & 0x40) ? 1 : 0); - codegen_flat_ss = 0; - } - } + if (!cpu_state.abrt) { + do_seg_load(seg, segdat); + seg->seg = selector; + seg->checked = 0; + if (seg == &cpu_state.seg_ds) { + if (seg->base == 0 && seg->limit_low == 0 && seg->limit_high == 0xffffffff) + cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; + else + cpu_cur_status |= CPU_STATUS_NOTFLATDS; + codegen_flat_ds = 0; + } + if (seg == &cpu_state.seg_ss) { + if (seg->base == 0 && seg->limit_low == 0 && seg->limit_high == 0xffffffff) + cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; + else + cpu_cur_status |= CPU_STATUS_NOTFLATSS; + set_stack32((segdat[3] & 0x40) ? 1 : 0); + codegen_flat_ss = 0; + } + } } void x86_smi_enter(void) { - uint32_t old_cr0 = cr0; + uint32_t old_cr0 = cr0; - if (smram_enable) - smram_enable(); - flushmmucache(); + if (smram_enable) + smram_enable(); + flushmmucache(); - cpu_386_flags_rebuild(); - cpl_override = 1; - cr0 = 0; /*Disable MMU*/ + cpu_386_flags_rebuild(); + cpl_override = 1; + cr0 = 0; /*Disable MMU*/ - if (cpu_iscyrix) { - uint32_t base; + if (cpu_iscyrix) { + uint32_t base; - if (!(cyrix.smhr & SMHR_VALID)) - cyrix.smhr = (cyrix.arr[3].base + cyrix.arr[3].size) | SMHR_VALID; - base = cyrix.smhr & SMHR_ADDR_MASK; + if (!(cyrix.smhr & SMHR_VALID)) + cyrix.smhr = (cyrix.arr[3].base + cyrix.arr[3].size) | SMHR_VALID; + base = cyrix.smhr & SMHR_ADDR_MASK; - writememl(0, base - 4, dr[7]); - writememl(0, base - 8, cpu_state.flags | (cpu_state.eflags << 16)); - writememl(0, base - 0xc, old_cr0); - writememl(0, base - 0x10, cpu_state.oldpc); - writememl(0, base - 0x14, cpu_state.pc); - writememl(0, base - 0x18, CS | (CPL << 21)); - cyrix_write_seg_descriptor(base - 0x20, &cpu_state.seg_cs); - writememl(0, base - 0x24, 0); + writememl(0, base - 4, dr[7]); + writememl(0, base - 8, cpu_state.flags | (cpu_state.eflags << 16)); + writememl(0, base - 0xc, old_cr0); + writememl(0, base - 0x10, cpu_state.oldpc); + writememl(0, base - 0x14, cpu_state.pc); + writememl(0, base - 0x18, CS | (CPL << 21)); + cyrix_write_seg_descriptor(base - 0x20, &cpu_state.seg_cs); + writememl(0, base - 0x24, 0); - cpl_override = 0; + cpl_override = 0; - cpu_cur_status = CPU_STATUS_SMM; - cpu_state.flags = 2; - cpu_state.eflags = 0; - cpu_state.pc = 0; - cr0 &= ~((1 << 0) | (1 << 2) | (1 << 3) | (1 << 31)); - dr[7] = 0x400; - cpu_state.seg_cs.seg = cyrix.arr[3].base >> 4; /*Guess*/ - cpu_state.seg_cs.base = cyrix.arr[3].base; - cpu_state.seg_cs.limit = 0xffffffff; - cpu_state.seg_cs.limit_low = 0; - cpu_state.seg_cs.limit_high = 0xffffffff; - cpu_state.seg_cs.access = (0 << 5) | 2; + cpu_cur_status = CPU_STATUS_SMM; + cpu_state.flags = 2; + cpu_state.eflags = 0; + cpu_state.pc = 0; + cr0 &= ~((1 << 0) | (1 << 2) | (1 << 3) | (1 << 31)); + dr[7] = 0x400; + cpu_state.seg_cs.seg = cyrix.arr[3].base >> 4; /*Guess*/ + cpu_state.seg_cs.base = cyrix.arr[3].base; + cpu_state.seg_cs.limit = 0xffffffff; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.limit_high = 0xffffffff; + cpu_state.seg_cs.access = (0 << 5) | 2; - use32 = 0; - stack32 = 0; - } else { - writememl(0, cpu_state.smbase + 0x8000 + 0x7ffc, old_cr0); - writememl(0, cpu_state.smbase + 0x8000 + 0x7ff8, cr3); - writememl(0, cpu_state.smbase + 0x8000 + 0x7ff4, cpu_state.flags | (cpu_state.eflags << 16)); - writememl(0, cpu_state.smbase + 0x8000 + 0x7ff0, cpu_state.pc); - writememl(0, cpu_state.smbase + 0x8000 + 0x7fec, EDI); - writememl(0, cpu_state.smbase + 0x8000 + 0x7fe8, ESI); - writememl(0, cpu_state.smbase + 0x8000 + 0x7fe4, EBP); - writememl(0, cpu_state.smbase + 0x8000 + 0x7fe0, ESP); - writememl(0, cpu_state.smbase + 0x8000 + 0x7fdc, EBX); - writememl(0, cpu_state.smbase + 0x8000 + 0x7fd8, EDX); - writememl(0, cpu_state.smbase + 0x8000 + 0x7fd4, ECX); - writememl(0, cpu_state.smbase + 0x8000 + 0x7fd0, EAX); - writememl(0, cpu_state.smbase + 0x8000 + 0x7fcc, dr[6]); - writememl(0, cpu_state.smbase + 0x8000 + 0x7fc8, dr[7]); - writememl(0, cpu_state.smbase + 0x8000 + 0x7fc4, tr.seg); - writememl(0, cpu_state.smbase + 0x8000 + 0x7fc0, ldt.seg); - writememl(0, cpu_state.smbase + 0x8000 + 0x7fbc, cpu_state.seg_gs.seg); - writememl(0, cpu_state.smbase + 0x8000 + 0x7fb8, cpu_state.seg_fs.seg); - writememl(0, cpu_state.smbase + 0x8000 + 0x7fb4, cpu_state.seg_ds.seg); - writememl(0, cpu_state.smbase + 0x8000 + 0x7fb0, cpu_state.seg_ss.seg); - writememl(0, cpu_state.smbase + 0x8000 + 0x7fac, cpu_state.seg_cs.seg); - writememl(0, cpu_state.smbase + 0x8000 + 0x7fa8, cpu_state.seg_es.seg); - smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f9c, &tr); - smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f90, &idt); - smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f84, &gdt); - smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f78, &ldt); - smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f6c, &cpu_state.seg_gs); - smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f60, &cpu_state.seg_fs); - smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f54, &cpu_state.seg_ds); - smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f48, &cpu_state.seg_ss); - smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f3c, &cpu_state.seg_cs); - smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f30, &cpu_state.seg_es); - writememl(0, cpu_state.smbase + 0x8000 + 0x7f28, cr4); - writememl(0, cpu_state.smbase + 0x8000 + 0x7ef8, cpu_state.smbase); - writememl(0, cpu_state.smbase + 0x8000 + 0x7efc, 0x00020000); - cpl_override = 0; + use32 = 0; + stack32 = 0; + } else { + writememl(0, cpu_state.smbase + 0x8000 + 0x7ffc, old_cr0); + writememl(0, cpu_state.smbase + 0x8000 + 0x7ff8, cr3); + writememl(0, cpu_state.smbase + 0x8000 + 0x7ff4, cpu_state.flags | (cpu_state.eflags << 16)); + writememl(0, cpu_state.smbase + 0x8000 + 0x7ff0, cpu_state.pc); + writememl(0, cpu_state.smbase + 0x8000 + 0x7fec, EDI); + writememl(0, cpu_state.smbase + 0x8000 + 0x7fe8, ESI); + writememl(0, cpu_state.smbase + 0x8000 + 0x7fe4, EBP); + writememl(0, cpu_state.smbase + 0x8000 + 0x7fe0, ESP); + writememl(0, cpu_state.smbase + 0x8000 + 0x7fdc, EBX); + writememl(0, cpu_state.smbase + 0x8000 + 0x7fd8, EDX); + writememl(0, cpu_state.smbase + 0x8000 + 0x7fd4, ECX); + writememl(0, cpu_state.smbase + 0x8000 + 0x7fd0, EAX); + writememl(0, cpu_state.smbase + 0x8000 + 0x7fcc, dr[6]); + writememl(0, cpu_state.smbase + 0x8000 + 0x7fc8, dr[7]); + writememl(0, cpu_state.smbase + 0x8000 + 0x7fc4, tr.seg); + writememl(0, cpu_state.smbase + 0x8000 + 0x7fc0, ldt.seg); + writememl(0, cpu_state.smbase + 0x8000 + 0x7fbc, cpu_state.seg_gs.seg); + writememl(0, cpu_state.smbase + 0x8000 + 0x7fb8, cpu_state.seg_fs.seg); + writememl(0, cpu_state.smbase + 0x8000 + 0x7fb4, cpu_state.seg_ds.seg); + writememl(0, cpu_state.smbase + 0x8000 + 0x7fb0, cpu_state.seg_ss.seg); + writememl(0, cpu_state.smbase + 0x8000 + 0x7fac, cpu_state.seg_cs.seg); + writememl(0, cpu_state.smbase + 0x8000 + 0x7fa8, cpu_state.seg_es.seg); + smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f9c, &tr); + smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f90, &idt); + smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f84, &gdt); + smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f78, &ldt); + smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f6c, &cpu_state.seg_gs); + smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f60, &cpu_state.seg_fs); + smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f54, &cpu_state.seg_ds); + smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f48, &cpu_state.seg_ss); + smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f3c, &cpu_state.seg_cs); + smi_write_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f30, &cpu_state.seg_es); + writememl(0, cpu_state.smbase + 0x8000 + 0x7f28, cr4); + writememl(0, cpu_state.smbase + 0x8000 + 0x7ef8, cpu_state.smbase); + writememl(0, cpu_state.smbase + 0x8000 + 0x7efc, 0x00020000); + cpl_override = 0; - cpu_cur_status = CPU_STATUS_SMM; - cpu_state.flags = 2; - cpu_state.eflags = 0; - cpu_state.pc = 0x8000; - cr0 &= ~((1 << 0) | (1 << 2) | (1 << 3) | (1 << 31)); - dr[7] = 0x400; - smi_load_smi_selector(&cpu_state.seg_ds); - smi_load_smi_selector(&cpu_state.seg_es); - smi_load_smi_selector(&cpu_state.seg_fs); - smi_load_smi_selector(&cpu_state.seg_gs); - smi_load_smi_selector(&cpu_state.seg_ss); - cpu_state.seg_cs.seg = 0x3000; - cpu_state.seg_cs.base = cpu_state.smbase; - cpu_state.seg_cs.limit = 0xffffffff; - cpu_state.seg_cs.limit_low = 0; - cpu_state.seg_cs.limit_high = 0xffffffff; - cpu_state.seg_cs.access = (0 << 5) | 2; + cpu_cur_status = CPU_STATUS_SMM; + cpu_state.flags = 2; + cpu_state.eflags = 0; + cpu_state.pc = 0x8000; + cr0 &= ~((1 << 0) | (1 << 2) | (1 << 3) | (1 << 31)); + dr[7] = 0x400; + smi_load_smi_selector(&cpu_state.seg_ds); + smi_load_smi_selector(&cpu_state.seg_es); + smi_load_smi_selector(&cpu_state.seg_fs); + smi_load_smi_selector(&cpu_state.seg_gs); + smi_load_smi_selector(&cpu_state.seg_ss); + cpu_state.seg_cs.seg = 0x3000; + cpu_state.seg_cs.base = cpu_state.smbase; + cpu_state.seg_cs.limit = 0xffffffff; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.limit_high = 0xffffffff; + cpu_state.seg_cs.access = (0 << 5) | 2; - use32 = 0; - stack32 = 0; - } + use32 = 0; + stack32 = 0; + } - oldcpl = 0; + oldcpl = 0; -// pclog("x86_smi_enter\n"); + // pclog("x86_smi_enter\n"); } void x86_smi_leave(void) { - uint32_t temp; - uint32_t new_cr0; + uint32_t temp; + uint32_t new_cr0; - if (cpu_iscyrix) { - uint32_t base = cyrix.smhr & SMHR_ADDR_MASK; + if (cpu_iscyrix) { + uint32_t base = cyrix.smhr & SMHR_ADDR_MASK; - cpl_override = 1; - dr[7] = readmeml(0, base - 4); - temp = readmeml(0, base - 8); - cpu_state.flags = temp & 0xffff; - cpu_state.eflags = temp >> 16; - new_cr0 = readmeml(0, base - 0xc); - cpu_state.pc = readmeml(0, base - 0x14); - cyrix_load_seg_descriptor(base - 0x20, &cpu_state.seg_cs); - cpl_override = 0; + cpl_override = 1; + dr[7] = readmeml(0, base - 4); + temp = readmeml(0, base - 8); + cpu_state.flags = temp & 0xffff; + cpu_state.eflags = temp >> 16; + new_cr0 = readmeml(0, base - 0xc); + cpu_state.pc = readmeml(0, base - 0x14); + cyrix_load_seg_descriptor(base - 0x20, &cpu_state.seg_cs); + cpl_override = 0; - cr0 = new_cr0; - } else { - cpl_override = 1; - new_cr0 = readmeml(0, cpu_state.smbase + 0x8000 + 0x7ffc); - cr3 = readmeml(0, cpu_state.smbase + 0x8000 + 0x7ff8); - temp = readmeml(0, cpu_state.smbase + 0x8000 + 0x7ff4); - cpu_state.flags = temp & 0xffff; - cpu_state.eflags = temp >> 16; - cpu_state.pc = readmeml(0, cpu_state.smbase + 0x8000 + 0x7ff0); - EDI = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fec); - ESI = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fe8); - EBP = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fe4); - ESP = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fe0); - EBX = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fdc); - EDX = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fd8); - ECX = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fd4); - EAX = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fd0); - dr[6] = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fcc); - dr[7] = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fc8); - tr.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fc4); - ldt.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fc0); - cpu_state.seg_gs.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fbc); - cpu_state.seg_fs.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fb8); - cpu_state.seg_ds.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fb4); - cpu_state.seg_ss.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fb0); - cpu_state.seg_cs.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fac); - cpu_state.seg_es.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fa8); - smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f9c, &tr); - smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f90, &idt); - smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f84, &gdt); - smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f78, &ldt); - smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f6c, &cpu_state.seg_gs); - smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f60, &cpu_state.seg_fs); - smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f54, &cpu_state.seg_ds); - smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f48, &cpu_state.seg_ss); - smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f3c, &cpu_state.seg_cs); - smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f30, &cpu_state.seg_es); - cr4 = readmeml(0, cpu_state.smbase + 0x8000 + 0x7f28); - cpu_state.smbase = readmeml(0, cpu_state.smbase + 0x8000 + 0x7ef8); - cpl_override = 0; + cr0 = new_cr0; + } else { + cpl_override = 1; + new_cr0 = readmeml(0, cpu_state.smbase + 0x8000 + 0x7ffc); + cr3 = readmeml(0, cpu_state.smbase + 0x8000 + 0x7ff8); + temp = readmeml(0, cpu_state.smbase + 0x8000 + 0x7ff4); + cpu_state.flags = temp & 0xffff; + cpu_state.eflags = temp >> 16; + cpu_state.pc = readmeml(0, cpu_state.smbase + 0x8000 + 0x7ff0); + EDI = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fec); + ESI = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fe8); + EBP = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fe4); + ESP = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fe0); + EBX = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fdc); + EDX = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fd8); + ECX = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fd4); + EAX = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fd0); + dr[6] = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fcc); + dr[7] = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fc8); + tr.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fc4); + ldt.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fc0); + cpu_state.seg_gs.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fbc); + cpu_state.seg_fs.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fb8); + cpu_state.seg_ds.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fb4); + cpu_state.seg_ss.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fb0); + cpu_state.seg_cs.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fac); + cpu_state.seg_es.seg = readmeml(0, cpu_state.smbase + 0x8000 + 0x7fa8); + smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f9c, &tr); + smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f90, &idt); + smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f84, &gdt); + smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f78, &ldt); + smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f6c, &cpu_state.seg_gs); + smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f60, &cpu_state.seg_fs); + smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f54, &cpu_state.seg_ds); + smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f48, &cpu_state.seg_ss); + smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f3c, &cpu_state.seg_cs); + smi_load_descriptor_cache(cpu_state.smbase + 0x8000 + 0x7f30, &cpu_state.seg_es); + cr4 = readmeml(0, cpu_state.smbase + 0x8000 + 0x7f28); + cpu_state.smbase = readmeml(0, cpu_state.smbase + 0x8000 + 0x7ef8); + cpl_override = 0; - cr0 = new_cr0; - } + cr0 = new_cr0; + } - cpu_386_flags_extract(); - cpu_cur_status = 0; - use32 = stack32 = 0; - if (cr0 & 1) { - cpu_cur_status |= CPU_STATUS_PMODE; - if (cpu_state.eflags & VM_FLAG) - cpu_cur_status |= CPU_STATUS_V86; - else { - if (cpu_state.seg_cs.access2 & 0x40) { - cpu_cur_status |= CPU_STATUS_USE32; - use32 = 0x300; - } - if (cpu_state.seg_ss.access2 & 0x40) { - cpu_cur_status |= CPU_STATUS_STACK32; - stack32 = 1; - } - } - } - if (!(cpu_state.seg_ds.base == 0 && cpu_state.seg_ds.limit_low == 0 && cpu_state.seg_ds.limit_high == 0xffffffff)) - cpu_cur_status |= CPU_STATUS_NOTFLATDS; - if (!(cpu_state.seg_ss.base == 0 && cpu_state.seg_ss.limit_low == 0 && cpu_state.seg_ss.limit_high == 0xffffffff)) - cpu_cur_status |= CPU_STATUS_NOTFLATSS; + cpu_386_flags_extract(); + cpu_cur_status = 0; + use32 = stack32 = 0; + if (cr0 & 1) { + cpu_cur_status |= CPU_STATUS_PMODE; + if (cpu_state.eflags & VM_FLAG) + cpu_cur_status |= CPU_STATUS_V86; + else { + if (cpu_state.seg_cs.access2 & 0x40) { + cpu_cur_status |= CPU_STATUS_USE32; + use32 = 0x300; + } + if (cpu_state.seg_ss.access2 & 0x40) { + cpu_cur_status |= CPU_STATUS_STACK32; + stack32 = 1; + } + } + } + if (!(cpu_state.seg_ds.base == 0 && cpu_state.seg_ds.limit_low == 0 && cpu_state.seg_ds.limit_high == 0xffffffff)) + cpu_cur_status |= CPU_STATUS_NOTFLATDS; + if (!(cpu_state.seg_ss.base == 0 && cpu_state.seg_ss.limit_low == 0 && cpu_state.seg_ss.limit_high == 0xffffffff)) + cpu_cur_status |= CPU_STATUS_NOTFLATSS; - if (smram_disable) - smram_disable(); - flushmmucache(); + if (smram_disable) + smram_disable(); + flushmmucache(); - oldcpl = CPL; + oldcpl = CPL; -// pclog("x86_smi_leave\n"); + // pclog("x86_smi_leave\n"); } diff --git a/src/cpu/x87.c b/src/cpu/x87.c index 96421e6b..093e6cd2 100644 --- a/src/cpu/x87.c +++ b/src/cpu/x87.c @@ -1,12 +1,12 @@ -//Quake timedemo demo1 - 8.1FPS +// Quake timedemo demo1 - 8.1FPS -//11A00 - D_SCAlloc -//11C1C - D_CacheSurface +// 11A00 - D_SCAlloc +// 11C1C - D_CacheSurface -//36174 - SCR_CalcRefdef +// 36174 - SCR_CalcRefdef -//SCR_CalcRefdef -//Calls R_SetVrect and R_ViewChanged +// SCR_CalcRefdef +// Calls R_SetVrect and R_ViewChanged #define fplog 0 @@ -19,68 +19,76 @@ #include "x87.h" #include "386_common.h" -#define X87_TAG_VALID 0 -#define X87_TAG_ZERO 1 +#define X87_TAG_VALID 0 +#define X87_TAG_ZERO 1 #define X87_TAG_INVALID 2 -#define X87_TAG_EMPTY 3 +#define X87_TAG_EMPTY 3 uint16_t x87_gettag() { - uint16_t ret = 0; - int c; + uint16_t ret = 0; + int c; - for (c = 0; c < 8; c++) { - if (cpu_state.tag[c] == TAG_EMPTY) - ret |= X87_TAG_EMPTY << (c * 2); - else if (cpu_state.tag[c] & TAG_UINT64) - ret |= 2 << (c * 2); - else if (cpu_state.ST[c] == 0.0 && !cpu_state.ismmx) - ret |= X87_TAG_ZERO << (c * 2); - else - ret |= X87_TAG_VALID << (c * 2); - } + for (c = 0; c < 8; c++) { + if (cpu_state.tag[c] == TAG_EMPTY) + ret |= X87_TAG_EMPTY << (c * 2); + else if (cpu_state.tag[c] & TAG_UINT64) + ret |= 2 << (c * 2); + else if (cpu_state.ST[c] == 0.0 && !cpu_state.ismmx) + ret |= X87_TAG_ZERO << (c * 2); + else + ret |= X87_TAG_VALID << (c * 2); + } - return ret; + return ret; } void x87_settag(uint16_t new_tag) { - int c; + int c; - for (c = 0; c < 8; c++) { - int tag = (new_tag >> (c * 2)) & 3; + for (c = 0; c < 8; c++) { + int tag = (new_tag >> (c * 2)) & 3; - if (tag == X87_TAG_EMPTY) - cpu_state.tag[c] = TAG_EMPTY; - else if (tag == 2) - cpu_state.tag[c] = TAG_VALID | TAG_UINT64; - else - cpu_state.tag[c] = TAG_VALID; - } + if (tag == X87_TAG_EMPTY) + cpu_state.tag[c] = TAG_EMPTY; + else if (tag == 2) + cpu_state.tag[c] = TAG_VALID | TAG_UINT64; + else + cpu_state.tag[c] = TAG_VALID; + } } 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 & 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\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()); + 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 & 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\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()); - } + 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() { -} +void x87_reset() {} diff --git a/src/cpu/x87_timings.c b/src/cpu/x87_timings.c index 8e4e8bcb..8d7ad7d8 100644 --- a/src/cpu/x87_timings.c +++ b/src/cpu/x87_timings.c @@ -3,307 +3,295 @@ x87_timings_t x87_timings; -const x87_timings_t x87_timings_8087 = - { - .f2xm1 = (310 + 630) / 2, - .fabs = (10 + 17) / 2, - .fadd = (70 + 100) / 2, - .fadd_32 = (90 + 120) / 2, - .fadd_64 = (95 + 125) / 2, - .fbld = (290 + 310) / 2, - .fbstp = (520 + 540) / 2, - .fchs = (10 + 17) / 2, - .fclex = (2 + 8) / 2, - .fcom = (40 + 50) / 2, - .fcom_32 = (60 + 70) / 2, - .fcom_64 = (65 + 75) / 2, - .fcos = 0, /*387+*/ - .fincdecstp = (6 + 12) / 2, - .fdisi_eni = (6 + 12) / 2, - .fdiv = (193 + 203) / 2, - .fdiv_32 = (215 + 225) / 2, - .fdiv_64 = (220 + 230) / 2, - .ffree = (9 + 16) / 2, - .fadd_i16 = (102 + 137) / 2, - .fadd_i32 = (108 + 143) / 2, - .fcom_i16 = (72 + 86) / 2, - .fcom_i32 = (78 + 91) / 2, - .fdiv_i16 = (224 + 238) / 2, - .fdiv_i32 = (230 + 243) / 2, - .fild_16 = (46 + 54) / 2, - .fild_32 = (50 + 60) / 2, - .fild_64 = (60 + 68) / 2, - .fmul_i16 = (124 + 138) / 2, - .fmul_i32 = (130 + 144) / 2, - .finit = (2 + 8) / 2, - .fist_16 = (80 + 90) / 2, - .fist_32 = (82 + 92) / 2, - .fist_64 = (94 + 105) / 2, - .fld = (17 + 22) / 2, - .fld_32 = (38 + 56) / 2, - .fld_64 = (40 + 60) / 2, - .fld_80 = (53 + 65) / 2, - .fld_z1 = (11 + 21) / 2, - .fld_const = (15 + 24) / 2, - .fldcw = (7 + 14) / 2, - .fldenv = (35 + 45) / 2, - .fmul = (90 + 145) / 2, - .fmul_32 = (110 + 125) / 2, - .fmul_64 = (154 + 168) / 2, - .fnop = (10 + 16) / 2, - .fpatan = (250 + 800) / 2, - .fprem = (15 + 190) / 2, - .fprem1 = 0, /*387+*/ - .fptan = (30 + 540) / 2, - .frndint = (16 + 50) / 2, - .frstor = (197 + 207) / 2, - .fsave = (197 + 207) / 2, - .fscale = (32 + 38) / 2, - .fsetpm = 0, /*287+*/ - .fsin_cos = 0, /*387+*/ - .fsincos = 0, /*387+*/ - .fsqrt = (180 + 186) / 2, - .fst = (15 + 22) / 2, - .fst_32 = (84 + 90) / 2, - .fst_64 = (96 + 104) / 2, - .fst_80 = (52 + 58) / 2, - .fstcw_sw = (12 + 18) / 2, - .fstenv = (40 + 50) / 2, - .ftst = (38 + 48) / 2, - .fucom = 0, /*387+*/ - .fwait = 4, - .fxam = (12 + 23) / 2, - .fxch = (10 + 15) / 2, - .fxtract = (27 + 55) / 2, - .fyl2x = (900 + 1100) / 2, - .fyl2xp1 = (700 + 1000) / 2 - }; +const x87_timings_t x87_timings_8087 = {.f2xm1 = (310 + 630) / 2, + .fabs = (10 + 17) / 2, + .fadd = (70 + 100) / 2, + .fadd_32 = (90 + 120) / 2, + .fadd_64 = (95 + 125) / 2, + .fbld = (290 + 310) / 2, + .fbstp = (520 + 540) / 2, + .fchs = (10 + 17) / 2, + .fclex = (2 + 8) / 2, + .fcom = (40 + 50) / 2, + .fcom_32 = (60 + 70) / 2, + .fcom_64 = (65 + 75) / 2, + .fcos = 0, /*387+*/ + .fincdecstp = (6 + 12) / 2, + .fdisi_eni = (6 + 12) / 2, + .fdiv = (193 + 203) / 2, + .fdiv_32 = (215 + 225) / 2, + .fdiv_64 = (220 + 230) / 2, + .ffree = (9 + 16) / 2, + .fadd_i16 = (102 + 137) / 2, + .fadd_i32 = (108 + 143) / 2, + .fcom_i16 = (72 + 86) / 2, + .fcom_i32 = (78 + 91) / 2, + .fdiv_i16 = (224 + 238) / 2, + .fdiv_i32 = (230 + 243) / 2, + .fild_16 = (46 + 54) / 2, + .fild_32 = (50 + 60) / 2, + .fild_64 = (60 + 68) / 2, + .fmul_i16 = (124 + 138) / 2, + .fmul_i32 = (130 + 144) / 2, + .finit = (2 + 8) / 2, + .fist_16 = (80 + 90) / 2, + .fist_32 = (82 + 92) / 2, + .fist_64 = (94 + 105) / 2, + .fld = (17 + 22) / 2, + .fld_32 = (38 + 56) / 2, + .fld_64 = (40 + 60) / 2, + .fld_80 = (53 + 65) / 2, + .fld_z1 = (11 + 21) / 2, + .fld_const = (15 + 24) / 2, + .fldcw = (7 + 14) / 2, + .fldenv = (35 + 45) / 2, + .fmul = (90 + 145) / 2, + .fmul_32 = (110 + 125) / 2, + .fmul_64 = (154 + 168) / 2, + .fnop = (10 + 16) / 2, + .fpatan = (250 + 800) / 2, + .fprem = (15 + 190) / 2, + .fprem1 = 0, /*387+*/ + .fptan = (30 + 540) / 2, + .frndint = (16 + 50) / 2, + .frstor = (197 + 207) / 2, + .fsave = (197 + 207) / 2, + .fscale = (32 + 38) / 2, + .fsetpm = 0, /*287+*/ + .fsin_cos = 0, /*387+*/ + .fsincos = 0, /*387+*/ + .fsqrt = (180 + 186) / 2, + .fst = (15 + 22) / 2, + .fst_32 = (84 + 90) / 2, + .fst_64 = (96 + 104) / 2, + .fst_80 = (52 + 58) / 2, + .fstcw_sw = (12 + 18) / 2, + .fstenv = (40 + 50) / 2, + .ftst = (38 + 48) / 2, + .fucom = 0, /*387+*/ + .fwait = 4, + .fxam = (12 + 23) / 2, + .fxch = (10 + 15) / 2, + .fxtract = (27 + 55) / 2, + .fyl2x = (900 + 1100) / 2, + .fyl2xp1 = (700 + 1000) / 2}; /*Mostly the same as 8087*/ -const x87_timings_t x87_timings_287 = - { - .f2xm1 = (310 + 630) / 2, - .fabs = (10 + 17) / 2, - .fadd = (70 + 100) / 2, - .fadd_32 = (90 + 120) / 2, - .fadd_64 = (95 + 125) / 2, - .fbld = (290 + 310) / 2, - .fbstp = (520 + 540) / 2, - .fchs = (10 + 17) / 2, - .fclex = (2 + 8) / 2, - .fcom = (40 + 50) / 2, - .fcom_32 = (60 + 70) / 2, - .fcom_64 = (65 + 75) / 2, - .fcos = 0, /*387+*/ - .fincdecstp = (6 + 12) / 2, - .fdisi_eni = 2, - .fdiv = (193 + 203) / 2, - .fdiv_32 = (215 + 225) / 2, - .fdiv_64 = (220 + 230) / 2, - .ffree = (9 + 16) / 2, - .fadd_i16 = (102 + 137) / 2, - .fadd_i32 = (108 + 143) / 2, - .fcom_i16 = (72 + 86) / 2, - .fcom_i32 = (78 + 91) / 2, - .fdiv_i16 = (224 + 238) / 2, - .fdiv_i32 = (230 + 243) / 2, - .fild_16 = (46 + 54) / 2, - .fild_32 = (50 + 60) / 2, - .fild_64 = (60 + 68) / 2, - .fmul_i16 = (124 + 138) / 2, - .fmul_i32 = (130 + 144) / 2, - .finit = (2 + 8) / 2, - .fist_16 = (80 + 90) / 2, - .fist_32 = (82 + 92) / 2, - .fist_64 = (94 + 105) / 2, - .fld = (17 + 22) / 2, - .fld_32 = (38 + 56) / 2, - .fld_64 = (40 + 60) / 2, - .fld_80 = (53 + 65) / 2, - .fld_z1 = (11 + 21) / 2, - .fld_const = (15 + 24) / 2, - .fldcw = (7 + 14) / 2, - .fldenv = (35 + 45) / 2, - .fmul = (90 + 145) / 2, - .fmul_32 = (110 + 125) / 2, - .fmul_64 = (154 + 168) / 2, - .fnop = (10 + 16) / 2, - .fpatan = (250 + 800) / 2, - .fprem = (15 + 190) / 2, - .fprem1 = 0, /*387+*/ - .fptan = (30 + 540) / 2, - .frndint = (16 + 50) / 2, - .frstor = (197 + 207) / 2, - .fsave = (197 + 207) / 2, - .fscale = (32 + 38) / 2, - .fsetpm = (2 + 8) / 2, /*287+*/ - .fsin_cos = 0, /*387+*/ - .fsincos = 0, /*387+*/ - .fsqrt = (180 + 186) / 2, - .fst = (15 + 22) / 2, - .fst_32 = (84 + 90) / 2, - .fst_64 = (96 + 104) / 2, - .fst_80 = (52 + 58) / 2, - .fstcw_sw = (12 + 18) / 2, - .fstenv = (40 + 50) / 2, - .ftst = (38 + 48) / 2, - .fucom = 0, /*387+*/ - .fwait = 3, - .fxam = (12 + 23) / 2, - .fxch = (10 + 15) / 2, - .fxtract = (27 + 55) / 2, - .fyl2x = (900 + 1100) / 2, - .fyl2xp1 = (700 + 1000) / 2 - }; +const x87_timings_t x87_timings_287 = {.f2xm1 = (310 + 630) / 2, + .fabs = (10 + 17) / 2, + .fadd = (70 + 100) / 2, + .fadd_32 = (90 + 120) / 2, + .fadd_64 = (95 + 125) / 2, + .fbld = (290 + 310) / 2, + .fbstp = (520 + 540) / 2, + .fchs = (10 + 17) / 2, + .fclex = (2 + 8) / 2, + .fcom = (40 + 50) / 2, + .fcom_32 = (60 + 70) / 2, + .fcom_64 = (65 + 75) / 2, + .fcos = 0, /*387+*/ + .fincdecstp = (6 + 12) / 2, + .fdisi_eni = 2, + .fdiv = (193 + 203) / 2, + .fdiv_32 = (215 + 225) / 2, + .fdiv_64 = (220 + 230) / 2, + .ffree = (9 + 16) / 2, + .fadd_i16 = (102 + 137) / 2, + .fadd_i32 = (108 + 143) / 2, + .fcom_i16 = (72 + 86) / 2, + .fcom_i32 = (78 + 91) / 2, + .fdiv_i16 = (224 + 238) / 2, + .fdiv_i32 = (230 + 243) / 2, + .fild_16 = (46 + 54) / 2, + .fild_32 = (50 + 60) / 2, + .fild_64 = (60 + 68) / 2, + .fmul_i16 = (124 + 138) / 2, + .fmul_i32 = (130 + 144) / 2, + .finit = (2 + 8) / 2, + .fist_16 = (80 + 90) / 2, + .fist_32 = (82 + 92) / 2, + .fist_64 = (94 + 105) / 2, + .fld = (17 + 22) / 2, + .fld_32 = (38 + 56) / 2, + .fld_64 = (40 + 60) / 2, + .fld_80 = (53 + 65) / 2, + .fld_z1 = (11 + 21) / 2, + .fld_const = (15 + 24) / 2, + .fldcw = (7 + 14) / 2, + .fldenv = (35 + 45) / 2, + .fmul = (90 + 145) / 2, + .fmul_32 = (110 + 125) / 2, + .fmul_64 = (154 + 168) / 2, + .fnop = (10 + 16) / 2, + .fpatan = (250 + 800) / 2, + .fprem = (15 + 190) / 2, + .fprem1 = 0, /*387+*/ + .fptan = (30 + 540) / 2, + .frndint = (16 + 50) / 2, + .frstor = (197 + 207) / 2, + .fsave = (197 + 207) / 2, + .fscale = (32 + 38) / 2, + .fsetpm = (2 + 8) / 2, /*287+*/ + .fsin_cos = 0, /*387+*/ + .fsincos = 0, /*387+*/ + .fsqrt = (180 + 186) / 2, + .fst = (15 + 22) / 2, + .fst_32 = (84 + 90) / 2, + .fst_64 = (96 + 104) / 2, + .fst_80 = (52 + 58) / 2, + .fstcw_sw = (12 + 18) / 2, + .fstenv = (40 + 50) / 2, + .ftst = (38 + 48) / 2, + .fucom = 0, /*387+*/ + .fwait = 3, + .fxam = (12 + 23) / 2, + .fxch = (10 + 15) / 2, + .fxtract = (27 + 55) / 2, + .fyl2x = (900 + 1100) / 2, + .fyl2xp1 = (700 + 1000) / 2}; -const x87_timings_t x87_timings_387 = - { - .f2xm1 = (211 + 476) / 2, - .fabs = 22, - .fadd = (23 + 34) / 2, - .fadd_32 = (24 + 32) / 2, - .fadd_64 = (29 + 37) / 2, - .fbld = (266 + 275) / 2, - .fbstp = (512 + 534) / 2, - .fchs = (24 + 25) / 2, - .fclex = 11, - .fcom = 24, - .fcom_32 = 26, - .fcom_64 = 31, - .fcos = (122 + 772) / 2, - .fincdecstp = 22, - .fdisi_eni = 2, - .fdiv = (88 + 91) / 2, - .fdiv_32 = 89, - .fdiv_64 = 94, - .ffree = 18, - .fadd_i16 = (71 + 85) / 2, - .fadd_i32 = (57 + 72) / 2, - .fcom_i16 = (71 + 75) / 2, - .fcom_i32 = (56 + 63) / 2, - .fdiv_i16 = (136 + 140) / 2, - .fdiv_i32 = (120 + 127) / 2, - .fild_16 = (61 + 65) / 2, - .fild_32 = (45 + 52) / 2, - .fild_64 = (56 + 67) / 2, - .fmul_i16 = (76 + 87) / 2, - .fmul_i32 = (61 + 82) / 2, - .finit = 33, - .fist_16 = (82 + 95) / 2, - .fist_32 = (79 + 93) / 2, - .fist_64 = (80 + 97) / 2, - .fld = 14, - .fld_32 = 20, - .fld_64 = 25, - .fld_80 = 44, - .fld_z1 = (20 + 24) / 2, - .fld_const = 40, - .fldcw = 19, - .fldenv = 71, - .fmul = (29 + 57) / 2, - .fmul_32 = (27 + 35) / 2, - .fmul_64 = (32 + 57) / 2, - .fnop = 12, - .fpatan = (314 + 487) / 2, - .fprem = (74 + 155) / 2, - .fprem1 = (95 + 185) / 2, - .fptan = (191 + 497) / 2, - .frndint = (66 + 80) / 2, - .frstor = 308, - .fsave = 375, - .fscale = (67 + 86) / 2, - .fsetpm = 12, - .fsin_cos = (122 + 771) / 2, - .fsincos = (194 + 809) / 2, - .fsqrt = (122 + 129) / 2, - .fst = 11, - .fst_32 = 44, - .fst_64 = 45, - .fst_80 = 53, - .fstcw_sw = 15, - .fstenv = 103, - .ftst = 28, - .fucom = 24, - .fwait = 6, - .fxam = (30 + 38) / 2, - .fxch = 18, - .fxtract = (70 + 76) / 2, - .fyl2x = (120 + 538) / 2, - .fyl2xp1 = (257 + 547) / 2 - }; +const x87_timings_t x87_timings_387 = {.f2xm1 = (211 + 476) / 2, + .fabs = 22, + .fadd = (23 + 34) / 2, + .fadd_32 = (24 + 32) / 2, + .fadd_64 = (29 + 37) / 2, + .fbld = (266 + 275) / 2, + .fbstp = (512 + 534) / 2, + .fchs = (24 + 25) / 2, + .fclex = 11, + .fcom = 24, + .fcom_32 = 26, + .fcom_64 = 31, + .fcos = (122 + 772) / 2, + .fincdecstp = 22, + .fdisi_eni = 2, + .fdiv = (88 + 91) / 2, + .fdiv_32 = 89, + .fdiv_64 = 94, + .ffree = 18, + .fadd_i16 = (71 + 85) / 2, + .fadd_i32 = (57 + 72) / 2, + .fcom_i16 = (71 + 75) / 2, + .fcom_i32 = (56 + 63) / 2, + .fdiv_i16 = (136 + 140) / 2, + .fdiv_i32 = (120 + 127) / 2, + .fild_16 = (61 + 65) / 2, + .fild_32 = (45 + 52) / 2, + .fild_64 = (56 + 67) / 2, + .fmul_i16 = (76 + 87) / 2, + .fmul_i32 = (61 + 82) / 2, + .finit = 33, + .fist_16 = (82 + 95) / 2, + .fist_32 = (79 + 93) / 2, + .fist_64 = (80 + 97) / 2, + .fld = 14, + .fld_32 = 20, + .fld_64 = 25, + .fld_80 = 44, + .fld_z1 = (20 + 24) / 2, + .fld_const = 40, + .fldcw = 19, + .fldenv = 71, + .fmul = (29 + 57) / 2, + .fmul_32 = (27 + 35) / 2, + .fmul_64 = (32 + 57) / 2, + .fnop = 12, + .fpatan = (314 + 487) / 2, + .fprem = (74 + 155) / 2, + .fprem1 = (95 + 185) / 2, + .fptan = (191 + 497) / 2, + .frndint = (66 + 80) / 2, + .frstor = 308, + .fsave = 375, + .fscale = (67 + 86) / 2, + .fsetpm = 12, + .fsin_cos = (122 + 771) / 2, + .fsincos = (194 + 809) / 2, + .fsqrt = (122 + 129) / 2, + .fst = 11, + .fst_32 = 44, + .fst_64 = 45, + .fst_80 = 53, + .fstcw_sw = 15, + .fstenv = 103, + .ftst = 28, + .fucom = 24, + .fwait = 6, + .fxam = (30 + 38) / 2, + .fxch = 18, + .fxtract = (70 + 76) / 2, + .fyl2x = (120 + 538) / 2, + .fyl2xp1 = (257 + 547) / 2}; -const x87_timings_t x87_timings_486 = - { - .f2xm1 = (140 + 270) / 2, - .fabs = 3, - .fadd = (8 + 20) / 2, - .fadd_32 = (8 + 20) / 2, - .fadd_64 = (8 + 20) / 2, - .fbld = (70 + 103) / 2, - .fbstp = (172 + 176) / 2, - .fchs = 6, - .fclex = 7, - .fcom = 4, - .fcom_32 = 4, - .fcom_64 = 4, - .fcos = (257 + 354) / 2, - .fincdecstp = 3, - .fdisi_eni = 3, - .fdiv = 73, - .fdiv_32 = 73, - .fdiv_64 = 73, - .ffree = 3, - .fadd_i16 = (20 + 35) / 2, - .fadd_i32 = (19 + 32) / 2, - .fcom_i16 = (16 + 20) / 2, - .fcom_i32 = (15 + 17) / 2, - .fdiv_i16 = (85 + 89) / 2, - .fdiv_i32 = (84 + 86) / 2, - .fild_16 = (13 + 16) / 2, - .fild_32 = (9 + 12) / 2, - .fild_64 = (10 + 18) / 2, - .fmul_i16 = (23 + 27) / 2, - .fmul_i32 = (22 + 24) / 2, - .finit = 17, - .fist_16 = (29 + 34) / 2, - .fist_32 = (28 + 34) / 2, - .fist_64 = (29 + 34) / 2, - .fld = 4, - .fld_32 = 3, - .fld_64 = 3, - .fld_80 = 6, - .fld_z1 = 4, - .fld_const = 8, - .fldcw = 4, - .fldenv = 34, - .fmul = 16, - .fmul_32 = 11, - .fmul_64 = 14, - .fnop = 3, - .fpatan = (218 + 303) / 2, - .fprem = (70 + 138) / 2, - .fprem1 = (72 + 167) / 2, - .fptan = (200 + 273) / 2, - .frndint = (21 + 30) / 2, - .frstor = 120, - .fsave = 143, - .fscale = (30 + 32) / 2, - .fsetpm = 3, - .fsin_cos = (257 + 354) / 2, - .fsincos = (292 + 365) / 2, - .fsqrt = (83 + 87) / 2, - .fst = 3, - .fst_32 = 7, - .fst_64 = 8, - .fst_80 = 6, - .fstcw_sw = 3, - .fstenv = 56, - .ftst = 4, - .fucom = 4, - .fwait = (1 + 3) / 2, - .fxam = 8, - .fxch = 4, - .fxtract = (16 + 20) / 2, - .fyl2x = (196 + 329) / 2, - .fyl2xp1 = (171 + 326) / 2 - }; +const x87_timings_t x87_timings_486 = {.f2xm1 = (140 + 270) / 2, + .fabs = 3, + .fadd = (8 + 20) / 2, + .fadd_32 = (8 + 20) / 2, + .fadd_64 = (8 + 20) / 2, + .fbld = (70 + 103) / 2, + .fbstp = (172 + 176) / 2, + .fchs = 6, + .fclex = 7, + .fcom = 4, + .fcom_32 = 4, + .fcom_64 = 4, + .fcos = (257 + 354) / 2, + .fincdecstp = 3, + .fdisi_eni = 3, + .fdiv = 73, + .fdiv_32 = 73, + .fdiv_64 = 73, + .ffree = 3, + .fadd_i16 = (20 + 35) / 2, + .fadd_i32 = (19 + 32) / 2, + .fcom_i16 = (16 + 20) / 2, + .fcom_i32 = (15 + 17) / 2, + .fdiv_i16 = (85 + 89) / 2, + .fdiv_i32 = (84 + 86) / 2, + .fild_16 = (13 + 16) / 2, + .fild_32 = (9 + 12) / 2, + .fild_64 = (10 + 18) / 2, + .fmul_i16 = (23 + 27) / 2, + .fmul_i32 = (22 + 24) / 2, + .finit = 17, + .fist_16 = (29 + 34) / 2, + .fist_32 = (28 + 34) / 2, + .fist_64 = (29 + 34) / 2, + .fld = 4, + .fld_32 = 3, + .fld_64 = 3, + .fld_80 = 6, + .fld_z1 = 4, + .fld_const = 8, + .fldcw = 4, + .fldenv = 34, + .fmul = 16, + .fmul_32 = 11, + .fmul_64 = 14, + .fnop = 3, + .fpatan = (218 + 303) / 2, + .fprem = (70 + 138) / 2, + .fprem1 = (72 + 167) / 2, + .fptan = (200 + 273) / 2, + .frndint = (21 + 30) / 2, + .frstor = 120, + .fsave = 143, + .fscale = (30 + 32) / 2, + .fsetpm = 3, + .fsin_cos = (257 + 354) / 2, + .fsincos = (292 + 365) / 2, + .fsqrt = (83 + 87) / 2, + .fst = 3, + .fst_32 = 7, + .fst_64 = 8, + .fst_80 = 6, + .fstcw_sw = 3, + .fstenv = 56, + .ftst = 4, + .fucom = 4, + .fwait = (1 + 3) / 2, + .fxam = 8, + .fxch = 4, + .fxtract = (16 + 20) / 2, + .fyl2x = (196 + 329) / 2, + .fyl2xp1 = (171 + 326) / 2}; diff --git a/src/devices/cassette.c b/src/devices/cassette.c index 5d16b0e7..c201f8b2 100644 --- a/src/devices/cassette.c +++ b/src/devices/cassette.c @@ -30,9 +30,9 @@ char cassettefn[256]; typedef struct cassette_t { - uint8_t motor; /* Motor status */ - pzxfile_t pzx; - int cycles_last; /* Cycle count at last cassette poll */ + uint8_t motor; /* Motor status */ + pzxfile_t pzx; + int cycles_last; /* Cycle count at last cassette poll */ } cassette_t; @@ -41,121 +41,107 @@ extern device_t cassette_device; static cassette_t *st_cas; #define CAS_LOG(x) pclog x -// #define CAS_LOG(x) - +// #define CAS_LOG(x) /* The PCem CPU uses IBM cycles (4.77MHz). PZX uses Spectrum cycles (3.5MHz) * so scale accordingly. */ static int32_t pzx_cycles(int32_t pc) { - double d = pc; + double d = pc; - return (int32_t)(((d * 3.5) / 4.772728) + 0.5); + return (int32_t)(((d * 3.5) / 4.772728) + 0.5); } void cassette_eject(void) { - if (st_cas->pzx.input) { - pzx_close(&st_cas->pzx); - } - cassettefn[0] = 0; + if (st_cas->pzx.input) { + pzx_close(&st_cas->pzx); + } + cassettefn[0] = 0; } void cassette_load(const char *filename) { - FILE *fp; - unsigned char magic[8]; + FILE *fp; + unsigned char magic[8]; - if (!filename) - return; + if (!filename) + return; - fp = fopen(filename, "rb"); - if (!fp) { - /* Warn user? */ - CAS_LOG(("Failed to open cassette input %s\n", filename)); - return; - } - memset(magic, 0, sizeof(magic)); - fread(magic, 1, sizeof(magic), fp); + fp = fopen(filename, "rb"); + if (!fp) { + /* Warn user? */ + CAS_LOG(("Failed to open cassette input %s\n", filename)); + return; + } + memset(magic, 0, sizeof(magic)); + fread(magic, 1, sizeof(magic), fp); - /* Check for PZX signature. In due course support could be added for - * other formats like TZX */ - if (!memcmp(magic, "PZXT", 4)) { - const char *result; + /* Check for PZX signature. In due course support could be added for + * other formats like TZX */ + if (!memcmp(magic, "PZXT", 4)) { + const char *result; - result = pzx_open(&st_cas->pzx, fp); + result = pzx_open(&st_cas->pzx, fp); - if (result) { - CAS_LOG(("Failed to open %s as PZX: %s\n", - filename, result)); - fclose(fp); - return; - } - strcpy(cassettefn, filename); - } + if (result) { + CAS_LOG(("Failed to open %s as PZX: %s\n", filename, result)); + fclose(fp); + return; + } + strcpy(cassettefn, filename); + } } uint8_t cassette_input(void) { - int ticks; + int ticks; - /* While motor is off, result is loopback */ - if (!st_cas->motor) { - return ppispeakon; - } - /* If there is no tapefile open don't try to extract data */ - if (st_cas->pzx.input == NULL) - return 0; - /* Otherwise see how many ticks there have been since the last input */ - if (st_cas->cycles_last == -1) { - st_cas->cycles_last = cycles; - } - if (cycles <= st_cas->cycles_last) { - ticks = (st_cas->cycles_last - cycles); - } else { - ticks = (st_cas->cycles_last + (cpu_get_speed() / 100) - cycles); - } - st_cas->cycles_last = cycles; + /* While motor is off, result is loopback */ + if (!st_cas->motor) { + return ppispeakon; + } + /* If there is no tapefile open don't try to extract data */ + if (st_cas->pzx.input == NULL) + return 0; + /* Otherwise see how many ticks there have been since the last input */ + if (st_cas->cycles_last == -1) { + st_cas->cycles_last = cycles; + } + if (cycles <= st_cas->cycles_last) { + ticks = (st_cas->cycles_last - cycles); + } else { + ticks = (st_cas->cycles_last + (cpu_get_speed() / 100) - cycles); + } + st_cas->cycles_last = cycles; - return pzx_advance(&st_cas->pzx, pzx_cycles(ticks)); + return pzx_advance(&st_cas->pzx, pzx_cycles(ticks)); } void cassette_set_motor(uint8_t on) { - if (on && !st_cas->motor) { - CAS_LOG(("Start cassette motor\n")); - st_cas->cycles_last = -1; - } - if (st_cas->motor && !on) { - CAS_LOG(("Stop cassette motor\n")); - st_cas->cycles_last = -1; - } - st_cas->motor = on; + if (on && !st_cas->motor) { + CAS_LOG(("Start cassette motor\n")); + st_cas->cycles_last = -1; + } + if (st_cas->motor && !on) { + CAS_LOG(("Stop cassette motor\n")); + st_cas->cycles_last = -1; + } + st_cas->motor = on; } static void *cassette_init(void) { - cassette_t *cas = malloc(sizeof(cassette_t)); + cassette_t *cas = malloc(sizeof(cassette_t)); - memset(cas, 0, sizeof(cassette_t)); - pzx_init(&cas->pzx); + memset(cas, 0, sizeof(cassette_t)); + pzx_init(&cas->pzx); - st_cas = cas; - return cas; + st_cas = cas; + return cas; } static void cassette_close(void *p) { - cassette_t *cas = (cassette_t *)p; + cassette_t *cas = (cassette_t *)p; - pzx_close(&cas->pzx); + pzx_close(&cas->pzx); - free(cas); + free(cas); } -device_t cassette_device = - { - "Cassette", - 0, - cassette_init, - cassette_close, - NULL, - NULL, - NULL, - NULL, - NULL - }; - +device_t cassette_device = {"Cassette", 0, cassette_init, cassette_close, NULL, NULL, NULL, NULL, NULL}; diff --git a/src/devices/esdi_at.c b/src/devices/esdi_at.c index 7a43d724..d12c87d0 100644 --- a/src/devices/esdi_at.c +++ b/src/devices/esdi_at.c @@ -20,705 +20,713 @@ #include "esdi_at.h" -#define IDE_TIME (TIMER_USEC*10)//(5 * 100 * (1 << TIMER_SHIFT)) +#define IDE_TIME (TIMER_USEC * 10) //(5 * 100 * (1 << TIMER_SHIFT)) -#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 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 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 +#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 extern char ide_fn[7][512]; typedef struct esdi_drive_t { - int cfg_spt; - int cfg_hpc; - int current_cylinder; - hdd_file_t hdd_file; + int cfg_spt; + int cfg_hpc; + int current_cylinder; + hdd_file_t hdd_file; } esdi_drive_t; typedef struct esdi_t { - uint8_t status; - uint8_t error; - int secount, sector, cylinder, head, cylprecomp; - uint8_t command; - uint8_t fdisk; - int pos; + 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; + int drive_sel; + int reset; + uint16_t buffer[256]; + int irqstat; - pc_timer_t callback_timer; + pc_timer_t callback_timer; - esdi_drive_t drives[2]; + esdi_drive_t drives[2]; - rom_t bios_rom; + rom_t bios_rom; } esdi_t; uint16_t esdi_readw(uint16_t port, void *p); void esdi_writew(uint16_t port, uint16_t val, void *p); static inline void esdi_irq_raise(esdi_t *esdi) { -// pclog("IDE_IRQ_RAISE\n"); - if (!(esdi->fdisk & 2)) - picint(1 << 14); + // pclog("IDE_IRQ_RAISE\n"); + if (!(esdi->fdisk & 2)) + picint(1 << 14); - esdi->irqstat = 1; + esdi->irqstat = 1; } -static inline void esdi_irq_lower(esdi_t *esdi) { - picintc(1 << 14); -} +static inline void esdi_irq_lower(esdi_t *esdi) { picintc(1 << 14); } void esdi_irq_update(esdi_t *esdi) { - if (esdi->irqstat && !((pic2.pend | pic2.ins) & 0x40) && !(esdi->fdisk & 2)) - picint(1 << 14); + if (esdi->irqstat && !((pic2.pend | pic2.ins) & 0x40) && !(esdi->fdisk & 2)) + picint(1 << 14); } /* * Return the sector offset for the current register values */ int esdi_get_sector(esdi_t *esdi, off64_t *addr) { - esdi_drive_t *drive = &esdi->drives[esdi->drive_sel]; - int heads = drive->cfg_hpc; - int sectors = drive->cfg_spt; + esdi_drive_t *drive = &esdi->drives[esdi->drive_sel]; + int heads = drive->cfg_hpc; + int sectors = drive->cfg_spt; - if (esdi->head > heads) { - pclog("esdi_get_sector: past end of configured heads\n"); - return 1; - } - if (esdi->sector >= sectors + 1) { - pclog("esdi_get_sector: past end of configured sectors\n"); - return 1; - } + if (esdi->head > heads) { + pclog("esdi_get_sector: past end of configured heads\n"); + return 1; + } + if (esdi->sector >= sectors + 1) { + pclog("esdi_get_sector: past end of configured sectors\n"); + return 1; + } - if (drive->cfg_spt == drive->hdd_file.spt && drive->cfg_hpc == drive->hdd_file.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)*/ - int c, h, s; - *addr = ((((off64_t)esdi->cylinder * heads) + esdi->head) * - sectors) + (esdi->sector - 1); + if (drive->cfg_spt == drive->hdd_file.spt && drive->cfg_hpc == drive->hdd_file.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)*/ + int c, h, s; + *addr = ((((off64_t)esdi->cylinder * heads) + esdi->head) * sectors) + (esdi->sector - 1); - s = *addr % (drive->hdd_file.spt - 1); - h = (*addr / (drive->hdd_file.spt - 1)) % drive->hdd_file.hpc; - c = (*addr / (drive->hdd_file.spt - 1)) / drive->hdd_file.hpc; + s = *addr % (drive->hdd_file.spt - 1); + h = (*addr / (drive->hdd_file.spt - 1)) % drive->hdd_file.hpc; + c = (*addr / (drive->hdd_file.spt - 1)) / drive->hdd_file.hpc; - *addr = ((((off64_t)c * drive->hdd_file.hpc) + h) * - drive->hdd_file.spt) + s; - } + *addr = ((((off64_t)c * drive->hdd_file.hpc) + h) * drive->hdd_file.spt) + s; + } - return 0; + return 0; } /** * Move to the next sector using CHS addressing */ void esdi_next_sector(esdi_t *esdi) { - esdi_drive_t *drive = &esdi->drives[esdi->drive_sel]; + esdi_drive_t *drive = &esdi->drives[esdi->drive_sel]; - esdi->sector++; - if (esdi->sector == (drive->cfg_spt + 1)) { - esdi->sector = 1; - esdi->head++; - if (esdi->head == drive->cfg_hpc) { - esdi->head = 0; - esdi->cylinder++; - if (drive->current_cylinder < drive->hdd_file.tracks) - drive->current_cylinder++; - } - } + esdi->sector++; + if (esdi->sector == (drive->cfg_spt + 1)) { + esdi->sector = 1; + esdi->head++; + if (esdi->head == drive->cfg_hpc) { + esdi->head = 0; + esdi->cylinder++; + if (drive->current_cylinder < drive->hdd_file.tracks) + drive->current_cylinder++; + } + } } void esdi_write(uint16_t port, uint8_t val, void *p) { - esdi_t *esdi = (esdi_t *)p; + esdi_t *esdi = (esdi_t *)p; -// pclog("esdi_write: addr=%04x val=%02x\n", port, val); - switch (port) { - case 0x1F0: /* Data */ - esdi_writew(port, val | (val << 8), p); - return; + // pclog("esdi_write: addr=%04x val=%02x\n", port, val); + switch (port) { + case 0x1F0: /* Data */ + esdi_writew(port, val | (val << 8), p); + return; - case 0x1F1: /* Write precompenstation */ - esdi->cylprecomp = val; - return; + case 0x1F1: /* Write precompenstation */ + esdi->cylprecomp = val; + return; - case 0x1F2: /* Sector count */ - esdi->secount = val; - return; + case 0x1F2: /* Sector count */ + esdi->secount = val; + return; - case 0x1F3: /* Sector */ - esdi->sector = val; - return; + case 0x1F3: /* Sector */ + esdi->sector = val; + return; - case 0x1F4: /* Cylinder low */ - esdi->cylinder = (esdi->cylinder & 0xFF00) | 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 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].hdd_file.f == NULL) - esdi->status = 0; - else - esdi->status = STAT_READY | STAT_DSC; - return; + case 0x1F6: /* Drive/Head */ + esdi->head = val & 0xF; + esdi->drive_sel = (val & 0x10) ? 1 : 0; + if (esdi->drives[esdi->drive_sel].hdd_file.f == NULL) + esdi->status = 0; + else + esdi->status = STAT_READY | STAT_DSC; + return; - case 0x1F7: /* Command register */ -// if (esdi->drives[esdi->drive_sel].hdd_file.f == NULL && val != CMD_SET_PARAMETERS && val != CMD_NOP && val != 0xe0 && (val & ~3) != 0x20 && (val & ~3) != 0x30 && (val & ~3) != 0x40 && val != 0x90 && val != CMD_READ_PARAMETERS) -// fatal("Command %02x on non-present drive\n", val); + case 0x1F7: /* Command register */ + // if (esdi->drives[esdi->drive_sel].hdd_file.f == NULL && val != CMD_SET_PARAMETERS && val != + // CMD_NOP && val != 0xe0 && (val & ~3) != 0x20 && (val & ~3) != 0x30 && (val & ~3) != 0x40 && val + // != 0x90 && val != CMD_READ_PARAMETERS) + // fatal("Command %02x on non-present drive\n", val); - esdi_irq_lower(esdi); - esdi->command = val; - esdi->error = 0; + esdi_irq_lower(esdi); + esdi->command = val; + esdi->error = 0; - switch (val & 0xf0) { - case CMD_RESTORE: -// pclog("Restore\n"); - esdi->command &= ~0x0f; /*Mask off step rate*/ - esdi->status = STAT_BUSY; - timer_set_delay_u64(&esdi->callback_timer, 200 * IDE_TIME); - break; + switch (val & 0xf0) { + case CMD_RESTORE: + // pclog("Restore\n"); + esdi->command &= ~0x0f; /*Mask off step rate*/ + esdi->status = STAT_BUSY; + timer_set_delay_u64(&esdi->callback_timer, 200 * IDE_TIME); + break; - case CMD_SEEK: -// pclog("Seek to cylinder %i\n", esdi->cylinder); - esdi->command &= ~0x0f; /*Mask off step rate*/ - esdi->status = STAT_BUSY; - timer_set_delay_u64(&esdi->callback_timer, 200 * IDE_TIME); - break; + case CMD_SEEK: + // pclog("Seek to cylinder %i\n", esdi->cylinder); + esdi->command &= ~0x0f; /*Mask off step rate*/ + esdi->status = STAT_BUSY; + timer_set_delay_u64(&esdi->callback_timer, 200 * IDE_TIME); + break; - default: - switch (val) { - case CMD_NOP:esdi->status = STAT_BUSY; - timer_set_delay_u64(&esdi->callback_timer, 200 * IDE_TIME); - break; + default: + switch (val) { + case CMD_NOP: + esdi->status = STAT_BUSY; + timer_set_delay_u64(&esdi->callback_timer, 200 * IDE_TIME); + break; - case CMD_READ: - case CMD_READ + 1: - case CMD_READ + 2: - case CMD_READ + 3: -// pclog("Read %i sectors from sector %i cylinder %i head %i %i\n",esdi->secount,esdi->sector,esdi->cylinder,esdi->head,ins); - esdi->command &= ~3; - if (val & 2) - fatal("Read with ECC\n"); - case 0xa0:esdi->status = STAT_BUSY; - timer_set_delay_u64(&esdi->callback_timer, 200 * IDE_TIME); - break; + case CMD_READ: + case CMD_READ + 1: + case CMD_READ + 2: + case CMD_READ + 3: + // pclog("Read %i sectors from sector %i cylinder %i head %i + // %i\n",esdi->secount,esdi->sector,esdi->cylinder,esdi->head,ins); + esdi->command &= ~3; + if (val & 2) + fatal("Read with ECC\n"); + case 0xa0: + esdi->status = STAT_BUSY; + timer_set_delay_u64(&esdi->callback_timer, 200 * IDE_TIME); + break; - case CMD_WRITE: - case CMD_WRITE + 1: - case CMD_WRITE + 2: - case CMD_WRITE + 3: -// pclog("Write %i sectors to sector %i cylinder %i head %i\n",esdi->secount,esdi->sector,esdi->cylinder,esdi->head); - esdi->command &= ~3; - if (val & 2) - fatal("Write with ECC\n"); - esdi->status = STAT_DRQ | STAT_DSC;// | STAT_BUSY; - esdi->pos = 0; - break; + case CMD_WRITE: + case CMD_WRITE + 1: + case CMD_WRITE + 2: + case CMD_WRITE + 3: + // pclog("Write %i sectors to sector %i cylinder %i head + // %i\n",esdi->secount,esdi->sector,esdi->cylinder,esdi->head); + esdi->command &= ~3; + if (val & 2) + fatal("Write with ECC\n"); + esdi->status = STAT_DRQ | STAT_DSC; // | STAT_BUSY; + esdi->pos = 0; + break; - case CMD_VERIFY: - case CMD_VERIFY + 1: -// pclog("Read verify %i sectors from sector %i cylinder %i head %i\n",esdi->secount,esdi->sector,esdi->cylinder,esdi->head); - esdi->command &= ~1; - esdi->status = STAT_BUSY; - timer_set_delay_u64(&esdi->callback_timer, 200 * IDE_TIME); - break; + case CMD_VERIFY: + case CMD_VERIFY + 1: + // pclog("Read verify %i sectors from sector %i cylinder %i head + // %i\n",esdi->secount,esdi->sector,esdi->cylinder,esdi->head); + esdi->command &= ~1; + esdi->status = STAT_BUSY; + timer_set_delay_u64(&esdi->callback_timer, 200 * IDE_TIME); + break; - case CMD_FORMAT: -// pclog("Format track %i head %i\n", esdi->cylinder, esdi->head); - esdi->status = STAT_DRQ;// | STAT_BUSY; - esdi->pos = 0; - break; + case CMD_FORMAT: + // pclog("Format track %i head %i\n", esdi->cylinder, esdi->head); + esdi->status = STAT_DRQ; // | STAT_BUSY; + esdi->pos = 0; + break; - case CMD_SET_PARAMETERS: /* Initialize Drive Parameters */ - esdi->status = STAT_BUSY; - timer_set_delay_u64(&esdi->callback_timer, 30 * IDE_TIME); - break; + case CMD_SET_PARAMETERS: /* Initialize Drive Parameters */ + esdi->status = STAT_BUSY; + timer_set_delay_u64(&esdi->callback_timer, 30 * IDE_TIME); + break; - case CMD_DIAGNOSE: /* Execute Drive Diagnostics */ - esdi->status = STAT_BUSY; - timer_set_delay_u64(&esdi->callback_timer, 200 * IDE_TIME); - break; + case CMD_DIAGNOSE: /* Execute Drive Diagnostics */ + esdi->status = STAT_BUSY; + timer_set_delay_u64(&esdi->callback_timer, 200 * IDE_TIME); + break; - case 0xe0: /*???*/ - case CMD_READ_PARAMETERS:esdi->status = STAT_BUSY; - timer_set_delay_u64(&esdi->callback_timer, 200 * IDE_TIME); - break; + case 0xe0: /*???*/ + case CMD_READ_PARAMETERS: + esdi->status = STAT_BUSY; + timer_set_delay_u64(&esdi->callback_timer, 200 * IDE_TIME); + break; - default:pclog("Bad esdi command %02X\n", val); - case 0xe8: /*???*/ - esdi->status = STAT_BUSY; - timer_set_delay_u64(&esdi->callback_timer, 200 * IDE_TIME); - break; - } - } - break; + default: + pclog("Bad esdi command %02X\n", val); + case 0xe8: /*???*/ + esdi->status = STAT_BUSY; + timer_set_delay_u64(&esdi->callback_timer, 200 * IDE_TIME); + break; + } + } + break; - case 0x3F6: /* Device control */ - if ((esdi->fdisk & 4) && !(val & 4)) { - timer_set_delay_u64(&esdi->callback_timer, 500 * IDE_TIME); - esdi->reset = 1; - esdi->status = STAT_BUSY; -// pclog("esdi Reset\n"); - } - if (val & 4) { - /*Drive held in reset*/ - timer_disable(&esdi->callback_timer); - esdi->status = STAT_BUSY; - } - esdi->fdisk = val; - esdi_irq_update(esdi); - return; - } -// fatal("Bad ESDI write %04X %02X\n", port, val); + case 0x3F6: /* Device control */ + if ((esdi->fdisk & 4) && !(val & 4)) { + timer_set_delay_u64(&esdi->callback_timer, 500 * IDE_TIME); + esdi->reset = 1; + esdi->status = STAT_BUSY; + // pclog("esdi Reset\n"); + } + if (val & 4) { + /*Drive held in reset*/ + timer_disable(&esdi->callback_timer); + esdi->status = STAT_BUSY; + } + esdi->fdisk = val; + esdi_irq_update(esdi); + return; + } + // fatal("Bad ESDI write %04X %02X\n", port, val); } void esdi_writew(uint16_t port, uint16_t val, void *p) { - esdi_t *esdi = (esdi_t *)p; + esdi_t *esdi = (esdi_t *)p; -// pclog("Write ESDIw %04X\n",val); - esdi->buffer[esdi->pos >> 1] = val; - esdi->pos += 2; + // pclog("Write ESDIw %04X\n",val); + esdi->buffer[esdi->pos >> 1] = val; + esdi->pos += 2; - if (esdi->pos >= 512) { - esdi->pos = 0; - esdi->status = STAT_BUSY; - timer_set_delay_u64(&esdi->callback_timer, 6 * IDE_TIME); - } + if (esdi->pos >= 512) { + esdi->pos = 0; + esdi->status = STAT_BUSY; + timer_set_delay_u64(&esdi->callback_timer, 6 * IDE_TIME); + } } uint8_t esdi_read(uint16_t port, void *p) { - esdi_t *esdi = (esdi_t *)p; - uint8_t temp = 0xff; + esdi_t *esdi = (esdi_t *)p; + uint8_t temp = 0xff; - switch (port) { - case 0x1F0: /* Data */ - temp = esdi_readw(port, esdi) & 0xff; - break; + switch (port) { + case 0x1F0: /* Data */ + temp = esdi_readw(port, esdi) & 0xff; + break; - case 0x1F1: /* Error */ - temp = esdi->error; - break; + case 0x1F1: /* Error */ + temp = esdi->error; + break; - case 0x1F2: /* Sector count */ - temp = (uint8_t)esdi->secount; - break; + case 0x1F2: /* Sector count */ + temp = (uint8_t)esdi->secount; + break; - case 0x1F3: /* Sector */ - temp = (uint8_t)esdi->sector; - break; + case 0x1F3: /* Sector */ + temp = (uint8_t)esdi->sector; + break; - case 0x1F4: /* Cylinder low */ - temp = (uint8_t)(esdi->cylinder & 0xFF); - break; + case 0x1F4: /* Cylinder low */ + temp = (uint8_t)(esdi->cylinder & 0xFF); + break; - case 0x1F5: /* Cylinder high */ - temp = (uint8_t)(esdi->cylinder >> 8); - break; + case 0x1F5: /* Cylinder high */ + temp = (uint8_t)(esdi->cylinder >> 8); + break; - case 0x1F6: /* Drive/Head */ - temp = (uint8_t)(esdi->head | (esdi->drive_sel ? 0x10 : 0) | 0xa0); - break; + case 0x1F6: /* Drive/Head */ + temp = (uint8_t)(esdi->head | (esdi->drive_sel ? 0x10 : 0) | 0xa0); + break; - case 0x1F7: /* Status */ - esdi_irq_lower(esdi); - temp = esdi->status; - break; - } + case 0x1F7: /* Status */ + esdi_irq_lower(esdi); + temp = esdi->status; + break; + } -// if (port != 0x1f7) pclog("esdi_read: addr=%04x val=%02x %04X:%04x\n", port, temp, CS, cpu_state.pc); - return temp; + // if (port != 0x1f7) pclog("esdi_read: addr=%04x val=%02x %04X:%04x\n", port, temp, CS, cpu_state.pc); + return temp; } uint16_t esdi_readw(uint16_t port, void *p) { - esdi_t *esdi = (esdi_t *)p; - uint16_t temp; + esdi_t *esdi = (esdi_t *)p; + uint16_t temp; - temp = esdi->buffer[esdi->pos >> 1]; - esdi->pos += 2; + temp = esdi->buffer[esdi->pos >> 1]; + esdi->pos += 2; - if (esdi->pos >= 512) { -// pclog("Over! packlen %i %i\n",ide->packlen,ide->pos); - 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) { - esdi_next_sector(esdi); - esdi->status = STAT_BUSY; - timer_set_delay_u64(&esdi->callback_timer, 6 * IDE_TIME); - } - } - } + if (esdi->pos >= 512) { + // pclog("Over! packlen %i %i\n",ide->packlen,ide->pos); + 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) { + esdi_next_sector(esdi); + esdi->status = STAT_BUSY; + timer_set_delay_u64(&esdi->callback_timer, 6 * IDE_TIME); + } + } + } -// pclog("esdi_readw: temp=%04x %i\n", temp, esdi->pos); - return temp; + // pclog("esdi_readw: temp=%04x %i\n", temp, esdi->pos); + return temp; } void esdi_callback(void *p) { - esdi_t *esdi = (esdi_t *)p; - esdi_drive_t *drive = &esdi->drives[esdi->drive_sel]; - off64_t addr; + esdi_t *esdi = (esdi_t *)p; + esdi_drive_t *drive = &esdi->drives[esdi->drive_sel]; + off64_t addr; -// pclog("esdi_callback: command=%02x reset=%i\n", esdi->command, esdi->reset); + // pclog("esdi_callback: command=%02x reset=%i\n", esdi->command, esdi->reset); - 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; -// pclog("Reset callback\n"); - return; - } - switch (esdi->command) { - case CMD_RESTORE: - if (!drive->hdd_file.f) { - esdi->status = STAT_READY | STAT_ERR | STAT_DSC; - esdi->error = ERR_ABRT; - esdi_irq_raise(esdi); - } else { - drive->current_cylinder = 0; - esdi->status = STAT_READY | STAT_DSC; - esdi_irq_raise(esdi); - } - break; + 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; + // pclog("Reset callback\n"); + return; + } + switch (esdi->command) { + case CMD_RESTORE: + if (!drive->hdd_file.f) { + esdi->status = STAT_READY | STAT_ERR | STAT_DSC; + esdi->error = ERR_ABRT; + esdi_irq_raise(esdi); + } else { + drive->current_cylinder = 0; + esdi->status = STAT_READY | STAT_DSC; + esdi_irq_raise(esdi); + } + break; - case CMD_SEEK: - if (!drive->hdd_file.f) { - esdi->status = STAT_READY | STAT_ERR | STAT_DSC; - esdi->error = ERR_ABRT; - esdi_irq_raise(esdi); - } else { - esdi->status = STAT_READY | STAT_DSC; - esdi_irq_raise(esdi); - } - break; + case CMD_SEEK: + if (!drive->hdd_file.f) { + esdi->status = STAT_READY | STAT_ERR | STAT_DSC; + esdi->error = ERR_ABRT; + esdi_irq_raise(esdi); + } else { + esdi->status = STAT_READY | STAT_DSC; + esdi_irq_raise(esdi); + } + break; - case CMD_READ: - if (!drive->hdd_file.f) { - esdi->status = STAT_READY | STAT_ERR | STAT_DSC; - esdi->error = ERR_ABRT; - esdi_irq_raise(esdi); - } else { - if (esdi_get_sector(esdi, &addr)) { - esdi->error = ERR_ID_NOT_FOUND; - esdi->status = STAT_READY | STAT_DSC | STAT_ERR; - esdi_irq_raise(esdi); - break; - } - if (hdd_read_sectors(&drive->hdd_file, addr, 1, esdi->buffer)) { - esdi->error = ERR_ID_NOT_FOUND; - esdi->status = STAT_READY | STAT_DSC | STAT_ERR; - esdi_irq_raise(esdi); - break; - } - esdi->pos = 0; - esdi->status = STAT_DRQ | STAT_READY | STAT_DSC; -// pclog("Read sector callback %i %i %i offset %08X %i left %i %02X\n",ide.sector,ide.cylinder,ide.head,addr,ide.secount,ide.spt,ide.atastat[ide.board]); -// if (addr) output=3; - esdi_irq_raise(esdi); - readflash_set(READFLASH_HDC, esdi->drive_sel); - } - break; + case CMD_READ: + if (!drive->hdd_file.f) { + esdi->status = STAT_READY | STAT_ERR | STAT_DSC; + esdi->error = ERR_ABRT; + esdi_irq_raise(esdi); + } else { + if (esdi_get_sector(esdi, &addr)) { + esdi->error = ERR_ID_NOT_FOUND; + esdi->status = STAT_READY | STAT_DSC | STAT_ERR; + esdi_irq_raise(esdi); + break; + } + if (hdd_read_sectors(&drive->hdd_file, addr, 1, esdi->buffer)) { + esdi->error = ERR_ID_NOT_FOUND; + esdi->status = STAT_READY | STAT_DSC | STAT_ERR; + esdi_irq_raise(esdi); + break; + } + esdi->pos = 0; + esdi->status = STAT_DRQ | STAT_READY | STAT_DSC; + // pclog("Read sector callback %i %i %i offset %08X %i left %i + // %02X\n",ide.sector,ide.cylinder,ide.head,addr,ide.secount,ide.spt,ide.atastat[ide.board]); + // if (addr) output=3; + esdi_irq_raise(esdi); + readflash_set(READFLASH_HDC, esdi->drive_sel); + } + break; - case CMD_WRITE: - if (!drive->hdd_file.f) { - esdi->status = STAT_READY | STAT_ERR | STAT_DSC; - esdi->error = ERR_ABRT; - esdi_irq_raise(esdi); - } else { - if (esdi_get_sector(esdi, &addr)) { - esdi->error = ERR_ID_NOT_FOUND; - esdi->status = STAT_READY | STAT_DSC | STAT_ERR; - esdi_irq_raise(esdi); - break; - } - if (hdd_write_sectors(&drive->hdd_file, addr, 1, esdi->buffer)) { - esdi->error = ERR_ID_NOT_FOUND; - esdi->status = STAT_READY | STAT_DSC | STAT_ERR; - esdi_irq_raise(esdi); - break; - } - esdi_irq_raise(esdi); - esdi->secount = (esdi->secount - 1) & 0xff; - if (esdi->secount) { - esdi->status = STAT_DRQ | STAT_READY | STAT_DSC; - esdi->pos = 0; - esdi_next_sector(esdi); - } else - esdi->status = STAT_READY | STAT_DSC; - readflash_set(READFLASH_HDC, esdi->drive_sel); - } - break; + case CMD_WRITE: + if (!drive->hdd_file.f) { + esdi->status = STAT_READY | STAT_ERR | STAT_DSC; + esdi->error = ERR_ABRT; + esdi_irq_raise(esdi); + } else { + if (esdi_get_sector(esdi, &addr)) { + esdi->error = ERR_ID_NOT_FOUND; + esdi->status = STAT_READY | STAT_DSC | STAT_ERR; + esdi_irq_raise(esdi); + break; + } + if (hdd_write_sectors(&drive->hdd_file, addr, 1, esdi->buffer)) { + esdi->error = ERR_ID_NOT_FOUND; + esdi->status = STAT_READY | STAT_DSC | STAT_ERR; + esdi_irq_raise(esdi); + break; + } + esdi_irq_raise(esdi); + esdi->secount = (esdi->secount - 1) & 0xff; + if (esdi->secount) { + esdi->status = STAT_DRQ | STAT_READY | STAT_DSC; + esdi->pos = 0; + esdi_next_sector(esdi); + } else + esdi->status = STAT_READY | STAT_DSC; + readflash_set(READFLASH_HDC, esdi->drive_sel); + } + break; - case CMD_VERIFY: - if (!drive->hdd_file.f) { - esdi->status = STAT_READY | STAT_ERR | STAT_DSC; - esdi->error = ERR_ABRT; - esdi_irq_raise(esdi); - } else { - if (esdi_get_sector(esdi, &addr)) { - esdi->error = ERR_ID_NOT_FOUND; - esdi->status = STAT_READY | STAT_DSC | STAT_ERR; - esdi_irq_raise(esdi); - break; - } - if (hdd_read_sectors(&drive->hdd_file, addr, 1, esdi->buffer)) { - esdi->error = ERR_ID_NOT_FOUND; - esdi->status = STAT_READY | STAT_DSC | STAT_ERR; - esdi_irq_raise(esdi); - break; - } - readflash_set(READFLASH_HDC, esdi->drive_sel); - esdi_next_sector(esdi); - esdi->secount = (esdi->secount - 1) & 0xff; - if (esdi->secount) - timer_set_delay_u64(&esdi->callback_timer, 6 * IDE_TIME); - else { - esdi->pos = 0; - esdi->status = STAT_READY | STAT_DSC; -// pclog("Read verify callback %i %i %i offset %08X %i left\n",ide.sector,ide.cylinder,ide.head,addr,ide.secount); - esdi_irq_raise(esdi); - } - } - break; + case CMD_VERIFY: + if (!drive->hdd_file.f) { + esdi->status = STAT_READY | STAT_ERR | STAT_DSC; + esdi->error = ERR_ABRT; + esdi_irq_raise(esdi); + } else { + if (esdi_get_sector(esdi, &addr)) { + esdi->error = ERR_ID_NOT_FOUND; + esdi->status = STAT_READY | STAT_DSC | STAT_ERR; + esdi_irq_raise(esdi); + break; + } + if (hdd_read_sectors(&drive->hdd_file, addr, 1, esdi->buffer)) { + esdi->error = ERR_ID_NOT_FOUND; + esdi->status = STAT_READY | STAT_DSC | STAT_ERR; + esdi_irq_raise(esdi); + break; + } + readflash_set(READFLASH_HDC, esdi->drive_sel); + esdi_next_sector(esdi); + esdi->secount = (esdi->secount - 1) & 0xff; + if (esdi->secount) + timer_set_delay_u64(&esdi->callback_timer, 6 * IDE_TIME); + else { + esdi->pos = 0; + esdi->status = STAT_READY | STAT_DSC; + // pclog("Read verify callback %i %i %i offset %08X %i + // left\n",ide.sector,ide.cylinder,ide.head,addr,ide.secount); + esdi_irq_raise(esdi); + } + } + break; - case CMD_FORMAT: - if (!drive->hdd_file.f) { - esdi->status = STAT_READY | STAT_ERR | STAT_DSC; - esdi->error = ERR_ABRT; - esdi_irq_raise(esdi); - } else { - if (esdi_get_sector(esdi, &addr)) { - esdi->error = ERR_ID_NOT_FOUND; - esdi->status = STAT_READY | STAT_DSC | STAT_ERR; - esdi_irq_raise(esdi); - break; - } - if (hdd_format_sectors(&drive->hdd_file, addr, esdi->secount)) { - esdi->error = ERR_ID_NOT_FOUND; - esdi->status = STAT_READY | STAT_DSC | STAT_ERR; - esdi_irq_raise(esdi); - break; - } - esdi->status = STAT_READY | STAT_DSC; - esdi_irq_raise(esdi); - readflash_set(READFLASH_HDC, esdi->drive_sel); - } - break; + case CMD_FORMAT: + if (!drive->hdd_file.f) { + esdi->status = STAT_READY | STAT_ERR | STAT_DSC; + esdi->error = ERR_ABRT; + esdi_irq_raise(esdi); + } else { + if (esdi_get_sector(esdi, &addr)) { + esdi->error = ERR_ID_NOT_FOUND; + esdi->status = STAT_READY | STAT_DSC | STAT_ERR; + esdi_irq_raise(esdi); + break; + } + if (hdd_format_sectors(&drive->hdd_file, addr, esdi->secount)) { + esdi->error = ERR_ID_NOT_FOUND; + esdi->status = STAT_READY | STAT_DSC | STAT_ERR; + esdi_irq_raise(esdi); + break; + } + esdi->status = STAT_READY | STAT_DSC; + esdi_irq_raise(esdi); + readflash_set(READFLASH_HDC, esdi->drive_sel); + } + break; - case CMD_DIAGNOSE: - if (!drive->hdd_file.f) { - esdi->status = STAT_READY | STAT_ERR | STAT_DSC; - esdi->error = ERR_ABRT; - esdi_irq_raise(esdi); - } else { - esdi->error = 1; /*No error detected*/ - esdi->status = STAT_READY | STAT_DSC; - esdi_irq_raise(esdi); - } - break; + case CMD_DIAGNOSE: + if (!drive->hdd_file.f) { + esdi->status = STAT_READY | STAT_ERR | STAT_DSC; + esdi->error = ERR_ABRT; + esdi_irq_raise(esdi); + } else { + esdi->error = 1; /*No error detected*/ + esdi->status = STAT_READY | STAT_DSC; + esdi_irq_raise(esdi); + } + break; - case CMD_SET_PARAMETERS: /* Initialize Drive Parameters */ - if (!drive->hdd_file.f) { - esdi->status = STAT_READY | STAT_ERR | STAT_DSC; - esdi->error = ERR_ABRT; - esdi_irq_raise(esdi); - } else { - drive->cfg_spt = esdi->secount; - drive->cfg_hpc = esdi->head + 1; - pclog("Parameters: spt=%i hpc=%i\n", drive->cfg_spt, drive->cfg_hpc); - if (!esdi->secount) - fatal("secount=0\n"); - esdi->status = STAT_READY | STAT_DSC; - esdi_irq_raise(esdi); - } - break; + case CMD_SET_PARAMETERS: /* Initialize Drive Parameters */ + if (!drive->hdd_file.f) { + esdi->status = STAT_READY | STAT_ERR | STAT_DSC; + esdi->error = ERR_ABRT; + esdi_irq_raise(esdi); + } else { + drive->cfg_spt = esdi->secount; + drive->cfg_hpc = esdi->head + 1; + pclog("Parameters: spt=%i hpc=%i\n", drive->cfg_spt, drive->cfg_hpc); + if (!esdi->secount) + fatal("secount=0\n"); + esdi->status = STAT_READY | STAT_DSC; + esdi_irq_raise(esdi); + } + break; - case CMD_NOP:esdi->status = STAT_READY | STAT_ERR | STAT_DSC; - esdi->error = ERR_ABRT; - esdi_irq_raise(esdi); - break; + case CMD_NOP: + esdi->status = STAT_READY | STAT_ERR | STAT_DSC; + esdi->error = ERR_ABRT; + esdi_irq_raise(esdi); + break; - case 0xe0: - if (!drive->hdd_file.f) { - esdi->status = STAT_READY | STAT_ERR | STAT_DSC; - esdi->error = ERR_ABRT; - esdi_irq_raise(esdi); - } else { - switch (esdi->cylinder >> 8) { - case 0x31:esdi->cylinder = drive->hdd_file.tracks; - break; - case 0x33:esdi->cylinder = drive->hdd_file.hpc; - break; - case 0x35:esdi->cylinder = 0x200; - break; - case 0x36:esdi->cylinder = drive->hdd_file.spt; - break; - default:pclog("EDSI Bad read config %02x\n", esdi->cylinder >> 8); - } - esdi->status = STAT_READY | STAT_DSC; - esdi_irq_raise(esdi); - } - break; + case 0xe0: + if (!drive->hdd_file.f) { + esdi->status = STAT_READY | STAT_ERR | STAT_DSC; + esdi->error = ERR_ABRT; + esdi_irq_raise(esdi); + } else { + switch (esdi->cylinder >> 8) { + case 0x31: + esdi->cylinder = drive->hdd_file.tracks; + break; + case 0x33: + esdi->cylinder = drive->hdd_file.hpc; + break; + case 0x35: + esdi->cylinder = 0x200; + break; + case 0x36: + esdi->cylinder = drive->hdd_file.spt; + break; + default: + pclog("EDSI Bad read config %02x\n", esdi->cylinder >> 8); + } + esdi->status = STAT_READY | STAT_DSC; + esdi_irq_raise(esdi); + } + break; - case 0xa0: - if (!drive->hdd_file.f) { - esdi->status = STAT_READY | STAT_ERR | STAT_DSC; - esdi->error = ERR_ABRT; - esdi_irq_raise(esdi); - } else { - memset(esdi->buffer, 0, 512); - memset(&esdi->buffer[3], 0xff, 512 - 6); - esdi->pos = 0; - esdi->status = STAT_DRQ | STAT_READY | STAT_DSC; -// pclog("Read sector callback %i %i %i offset %08X %i left %i %02X\n",ide.sector,ide.cylinder,ide.head,addr,ide.secount,ide.spt,ide.atastat[ide.board]); -// if (addr) output=3; - esdi_irq_raise(esdi); - } - break; + case 0xa0: + if (!drive->hdd_file.f) { + esdi->status = STAT_READY | STAT_ERR | STAT_DSC; + esdi->error = ERR_ABRT; + esdi_irq_raise(esdi); + } else { + memset(esdi->buffer, 0, 512); + memset(&esdi->buffer[3], 0xff, 512 - 6); + esdi->pos = 0; + esdi->status = STAT_DRQ | STAT_READY | STAT_DSC; + // pclog("Read sector callback %i %i %i offset %08X %i left %i + // %02X\n",ide.sector,ide.cylinder,ide.head,addr,ide.secount,ide.spt,ide.atastat[ide.board]); + // if (addr) output=3; + esdi_irq_raise(esdi); + } + break; - case CMD_READ_PARAMETERS: - if (!drive->hdd_file.f) { - esdi->status = STAT_READY | STAT_ERR | STAT_DSC; - esdi->error = ERR_ABRT; - esdi_irq_raise(esdi); - } else { - memset(esdi->buffer, 0, 512); + case CMD_READ_PARAMETERS: + if (!drive->hdd_file.f) { + esdi->status = STAT_READY | STAT_ERR | STAT_DSC; + esdi->error = ERR_ABRT; + esdi_irq_raise(esdi); + } else { + memset(esdi->buffer, 0, 512); - esdi->buffer[0] = 0x44; /* general configuration */ - esdi->buffer[1] = drive->hdd_file.tracks; /* number of non-removable cylinders */ - esdi->buffer[2] = 0; /* number of removable cylinders */ - esdi->buffer[3] = drive->hdd_file.hpc; /* number of heads */ - esdi->buffer[5] = esdi->buffer[4] * drive->hdd_file.spt; /* number of unformatted bytes/sector */ - esdi->buffer[4] = 600; /* number of unformatted bytes/track */ - esdi->buffer[6] = drive->hdd_file.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 */ -// char wdp_cnsn[20]; /* controller serial number */ - esdi->buffer[20] = 2; /* controller type */ - esdi->buffer[21] = 1; /* sector buffer size, in sectors */ - esdi->buffer[22] = 0; /* ecc bytes appended */ -// char wdp_rev[8]; /* firmware revision */ - //27 - 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; - esdi_irq_raise(esdi); - } - break; + esdi->buffer[0] = 0x44; /* general configuration */ + esdi->buffer[1] = drive->hdd_file.tracks; /* number of non-removable cylinders */ + esdi->buffer[2] = 0; /* number of removable cylinders */ + esdi->buffer[3] = drive->hdd_file.hpc; /* number of heads */ + esdi->buffer[5] = esdi->buffer[4] * drive->hdd_file.spt; /* number of unformatted bytes/sector */ + esdi->buffer[4] = 600; /* number of unformatted bytes/track */ + esdi->buffer[6] = drive->hdd_file.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 */ + // char wdp_cnsn[20]; /* controller serial number */ + esdi->buffer[20] = 2; /* controller type */ + esdi->buffer[21] = 1; /* sector buffer size, in sectors */ + esdi->buffer[22] = 0; /* ecc bytes appended */ + // char wdp_rev[8]; /* firmware revision */ + // 27 + 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; + esdi_irq_raise(esdi); + } + break; - default:pclog("ESDI Callback on unknown command %02x\n", esdi->command); - case 0xe8: esdi->status = STAT_READY | STAT_ERR | STAT_DSC; - esdi->error = ERR_ABRT; - esdi_irq_raise(esdi); - break; - } + default: + pclog("ESDI Callback on unknown command %02x\n", esdi->command); + case 0xe8: + esdi->status = STAT_READY | STAT_ERR | STAT_DSC; + esdi->error = ERR_ABRT; + esdi_irq_raise(esdi); + break; + } } static void esdi_rom_write(uint32_t addr, uint8_t val, void *p) { - rom_t *rom = (rom_t *)p; + rom_t *rom = (rom_t *)p; - addr &= rom->mask; + addr &= rom->mask; - if (addr >= 0x1f00 && addr < 0x2000) - rom->rom[addr] = val; + if (addr >= 0x1f00 && addr < 0x2000) + rom->rom[addr] = val; } void *wd1007vse1_init() { - esdi_t *esdi = malloc(sizeof(esdi_t)); - memset(esdi, 0, sizeof(esdi_t)); + esdi_t *esdi = malloc(sizeof(esdi_t)); + memset(esdi, 0, sizeof(esdi_t)); - hdd_load(&esdi->drives[0].hdd_file, 0, ide_fn[0]); - hdd_load(&esdi->drives[1].hdd_file, 1, ide_fn[1]); + hdd_load(&esdi->drives[0].hdd_file, 0, ide_fn[0]); + hdd_load(&esdi->drives[1].hdd_file, 1, ide_fn[1]); - esdi->drives[0].cfg_spt = esdi->drives[0].hdd_file.spt; - esdi->drives[0].cfg_hpc = esdi->drives[0].hdd_file.hpc; - esdi->drives[1].cfg_spt = esdi->drives[1].hdd_file.spt; - esdi->drives[1].cfg_hpc = esdi->drives[1].hdd_file.hpc; + esdi->drives[0].cfg_spt = esdi->drives[0].hdd_file.spt; + esdi->drives[0].cfg_hpc = esdi->drives[0].hdd_file.hpc; + esdi->drives[1].cfg_spt = esdi->drives[1].hdd_file.spt; + esdi->drives[1].cfg_hpc = esdi->drives[1].hdd_file.hpc; - esdi->status = STAT_READY | STAT_DSC; - esdi->error = 1; /*No errors*/ + esdi->status = STAT_READY | STAT_DSC; + esdi->error = 1; /*No errors*/ - rom_init(&esdi->bios_rom, "62-000279-061.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&esdi->bios_rom, "62-000279-061.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); - mem_mapping_set_handler(&esdi->bios_rom.mapping, - rom_read, rom_readw, rom_readl, - esdi_rom_write, NULL, NULL); + mem_mapping_set_handler(&esdi->bios_rom.mapping, rom_read, rom_readw, rom_readl, esdi_rom_write, NULL, NULL); - io_sethandler(0x01f0, 0x0001, esdi_read, esdi_readw, NULL, esdi_write, esdi_writew, NULL, esdi); - io_sethandler(0x01f1, 0x0007, esdi_read, NULL, NULL, esdi_write, NULL, NULL, esdi); - io_sethandler(0x03f6, 0x0001, NULL, NULL, NULL, esdi_write, NULL, NULL, esdi); + io_sethandler(0x01f0, 0x0001, esdi_read, esdi_readw, NULL, esdi_write, esdi_writew, NULL, esdi); + io_sethandler(0x01f1, 0x0007, esdi_read, NULL, NULL, esdi_write, NULL, NULL, esdi); + io_sethandler(0x03f6, 0x0001, NULL, NULL, NULL, esdi_write, NULL, NULL, esdi); - timer_add(&esdi->callback_timer, esdi_callback, esdi, 0); + timer_add(&esdi->callback_timer, esdi_callback, esdi, 0); - return esdi; + return esdi; } void wd1007vse1_close(void *p) { - esdi_t *esdi = (esdi_t *)p; + esdi_t *esdi = (esdi_t *)p; - hdd_close(&esdi->drives[0].hdd_file); - hdd_close(&esdi->drives[1].hdd_file); + hdd_close(&esdi->drives[0].hdd_file); + hdd_close(&esdi->drives[1].hdd_file); - free(esdi); + free(esdi); } -static int wd1007vse1_available() { - return rom_present("62-000279-061.bin"); -} +static int wd1007vse1_available() { return rom_present("62-000279-061.bin"); } -device_t wd1007vse1_device = - { - "Western Digital WD1007V-SE1 (ESDI)", - DEVICE_AT, - wd1007vse1_init, - wd1007vse1_close, - wd1007vse1_available, - NULL, - NULL, - NULL, - NULL - }; +device_t wd1007vse1_device = {"Western Digital WD1007V-SE1 (ESDI)", + DEVICE_AT, + wd1007vse1_init, + wd1007vse1_close, + wd1007vse1_available, + NULL, + NULL, + NULL, + NULL}; diff --git a/src/devices/f82c710_upc.c b/src/devices/f82c710_upc.c index 58a27437..82f07ffe 100644 --- a/src/devices/f82c710_upc.c +++ b/src/devices/f82c710_upc.c @@ -40,37 +40,38 @@ #include "keyboard_at.h" #include "pic.h" -#define UPC_MOUSE_DEV_IDLE 0x01 /* bit 0, Device Idle */ -#define UPC_MOUSE_RX_FULL 0x02 /* bit 1, Device Char received */ -#define UPC_MOUSE_TX_IDLE 0x04 /* bit 2, Device XMIT Idle */ -#define UPC_MOUSE_RESET 0x08 /* bit 3, Device Reset */ -#define UPC_MOUSE_INTS_ON 0x10 /* bit 4, Device Interrupt On */ -#define UPC_MOUSE_ERROR_FLAG 0x20 /* bit 5, Device Error */ -#define UPC_MOUSE_CLEAR 0x40 /* bit 6, Device Clear */ -#define UPC_MOUSE_ENABLE 0x80 /* bit 7, Device Enable */ +#define UPC_MOUSE_DEV_IDLE 0x01 /* bit 0, Device Idle */ +#define UPC_MOUSE_RX_FULL 0x02 /* bit 1, Device Char received */ +#define UPC_MOUSE_TX_IDLE 0x04 /* bit 2, Device XMIT Idle */ +#define UPC_MOUSE_RESET 0x08 /* bit 3, Device Reset */ +#define UPC_MOUSE_INTS_ON 0x10 /* bit 4, Device Interrupt On */ +#define UPC_MOUSE_ERROR_FLAG 0x20 /* bit 5, Device Error */ +#define UPC_MOUSE_CLEAR 0x40 /* bit 6, Device Clear */ +#define UPC_MOUSE_ENABLE 0x80 /* bit 7, Device Enable */ typedef struct upc_t { - int configuration_state; // state of algorithm to enter configuration mode - int configuration_mode; - uint8_t next_value; // next expected value of configuration algorithm - uint16_t cri_addr; // cri = configuration index register, addr is even - uint16_t cap_addr; // cap = configuration access port, addr is odd and is cri_addr + 1 - uint8_t cri; // currently indexed register + int configuration_state; // state of algorithm to enter configuration mode + int configuration_mode; + uint8_t next_value; // next expected value of configuration algorithm + uint16_t cri_addr; // cri = configuration index register, addr is even + uint16_t cap_addr; // cap = configuration access port, addr is odd and is cri_addr + 1 + uint8_t cri; // currently indexed register - // these regs are not affected by reset - uint8_t regs[15]; // there are 16 indexes, but there is no need to store the last one which is: R = cri_addr / 4, W = exit config mode + // these regs are not affected by reset + uint8_t regs[15]; // there are 16 indexes, but there is no need to store the last one which is: R = cri_addr / 4, W = exit + // config mode - int serial_irq; - int parallel_irq; // TODO: currently not implemented in PCem + int serial_irq; + int parallel_irq; // TODO: currently not implemented in PCem - int mouse_irq; - uint16_t mdata_addr; // Address of PS/2 data register - uint16_t mstat_addr; // Address of PS/2 status register - uint8_t mouse_status; // Mouse interface status register - uint8_t mouse_data; // Mouse interface data register - void (*mouse_write)(uint8_t val, void *p); - void *mouse_p; - pc_timer_t mouse_delay_timer; + int mouse_irq; + uint16_t mdata_addr; // Address of PS/2 data register + uint16_t mstat_addr; // Address of PS/2 status register + uint8_t mouse_status; // Mouse interface status register + uint8_t mouse_data; // Mouse interface data register + void (*mouse_write)(uint8_t val, void *p); + void *mouse_p; + pc_timer_t mouse_delay_timer; } upc_t; static upc_t upc; @@ -85,385 +86,354 @@ void upc_mouse_write(uint16_t port, uint8_t val, void *priv); void upc_mouse_poll(void *priv); void upc_update_config(upc_t *upc) { - switch (upc->cri) { - case 0: - if (upc->regs[0] & 0x4) { - serial1_set(upc->regs[4] * 4, upc->serial_irq); - pclog("UPC: UART at %04X, irq %d\n", upc->regs[4] * 4, upc->serial_irq); - } else { - serial1_remove(); - pclog("UPC: UART disabled\n"); - } - if (upc->regs[0] & 0x8) { - lpt1_init(upc->regs[6] * 4); - pclog("UPC: PARALLEL at %04X, irq %d\n", upc->regs[6] * 4, upc->parallel_irq); - } else { - lpt1_remove(); - pclog("UPC: PARALLEL disabled\n"); - } - if ((upc->regs[0] & 0x60) != 0) - pclog("UPC: Oscillator control not implemented!\n"); - break; + switch (upc->cri) { + case 0: + if (upc->regs[0] & 0x4) { + serial1_set(upc->regs[4] * 4, upc->serial_irq); + pclog("UPC: UART at %04X, irq %d\n", upc->regs[4] * 4, upc->serial_irq); + } else { + serial1_remove(); + pclog("UPC: UART disabled\n"); + } + if (upc->regs[0] & 0x8) { + lpt1_init(upc->regs[6] * 4); + pclog("UPC: PARALLEL at %04X, irq %d\n", upc->regs[6] * 4, upc->parallel_irq); + } else { + lpt1_remove(); + pclog("UPC: PARALLEL disabled\n"); + } + if ((upc->regs[0] & 0x60) != 0) + pclog("UPC: Oscillator control not implemented!\n"); + break; - case 1: - if ((upc->regs[1] & 0x80) != 0) - pclog("UPC: Restricted serial reset not implemented!\n"); - if ((upc->regs[1] & 0x80) != 0) - pclog("UPC: Restricted serial reset not implemented!\n"); - if ((upc->regs[1] & 0x40) != 0) - pclog("UPC: Bidirectional parallel port support not implemented!\n"); - if ((upc->regs[1] & 0x38) != 0) - pclog("UPC: UART force CTS, DSR, DCD not implemented!\n"); - break; + case 1: + if ((upc->regs[1] & 0x80) != 0) + pclog("UPC: Restricted serial reset not implemented!\n"); + if ((upc->regs[1] & 0x80) != 0) + pclog("UPC: Restricted serial reset not implemented!\n"); + if ((upc->regs[1] & 0x40) != 0) + pclog("UPC: Bidirectional parallel port support not implemented!\n"); + if ((upc->regs[1] & 0x38) != 0) + pclog("UPC: UART force CTS, DSR, DCD not implemented!\n"); + break; - case 2: - if ((upc->regs[2] & 0x70) != 0) - pclog("UPC: UART clock control not implemented!\n"); - break; + case 2: + if ((upc->regs[2] & 0x70) != 0) + pclog("UPC: UART clock control not implemented!\n"); + break; - case 9: - if (upc->regs[9] == 0xb0) - pclog("UPC: GPCS not implemented! (at default address: %04X)\n", upc->regs[9] * 4); - else if (upc->regs[9] != 0) - pclog("UPC: GPCS not implemented! (at address: %04X)\n", upc->regs[9] * 4); - break; + case 9: + if (upc->regs[9] == 0xb0) + pclog("UPC: GPCS not implemented! (at default address: %04X)\n", upc->regs[9] * 4); + else if (upc->regs[9] != 0) + pclog("UPC: GPCS not implemented! (at address: %04X)\n", upc->regs[9] * 4); + break; - case 12: - /* Adding the IDE and floppy controllers when they are already present causes problems.*/ - /* FIX: remove floppy and IDE controllers before adding them again if needed. */ - fdc_remove(); - ide_pri_disable(); - if ((upc->regs[12] & 0x40) != 0) { - pclog("UPC: IDE XT mode not implemented!\n"); - } else { - if (upc->regs[12] & 0x80) { - ide_pri_enable(); - pclog("UPC: AT IDE enabled\n"); - } else { - pclog("UPC: AT IDE disabled\n"); - } - } + case 12: + /* Adding the IDE and floppy controllers when they are already present causes problems.*/ + /* FIX: remove floppy and IDE controllers before adding them again if needed. */ + fdc_remove(); + ide_pri_disable(); + if ((upc->regs[12] & 0x40) != 0) { + pclog("UPC: IDE XT mode not implemented!\n"); + } else { + if (upc->regs[12] & 0x80) { + ide_pri_enable(); + pclog("UPC: AT IDE enabled\n"); + } else { + pclog("UPC: AT IDE disabled\n"); + } + } - if (upc->regs[12] & 0x20) { - fdc_add(); - pclog("UPC: FDC enabled\n"); - } else { - pclog("UPC: FDC disabled\n"); - } + if (upc->regs[12] & 0x20) { + fdc_add(); + pclog("UPC: FDC enabled\n"); + } else { + pclog("UPC: FDC disabled\n"); + } - if ((upc->regs[12] & 0x10) != 0) - pclog("UPC: FDC power down mode not implemented!\n"); - if ((upc->regs[12] & 0x0C) != 0) - pclog("UPC: RTCCS not implemented!\n"); - if ((upc->regs[12] & 0x01) != 0) - pclog("UPC: PS/2 mouse port power down not implemented!\n"); - break; + if ((upc->regs[12] & 0x10) != 0) + pclog("UPC: FDC power down mode not implemented!\n"); + if ((upc->regs[12] & 0x0C) != 0) + pclog("UPC: RTCCS not implemented!\n"); + if ((upc->regs[12] & 0x01) != 0) + pclog("UPC: PS/2 mouse port power down not implemented!\n"); + break; - case 13: - if (upc->regs[13] != 0) { - upc->mdata_addr = upc->regs[13] * 4; - upc->mstat_addr = upc->mdata_addr + 1; - pclog("UPC: PS/2 mouse port at %04X, irq %d\n", upc->mdata_addr, upc->mouse_irq); - upc_mouse_enable(upc); - } else { - pclog("UPC: PS/2 mouse port disabled\n"); - upc_mouse_disable(upc); - } + case 13: + if (upc->regs[13] != 0) { + upc->mdata_addr = upc->regs[13] * 4; + upc->mstat_addr = upc->mdata_addr + 1; + pclog("UPC: PS/2 mouse port at %04X, irq %d\n", upc->mdata_addr, upc->mouse_irq); + upc_mouse_enable(upc); + } else { + pclog("UPC: PS/2 mouse port disabled\n"); + upc_mouse_disable(upc); + } - case 14: - if (upc->regs[14] != 0) - pclog("UPC: Test mode not implemented!\n"); - break; - } + case 14: + if (upc->regs[14] != 0) + pclog("UPC: Test mode not implemented!\n"); + break; + } } uint8_t upc_config_read(uint16_t port, void *priv) { - upc_t *upc = (upc_t *)priv; - uint8_t temp = 0xff; + upc_t *upc = (upc_t *)priv; + uint8_t temp = 0xff; - if (upc->configuration_mode) { - if (port == upc->cri_addr) { - temp = upc->cri; - } else if (port == upc->cap_addr) { - if (upc->cri == 0xf) - temp = upc->cri_addr / 4; - else - temp = upc->regs[upc->cri]; - } - } + if (upc->configuration_mode) { + if (port == upc->cri_addr) { + temp = upc->cri; + } else if (port == upc->cap_addr) { + if (upc->cri == 0xf) + temp = upc->cri_addr / 4; + else + temp = upc->regs[upc->cri]; + } + } -// pclog("UPC READ : %04X, %02X\n", port, temp); - return temp; + // pclog("UPC READ : %04X, %02X\n", port, temp); + return temp; } void upc_config_write(uint16_t port, uint8_t val, void *priv) { - upc_t *upc = (upc_t *)priv; - int configuration_state_event = 0; + upc_t *upc = (upc_t *)priv; + int configuration_state_event = 0; -// pclog("UPC WRITE: %04X, %02X\n", port, val); + // pclog("UPC WRITE: %04X, %02X\n", port, val); - switch (port) { - case 0x2fa: - /* Execute configuration step 1 for any value except 9, ff or 36 */ - if (upc->configuration_state == 0) { - configuration_state_event = 1; - /* next value should be the 1's complement of the current one */ - upc->next_value = 0xff - val; - } else if (upc->configuration_state == 4) { - uint8_t addr_verify = upc->cri_addr / 4; - addr_verify += val; - if (addr_verify == 0xff) { - upc->configuration_mode = 1; - // TODO: is the value of cri reset here or when exiting configuration mode? - io_sethandler(upc->cri_addr, 0x0002, upc_config_read, NULL, NULL, upc_config_write, NULL, NULL, upc); - pclog("UPC: in configuration mode at %04X\n", upc->cri_addr); - } else { - upc->configuration_mode = 0; - pclog("UPC: configuration mode failed (sum = %02X)\n", addr_verify); - } - } - break; - case 0x3fa: - /* go to configuration step 2 if value is the expected one */ - if (upc->configuration_state == 1 && val == upc->next_value) - configuration_state_event = 1; - else if (upc->configuration_state == 2 && val == 0x36) - configuration_state_event = 1; - else if (upc->configuration_state == 3) { - upc->cri_addr = val * 4; - upc->cap_addr = upc->cri_addr + 1; - configuration_state_event = 1; - } - break; - default:break; - } - if (upc->configuration_mode) { - if (port == upc->cri_addr) { - upc->cri = val & 0xf; + switch (port) { + case 0x2fa: + /* Execute configuration step 1 for any value except 9, ff or 36 */ + if (upc->configuration_state == 0) { + configuration_state_event = 1; + /* next value should be the 1's complement of the current one */ + upc->next_value = 0xff - val; + } else if (upc->configuration_state == 4) { + uint8_t addr_verify = upc->cri_addr / 4; + addr_verify += val; + if (addr_verify == 0xff) { + upc->configuration_mode = 1; + // TODO: is the value of cri reset here or when exiting configuration mode? + io_sethandler(upc->cri_addr, 0x0002, upc_config_read, NULL, NULL, upc_config_write, NULL, NULL, + upc); + pclog("UPC: in configuration mode at %04X\n", upc->cri_addr); + } else { + upc->configuration_mode = 0; + pclog("UPC: configuration mode failed (sum = %02X)\n", addr_verify); + } + } + break; + case 0x3fa: + /* go to configuration step 2 if value is the expected one */ + if (upc->configuration_state == 1 && val == upc->next_value) + configuration_state_event = 1; + else if (upc->configuration_state == 2 && val == 0x36) + configuration_state_event = 1; + else if (upc->configuration_state == 3) { + upc->cri_addr = val * 4; + upc->cap_addr = upc->cri_addr + 1; + configuration_state_event = 1; + } + break; + default: + break; + } + if (upc->configuration_mode) { + if (port == upc->cri_addr) { + upc->cri = val & 0xf; - } else if (port == upc->cap_addr) { - if (upc->cri == 0xf) { - pclog("UPC: exiting configuration mode\n"); - upc->configuration_mode = 0; - io_removehandler(upc->cri_addr, 0x0002, upc_config_read, NULL, NULL, upc_config_write, NULL, NULL, upc); - } else { - upc->regs[upc->cri] = val; - /* configuration should be updated at each register write, otherwise PC5086 do not detect ports correctly */ - upc_update_config(upc); - } - } - } + } else if (port == upc->cap_addr) { + if (upc->cri == 0xf) { + pclog("UPC: exiting configuration mode\n"); + upc->configuration_mode = 0; + io_removehandler(upc->cri_addr, 0x0002, upc_config_read, NULL, NULL, upc_config_write, NULL, NULL, + upc); + } else { + upc->regs[upc->cri] = val; + /* configuration should be updated at each register write, otherwise PC5086 do not detect ports + * correctly */ + upc_update_config(upc); + } + } + } - // TODO: is the state only reset when accessing 0x2fa and 0x3fa wrongly? - if ((port == 0x2fa || port == 0x3fa) && configuration_state_event) - upc->configuration_state++; - else - upc->configuration_state = 0; + // TODO: is the state only reset when accessing 0x2fa and 0x3fa wrongly? + if ((port == 0x2fa || port == 0x3fa) && configuration_state_event) + upc->configuration_state++; + else + upc->configuration_state = 0; } static void *upc_init() { - pclog("UPC INIT\n"); + pclog("UPC INIT\n"); - /* Disable all peripherals. upc_update_config will enable configured peripherals */ - serial1_remove(); - serial2_remove(); - lpt1_remove(); - lpt2_remove(); - fdc_remove(); - ide_pri_disable(); - ide_sec_disable(); - serial1_set_has_fifo(0); + /* Disable all peripherals. upc_update_config will enable configured peripherals */ + serial1_remove(); + serial2_remove(); + lpt1_remove(); + lpt2_remove(); + fdc_remove(); + ide_pri_disable(); + ide_sec_disable(); + serial1_set_has_fifo(0); - memset(&upc, 0, sizeof(upc)); + memset(&upc, 0, sizeof(upc)); - upc.serial_irq = device_get_config_int("serial_irq"); - upc.parallel_irq = device_get_config_int("parallel_irq"); + upc.serial_irq = device_get_config_int("serial_irq"); + upc.parallel_irq = device_get_config_int("parallel_irq"); - // because of these addresses, serial ports must be 16450 without fifos - io_sethandler(0x02fa, 0x0001, NULL, NULL, NULL, upc_config_write, NULL, NULL, &upc); - io_sethandler(0x03fa, 0x0001, NULL, NULL, NULL, upc_config_write, NULL, NULL, &upc); + // because of these addresses, serial ports must be 16450 without fifos + io_sethandler(0x02fa, 0x0001, NULL, NULL, NULL, upc_config_write, NULL, NULL, &upc); + io_sethandler(0x03fa, 0x0001, NULL, NULL, NULL, upc_config_write, NULL, NULL, &upc); - upc.regs[0] = 0x0c; - upc.regs[1] = 0x00; - upc.regs[2] = 0x00; - upc.regs[3] = 0x00; - upc.regs[4] = 0xfe; - upc.regs[5] = 0x00; - upc.regs[6] = 0x9e; - upc.regs[7] = 0x00; - upc.regs[8] = 0x00; - upc.regs[9] = 0xb0; - upc.regs[10] = 0x00; - upc.regs[11] = 0x00; - upc.regs[12] = 0xa0; - upc.regs[13] = 0x00; - upc.regs[14] = 0x00; + upc.regs[0] = 0x0c; + upc.regs[1] = 0x00; + upc.regs[2] = 0x00; + upc.regs[3] = 0x00; + upc.regs[4] = 0xfe; + upc.regs[5] = 0x00; + upc.regs[6] = 0x9e; + upc.regs[7] = 0x00; + upc.regs[8] = 0x00; + upc.regs[9] = 0xb0; + upc.regs[10] = 0x00; + upc.regs[11] = 0x00; + upc.regs[12] = 0xa0; + upc.regs[13] = 0x00; + upc.regs[14] = 0x00; - for (upc.cri = 0; upc.cri < 15; upc.cri++) - upc_update_config(&upc); - upc.cri = 0; + for (upc.cri = 0; upc.cri < 15; upc.cri++) + upc_update_config(&upc); + upc.cri = 0; - /********************* Initialize mouse interface ********************/ - if (romset == ROM_PC5086) /* IRQ is 2 for PC5086 and 12 for others */ - upc.mouse_irq = 2; - else - upc.mouse_irq = 12; - upc.mdata_addr = upc.regs[13] * 4; - upc.mstat_addr = upc.mdata_addr + 1; - upc.mouse_status = UPC_MOUSE_DEV_IDLE | UPC_MOUSE_TX_IDLE; - upc.mouse_data = 0xff; - /* Set timer for mouse polling */ - timer_add(&upc.mouse_delay_timer, upc_mouse_poll, &upc, 1); + /********************* Initialize mouse interface ********************/ + if (romset == ROM_PC5086) /* IRQ is 2 for PC5086 and 12 for others */ + upc.mouse_irq = 2; + else + upc.mouse_irq = 12; + upc.mdata_addr = upc.regs[13] * 4; + upc.mstat_addr = upc.mdata_addr + 1; + upc.mouse_status = UPC_MOUSE_DEV_IDLE | UPC_MOUSE_TX_IDLE; + upc.mouse_data = 0xff; + /* Set timer for mouse polling */ + timer_add(&upc.mouse_delay_timer, upc_mouse_poll, &upc, 1); - return &upc; + return &upc; } -static device_config_t upc_config[] = - { - { - .name = "serial_irq", - .description = "Serial Port IRQ", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "IRQ 4 (for address 0x3F8/COM1)", - .value = 4 - }, - { - .description = "IRQ 3 (for address 0x2F8/COM2)", - .value = 3 - }, - { - .description = "Disabled", - .value = 0 // TODO: see if this breaks PCem's PIC - } - }, - .default_int = 4 - }, - { - .name = "parallel_irq", - .description = "Parallel Port IRQ", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "IRQ 7 (for address 0x378/LPTB)", - .value = 7 - }, - { - .description = "IRQ 5 (for address 0x278/LPTC)", - .value = 5 - }, - { - .description = "Disabled", - .value = 0 // TODO: see if this breaks PCem's PIC - } - }, - .default_int = 7 - }, - // For the Hyundai Super-286TR, the only other jumper is the Color/Mono one and it's handled by the at keyboard controller code. - { - .type = -1 - } - }; +static device_config_t upc_config[] = {{.name = "serial_irq", + .description = "Serial Port IRQ", + .type = CONFIG_SELECTION, + .selection = {{.description = "IRQ 4 (for address 0x3F8/COM1)", .value = 4}, + {.description = "IRQ 3 (for address 0x2F8/COM2)", .value = 3}, + { + .description = "Disabled", + .value = 0 // TODO: see if this breaks PCem's PIC + }}, + .default_int = 4}, + {.name = "parallel_irq", + .description = "Parallel Port IRQ", + .type = CONFIG_SELECTION, + .selection = {{.description = "IRQ 7 (for address 0x378/LPTB)", .value = 7}, + {.description = "IRQ 5 (for address 0x278/LPTC)", .value = 5}, + { + .description = "Disabled", + .value = 0 // TODO: see if this breaks PCem's PIC + }}, + .default_int = 7}, + // For the Hyundai Super-286TR, the only other jumper is the Color/Mono one and it's + // handled by the at keyboard controller code. + {.type = -1}}; -device_t f82c710_upc_device = - { - "F82C710 UPC", - 0, - upc_init, - NULL, - NULL, - NULL, - NULL, - NULL, - upc_config - }; +device_t f82c710_upc_device = {"F82C710 UPC", 0, upc_init, NULL, NULL, NULL, NULL, NULL, upc_config}; /****************** PS/2 mouse port *********************/ uint8_t upc_mouse_read(uint16_t port, void *priv) { - upc_t *upc = (upc_t *)priv; - uint8_t temp = 0xff; - if (port == upc->mstat_addr) { - temp = upc->mouse_status; - } + upc_t *upc = (upc_t *)priv; + uint8_t temp = 0xff; + if (port == upc->mstat_addr) { + temp = upc->mouse_status; + } - if (port == upc->mdata_addr && (upc->mouse_status & UPC_MOUSE_RX_FULL)) { - temp = upc->mouse_data; - upc->mouse_data = 0xff; - upc->mouse_status &= ~UPC_MOUSE_RX_FULL; - upc->mouse_status |= UPC_MOUSE_DEV_IDLE; - // pclog("%04X:%04X UPC mouse READ: %04X, %02X\n", CS, cpu_state.pc, port, temp); - } + if (port == upc->mdata_addr && (upc->mouse_status & UPC_MOUSE_RX_FULL)) { + temp = upc->mouse_data; + upc->mouse_data = 0xff; + upc->mouse_status &= ~UPC_MOUSE_RX_FULL; + upc->mouse_status |= UPC_MOUSE_DEV_IDLE; + // pclog("%04X:%04X UPC mouse READ: %04X, %02X\n", CS, cpu_state.pc, port, temp); + } - // pclog("%04X:%04X UPC mouse READ: %04X, %02X\n", CS, cpu_state.pc, port, temp); - return temp; + // pclog("%04X:%04X UPC mouse READ: %04X, %02X\n", CS, cpu_state.pc, port, temp); + return temp; } void upc_mouse_write(uint16_t port, uint8_t val, void *priv) { - // pclog("%04X:%04X UPC mouse WRITE: %04X, %02X\n", CS, cpu_state.pc, port, val); + // pclog("%04X:%04X UPC mouse WRITE: %04X, %02X\n", CS, cpu_state.pc, port, val); - upc_t *upc = (upc_t *)priv; - if (port == upc->mstat_addr) { - /* write status bits - * DEV_IDLE, TX_IDLE, RX_FULL and ERROR_FLAG bits are unchanged - */ - upc->mouse_status = (val & 0xD8) | (upc->mouse_status & 0x27); - if (upc->mouse_status & UPC_MOUSE_ENABLE) - mouse_scan = 1; - else - mouse_scan = 0; - if (upc->mouse_status & (UPC_MOUSE_CLEAR | UPC_MOUSE_RESET)) { - /* if CLEAR or RESET bit is set, clear mouse queue */ - mouse_queue_start = mouse_queue_end; - upc->mouse_status &= ~UPC_MOUSE_RX_FULL; - upc->mouse_status |= UPC_MOUSE_DEV_IDLE | UPC_MOUSE_TX_IDLE; - mouse_scan = 0; - } - } + upc_t *upc = (upc_t *)priv; + if (port == upc->mstat_addr) { + /* write status bits + * DEV_IDLE, TX_IDLE, RX_FULL and ERROR_FLAG bits are unchanged + */ + upc->mouse_status = (val & 0xD8) | (upc->mouse_status & 0x27); + if (upc->mouse_status & UPC_MOUSE_ENABLE) + mouse_scan = 1; + else + mouse_scan = 0; + if (upc->mouse_status & (UPC_MOUSE_CLEAR | UPC_MOUSE_RESET)) { + /* if CLEAR or RESET bit is set, clear mouse queue */ + mouse_queue_start = mouse_queue_end; + upc->mouse_status &= ~UPC_MOUSE_RX_FULL; + upc->mouse_status |= UPC_MOUSE_DEV_IDLE | UPC_MOUSE_TX_IDLE; + mouse_scan = 0; + } + } - if (port == upc->mdata_addr) { - if ((upc->mouse_status & UPC_MOUSE_TX_IDLE) && (upc->mouse_status & UPC_MOUSE_ENABLE)) { - upc->mouse_data = val; - if (upc->mouse_write) - upc->mouse_write(val, upc->mouse_p); - } - } + if (port == upc->mdata_addr) { + if ((upc->mouse_status & UPC_MOUSE_TX_IDLE) && (upc->mouse_status & UPC_MOUSE_ENABLE)) { + upc->mouse_data = val; + if (upc->mouse_write) + upc->mouse_write(val, upc->mouse_p); + } + } } void upc_mouse_disable(upc_t *upc) { - io_removehandler(upc->mdata_addr, 0x0002, upc_mouse_read, NULL, NULL, upc_mouse_write, NULL, NULL, upc); + io_removehandler(upc->mdata_addr, 0x0002, upc_mouse_read, NULL, NULL, upc_mouse_write, NULL, NULL, upc); } void upc_mouse_enable(upc_t *upc) { - io_sethandler(upc->mdata_addr, 0x0002, upc_mouse_read, NULL, NULL, upc_mouse_write, NULL, NULL, upc); + io_sethandler(upc->mdata_addr, 0x0002, upc_mouse_read, NULL, NULL, upc_mouse_write, NULL, NULL, upc); } void upc_set_mouse(void (*mouse_write)(uint8_t val, void *p), void *p) { - upc.mouse_write = mouse_write; - upc.mouse_p = p; + upc.mouse_write = mouse_write; + upc.mouse_p = p; } void upc_mouse_poll(void *priv) { - upc_t *upc = (upc_t *)priv; - timer_advance_u64(&upc->mouse_delay_timer, (1000 * TIMER_USEC)); + upc_t *upc = (upc_t *)priv; + timer_advance_u64(&upc->mouse_delay_timer, (1000 * TIMER_USEC)); - /* check if there is something in the mouse queue */ - if (mouse_queue_start != mouse_queue_end) { - // pclog("Mouse timer. %d %d %02X %02X\n", mouse_queue_start, mouse_queue_end, upc->mouse_status, upc->mouse_data); - if ((upc->mouse_status & UPC_MOUSE_ENABLE) && !(upc->mouse_status & UPC_MOUSE_RX_FULL)) { - upc->mouse_data = mouse_queue[mouse_queue_start]; - mouse_queue_start = (mouse_queue_start + 1) & 0xf; - /* update mouse status */ - upc->mouse_status |= UPC_MOUSE_RX_FULL; - upc->mouse_status &= ~(UPC_MOUSE_DEV_IDLE); - // pclog("Reading %02X from the mouse queue at %i %i. New status is %02X\n", upc->mouse_data, mouse_queue_start, mouse_queue_end, upc->mouse_status); - /* raise IRQ if enabled */ - if (upc->mouse_status & UPC_MOUSE_INTS_ON) { - picint(1 << upc->mouse_irq); - // pclog("upc_mouse : take IRQ %d\n", upc->mouse_irq); - } - } - } + /* check if there is something in the mouse queue */ + if (mouse_queue_start != mouse_queue_end) { + // pclog("Mouse timer. %d %d %02X %02X\n", mouse_queue_start, mouse_queue_end, upc->mouse_status, + // upc->mouse_data); + if ((upc->mouse_status & UPC_MOUSE_ENABLE) && !(upc->mouse_status & UPC_MOUSE_RX_FULL)) { + upc->mouse_data = mouse_queue[mouse_queue_start]; + mouse_queue_start = (mouse_queue_start + 1) & 0xf; + /* update mouse status */ + upc->mouse_status |= UPC_MOUSE_RX_FULL; + upc->mouse_status &= ~(UPC_MOUSE_DEV_IDLE); + // pclog("Reading %02X from the mouse queue at %i %i. New status is %02X\n", upc->mouse_data, + // mouse_queue_start, mouse_queue_end, upc->mouse_status); + /* raise IRQ if enabled */ + if (upc->mouse_status & UPC_MOUSE_INTS_ON) { + picint(1 << upc->mouse_irq); + // pclog("upc_mouse : take IRQ %d\n", upc->mouse_irq); + } + } + } } diff --git a/src/devices/nvr.c b/src/devices/nvr.c index c748eead..eb6bff22 100644 --- a/src/devices/nvr.c +++ b/src/devices/nvr.c @@ -23,634 +23,773 @@ int nvraddr; int nvr_dosave = 0; typedef struct nvr_t { - pc_timer_t rtc_timer; - pc_timer_t onesec_timer; - pc_timer_t update_end_timer; + pc_timer_t rtc_timer; + pc_timer_t onesec_timer; + pc_timer_t update_end_timer; - int onesec_cnt; + int onesec_cnt; } nvr_t; FILE *nvrfopen(char *fn, char *mode) { - char s[512]; - FILE *f; + char s[512]; + FILE *f; - strcpy(s, nvr_path); - put_backslash(s); - strcat(s, config_name); - strcat(s, "."); - strcat(s, fn); - pclog("NVR try opening %s\n", s); - f = fopen(s, mode); - if (f) - return f; + strcpy(s, nvr_path); + put_backslash(s); + strcat(s, config_name); + strcat(s, "."); + strcat(s, fn); + pclog("NVR try opening %s\n", s); + f = fopen(s, mode); + if (f) + return f; - if (mode[0] == 'r') { - snprintf(s, 512, "%s%s", nvr_default_path, fn); - return fopen(s, mode); - } else { - pclog("Failed to open file '%s' for write\n", s); - return NULL; - } + if (mode[0] == 'r') { + snprintf(s, 512, "%s%s", nvr_default_path, fn); + return fopen(s, mode); + } else { + pclog("Failed to open file '%s' for write\n", s); + return NULL; + } } -void getnvrtime() { - time_get(nvrram); -} +void getnvrtime() { time_get(nvrram); } static void nvr_speed_changed(void *p) { - nvr_t *nvr = (nvr_t *)p; + nvr_t *nvr = (nvr_t *)p; - if (!(nvrram[RTC_REGA] & RTC_RS)) { - timer_disable(&nvr->rtc_timer); - return; - } else { - int c = 1 << ((nvrram[RTC_REGA] & RTC_RS) - 1); - timer_set_delay_u64(&nvr->rtc_timer, (uint64_t)(RTCCONST * c)); - } + if (!(nvrram[RTC_REGA] & RTC_RS)) { + timer_disable(&nvr->rtc_timer); + return; + } else { + int c = 1 << ((nvrram[RTC_REGA] & RTC_RS) - 1); + timer_set_delay_u64(&nvr->rtc_timer, (uint64_t)(RTCCONST * c)); + } } static void nvr_rtc(void *p) { - nvr_t *nvr = (nvr_t *)p; + nvr_t *nvr = (nvr_t *)p; - if (!(nvrram[RTC_REGA] & RTC_RS)) { - timer_disable(&nvr->rtc_timer); - return; - } else { - int c = 1 << ((nvrram[RTC_REGA] & RTC_RS) - 1); - timer_advance_u64(&nvr->rtc_timer, (uint64_t)(RTCCONST * c)); -// pclog("RTCtime now %f\n",rtctime); - nvrram[RTC_REGC] |= RTC_PF; - if (nvrram[RTC_REGB] & RTC_PIE) { - nvrram[RTC_REGC] |= RTC_IRQF; - if (AMSTRAD) - picint(2); - else - picint(0x100); -// pclog("RTC int\n"); - } - } + if (!(nvrram[RTC_REGA] & RTC_RS)) { + timer_disable(&nvr->rtc_timer); + return; + } else { + int c = 1 << ((nvrram[RTC_REGA] & RTC_RS) - 1); + timer_advance_u64(&nvr->rtc_timer, (uint64_t)(RTCCONST * c)); + // pclog("RTCtime now %f\n",rtctime); + nvrram[RTC_REGC] |= RTC_PF; + if (nvrram[RTC_REGB] & RTC_PIE) { + nvrram[RTC_REGC] |= RTC_IRQF; + if (AMSTRAD) + picint(2); + else + picint(0x100); + // pclog("RTC int\n"); + } + } } int nvr_update_status = 0; -#define ALARM_DONTCARE 0xc0 +#define ALARM_DONTCARE 0xc0 int nvr_check_alarm(int nvraddr) { - return (nvrram[nvraddr + 1] == nvrram[nvraddr] || (nvrram[nvraddr + 1] & ALARM_DONTCARE) == ALARM_DONTCARE); + return (nvrram[nvraddr + 1] == nvrram[nvraddr] || (nvrram[nvraddr + 1] & ALARM_DONTCARE) == ALARM_DONTCARE); } static void nvr_update_end(void *p) { -// nvr_t *nvr = (nvr_t *)p; + // nvr_t *nvr = (nvr_t *)p; - if (!(nvrram[RTC_REGB] & RTC_SET)) { - getnvrtime(); - /* Clear update status. */ - nvr_update_status = 0; + if (!(nvrram[RTC_REGB] & RTC_SET)) { + getnvrtime(); + /* Clear update status. */ + nvr_update_status = 0; - if (nvr_check_alarm(RTC_SECONDS) && nvr_check_alarm(RTC_MINUTES) && nvr_check_alarm(RTC_HOURS)) { - nvrram[RTC_REGC] |= RTC_AF; - if (nvrram[RTC_REGB] & RTC_AIE) { - nvrram[RTC_REGC] |= RTC_IRQF; - if (AMSTRAD) - picint(2); - else - picint(0x100); - } - } + if (nvr_check_alarm(RTC_SECONDS) && nvr_check_alarm(RTC_MINUTES) && nvr_check_alarm(RTC_HOURS)) { + nvrram[RTC_REGC] |= RTC_AF; + if (nvrram[RTC_REGB] & RTC_AIE) { + nvrram[RTC_REGC] |= RTC_IRQF; + if (AMSTRAD) + picint(2); + else + picint(0x100); + } + } - /* The flag and interrupt should be issued on update ended, not started. */ - nvrram[RTC_REGC] |= RTC_UF; - if (nvrram[RTC_REGB] & RTC_UIE) { - nvrram[RTC_REGC] |= RTC_IRQF; - if (AMSTRAD) - picint(2); - else - picint(0x100); - } - } + /* The flag and interrupt should be issued on update ended, not started. */ + nvrram[RTC_REGC] |= RTC_UF; + if (nvrram[RTC_REGB] & RTC_UIE) { + nvrram[RTC_REGC] |= RTC_IRQF; + if (AMSTRAD) + picint(2); + else + picint(0x100); + } + } -// pclog("RTC onesec\n"); + // pclog("RTC onesec\n"); } static void nvr_onesec(void *p) { - nvr_t *nvr = (nvr_t *)p; + nvr_t *nvr = (nvr_t *)p; - nvr->onesec_cnt++; - if (nvr->onesec_cnt >= 100) { - if (!(nvrram[RTC_REGB] & RTC_SET)) { - nvr_update_status = RTC_UIP; - rtc_tick(); + nvr->onesec_cnt++; + if (nvr->onesec_cnt >= 100) { + if (!(nvrram[RTC_REGB] & RTC_SET)) { + nvr_update_status = RTC_UIP; + rtc_tick(); - timer_set_delay_u64(&nvr->update_end_timer, (uint64_t)((244.0 + 1984.0) * TIMER_USEC)); - } - nvr->onesec_cnt = 0; - } - timer_advance_u64(&nvr->onesec_timer, (uint64_t)(10000 * TIMER_USEC)); + timer_set_delay_u64(&nvr->update_end_timer, (uint64_t)((244.0 + 1984.0) * TIMER_USEC)); + } + nvr->onesec_cnt = 0; + } + timer_advance_u64(&nvr->onesec_timer, (uint64_t)(10000 * TIMER_USEC)); } static void writenvr(uint16_t addr, uint8_t val, void *p) { - nvr_t *nvr = (nvr_t *)p; - int c, old; + nvr_t *nvr = (nvr_t *)p; + int c, old; - cycles -= ISA_CYCLES(8); -// printf("Write NVR %03X %02X %02X %04X:%04X %i\n",addr,nvraddr,val,cs>>4,pc,ins); - if (addr & 1) { - if (nvraddr == RTC_REGC || nvraddr == RTC_REGD) - return; /* Registers C and D are read-only. There's no reason to continue. */ -// if (nvraddr == 0x33) pclog("NVRWRITE33 %02X %04X:%04X %i\n",val,CS,pc,ins); - if (nvraddr > RTC_REGD && nvrram[nvraddr] != val) - nvr_dosave = 1; + cycles -= ISA_CYCLES(8); + // printf("Write NVR %03X %02X %02X %04X:%04X %i\n",addr,nvraddr,val,cs>>4,pc,ins); + if (addr & 1) { + if (nvraddr == RTC_REGC || nvraddr == RTC_REGD) + return; /* Registers C and D are read-only. There's no reason to continue. */ + // if (nvraddr == 0x33) pclog("NVRWRITE33 %02X %04X:%04X %i\n",val,CS,pc,ins); + if (nvraddr > RTC_REGD && nvrram[nvraddr] != val) + nvr_dosave = 1; - old = nvrram[nvraddr]; - nvrram[nvraddr] = val; + old = nvrram[nvraddr]; + nvrram[nvraddr] = val; - if (nvraddr == RTC_REGA) { -// pclog("NVR rate %i\n",val&0xF); - if (val & RTC_RS) { - c = 1 << ((val & RTC_RS) - 1); - timer_set_delay_u64(&nvr->rtc_timer, (uint64_t)(RTCCONST * c)); - } else - timer_disable(&nvr->rtc_timer); - } else { - if (nvraddr == RTC_REGB) { - if (((old ^ val) & RTC_SET) && (val & RTC_SET)) { - nvrram[RTC_REGA] &= ~RTC_UIP; /* This has to be done according to the datasheet. */ - nvrram[RTC_REGB] &= ~RTC_UIE; /* This also has to happen per the specification. */ - } - } + if (nvraddr == RTC_REGA) { + // pclog("NVR rate %i\n",val&0xF); + if (val & RTC_RS) { + c = 1 << ((val & RTC_RS) - 1); + timer_set_delay_u64(&nvr->rtc_timer, (uint64_t)(RTCCONST * c)); + } else + timer_disable(&nvr->rtc_timer); + } else { + if (nvraddr == RTC_REGB) { + if (((old ^ val) & RTC_SET) && (val & RTC_SET)) { + nvrram[RTC_REGA] &= ~RTC_UIP; /* This has to be done according to the datasheet. */ + nvrram[RTC_REGB] &= ~RTC_UIE; /* This also has to happen per the specification. */ + } + } - if ((nvraddr < RTC_REGA) || (nvraddr == RTC_CENTURY)) { - if ((nvraddr != 1) && (nvraddr != 3) && (nvraddr != 5)) { - if ((old != val) && !enable_sync) { - time_update(nvrram, nvraddr); - nvr_dosave = 1; - } - } - } - } - } else { - nvraddr = val & nvrmask; - /*PS/2 BIOSes will disable NMIs and expect the watchdog timer to still be able - to fire them. I suspect the watchdog is exempt from NMI masking. Currently NMIs - are always enabled for PS/2 machines - this would mean that other peripherals - could fire NMIs regardless of the mask state, but as there aren't any emulated - MCA peripherals that do this it's currently a moot point.*/ + if ((nvraddr < RTC_REGA) || (nvraddr == RTC_CENTURY)) { + if ((nvraddr != 1) && (nvraddr != 3) && (nvraddr != 5)) { + if ((old != val) && !enable_sync) { + time_update(nvrram, nvraddr); + nvr_dosave = 1; + } + } + } + } + } else { + nvraddr = val & nvrmask; + /*PS/2 BIOSes will disable NMIs and expect the watchdog timer to still be able + to fire them. I suspect the watchdog is exempt from NMI masking. Currently NMIs + are always enabled for PS/2 machines - this would mean that other peripherals + could fire NMIs regardless of the mask state, but as there aren't any emulated + MCA peripherals that do this it's currently a moot point.*/ - /* Also don't update the NMI mask on Amstrad PCs - actually - * ought not to do it for any XT because their NMI mask - * register is at 0xA0. But particularly important on the - * PC200 and PPC because their video subsystem issues NMIs */ - if (!(models[model]->flags & (MODEL_MCA | MODEL_AMSTRAD))) { - nmi_mask = ~val & 0x80; - } - } + /* Also don't update the NMI mask on Amstrad PCs - actually + * ought not to do it for any XT because their NMI mask + * register is at 0xA0. But particularly important on the + * PC200 and PPC because their video subsystem issues NMIs */ + if (!(models[model]->flags & (MODEL_MCA | MODEL_AMSTRAD))) { + nmi_mask = ~val & 0x80; + } + } } uint8_t readnvr(uint16_t addr, void *p) { -// nvr_t *nvr = (nvr_t *)p; - uint8_t temp; -// printf("Read NVR %03X %02X %02X %04X:%04X\n",addr,nvraddr,nvrram[nvraddr],cs>>4,pc); - cycles -= ISA_CYCLES(8); - if (addr & 1) { - if (nvraddr == RTC_REGA) - return ((nvrram[RTC_REGA] & 0x7F) | nvr_update_status); - if (nvraddr == RTC_REGD) - nvrram[RTC_REGD] |= RTC_VRT; - if (nvraddr == RTC_REGC) { - if (AMSTRAD) - picintc(2); - else - picintc(0x100); - temp = nvrram[RTC_REGC]; - nvrram[RTC_REGC] = 0; - return temp; - } -// if (AMIBIOS && nvraddr==0x36) return 0; -// if (nvraddr==0xA) nvrram[0xA]^=0x80; - return nvrram[nvraddr]; - } - return nvraddr; + // nvr_t *nvr = (nvr_t *)p; + uint8_t temp; + // printf("Read NVR %03X %02X %02X %04X:%04X\n",addr,nvraddr,nvrram[nvraddr],cs>>4,pc); + cycles -= ISA_CYCLES(8); + if (addr & 1) { + if (nvraddr == RTC_REGA) + return ((nvrram[RTC_REGA] & 0x7F) | nvr_update_status); + if (nvraddr == RTC_REGD) + nvrram[RTC_REGD] |= RTC_VRT; + if (nvraddr == RTC_REGC) { + if (AMSTRAD) + picintc(2); + else + picintc(0x100); + temp = nvrram[RTC_REGC]; + nvrram[RTC_REGC] = 0; + return temp; + } + // if (AMIBIOS && nvraddr==0x36) return 0; + // if (nvraddr==0xA) nvrram[0xA]^=0x80; + return nvrram[nvraddr]; + } + return nvraddr; } void loadnvr() { - FILE *f; + FILE *f; - nvrmask = 63; - oldromset = romset; - switch (romset) { - case ROM_PC1512: f = nvrfopen("pc1512.nvr", "rb"); - break; - case ROM_PC1640: f = nvrfopen("pc1640.nvr", "rb"); - break; - case ROM_PC200: f = nvrfopen("pc200.nvr", "rb"); - break; - case ROM_PC2086: f = nvrfopen("pc2086.nvr", "rb"); - break; - case ROM_PC3086: f = nvrfopen("pc3086.nvr", "rb"); - break; - case ROM_PC5086: f = nvrfopen("pc5086.nvr", "rb"); - break; - case ROM_PPC512: f = nvrfopen("ppc512.nvr", "rb"); - break; - case ROM_IBMAT: f = nvrfopen("at.nvr", "rb"); - break; - case ROM_IBMXT286: f = nvrfopen("ibmxt286.nvr", "rb"); - break; - case ROM_IBMPS1_2011: f = nvrfopen("ibmps1_2011.nvr", "rb"); /*nvrmask = 127; */break; - case ROM_IBMPS1_2121: f = nvrfopen("ibmps1_2121.nvr", "rb"); - nvrmask = 127; - break; - case ROM_IBMPS2_M30_286: f = nvrfopen("ibmps2_m30_286.nvr", "rb"); /*nvrmask = 127; */break; - case ROM_IBMPS2_M50: f = nvrfopen("ibmps2_m50.nvr", "rb"); - break; - case ROM_IBMPS2_M55SX: f = nvrfopen("ibmps2_m55sx.nvr", "rb"); - break; - case ROM_IBMPS2_M80: f = nvrfopen("ibmps2_m80.nvr", "rb"); - break; - case ROM_CMDPC30: f = nvrfopen("cmdpc30.nvr", "rb"); - nvrmask = 127; - break; - case ROM_AMI286: f = nvrfopen("ami286.nvr", "rb"); - nvrmask = 127; - break; - case ROM_TG286M: f = nvrfopen("tg286m.nvr", "rb"); - nvrmask = 127; - break; - case ROM_AWARD286: f = nvrfopen("award286.nvr", "rb"); - nvrmask = 127; - break; - case ROM_GDC212M: f = nvrfopen("gdc212m.nvr", "rb"); - nvrmask = 127; - break; - case ROM_HYUNDAI_SUPER286TR: f = nvrfopen("super286tr.nvr", "rb"); - nvrmask = 127; - break; - case ROM_GW286CT: f = nvrfopen("gw286ct.nvr", "rb"); - nvrmask = 127; - break; - case ROM_SPC4200P: f = nvrfopen("spc4200p.nvr", "rb"); - nvrmask = 127; - break; - case ROM_SPC4216P: f = nvrfopen("spc4216p.nvr", "rb"); - nvrmask = 127; - break; - case ROM_SPC4620P: f = nvrfopen("spc4620p.nvr", "rb"); - nvrmask = 127; - break; - case ROM_SPC6000A: f = nvrfopen("spc6000a.nvr", "rb"); - nvrmask = 127; - break; - case ROM_SPC6033P: f = nvrfopen("spc6033p.nvr", "rb"); - nvrmask = 127; - break; - case ROM_DELL200: f = nvrfopen("dell200.nvr", "rb"); - nvrmask = 127; - break; - case ROM_IBMAT386: f = nvrfopen("at386.nvr", "rb"); - nvrmask = 127; - break; - case ROM_DESKPRO_386: f = nvrfopen("deskpro386.nvr", "rb"); - break; - case ROM_ACER386: f = nvrfopen("acer386.nvr", "rb"); - nvrmask = 127; - break; - case ROM_KMXC02: f = nvrfopen("kmxc02.nvr", "rb"); - nvrmask = 127; - break; - case ROM_MEGAPC: f = nvrfopen("megapc.nvr", "rb"); - nvrmask = 127; - break; - case ROM_AMA932J: f = nvrfopen("ama932j.nvr", "rb"); - nvrmask = 127; - break; - case ROM_AMI386SX: f = nvrfopen("ami386.nvr", "rb"); - nvrmask = 127; - break; - case ROM_AMI486: f = nvrfopen("ami486.nvr", "rb"); - nvrmask = 127; - break; - case ROM_WIN486: f = nvrfopen("win486.nvr", "rb"); - nvrmask = 127; - break; - case ROM_PCI486: f = nvrfopen("hot-433.nvr", "rb"); - nvrmask = 127; - break; - case ROM_SIS496: f = nvrfopen("sis496.nvr", "rb"); - nvrmask = 127; - break; - case ROM_P55VA: f = nvrfopen("p55va.nvr", "rb"); - nvrmask = 127; - break; - case ROM_P55TVP4: f = nvrfopen("p55tvp4.nvr", "rb"); - nvrmask = 127; - break; - case ROM_430VX: f = nvrfopen("430vx.nvr", "rb"); - nvrmask = 127; - break; - case ROM_REVENGE: f = nvrfopen("revenge.nvr", "rb"); - nvrmask = 127; - break; - case ROM_ENDEAVOR: f = nvrfopen("endeavor.nvr", "rb"); - nvrmask = 127; - break; - case ROM_P55T2P4: f = nvrfopen("p55t2p4.nvr", "rb"); - nvrmask = 127; - break; - case ROM_PX386: f = nvrfopen("px386.nvr", "rb"); - nvrmask = 127; - break; - case ROM_DTK386: f = nvrfopen("dtk386.nvr", "rb"); - nvrmask = 127; - break; - case ROM_MR386DX_OPTI495: f = nvrfopen("mr386dx_opti495.nvr", "rb"); - nvrmask = 127; - break; - case ROM_AMI386DX_OPTI495: f = nvrfopen("ami386dx_opti495.nvr", "rb"); - nvrmask = 127; - break; - case ROM_EPSON_PCAX: f = nvrfopen("epson_pcax.nvr", "rb"); - nvrmask = 127; - break; - case ROM_EPSON_PCAX2E: f = nvrfopen("epson_pcax2e.nvr", "rb"); - nvrmask = 127; - break; - case ROM_PB_L300SX: f = nvrfopen("pb_l300sx.nvr", "rb"); - nvrmask = 127; - break; - case ROM_EPSON_PCAX3: f = nvrfopen("epson_pcax3.nvr", "rb"); - nvrmask = 127; - break; - case ROM_COMPAQ_PII: f = nvrfopen("compaq_pii.nvr", "rb"); - break; - case ROM_T3100E: f = nvrfopen("t3100e.nvr", "rb"); - break; - case ROM_T1000: tc8521_loadnvr(); - t1000_configsys_loadnvr(); - t1000_emsboard_loadnvr(); - return; - case ROM_T1200: tc8521_loadnvr(); - t1200_state_loadnvr(); - t1000_emsboard_loadnvr(); - return; - case ROM_ELX_PC425X: f = nvrfopen("elx_pc425.nvr", "rb"); - nvrmask = 127; - break; - case ROM_PB570: f = nvrfopen("pb570.nvr", "rb"); - nvrmask = 127; - break; - case ROM_ZAPPA: f = nvrfopen("zappa.nvr", "rb"); - nvrmask = 127; - break; - case ROM_ITAUTEC_INFOWAYM: f = nvrfopen("infowaym.nvr", "rb"); - nvrmask = 127; - break; - case ROM_PB520R: f = nvrfopen("pb520r.nvr", "rb"); - nvrmask = 127; - break; - case ROM_XI8088: f = nvrfopen("xi8088.nvr", "rb"); - nvrmask = 127; - break; - case ROM_IBMPS2_M70_TYPE3: f = nvrfopen("ibmps2_m70_type3.nvr", "rb"); - break; - case ROM_IBMPS2_M70_TYPE4: f = nvrfopen("ibmps2_m70_type4.nvr", "rb"); - break; - case ROM_TULIP_TC7: f = nvrfopen("tulip_tc7.nvr", "rb"); - break; - case ROM_PB410A: f = nvrfopen("pb410a.nvr", "rb"); - nvrmask = 127; - break; - case ROM_BULL_MICRAL_45: f = nvrfopen("bull_micral_45.nvr", "rb"); - break; - case ROM_FIC_VA503P: f = nvrfopen("fic_va503p.nvr", "rb"); - nvrmask = 127; - break; - case ROM_CBM_SL386SX25: f = nvrfopen("cbm_sl386sx25.nvr", "rb"); - nvrmask = 127; - break; - case ROM_IBMPS1_2133_451: f = nvrfopen("ibmps1_2133.nvr", "rb"); - nvrmask = 127; - break; - case ROM_ECS_386_32: f = nvrfopen("ecs_386_32.nvr", "rb"); - nvrmask = 127; - break; - case ROM_VS440FX: f = nvrfopen("vs440fx.nvr", "rb"); - nvrmask = 127; - break; - case ROM_GA686BX: f = nvrfopen("ga686bx.nvr", "rb"); - nvrmask = 127; - break; + nvrmask = 63; + oldromset = romset; + switch (romset) { + case ROM_PC1512: + f = nvrfopen("pc1512.nvr", "rb"); + break; + case ROM_PC1640: + f = nvrfopen("pc1640.nvr", "rb"); + break; + case ROM_PC200: + f = nvrfopen("pc200.nvr", "rb"); + break; + case ROM_PC2086: + f = nvrfopen("pc2086.nvr", "rb"); + break; + case ROM_PC3086: + f = nvrfopen("pc3086.nvr", "rb"); + break; + case ROM_PC5086: + f = nvrfopen("pc5086.nvr", "rb"); + break; + case ROM_PPC512: + f = nvrfopen("ppc512.nvr", "rb"); + break; + case ROM_IBMAT: + f = nvrfopen("at.nvr", "rb"); + break; + case ROM_IBMXT286: + f = nvrfopen("ibmxt286.nvr", "rb"); + break; + case ROM_IBMPS1_2011: + f = nvrfopen("ibmps1_2011.nvr", "rb"); /*nvrmask = 127; */ + break; + case ROM_IBMPS1_2121: + f = nvrfopen("ibmps1_2121.nvr", "rb"); + nvrmask = 127; + break; + case ROM_IBMPS2_M30_286: + f = nvrfopen("ibmps2_m30_286.nvr", "rb"); /*nvrmask = 127; */ + break; + case ROM_IBMPS2_M50: + f = nvrfopen("ibmps2_m50.nvr", "rb"); + break; + case ROM_IBMPS2_M55SX: + f = nvrfopen("ibmps2_m55sx.nvr", "rb"); + break; + case ROM_IBMPS2_M80: + f = nvrfopen("ibmps2_m80.nvr", "rb"); + break; + case ROM_CMDPC30: + f = nvrfopen("cmdpc30.nvr", "rb"); + nvrmask = 127; + break; + case ROM_AMI286: + f = nvrfopen("ami286.nvr", "rb"); + nvrmask = 127; + break; + case ROM_TG286M: + f = nvrfopen("tg286m.nvr", "rb"); + nvrmask = 127; + break; + case ROM_AWARD286: + f = nvrfopen("award286.nvr", "rb"); + nvrmask = 127; + break; + case ROM_GDC212M: + f = nvrfopen("gdc212m.nvr", "rb"); + nvrmask = 127; + break; + case ROM_HYUNDAI_SUPER286TR: + f = nvrfopen("super286tr.nvr", "rb"); + nvrmask = 127; + break; + case ROM_GW286CT: + f = nvrfopen("gw286ct.nvr", "rb"); + nvrmask = 127; + break; + case ROM_SPC4200P: + f = nvrfopen("spc4200p.nvr", "rb"); + nvrmask = 127; + break; + case ROM_SPC4216P: + f = nvrfopen("spc4216p.nvr", "rb"); + nvrmask = 127; + break; + case ROM_SPC4620P: + f = nvrfopen("spc4620p.nvr", "rb"); + nvrmask = 127; + break; + case ROM_SPC6000A: + f = nvrfopen("spc6000a.nvr", "rb"); + nvrmask = 127; + break; + case ROM_SPC6033P: + f = nvrfopen("spc6033p.nvr", "rb"); + nvrmask = 127; + break; + case ROM_DELL200: + f = nvrfopen("dell200.nvr", "rb"); + nvrmask = 127; + break; + case ROM_IBMAT386: + f = nvrfopen("at386.nvr", "rb"); + nvrmask = 127; + break; + case ROM_DESKPRO_386: + f = nvrfopen("deskpro386.nvr", "rb"); + break; + case ROM_ACER386: + f = nvrfopen("acer386.nvr", "rb"); + nvrmask = 127; + break; + case ROM_KMXC02: + f = nvrfopen("kmxc02.nvr", "rb"); + nvrmask = 127; + break; + case ROM_MEGAPC: + f = nvrfopen("megapc.nvr", "rb"); + nvrmask = 127; + break; + case ROM_AMA932J: + f = nvrfopen("ama932j.nvr", "rb"); + nvrmask = 127; + break; + case ROM_AMI386SX: + f = nvrfopen("ami386.nvr", "rb"); + nvrmask = 127; + break; + case ROM_AMI486: + f = nvrfopen("ami486.nvr", "rb"); + nvrmask = 127; + break; + case ROM_WIN486: + f = nvrfopen("win486.nvr", "rb"); + nvrmask = 127; + break; + case ROM_PCI486: + f = nvrfopen("hot-433.nvr", "rb"); + nvrmask = 127; + break; + case ROM_SIS496: + f = nvrfopen("sis496.nvr", "rb"); + nvrmask = 127; + break; + case ROM_P55VA: + f = nvrfopen("p55va.nvr", "rb"); + nvrmask = 127; + break; + case ROM_P55TVP4: + f = nvrfopen("p55tvp4.nvr", "rb"); + nvrmask = 127; + break; + case ROM_430VX: + f = nvrfopen("430vx.nvr", "rb"); + nvrmask = 127; + break; + case ROM_REVENGE: + f = nvrfopen("revenge.nvr", "rb"); + nvrmask = 127; + break; + case ROM_ENDEAVOR: + f = nvrfopen("endeavor.nvr", "rb"); + nvrmask = 127; + break; + case ROM_P55T2P4: + f = nvrfopen("p55t2p4.nvr", "rb"); + nvrmask = 127; + break; + case ROM_PX386: + f = nvrfopen("px386.nvr", "rb"); + nvrmask = 127; + break; + case ROM_DTK386: + f = nvrfopen("dtk386.nvr", "rb"); + nvrmask = 127; + break; + case ROM_MR386DX_OPTI495: + f = nvrfopen("mr386dx_opti495.nvr", "rb"); + nvrmask = 127; + break; + case ROM_AMI386DX_OPTI495: + f = nvrfopen("ami386dx_opti495.nvr", "rb"); + nvrmask = 127; + break; + case ROM_EPSON_PCAX: + f = nvrfopen("epson_pcax.nvr", "rb"); + nvrmask = 127; + break; + case ROM_EPSON_PCAX2E: + f = nvrfopen("epson_pcax2e.nvr", "rb"); + nvrmask = 127; + break; + case ROM_PB_L300SX: + f = nvrfopen("pb_l300sx.nvr", "rb"); + nvrmask = 127; + break; + case ROM_EPSON_PCAX3: + f = nvrfopen("epson_pcax3.nvr", "rb"); + nvrmask = 127; + break; + case ROM_COMPAQ_PII: + f = nvrfopen("compaq_pii.nvr", "rb"); + break; + case ROM_T3100E: + f = nvrfopen("t3100e.nvr", "rb"); + break; + case ROM_T1000: + tc8521_loadnvr(); + t1000_configsys_loadnvr(); + t1000_emsboard_loadnvr(); + return; + case ROM_T1200: + tc8521_loadnvr(); + t1200_state_loadnvr(); + t1000_emsboard_loadnvr(); + return; + case ROM_ELX_PC425X: + f = nvrfopen("elx_pc425.nvr", "rb"); + nvrmask = 127; + break; + case ROM_PB570: + f = nvrfopen("pb570.nvr", "rb"); + nvrmask = 127; + break; + case ROM_ZAPPA: + f = nvrfopen("zappa.nvr", "rb"); + nvrmask = 127; + break; + case ROM_ITAUTEC_INFOWAYM: + f = nvrfopen("infowaym.nvr", "rb"); + nvrmask = 127; + break; + case ROM_PB520R: + f = nvrfopen("pb520r.nvr", "rb"); + nvrmask = 127; + break; + case ROM_XI8088: + f = nvrfopen("xi8088.nvr", "rb"); + nvrmask = 127; + break; + case ROM_IBMPS2_M70_TYPE3: + f = nvrfopen("ibmps2_m70_type3.nvr", "rb"); + break; + case ROM_IBMPS2_M70_TYPE4: + f = nvrfopen("ibmps2_m70_type4.nvr", "rb"); + break; + case ROM_TULIP_TC7: + f = nvrfopen("tulip_tc7.nvr", "rb"); + break; + case ROM_PB410A: + f = nvrfopen("pb410a.nvr", "rb"); + nvrmask = 127; + break; + case ROM_BULL_MICRAL_45: + f = nvrfopen("bull_micral_45.nvr", "rb"); + break; + case ROM_FIC_VA503P: + f = nvrfopen("fic_va503p.nvr", "rb"); + nvrmask = 127; + break; + case ROM_CBM_SL386SX25: + f = nvrfopen("cbm_sl386sx25.nvr", "rb"); + nvrmask = 127; + break; + case ROM_IBMPS1_2133_451: + f = nvrfopen("ibmps1_2133.nvr", "rb"); + nvrmask = 127; + break; + case ROM_ECS_386_32: + f = nvrfopen("ecs_386_32.nvr", "rb"); + nvrmask = 127; + break; + case ROM_VS440FX: + f = nvrfopen("vs440fx.nvr", "rb"); + nvrmask = 127; + break; + case ROM_GA686BX: + f = nvrfopen("ga686bx.nvr", "rb"); + nvrmask = 127; + break; - default: return; - } - if (!f) { - memset(nvrram, 0xFF, 128); - if (!enable_sync) { - nvrram[RTC_SECONDS] = nvrram[RTC_MINUTES] = nvrram[RTC_HOURS] = 0; - nvrram[RTC_DOM] = nvrram[RTC_MONTH] = 1; - nvrram[RTC_YEAR] = BCD(80); - nvrram[RTC_CENTURY] = BCD(19); - nvrram[RTC_REGB] = RTC_2412; - } - return; - } - fread(nvrram, 128, 1, f); - if (enable_sync) - time_internal_sync(nvrram); - else - time_internal_set_nvrram(nvrram); /* Update the internal clock state based on the NVR registers. */ - fclose(f); - nvrram[RTC_REGA] = 6; - nvrram[RTC_REGB] = RTC_2412; + default: + return; + } + if (!f) { + memset(nvrram, 0xFF, 128); + if (!enable_sync) { + nvrram[RTC_SECONDS] = nvrram[RTC_MINUTES] = nvrram[RTC_HOURS] = 0; + nvrram[RTC_DOM] = nvrram[RTC_MONTH] = 1; + nvrram[RTC_YEAR] = BCD(80); + nvrram[RTC_CENTURY] = BCD(19); + nvrram[RTC_REGB] = RTC_2412; + } + return; + } + fread(nvrram, 128, 1, f); + if (enable_sync) + time_internal_sync(nvrram); + else + time_internal_set_nvrram(nvrram); /* Update the internal clock state based on the NVR registers. */ + fclose(f); + nvrram[RTC_REGA] = 6; + nvrram[RTC_REGB] = RTC_2412; } void savenvr() { - FILE *f; - switch (oldromset) { - case ROM_PC1512: f = nvrfopen("pc1512.nvr", "wb"); - break; - case ROM_PC1640: f = nvrfopen("pc1640.nvr", "wb"); - break; - case ROM_PC200: f = nvrfopen("pc200.nvr", "wb"); - break; - case ROM_PC2086: f = nvrfopen("pc2086.nvr", "wb"); - break; - case ROM_PC3086: f = nvrfopen("pc3086.nvr", "wb"); - break; - case ROM_PC5086: f = nvrfopen("pc5086.nvr", "wb"); - break; - case ROM_PPC512: f = nvrfopen("ppc512.nvr", "wb"); - break; - case ROM_IBMAT: f = nvrfopen("at.nvr", "wb"); - break; - case ROM_IBMXT286: f = nvrfopen("ibmxt286.nvr", "wb"); - break; - case ROM_IBMPS1_2011: f = nvrfopen("ibmps1_2011.nvr", "wb"); - break; - case ROM_IBMPS1_2121: f = nvrfopen("ibmps1_2121.nvr", "wb"); - break; - case ROM_IBMPS2_M30_286: f = nvrfopen("ibmps2_m30_286.nvr", "wb"); - break; - case ROM_IBMPS2_M50: f = nvrfopen("ibmps2_m50.nvr", "wb"); - break; - case ROM_IBMPS2_M55SX: f = nvrfopen("ibmps2_m55sx.nvr", "wb"); - break; - case ROM_IBMPS2_M80: f = nvrfopen("ibmps2_m80.nvr", "wb"); - break; - case ROM_CMDPC30: f = nvrfopen("cmdpc30.nvr", "wb"); - break; - case ROM_AMI286: f = nvrfopen("ami286.nvr", "wb"); - break; - case ROM_TG286M: f = nvrfopen("tg286m.nvr", "wb"); - break; - case ROM_AWARD286: f = nvrfopen("award286.nvr", "wb"); - break; - case ROM_GDC212M: f = nvrfopen("gdc212m.nvr", "wb"); - break; - case ROM_HYUNDAI_SUPER286TR: f = nvrfopen("super286tr.nvr", "wb"); - break; - case ROM_GW286CT: f = nvrfopen("gw286ct.nvr", "wb"); - break; - case ROM_SPC4200P: f = nvrfopen("spc4200p.nvr", "wb"); - break; - case ROM_SPC4216P: f = nvrfopen("spc4216p.nvr", "wb"); - break; - case ROM_SPC4620P: f = nvrfopen("spc4620p.nvr", "wb"); - break; - case ROM_SPC6000A: f = nvrfopen("spc6000a.nvr", "wb"); - break; - case ROM_SPC6033P: f = nvrfopen("spc6033p.nvr", "wb"); - break; - case ROM_DELL200: f = nvrfopen("dell200.nvr", "wb"); - break; - case ROM_IBMAT386: f = nvrfopen("at386.nvr", "wb"); - break; - case ROM_DESKPRO_386: f = nvrfopen("deskpro386.nvr", "wb"); - break; - case ROM_ACER386: f = nvrfopen("acer386.nvr", "wb"); - break; - case ROM_KMXC02: f = nvrfopen("kmxc02.nvr", "wb"); - break; - case ROM_MEGAPC: f = nvrfopen("megapc.nvr", "wb"); - break; - case ROM_AMA932J: f = nvrfopen("ama932j.nvr", "wb"); - break; - case ROM_AMI386SX: f = nvrfopen("ami386.nvr", "wb"); - break; - case ROM_AMI486: f = nvrfopen("ami486.nvr", "wb"); - break; - case ROM_WIN486: f = nvrfopen("win486.nvr", "wb"); - break; - case ROM_PCI486: f = nvrfopen("hot-433.nvr", "wb"); - break; - case ROM_SIS496: f = nvrfopen("sis496.nvr", "wb"); - break; - case ROM_P55VA: f = nvrfopen("p55va.nvr", "wb"); - break; - case ROM_P55TVP4: f = nvrfopen("p55tvp4.nvr", "wb"); - break; - case ROM_430VX: f = nvrfopen("430vx.nvr", "wb"); - break; - case ROM_REVENGE: f = nvrfopen("revenge.nvr", "wb"); - break; - case ROM_ENDEAVOR: f = nvrfopen("endeavor.nvr", "wb"); - break; - case ROM_P55T2P4: f = nvrfopen("p55t2p4.nvr", "wb"); - break; - case ROM_PX386: f = nvrfopen("px386.nvr", "wb"); - break; - case ROM_DTK386: f = nvrfopen("dtk386.nvr", "wb"); - break; - case ROM_MR386DX_OPTI495: f = nvrfopen("mr386dx_opti495.nvr", "wb"); - break; - case ROM_AMI386DX_OPTI495: f = nvrfopen("ami386dx_opti495.nvr", "wb"); - break; - case ROM_EPSON_PCAX: f = nvrfopen("epson_pcax.nvr", "wb"); - break; - case ROM_EPSON_PCAX2E: f = nvrfopen("epson_pcax2e.nvr", "wb"); - break; - case ROM_EPSON_PCAX3: f = nvrfopen("epson_pcax3.nvr", "wb"); - break; - case ROM_COMPAQ_PII: f = nvrfopen("compaq_pii.nvr", "wb"); - break; - case ROM_PB_L300SX: f = nvrfopen("pb_l300sx.nvr", "wb"); - break; - case ROM_T3100E: f = nvrfopen("t3100e.nvr", "wb"); - break; - case ROM_T1000: tc8521_savenvr(); - t1000_configsys_savenvr(); - t1000_emsboard_savenvr(); - return; - case ROM_T1200: tc8521_savenvr(); - t1200_state_savenvr(); - t1000_emsboard_savenvr(); - return; - case ROM_ELX_PC425X: f = nvrfopen("elx_pc425.nvr", "wb"); - break; - case ROM_PB570: f = nvrfopen("pb570.nvr", "wb"); - break; - case ROM_ZAPPA: f = nvrfopen("zappa.nvr", "wb"); - break; - case ROM_ITAUTEC_INFOWAYM: f = nvrfopen("infowaym.nvr", "wb"); - break; - case ROM_PB520R: f = nvrfopen("pb520r.nvr", "wb"); - break; - case ROM_XI8088: f = nvrfopen("xi8088.nvr", "wb"); - break; - case ROM_IBMPS2_M70_TYPE3: f = nvrfopen("ibmps2_m70_type3.nvr", "wb"); - break; - case ROM_IBMPS2_M70_TYPE4: f = nvrfopen("ibmps2_m70_type4.nvr", "wb"); - break; - case ROM_TULIP_TC7: f = nvrfopen("tulip_tc7.nvr", "wb"); - break; - case ROM_PB410A: f = nvrfopen("pb410a.nvr", "wb"); - break; - case ROM_BULL_MICRAL_45: f = nvrfopen("bull_micral_45.nvr", "wb"); - break; - case ROM_FIC_VA503P: f = nvrfopen("fic_va503p.nvr", "wb"); - break; - case ROM_CBM_SL386SX25: f = nvrfopen("cbm_sl386sx25.nvr", "wb"); - break; - case ROM_IBMPS1_2133_451: f = nvrfopen("ibmps1_2133.nvr", "wb"); - break; - case ROM_ECS_386_32: f = nvrfopen("ecs_386_32.nvr", "wb"); - break; - case ROM_VS440FX: f = nvrfopen("vs440fx.nvr", "wb"); - break; - case ROM_GA686BX: f = nvrfopen("ga686bx.nvr", "wb"); - break; + FILE *f; + switch (oldromset) { + case ROM_PC1512: + f = nvrfopen("pc1512.nvr", "wb"); + break; + case ROM_PC1640: + f = nvrfopen("pc1640.nvr", "wb"); + break; + case ROM_PC200: + f = nvrfopen("pc200.nvr", "wb"); + break; + case ROM_PC2086: + f = nvrfopen("pc2086.nvr", "wb"); + break; + case ROM_PC3086: + f = nvrfopen("pc3086.nvr", "wb"); + break; + case ROM_PC5086: + f = nvrfopen("pc5086.nvr", "wb"); + break; + case ROM_PPC512: + f = nvrfopen("ppc512.nvr", "wb"); + break; + case ROM_IBMAT: + f = nvrfopen("at.nvr", "wb"); + break; + case ROM_IBMXT286: + f = nvrfopen("ibmxt286.nvr", "wb"); + break; + case ROM_IBMPS1_2011: + f = nvrfopen("ibmps1_2011.nvr", "wb"); + break; + case ROM_IBMPS1_2121: + f = nvrfopen("ibmps1_2121.nvr", "wb"); + break; + case ROM_IBMPS2_M30_286: + f = nvrfopen("ibmps2_m30_286.nvr", "wb"); + break; + case ROM_IBMPS2_M50: + f = nvrfopen("ibmps2_m50.nvr", "wb"); + break; + case ROM_IBMPS2_M55SX: + f = nvrfopen("ibmps2_m55sx.nvr", "wb"); + break; + case ROM_IBMPS2_M80: + f = nvrfopen("ibmps2_m80.nvr", "wb"); + break; + case ROM_CMDPC30: + f = nvrfopen("cmdpc30.nvr", "wb"); + break; + case ROM_AMI286: + f = nvrfopen("ami286.nvr", "wb"); + break; + case ROM_TG286M: + f = nvrfopen("tg286m.nvr", "wb"); + break; + case ROM_AWARD286: + f = nvrfopen("award286.nvr", "wb"); + break; + case ROM_GDC212M: + f = nvrfopen("gdc212m.nvr", "wb"); + break; + case ROM_HYUNDAI_SUPER286TR: + f = nvrfopen("super286tr.nvr", "wb"); + break; + case ROM_GW286CT: + f = nvrfopen("gw286ct.nvr", "wb"); + break; + case ROM_SPC4200P: + f = nvrfopen("spc4200p.nvr", "wb"); + break; + case ROM_SPC4216P: + f = nvrfopen("spc4216p.nvr", "wb"); + break; + case ROM_SPC4620P: + f = nvrfopen("spc4620p.nvr", "wb"); + break; + case ROM_SPC6000A: + f = nvrfopen("spc6000a.nvr", "wb"); + break; + case ROM_SPC6033P: + f = nvrfopen("spc6033p.nvr", "wb"); + break; + case ROM_DELL200: + f = nvrfopen("dell200.nvr", "wb"); + break; + case ROM_IBMAT386: + f = nvrfopen("at386.nvr", "wb"); + break; + case ROM_DESKPRO_386: + f = nvrfopen("deskpro386.nvr", "wb"); + break; + case ROM_ACER386: + f = nvrfopen("acer386.nvr", "wb"); + break; + case ROM_KMXC02: + f = nvrfopen("kmxc02.nvr", "wb"); + break; + case ROM_MEGAPC: + f = nvrfopen("megapc.nvr", "wb"); + break; + case ROM_AMA932J: + f = nvrfopen("ama932j.nvr", "wb"); + break; + case ROM_AMI386SX: + f = nvrfopen("ami386.nvr", "wb"); + break; + case ROM_AMI486: + f = nvrfopen("ami486.nvr", "wb"); + break; + case ROM_WIN486: + f = nvrfopen("win486.nvr", "wb"); + break; + case ROM_PCI486: + f = nvrfopen("hot-433.nvr", "wb"); + break; + case ROM_SIS496: + f = nvrfopen("sis496.nvr", "wb"); + break; + case ROM_P55VA: + f = nvrfopen("p55va.nvr", "wb"); + break; + case ROM_P55TVP4: + f = nvrfopen("p55tvp4.nvr", "wb"); + break; + case ROM_430VX: + f = nvrfopen("430vx.nvr", "wb"); + break; + case ROM_REVENGE: + f = nvrfopen("revenge.nvr", "wb"); + break; + case ROM_ENDEAVOR: + f = nvrfopen("endeavor.nvr", "wb"); + break; + case ROM_P55T2P4: + f = nvrfopen("p55t2p4.nvr", "wb"); + break; + case ROM_PX386: + f = nvrfopen("px386.nvr", "wb"); + break; + case ROM_DTK386: + f = nvrfopen("dtk386.nvr", "wb"); + break; + case ROM_MR386DX_OPTI495: + f = nvrfopen("mr386dx_opti495.nvr", "wb"); + break; + case ROM_AMI386DX_OPTI495: + f = nvrfopen("ami386dx_opti495.nvr", "wb"); + break; + case ROM_EPSON_PCAX: + f = nvrfopen("epson_pcax.nvr", "wb"); + break; + case ROM_EPSON_PCAX2E: + f = nvrfopen("epson_pcax2e.nvr", "wb"); + break; + case ROM_EPSON_PCAX3: + f = nvrfopen("epson_pcax3.nvr", "wb"); + break; + case ROM_COMPAQ_PII: + f = nvrfopen("compaq_pii.nvr", "wb"); + break; + case ROM_PB_L300SX: + f = nvrfopen("pb_l300sx.nvr", "wb"); + break; + case ROM_T3100E: + f = nvrfopen("t3100e.nvr", "wb"); + break; + case ROM_T1000: + tc8521_savenvr(); + t1000_configsys_savenvr(); + t1000_emsboard_savenvr(); + return; + case ROM_T1200: + tc8521_savenvr(); + t1200_state_savenvr(); + t1000_emsboard_savenvr(); + return; + case ROM_ELX_PC425X: + f = nvrfopen("elx_pc425.nvr", "wb"); + break; + case ROM_PB570: + f = nvrfopen("pb570.nvr", "wb"); + break; + case ROM_ZAPPA: + f = nvrfopen("zappa.nvr", "wb"); + break; + case ROM_ITAUTEC_INFOWAYM: + f = nvrfopen("infowaym.nvr", "wb"); + break; + case ROM_PB520R: + f = nvrfopen("pb520r.nvr", "wb"); + break; + case ROM_XI8088: + f = nvrfopen("xi8088.nvr", "wb"); + break; + case ROM_IBMPS2_M70_TYPE3: + f = nvrfopen("ibmps2_m70_type3.nvr", "wb"); + break; + case ROM_IBMPS2_M70_TYPE4: + f = nvrfopen("ibmps2_m70_type4.nvr", "wb"); + break; + case ROM_TULIP_TC7: + f = nvrfopen("tulip_tc7.nvr", "wb"); + break; + case ROM_PB410A: + f = nvrfopen("pb410a.nvr", "wb"); + break; + case ROM_BULL_MICRAL_45: + f = nvrfopen("bull_micral_45.nvr", "wb"); + break; + case ROM_FIC_VA503P: + f = nvrfopen("fic_va503p.nvr", "wb"); + break; + case ROM_CBM_SL386SX25: + f = nvrfopen("cbm_sl386sx25.nvr", "wb"); + break; + case ROM_IBMPS1_2133_451: + f = nvrfopen("ibmps1_2133.nvr", "wb"); + break; + case ROM_ECS_386_32: + f = nvrfopen("ecs_386_32.nvr", "wb"); + break; + case ROM_VS440FX: + f = nvrfopen("vs440fx.nvr", "wb"); + break; + case ROM_GA686BX: + f = nvrfopen("ga686bx.nvr", "wb"); + break; - default: return; - } - fwrite(nvrram, 128, 1, f); - fclose(f); + default: + return; + } + fwrite(nvrram, 128, 1, f); + fclose(f); } static void *nvr_init() { - nvr_t *nvr = (nvr_t *)malloc(sizeof(nvr_t)); - memset(nvr, 0, sizeof(nvr_t)); + nvr_t *nvr = (nvr_t *)malloc(sizeof(nvr_t)); + memset(nvr, 0, sizeof(nvr_t)); - io_sethandler(0x0070, 0x0002, readnvr, NULL, NULL, writenvr, NULL, NULL, nvr); - timer_add(&nvr->rtc_timer, nvr_rtc, nvr, 1); - timer_add(&nvr->onesec_timer, nvr_onesec, nvr, 1); - timer_add(&nvr->update_end_timer, nvr_update_end, nvr, 0); + io_sethandler(0x0070, 0x0002, readnvr, NULL, NULL, writenvr, NULL, NULL, nvr); + timer_add(&nvr->rtc_timer, nvr_rtc, nvr, 1); + timer_add(&nvr->onesec_timer, nvr_onesec, nvr, 1); + timer_add(&nvr->update_end_timer, nvr_update_end, nvr, 0); - return nvr; + return nvr; } static void nvr_close(void *p) { - nvr_t *nvr = (nvr_t *)p; + nvr_t *nvr = (nvr_t *)p; - free(nvr); + free(nvr); } -device_t nvr_device = - { - "Motorola MC146818 RTC", - 0, - nvr_init, - nvr_close, - NULL, - nvr_speed_changed, - NULL, - NULL, - NULL - }; +device_t nvr_device = {"Motorola MC146818 RTC", 0, nvr_init, nvr_close, NULL, nvr_speed_changed, NULL, NULL, NULL}; diff --git a/src/devices/ps2_nvr.c b/src/devices/ps2_nvr.c index 1c2bddfd..6240980f 100644 --- a/src/devices/ps2_nvr.c +++ b/src/devices/ps2_nvr.c @@ -6,89 +6,91 @@ #include "nvr.h" typedef struct ps2_nvr_t { - int addr; - uint8_t ram[8192]; + int addr; + uint8_t ram[8192]; } ps2_nvr_t; static uint8_t ps2_nvr_read(uint16_t port, void *p) { - ps2_nvr_t *nvr = (ps2_nvr_t *)p; + ps2_nvr_t *nvr = (ps2_nvr_t *)p; - switch (port) { - case 0x74:return nvr->addr & 0xff; - case 0x75:return nvr->addr >> 8; - case 0x76:return nvr->ram[nvr->addr]; - } + switch (port) { + case 0x74: + return nvr->addr & 0xff; + case 0x75: + return nvr->addr >> 8; + case 0x76: + return nvr->ram[nvr->addr]; + } - return 0xff; + return 0xff; } static void ps2_nvr_write(uint16_t port, uint8_t val, void *p) { - ps2_nvr_t *nvr = (ps2_nvr_t *)p; + ps2_nvr_t *nvr = (ps2_nvr_t *)p; -// pclog("ps2_nvr_write: port=%04x val=%02x\n", port, val); - 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; - } + // pclog("ps2_nvr_write: port=%04x val=%02x\n", port, val); + 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() { - ps2_nvr_t *nvr = (ps2_nvr_t *)malloc(sizeof(ps2_nvr_t)); - FILE *f = NULL; + ps2_nvr_t *nvr = (ps2_nvr_t *)malloc(sizeof(ps2_nvr_t)); + FILE *f = NULL; - memset(nvr, 0, sizeof(ps2_nvr_t)); + memset(nvr, 0, sizeof(ps2_nvr_t)); - io_sethandler(0x0074, 0x0003, ps2_nvr_read, NULL, NULL, ps2_nvr_write, NULL, NULL, nvr); + io_sethandler(0x0074, 0x0003, ps2_nvr_read, NULL, NULL, ps2_nvr_write, NULL, NULL, nvr); - switch (romset) { - case ROM_IBMPS2_M70_TYPE3:f = nvrfopen("ibmps2_m70_type3_sec.nvr", "rb"); - break; - case ROM_IBMPS2_M70_TYPE4:f = nvrfopen("ibmps2_m70_type4_sec.nvr", "rb"); - break; - case ROM_IBMPS2_M80: f = nvrfopen("ibmps2_m80_sec.nvr", "rb"); - break; - } - if (f) { - fread(nvr->ram, 8192, 1, f); - fclose(f); - } else - memset(nvr->ram, 0xFF, 8192); + switch (romset) { + case ROM_IBMPS2_M70_TYPE3: + f = nvrfopen("ibmps2_m70_type3_sec.nvr", "rb"); + break; + case ROM_IBMPS2_M70_TYPE4: + f = nvrfopen("ibmps2_m70_type4_sec.nvr", "rb"); + break; + case ROM_IBMPS2_M80: + f = nvrfopen("ibmps2_m80_sec.nvr", "rb"); + break; + } + if (f) { + fread(nvr->ram, 8192, 1, f); + fclose(f); + } else + memset(nvr->ram, 0xFF, 8192); - return nvr; + return nvr; } static void ps2_nvr_close(void *p) { - ps2_nvr_t *nvr = (ps2_nvr_t *)p; - FILE *f = NULL; + ps2_nvr_t *nvr = (ps2_nvr_t *)p; + FILE *f = NULL; - switch (romset) { - case ROM_IBMPS2_M70_TYPE3:f = nvrfopen("ibmps2_m70_type3_sec.nvr", "wb"); - break; - case ROM_IBMPS2_M70_TYPE4:f = nvrfopen("ibmps2_m70_type4_sec.nvr", "wb"); - break; - case ROM_IBMPS2_M80: f = nvrfopen("ibmps2_m80_sec.nvr", "wb"); - break; - } - if (f) { - fwrite(nvr->ram, 8192, 1, f); - fclose(f); - } + switch (romset) { + case ROM_IBMPS2_M70_TYPE3: + f = nvrfopen("ibmps2_m70_type3_sec.nvr", "wb"); + break; + case ROM_IBMPS2_M70_TYPE4: + f = nvrfopen("ibmps2_m70_type4_sec.nvr", "wb"); + break; + case ROM_IBMPS2_M80: + f = nvrfopen("ibmps2_m80_sec.nvr", "wb"); + break; + } + if (f) { + fwrite(nvr->ram, 8192, 1, f); + fclose(f); + } - free(nvr); + free(nvr); } -device_t ps2_nvr_device = - { - "PS/2 NVRRAM", - 0, - ps2_nvr_init, - ps2_nvr_close, - NULL, - NULL, - NULL, - NULL - }; +device_t ps2_nvr_device = {"PS/2 NVRRAM", 0, ps2_nvr_init, ps2_nvr_close, NULL, NULL, NULL, NULL}; diff --git a/src/devices/sis496.c b/src/devices/sis496.c index 845d76fd..724a9d72 100644 --- a/src/devices/sis496.c +++ b/src/devices/sis496.c @@ -9,137 +9,131 @@ #include "sis496.h" typedef struct sis496_t { - uint8_t pci_conf[256]; + uint8_t pci_conf[256]; } sis496_t; void sis496_recalcmapping(sis496_t *sis496) { - int c; + int c; - for (c = 0; c < 8; c++) { - uint32_t base = 0xc0000 + (c << 15); - if (sis496->pci_conf[0x44] & (1 << c)) { - switch (sis496->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); - } + for (c = 0; c < 8; c++) { + uint32_t base = 0xc0000 + (c << 15); + if (sis496->pci_conf[0x44] & (1 << c)) { + switch (sis496->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(); + flushmmucache(); } void sis496_write(int func, int addr, uint8_t val, void *p) { - sis496_t *sis496 = (sis496_t *)p; - //pclog("sis496_write : addr=%02x val=%02x\n", addr, val); - switch (addr) { - case 0x44: /*Shadow configure*/ - if ((sis496->pci_conf[0x44] & val) ^ 0xf0) { - sis496->pci_conf[0x44] = val; - sis496_recalcmapping(sis496); - } - break; - case 0x45: /*Shadow configure*/ - if ((sis496->pci_conf[0x45] & val) ^ 0x01) { - sis496->pci_conf[0x45] = val; - sis496_recalcmapping(sis496); - } - break; + sis496_t *sis496 = (sis496_t *)p; + // pclog("sis496_write : addr=%02x val=%02x\n", addr, val); + switch (addr) { + case 0x44: /*Shadow configure*/ + if ((sis496->pci_conf[0x44] & val) ^ 0xf0) { + sis496->pci_conf[0x44] = val; + sis496_recalcmapping(sis496); + } + break; + case 0x45: /*Shadow configure*/ + if ((sis496->pci_conf[0x45] & val) ^ 0x01) { + sis496->pci_conf[0x45] = val; + sis496_recalcmapping(sis496); + } + break; - case 0xc0: - // pclog("IRQ routing %02x %02x\n", addr, val); - if (val & 0x80) - pci_set_irq_routing(PCI_INTA, val & 0xf); - else - pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED); - break; - case 0xc1: -// pclog("IRQ routing %02x %02x\n", addr, val); - if (val & 0x80) - pci_set_irq_routing(PCI_INTB, val & 0xf); - else - pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED); - break; - case 0xc2: -// pclog("IRQ routing %02x %02x\n", addr, val); - if (val & 0x80) - pci_set_irq_routing(PCI_INTC, val & 0xf); - else - pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED); - break; - case 0xc3: -// pclog("IRQ routing %02x %02x\n", addr, val); - if (val & 0x80) - pci_set_irq_routing(PCI_INTD, val & 0xf); - else - pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); - break; - } + case 0xc0: + // pclog("IRQ routing %02x %02x\n", addr, val); + if (val & 0x80) + pci_set_irq_routing(PCI_INTA, val & 0xf); + else + pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED); + break; + case 0xc1: + // pclog("IRQ routing %02x %02x\n", addr, val); + if (val & 0x80) + pci_set_irq_routing(PCI_INTB, val & 0xf); + else + pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED); + break; + case 0xc2: + // pclog("IRQ routing %02x %02x\n", addr, val); + if (val & 0x80) + pci_set_irq_routing(PCI_INTC, val & 0xf); + else + pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED); + break; + case 0xc3: + // pclog("IRQ routing %02x %02x\n", addr, val); + 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) - sis496->pci_conf[addr] = val; + if ((addr >= 4 && addr < 8) || addr >= 0x40) + sis496->pci_conf[addr] = val; } uint8_t sis496_read(int func, int addr, void *p) { - sis496_t *sis496 = (sis496_t *)p; + sis496_t *sis496 = (sis496_t *)p; - return sis496->pci_conf[addr]; + return sis496->pci_conf[addr]; } void *sis496_init() { - sis496_t *sis496 = malloc(sizeof(sis496_t)); - memset(sis496, 0, sizeof(sis496_t)); + sis496_t *sis496 = malloc(sizeof(sis496_t)); + memset(sis496, 0, sizeof(sis496_t)); - pci_add_specific(5, sis496_read, sis496_write, sis496); + pci_add_specific(5, sis496_read, sis496_write, sis496); - 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[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[0x04] = 7; + sis496->pci_conf[0x05] = 0; - sis496->pci_conf[0x06] = 0x80; - sis496->pci_conf[0x07] = 0x02; + sis496->pci_conf[0x06] = 0x80; + sis496->pci_conf[0x07] = 0x02; - sis496->pci_conf[0x08] = 2; /*Device revision*/ + 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[0x09] = 0x00; /*Device class (PCI bridge)*/ + sis496->pci_conf[0x0a] = 0x00; + sis496->pci_conf[0x0b] = 0x06; - sis496->pci_conf[0x0e] = 0x00; /*Single function device*/ + sis496->pci_conf[0x0e] = 0x00; /*Single function device*/ - pci_set_card_routing(15, PCI_INTA); - pci_set_card_routing(13, PCI_INTD); - pci_set_card_routing(11, PCI_INTC); + pci_set_card_routing(15, PCI_INTA); + pci_set_card_routing(13, PCI_INTD); + pci_set_card_routing(11, PCI_INTC); - pic_init_elcrx(); + pic_init_elcrx(); - return sis496; + return sis496; } void sis496_close(void *p) { - sis496_t *sis496 = (sis496_t *)p; + sis496_t *sis496 = (sis496_t *)p; - free(sis496); + free(sis496); } -device_t sis496_device = - { - "SiS 496/497", - 0, - sis496_init, - sis496_close, - NULL, - NULL, - NULL, - NULL - }; +device_t sis496_device = {"SiS 496/497", 0, sis496_init, sis496_close, NULL, NULL, NULL, NULL}; diff --git a/src/disc/disc.c b/src/disc/disc.c index a47dd022..95652aa4 100644 --- a/src/disc/disc.c +++ b/src/disc/disc.c @@ -19,7 +19,7 @@ int drive_type[2]; int curdrive = 0; -//char discfns[2][260] = {"", ""}; +// char discfns[2][260] = {"", ""}; int defaultwriteprot = 0; int fdc_ready; @@ -45,234 +45,225 @@ void (*fdc_sectorid)(uint8_t track, uint8_t side, uint8_t sector, uint8_t size, void (*fdc_indexpulse)();*/ static struct { - char *ext; - void (*load)(int drive, char *fn); - void (*close)(int drive); - int size; -} - loaders[] = - { - {"IMG", img_load, img_close, -1}, - {"IMA", img_load, img_close, -1}, - {"360", img_load, img_close, -1}, - {"XDF", img_load, img_close, -1}, - {"FDI", fdi_load, fdi_close, -1}, - {0, 0, 0} - }; + char *ext; + void (*load)(int drive, char *fn); + void (*close)(int drive); + int size; +} loaders[] = {{"IMG", img_load, img_close, -1}, {"IMA", img_load, img_close, -1}, {"360", img_load, img_close, -1}, + {"XDF", img_load, img_close, -1}, {"FDI", fdi_load, fdi_close, -1}, {0, 0, 0}}; static int driveloaders[4]; void disc_load(int drive, char *fn) { - int c = 0, size; - char *p; - FILE *f; -// pclog("disc_load %i %s\n", drive, fn); -// setejecttext(drive, ""); - if (!fn) - return; - p = get_extension(fn); - if (!p) - return; -// setejecttext(drive, fn); - pclog("Loading :%i %s %s\n", drive, fn, p); - f = fopen(fn, "rb"); - if (!f) - return; - fseek(f, -1, SEEK_END); - size = ftell(f) + 1; - fclose(f); - while (loaders[c].ext) { - if (!strcasecmp(p, loaders[c].ext) && (size == loaders[c].size || loaders[c].size == -1)) { - pclog("Loading as %s\n", p); - driveloaders[drive] = c; - loaders[c].load(drive, fn); - drive_empty[drive] = 0; - disc_changed[drive] = 1; - strcpy(discfns[drive], fn); - fdd_disc_changed(drive); - return; - } - c++; - } - pclog("Couldn't load %s %s\n", fn, p); - drive_empty[drive] = 1; - discfns[drive][0] = 0; + int c = 0, size; + char *p; + FILE *f; + // pclog("disc_load %i %s\n", drive, fn); + // setejecttext(drive, ""); + if (!fn) + return; + p = get_extension(fn); + if (!p) + return; + // setejecttext(drive, fn); + pclog("Loading :%i %s %s\n", drive, fn, p); + f = fopen(fn, "rb"); + if (!f) + return; + fseek(f, -1, SEEK_END); + size = ftell(f) + 1; + fclose(f); + while (loaders[c].ext) { + if (!strcasecmp(p, loaders[c].ext) && (size == loaders[c].size || loaders[c].size == -1)) { + pclog("Loading as %s\n", p); + driveloaders[drive] = c; + loaders[c].load(drive, fn); + drive_empty[drive] = 0; + disc_changed[drive] = 1; + strcpy(discfns[drive], fn); + fdd_disc_changed(drive); + return; + } + c++; + } + pclog("Couldn't load %s %s\n", fn, p); + drive_empty[drive] = 1; + discfns[drive][0] = 0; } void disc_close(int drive) { -// pclog("disc_close %i\n", drive); - if (loaders[driveloaders[drive]].close) - loaders[driveloaders[drive]].close(drive); - drive_empty[drive] = 1; - discfns[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].readaddress = NULL; - drives[drive].format = NULL; + // pclog("disc_close %i\n", drive); + if (loaders[driveloaders[drive]].close) + loaders[driveloaders[drive]].close(drive); + drive_empty[drive] = 1; + discfns[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].readaddress = NULL; + drives[drive].format = NULL; } int disc_notfound = 0; static int disc_period = 32; int disc_hole(int drive) { - drive ^= fdd_swap; + drive ^= fdd_swap; - if (drive < 2 && drives[drive].hole) { - return drives[drive].hole(drive); - } else { - return 0; - } + if (drive < 2 && drives[drive].hole) { + return drives[drive].hole(drive); + } else { + return 0; + } } void disc_poll() { - timer_advance_u64(&disc_poll_timer, disc_period * TIMER_USEC); + timer_advance_u64(&disc_poll_timer, disc_period * TIMER_USEC); - if (disc_drivesel < 2 && drives[disc_drivesel].poll) - drives[disc_drivesel].poll(); + if (disc_drivesel < 2 && drives[disc_drivesel].poll) + drives[disc_drivesel].poll(); - if (disc_notfound) { - disc_notfound--; - if (!disc_notfound) - fdc_notfound(FDC_STATUS_AM_NOT_FOUND); - } + if (disc_notfound) { + disc_notfound--; + if (!disc_notfound) + fdc_notfound(FDC_STATUS_AM_NOT_FOUND); + } } int disc_get_bitcell_period(int rate) { - int bit_rate = 0; + int bit_rate = 0; - 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; - } + 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*/ + return 1000000 / bit_rate * 2; /*Bitcell period in ns*/ } void disc_set_rate(int drive, int drvden, int rate) { - switch (rate) { - case 0: /*High density*/ - disc_period = 16; - break; - case 1: - switch (drvden) { - case 0: /*Double density (360 rpm)*/ - disc_period = 26; - break; - case 1: /*High density (360 rpm)*/ - disc_period = 16; - break; - case 2:disc_period = 4; - break; - } - case 2: /*Double density*/ - disc_period = 32; - break; - case 3: /*Extended density*/ - disc_period = 8; - break; - } + switch (rate) { + case 0: /*High density*/ + disc_period = 16; + break; + case 1: + switch (drvden) { + case 0: /*Double density (360 rpm)*/ + disc_period = 26; + break; + case 1: /*High density (360 rpm)*/ + disc_period = 16; + break; + case 2: + disc_period = 4; + break; + } + case 2: /*Double density*/ + disc_period = 32; + break; + case 3: /*Extended density*/ + disc_period = 8; + break; + } } void disc_reset() { - int drive; + int drive; - curdrive = 0; - disc_period = 32; - timer_add(&disc_poll_timer, disc_poll, NULL, 0); + curdrive = 0; + disc_period = 32; + timer_add(&disc_poll_timer, disc_poll, NULL, 0); - for (drive = 0; drive < 2; drive++) { - if (loaders[driveloaders[drive]].close) - loaders[driveloaders[drive]].close(drive); - drive_empty[drive] = 1; - drives[drive].hole = NULL; - drives[drive].poll = NULL; - drives[drive].seek = NULL; - drives[drive].readsector = NULL; - drives[drive].writesector = NULL; - drives[drive].readaddress = NULL; - drives[drive].format = NULL; - } + for (drive = 0; drive < 2; drive++) { + if (loaders[driveloaders[drive]].close) + loaders[driveloaders[drive]].close(drive); + drive_empty[drive] = 1; + drives[drive].hole = NULL; + drives[drive].poll = NULL; + drives[drive].seek = NULL; + drives[drive].readsector = NULL; + drives[drive].writesector = NULL; + drives[drive].readaddress = NULL; + drives[drive].format = NULL; + } } -void disc_init() { - disc_reset(); -} +void disc_init() { disc_reset(); } int oldtrack[2] = {0, 0}; void disc_seek(int drive, int track) { -// pclog("disc_seek: drive=%i track=%i\n", drive, track); - if (drive < 2 && drives[drive].seek) - drives[drive].seek(drive, track); -// if (track != oldtrack[drive]) -// fdc_discchange_clear(drive); -// ddnoise_seek(track - oldtrack[drive]); -// oldtrack[drive] = track; + // pclog("disc_seek: drive=%i track=%i\n", drive, track); + if (drive < 2 && drives[drive].seek) + drives[drive].seek(drive, track); + // if (track != oldtrack[drive]) + // fdc_discchange_clear(drive); + // ddnoise_seek(track - oldtrack[drive]); + // oldtrack[drive] = track; } void disc_readsector(int drive, int sector, int track, int side, int density, int sector_size) { - drive ^= fdd_swap; + drive ^= fdd_swap; - if (drive < 2 && drives[drive].readsector) - drives[drive].readsector(drive, sector, track, side, density, sector_size); - else - disc_notfound = 1000; + if (drive < 2 && drives[drive].readsector) + drives[drive].readsector(drive, sector, track, side, density, sector_size); + else + disc_notfound = 1000; } void disc_writesector(int drive, int sector, int track, int side, int density, int sector_size) { - drive ^= fdd_swap; + drive ^= fdd_swap; - if (drive < 2 && drives[drive].writesector) - drives[drive].writesector(drive, sector, track, side, density, sector_size); - else - disc_notfound = 1000; + if (drive < 2 && drives[drive].writesector) + drives[drive].writesector(drive, sector, track, side, density, sector_size); + else + disc_notfound = 1000; } void disc_readaddress(int drive, int track, int side, int density) { - drive ^= fdd_swap; + drive ^= fdd_swap; - if (drive < 2 && drives[drive].readaddress) - drives[drive].readaddress(drive, track, side, density); + if (drive < 2 && drives[drive].readaddress) + drives[drive].readaddress(drive, track, side, density); } void disc_format(int drive, int track, int side, int density, uint8_t fill) { - drive ^= fdd_swap; + drive ^= fdd_swap; - if (drive < 2 && drives[drive].format) - drives[drive].format(drive, track, side, density, fill); - else - disc_notfound = 1000; + if (drive < 2 && drives[drive].format) + drives[drive].format(drive, track, side, density, fill); + else + disc_notfound = 1000; } void disc_stop(int drive) { - drive ^= fdd_swap; + drive ^= fdd_swap; - if (drive < 2 && drives[drive].stop) - drives[drive].stop(drive); + if (drive < 2 && drives[drive].stop) + drives[drive].stop(drive); } void disc_set_drivesel(int drive) { - drive ^= fdd_swap; + drive ^= fdd_swap; - disc_drivesel = drive; + disc_drivesel = drive; } void disc_set_motor_enable(int motor_enable) { - if (motor_enable && !motoron) - timer_set_delay_u64(&disc_poll_timer, disc_period * TIMER_USEC); - else if (!motor_enable) - timer_disable(&disc_poll_timer); - motoron = motor_enable; + if (motor_enable && !motoron) + timer_set_delay_u64(&disc_poll_timer, disc_period * TIMER_USEC); + else if (!motor_enable) + timer_disable(&disc_poll_timer); + motoron = motor_enable; } diff --git a/src/disc/disc_fdi.c b/src/disc/disc_fdi.c index b647a696..68f62114 100644 --- a/src/disc/disc_fdi.c +++ b/src/disc/disc_fdi.c @@ -7,15 +7,15 @@ #include "fdi2raw.h" static struct { - FILE *f; - FDI *h; - uint8_t track_data[2][4][256 * 1024]; + FILE *f; + FDI *h; + uint8_t track_data[2][4][256 * 1024]; - int sides; - int tracklen[2][4]; - int trackindex[2][4]; + int sides; + int tracklen[2][4]; + int trackindex[2][4]; - int lasttrack; + int lasttrack; } fdi[2]; static uint8_t fdi_timing[256 * 1024]; @@ -30,188 +30,185 @@ static uint16_t CRCTable[256]; static int pollbytesleft = 0, pollbitsleft = 0; static void fdi_setupcrc(uint16_t poly, uint16_t rvalue) { - int c = 256, bc; - uint16_t crctemp; + int c = 256, bc; + uint16_t crctemp; - while (c--) { - crctemp = c << 8; - bc = 8; + while (c--) { + crctemp = c << 8; + bc = 8; - while (bc--) { - if (crctemp & 0x8000) { - crctemp = (crctemp << 1) ^ poly; - } else { - crctemp <<= 1; - } - } + while (bc--) { + if (crctemp & 0x8000) { + crctemp = (crctemp << 1) ^ poly; + } else { + crctemp <<= 1; + } + } - CRCTable[c] = crctemp; - } + CRCTable[c] = crctemp; + } } void fdi_init() { -// printf("FDI reset\n"); - memset(&fdi, 0, sizeof(fdi)); - fdi_setupcrc(0x1021, 0xcdb4); + // printf("FDI reset\n"); + memset(&fdi, 0, sizeof(fdi)); + fdi_setupcrc(0x1021, 0xcdb4); } int fdi_hole(int drive) { - switch (fdi2raw_get_bit_rate(fdi[drive].h)) { - case 1000:return 2; - case 500:return 1; - default:return 0; - } + switch (fdi2raw_get_bit_rate(fdi[drive].h)) { + case 1000: + return 2; + case 500: + return 1; + default: + return 0; + } } void fdi_load(int drive, char *fn) { - writeprot[drive] = fwriteprot[drive] = 1; - fdi[drive].f = fopen(fn, "rb"); - if (!fdi[drive].f) - return; - fdi[drive].h = fdi2raw_header(fdi[drive].f); -// if (!fdih[drive]) printf("Failed to load!\n"); - fdi[drive].lasttrack = fdi2raw_get_last_track(fdi[drive].h); - fdi[drive].sides = fdi2raw_get_last_head(fdi[drive].h) + 1; -// printf("Last track %i\n",fdilasttrack[drive]); - drives[drive].seek = fdi_seek; - drives[drive].readsector = fdi_readsector; - drives[drive].writesector = fdi_writesector; - drives[drive].readaddress = fdi_readaddress; - drives[drive].hole = fdi_hole; - drives[drive].poll = fdi_poll; - drives[drive].format = fdi_format; - drives[drive].stop = fdi_stop; -// pclog("Loaded as FDI\n"); + writeprot[drive] = fwriteprot[drive] = 1; + fdi[drive].f = fopen(fn, "rb"); + if (!fdi[drive].f) + return; + fdi[drive].h = fdi2raw_header(fdi[drive].f); + // if (!fdih[drive]) printf("Failed to load!\n"); + fdi[drive].lasttrack = fdi2raw_get_last_track(fdi[drive].h); + fdi[drive].sides = fdi2raw_get_last_head(fdi[drive].h) + 1; + // printf("Last track %i\n",fdilasttrack[drive]); + drives[drive].seek = fdi_seek; + drives[drive].readsector = fdi_readsector; + drives[drive].writesector = fdi_writesector; + drives[drive].readaddress = fdi_readaddress; + drives[drive].hole = fdi_hole; + drives[drive].poll = fdi_poll; + drives[drive].format = fdi_format; + drives[drive].stop = fdi_stop; + // pclog("Loaded as FDI\n"); } void fdi_close(int drive) { - if (fdi[drive].h) - fdi2raw_header_free(fdi[drive].h); - if (fdi[drive].f) - fclose(fdi[drive].f); - fdi[drive].f = NULL; + if (fdi[drive].h) + fdi2raw_header_free(fdi[drive].h); + if (fdi[drive].f) + fclose(fdi[drive].f); + fdi[drive].f = NULL; } void fdi_seek(int drive, int track) { - int density; + int density; - if (!fdi[drive].f) - return; -// printf("Track start %i\n",track); - if (track < 0) - track = 0; - if (track > fdi[drive].lasttrack) - track = fdi[drive].lasttrack - 1; + if (!fdi[drive].f) + return; + // printf("Track start %i\n",track); + if (track < 0) + track = 0; + if (track > fdi[drive].lasttrack) + track = fdi[drive].lasttrack - 1; - for (density = 0; density < 4; density++) { - int c = fdi2raw_loadtrack(fdi[drive].h, (uint16_t *)fdi[drive].track_data[0][density], - (uint16_t *)fdi_timing, - track * fdi[drive].sides, - &fdi[drive].tracklen[0][density], - &fdi[drive].trackindex[0][density], NULL, density); - if (!c) - memset(fdi[drive].track_data[0][density], 0, fdi[drive].tracklen[0][density]); + for (density = 0; density < 4; density++) { + int c = fdi2raw_loadtrack(fdi[drive].h, (uint16_t *)fdi[drive].track_data[0][density], (uint16_t *)fdi_timing, + track * fdi[drive].sides, &fdi[drive].tracklen[0][density], + &fdi[drive].trackindex[0][density], NULL, density); + if (!c) + memset(fdi[drive].track_data[0][density], 0, fdi[drive].tracklen[0][density]); - if (fdi[drive].sides == 2) { - c = fdi2raw_loadtrack(fdi[drive].h, (uint16_t *)fdi[drive].track_data[1][density], - (uint16_t *)fdi_timing, - (track * fdi[drive].sides) + 1, - &fdi[drive].tracklen[1][density], - &fdi[drive].trackindex[1][density], NULL, density); - if (!c) - memset(fdi[drive].track_data[1][density], 0, fdi[drive].tracklen[1][density]); - } else { - memset(fdi[drive].track_data[1][density], 0, 65536); - fdi[drive].tracklen[1][density] = fdi[drive].trackindex[1][density] = 10000; - } - } + if (fdi[drive].sides == 2) { + c = fdi2raw_loadtrack(fdi[drive].h, (uint16_t *)fdi[drive].track_data[1][density], (uint16_t *)fdi_timing, + (track * fdi[drive].sides) + 1, &fdi[drive].tracklen[1][density], + &fdi[drive].trackindex[1][density], NULL, density); + if (!c) + memset(fdi[drive].track_data[1][density], 0, fdi[drive].tracklen[1][density]); + } else { + memset(fdi[drive].track_data[1][density], 0, 65536); + fdi[drive].tracklen[1][density] = fdi[drive].trackindex[1][density] = 10000; + } + } } -void fdi_writeback(int drive, int track) { - return; -} +void fdi_writeback(int drive, int track) { return; } void fdi_readsector(int drive, int sector, int track, int side, int rate, int sector_size) { - fdi_revs = 0; - fdi_sector = sector; - fdi_track = track; - fdi_side = side; - fdi_n = sector_size; - fdi_drive = drive; - if (rate == 2) - fdi_density = 1; - if (rate == 0) - fdi_density = 2; - if (rate == 3) - fdi_density = 3; + fdi_revs = 0; + fdi_sector = sector; + fdi_track = track; + fdi_side = side; + fdi_n = sector_size; + fdi_drive = drive; + if (rate == 2) + fdi_density = 1; + if (rate == 0) + fdi_density = 2; + if (rate == 3) + fdi_density = 3; -// pclog("FDI Read sector %i %i %i %i %i\n",drive,side,track,sector, fdi_density); -// if (pollbytesleft) -// pclog("In the middle of a sector!\n"); + // pclog("FDI Read sector %i %i %i %i %i\n",drive,side,track,sector, fdi_density); + // if (pollbytesleft) + // pclog("In the middle of a sector!\n"); - fdi_inread = 1; - fdi_inwrite = 0; - fdi_inreadaddr = 0; - fdi_readpos = 0; + fdi_inread = 1; + fdi_inwrite = 0; + fdi_inreadaddr = 0; + fdi_readpos = 0; } void fdi_writesector(int drive, int sector, int track, int side, int rate, int sector_size) { - fdi_revs = 0; - fdi_sector = sector; - fdi_track = track; - fdi_side = side; - fdi_n = sector_size; - fdi_drive = drive; - if (rate == 2) - fdi_density = 1; - if (rate == 0) - fdi_density = 2; - if (rate == 3) - fdi_density = 3; -// pclog("Write sector %i %i %i %i\n",drive,side,track,sector); + fdi_revs = 0; + fdi_sector = sector; + fdi_track = track; + fdi_side = side; + fdi_n = sector_size; + fdi_drive = drive; + if (rate == 2) + fdi_density = 1; + if (rate == 0) + fdi_density = 2; + if (rate == 3) + fdi_density = 3; + // pclog("Write sector %i %i %i %i\n",drive,side,track,sector); - fdi_inread = 0; - fdi_inwrite = 1; - fdi_inreadaddr = 0; - fdi_readpos = 0; + fdi_inread = 0; + fdi_inwrite = 1; + fdi_inreadaddr = 0; + fdi_readpos = 0; } void fdi_readaddress(int drive, int track, int side, int rate) { - fdi_revs = 0; - fdi_track = track; - fdi_side = side; - fdi_drive = drive; - if (rate == 2) - fdi_density = 1; - if (rate == 0) - fdi_density = 2; - if (rate == 3) - fdi_density = 3; -// pclog("Read address %i %i %i %i %i %p\n",drive,side,track, rate, fdi_density, &fdi_inreadaddr); + fdi_revs = 0; + fdi_track = track; + fdi_side = side; + fdi_drive = drive; + if (rate == 2) + fdi_density = 1; + if (rate == 0) + fdi_density = 2; + if (rate == 3) + fdi_density = 3; + // pclog("Read address %i %i %i %i %i %p\n",drive,side,track, rate, fdi_density, &fdi_inreadaddr); - fdi_inread = 0; - fdi_inwrite = 0; - fdi_inreadaddr = 1; - fdi_readpos = 0; + fdi_inread = 0; + fdi_inwrite = 0; + fdi_inreadaddr = 1; + fdi_readpos = 0; } void fdi_format(int drive, int track, int side, int rate, uint8_t fill) { - fdi_revs = 0; - fdi_track = track; - fdi_side = side; - fdi_drive = drive; - if (rate == 2) - fdi_density = 1; - if (rate == 0) - fdi_density = 2; - if (rate == 3) - fdi_density = 3; -// pclog("Format %i %i %i\n",drive,side,track); + fdi_revs = 0; + fdi_track = track; + fdi_side = side; + fdi_drive = drive; + if (rate == 2) + fdi_density = 1; + if (rate == 0) + fdi_density = 2; + if (rate == 3) + fdi_density = 3; + // pclog("Format %i %i %i\n",drive,side,track); - fdi_inread = 0; - fdi_inwrite = 1; - fdi_inreadaddr = 0; - fdi_readpos = 0; + fdi_inread = 0; + fdi_inwrite = 1; + fdi_inreadaddr = 0; + fdi_readpos = 0; } static uint16_t fdi_buffer; @@ -222,201 +219,230 @@ static int sectorsize, fdc_sectorsize; static int ddidbitsleft = 0; static uint8_t decodefm(uint16_t dat) { - uint8_t temp; - temp = 0; - 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; + uint8_t temp; + temp = 0; + 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 fdi_stop() { -// pclog("fdi_stop\n"); - fdi_inread = fdi_inwrite = fdi_inreadaddr = 0; - fdi_nextsector = ddidbitsleft = pollbitsleft = 0; + // pclog("fdi_stop\n"); + fdi_inread = fdi_inwrite = fdi_inreadaddr = 0; + fdi_nextsector = ddidbitsleft = pollbitsleft = 0; } static uint16_t crc; -static void calccrc(uint8_t byte) { - crc = (crc << 8) ^ CRCTable[(crc >> 8) ^ byte]; -} +static void calccrc(uint8_t byte) { crc = (crc << 8) ^ CRCTable[(crc >> 8) ^ byte]; } static int fdi_indextime_blank = 6250 * 8; void fdi_poll() { - int tempi, c; - int bitcount; + int tempi, c; + int bitcount; - for (bitcount = 0; bitcount < 16; bitcount++) { - if (fdi_pos >= fdi[fdi_drive].tracklen[fdi_side][fdi_density]) { - fdi_pos = 0; - if (fdi[fdi_drive].tracklen[fdi_side][fdi_density]) - fdc_indexpulse(); - else { - fdi_indextime_blank--; - if (!fdi_indextime_blank) { - fdi_indextime_blank = 6250 * 8; - fdc_indexpulse(); - } - } - } - tempi = fdi[fdi_drive].track_data[fdi_side][fdi_density][((fdi_pos >> 3) & 0xFFFF) ^ 1] & (1 << (7 - (fdi_pos & 7))); - fdi_pos++; - fdi_buffer <<= 1; - fdi_buffer |= (tempi ? 1 : 0); - if (fdi_inwrite) { - fdi_inwrite = 0; - fdc_writeprotect(); - return; - } - if (!fdi_inread && !fdi_inreadaddr) - return; - if (fdi_pos == fdi[fdi_drive].trackindex[fdi_side][fdi_density]) { - fdi_revs++; - if (fdi_revs == 3) { -// pclog("Not found!\n"); - fdc_notfound(FDC_STATUS_NOT_FOUND); - fdi_inread = fdi_inreadaddr = 0; - return; - } - if (fdi_sector == SECTOR_FIRST) - fdi_sector = SECTOR_NEXT; - } - if (pollbitsleft) { - pollbitsleft--; - if (!pollbitsleft) { - pollbytesleft--; - if (pollbytesleft) - pollbitsleft = 16; /*Set up another word if we need it*/ - if (readidpoll) { - fdi_sectordat[5 - pollbytesleft] = decodefm(fdi_buffer); - if (!pollbytesleft) { -// pclog("Header over %i,%i %i,%i\n", fdi_sectordat[0], fdi_sectordat[2], fdi_track, fdi_sector); - if ((fdi_sectordat[0] == fdi_track && (fdi_sectordat[3] == fdi_n) && (fdi_sectordat[2] == fdi_sector || fdi_sector == SECTOR_NEXT)) || fdi_inreadaddr) { - crc = (fdi_density) ? 0xcdb4 : 0xffff; - calccrc(0xFE); - for (c = 0; c < 4; c++) - calccrc(fdi_sectordat[c]); + for (bitcount = 0; bitcount < 16; bitcount++) { + if (fdi_pos >= fdi[fdi_drive].tracklen[fdi_side][fdi_density]) { + fdi_pos = 0; + if (fdi[fdi_drive].tracklen[fdi_side][fdi_density]) + fdc_indexpulse(); + else { + fdi_indextime_blank--; + if (!fdi_indextime_blank) { + fdi_indextime_blank = 6250 * 8; + fdc_indexpulse(); + } + } + } + tempi = fdi[fdi_drive].track_data[fdi_side][fdi_density][((fdi_pos >> 3) & 0xFFFF) ^ 1] & + (1 << (7 - (fdi_pos & 7))); + fdi_pos++; + fdi_buffer <<= 1; + fdi_buffer |= (tempi ? 1 : 0); + if (fdi_inwrite) { + fdi_inwrite = 0; + fdc_writeprotect(); + return; + } + if (!fdi_inread && !fdi_inreadaddr) + return; + if (fdi_pos == fdi[fdi_drive].trackindex[fdi_side][fdi_density]) { + fdi_revs++; + if (fdi_revs == 3) { + // pclog("Not found!\n"); + fdc_notfound(FDC_STATUS_NOT_FOUND); + fdi_inread = fdi_inreadaddr = 0; + return; + } + if (fdi_sector == SECTOR_FIRST) + fdi_sector = SECTOR_NEXT; + } + if (pollbitsleft) { + pollbitsleft--; + if (!pollbitsleft) { + pollbytesleft--; + if (pollbytesleft) + pollbitsleft = 16; /*Set up another word if we need it*/ + if (readidpoll) { + fdi_sectordat[5 - pollbytesleft] = decodefm(fdi_buffer); + if (!pollbytesleft) { + // pclog("Header over %i,%i %i,%i\n", + // fdi_sectordat[0], fdi_sectordat[2], + // fdi_track, fdi_sector); + if ((fdi_sectordat[0] == fdi_track && (fdi_sectordat[3] == fdi_n) && + (fdi_sectordat[2] == fdi_sector || fdi_sector == SECTOR_NEXT)) || + fdi_inreadaddr) { + crc = (fdi_density) ? 0xcdb4 : 0xffff; + calccrc(0xFE); + for (c = 0; c < 4; c++) + calccrc(fdi_sectordat[c]); - if ((crc >> 8) != fdi_sectordat[4] || (crc & 0xFF) != fdi_sectordat[5]) { -// pclog("Header CRC error : %02X %02X %02X %02X\n",crc>>8,crc&0xFF,fdi_sectordat[4],fdi_sectordat[5]); -// dumpregs(); -// exit(-1); - inreadop = 0; - if (fdi_inreadaddr) - fdc_sectorid(fdi_sectordat[0], fdi_sectordat[1], fdi_sectordat[2], fdi_sectordat[3], fdi_sectordat[4], fdi_sectordat[5]); - else - fdc_headercrcerror(); - return; - } -// pclog("Sector %i,%i %i,%i\n", fdi_sectordat[0], fdi_sectordat[2], fdi_track, fdi_sector); - if (fdi_sectordat[0] == fdi_track && (fdi_sectordat[2] == fdi_sector || fdi_sector == SECTOR_NEXT) && fdi_inread && !fdi_inreadaddr) { - fdi_nextsector = 1; - readidpoll = 0; - sectorsize = (1 << (fdi_sectordat[3] + 7)) + 2; - fdc_sectorsize = fdi_sectordat[3]; - } - if (fdi_inreadaddr) { - fdc_sectorid(fdi_sectordat[0], fdi_sectordat[1], fdi_sectordat[2], fdi_sectordat[3], fdi_sectordat[4], fdi_sectordat[5]); - fdi_inreadaddr = 0; - } - } - } - } - if (readdatapoll) { -// pclog("readdatapoll %i %02x\n", pollbytesleft, decodefm(fdi_buffer)); - if (pollbytesleft > 1) { - calccrc(decodefm(fdi_buffer)); - } else - sectorcrc[1 - pollbytesleft] = decodefm(fdi_buffer); - if (!pollbytesleft) { - fdi_inread = 0; -//#if 0 - if ((crc >> 8) != sectorcrc[0] || (crc & 0xFF) != sectorcrc[1])// || (fditrack==79 && fdisect==4 && fdc_side&1)) - { -// pclog("Data CRC error : %02X %02X %02X %02X %i %04X %02X%02X\n",crc>>8,crc&0xFF,sectorcrc[0],sectorcrc[1],fdi_pos,crc,sectorcrc[0],sectorcrc[1]); - inreadop = 0; - fdc_data(decodefm(lastfdidat[1])); - fdc_finishread(); - fdc_datacrcerror(); - readdatapoll = 0; - return; - } -//#endif -// pclog("End of FDI read %02X %02X %02X %02X\n",crc>>8,crc&0xFF,sectorcrc[0],sectorcrc[1]); - fdc_data(decodefm(lastfdidat[1])); - fdc_finishread(); - } else if (lastfdidat[1] != 0) - fdc_data(decodefm(lastfdidat[1])); - lastfdidat[1] = lastfdidat[0]; - lastfdidat[0] = fdi_buffer; - if (!pollbytesleft) - readdatapoll = 0; - } - } - } - if (fdi_buffer == 0x4489 && fdi_density) { -// rpclog("Found sync\n"); - ddidbitsleft = 17; - } + if ((crc >> 8) != fdi_sectordat[4] || (crc & 0xFF) != fdi_sectordat[5]) { + // pclog("Header + // CRC + // error : + // %02X + // %02X + // %02X + // %02X\n",crc>>8,crc&0xFF,fdi_sectordat[4],fdi_sectordat[5]); + // dumpregs(); + // exit(-1); + inreadop = 0; + if (fdi_inreadaddr) + fdc_sectorid(fdi_sectordat[0], fdi_sectordat[1], + fdi_sectordat[2], fdi_sectordat[3], + fdi_sectordat[4], fdi_sectordat[5]); + else + fdc_headercrcerror(); + return; + } + // pclog("Sector %i,%i + // %i,%i\n", + // fdi_sectordat[0], + // fdi_sectordat[2], + // fdi_track, fdi_sector); + if (fdi_sectordat[0] == fdi_track && + (fdi_sectordat[2] == fdi_sector || fdi_sector == SECTOR_NEXT) && + fdi_inread && !fdi_inreadaddr) { + fdi_nextsector = 1; + readidpoll = 0; + sectorsize = (1 << (fdi_sectordat[3] + 7)) + 2; + fdc_sectorsize = fdi_sectordat[3]; + } + if (fdi_inreadaddr) { + fdc_sectorid(fdi_sectordat[0], fdi_sectordat[1], fdi_sectordat[2], + fdi_sectordat[3], fdi_sectordat[4], + fdi_sectordat[5]); + fdi_inreadaddr = 0; + } + } + } + } + if (readdatapoll) { + // pclog("readdatapoll %i %02x\n", pollbytesleft, + // decodefm(fdi_buffer)); + if (pollbytesleft > 1) { + calccrc(decodefm(fdi_buffer)); + } else + sectorcrc[1 - pollbytesleft] = decodefm(fdi_buffer); + if (!pollbytesleft) { + fdi_inread = 0; + //#if 0 + if ((crc >> 8) != sectorcrc[0] || + (crc & 0xFF) != + sectorcrc[1]) // || (fditrack==79 && fdisect==4 && fdc_side&1)) + { + // pclog("Data CRC error : + // %02X %02X %02X %02X %i + // %04X + // %02X%02X\n",crc>>8,crc&0xFF,sectorcrc[0],sectorcrc[1],fdi_pos,crc,sectorcrc[0],sectorcrc[1]); + inreadop = 0; + fdc_data(decodefm(lastfdidat[1])); + fdc_finishread(); + fdc_datacrcerror(); + readdatapoll = 0; + return; + } + //#endif + // pclog("End of FDI read %02X %02X %02X + // %02X\n",crc>>8,crc&0xFF,sectorcrc[0],sectorcrc[1]); + fdc_data(decodefm(lastfdidat[1])); + fdc_finishread(); + } else if (lastfdidat[1] != 0) + fdc_data(decodefm(lastfdidat[1])); + lastfdidat[1] = lastfdidat[0]; + lastfdidat[0] = fdi_buffer; + if (!pollbytesleft) + readdatapoll = 0; + } + } + } + if (fdi_buffer == 0x4489 && fdi_density) { + // rpclog("Found sync\n"); + ddidbitsleft = 17; + } - if (fdi_buffer == 0xF57E && !fdi_density) { - pollbytesleft = 6; - pollbitsleft = 16; - readidpoll = 1; - } - if ((fdi_buffer == 0xF56F || fdi_buffer == 0xF56A) && !fdi_density) { - if (fdi_nextsector) { - pollbytesleft = sectorsize; - pollbitsleft = 16; - readdatapoll = 1; - fdi_nextsector = 0; - crc = 0xffff; - if (fdi_buffer == 0xF56A) - calccrc(0xF8); - else - calccrc(0xFB); - lastfdidat[0] = lastfdidat[1] = 0; - } - } - if (ddidbitsleft) { - ddidbitsleft--; - if (!ddidbitsleft && !readdatapoll) { -// printf("ID bits over %04X %02X %i\n",fdibuffer,decodefm(fdibuffer),fdipos); - if (decodefm(fdi_buffer) == 0xFE) { -// printf("Sector header %i %i\n", fdi_inread, fdi_inreadaddr); - pollbytesleft = 6; - pollbitsleft = 16; - readidpoll = 1; - } else if (decodefm(fdi_buffer) == 0xFB) { -// printf("Data header %i %i\n", fdi_inread, fdi_inreadaddr); - if (fdi_nextsector) { - pollbytesleft = sectorsize; - pollbitsleft = 16; - readdatapoll = 1; - fdi_nextsector = 0; - crc = 0xcdb4; - if (fdi_buffer == 0xF56A) - calccrc(0xF8); - else - calccrc(0xFB); - lastfdidat[0] = lastfdidat[1] = 0; - } - } - } - } - } + if (fdi_buffer == 0xF57E && !fdi_density) { + pollbytesleft = 6; + pollbitsleft = 16; + readidpoll = 1; + } + if ((fdi_buffer == 0xF56F || fdi_buffer == 0xF56A) && !fdi_density) { + if (fdi_nextsector) { + pollbytesleft = sectorsize; + pollbitsleft = 16; + readdatapoll = 1; + fdi_nextsector = 0; + crc = 0xffff; + if (fdi_buffer == 0xF56A) + calccrc(0xF8); + else + calccrc(0xFB); + lastfdidat[0] = lastfdidat[1] = 0; + } + } + if (ddidbitsleft) { + ddidbitsleft--; + if (!ddidbitsleft && !readdatapoll) { + // printf("ID bits over %04X %02X + // %i\n",fdibuffer,decodefm(fdibuffer),fdipos); + if (decodefm(fdi_buffer) == 0xFE) { + // printf("Sector header %i %i\n", fdi_inread, + // fdi_inreadaddr); + pollbytesleft = 6; + pollbitsleft = 16; + readidpoll = 1; + } else if (decodefm(fdi_buffer) == 0xFB) { + // printf("Data header %i %i\n", fdi_inread, + // fdi_inreadaddr); + if (fdi_nextsector) { + pollbytesleft = sectorsize; + pollbitsleft = 16; + readdatapoll = 1; + fdi_nextsector = 0; + crc = 0xcdb4; + if (fdi_buffer == 0xF56A) + calccrc(0xF8); + else + calccrc(0xFB); + lastfdidat[0] = lastfdidat[1] = 0; + } + } + } + } + } } diff --git a/src/disc/disc_img.c b/src/disc/disc_img.c index d8b2f571..48aa53d5 100644 --- a/src/disc/disc_img.c +++ b/src/disc/disc_img.c @@ -5,14 +5,14 @@ #include "disc_sector.h" static struct { - FILE *f; - uint8_t track_data[2][20 * 1024]; - int sectors, tracks, sides; - int sector_size; - int rate; - int xdf_type; /* 0 = not XDF, 1-5 = one of the five XDF types */ - int hole; - double bitcell_period_300rpm; + FILE *f; + uint8_t track_data[2][20 * 1024]; + int sectors, tracks, sides; + int sector_size; + int rate; + int xdf_type; /* 0 = not XDF, 1-5 = one of the five XDF types */ + int hole; + double bitcell_period_300rpm; } img[2]; static uint8_t xdf_track0[5][3]; @@ -24,410 +24,416 @@ int bpb_disable; void img_writeback(int drive, int track); static int img_sector_size_code(int drive) { - switch (img[drive].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; - } + switch (img[drive].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; + } } void img_init() { - memset(img, 0, sizeof(img)); -// adl[0] = adl[1] = 0; + memset(img, 0, sizeof(img)); + // adl[0] = adl[1] = 0; } static void add_to_map(uint8_t *arr, uint8_t p1, uint8_t p2, uint8_t p3) { - arr[0] = p1; - arr[1] = p2; - arr[2] = p3; + arr[0] = p1; + arr[1] = p2; + arr[2] = p3; } static int xdf_maps_initialized = 0; static void initialize_xdf_maps() { - // XDF 5.25" 2HD - /* Adds, in this order: sectors per FAT, sectors per each side of track 0, difference between that and virtual sector number specified in BPB. */ - add_to_map(xdf_track0[0], 9, 17, 2); - xdf_spt[0] = 3; - /* Adds, in this order: side, sequential order (not used in PCem), sector size. */ - add_to_map(xdf_map[0][0], 0, 0, 3); - add_to_map(xdf_map[0][1], 0, 2, 6); - add_to_map(xdf_map[0][2], 1, 0, 2); - add_to_map(xdf_map[0][3], 0, 1, 2); - add_to_map(xdf_map[0][4], 1, 2, 6); - add_to_map(xdf_map[0][5], 1, 1, 3); + // XDF 5.25" 2HD + /* Adds, in this order: sectors per FAT, sectors per each side of track 0, difference between that and virtual sector + * number specified in BPB. */ + add_to_map(xdf_track0[0], 9, 17, 2); + xdf_spt[0] = 3; + /* Adds, in this order: side, sequential order (not used in PCem), sector size. */ + add_to_map(xdf_map[0][0], 0, 0, 3); + add_to_map(xdf_map[0][1], 0, 2, 6); + add_to_map(xdf_map[0][2], 1, 0, 2); + add_to_map(xdf_map[0][3], 0, 1, 2); + add_to_map(xdf_map[0][4], 1, 2, 6); + add_to_map(xdf_map[0][5], 1, 1, 3); - // XDF 3.5" 2HD - add_to_map(xdf_track0[1], 11, 19, 4); - xdf_spt[1] = 4; - add_to_map(xdf_map[1][0], 0, 0, 3); - add_to_map(xdf_map[1][1], 0, 2, 4); - add_to_map(xdf_map[1][2], 1, 3, 6); - add_to_map(xdf_map[1][3], 0, 1, 2); - add_to_map(xdf_map[1][4], 1, 1, 2); - add_to_map(xdf_map[1][5], 0, 3, 6); - add_to_map(xdf_map[1][6], 1, 0, 4); - add_to_map(xdf_map[1][7], 1, 2, 3); + // XDF 3.5" 2HD + add_to_map(xdf_track0[1], 11, 19, 4); + xdf_spt[1] = 4; + add_to_map(xdf_map[1][0], 0, 0, 3); + add_to_map(xdf_map[1][1], 0, 2, 4); + add_to_map(xdf_map[1][2], 1, 3, 6); + add_to_map(xdf_map[1][3], 0, 1, 2); + add_to_map(xdf_map[1][4], 1, 1, 2); + add_to_map(xdf_map[1][5], 0, 3, 6); + add_to_map(xdf_map[1][6], 1, 0, 4); + add_to_map(xdf_map[1][7], 1, 2, 3); - // XDF 3.5" 2ED - add_to_map(xdf_track0[2], 22, 37, 9); - xdf_spt[2] = 4; - add_to_map(xdf_map[2][0], 0, 0, 3); - add_to_map(xdf_map[2][1], 0, 1, 4); - add_to_map(xdf_map[2][2], 0, 2, 5); - add_to_map(xdf_map[2][3], 0, 3, 7); - add_to_map(xdf_map[2][4], 1, 0, 3); - add_to_map(xdf_map[2][5], 1, 1, 4); - add_to_map(xdf_map[2][6], 1, 2, 5); - add_to_map(xdf_map[2][7], 1, 3, 7); + // XDF 3.5" 2ED + add_to_map(xdf_track0[2], 22, 37, 9); + xdf_spt[2] = 4; + add_to_map(xdf_map[2][0], 0, 0, 3); + add_to_map(xdf_map[2][1], 0, 1, 4); + add_to_map(xdf_map[2][2], 0, 2, 5); + add_to_map(xdf_map[2][3], 0, 3, 7); + add_to_map(xdf_map[2][4], 1, 0, 3); + add_to_map(xdf_map[2][5], 1, 1, 4); + add_to_map(xdf_map[2][6], 1, 2, 5); + add_to_map(xdf_map[2][7], 1, 3, 7); - // XXDF 3.5" 2HD - add_to_map(xdf_track0[3], 12, 20, 4); - xdf_spt[3] = 2; - add_to_map(xdf_map[3][0], 0, 0, 5); - add_to_map(xdf_map[3][1], 1, 1, 6); - add_to_map(xdf_map[3][2], 0, 1, 6); - add_to_map(xdf_map[3][3], 1, 0, 5); + // XXDF 3.5" 2HD + add_to_map(xdf_track0[3], 12, 20, 4); + xdf_spt[3] = 2; + add_to_map(xdf_map[3][0], 0, 0, 5); + add_to_map(xdf_map[3][1], 1, 1, 6); + add_to_map(xdf_map[3][2], 0, 1, 6); + add_to_map(xdf_map[3][3], 1, 0, 5); - // XXDF 3.5" 2ED - add_to_map(xdf_track0[4], 21, 39, 9); - xdf_spt[4] = 2; - add_to_map(xdf_map[4][0], 0, 0, 6); - add_to_map(xdf_map[4][1], 1, 1, 7); - add_to_map(xdf_map[4][2], 0, 1, 7); - add_to_map(xdf_map[4][3], 1, 0, 6); + // XXDF 3.5" 2ED + add_to_map(xdf_track0[4], 21, 39, 9); + xdf_spt[4] = 2; + add_to_map(xdf_map[4][0], 0, 0, 6); + add_to_map(xdf_map[4][1], 1, 1, 7); + add_to_map(xdf_map[4][2], 0, 1, 7); + add_to_map(xdf_map[4][3], 1, 0, 6); - xdf_maps_initialized = 1; + xdf_maps_initialized = 1; } void img_load(int drive, char *fn) { - int size; - double bit_rate_300; - uint16_t bpb_bps; - uint16_t bpb_total; - uint8_t bpb_mid; /* Media type ID. */ - uint8_t bpb_sectors; - uint8_t bpb_sides; - uint32_t bpt; - uint8_t max_spt = 0; /* Used for XDF detection. */ + int size; + double bit_rate_300; + uint16_t bpb_bps; + uint16_t bpb_total; + uint8_t bpb_mid; /* Media type ID. */ + uint8_t bpb_sectors; + uint8_t bpb_sides; + uint32_t bpt; + uint8_t max_spt = 0; /* Used for XDF detection. */ - if (!xdf_maps_initialized) - initialize_xdf_maps(); /* Initialize XDF maps, will need them to properly register sectors in tracks. */ + if (!xdf_maps_initialized) + initialize_xdf_maps(); /* Initialize XDF maps, will need them to properly register sectors in tracks. */ - writeprot[drive] = 0; - img[drive].f = fopen(fn, "rb+"); - if (!img[drive].f) { - img[drive].f = fopen(fn, "rb"); - if (!img[drive].f) - return; - writeprot[drive] = 1; - } - fwriteprot[drive] = writeprot[drive]; + writeprot[drive] = 0; + img[drive].f = fopen(fn, "rb+"); + if (!img[drive].f) { + img[drive].f = fopen(fn, "rb"); + if (!img[drive].f) + return; + writeprot[drive] = 1; + } + fwriteprot[drive] = writeprot[drive]; - /* Read the BPB */ - fseek(img[drive].f, 0x0B, SEEK_SET); - fread(&bpb_bps, 1, 2, img[drive].f); - fseek(img[drive].f, 0x13, SEEK_SET); - fread(&bpb_total, 1, 2, img[drive].f); - fseek(img[drive].f, 0x15, SEEK_SET); - bpb_mid = fgetc(img[drive].f); - fseek(img[drive].f, 0x18, SEEK_SET); - bpb_sectors = fgetc(img[drive].f); - fseek(img[drive].f, 0x1A, SEEK_SET); - bpb_sides = fgetc(img[drive].f); + /* Read the BPB */ + fseek(img[drive].f, 0x0B, SEEK_SET); + fread(&bpb_bps, 1, 2, img[drive].f); + fseek(img[drive].f, 0x13, SEEK_SET); + fread(&bpb_total, 1, 2, img[drive].f); + fseek(img[drive].f, 0x15, SEEK_SET); + bpb_mid = fgetc(img[drive].f); + fseek(img[drive].f, 0x18, SEEK_SET); + bpb_sectors = fgetc(img[drive].f); + fseek(img[drive].f, 0x1A, SEEK_SET); + bpb_sides = fgetc(img[drive].f); - fseek(img[drive].f, -1, SEEK_END); - size = ftell(img[drive].f) + 1; + fseek(img[drive].f, -1, SEEK_END); + size = ftell(img[drive].f) + 1; - img[drive].sides = 2; - img[drive].sector_size = 512; + img[drive].sides = 2; + img[drive].sector_size = 512; - pclog("BPB reports %i sides and %i bytes per sector\n", bpb_sides, bpb_bps); + pclog("BPB reports %i sides and %i bytes per sector\n", bpb_sides, bpb_bps); - if (bpb_disable || (bpb_sides < 1) || (bpb_sides > 2) || (bpb_bps < 128) || (bpb_bps > 2048)) { - /* 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 (bpb_disable || (bpb_sides < 1) || (bpb_sides > 2) || (bpb_bps < 128) || (bpb_bps > 2048)) { + /* 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)) { - img[drive].sectors = 8; - img[drive].tracks = 40; - img[drive].sides = 1; - bit_rate_300 = 250; - } else if (size <= (180 * 1024)) { - img[drive].sectors = 9; - img[drive].tracks = 40; - img[drive].sides = 1; - bit_rate_300 = 250; - } else if (size <= (320 * 1024)) { - img[drive].sectors = 8; - img[drive].tracks = 40; - bit_rate_300 = 250; - } else if (size <= (360 * 1024)) { - img[drive].sectors = 9; - img[drive].tracks = 40; - bit_rate_300 = 250; - } /*Double density*/ - else if (size < (1024 * 1024)) { - img[drive].sectors = 9; - img[drive].tracks = 80; - bit_rate_300 = 250; - } /*Double density*/ - else if (size <= 1228800) { - img[drive].sectors = 15; - img[drive].tracks = 80; - bit_rate_300 = (500.0 * 300.0) / 360.0; - } /*High density 1.2MB*/ - else if (size <= (0x1A4000 - 1)) { - img[drive].sectors = 18; - img[drive].tracks = 80; - bit_rate_300 = 500; - } /*High density (not supported by Tandy 1000)*/ - // else if (size == 1884160) { img[drive].sectors = 23; img[drive].tracks = 80; bit_rate_300 = 500; } /*XDF format - used by OS/2 Warp*/ - // else if (size == 1763328) { img[drive].sectors = 21; img[drive].tracks = 82; bit_rate_300 = 500; } /*XDF format - used by OS/2 Warp*/ - else if (size <= 2000000) { - img[drive].sectors = 21; - img[drive].tracks = 80; - bit_rate_300 = 500; - } /*DMF format - used by Windows 95 - changed by OBattler to 2000000, ie. the real unformatted capacity @ 500 kbps and 300 rpm */ - else { - img[drive].sectors = 36; - img[drive].tracks = 80; - bit_rate_300 = 1000; - } /*E density*/ + if (size <= (160 * 1024)) { + img[drive].sectors = 8; + img[drive].tracks = 40; + img[drive].sides = 1; + bit_rate_300 = 250; + } else if (size <= (180 * 1024)) { + img[drive].sectors = 9; + img[drive].tracks = 40; + img[drive].sides = 1; + bit_rate_300 = 250; + } else if (size <= (320 * 1024)) { + img[drive].sectors = 8; + img[drive].tracks = 40; + bit_rate_300 = 250; + } else if (size <= (360 * 1024)) { + img[drive].sectors = 9; + img[drive].tracks = 40; + bit_rate_300 = 250; + } /*Double density*/ + else if (size < (1024 * 1024)) { + img[drive].sectors = 9; + img[drive].tracks = 80; + bit_rate_300 = 250; + } /*Double density*/ + else if (size <= 1228800) { + img[drive].sectors = 15; + img[drive].tracks = 80; + bit_rate_300 = (500.0 * 300.0) / 360.0; + } /*High density 1.2MB*/ + else if (size <= (0x1A4000 - 1)) { + img[drive].sectors = 18; + img[drive].tracks = 80; + bit_rate_300 = 500; + } /*High density (not supported by Tandy 1000)*/ + // else if (size == 1884160) { img[drive].sectors = 23; img[drive].tracks = 80; bit_rate_300 = 500; } /*XDF + // format - used by OS/2 Warp*/ else if (size == 1763328) { img[drive].sectors = 21; img[drive].tracks = 82; + // bit_rate_300 = 500; } /*XDF format - used by OS/2 Warp*/ + else if (size <= 2000000) { + img[drive].sectors = 21; + img[drive].tracks = 80; + bit_rate_300 = 500; + } /*DMF format - used by Windows 95 - changed by OBattler to 2000000, ie. the real unformatted capacity @ 500 kbps + and 300 rpm */ + else { + img[drive].sectors = 36; + img[drive].tracks = 80; + bit_rate_300 = 1000; + } /*E density*/ - img[drive].xdf_type = 0; - } else { - /* The BPB readings appear to be valid, so let's set the values. */ - /* Number of tracks = number of total sectors divided by sides times sectors per track. */ - img[drive].tracks = ((uint32_t)bpb_total) / (((uint32_t)bpb_sides) * ((uint32_t)bpb_sectors)); - /* The rest we just set directly from the BPB. */ - img[drive].sectors = bpb_sectors; - img[drive].sides = bpb_sides; - /* Now we calculate bytes per track, which is bpb_sectors * bpb_bps. */ - bpt = (uint32_t)bpb_sectors * (uint32_t)bpb_bps; - /* Now we should be able to calculate the bit rate. */ - pclog("The image has %i bytes per track\n", bpt); - if (bpt <= 6250) - bit_rate_300 = 250; /* Double-density */ - else if (bpt <= 7500) - bit_rate_300 = 300; /* Double-density, 300 kbps @ 300 rpm */ - else if (bpt <= 10416) { - bit_rate_300 = (bpb_mid == 0xF0) ? 500 : ((500.0 * 300.0) / 360.0); /* High-density @ 300 or 360 rpm, depending on media type ID */ - max_spt = (bpb_mid == 0xF0) ? 22 : 18; - } else if (bpt <= 12500) /* High-density @ 300 rpm */ - { - bit_rate_300 = 500; - max_spt = 22; - } else if (bpt <= 25000) /* Extended density @ 300 rpm */ - { - bit_rate_300 = 1000; - max_spt = 45; - } else /* Image too big, eject */ - { - pclog("Image has more than 25000 bytes per track, ejecting...\n"); - fclose(img[drive].f); - return; - } + img[drive].xdf_type = 0; + } else { + /* The BPB readings appear to be valid, so let's set the values. */ + /* Number of tracks = number of total sectors divided by sides times sectors per track. */ + img[drive].tracks = ((uint32_t)bpb_total) / (((uint32_t)bpb_sides) * ((uint32_t)bpb_sectors)); + /* The rest we just set directly from the BPB. */ + img[drive].sectors = bpb_sectors; + img[drive].sides = bpb_sides; + /* Now we calculate bytes per track, which is bpb_sectors * bpb_bps. */ + bpt = (uint32_t)bpb_sectors * (uint32_t)bpb_bps; + /* Now we should be able to calculate the bit rate. */ + pclog("The image has %i bytes per track\n", bpt); + if (bpt <= 6250) + bit_rate_300 = 250; /* Double-density */ + else if (bpt <= 7500) + bit_rate_300 = 300; /* Double-density, 300 kbps @ 300 rpm */ + else if (bpt <= 10416) { + bit_rate_300 = (bpb_mid == 0xF0) + ? 500 + : ((500.0 * 300.0) / + 360.0); /* High-density @ 300 or 360 rpm, depending on media type ID */ + max_spt = (bpb_mid == 0xF0) ? 22 : 18; + } else if (bpt <= 12500) /* High-density @ 300 rpm */ + { + bit_rate_300 = 500; + max_spt = 22; + } else if (bpt <= 25000) /* Extended density @ 300 rpm */ + { + bit_rate_300 = 1000; + max_spt = 45; + } else /* Image too big, eject */ + { + pclog("Image has more than 25000 bytes per track, ejecting...\n"); + fclose(img[drive].f); + return; + } - if (bpb_bps == 512) /* BPB reports 512 bytes per sector, let's see if it's XDF or not */ - { - if (bit_rate_300 <= 300) /* Double-density disk, not XDF */ - { - img[drive].xdf_type = 0; - } else { - if (bpb_sectors > max_spt) { - switch (bpb_sectors) { - case 19: /* High density XDF @ 360 rpm */ - img[drive].xdf_type = 1; - break; - case 23: /* High density XDF @ 300 rpm */ - img[drive].xdf_type = 2; - break; - case 24: /* High density XXDF @ 300 rpm */ - img[drive].xdf_type = 4; - break; - case 46: /* Extended density XDF */ - img[drive].xdf_type = 3; - break; - case 48: /* Extended density XXDF */ - img[drive].xdf_type = 5; - break; - default: /* Unknown, as we're beyond maximum sectors, get out */ - fclose(img[drive].f); - return; - } - } else /* Amount of sectors per track that fits into a track, therefore not XDF */ - { - img[drive].xdf_type = 0; - } - } - } else /* BPB reports sector size other than 512, can't possibly be XDF */ - { - img[drive].xdf_type = 0; - } - } + if (bpb_bps == 512) /* BPB reports 512 bytes per sector, let's see if it's XDF or not */ + { + if (bit_rate_300 <= 300) /* Double-density disk, not XDF */ + { + img[drive].xdf_type = 0; + } else { + if (bpb_sectors > max_spt) { + switch (bpb_sectors) { + case 19: /* High density XDF @ 360 rpm */ + img[drive].xdf_type = 1; + break; + case 23: /* High density XDF @ 300 rpm */ + img[drive].xdf_type = 2; + break; + case 24: /* High density XXDF @ 300 rpm */ + img[drive].xdf_type = 4; + break; + case 46: /* Extended density XDF */ + img[drive].xdf_type = 3; + break; + case 48: /* Extended density XXDF */ + img[drive].xdf_type = 5; + break; + default: /* Unknown, as we're beyond maximum sectors, get out */ + fclose(img[drive].f); + return; + } + } else /* Amount of sectors per track that fits into a track, therefore not XDF */ + { + img[drive].xdf_type = 0; + } + } + } else /* BPB reports sector size other than 512, can't possibly be XDF */ + { + img[drive].xdf_type = 0; + } + } - if ((bit_rate_300 == 250) || (bit_rate_300 == 300)) { - img[drive].hole = 0; - } else if (bit_rate_300 == 1000) { - img[drive].hole = 2; - } else { - img[drive].hole = 1; - } + if ((bit_rate_300 == 250) || (bit_rate_300 == 300)) { + img[drive].hole = 0; + } else if (bit_rate_300 == 1000) { + img[drive].hole = 2; + } else { + img[drive].hole = 1; + } - if (img[drive].xdf_type) /* In case of XDF-formatted image, write-protect */ - { - writeprot[drive] = 1; - fwriteprot[drive] = writeprot[drive]; - } + if (img[drive].xdf_type) /* In case of XDF-formatted image, write-protect */ + { + writeprot[drive] = 1; + fwriteprot[drive] = writeprot[drive]; + } - drives[drive].seek = img_seek; - drives[drive].readsector = disc_sector_readsector; - drives[drive].writesector = disc_sector_writesector; - drives[drive].readaddress = disc_sector_readaddress; - drives[drive].hole = img_hole; - drives[drive].poll = disc_sector_poll; - drives[drive].format = disc_sector_format; - disc_sector_writeback[drive] = img_writeback; + drives[drive].seek = img_seek; + drives[drive].readsector = disc_sector_readsector; + drives[drive].writesector = disc_sector_writesector; + drives[drive].readaddress = disc_sector_readaddress; + drives[drive].hole = img_hole; + drives[drive].poll = disc_sector_poll; + drives[drive].format = disc_sector_format; + disc_sector_writeback[drive] = img_writeback; - img[drive].bitcell_period_300rpm = 1000000.0 / bit_rate_300 * 2.0; - pclog("bit_rate_300=%g\n", bit_rate_300); - pclog("bitcell_period_300=%g\n", img[drive].bitcell_period_300rpm); -// img[drive].bitcell_period_300rpm = disc_get_bitcell_period(img[drive].rate); - pclog("img_load %d %p sectors=%i tracks=%i sides=%i sector_size=%i hole=%i\n", drive, drives, img[drive].sectors, img[drive].tracks, img[drive].sides, img[drive].sector_size, img[drive].hole); + img[drive].bitcell_period_300rpm = 1000000.0 / bit_rate_300 * 2.0; + pclog("bit_rate_300=%g\n", bit_rate_300); + pclog("bitcell_period_300=%g\n", img[drive].bitcell_period_300rpm); + // img[drive].bitcell_period_300rpm = disc_get_bitcell_period(img[drive].rate); + pclog("img_load %d %p sectors=%i tracks=%i sides=%i sector_size=%i hole=%i\n", drive, drives, img[drive].sectors, + img[drive].tracks, img[drive].sides, img[drive].sector_size, img[drive].hole); } -int img_hole(int drive) { - return img[drive].hole; -} +int img_hole(int drive) { return img[drive].hole; } void img_close(int drive) { - if (img[drive].f) - fclose(img[drive].f); - img[drive].f = NULL; + if (img[drive].f) + fclose(img[drive].f); + img[drive].f = NULL; } void img_seek(int drive, int track) { - int side; - int current_xdft = img[drive].xdf_type - 1; + int side; + int current_xdft = img[drive].xdf_type - 1; - uint8_t sectors_fat, effective_sectors; /* Needed for XDF */ + uint8_t sectors_fat, effective_sectors; /* Needed for XDF */ - if (!img[drive].f) - return; - pclog("Seek drive=%i track=%i sectors=%i sector_size=%i sides=%i\n", drive, track, img[drive].sectors, img[drive].sector_size, img[drive].sides); -// pclog(" %i %i\n", drive_type[drive], img[drive].tracks); - if (img[drive].tracks <= 41 && fdd_doublestep_40(drive)) - track /= 2; + if (!img[drive].f) + return; + pclog("Seek drive=%i track=%i sectors=%i sector_size=%i sides=%i\n", drive, track, img[drive].sectors, + img[drive].sector_size, img[drive].sides); + // pclog(" %i %i\n", drive_type[drive], img[drive].tracks); + if (img[drive].tracks <= 41 && fdd_doublestep_40(drive)) + track /= 2; - pclog("Disk seeked to track %i\n", track); - disc_track[drive] = track; + pclog("Disk seeked to track %i\n", track); + disc_track[drive] = track; - if (img[drive].sides == 2) { - fseek(img[drive].f, track * img[drive].sectors * img[drive].sector_size * 2, SEEK_SET); - fread(img[drive].track_data[0], img[drive].sectors * img[drive].sector_size, 1, img[drive].f); - fread(img[drive].track_data[1], img[drive].sectors * img[drive].sector_size, 1, img[drive].f); - } else { - fseek(img[drive].f, track * img[drive].sectors * img[drive].sector_size, SEEK_SET); - fread(img[drive].track_data[0], img[drive].sectors * img[drive].sector_size, 1, img[drive].f); - } + if (img[drive].sides == 2) { + fseek(img[drive].f, track * img[drive].sectors * img[drive].sector_size * 2, SEEK_SET); + fread(img[drive].track_data[0], img[drive].sectors * img[drive].sector_size, 1, img[drive].f); + fread(img[drive].track_data[1], img[drive].sectors * img[drive].sector_size, 1, img[drive].f); + } else { + fseek(img[drive].f, track * img[drive].sectors * img[drive].sector_size, SEEK_SET); + fread(img[drive].track_data[0], img[drive].sectors * img[drive].sector_size, 1, img[drive].f); + } - disc_sector_reset(drive, 0); - disc_sector_reset(drive, 1); + disc_sector_reset(drive, 0); + disc_sector_reset(drive, 1); - int sector, current_pos; + int sector, current_pos; - if (img[drive].xdf_type) { - sectors_fat = xdf_track0[current_xdft][0]; - effective_sectors = xdf_track0[current_xdft][1]; -// sector_gap = xdf_track0[current_xdft][2]; + if (img[drive].xdf_type) { + sectors_fat = xdf_track0[current_xdft][0]; + effective_sectors = xdf_track0[current_xdft][1]; + // sector_gap = xdf_track0[current_xdft][2]; - if (!track) { - /* Track 0, register sectors according to track 0 map. */ - /* First, the "Side 0" buffer, will also contain one sector from side 1. */ - current_pos = 0; - for (sector = 0; sector < sectors_fat; sector++) { - disc_sector_add(drive, 0, track, 0, sector + 0x81, 2, - img[drive].bitcell_period_300rpm, - &img[drive].track_data[0][current_pos]); - current_pos += 512; - } - disc_sector_add(drive, 1, track, 1, 0x81, 2, - img[drive].bitcell_period_300rpm, - &img[drive].track_data[0][current_pos]); - current_pos += 512; - for (sector = 0; sector < 8; sector++) { - disc_sector_add(drive, 0, track, 0, sector + 1, 2, - img[drive].bitcell_period_300rpm, - &img[drive].track_data[0][current_pos]); - current_pos += 512; - } - /* Now the "Side 1" buffer, will also contain one sector from side 0. */ - current_pos = 0; - for (sector = 0; sector < 14; sector++) { - disc_sector_add(drive, 1, track, 1, sector + 0x82, 2, - img[drive].bitcell_period_300rpm, - &img[drive].track_data[1][current_pos]); - current_pos += 512; - } - current_pos += (5 * 512); - for (; sector < effective_sectors - 1; sector++) { - disc_sector_add(drive, 1, track, 1, sector + 0x82, 2, - img[drive].bitcell_period_300rpm, - &img[drive].track_data[1][current_pos]); - current_pos += 512; - } - current_pos += 512; - } else { - /* Non-zero track, this will have sectors of various sizes. */ - /* First, the "Side 0" buffer. */ - current_pos = 0; - for (sector = 0; sector < xdf_spt[current_xdft]; sector++) { - disc_sector_add(drive, xdf_map[current_xdft][sector][0], track, xdf_map[current_xdft][sector][0], - xdf_map[current_xdft][sector][2] + 0x80, xdf_map[current_xdft][sector][2], - img[drive].bitcell_period_300rpm, - &img[drive].track_data[0][current_pos]); - current_pos += (128 << xdf_map[current_xdft][sector][2]); - } - /* Then, the "Side 1" buffer. */ - current_pos = 0; - for (sector = xdf_spt[current_xdft]; sector < (xdf_spt[current_xdft] << 1); sector++) { - disc_sector_add(drive, xdf_map[current_xdft][sector][0], track, xdf_map[current_xdft][sector][0], - xdf_map[current_xdft][sector][2] + 0x80, xdf_map[current_xdft][sector][2], - img[drive].bitcell_period_300rpm, - &img[drive].track_data[1][current_pos]); - current_pos += (128 << xdf_map[current_xdft][sector][2]); - } - } - } else { - for (side = 0; side < img[drive].sides; side++) { - for (sector = 0; sector < img[drive].sectors; sector++) - disc_sector_add(drive, side, track, side, sector + 1, img_sector_size_code(drive), - img[drive].bitcell_period_300rpm, - &img[drive].track_data[side][sector * img[drive].sector_size]); - } - } + if (!track) { + /* Track 0, register sectors according to track 0 map. */ + /* First, the "Side 0" buffer, will also contain one sector from side 1. */ + current_pos = 0; + for (sector = 0; sector < sectors_fat; sector++) { + disc_sector_add(drive, 0, track, 0, sector + 0x81, 2, img[drive].bitcell_period_300rpm, + &img[drive].track_data[0][current_pos]); + current_pos += 512; + } + disc_sector_add(drive, 1, track, 1, 0x81, 2, img[drive].bitcell_period_300rpm, + &img[drive].track_data[0][current_pos]); + current_pos += 512; + for (sector = 0; sector < 8; sector++) { + disc_sector_add(drive, 0, track, 0, sector + 1, 2, img[drive].bitcell_period_300rpm, + &img[drive].track_data[0][current_pos]); + current_pos += 512; + } + /* Now the "Side 1" buffer, will also contain one sector from side 0. */ + current_pos = 0; + for (sector = 0; sector < 14; sector++) { + disc_sector_add(drive, 1, track, 1, sector + 0x82, 2, img[drive].bitcell_period_300rpm, + &img[drive].track_data[1][current_pos]); + current_pos += 512; + } + current_pos += (5 * 512); + for (; sector < effective_sectors - 1; sector++) { + disc_sector_add(drive, 1, track, 1, sector + 0x82, 2, img[drive].bitcell_period_300rpm, + &img[drive].track_data[1][current_pos]); + current_pos += 512; + } + current_pos += 512; + } else { + /* Non-zero track, this will have sectors of various sizes. */ + /* First, the "Side 0" buffer. */ + current_pos = 0; + for (sector = 0; sector < xdf_spt[current_xdft]; sector++) { + disc_sector_add(drive, xdf_map[current_xdft][sector][0], track, xdf_map[current_xdft][sector][0], + xdf_map[current_xdft][sector][2] + 0x80, xdf_map[current_xdft][sector][2], + img[drive].bitcell_period_300rpm, &img[drive].track_data[0][current_pos]); + current_pos += (128 << xdf_map[current_xdft][sector][2]); + } + /* Then, the "Side 1" buffer. */ + current_pos = 0; + for (sector = xdf_spt[current_xdft]; sector < (xdf_spt[current_xdft] << 1); sector++) { + disc_sector_add(drive, xdf_map[current_xdft][sector][0], track, xdf_map[current_xdft][sector][0], + xdf_map[current_xdft][sector][2] + 0x80, xdf_map[current_xdft][sector][2], + img[drive].bitcell_period_300rpm, &img[drive].track_data[1][current_pos]); + current_pos += (128 << xdf_map[current_xdft][sector][2]); + } + } + } else { + for (side = 0; side < img[drive].sides; side++) { + for (sector = 0; sector < img[drive].sectors; sector++) + disc_sector_add(drive, side, track, side, sector + 1, img_sector_size_code(drive), + img[drive].bitcell_period_300rpm, + &img[drive].track_data[side][sector * img[drive].sector_size]); + } + } } void img_writeback(int drive, int track) { - if (!img[drive].f) - return; + if (!img[drive].f) + return; - if (img[drive].xdf_type) - return; /*Should never happen*/ + if (img[drive].xdf_type) + return; /*Should never happen*/ - if (img[drive].sides == 2) { - fseek(img[drive].f, track * img[drive].sectors * img[drive].sector_size * 2, SEEK_SET); - fwrite(img[drive].track_data[0], img[drive].sectors * img[drive].sector_size, 1, img[drive].f); - fwrite(img[drive].track_data[1], img[drive].sectors * img[drive].sector_size, 1, img[drive].f); - } else { - fseek(img[drive].f, track * img[drive].sectors * img[drive].sector_size, SEEK_SET); - fwrite(img[drive].track_data[0], img[drive].sectors * img[drive].sector_size, 1, img[drive].f); - } + if (img[drive].sides == 2) { + fseek(img[drive].f, track * img[drive].sectors * img[drive].sector_size * 2, SEEK_SET); + fwrite(img[drive].track_data[0], img[drive].sectors * img[drive].sector_size, 1, img[drive].f); + fwrite(img[drive].track_data[1], img[drive].sectors * img[drive].sector_size, 1, img[drive].f); + } else { + fseek(img[drive].f, track * img[drive].sectors * img[drive].sector_size, SEEK_SET); + fwrite(img[drive].track_data[0], img[drive].sectors * img[drive].sector_size, 1, img[drive].f); + } } - diff --git a/src/disc/disc_sector.c b/src/disc/disc_sector.c index 1593a080..1af5ee84 100644 --- a/src/disc/disc_sector.c +++ b/src/disc/disc_sector.c @@ -9,9 +9,9 @@ #define MAX_SECTORS 256 typedef struct { - uint8_t c, h, r, n; - int rate; - uint8_t *data; + uint8_t c, h, r, n; + int rate; + uint8_t *data; } sector_t; static sector_t disc_sector_data[2][2][MAX_SECTORS]; @@ -19,19 +19,19 @@ static int disc_sector_count[2][2]; void (*disc_sector_writeback[2])(int drive, int track); enum { - STATE_IDLE, - STATE_READ_FIND_SECTOR, - STATE_READ_SECTOR, - STATE_READ_FIND_FIRST_SECTOR, - STATE_READ_FIRST_SECTOR, - STATE_READ_FIND_NEXT_SECTOR, - STATE_READ_NEXT_SECTOR, - STATE_WRITE_FIND_SECTOR, - STATE_WRITE_SECTOR, - STATE_READ_FIND_ADDRESS, - STATE_READ_ADDRESS, - STATE_FORMAT_FIND, - STATE_FORMAT + STATE_IDLE, + STATE_READ_FIND_SECTOR, + STATE_READ_SECTOR, + STATE_READ_FIND_FIRST_SECTOR, + STATE_READ_FIRST_SECTOR, + STATE_READ_FIND_NEXT_SECTOR, + STATE_READ_NEXT_SECTOR, + STATE_WRITE_FIND_SECTOR, + STATE_WRITE_SECTOR, + STATE_READ_FIND_ADDRESS, + STATE_READ_ADDRESS, + STATE_FORMAT_FIND, + STATE_FORMAT }; static int disc_sector_state; @@ -47,338 +47,327 @@ static int index_count; static int disc_sector_status; -void disc_sector_reset(int drive, int side) { - disc_sector_count[drive][side] = 0; -} +void disc_sector_reset(int drive, int side) { disc_sector_count[drive][side] = 0; } void disc_sector_add(int drive, int side, uint8_t c, uint8_t h, uint8_t r, uint8_t n, int rate, uint8_t *data) { - sector_t *s = &disc_sector_data[drive][side][disc_sector_count[drive][side]]; -//pclog("disc_sector_add: drive=%i side=%i %i r=%i\n", drive, side, disc_sector_count[drive][side],r ); - if (disc_sector_count[drive][side] >= MAX_SECTORS) - return; + sector_t *s = &disc_sector_data[drive][side][disc_sector_count[drive][side]]; + // pclog("disc_sector_add: drive=%i side=%i %i r=%i\n", drive, side, disc_sector_count[drive][side],r ); + if (disc_sector_count[drive][side] >= MAX_SECTORS) + return; - s->c = c; - s->h = h; - s->r = r; - s->n = n; - s->rate = rate; - s->data = data; + s->c = c; + s->h = h; + s->r = r; + s->n = n; + s->rate = rate; + s->data = data; - disc_sector_count[drive][side]++; + disc_sector_count[drive][side]++; } static int get_bitcell_period() { - return (disc_sector_data[disc_sector_drive][disc_sector_side][cur_sector].rate * 300) / fdd_getrpm(disc_sector_drive); + return (disc_sector_data[disc_sector_drive][disc_sector_side][cur_sector].rate * 300) / fdd_getrpm(disc_sector_drive); } void disc_sector_readsector(int drive, int sector, int track, int side, int rate, int sector_size) { -// pclog("disc_sector_readsector: fdc_period=%i img_period=%i rate=%i sector=%i track=%i side=%i\n", fdc_get_bitcell_period(), get_bitcell_period(), rate, sector, track, side); + // pclog("disc_sector_readsector: fdc_period=%i img_period=%i rate=%i sector=%i track=%i side=%i\n", + // fdc_get_bitcell_period(), get_bitcell_period(), rate, sector, track, side); - if (sector == SECTOR_FIRST) - disc_sector_state = STATE_READ_FIND_FIRST_SECTOR; - else if (sector == SECTOR_NEXT) - disc_sector_state = STATE_READ_FIND_NEXT_SECTOR; - else - disc_sector_state = STATE_READ_FIND_SECTOR; - disc_sector_track = track; - disc_sector_side = side; - disc_sector_drive = drive; - disc_sector_sector = sector; - disc_sector_n = sector_size; - index_count = 0; + if (sector == SECTOR_FIRST) + disc_sector_state = STATE_READ_FIND_FIRST_SECTOR; + else if (sector == SECTOR_NEXT) + disc_sector_state = STATE_READ_FIND_NEXT_SECTOR; + else + disc_sector_state = STATE_READ_FIND_SECTOR; + disc_sector_track = track; + disc_sector_side = side; + disc_sector_drive = drive; + disc_sector_sector = sector; + disc_sector_n = sector_size; + index_count = 0; - disc_sector_status = FDC_STATUS_AM_NOT_FOUND; + disc_sector_status = FDC_STATUS_AM_NOT_FOUND; } void disc_sector_writesector(int drive, int sector, int track, int side, int rate, int sector_size) { -// pclog("disc_sector_writesector: fdc_period=%i img_period=%i rate=%i\n", fdc_get_bitcell_period(), get_bitcell_period(), rate); + // pclog("disc_sector_writesector: fdc_period=%i img_period=%i rate=%i\n", fdc_get_bitcell_period(), + // get_bitcell_period(), rate); - disc_sector_state = STATE_WRITE_FIND_SECTOR; - disc_sector_track = track; - disc_sector_side = side; - disc_sector_drive = drive; - disc_sector_sector = sector; - disc_sector_n = sector_size; - index_count = 0; + disc_sector_state = STATE_WRITE_FIND_SECTOR; + disc_sector_track = track; + disc_sector_side = side; + disc_sector_drive = drive; + disc_sector_sector = sector; + disc_sector_n = sector_size; + index_count = 0; - disc_sector_status = FDC_STATUS_AM_NOT_FOUND; + disc_sector_status = FDC_STATUS_AM_NOT_FOUND; } void disc_sector_readaddress(int drive, int track, int side, int rate) { -// pclog("disc_sector_readaddress: fdc_period=%i img_period=%i rate=%i track=%i side=%i\n", fdc_get_bitcell_period(), get_bitcell_period(), rate, track, side); + // pclog("disc_sector_readaddress: fdc_period=%i img_period=%i rate=%i track=%i side=%i\n", + // fdc_get_bitcell_period(), get_bitcell_period(), rate, track, side); - disc_sector_state = STATE_READ_FIND_ADDRESS; - disc_sector_track = track; - disc_sector_side = side; - disc_sector_drive = drive; - index_count = 0; + disc_sector_state = STATE_READ_FIND_ADDRESS; + disc_sector_track = track; + disc_sector_side = side; + disc_sector_drive = drive; + index_count = 0; - disc_sector_status = FDC_STATUS_AM_NOT_FOUND; + disc_sector_status = FDC_STATUS_AM_NOT_FOUND; } void disc_sector_format(int drive, int track, int side, int rate, uint8_t fill) { - disc_sector_state = STATE_FORMAT_FIND; - disc_sector_track = track; - disc_sector_side = side; - disc_sector_drive = drive; - disc_sector_fill = fill; - index_count = 0; + disc_sector_state = STATE_FORMAT_FIND; + disc_sector_track = track; + disc_sector_side = side; + disc_sector_drive = drive; + disc_sector_fill = fill; + index_count = 0; } -void disc_sector_stop() { - disc_sector_state = STATE_IDLE; -} +void disc_sector_stop() { disc_sector_state = STATE_IDLE; } static void advance_byte() { - if (disc_intersector_delay) { - disc_intersector_delay--; - return; - } - cur_byte++; - if (cur_byte >= (128 << disc_sector_data[disc_sector_drive][disc_sector_side][cur_sector].n)) { - cur_byte = 0; - cur_sector++; - if (cur_sector >= disc_sector_count[disc_sector_drive][disc_sector_side]) { - cur_sector = 0; - fdc_indexpulse(); - index_count++; - } - disc_intersector_delay = 40; - } + if (disc_intersector_delay) { + disc_intersector_delay--; + return; + } + cur_byte++; + if (cur_byte >= (128 << disc_sector_data[disc_sector_drive][disc_sector_side][cur_sector].n)) { + cur_byte = 0; + cur_sector++; + if (cur_sector >= disc_sector_count[disc_sector_drive][disc_sector_side]) { + cur_sector = 0; + fdc_indexpulse(); + index_count++; + } + disc_intersector_delay = 40; + } } void disc_sector_poll() { - sector_t *s; - int data; + sector_t *s; + int data; - if (cur_sector >= disc_sector_count[disc_sector_drive][disc_sector_side]) - cur_sector = 0; - if (cur_byte >= (128 << disc_sector_data[disc_sector_drive][disc_sector_side][cur_sector].n)) - cur_byte = 0; + if (cur_sector >= disc_sector_count[disc_sector_drive][disc_sector_side]) + cur_sector = 0; + if (cur_byte >= (128 << disc_sector_data[disc_sector_drive][disc_sector_side][cur_sector].n)) + cur_byte = 0; - s = &disc_sector_data[disc_sector_drive][disc_sector_side][cur_sector]; - switch (disc_sector_state) { - case STATE_IDLE:break; + s = &disc_sector_data[disc_sector_drive][disc_sector_side][cur_sector]; + switch (disc_sector_state) { + case STATE_IDLE: + break; - case STATE_READ_FIND_SECTOR: -/* pclog("STATE_READ_FIND_SECTOR: cur_sector=%i cur_byte=%i sector=%i,%i side=%i,%i track=%i,%i period=%i,%i\n", - cur_sector, cur_byte, - disc_sector_sector, s->r, - disc_sector_side, s->h, - disc_sector_track, s->c, - fdc_get_bitcell_period(), get_bitcell_period());*/ - if (index_count > 1) { -// pclog("Find sector not found\n"); - fdc_notfound(disc_sector_status); - disc_sector_state = STATE_IDLE; - break; - } -/* pclog("%i %i %i %i %i\n", cur_byte, disc_sector_track != s->c, - disc_sector_side != s->h, - disc_sector_sector != s->r, - fdc_get_bitcell_period() != get_bitcell_period());*/ - if (!cur_byte && fdc_get_bitcell_period() == get_bitcell_period() && - fdd_can_read_medium(disc_sector_drive ^ fdd_swap)) - disc_sector_status = FDC_STATUS_NOT_FOUND; /*Disc readable, assume address marker found*/ + case STATE_READ_FIND_SECTOR: + /* pclog("STATE_READ_FIND_SECTOR: cur_sector=%i cur_byte=%i sector=%i,%i side=%i,%i track=%i,%i + period=%i,%i\n", cur_sector, cur_byte, disc_sector_sector, s->r, disc_sector_side, s->h, disc_sector_track, + s->c, fdc_get_bitcell_period(), get_bitcell_period());*/ + if (index_count > 1) { + // pclog("Find sector not found\n"); + fdc_notfound(disc_sector_status); + disc_sector_state = STATE_IDLE; + break; + } + /* pclog("%i %i %i %i %i\n", cur_byte, disc_sector_track != s->c, + disc_sector_side != s->h, + disc_sector_sector != s->r, + fdc_get_bitcell_period() != get_bitcell_period());*/ + if (!cur_byte && fdc_get_bitcell_period() == get_bitcell_period() && + fdd_can_read_medium(disc_sector_drive ^ fdd_swap)) + disc_sector_status = FDC_STATUS_NOT_FOUND; /*Disc readable, assume address marker found*/ - if (cur_byte || - fdc_get_bitcell_period() != get_bitcell_period() || - !fdd_can_read_medium(disc_sector_drive ^ fdd_swap) || - disc_intersector_delay) { - advance_byte(); - break; - } - if (disc_sector_track != s->c || - disc_sector_side != s->h || - disc_sector_sector != s->r || - disc_sector_n != s->n) { - if (disc_sector_track != s->c) - disc_sector_status = (disc_sector_track == 0xff) ? FDC_STATUS_BAD_CYLINDER : FDC_STATUS_WRONG_CYLINDER; - advance_byte(); - break; - } - disc_sector_state = STATE_READ_SECTOR; - case STATE_READ_SECTOR: -// pclog("STATE_READ_SECTOR: cur_byte=%i %i\n", cur_byte, disc_intersector_delay); - if (fdc_data(s->data[cur_byte])) { -// pclog("fdc_data failed\n"); - return; - } - advance_byte(); - if (!cur_byte) { - disc_sector_state = STATE_IDLE; - fdc_finishread(); - } - break; + if (cur_byte || fdc_get_bitcell_period() != get_bitcell_period() || + !fdd_can_read_medium(disc_sector_drive ^ fdd_swap) || disc_intersector_delay) { + advance_byte(); + break; + } + if (disc_sector_track != s->c || disc_sector_side != s->h || disc_sector_sector != s->r || + disc_sector_n != s->n) { + if (disc_sector_track != s->c) + disc_sector_status = + (disc_sector_track == 0xff) ? FDC_STATUS_BAD_CYLINDER : FDC_STATUS_WRONG_CYLINDER; + advance_byte(); + break; + } + disc_sector_state = STATE_READ_SECTOR; + case STATE_READ_SECTOR: + // pclog("STATE_READ_SECTOR: cur_byte=%i %i\n", cur_byte, disc_intersector_delay); + if (fdc_data(s->data[cur_byte])) { + // pclog("fdc_data failed\n"); + return; + } + advance_byte(); + if (!cur_byte) { + disc_sector_state = STATE_IDLE; + fdc_finishread(); + } + break; - case STATE_READ_FIND_FIRST_SECTOR: - if (!(fdd_can_read_medium(disc_sector_drive ^ fdd_swap))) { -// pclog("Medium is of a density not supported by the drive\n"); - fdc_notfound(FDC_STATUS_AM_NOT_FOUND); - disc_sector_state = STATE_IDLE; - break; - } - if (!cur_byte && fdc_get_bitcell_period() == get_bitcell_period() && - fdd_can_read_medium(disc_sector_drive ^ fdd_swap)) - disc_sector_status = FDC_STATUS_NOT_FOUND; /*Disc readable, assume address marker found*/ + case STATE_READ_FIND_FIRST_SECTOR: + if (!(fdd_can_read_medium(disc_sector_drive ^ fdd_swap))) { + // pclog("Medium is of a density not supported by the drive\n"); + fdc_notfound(FDC_STATUS_AM_NOT_FOUND); + disc_sector_state = STATE_IDLE; + break; + } + if (!cur_byte && fdc_get_bitcell_period() == get_bitcell_period() && + fdd_can_read_medium(disc_sector_drive ^ fdd_swap)) + disc_sector_status = FDC_STATUS_NOT_FOUND; /*Disc readable, assume address marker found*/ - if (cur_byte || !index_count || fdc_get_bitcell_period() != get_bitcell_period() || - disc_intersector_delay) { - advance_byte(); - break; - } - disc_sector_state = STATE_READ_FIRST_SECTOR; - case STATE_READ_FIRST_SECTOR: - if (fdc_data(s->data[cur_byte])) - return; - advance_byte(); - if (!cur_byte) { - disc_sector_state = STATE_IDLE; - fdc_finishread(); - } - break; + if (cur_byte || !index_count || fdc_get_bitcell_period() != get_bitcell_period() || disc_intersector_delay) { + advance_byte(); + break; + } + disc_sector_state = STATE_READ_FIRST_SECTOR; + case STATE_READ_FIRST_SECTOR: + if (fdc_data(s->data[cur_byte])) + return; + advance_byte(); + if (!cur_byte) { + disc_sector_state = STATE_IDLE; + fdc_finishread(); + } + break; - case STATE_READ_FIND_NEXT_SECTOR: - if (!(fdd_can_read_medium(disc_sector_drive ^ fdd_swap))) { -// pclog("Medium is of a density not supported by the drive\n"); - fdc_notfound(FDC_STATUS_AM_NOT_FOUND); - disc_sector_state = STATE_IDLE; - break; - } - if (index_count) { -// pclog("Find next sector hit end of track\n"); - fdc_notfound(disc_sector_status); - disc_sector_state = STATE_IDLE; - break; - } - if (cur_byte || fdc_get_bitcell_period() != get_bitcell_period() || - disc_intersector_delay) { - advance_byte(); - break; - } - disc_sector_state = STATE_READ_NEXT_SECTOR; - case STATE_READ_NEXT_SECTOR: - if (fdc_data(s->data[cur_byte])) - break; - advance_byte(); - if (!cur_byte) { - disc_sector_state = STATE_IDLE; - fdc_finishread(); - } - break; + case STATE_READ_FIND_NEXT_SECTOR: + if (!(fdd_can_read_medium(disc_sector_drive ^ fdd_swap))) { + // pclog("Medium is of a density not supported by the drive\n"); + fdc_notfound(FDC_STATUS_AM_NOT_FOUND); + disc_sector_state = STATE_IDLE; + break; + } + if (index_count) { + // pclog("Find next sector hit end of track\n"); + fdc_notfound(disc_sector_status); + disc_sector_state = STATE_IDLE; + break; + } + if (cur_byte || fdc_get_bitcell_period() != get_bitcell_period() || disc_intersector_delay) { + advance_byte(); + break; + } + disc_sector_state = STATE_READ_NEXT_SECTOR; + case STATE_READ_NEXT_SECTOR: + if (fdc_data(s->data[cur_byte])) + break; + advance_byte(); + if (!cur_byte) { + disc_sector_state = STATE_IDLE; + fdc_finishread(); + } + break; - case STATE_WRITE_FIND_SECTOR: - if (!(fdd_can_read_medium(disc_sector_drive ^ fdd_swap))) { -// pclog("Medium is of a density not supported by the drive\n"); - fdc_notfound(FDC_STATUS_AM_NOT_FOUND); - disc_sector_state = STATE_IDLE; - break; - } + case STATE_WRITE_FIND_SECTOR: + if (!(fdd_can_read_medium(disc_sector_drive ^ fdd_swap))) { + // pclog("Medium is of a density not supported by the drive\n"); + fdc_notfound(FDC_STATUS_AM_NOT_FOUND); + disc_sector_state = STATE_IDLE; + break; + } - if (!cur_byte && fdc_get_bitcell_period() == get_bitcell_period() && - fdd_can_read_medium(disc_sector_drive ^ fdd_swap)) - disc_sector_status = FDC_STATUS_NOT_FOUND; /*Disc readable, assume address marker found*/ + if (!cur_byte && fdc_get_bitcell_period() == get_bitcell_period() && + fdd_can_read_medium(disc_sector_drive ^ fdd_swap)) + disc_sector_status = FDC_STATUS_NOT_FOUND; /*Disc readable, assume address marker found*/ - if (writeprot[disc_sector_drive]) { - fdc_writeprotect(); - disc_sector_state = STATE_IDLE; - return; - } - if (index_count > 1) { -// pclog("Write find sector not found\n"); - fdc_notfound(disc_sector_status); - disc_sector_state = STATE_IDLE; - break; - } - if (cur_byte || - fdc_get_bitcell_period() != get_bitcell_period() || - disc_intersector_delay) { - advance_byte(); - break; - } - if (disc_sector_track != s->c || - disc_sector_side != s->h || - disc_sector_sector != s->r || - disc_sector_n != s->n) { - if (disc_sector_track != s->c) - disc_sector_status = (disc_sector_track == 0xff) ? FDC_STATUS_BAD_CYLINDER : FDC_STATUS_WRONG_CYLINDER; - advance_byte(); - break; - } - disc_sector_state = STATE_WRITE_SECTOR; - case STATE_WRITE_SECTOR:data = fdc_getdata(cur_byte == ((128 << s->n) - 1)); - if (data == -1) - break; - s->data[cur_byte] = data; - advance_byte(); - if (!cur_byte) { - disc_sector_state = STATE_IDLE; - disc_sector_writeback[disc_sector_drive](disc_sector_drive, disc_sector_track); - fdc_finishread(); - } - break; + if (writeprot[disc_sector_drive]) { + fdc_writeprotect(); + disc_sector_state = STATE_IDLE; + return; + } + if (index_count > 1) { + // pclog("Write find sector not found\n"); + fdc_notfound(disc_sector_status); + disc_sector_state = STATE_IDLE; + break; + } + if (cur_byte || fdc_get_bitcell_period() != get_bitcell_period() || disc_intersector_delay) { + advance_byte(); + break; + } + if (disc_sector_track != s->c || disc_sector_side != s->h || disc_sector_sector != s->r || + disc_sector_n != s->n) { + if (disc_sector_track != s->c) + disc_sector_status = + (disc_sector_track == 0xff) ? FDC_STATUS_BAD_CYLINDER : FDC_STATUS_WRONG_CYLINDER; + advance_byte(); + break; + } + disc_sector_state = STATE_WRITE_SECTOR; + case STATE_WRITE_SECTOR: + data = fdc_getdata(cur_byte == ((128 << s->n) - 1)); + if (data == -1) + break; + s->data[cur_byte] = data; + advance_byte(); + if (!cur_byte) { + disc_sector_state = STATE_IDLE; + disc_sector_writeback[disc_sector_drive](disc_sector_drive, disc_sector_track); + fdc_finishread(); + } + break; - case STATE_READ_FIND_ADDRESS: - if (!(fdd_can_read_medium(disc_sector_drive ^ fdd_swap))) { -// pclog("Medium is of a density not supported by the drive\n"); - fdc_notfound(FDC_STATUS_AM_NOT_FOUND); - disc_sector_state = STATE_IDLE; - break; - } + case STATE_READ_FIND_ADDRESS: + if (!(fdd_can_read_medium(disc_sector_drive ^ fdd_swap))) { + // pclog("Medium is of a density not supported by the drive\n"); + fdc_notfound(FDC_STATUS_AM_NOT_FOUND); + disc_sector_state = STATE_IDLE; + break; + } - if (!cur_byte && fdc_get_bitcell_period() == get_bitcell_period() && - fdd_can_read_medium(disc_sector_drive ^ fdd_swap)) - disc_sector_status = FDC_STATUS_NOT_FOUND; /*Disc readable, assume address marker found*/ + if (!cur_byte && fdc_get_bitcell_period() == get_bitcell_period() && + fdd_can_read_medium(disc_sector_drive ^ fdd_swap)) + disc_sector_status = FDC_STATUS_NOT_FOUND; /*Disc readable, assume address marker found*/ - if (index_count) { -// pclog("Find next sector hit end of track\n"); - fdc_notfound(disc_sector_status); - disc_sector_state = STATE_IDLE; - break; - } - if (cur_byte || fdc_get_bitcell_period() != get_bitcell_period() || - disc_intersector_delay) { - advance_byte(); - break; - } - disc_sector_state = STATE_READ_ADDRESS; - case STATE_READ_ADDRESS:fdc_sectorid(s->c, s->h, s->r, s->n, 0, 0); - advance_byte(); - disc_sector_state = STATE_IDLE; - break; + if (index_count) { + // pclog("Find next sector hit end of track\n"); + fdc_notfound(disc_sector_status); + disc_sector_state = STATE_IDLE; + break; + } + if (cur_byte || fdc_get_bitcell_period() != get_bitcell_period() || disc_intersector_delay) { + advance_byte(); + break; + } + disc_sector_state = STATE_READ_ADDRESS; + case STATE_READ_ADDRESS: + fdc_sectorid(s->c, s->h, s->r, s->n, 0, 0); + advance_byte(); + disc_sector_state = STATE_IDLE; + break; - case STATE_FORMAT_FIND: - if (writeprot[disc_sector_drive]) { - fdc_writeprotect(); - disc_sector_state = STATE_IDLE; - return; - } - if (!index_count || fdc_get_bitcell_period() != get_bitcell_period() || - disc_intersector_delay) { - advance_byte(); - break; - } - if (!(fdd_can_read_medium(disc_sector_drive ^ fdd_swap))) { -// pclog("Medium is of a density not supported by the drive\n"); - fdc_notfound(FDC_STATUS_NOT_FOUND); - disc_sector_state = STATE_IDLE; - break; - } - if (fdc_get_bitcell_period() != get_bitcell_period()) { - fdc_notfound(FDC_STATUS_NOT_FOUND); - disc_sector_state = STATE_IDLE; - break; - } - disc_sector_state = STATE_FORMAT; - case STATE_FORMAT: - if (!disc_intersector_delay && fdc_get_bitcell_period() == get_bitcell_period()) - s->data[cur_byte] = disc_sector_fill; - advance_byte(); - if (index_count == 2) { - disc_sector_writeback[disc_sector_drive](disc_sector_drive, disc_sector_track); - fdc_finishread(); - disc_sector_state = STATE_IDLE; - } - break; - } + case STATE_FORMAT_FIND: + if (writeprot[disc_sector_drive]) { + fdc_writeprotect(); + disc_sector_state = STATE_IDLE; + return; + } + if (!index_count || fdc_get_bitcell_period() != get_bitcell_period() || disc_intersector_delay) { + advance_byte(); + break; + } + if (!(fdd_can_read_medium(disc_sector_drive ^ fdd_swap))) { + // pclog("Medium is of a density not supported by the drive\n"); + fdc_notfound(FDC_STATUS_NOT_FOUND); + disc_sector_state = STATE_IDLE; + break; + } + if (fdc_get_bitcell_period() != get_bitcell_period()) { + fdc_notfound(FDC_STATUS_NOT_FOUND); + disc_sector_state = STATE_IDLE; + break; + } + disc_sector_state = STATE_FORMAT; + case STATE_FORMAT: + if (!disc_intersector_delay && fdc_get_bitcell_period() == get_bitcell_period()) + s->data[cur_byte] = disc_sector_fill; + advance_byte(); + if (index_count == 2) { + disc_sector_writeback[disc_sector_drive](disc_sector_drive, disc_sector_track); + fdc_finishread(); + disc_sector_state = STATE_IDLE; + } + break; + } } diff --git a/src/dosbox/vid_cga_comp.c b/src/dosbox/vid_cga_comp.c index 9afd3f9f..25f57b6e 100644 --- a/src/dosbox/vid_cga_comp.c +++ b/src/dosbox/vid_cga_comp.c @@ -1,5 +1,5 @@ /* Code borrowed from DOSBox and adapted by OBattler. - Original author: reenigne. */ + Original author: reenigne. */ #include #include @@ -25,27 +25,22 @@ static double hue_offset = 0; static const double tau = 6.28318531; // == 2*pi static unsigned char chroma_multiplexer[256] = { - 2, 2, 2, 2, 114, 174, 4, 3, 2, 1, 133, 135, 2, 113, 150, 4, - 133, 2, 1, 99, 151, 152, 2, 1, 3, 2, 96, 136, 151, 152, 151, 152, - 2, 56, 62, 4, 111, 250, 118, 4, 0, 51, 207, 137, 1, 171, 209, 5, - 140, 50, 54, 100, 133, 202, 57, 4, 2, 50, 153, 149, 128, 198, 198, 135, - 32, 1, 36, 81, 147, 158, 1, 42, 33, 1, 210, 254, 34, 109, 169, 77, - 177, 2, 0, 165, 189, 154, 3, 44, 33, 0, 91, 197, 178, 142, 144, 192, - 4, 2, 61, 67, 117, 151, 112, 83, 4, 0, 249, 255, 3, 107, 249, 117, - 147, 1, 50, 162, 143, 141, 52, 54, 3, 0, 145, 206, 124, 123, 192, 193, - 72, 78, 2, 0, 159, 208, 4, 0, 53, 58, 164, 159, 37, 159, 171, 1, - 248, 117, 4, 98, 212, 218, 5, 2, 54, 59, 93, 121, 176, 181, 134, 130, - 1, 61, 31, 0, 160, 255, 34, 1, 1, 58, 197, 166, 0, 177, 194, 2, - 162, 111, 34, 96, 205, 253, 32, 1, 1, 57, 123, 125, 119, 188, 150, 112, - 78, 4, 0, 75, 166, 180, 20, 38, 78, 1, 143, 246, 42, 113, 156, 37, - 252, 4, 1, 188, 175, 129, 1, 37, 118, 4, 88, 249, 202, 150, 145, 200, - 61, 59, 60, 60, 228, 252, 117, 77, 60, 58, 248, 251, 81, 212, 254, 107, - 198, 59, 58, 169, 250, 251, 81, 80, 100, 58, 154, 250, 251, 252, 252, 252}; + 2, 2, 2, 2, 114, 174, 4, 3, 2, 1, 133, 135, 2, 113, 150, 4, 133, 2, 1, 99, 151, 152, 2, 1, + 3, 2, 96, 136, 151, 152, 151, 152, 2, 56, 62, 4, 111, 250, 118, 4, 0, 51, 207, 137, 1, 171, 209, 5, + 140, 50, 54, 100, 133, 202, 57, 4, 2, 50, 153, 149, 128, 198, 198, 135, 32, 1, 36, 81, 147, 158, 1, 42, + 33, 1, 210, 254, 34, 109, 169, 77, 177, 2, 0, 165, 189, 154, 3, 44, 33, 0, 91, 197, 178, 142, 144, 192, + 4, 2, 61, 67, 117, 151, 112, 83, 4, 0, 249, 255, 3, 107, 249, 117, 147, 1, 50, 162, 143, 141, 52, 54, + 3, 0, 145, 206, 124, 123, 192, 193, 72, 78, 2, 0, 159, 208, 4, 0, 53, 58, 164, 159, 37, 159, 171, 1, + 248, 117, 4, 98, 212, 218, 5, 2, 54, 59, 93, 121, 176, 181, 134, 130, 1, 61, 31, 0, 160, 255, 34, 1, + 1, 58, 197, 166, 0, 177, 194, 2, 162, 111, 34, 96, 205, 253, 32, 1, 1, 57, 123, 125, 119, 188, 150, 112, + 78, 4, 0, 75, 166, 180, 20, 38, 78, 1, 143, 246, 42, 113, 156, 37, 252, 4, 1, 188, 175, 129, 1, 37, + 118, 4, 88, 249, 202, 150, 145, 200, 61, 59, 60, 60, 228, 252, 117, 77, 60, 58, 248, 251, 81, 212, 254, 107, + 198, 59, 58, 169, 250, 251, 81, 80, 100, 58, 154, 250, 251, 252, 252, 252}; -static double intensity[4] = { - 77.175381, 88.654656, 166.564623, 174.228438}; +static double intensity[4] = {77.175381, 88.654656, 166.564623, 174.228438}; -#define NEW_CGA(c, i, r, g, b) (((c)/0.72)*0.29 + ((i)/0.28)*0.32 + ((r)/0.28)*0.1 + ((g)/0.28)*0.22 + ((b)/0.28)*0.07) +#define NEW_CGA(c, i, r, g, b) \ + (((c) / 0.72) * 0.29 + ((i) / 0.28) * 0.32 + ((r) / 0.28) * 0.1 + ((g) / 0.28) * 0.22 + ((b) / 0.28) * 0.07) double mode_brightness; double mode_contrast; @@ -62,83 +57,82 @@ static bool new_cga = 0; FILE *df; void update_cga16_color(uint8_t cgamode) { - int x; + int x; - if (!new_cga) { - min_v = chroma_multiplexer[0] + intensity[0]; - max_v = chroma_multiplexer[255] + intensity[3]; - } else { - double i0 = intensity[0]; - double i3 = intensity[3]; - min_v = NEW_CGA(chroma_multiplexer[0], i0, i0, i0, i0); - max_v = NEW_CGA(chroma_multiplexer[255], i3, i3, i3, i3); - } - mode_contrast = 256 / (max_v - min_v); - mode_brightness = -min_v * mode_contrast; - if ((cgamode & 3) == 1) - mode_hue = 14; - else - mode_hue = 4; + if (!new_cga) { + min_v = chroma_multiplexer[0] + intensity[0]; + max_v = chroma_multiplexer[255] + intensity[3]; + } else { + double i0 = intensity[0]; + double i3 = intensity[3]; + min_v = NEW_CGA(chroma_multiplexer[0], i0, i0, i0, i0); + max_v = NEW_CGA(chroma_multiplexer[255], i3, i3, i3, i3); + } + mode_contrast = 256 / (max_v - min_v); + mode_brightness = -min_v * mode_contrast; + if ((cgamode & 3) == 1) + mode_hue = 14; + else + mode_hue = 4; - mode_contrast *= contrast * (new_cga ? 1.2 : 1) / 100; // new CGA: 120% - mode_brightness += (new_cga ? brightness - 10 : brightness) * 5; // new CGA: -10 - double mode_saturation = (new_cga ? 4.35 : 2.9) * saturation / 100; // new CGA: 150% + mode_contrast *= contrast * (new_cga ? 1.2 : 1) / 100; // new CGA: 120% + mode_brightness += (new_cga ? brightness - 10 : brightness) * 5; // new CGA: -10 + double mode_saturation = (new_cga ? 4.35 : 2.9) * saturation / 100; // new CGA: 150% - for (x = 0; x < 1024; ++x) { - int phase = x & 3; - int right = (x >> 2) & 15; - int left = (x >> 6) & 15; - int rc = right; - int lc = left; - if ((cgamode & 4) != 0) { - rc = (right & 8) | ((right & 7) != 0 ? 7 : 0); - lc = (left & 8) | ((left & 7) != 0 ? 7 : 0); - } - double c = - chroma_multiplexer[((lc & 7) << 5) | ((rc & 7) << 2) | phase]; - double i = intensity[(left >> 3) | ((right >> 2) & 2)]; - double v; - if (!new_cga) - v = c + i; - else { - double r = intensity[((left >> 2) & 1) | ((right >> 1) & 2)]; - double g = intensity[((left >> 1) & 1) | (right & 2)]; - double b = intensity[(left & 1) | ((right << 1) & 2)]; - v = NEW_CGA(c, i, r, g, b); - } - CGA_Composite_Table[x] = (int)(v * mode_contrast + mode_brightness); - } + for (x = 0; x < 1024; ++x) { + int phase = x & 3; + int right = (x >> 2) & 15; + int left = (x >> 6) & 15; + int rc = right; + int lc = left; + if ((cgamode & 4) != 0) { + rc = (right & 8) | ((right & 7) != 0 ? 7 : 0); + lc = (left & 8) | ((left & 7) != 0 ? 7 : 0); + } + double c = chroma_multiplexer[((lc & 7) << 5) | ((rc & 7) << 2) | phase]; + double i = intensity[(left >> 3) | ((right >> 2) & 2)]; + double v; + if (!new_cga) + v = c + i; + else { + double r = intensity[((left >> 2) & 1) | ((right >> 1) & 2)]; + double g = intensity[((left >> 1) & 1) | (right & 2)]; + double b = intensity[(left & 1) | ((right << 1) & 2)]; + v = NEW_CGA(c, i, r, g, b); + } + CGA_Composite_Table[x] = (int)(v * mode_contrast + mode_brightness); + } - double i = CGA_Composite_Table[6 * 68] - CGA_Composite_Table[6 * 68 + 2]; - double q = CGA_Composite_Table[6 * 68 + 1] - CGA_Composite_Table[6 * 68 + 3]; + double i = CGA_Composite_Table[6 * 68] - CGA_Composite_Table[6 * 68 + 2]; + double q = CGA_Composite_Table[6 * 68 + 1] - CGA_Composite_Table[6 * 68 + 3]; - double a = tau * (33 + 90 + hue_offset + mode_hue) / 360.0; - double c = cos(a); - double s = sin(a); - double r = 256 * mode_saturation / sqrt(i * i + q * q); + double a = tau * (33 + 90 + hue_offset + mode_hue) / 360.0; + double c = cos(a); + double s = sin(a); + double r = 256 * mode_saturation / sqrt(i * i + q * q); - double iq_adjust_i = -(i * c + q * s) * r; - double iq_adjust_q = (q * c - i * s) * r; + double iq_adjust_i = -(i * c + q * s) * r; + double iq_adjust_q = (q * c - i * s) * r; - static const double ri = 0.9563; - static const double rq = 0.6210; - static const double gi = -0.2721; - static const double gq = -0.6474; - static const double bi = -1.1069; - static const double bq = 1.7046; + static const double ri = 0.9563; + static const double rq = 0.6210; + static const double gi = -0.2721; + static const double gq = -0.6474; + static const double bi = -1.1069; + static const double bq = 1.7046; - video_ri = (int)(ri * iq_adjust_i + rq * iq_adjust_q); - video_rq = (int)(-ri * iq_adjust_q + rq * iq_adjust_i); - video_gi = (int)(gi * iq_adjust_i + gq * iq_adjust_q); - video_gq = (int)(-gi * iq_adjust_q + gq * iq_adjust_i); - video_bi = (int)(bi * iq_adjust_i + bq * iq_adjust_q); - video_bq = (int)(-bi * iq_adjust_q + bq * iq_adjust_i); - video_sharpness = (int)(sharpness * 256 / 100); + video_ri = (int)(ri * iq_adjust_i + rq * iq_adjust_q); + video_rq = (int)(-ri * iq_adjust_q + rq * iq_adjust_i); + video_gi = (int)(gi * iq_adjust_i + gq * iq_adjust_q); + video_gq = (int)(-gi * iq_adjust_q + gq * iq_adjust_i); + video_bi = (int)(bi * iq_adjust_i + bq * iq_adjust_q); + video_bq = (int)(-bi * iq_adjust_q + bq * iq_adjust_i); + video_sharpness = (int)(sharpness * 256 / 100); } static Bit8u byte_clamp(int v) { - v >>= 13; - return v < 0 ? 0 : (v > 255 ? 255 : v); + v >>= 13; + return v < 0 ? 0 : (v > 255 ? 255 : v); } /* 2048x1536 is the maximum we can possibly support. */ @@ -148,157 +142,162 @@ static int temp[SCALER_MAXWIDTH + 10] = {0}; static int atemp[SCALER_MAXWIDTH + 2] = {0}; static int btemp[SCALER_MAXWIDTH + 2] = {0}; -Bit8u *Composite_Process(uint8_t cgamode, Bit8u border, Bit32u blocks/*, bool doublewidth*/, Bit8u *TempLine) { - int x; - Bit32u x2; +Bit8u *Composite_Process(uint8_t cgamode, Bit8u border, Bit32u blocks /*, bool doublewidth*/, Bit8u *TempLine) { + int x; + Bit32u x2; - int w = blocks * 4; + int w = blocks * 4; -#define COMPOSITE_CONVERT(I, Q) do { \ - i[1] = (i[1]<<3) - ap[1]; \ - a = ap[0]; \ - b = bp[0]; \ - c = i[0]+i[0]; \ - d = i[-1]+i[1]; \ - y = ((c+d)<<8) + video_sharpness*(c-d); \ - rr = y + video_ri*(I) + video_rq*(Q); \ - gg = y + video_gi*(I) + video_gq*(Q); \ - bb = y + video_bi*(I) + video_bq*(Q); \ - ++i; \ - ++ap; \ - ++bp; \ - *srgb = (byte_clamp(rr)<<16) | (byte_clamp(gg)<<8) | byte_clamp(bb); \ - ++srgb; \ -} while (0) +#define COMPOSITE_CONVERT(I, Q) \ + do { \ + i[1] = (i[1] << 3) - ap[1]; \ + a = ap[0]; \ + b = bp[0]; \ + c = i[0] + i[0]; \ + d = i[-1] + i[1]; \ + y = ((c + d) << 8) + video_sharpness * (c - d); \ + rr = y + video_ri * (I) + video_rq * (Q); \ + gg = y + video_gi * (I) + video_gq * (Q); \ + bb = y + video_bi * (I) + video_bq * (Q); \ + ++i; \ + ++ap; \ + ++bp; \ + *srgb = (byte_clamp(rr) << 16) | (byte_clamp(gg) << 8) | byte_clamp(bb); \ + ++srgb; \ + } while (0) -#define OUT(v) do { *o = (v); ++o; } while (0) +#define OUT(v) \ + do { \ + *o = (v); \ + ++o; \ + } while (0) - // Simulate CGA composite output - int *o = temp; - Bit8u *rgbi = TempLine; - int *b = &CGA_Composite_Table[border * 68]; - for (x = 0; x < 4; ++x) - OUT(b[(x + 3) & 3]); - OUT(CGA_Composite_Table[(border << 6) | ((*rgbi) << 2) | 3]); - for (x = 0; x < w - 1; ++x) { - OUT(CGA_Composite_Table[(rgbi[0] << 6) | (rgbi[1] << 2) | (x & 3)]); - ++rgbi; - } - OUT(CGA_Composite_Table[((*rgbi) << 6) | (border << 2) | 3]); - for (x = 0; x < 5; ++x) - OUT(b[x & 3]); + // Simulate CGA composite output + int *o = temp; + Bit8u *rgbi = TempLine; + int *b = &CGA_Composite_Table[border * 68]; + for (x = 0; x < 4; ++x) + OUT(b[(x + 3) & 3]); + OUT(CGA_Composite_Table[(border << 6) | ((*rgbi) << 2) | 3]); + for (x = 0; x < w - 1; ++x) { + OUT(CGA_Composite_Table[(rgbi[0] << 6) | (rgbi[1] << 2) | (x & 3)]); + ++rgbi; + } + OUT(CGA_Composite_Table[((*rgbi) << 6) | (border << 2) | 3]); + for (x = 0; x < 5; ++x) + OUT(b[x & 3]); - if ((cgamode & 4) != 0) { - // Decode - int *i = temp + 5; - Bit32u *srgb = (Bit32u *)TempLine; - for (x2 = 0; x2 < blocks * 4; ++x2) { - int c = (i[0] + i[0]) << 3; - int d = (i[-1] + i[1]) << 3; - int y = ((c + d) << 8) + video_sharpness * (c - d); - ++i; - *srgb = byte_clamp(y) * 0x10101; - ++srgb; - } - } else { - // Store chroma - int *i = temp + 4; - int *ap = atemp + 1; - int *bp = btemp + 1; - for (x = -1; x < w + 1; ++x) { - ap[x] = i[-4] - ((i[-2] - i[0] + i[2]) << 1) + i[4]; - bp[x] = (i[-3] - i[-1] + i[1] - i[3]) << 1; - ++i; - } + if ((cgamode & 4) != 0) { + // Decode + int *i = temp + 5; + Bit32u *srgb = (Bit32u *)TempLine; + for (x2 = 0; x2 < blocks * 4; ++x2) { + int c = (i[0] + i[0]) << 3; + int d = (i[-1] + i[1]) << 3; + int y = ((c + d) << 8) + video_sharpness * (c - d); + ++i; + *srgb = byte_clamp(y) * 0x10101; + ++srgb; + } + } else { + // Store chroma + int *i = temp + 4; + int *ap = atemp + 1; + int *bp = btemp + 1; + for (x = -1; x < w + 1; ++x) { + ap[x] = i[-4] - ((i[-2] - i[0] + i[2]) << 1) + i[4]; + bp[x] = (i[-3] - i[-1] + i[1] - i[3]) << 1; + ++i; + } - // Decode - i = temp + 5; - i[-1] = (i[-1] << 3) - ap[-1]; - i[0] = (i[0] << 3) - ap[0]; - Bit32u *srgb = (Bit32u *)TempLine; - for (x2 = 0; x2 < blocks; ++x2) { - int y, a, b, c, d, rr, gg, bb; - COMPOSITE_CONVERT(a, b); - COMPOSITE_CONVERT(-b, a); - COMPOSITE_CONVERT(-a, -b); - COMPOSITE_CONVERT(b, -a); - } - } + // Decode + i = temp + 5; + i[-1] = (i[-1] << 3) - ap[-1]; + i[0] = (i[0] << 3) - ap[0]; + Bit32u *srgb = (Bit32u *)TempLine; + for (x2 = 0; x2 < blocks; ++x2) { + int y, a, b, c, d, rr, gg, bb; + COMPOSITE_CONVERT(a, b); + COMPOSITE_CONVERT(-b, a); + COMPOSITE_CONVERT(-a, -b); + COMPOSITE_CONVERT(b, -a); + } + } #undef COMPOSITE_CONVERT #undef OUT - return TempLine; + return TempLine; } void IncreaseHue(uint8_t cgamode) { - hue_offset += 5.0; + hue_offset += 5.0; - update_cga16_color(cgamode); + update_cga16_color(cgamode); } void DecreaseHue(uint8_t cgamode) { - hue_offset -= 5.0; + hue_offset -= 5.0; - update_cga16_color(cgamode); + update_cga16_color(cgamode); } void IncreaseSaturation(uint8_t cgamode) { - saturation += 5; + saturation += 5; - update_cga16_color(cgamode); + update_cga16_color(cgamode); } void DecreaseSaturation(uint8_t cgamode) { - saturation -= 5; + saturation -= 5; - update_cga16_color(cgamode); + update_cga16_color(cgamode); } void IncreaseContrast(uint8_t cgamode) { - contrast += 5; + contrast += 5; - update_cga16_color(cgamode); + update_cga16_color(cgamode); } void DecreaseContrast(uint8_t cgamode) { - contrast -= 5; + contrast -= 5; - update_cga16_color(cgamode); + update_cga16_color(cgamode); } void IncreaseBrightness(uint8_t cgamode) { - brightness += 5; + brightness += 5; - update_cga16_color(cgamode); + update_cga16_color(cgamode); } void DecreaseBrightness(uint8_t cgamode) { - brightness -= 5; + brightness -= 5; - update_cga16_color(cgamode); + update_cga16_color(cgamode); } void IncreaseSharpness(uint8_t cgamode) { - sharpness += 10; + sharpness += 10; - update_cga16_color(cgamode); + update_cga16_color(cgamode); } void DecreaseSharpness(uint8_t cgamode) { - sharpness -= 10; + sharpness -= 10; - update_cga16_color(cgamode); + update_cga16_color(cgamode); } void cga_comp_init(int revision) { - new_cga = revision; + new_cga = revision; - /* Making sure this gets reset after reset. */ - brightness = 0; - contrast = 100; - saturation = 100; - sharpness = 0; - hue_offset = 0; + /* Making sure this gets reset after reset. */ + brightness = 0; + contrast = 100; + saturation = 100; + sharpness = 0; + hue_offset = 0; - update_cga16_color(0); + update_cga16_color(0); } diff --git a/src/fdi2raw.c b/src/fdi2raw.c index 646b909d..c13b68bb 100644 --- a/src/fdi2raw.c +++ b/src/fdi2raw.c @@ -53,24 +53,25 @@ #include #ifdef DEBUG -static char *datalog(uae_u8 *src, int len) -{ - static char buf[1000]; - static int offset; - int i = 0, offset2; +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; + 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 ""; } @@ -81,23 +82,21 @@ static char *datalog(uae_u8 *src, int len) { return ""; } 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_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; +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 @@ -111,209 +110,209 @@ static void *fdi_malloc (int size) #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; + 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]; + 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])) +#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; + 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; + 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); - } + 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); - } + 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); - } + 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); - } + 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; + if (v & 0x8000) + v |= 0xffff0000; + return v; } static uae_u32 sign_extend8(uae_u32 v) { - if (v & 0x80) - v |= 0xffffff00; - return 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; + 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) { + 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; + // 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 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); + // 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); - } + // 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; + 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) { - outlog("track %d: unknown track type 0x%02.2X\n", fdi->current_track, fdi->track_type); -// return -1; + outlog("track %d: unknown track type 0x%02.2X\n", fdi->current_track, fdi->track_type); + // return -1; } /* unsupported track */ #if 0 @@ -325,13 +324,13 @@ static void zyy (FDI *fdi) #endif /* empty track */ static void track_empty(FDI *fdi) { -// return 0; + // return 0; } /* unknown sector described type */ static void dxx(FDI *fdi) { - outlog("\ntrack %d: unknown sector described type 0x%02.2X\n", fdi->current_track, fdi->track_type); - fdi->err = 1; + outlog("\ntrack %d: unknown sector described type 0x%02.2X\n", fdi->current_track, fdi->track_type); + fdi->err = 1; } /* unsupported sector described type */ #if 0 @@ -343,97 +342,97 @@ static void dyy (FDI *fdi) #endif /* 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) { - outlog("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; - outlog("mfmsync buffer overflow\n"); - fdi->err = 1; - } - fdi->out++; + if (fdi->nextdrop) { + fdi->nextdrop = 0; + return; + } + fdi->mfmsync_buffer[fdi->mfmsync_offset++] = fdi->out; + if (fdi->out == 0) { + outlog("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; + outlog("mfmsync buffer overflow\n"); + fdi->err = 1; + } + fdi->out++; } #define BIT_BYTEOFFSET ((fdi->out) >> 3) -#define BIT_BITOFFSET (7-((fdi->out)&7)) +#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) { - outlog("destination buffer overflow\n"); - fdi->err = 1; - fdi->out = 1; - } + 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) { + outlog("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); + add_mfm_sync_bit(fdi); + bit_add(fdi, bit); } /* remove following bit */ static void bit_drop_next(FDI *fdi) { - if (fdi->nextdrop > 0) { - outlog("multiple bit_drop_next() called"); - } else if (fdi->nextdrop < 0) { - fdi->nextdrop = 0; - debuglog(":DNN:"); - return; - } - debuglog(":DN:"); - fdi->nextdrop = 1; + if (fdi->nextdrop > 0) { + outlog("multiple bit_drop_next() called"); + } else if (fdi->nextdrop < 0) { + fdi->nextdrop = 0; + debuglog(":DNN:"); + return; + } + debuglog(":DN:"); + fdi->nextdrop = 1; } /* ignore next bit_drop_next() */ static void bit_dedrop(FDI *fdi) { - if (fdi->nextdrop) { - outlog("bit_drop_next called before bit_dedrop"); - } - fdi->nextdrop = -1; - debuglog(":BDD:"); + if (fdi->nextdrop) { + outlog("bit_drop_next called before bit_dedrop"); + } + fdi->nextdrop = -1; + debuglog(":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)); + 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); + 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)); + 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); + 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)); + int i; + for (i = 14; i >= 0; i -= 2) + bit_mfm_add(fdi, v & (1 << i)); } /* bit 0 */ @@ -448,102 +447,102 @@ static void s03(FDI *fdi) { word_add(fdi, 0x5224); } 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; - debuglog("s08:len=%d,data=%02.2X", bytes, byte); - while (bytes--) - byte_add(fdi, byte); + int bytes = *fdi->track_src++; + uae_u8 byte = *fdi->track_src++; + if (bytes == 0) + bytes = 256; + debuglog("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); - debuglog("s09:len=%d,data=%02.2X", bytes, byte); - while (bytes--) - byte_mfm_add(fdi, byte); + int bytes = *fdi->track_src++; + uae_u8 byte = *fdi->track_src++; + if (bytes == 0) + bytes = 256; + bit_drop_next(fdi); + debuglog("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; - debuglog("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--; - } - } + int i, bits = (fdi->track_src[0] << 8) | fdi->track_src[1]; + uae_u8 b; + fdi->track_src += 2; + debuglog("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; - debuglog("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--; - } - } + int i, bits = ((fdi->track_src[0] << 8) | fdi->track_src[1]) + 65536; + uae_u8 b; + fdi->track_src += 2; + debuglog("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); - debuglog("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--; - } - } + int i, bits = (fdi->track_src[0] << 8) | fdi->track_src[1]; + uae_u8 b; + fdi->track_src += 2; + bit_drop_next(fdi); + debuglog("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); - debuglog("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--; - } - } + int i, bits = ((fdi->track_src[0] << 8) | fdi->track_src[1]) + 65536; + uae_u8 b; + fdi->track_src += 2; + bit_drop_next(fdi); + debuglog("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--; + } + } } /* ***** */ @@ -554,33 +553,33 @@ static void s0d(FDI *fdi) { /*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++; - } + if (shift == 0) + return; + while (start <= end) { + start[0] <<= shift; + start[0] |= start[1] >> (8 - shift); + start++; + } }*/ -//static int check_offset; +// static int check_offset; /*static uae_u16 getmfmword (uae_u8 *mbuf) { - uae_u32 v; + 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; + 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; + return ((getmfmword (mbuf) << 16) | getmfmword (mbuf + 2)) & MFMMASK; }*/ #if 0 @@ -743,165 +742,162 @@ static int amiga_check_track (FDI *fdi) #endif static void amiga_data_raw(FDI *fdi, uae_u8 *secbuf, uae_u8 *crc, int len) { - int i; - uae_u8 crcbuf[4]; + 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]); + 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; + 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 < 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]); + 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; + 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); + 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; + 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]); + 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); - debuglog("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; + bit_drop_next(fdi); + debuglog("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); - debuglog("s21:header=%s", datalog(fdi->track_src, 4)); - amiga_sector_header(fdi, fdi->track_src, 0, 0, 0); - fdi->track_src += 4; + bit_drop_next(fdi); + debuglog("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); - debuglog("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; + bit_drop_next(fdi); + debuglog("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) { - debuglog("s23:data=%s", datalog(fdi->track_src, 512)); - amiga_data(fdi, fdi->track_src); - fdi->track_src += 512; + debuglog("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++; - debuglog("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; + int shift = *fdi->track_src++; + debuglog("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++; - debuglog("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); + int shift = *fdi->track_src++; + debuglog("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); - debuglog("s26:data=%s", datalog(fdi->track_src, 512)); - amiga_data(fdi, fdi->track_src); - fdi->track_src += 512; + s21(fdi); + debuglog("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); - debuglog("s27:data=%s", datalog(fdi->track_src, 512)); - amiga_data(fdi, fdi->track_src); - fdi->track_src += 512; + s22(fdi); + debuglog("s27:data=%s", datalog(fdi->track_src, 512)); + amiga_data(fdi, fdi->track_src); + fdi->track_src += 512; } /* *** */ @@ -909,393 +905,392 @@ static void s27(FDI *fdi) { /* *** */ static uae_u16 ibm_crc(uae_u8 byte, int reset) { - static uae_u16 crc; - int i; + 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; + 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; + 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]); + 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; + 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]); + 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); + 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); + 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); + bit_drop_next(fdi); + bytes_mfm_add(fdi, 0x4e, 78); } /* standard extended IBM sector header */ static void s13(FDI *fdi) { - bit_drop_next(fdi); - debuglog("s13:header=%s", datalog(fdi->track_src, 4)); - ibm_sector_header(fdi, fdi->track_src, 0, -1, 1); - fdi->track_src += 4; + bit_drop_next(fdi); + debuglog("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) { - debuglog("s14:header=%s", datalog(fdi->track_src, 4)); - ibm_sector_header(fdi, fdi->track_src, 0, -1, 0); - fdi->track_src += 4; + debuglog("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); - debuglog("s15:sector=%d", *fdi->track_src); - ibm_sector_header(fdi, 0, 0, *fdi->track_src++, 1); + bit_drop_next(fdi); + debuglog("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) { - debuglog("s16:track=%d", *fdi->track_src); - ibm_sector_header(fdi, 0, 0, *fdi->track_src++, 0); + debuglog("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) { - debuglog("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; + debuglog("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) { - debuglog("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; + debuglog("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) { - debuglog("s19:data=%s", datalog(fdi->track_src, 512)); - ibm_data(fdi, fdi->track_src, 0, 512); - fdi->track_src += 512; + debuglog("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++; - debuglog("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; + int shift = *fdi->track_src++; + debuglog("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++; - debuglog("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; + int shift = *fdi->track_src++; + debuglog("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; + 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); + s15(fdi); + bytes_mfm_add(fdi, 0x4e, 22); + bytes_mfm_add(fdi, 0x00, 12); + s19(fdi); } /* end marker */ -static void sff(FDI *fdi) { -} +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 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; + 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 */ + 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; + 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; + 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; + 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; + 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; + 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; + 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); -} +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); -} +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); -} +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); -} +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); -} +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); -} +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); -} +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 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; + 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; - } + 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; - outlog("sectors_described, index offset: %d\n", fdi->index_offset); + 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; + outlog("sectors_described, index offset: %d\n", fdi->index_offset); - do { - fdi->track_type = *fdi->track_src++; - outlog("%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); - outlog(" %d\n", fdi->out - oldout); - oldout = fdi->out; - if (fdi->out < 0 || fdi->err) { - outlog("\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) { - outlog("source buffer overrun, previous type: %02.2X\n", fdi->track_type); - return -1; - } - } while (fdi->track_type != 0xff); - outlog("\n"); - fix_mfm_sync(fdi); - return fdi->out; + do { + fdi->track_type = *fdi->track_src++; + outlog("%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); + outlog(" %d\n", fdi->out - oldout); + oldout = fdi->out; + if (fdi->out < 0 || fdi->err) { + outlog("\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) { + outlog("source buffer overrun, previous type: %02.2X\n", fdi->track_type); + return -1; + } + } while (fdi->track_type != 0xff); + outlog("\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; + 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; + *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) { @@ -1313,18 +1308,18 @@ static void dumpstream(int track, uae_u8 *stream, int len) { 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++; + int off1 = bitoffset / 8; + int off2 = bitoffset % 8; + p[off1] |= bit << (7 - off2); + bitoffset++; } struct pulse_sample { - uint32_t size; - int number_of_bits; + uint32_t size; + int number_of_bits; }; -#define FDI_MAX_ARRAY 10 /* change this value as you want */ +#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; @@ -1332,15 +1327,15 @@ 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; + 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; + 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 @@ -1472,617 +1467,606 @@ static void fdi2_decode (FDI *fdi, uint32_t totalavg, uae_u32 *avgp, uae_u32 *mi #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; +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) { - outlog("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) { + /* 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) { + outlog("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)))) { - //init_array(standard_MFM_2_bit_cell_size, mfm + 1); - 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. */ + /* 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)))) { + // init_array(standard_MFM_2_bit_cell_size, mfm + 1); + 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 <= (3 * (int64_t)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 <= (3 * (int64_t)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)) { - outlog("FDI: avg_pulse outside bounds! avg=%u min=%u max=%u\n", avg_pulse, min_pulse, max_pulse); - outlog("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) - outlog("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 <= (3 * (int64_t)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 <= (3 * (int64_t)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 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 <= (3 * (int64_t)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 <= (3 * (int64_t)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)) { + outlog("FDI: avg_pulse outside bounds! avg=%u min=%u max=%u\n", avg_pulse, min_pulse, + max_pulse); + outlog("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) + outlog("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 <= (3 * (int64_t)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 <= (3 * (int64_t)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++; - } - } - } + /* 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); - } + /* 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; - } + /* 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; + 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; + 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]; + 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; + 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; -// d = fdi->track_dst; - 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; - } + // d = fdi->track_dst; + 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 (p1[idx_off1] + 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++) { - int sum = p1[idx_off1] + p1[idx_off2]; - if (sum >= maxidx) { - totalavg += *p2; - } else { - weakbits++; - } - p2++; - p1 += idx_off3; - idxp[i] = sum; - } - len = totalavg / 100000; - outlog("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; + maxidx = 0; + indexoffset = 0; + p1 = idxp; + for (i = 0; i < pulses; i++) { + if (p1[idx_off1] + 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++) { + int sum = p1[idx_off1] + p1[idx_off2]; + if (sum >= maxidx) { + totalavg += *p2; + } else { + weakbits++; + } + p2++; + p1 += idx_off3; + idxp[i] = sum; + } + len = totalavg / 100000; + outlog("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; + 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; + 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); - debuglog("FREE: memory allocated %d\n", fdi_allocated); + 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); + debuglog("FREE: memory allocated %d\n", fdi_allocated); } -int fdi2raw_get_last_track(FDI *fdi) { - return fdi->last_track; -} +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; + if (fdi->header[152] == 0x02) + return 22; + return 11; } -int fdi2raw_get_last_head(FDI *fdi) { - return fdi->last_head; -} +int fdi2raw_get_last_head(FDI *fdi) { return fdi->last_head; } -int fdi2raw_get_rotation(FDI *fdi) { - return fdi->rotation_speed; -} +int fdi2raw_get_rotation(FDI *fdi) { return fdi->rotation_speed; } -int fdi2raw_get_bit_rate(FDI *fdi) { - return fdi->bit_rate; -} +int fdi2raw_get_bit_rate(FDI *fdi) { return fdi->bit_rate; } -int fdi2raw_get_type(FDI *fdi) { - return fdi->disk_type; -} +int fdi2raw_get_type(FDI *fdi) { return fdi->disk_type; } -int fdi2raw_get_write_protect(FDI *fdi) { - return fdi->write_protect; -} +int fdi2raw_get_write_protect(FDI *fdi) { return fdi->write_protect; } FDI *fdi2raw_header(FILE *f) { - int i, offset, oldseek; - uae_u8 type, size; - FDI *fdi; + int i, offset, oldseek; + uae_u8 type, size; + FDI *fdi; - debuglog("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; - } + debuglog("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->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; - outlog("FDI version %d.%d\n", fdi->header[140], fdi->header[141]); - outlog("last_track=%d rotation_speed=%d\n", fdi->last_track, fdi->rotation_speed); + 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; + outlog("FDI version %d.%d\n", fdi->header[140], fdi->header[141]); + outlog("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; + 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; + 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; +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); - //fdi2_gcr_decode (fdi, totalavg, avgp, minp, maxp, idxp, idx_off1, idx_off2, idx_off3, maxidx, pulses); - outlog("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; + 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); + // fdi2_gcr_decode (fdi, totalavg, avgp, minp, maxp, idxp, idx_off1, idx_off2, idx_off3, maxidx, pulses); + outlog("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; + 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); + 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]; +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); + 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->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; + 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; + 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; - outlog("track %d: srclen: %d track_type: %02.2X, bitrate: %d\n", - fdi->current_track, fdi->track_src_len, fdi->track_type, fdi->bit_rate); + outlog("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) { + if ((fdi->track_type & 0xc0) == 0x80) { - outlen = decode_lowlevel_track(fdi, track, cache); + outlen = decode_lowlevel_track(fdi, track, cache); - } else if ((fdi->track_type & 0xf0) == 0xf0) { + } else if ((fdi->track_type & 0xf0) == 0xf0) { - outlen = decode_raw_track(fdi); + outlen = decode_raw_track(fdi); - } else if ((fdi->track_type & 0xf0) == 0xe0) { + } else if ((fdi->track_type & 0xf0) == 0xe0) { - outlen = handle_sectors_described_track(fdi); + outlen = handle_sectors_described_track(fdi); - } else if ((fdi->track_type & 0xf0)) { + } else if ((fdi->track_type & 0xf0)) { - zxx(fdi); - outlen = -1; + zxx(fdi); + outlen = -1; - } else if (fdi->track_type < 0x10) { + } else if (fdi->track_type < 0x10) { - decode_normal_track[fdi->track_type](fdi); - fix_mfm_sync(fdi); - outlen = fdi->out; + decode_normal_track[fdi->track_type](fdi); + fix_mfm_sync(fdi); + outlen = fdi->out; - } else { + } else { - zxx(fdi); - outlen = -1; + zxx(fdi); + outlen = -1; + } - } + // amiga_check_track (fdi); -// amiga_check_track (fdi); + if (fdi->err) + return 0; - 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; + 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/flash/intel_flash.c b/src/flash/intel_flash.c index cf6d169f..ce87d5b6 100644 --- a/src/flash/intel_flash.c +++ b/src/flash/intel_flash.c @@ -3,424 +3,376 @@ #include "device.h" #include "mem.h" -#define FLASH_2MBIT 4 -#define FLASH_IS_BXB 2 -#define FLASH_INVERT 1 +#define FLASH_2MBIT 4 +#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 -#define BLOCK_MAIN2 4 /*2Mbit devices only*/ +#define BLOCK_MAIN 0 +#define BLOCK_DATA1 1 +#define BLOCK_DATA2 2 +#define BLOCK_BOOT 3 +#define BLOCK_MAIN2 4 /*2Mbit devices only*/ 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_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 }; typedef struct flash_t { - uint8_t command, status; - uint16_t flash_id; - uint8_t type; - int invert_high_pin; - mem_mapping_t mapping[8], mapping_h[10]; - uint32_t block_start[5], block_end[5], block_len[5]; - uint8_t array[256 * 1024]; - uint32_t addr_mask; + uint8_t command, status; + uint16_t flash_id; + uint8_t type; + int invert_high_pin; + mem_mapping_t mapping[8], mapping_h[10]; + uint32_t block_start[5], block_end[5], block_len[5]; + uint8_t array[256 * 1024]; + uint32_t addr_mask; } flash_t; static char 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; - // pclog("flash_read : addr=%08x command=%02x %04x:%08x\n", addr, flash->command, CS, cpu_state.pc); - addr &= flash->addr_mask; - switch (flash->command) { - case CMD_READ_ARRAY: - default:return flash->array[addr]; + flash_t *flash = (flash_t *)p; + if (flash->invert_high_pin) + addr ^= 0x10000; + // pclog("flash_read : addr=%08x command=%02x %04x:%08x\n", addr, flash->command, CS, cpu_state.pc); + addr &= flash->addr_mask; + 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_IID: + if (addr & 1) + return flash->flash_id; + return 0x89; - case CMD_READ_STATUS:return flash->status; - } + case CMD_READ_STATUS: + return flash->status; + } } static uint16_t flash_readw(uint32_t addr, void *p) { - flash_t *flash = (flash_t *)p; - addr &= flash->addr_mask; - if (flash->invert_high_pin) - addr ^= 0x10000; - switch (flash->command) { - case CMD_READ_ARRAY: - default:return *(uint16_t *)&(flash->array[addr]); + flash_t *flash = (flash_t *)p; + addr &= flash->addr_mask; + if (flash->invert_high_pin) + addr ^= 0x10000; + switch (flash->command) { + case CMD_READ_ARRAY: + default: + return *(uint16_t *)&(flash->array[addr]); - case CMD_IID:return 0x89 | (flash->flash_id << 8); + case CMD_IID: + return 0x89 | (flash->flash_id << 8); - case CMD_READ_STATUS:return flash->status; - } + case CMD_READ_STATUS: + return flash->status; + } } static uint32_t flash_readl(uint32_t addr, void *p) { - flash_t *flash = (flash_t *)p; - addr &= flash->addr_mask; - if (flash->invert_high_pin) - addr ^= 0x10000; - return *(uint32_t *)&(flash->array[addr]); + flash_t *flash = (flash_t *)p; + addr &= flash->addr_mask; + if (flash->invert_high_pin) + addr ^= 0x10000; + return *(uint32_t *)&(flash->array[addr]); } static void flash_write(uint32_t addr, uint8_t val, void *p) { - flash_t *flash = (flash_t *)p; - int i; -// pclog("flash_write : addr=%08x val=%02x command=%02x %04x:%08x\n", addr, val, flash->command, CS, cpu_state.pc); + flash_t *flash = (flash_t *)p; + int i; + // pclog("flash_write : addr=%08x val=%02x command=%02x %04x:%08x\n", addr, val, flash->command, CS, cpu_state.pc); - if (flash->invert_high_pin) - addr ^= 0x10000; - addr &= flash->addr_mask; + if (flash->invert_high_pin) + addr ^= 0x10000; + addr &= flash->addr_mask; - switch (flash->command) { - case CMD_ERASE_SETUP: - if (val == CMD_ERASE_CONFIRM) { - // pclog("flash_write: erase %05x\n", addr); + switch (flash->command) { + case CMD_ERASE_SETUP: + if (val == CMD_ERASE_CONFIRM) { + // pclog("flash_write: erase %05x\n", addr); - 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]); - } + 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; + flash->status = 0x80; + } + flash->command = CMD_READ_STATUS; + break; - case CMD_PROGRAM_SETUP: - // pclog("flash_write: program %05x %02x\n", addr, val); - if ((addr & 0x3e000) != (flash->block_start[3] & 0x3e000)) - flash->array[addr] = val; - flash->command = CMD_READ_STATUS; - flash->status = 0x80; - break; + case CMD_PROGRAM_SETUP: + // pclog("flash_write: program %05x %02x\n", addr, val); + if ((addr & 0x3e000) != (flash->block_start[3] & 0x3e000)) + 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; - } - } + 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; + 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) + 0x20000) & flash->addr_mask), 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) + 0x20000) & flash->addr_mask), 0, (void *)flash); - } + 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) + 0x20000) & flash->addr_mask), 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) + 0x20000) & flash->addr_mask), 0, (void *)flash); + } - if (flash->type & FLASH_2MBIT) { - mem_mapping_add(&flash->mapping_h[8], 0xfffc0000, 0x20000, - flash_read, flash_readw, flash_readl, - flash_write, mem_write_nullw, mem_write_nulll, - flash->array, 0, (void *)flash); - } + if (flash->type & FLASH_2MBIT) { + mem_mapping_add(&flash->mapping_h[8], 0xfffc0000, 0x20000, flash_read, flash_readw, flash_readl, flash_write, + mem_write_nullw, mem_write_nulll, flash->array, 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. */ +/* 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; + 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) + 0x20000) & flash->addr_mask), 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) + 0x20000) & flash->addr_mask), 0, (void *)flash); - } + 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) + 0x20000) & flash->addr_mask), 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) + 0x20000) & flash->addr_mask), 0, (void *)flash); + } - if (flash->type & FLASH_2MBIT) { - mem_mapping_add(&flash->mapping_h[8], 0xfffc0000, 0x10000, - flash_read, flash_readw, flash_readl, - flash_write, mem_write_nullw, mem_write_nulll, - flash->array + 0x10000, 0, (void *)flash); - mem_mapping_add(&flash->mapping_h[9], 0xfffd0000, 0x10000, - flash_read, flash_readw, flash_readl, - flash_write, mem_write_nullw, mem_write_nulll, - flash->array, 0, (void *)flash); - } + if (flash->type & FLASH_2MBIT) { + mem_mapping_add(&flash->mapping_h[8], 0xfffc0000, 0x10000, flash_read, flash_readw, flash_readl, flash_write, + mem_write_nullw, mem_write_nulll, flash->array + 0x10000, 0, (void *)flash); + mem_mapping_add(&flash->mapping_h[9], 0xfffd0000, 0x10000, flash_read, flash_readw, flash_readl, flash_write, + mem_write_nullw, mem_write_nulll, flash->array, 0, (void *)flash); + } } void *intel_flash_init(uint8_t type, uint8_t flash_id) { - FILE *f; - flash_t *flash = malloc(sizeof(flash_t)); - memset(flash, 0, sizeof(flash_t)); - char fpath[1024]; - int i; + FILE *f; + flash_t *flash = malloc(sizeof(flash_t)); + memset(flash, 0, sizeof(flash_t)); + char fpath[1024]; + int i; - flash->type = type; + flash->type = type; - switch (romset) { - case ROM_REVENGE:strcpy(flash_path, "revenge/"); - break; - case ROM_PB520R:strcpy(flash_path, "pb520r/"); - break; - case ROM_ENDEAVOR:strcpy(flash_path, "endeavor/"); - break; - case ROM_PB570:strcpy(flash_path, "pb570/"); - break; - case ROM_ZAPPA:strcpy(flash_path, "zappa/"); - break; - case ROM_P55VA:strcpy(flash_path, "p55va/"); - break; - case ROM_P55TVP4:strcpy(flash_path, "p55tvp4/"); - break; - case ROM_430VX:strcpy(flash_path, "430vx/"); - break; - case ROM_P55T2P4:strcpy(flash_path, "p55t2p4/"); - break; - case ROM_ITAUTEC_INFOWAYM:strcpy(flash_path, "infowaym/"); - break; - case ROM_VS440FX:strcpy(flash_path, "vs440fx/"); - break; - case ROM_GA686BX:strcpy(flash_path, "ga686bx/"); - break; + switch (romset) { + case ROM_REVENGE: + strcpy(flash_path, "revenge/"); + break; + case ROM_PB520R: + strcpy(flash_path, "pb520r/"); + break; + case ROM_ENDEAVOR: + strcpy(flash_path, "endeavor/"); + break; + case ROM_PB570: + strcpy(flash_path, "pb570/"); + break; + case ROM_ZAPPA: + strcpy(flash_path, "zappa/"); + break; + case ROM_P55VA: + strcpy(flash_path, "p55va/"); + break; + case ROM_P55TVP4: + strcpy(flash_path, "p55tvp4/"); + break; + case ROM_430VX: + strcpy(flash_path, "430vx/"); + break; + case ROM_P55T2P4: + strcpy(flash_path, "p55t2p4/"); + break; + case ROM_ITAUTEC_INFOWAYM: + strcpy(flash_path, "infowaym/"); + break; + case ROM_VS440FX: + strcpy(flash_path, "vs440fx/"); + break; + case ROM_GA686BX: + strcpy(flash_path, "ga686bx/"); + break; - default:fatal("intel_flash_init on unsupported ROM set %i\n", romset); - } - // pclog("Flash init: Path is: %s\n", flash_path); + default: + fatal("intel_flash_init on unsupported ROM set %i\n", romset); + } + // pclog("Flash init: Path is: %s\n", flash_path); - flash->flash_id = flash_id; + flash->flash_id = flash_id; - flash->addr_mask = (type & FLASH_2MBIT) ? 0x3ffff : 0x1ffff; + flash->addr_mask = (type & FLASH_2MBIT) ? 0x3ffff : 0x1ffff; -// flash->flash_id = (type & FLASH_IS_BXB) ? 0x95 : 0x94; - flash->invert_high_pin = (type & FLASH_INVERT); + // flash->flash_id = (type & FLASH_IS_BXB) ? 0x95 : 0x94; + flash->invert_high_pin = (type & FLASH_INVERT); - if (type & FLASH_2MBIT) { - flash->block_len[BLOCK_MAIN] = 0x20000; - flash->block_len[BLOCK_MAIN2] = 0x18000; - flash->block_len[BLOCK_DATA1] = 0x02000; - flash->block_len[BLOCK_DATA2] = 0x02000; - flash->block_len[BLOCK_BOOT] = 0x04000; + if (type & FLASH_2MBIT) { + flash->block_len[BLOCK_MAIN] = 0x20000; + flash->block_len[BLOCK_MAIN2] = 0x18000; + flash->block_len[BLOCK_DATA1] = 0x02000; + flash->block_len[BLOCK_DATA2] = 0x02000; + flash->block_len[BLOCK_BOOT] = 0x04000; - if (type & FLASH_IS_BXB) /* 28F001BX-B */ - { - flash->block_start[BLOCK_MAIN] = 0x20000; /* MAIN BLOCK */ - flash->block_end[BLOCK_MAIN] = 0x3ffff; - flash->block_start[BLOCK_MAIN2] = 0x08000; /* MAIN BLOCK */ - flash->block_end[BLOCK_MAIN2] = 0x1ffff; - flash->block_start[BLOCK_DATA1] = 0x04000; /* DATA AREA 1 BLOCK */ - flash->block_end[BLOCK_DATA1] = 0x05fff; - flash->block_start[BLOCK_DATA2] = 0x06000; /* DATA AREA 2 BLOCK */ - flash->block_end[BLOCK_DATA2] = 0x07fff; - flash->block_start[BLOCK_BOOT] = 0x00000; /* BOOT BLOCK */ - flash->block_end[BLOCK_BOOT] = 0x03fff; - } else /* 28F001BX-T */ - { - flash->block_start[BLOCK_MAIN] = 0x00000; /* MAIN BLOCK */ - flash->block_end[BLOCK_MAIN] = 0x1ffff; - flash->block_start[BLOCK_MAIN2] = 0x20000; /* MAIN BLOCK */ - flash->block_end[BLOCK_MAIN2] = 0x37fff; - flash->block_start[BLOCK_DATA1] = 0x38000; /* DATA AREA 1 BLOCK */ - flash->block_end[BLOCK_DATA1] = 0x39fff; - flash->block_start[BLOCK_DATA2] = 0x3a000; /* DATA AREA 2 BLOCK */ - flash->block_end[BLOCK_DATA2] = 0x3bfff; - flash->block_start[BLOCK_BOOT] = 0x3c000; /* BOOT BLOCK */ - flash->block_end[BLOCK_BOOT] = 0x3ffff; - } - } else { - /* 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] = 0x20000; /* MAIN BLOCK */ + flash->block_end[BLOCK_MAIN] = 0x3ffff; + flash->block_start[BLOCK_MAIN2] = 0x08000; /* MAIN BLOCK */ + flash->block_end[BLOCK_MAIN2] = 0x1ffff; + flash->block_start[BLOCK_DATA1] = 0x04000; /* DATA AREA 1 BLOCK */ + flash->block_end[BLOCK_DATA1] = 0x05fff; + flash->block_start[BLOCK_DATA2] = 0x06000; /* DATA AREA 2 BLOCK */ + flash->block_end[BLOCK_DATA2] = 0x07fff; + flash->block_start[BLOCK_BOOT] = 0x00000; /* BOOT BLOCK */ + flash->block_end[BLOCK_BOOT] = 0x03fff; + } else /* 28F001BX-T */ + { + flash->block_start[BLOCK_MAIN] = 0x00000; /* MAIN BLOCK */ + flash->block_end[BLOCK_MAIN] = 0x1ffff; + flash->block_start[BLOCK_MAIN2] = 0x20000; /* MAIN BLOCK */ + flash->block_end[BLOCK_MAIN2] = 0x37fff; + flash->block_start[BLOCK_DATA1] = 0x38000; /* DATA AREA 1 BLOCK */ + flash->block_end[BLOCK_DATA1] = 0x39fff; + flash->block_start[BLOCK_DATA2] = 0x3a000; /* DATA AREA 2 BLOCK */ + flash->block_end[BLOCK_DATA2] = 0x3bfff; + flash->block_start[BLOCK_BOOT] = 0x3c000; /* BOOT BLOCK */ + flash->block_end[BLOCK_BOOT] = 0x3ffff; + } + } else { + /* 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; - } - } + 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]); - } + 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); - if (type & FLASH_2MBIT) { - memcpy(flash->array + 0x20000, rom + 0x30000, 65536); - memcpy(flash->array + 0x30000, rom + 0x20000, 65536); - } - } else { - memcpy(flash->array, rom, 131072); - if (type & FLASH_2MBIT) - memcpy(flash->array + 0x20000, rom + 0x20000, 131072); - } + if (flash->invert_high_pin) { + memcpy(flash->array, rom + 65536, 65536); + memcpy(flash->array + 65536, rom, 65536); + if (type & FLASH_2MBIT) { + memcpy(flash->array + 0x20000, rom + 0x30000, 65536); + memcpy(flash->array + 0x30000, rom + 0x20000, 65536); + } + } else { + memcpy(flash->array, rom, 131072); + if (type & FLASH_2MBIT) + memcpy(flash->array + 0x20000, rom + 0x20000, 131072); + } - if (flash->invert_high_pin) { - intel_flash_add_mappings_inverted(flash); - } else { - intel_flash_add_mappings(flash); - } + 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; + flash->command = CMD_READ_ARRAY; + flash->status = 0; - strcpy(fpath, flash_path); - strcat(fpath, "flash.bin"); - f = romfopen(fpath, "rb"); - if (f) { - fread(&(flash->array[flash->block_start[BLOCK_MAIN]]), flash->block_len[BLOCK_MAIN], 1, f); - if (type & FLASH_2MBIT) - fread(&(flash->array[flash->block_start[BLOCK_MAIN2]]), flash->block_len[BLOCK_MAIN2], 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); - } + strcpy(fpath, flash_path); + strcat(fpath, "flash.bin"); + f = romfopen(fpath, "rb"); + if (f) { + fread(&(flash->array[flash->block_start[BLOCK_MAIN]]), flash->block_len[BLOCK_MAIN], 1, f); + if (type & FLASH_2MBIT) + fread(&(flash->array[flash->block_start[BLOCK_MAIN2]]), flash->block_len[BLOCK_MAIN2], 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); + } - return flash; + return flash; } /* For AMI BIOS'es - Intel 28F001BXT with high address pin inverted. */ -void *intel_flash_bxt_ami_init() { - return intel_flash_init(FLASH_INVERT, 0x94); -} +void *intel_flash_bxt_ami_init() { return intel_flash_init(FLASH_INVERT, 0x94); } /* For Award BIOS'es - Intel 28F001BXT with high address pin not inverted. */ -void *intel_flash_bxt_init() { - return intel_flash_init(0, 0x94); -} +void *intel_flash_bxt_init() { return intel_flash_init(0, 0x94); } /* For Acer BIOS'es - Intel 28F001BXB. */ -void *intel_flash_bxb_init() { - return intel_flash_init(FLASH_IS_BXB, 0x95); -} +void *intel_flash_bxb_init() { return intel_flash_init(FLASH_IS_BXB, 0x95); } -static void *intel_flash_28fb200bxt_init(void) { - return intel_flash_init(FLASH_INVERT | FLASH_2MBIT, 0x74); -} +static void *intel_flash_28fb200bxt_init(void) { return intel_flash_init(FLASH_INVERT | FLASH_2MBIT, 0x74); } -static void *intel_flash_28f002bc_init(void) { - return intel_flash_init(FLASH_INVERT | FLASH_2MBIT, 0x7c); -} +static void *intel_flash_28f002bc_init(void) { return intel_flash_init(FLASH_INVERT | FLASH_2MBIT, 0x7c); } void intel_flash_close(void *p) { - FILE *f; - flash_t *flash = (flash_t *)p; + FILE *f; + flash_t *flash = (flash_t *)p; - char fpath[1024]; + char fpath[1024]; - strcpy(fpath, flash_path); - strcat(fpath, "flash.bin"); - f = romfopen(fpath, "wb"); - fwrite(&(flash->array[flash->block_start[BLOCK_MAIN]]), flash->block_len[BLOCK_MAIN], 1, f); - if (flash->type & FLASH_2MBIT) - fwrite(&(flash->array[flash->block_start[BLOCK_MAIN2]]), flash->block_len[BLOCK_MAIN2], 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); + strcpy(fpath, flash_path); + strcat(fpath, "flash.bin"); + f = romfopen(fpath, "wb"); + fwrite(&(flash->array[flash->block_start[BLOCK_MAIN]]), flash->block_len[BLOCK_MAIN], 1, f); + if (flash->type & FLASH_2MBIT) + fwrite(&(flash->array[flash->block_start[BLOCK_MAIN2]]), flash->block_len[BLOCK_MAIN2], 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); + free(flash); } -device_t intel_flash_bxt_ami_device = - { - "Intel 28F001BXT Flash BIOS", - 0, - intel_flash_bxt_ami_init, - intel_flash_close, - NULL, - NULL, - NULL, - NULL, - NULL - }; +device_t intel_flash_bxt_ami_device = { + "Intel 28F001BXT Flash BIOS", 0, intel_flash_bxt_ami_init, intel_flash_close, NULL, NULL, NULL, NULL, NULL}; -device_t intel_flash_bxt_device = - { - "Intel 28F001BXT Flash BIOS", - 0, - intel_flash_bxt_init, - intel_flash_close, - NULL, - NULL, - NULL, - NULL, - NULL - }; +device_t intel_flash_bxt_device = { + "Intel 28F001BXT Flash BIOS", 0, intel_flash_bxt_init, intel_flash_close, NULL, NULL, NULL, NULL, NULL}; -device_t intel_flash_bxb_device = - { - "Intel 28F001BXB Flash BIOS", - 0, - intel_flash_bxb_init, - intel_flash_close, - NULL, - NULL, - NULL, - NULL, - NULL - }; +device_t intel_flash_bxb_device = { + "Intel 28F001BXB Flash BIOS", 0, intel_flash_bxb_init, intel_flash_close, NULL, NULL, NULL, NULL, NULL}; -device_t intel_flash_28fb200bxt_device = - { - "Intel 28FB200BX-T Flash BIOS", - 0, - intel_flash_28fb200bxt_init, - intel_flash_close, - NULL, - NULL, - NULL, - NULL, - NULL - }; +device_t intel_flash_28fb200bxt_device = { + "Intel 28FB200BX-T Flash BIOS", 0, intel_flash_28fb200bxt_init, intel_flash_close, NULL, NULL, NULL, NULL, NULL}; -device_t intel_flash_28f002bc_device = - { - "Intel 28F002BC Flash BIOS", - 0, - intel_flash_28f002bc_init, - intel_flash_close, - NULL, - NULL, - NULL, - NULL, - NULL - }; +device_t intel_flash_28f002bc_device = { + "Intel 28F002BC Flash BIOS", 0, intel_flash_28f002bc_init, intel_flash_close, NULL, NULL, NULL, NULL, NULL}; diff --git a/src/flash/rom.c b/src/flash/rom.c index ab5cbec6..308e9a1f 100644 --- a/src/flash/rom.c +++ b/src/flash/rom.c @@ -7,113 +7,100 @@ #include "paths.h" FILE *romfopen(char *fn, char *mode) { - FILE *f; - char s[512]; - int i; + FILE *f; + char s[512]; + int i; - for (i = 0; i < num_roms_paths; ++i) { - get_roms_path(i, s, 511); - put_backslash(s); - strcat(s, fn); - f = fopen(s, mode); - if (f) - return f; - } - return 0; + for (i = 0; i < num_roms_paths; ++i) { + get_roms_path(i, s, 511); + put_backslash(s); + strcat(s, fn); + f = fopen(s, mode); + if (f) + return f; + } + return 0; } int rom_present(char *fn) { - FILE *f; - f = romfopen(fn, "rb"); - if (f) { - fclose(f); - return 1; - } - return 0; + FILE *f; + f = romfopen(fn, "rb"); + if (f) { + fclose(f); + return 1; + } + return 0; } uint8_t rom_read(uint32_t addr, void *p) { - rom_t *rom = (rom_t *)p; -// pclog("rom_read : %08x %08x %02x\n", addr, rom->mask, rom->rom[addr & rom->mask]); - return rom->rom[addr & rom->mask]; + rom_t *rom = (rom_t *)p; + // pclog("rom_read : %08x %08x %02x\n", addr, rom->mask, rom->rom[addr & rom->mask]); + return rom->rom[addr & rom->mask]; } uint16_t rom_readw(uint32_t addr, void *p) { - rom_t *rom = (rom_t *)p; -// pclog("rom_readw: %08x %08x %04x\n", addr, rom->mask, *(uint16_t *)&rom->rom[addr & rom->mask]); - return *(uint16_t *)&rom->rom[addr & rom->mask]; + rom_t *rom = (rom_t *)p; + // pclog("rom_readw: %08x %08x %04x\n", addr, rom->mask, *(uint16_t *)&rom->rom[addr & rom->mask]); + return *(uint16_t *)&rom->rom[addr & rom->mask]; } uint32_t rom_readl(uint32_t addr, void *p) { - rom_t *rom = (rom_t *)p; -// pclog("rom_readl: %08x %08x %08x\n", addr, rom->mask, *(uint32_t *)&rom->rom[addr & rom->mask]); - return *(uint32_t *)&rom->rom[addr & rom->mask]; + rom_t *rom = (rom_t *)p; + // pclog("rom_readl: %08x %08x %08x\n", addr, rom->mask, *(uint32_t *)&rom->rom[addr & rom->mask]); + return *(uint32_t *)&rom->rom[addr & rom->mask]; } int rom_init(rom_t *rom, char *fn, uint32_t address, int size, int mask, int file_offset, uint32_t flags) { - FILE *f = romfopen(fn, "rb"); + FILE *f = romfopen(fn, "rb"); - if (!f) { - pclog("ROM image not found : %s\n", fn); - return -1; - } + if (!f) { + pclog("ROM image not found : %s\n", fn); + return -1; + } - rom->rom = malloc(size); - fseek(f, file_offset, SEEK_SET); - fread(rom->rom, size, 1, f); - fclose(f); + rom->rom = malloc(size); + fseek(f, file_offset, SEEK_SET); + fread(rom->rom, size, 1, f); + fclose(f); - rom->mask = mask; + rom->mask = mask; - mem_mapping_add(&rom->mapping, address, size, rom_read, - rom_readw, - rom_readl, - mem_write_null, - mem_write_nullw, - mem_write_nulll, - rom->rom, - flags | MEM_MAPPING_ROM, - rom); + mem_mapping_add(&rom->mapping, address, size, rom_read, rom_readw, rom_readl, mem_write_null, mem_write_nullw, + mem_write_nulll, rom->rom, flags | MEM_MAPPING_ROM, rom); - return 0; + return 0; } -int rom_init_interleaved(rom_t *rom, char *fn_low, char *fn_high, uint32_t address, int size, int mask, int file_offset, uint32_t flags) { - FILE *f_low = romfopen(fn_low, "rb"); - FILE *f_high = romfopen(fn_high, "rb"); - int c; +int rom_init_interleaved(rom_t *rom, char *fn_low, char *fn_high, uint32_t address, int size, int mask, int file_offset, + uint32_t flags) { + FILE *f_low = romfopen(fn_low, "rb"); + FILE *f_high = romfopen(fn_high, "rb"); + int c; - if (!f_low || !f_high) { - if (!f_low) - pclog("ROM image not found : %s\n", fn_low); - else - fclose(f_low); - if (!f_high) - pclog("ROM image not found : %s\n", fn_high); - else - fclose(f_high); - return -1; - } + if (!f_low || !f_high) { + if (!f_low) + pclog("ROM image not found : %s\n", fn_low); + else + fclose(f_low); + if (!f_high) + pclog("ROM image not found : %s\n", fn_high); + else + fclose(f_high); + return -1; + } - rom->rom = malloc(size); - fseek(f_low, file_offset, SEEK_SET); - fseek(f_high, file_offset, SEEK_SET); - for (c = 0; c < size; c += 2) { - rom->rom[c] = getc(f_low); - rom->rom[c + 1] = getc(f_high); - } - fclose(f_high); - fclose(f_low); + rom->rom = malloc(size); + fseek(f_low, file_offset, SEEK_SET); + fseek(f_high, file_offset, SEEK_SET); + for (c = 0; c < size; c += 2) { + rom->rom[c] = getc(f_low); + rom->rom[c + 1] = getc(f_high); + } + fclose(f_high); + fclose(f_low); - rom->mask = mask; + rom->mask = mask; - mem_mapping_add(&rom->mapping, address, size, rom_read, - rom_readw, - rom_readl, - mem_write_null, - mem_write_nullw, - mem_write_nulll, - rom->rom, - flags | MEM_MAPPING_ROM, - rom); + mem_mapping_add(&rom->mapping, address, size, rom_read, rom_readw, rom_readl, mem_write_null, mem_write_nullw, + mem_write_nulll, rom->rom, flags | MEM_MAPPING_ROM, rom); - return 0; + return 0; } diff --git a/src/flash/sst39sf010.c b/src/flash/sst39sf010.c index 52c19d70..76e5783e 100644 --- a/src/flash/sst39sf010.c +++ b/src/flash/sst39sf010.c @@ -6,232 +6,224 @@ #include "xi8088.h" typedef struct sst_t { - int command_state; - int id_mode; - int erase; - int dirty; + int command_state; + int id_mode; + int erase; + int dirty; - char flash_path[1024]; - uint8_t data[0x20000]; + char flash_path[1024]; + uint8_t data[0x20000]; } sst_t; -#define SST_CHIP_ERASE 0x10 -#define SST_SECTOR_ERASE 0x30 -#define SST_ERASE 0x80 -#define SST_SET_ID_MODE 0x90 -#define SST_BYTE_PROGRAM 0xa0 +#define SST_CHIP_ERASE 0x10 +#define SST_SECTOR_ERASE 0x30 +#define SST_ERASE 0x80 +#define SST_SET_ID_MODE 0x90 +#define SST_BYTE_PROGRAM 0xa0 #define SST_CLEAR_ID_MODE 0xf0 static void set_id_mode(sst_t *sst); static void clear_id_mode(sst_t *sst); static uint32_t sst_masked_rom_addr(uint32_t addr) { - // The flipped MSB of the Xi 8088 is only present in the on-disk files, - // in ram the mapping is as the software sees. This does not cause - // problems with the programming commands because they only use the - // lower 2 bytes. - if (romset == ROM_XI8088 && !xi8088_bios_128kb()) - return addr & 0xffff; - else - return addr & 0x1ffff; + // The flipped MSB of the Xi 8088 is only present in the on-disk files, + // in ram the mapping is as the software sees. This does not cause + // problems with the programming commands because they only use the + // lower 2 bytes. + if (romset == ROM_XI8088 && !xi8088_bios_128kb()) + return addr & 0xffff; + else + return addr & 0x1ffff; } static void sst_new_command(sst_t *sst, uint8_t val) { - switch (val) { - case SST_CHIP_ERASE: - if (sst->erase) { - memset(rom, 0xff, 0x20000); - memset(sst->data, 0xff, 0x20000); - } - sst->command_state = 0; - sst->erase = 0; - break; + switch (val) { + case SST_CHIP_ERASE: + if (sst->erase) { + memset(rom, 0xff, 0x20000); + memset(sst->data, 0xff, 0x20000); + } + sst->command_state = 0; + sst->erase = 0; + break; - case SST_ERASE:sst->command_state = 0; - sst->erase = 1; - break; + case SST_ERASE: + sst->command_state = 0; + sst->erase = 1; + break; - case SST_SET_ID_MODE: - if (!sst->id_mode) - set_id_mode(sst); - sst->command_state = 0; - sst->erase = 0; - break; + case SST_SET_ID_MODE: + if (!sst->id_mode) + set_id_mode(sst); + sst->command_state = 0; + sst->erase = 0; + break; - case SST_BYTE_PROGRAM:sst->command_state = 3; - sst->erase = 0; - break; + case SST_BYTE_PROGRAM: + sst->command_state = 3; + sst->erase = 0; + break; - case SST_CLEAR_ID_MODE: - if (sst->id_mode) - clear_id_mode(sst); - sst->command_state = 0; - sst->erase = 0; - break; + case SST_CLEAR_ID_MODE: + if (sst->id_mode) + clear_id_mode(sst); + sst->command_state = 0; + sst->erase = 0; + break; - default:sst->command_state = 0; - sst->erase = 0; - } + default: + sst->command_state = 0; + sst->erase = 0; + } } static void sst_sector_erase(sst_t *sst, uint32_t sst_addr) { -// pclog("SST sector erase sst_addr %08x\n", sst_addr); - memset(&rom[sst_addr & 0x1f000], 0xff, 4096); - memset(&sst->data[sst_addr & 0x1f000], 0xff, 4096); - sst->dirty = 1; + // pclog("SST sector erase sst_addr %08x\n", sst_addr); + memset(&rom[sst_addr & 0x1f000], 0xff, 4096); + memset(&sst->data[sst_addr & 0x1f000], 0xff, 4096); + sst->dirty = 1; } static uint8_t sst_read_id(uint32_t addr, void *p) { - if ((addr & 0xffff) == 0) - return 0xbf; /*SST*/ - else if ((addr & 0xffff) == 1) - return 0xb5; /*39SF010*/ - else - return 0xff; -// fatal("sst_read_id: addr=%08x\n", addr); + if ((addr & 0xffff) == 0) + return 0xbf; /*SST*/ + else if ((addr & 0xffff) == 1) + return 0xb5; /*39SF010*/ + else + return 0xff; + // fatal("sst_read_id: addr=%08x\n", addr); } static void sst_write(uint32_t addr, uint8_t val, void *p) { - sst_t *sst = (sst_t *)p; + sst_t *sst = (sst_t *)p; -// pclog("sst_write: addr=%08x val=%02x state=%i\n", addr, val, sst->command_state); - switch (sst->command_state) { - case 0: - if (val == 0xf0) { - if (sst->id_mode) - clear_id_mode(sst); - } else if ((addr & 0xffff) == 0x5555 && val == 0xaa) - sst->command_state = 1; - else - sst->command_state = 0; - break; - case 1: - if ((addr & 0xffff) == 0x2aaa && val == 0x55) - sst->command_state = 2; - else - sst->command_state = 0; - break; - case 2: - if ((addr & 0xffff) == 0x5555) - sst_new_command(sst, val); - else if (val == SST_SECTOR_ERASE && sst->erase) { - sst_sector_erase(sst, sst_masked_rom_addr(addr)); - sst->command_state = 0; - } else - sst->command_state = 0; - break; - case 3: -// pclog("Byte program %08x %02x\n", addr, val); - rom[sst_masked_rom_addr(addr)] = val; - sst->data[sst_masked_rom_addr(addr)] = val; - sst->command_state = 0; - sst->dirty = 1; - break; - } + // pclog("sst_write: addr=%08x val=%02x state=%i\n", addr, val, sst->command_state); + switch (sst->command_state) { + case 0: + if (val == 0xf0) { + if (sst->id_mode) + clear_id_mode(sst); + } else if ((addr & 0xffff) == 0x5555 && val == 0xaa) + sst->command_state = 1; + else + sst->command_state = 0; + break; + case 1: + if ((addr & 0xffff) == 0x2aaa && val == 0x55) + sst->command_state = 2; + else + sst->command_state = 0; + break; + case 2: + if ((addr & 0xffff) == 0x5555) + sst_new_command(sst, val); + else if (val == SST_SECTOR_ERASE && sst->erase) { + sst_sector_erase(sst, sst_masked_rom_addr(addr)); + sst->command_state = 0; + } else + sst->command_state = 0; + break; + case 3: + // pclog("Byte program %08x %02x\n", addr, val); + rom[sst_masked_rom_addr(addr)] = val; + sst->data[sst_masked_rom_addr(addr)] = val; + sst->command_state = 0; + sst->dirty = 1; + break; + } } static void set_id_mode(sst_t *sst) { - int c; + int c; - for (c = 0; c < 8; c++) { - mem_mapping_set_handler(&bios_mapping[c], - sst_read_id, NULL, NULL, - sst_write, NULL, NULL); - mem_mapping_set_p(&bios_mapping[c], sst); - mem_mapping_set_handler(&bios_high_mapping[c], - sst_read_id, NULL, NULL, - sst_write, NULL, NULL); - mem_mapping_set_p(&bios_high_mapping[c], sst); - } - sst->id_mode = 1; + for (c = 0; c < 8; c++) { + mem_mapping_set_handler(&bios_mapping[c], sst_read_id, NULL, NULL, sst_write, NULL, NULL); + mem_mapping_set_p(&bios_mapping[c], sst); + mem_mapping_set_handler(&bios_high_mapping[c], sst_read_id, NULL, NULL, sst_write, NULL, NULL); + mem_mapping_set_p(&bios_high_mapping[c], sst); + } + sst->id_mode = 1; } static void clear_id_mode(sst_t *sst) { - int c; + int c; - for (c = 0; c < 8; c++) { - mem_mapping_set_handler(&bios_mapping[c], - mem_read_bios, mem_read_biosw, mem_read_biosl, - sst_write, NULL, NULL); - mem_mapping_set_p(&bios_mapping[c], sst); - mem_mapping_set_handler(&bios_high_mapping[c], - mem_read_bios, mem_read_biosw, mem_read_biosl, - sst_write, NULL, NULL); - mem_mapping_set_p(&bios_high_mapping[c], sst); - } - sst->id_mode = 0; + for (c = 0; c < 8; c++) { + mem_mapping_set_handler(&bios_mapping[c], mem_read_bios, mem_read_biosw, mem_read_biosl, sst_write, NULL, NULL); + mem_mapping_set_p(&bios_mapping[c], sst); + mem_mapping_set_handler(&bios_high_mapping[c], mem_read_bios, mem_read_biosw, mem_read_biosl, sst_write, NULL, + NULL); + mem_mapping_set_p(&bios_high_mapping[c], sst); + } + sst->id_mode = 0; } static void *sst_39sf010_init() { - FILE *f; - sst_t *sst = malloc(sizeof(sst_t)); - memset(sst, 0, sizeof(sst_t)); + FILE *f; + sst_t *sst = malloc(sizeof(sst_t)); + memset(sst, 0, sizeof(sst_t)); - switch (romset) { - case ROM_XI8088:strcpy(sst->flash_path, "xi8088/"); - break; + switch (romset) { + case ROM_XI8088: + strcpy(sst->flash_path, "xi8088/"); + break; - case ROM_FIC_VA503P:strcpy(sst->flash_path, "fic_va503p/"); - break; + case ROM_FIC_VA503P: + strcpy(sst->flash_path, "fic_va503p/"); + break; - default:fatal("sst_39sf010_init on unsupported ROM set %i\n", romset); - } - strcat(sst->flash_path, "flash.bin"); - f = romfopen(sst->flash_path, "rb"); - if (f) { - switch (romset) { - case ROM_XI8088: - if (xi8088_bios_128kb()) - fread(rom + 0x10000, 0x10000, 1, f); - fread(rom, 0x10000, 1, f); - break; + default: + fatal("sst_39sf010_init on unsupported ROM set %i\n", romset); + } + strcat(sst->flash_path, "flash.bin"); + f = romfopen(sst->flash_path, "rb"); + if (f) { + switch (romset) { + case ROM_XI8088: + if (xi8088_bios_128kb()) + fread(rom + 0x10000, 0x10000, 1, f); + fread(rom, 0x10000, 1, f); + break; - case ROM_FIC_VA503P:fread(rom, 0x20000, 1, f); - break; + case ROM_FIC_VA503P: + fread(rom, 0x20000, 1, f); + break; - default:fatal("sst_39sf010_init on unsupported ROM set %i\n", romset); - } - fclose(f); - } - memcpy(sst->data, rom, 0x20000); + default: + fatal("sst_39sf010_init on unsupported ROM set %i\n", romset); + } + fclose(f); + } + memcpy(sst->data, rom, 0x20000); - clear_id_mode(sst); + clear_id_mode(sst); - return sst; + return sst; } static void sst_39sf010_close(void *p) { - sst_t *sst = (sst_t *)p; + sst_t *sst = (sst_t *)p; - if (sst->dirty) { - FILE *f = romfopen(sst->flash_path, "wb"); - switch (romset) { - case ROM_XI8088: - if (xi8088_bios_128kb()) - fwrite(sst->data + 0x10000, 0x10000, 1, f); - fwrite(sst->data, 0x10000, 1, f); - break; + if (sst->dirty) { + FILE *f = romfopen(sst->flash_path, "wb"); + switch (romset) { + case ROM_XI8088: + if (xi8088_bios_128kb()) + fwrite(sst->data + 0x10000, 0x10000, 1, f); + fwrite(sst->data, 0x10000, 1, f); + break; - case ROM_FIC_VA503P:fwrite(sst->data, 0x20000, 1, f); - break; + case ROM_FIC_VA503P: + fwrite(sst->data, 0x20000, 1, f); + break; - default:fatal("sst_39sf010_init on unsupported ROM set %i\n", romset); - } - fclose(f); - } + default: + fatal("sst_39sf010_init on unsupported ROM set %i\n", romset); + } + fclose(f); + } - free(sst); + free(sst); } -device_t sst_39sf010_device = - { - "SST 39SF010 Flash BIOS", - 0, - sst_39sf010_init, - sst_39sf010_close, - NULL, - NULL, - NULL, - NULL, - NULL - }; +device_t sst_39sf010_device = {"SST 39SF010 Flash BIOS", 0, sst_39sf010_init, sst_39sf010_close, NULL, NULL, NULL, NULL, NULL}; diff --git a/src/flash/tandy_eeprom.c b/src/flash/tandy_eeprom.c index aa345a6d..10ab8fc7 100644 --- a/src/flash/tandy_eeprom.c +++ b/src/flash/tandy_eeprom.c @@ -6,148 +6,144 @@ #include "nvr.h" typedef struct { - int state; - int count; - int addr; - int clock; - uint16_t data; - uint16_t store[64]; + int state; + int count; + int addr; + int clock; + uint16_t data; + uint16_t store[64]; - int romset; + int romset; } tandy_eeprom_t; -enum { - EEPROM_IDLE, - EEPROM_GET_OPERATION, - EEPROM_READ, - EEPROM_WRITE -}; +enum { EEPROM_IDLE, EEPROM_GET_OPERATION, EEPROM_READ, EEPROM_WRITE }; static int eeprom_data_out; void tandy_eeprom_write(uint16_t addr, uint8_t val, void *p) { - tandy_eeprom_t *eeprom = (tandy_eeprom_t *)p; + tandy_eeprom_t *eeprom = (tandy_eeprom_t *)p; - if ((val & 4) && !eeprom->clock) { -// pclog("eeprom_write %02x %i %i\n", val, eeprom->state, eeprom->count); - switch (eeprom->state) { - case EEPROM_IDLE: - switch (eeprom->count) { - case 0: - if (!(val & 3)) - eeprom->count = 1; - else - eeprom->count = 0; - break; - case 1: - if ((val & 3) == 2) - eeprom->count = 2; - else - eeprom->count = 0; - break; - case 2: - if ((val & 3) == 3) - eeprom->state = EEPROM_GET_OPERATION; - eeprom->count = 0; - break; - } - break; - case EEPROM_GET_OPERATION:eeprom->data = (eeprom->data << 1) | (val & 1); - eeprom->count++; - if (eeprom->count == 8) { - eeprom->count = 0; -// pclog("EEPROM get operation %02x\n", eeprom->data); - eeprom->addr = eeprom->data & 0x3f; - switch (eeprom->data & 0xc0) { - case 0x40:eeprom->state = EEPROM_WRITE; - break; - case 0x80:eeprom->state = EEPROM_READ; - eeprom->data = eeprom->store[eeprom->addr]; -// pclog("EEPROM read data %02x %04x\n", eeprom->addr, eeprom->data); - break; - default:eeprom->state = EEPROM_IDLE; - break; - } - } - break; + if ((val & 4) && !eeprom->clock) { + // pclog("eeprom_write %02x %i %i\n", val, eeprom->state, eeprom->count); + switch (eeprom->state) { + case EEPROM_IDLE: + switch (eeprom->count) { + case 0: + if (!(val & 3)) + eeprom->count = 1; + else + eeprom->count = 0; + break; + case 1: + if ((val & 3) == 2) + eeprom->count = 2; + else + eeprom->count = 0; + break; + case 2: + if ((val & 3) == 3) + eeprom->state = EEPROM_GET_OPERATION; + eeprom->count = 0; + break; + } + break; + case EEPROM_GET_OPERATION: + eeprom->data = (eeprom->data << 1) | (val & 1); + eeprom->count++; + if (eeprom->count == 8) { + eeprom->count = 0; + // pclog("EEPROM get operation %02x\n", eeprom->data); + eeprom->addr = eeprom->data & 0x3f; + switch (eeprom->data & 0xc0) { + case 0x40: + eeprom->state = EEPROM_WRITE; + break; + case 0x80: + eeprom->state = EEPROM_READ; + eeprom->data = eeprom->store[eeprom->addr]; + // pclog("EEPROM read data %02x %04x\n", + // eeprom->addr, eeprom->data); + break; + default: + eeprom->state = EEPROM_IDLE; + break; + } + } + break; - case EEPROM_READ:eeprom_data_out = eeprom->data & 0x8000; - eeprom->data <<= 1; - eeprom->count++; - if (eeprom->count == 16) { - eeprom->count = 0; - eeprom->state = EEPROM_IDLE; - } - break; - case EEPROM_WRITE:eeprom->data = (eeprom->data << 1) | (val & 1); - eeprom->count++; - if (eeprom->count == 16) { - eeprom->count = 0; - eeprom->state = EEPROM_IDLE; -// pclog("EEPROM write %04x to %02x\n", eeprom->data, eeprom->addr); - eeprom->store[eeprom->addr] = eeprom->data; - } - break; - } - } + case EEPROM_READ: + eeprom_data_out = eeprom->data & 0x8000; + eeprom->data <<= 1; + eeprom->count++; + if (eeprom->count == 16) { + eeprom->count = 0; + eeprom->state = EEPROM_IDLE; + } + break; + case EEPROM_WRITE: + eeprom->data = (eeprom->data << 1) | (val & 1); + eeprom->count++; + if (eeprom->count == 16) { + eeprom->count = 0; + eeprom->state = EEPROM_IDLE; + // pclog("EEPROM write %04x to %02x\n", eeprom->data, + // eeprom->addr); + eeprom->store[eeprom->addr] = eeprom->data; + } + break; + } + } - eeprom->clock = val & 4; + eeprom->clock = val & 4; } int tandy_eeprom_read() { -// pclog("tandy_eeprom_read: data_out=%x\n", eeprom_data_out); - return eeprom_data_out; + // pclog("tandy_eeprom_read: data_out=%x\n", eeprom_data_out); + return eeprom_data_out; } void *tandy_eeprom_init() { - tandy_eeprom_t *eeprom = malloc(sizeof(tandy_eeprom_t)); - FILE *f = NULL; + tandy_eeprom_t *eeprom = malloc(sizeof(tandy_eeprom_t)); + FILE *f = NULL; - memset(eeprom, 0, sizeof(tandy_eeprom_t)); + memset(eeprom, 0, sizeof(tandy_eeprom_t)); - eeprom->romset = romset; - switch (romset) { - case ROM_TANDY1000HX:f = nvrfopen("tandy1000hx.bin", "rb"); - break; - case ROM_TANDY1000SL2:f = nvrfopen("tandy1000sl2.bin", "rb"); - break; - } - if (f) { - fread(eeprom->store, 128, 1, f); - fclose(f); - } else - memset(eeprom->store, 0, 128); + eeprom->romset = romset; + switch (romset) { + case ROM_TANDY1000HX: + f = nvrfopen("tandy1000hx.bin", "rb"); + break; + case ROM_TANDY1000SL2: + f = nvrfopen("tandy1000sl2.bin", "rb"); + break; + } + if (f) { + fread(eeprom->store, 128, 1, f); + fclose(f); + } else + memset(eeprom->store, 0, 128); - io_sethandler(0x037c, 0x0001, NULL, NULL, NULL, tandy_eeprom_write, NULL, NULL, eeprom); + io_sethandler(0x037c, 0x0001, NULL, NULL, NULL, tandy_eeprom_write, NULL, NULL, eeprom); - return eeprom; + return eeprom; } void tandy_eeprom_close(void *p) { - tandy_eeprom_t *eeprom = (tandy_eeprom_t *)p; - FILE *f = NULL; + tandy_eeprom_t *eeprom = (tandy_eeprom_t *)p; + FILE *f = NULL; - switch (eeprom->romset) { - case ROM_TANDY1000HX:f = nvrfopen("tandy1000hx.bin", "wb"); - break; - case ROM_TANDY1000SL2:f = nvrfopen("tandy1000sl2.bin", "wb"); - break; - } - fwrite(eeprom->store, 128, 1, f); - fclose(f); + switch (eeprom->romset) { + case ROM_TANDY1000HX: + f = nvrfopen("tandy1000hx.bin", "wb"); + break; + case ROM_TANDY1000SL2: + f = nvrfopen("tandy1000sl2.bin", "wb"); + break; + } + fwrite(eeprom->store, 128, 1, f); + fclose(f); - free(eeprom); + free(eeprom); } -device_t tandy_eeprom_device = - { - "Tandy EEPROM", - 0, - tandy_eeprom_init, - tandy_eeprom_close, - NULL, - NULL, - NULL, - NULL, - NULL - }; +device_t tandy_eeprom_device = {"Tandy EEPROM", 0, tandy_eeprom_init, tandy_eeprom_close, NULL, NULL, NULL, NULL, NULL}; diff --git a/src/flash/tandy_rom.c b/src/flash/tandy_rom.c index 14c16768..98b95798 100644 --- a/src/flash/tandy_rom.c +++ b/src/flash/tandy_rom.c @@ -11,76 +11,62 @@ static int tandy_rom_offset; static mem_mapping_t tandy_rom_mapping; uint8_t tandy_read_rom(uint32_t addr, void *p) { - uint32_t addr2 = (addr & 0xffff) + tandy_rom_offset; -// if (!nopageerrors) pclog("tandy_read_rom: %05x %05x %02x %04x:%04x\n", addr, addr2, tandy_rom[addr2], CS,pc); - return tandy_rom[addr2]; + uint32_t addr2 = (addr & 0xffff) + tandy_rom_offset; + // if (!nopageerrors) pclog("tandy_read_rom: %05x %05x %02x %04x:%04x\n", addr, addr2, tandy_rom[addr2], CS,pc); + return tandy_rom[addr2]; } uint16_t tandy_read_romw(uint32_t addr, void *p) { - uint32_t addr2 = (addr & 0xffff) + tandy_rom_offset; -// if (!nopageerrors) pclog("tandy_read_romw: %05x %05x %04x %04x:%04x\n", addr, addr2, *(uint16_t *)&tandy_rom[addr2], CS,pc); - return *(uint16_t *)&tandy_rom[addr2]; + uint32_t addr2 = (addr & 0xffff) + tandy_rom_offset; + // if (!nopageerrors) pclog("tandy_read_romw: %05x %05x %04x %04x:%04x\n", addr, addr2, *(uint16_t + // *)&tandy_rom[addr2], CS,pc); + return *(uint16_t *)&tandy_rom[addr2]; } uint32_t tandy_read_roml(uint32_t addr, void *p) { - uint32_t addr2 = (addr & 0xffff) + tandy_rom_offset; -// if (!nopageerrors) pclog("tandy_read_roml: %05x %05x %08x\n", addr, addr2, *(uint32_t *)&tandy_rom[addr2]); - return *(uint32_t *)&tandy_rom[addr2]; + uint32_t addr2 = (addr & 0xffff) + tandy_rom_offset; + // if (!nopageerrors) pclog("tandy_read_roml: %05x %05x %08x\n", addr, addr2, *(uint32_t *)&tandy_rom[addr2]); + return *(uint32_t *)&tandy_rom[addr2]; } uint8_t tandy_rom_bank_read(uint16_t port, void *p) { - if (port == 0xffea) - return tandy_rom_bank ^ 0x10; - else - return 0xff; + if (port == 0xffea) + return tandy_rom_bank ^ 0x10; + else + return 0xff; } void tandy_rom_bank_write(uint16_t port, uint8_t val, void *p) { - if (port == 0xffea) { - tandy_rom_bank = val; - tandy_rom_offset = ((val ^ 4) & 7) * 0x10000; - mem_mapping_set_exec(&tandy_rom_mapping, &tandy_rom[tandy_rom_offset]); -// pclog("tandy_rom_bank_write: port=%04x val=%02x offset=%05x\n", port, val, tandy_rom_offset); - } -// else -// pclog("Bad tandy write port=%04x val=%02x\n", port, val); + if (port == 0xffea) { + tandy_rom_bank = val; + tandy_rom_offset = ((val ^ 4) & 7) * 0x10000; + mem_mapping_set_exec(&tandy_rom_mapping, &tandy_rom[tandy_rom_offset]); + // pclog("tandy_rom_bank_write: port=%04x val=%02x offset=%05x\n", port, val, tandy_rom_offset); + } + // else + // pclog("Bad tandy write port=%04x val=%02x\n", port, val); } void *tandy_rom_init() { - FILE *f, *ff; - int c; + FILE *f, *ff; + int c; - tandy_rom = malloc(0x80000); + tandy_rom = malloc(0x80000); - f = romfopen("tandy1000sl2/8079047.hu1", "rb"); - ff = romfopen("tandy1000sl2/8079048.hu2", "rb"); - for (c = 0x0000; c < 0x80000; c += 2) { - tandy_rom[c] = getc(f); - tandy_rom[c + 1] = getc(ff); - } - fclose(ff); - fclose(f); + f = romfopen("tandy1000sl2/8079047.hu1", "rb"); + ff = romfopen("tandy1000sl2/8079048.hu2", "rb"); + for (c = 0x0000; c < 0x80000; c += 2) { + tandy_rom[c] = getc(f); + tandy_rom[c + 1] = getc(ff); + } + fclose(ff); + fclose(f); - mem_mapping_add(&tandy_rom_mapping, 0xe0000, 0x10000, - tandy_read_rom, tandy_read_romw, tandy_read_roml, - NULL, NULL, NULL, - tandy_rom, MEM_MAPPING_EXTERNAL, NULL); + mem_mapping_add(&tandy_rom_mapping, 0xe0000, 0x10000, tandy_read_rom, tandy_read_romw, tandy_read_roml, NULL, NULL, NULL, + tandy_rom, MEM_MAPPING_EXTERNAL, NULL); - io_sethandler(0xffe8, 0x0008, tandy_rom_bank_read, NULL, NULL, tandy_rom_bank_write, NULL, NULL, NULL); + io_sethandler(0xffe8, 0x0008, tandy_rom_bank_read, NULL, NULL, tandy_rom_bank_write, NULL, NULL, NULL); - return tandy_rom; + return tandy_rom; } -void tandy_rom_close(void *p) { - free(p); -} +void tandy_rom_close(void *p) { free(p); } -device_t tandy_rom_device = - { - "Tandy 1000SL/2 ROM", - 0, - tandy_rom_init, - tandy_rom_close, - NULL, - NULL, - NULL, - NULL, - NULL - }; +device_t tandy_rom_device = {"Tandy 1000SL/2 ROM", 0, tandy_rom_init, tandy_rom_close, NULL, NULL, NULL, NULL, NULL}; diff --git a/src/floppy/fdc.c b/src/floppy/fdc.c index d611e8d7..80be3884 100644 --- a/src/floppy/fdc.c +++ b/src/floppy/fdc.c @@ -25,56 +25,56 @@ static int fdc_reset_stat = 0; /*FDC*/ typedef struct FDC { - uint8_t dor, stat, command, dat, st0; - int head, track[256], sector, drive, lastdrive; - int sector_size; - int rw_track; - int pos; - uint8_t params[256]; - uint8_t res[256]; - int pnum, ptot; - int rate; - uint8_t specify[256]; - int eot[256]; - int lock; - int perp; - uint8_t config, pretrk; - int abort; - uint8_t format_dat[256]; - int format_state; - int tc; - int written; + uint8_t dor, stat, command, dat, st0; + int head, track[256], sector, drive, lastdrive; + int sector_size; + int rw_track; + int pos; + uint8_t params[256]; + uint8_t res[256]; + int pnum, ptot; + int rate; + uint8_t specify[256]; + int eot[256]; + int lock; + int perp; + uint8_t config, pretrk; + int abort; + uint8_t format_dat[256]; + int format_state; + int tc; + int written; - int pcjr, ps1; + int pcjr, ps1; - pc_timer_t watchdog_timer; - int watchdog_count; + pc_timer_t watchdog_timer; + int watchdog_count; - int data_ready; - int inread; + int data_ready; + int inread; - int dskchg_activelow; - int enable_3f1; + int dskchg_activelow; + int enable_3f1; - int bitcell_period; + int bitcell_period; - int is_nsc; /* 1 = FDC is on a National Semiconductor Super I/O chip, 0 = other FDC. This is needed, - because the National Semiconductor Super I/O chips add some FDC commands. */ - int enh_mode; - int rwc[2]; - int boot_drive; - int densel_polarity; - int densel_force; - int drvrate[2]; + int is_nsc; /* 1 = FDC is on a National Semiconductor Super I/O chip, 0 = other FDC. This is needed, + because the National Semiconductor Super I/O chips add some FDC commands. */ + int enh_mode; + int rwc[2]; + int boot_drive; + int densel_polarity; + int densel_force; + int drvrate[2]; - int dma; - int fifo, tfifo; - int fifobufpos; - uint8_t fifobuf[16]; + int dma; + int fifo, tfifo; + int fifobufpos; + uint8_t fifobuf[16]; - int int_pending; + int int_pending; - pc_timer_t timer; + pc_timer_t timer; } FDC; static FDC fdc; @@ -89,1198 +89,1198 @@ int discrate[2]; int discint; void fdc_reset() { - fdc.stat = 0x80; - fdc.pnum = fdc.ptot = 0; - fdc.st0 = 0; - fdc.lock = 0; - fdc.head = 0; - fdc.abort = 0; - if (!AT && romset != ROM_XI8088 && romset != ROM_PC5086) { - fdc.rate = 2; - // fdc_update_rate(); - } -// pclog("Reset FDC\n"); + fdc.stat = 0x80; + fdc.pnum = fdc.ptot = 0; + fdc.st0 = 0; + fdc.lock = 0; + fdc.head = 0; + fdc.abort = 0; + if (!AT && romset != ROM_XI8088 && romset != ROM_PC5086) { + fdc.rate = 2; + // fdc_update_rate(); + } + // pclog("Reset FDC\n"); } void fdc_reset_fifo_buf() { - memset(fdc.fifobuf, 0, 16); - fdc.fifobufpos = 0; + memset(fdc.fifobuf, 0, 16); + fdc.fifobufpos = 0; } void fdc_fifo_buf_write(int val) { - if (fdc.fifobufpos < fdc.tfifo) { - fdc.fifobuf[fdc.fifobufpos] = val; - fdc.fifobufpos++; - fdc.fifobufpos %= fdc.tfifo; - // pclog("FIFO buffer position = %02X\n", fdc.fifobufpos); - if (fdc.fifobufpos == fdc.tfifo) - fdc.fifobufpos = 0; - } + if (fdc.fifobufpos < fdc.tfifo) { + fdc.fifobuf[fdc.fifobufpos] = val; + fdc.fifobufpos++; + fdc.fifobufpos %= fdc.tfifo; + // pclog("FIFO buffer position = %02X\n", fdc.fifobufpos); + if (fdc.fifobufpos == fdc.tfifo) + fdc.fifobufpos = 0; + } } int fdc_fifo_buf_read() { - int temp = 0; - if (fdc.fifobufpos < fdc.tfifo) { - temp = fdc.fifobuf[fdc.fifobufpos]; - fdc.fifobufpos++; - fdc.fifobufpos %= fdc.tfifo; - // pclog("FIFO buffer position = %02X\n", fdc.fifobufpos); - if (fdc.fifobufpos == fdc.tfifo) - fdc.fifobufpos = 0; - } - return temp; + int temp = 0; + if (fdc.fifobufpos < fdc.tfifo) { + temp = fdc.fifobuf[fdc.fifobufpos]; + fdc.fifobufpos++; + fdc.fifobufpos %= fdc.tfifo; + // pclog("FIFO buffer position = %02X\n", fdc.fifobufpos); + if (fdc.fifobufpos == fdc.tfifo) + fdc.fifobufpos = 0; + } + return temp; } /* For DMA mode, just goes ahead in FIFO buffer but doesn't actually read or write anything. */ void fdc_fifo_buf_dummy() { - if (fdc.fifobufpos < fdc.tfifo) { - fdc.fifobufpos++; - fdc.fifobufpos %= fdc.tfifo; - // pclog("FIFO buffer position = %02X\n", fdc.fifobufpos); - if (fdc.fifobufpos == fdc.tfifo) - fdc.fifobufpos = 0; - } + if (fdc.fifobufpos < fdc.tfifo) { + fdc.fifobufpos++; + fdc.fifobufpos %= fdc.tfifo; + // pclog("FIFO buffer position = %02X\n", fdc.fifobufpos); + if (fdc.fifobufpos == fdc.tfifo) + fdc.fifobufpos = 0; + } } static void fdc_int() { - if (!fdc.pcjr) - picint(1 << 6); + if (!fdc.pcjr) + picint(1 << 6); } static void fdc_watchdog_poll(void *p) { - FDC *fdc = (FDC *)p; + FDC *fdc = (FDC *)p; - fdc->watchdog_count--; - if (fdc->watchdog_count) - timer_advance_u64(&fdc->watchdog_timer, 1000 * TIMER_USEC); - else { -// pclog("Watchdog timed out\n"); + fdc->watchdog_count--; + if (fdc->watchdog_count) + timer_advance_u64(&fdc->watchdog_timer, 1000 * TIMER_USEC); + else { + // pclog("Watchdog timed out\n"); - if (fdc->dor & 0x20) - picint(1 << 6); - } + if (fdc->dor & 0x20) + picint(1 << 6); + } } /* fdc.rwc per Winbond W83877F datasheet: - 0 = normal; - 1 = 500 kbps, 360 rpm; - 2 = 500 kbps, 300 rpm; - 3 = 250 kbps + 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 and the rate actually being - processed by drive can mismatch, in which case the FDC won't receive the correct data. + Drive is only aware of selected rate and densel, so on real hardware, the rate expected by FDC and the rate actually being + processed by drive can mismatch, in which case the FDC won't receive the correct data. */ int bit_rate = 250; -void fdc_update_is_nsc(int is_nsc) { - fdc.is_nsc = is_nsc; -} +void fdc_update_is_nsc(int is_nsc) { fdc.is_nsc = is_nsc; } -void fdc_update_enh_mode(int enh_mode) { - fdc.enh_mode = enh_mode; -} +void fdc_update_enh_mode(int enh_mode) { fdc.enh_mode = enh_mode; } -int fdc_get_rwc(int drive) { - return fdc.rwc[drive]; -} +int fdc_get_rwc(int drive) { return fdc.rwc[drive]; } -void fdc_update_rwc(int drive, int rwc) { - fdc.rwc[drive] = rwc; -} +void fdc_update_rwc(int drive, int rwc) { fdc.rwc[drive] = rwc; } -int fdc_get_boot_drive() { - return fdc.boot_drive; -} +int fdc_get_boot_drive() { return fdc.boot_drive; } -void fdc_update_boot_drive(int boot_drive) { - fdc.boot_drive = boot_drive; -} +void fdc_update_boot_drive(int boot_drive) { fdc.boot_drive = boot_drive; } -void fdc_update_densel_polarity(int densel_polarity) { - fdc.densel_polarity = densel_polarity; -} +void fdc_update_densel_polarity(int densel_polarity) { fdc.densel_polarity = densel_polarity; } -void fdc_update_densel_force(int densel_force) { - fdc.densel_force = densel_force; -} +void fdc_update_densel_force(int densel_force) { fdc.densel_force = densel_force; } -void fdc_update_drvrate(int drive, int drvrate) { - fdc.drvrate[drive] = drvrate; -} +void fdc_update_drvrate(int drive, int drvrate) { fdc.drvrate[drive] = drvrate; } void fdc_update_rate(int drive) { - if ((fdc.rwc[drive] == 1) || (fdc.rwc[drive] == 2)) { - bit_rate = 500; - } else if (fdc.rwc[drive] == 3) { - bit_rate = 250; - } else - switch (fdc.rate) { - case 0: /*High density*/ - bit_rate = 500; - break; - case 1: /*Double density (360 rpm)*/ - switch (fdc.drvrate[drive]) { - case 0: bit_rate = 300; - break; - case 1: bit_rate = 500; - break; - case 2: bit_rate = 2000; - break; - } - break; - case 2: /*Double density*/ - bit_rate = 250; - break; - case 3: /*Extended density*/ - bit_rate = 1000; - break; - } + if ((fdc.rwc[drive] == 1) || (fdc.rwc[drive] == 2)) { + bit_rate = 500; + } else if (fdc.rwc[drive] == 3) { + bit_rate = 250; + } else + switch (fdc.rate) { + case 0: /*High density*/ + bit_rate = 500; + break; + case 1: /*Double density (360 rpm)*/ + switch (fdc.drvrate[drive]) { + case 0: + bit_rate = 300; + break; + case 1: + bit_rate = 500; + break; + case 2: + bit_rate = 2000; + break; + } + break; + case 2: /*Double density*/ + bit_rate = 250; + break; + case 3: /*Extended density*/ + bit_rate = 1000; + break; + } - fdc.bitcell_period = 1000000 / bit_rate * 2; /*Bitcell period in ns*/ -// pclog("fdc_update_rate: rate=%i bit_rate=%i bitcell_period=%i\n", fdc.rate, bit_rate, fdc.bitcell_period); + fdc.bitcell_period = 1000000 / bit_rate * 2; /*Bitcell period in ns*/ + // pclog("fdc_update_rate: rate=%i bit_rate=%i bitcell_period=%i\n", fdc.rate, bit_rate, fdc.bitcell_period); } -int fdc_get_bitcell_period() { - return fdc.bitcell_period; -} +int fdc_get_bitcell_period() { return fdc.bitcell_period; } static int fdc_get_densel(int drive) { - switch (fdc.rwc[drive]) { - case 1: - case 3: return 0; - case 2: return 1; - } + switch (fdc.rwc[drive]) { + case 1: + case 3: + return 0; + case 2: + return 1; + } - if (!fdc.is_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; - } - } + if (!fdc.is_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; - } + 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; + return 0; } static void fdc_rate(int drive) { - fdc_update_rate(drive); - disc_set_rate(drive, fdc.drvrate[drive], fdc.rate); - fdd_set_densel(fdc_get_densel(drive)); + fdc_update_rate(drive); + disc_set_rate(drive, fdc.drvrate[drive], fdc.rate); + fdd_set_densel(fdc_get_densel(drive)); } void fdc_write(uint16_t addr, uint8_t val, void *priv) { -// pclog("Write FDC %04X %02X %04X:%04X %i %02X %i rate=%i %i\n",addr,val,cs>>4,pc,ins,fdc.st0,ins,fdc.rate, fdc.data_ready); - int drive; + // pclog("Write FDC %04X %02X %04X:%04X %i %02X %i rate=%i %i\n",addr,val,cs>>4,pc,ins,fdc.st0,ins,fdc.rate, + // fdc.data_ready); + int drive; - cycles -= ISA_CYCLES(8); + cycles -= ISA_CYCLES(8); - switch (addr & 7) { - case 1: return; - case 2: /*DOR*/ -// if (val == 0xD && (cs >> 4) == 0xFC81600 && ins > 769619936) output = 3; -// printf("DOR was %02X\n",fdc.dor); - if (fdc.pcjr) { - if ((fdc.dor & 0x40) && !(val & 0x40)) { - timer_set_delay_u64(&fdc.watchdog_timer, 1000 * TIMER_USEC); - fdc.watchdog_count = 1000; - picintc(1 << 6); -// pclog("watchdog set %i %i\n", fdc.watchdog_timer, TIMER_USEC); - } - if ((val & 0x80) && !(fdc.dor & 0x80)) { - timer_set_delay_u64(&fdc.timer, 8 * TIMER_USEC); - discint = -1; - fdc_reset(); - } - disc_set_motor_enable(val & 0x01); - fdc.drive = 0; - } else { - if ((val & 4) && !(fdc.dor & 4)) { - timer_set_delay_u64(&fdc.timer, 8 * TIMER_USEC); - discint = -1; - fdc_reset(); - } - disc_set_motor_enable((val & 0xf0) ? 1 : 0); - fdc.drive = val & 3; - } - fdc.dor = val; -// printf("DOR now %02X\n",val); - return; - case 3: - /* TDR */ - if (fdc.enh_mode) { - drive = (fdc.dor & 1) ^ fdd_swap; - fdc.rwc[drive] = (val & 0x30) >> 4; - } - return; - case 4: - if (val & 0x80) { - timer_set_delay_u64(&fdc.timer, 8 * TIMER_USEC); - discint = -1; - fdc_reset(); - } - return; - case 5: /*Command register*/ - if ((fdc.stat & 0xf0) == 0xb0) { - if (fdc.pcjr || !fdc.fifo) { - fdc.dat = val; - fdc.stat &= ~0x80; - } else { - fdc_fifo_buf_write(val); - if (fdc.fifobufpos == 0) - fdc.stat &= ~0x80; - } - break; - } -// if (fdc.inread) -// rpclog("c82c711_fdc_write : writing while inread! %02X\n", val); -// rpclog("Write command reg %i %i\n",fdc.pnum, fdc.ptot); - if (fdc.pnum == fdc.ptot) { - fdc.tc = 0; - fdc.data_ready = 0; + switch (addr & 7) { + case 1: + return; + case 2: /*DOR*/ + // if (val == 0xD && (cs >> 4) == 0xFC81600 && ins > 769619936) output = 3; + // printf("DOR was %02X\n",fdc.dor); + if (fdc.pcjr) { + if ((fdc.dor & 0x40) && !(val & 0x40)) { + timer_set_delay_u64(&fdc.watchdog_timer, 1000 * TIMER_USEC); + fdc.watchdog_count = 1000; + picintc(1 << 6); + // pclog("watchdog set %i %i\n", fdc.watchdog_timer, TIMER_USEC); + } + if ((val & 0x80) && !(fdc.dor & 0x80)) { + timer_set_delay_u64(&fdc.timer, 8 * TIMER_USEC); + discint = -1; + fdc_reset(); + } + disc_set_motor_enable(val & 0x01); + fdc.drive = 0; + } else { + if ((val & 4) && !(fdc.dor & 4)) { + timer_set_delay_u64(&fdc.timer, 8 * TIMER_USEC); + discint = -1; + fdc_reset(); + } + disc_set_motor_enable((val & 0xf0) ? 1 : 0); + fdc.drive = val & 3; + } + fdc.dor = val; + // printf("DOR now %02X\n",val); + return; + case 3: + /* TDR */ + if (fdc.enh_mode) { + drive = (fdc.dor & 1) ^ fdd_swap; + fdc.rwc[drive] = (val & 0x30) >> 4; + } + return; + case 4: + if (val & 0x80) { + timer_set_delay_u64(&fdc.timer, 8 * TIMER_USEC); + discint = -1; + fdc_reset(); + } + return; + case 5: /*Command register*/ + if ((fdc.stat & 0xf0) == 0xb0) { + if (fdc.pcjr || !fdc.fifo) { + fdc.dat = val; + fdc.stat &= ~0x80; + } else { + fdc_fifo_buf_write(val); + if (fdc.fifobufpos == 0) + fdc.stat &= ~0x80; + } + break; + } + // if (fdc.inread) + // rpclog("c82c711_fdc_write : writing while inread! %02X\n", val); + // rpclog("Write command reg %i %i\n",fdc.pnum, fdc.ptot); + if (fdc.pnum == fdc.ptot) { + fdc.tc = 0; + fdc.data_ready = 0; - fdc.command = val; -// pclog("Starting FDC command %02X\n",fdc.command); - switch (fdc.command) { - case 1: /*Mode*/ - if (!fdc.is_nsc) - goto bad_command; - fdc.pnum = 0; - fdc.ptot = 4; - fdc.stat = 0x90; - fdc.pos = 0; - fdc.format_state = 0; - break; + fdc.command = val; + // pclog("Starting FDC command %02X\n",fdc.command); + switch (fdc.command) { + case 1: /*Mode*/ + if (!fdc.is_nsc) + goto bad_command; + fdc.pnum = 0; + fdc.ptot = 4; + fdc.stat = 0x90; + fdc.pos = 0; + fdc.format_state = 0; + break; - case 0x02: - case 0x42: /*Read track*/ - fdc.pnum = 0; - fdc.ptot = 8; - fdc.stat = 0x90; - fdc.pos = 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: - case 0x45: - case 0x85: - case 0xc5: /*Write data*/ -// printf("Write data!\n"); - fdc.pnum = 0; - fdc.ptot = 8; - fdc.stat = 0x90; - fdc.pos = 0; -// readflash=1; - break; - case 0x06: - case 0x26: - case 0x46: - case 0x66: /*Read data*/ - case 0x86: - case 0xa6: - case 0xc6: - case 0xe6:fdc.pnum = 0; - fdc.ptot = 8; - fdc.stat = 0x90; - fdc.pos = 0; - break; - case 0x07: /*Recalibrate*/ - fdc.pnum = 0; - fdc.ptot = 1; - fdc.stat = 0x90; - break; - case 0x08: /*Sense interrupt status*/ - if (fdc.int_pending || fdc_reset_stat) { -// printf("Sense interrupt status %i\n",curdrive); - fdc.lastdrive = fdc.drive; -// fdc.stat = 0x10 | (fdc.stat & 0xf); - discint = 8; - fdc.pos = 0; - fdc_callback(); - } else { - fdc.stat = 0x10; - discint = 0xfc; - timer_set_delay_u64(&fdc.timer, 100 * TIMER_USEC); - } - break; - case 0x0a: - case 0x4a: /*Read sector ID*/ - fdc.pnum = 0; - fdc.ptot = 1; - fdc.stat = 0x90; - fdc.pos = 0; - break; - case 0x0d: - case 0x4d: - case 0x8d: - case 0xcd: /*Format track*/ - fdc.pnum = 0; - fdc.ptot = 5; - fdc.stat = 0x90; - fdc.pos = 0; - fdc.format_state = 0; - break; - case 0x0f: /*Seek*/ - fdc.pnum = 0; - fdc.ptot = 2; - fdc.stat = 0x90; - break; - case 0x0e: /*Dump registers*/ - fdc.lastdrive = fdc.drive; - discint = 0x0e; - fdc.pos = 0; - fdc_callback(); - break; - case 0x10: /*Get version*/ - fdc.lastdrive = fdc.drive; - discint = 0x10; - fdc.pos = 0; - fdc_callback(); - break; - case 0x12: /*Set perpendicular mode*/ - fdc.pnum = 0; - fdc.ptot = 1; - fdc.stat = 0x90; - fdc.pos = 0; - break; - case 0x13: /*Configure*/ - fdc.pnum = 0; - fdc.ptot = 3; - fdc.stat = 0x90; - fdc.pos = 0; - break; - case 0x14: /*Unlock*/ - case 0x94: /*Lock*/ - fdc.lastdrive = fdc.drive; - discint = fdc.command; - fdc.pos = 0; - fdc_callback(); - break; + case 0x02: + case 0x42: /*Read track*/ + fdc.pnum = 0; + fdc.ptot = 8; + fdc.stat = 0x90; + fdc.pos = 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: + case 0x45: + case 0x85: + case 0xc5: /*Write data*/ + // printf("Write data!\n"); + fdc.pnum = 0; + fdc.ptot = 8; + fdc.stat = 0x90; + fdc.pos = 0; + // readflash=1; + break; + case 0x06: + case 0x26: + case 0x46: + case 0x66: /*Read data*/ + case 0x86: + case 0xa6: + case 0xc6: + case 0xe6: + fdc.pnum = 0; + fdc.ptot = 8; + fdc.stat = 0x90; + fdc.pos = 0; + break; + case 0x07: /*Recalibrate*/ + fdc.pnum = 0; + fdc.ptot = 1; + fdc.stat = 0x90; + break; + case 0x08: /*Sense interrupt status*/ + if (fdc.int_pending || fdc_reset_stat) { + // printf("Sense interrupt status %i\n",curdrive); + fdc.lastdrive = fdc.drive; + // fdc.stat = 0x10 | (fdc.stat & 0xf); + discint = 8; + fdc.pos = 0; + fdc_callback(); + } else { + fdc.stat = 0x10; + discint = 0xfc; + timer_set_delay_u64(&fdc.timer, 100 * TIMER_USEC); + } + break; + case 0x0a: + case 0x4a: /*Read sector ID*/ + fdc.pnum = 0; + fdc.ptot = 1; + fdc.stat = 0x90; + fdc.pos = 0; + break; + case 0x0d: + case 0x4d: + case 0x8d: + case 0xcd: /*Format track*/ + fdc.pnum = 0; + fdc.ptot = 5; + fdc.stat = 0x90; + fdc.pos = 0; + fdc.format_state = 0; + break; + case 0x0f: /*Seek*/ + fdc.pnum = 0; + fdc.ptot = 2; + fdc.stat = 0x90; + break; + case 0x0e: /*Dump registers*/ + fdc.lastdrive = fdc.drive; + discint = 0x0e; + fdc.pos = 0; + fdc_callback(); + break; + case 0x10: /*Get version*/ + fdc.lastdrive = fdc.drive; + discint = 0x10; + fdc.pos = 0; + fdc_callback(); + break; + case 0x12: /*Set perpendicular mode*/ + fdc.pnum = 0; + fdc.ptot = 1; + fdc.stat = 0x90; + fdc.pos = 0; + break; + case 0x13: /*Configure*/ + fdc.pnum = 0; + fdc.ptot = 3; + fdc.stat = 0x90; + fdc.pos = 0; + break; + case 0x14: /*Unlock*/ + case 0x94: /*Lock*/ + fdc.lastdrive = fdc.drive; + discint = fdc.command; + fdc.pos = 0; + fdc_callback(); + break; - case 0x18: - if (!fdc.is_nsc) - goto bad_command; - fdc.lastdrive = fdc.drive; - discint = 0x10; - fdc.pos = 0; - fdc_callback(); - /* fdc.stat = 0x10; - discint = 0xfc; - fdc_callback(); */ - break; + case 0x18: + if (!fdc.is_nsc) + goto bad_command; + fdc.lastdrive = fdc.drive; + discint = 0x10; + fdc.pos = 0; + fdc_callback(); + /* fdc.stat = 0x10; + discint = 0xfc; + fdc_callback(); */ + break; - default: - bad_command: - // fatal("Bad FDC command %02X\n",val); -// dumpregs(); -// exit(-1); - fdc.stat = 0x10; - discint = 0xfc; - timer_set_delay_u64(&fdc.timer, 100 * TIMER_USEC); - break; - } - } else { - fdc.params[fdc.pnum++] = val; - if (fdc.pnum == fdc.ptot) { - uint64_t time; + default: + bad_command: + // fatal("Bad FDC command %02X\n",val); + // dumpregs(); + // exit(-1); + fdc.stat = 0x10; + discint = 0xfc; + timer_set_delay_u64(&fdc.timer, 100 * TIMER_USEC); + break; + } + } else { + fdc.params[fdc.pnum++] = val; + if (fdc.pnum == fdc.ptot) { + uint64_t time; -// pclog("Got all params %02X\n", fdc.command); - fdc.stat = 0x30; - timer_set_delay_u64(&fdc.timer, 256 * TIMER_USEC); -// fdc.drive = fdc.params[0] & 3; - disc_drivesel = fdc.drive & 1; - fdc_reset_stat = 0; - disc_set_drivesel(fdc.drive & 1); - discint = fdc.command & 0x1f; - switch (fdc.command) { - case 0x02: - case 0x42: /*Read track*/ - fdc_rate(fdc.drive); - fdc.head = fdc.params[2]; - fdc.sector = fdc.params[3]; - fdc.sector_size = fdc.params[4]; - fdc.eot[fdc.drive] = fdc.params[5]; - if (fdc.config & 0x40) - fdd_seek(fdc.drive, fdc.params[1] - fdc.track[fdc.drive]); - fdc.track[fdc.drive] = fdc.params[1]; -// pclog("Read a track track=%i head=%i sector=%i eot=%i\n", fdc.track[fdc.drive], fdc.head, fdc.sector, fdc.eot[fdc.drive]); - disc_readsector(fdc.drive, SECTOR_FIRST, fdc.track[fdc.drive], fdc.head, fdc.rate, fdc.params[4]); - timer_disable(&fdc.timer); - readflash_set(READFLASH_FDC, fdc.drive); - fdc.inread = 1; - break; + // pclog("Got all params %02X\n", fdc.command); + fdc.stat = 0x30; + timer_set_delay_u64(&fdc.timer, 256 * TIMER_USEC); + // fdc.drive = fdc.params[0] & 3; + disc_drivesel = fdc.drive & 1; + fdc_reset_stat = 0; + disc_set_drivesel(fdc.drive & 1); + discint = fdc.command & 0x1f; + switch (fdc.command) { + case 0x02: + case 0x42: /*Read track*/ + fdc_rate(fdc.drive); + fdc.head = fdc.params[2]; + fdc.sector = fdc.params[3]; + fdc.sector_size = fdc.params[4]; + fdc.eot[fdc.drive] = fdc.params[5]; + if (fdc.config & 0x40) + fdd_seek(fdc.drive, fdc.params[1] - fdc.track[fdc.drive]); + fdc.track[fdc.drive] = fdc.params[1]; + // pclog("Read a track track=%i head=%i sector=%i + // eot=%i\n", fdc.track[fdc.drive], fdc.head, + // fdc.sector, fdc.eot[fdc.drive]); + disc_readsector(fdc.drive, SECTOR_FIRST, fdc.track[fdc.drive], fdc.head, fdc.rate, + fdc.params[4]); + timer_disable(&fdc.timer); + readflash_set(READFLASH_FDC, fdc.drive); + fdc.inread = 1; + break; - case 0x03: /*Specify*/ - fdc.stat = 0x80; - fdc.specify[0] = fdc.params[0]; - fdc.specify[1] = fdc.params[1]; - fdc.dma = (fdc.specify[1] & 1) ^ 1; - timer_disable(&fdc.timer); - break; + case 0x03: /*Specify*/ + fdc.stat = 0x80; + fdc.specify[0] = fdc.params[0]; + fdc.specify[1] = fdc.params[1]; + fdc.dma = (fdc.specify[1] & 1) ^ 1; + timer_disable(&fdc.timer); + break; - case 0x05: - case 0x45: - case 0x85: - case 0xc5: /*Write data*/ - fdc_rate(fdc.drive); - fdc.head = fdc.params[2]; - fdc.sector = fdc.params[3]; - fdc.sector_size = fdc.params[4]; - fdc.eot[fdc.drive] = fdc.params[5]; - fdc.rw_track = fdc.params[1]; - if (fdc.config & 0x40) { - fdd_seek(fdc.drive, fdc.rw_track - fdc.track[fdc.drive]); - fdc.track[fdc.drive] = fdc.rw_track; - } + case 0x05: + case 0x45: + case 0x85: + case 0xc5: /*Write data*/ + fdc_rate(fdc.drive); + fdc.head = fdc.params[2]; + fdc.sector = fdc.params[3]; + fdc.sector_size = fdc.params[4]; + fdc.eot[fdc.drive] = fdc.params[5]; + fdc.rw_track = fdc.params[1]; + if (fdc.config & 0x40) { + fdd_seek(fdc.drive, fdc.rw_track - fdc.track[fdc.drive]); + fdc.track[fdc.drive] = fdc.rw_track; + } - disc_writesector(fdc.drive, fdc.sector, fdc.rw_track, fdc.head, fdc.rate, fdc.params[4]); - timer_disable(&fdc.timer); - fdc.written = 0; - readflash_set(READFLASH_FDC, fdc.drive); - fdc.pos = 0; - if (fdc.pcjr) - fdc.stat = 0xb0; -// ioc_fiq(IOC_FIQ_DISC_DATA); - break; + disc_writesector(fdc.drive, fdc.sector, fdc.rw_track, fdc.head, fdc.rate, fdc.params[4]); + timer_disable(&fdc.timer); + fdc.written = 0; + readflash_set(READFLASH_FDC, fdc.drive); + fdc.pos = 0; + if (fdc.pcjr) + fdc.stat = 0xb0; + // ioc_fiq(IOC_FIQ_DISC_DATA); + break; - case 0x06: - case 0x26: - case 0x46: - case 0x66: /*Read data*/ - case 0x86: - case 0xa6: - case 0xc6: - case 0xe6: fdc_rate(fdc.drive); - fdc.head = fdc.params[2]; - fdc.sector = fdc.params[3]; - fdc.sector_size = fdc.params[4]; - fdc.eot[fdc.drive] = fdc.params[5]; - fdc.rw_track = fdc.params[1]; - if (fdc.config & 0x40) { - fdd_seek(fdc.drive, fdc.rw_track - fdc.track[fdc.drive]); - fdc.track[fdc.drive] = fdc.rw_track; - } + case 0x06: + case 0x26: + case 0x46: + case 0x66: /*Read data*/ + case 0x86: + case 0xa6: + case 0xc6: + case 0xe6: + fdc_rate(fdc.drive); + fdc.head = fdc.params[2]; + fdc.sector = fdc.params[3]; + fdc.sector_size = fdc.params[4]; + fdc.eot[fdc.drive] = fdc.params[5]; + fdc.rw_track = fdc.params[1]; + if (fdc.config & 0x40) { + fdd_seek(fdc.drive, fdc.rw_track - fdc.track[fdc.drive]); + fdc.track[fdc.drive] = fdc.rw_track; + } - disc_readsector(fdc.drive, fdc.sector, fdc.rw_track, fdc.head, fdc.rate, fdc.params[4]); - timer_disable(&fdc.timer); - readflash_set(READFLASH_FDC, fdc.drive); - fdc.inread = 1; - break; + disc_readsector(fdc.drive, fdc.sector, fdc.rw_track, fdc.head, fdc.rate, fdc.params[4]); + timer_disable(&fdc.timer); + readflash_set(READFLASH_FDC, fdc.drive); + fdc.inread = 1; + break; - case 0x07: /*Recalibrate*/ - fdc.stat = 1 << fdc.drive; - timer_disable(&fdc.timer); - time = fdd_seek(fdc.drive, SEEK_RECALIBRATE); - if (time) - timer_set_delay_u64(&fdc.timer, time); - break; + case 0x07: /*Recalibrate*/ + fdc.stat = 1 << fdc.drive; + timer_disable(&fdc.timer); + time = fdd_seek(fdc.drive, SEEK_RECALIBRATE); + if (time) + timer_set_delay_u64(&fdc.timer, time); + break; - case 0x0d: - case 0x4d: - case 0x8d: - case 0xcd: /*Format*/ - fdc_rate(fdc.drive); - fdc.head = (fdc.params[0] & 4) ? 1 : 0; - fdc.format_state = 1; - fdc.pos = 0; - fdc.stat = 0x30; - break; + case 0x0d: + case 0x4d: + case 0x8d: + case 0xcd: /*Format*/ + fdc_rate(fdc.drive); + fdc.head = (fdc.params[0] & 4) ? 1 : 0; + fdc.format_state = 1; + fdc.pos = 0; + fdc.stat = 0x30; + break; - case 0x0f: /*Seek*/ - fdc.stat = 1 << fdc.drive; - fdc.head = 0; - timer_disable(&fdc.timer); - time = fdd_seek(fdc.drive, fdc.params[1] - fdc.track[fdc.drive]); - if (time) - timer_set_delay_u64(&fdc.timer, time); -// pclog("Seek to %i\n", fdc.params[1]); - break; + case 0x0f: /*Seek*/ + fdc.stat = 1 << fdc.drive; + fdc.head = 0; + timer_disable(&fdc.timer); + time = fdd_seek(fdc.drive, fdc.params[1] - fdc.track[fdc.drive]); + if (time) + timer_set_delay_u64(&fdc.timer, time); + // pclog("Seek to %i\n", fdc.params[1]); + break; - case 0x0a: - case 0x4a: /*Read sector ID*/ - fdc_rate(fdc.drive); - timer_disable(&fdc.timer); - fdc.head = (fdc.params[0] & 4) ? 1 : 0; -// pclog("Read sector ID %i %i\n", fdc.rate, fdc.drive); - disc_readaddress(fdc.drive, fdc.track[fdc.drive], fdc.head, fdc.rate); - break; + case 0x0a: + case 0x4a: /*Read sector ID*/ + fdc_rate(fdc.drive); + timer_disable(&fdc.timer); + fdc.head = (fdc.params[0] & 4) ? 1 : 0; + // pclog("Read sector ID %i %i\n", fdc.rate, + // fdc.drive); + disc_readaddress(fdc.drive, fdc.track[fdc.drive], fdc.head, fdc.rate); + break; - case 0x94: /*Unlock*/ - discint = 0x94; - break; - } - } - } - return; - case 7: - if (!AT && romset != ROM_XI8088 && romset != ROM_PC5086) - return; - fdc.rate = val & 3; + case 0x94: /*Unlock*/ + discint = 0x94; + break; + } + } + } + return; + case 7: + if (!AT && romset != ROM_XI8088 && romset != ROM_PC5086) + return; + fdc.rate = val & 3; - disc_3f7 = val; - return; - } -// printf("Write FDC %04X %02X\n",addr,val); -// dumpregs(); -// exit(-1); + disc_3f7 = val; + return; + } + // printf("Write FDC %04X %02X\n",addr,val); + // dumpregs(); + // exit(-1); } int paramstogo = 0; uint8_t fdc_read(uint16_t addr, void *priv) { - uint8_t temp; - int drive; + uint8_t temp; + int drive; - cycles -= ISA_CYCLES(8); + cycles -= ISA_CYCLES(8); -// /*if (addr!=0x3f4) */printf("Read FDC %04X %04X:%04X %04X %i %02X %02x %i ",addr,cs>>4,pc,BX,fdc.pos,fdc.st0,fdc.stat,ins); - switch (addr & 7) { - case 1: /*???*/ - drive = (fdc.dor & 1) ^ fdd_swap; - if (!fdc.enable_3f1) - return 0xff; -// temp=0x50; - temp = 0x70; - if (drive) - temp &= ~0x40; - else - temp &= ~0x20; + // /*if (addr!=0x3f4) */printf("Read FDC %04X %04X:%04X %04X %i %02X %02x %i + // ",addr,cs>>4,pc,BX,fdc.pos,fdc.st0,fdc.stat,ins); + switch (addr & 7) { + case 1: /*???*/ + drive = (fdc.dor & 1) ^ fdd_swap; + if (!fdc.enable_3f1) + return 0xff; + // temp=0x50; + temp = 0x70; + if (drive) + temp &= ~0x40; + else + temp &= ~0x20; - if (fdc.dor & 0x10) - temp |= 1; - if (fdc.dor & 0x20) - temp |= 2; - break; - case 3:drive = (fdc.dor & 1) ^ fdd_swap; - if (fdc.ps1) { - /*PS/1 Model 2121 seems return drive type in port 0x3f3, - despite the 82077AA FDC not implementing this. This is - presumably implemented outside the FDC on one of the - motherboard's support chips.*/ - if (fdd_is_525(drive)) - temp = 0x20; - else if (fdd_is_ed(drive)) - temp = 0x10; - else - temp = 0x00; - } else if (!fdc.enh_mode) - temp = 0x20; - else { - temp = fdc.rwc[drive] << 4; - } - break; - case 4: /*Status*/ - temp = fdc.stat; - break; - case 5: /*Data*/ - fdc.stat &= ~0x80; - if ((fdc.stat & 0xf0) == 0xf0) { - if (fdc.pcjr || !fdc.fifo) - temp = fdc.dat; - else { - temp = fdc_fifo_buf_read(); - } - break; - } - if (paramstogo) { - paramstogo--; - temp = fdc.res[10 - paramstogo]; -// pclog("Read param %i %02X\n",10-paramstogo,temp); - if (!paramstogo) { - fdc.stat = 0x80; -// fdc.st0=0; - } else { - fdc.stat |= 0xC0; -// fdc_poll(); - } - } else { - if (lastbyte) - fdc.stat = 0x80; - lastbyte = 0; - temp = fdc.dat; - fdc.data_ready = 0; - } - fdc.stat &= 0xf0; - break; - case 7: /*Disk change*/ - drive = (fdc.dor & 1) ^ fdd_swap; - if (fdc.dor & (0x10 << drive)) - temp = (disc_changed[drive] || drive_empty[drive]) ? 0x80 : 0; - else - temp = 0; - if (fdc.dskchg_activelow) /*PC2086/3086 seem to reverse this bit*/ - temp ^= 0x80; -// printf("- DC %i %02X %02X %i %i - ",fdc.dor & 1, fdc.dor, 0x10 << (fdc.dor & 1), discchanged[fdc.dor & 1], driveempty[fdc.dor & 1]); - temp |= 1; -// discchanged[fdc.dor&1]=0; - break; - default:temp = 0xFF; -// printf("Bad read FDC %04X\n",addr); -// dumpregs(); -// exit(-1); - } -// /*if (addr!=0x3f4) */printf("%02X rate=%i %i\n",temp,fdc.rate, fdc.data_ready); - return temp; + if (fdc.dor & 0x10) + temp |= 1; + if (fdc.dor & 0x20) + temp |= 2; + break; + case 3: + drive = (fdc.dor & 1) ^ fdd_swap; + if (fdc.ps1) { + /*PS/1 Model 2121 seems return drive type in port 0x3f3, + despite the 82077AA FDC not implementing this. This is + presumably implemented outside the FDC on one of the + motherboard's support chips.*/ + if (fdd_is_525(drive)) + temp = 0x20; + else if (fdd_is_ed(drive)) + temp = 0x10; + else + temp = 0x00; + } else if (!fdc.enh_mode) + temp = 0x20; + else { + temp = fdc.rwc[drive] << 4; + } + break; + case 4: /*Status*/ + temp = fdc.stat; + break; + case 5: /*Data*/ + fdc.stat &= ~0x80; + if ((fdc.stat & 0xf0) == 0xf0) { + if (fdc.pcjr || !fdc.fifo) + temp = fdc.dat; + else { + temp = fdc_fifo_buf_read(); + } + break; + } + if (paramstogo) { + paramstogo--; + temp = fdc.res[10 - paramstogo]; + // pclog("Read param %i %02X\n",10-paramstogo,temp); + if (!paramstogo) { + fdc.stat = 0x80; + // fdc.st0=0; + } else { + fdc.stat |= 0xC0; + // fdc_poll(); + } + } else { + if (lastbyte) + fdc.stat = 0x80; + lastbyte = 0; + temp = fdc.dat; + fdc.data_ready = 0; + } + fdc.stat &= 0xf0; + break; + case 7: /*Disk change*/ + drive = (fdc.dor & 1) ^ fdd_swap; + if (fdc.dor & (0x10 << drive)) + temp = (disc_changed[drive] || drive_empty[drive]) ? 0x80 : 0; + else + temp = 0; + if (fdc.dskchg_activelow) /*PC2086/3086 seem to reverse this bit*/ + temp ^= 0x80; + // printf("- DC %i %02X %02X %i %i - ",fdc.dor & 1, fdc.dor, 0x10 << (fdc.dor & 1), + // discchanged[fdc.dor & 1], driveempty[fdc.dor & 1]); + temp |= 1; + // discchanged[fdc.dor&1]=0; + break; + default: + temp = 0xFF; + // printf("Bad read FDC %04X\n",addr); + // dumpregs(); + // exit(-1); + } + // /*if (addr!=0x3f4) */printf("%02X rate=%i %i\n",temp,fdc.rate, fdc.data_ready); + return temp; } void fdc_callback() { - int temp; - int drive; + int temp; + int drive; -// pclog("fdc_callback %i\n", discint); -// if (fdc.inread) -// rpclog("c82c711_fdc_callback : while inread! %08X %i %02X %i\n", discint, fdc.drive, fdc.st0, ins); - switch (discint) { - case -3: /*End of command with interrupt*/ -// if (output) printf("EOC - interrupt!\n"); -//rpclog("EOC\n"); - fdc_int(); - case -2: /*End of command*/ - fdc.stat = (fdc.stat & 0xf) | 0x80; - return; - case -1: /*Reset*/ -//rpclog("Reset\n"); - fdc_int(); - fdc_reset_stat = 4; - return; - case 1: /*Mode*/ - fdc.stat = 0x80; - fdc.densel_force = (fdc.params[2] & 0xC0) >> 6; - return; + // pclog("fdc_callback %i\n", discint); + // if (fdc.inread) + // rpclog("c82c711_fdc_callback : while inread! %08X %i %02X %i\n", discint, fdc.drive, fdc.st0, ins); + switch (discint) { + case -3: /*End of command with interrupt*/ + // if (output) printf("EOC - interrupt!\n"); + // rpclog("EOC\n"); + fdc_int(); + case -2: /*End of command*/ + fdc.stat = (fdc.stat & 0xf) | 0x80; + return; + case -1: /*Reset*/ + // rpclog("Reset\n"); + fdc_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*/ - readflash_set(READFLASH_FDC, fdc.drive); - fdc.eot[fdc.drive]--; -// pclog("Read a track callback, eot=%i\n", fdc.eot[fdc.drive]); - if (!fdc.eot[fdc.drive] || fdc.tc) { -// pclog("Complete\n"); - fdc.inread = 0; - discint = -2; - fdc_int(); - fdc.stat = 0xD0; - fdc.res[4] = (fdc.head ? 4 : 0) | fdc.drive; - fdc.res[5] = fdc.res[6] = 0; - fdc.res[7] = fdc.track[fdc.drive]; - fdc.res[8] = fdc.head; - fdc.res[9] = fdc.sector; - fdc.res[10] = fdc.params[4]; - paramstogo = 7; - return; - } else - disc_readsector(fdc.drive, SECTOR_NEXT, fdc.track[fdc.drive], fdc.head, fdc.rate, fdc.params[4]); - fdc.inread = 1; - return; - case 4: /*Sense drive status*/ - drive = fdc.params[0] & 1; - if (fdd_get_type(drive)) { - fdc.res[10] = (fdc.params[0] & 7) | 0x28; - if (fdd_track0(drive)) - fdc.res[10] |= 0x10; - if (writeprot[drive]) - fdc.res[10] |= 0x40; - } else { - fdc.res[10] = 0x80 | (fdc.params[0] & 3); - } + case 2: /*Read track*/ + readflash_set(READFLASH_FDC, fdc.drive); + fdc.eot[fdc.drive]--; + // pclog("Read a track callback, eot=%i\n", fdc.eot[fdc.drive]); + if (!fdc.eot[fdc.drive] || fdc.tc) { + // pclog("Complete\n"); + fdc.inread = 0; + discint = -2; + fdc_int(); + fdc.stat = 0xD0; + fdc.res[4] = (fdc.head ? 4 : 0) | fdc.drive; + fdc.res[5] = fdc.res[6] = 0; + fdc.res[7] = fdc.track[fdc.drive]; + fdc.res[8] = fdc.head; + fdc.res[9] = fdc.sector; + fdc.res[10] = fdc.params[4]; + paramstogo = 7; + return; + } else + disc_readsector(fdc.drive, SECTOR_NEXT, fdc.track[fdc.drive], fdc.head, fdc.rate, fdc.params[4]); + fdc.inread = 1; + return; + case 4: /*Sense drive status*/ + drive = fdc.params[0] & 1; + if (fdd_get_type(drive)) { + fdc.res[10] = (fdc.params[0] & 7) | 0x28; + if (fdd_track0(drive)) + fdc.res[10] |= 0x10; + if (writeprot[drive]) + fdc.res[10] |= 0x40; + } else { + fdc.res[10] = 0x80 | (fdc.params[0] & 3); + } - fdc.stat = (fdc.stat & 0xf) | 0xd0; - paramstogo = 1; - discint = 0; - return; - case 5: /*Write data*/ - readflash_set(READFLASH_FDC, fdc.drive); - if (fdc.sector == fdc.params[5]) { - fdc.sector = 1; - if (fdc.command & 0x80) { - fdc.head ^= 1; - if (!fdc.head) { - fdc.rw_track++; - fdc.tc = 1; - } - } else { - fdc.rw_track++; - fdc.tc = 1; - } - } else - fdc.sector++; - if (fdc.tc) { - discint = -2; - fdc_int(); - fdc.stat = 0xD0; - fdc.res[4] = (fdc.head ? 4 : 0) | fdc.drive; - fdc.res[5] = fdc.res[6] = 0; - fdc.res[7] = fdc.rw_track; - fdc.res[8] = fdc.head; - fdc.res[9] = fdc.sector; - fdc.res[10] = fdc.params[4]; - paramstogo = 7; - return; - } - disc_writesector(fdc.drive, fdc.sector, fdc.rw_track, fdc.head, fdc.rate, fdc.params[4]); -// ioc_fiq(IOC_FIQ_DISC_DATA); - return; - case 6: /*Read data*/ -// rpclog("Read data %i\n", fdc.tc); - readflash_set(READFLASH_FDC, fdc.drive); - if (fdc.sector == fdc.params[5]) { - fdc.sector = 1; - if (fdc.command & 0x80) { - fdc.head ^= 1; - if (!fdc.head) { - fdc.rw_track++; - fdc.tc = 1; - } - } else { - fdc.rw_track++; - fdc.tc = 1; - } - } else - fdc.sector++; - if (fdc.tc) { - fdc.inread = 0; - discint = -2; - fdc_int(); - fdc.stat = 0xD0; - fdc.res[4] = (fdc.head ? 4 : 0) | fdc.drive; - fdc.res[5] = fdc.res[6] = 0; - fdc.res[7] = fdc.rw_track; - fdc.res[8] = fdc.head; - fdc.res[9] = fdc.sector; - fdc.res[10] = fdc.params[4]; - paramstogo = 7; - return; - } - disc_readsector(fdc.drive, fdc.sector, fdc.rw_track, fdc.head, fdc.rate, fdc.params[4]); - fdc.inread = 1; - return; + fdc.stat = (fdc.stat & 0xf) | 0xd0; + paramstogo = 1; + discint = 0; + return; + case 5: /*Write data*/ + readflash_set(READFLASH_FDC, fdc.drive); + if (fdc.sector == fdc.params[5]) { + fdc.sector = 1; + if (fdc.command & 0x80) { + fdc.head ^= 1; + if (!fdc.head) { + fdc.rw_track++; + fdc.tc = 1; + } + } else { + fdc.rw_track++; + fdc.tc = 1; + } + } else + fdc.sector++; + if (fdc.tc) { + discint = -2; + fdc_int(); + fdc.stat = 0xD0; + fdc.res[4] = (fdc.head ? 4 : 0) | fdc.drive; + fdc.res[5] = fdc.res[6] = 0; + fdc.res[7] = fdc.rw_track; + fdc.res[8] = fdc.head; + fdc.res[9] = fdc.sector; + fdc.res[10] = fdc.params[4]; + paramstogo = 7; + return; + } + disc_writesector(fdc.drive, fdc.sector, fdc.rw_track, fdc.head, fdc.rate, fdc.params[4]); + // ioc_fiq(IOC_FIQ_DISC_DATA); + return; + case 6: /*Read data*/ + // rpclog("Read data %i\n", fdc.tc); + readflash_set(READFLASH_FDC, fdc.drive); + if (fdc.sector == fdc.params[5]) { + fdc.sector = 1; + if (fdc.command & 0x80) { + fdc.head ^= 1; + if (!fdc.head) { + fdc.rw_track++; + fdc.tc = 1; + } + } else { + fdc.rw_track++; + fdc.tc = 1; + } + } else + fdc.sector++; + if (fdc.tc) { + fdc.inread = 0; + discint = -2; + fdc_int(); + fdc.stat = 0xD0; + fdc.res[4] = (fdc.head ? 4 : 0) | fdc.drive; + fdc.res[5] = fdc.res[6] = 0; + fdc.res[7] = fdc.rw_track; + fdc.res[8] = fdc.head; + fdc.res[9] = fdc.sector; + fdc.res[10] = fdc.params[4]; + paramstogo = 7; + return; + } + disc_readsector(fdc.drive, fdc.sector, fdc.rw_track, fdc.head, fdc.rate, fdc.params[4]); + fdc.inread = 1; + return; - case 7: /*Recalibrate*/ - drive = fdc.params[0] & 1; - fdc.track[fdc.drive] = 0; -// if (!driveempty[fdc.dor & 1]) discchanged[fdc.dor & 1] = 0; - if (fdc.drive <= 1 && fdd_get_type(drive)) - fdc.st0 = 0x20 | (fdc.params[0] & 3) | (fdc.head ? 4 : 0); - else - fdc.st0 = 0x68 | (fdc.params[0] & 3) | (fdc.head ? 4 : 0); - fdc.int_pending = 1; - discint = -3; - timer_set_delay_u64(&fdc.timer, 2048 * TIMER_USEC); -// printf("Recalibrate complete!\n"); - fdc.stat = 0x80 | (1 << fdc.drive); - return; + case 7: /*Recalibrate*/ + drive = fdc.params[0] & 1; + fdc.track[fdc.drive] = 0; + // if (!driveempty[fdc.dor & 1]) discchanged[fdc.dor & 1] = 0; + if (fdc.drive <= 1 && fdd_get_type(drive)) + fdc.st0 = 0x20 | (fdc.params[0] & 3) | (fdc.head ? 4 : 0); + else + fdc.st0 = 0x68 | (fdc.params[0] & 3) | (fdc.head ? 4 : 0); + fdc.int_pending = 1; + discint = -3; + timer_set_delay_u64(&fdc.timer, 2048 * TIMER_USEC); + // printf("Recalibrate complete!\n"); + fdc.stat = 0x80 | (1 << fdc.drive); + return; - case 8: /*Sense interrupt status*/ -// pclog("Sense interrupt status %i\n", fdc_reset_stat); + case 8: /*Sense interrupt status*/ + // pclog("Sense interrupt status %i\n", fdc_reset_stat); - fdc.stat = (fdc.stat & 0xf) | 0xd0; - if (fdc_reset_stat) - fdc.res[9] = 0xc0 | (4 - fdc_reset_stat) | (fdc.head ? 4 : 0); - else - fdc.res[9] = fdc.st0; - fdc.res[10] = fdc.track[fdc.drive]; - if (fdc_reset_stat) - fdc_reset_stat--; - if (!fdc_reset_stat) - fdc.int_pending = 0; + fdc.stat = (fdc.stat & 0xf) | 0xd0; + if (fdc_reset_stat) + fdc.res[9] = 0xc0 | (4 - fdc_reset_stat) | (fdc.head ? 4 : 0); + else + fdc.res[9] = fdc.st0; + fdc.res[10] = fdc.track[fdc.drive]; + if (fdc_reset_stat) + fdc_reset_stat--; + if (!fdc_reset_stat) + fdc.int_pending = 0; - paramstogo = 2; - discint = 0; - return; + paramstogo = 2; + discint = 0; + return; - case 0x0d: /*Format track*/ -// rpclog("Format\n"); - if (fdc.format_state == 1) { -// ioc_fiq(IOC_FIQ_DISC_DATA); - fdc.format_state = 2; - timer_set_delay_u64(&fdc.timer, 8 * TIMER_USEC); - } else if (fdc.format_state == 2) { - temp = fdc_getdata(fdc.pos == ((fdc.params[2] * 4) - 1)); - if (temp == -1) { - timer_set_delay_u64(&fdc.timer, 8 * TIMER_USEC); - return; - } - fdc.format_dat[fdc.pos++] = temp; - if (fdc.pos == (fdc.params[2] * 4)) - fdc.format_state = 3; - timer_set_delay_u64(&fdc.timer, 8 * TIMER_USEC); - } else if (fdc.format_state == 3) { -// pclog("Format next stage track %i head %i\n", fdc.track[fdc.drive], fdc.head); - disc_format(fdc.drive, fdc.track[fdc.drive], fdc.head, fdc.rate, fdc.params[4]); - fdc.format_state = 4; - } else { - discint = -2; - fdc_int(); - fdc.stat = 0xD0; - fdc.res[4] = (fdc.head ? 4 : 0) | fdc.drive; - fdc.res[5] = fdc.res[6] = 0; - fdc.res[7] = fdc.track[fdc.drive]; - fdc.res[8] = fdc.head; - fdc.res[9] = fdc.format_dat[fdc.pos - 2] + 1; - fdc.res[10] = fdc.params[4]; - paramstogo = 7; - fdc.format_state = 0; - return; - } - return; + case 0x0d: /*Format track*/ + // rpclog("Format\n"); + if (fdc.format_state == 1) { + // ioc_fiq(IOC_FIQ_DISC_DATA); + fdc.format_state = 2; + timer_set_delay_u64(&fdc.timer, 8 * TIMER_USEC); + } else if (fdc.format_state == 2) { + temp = fdc_getdata(fdc.pos == ((fdc.params[2] * 4) - 1)); + if (temp == -1) { + timer_set_delay_u64(&fdc.timer, 8 * TIMER_USEC); + return; + } + fdc.format_dat[fdc.pos++] = temp; + if (fdc.pos == (fdc.params[2] * 4)) + fdc.format_state = 3; + timer_set_delay_u64(&fdc.timer, 8 * TIMER_USEC); + } else if (fdc.format_state == 3) { + // pclog("Format next stage track %i head %i\n", fdc.track[fdc.drive], fdc.head); + disc_format(fdc.drive, fdc.track[fdc.drive], fdc.head, fdc.rate, fdc.params[4]); + fdc.format_state = 4; + } else { + discint = -2; + fdc_int(); + fdc.stat = 0xD0; + fdc.res[4] = (fdc.head ? 4 : 0) | fdc.drive; + fdc.res[5] = fdc.res[6] = 0; + fdc.res[7] = fdc.track[fdc.drive]; + fdc.res[8] = fdc.head; + fdc.res[9] = fdc.format_dat[fdc.pos - 2] + 1; + fdc.res[10] = fdc.params[4]; + paramstogo = 7; + fdc.format_state = 0; + return; + } + return; - case 15: /*Seek*/ - drive = fdc.params[0] & 1; - fdc.track[fdc.drive] = fdc.params[1]; -// if (!driveempty[fdc.dor & 1]) discchanged[fdc.dor & 1] = 0; -// printf("Seeked to track %i %i\n",fdc.track[fdc.drive], fdc.drive); - if (fdc.drive <= 1 && fdd_get_type(drive)) - fdc.st0 = 0x20 | (fdc.params[0] & 3) | (fdc.head ? 4 : 0); - else - fdc.st0 = 0x68 | (fdc.params[0] & 3) | (fdc.head ? 4 : 0); - fdc.int_pending = 1; - discint = -3; - timer_set_delay_u64(&fdc.timer, 1024 * TIMER_USEC); - fdc.stat = 0x80 | (1 << fdc.drive); -// pclog("Stat %02X ST0 %02X\n", fdc.stat, fdc.st0); - return; - case 0x0e: /*Dump registers*/ - fdc.stat = (fdc.stat & 0xf) | 0xd0; - fdc.res[1] = fdc.track[0]; - fdc.res[2] = fdc.track[1]; - fdc.res[3] = 0; - fdc.res[4] = 0; - 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; - paramstogo = 10; - discint = 0; - return; + case 15: /*Seek*/ + drive = fdc.params[0] & 1; + fdc.track[fdc.drive] = fdc.params[1]; + // if (!driveempty[fdc.dor & 1]) discchanged[fdc.dor & 1] = 0; + // printf("Seeked to track %i %i\n",fdc.track[fdc.drive], fdc.drive); + if (fdc.drive <= 1 && fdd_get_type(drive)) + fdc.st0 = 0x20 | (fdc.params[0] & 3) | (fdc.head ? 4 : 0); + else + fdc.st0 = 0x68 | (fdc.params[0] & 3) | (fdc.head ? 4 : 0); + fdc.int_pending = 1; + discint = -3; + timer_set_delay_u64(&fdc.timer, 1024 * TIMER_USEC); + fdc.stat = 0x80 | (1 << fdc.drive); + // pclog("Stat %02X ST0 %02X\n", fdc.stat, fdc.st0); + return; + case 0x0e: /*Dump registers*/ + fdc.stat = (fdc.stat & 0xf) | 0xd0; + fdc.res[1] = fdc.track[0]; + fdc.res[2] = fdc.track[1]; + fdc.res[3] = 0; + fdc.res[4] = 0; + 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; + paramstogo = 10; + discint = 0; + return; - case 0x10: /*Version*/ - fdc.stat = (fdc.stat & 0xf) | 0xd0; - fdc.res[10] = 0x90; - paramstogo = 1; - discint = 0; - return; + case 0x10: /*Version*/ + fdc.stat = (fdc.stat & 0xf) | 0xd0; + fdc.res[10] = 0x90; + paramstogo = 1; + discint = 0; + return; - case 0x12:fdc.perp = fdc.params[0]; - fdc.stat = 0x80; -// picint(0x40); - 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) + 1; - pclog("FIFO is now %02X, threshold is %02X\n", fdc.fifo, fdc.tfifo); - fdc.stat = 0x80; -// picint(0x40); - return; - case 0x14: /*Unlock*/ - fdc.lock = 0; - fdc.stat = (fdc.stat & 0xf) | 0xd0; - fdc.res[10] = 0; - paramstogo = 1; - discint = 0; - return; - case 0x94: /*Lock*/ - fdc.lock = 1; - fdc.stat = (fdc.stat & 0xf) | 0xd0; - fdc.res[10] = 0x10; - paramstogo = 1; - discint = 0; - return; + case 0x12: + fdc.perp = fdc.params[0]; + fdc.stat = 0x80; + // picint(0x40); + 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) + 1; + pclog("FIFO is now %02X, threshold is %02X\n", fdc.fifo, fdc.tfifo); + fdc.stat = 0x80; + // picint(0x40); + return; + case 0x14: /*Unlock*/ + fdc.lock = 0; + fdc.stat = (fdc.stat & 0xf) | 0xd0; + fdc.res[10] = 0; + paramstogo = 1; + discint = 0; + return; + case 0x94: /*Lock*/ + fdc.lock = 1; + fdc.stat = (fdc.stat & 0xf) | 0xd0; + fdc.res[10] = 0x10; + paramstogo = 1; + discint = 0; + return; - case 0x18: /*NSC*/ - fdc.stat = (fdc.stat & 0xf) | 0xd0; - fdc.res[10] = 0x73; - paramstogo = 1; - discint = 0; - return; + case 0x18: /*NSC*/ + fdc.stat = (fdc.stat & 0xf) | 0xd0; + fdc.res[10] = 0x73; + paramstogo = 1; + discint = 0; + return; - case 0xfc: /*Invalid*/ - fdc.dat = fdc.st0 = 0x80; -// pclog("Inv!\n"); - //picint(0x40); - fdc.stat = (fdc.stat & 0xf) | 0xd0; -// fdc.stat|=0xC0; - fdc.res[10] = fdc.st0; - paramstogo = 1; - discint = 0; - return; - } -// printf("Bad FDC disc int %i\n",discint); -// dumpregs(); -// exit(-1); + case 0xfc: /*Invalid*/ + fdc.dat = fdc.st0 = 0x80; + // pclog("Inv!\n"); + // picint(0x40); + fdc.stat = (fdc.stat & 0xf) | 0xd0; + // fdc.stat|=0xC0; + fdc.res[10] = fdc.st0; + paramstogo = 1; + discint = 0; + return; + } + // printf("Bad FDC disc int %i\n",discint); + // dumpregs(); + // exit(-1); } void fdc_overrun() { - disc_sector_stop(); - timer_disable(&fdc.timer); + disc_sector_stop(); + timer_disable(&fdc.timer); - fdc_int(); - fdc.stat = 0xD0; - fdc.res[4] = 0x40 | (fdc.head ? 4 : 0) | fdc.drive; - fdc.res[5] = 0x10; /*Overrun*/ - fdc.res[6] = 0; - fdc.res[7] = 0; - fdc.res[8] = 0; - fdc.res[9] = 0; - fdc.res[10] = 0; - paramstogo = 7; + fdc_int(); + fdc.stat = 0xD0; + fdc.res[4] = 0x40 | (fdc.head ? 4 : 0) | fdc.drive; + fdc.res[5] = 0x10; /*Overrun*/ + fdc.res[6] = 0; + fdc.res[7] = 0; + fdc.res[8] = 0; + fdc.res[9] = 0; + fdc.res[10] = 0; + paramstogo = 7; } int fdc_data(uint8_t data) { - if (fdc.tc) - return 0; + if (fdc.tc) + return 0; - if (fdc.pcjr || !fdc.dma) { - if (fdc.data_ready) { - fdc_overrun(); -// pclog("Overrun\n"); - return -1; - } + if (fdc.pcjr || !fdc.dma) { + if (fdc.data_ready) { + fdc_overrun(); + // pclog("Overrun\n"); + return -1; + } - if (fdc.pcjr || !fdc.fifo) { - fdc.dat = data; - fdc.data_ready = 1; - fdc.stat = 0xf0; - } else { - // FIFO enabled - fdc_fifo_buf_write(data); - if (fdc.fifobufpos == 0) { - // We have wrapped around, means FIFO is over - fdc.data_ready = 1; - fdc.stat = 0xf0; - } - } - } else { - if (dma_channel_write(2, data) & DMA_OVER) - fdc.tc = 1; + if (fdc.pcjr || !fdc.fifo) { + fdc.dat = data; + fdc.data_ready = 1; + fdc.stat = 0xf0; + } else { + // FIFO enabled + fdc_fifo_buf_write(data); + if (fdc.fifobufpos == 0) { + // We have wrapped around, means FIFO is over + fdc.data_ready = 1; + fdc.stat = 0xf0; + } + } + } else { + if (dma_channel_write(2, data) & DMA_OVER) + fdc.tc = 1; - if (!fdc.fifo) { - fdc.data_ready = 1; - fdc.stat = 0xd0; - } else { - fdc_fifo_buf_dummy(); - if (fdc.fifobufpos == 0) { - // We have wrapped around, means FIFO is over - fdc.data_ready = 1; - fdc.stat = 0xd0; - } - } - } + if (!fdc.fifo) { + fdc.data_ready = 1; + fdc.stat = 0xd0; + } else { + fdc_fifo_buf_dummy(); + if (fdc.fifobufpos == 0) { + // We have wrapped around, means FIFO is over + fdc.data_ready = 1; + fdc.stat = 0xd0; + } + } + } - return 0; + return 0; } void fdc_finishread() { - fdc.inread = 0; - timer_set_delay_u64(&fdc.timer, 200 * TIMER_USEC); -// rpclog("fdc_finishread\n"); + fdc.inread = 0; + timer_set_delay_u64(&fdc.timer, 200 * TIMER_USEC); + // rpclog("fdc_finishread\n"); } void fdc_notfound(int reason) { -// pclog("fdc_notfound: reason=%i\n", reason); - timer_disable(&fdc.timer); + // pclog("fdc_notfound: reason=%i\n", reason); + timer_disable(&fdc.timer); - fdc_int(); - fdc.stat = 0xD0; - fdc.res[4] = 0x40 | (fdc.head ? 4 : 0) | fdc.drive; - switch (reason) { - case FDC_STATUS_AM_NOT_FOUND:fdc.res[5] = ST1_ND | ST1_MA; - fdc.res[6] = 0; - break; - case FDC_STATUS_NOT_FOUND:fdc.res[5] = ST1_ND; - fdc.res[6] = 0; - break; - case FDC_STATUS_WRONG_CYLINDER:fdc.res[5] = ST1_ND; - fdc.res[6] = ST2_WC; - break; - case FDC_STATUS_BAD_CYLINDER:fdc.res[5] = ST1_ND; - fdc.res[6] = ST2_WC | ST2_BC; - break; - } - fdc.res[7] = fdc.rw_track; - fdc.res[8] = fdc.head; - fdc.res[9] = fdc.sector; - fdc.res[10] = fdc.sector_size; - paramstogo = 7; -// rpclog("c82c711_fdc_notfound\n"); + fdc_int(); + fdc.stat = 0xD0; + fdc.res[4] = 0x40 | (fdc.head ? 4 : 0) | fdc.drive; + switch (reason) { + case FDC_STATUS_AM_NOT_FOUND: + fdc.res[5] = ST1_ND | ST1_MA; + fdc.res[6] = 0; + break; + case FDC_STATUS_NOT_FOUND: + fdc.res[5] = ST1_ND; + fdc.res[6] = 0; + break; + case FDC_STATUS_WRONG_CYLINDER: + fdc.res[5] = ST1_ND; + fdc.res[6] = ST2_WC; + break; + case FDC_STATUS_BAD_CYLINDER: + fdc.res[5] = ST1_ND; + fdc.res[6] = ST2_WC | ST2_BC; + break; + } + fdc.res[7] = fdc.rw_track; + fdc.res[8] = fdc.head; + fdc.res[9] = fdc.sector; + fdc.res[10] = fdc.sector_size; + paramstogo = 7; + // rpclog("c82c711_fdc_notfound\n"); } void fdc_datacrcerror() { - timer_disable(&fdc.timer); + timer_disable(&fdc.timer); - fdc_int(); - fdc.stat = 0xD0; - fdc.res[4] = 0x40 | (fdc.head ? 4 : 0) | fdc.drive; - fdc.res[5] = 0x20; /*Data error*/ - fdc.res[6] = 0x20; /*Data error in data field*/ - fdc.res[7] = fdc.rw_track; - fdc.res[8] = fdc.head; - fdc.res[9] = fdc.sector; - fdc.res[10] = fdc.sector_size; - paramstogo = 7; -// rpclog("c82c711_fdc_datacrcerror\n"); + fdc_int(); + fdc.stat = 0xD0; + fdc.res[4] = 0x40 | (fdc.head ? 4 : 0) | fdc.drive; + fdc.res[5] = 0x20; /*Data error*/ + fdc.res[6] = 0x20; /*Data error in data field*/ + fdc.res[7] = fdc.rw_track; + fdc.res[8] = fdc.head; + fdc.res[9] = fdc.sector; + fdc.res[10] = fdc.sector_size; + paramstogo = 7; + // rpclog("c82c711_fdc_datacrcerror\n"); } void fdc_headercrcerror() { - timer_disable(&fdc.timer); + timer_disable(&fdc.timer); - fdc_int(); - fdc.stat = 0xD0; - fdc.res[4] = 0x40 | (fdc.head ? 4 : 0) | fdc.drive; - fdc.res[5] = 0x20; /*Data error*/ - fdc.res[6] = 0; - fdc.res[7] = fdc.rw_track; - fdc.res[8] = fdc.head; - fdc.res[9] = fdc.sector; - fdc.res[10] = fdc.sector_size; - paramstogo = 7; -// rpclog("c82c711_fdc_headercrcerror\n"); + fdc_int(); + fdc.stat = 0xD0; + fdc.res[4] = 0x40 | (fdc.head ? 4 : 0) | fdc.drive; + fdc.res[5] = 0x20; /*Data error*/ + fdc.res[6] = 0; + fdc.res[7] = fdc.rw_track; + fdc.res[8] = fdc.head; + fdc.res[9] = fdc.sector; + fdc.res[10] = fdc.sector_size; + paramstogo = 7; + // rpclog("c82c711_fdc_headercrcerror\n"); } void fdc_writeprotect() { - timer_disable(&fdc.timer); + timer_disable(&fdc.timer); - fdc_int(); - fdc.stat = 0xD0; - fdc.res[4] = 0x40 | (fdc.head ? 4 : 0) | fdc.drive; - fdc.res[5] = 0x02; /*Not writeable*/ - fdc.res[6] = 0; - fdc.res[7] = fdc.rw_track; - fdc.res[8] = fdc.head; - fdc.res[9] = fdc.sector; - fdc.res[10] = fdc.sector_size; - paramstogo = 7; + fdc_int(); + fdc.stat = 0xD0; + fdc.res[4] = 0x40 | (fdc.head ? 4 : 0) | fdc.drive; + fdc.res[5] = 0x02; /*Not writeable*/ + fdc.res[6] = 0; + fdc.res[7] = fdc.rw_track; + fdc.res[8] = fdc.head; + fdc.res[9] = fdc.sector; + fdc.res[10] = fdc.sector_size; + paramstogo = 7; } int fdc_getdata(int last) { - int data; + int data; - if (fdc.pcjr || !fdc.dma) { - if (fdc.written) { - fdc_overrun(); -// pclog("Overrun\n"); - return -1; - } - if (fdc.pcjr || !fdc.fifo) { - data = fdc.dat; + if (fdc.pcjr || !fdc.dma) { + if (fdc.written) { + fdc_overrun(); + // pclog("Overrun\n"); + return -1; + } + if (fdc.pcjr || !fdc.fifo) { + data = fdc.dat; - if (!last) - fdc.stat = 0xb0; - } else { - data = fdc_fifo_buf_read(); + if (!last) + fdc.stat = 0xb0; + } else { + data = fdc_fifo_buf_read(); - if (!last && (fdc.fifobufpos == 0)) - fdc.stat = 0xb0; - } - } else { - data = dma_channel_read(2); + if (!last && (fdc.fifobufpos == 0)) + fdc.stat = 0xb0; + } + } else { + data = dma_channel_read(2); - if (!fdc.fifo) { - if (!last) - fdc.stat = 0x90; - } else { - fdc_fifo_buf_dummy(); + if (!fdc.fifo) { + if (!last) + fdc.stat = 0x90; + } else { + fdc_fifo_buf_dummy(); - if (!last && (fdc.fifobufpos == 0)) - fdc.stat = 0x90; - } + if (!last && (fdc.fifobufpos == 0)) + fdc.stat = 0x90; + } - if (data & DMA_OVER) - fdc.tc = 1; - } + if (data & DMA_OVER) + fdc.tc = 1; + } - fdc.written = 0; - return data & 0xff; + fdc.written = 0; + return data & 0xff; } void fdc_sectorid(uint8_t track, uint8_t side, uint8_t sector, uint8_t size, uint8_t crc1, uint8_t crc2) { -// pclog("SectorID %i %i %i %i\n", track, side, sector, size); - fdc_int(); - fdc.stat = 0xD0; - fdc.res[4] = (fdc.head ? 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; - paramstogo = 7; + // pclog("SectorID %i %i %i %i\n", track, side, sector, size); + fdc_int(); + fdc.stat = 0xD0; + fdc.res[4] = (fdc.head ? 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; + paramstogo = 7; } void fdc_indexpulse() { -// ioc_irqa(IOC_IRQA_DISC_INDEX); -// rpclog("c82c711_fdc_indexpulse\n"); + // ioc_irqa(IOC_IRQA_DISC_INDEX); + // rpclog("c82c711_fdc_indexpulse\n"); } void fdc_init() { - timer_add(&fdc.timer, fdc_callback, NULL, 0); - fdc.dskchg_activelow = 0; - fdc.enable_3f1 = 1; + timer_add(&fdc.timer, fdc_callback, NULL, 0); + fdc.dskchg_activelow = 0; + fdc.enable_3f1 = 1; - fdc_update_enh_mode(0); - fdc_update_densel_polarity(1); - fdc_update_rwc(0, 0); - fdc_update_rwc(1, 0); - fdc_update_densel_force(0); + fdc_update_enh_mode(0); + fdc_update_densel_polarity(1); + fdc_update_rwc(0, 0); + fdc_update_rwc(1, 0); + fdc_update_densel_force(0); - fdc.fifo = fdc.tfifo = 0; + fdc.fifo = fdc.tfifo = 0; } void fdc_add() { - io_sethandler(0x03f0, 0x0006, fdc_read, NULL, NULL, fdc_write, NULL, NULL, NULL); - io_sethandler(0x03f7, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, NULL); - fdc.pcjr = 0; - fdc.ps1 = 0; + io_sethandler(0x03f0, 0x0006, fdc_read, NULL, NULL, fdc_write, NULL, NULL, NULL); + io_sethandler(0x03f7, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, NULL); + fdc.pcjr = 0; + fdc.ps1 = 0; } void fdc_add_pcjr() { - io_sethandler(0x00f0, 0x0006, fdc_read, NULL, NULL, fdc_write, NULL, NULL, NULL); - timer_add(&fdc.watchdog_timer, fdc_watchdog_poll, &fdc, 0); - fdc.pcjr = 1; - fdc.ps1 = 0; + io_sethandler(0x00f0, 0x0006, fdc_read, NULL, NULL, fdc_write, NULL, NULL, NULL); + timer_add(&fdc.watchdog_timer, fdc_watchdog_poll, &fdc, 0); + fdc.pcjr = 1; + fdc.ps1 = 0; } void fdc_remove() { - io_removehandler(0x03f0, 0x0006, fdc_read, NULL, NULL, fdc_write, NULL, NULL, NULL); - io_removehandler(0x03f7, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, NULL); + io_removehandler(0x03f0, 0x0006, fdc_read, NULL, NULL, fdc_write, NULL, NULL, NULL); + io_removehandler(0x03f7, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, NULL); } void fdc_discchange_clear(int drive) { - if (drive < 2) - disc_changed[drive] = 0; + if (drive < 2) + disc_changed[drive] = 0; } -int fdc_discchange_read() { - return (disc_changed[fdc.drive] || drive_empty[fdc.drive]) ? 1 : 0; -} +int fdc_discchange_read() { return (disc_changed[fdc.drive] || drive_empty[fdc.drive]) ? 1 : 0; } -void fdc_set_dskchg_activelow() { - fdc.dskchg_activelow = 1; -} +void fdc_set_dskchg_activelow() { fdc.dskchg_activelow = 1; } -void fdc_3f1_enable(int enable) { - fdc.enable_3f1 = enable; -} +void fdc_3f1_enable(int enable) { fdc.enable_3f1 = enable; } -void fdc_set_ps1() { - fdc.ps1 = 1; -} +void fdc_set_ps1() { fdc.ps1 = 1; } diff --git a/src/floppy/fdc37c665.c b/src/floppy/fdc37c665.c index e26760c8..dcaff38a 100644 --- a/src/floppy/fdc37c665.c +++ b/src/floppy/fdc37c665.c @@ -12,126 +12,142 @@ static int fdc37c665_curreg; static uint8_t fdc37c665_regs[16]; static void write_lock(uint8_t val) { - if (val == 0x55 && fdc37c665_lock[1] == 0x55) - fdc_3f1_enable(0); - if (fdc37c665_lock[0] == 0x55 && fdc37c665_lock[1] == 0x55 && val != 0x55) - fdc_3f1_enable(1); + if (val == 0x55 && fdc37c665_lock[1] == 0x55) + fdc_3f1_enable(0); + if (fdc37c665_lock[0] == 0x55 && fdc37c665_lock[1] == 0x55 && val != 0x55) + fdc_3f1_enable(1); - fdc37c665_lock[0] = fdc37c665_lock[1]; - fdc37c665_lock[1] = val; + fdc37c665_lock[0] = fdc37c665_lock[1]; + fdc37c665_lock[1] = val; } void fdc37c665_write(uint16_t port, uint8_t val, void *priv) { -// pclog("Write SuperIO %04x %02x\n", port, val); - if (fdc37c665_lock[0] == 0x55 && fdc37c665_lock[1] == 0x55) { - if (port == 0x3f0) { - if (val == 0xaa) - write_lock(val); - else - fdc37c665_curreg = val & 0xf; - } else { - uint16_t com3_addr = 0, com4_addr = 0; - fdc37c665_regs[fdc37c665_curreg] = val; -// pclog("Write superIO %02x %02x %04x(%08x):%08x\n", fdc37c665_curreg, val, CS, cs, pc); + // pclog("Write SuperIO %04x %02x\n", port, val); + if (fdc37c665_lock[0] == 0x55 && fdc37c665_lock[1] == 0x55) { + if (port == 0x3f0) { + if (val == 0xaa) + write_lock(val); + else + fdc37c665_curreg = val & 0xf; + } else { + uint16_t com3_addr = 0, com4_addr = 0; + fdc37c665_regs[fdc37c665_curreg] = val; + // pclog("Write superIO %02x %02x %04x(%08x):%08x\n", fdc37c665_curreg, val, CS, + // cs, pc); - switch (fdc37c665_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; - } + switch (fdc37c665_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; + } - if (!(fdc37c665_regs[2] & 4)) - serial1_remove(); - else - switch (fdc37c665_regs[2] & 3) { - case 0:serial1_set(0x3f8, 4); - break; - case 1:serial1_set(0x2f8, 4); - break; - case 2:serial1_set(com3_addr, 4); - break; - case 3:serial1_set(com4_addr, 4); - break; - } + if (!(fdc37c665_regs[2] & 4)) + serial1_remove(); + else + switch (fdc37c665_regs[2] & 3) { + case 0: + serial1_set(0x3f8, 4); + break; + case 1: + serial1_set(0x2f8, 4); + break; + case 2: + serial1_set(com3_addr, 4); + break; + case 3: + serial1_set(com4_addr, 4); + break; + } - if (!(fdc37c665_regs[2] & 0x40)) - serial2_remove(); - else - switch (fdc37c665_regs[2] & 0x30) { - case 0x00:serial2_set(0x3f8, 3); - break; - case 0x10:serial2_set(0x2f8, 3); - break; - case 0x20:serial2_set(com3_addr, 3); - break; - case 0x30:serial2_set(com4_addr, 3); - break; - } + if (!(fdc37c665_regs[2] & 0x40)) + serial2_remove(); + else + switch (fdc37c665_regs[2] & 0x30) { + case 0x00: + serial2_set(0x3f8, 3); + break; + case 0x10: + serial2_set(0x2f8, 3); + break; + case 0x20: + serial2_set(com3_addr, 3); + break; + case 0x30: + serial2_set(com4_addr, 3); + break; + } - lpt1_remove(); - lpt2_remove(); - switch (fdc37c665_regs[1] & 3) { - case 1:lpt1_init(0x3bc); - break; - case 2:lpt1_init(0x378); - break; - case 3:lpt1_init(0x278); - break; - } + lpt1_remove(); + lpt2_remove(); + switch (fdc37c665_regs[1] & 3) { + case 1: + lpt1_init(0x3bc); + break; + case 2: + lpt1_init(0x378); + break; + case 3: + lpt1_init(0x278); + break; + } - fdc_update_enh_mode((fdc37c665_regs[3] & 2) ? 1 : 0); + fdc_update_enh_mode((fdc37c665_regs[3] & 2) ? 1 : 0); - fdc_update_densel_force((fdc37c665_regs[5] & 0x18) >> 3); - fdd_swap = ((fdc37c665_regs[5] & 0x20) >> 5); - } - } else { - if (port == 0x3f0) - write_lock(val); - } + fdc_update_densel_force((fdc37c665_regs[5] & 0x18) >> 3); + fdd_swap = ((fdc37c665_regs[5] & 0x20) >> 5); + } + } else { + if (port == 0x3f0) + write_lock(val); + } } uint8_t fdc37c665_read(uint16_t port, void *priv) { -// pclog("Read SuperIO %04x %02x\n", port, fdc37c665_curreg); - if (fdc37c665_lock[0] == 0x55 && fdc37c665_lock[1] == 0x55) { - if (port == 0x3f1) - return fdc37c665_regs[fdc37c665_curreg]; - } - return 0xff; + // pclog("Read SuperIO %04x %02x\n", port, fdc37c665_curreg); + if (fdc37c665_lock[0] == 0x55 && fdc37c665_lock[1] == 0x55) { + if (port == 0x3f1) + return fdc37c665_regs[fdc37c665_curreg]; + } + return 0xff; } void fdc37c665_init() { - io_sethandler(0x03f0, 0x0002, fdc37c665_read, NULL, NULL, fdc37c665_write, NULL, NULL, NULL); + io_sethandler(0x03f0, 0x0002, fdc37c665_read, NULL, NULL, fdc37c665_write, NULL, NULL, NULL); - fdc_update_is_nsc(0); + fdc_update_is_nsc(0); - fdc37c665_lock[0] = fdc37c665_lock[1] = 0; - fdc37c665_regs[0x0] = 0x3b; - fdc37c665_regs[0x1] = 0x9f; - fdc37c665_regs[0x2] = 0xdc; - fdc37c665_regs[0x3] = 0x78; - fdc37c665_regs[0x4] = 0x00; - fdc37c665_regs[0x5] = 0x00; - fdc37c665_regs[0x6] = 0xff; - fdc37c665_regs[0x7] = 0x00; - fdc37c665_regs[0x8] = 0x00; - fdc37c665_regs[0x9] = 0x00; - fdc37c665_regs[0xa] = 0x00; - fdc37c665_regs[0xb] = 0x00; - fdc37c665_regs[0xc] = 0x00; - fdc37c665_regs[0xd] = 0x65; - fdc37c665_regs[0xe] = 0x01; - fdc37c665_regs[0xf] = 0x00; + fdc37c665_lock[0] = fdc37c665_lock[1] = 0; + fdc37c665_regs[0x0] = 0x3b; + fdc37c665_regs[0x1] = 0x9f; + fdc37c665_regs[0x2] = 0xdc; + fdc37c665_regs[0x3] = 0x78; + fdc37c665_regs[0x4] = 0x00; + fdc37c665_regs[0x5] = 0x00; + fdc37c665_regs[0x6] = 0xff; + fdc37c665_regs[0x7] = 0x00; + fdc37c665_regs[0x8] = 0x00; + fdc37c665_regs[0x9] = 0x00; + fdc37c665_regs[0xa] = 0x00; + fdc37c665_regs[0xb] = 0x00; + fdc37c665_regs[0xc] = 0x00; + fdc37c665_regs[0xd] = 0x65; + fdc37c665_regs[0xe] = 0x01; + fdc37c665_regs[0xf] = 0x00; - fdc_update_densel_polarity(1); - fdc_update_densel_force(0); - fdd_swap = 0; + fdc_update_densel_polarity(1); + fdc_update_densel_force(0); + fdd_swap = 0; } diff --git a/src/floppy/fdc37c93x.c b/src/floppy/fdc37c93x.c index a8c17959..b78d7166 100644 --- a/src/floppy/fdc37c93x.c +++ b/src/floppy/fdc37c93x.c @@ -8,207 +8,227 @@ #include "fdc37c93x.h" typedef struct fdc37c93x_t { - int index; + int index; - uint8_t global_regs[0x30]; - uint8_t fdc_regs[0x100]; - uint8_t ide1_regs[0x100]; - uint8_t ide2_regs[0x100]; - uint8_t lpt_regs[0x100]; - uint8_t com1_regs[0x100]; - uint8_t com2_regs[0x100]; - uint8_t rtc_regs[0x100]; - uint8_t kbd_regs[0x100]; - uint8_t auxio_regs[0x100]; - uint8_t accessbus_regs[0x100]; + uint8_t global_regs[0x30]; + uint8_t fdc_regs[0x100]; + uint8_t ide1_regs[0x100]; + uint8_t ide2_regs[0x100]; + uint8_t lpt_regs[0x100]; + uint8_t com1_regs[0x100]; + uint8_t com2_regs[0x100]; + uint8_t rtc_regs[0x100]; + uint8_t kbd_regs[0x100]; + uint8_t auxio_regs[0x100]; + uint8_t accessbus_regs[0x100]; - uint8_t lock[2]; + uint8_t lock[2]; } fdc37c93x_t; static fdc37c93x_t fdc37c93x_global; static void write_lock(fdc37c93x_t *fdc37c93x, uint8_t val) { - if (val == 0x55 && fdc37c93x->lock[1] == 0x55) - fdc_3f1_enable(0); - if (fdc37c93x->lock[0] == 0x55 && fdc37c93x->lock[1] == 0x55 && val != 0x55) - fdc_3f1_enable(1); + if (val == 0x55 && fdc37c93x->lock[1] == 0x55) + fdc_3f1_enable(0); + if (fdc37c93x->lock[0] == 0x55 && fdc37c93x->lock[1] == 0x55 && val != 0x55) + fdc_3f1_enable(1); - fdc37c93x->lock[0] = fdc37c93x->lock[1]; - fdc37c93x->lock[1] = val; + fdc37c93x->lock[0] = fdc37c93x->lock[1]; + fdc37c93x->lock[1] = val; } void fdc37c93x_write(uint16_t port, uint8_t val, void *p) { - fdc37c93x_t *fdc37c93x = (fdc37c93x_t *)p; + fdc37c93x_t *fdc37c93x = (fdc37c93x_t *)p; -// pclog("Write SuperIO %04x %02x\n", port, val); - if (fdc37c93x->lock[0] == 0x55 && fdc37c93x->lock[1] == 0x55) { - if (port == 0x3f0) { - if (val == 0xaa) - write_lock(fdc37c93x, val); - else - fdc37c93x->index = val; - } else { - uint16_t addr; - int irq; + // pclog("Write SuperIO %04x %02x\n", port, val); + if (fdc37c93x->lock[0] == 0x55 && fdc37c93x->lock[1] == 0x55) { + if (port == 0x3f0) { + if (val == 0xaa) + write_lock(fdc37c93x, val); + else + fdc37c93x->index = val; + } else { + uint16_t addr; + int irq; -// pclog("fdc37c93x_write: index=%02x dev=%i val=%02x\n", fdc37c93x->index, fdc37c93x->global_regs[7], val); - if (fdc37c93x->index < 0x30) { - if (fdc37c93x->index != 0x20 && fdc37c93x->index != 0x21) - fdc37c93x->global_regs[fdc37c93x->index] = val; - } else - switch (fdc37c93x->global_regs[7]) { - case 0:fdc37c93x->fdc_regs[fdc37c93x->index] = val; - break; - case 1:fdc37c93x->ide1_regs[fdc37c93x->index] = val; - break; - case 2:fdc37c93x->ide2_regs[fdc37c93x->index] = val; - break; - case 3:fdc37c93x->lpt_regs[fdc37c93x->index] = val; - break; - case 4:fdc37c93x->com1_regs[fdc37c93x->index] = val; - break; - case 5:fdc37c93x->com2_regs[fdc37c93x->index] = val; - break; - case 6:fdc37c93x->rtc_regs[fdc37c93x->index] = val; - break; - case 7:fdc37c93x->kbd_regs[fdc37c93x->index] = val; - break; - case 8:fdc37c93x->auxio_regs[fdc37c93x->index] = val; - break; - case 9:fdc37c93x->accessbus_regs[fdc37c93x->index] = val; - break; - } + // pclog("fdc37c93x_write: index=%02x dev=%i val=%02x\n", fdc37c93x->index, + // fdc37c93x->global_regs[7], val); + if (fdc37c93x->index < 0x30) { + if (fdc37c93x->index != 0x20 && fdc37c93x->index != 0x21) + fdc37c93x->global_regs[fdc37c93x->index] = val; + } else + switch (fdc37c93x->global_regs[7]) { + case 0: + fdc37c93x->fdc_regs[fdc37c93x->index] = val; + break; + case 1: + fdc37c93x->ide1_regs[fdc37c93x->index] = val; + break; + case 2: + fdc37c93x->ide2_regs[fdc37c93x->index] = val; + break; + case 3: + fdc37c93x->lpt_regs[fdc37c93x->index] = val; + break; + case 4: + fdc37c93x->com1_regs[fdc37c93x->index] = val; + break; + case 5: + fdc37c93x->com2_regs[fdc37c93x->index] = val; + break; + case 6: + fdc37c93x->rtc_regs[fdc37c93x->index] = val; + break; + case 7: + fdc37c93x->kbd_regs[fdc37c93x->index] = val; + break; + case 8: + fdc37c93x->auxio_regs[fdc37c93x->index] = val; + break; + case 9: + fdc37c93x->accessbus_regs[fdc37c93x->index] = val; + break; + } - fdc_remove(); - if ((fdc37c93x->global_regs[0x22] & 0x01) && (fdc37c93x->fdc_regs[0x30] & 0x01)) { -// pclog("FDC enabled\n"); - fdc_add(); - } -/* else - pclog("FDC disabled\n");*/ + fdc_remove(); + if ((fdc37c93x->global_regs[0x22] & 0x01) && (fdc37c93x->fdc_regs[0x30] & 0x01)) { + // pclog("FDC enabled\n"); + fdc_add(); + } + /* else + pclog("FDC disabled\n");*/ - lpt1_remove(); - lpt2_remove(); - addr = (fdc37c93x->lpt_regs[0x61] & 0xfc) | ((fdc37c93x->lpt_regs[0x60] & 3) << 8); - if ((fdc37c93x->global_regs[0x22] & (1 << 3)) && (fdc37c93x->lpt_regs[0x30] & 0x01)) { -// pclog("LPT addr = %04x\n", addr); - lpt1_init(addr); - } -/* else - pclog("LPT disabled\n");*/ + lpt1_remove(); + lpt2_remove(); + addr = (fdc37c93x->lpt_regs[0x61] & 0xfc) | ((fdc37c93x->lpt_regs[0x60] & 3) << 8); + if ((fdc37c93x->global_regs[0x22] & (1 << 3)) && (fdc37c93x->lpt_regs[0x30] & 0x01)) { + // pclog("LPT addr = %04x\n", addr); + lpt1_init(addr); + } + /* else + pclog("LPT disabled\n");*/ - serial1_remove(); - addr = (fdc37c93x->com1_regs[0x61] & 0xf8) | ((fdc37c93x->com1_regs[0x60] & 3) << 8); - irq = fdc37c93x->com1_regs[0x70] & 0xf; - if ((fdc37c93x->global_regs[0x22] & (1 << 4)) && (fdc37c93x->com1_regs[0x30] & 0x01)) { -// pclog("COM1 addr = %04x, IRQ = %i\n", addr, irq); - serial1_set(addr, irq); - } -/* else - pclog("COM1 disabled\n");*/ + serial1_remove(); + addr = (fdc37c93x->com1_regs[0x61] & 0xf8) | ((fdc37c93x->com1_regs[0x60] & 3) << 8); + irq = fdc37c93x->com1_regs[0x70] & 0xf; + if ((fdc37c93x->global_regs[0x22] & (1 << 4)) && (fdc37c93x->com1_regs[0x30] & 0x01)) { + // pclog("COM1 addr = %04x, IRQ = %i\n", addr, irq); + serial1_set(addr, irq); + } + /* else + pclog("COM1 disabled\n");*/ - serial2_remove(); - addr = (fdc37c93x->com2_regs[0x61] & 0xf8) | ((fdc37c93x->com2_regs[0x60] & 3) << 8); - irq = fdc37c93x->com2_regs[0x70] & 0xf; - if ((fdc37c93x->global_regs[0x22] & (1 << 5)) && (fdc37c93x->com2_regs[0x30] & 0x01)) { -// pclog("COM2 addr = %04x, IRQ = %i\n", addr, irq); - serial2_set(addr, irq); - } -/* else - pclog("COM2 disabled\n");*/ + serial2_remove(); + addr = (fdc37c93x->com2_regs[0x61] & 0xf8) | ((fdc37c93x->com2_regs[0x60] & 3) << 8); + irq = fdc37c93x->com2_regs[0x70] & 0xf; + if ((fdc37c93x->global_regs[0x22] & (1 << 5)) && (fdc37c93x->com2_regs[0x30] & 0x01)) { + // pclog("COM2 addr = %04x, IRQ = %i\n", addr, irq); + serial2_set(addr, irq); + } + /* else + pclog("COM2 disabled\n");*/ + fdc_update_enh_mode(fdc37c93x->fdc_regs[0xf0] & 1); - fdc_update_enh_mode(fdc37c93x->fdc_regs[0xf0] & 1); - - fdc_update_densel_force((fdc37c93x->fdc_regs[0xf1] & 0x0c) >> 2); - fdd_swap = (fdc37c93x->fdc_regs[0xf0] & (1 << 4)) ? 1 : 0; - } - } else { - if (port == 0x3f0) - write_lock(fdc37c93x, val); - } + fdc_update_densel_force((fdc37c93x->fdc_regs[0xf1] & 0x0c) >> 2); + fdd_swap = (fdc37c93x->fdc_regs[0xf0] & (1 << 4)) ? 1 : 0; + } + } else { + if (port == 0x3f0) + write_lock(fdc37c93x, val); + } } uint8_t fdc37c93x_read(uint16_t port, void *p) { - fdc37c93x_t *fdc37c93x = (fdc37c93x_t *)p; + fdc37c93x_t *fdc37c93x = (fdc37c93x_t *)p; -// pclog("Read SuperIO %04x %02x\n", port, fdc37c665_curreg); - if (fdc37c93x->lock[0] == 0x55 && fdc37c93x->lock[1] == 0x55) { - if (port == 0x3f1) { - if (fdc37c93x->index < 0x30) - return fdc37c93x->global_regs[fdc37c93x->index]; - else - switch (fdc37c93x->global_regs[7]) { - case 0:return fdc37c93x->fdc_regs[fdc37c93x->index]; - case 1:return fdc37c93x->ide1_regs[fdc37c93x->index]; - case 2:return fdc37c93x->ide2_regs[fdc37c93x->index]; - case 3:return fdc37c93x->lpt_regs[fdc37c93x->index]; - case 4:return fdc37c93x->com1_regs[fdc37c93x->index]; - case 5:return fdc37c93x->com2_regs[fdc37c93x->index]; - case 6:return fdc37c93x->rtc_regs[fdc37c93x->index]; - case 7:return fdc37c93x->kbd_regs[fdc37c93x->index]; - case 8:return fdc37c93x->auxio_regs[fdc37c93x->index]; - case 9:return fdc37c93x->accessbus_regs[fdc37c93x->index]; - } - } - } - return 0xff; + // pclog("Read SuperIO %04x %02x\n", port, fdc37c665_curreg); + if (fdc37c93x->lock[0] == 0x55 && fdc37c93x->lock[1] == 0x55) { + if (port == 0x3f1) { + if (fdc37c93x->index < 0x30) + return fdc37c93x->global_regs[fdc37c93x->index]; + else + switch (fdc37c93x->global_regs[7]) { + case 0: + return fdc37c93x->fdc_regs[fdc37c93x->index]; + case 1: + return fdc37c93x->ide1_regs[fdc37c93x->index]; + case 2: + return fdc37c93x->ide2_regs[fdc37c93x->index]; + case 3: + return fdc37c93x->lpt_regs[fdc37c93x->index]; + case 4: + return fdc37c93x->com1_regs[fdc37c93x->index]; + case 5: + return fdc37c93x->com2_regs[fdc37c93x->index]; + case 6: + return fdc37c93x->rtc_regs[fdc37c93x->index]; + case 7: + return fdc37c93x->kbd_regs[fdc37c93x->index]; + case 8: + return fdc37c93x->auxio_regs[fdc37c93x->index]; + case 9: + return fdc37c93x->accessbus_regs[fdc37c93x->index]; + } + } + } + return 0xff; } void fdc37c932fr_init() { - fdc37c93x_t *fdc37c93x = &fdc37c93x_global; - int c; + fdc37c93x_t *fdc37c93x = &fdc37c93x_global; + int c; - io_sethandler(0x03f0, 0x0002, fdc37c93x_read, NULL, NULL, fdc37c93x_write, NULL, NULL, fdc37c93x); + io_sethandler(0x03f0, 0x0002, fdc37c93x_read, NULL, NULL, fdc37c93x_write, NULL, NULL, fdc37c93x); - fdc_update_is_nsc(0); + fdc_update_is_nsc(0); - memset(&fdc37c93x_global, 0, sizeof(fdc37c93x_global)); + memset(&fdc37c93x_global, 0, sizeof(fdc37c93x_global)); - fdc37c93x->global_regs[0x03] = 0x03; - fdc37c93x->global_regs[0x20] = 0x03; - fdc37c93x->global_regs[0x21] = 0x01; - fdc37c93x->global_regs[0x24] = 0x04; - fdc37c93x->global_regs[0x26] = 0xf0; - fdc37c93x->global_regs[0x27] = 0x03; + fdc37c93x->global_regs[0x03] = 0x03; + fdc37c93x->global_regs[0x20] = 0x03; + fdc37c93x->global_regs[0x21] = 0x01; + fdc37c93x->global_regs[0x24] = 0x04; + fdc37c93x->global_regs[0x26] = 0xf0; + fdc37c93x->global_regs[0x27] = 0x03; - fdc37c93x->fdc_regs[0x60] = 0x03; - fdc37c93x->fdc_regs[0x61] = 0xf0; - fdc37c93x->fdc_regs[0x70] = 0x06; - fdc37c93x->fdc_regs[0x74] = 0x02; - fdc37c93x->fdc_regs[0xf0] = 0x0e; - fdc37c93x->fdc_regs[0xf2] = 0xff; + fdc37c93x->fdc_regs[0x60] = 0x03; + fdc37c93x->fdc_regs[0x61] = 0xf0; + fdc37c93x->fdc_regs[0x70] = 0x06; + fdc37c93x->fdc_regs[0x74] = 0x02; + fdc37c93x->fdc_regs[0xf0] = 0x0e; + fdc37c93x->fdc_regs[0xf2] = 0xff; - fdc37c93x->ide1_regs[0x60] = 0x01; - fdc37c93x->ide1_regs[0x61] = 0xf0; - fdc37c93x->ide1_regs[0x62] = 0x03; - fdc37c93x->ide1_regs[0x63] = 0xf6; - fdc37c93x->ide1_regs[0x70] = 0x0e; - fdc37c93x->ide1_regs[0xf0] = 0x0c; - fdc37c93x->ide1_regs[0xf1] = 0x0d; + fdc37c93x->ide1_regs[0x60] = 0x01; + fdc37c93x->ide1_regs[0x61] = 0xf0; + fdc37c93x->ide1_regs[0x62] = 0x03; + fdc37c93x->ide1_regs[0x63] = 0xf6; + fdc37c93x->ide1_regs[0x70] = 0x0e; + fdc37c93x->ide1_regs[0xf0] = 0x0c; + fdc37c93x->ide1_regs[0xf1] = 0x0d; - fdc37c93x->lpt_regs[0x74] = 0x04; - fdc37c93x->lpt_regs[0xf0] = 0x3c; + fdc37c93x->lpt_regs[0x74] = 0x04; + fdc37c93x->lpt_regs[0xf0] = 0x3c; - fdc37c93x->com2_regs[0x74] = 0x04; - fdc37c93x->com2_regs[0xf1] = 0x02; - fdc37c93x->com2_regs[0xf2] = 0x03; + fdc37c93x->com2_regs[0x74] = 0x04; + fdc37c93x->com2_regs[0xf1] = 0x02; + fdc37c93x->com2_regs[0xf2] = 0x03; - fdc37c93x->rtc_regs[0x63] = 0x70; - fdc37c93x->rtc_regs[0xf4] = 0x03; + fdc37c93x->rtc_regs[0x63] = 0x70; + fdc37c93x->rtc_regs[0xf4] = 0x03; - fdc37c93x->auxio_regs[0xb1] = 0x80; - fdc37c93x->auxio_regs[0xc0] = 0x01; - fdc37c93x->auxio_regs[0xc1] = 0x01; - fdc37c93x->auxio_regs[0xc5] = 0x01; - fdc37c93x->auxio_regs[0xc6] = 0x01; - fdc37c93x->auxio_regs[0xc7] = 0x01; - fdc37c93x->auxio_regs[0xc8] = 0x01; - fdc37c93x->auxio_regs[0xc9] = 0x80; - for (c = 0xcb; c < 0xee; c++) - fdc37c93x->auxio_regs[c] = 0x01; + fdc37c93x->auxio_regs[0xb1] = 0x80; + fdc37c93x->auxio_regs[0xc0] = 0x01; + fdc37c93x->auxio_regs[0xc1] = 0x01; + fdc37c93x->auxio_regs[0xc5] = 0x01; + fdc37c93x->auxio_regs[0xc6] = 0x01; + fdc37c93x->auxio_regs[0xc7] = 0x01; + fdc37c93x->auxio_regs[0xc8] = 0x01; + fdc37c93x->auxio_regs[0xc9] = 0x80; + for (c = 0xcb; c < 0xee; c++) + fdc37c93x->auxio_regs[c] = 0x01; - fdc_update_densel_polarity(1); - fdc_update_densel_force(0); - fdd_swap = 0; + fdc_update_densel_polarity(1); + fdc_update_densel_force(0); + fdd_swap = 0; } diff --git a/src/floppy/fdd.c b/src/floppy/fdd.c index b81ce4cb..ddffef39 100644 --- a/src/floppy/fdd.c +++ b/src/floppy/fdd.c @@ -4,16 +4,16 @@ #include "fdd.h" static struct { - int type; + int type; - int track; + int track; - int densel; + int densel; - int drate; + int drate; - int kbps; - int fdc_kbps; + int kbps; + int fdc_kbps; } fdd[2]; /* Flags: @@ -25,180 +25,171 @@ static struct { Bit 5: extended density supported; Bit 6: double step for 40-track media; */ -#define FLAG_RPM_300 1 -#define FLAG_RPM_360 2 -#define FLAG_525 4 -#define FLAG_HOLE0 8 -#define FLAG_HOLE1 16 -#define FLAG_HOLE2 32 -#define FLAG_DOUBLE_STEP 64 +#define FLAG_RPM_300 1 +#define FLAG_RPM_360 2 +#define FLAG_525 4 +#define FLAG_HOLE0 8 +#define FLAG_HOLE1 16 +#define FLAG_HOLE2 32 +#define FLAG_DOUBLE_STEP 64 static struct { - int max_track; - int flags; -} drive_types[] = - { - { /*None*/ - .max_track = 0, - .flags = 0 - }, - { /*5.25" DD*/ - .max_track = 41, - .flags = FLAG_RPM_300 | FLAG_525 | FLAG_HOLE0 - }, - { /*5.25" HD*/ - .max_track = 82, - .flags = FLAG_RPM_360 | FLAG_525 | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP - }, - { /*5.25" HD Dual RPM*/ - .max_track = 82, - .flags = FLAG_RPM_300 | FLAG_RPM_360 | FLAG_525 | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP - }, - { /*3.5" DD*/ - .max_track = 82, - .flags = FLAG_RPM_300 | FLAG_HOLE0 - }, - { /*3.5" HD*/ - .max_track = 82, - .flags = FLAG_RPM_300 | FLAG_HOLE0 | FLAG_HOLE1 - }, - { /*3.5" HD 3-Mode*/ - .max_track = 82, - .flags = FLAG_RPM_300 | FLAG_RPM_360 | FLAG_HOLE0 | FLAG_HOLE1 - }, - { /*3.5" ED*/ - .max_track = 82, - .flags = FLAG_RPM_300 | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_HOLE2 - } - }; + int max_track; + int flags; +} drive_types[] = {{/*None*/ + .max_track = 0, + .flags = 0}, + {/*5.25" DD*/ + .max_track = 41, + .flags = FLAG_RPM_300 | FLAG_525 | FLAG_HOLE0}, + {/*5.25" HD*/ + .max_track = 82, + .flags = FLAG_RPM_360 | FLAG_525 | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP}, + {/*5.25" HD Dual RPM*/ + .max_track = 82, + .flags = FLAG_RPM_300 | FLAG_RPM_360 | FLAG_525 | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP}, + {/*3.5" DD*/ + .max_track = 82, + .flags = FLAG_RPM_300 | FLAG_HOLE0}, + {/*3.5" HD*/ + .max_track = 82, + .flags = FLAG_RPM_300 | FLAG_HOLE0 | FLAG_HOLE1}, + {/*3.5" HD 3-Mode*/ + .max_track = 82, + .flags = FLAG_RPM_300 | FLAG_RPM_360 | FLAG_HOLE0 | FLAG_HOLE1}, + {/*3.5" ED*/ + .max_track = 82, + .flags = FLAG_RPM_300 | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_HOLE2}}; int fdd_swap = 0; uint64_t fdd_seek(int drive, int track_diff) { - drive ^= fdd_swap; + drive ^= fdd_swap; - if (drive >= 2) - return 1000 * TIMER_USEC; + if (drive >= 2) + return 1000 * TIMER_USEC; - fdd[drive].track += track_diff; + fdd[drive].track += track_diff; - if (fdd[drive].track < 0) - fdd[drive].track = 0; + 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; + if (fdd[drive].track > drive_types[fdd[drive].type].max_track) + fdd[drive].track = drive_types[fdd[drive].type].max_track; -// pclog("fdd_seek: drive=%i track_diff=%i old_track=%i track=%i\n", drive, track_diff, old_track, fdd[drive].track); + // pclog("fdd_seek: drive=%i track_diff=%i old_track=%i track=%i\n", drive, track_diff, old_track, + // fdd[drive].track); - fdc_discchange_clear(drive); + fdc_discchange_clear(drive); - disc_seek(drive, fdd[drive].track); - return 1000 * TIMER_USEC; + disc_seek(drive, fdd[drive].track); + return 1000 * TIMER_USEC; } void fdd_disc_changed(int drive) { - drive ^= fdd_swap; + drive ^= fdd_swap; - /*Force reload of current track data*/ - if (drive < 2) - disc_seek(drive, fdd[drive].track); + /*Force reload of current track data*/ + if (drive < 2) + disc_seek(drive, fdd[drive].track); } int fdd_track0(int drive) { - drive ^= fdd_swap; + drive ^= fdd_swap; - if (drive >= 2) - return 0; + if (drive >= 2) + return 0; - /* If drive is disabled, TRK0 never gets set. */ - if (!drive_types[fdd[drive].type].max_track) - return 0; + /* If drive is disabled, TRK0 never gets set. */ + if (!drive_types[fdd[drive].type].max_track) + return 0; - return !fdd[drive].track; + return !fdd[drive].track; } void fdd_set_densel(int densel) { - fdd[0].densel = densel; - fdd[1].densel = densel; + fdd[0].densel = densel; + fdd[1].densel = densel; } int fdd_getrpm(int drive) { - int hole; + int hole; - drive ^= fdd_swap; + drive ^= fdd_swap; - if (drive >= 2) - return 0; + if (drive >= 2) + return 0; - hole = disc_hole(drive); + hole = disc_hole(drive); - 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_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 fdd[drive].densel ? 360 : 300; - } else { - /* disc_hole(drive) returns 0 for double density media, 1 for high density, and 2 for extended density. */ - if (hole == 1) { - return fdd[drive].densel ? 300 : 360; - } else { - return 300; - } - } + if (drive_types[fdd[drive].type].flags & FLAG_525) { + return fdd[drive].densel ? 360 : 300; + } else { + /* disc_hole(drive) returns 0 for double density media, 1 for high density, and 2 for extended density. */ + if (hole == 1) { + return fdd[drive].densel ? 300 : 360; + } else { + return 300; + } + } - switch (fdd[drive].type) { - case 0:return 300; - case 1:return 360; - } + switch (fdd[drive].type) { + case 0: + return 300; + case 1: + return 360; + } } -void fdd_setswap(int swap) { - fdd_swap = swap ? 1 : 0; -} +void fdd_setswap(int swap) { fdd_swap = swap ? 1 : 0; } int fdd_can_read_medium(int drive) { - int hole; + int hole; - drive ^= fdd_swap; + drive ^= fdd_swap; - if (drive >= 2) - return 0; + if (drive >= 2) + return 0; - hole = disc_hole(drive); + hole = disc_hole(drive); - hole = 1 << (hole + 3); + hole = 1 << (hole + 3); -// pclog("Drive %02X, type %02X, hole flag %02X, flags %02X, result %02X\n", drive, fdd[drive].type, hole, drive_types[fdd[drive].type].flags, drive_types[fdd[drive].type].flags & hole); - return (drive_types[fdd[drive].type].flags & hole) ? 1 : 0; + // pclog("Drive %02X, type %02X, hole flag %02X, flags %02X, result %02X\n", drive, fdd[drive].type, hole, + //drive_types[fdd[drive].type].flags, drive_types[fdd[drive].type].flags & hole); + return (drive_types[fdd[drive].type].flags & hole) ? 1 : 0; } int fdd_doublestep_40(int drive) { - if (drive >= 2) - return 0; - return drive_types[fdd[drive].type].flags & FLAG_DOUBLE_STEP; + if (drive >= 2) + return 0; + return drive_types[fdd[drive].type].flags & FLAG_DOUBLE_STEP; } void fdd_set_type(int drive, int type) { - if (drive < 2) - fdd[drive].type = type; + if (drive < 2) + fdd[drive].type = type; } int fdd_get_type(int drive) { - if (drive >= 2) - return 0; - return fdd[drive].type; + if (drive >= 2) + return 0; + return fdd[drive].type; } int fdd_is_525(int drive) { - if (drive >= 2) - return 0; - return drive_types[fdd[drive].type].flags & FLAG_525; + if (drive >= 2) + return 0; + return drive_types[fdd[drive].type].flags & FLAG_525; } int fdd_is_ed(int drive) { - if (drive >= 2) - return 0; - return drive_types[fdd[drive].type].flags & FLAG_HOLE2; + if (drive >= 2) + return 0; + return drive_types[fdd[drive].type].flags & FLAG_HOLE2; } diff --git a/src/hdd/hdd.c b/src/hdd/hdd.c index 82c07ec3..a00bc576 100644 --- a/src/hdd/hdd.c +++ b/src/hdd/hdd.c @@ -23,144 +23,125 @@ static device_t null_hdd_device; static int hdd_controller_current; char *hdd_controller_get_name(int hdd) { - if (hdd_controllers[hdd] != NULL) - return hdd_controllers[hdd]->name; - return ""; + if (hdd_controllers[hdd] != NULL) + return hdd_controllers[hdd]->name; + return ""; } char *hdd_controller_get_internal_name(int hdd) { - if (hdd_controllers[hdd] != NULL) - return hdd_controllers[hdd]->internal_name; - return ""; + if (hdd_controllers[hdd] != NULL) + return hdd_controllers[hdd]->internal_name; + return ""; } int hdd_controller_get_flags(int hdd) { - if (hdd_controllers[hdd] != NULL) - return hdd_controllers[hdd]->device->flags; - return 0; + if (hdd_controllers[hdd] != NULL) + return hdd_controllers[hdd]->device->flags; + return 0; } int hdd_controller_available(int hdd) { - if (hdd_controllers[hdd] != NULL) - return device_available(hdd_controllers[hdd]->device); - return 0; + if (hdd_controllers[hdd] != NULL) + return device_available(hdd_controllers[hdd]->device); + return 0; } int hdd_controller_is_mfm(char *internal_name) { - int c = 0; + int c = 0; - while (hdd_controllers[c] != NULL) { - if (!strcmp(internal_name, hdd_controllers[c]->internal_name)) { - hdd_controller_current = c; - if (strcmp(internal_name, "none")) - return hdd_controllers[c]->is_mfm; - } - c++; - } + while (hdd_controllers[c] != NULL) { + if (!strcmp(internal_name, hdd_controllers[c]->internal_name)) { + hdd_controller_current = c; + if (strcmp(internal_name, "none")) + return hdd_controllers[c]->is_mfm; + } + c++; + } - return 0; + return 0; } int hdd_controller_is_ide(char *internal_name) { - int c = 0; + int c = 0; - while (hdd_controllers[c] != NULL) { - if (!strcmp(internal_name, hdd_controllers[c]->internal_name)) { - hdd_controller_current = c; - if (strcmp(internal_name, "none")) - return hdd_controllers[c]->is_ide; - } - c++; - } + while (hdd_controllers[c] != NULL) { + if (!strcmp(internal_name, hdd_controllers[c]->internal_name)) { + hdd_controller_current = c; + if (strcmp(internal_name, "none")) + return hdd_controllers[c]->is_ide; + } + c++; + } - return 0; + return 0; } int hdd_controller_is_scsi(char *internal_name) { - int c = 0; + int c = 0; - while (hdd_controllers[c] != NULL) { - if (!strcmp(internal_name, hdd_controllers[c]->internal_name)) { - hdd_controller_current = c; - if (strcmp(internal_name, "none")) - return hdd_controllers[c]->is_scsi; - } - c++; - } + while (hdd_controllers[c] != NULL) { + if (!strcmp(internal_name, hdd_controllers[c]->internal_name)) { + hdd_controller_current = c; + if (strcmp(internal_name, "none")) + return hdd_controllers[c]->is_scsi; + } + c++; + } - return 0; + return 0; } int hdd_controller_has_config(char *internal_name) { - int c = 0; + int c = 0; - while (hdd_controllers[c] != NULL) { - if (!strcmp(internal_name, hdd_controllers[c]->internal_name)) { - hdd_controller_current = c; - if (strcmp(internal_name, "none")) - return hdd_controllers[c]->device->config ? 1 : 0; - } - c++; - } + while (hdd_controllers[c] != NULL) { + if (!strcmp(internal_name, hdd_controllers[c]->internal_name)) { + hdd_controller_current = c; + if (strcmp(internal_name, "none")) + return hdd_controllers[c]->device->config ? 1 : 0; + } + c++; + } - return 0; + return 0; } device_t *hdd_controller_get_device(char *internal_name) { - int c = 0; + int c = 0; - while (hdd_controllers[c] != NULL) { - if (!strcmp(internal_name, hdd_controllers[c]->internal_name)) { - hdd_controller_current = c; - if (strcmp(internal_name, "none")) - return hdd_controllers[c]->device; - } - c++; - } + while (hdd_controllers[c] != NULL) { + if (!strcmp(internal_name, hdd_controllers[c]->internal_name)) { + hdd_controller_current = c; + if (strcmp(internal_name, "none")) + return hdd_controllers[c]->device; + } + c++; + } - return NULL; + return NULL; } -int hdd_controller_current_is_mfm() { - return hdd_controller_is_mfm(hdd_controller_name); -} -int hdd_controller_current_is_ide() { - return hdd_controller_is_ide(hdd_controller_name); -} -int hdd_controller_current_is_scsi() { - return hdd_controller_is_scsi(hdd_controller_name); -} +int hdd_controller_current_is_mfm() { return hdd_controller_is_mfm(hdd_controller_name); } +int hdd_controller_current_is_ide() { return hdd_controller_is_ide(hdd_controller_name); } +int hdd_controller_current_is_scsi() { return hdd_controller_is_scsi(hdd_controller_name); } void hdd_controller_init(char *internal_name) { - int c = 0; + int c = 0; - while (hdd_controllers[c] != NULL) { - if (!strcmp(internal_name, hdd_controllers[c]->internal_name)) { - hdd_controller_current = c; - if (strcmp(internal_name, "none")) - device_add(hdd_controllers[c]->device); - return; - } - c++; - } - /* fatal("Could not find hdd_controller %s\n", internal_name);*/ + while (hdd_controllers[c] != NULL) { + if (!strcmp(internal_name, hdd_controllers[c]->internal_name)) { + hdd_controller_current = c; + if (strcmp(internal_name, "none")) + device_add(hdd_controllers[c]->device); + return; + } + c++; + } + /* fatal("Could not find hdd_controller %s\n", internal_name);*/ } -static void *null_hdd_init() { - return NULL; -} +static void *null_hdd_init() { return NULL; } -static void null_hdd_close(void *p) { -} +static void null_hdd_close(void *p) {} -static device_t null_hdd_device = - { - "Null HDD controller", - 0, - null_hdd_init, - null_hdd_close, - NULL, - NULL, - NULL, - NULL, - NULL}; +static device_t null_hdd_device = {"Null HDD controller", 0, null_hdd_init, null_hdd_close, NULL, NULL, NULL, NULL, NULL}; HDD_CONTROLLER h_none = {"None", "none", &null_hdd_device, 0, 0, 0}; HDD_CONTROLLER h_mfm_at = {"[MFM] AT Fixed Disk Adapter", "mfm_at", &mfm_at_device, 1, 0, 0}; @@ -180,20 +161,20 @@ HDD_CONTROLLER h_rt1000b = {"[SCSI] Rancho RT1000B", "rt1000b", &scsi_rt1000b_de HDD_CONTROLLER h_t130b = {"[SCSI] Trantor T130B", "t130b", &scsi_t130b_device, 0, 0, 1}; void hdd_controller_init_builtin() { - pcem_add_hddcontroller(&h_none); - pcem_add_hddcontroller(&h_mfm_at); - pcem_add_hddcontroller(&h_dtc5150x); - pcem_add_hddcontroller(&h_mfm_xebec); - pcem_add_hddcontroller(&h_esdi_mca); - pcem_add_hddcontroller(&h_wd1007vse1); - pcem_add_hddcontroller(&h_ide); - pcem_add_hddcontroller(&h_xtide); - pcem_add_hddcontroller(&h_xtide_at); - pcem_add_hddcontroller(&h_xtide_ps1); - pcem_add_hddcontroller(&h_aha1542c); - pcem_add_hddcontroller(&h_bt545s); - pcem_add_hddcontroller(&h_ibmscsi_mca); - pcem_add_hddcontroller(&h_lcs6821n); - pcem_add_hddcontroller(&h_rt1000b); - pcem_add_hddcontroller(&h_t130b); + pcem_add_hddcontroller(&h_none); + pcem_add_hddcontroller(&h_mfm_at); + pcem_add_hddcontroller(&h_dtc5150x); + pcem_add_hddcontroller(&h_mfm_xebec); + pcem_add_hddcontroller(&h_esdi_mca); + pcem_add_hddcontroller(&h_wd1007vse1); + pcem_add_hddcontroller(&h_ide); + pcem_add_hddcontroller(&h_xtide); + pcem_add_hddcontroller(&h_xtide_at); + pcem_add_hddcontroller(&h_xtide_ps1); + pcem_add_hddcontroller(&h_aha1542c); + pcem_add_hddcontroller(&h_bt545s); + pcem_add_hddcontroller(&h_ibmscsi_mca); + pcem_add_hddcontroller(&h_lcs6821n); + pcem_add_hddcontroller(&h_rt1000b); + pcem_add_hddcontroller(&h_t130b); } \ No newline at end of file diff --git a/src/hdd/hdd_esdi.c b/src/hdd/hdd_esdi.c index 84e7dc0e..1ad21c75 100644 --- a/src/hdd/hdd_esdi.c +++ b/src/hdd/hdd_esdi.c @@ -29,841 +29,856 @@ extern char ide_fn[7][512]; typedef struct esdi_t { - rom_t bios_rom; + rom_t bios_rom; - uint8_t basic_ctrl; - uint8_t status; - uint8_t irq_status; + uint8_t basic_ctrl; + uint8_t status; + uint8_t irq_status; - int irq_in_progress; - int cmd_req_in_progress; + int irq_in_progress; + int cmd_req_in_progress; - int cmd_pos; - uint16_t cmd_data[4]; - int cmd_dev; + int cmd_pos; + uint16_t cmd_data[4]; + int cmd_dev; - int status_pos, status_len; - uint16_t status_data[256]; + int status_pos, status_len; + uint16_t status_data[256]; - int data_pos; - uint16_t data[256]; + int data_pos; + uint16_t data[256]; - uint16_t sector_buffer[256][256]; + uint16_t sector_buffer[256][256]; - int sector_pos; - int sector_count; + int sector_pos; + int sector_count; - int command; - int cmd_state; + int command; + int cmd_state; - int in_reset; - pc_timer_t callback_timer; + int in_reset; + pc_timer_t callback_timer; - uint32_t rba; + uint32_t rba; - struct { - int req_in_progress; - } cmds[3]; + struct { + int req_in_progress; + } cmds[3]; - hdd_file_t hdd_file[2]; + hdd_file_t hdd_file[2]; - uint8_t pos_regs[8]; + uint8_t pos_regs[8]; } esdi_t; -#define STATUS_DMA_ENA (1 << 7) -#define STATUS_IRQ_PENDING (1 << 6) +#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_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 STATUS_CMD_IR_FULL (1 << 2) +#define STATUS_TRANSFER_REQ (1 << 1) +#define STATUS_IRQ (1 << 0) -#define CTRL_RESET (1 << 7) +#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_DEVICE_0 (0 << 5) #define IRQ_CMD_COMPLETE_SUCCESS 0x1 -#define IRQ_RESET_COMPLETE 0xa -#define IRQ_DATA_TRANSFER_READY 0xb +#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_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 0xf -#define ATTN_CMD_REQ 1 -#define ATTN_EOI 2 -#define ATTN_RESET 4 +#define ATTN_DEVICE_0 (0 << 5) +#define ATTN_DEVICE_1 (1 << 5) +#define ATTN_REQ_MASK 0xf +#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_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 CMD_GET_POS_INFO 0x0a #define STATUS_LEN(x) ((x) << 8) #define STATUS_DEVICE(x) ((x) << 5) #define STATUS_DEVICE_HOST_ADAPTER (7 << 5) static inline void esdi_set_irq(esdi_t *esdi) { - if (esdi->basic_ctrl & CTRL_IRQ_ENA) - picint(1 << 14); -} -static inline void esdi_clear_irq() { - picintc(1 << 14); + if (esdi->basic_ctrl & CTRL_IRQ_ENA) + picint(1 << 14); } +static inline void esdi_clear_irq() { picintc(1 << 14); } static uint8_t esdi_read(uint16_t port, void *p) { - esdi_t *esdi = (esdi_t *)p; - uint8_t temp = 0xff; + esdi_t *esdi = (esdi_t *)p; + uint8_t temp = 0xff; - switch (port) { - case 0x3512: /*Basic status register*/ - temp = esdi->status; - break; - case 0x3513: /*IRQ status*/ - esdi->status &= ~STATUS_IRQ; - temp = esdi->irq_status; - break; + switch (port) { + case 0x3512: /*Basic status register*/ + temp = esdi->status; + break; + case 0x3513: /*IRQ status*/ + esdi->status &= ~STATUS_IRQ; + temp = esdi->irq_status; + break; - default:fatal("esdi_read port=%04x\n", port); - } + default: + fatal("esdi_read port=%04x\n", port); + } -// pclog("esdi_read: port=%04x val=%02x %04x(%05x):%04x %02x %02x\n", port, temp,CS,cs,cpu_state.pc, BL, BH); - return temp; + // pclog("esdi_read: port=%04x val=%02x %04x(%05x):%04x %02x %02x\n", port, temp,CS,cs,cpu_state.pc, BL, BH); + return temp; } static void esdi_write(uint16_t port, uint8_t val, void *p) { - esdi_t *esdi = (esdi_t *)p; + esdi_t *esdi = (esdi_t *)p; -// pclog("esdi_write: port=%04x val=%02x %04x:%04x %02x %i\n", port, val,CS,cpu_state.pc, esdi->status, esdi->irq_in_progress); - switch (port) { - case 0x3512: /*Basic control register*/ - if ((esdi->basic_ctrl & CTRL_RESET) && !(val & CTRL_RESET)) { -// pclog("ESDI reset\n"); - esdi->in_reset = 1; - timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME * 50); - esdi->status = STATUS_BUSY; - } - esdi->basic_ctrl = val; - if (!(esdi->basic_ctrl & CTRL_IRQ_ENA)) - picintc(1 << 14); - break; - case 0x3513: /*Attention register*/ - switch (val & ATTN_DEVICE_SEL) { - case ATTN_HOST_ADAPTER: - switch (val & ATTN_REQ_MASK) { - case ATTN_CMD_REQ: - if (esdi->cmd_req_in_progress) - fatal("Try to start command on in_progress adapter\n"); - esdi->cmd_req_in_progress = 1; - esdi->cmd_dev = ATTN_HOST_ADAPTER; - esdi->status |= STATUS_BUSY; - esdi->cmd_pos = 0; - esdi->status_pos = 0; - break; + // pclog("esdi_write: port=%04x val=%02x %04x:%04x %02x %i\n", port, val,CS,cpu_state.pc, esdi->status, + // esdi->irq_in_progress); + switch (port) { + case 0x3512: /*Basic control register*/ + if ((esdi->basic_ctrl & CTRL_RESET) && !(val & CTRL_RESET)) { + // pclog("ESDI reset\n"); + esdi->in_reset = 1; + timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME * 50); + esdi->status = STATUS_BUSY; + } + esdi->basic_ctrl = val; + if (!(esdi->basic_ctrl & CTRL_IRQ_ENA)) + picintc(1 << 14); + break; + case 0x3513: /*Attention register*/ + switch (val & ATTN_DEVICE_SEL) { + case ATTN_HOST_ADAPTER: + switch (val & ATTN_REQ_MASK) { + case ATTN_CMD_REQ: + if (esdi->cmd_req_in_progress) + fatal("Try to start command on in_progress adapter\n"); + esdi->cmd_req_in_progress = 1; + esdi->cmd_dev = ATTN_HOST_ADAPTER; + esdi->status |= STATUS_BUSY; + esdi->cmd_pos = 0; + esdi->status_pos = 0; + break; - case ATTN_EOI:esdi->irq_in_progress = 0; - esdi->status &= ~STATUS_IRQ; - esdi_clear_irq(); - break; + case ATTN_EOI: + esdi->irq_in_progress = 0; + esdi->status &= ~STATUS_IRQ; + esdi_clear_irq(); + break; - case ATTN_RESET: -// pclog("ESDI reset\n"); - esdi->in_reset = 1; - timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME * 50); - esdi->status = STATUS_BUSY; - break; + case ATTN_RESET: + // pclog("ESDI reset\n"); + esdi->in_reset = 1; + timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME * 50); + esdi->status = STATUS_BUSY; + break; - default:fatal("Bad attention request %02x\n", val); - } - break; + default: + fatal("Bad attention request %02x\n", val); + } + break; - case ATTN_DEVICE_0: - switch (val & ATTN_REQ_MASK) { - case ATTN_CMD_REQ: - if (esdi->cmd_req_in_progress) - fatal("Try to start command on in_progress device0\n"); - esdi->cmd_req_in_progress = 1; - esdi->cmd_dev = ATTN_DEVICE_0; - esdi->status |= STATUS_BUSY; - esdi->cmd_pos = 0; - esdi->status_pos = 0; - break; + case ATTN_DEVICE_0: + switch (val & ATTN_REQ_MASK) { + case ATTN_CMD_REQ: + if (esdi->cmd_req_in_progress) + fatal("Try to start command on in_progress device0\n"); + esdi->cmd_req_in_progress = 1; + esdi->cmd_dev = ATTN_DEVICE_0; + esdi->status |= STATUS_BUSY; + esdi->cmd_pos = 0; + esdi->status_pos = 0; + break; - case ATTN_EOI:esdi->irq_in_progress = 0; - esdi->status &= ~STATUS_IRQ; - esdi_clear_irq(); - break; + case ATTN_EOI: + esdi->irq_in_progress = 0; + esdi->status &= ~STATUS_IRQ; + esdi_clear_irq(); + break; - default:fatal("Bad attention request %02x\n", val); - } - break; + default: + fatal("Bad attention request %02x\n", val); + } + break; - case ATTN_DEVICE_1: - switch (val & ATTN_REQ_MASK) { - case ATTN_CMD_REQ: - if (esdi->cmd_req_in_progress) - fatal("Try to start command on in_progress device0\n"); - esdi->cmd_req_in_progress = 1; - esdi->cmd_dev = ATTN_DEVICE_1; - esdi->status |= STATUS_BUSY; - esdi->cmd_pos = 0; - esdi->status_pos = 0; - break; + case ATTN_DEVICE_1: + switch (val & ATTN_REQ_MASK) { + case ATTN_CMD_REQ: + if (esdi->cmd_req_in_progress) + fatal("Try to start command on in_progress device0\n"); + esdi->cmd_req_in_progress = 1; + esdi->cmd_dev = ATTN_DEVICE_1; + esdi->status |= STATUS_BUSY; + esdi->cmd_pos = 0; + esdi->status_pos = 0; + break; - case ATTN_EOI:esdi->irq_in_progress = 0; - esdi->status &= ~STATUS_IRQ; - esdi_clear_irq(); - break; + case ATTN_EOI: + esdi->irq_in_progress = 0; + esdi->status &= ~STATUS_IRQ; + esdi_clear_irq(); + break; - default:fatal("Bad attention request %02x\n", val); - } - break; + default: + fatal("Bad attention request %02x\n", val); + } + break; - default:fatal("Attention to unknown device %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); - } + default: + fatal("esdi_write port=%04x val=%02x\n", port, val); + } } static uint16_t esdi_readw(uint16_t port, void *p) { - esdi_t *esdi = (esdi_t *)p; - uint16_t temp = 0xffff; + esdi_t *esdi = (esdi_t *)p; + uint16_t temp = 0xffff; - switch (port) { - case 0x3510: /*Status Interface Register*/ - if (esdi->status_pos >= esdi->status_len) - return 0; - temp = esdi->status_data[esdi->status_pos++]; - if (esdi->status_pos >= esdi->status_len) { - esdi->status &= ~STATUS_STATUS_OUT_FULL; - esdi->status_pos = esdi->status_len = 0; - } - break; + switch (port) { + case 0x3510: /*Status Interface Register*/ + if (esdi->status_pos >= esdi->status_len) + return 0; + temp = esdi->status_data[esdi->status_pos++]; + if (esdi->status_pos >= esdi->status_len) { + esdi->status &= ~STATUS_STATUS_OUT_FULL; + esdi->status_pos = esdi->status_len = 0; + } + break; - default:fatal("esdi_readw port=%04x\n", port); - } + default: + fatal("esdi_readw port=%04x\n", port); + } -// pclog("esdi_readw: port=%04x val=%04x\n", port, temp); - return temp; + // pclog("esdi_readw: port=%04x val=%04x\n", port, temp); + return temp; } static void esdi_writew(uint16_t port, uint16_t val, void *p) { - esdi_t *esdi = (esdi_t *)p; + esdi_t *esdi = (esdi_t *)p; -// pclog("esdi_writew: port=%04x val=%04x\n", port, val); - switch (port) { - case 0x3510: /*Command Interface Register*/ - if (esdi->cmd_pos >= 4) - fatal("CIR pos 4\n"); - esdi->cmd_data[esdi->cmd_pos++] = val; - if (((esdi->cmd_data[0] & CMD_SIZE_4) && esdi->cmd_pos == 4) || - (!(esdi->cmd_data[0] & CMD_SIZE_4) && esdi->cmd_pos == 2)) { -// pclog("Received command - %04x %04x %04x %04x\n", esdi->cmd_data[0], esdi->cmd_data[1], esdi->cmd_data[2], esdi->cmd_data[3]); + // pclog("esdi_writew: port=%04x val=%04x\n", port, val); + switch (port) { + case 0x3510: /*Command Interface Register*/ + if (esdi->cmd_pos >= 4) + fatal("CIR pos 4\n"); + esdi->cmd_data[esdi->cmd_pos++] = val; + if (((esdi->cmd_data[0] & CMD_SIZE_4) && esdi->cmd_pos == 4) || + (!(esdi->cmd_data[0] & CMD_SIZE_4) && esdi->cmd_pos == 2)) { + // pclog("Received command - %04x %04x %04x %04x\n", esdi->cmd_data[0], + // esdi->cmd_data[1], esdi->cmd_data[2], esdi->cmd_data[3]); - esdi->cmd_pos = 0; - esdi->cmd_req_in_progress = 0; - esdi->cmd_state = 0; + esdi->cmd_pos = 0; + esdi->cmd_req_in_progress = 0; + esdi->cmd_state = 0; - if ((esdi->cmd_data[0] & CMD_DEVICE_SEL) != esdi->cmd_dev) - fatal("Command device mismatch with attn\n"); - esdi->command = esdi->cmd_data[0] & CMD_MASK; - timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME); - esdi->status = STATUS_BUSY; - esdi->data_pos = 0; - } - break; + if ((esdi->cmd_data[0] & CMD_DEVICE_SEL) != esdi->cmd_dev) + fatal("Command device mismatch with attn\n"); + esdi->command = esdi->cmd_data[0] & CMD_MASK; + timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME); + esdi->status = STATUS_BUSY; + esdi->data_pos = 0; + } + break; - default:fatal("esdi_writew port=%04x val=%04x\n", port, val); - } + default: + fatal("esdi_writew port=%04x val=%04x\n", port, val); + } } static void cmd_unsupported(esdi_t *esdi) { - esdi->status_len = 9; - esdi->status_data[0] = esdi->command | STATUS_LEN(9) | esdi->cmd_dev; - esdi->status_data[1] = 0x0f03; /*Attention error, command not supported*/ - esdi->status_data[2] = 0x0002; /*Interface fault*/ - esdi->status_data[3] = 0; - esdi->status_data[4] = 0; - esdi->status_data[5] = 0; - esdi->status_data[6] = 0; - esdi->status_data[7] = 0; - esdi->status_data[8] = 0; + esdi->status_len = 9; + esdi->status_data[0] = esdi->command | STATUS_LEN(9) | esdi->cmd_dev; + esdi->status_data[1] = 0x0f03; /*Attention error, command not supported*/ + esdi->status_data[2] = 0x0002; /*Interface fault*/ + esdi->status_data[3] = 0; + esdi->status_data[4] = 0; + esdi->status_data[5] = 0; + esdi->status_data[6] = 0; + esdi->status_data[7] = 0; + esdi->status_data[8] = 0; - esdi->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; - esdi->irq_status = esdi->cmd_dev | IRQ_CMD_COMPLETE_FAILURE; - esdi->irq_in_progress = 1; - esdi_set_irq(esdi); + esdi->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; + esdi->irq_status = esdi->cmd_dev | IRQ_CMD_COMPLETE_FAILURE; + esdi->irq_in_progress = 1; + esdi_set_irq(esdi); } static void device_not_present(esdi_t *esdi) { - esdi->status_len = 9; - esdi->status_data[0] = esdi->command | STATUS_LEN(9) | esdi->cmd_dev; - esdi->status_data[1] = 0x0c11; /*Command failed, internal hardware error*/ - esdi->status_data[2] = 0x000b; /*Selection error*/ - esdi->status_data[3] = 0; - esdi->status_data[4] = 0; - esdi->status_data[5] = 0; - esdi->status_data[6] = 0; - esdi->status_data[7] = 0; - esdi->status_data[8] = 0; + esdi->status_len = 9; + esdi->status_data[0] = esdi->command | STATUS_LEN(9) | esdi->cmd_dev; + esdi->status_data[1] = 0x0c11; /*Command failed, internal hardware error*/ + esdi->status_data[2] = 0x000b; /*Selection error*/ + esdi->status_data[3] = 0; + esdi->status_data[4] = 0; + esdi->status_data[5] = 0; + esdi->status_data[6] = 0; + esdi->status_data[7] = 0; + esdi->status_data[8] = 0; - esdi->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; - esdi->irq_status = esdi->cmd_dev | IRQ_CMD_COMPLETE_FAILURE; - esdi->irq_in_progress = 1; - esdi_set_irq(esdi); + esdi->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; + esdi->irq_status = esdi->cmd_dev | IRQ_CMD_COMPLETE_FAILURE; + esdi->irq_in_progress = 1; + esdi_set_irq(esdi); } static void rba_out_of_range(esdi_t *esdi) { - esdi->status_len = 9; - esdi->status_data[0] = esdi->command | STATUS_LEN(9) | esdi->cmd_dev; - esdi->status_data[1] = 0x0e01; /*Command block error, invalid parameter*/ - esdi->status_data[2] = 0x0007; /*RBA out of range*/ - esdi->status_data[3] = 0; - esdi->status_data[4] = 0; - esdi->status_data[5] = 0; - esdi->status_data[6] = 0; - esdi->status_data[7] = 0; - esdi->status_data[8] = 0; + esdi->status_len = 9; + esdi->status_data[0] = esdi->command | STATUS_LEN(9) | esdi->cmd_dev; + esdi->status_data[1] = 0x0e01; /*Command block error, invalid parameter*/ + esdi->status_data[2] = 0x0007; /*RBA out of range*/ + esdi->status_data[3] = 0; + esdi->status_data[4] = 0; + esdi->status_data[5] = 0; + esdi->status_data[6] = 0; + esdi->status_data[7] = 0; + esdi->status_data[8] = 0; - esdi->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; - esdi->irq_status = esdi->cmd_dev | IRQ_CMD_COMPLETE_FAILURE; - esdi->irq_in_progress = 1; - esdi_set_irq(esdi); + esdi->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; + esdi->irq_status = esdi->cmd_dev | IRQ_CMD_COMPLETE_FAILURE; + esdi->irq_in_progress = 1; + esdi_set_irq(esdi); } static void complete_command_status(esdi_t *esdi) { - esdi->status_len = 7; - if (esdi->cmd_dev == ATTN_DEVICE_0) - esdi->status_data[0] = CMD_READ | STATUS_LEN(7) | STATUS_DEVICE(0); - else - esdi->status_data[0] = CMD_READ | STATUS_LEN(7) | STATUS_DEVICE(1); - esdi->status_data[1] = 0x0000; /*Error bits*/ - esdi->status_data[2] = 0x1900; /*Device status*/ - esdi->status_data[3] = 0; /*Number of blocks left to do*/ - esdi->status_data[4] = (esdi->rba - 1) & 0xffff; /*Last RBA processed*/ - esdi->status_data[5] = (esdi->rba - 1) >> 8; - esdi->status_data[6] = 0; /*Number of blocks requiring error recovery*/ + esdi->status_len = 7; + if (esdi->cmd_dev == ATTN_DEVICE_0) + esdi->status_data[0] = CMD_READ | STATUS_LEN(7) | STATUS_DEVICE(0); + else + esdi->status_data[0] = CMD_READ | STATUS_LEN(7) | STATUS_DEVICE(1); + esdi->status_data[1] = 0x0000; /*Error bits*/ + esdi->status_data[2] = 0x1900; /*Device status*/ + esdi->status_data[3] = 0; /*Number of blocks left to do*/ + esdi->status_data[4] = (esdi->rba - 1) & 0xffff; /*Last RBA processed*/ + esdi->status_data[5] = (esdi->rba - 1) >> 8; + esdi->status_data[6] = 0; /*Number of blocks requiring error recovery*/ } -#define ESDI_ADAPTER_ONLY() do \ - { \ - if (esdi->cmd_dev != ATTN_HOST_ADAPTER) \ - { \ - cmd_unsupported(esdi); \ - return; \ - } \ +#define ESDI_ADAPTER_ONLY() \ + do { \ + if (esdi->cmd_dev != ATTN_HOST_ADAPTER) { \ + cmd_unsupported(esdi); \ + return; \ + } \ } while (0) -#define ESDI_DRIVE_ONLY() do \ - { \ - if (esdi->cmd_dev != ATTN_DEVICE_0 && esdi->cmd_dev != ATTN_DEVICE_1) \ - { \ - cmd_unsupported(esdi); \ - return; \ - } \ - if (esdi->cmd_dev == ATTN_DEVICE_0) \ - hdd_file = &esdi->hdd_file[0]; \ - else \ - hdd_file = &esdi->hdd_file[1]; \ +#define ESDI_DRIVE_ONLY() \ + do { \ + if (esdi->cmd_dev != ATTN_DEVICE_0 && esdi->cmd_dev != ATTN_DEVICE_1) { \ + cmd_unsupported(esdi); \ + return; \ + } \ + if (esdi->cmd_dev == ATTN_DEVICE_0) \ + hdd_file = &esdi->hdd_file[0]; \ + else \ + hdd_file = &esdi->hdd_file[1]; \ } while (0) static void esdi_callback(void *p) { - esdi_t *esdi = (esdi_t *)p; - hdd_file_t *hdd_file; - -// pclog("esdi_callback: in_reset=%i command=%x\n", esdi->in_reset, esdi->command); - if (esdi->in_reset) { - esdi->in_reset = 0; - esdi->status = STATUS_IRQ; - esdi->irq_status = IRQ_HOST_ADAPTER | IRQ_RESET_COMPLETE; - -// pclog("esdi reset complete\n"); - return; - } - switch (esdi->command) { - case CMD_READ:ESDI_DRIVE_ONLY(); - - if (!hdd_file->f) { - device_not_present(esdi); - return; - } - - switch (esdi->cmd_state) { - case 0:esdi->rba = (esdi->cmd_data[2] | (esdi->cmd_data[3] << 16)) & 0x0fffffff; - - esdi->sector_pos = 0; - esdi->sector_count = esdi->cmd_data[1]; - - if ((esdi->rba + esdi->sector_count) >= hdd_file->sectors) { - rba_out_of_range(esdi); - return; - } - - esdi->status = STATUS_IRQ | STATUS_CMD_IN_PROGRESS | STATUS_TRANSFER_REQ; - esdi->irq_status = esdi->cmd_dev | IRQ_DATA_TRANSFER_READY; - esdi->irq_in_progress = 1; - esdi_set_irq(esdi); - - esdi->cmd_state = 1; - timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME); - esdi->data_pos = 0; - break; - - case 1: - if (!(esdi->basic_ctrl & CTRL_DMA_ENA)) { -// pclog("DMA not enabled\n"); - timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME); - return; - } - while (esdi->sector_pos < esdi->sector_count) { - if (!esdi->data_pos) { - if (esdi->rba >= hdd_file->sectors) - fatal("Read past end of drive\n"); - hdd_read_sectors(hdd_file, esdi->rba, 1, esdi->data); - readflash_set(READFLASH_HDC, esdi->cmd_dev == ATTN_DEVICE_0 ? 0 : 1); - } -// pclog("Read sector %i %i %08x\n", esdi->sector_pos, esdi->data_pos, esdi->rba*512); - while (esdi->data_pos < 256) { - int val = dma_channel_write(5, esdi->data[esdi->data_pos]); - - if (val == DMA_NODATA) { -// pclog("DMA out of data\n"); - timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME); - return; - } - - esdi->data_pos++; - } - - esdi->data_pos = 0; - esdi->sector_pos++; - esdi->rba++; - } - - esdi->status = STATUS_CMD_IN_PROGRESS; - esdi->cmd_state = 2; - timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME); - break; - - case 2: -// pclog("Read sector complete\n"); - complete_command_status(esdi); - - esdi->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; - esdi->irq_status = esdi->cmd_dev | IRQ_CMD_COMPLETE_SUCCESS; - esdi->irq_in_progress = 1; - esdi_set_irq(esdi); - break; - } - break; - - case CMD_WRITE: - case CMD_WRITE_VERIFY:ESDI_DRIVE_ONLY(); - - if (!hdd_file->f) { - device_not_present(esdi); - return; - } - - switch (esdi->cmd_state) { - case 0:esdi->rba = (esdi->cmd_data[2] | (esdi->cmd_data[3] << 16)) & 0x0fffffff; - - esdi->sector_pos = 0; - esdi->sector_count = esdi->cmd_data[1]; - - if ((esdi->rba + esdi->sector_count) >= hdd_file->sectors) { - rba_out_of_range(esdi); - return; - } - - esdi->status = STATUS_IRQ | STATUS_CMD_IN_PROGRESS | STATUS_TRANSFER_REQ; - esdi->irq_status = esdi->cmd_dev | IRQ_DATA_TRANSFER_READY; - esdi->irq_in_progress = 1; - esdi_set_irq(esdi); - - esdi->cmd_state = 1; - timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME); - esdi->data_pos = 0; - break; - - case 1: - if (!(esdi->basic_ctrl & CTRL_DMA_ENA)) { -// pclog("DMA not enabled\n"); - timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME); - return; - } - while (esdi->sector_pos < esdi->sector_count) { -// pclog("Write sector %i %08x\n", esdi->sector_pos, esdi->rba*512); - while (esdi->data_pos < 256) { - int val = dma_channel_read(5); - - if (val == DMA_NODATA) { -// pclog("DMA out of data\n"); - timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME); - return; - } - - esdi->data[esdi->data_pos++] = val & 0xffff; - } - - if (esdi->rba >= hdd_file->sectors) - fatal("Write past end of drive\n"); - hdd_write_sectors(hdd_file, esdi->rba, 1, esdi->data); - esdi->rba++; - esdi->sector_pos++; - readflash_set(READFLASH_HDC, esdi->cmd_dev == ATTN_DEVICE_0 ? 0 : 1); - - esdi->data_pos = 0; - } - - esdi->status = STATUS_CMD_IN_PROGRESS; - esdi->cmd_state = 2; - timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME); - break; - - case 2: -// pclog("Write sector complete\n"); - complete_command_status(esdi); - - esdi->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; - esdi->irq_status = esdi->cmd_dev | IRQ_CMD_COMPLETE_SUCCESS; - esdi->irq_in_progress = 1; - esdi_set_irq(esdi); - break; - } - break; - - case CMD_READ_VERIFY:ESDI_DRIVE_ONLY(); - - if (!hdd_file->f) { - device_not_present(esdi); - return; - } - - if ((esdi->rba + esdi->sector_count) >= hdd_file->sectors) { - rba_out_of_range(esdi); - return; - } - esdi->rba += esdi->sector_count; - complete_command_status(esdi); - esdi->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; - esdi->irq_status = esdi->cmd_dev | IRQ_CMD_COMPLETE_SUCCESS; - esdi->irq_in_progress = 1; - esdi_set_irq(esdi); - break; - - case CMD_SEEK:ESDI_DRIVE_ONLY(); - - if (!hdd_file->f) { - device_not_present(esdi); - return; - } - - complete_command_status(esdi); - esdi->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; - esdi->irq_status = esdi->cmd_dev | IRQ_CMD_COMPLETE_SUCCESS; - esdi->irq_in_progress = 1; - esdi_set_irq(esdi); - break; - - case CMD_GET_DEV_STATUS:ESDI_DRIVE_ONLY(); - - if (!hdd_file->f) { - device_not_present(esdi); - return; - } - - if ((esdi->status & STATUS_IRQ) || esdi->irq_in_progress) - fatal("IRQ in progress %02x %i\n", esdi->status, esdi->irq_in_progress); - - esdi->status_len = 9; - esdi->status_data[0] = CMD_GET_DEV_STATUS | STATUS_LEN(9) | STATUS_DEVICE_HOST_ADAPTER; - esdi->status_data[1] = 0x0000; /*Error bits*/ - esdi->status_data[2] = 0x1900; /*Device status*/ - esdi->status_data[3] = 0; /*ESDI Standard Status*/ - esdi->status_data[4] = 0; /*ESDI Vendor Unique Status*/ - esdi->status_data[5] = 0; - esdi->status_data[6] = 0; - esdi->status_data[7] = 0; - esdi->status_data[8] = 0; - - esdi->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; - esdi->irq_status = esdi->cmd_dev | IRQ_CMD_COMPLETE_SUCCESS; - esdi->irq_in_progress = 1; - esdi_set_irq(esdi); - break; - - case CMD_GET_DEV_CONFIG:ESDI_DRIVE_ONLY(); - - if (!hdd_file->f) { - device_not_present(esdi); - return; - } - - if ((esdi->status & STATUS_IRQ) || esdi->irq_in_progress) - fatal("IRQ in progress %02x %i\n", esdi->status, esdi->irq_in_progress); - - esdi->status_len = 6; - esdi->status_data[0] = CMD_GET_DEV_CONFIG | STATUS_LEN(6) | STATUS_DEVICE_HOST_ADAPTER; - esdi->status_data[1] = 0x10; /*Zero defect*/ - esdi->status_data[2] = hdd_file->sectors & 0xffff; - esdi->status_data[3] = hdd_file->sectors >> 16; - esdi->status_data[4] = hdd_file->tracks; - esdi->status_data[5] = hdd_file->hpc | (hdd_file->spt << 16); - -/* pclog("CMD_GET_DEV_CONFIG %i %04x %04x %04x %04x %04x %04x\n", drive->sectors, - esdi->status_data[0], esdi->status_data[1], - esdi->status_data[2], esdi->status_data[3], - esdi->status_data[4], esdi->status_data[5]);*/ - - esdi->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; - esdi->irq_status = esdi->cmd_dev | IRQ_CMD_COMPLETE_SUCCESS; - esdi->irq_in_progress = 1; - esdi_set_irq(esdi); - break; - - case CMD_GET_POS_INFO:ESDI_ADAPTER_ONLY(); - - if ((esdi->status & STATUS_IRQ) || esdi->irq_in_progress) - fatal("IRQ in progress %02x %i\n", esdi->status, esdi->irq_in_progress); - - esdi->status_len = 5; - esdi->status_data[0] = CMD_GET_POS_INFO | STATUS_LEN(5) | STATUS_DEVICE_HOST_ADAPTER; - esdi->status_data[1] = 0xffdd; /*MCA ID*/ - esdi->status_data[2] = esdi->pos_regs[3] | (esdi->pos_regs[2] << 8); - esdi->status_data[3] = 0xff; - esdi->status_data[4] = 0xff; - - esdi->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; - esdi->irq_status = IRQ_HOST_ADAPTER | IRQ_CMD_COMPLETE_SUCCESS; - esdi->irq_in_progress = 1; - esdi_set_irq(esdi); - break; - - case 0x11:ESDI_ADAPTER_ONLY(); - switch (esdi->cmd_state) { - case 0:esdi->sector_pos = 0; - esdi->sector_count = esdi->cmd_data[1]; - if (esdi->sector_count > 256) - fatal("Read sector buffer count %04x\n", esdi->cmd_data[1]); - - esdi->status = STATUS_IRQ | STATUS_CMD_IN_PROGRESS | STATUS_TRANSFER_REQ; - esdi->irq_status = IRQ_HOST_ADAPTER | IRQ_DATA_TRANSFER_READY; - esdi->irq_in_progress = 1; - esdi_set_irq(esdi); - - esdi->cmd_state = 1; - timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME); - esdi->data_pos = 0; - break; - - case 1: - if (!(esdi->basic_ctrl & CTRL_DMA_ENA)) { -// pclog("DMA not enabled\n"); - timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME); - return; - } - while (esdi->sector_pos < esdi->sector_count) { - if (!esdi->data_pos) - memcpy(esdi->data, esdi->sector_buffer[esdi->sector_pos++], 512); -// pclog("Transfer sector %i\n", esdi->sector_pos); - while (esdi->data_pos < 256) { - int val = dma_channel_write(5, esdi->data[esdi->data_pos]); - - if (val == DMA_NODATA) { -// pclog("DMA out of data\n"); - timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME); - return; - } - - esdi->data_pos++; - } - - esdi->data_pos = 0; - } - - esdi->status = STATUS_CMD_IN_PROGRESS; - esdi->cmd_state = 2; - timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME); - break; - - case 2: -// pclog("Read sector buffer complete\n"); - esdi->status = STATUS_IRQ; - esdi->irq_status = IRQ_HOST_ADAPTER | IRQ_CMD_COMPLETE_SUCCESS; - esdi->irq_in_progress = 1; - esdi_set_irq(esdi); - break; - } - break; - - case 0x10:ESDI_ADAPTER_ONLY(); - switch (esdi->cmd_state) { - case 0:esdi->sector_pos = 0; - esdi->sector_count = esdi->cmd_data[1]; - if (esdi->sector_count > 256) - fatal("Write sector buffer count %04x\n", esdi->cmd_data[1]); - - esdi->status = STATUS_IRQ | STATUS_CMD_IN_PROGRESS | STATUS_TRANSFER_REQ; - esdi->irq_status = IRQ_HOST_ADAPTER | IRQ_DATA_TRANSFER_READY; - esdi->irq_in_progress = 1; - esdi_set_irq(esdi); - - esdi->cmd_state = 1; - timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME); - esdi->data_pos = 0; - break; - - case 1: - if (!(esdi->basic_ctrl & CTRL_DMA_ENA)) { -// pclog("DMA not enabled\n"); - timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME); - return; - } - while (esdi->sector_pos < esdi->sector_count) { -// pclog("Transfer sector %i\n", esdi->sector_pos); - while (esdi->data_pos < 256) { - int val = dma_channel_read(5); - - if (val == DMA_NODATA) { - // pclog("DMA out of data\n"); - timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME); - return; - } - - esdi->data[esdi->data_pos++] = val & 0xffff;; - } - - memcpy(esdi->sector_buffer[esdi->sector_pos++], esdi->data, 512); - esdi->data_pos = 0; - } - - esdi->status = STATUS_CMD_IN_PROGRESS; - esdi->cmd_state = 2; - timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME); - break; - - case 2: -// pclog("Write sector buffer complete\n"); - esdi->status = STATUS_IRQ; - esdi->irq_status = IRQ_HOST_ADAPTER | IRQ_CMD_COMPLETE_SUCCESS; - esdi->irq_in_progress = 1; - esdi_set_irq(esdi); - break; - } - break; - - case 0x12:ESDI_ADAPTER_ONLY(); - - if ((esdi->status & STATUS_IRQ) || esdi->irq_in_progress) - fatal("IRQ in progress %02x %i\n", esdi->status, esdi->irq_in_progress); - - esdi->status_len = 2; - esdi->status_data[0] = 0x12 | STATUS_LEN(5) | STATUS_DEVICE_HOST_ADAPTER; - esdi->status_data[1] = 0; - - esdi->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; - esdi->irq_status = IRQ_HOST_ADAPTER | IRQ_CMD_COMPLETE_SUCCESS; - esdi->irq_in_progress = 1; - esdi_set_irq(esdi); - break; - - default:fatal("Bad command %02x %i\n", esdi->command, esdi->cmd_dev); - - } + esdi_t *esdi = (esdi_t *)p; + hdd_file_t *hdd_file; + + // pclog("esdi_callback: in_reset=%i command=%x\n", esdi->in_reset, esdi->command); + if (esdi->in_reset) { + esdi->in_reset = 0; + esdi->status = STATUS_IRQ; + esdi->irq_status = IRQ_HOST_ADAPTER | IRQ_RESET_COMPLETE; + + // pclog("esdi reset complete\n"); + return; + } + switch (esdi->command) { + case CMD_READ: + ESDI_DRIVE_ONLY(); + + if (!hdd_file->f) { + device_not_present(esdi); + return; + } + + switch (esdi->cmd_state) { + case 0: + esdi->rba = (esdi->cmd_data[2] | (esdi->cmd_data[3] << 16)) & 0x0fffffff; + + esdi->sector_pos = 0; + esdi->sector_count = esdi->cmd_data[1]; + + if ((esdi->rba + esdi->sector_count) >= hdd_file->sectors) { + rba_out_of_range(esdi); + return; + } + + esdi->status = STATUS_IRQ | STATUS_CMD_IN_PROGRESS | STATUS_TRANSFER_REQ; + esdi->irq_status = esdi->cmd_dev | IRQ_DATA_TRANSFER_READY; + esdi->irq_in_progress = 1; + esdi_set_irq(esdi); + + esdi->cmd_state = 1; + timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME); + esdi->data_pos = 0; + break; + + case 1: + if (!(esdi->basic_ctrl & CTRL_DMA_ENA)) { + // pclog("DMA not enabled\n"); + timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME); + return; + } + while (esdi->sector_pos < esdi->sector_count) { + if (!esdi->data_pos) { + if (esdi->rba >= hdd_file->sectors) + fatal("Read past end of drive\n"); + hdd_read_sectors(hdd_file, esdi->rba, 1, esdi->data); + readflash_set(READFLASH_HDC, esdi->cmd_dev == ATTN_DEVICE_0 ? 0 : 1); + } + // pclog("Read sector %i %i %08x\n", esdi->sector_pos, + // esdi->data_pos, esdi->rba*512); + while (esdi->data_pos < 256) { + int val = dma_channel_write(5, esdi->data[esdi->data_pos]); + + if (val == DMA_NODATA) { + // pclog("DMA out of data\n"); + timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME); + return; + } + + esdi->data_pos++; + } + + esdi->data_pos = 0; + esdi->sector_pos++; + esdi->rba++; + } + + esdi->status = STATUS_CMD_IN_PROGRESS; + esdi->cmd_state = 2; + timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME); + break; + + case 2: + // pclog("Read sector complete\n"); + complete_command_status(esdi); + + esdi->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; + esdi->irq_status = esdi->cmd_dev | IRQ_CMD_COMPLETE_SUCCESS; + esdi->irq_in_progress = 1; + esdi_set_irq(esdi); + break; + } + break; + + case CMD_WRITE: + case CMD_WRITE_VERIFY: + ESDI_DRIVE_ONLY(); + + if (!hdd_file->f) { + device_not_present(esdi); + return; + } + + switch (esdi->cmd_state) { + case 0: + esdi->rba = (esdi->cmd_data[2] | (esdi->cmd_data[3] << 16)) & 0x0fffffff; + + esdi->sector_pos = 0; + esdi->sector_count = esdi->cmd_data[1]; + + if ((esdi->rba + esdi->sector_count) >= hdd_file->sectors) { + rba_out_of_range(esdi); + return; + } + + esdi->status = STATUS_IRQ | STATUS_CMD_IN_PROGRESS | STATUS_TRANSFER_REQ; + esdi->irq_status = esdi->cmd_dev | IRQ_DATA_TRANSFER_READY; + esdi->irq_in_progress = 1; + esdi_set_irq(esdi); + + esdi->cmd_state = 1; + timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME); + esdi->data_pos = 0; + break; + + case 1: + if (!(esdi->basic_ctrl & CTRL_DMA_ENA)) { + // pclog("DMA not enabled\n"); + timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME); + return; + } + while (esdi->sector_pos < esdi->sector_count) { + // pclog("Write sector %i %08x\n", esdi->sector_pos, + // esdi->rba*512); + while (esdi->data_pos < 256) { + int val = dma_channel_read(5); + + if (val == DMA_NODATA) { + // pclog("DMA out of data\n"); + timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME); + return; + } + + esdi->data[esdi->data_pos++] = val & 0xffff; + } + + if (esdi->rba >= hdd_file->sectors) + fatal("Write past end of drive\n"); + hdd_write_sectors(hdd_file, esdi->rba, 1, esdi->data); + esdi->rba++; + esdi->sector_pos++; + readflash_set(READFLASH_HDC, esdi->cmd_dev == ATTN_DEVICE_0 ? 0 : 1); + + esdi->data_pos = 0; + } + + esdi->status = STATUS_CMD_IN_PROGRESS; + esdi->cmd_state = 2; + timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME); + break; + + case 2: + // pclog("Write sector complete\n"); + complete_command_status(esdi); + + esdi->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; + esdi->irq_status = esdi->cmd_dev | IRQ_CMD_COMPLETE_SUCCESS; + esdi->irq_in_progress = 1; + esdi_set_irq(esdi); + break; + } + break; + + case CMD_READ_VERIFY: + ESDI_DRIVE_ONLY(); + + if (!hdd_file->f) { + device_not_present(esdi); + return; + } + + if ((esdi->rba + esdi->sector_count) >= hdd_file->sectors) { + rba_out_of_range(esdi); + return; + } + esdi->rba += esdi->sector_count; + complete_command_status(esdi); + esdi->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; + esdi->irq_status = esdi->cmd_dev | IRQ_CMD_COMPLETE_SUCCESS; + esdi->irq_in_progress = 1; + esdi_set_irq(esdi); + break; + + case CMD_SEEK: + ESDI_DRIVE_ONLY(); + + if (!hdd_file->f) { + device_not_present(esdi); + return; + } + + complete_command_status(esdi); + esdi->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; + esdi->irq_status = esdi->cmd_dev | IRQ_CMD_COMPLETE_SUCCESS; + esdi->irq_in_progress = 1; + esdi_set_irq(esdi); + break; + + case CMD_GET_DEV_STATUS: + ESDI_DRIVE_ONLY(); + + if (!hdd_file->f) { + device_not_present(esdi); + return; + } + + if ((esdi->status & STATUS_IRQ) || esdi->irq_in_progress) + fatal("IRQ in progress %02x %i\n", esdi->status, esdi->irq_in_progress); + + esdi->status_len = 9; + esdi->status_data[0] = CMD_GET_DEV_STATUS | STATUS_LEN(9) | STATUS_DEVICE_HOST_ADAPTER; + esdi->status_data[1] = 0x0000; /*Error bits*/ + esdi->status_data[2] = 0x1900; /*Device status*/ + esdi->status_data[3] = 0; /*ESDI Standard Status*/ + esdi->status_data[4] = 0; /*ESDI Vendor Unique Status*/ + esdi->status_data[5] = 0; + esdi->status_data[6] = 0; + esdi->status_data[7] = 0; + esdi->status_data[8] = 0; + + esdi->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; + esdi->irq_status = esdi->cmd_dev | IRQ_CMD_COMPLETE_SUCCESS; + esdi->irq_in_progress = 1; + esdi_set_irq(esdi); + break; + + case CMD_GET_DEV_CONFIG: + ESDI_DRIVE_ONLY(); + + if (!hdd_file->f) { + device_not_present(esdi); + return; + } + + if ((esdi->status & STATUS_IRQ) || esdi->irq_in_progress) + fatal("IRQ in progress %02x %i\n", esdi->status, esdi->irq_in_progress); + + esdi->status_len = 6; + esdi->status_data[0] = CMD_GET_DEV_CONFIG | STATUS_LEN(6) | STATUS_DEVICE_HOST_ADAPTER; + esdi->status_data[1] = 0x10; /*Zero defect*/ + esdi->status_data[2] = hdd_file->sectors & 0xffff; + esdi->status_data[3] = hdd_file->sectors >> 16; + esdi->status_data[4] = hdd_file->tracks; + esdi->status_data[5] = hdd_file->hpc | (hdd_file->spt << 16); + + /* pclog("CMD_GET_DEV_CONFIG %i %04x %04x %04x %04x %04x %04x\n", drive->sectors, + esdi->status_data[0], esdi->status_data[1], + esdi->status_data[2], esdi->status_data[3], + esdi->status_data[4], esdi->status_data[5]);*/ + + esdi->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; + esdi->irq_status = esdi->cmd_dev | IRQ_CMD_COMPLETE_SUCCESS; + esdi->irq_in_progress = 1; + esdi_set_irq(esdi); + break; + + case CMD_GET_POS_INFO: + ESDI_ADAPTER_ONLY(); + + if ((esdi->status & STATUS_IRQ) || esdi->irq_in_progress) + fatal("IRQ in progress %02x %i\n", esdi->status, esdi->irq_in_progress); + + esdi->status_len = 5; + esdi->status_data[0] = CMD_GET_POS_INFO | STATUS_LEN(5) | STATUS_DEVICE_HOST_ADAPTER; + esdi->status_data[1] = 0xffdd; /*MCA ID*/ + esdi->status_data[2] = esdi->pos_regs[3] | (esdi->pos_regs[2] << 8); + esdi->status_data[3] = 0xff; + esdi->status_data[4] = 0xff; + + esdi->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; + esdi->irq_status = IRQ_HOST_ADAPTER | IRQ_CMD_COMPLETE_SUCCESS; + esdi->irq_in_progress = 1; + esdi_set_irq(esdi); + break; + + case 0x11: + ESDI_ADAPTER_ONLY(); + switch (esdi->cmd_state) { + case 0: + esdi->sector_pos = 0; + esdi->sector_count = esdi->cmd_data[1]; + if (esdi->sector_count > 256) + fatal("Read sector buffer count %04x\n", esdi->cmd_data[1]); + + esdi->status = STATUS_IRQ | STATUS_CMD_IN_PROGRESS | STATUS_TRANSFER_REQ; + esdi->irq_status = IRQ_HOST_ADAPTER | IRQ_DATA_TRANSFER_READY; + esdi->irq_in_progress = 1; + esdi_set_irq(esdi); + + esdi->cmd_state = 1; + timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME); + esdi->data_pos = 0; + break; + + case 1: + if (!(esdi->basic_ctrl & CTRL_DMA_ENA)) { + // pclog("DMA not enabled\n"); + timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME); + return; + } + while (esdi->sector_pos < esdi->sector_count) { + if (!esdi->data_pos) + memcpy(esdi->data, esdi->sector_buffer[esdi->sector_pos++], 512); + // pclog("Transfer sector %i\n", esdi->sector_pos); + while (esdi->data_pos < 256) { + int val = dma_channel_write(5, esdi->data[esdi->data_pos]); + + if (val == DMA_NODATA) { + // pclog("DMA out of data\n"); + timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME); + return; + } + + esdi->data_pos++; + } + + esdi->data_pos = 0; + } + + esdi->status = STATUS_CMD_IN_PROGRESS; + esdi->cmd_state = 2; + timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME); + break; + + case 2: + // pclog("Read sector buffer complete\n"); + esdi->status = STATUS_IRQ; + esdi->irq_status = IRQ_HOST_ADAPTER | IRQ_CMD_COMPLETE_SUCCESS; + esdi->irq_in_progress = 1; + esdi_set_irq(esdi); + break; + } + break; + + case 0x10: + ESDI_ADAPTER_ONLY(); + switch (esdi->cmd_state) { + case 0: + esdi->sector_pos = 0; + esdi->sector_count = esdi->cmd_data[1]; + if (esdi->sector_count > 256) + fatal("Write sector buffer count %04x\n", esdi->cmd_data[1]); + + esdi->status = STATUS_IRQ | STATUS_CMD_IN_PROGRESS | STATUS_TRANSFER_REQ; + esdi->irq_status = IRQ_HOST_ADAPTER | IRQ_DATA_TRANSFER_READY; + esdi->irq_in_progress = 1; + esdi_set_irq(esdi); + + esdi->cmd_state = 1; + timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME); + esdi->data_pos = 0; + break; + + case 1: + if (!(esdi->basic_ctrl & CTRL_DMA_ENA)) { + // pclog("DMA not enabled\n"); + timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME); + return; + } + while (esdi->sector_pos < esdi->sector_count) { + // pclog("Transfer sector %i\n", esdi->sector_pos); + while (esdi->data_pos < 256) { + int val = dma_channel_read(5); + + if (val == DMA_NODATA) { + // pclog("DMA out of data\n"); + timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME); + return; + } + + esdi->data[esdi->data_pos++] = val & 0xffff; + ; + } + + memcpy(esdi->sector_buffer[esdi->sector_pos++], esdi->data, 512); + esdi->data_pos = 0; + } + + esdi->status = STATUS_CMD_IN_PROGRESS; + esdi->cmd_state = 2; + timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME); + break; + + case 2: + // pclog("Write sector buffer complete\n"); + esdi->status = STATUS_IRQ; + esdi->irq_status = IRQ_HOST_ADAPTER | IRQ_CMD_COMPLETE_SUCCESS; + esdi->irq_in_progress = 1; + esdi_set_irq(esdi); + break; + } + break; + + case 0x12: + ESDI_ADAPTER_ONLY(); + + if ((esdi->status & STATUS_IRQ) || esdi->irq_in_progress) + fatal("IRQ in progress %02x %i\n", esdi->status, esdi->irq_in_progress); + + esdi->status_len = 2; + esdi->status_data[0] = 0x12 | STATUS_LEN(5) | STATUS_DEVICE_HOST_ADAPTER; + esdi->status_data[1] = 0; + + esdi->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; + esdi->irq_status = IRQ_HOST_ADAPTER | IRQ_CMD_COMPLETE_SUCCESS; + esdi->irq_in_progress = 1; + esdi_set_irq(esdi); + break; + + default: + fatal("Bad command %02x %i\n", esdi->command, esdi->cmd_dev); + } } static uint8_t esdi_mca_read(int port, void *p) { - esdi_t *esdi = (esdi_t *)p; + esdi_t *esdi = (esdi_t *)p; -// pclog("esdi_mca_read: port=%04x\n", port); + // pclog("esdi_mca_read: port=%04x\n", port); - return esdi->pos_regs[port & 7]; + return esdi->pos_regs[port & 7]; } static void esdi_mca_write(int port, uint8_t val, void *p) { - esdi_t *esdi = (esdi_t *)p; + esdi_t *esdi = (esdi_t *)p; - if (port < 0x102) - return; + if (port < 0x102) + return; -// pclog("esdi_mca_write: port=%04x val=%02x %04x:%04x\n", port, val, CS, cpu_state.pc); + // pclog("esdi_mca_write: port=%04x val=%02x %04x:%04x\n", port, val, CS, cpu_state.pc); - esdi->pos_regs[port & 7] = val; + esdi->pos_regs[port & 7] = val; - io_removehandler(0x3510, 0x0008, esdi_read, esdi_readw, NULL, esdi_write, esdi_writew, NULL, esdi); - mem_mapping_disable(&esdi->bios_rom.mapping); - if (esdi->pos_regs[2] & 1) { - io_sethandler(0x3510, 0x0008, esdi_read, esdi_readw, NULL, esdi_write, esdi_writew, NULL, esdi); - if (!(esdi->pos_regs[3] & 8)) { - mem_mapping_enable(&esdi->bios_rom.mapping); - mem_mapping_set_addr(&esdi->bios_rom.mapping, ((esdi->pos_regs[3] & 7) * 0x4000) + 0xc0000, 0x4000); -// pclog("ESDI BIOS ROM at %05x %02x\n", ((esdi->pos_regs[3] & 7) * 0x4000) + 0xc0000, esdi->pos_regs[3]); - } - } + io_removehandler(0x3510, 0x0008, esdi_read, esdi_readw, NULL, esdi_write, esdi_writew, NULL, esdi); + mem_mapping_disable(&esdi->bios_rom.mapping); + if (esdi->pos_regs[2] & 1) { + io_sethandler(0x3510, 0x0008, esdi_read, esdi_readw, NULL, esdi_write, esdi_writew, NULL, esdi); + if (!(esdi->pos_regs[3] & 8)) { + mem_mapping_enable(&esdi->bios_rom.mapping); + mem_mapping_set_addr(&esdi->bios_rom.mapping, ((esdi->pos_regs[3] & 7) * 0x4000) + 0xc0000, 0x4000); + // pclog("ESDI BIOS ROM at %05x %02x\n", ((esdi->pos_regs[3] & 7) * 0x4000) + + // 0xc0000, esdi->pos_regs[3]); + } + } } static void *esdi_init() { - esdi_t *esdi = malloc(sizeof(esdi_t)); - memset(esdi, 0, sizeof(esdi_t)); + esdi_t *esdi = malloc(sizeof(esdi_t)); + memset(esdi, 0, sizeof(esdi_t)); - rom_init_interleaved(&esdi->bios_rom, "90x8970.bin", "90x8969.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); - mem_mapping_disable(&esdi->bios_rom.mapping); + rom_init_interleaved(&esdi->bios_rom, "90x8970.bin", "90x8969.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + mem_mapping_disable(&esdi->bios_rom.mapping); - hdd_load(&esdi->hdd_file[0], 0, ide_fn[0]); - hdd_load(&esdi->hdd_file[1], 1, ide_fn[1]); + hdd_load(&esdi->hdd_file[0], 0, ide_fn[0]); + hdd_load(&esdi->hdd_file[1], 1, ide_fn[1]); - timer_add(&esdi->callback_timer, esdi_callback, esdi, 0); + timer_add(&esdi->callback_timer, esdi_callback, esdi, 0); - mca_add(esdi_mca_read, esdi_mca_write, NULL, esdi); + mca_add(esdi_mca_read, esdi_mca_write, NULL, esdi); - esdi->pos_regs[0] = 0xff; - esdi->pos_regs[1] = 0xdd; + esdi->pos_regs[0] = 0xff; + esdi->pos_regs[1] = 0xdd; - esdi->in_reset = 1; - timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME * 50); - esdi->status = STATUS_BUSY; + esdi->in_reset = 1; + timer_set_delay_u64(&esdi->callback_timer, ESDI_TIME * 50); + esdi->status = STATUS_BUSY; - return esdi; + return esdi; } static void esdi_close(void *p) { - esdi_t *esdi = (esdi_t *)p; + esdi_t *esdi = (esdi_t *)p; - hdd_close(&esdi->hdd_file[0]); - hdd_close(&esdi->hdd_file[1]); + hdd_close(&esdi->hdd_file[0]); + hdd_close(&esdi->hdd_file[1]); - free(esdi); + free(esdi); } -static int esdi_available() { - return rom_present("90x8969.bin") && rom_present("90x8970.bin"); -} +static int esdi_available() { return rom_present("90x8969.bin") && rom_present("90x8970.bin"); } -device_t hdd_esdi_device = - { - "IBM ESDI Fixed Disk Adapter (MCA)", - DEVICE_MCA, - esdi_init, - esdi_close, - esdi_available, - NULL, - NULL, - NULL, - NULL - }; +device_t hdd_esdi_device = { + "IBM ESDI Fixed Disk Adapter (MCA)", DEVICE_MCA, esdi_init, esdi_close, esdi_available, NULL, NULL, NULL, NULL}; diff --git a/src/hdd/hdd_file.c b/src/hdd/hdd_file.c index 3217aa2f..5deedae8 100644 --- a/src/hdd/hdd_file.c +++ b/src/hdd/hdd_file.c @@ -9,162 +9,156 @@ #include "minivhd/minivhd_util.h" void hdd_load_ext(hdd_file_t *hdd, const char *fn, int spt, int hpc, int tracks, int read_only) { - if (hdd->f == NULL) { - /* Try to open existing hard disk image */ - if (read_only) - hdd->f = (void *)fopen64(fn, "rb"); - else - hdd->f = (void *)fopen64(fn, "rb+"); - if (hdd->f != NULL) { - hdd->img_type = HDD_IMG_RAW; - /* Check if the file we opened is a VHD */ - if (mvhd_file_is_vhd((FILE *)hdd->f)) { - int err; - fclose((FILE *)hdd->f); - MVHDMeta *vhdm = mvhd_open(fn, (bool)read_only, &err); - if (vhdm == NULL) { - hdd->f = NULL; - if (err == MVHD_ERR_FILE) { - pclog("Cannot open VHD file '%s' : %s", - fn, strerror(mvhd_errno)); - } else { - pclog("Cannot open VHD file '%s' : %s", - fn, mvhd_strerr(err)); - } - return; - } - /*else if (err == MVHD_ERR_TIMESTAMP) - { - pclog("VHD: Parent/child timestamp mismatch"); - mvhd_close(vhdm); - hdd->f = NULL; - return; - }*/ // FIX: This is to see if this resolves Issue #59 - hdd->f = (void *)vhdm; - hdd->img_type = HDD_IMG_VHD; - } - } else { - /* Failed to open existing hard disk image */ - if (errno == ENOENT && !read_only) { - /* Failed because it does not exist, - so try to create new file */ - hdd->f = (void *)fopen64(fn, "wb+"); - if (hdd->f == NULL) { - pclog("Cannot create file '%s': %s", - fn, strerror(errno)); - return; - } - } else { - /* Failed for another reason */ - pclog("Cannot open file '%s': %s", - fn, strerror(errno)); - return; - } - hdd->img_type = HDD_IMG_RAW; - } - } - if (hdd->img_type == HDD_IMG_VHD) { - MVHDMeta *vhdm = (MVHDMeta *)hdd->f; - MVHDGeom geom = mvhd_get_geometry(vhdm); - hdd->spt = geom.spt; - hdd->hpc = geom.heads; - hdd->tracks = geom.cyl; - } else if (hdd->img_type == HDD_IMG_RAW) { - hdd->spt = spt; - hdd->hpc = hpc; - hdd->tracks = tracks; - } - hdd->sectors = hdd->spt * hdd->hpc * hdd->tracks; - hdd->read_only = read_only; + if (hdd->f == NULL) { + /* Try to open existing hard disk image */ + if (read_only) + hdd->f = (void *)fopen64(fn, "rb"); + else + hdd->f = (void *)fopen64(fn, "rb+"); + if (hdd->f != NULL) { + hdd->img_type = HDD_IMG_RAW; + /* Check if the file we opened is a VHD */ + if (mvhd_file_is_vhd((FILE *)hdd->f)) { + int err; + fclose((FILE *)hdd->f); + MVHDMeta *vhdm = mvhd_open(fn, (bool)read_only, &err); + if (vhdm == NULL) { + hdd->f = NULL; + if (err == MVHD_ERR_FILE) { + pclog("Cannot open VHD file '%s' : %s", fn, strerror(mvhd_errno)); + } else { + pclog("Cannot open VHD file '%s' : %s", fn, mvhd_strerr(err)); + } + return; + } + /*else if (err == MVHD_ERR_TIMESTAMP) + { + pclog("VHD: Parent/child timestamp mismatch"); + mvhd_close(vhdm); + hdd->f = NULL; + return; + }*/ // FIX: This is to see if this resolves Issue #59 + hdd->f = (void *)vhdm; + hdd->img_type = HDD_IMG_VHD; + } + } else { + /* Failed to open existing hard disk image */ + if (errno == ENOENT && !read_only) { + /* Failed because it does not exist, + so try to create new file */ + hdd->f = (void *)fopen64(fn, "wb+"); + if (hdd->f == NULL) { + pclog("Cannot create file '%s': %s", fn, strerror(errno)); + return; + } + } else { + /* Failed for another reason */ + pclog("Cannot open file '%s': %s", fn, strerror(errno)); + return; + } + hdd->img_type = HDD_IMG_RAW; + } + } + if (hdd->img_type == HDD_IMG_VHD) { + MVHDMeta *vhdm = (MVHDMeta *)hdd->f; + MVHDGeom geom = mvhd_get_geometry(vhdm); + hdd->spt = geom.spt; + hdd->hpc = geom.heads; + hdd->tracks = geom.cyl; + } else if (hdd->img_type == HDD_IMG_RAW) { + hdd->spt = spt; + hdd->hpc = hpc; + hdd->tracks = tracks; + } + hdd->sectors = hdd->spt * hdd->hpc * hdd->tracks; + hdd->read_only = read_only; } -void hdd_load(hdd_file_t *hdd, int d, const char *fn) { - hdd_load_ext(hdd, fn, hdc[d].spt, hdc[d].hpc, hdc[d].tracks, 0); -} +void hdd_load(hdd_file_t *hdd, int d, const char *fn) { hdd_load_ext(hdd, fn, hdc[d].spt, hdc[d].hpc, hdc[d].tracks, 0); } void hdd_close(hdd_file_t *hdd) { - if (hdd->f) { - if (hdd->img_type == HDD_IMG_VHD) - mvhd_close((MVHDMeta *)hdd->f); - else if (hdd->img_type == HDD_IMG_RAW) - fclose((FILE *)hdd->f); - } - hdd->img_type = HDD_IMG_RAW; - hdd->f = NULL; + if (hdd->f) { + if (hdd->img_type == HDD_IMG_VHD) + mvhd_close((MVHDMeta *)hdd->f); + else if (hdd->img_type == HDD_IMG_RAW) + fclose((FILE *)hdd->f); + } + hdd->img_type = HDD_IMG_RAW; + hdd->f = NULL; } int hdd_read_sectors(hdd_file_t *hdd, int offset, int nr_sectors, void *buffer) { - if (hdd->img_type == HDD_IMG_VHD) { - return mvhd_read_sectors((MVHDMeta *)hdd->f, offset, nr_sectors, buffer); - } else if (hdd->img_type == HDD_IMG_RAW) { - off64_t addr; - int transfer_sectors = nr_sectors; + if (hdd->img_type == HDD_IMG_VHD) { + return mvhd_read_sectors((MVHDMeta *)hdd->f, offset, nr_sectors, buffer); + } else if (hdd->img_type == HDD_IMG_RAW) { + off64_t addr; + int transfer_sectors = nr_sectors; - if ((hdd->sectors - offset) < transfer_sectors) - transfer_sectors = hdd->sectors - offset; - addr = (uint64_t)offset * 512; + if ((hdd->sectors - offset) < transfer_sectors) + transfer_sectors = hdd->sectors - offset; + addr = (uint64_t)offset * 512; - fseeko64((FILE *)hdd->f, addr, SEEK_SET); - fread(buffer, transfer_sectors * 512, 1, (FILE *)hdd->f); + fseeko64((FILE *)hdd->f, addr, SEEK_SET); + fread(buffer, transfer_sectors * 512, 1, (FILE *)hdd->f); - if (nr_sectors != transfer_sectors) - return 1; - return 0; - } - /* Keep the compiler happy */ - return 1; + if (nr_sectors != transfer_sectors) + return 1; + return 0; + } + /* Keep the compiler happy */ + return 1; } int hdd_write_sectors(hdd_file_t *hdd, int offset, int nr_sectors, void *buffer) { - if (hdd->img_type == HDD_IMG_VHD) { - return mvhd_write_sectors((MVHDMeta *)hdd->f, offset, nr_sectors, buffer); - } else if (hdd->img_type == HDD_IMG_RAW) { - off64_t addr; - int transfer_sectors = nr_sectors; + if (hdd->img_type == HDD_IMG_VHD) { + return mvhd_write_sectors((MVHDMeta *)hdd->f, offset, nr_sectors, buffer); + } else if (hdd->img_type == HDD_IMG_RAW) { + off64_t addr; + int transfer_sectors = nr_sectors; - if (hdd->read_only) - return 1; + if (hdd->read_only) + return 1; - if ((hdd->sectors - offset) < transfer_sectors) - transfer_sectors = hdd->sectors - offset; - addr = (uint64_t)offset * 512; + if ((hdd->sectors - offset) < transfer_sectors) + transfer_sectors = hdd->sectors - offset; + addr = (uint64_t)offset * 512; - fseeko64((FILE *)hdd->f, addr, SEEK_SET); - fwrite(buffer, transfer_sectors * 512, 1, (FILE *)hdd->f); + fseeko64((FILE *)hdd->f, addr, SEEK_SET); + fwrite(buffer, transfer_sectors * 512, 1, (FILE *)hdd->f); - if (nr_sectors != transfer_sectors) - return 1; - return 0; - } - /* Keep the compiler happy */ - return 1; + if (nr_sectors != transfer_sectors) + return 1; + return 0; + } + /* Keep the compiler happy */ + return 1; } int hdd_format_sectors(hdd_file_t *hdd, int offset, int nr_sectors) { - if (hdd->img_type == HDD_IMG_VHD) { - return mvhd_format_sectors((MVHDMeta *)hdd->f, offset, nr_sectors); - } else if (hdd->img_type == HDD_IMG_RAW) { - off64_t addr; - int c; - uint8_t zero_buffer[512]; - int transfer_sectors = nr_sectors; + if (hdd->img_type == HDD_IMG_VHD) { + return mvhd_format_sectors((MVHDMeta *)hdd->f, offset, nr_sectors); + } else if (hdd->img_type == HDD_IMG_RAW) { + off64_t addr; + int c; + uint8_t zero_buffer[512]; + int transfer_sectors = nr_sectors; - if (hdd->read_only) - return 1; + if (hdd->read_only) + return 1; - memset(zero_buffer, 0, 512); + memset(zero_buffer, 0, 512); - if ((hdd->sectors - offset) < transfer_sectors) - transfer_sectors = hdd->sectors - offset; - addr = (uint64_t)offset * 512; - fseeko64((FILE *)hdd->f, addr, SEEK_SET); - for (c = 0; c < transfer_sectors; c++) - fwrite(zero_buffer, 512, 1, (FILE *)hdd->f); + if ((hdd->sectors - offset) < transfer_sectors) + transfer_sectors = hdd->sectors - offset; + addr = (uint64_t)offset * 512; + fseeko64((FILE *)hdd->f, addr, SEEK_SET); + for (c = 0; c < transfer_sectors; c++) + fwrite(zero_buffer, 512, 1, (FILE *)hdd->f); - if (nr_sectors != transfer_sectors) - return 1; - return 0; - } - /* Keep the compiler happy */ - return 1; + if (nr_sectors != transfer_sectors) + return 1; + return 0; + } + /* Keep the compiler happy */ + return 1; } diff --git a/src/hdd/minivhd/cwalk.c b/src/hdd/minivhd/cwalk.c index eb05a3ed..e64350eb 100644 --- a/src/hdd/minivhd/cwalk.c +++ b/src/hdd/minivhd/cwalk.c @@ -11,8 +11,7 @@ * We try to default to a different path style depending on the operating * system. So this should detect whether we should use windows or unix paths. */ -#if defined(WIN32) || defined(_WIN32) || \ - defined(__WIN32) && !defined(__CYGWIN__) +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__) static enum cwk_path_style path_style = CWK_STYLE_WINDOWS; #else static enum cwk_path_style path_style = CWK_STYLE_UNIX; @@ -23,8 +22,7 @@ static enum cwk_path_style path_style = CWK_STYLE_UNIX; * multiple separators, but it generally outputs just a backslash. The output * will always use the first character for the output. */ -static const char *separators[] = {[CWK_STYLE_WINDOWS] = "\\/", - [CWK_STYLE_UNIX] = "/"}; +static const char *separators[] = {[CWK_STYLE_WINDOWS] = "\\/", [CWK_STYLE_UNIX] = "/"}; /** * A joined path represents multiple path strings which are concatenated, but @@ -32,1342 +30,1295 @@ static const char *separators[] = {[CWK_STYLE_WINDOWS] = "\\/", * iterate over the segments as if it was one piece of path. */ struct cwk_segment_joined { - struct cwk_segment segment; - const char **paths; - size_t path_index; + struct cwk_segment segment; + const char **paths; + size_t path_index; }; -static size_t cwk_path_output_sized(char *buffer, size_t buffer_size, - size_t position, const char *str, size_t length) { - size_t amount_written; +static size_t cwk_path_output_sized(char *buffer, size_t buffer_size, size_t position, const char *str, size_t length) { + size_t amount_written; - // First we determine the amount which we can write to the buffer. There are - // three cases. In the first case we have enough to store the whole string in - // it. In the second one we can only store a part of it, and in the third we - // have no space left. - if (buffer_size > position + length) { - amount_written = length; - } else if (buffer_size > position) { - amount_written = buffer_size - position; - } else { - amount_written = 0; - } + // First we determine the amount which we can write to the buffer. There are + // three cases. In the first case we have enough to store the whole string in + // it. In the second one we can only store a part of it, and in the third we + // have no space left. + if (buffer_size > position + length) { + amount_written = length; + } else if (buffer_size > position) { + amount_written = buffer_size - position; + } else { + amount_written = 0; + } - // If we actually want to write out something we will do that here. We will - // always append a '\0', this way we are guaranteed to have a valid string at - // all times. - if (amount_written > 0) { - memmove(&buffer[position], str, amount_written); - } + // If we actually want to write out something we will do that here. We will + // always append a '\0', this way we are guaranteed to have a valid string at + // all times. + if (amount_written > 0) { + memmove(&buffer[position], str, amount_written); + } - // Return the theoretical length which would have been written when everything - // would have fit in the buffer. - return length; + // Return the theoretical length which would have been written when everything + // would have fit in the buffer. + return length; } -static size_t cwk_path_output_current(char *buffer, size_t buffer_size, - size_t position) { - // We output a "current" directory, which is a single character. This - // character is currently not style dependant. - return cwk_path_output_sized(buffer, buffer_size, position, ".", 1); +static size_t cwk_path_output_current(char *buffer, size_t buffer_size, size_t position) { + // We output a "current" directory, which is a single character. This + // character is currently not style dependant. + return cwk_path_output_sized(buffer, buffer_size, position, ".", 1); } -static size_t cwk_path_output_back(char *buffer, size_t buffer_size, - size_t position) { - // We output a "back" directory, which ahs two characters. This - // character is currently not style dependant. - return cwk_path_output_sized(buffer, buffer_size, position, "..", 2); +static size_t cwk_path_output_back(char *buffer, size_t buffer_size, size_t position) { + // We output a "back" directory, which ahs two characters. This + // character is currently not style dependant. + return cwk_path_output_sized(buffer, buffer_size, position, "..", 2); } -static size_t cwk_path_output_separator(char *buffer, size_t buffer_size, - size_t position) { - // We output a separator, which is a single character. - return cwk_path_output_sized(buffer, buffer_size, position, - separators[path_style], 1); +static size_t cwk_path_output_separator(char *buffer, size_t buffer_size, size_t position) { + // We output a separator, which is a single character. + return cwk_path_output_sized(buffer, buffer_size, position, separators[path_style], 1); } -static size_t cwk_path_output_dot(char *buffer, size_t buffer_size, - size_t position) { - // We output a dot, which is a single character. This is used for extensions. - return cwk_path_output_sized(buffer, buffer_size, position, ".", 1); +static size_t cwk_path_output_dot(char *buffer, size_t buffer_size, size_t position) { + // We output a dot, which is a single character. This is used for extensions. + return cwk_path_output_sized(buffer, buffer_size, position, ".", 1); } -static size_t cwk_path_output(char *buffer, size_t buffer_size, size_t position, - const char *str) { - size_t length; +static size_t cwk_path_output(char *buffer, size_t buffer_size, size_t position, const char *str) { + size_t length; - // This just does a sized output internally, but first measuring the - // null-terminated string. - length = strlen(str); - return cwk_path_output_sized(buffer, buffer_size, position, str, length); + // This just does a sized output internally, but first measuring the + // null-terminated string. + length = strlen(str); + return cwk_path_output_sized(buffer, buffer_size, position, str, length); } -static void cwk_path_terminate_output(char *buffer, size_t buffer_size, - size_t pos) { - if (buffer_size > 0) { - if (pos >= buffer_size) { - buffer[buffer_size - 1] = '\0'; - } else { - buffer[pos] = '\0'; - } - } +static void cwk_path_terminate_output(char *buffer, size_t buffer_size, size_t pos) { + if (buffer_size > 0) { + if (pos >= buffer_size) { + buffer[buffer_size - 1] = '\0'; + } else { + buffer[pos] = '\0'; + } + } } -static bool cwk_path_is_string_equal(const char *first, const char *second, - size_t n) { - // If the path style is UNIX, we will compare case sensitively. This can be - // done easily using strncmp. - if (path_style == CWK_STYLE_UNIX) { - return strncmp(first, second, n) == 0; - } +static bool cwk_path_is_string_equal(const char *first, const char *second, size_t n) { + // If the path style is UNIX, we will compare case sensitively. This can be + // done easily using strncmp. + if (path_style == CWK_STYLE_UNIX) { + return strncmp(first, second, n) == 0; + } - // However, if this is windows we will have to compare case insensitively. - // Since there is no standard method to do that we will have to do it on our - // own. - while (*first && *second && n > 0) { - // We can consider the string to be not equal if the two lowercase - // characters are not equal. - if (tolower(*first++) != tolower(*second++)) { - return false; - } + // However, if this is windows we will have to compare case insensitively. + // Since there is no standard method to do that we will have to do it on our + // own. + while (*first && *second && n > 0) { + // We can consider the string to be not equal if the two lowercase + // characters are not equal. + if (tolower(*first++) != tolower(*second++)) { + return false; + } - --n; - } + --n; + } - // We can consider the string to be equal if we either reached n == 0 or both - // cursors point to a null character. - return n == 0 || (*first == '\0' && *second == '\0'); + // We can consider the string to be equal if we either reached n == 0 or both + // cursors point to a null character. + return n == 0 || (*first == '\0' && *second == '\0'); } static const char *cwk_path_find_next_stop(const char *c) { - // We just move forward until we find a '\0' or a separator, which will be our - // next "stop". - while (*c != '\0' && !cwk_path_is_separator(c)) { - ++c; - } + // We just move forward until we find a '\0' or a separator, which will be our + // next "stop". + while (*c != '\0' && !cwk_path_is_separator(c)) { + ++c; + } - // Return the pointer of the next stop. - return c; + // Return the pointer of the next stop. + return c; } static const char *cwk_path_find_previous_stop(const char *begin, const char *c) { - // We just move back until we find a separator or reach the beginning of the - // path, which will be our previous "stop". - while (c > begin && !cwk_path_is_separator(c)) { - --c; - } + // We just move back until we find a separator or reach the beginning of the + // path, which will be our previous "stop". + while (c > begin && !cwk_path_is_separator(c)) { + --c; + } - // Return the pointer to the previous stop. We have to return the first - // character after the separator, not on the separator itself. - if (cwk_path_is_separator(c)) { - return c + 1; - } else { - return c; - } + // Return the pointer to the previous stop. We have to return the first + // character after the separator, not on the separator itself. + if (cwk_path_is_separator(c)) { + return c + 1; + } else { + return c; + } } -static bool cwk_path_get_first_segment_without_root(const char *path, - const char *segments, struct cwk_segment *segment) { - // Let's remember the path. We will move the path pointer afterwards, that's - // why this has to be done first. - segment->path = path; - segment->segments = segments; +static bool cwk_path_get_first_segment_without_root(const char *path, const char *segments, struct cwk_segment *segment) { + // Let's remember the path. We will move the path pointer afterwards, that's + // why this has to be done first. + segment->path = path; + segment->segments = segments; - // Now let's check whether this is an empty string. An empty string has no - // segment it could use. - if (*segments == '\0') { - return false; - } + // Now let's check whether this is an empty string. An empty string has no + // segment it could use. + if (*segments == '\0') { + return false; + } - // If the string starts with separators, we will jump over those. If there is - // only a slash and a '\0' after it, we can't determine the first segment - // since there is none. - while (cwk_path_is_separator(segments)) { - ++segments; - if (*segments == '\0') { - return false; - } - } + // If the string starts with separators, we will jump over those. If there is + // only a slash and a '\0' after it, we can't determine the first segment + // since there is none. + while (cwk_path_is_separator(segments)) { + ++segments; + if (*segments == '\0') { + return false; + } + } - // So this is the beginning of our segment. - segment->begin = segments; + // So this is the beginning of our segment. + segment->begin = segments; - // Now let's determine the end of the segment, which we do by moving the path - // pointer further until we find a separator. - segments = cwk_path_find_next_stop(segments); + // Now let's determine the end of the segment, which we do by moving the path + // pointer further until we find a separator. + segments = cwk_path_find_next_stop(segments); - // And finally, calculate the size of the segment by subtracting the position - // from the end. - segment->size = segments - segment->begin; - segment->end = segments; + // And finally, calculate the size of the segment by subtracting the position + // from the end. + segment->size = segments - segment->begin; + segment->end = segments; - // Tell the caller that we found a segment. - return true; + // Tell the caller that we found a segment. + return true; } -static bool cwk_path_get_last_segment_without_root(const char *path, - struct cwk_segment *segment) { - // Now this is fairly similar to the normal algorithm, however, it will assume - // that there is no root in the path. So we grab the first segment at this - // position, assuming there is no root. - if (!cwk_path_get_first_segment_without_root(path, path, segment)) { - return false; - } +static bool cwk_path_get_last_segment_without_root(const char *path, struct cwk_segment *segment) { + // Now this is fairly similar to the normal algorithm, however, it will assume + // that there is no root in the path. So we grab the first segment at this + // position, assuming there is no root. + if (!cwk_path_get_first_segment_without_root(path, path, segment)) { + return false; + } - // Now we find our last segment. The segment struct of the caller - // will contain the last segment, since the function we call here will not - // change the segment struct when it reaches the end. - while (cwk_path_get_next_segment(segment)) { - // We just loop until there is no other segment left. - } + // Now we find our last segment. The segment struct of the caller + // will contain the last segment, since the function we call here will not + // change the segment struct when it reaches the end. + while (cwk_path_get_next_segment(segment)) { + // We just loop until there is no other segment left. + } - return true; + return true; } -static bool cwk_path_get_first_segment_joined(const char **paths, - struct cwk_segment_joined *sj) { - bool result; +static bool cwk_path_get_first_segment_joined(const char **paths, struct cwk_segment_joined *sj) { + bool result; - // Prepare the first segment. We position the joined segment on the first path - // and assign the path array to the struct. - sj->path_index = 0; - sj->paths = paths; + // Prepare the first segment. We position the joined segment on the first path + // and assign the path array to the struct. + sj->path_index = 0; + sj->paths = paths; - // We loop through all paths until we find one which has a segment. The result - // is stored in a variable, so we can let the caller know whether we found one - // or not. - result = false; - while (paths[sj->path_index] != NULL && - (result = cwk_path_get_first_segment(paths[sj->path_index], - &sj->segment)) == false) { - ++sj->path_index; - } + // We loop through all paths until we find one which has a segment. The result + // is stored in a variable, so we can let the caller know whether we found one + // or not. + result = false; + while (paths[sj->path_index] != NULL && + (result = cwk_path_get_first_segment(paths[sj->path_index], &sj->segment)) == false) { + ++sj->path_index; + } - return result; + return result; } static bool cwk_path_get_next_segment_joined(struct cwk_segment_joined *sj) { - bool result; + bool result; - if (sj->paths[sj->path_index] == NULL) { - // We reached already the end of all paths, so there is no other segment - // left. - return false; - } else if (cwk_path_get_next_segment(&sj->segment)) { - // There was another segment on the current path, so we are good to - // continue. - return true; - } + if (sj->paths[sj->path_index] == NULL) { + // We reached already the end of all paths, so there is no other segment + // left. + return false; + } else if (cwk_path_get_next_segment(&sj->segment)) { + // There was another segment on the current path, so we are good to + // continue. + return true; + } - // We try to move to the next path which has a segment available. We must at - // least move one further since the current path reached the end. - result = false; + // We try to move to the next path which has a segment available. We must at + // least move one further since the current path reached the end. + result = false; - do { - ++sj->path_index; + do { + ++sj->path_index; - // And we obviously have to stop this loop if there are no more paths left. - if (sj->paths[sj->path_index] == NULL) { - break; - } + // And we obviously have to stop this loop if there are no more paths left. + if (sj->paths[sj->path_index] == NULL) { + break; + } - // Grab the first segment of the next path and determine whether this path - // has anything useful in it. There is one more thing we have to consider - // here - for the first time we do this we want to skip the root, but - // afterwards we will consider that to be part of the segments. - result = cwk_path_get_first_segment_without_root(sj->paths[sj->path_index], - sj->paths[sj->path_index], &sj->segment); + // Grab the first segment of the next path and determine whether this path + // has anything useful in it. There is one more thing we have to consider + // here - for the first time we do this we want to skip the root, but + // afterwards we will consider that to be part of the segments. + result = cwk_path_get_first_segment_without_root(sj->paths[sj->path_index], sj->paths[sj->path_index], + &sj->segment); - } while (!result); + } while (!result); - // Finally, report the result back to the caller. - return result; + // Finally, report the result back to the caller. + return result; } static bool cwk_path_get_previous_segment_joined(struct cwk_segment_joined *sj) { - bool result; + bool result; - if (*sj->paths == NULL) { - // It's possible that there is no initialized segment available in the - // struct since there are no paths. In that case we can return false, since - // there is no previous segment. - return false; - } else if (cwk_path_get_previous_segment(&sj->segment)) { - // Now we try to get the previous segment from the current path. If we can - // do that successfully, we can let the caller know that we found one. - return true; - } + if (*sj->paths == NULL) { + // It's possible that there is no initialized segment available in the + // struct since there are no paths. In that case we can return false, since + // there is no previous segment. + return false; + } else if (cwk_path_get_previous_segment(&sj->segment)) { + // Now we try to get the previous segment from the current path. If we can + // do that successfully, we can let the caller know that we found one. + return true; + } - result = false; + result = false; - do { - // We are done once we reached index 0. In that case there are no more - // segments left. - if (sj->path_index == 0) { - break; - } + do { + // We are done once we reached index 0. In that case there are no more + // segments left. + if (sj->path_index == 0) { + break; + } - // There is another path which we have to inspect. So we decrease the path - // index. - --sj->path_index; + // There is another path which we have to inspect. So we decrease the path + // index. + --sj->path_index; - // If this is the first path we will have to consider that this path might - // include a root, otherwise we just treat is as a segment. - if (sj->path_index == 0) { - result = cwk_path_get_last_segment(sj->paths[sj->path_index], - &sj->segment); - } else { - result = cwk_path_get_last_segment_without_root(sj->paths[sj->path_index], - &sj->segment); - } + // If this is the first path we will have to consider that this path might + // include a root, otherwise we just treat is as a segment. + if (sj->path_index == 0) { + result = cwk_path_get_last_segment(sj->paths[sj->path_index], &sj->segment); + } else { + result = cwk_path_get_last_segment_without_root(sj->paths[sj->path_index], &sj->segment); + } - } while (!result); + } while (!result); - return result; + return result; } static bool cwk_path_segment_back_will_be_removed(struct cwk_segment_joined *sj) { - enum cwk_segment_type type; - int counter; + enum cwk_segment_type type; + int counter; - // We are handling back segments here. We must verify how many back segments - // and how many normal segments come before this one to decide whether we keep - // or remove it. + // We are handling back segments here. We must verify how many back segments + // and how many normal segments come before this one to decide whether we keep + // or remove it. - // The counter determines how many normal segments are our current segment, - // which will popped off before us. If the counter goes above zero it means - // that our segment will be popped as well. - counter = 0; + // The counter determines how many normal segments are our current segment, + // which will popped off before us. If the counter goes above zero it means + // that our segment will be popped as well. + counter = 0; - // We loop over all previous segments until we either reach the beginning, - // which means our segment will not be dropped or the counter goes above zero. - while (cwk_path_get_previous_segment_joined(sj)) { + // We loop over all previous segments until we either reach the beginning, + // which means our segment will not be dropped or the counter goes above zero. + while (cwk_path_get_previous_segment_joined(sj)) { - // Now grab the type. The type determines whether we will increase or - // decrease the counter. We don't handle a CWK_CURRENT frame here since it - // has no influence. - type = cwk_path_get_segment_type(&sj->segment); - if (type == CWK_NORMAL) { - // This is a normal segment. The normal segment will increase the counter - // since it neutralizes one back segment. If we go above zero we can - // return immediately. - ++counter; - if (counter > 0) { - return true; - } - } else if (type == CWK_BACK) { - // A CWK_BACK segment will reduce the counter by one. We can not remove a - // back segment as long we are not above zero since we don't have the - // opposite normal segment which we would remove. - --counter; - } - } + // Now grab the type. The type determines whether we will increase or + // decrease the counter. We don't handle a CWK_CURRENT frame here since it + // has no influence. + type = cwk_path_get_segment_type(&sj->segment); + if (type == CWK_NORMAL) { + // This is a normal segment. The normal segment will increase the counter + // since it neutralizes one back segment. If we go above zero we can + // return immediately. + ++counter; + if (counter > 0) { + return true; + } + } else if (type == CWK_BACK) { + // A CWK_BACK segment will reduce the counter by one. We can not remove a + // back segment as long we are not above zero since we don't have the + // opposite normal segment which we would remove. + --counter; + } + } - // We never got a count larger than zero, so we will keep this segment alive. - return false; + // We never got a count larger than zero, so we will keep this segment alive. + return false; } -static bool cwk_path_segment_normal_will_be_removed( - struct cwk_segment_joined *sj) { - enum cwk_segment_type type; - int counter; +static bool cwk_path_segment_normal_will_be_removed(struct cwk_segment_joined *sj) { + enum cwk_segment_type type; + int counter; - // The counter determines how many segments are above our current segment, - // which will popped off before us. If the counter goes below zero it means - // that our segment will be popped as well. - counter = 0; + // The counter determines how many segments are above our current segment, + // which will popped off before us. If the counter goes below zero it means + // that our segment will be popped as well. + counter = 0; - // We loop over all following segments until we either reach the end, which - // means our segment will not be dropped or the counter goes below zero. - while (cwk_path_get_next_segment_joined(sj)) { + // We loop over all following segments until we either reach the end, which + // means our segment will not be dropped or the counter goes below zero. + while (cwk_path_get_next_segment_joined(sj)) { - // First, grab the type. The type determines whether we will increase or - // decrease the counter. We don't handle a CWK_CURRENT frame here since it - // has no influence. - type = cwk_path_get_segment_type(&sj->segment); - if (type == CWK_NORMAL) { - // This is a normal segment. The normal segment will increase the counter - // since it will be removed by a "../" before us. - ++counter; - } else if (type == CWK_BACK) { - // A CWK_BACK segment will reduce the counter by one. If we are below zero - // we can return immediately. - --counter; - if (counter < 0) { - return true; - } - } - } + // First, grab the type. The type determines whether we will increase or + // decrease the counter. We don't handle a CWK_CURRENT frame here since it + // has no influence. + type = cwk_path_get_segment_type(&sj->segment); + if (type == CWK_NORMAL) { + // This is a normal segment. The normal segment will increase the counter + // since it will be removed by a "../" before us. + ++counter; + } else if (type == CWK_BACK) { + // A CWK_BACK segment will reduce the counter by one. If we are below zero + // we can return immediately. + --counter; + if (counter < 0) { + return true; + } + } + } - // We never got a negative count, so we will keep this segment alive. - return false; + // We never got a negative count, so we will keep this segment alive. + return false; } -static bool -cwk_path_segment_will_be_removed(const struct cwk_segment_joined *sj, - bool absolute) { - enum cwk_segment_type type; - struct cwk_segment_joined sjc; +static bool cwk_path_segment_will_be_removed(const struct cwk_segment_joined *sj, bool absolute) { + enum cwk_segment_type type; + struct cwk_segment_joined sjc; - // We copy the joined path so we don't need to modify it. - sjc = *sj; + // We copy the joined path so we don't need to modify it. + sjc = *sj; - // First we check whether this is a CWK_CURRENT or CWK_BACK segment, since - // those will always be dropped. - type = cwk_path_get_segment_type(&sj->segment); - if (type == CWK_CURRENT) { - return true; - } else if (type == CWK_BACK && absolute) { - return true; - } else if (type == CWK_BACK) { - return cwk_path_segment_back_will_be_removed(&sjc); - } else { - return cwk_path_segment_normal_will_be_removed(&sjc); - } + // First we check whether this is a CWK_CURRENT or CWK_BACK segment, since + // those will always be dropped. + type = cwk_path_get_segment_type(&sj->segment); + if (type == CWK_CURRENT) { + return true; + } else if (type == CWK_BACK && absolute) { + return true; + } else if (type == CWK_BACK) { + return cwk_path_segment_back_will_be_removed(&sjc); + } else { + return cwk_path_segment_normal_will_be_removed(&sjc); + } } -static bool -cwk_path_segment_joined_skip_invisible(struct cwk_segment_joined *sj, - bool absolute) { - while (cwk_path_segment_will_be_removed(sj, absolute)) { - if (!cwk_path_get_next_segment_joined(sj)) { - return false; - } - } +static bool cwk_path_segment_joined_skip_invisible(struct cwk_segment_joined *sj, bool absolute) { + while (cwk_path_segment_will_be_removed(sj, absolute)) { + if (!cwk_path_get_next_segment_joined(sj)) { + return false; + } + } - return true; + return true; } static void cwk_path_get_root_windows(const char *path, size_t *length) { - const char *c; - bool is_device_path; + const char *c; + bool is_device_path; - // A device path is a path which starts with "\\." or "\\?". A device path can - // be a UNC path as well, in which case it will take up one more segment. - is_device_path = false; + // A device path is a path which starts with "\\." or "\\?". A device path can + // be a UNC path as well, in which case it will take up one more segment. + is_device_path = false; - // We can not determine the root if this is an empty string. So we set the - // root to NULL and the length to zero and cancel the whole thing. - c = path; - *length = 0; - if (!*c) { - return; - } + // We can not determine the root if this is an empty string. So we set the + // root to NULL and the length to zero and cancel the whole thing. + c = path; + *length = 0; + if (!*c) { + return; + } - // Now we have to verify whether this is a windows network path (UNC), which - // we will consider our root. - if (cwk_path_is_separator(c)) { - ++c; + // Now we have to verify whether this is a windows network path (UNC), which + // we will consider our root. + if (cwk_path_is_separator(c)) { + ++c; - // Check whether the path starts with a single back slash, which means this - // is not a network path - just a normal path starting with a backslash. - if (!cwk_path_is_separator(c)) { - // Okay, this is not a network path but we still use the backslash as a - // root. - ++(*length); - return; - } + // Check whether the path starts with a single back slash, which means this + // is not a network path - just a normal path starting with a backslash. + if (!cwk_path_is_separator(c)) { + // Okay, this is not a network path but we still use the backslash as a + // root. + ++(*length); + return; + } - // Yes, this is a network or device path. Skip the previous separator. Now - // we need to determine whether this is a device path. We might advance one - // character here if the server name starts with a '?' or a '.', but that's - // fine since we will search for a separator afterwards anyway. - ++c; - is_device_path = (*c == '?' || *c == '.') && cwk_path_is_separator(++c); - if (is_device_path) { - // That's a device path, and the root must be either "\\.\" or "\\?\" - // which is 4 characters long. (at least that's how Windows - // GetFullPathName behaves.) - *length = 4; - return; - } + // Yes, this is a network or device path. Skip the previous separator. Now + // we need to determine whether this is a device path. We might advance one + // character here if the server name starts with a '?' or a '.', but that's + // fine since we will search for a separator afterwards anyway. + ++c; + is_device_path = (*c == '?' || *c == '.') && cwk_path_is_separator(++c); + if (is_device_path) { + // That's a device path, and the root must be either "\\.\" or "\\?\" + // which is 4 characters long. (at least that's how Windows + // GetFullPathName behaves.) + *length = 4; + return; + } - // We will grab anything up to the next stop. The next top might be a '\0' - // or another separator. That will be the server name. - c = cwk_path_find_next_stop(c); + // We will grab anything up to the next stop. The next top might be a '\0' + // or another separator. That will be the server name. + c = cwk_path_find_next_stop(c); - // If this is a separator and not the end of a string we wil have to include - // it. However, if this is a '\0' we must not skip it. - while (cwk_path_is_separator(c)) { - ++c; - } + // If this is a separator and not the end of a string we wil have to include + // it. However, if this is a '\0' we must not skip it. + while (cwk_path_is_separator(c)) { + ++c; + } - // We are now skipping the shared folder name, which will end after the - // next stop. - c = cwk_path_find_next_stop(c); + // We are now skipping the shared folder name, which will end after the + // next stop. + c = cwk_path_find_next_stop(c); - // Then there might be a separator at the end. We will include that as well, - // it will mark the path as absolute. - if (cwk_path_is_separator(c)) { - ++c; - } + // Then there might be a separator at the end. We will include that as well, + // it will mark the path as absolute. + if (cwk_path_is_separator(c)) { + ++c; + } - // Finally, calculate the size of the root. - *length = c - path; - return; - } + // Finally, calculate the size of the root. + *length = c - path; + return; + } - // Move to the next and check whether this is a colon. - if (*++c == ':') { - *length = 2; + // Move to the next and check whether this is a colon. + if (*++c == ':') { + *length = 2; - // Now check whether this is a backslash (or slash). If it is not, we could - // assume that the next character is a '\0' if it is a valid path. However, - // we will not assume that - since ':' is not valid in a path it must be a - // mistake by the caller than. We will try to understand it anyway. - if (cwk_path_is_separator(++c)) { - *length = 3; - } - } + // Now check whether this is a backslash (or slash). If it is not, we could + // assume that the next character is a '\0' if it is a valid path. However, + // we will not assume that - since ':' is not valid in a path it must be a + // mistake by the caller than. We will try to understand it anyway. + if (cwk_path_is_separator(++c)) { + *length = 3; + } + } } static void cwk_path_get_root_unix(const char *path, size_t *length) { - // The slash of the unix path represents the root. There is no root if there - // is no slash. - if (cwk_path_is_separator(path)) { - *length = 1; - } else { - *length = 0; - } + // The slash of the unix path represents the root. There is no root if there + // is no slash. + if (cwk_path_is_separator(path)) { + *length = 1; + } else { + *length = 0; + } } static bool cwk_path_is_root_absolute(const char *path, size_t length) { - // This is definitely not absolute if there is no root. - if (length == 0) { - return false; - } + // This is definitely not absolute if there is no root. + if (length == 0) { + return false; + } - // If there is a separator at the end of the root, we can safely consider this - // to be an absolute path. - return cwk_path_is_separator(&path[length - 1]); + // If there is a separator at the end of the root, we can safely consider this + // to be an absolute path. + return cwk_path_is_separator(&path[length - 1]); } -static size_t cwk_path_join_and_normalize_multiple(const char **paths, - char *buffer, size_t buffer_size) { - size_t pos; - bool absolute, has_segment_output; - struct cwk_segment_joined sj; +static size_t cwk_path_join_and_normalize_multiple(const char **paths, char *buffer, size_t buffer_size) { + size_t pos; + bool absolute, has_segment_output; + struct cwk_segment_joined sj; - // We initialize the position after the root, which should get us started. - cwk_path_get_root(paths[0], &pos); + // We initialize the position after the root, which should get us started. + cwk_path_get_root(paths[0], &pos); - // Determine whether the path is absolute or not. We need that to determine - // later on whether we can remove superfluous "../" or not. - absolute = cwk_path_is_root_absolute(paths[0], pos); + // Determine whether the path is absolute or not. We need that to determine + // later on whether we can remove superfluous "../" or not. + absolute = cwk_path_is_root_absolute(paths[0], pos); - // First copy the root to the output. We will not modify the root. - cwk_path_output_sized(buffer, buffer_size, 0, paths[0], pos); + // First copy the root to the output. We will not modify the root. + cwk_path_output_sized(buffer, buffer_size, 0, paths[0], pos); - // So we just grab the first segment. If there is no segment we will always - // output a "/", since we currently only support absolute paths here. - if (!cwk_path_get_first_segment_joined(paths, &sj)) { - goto done; - } + // So we just grab the first segment. If there is no segment we will always + // output a "/", since we currently only support absolute paths here. + if (!cwk_path_get_first_segment_joined(paths, &sj)) { + goto done; + } - // Let's assume that we don't have any segment output for now. We will toggle - // this flag once there is some output. - has_segment_output = false; + // Let's assume that we don't have any segment output for now. We will toggle + // this flag once there is some output. + has_segment_output = false; - do { - // Check whether we have to drop this segment because of resolving a - // relative path or because it is a CWK_CURRENT segment. - if (cwk_path_segment_will_be_removed(&sj, absolute)) { - continue; - } + do { + // Check whether we have to drop this segment because of resolving a + // relative path or because it is a CWK_CURRENT segment. + if (cwk_path_segment_will_be_removed(&sj, absolute)) { + continue; + } - // Remember that we have segment output, so we can handle the trailing slash - // later on. This is necessary since we might have segments but they are all - // removed. - has_segment_output = true; + // Remember that we have segment output, so we can handle the trailing slash + // later on. This is necessary since we might have segments but they are all + // removed. + has_segment_output = true; - // Write out the segment but keep in mind that we need to follow the - // buffer size limitations. That's why we use the path output functions - // here. - pos += cwk_path_output_sized(buffer, buffer_size, pos, sj.segment.begin, - sj.segment.size); - pos += cwk_path_output_separator(buffer, buffer_size, pos); - } while (cwk_path_get_next_segment_joined(&sj)); + // Write out the segment but keep in mind that we need to follow the + // buffer size limitations. That's why we use the path output functions + // here. + pos += cwk_path_output_sized(buffer, buffer_size, pos, sj.segment.begin, sj.segment.size); + pos += cwk_path_output_separator(buffer, buffer_size, pos); + } while (cwk_path_get_next_segment_joined(&sj)); - // Remove the trailing slash, but only if we have segment output. We don't - // want to remove anything from the root. - if (has_segment_output) { - --pos; - } else if (pos == 0) { - // This may happen if the path is absolute and all segments have been - // removed. We can not have an empty output - and empty output means we stay - // in the current directory. So we will output a ".". - assert(absolute == false); - pos += cwk_path_output_current(buffer, buffer_size, pos); - } + // Remove the trailing slash, but only if we have segment output. We don't + // want to remove anything from the root. + if (has_segment_output) { + --pos; + } else if (pos == 0) { + // This may happen if the path is absolute and all segments have been + // removed. We can not have an empty output - and empty output means we stay + // in the current directory. So we will output a ".". + assert(absolute == false); + pos += cwk_path_output_current(buffer, buffer_size, pos); + } - // We must append a '\0' in any case, unless the buffer size is zero. If the - // buffer size is zero, which means we can not. - done: - cwk_path_terminate_output(buffer, buffer_size, pos); + // We must append a '\0' in any case, unless the buffer size is zero. If the + // buffer size is zero, which means we can not. +done: + cwk_path_terminate_output(buffer, buffer_size, pos); - // And finally let our caller know about the total size of the normalized - // path. - return pos; + // And finally let our caller know about the total size of the normalized + // path. + return pos; } -size_t cwk_path_get_absolute(const char *base, const char *path, char *buffer, - size_t buffer_size) { - size_t i; - const char *paths[4]; +size_t cwk_path_get_absolute(const char *base, const char *path, char *buffer, size_t buffer_size) { + size_t i; + const char *paths[4]; - // The basename should be an absolute path if the caller is using the API - // correctly. However, he might not and in that case we will append a fake - // root at the beginning. - if (cwk_path_is_absolute(base)) { - i = 0; - } else { - paths[0] = "/"; - i = 1; - } + // The basename should be an absolute path if the caller is using the API + // correctly. However, he might not and in that case we will append a fake + // root at the beginning. + if (cwk_path_is_absolute(base)) { + i = 0; + } else { + paths[0] = "/"; + i = 1; + } - if (cwk_path_is_absolute(path)) { - // If the submitted path is not relative the base path becomes irrelevant. - // We will only normalize the submitted path instead. - paths[i++] = path; - paths[i] = NULL; - } else { - // Otherwise we append the relative path to the base path and normalize it. - // The result will be a new absolute path. - paths[i++] = base; - paths[i++] = path; - paths[i] = NULL; - } + if (cwk_path_is_absolute(path)) { + // If the submitted path is not relative the base path becomes irrelevant. + // We will only normalize the submitted path instead. + paths[i++] = path; + paths[i] = NULL; + } else { + // Otherwise we append the relative path to the base path and normalize it. + // The result will be a new absolute path. + paths[i++] = base; + paths[i++] = path; + paths[i] = NULL; + } - // Finally join everything together and normalize it. - return cwk_path_join_and_normalize_multiple(paths, buffer, buffer_size); + // Finally join everything together and normalize it. + return cwk_path_join_and_normalize_multiple(paths, buffer, buffer_size); } -static void cwk_path_skip_segments_until_diverge(struct cwk_segment_joined *bsj, - struct cwk_segment_joined *osj, bool absolute, bool *base_available, - bool *other_available) { - // Now looping over all segments until they start to diverge. A path may - // diverge if two segments are not equal or if one path reaches the end. - do { +static void cwk_path_skip_segments_until_diverge(struct cwk_segment_joined *bsj, struct cwk_segment_joined *osj, bool absolute, + bool *base_available, bool *other_available) { + // Now looping over all segments until they start to diverge. A path may + // diverge if two segments are not equal or if one path reaches the end. + do { - // Check whether there is anything available after we skip everything which - // is invisible. We do that for both paths, since we want to let the caller - // know which path has some trailing segments after they diverge. - *base_available = cwk_path_segment_joined_skip_invisible(bsj, absolute); - *other_available = cwk_path_segment_joined_skip_invisible(osj, absolute); + // Check whether there is anything available after we skip everything which + // is invisible. We do that for both paths, since we want to let the caller + // know which path has some trailing segments after they diverge. + *base_available = cwk_path_segment_joined_skip_invisible(bsj, absolute); + *other_available = cwk_path_segment_joined_skip_invisible(osj, absolute); - // We are done if one or both of those paths reached the end. They either - // diverge or both reached the end - but in both cases we can not continue - // here. - if (!*base_available || !*other_available) { - break; - } + // We are done if one or both of those paths reached the end. They either + // diverge or both reached the end - but in both cases we can not continue + // here. + if (!*base_available || !*other_available) { + break; + } - // Compare the content of both segments. We are done if they are not equal, - // since they diverge. - if (!cwk_path_is_string_equal(bsj->segment.begin, osj->segment.begin, - bsj->segment.size)) { - break; - } + // Compare the content of both segments. We are done if they are not equal, + // since they diverge. + if (!cwk_path_is_string_equal(bsj->segment.begin, osj->segment.begin, bsj->segment.size)) { + break; + } - // We keep going until one of those segments reached the end. The next - // segment might be invisible, but we will check for that in the beginning - // of the loop once again. - *base_available = cwk_path_get_next_segment_joined(bsj); - *other_available = cwk_path_get_next_segment_joined(osj); - } while (*base_available && *other_available); + // We keep going until one of those segments reached the end. The next + // segment might be invisible, but we will check for that in the beginning + // of the loop once again. + *base_available = cwk_path_get_next_segment_joined(bsj); + *other_available = cwk_path_get_next_segment_joined(osj); + } while (*base_available && *other_available); } -size_t cwk_path_get_relative(const char *base_directory, const char *path, - char *buffer, size_t buffer_size) { - size_t pos, base_root_length, path_root_length; - bool absolute, base_available, other_available, has_output; - const char *base_paths[2], *other_paths[2]; - struct cwk_segment_joined bsj, osj; +size_t cwk_path_get_relative(const char *base_directory, const char *path, char *buffer, size_t buffer_size) { + size_t pos, base_root_length, path_root_length; + bool absolute, base_available, other_available, has_output; + const char *base_paths[2], *other_paths[2]; + struct cwk_segment_joined bsj, osj; - pos = 0; + pos = 0; - // First we compare the roots of those two paths. If the roots are not equal - // we can't continue, since there is no way to get a relative path from - // different roots. - cwk_path_get_root(base_directory, &base_root_length); - cwk_path_get_root(path, &path_root_length); - if (!cwk_path_is_string_equal(base_directory, path, base_root_length)) { - return pos; - } + // First we compare the roots of those two paths. If the roots are not equal + // we can't continue, since there is no way to get a relative path from + // different roots. + cwk_path_get_root(base_directory, &base_root_length); + cwk_path_get_root(path, &path_root_length); + if (!cwk_path_is_string_equal(base_directory, path, base_root_length)) { + return pos; + } - // Verify whether this is an absolute path. We need to know that since we can - // remove all back-segments if it is. - absolute = cwk_path_is_root_absolute(base_directory, base_root_length); + // Verify whether this is an absolute path. We need to know that since we can + // remove all back-segments if it is. + absolute = cwk_path_is_root_absolute(base_directory, base_root_length); - // Initialize our joined segments. This will allow us to use the internal - // functions to skip until diverge and invisible. We only have one path in - // them though. - base_paths[0] = base_directory; - base_paths[1] = NULL; - other_paths[0] = path; - other_paths[1] = NULL; - cwk_path_get_first_segment_joined(base_paths, &bsj); - cwk_path_get_first_segment_joined(other_paths, &osj); + // Initialize our joined segments. This will allow us to use the internal + // functions to skip until diverge and invisible. We only have one path in + // them though. + base_paths[0] = base_directory; + base_paths[1] = NULL; + other_paths[0] = path; + other_paths[1] = NULL; + cwk_path_get_first_segment_joined(base_paths, &bsj); + cwk_path_get_first_segment_joined(other_paths, &osj); - // Okay, now we skip until the segments diverge. We don't have anything to do - // with the segments which are equal. - cwk_path_skip_segments_until_diverge(&bsj, &osj, absolute, &base_available, - &other_available); + // Okay, now we skip until the segments diverge. We don't have anything to do + // with the segments which are equal. + cwk_path_skip_segments_until_diverge(&bsj, &osj, absolute, &base_available, &other_available); - // Assume there is no output until we have got some. We will need this - // information later on to remove trailing slashes or alternatively output a - // current-segment. - has_output = false; + // Assume there is no output until we have got some. We will need this + // information later on to remove trailing slashes or alternatively output a + // current-segment. + has_output = false; - // So if we still have some segments left in the base path we will now output - // a back segment for all of them. - if (base_available) { - do { - // Skip any invisible segment. We don't care about those and we don't need - // to navigate back because of them. - if (!cwk_path_segment_joined_skip_invisible(&bsj, absolute)) { - break; - } + // So if we still have some segments left in the base path we will now output + // a back segment for all of them. + if (base_available) { + do { + // Skip any invisible segment. We don't care about those and we don't need + // to navigate back because of them. + if (!cwk_path_segment_joined_skip_invisible(&bsj, absolute)) { + break; + } - // Toggle the flag if we have output. We need to remember that, since we - // want to remove the trailing slash. - has_output = true; + // Toggle the flag if we have output. We need to remember that, since we + // want to remove the trailing slash. + has_output = true; - // Output the back segment and a separator. No need to worry about the - // superfluous segment since it will be removed later on. - pos += cwk_path_output_back(buffer, buffer_size, pos); - pos += cwk_path_output_separator(buffer, buffer_size, pos); - } while (cwk_path_get_next_segment_joined(&bsj)); - } + // Output the back segment and a separator. No need to worry about the + // superfluous segment since it will be removed later on. + pos += cwk_path_output_back(buffer, buffer_size, pos); + pos += cwk_path_output_separator(buffer, buffer_size, pos); + } while (cwk_path_get_next_segment_joined(&bsj)); + } - // And if we have some segments available of the target path we will output - // all of those. - if (other_available) { - do { - // Again, skip any invisible segments since we don't need to navigate into - // them. - if (!cwk_path_segment_joined_skip_invisible(&osj, absolute)) { - break; - } + // And if we have some segments available of the target path we will output + // all of those. + if (other_available) { + do { + // Again, skip any invisible segments since we don't need to navigate into + // them. + if (!cwk_path_segment_joined_skip_invisible(&osj, absolute)) { + break; + } - // Toggle the flag if we have output. We need to remember that, since we - // want to remove the trailing slash. - has_output = true; + // Toggle the flag if we have output. We need to remember that, since we + // want to remove the trailing slash. + has_output = true; - // Output the current segment and a separator. No need to worry about the - // superfluous segment since it will be removed later on. - pos += cwk_path_output_sized(buffer, buffer_size, pos, osj.segment.begin, - osj.segment.size); - pos += cwk_path_output_separator(buffer, buffer_size, pos); - } while (cwk_path_get_next_segment_joined(&osj)); - } + // Output the current segment and a separator. No need to worry about the + // superfluous segment since it will be removed later on. + pos += cwk_path_output_sized(buffer, buffer_size, pos, osj.segment.begin, osj.segment.size); + pos += cwk_path_output_separator(buffer, buffer_size, pos); + } while (cwk_path_get_next_segment_joined(&osj)); + } - // If we have some output by now we will have to remove the trailing slash. We - // simply do that by moving back one character. The terminate output function - // will then place the '\0' on this position. Otherwise, if there is no - // output, we will have to output a "current directory", since the target path - // points to the base path. - if (has_output) { - --pos; - } else { - pos += cwk_path_output_current(buffer, buffer_size, pos); - } + // If we have some output by now we will have to remove the trailing slash. We + // simply do that by moving back one character. The terminate output function + // will then place the '\0' on this position. Otherwise, if there is no + // output, we will have to output a "current directory", since the target path + // points to the base path. + if (has_output) { + --pos; + } else { + pos += cwk_path_output_current(buffer, buffer_size, pos); + } - // Finally, we can terminate the output - which means we place a '\0' at the - // current position or at the end of the buffer. - cwk_path_terminate_output(buffer, buffer_size, pos); + // Finally, we can terminate the output - which means we place a '\0' at the + // current position or at the end of the buffer. + cwk_path_terminate_output(buffer, buffer_size, pos); - return pos; + return pos; } -size_t cwk_path_join(const char *path_a, const char *path_b, char *buffer, - size_t buffer_size) { - const char *paths[3]; +size_t cwk_path_join(const char *path_a, const char *path_b, char *buffer, size_t buffer_size) { + const char *paths[3]; - // This is simple. We will just create an array with the two paths which we - // wish to join. - paths[0] = path_a; - paths[1] = path_b; - paths[2] = NULL; + // This is simple. We will just create an array with the two paths which we + // wish to join. + paths[0] = path_a; + paths[1] = path_b; + paths[2] = NULL; - // And then call the join and normalize function which will do the hard work - // for us. - return cwk_path_join_and_normalize_multiple(paths, buffer, buffer_size); + // And then call the join and normalize function which will do the hard work + // for us. + return cwk_path_join_and_normalize_multiple(paths, buffer, buffer_size); } -size_t cwk_path_join_multiple(const char **paths, char *buffer, - size_t buffer_size) { - // We can just call the internal join and normalize function for this one, - // since it will handle everything. - return cwk_path_join_and_normalize_multiple(paths, buffer, buffer_size); +size_t cwk_path_join_multiple(const char **paths, char *buffer, size_t buffer_size) { + // We can just call the internal join and normalize function for this one, + // since it will handle everything. + return cwk_path_join_and_normalize_multiple(paths, buffer, buffer_size); } void cwk_path_get_root(const char *path, size_t *length) { - // We use a different implementation here based on the configuration of the - // library. - if (path_style == CWK_STYLE_WINDOWS) { - cwk_path_get_root_windows(path, length); - } else { - cwk_path_get_root_unix(path, length); - } + // We use a different implementation here based on the configuration of the + // library. + if (path_style == CWK_STYLE_WINDOWS) { + cwk_path_get_root_windows(path, length); + } else { + cwk_path_get_root_unix(path, length); + } } -size_t cwk_path_change_root(const char *path, const char *new_root, - char *buffer, size_t buffer_size) { - const char *tail; - size_t root_length, path_length, tail_length, new_root_length, new_path_size; +size_t cwk_path_change_root(const char *path, const char *new_root, char *buffer, size_t buffer_size) { + const char *tail; + size_t root_length, path_length, tail_length, new_root_length, new_path_size; - // First we need to determine the actual size of the root which we will - // change. - cwk_path_get_root(path, &root_length); + // First we need to determine the actual size of the root which we will + // change. + cwk_path_get_root(path, &root_length); - // Now we determine the sizes of the new root and the path. We need that to - // determine the size of the part after the root (the tail). - new_root_length = strlen(new_root); - path_length = strlen(path); + // Now we determine the sizes of the new root and the path. We need that to + // determine the size of the part after the root (the tail). + new_root_length = strlen(new_root); + path_length = strlen(path); - // Okay, now we calculate the position of the tail and the length of it. - tail = path + root_length; - tail_length = path_length - root_length; + // Okay, now we calculate the position of the tail and the length of it. + tail = path + root_length; + tail_length = path_length - root_length; - // We first output the tail and then the new root, that's because the source - // path and the buffer may be overlapping. This way the root will not - // overwrite the tail. - cwk_path_output_sized(buffer, buffer_size, new_root_length, tail, - tail_length); - cwk_path_output_sized(buffer, buffer_size, 0, new_root, new_root_length); + // We first output the tail and then the new root, that's because the source + // path and the buffer may be overlapping. This way the root will not + // overwrite the tail. + cwk_path_output_sized(buffer, buffer_size, new_root_length, tail, tail_length); + cwk_path_output_sized(buffer, buffer_size, 0, new_root, new_root_length); - // Finally we calculate the size o the new path and terminate the output with - // a '\0'. - new_path_size = tail_length + new_root_length; - cwk_path_terminate_output(buffer, buffer_size, new_path_size); + // Finally we calculate the size o the new path and terminate the output with + // a '\0'. + new_path_size = tail_length + new_root_length; + cwk_path_terminate_output(buffer, buffer_size, new_path_size); - return new_path_size; + return new_path_size; } bool cwk_path_is_absolute(const char *path) { - size_t length; + size_t length; - // We grab the root of the path. This root does not include the first - // separator of a path. - cwk_path_get_root(path, &length); + // We grab the root of the path. This root does not include the first + // separator of a path. + cwk_path_get_root(path, &length); - // Now we can determine whether the root is absolute or not. - return cwk_path_is_root_absolute(path, length); + // Now we can determine whether the root is absolute or not. + return cwk_path_is_root_absolute(path, length); } bool cwk_path_is_relative(const char *path) { - // The path is relative if it is not absolute. - return !cwk_path_is_absolute(path); + // The path is relative if it is not absolute. + return !cwk_path_is_absolute(path); } -void cwk_path_get_basename(const char *path, const char **basename, - size_t *length) { - struct cwk_segment segment; +void cwk_path_get_basename(const char *path, const char **basename, size_t *length) { + struct cwk_segment segment; - // We get the last segment of the path. The last segment will contain the - // basename if there is any. If there are no segments we will set the basename - // to NULL and the length to 0. - if (!cwk_path_get_last_segment(path, &segment)) { - *basename = NULL; - *length = 0; - return; - } + // We get the last segment of the path. The last segment will contain the + // basename if there is any. If there are no segments we will set the basename + // to NULL and the length to 0. + if (!cwk_path_get_last_segment(path, &segment)) { + *basename = NULL; + *length = 0; + return; + } - // Now we can just output the segment contents, since that's our basename. - // There might be trailing separators after the basename, but the size does - // not include those. - *basename = segment.begin; - *length = segment.size; + // Now we can just output the segment contents, since that's our basename. + // There might be trailing separators after the basename, but the size does + // not include those. + *basename = segment.begin; + *length = segment.size; } -size_t cwk_path_change_basename(const char *path, const char *new_basename, - char *buffer, size_t buffer_size) { - struct cwk_segment segment; - size_t pos, root_size, new_basename_size; +size_t cwk_path_change_basename(const char *path, const char *new_basename, char *buffer, size_t buffer_size) { + struct cwk_segment segment; + size_t pos, root_size, new_basename_size; - // First we try to get the last segment. We may only have a root without any - // segments, in which case we will create one. - if (!cwk_path_get_last_segment(path, &segment)) { + // First we try to get the last segment. We may only have a root without any + // segments, in which case we will create one. + if (!cwk_path_get_last_segment(path, &segment)) { - // So there is no segment in this path. First we grab the root and output - // that. We are not going to modify the root in any way. - cwk_path_get_root(path, &root_size); - pos = cwk_path_output_sized(buffer, buffer_size, 0, path, root_size); + // So there is no segment in this path. First we grab the root and output + // that. We are not going to modify the root in any way. + cwk_path_get_root(path, &root_size); + pos = cwk_path_output_sized(buffer, buffer_size, 0, path, root_size); - // We have to trim the separators from the beginning of the new basename. - // This is quite easy to do. - while (cwk_path_is_separator(new_basename)) { - ++new_basename; - } + // We have to trim the separators from the beginning of the new basename. + // This is quite easy to do. + while (cwk_path_is_separator(new_basename)) { + ++new_basename; + } - // Now we measure the length of the new basename, this is a two step - // process. First we find the '\0' character at the end of the string. - new_basename_size = 0; - while (new_basename[new_basename_size]) { - ++new_basename_size; - } + // Now we measure the length of the new basename, this is a two step + // process. First we find the '\0' character at the end of the string. + new_basename_size = 0; + while (new_basename[new_basename_size]) { + ++new_basename_size; + } - // And then we trim the separators at the end of the basename until we reach - // the first valid character. - while (new_basename_size > 0 && - cwk_path_is_separator(&new_basename[new_basename_size - 1])) { - --new_basename_size; - } + // And then we trim the separators at the end of the basename until we reach + // the first valid character. + while (new_basename_size > 0 && cwk_path_is_separator(&new_basename[new_basename_size - 1])) { + --new_basename_size; + } - // Now we will output the new basename after the root. - pos += cwk_path_output_sized(buffer, buffer_size, pos, new_basename, - new_basename_size); + // Now we will output the new basename after the root. + pos += cwk_path_output_sized(buffer, buffer_size, pos, new_basename, new_basename_size); - // And finally terminate the output and return the total size of the path. - cwk_path_terminate_output(buffer, buffer_size, pos); - return pos; - } + // And finally terminate the output and return the total size of the path. + cwk_path_terminate_output(buffer, buffer_size, pos); + return pos; + } - // If there is a last segment we can just forward this call, which is fairly - // easy. - return cwk_path_change_segment(&segment, new_basename, buffer, buffer_size); + // If there is a last segment we can just forward this call, which is fairly + // easy. + return cwk_path_change_segment(&segment, new_basename, buffer, buffer_size); } void cwk_path_get_dirname(const char *path, size_t *length) { - struct cwk_segment segment; + struct cwk_segment segment; - // We get the last segment of the path. The last segment will contain the - // basename if there is any. If there are no segments we will set the length - // to 0. - if (!cwk_path_get_last_segment(path, &segment)) { - *length = 0; - return; - } + // We get the last segment of the path. The last segment will contain the + // basename if there is any. If there are no segments we will set the length + // to 0. + if (!cwk_path_get_last_segment(path, &segment)) { + *length = 0; + return; + } - // We can now return the length from the beginning of the string up to the - // beginning of the last segment. - *length = segment.begin - path; + // We can now return the length from the beginning of the string up to the + // beginning of the last segment. + *length = segment.begin - path; } -bool cwk_path_get_extension(const char *path, const char **extension, - size_t *length) { - struct cwk_segment segment; - const char *c; +bool cwk_path_get_extension(const char *path, const char **extension, size_t *length) { + struct cwk_segment segment; + const char *c; - // We get the last segment of the path. The last segment will contain the - // extension if there is any. - if (!cwk_path_get_last_segment(path, &segment)) { - return false; - } + // We get the last segment of the path. The last segment will contain the + // extension if there is any. + if (!cwk_path_get_last_segment(path, &segment)) { + return false; + } - // Now we search for a dot within the segment. If there is a dot, we consider - // the rest of the segment the extension. We do this from the end towards the - // beginning, since we want to find the last dot. - for (c = segment.end; c >= segment.begin; --c) { - if (*c == '.') { - // Okay, we found an extension. We can stop looking now. - *extension = c; - *length = segment.end - c; - return true; - } - } + // Now we search for a dot within the segment. If there is a dot, we consider + // the rest of the segment the extension. We do this from the end towards the + // beginning, since we want to find the last dot. + for (c = segment.end; c >= segment.begin; --c) { + if (*c == '.') { + // Okay, we found an extension. We can stop looking now. + *extension = c; + *length = segment.end - c; + return true; + } + } - // We couldn't find any extension. - return false; + // We couldn't find any extension. + return false; } bool cwk_path_has_extension(const char *path) { - const char *extension; - size_t length; + const char *extension; + size_t length; - // We just wrap the get_extension call which will then do the work for us. - return cwk_path_get_extension(path, &extension, &length); + // We just wrap the get_extension call which will then do the work for us. + return cwk_path_get_extension(path, &extension, &length); } -size_t cwk_path_change_extension(const char *path, const char *new_extension, - char *buffer, size_t buffer_size) { - struct cwk_segment segment; - const char *c, *old_extension; - size_t pos, root_size, trail_size, new_extension_size; +size_t cwk_path_change_extension(const char *path, const char *new_extension, char *buffer, size_t buffer_size) { + struct cwk_segment segment; + const char *c, *old_extension; + size_t pos, root_size, trail_size, new_extension_size; - // First we try to get the last segment. We may only have a root without any - // segments, in which case we will create one. - if (!cwk_path_get_last_segment(path, &segment)) { + // First we try to get the last segment. We may only have a root without any + // segments, in which case we will create one. + if (!cwk_path_get_last_segment(path, &segment)) { - // So there is no segment in this path. First we grab the root and output - // that. We are not going to modify the root in any way. If there is no - // root, this will end up with a root size 0, and nothing will be written. - cwk_path_get_root(path, &root_size); - pos = cwk_path_output_sized(buffer, buffer_size, 0, path, root_size); + // So there is no segment in this path. First we grab the root and output + // that. We are not going to modify the root in any way. If there is no + // root, this will end up with a root size 0, and nothing will be written. + cwk_path_get_root(path, &root_size); + pos = cwk_path_output_sized(buffer, buffer_size, 0, path, root_size); - // Add a dot if the submitted value doesn't have any. - if (*new_extension != '.') { - pos += cwk_path_output_dot(buffer, buffer_size, pos); - } + // Add a dot if the submitted value doesn't have any. + if (*new_extension != '.') { + pos += cwk_path_output_dot(buffer, buffer_size, pos); + } - // And finally terminate the output and return the total size of the path. - pos += cwk_path_output(buffer, buffer_size, pos, new_extension); - cwk_path_terminate_output(buffer, buffer_size, pos); - return pos; - } + // And finally terminate the output and return the total size of the path. + pos += cwk_path_output(buffer, buffer_size, pos, new_extension); + cwk_path_terminate_output(buffer, buffer_size, pos); + return pos; + } - // Now we seek the old extension in the last segment, which we will replace - // with the new one. If there is no old extension, it will point to the end of - // the segment. - old_extension = segment.end; - for (c = segment.begin; c < segment.end; ++c) { - if (*c == '.') { - old_extension = c; - } - } + // Now we seek the old extension in the last segment, which we will replace + // with the new one. If there is no old extension, it will point to the end of + // the segment. + old_extension = segment.end; + for (c = segment.begin; c < segment.end; ++c) { + if (*c == '.') { + old_extension = c; + } + } - pos = cwk_path_output_sized(buffer, buffer_size, 0, segment.path, - old_extension - segment.path); + pos = cwk_path_output_sized(buffer, buffer_size, 0, segment.path, old_extension - segment.path); - // If the new extension starts with a dot, we will skip that dot. We always - // output exactly one dot before the extension. If the extension contains - // multiple dots, we will output those as part of the extension. - if (*new_extension == '.') { - ++new_extension; - } + // If the new extension starts with a dot, we will skip that dot. We always + // output exactly one dot before the extension. If the extension contains + // multiple dots, we will output those as part of the extension. + if (*new_extension == '.') { + ++new_extension; + } - // We calculate the size of the new extension, including the dot, in order to - // output the trail - which is any part of the path coming after the - // extension. We must output this first, since the buffer may overlap with the - // submitted path - and it would be overridden by longer extensions. - new_extension_size = strlen(new_extension) + 1; - trail_size = cwk_path_output(buffer, buffer_size, pos + new_extension_size, - segment.end); + // We calculate the size of the new extension, including the dot, in order to + // output the trail - which is any part of the path coming after the + // extension. We must output this first, since the buffer may overlap with the + // submitted path - and it would be overridden by longer extensions. + new_extension_size = strlen(new_extension) + 1; + trail_size = cwk_path_output(buffer, buffer_size, pos + new_extension_size, segment.end); - // Finally we output the dot and the new extension. The new extension itself - // doesn't contain the dot anymore, so we must output that first. - pos += cwk_path_output_dot(buffer, buffer_size, pos); - pos += cwk_path_output(buffer, buffer_size, pos, new_extension); + // Finally we output the dot and the new extension. The new extension itself + // doesn't contain the dot anymore, so we must output that first. + pos += cwk_path_output_dot(buffer, buffer_size, pos); + pos += cwk_path_output(buffer, buffer_size, pos, new_extension); - // Now we terminate the output with a null-terminating character, but before - // we do that we must add the size of the trail to the position which we - // output before. - pos += trail_size; - cwk_path_terminate_output(buffer, buffer_size, pos); + // Now we terminate the output with a null-terminating character, but before + // we do that we must add the size of the trail to the position which we + // output before. + pos += trail_size; + cwk_path_terminate_output(buffer, buffer_size, pos); - // And the position is our output size now. - return pos; + // And the position is our output size now. + return pos; } size_t cwk_path_normalize(const char *path, char *buffer, size_t buffer_size) { - const char *paths[2]; + const char *paths[2]; - // Now we initialize the paths which we will normalize. Since this function - // only supports submitting a single path, we will only add that one. - paths[0] = path; - paths[1] = NULL; + // Now we initialize the paths which we will normalize. Since this function + // only supports submitting a single path, we will only add that one. + paths[0] = path; + paths[1] = NULL; - return cwk_path_join_and_normalize_multiple(paths, buffer, buffer_size); + return cwk_path_join_and_normalize_multiple(paths, buffer, buffer_size); } size_t cwk_path_get_intersection(const char *path_base, const char *path_other) { - bool absolute; - size_t base_root_length, other_root_length; - const char *end; - const char *paths_base[2], *paths_other[2]; - struct cwk_segment_joined base, other; + bool absolute; + size_t base_root_length, other_root_length; + const char *end; + const char *paths_base[2], *paths_other[2]; + struct cwk_segment_joined base, other; - // We first compare the two roots. We just return zero if they are not equal. - // This will also happen to return zero if the paths are mixed relative and - // absolute. - cwk_path_get_root(path_base, &base_root_length); - cwk_path_get_root(path_other, &other_root_length); - if (!cwk_path_is_string_equal(path_base, path_other, base_root_length)) { - return 0; - } + // We first compare the two roots. We just return zero if they are not equal. + // This will also happen to return zero if the paths are mixed relative and + // absolute. + cwk_path_get_root(path_base, &base_root_length); + cwk_path_get_root(path_other, &other_root_length); + if (!cwk_path_is_string_equal(path_base, path_other, base_root_length)) { + return 0; + } - // Configure our paths. We just have a single path in here for now. - paths_base[0] = path_base; - paths_base[1] = NULL; - paths_other[0] = path_other; - paths_other[1] = NULL; + // Configure our paths. We just have a single path in here for now. + paths_base[0] = path_base; + paths_base[1] = NULL; + paths_other[0] = path_other; + paths_other[1] = NULL; - // So we get the first segment of both paths. If one of those paths don't have - // any segment, we will return 0. - if (!cwk_path_get_first_segment_joined(paths_base, &base) || - !cwk_path_get_first_segment_joined(paths_other, &other)) { - return base_root_length; - } + // So we get the first segment of both paths. If one of those paths don't have + // any segment, we will return 0. + if (!cwk_path_get_first_segment_joined(paths_base, &base) || !cwk_path_get_first_segment_joined(paths_other, &other)) { + return base_root_length; + } - // We now determine whether the path is absolute or not. This is required - // because if will ignore removed segments, and this behaves differently if - // the path is absolute. However, we only need to check the base path because - // we are guaranteed that both paths are either relative or absolute. - absolute = cwk_path_is_root_absolute(path_base, base_root_length); + // We now determine whether the path is absolute or not. This is required + // because if will ignore removed segments, and this behaves differently if + // the path is absolute. However, we only need to check the base path because + // we are guaranteed that both paths are either relative or absolute. + absolute = cwk_path_is_root_absolute(path_base, base_root_length); - // We must keep track of the end of the previous segment. Initially, this is - // set to the beginning of the path. This means that 0 is returned if the - // first segment is not equal. - end = path_base + base_root_length; + // We must keep track of the end of the previous segment. Initially, this is + // set to the beginning of the path. This means that 0 is returned if the + // first segment is not equal. + end = path_base + base_root_length; - // Now we loop over both segments until one of them reaches the end or their - // contents are not equal. - do { - // We skip all segments which will be removed in each path, since we want to - // know about the true path. - if (!cwk_path_segment_joined_skip_invisible(&base, absolute) || - !cwk_path_segment_joined_skip_invisible(&other, absolute)) { - break; - } + // Now we loop over both segments until one of them reaches the end or their + // contents are not equal. + do { + // We skip all segments which will be removed in each path, since we want to + // know about the true path. + if (!cwk_path_segment_joined_skip_invisible(&base, absolute) || + !cwk_path_segment_joined_skip_invisible(&other, absolute)) { + break; + } - if (!cwk_path_is_string_equal(base.segment.begin, other.segment.begin, - base.segment.size)) { - // So the content of those two segments are not equal. We will return the - // size up to the beginning. - return end - path_base; - } + if (!cwk_path_is_string_equal(base.segment.begin, other.segment.begin, base.segment.size)) { + // So the content of those two segments are not equal. We will return the + // size up to the beginning. + return end - path_base; + } - // Remember the end of the previous segment before we go to the next one. - end = base.segment.end; - } while (cwk_path_get_next_segment_joined(&base) && - cwk_path_get_next_segment_joined(&other)); + // Remember the end of the previous segment before we go to the next one. + end = base.segment.end; + } while (cwk_path_get_next_segment_joined(&base) && cwk_path_get_next_segment_joined(&other)); - // Now we calculate the length up to the last point where our paths pointed to - // the same place. - return end - path_base; + // Now we calculate the length up to the last point where our paths pointed to + // the same place. + return end - path_base; } bool cwk_path_get_first_segment(const char *path, struct cwk_segment *segment) { - size_t length; - const char *segments; + size_t length; + const char *segments; - // We skip the root since that's not part of the first segment. The root is - // treated as a separate entity. - cwk_path_get_root(path, &length); - segments = path + length; + // We skip the root since that's not part of the first segment. The root is + // treated as a separate entity. + cwk_path_get_root(path, &length); + segments = path + length; - // Now, after we skipped the root we can continue and find the actual segment - // content. - return cwk_path_get_first_segment_without_root(path, segments, segment); + // Now, after we skipped the root we can continue and find the actual segment + // content. + return cwk_path_get_first_segment_without_root(path, segments, segment); } bool cwk_path_get_last_segment(const char *path, struct cwk_segment *segment) { - // We first grab the first segment. This might be our last segment as well, - // but we don't know yet. There is no last segment if there is no first - // segment, so we return false in that case. - if (!cwk_path_get_first_segment(path, segment)) { - return false; - } + // We first grab the first segment. This might be our last segment as well, + // but we don't know yet. There is no last segment if there is no first + // segment, so we return false in that case. + if (!cwk_path_get_first_segment(path, segment)) { + return false; + } - // Now we find our last segment. The segment struct of the caller - // will contain the last segment, since the function we call here will not - // change the segment struct when it reaches the end. - while (cwk_path_get_next_segment(segment)) { - // We just loop until there is no other segment left. - } + // Now we find our last segment. The segment struct of the caller + // will contain the last segment, since the function we call here will not + // change the segment struct when it reaches the end. + while (cwk_path_get_next_segment(segment)) { + // We just loop until there is no other segment left. + } - return true; + return true; } bool cwk_path_get_next_segment(struct cwk_segment *segment) { - const char *c; + const char *c; - // First we jump to the end of the previous segment. The first character must - // be either a '\0' or a separator. - c = segment->begin + segment->size; - if (*c == '\0') { - return false; - } + // First we jump to the end of the previous segment. The first character must + // be either a '\0' or a separator. + c = segment->begin + segment->size; + if (*c == '\0') { + return false; + } - // Now we skip all separator until we reach something else. We are not yet - // guaranteed to have a segment, since the string could just end afterwards. - assert(cwk_path_is_separator(c)); - do { - ++c; - } while (cwk_path_is_separator(c)); + // Now we skip all separator until we reach something else. We are not yet + // guaranteed to have a segment, since the string could just end afterwards. + assert(cwk_path_is_separator(c)); + do { + ++c; + } while (cwk_path_is_separator(c)); - // If the string ends here, we can safely assume that there is no other - // segment after this one. - if (*c == '\0') { - return false; - } + // If the string ends here, we can safely assume that there is no other + // segment after this one. + if (*c == '\0') { + return false; + } - // Now we are safe to assume there is a segment. We store the beginning of - // this segment in the segment struct of the caller. - segment->begin = c; + // Now we are safe to assume there is a segment. We store the beginning of + // this segment in the segment struct of the caller. + segment->begin = c; - // And now determine the size of this segment, and store it in the struct of - // the caller as well. - c = cwk_path_find_next_stop(c); - segment->end = c; - segment->size = c - segment->begin; + // And now determine the size of this segment, and store it in the struct of + // the caller as well. + c = cwk_path_find_next_stop(c); + segment->end = c; + segment->size = c - segment->begin; - // Tell the caller that we found a segment. - return true; + // Tell the caller that we found a segment. + return true; } bool cwk_path_get_previous_segment(struct cwk_segment *segment) { - const char *c; + const char *c; - // The current position might point to the first character of the path, which - // means there are no previous segments available. - c = segment->begin; - if (c <= segment->segments) { - return false; - } + // The current position might point to the first character of the path, which + // means there are no previous segments available. + c = segment->begin; + if (c <= segment->segments) { + return false; + } - // We move towards the beginning of the path until we either reached the - // beginning or the character is no separator anymore. - do { - --c; - if (c <= segment->segments) { - // So we reached the beginning here and there is no segment. So we return - // false and don't change the segment structure submitted by the caller. - return false; - } - } while (cwk_path_is_separator(c)); + // We move towards the beginning of the path until we either reached the + // beginning or the character is no separator anymore. + do { + --c; + if (c <= segment->segments) { + // So we reached the beginning here and there is no segment. So we return + // false and don't change the segment structure submitted by the caller. + return false; + } + } while (cwk_path_is_separator(c)); - // We are guaranteed now that there is another segment, since we moved before - // the previous separator and did not reach the segment path beginning. - segment->end = c + 1; - segment->begin = cwk_path_find_previous_stop(segment->segments, c); - segment->size = segment->end - segment->begin; + // We are guaranteed now that there is another segment, since we moved before + // the previous separator and did not reach the segment path beginning. + segment->end = c + 1; + segment->begin = cwk_path_find_previous_stop(segment->segments, c); + segment->size = segment->end - segment->begin; - return true; + return true; } -enum cwk_segment_type cwk_path_get_segment_type( - const struct cwk_segment *segment) { - // We just make a string comparison with the segment contents and return the - // appropriate type. - if (strncmp(segment->begin, ".", segment->size) == 0) { - return CWK_CURRENT; - } else if (strncmp(segment->begin, "..", segment->size) == 0) { - return CWK_BACK; - } +enum cwk_segment_type cwk_path_get_segment_type(const struct cwk_segment *segment) { + // We just make a string comparison with the segment contents and return the + // appropriate type. + if (strncmp(segment->begin, ".", segment->size) == 0) { + return CWK_CURRENT; + } else if (strncmp(segment->begin, "..", segment->size) == 0) { + return CWK_BACK; + } - return CWK_NORMAL; + return CWK_NORMAL; } bool cwk_path_is_separator(const char *str) { - const char *c; + const char *c; - // We loop over all characters in the read symbols. - c = separators[path_style]; - while (*c) { - if (*c == *str) { - return true; - } + // We loop over all characters in the read symbols. + c = separators[path_style]; + while (*c) { + if (*c == *str) { + return true; + } - ++c; - } + ++c; + } - return false; + return false; } -size_t cwk_path_change_segment(struct cwk_segment *segment, const char *value, - char *buffer, size_t buffer_size) { - size_t pos, value_size, tail_size; +size_t cwk_path_change_segment(struct cwk_segment *segment, const char *value, char *buffer, size_t buffer_size) { + size_t pos, value_size, tail_size; - // First we have to output the head, which is the whole string up to the - // beginning of the segment. This part of the path will just stay the same. - pos = cwk_path_output_sized(buffer, buffer_size, 0, segment->path, - segment->begin - segment->path); + // First we have to output the head, which is the whole string up to the + // beginning of the segment. This part of the path will just stay the same. + pos = cwk_path_output_sized(buffer, buffer_size, 0, segment->path, segment->begin - segment->path); - // In order to trip the submitted value, we will skip any separator at the - // beginning of it and behave as if it was never there. - while (cwk_path_is_separator(value)) { - ++value; - } + // In order to trip the submitted value, we will skip any separator at the + // beginning of it and behave as if it was never there. + while (cwk_path_is_separator(value)) { + ++value; + } - // Now we determine the length of the value. In order to do that we first - // locate the '\0'. - value_size = 0; - while (value[value_size]) { - ++value_size; - } + // Now we determine the length of the value. In order to do that we first + // locate the '\0'. + value_size = 0; + while (value[value_size]) { + ++value_size; + } - // Since we trim separators at the beginning and in the end of the value we - // have to subtract from the size until there are either no more characters - // left or the last character is no separator. - while (value_size > 0 && cwk_path_is_separator(&value[value_size - 1])) { - --value_size; - } + // Since we trim separators at the beginning and in the end of the value we + // have to subtract from the size until there are either no more characters + // left or the last character is no separator. + while (value_size > 0 && cwk_path_is_separator(&value[value_size - 1])) { + --value_size; + } - // We also have to determine the tail size, which is the part of the string - // following the current segment. This part will not change. - tail_size = strlen(segment->end); + // We also have to determine the tail size, which is the part of the string + // following the current segment. This part will not change. + tail_size = strlen(segment->end); - // Now we output the tail. We have to do that, because if the buffer and the - // source are overlapping we would override the tail if the value is - // increasing in length. - cwk_path_output_sized(buffer, buffer_size, pos + value_size, segment->end, - tail_size); + // Now we output the tail. We have to do that, because if the buffer and the + // source are overlapping we would override the tail if the value is + // increasing in length. + cwk_path_output_sized(buffer, buffer_size, pos + value_size, segment->end, tail_size); - // Finally we can output the value in the middle of the head and the tail, - // where we have enough space to fit the whole trimmed value. - pos += cwk_path_output_sized(buffer, buffer_size, pos, value, value_size); + // Finally we can output the value in the middle of the head and the tail, + // where we have enough space to fit the whole trimmed value. + pos += cwk_path_output_sized(buffer, buffer_size, pos, value, value_size); - // Now we add the tail size to the current position and terminate the output - - // basically, ensure that there is a '\0' at the end of the buffer. - pos += tail_size; - cwk_path_terminate_output(buffer, buffer_size, pos); + // Now we add the tail size to the current position and terminate the output - + // basically, ensure that there is a '\0' at the end of the buffer. + pos += tail_size; + cwk_path_terminate_output(buffer, buffer_size, pos); - // And now tell the caller how long the whole path would be. - return pos; + // And now tell the caller how long the whole path would be. + return pos; } enum cwk_path_style cwk_path_guess_style(const char *path) { - const char *c; - size_t root_length; - struct cwk_segment segment; + const char *c; + size_t root_length; + struct cwk_segment segment; - // First we determine the root. Only windows roots can be longer than a single - // slash, so if we can determine that it starts with something like "C:", we - // know that this is a windows path. - cwk_path_get_root_windows(path, &root_length); - if (root_length > 1) { - return CWK_STYLE_WINDOWS; - } + // First we determine the root. Only windows roots can be longer than a single + // slash, so if we can determine that it starts with something like "C:", we + // know that this is a windows path. + cwk_path_get_root_windows(path, &root_length); + if (root_length > 1) { + return CWK_STYLE_WINDOWS; + } - // Next we check for slashes. Windows uses backslashes, while unix uses - // forward slashes. Windows actually supports both, but our best guess is to - // assume windows with backslashes and unix with forward slashes. - for (c = path; *c; ++c) { - if (*c == *separators[CWK_STYLE_UNIX]) { - return CWK_STYLE_UNIX; - } else if (*c == *separators[CWK_STYLE_WINDOWS]) { - return CWK_STYLE_WINDOWS; - } - } + // Next we check for slashes. Windows uses backslashes, while unix uses + // forward slashes. Windows actually supports both, but our best guess is to + // assume windows with backslashes and unix with forward slashes. + for (c = path; *c; ++c) { + if (*c == *separators[CWK_STYLE_UNIX]) { + return CWK_STYLE_UNIX; + } else if (*c == *separators[CWK_STYLE_WINDOWS]) { + return CWK_STYLE_WINDOWS; + } + } - // This path does not have any slashes. We grab the last segment (which - // actually must be the first one), and determine whether the segment starts - // with a dot. A dot is a hidden folder or file in the UNIX world, in that - // case we assume the path to have UNIX style. - if (!cwk_path_get_last_segment(path, &segment)) { - // We couldn't find any segments, so we default to a UNIX path style since - // there is no way to make any assumptions. - return CWK_STYLE_UNIX; - } + // This path does not have any slashes. We grab the last segment (which + // actually must be the first one), and determine whether the segment starts + // with a dot. A dot is a hidden folder or file in the UNIX world, in that + // case we assume the path to have UNIX style. + if (!cwk_path_get_last_segment(path, &segment)) { + // We couldn't find any segments, so we default to a UNIX path style since + // there is no way to make any assumptions. + return CWK_STYLE_UNIX; + } - if (*segment.begin == '.') { - return CWK_STYLE_UNIX; - } + if (*segment.begin == '.') { + return CWK_STYLE_UNIX; + } - // And finally we check whether the last segment contains a dot. If it - // contains a dot, that might be an extension. Windows is more likely to have - // file names with extensions, so our guess would be windows. - for (c = segment.begin; *c; ++c) { - if (*c == '.') { - return CWK_STYLE_WINDOWS; - } - } + // And finally we check whether the last segment contains a dot. If it + // contains a dot, that might be an extension. Windows is more likely to have + // file names with extensions, so our guess would be windows. + for (c = segment.begin; *c; ++c) { + if (*c == '.') { + return CWK_STYLE_WINDOWS; + } + } - // All our checks failed, so we will return a default value which is currently - // UNIX. - return CWK_STYLE_UNIX; + // All our checks failed, so we will return a default value which is currently + // UNIX. + return CWK_STYLE_UNIX; } void cwk_path_set_style(enum cwk_path_style style) { - // We can just set the global path style variable and then the behaviour for - // all functions will change accordingly. - assert(style == CWK_STYLE_UNIX || style == CWK_STYLE_WINDOWS); - path_style = style; + // We can just set the global path style variable and then the behaviour for + // all functions will change accordingly. + assert(style == CWK_STYLE_UNIX || style == CWK_STYLE_WINDOWS); + path_style = style; } enum cwk_path_style cwk_path_get_style(void) { - // Simply return the path style which we store in a global variable. - return path_style; + // Simply return the path style which we store in a global variable. + return path_style; } diff --git a/src/hdd/minivhd/libxml2_encoding.c b/src/hdd/minivhd/libxml2_encoding.c index 719b63db..154b6751 100644 --- a/src/hdd/minivhd/libxml2_encoding.c +++ b/src/hdd/minivhd/libxml2_encoding.c @@ -18,7 +18,7 @@ * daniel@veillard.com * * Original code for IsoLatin1 and UTF-16 by "Martin J. Duerst" - * + * * Adapted and abridged for MiniVHD by Sherman Perry */ #include @@ -27,13 +27,13 @@ static int xmlLittleEndian = 1; /* Note: extracted from original 'void xmlInitCharEncodingHandlers(void)' function */ void xmlEncodingInit(void) { - unsigned short int tst = 0x1234; - unsigned char *ptr = (unsigned char *)&tst; + unsigned short int tst = 0x1234; + unsigned char *ptr = (unsigned char *)&tst; - if (*ptr == 0x12) - xmlLittleEndian = 0; - else if (*ptr == 0x34) - xmlLittleEndian = 1; + if (*ptr == 0x12) + xmlLittleEndian = 0; + else if (*ptr == 0x34) + xmlLittleEndian = 1; } /** @@ -53,81 +53,80 @@ void xmlEncodingInit(void) { * The value of *inlen after return is the number of octets consumed * if the return value is positive, else unpredictable. */ -int UTF16LEToUTF8(unsigned char *out, int *outlen, - const unsigned char *inb, int *inlenb) { - unsigned char *outstart = out; - const unsigned char *processed = inb; - unsigned char *outend = out + *outlen; - unsigned short *in = (unsigned short *)inb; - unsigned short *inend; - unsigned int c, d, inlen; - unsigned char *tmp; - int bits; +int UTF16LEToUTF8(unsigned char *out, int *outlen, const unsigned char *inb, int *inlenb) { + unsigned char *outstart = out; + const unsigned char *processed = inb; + unsigned char *outend = out + *outlen; + unsigned short *in = (unsigned short *)inb; + unsigned short *inend; + unsigned int c, d, inlen; + unsigned char *tmp; + int bits; - if ((*inlenb % 2) == 1) - (*inlenb)--; - inlen = *inlenb / 2; - inend = in + inlen; - while ((in < inend) && (out - outstart + 5 < *outlen)) { - if (xmlLittleEndian) { - c = *in++; - } else { - tmp = (unsigned char *)in; - c = *tmp++; - c = c | (((unsigned int)*tmp) << 8); - in++; - } - if ((c & 0xFC00) == 0xD800) { /* surrogates */ - if (in >= inend) { /* (in > inend) shouldn't happens */ - break; - } - if (xmlLittleEndian) { - d = *in++; - } else { - tmp = (unsigned char *)in; - d = *tmp++; - d = d | (((unsigned int)*tmp) << 8); - in++; - } - if ((d & 0xFC00) == 0xDC00) { - c &= 0x03FF; - c <<= 10; - c |= d & 0x03FF; - c += 0x10000; - } else { - *outlen = out - outstart; - *inlenb = processed - inb; - return (-2); - } - } + if ((*inlenb % 2) == 1) + (*inlenb)--; + inlen = *inlenb / 2; + inend = in + inlen; + while ((in < inend) && (out - outstart + 5 < *outlen)) { + if (xmlLittleEndian) { + c = *in++; + } else { + tmp = (unsigned char *)in; + c = *tmp++; + c = c | (((unsigned int)*tmp) << 8); + in++; + } + if ((c & 0xFC00) == 0xD800) { /* surrogates */ + if (in >= inend) { /* (in > inend) shouldn't happens */ + break; + } + if (xmlLittleEndian) { + d = *in++; + } else { + tmp = (unsigned char *)in; + d = *tmp++; + d = d | (((unsigned int)*tmp) << 8); + in++; + } + if ((d & 0xFC00) == 0xDC00) { + c &= 0x03FF; + c <<= 10; + c |= d & 0x03FF; + c += 0x10000; + } else { + *outlen = out - outstart; + *inlenb = processed - inb; + return (-2); + } + } - /* assertion: c is a single UTF-4 value */ - if (out >= outend) - break; - if (c < 0x80) { - *out++ = c; - bits = -6; - } else if (c < 0x800) { - *out++ = ((c >> 6) & 0x1F) | 0xC0; - bits = 0; - } else if (c < 0x10000) { - *out++ = ((c >> 12) & 0x0F) | 0xE0; - bits = 6; - } else { - *out++ = ((c >> 18) & 0x07) | 0xF0; - bits = 12; - } + /* assertion: c is a single UTF-4 value */ + if (out >= outend) + break; + if (c < 0x80) { + *out++ = c; + bits = -6; + } else if (c < 0x800) { + *out++ = ((c >> 6) & 0x1F) | 0xC0; + bits = 0; + } else if (c < 0x10000) { + *out++ = ((c >> 12) & 0x0F) | 0xE0; + bits = 6; + } else { + *out++ = ((c >> 18) & 0x07) | 0xF0; + bits = 12; + } - for (; bits >= 0; bits -= 6) { - if (out >= outend) - break; - *out++ = ((c >> bits) & 0x3F) | 0x80; - } - processed = (const unsigned char *)in; - } - *outlen = out - outstart; - *inlenb = processed - inb; - return (*outlen); + for (; bits >= 0; bits -= 6) { + if (out >= outend) + break; + *out++ = ((c >> bits) & 0x3F) | 0x80; + } + processed = (const unsigned char *)in; + } + *outlen = out - outstart; + *inlenb = processed - inb; + return (*outlen); } /** @@ -143,105 +142,104 @@ int UTF16LEToUTF8(unsigned char *out, int *outlen, * Returns the number of bytes written, or -1 if lack of space, or -2 * if the transcoding failed. */ -int UTF8ToUTF16LE(unsigned char *outb, int *outlen, - const unsigned char *in, int *inlen) { - unsigned short *out = (unsigned short *)outb; - const unsigned char *processed = in; - const unsigned char *const instart = in; - unsigned short *outstart = out; - unsigned short *outend; - const unsigned char *inend; - unsigned int c, d; - int trailing; - unsigned char *tmp; - unsigned short tmp1, tmp2; +int UTF8ToUTF16LE(unsigned char *outb, int *outlen, const unsigned char *in, int *inlen) { + unsigned short *out = (unsigned short *)outb; + const unsigned char *processed = in; + const unsigned char *const instart = in; + unsigned short *outstart = out; + unsigned short *outend; + const unsigned char *inend; + unsigned int c, d; + int trailing; + unsigned char *tmp; + unsigned short tmp1, tmp2; - /* UTF16LE encoding has no BOM */ - if ((out == NULL) || (outlen == NULL) || (inlen == NULL)) - return (-1); - if (in == NULL) { - *outlen = 0; - *inlen = 0; - return (0); - } - inend = in + *inlen; - outend = out + (*outlen / 2); - while (in < inend) { - d = *in++; - if (d < 0x80) { - c = d; - trailing = 0; - } else if (d < 0xC0) { - /* trailing byte in leading position */ - *outlen = (out - outstart) * 2; - *inlen = processed - instart; - return (-2); - } else if (d < 0xE0) { - c = d & 0x1F; - trailing = 1; - } else if (d < 0xF0) { - c = d & 0x0F; - trailing = 2; - } else if (d < 0xF8) { - c = d & 0x07; - trailing = 3; - } else { - /* no chance for this in UTF-16 */ - *outlen = (out - outstart) * 2; - *inlen = processed - instart; - return (-2); - } + /* UTF16LE encoding has no BOM */ + if ((out == NULL) || (outlen == NULL) || (inlen == NULL)) + return (-1); + if (in == NULL) { + *outlen = 0; + *inlen = 0; + return (0); + } + inend = in + *inlen; + outend = out + (*outlen / 2); + while (in < inend) { + d = *in++; + if (d < 0x80) { + c = d; + trailing = 0; + } else if (d < 0xC0) { + /* trailing byte in leading position */ + *outlen = (out - outstart) * 2; + *inlen = processed - instart; + return (-2); + } else if (d < 0xE0) { + c = d & 0x1F; + trailing = 1; + } else if (d < 0xF0) { + c = d & 0x0F; + trailing = 2; + } else if (d < 0xF8) { + c = d & 0x07; + trailing = 3; + } else { + /* no chance for this in UTF-16 */ + *outlen = (out - outstart) * 2; + *inlen = processed - instart; + return (-2); + } - if (inend - in < trailing) { - break; - } + if (inend - in < trailing) { + break; + } - for (; trailing; trailing--) { - if ((in >= inend) || (((d = *in++) & 0xC0) != 0x80)) - break; - c <<= 6; - c |= d & 0x3F; - } + for (; trailing; trailing--) { + if ((in >= inend) || (((d = *in++) & 0xC0) != 0x80)) + break; + c <<= 6; + c |= d & 0x3F; + } - /* assertion: c is a single UTF-4 value */ - if (c < 0x10000) { - if (out >= outend) - break; - if (xmlLittleEndian) { - *out++ = c; - } else { - tmp = (unsigned char *)out; - *tmp = c; - *(tmp + 1) = c >> 8; - out++; - } - } else if (c < 0x110000) { - if (out + 1 >= outend) - break; - c -= 0x10000; - if (xmlLittleEndian) { - *out++ = 0xD800 | (c >> 10); - *out++ = 0xDC00 | (c & 0x03FF); - } else { - tmp1 = 0xD800 | (c >> 10); - tmp = (unsigned char *)out; - *tmp = (unsigned char)tmp1; - *(tmp + 1) = tmp1 >> 8; - out++; + /* assertion: c is a single UTF-4 value */ + if (c < 0x10000) { + if (out >= outend) + break; + if (xmlLittleEndian) { + *out++ = c; + } else { + tmp = (unsigned char *)out; + *tmp = c; + *(tmp + 1) = c >> 8; + out++; + } + } else if (c < 0x110000) { + if (out + 1 >= outend) + break; + c -= 0x10000; + if (xmlLittleEndian) { + *out++ = 0xD800 | (c >> 10); + *out++ = 0xDC00 | (c & 0x03FF); + } else { + tmp1 = 0xD800 | (c >> 10); + tmp = (unsigned char *)out; + *tmp = (unsigned char)tmp1; + *(tmp + 1) = tmp1 >> 8; + out++; - tmp2 = 0xDC00 | (c & 0x03FF); - tmp = (unsigned char *)out; - *tmp = (unsigned char)tmp2; - *(tmp + 1) = tmp2 >> 8; - out++; - } - } else - break; - processed = in; - } - *outlen = (out - outstart) * 2; - *inlen = processed - instart; - return (*outlen); + tmp2 = 0xDC00 | (c & 0x03FF); + tmp = (unsigned char *)out; + *tmp = (unsigned char)tmp2; + *(tmp + 1) = tmp2 >> 8; + out++; + } + } else + break; + processed = in; + } + *outlen = (out - outstart) * 2; + *inlen = processed - instart; + return (*outlen); } /** @@ -261,85 +259,84 @@ int UTF8ToUTF16LE(unsigned char *outb, int *outlen, * The value of *inlen after return is the number of octets consumed * if the return value is positive, else unpredictable. */ -int UTF16BEToUTF8(unsigned char *out, int *outlen, - const unsigned char *inb, int *inlenb) { - unsigned char *outstart = out; - const unsigned char *processed = inb; - unsigned char *outend = out + *outlen; - unsigned short *in = (unsigned short *)inb; - unsigned short *inend; - unsigned int c, d, inlen; - unsigned char *tmp; - int bits; +int UTF16BEToUTF8(unsigned char *out, int *outlen, const unsigned char *inb, int *inlenb) { + unsigned char *outstart = out; + const unsigned char *processed = inb; + unsigned char *outend = out + *outlen; + unsigned short *in = (unsigned short *)inb; + unsigned short *inend; + unsigned int c, d, inlen; + unsigned char *tmp; + int bits; - if ((*inlenb % 2) == 1) - (*inlenb)--; - inlen = *inlenb / 2; - inend = in + inlen; - while (in < inend) { - if (xmlLittleEndian) { - tmp = (unsigned char *)in; - c = *tmp++; - c = c << 8; - c = c | (unsigned int)*tmp; - in++; - } else { - c = *in++; - } - if ((c & 0xFC00) == 0xD800) { /* surrogates */ - if (in >= inend) { /* (in > inend) shouldn't happens */ - *outlen = out - outstart; - *inlenb = processed - inb; - return (-2); - } - if (xmlLittleEndian) { - tmp = (unsigned char *)in; - d = *tmp++; - d = d << 8; - d = d | (unsigned int)*tmp; - in++; - } else { - d = *in++; - } - if ((d & 0xFC00) == 0xDC00) { - c &= 0x03FF; - c <<= 10; - c |= d & 0x03FF; - c += 0x10000; - } else { - *outlen = out - outstart; - *inlenb = processed - inb; - return (-2); - } - } + if ((*inlenb % 2) == 1) + (*inlenb)--; + inlen = *inlenb / 2; + inend = in + inlen; + while (in < inend) { + if (xmlLittleEndian) { + tmp = (unsigned char *)in; + c = *tmp++; + c = c << 8; + c = c | (unsigned int)*tmp; + in++; + } else { + c = *in++; + } + if ((c & 0xFC00) == 0xD800) { /* surrogates */ + if (in >= inend) { /* (in > inend) shouldn't happens */ + *outlen = out - outstart; + *inlenb = processed - inb; + return (-2); + } + if (xmlLittleEndian) { + tmp = (unsigned char *)in; + d = *tmp++; + d = d << 8; + d = d | (unsigned int)*tmp; + in++; + } else { + d = *in++; + } + if ((d & 0xFC00) == 0xDC00) { + c &= 0x03FF; + c <<= 10; + c |= d & 0x03FF; + c += 0x10000; + } else { + *outlen = out - outstart; + *inlenb = processed - inb; + return (-2); + } + } - /* assertion: c is a single UTF-4 value */ - if (out >= outend) - break; - if (c < 0x80) { - *out++ = c; - bits = -6; - } else if (c < 0x800) { - *out++ = ((c >> 6) & 0x1F) | 0xC0; - bits = 0; - } else if (c < 0x10000) { - *out++ = ((c >> 12) & 0x0F) | 0xE0; - bits = 6; - } else { - *out++ = ((c >> 18) & 0x07) | 0xF0; - bits = 12; - } + /* assertion: c is a single UTF-4 value */ + if (out >= outend) + break; + if (c < 0x80) { + *out++ = c; + bits = -6; + } else if (c < 0x800) { + *out++ = ((c >> 6) & 0x1F) | 0xC0; + bits = 0; + } else if (c < 0x10000) { + *out++ = ((c >> 12) & 0x0F) | 0xE0; + bits = 6; + } else { + *out++ = ((c >> 18) & 0x07) | 0xF0; + bits = 12; + } - for (; bits >= 0; bits -= 6) { - if (out >= outend) - break; - *out++ = ((c >> bits) & 0x3F) | 0x80; - } - processed = (const unsigned char *)in; - } - *outlen = out - outstart; - *inlenb = processed - inb; - return (*outlen); + for (; bits >= 0; bits -= 6) { + if (out >= outend) + break; + *out++ = ((c >> bits) & 0x3F) | 0x80; + } + processed = (const unsigned char *)in; + } + *outlen = out - outstart; + *inlenb = processed - inb; + return (*outlen); } /** @@ -355,108 +352,107 @@ int UTF16BEToUTF8(unsigned char *out, int *outlen, * Returns the number of byte written, or -1 by lack of space, or -2 * if the transcoding failed. */ -int UTF8ToUTF16BE(unsigned char *outb, int *outlen, - const unsigned char *in, int *inlen) { - unsigned short *out = (unsigned short *)outb; - const unsigned char *processed = in; - const unsigned char *const instart = in; - unsigned short *outstart = out; - unsigned short *outend; - const unsigned char *inend; - unsigned int c, d; - int trailing; - unsigned char *tmp; - unsigned short tmp1, tmp2; +int UTF8ToUTF16BE(unsigned char *outb, int *outlen, const unsigned char *in, int *inlen) { + unsigned short *out = (unsigned short *)outb; + const unsigned char *processed = in; + const unsigned char *const instart = in; + unsigned short *outstart = out; + unsigned short *outend; + const unsigned char *inend; + unsigned int c, d; + int trailing; + unsigned char *tmp; + unsigned short tmp1, tmp2; - /* UTF-16BE has no BOM */ - if ((outb == NULL) || (outlen == NULL) || (inlen == NULL)) - return (-1); - if (in == NULL) { - *outlen = 0; - *inlen = 0; - return (0); - } - inend = in + *inlen; - outend = out + (*outlen / 2); - while (in < inend) { - d = *in++; - if (d < 0x80) { - c = d; - trailing = 0; - } else if (d < 0xC0) { - /* trailing byte in leading position */ - *outlen = out - outstart; - *inlen = processed - instart; - return (-2); - } else if (d < 0xE0) { - c = d & 0x1F; - trailing = 1; - } else if (d < 0xF0) { - c = d & 0x0F; - trailing = 2; - } else if (d < 0xF8) { - c = d & 0x07; - trailing = 3; - } else { - /* no chance for this in UTF-16 */ - *outlen = out - outstart; - *inlen = processed - instart; - return (-2); - } + /* UTF-16BE has no BOM */ + if ((outb == NULL) || (outlen == NULL) || (inlen == NULL)) + return (-1); + if (in == NULL) { + *outlen = 0; + *inlen = 0; + return (0); + } + inend = in + *inlen; + outend = out + (*outlen / 2); + while (in < inend) { + d = *in++; + if (d < 0x80) { + c = d; + trailing = 0; + } else if (d < 0xC0) { + /* trailing byte in leading position */ + *outlen = out - outstart; + *inlen = processed - instart; + return (-2); + } else if (d < 0xE0) { + c = d & 0x1F; + trailing = 1; + } else if (d < 0xF0) { + c = d & 0x0F; + trailing = 2; + } else if (d < 0xF8) { + c = d & 0x07; + trailing = 3; + } else { + /* no chance for this in UTF-16 */ + *outlen = out - outstart; + *inlen = processed - instart; + return (-2); + } - if (inend - in < trailing) { - break; - } + if (inend - in < trailing) { + break; + } - for (; trailing; trailing--) { - if ((in >= inend) || (((d = *in++) & 0xC0) != 0x80)) - break; - c <<= 6; - c |= d & 0x3F; - } + for (; trailing; trailing--) { + if ((in >= inend) || (((d = *in++) & 0xC0) != 0x80)) + break; + c <<= 6; + c |= d & 0x3F; + } - /* assertion: c is a single UTF-4 value */ - if (c < 0x10000) { - if (out >= outend) - break; - if (xmlLittleEndian) { - tmp = (unsigned char *)out; - *tmp = c >> 8; - *(tmp + 1) = c; - out++; - } else { - *out++ = c; - } - } else if (c < 0x110000) { - if (out + 1 >= outend) - break; - c -= 0x10000; - if (xmlLittleEndian) { - tmp1 = 0xD800 | (c >> 10); - tmp = (unsigned char *)out; - *tmp = tmp1 >> 8; - *(tmp + 1) = (unsigned char)tmp1; - out++; + /* assertion: c is a single UTF-4 value */ + if (c < 0x10000) { + if (out >= outend) + break; + if (xmlLittleEndian) { + tmp = (unsigned char *)out; + *tmp = c >> 8; + *(tmp + 1) = c; + out++; + } else { + *out++ = c; + } + } else if (c < 0x110000) { + if (out + 1 >= outend) + break; + c -= 0x10000; + if (xmlLittleEndian) { + tmp1 = 0xD800 | (c >> 10); + tmp = (unsigned char *)out; + *tmp = tmp1 >> 8; + *(tmp + 1) = (unsigned char)tmp1; + out++; - tmp2 = 0xDC00 | (c & 0x03FF); - tmp = (unsigned char *)out; - *tmp = tmp2 >> 8; - *(tmp + 1) = (unsigned char)tmp2; - out++; - } else { - *out++ = 0xD800 | (c >> 10); - *out++ = 0xDC00 | (c & 0x03FF); - } - } else - break; - processed = in; - } - *outlen = (out - outstart) * 2; - *inlen = processed - instart; - return (*outlen); + tmp2 = 0xDC00 | (c & 0x03FF); + tmp = (unsigned char *)out; + *tmp = tmp2 >> 8; + *(tmp + 1) = (unsigned char)tmp2; + out++; + } else { + *out++ = 0xD800 | (c >> 10); + *out++ = 0xDC00 | (c & 0x03FF); + } + } else + break; + processed = in; + } + *outlen = (out - outstart) * 2; + *inlen = processed - instart; + return (*outlen); } -/* This file is licenced under the MIT licence as follows: +/* This file is licenced under the MIT licence as follows: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/hdd/minivhd/minivhd_convert.c b/src/hdd/minivhd/minivhd_convert.c index b968dac7..55b8fec5 100644 --- a/src/hdd/minivhd/minivhd_convert.c +++ b/src/hdd/minivhd/minivhd_convert.c @@ -14,95 +14,95 @@ static FILE *mvhd_open_existing_raw_img(const char *utf8_raw_path, MVHDGeom *geom, int *err); static FILE *mvhd_open_existing_raw_img(const char *utf8_raw_path, MVHDGeom *geom, int *err) { - FILE *raw_img = mvhd_fopen(utf8_raw_path, "rb", err); - if (raw_img == NULL) { - *err = MVHD_ERR_FILE; - return NULL; - } - if (geom == NULL) { - *err = MVHD_ERR_INVALID_GEOM; - return NULL; - } - mvhd_fseeko64(raw_img, 0, SEEK_END); - uint64_t size_bytes = (uint64_t)mvhd_ftello64(raw_img); - MVHDGeom new_geom = mvhd_calculate_geometry(size_bytes); - if (mvhd_calc_size_bytes(&new_geom) != size_bytes) { - *err = MVHD_ERR_CONV_SIZE; - return NULL; - } - geom->cyl = new_geom.cyl; - geom->heads = new_geom.heads; - geom->spt = new_geom.spt; - mvhd_fseeko64(raw_img, 0, SEEK_SET); - return raw_img; + FILE *raw_img = mvhd_fopen(utf8_raw_path, "rb", err); + if (raw_img == NULL) { + *err = MVHD_ERR_FILE; + return NULL; + } + if (geom == NULL) { + *err = MVHD_ERR_INVALID_GEOM; + return NULL; + } + mvhd_fseeko64(raw_img, 0, SEEK_END); + uint64_t size_bytes = (uint64_t)mvhd_ftello64(raw_img); + MVHDGeom new_geom = mvhd_calculate_geometry(size_bytes); + if (mvhd_calc_size_bytes(&new_geom) != size_bytes) { + *err = MVHD_ERR_CONV_SIZE; + return NULL; + } + geom->cyl = new_geom.cyl; + geom->heads = new_geom.heads; + geom->spt = new_geom.spt; + mvhd_fseeko64(raw_img, 0, SEEK_SET); + return raw_img; } MVHDMeta *mvhd_convert_to_vhd_fixed(const char *utf8_raw_path, const char *utf8_vhd_path, int *err) { - MVHDGeom geom; - FILE *raw_img = mvhd_open_existing_raw_img(utf8_raw_path, &geom, err); - if (raw_img == NULL) { - return NULL; - } - uint64_t size_in_bytes = mvhd_calc_size_bytes(&geom); - MVHDMeta *vhdm = mvhd_create_fixed_raw(utf8_vhd_path, raw_img, size_in_bytes, &geom, err, NULL); - if (vhdm == NULL) { - return NULL; - } - return vhdm; + MVHDGeom geom; + FILE *raw_img = mvhd_open_existing_raw_img(utf8_raw_path, &geom, err); + if (raw_img == NULL) { + return NULL; + } + uint64_t size_in_bytes = mvhd_calc_size_bytes(&geom); + MVHDMeta *vhdm = mvhd_create_fixed_raw(utf8_vhd_path, raw_img, size_in_bytes, &geom, err, NULL); + if (vhdm == NULL) { + return NULL; + } + return vhdm; } MVHDMeta *mvhd_convert_to_vhd_sparse(const char *utf8_raw_path, const char *utf8_vhd_path, int *err) { - MVHDGeom geom; - MVHDMeta *vhdm = NULL; - FILE *raw_img = mvhd_open_existing_raw_img(utf8_raw_path, &geom, err); - if (raw_img == NULL) { - return NULL; - } - vhdm = mvhd_create_sparse(utf8_vhd_path, geom, err); - if (vhdm == NULL) { - goto end; - } - uint8_t buff[4096] = {0}; // 8 sectors - uint8_t empty_buff[4096] = {0}; - int total_sectors = mvhd_calc_size_sectors(&geom); - int copy_sect = 0, i; - for (i = 0; i < total_sectors; i += 8) { - copy_sect = 8; - if ((i + 8) >= total_sectors) { - copy_sect = total_sectors - i; - memset(buff, 0, sizeof buff); - } - fread(buff, MVHD_SECTOR_SIZE, copy_sect, raw_img); - /* Only write data if there's data to write, to take advantage of the sparse VHD format */ - if (memcmp(buff, empty_buff, sizeof buff) != 0) { - mvhd_write_sectors(vhdm, i, copy_sect, buff); - } - } - end: - fclose(raw_img); - return vhdm; + MVHDGeom geom; + MVHDMeta *vhdm = NULL; + FILE *raw_img = mvhd_open_existing_raw_img(utf8_raw_path, &geom, err); + if (raw_img == NULL) { + return NULL; + } + vhdm = mvhd_create_sparse(utf8_vhd_path, geom, err); + if (vhdm == NULL) { + goto end; + } + uint8_t buff[4096] = {0}; // 8 sectors + uint8_t empty_buff[4096] = {0}; + int total_sectors = mvhd_calc_size_sectors(&geom); + int copy_sect = 0, i; + for (i = 0; i < total_sectors; i += 8) { + copy_sect = 8; + if ((i + 8) >= total_sectors) { + copy_sect = total_sectors - i; + memset(buff, 0, sizeof buff); + } + fread(buff, MVHD_SECTOR_SIZE, copy_sect, raw_img); + /* Only write data if there's data to write, to take advantage of the sparse VHD format */ + if (memcmp(buff, empty_buff, sizeof buff) != 0) { + mvhd_write_sectors(vhdm, i, copy_sect, buff); + } + } +end: + fclose(raw_img); + return vhdm; } FILE *mvhd_convert_to_raw(const char *utf8_vhd_path, const char *utf8_raw_path, int *err) { - FILE *raw_img = mvhd_fopen(utf8_raw_path, "wb", err); - if (raw_img == NULL) { - return NULL; - } - MVHDMeta *vhdm = mvhd_open(utf8_vhd_path, true, err); - if (vhdm == NULL) { - fclose(raw_img); - return NULL; - } - uint8_t buff[4096] = {0}; // 8 sectors - int total_sectors = mvhd_calc_size_sectors((MVHDGeom *)&vhdm->footer.geom); - int copy_sect = 0, i; - for (i = 0; i < total_sectors; i += 8) { - copy_sect = 8; - if ((i + 8) >= total_sectors) { - copy_sect = total_sectors - i; - } - mvhd_read_sectors(vhdm, i, copy_sect, buff); - fwrite(buff, MVHD_SECTOR_SIZE, copy_sect, raw_img); - } - mvhd_close(vhdm); - mvhd_fseeko64(raw_img, 0, SEEK_SET); - return raw_img; + FILE *raw_img = mvhd_fopen(utf8_raw_path, "wb", err); + if (raw_img == NULL) { + return NULL; + } + MVHDMeta *vhdm = mvhd_open(utf8_vhd_path, true, err); + if (vhdm == NULL) { + fclose(raw_img); + return NULL; + } + uint8_t buff[4096] = {0}; // 8 sectors + int total_sectors = mvhd_calc_size_sectors((MVHDGeom *)&vhdm->footer.geom); + int copy_sect = 0, i; + for (i = 0; i < total_sectors; i += 8) { + copy_sect = 8; + if ((i + 8) >= total_sectors) { + copy_sect = total_sectors - i; + } + mvhd_read_sectors(vhdm, i, copy_sect, buff); + fwrite(buff, MVHD_SECTOR_SIZE, copy_sect, raw_img); + } + mvhd_close(vhdm); + mvhd_fseeko64(raw_img, 0, SEEK_SET); + return raw_img; } diff --git a/src/hdd/minivhd/minivhd_create.c b/src/hdd/minivhd/minivhd_create.c index ac9e6396..5e86ab8b 100644 --- a/src/hdd/minivhd/minivhd_create.c +++ b/src/hdd/minivhd/minivhd_create.c @@ -15,461 +15,468 @@ #include "minivhd/minivhd_create.h" #include "minivhd/minivhd.h" -static void mvhd_gen_footer(MVHDFooter *footer, uint64_t size_in_bytes, MVHDGeom *geom, MVHDType type, uint64_t sparse_header_off); -static void mvhd_gen_sparse_header(MVHDSparseHeader *header, uint32_t num_blks, uint64_t bat_offset, uint32_t block_size_in_sectors); -static int mvhd_gen_par_loc(MVHDSparseHeader *header, - const char *child_path, - const char *par_path, - uint64_t start_offset, - mvhd_utf16 *w2ku_path_buff, - mvhd_utf16 *w2ru_path_buff, - MVHDError *err); -static MVHDMeta *mvhd_create_sparse_diff(const char *path, const char *par_path, uint64_t size_in_bytes, MVHDGeom *geom, uint32_t block_size_in_sectors, int *err); +static void mvhd_gen_footer(MVHDFooter *footer, uint64_t size_in_bytes, MVHDGeom *geom, MVHDType type, + uint64_t sparse_header_off); +static void mvhd_gen_sparse_header(MVHDSparseHeader *header, uint32_t num_blks, uint64_t bat_offset, + uint32_t block_size_in_sectors); +static int mvhd_gen_par_loc(MVHDSparseHeader *header, const char *child_path, const char *par_path, uint64_t start_offset, + mvhd_utf16 *w2ku_path_buff, mvhd_utf16 *w2ru_path_buff, MVHDError *err); +static MVHDMeta *mvhd_create_sparse_diff(const char *path, const char *par_path, uint64_t size_in_bytes, MVHDGeom *geom, + uint32_t block_size_in_sectors, int *err); /** * \brief Populate a VHD footer - * + * * \param [in] footer to populate * \param [in] size_in_bytes is the total size of the virtual hard disk in bytes * \param [in] geom to use * \param [in] type of HVD that is being created * \param [in] sparse_header_off, an absolute file offset to the sparse header. Not used for fixed VHD images */ -static void mvhd_gen_footer(MVHDFooter *footer, uint64_t size_in_bytes, MVHDGeom *geom, MVHDType type, uint64_t sparse_header_off) { - memcpy(footer->cookie, "conectix", sizeof footer->cookie); - footer->features = 0x00000002; - footer->fi_fmt_vers = 0x00010000; - footer->data_offset = (type == MVHD_TYPE_DIFF || type == MVHD_TYPE_DYNAMIC) ? sparse_header_off : 0xffffffffffffffff; - footer->timestamp = vhd_calc_timestamp(); - memcpy(footer->cr_app, "mvhd", sizeof footer->cr_app); - footer->cr_vers = 0x000e0000; - memcpy(footer->cr_host_os, "Wi2k", sizeof footer->cr_host_os); - footer->orig_sz = footer->curr_sz = size_in_bytes; - footer->geom.cyl = geom->cyl; - footer->geom.heads = geom->heads; - footer->geom.spt = geom->spt; - footer->disk_type = type; - mvhd_generate_uuid(footer->uuid); - footer->checksum = mvhd_gen_footer_checksum(footer); +static void mvhd_gen_footer(MVHDFooter *footer, uint64_t size_in_bytes, MVHDGeom *geom, MVHDType type, + uint64_t sparse_header_off) { + memcpy(footer->cookie, "conectix", sizeof footer->cookie); + footer->features = 0x00000002; + footer->fi_fmt_vers = 0x00010000; + footer->data_offset = (type == MVHD_TYPE_DIFF || type == MVHD_TYPE_DYNAMIC) ? sparse_header_off : 0xffffffffffffffff; + footer->timestamp = vhd_calc_timestamp(); + memcpy(footer->cr_app, "mvhd", sizeof footer->cr_app); + footer->cr_vers = 0x000e0000; + memcpy(footer->cr_host_os, "Wi2k", sizeof footer->cr_host_os); + footer->orig_sz = footer->curr_sz = size_in_bytes; + footer->geom.cyl = geom->cyl; + footer->geom.heads = geom->heads; + footer->geom.spt = geom->spt; + footer->disk_type = type; + mvhd_generate_uuid(footer->uuid); + footer->checksum = mvhd_gen_footer_checksum(footer); } /** * \brief Populate a VHD sparse header - * + * * \param [in] header for sparse and differencing images * \param [in] num_blks is the number of data blocks that the image contains * \param [in] bat_offset is the absolute file offset for start of the Block Allocation Table * \param [in] block_size_in_sectors is the block size in sectors. */ -static void mvhd_gen_sparse_header(MVHDSparseHeader *header, uint32_t num_blks, uint64_t bat_offset, uint32_t block_size_in_sectors) { - memcpy(header->cookie, "cxsparse", sizeof header->cookie); - header->data_offset = 0xffffffffffffffff; - header->bat_offset = bat_offset; - header->head_vers = 0x00010000; - header->max_bat_ent = num_blks; - header->block_sz = block_size_in_sectors * (uint32_t)MVHD_SECTOR_SIZE; - header->checksum = mvhd_gen_sparse_checksum(header); +static void mvhd_gen_sparse_header(MVHDSparseHeader *header, uint32_t num_blks, uint64_t bat_offset, + uint32_t block_size_in_sectors) { + memcpy(header->cookie, "cxsparse", sizeof header->cookie); + header->data_offset = 0xffffffffffffffff; + header->bat_offset = bat_offset; + header->head_vers = 0x00010000; + header->max_bat_ent = num_blks; + header->block_sz = block_size_in_sectors * (uint32_t)MVHD_SECTOR_SIZE; + header->checksum = mvhd_gen_sparse_checksum(header); } /** * \brief Generate parent locators for differencing VHD images - * + * * \param [in] header the sparse header to populate with parent locator entries * \param [in] child_path is the full path to the VHD being created * \param [in] par_path is the full path to the parent image - * \param [in] start_offset is the absolute file offset from where to start storing the entries themselves. Must be sector aligned. - * \param [out] w2ku_path_buff is a buffer containing the full path to the parent, encoded as UTF16-LE - * \param [out] w2ru_path_buff is a buffer containing the relative path to the parent, encoded as UTF16-LE - * \param [out] err indicates what error occurred, if any - * + * \param [in] start_offset is the absolute file offset from where to start storing the entries themselves. Must be sector + * aligned. \param [out] w2ku_path_buff is a buffer containing the full path to the parent, encoded as UTF16-LE \param [out] + * w2ru_path_buff is a buffer containing the relative path to the parent, encoded as UTF16-LE \param [out] err indicates what + * error occurred, if any + * * \retval 0 if success * \retval < 0 if an error occurrs. Check value of *err for actual error */ -static int mvhd_gen_par_loc(MVHDSparseHeader *header, - const char *child_path, - const char *par_path, - uint64_t start_offset, - mvhd_utf16 *w2ku_path_buff, - mvhd_utf16 *w2ru_path_buff, - MVHDError *err) { - /* Get our paths to store in the differencing VHD. We want both the absolute path to the parent, - as well as the relative path from the child VHD */ - int rv = 0; - char *par_filename; - size_t par_fn_len; - char rel_path[MVHD_MAX_PATH_BYTES] = {0}; - char child_dir[MVHD_MAX_PATH_BYTES] = {0}; - size_t child_dir_len; - if (strlen(child_path) < sizeof child_dir) { - strcpy(child_dir, child_path); - } else { - *err = MVHD_ERR_PATH_LEN; - rv = -1; - goto end; - } - cwk_path_get_basename(par_path, (const char **)&par_filename, &par_fn_len); - cwk_path_get_dirname(child_dir, &child_dir_len); - child_dir[child_dir_len] = '\0'; - size_t rel_len = cwk_path_get_relative(child_dir, par_path, rel_path, sizeof rel_path); - if (rel_len > sizeof rel_path) { - *err = MVHD_ERR_PATH_LEN; - rv = -1; - goto end; - } - /* We have our paths, now store the parent filename directly in the sparse header. */ - int outlen = sizeof header->par_utf16_name; - int utf_ret; - utf_ret = UTF8ToUTF16BE((unsigned char *)header->par_utf16_name, &outlen, (const unsigned char *)par_filename, (int *)&par_fn_len); - if (utf_ret < 0) { - mvhd_set_encoding_err(utf_ret, (int *)err); - rv = -1; - goto end; - } +static int mvhd_gen_par_loc(MVHDSparseHeader *header, const char *child_path, const char *par_path, uint64_t start_offset, + mvhd_utf16 *w2ku_path_buff, mvhd_utf16 *w2ru_path_buff, MVHDError *err) { + /* Get our paths to store in the differencing VHD. We want both the absolute path to the parent, + as well as the relative path from the child VHD */ + int rv = 0; + char *par_filename; + size_t par_fn_len; + char rel_path[MVHD_MAX_PATH_BYTES] = {0}; + char child_dir[MVHD_MAX_PATH_BYTES] = {0}; + size_t child_dir_len; + if (strlen(child_path) < sizeof child_dir) { + strcpy(child_dir, child_path); + } else { + *err = MVHD_ERR_PATH_LEN; + rv = -1; + goto end; + } + cwk_path_get_basename(par_path, (const char **)&par_filename, &par_fn_len); + cwk_path_get_dirname(child_dir, &child_dir_len); + child_dir[child_dir_len] = '\0'; + size_t rel_len = cwk_path_get_relative(child_dir, par_path, rel_path, sizeof rel_path); + if (rel_len > sizeof rel_path) { + *err = MVHD_ERR_PATH_LEN; + rv = -1; + goto end; + } + /* We have our paths, now store the parent filename directly in the sparse header. */ + int outlen = sizeof header->par_utf16_name; + int utf_ret; + utf_ret = UTF8ToUTF16BE((unsigned char *)header->par_utf16_name, &outlen, (const unsigned char *)par_filename, + (int *)&par_fn_len); + if (utf_ret < 0) { + mvhd_set_encoding_err(utf_ret, (int *)err); + rv = -1; + goto end; + } - /* And encode the paths to UTF16-LE */ - size_t par_path_len = strlen(par_path); - outlen = sizeof *w2ku_path_buff * MVHD_MAX_PATH_CHARS; - utf_ret = UTF8ToUTF16LE((unsigned char *)w2ku_path_buff, &outlen, (const unsigned char *)par_path, (int *)&par_path_len); - if (utf_ret < 0) { - mvhd_set_encoding_err(utf_ret, (int *)err); - rv = -1; - goto end; - } - int w2ku_len = utf_ret; - outlen = sizeof *w2ru_path_buff * MVHD_MAX_PATH_CHARS; - utf_ret = UTF8ToUTF16LE((unsigned char *)w2ru_path_buff, &outlen, (const unsigned char *)rel_path, (int *)&rel_len); - if (utf_ret < 0) { - mvhd_set_encoding_err(utf_ret, (int *)err); - rv = -1; - goto end; - } - int w2ru_len = utf_ret; - /** - * Finally populate the parent locaters in the sparse header. - * This is the information needed to find the paths saved elsewhere - * in the VHD image - */ + /* And encode the paths to UTF16-LE */ + size_t par_path_len = strlen(par_path); + outlen = sizeof *w2ku_path_buff * MVHD_MAX_PATH_CHARS; + utf_ret = UTF8ToUTF16LE((unsigned char *)w2ku_path_buff, &outlen, (const unsigned char *)par_path, (int *)&par_path_len); + if (utf_ret < 0) { + mvhd_set_encoding_err(utf_ret, (int *)err); + rv = -1; + goto end; + } + int w2ku_len = utf_ret; + outlen = sizeof *w2ru_path_buff * MVHD_MAX_PATH_CHARS; + utf_ret = UTF8ToUTF16LE((unsigned char *)w2ru_path_buff, &outlen, (const unsigned char *)rel_path, (int *)&rel_len); + if (utf_ret < 0) { + mvhd_set_encoding_err(utf_ret, (int *)err); + rv = -1; + goto end; + } + int w2ru_len = utf_ret; + /** + * Finally populate the parent locaters in the sparse header. + * This is the information needed to find the paths saved elsewhere + * in the VHD image + */ - /* Note about the plat_data_space field: The VHD spec says this field stores the number of sectors needed to store the locator path. - * However, Hyper-V and VPC store the number of bytes, not the number of sectors, and will refuse to open VHDs which have the - * number of sectors in this field. - * See https://stackoverflow.com/questions/40760181/mistake-in-virtual-hard-disk-image-format-specification - */ - header->par_loc_entry[0].plat_code = MVHD_DIF_LOC_W2KU; - header->par_loc_entry[0].plat_data_len = (uint32_t)w2ku_len; - header->par_loc_entry[0].plat_data_offset = (uint64_t)start_offset; - header->par_loc_entry[0].plat_data_space = ((header->par_loc_entry[0].plat_data_len / MVHD_SECTOR_SIZE) + 1) * MVHD_SECTOR_SIZE; - header->par_loc_entry[1].plat_code = MVHD_DIF_LOC_W2RU; - header->par_loc_entry[1].plat_data_len = (uint32_t)w2ru_len; - header->par_loc_entry[1].plat_data_offset = (uint64_t)start_offset + ((uint64_t)header->par_loc_entry[0].plat_data_space); - header->par_loc_entry[1].plat_data_space = ((header->par_loc_entry[1].plat_data_len / MVHD_SECTOR_SIZE) + 1) * MVHD_SECTOR_SIZE; - goto end; + /* Note about the plat_data_space field: The VHD spec says this field stores the number of sectors needed to store the + * locator path. However, Hyper-V and VPC store the number of bytes, not the number of sectors, and will refuse to open + * VHDs which have the number of sectors in this field. See + * https://stackoverflow.com/questions/40760181/mistake-in-virtual-hard-disk-image-format-specification + */ + header->par_loc_entry[0].plat_code = MVHD_DIF_LOC_W2KU; + header->par_loc_entry[0].plat_data_len = (uint32_t)w2ku_len; + header->par_loc_entry[0].plat_data_offset = (uint64_t)start_offset; + header->par_loc_entry[0].plat_data_space = + ((header->par_loc_entry[0].plat_data_len / MVHD_SECTOR_SIZE) + 1) * MVHD_SECTOR_SIZE; + header->par_loc_entry[1].plat_code = MVHD_DIF_LOC_W2RU; + header->par_loc_entry[1].plat_data_len = (uint32_t)w2ru_len; + header->par_loc_entry[1].plat_data_offset = (uint64_t)start_offset + ((uint64_t)header->par_loc_entry[0].plat_data_space); + header->par_loc_entry[1].plat_data_space = + ((header->par_loc_entry[1].plat_data_len / MVHD_SECTOR_SIZE) + 1) * MVHD_SECTOR_SIZE; + goto end; - end: - return rv; +end: + return rv; } MVHDMeta *mvhd_create_fixed(const char *path, MVHDGeom geom, int *err, mvhd_progress_callback progress_callback) { - uint64_t size_in_bytes = mvhd_calc_size_bytes(&geom); - return mvhd_create_fixed_raw(path, NULL, size_in_bytes, &geom, err, progress_callback); + uint64_t size_in_bytes = mvhd_calc_size_bytes(&geom); + return mvhd_create_fixed_raw(path, NULL, size_in_bytes, &geom, err, progress_callback); } /** * \brief internal function that implements public mvhd_create_fixed() functionality - * + * * Contains one more parameter than the public function, to allow using an existing * raw disk image as the data source for the new fixed VHD. - * + * * \param [in] raw_image file handle to a raw disk image to populate VHD */ -MVHDMeta *mvhd_create_fixed_raw(const char *path, FILE *raw_img, uint64_t size_in_bytes, MVHDGeom *geom, int *err, mvhd_progress_callback progress_callback) { - uint8_t img_data[MVHD_SECTOR_SIZE] = {0}; - uint8_t footer_buff[MVHD_FOOTER_SIZE] = {0}; - MVHDMeta *vhdm = calloc(1, sizeof *vhdm); - if (vhdm == NULL) { - *err = MVHD_ERR_MEM; - goto end; - } - if (geom == NULL || (geom->cyl == 0 || geom->heads == 0 || geom->spt == 0)) { - *err = MVHD_ERR_INVALID_GEOM; - goto cleanup_vhdm; - } - FILE *f = mvhd_fopen(path, "wb+", err); - if (f == NULL) { - goto cleanup_vhdm; - } - mvhd_fseeko64(f, 0, SEEK_SET); - uint32_t size_sectors = (uint32_t)(size_in_bytes / MVHD_SECTOR_SIZE); - uint32_t s; - if (progress_callback) - progress_callback(0, size_sectors); - if (raw_img != NULL) { - mvhd_fseeko64(raw_img, 0, SEEK_END); - uint64_t raw_size = (uint64_t)mvhd_ftello64(raw_img); - MVHDGeom raw_geom = mvhd_calculate_geometry(raw_size); - if (mvhd_calc_size_bytes(&raw_geom) != raw_size) { - *err = MVHD_ERR_CONV_SIZE; - goto cleanup_vhdm; - } - mvhd_gen_footer(&vhdm->footer, raw_size, geom, MVHD_TYPE_FIXED, 0); - mvhd_fseeko64(raw_img, 0, SEEK_SET); - for (s = 0; s < size_sectors; s++) { - fread(img_data, sizeof img_data, 1, raw_img); - fwrite(img_data, sizeof img_data, 1, f); - if (progress_callback) - progress_callback(s + 1, size_sectors); - } - } else { - mvhd_gen_footer(&vhdm->footer, size_in_bytes, geom, MVHD_TYPE_FIXED, 0); - for (s = 0; s < size_sectors; s++) { - fwrite(img_data, sizeof img_data, 1, f); - if (progress_callback) - progress_callback(s + 1, size_sectors); - } - } - mvhd_footer_to_buffer(&vhdm->footer, footer_buff); - fwrite(footer_buff, sizeof footer_buff, 1, f); - fclose(f); - f = NULL; - free(vhdm); - vhdm = mvhd_open(path, false, err); - goto end; +MVHDMeta *mvhd_create_fixed_raw(const char *path, FILE *raw_img, uint64_t size_in_bytes, MVHDGeom *geom, int *err, + mvhd_progress_callback progress_callback) { + uint8_t img_data[MVHD_SECTOR_SIZE] = {0}; + uint8_t footer_buff[MVHD_FOOTER_SIZE] = {0}; + MVHDMeta *vhdm = calloc(1, sizeof *vhdm); + if (vhdm == NULL) { + *err = MVHD_ERR_MEM; + goto end; + } + if (geom == NULL || (geom->cyl == 0 || geom->heads == 0 || geom->spt == 0)) { + *err = MVHD_ERR_INVALID_GEOM; + goto cleanup_vhdm; + } + FILE *f = mvhd_fopen(path, "wb+", err); + if (f == NULL) { + goto cleanup_vhdm; + } + mvhd_fseeko64(f, 0, SEEK_SET); + uint32_t size_sectors = (uint32_t)(size_in_bytes / MVHD_SECTOR_SIZE); + uint32_t s; + if (progress_callback) + progress_callback(0, size_sectors); + if (raw_img != NULL) { + mvhd_fseeko64(raw_img, 0, SEEK_END); + uint64_t raw_size = (uint64_t)mvhd_ftello64(raw_img); + MVHDGeom raw_geom = mvhd_calculate_geometry(raw_size); + if (mvhd_calc_size_bytes(&raw_geom) != raw_size) { + *err = MVHD_ERR_CONV_SIZE; + goto cleanup_vhdm; + } + mvhd_gen_footer(&vhdm->footer, raw_size, geom, MVHD_TYPE_FIXED, 0); + mvhd_fseeko64(raw_img, 0, SEEK_SET); + for (s = 0; s < size_sectors; s++) { + fread(img_data, sizeof img_data, 1, raw_img); + fwrite(img_data, sizeof img_data, 1, f); + if (progress_callback) + progress_callback(s + 1, size_sectors); + } + } else { + mvhd_gen_footer(&vhdm->footer, size_in_bytes, geom, MVHD_TYPE_FIXED, 0); + for (s = 0; s < size_sectors; s++) { + fwrite(img_data, sizeof img_data, 1, f); + if (progress_callback) + progress_callback(s + 1, size_sectors); + } + } + mvhd_footer_to_buffer(&vhdm->footer, footer_buff); + fwrite(footer_buff, sizeof footer_buff, 1, f); + fclose(f); + f = NULL; + free(vhdm); + vhdm = mvhd_open(path, false, err); + goto end; - cleanup_vhdm: - free(vhdm); - vhdm = NULL; - end: - return vhdm; +cleanup_vhdm: + free(vhdm); + vhdm = NULL; +end: + return vhdm; } /** * \brief Create sparse or differencing VHD image. - * + * * \param [in] path is the absolute path to the VHD file to create - * \param [in] par_path is the absolute path to a parent image. If NULL, a sparse image is created, otherwise create a differencing image - * \param [in] size_in_bytes is the total size in bytes of the virtual hard disk image - * \param [in] geom is the HDD geometry of the image to create. Determines final image size - * \param [in] block_size_in_sectors is the block size in sectors + * \param [in] par_path is the absolute path to a parent image. If NULL, a sparse image is created, otherwise create a + * differencing image \param [in] size_in_bytes is the total size in bytes of the virtual hard disk image \param [in] geom is the + * HDD geometry of the image to create. Determines final image size \param [in] block_size_in_sectors is the block size in sectors * \param [out] err indicates what error occurred, if any - * + * * \return NULL if an error occurrs. Check value of *err for actual error. Otherwise returns pointer to a MVHDMeta struct */ -static MVHDMeta *mvhd_create_sparse_diff(const char *path, const char *par_path, uint64_t size_in_bytes, MVHDGeom *geom, uint32_t block_size_in_sectors, int *err) { - uint8_t footer_buff[MVHD_FOOTER_SIZE] = {0}; - uint8_t sparse_buff[MVHD_SPARSE_SIZE] = {0}; - uint8_t bat_sect[MVHD_SECTOR_SIZE]; - MVHDGeom par_geom = {0}; - memset(bat_sect, 0xffffffff, sizeof bat_sect); - MVHDMeta *vhdm = NULL; - MVHDMeta *par_vhdm = NULL; - mvhd_utf16 *w2ku_path_buff = NULL; - mvhd_utf16 *w2ru_path_buff = NULL; - uint32_t par_mod_timestamp = 0; - if (par_path != NULL) { - par_mod_timestamp = mvhd_file_mod_timestamp(par_path, err); - if (*err != 0) { - goto end; - } - par_vhdm = mvhd_open(par_path, true, err); - if (par_vhdm == NULL) { - goto end; - } - } - vhdm = calloc(1, sizeof *vhdm); - if (vhdm == NULL) { - *err = MVHD_ERR_MEM; - goto cleanup_par_vhdm; - } - if (par_vhdm != NULL) { - /* We use the geometry from the parent VHD, not what was passed in */ - par_geom.cyl = par_vhdm->footer.geom.cyl; - par_geom.heads = par_vhdm->footer.geom.heads; - par_geom.spt = par_vhdm->footer.geom.spt; - geom = &par_geom; - size_in_bytes = par_vhdm->footer.curr_sz; - } else if (geom == NULL || (geom->cyl == 0 || geom->heads == 0 || geom->spt == 0)) { - *err = MVHD_ERR_INVALID_GEOM; - goto cleanup_vhdm; - } +static MVHDMeta *mvhd_create_sparse_diff(const char *path, const char *par_path, uint64_t size_in_bytes, MVHDGeom *geom, + uint32_t block_size_in_sectors, int *err) { + uint8_t footer_buff[MVHD_FOOTER_SIZE] = {0}; + uint8_t sparse_buff[MVHD_SPARSE_SIZE] = {0}; + uint8_t bat_sect[MVHD_SECTOR_SIZE]; + MVHDGeom par_geom = {0}; + memset(bat_sect, 0xffffffff, sizeof bat_sect); + MVHDMeta *vhdm = NULL; + MVHDMeta *par_vhdm = NULL; + mvhd_utf16 *w2ku_path_buff = NULL; + mvhd_utf16 *w2ru_path_buff = NULL; + uint32_t par_mod_timestamp = 0; + if (par_path != NULL) { + par_mod_timestamp = mvhd_file_mod_timestamp(par_path, err); + if (*err != 0) { + goto end; + } + par_vhdm = mvhd_open(par_path, true, err); + if (par_vhdm == NULL) { + goto end; + } + } + vhdm = calloc(1, sizeof *vhdm); + if (vhdm == NULL) { + *err = MVHD_ERR_MEM; + goto cleanup_par_vhdm; + } + if (par_vhdm != NULL) { + /* We use the geometry from the parent VHD, not what was passed in */ + par_geom.cyl = par_vhdm->footer.geom.cyl; + par_geom.heads = par_vhdm->footer.geom.heads; + par_geom.spt = par_vhdm->footer.geom.spt; + geom = &par_geom; + size_in_bytes = par_vhdm->footer.curr_sz; + } else if (geom == NULL || (geom->cyl == 0 || geom->heads == 0 || geom->spt == 0)) { + *err = MVHD_ERR_INVALID_GEOM; + goto cleanup_vhdm; + } - FILE *f = mvhd_fopen(path, "wb+", err); - if (f == NULL) { - goto cleanup_vhdm; - } - mvhd_fseeko64(f, 0, SEEK_SET); - /* Note, the sparse header follows the footer copy at the beginning of the file */ - if (par_path == NULL) { - mvhd_gen_footer(&vhdm->footer, size_in_bytes, geom, MVHD_TYPE_DYNAMIC, MVHD_FOOTER_SIZE); - } else { - mvhd_gen_footer(&vhdm->footer, size_in_bytes, geom, MVHD_TYPE_DIFF, MVHD_FOOTER_SIZE); - } - mvhd_footer_to_buffer(&vhdm->footer, footer_buff); - /* As mentioned, start with a copy of the footer */ - fwrite(footer_buff, sizeof footer_buff, 1, f); - /** - * Calculate the number of (2MB or 512KB) data blocks required to store the entire - * contents of the disk image, followed by the number of sectors the - * BAT occupies in the image. Note, the BAT is sector aligned, and is padded - * to the next sector boundary - * */ - uint32_t size_in_sectors = (uint32_t)(size_in_bytes / MVHD_SECTOR_SIZE); - uint32_t num_blks = size_in_sectors / block_size_in_sectors; - if (size_in_sectors % block_size_in_sectors != 0) { - num_blks += 1; - } - uint32_t num_bat_sect = num_blks / MVHD_BAT_ENT_PER_SECT; - if (num_blks % MVHD_BAT_ENT_PER_SECT != 0) { - num_bat_sect += 1; - } - /* Storing the BAT directly following the footer and header */ - uint64_t bat_offset = MVHD_FOOTER_SIZE + MVHD_SPARSE_SIZE; - uint64_t par_loc_offset = 0; + FILE *f = mvhd_fopen(path, "wb+", err); + if (f == NULL) { + goto cleanup_vhdm; + } + mvhd_fseeko64(f, 0, SEEK_SET); + /* Note, the sparse header follows the footer copy at the beginning of the file */ + if (par_path == NULL) { + mvhd_gen_footer(&vhdm->footer, size_in_bytes, geom, MVHD_TYPE_DYNAMIC, MVHD_FOOTER_SIZE); + } else { + mvhd_gen_footer(&vhdm->footer, size_in_bytes, geom, MVHD_TYPE_DIFF, MVHD_FOOTER_SIZE); + } + mvhd_footer_to_buffer(&vhdm->footer, footer_buff); + /* As mentioned, start with a copy of the footer */ + fwrite(footer_buff, sizeof footer_buff, 1, f); + /** + * Calculate the number of (2MB or 512KB) data blocks required to store the entire + * contents of the disk image, followed by the number of sectors the + * BAT occupies in the image. Note, the BAT is sector aligned, and is padded + * to the next sector boundary + * */ + uint32_t size_in_sectors = (uint32_t)(size_in_bytes / MVHD_SECTOR_SIZE); + uint32_t num_blks = size_in_sectors / block_size_in_sectors; + if (size_in_sectors % block_size_in_sectors != 0) { + num_blks += 1; + } + uint32_t num_bat_sect = num_blks / MVHD_BAT_ENT_PER_SECT; + if (num_blks % MVHD_BAT_ENT_PER_SECT != 0) { + num_bat_sect += 1; + } + /* Storing the BAT directly following the footer and header */ + uint64_t bat_offset = MVHD_FOOTER_SIZE + MVHD_SPARSE_SIZE; + uint64_t par_loc_offset = 0; - /** - * If creating a differencing VHD, populate the sparse header with additional - * data about the parent image, and where to find it, and it's last modified timestamp - * */ - if (par_vhdm != NULL) { - /** - * Create output buffers to encode paths into. - * The paths are not stored directly in the sparse header, hence the need to - * store them in buffers to be written to the VHD image later - */ - w2ku_path_buff = calloc(MVHD_MAX_PATH_CHARS, sizeof *w2ku_path_buff); - if (w2ku_path_buff == NULL) { - *err = MVHD_ERR_MEM; - goto end; - } - w2ru_path_buff = calloc(MVHD_MAX_PATH_CHARS, sizeof *w2ru_path_buff); - if (w2ru_path_buff == NULL) { - *err = MVHD_ERR_MEM; - goto end; - } - memcpy(vhdm->sparse.par_uuid, par_vhdm->footer.uuid, sizeof vhdm->sparse.par_uuid); - par_loc_offset = bat_offset + ((uint64_t)num_bat_sect * MVHD_SECTOR_SIZE) + (5 * MVHD_SECTOR_SIZE); - if (mvhd_gen_par_loc(&vhdm->sparse, path, par_path, par_loc_offset, w2ku_path_buff, w2ru_path_buff, (MVHDError *)err) < 0) { - goto cleanup_vhdm; - } - vhdm->sparse.par_timestamp = par_mod_timestamp; - } - mvhd_gen_sparse_header(&vhdm->sparse, num_blks, bat_offset, block_size_in_sectors); - mvhd_header_to_buffer(&vhdm->sparse, sparse_buff); - fwrite(sparse_buff, sizeof sparse_buff, 1, f); - /* The BAT sectors need to be filled with 0xffffffff */ - uint32_t i; - for (i = 0; i < num_bat_sect; i++) { - fwrite(bat_sect, sizeof bat_sect, 1, f); - } - mvhd_write_empty_sectors(f, 5); - /** - * If creating a differencing VHD, the paths to the parent image need to be written - * tp the file. Both absolute and relative paths are written - * */ - if (par_vhdm != NULL) { - uint64_t curr_pos = (uint64_t)mvhd_ftello64(f); - /* Double check my sums... */ - assert(curr_pos == par_loc_offset); - /* Fill the space required for location data with zero */ - uint8_t empty_sect[MVHD_SECTOR_SIZE] = {0}; - int i; - uint32_t j; - for (i = 0; i < 2; i++) { - for (j = 0; j < (vhdm->sparse.par_loc_entry[i].plat_data_space / MVHD_SECTOR_SIZE); j++) { - fwrite(empty_sect, sizeof empty_sect, 1, f); - } - } - /* Now write the location entries */ - mvhd_fseeko64(f, vhdm->sparse.par_loc_entry[0].plat_data_offset, SEEK_SET); - fwrite(w2ku_path_buff, vhdm->sparse.par_loc_entry[0].plat_data_len, 1, f); - mvhd_fseeko64(f, vhdm->sparse.par_loc_entry[1].plat_data_offset, SEEK_SET); - fwrite(w2ru_path_buff, vhdm->sparse.par_loc_entry[1].plat_data_len, 1, f); - /* and reset the file position to continue */ - mvhd_fseeko64(f, vhdm->sparse.par_loc_entry[1].plat_data_offset + vhdm->sparse.par_loc_entry[1].plat_data_space, SEEK_SET); - mvhd_write_empty_sectors(f, 5); - } - /* And finish with the footer */ - fwrite(footer_buff, sizeof footer_buff, 1, f); - fclose(f); - f = NULL; - free(vhdm); - vhdm = mvhd_open(path, false, err); - goto end; + /** + * If creating a differencing VHD, populate the sparse header with additional + * data about the parent image, and where to find it, and it's last modified timestamp + * */ + if (par_vhdm != NULL) { + /** + * Create output buffers to encode paths into. + * The paths are not stored directly in the sparse header, hence the need to + * store them in buffers to be written to the VHD image later + */ + w2ku_path_buff = calloc(MVHD_MAX_PATH_CHARS, sizeof *w2ku_path_buff); + if (w2ku_path_buff == NULL) { + *err = MVHD_ERR_MEM; + goto end; + } + w2ru_path_buff = calloc(MVHD_MAX_PATH_CHARS, sizeof *w2ru_path_buff); + if (w2ru_path_buff == NULL) { + *err = MVHD_ERR_MEM; + goto end; + } + memcpy(vhdm->sparse.par_uuid, par_vhdm->footer.uuid, sizeof vhdm->sparse.par_uuid); + par_loc_offset = bat_offset + ((uint64_t)num_bat_sect * MVHD_SECTOR_SIZE) + (5 * MVHD_SECTOR_SIZE); + if (mvhd_gen_par_loc(&vhdm->sparse, path, par_path, par_loc_offset, w2ku_path_buff, w2ru_path_buff, + (MVHDError *)err) < 0) { + goto cleanup_vhdm; + } + vhdm->sparse.par_timestamp = par_mod_timestamp; + } + mvhd_gen_sparse_header(&vhdm->sparse, num_blks, bat_offset, block_size_in_sectors); + mvhd_header_to_buffer(&vhdm->sparse, sparse_buff); + fwrite(sparse_buff, sizeof sparse_buff, 1, f); + /* The BAT sectors need to be filled with 0xffffffff */ + uint32_t i; + for (i = 0; i < num_bat_sect; i++) { + fwrite(bat_sect, sizeof bat_sect, 1, f); + } + mvhd_write_empty_sectors(f, 5); + /** + * If creating a differencing VHD, the paths to the parent image need to be written + * tp the file. Both absolute and relative paths are written + * */ + if (par_vhdm != NULL) { + uint64_t curr_pos = (uint64_t)mvhd_ftello64(f); + /* Double check my sums... */ + assert(curr_pos == par_loc_offset); + /* Fill the space required for location data with zero */ + uint8_t empty_sect[MVHD_SECTOR_SIZE] = {0}; + int i; + uint32_t j; + for (i = 0; i < 2; i++) { + for (j = 0; j < (vhdm->sparse.par_loc_entry[i].plat_data_space / MVHD_SECTOR_SIZE); j++) { + fwrite(empty_sect, sizeof empty_sect, 1, f); + } + } + /* Now write the location entries */ + mvhd_fseeko64(f, vhdm->sparse.par_loc_entry[0].plat_data_offset, SEEK_SET); + fwrite(w2ku_path_buff, vhdm->sparse.par_loc_entry[0].plat_data_len, 1, f); + mvhd_fseeko64(f, vhdm->sparse.par_loc_entry[1].plat_data_offset, SEEK_SET); + fwrite(w2ru_path_buff, vhdm->sparse.par_loc_entry[1].plat_data_len, 1, f); + /* and reset the file position to continue */ + mvhd_fseeko64(f, vhdm->sparse.par_loc_entry[1].plat_data_offset + vhdm->sparse.par_loc_entry[1].plat_data_space, + SEEK_SET); + mvhd_write_empty_sectors(f, 5); + } + /* And finish with the footer */ + fwrite(footer_buff, sizeof footer_buff, 1, f); + fclose(f); + f = NULL; + free(vhdm); + vhdm = mvhd_open(path, false, err); + goto end; - cleanup_vhdm: - free(vhdm); - vhdm = NULL; - cleanup_par_vhdm: - if (par_vhdm != NULL) { - mvhd_close(par_vhdm); - } - end: - free(w2ku_path_buff); - free(w2ru_path_buff); - return vhdm; +cleanup_vhdm: + free(vhdm); + vhdm = NULL; +cleanup_par_vhdm: + if (par_vhdm != NULL) { + mvhd_close(par_vhdm); + } +end: + free(w2ku_path_buff); + free(w2ru_path_buff); + return vhdm; } MVHDMeta *mvhd_create_sparse(const char *path, MVHDGeom geom, int *err) { - uint64_t size_in_bytes = mvhd_calc_size_bytes(&geom); - return mvhd_create_sparse_diff(path, NULL, size_in_bytes, &geom, MVHD_BLOCK_LARGE, err); + uint64_t size_in_bytes = mvhd_calc_size_bytes(&geom); + return mvhd_create_sparse_diff(path, NULL, size_in_bytes, &geom, MVHD_BLOCK_LARGE, err); } MVHDMeta *mvhd_create_diff(const char *path, const char *par_path, int *err) { - return mvhd_create_sparse_diff(path, par_path, 0, NULL, MVHD_BLOCK_LARGE, err); + return mvhd_create_sparse_diff(path, par_path, 0, NULL, MVHD_BLOCK_LARGE, err); } MVHDMeta *mvhd_create_ex(MVHDCreationOptions options, int *err) { - uint32_t geom_sector_size; - switch (options.type) { - case MVHD_TYPE_FIXED: - case MVHD_TYPE_DYNAMIC:geom_sector_size = mvhd_calc_size_sectors(&(options.geometry)); - if ((options.size_in_bytes > 0 && (options.size_in_bytes % MVHD_SECTOR_SIZE) > 0) - || (options.size_in_bytes > MVHD_MAX_SIZE_IN_BYTES) - || (options.size_in_bytes == 0 && geom_sector_size == 0)) { - *err = MVHD_ERR_INVALID_SIZE; - return NULL; - } + uint32_t geom_sector_size; + switch (options.type) { + case MVHD_TYPE_FIXED: + case MVHD_TYPE_DYNAMIC: + geom_sector_size = mvhd_calc_size_sectors(&(options.geometry)); + if ((options.size_in_bytes > 0 && (options.size_in_bytes % MVHD_SECTOR_SIZE) > 0) || + (options.size_in_bytes > MVHD_MAX_SIZE_IN_BYTES) || (options.size_in_bytes == 0 && geom_sector_size == 0)) { + *err = MVHD_ERR_INVALID_SIZE; + return NULL; + } - if (options.size_in_bytes > 0 && ((uint64_t)geom_sector_size * MVHD_SECTOR_SIZE) > options.size_in_bytes) { - *err = MVHD_ERR_INVALID_GEOM; - return NULL; - } + if (options.size_in_bytes > 0 && ((uint64_t)geom_sector_size * MVHD_SECTOR_SIZE) > options.size_in_bytes) { + *err = MVHD_ERR_INVALID_GEOM; + return NULL; + } - if (options.size_in_bytes == 0) - options.size_in_bytes = (uint64_t)geom_sector_size * MVHD_SECTOR_SIZE; + if (options.size_in_bytes == 0) + options.size_in_bytes = (uint64_t)geom_sector_size * MVHD_SECTOR_SIZE; - if (geom_sector_size == 0) - options.geometry = mvhd_calculate_geometry(options.size_in_bytes); - break; - case MVHD_TYPE_DIFF: - if (options.parent_path == NULL) { - *err = MVHD_ERR_FILE; - return NULL; - } - break; - default:*err = MVHD_ERR_TYPE; - return NULL; - } + if (geom_sector_size == 0) + options.geometry = mvhd_calculate_geometry(options.size_in_bytes); + break; + case MVHD_TYPE_DIFF: + if (options.parent_path == NULL) { + *err = MVHD_ERR_FILE; + return NULL; + } + break; + default: + *err = MVHD_ERR_TYPE; + return NULL; + } - if (options.path == NULL) { - *err = MVHD_ERR_FILE; - return NULL; - } + if (options.path == NULL) { + *err = MVHD_ERR_FILE; + return NULL; + } - if (options.type != MVHD_TYPE_FIXED) { - if (options.block_size_in_sectors == MVHD_BLOCK_DEFAULT) - options.block_size_in_sectors = MVHD_BLOCK_LARGE; + if (options.type != MVHD_TYPE_FIXED) { + if (options.block_size_in_sectors == MVHD_BLOCK_DEFAULT) + options.block_size_in_sectors = MVHD_BLOCK_LARGE; - if (options.block_size_in_sectors != MVHD_BLOCK_LARGE && options.block_size_in_sectors != MVHD_BLOCK_SMALL) { - *err = MVHD_ERR_INVALID_BLOCK_SIZE; - return NULL; - } - } + if (options.block_size_in_sectors != MVHD_BLOCK_LARGE && options.block_size_in_sectors != MVHD_BLOCK_SMALL) { + *err = MVHD_ERR_INVALID_BLOCK_SIZE; + return NULL; + } + } - switch (options.type) { - case MVHD_TYPE_FIXED:return mvhd_create_fixed_raw(options.path, NULL, options.size_in_bytes, &(options.geometry), err, options.progress_callback); - case MVHD_TYPE_DYNAMIC:return mvhd_create_sparse_diff(options.path, NULL, options.size_in_bytes, &(options.geometry), options.block_size_in_sectors, err); - case MVHD_TYPE_DIFF:return mvhd_create_sparse_diff(options.path, options.parent_path, 0, NULL, options.block_size_in_sectors, err); - } + switch (options.type) { + case MVHD_TYPE_FIXED: + return mvhd_create_fixed_raw(options.path, NULL, options.size_in_bytes, &(options.geometry), err, + options.progress_callback); + case MVHD_TYPE_DYNAMIC: + return mvhd_create_sparse_diff(options.path, NULL, options.size_in_bytes, &(options.geometry), + options.block_size_in_sectors, err); + case MVHD_TYPE_DIFF: + return mvhd_create_sparse_diff(options.path, options.parent_path, 0, NULL, options.block_size_in_sectors, err); + } - return NULL; /* Make the compiler happy */ + return NULL; /* Make the compiler happy */ } diff --git a/src/hdd/minivhd/minivhd_io.c b/src/hdd/minivhd/minivhd_io.c index b9c3008d..e07798af 100644 --- a/src/hdd/minivhd/minivhd_io.c +++ b/src/hdd/minivhd/minivhd_io.c @@ -11,14 +11,15 @@ #include "minivhd/minivhd_internal.h" #include "minivhd/minivhd_util.h" -/* The following bit array macros adapted from +/* The following bit array macros adapted from http://www.mathcs.emory.edu/~cheung/Courses/255/Syllabus/1-C-intro/bit-array.html */ -#define VHD_SETBIT(A, k) ( A[(k/8)] |= (0x80 >> (k%8)) ) -#define VHD_CLEARBIT(A, k) ( A[(k/8)] &= ~(0x80 >> (k%8)) ) -#define VHD_TESTBIT(A, k) ( A[(k/8)] & (0x80 >> (k%8)) ) +#define VHD_SETBIT(A, k) (A[(k / 8)] |= (0x80 >> (k % 8))) +#define VHD_CLEARBIT(A, k) (A[(k / 8)] &= ~(0x80 >> (k % 8))) +#define VHD_TESTBIT(A, k) (A[(k / 8)] & (0x80 >> (k % 8))) -static inline void mvhd_check_sectors(uint32_t offset, int num_sectors, uint32_t total_sectors, int *transfer_sect, int *trunc_sect); +static inline void mvhd_check_sectors(uint32_t offset, int num_sectors, uint32_t total_sectors, int *transfer_sect, + int *trunc_sect); static void mvhd_read_sect_bitmap(MVHDMeta *vhdm, int blk); static void mvhd_write_bat_entry(MVHDMeta *vhdm, int blk); static void mvhd_create_block(MVHDMeta *vhdm, int blk); @@ -26,258 +27,257 @@ static void mvhd_write_curr_sect_bitmap(MVHDMeta *vhdm); /** * \brief Check that we will not be overflowing buffers - * + * * \param [in] offset The offset from which we are beginning from * \param [in] num_sectors The number of sectors which we desire to read/write * \param [in] total_sectors The total number of sectors available - * \param [out] transfer_sect The number of sectors to actually write. + * \param [out] transfer_sect The number of sectors to actually write. * This may be lower than num_sectors if offset + num_sectors >= total_sectors * \param [out] trunc_sectors The number of sectors truncated if transfer_sectors < num_sectors */ -static inline void mvhd_check_sectors(uint32_t offset, int num_sectors, uint32_t total_sectors, int *transfer_sect, int *trunc_sect) { - *transfer_sect = num_sectors; - *trunc_sect = 0; - if ((total_sectors - offset) < (uint32_t)*transfer_sect) { - *transfer_sect = total_sectors - offset; - *trunc_sect = num_sectors - *transfer_sect; - } +static inline void mvhd_check_sectors(uint32_t offset, int num_sectors, uint32_t total_sectors, int *transfer_sect, + int *trunc_sect) { + *transfer_sect = num_sectors; + *trunc_sect = 0; + if ((total_sectors - offset) < (uint32_t)*transfer_sect) { + *transfer_sect = total_sectors - offset; + *trunc_sect = num_sectors - *transfer_sect; + } } void mvhd_write_empty_sectors(FILE *f, int sector_count) { - uint8_t zero_bytes[MVHD_SECTOR_SIZE] = {0}; - int i; - for (i = 0; i < sector_count; i++) { - fwrite(zero_bytes, sizeof zero_bytes, 1, f); - } + uint8_t zero_bytes[MVHD_SECTOR_SIZE] = {0}; + int i; + for (i = 0; i < sector_count; i++) { + fwrite(zero_bytes, sizeof zero_bytes, 1, f); + } } /** * \brief Read the sector bitmap for a block. - * - * If the block is sparse, the sector bitmap in memory will be + * + * If the block is sparse, the sector bitmap in memory will be * zeroed. Otherwise, the sector bitmap is read from the VHD file. - * + * * \param [in] vhdm MiniVHD data structure * \param [in] blk The block for which to read the sector bitmap from */ static void mvhd_read_sect_bitmap(MVHDMeta *vhdm, int blk) { - if (vhdm->block_offset[blk] != MVHD_SPARSE_BLK) { - mvhd_fseeko64(vhdm->f, (uint64_t)vhdm->block_offset[blk] * MVHD_SECTOR_SIZE, SEEK_SET); - fread(vhdm->bitmap.curr_bitmap, vhdm->bitmap.sector_count * MVHD_SECTOR_SIZE, 1, vhdm->f); - } else { - memset(vhdm->bitmap.curr_bitmap, 0, vhdm->bitmap.sector_count * MVHD_SECTOR_SIZE); - } - vhdm->bitmap.curr_block = blk; + if (vhdm->block_offset[blk] != MVHD_SPARSE_BLK) { + mvhd_fseeko64(vhdm->f, (uint64_t)vhdm->block_offset[blk] * MVHD_SECTOR_SIZE, SEEK_SET); + fread(vhdm->bitmap.curr_bitmap, vhdm->bitmap.sector_count * MVHD_SECTOR_SIZE, 1, vhdm->f); + } else { + memset(vhdm->bitmap.curr_bitmap, 0, vhdm->bitmap.sector_count * MVHD_SECTOR_SIZE); + } + vhdm->bitmap.curr_block = blk; } /** * \brief Write the current sector bitmap in memory to file - * + * * \param [in] vhdm MiniVHD data structure */ static void mvhd_write_curr_sect_bitmap(MVHDMeta *vhdm) { - if (vhdm->bitmap.curr_block >= 0) { - int64_t abs_offset = (int64_t)vhdm->block_offset[vhdm->bitmap.curr_block] * MVHD_SECTOR_SIZE; - mvhd_fseeko64(vhdm->f, abs_offset, SEEK_SET); - fwrite(vhdm->bitmap.curr_bitmap, MVHD_SECTOR_SIZE, vhdm->bitmap.sector_count, vhdm->f); - } + if (vhdm->bitmap.curr_block >= 0) { + int64_t abs_offset = (int64_t)vhdm->block_offset[vhdm->bitmap.curr_block] * MVHD_SECTOR_SIZE; + mvhd_fseeko64(vhdm->f, abs_offset, SEEK_SET); + fwrite(vhdm->bitmap.curr_bitmap, MVHD_SECTOR_SIZE, vhdm->bitmap.sector_count, vhdm->f); + } } /** * \brief Write block offset from memory into file - * + * * \param [in] vhdm MiniVHD data structure * \param [in] blk The block for which to write the offset for */ static void mvhd_write_bat_entry(MVHDMeta *vhdm, int blk) { - uint64_t table_offset = vhdm->sparse.bat_offset + ((uint64_t)blk * sizeof *vhdm->block_offset); - uint32_t offset = mvhd_to_be32(vhdm->block_offset[blk]); - mvhd_fseeko64(vhdm->f, table_offset, SEEK_SET); - fwrite(&offset, sizeof offset, 1, vhdm->f); + uint64_t table_offset = vhdm->sparse.bat_offset + ((uint64_t)blk * sizeof *vhdm->block_offset); + uint32_t offset = mvhd_to_be32(vhdm->block_offset[blk]); + mvhd_fseeko64(vhdm->f, table_offset, SEEK_SET); + fwrite(&offset, sizeof offset, 1, vhdm->f); } /** * \brief Create an empty block in a sparse or differencing VHD image - * - * VHD images store data in blocks, which are typically 4096 sectors in size - * (~2MB). These blocks may be stored on disk in any order. Blocks are created + * + * VHD images store data in blocks, which are typically 4096 sectors in size + * (~2MB). These blocks may be stored on disk in any order. Blocks are created * on demand when required. - * - * This function creates new, empty blocks, by replacing the footer at the end of the file + * + * This function creates new, empty blocks, by replacing the footer at the end of the file * and then re-inserting the footer at the new file end. The BAT table entry for the * new block is updated with the new offset. - * + * * \param [in] vhdm MiniVHD data structure * \param [in] blk The block number to create */ static void mvhd_create_block(MVHDMeta *vhdm, int blk) { - uint8_t footer[MVHD_FOOTER_SIZE]; - /* Seek to where the footer SHOULD be */ - mvhd_fseeko64(vhdm->f, -MVHD_FOOTER_SIZE, SEEK_END); - fread(footer, sizeof footer, 1, vhdm->f); - mvhd_fseeko64(vhdm->f, -MVHD_FOOTER_SIZE, SEEK_END); - if (!mvhd_is_conectix_str(footer)) { - /* Oh dear. We use the header instead, since something has gone wrong at the footer */ - mvhd_fseeko64(vhdm->f, 0, SEEK_SET); - fread(footer, sizeof footer, 1, vhdm->f); - mvhd_fseeko64(vhdm->f, 0, SEEK_END); - } - int64_t abs_offset = mvhd_ftello64(vhdm->f); - if (abs_offset % MVHD_SECTOR_SIZE != 0) { - /* Yikes! We're supposed to be on a sector boundary. Add some padding */ - int64_t padding_amount = (int64_t)MVHD_SECTOR_SIZE - (abs_offset % MVHD_SECTOR_SIZE); - uint8_t zero_byte = 0; - int i; - for (i = 0; i < padding_amount; i++) { - fwrite(&zero_byte, sizeof zero_byte, 1, vhdm->f); - } - abs_offset += padding_amount; - } - uint32_t sect_offset = (uint32_t)(abs_offset / MVHD_SECTOR_SIZE); - int blk_size_sectors = vhdm->sparse.block_sz / MVHD_SECTOR_SIZE; - mvhd_write_empty_sectors(vhdm->f, vhdm->bitmap.sector_count + blk_size_sectors); - /* Add a bit of padding. That's what Windows appears to do, although it's not strictly necessary... */ - mvhd_write_empty_sectors(vhdm->f, 5); - /* And we finish with the footer */ - fwrite(footer, sizeof footer, 1, vhdm->f); - /* We no longer have a sparse block. Update that BAT! */ - vhdm->block_offset[blk] = sect_offset; - mvhd_write_bat_entry(vhdm, blk); + uint8_t footer[MVHD_FOOTER_SIZE]; + /* Seek to where the footer SHOULD be */ + mvhd_fseeko64(vhdm->f, -MVHD_FOOTER_SIZE, SEEK_END); + fread(footer, sizeof footer, 1, vhdm->f); + mvhd_fseeko64(vhdm->f, -MVHD_FOOTER_SIZE, SEEK_END); + if (!mvhd_is_conectix_str(footer)) { + /* Oh dear. We use the header instead, since something has gone wrong at the footer */ + mvhd_fseeko64(vhdm->f, 0, SEEK_SET); + fread(footer, sizeof footer, 1, vhdm->f); + mvhd_fseeko64(vhdm->f, 0, SEEK_END); + } + int64_t abs_offset = mvhd_ftello64(vhdm->f); + if (abs_offset % MVHD_SECTOR_SIZE != 0) { + /* Yikes! We're supposed to be on a sector boundary. Add some padding */ + int64_t padding_amount = (int64_t)MVHD_SECTOR_SIZE - (abs_offset % MVHD_SECTOR_SIZE); + uint8_t zero_byte = 0; + int i; + for (i = 0; i < padding_amount; i++) { + fwrite(&zero_byte, sizeof zero_byte, 1, vhdm->f); + } + abs_offset += padding_amount; + } + uint32_t sect_offset = (uint32_t)(abs_offset / MVHD_SECTOR_SIZE); + int blk_size_sectors = vhdm->sparse.block_sz / MVHD_SECTOR_SIZE; + mvhd_write_empty_sectors(vhdm->f, vhdm->bitmap.sector_count + blk_size_sectors); + /* Add a bit of padding. That's what Windows appears to do, although it's not strictly necessary... */ + mvhd_write_empty_sectors(vhdm->f, 5); + /* And we finish with the footer */ + fwrite(footer, sizeof footer, 1, vhdm->f); + /* We no longer have a sparse block. Update that BAT! */ + vhdm->block_offset[blk] = sect_offset; + mvhd_write_bat_entry(vhdm, blk); } int mvhd_fixed_read(MVHDMeta *vhdm, uint32_t offset, int num_sectors, void *out_buff) { - int64_t addr; - int transfer_sectors, truncated_sectors; - uint32_t total_sectors = (uint32_t)(vhdm->footer.curr_sz / MVHD_SECTOR_SIZE); - mvhd_check_sectors(offset, num_sectors, total_sectors, &transfer_sectors, &truncated_sectors); - addr = (int64_t)offset * MVHD_SECTOR_SIZE; - mvhd_fseeko64(vhdm->f, addr, SEEK_SET); - fread(out_buff, transfer_sectors * MVHD_SECTOR_SIZE, 1, vhdm->f); - return truncated_sectors; + int64_t addr; + int transfer_sectors, truncated_sectors; + uint32_t total_sectors = (uint32_t)(vhdm->footer.curr_sz / MVHD_SECTOR_SIZE); + mvhd_check_sectors(offset, num_sectors, total_sectors, &transfer_sectors, &truncated_sectors); + addr = (int64_t)offset * MVHD_SECTOR_SIZE; + mvhd_fseeko64(vhdm->f, addr, SEEK_SET); + fread(out_buff, transfer_sectors * MVHD_SECTOR_SIZE, 1, vhdm->f); + return truncated_sectors; } int mvhd_sparse_read(MVHDMeta *vhdm, uint32_t offset, int num_sectors, void *out_buff) { - int transfer_sectors, truncated_sectors; - uint32_t total_sectors = (uint32_t)(vhdm->footer.curr_sz / MVHD_SECTOR_SIZE); - mvhd_check_sectors(offset, num_sectors, total_sectors, &transfer_sectors, &truncated_sectors); - uint8_t *buff = (uint8_t *)out_buff; - int64_t addr; - uint32_t s, ls; - int blk, prev_blk, sib; - ls = offset + transfer_sectors; - prev_blk = -1; - for (s = offset; s < ls; s++) { - blk = s / vhdm->sect_per_block; - sib = s % vhdm->sect_per_block; - if (blk != prev_blk) { - prev_blk = blk; - if (vhdm->bitmap.curr_block != blk) { - mvhd_read_sect_bitmap(vhdm, blk); - mvhd_fseeko64(vhdm->f, (uint64_t)sib * MVHD_SECTOR_SIZE, SEEK_CUR); - } else { - addr = ((int64_t)vhdm->block_offset[blk] + vhdm->bitmap.sector_count + sib) * MVHD_SECTOR_SIZE; - mvhd_fseeko64(vhdm->f, addr, SEEK_SET); - } - } - if (VHD_TESTBIT(vhdm->bitmap.curr_bitmap, sib)) { - fread(buff, MVHD_SECTOR_SIZE, 1, vhdm->f); - } else { - memset(buff, 0, MVHD_SECTOR_SIZE); - mvhd_fseeko64(vhdm->f, MVHD_SECTOR_SIZE, SEEK_CUR); - } - buff += MVHD_SECTOR_SIZE; - } - return truncated_sectors; + int transfer_sectors, truncated_sectors; + uint32_t total_sectors = (uint32_t)(vhdm->footer.curr_sz / MVHD_SECTOR_SIZE); + mvhd_check_sectors(offset, num_sectors, total_sectors, &transfer_sectors, &truncated_sectors); + uint8_t *buff = (uint8_t *)out_buff; + int64_t addr; + uint32_t s, ls; + int blk, prev_blk, sib; + ls = offset + transfer_sectors; + prev_blk = -1; + for (s = offset; s < ls; s++) { + blk = s / vhdm->sect_per_block; + sib = s % vhdm->sect_per_block; + if (blk != prev_blk) { + prev_blk = blk; + if (vhdm->bitmap.curr_block != blk) { + mvhd_read_sect_bitmap(vhdm, blk); + mvhd_fseeko64(vhdm->f, (uint64_t)sib * MVHD_SECTOR_SIZE, SEEK_CUR); + } else { + addr = ((int64_t)vhdm->block_offset[blk] + vhdm->bitmap.sector_count + sib) * MVHD_SECTOR_SIZE; + mvhd_fseeko64(vhdm->f, addr, SEEK_SET); + } + } + if (VHD_TESTBIT(vhdm->bitmap.curr_bitmap, sib)) { + fread(buff, MVHD_SECTOR_SIZE, 1, vhdm->f); + } else { + memset(buff, 0, MVHD_SECTOR_SIZE); + mvhd_fseeko64(vhdm->f, MVHD_SECTOR_SIZE, SEEK_CUR); + } + buff += MVHD_SECTOR_SIZE; + } + return truncated_sectors; } int mvhd_diff_read(MVHDMeta *vhdm, uint32_t offset, int num_sectors, void *out_buff) { - int transfer_sectors, truncated_sectors; - uint32_t total_sectors = (uint32_t)(vhdm->footer.curr_sz / MVHD_SECTOR_SIZE); - mvhd_check_sectors(offset, num_sectors, total_sectors, &transfer_sectors, &truncated_sectors); - uint8_t *buff = (uint8_t *)out_buff; - MVHDMeta *curr_vhdm = vhdm; - uint32_t s, ls; - int blk, sib; - ls = offset + transfer_sectors; - for (s = offset; s < ls; s++) { - while (curr_vhdm->footer.disk_type == MVHD_TYPE_DIFF) { - blk = s / curr_vhdm->sect_per_block; - sib = s % curr_vhdm->sect_per_block; - if (curr_vhdm->bitmap.curr_block != blk) { - mvhd_read_sect_bitmap(curr_vhdm, blk); - } - if (!VHD_TESTBIT(curr_vhdm->bitmap.curr_bitmap, sib)) { - curr_vhdm = curr_vhdm->parent; - } else { - break; - } - } - /* We handle actual sector reading using the fixed or sparse functions, - as a differencing VHD is also a sparse VHD */ - if (curr_vhdm->footer.disk_type == MVHD_TYPE_DIFF || curr_vhdm->footer.disk_type == MVHD_TYPE_DYNAMIC) { - mvhd_sparse_read(curr_vhdm, s, 1, buff); - } else { - mvhd_fixed_read(curr_vhdm, s, 1, buff); - } - curr_vhdm = vhdm; - buff += MVHD_SECTOR_SIZE; - } - return truncated_sectors; + int transfer_sectors, truncated_sectors; + uint32_t total_sectors = (uint32_t)(vhdm->footer.curr_sz / MVHD_SECTOR_SIZE); + mvhd_check_sectors(offset, num_sectors, total_sectors, &transfer_sectors, &truncated_sectors); + uint8_t *buff = (uint8_t *)out_buff; + MVHDMeta *curr_vhdm = vhdm; + uint32_t s, ls; + int blk, sib; + ls = offset + transfer_sectors; + for (s = offset; s < ls; s++) { + while (curr_vhdm->footer.disk_type == MVHD_TYPE_DIFF) { + blk = s / curr_vhdm->sect_per_block; + sib = s % curr_vhdm->sect_per_block; + if (curr_vhdm->bitmap.curr_block != blk) { + mvhd_read_sect_bitmap(curr_vhdm, blk); + } + if (!VHD_TESTBIT(curr_vhdm->bitmap.curr_bitmap, sib)) { + curr_vhdm = curr_vhdm->parent; + } else { + break; + } + } + /* We handle actual sector reading using the fixed or sparse functions, + as a differencing VHD is also a sparse VHD */ + if (curr_vhdm->footer.disk_type == MVHD_TYPE_DIFF || curr_vhdm->footer.disk_type == MVHD_TYPE_DYNAMIC) { + mvhd_sparse_read(curr_vhdm, s, 1, buff); + } else { + mvhd_fixed_read(curr_vhdm, s, 1, buff); + } + curr_vhdm = vhdm; + buff += MVHD_SECTOR_SIZE; + } + return truncated_sectors; } int mvhd_fixed_write(MVHDMeta *vhdm, uint32_t offset, int num_sectors, void *in_buff) { - int64_t addr; - int transfer_sectors, truncated_sectors; - uint32_t total_sectors = (uint32_t)(vhdm->footer.curr_sz / MVHD_SECTOR_SIZE); - mvhd_check_sectors(offset, num_sectors, total_sectors, &transfer_sectors, &truncated_sectors); - addr = (int64_t)offset * MVHD_SECTOR_SIZE; - mvhd_fseeko64(vhdm->f, addr, SEEK_SET); - fwrite(in_buff, transfer_sectors * MVHD_SECTOR_SIZE, 1, vhdm->f); - return truncated_sectors; + int64_t addr; + int transfer_sectors, truncated_sectors; + uint32_t total_sectors = (uint32_t)(vhdm->footer.curr_sz / MVHD_SECTOR_SIZE); + mvhd_check_sectors(offset, num_sectors, total_sectors, &transfer_sectors, &truncated_sectors); + addr = (int64_t)offset * MVHD_SECTOR_SIZE; + mvhd_fseeko64(vhdm->f, addr, SEEK_SET); + fwrite(in_buff, transfer_sectors * MVHD_SECTOR_SIZE, 1, vhdm->f); + return truncated_sectors; } int mvhd_sparse_diff_write(MVHDMeta *vhdm, uint32_t offset, int num_sectors, void *in_buff) { - int transfer_sectors, truncated_sectors; - uint32_t total_sectors = (uint32_t)(vhdm->footer.curr_sz / MVHD_SECTOR_SIZE); - mvhd_check_sectors(offset, num_sectors, total_sectors, &transfer_sectors, &truncated_sectors); - uint8_t *buff = (uint8_t *)in_buff; - int64_t addr; - uint32_t s, ls; - int blk, prev_blk, sib; - ls = offset + transfer_sectors; - prev_blk = -1; - for (s = offset; s < ls; s++) { - blk = s / vhdm->sect_per_block; - sib = s % vhdm->sect_per_block; - if (vhdm->bitmap.curr_block != blk && prev_blk >= 0) { - /* Write the sector bitmap for the previous block, before we replace it. */ - mvhd_write_curr_sect_bitmap(vhdm); - } - if (vhdm->block_offset[blk] == MVHD_SPARSE_BLK) { - /* "read" the sector bitmap first, before creating a new block, as the bitmap will be - zero either way */ - mvhd_read_sect_bitmap(vhdm, blk); - mvhd_create_block(vhdm, blk); - } - if (blk != prev_blk) { - if (vhdm->bitmap.curr_block != blk) { - mvhd_read_sect_bitmap(vhdm, blk); - mvhd_fseeko64(vhdm->f, (uint64_t)sib * MVHD_SECTOR_SIZE, SEEK_CUR); - } else { - addr = ((int64_t)vhdm->block_offset[blk] + vhdm->bitmap.sector_count + sib) * MVHD_SECTOR_SIZE; - mvhd_fseeko64(vhdm->f, addr, SEEK_SET); - } - prev_blk = blk; - } - fwrite(buff, MVHD_SECTOR_SIZE, 1, vhdm->f); - VHD_SETBIT(vhdm->bitmap.curr_bitmap, sib); - buff += MVHD_SECTOR_SIZE; - } - /* And write the sector bitmap for the last block we visited to disk */ - mvhd_write_curr_sect_bitmap(vhdm); - return truncated_sectors; + int transfer_sectors, truncated_sectors; + uint32_t total_sectors = (uint32_t)(vhdm->footer.curr_sz / MVHD_SECTOR_SIZE); + mvhd_check_sectors(offset, num_sectors, total_sectors, &transfer_sectors, &truncated_sectors); + uint8_t *buff = (uint8_t *)in_buff; + int64_t addr; + uint32_t s, ls; + int blk, prev_blk, sib; + ls = offset + transfer_sectors; + prev_blk = -1; + for (s = offset; s < ls; s++) { + blk = s / vhdm->sect_per_block; + sib = s % vhdm->sect_per_block; + if (vhdm->bitmap.curr_block != blk && prev_blk >= 0) { + /* Write the sector bitmap for the previous block, before we replace it. */ + mvhd_write_curr_sect_bitmap(vhdm); + } + if (vhdm->block_offset[blk] == MVHD_SPARSE_BLK) { + /* "read" the sector bitmap first, before creating a new block, as the bitmap will be + zero either way */ + mvhd_read_sect_bitmap(vhdm, blk); + mvhd_create_block(vhdm, blk); + } + if (blk != prev_blk) { + if (vhdm->bitmap.curr_block != blk) { + mvhd_read_sect_bitmap(vhdm, blk); + mvhd_fseeko64(vhdm->f, (uint64_t)sib * MVHD_SECTOR_SIZE, SEEK_CUR); + } else { + addr = ((int64_t)vhdm->block_offset[blk] + vhdm->bitmap.sector_count + sib) * MVHD_SECTOR_SIZE; + mvhd_fseeko64(vhdm->f, addr, SEEK_SET); + } + prev_blk = blk; + } + fwrite(buff, MVHD_SECTOR_SIZE, 1, vhdm->f); + VHD_SETBIT(vhdm->bitmap.curr_bitmap, sib); + buff += MVHD_SECTOR_SIZE; + } + /* And write the sector bitmap for the last block we visited to disk */ + mvhd_write_curr_sect_bitmap(vhdm); + return truncated_sectors; } -int mvhd_noop_write(MVHDMeta *vhdm, uint32_t offset, int num_sectors, void *in_buff) { - return 0; -} +int mvhd_noop_write(MVHDMeta *vhdm, uint32_t offset, int num_sectors, void *in_buff) { return 0; } diff --git a/src/hdd/minivhd/minivhd_manage.c b/src/hdd/minivhd/minivhd_manage.c index 8efc3c1e..f3828ac5 100644 --- a/src/hdd/minivhd/minivhd_manage.c +++ b/src/hdd/minivhd/minivhd_manage.c @@ -21,12 +21,12 @@ int mvhd_errno = 0; static char tmp_open_path[MVHD_MAX_PATH_BYTES] = {0}; struct MVHDPaths { - char dir_path[MVHD_MAX_PATH_BYTES]; - char file_name[MVHD_MAX_PATH_BYTES]; - char w2ku_path[MVHD_MAX_PATH_BYTES]; - char w2ru_path[MVHD_MAX_PATH_BYTES]; - char joined_path[MVHD_MAX_PATH_BYTES]; - uint16_t tmp_src_path[MVHD_MAX_PATH_CHARS]; + char dir_path[MVHD_MAX_PATH_BYTES]; + char file_name[MVHD_MAX_PATH_BYTES]; + char w2ku_path[MVHD_MAX_PATH_BYTES]; + char w2ru_path[MVHD_MAX_PATH_BYTES]; + char joined_path[MVHD_MAX_PATH_BYTES]; + uint16_t tmp_src_path[MVHD_MAX_PATH_CHARS]; }; static void mvhd_read_footer(MVHDMeta *vhdm); @@ -39,497 +39,504 @@ static int mvhd_init_sector_bitmap(MVHDMeta *vhdm, MVHDError *err); /** * \brief Populate data stuctures with content from a VHD footer - * + * * \param [in] vhdm MiniVHD data structure */ static void mvhd_read_footer(MVHDMeta *vhdm) { - uint8_t buffer[MVHD_FOOTER_SIZE]; - mvhd_fseeko64(vhdm->f, -MVHD_FOOTER_SIZE, SEEK_END); - fread(buffer, sizeof buffer, 1, vhdm->f); - mvhd_buffer_to_footer(&vhdm->footer, buffer); + uint8_t buffer[MVHD_FOOTER_SIZE]; + mvhd_fseeko64(vhdm->f, -MVHD_FOOTER_SIZE, SEEK_END); + fread(buffer, sizeof buffer, 1, vhdm->f); + mvhd_buffer_to_footer(&vhdm->footer, buffer); } /** * \brief Populate data stuctures with content from a VHD sparse header - * + * * \param [in] vhdm MiniVHD data structure */ static void mvhd_read_sparse_header(MVHDMeta *vhdm) { - uint8_t buffer[MVHD_SPARSE_SIZE]; - mvhd_fseeko64(vhdm->f, vhdm->footer.data_offset, SEEK_SET); - fread(buffer, sizeof buffer, 1, vhdm->f); - mvhd_buffer_to_header(&vhdm->sparse, buffer); + uint8_t buffer[MVHD_SPARSE_SIZE]; + mvhd_fseeko64(vhdm->f, vhdm->footer.data_offset, SEEK_SET); + fread(buffer, sizeof buffer, 1, vhdm->f); + mvhd_buffer_to_header(&vhdm->sparse, buffer); } /** * \brief Validate VHD footer checksum - * + * * This works by generating a checksum from the footer, and comparing it against the stored checksum. - * + * * \param [in] vhdm MiniVHD data structure */ static bool mvhd_footer_checksum_valid(MVHDMeta *vhdm) { - return vhdm->footer.checksum == mvhd_gen_footer_checksum(&vhdm->footer); + return vhdm->footer.checksum == mvhd_gen_footer_checksum(&vhdm->footer); } /** * \brief Validate VHD sparse header checksum - * + * * This works by generating a checksum from the sparse header, and comparing it against the stored checksum. - * + * * \param [in] vhdm MiniVHD data structure */ static bool mvhd_sparse_checksum_valid(MVHDMeta *vhdm) { - return vhdm->sparse.checksum == mvhd_gen_sparse_checksum(&vhdm->sparse); + return vhdm->sparse.checksum == mvhd_gen_sparse_checksum(&vhdm->sparse); } /** * \brief Read BAT into MiniVHD data structure - * - * The Block Allocation Table (BAT) is the structure in a sparse and differencing VHD which stores + * + * The Block Allocation Table (BAT) is the structure in a sparse and differencing VHD which stores * the 4-byte sector offsets for each data block. This function allocates enough memory to contain * the entire BAT, and then reads the contents of the BAT into the buffer. - * + * * \param [in] vhdm MiniVHD data structure * \param [out] err this is populated with MVHD_ERR_MEM if the calloc fails - * + * * \retval -1 if an error occurrs. Check value of err in this case * \retval 0 if the function call succeeds */ static int mvhd_read_bat(MVHDMeta *vhdm, MVHDError *err) { - vhdm->block_offset = calloc(vhdm->sparse.max_bat_ent, sizeof *vhdm->block_offset); - if (vhdm->block_offset == NULL) { - *err = MVHD_ERR_MEM; - return -1; - } - mvhd_fseeko64(vhdm->f, vhdm->sparse.bat_offset, SEEK_SET); - uint32_t i; - for (i = 0; i < vhdm->sparse.max_bat_ent; i++) { - fread(&vhdm->block_offset[i], sizeof *vhdm->block_offset, 1, vhdm->f); - vhdm->block_offset[i] = mvhd_from_be32(vhdm->block_offset[i]); - } - return 0; + vhdm->block_offset = calloc(vhdm->sparse.max_bat_ent, sizeof *vhdm->block_offset); + if (vhdm->block_offset == NULL) { + *err = MVHD_ERR_MEM; + return -1; + } + mvhd_fseeko64(vhdm->f, vhdm->sparse.bat_offset, SEEK_SET); + uint32_t i; + for (i = 0; i < vhdm->sparse.max_bat_ent; i++) { + fread(&vhdm->block_offset[i], sizeof *vhdm->block_offset, 1, vhdm->f); + vhdm->block_offset[i] = mvhd_from_be32(vhdm->block_offset[i]); + } + return 0; } /** * \brief Perform a one-time calculation of some sparse VHD values - * + * * \param [in] vhdm MiniVHD data structure */ static void mvhd_calc_sparse_values(MVHDMeta *vhdm) { - vhdm->sect_per_block = vhdm->sparse.block_sz / MVHD_SECTOR_SIZE; - int bm_bytes = vhdm->sect_per_block / 8; - vhdm->bitmap.sector_count = bm_bytes / MVHD_SECTOR_SIZE; - if (bm_bytes % MVHD_SECTOR_SIZE > 0) { - vhdm->bitmap.sector_count++; - } + vhdm->sect_per_block = vhdm->sparse.block_sz / MVHD_SECTOR_SIZE; + int bm_bytes = vhdm->sect_per_block / 8; + vhdm->bitmap.sector_count = bm_bytes / MVHD_SECTOR_SIZE; + if (bm_bytes % MVHD_SECTOR_SIZE > 0) { + vhdm->bitmap.sector_count++; + } } /** * \brief Allocate memory for a sector bitmap. - * + * * Each data block is preceded by a sector bitmap. Each bit indicates whether the corresponding sector - * is considered 'clean' or 'dirty' (for sparse VHD images), or whether to read from the parent or current + * is considered 'clean' or 'dirty' (for sparse VHD images), or whether to read from the parent or current * image (for differencing images). - * + * * \param [in] vhdm MiniVHD data structure * \param [out] err this is populated with MVHD_ERR_MEM if the calloc fails - * + * * \retval -1 if an error occurrs. Check value of err in this case * \retval 0 if the function call succeeds */ static int mvhd_init_sector_bitmap(MVHDMeta *vhdm, MVHDError *err) { - vhdm->bitmap.curr_bitmap = calloc(vhdm->bitmap.sector_count, MVHD_SECTOR_SIZE); - if (vhdm->bitmap.curr_bitmap == NULL) { - *err = MVHD_ERR_MEM; - return -1; - } - vhdm->bitmap.curr_block = -1; - return 0; + vhdm->bitmap.curr_bitmap = calloc(vhdm->bitmap.sector_count, MVHD_SECTOR_SIZE); + if (vhdm->bitmap.curr_bitmap == NULL) { + *err = MVHD_ERR_MEM; + return -1; + } + vhdm->bitmap.curr_block = -1; + return 0; } /** * \brief Check if the path for a given platform code exists - * - * From the available paths, both relative and absolute, construct a full path + * + * From the available paths, both relative and absolute, construct a full path * and attempt to open a file at that path. - * - * Note, this function makes no attempt to verify that the path is the correct + * + * Note, this function makes no attempt to verify that the path is the correct * VHD image, or even a VHD image at all. - * + * * \param [in] paths a struct containing all available paths to work with - * \param [in] the platform code to try and obtain a path for. Setting this to zero + * \param [in] the platform code to try and obtain a path for. Setting this to zero * will try using the directory of the child image - * + * * \retval true if a file is found * \retval false if a file is not found */ static bool mvhd_parent_path_exists(struct MVHDPaths *paths, uint32_t plat_code) { - memset(paths->joined_path, 0, sizeof paths->joined_path); - FILE *f; - int cwk_ret, ferr; - enum cwk_path_style style = cwk_path_guess_style((const char *)paths->dir_path); - cwk_path_set_style(style); - cwk_ret = 1; - if (plat_code == MVHD_DIF_LOC_W2RU && *paths->w2ru_path) { - cwk_ret = cwk_path_join((const char *)paths->dir_path, (const char *)paths->w2ru_path, paths->joined_path, sizeof paths->joined_path); - } else if (plat_code == MVHD_DIF_LOC_W2KU && *paths->w2ku_path) { - memcpy(paths->joined_path, paths->w2ku_path, (sizeof paths->joined_path) - 1); - cwk_ret = 0; - } else if (plat_code == 0) { - cwk_ret = cwk_path_join((const char *)paths->dir_path, (const char *)paths->file_name, paths->joined_path, sizeof paths->joined_path); - } - if (cwk_ret > MVHD_MAX_PATH_BYTES) { - return false; - } - f = mvhd_fopen((const char *)paths->joined_path, "rb", &ferr); - if (f != NULL) { - /* We found a file at the requested path! */ - memcpy(tmp_open_path, paths->joined_path, (sizeof paths->joined_path) - 1); - tmp_open_path[sizeof tmp_open_path - 1] = '\0'; - fclose(f); - return true; - } else { - return false; - } + memset(paths->joined_path, 0, sizeof paths->joined_path); + FILE *f; + int cwk_ret, ferr; + enum cwk_path_style style = cwk_path_guess_style((const char *)paths->dir_path); + cwk_path_set_style(style); + cwk_ret = 1; + if (plat_code == MVHD_DIF_LOC_W2RU && *paths->w2ru_path) { + cwk_ret = cwk_path_join((const char *)paths->dir_path, (const char *)paths->w2ru_path, paths->joined_path, + sizeof paths->joined_path); + } else if (plat_code == MVHD_DIF_LOC_W2KU && *paths->w2ku_path) { + memcpy(paths->joined_path, paths->w2ku_path, (sizeof paths->joined_path) - 1); + cwk_ret = 0; + } else if (plat_code == 0) { + cwk_ret = cwk_path_join((const char *)paths->dir_path, (const char *)paths->file_name, paths->joined_path, + sizeof paths->joined_path); + } + if (cwk_ret > MVHD_MAX_PATH_BYTES) { + return false; + } + f = mvhd_fopen((const char *)paths->joined_path, "rb", &ferr); + if (f != NULL) { + /* We found a file at the requested path! */ + memcpy(tmp_open_path, paths->joined_path, (sizeof paths->joined_path) - 1); + tmp_open_path[sizeof tmp_open_path - 1] = '\0'; + fclose(f); + return true; + } else { + return false; + } } /** * \brief attempt to obtain a file path to a file that may be a valid VHD image - * - * Differential VHD images store both a UTF-16BE file name (or path), and up to - * eight "parent locator" entries. Using this information, this function tries to + * + * Differential VHD images store both a UTF-16BE file name (or path), and up to + * eight "parent locator" entries. Using this information, this function tries to * find a parent image. - * + * * This function does not verify if the path returned is a valid parent image. - * + * * \param [in] vhdm current MiniVHD data structure * \param [out] err any errors that may occurr. Check this if NULL is returned - * - * \return a pointer to the global string `tmp_open_path`, or NULL if a path could + * + * \return a pointer to the global string `tmp_open_path`, or NULL if a path could * not be found, or some error occurred */ static char *mvhd_get_diff_parent_path(MVHDMeta *vhdm, int *err) { - int utf_outlen, utf_inlen, utf_ret; - char *par_fp = NULL; - /* We can't resolve relative paths if we don't have an absolute - path to work with */ - if (!cwk_path_is_absolute((const char *)vhdm->filename)) { - *err = MVHD_ERR_PATH_REL; - goto end; - } - struct MVHDPaths *paths = calloc(1, sizeof *paths); - if (paths == NULL) { - *err = MVHD_ERR_MEM; - goto end; - } - size_t dirlen; - cwk_path_get_dirname((const char *)vhdm->filename, &dirlen); - if (dirlen >= sizeof paths->dir_path) { - *err = MVHD_ERR_PATH_LEN; - goto paths_cleanup; - } - memcpy(paths->dir_path, vhdm->filename, dirlen); - /* Get the filename field from the sparse header. */ - utf_outlen = (int)sizeof paths->file_name; - utf_inlen = (int)sizeof vhdm->sparse.par_utf16_name; - utf_ret = UTF16BEToUTF8((unsigned char *)paths->file_name, &utf_outlen, (const unsigned char *)vhdm->sparse.par_utf16_name, &utf_inlen); - if (utf_ret < 0) { - mvhd_set_encoding_err(utf_ret, err); - goto paths_cleanup; - } - /* Now read the parent locator entries, both relative and absolute, if they exist */ - unsigned char *loc_path; - int i; - for (i = 0; i < 8; i++) { - utf_outlen = MVHD_MAX_PATH_BYTES - 1; - if (vhdm->sparse.par_loc_entry[i].plat_code == MVHD_DIF_LOC_W2RU) { - loc_path = (unsigned char *)paths->w2ru_path; - } else if (vhdm->sparse.par_loc_entry[i].plat_code == MVHD_DIF_LOC_W2KU) { - loc_path = (unsigned char *)paths->w2ku_path; - } else { - continue; - } - utf_inlen = vhdm->sparse.par_loc_entry[i].plat_data_len; - if (utf_inlen > MVHD_MAX_PATH_BYTES) { - *err = MVHD_ERR_PATH_LEN; - goto paths_cleanup; - } - mvhd_fseeko64(vhdm->f, vhdm->sparse.par_loc_entry[i].plat_data_offset, SEEK_SET); - fread(paths->tmp_src_path, sizeof(uint8_t), utf_inlen, vhdm->f); - /* Note, the W2*u parent locators are UTF-16LE, unlike the filename field previously obtained, - which is UTF-16BE */ - utf_ret = UTF16LEToUTF8(loc_path, &utf_outlen, (const unsigned char *)paths->tmp_src_path, &utf_inlen); - if (utf_ret < 0) { - mvhd_set_encoding_err(utf_ret, err); - goto paths_cleanup; - } - } - /* We have paths in UTF-8. We should have enough info to try and find the parent VHD */ - /* Does the relative path exist? */ - if (mvhd_parent_path_exists(paths, MVHD_DIF_LOC_W2RU)) { - par_fp = tmp_open_path; - goto paths_cleanup; - } - /* What about trying the child directory? */ - if (mvhd_parent_path_exists(paths, 0)) { - par_fp = tmp_open_path; - goto paths_cleanup; - } - /* Well, all else fails, try the stored absolute path, if it exists */ - if (mvhd_parent_path_exists(paths, MVHD_DIF_LOC_W2KU)) { - par_fp = tmp_open_path; - goto paths_cleanup; - } - /* If we reach this point, we could not find a path with a valid file */ - par_fp = NULL; - *err = MVHD_ERR_PAR_NOT_FOUND; + int utf_outlen, utf_inlen, utf_ret; + char *par_fp = NULL; + /* We can't resolve relative paths if we don't have an absolute + path to work with */ + if (!cwk_path_is_absolute((const char *)vhdm->filename)) { + *err = MVHD_ERR_PATH_REL; + goto end; + } + struct MVHDPaths *paths = calloc(1, sizeof *paths); + if (paths == NULL) { + *err = MVHD_ERR_MEM; + goto end; + } + size_t dirlen; + cwk_path_get_dirname((const char *)vhdm->filename, &dirlen); + if (dirlen >= sizeof paths->dir_path) { + *err = MVHD_ERR_PATH_LEN; + goto paths_cleanup; + } + memcpy(paths->dir_path, vhdm->filename, dirlen); + /* Get the filename field from the sparse header. */ + utf_outlen = (int)sizeof paths->file_name; + utf_inlen = (int)sizeof vhdm->sparse.par_utf16_name; + utf_ret = UTF16BEToUTF8((unsigned char *)paths->file_name, &utf_outlen, + (const unsigned char *)vhdm->sparse.par_utf16_name, &utf_inlen); + if (utf_ret < 0) { + mvhd_set_encoding_err(utf_ret, err); + goto paths_cleanup; + } + /* Now read the parent locator entries, both relative and absolute, if they exist */ + unsigned char *loc_path; + int i; + for (i = 0; i < 8; i++) { + utf_outlen = MVHD_MAX_PATH_BYTES - 1; + if (vhdm->sparse.par_loc_entry[i].plat_code == MVHD_DIF_LOC_W2RU) { + loc_path = (unsigned char *)paths->w2ru_path; + } else if (vhdm->sparse.par_loc_entry[i].plat_code == MVHD_DIF_LOC_W2KU) { + loc_path = (unsigned char *)paths->w2ku_path; + } else { + continue; + } + utf_inlen = vhdm->sparse.par_loc_entry[i].plat_data_len; + if (utf_inlen > MVHD_MAX_PATH_BYTES) { + *err = MVHD_ERR_PATH_LEN; + goto paths_cleanup; + } + mvhd_fseeko64(vhdm->f, vhdm->sparse.par_loc_entry[i].plat_data_offset, SEEK_SET); + fread(paths->tmp_src_path, sizeof(uint8_t), utf_inlen, vhdm->f); + /* Note, the W2*u parent locators are UTF-16LE, unlike the filename field previously obtained, + which is UTF-16BE */ + utf_ret = UTF16LEToUTF8(loc_path, &utf_outlen, (const unsigned char *)paths->tmp_src_path, &utf_inlen); + if (utf_ret < 0) { + mvhd_set_encoding_err(utf_ret, err); + goto paths_cleanup; + } + } + /* We have paths in UTF-8. We should have enough info to try and find the parent VHD */ + /* Does the relative path exist? */ + if (mvhd_parent_path_exists(paths, MVHD_DIF_LOC_W2RU)) { + par_fp = tmp_open_path; + goto paths_cleanup; + } + /* What about trying the child directory? */ + if (mvhd_parent_path_exists(paths, 0)) { + par_fp = tmp_open_path; + goto paths_cleanup; + } + /* Well, all else fails, try the stored absolute path, if it exists */ + if (mvhd_parent_path_exists(paths, MVHD_DIF_LOC_W2KU)) { + par_fp = tmp_open_path; + goto paths_cleanup; + } + /* If we reach this point, we could not find a path with a valid file */ + par_fp = NULL; + *err = MVHD_ERR_PAR_NOT_FOUND; - paths_cleanup: - free(paths); - paths = NULL; - end: - return par_fp; +paths_cleanup: + free(paths); + paths = NULL; +end: + return par_fp; } /** * \brief Attach the read/write function pointers to read/write functions - * - * Depending on the VHD type, different sector reading and writing functions are used. + * + * Depending on the VHD type, different sector reading and writing functions are used. * The functions are called via function pointers stored in the vhdm struct. - * + * * \param [in] vhdm MiniVHD data structure */ static void mvhd_assign_io_funcs(MVHDMeta *vhdm) { - switch (vhdm->footer.disk_type) { - case MVHD_TYPE_FIXED:vhdm->read_sectors = mvhd_fixed_read; - vhdm->write_sectors = mvhd_fixed_write; - break; - case MVHD_TYPE_DYNAMIC:vhdm->read_sectors = mvhd_sparse_read; - vhdm->write_sectors = mvhd_sparse_diff_write; - break; - case MVHD_TYPE_DIFF:vhdm->read_sectors = mvhd_diff_read; - vhdm->write_sectors = mvhd_sparse_diff_write; - break; - } - if (vhdm->readonly) { - vhdm->write_sectors = mvhd_noop_write; - } + switch (vhdm->footer.disk_type) { + case MVHD_TYPE_FIXED: + vhdm->read_sectors = mvhd_fixed_read; + vhdm->write_sectors = mvhd_fixed_write; + break; + case MVHD_TYPE_DYNAMIC: + vhdm->read_sectors = mvhd_sparse_read; + vhdm->write_sectors = mvhd_sparse_diff_write; + break; + case MVHD_TYPE_DIFF: + vhdm->read_sectors = mvhd_diff_read; + vhdm->write_sectors = mvhd_sparse_diff_write; + break; + } + if (vhdm->readonly) { + vhdm->write_sectors = mvhd_noop_write; + } } bool mvhd_file_is_vhd(FILE *f) { - if (f) { - uint8_t con_str[8]; - mvhd_fseeko64(f, -MVHD_FOOTER_SIZE, SEEK_END); - fread(con_str, sizeof con_str, 1, f); - return mvhd_is_conectix_str(con_str); - } else { - return false; - } + if (f) { + uint8_t con_str[8]; + mvhd_fseeko64(f, -MVHD_FOOTER_SIZE, SEEK_END); + fread(con_str, sizeof con_str, 1, f); + return mvhd_is_conectix_str(con_str); + } else { + return false; + } } MVHDGeom mvhd_calculate_geometry(uint64_t size) { - MVHDGeom chs; - uint32_t ts = (uint32_t)(size / MVHD_SECTOR_SIZE); - uint32_t spt, heads, cyl, cth; - if (ts > 65535 * 16 * 255) { - ts = 65535 * 16 * 255; - } - if (ts >= 65535 * 16 * 63) { - spt = 255; - heads = 16; - cth = ts / spt; - } else { - spt = 17; - cth = ts / spt; - heads = (cth + 1023) / 1024; - if (heads < 4) { - heads = 4; - } - if (cth >= (heads * 1024) || heads > 16) { - spt = 31; - heads = 16; - cth = ts / spt; - } - if (cth >= (heads * 1024)) { - spt = 63; - heads = 16; - cth = ts / spt; - } - } - cyl = cth / heads; - chs.heads = heads; - chs.spt = spt; - chs.cyl = cyl; - return chs; + MVHDGeom chs; + uint32_t ts = (uint32_t)(size / MVHD_SECTOR_SIZE); + uint32_t spt, heads, cyl, cth; + if (ts > 65535 * 16 * 255) { + ts = 65535 * 16 * 255; + } + if (ts >= 65535 * 16 * 63) { + spt = 255; + heads = 16; + cth = ts / spt; + } else { + spt = 17; + cth = ts / spt; + heads = (cth + 1023) / 1024; + if (heads < 4) { + heads = 4; + } + if (cth >= (heads * 1024) || heads > 16) { + spt = 31; + heads = 16; + cth = ts / spt; + } + if (cth >= (heads * 1024)) { + spt = 63; + heads = 16; + cth = ts / spt; + } + } + cyl = cth / heads; + chs.heads = heads; + chs.spt = spt; + chs.cyl = cyl; + return chs; } MVHDMeta *mvhd_open(const char *path, bool readonly, int *err) { - MVHDError open_err; - MVHDMeta *vhdm = calloc(sizeof *vhdm, 1); - if (vhdm == NULL) { - *err = MVHD_ERR_MEM; - goto end; - } - if (strlen(path) >= sizeof vhdm->filename) { - *err = MVHD_ERR_PATH_LEN; - goto cleanup_vhdm; - } - //This is safe, as we've just checked for potential overflow above - strcpy(vhdm->filename, path); - vhdm->f = readonly ? mvhd_fopen((const char *)vhdm->filename, "rb", err) : mvhd_fopen((const char *)vhdm->filename, "rb+", err); - if (vhdm->f == NULL) { - /* note, mvhd_fopen sets err for us */ - goto cleanup_vhdm; - } - vhdm->readonly = readonly; - if (!mvhd_file_is_vhd(vhdm->f)) { - *err = MVHD_ERR_NOT_VHD; - goto cleanup_file; - } - mvhd_read_footer(vhdm); - if (!mvhd_footer_checksum_valid(vhdm)) { - *err = MVHD_ERR_FOOTER_CHECKSUM; - goto cleanup_file; - } - if (vhdm->footer.disk_type == MVHD_TYPE_DIFF || vhdm->footer.disk_type == MVHD_TYPE_DYNAMIC) { - mvhd_read_sparse_header(vhdm); - if (!mvhd_sparse_checksum_valid(vhdm)) { - *err = MVHD_ERR_SPARSE_CHECKSUM; - goto cleanup_file; - } - if (mvhd_read_bat(vhdm, &open_err) == -1) { - *err = open_err; - goto cleanup_file; - } - mvhd_calc_sparse_values(vhdm); - if (mvhd_init_sector_bitmap(vhdm, &open_err) == -1) { - *err = open_err; - goto cleanup_bat; - } + MVHDError open_err; + MVHDMeta *vhdm = calloc(sizeof *vhdm, 1); + if (vhdm == NULL) { + *err = MVHD_ERR_MEM; + goto end; + } + if (strlen(path) >= sizeof vhdm->filename) { + *err = MVHD_ERR_PATH_LEN; + goto cleanup_vhdm; + } + // This is safe, as we've just checked for potential overflow above + strcpy(vhdm->filename, path); + vhdm->f = readonly ? mvhd_fopen((const char *)vhdm->filename, "rb", err) + : mvhd_fopen((const char *)vhdm->filename, "rb+", err); + if (vhdm->f == NULL) { + /* note, mvhd_fopen sets err for us */ + goto cleanup_vhdm; + } + vhdm->readonly = readonly; + if (!mvhd_file_is_vhd(vhdm->f)) { + *err = MVHD_ERR_NOT_VHD; + goto cleanup_file; + } + mvhd_read_footer(vhdm); + if (!mvhd_footer_checksum_valid(vhdm)) { + *err = MVHD_ERR_FOOTER_CHECKSUM; + goto cleanup_file; + } + if (vhdm->footer.disk_type == MVHD_TYPE_DIFF || vhdm->footer.disk_type == MVHD_TYPE_DYNAMIC) { + mvhd_read_sparse_header(vhdm); + if (!mvhd_sparse_checksum_valid(vhdm)) { + *err = MVHD_ERR_SPARSE_CHECKSUM; + goto cleanup_file; + } + if (mvhd_read_bat(vhdm, &open_err) == -1) { + *err = open_err; + goto cleanup_file; + } + mvhd_calc_sparse_values(vhdm); + if (mvhd_init_sector_bitmap(vhdm, &open_err) == -1) { + *err = open_err; + goto cleanup_bat; + } - } else if (vhdm->footer.disk_type != MVHD_TYPE_FIXED) { - *err = MVHD_ERR_TYPE; - goto cleanup_bitmap; - } - mvhd_assign_io_funcs(vhdm); - vhdm->format_buffer.zero_data = calloc(64, MVHD_SECTOR_SIZE); - if (vhdm->format_buffer.zero_data == NULL) { - *err = MVHD_ERR_MEM; - goto cleanup_bitmap; - } - vhdm->format_buffer.sector_count = 64; - if (vhdm->footer.disk_type == MVHD_TYPE_DIFF) { - char *par_path = mvhd_get_diff_parent_path(vhdm, err); - if (par_path == NULL) { - goto cleanup_format_buff; - } - uint32_t par_mod_ts = mvhd_file_mod_timestamp(par_path, err); - if (*err != 0) { - goto cleanup_format_buff; - } - if (vhdm->sparse.par_timestamp != par_mod_ts) { - /* The last-modified timestamp is to fragile to make this a fatal error. - Instead, we inform the caller of the potential problem. */ - *err = MVHD_ERR_TIMESTAMP; - } - vhdm->parent = mvhd_open(par_path, true, err); - if (vhdm->parent == NULL) { - goto cleanup_format_buff; - } - if (memcmp(vhdm->sparse.par_uuid, vhdm->parent->footer.uuid, sizeof vhdm->sparse.par_uuid) != 0) { - *err = MVHD_ERR_INVALID_PAR_UUID; - goto cleanup_format_buff; - } - } - /* If we've reached this point, we are good to go, so skip the cleanup steps */ - goto end; - cleanup_format_buff: - free(vhdm->format_buffer.zero_data); - vhdm->format_buffer.zero_data = NULL; - cleanup_bitmap: - free(vhdm->bitmap.curr_bitmap); - vhdm->bitmap.curr_bitmap = NULL; - cleanup_bat: - free(vhdm->block_offset); - vhdm->block_offset = NULL; - cleanup_file: - fclose(vhdm->f); - vhdm->f = NULL; - cleanup_vhdm: - free(vhdm); - vhdm = NULL; - end: - return vhdm; + } else if (vhdm->footer.disk_type != MVHD_TYPE_FIXED) { + *err = MVHD_ERR_TYPE; + goto cleanup_bitmap; + } + mvhd_assign_io_funcs(vhdm); + vhdm->format_buffer.zero_data = calloc(64, MVHD_SECTOR_SIZE); + if (vhdm->format_buffer.zero_data == NULL) { + *err = MVHD_ERR_MEM; + goto cleanup_bitmap; + } + vhdm->format_buffer.sector_count = 64; + if (vhdm->footer.disk_type == MVHD_TYPE_DIFF) { + char *par_path = mvhd_get_diff_parent_path(vhdm, err); + if (par_path == NULL) { + goto cleanup_format_buff; + } + uint32_t par_mod_ts = mvhd_file_mod_timestamp(par_path, err); + if (*err != 0) { + goto cleanup_format_buff; + } + if (vhdm->sparse.par_timestamp != par_mod_ts) { + /* The last-modified timestamp is to fragile to make this a fatal error. + Instead, we inform the caller of the potential problem. */ + *err = MVHD_ERR_TIMESTAMP; + } + vhdm->parent = mvhd_open(par_path, true, err); + if (vhdm->parent == NULL) { + goto cleanup_format_buff; + } + if (memcmp(vhdm->sparse.par_uuid, vhdm->parent->footer.uuid, sizeof vhdm->sparse.par_uuid) != 0) { + *err = MVHD_ERR_INVALID_PAR_UUID; + goto cleanup_format_buff; + } + } + /* If we've reached this point, we are good to go, so skip the cleanup steps */ + goto end; +cleanup_format_buff: + free(vhdm->format_buffer.zero_data); + vhdm->format_buffer.zero_data = NULL; +cleanup_bitmap: + free(vhdm->bitmap.curr_bitmap); + vhdm->bitmap.curr_bitmap = NULL; +cleanup_bat: + free(vhdm->block_offset); + vhdm->block_offset = NULL; +cleanup_file: + fclose(vhdm->f); + vhdm->f = NULL; +cleanup_vhdm: + free(vhdm); + vhdm = NULL; +end: + return vhdm; } void mvhd_close(MVHDMeta *vhdm) { - if (vhdm != NULL) { - if (vhdm->parent != NULL) { - mvhd_close(vhdm->parent); - } - fclose(vhdm->f); - if (vhdm->block_offset != NULL) { - free(vhdm->block_offset); - vhdm->block_offset = NULL; - } - if (vhdm->bitmap.curr_bitmap != NULL) { - free(vhdm->bitmap.curr_bitmap); - vhdm->bitmap.curr_bitmap = NULL; - } - if (vhdm->format_buffer.zero_data != NULL) { - free(vhdm->format_buffer.zero_data); - vhdm->format_buffer.zero_data = NULL; - } - free(vhdm); - vhdm = NULL; - } + if (vhdm != NULL) { + if (vhdm->parent != NULL) { + mvhd_close(vhdm->parent); + } + fclose(vhdm->f); + if (vhdm->block_offset != NULL) { + free(vhdm->block_offset); + vhdm->block_offset = NULL; + } + if (vhdm->bitmap.curr_bitmap != NULL) { + free(vhdm->bitmap.curr_bitmap); + vhdm->bitmap.curr_bitmap = NULL; + } + if (vhdm->format_buffer.zero_data != NULL) { + free(vhdm->format_buffer.zero_data); + vhdm->format_buffer.zero_data = NULL; + } + free(vhdm); + vhdm = NULL; + } } int mvhd_diff_update_par_timestamp(MVHDMeta *vhdm, int *err) { - uint8_t sparse_buff[1024]; - if (vhdm == NULL || err == NULL) { - *err = MVHD_ERR_INVALID_PARAMS; - return -1; - } - if (vhdm->footer.disk_type != MVHD_TYPE_DIFF) { - *err = MVHD_ERR_TYPE; - return -1; - } - char *par_path = mvhd_get_diff_parent_path(vhdm, err); - if (par_path == NULL) { - return -1; - } - uint32_t par_mod_ts = mvhd_file_mod_timestamp(par_path, err); - if (*err != 0) { - return -1; - } - /* Update the timestamp and sparse header checksum */ - vhdm->sparse.par_timestamp = par_mod_ts; - vhdm->sparse.checksum = mvhd_gen_sparse_checksum(&vhdm->sparse); - /* Generate and write the updated sparse header */ - mvhd_header_to_buffer(&vhdm->sparse, sparse_buff); - mvhd_fseeko64(vhdm->f, (int64_t)vhdm->footer.data_offset, SEEK_SET); - fwrite(sparse_buff, sizeof sparse_buff, 1, vhdm->f); - return 0; + uint8_t sparse_buff[1024]; + if (vhdm == NULL || err == NULL) { + *err = MVHD_ERR_INVALID_PARAMS; + return -1; + } + if (vhdm->footer.disk_type != MVHD_TYPE_DIFF) { + *err = MVHD_ERR_TYPE; + return -1; + } + char *par_path = mvhd_get_diff_parent_path(vhdm, err); + if (par_path == NULL) { + return -1; + } + uint32_t par_mod_ts = mvhd_file_mod_timestamp(par_path, err); + if (*err != 0) { + return -1; + } + /* Update the timestamp and sparse header checksum */ + vhdm->sparse.par_timestamp = par_mod_ts; + vhdm->sparse.checksum = mvhd_gen_sparse_checksum(&vhdm->sparse); + /* Generate and write the updated sparse header */ + mvhd_header_to_buffer(&vhdm->sparse, sparse_buff); + mvhd_fseeko64(vhdm->f, (int64_t)vhdm->footer.data_offset, SEEK_SET); + fwrite(sparse_buff, sizeof sparse_buff, 1, vhdm->f); + return 0; } int mvhd_read_sectors(MVHDMeta *vhdm, uint32_t offset, int num_sectors, void *out_buff) { - return vhdm->read_sectors(vhdm, offset, num_sectors, out_buff); + return vhdm->read_sectors(vhdm, offset, num_sectors, out_buff); } int mvhd_write_sectors(MVHDMeta *vhdm, uint32_t offset, int num_sectors, void *in_buff) { - return vhdm->write_sectors(vhdm, offset, num_sectors, in_buff); + return vhdm->write_sectors(vhdm, offset, num_sectors, in_buff); } int mvhd_format_sectors(MVHDMeta *vhdm, uint32_t offset, int num_sectors) { - int num_full = num_sectors / vhdm->format_buffer.sector_count; - int remain = num_sectors % vhdm->format_buffer.sector_count; - int i; - for (i = 0; i < num_full; i++) { - vhdm->write_sectors(vhdm, offset, vhdm->format_buffer.sector_count, vhdm->format_buffer.zero_data); - offset += vhdm->format_buffer.sector_count; - } - vhdm->write_sectors(vhdm, offset, remain, vhdm->format_buffer.zero_data); - return 0; + int num_full = num_sectors / vhdm->format_buffer.sector_count; + int remain = num_sectors % vhdm->format_buffer.sector_count; + int i; + for (i = 0; i < num_full; i++) { + vhdm->write_sectors(vhdm, offset, vhdm->format_buffer.sector_count, vhdm->format_buffer.zero_data); + offset += vhdm->format_buffer.sector_count; + } + vhdm->write_sectors(vhdm, offset, remain, vhdm->format_buffer.zero_data); + return 0; } diff --git a/src/hdd/minivhd/minivhd_struct_rw.c b/src/hdd/minivhd/minivhd_struct_rw.c index 3815a5e2..301d1758 100644 --- a/src/hdd/minivhd/minivhd_struct_rw.c +++ b/src/hdd/minivhd/minivhd_struct_rw.c @@ -24,140 +24,156 @@ static void mvhd_next_struct_to_buffer(void *struct_memb, size_t memb_size, bool /** * \brief Get the next field from a buffer and store it in a struct member, converting endian if necessary - * + * * \param [out] struct_memb struct member to save the field to * \param [in] memb_size the size of struct_memb, in bytes * \param [in] req_endian is the field a value that requires endian conversion (eg: uint16, uint32) * \param [in] buffer the buffer from which fields are read from. Will be advanced at the end of the function call */ static void mvhd_next_buffer_to_struct(void *struct_memb, size_t memb_size, bool req_endian, uint8_t **buffer) { - memcpy(struct_memb, *buffer, memb_size); - if (req_endian) { - switch (memb_size) { - case 2:*(uint16_t *)(struct_memb) = mvhd_from_be16(*(uint16_t *)(struct_memb)); - break; - case 4:*(uint32_t *)(struct_memb) = mvhd_from_be32(*(uint32_t *)(struct_memb)); - break; - case 8:*(uint64_t *)(struct_memb) = mvhd_from_be64(*(uint64_t *)(struct_memb)); - break; - } - } - *buffer += memb_size; + memcpy(struct_memb, *buffer, memb_size); + if (req_endian) { + switch (memb_size) { + case 2: + *(uint16_t *)(struct_memb) = mvhd_from_be16(*(uint16_t *)(struct_memb)); + break; + case 4: + *(uint32_t *)(struct_memb) = mvhd_from_be32(*(uint32_t *)(struct_memb)); + break; + case 8: + *(uint64_t *)(struct_memb) = mvhd_from_be64(*(uint64_t *)(struct_memb)); + break; + } + } + *buffer += memb_size; } /** * \brief Save a struct member into a buffer, converting endian if necessary - * + * * \param [in] struct_memb struct member read from * \param [in] memb_size the size of struct_memb, in bytes * \param [in] req_endian is the field a value that requires endian conversion (eg: uint16, uint32) * \param [out] buffer the buffer from which struct member is saved to. Will be advanced at the end of the function call */ static void mvhd_next_struct_to_buffer(void *struct_memb, size_t memb_size, bool req_endian, uint8_t **buffer) { - uint8_t *buf_ptr = *buffer; - memcpy(buf_ptr, struct_memb, memb_size); - if (req_endian) { - switch (memb_size) { - case 2:*((uint16_t *)buf_ptr) = mvhd_to_be16(*(uint16_t *)(struct_memb)); - break; - case 4:*((uint32_t *)buf_ptr) = mvhd_to_be32(*(uint32_t *)(struct_memb)); - break; - case 8:*((uint64_t *)buf_ptr) = mvhd_to_be64(*(uint64_t *)(struct_memb)); - break; - } - } - buf_ptr += memb_size; - *buffer = buf_ptr; + uint8_t *buf_ptr = *buffer; + memcpy(buf_ptr, struct_memb, memb_size); + if (req_endian) { + switch (memb_size) { + case 2: + *((uint16_t *)buf_ptr) = mvhd_to_be16(*(uint16_t *)(struct_memb)); + break; + case 4: + *((uint32_t *)buf_ptr) = mvhd_to_be32(*(uint32_t *)(struct_memb)); + break; + case 8: + *((uint64_t *)buf_ptr) = mvhd_to_be64(*(uint64_t *)(struct_memb)); + break; + } + } + buf_ptr += memb_size; + *buffer = buf_ptr; } void mvhd_buffer_to_footer(MVHDFooter *footer, uint8_t *buffer) { - uint8_t *buff_ptr = buffer; - mvhd_next_buffer_to_struct(&footer->cookie, sizeof footer->cookie, false, &buff_ptr); - mvhd_next_buffer_to_struct(&footer->features, sizeof footer->features, true, &buff_ptr); - mvhd_next_buffer_to_struct(&footer->fi_fmt_vers, sizeof footer->fi_fmt_vers, true, &buff_ptr); - mvhd_next_buffer_to_struct(&footer->data_offset, sizeof footer->data_offset, true, &buff_ptr); - mvhd_next_buffer_to_struct(&footer->timestamp, sizeof footer->timestamp, true, &buff_ptr); - mvhd_next_buffer_to_struct(&footer->cr_app, sizeof footer->cr_app, false, &buff_ptr); - mvhd_next_buffer_to_struct(&footer->cr_vers, sizeof footer->cr_vers, true, &buff_ptr); - mvhd_next_buffer_to_struct(&footer->cr_host_os, sizeof footer->cr_host_os, false, &buff_ptr); - mvhd_next_buffer_to_struct(&footer->orig_sz, sizeof footer->orig_sz, true, &buff_ptr); - mvhd_next_buffer_to_struct(&footer->curr_sz, sizeof footer->curr_sz, true, &buff_ptr); - mvhd_next_buffer_to_struct(&footer->geom.cyl, sizeof footer->geom.cyl, true, &buff_ptr); - mvhd_next_buffer_to_struct(&footer->geom.heads, sizeof footer->geom.heads, false, &buff_ptr); - mvhd_next_buffer_to_struct(&footer->geom.spt, sizeof footer->geom.spt, false, &buff_ptr); - mvhd_next_buffer_to_struct(&footer->disk_type, sizeof footer->disk_type, true, &buff_ptr); - mvhd_next_buffer_to_struct(&footer->checksum, sizeof footer->checksum, true, &buff_ptr); - mvhd_next_buffer_to_struct(&footer->uuid, sizeof footer->uuid, false, &buff_ptr); - mvhd_next_buffer_to_struct(&footer->saved_st, sizeof footer->saved_st, false, &buff_ptr); - mvhd_next_buffer_to_struct(&footer->reserved, sizeof footer->reserved, false, &buff_ptr); + uint8_t *buff_ptr = buffer; + mvhd_next_buffer_to_struct(&footer->cookie, sizeof footer->cookie, false, &buff_ptr); + mvhd_next_buffer_to_struct(&footer->features, sizeof footer->features, true, &buff_ptr); + mvhd_next_buffer_to_struct(&footer->fi_fmt_vers, sizeof footer->fi_fmt_vers, true, &buff_ptr); + mvhd_next_buffer_to_struct(&footer->data_offset, sizeof footer->data_offset, true, &buff_ptr); + mvhd_next_buffer_to_struct(&footer->timestamp, sizeof footer->timestamp, true, &buff_ptr); + mvhd_next_buffer_to_struct(&footer->cr_app, sizeof footer->cr_app, false, &buff_ptr); + mvhd_next_buffer_to_struct(&footer->cr_vers, sizeof footer->cr_vers, true, &buff_ptr); + mvhd_next_buffer_to_struct(&footer->cr_host_os, sizeof footer->cr_host_os, false, &buff_ptr); + mvhd_next_buffer_to_struct(&footer->orig_sz, sizeof footer->orig_sz, true, &buff_ptr); + mvhd_next_buffer_to_struct(&footer->curr_sz, sizeof footer->curr_sz, true, &buff_ptr); + mvhd_next_buffer_to_struct(&footer->geom.cyl, sizeof footer->geom.cyl, true, &buff_ptr); + mvhd_next_buffer_to_struct(&footer->geom.heads, sizeof footer->geom.heads, false, &buff_ptr); + mvhd_next_buffer_to_struct(&footer->geom.spt, sizeof footer->geom.spt, false, &buff_ptr); + mvhd_next_buffer_to_struct(&footer->disk_type, sizeof footer->disk_type, true, &buff_ptr); + mvhd_next_buffer_to_struct(&footer->checksum, sizeof footer->checksum, true, &buff_ptr); + mvhd_next_buffer_to_struct(&footer->uuid, sizeof footer->uuid, false, &buff_ptr); + mvhd_next_buffer_to_struct(&footer->saved_st, sizeof footer->saved_st, false, &buff_ptr); + mvhd_next_buffer_to_struct(&footer->reserved, sizeof footer->reserved, false, &buff_ptr); } void mvhd_footer_to_buffer(MVHDFooter *footer, uint8_t *buffer) { - uint8_t *buff_ptr = buffer; - mvhd_next_struct_to_buffer(&footer->cookie, sizeof footer->cookie, false, &buff_ptr); - mvhd_next_struct_to_buffer(&footer->features, sizeof footer->features, true, &buff_ptr); - mvhd_next_struct_to_buffer(&footer->fi_fmt_vers, sizeof footer->fi_fmt_vers, true, &buff_ptr); - mvhd_next_struct_to_buffer(&footer->data_offset, sizeof footer->data_offset, true, &buff_ptr); - mvhd_next_struct_to_buffer(&footer->timestamp, sizeof footer->timestamp, true, &buff_ptr); - mvhd_next_struct_to_buffer(&footer->cr_app, sizeof footer->cr_app, false, &buff_ptr); - mvhd_next_struct_to_buffer(&footer->cr_vers, sizeof footer->cr_vers, true, &buff_ptr); - mvhd_next_struct_to_buffer(&footer->cr_host_os, sizeof footer->cr_host_os, false, &buff_ptr); - mvhd_next_struct_to_buffer(&footer->orig_sz, sizeof footer->orig_sz, true, &buff_ptr); - mvhd_next_struct_to_buffer(&footer->curr_sz, sizeof footer->curr_sz, true, &buff_ptr); - mvhd_next_struct_to_buffer(&footer->geom.cyl, sizeof footer->geom.cyl, true, &buff_ptr); - mvhd_next_struct_to_buffer(&footer->geom.heads, sizeof footer->geom.heads, false, &buff_ptr); - mvhd_next_struct_to_buffer(&footer->geom.spt, sizeof footer->geom.spt, false, &buff_ptr); - mvhd_next_struct_to_buffer(&footer->disk_type, sizeof footer->disk_type, true, &buff_ptr); - mvhd_next_struct_to_buffer(&footer->checksum, sizeof footer->checksum, true, &buff_ptr); - mvhd_next_struct_to_buffer(&footer->uuid, sizeof footer->uuid, false, &buff_ptr); - mvhd_next_struct_to_buffer(&footer->saved_st, sizeof footer->saved_st, false, &buff_ptr); - mvhd_next_struct_to_buffer(&footer->reserved, sizeof footer->reserved, false, &buff_ptr); + uint8_t *buff_ptr = buffer; + mvhd_next_struct_to_buffer(&footer->cookie, sizeof footer->cookie, false, &buff_ptr); + mvhd_next_struct_to_buffer(&footer->features, sizeof footer->features, true, &buff_ptr); + mvhd_next_struct_to_buffer(&footer->fi_fmt_vers, sizeof footer->fi_fmt_vers, true, &buff_ptr); + mvhd_next_struct_to_buffer(&footer->data_offset, sizeof footer->data_offset, true, &buff_ptr); + mvhd_next_struct_to_buffer(&footer->timestamp, sizeof footer->timestamp, true, &buff_ptr); + mvhd_next_struct_to_buffer(&footer->cr_app, sizeof footer->cr_app, false, &buff_ptr); + mvhd_next_struct_to_buffer(&footer->cr_vers, sizeof footer->cr_vers, true, &buff_ptr); + mvhd_next_struct_to_buffer(&footer->cr_host_os, sizeof footer->cr_host_os, false, &buff_ptr); + mvhd_next_struct_to_buffer(&footer->orig_sz, sizeof footer->orig_sz, true, &buff_ptr); + mvhd_next_struct_to_buffer(&footer->curr_sz, sizeof footer->curr_sz, true, &buff_ptr); + mvhd_next_struct_to_buffer(&footer->geom.cyl, sizeof footer->geom.cyl, true, &buff_ptr); + mvhd_next_struct_to_buffer(&footer->geom.heads, sizeof footer->geom.heads, false, &buff_ptr); + mvhd_next_struct_to_buffer(&footer->geom.spt, sizeof footer->geom.spt, false, &buff_ptr); + mvhd_next_struct_to_buffer(&footer->disk_type, sizeof footer->disk_type, true, &buff_ptr); + mvhd_next_struct_to_buffer(&footer->checksum, sizeof footer->checksum, true, &buff_ptr); + mvhd_next_struct_to_buffer(&footer->uuid, sizeof footer->uuid, false, &buff_ptr); + mvhd_next_struct_to_buffer(&footer->saved_st, sizeof footer->saved_st, false, &buff_ptr); + mvhd_next_struct_to_buffer(&footer->reserved, sizeof footer->reserved, false, &buff_ptr); } void mvhd_buffer_to_header(MVHDSparseHeader *header, uint8_t *buffer) { - uint8_t *buff_ptr = buffer; - mvhd_next_buffer_to_struct(&header->cookie, sizeof header->cookie, false, &buff_ptr); - mvhd_next_buffer_to_struct(&header->data_offset, sizeof header->data_offset, true, &buff_ptr); - mvhd_next_buffer_to_struct(&header->bat_offset, sizeof header->bat_offset, true, &buff_ptr); - mvhd_next_buffer_to_struct(&header->head_vers, sizeof header->head_vers, true, &buff_ptr); - mvhd_next_buffer_to_struct(&header->max_bat_ent, sizeof header->max_bat_ent, true, &buff_ptr); - mvhd_next_buffer_to_struct(&header->block_sz, sizeof header->block_sz, true, &buff_ptr); - mvhd_next_buffer_to_struct(&header->checksum, sizeof header->checksum, true, &buff_ptr); - mvhd_next_buffer_to_struct(&header->par_uuid, sizeof header->par_uuid, false, &buff_ptr); - mvhd_next_buffer_to_struct(&header->par_timestamp, sizeof header->par_timestamp, true, &buff_ptr); - mvhd_next_buffer_to_struct(&header->reserved_1, sizeof header->reserved_1, true, &buff_ptr); - mvhd_next_buffer_to_struct(&header->par_utf16_name, sizeof header->par_utf16_name, false, &buff_ptr); - int i; - for (i = 0; i < 8; i++) { - mvhd_next_buffer_to_struct(&header->par_loc_entry[i].plat_code, sizeof header->par_loc_entry[i].plat_code, true, &buff_ptr); - mvhd_next_buffer_to_struct(&header->par_loc_entry[i].plat_data_space, sizeof header->par_loc_entry[i].plat_data_space, true, &buff_ptr); - mvhd_next_buffer_to_struct(&header->par_loc_entry[i].plat_data_len, sizeof header->par_loc_entry[i].plat_data_len, true, &buff_ptr); - mvhd_next_buffer_to_struct(&header->par_loc_entry[i].reserved, sizeof header->par_loc_entry[i].reserved, true, &buff_ptr); - mvhd_next_buffer_to_struct(&header->par_loc_entry[i].plat_data_offset, sizeof header->par_loc_entry[i].plat_data_offset, true, &buff_ptr); - } - mvhd_next_buffer_to_struct(&header->reserved_2, sizeof header->reserved_2, false, &buff_ptr); + uint8_t *buff_ptr = buffer; + mvhd_next_buffer_to_struct(&header->cookie, sizeof header->cookie, false, &buff_ptr); + mvhd_next_buffer_to_struct(&header->data_offset, sizeof header->data_offset, true, &buff_ptr); + mvhd_next_buffer_to_struct(&header->bat_offset, sizeof header->bat_offset, true, &buff_ptr); + mvhd_next_buffer_to_struct(&header->head_vers, sizeof header->head_vers, true, &buff_ptr); + mvhd_next_buffer_to_struct(&header->max_bat_ent, sizeof header->max_bat_ent, true, &buff_ptr); + mvhd_next_buffer_to_struct(&header->block_sz, sizeof header->block_sz, true, &buff_ptr); + mvhd_next_buffer_to_struct(&header->checksum, sizeof header->checksum, true, &buff_ptr); + mvhd_next_buffer_to_struct(&header->par_uuid, sizeof header->par_uuid, false, &buff_ptr); + mvhd_next_buffer_to_struct(&header->par_timestamp, sizeof header->par_timestamp, true, &buff_ptr); + mvhd_next_buffer_to_struct(&header->reserved_1, sizeof header->reserved_1, true, &buff_ptr); + mvhd_next_buffer_to_struct(&header->par_utf16_name, sizeof header->par_utf16_name, false, &buff_ptr); + int i; + for (i = 0; i < 8; i++) { + mvhd_next_buffer_to_struct(&header->par_loc_entry[i].plat_code, sizeof header->par_loc_entry[i].plat_code, true, + &buff_ptr); + mvhd_next_buffer_to_struct(&header->par_loc_entry[i].plat_data_space, + sizeof header->par_loc_entry[i].plat_data_space, true, &buff_ptr); + mvhd_next_buffer_to_struct(&header->par_loc_entry[i].plat_data_len, sizeof header->par_loc_entry[i].plat_data_len, + true, &buff_ptr); + mvhd_next_buffer_to_struct(&header->par_loc_entry[i].reserved, sizeof header->par_loc_entry[i].reserved, true, + &buff_ptr); + mvhd_next_buffer_to_struct(&header->par_loc_entry[i].plat_data_offset, + sizeof header->par_loc_entry[i].plat_data_offset, true, &buff_ptr); + } + mvhd_next_buffer_to_struct(&header->reserved_2, sizeof header->reserved_2, false, &buff_ptr); } void mvhd_header_to_buffer(MVHDSparseHeader *header, uint8_t *buffer) { - uint8_t *buff_ptr = buffer; - mvhd_next_struct_to_buffer(&header->cookie, sizeof header->cookie, false, &buff_ptr); - mvhd_next_struct_to_buffer(&header->data_offset, sizeof header->data_offset, true, &buff_ptr); - mvhd_next_struct_to_buffer(&header->bat_offset, sizeof header->bat_offset, true, &buff_ptr); - mvhd_next_struct_to_buffer(&header->head_vers, sizeof header->head_vers, true, &buff_ptr); - mvhd_next_struct_to_buffer(&header->max_bat_ent, sizeof header->max_bat_ent, true, &buff_ptr); - mvhd_next_struct_to_buffer(&header->block_sz, sizeof header->block_sz, true, &buff_ptr); - mvhd_next_struct_to_buffer(&header->checksum, sizeof header->checksum, true, &buff_ptr); - mvhd_next_struct_to_buffer(&header->par_uuid, sizeof header->par_uuid, false, &buff_ptr); - mvhd_next_struct_to_buffer(&header->par_timestamp, sizeof header->par_timestamp, true, &buff_ptr); - mvhd_next_struct_to_buffer(&header->reserved_1, sizeof header->reserved_1, true, &buff_ptr); - mvhd_next_struct_to_buffer(&header->par_utf16_name, sizeof header->par_utf16_name, false, &buff_ptr); - int i; - for (i = 0; i < 8; i++) { - mvhd_next_struct_to_buffer(&header->par_loc_entry[i].plat_code, sizeof header->par_loc_entry[i].plat_code, true, &buff_ptr); - mvhd_next_struct_to_buffer(&header->par_loc_entry[i].plat_data_space, sizeof header->par_loc_entry[i].plat_data_space, true, &buff_ptr); - mvhd_next_struct_to_buffer(&header->par_loc_entry[i].plat_data_len, sizeof header->par_loc_entry[i].plat_data_len, true, &buff_ptr); - mvhd_next_struct_to_buffer(&header->par_loc_entry[i].reserved, sizeof header->par_loc_entry[i].reserved, true, &buff_ptr); - mvhd_next_struct_to_buffer(&header->par_loc_entry[i].plat_data_offset, sizeof header->par_loc_entry[i].plat_data_offset, true, &buff_ptr); - } - mvhd_next_struct_to_buffer(&header->reserved_2, sizeof header->reserved_2, false, &buff_ptr); + uint8_t *buff_ptr = buffer; + mvhd_next_struct_to_buffer(&header->cookie, sizeof header->cookie, false, &buff_ptr); + mvhd_next_struct_to_buffer(&header->data_offset, sizeof header->data_offset, true, &buff_ptr); + mvhd_next_struct_to_buffer(&header->bat_offset, sizeof header->bat_offset, true, &buff_ptr); + mvhd_next_struct_to_buffer(&header->head_vers, sizeof header->head_vers, true, &buff_ptr); + mvhd_next_struct_to_buffer(&header->max_bat_ent, sizeof header->max_bat_ent, true, &buff_ptr); + mvhd_next_struct_to_buffer(&header->block_sz, sizeof header->block_sz, true, &buff_ptr); + mvhd_next_struct_to_buffer(&header->checksum, sizeof header->checksum, true, &buff_ptr); + mvhd_next_struct_to_buffer(&header->par_uuid, sizeof header->par_uuid, false, &buff_ptr); + mvhd_next_struct_to_buffer(&header->par_timestamp, sizeof header->par_timestamp, true, &buff_ptr); + mvhd_next_struct_to_buffer(&header->reserved_1, sizeof header->reserved_1, true, &buff_ptr); + mvhd_next_struct_to_buffer(&header->par_utf16_name, sizeof header->par_utf16_name, false, &buff_ptr); + int i; + for (i = 0; i < 8; i++) { + mvhd_next_struct_to_buffer(&header->par_loc_entry[i].plat_code, sizeof header->par_loc_entry[i].plat_code, true, + &buff_ptr); + mvhd_next_struct_to_buffer(&header->par_loc_entry[i].plat_data_space, + sizeof header->par_loc_entry[i].plat_data_space, true, &buff_ptr); + mvhd_next_struct_to_buffer(&header->par_loc_entry[i].plat_data_len, sizeof header->par_loc_entry[i].plat_data_len, + true, &buff_ptr); + mvhd_next_struct_to_buffer(&header->par_loc_entry[i].reserved, sizeof header->par_loc_entry[i].reserved, true, + &buff_ptr); + mvhd_next_struct_to_buffer(&header->par_loc_entry[i].plat_data_offset, + sizeof header->par_loc_entry[i].plat_data_offset, true, &buff_ptr); + } + mvhd_next_struct_to_buffer(&header->reserved_2, sizeof header->reserved_2, false, &buff_ptr); } diff --git a/src/hdd/minivhd/minivhd_util.c b/src/hdd/minivhd/minivhd_util.c index d5e60168..9d30f18e 100644 --- a/src/hdd/minivhd/minivhd_util.c +++ b/src/hdd/minivhd/minivhd_util.c @@ -24,295 +24,309 @@ const char MVHD_CREATOR_HOST_OS[] = "Wi2k"; const char MVHD_CXSPARSE_COOKIE[] = "cxsparse"; uint16_t mvhd_from_be16(uint16_t val) { - uint8_t *tmp = (uint8_t *)&val; - uint16_t ret = 0; - ret |= (uint16_t)tmp[0] << 8; - ret |= (uint16_t)tmp[1] << 0; - return ret; + uint8_t *tmp = (uint8_t *)&val; + uint16_t ret = 0; + ret |= (uint16_t)tmp[0] << 8; + ret |= (uint16_t)tmp[1] << 0; + return ret; } uint32_t mvhd_from_be32(uint32_t val) { - uint8_t *tmp = (uint8_t *)&val; - uint32_t ret = 0; - ret = (uint32_t)tmp[0] << 24; - ret |= (uint32_t)tmp[1] << 16; - ret |= (uint32_t)tmp[2] << 8; - ret |= (uint32_t)tmp[3] << 0; - return ret; + uint8_t *tmp = (uint8_t *)&val; + uint32_t ret = 0; + ret = (uint32_t)tmp[0] << 24; + ret |= (uint32_t)tmp[1] << 16; + ret |= (uint32_t)tmp[2] << 8; + ret |= (uint32_t)tmp[3] << 0; + return ret; } uint64_t mvhd_from_be64(uint64_t val) { - uint8_t *tmp = (uint8_t *)&val; - uint64_t ret = 0; - ret = (uint64_t)tmp[0] << 56; - ret |= (uint64_t)tmp[1] << 48; - ret |= (uint64_t)tmp[2] << 40; - ret |= (uint64_t)tmp[3] << 32; - ret |= (uint64_t)tmp[4] << 24; - ret |= (uint64_t)tmp[5] << 16; - ret |= (uint64_t)tmp[6] << 8; - ret |= (uint64_t)tmp[7] << 0; - return ret; + uint8_t *tmp = (uint8_t *)&val; + uint64_t ret = 0; + ret = (uint64_t)tmp[0] << 56; + ret |= (uint64_t)tmp[1] << 48; + ret |= (uint64_t)tmp[2] << 40; + ret |= (uint64_t)tmp[3] << 32; + ret |= (uint64_t)tmp[4] << 24; + ret |= (uint64_t)tmp[5] << 16; + ret |= (uint64_t)tmp[6] << 8; + ret |= (uint64_t)tmp[7] << 0; + return ret; } uint16_t mvhd_to_be16(uint16_t val) { - uint16_t ret = 0; - uint8_t *tmp = (uint8_t *)&ret; - tmp[0] = (val & 0xff00) >> 8; - tmp[1] = (val & 0x00ff) >> 0; - return ret; + uint16_t ret = 0; + uint8_t *tmp = (uint8_t *)&ret; + tmp[0] = (val & 0xff00) >> 8; + tmp[1] = (val & 0x00ff) >> 0; + return ret; } uint32_t mvhd_to_be32(uint32_t val) { - uint32_t ret = 0; - uint8_t *tmp = (uint8_t *)&ret; - tmp[0] = (val & 0xff000000) >> 24; - tmp[1] = (val & 0x00ff0000) >> 16; - tmp[2] = (val & 0x0000ff00) >> 8; - tmp[3] = (val & 0x000000ff) >> 0; - return ret; + uint32_t ret = 0; + uint8_t *tmp = (uint8_t *)&ret; + tmp[0] = (val & 0xff000000) >> 24; + tmp[1] = (val & 0x00ff0000) >> 16; + tmp[2] = (val & 0x0000ff00) >> 8; + tmp[3] = (val & 0x000000ff) >> 0; + return ret; } uint64_t mvhd_to_be64(uint64_t val) { - uint64_t ret = 0; - uint8_t *tmp = (uint8_t *)&ret; - tmp[0] = (uint8_t)((val & 0xff00000000000000) >> 56); - tmp[1] = (uint8_t)((val & 0x00ff000000000000) >> 48); - tmp[2] = (uint8_t)((val & 0x0000ff0000000000) >> 40); - tmp[3] = (uint8_t)((val & 0x000000ff00000000) >> 32); - tmp[4] = (uint8_t)((val & 0x00000000ff000000) >> 24); - tmp[5] = (uint8_t)((val & 0x0000000000ff0000) >> 16); - tmp[6] = (uint8_t)((val & 0x000000000000ff00) >> 8); - tmp[7] = (uint8_t)((val & 0x00000000000000ff) >> 0); - return ret; + uint64_t ret = 0; + uint8_t *tmp = (uint8_t *)&ret; + tmp[0] = (uint8_t)((val & 0xff00000000000000) >> 56); + tmp[1] = (uint8_t)((val & 0x00ff000000000000) >> 48); + tmp[2] = (uint8_t)((val & 0x0000ff0000000000) >> 40); + tmp[3] = (uint8_t)((val & 0x000000ff00000000) >> 32); + tmp[4] = (uint8_t)((val & 0x00000000ff000000) >> 24); + tmp[5] = (uint8_t)((val & 0x0000000000ff0000) >> 16); + tmp[6] = (uint8_t)((val & 0x000000000000ff00) >> 8); + tmp[7] = (uint8_t)((val & 0x00000000000000ff) >> 0); + return ret; } bool mvhd_is_conectix_str(const void *buffer) { - if (strncmp(buffer, MVHD_CONECTIX_COOKIE, strlen(MVHD_CONECTIX_COOKIE)) == 0) { - return true; - } else { - return false; - } + if (strncmp(buffer, MVHD_CONECTIX_COOKIE, strlen(MVHD_CONECTIX_COOKIE)) == 0) { + return true; + } else { + return false; + } } void mvhd_generate_uuid(uint8_t *uuid) { - /* We aren't doing crypto here, so using system time as seed should be good enough */ - srand((unsigned int)time(0)); - int n; - for (n = 0; n < 16; n++) { - uuid[n] = rand(); - } - uuid[6] &= 0x0F; - uuid[6] |= 0x40; /* Type 4 */ - uuid[8] &= 0x3F; - uuid[8] |= 0x80; /* Variant 1 */ + /* We aren't doing crypto here, so using system time as seed should be good enough */ + srand((unsigned int)time(0)); + int n; + for (n = 0; n < 16; n++) { + uuid[n] = rand(); + } + uuid[6] &= 0x0F; + uuid[6] |= 0x40; /* Type 4 */ + uuid[8] &= 0x3F; + uuid[8] |= 0x80; /* Variant 1 */ } uint32_t vhd_calc_timestamp(void) { - time_t start_time; - time_t curr_time; - double vhd_time; - start_time = MVHD_START_TS; /* 1 Jan 2000 00:00 */ - curr_time = time(NULL); - vhd_time = difftime(curr_time, start_time); - return (uint32_t)vhd_time; + time_t start_time; + time_t curr_time; + double vhd_time; + start_time = MVHD_START_TS; /* 1 Jan 2000 00:00 */ + curr_time = time(NULL); + vhd_time = difftime(curr_time, start_time); + return (uint32_t)vhd_time; } uint32_t mvhd_epoch_to_vhd_ts(time_t ts) { - time_t start_time = MVHD_START_TS; - if (ts < start_time) { - return start_time; - } - double vhd_time = difftime(ts, start_time); - return (uint32_t)vhd_time; + time_t start_time = MVHD_START_TS; + if (ts < start_time) { + return start_time; + } + double vhd_time = difftime(ts, start_time); + return (uint32_t)vhd_time; } time_t vhd_get_created_time(MVHDMeta *vhdm) { - time_t vhd_time = (time_t)vhdm->footer.timestamp; - time_t vhd_time_unix = MVHD_START_TS + vhd_time; - return vhd_time_unix; + time_t vhd_time = (time_t)vhdm->footer.timestamp; + time_t vhd_time_unix = MVHD_START_TS + vhd_time; + return vhd_time_unix; } FILE *mvhd_fopen(const char *path, const char *mode, int *err) { - FILE *f = NULL; + FILE *f = NULL; #ifdef _WIN32 - size_t path_len = strlen(path); - size_t mode_len = strlen(mode); - mvhd_utf16 new_path[260] = {0}; - int new_path_len = (sizeof new_path) - 2; - mvhd_utf16 mode_str[5] = {0}; - int new_mode_len = (sizeof mode_str) - 2; - int path_res = UTF8ToUTF16LE((unsigned char *)new_path, &new_path_len, (const unsigned char *)path, (int *)&path_len); - int mode_res = UTF8ToUTF16LE((unsigned char *)mode_str, &new_mode_len, (const unsigned char *)mode, (int *)&mode_len); - if (path_res > 0 && mode_res > 0) { - f = _wfopen(new_path, mode_str); - if (f == NULL) { - mvhd_errno = errno; - *err = MVHD_ERR_FILE; - } - } else { - if (path_res == -1 || mode_res == -1) { - *err = MVHD_ERR_UTF_SIZE; - } else if (path_res == -2 || mode_res == -2) { - *err = MVHD_ERR_UTF_TRANSCODING_FAILED; - } - } + size_t path_len = strlen(path); + size_t mode_len = strlen(mode); + mvhd_utf16 new_path[260] = {0}; + int new_path_len = (sizeof new_path) - 2; + mvhd_utf16 mode_str[5] = {0}; + int new_mode_len = (sizeof mode_str) - 2; + int path_res = UTF8ToUTF16LE((unsigned char *)new_path, &new_path_len, (const unsigned char *)path, (int *)&path_len); + int mode_res = UTF8ToUTF16LE((unsigned char *)mode_str, &new_mode_len, (const unsigned char *)mode, (int *)&mode_len); + if (path_res > 0 && mode_res > 0) { + f = _wfopen(new_path, mode_str); + if (f == NULL) { + mvhd_errno = errno; + *err = MVHD_ERR_FILE; + } + } else { + if (path_res == -1 || mode_res == -1) { + *err = MVHD_ERR_UTF_SIZE; + } else if (path_res == -2 || mode_res == -2) { + *err = MVHD_ERR_UTF_TRANSCODING_FAILED; + } + } #else - f = fopen(path, mode); - if (f == NULL) - { - mvhd_errno = errno; - *err = MVHD_ERR_FILE; - } + f = fopen(path, mode); + if (f == NULL) { + mvhd_errno = errno; + *err = MVHD_ERR_FILE; + } #endif - return f; + return f; } void mvhd_set_encoding_err(int encoding_retval, int *err) { - if (encoding_retval == -1) { - *err = MVHD_ERR_UTF_SIZE; - } else if (encoding_retval == -2) { - *err = MVHD_ERR_UTF_TRANSCODING_FAILED; - } + if (encoding_retval == -1) { + *err = MVHD_ERR_UTF_SIZE; + } else if (encoding_retval == -2) { + *err = MVHD_ERR_UTF_TRANSCODING_FAILED; + } } uint64_t mvhd_calc_size_bytes(MVHDGeom *geom) { - uint64_t img_size = (uint64_t)geom->cyl * (uint64_t)geom->heads * (uint64_t)geom->spt * (uint64_t)MVHD_SECTOR_SIZE; - return img_size; + uint64_t img_size = (uint64_t)geom->cyl * (uint64_t)geom->heads * (uint64_t)geom->spt * (uint64_t)MVHD_SECTOR_SIZE; + return img_size; } uint32_t mvhd_calc_size_sectors(MVHDGeom *geom) { - uint32_t sector_size = (uint32_t)geom->cyl * (uint32_t)geom->heads * (uint32_t)geom->spt; - return sector_size; + uint32_t sector_size = (uint32_t)geom->cyl * (uint32_t)geom->heads * (uint32_t)geom->spt; + return sector_size; } MVHDGeom mvhd_get_geometry(MVHDMeta *vhdm) { - MVHDGeom geometry = {.cyl = vhdm->footer.geom.cyl, .heads = vhdm->footer.geom.heads, .spt = vhdm->footer.geom.spt}; - return geometry; + MVHDGeom geometry = {.cyl = vhdm->footer.geom.cyl, .heads = vhdm->footer.geom.heads, .spt = vhdm->footer.geom.spt}; + return geometry; } -uint64_t mvhd_get_current_size(MVHDMeta *vhdm) { - return vhdm->footer.curr_sz; -} +uint64_t mvhd_get_current_size(MVHDMeta *vhdm) { return vhdm->footer.curr_sz; } uint32_t mvhd_gen_footer_checksum(MVHDFooter *footer) { - uint32_t new_chk = 0; - uint32_t orig_chk = footer->checksum; - footer->checksum = 0; - uint8_t *footer_bytes = (uint8_t *)footer; - size_t i; - for (i = 0; i < sizeof *footer; i++) { - new_chk += footer_bytes[i]; - } - footer->checksum = orig_chk; - return ~new_chk; + uint32_t new_chk = 0; + uint32_t orig_chk = footer->checksum; + footer->checksum = 0; + uint8_t *footer_bytes = (uint8_t *)footer; + size_t i; + for (i = 0; i < sizeof *footer; i++) { + new_chk += footer_bytes[i]; + } + footer->checksum = orig_chk; + return ~new_chk; } uint32_t mvhd_gen_sparse_checksum(MVHDSparseHeader *header) { - uint32_t new_chk = 0; - uint32_t orig_chk = header->checksum; - header->checksum = 0; - uint8_t *sparse_bytes = (uint8_t *)header; - size_t i; - for (i = 0; i < sizeof *header; i++) { - new_chk += sparse_bytes[i]; - } - header->checksum = orig_chk; - return ~new_chk; + uint32_t new_chk = 0; + uint32_t orig_chk = header->checksum; + header->checksum = 0; + uint8_t *sparse_bytes = (uint8_t *)header; + size_t i; + for (i = 0; i < sizeof *header; i++) { + new_chk += sparse_bytes[i]; + } + header->checksum = orig_chk; + return ~new_chk; } const char *mvhd_strerr(MVHDError err) { - switch (err) { - case MVHD_ERR_MEM:return "memory allocation error"; - case MVHD_ERR_FILE:return "file error"; - case MVHD_ERR_NOT_VHD:return "file is not a VHD image"; - case MVHD_ERR_TYPE:return "unsupported VHD image type"; - case MVHD_ERR_FOOTER_CHECKSUM:return "invalid VHD footer checksum"; - case MVHD_ERR_SPARSE_CHECKSUM:return "invalid VHD sparse header checksum"; - case MVHD_ERR_UTF_TRANSCODING_FAILED:return "error converting path encoding"; - case MVHD_ERR_UTF_SIZE:return "buffer size mismatch when converting path encoding"; - case MVHD_ERR_PATH_REL:return "relative path detected where absolute path expected"; - case MVHD_ERR_PATH_LEN:return "path length exceeds MVHD_MAX_PATH"; - case MVHD_ERR_PAR_NOT_FOUND:return "parent VHD image not found"; - case MVHD_ERR_INVALID_PAR_UUID:return "UUID mismatch between child and parent VHD"; - case MVHD_ERR_INVALID_GEOM:return "invalid geometry detected"; - case MVHD_ERR_INVALID_SIZE:return "invalid size"; - case MVHD_ERR_INVALID_BLOCK_SIZE:return "invalid block size"; - case MVHD_ERR_INVALID_PARAMS:return "invalid parameters passed to function"; - case MVHD_ERR_CONV_SIZE:return "error converting image. Size mismatch detechted"; - default:return "unknown error"; - } + switch (err) { + case MVHD_ERR_MEM: + return "memory allocation error"; + case MVHD_ERR_FILE: + return "file error"; + case MVHD_ERR_NOT_VHD: + return "file is not a VHD image"; + case MVHD_ERR_TYPE: + return "unsupported VHD image type"; + case MVHD_ERR_FOOTER_CHECKSUM: + return "invalid VHD footer checksum"; + case MVHD_ERR_SPARSE_CHECKSUM: + return "invalid VHD sparse header checksum"; + case MVHD_ERR_UTF_TRANSCODING_FAILED: + return "error converting path encoding"; + case MVHD_ERR_UTF_SIZE: + return "buffer size mismatch when converting path encoding"; + case MVHD_ERR_PATH_REL: + return "relative path detected where absolute path expected"; + case MVHD_ERR_PATH_LEN: + return "path length exceeds MVHD_MAX_PATH"; + case MVHD_ERR_PAR_NOT_FOUND: + return "parent VHD image not found"; + case MVHD_ERR_INVALID_PAR_UUID: + return "UUID mismatch between child and parent VHD"; + case MVHD_ERR_INVALID_GEOM: + return "invalid geometry detected"; + case MVHD_ERR_INVALID_SIZE: + return "invalid size"; + case MVHD_ERR_INVALID_BLOCK_SIZE: + return "invalid block size"; + case MVHD_ERR_INVALID_PARAMS: + return "invalid parameters passed to function"; + case MVHD_ERR_CONV_SIZE: + return "error converting image. Size mismatch detechted"; + default: + return "unknown error"; + } } int64_t mvhd_ftello64(FILE *stream) { #ifdef _MSC_VER - return _ftelli64(stream); + return _ftelli64(stream); #elif defined(__MINGW32__) - return ftello64(stream); + return ftello64(stream); #else /* This should work with linux (with _FILE_OFFSET_BITS), and hopefully OS X and BSD */ - return ftello(stream); + return ftello(stream); #endif } int mvhd_fseeko64(FILE *stream, int64_t offset, int origin) { #ifdef _MSC_VER - return _fseeki64(stream, offset, origin); + return _fseeki64(stream, offset, origin); #elif defined(__MINGW32__) - return fseeko64(stream, offset, origin); + return fseeko64(stream, offset, origin); #else /* This should work with linux (with _FILE_OFFSET_BITS), and hopefully OS X and BSD */ - return fseeko(stream, offset, origin); + return fseeko(stream, offset, origin); #endif } uint32_t mvhd_crc32_for_byte(uint32_t r) { - int j; - for (j = 0; j < 8; ++j) - r = (r & 1 ? 0 : (uint32_t)0xEDB88320L) ^ r >> 1; - return r ^ (uint32_t)0xFF000000L; + int j; + for (j = 0; j < 8; ++j) + r = (r & 1 ? 0 : (uint32_t)0xEDB88320L) ^ r >> 1; + return r ^ (uint32_t)0xFF000000L; } uint32_t mvhd_crc32(const void *data, size_t n_bytes) { - static uint32_t table[0x100]; - size_t i; - if (!*table) - for (i = 0; i < 0x100; ++i) - table[i] = mvhd_crc32_for_byte(i); + static uint32_t table[0x100]; + size_t i; + if (!*table) + for (i = 0; i < 0x100; ++i) + table[i] = mvhd_crc32_for_byte(i); - uint32_t crc = 0; - for (i = 0; i < n_bytes; ++i) - crc = table[(uint8_t)crc ^ ((uint8_t *)data)[i]] ^ crc >> 8; + uint32_t crc = 0; + for (i = 0; i < n_bytes; ++i) + crc = table[(uint8_t)crc ^ ((uint8_t *)data)[i]] ^ crc >> 8; - return crc; + return crc; } uint32_t mvhd_file_mod_timestamp(const char *path, int *err) { - *err = 0; + *err = 0; #ifdef _WIN32 - struct _stat file_stat; - size_t path_len = strlen(path); - mvhd_utf16 new_path[260] = {0}; - int new_path_len = (sizeof new_path) - 2; - int path_res = UTF8ToUTF16LE((unsigned char *)new_path, &new_path_len, (const unsigned char *)path, (int *)&path_len); - if (path_res > 0) { - int stat_res = _wstat(new_path, &file_stat); - if (stat_res != 0) { - mvhd_errno = errno; - *err = MVHD_ERR_FILE; - return 0; - } - return mvhd_epoch_to_vhd_ts(file_stat.st_mtime); - } else { - if (path_res == -1) { - *err = MVHD_ERR_UTF_SIZE; - } else if (path_res == -2) { - *err = MVHD_ERR_UTF_TRANSCODING_FAILED; - } - return 0; - } + struct _stat file_stat; + size_t path_len = strlen(path); + mvhd_utf16 new_path[260] = {0}; + int new_path_len = (sizeof new_path) - 2; + int path_res = UTF8ToUTF16LE((unsigned char *)new_path, &new_path_len, (const unsigned char *)path, (int *)&path_len); + if (path_res > 0) { + int stat_res = _wstat(new_path, &file_stat); + if (stat_res != 0) { + mvhd_errno = errno; + *err = MVHD_ERR_FILE; + return 0; + } + return mvhd_epoch_to_vhd_ts(file_stat.st_mtime); + } else { + if (path_res == -1) { + *err = MVHD_ERR_UTF_SIZE; + } else if (path_res == -2) { + *err = MVHD_ERR_UTF_TRANSCODING_FAILED; + } + return 0; + } #else - struct stat file_stat; - int stat_res = stat(path, &file_stat); - if (stat_res != 0) - { - mvhd_errno = errno; - *err = MVHD_ERR_FILE; - return 0; - } - return mvhd_epoch_to_vhd_ts(file_stat.st_mtime); + struct stat file_stat; + int stat_res = stat(path, &file_stat); + if (stat_res != 0) { + mvhd_errno = errno; + *err = MVHD_ERR_FILE; + return 0; + } + return mvhd_epoch_to_vhd_ts(file_stat.st_mtime); #endif } diff --git a/src/ide/ide.c b/src/ide/ide.c index fdc51362..56d9979e 100644 --- a/src/ide/ide.c +++ b/src/ide/ide.c @@ -22,64 +22,60 @@ #include "ide.h" /* ATA Commands */ -#define WIN_SRST 0x08 /* ATAPI Device Reset */ -#define WIN_RECAL 0x10 -#define WIN_RESTORE WIN_RECAL -#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 */ -#define WIN_VERIFY 0x40 /* 28-Bit Verify */ -#define WIN_VERIFY_ONCE 0x41 /* Deprecated command - same as 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_WRITE_DMA 0xCA -#define WIN_SETIDLE1 0xE3 -#define WIN_CHECK_POWER_MODE 0xE5 -#define WIN_IDENTIFY 0xEC /* Ask drive to identify itself */ -#define WIN_SET_FEATURES 0xEF +#define WIN_SRST 0x08 /* ATAPI Device Reset */ +#define WIN_RECAL 0x10 +#define WIN_RESTORE WIN_RECAL +#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 */ +#define WIN_VERIFY 0x40 /* 28-Bit Verify */ +#define WIN_VERIFY_ONCE 0x41 /* Deprecated command - same as 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_WRITE_DMA 0xCA +#define WIN_SETIDLE1 0xE3 +#define WIN_CHECK_POWER_MODE 0xE5 +#define WIN_IDENTIFY 0xEC /* Ask drive to identify itself */ +#define WIN_SET_FEATURES 0xEF /** Evaluate to non-zero if the currently selected drive is an ATAPI device */ -#define IDE_DRIVE_IS_CDROM(ide) (ide->type == IDE_CDROM) +#define IDE_DRIVE_IS_CDROM(ide) (ide->type == IDE_CDROM) -enum { - IDE_NONE = 0, - IDE_HDD, - IDE_CDROM -}; +enum { IDE_NONE = 0, IDE_HDD, IDE_CDROM }; struct IDE; typedef struct IDE { - int type; - int board; - uint8_t atastat; - uint8_t error; - int secount, sector, cylinder, head, drive, cylprecomp; - uint8_t command; - uint8_t fdisk; - int pos; - int reset; - uint16_t buffer[65536]; - int irqstat; - int service; - int lba; - uint32_t lba_addr; - int skip512; - int blocksize, blockcount; - uint8_t sector_buffer[256 * 512]; - int do_initial_read; - int sector_pos; - hdd_file_t hdd_file; - atapi_device_t atapi; + int type; + int board; + uint8_t atastat; + uint8_t error; + int secount, sector, cylinder, head, drive, cylprecomp; + uint8_t command; + uint8_t fdisk; + int pos; + int reset; + uint16_t buffer[65536]; + int irqstat; + int service; + int lba; + uint32_t lba_addr; + int skip512; + int blocksize, blockcount; + uint8_t sector_buffer[256 * 512]; + int do_initial_read; + int sector_pos; + hdd_file_t hdd_file; + atapi_device_t atapi; } IDE; int cdrom_channel = 2; @@ -100,35 +96,33 @@ pc_timer_t ide_timer[2]; int cur_ide[2]; -uint8_t getstat(IDE *ide) { - return ide->atastat; -} +uint8_t getstat(IDE *ide) { return ide->atastat; } void ide_irq_raise(IDE *ide) { -// pclog("IDE_IRQ_RAISE\n"); - if (!(ide->fdisk & 2)) { -// if (ide->board && !ide->irqstat) pclog("IDE_IRQ_RAISE\n"); - picint((ide->board) ? (1 << 15) : (1 << 14)); - if (ide_bus_master_set_irq) - ide_bus_master_set_irq(ide->board, ide_bus_master_p); - } - ide->irqstat = 1; - ide->service = 1; + // pclog("IDE_IRQ_RAISE\n"); + if (!(ide->fdisk & 2)) { + // if (ide->board && !ide->irqstat) pclog("IDE_IRQ_RAISE\n"); + picint((ide->board) ? (1 << 15) : (1 << 14)); + if (ide_bus_master_set_irq) + ide_bus_master_set_irq(ide->board, ide_bus_master_p); + } + ide->irqstat = 1; + ide->service = 1; } static inline void ide_irq_lower(IDE *ide) { -// pclog("IDE_IRQ_LOWER\n"); -// if (ide.board == 0) { - picintc((ide->board) ? (1 << 15) : (1 << 14)); -// } - ide->irqstat = 0; + // pclog("IDE_IRQ_LOWER\n"); + // if (ide.board == 0) { + picintc((ide->board) ? (1 << 15) : (1 << 14)); + // } + ide->irqstat = 0; } void ide_irq_update(IDE *ide) { - if (ide->irqstat && !((pic2.pend | pic2.ins) & 0x40) && !(ide->fdisk & 2)) - picint((ide->board) ? (1 << 15) : (1 << 14)); - else if ((pic2.pend | pic2.ins) & 0x40) - picintc((ide->board) ? (1 << 15) : (1 << 14)); + if (ide->irqstat && !((pic2.pend | pic2.ins) & 0x40) && !(ide->fdisk & 2)) + picint((ide->board) ? (1 << 15) : (1 << 14)); + else if ((pic2.pend | pic2.ins) & 0x40) + picintc((ide->board) ? (1 << 15) : (1 << 14)); } /** * Copy a string into a buffer, padding with spaces, and placing characters as @@ -140,1076 +134,1061 @@ void ide_irq_update(IDE *ide) { * this length will be padded with spaces. */ void ide_padstr(char *str, const char *src, int len) { - int i, v; + int i, v; - for (i = 0; i < len; i++) { - if (*src != '\0') { - v = *src++; - } else { - v = ' '; - } - str[i ^ 1] = v; - } + for (i = 0; i < len; i++) { + if (*src != '\0') { + v = *src++; + } else { + v = ' '; + } + str[i ^ 1] = v; + } } /** * Fill in ide->buffer with the output of the "IDENTIFY DEVICE" command */ static void ide_identify(IDE *ide) { - memset(ide->buffer, 0, 512); + memset(ide->buffer, 0, 512); - //ide->buffer[1] = 101; /* Cylinders */ + // ide->buffer[1] = 101; /* Cylinders */ - if ((hdc[cur_ide[ide->board]].tracks * hdc[cur_ide[ide->board]].hpc * hdc[cur_ide[ide->board]].spt) >= 16514064) - ide->buffer[1] = 16383; - else - ide->buffer[1] = hdc[cur_ide[ide->board]].tracks; /* Cylinders */ - ide->buffer[3] = hdc[cur_ide[ide->board]].hpc; /* Heads */ - ide->buffer[6] = hdc[cur_ide[ide->board]].spt; /* Sectors */ + if ((hdc[cur_ide[ide->board]].tracks * hdc[cur_ide[ide->board]].hpc * hdc[cur_ide[ide->board]].spt) >= 16514064) + ide->buffer[1] = 16383; + else + ide->buffer[1] = hdc[cur_ide[ide->board]].tracks; /* Cylinders */ + ide->buffer[3] = hdc[cur_ide[ide->board]].hpc; /* Heads */ + ide->buffer[6] = hdc[cur_ide[ide->board]].spt; /* Sectors */ - ide_padstr((char *)(ide->buffer + 10), "", 20); /* Serial Number */ - ide_padstr((char *)(ide->buffer + 23), "v1.0", 8); /* Firmware */ - ide_padstr((char *)(ide->buffer + 27), "PCemHD", 40); /* Model */ + ide_padstr((char *)(ide->buffer + 10), "", 20); /* Serial Number */ + ide_padstr((char *)(ide->buffer + 23), "v1.0", 8); /* Firmware */ + ide_padstr((char *)(ide->buffer + 27), "PCemHD", 40); /* Model */ - ide->buffer[0] = (1 << 6); /*Fixed drive*/ - ide->buffer[20] = 3; /*Buffer type*/ - ide->buffer[21] = 512; /*Buffer size*/ - ide->buffer[47] = 16; /*Max sectors on multiple transfer command*/ - ide->buffer[48] = 1; /*Dword transfers supported*/ - ide->buffer[49] = (1 << 9) | (1 << 8); /* LBA and DMA supported */ - ide->buffer[50] = 0x4000; /* Capabilities */ - ide->buffer[51] = 2 << 8; /*PIO timing mode*/ - ide->buffer[52] = 2 << 8; /*DMA timing mode*/ - ide->buffer[59] = ide->blocksize ? (ide->blocksize | 0x100) : 0; - ide->buffer[60] = (hdc[cur_ide[ide->board]].tracks * hdc[cur_ide[ide->board]].hpc * hdc[cur_ide[ide->board]].spt) & 0xFFFF; /* Total addressable sectors (LBA) */ - ide->buffer[61] = (hdc[cur_ide[ide->board]].tracks * hdc[cur_ide[ide->board]].hpc * hdc[cur_ide[ide->board]].spt) >> 16; - ide->buffer[63] = 7; /*Multiword DMA*/ - ide->buffer[80] = 0xe; /*ATA-1 to ATA-3 supported*/ + ide->buffer[0] = (1 << 6); /*Fixed drive*/ + ide->buffer[20] = 3; /*Buffer type*/ + ide->buffer[21] = 512; /*Buffer size*/ + ide->buffer[47] = 16; /*Max sectors on multiple transfer command*/ + ide->buffer[48] = 1; /*Dword transfers supported*/ + ide->buffer[49] = (1 << 9) | (1 << 8); /* LBA and DMA supported */ + ide->buffer[50] = 0x4000; /* Capabilities */ + ide->buffer[51] = 2 << 8; /*PIO timing mode*/ + ide->buffer[52] = 2 << 8; /*DMA timing mode*/ + ide->buffer[59] = ide->blocksize ? (ide->blocksize | 0x100) : 0; + ide->buffer[60] = (hdc[cur_ide[ide->board]].tracks * hdc[cur_ide[ide->board]].hpc * hdc[cur_ide[ide->board]].spt) & + 0xFFFF; /* Total addressable sectors (LBA) */ + ide->buffer[61] = (hdc[cur_ide[ide->board]].tracks * hdc[cur_ide[ide->board]].hpc * hdc[cur_ide[ide->board]].spt) >> 16; + ide->buffer[63] = 7; /*Multiword DMA*/ + ide->buffer[80] = 0xe; /*ATA-1 to ATA-3 supported*/ } /* * Return the sector offset for the current register values */ static off64_t ide_get_sector(IDE *ide) { - if (ide->lba) { - return (off64_t)ide->lba_addr + ide->skip512; - } else { - int heads = ide->hdd_file.hpc; - int sectors = ide->hdd_file.spt; + if (ide->lba) { + return (off64_t)ide->lba_addr + ide->skip512; + } else { + int heads = ide->hdd_file.hpc; + int sectors = ide->hdd_file.spt; - return ((((off64_t)ide->cylinder * heads) + ide->head) * - sectors) + (ide->sector - 1) + ide->skip512; - } + 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 *ide) { - if (ide->lba) { - ide->lba_addr++; - } else { - ide->sector++; + if (ide->lba) { + ide->lba_addr++; + } else { + ide->sector++; - if (ide->sector == (ide->hdd_file.spt + 1)) { - ide->sector = 1; - ide->head++; + if (ide->sector == (ide->hdd_file.spt + 1)) { + ide->sector = 1; + ide->head++; - if (ide->head == ide->hdd_file.hpc) { - ide->head = 0; - ide->cylinder++; - } - } - } + if (ide->head == ide->hdd_file.hpc) { + ide->head = 0; + ide->cylinder++; + } + } + } } static void loadhd(IDE *ide, int d, const char *fn) { - hdd_load(&ide->hdd_file, d, fn); + hdd_load(&ide->hdd_file, d, fn); - if (ide->hdd_file.f) - ide->type = IDE_HDD; - else - ide->type = IDE_NONE; + if (ide->hdd_file.f) + ide->type = IDE_HDD; + else + ide->type = IDE_NONE; } void ide_set_signature(IDE *ide) { - ide->secount = 1; - ide->sector = 1; - ide->head = 0; - ide->cylinder = (IDE_DRIVE_IS_CDROM(ide) ? 0xEB14 : ((ide->type == IDE_HDD) ? 0 : 0xFFFF)); -// if (ide->type == IDE_HDD) ide->drive = 0; + ide->secount = 1; + ide->sector = 1; + ide->head = 0; + ide->cylinder = (IDE_DRIVE_IS_CDROM(ide) ? 0xEB14 : ((ide->type == IDE_HDD) ? 0 : 0xFFFF)); + // if (ide->type == IDE_HDD) ide->drive = 0; } void resetide(void) { - int d; + int d; - /* Close hard disk image files (if previously open) */ - for (d = 0; d < 4; d++) { - ide_drives[d].type = IDE_NONE; - hdd_close(&ide_drives[d].hdd_file); + /* Close hard disk image files (if previously open) */ + for (d = 0; d < 4; d++) { + ide_drives[d].type = IDE_NONE; + hdd_close(&ide_drives[d].hdd_file); - ide_drives[d].atastat = READY_STAT | DSC_STAT; - ide_drives[d].service = 0; - ide_drives[d].board = (d & 2) ? 1 : 0; - } + ide_drives[d].atastat = READY_STAT | DSC_STAT; + ide_drives[d].service = 0; + ide_drives[d].board = (d & 2) ? 1 : 0; + } - if (hdd_controller_current_is_ide()) { - for (d = 0; d < 4; d++) { - ide_drives[d].drive = d; + if (hdd_controller_current_is_ide()) { + for (d = 0; d < 4; d++) { + ide_drives[d].drive = d; - if (cdrom_channel == d) { - ide_drives[d].type = IDE_CDROM; - scsi_bus_atapi_init(&ide_drives[d].atapi.bus, &scsi_cd, d, &ide_drives[d].atapi); - } else if (zip_channel == d) { - ide_drives[d].type = IDE_CDROM; - scsi_bus_atapi_init(&ide_drives[d].atapi.bus, &scsi_zip, d, &ide_drives[d].atapi); - } else { - loadhd(&ide_drives[d], d, ide_fn[d]); - } + if (cdrom_channel == d) { + ide_drives[d].type = IDE_CDROM; + scsi_bus_atapi_init(&ide_drives[d].atapi.bus, &scsi_cd, d, &ide_drives[d].atapi); + } else if (zip_channel == d) { + ide_drives[d].type = IDE_CDROM; + scsi_bus_atapi_init(&ide_drives[d].atapi.bus, &scsi_zip, d, &ide_drives[d].atapi); + } else { + loadhd(&ide_drives[d], d, ide_fn[d]); + } - ide_set_signature(&ide_drives[d]); + ide_set_signature(&ide_drives[d]); - ide_drives[d].atapi.ide = &ide_drives[d]; - ide_drives[d].atapi.board = (d & 2) ? 1 : 0; - ide_drives[d].atapi.atastat = &ide_drives[d].atastat; - ide_drives[d].atapi.error = &ide_drives[d].error; - ide_drives[d].atapi.cylinder = &ide_drives[d].cylinder; - } - } + ide_drives[d].atapi.ide = &ide_drives[d]; + ide_drives[d].atapi.board = (d & 2) ? 1 : 0; + ide_drives[d].atapi.atastat = &ide_drives[d].atastat; + ide_drives[d].atapi.error = &ide_drives[d].error; + ide_drives[d].atapi.cylinder = &ide_drives[d].cylinder; + } + } - cur_ide[0] = 0; - cur_ide[1] = 2; + cur_ide[0] = 0; + cur_ide[1] = 2; } int idetimes = 0; void writeidew(int ide_board, uint16_t val) { - IDE *ide = &ide_drives[cur_ide[ide_board]]; + IDE *ide = &ide_drives[cur_ide[ide_board]]; - if (ide->command == WIN_PACKETCMD) { - atapi_data_write(&ide->atapi, val); - } else { - ide->buffer[ide->pos >> 1] = val; - ide->pos += 2; + if (ide->command == WIN_PACKETCMD) { + atapi_data_write(&ide->atapi, val); + } else { + ide->buffer[ide->pos >> 1] = val; + ide->pos += 2; - if (ide->pos >= 512) { - ide->pos = 0; - ide->atastat = BUSY_STAT; - if (ide->command == WIN_WRITE_MULTIPLE) - callbackide(ide_board); - else - timer_set_delay_u64(&ide_timer[ide_board], 6 * IDE_TIME); - } - } + if (ide->pos >= 512) { + ide->pos = 0; + ide->atastat = BUSY_STAT; + if (ide->command == WIN_WRITE_MULTIPLE) + callbackide(ide_board); + else + timer_set_delay_u64(&ide_timer[ide_board], 6 * IDE_TIME); + } + } } void writeidel(int ide_board, uint32_t val) { -// pclog("WriteIDEl %08X\n", val); - writeidew(ide_board, val); - writeidew(ide_board, val >> 16); + // pclog("WriteIDEl %08X\n", val); + writeidew(ide_board, val); + writeidew(ide_board, val >> 16); } void writeide(int ide_board, uint16_t addr, uint8_t val) { - IDE *ide = &ide_drives[cur_ide[ide_board]]; - IDE *ide_other = &ide_drives[cur_ide[ide_board] ^ 1]; + IDE *ide = &ide_drives[cur_ide[ide_board]]; + IDE *ide_other = &ide_drives[cur_ide[ide_board] ^ 1]; -/* if (ide_board && (cr0&1) && !(eflags&VM_FLAG)) - { -// pclog("Failed write IDE %04X:%08X\n",CS,pc); + /* if (ide_board && (cr0&1) && !(eflags&VM_FLAG)) + { + // pclog("Failed write IDE %04X:%08X\n",CS,pc); + return; + }*/ + // if ((cr0&1) && !(eflags&VM_FLAG)) + // if (ide_board) + // pclog("WriteIDE %04X %02X from %04X(%08X):%08X %i\n", addr, val, CS, cs, cpu_state.pc, ins); + // return; + addr |= 0x80; + // if (ide_board) pclog("Write IDEb %04X %02X %04X(%08X):%04X %i %02X + // %02X\n",addr,val,CS,cs,pc,ins,ide->atastat,ide_drives[0].atastat); + /*if (idedebug) */ + // pclog("Write IDE %08X %02X %04X:%08X\n",addr,val,CS,pc); + // int c; + // rpclog("Write IDE %08X %02X %08X %08X\n",addr,val,PC,armregs[12]); + + if (ide->type == IDE_NONE && (addr == 0x1f0 || addr == 0x1f7)) return; - }*/ -// if ((cr0&1) && !(eflags&VM_FLAG)) -// if (ide_board) -// pclog("WriteIDE %04X %02X from %04X(%08X):%08X %i\n", addr, val, CS, cs, cpu_state.pc, ins); -// return; - addr |= 0x80; -// if (ide_board) pclog("Write IDEb %04X %02X %04X(%08X):%04X %i %02X %02X\n",addr,val,CS,cs,pc,ins,ide->atastat,ide_drives[0].atastat); - /*if (idedebug) */ -// pclog("Write IDE %08X %02X %04X:%08X\n",addr,val,CS,pc); -// int c; -// rpclog("Write IDE %08X %02X %08X %08X\n",addr,val,PC,armregs[12]); - if (ide->type == IDE_NONE && (addr == 0x1f0 || addr == 0x1f7)) - return; + switch (addr) { + case 0x1F0: /* Data */ + writeidew(ide_board, val | (val << 8)); + return; - switch (addr) { - case 0x1F0: /* Data */ - writeidew(ide_board, val | (val << 8)); - return; + case 0x1F1: /* Features */ + ide->cylprecomp = val; + ide_other->cylprecomp = val; + return; - case 0x1F1: /* Features */ - ide->cylprecomp = val; - ide_other->cylprecomp = val; - return; + case 0x1F2: /* Sector count */ + ide->secount = val; + ide_other->secount = val; + return; - case 0x1F2: /* Sector count */ - ide->secount = val; - ide_other->secount = val; - return; + case 0x1F3: /* 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 0x1F3: /* 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 0x1F4: /* Cylinder low */ + ide->cylinder = (ide->cylinder & 0xFF00) | val; + ide->lba_addr = (ide->lba_addr & 0xFFF00FF) | (val << 8); + ide_other->cylinder = (ide_other->cylinder & 0xFF00) | val; + ide_other->lba_addr = (ide_other->lba_addr & 0xFFF00FF) | (val << 8); + // pclog("Write cylinder low %02X\n",val); + return; - case 0x1F4: /* Cylinder low */ - ide->cylinder = (ide->cylinder & 0xFF00) | val; - ide->lba_addr = (ide->lba_addr & 0xFFF00FF) | (val << 8); - ide_other->cylinder = (ide_other->cylinder & 0xFF00) | val; - ide_other->lba_addr = (ide_other->lba_addr & 0xFFF00FF) | (val << 8); -// pclog("Write cylinder low %02X\n",val); - return; + case 0x1F5: /* Cylinder high */ + ide->cylinder = (ide->cylinder & 0xFF) | (val << 8); + ide->lba_addr = (ide->lba_addr & 0xF00FFFF) | (val << 16); + ide_other->cylinder = (ide_other->cylinder & 0xFF) | (val << 8); + ide_other->lba_addr = (ide_other->lba_addr & 0xF00FFFF) | (val << 16); + return; - case 0x1F5: /* Cylinder high */ - ide->cylinder = (ide->cylinder & 0xFF) | (val << 8); - ide->lba_addr = (ide->lba_addr & 0xF00FFFF) | (val << 16); - ide_other->cylinder = (ide_other->cylinder & 0xFF) | (val << 8); - ide_other->lba_addr = (ide_other->lba_addr & 0xF00FFFF) | (val << 16); - return; + case 0x1F6: /* Drive/Head */ + /* if (val==0xB0) + { + dumpregs(); + exit(-1); + }*/ - case 0x1F6: /* Drive/Head */ -/* if (val==0xB0) - { - dumpregs(); - exit(-1); - }*/ + if (cur_ide[ide_board] != ((val >> 4) & 1) + (ide_board << 1)) { + cur_ide[ide_board] = ((val >> 4) & 1) + (ide_board << 1); - if (cur_ide[ide_board] != ((val >> 4) & 1) + (ide_board << 1)) { - cur_ide[ide_board] = ((val >> 4) & 1) + (ide_board << 1); + if (ide->reset || ide_other->reset) { + ide->atastat = ide_other->atastat = READY_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; + // ide->blocksize = ide_other->blocksize = 0; + if (IDE_DRIVE_IS_CDROM(ide)) + ide->cylinder = 0xEB14; + if (IDE_DRIVE_IS_CDROM(ide_other)) + ide_other->cylinder = 0xEB14; - if (ide->reset || ide_other->reset) { - ide->atastat = ide_other->atastat = READY_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; - // ide->blocksize = ide_other->blocksize = 0; - if (IDE_DRIVE_IS_CDROM(ide)) - ide->cylinder = 0xEB14; - if (IDE_DRIVE_IS_CDROM(ide_other)) - ide_other->cylinder = 0xEB14; + timer_disable(&ide_timer[ide_board]); + return; + } - timer_disable(&ide_timer[ide_board]); - return; - } + ide = &ide_drives[cur_ide[ide_board]]; + } - ide = &ide_drives[cur_ide[ide_board]]; - } + ide->head = val & 0xF; + ide->lba = val & 0x40; + ide_other->head = val & 0xF; + ide_other->lba = val & 0x40; - 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); - ide->lba_addr = (ide->lba_addr & 0x0FFFFFF) | ((val & 0xF) << 24); - ide_other->lba_addr = (ide_other->lba_addr & 0x0FFFFFF) | ((val & 0xF) << 24); + ide_irq_update(ide); + return; - ide_irq_update(ide); - return; + case 0x1F7: /* Command register */ + if (ide->type == IDE_NONE) + return; + // pclog("IDE command %02X drive %i\n",val,ide.drive); + ide_irq_lower(ide); + ide->command = val; - case 0x1F7: /* Command register */ - if (ide->type == IDE_NONE) - return; -// pclog("IDE command %02X drive %i\n",val,ide.drive); - ide_irq_lower(ide); - ide->command = val; + // pclog("New IDE command - %02X %i %i\n",ide->command,cur_ide[ide_board],ide_board); + ide->error = 0; + switch (val) { + case WIN_SRST: /* ATAPI Device Reset */ + if (IDE_DRIVE_IS_CDROM(ide)) + ide->atastat = BUSY_STAT; + else + ide->atastat = READY_STAT; + timer_set_delay_u64(&ide_timer[ide_board], 100 * IDE_TIME); + return; -// pclog("New IDE command - %02X %i %i\n",ide->command,cur_ide[ide_board],ide_board); - ide->error = 0; - switch (val) { - case WIN_SRST: /* ATAPI Device Reset */ - if (IDE_DRIVE_IS_CDROM(ide)) - ide->atastat = BUSY_STAT; - else - ide->atastat = READY_STAT; - timer_set_delay_u64(&ide_timer[ide_board], 100 * IDE_TIME); - return; + case WIN_RESTORE: + case WIN_SEEK: + // pclog("WIN_RESTORE start\n"); + ide->atastat = READY_STAT | BUSY_STAT; + timer_set_delay_u64(&ide_timer[ide_board], 100 * IDE_TIME); + return; - case WIN_RESTORE: - case WIN_SEEK: -// pclog("WIN_RESTORE start\n"); - ide->atastat = READY_STAT | BUSY_STAT; - timer_set_delay_u64(&ide_timer[ide_board], 100 * IDE_TIME); - return; - - case WIN_READ_MULTIPLE: - if (!ide->blocksize && (ide->type != IDE_CDROM)) - fatal("READ_MULTIPLE - blocksize = 0\n"); + case WIN_READ_MULTIPLE: + if (!ide->blocksize && (ide->type != IDE_CDROM)) + fatal("READ_MULTIPLE - blocksize = 0\n"); #if 0 if (ide->lba) pclog("Read Multiple %i sectors from LBA addr %07X\n",ide->secount,ide->lba_addr); else pclog("Read Multiple %i sectors from sector %i cylinder %i head %i %i\n",ide->secount,ide->sector,ide->cylinder,ide->head,ins); #endif - ide->blockcount = 0; + ide->blockcount = 0; - case WIN_READ: - case WIN_READ_NORETRY: - case WIN_READ_DMA: + case WIN_READ: + case WIN_READ_NORETRY: + case WIN_READ_DMA: /* if (ide.secount>1) { - fatal("Read %i sectors from sector %i cylinder %i head %i\n",ide.secount,ide.sector,ide.cylinder,ide.head); + fatal("Read %i sectors from sector %i cylinder %i head + %i\n",ide.secount,ide.sector,ide.cylinder,ide.head); }*/ #if 0 if (ide->lba) pclog("Read %i sectors from LBA addr %07X\n",ide->secount,ide->lba_addr); else pclog("Read %i sectors from sector %i cylinder %i head %i %i\n",ide->secount,ide->sector,ide->cylinder,ide->head,ins); #endif - ide->atastat = BUSY_STAT; - timer_set_delay_u64(&ide_timer[ide_board], 200 * IDE_TIME); - ide->do_initial_read = 1; - return; + ide->atastat = BUSY_STAT; + timer_set_delay_u64(&ide_timer[ide_board], 200 * IDE_TIME); + ide->do_initial_read = 1; + return; - case WIN_WRITE_MULTIPLE: - if (!ide->blocksize && (ide->type != IDE_CDROM)) - fatal("Write_MULTIPLE - blocksize = 0\n"); + case WIN_WRITE_MULTIPLE: + if (!ide->blocksize && (ide->type != IDE_CDROM)) + fatal("Write_MULTIPLE - blocksize = 0\n"); #if 0 if (ide->lba) pclog("Write Multiple %i sectors from LBA addr %07X\n",ide->secount,ide->lba_addr); else pclog("Write Multiple %i sectors to sector %i cylinder %i head %i\n",ide->secount,ide->sector,ide->cylinder,ide->head); #endif - ide->blockcount = 0; + ide->blockcount = 0; - case WIN_WRITE: - case WIN_WRITE_NORETRY: - /* if (ide.secount>1) - { - fatal("Write %i sectors to sector %i cylinder %i head %i\n",ide.secount,ide.sector,ide.cylinder,ide.head); - }*/ + case WIN_WRITE: + case WIN_WRITE_NORETRY: + /* if (ide.secount>1) + { + fatal("Write %i sectors to sector %i cylinder %i head + %i\n",ide.secount,ide.sector,ide.cylinder,ide.head); + }*/ #if 0 if (ide->lba) pclog("Write %i sectors from LBA addr %07X\n",ide->secount,ide->lba_addr); else pclog("Write %i sectors to sector %i cylinder %i head %i\n",ide->secount,ide->sector,ide->cylinder,ide->head); #endif - ide->atastat = DRQ_STAT | DSC_STAT | READY_STAT; - ide->pos = 0; - return; + ide->atastat = DRQ_STAT | DSC_STAT | READY_STAT; + ide->pos = 0; + return; - case WIN_WRITE_DMA: + case WIN_WRITE_DMA: #if 0 if (ide->lba) pclog("Write %i sectors from LBA addr %07X\n",ide->secount,ide->lba_addr); else pclog("Write %i sectors to sector %i cylinder %i head %i\n",ide->secount,ide->sector,ide->cylinder,ide->head); #endif - ide->atastat = BUSY_STAT; - timer_set_delay_u64(&ide_timer[ide_board], 200 * IDE_TIME); - return; + ide->atastat = BUSY_STAT; + timer_set_delay_u64(&ide_timer[ide_board], 200 * IDE_TIME); + return; - case WIN_VERIFY: - case WIN_VERIFY_ONCE: + case WIN_VERIFY: + case WIN_VERIFY_ONCE: #if 0 if (ide->lba) pclog("Read verify %i sectors from LBA addr %07X\n",ide->secount,ide->lba_addr); else pclog("Read verify %i sectors from sector %i cylinder %i head %i\n",ide->secount,ide->sector,ide->cylinder,ide->head); #endif - ide->atastat = BUSY_STAT; - timer_set_delay_u64(&ide_timer[ide_board], 200 * IDE_TIME); - return; + ide->atastat = BUSY_STAT; + timer_set_delay_u64(&ide_timer[ide_board], 200 * IDE_TIME); + return; - case WIN_FORMAT: -// pclog("Format track %i head %i\n",ide.cylinder,ide.head); - ide->atastat = DRQ_STAT; -// idecallback[ide_board]=200; - ide->pos = 0; - return; + case WIN_FORMAT: + // pclog("Format track %i head %i\n",ide.cylinder,ide.head); + ide->atastat = DRQ_STAT; + // idecallback[ide_board]=200; + ide->pos = 0; + return; - case WIN_SPECIFY: /* Initialize Drive Parameters */ - ide->atastat = BUSY_STAT; - timer_set_delay_u64(&ide_timer[ide_board], 30 * IDE_TIME); -// pclog("SPECIFY\n"); -// output=1; - return; + case WIN_SPECIFY: /* Initialize Drive Parameters */ + ide->atastat = BUSY_STAT; + timer_set_delay_u64(&ide_timer[ide_board], 30 * IDE_TIME); + // pclog("SPECIFY\n"); + // output=1; + return; - case WIN_DRIVE_DIAGNOSTICS: /* Execute Drive Diagnostics */ - ide->atastat = BUSY_STAT; - timer_set_delay_u64(&ide_timer[ide_board], 200 * IDE_TIME); - return; + case WIN_DRIVE_DIAGNOSTICS: /* Execute Drive Diagnostics */ + ide->atastat = BUSY_STAT; + timer_set_delay_u64(&ide_timer[ide_board], 200 * IDE_TIME); + return; - case WIN_PIDENTIFY: /* Identify Packet Device */ - case WIN_SET_MULTIPLE_MODE: /*Set Multiple Mode*/ -// output=1; - case WIN_SETIDLE1: /* Idle */ - case WIN_CHECK_POWER_MODE:ide->atastat = BUSY_STAT; - callbackide(ide_board); -// idecallback[ide_board]=200*IDE_TIME; - return; + case WIN_PIDENTIFY: /* Identify Packet Device */ + case WIN_SET_MULTIPLE_MODE: /*Set Multiple Mode*/ + // output=1; + case WIN_SETIDLE1: /* Idle */ + case WIN_CHECK_POWER_MODE: + ide->atastat = BUSY_STAT; + callbackide(ide_board); + // idecallback[ide_board]=200*IDE_TIME; + return; - case WIN_IDENTIFY: /* Identify Device */ - case WIN_SET_FEATURES: -// output=3; -// timetolive=500; - ide->atastat = BUSY_STAT; - timer_set_delay_u64(&ide_timer[ide_board], 200 * IDE_TIME); - return; + case WIN_IDENTIFY: /* Identify Device */ + case WIN_SET_FEATURES: + // output=3; + // timetolive=500; + ide->atastat = BUSY_STAT; + timer_set_delay_u64(&ide_timer[ide_board], 200 * IDE_TIME); + return; - case WIN_PACKETCMD: /* ATAPI Packet */ - if (ide->type == IDE_CDROM) - atapi_command_start(&ide->atapi, ide->cylprecomp); + case WIN_PACKETCMD: /* ATAPI Packet */ + if (ide->type == IDE_CDROM) + atapi_command_start(&ide->atapi, ide->cylprecomp); - ide->atastat = BUSY_STAT; - timer_set_delay_u64(&ide_timer[ide_board], IDE_TIME); + ide->atastat = BUSY_STAT; + timer_set_delay_u64(&ide_timer[ide_board], IDE_TIME); - ide->atapi.bus_state = 0; - return; + ide->atapi.bus_state = 0; + return; - case 0xF0: - default:ide->atastat = READY_STAT | ERR_STAT | DSC_STAT; - ide->error = ABRT_ERR; - ide_irq_raise(ide); -/* fatal("Bad IDE command %02X\n", val);*/ - return; - } + case 0xF0: + default: + ide->atastat = READY_STAT | ERR_STAT | DSC_STAT; + ide->error = ABRT_ERR; + ide_irq_raise(ide); + /* fatal("Bad IDE command %02X\n", val);*/ + return; + } - return; + return; - case 0x3F6: /* Device control */ - if ((ide->fdisk & 4) && !(val & 4) && (ide->type != IDE_NONE || ide_other->type != IDE_NONE)) { - timer_set_delay_u64(&ide_timer[ide_board], 500 * IDE_TIME); - ide->reset = ide_other->reset = 1; - ide->atastat = ide_other->atastat = BUSY_STAT; -// pclog("IDE Reset %i\n", ide_board); - } - if (val & 4) { - /*Drive held in reset*/ - timer_disable(&ide_timer[ide_board]); - ide->atastat = ide_other->atastat = BUSY_STAT; - } - ide->fdisk = ide_other->fdisk = val; - ide_irq_update(ide); - return; - } -// fatal("Bad IDE write %04X %02X\n", addr, val); + case 0x3F6: /* Device control */ + if ((ide->fdisk & 4) && !(val & 4) && (ide->type != IDE_NONE || ide_other->type != IDE_NONE)) { + timer_set_delay_u64(&ide_timer[ide_board], 500 * IDE_TIME); + ide->reset = ide_other->reset = 1; + ide->atastat = ide_other->atastat = BUSY_STAT; + // pclog("IDE Reset %i\n", ide_board); + } + if (val & 4) { + /*Drive held in reset*/ + timer_disable(&ide_timer[ide_board]); + ide->atastat = ide_other->atastat = BUSY_STAT; + } + ide->fdisk = ide_other->fdisk = val; + ide_irq_update(ide); + return; + } + // fatal("Bad IDE write %04X %02X\n", addr, val); } uint8_t readide(int ide_board, uint16_t addr) { - IDE *ide = &ide_drives[cur_ide[ide_board]]; - uint8_t temp = 0xff; - uint16_t tempw; + IDE *ide = &ide_drives[cur_ide[ide_board]]; + uint8_t temp = 0xff; + uint16_t tempw; - addr |= 0x80; + addr |= 0x80; -/* if (ide_board && (cr0&1) && !(eflags&VM_FLAG)) - { -// pclog("Failed read IDE %04X:%08X\n",CS,pc); - return 0xFF; - }*/ -// if ((cr0&1) && !(eflags&VM_FLAG)) -// pclog("ReadIDE %04X from %04X(%08X):%08X\n", addr, CS, cs, pc); -// return 0xFF; + /* if (ide_board && (cr0&1) && !(eflags&VM_FLAG)) + { + // pclog("Failed read IDE %04X:%08X\n",CS,pc); + return 0xFF; + }*/ + // if ((cr0&1) && !(eflags&VM_FLAG)) + // pclog("ReadIDE %04X from %04X(%08X):%08X\n", addr, CS, cs, pc); + // return 0xFF; - if (ide->type == IDE_NONE && (addr == 0x1f0 || addr == 0x1f7)) - return 0; -// /*if (addr!=0x1F7 && addr!=0x3F6) */pclog("Read IDEb %04X %02X %02X %i %04X:%04X %i %04X\n",addr,ide->atastat,(ide->atastat & ~DSC_STAT) | (ide->service ? SERVICE_STAT : 0),cur_ide[ide_board],CS,pc,ide_board, BX); -//rpclog("Read IDE %08X %08X %02X\n",addr,PC,iomd.irqb.mask); - switch (addr) { - case 0x1F0: /* Data */ - tempw = readidew(ide_board); -// pclog("Read IDEW %04X\n", tempw); - temp = tempw & 0xff; - break; + if (ide->type == IDE_NONE && (addr == 0x1f0 || addr == 0x1f7)) + return 0; + // /*if (addr!=0x1F7 && addr!=0x3F6) */pclog("Read IDEb %04X %02X %02X %i %04X:%04X %i + // %04X\n",addr,ide->atastat,(ide->atastat & ~DSC_STAT) | (ide->service ? SERVICE_STAT : + // 0),cur_ide[ide_board],CS,pc,ide_board, BX); + // rpclog("Read IDE %08X %08X %02X\n",addr,PC,iomd.irqb.mask); + switch (addr) { + case 0x1F0: /* Data */ + tempw = readidew(ide_board); + // pclog("Read IDEW %04X\n", tempw); + temp = tempw & 0xff; + break; - case 0x1F1: /* Error */ -// pclog("Read error %02X\n",ide.error); - temp = ide->error; - break; + case 0x1F1: /* Error */ + // pclog("Read error %02X\n",ide.error); + temp = ide->error; + break; - case 0x1F2: /* Sector count */ -// pclog("Read sector count %02X\n",ide->secount); - if (ide->type == IDE_CDROM && ide->command == WIN_PACKETCMD) - temp = atapi_read_iir(&ide->atapi); - else - temp = (uint8_t)ide->secount; - break; + case 0x1F2: /* Sector count */ + // pclog("Read sector count %02X\n",ide->secount); + if (ide->type == IDE_CDROM && ide->command == WIN_PACKETCMD) + temp = atapi_read_iir(&ide->atapi); + else + temp = (uint8_t)ide->secount; + break; - case 0x1F3: /* Sector */ - temp = (uint8_t)ide->sector; - break; + case 0x1F3: /* Sector */ + temp = (uint8_t)ide->sector; + break; - case 0x1F4: /* Cylinder low */ -// pclog("Read cyl low %02X\n",ide.cylinder&0xFF); - temp = (uint8_t)(ide->cylinder & 0xFF); - break; + case 0x1F4: /* Cylinder low */ + // pclog("Read cyl low %02X\n",ide.cylinder&0xFF); + temp = (uint8_t)(ide->cylinder & 0xFF); + break; - case 0x1F5: /* Cylinder high */ -// pclog("Read cyl low %02X\n",ide.cylinder>>8); - temp = (uint8_t)(ide->cylinder >> 8); - break; + case 0x1F5: /* Cylinder high */ + // pclog("Read cyl low %02X\n",ide.cylinder>>8); + temp = (uint8_t)(ide->cylinder >> 8); + break; - case 0x1F6: /* Drive/Head */ - temp = (uint8_t)(ide->head | ((cur_ide[ide_board] & 1) ? 0x10 : 0) | (ide->lba ? 0x40 : 0) | 0xa0); - break; + case 0x1F6: /* Drive/Head */ + temp = (uint8_t)(ide->head | ((cur_ide[ide_board] & 1) ? 0x10 : 0) | (ide->lba ? 0x40 : 0) | 0xa0); + break; - case 0x1F7: /* Status */ - if (ide->type == IDE_NONE) { -// pclog("Return status 00\n"); - temp = 0; - break; - } - ide_irq_lower(ide); - if (ide->type == IDE_CDROM) { -// pclog("Read CDROM status %02X\n",(ide->atastat & ~DSC_STAT) | (ide->service ? SERVICE_STAT : 0)); - temp = (ide->atastat & ~DSC_STAT) | (ide->service ? SERVICE_STAT : 0); - if (ide->command == WIN_PACKETCMD) { - if (atapi_read_drq(&ide->atapi)) - temp |= DRQ_STAT; - else - temp &= ~DRQ_STAT; - } - } else { -// && ide->service) return ide.atastat[ide.board]|SERVICE_STAT; -// pclog("Return status %02X %04X:%04X %02X %02X\n",ide->atastat, CS ,pc, AH, BH); - temp = ide->atastat; - } - break; + case 0x1F7: /* Status */ + if (ide->type == IDE_NONE) { + // pclog("Return status 00\n"); + temp = 0; + break; + } + ide_irq_lower(ide); + if (ide->type == IDE_CDROM) { + // pclog("Read CDROM status %02X\n",(ide->atastat & ~DSC_STAT) | (ide->service ? + // SERVICE_STAT : 0)); + temp = (ide->atastat & ~DSC_STAT) | (ide->service ? SERVICE_STAT : 0); + if (ide->command == WIN_PACKETCMD) { + if (atapi_read_drq(&ide->atapi)) + temp |= DRQ_STAT; + else + temp &= ~DRQ_STAT; + } + } else { + // && ide->service) return ide.atastat[ide.board]|SERVICE_STAT; + // pclog("Return status %02X %04X:%04X %02X %02X\n",ide->atastat, CS ,pc, AH, BH); + temp = ide->atastat; + } + break; - case 0x3F6: /* Alternate Status */ -// pclog("3F6 read %02X\n",ide.atastat[ide.board]); -// if (output) output=0; - if (ide->type == IDE_NONE) { -// pclog("Return status 00\n"); - temp = 0; - break; - } - if (ide->type == IDE_CDROM) { -// pclog("Read CDROM status %02X\n",(ide->atastat & ~DSC_STAT) | (ide->service ? SERVICE_STAT : 0)); - temp = (ide->atastat & ~DSC_STAT) | (ide->service ? SERVICE_STAT : 0); - if (ide->command == WIN_PACKETCMD) { - if (atapi_read_drq(&ide->atapi)) - temp |= DRQ_STAT; - else - temp &= ~DRQ_STAT; - } - } else { -// && ide->service) return ide.atastat[ide.board]|SERVICE_STAT; -// pclog("Return status %02X\n",ide->atastat); - temp = ide->atastat; - } - break; - } -// if (ide_board) pclog("Read IDEb %04X %02X %02X %02X %i %04X:%04X %i\n", addr, temp, ide->atastat,(ide->atastat & ~DSC_STAT) | (ide->service ? SERVICE_STAT : 0),cur_ide[ide_board],CS,cpu_state.pc,ide_board); - return temp; -// fatal("Bad IDE read %04X\n", addr); + case 0x3F6: /* Alternate Status */ + // pclog("3F6 read %02X\n",ide.atastat[ide.board]); + // if (output) output=0; + if (ide->type == IDE_NONE) { + // pclog("Return status 00\n"); + temp = 0; + break; + } + if (ide->type == IDE_CDROM) { + // pclog("Read CDROM status %02X\n",(ide->atastat & ~DSC_STAT) | (ide->service ? + // SERVICE_STAT : 0)); + temp = (ide->atastat & ~DSC_STAT) | (ide->service ? SERVICE_STAT : 0); + if (ide->command == WIN_PACKETCMD) { + if (atapi_read_drq(&ide->atapi)) + temp |= DRQ_STAT; + else + temp &= ~DRQ_STAT; + } + } else { + // && ide->service) return ide.atastat[ide.board]|SERVICE_STAT; + // pclog("Return status %02X\n",ide->atastat); + temp = ide->atastat; + } + break; + } + // if (ide_board) pclog("Read IDEb %04X %02X %02X %02X %i %04X:%04X %i\n", addr, temp, ide->atastat,(ide->atastat + // & ~DSC_STAT) | (ide->service ? SERVICE_STAT : 0),cur_ide[ide_board],CS,cpu_state.pc,ide_board); + return temp; + // fatal("Bad IDE read %04X\n", addr); } uint16_t readidew(int ide_board) { - IDE *ide = &ide_drives[cur_ide[ide_board]]; - uint16_t temp; + IDE *ide = &ide_drives[cur_ide[ide_board]]; + uint16_t temp; -/* if (ide_board && (cr0&1) && !(eflags&VM_FLAG)) - { -// pclog("Failed read IDEw %04X:%08X\n",CS,pc); - return 0xFFFF; - }*/ -// return 0xFFFF; -// pclog("Read IDEw %04X %04X:%04X %02X %i %i\n",ide->buffer[ide->pos >> 1],CS,pc,opcode,ins, ide->pos); + /* if (ide_board && (cr0&1) && !(eflags&VM_FLAG)) + { + // pclog("Failed read IDEw %04X:%08X\n",CS,pc); + return 0xFFFF; + }*/ + // return 0xFFFF; + // pclog("Read IDEw %04X %04X:%04X %02X %i %i\n",ide->buffer[ide->pos >> 1],CS,pc,opcode,ins, ide->pos); - if (ide->command == WIN_PACKETCMD) { - temp = atapi_data_read(&ide->atapi); - } else { - temp = ide->buffer[ide->pos >> 1]; - ide->pos += 2; - if (ide->pos >= 512 && ide->command) { -// pclog("Over! packlen %i %i\n",ide->packlen,ide->pos); - ide->pos = 0; - ide->atastat = READY_STAT | DSC_STAT; - 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 = BUSY_STAT | READY_STAT | DSC_STAT; - if (ide->command == WIN_READ_MULTIPLE) - callbackide(ide_board); - else - timer_set_delay_u64(&ide_timer[ide_board], 6 * IDE_TIME); -// pclog("set idecallback\n"); -// callbackide(ide_board); - } -// else -// pclog("readidew done %02X\n", ide->atastat); - } - } - } -// pclog("Read IDEw %04X\n",temp); - return temp; + if (ide->command == WIN_PACKETCMD) { + temp = atapi_data_read(&ide->atapi); + } else { + temp = ide->buffer[ide->pos >> 1]; + ide->pos += 2; + if (ide->pos >= 512 && ide->command) { + // pclog("Over! packlen %i %i\n",ide->packlen,ide->pos); + ide->pos = 0; + ide->atastat = READY_STAT | DSC_STAT; + 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 = BUSY_STAT | READY_STAT | DSC_STAT; + if (ide->command == WIN_READ_MULTIPLE) + callbackide(ide_board); + else + timer_set_delay_u64(&ide_timer[ide_board], 6 * IDE_TIME); + // pclog("set idecallback\n"); + // callbackide(ide_board); + } + // else + // pclog("readidew done %02X\n", ide->atastat); + } + } + } + // pclog("Read IDEw %04X\n",temp); + return temp; } uint32_t readidel(int ide_board) { - uint16_t temp; -// pclog("Read IDEl %i\n", ide_board); - temp = readidew(ide_board); - return temp | (readidew(ide_board) << 16); + uint16_t temp; + // pclog("Read IDEl %i\n", ide_board); + temp = readidew(ide_board); + return temp | (readidew(ide_board) << 16); } int times30 = 0; void callbackide(int ide_board) { - IDE *ide = &ide_drives[cur_ide[ide_board]]; - IDE *ide_other = &ide_drives[cur_ide[ide_board] ^ 1]; - atapi_device_t *atapi_dev = &ide->atapi; + IDE *ide = &ide_drives[cur_ide[ide_board]]; + IDE *ide_other = &ide_drives[cur_ide[ide_board] ^ 1]; + atapi_device_t *atapi_dev = &ide->atapi; - ext_ide = ide; -// return; - if (ide->command == 0x30) - times30++; -// if (times30==2240) output=1; - //if (times30==2471 && ide->command==0xA0) output=1; -///*if (ide_board) */pclog("CALLBACK %02X %i %i %i\n",ide->command,times30,ide->reset,cur_ide[ide_board]); -// if (times30==1294) -// output=1; - if (ide->reset) { - ide->atastat = ide_other->atastat = READY_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_CDROM(ide)) { - ide->cylinder = 0xEB14; - atapi->stop(); - atapi_reset(&ide->atapi); - } - if (ide->type == IDE_NONE) { - ide->cylinder = 0xFFFF; - ide->error = 0xff; - atapi->stop(); - } - if (IDE_DRIVE_IS_CDROM(ide_other)) { - ide_other->cylinder = 0xEB14; - atapi->stop(); - atapi_reset(&ide_other->atapi); - } - if (ide_other->type == IDE_NONE) { - ide_other->cylinder = 0xFFFF; - ide_other->error = 0xff; - atapi->stop(); - } -// pclog("Reset callback\n"); - 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 = READY_STAT | DSC_STAT; - ide->error = 1; /*Device passed*/ - ide->secount = ide->sector = 1; - ide_set_signature(ide); - if (IDE_DRIVE_IS_CDROM(ide)) - ide->atastat = 0; - ide_irq_raise(ide); - if (IDE_DRIVE_IS_CDROM(ide)) - ide->service = 0; - return; + ext_ide = ide; + // return; + if (ide->command == 0x30) + times30++; + // if (times30==2240) output=1; + // if (times30==2471 && ide->command==0xA0) output=1; + ///*if (ide_board) */pclog("CALLBACK %02X %i %i %i\n",ide->command,times30,ide->reset,cur_ide[ide_board]); + // if (times30==1294) + // output=1; + if (ide->reset) { + ide->atastat = ide_other->atastat = READY_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_CDROM(ide)) { + ide->cylinder = 0xEB14; + atapi->stop(); + atapi_reset(&ide->atapi); + } + if (ide->type == IDE_NONE) { + ide->cylinder = 0xFFFF; + ide->error = 0xff; + atapi->stop(); + } + if (IDE_DRIVE_IS_CDROM(ide_other)) { + ide_other->cylinder = 0xEB14; + atapi->stop(); + atapi_reset(&ide_other->atapi); + } + if (ide_other->type == IDE_NONE) { + ide_other->cylinder = 0xFFFF; + ide_other->error = 0xff; + atapi->stop(); + } + // pclog("Reset callback\n"); + 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 = READY_STAT | DSC_STAT; + ide->error = 1; /*Device passed*/ + ide->secount = ide->sector = 1; + ide_set_signature(ide); + if (IDE_DRIVE_IS_CDROM(ide)) + ide->atastat = 0; + ide_irq_raise(ide); + if (IDE_DRIVE_IS_CDROM(ide)) + ide->service = 0; + return; - case WIN_RESTORE: - case WIN_SEEK: - if (IDE_DRIVE_IS_CDROM(ide)) { - pclog("WIN_RESTORE callback on CD-ROM\n"); - goto abort_cmd; - } -// pclog("WIN_RESTORE callback\n"); - ide->atastat = READY_STAT | DSC_STAT; - ide_irq_raise(ide); - return; + case WIN_RESTORE: + case WIN_SEEK: + if (IDE_DRIVE_IS_CDROM(ide)) { + pclog("WIN_RESTORE callback on CD-ROM\n"); + goto abort_cmd; + } + // pclog("WIN_RESTORE callback\n"); + ide->atastat = READY_STAT | DSC_STAT; + ide_irq_raise(ide); + return; - case WIN_READ: - case WIN_READ_NORETRY: - if (IDE_DRIVE_IS_CDROM(ide)) { - ide_set_signature(ide); - goto abort_cmd; - } - if (ide->do_initial_read) { - ide->do_initial_read = 0; - ide->sector_pos = 0; - hdd_read_sectors(&ide->hdd_file, ide_get_sector(ide), ide->secount ? ide->secount : 256, ide->sector_buffer); - } - memcpy(ide->buffer, &ide->sector_buffer[ide->sector_pos * 512], 512); - ide->sector_pos++; -// pclog("Read %i %i %i %08X\n",ide.cylinder,ide.head,ide.sector,addr); - /* if (ide.cylinder || ide.head) - { - fatal("Read from other cylinder/head"); - }*/ - ide->pos = 0; - ide->atastat = DRQ_STAT | READY_STAT | DSC_STAT; -// pclog("Read sector callback %i %i %i offset %08X %i left %i %02X\n",ide.sector,ide.cylinder,ide.head,addr,ide.secount,ide.spt,ide.atastat[ide.board]); -// if (addr) output=3; - ide_irq_raise(ide); + case WIN_READ: + case WIN_READ_NORETRY: + if (IDE_DRIVE_IS_CDROM(ide)) { + ide_set_signature(ide); + goto abort_cmd; + } + if (ide->do_initial_read) { + ide->do_initial_read = 0; + ide->sector_pos = 0; + hdd_read_sectors(&ide->hdd_file, ide_get_sector(ide), ide->secount ? ide->secount : 256, + ide->sector_buffer); + } + memcpy(ide->buffer, &ide->sector_buffer[ide->sector_pos * 512], 512); + ide->sector_pos++; + // pclog("Read %i %i %i %08X\n",ide.cylinder,ide.head,ide.sector,addr); + /* if (ide.cylinder || ide.head) + { + fatal("Read from other cylinder/head"); + }*/ + ide->pos = 0; + ide->atastat = DRQ_STAT | READY_STAT | DSC_STAT; + // pclog("Read sector callback %i %i %i offset %08X %i left %i + // %02X\n",ide.sector,ide.cylinder,ide.head,addr,ide.secount,ide.spt,ide.atastat[ide.board]); if + // (addr) output=3; + ide_irq_raise(ide); - readflash_set(READFLASH_HDC, ide->drive); - return; + readflash_set(READFLASH_HDC, ide->drive); + return; - case WIN_READ_DMA: - if (IDE_DRIVE_IS_CDROM(ide)) { - goto abort_cmd; - } - if (ide->do_initial_read) { - ide->do_initial_read = 0; - ide->sector_pos = 0; - hdd_read_sectors(&ide->hdd_file, ide_get_sector(ide), ide->secount ? ide->secount : 256, ide->sector_buffer); - } - ide->pos = 0; + case WIN_READ_DMA: + if (IDE_DRIVE_IS_CDROM(ide)) { + goto abort_cmd; + } + if (ide->do_initial_read) { + ide->do_initial_read = 0; + ide->sector_pos = 0; + hdd_read_sectors(&ide->hdd_file, ide_get_sector(ide), ide->secount ? ide->secount : 256, + ide->sector_buffer); + } + ide->pos = 0; - if (ide_bus_master_read_data) { - if (ide_bus_master_read_data(ide_board, &ide->sector_buffer[ide->sector_pos * 512], 512, ide_bus_master_p)) - timer_set_delay_u64(&ide_timer[ide_board], 6 * IDE_TIME); /*DMA not performed, try again later*/ - else { - /*DMA successful*/ - ide->sector_pos++; - ide->atastat = DRQ_STAT | READY_STAT | DSC_STAT; + if (ide_bus_master_read_data) { + if (ide_bus_master_read_data(ide_board, &ide->sector_buffer[ide->sector_pos * 512], 512, + ide_bus_master_p)) + timer_set_delay_u64(&ide_timer[ide_board], 6 * IDE_TIME); /*DMA not performed, try again later*/ + else { + /*DMA successful*/ + ide->sector_pos++; + ide->atastat = DRQ_STAT | READY_STAT | DSC_STAT; - ide->secount = (ide->secount - 1) & 0xff; - if (ide->secount) { - ide_next_sector(ide); - ide->atastat = BUSY_STAT; - timer_set_delay_u64(&ide_timer[ide_board], 6 * IDE_TIME); - } else { - ide_irq_raise(ide); - } - } - } + ide->secount = (ide->secount - 1) & 0xff; + if (ide->secount) { + ide_next_sector(ide); + ide->atastat = BUSY_STAT; + timer_set_delay_u64(&ide_timer[ide_board], 6 * IDE_TIME); + } else { + ide_irq_raise(ide); + } + } + } - readflash_set(READFLASH_HDC, ide->drive); - return; + readflash_set(READFLASH_HDC, ide->drive); + return; - case WIN_READ_MULTIPLE: - if (IDE_DRIVE_IS_CDROM(ide)) { - goto abort_cmd; - } - if (ide->do_initial_read) { - ide->do_initial_read = 0; - ide->sector_pos = 0; - hdd_read_sectors(&ide->hdd_file, ide_get_sector(ide), ide->secount ? ide->secount : 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 | READY_STAT | DSC_STAT; - if (!ide->blockcount)// || ide->secount == 1) - { -// pclog("Read multiple int\n"); - ide_irq_raise(ide); - } - ide->blockcount++; - if (ide->blockcount >= ide->blocksize) - ide->blockcount = 0; + case WIN_READ_MULTIPLE: + if (IDE_DRIVE_IS_CDROM(ide)) { + goto abort_cmd; + } + if (ide->do_initial_read) { + ide->do_initial_read = 0; + ide->sector_pos = 0; + hdd_read_sectors(&ide->hdd_file, ide_get_sector(ide), ide->secount ? ide->secount : 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 | READY_STAT | DSC_STAT; + if (!ide->blockcount) // || ide->secount == 1) + { + // pclog("Read multiple int\n"); + ide_irq_raise(ide); + } + ide->blockcount++; + if (ide->blockcount >= ide->blocksize) + ide->blockcount = 0; - readflash_set(READFLASH_HDC, ide->drive); - return; + readflash_set(READFLASH_HDC, ide->drive); + return; - case WIN_WRITE: - case WIN_WRITE_NORETRY: - if (IDE_DRIVE_IS_CDROM(ide)) { - goto abort_cmd; - } - hdd_write_sectors(&ide->hdd_file, ide_get_sector(ide), 1, ide->buffer); - ide_irq_raise(ide); - ide->secount = (ide->secount - 1) & 0xff; - if (ide->secount) { - ide->atastat = DRQ_STAT | READY_STAT | DSC_STAT; - ide->pos = 0; - ide_next_sector(ide); - } else - ide->atastat = READY_STAT | DSC_STAT; + case WIN_WRITE: + case WIN_WRITE_NORETRY: + if (IDE_DRIVE_IS_CDROM(ide)) { + goto abort_cmd; + } + hdd_write_sectors(&ide->hdd_file, ide_get_sector(ide), 1, ide->buffer); + ide_irq_raise(ide); + ide->secount = (ide->secount - 1) & 0xff; + if (ide->secount) { + ide->atastat = DRQ_STAT | READY_STAT | DSC_STAT; + ide->pos = 0; + ide_next_sector(ide); + } else + ide->atastat = READY_STAT | DSC_STAT; - readflash_set(READFLASH_HDC, ide->drive); - return; + readflash_set(READFLASH_HDC, ide->drive); + return; - case WIN_WRITE_DMA: - if (IDE_DRIVE_IS_CDROM(ide)) { - goto abort_cmd; - } + case WIN_WRITE_DMA: + if (IDE_DRIVE_IS_CDROM(ide)) { + goto abort_cmd; + } - if (ide_bus_master_write_data) { - if (ide_bus_master_write_data(ide_board, (uint8_t *)ide->buffer, 512, ide_bus_master_p)) - timer_set_delay_u64(&ide_timer[ide_board], 6 * IDE_TIME); /*DMA not performed, try again later*/ - else { - /*DMA successful*/ - hdd_write_sectors(&ide->hdd_file, ide_get_sector(ide), 1, ide->buffer); + if (ide_bus_master_write_data) { + if (ide_bus_master_write_data(ide_board, (uint8_t *)ide->buffer, 512, ide_bus_master_p)) + timer_set_delay_u64(&ide_timer[ide_board], 6 * IDE_TIME); /*DMA not performed, try again later*/ + else { + /*DMA successful*/ + hdd_write_sectors(&ide->hdd_file, ide_get_sector(ide), 1, ide->buffer); - ide->atastat = DRQ_STAT | READY_STAT | DSC_STAT; + ide->atastat = DRQ_STAT | READY_STAT | DSC_STAT; - ide->secount = (ide->secount - 1) & 0xff; - if (ide->secount) { - ide_next_sector(ide); - ide->atastat = BUSY_STAT; - timer_set_delay_u64(&ide_timer[ide_board], 6 * IDE_TIME); - } else { - ide_irq_raise(ide); - } - } - } + ide->secount = (ide->secount - 1) & 0xff; + if (ide->secount) { + ide_next_sector(ide); + ide->atastat = BUSY_STAT; + timer_set_delay_u64(&ide_timer[ide_board], 6 * IDE_TIME); + } else { + ide_irq_raise(ide); + } + } + } - readflash_set(READFLASH_HDC, ide->drive); - return; + readflash_set(READFLASH_HDC, ide->drive); + return; - case WIN_WRITE_MULTIPLE: - if (IDE_DRIVE_IS_CDROM(ide)) { - goto abort_cmd; - } - hdd_write_sectors(&ide->hdd_file, ide_get_sector(ide), 1, 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 | READY_STAT | DSC_STAT; - ide->pos = 0; - ide_next_sector(ide); - } else - ide->atastat = READY_STAT | DSC_STAT; + case WIN_WRITE_MULTIPLE: + if (IDE_DRIVE_IS_CDROM(ide)) { + goto abort_cmd; + } + hdd_write_sectors(&ide->hdd_file, ide_get_sector(ide), 1, 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 | READY_STAT | DSC_STAT; + ide->pos = 0; + ide_next_sector(ide); + } else + ide->atastat = READY_STAT | DSC_STAT; - readflash_set(READFLASH_HDC, ide->drive); - return; + readflash_set(READFLASH_HDC, ide->drive); + return; - case WIN_VERIFY: - case WIN_VERIFY_ONCE: - if (IDE_DRIVE_IS_CDROM(ide)) { - goto abort_cmd; - } - ide->pos = 0; - ide->atastat = READY_STAT | DSC_STAT; -// pclog("Read verify callback %i %i %i offset %08X %i left\n",ide.sector,ide.cylinder,ide.head,addr,ide.secount); - ide_irq_raise(ide); + case WIN_VERIFY: + case WIN_VERIFY_ONCE: + if (IDE_DRIVE_IS_CDROM(ide)) { + goto abort_cmd; + } + ide->pos = 0; + ide->atastat = READY_STAT | DSC_STAT; + // pclog("Read verify callback %i %i %i offset %08X %i + // left\n",ide.sector,ide.cylinder,ide.head,addr,ide.secount); + ide_irq_raise(ide); - readflash_set(READFLASH_HDC, ide->drive); - return; + readflash_set(READFLASH_HDC, ide->drive); + return; - case WIN_FORMAT: - if (IDE_DRIVE_IS_CDROM(ide)) { - goto abort_cmd; - } - hdd_format_sectors(&ide->hdd_file, ide_get_sector(ide), ide->secount); - ide->atastat = READY_STAT | DSC_STAT; - ide_irq_raise(ide); + case WIN_FORMAT: + if (IDE_DRIVE_IS_CDROM(ide)) { + goto abort_cmd; + } + hdd_format_sectors(&ide->hdd_file, ide_get_sector(ide), ide->secount); + ide->atastat = READY_STAT | DSC_STAT; + ide_irq_raise(ide); - readflash_set(READFLASH_HDC, ide->drive); - return; + readflash_set(READFLASH_HDC, ide->drive); + return; - case WIN_DRIVE_DIAGNOSTICS:ide_set_signature(ide); - ide->error = 1; /*No error detected*/ - if (IDE_DRIVE_IS_CDROM(ide)) { - ide->atastat = 0; - } else { - ide->atastat = READY_STAT | DSC_STAT; - ide_irq_raise(ide); - } - return; + case WIN_DRIVE_DIAGNOSTICS: + ide_set_signature(ide); + ide->error = 1; /*No error detected*/ + if (IDE_DRIVE_IS_CDROM(ide)) { + ide->atastat = 0; + } else { + ide->atastat = READY_STAT | DSC_STAT; + ide_irq_raise(ide); + } + return; - case WIN_SPECIFY: /* Initialize Drive Parameters */ - if (IDE_DRIVE_IS_CDROM(ide)) { - pclog("IS CDROM - ABORT\n"); - goto abort_cmd; - } - ide->hdd_file.spt = ide->secount; - ide->hdd_file.hpc = ide->head + 1; - ide->atastat = READY_STAT | DSC_STAT; -// pclog("SPECIFY - %i sectors per track, %i heads per cylinder %i %i\n",ide->spt,ide->hpc,cur_ide[ide_board],ide_board); - ide_irq_raise(ide); - return; + case WIN_SPECIFY: /* Initialize Drive Parameters */ + if (IDE_DRIVE_IS_CDROM(ide)) { + pclog("IS CDROM - ABORT\n"); + goto abort_cmd; + } + ide->hdd_file.spt = ide->secount; + ide->hdd_file.hpc = ide->head + 1; + ide->atastat = READY_STAT | DSC_STAT; + // pclog("SPECIFY - %i sectors per track, %i heads per cylinder %i + // %i\n",ide->spt,ide->hpc,cur_ide[ide_board],ide_board); + ide_irq_raise(ide); + return; - case WIN_PIDENTIFY: /* Identify Packet Device */ - if (IDE_DRIVE_IS_CDROM(ide)) { -// pclog("ATAPI identify\n"); - atapi_dev->bus.devices[0]->atapi_identify(ide->buffer, atapi_dev->bus.device_data[0]); + case WIN_PIDENTIFY: /* Identify Packet Device */ + if (IDE_DRIVE_IS_CDROM(ide)) { + // pclog("ATAPI identify\n"); + atapi_dev->bus.devices[0]->atapi_identify(ide->buffer, atapi_dev->bus.device_data[0]); - ide->pos = 0; - ide->error = 0; - ide->atastat = DRQ_STAT | READY_STAT | DSC_STAT; - ide_irq_raise(ide); - return; - } -// pclog("Not ATAPI\n"); - goto abort_cmd; + ide->pos = 0; + ide->error = 0; + ide->atastat = DRQ_STAT | READY_STAT | DSC_STAT; + ide_irq_raise(ide); + return; + } + // pclog("Not ATAPI\n"); + goto abort_cmd; - case WIN_SET_MULTIPLE_MODE: - if (IDE_DRIVE_IS_CDROM(ide)) { - pclog("IS CDROM - ABORT\n"); - goto abort_cmd; - } - ide->blocksize = ide->secount; - ide->atastat = READY_STAT | DSC_STAT; - pclog("Set multiple mode - %i\n", ide->blocksize); - ide_irq_raise(ide); - return; + case WIN_SET_MULTIPLE_MODE: + if (IDE_DRIVE_IS_CDROM(ide)) { + pclog("IS CDROM - ABORT\n"); + goto abort_cmd; + } + ide->blocksize = ide->secount; + ide->atastat = READY_STAT | DSC_STAT; + pclog("Set multiple mode - %i\n", ide->blocksize); + ide_irq_raise(ide); + return; - case WIN_SETIDLE1: /* Idle */ - goto abort_cmd; + case WIN_SETIDLE1: /* Idle */ + goto abort_cmd; - case WIN_IDENTIFY: /* Identify Device */ - if (ide->type == IDE_NONE) { - goto abort_cmd; - } - if (IDE_DRIVE_IS_CDROM(ide)) { - ide_set_signature(ide); - goto abort_cmd; - } else { - ide_identify(ide); - ide->pos = 0; - ide->atastat = DRQ_STAT | READY_STAT | DSC_STAT; -// pclog("ID callback\n"); - ide_irq_raise(ide); - } - return; + case WIN_IDENTIFY: /* Identify Device */ + if (ide->type == IDE_NONE) { + goto abort_cmd; + } + if (IDE_DRIVE_IS_CDROM(ide)) { + ide_set_signature(ide); + goto abort_cmd; + } else { + ide_identify(ide); + ide->pos = 0; + ide->atastat = DRQ_STAT | READY_STAT | DSC_STAT; + // pclog("ID callback\n"); + ide_irq_raise(ide); + } + return; - case WIN_SET_FEATURES: - if (ide->type == IDE_NONE) - goto abort_cmd; - if (!IDE_DRIVE_IS_CDROM(ide)) - goto abort_cmd; + case WIN_SET_FEATURES: + if (ide->type == IDE_NONE) + goto abort_cmd; + if (!IDE_DRIVE_IS_CDROM(ide)) + goto abort_cmd; - if (!atapi_dev->bus.devices[0]->atapi_set_feature(ide->cylprecomp, ide->secount, atapi_dev->bus.device_data[0])) - goto abort_cmd; - ide->atastat = READY_STAT | DSC_STAT; - ide_irq_raise(ide); - return; + if (!atapi_dev->bus.devices[0]->atapi_set_feature(ide->cylprecomp, ide->secount, atapi_dev->bus.device_data[0])) + goto abort_cmd; + ide->atastat = READY_STAT | DSC_STAT; + ide_irq_raise(ide); + return; - case WIN_CHECK_POWER_MODE: - if (ide->type == IDE_NONE) { - goto abort_cmd; - } - ide->secount = 0xff; - ide->atastat = READY_STAT | DSC_STAT; - ide_irq_raise(ide); - return; + case WIN_CHECK_POWER_MODE: + if (ide->type == IDE_NONE) { + goto abort_cmd; + } + ide->secount = 0xff; + ide->atastat = READY_STAT | DSC_STAT; + ide_irq_raise(ide); + return; - case WIN_PACKETCMD: /* ATAPI Packet */ - if (!IDE_DRIVE_IS_CDROM(ide)) - goto abort_cmd; + case WIN_PACKETCMD: /* ATAPI Packet */ + if (!IDE_DRIVE_IS_CDROM(ide)) + goto abort_cmd; - atapi_process_packet(atapi_dev); + atapi_process_packet(atapi_dev); - return; - } + return; + } - abort_cmd: - ide->command = 0; - ide->atastat = READY_STAT | ERR_STAT | DSC_STAT; - ide->error = ABRT_ERR; - ide->pos = 0; - ide_irq_raise(ide); +abort_cmd: + ide->command = 0; + ide->atastat = READY_STAT | ERR_STAT | DSC_STAT; + ide->error = ABRT_ERR; + ide->pos = 0; + ide_irq_raise(ide); } -void ide_callback_pri() { - callbackide(0); -} +void ide_callback_pri() { callbackide(0); } -void ide_callback_sec() { - callbackide(1); -} +void ide_callback_sec() { callbackide(1); } -void ide_write_pri(uint16_t addr, uint8_t val, void *priv) { - writeide(0, addr, val); -} -void ide_write_pri_w(uint16_t addr, uint16_t val, void *priv) { - writeidew(0, val); -} -void ide_write_pri_l(uint16_t addr, uint32_t val, void *priv) { - writeidel(0, val); -} -uint8_t ide_read_pri(uint16_t addr, void *priv) { - return readide(0, addr); -} -uint16_t ide_read_pri_w(uint16_t addr, void *priv) { - return readidew(0); -} -uint32_t ide_read_pri_l(uint16_t addr, void *priv) { - return readidel(0); -} +void ide_write_pri(uint16_t addr, uint8_t val, void *priv) { writeide(0, addr, val); } +void ide_write_pri_w(uint16_t addr, uint16_t val, void *priv) { writeidew(0, val); } +void ide_write_pri_l(uint16_t addr, uint32_t val, void *priv) { writeidel(0, val); } +uint8_t ide_read_pri(uint16_t addr, void *priv) { return readide(0, addr); } +uint16_t ide_read_pri_w(uint16_t addr, void *priv) { return readidew(0); } +uint32_t ide_read_pri_l(uint16_t addr, void *priv) { return readidel(0); } -void ide_write_sec(uint16_t addr, uint8_t val, void *priv) { - writeide(1, addr, val); -} -void ide_write_sec_w(uint16_t addr, uint16_t val, void *priv) { - writeidew(1, val); -} -void ide_write_sec_l(uint16_t addr, uint32_t val, void *priv) { - writeidel(1, val); -} -uint8_t ide_read_sec(uint16_t addr, void *priv) { - return readide(1, addr); -} -uint16_t ide_read_sec_w(uint16_t addr, void *priv) { - return readidew(1); -} -uint32_t ide_read_sec_l(uint16_t addr, void *priv) { - return readidel(1); -} +void ide_write_sec(uint16_t addr, uint8_t val, void *priv) { writeide(1, addr, val); } +void ide_write_sec_w(uint16_t addr, uint16_t val, void *priv) { writeidew(1, val); } +void ide_write_sec_l(uint16_t addr, uint32_t val, void *priv) { writeidel(1, val); } +uint8_t ide_read_sec(uint16_t addr, void *priv) { return readide(1, addr); } +uint16_t ide_read_sec_w(uint16_t addr, void *priv) { return readidew(1); } +uint32_t ide_read_sec_l(uint16_t addr, void *priv) { return readidel(1); } void ide_pri_enable() { - io_sethandler(0x01f0, 0x0008, ide_read_pri, ide_read_pri_w, ide_read_pri_l, ide_write_pri, ide_write_pri_w, ide_write_pri_l, NULL); - io_sethandler(0x03f6, 0x0001, ide_read_pri, NULL, NULL, ide_write_pri, NULL, NULL, NULL); + io_sethandler(0x01f0, 0x0008, ide_read_pri, ide_read_pri_w, ide_read_pri_l, ide_write_pri, ide_write_pri_w, + ide_write_pri_l, NULL); + io_sethandler(0x03f6, 0x0001, ide_read_pri, NULL, NULL, ide_write_pri, NULL, NULL, NULL); } void ide_pri_disable() { - io_removehandler(0x01f0, 0x0008, ide_read_pri, ide_read_pri_w, ide_read_pri_l, ide_write_pri, ide_write_pri_w, ide_write_pri_l, NULL); - io_removehandler(0x03f6, 0x0001, ide_read_pri, NULL, NULL, ide_write_pri, NULL, NULL, NULL); + io_removehandler(0x01f0, 0x0008, ide_read_pri, ide_read_pri_w, ide_read_pri_l, ide_write_pri, ide_write_pri_w, + ide_write_pri_l, NULL); + io_removehandler(0x03f6, 0x0001, ide_read_pri, NULL, NULL, ide_write_pri, NULL, NULL, NULL); } void ide_sec_enable() { - io_sethandler(0x0170, 0x0008, ide_read_sec, ide_read_sec_w, ide_read_sec_l, ide_write_sec, ide_write_sec_w, ide_write_sec_l, NULL); - io_sethandler(0x0376, 0x0001, ide_read_sec, NULL, NULL, ide_write_sec, NULL, NULL, NULL); + io_sethandler(0x0170, 0x0008, ide_read_sec, ide_read_sec_w, ide_read_sec_l, ide_write_sec, ide_write_sec_w, + ide_write_sec_l, NULL); + io_sethandler(0x0376, 0x0001, ide_read_sec, NULL, NULL, ide_write_sec, NULL, NULL, NULL); } void ide_sec_disable() { - io_removehandler(0x0170, 0x0008, ide_read_sec, ide_read_sec_w, ide_read_sec_l, ide_write_sec, ide_write_sec_w, ide_write_sec_l, NULL); - io_removehandler(0x0376, 0x0001, ide_read_sec, NULL, NULL, ide_write_sec, NULL, NULL, NULL); + io_removehandler(0x0170, 0x0008, ide_read_sec, ide_read_sec_w, ide_read_sec_l, ide_write_sec, ide_write_sec_w, + ide_write_sec_l, NULL); + io_removehandler(0x0376, 0x0001, ide_read_sec, NULL, NULL, ide_write_sec, NULL, NULL, NULL); } static void *ide_init() { - ide_pri_enable(); - ide_sec_enable(); + ide_pri_enable(); + ide_sec_enable(); - timer_add(&ide_timer[0], ide_callback_pri, NULL, 0); - timer_add(&ide_timer[1], ide_callback_sec, NULL, 0); + timer_add(&ide_timer[0], ide_callback_pri, NULL, 0); + timer_add(&ide_timer[1], ide_callback_sec, NULL, 0); - return (void *)-1; + return (void *)-1; } static void ide_close(void *p) { - int c; + int c; - for (c = 0; c < 4; c++) { - ide_drives[c].type = IDE_NONE; - hdd_close(&ide_drives[c].hdd_file); - } + for (c = 0; c < 4; c++) { + ide_drives[c].type = IDE_NONE; + hdd_close(&ide_drives[c].hdd_file); + } } -void -ide_set_bus_master(int (*read_data)(int channel, uint8_t *data, int size, void *p), int (*write_data)(int channel, uint8_t *data, int size, void *p), void (*set_irq)(int channel, void *p), void *p) { - ide_bus_master_read_data = read_data; - ide_bus_master_write_data = write_data; - ide_bus_master_set_irq = set_irq; - ide_bus_master_p = p; +void ide_set_bus_master(int (*read_data)(int channel, uint8_t *data, int size, void *p), + int (*write_data)(int channel, uint8_t *data, int size, void *p), void (*set_irq)(int channel, void *p), + void *p) { + ide_bus_master_read_data = read_data; + ide_bus_master_write_data = write_data; + ide_bus_master_set_irq = set_irq; + ide_bus_master_p = p; } void ide_reset_devices() { - if (ide_drives[0].type != IDE_NONE || ide_drives[1].type != IDE_NONE) { - timer_set_delay_u64(&ide_timer[0], 500 * IDE_TIME); - ide_drives[0].reset = ide_drives[1].reset = 1; - ide_drives[0].atastat = ide_drives[1].atastat = BUSY_STAT; - if (ide_drives[0].type != IDE_NONE) - cur_ide[0] = 0; - else - cur_ide[0] = 1; - } - if (ide_drives[2].type != IDE_NONE || ide_drives[3].type != IDE_NONE) { - timer_set_delay_u64(&ide_timer[1], 500 * IDE_TIME); - ide_drives[2].reset = ide_drives[3].reset = 1; - ide_drives[2].atastat = ide_drives[3].atastat = BUSY_STAT; - if (ide_drives[2].type != IDE_NONE) - cur_ide[1] = 2; - else - cur_ide[1] = 3; - } + if (ide_drives[0].type != IDE_NONE || ide_drives[1].type != IDE_NONE) { + timer_set_delay_u64(&ide_timer[0], 500 * IDE_TIME); + ide_drives[0].reset = ide_drives[1].reset = 1; + ide_drives[0].atastat = ide_drives[1].atastat = BUSY_STAT; + if (ide_drives[0].type != IDE_NONE) + cur_ide[0] = 0; + else + cur_ide[0] = 1; + } + if (ide_drives[2].type != IDE_NONE || ide_drives[3].type != IDE_NONE) { + timer_set_delay_u64(&ide_timer[1], 500 * IDE_TIME); + ide_drives[2].reset = ide_drives[3].reset = 1; + ide_drives[2].atastat = ide_drives[3].atastat = BUSY_STAT; + if (ide_drives[2].type != IDE_NONE) + cur_ide[1] = 2; + else + cur_ide[1] = 3; + } } -device_t ide_device = - { - "Standard IDE", - DEVICE_AT, - ide_init, - ide_close, - NULL, - NULL, - NULL, - NULL, - NULL - }; +device_t ide_device = {"Standard IDE", DEVICE_AT, ide_init, ide_close, NULL, NULL, NULL, NULL, NULL}; diff --git a/src/ide/ide_atapi.c b/src/ide/ide_atapi.c index d51adf6b..c24d2335 100644 --- a/src/ide/ide_atapi.c +++ b/src/ide/ide_atapi.c @@ -6,486 +6,495 @@ #define IDE_TIME (100 * TIMER_USEC) -#define ATAPI_STATE_IDLE 0 -#define ATAPI_STATE_COMMAND 1 -#define ATAPI_STATE_GOT_COMMAND 2 -#define ATAPI_STATE_NEXT_PHASE 3 -#define ATAPI_STATE_READ_STATUS 4 -#define ATAPI_STATE_READ_MESSAGE 5 -#define ATAPI_STATE_END_PHASE 6 -#define ATAPI_STATE_READ_DATA 7 -#define ATAPI_STATE_READ_DATA_WAIT 8 -#define ATAPI_STATE_WRITE_DATA 9 +#define ATAPI_STATE_IDLE 0 +#define ATAPI_STATE_COMMAND 1 +#define ATAPI_STATE_GOT_COMMAND 2 +#define ATAPI_STATE_NEXT_PHASE 3 +#define ATAPI_STATE_READ_STATUS 4 +#define ATAPI_STATE_READ_MESSAGE 5 +#define ATAPI_STATE_END_PHASE 6 +#define ATAPI_STATE_READ_DATA 7 +#define ATAPI_STATE_READ_DATA_WAIT 8 +#define ATAPI_STATE_WRITE_DATA 9 #define ATAPI_STATE_WRITE_DATA_WAIT 10 -#define ATAPI_STATE_RETRY_READ_DMA 11 +#define ATAPI_STATE_RETRY_READ_DMA 11 #define ATAPI_STATE_RETRY_WRITE_DMA 12 -#define FEATURES_DMA 0x01 +#define FEATURES_DMA 0x01 #define FEATURES_OVERLAP 0x02 ATAPI *atapi; void atapi_data_write(atapi_device_t *atapi_dev, uint16_t val) { - switch (atapi_dev->state) { - case ATAPI_STATE_COMMAND:atapi_dev->command[atapi_dev->command_pos++] = val & 0xff; - atapi_dev->command[atapi_dev->command_pos++] = val >> 8; - if (atapi_dev->command_pos >= 12) { - atapi_dev->state = ATAPI_STATE_GOT_COMMAND; - timer_set_delay_u64(&ide_timer[atapi_dev->board], 6 * IDE_TIME); - *atapi_dev->atastat = BUSY_STAT | (*atapi_dev->atastat & ERR_STAT); - } - break; + switch (atapi_dev->state) { + case ATAPI_STATE_COMMAND: + atapi_dev->command[atapi_dev->command_pos++] = val & 0xff; + atapi_dev->command[atapi_dev->command_pos++] = val >> 8; + if (atapi_dev->command_pos >= 12) { + atapi_dev->state = ATAPI_STATE_GOT_COMMAND; + timer_set_delay_u64(&ide_timer[atapi_dev->board], 6 * IDE_TIME); + *atapi_dev->atastat = BUSY_STAT | (*atapi_dev->atastat & ERR_STAT); + } + break; - case ATAPI_STATE_WRITE_DATA_WAIT:atapi_dev->data[atapi_dev->data_write_pos++] = val & 0xff; - atapi_dev->data[atapi_dev->data_write_pos++] = val >> 8; -// pclog("Write ATAPI data %i %i %i\n", atapi_dev->data_write_pos, atapi_dev->data_read_pos, idecallback[atapi_dev->board]); - if (atapi_dev->data_write_pos >= atapi_dev->data_read_pos) { - atapi_dev->bus_state = 0; - atapi_dev->state = ATAPI_STATE_WRITE_DATA; - timer_set_delay_u64(&ide_timer[atapi_dev->board], 6 * IDE_TIME); - *atapi_dev->atastat = BUSY_STAT | (*atapi_dev->atastat & ERR_STAT); - } - break; - } + case ATAPI_STATE_WRITE_DATA_WAIT: + atapi_dev->data[atapi_dev->data_write_pos++] = val & 0xff; + atapi_dev->data[atapi_dev->data_write_pos++] = val >> 8; + // pclog("Write ATAPI data %i %i %i\n", atapi_dev->data_write_pos, atapi_dev->data_read_pos, + // idecallback[atapi_dev->board]); + if (atapi_dev->data_write_pos >= atapi_dev->data_read_pos) { + atapi_dev->bus_state = 0; + atapi_dev->state = ATAPI_STATE_WRITE_DATA; + timer_set_delay_u64(&ide_timer[atapi_dev->board], 6 * IDE_TIME); + *atapi_dev->atastat = BUSY_STAT | (*atapi_dev->atastat & ERR_STAT); + } + break; + } } uint16_t atapi_data_read(atapi_device_t *atapi_dev) { - uint16_t temp = 0xffff; + uint16_t temp = 0xffff; - switch (atapi_dev->state) { - case ATAPI_STATE_READ_DATA_WAIT: - if (atapi_dev->data_read_pos >= atapi_dev->data_write_pos) { -// pclog("ATAPI_STATE_READ_DATA_WAIT - out of data!\n"); - break; - } + switch (atapi_dev->state) { + case ATAPI_STATE_READ_DATA_WAIT: + if (atapi_dev->data_read_pos >= atapi_dev->data_write_pos) { + // pclog("ATAPI_STATE_READ_DATA_WAIT - out of data!\n"); + break; + } - temp = atapi_dev->data[atapi_dev->data_read_pos++]; - if (atapi_dev->data_read_pos < atapi_dev->data_write_pos) - temp |= (atapi_dev->data[atapi_dev->data_read_pos++] << 8); -// pclog("Read data %04x\n", temp); - if (atapi_dev->data_read_pos >= atapi_dev->data_write_pos) { - atapi_dev->state = ATAPI_STATE_NEXT_PHASE; - timer_set_delay_u64(&ide_timer[atapi_dev->board], 6 * IDE_TIME); - *atapi_dev->atastat = BUSY_STAT | (*atapi_dev->atastat & ERR_STAT); - } - break; - } + temp = atapi_dev->data[atapi_dev->data_read_pos++]; + if (atapi_dev->data_read_pos < atapi_dev->data_write_pos) + temp |= (atapi_dev->data[atapi_dev->data_read_pos++] << 8); + // pclog("Read data %04x\n", temp); + if (atapi_dev->data_read_pos >= atapi_dev->data_write_pos) { + atapi_dev->state = ATAPI_STATE_NEXT_PHASE; + timer_set_delay_u64(&ide_timer[atapi_dev->board], 6 * IDE_TIME); + *atapi_dev->atastat = BUSY_STAT | (*atapi_dev->atastat & ERR_STAT); + } + break; + } - return temp; + return temp; } static int wait_for_bus(scsi_bus_t *bus, int state, int req_needed) { - int c; + int c; - for (c = 0; c < 20; c++) { - int bus_state = scsi_bus_read(bus); + for (c = 0; c < 20; c++) { + int bus_state = scsi_bus_read(bus); - if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) == state && (bus_state & BUS_BSY)) { - if (!req_needed || (bus_state & BUS_REQ)) - return 1; - } - } + if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) == state && (bus_state & BUS_BSY)) { + if (!req_needed || (bus_state & BUS_REQ)) + return 1; + } + } - return 0; + return 0; } void atapi_command_start(atapi_device_t *atapi, uint8_t features) { - scsi_bus_t *bus = &atapi->bus; + scsi_bus_t *bus = &atapi->bus; - atapi->use_dma = features & 1; + atapi->use_dma = features & 1; - scsi_bus_update(bus, BUS_SEL | BUS_SETDATA(1 << 0)); - if (!(scsi_bus_read(bus) & BUS_BSY)) - fatal("STATE_SCSI_SELECT failed to select target\n"); + scsi_bus_update(bus, BUS_SEL | BUS_SETDATA(1 << 0)); + if (!(scsi_bus_read(bus) & BUS_BSY)) + fatal("STATE_SCSI_SELECT failed to select target\n"); - scsi_bus_update(bus, 0); - if (!(scsi_bus_read(bus) & BUS_BSY)) - fatal("STATE_SCSI_SELECT failed to select target 2\n"); + scsi_bus_update(bus, 0); + if (!(scsi_bus_read(bus) & BUS_BSY)) + fatal("STATE_SCSI_SELECT failed to select target 2\n"); - /*Device should now be selected*/ - if (!wait_for_bus(bus, BUS_CD, 1)) - fatal("Device failed to request command\n"); + /*Device should now be selected*/ + if (!wait_for_bus(bus, BUS_CD, 1)) + fatal("Device failed to request command\n"); - atapi->state = ATAPI_STATE_COMMAND; - atapi->command_pos = 0; + atapi->state = ATAPI_STATE_COMMAND; + atapi->command_pos = 0; } uint8_t atapi_read_iir(atapi_device_t *atapi_dev) { - uint8_t val = 0; - int bus_status = atapi_dev->bus_state;//scsi_bus_read(&atapi_dev->bus); + uint8_t val = 0; + int bus_status = atapi_dev->bus_state; // scsi_bus_read(&atapi_dev->bus); - if (bus_status & BUS_CD) - val |= 1; - if (bus_status & BUS_IO) - val |= 2; + if (bus_status & BUS_CD) + val |= 1; + if (bus_status & BUS_IO) + val |= 2; -// pclog("Read IIR %02X %02x\n", val, bus_status); + // pclog("Read IIR %02X %02x\n", val, bus_status); - return val; + return val; } -uint8_t atapi_read_drq(atapi_device_t *atapi_dev) { - return atapi_dev->bus_state & BUS_REQ; -} +uint8_t atapi_read_drq(atapi_device_t *atapi_dev) { return atapi_dev->bus_state & BUS_REQ; } void atapi_set_transfer_granularity(atapi_device_t *atapi_dev, int size) { - if (atapi_dev->max_transfer_len > size) - atapi_dev->max_transfer_len -= (atapi_dev->max_transfer_len % size); + if (atapi_dev->max_transfer_len > size) + atapi_dev->max_transfer_len -= (atapi_dev->max_transfer_len % size); } void atapi_process_packet(atapi_device_t *atapi_dev) { -// pclog("atapi_process_packet: state=%i\n", atapi_dev->state); - switch (atapi_dev->state) { - case ATAPI_STATE_COMMAND:*atapi_dev->atastat = READY_STAT | (*atapi_dev->atastat & ERR_STAT); - atapi_dev->max_transfer_len = (*atapi_dev->cylinder) & ~1; - if (!atapi_dev->max_transfer_len) - atapi_dev->max_transfer_len = 0xfffe; - atapi_dev->bus_state = BUS_CD | BUS_REQ; - break; + // pclog("atapi_process_packet: state=%i\n", atapi_dev->state); + switch (atapi_dev->state) { + case ATAPI_STATE_COMMAND: + *atapi_dev->atastat = READY_STAT | (*atapi_dev->atastat & ERR_STAT); + atapi_dev->max_transfer_len = (*atapi_dev->cylinder) & ~1; + if (!atapi_dev->max_transfer_len) + atapi_dev->max_transfer_len = 0xfffe; + atapi_dev->bus_state = BUS_CD | BUS_REQ; + break; - case ATAPI_STATE_GOT_COMMAND: { - int pos = 0; - int bus_state; - int c; + case ATAPI_STATE_GOT_COMMAND: { + int pos = 0; + int bus_state; + int c; - for (c = 0; c < 20; c++) { - bus_state = scsi_bus_read(&atapi_dev->bus); + for (c = 0; c < 20; c++) { + bus_state = scsi_bus_read(&atapi_dev->bus); - if (!(bus_state & BUS_BSY)) - fatal("SEND_COMMAND - dropped BSY\n"); - if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) != BUS_CD) - fatal("SEND_COMMAND - bus phase incorrect\n"); - if (bus_state & BUS_REQ) - break; - } - if (c == 20) - fatal("SEND_COMMAND timed out\n"); + if (!(bus_state & BUS_BSY)) + fatal("SEND_COMMAND - dropped BSY\n"); + if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) != BUS_CD) + fatal("SEND_COMMAND - bus phase incorrect\n"); + if (bus_state & BUS_REQ) + break; + } + if (c == 20) + fatal("SEND_COMMAND timed out\n"); - while (1) { - int bus_out; + while (1) { + int bus_out; - for (c = 0; c < 20; c++) { - int bus_state = scsi_bus_read(&atapi_dev->bus); + for (c = 0; c < 20; c++) { + int bus_state = scsi_bus_read(&atapi_dev->bus); - if (!(bus_state & BUS_BSY)) - fatal("SEND_COMMAND - dropped BSY\n"); - if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) != BUS_CD) - break; - if (bus_state & BUS_REQ) - break; - } - if (c == 20) { -// pclog("SEND_COMMAND timed out %x\n", scsi_bus_read(&atapi_dev->bus)); - atapi_dev->state = ATAPI_STATE_NEXT_PHASE; - timer_set_delay_u64(&ide_timer[atapi_dev->board], 6 * IDE_TIME); - break; - } + if (!(bus_state & BUS_BSY)) + fatal("SEND_COMMAND - dropped BSY\n"); + if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) != BUS_CD) + break; + if (bus_state & BUS_REQ) + break; + } + if (c == 20) { + // pclog("SEND_COMMAND timed out %x\n", + // scsi_bus_read(&atapi_dev->bus)); + atapi_dev->state = ATAPI_STATE_NEXT_PHASE; + timer_set_delay_u64(&ide_timer[atapi_dev->board], 6 * IDE_TIME); + break; + } - bus_state = scsi_bus_read(&atapi_dev->bus); + bus_state = scsi_bus_read(&atapi_dev->bus); - if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG | BUS_REQ)) != (BUS_CD | BUS_REQ)) { -// pclog("SEND_COMMAND - bus state changed %x\n", bus_state); - atapi_dev->state = ATAPI_STATE_NEXT_PHASE; - timer_set_delay_u64(&ide_timer[atapi_dev->board], 6 * IDE_TIME); - break; - } + if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG | BUS_REQ)) != (BUS_CD | BUS_REQ)) { + // pclog("SEND_COMMAND - bus state changed %x\n", + // bus_state); + atapi_dev->state = ATAPI_STATE_NEXT_PHASE; + timer_set_delay_u64(&ide_timer[atapi_dev->board], 6 * IDE_TIME); + break; + } - if (pos >= atapi_dev->command_pos) - bus_out = BUS_SETDATA(0); /*Pad out with zeroes*/ - else - bus_out = BUS_SETDATA(atapi_dev->command[pos++]); - scsi_bus_update(&atapi_dev->bus, bus_out | BUS_ACK); - scsi_bus_update(&atapi_dev->bus, bus_out & ~BUS_ACK); + if (pos >= atapi_dev->command_pos) + bus_out = BUS_SETDATA(0); /*Pad out with zeroes*/ + else + bus_out = BUS_SETDATA(atapi_dev->command[pos++]); + scsi_bus_update(&atapi_dev->bus, bus_out | BUS_ACK); + scsi_bus_update(&atapi_dev->bus, bus_out & ~BUS_ACK); - if (!(bus_state & BUS_BSY)) - fatal("SEND_COMMAND - dropped BSY\n"); + if (!(bus_state & BUS_BSY)) + fatal("SEND_COMMAND - dropped BSY\n"); -// if (pos >= atapi_dev->command_pos) -// fatal("Out of data!\n"); - } - } - break; + // if (pos >= atapi_dev->command_pos) + // fatal("Out of data!\n"); + } + } break; - case ATAPI_STATE_NEXT_PHASE: { - int c; + case ATAPI_STATE_NEXT_PHASE: { + int c; - for (c = 0; c < 20; c++) { - int bus_state = scsi_bus_read(&atapi_dev->bus); + for (c = 0; c < 20; c++) { + int bus_state = scsi_bus_read(&atapi_dev->bus); -// if (!c) -// pclog("NEXT_PHASE - %x\n", bus_state); - if (!(bus_state & BUS_BSY)) - fatal("NEXT_PHASE - dropped BSY waiting\n"); + // if (!c) + // pclog("NEXT_PHASE - %x\n", bus_state); + if (!(bus_state & BUS_BSY)) + fatal("NEXT_PHASE - dropped BSY waiting\n"); - if (bus_state & BUS_REQ) { - scsi_device_t *scsi_dev = atapi_dev->bus.devices[0]; - void *scsi_data = atapi_dev->bus.device_data[0]; + if (bus_state & BUS_REQ) { + scsi_device_t *scsi_dev = atapi_dev->bus.devices[0]; + void *scsi_data = atapi_dev->bus.device_data[0]; - switch (bus_state & (BUS_IO | BUS_CD | BUS_MSG)) { - case 0:atapi_dev->data_read_pos = scsi_dev->get_bytes_required(scsi_data); + switch (bus_state & (BUS_IO | BUS_CD | BUS_MSG)) { + case 0: + atapi_dev->data_read_pos = scsi_dev->get_bytes_required(scsi_data); - atapi_dev->data_write_pos = 0; + atapi_dev->data_write_pos = 0; - if (atapi_dev->use_dma) { - if (ide_bus_master_write_data) { - if (ide_bus_master_write_data(atapi_dev->board, atapi_dev->data, atapi_dev->data_read_pos, ide_bus_master_p)) { - atapi_dev->state = ATAPI_STATE_RETRY_WRITE_DMA; - timer_set_delay_u64(&ide_timer[atapi_dev->board], 1 * IDE_TIME); - } else { - atapi_dev->data_write_pos = atapi_dev->data_read_pos; - atapi_dev->bus_state = 0; - atapi_dev->state = ATAPI_STATE_WRITE_DATA; - timer_set_delay_u64(&ide_timer[atapi_dev->board], 6 * IDE_TIME); - } - } else { - atapi_dev->state = ATAPI_STATE_RETRY_WRITE_DMA; - timer_set_delay_u64(&ide_timer[atapi_dev->board], 1 * IDE_TIME); - } - } else { - if (atapi_dev->data_read_pos > atapi_dev->max_transfer_len) - atapi_dev->data_read_pos = atapi_dev->max_transfer_len; + if (atapi_dev->use_dma) { + if (ide_bus_master_write_data) { + if (ide_bus_master_write_data(atapi_dev->board, atapi_dev->data, + atapi_dev->data_read_pos, + ide_bus_master_p)) { + atapi_dev->state = ATAPI_STATE_RETRY_WRITE_DMA; + timer_set_delay_u64(&ide_timer[atapi_dev->board], 1 * IDE_TIME); + } else { + atapi_dev->data_write_pos = atapi_dev->data_read_pos; + atapi_dev->bus_state = 0; + atapi_dev->state = ATAPI_STATE_WRITE_DATA; + timer_set_delay_u64(&ide_timer[atapi_dev->board], 6 * IDE_TIME); + } + } else { + atapi_dev->state = ATAPI_STATE_RETRY_WRITE_DMA; + timer_set_delay_u64(&ide_timer[atapi_dev->board], 1 * IDE_TIME); + } + } else { + if (atapi_dev->data_read_pos > atapi_dev->max_transfer_len) + atapi_dev->data_read_pos = atapi_dev->max_transfer_len; - atapi_dev->state = ATAPI_STATE_WRITE_DATA_WAIT; + atapi_dev->state = ATAPI_STATE_WRITE_DATA_WAIT; - *atapi_dev->cylinder = atapi_dev->data_read_pos; + *atapi_dev->cylinder = atapi_dev->data_read_pos; -// pclog("WRITE_DATA: bytes=%i\n", *atapi_dev->cylinder); - *atapi_dev->atastat = READY_STAT | DRQ_STAT | (*atapi_dev->atastat & ERR_STAT); - atapi_dev->bus_state = BUS_REQ; - ide_irq_raise(atapi_dev->ide); - } - break; + // pclog("WRITE_DATA: + // bytes=%i\n", + // *atapi_dev->cylinder); + *atapi_dev->atastat = READY_STAT | DRQ_STAT | (*atapi_dev->atastat & ERR_STAT); + atapi_dev->bus_state = BUS_REQ; + ide_irq_raise(atapi_dev->ide); + } + break; - case BUS_IO:atapi_dev->state = ATAPI_STATE_READ_DATA; - atapi_dev->data_read_pos = atapi_dev->data_write_pos = 0; - break; + case BUS_IO: + atapi_dev->state = ATAPI_STATE_READ_DATA; + atapi_dev->data_read_pos = atapi_dev->data_write_pos = 0; + break; - case (BUS_IO | BUS_CD):atapi_dev->state = ATAPI_STATE_READ_STATUS; - break; + case (BUS_IO | BUS_CD): + atapi_dev->state = ATAPI_STATE_READ_STATUS; + break; - case (BUS_CD | BUS_IO | BUS_MSG):atapi_dev->state = ATAPI_STATE_READ_MESSAGE; - break; + case (BUS_CD | BUS_IO | BUS_MSG): + atapi_dev->state = ATAPI_STATE_READ_MESSAGE; + break; - default:fatal("NEXT_PHASE - bus state changed %x\n", bus_state); - } - break; - } - } - timer_set_delay_u64(&ide_timer[atapi_dev->board], 6 * IDE_TIME); - } - break; + default: + fatal("NEXT_PHASE - bus state changed %x\n", bus_state); + } + break; + } + } + timer_set_delay_u64(&ide_timer[atapi_dev->board], 6 * IDE_TIME); + } break; - case ATAPI_STATE_READ_STATUS: { - int c; + case ATAPI_STATE_READ_STATUS: { + int c; - for (c = 0; c < 20; c++) { - int bus_state = scsi_bus_read(&atapi_dev->bus); + for (c = 0; c < 20; c++) { + int bus_state = scsi_bus_read(&atapi_dev->bus); - if (!(bus_state & BUS_BSY)) - fatal("READ_STATUS - dropped BSY waiting\n"); + if (!(bus_state & BUS_BSY)) + fatal("READ_STATUS - dropped BSY waiting\n"); - if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) != (BUS_CD | BUS_IO)) - fatal("READ_STATUS - changed phase\n"); + if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) != (BUS_CD | BUS_IO)) + fatal("READ_STATUS - changed phase\n"); - if (bus_state & BUS_REQ) { -// uint8_t status = BUS_GETDATA(bus_state); - int bus_out = 0; + if (bus_state & BUS_REQ) { + // uint8_t status = BUS_GETDATA(bus_state); + int bus_out = 0; -// pclog("Read status %02x\n", status); + // pclog("Read status %02x\n", status); - scsi_bus_update(&atapi_dev->bus, bus_out | BUS_ACK); - scsi_bus_update(&atapi_dev->bus, bus_out & ~BUS_ACK); + scsi_bus_update(&atapi_dev->bus, bus_out | BUS_ACK); + scsi_bus_update(&atapi_dev->bus, bus_out & ~BUS_ACK); - atapi_dev->state = ATAPI_STATE_NEXT_PHASE; - break; - } - } - timer_set_delay_u64(&ide_timer[atapi_dev->board], 6 * IDE_TIME); - } - break; + atapi_dev->state = ATAPI_STATE_NEXT_PHASE; + break; + } + } + timer_set_delay_u64(&ide_timer[atapi_dev->board], 6 * IDE_TIME); + } break; - case ATAPI_STATE_READ_MESSAGE: { - int c; + case ATAPI_STATE_READ_MESSAGE: { + int c; - for (c = 0; c < 20; c++) { - int bus_state = scsi_bus_read(&atapi_dev->bus); + for (c = 0; c < 20; c++) { + int bus_state = scsi_bus_read(&atapi_dev->bus); - if (!(bus_state & BUS_BSY)) - fatal("READ_MESSAGE - dropped BSY waiting\n"); + if (!(bus_state & BUS_BSY)) + fatal("READ_MESSAGE - dropped BSY waiting\n"); - if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) != (BUS_CD | BUS_IO | BUS_MSG)) { -// pclog("READ_MESSAGE - changed phase\n"); - atapi_dev->state = ATAPI_STATE_NEXT_PHASE; - break; - } + if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) != (BUS_CD | BUS_IO | BUS_MSG)) { + // pclog("READ_MESSAGE - changed phase\n"); + atapi_dev->state = ATAPI_STATE_NEXT_PHASE; + break; + } - if (bus_state & BUS_REQ) { - uint8_t msg = BUS_GETDATA(bus_state); - int bus_out = 0; + if (bus_state & BUS_REQ) { + uint8_t msg = BUS_GETDATA(bus_state); + int bus_out = 0; -// pclog("Read message %02x\n", msg); - scsi_bus_update(&atapi_dev->bus, bus_out | BUS_ACK); - scsi_bus_update(&atapi_dev->bus, bus_out & ~BUS_ACK); + // pclog("Read message %02x\n", msg); + scsi_bus_update(&atapi_dev->bus, bus_out | BUS_ACK); + scsi_bus_update(&atapi_dev->bus, bus_out & ~BUS_ACK); - switch (msg) { - case MSG_COMMAND_COMPLETE:atapi_dev->state = ATAPI_STATE_END_PHASE; - break; + switch (msg) { + case MSG_COMMAND_COMPLETE: + atapi_dev->state = ATAPI_STATE_END_PHASE; + break; - default:fatal("READ_MESSAGE - unknown message %02x\n", msg); - } - break; - } - } - timer_set_delay_u64(&ide_timer[atapi_dev->board], 6 * IDE_TIME); - } - break; + default: + fatal("READ_MESSAGE - unknown message %02x\n", msg); + } + break; + } + } + timer_set_delay_u64(&ide_timer[atapi_dev->board], 6 * IDE_TIME); + } break; - case ATAPI_STATE_READ_DATA: { - while (atapi_dev->data_write_pos < atapi_dev->max_transfer_len) { - int c; + case ATAPI_STATE_READ_DATA: { + while (atapi_dev->data_write_pos < atapi_dev->max_transfer_len) { + int c; - for (c = 0; c < 20; c++) { - int bus_state = scsi_bus_read(&atapi_dev->bus); + for (c = 0; c < 20; c++) { + int bus_state = scsi_bus_read(&atapi_dev->bus); - if (!(bus_state & BUS_BSY)) - fatal("READ_DATA - dropped BSY waiting\n"); + if (!(bus_state & BUS_BSY)) + fatal("READ_DATA - dropped BSY waiting\n"); - if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) != BUS_IO) { -// pclog("READ_DATA - changed phase\n"); - break; - } + if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) != BUS_IO) { + // pclog("READ_DATA - changed phase\n"); + break; + } - if (bus_state & BUS_REQ) { - uint8_t data = BUS_GETDATA(bus_state); - int bus_out = 0; + if (bus_state & BUS_REQ) { + uint8_t data = BUS_GETDATA(bus_state); + int bus_out = 0; - atapi_dev->data[atapi_dev->data_write_pos++] = data; + atapi_dev->data[atapi_dev->data_write_pos++] = data; -// pclog("Read data %02x %i\n", data, atapi_dev->data_write_pos); - scsi_bus_update(&atapi_dev->bus, bus_out | BUS_ACK); - scsi_bus_update(&atapi_dev->bus, bus_out & ~BUS_ACK); - break; - } - } - if ((scsi_bus_read(&atapi_dev->bus) & (BUS_IO | BUS_CD | BUS_MSG)) != BUS_IO) - break; - } - if (atapi_dev->use_dma) { - if (ide_bus_master_read_data) { - if (ide_bus_master_read_data(atapi_dev->board, atapi_dev->data, atapi_dev->data_write_pos, ide_bus_master_p)) { - atapi_dev->state = ATAPI_STATE_RETRY_READ_DMA; - timer_set_delay_u64(&ide_timer[atapi_dev->board], 1 * IDE_TIME); - } else { - atapi_dev->state = ATAPI_STATE_NEXT_PHASE; - timer_set_delay_u64(&ide_timer[atapi_dev->board], 1 * IDE_TIME); - } - } else { - atapi_dev->state = ATAPI_STATE_RETRY_READ_DMA; - timer_set_delay_u64(&ide_timer[atapi_dev->board], 1 * IDE_TIME); - } - } else { - atapi_dev->state = ATAPI_STATE_READ_DATA_WAIT; - *atapi_dev->atastat = READY_STAT | DRQ_STAT | (*atapi_dev->atastat & ERR_STAT); - *atapi_dev->cylinder = atapi_dev->data_write_pos; -// pclog("READ_DATA: bytes=%i\n", *atapi_dev->cylinder); - atapi_dev->bus_state = BUS_IO | BUS_REQ; - ide_irq_raise(atapi_dev->ide); - } - } - break; + // pclog("Read data %02x %i\n", data, + // atapi_dev->data_write_pos); + scsi_bus_update(&atapi_dev->bus, bus_out | BUS_ACK); + scsi_bus_update(&atapi_dev->bus, bus_out & ~BUS_ACK); + break; + } + } + if ((scsi_bus_read(&atapi_dev->bus) & (BUS_IO | BUS_CD | BUS_MSG)) != BUS_IO) + break; + } + if (atapi_dev->use_dma) { + if (ide_bus_master_read_data) { + if (ide_bus_master_read_data(atapi_dev->board, atapi_dev->data, atapi_dev->data_write_pos, + ide_bus_master_p)) { + atapi_dev->state = ATAPI_STATE_RETRY_READ_DMA; + timer_set_delay_u64(&ide_timer[atapi_dev->board], 1 * IDE_TIME); + } else { + atapi_dev->state = ATAPI_STATE_NEXT_PHASE; + timer_set_delay_u64(&ide_timer[atapi_dev->board], 1 * IDE_TIME); + } + } else { + atapi_dev->state = ATAPI_STATE_RETRY_READ_DMA; + timer_set_delay_u64(&ide_timer[atapi_dev->board], 1 * IDE_TIME); + } + } else { + atapi_dev->state = ATAPI_STATE_READ_DATA_WAIT; + *atapi_dev->atastat = READY_STAT | DRQ_STAT | (*atapi_dev->atastat & ERR_STAT); + *atapi_dev->cylinder = atapi_dev->data_write_pos; + // pclog("READ_DATA: bytes=%i\n", *atapi_dev->cylinder); + atapi_dev->bus_state = BUS_IO | BUS_REQ; + ide_irq_raise(atapi_dev->ide); + } + } break; - case ATAPI_STATE_WRITE_DATA: { - atapi_dev->data_read_pos = 0; -// pclog("ATAPI_STATE_WRITE_DATA - %i\n", atapi_dev->data_write_pos); - while (atapi_dev->data_read_pos < atapi_dev->data_write_pos) { - int bus_state = scsi_bus_read(&atapi_dev->bus); + case ATAPI_STATE_WRITE_DATA: { + atapi_dev->data_read_pos = 0; + // pclog("ATAPI_STATE_WRITE_DATA - %i\n", atapi_dev->data_write_pos); + while (atapi_dev->data_read_pos < atapi_dev->data_write_pos) { + int bus_state = scsi_bus_read(&atapi_dev->bus); - if (!(bus_state & BUS_BSY)) - fatal("WRITE_DATA - dropped BSY waiting\n"); + if (!(bus_state & BUS_BSY)) + fatal("WRITE_DATA - dropped BSY waiting\n"); - if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) != 0) { -// pclog("WRITE_DATA - changed phase\n"); - atapi_dev->state = ATAPI_STATE_NEXT_PHASE; - break; - } + if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) != 0) { + // pclog("WRITE_DATA - changed phase\n"); + atapi_dev->state = ATAPI_STATE_NEXT_PHASE; + break; + } - if (bus_state & BUS_REQ) { - uint8_t data = atapi_dev->data[atapi_dev->data_read_pos++]; - int bus_out; + if (bus_state & BUS_REQ) { + uint8_t data = atapi_dev->data[atapi_dev->data_read_pos++]; + int bus_out; -// pclog("Write data %02x %i\n", data, atapi_dev->data_read_pos-1); - bus_out = BUS_SETDATA(data); - scsi_bus_update(&atapi_dev->bus, bus_out | BUS_ACK); - scsi_bus_update(&atapi_dev->bus, bus_out & ~BUS_ACK); - } - } + // pclog("Write data %02x %i\n", data, + // atapi_dev->data_read_pos-1); + bus_out = BUS_SETDATA(data); + scsi_bus_update(&atapi_dev->bus, bus_out | BUS_ACK); + scsi_bus_update(&atapi_dev->bus, bus_out & ~BUS_ACK); + } + } - atapi_dev->state = ATAPI_STATE_NEXT_PHASE; - timer_set_delay_u64(&ide_timer[atapi_dev->board], 1 * IDE_TIME); - } - break; + atapi_dev->state = ATAPI_STATE_NEXT_PHASE; + timer_set_delay_u64(&ide_timer[atapi_dev->board], 1 * IDE_TIME); + } break; - case ATAPI_STATE_END_PHASE: { - int c; - /*Wait for SCSI command to move to next phase*/ - for (c = 0; c < 20; c++) { - int bus_state = scsi_bus_read(&atapi_dev->bus); + case ATAPI_STATE_END_PHASE: { + int c; + /*Wait for SCSI command to move to next phase*/ + for (c = 0; c < 20; c++) { + int bus_state = scsi_bus_read(&atapi_dev->bus); - if (!(bus_state & BUS_BSY)) { -// pclog("END_PHASE - dropped BSY waiting\n"); - atapi_dev->state = ATAPI_STATE_IDLE; - break; - } + if (!(bus_state & BUS_BSY)) { + // pclog("END_PHASE - dropped BSY waiting\n"); + atapi_dev->state = ATAPI_STATE_IDLE; + break; + } - if (bus_state & BUS_REQ) - fatal("END_PHASE - unexpected REQ\n"); - } - if (atapi_dev->state == ATAPI_STATE_IDLE) { - scsi_device_t *scsi_dev = atapi_dev->bus.devices[0]; - void *scsi_data = atapi_dev->bus.device_data[0]; + if (bus_state & BUS_REQ) + fatal("END_PHASE - unexpected REQ\n"); + } + if (atapi_dev->state == ATAPI_STATE_IDLE) { + scsi_device_t *scsi_dev = atapi_dev->bus.devices[0]; + void *scsi_data = atapi_dev->bus.device_data[0]; - *atapi_dev->atastat = READY_STAT; - atapi_dev->bus_state = BUS_IO | BUS_CD; - if (scsi_dev->get_status(scsi_data) != STATUS_GOOD) { - *atapi_dev->error = (scsi_dev->get_sense_key(scsi_data) << 4) | ABRT_ERR; - if (scsi_dev->get_sense_key(scsi_data) == KEY_UNIT_ATTENTION) - *atapi_dev->error |= MCR_ERR; - *atapi_dev->atastat |= ERR_STAT; - } - ide_irq_raise(atapi_dev->ide); - } else - timer_set_delay_u64(&ide_timer[atapi_dev->board], 6 * IDE_TIME); - } - break; + *atapi_dev->atastat = READY_STAT; + atapi_dev->bus_state = BUS_IO | BUS_CD; + if (scsi_dev->get_status(scsi_data) != STATUS_GOOD) { + *atapi_dev->error = (scsi_dev->get_sense_key(scsi_data) << 4) | ABRT_ERR; + if (scsi_dev->get_sense_key(scsi_data) == KEY_UNIT_ATTENTION) + *atapi_dev->error |= MCR_ERR; + *atapi_dev->atastat |= ERR_STAT; + } + ide_irq_raise(atapi_dev->ide); + } else + timer_set_delay_u64(&ide_timer[atapi_dev->board], 6 * IDE_TIME); + } break; - case ATAPI_STATE_RETRY_READ_DMA: { - if (ide_bus_master_read_data(atapi_dev->board, atapi_dev->data, atapi_dev->data_write_pos, ide_bus_master_p)) { - timer_set_delay_u64(&ide_timer[atapi_dev->board], 1 * IDE_TIME); - } else { - atapi_dev->state = ATAPI_STATE_NEXT_PHASE; - timer_set_delay_u64(&ide_timer[atapi_dev->board], 6 * IDE_TIME); - } - } - break; + case ATAPI_STATE_RETRY_READ_DMA: { + if (ide_bus_master_read_data(atapi_dev->board, atapi_dev->data, atapi_dev->data_write_pos, ide_bus_master_p)) { + timer_set_delay_u64(&ide_timer[atapi_dev->board], 1 * IDE_TIME); + } else { + atapi_dev->state = ATAPI_STATE_NEXT_PHASE; + timer_set_delay_u64(&ide_timer[atapi_dev->board], 6 * IDE_TIME); + } + } break; - case ATAPI_STATE_RETRY_WRITE_DMA: { - if (ide_bus_master_write_data(atapi_dev->board, atapi_dev->data, atapi_dev->data_read_pos, ide_bus_master_p)) { - timer_set_delay_u64(&ide_timer[atapi_dev->board], 1 * IDE_TIME); - } else { - atapi_dev->bus_state = 0; - atapi_dev->state = ATAPI_STATE_WRITE_DATA; - timer_set_delay_u64(&ide_timer[atapi_dev->board], 6 * IDE_TIME); - } - } - break; - } + case ATAPI_STATE_RETRY_WRITE_DMA: { + if (ide_bus_master_write_data(atapi_dev->board, atapi_dev->data, atapi_dev->data_read_pos, ide_bus_master_p)) { + timer_set_delay_u64(&ide_timer[atapi_dev->board], 1 * IDE_TIME); + } else { + atapi_dev->bus_state = 0; + atapi_dev->state = ATAPI_STATE_WRITE_DATA; + timer_set_delay_u64(&ide_timer[atapi_dev->board], 6 * IDE_TIME); + } + } break; + } } void atapi_reset(atapi_device_t *atapi_dev) { - pclog("atapi_reset\n"); - atapi_dev->state = ATAPI_STATE_IDLE; - atapi_dev->command_pos = 0; - atapi_dev->data_read_pos = 0; - atapi_dev->data_write_pos = 0; - scsi_bus_reset(&atapi_dev->bus); + pclog("atapi_reset\n"); + atapi_dev->state = ATAPI_STATE_IDLE; + atapi_dev->command_pos = 0; + atapi_dev->data_read_pos = 0; + atapi_dev->data_write_pos = 0; + scsi_bus_reset(&atapi_dev->bus); } diff --git a/src/ide/ide_sff8038i.c b/src/ide/ide_sff8038i.c index 1b215d06..f5587830 100644 --- a/src/ide/ide_sff8038i.c +++ b/src/ide/ide_sff8038i.c @@ -6,177 +6,184 @@ #include "mem.h" static void sff_bus_master_next_addr(sff_busmaster_t *busmaster, int channel) { - busmaster[channel].addr = (*(uint32_t *)(&ram[busmaster[channel].ptr_cur])) & ~1; - busmaster[channel].count = (*(uint32_t *)(&ram[busmaster[channel].ptr_cur + 4])) & 0xfffe; - if (!busmaster[channel].count) - busmaster[channel].count = 0x10000; - busmaster[channel].eot = (*(uint32_t *)(&ram[busmaster[channel].ptr_cur + 4])) >> 31; - busmaster[channel].ptr_cur += 8; -// pclog("New DMA settings on channel %i - Addr %08X Count %04X EOT %i\n", channel, piix_busmaster[channel].addr, piix_busmaster[channel].count, piix_busmaster[channel].eot); + busmaster[channel].addr = (*(uint32_t *)(&ram[busmaster[channel].ptr_cur])) & ~1; + busmaster[channel].count = (*(uint32_t *)(&ram[busmaster[channel].ptr_cur + 4])) & 0xfffe; + if (!busmaster[channel].count) + busmaster[channel].count = 0x10000; + busmaster[channel].eot = (*(uint32_t *)(&ram[busmaster[channel].ptr_cur + 4])) >> 31; + busmaster[channel].ptr_cur += 8; + // pclog("New DMA settings on channel %i - Addr %08X Count %04X EOT %i\n", channel, piix_busmaster[channel].addr, + // piix_busmaster[channel].count, piix_busmaster[channel].eot); } void sff_bus_master_write(uint16_t port, uint8_t val, void *p) { - sff_busmaster_t *busmaster = (sff_busmaster_t *)p; - int channel = (port & 8) ? 1 : 0; -// pclog("PIIX Bus Master write %04X %02X %04x:%08x\n", port, val, CS, pc); - switch (port & 7) { - case 0: - if ((val & 1) && !(busmaster[channel].command & 1)) /*Start*/ - { - busmaster[channel].ptr_cur = busmaster[channel].ptr; - sff_bus_master_next_addr(busmaster, channel); - busmaster[channel].status |= 1; - } - if (!(val & 1) && (busmaster[channel].command & 1)) /*Stop*/ - busmaster[channel].status &= ~1; + sff_busmaster_t *busmaster = (sff_busmaster_t *)p; + int channel = (port & 8) ? 1 : 0; + // pclog("PIIX Bus Master write %04X %02X %04x:%08x\n", port, val, CS, pc); + switch (port & 7) { + case 0: + if ((val & 1) && !(busmaster[channel].command & 1)) /*Start*/ + { + busmaster[channel].ptr_cur = busmaster[channel].ptr; + sff_bus_master_next_addr(busmaster, channel); + busmaster[channel].status |= 1; + } + if (!(val & 1) && (busmaster[channel].command & 1)) /*Stop*/ + busmaster[channel].status &= ~1; - busmaster[channel].command = val; - break; - case 2:busmaster[channel].status = (val & 0x60) | ((busmaster[channel].status & ~val) & 6) | (busmaster[channel].status & 1); - break; - case 4:busmaster[channel].ptr = (busmaster[channel].ptr & 0xffffff00) | val; - break; - case 5:busmaster[channel].ptr = (busmaster[channel].ptr & 0xffff00ff) | (val << 8); - break; - case 6:busmaster[channel].ptr = (busmaster[channel].ptr & 0xff00ffff) | (val << 16); - break; - case 7:busmaster[channel].ptr = (busmaster[channel].ptr & 0x00ffffff) | (val << 24); - break; - } + busmaster[channel].command = val; + break; + case 2: + busmaster[channel].status = + (val & 0x60) | ((busmaster[channel].status & ~val) & 6) | (busmaster[channel].status & 1); + break; + case 4: + busmaster[channel].ptr = (busmaster[channel].ptr & 0xffffff00) | val; + break; + case 5: + busmaster[channel].ptr = (busmaster[channel].ptr & 0xffff00ff) | (val << 8); + break; + case 6: + busmaster[channel].ptr = (busmaster[channel].ptr & 0xff00ffff) | (val << 16); + break; + case 7: + busmaster[channel].ptr = (busmaster[channel].ptr & 0x00ffffff) | (val << 24); + break; + } } uint8_t sff_bus_master_read(uint16_t port, void *p) { - sff_busmaster_t *busmaster = (sff_busmaster_t *)p; - int channel = (port & 8) ? 1 : 0; -// pclog("PIIX Bus Master read %04X %04x:%08x\n", port, CS, pc); - switch (port & 7) { - case 0:return busmaster[channel].command; - case 2:return busmaster[channel].status; - case 4:return busmaster[channel].ptr; - case 5:return busmaster[channel].ptr >> 8; - case 6:return busmaster[channel].ptr >> 16; - case 7:return busmaster[channel].ptr >> 24; - } - return 0xff; + sff_busmaster_t *busmaster = (sff_busmaster_t *)p; + int channel = (port & 8) ? 1 : 0; + // pclog("PIIX Bus Master read %04X %04x:%08x\n", port, CS, pc); + switch (port & 7) { + case 0: + return busmaster[channel].command; + case 2: + return busmaster[channel].status; + case 4: + return busmaster[channel].ptr; + case 5: + return busmaster[channel].ptr >> 8; + case 6: + return busmaster[channel].ptr >> 16; + case 7: + return busmaster[channel].ptr >> 24; + } + return 0xff; } static int sff_bus_master_data_read(int channel, uint8_t *data, int size, void *p) { - sff_busmaster_t *busmaster = (sff_busmaster_t *)p; - int transferred = 0; + sff_busmaster_t *busmaster = (sff_busmaster_t *)p; + int transferred = 0; - if (!(busmaster[channel].status & 1)) - return 1; /*DMA disabled*/ + if (!(busmaster[channel].status & 1)) + return 1; /*DMA disabled*/ - while (transferred < size) { - if (busmaster[channel].count < (size - transferred) && busmaster[channel].eot) - fatal("DMA on channel %i - Read count less than size! Addr %08X Count %04X EOT %i size %i\n", - channel, - busmaster[channel].addr, - busmaster[channel].count, - busmaster[channel].eot, - size); + while (transferred < size) { + if (busmaster[channel].count < (size - transferred) && busmaster[channel].eot) + fatal("DMA on channel %i - Read count less than size! Addr %08X Count %04X EOT %i size %i\n", channel, + busmaster[channel].addr, busmaster[channel].count, busmaster[channel].eot, size); - mem_invalidate_range(busmaster[channel].addr, busmaster[channel].addr + (size - 1)); + mem_invalidate_range(busmaster[channel].addr, busmaster[channel].addr + (size - 1)); - if (busmaster[channel].count < (size - transferred)) { -// pclog("Transferring smaller - %i bytes\n", piix_busmaster[channel].count); - if (busmaster[channel].addr < (mem_size * 1024)) { - int count = busmaster[channel].count; - if ((busmaster[channel].addr + count) > (mem_size * 1024)) - count = (mem_size * 1024) - busmaster[channel].addr; - memcpy(&ram[busmaster[channel].addr], data + transferred, count); - } - transferred += busmaster[channel].count; - busmaster[channel].addr += busmaster[channel].count; - busmaster[channel].count = 0; - } else { -// pclog("Transferring larger - %i bytes\n", size - transferred); - if (busmaster[channel].addr < (mem_size * 1024)) { - int count = size - transferred; - if ((busmaster[channel].addr + count) > (mem_size * 1024)) - count = (mem_size * 1024) - busmaster[channel].addr; - memcpy(&ram[busmaster[channel].addr], data + transferred, count); - } - busmaster[channel].addr += (size - transferred); - busmaster[channel].count -= (size - transferred); - transferred += (size - transferred); - } + if (busmaster[channel].count < (size - transferred)) { + // pclog("Transferring smaller - %i bytes\n", piix_busmaster[channel].count); + if (busmaster[channel].addr < (mem_size * 1024)) { + int count = busmaster[channel].count; + if ((busmaster[channel].addr + count) > (mem_size * 1024)) + count = (mem_size * 1024) - busmaster[channel].addr; + memcpy(&ram[busmaster[channel].addr], data + transferred, count); + } + transferred += busmaster[channel].count; + busmaster[channel].addr += busmaster[channel].count; + busmaster[channel].count = 0; + } else { + // pclog("Transferring larger - %i bytes\n", size - transferred); + if (busmaster[channel].addr < (mem_size * 1024)) { + int count = size - transferred; + if ((busmaster[channel].addr + count) > (mem_size * 1024)) + count = (mem_size * 1024) - busmaster[channel].addr; + memcpy(&ram[busmaster[channel].addr], data + transferred, count); + } + busmaster[channel].addr += (size - transferred); + busmaster[channel].count -= (size - transferred); + transferred += (size - transferred); + } -// pclog("DMA on channel %i - Addr %08X Count %04X EOT %i\n", channel, piix_busmaster[channel].addr, piix_busmaster[channel].count, piix_busmaster[channel].eot); + // pclog("DMA on channel %i - Addr %08X Count %04X EOT %i\n", channel, + // piix_busmaster[channel].addr, piix_busmaster[channel].count, piix_busmaster[channel].eot); - if (!busmaster[channel].count) { -// pclog("DMA on channel %i - block over\n", channel); - if (busmaster[channel].eot) /*End of transfer?*/ - { -// pclog("DMA on channel %i - transfer over\n", channel); - busmaster[channel].status &= ~1; - } else - sff_bus_master_next_addr(busmaster, channel); - } - } - return 0; + if (!busmaster[channel].count) { + // pclog("DMA on channel %i - block over\n", channel); + if (busmaster[channel].eot) /*End of transfer?*/ + { + // pclog("DMA on channel %i - transfer over\n", channel); + busmaster[channel].status &= ~1; + } else + sff_bus_master_next_addr(busmaster, channel); + } + } + return 0; } static int sff_bus_master_data_write(int channel, uint8_t *data, int size, void *p) { - sff_busmaster_t *busmaster = (sff_busmaster_t *)p; - int transferred = 0; + sff_busmaster_t *busmaster = (sff_busmaster_t *)p; + int transferred = 0; - if (!(busmaster[channel].status & 1)) - return 1; /*DMA disabled*/ + if (!(busmaster[channel].status & 1)) + return 1; /*DMA disabled*/ - while (transferred < size) { - if (busmaster[channel].count < (size - transferred) && busmaster[channel].eot) - fatal("DMA on channel %i - Write count less than size! Addr %08X Count %04X EOT %i size %i\n", - channel, - busmaster[channel].addr, - busmaster[channel].count, - busmaster[channel].eot, - size); + while (transferred < size) { + if (busmaster[channel].count < (size - transferred) && busmaster[channel].eot) + fatal("DMA on channel %i - Write count less than size! Addr %08X Count %04X EOT %i size %i\n", channel, + busmaster[channel].addr, busmaster[channel].count, busmaster[channel].eot, size); - if (busmaster[channel].count < (size - transferred)) { -// pclog("Transferring smaller - %i bytes\n", piix_busmaster[channel].count); - if (busmaster[channel].addr < (mem_size * 1024)) { - int count = busmaster[channel].count; - if ((busmaster[channel].addr + count) > (mem_size * 1024)) - count = (mem_size * 1024) - busmaster[channel].addr; - memcpy(data + transferred, &ram[busmaster[channel].addr], count); - } - transferred += busmaster[channel].count; - busmaster[channel].addr += busmaster[channel].count; - busmaster[channel].count = 0; - } else { -// pclog("Transferring larger - %i bytes\n", size - transferred); - if (busmaster[channel].addr < (mem_size * 1024)) { - int count = size - transferred; - if ((busmaster[channel].addr + count) > (mem_size * 1024)) - count = (mem_size * 1024) - busmaster[channel].addr; - memcpy(data + transferred, &ram[busmaster[channel].addr], count); - } - busmaster[channel].addr += (size - transferred); - busmaster[channel].count -= (size - transferred); - transferred += (size - transferred); - } + if (busmaster[channel].count < (size - transferred)) { + // pclog("Transferring smaller - %i bytes\n", piix_busmaster[channel].count); + if (busmaster[channel].addr < (mem_size * 1024)) { + int count = busmaster[channel].count; + if ((busmaster[channel].addr + count) > (mem_size * 1024)) + count = (mem_size * 1024) - busmaster[channel].addr; + memcpy(data + transferred, &ram[busmaster[channel].addr], count); + } + transferred += busmaster[channel].count; + busmaster[channel].addr += busmaster[channel].count; + busmaster[channel].count = 0; + } else { + // pclog("Transferring larger - %i bytes\n", size - transferred); + if (busmaster[channel].addr < (mem_size * 1024)) { + int count = size - transferred; + if ((busmaster[channel].addr + count) > (mem_size * 1024)) + count = (mem_size * 1024) - busmaster[channel].addr; + memcpy(data + transferred, &ram[busmaster[channel].addr], count); + } + busmaster[channel].addr += (size - transferred); + busmaster[channel].count -= (size - transferred); + transferred += (size - transferred); + } -// pclog("DMA on channel %i - Addr %08X Count %04X EOT %i\n", channel, piix_busmaster[channel].addr, piix_busmaster[channel].count, piix_busmaster[channel].eot); + // pclog("DMA on channel %i - Addr %08X Count %04X EOT %i\n", channel, + // piix_busmaster[channel].addr, piix_busmaster[channel].count, piix_busmaster[channel].eot); - if (!busmaster[channel].count) { -// pclog("DMA on channel %i - block over\n", channel); - if (busmaster[channel].eot) /*End of transfer?*/ - { -// pclog("DMA on channel %i - transfer over\n", channel); - busmaster[channel].status &= ~1; - } else - sff_bus_master_next_addr(busmaster, channel); - } - } - return 0; + if (!busmaster[channel].count) { + // pclog("DMA on channel %i - block over\n", channel); + if (busmaster[channel].eot) /*End of transfer?*/ + { + // pclog("DMA on channel %i - transfer over\n", channel); + busmaster[channel].status &= ~1; + } else + sff_bus_master_next_addr(busmaster, channel); + } + } + return 0; } static void sff_bus_master_set_irq(int channel, void *p) { - sff_busmaster_t *busmaster = (sff_busmaster_t *)p; + sff_busmaster_t *busmaster = (sff_busmaster_t *)p; - busmaster[channel].status |= 4; + busmaster[channel].status |= 4; } void sff_bus_master_init(sff_busmaster_t *busmaster) { - ide_set_bus_master(sff_bus_master_data_read, sff_bus_master_data_write, sff_bus_master_set_irq, busmaster); + ide_set_bus_master(sff_bus_master_data_read, sff_bus_master_data_write, sff_bus_master_set_irq, busmaster); } diff --git a/src/ide/xtide.c b/src/ide/xtide.c index 4f9055f6..280534ae 100644 --- a/src/ide/xtide.c +++ b/src/ide/xtide.c @@ -9,143 +9,113 @@ #include "xtide.h" typedef struct xtide_t { - uint8_t data_high; - rom_t bios_rom; + uint8_t data_high; + rom_t bios_rom; } xtide_t; static void xtide_write(uint16_t port, uint8_t val, void *p) { - xtide_t *xtide = (xtide_t *)p; + xtide_t *xtide = (xtide_t *)p; - switch (port & 0xf) { - case 0x0:writeidew(0, val | (xtide->data_high << 8)); - return; + switch (port & 0xf) { + case 0x0: + writeidew(0, val | (xtide->data_high << 8)); + return; - case 0x1: - case 0x2: - case 0x3: - case 0x4: - case 0x5: - case 0x6: - case 0x7:writeide(0, (port & 0xf) | 0x1f0, val); - return; + case 0x1: + case 0x2: + case 0x3: + case 0x4: + case 0x5: + case 0x6: + case 0x7: + writeide(0, (port & 0xf) | 0x1f0, val); + return; - case 0x8:xtide->data_high = val; - return; + case 0x8: + xtide->data_high = val; + return; - case 0xe:writeide(0, 0x3f6, val); - return; - } + case 0xe: + writeide(0, 0x3f6, val); + return; + } } static uint8_t xtide_read(uint16_t port, void *p) { - xtide_t *xtide = (xtide_t *)p; - uint16_t tempw; + xtide_t *xtide = (xtide_t *)p; + uint16_t tempw; - switch (port & 0xf) { - case 0x0:tempw = readidew(0); - xtide->data_high = tempw >> 8; - return tempw & 0xff; + switch (port & 0xf) { + case 0x0: + tempw = readidew(0); + xtide->data_high = tempw >> 8; + return tempw & 0xff; - case 0x1: - case 0x2: - case 0x3: - case 0x4: - case 0x5: - case 0x6: - case 0x7:return readide(0, (port & 0xf) | 0x1f0); + case 0x1: + case 0x2: + case 0x3: + case 0x4: + case 0x5: + case 0x6: + case 0x7: + return readide(0, (port & 0xf) | 0x1f0); - case 0x8:return xtide->data_high; + case 0x8: + return xtide->data_high; - case 0xe:return readide(0, 0x3f6); - } + case 0xe: + return readide(0, 0x3f6); + } - return 0xff; + return 0xff; } static void *xtide_init() { - xtide_t *xtide = malloc(sizeof(xtide_t)); - memset(xtide, 0, sizeof(xtide_t)); + xtide_t *xtide = malloc(sizeof(xtide_t)); + memset(xtide, 0, sizeof(xtide_t)); - rom_init(&xtide->bios_rom, "ide_xt.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); - device_add(&ide_device); - ide_pri_disable(); - ide_sec_disable(); - io_sethandler(0x0300, 0x0010, xtide_read, NULL, NULL, xtide_write, NULL, NULL, xtide); + rom_init(&xtide->bios_rom, "ide_xt.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + device_add(&ide_device); + ide_pri_disable(); + ide_sec_disable(); + io_sethandler(0x0300, 0x0010, xtide_read, NULL, NULL, xtide_write, NULL, NULL, xtide); - return xtide; + return xtide; } static void *xtide_at_init() { - xtide_t *xtide = malloc(sizeof(xtide_t)); - memset(xtide, 0, sizeof(xtide_t)); + xtide_t *xtide = malloc(sizeof(xtide_t)); + memset(xtide, 0, sizeof(xtide_t)); - rom_init(&xtide->bios_rom, "ide_at.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); - device_add(&ide_device); + rom_init(&xtide->bios_rom, "ide_at.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + device_add(&ide_device); - return xtide; + return xtide; } static void *xtide_ps1_init() { - xtide_t *xtide = malloc(sizeof(xtide_t)); - memset(xtide, 0, sizeof(xtide_t)); + xtide_t *xtide = malloc(sizeof(xtide_t)); + memset(xtide, 0, sizeof(xtide_t)); - rom_init(&xtide->bios_rom, "ide_at_1_1_5.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); - device_add(&ide_device); + rom_init(&xtide->bios_rom, "ide_at_1_1_5.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + device_add(&ide_device); - return xtide; + return xtide; } static void xtide_close(void *p) { - xtide_t *xtide = (xtide_t *)p; + xtide_t *xtide = (xtide_t *)p; - free(xtide); + free(xtide); } -static int xtide_available() { - return rom_present("ide_xt.bin"); -} +static int xtide_available() { return rom_present("ide_xt.bin"); } -static int xtide_at_available() { - return rom_present("ide_at.bin"); -} +static int xtide_at_available() { return rom_present("ide_at.bin"); } -static int xtide_ps1_available() { - return rom_present("ide_at_1_1_5.bin"); -} +static int xtide_ps1_available() { return rom_present("ide_at_1_1_5.bin"); } -device_t xtide_device = - { - "XTIDE", - 0, - xtide_init, - xtide_close, - xtide_available, - NULL, - NULL, - NULL, - NULL - }; -device_t xtide_at_device = - { - "XTIDE (AT)", - DEVICE_AT, - xtide_at_init, - xtide_close, - xtide_at_available, - NULL, - NULL, - NULL, - NULL - }; -device_t xtide_ps1_device = - { - "XTIDE (PS/1)", - DEVICE_PS1, - xtide_ps1_init, - xtide_close, - xtide_ps1_available, - NULL, - NULL, - NULL, - NULL - }; +device_t xtide_device = {"XTIDE", 0, xtide_init, xtide_close, xtide_available, NULL, NULL, NULL, NULL}; +device_t xtide_at_device = {"XTIDE (AT)", DEVICE_AT, xtide_at_init, xtide_close, xtide_at_available, NULL, NULL, NULL, NULL}; +device_t xtide_ps1_device = {"XTIDE (PS/1)", DEVICE_PS1, xtide_ps1_init, xtide_close, xtide_ps1_available, + NULL, NULL, NULL, NULL}; diff --git a/src/io.c b/src/io.c index 953b239d..02a992dc 100644 --- a/src/io.c +++ b/src/io.c @@ -16,91 +16,83 @@ void (*port_outl[0x10000][2])(uint16_t addr, uint32_t val, void *priv); void *port_priv[0x10000][2]; void io_init() { - int c; - pclog("io_init\n"); - for (c = 0; c < 0x10000; c++) { - port_inb[c][0] = NULL; - port_inw[c][0] = NULL; - port_inl[c][0] = NULL; - port_outb[c][0] = NULL; - port_outw[c][0] = NULL; - port_outl[c][0] = NULL; - port_inb[c][1] = NULL; - port_inw[c][1] = NULL; - port_inl[c][1] = NULL; - port_outb[c][1] = NULL; - port_outw[c][1] = NULL; - port_outl[c][1] = NULL; - port_priv[c][0] = NULL; - port_priv[c][1] = NULL; - } + int c; + pclog("io_init\n"); + for (c = 0; c < 0x10000; c++) { + port_inb[c][0] = NULL; + port_inw[c][0] = NULL; + port_inl[c][0] = NULL; + port_outb[c][0] = NULL; + port_outw[c][0] = NULL; + port_outl[c][0] = NULL; + port_inb[c][1] = NULL; + port_inw[c][1] = NULL; + port_inl[c][1] = NULL; + port_outb[c][1] = NULL; + port_outw[c][1] = NULL; + port_outl[c][1] = NULL; + port_priv[c][0] = NULL; + port_priv[c][1] = NULL; + } } -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; - for (c = 0; c < size; c++) { - if (!port_inb[base + c][0] && !port_inw[base + c][0] && !port_inl[base + c][0] && - !port_outb[base + c][0] && !port_outw[base + c][0] && !port_outl[base + c][0]) { - port_inb[base + c][0] = inb; - port_inw[base + c][0] = inw; - port_inl[base + c][0] = inl; - port_outb[base + c][0] = outb; - port_outw[base + c][0] = outw; - port_outl[base + c][0] = outl; - port_priv[base + c][0] = priv; - } else if (!port_inb[base + c][1] && !port_inw[base + c][1] && !port_inl[base + c][1] && - !port_outb[base + c][1] && !port_outw[base + c][1] && !port_outl[base + c][1]) { - port_inb[base + c][1] = inb; - port_inw[base + c][1] = inw; - port_inl[base + c][1] = inl; - port_outb[base + c][1] = outb; - port_outw[base + c][1] = outw; - port_outl[base + c][1] = outl; - port_priv[base + c][1] = priv; - } - } +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; + for (c = 0; c < size; c++) { + if (!port_inb[base + c][0] && !port_inw[base + c][0] && !port_inl[base + c][0] && !port_outb[base + c][0] && + !port_outw[base + c][0] && !port_outl[base + c][0]) { + port_inb[base + c][0] = inb; + port_inw[base + c][0] = inw; + port_inl[base + c][0] = inl; + port_outb[base + c][0] = outb; + port_outw[base + c][0] = outw; + port_outl[base + c][0] = outl; + port_priv[base + c][0] = priv; + } else if (!port_inb[base + c][1] && !port_inw[base + c][1] && !port_inl[base + c][1] && + !port_outb[base + c][1] && !port_outw[base + c][1] && !port_outl[base + c][1]) { + port_inb[base + c][1] = inb; + port_inw[base + c][1] = inw; + port_inl[base + c][1] = inl; + port_outb[base + c][1] = outb; + port_outw[base + c][1] = outw; + port_outl[base + c][1] = outl; + port_priv[base + c][1] = priv; + } + } } -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; - for (c = 0; c < size; c++) { - if (port_priv[base + c][0] == priv && - port_inb[base + c][0] == inb && port_inw[base + c][0] == inw && port_inl[base + c][0] == inl && - port_outb[base + c][0] == outb && port_outw[base + c][0] == outw && port_outl[base + c][0] == outl) { - port_inb[base + c][0] = NULL; - port_inw[base + c][0] = NULL; - port_inl[base + c][0] = NULL; - port_outb[base + c][0] = NULL; - port_outw[base + c][0] = NULL; - port_outl[base + c][0] = NULL; - port_priv[base + c][0] = NULL; - } - if (port_priv[base + c][1] == priv && - port_inb[base + c][1] == inb && port_inw[base + c][1] == inw && port_inl[base + c][1] == inl && - port_outb[base + c][1] == outb && port_outw[base + c][1] == outw && port_outl[base + c][1] == outl) { - port_inb[base + c][1] = NULL; - port_inw[base + c][1] = NULL; - port_inl[base + c][1] = NULL; - port_outb[base + c][1] = NULL; - port_outw[base + c][1] = NULL; - port_outl[base + c][1] = NULL; - port_priv[base + c][1] = NULL; - } - } +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; + for (c = 0; c < size; c++) { + if (port_priv[base + c][0] == priv && port_inb[base + c][0] == inb && port_inw[base + c][0] == inw && + port_inl[base + c][0] == inl && port_outb[base + c][0] == outb && port_outw[base + c][0] == outw && + port_outl[base + c][0] == outl) { + port_inb[base + c][0] = NULL; + port_inw[base + c][0] = NULL; + port_inl[base + c][0] = NULL; + port_outb[base + c][0] = NULL; + port_outw[base + c][0] = NULL; + port_outl[base + c][0] = NULL; + port_priv[base + c][0] = NULL; + } + if (port_priv[base + c][1] == priv && port_inb[base + c][1] == inb && port_inw[base + c][1] == inw && + port_inl[base + c][1] == inl && port_outb[base + c][1] == outb && port_outw[base + c][1] == outw && + port_outl[base + c][1] == outl) { + port_inb[base + c][1] = NULL; + port_inw[base + c][1] = NULL; + port_inl[base + c][1] = NULL; + port_outb[base + c][1] = NULL; + port_outw[base + c][1] = NULL; + port_outl[base + c][1] = NULL; + port_priv[base + c][1] = NULL; + } + } } uint8_t cgamode, cgastat = 0, cgacol; @@ -109,90 +101,88 @@ uint8_t lpt2dat; int sw9; int t237 = 0; uint8_t inb(uint16_t port) { - uint8_t temp = 0xff; + uint8_t temp = 0xff; - if (port_inb[port][0]) - temp &= port_inb[port][0](port, port_priv[port][0]); - if (port_inb[port][1]) - temp &= port_inb[port][1](port, port_priv[port][1]); + if (port_inb[port][0]) + temp &= port_inb[port][0](port, port_priv[port][0]); + if (port_inb[port][1]) + temp &= port_inb[port][1](port, port_priv[port][1]); - if (port & 0x80) - amstrad_latch = AMSTRAD_NOLATCH; - else if (port & 0x4000) - amstrad_latch = AMSTRAD_SW10; - else - amstrad_latch = AMSTRAD_SW9; + if (port & 0x80) + amstrad_latch = AMSTRAD_NOLATCH; + else if (port & 0x4000) + amstrad_latch = AMSTRAD_SW10; + else + amstrad_latch = AMSTRAD_SW9; -/* if (!port_inb[port][0] && !port_inb[port][1]) - pclog("Bad INB %04X %04X:%04X\n", port, CS, pc);*/ + /* if (!port_inb[port][0] && !port_inb[port][1]) + pclog("Bad INB %04X %04X:%04X\n", port, CS, pc);*/ - return temp; + return temp; } -uint8_t cpu_readport(uint32_t port) { - return inb(port); -} +uint8_t cpu_readport(uint32_t port) { return inb(port); } void outb(uint16_t port, uint8_t val) { - if (port_outb[port][0]) - port_outb[port][0](port, val, port_priv[port][0]); - if (port_outb[port][1]) - port_outb[port][1](port, val, port_priv[port][1]); + if (port_outb[port][0]) + port_outb[port][0](port, val, port_priv[port][0]); + if (port_outb[port][1]) + port_outb[port][1](port, val, port_priv[port][1]); -/* if (!port_outb[port][0] && !port_outb[port][1]) - pclog("Bad OUTB %04X %02X %04X:%08X\n", port, val, CS, pc);*/ - return; + /* if (!port_outb[port][0] && !port_outb[port][1]) + pclog("Bad OUTB %04X %02X %04X:%08X\n", port, val, CS, pc);*/ + return; } uint16_t inw(uint16_t port) { -// pclog("INW %04X\n", port); - if (port_inw[port][0]) - return port_inw[port][0](port, port_priv[port][0]); - if (port_inw[port][1]) - return port_inw[port][1](port, port_priv[port][1]); + // pclog("INW %04X\n", port); + if (port_inw[port][0]) + return port_inw[port][0](port, port_priv[port][0]); + if (port_inw[port][1]) + return port_inw[port][1](port, port_priv[port][1]); - return inb(port) | (inb(port + 1) << 8); + return inb(port) | (inb(port + 1) << 8); } void outw(uint16_t port, uint16_t val) { -// printf("OUTW %04X %04X %04X:%08X\n",port,val, CS, pc); -/* if ((port & ~0xf) == 0xf000) - pclog("OUTW %04X %04X\n", port, val);*/ + // printf("OUTW %04X %04X %04X:%08X\n",port,val, CS, pc); + /* if ((port & ~0xf) == 0xf000) + pclog("OUTW %04X %04X\n", port, val);*/ - if (port_outw[port][0]) - port_outw[port][0](port, val, port_priv[port][0]); - if (port_outw[port][1]) - port_outw[port][1](port, val, port_priv[port][1]); + if (port_outw[port][0]) + port_outw[port][0](port, val, port_priv[port][0]); + if (port_outw[port][1]) + port_outw[port][1](port, val, port_priv[port][1]); - if (port_outw[port][0] || port_outw[port][1]) - return; + if (port_outw[port][0] || port_outw[port][1]) + return; - outb(port, val); - outb(port + 1, val >> 8); + outb(port, val); + outb(port + 1, val >> 8); } uint32_t inl(uint16_t port) { -// pclog("INL %04X\n", port); - if (port_inl[port][0]) - return port_inl[port][0](port, port_priv[port][0]); - if (port_inl[port][1]) - return port_inl[port][1](port, port_priv[port][1]); + // pclog("INL %04X\n", port); + if (port_inl[port][0]) + return port_inl[port][0](port, port_priv[port][0]); + if (port_inl[port][1]) + return port_inl[port][1](port, port_priv[port][1]); - return inw(port) | (inw(port + 2) << 16); + return inw(port) | (inw(port + 2) << 16); } void outl(uint16_t port, uint32_t val) { -/* if ((port & ~0xf) == 0xf000) - pclog("OUTL %04X %08X\n", port, val);*/ + /* if ((port & ~0xf) == 0xf000) + pclog("OUTL %04X %08X\n", port, val);*/ - if (port_outl[port][0]) - port_outl[port][0](port, val, port_priv[port][0]); - if (port_outl[port][1]) - port_outl[port][1](port, val, port_priv[port][1]); + if (port_outl[port][0]) + port_outl[port][0](port, val, port_priv[port][0]); + if (port_outl[port][1]) + port_outl[port][1](port, val, port_priv[port][1]); - if (port_outl[port][0] || port_outl[port][1]) - return; + if (port_outl[port][0] || port_outl[port][1]) + return; - outw(port, val); - outw(port + 2, val >> 16); + outw(port, val); + outw(port + 2, val >> 16); } diff --git a/src/joystick/gameport.c b/src/joystick/gameport.c index dc657fb0..a423a489 100644 --- a/src/joystick/gameport.c +++ b/src/joystick/gameport.c @@ -14,206 +14,165 @@ int joystick_type; -static 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, - NULL - }; +static 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, NULL}; char *joystick_get_name(int joystick) { - if (!joystick_list[joystick]) - return NULL; - return joystick_list[joystick]->name; + if (!joystick_list[joystick]) + return NULL; + return joystick_list[joystick]->name; } -int joystick_get_max_joysticks(int joystick) { - return joystick_list[joystick]->max_joysticks; -} +int joystick_get_max_joysticks(int joystick) { return joystick_list[joystick]->max_joysticks; } -int joystick_get_axis_count(int joystick) { - return joystick_list[joystick]->axis_count; -} +int joystick_get_axis_count(int joystick) { return joystick_list[joystick]->axis_count; } -int joystick_get_button_count(int joystick) { - return joystick_list[joystick]->button_count; -} +int joystick_get_button_count(int joystick) { return joystick_list[joystick]->button_count; } -int joystick_get_pov_count(int joystick) { - return joystick_list[joystick]->pov_count; -} +int joystick_get_pov_count(int joystick) { return joystick_list[joystick]->pov_count; } -char *joystick_get_axis_name(int joystick, int id) { - return joystick_list[joystick]->axis_names[id]; -} +char *joystick_get_axis_name(int joystick, int id) { return joystick_list[joystick]->axis_names[id]; } -char *joystick_get_button_name(int joystick, int id) { - return joystick_list[joystick]->button_names[id]; -} +char *joystick_get_button_name(int joystick, int id) { return joystick_list[joystick]->button_names[id]; } -char *joystick_get_pov_name(int joystick, int id) { - return joystick_list[joystick]->pov_names[id]; -} +char *joystick_get_pov_name(int joystick, int id) { return joystick_list[joystick]->pov_names[id]; } typedef struct gameport_axis_t { - pc_timer_t timer; - int axis_nr; - struct gameport_t *gameport; + pc_timer_t timer; + int axis_nr; + struct gameport_t *gameport; } gameport_axis_t; typedef struct gameport_t { - uint8_t state; + uint8_t state; - gameport_axis_t axis[4]; + gameport_axis_t axis[4]; - joystick_if_t *joystick; - void *joystick_dat; + joystick_if_t *joystick; + void *joystick_dat; } gameport_t; static gameport_t *gameport_global = NULL; static void gameport_time(gameport_t *gameport, int nr, int axis) { - if (axis == AXIS_NOT_PRESENT) { - timer_disable(&gameport->axis[nr].timer); - } else { - axis += 32768; - axis = (axis * 100) / 65; /*Axis now in ohms*/ - axis = (axis * 11) / 1000; - timer_set_delay_u64(&gameport->axis[nr].timer, TIMER_USEC * (axis + 24)); /*max = 11.115 ms*/ - } + if (axis == AXIS_NOT_PRESENT) { + timer_disable(&gameport->axis[nr].timer); + } else { + axis += 32768; + axis = (axis * 100) / 65; /*Axis now in ohms*/ + axis = (axis * 11) / 1000; + timer_set_delay_u64(&gameport->axis[nr].timer, TIMER_USEC * (axis + 24)); /*max = 11.115 ms*/ + } } void gameport_write(uint16_t addr, uint8_t val, void *p) { - gameport_t *gameport = (gameport_t *)p; + gameport_t *gameport = (gameport_t *)p; - gameport->state |= 0x0f; -// pclog("gameport_write : joysticks_present=%i\n", joysticks_present); + gameport->state |= 0x0f; + // pclog("gameport_write : joysticks_present=%i\n", joysticks_present); - gameport_time(gameport, 0, gameport->joystick->read_axis(gameport->joystick_dat, 0)); - gameport_time(gameport, 1, gameport->joystick->read_axis(gameport->joystick_dat, 1)); - gameport_time(gameport, 2, gameport->joystick->read_axis(gameport->joystick_dat, 2)); - gameport_time(gameport, 3, gameport->joystick->read_axis(gameport->joystick_dat, 3)); + gameport_time(gameport, 0, gameport->joystick->read_axis(gameport->joystick_dat, 0)); + gameport_time(gameport, 1, gameport->joystick->read_axis(gameport->joystick_dat, 1)); + gameport_time(gameport, 2, gameport->joystick->read_axis(gameport->joystick_dat, 2)); + gameport_time(gameport, 3, gameport->joystick->read_axis(gameport->joystick_dat, 3)); - gameport->joystick->write(gameport->joystick_dat); + gameport->joystick->write(gameport->joystick_dat); - cycles -= ISA_CYCLES(8); + cycles -= ISA_CYCLES(8); } uint8_t gameport_read(uint16_t addr, void *p) { - gameport_t *gameport = (gameport_t *)p; - uint8_t ret; + gameport_t *gameport = (gameport_t *)p; + uint8_t ret; -// if (joysticks_present) - ret = gameport->state | gameport->joystick->read(gameport->joystick_dat);//0xf0; -// else -// ret = 0xff; + // if (joysticks_present) + ret = gameport->state | gameport->joystick->read(gameport->joystick_dat); // 0xf0; + // else + // ret = 0xff; -// pclog("gameport_read: ret=%02x %08x:%08x isa_cycles=%i %i\n", ret, cs, cpu_state.pc, isa_cycles, gameport->axis[0].count); + // pclog("gameport_read: ret=%02x %08x:%08x isa_cycles=%i %i\n", ret, cs, cpu_state.pc, isa_cycles, + // gameport->axis[0].count); - cycles -= ISA_CYCLES(8); + cycles -= ISA_CYCLES(8); - return ret; + return ret; } void gameport_timer_over(void *p) { - gameport_axis_t *axis = (gameport_axis_t *)p; - gameport_t *gameport = axis->gameport; + gameport_axis_t *axis = (gameport_axis_t *)p; + gameport_t *gameport = axis->gameport; - gameport->state &= ~(1 << axis->axis_nr); + gameport->state &= ~(1 << axis->axis_nr); - if (axis == &gameport->axis[0]) - gameport->joystick->a0_over(gameport->joystick_dat); + if (axis == &gameport->axis[0]) + gameport->joystick->a0_over(gameport->joystick_dat); } void *gameport_init_common() { - gameport_t *gameport = malloc(sizeof(gameport_t)); + gameport_t *gameport = malloc(sizeof(gameport_t)); - memset(gameport, 0, sizeof(gameport_t)); + memset(gameport, 0, sizeof(gameport_t)); - gameport->axis[0].gameport = gameport; - gameport->axis[1].gameport = gameport; - gameport->axis[2].gameport = gameport; - gameport->axis[3].gameport = gameport; + gameport->axis[0].gameport = gameport; + gameport->axis[1].gameport = gameport; + gameport->axis[2].gameport = gameport; + gameport->axis[3].gameport = gameport; - gameport->axis[0].axis_nr = 0; - gameport->axis[1].axis_nr = 1; - gameport->axis[2].axis_nr = 2; - gameport->axis[3].axis_nr = 3; + gameport->axis[0].axis_nr = 0; + gameport->axis[1].axis_nr = 1; + gameport->axis[2].axis_nr = 2; + gameport->axis[3].axis_nr = 3; - timer_add(&gameport->axis[0].timer, gameport_timer_over, &gameport->axis[0], 0); - timer_add(&gameport->axis[1].timer, gameport_timer_over, &gameport->axis[1], 0); - timer_add(&gameport->axis[2].timer, gameport_timer_over, &gameport->axis[2], 0); - timer_add(&gameport->axis[3].timer, gameport_timer_over, &gameport->axis[3], 0); + timer_add(&gameport->axis[0].timer, gameport_timer_over, &gameport->axis[0], 0); + timer_add(&gameport->axis[1].timer, gameport_timer_over, &gameport->axis[1], 0); + timer_add(&gameport->axis[2].timer, gameport_timer_over, &gameport->axis[2], 0); + timer_add(&gameport->axis[3].timer, gameport_timer_over, &gameport->axis[3], 0); - gameport->joystick = joystick_list[joystick_type]; - gameport->joystick_dat = gameport->joystick->init(); + gameport->joystick = joystick_list[joystick_type]; + gameport->joystick_dat = gameport->joystick->init(); - gameport_global = gameport; + gameport_global = gameport; - return gameport; + return gameport; } void gameport_update_joystick_type() { - gameport_t *gameport = gameport_global; + gameport_t *gameport = gameport_global; - if (gameport) { - gameport->joystick->close(gameport->joystick_dat); - gameport->joystick = joystick_list[joystick_type]; - gameport->joystick_dat = gameport->joystick->init(); - } + if (gameport) { + gameport->joystick->close(gameport->joystick_dat); + gameport->joystick = joystick_list[joystick_type]; + gameport->joystick_dat = gameport->joystick->init(); + } } void *gameport_init() { - gameport_t *gameport = gameport_init_common(); + gameport_t *gameport = gameport_init_common(); - io_sethandler(0x0200, 0x0008, gameport_read, NULL, NULL, gameport_write, NULL, NULL, gameport); + io_sethandler(0x0200, 0x0008, gameport_read, NULL, NULL, gameport_write, NULL, NULL, gameport); - return gameport; + return gameport; } void *gameport_201_init() { - gameport_t *gameport = gameport_init_common(); + gameport_t *gameport = gameport_init_common(); - io_sethandler(0x0201, 0x0001, gameport_read, NULL, NULL, gameport_write, NULL, NULL, gameport); + io_sethandler(0x0201, 0x0001, gameport_read, NULL, NULL, gameport_write, NULL, NULL, gameport); - return gameport; + return gameport; } void gameport_close(void *p) { - gameport_t *gameport = (gameport_t *)p; + gameport_t *gameport = (gameport_t *)p; - gameport->joystick->close(gameport->joystick_dat); + gameport->joystick->close(gameport->joystick_dat); - gameport_global = NULL; + gameport_global = NULL; - free(gameport); + free(gameport); } -device_t gameport_device = - { - "Game port", - 0, - gameport_init, - gameport_close, - NULL, - NULL, - NULL, - NULL - }; +device_t gameport_device = {"Game port", 0, gameport_init, gameport_close, NULL, NULL, NULL, NULL}; -device_t gameport_201_device = - { - "Game port (port 201h only)", - 0, - gameport_201_init, - gameport_close, - NULL, - NULL, - NULL, - NULL - }; +device_t gameport_201_device = {"Game port (port 201h only)", 0, gameport_201_init, gameport_close, NULL, NULL, NULL, NULL}; diff --git a/src/joystick/joystick_ch_flightstick_pro.c b/src/joystick/joystick_ch_flightstick_pro.c index b9c32dd2..f55baaf4 100644 --- a/src/joystick/joystick_ch_flightstick_pro.c +++ b/src/joystick/joystick_ch_flightstick_pro.c @@ -6,73 +6,69 @@ #include "joystick_standard.h" #include "plat-joystick.h" -static void *ch_flightstick_pro_init() { - return NULL; -} +static void *ch_flightstick_pro_init() { return NULL; } -static void ch_flightstick_pro_close(void *p) { -} +static void ch_flightstick_pro_close(void *p) {} static uint8_t ch_flightstick_pro_read(void *p) { - uint8_t ret = 0xf0; + 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; - } - } + 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; + return ret; } -static void ch_flightstick_pro_write(void *p) { -} +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; + 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]; - } - return 0; + 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]; + } + return 0; } -static void ch_flightstick_pro_a0_over(void *p) { -} +static void ch_flightstick_pro_a0_over(void *p) {} -joystick_if_t joystick_ch_flightstick_pro = - { - .name = "CH Flightstick Pro", - .init = ch_flightstick_pro_init, - .close = ch_flightstick_pro_close, - .read = ch_flightstick_pro_read, - .write = ch_flightstick_pro_write, - .read_axis = ch_flightstick_pro_read_axis, - .a0_over = ch_flightstick_pro_a0_over, - .max_joysticks = 1, - .axis_count = 3, - .button_count = 4, - .pov_count = 1, - .axis_names = {"X axis", "Y axis", "Throttle"}, - .button_names = {"Button 1", "Button 2", "Button 3", "Button 4"}, - .pov_names = {"POV"} - }; +joystick_if_t joystick_ch_flightstick_pro = {.name = "CH Flightstick Pro", + .init = ch_flightstick_pro_init, + .close = ch_flightstick_pro_close, + .read = ch_flightstick_pro_read, + .write = ch_flightstick_pro_write, + .read_axis = ch_flightstick_pro_read_axis, + .a0_over = ch_flightstick_pro_a0_over, + .max_joysticks = 1, + .axis_count = 3, + .button_count = 4, + .pov_count = 1, + .axis_names = {"X axis", "Y axis", "Throttle"}, + .button_names = {"Button 1", "Button 2", "Button 3", "Button 4"}, + .pov_names = {"POV"}}; diff --git a/src/joystick/joystick_standard.c b/src/joystick/joystick_standard.c index b9159536..f572d8cc 100644 --- a/src/joystick/joystick_standard.c +++ b/src/joystick/joystick_standard.c @@ -6,181 +6,176 @@ #include "joystick_standard.h" #include "plat-joystick.h" -static void *joystick_standard_init() { - return NULL; -} +static void *joystick_standard_init() { return NULL; } -static void joystick_standard_close(void *p) { -} +static void joystick_standard_close(void *p) {} static uint8_t joystick_standard_read(void *p) { - uint8_t ret = 0xf0; + 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; - } + 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; + return ret; } static uint8_t joystick_standard_read_4button(void *p) { - uint8_t ret = 0xf0; + 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_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; + return ret; } -static void joystick_standard_write(void *p) { -} +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]; - } - return 0; + 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]; + } + return 0; } static int joystick_standard_read_axis_4button(void *p, int axis) { - if (!JOYSTICK_PRESENT(0)) - return AXIS_NOT_PRESENT; + 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; - } - return 0; + 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; + } + return 0; } static int joystick_standard_read_axis_6button(void *p, int axis) { - if (!JOYSTICK_PRESENT(0)) - return AXIS_NOT_PRESENT; + 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; - } - return 0; + 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; + } + return 0; } static int joystick_standard_read_axis_8button(void *p, int axis) { - if (!JOYSTICK_PRESENT(0)) - return AXIS_NOT_PRESENT; + 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; - } - return 0; + 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; + } + return 0; } -static void joystick_standard_a0_over(void *p) { -} +static void joystick_standard_a0_over(void *p) {} -joystick_if_t joystick_standard = - { - .name = "Standard 2-button joystick(s)", - .init = joystick_standard_init, - .close = joystick_standard_close, - .read = joystick_standard_read, - .write = joystick_standard_write, - .read_axis = joystick_standard_read_axis, - .a0_over = joystick_standard_a0_over, - .max_joysticks = 2, - .axis_count = 2, - .button_count = 2, - .axis_names = {"X axis", "Y axis"}, - .button_names = {"Button 1", "Button 2"} - }; -joystick_if_t joystick_standard_4button = - { - .name = "Standard 4-button joystick", - .init = joystick_standard_init, - .close = joystick_standard_close, - .read = joystick_standard_read_4button, - .write = joystick_standard_write, - .read_axis = joystick_standard_read_axis_4button, - .a0_over = joystick_standard_a0_over, - .max_joysticks = 1, - .axis_count = 2, - .button_count = 4, - .axis_names = {"X axis", "Y axis"}, - .button_names = {"Button 1", "Button 2", "Button 3", "Button 4"} - }; -joystick_if_t joystick_standard_6button = - { - .name = "Standard 6-button joystick", - .init = joystick_standard_init, - .close = joystick_standard_close, - .read = joystick_standard_read_4button, - .write = joystick_standard_write, - .read_axis = joystick_standard_read_axis_6button, - .a0_over = joystick_standard_a0_over, - .max_joysticks = 1, - .axis_count = 2, - .button_count = 6, - .axis_names = {"X axis", "Y axis"}, - .button_names = {"Button 1", "Button 2", "Button 3", "Button 4", "Button 5", "Button 6"} - }; -joystick_if_t joystick_standard_8button = - { - .name = "Standard 8-button joystick", - .init = joystick_standard_init, - .close = joystick_standard_close, - .read = joystick_standard_read_4button, - .write = joystick_standard_write, - .read_axis = joystick_standard_read_axis_8button, - .a0_over = joystick_standard_a0_over, - .max_joysticks = 1, - .axis_count = 2, - .button_count = 8, - .axis_names = {"X axis", "Y axis"}, - .button_names = {"Button 1", "Button 2", "Button 3", "Button 4", "Button 5", "Button 6", "Button 7", "Button 8"} - }; +joystick_if_t joystick_standard = {.name = "Standard 2-button joystick(s)", + .init = joystick_standard_init, + .close = joystick_standard_close, + .read = joystick_standard_read, + .write = joystick_standard_write, + .read_axis = joystick_standard_read_axis, + .a0_over = joystick_standard_a0_over, + .max_joysticks = 2, + .axis_count = 2, + .button_count = 2, + .axis_names = {"X axis", "Y axis"}, + .button_names = {"Button 1", "Button 2"}}; +joystick_if_t joystick_standard_4button = {.name = "Standard 4-button joystick", + .init = joystick_standard_init, + .close = joystick_standard_close, + .read = joystick_standard_read_4button, + .write = joystick_standard_write, + .read_axis = joystick_standard_read_axis_4button, + .a0_over = joystick_standard_a0_over, + .max_joysticks = 1, + .axis_count = 2, + .button_count = 4, + .axis_names = {"X axis", "Y axis"}, + .button_names = {"Button 1", "Button 2", "Button 3", "Button 4"}}; +joystick_if_t joystick_standard_6button = { + .name = "Standard 6-button joystick", + .init = joystick_standard_init, + .close = joystick_standard_close, + .read = joystick_standard_read_4button, + .write = joystick_standard_write, + .read_axis = joystick_standard_read_axis_6button, + .a0_over = joystick_standard_a0_over, + .max_joysticks = 1, + .axis_count = 2, + .button_count = 6, + .axis_names = {"X axis", "Y axis"}, + .button_names = {"Button 1", "Button 2", "Button 3", "Button 4", "Button 5", "Button 6"}}; +joystick_if_t joystick_standard_8button = { + .name = "Standard 8-button joystick", + .init = joystick_standard_init, + .close = joystick_standard_close, + .read = joystick_standard_read_4button, + .write = joystick_standard_write, + .read_axis = joystick_standard_read_axis_8button, + .a0_over = joystick_standard_a0_over, + .max_joysticks = 1, + .axis_count = 2, + .button_count = 8, + .axis_names = {"X axis", "Y axis"}, + .button_names = {"Button 1", "Button 2", "Button 3", "Button 4", "Button 5", "Button 6", "Button 7", "Button 8"}}; diff --git a/src/joystick/joystick_sw_pad.c b/src/joystick/joystick_sw_pad.c index 23f1d066..e5c627da 100644 --- a/src/joystick/joystick_sw_pad.c +++ b/src/joystick/joystick_sw_pad.c @@ -1,5 +1,5 @@ /*Sidewinder game pad 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?) @@ -29,181 +29,177 @@ #include "plat-joystick.h" typedef struct { - pc_timer_t poll_timer; - int poll_left; - int poll_clock; - uint64_t poll_data; - int poll_mode; + pc_timer_t poll_timer; + int poll_left; + int poll_clock; + uint64_t poll_data; + int poll_mode; - pc_timer_t trigger_timer; - int data_mode; + pc_timer_t trigger_timer; + int data_mode; } sw_data; static void sw_timer_over(void *p) { - sw_data *sw = (sw_data *)p; + sw_data *sw = (sw_data *)p; - sw->poll_clock = !sw->poll_clock; + sw->poll_clock = !sw->poll_clock; - if (sw->poll_clock) { - sw->poll_data >>= (sw->poll_mode ? 3 : 1); - sw->poll_left--; - } + if (sw->poll_clock) { + sw->poll_data >>= (sw->poll_mode ? 3 : 1); + sw->poll_left--; + } - if (sw->poll_left == 1 && !sw->poll_clock) - timer_advance_u64(&sw->poll_timer, TIMER_USEC * 160); - else if (sw->poll_left) - timer_set_delay_u64(&sw->poll_timer, TIMER_USEC * 5); + if (sw->poll_left == 1 && !sw->poll_clock) + timer_advance_u64(&sw->poll_timer, TIMER_USEC * 160); + else if (sw->poll_left) + timer_set_delay_u64(&sw->poll_timer, TIMER_USEC * 5); } -static void sw_trigger_timer_over(void *p) { -} +static void sw_trigger_timer_over(void *p) {} static int sw_parity(uint16_t data) { - int bits_set = 0; + int bits_set = 0; - while (data) { - bits_set++; - data &= (data - 1); - } + while (data) { + bits_set++; + data &= (data - 1); + } - return bits_set & 1; + return bits_set & 1; } static void *sw_init() { - sw_data *sw = (sw_data *)malloc(sizeof(sw_data)); - memset(sw, 0, sizeof(sw_data)); + sw_data *sw = (sw_data *)malloc(sizeof(sw_data)); + memset(sw, 0, sizeof(sw_data)); - timer_add(&sw->poll_timer, sw_timer_over, sw, 0); - timer_add(&sw->trigger_timer, sw_trigger_timer_over, sw, 0); + timer_add(&sw->poll_timer, sw_timer_over, sw, 0); + timer_add(&sw->trigger_timer, sw_trigger_timer_over, sw, 0); - return sw; + return sw; } static void sw_close(void *p) { - sw_data *sw = (sw_data *)p; + sw_data *sw = (sw_data *)p; - free(sw); + free(sw); } static uint8_t sw_read(void *p) { - sw_data *sw = (sw_data *)p; - uint8_t temp = 0; + sw_data *sw = (sw_data *)p; + uint8_t temp = 0; - if (!JOYSTICK_PRESENT(0)) - return 0xff; + if (!JOYSTICK_PRESENT(0)) + return 0xff; - if (timer_is_enabled(&sw->poll_timer)) { - if (sw->poll_clock) - temp |= 0x10; + if (timer_is_enabled(&sw->poll_timer)) { + 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; + 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; + return temp; } static void sw_write(void *p) { - sw_data *sw = (sw_data *)p; - int time_since_last = timer_get_remaining_us(&sw->trigger_timer); + sw_data *sw = (sw_data *)p; + int time_since_last = timer_get_remaining_us(&sw->trigger_timer); - if (!JOYSTICK_PRESENT(0)) - return; + if (!JOYSTICK_PRESENT(0)) + return; - if (!sw->poll_left) { - sw->poll_clock = 1; - timer_set_delay_u64(&sw->poll_timer, TIMER_USEC * 40); + if (!sw->poll_left) { + sw->poll_clock = 1; + timer_set_delay_u64(&sw->poll_timer, TIMER_USEC * 40); - if (time_since_last > 9900 && time_since_last < 9940) { -// pclog("sw sends ID packet\n"); - sw->poll_mode = 0; - sw->poll_left = 49; - sw->poll_data = 0x2400ull | (0x1830ull << 15) | (0x19b0ull << 30); - } else { - int c; + if (time_since_last > 9900 && time_since_last < 9940) { + // pclog("sw sends ID packet\n"); + sw->poll_mode = 0; + sw->poll_left = 49; + sw->poll_data = 0x2400ull | (0x1830ull << 15) | (0x19b0ull << 30); + } else { + int c; -// pclog("sw sends data packet %08x %i\n", cpu_state.pc, data_packets++); + // pclog("sw sends data packet %08x %i\n", cpu_state.pc, data_packets++); - sw->poll_mode = sw->data_mode; - sw->data_mode = !sw->data_mode; + 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; - } + 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++) { - uint64_t data = 0x3fff; - int b; + for (c = 0; c < 4; c++) { + uint64_t data = 0x3fff; + int b; - if (!JOYSTICK_PRESENT(c)) - break; + 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; + 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)); - } + for (b = 0; b < 10; b++) { + if (joystick_state[c].button[b]) + data &= ~(1 << (b + 4)); + } - if (sw_parity(data)) - data |= 0x4000; + 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)); - } - } - } - } + 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)); + } + } + } + } - timer_disable(&sw->trigger_timer); + timer_disable(&sw->trigger_timer); } static int sw_read_axis(void *p, int axis) { - if (!JOYSTICK_PRESENT(0)) - return AXIS_NOT_PRESENT; + if (!JOYSTICK_PRESENT(0)) + return AXIS_NOT_PRESENT; - return 0; /*No analogue support on Sidewinder game pad*/ + return 0; /*No analogue support on Sidewinder game pad*/ } static void sw_a0_over(void *p) { - sw_data *sw = (sw_data *)p; + sw_data *sw = (sw_data *)p; - timer_set_delay_u64(&sw->trigger_timer, TIMER_USEC * 10000); + timer_set_delay_u64(&sw->trigger_timer, TIMER_USEC * 10000); } -joystick_if_t joystick_sw_pad = - { - .name = "Microsoft SideWinder Pad", - .init = sw_init, - .close = sw_close, - .read = sw_read, - .write = sw_write, - .read_axis = sw_read_axis, - .a0_over = sw_a0_over, - .max_joysticks = 4, - .axis_count = 2, - .button_count = 10, - .axis_names = {"X axis", "Y axis"}, - .button_names = {"A", "B", "C", "X", "Y", "Z", "L", "R", "Start", "M"} - }; +joystick_if_t joystick_sw_pad = {.name = "Microsoft SideWinder Pad", + .init = sw_init, + .close = sw_close, + .read = sw_read, + .write = sw_write, + .read_axis = sw_read_axis, + .a0_over = sw_a0_over, + .max_joysticks = 4, + .axis_count = 2, + .button_count = 10, + .axis_names = {"X axis", "Y axis"}, + .button_names = {"A", "B", "C", "X", "Y", "Z", "L", "R", "Start", "M"}}; diff --git a/src/joystick/joystick_tm_fcs.c b/src/joystick/joystick_tm_fcs.c index e1f290c7..4a87db26 100644 --- a/src/joystick/joystick_tm_fcs.c +++ b/src/joystick/joystick_tm_fcs.c @@ -6,74 +6,69 @@ #include "joystick_standard.h" #include "plat-joystick.h" -static void *tm_fcs_init() { - return NULL; -} +static void *tm_fcs_init() { return NULL; } -static void tm_fcs_close(void *p) { -} +static void tm_fcs_close(void *p) {} static uint8_t tm_fcs_read(void *p) { - uint8_t ret = 0xf0; + 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_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; + return ret; } -static void tm_fcs_write(void *p) { -} +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; + 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; - } - return 0; + 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; + } + return 0; } -static void tm_fcs_a0_over(void *p) { -} +static void tm_fcs_a0_over(void *p) {} -joystick_if_t joystick_tm_fcs = - { - .name = "Thrustmaster Flight Control System", - .init = tm_fcs_init, - .close = tm_fcs_close, - .read = tm_fcs_read, - .write = tm_fcs_write, - .read_axis = tm_fcs_read_axis, - .a0_over = tm_fcs_a0_over, - .max_joysticks = 1, - .axis_count = 2, - .button_count = 4, - .pov_count = 1, - .axis_names = {"X axis", "Y axis"}, - .button_names = {"Button 1", "Button 2", "Button 3", "Button 4"}, - .pov_names = {"POV"} - }; +joystick_if_t joystick_tm_fcs = {.name = "Thrustmaster Flight Control System", + .init = tm_fcs_init, + .close = tm_fcs_close, + .read = tm_fcs_read, + .write = tm_fcs_write, + .read_axis = tm_fcs_read_axis, + .a0_over = tm_fcs_a0_over, + .max_joysticks = 1, + .axis_count = 2, + .button_count = 4, + .pov_count = 1, + .axis_names = {"X axis", "Y axis"}, + .button_names = {"Button 1", "Button 2", "Button 3", "Button 4"}, + .pov_names = {"POV"}}; diff --git a/src/keyboard/keyboard.c b/src/keyboard/keyboard.c index 32734475..b94fb5a2 100644 --- a/src/keyboard/keyboard.c +++ b/src/keyboard/keyboard.c @@ -5,381 +5,1396 @@ int keybsendcallback = 0; typedef struct { - uint8_t scancodes_make[8]; - uint8_t scancodes_break[8]; + uint8_t scancodes_make[8]; + uint8_t scancodes_break[8]; } scancode; /*272 = 256 + 16 fake interim scancodes for disambiguation purposes.*/ -static scancode scancode_set1[272] = - { - {{0}, {0}}, {{0x01, 0}, {0x81, 0}}, {{0x02, 0}, {0x82, 0}}, {{0x03, 0}, {0x83, 0}}, - {{0x04, 0}, {0x84, 0}}, {{0x05, 0}, {0x85, 0}}, {{0x06, 0}, {0x86, 0}}, {{0x07, 0}, {0x87, 0}}, - {{0x08, 0}, {0x88, 0}}, {{0x09, 0}, {0x89, 0}}, {{0x0a, 0}, {0x8a, 0}}, {{0x0b, 0}, {0x8b, 0}}, - {{0x0c, 0}, {0x8c, 0}}, {{0x0d, 0}, {0x8d, 0}}, {{0x0e, 0}, {0x8e, 0}}, {{0x0f, 0}, {0x8f, 0}}, - {{0x10, 0}, {0x90, 0}}, {{0x11, 0}, {0x91, 0}}, {{0x12, 0}, {0x92, 0}}, {{0x13, 0}, {0x93, 0}}, - {{0x14, 0}, {0x94, 0}}, {{0x15, 0}, {0x95, 0}}, {{0x16, 0}, {0x96, 0}}, {{0x17, 0}, {0x97, 0}}, - {{0x18, 0}, {0x98, 0}}, {{0x19, 0}, {0x99, 0}}, {{0x1a, 0}, {0x9a, 0}}, {{0x1b, 0}, {0x9b, 0}}, - {{0x1c, 0}, {0x9c, 0}}, {{0x1d, 0}, {0x9d, 0}}, {{0x1e, 0}, {0x9e, 0}}, {{0x1f, 0}, {0x9f, 0}}, - {{0x20, 0}, {0xa0, 0}}, {{0x21, 0}, {0xa1, 0}}, {{0x22, 0}, {0xa2, 0}}, {{0x23, 0}, {0xa3, 0}}, - {{0x24, 0}, {0xa4, 0}}, {{0x25, 0}, {0xa5, 0}}, {{0x26, 0}, {0xa6, 0}}, {{0x27, 0}, {0xa7, 0}}, - {{0x28, 0}, {0xa8, 0}}, {{0x29, 0}, {0xa9, 0}}, {{0x2a, 0}, {0xaa, 0}}, {{0x2b, 0}, {0xab, 0}}, - {{0x2c, 0}, {0xac, 0}}, {{0x2d, 0}, {0xad, 0}}, {{0x2e, 0}, {0xae, 0}}, {{0x2f, 0}, {0xaf, 0}}, - {{0x30, 0}, {0xb0, 0}}, {{0x31, 0}, {0xb1, 0}}, {{0x32, 0}, {0xb2, 0}}, {{0x33, 0}, {0xb3, 0}}, - {{0x34, 0}, {0xb4, 0}}, {{0x35, 0}, {0xb5, 0}}, {{0x36, 0}, {0xb6, 0}}, {{0x37, 0}, {0xb7, 0}}, - {{0x38, 0}, {0xb8, 0}}, {{0x39, 0}, {0xb9, 0}}, {{0x3a, 0}, {0xba, 0}}, {{0x3b, 0}, {0xbb, 0}}, - {{0x3c, 0}, {0xbc, 0}}, {{0x3d, 0}, {0xbd, 0}}, {{0x3e, 0}, {0xbe, 0}}, {{0x3f, 0}, {0xbf, 0}}, - {{0x40, 0}, {0xc0, 0}}, {{0x41, 0}, {0xc1, 0}}, {{0x42, 0}, {0xc2, 0}}, {{0x43, 0}, {0xc3, 0}}, - {{0x44, 0}, {0xc4, 0}}, {{0x45, 0}, {0xc5, 0}}, {{0x46, 0}, {0xc6, 0}}, {{0x47, 0}, {0xc7, 0}}, - {{0x48, 0}, {0xc8, 0}}, {{0x49, 0}, {0xc9, 0}}, {{0x4a, 0}, {0xca, 0}}, {{0x4b, 0}, {0xcb, 0}}, - {{0x4c, 0}, {0xcc, 0}}, {{0x4d, 0}, {0xcd, 0}}, {{0x4e, 0}, {0xce, 0}}, {{0x4f, 0}, {0xcf, 0}}, - {{0x50, 0}, {0xd0, 0}}, {{0x51, 0}, {0xd1, 0}}, {{0x52, 0}, {0xd2, 0}}, {{0x53, 0}, {0xd3, 0}}, - {{0x54, 0}, {0xd4, 0}}, {{0x55, 0}, {0xd5, 0}}, {{0x56, 0}, {0xd6, 0}}, {{0x57, 0}, {0xd7, 0}}, - {{0x58, 0}, {0xd8, 0}}, {{0x59, 0}, {0xd9, 0}}, {{0x5a, 0}, {0xda, 0}}, {{0x5b, 0}, {0xdb, 0}}, - {{0x5c, 0}, {0xdc, 0}}, {{0x5d, 0}, {0xdd, 0}}, {{0x5e, 0}, {0xde, 0}}, {{0x5f, 0}, {0xdf, 0}}, - {{0x60, 0}, {0xe0, 0}}, {{0x61, 0}, {0xe1, 0}}, {{0x62, 0}, {0xe2, 0}}, {{0x63, 0}, {0xe3, 0}}, - {{0x64, 0}, {0xe4, 0}}, {{0x65, 0}, {0xe5, 0}}, {{0x66, 0}, {0xe6, 0}}, {{0x67, 0}, {0xe7, 0}}, - {{0x68, 0}, {0xe8, 0}}, {{0x69, 0}, {0xe9, 0}}, {{0x6a, 0}, {0xea, 0}}, {{0x6b, 0}, {0xeb, 0}}, - {{0x6c, 0}, {0xec, 0}}, {{0x6d, 0}, {0xed, 0}}, {{0x6e, 0}, {0xee, 0}}, {{0x6f, 0}, {0xef, 0}}, - {{0x70, 0}, {0xf0, 0}}, {{0x71, 0}, {0xf1, 0}}, {{0x72, 0}, {0xf2, 0}}, {{0x73, 0}, {0xf3, 0}}, - {{0x74, 0}, {0xf4, 0}}, {{0x75, 0}, {0xf5, 0}}, {{0x76, 0}, {0xf6, 0}}, {{0x77, 0}, {0xf7, 0}}, - {{0x78, 0}, {0xf8, 0}}, {{0x79, 0}, {0xf9, 0}}, {{0x7a, 0}, {0xfa, 0}}, {{0x7b, 0}, {0xfb, 0}}, - {{0x7c, 0}, {0xfc, 0}}, {{0x7d, 0}, {0xfd, 0}}, {{0x7e, 0}, {0xfe, 0}}, {{0x7f, 0}, {0xff, 0}}, +static scancode scancode_set1[272] = { + {{0}, {0}}, + {{0x01, 0}, {0x81, 0}}, + {{0x02, 0}, {0x82, 0}}, + {{0x03, 0}, {0x83, 0}}, + {{0x04, 0}, {0x84, 0}}, + {{0x05, 0}, {0x85, 0}}, + {{0x06, 0}, {0x86, 0}}, + {{0x07, 0}, {0x87, 0}}, + {{0x08, 0}, {0x88, 0}}, + {{0x09, 0}, {0x89, 0}}, + {{0x0a, 0}, {0x8a, 0}}, + {{0x0b, 0}, {0x8b, 0}}, + {{0x0c, 0}, {0x8c, 0}}, + {{0x0d, 0}, {0x8d, 0}}, + {{0x0e, 0}, {0x8e, 0}}, + {{0x0f, 0}, {0x8f, 0}}, + {{0x10, 0}, {0x90, 0}}, + {{0x11, 0}, {0x91, 0}}, + {{0x12, 0}, {0x92, 0}}, + {{0x13, 0}, {0x93, 0}}, + {{0x14, 0}, {0x94, 0}}, + {{0x15, 0}, {0x95, 0}}, + {{0x16, 0}, {0x96, 0}}, + {{0x17, 0}, {0x97, 0}}, + {{0x18, 0}, {0x98, 0}}, + {{0x19, 0}, {0x99, 0}}, + {{0x1a, 0}, {0x9a, 0}}, + {{0x1b, 0}, {0x9b, 0}}, + {{0x1c, 0}, {0x9c, 0}}, + {{0x1d, 0}, {0x9d, 0}}, + {{0x1e, 0}, {0x9e, 0}}, + {{0x1f, 0}, {0x9f, 0}}, + {{0x20, 0}, {0xa0, 0}}, + {{0x21, 0}, {0xa1, 0}}, + {{0x22, 0}, {0xa2, 0}}, + {{0x23, 0}, {0xa3, 0}}, + {{0x24, 0}, {0xa4, 0}}, + {{0x25, 0}, {0xa5, 0}}, + {{0x26, 0}, {0xa6, 0}}, + {{0x27, 0}, {0xa7, 0}}, + {{0x28, 0}, {0xa8, 0}}, + {{0x29, 0}, {0xa9, 0}}, + {{0x2a, 0}, {0xaa, 0}}, + {{0x2b, 0}, {0xab, 0}}, + {{0x2c, 0}, {0xac, 0}}, + {{0x2d, 0}, {0xad, 0}}, + {{0x2e, 0}, {0xae, 0}}, + {{0x2f, 0}, {0xaf, 0}}, + {{0x30, 0}, {0xb0, 0}}, + {{0x31, 0}, {0xb1, 0}}, + {{0x32, 0}, {0xb2, 0}}, + {{0x33, 0}, {0xb3, 0}}, + {{0x34, 0}, {0xb4, 0}}, + {{0x35, 0}, {0xb5, 0}}, + {{0x36, 0}, {0xb6, 0}}, + {{0x37, 0}, {0xb7, 0}}, + {{0x38, 0}, {0xb8, 0}}, + {{0x39, 0}, {0xb9, 0}}, + {{0x3a, 0}, {0xba, 0}}, + {{0x3b, 0}, {0xbb, 0}}, + {{0x3c, 0}, {0xbc, 0}}, + {{0x3d, 0}, {0xbd, 0}}, + {{0x3e, 0}, {0xbe, 0}}, + {{0x3f, 0}, {0xbf, 0}}, + {{0x40, 0}, {0xc0, 0}}, + {{0x41, 0}, {0xc1, 0}}, + {{0x42, 0}, {0xc2, 0}}, + {{0x43, 0}, {0xc3, 0}}, + {{0x44, 0}, {0xc4, 0}}, + {{0x45, 0}, {0xc5, 0}}, + {{0x46, 0}, {0xc6, 0}}, + {{0x47, 0}, {0xc7, 0}}, + {{0x48, 0}, {0xc8, 0}}, + {{0x49, 0}, {0xc9, 0}}, + {{0x4a, 0}, {0xca, 0}}, + {{0x4b, 0}, {0xcb, 0}}, + {{0x4c, 0}, {0xcc, 0}}, + {{0x4d, 0}, {0xcd, 0}}, + {{0x4e, 0}, {0xce, 0}}, + {{0x4f, 0}, {0xcf, 0}}, + {{0x50, 0}, {0xd0, 0}}, + {{0x51, 0}, {0xd1, 0}}, + {{0x52, 0}, {0xd2, 0}}, + {{0x53, 0}, {0xd3, 0}}, + {{0x54, 0}, {0xd4, 0}}, + {{0x55, 0}, {0xd5, 0}}, + {{0x56, 0}, {0xd6, 0}}, + {{0x57, 0}, {0xd7, 0}}, + {{0x58, 0}, {0xd8, 0}}, + {{0x59, 0}, {0xd9, 0}}, + {{0x5a, 0}, {0xda, 0}}, + {{0x5b, 0}, {0xdb, 0}}, + {{0x5c, 0}, {0xdc, 0}}, + {{0x5d, 0}, {0xdd, 0}}, + {{0x5e, 0}, {0xde, 0}}, + {{0x5f, 0}, {0xdf, 0}}, + {{0x60, 0}, {0xe0, 0}}, + {{0x61, 0}, {0xe1, 0}}, + {{0x62, 0}, {0xe2, 0}}, + {{0x63, 0}, {0xe3, 0}}, + {{0x64, 0}, {0xe4, 0}}, + {{0x65, 0}, {0xe5, 0}}, + {{0x66, 0}, {0xe6, 0}}, + {{0x67, 0}, {0xe7, 0}}, + {{0x68, 0}, {0xe8, 0}}, + {{0x69, 0}, {0xe9, 0}}, + {{0x6a, 0}, {0xea, 0}}, + {{0x6b, 0}, {0xeb, 0}}, + {{0x6c, 0}, {0xec, 0}}, + {{0x6d, 0}, {0xed, 0}}, + {{0x6e, 0}, {0xee, 0}}, + {{0x6f, 0}, {0xef, 0}}, + {{0x70, 0}, {0xf0, 0}}, + {{0x71, 0}, {0xf1, 0}}, + {{0x72, 0}, {0xf2, 0}}, + {{0x73, 0}, {0xf3, 0}}, + {{0x74, 0}, {0xf4, 0}}, + {{0x75, 0}, {0xf5, 0}}, + {{0x76, 0}, {0xf6, 0}}, + {{0x77, 0}, {0xf7, 0}}, + {{0x78, 0}, {0xf8, 0}}, + {{0x79, 0}, {0xf9, 0}}, + {{0x7a, 0}, {0xfa, 0}}, + {{0x7b, 0}, {0xfb, 0}}, + {{0x7c, 0}, {0xfc, 0}}, + {{0x7d, 0}, {0xfd, 0}}, + {{0x7e, 0}, {0xfe, 0}}, + {{0x7f, 0}, {0xff, 0}}, - {{0x80, 0}, {0}}, {{0x81, 0}, {0}}, {{0x82, 0}, {0}}, {{0xe0, 0x03, 0}, {0xe0, 0x83, 0}}, /*80*/ - {{0xe0, 0x04, 0}, {0xe0, 0x84, 0}}, {{0x85, 0}, {0}}, {{0x86, 0}, {0}}, {{0x87, 0}, {0}}, /*84*/ - {{0xe0, 0x08, 0}, {0xe0, 0x88, 0}}, {{0xe0, 0x09, 0}, {0xe0, 0x89, 0}}, {{0xe0, 0x0a, 0}, {0xe0, 0x8a, 0}}, {{0xe0, 0x0b, 0}, {0xe0, 0x8b, 0}}, /*88*/ - {{0xe0, 0x0c, 0}, {0xe0, 0x8c, 0}}, {{0}, {0}}, {{0xe0, 0x0e, 0}, {0xe0, 0x8e, 0}}, {{0xe0, 0x0f, 0}, {0xe0, 0x8f, 0}}, /*8c*/ - {{0xe0, 0x10, 0}, {0xe0, 0x90, 0}}, {{0xe0, 0x11, 0}, {0xe0, 0x91, 0}}, {{0xe0, 0x12, 0}, {0xe0, 0x92, 0}}, {{0xe0, 0x13, 0}, {0xe0, 0x93, 0}}, /*90*/ - {{0xe0, 0x14, 0}, {0xe0, 0x94, 0}}, {{0xe0, 0x15, 0}, {0xe0, 0x95, 0}}, {{0xe0, 0x16, 0}, {0xe0, 0x96, 0}}, {{0xe0, 0x17, 0}, {0xe0, 0x97, 0}}, /*94*/ - {{0xe0, 0x18, 0}, {0xe0, 0x98, 0}}, {{0xe0, 0x19, 0}, {0xe0, 0x99, 0}}, {{0xe0, 0x1a, 0}, {0xe0, 0x9a, 0}}, {{0xe0, 0x1b, 0}, {0xe0, 0x9b, 0}}, /*98*/ - {{0xe0, 0x1c, 0}, {0xe0, 0x9c, 0}}, {{0xe0, 0x1d, 0}, {0xe0, 0x9d, 0}}, {{0xe0, 0x1e, 0}, {0xe0, 0x9e, 0}}, {{0xe0, 0x1f, 0}, {0xe0, 0x9f, 0}}, /*9c*/ - {{0xe0, 0x20, 0}, {0xe0, 0xa0, 0}}, {{0xe0, 0x21, 0}, {0xe0, 0xa1, 0}}, {{0xe0, 0x22, 0}, {0xe0, 0xa2, 0}}, {{0xe0, 0x23, 0}, {0xe0, 0xa3, 0}}, /*a0*/ - {{0xe0, 0x24, 0}, {0xe0, 0xa4, 0}}, {{0xe0, 0x25, 0}, {0xe0, 0xa5, 0}}, {{0xe0, 0x26, 0}, {0xe0, 0xa6, 0}}, {{0}, {0}}, /*a4*/ - {{0}, {0}}, {{0}, {0}}, {{0xe0, 0x2a, 0}, {0xe0, 0xaa, 0}}, {{0}, {0}}, /*a8*/ - {{0xe0, 0x2c, 0}, {0xe0, 0xac, 0}}, {{0xe0, 0x2d, 0}, {0xe0, 0xad, 0}}, {{0xe0, 0x2e, 0}, {0xe0, 0xae, 0}}, {{0xe0, 0x2f, 0}, {0xe0, 0xaf, 0}}, /*ac*/ - {{0xe0, 0x30, 0}, {0xe0, 0xb0, 0}}, {{0xe0, 0x31, 0}, {0xe0, 0xb1, 0}}, {{0xe0, 0x32, 0}, {0xe0, 0xb2, 0}}, {{0}, {0}}, /*b0*/ - {{0xe0, 0x34, 0}, {0xe0, 0xb4, 0}}, {{0xe0, 0x35, 0}, {0xe0, 0xb5, 0}}, {{0xe0, 0x36, 0}, {0xe0, 0xb6, 0}}, {{0xe0, 0x37, 0}, {0xe0, 0xb7, 0}}, /*b4*/ - {{0xe0, 0x38, 0}, {0xe0, 0xb8, 0}}, {{0}, {0}}, {{0xe0, 0x3a, 0}, {0xe0, 0xba, 0}}, {{0xe0, 0x3b, 0}, {0xe0, 0xbb, 0}}, /*b8*/ - {{0xe0, 0x3c, 0}, {0xe0, 0xbc, 0}}, {{0xe0, 0x3d, 0}, {0xe0, 0xbd, 0}}, {{0xe0, 0x3e, 0}, {0xe0, 0xbe, 0}}, {{0xe0, 0x3f, 0}, {0xe0, 0xbf, 0}}, /*bc*/ - {{0xe0, 0x40, 0}, {0xe0, 0xc0, 0}}, {{0xe0, 0x41, 0}, {0xe0, 0xc1, 0}}, {{0xe0, 0x42, 0}, {0xe0, 0xc2, 0}}, {{0xe0, 0x43, 0}, {0xe0, 0xc3, 0}}, /*c0*/ - {{0xe0, 0x44, 0}, {0xe0, 0xc4, 0}}, {{0}, {0}}, {{0xe0, 0x46, 0}, {0xe0, 0xc6, 0}}, {{0xe0, 0x47, 0}, {0xe0, 0xc7, 0}}, /*c4*/ - {{0xe0, 0x48, 0}, {0xe0, 0xc8, 0}}, {{0xe0, 0x49, 0}, {0xe0, 0xc9, 0}}, {{0}, {0}}, {{0xe0, 0x4b, 0}, {0xe0, 0xcb, 0}}, /*c8*/ - {{0xe0, 0x4c, 0}, {0xe0, 0xcc, 0}}, {{0xe0, 0x4d, 0}, {0xe0, 0xcd, 0}}, {{0xe0, 0x4e, 0}, {0xe0, 0xce, 0}}, {{0xe0, 0x4f, 0}, {0xe0, 0xcf, 0}}, /*cc*/ - {{0xe0, 0x50, 0}, {0xe0, 0xd0, 0}}, {{0xe0, 0x51, 0}, {0xe0, 0xd1, 0}}, {{0xe0, 0x52, 0}, {0xe0, 0xd2, 0}}, {{0xe0, 0x53, 0}, {0xe0, 0xd3, 0}}, /*d0*/ - {{0xd4, 0}, {0}}, {{0xe0, 0x55, 0}, {0xe0, 0xd5, 0}}, {{0}, {0}}, {{0xe0, 0x57, 0}, {0xe0, 0xd7, 0}}, /*d4*/ - {{0xe0, 0x58, 0}, {0xe0, 0xd8, 0}}, {{0xe0, 0x59, 0}, {0xe0, 0xd9, 0}}, {{0xe0, 0x5a, 0}, {0xe0, 0xaa, 0}}, {{0xe0, 0x5b, 0}, {0xe0, 0xdb, 0}}, /*d8*/ - {{0xe0, 0x5c, 0}, {0xe0, 0xdc, 0}}, {{0xe0, 0x5d, 0}, {0xe0, 0xdd, 0}}, {{0xe0, 0x5e, 0}, {0xe0, 0xee, 0}}, {{0xe0, 0x5f, 0}, {0xe0, 0xdf, 0}}, /*dc*/ - {{0}, {0}}, {{0xe0, 0x61, 0}, {0xe0, 0xe1, 0}}, {{0xe0, 0x62, 0}, {0xe0, 0xe2, 0}}, {{0xe0, 0x63, 0}, {0xe0, 0xe3, 0}}, /*e0*/ - {{0xe0, 0x64, 0}, {0xe0, 0xe4, 0}}, {{0xe0, 0x65, 0}, {0xe0, 0xe5, 0}}, {{0xe0, 0x66, 0}, {0xe0, 0xe6, 0}}, {{0xe0, 0x67, 0}, {0xe0, 0xe7, 0}}, /*e4*/ - {{0xe0, 0x68, 0}, {0xe0, 0xe8, 0}}, {{0xe0, 0x69, 0}, {0xe0, 0xe9, 0}}, {{0xe0, 0x6a, 0}, {0xe0, 0xea, 0}}, {{0xe0, 0x6b, 0}, {0xe0, 0xeb, 0}}, /*e8*/ - {{0xe0, 0x6c, 0}, {0xe0, 0xec, 0}}, {{0xe0, 0x6d, 0}, {0xe0, 0xed, 0}}, {{0xe0, 0x6e, 0}, {0xe0, 0xee, 0}}, {{0}, {0}}, /*ec*/ - {{0xe0, 0x70, 0}, {0xe0, 0xf0, 0}}, {{0xf1, 0}, {0}}, {{0xf2, 0}, {0}}, {{0xe0, 0x73, 0}, {0xe0, 0xf3, 0}}, /*f0*/ - {{0xe0, 0x74, 0}, {0xe0, 0xf4, 0}}, {{0xe0, 0x75, 0}, {0xe0, 0xf5, 0}}, {{0}, {0}}, {{0xe0, 0x77, 0}, {0xe0, 0xf7, 0}}, /*f4*/ - {{0xe0, 0x78, 0}, {0xe0, 0xf8, 0}}, {{0xe0, 0x79, 0}, {0xe0, 0xf9, 0}}, {{0xe0, 0x7a, 0}, {0xe0, 0xfa, 0}}, {{0xe0, 0x7b, 0}, {0xe0, 0xfb, 0}}, /*f8*/ - {{0xe0, 0x7c, 0}, {0xe0, 0xfc, 0}}, {{0xe0, 0x7d, 0}, {0xe0, 0xfd, 0}}, {{0xe0, 0x7e, 0}, {0xe0, 0xfe, 0}}, {{0xe1, 0x1d, 0x45, 0xe1, 0x9d, 0xc5, 0}, {0}}, /*fc*/ - {{0}, {0}}, {{0xe0, 0x01, 0}, {0xe0, 0x81, 0}}, {{0xe0, 0x02, 0}, {0xe0, 0x82, 0}}, {{0}, {0}}, /*100*/ - {{0}, {0}}, {{0xe0, 0x05, 0}, {0xe0, 0x85, 0}}, {{0xe0, 0x06, 0}, {0xe0, 0x86, 0}}, {{0xe0, 0x07, 0}, {0xe0, 0x87, 0}}, /*104*/ - {{0xe0, 0x71, 0}, {0xe0, 0xf1, 0}}, {{0xe0, 0x72, 0}, {0xe0, 0xf2, 0}}, {{0xe0, 0x7f, 0}, {0xe0, 0xff, 0}}, {{0xe0, 0xe1, 0}, {0}}, /*108*/ - {{0xe0, 0xee, 0}, {0}}, {{0xe0, 0xf1, 0}, {0}}, {{0xe0, 0xfe, 0}, {0}}, {{0xe0, 0xff, 0}, {0}} /*10c*/ - }; + {{0x80, 0}, {0}}, + {{0x81, 0}, {0}}, + {{0x82, 0}, {0}}, + {{0xe0, 0x03, 0}, {0xe0, 0x83, 0}}, /*80*/ + {{0xe0, 0x04, 0}, {0xe0, 0x84, 0}}, + {{0x85, 0}, {0}}, + {{0x86, 0}, {0}}, + {{0x87, 0}, {0}}, /*84*/ + {{0xe0, 0x08, 0}, {0xe0, 0x88, 0}}, + {{0xe0, 0x09, 0}, {0xe0, 0x89, 0}}, + {{0xe0, 0x0a, 0}, {0xe0, 0x8a, 0}}, + {{0xe0, 0x0b, 0}, {0xe0, 0x8b, 0}}, /*88*/ + {{0xe0, 0x0c, 0}, {0xe0, 0x8c, 0}}, + {{0}, {0}}, + {{0xe0, 0x0e, 0}, {0xe0, 0x8e, 0}}, + {{0xe0, 0x0f, 0}, {0xe0, 0x8f, 0}}, /*8c*/ + {{0xe0, 0x10, 0}, {0xe0, 0x90, 0}}, + {{0xe0, 0x11, 0}, {0xe0, 0x91, 0}}, + {{0xe0, 0x12, 0}, {0xe0, 0x92, 0}}, + {{0xe0, 0x13, 0}, {0xe0, 0x93, 0}}, /*90*/ + {{0xe0, 0x14, 0}, {0xe0, 0x94, 0}}, + {{0xe0, 0x15, 0}, {0xe0, 0x95, 0}}, + {{0xe0, 0x16, 0}, {0xe0, 0x96, 0}}, + {{0xe0, 0x17, 0}, {0xe0, 0x97, 0}}, /*94*/ + {{0xe0, 0x18, 0}, {0xe0, 0x98, 0}}, + {{0xe0, 0x19, 0}, {0xe0, 0x99, 0}}, + {{0xe0, 0x1a, 0}, {0xe0, 0x9a, 0}}, + {{0xe0, 0x1b, 0}, {0xe0, 0x9b, 0}}, /*98*/ + {{0xe0, 0x1c, 0}, {0xe0, 0x9c, 0}}, + {{0xe0, 0x1d, 0}, {0xe0, 0x9d, 0}}, + {{0xe0, 0x1e, 0}, {0xe0, 0x9e, 0}}, + {{0xe0, 0x1f, 0}, {0xe0, 0x9f, 0}}, /*9c*/ + {{0xe0, 0x20, 0}, {0xe0, 0xa0, 0}}, + {{0xe0, 0x21, 0}, {0xe0, 0xa1, 0}}, + {{0xe0, 0x22, 0}, {0xe0, 0xa2, 0}}, + {{0xe0, 0x23, 0}, {0xe0, 0xa3, 0}}, /*a0*/ + {{0xe0, 0x24, 0}, {0xe0, 0xa4, 0}}, + {{0xe0, 0x25, 0}, {0xe0, 0xa5, 0}}, + {{0xe0, 0x26, 0}, {0xe0, 0xa6, 0}}, + {{0}, {0}}, /*a4*/ + {{0}, {0}}, + {{0}, {0}}, + {{0xe0, 0x2a, 0}, {0xe0, 0xaa, 0}}, + {{0}, {0}}, /*a8*/ + {{0xe0, 0x2c, 0}, {0xe0, 0xac, 0}}, + {{0xe0, 0x2d, 0}, {0xe0, 0xad, 0}}, + {{0xe0, 0x2e, 0}, {0xe0, 0xae, 0}}, + {{0xe0, 0x2f, 0}, {0xe0, 0xaf, 0}}, /*ac*/ + {{0xe0, 0x30, 0}, {0xe0, 0xb0, 0}}, + {{0xe0, 0x31, 0}, {0xe0, 0xb1, 0}}, + {{0xe0, 0x32, 0}, {0xe0, 0xb2, 0}}, + {{0}, {0}}, /*b0*/ + {{0xe0, 0x34, 0}, {0xe0, 0xb4, 0}}, + {{0xe0, 0x35, 0}, {0xe0, 0xb5, 0}}, + {{0xe0, 0x36, 0}, {0xe0, 0xb6, 0}}, + {{0xe0, 0x37, 0}, {0xe0, 0xb7, 0}}, /*b4*/ + {{0xe0, 0x38, 0}, {0xe0, 0xb8, 0}}, + {{0}, {0}}, + {{0xe0, 0x3a, 0}, {0xe0, 0xba, 0}}, + {{0xe0, 0x3b, 0}, {0xe0, 0xbb, 0}}, /*b8*/ + {{0xe0, 0x3c, 0}, {0xe0, 0xbc, 0}}, + {{0xe0, 0x3d, 0}, {0xe0, 0xbd, 0}}, + {{0xe0, 0x3e, 0}, {0xe0, 0xbe, 0}}, + {{0xe0, 0x3f, 0}, {0xe0, 0xbf, 0}}, /*bc*/ + {{0xe0, 0x40, 0}, {0xe0, 0xc0, 0}}, + {{0xe0, 0x41, 0}, {0xe0, 0xc1, 0}}, + {{0xe0, 0x42, 0}, {0xe0, 0xc2, 0}}, + {{0xe0, 0x43, 0}, {0xe0, 0xc3, 0}}, /*c0*/ + {{0xe0, 0x44, 0}, {0xe0, 0xc4, 0}}, + {{0}, {0}}, + {{0xe0, 0x46, 0}, {0xe0, 0xc6, 0}}, + {{0xe0, 0x47, 0}, {0xe0, 0xc7, 0}}, /*c4*/ + {{0xe0, 0x48, 0}, {0xe0, 0xc8, 0}}, + {{0xe0, 0x49, 0}, {0xe0, 0xc9, 0}}, + {{0}, {0}}, + {{0xe0, 0x4b, 0}, {0xe0, 0xcb, 0}}, /*c8*/ + {{0xe0, 0x4c, 0}, {0xe0, 0xcc, 0}}, + {{0xe0, 0x4d, 0}, {0xe0, 0xcd, 0}}, + {{0xe0, 0x4e, 0}, {0xe0, 0xce, 0}}, + {{0xe0, 0x4f, 0}, {0xe0, 0xcf, 0}}, /*cc*/ + {{0xe0, 0x50, 0}, {0xe0, 0xd0, 0}}, + {{0xe0, 0x51, 0}, {0xe0, 0xd1, 0}}, + {{0xe0, 0x52, 0}, {0xe0, 0xd2, 0}}, + {{0xe0, 0x53, 0}, {0xe0, 0xd3, 0}}, /*d0*/ + {{0xd4, 0}, {0}}, + {{0xe0, 0x55, 0}, {0xe0, 0xd5, 0}}, + {{0}, {0}}, + {{0xe0, 0x57, 0}, {0xe0, 0xd7, 0}}, /*d4*/ + {{0xe0, 0x58, 0}, {0xe0, 0xd8, 0}}, + {{0xe0, 0x59, 0}, {0xe0, 0xd9, 0}}, + {{0xe0, 0x5a, 0}, {0xe0, 0xaa, 0}}, + {{0xe0, 0x5b, 0}, {0xe0, 0xdb, 0}}, /*d8*/ + {{0xe0, 0x5c, 0}, {0xe0, 0xdc, 0}}, + {{0xe0, 0x5d, 0}, {0xe0, 0xdd, 0}}, + {{0xe0, 0x5e, 0}, {0xe0, 0xee, 0}}, + {{0xe0, 0x5f, 0}, {0xe0, 0xdf, 0}}, /*dc*/ + {{0}, {0}}, + {{0xe0, 0x61, 0}, {0xe0, 0xe1, 0}}, + {{0xe0, 0x62, 0}, {0xe0, 0xe2, 0}}, + {{0xe0, 0x63, 0}, {0xe0, 0xe3, 0}}, /*e0*/ + {{0xe0, 0x64, 0}, {0xe0, 0xe4, 0}}, + {{0xe0, 0x65, 0}, {0xe0, 0xe5, 0}}, + {{0xe0, 0x66, 0}, {0xe0, 0xe6, 0}}, + {{0xe0, 0x67, 0}, {0xe0, 0xe7, 0}}, /*e4*/ + {{0xe0, 0x68, 0}, {0xe0, 0xe8, 0}}, + {{0xe0, 0x69, 0}, {0xe0, 0xe9, 0}}, + {{0xe0, 0x6a, 0}, {0xe0, 0xea, 0}}, + {{0xe0, 0x6b, 0}, {0xe0, 0xeb, 0}}, /*e8*/ + {{0xe0, 0x6c, 0}, {0xe0, 0xec, 0}}, + {{0xe0, 0x6d, 0}, {0xe0, 0xed, 0}}, + {{0xe0, 0x6e, 0}, {0xe0, 0xee, 0}}, + {{0}, {0}}, /*ec*/ + {{0xe0, 0x70, 0}, {0xe0, 0xf0, 0}}, + {{0xf1, 0}, {0}}, + {{0xf2, 0}, {0}}, + {{0xe0, 0x73, 0}, {0xe0, 0xf3, 0}}, /*f0*/ + {{0xe0, 0x74, 0}, {0xe0, 0xf4, 0}}, + {{0xe0, 0x75, 0}, {0xe0, 0xf5, 0}}, + {{0}, {0}}, + {{0xe0, 0x77, 0}, {0xe0, 0xf7, 0}}, /*f4*/ + {{0xe0, 0x78, 0}, {0xe0, 0xf8, 0}}, + {{0xe0, 0x79, 0}, {0xe0, 0xf9, 0}}, + {{0xe0, 0x7a, 0}, {0xe0, 0xfa, 0}}, + {{0xe0, 0x7b, 0}, {0xe0, 0xfb, 0}}, /*f8*/ + {{0xe0, 0x7c, 0}, {0xe0, 0xfc, 0}}, + {{0xe0, 0x7d, 0}, {0xe0, 0xfd, 0}}, + {{0xe0, 0x7e, 0}, {0xe0, 0xfe, 0}}, + {{0xe1, 0x1d, 0x45, 0xe1, 0x9d, 0xc5, 0}, {0}}, /*fc*/ + {{0}, {0}}, + {{0xe0, 0x01, 0}, {0xe0, 0x81, 0}}, + {{0xe0, 0x02, 0}, {0xe0, 0x82, 0}}, + {{0}, {0}}, /*100*/ + {{0}, {0}}, + {{0xe0, 0x05, 0}, {0xe0, 0x85, 0}}, + {{0xe0, 0x06, 0}, {0xe0, 0x86, 0}}, + {{0xe0, 0x07, 0}, {0xe0, 0x87, 0}}, /*104*/ + {{0xe0, 0x71, 0}, {0xe0, 0xf1, 0}}, + {{0xe0, 0x72, 0}, {0xe0, 0xf2, 0}}, + {{0xe0, 0x7f, 0}, {0xe0, 0xff, 0}}, + {{0xe0, 0xe1, 0}, {0}}, /*108*/ + {{0xe0, 0xee, 0}, {0}}, + {{0xe0, 0xf1, 0}, {0}}, + {{0xe0, 0xfe, 0}, {0}}, + {{0xe0, 0xff, 0}, {0}} /*10c*/ +}; /*272 = 256 + 16 fake interim scancodes for disambiguation purposes.*/ -static scancode scancode_set2[272] = - { - {{0}, {0}}, {{0x76, 0}, {0xf0, 0x76, 0}}, {{0x16, 0}, {0xf0, 0x16, 0}}, {{0x1e, 0}, {0xf0, 0x1e, 0}}, - {{0x26, 0}, {0xf0, 0x26, 0}}, {{0x25, 0}, {0xf0, 0x25, 0}}, {{0x2e, 0}, {0xf0, 0x2e, 0}}, {{0x36, 0}, {0xf0, 0x36, 0}}, - {{0x3d, 0}, {0xf0, 0x3d, 0}}, {{0x3e, 0}, {0xf0, 0x3e, 0}}, {{0x46, 0}, {0xf0, 0x46, 0}}, {{0x45, 0}, {0xf0, 0x45, 0}}, - {{0x4e, 0}, {0xf0, 0x4e, 0}}, {{0x55, 0}, {0xf0, 0x55, 0}}, {{0x66, 0}, {0xf0, 0x66, 0}}, {{0x0d, 0}, {0xf0, 0x0d, 0}}, - {{0x15, 0}, {0xf0, 0x15, 0}}, {{0x1d, 0}, {0xf0, 0x1d, 0}}, {{0x24, 0}, {0xf0, 0x24, 0}}, {{0x2d, 0}, {0xf0, 0x2d, 0}}, - {{0x2c, 0}, {0xf0, 0x2c, 0}}, {{0x35, 0}, {0xf0, 0x35, 0}}, {{0x3c, 0}, {0xf0, 0x3c, 0}}, {{0x43, 0}, {0xf0, 0x43, 0}}, - {{0x44, 0}, {0xf0, 0x44, 0}}, {{0x4d, 0}, {0xf0, 0x4d, 0}}, {{0x54, 0}, {0xf0, 0x54, 0}}, {{0x5b, 0}, {0xf0, 0x5b, 0}}, - {{0x5a, 0}, {0xf0, 0x5a, 0}}, {{0x14, 0}, {0xf0, 0x14, 0}}, {{0x1c, 0}, {0xf0, 0x1c, 0}}, {{0x1b, 0}, {0xf0, 0x1b, 0}}, - {{0x23, 0}, {0xf0, 0x23, 0}}, {{0x2b, 0}, {0xf0, 0x2b, 0}}, {{0x34, 0}, {0xf0, 0x34, 0}}, {{0x33, 0}, {0xf0, 0x33, 0}}, - {{0x3b, 0}, {0xf0, 0x3b, 0}}, {{0x42, 0}, {0xf0, 0x42, 0}}, {{0x4b, 0}, {0xf0, 0x4b, 0}}, {{0x4c, 0}, {0xf0, 0x4c, 0}}, - {{0x52, 0}, {0xf0, 0x52, 0}}, {{0x0e, 0}, {0xf0, 0x0e, 0}}, {{0x12, 0}, {0xf0, 0x12, 0}}, {{0x5d, 0}, {0xf0, 0x5d, 0}}, - {{0x1a, 0}, {0xf0, 0x1a, 0}}, {{0x22, 0}, {0xf0, 0x22, 0}}, {{0x21, 0}, {0xf0, 0x21, 0}}, {{0x2a, 0}, {0xf0, 0x2a, 0}}, - {{0x32, 0}, {0xf0, 0x32, 0}}, {{0x31, 0}, {0xf0, 0x31, 0}}, {{0x3a, 0}, {0xf0, 0x3a, 0}}, {{0x41, 0}, {0xf0, 0x41, 0}}, - {{0x49, 0}, {0xf0, 0x49, 0}}, {{0x4a, 0}, {0xf0, 0x4a, 0}}, {{0x59, 0}, {0xf0, 0x59, 0}}, {{0x7c, 0}, {0xf0, 0x7c, 0}}, - {{0x11, 0}, {0xf0, 0x11, 0}}, {{0x29, 0}, {0xf0, 0x29, 0}}, {{0x58, 0}, {0xf0, 0x58, 0}}, {{0x05, 0}, {0xf0, 0x05, 0}}, - {{0x06, 0}, {0xf0, 0x06, 0}}, {{0x04, 0}, {0xf0, 0x04, 0}}, {{0x0c, 0}, {0xf0, 0x0c, 0}}, {{0x03, 0}, {0xf0, 0x03, 0}}, - {{0x0b, 0}, {0xf0, 0x0b, 0}}, {{0x83, 0}, {0xf0, 0x83, 0}}, {{0x0a, 0}, {0xf0, 0x0a, 0}}, {{0x01, 0}, {0xf0, 0x01, 0}}, - {{0x09, 0}, {0xf0, 0x09, 0}}, {{0x77, 0}, {0xf0, 0x77, 0}}, {{0x7e, 0}, {0xf0, 0x7e, 0}}, {{0x6c, 0}, {0xf0, 0x6c, 0}}, - {{0x75, 0}, {0xf0, 0x75, 0}}, {{0x7d, 0}, {0xf0, 0x7d, 0}}, {{0x7b, 0}, {0xf0, 0x7b, 0}}, {{0x6b, 0}, {0xf0, 0x6b, 0}}, - {{0x73, 0}, {0xf0, 0x73, 0}}, {{0x74, 0}, {0xf0, 0x74, 0}}, {{0x79, 0}, {0xf0, 0x79, 0}}, {{0x69, 0}, {0xf0, 0x69, 0}}, - {{0x72, 0}, {0xf0, 0x72, 0}}, {{0x7a, 0}, {0xf0, 0x7a, 0}}, {{0x70, 0}, {0xf0, 0x70, 0}}, {{0x71, 0}, {0xf0, 0x71, 0}}, - {{0x84, 0}, {0xf0, 0x84, 0}}, {{0, 0}, {0, 0}}, {{0x61, 0}, {0xf0, 0x61, 0}}, {{0x78, 0}, {0xf0, 0x78, 0}}, - {{0x07, 0}, {0xf0, 0x07, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{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 scancode scancode_set2[272] = { + {{0}, {0}}, + {{0x76, 0}, {0xf0, 0x76, 0}}, + {{0x16, 0}, {0xf0, 0x16, 0}}, + {{0x1e, 0}, {0xf0, 0x1e, 0}}, + {{0x26, 0}, {0xf0, 0x26, 0}}, + {{0x25, 0}, {0xf0, 0x25, 0}}, + {{0x2e, 0}, {0xf0, 0x2e, 0}}, + {{0x36, 0}, {0xf0, 0x36, 0}}, + {{0x3d, 0}, {0xf0, 0x3d, 0}}, + {{0x3e, 0}, {0xf0, 0x3e, 0}}, + {{0x46, 0}, {0xf0, 0x46, 0}}, + {{0x45, 0}, {0xf0, 0x45, 0}}, + {{0x4e, 0}, {0xf0, 0x4e, 0}}, + {{0x55, 0}, {0xf0, 0x55, 0}}, + {{0x66, 0}, {0xf0, 0x66, 0}}, + {{0x0d, 0}, {0xf0, 0x0d, 0}}, + {{0x15, 0}, {0xf0, 0x15, 0}}, + {{0x1d, 0}, {0xf0, 0x1d, 0}}, + {{0x24, 0}, {0xf0, 0x24, 0}}, + {{0x2d, 0}, {0xf0, 0x2d, 0}}, + {{0x2c, 0}, {0xf0, 0x2c, 0}}, + {{0x35, 0}, {0xf0, 0x35, 0}}, + {{0x3c, 0}, {0xf0, 0x3c, 0}}, + {{0x43, 0}, {0xf0, 0x43, 0}}, + {{0x44, 0}, {0xf0, 0x44, 0}}, + {{0x4d, 0}, {0xf0, 0x4d, 0}}, + {{0x54, 0}, {0xf0, 0x54, 0}}, + {{0x5b, 0}, {0xf0, 0x5b, 0}}, + {{0x5a, 0}, {0xf0, 0x5a, 0}}, + {{0x14, 0}, {0xf0, 0x14, 0}}, + {{0x1c, 0}, {0xf0, 0x1c, 0}}, + {{0x1b, 0}, {0xf0, 0x1b, 0}}, + {{0x23, 0}, {0xf0, 0x23, 0}}, + {{0x2b, 0}, {0xf0, 0x2b, 0}}, + {{0x34, 0}, {0xf0, 0x34, 0}}, + {{0x33, 0}, {0xf0, 0x33, 0}}, + {{0x3b, 0}, {0xf0, 0x3b, 0}}, + {{0x42, 0}, {0xf0, 0x42, 0}}, + {{0x4b, 0}, {0xf0, 0x4b, 0}}, + {{0x4c, 0}, {0xf0, 0x4c, 0}}, + {{0x52, 0}, {0xf0, 0x52, 0}}, + {{0x0e, 0}, {0xf0, 0x0e, 0}}, + {{0x12, 0}, {0xf0, 0x12, 0}}, + {{0x5d, 0}, {0xf0, 0x5d, 0}}, + {{0x1a, 0}, {0xf0, 0x1a, 0}}, + {{0x22, 0}, {0xf0, 0x22, 0}}, + {{0x21, 0}, {0xf0, 0x21, 0}}, + {{0x2a, 0}, {0xf0, 0x2a, 0}}, + {{0x32, 0}, {0xf0, 0x32, 0}}, + {{0x31, 0}, {0xf0, 0x31, 0}}, + {{0x3a, 0}, {0xf0, 0x3a, 0}}, + {{0x41, 0}, {0xf0, 0x41, 0}}, + {{0x49, 0}, {0xf0, 0x49, 0}}, + {{0x4a, 0}, {0xf0, 0x4a, 0}}, + {{0x59, 0}, {0xf0, 0x59, 0}}, + {{0x7c, 0}, {0xf0, 0x7c, 0}}, + {{0x11, 0}, {0xf0, 0x11, 0}}, + {{0x29, 0}, {0xf0, 0x29, 0}}, + {{0x58, 0}, {0xf0, 0x58, 0}}, + {{0x05, 0}, {0xf0, 0x05, 0}}, + {{0x06, 0}, {0xf0, 0x06, 0}}, + {{0x04, 0}, {0xf0, 0x04, 0}}, + {{0x0c, 0}, {0xf0, 0x0c, 0}}, + {{0x03, 0}, {0xf0, 0x03, 0}}, + {{0x0b, 0}, {0xf0, 0x0b, 0}}, + {{0x83, 0}, {0xf0, 0x83, 0}}, + {{0x0a, 0}, {0xf0, 0x0a, 0}}, + {{0x01, 0}, {0xf0, 0x01, 0}}, + {{0x09, 0}, {0xf0, 0x09, 0}}, + {{0x77, 0}, {0xf0, 0x77, 0}}, + {{0x7e, 0}, {0xf0, 0x7e, 0}}, + {{0x6c, 0}, {0xf0, 0x6c, 0}}, + {{0x75, 0}, {0xf0, 0x75, 0}}, + {{0x7d, 0}, {0xf0, 0x7d, 0}}, + {{0x7b, 0}, {0xf0, 0x7b, 0}}, + {{0x6b, 0}, {0xf0, 0x6b, 0}}, + {{0x73, 0}, {0xf0, 0x73, 0}}, + {{0x74, 0}, {0xf0, 0x74, 0}}, + {{0x79, 0}, {0xf0, 0x79, 0}}, + {{0x69, 0}, {0xf0, 0x69, 0}}, + {{0x72, 0}, {0xf0, 0x72, 0}}, + {{0x7a, 0}, {0xf0, 0x7a, 0}}, + {{0x70, 0}, {0xf0, 0x70, 0}}, + {{0x71, 0}, {0xf0, 0x71, 0}}, + {{0x84, 0}, {0xf0, 0x84, 0}}, + {{0, 0}, {0, 0}}, + {{0x61, 0}, {0xf0, 0x61, 0}}, + {{0x78, 0}, {0xf0, 0x78, 0}}, + {{0x07, 0}, {0xf0, 0x07, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0xe0, 0x5a, 0}, {0xe0, 0xf0, 0x5a, 0}}, {{0xe0, 0x14, 0}, {0xe0, 0xf0, 0x14, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0xe0, 0x4a, 0}, {0xe0, 0xf0, 0x4a, 0}}, {{0, 0}, {0, 0}}, {{0xe0, 0x7c, 0}, {0xe0, 0xf0, 0x7c, 0}}, - {{0xe0, 0x11, 0}, {0xe0, 0xf0, 0x11, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0xe0, 0x6c, 0}, {0xe0, 0xf0, 0x6c, 0}}, - {{0xe0, 0x75, 0}, {0xe0, 0xf0, 0x75, 0}}, {{0xe0, 0x7d, 0}, {0xe0, 0xf0, 0x7d, 0}}, {{0, 0}, {0, 0}}, {{0xe0, 0x6b, 0}, {0xe0, 0xf0, 0x6b, 0}}, - {{0, 0}, {0, 0}}, {{0xe0, 0x74, 0}, {0xe0, 0xf0, 0x74, 0}}, {{0, 0}, {0, 0}}, {{0xe0, 0x69, 0}, {0xe0, 0xf0, 0x69, 0}}, - {{0xe0, 0x72, 0}, {0xe0, 0xf0, 0x72, 0}}, {{0xe0, 0x7a, 0}, {0xe0, 0xf0, 0x7a, 0}}, {{0xe0, 0x70, 0}, {0xe0, 0xf0, 0x70, 0}}, {{0xe0, 0x71, 0}, {0xe0, 0xf0, 0x71, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0xe0, 0x1f, 0}, {0xe0, 0xf0, 0x1f, 0}}, - {{0xe0, 0x27, 0}, {0xe0, 0xf0, 0x27, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0xe0, 0x5a, 0}, {0xe0, 0xf0, 0x5a, 0}}, + {{0xe0, 0x14, 0}, {0xe0, 0xf0, 0x14, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0xe0, 0x4a, 0}, {0xe0, 0xf0, 0x4a, 0}}, + {{0, 0}, {0, 0}}, + {{0xe0, 0x7c, 0}, {0xe0, 0xf0, 0x7c, 0}}, + {{0xe0, 0x11, 0}, {0xe0, 0xf0, 0x11, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0xe0, 0x6c, 0}, {0xe0, 0xf0, 0x6c, 0}}, + {{0xe0, 0x75, 0}, {0xe0, 0xf0, 0x75, 0}}, + {{0xe0, 0x7d, 0}, {0xe0, 0xf0, 0x7d, 0}}, + {{0, 0}, {0, 0}}, + {{0xe0, 0x6b, 0}, {0xe0, 0xf0, 0x6b, 0}}, + {{0, 0}, {0, 0}}, + {{0xe0, 0x74, 0}, {0xe0, 0xf0, 0x74, 0}}, + {{0, 0}, {0, 0}}, + {{0xe0, 0x69, 0}, {0xe0, 0xf0, 0x69, 0}}, + {{0xe0, 0x72, 0}, {0xe0, 0xf0, 0x72, 0}}, + {{0xe0, 0x7a, 0}, {0xe0, 0xf0, 0x7a, 0}}, + {{0xe0, 0x70, 0}, {0xe0, 0xf0, 0x70, 0}}, + {{0xe0, 0x71, 0}, {0xe0, 0xf0, 0x71, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0xe0, 0x1f, 0}, {0xe0, 0xf0, 0x1f, 0}}, + {{0xe0, 0x27, 0}, {0xe0, 0xf0, 0x27, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, - {{0}, {0}}, {{0xe0, 0x01, 0}, {0xe0, 0xf0, 0x01, 0}}, {{0xe0, 0x02, 0}, {0xe0, 0xf0, 0x02, 0}}, {{0}, {0}}, /*100*/ - {{0}, {0}}, {{0xe0, 0x05, 0}, {0xe0, 0xf0, 0x15, 0}}, {{0xe0, 0x06, 0}, {0xe0, 0xf0, 0x06, 0}}, {{0xe0, 0x07, 0}, {0xe0, 0xf0, 0x07, 0}}, /*104*/ - {{0xe0, 0x71, 0}, {0xe0, 0xf0, 0x71, 0}}, {{0xe0, 0x72, 0}, {0xe0, 0xf0, 0x72, 0}}, {{0xe0, 0x7f, 0}, {0xe0, 0xf0, 0x7f, 0}}, {{0xe0, 0xe1, 0}, {0}}, /*108*/ - {{0xe0, 0xee, 0}, {0}}, {{0xe0, 0xf1, 0}, {0}}, {{0xe0, 0xfe, 0}, {0}}, {{0xe0, 0xff, 0}, {0}} /*10c*/ - }; + {{0}, {0}}, + {{0xe0, 0x01, 0}, {0xe0, 0xf0, 0x01, 0}}, + {{0xe0, 0x02, 0}, {0xe0, 0xf0, 0x02, 0}}, + {{0}, {0}}, /*100*/ + {{0}, {0}}, + {{0xe0, 0x05, 0}, {0xe0, 0xf0, 0x15, 0}}, + {{0xe0, 0x06, 0}, {0xe0, 0xf0, 0x06, 0}}, + {{0xe0, 0x07, 0}, {0xe0, 0xf0, 0x07, 0}}, /*104*/ + {{0xe0, 0x71, 0}, {0xe0, 0xf0, 0x71, 0}}, + {{0xe0, 0x72, 0}, {0xe0, 0xf0, 0x72, 0}}, + {{0xe0, 0x7f, 0}, {0xe0, 0xf0, 0x7f, 0}}, + {{0xe0, 0xe1, 0}, {0}}, /*108*/ + {{0xe0, 0xee, 0}, {0}}, + {{0xe0, 0xf1, 0}, {0}}, + {{0xe0, 0xfe, 0}, {0}}, + {{0xe0, 0xff, 0}, {0}} /*10c*/ +}; /*272 = 256 + 16 fake interim scancodes for disambiguation purposes.*/ -static scancode scancode_set3[272] = - { - {{0}, {0}}, {{0x76, 0}, {0xf0, 0x76, 0}}, {{0x16, 0}, {0xf0, 0x16, 0}}, {{0x1e, 0}, {0xf0, 0x1e, 0}}, - {{0x26, 0}, {0xf0, 0x26, 0}}, {{0x25, 0}, {0xf0, 0x25, 0}}, {{0x2e, 0}, {0xf0, 0x2e, 0}}, {{0x36, 0}, {0xf0, 0x36, 0}}, - {{0x3d, 0}, {0xf0, 0x3d, 0}}, {{0x3e, 0}, {0xf0, 0x3e, 0}}, {{0x46, 0}, {0xf0, 0x46, 0}}, {{0x45, 0}, {0xf0, 0x45, 0}}, - {{0x4e, 0}, {0xf0, 0x4e, 0}}, {{0x55, 0}, {0xf0, 0x55, 0}}, {{0x66, 0}, {0xf0, 0x66, 0}}, {{0x0d, 0}, {0xf0, 0x0d, 0}}, - {{0x15, 0}, {0xf0, 0x15, 0}}, {{0x1d, 0}, {0xf0, 0x1d, 0}}, {{0x24, 0}, {0xf0, 0x24, 0}}, {{0x2d, 0}, {0xf0, 0x2d, 0}}, - {{0x2c, 0}, {0xf0, 0x2c, 0}}, {{0x35, 0}, {0xf0, 0x35, 0}}, {{0x3c, 0}, {0xf0, 0x3c, 0}}, {{0x43, 0}, {0xf0, 0x43, 0}}, - {{0x44, 0}, {0xf0, 0x44, 0}}, {{0x4d, 0}, {0xf0, 0x4d, 0}}, {{0x54, 0}, {0xf0, 0x54, 0}}, {{0x5b, 0}, {0xf0, 0x5b, 0}}, - {{0x5a, 0}, {0xf0, 0x5a, 0}}, {{0x19, 0}, {0xf0, 0x19, 0}}, {{0x1c, 0}, {0xf0, 0x1c, 0}}, {{0x1b, 0}, {0xf0, 0x1b, 0}}, - {{0x23, 0}, {0xf0, 0x23, 0}}, {{0x2b, 0}, {0xf0, 0x2b, 0}}, {{0x34, 0}, {0xf0, 0x34, 0}}, {{0x33, 0}, {0xf0, 0x33, 0}}, - {{0x3b, 0}, {0xf0, 0x3b, 0}}, {{0x42, 0}, {0xf0, 0x42, 0}}, {{0x4b, 0}, {0xf0, 0x4b, 0}}, {{0x4c, 0}, {0xf0, 0x4c, 0}}, - {{0x52, 0}, {0xf0, 0x52, 0}}, {{0x0e, 0}, {0xf0, 0x0e, 0}}, {{0x12, 0}, {0xf0, 0x12, 0}}, {{0x5c, 0}, {0xf0, 0x5c, 0}}, - {{0x1a, 0}, {0xf0, 0x1a, 0}}, {{0x22, 0}, {0xf0, 0x22, 0}}, {{0x21, 0}, {0xf0, 0x21, 0}}, {{0x2a, 0}, {0xf0, 0x2a, 0}}, - {{0x32, 0}, {0xf0, 0x32, 0}}, {{0x31, 0}, {0xf0, 0x31, 0}}, {{0x3a, 0}, {0xf0, 0x3a, 0}}, {{0x41, 0}, {0xf0, 0x41, 0}}, - {{0x49, 0}, {0xf0, 0x49, 0}}, {{0x4a, 0}, {0xf0, 0x4a, 0}}, {{0x59, 0}, {0xf0, 0x59, 0}}, {{0x7c, 0}, {0xf0, 0x7c, 0}}, - {{0x11, 0}, {0xf0, 0x11, 0}}, {{0x29, 0}, {0xf0, 0x29, 0}}, {{0x14, 0}, {0xf0, 0x14, 0}}, {{0x05, 0}, {0xf0, 0x05, 0}}, - {{0x06, 0}, {0xf0, 0x06, 0}}, {{0x04, 0}, {0xf0, 0x04, 0}}, {{0x0c, 0}, {0xf0, 0x0c, 0}}, {{0x03, 0}, {0xf0, 0x03, 0}}, - {{0x0b, 0}, {0xf0, 0x0b, 0}}, {{0x83, 0}, {0xf0, 0x83, 0}}, {{0x0a, 0}, {0xf0, 0x0a, 0}}, {{0x01, 0}, {0xf0, 0x01, 0}}, - {{0x09, 0}, {0xf0, 0x09, 0}}, {{0x77, 0}, {0xf0, 0x77, 0}}, {{0x7e, 0}, {0xf0, 0x7e, 0}}, {{0x6c, 0}, {0xf0, 0x6c, 0}}, - {{0x75, 0}, {0xf0, 0x75, 0}}, {{0x7d, 0}, {0xf0, 0x7d, 0}}, {{0x7b, 0}, {0xf0, 0x7b, 0}}, {{0x6b, 0}, {0xf0, 0x6b, 0}}, - {{0x73, 0}, {0xf0, 0x73, 0}}, {{0x74, 0}, {0xf0, 0x74, 0}}, {{0x79, 0}, {0xf0, 0x79, 0}}, {{0x69, 0}, {0xf0, 0x69, 0}}, - {{0x72, 0}, {0xf0, 0x72, 0}}, {{0x7a, 0}, {0xf0, 0x7a, 0}}, {{0x70, 0}, {0xf0, 0x70, 0}}, {{0x71, 0}, {0xf0, 0x71, 0}}, - {{0x84, 0}, {0xf0, 0x84, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0x78, 0}, {0xf0, 0x78, 0}}, - {{0x07, 0}, {0xf0, 0x07, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{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 scancode scancode_set3[272] = { + {{0}, {0}}, + {{0x76, 0}, {0xf0, 0x76, 0}}, + {{0x16, 0}, {0xf0, 0x16, 0}}, + {{0x1e, 0}, {0xf0, 0x1e, 0}}, + {{0x26, 0}, {0xf0, 0x26, 0}}, + {{0x25, 0}, {0xf0, 0x25, 0}}, + {{0x2e, 0}, {0xf0, 0x2e, 0}}, + {{0x36, 0}, {0xf0, 0x36, 0}}, + {{0x3d, 0}, {0xf0, 0x3d, 0}}, + {{0x3e, 0}, {0xf0, 0x3e, 0}}, + {{0x46, 0}, {0xf0, 0x46, 0}}, + {{0x45, 0}, {0xf0, 0x45, 0}}, + {{0x4e, 0}, {0xf0, 0x4e, 0}}, + {{0x55, 0}, {0xf0, 0x55, 0}}, + {{0x66, 0}, {0xf0, 0x66, 0}}, + {{0x0d, 0}, {0xf0, 0x0d, 0}}, + {{0x15, 0}, {0xf0, 0x15, 0}}, + {{0x1d, 0}, {0xf0, 0x1d, 0}}, + {{0x24, 0}, {0xf0, 0x24, 0}}, + {{0x2d, 0}, {0xf0, 0x2d, 0}}, + {{0x2c, 0}, {0xf0, 0x2c, 0}}, + {{0x35, 0}, {0xf0, 0x35, 0}}, + {{0x3c, 0}, {0xf0, 0x3c, 0}}, + {{0x43, 0}, {0xf0, 0x43, 0}}, + {{0x44, 0}, {0xf0, 0x44, 0}}, + {{0x4d, 0}, {0xf0, 0x4d, 0}}, + {{0x54, 0}, {0xf0, 0x54, 0}}, + {{0x5b, 0}, {0xf0, 0x5b, 0}}, + {{0x5a, 0}, {0xf0, 0x5a, 0}}, + {{0x19, 0}, {0xf0, 0x19, 0}}, + {{0x1c, 0}, {0xf0, 0x1c, 0}}, + {{0x1b, 0}, {0xf0, 0x1b, 0}}, + {{0x23, 0}, {0xf0, 0x23, 0}}, + {{0x2b, 0}, {0xf0, 0x2b, 0}}, + {{0x34, 0}, {0xf0, 0x34, 0}}, + {{0x33, 0}, {0xf0, 0x33, 0}}, + {{0x3b, 0}, {0xf0, 0x3b, 0}}, + {{0x42, 0}, {0xf0, 0x42, 0}}, + {{0x4b, 0}, {0xf0, 0x4b, 0}}, + {{0x4c, 0}, {0xf0, 0x4c, 0}}, + {{0x52, 0}, {0xf0, 0x52, 0}}, + {{0x0e, 0}, {0xf0, 0x0e, 0}}, + {{0x12, 0}, {0xf0, 0x12, 0}}, + {{0x5c, 0}, {0xf0, 0x5c, 0}}, + {{0x1a, 0}, {0xf0, 0x1a, 0}}, + {{0x22, 0}, {0xf0, 0x22, 0}}, + {{0x21, 0}, {0xf0, 0x21, 0}}, + {{0x2a, 0}, {0xf0, 0x2a, 0}}, + {{0x32, 0}, {0xf0, 0x32, 0}}, + {{0x31, 0}, {0xf0, 0x31, 0}}, + {{0x3a, 0}, {0xf0, 0x3a, 0}}, + {{0x41, 0}, {0xf0, 0x41, 0}}, + {{0x49, 0}, {0xf0, 0x49, 0}}, + {{0x4a, 0}, {0xf0, 0x4a, 0}}, + {{0x59, 0}, {0xf0, 0x59, 0}}, + {{0x7c, 0}, {0xf0, 0x7c, 0}}, + {{0x11, 0}, {0xf0, 0x11, 0}}, + {{0x29, 0}, {0xf0, 0x29, 0}}, + {{0x14, 0}, {0xf0, 0x14, 0}}, + {{0x05, 0}, {0xf0, 0x05, 0}}, + {{0x06, 0}, {0xf0, 0x06, 0}}, + {{0x04, 0}, {0xf0, 0x04, 0}}, + {{0x0c, 0}, {0xf0, 0x0c, 0}}, + {{0x03, 0}, {0xf0, 0x03, 0}}, + {{0x0b, 0}, {0xf0, 0x0b, 0}}, + {{0x83, 0}, {0xf0, 0x83, 0}}, + {{0x0a, 0}, {0xf0, 0x0a, 0}}, + {{0x01, 0}, {0xf0, 0x01, 0}}, + {{0x09, 0}, {0xf0, 0x09, 0}}, + {{0x77, 0}, {0xf0, 0x77, 0}}, + {{0x7e, 0}, {0xf0, 0x7e, 0}}, + {{0x6c, 0}, {0xf0, 0x6c, 0}}, + {{0x75, 0}, {0xf0, 0x75, 0}}, + {{0x7d, 0}, {0xf0, 0x7d, 0}}, + {{0x7b, 0}, {0xf0, 0x7b, 0}}, + {{0x6b, 0}, {0xf0, 0x6b, 0}}, + {{0x73, 0}, {0xf0, 0x73, 0}}, + {{0x74, 0}, {0xf0, 0x74, 0}}, + {{0x79, 0}, {0xf0, 0x79, 0}}, + {{0x69, 0}, {0xf0, 0x69, 0}}, + {{0x72, 0}, {0xf0, 0x72, 0}}, + {{0x7a, 0}, {0xf0, 0x7a, 0}}, + {{0x70, 0}, {0xf0, 0x70, 0}}, + {{0x71, 0}, {0xf0, 0x71, 0}}, + {{0x84, 0}, {0xf0, 0x84, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0x78, 0}, {0xf0, 0x78, 0}}, + {{0x07, 0}, {0xf0, 0x07, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0x79, 0}, {0xf0, 0x79, 0}}, {{0x58, 0}, {0xf0, 0x58, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0x77, 0}, {0xf0, 0x77, 0}}, {{0, 0}, {0, 0}}, {{0x57, 0}, {0xf0, 0x57, 0}}, - {{0x39, 0}, {0xf0, 0x39, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0x6e, 0}, {0xf0, 0x6e, 0}}, - {{0x63, 0}, {0xf0, 0x63, 0}}, {{0x6f, 0}, {0xf0, 0x6f, 0}}, {{0, 0}, {0, 0}}, {{0x61, 0}, {0xf0, 0x61, 0}}, - {{0, 0}, {0, 0}}, {{0x6a, 0}, {0xf0, 0x6a, 0}}, {{0, 0}, {0, 0}}, {{0x65, 0}, {0xf0, 0x65, 0}}, - {{0x60, 0}, {0xf0, 0x60, 0}}, {{0x6d, 0}, {0xf0, 0x6d, 0}}, {{0x67, 0}, {0xf0, 0x67, 0}}, {{0x64, 0}, {0xf0, 0x64, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0x8b, 0}, {0xf0, 0x8b, 0}}, - {{0x8c, 0}, {0xf0, 0x8c, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0x79, 0}, {0xf0, 0x79, 0}}, + {{0x58, 0}, {0xf0, 0x58, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0x77, 0}, {0xf0, 0x77, 0}}, + {{0, 0}, {0, 0}}, + {{0x57, 0}, {0xf0, 0x57, 0}}, + {{0x39, 0}, {0xf0, 0x39, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0x6e, 0}, {0xf0, 0x6e, 0}}, + {{0x63, 0}, {0xf0, 0x63, 0}}, + {{0x6f, 0}, {0xf0, 0x6f, 0}}, + {{0, 0}, {0, 0}}, + {{0x61, 0}, {0xf0, 0x61, 0}}, + {{0, 0}, {0, 0}}, + {{0x6a, 0}, {0xf0, 0x6a, 0}}, + {{0, 0}, {0, 0}}, + {{0x65, 0}, {0xf0, 0x65, 0}}, + {{0x60, 0}, {0xf0, 0x60, 0}}, + {{0x6d, 0}, {0xf0, 0x6d, 0}}, + {{0x67, 0}, {0xf0, 0x67, 0}}, + {{0x64, 0}, {0xf0, 0x64, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0x8b, 0}, {0xf0, 0x8b, 0}}, + {{0x8c, 0}, {0xf0, 0x8c, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, {{0, 0}, {0, 0}}, - }; + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, + {{0, 0}, {0, 0}}, +}; /*XT keyboard has no escape scancodes, and no scancodes beyond 53*/ -static scancode scancode_xt[272] = - { - {{0}, {0}}, {{0x01, 0}, {0x81, 0}}, {{0x02, 0}, {0x82, 0}}, {{0x03, 0}, {0x83, 0}}, - {{0x04, 0}, {0x84, 0}}, {{0x05, 0}, {0x85, 0}}, {{0x06, 0}, {0x86, 0}}, {{0x07, 0}, {0x87, 0}}, - {{0x08, 0}, {0x88, 0}}, {{0x09, 0}, {0x89, 0}}, {{0x0a, 0}, {0x8a, 0}}, {{0x0b, 0}, {0x8b, 0}}, - {{0x0c, 0}, {0x8c, 0}}, {{0x0d, 0}, {0x8d, 0}}, {{0x0e, 0}, {0x8e, 0}}, {{0x0f, 0}, {0x8f, 0}}, - {{0x10, 0}, {0x90, 0}}, {{0x11, 0}, {0x91, 0}}, {{0x12, 0}, {0x92, 0}}, {{0x13, 0}, {0x93, 0}}, - {{0x14, 0}, {0x94, 0}}, {{0x15, 0}, {0x95, 0}}, {{0x16, 0}, {0x96, 0}}, {{0x17, 0}, {0x97, 0}}, - {{0x18, 0}, {0x98, 0}}, {{0x19, 0}, {0x99, 0}}, {{0x1a, 0}, {0x9a, 0}}, {{0x1b, 0}, {0x9b, 0}}, - {{0x1c, 0}, {0x9c, 0}}, {{0x1d, 0}, {0x9d, 0}}, {{0x1e, 0}, {0x9e, 0}}, {{0x1f, 0}, {0x9f, 0}}, - {{0x20, 0}, {0xa0, 0}}, {{0x21, 0}, {0xa1, 0}}, {{0x22, 0}, {0xa2, 0}}, {{0x23, 0}, {0xa3, 0}}, - {{0x24, 0}, {0xa4, 0}}, {{0x25, 0}, {0xa5, 0}}, {{0x26, 0}, {0xa6, 0}}, {{0x27, 0}, {0xa7, 0}}, - {{0x28, 0}, {0xa8, 0}}, {{0x29, 0}, {0xa9, 0}}, {{0x2a, 0}, {0xaa, 0}}, {{0x2b, 0}, {0xab, 0}}, - {{0x2c, 0}, {0xac, 0}}, {{0x2d, 0}, {0xad, 0}}, {{0x2e, 0}, {0xae, 0}}, {{0x2f, 0}, {0xaf, 0}}, - {{0x30, 0}, {0xb0, 0}}, {{0x31, 0}, {0xb1, 0}}, {{0x32, 0}, {0xb2, 0}}, {{0x33, 0}, {0xb3, 0}}, - {{0x34, 0}, {0xb4, 0}}, {{0x35, 0}, {0xb5, 0}}, {{0x36, 0}, {0xb6, 0}}, {{0x37, 0}, {0xb7, 0}}, - {{0x38, 0}, {0xb8, 0}}, {{0x39, 0}, {0xb9, 0}}, {{0x3a, 0}, {0xba, 0}}, {{0x3b, 0}, {0xbb, 0}}, - {{0x3c, 0}, {0xbc, 0}}, {{0x3d, 0}, {0xbd, 0}}, {{0x3e, 0}, {0xbe, 0}}, {{0x3f, 0}, {0xbf, 0}}, - {{0x40, 0}, {0xc0, 0}}, {{0x41, 0}, {0xc1, 0}}, {{0x42, 0}, {0xc2, 0}}, {{0x43, 0}, {0xc3, 0}}, - {{0x44, 0}, {0xc4, 0}}, {{0x45, 0}, {0xc5, 0}}, {{0x46, 0}, {0xc6, 0}}, {{0x47, 0}, {0xc7, 0}}, - {{0x48, 0}, {0xc8, 0}}, {{0x49, 0}, {0xc9, 0}}, {{0x4a, 0}, {0xca, 0}}, {{0x4b, 0}, {0xcb, 0}}, - {{0x4c, 0}, {0xcc, 0}}, {{0x4d, 0}, {0xcd, 0}}, {{0x4e, 0}, {0xce, 0}}, {{0x4f, 0}, {0xcf, 0}}, - {{0x50, 0}, {0xd0, 0}}, {{0x51, 0}, {0xd1, 0}}, {{0x52, 0}, {0xd2, 0}}, {{0x53, 0}, {0xd3, 0}}, - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*54*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*58*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*5c*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*60*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*64*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*68*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*6c*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*70*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*74*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*78*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*7c*/ +static scancode scancode_xt[272] = { + {{0}, {0}}, + {{0x01, 0}, {0x81, 0}}, + {{0x02, 0}, {0x82, 0}}, + {{0x03, 0}, {0x83, 0}}, + {{0x04, 0}, {0x84, 0}}, + {{0x05, 0}, {0x85, 0}}, + {{0x06, 0}, {0x86, 0}}, + {{0x07, 0}, {0x87, 0}}, + {{0x08, 0}, {0x88, 0}}, + {{0x09, 0}, {0x89, 0}}, + {{0x0a, 0}, {0x8a, 0}}, + {{0x0b, 0}, {0x8b, 0}}, + {{0x0c, 0}, {0x8c, 0}}, + {{0x0d, 0}, {0x8d, 0}}, + {{0x0e, 0}, {0x8e, 0}}, + {{0x0f, 0}, {0x8f, 0}}, + {{0x10, 0}, {0x90, 0}}, + {{0x11, 0}, {0x91, 0}}, + {{0x12, 0}, {0x92, 0}}, + {{0x13, 0}, {0x93, 0}}, + {{0x14, 0}, {0x94, 0}}, + {{0x15, 0}, {0x95, 0}}, + {{0x16, 0}, {0x96, 0}}, + {{0x17, 0}, {0x97, 0}}, + {{0x18, 0}, {0x98, 0}}, + {{0x19, 0}, {0x99, 0}}, + {{0x1a, 0}, {0x9a, 0}}, + {{0x1b, 0}, {0x9b, 0}}, + {{0x1c, 0}, {0x9c, 0}}, + {{0x1d, 0}, {0x9d, 0}}, + {{0x1e, 0}, {0x9e, 0}}, + {{0x1f, 0}, {0x9f, 0}}, + {{0x20, 0}, {0xa0, 0}}, + {{0x21, 0}, {0xa1, 0}}, + {{0x22, 0}, {0xa2, 0}}, + {{0x23, 0}, {0xa3, 0}}, + {{0x24, 0}, {0xa4, 0}}, + {{0x25, 0}, {0xa5, 0}}, + {{0x26, 0}, {0xa6, 0}}, + {{0x27, 0}, {0xa7, 0}}, + {{0x28, 0}, {0xa8, 0}}, + {{0x29, 0}, {0xa9, 0}}, + {{0x2a, 0}, {0xaa, 0}}, + {{0x2b, 0}, {0xab, 0}}, + {{0x2c, 0}, {0xac, 0}}, + {{0x2d, 0}, {0xad, 0}}, + {{0x2e, 0}, {0xae, 0}}, + {{0x2f, 0}, {0xaf, 0}}, + {{0x30, 0}, {0xb0, 0}}, + {{0x31, 0}, {0xb1, 0}}, + {{0x32, 0}, {0xb2, 0}}, + {{0x33, 0}, {0xb3, 0}}, + {{0x34, 0}, {0xb4, 0}}, + {{0x35, 0}, {0xb5, 0}}, + {{0x36, 0}, {0xb6, 0}}, + {{0x37, 0}, {0xb7, 0}}, + {{0x38, 0}, {0xb8, 0}}, + {{0x39, 0}, {0xb9, 0}}, + {{0x3a, 0}, {0xba, 0}}, + {{0x3b, 0}, {0xbb, 0}}, + {{0x3c, 0}, {0xbc, 0}}, + {{0x3d, 0}, {0xbd, 0}}, + {{0x3e, 0}, {0xbe, 0}}, + {{0x3f, 0}, {0xbf, 0}}, + {{0x40, 0}, {0xc0, 0}}, + {{0x41, 0}, {0xc1, 0}}, + {{0x42, 0}, {0xc2, 0}}, + {{0x43, 0}, {0xc3, 0}}, + {{0x44, 0}, {0xc4, 0}}, + {{0x45, 0}, {0xc5, 0}}, + {{0x46, 0}, {0xc6, 0}}, + {{0x47, 0}, {0xc7, 0}}, + {{0x48, 0}, {0xc8, 0}}, + {{0x49, 0}, {0xc9, 0}}, + {{0x4a, 0}, {0xca, 0}}, + {{0x4b, 0}, {0xcb, 0}}, + {{0x4c, 0}, {0xcc, 0}}, + {{0x4d, 0}, {0xcd, 0}}, + {{0x4e, 0}, {0xce, 0}}, + {{0x4f, 0}, {0xcf, 0}}, + {{0x50, 0}, {0xd0, 0}}, + {{0x51, 0}, {0xd1, 0}}, + {{0x52, 0}, {0xd2, 0}}, + {{0x53, 0}, {0xd3, 0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*54*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*58*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*5c*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*60*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*64*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*68*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*6c*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*70*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*74*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*78*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*7c*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*80*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*84*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*88*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*8c*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*90*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*94*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*98*/ - {{0x1c, 0}, {0x9c, 0}}, {{0x1d, 0}, {0x9d, 0}}, {{0}, {0}}, {{0}, {0}}, /*9c*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*a0*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*a4*/ - {{0}, {0}}, {{0}, {0}}, {{0x2a, 0}, {0xaa, 0}}, {{0}, {0}}, /*a8*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*ac*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*b0*/ - {{0}, {0}}, {{0x35, 0}, {0xb5, 0}}, {{0x36, 0}, {0xb6, 0}}, {{0x37, 0}, {0xb7, 0}}, /*b4*/ - {{0x38, 0}, {0xb8, 0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*b8*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*bc*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*c0*/ - {{0}, {0}}, {{0}, {0}}, {{0x46, 0}, {0xc6, 0}}, {{0x47, 0}, {0xc7, 0}}, /*c4*/ - {{0x48, 0}, {0xc8, 0}}, {{0x49, 0}, {0xc9, 0}}, {{0}, {0}}, {{0x4b, 0}, {0xcb, 0}}, /*c8*/ - {{0}, {0}}, {{0x4d, 0}, {0xcd, 0}}, {{0}, {0}}, {{0x4f, 0}, {0xcf, 0}}, /*cc*/ - {{0x50, 0}, {0xd0, 0}}, {{0x51, 0}, {0xd1, 0}}, {{0x52, 0}, {0xd2, 0}}, {{0x53, 0}, {0xd3, 0}}, /*d0*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*d4*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*d8*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*dc*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*e0*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*e4*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*e8*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*ec*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*f0*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*f4*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*f8*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*fc*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*100*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*104*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*108*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*10c*/ - }; + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*80*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*84*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*88*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*8c*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*90*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*94*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*98*/ + {{0x1c, 0}, {0x9c, 0}}, + {{0x1d, 0}, {0x9d, 0}}, + {{0}, {0}}, + {{0}, {0}}, /*9c*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*a0*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*a4*/ + {{0}, {0}}, + {{0}, {0}}, + {{0x2a, 0}, {0xaa, 0}}, + {{0}, {0}}, /*a8*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*ac*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*b0*/ + {{0}, {0}}, + {{0x35, 0}, {0xb5, 0}}, + {{0x36, 0}, {0xb6, 0}}, + {{0x37, 0}, {0xb7, 0}}, /*b4*/ + {{0x38, 0}, {0xb8, 0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*b8*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*bc*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*c0*/ + {{0}, {0}}, + {{0}, {0}}, + {{0x46, 0}, {0xc6, 0}}, + {{0x47, 0}, {0xc7, 0}}, /*c4*/ + {{0x48, 0}, {0xc8, 0}}, + {{0x49, 0}, {0xc9, 0}}, + {{0}, {0}}, + {{0x4b, 0}, {0xcb, 0}}, /*c8*/ + {{0}, {0}}, + {{0x4d, 0}, {0xcd, 0}}, + {{0}, {0}}, + {{0x4f, 0}, {0xcf, 0}}, /*cc*/ + {{0x50, 0}, {0xd0, 0}}, + {{0x51, 0}, {0xd1, 0}}, + {{0x52, 0}, {0xd2, 0}}, + {{0x53, 0}, {0xd3, 0}}, /*d0*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*d4*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*d8*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*dc*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*e0*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*e4*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*e8*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*ec*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*f0*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*f4*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*f8*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*fc*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*100*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*104*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*108*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*10c*/ +}; /*Tandy keyboard has slightly different scancodes to XT*/ -static scancode scancode_tandy[272] = - { - {{0}, {0}}, {{0x01, 0}, {0x81, 0}}, {{0x02, 0}, {0x82, 0}}, {{0x03, 0}, {0x83, 0}}, - {{0x04, 0}, {0x84, 0}}, {{0x05, 0}, {0x85, 0}}, {{0x06, 0}, {0x86, 0}}, {{0x07, 0}, {0x87, 0}}, - {{0x08, 0}, {0x88, 0}}, {{0x09, 0}, {0x89, 0}}, {{0x0a, 0}, {0x8a, 0}}, {{0x0b, 0}, {0x8b, 0}}, - {{0x0c, 0}, {0x8c, 0}}, {{0x0d, 0}, {0x8d, 0}}, {{0x0e, 0}, {0x8e, 0}}, {{0x0f, 0}, {0x8f, 0}}, - {{0x10, 0}, {0x90, 0}}, {{0x11, 0}, {0x91, 0}}, {{0x12, 0}, {0x92, 0}}, {{0x13, 0}, {0x93, 0}}, - {{0x14, 0}, {0x94, 0}}, {{0x15, 0}, {0x95, 0}}, {{0x16, 0}, {0x96, 0}}, {{0x17, 0}, {0x97, 0}}, - {{0x18, 0}, {0x98, 0}}, {{0x19, 0}, {0x99, 0}}, {{0x1a, 0}, {0x9a, 0}}, {{0x1b, 0}, {0x9b, 0}}, - {{0x1c, 0}, {0x9c, 0}}, {{0x1d, 0}, {0x9d, 0}}, {{0x1e, 0}, {0x9e, 0}}, {{0x1f, 0}, {0x9f, 0}}, - {{0x20, 0}, {0xa0, 0}}, {{0x21, 0}, {0xa1, 0}}, {{0x22, 0}, {0xa2, 0}}, {{0x23, 0}, {0xa3, 0}}, - {{0x24, 0}, {0xa4, 0}}, {{0x25, 0}, {0xa5, 0}}, {{0x26, 0}, {0xa6, 0}}, {{0x27, 0}, {0xa7, 0}}, - {{0x28, 0}, {0xa8, 0}}, {{0x29, 0}, {0xa9, 0}}, {{0x2a, 0}, {0xaa, 0}}, {{0x47, 0}, {0xc7, 0}}, - {{0x2c, 0}, {0xac, 0}}, {{0x2d, 0}, {0xad, 0}}, {{0x2e, 0}, {0xae, 0}}, {{0x2f, 0}, {0xaf, 0}}, - {{0x30, 0}, {0xb0, 0}}, {{0x31, 0}, {0xb1, 0}}, {{0x32, 0}, {0xb2, 0}}, {{0x33, 0}, {0xb3, 0}}, - {{0x34, 0}, {0xb4, 0}}, {{0x35, 0}, {0xb5, 0}}, {{0x36, 0}, {0xb6, 0}}, {{0x37, 0}, {0xb7, 0}}, - {{0x38, 0}, {0xb8, 0}}, {{0x39, 0}, {0xb9, 0}}, {{0x3a, 0}, {0xba, 0}}, {{0x3b, 0}, {0xbb, 0}}, - {{0x3c, 0}, {0xbc, 0}}, {{0x3d, 0}, {0xbd, 0}}, {{0x3e, 0}, {0xbe, 0}}, {{0x3f, 0}, {0xbf, 0}}, - {{0x40, 0}, {0xc0, 0}}, {{0x41, 0}, {0xc1, 0}}, {{0x42, 0}, {0xc2, 0}}, {{0x43, 0}, {0xc3, 0}}, - {{0x44, 0}, {0xc4, 0}}, {{0x45, 0}, {0xc5, 0}}, {{0x46, 0}, {0xc6, 0}}, {{0x47, 0}, {0xc7, 0}}, - {{0x48, 0}, {0xc8, 0}}, {{0x49, 0}, {0xc9, 0}}, {{0x4a, 0}, {0xca, 0}}, {{0x4b, 0}, {0xcb, 0}}, - {{0x4c, 0}, {0xcc, 0}}, {{0x4d, 0}, {0xcd, 0}}, {{0x4e, 0}, {0xce, 0}}, {{0x4f, 0}, {0xcf, 0}}, - {{0x50, 0}, {0xd0, 0}}, {{0x51, 0}, {0xd1, 0}}, {{0x52, 0}, {0xd2, 0}}, {{0x56, 0}, {0xd6, 0}}, - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*54*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*58*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*5c*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*60*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*64*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*68*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*6c*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*70*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*74*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*78*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*7c*/ +static scancode scancode_tandy[272] = { + {{0}, {0}}, + {{0x01, 0}, {0x81, 0}}, + {{0x02, 0}, {0x82, 0}}, + {{0x03, 0}, {0x83, 0}}, + {{0x04, 0}, {0x84, 0}}, + {{0x05, 0}, {0x85, 0}}, + {{0x06, 0}, {0x86, 0}}, + {{0x07, 0}, {0x87, 0}}, + {{0x08, 0}, {0x88, 0}}, + {{0x09, 0}, {0x89, 0}}, + {{0x0a, 0}, {0x8a, 0}}, + {{0x0b, 0}, {0x8b, 0}}, + {{0x0c, 0}, {0x8c, 0}}, + {{0x0d, 0}, {0x8d, 0}}, + {{0x0e, 0}, {0x8e, 0}}, + {{0x0f, 0}, {0x8f, 0}}, + {{0x10, 0}, {0x90, 0}}, + {{0x11, 0}, {0x91, 0}}, + {{0x12, 0}, {0x92, 0}}, + {{0x13, 0}, {0x93, 0}}, + {{0x14, 0}, {0x94, 0}}, + {{0x15, 0}, {0x95, 0}}, + {{0x16, 0}, {0x96, 0}}, + {{0x17, 0}, {0x97, 0}}, + {{0x18, 0}, {0x98, 0}}, + {{0x19, 0}, {0x99, 0}}, + {{0x1a, 0}, {0x9a, 0}}, + {{0x1b, 0}, {0x9b, 0}}, + {{0x1c, 0}, {0x9c, 0}}, + {{0x1d, 0}, {0x9d, 0}}, + {{0x1e, 0}, {0x9e, 0}}, + {{0x1f, 0}, {0x9f, 0}}, + {{0x20, 0}, {0xa0, 0}}, + {{0x21, 0}, {0xa1, 0}}, + {{0x22, 0}, {0xa2, 0}}, + {{0x23, 0}, {0xa3, 0}}, + {{0x24, 0}, {0xa4, 0}}, + {{0x25, 0}, {0xa5, 0}}, + {{0x26, 0}, {0xa6, 0}}, + {{0x27, 0}, {0xa7, 0}}, + {{0x28, 0}, {0xa8, 0}}, + {{0x29, 0}, {0xa9, 0}}, + {{0x2a, 0}, {0xaa, 0}}, + {{0x47, 0}, {0xc7, 0}}, + {{0x2c, 0}, {0xac, 0}}, + {{0x2d, 0}, {0xad, 0}}, + {{0x2e, 0}, {0xae, 0}}, + {{0x2f, 0}, {0xaf, 0}}, + {{0x30, 0}, {0xb0, 0}}, + {{0x31, 0}, {0xb1, 0}}, + {{0x32, 0}, {0xb2, 0}}, + {{0x33, 0}, {0xb3, 0}}, + {{0x34, 0}, {0xb4, 0}}, + {{0x35, 0}, {0xb5, 0}}, + {{0x36, 0}, {0xb6, 0}}, + {{0x37, 0}, {0xb7, 0}}, + {{0x38, 0}, {0xb8, 0}}, + {{0x39, 0}, {0xb9, 0}}, + {{0x3a, 0}, {0xba, 0}}, + {{0x3b, 0}, {0xbb, 0}}, + {{0x3c, 0}, {0xbc, 0}}, + {{0x3d, 0}, {0xbd, 0}}, + {{0x3e, 0}, {0xbe, 0}}, + {{0x3f, 0}, {0xbf, 0}}, + {{0x40, 0}, {0xc0, 0}}, + {{0x41, 0}, {0xc1, 0}}, + {{0x42, 0}, {0xc2, 0}}, + {{0x43, 0}, {0xc3, 0}}, + {{0x44, 0}, {0xc4, 0}}, + {{0x45, 0}, {0xc5, 0}}, + {{0x46, 0}, {0xc6, 0}}, + {{0x47, 0}, {0xc7, 0}}, + {{0x48, 0}, {0xc8, 0}}, + {{0x49, 0}, {0xc9, 0}}, + {{0x4a, 0}, {0xca, 0}}, + {{0x4b, 0}, {0xcb, 0}}, + {{0x4c, 0}, {0xcc, 0}}, + {{0x4d, 0}, {0xcd, 0}}, + {{0x4e, 0}, {0xce, 0}}, + {{0x4f, 0}, {0xcf, 0}}, + {{0x50, 0}, {0xd0, 0}}, + {{0x51, 0}, {0xd1, 0}}, + {{0x52, 0}, {0xd2, 0}}, + {{0x56, 0}, {0xd6, 0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*54*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*58*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*5c*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*60*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*64*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*68*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*6c*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*70*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*74*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*78*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*7c*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*80*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*84*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*88*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*8c*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*90*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*94*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*98*/ - {{0x57, 0}, {0xd7, 0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*9c*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*a0*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*a4*/ - {{0}, {0}}, {{0}, {0}}, {{0x2a, 0}, {0xaa, 0}}, {{0}, {0}}, /*a8*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*ac*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*b0*/ - {{0}, {0}}, {{0x35, 0}, {0xb5, 0}}, {{0x36, 0}, {0xb6, 0}}, {{0x37, 0}, {0xb7, 0}}, /*b4*/ - {{0x38, 0}, {0xb8, 0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*b8*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*bc*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*c0*/ - {{0}, {0}}, {{0}, {0}}, {{0x46, 0}, {0xc6, 0}}, {{0x47, 0}, {0xc7, 0}}, /*c4*/ - {{0x29, 0}, {0xa9, 0}}, {{0x49, 0}, {0xc9, 0}}, {{0}, {0}}, {{0x2b, 0}, {0xab, 0}}, /*c8*/ - {{0}, {0}}, {{0x4e, 0}, {0xce, 0}}, {{0}, {0}}, {{0x4f, 0}, {0xcf, 0}}, /*cc*/ - {{0x4a, 0}, {0xca, 0}}, {{0x51, 0}, {0xd1, 0}}, {{0x52, 0}, {0xd2, 0}}, {{0x53, 0}, {0xd3, 0}}, /*d0*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*d4*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*d8*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*dc*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*e0*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*e4*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*e8*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*ec*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*f0*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*f4*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*f8*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*fc*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*100*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*104*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*108*/ - {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, {{0}, {0}}, /*10c*/ - }; + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*80*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*84*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*88*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*8c*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*90*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*94*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*98*/ + {{0x57, 0}, {0xd7, 0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*9c*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*a0*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*a4*/ + {{0}, {0}}, + {{0}, {0}}, + {{0x2a, 0}, {0xaa, 0}}, + {{0}, {0}}, /*a8*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*ac*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*b0*/ + {{0}, {0}}, + {{0x35, 0}, {0xb5, 0}}, + {{0x36, 0}, {0xb6, 0}}, + {{0x37, 0}, {0xb7, 0}}, /*b4*/ + {{0x38, 0}, {0xb8, 0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*b8*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*bc*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*c0*/ + {{0}, {0}}, + {{0}, {0}}, + {{0x46, 0}, {0xc6, 0}}, + {{0x47, 0}, {0xc7, 0}}, /*c4*/ + {{0x29, 0}, {0xa9, 0}}, + {{0x49, 0}, {0xc9, 0}}, + {{0}, {0}}, + {{0x2b, 0}, {0xab, 0}}, /*c8*/ + {{0}, {0}}, + {{0x4e, 0}, {0xce, 0}}, + {{0}, {0}}, + {{0x4f, 0}, {0xcf, 0}}, /*cc*/ + {{0x4a, 0}, {0xca, 0}}, + {{0x51, 0}, {0xd1, 0}}, + {{0x52, 0}, {0xd2, 0}}, + {{0x53, 0}, {0xd3, 0}}, /*d0*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*d4*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*d8*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*dc*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*e0*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*e4*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*e8*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*ec*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*f0*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*f4*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*f8*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*fc*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*100*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*104*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*108*/ + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, + {{0}, {0}}, /*10c*/ +}; static uint8_t oldkey[272]; static uint8_t keydelay[272]; @@ -390,78 +1405,82 @@ int keyboard_scan = 1; static scancode *at_scancodes; void keyboard_set_scancode_set(int set) { - switch (set) { - case SCANCODE_SET_1:at_scancodes = scancode_set1; - break; - case SCANCODE_SET_2:at_scancodes = scancode_set2; - break; - case SCANCODE_SET_3:at_scancodes = scancode_set3; - break; - default:pclog("Invalid scancode set: %i\n", set); - } + switch (set) { + case SCANCODE_SET_1: + at_scancodes = scancode_set1; + break; + case SCANCODE_SET_2: + at_scancodes = scancode_set2; + break; + case SCANCODE_SET_3: + at_scancodes = scancode_set3; + break; + default: + pclog("Invalid scancode set: %i\n", set); + } } void keyboard_process() { - int c; - int d; - scancode *scancodes = (AT || romset == ROM_XI8088) ? at_scancodes : scancode_xt; - if (!keyboard_scan) - return; - if (TANDY) - scancodes = scancode_tandy; + int c; + int d; + scancode *scancodes = (AT || romset == ROM_XI8088) ? at_scancodes : scancode_xt; + if (!keyboard_scan) + return; + if (TANDY) + scancodes = scancode_tandy; - for (c = 0; c < 272; c++) { - if (pcem_key[c]) - keydelay[c]++; - else - keydelay[c] = 0; - } + for (c = 0; c < 272; c++) { + if (pcem_key[c]) + keydelay[c]++; + else + keydelay[c] = 0; + } - for (c = 0; c < 272; c++) { - if (pcem_key[c] != oldkey[c]) { - oldkey[c] = pcem_key[c]; - if (pcem_key[c] && scancodes[c].scancodes_make[0] == 0) - continue; - if (!pcem_key[c] && scancodes[c].scancodes_break[0] == 0) - continue; -// pclog("Key %02X start\n", c); - d = 0; - if (pcem_key[c]) { - while (scancodes[c].scancodes_make[d] != 0) - keyboard_send(scancodes[c].scancodes_make[d++]); - } else { - while (scancodes[c].scancodes_break[d] != 0) - keyboard_send(scancodes[c].scancodes_break[d++]); - } - } - } + for (c = 0; c < 272; c++) { + if (pcem_key[c] != oldkey[c]) { + oldkey[c] = pcem_key[c]; + if (pcem_key[c] && scancodes[c].scancodes_make[0] == 0) + continue; + if (!pcem_key[c] && scancodes[c].scancodes_break[0] == 0) + continue; + // pclog("Key %02X start\n", c); + d = 0; + if (pcem_key[c]) { + while (scancodes[c].scancodes_make[d] != 0) + keyboard_send(scancodes[c].scancodes_make[d++]); + } else { + while (scancodes[c].scancodes_break[d] != 0) + keyboard_send(scancodes[c].scancodes_break[d++]); + } + } + } - for (c = 0; c < 272; c++) { - if (keydelay[c] >= 30) { - keydelay[c] -= 10; - if (scancodes[c].scancodes_make[0] == 0) - continue; + for (c = 0; c < 272; c++) { + if (keydelay[c] >= 30) { + keydelay[c] -= 10; + if (scancodes[c].scancodes_make[0] == 0) + continue; - d = 0; + d = 0; - while (scancodes[c].scancodes_make[d] != 0) - keyboard_send(scancodes[c].scancodes_make[d++]); - } - } + while (scancodes[c].scancodes_make[d] != 0) + keyboard_send(scancodes[c].scancodes_make[d++]); + } + } } void keyboard_send_scancode(int code, int is_break) { - scancode *scancodes = (AT || romset == ROM_XI8088) ? at_scancodes : scancode_xt; - int d = 0; + scancode *scancodes = (AT || romset == ROM_XI8088) ? at_scancodes : scancode_xt; + int d = 0; - if (!keyboard_scan) - return; + if (!keyboard_scan) + return; - if (!is_break) { - while (scancodes[code].scancodes_make[d] != 0) - keyboard_send(scancodes[code].scancodes_make[d++]); - } else { - while (scancodes[code].scancodes_break[d] != 0) - keyboard_send(scancodes[code].scancodes_break[d++]); - } + if (!is_break) { + while (scancodes[code].scancodes_make[d] != 0) + keyboard_send(scancodes[code].scancodes_make[d++]); + } else { + while (scancodes[code].scancodes_break[d] != 0) + keyboard_send(scancodes[code].scancodes_break[d++]); + } } diff --git a/src/keyboard/keyboard_amstrad.c b/src/keyboard/keyboard_amstrad.c index ebe81c1c..25028755 100644 --- a/src/keyboard/keyboard_amstrad.c +++ b/src/keyboard/keyboard_amstrad.c @@ -10,23 +10,23 @@ #include "keyboard.h" #include "keyboard_amstrad.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 +#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 struct { - int wantirq; + int wantirq; - uint8_t key_waiting; - uint8_t pa; - uint8_t pb; + uint8_t key_waiting; + uint8_t pa; + uint8_t pb; - pc_timer_t send_delay_timer; + pc_timer_t send_delay_timer; } keyboard_amstrad; static uint8_t key_queue[16]; @@ -35,121 +35,129 @@ static int key_queue_start = 0, key_queue_end = 0; static uint8_t amstrad_systemstat_1, amstrad_systemstat_2; void keyboard_amstrad_poll() { - timer_advance_u64(&keyboard_amstrad.send_delay_timer, (1000 * TIMER_USEC)); - if (keyboard_amstrad.wantirq) { - keyboard_amstrad.wantirq = 0; - keyboard_amstrad.pa = keyboard_amstrad.key_waiting; - picint(2); - pclog("keyboard_amstrad : take IRQ\n"); - } - if (key_queue_start != key_queue_end && !keyboard_amstrad.pa) { - keyboard_amstrad.key_waiting = key_queue[key_queue_start]; - pclog("Reading %02X from the key queue at %i\n", keyboard_amstrad.key_waiting, key_queue_start); - key_queue_start = (key_queue_start + 1) & 0xf; - keyboard_amstrad.wantirq = 1; - } + timer_advance_u64(&keyboard_amstrad.send_delay_timer, (1000 * TIMER_USEC)); + if (keyboard_amstrad.wantirq) { + keyboard_amstrad.wantirq = 0; + keyboard_amstrad.pa = keyboard_amstrad.key_waiting; + picint(2); + pclog("keyboard_amstrad : take IRQ\n"); + } + if (key_queue_start != key_queue_end && !keyboard_amstrad.pa) { + keyboard_amstrad.key_waiting = key_queue[key_queue_start]; + pclog("Reading %02X from the key queue at %i\n", keyboard_amstrad.key_waiting, key_queue_start); + key_queue_start = (key_queue_start + 1) & 0xf; + keyboard_amstrad.wantirq = 1; + } } void keyboard_amstrad_adddata(uint8_t val) { - key_queue[key_queue_end] = val; - pclog("keyboard_amstrad : %02X added to key queue at %i\n", val, key_queue_end); - key_queue_end = (key_queue_end + 1) & 0xf; - return; + key_queue[key_queue_end] = val; + pclog("keyboard_amstrad : %02X added to key queue at %i\n", val, key_queue_end); + key_queue_end = (key_queue_end + 1) & 0xf; + return; } void keyboard_amstrad_write(uint16_t port, uint8_t val, void *priv) { - pclog("keyboard_amstrad : write %04X %02X %02X\n", port, val, keyboard_amstrad.pb); + pclog("keyboard_amstrad : write %04X %02X %02X\n", port, val, keyboard_amstrad.pb); - switch (port) { - case 0x61:pclog("keyboard_amstrad : pb write %02X %02X %i %02X %i\n", val, keyboard_amstrad.pb, !(keyboard_amstrad.pb & 0x40), keyboard_amstrad.pb & 0x40, (val & 0x40)); - if (!(keyboard_amstrad.pb & 0x40) && (val & 0x40)) /*Reset keyboard*/ - { - pclog("keyboard_amstrad : reset keyboard\n"); - keyboard_amstrad_adddata(0xaa); - } - keyboard_amstrad.pb = val; - ppi.pb = val; + switch (port) { + case 0x61: + pclog("keyboard_amstrad : pb write %02X %02X %i %02X %i\n", val, keyboard_amstrad.pb, + !(keyboard_amstrad.pb & 0x40), keyboard_amstrad.pb & 0x40, (val & 0x40)); + if (!(keyboard_amstrad.pb & 0x40) && (val & 0x40)) /*Reset keyboard*/ + { + pclog("keyboard_amstrad : reset keyboard\n"); + keyboard_amstrad_adddata(0xaa); + } + keyboard_amstrad.pb = val; + ppi.pb = val; - timer_process(); + timer_process(); - speaker_update(); - speaker_gated = val & 1; - speaker_enable = val & 2; - if (speaker_enable) - was_speaker_enable = 1; - pit_set_gate(&pit, 2, val & 1); + 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 (val & 0x80) - keyboard_amstrad.pa = 0; - break; + if (val & 0x80) + keyboard_amstrad.pa = 0; + break; - case 0x63:break; + case 0x63: + break; - case 0x64:amstrad_systemstat_1 = val; - break; + case 0x64: + amstrad_systemstat_1 = val; + break; - case 0x65:amstrad_systemstat_2 = val; - break; + case 0x65: + amstrad_systemstat_2 = val; + break; - default:pclog("\nBad XT keyboard write %04X %02X\n", port, val); -// dumpregs(); -// exit(-1); - } + default: + pclog("\nBad XT keyboard write %04X %02X\n", port, val); + // dumpregs(); + // exit(-1); + } } uint8_t keyboard_amstrad_read(uint16_t port, void *priv) { - uint8_t temp = 0xff; -// pclog("keyboard_amstrad : read %04X ", port); - switch (port) { - case 0x60: - if (keyboard_amstrad.pb & 0x80) { - temp = (amstrad_systemstat_1 | 0xd) & 0x7f; - } else { - temp = keyboard_amstrad.pa; - if (key_queue_start == key_queue_end) { - keyboard_amstrad.wantirq = 0; - } else { - keyboard_amstrad.key_waiting = key_queue[key_queue_start]; - key_queue_start = (key_queue_start + 1) & 0xf; - keyboard_amstrad.wantirq = 1; - } - } - break; + uint8_t temp = 0xff; + // pclog("keyboard_amstrad : read %04X ", port); + switch (port) { + case 0x60: + if (keyboard_amstrad.pb & 0x80) { + temp = (amstrad_systemstat_1 | 0xd) & 0x7f; + } else { + temp = keyboard_amstrad.pa; + if (key_queue_start == key_queue_end) { + keyboard_amstrad.wantirq = 0; + } else { + keyboard_amstrad.key_waiting = key_queue[key_queue_start]; + key_queue_start = (key_queue_start + 1) & 0xf; + keyboard_amstrad.wantirq = 1; + } + } + break; - case 0x61:temp = keyboard_amstrad.pb; - break; + case 0x61: + temp = keyboard_amstrad.pb; + break; - case 0x62: - if (keyboard_amstrad.pb & 0x04) - temp = amstrad_systemstat_2 & 0xf; - else - temp = amstrad_systemstat_2 >> 4; - temp |= (ppispeakon ? 0x20 : 0); - if (nmi) - temp |= 0x40; - break; + case 0x62: + if (keyboard_amstrad.pb & 0x04) + temp = amstrad_systemstat_2 & 0xf; + else + temp = amstrad_systemstat_2 >> 4; + temp |= (ppispeakon ? 0x20 : 0); + if (nmi) + temp |= 0x40; + break; - default:pclog("\nBad XT keyboard read %04X\n", port); -// dumpregs(); -// exit(-1); - } -// pclog("%02X %04X:%04X\n", temp, CS, pc); - return temp; + default: + pclog("\nBad XT keyboard read %04X\n", port); + // dumpregs(); + // exit(-1); + } + // pclog("%02X %04X:%04X\n", temp, CS, pc); + return temp; } void keyboard_amstrad_reset() { - keyboard_amstrad.wantirq = 0; + keyboard_amstrad.wantirq = 0; - keyboard_scan = 1; + keyboard_scan = 1; } void keyboard_amstrad_init() { - //return; - pclog("keyboard_amstrad_init\n"); - io_sethandler(0x0060, 0x0006, keyboard_amstrad_read, NULL, NULL, keyboard_amstrad_write, NULL, NULL, NULL); - keyboard_amstrad_reset(); - keyboard_send = keyboard_amstrad_adddata; - keyboard_poll = keyboard_amstrad_poll; + // return; + pclog("keyboard_amstrad_init\n"); + io_sethandler(0x0060, 0x0006, keyboard_amstrad_read, NULL, NULL, keyboard_amstrad_write, NULL, NULL, NULL); + keyboard_amstrad_reset(); + keyboard_send = keyboard_amstrad_adddata; + keyboard_poll = keyboard_amstrad_poll; - timer_add(&keyboard_amstrad.send_delay_timer, keyboard_amstrad_poll, NULL, 1); + timer_add(&keyboard_amstrad.send_delay_timer, keyboard_amstrad_poll, NULL, 1); } diff --git a/src/keyboard/keyboard_at.c b/src/keyboard/keyboard_at.c index 5f6b6888..04636f74 100644 --- a/src/keyboard/keyboard_at.c +++ b/src/keyboard/keyboard_at.c @@ -14,75 +14,70 @@ #include "keyboard.h" #include "keyboard_at.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 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 (16 * TIMER_USEC) #define RESET_DELAY_TIME (100 * 10) /*600ms*/ struct { - int initialised; - int want60; - int wantirq, wantirq12; - uint8_t command; - uint8_t status; - uint8_t mem[0x20]; - uint8_t out; - int out_new, out_delayed; + int initialised; + int want60; + int wantirq, wantirq12; + uint8_t command; + uint8_t status; + uint8_t mem[0x20]; + uint8_t out; + int out_new, out_delayed; - int scancode_set; - int translate; - int next_is_release; + int scancode_set; + int translate; + int next_is_release; - uint8_t input_port; - uint8_t output_port; + uint8_t input_port; + uint8_t output_port; - uint8_t key_command; - int key_wantdata; + uint8_t key_command; + int key_wantdata; - int last_irq; + int last_irq; - void (*mouse_write)(uint8_t val, void *p); - void *mouse_p; + void (*mouse_write)(uint8_t val, void *p); + void *mouse_p; - pc_timer_t refresh_timer; - int refresh; + pc_timer_t refresh_timer; + int refresh; - int is_ps2; + int is_ps2; - pc_timer_t send_delay_timer; + pc_timer_t send_delay_timer; - int reset_delay; + int reset_delay; } keyboard_at; /*Translation table taken from https://www.win.tue.nl/~aeb/linux/kbd/scancodes-10.html#ss10.3*/ -static uint8_t at_translation[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 uint8_t at_translation[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 uint8_t key_ctrl_queue[16]; static int key_ctrl_queue_start = 0, key_ctrl_queue_end = 0; @@ -95,732 +90,766 @@ int mouse_queue_start = 0, mouse_queue_end = 0; void keyboard_at_adddata_keyboard(uint8_t val); void keyboard_at_poll() { - timer_advance_u64(&keyboard_at.send_delay_timer, (100 * TIMER_USEC)); + timer_advance_u64(&keyboard_at.send_delay_timer, (100 * TIMER_USEC)); - if (keyboard_at.out_new != -1 && !keyboard_at.last_irq) { - keyboard_at.wantirq = 0; - if (keyboard_at.out_new & 0x100) { - if (mouse_scan) { -// pclog("keyboard_at : take IRQ12\n"); - if (keyboard_at.mem[0] & 0x02) - picint(0x1000); - keyboard_at.out = keyboard_at.out_new & 0xff; - keyboard_at.out_new = -1; - keyboard_at.status |= STAT_OFULL; - keyboard_at.status &= ~STAT_IFULL; - keyboard_at.status |= STAT_MFULL; - keyboard_at.last_irq = 0x1000; - } else { -// pclog("keyboard_at: suppressing IRQ12\n"); - keyboard_at.out_new = -1; - } - } else { - if (keyboard_at.mem[0] & 0x01) - picint(2); - keyboard_at.out = keyboard_at.out_new & 0xff; - keyboard_at.out_new = -1; - keyboard_at.status |= STAT_OFULL; - keyboard_at.status &= ~STAT_IFULL; - keyboard_at.status &= ~STAT_MFULL; -// pclog("keyboard_at : take IRQ1\n"); - keyboard_at.last_irq = 2; - } - } + if (keyboard_at.out_new != -1 && !keyboard_at.last_irq) { + keyboard_at.wantirq = 0; + if (keyboard_at.out_new & 0x100) { + if (mouse_scan) { + // pclog("keyboard_at : take IRQ12\n"); + if (keyboard_at.mem[0] & 0x02) + picint(0x1000); + keyboard_at.out = keyboard_at.out_new & 0xff; + keyboard_at.out_new = -1; + keyboard_at.status |= STAT_OFULL; + keyboard_at.status &= ~STAT_IFULL; + keyboard_at.status |= STAT_MFULL; + keyboard_at.last_irq = 0x1000; + } else { + // pclog("keyboard_at: suppressing IRQ12\n"); + keyboard_at.out_new = -1; + } + } else { + if (keyboard_at.mem[0] & 0x01) + picint(2); + keyboard_at.out = keyboard_at.out_new & 0xff; + keyboard_at.out_new = -1; + keyboard_at.status |= STAT_OFULL; + keyboard_at.status &= ~STAT_IFULL; + keyboard_at.status &= ~STAT_MFULL; + // pclog("keyboard_at : take IRQ1\n"); + keyboard_at.last_irq = 2; + } + } - if (keyboard_at.out_new == -1 && !(keyboard_at.status & STAT_OFULL) && - key_ctrl_queue_start != key_ctrl_queue_end) { - keyboard_at.out_new = key_ctrl_queue[key_ctrl_queue_start] | 0x200; - key_ctrl_queue_start = (key_ctrl_queue_start + 1) & 0xf; - } else if (!(keyboard_at.status & STAT_OFULL) && keyboard_at.out_new == -1 && - keyboard_at.out_delayed != -1) { - keyboard_at.out_new = keyboard_at.out_delayed; - keyboard_at.out_delayed = -1; - } else if (!(keyboard_at.status & STAT_OFULL) && keyboard_at.out_new == -1 && - !(keyboard_at.mem[0] & 0x10) && keyboard_at.out_delayed != -1) { - keyboard_at.out_new = keyboard_at.out_delayed; - keyboard_at.out_delayed = -1; - } else if (!(keyboard_at.status & STAT_OFULL) && keyboard_at.out_new == -1 && /*!(keyboard_at.mem[0] & 0x20) &&*/ - mouse_queue_start != mouse_queue_end) { - keyboard_at.out_new = mouse_queue[mouse_queue_start] | 0x100; - mouse_queue_start = (mouse_queue_start + 1) & 0xf; - } else if (!(keyboard_at.status & STAT_OFULL) && keyboard_at.out_new == -1 && - !(keyboard_at.mem[0] & 0x10) && key_queue_start != key_queue_end) { - keyboard_at.out_new = key_queue[key_queue_start]; - key_queue_start = (key_queue_start + 1) & 0xf; - } + if (keyboard_at.out_new == -1 && !(keyboard_at.status & STAT_OFULL) && key_ctrl_queue_start != key_ctrl_queue_end) { + keyboard_at.out_new = key_ctrl_queue[key_ctrl_queue_start] | 0x200; + key_ctrl_queue_start = (key_ctrl_queue_start + 1) & 0xf; + } else if (!(keyboard_at.status & STAT_OFULL) && keyboard_at.out_new == -1 && keyboard_at.out_delayed != -1) { + keyboard_at.out_new = keyboard_at.out_delayed; + keyboard_at.out_delayed = -1; + } else if (!(keyboard_at.status & STAT_OFULL) && keyboard_at.out_new == -1 && !(keyboard_at.mem[0] & 0x10) && + keyboard_at.out_delayed != -1) { + keyboard_at.out_new = keyboard_at.out_delayed; + keyboard_at.out_delayed = -1; + } else if (!(keyboard_at.status & STAT_OFULL) && keyboard_at.out_new == -1 && /*!(keyboard_at.mem[0] & 0x20) &&*/ + mouse_queue_start != mouse_queue_end) { + keyboard_at.out_new = mouse_queue[mouse_queue_start] | 0x100; + mouse_queue_start = (mouse_queue_start + 1) & 0xf; + } else if (!(keyboard_at.status & STAT_OFULL) && keyboard_at.out_new == -1 && !(keyboard_at.mem[0] & 0x10) && + key_queue_start != key_queue_end) { + keyboard_at.out_new = key_queue[key_queue_start]; + key_queue_start = (key_queue_start + 1) & 0xf; + } - if (keyboard_at.reset_delay) { - keyboard_at.reset_delay--; - if (!keyboard_at.reset_delay) - keyboard_at_adddata_keyboard(0xaa); - } + if (keyboard_at.reset_delay) { + keyboard_at.reset_delay--; + if (!keyboard_at.reset_delay) + keyboard_at_adddata_keyboard(0xaa); + } } void keyboard_at_adddata(uint8_t val) { - key_ctrl_queue[key_ctrl_queue_end] = val; - key_ctrl_queue_end = (key_ctrl_queue_end + 1) & 0xf; + key_ctrl_queue[key_ctrl_queue_end] = val; + key_ctrl_queue_end = (key_ctrl_queue_end + 1) & 0xf; - if (!(keyboard_at.out_new & 0x300)) { - keyboard_at.out_delayed = keyboard_at.out_new; - keyboard_at.out_new = -1; - } + if (!(keyboard_at.out_new & 0x300)) { + keyboard_at.out_delayed = keyboard_at.out_new; + keyboard_at.out_new = -1; + } } void keyboard_at_adddata_keyboard(uint8_t val) { - if (keyboard_at.reset_delay) - return; -/* if (val == 0x1c) - { - key_1c++; - if (key_1c == 4) - output = 3; - }*/ + if (keyboard_at.reset_delay) + return; + /* if (val == 0x1c) + { + key_1c++; + if (key_1c == 4) + output = 3; + }*/ - /* Test for T3100E 'Fn' key (Right Alt / Right Ctrl) */ - if (romset == ROM_T3100E && (pcem_key[0xb8] || pcem_key[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 */ - } - } - if (keyboard_at.translate) { - if (val == 0xf0) { - keyboard_at.next_is_release = 1; - return; - } else { - val = at_translation[val]; - if (keyboard_at.next_is_release) - val |= 0x80; - keyboard_at.next_is_release = 0; - } - } - key_queue[key_queue_end] = val; - key_queue_end = (key_queue_end + 1) & 0xf; -// pclog("keyboard_at : %02X added to key queue\n", val); - return; + /* Test for T3100E 'Fn' key (Right Alt / Right Ctrl) */ + if (romset == ROM_T3100E && (pcem_key[0xb8] || pcem_key[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 */ + } + } + if (keyboard_at.translate) { + if (val == 0xf0) { + keyboard_at.next_is_release = 1; + return; + } else { + val = at_translation[val]; + if (keyboard_at.next_is_release) + val |= 0x80; + keyboard_at.next_is_release = 0; + } + } + key_queue[key_queue_end] = val; + key_queue_end = (key_queue_end + 1) & 0xf; + // pclog("keyboard_at : %02X added to key queue\n", val); + return; } void keyboard_at_adddata_mouse(uint8_t val) { - mouse_queue[mouse_queue_end] = val; - mouse_queue_end = (mouse_queue_end + 1) & 0xf; -// pclog("keyboard_at : %02X added to mouse queue\n", val); - return; + mouse_queue[mouse_queue_end] = val; + mouse_queue_end = (mouse_queue_end + 1) & 0xf; + // pclog("keyboard_at : %02X added to mouse queue\n", val); + return; } void keyboard_at_write(uint16_t port, uint8_t val, void *priv) { -// pclog("keyboard_at : write %04X %02X %i %02X\n", port, val, keyboard_at.key_wantdata, ram[8]); - if (romset == ROM_XI8088 && port == 0x63) - port = 0x61; -/* if (ram[8] == 0xc3) - { - output = 3; - }*/ - switch (port) { - case 0x60: - if (keyboard_at.want60) { - /*Write to controller*/ - keyboard_at.want60 = 0; - switch (keyboard_at.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:keyboard_at.mem[keyboard_at.command & 0x1f] = val; - if (keyboard_at.command == 0x60) { - if ((val & 1) && (keyboard_at.status & STAT_OFULL)) - keyboard_at.wantirq = 1; - if (!(val & 1) && keyboard_at.wantirq) - keyboard_at.wantirq = 0; - mouse_scan = !(val & 0x20); - keyboard_at.translate = val & 0x40; - } - break; + // pclog("keyboard_at : write %04X %02X %i %02X\n", port, val, keyboard_at.key_wantdata, ram[8]); + if (romset == ROM_XI8088 && port == 0x63) + port = 0x61; + /* if (ram[8] == 0xc3) + { + output = 3; + }*/ + switch (port) { + case 0x60: + if (keyboard_at.want60) { + /*Write to controller*/ + keyboard_at.want60 = 0; + switch (keyboard_at.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: + keyboard_at.mem[keyboard_at.command & 0x1f] = val; + if (keyboard_at.command == 0x60) { + if ((val & 1) && (keyboard_at.status & STAT_OFULL)) + keyboard_at.wantirq = 1; + if (!(val & 1) && keyboard_at.wantirq) + keyboard_at.wantirq = 0; + mouse_scan = !(val & 0x20); + keyboard_at.translate = val & 0x40; + } + break; - case 0xb6: /* T3100e - set colour/mono switch */ - if (romset == ROM_T3100E) - t3100e_mono_set(val); - break; + case 0xb6: /* T3100e - set colour/mono switch */ + if (romset == ROM_T3100E) + t3100e_mono_set(val); + break; - case 0xcb: /*AMI - set keyboard mode*/ - break; + case 0xcb: /*AMI - set keyboard mode*/ + break; - case 0xcf: /*??? - sent by MegaPC BIOS*/ - break; + case 0xcf: /*??? - sent by MegaPC BIOS*/ + break; - case 0xd1: /*Write output port*/ -// pclog("Write output port - %02X %02X %04X:%04X\n", keyboard_at.output_port, val, CS, pc); - if ((keyboard_at.output_port ^ val) & 0x02) /*A20 enable change*/ - { - mem_a20_key = val & 0x02; - mem_a20_recalc(); -// pclog("Rammask change to %08X %02X\n", rammask, val & 0x02); - flushmmucache(); - } - keyboard_at.output_port = val; - break; + case 0xd1: /*Write output port*/ + // pclog("Write output port - %02X %02X %04X:%04X\n", + // keyboard_at.output_port, val, CS, pc); + if ((keyboard_at.output_port ^ val) & 0x02) /*A20 enable change*/ + { + mem_a20_key = val & 0x02; + mem_a20_recalc(); + // pclog("Rammask change to %08X %02X\n", rammask, + // val & 0x02); + flushmmucache(); + } + keyboard_at.output_port = val; + break; - case 0xd2: /*Write to keyboard output buffer*/ - keyboard_at_adddata(val); - break; + case 0xd2: /*Write to keyboard output buffer*/ + keyboard_at_adddata(val); + break; - case 0xd3: /*Write to mouse output buffer*/ - keyboard_at_adddata_mouse(val); - break; + case 0xd3: /*Write to mouse output buffer*/ + keyboard_at_adddata_mouse(val); + break; - case 0xd4: /*Write to mouse*/ - if (keyboard_at.mouse_write) { - keyboard_at.mouse_write(val, keyboard_at.mouse_p); - /*Implicitly enable mouse*/ - mouse_scan = 1; - keyboard_at.mem[0] &= ~0x20; - } - break; + case 0xd4: /*Write to mouse*/ + if (keyboard_at.mouse_write) { + keyboard_at.mouse_write(val, keyboard_at.mouse_p); + /*Implicitly enable mouse*/ + mouse_scan = 1; + keyboard_at.mem[0] &= ~0x20; + } + break; - default:pclog("Bad AT keyboard controller 0060 write %02X command %02X\n", val, keyboard_at.command); -// dumpregs(); -// exit(-1); - } - } else { - /*Write to keyboard*/ - keyboard_at.mem[0] &= ~0x10; - if (keyboard_at.key_wantdata) { - keyboard_at.key_wantdata = 0; - switch (keyboard_at.key_command) { - case 0xed: /*Set/reset LEDs*/ - keyboard_at_adddata_keyboard(0xfa); - break; + default: + pclog("Bad AT keyboard controller 0060 write %02X command %02X\n", val, keyboard_at.command); + // dumpregs(); + // exit(-1); + } + } else { + /*Write to keyboard*/ + keyboard_at.mem[0] &= ~0x10; + if (keyboard_at.key_wantdata) { + keyboard_at.key_wantdata = 0; + switch (keyboard_at.key_command) { + case 0xed: /*Set/reset LEDs*/ + keyboard_at_adddata_keyboard(0xfa); + break; - case 0xf0: /*Set scancode set*/ - switch (val) { - case 0: /*Read current set*/ - keyboard_at_adddata_keyboard(0xfa); - switch (keyboard_at.scancode_set) { - case SCANCODE_SET_1:keyboard_at_adddata_keyboard(0x01); - break; - case SCANCODE_SET_2:keyboard_at_adddata_keyboard(0x02); - break; - case SCANCODE_SET_3:keyboard_at_adddata_keyboard(0x03); - break; - } - break; - case 1:keyboard_at.scancode_set = SCANCODE_SET_1; - keyboard_set_scancode_set(SCANCODE_SET_1); - keyboard_at_adddata_keyboard(0xfa); - break; - case 2:keyboard_at.scancode_set = SCANCODE_SET_2; - keyboard_set_scancode_set(SCANCODE_SET_2); - keyboard_at_adddata_keyboard(0xfa); - break; - case 3:keyboard_at.scancode_set = SCANCODE_SET_3; - keyboard_set_scancode_set(SCANCODE_SET_3); - keyboard_at_adddata_keyboard(0xfa); - break; - default:keyboard_at_adddata_keyboard(0xfe); - break; - } - break; + case 0xf0: /*Set scancode set*/ + switch (val) { + case 0: /*Read current set*/ + keyboard_at_adddata_keyboard(0xfa); + switch (keyboard_at.scancode_set) { + case SCANCODE_SET_1: + keyboard_at_adddata_keyboard(0x01); + break; + case SCANCODE_SET_2: + keyboard_at_adddata_keyboard(0x02); + break; + case SCANCODE_SET_3: + keyboard_at_adddata_keyboard(0x03); + break; + } + break; + case 1: + keyboard_at.scancode_set = SCANCODE_SET_1; + keyboard_set_scancode_set(SCANCODE_SET_1); + keyboard_at_adddata_keyboard(0xfa); + break; + case 2: + keyboard_at.scancode_set = SCANCODE_SET_2; + keyboard_set_scancode_set(SCANCODE_SET_2); + keyboard_at_adddata_keyboard(0xfa); + break; + case 3: + keyboard_at.scancode_set = SCANCODE_SET_3; + keyboard_set_scancode_set(SCANCODE_SET_3); + keyboard_at_adddata_keyboard(0xfa); + break; + default: + keyboard_at_adddata_keyboard(0xfe); + break; + } + break; - case 0xf3: /*Set typematic rate/delay*/ - keyboard_at_adddata_keyboard(0xfa); - break; + case 0xf3: /*Set typematic rate/delay*/ + keyboard_at_adddata_keyboard(0xfa); + break; - default:pclog("Bad AT keyboard 0060 write %02X command %02X\n", val, keyboard_at.key_command); -// dumpregs(); -// exit(-1); - } - } else { - keyboard_at.key_command = val; - switch (val) { - case 0x05: /*??? - sent by NT 4.0*/ - keyboard_at_adddata_keyboard(0xfe); - break; + default: + pclog("Bad AT keyboard 0060 write %02X command %02X\n", val, keyboard_at.key_command); + // dumpregs(); + // exit(-1); + } + } else { + keyboard_at.key_command = val; + switch (val) { + case 0x05: /*??? - sent by NT 4.0*/ + keyboard_at_adddata_keyboard(0xfe); + break; - case 0xed: /*Set/reset LEDs*/ - keyboard_at.key_wantdata = 1; - keyboard_at_adddata_keyboard(0xfa); - break; + case 0xed: /*Set/reset LEDs*/ + keyboard_at.key_wantdata = 1; + keyboard_at_adddata_keyboard(0xfa); + break; - case 0xee: /*Diagnostic echo*/ - keyboard_at_adddata_keyboard(0xee); - break; + case 0xee: /*Diagnostic echo*/ + keyboard_at_adddata_keyboard(0xee); + break; - case 0xf0: /*Set scancode set*/ - keyboard_at.key_wantdata = 1; - keyboard_at_adddata_keyboard(0xfa); - break; + case 0xf0: /*Set scancode set*/ + keyboard_at.key_wantdata = 1; + keyboard_at_adddata_keyboard(0xfa); + break; - case 0xf2: /*Read ID*/ - keyboard_at_adddata_keyboard(0xfa); - keyboard_at_adddata_keyboard(0xab); - keyboard_at_adddata_keyboard(0x83); - break; + case 0xf2: /*Read ID*/ + keyboard_at_adddata_keyboard(0xfa); + keyboard_at_adddata_keyboard(0xab); + keyboard_at_adddata_keyboard(0x83); + break; - case 0xf3: /*Set typematic rate/delay*/ - keyboard_at.key_wantdata = 1; - keyboard_at_adddata_keyboard(0xfa); - break; + case 0xf3: /*Set typematic rate/delay*/ + keyboard_at.key_wantdata = 1; + keyboard_at_adddata_keyboard(0xfa); + break; - case 0xf4: /*Enable keyboard*/ - keyboard_scan = 1; - keyboard_at_adddata_keyboard(0xfa); - break; - case 0xf5: /*Disable keyboard*/ - keyboard_scan = 0; - keyboard_at_adddata_keyboard(0xfa); - break; + case 0xf4: /*Enable keyboard*/ + keyboard_scan = 1; + keyboard_at_adddata_keyboard(0xfa); + break; + case 0xf5: /*Disable keyboard*/ + keyboard_scan = 0; + keyboard_at_adddata_keyboard(0xfa); + break; - case 0xff: /*Reset*/ - key_queue_start = key_queue_end = 0; /*Clear key queue*/ - keyboard_at_adddata_keyboard(0xfa); - keyboard_at.reset_delay = RESET_DELAY_TIME; - break; + case 0xff: /*Reset*/ + key_queue_start = key_queue_end = 0; /*Clear key queue*/ + keyboard_at_adddata_keyboard(0xfa); + keyboard_at.reset_delay = RESET_DELAY_TIME; + break; - default:pclog("Bad AT keyboard command %02X\n", val); - keyboard_at_adddata_keyboard(0xfe); -// dumpregs(); -// exit(-1); - } - } - } - break; + default: + pclog("Bad AT keyboard command %02X\n", val); + keyboard_at_adddata_keyboard(0xfe); + // dumpregs(); + // exit(-1); + } + } + } + break; - case 0x61:ppi.pb = val; + case 0x61: + ppi.pb = val; - speaker_update(); - speaker_gated = val & 1; - speaker_enable = val & 2; - if (speaker_enable) - was_speaker_enable = 1; - pit_set_gate(&pit, 2, val & 1); + 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; + if (romset == ROM_XI8088) { + if (val & 0x04) + xi8088_turbo_set(1); + else + xi8088_turbo_set(0); + } + break; - case 0x64:keyboard_at.want60 = 0; - keyboard_at.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:keyboard_at_adddata(keyboard_at.mem[val & 0x1f]); - break; + case 0x64: + keyboard_at.want60 = 0; + keyboard_at.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: + keyboard_at_adddata(keyboard_at.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:keyboard_at.want60 = 1; - 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: + keyboard_at.want60 = 1; + break; - case 0xa1: /*AMI - get controlled version*/ - break; + case 0xa1: /*AMI - get controlled version*/ + break; - case 0xa7: /*Disable mouse port*/ - mouse_scan = 0; - keyboard_at.mem[0] |= 0x20; - break; + case 0xa7: /*Disable mouse port*/ + mouse_scan = 0; + keyboard_at.mem[0] |= 0x20; + break; - case 0xa8: /*Enable mouse port*/ - mouse_scan = 1; - keyboard_at.mem[0] &= ~0x20; - break; + case 0xa8: /*Enable mouse port*/ + mouse_scan = 1; + keyboard_at.mem[0] &= ~0x20; + break; - case 0xa9: /*Test mouse port*/ - keyboard_at_adddata(0x00); /*no error*/ - break; + case 0xa9: /*Test mouse port*/ + keyboard_at_adddata(0x00); /*no error*/ + break; - case 0xaa: /*Self-test*/ - if (!keyboard_at.initialised) { - keyboard_at.initialised = 1; - key_ctrl_queue_start = key_ctrl_queue_end = 0; - keyboard_at.status &= ~STAT_OFULL; - } - /* T3100e and Samsung SPC-6000A expects STAT_IFULL to be set immediately - * after sending 0xAA */ - if (romset == ROM_T3100E || romset == ROM_SPC6000A) - keyboard_at.status |= STAT_IFULL; - keyboard_at.status |= STAT_SYSFLAG; - keyboard_at.mem[0] |= 0x04; - keyboard_at_adddata(0x55); - /*Self-test also resets the output port, enabling A20*/ - if (!(keyboard_at.output_port & 0x02)) { - mem_a20_key = 2; - mem_a20_recalc(); -// pclog("Rammask change to %08X %02X\n", rammask, val & 0x02); - flushmmucache(); - } - keyboard_at.output_port = 0xcf; - break; + case 0xaa: /*Self-test*/ + if (!keyboard_at.initialised) { + keyboard_at.initialised = 1; + key_ctrl_queue_start = key_ctrl_queue_end = 0; + keyboard_at.status &= ~STAT_OFULL; + } + /* T3100e and Samsung SPC-6000A expects STAT_IFULL to be set immediately + * after sending 0xAA */ + if (romset == ROM_T3100E || romset == ROM_SPC6000A) + keyboard_at.status |= STAT_IFULL; + keyboard_at.status |= STAT_SYSFLAG; + keyboard_at.mem[0] |= 0x04; + keyboard_at_adddata(0x55); + /*Self-test also resets the output port, enabling A20*/ + if (!(keyboard_at.output_port & 0x02)) { + mem_a20_key = 2; + mem_a20_recalc(); + // pclog("Rammask change to %08X %02X\n", rammask, val & 0x02); + flushmmucache(); + } + keyboard_at.output_port = 0xcf; + break; - case 0xab: /*Interface test*/ - keyboard_at_adddata(0x00); /*no error*/ - break; + case 0xab: /*Interface test*/ + keyboard_at_adddata(0x00); /*no error*/ + break; - case 0xad: /*Disable keyboard*/ - keyboard_at.mem[0] |= 0x10; - break; + case 0xad: /*Disable keyboard*/ + keyboard_at.mem[0] |= 0x10; + break; - case 0xae: /*Enable keyboard*/ - keyboard_at.mem[0] &= ~0x10; - break; + case 0xae: /*Enable keyboard*/ + keyboard_at.mem[0] &= ~0x10; + break; - case 0xb0: /* T3100e: Turbo on */ - if (romset == ROM_T3100E) - t3100e_turbo_set(1); - break; + case 0xb0: /* T3100e: Turbo on */ + if (romset == ROM_T3100E) + t3100e_turbo_set(1); + break; - case 0xb1: /* T3100e: Turbo off */ - if (romset == ROM_T3100E) - t3100e_turbo_set(0); - break; + case 0xb1: /* T3100e: Turbo off */ + if (romset == ROM_T3100E) + t3100e_turbo_set(0); + break; - case 0xb2: /* T3100e: Select external display */ - if (romset == ROM_T3100E) - t3100e_display_set(0x00); - break; + case 0xb2: /* T3100e: Select external display */ + if (romset == ROM_T3100E) + t3100e_display_set(0x00); + break; - case 0xb3: /* T3100e: Select internal display */ - if (romset == ROM_T3100E) - t3100e_display_set(0x01); - break; + case 0xb3: /* T3100e: Select internal display */ + if (romset == ROM_T3100E) + t3100e_display_set(0x01); + break; - case 0xb4: /* T3100e: Get configuration / status */ - if (romset == ROM_T3100E) - keyboard_at_adddata(t3100e_config_get()); - break; + case 0xb4: /* T3100e: Get configuration / status */ + if (romset == ROM_T3100E) + keyboard_at_adddata(t3100e_config_get()); + break; - case 0xb5: /* T3100e: Get colour / mono byte */ - if (romset == ROM_T3100E) - keyboard_at_adddata(t3100e_mono_get()); - break; + case 0xb5: /* T3100e: Get colour / mono byte */ + if (romset == ROM_T3100E) + keyboard_at_adddata(t3100e_mono_get()); + break; - case 0xb6: /* T3100e: Set colour / mono byte */ - if (romset == ROM_T3100E) - keyboard_at.want60 = 1; - break; + case 0xb6: /* T3100e: Set colour / mono byte */ + if (romset == ROM_T3100E) + keyboard_at.want60 = 1; + break; - case 0xba: - if (romset == ROM_ENDEAVOR || romset == ROM_ZAPPA || romset == ROM_ITAUTEC_INFOWAYM) - keyboard_at_adddata(0); - break; + case 0xba: + if (romset == ROM_ENDEAVOR || romset == ROM_ZAPPA || romset == ROM_ITAUTEC_INFOWAYM) + keyboard_at_adddata(0); + break; - /* T3100e commands not implemented: - * 0xB7: Emulate PS/2 keyboard - * 0xB8: Emulate AT keyboard */ + /* T3100e commands not implemented: + * 0xB7: Emulate PS/2 keyboard + * 0xB8: Emulate AT keyboard */ - 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 (romset == ROM_T3100E) { - if (pcem_key[0xb8] || /* Right Alt */ - pcem_key[0x9d]) /* Right Ctrl */ - { - keyboard_at_adddata(0x04); - } else - keyboard_at_adddata(0x00); - } - break; + 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 (romset == ROM_T3100E) { + if (pcem_key[0xb8] || /* Right Alt */ + pcem_key[0x9d]) /* Right Ctrl */ + { + keyboard_at_adddata(0x04); + } else + keyboard_at_adddata(0x00); + } + break; - case 0xbc: /* T3100e: Reset Fn+Key notification */ - if (romset == ROM_T3100E) - t3100e_notify_set(0x00); - break; + case 0xbc: /* T3100e: Reset Fn+Key notification */ + if (romset == ROM_T3100E) + t3100e_notify_set(0x00); + break; - case 0xc0: /*Read input port*/ - /* The T3100e returns all bits set except bit 6 which - * is set by t3100e_mono_set() */ - if (romset == ROM_T3100E) - keyboard_at.input_port = (t3100e_mono_get() & 1) ? 0xFF : 0xBF; + case 0xc0: /*Read input port*/ + /* The T3100e returns all bits set except bit 6 which + * is set by t3100e_mono_set() */ + if (romset == ROM_T3100E) + keyboard_at.input_port = (t3100e_mono_get() & 1) ? 0xFF : 0xBF; - if (romset == ROM_ENDEAVOR || romset == ROM_ZAPPA || romset == ROM_ITAUTEC_INFOWAYM) - keyboard_at_adddata(keyboard_at.input_port | 4 | 0x40); - else - keyboard_at_adddata(keyboard_at.input_port | 4); + if (romset == ROM_ENDEAVOR || romset == ROM_ZAPPA || romset == ROM_ITAUTEC_INFOWAYM) + keyboard_at_adddata(keyboard_at.input_port | 4 | 0x40); + else + keyboard_at_adddata(keyboard_at.input_port | 4); - keyboard_at.input_port = ((keyboard_at.input_port + 1) & 3) | (keyboard_at.input_port & 0xfc); - break; + keyboard_at.input_port = ((keyboard_at.input_port + 1) & 3) | (keyboard_at.input_port & 0xfc); + break; - case 0xc9: /*AMI - block P22 and P23 ??? */ - break; + case 0xc9: /*AMI - block P22 and P23 ??? */ + break; - case 0xca: /*AMI - read keyboard mode*/ - if (romset == ROM_GA686BX) /*TODO*/ - keyboard_at_adddata(0x01); /*PS2 mode*/ - else - keyboard_at_adddata(0x00); /*ISA mode*/ - break; + case 0xca: /*AMI - read keyboard mode*/ + if (romset == ROM_GA686BX) /*TODO*/ + keyboard_at_adddata(0x01); /*PS2 mode*/ + else + keyboard_at_adddata(0x00); /*ISA mode*/ + break; - case 0xcb: /*AMI - set keyboard mode*/ - keyboard_at.want60 = 1; - break; + case 0xcb: /*AMI - set keyboard mode*/ + keyboard_at.want60 = 1; + break; - case 0xcf: /*??? - sent by MegaPC BIOS*/ - keyboard_at.want60 = 1; - break; + case 0xcf: /*??? - sent by MegaPC BIOS*/ + keyboard_at.want60 = 1; + break; - case 0xd0: /*Read output port*/ - keyboard_at_adddata(keyboard_at.output_port); - break; + case 0xd0: /*Read output port*/ + keyboard_at_adddata(keyboard_at.output_port); + break; - case 0xd1: /*Write output port*/ - keyboard_at.want60 = 1; - break; + case 0xd1: /*Write output port*/ + keyboard_at.want60 = 1; + break; - case 0xd2: /*Write keyboard output buffer*/ - keyboard_at.want60 = 1; - break; + case 0xd2: /*Write keyboard output buffer*/ + keyboard_at.want60 = 1; + break; - case 0xd3: /*Write mouse output buffer*/ - keyboard_at.want60 = 1; - break; + case 0xd3: /*Write mouse output buffer*/ + keyboard_at.want60 = 1; + break; - case 0xd4: /*Write to mouse*/ - keyboard_at.want60 = 1; - break; + case 0xd4: /*Write to mouse*/ + keyboard_at.want60 = 1; + break; - case 0xe0: /*Read test inputs*/ - keyboard_at_adddata(0x00); - break; + case 0xe0: /*Read test inputs*/ + keyboard_at_adddata(0x00); + break; - // AWARD BIOS: called after turbo ON/OFF in the - // Hyundai Super-286TR and probably other AWARD 286 - // bioses. Related to the Turbo LEDs. Exact function - // can't be confirmed because the system in question - // has no such leds. - //case 0xe8: /* Turbo ON, always followed by 0xba */ - //case 0xe9: /* Turbo OFF */ - //break; + // AWARD BIOS: called after turbo ON/OFF in the + // Hyundai Super-286TR and probably other AWARD 286 + // bioses. Related to the Turbo LEDs. Exact function + // can't be confirmed because the system in question + // has no such leds. + // case 0xe8: /* Turbo ON, always followed by 0xba */ + // case 0xe9: /* Turbo OFF */ + // break; - case 0xef: /*??? - sent by AMI486*/ - break; + case 0xef: /*??? - sent by AMI486*/ + break; - case 0xf0: - case 0xf2: - case 0xf4: - case 0xf6: - case 0xf8: - case 0xfa: - case 0xfc: - case 0xfe: /*Pulse output port - pin 0 selected - x86 reset*/ - softresetx86(); /*Pulse reset!*/ - cpu_set_edx(); - break; + case 0xf0: + case 0xf2: + case 0xf4: + case 0xf6: + case 0xf8: + case 0xfa: + case 0xfc: + case 0xfe: /*Pulse output port - pin 0 selected - x86 reset*/ + softresetx86(); /*Pulse reset!*/ + cpu_set_edx(); + break; - case 0xff: /*Pulse output port - but no pins selected - sent by MegaPC BIOS*/ - break; + case 0xff: /*Pulse output port - but no pins selected - sent by MegaPC BIOS*/ + break; - default:pclog("Bad AT keyboard controller command %02X\n", val); -// dumpregs(); -// exit(-1); - } - } + default: + pclog("Bad AT keyboard controller command %02X\n", val); + // dumpregs(); + // exit(-1); + } + } } uint8_t keyboard_at_read(uint16_t port, void *priv) { - uint8_t temp = 0xff; + uint8_t temp = 0xff; - if (romset != ROM_IBMAT && romset != ROM_IBMXT286) - cycles -= ISA_CYCLES(8); -// if (port != 0x61) pclog("keyboard_at : read %04X ", port); - if (romset == ROM_XI8088 && port == 0x63) - port = 0x61; - switch (port) { - case 0x60:temp = keyboard_at.out; - keyboard_at.status &= ~(STAT_OFULL/* | STAT_MFULL*/); - picintc(keyboard_at.last_irq); - keyboard_at.last_irq = 0; - break; + if (romset != ROM_IBMAT && romset != ROM_IBMXT286) + cycles -= ISA_CYCLES(8); + // if (port != 0x61) pclog("keyboard_at : read %04X ", port); + if (romset == ROM_XI8088 && port == 0x63) + port = 0x61; + switch (port) { + case 0x60: + temp = keyboard_at.out; + keyboard_at.status &= ~(STAT_OFULL /* | STAT_MFULL*/); + picintc(keyboard_at.last_irq); + keyboard_at.last_irq = 0; + break; - case 0x61:temp = ppi.pb & ~0xe0; - if (ppispeakon) - temp |= 0x20; - if (keyboard_at.is_ps2) { - if (keyboard_at.refresh) - temp |= 0x10; - else - temp &= ~0x10; - } - if (romset == ROM_XI8088) { - if (xi8088_turbo_get()) - temp |= 0x04; - else - temp &= ~0x04; - } - break; + case 0x61: + temp = ppi.pb & ~0xe0; + if (ppispeakon) + temp |= 0x20; + if (keyboard_at.is_ps2) { + if (keyboard_at.refresh) + temp |= 0x10; + else + temp &= ~0x10; + } + if (romset == ROM_XI8088) { + if (xi8088_turbo_get()) + temp |= 0x04; + else + temp &= ~0x04; + } + break; - case 0x64:temp = keyboard_at.status & ~4; - if (keyboard_at.mem[0] & 0x04) - temp |= 0x04; - keyboard_at.status &= ~(STAT_RTIMEOUT/* | STAT_TTIMEOUT*/); - break; - } -// if (port != 0x61) pclog("%02X %08X\n", temp, rammask); - return temp; + case 0x64: + temp = keyboard_at.status & ~4; + if (keyboard_at.mem[0] & 0x04) + temp |= 0x04; + keyboard_at.status &= ~(STAT_RTIMEOUT /* | STAT_TTIMEOUT*/); + break; + } + // if (port != 0x61) pclog("%02X %08X\n", temp, rammask); + return temp; } void keyboard_at_reset() { - keyboard_at.initialised = 0; - keyboard_at.status = STAT_LOCK | STAT_CD; - keyboard_at.mem[0] = 0x11; - keyboard_at.wantirq = 0; - keyboard_at.output_port = 0xcf; - if (romset == ROM_XI8088) - keyboard_at.input_port = (video_is_mda()) ? 0xb0 : 0xf0; - else - keyboard_at.input_port = (video_is_mda()) ? 0xf0 : 0xb0; - keyboard_at.out_new = -1; - keyboard_at.out_delayed = -1; - keyboard_at.last_irq = 0; + keyboard_at.initialised = 0; + keyboard_at.status = STAT_LOCK | STAT_CD; + keyboard_at.mem[0] = 0x11; + keyboard_at.wantirq = 0; + keyboard_at.output_port = 0xcf; + if (romset == ROM_XI8088) + keyboard_at.input_port = (video_is_mda()) ? 0xb0 : 0xf0; + else + keyboard_at.input_port = (video_is_mda()) ? 0xf0 : 0xb0; + keyboard_at.out_new = -1; + keyboard_at.out_delayed = -1; + keyboard_at.last_irq = 0; - keyboard_at.key_wantdata = 0; + keyboard_at.key_wantdata = 0; - keyboard_scan = 1; + keyboard_scan = 1; } static void at_refresh(void *p) { - keyboard_at.refresh = !keyboard_at.refresh; - timer_advance_u64(&keyboard_at.refresh_timer, PS2_REFRESH_TIME); + keyboard_at.refresh = !keyboard_at.refresh; + timer_advance_u64(&keyboard_at.refresh_timer, PS2_REFRESH_TIME); } void keyboard_at_init() { - //return; - memset(&keyboard_at, 0, sizeof(keyboard_at)); - io_sethandler(0x0060, 0x0005, keyboard_at_read, NULL, NULL, keyboard_at_write, NULL, NULL, NULL); - keyboard_at_reset(); - keyboard_send = keyboard_at_adddata_keyboard; - keyboard_poll = keyboard_at_poll; - keyboard_at.mouse_write = NULL; - keyboard_at.mouse_p = NULL; - keyboard_at.is_ps2 = 0; - keyboard_set_scancode_set(SCANCODE_SET_2); - keyboard_at.scancode_set = SCANCODE_SET_2; + // return; + memset(&keyboard_at, 0, sizeof(keyboard_at)); + io_sethandler(0x0060, 0x0005, keyboard_at_read, NULL, NULL, keyboard_at_write, NULL, NULL, NULL); + keyboard_at_reset(); + keyboard_send = keyboard_at_adddata_keyboard; + keyboard_poll = keyboard_at_poll; + keyboard_at.mouse_write = NULL; + keyboard_at.mouse_p = NULL; + keyboard_at.is_ps2 = 0; + keyboard_set_scancode_set(SCANCODE_SET_2); + keyboard_at.scancode_set = SCANCODE_SET_2; - timer_add(&keyboard_at.send_delay_timer, keyboard_at_poll, NULL, 1); + timer_add(&keyboard_at.send_delay_timer, keyboard_at_poll, NULL, 1); } void keyboard_at_set_mouse(void (*mouse_write)(uint8_t val, void *p), void *p) { - keyboard_at.mouse_write = mouse_write; - keyboard_at.mouse_p = p; + keyboard_at.mouse_write = mouse_write; + keyboard_at.mouse_p = p; } void keyboard_at_init_ps2() { - timer_add(&keyboard_at.refresh_timer, at_refresh, NULL, 1); - keyboard_at.is_ps2 = 1; + timer_add(&keyboard_at.refresh_timer, at_refresh, NULL, 1); + keyboard_at.is_ps2 = 1; } diff --git a/src/keyboard/keyboard_olim24.c b/src/keyboard/keyboard_olim24.c index f9512c96..452ad4fa 100644 --- a/src/keyboard/keyboard_olim24.c +++ b/src/keyboard/keyboard_olim24.c @@ -12,29 +12,29 @@ #include "keyboard.h" #include "keyboard_olim24.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 +#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 struct { - int wantirq; - uint8_t command; - uint8_t status; - uint8_t out; + int wantirq; + uint8_t command; + uint8_t status; + uint8_t out; - uint8_t output_port; + uint8_t output_port; - int param, param_total; - uint8_t params[16]; + int param, param_total; + uint8_t params[16]; - int mouse_mode; + int mouse_mode; - pc_timer_t send_delay_timer; + pc_timer_t send_delay_timer; } keyboard_olim24; static uint8_t key_queue[16]; @@ -43,272 +43,276 @@ static int key_queue_start = 0, key_queue_end = 0; static uint8_t mouse_scancodes[7]; void keyboard_olim24_poll() { - timer_advance_u64(&keyboard_olim24.send_delay_timer, (1000 * TIMER_USEC)); - //pclog("poll %i\n", keyboard_olim24.wantirq); - if (keyboard_olim24.wantirq) { - keyboard_olim24.wantirq = 0; - picint(2); - pclog("keyboard_olim24 : take IRQ\n"); - } - if (!(keyboard_olim24.status & STAT_OFULL) && key_queue_start != key_queue_end) { - pclog("Reading %02X from the key queue at %i\n", keyboard_olim24.out, key_queue_start); - keyboard_olim24.out = key_queue[key_queue_start]; - key_queue_start = (key_queue_start + 1) & 0xf; - keyboard_olim24.status |= STAT_OFULL; - keyboard_olim24.status &= ~STAT_IFULL; - keyboard_olim24.wantirq = 1; - } + timer_advance_u64(&keyboard_olim24.send_delay_timer, (1000 * TIMER_USEC)); + // pclog("poll %i\n", keyboard_olim24.wantirq); + if (keyboard_olim24.wantirq) { + keyboard_olim24.wantirq = 0; + picint(2); + pclog("keyboard_olim24 : take IRQ\n"); + } + if (!(keyboard_olim24.status & STAT_OFULL) && key_queue_start != key_queue_end) { + pclog("Reading %02X from the key queue at %i\n", keyboard_olim24.out, key_queue_start); + keyboard_olim24.out = key_queue[key_queue_start]; + key_queue_start = (key_queue_start + 1) & 0xf; + keyboard_olim24.status |= STAT_OFULL; + keyboard_olim24.status &= ~STAT_IFULL; + keyboard_olim24.wantirq = 1; + } } void keyboard_olim24_adddata(uint8_t val) { - key_queue[key_queue_end] = val; - key_queue_end = (key_queue_end + 1) & 0xf; - pclog("keyboard_olim24 : %02X added to key queue %02X\n", val, keyboard_olim24.status); - return; + key_queue[key_queue_end] = val; + key_queue_end = (key_queue_end + 1) & 0xf; + pclog("keyboard_olim24 : %02X added to key queue %02X\n", val, keyboard_olim24.status); + return; } void keyboard_olim24_write(uint16_t port, uint8_t val, void *priv) { - pclog("keyboard_olim24 : write %04X %02X\n", port, val); -/* if (ram[8] == 0xc3) - { - output = 3; - }*/ - switch (port) { - case 0x60: - if (keyboard_olim24.param != keyboard_olim24.param_total) { - keyboard_olim24.params[keyboard_olim24.param++] = val; - if (keyboard_olim24.param == keyboard_olim24.param_total) { - switch (keyboard_olim24.command) { - case 0x11:keyboard_olim24.mouse_mode = 0; - mouse_scancodes[0] = keyboard_olim24.params[0]; - mouse_scancodes[1] = keyboard_olim24.params[1]; - mouse_scancodes[2] = keyboard_olim24.params[2]; - mouse_scancodes[3] = keyboard_olim24.params[3]; - mouse_scancodes[4] = keyboard_olim24.params[4]; - mouse_scancodes[5] = keyboard_olim24.params[5]; - mouse_scancodes[6] = keyboard_olim24.params[6]; - break; + pclog("keyboard_olim24 : write %04X %02X\n", port, val); + /* if (ram[8] == 0xc3) + { + output = 3; + }*/ + switch (port) { + case 0x60: + if (keyboard_olim24.param != keyboard_olim24.param_total) { + keyboard_olim24.params[keyboard_olim24.param++] = val; + if (keyboard_olim24.param == keyboard_olim24.param_total) { + switch (keyboard_olim24.command) { + case 0x11: + keyboard_olim24.mouse_mode = 0; + mouse_scancodes[0] = keyboard_olim24.params[0]; + mouse_scancodes[1] = keyboard_olim24.params[1]; + mouse_scancodes[2] = keyboard_olim24.params[2]; + mouse_scancodes[3] = keyboard_olim24.params[3]; + mouse_scancodes[4] = keyboard_olim24.params[4]; + mouse_scancodes[5] = keyboard_olim24.params[5]; + mouse_scancodes[6] = keyboard_olim24.params[6]; + break; - case 0x12:keyboard_olim24.mouse_mode = 1; - mouse_scancodes[0] = keyboard_olim24.params[0]; - mouse_scancodes[1] = keyboard_olim24.params[1]; - mouse_scancodes[2] = keyboard_olim24.params[2]; - break; + case 0x12: + keyboard_olim24.mouse_mode = 1; + mouse_scancodes[0] = keyboard_olim24.params[0]; + mouse_scancodes[1] = keyboard_olim24.params[1]; + mouse_scancodes[2] = keyboard_olim24.params[2]; + break; - default:pclog("Bad keyboard command complete %02X\n", keyboard_olim24.command); -// dumpregs(); -// exit(-1); - } - } - } else { - keyboard_olim24.command = val; - switch (val) { - case 0x01: /*Self-test*/ - break; + default: + pclog("Bad keyboard command complete %02X\n", keyboard_olim24.command); + // dumpregs(); + // exit(-1); + } + } + } else { + keyboard_olim24.command = val; + switch (val) { + case 0x01: /*Self-test*/ + break; - case 0x05: /*Read ID*/ - keyboard_olim24_adddata(0x00); - break; + case 0x05: /*Read ID*/ + keyboard_olim24_adddata(0x00); + break; - case 0x11:keyboard_olim24.param = 0; - keyboard_olim24.param_total = 9; - break; + case 0x11: + keyboard_olim24.param = 0; + keyboard_olim24.param_total = 9; + break; - case 0x12:keyboard_olim24.param = 0; - keyboard_olim24.param_total = 4; - break; + case 0x12: + keyboard_olim24.param = 0; + keyboard_olim24.param_total = 4; + break; - default:pclog("Bad keyboard command %02X\n", val); -// dumpregs(); -// exit(-1); - } - } + default: + pclog("Bad keyboard command %02X\n", val); + // dumpregs(); + // exit(-1); + } + } - break; + break; - case 0x61:ppi.pb = val; + case 0x61: + ppi.pb = val; - timer_process(); + timer_process(); - 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; - } + 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; + } } uint8_t keyboard_olim24_read(uint16_t port, void *priv) { - uint8_t temp = 0xff; -// pclog("keyboard_olim24 : read %04X ", port); - switch (port) { - case 0x60:temp = keyboard_olim24.out; - if (key_queue_start == key_queue_end) { - keyboard_olim24.status &= ~STAT_OFULL; - keyboard_olim24.wantirq = 0; - } else { - keyboard_olim24.out = key_queue[key_queue_start]; - key_queue_start = (key_queue_start + 1) & 0xf; - keyboard_olim24.status |= STAT_OFULL; - keyboard_olim24.status &= ~STAT_IFULL; - keyboard_olim24.wantirq = 1; - } - break; + uint8_t temp = 0xff; + // pclog("keyboard_olim24 : read %04X ", port); + switch (port) { + case 0x60: + temp = keyboard_olim24.out; + if (key_queue_start == key_queue_end) { + keyboard_olim24.status &= ~STAT_OFULL; + keyboard_olim24.wantirq = 0; + } else { + keyboard_olim24.out = key_queue[key_queue_start]; + key_queue_start = (key_queue_start + 1) & 0xf; + keyboard_olim24.status |= STAT_OFULL; + keyboard_olim24.status &= ~STAT_IFULL; + keyboard_olim24.wantirq = 1; + } + break; - case 0x61:return ppi.pb; + case 0x61: + return ppi.pb; - case 0x64:temp = keyboard_olim24.status; - keyboard_olim24.status &= ~(STAT_RTIMEOUT | STAT_TTIMEOUT); - break; + case 0x64: + temp = keyboard_olim24.status; + keyboard_olim24.status &= ~(STAT_RTIMEOUT | STAT_TTIMEOUT); + break; - default:pclog("\nBad olim24 keyboard read %04X\n", port); -// dumpregs(); -// exit(-1); - } -// pclog("%02X\n", temp); - return temp; + default: + pclog("\nBad olim24 keyboard read %04X\n", port); + // dumpregs(); + // exit(-1); + } + // pclog("%02X\n", temp); + return temp; } void keyboard_olim24_reset() { - keyboard_olim24.status = STAT_LOCK | STAT_CD; - keyboard_olim24.wantirq = 0; + keyboard_olim24.status = STAT_LOCK | STAT_CD; + keyboard_olim24.wantirq = 0; - keyboard_scan = 1; + keyboard_scan = 1; - keyboard_olim24.param = keyboard_olim24.param_total = 0; + keyboard_olim24.param = keyboard_olim24.param_total = 0; - keyboard_olim24.mouse_mode = 0; - mouse_scancodes[0] = 0x1c; - mouse_scancodes[1] = 0x53; - mouse_scancodes[2] = 0x01; - mouse_scancodes[3] = 0x4b; - mouse_scancodes[4] = 0x4d; - mouse_scancodes[5] = 0x48; - mouse_scancodes[6] = 0x50; + keyboard_olim24.mouse_mode = 0; + mouse_scancodes[0] = 0x1c; + mouse_scancodes[1] = 0x53; + mouse_scancodes[2] = 0x01; + mouse_scancodes[3] = 0x4b; + mouse_scancodes[4] = 0x4d; + mouse_scancodes[5] = 0x48; + mouse_scancodes[6] = 0x50; } typedef struct mouse_olim24_t { - int x, y, b; + int x, y, b; } mouse_olim24_t; void mouse_olim24_poll(int x, int y, int z, int b, void *p) { - mouse_olim24_t *mouse = (mouse_olim24_t *)p; + mouse_olim24_t *mouse = (mouse_olim24_t *)p; - mouse->x += x; - mouse->y += y; + mouse->x += x; + mouse->y += y; -// pclog("mouse_poll - %i, %i %i, %i\n", x, y, mouse->x, mouse->y); + // pclog("mouse_poll - %i, %i %i, %i\n", x, y, mouse->x, mouse->y); - if (((key_queue_end - key_queue_start) & 0xf) > 14) - return; - if ((b & 1) && !(mouse->b & 1)) - keyboard_olim24_adddata(mouse_scancodes[0]); - if (!(b & 1) && (mouse->b & 1)) - keyboard_olim24_adddata(mouse_scancodes[0] | 0x80); - mouse->b = (mouse->b & ~1) | (b & 1); + if (((key_queue_end - key_queue_start) & 0xf) > 14) + return; + if ((b & 1) && !(mouse->b & 1)) + keyboard_olim24_adddata(mouse_scancodes[0]); + if (!(b & 1) && (mouse->b & 1)) + keyboard_olim24_adddata(mouse_scancodes[0] | 0x80); + mouse->b = (mouse->b & ~1) | (b & 1); - if (((key_queue_end - key_queue_start) & 0xf) > 14) - return; - if ((b & 2) && !(mouse->b & 2)) - keyboard_olim24_adddata(mouse_scancodes[2]); - if (!(b & 2) && (mouse->b & 2)) - keyboard_olim24_adddata(mouse_scancodes[2] | 0x80); - mouse->b = (mouse->b & ~2) | (b & 2); + if (((key_queue_end - key_queue_start) & 0xf) > 14) + return; + if ((b & 2) && !(mouse->b & 2)) + keyboard_olim24_adddata(mouse_scancodes[2]); + if (!(b & 2) && (mouse->b & 2)) + keyboard_olim24_adddata(mouse_scancodes[2] | 0x80); + mouse->b = (mouse->b & ~2) | (b & 2); - if (((key_queue_end - key_queue_start) & 0xf) > 14) - return; - if ((b & 4) && !(mouse->b & 4)) - keyboard_olim24_adddata(mouse_scancodes[1]); - if (!(b & 4) && (mouse->b & 4)) - keyboard_olim24_adddata(mouse_scancodes[1] | 0x80); - mouse->b = (mouse->b & ~4) | (b & 4); + if (((key_queue_end - key_queue_start) & 0xf) > 14) + return; + if ((b & 4) && !(mouse->b & 4)) + keyboard_olim24_adddata(mouse_scancodes[1]); + if (!(b & 4) && (mouse->b & 4)) + keyboard_olim24_adddata(mouse_scancodes[1] | 0x80); + mouse->b = (mouse->b & ~4) | (b & 4); - if (keyboard_olim24.mouse_mode) { - if (((key_queue_end - key_queue_start) & 0xf) > 12) - return; - if (!mouse->x && !mouse->y) - return; + if (keyboard_olim24.mouse_mode) { + if (((key_queue_end - key_queue_start) & 0xf) > 12) + return; + if (!mouse->x && !mouse->y) + return; - mouse->y = -mouse->y; + mouse->y = -mouse->y; - if (mouse->x < -127) - mouse->x = -127; - if (mouse->x > 127) - mouse->x = 127; - if (mouse->x < -127) - mouse->x = 0x80 | ((-mouse->x) & 0x7f); + if (mouse->x < -127) + mouse->x = -127; + if (mouse->x > 127) + mouse->x = 127; + if (mouse->x < -127) + mouse->x = 0x80 | ((-mouse->x) & 0x7f); - if (mouse->y < -127) - mouse->y = -127; - if (mouse->y > 127) - mouse->y = 127; - if (mouse->y < -127) - mouse->y = 0x80 | ((-mouse->y) & 0x7f); + if (mouse->y < -127) + mouse->y = -127; + if (mouse->y > 127) + mouse->y = 127; + if (mouse->y < -127) + mouse->y = 0x80 | ((-mouse->y) & 0x7f); - keyboard_olim24_adddata(0xfe); - keyboard_olim24_adddata(mouse->x); - keyboard_olim24_adddata(mouse->y); + keyboard_olim24_adddata(0xfe); + keyboard_olim24_adddata(mouse->x); + keyboard_olim24_adddata(mouse->y); - mouse->x = mouse->y = 0; - } else { - while (mouse->x < -4) { - if (((key_queue_end - key_queue_start) & 0xf) > 14) - return; - mouse->x += 4; - keyboard_olim24_adddata(mouse_scancodes[3]); - } - while (mouse->x > 4) { - if (((key_queue_end - key_queue_start) & 0xf) > 14) - return; - mouse->x -= 4; - keyboard_olim24_adddata(mouse_scancodes[4]); - } - while (mouse->y < -4) { - if (((key_queue_end - key_queue_start) & 0xf) > 14) - return; - mouse->y += 4; - keyboard_olim24_adddata(mouse_scancodes[5]); - } - while (mouse->y > 4) { - if (((key_queue_end - key_queue_start) & 0xf) > 14) - return; - mouse->y -= 4; - keyboard_olim24_adddata(mouse_scancodes[6]); - } - } + mouse->x = mouse->y = 0; + } else { + while (mouse->x < -4) { + if (((key_queue_end - key_queue_start) & 0xf) > 14) + return; + mouse->x += 4; + keyboard_olim24_adddata(mouse_scancodes[3]); + } + while (mouse->x > 4) { + if (((key_queue_end - key_queue_start) & 0xf) > 14) + return; + mouse->x -= 4; + keyboard_olim24_adddata(mouse_scancodes[4]); + } + while (mouse->y < -4) { + if (((key_queue_end - key_queue_start) & 0xf) > 14) + return; + mouse->y += 4; + keyboard_olim24_adddata(mouse_scancodes[5]); + } + while (mouse->y > 4) { + if (((key_queue_end - key_queue_start) & 0xf) > 14) + return; + mouse->y -= 4; + keyboard_olim24_adddata(mouse_scancodes[6]); + } + } } static void *mouse_olim24_init() { - mouse_olim24_t *mouse = (mouse_olim24_t *)malloc(sizeof(mouse_olim24_t)); - memset(mouse, 0, sizeof(mouse_olim24_t)); + mouse_olim24_t *mouse = (mouse_olim24_t *)malloc(sizeof(mouse_olim24_t)); + memset(mouse, 0, sizeof(mouse_olim24_t)); - return mouse; + return mouse; } static void mouse_olim24_close(void *p) { - mouse_olim24_t *mouse = (mouse_olim24_t *)p; + mouse_olim24_t *mouse = (mouse_olim24_t *)p; - free(mouse); + free(mouse); } -mouse_t mouse_olim24 = - { - "Olivetti M24 mouse", - mouse_olim24_init, - mouse_olim24_close, - mouse_olim24_poll, - MOUSE_TYPE_OLIM24 - }; +mouse_t mouse_olim24 = {"Olivetti M24 mouse", mouse_olim24_init, mouse_olim24_close, mouse_olim24_poll, MOUSE_TYPE_OLIM24}; void keyboard_olim24_init() { - //return; - io_sethandler(0x0060, 0x0002, keyboard_olim24_read, NULL, NULL, keyboard_olim24_write, NULL, NULL, NULL); - io_sethandler(0x0064, 0x0001, keyboard_olim24_read, NULL, NULL, keyboard_olim24_write, NULL, NULL, NULL); - keyboard_olim24_reset(); - keyboard_send = keyboard_olim24_adddata; - keyboard_poll = keyboard_olim24_poll; + // return; + io_sethandler(0x0060, 0x0002, keyboard_olim24_read, NULL, NULL, keyboard_olim24_write, NULL, NULL, NULL); + io_sethandler(0x0064, 0x0001, keyboard_olim24_read, NULL, NULL, keyboard_olim24_write, NULL, NULL, NULL); + keyboard_olim24_reset(); + keyboard_send = keyboard_olim24_adddata; + keyboard_poll = keyboard_olim24_poll; - timer_add(&keyboard_olim24.send_delay_timer, keyboard_olim24_poll, NULL, 1); + timer_add(&keyboard_olim24.send_delay_timer, keyboard_olim24_poll, NULL, 1); } diff --git a/src/keyboard/keyboard_pcjr.c b/src/keyboard/keyboard_pcjr.c index a2a6a5b5..f187c068 100644 --- a/src/keyboard/keyboard_pcjr.c +++ b/src/keyboard/keyboard_pcjr.c @@ -15,176 +15,185 @@ #include "keyboard.h" #include "keyboard_pcjr.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 +#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 struct { - int latched; - int data; + int latched; + int data; - int serial_data[44]; - int serial_pos; + int serial_data[44]; + int serial_pos; - uint8_t pa; - uint8_t pb; + uint8_t pa; + uint8_t pb; - pc_timer_t send_delay_timer; + pc_timer_t send_delay_timer; } keyboard_pcjr; static uint8_t key_queue[16]; static int key_queue_start = 0, key_queue_end = 0; void keyboard_pcjr_poll() { - timer_advance_u64(&keyboard_pcjr.send_delay_timer, (220 * TIMER_USEC)); + timer_advance_u64(&keyboard_pcjr.send_delay_timer, (220 * TIMER_USEC)); - if (key_queue_start != key_queue_end && !keyboard_pcjr.serial_pos && !keyboard_pcjr.latched) { - int c; - int p = 0; - uint8_t key = key_queue[key_queue_start]; + if (key_queue_start != key_queue_end && !keyboard_pcjr.serial_pos && !keyboard_pcjr.latched) { + int c; + int p = 0; + uint8_t key = key_queue[key_queue_start]; -// pclog("Reading %02X from the key queue at %i\n", key, key_queue_start); - key_queue_start = (key_queue_start + 1) & 0xf; + // pclog("Reading %02X from the key queue at %i\n", key, key_queue_start); + key_queue_start = (key_queue_start + 1) & 0xf; - keyboard_pcjr.latched = 1; + keyboard_pcjr.latched = 1; - keyboard_pcjr.serial_data[0] = 1; /*Start bit*/ - keyboard_pcjr.serial_data[1] = 0; + keyboard_pcjr.serial_data[0] = 1; /*Start bit*/ + keyboard_pcjr.serial_data[1] = 0; - for (c = 0; c < 8; c++) { - if (key & (1 << c)) { - keyboard_pcjr.serial_data[(c + 1) * 2] = 1; - keyboard_pcjr.serial_data[(c + 1) * 2 + 1] = 0; - p++; - } else { - keyboard_pcjr.serial_data[(c + 1) * 2] = 0; - keyboard_pcjr.serial_data[(c + 1) * 2 + 1] = 1; - } - } + for (c = 0; c < 8; c++) { + if (key & (1 << c)) { + keyboard_pcjr.serial_data[(c + 1) * 2] = 1; + keyboard_pcjr.serial_data[(c + 1) * 2 + 1] = 0; + p++; + } else { + keyboard_pcjr.serial_data[(c + 1) * 2] = 0; + keyboard_pcjr.serial_data[(c + 1) * 2 + 1] = 1; + } + } - if (p & 1) /*Parity*/ - { - keyboard_pcjr.serial_data[9 * 2] = 1; - keyboard_pcjr.serial_data[9 * 2 + 1] = 0; - } else { - keyboard_pcjr.serial_data[9 * 2] = 0; - keyboard_pcjr.serial_data[9 * 2 + 1] = 1; - } + if (p & 1) /*Parity*/ + { + keyboard_pcjr.serial_data[9 * 2] = 1; + keyboard_pcjr.serial_data[9 * 2 + 1] = 0; + } else { + keyboard_pcjr.serial_data[9 * 2] = 0; + keyboard_pcjr.serial_data[9 * 2 + 1] = 1; + } - for (c = 0; c < 11; c++) /*11 stop bits*/ - { - keyboard_pcjr.serial_data[(c + 10) * 2] = 0; - keyboard_pcjr.serial_data[(c + 10) * 2 + 1] = 0; - } + for (c = 0; c < 11; c++) /*11 stop bits*/ + { + keyboard_pcjr.serial_data[(c + 10) * 2] = 0; + keyboard_pcjr.serial_data[(c + 10) * 2 + 1] = 0; + } - keyboard_pcjr.serial_pos++; - } + keyboard_pcjr.serial_pos++; + } - if (keyboard_pcjr.serial_pos) { - keyboard_pcjr.data = keyboard_pcjr.serial_data[keyboard_pcjr.serial_pos - 1]; - nmi = keyboard_pcjr.data; - keyboard_pcjr.serial_pos++; - if (keyboard_pcjr.serial_pos == 42 + 1) - keyboard_pcjr.serial_pos = 0; -// pclog("Keyboard poll %i %i\n", keyboard_pcjr.data, keyboard_pcjr.serial_pos); - } + if (keyboard_pcjr.serial_pos) { + keyboard_pcjr.data = keyboard_pcjr.serial_data[keyboard_pcjr.serial_pos - 1]; + nmi = keyboard_pcjr.data; + keyboard_pcjr.serial_pos++; + if (keyboard_pcjr.serial_pos == 42 + 1) + keyboard_pcjr.serial_pos = 0; + // pclog("Keyboard poll %i %i\n", keyboard_pcjr.data, keyboard_pcjr.serial_pos); + } } void keyboard_pcjr_adddata(uint8_t val) { - key_queue[key_queue_end] = val; -// pclog("keyboard_pcjr : %02X added to key queue at %i\n", val, key_queue_end); - key_queue_end = (key_queue_end + 1) & 0xf; - return; + key_queue[key_queue_end] = val; + // pclog("keyboard_pcjr : %02X added to key queue at %i\n", val, key_queue_end); + key_queue_end = (key_queue_end + 1) & 0xf; + return; } void keyboard_pcjr_write(uint16_t port, uint8_t val, void *priv) { -// pclog("keyboard_pcjr : write %04X %02X %02X\n", port, val, keyboard_pcjr.pb); -/* if (ram[8] == 0xc3) - { - output = 3; - }*/ - switch (port) { - case 0x60:keyboard_pcjr.pa = val; - break; + // pclog("keyboard_pcjr : write %04X %02X %02X\n", port, val, keyboard_pcjr.pb); + /* if (ram[8] == 0xc3) + { + output = 3; + }*/ + switch (port) { + case 0x60: + keyboard_pcjr.pa = val; + break; - case 0x61:keyboard_pcjr.pb = val; + case 0x61: + keyboard_pcjr.pb = val; - timer_process(); + timer_process(); - cassette_set_motor((val & 8) ? 0 : 1); + cassette_set_motor((val & 8) ? 0 : 1); - 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; + 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; - } + case 0xa0: + nmi_mask = val & 0x80; + pit_set_using_timer(&pit, 1, !(val & 0x20)); + break; + } } uint8_t keyboard_pcjr_read(uint16_t port, void *priv) { - uint8_t temp = 0xff; -// pclog("keyboard_pcjr : read %04X ", port); - switch (port) { - case 0x60:temp = keyboard_pcjr.pa; - break; + uint8_t temp = 0xff; + // pclog("keyboard_pcjr : read %04X ", port); + switch (port) { + case 0x60: + temp = keyboard_pcjr.pa; + break; - case 0x61:temp = keyboard_pcjr.pb; - break; + case 0x61: + temp = keyboard_pcjr.pb; + break; - case 0x62:temp = (keyboard_pcjr.latched ? 1 : 0); - temp |= 0x02; /*Modem card not installed*/ - if (fdd_get_type(0) == 0) - temp |= 0x04; /*Disc card not installed*/ - if (!(keyboard_pcjr.pb & 8)) - temp |= (cassette_input()) ? 0x10 : 0; - else - temp |= (ppispeakon ? 0x10 : 0); - temp |= (ppispeakon ? 0x20 : 0); - temp |= (keyboard_pcjr.data ? 0x40 : 0); -// temp |= 0x04; - if (keyboard_pcjr.data) - temp |= 0x40; - break; + case 0x62: + temp = (keyboard_pcjr.latched ? 1 : 0); + temp |= 0x02; /*Modem card not installed*/ + if (fdd_get_type(0) == 0) + temp |= 0x04; /*Disc card not installed*/ + if (!(keyboard_pcjr.pb & 8)) + temp |= (cassette_input()) ? 0x10 : 0; + else + temp |= (ppispeakon ? 0x10 : 0); + temp |= (ppispeakon ? 0x20 : 0); + temp |= (keyboard_pcjr.data ? 0x40 : 0); + // temp |= 0x04; + if (keyboard_pcjr.data) + temp |= 0x40; + break; - case 0xa0:keyboard_pcjr.latched = 0; - break; + case 0xa0: + keyboard_pcjr.latched = 0; + break; - default:pclog("\nBad XT keyboard read %04X\n", port); - //dumpregs(); - //exit(-1); - } -// pclog("%02X\n", temp); - return temp; + default: + pclog("\nBad XT keyboard read %04X\n", port); + // dumpregs(); + // exit(-1); + } + // pclog("%02X\n", temp); + return temp; } -void keyboard_pcjr_reset() { -} +void keyboard_pcjr_reset() {} void keyboard_pcjr_init() { - //return; - io_sethandler(0x0060, 0x0004, keyboard_pcjr_read, NULL, NULL, keyboard_pcjr_write, NULL, NULL, NULL); - io_sethandler(0x00a0, 0x0008, keyboard_pcjr_read, NULL, NULL, keyboard_pcjr_write, NULL, NULL, NULL); - keyboard_pcjr_reset(); - keyboard_send = keyboard_pcjr_adddata; - keyboard_poll = keyboard_pcjr_poll; + // return; + io_sethandler(0x0060, 0x0004, keyboard_pcjr_read, NULL, NULL, keyboard_pcjr_write, NULL, NULL, NULL); + io_sethandler(0x00a0, 0x0008, keyboard_pcjr_read, NULL, NULL, keyboard_pcjr_write, NULL, NULL, NULL); + keyboard_pcjr_reset(); + keyboard_send = keyboard_pcjr_adddata; + keyboard_poll = keyboard_pcjr_poll; - timer_add(&keyboard_pcjr.send_delay_timer, keyboard_pcjr_poll, NULL, 1); + timer_add(&keyboard_pcjr.send_delay_timer, keyboard_pcjr_poll, NULL, 1); } diff --git a/src/keyboard/keyboard_xt.c b/src/keyboard/keyboard_xt.c index ac60252d..2ddb3713 100644 --- a/src/keyboard/keyboard_xt.c +++ b/src/keyboard/keyboard_xt.c @@ -16,235 +16,238 @@ #include "keyboard.h" #include "keyboard_xt.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 +#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 struct { - int wantirq; - uint8_t key_waiting; + int wantirq; + uint8_t key_waiting; - uint8_t pa; - uint8_t pb; + uint8_t pa; + uint8_t pb; - int shift_full; + int shift_full; - int tandy; - int pb2_turbo; + int tandy; + int pb2_turbo; - pc_timer_t send_delay_timer; + pc_timer_t send_delay_timer; } keyboard_xt; static uint8_t key_queue[16]; static int key_queue_start = 0, key_queue_end = 0; void keyboard_xt_poll() { - timer_advance_u64(&keyboard_xt.send_delay_timer, (1000 * TIMER_USEC)); - if (!(keyboard_xt.pb & 0x40) && romset != ROM_TANDY) - return; - if (keyboard_xt.wantirq) { - keyboard_xt.wantirq = 0; - keyboard_xt.pa = keyboard_xt.key_waiting; - keyboard_xt.shift_full = 1; - picint(2); - pclog("keyboard_xt : take IRQ\n"); - } - if (key_queue_start != key_queue_end && !keyboard_xt.shift_full) { - keyboard_xt.key_waiting = key_queue[key_queue_start]; - pclog("Reading %02X from the key queue at %i\n", keyboard_xt.key_waiting, key_queue_start); - key_queue_start = (key_queue_start + 1) & 0xf; - keyboard_xt.wantirq = 1; - } + timer_advance_u64(&keyboard_xt.send_delay_timer, (1000 * TIMER_USEC)); + if (!(keyboard_xt.pb & 0x40) && romset != ROM_TANDY) + return; + if (keyboard_xt.wantirq) { + keyboard_xt.wantirq = 0; + keyboard_xt.pa = keyboard_xt.key_waiting; + keyboard_xt.shift_full = 1; + picint(2); + pclog("keyboard_xt : take IRQ\n"); + } + if (key_queue_start != key_queue_end && !keyboard_xt.shift_full) { + keyboard_xt.key_waiting = key_queue[key_queue_start]; + pclog("Reading %02X from the key queue at %i\n", keyboard_xt.key_waiting, key_queue_start); + key_queue_start = (key_queue_start + 1) & 0xf; + keyboard_xt.wantirq = 1; + } } void keyboard_xt_adddata(uint8_t val) { - /* Test for T1000 'Fn' key (Right Alt / Right Ctrl) */ - if (romset == ROM_T1000 || romset == ROM_T1200) { - if (pcem_key[0xb8] || pcem_key[0x9D]) /* 'Fn' pressed */ - { - t1000_syskey(0x00, 0x04, 0x00); /* Set 'Fn' indicator */ - switch (val) { - case 0x45: /* Num Lock => toggle numpad */ - t1000_syskey(0x00, 0x00, 0x10); - break; - case 0x47: /* Home => internal display */ - t1000_syskey(0x40, 0x00, 0x00); - break; - case 0x49: /* PgDn => turbo on */ - t1000_syskey(0x80, 0x00, 0x00); - break; - case 0x4D: /* Right => toggle LCD font */ - t1000_syskey(0x00, 0x00, 0x20); - break; - case 0x4F: /* End => external display */ - t1000_syskey(0x00, 0x40, 0x00); - break; - case 0x51: /* PgDn => turbo off */ - t1000_syskey(0x00, 0x80, 0x00); - break; - case 0x54: /* SysRQ => toggle window */ - t1000_syskey(0x00, 0x00, 0x08); - break; - } - } else { - t1000_syskey(0x04, 0x00, 0x00); /* Reset 'Fn' indicator */ - } - } + /* Test for T1000 'Fn' key (Right Alt / Right Ctrl) */ + if (romset == ROM_T1000 || romset == ROM_T1200) { + if (pcem_key[0xb8] || pcem_key[0x9D]) /* 'Fn' pressed */ + { + t1000_syskey(0x00, 0x04, 0x00); /* Set 'Fn' indicator */ + switch (val) { + case 0x45: /* Num Lock => toggle numpad */ + t1000_syskey(0x00, 0x00, 0x10); + break; + case 0x47: /* Home => internal display */ + t1000_syskey(0x40, 0x00, 0x00); + break; + case 0x49: /* PgDn => turbo on */ + t1000_syskey(0x80, 0x00, 0x00); + break; + case 0x4D: /* Right => toggle LCD font */ + t1000_syskey(0x00, 0x00, 0x20); + break; + case 0x4F: /* End => external display */ + t1000_syskey(0x00, 0x40, 0x00); + break; + case 0x51: /* PgDn => turbo off */ + t1000_syskey(0x00, 0x80, 0x00); + break; + case 0x54: /* SysRQ => toggle window */ + t1000_syskey(0x00, 0x00, 0x08); + break; + } + } else { + t1000_syskey(0x04, 0x00, 0x00); /* Reset 'Fn' indicator */ + } + } - key_queue[key_queue_end] = val; - pclog("keyboard_xt : %02X added to key queue at %i\n", val, key_queue_end); - key_queue_end = (key_queue_end + 1) & 0xf; - return; + key_queue[key_queue_end] = val; + pclog("keyboard_xt : %02X added to key queue at %i\n", val, key_queue_end); + key_queue_end = (key_queue_end + 1) & 0xf; + return; } void keyboard_xt_write(uint16_t port, uint8_t val, void *priv) { -// pclog("keyboard_xt : write %04X %02X %02X\n", port, val, keyboard_xt.pb); -/* if (ram[8] == 0xc3) - { - output = 3; - }*/ - switch (port) { - case 0x61: -// pclog("keyboard_xt : pb write %02X %02X %i %02X %i\n", val, keyboard_xt.pb, !(keyboard_xt.pb & 0x40), keyboard_xt.pb & 0x40, (val & 0x40)); - if (!(keyboard_xt.pb & 0x40) && (val & 0x40)) /*Reset keyboard*/ - { - pclog("keyboard_xt : reset keyboard\n"); - key_queue_start = key_queue_end = 0; - keyboard_xt.wantirq = 0; - keyboard_xt.shift_full = 0; - keyboard_xt_adddata(0xaa); - } - keyboard_xt.pb = val; - ppi.pb = val; + // pclog("keyboard_xt : write %04X %02X %02X\n", port, val, keyboard_xt.pb); + /* if (ram[8] == 0xc3) + { + output = 3; + }*/ + switch (port) { + case 0x61: + // pclog("keyboard_xt : pb write %02X %02X %i %02X %i\n", val, keyboard_xt.pb, !(keyboard_xt.pb & + // 0x40), keyboard_xt.pb & 0x40, (val & 0x40)); + if (!(keyboard_xt.pb & 0x40) && (val & 0x40)) /*Reset keyboard*/ + { + pclog("keyboard_xt : reset keyboard\n"); + key_queue_start = key_queue_end = 0; + keyboard_xt.wantirq = 0; + keyboard_xt.shift_full = 0; + keyboard_xt_adddata(0xaa); + } + keyboard_xt.pb = val; + ppi.pb = val; - timer_process(); + timer_process(); - if (romset == ROM_IBMPC) - cassette_set_motor((val & 8) ? 0 : 1); - else if (keyboard_xt.pb2_turbo) - cpu_set_turbo((val & 4) ? 0 : 1); + if (romset == ROM_IBMPC) + cassette_set_motor((val & 8) ? 0 : 1); + else if (keyboard_xt.pb2_turbo) + cpu_set_turbo((val & 4) ? 0 : 1); - speaker_update(); - speaker_gated = val & 1; - speaker_enable = val & 2; - if (speaker_enable) - was_speaker_enable = 1; - pit_set_gate(&pit, 2, val & 1); + 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 (val & 0x80) { - keyboard_xt.pa = 0; - keyboard_xt.shift_full = 0; - picintc(2); - } - break; - } + if (val & 0x80) { + keyboard_xt.pa = 0; + keyboard_xt.shift_full = 0; + picintc(2); + } + break; + } } uint8_t keyboard_xt_read(uint16_t port, void *priv) { - uint8_t temp = 0xff; -// pclog("keyboard_xt : read %04X ", port); - switch (port) { - case 0x60: - if ((romset == ROM_IBMPC || romset == ROM_LEDGE_MODELM) && (keyboard_xt.pb & 0x80)) { - if (video_is_ega_vga()) - temp = 0x4D; - else if (video_is_mda()) - temp = 0x7D; - else - temp = 0x6D; - if (hasfpu) - temp |= 0x02; - } else if ((romset == ROM_ATARIPC3) && (keyboard_xt.pb & 0x80)) { - temp = 0x7f; - } else { - temp = keyboard_xt.pa; - } - break; + uint8_t temp = 0xff; + // pclog("keyboard_xt : read %04X ", port); + switch (port) { + case 0x60: + if ((romset == ROM_IBMPC || romset == ROM_LEDGE_MODELM) && (keyboard_xt.pb & 0x80)) { + if (video_is_ega_vga()) + temp = 0x4D; + else if (video_is_mda()) + temp = 0x7D; + else + temp = 0x6D; + if (hasfpu) + temp |= 0x02; + } else if ((romset == ROM_ATARIPC3) && (keyboard_xt.pb & 0x80)) { + temp = 0x7f; + } else { + temp = keyboard_xt.pa; + } + break; - case 0x61:temp = keyboard_xt.pb; - break; + case 0x61: + temp = keyboard_xt.pb; + break; - case 0x62: - if (romset == ROM_IBMPC) { - if (keyboard_xt.pb & 0x04) - temp = ((mem_size - 64) / 32) & 0xf; - else - temp = ((mem_size - 64) / 32) >> 4; + case 0x62: + if (romset == ROM_IBMPC) { + if (keyboard_xt.pb & 0x04) + temp = ((mem_size - 64) / 32) & 0xf; + else + temp = ((mem_size - 64) / 32) >> 4; - temp |= (cassette_input()) ? 0x10 : 0; - } else if (romset == ROM_LEDGE_MODELM) { - /*High bit of memory size is read from port 0xa0*/ - temp = ((mem_size - 64) / 32) & 0xf; - } else if (romset == ROM_ATARIPC3) { - if (keyboard_xt.pb & 0x04) - temp = 0xf; - else - temp = 4; - } else { - if (keyboard_xt.pb & 0x08) { - if (video_is_ega_vga()) - temp = 4; - else if (video_is_mda()) - temp = 7; - else - temp = 6; - } else - temp = hasfpu ? 0xf : 0xd; - } - temp |= (ppispeakon ? 0x20 : 0); - if (keyboard_xt.tandy) - temp |= (tandy_eeprom_read() ? 0x10 : 0); - break; + temp |= (cassette_input()) ? 0x10 : 0; + } else if (romset == ROM_LEDGE_MODELM) { + /*High bit of memory size is read from port 0xa0*/ + temp = ((mem_size - 64) / 32) & 0xf; + } else if (romset == ROM_ATARIPC3) { + if (keyboard_xt.pb & 0x04) + temp = 0xf; + else + temp = 4; + } else { + if (keyboard_xt.pb & 0x08) { + if (video_is_ega_vga()) + temp = 4; + else if (video_is_mda()) + temp = 7; + else + temp = 6; + } else + temp = hasfpu ? 0xf : 0xd; + } + temp |= (ppispeakon ? 0x20 : 0); + if (keyboard_xt.tandy) + temp |= (tandy_eeprom_read() ? 0x10 : 0); + break; - default:pclog("\nBad XT keyboard read %04X\n", port); - //dumpregs(); - //exit(-1); - } -// pclog("%02X\n", temp); - return temp; + default: + pclog("\nBad XT keyboard read %04X\n", port); + // dumpregs(); + // exit(-1); + } + // pclog("%02X\n", temp); + return temp; } static uint8_t ledge_modelm_read(uint16_t port, void *p) { - uint8_t temp = 0; + uint8_t temp = 0; - if (((mem_size - 64) / 32) >> 4) - temp |= 0x40; + if (((mem_size - 64) / 32) >> 4) + temp |= 0x40; - return temp; + return temp; } void keyboard_xt_reset() { - keyboard_xt.wantirq = 0; + keyboard_xt.wantirq = 0; - keyboard_scan = 1; + keyboard_scan = 1; } void keyboard_xt_init() { - //return; - io_sethandler(0x0060, 0x0004, keyboard_xt_read, NULL, NULL, keyboard_xt_write, NULL, NULL, NULL); - if (romset == ROM_LEDGE_MODELM) - io_sethandler(0x00a0, 0x0001, ledge_modelm_read, NULL, NULL, NULL, NULL, NULL, NULL); - keyboard_xt_reset(); - keyboard_send = keyboard_xt_adddata; - keyboard_poll = keyboard_xt_poll; - keyboard_xt.tandy = 0; - keyboard_xt.pb2_turbo = (romset == ROM_GENXT || romset == ROM_DTKXT || romset == ROM_AMIXT || romset == ROM_PXXT) ? 1 : 0; + // return; + io_sethandler(0x0060, 0x0004, keyboard_xt_read, NULL, NULL, keyboard_xt_write, NULL, NULL, NULL); + if (romset == ROM_LEDGE_MODELM) + io_sethandler(0x00a0, 0x0001, ledge_modelm_read, NULL, NULL, NULL, NULL, NULL, NULL); + keyboard_xt_reset(); + keyboard_send = keyboard_xt_adddata; + keyboard_poll = keyboard_xt_poll; + keyboard_xt.tandy = 0; + keyboard_xt.pb2_turbo = (romset == ROM_GENXT || romset == ROM_DTKXT || romset == ROM_AMIXT || romset == ROM_PXXT) ? 1 : 0; - timer_add(&keyboard_xt.send_delay_timer, keyboard_xt_poll, NULL, 1); + timer_add(&keyboard_xt.send_delay_timer, keyboard_xt_poll, NULL, 1); } void keyboard_tandy_init() { - //return; - io_sethandler(0x0060, 0x0004, keyboard_xt_read, NULL, NULL, keyboard_xt_write, NULL, NULL, NULL); - keyboard_xt_reset(); - keyboard_send = keyboard_xt_adddata; - keyboard_poll = keyboard_xt_poll; - keyboard_xt.tandy = (romset != ROM_TANDY) ? 1 : 0; + // return; + io_sethandler(0x0060, 0x0004, keyboard_xt_read, NULL, NULL, keyboard_xt_write, NULL, NULL, NULL); + keyboard_xt_reset(); + keyboard_send = keyboard_xt_adddata; + keyboard_poll = keyboard_xt_poll; + keyboard_xt.tandy = (romset != ROM_TANDY) ? 1 : 0; - timer_add(&keyboard_xt.send_delay_timer, keyboard_xt_poll, NULL, 1); + timer_add(&keyboard_xt.send_delay_timer, keyboard_xt_poll, NULL, 1); } diff --git a/src/lpt/lpt.c b/src/lpt/lpt.c index 2981ff7c..db4c3e73 100644 --- a/src/lpt/lpt.c +++ b/src/lpt/lpt.c @@ -24,143 +24,149 @@ LPT_DEVICE l_lpt_dac = {"LPT DAC / Covox Speech Thing", "lpt_dac", &lpt_dac_devi LPT_DEVICE l_lpt_dac_stereo = {"Stereo LPT DAC", "lpt_dac_stereo", &lpt_dac_stereo_device}; char *lpt_device_get_name(int id) { - if (lpt_devices[id] == NULL || strlen(lpt_devices[id]->name) == 0) - return NULL; - return lpt_devices[id]->name; + if (lpt_devices[id] == NULL || strlen(lpt_devices[id]->name) == 0) + return NULL; + return lpt_devices[id]->name; } char *lpt_device_get_internal_name(int id) { - if (lpt_devices[id] == NULL || strlen(lpt_devices[id]->internal_name) == 0) - return NULL; - return lpt_devices[id]->internal_name; + if (lpt_devices[id] == NULL || strlen(lpt_devices[id]->internal_name) == 0) + return NULL; + return lpt_devices[id]->internal_name; } static lpt_device_t *lpt1_device; static void *lpt1_device_p; void lpt1_device_init() { - int c = 0; + int c = 0; - while (lpt_devices[c] != NULL && strcmp(lpt_devices[c]->internal_name, lpt1_device_name) && strlen(lpt_devices[c]->internal_name) != 0) - c++; + while (lpt_devices[c] != NULL && strcmp(lpt_devices[c]->internal_name, lpt1_device_name) && + strlen(lpt_devices[c]->internal_name) != 0) + c++; - if (lpt_devices[c] == NULL || strlen(lpt_devices[c]->internal_name) == 0) - lpt1_device = NULL; - else if (lpt_devices[c] != NULL) { - lpt1_device = lpt_devices[c]->device; - if (lpt1_device) - lpt1_device_p = lpt1_device->init(); - } + if (lpt_devices[c] == NULL || strlen(lpt_devices[c]->internal_name) == 0) + lpt1_device = NULL; + else if (lpt_devices[c] != NULL) { + lpt1_device = lpt_devices[c]->device; + if (lpt1_device) + lpt1_device_p = lpt1_device->init(); + } } void lpt1_device_close() { - if (lpt1_device) - lpt1_device->close(lpt1_device_p); - lpt1_device = NULL; + if (lpt1_device) + lpt1_device->close(lpt1_device_p); + lpt1_device = NULL; } static uint8_t lpt1_dat, lpt2_dat; static uint8_t lpt1_ctrl, lpt2_ctrl; void lpt1_write(uint16_t port, uint8_t val, void *priv) { - switch (port & 3) { - case 0: - if (lpt1_device) - lpt1_device->write_data(val, lpt1_device_p); - lpt1_dat = val; - break; - case 2: - if (lpt1_device) - lpt1_device->write_ctrl(val, lpt1_device_p); - lpt1_ctrl = val; - break; - } + switch (port & 3) { + case 0: + if (lpt1_device) + lpt1_device->write_data(val, lpt1_device_p); + lpt1_dat = val; + break; + case 2: + if (lpt1_device) + lpt1_device->write_ctrl(val, lpt1_device_p); + lpt1_ctrl = val; + break; + } } int lpt_device_has_config(int devId) { - if (lpt_devices[devId] == NULL || !lpt_devices[devId]->device) - return 0; - return lpt_devices[devId]->device->config ? 1 : 0; + if (lpt_devices[devId] == NULL || !lpt_devices[devId]->device) + return 0; + return lpt_devices[devId]->device->config ? 1 : 0; } lpt_device_t *lpt_get_device(int devId) { - if (lpt_devices[devId] == NULL || !lpt_devices[devId]->device) - return 0; + if (lpt_devices[devId] == NULL || !lpt_devices[devId]->device) + return 0; - return lpt_devices[devId]->device; + return lpt_devices[devId]->device; } int lpt_device_get_from_internal_name(char *s) { - int c = 0; + int c = 0; - while (lpt_devices[c] != NULL && strlen(lpt_devices[c]->internal_name)) { - if (!strcmp(lpt_devices[c]->internal_name, s)) - return c; - c++; - } + while (lpt_devices[c] != NULL && strlen(lpt_devices[c]->internal_name)) { + if (!strcmp(lpt_devices[c]->internal_name, s)) + return c; + c++; + } - return 0; + return 0; } uint8_t lpt1_read(uint16_t port, void *priv) { - switch (port & 3) { - case 0:return lpt1_dat; - case 1: - if (lpt1_device) - return lpt1_device->read_status(lpt1_device_p); - return 0; - case 2:return lpt1_ctrl; - } - return 0xff; + switch (port & 3) { + case 0: + return lpt1_dat; + case 1: + if (lpt1_device) + return lpt1_device->read_status(lpt1_device_p); + return 0; + case 2: + return lpt1_ctrl; + } + return 0xff; } void lpt2_write(uint16_t port, uint8_t val, void *priv) { - switch (port & 3) { - case 0:lpt2_dat = val; - break; - case 2:lpt2_ctrl = val; - break; - } + switch (port & 3) { + case 0: + lpt2_dat = val; + break; + case 2: + lpt2_ctrl = val; + break; + } } uint8_t lpt2_read(uint16_t port, void *priv) { - switch (port & 3) { - case 0:return lpt2_dat; - case 1:return 0; - case 2:return lpt2_ctrl; - } - return 0xff; + switch (port & 3) { + case 0: + return lpt2_dat; + case 1: + return 0; + case 2: + return lpt2_ctrl; + } + return 0xff; } void lpt_init() { - 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); + 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); } void lpt1_init(uint16_t port) { - if (port) - io_sethandler(port, 0x0003, lpt1_read, NULL, NULL, lpt1_write, NULL, NULL, NULL); + if (port) + io_sethandler(port, 0x0003, lpt1_read, NULL, NULL, lpt1_write, NULL, NULL, NULL); } void lpt1_remove() { - io_removehandler(0x0278, 0x0003, lpt1_read, NULL, NULL, lpt1_write, NULL, NULL, NULL); - io_removehandler(0x0378, 0x0003, lpt1_read, NULL, NULL, lpt1_write, NULL, NULL, NULL); - io_removehandler(0x03bc, 0x0003, lpt1_read, NULL, NULL, lpt1_write, NULL, NULL, NULL); + io_removehandler(0x0278, 0x0003, lpt1_read, NULL, NULL, lpt1_write, NULL, NULL, NULL); + io_removehandler(0x0378, 0x0003, lpt1_read, NULL, NULL, lpt1_write, NULL, NULL, NULL); + io_removehandler(0x03bc, 0x0003, lpt1_read, NULL, NULL, lpt1_write, NULL, NULL, NULL); } void lpt2_init(uint16_t port) { - if (port) - io_sethandler(port, 0x0003, lpt2_read, NULL, NULL, lpt2_write, NULL, NULL, NULL); + if (port) + io_sethandler(port, 0x0003, lpt2_read, NULL, NULL, lpt2_write, NULL, NULL, NULL); } void lpt2_remove() { - io_removehandler(0x0278, 0x0003, lpt2_read, NULL, NULL, lpt2_write, NULL, NULL, NULL); - io_removehandler(0x0378, 0x0003, lpt2_read, NULL, NULL, lpt2_write, NULL, NULL, NULL); - io_removehandler(0x03bc, 0x0003, lpt2_read, NULL, NULL, lpt2_write, NULL, NULL, NULL); + io_removehandler(0x0278, 0x0003, lpt2_read, NULL, NULL, lpt2_write, NULL, NULL, NULL); + io_removehandler(0x0378, 0x0003, lpt2_read, NULL, NULL, lpt2_write, NULL, NULL, NULL); + io_removehandler(0x03bc, 0x0003, lpt2_read, NULL, NULL, lpt2_write, NULL, NULL, NULL); } -void lpt2_remove_ams() { - io_removehandler(0x0379, 0x0002, lpt2_read, NULL, NULL, lpt2_write, NULL, NULL, NULL); -} +void lpt2_remove_ams() { io_removehandler(0x0379, 0x0002, lpt2_read, NULL, NULL, lpt2_write, NULL, NULL, NULL); } void lpt_init_builtin() { - pcem_add_lpt(&l_none); - pcem_add_lpt(&l_dss); - pcem_add_lpt(&l_lpt_dac); - pcem_add_lpt(&l_lpt_dac_stereo); + pcem_add_lpt(&l_none); + pcem_add_lpt(&l_dss); + pcem_add_lpt(&l_lpt_dac); + pcem_add_lpt(&l_lpt_dac_stereo); } \ No newline at end of file diff --git a/src/lpt/lpt_dac.c b/src/lpt/lpt_dac.c index ebcaee62..a9daabcb 100644 --- a/src/lpt/lpt_dac.c +++ b/src/lpt/lpt_dac.c @@ -6,107 +6,93 @@ #include "sound.h" typedef struct lpt_dac_t { - uint8_t dac_val_l, dac_val_r; + uint8_t dac_val_l, dac_val_r; - int is_stereo; - int channel; + int is_stereo; + int channel; - int16_t buffer[2][MAXSOUNDBUFLEN]; - int pos; + int16_t buffer[2][MAXSOUNDBUFLEN]; + 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; - } + 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; + lpt_dac_t *lpt_dac = (lpt_dac_t *)p; - 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); + 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; + lpt_dac_t *lpt_dac = (lpt_dac_t *)p; - if (lpt_dac->is_stereo) - lpt_dac->channel = val & 0x01; + if (lpt_dac->is_stereo) + lpt_dac->channel = val & 0x01; } -static uint8_t dac_read_status(void *p) { - return 0; -} +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; + lpt_dac_t *lpt_dac = (lpt_dac_t *)p; + int c; - dac_update(lpt_dac); + 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; + 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)); + 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); + sound_add_handler(dac_get_buffer, lpt_dac); - return lpt_dac; + return lpt_dac; } static void *dac_stereo_init() { - lpt_dac_t *lpt_dac = dac_init(); + lpt_dac_t *lpt_dac = dac_init(); - lpt_dac->is_stereo = 1; + lpt_dac->is_stereo = 1; - return lpt_dac; + return lpt_dac; } static void dac_close(void *p) { - lpt_dac_t *lpt_dac = (lpt_dac_t *)p; + lpt_dac_t *lpt_dac = (lpt_dac_t *)p; - free(lpt_dac); + free(lpt_dac); } -lpt_device_t lpt_dac_device = - { - "LPT DAC / Covox Speech Thing", - 0, - dac_init, - dac_close, - NULL, - NULL, - NULL, - NULL, - NULL, - dac_write_data, - dac_write_ctrl, - dac_read_status, - }; -lpt_device_t lpt_dac_stereo_device = - { - "Stereo LPT DAC", - 0, - dac_stereo_init, - dac_close, - NULL, - NULL, - NULL, - NULL, - NULL, - dac_write_data, - dac_write_ctrl, - dac_read_status, - }; +lpt_device_t lpt_dac_device = { + "LPT DAC / Covox Speech Thing", + 0, + dac_init, + dac_close, + NULL, + NULL, + NULL, + NULL, + NULL, + dac_write_data, + dac_write_ctrl, + dac_read_status, +}; +lpt_device_t lpt_dac_stereo_device = { + "Stereo LPT DAC", 0, dac_stereo_init, dac_close, NULL, NULL, NULL, NULL, NULL, dac_write_data, dac_write_ctrl, + dac_read_status, +}; diff --git a/src/lpt/lpt_dss.c b/src/lpt/lpt_dss.c index 14197c6a..54191825 100644 --- a/src/lpt/lpt_dss.c +++ b/src/lpt/lpt_dss.c @@ -6,99 +6,84 @@ #include "sound.h" typedef struct dss_t { - uint8_t fifo[16]; - int read_idx, write_idx; + uint8_t fifo[16]; + int read_idx, write_idx; - uint8_t dac_val; + uint8_t dac_val; - pc_timer_t timer; + pc_timer_t timer; - int16_t buffer[MAXSOUNDBUFLEN]; - int pos; + int16_t buffer[MAXSOUNDBUFLEN]; + 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; + 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; + dss_t *dss = (dss_t *)p; - if ((dss->write_idx - dss->read_idx) < 16) { - dss->fifo[dss->write_idx & 15] = val; - dss->write_idx++; - } + 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 void dss_write_ctrl(uint8_t val, void *p) {} static uint8_t dss_read_status(void *p) { - dss_t *dss = (dss_t *)p; + dss_t *dss = (dss_t *)p; - if ((dss->write_idx - dss->read_idx) >= 16) - return 0x40; - return 0; + 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_t *dss = (dss_t *)p; + int c; - dss_update(dss); + dss_update(dss); - for (c = 0; c < len * 2; c += 2) { - int16_t val = (int16_t)dss_iir((float)dss->buffer[c >> 1]); + 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; - } + buffer[c] += val; + buffer[c + 1] += val; + } - dss->pos = 0; + dss->pos = 0; } static void dss_callback(void *p) { - dss_t *dss = (dss_t *)p; + dss_t *dss = (dss_t *)p; - dss_update(dss); + dss_update(dss); - if ((dss->write_idx - dss->read_idx) > 0) { - dss->dac_val = dss->fifo[dss->read_idx & 15]; - dss->read_idx++; - } + if ((dss->write_idx - dss->read_idx) > 0) { + dss->dac_val = dss->fifo[dss->read_idx & 15]; + dss->read_idx++; + } - timer_advance_u64(&dss->timer, (TIMER_USEC * (1000000.0 / 7000.0))); + timer_advance_u64(&dss->timer, (TIMER_USEC * (1000000.0 / 7000.0))); } static void *dss_init() { - dss_t *dss = malloc(sizeof(dss_t)); - memset(dss, 0, sizeof(dss_t)); + dss_t *dss = malloc(sizeof(dss_t)); + memset(dss, 0, sizeof(dss_t)); - sound_add_handler(dss_get_buffer, dss); - timer_add(&dss->timer, dss_callback, dss, 1); + sound_add_handler(dss_get_buffer, dss); + timer_add(&dss->timer, dss_callback, dss, 1); - return dss; + return dss; } static void dss_close(void *p) { - dss_t *dss = (dss_t *)p; + dss_t *dss = (dss_t *)p; - free(dss); + free(dss); } -lpt_device_t dss_device = - { - "Disney Sound Source", - NULL, - dss_init, - dss_close, - NULL, - NULL, - NULL, - NULL, - NULL, - dss_write_data, - dss_write_ctrl, - dss_read_status, - NULL - }; +lpt_device_t dss_device = {"Disney Sound Source", NULL, dss_init, dss_close, NULL, NULL, NULL, NULL, NULL, + dss_write_data, dss_write_ctrl, dss_read_status, NULL}; diff --git a/src/mcr.c b/src/mcr.c index 76d85dd4..558eed5b 100644 --- a/src/mcr.c +++ b/src/mcr.c @@ -8,29 +8,28 @@ int nextreg6; uint8_t mcr22; int mcrlock, mcrfirst; void resetmcr() { - mcrlock = 0; - mcrfirst = 1; + mcrlock = 0; + mcrfirst = 1; } void writemcr(uint16_t addr, uint8_t val) { - printf("Write MCR %04X %02X %04X:%04X\n", addr, val, CS, cpu_state.pc); - switch (addr) { - case 0x22: - if (val == 6 && mcr22 == 6) - nextreg6 = 1; - else - nextreg6 = 0; -// if ((val&1) && (mcr22&1)) shadowbios=1; -// if (!(val&1) && !(mcr22&1)) shadowbios=0; -// if (!mcrfirst) shadowbios=val&1; -// mcrfirst=0; -// dumpregs(); -// exit(-1); - break; - case 0x23: -// if (nextreg6) shadowbios=!val; - break; - } - mcr22 = val; + printf("Write MCR %04X %02X %04X:%04X\n", addr, val, CS, cpu_state.pc); + switch (addr) { + case 0x22: + if (val == 6 && mcr22 == 6) + nextreg6 = 1; + else + nextreg6 = 0; + // if ((val&1) && (mcr22&1)) shadowbios=1; + // if (!(val&1) && !(mcr22&1)) shadowbios=0; + // if (!mcrfirst) shadowbios=val&1; + // mcrfirst=0; + // dumpregs(); + // exit(-1); + break; + case 0x23: + // if (nextreg6) shadowbios=!val; + break; + } + mcr22 = val; } - diff --git a/src/memory/mem.c b/src/memory/mem.c index 35d1efef..286ee4c0 100644 --- a/src/memory/mem.c +++ b/src/memory/mem.c @@ -1,5 +1,5 @@ /*MESS ROM 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 @@ -58,1562 +58,1375 @@ int mmuflush = 0; int mmu_perm = 4; int mem_addr_is_ram(uint32_t addr) { - mem_mapping_t *mapping = read_mapping[addr >> 14]; + mem_mapping_t *mapping = read_mapping[addr >> 14]; - return (mapping == &ram_low_mapping) || (mapping == &ram_high_mapping) || (mapping == &ram_mid_mapping) || (mapping == &ram_remapped_mapping); + return (mapping == &ram_low_mapping) || (mapping == &ram_high_mapping) || (mapping == &ram_mid_mapping) || + (mapping == &ram_remapped_mapping); } void resetreadlookup() { - int c; -// /*if (output) */pclog("resetreadlookup\n"); - memset(readlookup2, 0xFF, 1024 * 1024 * sizeof(uintptr_t)); - for (c = 0; c < 256; c++) - readlookup[c] = 0xFFFFFFFF; - readlnext = 0; - memset(writelookup2, 0xFF, 1024 * 1024 * sizeof(uintptr_t)); - memset(page_lookup, 0, (1 << 20) * sizeof(page_t *)); - for (c = 0; c < 256; c++) - writelookup[c] = 0xFFFFFFFF; - writelnext = 0; - pccache = 0xFFFFFFFF; -// readlnum=writelnum=0; - + int c; + // /*if (output) */pclog("resetreadlookup\n"); + memset(readlookup2, 0xFF, 1024 * 1024 * sizeof(uintptr_t)); + for (c = 0; c < 256; c++) + readlookup[c] = 0xFFFFFFFF; + readlnext = 0; + memset(writelookup2, 0xFF, 1024 * 1024 * sizeof(uintptr_t)); + memset(page_lookup, 0, (1 << 20) * sizeof(page_t *)); + for (c = 0; c < 256; c++) + writelookup[c] = 0xFFFFFFFF; + writelnext = 0; + pccache = 0xFFFFFFFF; + // readlnum=writelnum=0; } void flushmmucache() { - int c; -// /*if (output) */pclog("flushmmucache\n"); -/* for (c=0;c<16;c++) - { - if ( readlookup2[0xE0+c]!=0xFFFFFFFF) pclog("RL2 %02X = %08X\n",0xE0+c, readlookup2[0xE0+c]); - if (writelookup2[0xE0+c]!=0xFFFFFFFF) pclog("WL2 %02X = %08X\n",0xE0+c,writelookup2[0xE0+c]); - }*/ - for (c = 0; c < 256; c++) { - if (readlookup[c] != 0xFFFFFFFF) { - readlookup2[readlookup[c]] = -1; - readlookup[c] = 0xFFFFFFFF; - } - if (writelookup[c] != 0xFFFFFFFF) { - page_lookup[writelookup[c]] = NULL; - writelookup2[writelookup[c]] = -1; - writelookup[c] = 0xFFFFFFFF; - } - } - mmuflush++; -// readlnum=writelnum=0; - pccache = (uint32_t)0xFFFFFFFF; - pccache2 = (uint8_t *)0xFFFFFFFF; - -// memset(readlookup,0xFF,sizeof(readlookup)); -// memset(readlookup2,0xFF,1024*1024*4); -// memset(writelookup,0xFF,sizeof(writelookup)); -// memset(writelookup2,0xFF,1024*1024*4); -/* if (!(cr0>>31)) return;*/ - -/* for (c = 0; c < 1024*1024; c++) - { - if (readlookup2[c] != 0xFFFFFFFF) + int c; + // /*if (output) */pclog("flushmmucache\n"); + /* for (c=0;c<16;c++) { - pclog("Readlookup inconsistency - %05X %08X\n", c, readlookup2[c]); - dumpregs(); - exit(-1); + if ( readlookup2[0xE0+c]!=0xFFFFFFFF) pclog("RL2 %02X = %08X\n",0xE0+c, readlookup2[0xE0+c]); + if (writelookup2[0xE0+c]!=0xFFFFFFFF) pclog("WL2 %02X = %08X\n",0xE0+c,writelookup2[0xE0+c]); + }*/ + for (c = 0; c < 256; c++) { + if (readlookup[c] != 0xFFFFFFFF) { + readlookup2[readlookup[c]] = -1; + readlookup[c] = 0xFFFFFFFF; } - if (writelookup2[c] != 0xFFFFFFFF) + if (writelookup[c] != 0xFFFFFFFF) { + page_lookup[writelookup[c]] = NULL; + writelookup2[writelookup[c]] = -1; + writelookup[c] = 0xFFFFFFFF; + } + } + mmuflush++; + // readlnum=writelnum=0; + pccache = (uint32_t)0xFFFFFFFF; + pccache2 = (uint8_t *)0xFFFFFFFF; + + // memset(readlookup,0xFF,sizeof(readlookup)); + // memset(readlookup2,0xFF,1024*1024*4); + // memset(writelookup,0xFF,sizeof(writelookup)); + // memset(writelookup2,0xFF,1024*1024*4); + /* if (!(cr0>>31)) return;*/ + + /* for (c = 0; c < 1024*1024; c++) { - pclog("Readlookup inconsistency - %05X %08X\n", c, readlookup2[c]); - dumpregs(); - exit(-1); - } - }*/ - codegen_flush(); + if (readlookup2[c] != 0xFFFFFFFF) + { + pclog("Readlookup inconsistency - %05X %08X\n", c, readlookup2[c]); + dumpregs(); + exit(-1); + } + if (writelookup2[c] != 0xFFFFFFFF) + { + pclog("Readlookup inconsistency - %05X %08X\n", c, readlookup2[c]); + dumpregs(); + exit(-1); + } + }*/ + codegen_flush(); } void flushmmucache_nopc() { - int c; - for (c = 0; c < 256; c++) { - if (readlookup[c] != 0xFFFFFFFF) { - readlookup2[readlookup[c]] = -1; - readlookup[c] = 0xFFFFFFFF; - } - if (writelookup[c] != 0xFFFFFFFF) { - page_lookup[writelookup[c]] = NULL; - writelookup2[writelookup[c]] = -1; - writelookup[c] = 0xFFFFFFFF; - } - } + int c; + for (c = 0; c < 256; c++) { + if (readlookup[c] != 0xFFFFFFFF) { + readlookup2[readlookup[c]] = -1; + readlookup[c] = 0xFFFFFFFF; + } + if (writelookup[c] != 0xFFFFFFFF) { + page_lookup[writelookup[c]] = NULL; + writelookup2[writelookup[c]] = -1; + writelookup[c] = 0xFFFFFFFF; + } + } } void flushmmucache_cr3() { - int c; -// /*if (output) */pclog("flushmmucache_cr3\n"); - for (c = 0; c < 256; c++) { - if (readlookup[c] != 0xFFFFFFFF)// && !readlookupp[c]) - { - readlookup2[readlookup[c]] = -1; - readlookup[c] = 0xFFFFFFFF; - } - if (writelookup[c] != 0xFFFFFFFF)// && !writelookupp[c]) - { - page_lookup[writelookup[c]] = NULL; - writelookup2[writelookup[c]] = -1; - writelookup[c] = 0xFFFFFFFF; - } - } -/* for (c = 0; c < 1024*1024; c++) - { - if (readlookup2[c] != 0xFFFFFFFF) + int c; + // /*if (output) */pclog("flushmmucache_cr3\n"); + for (c = 0; c < 256; c++) { + if (readlookup[c] != 0xFFFFFFFF) // && !readlookupp[c]) { - pclog("Readlookup inconsistency - %05X %08X\n", c, readlookup2[c]); - dumpregs(); - exit(-1); + readlookup2[readlookup[c]] = -1; + readlookup[c] = 0xFFFFFFFF; } - if (writelookup2[c] != 0xFFFFFFFF) + if (writelookup[c] != 0xFFFFFFFF) // && !writelookupp[c]) { - pclog("Readlookup inconsistency - %05X %08X\n", c, readlookup2[c]); - dumpregs(); - exit(-1); + page_lookup[writelookup[c]] = NULL; + writelookup2[writelookup[c]] = -1; + writelookup[c] = 0xFFFFFFFF; } - }*/ + } + /* for (c = 0; c < 1024*1024; c++) + { + if (readlookup2[c] != 0xFFFFFFFF) + { + pclog("Readlookup inconsistency - %05X %08X\n", c, readlookup2[c]); + dumpregs(); + exit(-1); + } + if (writelookup2[c] != 0xFFFFFFFF) + { + pclog("Readlookup inconsistency - %05X %08X\n", c, readlookup2[c]); + dumpregs(); + exit(-1); + } + }*/ } void mem_flush_write_page(uint32_t addr, uint32_t virt) { - int c; - page_t *page_target = &pages[addr >> 12]; -// pclog("mem_flush_write_page %08x %08x\n", virt, addr); + int c; + page_t *page_target = &pages[addr >> 12]; + // pclog("mem_flush_write_page %08x %08x\n", virt, addr); - for (c = 0; c < 256; c++) { - if (writelookup[c] != 0xffffffff) { - uintptr_t target = (uintptr_t)&ram[(uintptr_t)(addr & ~0xfff) - (virt & ~0xfff)]; + for (c = 0; c < 256; c++) { + if (writelookup[c] != 0xffffffff) { + uintptr_t target = (uintptr_t)&ram[(uintptr_t)(addr & ~0xfff) - (virt & ~0xfff)]; -// if ((virt & ~0xfff) == 0xc022e000) -// pclog(" Checking %02x %p %p\n", (void *)writelookup2[writelookup[c]], (void *)target); - if (writelookup2[writelookup[c]] == target || page_lookup[writelookup[c]] == page_target) { -// pclog(" throw out %02x %p %p\n", writelookup[c], (void *)page_lookup[writelookup[c]], (void *)writelookup2[writelookup[c]]); - writelookup2[writelookup[c]] = -1; - page_lookup[writelookup[c]] = NULL; - writelookup[c] = 0xffffffff; - } - } - } + // if ((virt & ~0xfff) == 0xc022e000) + // pclog(" Checking %02x %p %p\n", (void *)writelookup2[writelookup[c]], + // (void *)target); + if (writelookup2[writelookup[c]] == target || page_lookup[writelookup[c]] == page_target) { + // pclog(" throw out %02x %p %p\n", writelookup[c], (void + // *)page_lookup[writelookup[c]], (void + // *)writelookup2[writelookup[c]]); + 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 mmutranslate_read(addr) mmutranslatereal(addr, 0) +#define mmutranslate_write(addr) mmutranslatereal(addr, 1) -static inline uint32_t mmu_readl(uint32_t addr) { - return *(uint32_t *)&_mem_exec[addr >> 14][addr & 0x3fff]; -} +static inline uint32_t mmu_readl(uint32_t addr) { return *(uint32_t *)&_mem_exec[addr >> 14][addr & 0x3fff]; } -static inline void mmu_writel(uint32_t addr, uint32_t val) { - *(uint32_t *)&_mem_exec[addr >> 14][addr & 0x3fff] = val; -} +static inline void mmu_writel(uint32_t addr, uint32_t val) { *(uint32_t *)&_mem_exec[addr >> 14][addr & 0x3fff] = val; } uint32_t mmutranslatereal(uint32_t addr, int rw) { - uint32_t addr2; - uint32_t temp, temp2, temp3; + uint32_t addr2; + uint32_t temp, temp2, temp3; - if (cpu_state.abrt) { -// pclog("Translate recursive abort\n"); - return -1; - } -/* if ((addr&~0xFFFFF)==0x77f00000) pclog("Do translate %08X %i %08X %08X\n",addr,rw,EAX,pc); - if (addr==0x77f61000) output = 3; - if (addr==0x77f62000) { dumpregs(); exit(-1); } - if (addr==0x77f9a000) { dumpregs(); exit(-1); }*/ - addr2 = ((cr3 & ~0xfff) + ((addr >> 20) & 0xffc)); - temp = temp2 = mmu_readl(addr2); -// if (output == 3) pclog("Do translate %08X %i %08X\n", addr, rw, temp); - if (!(temp & 1))// || (CPL==3 && !(temp&4) && !cpl_override) || (rw && !(temp&2) && (CPL==3 || cr0&WP_FLAG))) - { -// if (!nopageerrors) pclog("Section not present! %08X %08X %02X %04X:%08X %i %i\n",addr,temp,opcode,CS,pc,CPL,rw); + if (cpu_state.abrt) { + // pclog("Translate recursive abort\n"); + return -1; + } + /* if ((addr&~0xFFFFF)==0x77f00000) pclog("Do translate %08X %i %08X %08X\n",addr,rw,EAX,pc); + if (addr==0x77f61000) output = 3; + if (addr==0x77f62000) { dumpregs(); exit(-1); } + if (addr==0x77f9a000) { dumpregs(); exit(-1); }*/ + addr2 = ((cr3 & ~0xfff) + ((addr >> 20) & 0xffc)); + temp = temp2 = mmu_readl(addr2); + // if (output == 3) pclog("Do translate %08X %i %08X\n", addr, rw, temp); + if (!(temp & 1)) // || (CPL==3 && !(temp&4) && !cpl_override) || (rw && !(temp&2) && (CPL==3 || cr0&WP_FLAG))) + { + // if (!nopageerrors) pclog("Section not present! %08X %08X %02X %04X:%08X %i + // %i\n",addr,temp,opcode,CS,pc,CPL,rw); - cr2 = addr; - temp &= 1; - if (CPL == 3) - temp |= 4; - if (rw) - temp |= 2; - cpu_state.abrt = ABRT_PF; - abrt_error = temp; -/* if (addr == 0x70046D) - { - dumpregs(); - exit(-1); - }*/ - return -1; - } + cr2 = addr; + temp &= 1; + if (CPL == 3) + temp |= 4; + if (rw) + temp |= 2; + cpu_state.abrt = ABRT_PF; + abrt_error = temp; + /* if (addr == 0x70046D) + { + dumpregs(); + exit(-1); + }*/ + 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))) { -// if (!nopageerrors) pclog("Page not present! %08X %08X %02X %02X %i %08X %04X:%08X %04X:%08X %i %i %i\n",addr,temp,opcode,opcode2,frame,rmdat32, CS,pc,SS,ESP,ins,CPL,rw); + 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))) { + // if (!nopageerrors) pclog("Page not present! %08X %08X %02X %02X %i %08X + // %04X:%08X %04X:%08X %i %i %i\n",addr,temp,opcode,opcode2,frame,rmdat32, + // CS,pc,SS,ESP,ins,CPL,rw); - cr2 = addr; - temp &= 1; - if (CPL == 3) - temp |= 4; - if (rw) - temp |= 2; - cpu_state.abrt = ABRT_PF; - abrt_error = temp; + cr2 = addr; + temp &= 1; + if (CPL == 3) + temp |= 4; + if (rw) + temp |= 2; + cpu_state.abrt = ABRT_PF; + abrt_error = temp; - return -1; - } + return -1; + } - mmu_perm = temp & 4; - ((uint32_t *)ram)[addr2 >> 2] |= 0x20; + mmu_perm = temp & 4; + ((uint32_t *)ram)[addr2 >> 2] |= 0x20; - return (temp & ~0x3fffff) + (addr & 0x3fffff); - } + return (temp & ~0x3fffff) + (addr & 0x3fffff); + } - temp = mmu_readl((temp & ~0xfff) + ((addr >> 10) & 0xffc)); - temp3 = temp & temp2; -// if (output == 3) pclog("Do translate %08X %08X\n", temp, temp3); - if (!(temp & 1) || (CPL == 3 && !(temp3 & 4) && !cpl_override) || (rw && !(temp3 & 2) && ((CPL == 3 && !cpl_override) || cr0 & WP_FLAG))) { -// if (!nopageerrors) pclog("Page not present! %08X %08X %02X %02X %i %08X %04X:%08X %04X:%08X %i %i %i\n",addr,temp,opcode,opcode2,frame,rmdat32, CS,pc,SS,ESP,ins,CPL,rw); -// dumpregs(); -// exit(-1); -// if (addr == 0x815F6E90) output = 3; -/* if (addr == 0x10ADE020) output = 3;*/ -/* if (addr == 0x10150010 && !nopageerrors) - { - dumpregs(); - exit(-1); - }*/ + temp = mmu_readl((temp & ~0xfff) + ((addr >> 10) & 0xffc)); + temp3 = temp & temp2; + // if (output == 3) pclog("Do translate %08X %08X\n", temp, temp3); + if (!(temp & 1) || (CPL == 3 && !(temp3 & 4) && !cpl_override) || + (rw && !(temp3 & 2) && ((CPL == 3 && !cpl_override) || cr0 & WP_FLAG))) { + // if (!nopageerrors) pclog("Page not present! %08X %08X %02X %02X %i %08X %04X:%08X + // %04X:%08X %i %i %i\n",addr,temp,opcode,opcode2,frame,rmdat32, CS,pc,SS,ESP,ins,CPL,rw); + // dumpregs(); + // exit(-1); + // if (addr == 0x815F6E90) output = 3; + /* if (addr == 0x10ADE020) output = 3;*/ + /* if (addr == 0x10150010 && !nopageerrors) + { + dumpregs(); + exit(-1); + }*/ - cr2 = addr; - temp &= 1; - if (CPL == 3) - temp |= 4; - if (rw) - temp |= 2; - cpu_state.abrt = ABRT_PF; - abrt_error = temp; -// pclog("%04X\n",abrt); - return -1; - } - mmu_perm = temp & 4; - mmu_writel(addr2, temp2 | 0x20); - mmu_writel((temp2 & ~0xfff) + ((addr >> 10) & 0xffc), temp | (rw ? 0x60 : 0x20)); -// /*if (output) */pclog("Translate %08X %08X %08X %08X:%08X %08X\n",addr,(temp&~0xFFF)+(addr&0xFFF),temp,cs,pc,EDI); + cr2 = addr; + temp &= 1; + if (CPL == 3) + temp |= 4; + if (rw) + temp |= 2; + cpu_state.abrt = ABRT_PF; + abrt_error = temp; + // pclog("%04X\n",abrt); + return -1; + } + mmu_perm = temp & 4; + mmu_writel(addr2, temp2 | 0x20); + mmu_writel((temp2 & ~0xfff) + ((addr >> 10) & 0xffc), temp | (rw ? 0x60 : 0x20)); + // /*if (output) */pclog("Translate %08X %08X %08X %08X:%08X + // %08X\n",addr,(temp&~0xFFF)+(addr&0xFFF),temp,cs,pc,EDI); - return (temp & ~0xFFF) + (addr & 0xFFF); + return (temp & ~0xFFF) + (addr & 0xFFF); } uint32_t mmutranslate_noabrt(uint32_t addr, int rw) { - uint32_t addr2; - uint32_t temp, temp2, temp3; + uint32_t addr2; + uint32_t temp, temp2, temp3; - if (cpu_state.abrt) - return -1; + if (cpu_state.abrt) + return -1; - addr2 = ((cr3 & ~0xfff) + ((addr >> 20) & 0xffc)); - temp = temp2 = mmu_readl(addr2); + addr2 = ((cr3 & ~0xfff) + ((addr >> 20) & 0xffc)); + temp = temp2 = mmu_readl(addr2); - if (!(temp & 1)) - return -1; + 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; + 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); - } + return (temp & ~0x3fffff) + (addr & 0x3fffff); + } - temp = mmu_readl((temp & ~0xfff) + ((addr >> 10) & 0xffc)); - temp3 = temp & temp2; + temp = mmu_readl((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; + if (!(temp & 1) || (CPL == 3 && !(temp3 & 4) && !cpl_override) || (rw && !(temp3 & 2) && (CPL == 3 || cr0 & WP_FLAG))) + return -1; - return (temp & ~0xFFF) + (addr & 0xFFF); + return (temp & ~0xFFF) + (addr & 0xFFF); } void mmu_invalidate(uint32_t addr) { -// readlookup2[addr >> 12] = writelookup2[addr >> 12] = 0xFFFFFFFF; - flushmmucache_cr3(); + // readlookup2[addr >> 12] = writelookup2[addr >> 12] = 0xFFFFFFFF; + flushmmucache_cr3(); } void addreadlookup(uint32_t virt, uint32_t phys) { -// return; -// printf("Addreadlookup %08X %08X %08X %08X %08X %08X %02X %08X\n",virt,phys,cs,ds,es,ss,opcode,pc); - if (virt == 0xffffffff) - return; + // return; + // printf("Addreadlookup %08X %08X %08X %08X %08X %08X %02X %08X\n",virt,phys,cs,ds,es,ss,opcode,pc); + if (virt == 0xffffffff) + return; - if (readlookup2[virt >> 12] != -1) { -/* if (readlookup2[virt>>12] != phys&~0xfff) - { - pclog("addreadlookup mismatch - %05X000 %05X000\n", readlookup[readlnext], virt >> 12); - dumpregs(); - exit(-1); - }*/ - return; - } + if (readlookup2[virt >> 12] != -1) { + /* if (readlookup2[virt>>12] != phys&~0xfff) + { + pclog("addreadlookup mismatch - %05X000 %05X000\n", readlookup[readlnext], virt >> 12); + dumpregs(); + exit(-1); + }*/ + return; + } - if (readlookup[readlnext] != 0xFFFFFFFF) { - readlookup2[readlookup[readlnext]] = -1; -// readlnum--; - } - 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); + if (readlookup[readlnext] != 0xFFFFFFFF) { + readlookup2[readlookup[readlnext]] = -1; + // readlnum--; + } + 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; + cycles -= 9; } void addwritelookup(uint32_t virt, uint32_t phys) { -// return; -// printf("Addwritelookup %08X %08X\n",virt,phys); - if (virt == 0xffffffff) - return; + // return; + // printf("Addwritelookup %08X %08X\n",virt,phys); + if (virt == 0xffffffff) + return; - if (page_lookup[virt >> 12]) { -/* if (writelookup2[virt>>12] != phys&~0xfff) - { - pclog("addwritelookup mismatch - %05X000 %05X000\n", readlookup[readlnext], virt >> 12); - dumpregs(); - exit(-1); - }*/ - return; - } + if (page_lookup[virt >> 12]) { + /* if (writelookup2[virt>>12] != phys&~0xfff) + { + pclog("addwritelookup mismatch - %05X000 %05X000\n", readlookup[readlnext], virt >> 12); + dumpregs(); + exit(-1); + }*/ + return; + } - if (writelookup[writelnext] != -1) { - page_lookup[writelookup[writelnext]] = NULL; - writelookup2[writelookup[writelnext]] = -1; -// writelnum--; - } -// if (page_lookup[virt >> 12] && (writelookup2[virt>>12] != 0xffffffff)) -// fatal("Bad write mapping\n"); + if (writelookup[writelnext] != -1) { + page_lookup[writelookup[writelnext]] = NULL; + writelookup2[writelookup[writelnext]] = -1; + // writelnum--; + } + // if (page_lookup[virt >> 12] && (writelookup2[virt>>12] != 0xffffffff)) + // fatal("Bad write mapping\n"); - if (pages[phys >> 12].block || (phys & ~0xfff) == recomp_page) - page_lookup[virt >> 12] = &pages[phys >> 12];//(uintptr_t)&ram[(uintptr_t)(phys & ~0xFFF) - (uintptr_t)(virt & ~0xfff)]; - else - writelookup2[virt >> 12] = (uintptr_t)&ram[(uintptr_t)(phys & ~0xFFF) - (uintptr_t)(virt & ~0xfff)]; -// pclog("addwritelookup %08x %08x %p %p %016llx %p\n", virt, phys, (void *)page_lookup[virt >> 12], (void *)writelookup2[virt >> 12], pages[phys >> 12].dirty_mask, (void *)&pages[phys >> 12]); - writelookupp[writelnext] = mmu_perm; - writelookup[writelnext++] = virt >> 12; - writelnext &= (cachesize - 1); + if (pages[phys >> 12].block || (phys & ~0xfff) == recomp_page) + page_lookup[virt >> 12] = + &pages[phys >> 12]; //(uintptr_t)&ram[(uintptr_t)(phys & ~0xFFF) - (uintptr_t)(virt & ~0xfff)]; + else + writelookup2[virt >> 12] = (uintptr_t)&ram[(uintptr_t)(phys & ~0xFFF) - (uintptr_t)(virt & ~0xfff)]; + // pclog("addwritelookup %08x %08x %p %p %016llx %p\n", virt, phys, (void *)page_lookup[virt >> 12], (void + // *)writelookup2[virt >> 12], pages[phys >> 12].dirty_mask, (void *)&pages[phys >> 12]); + writelookupp[writelnext] = mmu_perm; + writelookup[writelnext++] = virt >> 12; + writelnext &= (cachesize - 1); - cycles -= 9; + cycles -= 9; } uint8_t *getpccache(uint32_t a) { - uint32_t a2 = a; + uint32_t a2 = a; - if (cr0 >> 31) { - a = mmutranslate_read(a); + if (cr0 >> 31) { + a = mmutranslate_read(a); - if (a == 0xFFFFFFFF) - return ram; - } - a &= rammask; + if (a == 0xFFFFFFFF) + return ram; + } + a &= rammask; - if (_mem_exec[a >> 14]) { - if (read_mapping[a >> 14]->flags & MEM_MAPPING_ROM) - cpu_prefetch_cycles = cpu_rom_prefetch_cycles; - else - cpu_prefetch_cycles = cpu_mem_prefetch_cycles; + if (_mem_exec[a >> 14]) { + if (read_mapping[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)]; - } + return &_mem_exec[a >> 14][(uintptr_t)(a & 0x3000) - (uintptr_t)(a2 & ~0xFFF)]; + } - pclog("Bad getpccache %08X\n", a); - return &ff_array[0 - (uintptr_t)(a2 & ~0xFFF)]; + pclog("Bad getpccache %08X\n", a); + return &ff_array[0 - (uintptr_t)(a2 & ~0xFFF)]; } uint8_t readmembl(uint32_t addr) { - mem_mapping_t *map; + mem_mapping_t *map; - mem_logical_addr = addr; - if (cr0 >> 31) { - addr = mmutranslate_read(addr); - if (addr == 0xFFFFFFFF) - return 0xFF; - } - addr &= rammask; + mem_logical_addr = addr; + if (cr0 >> 31) { + addr = mmutranslate_read(addr); + if (addr == 0xFFFFFFFF) + return 0xFF; + } + addr &= rammask; - map = read_mapping[addr >> 14]; - if (map && map->read_b) - return map->read_b(addr, map->p); -// pclog("Bad readmembl %08X %04X:%08X\n", addr, CS, pc); - return 0xFF; + map = read_mapping[addr >> 14]; + if (map && map->read_b) + return map->read_b(addr, map->p); + // pclog("Bad readmembl %08X %04X:%08X\n", addr, CS, pc); + return 0xFF; } void writemembl(uint32_t addr, uint8_t val) { - mem_mapping_t *map; + mem_mapping_t *map; - mem_logical_addr = addr; + mem_logical_addr = addr; - if (page_lookup[addr >> 12]) { - page_lookup[addr >> 12]->write_b(addr, val, page_lookup[addr >> 12]); - return; - } - if (cr0 >> 31) { - addr = mmutranslate_write(addr); - if (addr == 0xFFFFFFFF) - return; - } - addr &= rammask; + if (page_lookup[addr >> 12]) { + page_lookup[addr >> 12]->write_b(addr, val, page_lookup[addr >> 12]); + return; + } + if (cr0 >> 31) { + addr = mmutranslate_write(addr); + if (addr == 0xFFFFFFFF) + return; + } + addr &= rammask; - map = write_mapping[addr >> 14]; - if (map && map->write_b) - return map->write_b(addr, val, map->p); -// else pclog("Bad writemembl %08X %02X %04X:%08X\n", addr, val, CS, pc); + map = write_mapping[addr >> 14]; + if (map && map->write_b) + return map->write_b(addr, val, map->p); + // else pclog("Bad writemembl %08X %02X %04X:%08X\n", addr, val, CS, pc); } uint16_t readmemwl(uint32_t addr) { - mem_mapping_t *map; + mem_mapping_t *map; - mem_logical_addr = addr; + mem_logical_addr = addr; - if (addr & 1) { - if (!cpu_cyrix_alignment || (addr & 7) == 7) - cycles -= timing_misaligned; - if ((addr & 0xFFF) > 0xFFE) { - if (cr0 >> 31) { - if (mmutranslate_read(addr) == 0xffffffff) - return 0xffff; - if (mmutranslate_read(addr + 1) == 0xffffffff) - return 0xffff; - } - return readmembl(addr) | (readmembl(addr + 1) << 8); - } else if (readlookup2[addr >> 12] != -1) - return *(uint16_t *)(readlookup2[addr >> 12] + addr); - } - if (cr0 >> 31) { - addr = mmutranslate_read(addr); - if (addr == 0xFFFFFFFF) - return 0xFFFF; - } + if (addr & 1) { + if (!cpu_cyrix_alignment || (addr & 7) == 7) + cycles -= timing_misaligned; + if ((addr & 0xFFF) > 0xFFE) { + if (cr0 >> 31) { + if (mmutranslate_read(addr) == 0xffffffff) + return 0xffff; + if (mmutranslate_read(addr + 1) == 0xffffffff) + return 0xffff; + } + return readmembl(addr) | (readmembl(addr + 1) << 8); + } else if (readlookup2[addr >> 12] != -1) + return *(uint16_t *)(readlookup2[addr >> 12] + addr); + } + if (cr0 >> 31) { + addr = mmutranslate_read(addr); + if (addr == 0xFFFFFFFF) + return 0xFFFF; + } - addr &= rammask; + addr &= rammask; - map = read_mapping[addr >> 14]; - if (map) { - if (map->read_w) - return map->read_w(addr, map->p); + map = read_mapping[addr >> 14]; + if (map) { + if (map->read_w) + return map->read_w(addr, map->p); - if (map->read_b) - return map->read_b(addr, map->p) | (map->read_b(addr + 1, map->p) << 8); - } + if (map->read_b) + return map->read_b(addr, map->p) | (map->read_b(addr + 1, map->p) << 8); + } -// pclog("Bad readmemwl %08X\n", addr); - return 0xffff; + // pclog("Bad readmemwl %08X\n", addr); + return 0xffff; } void writememwl(uint32_t addr, uint16_t val) { - mem_mapping_t *map; + mem_mapping_t *map; - mem_logical_addr = addr; + mem_logical_addr = addr; - if (addr & 1) { - if (!cpu_cyrix_alignment || (addr & 7) == 7) - cycles -= timing_misaligned; - if ((addr & 0xFFF) > 0xFFE) { - if (cr0 >> 31) { - if (mmutranslate_write(addr) == 0xffffffff) - return; - if (mmutranslate_write(addr + 1) == 0xffffffff) - return; - } - writemembl(addr, val); - writemembl(addr + 1, val >> 8); - return; - } else if (writelookup2[addr >> 12] != -1) { - *(uint16_t *)(writelookup2[addr >> 12] + addr) = val; - return; - } - } + if (addr & 1) { + if (!cpu_cyrix_alignment || (addr & 7) == 7) + cycles -= timing_misaligned; + if ((addr & 0xFFF) > 0xFFE) { + if (cr0 >> 31) { + if (mmutranslate_write(addr) == 0xffffffff) + return; + if (mmutranslate_write(addr + 1) == 0xffffffff) + return; + } + writemembl(addr, val); + writemembl(addr + 1, val >> 8); + return; + } else if (writelookup2[addr >> 12] != -1) { + *(uint16_t *)(writelookup2[addr >> 12] + addr) = val; + return; + } + } - if (page_lookup[addr >> 12]) { - page_lookup[addr >> 12]->write_w(addr, val, page_lookup[addr >> 12]); - return; - } - if (cr0 >> 31) { - addr = mmutranslate_write(addr); - if (addr == 0xFFFFFFFF) - return; - } + if (page_lookup[addr >> 12]) { + page_lookup[addr >> 12]->write_w(addr, val, page_lookup[addr >> 12]); + return; + } + if (cr0 >> 31) { + addr = mmutranslate_write(addr); + if (addr == 0xFFFFFFFF) + return; + } - addr &= rammask; + addr &= rammask; - map = write_mapping[addr >> 14]; - if (map) { - if (map->write_w) - map->write_w(addr, val, map->p); - else if (map->write_b) { - map->write_b(addr, val, map->p); - map->write_b(addr + 1, val >> 8, map->p); - } - } + map = write_mapping[addr >> 14]; + if (map) { + if (map->write_w) + map->write_w(addr, val, map->p); + else if (map->write_b) { + map->write_b(addr, val, map->p); + map->write_b(addr + 1, val >> 8, map->p); + } + } -// pclog("Bad writememwl %08X %04X\n", addr, val); + // pclog("Bad writememwl %08X %04X\n", addr, val); } uint32_t readmemll(uint32_t addr) { - mem_mapping_t *map; + mem_mapping_t *map; - mem_logical_addr = addr; + mem_logical_addr = addr; - if (addr & 3) { - if (!cpu_cyrix_alignment || (addr & 7) > 4) - cycles -= timing_misaligned; - if ((addr & 0xFFF) > 0xFFC) { - if (cr0 >> 31) { - if (mmutranslate_read(addr) == 0xffffffff) - return 0xffffffff; - if (mmutranslate_read(addr + 3) == 0xffffffff) - return 0xffffffff; - } - return readmemwl(addr) | (readmemwl(addr + 2) << 16); - } else if (readlookup2[addr >> 12] != -1) - return *(uint32_t *)(readlookup2[addr >> 12] + addr); - } + if (addr & 3) { + if (!cpu_cyrix_alignment || (addr & 7) > 4) + cycles -= timing_misaligned; + if ((addr & 0xFFF) > 0xFFC) { + if (cr0 >> 31) { + if (mmutranslate_read(addr) == 0xffffffff) + return 0xffffffff; + if (mmutranslate_read(addr + 3) == 0xffffffff) + return 0xffffffff; + } + return readmemwl(addr) | (readmemwl(addr + 2) << 16); + } else if (readlookup2[addr >> 12] != -1) + return *(uint32_t *)(readlookup2[addr >> 12] + addr); + } - if (cr0 >> 31) { - addr = mmutranslate_read(addr); - if (addr == 0xFFFFFFFF) - return 0xFFFFFFFF; - } + if (cr0 >> 31) { + addr = mmutranslate_read(addr); + if (addr == 0xFFFFFFFF) + return 0xFFFFFFFF; + } - addr &= rammask; + addr &= rammask; - map = read_mapping[addr >> 14]; - if (map) { - if (map->read_l) - return map->read_l(addr, map->p); + map = read_mapping[addr >> 14]; + if (map) { + if (map->read_l) + return map->read_l(addr, map->p); - if (map->read_w) - return map->read_w(addr, map->p) | (map->read_w(addr + 2, map->p) << 16); + if (map->read_w) + return map->read_w(addr, map->p) | (map->read_w(addr + 2, map->p) << 16); - if (map->read_b) - return map->read_b(addr, map->p) | (map->read_b(addr + 1, map->p) << 8) | - (map->read_b(addr + 2, map->p) << 16) | (map->read_b(addr + 3, map->p) << 24); - } + if (map->read_b) + return map->read_b(addr, map->p) | (map->read_b(addr + 1, map->p) << 8) | + (map->read_b(addr + 2, map->p) << 16) | (map->read_b(addr + 3, map->p) << 24); + } -// pclog("Bad readmemll %08X\n", addr); - return 0xffffffff; + // pclog("Bad readmemll %08X\n", addr); + return 0xffffffff; } void writememll(uint32_t addr, uint32_t val) { - mem_mapping_t *map; + mem_mapping_t *map; - mem_logical_addr = addr; + mem_logical_addr = addr; - if (addr & 3) { - if (!cpu_cyrix_alignment || (addr & 7) > 4) - cycles -= timing_misaligned; - if ((addr & 0xFFF) > 0xFFC) { - if (cr0 >> 31) { - if (mmutranslate_write(addr) == 0xffffffff) - return; - if (mmutranslate_write(addr + 3) == 0xffffffff) - return; - } - writememwl(addr, val); - writememwl(addr + 2, val >> 16); - return; - } else if (writelookup2[addr >> 12] != -1) { - *(uint32_t *)(writelookup2[addr >> 12] + addr) = val; - return; - } - } - if (page_lookup[addr >> 12]) { - page_lookup[addr >> 12]->write_l(addr, val, page_lookup[addr >> 12]); - return; - } - if (cr0 >> 31) { - addr = mmutranslate_write(addr); - if (addr == 0xFFFFFFFF) - return; - } + if (addr & 3) { + if (!cpu_cyrix_alignment || (addr & 7) > 4) + cycles -= timing_misaligned; + if ((addr & 0xFFF) > 0xFFC) { + if (cr0 >> 31) { + if (mmutranslate_write(addr) == 0xffffffff) + return; + if (mmutranslate_write(addr + 3) == 0xffffffff) + return; + } + writememwl(addr, val); + writememwl(addr + 2, val >> 16); + return; + } else if (writelookup2[addr >> 12] != -1) { + *(uint32_t *)(writelookup2[addr >> 12] + addr) = val; + return; + } + } + if (page_lookup[addr >> 12]) { + page_lookup[addr >> 12]->write_l(addr, val, page_lookup[addr >> 12]); + return; + } + if (cr0 >> 31) { + addr = mmutranslate_write(addr); + if (addr == 0xFFFFFFFF) + return; + } - addr &= rammask; + addr &= rammask; - map = write_mapping[addr >> 14]; - if (map) { - if (map->write_l) - map->write_l(addr, val, map->p); - else if (map->write_w) { - map->write_w(addr, val, map->p); - map->write_w(addr + 2, val >> 16, map->p); - } else if (map->write_b) { - map->write_b(addr, val, map->p); - map->write_b(addr + 1, val >> 8, map->p); - map->write_b(addr + 2, val >> 16, map->p); - map->write_b(addr + 3, val >> 24, map->p); - } - } -// pclog("Bad writememll %08X %08X\n", addr, val); + map = write_mapping[addr >> 14]; + if (map) { + if (map->write_l) + map->write_l(addr, val, map->p); + else if (map->write_w) { + map->write_w(addr, val, map->p); + map->write_w(addr + 2, val >> 16, map->p); + } else if (map->write_b) { + map->write_b(addr, val, map->p); + map->write_b(addr + 1, val >> 8, map->p); + map->write_b(addr + 2, val >> 16, map->p); + map->write_b(addr + 3, val >> 24, map->p); + } + } + // pclog("Bad writememll %08X %08X\n", addr, val); } uint64_t readmemql(uint32_t addr) { - mem_mapping_t *map; + mem_mapping_t *map; - mem_logical_addr = addr; + mem_logical_addr = addr; - if (addr & 7) { - cycles -= timing_misaligned; - if ((addr & 0xFFF) > 0xFF8) { - if (cr0 >> 31) { - if (mmutranslate_read(addr) == 0xffffffff) - return 0xffffffff; - if (mmutranslate_read(addr + 7) == 0xffffffff) - return 0xffffffff; - } - return readmemll(addr) | ((uint64_t)readmemll(addr + 4) << 32); - } else if (readlookup2[addr >> 12] != -1) - return *(uint64_t *)(readlookup2[addr >> 12] + addr); - } + if (addr & 7) { + cycles -= timing_misaligned; + if ((addr & 0xFFF) > 0xFF8) { + if (cr0 >> 31) { + if (mmutranslate_read(addr) == 0xffffffff) + return 0xffffffff; + if (mmutranslate_read(addr + 7) == 0xffffffff) + return 0xffffffff; + } + return readmemll(addr) | ((uint64_t)readmemll(addr + 4) << 32); + } else if (readlookup2[addr >> 12] != -1) + return *(uint64_t *)(readlookup2[addr >> 12] + addr); + } - if (cr0 >> 31) { - addr = mmutranslate_read(addr); - if (addr == 0xFFFFFFFF) - return 0xFFFFFFFF; - } + if (cr0 >> 31) { + addr = mmutranslate_read(addr); + if (addr == 0xFFFFFFFF) + return 0xFFFFFFFF; + } - addr &= rammask; + addr &= rammask; - map = read_mapping[addr >> 14]; - if (map && map->read_l) - return map->read_l(addr, map->p) | ((uint64_t)map->read_l(addr + 4, map->p) << 32); + map = read_mapping[addr >> 14]; + if (map && map->read_l) + return map->read_l(addr, map->p) | ((uint64_t)map->read_l(addr + 4, map->p) << 32); - return readmemll(addr) | ((uint64_t)readmemll(addr + 4) << 32); + return readmemll(addr) | ((uint64_t)readmemll(addr + 4) << 32); } void writememql(uint32_t addr, uint64_t val) { - mem_mapping_t *map; + mem_mapping_t *map; - mem_logical_addr = addr; + mem_logical_addr = addr; - if (addr & 7) { - cycles -= timing_misaligned; - if ((addr & 0xFFF) > 0xFF8) { - if (cr0 >> 31) { - if (mmutranslate_write(addr) == 0xffffffff) - return; - if (mmutranslate_write(addr + 7) == 0xffffffff) - return; - } - writememll(addr, val); - writememll(addr + 4, val >> 32); - return; - } else if (writelookup2[addr >> 12] != -1) { - *(uint64_t *)(writelookup2[addr >> 12] + addr) = val; - return; - } - } - if (page_lookup[addr >> 12]) { - page_lookup[addr >> 12]->write_l(addr, val, page_lookup[addr >> 12]); - page_lookup[addr >> 12]->write_l(addr + 4, val >> 32, page_lookup[addr >> 12]); - return; - } - if (cr0 >> 31) { - addr = mmutranslate_write(addr); - if (addr == 0xFFFFFFFF) - return; - } + if (addr & 7) { + cycles -= timing_misaligned; + if ((addr & 0xFFF) > 0xFF8) { + if (cr0 >> 31) { + if (mmutranslate_write(addr) == 0xffffffff) + return; + if (mmutranslate_write(addr + 7) == 0xffffffff) + return; + } + writememll(addr, val); + writememll(addr + 4, val >> 32); + return; + } else if (writelookup2[addr >> 12] != -1) { + *(uint64_t *)(writelookup2[addr >> 12] + addr) = val; + return; + } + } + if (page_lookup[addr >> 12]) { + page_lookup[addr >> 12]->write_l(addr, val, page_lookup[addr >> 12]); + page_lookup[addr >> 12]->write_l(addr + 4, val >> 32, page_lookup[addr >> 12]); + return; + } + if (cr0 >> 31) { + addr = mmutranslate_write(addr); + if (addr == 0xFFFFFFFF) + return; + } - addr &= rammask; + addr &= rammask; - map = write_mapping[addr >> 14]; - if (map) { - if (map->write_l) { - map->write_l(addr, val, map->p); - map->write_l(addr + 4, val >> 32, map->p); - } else if (map->write_w) { - map->write_w(addr, val, map->p); - map->write_w(addr + 2, val >> 16, map->p); - map->write_w(addr + 4, val >> 32, map->p); - map->write_w(addr + 6, val >> 48, map->p); - } else if (map->write_b) { - map->write_b(addr, val, map->p); - map->write_b(addr + 1, val >> 8, map->p); - map->write_b(addr + 2, val >> 16, map->p); - map->write_b(addr + 3, val >> 24, map->p); - map->write_b(addr + 4, val >> 32, map->p); - map->write_b(addr + 5, val >> 40, map->p); - map->write_b(addr + 6, val >> 48, map->p); - map->write_b(addr + 7, val >> 56, map->p); - } - } -// pclog("Bad writememql %08X %08X\n", addr, val); + map = write_mapping[addr >> 14]; + if (map) { + if (map->write_l) { + map->write_l(addr, val, map->p); + map->write_l(addr + 4, val >> 32, map->p); + } else if (map->write_w) { + map->write_w(addr, val, map->p); + map->write_w(addr + 2, val >> 16, map->p); + map->write_w(addr + 4, val >> 32, map->p); + map->write_w(addr + 6, val >> 48, map->p); + } else if (map->write_b) { + map->write_b(addr, val, map->p); + map->write_b(addr + 1, val >> 8, map->p); + map->write_b(addr + 2, val >> 16, map->p); + map->write_b(addr + 3, val >> 24, map->p); + map->write_b(addr + 4, val >> 32, map->p); + map->write_b(addr + 5, val >> 40, map->p); + map->write_b(addr + 6, val >> 48, map->p); + map->write_b(addr + 7, val >> 56, map->p); + } + } + // pclog("Bad writememql %08X %08X\n", addr, val); } uint8_t mem_readb_phys(uint32_t addr) { - mem_mapping_t *map = read_mapping[addr >> 14]; + mem_mapping_t *map = read_mapping[addr >> 14]; - mem_logical_addr = 0xffffffff; + mem_logical_addr = 0xffffffff; - if (map && map->read_b) - return map->read_b(addr, map->p); + if (map && map->read_b) + return map->read_b(addr, map->p); - return 0xff; + return 0xff; } uint16_t mem_readw_phys(uint32_t addr) { - mem_mapping_t *map = read_mapping[addr >> 14]; + mem_mapping_t *map = read_mapping[addr >> 14]; - mem_logical_addr = 0xffffffff; + mem_logical_addr = 0xffffffff; - if (map && map->read_w) - return map->read_w(addr, map->p); + if (map && map->read_w) + return map->read_w(addr, map->p); - return mem_readb_phys(addr) | (mem_readb_phys(addr + 1) << 8); + return mem_readb_phys(addr) | (mem_readb_phys(addr + 1) << 8); } uint32_t mem_readl_phys(uint32_t addr) { - mem_mapping_t *map = read_mapping[addr >> 14]; + mem_mapping_t *map = read_mapping[addr >> 14]; - mem_logical_addr = 0xffffffff; + mem_logical_addr = 0xffffffff; - if (map && map->read_l) - return map->read_l(addr, map->p); + if (map && map->read_l) + return map->read_l(addr, map->p); - return mem_readw_phys(addr) | (mem_readw_phys(addr + 2) << 16); + return mem_readw_phys(addr) | (mem_readw_phys(addr + 2) << 16); } void mem_writeb_phys(uint32_t addr, uint8_t val) { - mem_mapping_t *map = write_mapping[addr >> 14]; + mem_mapping_t *map = write_mapping[addr >> 14]; - mem_logical_addr = 0xffffffff; + mem_logical_addr = 0xffffffff; - if (map && map->write_b) - map->write_b(addr, val, map->p); + if (map && map->write_b) + map->write_b(addr, val, map->p); } void mem_writew_phys(uint32_t addr, uint16_t val) { - mem_mapping_t *map = write_mapping[addr >> 14]; + mem_mapping_t *map = write_mapping[addr >> 14]; - mem_logical_addr = 0xffffffff; + mem_logical_addr = 0xffffffff; - if (map && map->write_w && !(addr & 1)) - map->write_w(addr, val, map->p); - else { - mem_writeb_phys(addr, val); - mem_writeb_phys(addr + 1, val >> 8); - } + if (map && map->write_w && !(addr & 1)) + map->write_w(addr, val, map->p); + else { + mem_writeb_phys(addr, val); + mem_writeb_phys(addr + 1, val >> 8); + } } void mem_writel_phys(uint32_t addr, uint32_t val) { - mem_mapping_t *map = write_mapping[addr >> 14]; + mem_mapping_t *map = write_mapping[addr >> 14]; - mem_logical_addr = 0xffffffff; + mem_logical_addr = 0xffffffff; - if (map && map->write_l && !(addr & 3)) - map->write_l(addr, val, map->p); - else { - mem_writew_phys(addr, val); - mem_writew_phys(addr + 2, val >> 16); - } + if (map && map->write_l && !(addr & 3)) + map->write_l(addr, val, map->p); + else { + mem_writew_phys(addr, val); + mem_writew_phys(addr + 2, val >> 16); + } } uint8_t mem_read_ram(uint32_t addr, void *priv) { -// if (addr >= 0xc0000 && addr < 0x0c8000) pclog("Read RAMb %08X\n", addr); - addreadlookup(mem_logical_addr, addr); - return ram[addr]; + // if (addr >= 0xc0000 && addr < 0x0c8000) pclog("Read RAMb %08X\n", addr); + addreadlookup(mem_logical_addr, addr); + return ram[addr]; } uint16_t mem_read_ramw(uint32_t addr, void *priv) { -// if (addr >= 0xc0000 && addr < 0x0c8000) pclog("Read RAMw %08X\n", addr); - addreadlookup(mem_logical_addr, addr); - return *(uint16_t *)&ram[addr]; + // if (addr >= 0xc0000 && addr < 0x0c8000) pclog("Read RAMw %08X\n", addr); + addreadlookup(mem_logical_addr, addr); + return *(uint16_t *)&ram[addr]; } uint32_t mem_read_raml(uint32_t addr, void *priv) { -// if (addr >= 0xc0000 && addr < 0x0c8000) pclog("Read RAMl %08X\n", addr); - addreadlookup(mem_logical_addr, addr); - return *(uint32_t *)&ram[addr]; + // if (addr >= 0xc0000 && addr < 0x0c8000) pclog("Read RAMl %08X\n", addr); + addreadlookup(mem_logical_addr, addr); + return *(uint32_t *)&ram[addr]; } uint32_t purgable_page_list_head = 0; int purgeable_page_count = 0; -static inline int page_index(page_t *p) { - return ((uintptr_t)p - (uintptr_t)pages) / sizeof(page_t); -} +static inline int page_index(page_t *p) { return ((uintptr_t)p - (uintptr_t)pages) / sizeof(page_t); } void page_add_to_evict_list(page_t *p) { -// pclog("page_add_to_evict_list: %08x %i\n", page_index(p), purgeable_page_count); - pages[purgable_page_list_head].evict_prev = page_index(p); - p->evict_next = purgable_page_list_head; - p->evict_prev = 0; - purgable_page_list_head = pages[purgable_page_list_head].evict_prev; - purgeable_page_count++; + // pclog("page_add_to_evict_list: %08x %i\n", page_index(p), purgeable_page_count); + pages[purgable_page_list_head].evict_prev = page_index(p); + p->evict_next = purgable_page_list_head; + p->evict_prev = 0; + purgable_page_list_head = pages[purgable_page_list_head].evict_prev; + purgeable_page_count++; } void page_remove_from_evict_list(page_t *p) { -// pclog("page_remove_from_evict_list: %08x %i\n", page_index(p), purgeable_page_count); - if (!page_in_evict_list(p)) - fatal("page_remove_from_evict_list: not in evict list!\n"); - if (p->evict_prev) - pages[p->evict_prev].evict_next = p->evict_next; - else - purgable_page_list_head = p->evict_next; - if (p->evict_next) - pages[p->evict_next].evict_prev = p->evict_prev; - p->evict_prev = EVICT_NOT_IN_LIST; - purgeable_page_count--; + // pclog("page_remove_from_evict_list: %08x %i\n", page_index(p), purgeable_page_count); + if (!page_in_evict_list(p)) + fatal("page_remove_from_evict_list: not in evict list!\n"); + if (p->evict_prev) + pages[p->evict_prev].evict_next = p->evict_next; + else + purgable_page_list_head = p->evict_next; + if (p->evict_next) + pages[p->evict_next].evict_prev = p->evict_prev; + p->evict_prev = EVICT_NOT_IN_LIST; + purgeable_page_count--; } void mem_write_ramb_page(uint32_t addr, uint8_t val, page_t *p) { - if (val != p->mem[addr & 0xfff] || codegen_in_recompile) { - uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); - int byte_offset = (addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; - uint64_t byte_mask = (uint64_t)1 << (addr & PAGE_BYTE_MASK_MASK); + if (val != p->mem[addr & 0xfff] || codegen_in_recompile) { + uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); + int byte_offset = (addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; + uint64_t byte_mask = (uint64_t)1 << (addr & PAGE_BYTE_MASK_MASK); -// pclog("mem_write_ramb_page: %08x %02x %08x %llx %llx\n", addr, val, cs+cpu_state.pc, p->dirty_mask, mask); - p->mem[addr & 0xfff] = val; - p->dirty_mask |= mask; - if ((p->code_present_mask & mask) && !page_in_evict_list(p)) { -// pclog("ramb add %08x %016llx %016llx\n", addr, p->code_present_mask[index], mask); - page_add_to_evict_list(p); - } - p->byte_dirty_mask[byte_offset] |= byte_mask; - if ((p->byte_code_present_mask[byte_offset] & byte_mask) && !page_in_evict_list(p)) { -// pclog(" ramb add %08x %016llx %016llx\n", addr, p->byte_code_present_mask[byte_offset], byte_mask); - page_add_to_evict_list(p); - } - } + // pclog("mem_write_ramb_page: %08x %02x %08x %llx %llx\n", addr, val, cs+cpu_state.pc, p->dirty_mask, + // mask); + p->mem[addr & 0xfff] = val; + p->dirty_mask |= mask; + if ((p->code_present_mask & mask) && !page_in_evict_list(p)) { + // pclog("ramb add %08x %016llx %016llx\n", addr, p->code_present_mask[index], + // mask); + page_add_to_evict_list(p); + } + p->byte_dirty_mask[byte_offset] |= byte_mask; + if ((p->byte_code_present_mask[byte_offset] & byte_mask) && !page_in_evict_list(p)) { + // pclog(" ramb add %08x %016llx %016llx\n", addr, + // p->byte_code_present_mask[byte_offset], byte_mask); + page_add_to_evict_list(p); + } + } } void mem_write_ramw_page(uint32_t addr, uint16_t val, page_t *p) { - if (val != *(uint16_t *)&p->mem[addr & 0xfff] || codegen_in_recompile) { - uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); - int byte_offset = (addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; - uint64_t byte_mask = (uint64_t)1 << (addr & PAGE_BYTE_MASK_MASK); + if (val != *(uint16_t *)&p->mem[addr & 0xfff] || codegen_in_recompile) { + uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); + int byte_offset = (addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; + uint64_t byte_mask = (uint64_t)1 << (addr & PAGE_BYTE_MASK_MASK); - if ((addr & 0xf) == 0xf) - mask |= (mask << 1); -// pclog("mem_write_ramw_page: %08x %04x %08x %016llx %016llx %016llx %08x %08x %p\n", addr, val, cs+cpu_state.pc, p->dirty_mask[index], p->code_present_mask[index], mask, p->evict_prev, p->evict_next, p); - *(uint16_t *)&p->mem[addr & 0xfff] = val; - p->dirty_mask |= mask; - if ((p->code_present_mask & mask) && !page_in_evict_list(p)) { -// pclog("ramw add %08x %016llx %016llx\n", addr, p->code_present_mask[index], mask); - page_add_to_evict_list(p); - } - if ((addr & PAGE_BYTE_MASK_MASK) == PAGE_BYTE_MASK_MASK) { - p->byte_dirty_mask[byte_offset + 1] |= 1; - if ((p->byte_code_present_mask[byte_offset + 1] & 1) && !page_in_evict_list(p)) { -// pclog("ramw add %08x %016llx %016llx\n", addr, p->code_present_mask[index], mask); - page_add_to_evict_list(p); - } - } else - byte_mask |= (byte_mask << 1); + if ((addr & 0xf) == 0xf) + mask |= (mask << 1); + // pclog("mem_write_ramw_page: %08x %04x %08x %016llx %016llx %016llx %08x %08x %p\n", addr, val, + // cs+cpu_state.pc, p->dirty_mask[index], p->code_present_mask[index], mask, p->evict_prev, p->evict_next, + // p); + *(uint16_t *)&p->mem[addr & 0xfff] = val; + p->dirty_mask |= mask; + if ((p->code_present_mask & mask) && !page_in_evict_list(p)) { + // pclog("ramw add %08x %016llx %016llx\n", addr, p->code_present_mask[index], + // mask); + page_add_to_evict_list(p); + } + if ((addr & PAGE_BYTE_MASK_MASK) == PAGE_BYTE_MASK_MASK) { + p->byte_dirty_mask[byte_offset + 1] |= 1; + if ((p->byte_code_present_mask[byte_offset + 1] & 1) && !page_in_evict_list(p)) { + // pclog("ramw add %08x %016llx %016llx\n", addr, + // p->code_present_mask[index], mask); + page_add_to_evict_list(p); + } + } else + byte_mask |= (byte_mask << 1); - p->byte_dirty_mask[byte_offset] |= byte_mask; + p->byte_dirty_mask[byte_offset] |= byte_mask; - if ((p->byte_code_present_mask[byte_offset] & byte_mask) && !page_in_evict_list(p)) { -// pclog("ramw add %08x %016llx %016llx\n", addr, p->code_present_mask[index], mask); - page_add_to_evict_list(p); - } - } + if ((p->byte_code_present_mask[byte_offset] & byte_mask) && !page_in_evict_list(p)) { + // pclog("ramw add %08x %016llx %016llx\n", addr, p->code_present_mask[index], + // mask); + page_add_to_evict_list(p); + } + } } void mem_write_raml_page(uint32_t addr, uint32_t val, page_t *p) { - if (val != *(uint32_t *)&p->mem[addr & 0xfff] || codegen_in_recompile) { - uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); - int byte_offset = (addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; - uint64_t byte_mask = (uint64_t)0xf << (addr & PAGE_BYTE_MASK_MASK); + if (val != *(uint32_t *)&p->mem[addr & 0xfff] || codegen_in_recompile) { + uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); + int byte_offset = (addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; + uint64_t byte_mask = (uint64_t)0xf << (addr & PAGE_BYTE_MASK_MASK); - if ((addr & 0xf) >= 0xd) - mask |= (mask << 1); -// pclog("mem_write_raml_page: %08x %08x %08x %016llx %016llx %016llx\n", addr, val, cs+cpu_state.pc, p->dirty_mask[index], p->code_present_mask[index], mask); - *(uint32_t *)&p->mem[addr & 0xfff] = val; - p->dirty_mask |= mask; - p->byte_dirty_mask[byte_offset] |= byte_mask; - if (!page_in_evict_list(p) && ((p->code_present_mask & mask) || (p->byte_code_present_mask[byte_offset] & byte_mask))) { -// pclog("raml add %08x %016llx %016llx\n", addr, p->code_present_mask[index], mask); - page_add_to_evict_list(p); - } - if ((addr & PAGE_BYTE_MASK_MASK) > (PAGE_BYTE_MASK_MASK - 3)) { - uint32_t byte_mask_2 = 0xf >> (4 - (addr & 3)); + if ((addr & 0xf) >= 0xd) + mask |= (mask << 1); + // pclog("mem_write_raml_page: %08x %08x %08x %016llx %016llx %016llx\n", addr, val, cs+cpu_state.pc, + // p->dirty_mask[index], p->code_present_mask[index], mask); + *(uint32_t *)&p->mem[addr & 0xfff] = val; + p->dirty_mask |= mask; + p->byte_dirty_mask[byte_offset] |= byte_mask; + if (!page_in_evict_list(p) && + ((p->code_present_mask & mask) || (p->byte_code_present_mask[byte_offset] & byte_mask))) { + // pclog("raml add %08x %016llx %016llx\n", addr, p->code_present_mask[index], + // mask); + page_add_to_evict_list(p); + } + if ((addr & PAGE_BYTE_MASK_MASK) > (PAGE_BYTE_MASK_MASK - 3)) { + uint32_t byte_mask_2 = 0xf >> (4 - (addr & 3)); - p->byte_dirty_mask[byte_offset + 1] |= byte_mask_2; - if ((p->byte_code_present_mask[byte_offset + 1] & byte_mask_2) && !page_in_evict_list(p)) { -// pclog("raml add %08x %016llx %016llx\n", addr, p->code_present_mask[index], mask); - page_add_to_evict_list(p); - } - } - } + p->byte_dirty_mask[byte_offset + 1] |= byte_mask_2; + if ((p->byte_code_present_mask[byte_offset + 1] & byte_mask_2) && !page_in_evict_list(p)) { + // pclog("raml add %08x %016llx %016llx\n", addr, + // p->code_present_mask[index], mask); + page_add_to_evict_list(p); + } + } + } } void mem_write_ram(uint32_t addr, uint8_t val, void *priv) { - addwritelookup(mem_logical_addr, addr); - mem_write_ramb_page(addr, val, &pages[addr >> 12]); + 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]); + 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]); + addwritelookup(mem_logical_addr, addr); + mem_write_raml_page(addr, val, &pages[addr >> 12]); } static uint32_t remap_start_addr; uint8_t mem_read_remapped(uint32_t addr, void *priv) { - addr = 0xA0000 + (addr - remap_start_addr); - addreadlookup(mem_logical_addr, addr); - return ram[addr]; + addr = 0xA0000 + (addr - remap_start_addr); + addreadlookup(mem_logical_addr, addr); + return ram[addr]; } uint16_t mem_read_remappedw(uint32_t addr, void *priv) { - addr = 0xA0000 + (addr - remap_start_addr); - addreadlookup(mem_logical_addr, addr); - return *(uint16_t *)&ram[addr]; + addr = 0xA0000 + (addr - remap_start_addr); + addreadlookup(mem_logical_addr, addr); + return *(uint16_t *)&ram[addr]; } uint32_t mem_read_remappedl(uint32_t addr, void *priv) { - addr = 0xA0000 + (addr - remap_start_addr); - addreadlookup(mem_logical_addr, addr); - return *(uint32_t *)&ram[addr]; + addr = 0xA0000 + (addr - remap_start_addr); + addreadlookup(mem_logical_addr, addr); + return *(uint32_t *)&ram[addr]; } void mem_write_remapped(uint32_t addr, uint8_t val, void *priv) { - uint32_t oldaddr = addr; - addr = 0xA0000 + (addr - remap_start_addr); - addwritelookup(mem_logical_addr, addr); - mem_write_ramb_page(addr, val, &pages[oldaddr >> 12]); + uint32_t oldaddr = addr; + addr = 0xA0000 + (addr - remap_start_addr); + addwritelookup(mem_logical_addr, addr); + mem_write_ramb_page(addr, val, &pages[oldaddr >> 12]); } void mem_write_remappedw(uint32_t addr, uint16_t val, void *priv) { - uint32_t oldaddr = addr; - addr = 0xA0000 + (addr - remap_start_addr); - addwritelookup(mem_logical_addr, addr); - mem_write_ramw_page(addr, val, &pages[oldaddr >> 12]); + uint32_t oldaddr = addr; + addr = 0xA0000 + (addr - remap_start_addr); + addwritelookup(mem_logical_addr, addr); + mem_write_ramw_page(addr, val, &pages[oldaddr >> 12]); } void mem_write_remappedl(uint32_t addr, uint32_t val, void *priv) { - uint32_t oldaddr = addr; - addr = 0xA0000 + (addr - remap_start_addr); - addwritelookup(mem_logical_addr, addr); - mem_write_raml_page(addr, val, &pages[oldaddr >> 12]); + uint32_t oldaddr = addr; + addr = 0xA0000 + (addr - remap_start_addr); + addwritelookup(mem_logical_addr, addr); + mem_write_raml_page(addr, val, &pages[oldaddr >> 12]); } uint8_t mem_read_bios(uint32_t addr, void *priv) { -// pclog("Read BIOS %08X %02X %04X:%04X\n", addr, rom[addr & biosmask], CS, pc); - return rom[addr & biosmask]; + // pclog("Read BIOS %08X %02X %04X:%04X\n", addr, rom[addr & biosmask], CS, pc); + return rom[addr & biosmask]; } uint16_t mem_read_biosw(uint32_t addr, void *priv) { -// pclog("Read BIOS %08X %04X %04X:%04X\n", addr, *(uint16_t *)&rom[addr & biosmask], CS, pc); - return *(uint16_t *)&rom[addr & biosmask]; + // pclog("Read BIOS %08X %04X %04X:%04X\n", addr, *(uint16_t *)&rom[addr & biosmask], CS, pc); + return *(uint16_t *)&rom[addr & biosmask]; } uint32_t mem_read_biosl(uint32_t addr, void *priv) { -// pclog("Read BIOS %08X %02X %04X:%04X\n", addr, *(uint32_t *)&rom[addr & biosmask], CS, pc); - return *(uint32_t *)&rom[addr & biosmask]; + // pclog("Read BIOS %08X %02X %04X:%04X\n", addr, *(uint32_t *)&rom[addr & biosmask], CS, pc); + 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) { - return *(uint16_t *)&romext[addr & 0x7fff]; -} -uint32_t mem_read_romextl(uint32_t addr, void *priv) { - return *(uint32_t *)&romext[addr & 0x7fff]; -} +uint8_t mem_read_romext(uint32_t addr, void *priv) { return romext[addr & 0x7fff]; } +uint16_t mem_read_romextw(uint32_t addr, void *priv) { return *(uint16_t *)&romext[addr & 0x7fff]; } +uint32_t mem_read_romextl(uint32_t addr, void *priv) { return *(uint32_t *)&romext[addr & 0x7fff]; } -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_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; + 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); - page_t *p = &pages[start_addr >> 12]; + 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); + page_t *p = &pages[start_addr >> 12]; -//pclog("mem_invalidate: %08x\n", start_addr); - p->dirty_mask |= mask; - if ((p->code_present_mask & mask) && !page_in_evict_list(p)) { -// pclog("invalidate add %08x %016llx %016llx\n", start_addr, p->code_present_mask[index], mask); - page_add_to_evict_list(p); - } - } + // pclog("mem_invalidate: %08x\n", start_addr); + p->dirty_mask |= mask; + if ((p->code_present_mask & mask) && !page_in_evict_list(p)) { + // pclog("invalidate add %08x %016llx %016llx\n", start_addr, + // p->code_present_mask[index], mask); + page_add_to_evict_list(p); + } + } } static inline int mem_mapping_read_allowed(uint32_t flags, int state) { -// pclog("mem_mapping_read_allowed: flags=%x state=%x\n", flags, 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; + // pclog("mem_mapping_read_allowed: flags=%x state=%x\n", flags, 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; + 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) { - uint64_t c; - mem_mapping_t *mapping = base_mapping.next; + uint64_t c; + mem_mapping_t *mapping = base_mapping.next; - if (!size) - return; - /*Clear out old mappings*/ - for (c = base; c < base + size; c += 0x4000) { - read_mapping[c >> 14] = NULL; - write_mapping[c >> 14] = NULL; - _mem_exec[c >> 14] = NULL; - } + if (!size) + return; + /*Clear out old mappings*/ + for (c = base; c < base + size; c += 0x4000) { + read_mapping[c >> 14] = NULL; + write_mapping[c >> 14] = NULL; + _mem_exec[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; + /*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])) { - read_mapping[c >> 14] = mapping; - if (mapping->exec) - _mem_exec[c >> 14] = mapping->exec + (c - mapping->base); - else - _mem_exec[c >> 14] = NULL; - } - if ((mapping->write_b || mapping->write_w || mapping->write_l) && - mem_mapping_write_allowed(mapping->flags, _mem_state[c >> 14])) { - write_mapping[c >> 14] = mapping; - } - } - } - mapping = mapping->next; - } - flushmmucache_cr3(); + 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])) { + read_mapping[c >> 14] = mapping; + if (mapping->exec) + _mem_exec[c >> 14] = mapping->exec + (c - mapping->base); + else + _mem_exec[c >> 14] = NULL; + } + if ((mapping->write_b || mapping->write_w || mapping->write_l) && + mem_mapping_write_allowed(mapping->flags, _mem_state[c >> 14])) { + write_mapping[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; +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; + /*Add mapping to the end of the list*/ + while (dest->next) + dest = dest->next; + dest->next = mapping; - 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; + 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); + 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; +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); + 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); + /*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; + /*Set new mapping*/ + mapping->enable = 1; + mapping->base = base; + mapping->size = size; - mem_mapping_recalc(mapping->base, mapping->size); + mem_mapping_recalc(mapping->base, mapping->size); } void mem_mapping_set_exec(mem_mapping_t *mapping, uint8_t *exec) { - mapping->exec = exec; + mapping->exec = exec; - mem_mapping_recalc(mapping->base, mapping->size); + mem_mapping_recalc(mapping->base, mapping->size); } -void mem_mapping_set_p(mem_mapping_t *mapping, void *p) { - mapping->p = p; -} +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; + mapping->enable = 0; - mem_mapping_recalc(mapping->base, mapping->size); + mem_mapping_recalc(mapping->base, mapping->size); } void mem_mapping_enable(mem_mapping_t *mapping) { - mapping->enable = 1; + mapping->enable = 1; - mem_mapping_recalc(mapping->base, mapping->size); + mem_mapping_recalc(mapping->base, mapping->size); } void mem_set_mem_state(uint32_t base, uint32_t size, int state) { - uint32_t c; + uint32_t c; -// pclog("mem_set_pci_enable: base=%08x size=%08x\n", base, size); - for (c = 0; c < size; c += 0x4000) - _mem_state[(c + base) >> 14] = state; + // pclog("mem_set_pci_enable: base=%08x size=%08x\n", base, size); + for (c = 0; c < size; c += 0x4000) + _mem_state[(c + base) >> 14] = state; - mem_mapping_recalc(base, size); + mem_mapping_recalc(base, size); } void mem_add_bios() { - 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 + (0x20000 & biosmask), - 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 + (0x24000 & 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 + (0x28000 & 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 + (0x2c000 & 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 + (0x30000 & 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 + (0x34000 & 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 + (0x38000 & 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 + (0x3c000 & biosmask), - MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM, - 0); + 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 + (0x20000 & biosmask), + 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 + (0x24000 & 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 + (0x28000 & 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 + (0x2c000 & 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 + (0x30000 & 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 + (0x34000 & 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 + (0x38000 & 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 + (0x3c000 & 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 + (0x20000 & biosmask), - 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 + (0x24000 & 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 + (0x28000 & 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 + (0x2c000 & 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 + (0x30000 & 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 + (0x34000 & 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 + (0x38000 & 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 + (0x3c000 & biosmask), - MEM_MAPPING_ROM, - 0); - if (biosmask == 0x3ffff) - mem_mapping_add(&bios_high_mapping[8], - (AT && cpu_16bitbus) ? 0xfc0000 : 0xfffc0000, - 0x20000, - 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[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 + (0x20000 & biosmask), 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 + (0x24000 & 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 + (0x28000 & 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 + (0x2c000 & 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 + (0x30000 & 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 + (0x34000 & 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 + (0x38000 & 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 + (0x3c000 & biosmask), MEM_MAPPING_ROM, 0); + if (biosmask == 0x3ffff) + mem_mapping_add(&bios_high_mapping[8], (AT && cpu_16bitbus) ? 0xfc0000 : 0xfffc0000, 0x20000, mem_read_bios, + mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom, + MEM_MAPPING_ROM, 0); } int mem_a20_key = 0, mem_a20_alt = 0; static int mem_a20_state = 2; static void mem_remap_top(int max_size) { - int c; + int 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; + 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; - remap_start_addr = start * 1024; + remap_start_addr = start * 1024; - for (c = ((start * 1024) >> 12); c < (((start + size) * 1024) >> 12); c++) { - int offset = c - ((start * 1024) >> 12); - pages[c].mem = &ram[0xA0000 + (offset << 12)]; - pages[c].write_b = mem_write_ramb_page; - pages[c].write_w = mem_write_ramw_page; - pages[c].write_l = mem_write_raml_page; - pages[c].evict_prev = EVICT_NOT_IN_LIST; - pages[c].byte_dirty_mask = &byte_dirty_mask[offset * 64]; - pages[c].byte_code_present_mask = &byte_code_present_mask[offset * 64]; - } + for (c = ((start * 1024) >> 12); c < (((start + size) * 1024) >> 12); c++) { + int offset = c - ((start * 1024) >> 12); + pages[c].mem = &ram[0xA0000 + (offset << 12)]; + pages[c].write_b = mem_write_ramb_page; + pages[c].write_w = mem_write_ramw_page; + pages[c].write_l = mem_write_raml_page; + pages[c].evict_prev = EVICT_NOT_IN_LIST; + pages[c].byte_dirty_mask = &byte_dirty_mask[offset * 64]; + pages[c].byte_code_present_mask = &byte_code_present_mask[offset * 64]; + } - mem_set_mem_state(start * 1024, size * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - mem_mapping_add(&ram_remapped_mapping, - start * 1024, - size * 1024, - mem_read_remapped, - mem_read_remappedw, - mem_read_remappedl, - mem_write_remapped, - mem_write_remappedw, - mem_write_remappedl, - ram + 0xA0000, - MEM_MAPPING_INTERNAL, - NULL); - } + mem_set_mem_state(start * 1024, size * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + mem_mapping_add(&ram_remapped_mapping, start * 1024, size * 1024, mem_read_remapped, mem_read_remappedw, + mem_read_remappedl, mem_write_remapped, mem_write_remappedw, mem_write_remappedl, ram + 0xA0000, + MEM_MAPPING_INTERNAL, NULL); + } } -void mem_remap_top_256k() { - mem_remap_top(256); -} -void mem_remap_top_384k() { - mem_remap_top(384); -} +void mem_remap_top_256k() { mem_remap_top(256); } +void mem_remap_top_384k() { mem_remap_top(384); } void mem_set_704kb() { - mem_set_mem_state(0x000000, (mem_size > 704) ? 0xb0000 : mem_size * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - mem_mapping_set_addr(&ram_low_mapping, 0x00000, (mem_size > 704) ? 0xb0000 : mem_size * 1024); + mem_set_mem_state(0x000000, (mem_size > 704) ? 0xb0000 : mem_size * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + mem_mapping_set_addr(&ram_low_mapping, 0x00000, (mem_size > 704) ? 0xb0000 : mem_size * 1024); } void mem_init() { - readlookup2 = malloc(1024 * 1024 * sizeof(uintptr_t)); - writelookup2 = malloc(1024 * 1024 * sizeof(uintptr_t)); - page_lookup = malloc((1 << 20) * sizeof(page_t *)); + readlookup2 = malloc(1024 * 1024 * sizeof(uintptr_t)); + writelookup2 = malloc(1024 * 1024 * sizeof(uintptr_t)); + page_lookup = malloc((1 << 20) * sizeof(page_t *)); - memset(ff_array, 0xff, sizeof(ff_array)); + memset(ff_array, 0xff, sizeof(ff_array)); - smram_enable = NULL; - smram_disable = NULL; + smram_enable = NULL; + smram_disable = NULL; } void mem_alloc() { - int c; + int c; - free(ram); - ram = malloc(mem_size * 1024); - memset(ram, 0, mem_size * 1024); + free(ram); + ram = malloc(mem_size * 1024); + memset(ram, 0, mem_size * 1024); - free(byte_dirty_mask); - byte_dirty_mask = malloc((mem_size * 1024) / 8); - memset(byte_dirty_mask, 0, (mem_size * 1024) / 8); - free(byte_code_present_mask); - byte_code_present_mask = malloc((mem_size * 1024) / 8); - memset(byte_code_present_mask, 0, (mem_size * 1024) / 8); + free(byte_dirty_mask); + byte_dirty_mask = malloc((mem_size * 1024) / 8); + memset(byte_dirty_mask, 0, (mem_size * 1024) / 8); + free(byte_code_present_mask); + byte_code_present_mask = malloc((mem_size * 1024) / 8); + memset(byte_code_present_mask, 0, (mem_size * 1024) / 8); - free(pages); - pages = malloc((((mem_size + 384) * 1024) >> 12) * sizeof(page_t)); - memset(pages, 0, (((mem_size + 384) * 1024) >> 12) * sizeof(page_t)); - for (c = 0; c < (((mem_size + 384) * 1024) >> 12); c++) { - pages[c].mem = &ram[c << 12]; - pages[c].write_b = mem_write_ramb_page; - pages[c].write_w = mem_write_ramw_page; - pages[c].write_l = mem_write_raml_page; - pages[c].evict_prev = EVICT_NOT_IN_LIST; - pages[c].byte_dirty_mask = &byte_dirty_mask[c * 64]; - pages[c].byte_code_present_mask = &byte_code_present_mask[c * 64]; - } + free(pages); + pages = malloc((((mem_size + 384) * 1024) >> 12) * sizeof(page_t)); + memset(pages, 0, (((mem_size + 384) * 1024) >> 12) * sizeof(page_t)); + for (c = 0; c < (((mem_size + 384) * 1024) >> 12); c++) { + pages[c].mem = &ram[c << 12]; + pages[c].write_b = mem_write_ramb_page; + pages[c].write_w = mem_write_ramw_page; + pages[c].write_l = mem_write_raml_page; + pages[c].evict_prev = EVICT_NOT_IN_LIST; + pages[c].byte_dirty_mask = &byte_dirty_mask[c * 64]; + pages[c].byte_code_present_mask = &byte_code_present_mask[c * 64]; + } - memset(page_lookup, 0, (1 << 20) * sizeof(page_t *)); + memset(page_lookup, 0, (1 << 20) * sizeof(page_t *)); - memset(read_mapping, 0, sizeof(read_mapping)); - memset(write_mapping, 0, sizeof(write_mapping)); - memset(_mem_exec, 0, sizeof(_mem_exec)); + memset(read_mapping, 0, sizeof(read_mapping)); + memset(write_mapping, 0, sizeof(write_mapping)); + memset(_mem_exec, 0, sizeof(_mem_exec)); - memset(&base_mapping, 0, sizeof(base_mapping)); + memset(&base_mapping, 0, sizeof(base_mapping)); - memset(_mem_state, 0, sizeof(_mem_state)); + memset(_mem_state, 0, sizeof(_mem_state)); - mem_set_mem_state(0x000000, (mem_size > 640) ? 0xa0000 : mem_size * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - if (romset == ROM_XI8088) { - // Xi 8088 UMBs are selected by DIP Switches - mem_set_mem_state(0x0a0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - mem_set_mem_state(0x0c0000, 0x08000, model_get_config_int("umb_c0000h_c7fff") ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL)); - mem_set_mem_state(0x0c8000, 0x08000, model_get_config_int("umb_c8000h_cffff") ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL)); - mem_set_mem_state(0x0d0000, 0x08000, model_get_config_int("umb_d0000h_d7fff") ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL)); - mem_set_mem_state(0x0d8000, 0x08000, model_get_config_int("umb_d8000h_dffff") ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL)); - mem_set_mem_state(0x0e0000, 0x08000, model_get_config_int("umb_e0000h_e7fff") ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL)); - mem_set_mem_state(0x0e8000, 0x08000, model_get_config_int("umb_e8000h_effff") ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL)); - mem_set_mem_state(0x0f0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - } else { - mem_set_mem_state(0x0a0000, 0x60000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - } + mem_set_mem_state(0x000000, (mem_size > 640) ? 0xa0000 : mem_size * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + if (romset == ROM_XI8088) { + // Xi 8088 UMBs are selected by DIP Switches + mem_set_mem_state(0x0a0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + mem_set_mem_state(0x0c0000, 0x08000, + model_get_config_int("umb_c0000h_c7fff") ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) + : (MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL)); + mem_set_mem_state(0x0c8000, 0x08000, + model_get_config_int("umb_c8000h_cffff") ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) + : (MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL)); + mem_set_mem_state(0x0d0000, 0x08000, + model_get_config_int("umb_d0000h_d7fff") ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) + : (MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL)); + mem_set_mem_state(0x0d8000, 0x08000, + model_get_config_int("umb_d8000h_dffff") ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) + : (MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL)); + mem_set_mem_state(0x0e0000, 0x08000, + model_get_config_int("umb_e0000h_e7fff") ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) + : (MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL)); + mem_set_mem_state(0x0e8000, 0x08000, + model_get_config_int("umb_e8000h_effff") ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) + : (MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL)); + mem_set_mem_state(0x0f0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + } else { + mem_set_mem_state(0x0a0000, 0x60000, 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) // 640k - 768k is graphics RAM - mem_mapping_add(&ram_mid_mapping, - 0xa0000, - 0x60000, - mem_read_ram, - mem_read_ramw, - mem_read_raml, - mem_write_ram, - mem_write_ramw, - mem_write_raml, - ram + 0xa0000, - MEM_MAPPING_INTERNAL, - NULL); + 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) // 640k - 768k is graphics RAM + mem_mapping_add(&ram_mid_mapping, 0xa0000, 0x60000, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, + mem_write_ramw, mem_write_raml, ram + 0xa0000, 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); + 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); -// pclog("Mem resize %i %i\n",mem_size,c); - mem_a20_key = 2; - mem_a20_alt = 0; - mem_a20_recalc(); + // pclog("Mem resize %i %i\n",mem_size,c); + mem_a20_key = 2; + mem_a20_alt = 0; + mem_a20_recalc(); - purgable_page_list_head = 0; - purgeable_page_count = 0; + purgable_page_list_head = 0; + purgeable_page_count = 0; } void mem_reset_page_blocks() { - int c; + int c; - 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 = BLOCK_INVALID; - pages[c].block_2 = BLOCK_INVALID; - } + 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 = BLOCK_INVALID; + pages[c].block_2 = BLOCK_INVALID; + } } void mem_a20_recalc() { - int state = mem_a20_key | mem_a20_alt; -// pclog("A20 recalc %i %i\n", state, mem_a20_state); - 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(); - } -// pclog("rammask now %08X\n", rammask); - mem_a20_state = state; + int state = mem_a20_key | mem_a20_alt; + // pclog("A20 recalc %i %i\n", state, mem_a20_state); + 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(); + } + // pclog("rammask now %08X\n", rammask); + mem_a20_state = state; } uint32_t get_phys_virt, get_phys_phys; diff --git a/src/memory/mem_bios.c b/src/memory/mem_bios.c index 09ea0879..9a256ca7 100644 --- a/src/memory/mem_bios.c +++ b/src/memory/mem_bios.c @@ -7,626 +7,670 @@ #include "xi8088.h" static void romfread(uint8_t *buf, size_t size, size_t count, FILE *fp) { - int result = fread(buf, size, count, fp); - if (result < count) { - pclog("ROM read failed: Expected %d, read %d\n", count, result); - } + int result = fread(buf, size, count, fp); + if (result < count) { + pclog("ROM read failed: Expected %d, read %d\n", count, result); + } } static int mem_load_basic(char *path) { - char s[256]; - FILE *f; + char s[256]; + FILE *f; - sprintf(s, "%s/ibm-basic-1.10.rom", path); - f = romfopen(s, "rb"); - if (!f) { - sprintf(s, "%s/basicc11.f6", path); - f = romfopen(s, "rb"); - if (!f) - return 1; /*I don't really care if BASIC is there or not*/ - romfread(rom + 0x6000, 8192, 1, f); - fclose(f); - sprintf(s, "%s/basicc11.f8", path); - f = romfopen(s, "rb"); - if (!f) - return 0; /*But if some of it is there, then all of it must be*/ - romfread(rom + 0x8000, 8192, 1, f); - fclose(f); - sprintf(s, "%s/basicc11.fa", path); - f = romfopen(s, "rb"); - if (!f) - return 0; - romfread(rom + 0xA000, 8192, 1, f); - fclose(f); - sprintf(s, "%s/basicc11.fc", path); - f = romfopen(s, "rb"); - if (!f) - return 0; - romfread(rom + 0xC000, 8192, 1, f); - fclose(f); - } else { - romfread(rom + 0x6000, 32768, 1, f); - fclose(f); - } + sprintf(s, "%s/ibm-basic-1.10.rom", path); + f = romfopen(s, "rb"); + if (!f) { + sprintf(s, "%s/basicc11.f6", path); + f = romfopen(s, "rb"); + if (!f) + return 1; /*I don't really care if BASIC is there or not*/ + romfread(rom + 0x6000, 8192, 1, f); + fclose(f); + sprintf(s, "%s/basicc11.f8", path); + f = romfopen(s, "rb"); + if (!f) + return 0; /*But if some of it is there, then all of it must be*/ + romfread(rom + 0x8000, 8192, 1, f); + fclose(f); + sprintf(s, "%s/basicc11.fa", path); + f = romfopen(s, "rb"); + if (!f) + return 0; + romfread(rom + 0xA000, 8192, 1, f); + fclose(f); + sprintf(s, "%s/basicc11.fc", path); + f = romfopen(s, "rb"); + if (!f) + return 0; + romfread(rom + 0xC000, 8192, 1, f); + fclose(f); + } else { + romfread(rom + 0x6000, 32768, 1, f); + fclose(f); + } - return 1; + return 1; } int loadbios() { - FILE *f = NULL, *ff = NULL; - int c; + FILE *f = NULL, *ff = NULL; + int c; - loadfont("mda.rom", FONT_MDA); - loadfont("wy700.rom", FONT_WY700); - loadfont("8x12.bin", FONT_MDSI); - loadfont("im1024font.bin", FONT_IM1024); + loadfont("mda.rom", FONT_MDA); + loadfont("wy700.rom", FONT_WY700); + loadfont("8x12.bin", FONT_MDSI); + loadfont("im1024font.bin", FONT_IM1024); - biosmask = 0xffff; + biosmask = 0xffff; - if (!rom) - rom = malloc(0x40000); - memset(romext, 0x63, 0x4000); - memset(rom, 0xff, 0x20000); + if (!rom) + rom = malloc(0x40000); + memset(romext, 0x63, 0x4000); + memset(rom, 0xff, 0x20000); - pclog("Starting with romset %i\n", romset); + pclog("Starting with romset %i\n", romset); - switch (romset) { - case ROM_PC1512:f = romfopen("pc1512/40043.v1", "rb"); - ff = romfopen("pc1512/40044.v1", "rb"); - if (!f || !ff) - break; - for (c = 0xC000; c < 0x10000; c += 2) { - rom[c] = getc(f); - rom[c + 1] = getc(ff); - } - fclose(ff); - fclose(f); - loadfont("pc1512/40078.ic127", FONT_CGA); - return 1; - case ROM_PC1640:f = romfopen("pc1640/40044.v3", "rb"); - ff = romfopen("pc1640/40043.v3", "rb"); - if (!f || !ff) - break; - for (c = 0xC000; c < 0x10000; c += 2) { - rom[c] = getc(f); - rom[c + 1] = getc(ff); - } - fclose(ff); - fclose(f); - f = romfopen("pc1640/40100", "rb"); - if (!f) - break; - fclose(f); - return 1; - case ROM_PC200:f = romfopen("pc200/pc20v2.1", "rb"); - ff = romfopen("pc200/pc20v2.0", "rb"); - if (!f || !ff) - break; - for (c = 0xC000; c < 0x10000; c += 2) { - rom[c] = getc(f); - rom[c + 1] = getc(ff); - } - fclose(ff); - fclose(f); - loadfont("pc200/40109.bin", FONT_PC200); - return 1; - case ROM_PPC512:f = romfopen("ppc512/40107.v2", "rb"); - ff = romfopen("ppc512/40108.v2", "rb"); - if (!f || !ff) - break; - for (c = 0xC000; c < 0x10000; c += 2) { - rom[c] = getc(f); - rom[c + 1] = getc(ff); - } - fclose(ff); - fclose(f); - loadfont("ppc512/40109.bin", FONT_PC200); - return 1; - case ROM_TANDY:f = romfopen("tandy/tandy1t1.020", "rb"); - if (!f) - break; - romfread(rom, 65536, 1, f); - fclose(f); - return 1; - case ROM_TANDY1000HX:f = romfopen("tandy1000hx/v020000.u12", "rb"); - if (!f) - break; - romfread(rom, 0x20000, 1, f); - fclose(f); - biosmask = 0x1ffff; - return 1; - case ROM_TANDY1000SL2:f = romfopen("tandy1000sl2/8079047.hu1", "rb"); - ff = romfopen("tandy1000sl2/8079048.hu2", "rb"); - if (!f || !ff) - break; - fseek(f, 0x30000 / 2, SEEK_SET); - fseek(ff, 0x30000 / 2, SEEK_SET); - for (c = 0x0000; c < 0x10000; c += 2) { - rom[c] = getc(f); - rom[c + 1] = getc(ff); - } - fclose(ff); - fclose(f); - return 1; -/* case ROM_IBMPCJR: - f=fopen("pcjr/bios.rom","rb"); - romfread(rom+0xE000,8192,1,f); + switch (romset) { + case ROM_PC1512: + f = romfopen("pc1512/40043.v1", "rb"); + ff = romfopen("pc1512/40044.v1", "rb"); + if (!f || !ff) + break; + for (c = 0xC000; c < 0x10000; c += 2) { + rom[c] = getc(f); + rom[c + 1] = getc(ff); + } + fclose(ff); fclose(f); - f=fopen("pcjr/basic.rom","rb"); - romfread(rom+0x6000,32768,1,f); + loadfont("pc1512/40078.ic127", FONT_CGA); + return 1; + case ROM_PC1640: + f = romfopen("pc1640/40044.v3", "rb"); + ff = romfopen("pc1640/40043.v3", "rb"); + if (!f || !ff) + break; + for (c = 0xC000; c < 0x10000; c += 2) { + rom[c] = getc(f); + rom[c + 1] = getc(ff); + } + fclose(ff); fclose(f); - break;*/ - case ROM_IBMXT:f = romfopen("ibmxt/xt.rom", "rb"); - if (!f) { - f = romfopen("ibmxt/5000027.u19", "rb"); - ff = romfopen("ibmxt/1501512.u18", "rb"); - if (!f || !ff) - break; - romfread(rom, 0x8000, 1, f); - romfread(rom + 0x8000, 0x8000, 1, ff); - fclose(ff); - fclose(f); - return 1; - } else { - romfread(rom, 65536, 1, f); - fclose(f); - return 1; - } - break; - - case ROM_IBMPCJR:f = romfopen("ibmpcjr/bios.rom", "rb"); - if (!f) - break; - romfread(rom, 0x10000, 1, f); - fclose(f); - return 1; - - case ROM_GENXT:f = romfopen("genxt/pcxt.rom", "rb"); - if (!f) - break; - romfread(rom + 0xE000, 8192, 1, f); - fclose(f); - if (!mem_load_basic("genxt")) - break; - return 1; - - case ROM_CBM_PC10:f = romfopen("cbm_pc10/cbm-pc10c-bios-v4.41-318085-08.bin", "rb"); - if (!f) - break; - romfread(rom + 0x8000, 32768, 1, f); - fclose(f); - return 1; - - case ROM_SUPER16T:f = romfopen("huyndaixt/super16t_v1.12ta.bin", "rb"); - if (!f) - break; - romfread(rom + 0xC000, 16384, 1, f); - fclose(f); - return 1; - - case ROM_SUPER16TE:f = romfopen("huyndaixte/super16te_v2.00id.bin", "rb"); - if (!f) - break; - romfread(rom + 0xC000, 16384, 1, f); - fclose(f); - return 1; - - case ROM_DTKXT:f = romfopen("dtk/dtk_erso_2.42_2764.bin", "rb"); - if (!f) - break; - romfread(rom + 0xE000, 8192, 1, f); - fclose(f); - return 1; - case ROM_OLIM24:f = romfopen("olivetti_m24/olivetti_m24_version_1.43_low.bin", "rb"); - ff = romfopen("olivetti_m24/olivetti_m24_version_1.43_high.bin", "rb"); - if (!f || !ff) - break; - for (c = 0x0000; c < 0x4000; c += 2) { - rom[c + 0xc000] = getc(f); - rom[c + 0xc001] = getc(ff); - } - fclose(ff); - fclose(f); - return 1; - - case ROM_PC2086:f = romfopen("pc2086/40179.ic129", "rb"); - ff = romfopen("pc2086/40180.ic132", "rb"); - if (!f || !ff) - break; - pclog("Loading BIOS\n"); - for (c = 0x0000; c < 0x4000; c += 2) { - rom[c + 0x0000] = getc(f); - rom[c + 0x0001] = getc(ff); - } - pclog("%02X %02X %02X\n", rom[0xfff0], rom[0xfff1], rom[0xfff2]); - fclose(ff); - fclose(f); - f = romfopen("pc2086/40186.ic171", "rb"); - if (!f) - break; - fclose(f); - biosmask = 0x3fff; - return 1; - - case ROM_PC3086:f = romfopen("pc3086/fc00.bin", "rb"); - if (!f) - break; - romfread(rom, 0x4000, 1, f); - fclose(f); - f = romfopen("pc3086/c000.bin", "rb"); - if (!f) - break; - fclose(f); - biosmask = 0x3fff; - return 1; - - case ROM_PC5086:f = romfopen("pc5086/sys_rom.bin", "rb"); - if (!f) - break; - romfread(rom, 65536, 1, f); - fclose(f); - return 1; - - case ROM_IBMAT: -/* f=romfopen("amic206.bin","rb"); - if (!f) break; - romfread(rom,65536,1,f); + f = romfopen("pc1640/40100", "rb"); + if (!f) + break; fclose(f); - return 1;*/ - case ROM_IBMAT386:f = romfopen("ibmat/62x0820.u27", "rb"); - ff = romfopen("ibmat/62x0821.u47", "rb"); - if (!f || !ff) - break; - for (c = 0x0000; c < 0x10000; c += 2) { - rom[c] = getc(f); - rom[c + 1] = getc(ff); - } - fclose(ff); - fclose(f); - return 1; - case ROM_CMDPC30:f = romfopen("cmdpc30/commodore pc 30 iii even.bin", "rb"); - ff = romfopen("cmdpc30/commodore pc 30 iii odd.bin", "rb"); - if (!f || !ff) - break; - for (c = 0x0000; c < 0x8000; c += 2) { - rom[c] = getc(f); - rom[c + 1] = getc(ff); - } - fclose(ff); - fclose(f); - biosmask = 0x7fff; - return 1; - case ROM_DELL200:f = romfopen("dells200/dell0.bin", "rb"); - ff = romfopen("dells200/dell1.bin", "rb"); - if (!f || !ff) - break; - for (c = 0x0000; c < 0x10000; c += 2) { - rom[c] = getc(f); - rom[c + 1] = getc(ff); - } - fclose(ff); - fclose(f); - return 1; -/* case ROM_IBMAT386: - f=romfopen("at386/at386.bin","rb"); - if (!f) break; - romfread(rom,65536,1,f); + return 1; + case ROM_PC200: + f = romfopen("pc200/pc20v2.1", "rb"); + ff = romfopen("pc200/pc20v2.0", "rb"); + if (!f || !ff) + break; + for (c = 0xC000; c < 0x10000; c += 2) { + rom[c] = getc(f); + rom[c + 1] = getc(ff); + } + fclose(ff); fclose(f); - return 1;*/ - case ROM_AMA932J: -// f=romfopen("at386/at386.bin","rb"); - f = romfopen("ama932j/ami.bin", "rb"); - if (!f) - break; - romfread(rom, 65536, 1, f); - fclose(f); - f = romfopen("ama932j/oti067.bin", "rb"); - if (!f) - break; - fclose(f); - return 1; + loadfont("pc200/40109.bin", FONT_PC200); + return 1; + case ROM_PPC512: + f = romfopen("ppc512/40107.v2", "rb"); + ff = romfopen("ppc512/40108.v2", "rb"); + if (!f || !ff) + break; + for (c = 0xC000; c < 0x10000; c += 2) { + rom[c] = getc(f); + rom[c + 1] = getc(ff); + } + fclose(ff); + fclose(f); + loadfont("ppc512/40109.bin", FONT_PC200); + return 1; + case ROM_TANDY: + f = romfopen("tandy/tandy1t1.020", "rb"); + if (!f) + break; + romfread(rom, 65536, 1, f); + fclose(f); + return 1; + case ROM_TANDY1000HX: + f = romfopen("tandy1000hx/v020000.u12", "rb"); + if (!f) + break; + romfread(rom, 0x20000, 1, f); + fclose(f); + biosmask = 0x1ffff; + return 1; + case ROM_TANDY1000SL2: + f = romfopen("tandy1000sl2/8079047.hu1", "rb"); + ff = romfopen("tandy1000sl2/8079048.hu2", "rb"); + if (!f || !ff) + break; + fseek(f, 0x30000 / 2, SEEK_SET); + fseek(ff, 0x30000 / 2, SEEK_SET); + for (c = 0x0000; c < 0x10000; c += 2) { + rom[c] = getc(f); + rom[c + 1] = getc(ff); + } + fclose(ff); + fclose(f); + return 1; + /* case ROM_IBMPCJR: + f=fopen("pcjr/bios.rom","rb"); + romfread(rom+0xE000,8192,1,f); + fclose(f); + f=fopen("pcjr/basic.rom","rb"); + romfread(rom+0x6000,32768,1,f); + fclose(f); + break;*/ + case ROM_IBMXT: + f = romfopen("ibmxt/xt.rom", "rb"); + if (!f) { + f = romfopen("ibmxt/5000027.u19", "rb"); + ff = romfopen("ibmxt/1501512.u18", "rb"); + if (!f || !ff) + break; + romfread(rom, 0x8000, 1, f); + romfread(rom + 0x8000, 0x8000, 1, ff); + fclose(ff); + fclose(f); + return 1; + } else { + romfread(rom, 65536, 1, f); + fclose(f); + return 1; + } + break; - case ROM_AMI386SX: -// f=romfopen("at386/at386.bin","rb"); - f = romfopen("ami386/ami386.bin", "rb"); - if (!f) - break; - romfread(rom, 65536, 1, f); - fclose(f); - return 1; + case ROM_IBMPCJR: + f = romfopen("ibmpcjr/bios.rom", "rb"); + if (!f) + break; + romfread(rom, 0x10000, 1, f); + fclose(f); + return 1; - case ROM_AMI386DX_OPTI495: /*This uses the OPTi 82C495 chipset*/ - f = romfopen("ami386dx/opt495sx.ami", "rb"); - if (!f) - break; - romfread(rom, 65536, 1, f); - fclose(f); - return 1; - case ROM_MR386DX_OPTI495: /*This uses the OPTi 82C495 chipset*/ - f = romfopen("mr386dx/opt495sx.mr", "rb"); - if (!f) - break; - romfread(rom, 65536, 1, f); - fclose(f); - return 1; + case ROM_GENXT: + f = romfopen("genxt/pcxt.rom", "rb"); + if (!f) + break; + romfread(rom + 0xE000, 8192, 1, f); + fclose(f); + if (!mem_load_basic("genxt")) + break; + return 1; - case ROM_ACER386:f = romfopen("acer386/acer386.bin", "rb"); - if (!f) - break; - romfread(rom, 65536, 1, f); - fclose(f); - rom[0xB0] = 0xB0 - 0x51; - rom[0x40d4] = 0x51; /*PUSH CX*/ - f = romfopen("acer386/oti067.bin", "rb"); - if (!f) - break; - fclose(f); - return 1; + case ROM_CBM_PC10: + f = romfopen("cbm_pc10/cbm-pc10c-bios-v4.41-318085-08.bin", "rb"); + if (!f) + break; + romfread(rom + 0x8000, 32768, 1, f); + fclose(f); + return 1; - case ROM_KMXC02:f = romfopen("kmxc02/3ctm005.bin", "rb"); - if (!f) - break; - romfread(rom, 65536, 1, f); - fclose(f); - return 1; + case ROM_SUPER16T: + f = romfopen("huyndaixt/super16t_v1.12ta.bin", "rb"); + if (!f) + break; + romfread(rom + 0xC000, 16384, 1, f); + fclose(f); + return 1; - case ROM_AMI286:f = romfopen("ami286/amic206.bin", "rb"); - if (!f) - break; - romfread(rom, 65536, 1, f); - fclose(f); -// memset(romext,0x63,0x8000); - return 1; + case ROM_SUPER16TE: + f = romfopen("huyndaixte/super16te_v2.00id.bin", "rb"); + if (!f) + break; + romfread(rom + 0xC000, 16384, 1, f); + fclose(f); + return 1; - case ROM_TG286M:f = romfopen("tg286m/ami.bin", "rb"); - if (!f) - break; - romfread(rom, 65536, 1, f); - fclose(f); -// memset(romext,0x63,0x8000); - return 1; + case ROM_DTKXT: + f = romfopen("dtk/dtk_erso_2.42_2764.bin", "rb"); + if (!f) + break; + romfread(rom + 0xE000, 8192, 1, f); + fclose(f); + return 1; + case ROM_OLIM24: + f = romfopen("olivetti_m24/olivetti_m24_version_1.43_low.bin", "rb"); + ff = romfopen("olivetti_m24/olivetti_m24_version_1.43_high.bin", "rb"); + if (!f || !ff) + break; + for (c = 0x0000; c < 0x4000; c += 2) { + rom[c + 0xc000] = getc(f); + rom[c + 0xc001] = getc(ff); + } + fclose(ff); + fclose(f); + return 1; - case ROM_AWARD286:f = romfopen("award286/award.bin", "rb"); - if (!f) - break; - romfread(rom, 65536, 1, f); - fclose(f); - return 1; + case ROM_PC2086: + f = romfopen("pc2086/40179.ic129", "rb"); + ff = romfopen("pc2086/40180.ic132", "rb"); + if (!f || !ff) + break; + pclog("Loading BIOS\n"); + for (c = 0x0000; c < 0x4000; c += 2) { + rom[c + 0x0000] = getc(f); + rom[c + 0x0001] = getc(ff); + } + pclog("%02X %02X %02X\n", rom[0xfff0], rom[0xfff1], rom[0xfff2]); + fclose(ff); + fclose(f); + f = romfopen("pc2086/40186.ic171", "rb"); + if (!f) + break; + fclose(f); + biosmask = 0x3fff; + return 1; - case ROM_GDC212M:f = romfopen("gdc212m/gdc212m_72h.bin", "rb"); - if (!f) - break; - romfread(rom, 65536, 1, f); - fclose(f); - return 1; + case ROM_PC3086: + f = romfopen("pc3086/fc00.bin", "rb"); + if (!f) + break; + romfread(rom, 0x4000, 1, f); + fclose(f); + f = romfopen("pc3086/c000.bin", "rb"); + if (!f) + break; + fclose(f); + biosmask = 0x3fff; + return 1; - case ROM_HYUNDAI_SUPER286TR:f = romfopen("super286tr/award.bin", "rb"); - if (!f) - break; - romfread(rom, 65536, 1, f); - fclose(f); - return 1; + case ROM_PC5086: + f = romfopen("pc5086/sys_rom.bin", "rb"); + if (!f) + break; + romfread(rom, 65536, 1, f); + fclose(f); + return 1; - case ROM_GW286CT:f = romfopen("gw286ct/2ctc001.bin", "rb"); - if (!f) - break; - romfread(rom, 65536, 1, f); - fclose(f); - return 1; + case ROM_IBMAT: + /* f=romfopen("amic206.bin","rb"); + if (!f) break; + romfread(rom,65536,1,f); + fclose(f); + return 1;*/ + case ROM_IBMAT386: + f = romfopen("ibmat/62x0820.u27", "rb"); + ff = romfopen("ibmat/62x0821.u47", "rb"); + if (!f || !ff) + break; + for (c = 0x0000; c < 0x10000; c += 2) { + rom[c] = getc(f); + rom[c + 1] = getc(ff); + } + fclose(ff); + fclose(f); + return 1; + case ROM_CMDPC30: + f = romfopen("cmdpc30/commodore pc 30 iii even.bin", "rb"); + ff = romfopen("cmdpc30/commodore pc 30 iii odd.bin", "rb"); + if (!f || !ff) + break; + for (c = 0x0000; c < 0x8000; c += 2) { + rom[c] = getc(f); + rom[c + 1] = getc(ff); + } + fclose(ff); + fclose(f); + biosmask = 0x7fff; + return 1; + case ROM_DELL200: + f = romfopen("dells200/dell0.bin", "rb"); + ff = romfopen("dells200/dell1.bin", "rb"); + if (!f || !ff) + break; + for (c = 0x0000; c < 0x10000; c += 2) { + rom[c] = getc(f); + rom[c + 1] = getc(ff); + } + fclose(ff); + fclose(f); + return 1; + /* case ROM_IBMAT386: + f=romfopen("at386/at386.bin","rb"); + if (!f) break; + romfread(rom,65536,1,f); + fclose(f); + return 1;*/ + case ROM_AMA932J: + // f=romfopen("at386/at386.bin","rb"); + f = romfopen("ama932j/ami.bin", "rb"); + if (!f) + break; + romfread(rom, 65536, 1, f); + fclose(f); + f = romfopen("ama932j/oti067.bin", "rb"); + if (!f) + break; + fclose(f); + return 1; - case ROM_SPC4200P:f = romfopen("spc4200p/u8.01", "rb"); - if (!f) - break; - romfread(rom, 65536, 1, f); - fclose(f); - return 1; + case ROM_AMI386SX: + // f=romfopen("at386/at386.bin","rb"); + f = romfopen("ami386/ami386.bin", "rb"); + if (!f) + break; + romfread(rom, 65536, 1, f); + fclose(f); + return 1; - case ROM_SPC4216P:f = romfopen("spc4216p/phoenix.bin", "rb"); - if (!f) { - f = romfopen("spc4216p/7101.u8", "rb"); - ff = romfopen("spc4216p/ac64.u10", "rb"); - if (!f || !ff) - break; - for (c = 0x0000; c < 0x10000; c += 2) { - rom[c] = getc(f); - rom[c + 1] = getc(ff); - } - fclose(ff); - fclose(f); - return 1; - } else { - romfread(rom, 65536, 1, f); + case ROM_AMI386DX_OPTI495: /*This uses the OPTi 82C495 chipset*/ + f = romfopen("ami386dx/opt495sx.ami", "rb"); + if (!f) + break; + romfread(rom, 65536, 1, f); + fclose(f); + return 1; + case ROM_MR386DX_OPTI495: /*This uses the OPTi 82C495 chipset*/ + f = romfopen("mr386dx/opt495sx.mr", "rb"); + if (!f) + break; + romfread(rom, 65536, 1, f); + fclose(f); + return 1; - fclose(f); - return 1; - } - break; + case ROM_ACER386: + f = romfopen("acer386/acer386.bin", "rb"); + if (!f) + break; + romfread(rom, 65536, 1, f); + fclose(f); + rom[0xB0] = 0xB0 - 0x51; + rom[0x40d4] = 0x51; /*PUSH CX*/ + f = romfopen("acer386/oti067.bin", "rb"); + if (!f) + break; + fclose(f); + return 1; - case ROM_SPC4620P:f = romfopen("spc4620p/svb6120a_font.rom", "rb"); - if (!f) - break; - fclose(f); - f = romfopen("spc4620p/31005h.u8", "rb"); - ff = romfopen("spc4620p/31005h.u10", "rb"); - if (f && ff) { - fseek(f, 0x8000, SEEK_SET); - fseek(ff, 0x8000, SEEK_SET); - for (c = 0x0000; c < 0x10000; c += 2) { - rom[c] = getc(f); - rom[c + 1] = getc(ff); - } - fclose(ff); - fclose(f); - return 1; - } - break; + case ROM_KMXC02: + f = romfopen("kmxc02/3ctm005.bin", "rb"); + if (!f) + break; + romfread(rom, 65536, 1, f); + fclose(f); + return 1; - case ROM_SPC6000A:f = romfopen("spc6000a/3c80.u27", "rb"); - ff = romfopen("spc6000a/9f80.u26", "rb"); - if (f && ff) { - for (c = 0x8000; c < 0x10000; c += 2) { - rom[c] = getc(f); - rom[c + 1] = getc(ff); - } - fclose(ff); - fclose(f); - return 1; - } - break; + case ROM_AMI286: + f = romfopen("ami286/amic206.bin", "rb"); + if (!f) + break; + romfread(rom, 65536, 1, f); + fclose(f); + // memset(romext,0x63,0x8000); + return 1; - case ROM_SPC6033P:f = romfopen("spc6033p/svb6120a_font.rom", "rb"); - if (!f) - break; - fclose(f); - f = romfopen("spc6033p/phoenix.bin", "rb"); - if (f) { - fseek(f, 0x10000, SEEK_SET); - romfread(rom, 65536, 1, f); + case ROM_TG286M: + f = romfopen("tg286m/ami.bin", "rb"); + if (!f) + break; + romfread(rom, 65536, 1, f); + fclose(f); + // memset(romext,0x63,0x8000); + return 1; - fclose(f); - return 1; - } - break; + case ROM_AWARD286: + f = romfopen("award286/award.bin", "rb"); + if (!f) + break; + romfread(rom, 65536, 1, f); + fclose(f); + return 1; - case ROM_EUROPC: -// return 0; - f = romfopen("europc/50145", "rb"); - if (!f) - break; - romfread(rom + 0x8000, 32768, 1, f); - fclose(f); -// memset(romext,0x63,0x8000); - return 1; + case ROM_GDC212M: + f = romfopen("gdc212m/gdc212m_72h.bin", "rb"); + if (!f) + break; + romfread(rom, 65536, 1, f); + fclose(f); + return 1; - case ROM_IBMPC:f = romfopen("ibmpc/pc102782.bin", "rb"); - if (!f) - break; -// f=fopen("pc081682.bin","rb"); - romfread(rom + 0xE000, 8192, 1, f); - fclose(f); - if (!mem_load_basic("ibmpc")) - break; - return 1; + case ROM_HYUNDAI_SUPER286TR: + f = romfopen("super286tr/award.bin", "rb"); + if (!f) + break; + romfread(rom, 65536, 1, f); + fclose(f); + return 1; - case ROM_MEGAPC:f = romfopen("megapc/41651-bios lo.u18", "rb"); - ff = romfopen("megapc/211253-bios hi.u19", "rb"); - if (!f || !ff) - break; - fseek(f, 0x8000, SEEK_SET); - fseek(ff, 0x8000, SEEK_SET); - for (c = 0x0000; c < 0x10000; c += 2) { - rom[c] = getc(f); - rom[c + 1] = getc(ff); - } - fclose(ff); - fclose(f); - return 1; + case ROM_GW286CT: + f = romfopen("gw286ct/2ctc001.bin", "rb"); + if (!f) + break; + romfread(rom, 65536, 1, f); + fclose(f); + return 1; - case ROM_AMI486:f = romfopen("ami486/ami486.bin", "rb"); - if (!f) - break; - romfread(rom, 65536, 1, f); - fclose(f); - //is486=1; - return 1; + case ROM_SPC4200P: + f = romfopen("spc4200p/u8.01", "rb"); + if (!f) + break; + romfread(rom, 65536, 1, f); + fclose(f); + return 1; - case ROM_WIN486: -// f=romfopen("win486/win486.bin","rb"); - f = romfopen("win486/ali1429g.amw", "rb"); - if (!f) - break; - romfread(rom, 65536, 1, f); - fclose(f); - //is486=1; - return 1; + case ROM_SPC4216P: + f = romfopen("spc4216p/phoenix.bin", "rb"); + if (!f) { + f = romfopen("spc4216p/7101.u8", "rb"); + ff = romfopen("spc4216p/ac64.u10", "rb"); + if (!f || !ff) + break; + for (c = 0x0000; c < 0x10000; c += 2) { + rom[c] = getc(f); + rom[c + 1] = getc(ff); + } + fclose(ff); + fclose(f); + return 1; + } else { + romfread(rom, 65536, 1, f); - case ROM_PCI486:f = romfopen("hot-433/hot-433.ami", "rb"); - if (!f) - break; - romfread(rom, 0x20000, 1, f); - fclose(f); - biosmask = 0x1ffff; - //is486=1; - return 1; + fclose(f); + return 1; + } + break; - case ROM_SIS496:f = romfopen("sis496/sis496-1.awa", "rb"); - if (!f) - break; - romfread(rom, 0x20000, 1, f); - fclose(f); - biosmask = 0x1ffff; - pclog("Load SIS496 %x %x\n", rom[0x1fff0], rom[0xfff0]); - return 1; + case ROM_SPC4620P: + f = romfopen("spc4620p/svb6120a_font.rom", "rb"); + if (!f) + break; + fclose(f); + f = romfopen("spc4620p/31005h.u8", "rb"); + ff = romfopen("spc4620p/31005h.u10", "rb"); + if (f && ff) { + fseek(f, 0x8000, SEEK_SET); + fseek(ff, 0x8000, SEEK_SET); + for (c = 0x0000; c < 0x10000; c += 2) { + rom[c] = getc(f); + rom[c + 1] = getc(ff); + } + fclose(ff); + fclose(f); + return 1; + } + break; - case ROM_P55VA:f = romfopen("p55va/va021297.bin", "rb"); - if (!f) - break; - romfread(rom, 0x20000, 1, f); - fclose(f); - biosmask = 0x1ffff; - return 1; + case ROM_SPC6000A: + f = romfopen("spc6000a/3c80.u27", "rb"); + ff = romfopen("spc6000a/9f80.u26", "rb"); + if (f && ff) { + for (c = 0x8000; c < 0x10000; c += 2) { + rom[c] = getc(f); + rom[c + 1] = getc(ff); + } + fclose(ff); + fclose(f); + return 1; + } + break; - case ROM_P55TVP4:f = romfopen("p55tvp4/tv5i0204.awd", "rb"); - if (!f) - break; - romfread(rom, 0x20000, 1, f); - fclose(f); - biosmask = 0x1ffff; - return 1; + case ROM_SPC6033P: + f = romfopen("spc6033p/svb6120a_font.rom", "rb"); + if (!f) + break; + fclose(f); + f = romfopen("spc6033p/phoenix.bin", "rb"); + if (f) { + fseek(f, 0x10000, SEEK_SET); + romfread(rom, 65536, 1, f); - case ROM_430VX: -// f = romfopen("430vx/ga586atv.bin", "rb"); -// f = fopen("430vx/vx29.bin", "rb"); - f = romfopen("430vx/55xwuq0e.bin", "rb"); -// f=romfopen("430vx/430vx","rb"); - if (!f) - break; - romfread(rom, 0x20000, 1, f); - fclose(f); - biosmask = 0x1ffff; - //is486=1; - return 1; + fclose(f); + return 1; + } + break; - case ROM_P55T2P4:f = romfopen("p55t2p4/0207_j2.bin", "rb"); - if (!f) - break; - romfread(rom, 0x20000, 1, f); - fclose(f); - biosmask = 0x1ffff; - return 1; + case ROM_EUROPC: + // return 0; + f = romfopen("europc/50145", "rb"); + if (!f) + break; + romfread(rom + 0x8000, 32768, 1, f); + fclose(f); + // memset(romext,0x63,0x8000); + return 1; - case ROM_REVENGE:f = romfopen("revenge/1009af2_.bio", "rb"); - if (!f) - break; - fseek(f, 0x80, SEEK_SET); - romfread(rom + 0x10000, 0x10000, 1, f); - fclose(f); - f = romfopen("revenge/1009af2_.bi1", "rb"); - if (!f) - break; - fseek(f, 0x80, SEEK_SET); - romfread(rom, 0xc000, 1, f); - fclose(f); - biosmask = 0x1ffff; - //is486=1; - return 1; - case ROM_ENDEAVOR:f = romfopen("endeavor/1006cb0_.bio", "rb"); - if (!f) - break; - fseek(f, 0x80, SEEK_SET); - romfread(rom + 0x10000, 0x10000, 1, f); - fclose(f); - f = romfopen("endeavor/1006cb0_.bi1", "rb"); - if (!f) - break; - fseek(f, 0x80, SEEK_SET); - romfread(rom, 0xd000, 1, f); - fclose(f); - biosmask = 0x1ffff; - //is486=1; - return 1; + case ROM_IBMPC: + f = romfopen("ibmpc/pc102782.bin", "rb"); + if (!f) + break; + // f=fopen("pc081682.bin","rb"); + romfread(rom + 0xE000, 8192, 1, f); + fclose(f); + if (!mem_load_basic("ibmpc")) + break; + return 1; - case ROM_IBMPS1_2011: + case ROM_MEGAPC: + f = romfopen("megapc/41651-bios lo.u18", "rb"); + ff = romfopen("megapc/211253-bios hi.u19", "rb"); + if (!f || !ff) + break; + fseek(f, 0x8000, SEEK_SET); + fseek(ff, 0x8000, SEEK_SET); + for (c = 0x0000; c < 0x10000; c += 2) { + rom[c] = getc(f); + rom[c + 1] = getc(ff); + } + fclose(ff); + fclose(f); + return 1; + + case ROM_AMI486: + f = romfopen("ami486/ami486.bin", "rb"); + if (!f) + break; + romfread(rom, 65536, 1, f); + fclose(f); + // is486=1; + return 1; + + case ROM_WIN486: + // f=romfopen("win486/win486.bin","rb"); + f = romfopen("win486/ali1429g.amw", "rb"); + if (!f) + break; + romfread(rom, 65536, 1, f); + fclose(f); + // is486=1; + return 1; + + case ROM_PCI486: + f = romfopen("hot-433/hot-433.ami", "rb"); + if (!f) + break; + romfread(rom, 0x20000, 1, f); + fclose(f); + biosmask = 0x1ffff; + // is486=1; + return 1; + + case ROM_SIS496: + f = romfopen("sis496/sis496-1.awa", "rb"); + if (!f) + break; + romfread(rom, 0x20000, 1, f); + fclose(f); + biosmask = 0x1ffff; + pclog("Load SIS496 %x %x\n", rom[0x1fff0], rom[0xfff0]); + return 1; + + case ROM_P55VA: + f = romfopen("p55va/va021297.bin", "rb"); + if (!f) + break; + romfread(rom, 0x20000, 1, f); + fclose(f); + biosmask = 0x1ffff; + return 1; + + case ROM_P55TVP4: + f = romfopen("p55tvp4/tv5i0204.awd", "rb"); + if (!f) + break; + romfread(rom, 0x20000, 1, f); + fclose(f); + biosmask = 0x1ffff; + return 1; + + case ROM_430VX: + // f = romfopen("430vx/ga586atv.bin", "rb"); + // f = fopen("430vx/vx29.bin", "rb"); + f = romfopen("430vx/55xwuq0e.bin", "rb"); + // f=romfopen("430vx/430vx","rb"); + if (!f) + break; + romfread(rom, 0x20000, 1, f); + fclose(f); + biosmask = 0x1ffff; + // is486=1; + return 1; + + case ROM_P55T2P4: + f = romfopen("p55t2p4/0207_j2.bin", "rb"); + if (!f) + break; + romfread(rom, 0x20000, 1, f); + fclose(f); + biosmask = 0x1ffff; + return 1; + + case ROM_REVENGE: + f = romfopen("revenge/1009af2_.bio", "rb"); + if (!f) + break; + fseek(f, 0x80, SEEK_SET); + romfread(rom + 0x10000, 0x10000, 1, f); + fclose(f); + f = romfopen("revenge/1009af2_.bi1", "rb"); + if (!f) + break; + fseek(f, 0x80, SEEK_SET); + romfread(rom, 0xc000, 1, f); + fclose(f); + biosmask = 0x1ffff; + // is486=1; + return 1; + case ROM_ENDEAVOR: + f = romfopen("endeavor/1006cb0_.bio", "rb"); + if (!f) + break; + fseek(f, 0x80, SEEK_SET); + romfread(rom + 0x10000, 0x10000, 1, f); + fclose(f); + f = romfopen("endeavor/1006cb0_.bi1", "rb"); + if (!f) + break; + fseek(f, 0x80, SEEK_SET); + romfread(rom, 0xd000, 1, f); + fclose(f); + biosmask = 0x1ffff; + // is486=1; + return 1; + + case ROM_IBMPS1_2011: #if 0 f=romfopen("ibmps1es/ibm_1057757_24-05-90.bin","rb"); ff=romfopen("ibmps1es/ibm_1057757_29-15-90.bin","rb"); @@ -641,554 +685,593 @@ int loadbios() { fclose(ff); fclose(f); #endif -//#if 0 - f = romfopen("ibmps1es/f80000.bin", "rb"); - if (!f) - break; - fseek(f, 0x60000, SEEK_SET); - romfread(rom, 0x20000, 1, f); - fclose(f); -//#endif - biosmask = 0x1ffff; - return 1; + //#if 0 + f = romfopen("ibmps1es/f80000.bin", "rb"); + if (!f) + break; + fseek(f, 0x60000, SEEK_SET); + romfread(rom, 0x20000, 1, f); + fclose(f); + //#endif + biosmask = 0x1ffff; + return 1; - case ROM_IBMPS1_2121:f = romfopen("ibmps1_2121/fc0000.bin", "rb"); - if (!f) - break; - fseek(f, 0x20000, SEEK_SET); - romfread(rom, 0x20000, 1, f); - fclose(f); - biosmask = 0x1ffff; - return 1; + case ROM_IBMPS1_2121: + f = romfopen("ibmps1_2121/fc0000.bin", "rb"); + if (!f) + break; + fseek(f, 0x20000, SEEK_SET); + romfread(rom, 0x20000, 1, f); + fclose(f); + biosmask = 0x1ffff; + return 1; - case ROM_DESKPRO_386:f = romfopen("deskpro386/109592-005.u11.bin", "rb"); - ff = romfopen("deskpro386/109591-005.u13.bin", "rb"); - if (!f || !ff) - break; - for (c = 0x0000; c < 0x8000; c += 2) { - rom[c] = getc(f); - rom[c + 1] = getc(ff); - } - fclose(ff); - fclose(f); - biosmask = 0x7fff; - return 1; + case ROM_DESKPRO_386: + f = romfopen("deskpro386/109592-005.u11.bin", "rb"); + ff = romfopen("deskpro386/109591-005.u13.bin", "rb"); + if (!f || !ff) + break; + for (c = 0x0000; c < 0x8000; c += 2) { + rom[c] = getc(f); + rom[c + 1] = getc(ff); + } + fclose(ff); + fclose(f); + biosmask = 0x7fff; + return 1; - case ROM_AMIXT:f = romfopen("amixt/ami_8088_bios_31jan89.bin", "rb"); - if (!f) - break; - romfread(rom + 0xE000, 8192, 1, f); - fclose(f); - return 1; + case ROM_AMIXT: + f = romfopen("amixt/ami_8088_bios_31jan89.bin", "rb"); + if (!f) + break; + romfread(rom + 0xE000, 8192, 1, f); + fclose(f); + return 1; - case ROM_LTXT:f = romfopen("ltxt/27c64.bin", "rb"); - if (!f) - break; - romfread(rom + 0xE000, 8192, 1, f); - fclose(f); - if (!mem_load_basic("ltxt")) - break; - return 1; + case ROM_LTXT: + f = romfopen("ltxt/27c64.bin", "rb"); + if (!f) + break; + romfread(rom + 0xE000, 8192, 1, f); + fclose(f); + if (!mem_load_basic("ltxt")) + break; + return 1; - case ROM_LXT3:f = romfopen("lxt3/27c64d.bin", "rb"); - if (!f) - break; - romfread(rom + 0xE000, 8192, 1, f); - fclose(f); - if (!mem_load_basic("lxt3")) - break; - return 1; + case ROM_LXT3: + f = romfopen("lxt3/27c64d.bin", "rb"); + if (!f) + break; + romfread(rom + 0xE000, 8192, 1, f); + fclose(f); + if (!mem_load_basic("lxt3")) + break; + return 1; - case ROM_PX386: /*Phoenix 80386 BIOS*/ - f = romfopen("px386/3iip001l.bin", "rb"); - ff = romfopen("px386/3iip001h.bin", "rb"); - if (!f || !ff) - break; - for (c = 0x0000; c < 0x10000; c += 2) { - rom[c] = getc(f); - rom[c + 1] = getc(ff); - } - fclose(ff); - fclose(f); - return 1; + case ROM_PX386: /*Phoenix 80386 BIOS*/ + f = romfopen("px386/3iip001l.bin", "rb"); + ff = romfopen("px386/3iip001h.bin", "rb"); + if (!f || !ff) + break; + for (c = 0x0000; c < 0x10000; c += 2) { + rom[c] = getc(f); + rom[c + 1] = getc(ff); + } + fclose(ff); + fclose(f); + return 1; - case ROM_DTK386: /*Uses NEAT chipset*/ - f = romfopen("dtk386/3cto001.bin", "rb"); - if (!f) - break; - romfread(rom, 65536, 1, f); - fclose(f); - return 1; + case ROM_DTK386: /*Uses NEAT chipset*/ + f = romfopen("dtk386/3cto001.bin", "rb"); + if (!f) + break; + romfread(rom, 65536, 1, f); + fclose(f); + return 1; - case ROM_PXXT:f = romfopen("pxxt/000p001.bin", "rb"); - if (!f) - break; - romfread(rom + 0xE000, 8192, 1, f); - fclose(f); - return 1; + case ROM_PXXT: + f = romfopen("pxxt/000p001.bin", "rb"); + if (!f) + break; + romfread(rom + 0xE000, 8192, 1, f); + fclose(f); + return 1; - case ROM_JUKOPC:f = romfopen("jukopc/000o001.bin", "rb"); - if (!f) - break; - romfread(rom + 0xE000, 8192, 1, f); - fclose(f); - return 1; + case ROM_JUKOPC: + f = romfopen("jukopc/000o001.bin", "rb"); + if (!f) + break; + romfread(rom + 0xE000, 8192, 1, f); + fclose(f); + return 1; - case ROM_IBMPS2_M30_286:f = romfopen("ibmps2_m30_286/33f5381a.bin", "rb"); - if (!f) - break; - romfread(rom, 0x20000, 1, f); - fclose(f); - biosmask = 0x1ffff; - return 1; + case ROM_IBMPS2_M30_286: + f = romfopen("ibmps2_m30_286/33f5381a.bin", "rb"); + if (!f) + break; + romfread(rom, 0x20000, 1, f); + fclose(f); + biosmask = 0x1ffff; + return 1; - case ROM_IBMPS2_M50:f = romfopen("i8550021/90x7423.zm14", "rb"); - ff = romfopen("i8550021/90x7426.zm16", "rb"); - if (!f || !ff) - break; - for (c = 0x0000; c < 0x10000; c += 2) { - rom[c] = getc(f); - rom[c + 1] = getc(ff); - } - fclose(ff); - fclose(f); - f = romfopen("i8550021/90x7420.zm13", "rb"); - ff = romfopen("i8550021/90x7429.zm18", "rb"); - if (!f || !ff) - break; - for (c = 0x10000; c < 0x20000; c += 2) { - rom[c] = getc(f); - rom[c + 1] = getc(ff); - } - fclose(ff); - fclose(f); - biosmask = 0x1ffff; - return 1; + case ROM_IBMPS2_M50: + f = romfopen("i8550021/90x7423.zm14", "rb"); + ff = romfopen("i8550021/90x7426.zm16", "rb"); + if (!f || !ff) + break; + for (c = 0x0000; c < 0x10000; c += 2) { + rom[c] = getc(f); + rom[c + 1] = getc(ff); + } + fclose(ff); + fclose(f); + f = romfopen("i8550021/90x7420.zm13", "rb"); + ff = romfopen("i8550021/90x7429.zm18", "rb"); + if (!f || !ff) + break; + for (c = 0x10000; c < 0x20000; c += 2) { + rom[c] = getc(f); + rom[c + 1] = getc(ff); + } + fclose(ff); + fclose(f); + biosmask = 0x1ffff; + return 1; - case ROM_IBMPS2_M55SX:f = romfopen("i8555081/33f8146.zm41", "rb"); - ff = romfopen("i8555081/33f8145.zm40", "rb"); - if (!f || !ff) - break; - for (c = 0x0000; c < 0x20000; c += 2) { - rom[c] = getc(f); - rom[c + 1] = getc(ff); - } - fclose(ff); - fclose(f); - biosmask = 0x1ffff; - return 1; + case ROM_IBMPS2_M55SX: + f = romfopen("i8555081/33f8146.zm41", "rb"); + ff = romfopen("i8555081/33f8145.zm40", "rb"); + if (!f || !ff) + break; + for (c = 0x0000; c < 0x20000; c += 2) { + rom[c] = getc(f); + rom[c + 1] = getc(ff); + } + fclose(ff); + fclose(f); + biosmask = 0x1ffff; + return 1; - case ROM_IBMPS2_M80:f = romfopen("i8580111/15f6637.bin", "rb"); - ff = romfopen("i8580111/15f6639.bin", "rb"); - if (!f || !ff) - break; - for (c = 0x0000; c < 0x20000; c += 2) { - rom[c] = getc(f); - rom[c + 1] = getc(ff); - } - fclose(ff); - fclose(f); - biosmask = 0x1ffff; - return 1; + case ROM_IBMPS2_M80: + f = romfopen("i8580111/15f6637.bin", "rb"); + ff = romfopen("i8580111/15f6639.bin", "rb"); + if (!f || !ff) + break; + for (c = 0x0000; c < 0x20000; c += 2) { + rom[c] = getc(f); + rom[c + 1] = getc(ff); + } + fclose(ff); + fclose(f); + biosmask = 0x1ffff; + return 1; - case ROM_ATARIPC3:f = romfopen("ataripc3/AWARD_ATARI_PC_BIOS_3.08.BIN", "rb"); - if (!f) - break; - romfread(rom + 0x8000, 32768, 1, f); - fclose(f); - return 1; + case ROM_ATARIPC3: + f = romfopen("ataripc3/AWARD_ATARI_PC_BIOS_3.08.BIN", "rb"); + if (!f) + break; + romfread(rom + 0x8000, 32768, 1, f); + fclose(f); + return 1; - case ROM_IBMXT286:f = romfopen("ibmxt286/BIOS_5162_21APR86_U34_78X7460_27256.BIN", "rb"); - ff = romfopen("ibmxt286/BIOS_5162_21APR86_U35_78X7461_27256.BIN", "rb"); - if (!f || !ff) - break; - for (c = 0x0000; c < 0x10000; c += 2) { - rom[c] = getc(f); - rom[c + 1] = getc(ff); - } - fclose(ff); - fclose(f); - return 1; + case ROM_IBMXT286: + f = romfopen("ibmxt286/BIOS_5162_21APR86_U34_78X7460_27256.BIN", "rb"); + ff = romfopen("ibmxt286/BIOS_5162_21APR86_U35_78X7461_27256.BIN", "rb"); + if (!f || !ff) + break; + for (c = 0x0000; c < 0x10000; c += 2) { + rom[c] = getc(f); + rom[c + 1] = getc(ff); + } + fclose(ff); + fclose(f); + return 1; - case ROM_EPSON_PCAX:f = romfopen("epson_pcax/EVAX", "rb"); - ff = romfopen("epson_pcax/ODAX", "rb"); - if (!f || !ff) - break; - for (c = 0x0000; c < 0x8000; c += 2) { - rom[c] = getc(f); - rom[c + 1] = getc(ff); - } - fclose(ff); - fclose(f); - biosmask = 0x7fff; - return 1; + case ROM_EPSON_PCAX: + f = romfopen("epson_pcax/EVAX", "rb"); + ff = romfopen("epson_pcax/ODAX", "rb"); + if (!f || !ff) + break; + for (c = 0x0000; c < 0x8000; c += 2) { + rom[c] = getc(f); + rom[c + 1] = getc(ff); + } + fclose(ff); + fclose(f); + biosmask = 0x7fff; + return 1; - case ROM_EPSON_PCAX2E:f = romfopen("epson_pcax2e/EVAXE", "rb"); - ff = romfopen("epson_pcax2e/ODAXE", "rb"); - if (!f || !ff) - break; - for (c = 0x0000; c < 0x10000; c += 2) { - rom[c] = getc(f); - rom[c + 1] = getc(ff); - } - fclose(ff); - fclose(f); - return 1; + case ROM_EPSON_PCAX2E: + f = romfopen("epson_pcax2e/EVAXE", "rb"); + ff = romfopen("epson_pcax2e/ODAXE", "rb"); + if (!f || !ff) + break; + for (c = 0x0000; c < 0x10000; c += 2) { + rom[c] = getc(f); + rom[c + 1] = getc(ff); + } + fclose(ff); + fclose(f); + return 1; - case ROM_EPSON_PCAX3:f = romfopen("epson_pcax3/EVAX3", "rb"); - ff = romfopen("epson_pcax3/ODAX3", "rb"); - if (!f || !ff) - break; - for (c = 0x0000; c < 0x10000; c += 2) { - rom[c] = getc(f); - rom[c + 1] = getc(ff); - } - fclose(ff); - fclose(f); - return 1; + case ROM_EPSON_PCAX3: + f = romfopen("epson_pcax3/EVAX3", "rb"); + ff = romfopen("epson_pcax3/ODAX3", "rb"); + if (!f || !ff) + break; + for (c = 0x0000; c < 0x10000; c += 2) { + rom[c] = getc(f); + rom[c + 1] = getc(ff); + } + fclose(ff); + fclose(f); + return 1; - case ROM_T3100E:loadfont("t3100e/t3100e_font.bin", FONT_T3100E); - f = romfopen("t3100e/t3100e.rom", "rb"); - if (!f) - break; - romfread(rom, 65536, 1, f); - fclose(f); - return 1; + case ROM_T3100E: + loadfont("t3100e/t3100e_font.bin", FONT_T3100E); + f = romfopen("t3100e/t3100e.rom", "rb"); + if (!f) + break; + romfread(rom, 65536, 1, f); + fclose(f); + return 1; - case ROM_T1000:loadfont("t1000/t1000font.rom", FONT_CGA); - f = romfopen("t1000/t1000.rom", "rb"); - if (!f) - break; - romfread(rom, 0x8000, 1, f); - memcpy(rom + 0x8000, rom, 0x8000); - biosmask = 0x7fff; - fclose(f); - return 1; + case ROM_T1000: + loadfont("t1000/t1000font.rom", FONT_CGA); + f = romfopen("t1000/t1000.rom", "rb"); + if (!f) + break; + romfread(rom, 0x8000, 1, f); + memcpy(rom + 0x8000, rom, 0x8000); + biosmask = 0x7fff; + fclose(f); + return 1; - case ROM_T1200:loadfont("t1200/t1000font.rom", FONT_CGA); - f = romfopen("t1200/t1200_019e.ic15.bin", "rb"); - if (!f) - break; - romfread(rom, 0x8000, 1, f); - memcpy(rom + 0x8000, rom, 0x8000); - biosmask = 0x7fff; - fclose(f); - return 1; + case ROM_T1200: + loadfont("t1200/t1000font.rom", FONT_CGA); + f = romfopen("t1200/t1200_019e.ic15.bin", "rb"); + if (!f) + break; + romfread(rom, 0x8000, 1, f); + memcpy(rom + 0x8000, rom, 0x8000); + biosmask = 0x7fff; + fclose(f); + return 1; - case ROM_PB_L300SX:f = romfopen("pb_l300sx/pb_l300sx.bin", "rb"); - if (!f) - break; - romfread(rom, 65536, 1, f); - fclose(f); - return 1; + case ROM_PB_L300SX: + f = romfopen("pb_l300sx/pb_l300sx.bin", "rb"); + if (!f) + break; + romfread(rom, 65536, 1, f); + fclose(f); + return 1; - case ROM_NCR_PC4I:f = romfopen("ncr_pc4i/NCR_PC4i_BIOSROM_1985.BIN", "rb"); - if (!f) - break; - romfread(rom, 0x4000, 1, f); - fclose(f); - biosmask = 0x3fff; - return 1; + case ROM_NCR_PC4I: + f = romfopen("ncr_pc4i/NCR_PC4i_BIOSROM_1985.BIN", "rb"); + if (!f) + break; + romfread(rom, 0x4000, 1, f); + fclose(f); + biosmask = 0x3fff; + return 1; - case ROM_TO16_PC:f = romfopen("to16_pc/TO16_103.bin", "rb"); - if (!f) - break; - romfread(rom + 0x8000, 32768, 1, f); - fclose(f); - return 1; + case ROM_TO16_PC: + f = romfopen("to16_pc/TO16_103.bin", "rb"); + if (!f) + break; + romfread(rom + 0x8000, 32768, 1, f); + fclose(f); + return 1; - case ROM_COMPAQ_PII:f = romfopen("compaq_pii/109740-001.rom", "rb"); - ff = romfopen("compaq_pii/109739-001.rom", "rb"); - if (!f || !ff) - break; - for (c = 0x0000; c < 0x8000; c += 2) { - rom[c] = getc(f); - rom[c + 1] = getc(ff); - } - fclose(ff); - fclose(f); - biosmask = 0x7fff; - return 1; + case ROM_COMPAQ_PII: + f = romfopen("compaq_pii/109740-001.rom", "rb"); + ff = romfopen("compaq_pii/109739-001.rom", "rb"); + if (!f || !ff) + break; + for (c = 0x0000; c < 0x8000; c += 2) { + rom[c] = getc(f); + rom[c + 1] = getc(ff); + } + fclose(ff); + fclose(f); + biosmask = 0x7fff; + return 1; - case ROM_ELX_PC425X: - /*PC-425X uses a single ROM chip containing both main and video BIOSes. - First 32kb is video BIOS, next 32kb is blank, last 64kb is main BIOS. - Alternatively, seperate BIOS + video BIOS dumps are supported.*/ - f = romfopen("elx_pc425x/elx_pc425x.bin", "rb"); - if (!f) { - if (!rom_present("elx_pc425x/elx_pc425x_vbios.bin")) - break; - f = romfopen("elx_pc425x/elx_pc425x_bios.bin", "rb"); - if (!f) - break; - } else - fseek(f, 0x10000, SEEK_SET); - romfread(rom, 65536, 1, f); - fclose(f); - return 1; + case ROM_ELX_PC425X: + /*PC-425X uses a single ROM chip containing both main and video BIOSes. + First 32kb is video BIOS, next 32kb is blank, last 64kb is main BIOS. + Alternatively, seperate BIOS + video BIOS dumps are supported.*/ + f = romfopen("elx_pc425x/elx_pc425x.bin", "rb"); + if (!f) { + if (!rom_present("elx_pc425x/elx_pc425x_vbios.bin")) + break; + f = romfopen("elx_pc425x/elx_pc425x_bios.bin", "rb"); + if (!f) + break; + } else + fseek(f, 0x10000, SEEK_SET); + romfread(rom, 65536, 1, f); + fclose(f); + return 1; - case ROM_PB570: - if (!rom_present("pb570/gd5430.bin")) - break; - f = romfopen("pb570/1007by0r.bio", "rb"); - if (!f) - break; - fseek(f, 0x80, SEEK_SET); - romfread(rom + 0x10000, 0x10000, 1, f); - fclose(f); - f = romfopen("pb570/1007by0r.bi1", "rb"); - if (!f) - break; - fseek(f, 0x80, SEEK_SET); - romfread(rom, 0xc000, 1, f); - romfread(rom + 0xc000, 0x1000, 1, f); - fclose(f); - biosmask = 0x1ffff; - return 1; + case ROM_PB570: + if (!rom_present("pb570/gd5430.bin")) + break; + f = romfopen("pb570/1007by0r.bio", "rb"); + if (!f) + break; + fseek(f, 0x80, SEEK_SET); + romfread(rom + 0x10000, 0x10000, 1, f); + fclose(f); + f = romfopen("pb570/1007by0r.bi1", "rb"); + if (!f) + break; + fseek(f, 0x80, SEEK_SET); + romfread(rom, 0xc000, 1, f); + romfread(rom + 0xc000, 0x1000, 1, f); + fclose(f); + biosmask = 0x1ffff; + return 1; - case ROM_ZAPPA:f = romfopen("zappa/1006bs0_.bio", "rb"); - if (!f) - break; - fseek(f, 0x80, SEEK_SET); - romfread(rom + 0x10000, 0x10000, 1, f); - fclose(f); - f = romfopen("zappa/1006bs0_.bi1", "rb"); - if (!f) - break; - fseek(f, 0x80, SEEK_SET); - romfread(rom, 0xd000, 1, f); - fclose(f); - biosmask = 0x1ffff; - return 1; + case ROM_ZAPPA: + f = romfopen("zappa/1006bs0_.bio", "rb"); + if (!f) + break; + fseek(f, 0x80, SEEK_SET); + romfread(rom + 0x10000, 0x10000, 1, f); + fclose(f); + f = romfopen("zappa/1006bs0_.bi1", "rb"); + if (!f) + break; + fseek(f, 0x80, SEEK_SET); + romfread(rom, 0xd000, 1, f); + fclose(f); + biosmask = 0x1ffff; + return 1; - // keep separate from generic Zappa because there is a BIOS logo - // in flash.bin - case ROM_ITAUTEC_INFOWAYM: -// if (!rom_present("infowaym/gd5434.bin")) -// break; - f = romfopen("infowaym/1006bs0_.bio", "rb"); - if (!f) - break; - fseek(f, 0x80, SEEK_SET); - romfread(rom + 0x10000, 0x10000, 1, f); - fclose(f); - f = romfopen("infowaym/1006bs0_.bi1", "rb"); - if (!f) - break; - fseek(f, 0x80, SEEK_SET); - romfread(rom, 0xd000, 1, f); - fclose(f); - biosmask = 0x1ffff; - return 1; + // keep separate from generic Zappa because there is a BIOS logo + // in flash.bin + case ROM_ITAUTEC_INFOWAYM: + // if (!rom_present("infowaym/gd5434.bin")) + // break; + f = romfopen("infowaym/1006bs0_.bio", "rb"); + if (!f) + break; + fseek(f, 0x80, SEEK_SET); + romfread(rom + 0x10000, 0x10000, 1, f); + fclose(f); + f = romfopen("infowaym/1006bs0_.bi1", "rb"); + if (!f) + break; + fseek(f, 0x80, SEEK_SET); + romfread(rom, 0xd000, 1, f); + fclose(f); + biosmask = 0x1ffff; + return 1; - case ROM_PB520R: - if (!rom_present("pb520r/gd5434.bin")) - break; - f = romfopen("pb520r/1009bc0r.bio", "rb"); - if (!f) - break; - fseek(f, 0x80, SEEK_SET); - romfread(rom + 0x10000, 0x10000, 1, f); - fclose(f); - f = romfopen("pb520r/1009bc0r.bi1", "rb"); - if (!f) - break; - fseek(f, 0x80, SEEK_SET); - romfread(rom, 0xc000, 1, f); - romfread(rom + 0xc000, 0x1000, 1, f); - fclose(f); - biosmask = 0x1ffff; - return 1; + case ROM_PB520R: + if (!rom_present("pb520r/gd5434.bin")) + break; + f = romfopen("pb520r/1009bc0r.bio", "rb"); + if (!f) + break; + fseek(f, 0x80, SEEK_SET); + romfread(rom + 0x10000, 0x10000, 1, f); + fclose(f); + f = romfopen("pb520r/1009bc0r.bi1", "rb"); + if (!f) + break; + fseek(f, 0x80, SEEK_SET); + romfread(rom, 0xc000, 1, f); + romfread(rom + 0xc000, 0x1000, 1, f); + fclose(f); + biosmask = 0x1ffff; + return 1; - case ROM_COMPAQ_PIP:f = romfopen("compaq_pip/Compaq Portable Plus 100666-001 Rev C.bin", "rb"); - if (!f) - break; - romfread(rom + 0xE000, 8192, 1, f); - fclose(f); - return 1; + case ROM_COMPAQ_PIP: + f = romfopen("compaq_pip/Compaq Portable Plus 100666-001 Rev C.bin", "rb"); + if (!f) + break; + romfread(rom + 0xE000, 8192, 1, f); + fclose(f); + return 1; - case ROM_XI8088:f = romfopen("xi8088/bios-xi8088.bin", "rb"); /* use the bios without xt-ide because it's configurable in pcem */ - if (!f) - break; - if (xi8088_bios_128kb()) { - /* high bit is flipped in xi8088 */ - romfread(rom + 0x10000, 0x10000, 1, f); - romfread(rom, 0x10000, 1, f); - biosmask = 0x1ffff; - } else { - /* smaller bios, more UMBs */ - romfread(rom, 0x10000, 1, f); - } - fclose(f); - return 1; + case ROM_XI8088: + f = romfopen("xi8088/bios-xi8088.bin", "rb"); /* use the bios without xt-ide because it's configurable in pcem */ + if (!f) + break; + if (xi8088_bios_128kb()) { + /* high bit is flipped in xi8088 */ + romfread(rom + 0x10000, 0x10000, 1, f); + romfread(rom, 0x10000, 1, f); + biosmask = 0x1ffff; + } else { + /* smaller bios, more UMBs */ + romfread(rom, 0x10000, 1, f); + } + fclose(f); + return 1; - case ROM_IBMPS2_M70_TYPE3:f = romfopen("ibmps2_m70_type3/70-a_even.bin", "rb"); - ff = romfopen("ibmps2_m70_type3/70-a_odd.bin", "rb"); - if (!f || !ff) - break; - for (c = 0x0000; c < 0x20000; c += 2) { - rom[c] = getc(f); - rom[c + 1] = getc(ff); - } - fclose(ff); - fclose(f); - biosmask = 0x1ffff; - return 1; + case ROM_IBMPS2_M70_TYPE3: + f = romfopen("ibmps2_m70_type3/70-a_even.bin", "rb"); + ff = romfopen("ibmps2_m70_type3/70-a_odd.bin", "rb"); + if (!f || !ff) + break; + for (c = 0x0000; c < 0x20000; c += 2) { + rom[c] = getc(f); + rom[c + 1] = getc(ff); + } + fclose(ff); + fclose(f); + biosmask = 0x1ffff; + return 1; - case ROM_IBMPS2_M70_TYPE4:f = romfopen("ibmps2_m70_type4/70-b_even.bin", "rb"); - ff = romfopen("ibmps2_m70_type4/70-b_odd.bin", "rb"); - if (!f || !ff) - break; - for (c = 0x0000; c < 0x20000; c += 2) { - rom[c] = getc(f); - rom[c + 1] = getc(ff); - } - fclose(ff); - fclose(f); - biosmask = 0x1ffff; - return 1; + case ROM_IBMPS2_M70_TYPE4: + f = romfopen("ibmps2_m70_type4/70-b_even.bin", "rb"); + ff = romfopen("ibmps2_m70_type4/70-b_odd.bin", "rb"); + if (!f || !ff) + break; + for (c = 0x0000; c < 0x20000; c += 2) { + rom[c] = getc(f); + rom[c + 1] = getc(ff); + } + fclose(ff); + fclose(f); + biosmask = 0x1ffff; + return 1; - case ROM_TULIP_TC7:f = romfopen("tulip_tc7/tc7be.bin", "rb"); - ff = romfopen("tulip_tc7/tc7bo.bin", "rb"); - if (!f || !ff) - break; - for (c = 0x0000; c < 0x8000; c += 2) { - rom[c] = getc(f); - rom[c + 1] = getc(ff); - } - fclose(ff); - fclose(f); - biosmask = 0x7fff; - return 1; + case ROM_TULIP_TC7: + f = romfopen("tulip_tc7/tc7be.bin", "rb"); + ff = romfopen("tulip_tc7/tc7bo.bin", "rb"); + if (!f || !ff) + break; + for (c = 0x0000; c < 0x8000; c += 2) { + rom[c] = getc(f); + rom[c + 1] = getc(ff); + } + fclose(ff); + fclose(f); + biosmask = 0x7fff; + return 1; - case ROM_ZD_SUPERS: /* [8088] Zenith Data Systems SupersPort */ - f = romfopen("zdsupers/z184m v3.1d.10d", "rb"); - if (!f) - break; - romfread(rom, 32768, 1, f); - fclose(f); - biosmask = 0x7fff; - return 1; + case ROM_ZD_SUPERS: /* [8088] Zenith Data Systems SupersPort */ + f = romfopen("zdsupers/z184m v3.1d.10d", "rb"); + if (!f) + break; + romfread(rom, 32768, 1, f); + fclose(f); + biosmask = 0x7fff; + return 1; - case ROM_PB410A:f = romfopen("pb410a/PB410A.080337.4ABF.U25.bin", "rb"); - if (!f) - break; - romfread(rom, 0x20000, 1, f); - fclose(f); - biosmask = 0x1ffff; - return 1; + case ROM_PB410A: + f = romfopen("pb410a/PB410A.080337.4ABF.U25.bin", "rb"); + if (!f) + break; + romfread(rom, 0x20000, 1, f); + fclose(f); + biosmask = 0x1ffff; + return 1; - case ROM_BULL_MICRAL_45: f = romfopen("bull_micral_45/even.fil", "rb"); - ff = romfopen("bull_micral_45/odd.fil", "rb"); - if (!f || !ff) - break; - for (c = 0x0000; c < 0x10000; c += 2) { - rom[c] = getc(f); - rom[c + 1] = getc(ff); - } - fclose(ff); - fclose(f); - return 1; + case ROM_BULL_MICRAL_45: + f = romfopen("bull_micral_45/even.fil", "rb"); + ff = romfopen("bull_micral_45/odd.fil", "rb"); + if (!f || !ff) + break; + for (c = 0x0000; c < 0x10000; c += 2) { + rom[c] = getc(f); + rom[c + 1] = getc(ff); + } + fclose(ff); + fclose(f); + return 1; - case ROM_FIC_VA503P:f = romfopen("fic_va503p/je4333.bin", "rb"); - if (!f) - break; - romfread(rom, 0x20000, 1, f); - fclose(f); - biosmask = 0x1ffff; - return 1; + case ROM_FIC_VA503P: + f = romfopen("fic_va503p/je4333.bin", "rb"); + if (!f) + break; + romfread(rom, 0x20000, 1, f); + fclose(f); + biosmask = 0x1ffff; + return 1; - case ROM_CBM_SL386SX25:f = romfopen("cbm_sl386sx25/f000.rom", "rb"); - if (!f) - break; - romfread(rom, 0x10000, 1, f); - fclose(f); - return 1; + case ROM_CBM_SL386SX25: + f = romfopen("cbm_sl386sx25/f000.rom", "rb"); + if (!f) + break; + romfread(rom, 0x10000, 1, f); + fclose(f); + return 1; - case ROM_IBMPS1_2133_451:f = romfopen("ibmps1_2133/PS1_2133_52G2974_ROM.bin", "rb"); - if (!f) - break; - romfread(rom, 0x20000, 1, f); - fclose(f); - biosmask = 0x1ffff; - return 1; + case ROM_IBMPS1_2133_451: + f = romfopen("ibmps1_2133/PS1_2133_52G2974_ROM.bin", "rb"); + if (!f) + break; + romfread(rom, 0x20000, 1, f); + fclose(f); + biosmask = 0x1ffff; + return 1; - case ROM_ECS_386_32: f = romfopen("ecs386_32/386_32_even.bin", "rb"); - ff = romfopen("ecs386_32/386_32_odd.bin", "rb"); - if (!f || !ff) - break; - for (c = 0x0000; c < 0x10000; c += 2) { - rom[c] = getc(f); - rom[c + 1] = getc(ff); - } - fclose(ff); - fclose(f); - return 1; + case ROM_ECS_386_32: + f = romfopen("ecs386_32/386_32_even.bin", "rb"); + ff = romfopen("ecs386_32/386_32_odd.bin", "rb"); + if (!f || !ff) + break; + for (c = 0x0000; c < 0x10000; c += 2) { + rom[c] = getc(f); + rom[c + 1] = getc(ff); + } + fclose(ff); + fclose(f); + return 1; - case ROM_LEDGE_MODELM:f = romfopen("leadingedge_modelm/Leading Edge - Model M - BIOS ROM - Version 4.71.bin", "rb"); - if (!f) - break; - romfread(rom, 0x4000, 1, f); - fclose(f); - biosmask = 0x3fff; - return 1; + case ROM_LEDGE_MODELM: + f = romfopen("leadingedge_modelm/Leading Edge - Model M - BIOS ROM - Version 4.71.bin", "rb"); + if (!f) + break; + romfread(rom, 0x4000, 1, f); + fclose(f); + biosmask = 0x3fff; + return 1; - case ROM_DESKPRO:f = romfopen("deskpro/Compaq - BIOS - Revision J - 106265-002.bin", "rb"); - if (!f) - break; - romfread(rom, 0x2000, 1, f); - fclose(f); - biosmask = 0x1fff; - return 1; + case ROM_DESKPRO: + f = romfopen("deskpro/Compaq - BIOS - Revision J - 106265-002.bin", "rb"); + if (!f) + break; + romfread(rom, 0x2000, 1, f); + fclose(f); + biosmask = 0x1fff; + return 1; - case ROM_VS440FX:f = romfopen("vs440fx/1018CS1_.BIO", "rb"); - if (!f) - break; - fseek(f, 0x80, SEEK_SET); - romfread(rom + 0x10000, 0x10000, 1, f); - fclose(f); - f = romfopen("vs440fx/1018CS1_.BI1", "rb"); - if (!f) - break; - fseek(f, 0x80, SEEK_SET); - romfread(rom + 0x00000, 0x10000, 1, f); - fclose(f); - f = romfopen("vs440fx/1018CS1_.BI2", "rb"); - if (!f) - break; - fseek(f, 0x80, SEEK_SET); - romfread(rom + 0x30000, 0x10000, 1, f); - fclose(f); - f = romfopen("vs440fx/1018CS1_.BI3", "rb"); - if (!f) - break; - fseek(f, 0x80, SEEK_SET); - romfread(rom + 0x20000, 0x0a000, 1, f); - fclose(f); + case ROM_VS440FX: + f = romfopen("vs440fx/1018CS1_.BIO", "rb"); + if (!f) + break; + fseek(f, 0x80, SEEK_SET); + romfread(rom + 0x10000, 0x10000, 1, f); + fclose(f); + f = romfopen("vs440fx/1018CS1_.BI1", "rb"); + if (!f) + break; + fseek(f, 0x80, SEEK_SET); + romfread(rom + 0x00000, 0x10000, 1, f); + fclose(f); + f = romfopen("vs440fx/1018CS1_.BI2", "rb"); + if (!f) + break; + fseek(f, 0x80, SEEK_SET); + romfread(rom + 0x30000, 0x10000, 1, f); + fclose(f); + f = romfopen("vs440fx/1018CS1_.BI3", "rb"); + if (!f) + break; + fseek(f, 0x80, SEEK_SET); + romfread(rom + 0x20000, 0x0a000, 1, f); + fclose(f); - f = romfopen("vs440fx/1018CS1_.RCV", "rb"); - if (!f) - break; - fseek(f, 0x80, SEEK_SET); - romfread(rom + 0x2c000, 0x04000, 1, f); - fclose(f); + f = romfopen("vs440fx/1018CS1_.RCV", "rb"); + if (!f) + break; + fseek(f, 0x80, SEEK_SET); + romfread(rom + 0x2c000, 0x04000, 1, f); + fclose(f); - biosmask = 0x3ffff; - return 1; + biosmask = 0x3ffff; + return 1; - case ROM_GA686BX:f = romfopen("ga686bx/6BX.F2a", "rb"); - if (!f) - break; - romfread(rom, 0x40000, 1, f); - fclose(f); + case ROM_GA686BX: + f = romfopen("ga686bx/6BX.F2a", "rb"); + if (!f) + break; + romfread(rom, 0x40000, 1, f); + fclose(f); - biosmask = 0x3ffff; - return 1; - } - printf("Failed to load ROM!\n"); - if (f) - fclose(f); - if (ff) - fclose(ff); - return 0; + biosmask = 0x3ffff; + return 1; + } + printf("Failed to load ROM!\n"); + if (f) + fclose(f); + if (ff) + fclose(ff); + return 0; } diff --git a/src/mfm/mfm_at.c b/src/mfm/mfm_at.c index b689079c..6a07a6c3 100644 --- a/src/mfm/mfm_at.c +++ b/src/mfm/mfm_at.c @@ -18,7 +18,7 @@ #include "mfm_at.h" -#define IDE_TIME (TIMER_USEC*10)//(5 * 100 * (1 << TIMER_SHIFT)) +#define IDE_TIME (TIMER_USEC * 10) //(5 * 100 * (1 << TIMER_SHIFT)) /*Rough estimate - MFM drives spin at 3600 RPM, with 17 sectors per track, meaning (3600/60)*17 = 1020 sectors per second, or 980us per sector. @@ -28,506 +28,506 @@ close in time*/ #define SECTOR_TIME (TIMER_USEC * 980) -#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 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 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 +#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 extern char ide_fn[7][512]; typedef struct mfm_drive_t { - int cfg_spt; - int cfg_hpc; - int current_cylinder; - hdd_file_t hdd_file; + int cfg_spt; + int cfg_hpc; + int current_cylinder; + hdd_file_t hdd_file; } mfm_drive_t; typedef struct mfm_t { - uint8_t status; - uint8_t error; - int secount, sector, cylinder, head, cylprecomp; - uint8_t command; - uint8_t fdisk; - int pos; + 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; + int drive_sel; + int reset; + uint16_t buffer[256]; + int irqstat; - pc_timer_t callback_timer; + pc_timer_t callback_timer; - mfm_drive_t drives[2]; + mfm_drive_t drives[2]; } mfm_t; uint16_t mfm_readw(uint16_t port, void *p); void mfm_writew(uint16_t port, uint16_t val, void *p); static inline void mfm_irq_raise(mfm_t *mfm) { -// pclog("IDE_IRQ_RAISE\n"); - if (!(mfm->fdisk & 2)) - picint(1 << 14); + // pclog("IDE_IRQ_RAISE\n"); + if (!(mfm->fdisk & 2)) + picint(1 << 14); - mfm->irqstat = 1; + mfm->irqstat = 1; } -static inline void mfm_irq_lower(mfm_t *mfm) { - picintc(1 << 14); -} +static inline void mfm_irq_lower(mfm_t *mfm) { picintc(1 << 14); } void mfm_irq_update(mfm_t *mfm) { - if (mfm->irqstat && !((pic2.pend | pic2.ins) & 0x40) && !(mfm->fdisk & 2)) - picint(1 << 14); + if (mfm->irqstat && !((pic2.pend | pic2.ins) & 0x40) && !(mfm->fdisk & 2)) + picint(1 << 14); } /* * Return the sector offset for the current register values */ static int mfm_get_sector(mfm_t *mfm, off64_t *addr) { - mfm_drive_t *drive = &mfm->drives[mfm->drive_sel]; - int heads = drive->cfg_hpc; - int sectors = drive->cfg_spt; + mfm_drive_t *drive = &mfm->drives[mfm->drive_sel]; + int heads = drive->cfg_hpc; + int sectors = drive->cfg_spt; - if (drive->current_cylinder != mfm->cylinder) { - pclog("mfm_get_sector: wrong cylinder\n"); - return 1; - } - if (mfm->head > heads) { - pclog("mfm_get_sector: past end of configured heads\n"); - return 1; - } - if (mfm->sector >= sectors + 1) { - pclog("mfm_get_sector: past end of configured sectors\n"); - return 1; - } - if (mfm->head > drive->hdd_file.hpc) { - pclog("mfm_get_sector: past end of heads\n"); - return 1; - } - if (mfm->sector >= drive->hdd_file.spt + 1) { - pclog("mfm_get_sector: past end of sectors\n"); - return 1; - } + if (drive->current_cylinder != mfm->cylinder) { + pclog("mfm_get_sector: wrong cylinder\n"); + return 1; + } + if (mfm->head > heads) { + pclog("mfm_get_sector: past end of configured heads\n"); + return 1; + } + if (mfm->sector >= sectors + 1) { + pclog("mfm_get_sector: past end of configured sectors\n"); + return 1; + } + if (mfm->head > drive->hdd_file.hpc) { + pclog("mfm_get_sector: past end of heads\n"); + return 1; + } + if (mfm->sector >= drive->hdd_file.spt + 1) { + pclog("mfm_get_sector: past end of sectors\n"); + return 1; + } - *addr = ((((off64_t)mfm->cylinder * heads) + mfm->head) * - sectors) + (mfm->sector - 1); + *addr = ((((off64_t)mfm->cylinder * heads) + mfm->head) * sectors) + (mfm->sector - 1); - return 0; + return 0; } /** * Move to the next sector using CHS addressing */ static void mfm_next_sector(mfm_t *mfm) { - mfm_drive_t *drive = &mfm->drives[mfm->drive_sel]; + mfm_drive_t *drive = &mfm->drives[mfm->drive_sel]; - mfm->sector++; - if (mfm->sector == (drive->cfg_spt + 1)) { - mfm->sector = 1; - mfm->head++; - if (mfm->head == drive->cfg_hpc) { - mfm->head = 0; - mfm->cylinder++; - if (drive->current_cylinder < drive->hdd_file.tracks) - drive->current_cylinder++; - } - } + mfm->sector++; + if (mfm->sector == (drive->cfg_spt + 1)) { + mfm->sector = 1; + mfm->head++; + if (mfm->head == drive->cfg_hpc) { + mfm->head = 0; + mfm->cylinder++; + if (drive->current_cylinder < drive->hdd_file.tracks) + drive->current_cylinder++; + } + } } void mfm_write(uint16_t port, uint8_t val, void *p) { - mfm_t *mfm = (mfm_t *)p; + mfm_t *mfm = (mfm_t *)p; -// pclog("mfm_write: addr=%04x val=%02x\n", port, val); - switch (port) { - case 0x1F0: /* Data */ - mfm_writew(port, val | (val << 8), p); - return; + // pclog("mfm_write: addr=%04x val=%02x\n", port, val); + switch (port) { + case 0x1F0: /* Data */ + mfm_writew(port, val | (val << 8), p); + return; - case 0x1F1: /* Write precompenstation */ - mfm->cylprecomp = val; - return; + case 0x1F1: /* Write precompenstation */ + mfm->cylprecomp = val; + return; - case 0x1F2: /* Sector count */ - mfm->secount = val; - return; + case 0x1F2: /* Sector count */ + mfm->secount = val; + return; - case 0x1F3: /* Sector */ - mfm->sector = val; - return; + case 0x1F3: /* Sector */ + mfm->sector = val; + return; - case 0x1F4: /* Cylinder low */ - mfm->cylinder = (mfm->cylinder & 0xFF00) | val; - return; + case 0x1F4: /* Cylinder low */ + mfm->cylinder = (mfm->cylinder & 0xFF00) | val; + return; - case 0x1F5: /* Cylinder high */ - mfm->cylinder = (mfm->cylinder & 0xFF) | (val << 8); - return; + case 0x1F5: /* Cylinder high */ + mfm->cylinder = (mfm->cylinder & 0xFF) | (val << 8); + return; - case 0x1F6: /* Drive/Head */ - mfm->head = val & 0xF; - mfm->drive_sel = (val & 0x10) ? 1 : 0; - if (mfm->drives[mfm->drive_sel].hdd_file.f == NULL) - mfm->status = 0; - else - mfm->status = STAT_READY | STAT_DSC; - return; + case 0x1F6: /* Drive/Head */ + mfm->head = val & 0xF; + mfm->drive_sel = (val & 0x10) ? 1 : 0; + if (mfm->drives[mfm->drive_sel].hdd_file.f == NULL) + mfm->status = 0; + else + mfm->status = STAT_READY | STAT_DSC; + return; - case 0x1F7: /* Command register */ - if (mfm->drives[mfm->drive_sel].hdd_file.f == NULL) - fatal("Command on non-present drive\n"); + case 0x1F7: /* Command register */ + if (mfm->drives[mfm->drive_sel].hdd_file.f == NULL) + fatal("Command on non-present drive\n"); - mfm_irq_lower(mfm); - mfm->command = val; - mfm->error = 0; + mfm_irq_lower(mfm); + mfm->command = val; + mfm->error = 0; - switch (val & 0xf0) { - case CMD_RESTORE: -// pclog("Restore\n"); - mfm->command &= ~0x0f; /*Mask off step rate*/ - mfm->status = STAT_BUSY; - timer_set_delay_u64(&mfm->callback_timer, 200 * IDE_TIME); - break; + switch (val & 0xf0) { + case CMD_RESTORE: + // pclog("Restore\n"); + mfm->command &= ~0x0f; /*Mask off step rate*/ + mfm->status = STAT_BUSY; + timer_set_delay_u64(&mfm->callback_timer, 200 * IDE_TIME); + break; - case CMD_SEEK: -// pclog("Seek to cylinder %i\n", mfm->cylinder); - mfm->command &= ~0x0f; /*Mask off step rate*/ - mfm->status = STAT_BUSY; - timer_set_delay_u64(&mfm->callback_timer, 200 * IDE_TIME); - break; + case CMD_SEEK: + // pclog("Seek to cylinder %i\n", mfm->cylinder); + mfm->command &= ~0x0f; /*Mask off step rate*/ + mfm->status = STAT_BUSY; + timer_set_delay_u64(&mfm->callback_timer, 200 * IDE_TIME); + break; - default: - switch (val) { - case CMD_READ: - case CMD_READ + 1: - case CMD_READ + 2: - case CMD_READ + 3: -// pclog("Read %i sectors from sector %i cylinder %i head %i %i\n",mfm->secount,mfm->sector,mfm->cylinder,mfm->head,ins); - mfm->command &= ~3; - if (val & 2) - fatal("Read with ECC\n"); - mfm->status = STAT_BUSY; - timer_set_delay_u64(&mfm->callback_timer, 200 * IDE_TIME); - break; + default: + switch (val) { + case CMD_READ: + case CMD_READ + 1: + case CMD_READ + 2: + case CMD_READ + 3: + // pclog("Read %i sectors from sector %i cylinder %i head %i + // %i\n",mfm->secount,mfm->sector,mfm->cylinder,mfm->head,ins); + mfm->command &= ~3; + if (val & 2) + fatal("Read with ECC\n"); + mfm->status = STAT_BUSY; + timer_set_delay_u64(&mfm->callback_timer, 200 * IDE_TIME); + break; - case CMD_WRITE: - case CMD_WRITE + 1: - case CMD_WRITE + 2: - case CMD_WRITE + 3: -// pclog("Write %i sectors to sector %i cylinder %i head %i\n",mfm->secount,mfm->sector,mfm->cylinder,mfm->head); - mfm->command &= ~3; - if (val & 2) - fatal("Write with ECC\n"); - mfm->status = STAT_DRQ | STAT_DSC;// | STAT_BUSY; - mfm->pos = 0; - break; + case CMD_WRITE: + case CMD_WRITE + 1: + case CMD_WRITE + 2: + case CMD_WRITE + 3: + // pclog("Write %i sectors to sector %i cylinder %i head + // %i\n",mfm->secount,mfm->sector,mfm->cylinder,mfm->head); + mfm->command &= ~3; + if (val & 2) + fatal("Write with ECC\n"); + mfm->status = STAT_DRQ | STAT_DSC; // | STAT_BUSY; + mfm->pos = 0; + break; - case CMD_VERIFY: - case CMD_VERIFY + 1: -// pclog("Read verify %i sectors from sector %i cylinder %i head %i\n",mfm->secount,mfm->sector,mfm->cylinder,mfm->head); - mfm->command &= ~1; - mfm->status = STAT_BUSY; - timer_set_delay_u64(&mfm->callback_timer, 200 * IDE_TIME); - break; + case CMD_VERIFY: + case CMD_VERIFY + 1: + // pclog("Read verify %i sectors from sector %i cylinder %i head + // %i\n",mfm->secount,mfm->sector,mfm->cylinder,mfm->head); + mfm->command &= ~1; + mfm->status = STAT_BUSY; + timer_set_delay_u64(&mfm->callback_timer, 200 * IDE_TIME); + break; - case CMD_FORMAT: -// pclog("Format track %i head %i\n", mfm->cylinder, mfm->head); - mfm->status = STAT_DRQ | STAT_BUSY; - mfm->pos = 0; - break; + case CMD_FORMAT: + // pclog("Format track %i head %i\n", mfm->cylinder, mfm->head); + mfm->status = STAT_DRQ | STAT_BUSY; + mfm->pos = 0; + break; - case CMD_SET_PARAMETERS: /* Initialize Drive Parameters */ - mfm->status = STAT_BUSY; - timer_set_delay_u64(&mfm->callback_timer, 30 * IDE_TIME); - break; + case CMD_SET_PARAMETERS: /* Initialize Drive Parameters */ + mfm->status = STAT_BUSY; + timer_set_delay_u64(&mfm->callback_timer, 30 * IDE_TIME); + break; - case CMD_DIAGNOSE: /* Execute Drive Diagnostics */ - mfm->status = STAT_BUSY; - timer_set_delay_u64(&mfm->callback_timer, 200 * IDE_TIME); - break; + case CMD_DIAGNOSE: /* Execute Drive Diagnostics */ + mfm->status = STAT_BUSY; + timer_set_delay_u64(&mfm->callback_timer, 200 * IDE_TIME); + break; - default:pclog("Bad MFM command %02X\n", val); - mfm->status = STAT_BUSY; - timer_set_delay_u64(&mfm->callback_timer, 200 * IDE_TIME); - break; - } - } - break; + default: + pclog("Bad MFM command %02X\n", val); + mfm->status = STAT_BUSY; + timer_set_delay_u64(&mfm->callback_timer, 200 * IDE_TIME); + break; + } + } + break; - case 0x3F6: /* Device control */ - if ((mfm->fdisk & 4) && !(val & 4)) { - timer_set_delay_u64(&mfm->callback_timer, 500 * IDE_TIME); - mfm->reset = 1; - mfm->status = STAT_BUSY; -// pclog("MFM Reset\n"); - } - if (val & 4) { - /*Drive held in reset*/ - timer_disable(&mfm->callback_timer); - mfm->status = STAT_BUSY; - } - mfm->fdisk = val; - mfm_irq_update(mfm); - return; - } -// fatal("Bad IDE write %04X %02X\n", addr, val); + case 0x3F6: /* Device control */ + if ((mfm->fdisk & 4) && !(val & 4)) { + timer_set_delay_u64(&mfm->callback_timer, 500 * IDE_TIME); + mfm->reset = 1; + mfm->status = STAT_BUSY; + // pclog("MFM Reset\n"); + } + if (val & 4) { + /*Drive held in reset*/ + timer_disable(&mfm->callback_timer); + mfm->status = STAT_BUSY; + } + mfm->fdisk = val; + mfm_irq_update(mfm); + return; + } + // fatal("Bad IDE write %04X %02X\n", addr, val); } void mfm_writew(uint16_t port, uint16_t val, void *p) { - mfm_t *mfm = (mfm_t *)p; + mfm_t *mfm = (mfm_t *)p; -// pclog("Write IDEw %04X\n",val); - mfm->buffer[mfm->pos >> 1] = val; - mfm->pos += 2; + // pclog("Write IDEw %04X\n",val); + mfm->buffer[mfm->pos >> 1] = val; + mfm->pos += 2; - if (mfm->pos >= 512) { - mfm->pos = 0; - mfm->status = STAT_BUSY; - timer_set_delay_u64(&mfm->callback_timer, SECTOR_TIME); - } + if (mfm->pos >= 512) { + mfm->pos = 0; + mfm->status = STAT_BUSY; + timer_set_delay_u64(&mfm->callback_timer, SECTOR_TIME); + } } uint8_t mfm_read(uint16_t port, void *p) { - mfm_t *mfm = (mfm_t *)p; - uint8_t temp = 0xff; + mfm_t *mfm = (mfm_t *)p; + uint8_t temp = 0xff; - switch (port) { - case 0x1F0: /* Data */ - temp = mfm_readw(port, mfm) & 0xff; - break; + switch (port) { + case 0x1F0: /* Data */ + temp = mfm_readw(port, mfm) & 0xff; + break; - case 0x1F1: /* Error */ - temp = mfm->error; - break; + case 0x1F1: /* Error */ + temp = mfm->error; + break; - case 0x1F2: /* Sector count */ - temp = (uint8_t)mfm->secount; - break; + case 0x1F2: /* Sector count */ + temp = (uint8_t)mfm->secount; + break; - case 0x1F3: /* Sector */ - temp = (uint8_t)mfm->sector; - break; + case 0x1F3: /* Sector */ + temp = (uint8_t)mfm->sector; + break; - case 0x1F4: /* Cylinder low */ - temp = (uint8_t)(mfm->cylinder & 0xFF); - break; + case 0x1F4: /* Cylinder low */ + temp = (uint8_t)(mfm->cylinder & 0xFF); + break; - case 0x1F5: /* Cylinder high */ - temp = (uint8_t)(mfm->cylinder >> 8); - break; + case 0x1F5: /* Cylinder high */ + temp = (uint8_t)(mfm->cylinder >> 8); + break; - case 0x1F6: /* Drive/Head */ - temp = (uint8_t)(mfm->head | (mfm->drive_sel ? 0x10 : 0) | 0xa0); - break; + case 0x1F6: /* Drive/Head */ + temp = (uint8_t)(mfm->head | (mfm->drive_sel ? 0x10 : 0) | 0xa0); + break; - case 0x1F7: /* Status */ - mfm_irq_lower(mfm); - temp = mfm->status; - break; - } + case 0x1F7: /* Status */ + mfm_irq_lower(mfm); + temp = mfm->status; + break; + } -// pclog("mfm_read: addr=%04x val=%02x %04X:%04x\n", port, temp, CS, cpu_state.pc); - return temp; + // pclog("mfm_read: addr=%04x val=%02x %04X:%04x\n", port, temp, CS, cpu_state.pc); + return temp; } uint16_t mfm_readw(uint16_t port, void *p) { - mfm_t *mfm = (mfm_t *)p; - uint16_t temp; + mfm_t *mfm = (mfm_t *)p; + uint16_t temp; - temp = mfm->buffer[mfm->pos >> 1]; - mfm->pos += 2; + temp = mfm->buffer[mfm->pos >> 1]; + mfm->pos += 2; - if (mfm->pos >= 512) { -// pclog("Over! packlen %i %i\n",ide->packlen,ide->pos); - mfm->pos = 0; - mfm->status = STAT_READY | STAT_DSC; - if (mfm->command == CMD_READ) { - mfm->secount = (mfm->secount - 1) & 0xff; - if (mfm->secount) { - mfm_next_sector(mfm); - mfm->status = STAT_BUSY | STAT_READY | STAT_DSC; - timer_set_delay_u64(&mfm->callback_timer, SECTOR_TIME); - } - } - } + if (mfm->pos >= 512) { + // pclog("Over! packlen %i %i\n",ide->packlen,ide->pos); + mfm->pos = 0; + mfm->status = STAT_READY | STAT_DSC; + if (mfm->command == CMD_READ) { + mfm->secount = (mfm->secount - 1) & 0xff; + if (mfm->secount) { + mfm_next_sector(mfm); + mfm->status = STAT_BUSY | STAT_READY | STAT_DSC; + timer_set_delay_u64(&mfm->callback_timer, SECTOR_TIME); + } + } + } -// pclog("mem_readw: temp=%04x %i\n", temp, mfm->pos); - return temp; + // pclog("mem_readw: temp=%04x %i\n", temp, mfm->pos); + return temp; } static void do_seek(mfm_t *mfm) { - mfm_drive_t *drive = &mfm->drives[mfm->drive_sel]; + mfm_drive_t *drive = &mfm->drives[mfm->drive_sel]; - if (mfm->cylinder < drive->hdd_file.tracks) - drive->current_cylinder = mfm->cylinder; - else - drive->current_cylinder = drive->hdd_file.tracks - 1; + if (mfm->cylinder < drive->hdd_file.tracks) + drive->current_cylinder = mfm->cylinder; + else + drive->current_cylinder = drive->hdd_file.tracks - 1; } void mfm_callback(void *p) { - mfm_t *mfm = (mfm_t *)p; - mfm_drive_t *drive = &mfm->drives[mfm->drive_sel]; - off64_t addr; + mfm_t *mfm = (mfm_t *)p; + mfm_drive_t *drive = &mfm->drives[mfm->drive_sel]; + off64_t addr; -// pclog("mfm_callback: command=%02x reset=%i\n", mfm->command, mfm->reset); + // pclog("mfm_callback: command=%02x reset=%i\n", mfm->command, mfm->reset); - if (mfm->reset) { - mfm->status = STAT_READY | STAT_DSC; - mfm->error = 1; - mfm->secount = 1; - mfm->sector = 1; - mfm->head = 0; - mfm->cylinder = 0; - mfm->reset = 0; -// pclog("Reset callback\n"); - return; - } - switch (mfm->command) { - case CMD_RESTORE:drive->current_cylinder = 0; - mfm->status = STAT_READY | STAT_DSC; - mfm_irq_raise(mfm); - break; + if (mfm->reset) { + mfm->status = STAT_READY | STAT_DSC; + mfm->error = 1; + mfm->secount = 1; + mfm->sector = 1; + mfm->head = 0; + mfm->cylinder = 0; + mfm->reset = 0; + // pclog("Reset callback\n"); + return; + } + switch (mfm->command) { + case CMD_RESTORE: + drive->current_cylinder = 0; + mfm->status = STAT_READY | STAT_DSC; + mfm_irq_raise(mfm); + break; - case CMD_SEEK:do_seek(mfm); - mfm->status = STAT_READY | STAT_DSC; - mfm_irq_raise(mfm); - break; + case CMD_SEEK: + do_seek(mfm); + mfm->status = STAT_READY | STAT_DSC; + mfm_irq_raise(mfm); + break; - case CMD_READ:do_seek(mfm); - if (mfm_get_sector(mfm, &addr)) { - mfm->error = ERR_ID_NOT_FOUND; - mfm->status = STAT_READY | STAT_DSC | STAT_ERR; - mfm_irq_raise(mfm); - break; - } + case CMD_READ: + do_seek(mfm); + if (mfm_get_sector(mfm, &addr)) { + mfm->error = ERR_ID_NOT_FOUND; + mfm->status = STAT_READY | STAT_DSC | STAT_ERR; + mfm_irq_raise(mfm); + break; + } -// pclog("Read %i %i %i %08X\n",ide.cylinder,ide.head,ide.sector,addr); - hdd_read_sectors(&drive->hdd_file, addr, 1, mfm->buffer); - mfm->pos = 0; - mfm->status = STAT_DRQ | STAT_READY | STAT_DSC; -// pclog("Read sector callback %i %i %i offset %08X %i left %i %02X\n",ide.sector,ide.cylinder,ide.head,addr,ide.secount,ide.spt,ide.atastat[ide.board]); -// if (addr) output=3; - mfm_irq_raise(mfm); - readflash_set(READFLASH_HDC, mfm->drive_sel); - break; + // pclog("Read %i %i %i %08X\n",ide.cylinder,ide.head,ide.sector,addr); + hdd_read_sectors(&drive->hdd_file, addr, 1, mfm->buffer); + mfm->pos = 0; + mfm->status = STAT_DRQ | STAT_READY | STAT_DSC; + // pclog("Read sector callback %i %i %i offset %08X %i left %i + // %02X\n",ide.sector,ide.cylinder,ide.head,addr,ide.secount,ide.spt,ide.atastat[ide.board]); if + // (addr) output=3; + mfm_irq_raise(mfm); + readflash_set(READFLASH_HDC, mfm->drive_sel); + break; - case CMD_WRITE:do_seek(mfm); - if (mfm_get_sector(mfm, &addr)) { - mfm->error = ERR_ID_NOT_FOUND; - mfm->status = STAT_READY | STAT_DSC | STAT_ERR; - mfm_irq_raise(mfm); - break; - } - hdd_write_sectors(&drive->hdd_file, addr, 1, mfm->buffer); - mfm_irq_raise(mfm); - mfm->secount = (mfm->secount - 1) & 0xff; - if (mfm->secount) { - mfm->status = STAT_DRQ | STAT_READY | STAT_DSC; - mfm->pos = 0; - mfm_next_sector(mfm); - } else - mfm->status = STAT_READY | STAT_DSC; - readflash_set(READFLASH_HDC, mfm->drive_sel); - break; + case CMD_WRITE: + do_seek(mfm); + if (mfm_get_sector(mfm, &addr)) { + mfm->error = ERR_ID_NOT_FOUND; + mfm->status = STAT_READY | STAT_DSC | STAT_ERR; + mfm_irq_raise(mfm); + break; + } + hdd_write_sectors(&drive->hdd_file, addr, 1, mfm->buffer); + mfm_irq_raise(mfm); + mfm->secount = (mfm->secount - 1) & 0xff; + if (mfm->secount) { + mfm->status = STAT_DRQ | STAT_READY | STAT_DSC; + mfm->pos = 0; + mfm_next_sector(mfm); + } else + mfm->status = STAT_READY | STAT_DSC; + readflash_set(READFLASH_HDC, mfm->drive_sel); + break; - case CMD_VERIFY:do_seek(mfm); - mfm->pos = 0; - mfm->status = STAT_READY | STAT_DSC; -// pclog("Read verify callback %i %i %i offset %08X %i left\n",ide.sector,ide.cylinder,ide.head,addr,ide.secount); - mfm_irq_raise(mfm); - readflash_set(READFLASH_HDC, mfm->drive_sel); - break; + case CMD_VERIFY: + do_seek(mfm); + mfm->pos = 0; + mfm->status = STAT_READY | STAT_DSC; + // pclog("Read verify callback %i %i %i offset %08X %i + // left\n",ide.sector,ide.cylinder,ide.head,addr,ide.secount); + mfm_irq_raise(mfm); + readflash_set(READFLASH_HDC, mfm->drive_sel); + break; - case CMD_FORMAT:do_seek(mfm); - if (mfm_get_sector(mfm, &addr)) { - mfm->error = ERR_ID_NOT_FOUND; - mfm->status = STAT_READY | STAT_DSC | STAT_ERR; - mfm_irq_raise(mfm); - break; - } - hdd_format_sectors(&drive->hdd_file, addr, mfm->secount); - mfm->status = STAT_READY | STAT_DSC; - mfm_irq_raise(mfm); - readflash_set(READFLASH_HDC, mfm->drive_sel); - break; + case CMD_FORMAT: + do_seek(mfm); + if (mfm_get_sector(mfm, &addr)) { + mfm->error = ERR_ID_NOT_FOUND; + mfm->status = STAT_READY | STAT_DSC | STAT_ERR; + mfm_irq_raise(mfm); + break; + } + hdd_format_sectors(&drive->hdd_file, addr, mfm->secount); + mfm->status = STAT_READY | STAT_DSC; + mfm_irq_raise(mfm); + readflash_set(READFLASH_HDC, mfm->drive_sel); + break; - case CMD_DIAGNOSE:mfm->error = 1; /*No error detected*/ - mfm->status = STAT_READY | STAT_DSC; - mfm_irq_raise(mfm); - break; + case CMD_DIAGNOSE: + mfm->error = 1; /*No error detected*/ + mfm->status = STAT_READY | STAT_DSC; + mfm_irq_raise(mfm); + break; - case CMD_SET_PARAMETERS: /* Initialize Drive Parameters */ - drive->cfg_spt = mfm->secount; - drive->cfg_hpc = mfm->head + 1; - pclog("Parameters: spt=%i hpc=%i\n", drive->cfg_spt, drive->cfg_hpc); - mfm->status = STAT_READY | STAT_DSC; - mfm_irq_raise(mfm); - break; + case CMD_SET_PARAMETERS: /* Initialize Drive Parameters */ + drive->cfg_spt = mfm->secount; + drive->cfg_hpc = mfm->head + 1; + pclog("Parameters: spt=%i hpc=%i\n", drive->cfg_spt, drive->cfg_hpc); + mfm->status = STAT_READY | STAT_DSC; + mfm_irq_raise(mfm); + break; - default:pclog("Callback on unknown command %02x\n", mfm->command); - mfm->status = STAT_READY | STAT_ERR | STAT_DSC; - mfm->error = ERR_ABRT; - mfm_irq_raise(mfm); - break; - } + default: + pclog("Callback on unknown command %02x\n", mfm->command); + mfm->status = STAT_READY | STAT_ERR | STAT_DSC; + mfm->error = ERR_ABRT; + mfm_irq_raise(mfm); + break; + } } void *mfm_init() { - mfm_t *mfm = malloc(sizeof(mfm_t)); - memset(mfm, 0, sizeof(mfm_t)); + mfm_t *mfm = malloc(sizeof(mfm_t)); + memset(mfm, 0, sizeof(mfm_t)); - hdd_load(&mfm->drives[0].hdd_file, 0, ide_fn[0]); - hdd_load(&mfm->drives[1].hdd_file, 1, ide_fn[1]); + hdd_load(&mfm->drives[0].hdd_file, 0, ide_fn[0]); + hdd_load(&mfm->drives[1].hdd_file, 1, ide_fn[1]); - mfm->status = STAT_READY | STAT_DSC; - mfm->error = 1; /*No errors*/ + mfm->status = STAT_READY | STAT_DSC; + mfm->error = 1; /*No errors*/ - io_sethandler(0x01f0, 0x0001, mfm_read, mfm_readw, NULL, mfm_write, mfm_writew, NULL, mfm); - io_sethandler(0x01f1, 0x0007, mfm_read, NULL, NULL, mfm_write, NULL, NULL, mfm); - io_sethandler(0x03f6, 0x0001, NULL, NULL, NULL, mfm_write, NULL, NULL, mfm); + io_sethandler(0x01f0, 0x0001, mfm_read, mfm_readw, NULL, mfm_write, mfm_writew, NULL, mfm); + io_sethandler(0x01f1, 0x0007, mfm_read, NULL, NULL, mfm_write, NULL, NULL, mfm); + io_sethandler(0x03f6, 0x0001, NULL, NULL, NULL, mfm_write, NULL, NULL, mfm); - timer_add(&mfm->callback_timer, mfm_callback, mfm, 0); + timer_add(&mfm->callback_timer, mfm_callback, mfm, 0); - return mfm; + return mfm; } void mfm_close(void *p) { - mfm_t *mfm = (mfm_t *)p; + mfm_t *mfm = (mfm_t *)p; - hdd_close(&mfm->drives[0].hdd_file); - hdd_close(&mfm->drives[1].hdd_file); + hdd_close(&mfm->drives[0].hdd_file); + hdd_close(&mfm->drives[1].hdd_file); - free(mfm); + free(mfm); } -device_t mfm_at_device = - { - "IBM PC AT Fixed Disk Adapter", - DEVICE_AT, - mfm_init, - mfm_close, - NULL, - NULL, - NULL, - NULL, - NULL - }; +device_t mfm_at_device = {"IBM PC AT Fixed Disk Adapter", DEVICE_AT, mfm_init, mfm_close, NULL, NULL, NULL, NULL, NULL}; diff --git a/src/mfm/mfm_xebec.c b/src/mfm/mfm_xebec.c index 1822bf24..4734ae71 100644 --- a/src/mfm/mfm_xebec.c +++ b/src/mfm/mfm_xebec.c @@ -26,776 +26,777 @@ extern char ide_fn[7][512]; 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 + 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 mfm_drive_t { - int cfg_spt; - int cfg_hpc; - int cfg_cyl; - int current_cylinder; - hdd_file_t hdd_file; + int cfg_spt; + int cfg_hpc; + int cfg_cyl; + int current_cylinder; + hdd_file_t hdd_file; } mfm_drive_t; typedef struct xebec_t { - rom_t bios_rom; + rom_t bios_rom; - pc_timer_t callback_timer; + pc_timer_t callback_timer; - int state; + int state; - uint8_t status; + uint8_t status; - uint8_t command[6]; - int command_pos; + uint8_t command[6]; + int command_pos; - uint8_t data[512]; - int data_pos, data_len; + uint8_t data[512]; + int data_pos, data_len; - uint8_t sector_buf[512]; + uint8_t sector_buf[512]; - uint8_t irq_dma_mask; + uint8_t irq_dma_mask; - uint8_t completion_byte; - uint8_t error; + uint8_t completion_byte; + uint8_t error; - int drive_sel; + int drive_sel; - mfm_drive_t drives[2]; + mfm_drive_t drives[2]; - int sector, head, cylinder; - int sector_count; + int sector, head, cylinder; + int sector_count; - uint8_t switches; + uint8_t switches; } xebec_t; #define STAT_IRQ 0x20 #define STAT_DRQ 0x10 #define STAT_BSY 0x08 -#define STAT_CD 0x04 -#define STAT_IO 0x02 +#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_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 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_NOT_READY 0x04 +#define ERR_SEEK_ERROR 0x15 #define ERR_ILLEGAL_SECTOR_ADDRESS 0x21 static uint8_t xebec_read(uint16_t port, void *p) { - xebec_t *xebec = (xebec_t *)p; - uint8_t temp = 0xff; + xebec_t *xebec = (xebec_t *)p; + uint8_t temp = 0xff; - switch (port) { - case 0x320: /*Read data*/ - xebec->status &= ~STAT_IRQ; - switch (xebec->state) { - case STATE_COMPLETION_BYTE: - if ((xebec->status & 0xf) != (STAT_CD | STAT_IO | STAT_REQ | STAT_BSY)) - fatal("Read data STATE_COMPLETION_BYTE, status=%02x\n", xebec->status); + switch (port) { + case 0x320: /*Read data*/ + xebec->status &= ~STAT_IRQ; + switch (xebec->state) { + case STATE_COMPLETION_BYTE: + if ((xebec->status & 0xf) != (STAT_CD | STAT_IO | STAT_REQ | STAT_BSY)) + fatal("Read data STATE_COMPLETION_BYTE, status=%02x\n", xebec->status); - temp = xebec->completion_byte; -// pclog("Read completion byte %02x\n", temp); - xebec->status = 0; - xebec->state = STATE_IDLE; - break; + temp = xebec->completion_byte; + // pclog("Read completion byte %02x\n", temp); + xebec->status = 0; + xebec->state = STATE_IDLE; + break; - case STATE_SEND_DATA: - if ((xebec->status & 0xf) != (STAT_IO | STAT_REQ | STAT_BSY)) - fatal("Read data STATE_COMPLETION_BYTE, status=%02x\n", xebec->status); - if (xebec->data_pos >= xebec->data_len) - fatal("Data write with full data!\n"); - temp = xebec->data[xebec->data_pos++]; - if (xebec->data_pos == xebec->data_len) { -// pclog("Read all data\n"); - xebec->status = STAT_BSY; - xebec->state = STATE_SENT_DATA; - timer_set_delay_u64(&xebec->callback_timer, XEBEC_TIME); - } - break; + case STATE_SEND_DATA: + if ((xebec->status & 0xf) != (STAT_IO | STAT_REQ | STAT_BSY)) + fatal("Read data STATE_COMPLETION_BYTE, status=%02x\n", xebec->status); + if (xebec->data_pos >= xebec->data_len) + fatal("Data write with full data!\n"); + temp = xebec->data[xebec->data_pos++]; + if (xebec->data_pos == xebec->data_len) { + // pclog("Read all data\n"); + xebec->status = STAT_BSY; + xebec->state = STATE_SENT_DATA; + timer_set_delay_u64(&xebec->callback_timer, XEBEC_TIME); + } + break; - default:fatal("Read data register - %i, %02x\n", xebec->state, xebec->status); - } - break; + default: + fatal("Read data register - %i, %02x\n", xebec->state, xebec->status); + } + break; - case 0x321: /*Read status*/ - //fatal("Read status\n"); - temp = xebec->status; - break; + case 0x321: /*Read status*/ + // fatal("Read status\n"); + temp = xebec->status; + break; - case 0x322: /*Read option jumpers*/ -// pclog("Read option jumpers\n"); - temp = xebec->switches; - break; - } + case 0x322: /*Read option jumpers*/ + // pclog("Read option jumpers\n"); + temp = xebec->switches; + break; + } -// if (port != 0x321) pclog("xebec_read: port=%04x val=%02x\n", port, temp); - return temp; + // if (port != 0x321) pclog("xebec_read: port=%04x val=%02x\n", port, temp); + return temp; } static void xebec_write(uint16_t port, uint8_t val, void *p) { - xebec_t *xebec = (xebec_t *)p; + xebec_t *xebec = (xebec_t *)p; -// pclog("xebec_write: port=%04x val=%02x\n", port, val); + // pclog("xebec_write: port=%04x val=%02x\n", port, val); - switch (port) { - case 0x320: /*Write data*/ -// pclog("Write data %02x\n"); - switch (xebec->state) { - case STATE_RECEIVE_COMMAND: - if ((xebec->status & 0xf) != (STAT_BSY | STAT_CD | STAT_REQ)) - fatal("Bad write data state - STATE_START_COMMAND, status=%02x\n", xebec->status); - if (xebec->command_pos >= 6) - fatal("Command write with full command!\n"); - /*Command data*/ - xebec->command[xebec->command_pos++] = val; - if (xebec->command_pos == 6) { - xebec->status = STAT_BSY; - xebec->state = STATE_START_COMMAND; - timer_set_delay_u64(&xebec->callback_timer, XEBEC_TIME); -// pclog("Command %02x\n", xebec->command[0]); - } - break; + switch (port) { + case 0x320: /*Write data*/ + // pclog("Write data %02x\n"); + switch (xebec->state) { + case STATE_RECEIVE_COMMAND: + if ((xebec->status & 0xf) != (STAT_BSY | STAT_CD | STAT_REQ)) + fatal("Bad write data state - STATE_START_COMMAND, status=%02x\n", xebec->status); + if (xebec->command_pos >= 6) + fatal("Command write with full command!\n"); + /*Command data*/ + xebec->command[xebec->command_pos++] = val; + if (xebec->command_pos == 6) { + xebec->status = STAT_BSY; + xebec->state = STATE_START_COMMAND; + timer_set_delay_u64(&xebec->callback_timer, XEBEC_TIME); + // pclog("Command %02x\n", xebec->command[0]); + } + break; - case STATE_RECEIVE_DATA: - if ((xebec->status & 0xf) != (STAT_BSY | STAT_REQ)) - fatal("Bad write data state - STATE_RECEIVE_DATA, status=%02x\n", xebec->status); - if (xebec->data_pos >= xebec->data_len) - fatal("Data write with full data!\n"); - /*Command data*/ - xebec->data[xebec->data_pos++] = val; - if (xebec->data_pos == xebec->data_len) { -// pclog("Got data\n"); - xebec->status = STAT_BSY; - xebec->state = STATE_RECEIVED_DATA; - timer_set_delay_u64(&xebec->callback_timer, XEBEC_TIME); - } - break; + case STATE_RECEIVE_DATA: + if ((xebec->status & 0xf) != (STAT_BSY | STAT_REQ)) + fatal("Bad write data state - STATE_RECEIVE_DATA, status=%02x\n", xebec->status); + if (xebec->data_pos >= xebec->data_len) + fatal("Data write with full data!\n"); + /*Command data*/ + xebec->data[xebec->data_pos++] = val; + if (xebec->data_pos == xebec->data_len) { + // pclog("Got data\n"); + xebec->status = STAT_BSY; + xebec->state = STATE_RECEIVED_DATA; + timer_set_delay_u64(&xebec->callback_timer, XEBEC_TIME); + } + break; - default:fatal("Write data unknown state - %i %02x\n", xebec->state, xebec->status); - } - break; + default: + fatal("Write data unknown state - %i %02x\n", xebec->state, xebec->status); + } + break; - case 0x321: /*Controller reset*/ -// pclog("Write controller reset\n"); - xebec->status = 0; - break; + case 0x321: /*Controller reset*/ + // pclog("Write controller reset\n"); + xebec->status = 0; + break; - case 0x322: /*Generate controller-select-pulse*/ -// pclog("Write controller-select-pulse\n"); - xebec->status = STAT_BSY | STAT_CD | STAT_REQ; - xebec->command_pos = 0; - xebec->state = STATE_RECEIVE_COMMAND; - break; + case 0x322: /*Generate controller-select-pulse*/ + // pclog("Write controller-select-pulse\n"); + xebec->status = STAT_BSY | STAT_CD | STAT_REQ; + xebec->command_pos = 0; + xebec->state = STATE_RECEIVE_COMMAND; + break; - case 0x323: /*DMA/IRQ mask register*/ -// pclog("Write DMA/IRQ mask %02x\n", val); - xebec->irq_dma_mask = val; - break; - } + case 0x323: /*DMA/IRQ mask register*/ + // pclog("Write DMA/IRQ mask %02x\n", val); + xebec->irq_dma_mask = val; + break; + } } static void xebec_complete(xebec_t *xebec) { - xebec->status = STAT_REQ | STAT_CD | STAT_IO | STAT_BSY; - xebec->state = STATE_COMPLETION_BYTE; - if (xebec->irq_dma_mask & IRQ_ENA) { - xebec->status |= STAT_IRQ; - picint(1 << 5); - } + xebec->status = STAT_REQ | STAT_CD | STAT_IO | STAT_BSY; + xebec->state = STATE_COMPLETION_BYTE; + if (xebec->irq_dma_mask & IRQ_ENA) { + xebec->status |= STAT_IRQ; + picint(1 << 5); + } } static void xebec_error(xebec_t *xebec, uint8_t error) { - xebec->completion_byte |= 0x02; - xebec->error = error; - pclog("xebec_error - %02x\n", xebec->error); + xebec->completion_byte |= 0x02; + xebec->error = error; + pclog("xebec_error - %02x\n", xebec->error); } static int xebec_get_sector(xebec_t *xebec, off64_t *addr) { - mfm_drive_t *drive = &xebec->drives[xebec->drive_sel]; - int heads = drive->cfg_hpc; + mfm_drive_t *drive = &xebec->drives[xebec->drive_sel]; + int heads = drive->cfg_hpc; - if (drive->current_cylinder != xebec->cylinder) { - pclog("mfm_get_sector: wrong cylinder\n"); - xebec->error = ERR_ILLEGAL_SECTOR_ADDRESS; - return 1; - } - if (xebec->head > heads) { - pclog("mfm_get_sector: past end of configured heads\n"); - xebec->error = ERR_ILLEGAL_SECTOR_ADDRESS; - return 1; - } - if (xebec->head > drive->hdd_file.hpc) { - pclog("mfm_get_sector: past end of heads\n"); - xebec->error = ERR_ILLEGAL_SECTOR_ADDRESS; - return 1; - } - if (xebec->sector >= 17) { - pclog("mfm_get_sector: past end of sectors\n"); - xebec->error = ERR_ILLEGAL_SECTOR_ADDRESS; - return 1; - } + if (drive->current_cylinder != xebec->cylinder) { + pclog("mfm_get_sector: wrong cylinder\n"); + xebec->error = ERR_ILLEGAL_SECTOR_ADDRESS; + return 1; + } + if (xebec->head > heads) { + pclog("mfm_get_sector: past end of configured heads\n"); + xebec->error = ERR_ILLEGAL_SECTOR_ADDRESS; + return 1; + } + if (xebec->head > drive->hdd_file.hpc) { + pclog("mfm_get_sector: past end of heads\n"); + xebec->error = ERR_ILLEGAL_SECTOR_ADDRESS; + return 1; + } + if (xebec->sector >= 17) { + pclog("mfm_get_sector: past end of sectors\n"); + xebec->error = ERR_ILLEGAL_SECTOR_ADDRESS; + return 1; + } - *addr = ((((off64_t)xebec->cylinder * heads) + xebec->head) * - 17) + xebec->sector; + *addr = ((((off64_t)xebec->cylinder * heads) + xebec->head) * 17) + xebec->sector; - return 0; + return 0; } static void xebec_next_sector(xebec_t *xebec) { - mfm_drive_t *drive = &xebec->drives[xebec->drive_sel]; + mfm_drive_t *drive = &xebec->drives[xebec->drive_sel]; - xebec->sector++; - if (xebec->sector >= 17) { - xebec->sector = 0; - xebec->head++; - if (xebec->head >= drive->cfg_hpc) { - xebec->head = 0; - xebec->cylinder++; - drive->current_cylinder++; - if (drive->current_cylinder >= drive->cfg_cyl) - drive->current_cylinder = drive->cfg_cyl - 1; - } - } + xebec->sector++; + if (xebec->sector >= 17) { + xebec->sector = 0; + xebec->head++; + if (xebec->head >= drive->cfg_hpc) { + xebec->head = 0; + xebec->cylinder++; + drive->current_cylinder++; + if (drive->current_cylinder >= drive->cfg_cyl) + drive->current_cylinder = drive->cfg_cyl - 1; + } + } } static void xebec_callback(void *p) { - xebec_t *xebec = (xebec_t *)p; - mfm_drive_t *drive; - - xebec->drive_sel = (xebec->command[1] & 0x20) ? 1 : 0; - xebec->completion_byte = xebec->drive_sel & 0x20; - - drive = &xebec->drives[xebec->drive_sel]; - - switch (xebec->command[0]) { - case CMD_TEST_DRIVE_READY: - if (!drive->hdd_file.f) - xebec_error(xebec, ERR_NOT_READY); - xebec_complete(xebec); - break; - - case CMD_RECALIBRATE: - if (!drive->hdd_file.f) - xebec_error(xebec, ERR_NOT_READY); - else { - xebec->cylinder = 0; - drive->current_cylinder = 0; - } - xebec_complete(xebec); - break; - - case CMD_READ_STATUS: - switch (xebec->state) { - case STATE_START_COMMAND:xebec->state = STATE_SEND_DATA; - xebec->data_pos = 0; - xebec->data_len = 4; - xebec->status = STAT_BSY | STAT_IO | STAT_REQ; - xebec->data[0] = xebec->error; - xebec->data[1] = xebec->drive_sel ? 0x20 : 0; - xebec->data[2] = xebec->data[3] = 0; -// pclog("Get status %02x\n", xebec->data[0]); - xebec->error = 0; - break; - - case STATE_SENT_DATA:xebec_complete(xebec); - break; - } - break; - - case CMD_VERIFY_SECTORS: - switch (xebec->state) { - case STATE_START_COMMAND:xebec->cylinder = xebec->command[3] | ((xebec->command[2] & 0xc0) << 2); - drive->current_cylinder = (xebec->cylinder >= drive->cfg_cyl) ? drive->cfg_cyl - 1 : xebec->cylinder; - xebec->head = xebec->command[1] & 0x1f; - xebec->sector = xebec->command[2] & 0x1f; - xebec->sector_count = xebec->command[4]; - do { - off64_t addr; - -// pclog("xebec Verify %i,%i,%i %i\n", xebec->cylinder, xebec->head, xebec->sector, xebec->sector_count); - if (xebec_get_sector(xebec, &addr)) { - pclog("xebec_get_sector failed\n"); - xebec_error(xebec, xebec->error); - xebec_complete(xebec); - return; - } - - xebec_next_sector(xebec); - - xebec->sector_count = (xebec->sector_count - 1) & 0xff; - } while (xebec->sector_count); - - xebec_complete(xebec); - - readflash_set(READFLASH_HDC, xebec->drive_sel); - break; - - default:fatal("CMD_VERIFY_SECTORS: bad state %i\n", xebec->state); - } - break; - - case CMD_FORMAT_TRACK: { - off64_t addr; - - xebec->cylinder = xebec->command[3] | ((xebec->command[2] & 0xc0) << 2); - drive->current_cylinder = (xebec->cylinder >= drive->cfg_cyl) ? drive->cfg_cyl - 1 : xebec->cylinder; - xebec->head = xebec->command[1] & 0x1f; -// pclog("Format track %i,%i\n", xebec->cylinder, xebec->head); - - if (xebec_get_sector(xebec, &addr)) { - pclog("xebec_get_sector failed\n"); - xebec_error(xebec, xebec->error); - xebec_complete(xebec); - return; - } - - hdd_format_sectors(&drive->hdd_file, addr, 17); - - xebec_complete(xebec); - } - break; - - case CMD_READ_SECTORS: - switch (xebec->state) { - case STATE_START_COMMAND:xebec->cylinder = xebec->command[3] | ((xebec->command[2] & 0xc0) << 2); - drive->current_cylinder = (xebec->cylinder >= drive->cfg_cyl) ? drive->cfg_cyl - 1 : xebec->cylinder; - xebec->head = xebec->command[1] & 0x1f; - xebec->sector = xebec->command[2] & 0x1f; - xebec->sector_count = xebec->command[4]; - xebec->state = STATE_SEND_DATA; - xebec->data_pos = 0; - xebec->data_len = 512; - { - off64_t addr; - - if (xebec_get_sector(xebec, &addr)) { - xebec_error(xebec, xebec->error); - xebec_complete(xebec); - return; - } -// pclog("xebec Read %i,%i,%i\n", xebec->cylinder, xebec->head, xebec->sector); - - hdd_read_sectors(&drive->hdd_file, addr, 1, xebec->sector_buf); - readflash_set(READFLASH_HDC, xebec->drive_sel); - } - if (xebec->irq_dma_mask & DMA_ENA) - timer_set_delay_u64(&xebec->callback_timer, XEBEC_TIME); - else { - xebec->status = STAT_BSY | STAT_IO | STAT_REQ; - memcpy(xebec->data, xebec->sector_buf, 512); - } - break; - - case STATE_SEND_DATA:xebec->status = STAT_BSY; - if (xebec->irq_dma_mask & DMA_ENA) { - for (; xebec->data_pos < 512; xebec->data_pos++) { - int val = dma_channel_write(3, xebec->sector_buf[xebec->data_pos]); - - if (val == DMA_NODATA) { - pclog("CMD_READ_SECTORS out of data!\n"); - xebec->status = STAT_BSY | STAT_CD | STAT_IO | STAT_REQ; - timer_set_delay_u64(&xebec->callback_timer, XEBEC_TIME); - return; - } - } - xebec->state = STATE_SENT_DATA; - timer_set_delay_u64(&xebec->callback_timer, XEBEC_TIME); - } else - fatal("Read sectors no DMA! - shouldn't get here\n"); - break; - - case STATE_SENT_DATA:xebec_next_sector(xebec); - - xebec->data_pos = 0; - - xebec->sector_count = (xebec->sector_count - 1) & 0xff; - - if (xebec->sector_count) { - off64_t addr; - - if (xebec_get_sector(xebec, &addr)) { - xebec_error(xebec, xebec->error); - xebec_complete(xebec); - return; - } - -// pclog("xebec Read %i,%i,%i\n", xebec->cylinder, xebec->head, xebec->sector); - - hdd_read_sectors(&drive->hdd_file, addr, 1, xebec->sector_buf); - readflash_set(READFLASH_HDC, xebec->drive_sel); - - xebec->state = STATE_SEND_DATA; - - if (xebec->irq_dma_mask & DMA_ENA) - timer_set_delay_u64(&xebec->callback_timer, XEBEC_TIME); - else { - xebec->status = STAT_BSY | STAT_IO | STAT_REQ; - memcpy(xebec->data, xebec->sector_buf, 512); - } - } else - xebec_complete(xebec); - break; - - default:fatal("CMD_READ_SECTORS: bad state %i\n", xebec->state); - } - break; - - case CMD_WRITE_SECTORS: - switch (xebec->state) { - case STATE_START_COMMAND:xebec->cylinder = xebec->command[3] | ((xebec->command[2] & 0xc0) << 2); - drive->current_cylinder = (xebec->cylinder >= drive->cfg_cyl) ? drive->cfg_cyl - 1 : xebec->cylinder; - xebec->head = xebec->command[1] & 0x1f; - xebec->sector = xebec->command[2] & 0x1f; - xebec->sector_count = xebec->command[4]; - xebec->state = STATE_RECEIVE_DATA; - xebec->data_pos = 0; - xebec->data_len = 512; - if (xebec->irq_dma_mask & DMA_ENA) - timer_set_delay_u64(&xebec->callback_timer, XEBEC_TIME); - else - xebec->status = STAT_BSY | STAT_REQ; - break; - - case STATE_RECEIVE_DATA:xebec->status = STAT_BSY; - if (xebec->irq_dma_mask & DMA_ENA) { - for (; xebec->data_pos < 512; xebec->data_pos++) { - int val = dma_channel_read(3); - - if (val == DMA_NODATA) { - pclog("CMD_WRITE_SECTORS out of data!\n"); - xebec->status = STAT_BSY | STAT_CD | STAT_IO | STAT_REQ; - timer_set_delay_u64(&xebec->callback_timer, XEBEC_TIME); - return; - } - - xebec->sector_buf[xebec->data_pos] = val & 0xff; - } - - xebec->state = STATE_RECEIVED_DATA; - timer_set_delay_u64(&xebec->callback_timer, XEBEC_TIME); - } else - fatal("Write sectors no DMA! - should never get here\n"); - break; - - case STATE_RECEIVED_DATA: - if (!(xebec->irq_dma_mask & DMA_ENA)) - memcpy(xebec->sector_buf, xebec->data, 512); - - { - off64_t addr; - - if (xebec_get_sector(xebec, &addr)) { - xebec_error(xebec, xebec->error); - xebec_complete(xebec); - return; - } - -// pclog("xebec Write %i,%i,%i %i\n", xebec->cylinder, xebec->head, xebec->sector, xebec->drive_sel); - - hdd_write_sectors(&drive->hdd_file, addr, 1, xebec->sector_buf); - } - - readflash_set(READFLASH_HDC, xebec->drive_sel); - - xebec_next_sector(xebec); - xebec->data_pos = 0; - xebec->sector_count = (xebec->sector_count - 1) & 0xff; - - if (xebec->sector_count) { - xebec->state = STATE_RECEIVE_DATA; - if (xebec->irq_dma_mask & DMA_ENA) - timer_set_delay_u64(&xebec->callback_timer, XEBEC_TIME); - else - xebec->status = STAT_BSY | STAT_REQ; - } else - xebec_complete(xebec); - break; - - default:fatal("CMD_WRITE_SECTORS: bad state %i\n", xebec->state); - } - break; - - case CMD_SEEK: - if (!drive->hdd_file.f) - xebec_error(xebec, ERR_NOT_READY); - else { - int cylinder = xebec->command[3] | ((xebec->command[2] & 0xc0) << 2); - - drive->current_cylinder = (cylinder >= drive->cfg_cyl) ? drive->cfg_cyl - 1 : cylinder; - - if (cylinder != drive->current_cylinder) - xebec_error(xebec, ERR_SEEK_ERROR); - } - xebec_complete(xebec); - break; - - case CMD_INIT_DRIVE_PARAMS: - switch (xebec->state) { - case STATE_START_COMMAND:xebec->state = STATE_RECEIVE_DATA; - xebec->data_pos = 0; - xebec->data_len = 8; - xebec->status = STAT_BSY | STAT_REQ; - break; - - case STATE_RECEIVED_DATA:drive->cfg_cyl = xebec->data[1] | (xebec->data[0] << 8); - drive->cfg_hpc = xebec->data[2]; - pclog("Drive %i: cylinders=%i, heads=%i\n", xebec->drive_sel, drive->cfg_cyl, drive->cfg_hpc); - xebec_complete(xebec); - break; - - default:fatal("CMD_INIT_DRIVE_PARAMS bad state %i\n", xebec->state); - } - break; - - case CMD_WRITE_SECTOR_BUFFER: - switch (xebec->state) { - case STATE_START_COMMAND:xebec->state = STATE_RECEIVE_DATA; - xebec->data_pos = 0; - xebec->data_len = 512; - if (xebec->irq_dma_mask & DMA_ENA) - timer_set_delay_u64(&xebec->callback_timer, XEBEC_TIME); - else - xebec->status = STAT_BSY | STAT_REQ; - break; - - case STATE_RECEIVE_DATA: - if (xebec->irq_dma_mask & DMA_ENA) { - xebec->status = STAT_BSY; - - for (; xebec->data_pos < 512; xebec->data_pos++) { - int val = dma_channel_read(3); - - if (val == DMA_NODATA) { - pclog("CMD_WRITE_SECTOR_BUFFER out of data!\n"); - xebec->status = STAT_BSY | STAT_CD | STAT_IO | STAT_REQ; - timer_set_delay_u64(&xebec->callback_timer, XEBEC_TIME); - return; - } - - xebec->data[xebec->data_pos] = val & 0xff; - } - - xebec->state = STATE_RECEIVED_DATA; - timer_set_delay_u64(&xebec->callback_timer, XEBEC_TIME); - } else - fatal("CMD_WRITE_SECTOR_BUFFER - should never get here!\n"); - break; - case STATE_RECEIVED_DATA:memcpy(xebec->sector_buf, xebec->data, 512); - xebec_complete(xebec); - break; - - default:fatal("CMD_WRITE_SECTOR_BUFFER bad state %i\n", xebec->state); - } - break; - - case CMD_BUFFER_DIAGNOSTIC: - case CMD_CONTROLLER_DIAGNOSTIC:xebec_complete(xebec); - break; - - case 0xfa:xebec_complete(xebec); - break; - - case CMD_DTC_SET_STEP_RATE:xebec_complete(xebec); - break; - - case CMD_DTC_GET_DRIVE_PARAMS: - switch (xebec->state) { - case STATE_START_COMMAND:xebec->state = STATE_SEND_DATA; - xebec->data_pos = 0; - xebec->data_len = 4; - xebec->status = STAT_BSY | STAT_IO | STAT_REQ; - memset(xebec->data, 0, 4); - xebec->data[0] = drive->hdd_file.tracks & 0xff; - xebec->data[1] = 17 | ((drive->hdd_file.tracks >> 2) & 0xc0); - xebec->data[2] = drive->hdd_file.hpc - 1; - pclog("Get drive params %02x %02x %02x %i\n", xebec->data[0], xebec->data[1], xebec->data[2], drive->hdd_file.tracks); - break; - - case STATE_SENT_DATA:xebec_complete(xebec); - break; - - default:fatal("CMD_INIT_DRIVE_PARAMS bad state %i\n", xebec->state); - } - break; - - case CMD_DTC_GET_GEOMETRY: - switch (xebec->state) { - case STATE_START_COMMAND:xebec->state = STATE_SEND_DATA; - xebec->data_pos = 0; - xebec->data_len = 16; - xebec->status = STAT_BSY | STAT_IO | STAT_REQ; - memset(xebec->data, 0, 16); - xebec->data[0x4] = drive->hdd_file.tracks & 0xff; - xebec->data[0x5] = (drive->hdd_file.tracks >> 8) & 0xff; - xebec->data[0xa] = drive->hdd_file.hpc; - break; - - case STATE_SENT_DATA:xebec_complete(xebec); - break; - } - break; - - case CMD_DTC_SET_GEOMETRY: - switch (xebec->state) { - case STATE_START_COMMAND:xebec->state = STATE_RECEIVE_DATA; - xebec->data_pos = 0; - xebec->data_len = 16; - xebec->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*/ - xebec_complete(xebec); - break; - } - break; - - default: - fatal("Unknown Xebec command - %02x %02x %02x %02x %02x %02x\n", - xebec->command[0], xebec->command[1], - xebec->command[2], xebec->command[3], - xebec->command[4], xebec->command[5]); - } + xebec_t *xebec = (xebec_t *)p; + mfm_drive_t *drive; + + xebec->drive_sel = (xebec->command[1] & 0x20) ? 1 : 0; + xebec->completion_byte = xebec->drive_sel & 0x20; + + drive = &xebec->drives[xebec->drive_sel]; + + switch (xebec->command[0]) { + case CMD_TEST_DRIVE_READY: + if (!drive->hdd_file.f) + xebec_error(xebec, ERR_NOT_READY); + xebec_complete(xebec); + break; + + case CMD_RECALIBRATE: + if (!drive->hdd_file.f) + xebec_error(xebec, ERR_NOT_READY); + else { + xebec->cylinder = 0; + drive->current_cylinder = 0; + } + xebec_complete(xebec); + break; + + case CMD_READ_STATUS: + switch (xebec->state) { + case STATE_START_COMMAND: + xebec->state = STATE_SEND_DATA; + xebec->data_pos = 0; + xebec->data_len = 4; + xebec->status = STAT_BSY | STAT_IO | STAT_REQ; + xebec->data[0] = xebec->error; + xebec->data[1] = xebec->drive_sel ? 0x20 : 0; + xebec->data[2] = xebec->data[3] = 0; + // pclog("Get status %02x\n", xebec->data[0]); + xebec->error = 0; + break; + + case STATE_SENT_DATA: + xebec_complete(xebec); + break; + } + break; + + case CMD_VERIFY_SECTORS: + switch (xebec->state) { + case STATE_START_COMMAND: + xebec->cylinder = xebec->command[3] | ((xebec->command[2] & 0xc0) << 2); + drive->current_cylinder = (xebec->cylinder >= drive->cfg_cyl) ? drive->cfg_cyl - 1 : xebec->cylinder; + xebec->head = xebec->command[1] & 0x1f; + xebec->sector = xebec->command[2] & 0x1f; + xebec->sector_count = xebec->command[4]; + do { + off64_t addr; + + // pclog("xebec Verify %i,%i,%i %i\n", xebec->cylinder, + // xebec->head, xebec->sector, xebec->sector_count); + if (xebec_get_sector(xebec, &addr)) { + pclog("xebec_get_sector failed\n"); + xebec_error(xebec, xebec->error); + xebec_complete(xebec); + return; + } + + xebec_next_sector(xebec); + + xebec->sector_count = (xebec->sector_count - 1) & 0xff; + } while (xebec->sector_count); + + xebec_complete(xebec); + + readflash_set(READFLASH_HDC, xebec->drive_sel); + break; + + default: + fatal("CMD_VERIFY_SECTORS: bad state %i\n", xebec->state); + } + break; + + case CMD_FORMAT_TRACK: { + off64_t addr; + + xebec->cylinder = xebec->command[3] | ((xebec->command[2] & 0xc0) << 2); + drive->current_cylinder = (xebec->cylinder >= drive->cfg_cyl) ? drive->cfg_cyl - 1 : xebec->cylinder; + xebec->head = xebec->command[1] & 0x1f; + // pclog("Format track %i,%i\n", xebec->cylinder, xebec->head); + + if (xebec_get_sector(xebec, &addr)) { + pclog("xebec_get_sector failed\n"); + xebec_error(xebec, xebec->error); + xebec_complete(xebec); + return; + } + + hdd_format_sectors(&drive->hdd_file, addr, 17); + + xebec_complete(xebec); + } break; + + case CMD_READ_SECTORS: + switch (xebec->state) { + case STATE_START_COMMAND: + xebec->cylinder = xebec->command[3] | ((xebec->command[2] & 0xc0) << 2); + drive->current_cylinder = (xebec->cylinder >= drive->cfg_cyl) ? drive->cfg_cyl - 1 : xebec->cylinder; + xebec->head = xebec->command[1] & 0x1f; + xebec->sector = xebec->command[2] & 0x1f; + xebec->sector_count = xebec->command[4]; + xebec->state = STATE_SEND_DATA; + xebec->data_pos = 0; + xebec->data_len = 512; + { + off64_t addr; + + if (xebec_get_sector(xebec, &addr)) { + xebec_error(xebec, xebec->error); + xebec_complete(xebec); + return; + } + // pclog("xebec Read %i,%i,%i\n", xebec->cylinder, xebec->head, + // xebec->sector); + + hdd_read_sectors(&drive->hdd_file, addr, 1, xebec->sector_buf); + readflash_set(READFLASH_HDC, xebec->drive_sel); + } + if (xebec->irq_dma_mask & DMA_ENA) + timer_set_delay_u64(&xebec->callback_timer, XEBEC_TIME); + else { + xebec->status = STAT_BSY | STAT_IO | STAT_REQ; + memcpy(xebec->data, xebec->sector_buf, 512); + } + break; + + case STATE_SEND_DATA: + xebec->status = STAT_BSY; + if (xebec->irq_dma_mask & DMA_ENA) { + for (; xebec->data_pos < 512; xebec->data_pos++) { + int val = dma_channel_write(3, xebec->sector_buf[xebec->data_pos]); + + if (val == DMA_NODATA) { + pclog("CMD_READ_SECTORS out of data!\n"); + xebec->status = STAT_BSY | STAT_CD | STAT_IO | STAT_REQ; + timer_set_delay_u64(&xebec->callback_timer, XEBEC_TIME); + return; + } + } + xebec->state = STATE_SENT_DATA; + timer_set_delay_u64(&xebec->callback_timer, XEBEC_TIME); + } else + fatal("Read sectors no DMA! - shouldn't get here\n"); + break; + + case STATE_SENT_DATA: + xebec_next_sector(xebec); + + xebec->data_pos = 0; + + xebec->sector_count = (xebec->sector_count - 1) & 0xff; + + if (xebec->sector_count) { + off64_t addr; + + if (xebec_get_sector(xebec, &addr)) { + xebec_error(xebec, xebec->error); + xebec_complete(xebec); + return; + } + + // pclog("xebec Read %i,%i,%i\n", xebec->cylinder, xebec->head, + // xebec->sector); + + hdd_read_sectors(&drive->hdd_file, addr, 1, xebec->sector_buf); + readflash_set(READFLASH_HDC, xebec->drive_sel); + + xebec->state = STATE_SEND_DATA; + + if (xebec->irq_dma_mask & DMA_ENA) + timer_set_delay_u64(&xebec->callback_timer, XEBEC_TIME); + else { + xebec->status = STAT_BSY | STAT_IO | STAT_REQ; + memcpy(xebec->data, xebec->sector_buf, 512); + } + } else + xebec_complete(xebec); + break; + + default: + fatal("CMD_READ_SECTORS: bad state %i\n", xebec->state); + } + break; + + case CMD_WRITE_SECTORS: + switch (xebec->state) { + case STATE_START_COMMAND: + xebec->cylinder = xebec->command[3] | ((xebec->command[2] & 0xc0) << 2); + drive->current_cylinder = (xebec->cylinder >= drive->cfg_cyl) ? drive->cfg_cyl - 1 : xebec->cylinder; + xebec->head = xebec->command[1] & 0x1f; + xebec->sector = xebec->command[2] & 0x1f; + xebec->sector_count = xebec->command[4]; + xebec->state = STATE_RECEIVE_DATA; + xebec->data_pos = 0; + xebec->data_len = 512; + if (xebec->irq_dma_mask & DMA_ENA) + timer_set_delay_u64(&xebec->callback_timer, XEBEC_TIME); + else + xebec->status = STAT_BSY | STAT_REQ; + break; + + case STATE_RECEIVE_DATA: + xebec->status = STAT_BSY; + if (xebec->irq_dma_mask & DMA_ENA) { + for (; xebec->data_pos < 512; xebec->data_pos++) { + int val = dma_channel_read(3); + + if (val == DMA_NODATA) { + pclog("CMD_WRITE_SECTORS out of data!\n"); + xebec->status = STAT_BSY | STAT_CD | STAT_IO | STAT_REQ; + timer_set_delay_u64(&xebec->callback_timer, XEBEC_TIME); + return; + } + + xebec->sector_buf[xebec->data_pos] = val & 0xff; + } + + xebec->state = STATE_RECEIVED_DATA; + timer_set_delay_u64(&xebec->callback_timer, XEBEC_TIME); + } else + fatal("Write sectors no DMA! - should never get here\n"); + break; + + case STATE_RECEIVED_DATA: + if (!(xebec->irq_dma_mask & DMA_ENA)) + memcpy(xebec->sector_buf, xebec->data, 512); + + { + off64_t addr; + + if (xebec_get_sector(xebec, &addr)) { + xebec_error(xebec, xebec->error); + xebec_complete(xebec); + return; + } + + // pclog("xebec Write %i,%i,%i %i\n", xebec->cylinder, xebec->head, + // xebec->sector, xebec->drive_sel); + + hdd_write_sectors(&drive->hdd_file, addr, 1, xebec->sector_buf); + } + + readflash_set(READFLASH_HDC, xebec->drive_sel); + + xebec_next_sector(xebec); + xebec->data_pos = 0; + xebec->sector_count = (xebec->sector_count - 1) & 0xff; + + if (xebec->sector_count) { + xebec->state = STATE_RECEIVE_DATA; + if (xebec->irq_dma_mask & DMA_ENA) + timer_set_delay_u64(&xebec->callback_timer, XEBEC_TIME); + else + xebec->status = STAT_BSY | STAT_REQ; + } else + xebec_complete(xebec); + break; + + default: + fatal("CMD_WRITE_SECTORS: bad state %i\n", xebec->state); + } + break; + + case CMD_SEEK: + if (!drive->hdd_file.f) + xebec_error(xebec, ERR_NOT_READY); + else { + int cylinder = xebec->command[3] | ((xebec->command[2] & 0xc0) << 2); + + drive->current_cylinder = (cylinder >= drive->cfg_cyl) ? drive->cfg_cyl - 1 : cylinder; + + if (cylinder != drive->current_cylinder) + xebec_error(xebec, ERR_SEEK_ERROR); + } + xebec_complete(xebec); + break; + + case CMD_INIT_DRIVE_PARAMS: + switch (xebec->state) { + case STATE_START_COMMAND: + xebec->state = STATE_RECEIVE_DATA; + xebec->data_pos = 0; + xebec->data_len = 8; + xebec->status = STAT_BSY | STAT_REQ; + break; + + case STATE_RECEIVED_DATA: + drive->cfg_cyl = xebec->data[1] | (xebec->data[0] << 8); + drive->cfg_hpc = xebec->data[2]; + pclog("Drive %i: cylinders=%i, heads=%i\n", xebec->drive_sel, drive->cfg_cyl, drive->cfg_hpc); + xebec_complete(xebec); + break; + + default: + fatal("CMD_INIT_DRIVE_PARAMS bad state %i\n", xebec->state); + } + break; + + case CMD_WRITE_SECTOR_BUFFER: + switch (xebec->state) { + case STATE_START_COMMAND: + xebec->state = STATE_RECEIVE_DATA; + xebec->data_pos = 0; + xebec->data_len = 512; + if (xebec->irq_dma_mask & DMA_ENA) + timer_set_delay_u64(&xebec->callback_timer, XEBEC_TIME); + else + xebec->status = STAT_BSY | STAT_REQ; + break; + + case STATE_RECEIVE_DATA: + if (xebec->irq_dma_mask & DMA_ENA) { + xebec->status = STAT_BSY; + + for (; xebec->data_pos < 512; xebec->data_pos++) { + int val = dma_channel_read(3); + + if (val == DMA_NODATA) { + pclog("CMD_WRITE_SECTOR_BUFFER out of data!\n"); + xebec->status = STAT_BSY | STAT_CD | STAT_IO | STAT_REQ; + timer_set_delay_u64(&xebec->callback_timer, XEBEC_TIME); + return; + } + + xebec->data[xebec->data_pos] = val & 0xff; + } + + xebec->state = STATE_RECEIVED_DATA; + timer_set_delay_u64(&xebec->callback_timer, XEBEC_TIME); + } else + fatal("CMD_WRITE_SECTOR_BUFFER - should never get here!\n"); + break; + case STATE_RECEIVED_DATA: + memcpy(xebec->sector_buf, xebec->data, 512); + xebec_complete(xebec); + break; + + default: + fatal("CMD_WRITE_SECTOR_BUFFER bad state %i\n", xebec->state); + } + break; + + case CMD_BUFFER_DIAGNOSTIC: + case CMD_CONTROLLER_DIAGNOSTIC: + xebec_complete(xebec); + break; + + case 0xfa: + xebec_complete(xebec); + break; + + case CMD_DTC_SET_STEP_RATE: + xebec_complete(xebec); + break; + + case CMD_DTC_GET_DRIVE_PARAMS: + switch (xebec->state) { + case STATE_START_COMMAND: + xebec->state = STATE_SEND_DATA; + xebec->data_pos = 0; + xebec->data_len = 4; + xebec->status = STAT_BSY | STAT_IO | STAT_REQ; + memset(xebec->data, 0, 4); + xebec->data[0] = drive->hdd_file.tracks & 0xff; + xebec->data[1] = 17 | ((drive->hdd_file.tracks >> 2) & 0xc0); + xebec->data[2] = drive->hdd_file.hpc - 1; + pclog("Get drive params %02x %02x %02x %i\n", xebec->data[0], xebec->data[1], xebec->data[2], + drive->hdd_file.tracks); + break; + + case STATE_SENT_DATA: + xebec_complete(xebec); + break; + + default: + fatal("CMD_INIT_DRIVE_PARAMS bad state %i\n", xebec->state); + } + break; + + case CMD_DTC_GET_GEOMETRY: + switch (xebec->state) { + case STATE_START_COMMAND: + xebec->state = STATE_SEND_DATA; + xebec->data_pos = 0; + xebec->data_len = 16; + xebec->status = STAT_BSY | STAT_IO | STAT_REQ; + memset(xebec->data, 0, 16); + xebec->data[0x4] = drive->hdd_file.tracks & 0xff; + xebec->data[0x5] = (drive->hdd_file.tracks >> 8) & 0xff; + xebec->data[0xa] = drive->hdd_file.hpc; + break; + + case STATE_SENT_DATA: + xebec_complete(xebec); + break; + } + break; + + case CMD_DTC_SET_GEOMETRY: + switch (xebec->state) { + case STATE_START_COMMAND: + xebec->state = STATE_RECEIVE_DATA; + xebec->data_pos = 0; + xebec->data_len = 16; + xebec->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*/ + xebec_complete(xebec); + break; + } + break; + + default: + fatal("Unknown Xebec command - %02x %02x %02x %02x %02x %02x\n", xebec->command[0], xebec->command[1], + xebec->command[2], xebec->command[3], xebec->command[4], xebec->command[5]); + } } static struct { - int tracks, hpc; -} xebec_hd_types[4] = - { - {306, 4}, /*Type 0*/ - {612, 4}, /*Type 16*/ - {615, 4}, /*Type 2*/ - {306, 8} /*Type 13*/ - }; + int tracks, hpc; +} xebec_hd_types[4] = { + {306, 4}, /*Type 0*/ + {612, 4}, /*Type 16*/ + {615, 4}, /*Type 2*/ + {306, 8} /*Type 13*/ +}; static void xebec_set_switches(xebec_t *xebec) { - int c, d; + int c, d; - xebec->switches = 0; + xebec->switches = 0; - for (d = 0; d < 2; d++) { - mfm_drive_t *drive = &xebec->drives[d]; + for (d = 0; d < 2; d++) { + mfm_drive_t *drive = &xebec->drives[d]; - if (!drive->hdd_file.f) - continue; + if (!drive->hdd_file.f) + continue; - for (c = 0; c < 4; c++) { - if (drive->hdd_file.spt == 17 && - drive->hdd_file.hpc == xebec_hd_types[c].hpc && - drive->hdd_file.tracks == xebec_hd_types[c].tracks) { - xebec->switches |= (c << (d ? 0 : 2)); - break; - } - } + for (c = 0; c < 4; c++) { + if (drive->hdd_file.spt == 17 && drive->hdd_file.hpc == xebec_hd_types[c].hpc && + drive->hdd_file.tracks == xebec_hd_types[c].tracks) { + xebec->switches |= (c << (d ? 0 : 2)); + break; + } + } - if (c == 4) - warning("Drive %c: has format not supported by Fixed Disk Adapter", d ? 'D' : 'C'); - } + if (c == 4) + warning("Drive %c: has format not supported by Fixed Disk Adapter", d ? 'D' : 'C'); + } } static void *xebec_init() { - xebec_t *xebec = malloc(sizeof(xebec_t)); - memset(xebec, 0, sizeof(xebec_t)); + xebec_t *xebec = malloc(sizeof(xebec_t)); + memset(xebec, 0, sizeof(xebec_t)); - hdd_load(&xebec->drives[0].hdd_file, 0, ide_fn[0]); - hdd_load(&xebec->drives[1].hdd_file, 1, ide_fn[1]); - xebec_set_switches(xebec); + hdd_load(&xebec->drives[0].hdd_file, 0, ide_fn[0]); + hdd_load(&xebec->drives[1].hdd_file, 1, ide_fn[1]); + xebec_set_switches(xebec); - rom_init(&xebec->bios_rom, "ibm_xebec_62x0822_1985.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&xebec->bios_rom, "ibm_xebec_62x0822_1985.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); - io_sethandler(0x0320, 0x0004, xebec_read, NULL, NULL, xebec_write, NULL, NULL, xebec); + io_sethandler(0x0320, 0x0004, xebec_read, NULL, NULL, xebec_write, NULL, NULL, xebec); - timer_add(&xebec->callback_timer, xebec_callback, xebec, 0); + timer_add(&xebec->callback_timer, xebec_callback, xebec, 0); - return xebec; + return xebec; } static void xebec_close(void *p) { - xebec_t *xebec = (xebec_t *)p; + xebec_t *xebec = (xebec_t *)p; - hdd_close(&xebec->drives[0].hdd_file); - hdd_close(&xebec->drives[1].hdd_file); + hdd_close(&xebec->drives[0].hdd_file); + hdd_close(&xebec->drives[1].hdd_file); - free(xebec); + free(xebec); } -static int xebec_available() { - return rom_present("ibm_xebec_62x0822_1985.bin"); -} +static int xebec_available() { return rom_present("ibm_xebec_62x0822_1985.bin"); } -device_t mfm_xebec_device = - { - "IBM PC Fixed Disk Adapter", - 0, - xebec_init, - xebec_close, - xebec_available, - NULL, - NULL, - NULL, - NULL - }; +device_t mfm_xebec_device = {"IBM PC Fixed Disk Adapter", 0, xebec_init, xebec_close, xebec_available, NULL, NULL, NULL, NULL}; static void *dtc_5150x_init() { - xebec_t *xebec = malloc(sizeof(xebec_t)); - memset(xebec, 0, sizeof(xebec_t)); + xebec_t *xebec = malloc(sizeof(xebec_t)); + memset(xebec, 0, sizeof(xebec_t)); - hdd_load(&xebec->drives[0].hdd_file, 0, ide_fn[0]); - hdd_load(&xebec->drives[1].hdd_file, 1, ide_fn[1]); - xebec->switches = 0xff; + hdd_load(&xebec->drives[0].hdd_file, 0, ide_fn[0]); + hdd_load(&xebec->drives[1].hdd_file, 1, ide_fn[1]); + xebec->switches = 0xff; - xebec->drives[0].cfg_cyl = xebec->drives[0].hdd_file.tracks; - xebec->drives[0].cfg_hpc = xebec->drives[0].hdd_file.hpc; - xebec->drives[1].cfg_cyl = xebec->drives[1].hdd_file.tracks; - xebec->drives[1].cfg_hpc = xebec->drives[1].hdd_file.hpc; + xebec->drives[0].cfg_cyl = xebec->drives[0].hdd_file.tracks; + xebec->drives[0].cfg_hpc = xebec->drives[0].hdd_file.hpc; + xebec->drives[1].cfg_cyl = xebec->drives[1].hdd_file.tracks; + xebec->drives[1].cfg_hpc = xebec->drives[1].hdd_file.hpc; - rom_init(&xebec->bios_rom, "dtc_cxd21a.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&xebec->bios_rom, "dtc_cxd21a.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); - io_sethandler(0x0320, 0x0004, xebec_read, NULL, NULL, xebec_write, NULL, NULL, xebec); + io_sethandler(0x0320, 0x0004, xebec_read, NULL, NULL, xebec_write, NULL, NULL, xebec); - timer_add(&xebec->callback_timer, xebec_callback, xebec, 0); + timer_add(&xebec->callback_timer, xebec_callback, xebec, 0); - return xebec; -} -static int dtc_5150x_available() { - return rom_present("dtc_cxd21a.bin"); + return xebec; } +static int dtc_5150x_available() { return rom_present("dtc_cxd21a.bin"); } -device_t dtc_5150x_device = - { - "DTC 5150X", - 0, - dtc_5150x_init, - xebec_close, - dtc_5150x_available, - NULL, - NULL, - NULL, - NULL - }; +device_t dtc_5150x_device = {"DTC 5150X", 0, dtc_5150x_init, xebec_close, dtc_5150x_available, NULL, NULL, NULL, NULL}; diff --git a/src/models/82091aa.c b/src/models/82091aa.c index c7c7ae04..af7c5be5 100644 --- a/src/models/82091aa.c +++ b/src/models/82091aa.c @@ -5,31 +5,31 @@ #include "lpt.h" #include "serial.h" -#define AIP_AIPID 0x00 -#define AIP_AIPREV 0x01 +#define AIP_AIPID 0x00 +#define AIP_AIPREV 0x01 #define AIP_AIPCFG1 0x02 #define AIP_AIPCFG2 0x03 -#define AIP_FCFG1 0x10 -#define AIP_FCFG2 0x11 -#define AIP_PCFG1 0x20 -#define AIP_PCFG2 0x21 -#define AIP_SACFG1 0x30 -#define AIP_SACFG2 0x31 -#define AIP_SBCFG1 0x40 -#define AIP_SBCFG2 0x41 -#define AIP_IDECFG 0x50 +#define AIP_FCFG1 0x10 +#define AIP_FCFG2 0x11 +#define AIP_PCFG1 0x20 +#define AIP_PCFG2 0x21 +#define AIP_SACFG1 0x30 +#define AIP_SACFG2 0x31 +#define AIP_SBCFG1 0x40 +#define AIP_SBCFG2 0x41 +#define AIP_IDECFG 0x50 -#define FCFG1_FDC_ENA (1 << 0) +#define FCFG1_FDC_ENA (1 << 0) #define FCFG1_FDC_ADDR (1 << 1) -#define PCFG1_PP_ENA (1 << 0) -#define PCFG1_PP_ADDR (3 << 1) +#define PCFG1_PP_ENA (1 << 0) +#define PCFG1_PP_ADDR (3 << 1) #define PCFG1_PP_ADDR_378 (0 << 1) #define PCFG1_PP_ADDR_278 (1 << 1) #define PCFG1_PP_ADDR_3BC (2 << 1) -#define SxCFG1_ENA (1 << 0) -#define SxCFG1_ADDR (7 << 1) +#define SxCFG1_ENA (1 << 0) +#define SxCFG1_ADDR (7 << 1) #define SxCFG1_ADDR_3F8 (0 << 1) #define SxCFG1_ADDR_2F8 (1 << 1) #define SxCFG1_ADDR_220 (2 << 1) @@ -38,151 +38,185 @@ #define SxCFG1_ADDR_2E8 (5 << 1) #define SxCFG1_ADDR_338 (6 << 1) #define SxCFG1_ADDR_3E8 (7 << 1) -#define SxCFG1_IRQ (1 << 4) -#define SxCFG1_IRQ_3 (0 << 4) -#define SxCFG1_IRQ_4 (1 << 4) +#define SxCFG1_IRQ (1 << 4) +#define SxCFG1_IRQ_3 (0 << 4) +#define SxCFG1_IRQ_4 (1 << 4) static struct { - int idx; - uint8_t regs[256]; + int idx; + uint8_t regs[256]; } aip; static uint8_t aip_read(uint16_t addr, void *p) { - uint8_t temp; + uint8_t temp; - if (!(addr & 1)) - temp = aip.idx; - else - temp = aip.regs[aip.idx]; + if (!(addr & 1)) + temp = aip.idx; + else + temp = aip.regs[aip.idx]; -// pclog("aip_read: addr=%04x val=%02x\n", addr, temp); - return temp; + // pclog("aip_read: addr=%04x val=%02x\n", addr, temp); + return temp; } static void aip_write(uint16_t addr, uint8_t val, void *p) { -// pclog("aip_write: addr=%04x val=%02x\n", addr, val); - if (!(addr & 1)) - aip.idx = val; - else { -// pclog("AIP register write: idx=%02x val=%02x\n", aip.idx, val); - switch (aip.idx) { - case AIP_AIPCFG1:aip.regs[AIP_AIPCFG1] = (val & ~0x4e) | (aip.regs[AIP_AIPCFG1] & 0x48); - break; - case AIP_AIPCFG2:aip.regs[AIP_AIPCFG2] = val & 0xf8; - break; - case AIP_FCFG1:aip.regs[AIP_FCFG1] = val & 0x83; - fdc_remove(); - if ((aip.regs[AIP_FCFG1] & FCFG1_FDC_ENA) && !(aip.regs[AIP_FCFG1] & FCFG1_FDC_ADDR)) - fdc_add(); - break; - case AIP_FCFG2:aip.regs[AIP_FCFG2] = (val & 0x0d) | (aip.regs[AIP_FCFG2] & 0x02); - break; - case AIP_PCFG1:aip.regs[AIP_PCFG1] = val & 0xef; - lpt1_remove(); - if (aip.regs[AIP_PCFG1] & PCFG1_PP_ENA) { - switch (aip.regs[AIP_PCFG1] & PCFG1_PP_ADDR) { - case PCFG1_PP_ADDR_378:lpt1_init(0x378); - break; - case PCFG1_PP_ADDR_278:lpt1_init(0x278); - break; - case PCFG1_PP_ADDR_3BC:lpt1_init(0x3bc); - break; - } - } - break; - case AIP_PCFG2:aip.regs[AIP_PCFG2] = (val & 0x0d) | (aip.regs[AIP_PCFG2] & 0x22); - break; - case AIP_SACFG1:aip.regs[AIP_SACFG1] = val & 0x9f; - serial1_remove(); - if (aip.regs[AIP_SACFG1] & SxCFG1_ENA) { - uint16_t base = 0; - int irq = 0; + // pclog("aip_write: addr=%04x val=%02x\n", addr, val); + if (!(addr & 1)) + aip.idx = val; + else { + // pclog("AIP register write: idx=%02x val=%02x\n", aip.idx, val); + switch (aip.idx) { + case AIP_AIPCFG1: + aip.regs[AIP_AIPCFG1] = (val & ~0x4e) | (aip.regs[AIP_AIPCFG1] & 0x48); + break; + case AIP_AIPCFG2: + aip.regs[AIP_AIPCFG2] = val & 0xf8; + break; + case AIP_FCFG1: + aip.regs[AIP_FCFG1] = val & 0x83; + fdc_remove(); + if ((aip.regs[AIP_FCFG1] & FCFG1_FDC_ENA) && !(aip.regs[AIP_FCFG1] & FCFG1_FDC_ADDR)) + fdc_add(); + break; + case AIP_FCFG2: + aip.regs[AIP_FCFG2] = (val & 0x0d) | (aip.regs[AIP_FCFG2] & 0x02); + break; + case AIP_PCFG1: + aip.regs[AIP_PCFG1] = val & 0xef; + lpt1_remove(); + if (aip.regs[AIP_PCFG1] & PCFG1_PP_ENA) { + switch (aip.regs[AIP_PCFG1] & PCFG1_PP_ADDR) { + case PCFG1_PP_ADDR_378: + lpt1_init(0x378); + break; + case PCFG1_PP_ADDR_278: + lpt1_init(0x278); + break; + case PCFG1_PP_ADDR_3BC: + lpt1_init(0x3bc); + break; + } + } + break; + case AIP_PCFG2: + aip.regs[AIP_PCFG2] = (val & 0x0d) | (aip.regs[AIP_PCFG2] & 0x22); + break; + case AIP_SACFG1: + aip.regs[AIP_SACFG1] = val & 0x9f; + serial1_remove(); + if (aip.regs[AIP_SACFG1] & SxCFG1_ENA) { + uint16_t base = 0; + int irq = 0; - switch (aip.regs[AIP_SACFG1] & SxCFG1_ADDR) { - case SxCFG1_ADDR_3F8: base = 0x3f8; - break; - case SxCFG1_ADDR_2F8: base = 0x2f8; - break; - case SxCFG1_ADDR_220: base = 0x220; - break; - case SxCFG1_ADDR_228: base = 0x228; - break; - case SxCFG1_ADDR_238: base = 0x238; - break; - case SxCFG1_ADDR_2E8: base = 0x2e8; - break; - case SxCFG1_ADDR_338: base = 0x338; - break; - case SxCFG1_ADDR_3E8: base = 0x3e8; - break; - } - switch (aip.regs[AIP_SACFG1] & SxCFG1_IRQ) { - case SxCFG1_IRQ_3: irq = 3; - break; - case SxCFG1_IRQ_4: irq = 4; - break; - } - serial1_set(base, irq); - } - break; - case AIP_SACFG2:aip.regs[AIP_SACFG2] = (val & 0x01d) | (aip.regs[AIP_SACFG2] & 0x02); - break; - case AIP_SBCFG1:aip.regs[AIP_SBCFG1] = val & 0x9f; - serial2_remove(); - if (aip.regs[AIP_SBCFG1] & SxCFG1_ENA) { - uint16_t base = 0; - int irq = 0; + switch (aip.regs[AIP_SACFG1] & SxCFG1_ADDR) { + case SxCFG1_ADDR_3F8: + base = 0x3f8; + break; + case SxCFG1_ADDR_2F8: + base = 0x2f8; + break; + case SxCFG1_ADDR_220: + base = 0x220; + break; + case SxCFG1_ADDR_228: + base = 0x228; + break; + case SxCFG1_ADDR_238: + base = 0x238; + break; + case SxCFG1_ADDR_2E8: + base = 0x2e8; + break; + case SxCFG1_ADDR_338: + base = 0x338; + break; + case SxCFG1_ADDR_3E8: + base = 0x3e8; + break; + } + switch (aip.regs[AIP_SACFG1] & SxCFG1_IRQ) { + case SxCFG1_IRQ_3: + irq = 3; + break; + case SxCFG1_IRQ_4: + irq = 4; + break; + } + serial1_set(base, irq); + } + break; + case AIP_SACFG2: + aip.regs[AIP_SACFG2] = (val & 0x01d) | (aip.regs[AIP_SACFG2] & 0x02); + break; + case AIP_SBCFG1: + aip.regs[AIP_SBCFG1] = val & 0x9f; + serial2_remove(); + if (aip.regs[AIP_SBCFG1] & SxCFG1_ENA) { + uint16_t base = 0; + int irq = 0; - switch (aip.regs[AIP_SBCFG1] & SxCFG1_ADDR) { - case SxCFG1_ADDR_3F8: base = 0x3f8; - break; - case SxCFG1_ADDR_2F8: base = 0x2f8; - break; - case SxCFG1_ADDR_220: base = 0x220; - break; - case SxCFG1_ADDR_228: base = 0x228; - break; - case SxCFG1_ADDR_238: base = 0x238; - break; - case SxCFG1_ADDR_2E8: base = 0x2e8; - break; - case SxCFG1_ADDR_338: base = 0x338; - break; - case SxCFG1_ADDR_3E8: base = 0x3e8; - break; - } - switch (aip.regs[AIP_SBCFG1] & SxCFG1_IRQ) { - case SxCFG1_IRQ_3: irq = 3; - break; - case SxCFG1_IRQ_4: irq = 4; - break; - } - serial2_set(base, irq); - } - break; - case AIP_SBCFG2:aip.regs[AIP_SACFG2] = (val & 0x01d) | (aip.regs[AIP_SACFG2] & 0x02); - break; - case AIP_IDECFG:aip.regs[AIP_IDECFG] = val & 0x07; - break; - } - } + switch (aip.regs[AIP_SBCFG1] & SxCFG1_ADDR) { + case SxCFG1_ADDR_3F8: + base = 0x3f8; + break; + case SxCFG1_ADDR_2F8: + base = 0x2f8; + break; + case SxCFG1_ADDR_220: + base = 0x220; + break; + case SxCFG1_ADDR_228: + base = 0x228; + break; + case SxCFG1_ADDR_238: + base = 0x238; + break; + case SxCFG1_ADDR_2E8: + base = 0x2e8; + break; + case SxCFG1_ADDR_338: + base = 0x338; + break; + case SxCFG1_ADDR_3E8: + base = 0x3e8; + break; + } + switch (aip.regs[AIP_SBCFG1] & SxCFG1_IRQ) { + case SxCFG1_IRQ_3: + irq = 3; + break; + case SxCFG1_IRQ_4: + irq = 4; + break; + } + serial2_set(base, irq); + } + break; + case AIP_SBCFG2: + aip.regs[AIP_SACFG2] = (val & 0x01d) | (aip.regs[AIP_SACFG2] & 0x02); + break; + case AIP_IDECFG: + aip.regs[AIP_IDECFG] = val & 0x07; + break; + } + } } void aip_82091aa_init(uint16_t base) { - io_sethandler(base, 0x0002, aip_read, NULL, NULL, aip_write, NULL, NULL, NULL); + io_sethandler(base, 0x0002, aip_read, NULL, NULL, aip_write, NULL, NULL, NULL); - memset(&aip.regs, 0xff, sizeof(aip.regs)); - aip.regs[AIP_AIPID] = 0xa0; - aip.regs[AIP_AIPREV] = 0x00; - aip.regs[AIP_AIPCFG1] = 0x40; - aip.regs[AIP_AIPCFG2] = 0x00; - aip.regs[AIP_FCFG1] = 0x01; - aip.regs[AIP_FCFG2] = 0x00; - aip.regs[AIP_PCFG1] = 0x00; - aip.regs[AIP_PCFG2] = 0x00; - aip.regs[AIP_SACFG1] = 0x00; - aip.regs[AIP_SACFG2] = 0x02; - aip.regs[AIP_SBCFG1] = 0x00; - aip.regs[AIP_SBCFG2] = 0x02; - aip.regs[AIP_IDECFG] = 0x01; + memset(&aip.regs, 0xff, sizeof(aip.regs)); + aip.regs[AIP_AIPID] = 0xa0; + aip.regs[AIP_AIPREV] = 0x00; + aip.regs[AIP_AIPCFG1] = 0x40; + aip.regs[AIP_AIPCFG2] = 0x00; + aip.regs[AIP_FCFG1] = 0x01; + aip.regs[AIP_FCFG2] = 0x00; + aip.regs[AIP_PCFG1] = 0x00; + aip.regs[AIP_PCFG2] = 0x00; + aip.regs[AIP_SACFG1] = 0x00; + aip.regs[AIP_SACFG2] = 0x02; + aip.regs[AIP_SBCFG1] = 0x00; + aip.regs[AIP_SBCFG2] = 0x02; + aip.regs[AIP_IDECFG] = 0x01; } diff --git a/src/models/acc2036.c b/src/models/acc2036.c index f517e141..c62feb69 100644 --- a/src/models/acc2036.c +++ b/src/models/acc2036.c @@ -4,75 +4,85 @@ #include "mem.h" static struct { - int reg_idx; - uint8_t regs[256]; + int reg_idx; + uint8_t regs[256]; } acc2036; static void acc2036_shadow_recalc() { - if (acc2036.regs[0x2c] & 8) { - switch (acc2036.regs[0x22] & 3) { - case 0:mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - break; - case 1:mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); - break; - case 2:mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); - break; - case 3:mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - break; - } - } else - mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + if (acc2036.regs[0x2c] & 8) { + switch (acc2036.regs[0x22] & 3) { + case 0: + mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + break; + case 1: + mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); + break; + case 2: + mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); + break; + case 3: + mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + break; + } + } else + mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - if (acc2036.regs[0x2c] & 4) { - switch (acc2036.regs[0x22] & 3) { - case 0:mem_set_mem_state(0xe0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - break; - case 1:mem_set_mem_state(0xe0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); - break; - case 2:mem_set_mem_state(0xe0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); - break; - case 3:mem_set_mem_state(0xe0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - break; - } - } else - mem_set_mem_state(0xe0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + if (acc2036.regs[0x2c] & 4) { + switch (acc2036.regs[0x22] & 3) { + case 0: + mem_set_mem_state(0xe0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + break; + case 1: + mem_set_mem_state(0xe0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); + break; + case 2: + mem_set_mem_state(0xe0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); + break; + case 3: + mem_set_mem_state(0xe0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + break; + } + } else + mem_set_mem_state(0xe0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); } static void acc2036_write(uint16_t addr, uint8_t val, void *p) { - if (!(addr & 1)) - acc2036.reg_idx = val; - else { - acc2036.regs[acc2036.reg_idx] = val; -// pclog("Write ACC2036 R%02x %02x %04x:%04x %i\n", acc2036.reg_idx, val, CS,cpu_state.pc, ins); + if (!(addr & 1)) + acc2036.reg_idx = val; + else { + acc2036.regs[acc2036.reg_idx] = val; + // pclog("Write ACC2036 R%02x %02x %04x:%04x %i\n", acc2036.reg_idx, val, CS,cpu_state.pc, ins); - switch (acc2036.reg_idx) { - case 0x22: - case 0x2c:acc2036_shadow_recalc(); - break; + switch (acc2036.reg_idx) { + case 0x22: + case 0x2c: + acc2036_shadow_recalc(); + break; - case 0x23:mem_mapping_disable(&ram_remapped_mapping); - if (val & 0x10) { - if (acc2036.regs[0x2c] & 0xc) - mem_remap_top_256k(); - else - mem_remap_top_384k(); - } - break; - } - } + case 0x23: + mem_mapping_disable(&ram_remapped_mapping); + if (val & 0x10) { + if (acc2036.regs[0x2c] & 0xc) + mem_remap_top_256k(); + else + mem_remap_top_384k(); + } + break; + } + } } static uint8_t acc2036_read(uint16_t addr, void *p) { - if (!(addr & 1)) - return acc2036.reg_idx; + if (!(addr & 1)) + return acc2036.reg_idx; - if (acc2036.reg_idx >= 0xbc) - return 0xff; + if (acc2036.reg_idx >= 0xbc) + return 0xff; - return acc2036.regs[acc2036.reg_idx]; + return acc2036.regs[acc2036.reg_idx]; } void acc2036_init() { - memset(&acc2036, 0, sizeof(acc2036)); - io_sethandler(0x00f2, 0x0002, acc2036_read, NULL, NULL, acc2036_write, NULL, NULL, NULL); + memset(&acc2036, 0, sizeof(acc2036)); + io_sethandler(0x00f2, 0x0002, acc2036_read, NULL, NULL, acc2036_write, NULL, NULL, NULL); } diff --git a/src/models/acc2168.c b/src/models/acc2168.c index 69b948c8..9970c4a7 100644 --- a/src/models/acc2168.c +++ b/src/models/acc2168.c @@ -6,87 +6,92 @@ #include "x86.h" static struct { - int reg_idx; - uint8_t regs[256]; - uint8_t port_62; + int reg_idx; + uint8_t regs[256]; + uint8_t port_62; } acc2168; static void acc2168_shadow_recalc() { - if (acc2168.regs[0x02] & 8) { - switch (acc2168.regs[0x02] & 0x30) { - case 0x00:mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); - break; - case 0x10:mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - break; - case 0x20:mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - break; - case 0x30:mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); - break; - } - } else - mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + if (acc2168.regs[0x02] & 8) { + switch (acc2168.regs[0x02] & 0x30) { + case 0x00: + mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); + break; + case 0x10: + mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + break; + case 0x20: + mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + break; + case 0x30: + mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); + break; + } + } else + mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - if (acc2168.regs[0x02] & 4) { - switch (acc2168.regs[0x02] & 0x30) { - case 0x00:mem_set_mem_state(0xe0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); - break; - case 0x10:mem_set_mem_state(0xe0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - break; - case 0x20:mem_set_mem_state(0xe0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - break; - case 0x30:mem_set_mem_state(0xe0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); - break; - } - } else - mem_set_mem_state(0xe0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + if (acc2168.regs[0x02] & 4) { + switch (acc2168.regs[0x02] & 0x30) { + case 0x00: + mem_set_mem_state(0xe0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); + break; + case 0x10: + mem_set_mem_state(0xe0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + break; + case 0x20: + mem_set_mem_state(0xe0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + break; + case 0x30: + mem_set_mem_state(0xe0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); + break; + } + } else + mem_set_mem_state(0xe0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); } static void acc2168_write(uint16_t addr, uint8_t val, void *p) { -// pclog("acc2168_write: addr=%04x val=%02x\n", addr, val); - if (!(addr & 1)) - acc2168.reg_idx = val; - else { - acc2168.regs[acc2168.reg_idx] = val; -// pclog("acc2168_write: idx=%02x val=%02x %04x:%04x\n", acc2168.reg_idx, val, CS,cpu_state.pc); + // pclog("acc2168_write: addr=%04x val=%02x\n", addr, val); + if (!(addr & 1)) + acc2168.reg_idx = val; + else { + acc2168.regs[acc2168.reg_idx] = val; + // pclog("acc2168_write: idx=%02x val=%02x %04x:%04x\n", acc2168.reg_idx, val, CS,cpu_state.pc); - switch (acc2168.reg_idx) { - case 0x02:acc2168_shadow_recalc(); - break; - } - } + switch (acc2168.reg_idx) { + case 0x02: + acc2168_shadow_recalc(); + break; + } + } } static uint8_t acc2168_read(uint16_t addr, void *p) { - if (!(addr & 1)) - return acc2168.reg_idx; + if (!(addr & 1)) + return acc2168.reg_idx; -// pclog("acc2168_read: idx=%02x val=%02x\n", acc2168.reg_idx, acc2168.regs[acc2168.reg_idx]); - return acc2168.regs[acc2168.reg_idx]; + // pclog("acc2168_read: idx=%02x val=%02x\n", acc2168.reg_idx, acc2168.regs[acc2168.reg_idx]); + return acc2168.regs[acc2168.reg_idx]; } -static uint8_t port78_read(uint16_t addr, void *p) { - return 0; -} +static uint8_t port78_read(uint16_t addr, void *p) { return 0; } -static uint8_t port92_read(uint16_t addr, void *p) { - return acc2168.port_62 | 0xfc; -} +static uint8_t port92_read(uint16_t addr, void *p) { return acc2168.port_62 | 0xfc; } static void port92_write(uint16_t addr, uint8_t val, void *p) { - if ((mem_a20_alt ^ val) & 2) { - mem_a20_alt = val & 2; - mem_a20_recalc(); - } - if ((~acc2168.port_62 & val) & 1) { - softresetx86(); - cpu_set_edx(); - } - acc2168.port_62 = val | 0xfC; + if ((mem_a20_alt ^ val) & 2) { + mem_a20_alt = val & 2; + mem_a20_recalc(); + } + if ((~acc2168.port_62 & val) & 1) { + softresetx86(); + cpu_set_edx(); + } + acc2168.port_62 = val | 0xfC; } void acc2168_init() { - memset(&acc2168, 0, sizeof(acc2168)); - io_sethandler(0x00f2, 0x0002, acc2168_read, NULL, NULL, acc2168_write, NULL, NULL, NULL); - io_sethandler(0x0078, 0x0001, port78_read, NULL, NULL, NULL, NULL, NULL, NULL); - io_sethandler(0x0092, 0x0001, port92_read, NULL, NULL, port92_write, NULL, NULL, NULL); + memset(&acc2168, 0, sizeof(acc2168)); + io_sethandler(0x00f2, 0x0002, acc2168_read, NULL, NULL, acc2168_write, NULL, NULL, NULL); + io_sethandler(0x0078, 0x0001, port78_read, NULL, NULL, NULL, NULL, NULL, NULL); + io_sethandler(0x0092, 0x0001, port92_read, NULL, NULL, port92_write, NULL, NULL, NULL); } diff --git a/src/models/acc3221.c b/src/models/acc3221.c index 803ffdf4..227d09a3 100644 --- a/src/models/acc3221.c +++ b/src/models/acc3221.c @@ -7,8 +7,8 @@ #include "serial.h" static struct { - int reg_idx; - uint8_t regs[256]; + int reg_idx; + uint8_t regs[256]; } acc3221; #define REG_BE_LPT1_DISABLE (1 << 4) @@ -16,11 +16,11 @@ static struct { #define REG_DB_SERIAL1_DISABLE (1 << 4) #define REG_DB_SERIAL2_DISABLE (1 << 1) -#define REG_DE_SIRQ3_SOURCE (3 << 6) +#define REG_DE_SIRQ3_SOURCE (3 << 6) #define REG_DE_SIRQ3_SERIAL1 (1 << 6) #define REG_DE_SIRQ3_SERIAL2 (3 << 6) -#define REG_DE_SIRQ4_SOURCE (3 << 4) +#define REG_DE_SIRQ4_SOURCE (3 << 4) #define REG_DE_SIRQ4_SERIAL1 (1 << 4) #define REG_DE_SIRQ4_SERIAL2 (3 << 4) @@ -29,79 +29,80 @@ static struct { #define REG_FE_IDE_DISABLE (1 << 1) static void acc3221_write(uint16_t addr, uint8_t val, void *p) { - if (!(addr & 1)) - acc3221.reg_idx = val; - else { - acc3221.regs[acc3221.reg_idx] = val; -// pclog("Write ACC2036 R%02x %02x %04x:%04x %i\n", acc2036.reg_idx, val, CS,cpu_state.pc, ins); + if (!(addr & 1)) + acc3221.reg_idx = val; + else { + acc3221.regs[acc3221.reg_idx] = val; + // pclog("Write ACC2036 R%02x %02x %04x:%04x %i\n", acc2036.reg_idx, val, CS,cpu_state.pc, ins); - if (acc3221.reg_idx >= 0xbc) { -// pclog("Write ACC3221 R%02x %02x %04x:%04x %i\n", acc3221.reg_idx, val, CS,cpu_state.pc, ins); - fdc_remove(); - if (!(acc3221.regs[0xfb] & REG_FB_FDC_DISABLE)) - fdc_add(); + if (acc3221.reg_idx >= 0xbc) { + // pclog("Write ACC3221 R%02x %02x %04x:%04x %i\n", acc3221.reg_idx, val, + // CS,cpu_state.pc, ins); + fdc_remove(); + if (!(acc3221.regs[0xfb] & REG_FB_FDC_DISABLE)) + fdc_add(); - serial1_remove(); - if (!(acc3221.regs[0xdb] & REG_DB_SERIAL1_DISABLE)) { - uint16_t addr = (acc3221.regs[0xdc] & 0x7f) << 2; + serial1_remove(); + if (!(acc3221.regs[0xdb] & REG_DB_SERIAL1_DISABLE)) { + uint16_t addr = (acc3221.regs[0xdc] & 0x7f) << 2; - if ((acc3221.regs[0xde] & REG_DE_SIRQ3_SOURCE) == REG_DE_SIRQ3_SERIAL1) { -// pclog("COM1 addr %03x IRQ 3\n", addr); - serial1_set(addr, 3); - } else if ((acc3221.regs[0xde] & REG_DE_SIRQ4_SOURCE) == REG_DE_SIRQ4_SERIAL1) { -// pclog("COM1 addr %03x IRQ 4\n", addr); - serial1_set(addr, 4); - } -// else -// pclog("COM1 addr %03x no IRQ\n", addr); - } -// else -// pclog("COM1 disabled\n"); + if ((acc3221.regs[0xde] & REG_DE_SIRQ3_SOURCE) == REG_DE_SIRQ3_SERIAL1) { + // pclog("COM1 addr %03x IRQ 3\n", addr); + serial1_set(addr, 3); + } else if ((acc3221.regs[0xde] & REG_DE_SIRQ4_SOURCE) == REG_DE_SIRQ4_SERIAL1) { + // pclog("COM1 addr %03x IRQ 4\n", addr); + serial1_set(addr, 4); + } + // else + // pclog("COM1 addr %03x no IRQ\n", addr); + } + // else + // pclog("COM1 disabled\n"); - serial2_remove(); - if (!(acc3221.regs[0xdb] & REG_DB_SERIAL2_DISABLE)) { - uint16_t addr = (acc3221.regs[0xdd] & 0x7f) << 2; + serial2_remove(); + if (!(acc3221.regs[0xdb] & REG_DB_SERIAL2_DISABLE)) { + uint16_t addr = (acc3221.regs[0xdd] & 0x7f) << 2; - if ((acc3221.regs[0xde] & REG_DE_SIRQ3_SOURCE) == REG_DE_SIRQ3_SERIAL2) { -// pclog("COM2 addr %03x IRQ 3\n", addr); - serial2_set(addr, 3); - } else if ((acc3221.regs[0xde] & REG_DE_SIRQ4_SOURCE) == REG_DE_SIRQ4_SERIAL2) { -// pclog("COM2 addr %03x IRQ 4\n", addr); - serial2_set(addr, 4); - } -// else -// pclog("COM2 addr %03x no IRQ\n", addr); - } -// else -// pclog("COM2 disabled\n"); + if ((acc3221.regs[0xde] & REG_DE_SIRQ3_SOURCE) == REG_DE_SIRQ3_SERIAL2) { + // pclog("COM2 addr %03x IRQ 3\n", addr); + serial2_set(addr, 3); + } else if ((acc3221.regs[0xde] & REG_DE_SIRQ4_SOURCE) == REG_DE_SIRQ4_SERIAL2) { + // pclog("COM2 addr %03x IRQ 4\n", addr); + serial2_set(addr, 4); + } + // else + // pclog("COM2 addr %03x no IRQ\n", addr); + } + // else + // pclog("COM2 disabled\n"); - lpt1_remove(); - lpt2_remove(); - if (!(acc3221.regs[0xbe] & REG_BE_LPT1_DISABLE)) { -// pclog("LPT1 addr %03x\n", acc3221.regs[0xbf] << 2); - lpt1_init(acc3221.regs[0xbf] << 2); - } -// else -// pclog("LPT1 disabled\n"); + lpt1_remove(); + lpt2_remove(); + if (!(acc3221.regs[0xbe] & REG_BE_LPT1_DISABLE)) { + // pclog("LPT1 addr %03x\n", acc3221.regs[0xbf] << 2); + lpt1_init(acc3221.regs[0xbf] << 2); + } + // else + // pclog("LPT1 disabled\n"); - ide_pri_disable(); - if (!(acc3221.regs[0xfe] & REG_FE_IDE_DISABLE)) - ide_pri_enable(); - } - } + ide_pri_disable(); + if (!(acc3221.regs[0xfe] & REG_FE_IDE_DISABLE)) + ide_pri_enable(); + } + } } static uint8_t acc3221_read(uint16_t addr, void *p) { - if (!(addr & 1)) - return acc3221.reg_idx; + if (!(addr & 1)) + return acc3221.reg_idx; - if (acc3221.reg_idx < 0xbc) - return 0xff; + if (acc3221.reg_idx < 0xbc) + return 0xff; - return acc3221.regs[acc3221.reg_idx]; + return acc3221.regs[acc3221.reg_idx]; } void acc3221_init() { - memset(&acc3221, 0, sizeof(acc3221)); - io_sethandler(0x00f2, 0x0002, acc3221_read, NULL, NULL, acc3221_write, NULL, NULL, NULL); + memset(&acc3221, 0, sizeof(acc3221)); + io_sethandler(0x00f2, 0x0002, acc3221_read, NULL, NULL, acc3221_write, NULL, NULL, NULL); } diff --git a/src/models/acer386sx.c b/src/models/acer386sx.c index 8de78908..d3d73a9e 100644 --- a/src/models/acer386sx.c +++ b/src/models/acer386sx.c @@ -15,115 +15,128 @@ static uint8_t acer_last_write; static int acer_locked; static void *acer_oti067; -void acer386sx_set_oti067(void *oti067) { - acer_oti067 = oti067; -} +void acer386sx_set_oti067(void *oti067) { acer_oti067 = oti067; } void acer386sx_write(uint16_t addr, uint8_t val, void *priv) { - if (addr & 1) { - if (acer_locked) { - if (acer_last_write == 0x14 && val == 0x09) - acer_locked = 0; + if (addr & 1) { + if (acer_locked) { + if (acer_last_write == 0x14 && val == 0x09) + acer_locked = 0; - acer_last_write = val; - return; - } + acer_last_write = val; + return; + } - if (acer_index == 0xff && val == 0xff) - acer_locked = 1; - else { - pclog("Write ACER reg %02x %02x %08x\n", acer_index, val, cs); - acer_regs[acer_index] = val; + if (acer_index == 0xff && val == 0xff) + acer_locked = 1; + else { + pclog("Write ACER reg %02x %02x %08x\n", acer_index, val, cs); + acer_regs[acer_index] = val; - switch (acer_index) { - case 0xa: - switch ((val >> 4) & 3) { - case 0:mem_set_mem_state(0xe0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - break; - case 1:mem_set_mem_state(0xe0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); - break; - case 2:mem_set_mem_state(0xe0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); - break; - case 3:mem_set_mem_state(0xe0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - break; - } - break; - case 0xb: - switch ((val >> 4) & 3) { - case 0:mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - break; - case 1:mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); - break; - case 2:mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); - break; - case 3:mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - break; - } - break; - } - } - } else - acer_index = val; + switch (acer_index) { + case 0xa: + switch ((val >> 4) & 3) { + case 0: + mem_set_mem_state(0xe0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + break; + case 1: + mem_set_mem_state(0xe0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); + break; + case 2: + mem_set_mem_state(0xe0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); + break; + case 3: + mem_set_mem_state(0xe0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + break; + } + break; + case 0xb: + switch ((val >> 4) & 3) { + case 0: + mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + break; + case 1: + mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); + break; + case 2: + mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); + break; + case 3: + mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + break; + } + break; + } + } + } else + acer_index = val; } uint8_t acer386sx_read(uint16_t addr, void *priv) { - if (acer_locked) - return 0xff; - if (addr & 1) { - if ((acer_index >= 0xc0 || acer_index == 0x20) && cpu_iscyrix) - return 0xff; /*Don't conflict with Cyrix config registers*/ - return acer_regs[acer_index]; - } else - return acer_index; + if (acer_locked) + return 0xff; + if (addr & 1) { + if ((acer_index >= 0xc0 || acer_index == 0x20) && cpu_iscyrix) + return 0xff; /*Don't conflict with Cyrix config registers*/ + return acer_regs[acer_index]; + } else + return acer_index; } static uint8_t acer386sx_37f = 0, acer386sx_io = 0; void acer386sx_io_write(uint16_t addr, uint8_t val, void *priv) { - switch (addr) { - case 0x37f:acer386sx_37f = val; - if (val & 4) - oti067_enable_disable(acer_oti067, 0); - else - oti067_enable_disable(acer_oti067, 1); - break; + switch (addr) { + case 0x37f: + acer386sx_37f = val; + if (val & 4) + oti067_enable_disable(acer_oti067, 0); + else + oti067_enable_disable(acer_oti067, 1); + break; - case 0x3f3:acer386sx_io = val; - serial1_remove(); - serial2_remove(); - lpt1_remove(); - lpt2_remove(); + case 0x3f3: + acer386sx_io = val; + serial1_remove(); + serial2_remove(); + lpt1_remove(); + lpt2_remove(); - switch (val & 3) { - case 0: lpt1_init(0x378); - break; - case 1: lpt1_init(0x3bc); - break; - case 2: lpt1_init(0x278); - break; - } - if (!(val & 0x04)) - serial1_set(0x3f8, 4); - if (!(val & 0x08)) - serial2_set(0x2f8, 3); - break; - } + switch (val & 3) { + case 0: + lpt1_init(0x378); + break; + case 1: + lpt1_init(0x3bc); + break; + case 2: + lpt1_init(0x278); + break; + } + if (!(val & 0x04)) + serial1_set(0x3f8, 4); + if (!(val & 0x08)) + serial2_set(0x2f8, 3); + break; + } } uint8_t acer386sx_io_read(uint16_t addr, void *priv) { - switch (addr) { - case 0x37f:return acer386sx_37f; + switch (addr) { + case 0x37f: + return acer386sx_37f; - case 0x3f3:return acer386sx_io; - } + case 0x3f3: + return acer386sx_io; + } - return 0xff; + return 0xff; } void acer386sx_init() { - io_sethandler(0x0022, 0x0002, acer386sx_read, NULL, NULL, acer386sx_write, NULL, NULL, NULL); - io_sethandler(0x037f, 0x0001, acer386sx_io_read, NULL, NULL, acer386sx_io_write, NULL, NULL, NULL); - io_sethandler(0x03f3, 0x0001, acer386sx_io_read, NULL, NULL, acer386sx_io_write, NULL, NULL, NULL); + io_sethandler(0x0022, 0x0002, acer386sx_read, NULL, NULL, acer386sx_write, NULL, NULL, NULL); + io_sethandler(0x037f, 0x0001, acer386sx_io_read, NULL, NULL, acer386sx_io_write, NULL, NULL, NULL); + io_sethandler(0x03f3, 0x0001, acer386sx_io_read, NULL, NULL, acer386sx_io_write, NULL, NULL, NULL); - acer386sx_io = 0; - acer386sx_37f = 0; + acer386sx_io = 0; + acer386sx_37f = 0; } diff --git a/src/models/ali1429.c b/src/models/ali1429.c index 90f536d1..b4366fef 100644 --- a/src/models/ali1429.c +++ b/src/models/ali1429.c @@ -10,55 +10,57 @@ static int ali1429_index; static uint8_t ali1429_regs[256]; static void ali1429_recalc() { - int c; + 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); - } + 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(); + flushmmucache(); } void ali1429_write(uint16_t port, uint8_t val, void *priv) { - if (!(port & 1)) - ali1429_index = val; - else { - ali1429_regs[ali1429_index] = val; -// pclog("ALI1429 write %02X %02X %04X:%04X %i\n",ali1429_index,val,CS,pc,ins); - switch (ali1429_index) { - case 0x13:ali1429_recalc(); - break; - case 0x14:ali1429_recalc(); - break; - } - } + if (!(port & 1)) + ali1429_index = val; + else { + ali1429_regs[ali1429_index] = val; + // pclog("ALI1429 write %02X %02X %04X:%04X %i\n",ali1429_index,val,CS,pc,ins); + switch (ali1429_index) { + case 0x13: + ali1429_recalc(); + break; + case 0x14: + 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]; + 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]; } -void ali1429_reset() { - memset(ali1429_regs, 0xff, 256); -} +void ali1429_reset() { memset(ali1429_regs, 0xff, 256); } -void ali1429_init() { - io_sethandler(0x0022, 0x0002, ali1429_read, NULL, NULL, ali1429_write, NULL, NULL, NULL); -} +void ali1429_init() { io_sethandler(0x0022, 0x0002, ali1429_read, NULL, NULL, ali1429_write, NULL, NULL, NULL); } diff --git a/src/models/amstrad.c b/src/models/amstrad.c index 9fa2a565..a2ed6974 100644 --- a/src/models/amstrad.c +++ b/src/models/amstrad.c @@ -15,286 +15,183 @@ int amstrad_latch = 0; static uint8_t amstrad_language; uint8_t amstrad_read(uint16_t port, void *priv) { - uint8_t temp; + uint8_t temp; - pclog("amstrad_read : %04X\n", port); - switch (port) { - case 0x378:return lpt1_read(port, NULL); - case 0x379:return lpt1_read(port, NULL) | (amstrad_language & 7); - case 0x37a:temp = lpt1_read(port, NULL) & 0x1f; - if (romset == ROM_PC1512) - return temp | 0x20; - if (romset == ROM_PC200 || romset == ROM_PPC512) { - if (fdc_discchange_read()) - temp |= 0x20; -/* DIP switches 4,5: Initial video mode */ - if (video_is_cga()) - temp |= 0x80; /* CGA 80 */ - else if (video_is_mda()) - temp |= 0xc0; /* MDA */ - return temp; - } - if (romset == ROM_PC1640) { - if (video_is_cga()) - temp |= 0x80; - else if (video_is_mda()) - temp |= 0xc0; + pclog("amstrad_read : %04X\n", port); + switch (port) { + case 0x378: + return lpt1_read(port, NULL); + case 0x379: + return lpt1_read(port, NULL) | (amstrad_language & 7); + case 0x37a: + temp = lpt1_read(port, NULL) & 0x1f; + if (romset == ROM_PC1512) + return temp | 0x20; + if (romset == ROM_PC200 || romset == ROM_PPC512) { + if (fdc_discchange_read()) + temp |= 0x20; + /* DIP switches 4,5: Initial video mode */ + if (video_is_cga()) + temp |= 0x80; /* CGA 80 */ + else if (video_is_mda()) + temp |= 0xc0; /* MDA */ + return temp; + } + if (romset == ROM_PC1640) { + if (video_is_cga()) + temp |= 0x80; + else if (video_is_mda()) + temp |= 0xc0; - switch (amstrad_latch) { - case AMSTRAD_NOLATCH:temp &= ~0x20; - break; - case AMSTRAD_SW9:temp &= ~0x20; - break; - case AMSTRAD_SW10:temp |= 0x20; - break; - } - } - return temp; - case 0x3de: - if (romset == ROM_PC200 || romset == ROM_PPC512) { -/* Read DIP switches / internal display adapter status. This code is only - * reached if the IDA is disabled; if it is enabled this read will be - * handled by the video card */ - } - return 0x20; /* Disable IDA */ - case 0xdead:return amstrad_dead; - } - return 0xff; + switch (amstrad_latch) { + case AMSTRAD_NOLATCH: + temp &= ~0x20; + break; + case AMSTRAD_SW9: + temp &= ~0x20; + break; + case AMSTRAD_SW10: + temp |= 0x20; + break; + } + } + return temp; + case 0x3de: + if (romset == ROM_PC200 || romset == ROM_PPC512) { + /* Read DIP switches / internal display adapter status. This code is only + * reached if the IDA is disabled; if it is enabled this read will be + * handled by the video card */ + } + return 0x20; /* Disable IDA */ + case 0xdead: + return amstrad_dead; + } + return 0xff; } void amstrad_write(uint16_t port, uint8_t val, void *priv) { - switch (port) { - case 0x66:softresetx86(); - break; + switch (port) { + case 0x66: + softresetx86(); + break; - case 0x378: - case 0x379: - case 0x37a:lpt1_write(port, val, NULL); - break; + case 0x378: + case 0x379: + case 0x37a: + lpt1_write(port, val, NULL); + break; - case 0xdead:amstrad_dead = val; - break; - } + case 0xdead: + amstrad_dead = val; + break; + } } static uint8_t mousex, mousey; static void amstrad_mouse_write(uint16_t addr, uint8_t val, void *p) { -// pclog("Write mouse %04X %02X %04X:%04X\n", addr, val, CS, pc); - if (addr == 0x78) - mousex = 0; - else - mousey = 0; + // pclog("Write mouse %04X %02X %04X:%04X\n", addr, val, CS, pc); + if (addr == 0x78) + mousex = 0; + else + mousey = 0; } static uint8_t amstrad_mouse_read(uint16_t addr, void *p) { -// printf("Read mouse %04X %04X:%04X %02X\n", addr, CS, pc, (addr == 0x78) ? mousex : mousey); - if (addr == 0x78) - return mousex; - return mousey; + // printf("Read mouse %04X %04X:%04X %02X\n", addr, CS, pc, (addr == 0x78) ? mousex : mousey); + if (addr == 0x78) + return mousex; + return mousey; } typedef struct mouse_amstrad_t { - int oldb; + int oldb; } mouse_amstrad_t; static void mouse_amstrad_poll(int x, int y, int z, int b, void *p) { - mouse_amstrad_t *mouse = (mouse_amstrad_t *)p; + mouse_amstrad_t *mouse = (mouse_amstrad_t *)p; - mousex += x; - mousey -= y; + mousex += x; + mousey -= y; - if ((b & 1) && !(mouse->oldb & 1)) - keyboard_send(0x7e); - if ((b & 2) && !(mouse->oldb & 2)) - keyboard_send(0x7d); - if (!(b & 1) && (mouse->oldb & 1)) - keyboard_send(0xfe); - if (!(b & 2) && (mouse->oldb & 2)) - keyboard_send(0xfd); + if ((b & 1) && !(mouse->oldb & 1)) + keyboard_send(0x7e); + if ((b & 2) && !(mouse->oldb & 2)) + keyboard_send(0x7d); + if (!(b & 1) && (mouse->oldb & 1)) + keyboard_send(0xfe); + if (!(b & 2) && (mouse->oldb & 2)) + keyboard_send(0xfd); - mouse->oldb = b; + mouse->oldb = b; } static void *mouse_amstrad_init() { - mouse_amstrad_t *mouse = (mouse_amstrad_t *)malloc(sizeof(mouse_amstrad_t)); - memset(mouse, 0, sizeof(mouse_amstrad_t)); + mouse_amstrad_t *mouse = (mouse_amstrad_t *)malloc(sizeof(mouse_amstrad_t)); + memset(mouse, 0, sizeof(mouse_amstrad_t)); - return mouse; + return mouse; } static void mouse_amstrad_close(void *p) { - mouse_amstrad_t *mouse = (mouse_amstrad_t *)p; + mouse_amstrad_t *mouse = (mouse_amstrad_t *)p; - free(mouse); + free(mouse); } -mouse_t mouse_amstrad = - { - "Amstrad mouse", - mouse_amstrad_init, - mouse_amstrad_close, - mouse_amstrad_poll, - MOUSE_TYPE_AMSTRAD - }; +mouse_t mouse_amstrad = {"Amstrad mouse", mouse_amstrad_init, mouse_amstrad_close, mouse_amstrad_poll, MOUSE_TYPE_AMSTRAD}; void amstrad_init() { - lpt2_remove_ams(); - - io_sethandler(0x0078, 0x0001, amstrad_mouse_read, NULL, NULL, amstrad_mouse_write, NULL, NULL, NULL); - io_sethandler(0x007a, 0x0001, amstrad_mouse_read, NULL, NULL, amstrad_mouse_write, NULL, NULL, NULL); - io_sethandler(0x0066, 0x0001, NULL, NULL, NULL, amstrad_write, NULL, NULL, NULL); - io_sethandler(0x0378, 0x0003, amstrad_read, NULL, NULL, amstrad_write, NULL, NULL, NULL); - io_sethandler(0xdead, 0x0001, amstrad_read, NULL, NULL, amstrad_write, NULL, NULL, NULL); - if ((romset == ROM_PC200 || romset == ROM_PPC512) && gfxcard != GFX_BUILTIN) - io_sethandler(0x03de, 0x0001, amstrad_read, NULL, NULL, amstrad_write, NULL, NULL, NULL); + lpt2_remove_ams(); + io_sethandler(0x0078, 0x0001, amstrad_mouse_read, NULL, NULL, amstrad_mouse_write, NULL, NULL, NULL); + io_sethandler(0x007a, 0x0001, amstrad_mouse_read, NULL, NULL, amstrad_mouse_write, NULL, NULL, NULL); + io_sethandler(0x0066, 0x0001, NULL, NULL, NULL, amstrad_write, NULL, NULL, NULL); + io_sethandler(0x0378, 0x0003, amstrad_read, NULL, NULL, amstrad_write, NULL, NULL, NULL); + io_sethandler(0xdead, 0x0001, amstrad_read, NULL, NULL, amstrad_write, NULL, NULL, NULL); + if ((romset == ROM_PC200 || romset == ROM_PPC512) && gfxcard != GFX_BUILTIN) + io_sethandler(0x03de, 0x0001, amstrad_read, NULL, NULL, amstrad_write, NULL, NULL, NULL); } static void *ams1512_init() { - amstrad_language = device_get_config_int("language"); - return &amstrad_language; + amstrad_language = device_get_config_int("language"); + return &amstrad_language; } -device_config_t ams1512_config[] = - { - { - .name = "language", - .description = "BIOS language", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "English", - .value = 7 - }, - { - .description = "German", - .value = 6 - }, - { - .description = "French", - .value = 5 - }, - { - .description = "Spanish", - .value = 4 - }, - { - .description = "Danish", - .value = 3 - }, - { - .description = "Swedish", - .value = 2 - }, - { - .description = "Italian", - .value = 1 - }, - { - .description = "Diagnostic mode", - .value = 0 - }, - { - .description = "" - } - }, - .default_int = 7 - }, - { - .type = -1 - } - }; +device_config_t ams1512_config[] = {{.name = "language", + .description = "BIOS language", + .type = CONFIG_SELECTION, + .selection = {{.description = "English", .value = 7}, + {.description = "German", .value = 6}, + {.description = "French", .value = 5}, + {.description = "Spanish", .value = 4}, + {.description = "Danish", .value = 3}, + {.description = "Swedish", .value = 2}, + {.description = "Italian", .value = 1}, + {.description = "Diagnostic mode", .value = 0}, + {.description = ""}}, + .default_int = 7}, + {.type = -1}}; -device_config_t ams2086_config[] = - { - { - .name = "language", - .description = "BIOS language", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "English", - .value = 7 - }, - { - .description = "Diagnostic mode", - .value = 0 - }, - { - .description = "" - } - }, - .default_int = 7 - }, - { - .type = -1 - } - }; +device_config_t ams2086_config[] = {{.name = "language", + .description = "BIOS language", + .type = CONFIG_SELECTION, + .selection = {{.description = "English", .value = 7}, + {.description = "Diagnostic mode", .value = 0}, + {.description = ""}}, + .default_int = 7}, + {.type = -1}}; -device_config_t ams3086_config[] = - { - { - .name = "language", - .description = "BIOS language", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "English", - .value = 7 - }, - { - .description = "Diagnostic mode", - .value = 3 - }, - { - .description = "" - } - }, - .default_int = 7 - }, - { - .type = -1 - } - }; +device_config_t ams3086_config[] = {{.name = "language", + .description = "BIOS language", + .type = CONFIG_SELECTION, + .selection = {{.description = "English", .value = 7}, + {.description = "Diagnostic mode", .value = 3}, + {.description = ""}}, + .default_int = 7}, + {.type = -1}}; -device_t ams1512_device = - { - "Amstrad PC1512 (BIOS)", - 0, - ams1512_init, - NULL, - NULL, - NULL, - NULL, - NULL, - ams1512_config - }; +device_t ams1512_device = {"Amstrad PC1512 (BIOS)", 0, ams1512_init, NULL, NULL, NULL, NULL, NULL, ams1512_config}; -device_t ams2086_device = - { - "Amstrad PC2086 (BIOS)", - 0, - ams1512_init, - NULL, - NULL, - NULL, - NULL, - NULL, - ams2086_config - }; +device_t ams2086_device = {"Amstrad PC2086 (BIOS)", 0, ams1512_init, NULL, NULL, NULL, NULL, NULL, ams2086_config}; -device_t ams3086_device = - { - "Amstrad PC3086 (BIOS)", - 0, - ams1512_init, - NULL, - NULL, - NULL, - NULL, - NULL, - ams3086_config - }; +device_t ams3086_device = {"Amstrad PC3086 (BIOS)", 0, ams1512_init, NULL, NULL, NULL, NULL, NULL, ams3086_config}; diff --git a/src/models/cbm_io.c b/src/models/cbm_io.c index 6a68ae48..5c5191fa 100644 --- a/src/models/cbm_io.c +++ b/src/models/cbm_io.c @@ -5,26 +5,29 @@ #include "serial.h" static void cbm_io_write(uint16_t port, uint8_t val, void *p) { - serial1_remove(); - serial2_remove(); - 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:serial1_set(0x2f8, 3); - break; - case 0x8:serial1_set(0x3f8, 4); - break; - } + serial1_remove(); + serial2_remove(); + 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: + serial1_set(0x2f8, 3); + break; + case 0x8: + serial1_set(0x3f8, 4); + break; + } } -void cbm_io_init() { - io_sethandler(0x0230, 0x0001, NULL, NULL, NULL, cbm_io_write, NULL, NULL, NULL); -} +void cbm_io_init() { io_sethandler(0x0230, 0x0001, NULL, NULL, NULL, cbm_io_write, NULL, NULL, NULL); } diff --git a/src/models/cmd640.c b/src/models/cmd640.c index 122674fd..f35d7715 100644 --- a/src/models/cmd640.c +++ b/src/models/cmd640.c @@ -8,60 +8,62 @@ static uint8_t card_cmd640[256]; void cmd640_write(int func, int addr, uint8_t val, void *priv) { -// pclog("cmd640_write: func=%d addr=%02x val=%02x %04x:%08x\n", func, addr, val, CS, cpu_state.pc); - if (func > 0) - return; + // pclog("cmd640_write: func=%d addr=%02x val=%02x %04x:%08x\n", func, addr, val, CS, cpu_state.pc); + if (func > 0) + return; - switch (addr) { - case 0x04:ide_pri_disable(); - ide_sec_disable(); - if (val & 0x01) { - ide_pri_enable(); - ide_sec_enable(); - } - card_cmd640[0x04] = val & 0x41; - break; - case 0x07:card_cmd640[0x07] = val & 0x86; - break; - case 0x3c:card_cmd640[0x3c] = val; - break; - } + switch (addr) { + case 0x04: + ide_pri_disable(); + ide_sec_disable(); + if (val & 0x01) { + ide_pri_enable(); + ide_sec_enable(); + } + card_cmd640[0x04] = val & 0x41; + break; + case 0x07: + card_cmd640[0x07] = val & 0x86; + break; + case 0x3c: + card_cmd640[0x3c] = val; + break; + } } static uint8_t cmd640_read(int func, int addr, void *p) { -// pclog("cmd640_read: func=%d addr=%02x val=%02x %04x:%08x\n", func, addr, card_cmd640[addr], CS, cpu_state.pc); - if (func > 0) - return 0xff; + // pclog("cmd640_read: func=%d addr=%02x val=%02x %04x:%08x\n", func, addr, card_cmd640[addr], CS, cpu_state.pc); + if (func > 0) + return 0xff; - return card_cmd640[addr]; + return card_cmd640[addr]; } void cmd640b_init(int card) { - pci_add_specific(card, cmd640_read, cmd640_write, NULL); + pci_add_specific(card, cmd640_read, cmd640_write, NULL); - memset(card_cmd640, 0, 256); - card_cmd640[0x00] = 0x95; - card_cmd640[0x01] = 0x10; /**/ - card_cmd640[0x02] = 0x40; - card_cmd640[0x03] = 0x06; /*CMD640*/ - card_cmd640[0x04] = 0x01; - card_cmd640[0x05] = 0x00; - card_cmd640[0x06] = 0x00; - card_cmd640[0x07] = 0x02; - card_cmd640[0x08] = 0x00; /*Revision*/ - card_cmd640[0x09] = 0x00; /*Programming interface*/ - card_cmd640[0x0a] = 0x01; /*Sub class - IDE controller*/ - card_cmd640[0x0b] = 0x01; /*Base class - Mass storage controller*/ + memset(card_cmd640, 0, 256); + card_cmd640[0x00] = 0x95; + card_cmd640[0x01] = 0x10; /**/ + card_cmd640[0x02] = 0x40; + card_cmd640[0x03] = 0x06; /*CMD640*/ + card_cmd640[0x04] = 0x01; + card_cmd640[0x05] = 0x00; + card_cmd640[0x06] = 0x00; + card_cmd640[0x07] = 0x02; + card_cmd640[0x08] = 0x00; /*Revision*/ + card_cmd640[0x09] = 0x00; /*Programming interface*/ + card_cmd640[0x0a] = 0x01; /*Sub class - IDE controller*/ + card_cmd640[0x0b] = 0x01; /*Base class - Mass storage controller*/ + card_cmd640[0x3c] = 0x0e; /*Interrupt line*/ + card_cmd640[0x3d] = 1; - card_cmd640[0x3c] = 0x0e; /*Interrupt line*/ - card_cmd640[0x3d] = 1; + card_cmd640[0x50] = 0x02; /*Revision = 2*/ + card_cmd640[0x51] = 0x80; /*2nd port disabled, drive 1 read ahead disabled*/ + card_cmd640[0x57] = 0x0c; /*Drive 2/3 read ahead disabled*/ + card_cmd640[0x59] = 0x40; /*Burst length*/ - card_cmd640[0x50] = 0x02; /*Revision = 2*/ - card_cmd640[0x51] = 0x80; /*2nd port disabled, drive 1 read ahead disabled*/ - card_cmd640[0x57] = 0x0c; /*Drive 2/3 read ahead disabled*/ - card_cmd640[0x59] = 0x40; /*Burst length*/ - - ide_pri_disable(); - ide_sec_disable(); + ide_pri_disable(); + ide_sec_disable(); } diff --git a/src/models/compaq.c b/src/models/compaq.c index 32bd6874..881bba45 100644 --- a/src/models/compaq.c +++ b/src/models/compaq.c @@ -6,39 +6,37 @@ static mem_mapping_t compaq_ram_mapping; uint8_t compaq_read_ram(uint32_t addr, void *priv) { - addr = (addr & 0x7ffff) + 0x80000; - addreadlookup(mem_logical_addr, addr); - return ram[addr]; + addr = (addr & 0x7ffff) + 0x80000; + addreadlookup(mem_logical_addr, addr); + return ram[addr]; } uint16_t compaq_read_ramw(uint32_t addr, void *priv) { - addr = (addr & 0x7ffff) + 0x80000; - addreadlookup(mem_logical_addr, addr); - return *(uint16_t *)&ram[addr]; + addr = (addr & 0x7ffff) + 0x80000; + addreadlookup(mem_logical_addr, addr); + return *(uint16_t *)&ram[addr]; } uint32_t compaq_read_raml(uint32_t addr, void *priv) { - addr = (addr & 0x7ffff) + 0x80000; - addreadlookup(mem_logical_addr, addr); - return *(uint32_t *)&ram[addr]; + addr = (addr & 0x7ffff) + 0x80000; + addreadlookup(mem_logical_addr, addr); + return *(uint32_t *)&ram[addr]; } void compaq_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]); + addr = (addr & 0x7ffff) + 0x80000; + addwritelookup(mem_logical_addr, addr); + mem_write_ramb_page(addr, val, &pages[addr >> 12]); } void compaq_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]); + addr = (addr & 0x7ffff) + 0x80000; + addwritelookup(mem_logical_addr, addr); + mem_write_ramw_page(addr, val, &pages[addr >> 12]); } void compaq_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]); + addr = (addr & 0x7ffff) + 0x80000; + addwritelookup(mem_logical_addr, addr); + mem_write_raml_page(addr, val, &pages[addr >> 12]); } void compaq_init() { - mem_mapping_add(&compaq_ram_mapping, 0xfa0000, 0x60000, - compaq_read_ram, compaq_read_ramw, compaq_read_raml, - compaq_write_ram, compaq_write_ramw, compaq_write_raml, - ram + 0xa0000, MEM_MAPPING_INTERNAL, NULL); + mem_mapping_add(&compaq_ram_mapping, 0xfa0000, 0x60000, compaq_read_ram, compaq_read_ramw, compaq_read_raml, + compaq_write_ram, compaq_write_ramw, compaq_write_raml, ram + 0xa0000, MEM_MAPPING_INTERNAL, NULL); } diff --git a/src/models/cs8230.c b/src/models/cs8230.c index e769a486..b00ca916 100644 --- a/src/models/cs8230.c +++ b/src/models/cs8230.c @@ -11,109 +11,111 @@ #include "mem.h" static struct { - int idx; - uint8_t regs[256]; + int idx; + uint8_t regs[256]; } cs8230; static void shadow_control(uint32_t addr, uint32_t size, int state) { -// pclog("shadow_control: addr=%08x size=%04x state=%02x\n", addr, size, state); - switch (state) { - case 0x00:mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - break; - case 0x01:mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); - break; - case 0x10:mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); - break; - case 0x11:mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - break; - } - flushmmucache_nopc(); + // pclog("shadow_control: addr=%08x size=%04x state=%02x\n", addr, size, state); + switch (state) { + case 0x00: + mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + break; + case 0x01: + mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); + break; + case 0x10: + mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); + break; + case 0x11: + mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + break; + } + flushmmucache_nopc(); } static void rethink_shadow_mappings(void) { - int c; + int c; - for (c = 0; c < 4 * 8; c++) /*Addresses 40000-bffff in 16k blocks*/ - { - if (cs8230.regs[0xa + (c >> 3)] & (1 << (c & 7))) - mem_set_mem_state(0x40000 + c * 0x4000, 0x4000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); /*IO channel*/ - else - mem_set_mem_state(0x40000 + c * 0x4000, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); /*System board*/ - } - for (c = 0; c < 2 * 8; c++) /*Addresses c0000-fffff in 16k blocks. System board ROM can be mapped here*/ - { - if (cs8230.regs[0xe + (c >> 3)] & (1 << (c & 7))) - mem_set_mem_state(0xc0000 + c * 0x4000, 0x4000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); /*IO channel*/ - else - shadow_control(0xc0000 + c * 0x4000, 0x4000, (cs8230.regs[9] >> (3 - (c >> 2))) & 0x11); - } + for (c = 0; c < 4 * 8; c++) /*Addresses 40000-bffff in 16k blocks*/ + { + if (cs8230.regs[0xa + (c >> 3)] & (1 << (c & 7))) + mem_set_mem_state(0x40000 + c * 0x4000, 0x4000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); /*IO channel*/ + else + mem_set_mem_state(0x40000 + c * 0x4000, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); /*System board*/ + } + for (c = 0; c < 2 * 8; c++) /*Addresses c0000-fffff in 16k blocks. System board ROM can be mapped here*/ + { + if (cs8230.regs[0xe + (c >> 3)] & (1 << (c & 7))) + mem_set_mem_state(0xc0000 + c * 0x4000, 0x4000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); /*IO channel*/ + else + shadow_control(0xc0000 + c * 0x4000, 0x4000, (cs8230.regs[9] >> (3 - (c >> 2))) & 0x11); + } } static uint8_t cs8230_read(uint16_t port, void *p) { - uint8_t ret = 0xff; + uint8_t ret = 0xff; - if (port & 1) { - switch (cs8230.idx) { - case 0x04: /*82C301 ID/version*/ - ret = cs8230.regs[cs8230.idx] & ~0xe3; - break; + if (port & 1) { + switch (cs8230.idx) { + case 0x04: /*82C301 ID/version*/ + ret = cs8230.regs[cs8230.idx] & ~0xe3; + break; - case 0x08: /*82C302 ID/Version*/ - ret = cs8230.regs[cs8230.idx] & ~0xe0; - break; + case 0x08: /*82C302 ID/Version*/ + ret = cs8230.regs[cs8230.idx] & ~0xe0; + break; - case 0x05: - case 0x06: /*82C301 registers*/ - case 0x09: - case 0x0a: - case 0x0b: - case 0x0c: /*82C302 registers*/ - case 0x0d: - case 0x0e: - case 0x0f: - case 0x10: - case 0x11: - case 0x12: - case 0x13: - case 0x28: - case 0x29: - case 0x2a:ret = cs8230.regs[cs8230.idx]; - break; - } - } + case 0x05: + case 0x06: /*82C301 registers*/ + case 0x09: + case 0x0a: + case 0x0b: + case 0x0c: /*82C302 registers*/ + case 0x0d: + case 0x0e: + case 0x0f: + case 0x10: + case 0x11: + case 0x12: + case 0x13: + case 0x28: + case 0x29: + case 0x2a: + ret = cs8230.regs[cs8230.idx]; + break; + } + } - return ret; + return ret; } static void cs8230_write(uint16_t port, uint8_t val, void *p) { - if (!(port & 1)) - cs8230.idx = val; - else { -// pclog("cs8230_write: reg=%02x val=%02x\n", cs8230.idx, val); - cs8230.regs[cs8230.idx] = val; - switch (cs8230.idx) { - case 0x09: /*RAM/ROM Configuration in boot area*/ - case 0x0a: - case 0x0b: - case 0x0c: - case 0x0d: - case 0x0e: - case 0x0f: /*Address maps*/ - rethink_shadow_mappings(); - break; - } - } + if (!(port & 1)) + cs8230.idx = val; + else { + // pclog("cs8230_write: reg=%02x val=%02x\n", cs8230.idx, val); + cs8230.regs[cs8230.idx] = val; + switch (cs8230.idx) { + case 0x09: /*RAM/ROM Configuration in boot area*/ + case 0x0a: + case 0x0b: + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: /*Address maps*/ + rethink_shadow_mappings(); + break; + } + } } void cs8230_init(void) { - memset(&cs8230, 0, sizeof(cs8230)); + memset(&cs8230, 0, sizeof(cs8230)); - io_sethandler(0x0022, 0x0002, - cs8230_read, NULL, NULL, - cs8230_write, NULL, NULL, - NULL); - if (mem_size > 768) { - mem_mapping_set_addr(&ram_mid_mapping, 0xa0000, mem_size > 1024 ? 0x60000 : 0x20000 + (mem_size - 768) * 1024); - mem_mapping_set_exec(&ram_mid_mapping, ram + 0xa0000); - } + io_sethandler(0x0022, 0x0002, cs8230_read, NULL, NULL, cs8230_write, NULL, NULL, NULL); + if (mem_size > 768) { + mem_mapping_set_addr(&ram_mid_mapping, 0xa0000, mem_size > 1024 ? 0x60000 : 0x20000 + (mem_size - 768) * 1024); + mem_mapping_set_exec(&ram_mid_mapping, ram + 0xa0000); + } } diff --git a/src/models/dells200.c b/src/models/dells200.c index d5867be4..bb646fcc 100644 --- a/src/models/dells200.c +++ b/src/models/dells200.c @@ -4,53 +4,57 @@ #include "dells200.h" -static struct { - uint8_t regs[3]; -} dells200; +static struct { uint8_t regs[3]; } dells200; static uint8_t dells200_in(uint16_t addr, void *p) { - uint8_t ret = 0xff; + uint8_t ret = 0xff; - switch (addr) { - case 0xa4:ret = dells200.regs[0]; - break; - case 0xa5:ret = dells200.regs[1]; - break; - case 0xab:ret = dells200.regs[2]; - break; - } + switch (addr) { + case 0xa4: + ret = dells200.regs[0]; + break; + case 0xa5: + ret = dells200.regs[1]; + break; + case 0xab: + ret = dells200.regs[2]; + break; + } -// pclog("dells200_in: addr=%04x ret=%02x %04x(%08x):%08x\n", addr, ret, CS,cs,cpu_state.pc); + // pclog("dells200_in: addr=%04x ret=%02x %04x(%08x):%08x\n", addr, ret, CS,cs,cpu_state.pc); - return ret; + return ret; } static void dells200_out(uint16_t addr, uint8_t val, void *p) { -// pclog("dells200_out: addr=%04x val=%02x %04x(%08x):%08x\n", addr, val, CS,cs,cpu_state.pc); + // pclog("dells200_out: addr=%04x val=%02x %04x(%08x):%08x\n", addr, val, CS,cs,cpu_state.pc); - switch (addr) { - case 0xa4:dells200.regs[0] = val; - mem_a20_alt = val & 0x40; - mem_a20_recalc(); - break; - case 0xa5:dells200.regs[1] = val; - if (val & 1) - mem_mapping_set_addr(&ram_low_mapping, 0, 0x40000); - else - mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000); - if (val & 1) - mem_mapping_disable(&ram_high_mapping); - else - mem_mapping_enable(&ram_high_mapping); - break; - case 0xab:dells200.regs[2] = val; - break; - } + switch (addr) { + case 0xa4: + dells200.regs[0] = val; + mem_a20_alt = val & 0x40; + mem_a20_recalc(); + break; + case 0xa5: + dells200.regs[1] = val; + if (val & 1) + mem_mapping_set_addr(&ram_low_mapping, 0, 0x40000); + else + mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000); + if (val & 1) + mem_mapping_disable(&ram_high_mapping); + else + mem_mapping_enable(&ram_high_mapping); + break; + case 0xab: + dells200.regs[2] = val; + break; + } } void dells200_chipset_init() { - memset(&dells200, 0, sizeof(dells200)); + memset(&dells200, 0, sizeof(dells200)); - io_sethandler(0x00a4, 0x0002, dells200_in, NULL, NULL, dells200_out, NULL, NULL, NULL); - io_sethandler(0x00ab, 0x0001, dells200_in, NULL, NULL, dells200_out, NULL, NULL, NULL); + io_sethandler(0x00a4, 0x0002, dells200_in, NULL, NULL, dells200_out, NULL, NULL, NULL); + io_sethandler(0x00ab, 0x0001, dells200_in, NULL, NULL, dells200_out, NULL, NULL, NULL); } diff --git a/src/models/dma.c b/src/models/dma.c index 860d0f60..ccc81459 100644 --- a/src/models/dma.c +++ b/src/models/dma.c @@ -19,684 +19,698 @@ static uint8_t dma_stat_rq; static uint8_t dma_command, dma16_command; static struct { - int xfr_command, xfr_channel; - int byte_ptr; + int xfr_command, xfr_channel; + int byte_ptr; - int is_ps2; + int is_ps2; } dma_ps2; -#define DMA_PS2_IOA (1 << 0) +#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) +#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); void dma_reset() { - int c; + int c; - dma_wp = dma16_wp = 0; - dma_m = 0; + 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; - } + 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; + } } uint8_t dma_read(uint16_t addr, void *priv) { - int channel = (addr >> 1) & 3; - uint8_t temp; -// printf("Read DMA %04X %04X:%04X %i %02X\n",addr,CS,pc, pic_intpending, pic.pend); - 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; + int channel = (addr >> 1) & 3; + uint8_t temp; + // printf("Read DMA %04X %04X:%04X %i %02X\n",addr,CS,pc, pic_intpending, pic.pend); + 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 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 8: /*Status register*/ + temp = dma_stat & 0xf; + dma_stat &= ~0xf; + return temp; - case 0xd:return 0; - } -// printf("Bad DMA read %04X %04X:%04X\n",addr,CS,pc); - return dmaregs[addr & 0xf]; + case 0xd: + return 0; + } + // printf("Bad DMA read %04X %04X:%04X\n",addr,CS,pc); + return dmaregs[addr & 0xf]; } void dma_write(uint16_t addr, uint8_t val, void *priv) { - int channel = (addr >> 1) & 3; -// printf("Write DMA %04X %02X %04X:%04X\n",addr,val,CS,pc); - 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; -// pclog("Addr = %04x\n", dma.ab[(addr >> 1) & 3]); - return; + int channel = (addr >> 1) & 3; + // printf("Write DMA %04X %02X %04X:%04X\n",addr,val,CS,pc); + 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; + // pclog("Addr = %04x\n", dma.ab[(addr >> 1) & 3]); + 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 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 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 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 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 0xc: /*Clear FF*/ + dma_wp = 0; + return; - case 0xd: /*Master clear*/ - dma_wp = 0; - dma_m |= 0xf; - return; + case 0xd: /*Master clear*/ + dma_wp = 0; + dma_m |= 0xf; + return; - case 0xf: /*Mask write*/ - dma_m = (dma_m & 0xf0) | (val & 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; + 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; + 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; - } + default: + fatal("Bad XFR Read command %i channel %i\n", dma_ps2.xfr_command, dma_ps2.xfr_channel); + } + break; + } -// pclog("Read DMA %04X %04X:%04X %02X\n",addr,CS,pc, temp); + // pclog("Read DMA %04X %04X:%04X %02X\n",addr,CS,pc, temp); - return temp; + 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; + dma_t *dma_c = &dma[dma_ps2.xfr_channel]; + uint8_t mode; -// pclog("Write PS2 DMA %04X %02X %04X:%04X\n",addr,val,CS,cpu_state.pc); + // pclog("Write PS2 DMA %04X %02X %04X:%04X\n",addr,val,CS,cpu_state.pc); - 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; + 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; -// case 0xb: output = 3; 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 0xb: output = 3; 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 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 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 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; + 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; - } + default: + fatal("Bad XFR command %i channel %i val %02x\n", dma_ps2.xfr_command, dma_ps2.xfr_channel, val); + } + break; + } } uint8_t dma16_read(uint16_t addr, void *priv) { - int channel = ((addr >> 2) & 3) + 4; - uint8_t temp; -// printf("Read DMA %04X %04X:%04X\n",addr,cs>>4,pc); - 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; + int channel = ((addr >> 2) & 3) + 4; + uint8_t temp; + // printf("Read DMA %04X %04X:%04X\n",addr,cs>>4,pc); + 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 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]; + case 8: /*Status register*/ + temp = dma_stat >> 4; + dma_stat &= ~0xf0; + return temp; + } + return dma16regs[addr & 0xf]; } void dma16_write(uint16_t addr, uint8_t val, void *priv) { - int channel = ((addr >> 2) & 3) + 4; -// printf("Write dma16 %04X %02X %04X:%04X\n",addr,val,CS,pc); - 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; + int channel = ((addr >> 2) & 3) + 4; + // printf("Write dma16 %04X %02X %04X:%04X\n",addr,val,CS,pc); + 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 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 8: /*Control register*/ + return; - case 0xa: /*Mask*/ - if (val & 4) - dma_m |= (0x10 << (val & 3)); - else - dma_m &= ~(0x10 << (val & 3)); - 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 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 0xc: /*Clear FF*/ + dma16_wp = 0; + return; - case 0xd: /*Master clear*/ - dma16_wp = 0; - dma_m |= 0xf0; - 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; - } + case 0xf: /*Mask write*/ + dma_m = (dma_m & 0x0f) | ((val & 0xf) << 4); + return; + } } 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; - } + 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; + } } -uint8_t dma_page_read(uint16_t addr, void *priv) { - return dmapages[addr & 0xf]; -} +uint8_t dma_page_read(uint16_t addr, void *priv) { return dmapages[addr & 0xf]; } void dma_init() { - io_sethandler(0x0000, 0x0010, dma_read, NULL, NULL, dma_write, NULL, NULL, NULL); - io_sethandler(0x0080, 0x0008, dma_page_read, NULL, NULL, dma_page_write, NULL, NULL, NULL); - dma_ps2.is_ps2 = 0; + io_sethandler(0x0000, 0x0010, dma_read, NULL, NULL, dma_write, NULL, NULL, NULL); + io_sethandler(0x0080, 0x0008, dma_page_read, NULL, NULL, dma_page_write, NULL, NULL, NULL); + dma_ps2.is_ps2 = 0; } void dma16_init() { - io_sethandler(0x00C0, 0x0020, dma16_read, NULL, NULL, dma16_write, NULL, NULL, NULL); - io_sethandler(0x0088, 0x0008, dma_page_read, NULL, NULL, dma_page_write, NULL, NULL, NULL); + io_sethandler(0x00C0, 0x0020, dma16_read, NULL, NULL, dma16_write, NULL, NULL, NULL); + io_sethandler(0x0088, 0x0008, dma_page_read, NULL, NULL, dma_page_write, NULL, NULL, NULL); } void ps2_dma_init() { - io_sethandler(0x0018, 0x0001, dma_ps2_read, NULL, NULL, dma_ps2_write, NULL, NULL, NULL); - io_sethandler(0x001a, 0x0001, dma_ps2_read, NULL, NULL, dma_ps2_write, NULL, NULL, NULL); - dma_ps2.is_ps2 = 1; + io_sethandler(0x0018, 0x0001, dma_ps2_read, NULL, NULL, dma_ps2_write, NULL, NULL, NULL); + io_sethandler(0x001a, 0x0001, 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(addr); - return temp; + uint8_t temp = mem_readb_phys(addr); + return temp; } void _dma_write(uint32_t addr, uint8_t val) { - mem_writeb_phys(addr, val); - mem_invalidate_range(addr, addr); + mem_writeb_phys(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; + 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 (channel < 4) { + if (dma_command & 0x04) + return DMA_NODATA; + } else { + if (dma16_command & 0x04) + return DMA_NODATA; + } - if (!AT) - refreshread(); + if (!AT) + refreshread(); - if (dma_m & (1 << channel)) - return DMA_NODATA; - if ((dma_c->mode & 0xC) != 8) - return DMA_NODATA; + 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->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--; + 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); - } - } + 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_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); - } + 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; + if (tc) + return temp | DMA_OVER; + return temp; } int dma_channel_write(int channel, uint16_t val) { - dma_t *dma_c = &dma[channel]; + 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 (channel < 4) { + if (dma_command & 0x04) + return DMA_NODATA; + } else { + if (dma16_command & 0x04) + return DMA_NODATA; + } - if (!AT) - refreshread(); + if (!AT) + refreshread(); - if (dma_m & (1 << channel)) - return DMA_NODATA; - if ((dma_c->mode & 0xC) != 4) - return DMA_NODATA; + 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); + if (!dma_c->size) { + _dma_write(dma_c->ac, val); - 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); - _dma_write(dma_c->ac + 1, val >> 8); + 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); + _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); - } else { - if (dma_ps2.is_ps2) - dma_c->ac += 2; - else - dma_c->ac = (dma_c->ac & 0xfe0000) | ((dma_c->ac + 2) & 0x1ffff); - } - } + 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_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); - } + 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; + if (dma_m & (1 << channel)) + return DMA_OVER; - return 0; + return 0; } static void dma_ps2_run(int channel) { - dma_t *dma_c = &dma[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); + 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--; + 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; - } + 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_rq |= (1 << channel); + dma_c->cc--; + } while (dma_c->cc > 0); - dma_stat |= (1 << channel); - break; + 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); + 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--; + 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; - } + 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_rq |= (1 << channel); + dma_c->cc--; + } while (dma_c->cc > 0); - ps2_cache_clean(); - dma_stat |= (1 << channel); - break; + 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; - } + 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_rq |= (1 << channel); + dma->cc--; + } while (dma->cc > 0); - dma_stat |= (1 << channel); - break; - } + dma_stat |= (1 << channel); + break; + } } diff --git a/src/models/headland.c b/src/models/headland.c index ea40773e..da4415b9 100644 --- a/src/models/headland.c +++ b/src/models/headland.c @@ -18,506 +18,486 @@ static mem_mapping_t headland_mid_mapping; static mem_mapping_t headland_high_mapping; static mem_mapping_t headland_4000_9FFF_mapping[24]; -// TODO - Headland chipset's memory address mapping emulation isn't fully implemented yet, so memory configuration is hardcoded now. -static int headland_mem_conf_cr0[41] = {0x00, 0x00, 0x20, 0x40, 0x60, 0xA0, 0x40, 0xE0, - 0xA0, 0xC0, 0xE0, 0xE0, 0xC0, 0xE0, 0xE0, 0xE0, - 0xE0, 0x20, 0x40, 0x40, 0xA0, 0xC0, 0xE0, 0xE0, - 0xC0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, - 0x20, 0x40, 0x60, 0x60, 0xC0, 0xE0, 0xE0, 0xE0, - 0xE0}; -static int headland_mem_conf_cr1[41] = {0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, - 0x00, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, - 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, - 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, - 0x40}; +// TODO - Headland chipset's memory address mapping emulation isn't fully implemented yet, so memory configuration is hardcoded +// now. +static int headland_mem_conf_cr0[41] = {0x00, 0x00, 0x20, 0x40, 0x60, 0xA0, 0x40, 0xE0, 0xA0, 0xC0, 0xE0, 0xE0, 0xC0, 0xE0, + 0xE0, 0xE0, 0xE0, 0x20, 0x40, 0x40, 0xA0, 0xC0, 0xE0, 0xE0, 0xC0, 0xE0, 0xE0, 0xE0, + 0xE0, 0xE0, 0xE0, 0xE0, 0x20, 0x40, 0x60, 0x60, 0xC0, 0xE0, 0xE0, 0xE0, 0xE0}; +static int headland_mem_conf_cr1[41] = {0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x00, 0x40, 0x40, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x40}; uint32_t get_headland_addr(uint32_t addr, uint16_t *mr) { - if (mr && (headland_regs_cr[0] & 2) && (*mr & 0x200)) { - addr = (addr & 0x3fff) | ((*mr & 0x1F) << 14); + if (mr && (headland_regs_cr[0] & 2) && (*mr & 0x200)) { + addr = (addr & 0x3fff) | ((*mr & 0x1F) << 14); - if (headland_regs_cr[1] & 0x40) { - if ((headland_regs_cr[4] & 0x80) && (headland_regs_cr[6] & 1)) { - if (headland_regs_cr[0] & 0x80) { - addr |= (*mr & 0x60) << 14; - if (*mr & 0x100) - addr += ((*mr & 0xC00) << 13) + (((*mr & 0x80) + 0x80) << 15); - else - addr += (*mr & 0x80) << 14; - } else if (*mr & 0x100) - addr += ((*mr & 0xC00) << 13) + (((*mr & 0x80) + 0x20) << 15); - else - addr += (*mr & 0x80) << 12; - } else if (headland_regs_cr[0] & 0x80) - addr |= (*mr & 0x100) ? ((*mr & 0x80) + 0x400) << 12 : (*mr & 0xE0) << 14; - else - addr |= (*mr & 0x100) ? ((*mr & 0xE0) + 0x40) << 14 : (*mr & 0x80) << 12; - } else { - if ((headland_regs_cr[4] & 0x80) && (headland_regs_cr[6] & 1)) { - if (headland_regs_cr[0] & 0x80) { - addr |= ((*mr & 0x60) << 14); - if (*mr & 0x180) - addr += ((*mr & 0xC00) << 13) + (((*mr & 0x180) - 0x60) << 16); - } else - addr |= ((*mr & 0x60) << 14) | ((*mr & 0x180) << 16) | ((*mr & 0xC00) << 13); - } else if (headland_regs_cr[0] & 0x80) - addr |= (*mr & 0x1E0) << 14; - else - addr |= (*mr & 0x180) << 12; - } - } else if (mr == NULL && (headland_regs_cr[0] & 4) == 0 && mem_size >= 1024 && addr >= 0x100000) - addr -= 0x60000; + if (headland_regs_cr[1] & 0x40) { + if ((headland_regs_cr[4] & 0x80) && (headland_regs_cr[6] & 1)) { + if (headland_regs_cr[0] & 0x80) { + addr |= (*mr & 0x60) << 14; + if (*mr & 0x100) + addr += ((*mr & 0xC00) << 13) + (((*mr & 0x80) + 0x80) << 15); + else + addr += (*mr & 0x80) << 14; + } else if (*mr & 0x100) + addr += ((*mr & 0xC00) << 13) + (((*mr & 0x80) + 0x20) << 15); + else + addr += (*mr & 0x80) << 12; + } else if (headland_regs_cr[0] & 0x80) + addr |= (*mr & 0x100) ? ((*mr & 0x80) + 0x400) << 12 : (*mr & 0xE0) << 14; + else + addr |= (*mr & 0x100) ? ((*mr & 0xE0) + 0x40) << 14 : (*mr & 0x80) << 12; + } else { + if ((headland_regs_cr[4] & 0x80) && (headland_regs_cr[6] & 1)) { + if (headland_regs_cr[0] & 0x80) { + addr |= ((*mr & 0x60) << 14); + if (*mr & 0x180) + addr += ((*mr & 0xC00) << 13) + (((*mr & 0x180) - 0x60) << 16); + } else + addr |= ((*mr & 0x60) << 14) | ((*mr & 0x180) << 16) | ((*mr & 0xC00) << 13); + } else if (headland_regs_cr[0] & 0x80) + addr |= (*mr & 0x1E0) << 14; + else + addr |= (*mr & 0x180) << 12; + } + } else if (mr == NULL && (headland_regs_cr[0] & 4) == 0 && mem_size >= 1024 && addr >= 0x100000) + addr -= 0x60000; - return addr; + return addr; } void headland_set_global_EMS_state(int state) { - int i; - uint32_t base_addr, virt_addr; + int i; + uint32_t base_addr, virt_addr; - for (i = 0; i < 32; i++) { - base_addr = (i + 16) << 14; - if (i >= 24) - base_addr += 0x20000; - if ((state & 2) && (headland_ems_mr[((state & 1) << 5) | i] & 0x200)) { - virt_addr = get_headland_addr(base_addr, &headland_ems_mr[((state & 1) << 5) | i]); - if (i < 24) - mem_mapping_disable(&headland_4000_9FFF_mapping[i]); - mem_mapping_disable(&headland_ems_mapping[(((state ^ 1) & 1) << 5) | i]); - mem_mapping_enable(&headland_ems_mapping[((state & 1) << 5) | i]); - if (virt_addr < (mem_size << 10)) - mem_mapping_set_exec(&headland_ems_mapping[((state & 1) << 5) | i], ram + virt_addr); - else - mem_mapping_set_exec(&headland_ems_mapping[((state & 1) << 5) | i], NULL); - } else { - mem_mapping_set_exec(&headland_ems_mapping[((state & 1) << 5) | i], ram + base_addr); - mem_mapping_disable(&headland_ems_mapping[(((state ^ 1) & 1) << 5) | i]); - mem_mapping_disable(&headland_ems_mapping[((state & 1) << 5) | i]); + for (i = 0; i < 32; i++) { + base_addr = (i + 16) << 14; + if (i >= 24) + base_addr += 0x20000; + if ((state & 2) && (headland_ems_mr[((state & 1) << 5) | i] & 0x200)) { + virt_addr = get_headland_addr(base_addr, &headland_ems_mr[((state & 1) << 5) | i]); + if (i < 24) + mem_mapping_disable(&headland_4000_9FFF_mapping[i]); + mem_mapping_disable(&headland_ems_mapping[(((state ^ 1) & 1) << 5) | i]); + mem_mapping_enable(&headland_ems_mapping[((state & 1) << 5) | i]); + if (virt_addr < (mem_size << 10)) + mem_mapping_set_exec(&headland_ems_mapping[((state & 1) << 5) | i], ram + virt_addr); + else + mem_mapping_set_exec(&headland_ems_mapping[((state & 1) << 5) | i], NULL); + } else { + mem_mapping_set_exec(&headland_ems_mapping[((state & 1) << 5) | i], ram + base_addr); + mem_mapping_disable(&headland_ems_mapping[(((state ^ 1) & 1) << 5) | i]); + mem_mapping_disable(&headland_ems_mapping[((state & 1) << 5) | i]); - if (i < 24) - mem_mapping_enable(&headland_4000_9FFF_mapping[i]); - } - } - flushmmucache(); + if (i < 24) + mem_mapping_enable(&headland_4000_9FFF_mapping[i]); + } + } + flushmmucache(); } void headland_memmap_state_update() { - int i; - uint32_t addr; + int i; + uint32_t addr; - for (i = 0; i < 24; i++) { - addr = get_headland_addr(0x40000 + (i << 14), NULL); - mem_mapping_set_exec(&headland_4000_9FFF_mapping[i], addr < (mem_size << 10) ? ram + addr : NULL); - //pclog("headland_memmap_state_update : Address %06X to %06X\n", 0x40000 + (i << 14), addr); - } + for (i = 0; i < 24; i++) { + addr = get_headland_addr(0x40000 + (i << 14), NULL); + mem_mapping_set_exec(&headland_4000_9FFF_mapping[i], addr < (mem_size << 10) ? ram + addr : NULL); + // pclog("headland_memmap_state_update : Address %06X to %06X\n", 0x40000 + (i << 14), addr); + } - mem_set_mem_state(0xA0000, 0x40000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + mem_set_mem_state(0xA0000, 0x40000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - if (mem_size > 640) { - if ((headland_regs_cr[0] & 4) == 0) { - mem_mapping_set_addr(&headland_mid_mapping, 0x100000, mem_size > 1024 ? 0x60000 : (mem_size - 640) << 10); - mem_mapping_set_exec(&headland_mid_mapping, ram + 0xA0000); - if (mem_size > 1024) { - mem_mapping_set_addr(&headland_high_mapping, 0x160000, (mem_size - 1024) << 10); - mem_mapping_set_exec(&headland_high_mapping, ram + 0x100000); - } - } else { - mem_mapping_set_addr(&headland_mid_mapping, 0xA0000, mem_size > 1024 ? 0x60000 : (mem_size - 640) << 10); - mem_mapping_set_exec(&headland_mid_mapping, ram + 0xA0000); - if (mem_size > 1024) { - mem_mapping_set_addr(&headland_high_mapping, 0x100000, (mem_size - 1024) << 10); - mem_mapping_set_exec(&headland_high_mapping, ram + 0x100000); - } - } - } + if (mem_size > 640) { + if ((headland_regs_cr[0] & 4) == 0) { + mem_mapping_set_addr(&headland_mid_mapping, 0x100000, mem_size > 1024 ? 0x60000 : (mem_size - 640) << 10); + mem_mapping_set_exec(&headland_mid_mapping, ram + 0xA0000); + if (mem_size > 1024) { + mem_mapping_set_addr(&headland_high_mapping, 0x160000, (mem_size - 1024) << 10); + mem_mapping_set_exec(&headland_high_mapping, ram + 0x100000); + } + } else { + mem_mapping_set_addr(&headland_mid_mapping, 0xA0000, mem_size > 1024 ? 0x60000 : (mem_size - 640) << 10); + mem_mapping_set_exec(&headland_mid_mapping, ram + 0xA0000); + if (mem_size > 1024) { + mem_mapping_set_addr(&headland_high_mapping, 0x100000, (mem_size - 1024) << 10); + mem_mapping_set_exec(&headland_high_mapping, ram + 0x100000); + } + } + } - headland_set_global_EMS_state(headland_regs_cr[0] & 3); + headland_set_global_EMS_state(headland_regs_cr[0] & 3); } void headland_write(uint16_t addr, uint8_t val, void *priv) { - uint8_t old_val, index; - uint32_t base_addr, virt_addr; + uint8_t old_val, index; + uint32_t base_addr, virt_addr; - switch (addr) { - case 0x22:headland_index = val; - break; + switch (addr) { + case 0x22: + headland_index = val; + break; - case 0x23:old_val = headland_regs[headland_index]; + case 0x23: + old_val = headland_regs[headland_index]; - if (headland_index == 0xc1 && !is486) - val = 0; - headland_regs[headland_index] = val; - //pclog("Headland write %02X %02X at %04X:%04X\n",headland_index,val,CS,cpu_state.oldpc); - if (headland_index == 0x82) { - if (val & 0x10) - 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(); - } - break; + if (headland_index == 0xc1 && !is486) + val = 0; + headland_regs[headland_index] = val; + // pclog("Headland write %02X %02X at %04X:%04X\n",headland_index,val,CS,cpu_state.oldpc); + if (headland_index == 0x82) { + if (val & 0x10) + 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(); + } + break; - case 0x92: - if ((mem_a20_alt ^ val) & 2) { - mem_a20_alt = val & 2; - mem_a20_recalc(); - } - if ((~headland_port_92 & val) & 1) { - softresetx86(); - cpu_set_edx(); - } - headland_port_92 = val | 0xFC; - break; + case 0x92: + if ((mem_a20_alt ^ val) & 2) { + mem_a20_alt = val & 2; + mem_a20_recalc(); + } + if ((~headland_port_92 & val) & 1) { + softresetx86(); + cpu_set_edx(); + } + headland_port_92 = val | 0xFC; + break; - case 0x1EC: - //pclog("Set EMS Map Register to %02X(actually FF%02X) at %04X:%04X\n", val, val, CS, cpu_state.oldpc); - headland_ems_mr[headland_ems_mar & 0x3F] = val | 0xFF00; - index = headland_ems_mar & 0x1F; - base_addr = (index + 16) << 14; - if (index >= 24) - base_addr += 0x20000; - if ((headland_regs_cr[0] & 2) && ((headland_regs_cr[0] & 1) == ((headland_ems_mar & 0x20) >> 5))) { - virt_addr = get_headland_addr(base_addr, &headland_ems_mr[headland_ems_mar & 0x3F]); - if (index < 24) - mem_mapping_disable(&headland_4000_9FFF_mapping[index]); - if (virt_addr < (mem_size << 10)) - mem_mapping_set_exec(&headland_ems_mapping[headland_ems_mar & 0x3F], ram + virt_addr); - else - mem_mapping_set_exec(&headland_ems_mapping[headland_ems_mar & 0x3F], NULL); - mem_mapping_enable(&headland_ems_mapping[headland_ems_mar & 0x3F]); - pclog("Map page %d(address %05X) to address %06X\n", index, base_addr, virt_addr); - flushmmucache(); - } - if (headland_ems_mar & 0x80) - headland_ems_mar++; - break; + case 0x1EC: + // pclog("Set EMS Map Register to %02X(actually FF%02X) at %04X:%04X\n", val, val, CS, cpu_state.oldpc); + headland_ems_mr[headland_ems_mar & 0x3F] = val | 0xFF00; + index = headland_ems_mar & 0x1F; + base_addr = (index + 16) << 14; + if (index >= 24) + base_addr += 0x20000; + if ((headland_regs_cr[0] & 2) && ((headland_regs_cr[0] & 1) == ((headland_ems_mar & 0x20) >> 5))) { + virt_addr = get_headland_addr(base_addr, &headland_ems_mr[headland_ems_mar & 0x3F]); + if (index < 24) + mem_mapping_disable(&headland_4000_9FFF_mapping[index]); + if (virt_addr < (mem_size << 10)) + mem_mapping_set_exec(&headland_ems_mapping[headland_ems_mar & 0x3F], ram + virt_addr); + else + mem_mapping_set_exec(&headland_ems_mapping[headland_ems_mar & 0x3F], NULL); + mem_mapping_enable(&headland_ems_mapping[headland_ems_mar & 0x3F]); + pclog("Map page %d(address %05X) to address %06X\n", index, base_addr, virt_addr); + flushmmucache(); + } + if (headland_ems_mar & 0x80) + headland_ems_mar++; + break; - case 0x1ED: - //pclog("Set Control Register Index to %02X at %04X:%04X\n", val, CS, cpu_state.oldpc); - headland_cri = val; - break; + case 0x1ED: + // pclog("Set Control Register Index to %02X at %04X:%04X\n", val, CS, cpu_state.oldpc); + headland_cri = val; + break; - case 0x1EE: - //pclog("Set EMS Map Address Register to %02X at %04X:%04X\n", val, CS, cpu_state.oldpc); - headland_ems_mar = val; - break; + case 0x1EE: + // pclog("Set EMS Map Address Register to %02X at %04X:%04X\n", val, CS, cpu_state.oldpc); + headland_ems_mar = val; + break; - case 0x1EF: - //pclog("Set Control Register %1X to %02X at %04X:%04X\n", headland_cri, val, CS, cpu_state.oldpc); - old_val = headland_regs_cr[headland_cri]; - switch (headland_cri) { - case 0:headland_regs_cr[0] = (val & 0x1F) | headland_mem_conf_cr0[(mem_size > 640 ? mem_size : mem_size - 128) >> 9]; - mem_set_mem_state(0xE0000, 0x10000, (val & 8 ? MEM_READ_INTERNAL : MEM_READ_EXTERNAL) | MEM_WRITE_DISABLED); - mem_set_mem_state(0xF0000, 0x10000, (val & 0x10 ? MEM_READ_INTERNAL : MEM_READ_EXTERNAL) | MEM_WRITE_DISABLED); - headland_memmap_state_update(); - break; - case 1:headland_regs_cr[1] = (val & 0xBF) | headland_mem_conf_cr1[(mem_size > 640 ? mem_size : mem_size - 128) >> 9]; - headland_memmap_state_update(); - break; - case 2: - case 3: - case 5:headland_regs_cr[headland_cri] = val; - headland_memmap_state_update(); - break; - case 4:headland_regs_cr[4] = (headland_regs_cr[4] & 0xF0) | (val & 0x0F); - if (val & 1) { - mem_mapping_disable(&bios_mapping[0]); - mem_mapping_disable(&bios_mapping[1]); - mem_mapping_disable(&bios_mapping[2]); - mem_mapping_disable(&bios_mapping[3]); - } else { - mem_mapping_enable(&bios_mapping[0]); - mem_mapping_enable(&bios_mapping[1]); - mem_mapping_enable(&bios_mapping[2]); - mem_mapping_enable(&bios_mapping[3]); - } - break; - case 6: - if (headland_regs_cr[4] & 0x80) { - headland_regs_cr[headland_cri] = (val & 0xFE) | (mem_size > 8192 ? 1 : 0); - headland_memmap_state_update(); - } - break; - default:break; - } - break; + case 0x1EF: + // pclog("Set Control Register %1X to %02X at %04X:%04X\n", headland_cri, val, CS, cpu_state.oldpc); + old_val = headland_regs_cr[headland_cri]; + switch (headland_cri) { + case 0: + headland_regs_cr[0] = + (val & 0x1F) | headland_mem_conf_cr0[(mem_size > 640 ? mem_size : mem_size - 128) >> 9]; + mem_set_mem_state(0xE0000, 0x10000, + (val & 8 ? MEM_READ_INTERNAL : MEM_READ_EXTERNAL) | MEM_WRITE_DISABLED); + mem_set_mem_state(0xF0000, 0x10000, + (val & 0x10 ? MEM_READ_INTERNAL : MEM_READ_EXTERNAL) | MEM_WRITE_DISABLED); + headland_memmap_state_update(); + break; + case 1: + headland_regs_cr[1] = + (val & 0xBF) | headland_mem_conf_cr1[(mem_size > 640 ? mem_size : mem_size - 128) >> 9]; + headland_memmap_state_update(); + break; + case 2: + case 3: + case 5: + headland_regs_cr[headland_cri] = val; + headland_memmap_state_update(); + break; + case 4: + headland_regs_cr[4] = (headland_regs_cr[4] & 0xF0) | (val & 0x0F); + if (val & 1) { + mem_mapping_disable(&bios_mapping[0]); + mem_mapping_disable(&bios_mapping[1]); + mem_mapping_disable(&bios_mapping[2]); + mem_mapping_disable(&bios_mapping[3]); + } else { + mem_mapping_enable(&bios_mapping[0]); + mem_mapping_enable(&bios_mapping[1]); + mem_mapping_enable(&bios_mapping[2]); + mem_mapping_enable(&bios_mapping[3]); + } + break; + case 6: + if (headland_regs_cr[4] & 0x80) { + headland_regs_cr[headland_cri] = (val & 0xFE) | (mem_size > 8192 ? 1 : 0); + headland_memmap_state_update(); + } + break; + default: + break; + } + break; - default:break; - } + default: + break; + } } void headland_writew(uint16_t addr, uint16_t val, void *priv) { - uint8_t index; - uint32_t base_addr, virt_addr; + uint8_t index; + uint32_t base_addr, virt_addr; - switch (addr) { - case 0x1EC: - //pclog("Set EMS Map Register to %04X at %04X:%04X\n", val, CS, cpu_state.oldpc); - headland_ems_mr[headland_ems_mar & 0x3F] = val; - index = headland_ems_mar & 0x1F; - base_addr = (index + 16) << 14; - if (index >= 24) - base_addr += 0x20000; - if ((headland_regs_cr[0] & 2) && (headland_regs_cr[0] & 1) == ((headland_ems_mar & 0x20) >> 5)) { - if (val & 0x200) { - virt_addr = get_headland_addr(base_addr, &headland_ems_mr[headland_ems_mar & 0x3F]); - if (index < 24) - mem_mapping_disable(&headland_4000_9FFF_mapping[index]); - if (virt_addr < (mem_size << 10)) - mem_mapping_set_exec(&headland_ems_mapping[headland_ems_mar & 0x3F], ram + virt_addr); - else - mem_mapping_set_exec(&headland_ems_mapping[headland_ems_mar & 0x3F], NULL); - mem_mapping_enable(&headland_ems_mapping[headland_ems_mar & 0x3F]); - //pclog("Map page %d(address %05X) to address %07X(val=%04X)\n", index, base_addr, virt_addr, val); - } else { - mem_mapping_set_exec(&headland_ems_mapping[headland_ems_mar & 0x3F], ram + base_addr); - mem_mapping_disable(&headland_ems_mapping[headland_ems_mar & 0x3F]); - if (index < 24) - mem_mapping_enable(&headland_4000_9FFF_mapping[index]); - //pclog("Unmap page %d(address %05X)\n", index, base_addr); - } - flushmmucache(); - } - if (headland_ems_mar & 0x80) - headland_ems_mar++; - break; + switch (addr) { + case 0x1EC: + // pclog("Set EMS Map Register to %04X at %04X:%04X\n", val, CS, cpu_state.oldpc); + headland_ems_mr[headland_ems_mar & 0x3F] = val; + index = headland_ems_mar & 0x1F; + base_addr = (index + 16) << 14; + if (index >= 24) + base_addr += 0x20000; + if ((headland_regs_cr[0] & 2) && (headland_regs_cr[0] & 1) == ((headland_ems_mar & 0x20) >> 5)) { + if (val & 0x200) { + virt_addr = get_headland_addr(base_addr, &headland_ems_mr[headland_ems_mar & 0x3F]); + if (index < 24) + mem_mapping_disable(&headland_4000_9FFF_mapping[index]); + if (virt_addr < (mem_size << 10)) + mem_mapping_set_exec(&headland_ems_mapping[headland_ems_mar & 0x3F], ram + virt_addr); + else + mem_mapping_set_exec(&headland_ems_mapping[headland_ems_mar & 0x3F], NULL); + mem_mapping_enable(&headland_ems_mapping[headland_ems_mar & 0x3F]); + // pclog("Map page %d(address %05X) to address %07X(val=%04X)\n", index, base_addr, virt_addr, + // val); + } else { + mem_mapping_set_exec(&headland_ems_mapping[headland_ems_mar & 0x3F], ram + base_addr); + mem_mapping_disable(&headland_ems_mapping[headland_ems_mar & 0x3F]); + if (index < 24) + mem_mapping_enable(&headland_4000_9FFF_mapping[index]); + // pclog("Unmap page %d(address %05X)\n", index, base_addr); + } + flushmmucache(); + } + if (headland_ems_mar & 0x80) + headland_ems_mar++; + break; - default:break; - } + default: + break; + } } uint8_t headland_read(uint16_t addr, void *priv) { - uint8_t val; + uint8_t val; - switch (addr) { - case 0x22:val = headland_index; - break; + switch (addr) { + case 0x22: + val = headland_index; + break; - case 0x23: - if ((headland_index >= 0xc0 || headland_index == 0x20) && cpu_iscyrix) - val = 0xff; /*Don't conflict with Cyrix config registers*/ - else - val = headland_regs[headland_index]; - break; + case 0x23: + if ((headland_index >= 0xc0 || headland_index == 0x20) && cpu_iscyrix) + val = 0xff; /*Don't conflict with Cyrix config registers*/ + else + val = headland_regs[headland_index]; + break; - case 0x92:val = headland_port_92 | 0xFC; - break; + case 0x92: + val = headland_port_92 | 0xFC; + break; - case 0x1EC:val = headland_ems_mr[headland_ems_mar & 0x3F]; - if (headland_ems_mar & 0x80) - headland_ems_mar++; - break; + case 0x1EC: + val = headland_ems_mr[headland_ems_mar & 0x3F]; + if (headland_ems_mar & 0x80) + headland_ems_mar++; + break; - case 0x1ED:val = headland_cri; - break; + case 0x1ED: + val = headland_cri; + break; - case 0x1EE:val = headland_ems_mar; - break; + case 0x1EE: + val = headland_ems_mar; + break; - case 0x1EF: - switch (headland_cri) { - case 0:val = (headland_regs_cr[0] & 0x1F) | headland_mem_conf_cr0[(mem_size > 640 ? mem_size : mem_size - 128) >> 9]; - break; - case 1:val = (headland_regs_cr[1] & 0xBF) | headland_mem_conf_cr1[(mem_size > 640 ? mem_size : mem_size - 128) >> 9]; - break; - case 6: - if (headland_regs_cr[4] & 0x80) - val = (headland_regs_cr[6] & 0xFE) | (mem_size > 8192 ? 1 : 0); - else - val = 0; - break; - default:val = headland_regs_cr[headland_cri]; - break; - } - break; + case 0x1EF: + switch (headland_cri) { + case 0: + val = (headland_regs_cr[0] & 0x1F) | + headland_mem_conf_cr0[(mem_size > 640 ? mem_size : mem_size - 128) >> 9]; + break; + case 1: + val = (headland_regs_cr[1] & 0xBF) | + headland_mem_conf_cr1[(mem_size > 640 ? mem_size : mem_size - 128) >> 9]; + break; + case 6: + if (headland_regs_cr[4] & 0x80) + val = (headland_regs_cr[6] & 0xFE) | (mem_size > 8192 ? 1 : 0); + else + val = 0; + break; + default: + val = headland_regs_cr[headland_cri]; + break; + } + break; - default:val = 0xFF; - break; - } + default: + val = 0xFF; + break; + } - return val; + return val; } uint16_t headland_readw(uint16_t addr, void *priv) { - uint16_t val; + uint16_t val; - switch (addr) { - case 0x1EC:val = headland_ems_mr[headland_ems_mar & 0x3F] | ((headland_regs_cr[4] & 0x80) ? 0xF000 : 0xFC00); - if (headland_ems_mar & 0x80) - headland_ems_mar++; - break; + switch (addr) { + case 0x1EC: + val = headland_ems_mr[headland_ems_mar & 0x3F] | ((headland_regs_cr[4] & 0x80) ? 0xF000 : 0xFC00); + if (headland_ems_mar & 0x80) + headland_ems_mar++; + break; - default:val = 0xFFFF; - break; - } + default: + val = 0xFFFF; + break; + } - return val; + return val; } uint8_t mem_read_headlandb(uint32_t addr, void *priv) { - uint8_t val = 0xff; + uint8_t val = 0xff; - addr = get_headland_addr(addr, priv); - if (addr < (mem_size << 10)) - val = ram[addr]; + addr = get_headland_addr(addr, priv); + if (addr < (mem_size << 10)) + val = ram[addr]; - return val; + return val; } void mem_write_headlandb(uint32_t addr, uint8_t val, void *priv) { - addr = get_headland_addr(addr, priv); - if (addr < (mem_size << 10)) - ram[addr] = val; + addr = get_headland_addr(addr, priv); + if (addr < (mem_size << 10)) + ram[addr] = val; } uint16_t mem_read_headlandw(uint32_t addr, void *priv) { - uint16_t val = 0xffff; + uint16_t val = 0xffff; - if ((addr & 0x3FFF) == 0x3FFF) - pclog("mem_read_headlandw(%08X, %p) called.\n", addr, priv); - addr = get_headland_addr(addr, priv); - if (addr < (mem_size << 10)) - val = *(uint16_t *)&ram[addr]; + if ((addr & 0x3FFF) == 0x3FFF) + pclog("mem_read_headlandw(%08X, %p) called.\n", addr, priv); + addr = get_headland_addr(addr, priv); + if (addr < (mem_size << 10)) + val = *(uint16_t *)&ram[addr]; - return val; + return val; } void mem_write_headlandw(uint32_t addr, uint16_t val, void *priv) { - if ((addr & 0x3FFF) == 0x3FFF) - pclog("mem_write_headlandw(%08X, %04X, %p) called.\n", addr, val, priv); - addr = get_headland_addr(addr, priv); - if (addr < (mem_size << 10)) - *(uint16_t *)&ram[addr] = val; + if ((addr & 0x3FFF) == 0x3FFF) + pclog("mem_write_headlandw(%08X, %04X, %p) called.\n", addr, val, priv); + addr = get_headland_addr(addr, priv); + if (addr < (mem_size << 10)) + *(uint16_t *)&ram[addr] = val; } uint32_t mem_read_headlandl(uint32_t addr, void *priv) { - uint32_t val = 0xffffffff; + uint32_t val = 0xffffffff; - if ((addr & 0x3FFF) > 0x3FFC) - pclog("mem_read_headlandl(%08X, %p) called.\n", addr, priv); - addr = get_headland_addr(addr, priv); - if (addr < (mem_size << 10)) - val = *(uint32_t *)&ram[addr]; + if ((addr & 0x3FFF) > 0x3FFC) + pclog("mem_read_headlandl(%08X, %p) called.\n", addr, priv); + addr = get_headland_addr(addr, priv); + if (addr < (mem_size << 10)) + val = *(uint32_t *)&ram[addr]; - return val; + return val; } void mem_write_headlandl(uint32_t addr, uint32_t val, void *priv) { - if ((addr & 0x3FFF) > 0x3FFC) - pclog("mem_write_headland(%08X, %08X, %p) called.\n", addr, val, priv); - addr = get_headland_addr(addr, priv); - if (addr < (mem_size << 10)) - *(uint32_t *)&ram[addr] = val; + if ((addr & 0x3FFF) > 0x3FFC) + pclog("mem_write_headland(%08X, %08X, %p) called.\n", addr, val, priv); + addr = get_headland_addr(addr, priv); + if (addr < (mem_size << 10)) + *(uint32_t *)&ram[addr] = val; } void headland_init() { - int i; + int i; - for (i = 0; i < 8; i++) - headland_regs_cr[i] = 0; - headland_regs_cr[0] = 4; + for (i = 0; i < 8; i++) + headland_regs_cr[i] = 0; + headland_regs_cr[0] = 4; - switch (romset) { - case ROM_AMI386SX: - // Remark - Previously distributed AMI386 BIOS doesn't seem to be for the Headland chipset. - io_sethandler(0x0022, 0x0002, headland_read, NULL, NULL, headland_write, NULL, NULL, NULL); - break; - case ROM_AMA932J:headland_regs_cr[4] = 0x20; - io_sethandler(0x0092, 0x0001, headland_read, NULL, NULL, headland_write, NULL, NULL, NULL); - break; - default:headland_regs_cr[4] = 0; - break; - } + switch (romset) { + case ROM_AMI386SX: + // Remark - Previously distributed AMI386 BIOS doesn't seem to be for the Headland chipset. + io_sethandler(0x0022, 0x0002, headland_read, NULL, NULL, headland_write, NULL, NULL, NULL); + break; + case ROM_AMA932J: + headland_regs_cr[4] = 0x20; + io_sethandler(0x0092, 0x0001, headland_read, NULL, NULL, headland_write, NULL, NULL, NULL); + break; + default: + headland_regs_cr[4] = 0; + break; + } - io_sethandler(0x01EC, 0x0001, headland_read, headland_readw, NULL, headland_write, headland_writew, NULL, NULL); - io_sethandler(0x01ED, 0x0003, headland_read, NULL, NULL, headland_write, NULL, NULL, NULL); + io_sethandler(0x01EC, 0x0001, headland_read, headland_readw, NULL, headland_write, headland_writew, NULL, NULL); + io_sethandler(0x01ED, 0x0003, headland_read, NULL, NULL, headland_write, NULL, NULL, NULL); - for (i = 0; i < 64; i++) - headland_ems_mr[i] = 0; + for (i = 0; i < 64; i++) + headland_ems_mr[i] = 0; - mem_mapping_disable(&ram_low_mapping); - mem_mapping_disable(&ram_mid_mapping); - mem_mapping_disable(&ram_high_mapping); + mem_mapping_disable(&ram_low_mapping); + mem_mapping_disable(&ram_mid_mapping); + mem_mapping_disable(&ram_high_mapping); - mem_mapping_add(&headland_low_mapping, - 0, - 0x40000, - mem_read_headlandb, - mem_read_headlandw, - mem_read_headlandl, - mem_write_headlandb, - mem_write_headlandw, - mem_write_headlandl, - ram, - MEM_MAPPING_INTERNAL, - NULL); + mem_mapping_add(&headland_low_mapping, 0, 0x40000, mem_read_headlandb, mem_read_headlandw, mem_read_headlandl, + mem_write_headlandb, mem_write_headlandw, mem_write_headlandl, ram, MEM_MAPPING_INTERNAL, NULL); - if (mem_size > 640) { - mem_mapping_add(&headland_mid_mapping, - 0xA0000, - 0x60000, - mem_read_headlandb, - mem_read_headlandw, - mem_read_headlandl, - mem_write_headlandb, - mem_write_headlandw, - mem_write_headlandl, - ram + 0xA0000, - MEM_MAPPING_INTERNAL, - NULL); - mem_mapping_enable(&headland_mid_mapping); - } + if (mem_size > 640) { + mem_mapping_add(&headland_mid_mapping, 0xA0000, 0x60000, mem_read_headlandb, mem_read_headlandw, + mem_read_headlandl, mem_write_headlandb, mem_write_headlandw, mem_write_headlandl, ram + 0xA0000, + MEM_MAPPING_INTERNAL, NULL); + mem_mapping_enable(&headland_mid_mapping); + } - if (mem_size > 1024) { - mem_mapping_add(&headland_high_mapping, - 0x100000, - ((mem_size - 1024) * 1024), - mem_read_headlandb, - mem_read_headlandw, - mem_read_headlandl, - mem_write_headlandb, - mem_write_headlandw, - mem_write_headlandl, - ram + 0x100000, - MEM_MAPPING_INTERNAL, - NULL); - mem_mapping_enable(&headland_high_mapping); - } + if (mem_size > 1024) { + mem_mapping_add(&headland_high_mapping, 0x100000, ((mem_size - 1024) * 1024), mem_read_headlandb, + mem_read_headlandw, mem_read_headlandl, mem_write_headlandb, mem_write_headlandw, + mem_write_headlandl, ram + 0x100000, MEM_MAPPING_INTERNAL, NULL); + mem_mapping_enable(&headland_high_mapping); + } - for (i = 0; i < 24; i++) { - mem_mapping_add(&headland_4000_9FFF_mapping[i], - 0x40000 + (i << 14), - 0x4000, - mem_read_headlandb, - mem_read_headlandw, - mem_read_headlandl, - mem_write_headlandb, - mem_write_headlandw, - mem_write_headlandl, - mem_size > 256 + (i << 4) ? ram + 0x40000 + (i << 14) : NULL, - MEM_MAPPING_INTERNAL, - NULL); - mem_mapping_enable(&headland_4000_9FFF_mapping[i]); - } + for (i = 0; i < 24; i++) { + mem_mapping_add(&headland_4000_9FFF_mapping[i], 0x40000 + (i << 14), 0x4000, mem_read_headlandb, + mem_read_headlandw, mem_read_headlandl, mem_write_headlandb, mem_write_headlandw, + mem_write_headlandl, mem_size > 256 + (i << 4) ? ram + 0x40000 + (i << 14) : NULL, + MEM_MAPPING_INTERNAL, NULL); + mem_mapping_enable(&headland_4000_9FFF_mapping[i]); + } - for (i = 0; i < 64; i++) { - headland_ems_mr[i] = 0; - mem_mapping_add(&headland_ems_mapping[i], - ((i & 31) + ((i & 31) >= 24 ? 24 : 16)) << 14, - 0x04000, - mem_read_headlandb, - mem_read_headlandw, - mem_read_headlandl, - mem_write_headlandb, - mem_write_headlandw, - mem_write_headlandl, - ram + (((i & 31) + ((i & 31) >= 24 ? 24 : 16)) << 14), - 0, - &headland_ems_mr[i]); - mem_mapping_disable(&headland_ems_mapping[i]); - } + for (i = 0; i < 64; i++) { + headland_ems_mr[i] = 0; + mem_mapping_add(&headland_ems_mapping[i], ((i & 31) + ((i & 31) >= 24 ? 24 : 16)) << 14, 0x04000, + mem_read_headlandb, mem_read_headlandw, mem_read_headlandl, mem_write_headlandb, + mem_write_headlandw, mem_write_headlandl, ram + (((i & 31) + ((i & 31) >= 24 ? 24 : 16)) << 14), + 0, &headland_ems_mr[i]); + mem_mapping_disable(&headland_ems_mapping[i]); + } - headland_memmap_state_update(); + headland_memmap_state_update(); } diff --git a/src/models/i430fx.c b/src/models/i430fx.c index 5f36a285..4c5cc01b 100644 --- a/src/models/i430fx.c +++ b/src/models/i430fx.c @@ -12,169 +12,176 @@ static uint8_t card_i430fx[256]; static void i430fx_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(); + 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(); } void i430fx_write(int func, int addr, uint8_t val, void *priv) { - if (func) - return; + if (func) + return; - if (addr >= 0x10 && addr < 0x4f) - 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; + 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 &= 0x02; - val |= 0x04; - break; - case 0x05:val = 0; - break; + case 0x04: /*Command register*/ + val &= 0x02; + val |= 0x04; + break; + case 0x05: + val = 0; + break; - case 0x06: /*Status*/ - val = 0; - break; - case 0x07:val = 0x02; - break; + case 0x06: /*Status*/ + val = 0; + break; + case 0x07: + val = 0x02; + break; - case 0x59: /*PAM0*/ - if ((card_i430fx[0x59] ^ val) & 0xf0) { - i430fx_map(0xf0000, 0x10000, val >> 4); - } - pclog("i430fx_write : PAM0 write %02X\n", val); - break; - case 0x5a: /*PAM1*/ - if ((card_i430fx[0x5a] ^ val) & 0x0f) - i430fx_map(0xc0000, 0x04000, val & 0xf); - if ((card_i430fx[0x5a] ^ val) & 0xf0) - i430fx_map(0xc4000, 0x04000, val >> 4); - break; - case 0x5b: /*PAM2*/ - if ((card_i430fx[0x5b] ^ val) & 0x0f) - i430fx_map(0xc8000, 0x04000, val & 0xf); - if ((card_i430fx[0x5b] ^ val) & 0xf0) - i430fx_map(0xcc000, 0x04000, val >> 4); - break; - case 0x5c: /*PAM3*/ - if ((card_i430fx[0x5c] ^ val) & 0x0f) - i430fx_map(0xd0000, 0x04000, val & 0xf); - if ((card_i430fx[0x5c] ^ val) & 0xf0) - i430fx_map(0xd4000, 0x04000, val >> 4); - break; - case 0x5d: /*PAM4*/ - if ((card_i430fx[0x5d] ^ val) & 0x0f) - i430fx_map(0xd8000, 0x04000, val & 0xf); - if ((card_i430fx[0x5d] ^ val) & 0xf0) - i430fx_map(0xdc000, 0x04000, val >> 4); - break; - case 0x5e: /*PAM5*/ - if ((card_i430fx[0x5e] ^ val) & 0x0f) - i430fx_map(0xe0000, 0x04000, val & 0xf); - if ((card_i430fx[0x5e] ^ val) & 0xf0) - i430fx_map(0xe4000, 0x04000, val >> 4); - pclog("i430fx_write : PAM5 write %02X\n", val); - break; - case 0x5f: /*PAM6*/ - if ((card_i430fx[0x5f] ^ val) & 0x0f) - i430fx_map(0xe8000, 0x04000, val & 0xf); - if ((card_i430fx[0x5f] ^ val) & 0xf0) - i430fx_map(0xec000, 0x04000, val >> 4); - pclog("i430fx_write : PAM6 write %02X\n", val); - break; + case 0x59: /*PAM0*/ + if ((card_i430fx[0x59] ^ val) & 0xf0) { + i430fx_map(0xf0000, 0x10000, val >> 4); + } + pclog("i430fx_write : PAM0 write %02X\n", val); + break; + case 0x5a: /*PAM1*/ + if ((card_i430fx[0x5a] ^ val) & 0x0f) + i430fx_map(0xc0000, 0x04000, val & 0xf); + if ((card_i430fx[0x5a] ^ val) & 0xf0) + i430fx_map(0xc4000, 0x04000, val >> 4); + break; + case 0x5b: /*PAM2*/ + if ((card_i430fx[0x5b] ^ val) & 0x0f) + i430fx_map(0xc8000, 0x04000, val & 0xf); + if ((card_i430fx[0x5b] ^ val) & 0xf0) + i430fx_map(0xcc000, 0x04000, val >> 4); + break; + case 0x5c: /*PAM3*/ + if ((card_i430fx[0x5c] ^ val) & 0x0f) + i430fx_map(0xd0000, 0x04000, val & 0xf); + if ((card_i430fx[0x5c] ^ val) & 0xf0) + i430fx_map(0xd4000, 0x04000, val >> 4); + break; + case 0x5d: /*PAM4*/ + if ((card_i430fx[0x5d] ^ val) & 0x0f) + i430fx_map(0xd8000, 0x04000, val & 0xf); + if ((card_i430fx[0x5d] ^ val) & 0xf0) + i430fx_map(0xdc000, 0x04000, val >> 4); + break; + case 0x5e: /*PAM5*/ + if ((card_i430fx[0x5e] ^ val) & 0x0f) + i430fx_map(0xe0000, 0x04000, val & 0xf); + if ((card_i430fx[0x5e] ^ val) & 0xf0) + i430fx_map(0xe4000, 0x04000, val >> 4); + pclog("i430fx_write : PAM5 write %02X\n", val); + break; + case 0x5f: /*PAM6*/ + if ((card_i430fx[0x5f] ^ val) & 0x0f) + i430fx_map(0xe8000, 0x04000, val & 0xf); + if ((card_i430fx[0x5f] ^ val) & 0xf0) + i430fx_map(0xec000, 0x04000, val >> 4); + pclog("i430fx_write : PAM6 write %02X\n", val); + break; - case 0x72: /*SMRAM*/ - pclog("Write SMRAM %02x\n", val); - val = (val & 0x78) | 2; /*SMRAM always at A0000-BFFFF*/ - val |= (card_i430fx[0x72] & 0x10); /*D_LCK can not be cleared by software*/ - if (val & 0x10) /*D_LCK locks D_OPEN and G_SMRAME*/ - { - val &= ~0x48; /*D_OPEN is forced to 0, G_SMRAME is read only*/ - val |= (card_i430fx[0x72] & 0x08); - } - if ((card_i430fx[0x72] ^ val) & 0x40) { - if (val & 0x40) /*SMRAM enabled*/ - { - pclog("Enable SMRAM\n"); - mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - } else { - pclog("Disable SMRAM\n"); - mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - } - } - break; - } + case 0x72: /*SMRAM*/ + pclog("Write SMRAM %02x\n", val); + val = (val & 0x78) | 2; /*SMRAM always at A0000-BFFFF*/ + val |= (card_i430fx[0x72] & 0x10); /*D_LCK can not be cleared by software*/ + if (val & 0x10) /*D_LCK locks D_OPEN and G_SMRAME*/ + { + val &= ~0x48; /*D_OPEN is forced to 0, G_SMRAME is read only*/ + val |= (card_i430fx[0x72] & 0x08); + } + if ((card_i430fx[0x72] ^ val) & 0x40) { + if (val & 0x40) /*SMRAM enabled*/ + { + pclog("Enable SMRAM\n"); + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } else { + pclog("Disable SMRAM\n"); + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + } + } + break; + } - card_i430fx[addr] = val; + card_i430fx[addr] = val; } uint8_t i430fx_read(int func, int addr, void *priv) { - if (func) - return 0xff; + if (func) + return 0xff; - return card_i430fx[addr]; + return card_i430fx[addr]; } static void i430fx_smram_enable(void) { - if (card_i430fx[0x72] & 8) - mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + if (card_i430fx[0x72] & 8) + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); } static void i430fx_smram_disable(void) { - if (card_i430fx[0x72] & 8) - mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + if (card_i430fx[0x72] & 8) + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); } void i430fx_init() { - pci_add_specific(0, i430fx_read, i430fx_write, NULL); + pci_add_specific(0, i430fx_read, i430fx_write, NULL); - memset(card_i430fx, 0, 256); - card_i430fx[0x00] = 0x86; - card_i430fx[0x01] = 0x80; /*Intel*/ - card_i430fx[0x02] = 0x2d; - card_i430fx[0x03] = 0x12; /*SB82437FX-66*/ - card_i430fx[0x04] = 0x06; - card_i430fx[0x05] = 0x00; - card_i430fx[0x06] = 0x00; - card_i430fx[0x07] = 0x82; - card_i430fx[0x08] = 0x00; /*A0 stepping*/ - card_i430fx[0x09] = 0x00; - card_i430fx[0x0a] = 0x00; - card_i430fx[0x0b] = 0x06; - card_i430fx[0x52] = 0x40; /*256kb PLB cache*/ -// card_i430fx[0x53] = 0x14; -// card_i430fx[0x56] = 0x52; /*DRAM control*/ - card_i430fx[0x57] = 0x01; - card_i430fx[0x60] = card_i430fx[0x61] = card_i430fx[0x62] = card_i430fx[0x63] = card_i430fx[0x64] = 0x02; -// card_i430fx[0x67] = 0x11; -// card_i430fx[0x69] = 0x03; -// card_i430fx[0x70] = 0x20; - card_i430fx[0x72] = 0x02; -// card_i430fx[0x74] = 0x0e; -// card_i430fx[0x78] = 0x23; + memset(card_i430fx, 0, 256); + card_i430fx[0x00] = 0x86; + card_i430fx[0x01] = 0x80; /*Intel*/ + card_i430fx[0x02] = 0x2d; + card_i430fx[0x03] = 0x12; /*SB82437FX-66*/ + card_i430fx[0x04] = 0x06; + card_i430fx[0x05] = 0x00; + card_i430fx[0x06] = 0x00; + card_i430fx[0x07] = 0x82; + card_i430fx[0x08] = 0x00; /*A0 stepping*/ + card_i430fx[0x09] = 0x00; + card_i430fx[0x0a] = 0x00; + card_i430fx[0x0b] = 0x06; + card_i430fx[0x52] = 0x40; /*256kb PLB cache*/ + // card_i430fx[0x53] = 0x14; + // card_i430fx[0x56] = 0x52; /*DRAM control*/ + card_i430fx[0x57] = 0x01; + card_i430fx[0x60] = card_i430fx[0x61] = card_i430fx[0x62] = card_i430fx[0x63] = card_i430fx[0x64] = 0x02; + // card_i430fx[0x67] = 0x11; + // card_i430fx[0x69] = 0x03; + // card_i430fx[0x70] = 0x20; + card_i430fx[0x72] = 0x02; + // card_i430fx[0x74] = 0x0e; + // card_i430fx[0x78] = 0x23; - smram_enable = i430fx_smram_enable; - smram_disable = i430fx_smram_disable; + smram_enable = i430fx_smram_enable; + smram_disable = i430fx_smram_disable; } void i430fx_reset() { - i430fx_write(0, 0x59, 0xf, NULL); /*Should reset all PCI devices, but just set PAM0 to point to ROM for now*/ + i430fx_write(0, 0x59, 0xf, NULL); /*Should reset all PCI devices, but just set PAM0 to point to ROM for now*/ } diff --git a/src/models/i430hx.c b/src/models/i430hx.c index e7bad6eb..49bf86d9 100644 --- a/src/models/i430hx.c +++ b/src/models/i430hx.c @@ -10,167 +10,174 @@ static uint8_t card_i430hx[256]; static void i430hx_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(); + 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(); } void i430hx_write(int func, int addr, uint8_t val, void *priv) { - if (func) - return; + if (func) + return; - if (addr >= 0x10 && addr < 0x4f) - 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; + 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 &= 0x02; - val |= 0x04; - break; - case 0x05:val = 0; - break; + case 0x04: /*Command register*/ + val &= 0x02; + val |= 0x04; + break; + case 0x05: + val = 0; + break; - case 0x06: /*Status*/ - val = 0; - break; - case 0x07:val &= 0x80; - val |= 0x02; - break; + case 0x06: /*Status*/ + val = 0; + break; + case 0x07: + val &= 0x80; + val |= 0x02; + break; - case 0x59: /*PAM0*/ - if ((card_i430hx[0x59] ^ val) & 0xf0) { - i430hx_map(0xf0000, 0x10000, val >> 4); -// shadowbios = (val & 0x10); - } - pclog("i430hx_write : PAM0 write %02X\n", val); - break; - case 0x5a: /*PAM1*/ - if ((card_i430hx[0x5a] ^ val) & 0x0f) - i430hx_map(0xc0000, 0x04000, val & 0xf); - if ((card_i430hx[0x5a] ^ val) & 0xf0) - i430hx_map(0xc4000, 0x04000, val >> 4); - break; - case 0x5b: /*PAM2*/ - if ((card_i430hx[0x5b] ^ val) & 0x0f) - i430hx_map(0xc8000, 0x04000, val & 0xf); - if ((card_i430hx[0x5b] ^ val) & 0xf0) - i430hx_map(0xcc000, 0x04000, val >> 4); - break; - case 0x5c: /*PAM3*/ - if ((card_i430hx[0x5c] ^ val) & 0x0f) - i430hx_map(0xd0000, 0x04000, val & 0xf); - if ((card_i430hx[0x5c] ^ val) & 0xf0) - i430hx_map(0xd4000, 0x04000, val >> 4); - break; - case 0x5d: /*PAM4*/ - if ((card_i430hx[0x5d] ^ val) & 0x0f) - i430hx_map(0xd8000, 0x04000, val & 0xf); - if ((card_i430hx[0x5d] ^ val) & 0xf0) - i430hx_map(0xdc000, 0x04000, val >> 4); - break; - case 0x5e: /*PAM5*/ - if ((card_i430hx[0x5e] ^ val) & 0x0f) - i430hx_map(0xe0000, 0x04000, val & 0xf); - if ((card_i430hx[0x5e] ^ val) & 0xf0) - i430hx_map(0xe4000, 0x04000, val >> 4); - pclog("i430hx_write : PAM5 write %02X\n", val); - break; - case 0x5f: /*PAM6*/ - if ((card_i430hx[0x5f] ^ val) & 0x0f) - i430hx_map(0xe8000, 0x04000, val & 0xf); - if ((card_i430hx[0x5f] ^ val) & 0xf0) - i430hx_map(0xec000, 0x04000, val >> 4); - pclog("i430hx_write : PAM6 write %02X\n", val); - break; + case 0x59: /*PAM0*/ + if ((card_i430hx[0x59] ^ val) & 0xf0) { + i430hx_map(0xf0000, 0x10000, val >> 4); + // shadowbios = (val & 0x10); + } + pclog("i430hx_write : PAM0 write %02X\n", val); + break; + case 0x5a: /*PAM1*/ + if ((card_i430hx[0x5a] ^ val) & 0x0f) + i430hx_map(0xc0000, 0x04000, val & 0xf); + if ((card_i430hx[0x5a] ^ val) & 0xf0) + i430hx_map(0xc4000, 0x04000, val >> 4); + break; + case 0x5b: /*PAM2*/ + if ((card_i430hx[0x5b] ^ val) & 0x0f) + i430hx_map(0xc8000, 0x04000, val & 0xf); + if ((card_i430hx[0x5b] ^ val) & 0xf0) + i430hx_map(0xcc000, 0x04000, val >> 4); + break; + case 0x5c: /*PAM3*/ + if ((card_i430hx[0x5c] ^ val) & 0x0f) + i430hx_map(0xd0000, 0x04000, val & 0xf); + if ((card_i430hx[0x5c] ^ val) & 0xf0) + i430hx_map(0xd4000, 0x04000, val >> 4); + break; + case 0x5d: /*PAM4*/ + if ((card_i430hx[0x5d] ^ val) & 0x0f) + i430hx_map(0xd8000, 0x04000, val & 0xf); + if ((card_i430hx[0x5d] ^ val) & 0xf0) + i430hx_map(0xdc000, 0x04000, val >> 4); + break; + case 0x5e: /*PAM5*/ + if ((card_i430hx[0x5e] ^ val) & 0x0f) + i430hx_map(0xe0000, 0x04000, val & 0xf); + if ((card_i430hx[0x5e] ^ val) & 0xf0) + i430hx_map(0xe4000, 0x04000, val >> 4); + pclog("i430hx_write : PAM5 write %02X\n", val); + break; + case 0x5f: /*PAM6*/ + if ((card_i430hx[0x5f] ^ val) & 0x0f) + i430hx_map(0xe8000, 0x04000, val & 0xf); + if ((card_i430hx[0x5f] ^ val) & 0xf0) + i430hx_map(0xec000, 0x04000, val >> 4); + pclog("i430hx_write : PAM6 write %02X\n", val); + break; - case 0x72: /*SMRAM*/ - pclog("Write SMRAM %02x\n", val); - val = (val & 0x78) | 2; /*SMRAM always at A0000-BFFFF*/ - val |= (card_i430hx[0x72] & 0x10); /*D_LCK can not be cleared by software*/ - if (val & 0x10) /*D_LCK locks D_OPEN and G_SMRAME*/ - { - val &= ~0x48; /*D_OPEN is forced to 0, G_SMRAME is read only*/ - val |= (card_i430hx[0x72] & 0x08); - } - if ((card_i430hx[0x72] ^ val) & 0x40) { - if (val & 0x40) /*SMRAM enabled*/ - { - pclog("Enable SMRAM\n"); - mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - } else { - pclog("Disable SMRAM\n"); - mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - } - } - break; - } + case 0x72: /*SMRAM*/ + pclog("Write SMRAM %02x\n", val); + val = (val & 0x78) | 2; /*SMRAM always at A0000-BFFFF*/ + val |= (card_i430hx[0x72] & 0x10); /*D_LCK can not be cleared by software*/ + if (val & 0x10) /*D_LCK locks D_OPEN and G_SMRAME*/ + { + val &= ~0x48; /*D_OPEN is forced to 0, G_SMRAME is read only*/ + val |= (card_i430hx[0x72] & 0x08); + } + if ((card_i430hx[0x72] ^ val) & 0x40) { + if (val & 0x40) /*SMRAM enabled*/ + { + pclog("Enable SMRAM\n"); + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } else { + pclog("Disable SMRAM\n"); + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + } + } + break; + } - card_i430hx[addr] = val; + card_i430hx[addr] = val; } uint8_t i430hx_read(int func, int addr, void *priv) { - if (func) - return 0xff; + if (func) + return 0xff; - return card_i430hx[addr]; + return card_i430hx[addr]; } static void i430hx_smram_enable(void) { - if (card_i430hx[0x72] & 8) - mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + if (card_i430hx[0x72] & 8) + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); } static void i430hx_smram_disable(void) { - if (card_i430hx[0x72] & 8) - mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + if (card_i430hx[0x72] & 8) + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); } void i430hx_init() { - pci_add_specific(0, i430hx_read, i430hx_write, NULL); + pci_add_specific(0, i430hx_read, i430hx_write, NULL); - memset(card_i430hx, 0, 256); - card_i430hx[0x00] = 0x86; - card_i430hx[0x01] = 0x80; /*Intel*/ - card_i430hx[0x02] = 0x50; - card_i430hx[0x03] = 0x12; /*82439HX*/ - card_i430hx[0x04] = 0x06; - card_i430hx[0x05] = 0x00; - card_i430hx[0x07] = 0x02; - card_i430hx[0x08] = 0x00; /*A0 stepping*/ - card_i430hx[0x0B] = 0x06; - card_i430hx[0x51] = 0x20; - card_i430hx[0x52] = 0xB5; /*512kb cache*/ - card_i430hx[0x56] = 0x52; /*DRAM control*/ - card_i430hx[0x59] = 0x40; - card_i430hx[0x5A] = card_i430hx[0x5B] = card_i430hx[0x5C] = card_i430hx[0x5D] = 0x44; - card_i430hx[0x5E] = card_i430hx[0x5F] = 0x44; - card_i430hx[0x60] = card_i430hx[0x61] = card_i430hx[0x62] = card_i430hx[0x63] = 0x02; - card_i430hx[0x64] = card_i430hx[0x5F] = 0x02; - card_i430hx[0x65] = card_i430hx[0x66] = card_i430hx[0x67] = 0x02; - card_i430hx[0x68] = 0x11; + memset(card_i430hx, 0, 256); + card_i430hx[0x00] = 0x86; + card_i430hx[0x01] = 0x80; /*Intel*/ + card_i430hx[0x02] = 0x50; + card_i430hx[0x03] = 0x12; /*82439HX*/ + card_i430hx[0x04] = 0x06; + card_i430hx[0x05] = 0x00; + card_i430hx[0x07] = 0x02; + card_i430hx[0x08] = 0x00; /*A0 stepping*/ + card_i430hx[0x0B] = 0x06; + card_i430hx[0x51] = 0x20; + card_i430hx[0x52] = 0xB5; /*512kb cache*/ + card_i430hx[0x56] = 0x52; /*DRAM control*/ + card_i430hx[0x59] = 0x40; + card_i430hx[0x5A] = card_i430hx[0x5B] = card_i430hx[0x5C] = card_i430hx[0x5D] = 0x44; + card_i430hx[0x5E] = card_i430hx[0x5F] = 0x44; + card_i430hx[0x60] = card_i430hx[0x61] = card_i430hx[0x62] = card_i430hx[0x63] = 0x02; + card_i430hx[0x64] = card_i430hx[0x5F] = 0x02; + card_i430hx[0x65] = card_i430hx[0x66] = card_i430hx[0x67] = 0x02; + card_i430hx[0x68] = 0x11; - smram_enable = i430hx_smram_enable; - smram_disable = i430hx_smram_disable; + smram_enable = i430hx_smram_enable; + smram_disable = i430hx_smram_disable; } void i430hx_reset() { - i430hx_write(0, 0x59, 0xf, NULL); /*Should reset all PCI devices, but just set PAM0 to point to ROM for now*/ + i430hx_write(0, 0x59, 0xf, NULL); /*Should reset all PCI devices, but just set PAM0 to point to ROM for now*/ } diff --git a/src/models/i430lx.c b/src/models/i430lx.c index eb7c5eaf..f8a49a17 100644 --- a/src/models/i430lx.c +++ b/src/models/i430lx.c @@ -14,188 +14,190 @@ static uint8_t card_i430lx[256]; static void i430lx_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(); + 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(); } void i430lx_write(int func, int addr, uint8_t val, void *priv) { - if (func) - return; + if (func) + return; - if (addr >= 0x10 && addr < 0x4f) - 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; + 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 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 0x06: /*Status*/ + val = 0; + break; + case 0x07: + val = 0x02; + break; - case 0x59: /*PAM0*/ - if ((card_i430lx[0x59] ^ val) & 0xf0) { - i430lx_map(0xf0000, 0x10000, val >> 4); - } - pclog("i430lx_write : PAM0 write %02X\n", val); - break; - case 0x5a: /*PAM1*/ - if ((card_i430lx[0x5a] ^ val) & 0x0f) - i430lx_map(0xc0000, 0x04000, val & 0xf); - if ((card_i430lx[0x5a] ^ val) & 0xf0) - i430lx_map(0xc4000, 0x04000, val >> 4); - break; - case 0x5b: /*PAM2*/ - if ((card_i430lx[0x5b] ^ val) & 0x0f) - i430lx_map(0xc8000, 0x04000, val & 0xf); - if ((card_i430lx[0x5b] ^ val) & 0xf0) - i430lx_map(0xcc000, 0x04000, val >> 4); - break; - case 0x5c: /*PAM3*/ - if ((card_i430lx[0x5c] ^ val) & 0x0f) - i430lx_map(0xd0000, 0x04000, val & 0xf); - if ((card_i430lx[0x5c] ^ val) & 0xf0) - i430lx_map(0xd4000, 0x04000, val >> 4); - break; - case 0x5d: /*PAM4*/ - if ((card_i430lx[0x5d] ^ val) & 0x0f) - i430lx_map(0xd8000, 0x04000, val & 0xf); - if ((card_i430lx[0x5d] ^ val) & 0xf0) - i430lx_map(0xdc000, 0x04000, val >> 4); - break; - case 0x5e: /*PAM5*/ - if ((card_i430lx[0x5e] ^ val) & 0x0f) - i430lx_map(0xe0000, 0x04000, val & 0xf); - if ((card_i430lx[0x5e] ^ val) & 0xf0) - i430lx_map(0xe4000, 0x04000, val >> 4); - pclog("i430lx_write : PAM5 write %02X\n", val); - break; - case 0x5f: /*PAM6*/ - if ((card_i430lx[0x5f] ^ val) & 0x0f) - i430lx_map(0xe8000, 0x04000, val & 0xf); - if ((card_i430lx[0x5f] ^ val) & 0xf0) - i430lx_map(0xec000, 0x04000, val >> 4); - pclog("i430lx_write : PAM6 write %02X\n", val); - break; + case 0x59: /*PAM0*/ + if ((card_i430lx[0x59] ^ val) & 0xf0) { + i430lx_map(0xf0000, 0x10000, val >> 4); + } + pclog("i430lx_write : PAM0 write %02X\n", val); + break; + case 0x5a: /*PAM1*/ + if ((card_i430lx[0x5a] ^ val) & 0x0f) + i430lx_map(0xc0000, 0x04000, val & 0xf); + if ((card_i430lx[0x5a] ^ val) & 0xf0) + i430lx_map(0xc4000, 0x04000, val >> 4); + break; + case 0x5b: /*PAM2*/ + if ((card_i430lx[0x5b] ^ val) & 0x0f) + i430lx_map(0xc8000, 0x04000, val & 0xf); + if ((card_i430lx[0x5b] ^ val) & 0xf0) + i430lx_map(0xcc000, 0x04000, val >> 4); + break; + case 0x5c: /*PAM3*/ + if ((card_i430lx[0x5c] ^ val) & 0x0f) + i430lx_map(0xd0000, 0x04000, val & 0xf); + if ((card_i430lx[0x5c] ^ val) & 0xf0) + i430lx_map(0xd4000, 0x04000, val >> 4); + break; + case 0x5d: /*PAM4*/ + if ((card_i430lx[0x5d] ^ val) & 0x0f) + i430lx_map(0xd8000, 0x04000, val & 0xf); + if ((card_i430lx[0x5d] ^ val) & 0xf0) + i430lx_map(0xdc000, 0x04000, val >> 4); + break; + case 0x5e: /*PAM5*/ + if ((card_i430lx[0x5e] ^ val) & 0x0f) + i430lx_map(0xe0000, 0x04000, val & 0xf); + if ((card_i430lx[0x5e] ^ val) & 0xf0) + i430lx_map(0xe4000, 0x04000, val >> 4); + pclog("i430lx_write : PAM5 write %02X\n", val); + break; + case 0x5f: /*PAM6*/ + if ((card_i430lx[0x5f] ^ val) & 0x0f) + i430lx_map(0xe8000, 0x04000, val & 0xf); + if ((card_i430lx[0x5f] ^ val) & 0xf0) + i430lx_map(0xec000, 0x04000, val >> 4); + pclog("i430lx_write : PAM6 write %02X\n", val); + break; - case 0x72: /*SMRAM*/ - pclog("Write SMRAM %02x\n", val); - val = (val & 0x38) | 2; /*SMRAM always at A0000-BFFFF*/ - val |= (card_i430lx[0x72] & 0x08); /*D_LCK can not be cleared by software*/ - if (val & 0x08) /*D_LCK locks D_OPEN*/ - { - val &= ~0x20; /*D_OPEN is forced to 0*/ - } - val |= (card_i430lx[0x72] & 0x08); - if ((card_i430lx[0x72] ^ val) & 0x20) { - if (val & 0x20) /*SMRAM enabled*/ - { - pclog("Enable SMRAM\n"); - mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - } else { - pclog("Disable SMRAM\n"); - mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - } - } - break; - } + case 0x72: /*SMRAM*/ + pclog("Write SMRAM %02x\n", val); + val = (val & 0x38) | 2; /*SMRAM always at A0000-BFFFF*/ + val |= (card_i430lx[0x72] & 0x08); /*D_LCK can not be cleared by software*/ + if (val & 0x08) /*D_LCK locks D_OPEN*/ + { + val &= ~0x20; /*D_OPEN is forced to 0*/ + } + val |= (card_i430lx[0x72] & 0x08); + if ((card_i430lx[0x72] ^ val) & 0x20) { + if (val & 0x20) /*SMRAM enabled*/ + { + pclog("Enable SMRAM\n"); + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } else { + pclog("Disable SMRAM\n"); + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + } + } + break; + } - card_i430lx[addr] = val; + card_i430lx[addr] = val; } uint8_t i430lx_read(int func, int addr, void *priv) { - if (func) - return 0xff; + if (func) + return 0xff; - return card_i430lx[addr]; + return card_i430lx[addr]; } static uint8_t trc = 0; -uint8_t i430lx_trc_read(uint16_t port, void *p) { - return trc; -} +uint8_t i430lx_trc_read(uint16_t port, void *p) { return trc; } void i430lx_trc_write(uint16_t port, uint8_t val, void *p) { - if ((val & 4) && !(trc & 4)) { - if (val & 2) /*Hard reset*/ - { - i430lx_write(0, 0x59, 0xf, NULL); /*Should reset all PCI devices, but just set PAM0 to point to ROM for now*/ - card_i430lx[0x72] = 0; /*Also clear SMRAM register so BIOS will relocate SMBASE*/ - keyboard_at_reset(); /*Reset keyboard controller to reset system flag*/ - ide_reset_devices(); - resetx86(); - } else - softresetx86(); - } + if ((val & 4) && !(trc & 4)) { + if (val & 2) /*Hard reset*/ + { + i430lx_write(0, 0x59, 0xf, + NULL); /*Should reset all PCI devices, but just set PAM0 to point to ROM for now*/ + card_i430lx[0x72] = 0; /*Also clear SMRAM register so BIOS will relocate SMBASE*/ + keyboard_at_reset(); /*Reset keyboard controller to reset system flag*/ + ide_reset_devices(); + resetx86(); + } else + softresetx86(); + } - trc = val; + trc = val; } -static void i430lx_smram_enable(void) { - mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); -} -static void i430lx_smram_disable(void) { - mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); -} +static void i430lx_smram_enable(void) { mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); } +static void i430lx_smram_disable(void) { mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); } void i430lx_init() { - pci_add_specific(0, i430lx_read, i430lx_write, NULL); + pci_add_specific(0, i430lx_read, i430lx_write, NULL); - memset(card_i430lx, 0, 256); - card_i430lx[0x00] = 0x86; - card_i430lx[0x01] = 0x80; /*Intel*/ - card_i430lx[0x02] = 0xa3; - card_i430lx[0x03] = 0x04; /*82434LX*/ - card_i430lx[0x04] = 0x06; - card_i430lx[0x05] = 0x00; - card_i430lx[0x06] = 0x00; - card_i430lx[0x07] = 0x02; - card_i430lx[0x08] = 0x03; /*A3 stepping*/ - card_i430lx[0x09] = 0x00; - card_i430lx[0x0a] = 0x00; - card_i430lx[0x0b] = 0x06; - card_i430lx[0x50] = 0x80; - card_i430lx[0x52] = 0x40; /*256kb PLB cache*/ -// card_i430lx[0x53] = 0x14; -// card_i430lx[0x56] = 0x52; /*DRAM control*/ - card_i430lx[0x57] = 0x31; - card_i430lx[0x60] = card_i430lx[0x61] = card_i430lx[0x62] = card_i430lx[0x63] = card_i430lx[0x64] = 0x02; -// card_i430lx[0x67] = 0x11; -// card_i430lx[0x69] = 0x03; -// card_i430lx[0x70] = 0x20; -// card_i430lx[0x72] = 0x02; -// card_i430lx[0x74] = 0x0e; -// card_i430lx[0x78] = 0x23; + memset(card_i430lx, 0, 256); + card_i430lx[0x00] = 0x86; + card_i430lx[0x01] = 0x80; /*Intel*/ + card_i430lx[0x02] = 0xa3; + card_i430lx[0x03] = 0x04; /*82434LX*/ + card_i430lx[0x04] = 0x06; + card_i430lx[0x05] = 0x00; + card_i430lx[0x06] = 0x00; + card_i430lx[0x07] = 0x02; + card_i430lx[0x08] = 0x03; /*A3 stepping*/ + card_i430lx[0x09] = 0x00; + card_i430lx[0x0a] = 0x00; + card_i430lx[0x0b] = 0x06; + card_i430lx[0x50] = 0x80; + card_i430lx[0x52] = 0x40; /*256kb PLB cache*/ + // card_i430lx[0x53] = 0x14; + // card_i430lx[0x56] = 0x52; /*DRAM control*/ + card_i430lx[0x57] = 0x31; + card_i430lx[0x60] = card_i430lx[0x61] = card_i430lx[0x62] = card_i430lx[0x63] = card_i430lx[0x64] = 0x02; + // card_i430lx[0x67] = 0x11; + // card_i430lx[0x69] = 0x03; + // card_i430lx[0x70] = 0x20; + // card_i430lx[0x72] = 0x02; + // card_i430lx[0x74] = 0x0e; + // card_i430lx[0x78] = 0x23; - io_sethandler(0x0cf9, 0x0001, i430lx_trc_read, NULL, NULL, i430lx_trc_write, NULL, NULL, NULL); + io_sethandler(0x0cf9, 0x0001, i430lx_trc_read, NULL, NULL, i430lx_trc_write, NULL, NULL, NULL); - smram_enable = i430lx_smram_enable; - smram_disable = i430lx_smram_disable; + smram_enable = i430lx_smram_enable; + smram_disable = i430lx_smram_disable; } diff --git a/src/models/i430vx.c b/src/models/i430vx.c index be5c8362..f8e58144 100644 --- a/src/models/i430vx.c +++ b/src/models/i430vx.c @@ -10,170 +10,177 @@ static uint8_t card_i430vx[256]; static void i430vx_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(); + 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(); } void i430vx_write(int func, int addr, uint8_t val, void *priv) { - if (func) - return; + if (func) + return; - if (addr >= 0x10 && addr < 0x4f) - 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; + 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 &= 0x02; - val |= 0x04; - break; - case 0x05:val = 0; - break; + case 0x04: /*Command register*/ + val &= 0x02; + val |= 0x04; + break; + case 0x05: + val = 0; + break; - case 0x06: /*Status*/ - val = 0; - break; - case 0x07:val &= 0x80; - val |= 0x02; - break; + case 0x06: /*Status*/ + val = 0; + break; + case 0x07: + val &= 0x80; + val |= 0x02; + break; - case 0x59: /*PAM0*/ - if ((card_i430vx[0x59] ^ val) & 0xf0) { - i430vx_map(0xf0000, 0x10000, val >> 4); - } - pclog("i430vx_write : PAM0 write %02X\n", val); - break; - case 0x5a: /*PAM1*/ - if ((card_i430vx[0x5a] ^ val) & 0x0f) - i430vx_map(0xc0000, 0x04000, val & 0xf); - if ((card_i430vx[0x5a] ^ val) & 0xf0) - i430vx_map(0xc4000, 0x04000, val >> 4); - break; - case 0x5b: /*PAM2*/ - if ((card_i430vx[0x5b] ^ val) & 0x0f) - i430vx_map(0xc8000, 0x04000, val & 0xf); - if ((card_i430vx[0x5b] ^ val) & 0xf0) - i430vx_map(0xcc000, 0x04000, val >> 4); - break; - case 0x5c: /*PAM3*/ - if ((card_i430vx[0x5c] ^ val) & 0x0f) - i430vx_map(0xd0000, 0x04000, val & 0xf); - if ((card_i430vx[0x5c] ^ val) & 0xf0) - i430vx_map(0xd4000, 0x04000, val >> 4); - break; - case 0x5d: /*PAM4*/ - if ((card_i430vx[0x5d] ^ val) & 0x0f) - i430vx_map(0xd8000, 0x04000, val & 0xf); - if ((card_i430vx[0x5d] ^ val) & 0xf0) - i430vx_map(0xdc000, 0x04000, val >> 4); - break; - case 0x5e: /*PAM5*/ - if ((card_i430vx[0x5e] ^ val) & 0x0f) - i430vx_map(0xe0000, 0x04000, val & 0xf); - if ((card_i430vx[0x5e] ^ val) & 0xf0) - i430vx_map(0xe4000, 0x04000, val >> 4); - pclog("i430vx_write : PAM5 write %02X\n", val); - break; - case 0x5f: /*PAM6*/ - if ((card_i430vx[0x5f] ^ val) & 0x0f) - i430vx_map(0xe8000, 0x04000, val & 0xf); - if ((card_i430vx[0x5f] ^ val) & 0xf0) - i430vx_map(0xec000, 0x04000, val >> 4); - pclog("i430vx_write : PAM6 write %02X\n", val); - break; + case 0x59: /*PAM0*/ + if ((card_i430vx[0x59] ^ val) & 0xf0) { + i430vx_map(0xf0000, 0x10000, val >> 4); + } + pclog("i430vx_write : PAM0 write %02X\n", val); + break; + case 0x5a: /*PAM1*/ + if ((card_i430vx[0x5a] ^ val) & 0x0f) + i430vx_map(0xc0000, 0x04000, val & 0xf); + if ((card_i430vx[0x5a] ^ val) & 0xf0) + i430vx_map(0xc4000, 0x04000, val >> 4); + break; + case 0x5b: /*PAM2*/ + if ((card_i430vx[0x5b] ^ val) & 0x0f) + i430vx_map(0xc8000, 0x04000, val & 0xf); + if ((card_i430vx[0x5b] ^ val) & 0xf0) + i430vx_map(0xcc000, 0x04000, val >> 4); + break; + case 0x5c: /*PAM3*/ + if ((card_i430vx[0x5c] ^ val) & 0x0f) + i430vx_map(0xd0000, 0x04000, val & 0xf); + if ((card_i430vx[0x5c] ^ val) & 0xf0) + i430vx_map(0xd4000, 0x04000, val >> 4); + break; + case 0x5d: /*PAM4*/ + if ((card_i430vx[0x5d] ^ val) & 0x0f) + i430vx_map(0xd8000, 0x04000, val & 0xf); + if ((card_i430vx[0x5d] ^ val) & 0xf0) + i430vx_map(0xdc000, 0x04000, val >> 4); + break; + case 0x5e: /*PAM5*/ + if ((card_i430vx[0x5e] ^ val) & 0x0f) + i430vx_map(0xe0000, 0x04000, val & 0xf); + if ((card_i430vx[0x5e] ^ val) & 0xf0) + i430vx_map(0xe4000, 0x04000, val >> 4); + pclog("i430vx_write : PAM5 write %02X\n", val); + break; + case 0x5f: /*PAM6*/ + if ((card_i430vx[0x5f] ^ val) & 0x0f) + i430vx_map(0xe8000, 0x04000, val & 0xf); + if ((card_i430vx[0x5f] ^ val) & 0xf0) + i430vx_map(0xec000, 0x04000, val >> 4); + pclog("i430vx_write : PAM6 write %02X\n", val); + break; - case 0x72: /*SMRAM*/ - pclog("Write SMRAM %02x\n", val); - val = (val & 0x78) | 2; /*SMRAM always at A0000-BFFFF*/ - val |= (card_i430vx[0x72] & 0x10); /*D_LCK can not be cleared by software*/ - if (val & 0x10) /*D_LCK locks D_OPEN and G_SMRAME*/ - { - val &= ~0x48; /*D_OPEN is forced to 0, G_SMRAME is read only*/ - val |= (card_i430vx[0x72] & 0x08); - } - if ((card_i430vx[0x72] ^ val) & 0x40) { - if (val & 0x40) /*SMRAM enabled*/ - { - pclog("Enable SMRAM\n"); - mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - } else { - pclog("Disable SMRAM\n"); - mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - } - } - break; - } + case 0x72: /*SMRAM*/ + pclog("Write SMRAM %02x\n", val); + val = (val & 0x78) | 2; /*SMRAM always at A0000-BFFFF*/ + val |= (card_i430vx[0x72] & 0x10); /*D_LCK can not be cleared by software*/ + if (val & 0x10) /*D_LCK locks D_OPEN and G_SMRAME*/ + { + val &= ~0x48; /*D_OPEN is forced to 0, G_SMRAME is read only*/ + val |= (card_i430vx[0x72] & 0x08); + } + if ((card_i430vx[0x72] ^ val) & 0x40) { + if (val & 0x40) /*SMRAM enabled*/ + { + pclog("Enable SMRAM\n"); + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } else { + pclog("Disable SMRAM\n"); + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + } + } + break; + } - card_i430vx[addr] = val; + card_i430vx[addr] = val; } uint8_t i430vx_read(int func, int addr, void *priv) { - if (func) - return 0xff; + if (func) + return 0xff; - return card_i430vx[addr]; + return card_i430vx[addr]; } static void i430vx_smram_enable(void) { - if (card_i430vx[0x72] & 8) - mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + if (card_i430vx[0x72] & 8) + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); } static void i430vx_smram_disable(void) { - if (card_i430vx[0x72] & 8) - mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + if (card_i430vx[0x72] & 8) + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); } void i430vx_init() { - pci_add_specific(0, i430vx_read, i430vx_write, NULL); + pci_add_specific(0, i430vx_read, i430vx_write, NULL); - memset(card_i430vx, 0, 256); - card_i430vx[0x00] = 0x86; - card_i430vx[0x01] = 0x80; /*Intel*/ - card_i430vx[0x02] = 0x30; - card_i430vx[0x03] = 0x70; /*82437VX*/ - card_i430vx[0x04] = 0x06; - card_i430vx[0x05] = 0x00; - card_i430vx[0x06] = 0x00; - card_i430vx[0x07] = 0x02; - card_i430vx[0x08] = 0x00; /*A0 stepping*/ - card_i430vx[0x09] = 0x00; - card_i430vx[0x0a] = 0x00; - card_i430vx[0x0b] = 0x06; - card_i430vx[0x52] = 0x42; /*256kb PLB cache*/ - card_i430vx[0x53] = 0x14; - card_i430vx[0x56] = 0x52; /*DRAM control*/ - card_i430vx[0x57] = 0x01; - card_i430vx[0x60] = card_i430vx[0x61] = card_i430vx[0x62] = card_i430vx[0x63] = card_i430vx[0x64] = 0x02; - card_i430vx[0x67] = 0x11; - card_i430vx[0x69] = 0x03; - card_i430vx[0x70] = 0x20; - card_i430vx[0x72] = 0x02; - card_i430vx[0x74] = 0x0e; - card_i430vx[0x78] = 0x23; + memset(card_i430vx, 0, 256); + card_i430vx[0x00] = 0x86; + card_i430vx[0x01] = 0x80; /*Intel*/ + card_i430vx[0x02] = 0x30; + card_i430vx[0x03] = 0x70; /*82437VX*/ + card_i430vx[0x04] = 0x06; + card_i430vx[0x05] = 0x00; + card_i430vx[0x06] = 0x00; + card_i430vx[0x07] = 0x02; + card_i430vx[0x08] = 0x00; /*A0 stepping*/ + card_i430vx[0x09] = 0x00; + card_i430vx[0x0a] = 0x00; + card_i430vx[0x0b] = 0x06; + card_i430vx[0x52] = 0x42; /*256kb PLB cache*/ + card_i430vx[0x53] = 0x14; + card_i430vx[0x56] = 0x52; /*DRAM control*/ + card_i430vx[0x57] = 0x01; + card_i430vx[0x60] = card_i430vx[0x61] = card_i430vx[0x62] = card_i430vx[0x63] = card_i430vx[0x64] = 0x02; + card_i430vx[0x67] = 0x11; + card_i430vx[0x69] = 0x03; + card_i430vx[0x70] = 0x20; + card_i430vx[0x72] = 0x02; + card_i430vx[0x74] = 0x0e; + card_i430vx[0x78] = 0x23; - smram_enable = i430vx_smram_enable; - smram_disable = i430vx_smram_disable; + smram_enable = i430vx_smram_enable; + smram_disable = i430vx_smram_disable; } void i430vx_reset() { - i430vx_write(0, 0x59, 0xf, NULL); /*Should reset all PCI devices, but just set PAM0 to point to ROM for now*/ + i430vx_write(0, 0x59, 0xf, NULL); /*Should reset all PCI devices, but just set PAM0 to point to ROM for now*/ } diff --git a/src/models/i440bx.c b/src/models/i440bx.c index 04788b8f..87bc2a79 100644 --- a/src/models/i440bx.c +++ b/src/models/i440bx.c @@ -12,174 +12,181 @@ static uint8_t card_i440bx[256]; static void i440bx_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(); + 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(); } void i440bx_write(int func, int addr, uint8_t val, void *priv) { - if (func) - return; + if (func) + return; - if (addr >= 0x10 && addr < 0x4f) - 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; + 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 &= 0x02; - val |= 0x04; - break; - case 0x05:val = 0; - break; + case 0x04: /*Command register*/ + val &= 0x02; + val |= 0x04; + break; + case 0x05: + val = 0; + break; - case 0x06: /*Status*/ - val = 0; - break; - case 0x07:val = 0x02; - break; + case 0x06: /*Status*/ + val = 0; + break; + case 0x07: + val = 0x02; + break; - case 0x59: /*PAM0*/ - if ((card_i440bx[0x59] ^ val) & 0xf0) { - i440bx_map(0xf0000, 0x10000, val >> 4); - } - pclog("i440bx_write : PAM0 write %02X\n", val); -// if (val == 0x10) -// output = 3; - break; - case 0x5a: /*PAM1*/ - if ((card_i440bx[0x5a] ^ val) & 0x0f) - i440bx_map(0xc0000, 0x04000, val & 0xf); - if ((card_i440bx[0x5a] ^ val) & 0xf0) - i440bx_map(0xc4000, 0x04000, val >> 4); - break; - case 0x5b: /*PAM2*/ - if ((card_i440bx[0x5b] ^ val) & 0x0f) - i440bx_map(0xc8000, 0x04000, val & 0xf); - if ((card_i440bx[0x5b] ^ val) & 0xf0) - i440bx_map(0xcc000, 0x04000, val >> 4); - break; - case 0x5c: /*PAM3*/ - if ((card_i440bx[0x5c] ^ val) & 0x0f) - i440bx_map(0xd0000, 0x04000, val & 0xf); - if ((card_i440bx[0x5c] ^ val) & 0xf0) - i440bx_map(0xd4000, 0x04000, val >> 4); - break; - case 0x5d: /*PAM4*/ - if ((card_i440bx[0x5d] ^ val) & 0x0f) - i440bx_map(0xd8000, 0x04000, val & 0xf); - if ((card_i440bx[0x5d] ^ val) & 0xf0) - i440bx_map(0xdc000, 0x04000, val >> 4); - break; - case 0x5e: /*PAM5*/ - if ((card_i440bx[0x5e] ^ val) & 0x0f) - i440bx_map(0xe0000, 0x04000, val & 0xf); - if ((card_i440bx[0x5e] ^ val) & 0xf0) - i440bx_map(0xe4000, 0x04000, val >> 4); - pclog("i440bx_write : PAM5 write %02X\n", val); - break; - case 0x5f: /*PAM6*/ - if ((card_i440bx[0x5f] ^ val) & 0x0f) - i440bx_map(0xe8000, 0x04000, val & 0xf); - if ((card_i440bx[0x5f] ^ val) & 0xf0) - i440bx_map(0xec000, 0x04000, val >> 4); - pclog("i440bx_write : PAM6 write %02X\n", val); - break; + case 0x59: /*PAM0*/ + if ((card_i440bx[0x59] ^ val) & 0xf0) { + i440bx_map(0xf0000, 0x10000, val >> 4); + } + pclog("i440bx_write : PAM0 write %02X\n", val); + // if (val == 0x10) + // output = 3; + break; + case 0x5a: /*PAM1*/ + if ((card_i440bx[0x5a] ^ val) & 0x0f) + i440bx_map(0xc0000, 0x04000, val & 0xf); + if ((card_i440bx[0x5a] ^ val) & 0xf0) + i440bx_map(0xc4000, 0x04000, val >> 4); + break; + case 0x5b: /*PAM2*/ + if ((card_i440bx[0x5b] ^ val) & 0x0f) + i440bx_map(0xc8000, 0x04000, val & 0xf); + if ((card_i440bx[0x5b] ^ val) & 0xf0) + i440bx_map(0xcc000, 0x04000, val >> 4); + break; + case 0x5c: /*PAM3*/ + if ((card_i440bx[0x5c] ^ val) & 0x0f) + i440bx_map(0xd0000, 0x04000, val & 0xf); + if ((card_i440bx[0x5c] ^ val) & 0xf0) + i440bx_map(0xd4000, 0x04000, val >> 4); + break; + case 0x5d: /*PAM4*/ + if ((card_i440bx[0x5d] ^ val) & 0x0f) + i440bx_map(0xd8000, 0x04000, val & 0xf); + if ((card_i440bx[0x5d] ^ val) & 0xf0) + i440bx_map(0xdc000, 0x04000, val >> 4); + break; + case 0x5e: /*PAM5*/ + if ((card_i440bx[0x5e] ^ val) & 0x0f) + i440bx_map(0xe0000, 0x04000, val & 0xf); + if ((card_i440bx[0x5e] ^ val) & 0xf0) + i440bx_map(0xe4000, 0x04000, val >> 4); + pclog("i440bx_write : PAM5 write %02X\n", val); + break; + case 0x5f: /*PAM6*/ + if ((card_i440bx[0x5f] ^ val) & 0x0f) + i440bx_map(0xe8000, 0x04000, val & 0xf); + if ((card_i440bx[0x5f] ^ val) & 0xf0) + i440bx_map(0xec000, 0x04000, val >> 4); + pclog("i440bx_write : PAM6 write %02X\n", val); + break; - case 0x72: /*SMRAM*/ -// pclog("Write SMRAM %02x was %02x\n", val, - val = (val & 0x78) | 2; /*SMRAM always at A0000-BFFFF*/ - val |= (card_i440bx[0x72] & 0x10); /*D_LCK can not be cleared by software*/ - if (val & 0x10) /*D_LCK locks D_OPEN and G_SMRAME*/ - { - val &= ~0x48; /*D_OPEN is forced to 0, G_SMRAME is read only*/ - val |= (card_i440bx[0x72] & 0x08); - } - if ((card_i440bx[0x72] ^ val) & 0x40) { - if (val & 0x40) /*SMRAM enabled*/ - { - pclog("Enable SMRAM\n"); - mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - } else { - pclog("Disable SMRAM\n"); - mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - } - } - break; - } + case 0x72: /*SMRAM*/ + // pclog("Write SMRAM %02x was %02x\n", val, + val = (val & 0x78) | 2; /*SMRAM always at A0000-BFFFF*/ + val |= (card_i440bx[0x72] & 0x10); /*D_LCK can not be cleared by software*/ + if (val & 0x10) /*D_LCK locks D_OPEN and G_SMRAME*/ + { + val &= ~0x48; /*D_OPEN is forced to 0, G_SMRAME is read only*/ + val |= (card_i440bx[0x72] & 0x08); + } + if ((card_i440bx[0x72] ^ val) & 0x40) { + if (val & 0x40) /*SMRAM enabled*/ + { + pclog("Enable SMRAM\n"); + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } else { + pclog("Disable SMRAM\n"); + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + } + } + break; + } - card_i440bx[addr] = val; + card_i440bx[addr] = val; } uint8_t i440bx_read(int func, int addr, void *priv) { - if (func) - return 0xff; + if (func) + return 0xff; - return card_i440bx[addr]; + return card_i440bx[addr]; } static void i440bx_smram_enable(void) { -// pclog("i440bx_smram_enable: 440BX 0x72=%02x\n", card_i440bx[0x72]); - if (card_i440bx[0x72] & 8) - mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + // pclog("i440bx_smram_enable: 440BX 0x72=%02x\n", card_i440bx[0x72]); + if (card_i440bx[0x72] & 8) + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); } static void i440bx_smram_disable(void) { -// pclog("i440bx_smram_disable: 440BX 0x72=%02x\n", card_i440bx[0x72]); - if (card_i440bx[0x72] & 8) - mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + // pclog("i440bx_smram_disable: 440BX 0x72=%02x\n", card_i440bx[0x72]); + if (card_i440bx[0x72] & 8) + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); } void i440bx_init() { - pci_add_specific(0, i440bx_read, i440bx_write, NULL); + pci_add_specific(0, i440bx_read, i440bx_write, NULL); - memset(card_i440bx, 0, 256); - card_i440bx[0x00] = 0x86; - card_i440bx[0x01] = 0x80; /*Intel*/ - card_i440bx[0x02] = 0x92; - card_i440bx[0x03] = 0x71; /*82441FX*/ - card_i440bx[0x04] = 0x06; - card_i440bx[0x05] = 0x00; - card_i440bx[0x06] = 0x00; - card_i440bx[0x07] = 0x02; - card_i440bx[0x08] = 0x02; /*B1 stepping*/ - card_i440bx[0x09] = 0x00; - card_i440bx[0x0a] = 0x00; - card_i440bx[0x0b] = 0x06; - card_i440bx[0x51] = 0x20; /*66 MHz bus*/ - card_i440bx[0x60] = card_i440bx[0x61] = card_i440bx[0x62] = card_i440bx[0x63] = 0x01; - card_i440bx[0x64] = card_i440bx[0x65] = card_i440bx[0x66] = card_i440bx[0x67] = 0x01; - card_i440bx[0x72] = 0x02; - card_i440bx[0x73] = 0x38; - card_i440bx[0x7a] = 0x02; /*AGP disabled*/ + memset(card_i440bx, 0, 256); + card_i440bx[0x00] = 0x86; + card_i440bx[0x01] = 0x80; /*Intel*/ + card_i440bx[0x02] = 0x92; + card_i440bx[0x03] = 0x71; /*82441FX*/ + card_i440bx[0x04] = 0x06; + card_i440bx[0x05] = 0x00; + card_i440bx[0x06] = 0x00; + card_i440bx[0x07] = 0x02; + card_i440bx[0x08] = 0x02; /*B1 stepping*/ + card_i440bx[0x09] = 0x00; + card_i440bx[0x0a] = 0x00; + card_i440bx[0x0b] = 0x06; + card_i440bx[0x51] = 0x20; /*66 MHz bus*/ + card_i440bx[0x60] = card_i440bx[0x61] = card_i440bx[0x62] = card_i440bx[0x63] = 0x01; + card_i440bx[0x64] = card_i440bx[0x65] = card_i440bx[0x66] = card_i440bx[0x67] = 0x01; + card_i440bx[0x72] = 0x02; + card_i440bx[0x73] = 0x38; + card_i440bx[0x7a] = 0x02; /*AGP disabled*/ - smram_enable = i440bx_smram_enable; - smram_disable = i440bx_smram_disable; + smram_enable = i440bx_smram_enable; + smram_disable = i440bx_smram_disable; } void i440bx_reset() { - i440bx_write(0, 0x59, 0xf, NULL); /*Should reset all PCI devices, but just set PAM0 to point to ROM for now*/ - i440bx_write(0, 0x5a, 0x0, NULL); - i440bx_write(0, 0x5b, 0x0, NULL); - i440bx_write(0, 0x5c, 0x0, NULL); - i440bx_write(0, 0x5d, 0x0, NULL); - i440bx_write(0, 0x5e, 0x0, NULL); - i440bx_write(0, 0x5f, 0x0, NULL); + i440bx_write(0, 0x59, 0xf, NULL); /*Should reset all PCI devices, but just set PAM0 to point to ROM for now*/ + i440bx_write(0, 0x5a, 0x0, NULL); + i440bx_write(0, 0x5b, 0x0, NULL); + i440bx_write(0, 0x5c, 0x0, NULL); + i440bx_write(0, 0x5d, 0x0, NULL); + i440bx_write(0, 0x5e, 0x0, NULL); + i440bx_write(0, 0x5f, 0x0, NULL); } diff --git a/src/models/i440fx.c b/src/models/i440fx.c index 862205ef..67b7e061 100644 --- a/src/models/i440fx.c +++ b/src/models/i440fx.c @@ -12,165 +12,172 @@ static uint8_t card_i440fx[256]; static void i440fx_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(); + 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(); } void i440fx_write(int func, int addr, uint8_t val, void *priv) { - if (func) - return; + if (func) + return; - if (addr >= 0x10 && addr < 0x4f) - 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; + 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 &= 0x02; - val |= 0x04; - break; - case 0x05:val = 0; - break; + case 0x04: /*Command register*/ + val &= 0x02; + val |= 0x04; + break; + case 0x05: + val = 0; + break; - case 0x06: /*Status*/ - val = 0; - break; - case 0x07:val = 0x02; - break; + case 0x06: /*Status*/ + val = 0; + break; + case 0x07: + val = 0x02; + break; - case 0x59: /*PAM0*/ - if ((card_i440fx[0x59] ^ val) & 0xf0) { - i440fx_map(0xf0000, 0x10000, val >> 4); - } - pclog("i440fx_write : PAM0 write %02X\n", val); - break; - case 0x5a: /*PAM1*/ - if ((card_i440fx[0x5a] ^ val) & 0x0f) - i440fx_map(0xc0000, 0x04000, val & 0xf); - if ((card_i440fx[0x5a] ^ val) & 0xf0) - i440fx_map(0xc4000, 0x04000, val >> 4); - break; - case 0x5b: /*PAM2*/ - if ((card_i440fx[0x5b] ^ val) & 0x0f) - i440fx_map(0xc8000, 0x04000, val & 0xf); - if ((card_i440fx[0x5b] ^ val) & 0xf0) - i440fx_map(0xcc000, 0x04000, val >> 4); - break; - case 0x5c: /*PAM3*/ - if ((card_i440fx[0x5c] ^ val) & 0x0f) - i440fx_map(0xd0000, 0x04000, val & 0xf); - if ((card_i440fx[0x5c] ^ val) & 0xf0) - i440fx_map(0xd4000, 0x04000, val >> 4); - break; - case 0x5d: /*PAM4*/ - if ((card_i440fx[0x5d] ^ val) & 0x0f) - i440fx_map(0xd8000, 0x04000, val & 0xf); - if ((card_i440fx[0x5d] ^ val) & 0xf0) - i440fx_map(0xdc000, 0x04000, val >> 4); - break; - case 0x5e: /*PAM5*/ - if ((card_i440fx[0x5e] ^ val) & 0x0f) - i440fx_map(0xe0000, 0x04000, val & 0xf); - if ((card_i440fx[0x5e] ^ val) & 0xf0) - i440fx_map(0xe4000, 0x04000, val >> 4); - pclog("i440fx_write : PAM5 write %02X\n", val); - break; - case 0x5f: /*PAM6*/ - if ((card_i440fx[0x5f] ^ val) & 0x0f) - i440fx_map(0xe8000, 0x04000, val & 0xf); - if ((card_i440fx[0x5f] ^ val) & 0xf0) - i440fx_map(0xec000, 0x04000, val >> 4); - pclog("i440fx_write : PAM6 write %02X\n", val); - break; + case 0x59: /*PAM0*/ + if ((card_i440fx[0x59] ^ val) & 0xf0) { + i440fx_map(0xf0000, 0x10000, val >> 4); + } + pclog("i440fx_write : PAM0 write %02X\n", val); + break; + case 0x5a: /*PAM1*/ + if ((card_i440fx[0x5a] ^ val) & 0x0f) + i440fx_map(0xc0000, 0x04000, val & 0xf); + if ((card_i440fx[0x5a] ^ val) & 0xf0) + i440fx_map(0xc4000, 0x04000, val >> 4); + break; + case 0x5b: /*PAM2*/ + if ((card_i440fx[0x5b] ^ val) & 0x0f) + i440fx_map(0xc8000, 0x04000, val & 0xf); + if ((card_i440fx[0x5b] ^ val) & 0xf0) + i440fx_map(0xcc000, 0x04000, val >> 4); + break; + case 0x5c: /*PAM3*/ + if ((card_i440fx[0x5c] ^ val) & 0x0f) + i440fx_map(0xd0000, 0x04000, val & 0xf); + if ((card_i440fx[0x5c] ^ val) & 0xf0) + i440fx_map(0xd4000, 0x04000, val >> 4); + break; + case 0x5d: /*PAM4*/ + if ((card_i440fx[0x5d] ^ val) & 0x0f) + i440fx_map(0xd8000, 0x04000, val & 0xf); + if ((card_i440fx[0x5d] ^ val) & 0xf0) + i440fx_map(0xdc000, 0x04000, val >> 4); + break; + case 0x5e: /*PAM5*/ + if ((card_i440fx[0x5e] ^ val) & 0x0f) + i440fx_map(0xe0000, 0x04000, val & 0xf); + if ((card_i440fx[0x5e] ^ val) & 0xf0) + i440fx_map(0xe4000, 0x04000, val >> 4); + pclog("i440fx_write : PAM5 write %02X\n", val); + break; + case 0x5f: /*PAM6*/ + if ((card_i440fx[0x5f] ^ val) & 0x0f) + i440fx_map(0xe8000, 0x04000, val & 0xf); + if ((card_i440fx[0x5f] ^ val) & 0xf0) + i440fx_map(0xec000, 0x04000, val >> 4); + pclog("i440fx_write : PAM6 write %02X\n", val); + break; - case 0x72: /*SMRAM*/ - pclog("Write SMRAM %02x\n", val); - val = (val & 0x78) | 2; /*SMRAM always at A0000-BFFFF*/ - val |= (card_i440fx[0x72] & 0x10); /*D_LCK can not be cleared by software*/ - if (val & 0x10) /*D_LCK locks D_OPEN and G_SMRAME*/ - { - val &= ~0x48; /*D_OPEN is forced to 0, G_SMRAME is read only*/ - val |= (card_i440fx[0x72] & 0x08); - } - if ((card_i440fx[0x72] ^ val) & 0x40) { - if (val & 0x40) /*SMRAM enabled*/ - { - pclog("Enable SMRAM\n"); - mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - } else { - pclog("Disable SMRAM\n"); - mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - } - } - break; - } + case 0x72: /*SMRAM*/ + pclog("Write SMRAM %02x\n", val); + val = (val & 0x78) | 2; /*SMRAM always at A0000-BFFFF*/ + val |= (card_i440fx[0x72] & 0x10); /*D_LCK can not be cleared by software*/ + if (val & 0x10) /*D_LCK locks D_OPEN and G_SMRAME*/ + { + val &= ~0x48; /*D_OPEN is forced to 0, G_SMRAME is read only*/ + val |= (card_i440fx[0x72] & 0x08); + } + if ((card_i440fx[0x72] ^ val) & 0x40) { + if (val & 0x40) /*SMRAM enabled*/ + { + pclog("Enable SMRAM\n"); + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } else { + pclog("Disable SMRAM\n"); + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + } + } + break; + } - card_i440fx[addr] = val; + card_i440fx[addr] = val; } uint8_t i440fx_read(int func, int addr, void *priv) { - if (func) - return 0xff; + if (func) + return 0xff; - return card_i440fx[addr]; + return card_i440fx[addr]; } static void i440fx_smram_enable(void) { - if (card_i440fx[0x72] & 8) - mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + if (card_i440fx[0x72] & 8) + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); } static void i440fx_smram_disable(void) { - if (card_i440fx[0x72] & 8) - mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + if (card_i440fx[0x72] & 8) + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); } void i440fx_init() { - pci_add_specific(0, i440fx_read, i440fx_write, NULL); + pci_add_specific(0, i440fx_read, i440fx_write, NULL); - memset(card_i440fx, 0, 256); - card_i440fx[0x00] = 0x86; - card_i440fx[0x01] = 0x80; /*Intel*/ - card_i440fx[0x02] = 0x37; - card_i440fx[0x03] = 0x12; /*82441FX*/ - card_i440fx[0x04] = 0x06; - card_i440fx[0x05] = 0x00; - card_i440fx[0x06] = 0x80; - card_i440fx[0x07] = 0x02; - card_i440fx[0x08] = 0x00; /*A0 stepping*/ - card_i440fx[0x09] = 0x00; - card_i440fx[0x0a] = 0x00; - card_i440fx[0x0b] = 0x06; - card_i440fx[0x51] = 0x84; /*Uniprocessor, 66 MHz bus*/ - card_i440fx[0x53] = 0x80; - card_i440fx[0x57] = 0x01; - card_i440fx[0x58] = 0x10; - card_i440fx[0x60] = card_i440fx[0x61] = card_i440fx[0x62] = card_i440fx[0x63] = card_i440fx[0x64] = 0x01; - card_i440fx[0x71] = 0x10; - card_i440fx[0x72] = 0x02; + memset(card_i440fx, 0, 256); + card_i440fx[0x00] = 0x86; + card_i440fx[0x01] = 0x80; /*Intel*/ + card_i440fx[0x02] = 0x37; + card_i440fx[0x03] = 0x12; /*82441FX*/ + card_i440fx[0x04] = 0x06; + card_i440fx[0x05] = 0x00; + card_i440fx[0x06] = 0x80; + card_i440fx[0x07] = 0x02; + card_i440fx[0x08] = 0x00; /*A0 stepping*/ + card_i440fx[0x09] = 0x00; + card_i440fx[0x0a] = 0x00; + card_i440fx[0x0b] = 0x06; + card_i440fx[0x51] = 0x84; /*Uniprocessor, 66 MHz bus*/ + card_i440fx[0x53] = 0x80; + card_i440fx[0x57] = 0x01; + card_i440fx[0x58] = 0x10; + card_i440fx[0x60] = card_i440fx[0x61] = card_i440fx[0x62] = card_i440fx[0x63] = card_i440fx[0x64] = 0x01; + card_i440fx[0x71] = 0x10; + card_i440fx[0x72] = 0x02; - smram_enable = i440fx_smram_enable; - smram_disable = i440fx_smram_disable; + smram_enable = i440fx_smram_enable; + smram_disable = i440fx_smram_disable; } void i440fx_reset() { - i440fx_write(0, 0x59, 0xf, NULL); /*Should reset all PCI devices, but just set PAM0 to point to ROM for now*/ + i440fx_write(0, 0x59, 0xf, NULL); /*Should reset all PCI devices, but just set PAM0 to point to ROM for now*/ } diff --git a/src/models/intel.c b/src/models/intel.c index 40239f6e..ada8cb25 100644 --- a/src/models/intel.c +++ b/src/models/intel.c @@ -12,158 +12,150 @@ static uint8_t batman_port_92; uint8_t batman_brdconfig(uint16_t port, void *p) { -// pclog("batman_brdconfig read port=%04x\n", port); - switch (port) { - case 0x73:return 0xff; - case 0x75:return 0xdf; - case 0x92:return batman_port_92; - } - return 0; + // pclog("batman_brdconfig read port=%04x\n", port); + switch (port) { + case 0x73: + return 0xff; + case 0x75: + return 0xdf; + case 0x92: + return batman_port_92; + } + return 0; } void batman_brdconfig_write(uint16_t port, uint8_t val, void *p) { - switch (port) { - case 0x92: - if ((mem_a20_alt ^ val) & 2) { - mem_a20_alt = val & 2; - mem_a20_recalc(); - } - if ((~batman_port_92 & val) & 1) { - softresetx86(); - cpu_set_edx(); - } - batman_port_92 = val; - } + switch (port) { + case 0x92: + if ((mem_a20_alt ^ val) & 2) { + mem_a20_alt = val & 2; + mem_a20_recalc(); + } + if ((~batman_port_92 & val) & 1) { + softresetx86(); + cpu_set_edx(); + } + batman_port_92 = val; + } } static uint16_t batman_timer_latch; static pc_timer_t batman_timer; -static void batman_timer_over(void *p) { -} +static void batman_timer_over(void *p) {} 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; - timer_set_delay_u64(&batman_timer, batman_timer_latch * TIMER_USEC); + if (addr & 1) + batman_timer_latch = (batman_timer_latch & 0xff) | (val << 8); + else + batman_timer_latch = (batman_timer_latch & 0xff00) | val; + timer_set_delay_u64(&batman_timer, batman_timer_latch * TIMER_USEC); } static uint8_t batman_timer_read(uint16_t addr, void *p) { - uint16_t batman_timer_latch; + uint16_t batman_timer_latch; - cycles -= (int)(PITCONST >> 32); + cycles -= (int)(PITCONST >> 32); - batman_timer_latch = timer_get_remaining_us(&batman_timer); + batman_timer_latch = timer_get_remaining_us(&batman_timer); - if (addr & 1) - return batman_timer_latch >> 8; - return batman_timer_latch & 0xff; + 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(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); - io_sethandler(0x0092, 0x0001, batman_brdconfig, NULL, NULL, batman_brdconfig_write, NULL, NULL, NULL); - batman_port_92 = 0; - timer_add(&batman_timer, batman_timer_over, NULL, 0); + io_sethandler(0x0078, 0x0002, batman_timer_read, NULL, NULL, batman_timer_write, NULL, NULL, NULL); + io_sethandler(0x0092, 0x0001, batman_brdconfig, NULL, NULL, batman_brdconfig_write, NULL, NULL, NULL); + batman_port_92 = 0; + timer_add(&batman_timer, batman_timer_over, NULL, 0); } uint8_t endeavor_brdconfig(uint16_t port, void *p) { - uint8_t temp; - CPU *cpu_s = &models[model]->cpu[cpu_manufacturer].cpus[cpu]; -// pclog("endeavor_brdconfig read port=%04x\n", port); - switch (port) { - case 0x79: - // Bit # | Description | Bit = 1 | Bit = 0 - // 0 | Internal CPU Clock Freq. (Switch 6) | 3/2x | 2x (Manual has these swapped in one place?) - // 1 | Soft Off capable power supply | No | Yes - // 2 | On-board Audio present | Yes | No - // 3 | External CPU clock (Switch 7) | | - // 4 | External CPU clock (Switch 8) | | - // 5 | Setup Disable (Switch 5) | Enable access | Disable access - // 6 | Clear CMOS (Switch 4) | Keep values | Clear values - // 7 | Password Clear (Switch 3) | Keep password | Clear password + uint8_t temp; + CPU *cpu_s = &models[model]->cpu[cpu_manufacturer].cpus[cpu]; + // pclog("endeavor_brdconfig read port=%04x\n", port); + switch (port) { + case 0x79: + // Bit # | Description | Bit = 1 | Bit = 0 + // 0 | Internal CPU Clock Freq. (Switch 6) | 3/2x | 2x (Manual has these swapped in one + // place?) 1 | Soft Off capable power supply | No | Yes 2 | On-board Audio present | Yes + // | No 3 | External CPU clock (Switch 7) | | 4 | External CPU clock (Switch 8) | | 5 + // | Setup Disable (Switch 5) | Enable access | Disable access 6 | Clear CMOS (Switch 4) | Keep + // values | Clear values 7 | Password Clear (Switch 3) | Keep password | Clear password - // Bus Speed | Switch 7 | Switch 8 - // 50 MHz | Off | Off - // 60 Mhz | On | Off - // 66 MHz | Off | On + // Bus Speed | Switch 7 | Switch 8 + // 50 MHz | Off | Off + // 60 Mhz | On | Off + // 66 MHz | Off | On - // Multiplier for each supported processor- - // -The 3/2 setting is used for 75 MHz, 90 MHz, and 100 MHz processors - // -The 2 times setting is used for 120 MHz processors. + // Multiplier for each supported processor- + // -The 3/2 setting is used for 75 MHz, 90 MHz, and 100 MHz processors + // -The 2 times setting is used for 120 MHz processors. - if (cpu_s->rspeed == 75000000 && cpu_s->pci_speed == 25000000) - temp = 0x01; - else if (cpu_s->rspeed == 90000000 && cpu_s->pci_speed == 30000000) - temp = 0x01 | 0x08; - else if (cpu_s->rspeed == 100000000 && cpu_s->pci_speed == 25000000) - temp = 0x00; - else if (cpu_s->rspeed == 100000000 && cpu_s->pci_speed == 33333333) - temp = 0x01 | 0x10; - else if (cpu_s->rspeed == 120000000 && cpu_s->pci_speed == 30000000) - temp = 0x08; - else if (cpu_s->rspeed == 133333333 && cpu_s->pci_speed == 33333333) - temp = 0x10; - else - temp = 0x10; // TODO: how are the overdrive processors configured? - return 0xe0 | temp; - } - return 0; + if (cpu_s->rspeed == 75000000 && cpu_s->pci_speed == 25000000) + temp = 0x01; + else if (cpu_s->rspeed == 90000000 && cpu_s->pci_speed == 30000000) + temp = 0x01 | 0x08; + else if (cpu_s->rspeed == 100000000 && cpu_s->pci_speed == 25000000) + temp = 0x00; + else if (cpu_s->rspeed == 100000000 && cpu_s->pci_speed == 33333333) + temp = 0x01 | 0x10; + else if (cpu_s->rspeed == 120000000 && cpu_s->pci_speed == 30000000) + temp = 0x08; + else if (cpu_s->rspeed == 133333333 && cpu_s->pci_speed == 33333333) + temp = 0x10; + else + temp = 0x10; // TODO: how are the overdrive processors configured? + return 0xe0 | temp; + } + return 0; } -void intel_endeavor_init() { - io_sethandler(0x0079, 0x0001, endeavor_brdconfig, NULL, NULL, NULL, NULL, NULL, NULL); -} +void intel_endeavor_init() { io_sethandler(0x0079, 0x0001, endeavor_brdconfig, NULL, NULL, NULL, NULL, NULL, NULL); } static uint8_t zappa_brdconfig(uint16_t port, void *p) { - uint8_t temp; - CPU *cpu_s = &models[model]->cpu[cpu_manufacturer].cpus[cpu]; -// pclog("zappa_brdconfig read port=%04x\n", port); - switch (port) { - case 0x79: - // Bit # | Description | Bit = 1 | Bit = 0 - // 0 | Internal CPU Clock Freq. (Switch 6) | 3/2x | 2x (Manual has these swapped in one place?) - // 1 | No Connect | | - // 2 | No Connect | | - // 3 | External CPU clock (Switch 7) | | - // 4 | External CPU clock (Switch 8) | | - // 5 | Setup Disable (Switch 5) | Enable access | Disable access - // 6 | Clear CMOS (Switch 4) | Keep values | Clear values - // 7 | Password Clear (Switch 3) | Keep password | Clear password + uint8_t temp; + CPU *cpu_s = &models[model]->cpu[cpu_manufacturer].cpus[cpu]; + // pclog("zappa_brdconfig read port=%04x\n", port); + switch (port) { + case 0x79: + // Bit # | Description | Bit = 1 | Bit = 0 + // 0 | Internal CPU Clock Freq. (Switch 6) | 3/2x | 2x (Manual has these swapped in one + // place?) 1 | No Connect | | 2 | No Connect | | 3 | + // External CPU clock (Switch 7) | | 4 | External CPU clock (Switch 8) | | 5 | + // Setup Disable (Switch 5) | Enable access | Disable access 6 | Clear CMOS (Switch 4) | Keep + // values | Clear values 7 | Password Clear (Switch 3) | Keep password | Clear password - // Bus Speed | Switch 7 | Switch 8 - // 50 MHz | Off | Off - // 60 Mhz | On | Off - // 66 MHz | Off | On + // Bus Speed | Switch 7 | Switch 8 + // 50 MHz | Off | Off + // 60 Mhz | On | Off + // 66 MHz | Off | On - // Multiplier for each supported processor- - // -The 3/2 setting is used for 75 MHz, 90 MHz, and 100 MHz processors - // -The 2 times setting is used for 120 MHz processors. + // Multiplier for each supported processor- + // -The 3/2 setting is used for 75 MHz, 90 MHz, and 100 MHz processors + // -The 2 times setting is used for 120 MHz processors. - if (cpu_s->rspeed == 75000000 && cpu_s->pci_speed == 25000000) - temp = 0x01; - else if (cpu_s->rspeed == 90000000 && cpu_s->pci_speed == 30000000) - temp = 0x01 | 0x08; - else if (cpu_s->rspeed == 100000000 && cpu_s->pci_speed == 25000000) - temp = 0x00; - else if (cpu_s->rspeed == 100000000 && cpu_s->pci_speed == 33333333) - temp = 0x01 | 0x10; - else if (cpu_s->rspeed == 120000000 && cpu_s->pci_speed == 30000000) - temp = 0x08; - else if (cpu_s->rspeed == 133333333 && cpu_s->pci_speed == 33333333) - temp = 0x10; - else - temp = 0x10; // TODO: how are the overdrive processors configured? - return 0xe0 | temp; - } - return 0; + if (cpu_s->rspeed == 75000000 && cpu_s->pci_speed == 25000000) + temp = 0x01; + else if (cpu_s->rspeed == 90000000 && cpu_s->pci_speed == 30000000) + temp = 0x01 | 0x08; + else if (cpu_s->rspeed == 100000000 && cpu_s->pci_speed == 25000000) + temp = 0x00; + else if (cpu_s->rspeed == 100000000 && cpu_s->pci_speed == 33333333) + temp = 0x01 | 0x10; + else if (cpu_s->rspeed == 120000000 && cpu_s->pci_speed == 30000000) + temp = 0x08; + else if (cpu_s->rspeed == 133333333 && cpu_s->pci_speed == 33333333) + temp = 0x10; + else + temp = 0x10; // TODO: how are the overdrive processors configured? + return 0xe0 | temp; + } + return 0; } -void intel_zappa_init() { - io_sethandler(0x0079, 0x0001, zappa_brdconfig, NULL, NULL, NULL, NULL, NULL, NULL); -} +void intel_zappa_init() { io_sethandler(0x0079, 0x0001, zappa_brdconfig, NULL, NULL, NULL, NULL, NULL, NULL); } diff --git a/src/models/jim.c b/src/models/jim.c index e7fef885..a7f6525c 100644 --- a/src/models/jim.c +++ b/src/models/jim.c @@ -5,73 +5,79 @@ uint8_t europcdat[16]; struct { - uint8_t dat[16]; - int stat; - int addr; + uint8_t dat[16]; + int stat; + int addr; } europc_rtc; void writejim(uint16_t addr, uint8_t val, void *p) { - if ((addr & 0xFF0) == 0x250) - europcdat[addr & 0xF] = val; - switch (addr) { - case 0x25A: -// printf("Write RTC stat %i val %02X\n",europc_rtc.stat,val); - switch (europc_rtc.stat) { - case 0:europc_rtc.addr = val & 0xF; - europc_rtc.stat++; -// printf("RTC addr now %02X - contents %02X\n",val&0xF,europc_rtc.dat[europc_rtc.addr]); - break; - case 1:europc_rtc.dat[europc_rtc.addr] = (europc_rtc.dat[europc_rtc.addr] & 0xF) | (val << 4); - europc_rtc.stat++; - break; - case 2:europc_rtc.dat[europc_rtc.addr] = (europc_rtc.dat[europc_rtc.addr] & 0xF0) | (val & 0xF); - europc_rtc.stat = 0; - break; - } - break; - } -// printf("Write JIM %04X %02X\n",addr,val); + if ((addr & 0xFF0) == 0x250) + europcdat[addr & 0xF] = val; + switch (addr) { + case 0x25A: + // printf("Write RTC stat %i val %02X\n",europc_rtc.stat,val); + switch (europc_rtc.stat) { + case 0: + europc_rtc.addr = val & 0xF; + europc_rtc.stat++; + // printf("RTC addr now %02X - contents + // %02X\n",val&0xF,europc_rtc.dat[europc_rtc.addr]); + break; + case 1: + europc_rtc.dat[europc_rtc.addr] = (europc_rtc.dat[europc_rtc.addr] & 0xF) | (val << 4); + europc_rtc.stat++; + break; + case 2: + europc_rtc.dat[europc_rtc.addr] = (europc_rtc.dat[europc_rtc.addr] & 0xF0) | (val & 0xF); + europc_rtc.stat = 0; + break; + } + break; + } + // printf("Write JIM %04X %02X\n",addr,val); } uint8_t readjim(uint16_t addr, void *p) { -// printf("Read JIM %04X\n",addr); - switch (addr) { - case 0x250: - case 0x251: - case 0x252: - case 0x253: return 0; - case 0x254: - case 0x255: - case 0x256: - case 0x257: return europcdat[addr & 0xF]; - case 0x25A: - if (europc_rtc.stat == 1) { - europc_rtc.stat = 2; - return europc_rtc.dat[europc_rtc.addr] >> 4; - } - if (europc_rtc.stat == 2) { - europc_rtc.stat = 0; - return europc_rtc.dat[europc_rtc.addr] & 0xF; - } - return 0; - } - return 0; + // printf("Read JIM %04X\n",addr); + switch (addr) { + case 0x250: + case 0x251: + case 0x252: + case 0x253: + return 0; + case 0x254: + case 0x255: + case 0x256: + case 0x257: + return europcdat[addr & 0xF]; + case 0x25A: + if (europc_rtc.stat == 1) { + europc_rtc.stat = 2; + return europc_rtc.dat[europc_rtc.addr] >> 4; + } + if (europc_rtc.stat == 2) { + europc_rtc.stat = 0; + return europc_rtc.dat[europc_rtc.addr] & 0xF; + } + return 0; + } + return 0; } void jim_init() { - uint8_t viddat; - memset(europc_rtc.dat, 0, 16); - europc_rtc.dat[0xF] = 1; - europc_rtc.dat[3] = 1; - europc_rtc.dat[4] = 1; - europc_rtc.dat[5] = 0x88; - if (gfxcard == GFX_CGA || gfxcard == GFX_COLORPLUS) - viddat = 0x12; - else if (gfxcard == GFX_MDA || gfxcard == GFX_HERCULES || gfxcard == GFX_INCOLOR) - viddat = 3; - else - viddat = 0x10; - europc_rtc.dat[0xB] = viddat; - europc_rtc.dat[0xD] = viddat; /*Checksum*/ - io_sethandler(0x250, 0x10, readjim, NULL, NULL, writejim, NULL, NULL, NULL); + uint8_t viddat; + memset(europc_rtc.dat, 0, 16); + europc_rtc.dat[0xF] = 1; + europc_rtc.dat[3] = 1; + europc_rtc.dat[4] = 1; + europc_rtc.dat[5] = 0x88; + if (gfxcard == GFX_CGA || gfxcard == GFX_COLORPLUS) + viddat = 0x12; + else if (gfxcard == GFX_MDA || gfxcard == GFX_HERCULES || gfxcard == GFX_INCOLOR) + viddat = 3; + else + viddat = 0x10; + europc_rtc.dat[0xB] = viddat; + europc_rtc.dat[0xD] = viddat; /*Checksum*/ + io_sethandler(0x250, 0x10, readjim, NULL, NULL, writejim, NULL, NULL, NULL); } diff --git a/src/models/laserxt.c b/src/models/laserxt.c index 6e8de08a..125d4ed5 100644 --- a/src/models/laserxt.c +++ b/src/models/laserxt.c @@ -11,112 +11,127 @@ static int laserxt_ems_baseaddr_index = 0; static uint8_t laserxt_turbo = 0x80; 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); - } + 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; + return addr; } static void laserxt_write(uint16_t port, uint8_t val, void *priv) { - int i; - uint32_t paddr, vaddr; + int i; + uint32_t paddr, vaddr; - switch (port) { - case 0x01F0:laserxt_turbo = val; - cpu_set_turbo((val & 0x80) >> 7); - //pclog("Turbo %s at %04X:%04X\n", (val & 0x80) ? "Enabled" : "Disabled", CS, cpu_state.oldpc); - break; - 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); + switch (port) { + case 0x01F0: + laserxt_turbo = val; + cpu_set_turbo((val & 0x80) >> 7); + // pclog("Turbo %s at %04X:%04X\n", (val & 0x80) ? "Enabled" : "Disabled", CS, cpu_state.oldpc); + break; + 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]); - } + 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; + flushmmucache(); + break; - case 0x0209: - case 0x4209: - case 0x8209: - case 0xC209:laserxt_emscontrol[port >> 14] = val; - laserxt_ems_baseaddr_index = 0; + 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); + for (i = 0; i < 4; i++) + laserxt_ems_baseaddr_index |= (laserxt_emscontrol[i] & 0x80) >> (7 - i); - 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); + 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; - } + flushmmucache(); + break; + } } static uint8_t laserxt_read(uint16_t port, void *priv) { - switch (port) { - case 0x01F0:return laserxt_turbo; + switch (port) { + case 0x01F0: + return laserxt_turbo; - case 0x0208: - case 0x4208: - case 0x8208: - case 0xC208:return laserxt_emspage[port >> 14]; + 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]; - } - return 0xff; + case 0x0209: + case 0x4209: + case 0x8209: + case 0xC209: + return laserxt_emscontrol[port >> 14]; + } + 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; + 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; + uint8_t val = 0xFF; - addr = get_laserxt_ems_addr(addr); - if (addr < (mem_size << 10)) - val = ram[addr]; + addr = get_laserxt_ems_addr(addr); + if (addr < (mem_size << 10)) + val = ram[addr]; - return val; + return val; } void laserxt_init() { - int i; + int i; - io_sethandler(0x01F0, 0x0001, laserxt_read, NULL, NULL, laserxt_write, NULL, NULL, NULL); - laserxt_turbo = 0x80; - cpu_set_turbo(1); + io_sethandler(0x01F0, 0x0001, laserxt_read, NULL, NULL, laserxt_write, NULL, NULL, NULL); + laserxt_turbo = 0x80; + cpu_set_turbo(1); - 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)); - } + 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(0x0a0000, 0x60000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + 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(0x0a0000, 0x60000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); } diff --git a/src/models/model.c b/src/models/model.c index 4cd1a839..800508c1 100644 --- a/src/models/model.c +++ b/src/models/model.c @@ -143,861 +143,1586 @@ void at_ga686bx_init(); int AMSTRAD, AT, PCI, TANDY, MCA; -int model_getromset() { - return models[model]->id; -} +int model_getromset() { return models[model]->id; } -int model_getromset_from_model(int model) { - return models[model]->id; -} +int model_getromset_from_model(int model) { return models[model]->id; } int model_getmodel(int romset) { - int c = 0; + int c = 0; - while (models[c]->id != -1) { - if (models[c]->id == romset) - return c; - c++; - } + while (models[c]->id != -1) { + if (models[c]->id == romset) + return c; + c++; + } - return 0; + return 0; } -char *model_getname() { - return models[model]->name; -} +char *model_getname() { return models[model]->name; } -char *model_get_internal_name() { - return models[model]->internal_name; -} +char *model_get_internal_name() { return models[model]->internal_name; } int model_get_model_from_internal_name(char *s) { - int c = 0; + int c = 0; - while (models[c] != NULL) { - if (!strcmp(models[c]->internal_name, s)) - return c; - c++; - } + while (models[c] != NULL) { + if (!strcmp(models[c]->internal_name, s)) + return c; + c++; + } - return 0; + return 0; } int model_has_fixed_gfx(int model) { - int gfx_flags = models[model]->flags & MODEL_GFX_MASK; + int gfx_flags = models[model]->flags & MODEL_GFX_MASK; - return (gfx_flags == MODEL_GFX_FIXED); + return (gfx_flags == MODEL_GFX_FIXED); } int model_has_optional_gfx(int model) { - int gfx_flags = models[model]->flags & MODEL_GFX_MASK; + int gfx_flags = models[model]->flags & MODEL_GFX_MASK; - return (gfx_flags == MODEL_GFX_DISABLE_HW || gfx_flags == MODEL_GFX_DISABLE_SW); + return (gfx_flags == MODEL_GFX_DISABLE_HW || gfx_flags == MODEL_GFX_DISABLE_SW); } void common_init() { - dma_init(); - fdc_add(); - lpt_init(); - pic_init(); - pit_init(); - serial1_init(0x3f8, 4, 1); - serial2_init(0x2f8, 3, 1); + dma_init(); + fdc_add(); + lpt_init(); + pic_init(); + pit_init(); + serial1_init(0x3f8, 4, 1); + serial2_init(0x2f8, 3, 1); } void xt_init() { - common_init(); - mem_add_bios(); - pit_set_out_func(&pit, 1, pit_refresh_timer_xt); - keyboard_xt_init(); - nmi_init(); - device_add(&gameport_device); - if (romset == ROM_IBMPC) - device_add(&cassette_device); + common_init(); + mem_add_bios(); + pit_set_out_func(&pit, 1, pit_refresh_timer_xt); + keyboard_xt_init(); + nmi_init(); + device_add(&gameport_device); + if (romset == ROM_IBMPC) + device_add(&cassette_device); } void compaq_xt_init() { - xt_init(); - lpt1_remove(); - lpt2_remove(); - lpt1_init(0x3bc); + xt_init(); + lpt1_remove(); + lpt2_remove(); + lpt1_init(0x3bc); } void pcjr_init() { - mem_add_bios(); - fdc_add_pcjr(); - pic_init(); - pit_init(); - pit_set_out_func(&pit, 0, pit_irq0_timer_pcjr); - serial1_init(0x2f8, 3, 1); - keyboard_pcjr_init(); - device_add(&sn76489_device); - nmi_mask = 0x80; - device_add(&cassette_device); + mem_add_bios(); + fdc_add_pcjr(); + pic_init(); + pit_init(); + pit_set_out_func(&pit, 0, pit_irq0_timer_pcjr); + serial1_init(0x2f8, 3, 1); + keyboard_pcjr_init(); + device_add(&sn76489_device); + nmi_mask = 0x80; + device_add(&cassette_device); } void tandy1k_init() { - TANDY = 1; - common_init(); - mem_add_bios(); - keyboard_tandy_init(); - if (romset == ROM_TANDY) - device_add(&sn76489_device); - else - device_add(&ncr8496_device); - nmi_init(); - if (romset != ROM_TANDY) - device_add(&tandy_eeprom_device); - device_add(&gameport_device); + TANDY = 1; + common_init(); + mem_add_bios(); + keyboard_tandy_init(); + if (romset == ROM_TANDY) + device_add(&sn76489_device); + else + device_add(&ncr8496_device); + nmi_init(); + if (romset != ROM_TANDY) + device_add(&tandy_eeprom_device); + device_add(&gameport_device); } void tandy1ksl2_init() { -// TANDY = 1; - common_init(); - mem_add_bios(); - keyboard_tandy_init(); - device_add(&pssj_device); - nmi_init(); - device_add(&tandy_rom_device); - device_add(&tandy_eeprom_device); - device_add(&gameport_device); + // TANDY = 1; + common_init(); + mem_add_bios(); + keyboard_tandy_init(); + device_add(&pssj_device); + nmi_init(); + device_add(&tandy_rom_device); + device_add(&tandy_eeprom_device); + device_add(&gameport_device); } void ams_init() { - AMSTRAD = 1; - common_init(); - mem_add_bios(); - lpt1_remove(); - amstrad_init(); - keyboard_amstrad_init(); - device_add(&nvr_device); - nmi_init(); - fdc_set_dskchg_activelow(); - device_add(&gameport_device); + AMSTRAD = 1; + common_init(); + mem_add_bios(); + lpt1_remove(); + amstrad_init(); + keyboard_amstrad_init(); + device_add(&nvr_device); + nmi_init(); + fdc_set_dskchg_activelow(); + device_add(&gameport_device); } void pc5086_init() { - xt_init(); - lpt1_remove(); /* remove LPT ports, they will be enabled by 82C710 */ - lpt2_remove(); - serial1_remove(); /* remove COM ports, they will be enabled by 82C710 */ - serial2_remove(); - device_add(&nvr_device); - fdc_set_dskchg_activelow(); - superxt_init(); + xt_init(); + lpt1_remove(); /* remove LPT ports, they will be enabled by 82C710 */ + lpt2_remove(); + serial1_remove(); /* remove COM ports, they will be enabled by 82C710 */ + serial2_remove(); + device_add(&nvr_device); + fdc_set_dskchg_activelow(); + superxt_init(); } void europc_init() { - common_init(); - mem_add_bios(); - jim_init(); - keyboard_xt_init(); - nmi_init(); - device_add(&gameport_device); + common_init(); + mem_add_bios(); + jim_init(); + keyboard_xt_init(); + nmi_init(); + device_add(&gameport_device); } void olim24_init() { - common_init(); - mem_add_bios(); - keyboard_olim24_init(); - device_add(&nvr_device); - olivetti_m24_init(); - nmi_init(); - device_add(&gameport_device); + common_init(); + mem_add_bios(); + keyboard_olim24_init(); + device_add(&nvr_device); + olivetti_m24_init(); + nmi_init(); + device_add(&gameport_device); } void xt_laserxt_init() { - xt_init(); - laserxt_init(); + xt_init(); + laserxt_init(); } void xt_zenith_init() /* [8088] Zenith Data Systems SupersPort */ { - dma_init(); - fdc_add(); - lpt_init(); - lpt2_remove(); /* only one parallel port */ - pic_init(); - pit_init(); - serial1_init(0x3f8, 4, 1); /* only one serial port */ - mem_add_bios(); - device_add(&zenith_scratchpad_device); - pit_set_out_func(&pit, 1, pit_refresh_timer_xt); - keyboard_xt_init(); - nmi_init(); + dma_init(); + fdc_add(); + lpt_init(); + lpt2_remove(); /* only one parallel port */ + pic_init(); + pit_init(); + serial1_init(0x3f8, 4, 1); /* only one serial port */ + mem_add_bios(); + device_add(&zenith_scratchpad_device); + pit_set_out_func(&pit, 1, pit_refresh_timer_xt); + keyboard_xt_init(); + nmi_init(); } void xt_xi8088_init() { - common_init(); - mem_add_bios(); - keyboard_at_init(); - keyboard_at_init_ps2(); - nmi_init(); - device_add(&nvr_device); - pic2_init(); - device_add(&gameport_device); - device_add(&sst_39sf010_device); + common_init(); + mem_add_bios(); + keyboard_at_init(); + keyboard_at_init_ps2(); + nmi_init(); + device_add(&nvr_device); + pic2_init(); + device_add(&gameport_device); + device_add(&sst_39sf010_device); } void at_init() { - AT = 1; - common_init(); - mem_add_bios(); - pit_set_out_func(&pit, 1, pit_refresh_timer_at); - dma16_init(); - keyboard_at_init(); - device_add(&nvr_device); - pic2_init(); - device_add(&gameport_device); - nmi_mask = 0; + AT = 1; + common_init(); + mem_add_bios(); + pit_set_out_func(&pit, 1, pit_refresh_timer_at); + dma16_init(); + keyboard_at_init(); + device_add(&nvr_device); + pic2_init(); + device_add(&gameport_device); + nmi_mask = 0; } void ibm_at_init() { - at_init(); - mem_remap_top_384k(); + at_init(); + mem_remap_top_384k(); } void at_cbm_init() { - at_init(); - cbm_io_init(); + at_init(); + cbm_io_init(); } void deskpro386_init() { - at_init(); - compaq_init(); + at_init(); + compaq_init(); } void dells200_init() { - at_init(); - dells200_chipset_init(); + at_init(); + dells200_chipset_init(); } void ps1_common_init() { - AT = 1; - common_init(); - mem_add_bios(); - pit_set_out_func(&pit, 1, pit_refresh_timer_at); - dma16_init(); - keyboard_at_init(); - device_add(&nvr_device); - pic2_init(); - fdc_set_dskchg_activelow(); - device_add(&ps1_audio_device); - /*PS/1 audio uses ports 200h and 202-207h, so only initialise gameport on 201h*/ - device_add(&gameport_201_device); + AT = 1; + common_init(); + mem_add_bios(); + pit_set_out_func(&pit, 1, pit_refresh_timer_at); + dma16_init(); + keyboard_at_init(); + device_add(&nvr_device); + pic2_init(); + fdc_set_dskchg_activelow(); + device_add(&ps1_audio_device); + /*PS/1 audio uses ports 200h and 202-207h, so only initialise gameport on 201h*/ + device_add(&gameport_201_device); } void ps1_m2011_init() { - ps1_common_init(); - ps1mb_init(); - mem_remap_top_384k(); + ps1_common_init(); + ps1mb_init(); + mem_remap_top_384k(); } void ps1_m2121_init() { - ps1_common_init(); - ps1mb_m2121_init(); - fdc_set_ps1(); + ps1_common_init(); + ps1mb_m2121_init(); + fdc_set_ps1(); } void ps1_m2133_init(void) { - at_init(); - vl82c480_init(); - ps1mb_m2133_init(); + at_init(); + vl82c480_init(); + ps1mb_m2133_init(); } void ps2_m30_286_init() { - AT = 1; - common_init(); - mem_add_bios(); - pit_set_out_func(&pit, 1, pit_refresh_timer_at); - dma16_init(); - keyboard_at_init(); -// mouse_ps2_init(); - device_add(&nvr_device); - pic2_init(); - ps2board_init(); - fdc_set_dskchg_activelow(); + AT = 1; + common_init(); + mem_add_bios(); + pit_set_out_func(&pit, 1, pit_refresh_timer_at); + dma16_init(); + keyboard_at_init(); + // mouse_ps2_init(); + device_add(&nvr_device); + pic2_init(); + ps2board_init(); + fdc_set_dskchg_activelow(); } static void ps2_common_init() { - AT = 1; - common_init(); - mem_add_bios(); - dma16_init(); - ps2_dma_init(); - keyboard_at_init(); - keyboard_at_init_ps2(); -// mouse_ps2_init(); - device_add(&nvr_device); - pic2_init(); + AT = 1; + common_init(); + mem_add_bios(); + dma16_init(); + ps2_dma_init(); + keyboard_at_init(); + keyboard_at_init_ps2(); + // mouse_ps2_init(); + device_add(&nvr_device); + pic2_init(); - pit_ps2_init(); + pit_ps2_init(); - nmi_mask = 0x80; + nmi_mask = 0x80; } void ps2_model_50_init() { - ps2_common_init(); - ps2_mca_board_model_50_init(); + ps2_common_init(); + ps2_mca_board_model_50_init(); } void ps2_model_55sx_init() { - ps2_common_init(); - ps2_mca_board_model_55sx_init(); + ps2_common_init(); + ps2_mca_board_model_55sx_init(); } void ps2_model_70_init() { - ps2_common_init(); - ps2_mca_board_model_70_type34_init(romset == ROM_IBMPS2_M70_TYPE4); + ps2_common_init(); + ps2_mca_board_model_70_type34_init(romset == ROM_IBMPS2_M70_TYPE4); } void ps2_model_80_init() { - ps2_common_init(); - ps2_mca_board_model_80_type2_init(); + ps2_common_init(); + ps2_mca_board_model_80_type2_init(); } void at_neat_init() { - at_init(); - neat_init(); + at_init(); + neat_init(); } void at_scamp_init() { - at_init(); - scamp_init(); + at_init(); + scamp_init(); } void at_scat_init() { - at_init(); - scat_init(); + at_init(); + scat_init(); } void at_scatsx_init() { - at_init(); - scatsx_init(); + at_init(); + scatsx_init(); } void at_acer386sx_init() { - at_init(); - acer386sx_init(); + at_init(); + acer386sx_init(); } void at_wd76c10_init() { - at_init(); - wd76c10_init(); + at_init(); + wd76c10_init(); } void at_headland_init() { - at_init(); - headland_init(); + at_init(); + headland_init(); } void at_opti495_init() { - at_init(); - opti495_init(); + at_init(); + opti495_init(); } void at_cs8230_init() { - at_init(); - cs8230_init(); + at_init(); + cs8230_init(); } void at_ali1429_init() { - at_init(); - ali1429_init(); + at_init(); + ali1429_init(); } void pb_l300sx_init() { - at_init(); - acc2036_init(); + at_init(); + acc2036_init(); } void at_pb410a_init() { - at_init(); - acc2168_init(); - acc3221_init(); + at_init(); + acc2168_init(); + acc3221_init(); } void at_sis496_init() { - at_init(); - pci_init(PCI_CONFIG_TYPE_1); - pci_slot(0xb); - pci_slot(0xd); - pci_slot(0xf); - device_add(&sis496_device); + at_init(); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0xb); + pci_slot(0xd); + pci_slot(0xf); + device_add(&sis496_device); } void at_sl82c460_init() { - at_init(); - sl82c460_init(); + at_init(); + sl82c460_init(); } void at_batman_init() { - at_init(); - pci_init(PCI_CONFIG_TYPE_2); - pci_slot(0xc); - pci_slot(0xe); - pci_slot(0x6); - i430lx_init(); - sio_init(2, 0xc, 0xe, 0x6, 0); - fdc37c665_init(); - intel_batman_init(); - device_add(&intel_flash_bxt_ami_device); + at_init(); + pci_init(PCI_CONFIG_TYPE_2); + pci_slot(0xc); + pci_slot(0xe); + pci_slot(0x6); + i430lx_init(); + sio_init(2, 0xc, 0xe, 0x6, 0); + fdc37c665_init(); + intel_batman_init(); + device_add(&intel_flash_bxt_ami_device); } void at_pb520r_init() { - at_init(); - pci_init(PCI_CONFIG_TYPE_2); - pci_slot(0xc); - pci_slot(0xe); - pci_slot(0x6); - i430lx_init(); - sio_init(2, 0xc, 0xe, 0x6, 0); - cmd640b_init(1); - aip_82091aa_init(0x22); - intel_batman_init(); - device_add(&intel_flash_bxt_ami_device); + at_init(); + pci_init(PCI_CONFIG_TYPE_2); + pci_slot(0xc); + pci_slot(0xe); + pci_slot(0x6); + i430lx_init(); + sio_init(2, 0xc, 0xe, 0x6, 0); + cmd640b_init(1); + aip_82091aa_init(0x22); + intel_batman_init(); + device_add(&intel_flash_bxt_ami_device); } void at_endeavor_init() { - at_init(); - pci_init(PCI_CONFIG_TYPE_1); - pci_slot(0xd); - pci_slot(0xe); - pci_slot(0xf); - pci_slot(0x10); - i430fx_init(); - piix_init(7, 0xd, 0xe, 0xf, 0x10, i430fx_reset); - pc87306_init(0x2e); - intel_endeavor_init(); - device_add(&intel_flash_bxt_ami_device); + at_init(); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0xd); + pci_slot(0xe); + pci_slot(0xf); + pci_slot(0x10); + i430fx_init(); + piix_init(7, 0xd, 0xe, 0xf, 0x10, i430fx_reset); + pc87306_init(0x2e); + intel_endeavor_init(); + device_add(&intel_flash_bxt_ami_device); } void at_pb570_init() { - at_init(); - pci_init(PCI_CONFIG_TYPE_1); - pci_slot(0x11); - pci_slot(0x13); - i430fx_init(); - piix_init(7, 0x11, 0x13, 0xb, 0x8, i430fx_reset); - pc87306_init(0x2e); - intel_endeavor_init(); - device_add(&intel_flash_bxt_ami_device); + at_init(); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0x11); + pci_slot(0x13); + i430fx_init(); + piix_init(7, 0x11, 0x13, 0xb, 0x8, i430fx_reset); + pc87306_init(0x2e); + intel_endeavor_init(); + device_add(&intel_flash_bxt_ami_device); } void at_zappa_init() { - at_init(); - pci_init(PCI_CONFIG_TYPE_1); - pci_slot(0xd); - pci_slot(0xe); - pci_slot(0xf); - pci_slot(0x10); - i430fx_init(); - piix_init(7, 0xd, 0xf, 0xe, 0x10, i430fx_reset); - pc87306_init(0x2e); - intel_zappa_init(); - device_add(&intel_flash_bxt_ami_device); + at_init(); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0xd); + pci_slot(0xe); + pci_slot(0xf); + pci_slot(0x10); + i430fx_init(); + piix_init(7, 0xd, 0xf, 0xe, 0x10, i430fx_reset); + pc87306_init(0x2e); + intel_zappa_init(); + device_add(&intel_flash_bxt_ami_device); } void at_p55va_init() { - at_init(); - pci_init(PCI_CONFIG_TYPE_1); - pci_slot(0x08); - pci_slot(0x09); - pci_slot(0x0A); - pci_slot(0x0B); - i430vx_init(); - piix_init(7, 0x08, 0x09, 0x0A, 0x0B, i430vx_reset); - fdc37c932fr_init(); - device_add(&intel_flash_bxt_device); + at_init(); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0x08); + pci_slot(0x09); + pci_slot(0x0A); + pci_slot(0x0B); + i430vx_init(); + piix_init(7, 0x08, 0x09, 0x0A, 0x0B, i430vx_reset); + fdc37c932fr_init(); + device_add(&intel_flash_bxt_device); } void at_p55tvp4_init() { - at_init(); - pci_init(PCI_CONFIG_TYPE_1); - pci_slot(0x0C); - pci_slot(0x0B); - pci_slot(0x0A); - pci_slot(0x09); - i430vx_init(); - piix_init(7, 0x0C, 0x0B, 0x0A, 0x09, i430vx_reset); - w83877f_init(0x3f0, 0x87); - device_add(&intel_flash_bxt_device); + at_init(); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0x0C); + pci_slot(0x0B); + pci_slot(0x0A); + pci_slot(0x09); + i430vx_init(); + piix_init(7, 0x0C, 0x0B, 0x0A, 0x09, i430vx_reset); + w83877f_init(0x3f0, 0x87); + device_add(&intel_flash_bxt_device); } void at_i430vx_init() { - at_init(); - pci_init(PCI_CONFIG_TYPE_1); - pci_slot(0x11); - pci_slot(0x12); - pci_slot(0x13); - pci_slot(0x14); - i430vx_init(); - piix_init(7, 18, 17, 20, 19, i430vx_reset); - um8669f_init(); - device_add(&intel_flash_bxt_device); + at_init(); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0x11); + pci_slot(0x12); + pci_slot(0x13); + pci_slot(0x14); + i430vx_init(); + piix_init(7, 18, 17, 20, 19, i430vx_reset); + um8669f_init(); + device_add(&intel_flash_bxt_device); } void at_p55t2p4_init() { - at_init(); - pci_init(PCI_CONFIG_TYPE_1); - pci_slot(0x0C); - pci_slot(0x0B); - pci_slot(0x0A); - pci_slot(0x09); - i430hx_init(); - piix_init(7, 0x0C, 0x0B, 0x0A, 0x09, i430hx_reset); - w83877f_init(0x3f0, 0x87); - device_add(&intel_flash_bxt_device); + at_init(); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0x0C); + pci_slot(0x0B); + pci_slot(0x0A); + pci_slot(0x09); + i430hx_init(); + piix_init(7, 0x0C, 0x0B, 0x0A, 0x09, i430hx_reset); + w83877f_init(0x3f0, 0x87); + device_add(&intel_flash_bxt_device); } void at_mvp3_init() { - at_init(); - pci_init(PCI_CONFIG_TYPE_1); - pci_slot(8); - pci_slot(9); - pci_slot(10); - mvp3_init(); - vt82c586b_init(7, 8, 9, 10, 0); - w83877tf_init(0x250, 0x89); - device_add(&sst_39sf010_device); + at_init(); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(8); + pci_slot(9); + pci_slot(10); + mvp3_init(); + vt82c586b_init(7, 8, 9, 10, 0); + w83877tf_init(0x250, 0x89); + device_add(&sst_39sf010_device); } void at_vs440fx_init() { - at_init(); - pci_init(PCI_CONFIG_TYPE_1); - pci_slot(0xb); - pci_slot(0xf); - pci_slot(0x11); - pci_slot(0x13); - i440fx_init(); - piix_init(7, 0xb, 0xf, 0x11, 0x13, i440fx_reset); - pc87307_init(0x2e); -// i440fx_init(); - device_add(&intel_flash_28fb200bxt_device); + at_init(); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0xb); + pci_slot(0xf); + pci_slot(0x11); + pci_slot(0x13); + i440fx_init(); + piix_init(7, 0xb, 0xf, 0x11, 0x13, i440fx_reset); + pc87307_init(0x2e); + // i440fx_init(); + device_add(&intel_flash_28fb200bxt_device); } void at_ga686bx_init() { - at_init(); - pci_init(PCI_CONFIG_TYPE_1); - pci_slot(0x8); - pci_slot(0x9); - pci_slot(0xa); - pci_slot(0xb); - i440bx_init(); - piix4_init(7, 0x8, 0x9, 0xa, 0xb, i440bx_reset); - w83977tf_init(0x3f0, 0x87); - device_add(&intel_flash_28f002bc_device); + at_init(); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0x8); + pci_slot(0x9); + pci_slot(0xa); + pci_slot(0xb); + i440bx_init(); + piix4_init(7, 0x8, 0x9, 0xa, 0xb, i440bx_reset); + w83977tf_init(0x3f0, 0x87); + device_add(&intel_flash_28f002bc_device); } void model_init() { - pclog("Initting as %s\n", model_getname()); - AMSTRAD = AT = PCI = TANDY = MCA = 0; - ide_set_bus_master(NULL, NULL, NULL, NULL); + pclog("Initting as %s\n", model_getname()); + AMSTRAD = AT = PCI = TANDY = MCA = 0; + ide_set_bus_master(NULL, NULL, NULL, NULL); - models[model]->init(); - if (models[model]->device) - device_add(models[model]->device); + models[model]->init(); + if (models[model]->device) + device_add(models[model]->device); } /* 8088 PC's */ -MODEL m_amixt = {"[8088] AMI XT clone", ROM_AMIXT, "amixt", {{"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 64, 640, 64, xt_init, NULL}; -MODEL m_ataripc3 = {"[8088] Atari PC3", ROM_ATARIPC3, "ataripc3", {{"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 64, 640, 64, xt_init, NULL}; -MODEL m_cbm_pc10 = {"[8088] Commodore PC-10", ROM_CBM_PC10, "cbm_pc10", {{"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 640, 640, 64, xt_init, NULL}; -MODEL m_compaq_pip = {"[8088] Compaq Portable Plus", ROM_COMPAQ_PIP, "compaq_pip", {{"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 128, 640, 64, compaq_xt_init, NULL}; -MODEL m_dtk = {"[8088] DTK XT clone", ROM_DTKXT, "dtk", {{"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 64, 640, 64, xt_init, NULL}; -MODEL m_genxt = {"[8088] Generic XT clone", ROM_GENXT, "genxt", {{"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 32, 704, 16, xt_init, NULL}; -MODEL m_hyundaixt = {"[8088] Hyundai Super16T", ROM_SUPER16T, "hyundaixt", {{"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 640, 640, 64, xt_init, NULL}; -MODEL m_hyundaixte = {"[8088] Hyundai Super16TE", ROM_SUPER16TE, "hyundaixte", {{"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 640, 640, 64, xt_init, NULL}; -MODEL m_ibmpc = {"[8088] IBM PC", ROM_IBMPC, "ibmpc", {{"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 64, 640, 32, xt_init, NULL}; -MODEL m_ibmpcjr = {"[8088] IBM PCjr", ROM_IBMPCJR, "ibmpcjr", {{"", cpus_pcjr}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED, 128, 640, 64, pcjr_init, &pcjr_device}; -MODEL m_ibmxt = {"[8088] IBM XT", ROM_IBMXT, "ibmxt", {{"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 64, 640, 64, xt_init, NULL}; -MODEL m_jukopc = {"[8088] Juko XT clone", ROM_JUKOPC, "jukopc", {{"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 64, 640, 64, xt_init, NULL}; -MODEL m_ledge_modelm = {"[8088] Leading Edge Model M", ROM_LEDGE_MODELM, "ledge_modelm", {{"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 128, 704, 64, xt_init, NULL}; -MODEL m_ncr_pc4i = {"[8088] NCR PC4i", ROM_NCR_PC4I, "ncr_pc4i", {{"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 256, 640, 64, xt_init, NULL}; -MODEL m_pxxt = {"[8088] Phoenix XT clone", ROM_PXXT, "pxxt", {{"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 64, 640, 64, xt_init, NULL}; -MODEL m_europc = {"[8088] Schneider EuroPC", ROM_EUROPC, "europc", {{"", cpus_europc}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 512, 640, 128, europc_init, NULL}; -MODEL m_tandy = {"[8088] Tandy 1000", ROM_TANDY, "tandy", {{"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED, 128, 640, 128, tandy1k_init, &tandy1000_device}; -MODEL m_tandy1000hx = {"[8088] Tandy 1000 HX", ROM_TANDY1000HX, "tandy1000hx", {{"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED, 256, 640, 128, tandy1k_init, &tandy1000hx_device}; -MODEL m_to16_pc = {"[8088] Thomson TO16 PC", ROM_TO16_PC, "to16_pc", {{"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 512, 640, 128, xt_init, NULL}; -MODEL m_t1000 = {"[8088] Toshiba T1000", ROM_T1000, "t1000", {{"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED, 512, 1280, 768, xt_t1000_init, NULL}; -MODEL m_ltxt = {"[8088] VTech Laser Turbo XT", ROM_LTXT, "ltxt", {{"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 64, 1152, 64, xt_laserxt_init, NULL}; -MODEL m_xi8088 = {"[8088] Xi8088", ROM_XI8088, "xi8088", {{"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE | MODEL_AT | MODEL_PS2, 64, 1024, 128, xt_xi8088_init, &xi8088_device}; -MODEL m_zdsupers = {"[8088] Zenith Data SupersPort", ROM_ZD_SUPERS, "zdsupers", {{"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 128, 640, 128, xt_zenith_init, NULL}; +MODEL m_amixt = {"[8088] AMI XT clone", + ROM_AMIXT, + "amixt", + {{"", cpus_8088}, {"", NULL}, {"", NULL}}, + MODEL_GFX_NONE, + 64, + 640, + 64, + xt_init, + NULL}; +MODEL m_ataripc3 = {"[8088] Atari PC3", + ROM_ATARIPC3, + "ataripc3", + {{"", cpus_8088}, {"", NULL}, {"", NULL}}, + MODEL_GFX_NONE, + 64, + 640, + 64, + xt_init, + NULL}; +MODEL m_cbm_pc10 = {"[8088] Commodore PC-10", + ROM_CBM_PC10, + "cbm_pc10", + {{"", cpus_8088}, {"", NULL}, {"", NULL}}, + MODEL_GFX_NONE, + 640, + 640, + 64, + xt_init, + NULL}; +MODEL m_compaq_pip = {"[8088] Compaq Portable Plus", + ROM_COMPAQ_PIP, + "compaq_pip", + {{"", cpus_8088}, {"", NULL}, {"", NULL}}, + MODEL_GFX_NONE, + 128, + 640, + 64, + compaq_xt_init, + NULL}; +MODEL m_dtk = {"[8088] DTK XT clone", + ROM_DTKXT, + "dtk", + {{"", cpus_8088}, {"", NULL}, {"", NULL}}, + MODEL_GFX_NONE, + 64, + 640, + 64, + xt_init, + NULL}; +MODEL m_genxt = {"[8088] Generic XT clone", + ROM_GENXT, + "genxt", + {{"", cpus_8088}, {"", NULL}, {"", NULL}}, + MODEL_GFX_NONE, + 32, + 704, + 16, + xt_init, + NULL}; +MODEL m_hyundaixt = {"[8088] Hyundai Super16T", + ROM_SUPER16T, + "hyundaixt", + {{"", cpus_8088}, {"", NULL}, {"", NULL}}, + MODEL_GFX_NONE, + 640, + 640, + 64, + xt_init, + NULL}; +MODEL m_hyundaixte = {"[8088] Hyundai Super16TE", + ROM_SUPER16TE, + "hyundaixte", + {{"", cpus_8088}, {"", NULL}, {"", NULL}}, + MODEL_GFX_NONE, + 640, + 640, + 64, + xt_init, + NULL}; +MODEL m_ibmpc = {"[8088] IBM PC", ROM_IBMPC, "ibmpc", {{"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 64, 640, 32, + xt_init, NULL}; +MODEL m_ibmpcjr = {"[8088] IBM PCjr", ROM_IBMPCJR, "ibmpcjr", {{"", cpus_pcjr}, {"", NULL}, {"", NULL}}, + MODEL_GFX_FIXED, 128, 640, 64, + pcjr_init, &pcjr_device}; +MODEL m_ibmxt = {"[8088] IBM XT", ROM_IBMXT, "ibmxt", {{"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 64, 640, 64, + xt_init, NULL}; +MODEL m_jukopc = {"[8088] Juko XT clone", + ROM_JUKOPC, + "jukopc", + {{"", cpus_8088}, {"", NULL}, {"", NULL}}, + MODEL_GFX_NONE, + 64, + 640, + 64, + xt_init, + NULL}; +MODEL m_ledge_modelm = {"[8088] Leading Edge Model M", + ROM_LEDGE_MODELM, + "ledge_modelm", + {{"", cpus_8088}, {"", NULL}, {"", NULL}}, + MODEL_GFX_NONE, + 128, + 704, + 64, + xt_init, + NULL}; +MODEL m_ncr_pc4i = {"[8088] NCR PC4i", ROM_NCR_PC4I, "ncr_pc4i", {{"", cpus_8088}, {"", NULL}, {"", NULL}}, + MODEL_GFX_NONE, 256, 640, 64, + xt_init, NULL}; +MODEL m_pxxt = {"[8088] Phoenix XT clone", + ROM_PXXT, + "pxxt", + {{"", cpus_8088}, {"", NULL}, {"", NULL}}, + MODEL_GFX_NONE, + 64, + 640, + 64, + xt_init, + NULL}; +MODEL m_europc = {"[8088] Schneider EuroPC", + ROM_EUROPC, + "europc", + {{"", cpus_europc}, {"", NULL}, {"", NULL}}, + MODEL_GFX_NONE, + 512, + 640, + 128, + europc_init, + NULL}; +MODEL m_tandy = { + "[8088] Tandy 1000", ROM_TANDY, "tandy", {{"", cpus_8088}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED, 128, 640, 128, + tandy1k_init, &tandy1000_device}; +MODEL m_tandy1000hx = {"[8088] Tandy 1000 HX", + ROM_TANDY1000HX, + "tandy1000hx", + {{"", cpus_8088}, {"", NULL}, {"", NULL}}, + MODEL_GFX_FIXED, + 256, + 640, + 128, + tandy1k_init, + &tandy1000hx_device}; +MODEL m_to16_pc = {"[8088] Thomson TO16 PC", + ROM_TO16_PC, + "to16_pc", + {{"", cpus_8088}, {"", NULL}, {"", NULL}}, + MODEL_GFX_NONE, + 512, + 640, + 128, + xt_init, + NULL}; +MODEL m_t1000 = {"[8088] Toshiba T1000", ROM_T1000, "t1000", {{"", cpus_8088}, {"", NULL}, {"", NULL}}, + MODEL_GFX_FIXED, 512, 1280, 768, + xt_t1000_init, NULL}; +MODEL m_ltxt = {"[8088] VTech Laser Turbo XT", + ROM_LTXT, + "ltxt", + {{"", cpus_8088}, {"", NULL}, {"", NULL}}, + MODEL_GFX_NONE, + 64, + 1152, + 64, + xt_laserxt_init, + NULL}; +MODEL m_xi8088 = {"[8088] Xi8088", + ROM_XI8088, + "xi8088", + {{"", cpus_8088}, {"", NULL}, {"", NULL}}, + MODEL_GFX_NONE | MODEL_AT | MODEL_PS2, + 64, + 1024, + 128, + xt_xi8088_init, + &xi8088_device}; +MODEL m_zdsupers = {"[8088] Zenith Data SupersPort", + ROM_ZD_SUPERS, + "zdsupers", + {{"", cpus_8088}, {"", NULL}, {"", NULL}}, + MODEL_GFX_NONE, + 128, + 640, + 128, + xt_zenith_init, + NULL}; /* 8086 PC's */ -MODEL m_pc1512 = {"[8086] Amstrad PC1512", ROM_PC1512, "pc1512", {{"", cpus_pc1512}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED | MODEL_AMSTRAD, 512, 640, 128, ams_init, &ams1512_device}; -MODEL m_pc1640 = {"[8086] Amstrad PC1640", ROM_PC1640, "pc1640", {{"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_HW | MODEL_AMSTRAD, 640, 640, 0, ams_init, &ams1512_device}; -MODEL m_pc2086 = {"[8086] Amstrad PC2086", ROM_PC2086, "pc2086", {{"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_HW | MODEL_AMSTRAD, 640, 640, 0, ams_init, &ams2086_device}; -MODEL m_pc3086 = {"[8086] Amstrad PC3086", ROM_PC3086, "pc3086", {{"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_HW | MODEL_AMSTRAD, 640, 640, 0, ams_init, &ams3086_device}; -MODEL m_pc5086 = {"[8086] Amstrad PC5086", ROM_PC5086, "pc5086", {{"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE | MODEL_PS2, 640, 640, 0, pc5086_init, &f82c710_upc_device}; -MODEL m_ppc512 = {"[8086] Amstrad PPC512/640", ROM_PPC512, "ppc512", {{"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_HW | MODEL_AMSTRAD, 512, 640, 128, ams_init, &ams1512_device}; -MODEL m_deskpro = {"[8086] Compaq Deskpro", ROM_DESKPRO, "deskpro", {{"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 128, 640, 128, compaq_xt_init, NULL}; -MODEL m_olivetti_m24 = {"[8086] Olivetti M24", ROM_OLIM24, "olivetti_m24", {{"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED | MODEL_OLIM24, 128, 640, 128, olim24_init, NULL}; -MODEL m_pc200 = {"[8086] Sinclair PC200", ROM_PC200, "pc200", {{"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_HW | MODEL_AMSTRAD, 512, 640, 128, ams_init, &ams1512_device}; -MODEL m_tandy1000sl2 = {"[8086] Tandy 1000 SL/2", ROM_TANDY1000SL2, "tandy1000sl2", {{"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED, 512, 768, 128, tandy1ksl2_init, NULL}; -MODEL m_t1200 = {"[8088] Toshiba T1200", ROM_T1200, "t1200", {{"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED, 1024, 2048, 1024, xt_t1200_init, NULL}; -MODEL m_lxt3 = {"[8086] VTech Laser XT3", ROM_LXT3, "lxt3", {{"", cpus_8086}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE, 512, 1152, 128, xt_laserxt_init, NULL}; +MODEL m_pc1512 = {"[8086] Amstrad PC1512", + ROM_PC1512, + "pc1512", + {{"", cpus_pc1512}, {"", NULL}, {"", NULL}}, + MODEL_GFX_FIXED | MODEL_AMSTRAD, + 512, + 640, + 128, + ams_init, + &ams1512_device}; +MODEL m_pc1640 = {"[8086] Amstrad PC1640", + ROM_PC1640, + "pc1640", + {{"", cpus_8086}, {"", NULL}, {"", NULL}}, + MODEL_GFX_DISABLE_HW | MODEL_AMSTRAD, + 640, + 640, + 0, + ams_init, + &ams1512_device}; +MODEL m_pc2086 = {"[8086] Amstrad PC2086", + ROM_PC2086, + "pc2086", + {{"", cpus_8086}, {"", NULL}, {"", NULL}}, + MODEL_GFX_DISABLE_HW | MODEL_AMSTRAD, + 640, + 640, + 0, + ams_init, + &ams2086_device}; +MODEL m_pc3086 = {"[8086] Amstrad PC3086", + ROM_PC3086, + "pc3086", + {{"", cpus_8086}, {"", NULL}, {"", NULL}}, + MODEL_GFX_DISABLE_HW | MODEL_AMSTRAD, + 640, + 640, + 0, + ams_init, + &ams3086_device}; +MODEL m_pc5086 = {"[8086] Amstrad PC5086", + ROM_PC5086, + "pc5086", + {{"", cpus_8086}, {"", NULL}, {"", NULL}}, + MODEL_GFX_NONE | MODEL_PS2, + 640, + 640, + 0, + pc5086_init, + &f82c710_upc_device}; +MODEL m_ppc512 = {"[8086] Amstrad PPC512/640", + ROM_PPC512, + "ppc512", + {{"", cpus_8086}, {"", NULL}, {"", NULL}}, + MODEL_GFX_DISABLE_HW | MODEL_AMSTRAD, + 512, + 640, + 128, + ams_init, + &ams1512_device}; +MODEL m_deskpro = {"[8086] Compaq Deskpro", ROM_DESKPRO, "deskpro", {{"", cpus_8086}, {"", NULL}, {"", NULL}}, + MODEL_GFX_NONE, 128, 640, 128, + compaq_xt_init, NULL}; +MODEL m_olivetti_m24 = {"[8086] Olivetti M24", + ROM_OLIM24, + "olivetti_m24", + {{"", cpus_8086}, {"", NULL}, {"", NULL}}, + MODEL_GFX_FIXED | MODEL_OLIM24, + 128, + 640, + 128, + olim24_init, + NULL}; +MODEL m_pc200 = {"[8086] Sinclair PC200", + ROM_PC200, + "pc200", + {{"", cpus_8086}, {"", NULL}, {"", NULL}}, + MODEL_GFX_DISABLE_HW | MODEL_AMSTRAD, + 512, + 640, + 128, + ams_init, + &ams1512_device}; +MODEL m_tandy1000sl2 = {"[8086] Tandy 1000 SL/2", + ROM_TANDY1000SL2, + "tandy1000sl2", + {{"", cpus_8086}, {"", NULL}, {"", NULL}}, + MODEL_GFX_FIXED, + 512, + 768, + 128, + tandy1ksl2_init, + NULL}; +MODEL m_t1200 = {"[8088] Toshiba T1200", ROM_T1200, "t1200", {{"", cpus_8086}, {"", NULL}, {"", NULL}}, + MODEL_GFX_FIXED, 1024, 2048, 1024, + xt_t1200_init, NULL}; +MODEL m_lxt3 = {"[8086] VTech Laser XT3", ROM_LXT3, "lxt3", {{"", cpus_8086}, {"", NULL}, {"", NULL}}, + MODEL_GFX_NONE, 512, 1152, 128, + xt_laserxt_init, NULL}; /* 286 PC's */ -MODEL m_ami286 = {"[286] AMI 286 clone", ROM_AMI286, "ami286", {{"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE | MODEL_AT | MODEL_HAS_IDE, 512, 16384, 128, at_neat_init, NULL}; -MODEL m_award286 = {"[286] Award 286 clone", ROM_AWARD286, "award286", {{"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE | MODEL_AT | MODEL_HAS_IDE, 512, 16384, 128, at_scat_init, NULL}; -MODEL m_bull_micral_45 = - {"[286] Bull Micral 45", ROM_BULL_MICRAL_45, "bull_micral_45", {{"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE | MODEL_AT | MODEL_HAS_IDE, 1024, 6144, 128, ibm_at_init, NULL}; -MODEL m_cmdpc30 = {"[286] Commodore PC 30 III", ROM_CMDPC30, "cmdpc30", {{"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE | MODEL_AT | MODEL_HAS_IDE, 640, 16384, 128, at_cbm_init, NULL}; -MODEL m_compaq_pii = - {"[286] Compaq Portable II", ROM_COMPAQ_PII, "compaq_pii", {{"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE | MODEL_AT | MODEL_HAS_IDE, 256, 15872, 128, ibm_at_init, NULL}; -MODEL m_dells200 = {"[286] DELL System 200", ROM_DELL200, "dells200", {{"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE | MODEL_AT, 640, 16384, 128, dells200_init, NULL}; -MODEL m_epson_pcax = {"[286] Epson PC AX", ROM_EPSON_PCAX, "epson_pcax", {{"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE | MODEL_AT, 256, 15872, 128, at_init, NULL}; -MODEL m_epson_pcax2e = {"[286] Epson PC AX2e", ROM_EPSON_PCAX2E, "epson_pcax2e", {{"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE | MODEL_AT | MODEL_PS2, 256, 15872, 128, at_init, NULL}; -MODEL m_gdc212m = - {"[286] Goldstar GDC-212M", ROM_GDC212M, "gdc212m", {{"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE | MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 512, 4096, 512, at_scat_init, NULL}; -MODEL m_gw286ct = {"[286] GW-286CT GEAR", ROM_GW286CT, "gw286ct", {{"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE | MODEL_AT, 512, 16384, 128, at_scat_init, NULL}; -MODEL m_super286tr = {"[286] Hyundai Super-286TR", ROM_HYUNDAI_SUPER286TR, "super286tr", {{"AMD", cpus_super286tr}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE | MODEL_AT | MODEL_HAS_IDE, 1024, 4096, 128, - at_scat_init, &f82c710_upc_device}; -MODEL m_ibmat = {"[286] IBM AT", ROM_IBMAT, "ibmat", {{"", cpus_ibmat}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE | MODEL_AT, 256, 15872, 128, ibm_at_init, NULL}; -MODEL m_ibmps1es = - {"[286] IBM PS/1 model 2011", ROM_IBMPS1_2011, "ibmps1es", {{"", cpus_ps1_m2011}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED | MODEL_AT | MODEL_PS2, 512, 16384, 512, ps1_m2011_init, NULL}; -MODEL m_ibmps2_m30_286 = - {"[286] IBM PS/2 Model 30-286", ROM_IBMPS2_M30_286, "ibmps2_m30_286", {{"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED | MODEL_AT | MODEL_PS2, 1, 16, 1, ps2_m30_286_init, - NULL}; -MODEL m_ibmps2_m50 = {"[286] IBM PS/2 Model 50", ROM_IBMPS2_M50, "ibmps2_m50", {{"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_SW | MODEL_AT | MODEL_PS2 | MODEL_MCA, 1, 16, 1, - ps2_model_50_init, NULL}; -MODEL m_ibmxt286 = {"[286] IBM XT Model 286", ROM_IBMXT286, "ibmxt286", {{"", cpus_ibmxt286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE | MODEL_AT, 256, 15872, 128, ibm_at_init, NULL}; -MODEL m_spc4200p = - {"[286] Samsung SPC-4200P", ROM_SPC4200P, "spc4200p", {{"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE | MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 512, 2048, 128, at_scat_init, NULL}; -MODEL m_spc4216p = {"[286] Samsung SPC-4216P", ROM_SPC4216P, "spc4216p", {{"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE | MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 5, 1, at_scat_init, NULL}; -MODEL m_spc4620p = - {"[286] Samsung SPC-4620P", ROM_SPC4620P, "spc4620p", {{"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_HW | MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 5, 1, at_scat_init, NULL}; -MODEL m_t3100e = {"[286] Toshiba T3100e", ROM_T3100E, "t3100e", {{"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_FIXED | MODEL_AT | MODEL_HAS_IDE, 1024, 5120, 256, at_t3100e_init, NULL}; -MODEL m_tg286m = {"[286] Trigem 286M", ROM_TG286M, "tg286m", {{"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE | MODEL_AT | MODEL_HAS_IDE, 512, 8192, 128, at_headland_init, NULL}; -MODEL m_tulip_tc7 = {"[286] Tulip AT Compact", ROM_TULIP_TC7, "tulip_tc7", {{"", cpus_286}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE | MODEL_AT | MODEL_HAS_IDE, 640, 15872, 128, ibm_at_init, NULL}; +MODEL m_ami286 = {"[286] AMI 286 clone", + ROM_AMI286, + "ami286", + {{"", cpus_286}, {"", NULL}, {"", NULL}}, + MODEL_GFX_NONE | MODEL_AT | MODEL_HAS_IDE, + 512, + 16384, + 128, + at_neat_init, + NULL}; +MODEL m_award286 = {"[286] Award 286 clone", + ROM_AWARD286, + "award286", + {{"", cpus_286}, {"", NULL}, {"", NULL}}, + MODEL_GFX_NONE | MODEL_AT | MODEL_HAS_IDE, + 512, + 16384, + 128, + at_scat_init, + NULL}; +MODEL m_bull_micral_45 = {"[286] Bull Micral 45", + ROM_BULL_MICRAL_45, + "bull_micral_45", + {{"", cpus_286}, {"", NULL}, {"", NULL}}, + MODEL_GFX_NONE | MODEL_AT | MODEL_HAS_IDE, + 1024, + 6144, + 128, + ibm_at_init, + NULL}; +MODEL m_cmdpc30 = {"[286] Commodore PC 30 III", + ROM_CMDPC30, + "cmdpc30", + {{"", cpus_286}, {"", NULL}, {"", NULL}}, + MODEL_GFX_NONE | MODEL_AT | MODEL_HAS_IDE, + 640, + 16384, + 128, + at_cbm_init, + NULL}; +MODEL m_compaq_pii = {"[286] Compaq Portable II", + ROM_COMPAQ_PII, + "compaq_pii", + {{"", cpus_286}, {"", NULL}, {"", NULL}}, + MODEL_GFX_NONE | MODEL_AT | MODEL_HAS_IDE, + 256, + 15872, + 128, + ibm_at_init, + NULL}; +MODEL m_dells200 = {"[286] DELL System 200", + ROM_DELL200, + "dells200", + {{"", cpus_286}, {"", NULL}, {"", NULL}}, + MODEL_GFX_NONE | MODEL_AT, + 640, + 16384, + 128, + dells200_init, + NULL}; +MODEL m_epson_pcax = {"[286] Epson PC AX", + ROM_EPSON_PCAX, + "epson_pcax", + {{"", cpus_286}, {"", NULL}, {"", NULL}}, + MODEL_GFX_NONE | MODEL_AT, + 256, + 15872, + 128, + at_init, + NULL}; +MODEL m_epson_pcax2e = {"[286] Epson PC AX2e", + ROM_EPSON_PCAX2E, + "epson_pcax2e", + {{"", cpus_286}, {"", NULL}, {"", NULL}}, + MODEL_GFX_NONE | MODEL_AT | MODEL_PS2, + 256, + 15872, + 128, + at_init, + NULL}; +MODEL m_gdc212m = {"[286] Goldstar GDC-212M", + ROM_GDC212M, + "gdc212m", + {{"", cpus_286}, {"", NULL}, {"", NULL}}, + MODEL_GFX_NONE | MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, + 512, + 4096, + 512, + at_scat_init, + NULL}; +MODEL m_gw286ct = {"[286] GW-286CT GEAR", + ROM_GW286CT, + "gw286ct", + {{"", cpus_286}, {"", NULL}, {"", NULL}}, + MODEL_GFX_NONE | MODEL_AT, + 512, + 16384, + 128, + at_scat_init, + NULL}; +MODEL m_super286tr = {"[286] Hyundai Super-286TR", + ROM_HYUNDAI_SUPER286TR, + "super286tr", + {{"AMD", cpus_super286tr}, {"", NULL}, {"", NULL}}, + MODEL_GFX_NONE | MODEL_AT | MODEL_HAS_IDE, + 1024, + 4096, + 128, + at_scat_init, + &f82c710_upc_device}; +MODEL m_ibmat = {"[286] IBM AT", + ROM_IBMAT, + "ibmat", + {{"", cpus_ibmat}, {"", NULL}, {"", NULL}}, + MODEL_GFX_NONE | MODEL_AT, + 256, + 15872, + 128, + ibm_at_init, + NULL}; +MODEL m_ibmps1es = {"[286] IBM PS/1 model 2011", + ROM_IBMPS1_2011, + "ibmps1es", + {{"", cpus_ps1_m2011}, {"", NULL}, {"", NULL}}, + MODEL_GFX_FIXED | MODEL_AT | MODEL_PS2, + 512, + 16384, + 512, + ps1_m2011_init, + NULL}; +MODEL m_ibmps2_m30_286 = {"[286] IBM PS/2 Model 30-286", + ROM_IBMPS2_M30_286, + "ibmps2_m30_286", + {{"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}}, + MODEL_GFX_FIXED | MODEL_AT | MODEL_PS2, + 1, + 16, + 1, + ps2_m30_286_init, + NULL}; +MODEL m_ibmps2_m50 = {"[286] IBM PS/2 Model 50", + ROM_IBMPS2_M50, + "ibmps2_m50", + {{"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}}, + MODEL_GFX_DISABLE_SW | MODEL_AT | MODEL_PS2 | MODEL_MCA, + 1, + 16, + 1, + ps2_model_50_init, + NULL}; +MODEL m_ibmxt286 = {"[286] IBM XT Model 286", + ROM_IBMXT286, + "ibmxt286", + {{"", cpus_ibmxt286}, {"", NULL}, {"", NULL}}, + MODEL_GFX_NONE | MODEL_AT, + 256, + 15872, + 128, + ibm_at_init, + NULL}; +MODEL m_spc4200p = {"[286] Samsung SPC-4200P", + ROM_SPC4200P, + "spc4200p", + {{"", cpus_286}, {"", NULL}, {"", NULL}}, + MODEL_GFX_NONE | MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, + 512, + 2048, + 128, + at_scat_init, + NULL}; +MODEL m_spc4216p = {"[286] Samsung SPC-4216P", + ROM_SPC4216P, + "spc4216p", + {{"", cpus_286}, {"", NULL}, {"", NULL}}, + MODEL_GFX_NONE | MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, + 1, + 5, + 1, + at_scat_init, + NULL}; +MODEL m_spc4620p = {"[286] Samsung SPC-4620P", + ROM_SPC4620P, + "spc4620p", + {{"", cpus_286}, {"", NULL}, {"", NULL}}, + MODEL_GFX_DISABLE_HW | MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, + 1, + 5, + 1, + at_scat_init, + NULL}; +MODEL m_t3100e = {"[286] Toshiba T3100e", + ROM_T3100E, + "t3100e", + {{"", cpus_286}, {"", NULL}, {"", NULL}}, + MODEL_GFX_FIXED | MODEL_AT | MODEL_HAS_IDE, + 1024, + 5120, + 256, + at_t3100e_init, + NULL}; +MODEL m_tg286m = {"[286] Trigem 286M", + ROM_TG286M, + "tg286m", + {{"", cpus_286}, {"", NULL}, {"", NULL}}, + MODEL_GFX_NONE | MODEL_AT | MODEL_HAS_IDE, + 512, + 8192, + 128, + at_headland_init, + NULL}; +MODEL m_tulip_tc7 = {"[286] Tulip AT Compact", + ROM_TULIP_TC7, + "tulip_tc7", + {{"", cpus_286}, {"", NULL}, {"", NULL}}, + MODEL_GFX_NONE | MODEL_AT | MODEL_HAS_IDE, + 640, + 15872, + 128, + ibm_at_init, + NULL}; /* 386SX PC's */ -MODEL m_acer386 = - {"[386SX] Acer 386SX25/N", ROM_ACER386, "acer386", {{"Intel", cpus_acer}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_SW | MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, at_acer386sx_init, - NULL}; -MODEL m_ama932j = {"[386SX] AMA-932J", ROM_AMA932J, "ama932j", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_FIXED | MODEL_AT | MODEL_HAS_IDE, 512, 8192, 128, - at_headland_init, NULL}; -MODEL m_ami386 = - {"[386SX] AMI 386SX clone", ROM_AMI386SX, "ami386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_NONE | MODEL_AT | MODEL_HAS_IDE, 512, 16384, 128, - at_headland_init, NULL}; -MODEL m_megapc = - {"[386SX] Amstrad MegaPC", ROM_MEGAPC, "megapc", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_DISABLE_HW | MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, - at_wd76c10_init, NULL}; -MODEL m_cbm_sl386sx25 = {"[386SX] Commodore SL386SX-25", ROM_CBM_SL386SX25, "cbm_sl386sx25", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, - MODEL_GFX_FIXED | MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1024, 16384, 512, at_scamp_init, NULL}; -MODEL m_dtk386 = {"[386SX] DTK 386SX clone", ROM_DTK386, "dtk386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_NONE | MODEL_AT | MODEL_HAS_IDE, 512, 16384, 128, - at_neat_init, NULL}; -MODEL m_epson_pcax3 = - {"[386SX] Epson PC AX3", ROM_EPSON_PCAX3, "epson_pcax3", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_NONE | MODEL_AT, 256, 15872, 128, at_init, NULL}; -MODEL m_ibmps1_2121 = - {"[386SX] IBM PS/1 model 2121", ROM_IBMPS1_2121, "ibmps1_2121", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_FIXED | MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, - 1, 16, 1, ps1_m2121_init, NULL}; -MODEL m_ibmps2_m55sx = {"[386SX] IBM PS/2 Model 55SX", ROM_IBMPS2_M55SX, "ibmps2_m55sx", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, - MODEL_GFX_DISABLE_SW | MODEL_AT | MODEL_PS2 | MODEL_MCA, 1, 8, 1, ps2_model_55sx_init, NULL}; -MODEL m_kmxc02 = {"[386SX] KMX-C-02", ROM_KMXC02, "kmxc02", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_NONE | MODEL_AT, 512, 16384, 512, at_scatsx_init, NULL}; -MODEL m_pb_l300sx = {"[386SX] Packard Bell Legend 300SX", ROM_PB_L300SX, "pb_l300sx", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, - MODEL_GFX_NONE | MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, pb_l300sx_init, NULL}; -MODEL m_spc6033p = - {"[386SX] Samsung SPC-6033P", ROM_SPC6033P, "spc6033p", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, MODEL_GFX_DISABLE_HW | MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 2, - 12, 2, at_scamp_init, NULL}; +MODEL m_acer386 = {"[386SX] Acer 386SX25/N", + ROM_ACER386, + "acer386", + {{"Intel", cpus_acer}, {"", NULL}, {"", NULL}}, + MODEL_GFX_DISABLE_SW | MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, + 1, + 16, + 1, + at_acer386sx_init, + NULL}; +MODEL m_ama932j = {"[386SX] AMA-932J", + ROM_AMA932J, + "ama932j", + {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, + MODEL_GFX_FIXED | MODEL_AT | MODEL_HAS_IDE, + 512, + 8192, + 128, + at_headland_init, + NULL}; +MODEL m_ami386 = {"[386SX] AMI 386SX clone", + ROM_AMI386SX, + "ami386", + {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, + MODEL_GFX_NONE | MODEL_AT | MODEL_HAS_IDE, + 512, + 16384, + 128, + at_headland_init, + NULL}; +MODEL m_megapc = {"[386SX] Amstrad MegaPC", + ROM_MEGAPC, + "megapc", + {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, + MODEL_GFX_DISABLE_HW | MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, + 1, + 16, + 1, + at_wd76c10_init, + NULL}; +MODEL m_cbm_sl386sx25 = {"[386SX] Commodore SL386SX-25", + ROM_CBM_SL386SX25, + "cbm_sl386sx25", + {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, + MODEL_GFX_FIXED | MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, + 1024, + 16384, + 512, + at_scamp_init, + NULL}; +MODEL m_dtk386 = {"[386SX] DTK 386SX clone", + ROM_DTK386, + "dtk386", + {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, + MODEL_GFX_NONE | MODEL_AT | MODEL_HAS_IDE, + 512, + 16384, + 128, + at_neat_init, + NULL}; +MODEL m_epson_pcax3 = {"[386SX] Epson PC AX3", + ROM_EPSON_PCAX3, + "epson_pcax3", + {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, + MODEL_GFX_NONE | MODEL_AT, + 256, + 15872, + 128, + at_init, + NULL}; +MODEL m_ibmps1_2121 = {"[386SX] IBM PS/1 model 2121", + ROM_IBMPS1_2121, + "ibmps1_2121", + {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, + MODEL_GFX_FIXED | MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, + 1, + 16, + 1, + ps1_m2121_init, + NULL}; +MODEL m_ibmps2_m55sx = {"[386SX] IBM PS/2 Model 55SX", + ROM_IBMPS2_M55SX, + "ibmps2_m55sx", + {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, + MODEL_GFX_DISABLE_SW | MODEL_AT | MODEL_PS2 | MODEL_MCA, + 1, + 8, + 1, + ps2_model_55sx_init, + NULL}; +MODEL m_kmxc02 = {"[386SX] KMX-C-02", + ROM_KMXC02, + "kmxc02", + {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, + MODEL_GFX_NONE | MODEL_AT, + 512, + 16384, + 512, + at_scatsx_init, + NULL}; +MODEL m_pb_l300sx = {"[386SX] Packard Bell Legend 300SX", + ROM_PB_L300SX, + "pb_l300sx", + {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, + MODEL_GFX_NONE | MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, + 1, + 16, + 1, + pb_l300sx_init, + NULL}; +MODEL m_spc6033p = {"[386SX] Samsung SPC-6033P", + ROM_SPC6033P, + "spc6033p", + {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}}, + MODEL_GFX_DISABLE_HW | MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, + 2, + 12, + 2, + at_scamp_init, + NULL}; /* 386DX PC's */ -MODEL m_ami386dx = - {"[386DX] AMI 386DX clone", ROM_AMI386DX_OPTI495, "ami386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, MODEL_GFX_NONE | MODEL_AT | MODEL_HAS_IDE, 1, 256, 1, - at_opti495_init, NULL}; -MODEL m_deskpro386 = - {"[386DX] Compaq Deskpro 386", ROM_DESKPRO_386, "deskpro386", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, MODEL_GFX_NONE | MODEL_AT, 1, 15, 1, deskpro386_init, - NULL}; -MODEL m_ecs_386_32 = - {"[386DX] ECS 386/32", ROM_ECS_386_32, "ecs_386_32", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, MODEL_GFX_NONE | MODEL_AT, 1, 16, 1, at_cs8230_init, NULL}; -MODEL m_ibmps2_m70_type3 = {"[386DX] IBM PS/2 Model 70 (type 3)", ROM_IBMPS2_M70_TYPE3, "ibmps2_m70_type3", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, - MODEL_GFX_DISABLE_SW | MODEL_AT | MODEL_PS2 | MODEL_MCA, 2, 16, 2, ps2_model_70_init, NULL}; -MODEL m_ibmps2_m80 = - {"[386DX] IBM PS/2 Model 80", ROM_IBMPS2_M80, "ibmps2_m80", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, MODEL_GFX_DISABLE_SW | MODEL_AT | MODEL_PS2 | MODEL_MCA, 1, - 12, 1, ps2_model_80_init, NULL}; -MODEL m_mr386dx = - {"[386DX] MR 386DX clone", ROM_MR386DX_OPTI495, "mr386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, MODEL_GFX_NONE | MODEL_AT | MODEL_HAS_IDE, 1, 256, 1, - at_opti495_init, NULL}; -MODEL m_spc6000a = {"[386DX] Samsung SPC-6000A", ROM_SPC6000A, "spc6000a", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, MODEL_GFX_NONE | MODEL_AT | MODEL_HAS_IDE, 1, 32, 1, - at_cs8230_init, NULL}; +MODEL m_ami386dx = {"[386DX] AMI 386DX clone", + ROM_AMI386DX_OPTI495, + "ami386dx", + {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, + MODEL_GFX_NONE | MODEL_AT | MODEL_HAS_IDE, + 1, + 256, + 1, + at_opti495_init, + NULL}; +MODEL m_deskpro386 = {"[386DX] Compaq Deskpro 386", + ROM_DESKPRO_386, + "deskpro386", + {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, + MODEL_GFX_NONE | MODEL_AT, + 1, + 15, + 1, + deskpro386_init, + NULL}; +MODEL m_ecs_386_32 = {"[386DX] ECS 386/32", + ROM_ECS_386_32, + "ecs_386_32", + {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, + MODEL_GFX_NONE | MODEL_AT, + 1, + 16, + 1, + at_cs8230_init, + NULL}; +MODEL m_ibmps2_m70_type3 = {"[386DX] IBM PS/2 Model 70 (type 3)", + ROM_IBMPS2_M70_TYPE3, + "ibmps2_m70_type3", + {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, + MODEL_GFX_DISABLE_SW | MODEL_AT | MODEL_PS2 | MODEL_MCA, + 2, + 16, + 2, + ps2_model_70_init, + NULL}; +MODEL m_ibmps2_m80 = {"[386DX] IBM PS/2 Model 80", + ROM_IBMPS2_M80, + "ibmps2_m80", + {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, + MODEL_GFX_DISABLE_SW | MODEL_AT | MODEL_PS2 | MODEL_MCA, + 1, + 12, + 1, + ps2_model_80_init, + NULL}; +MODEL m_mr386dx = {"[386DX] MR 386DX clone", + ROM_MR386DX_OPTI495, + "mr386dx", + {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, + MODEL_GFX_NONE | MODEL_AT | MODEL_HAS_IDE, + 1, + 256, + 1, + at_opti495_init, + NULL}; +MODEL m_spc6000a = {"[386DX] Samsung SPC-6000A", + ROM_SPC6000A, + "spc6000a", + {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}}, + MODEL_GFX_NONE | MODEL_AT | MODEL_HAS_IDE, + 1, + 32, + 1, + at_cs8230_init, + NULL}; /* 486 PC's */ -MODEL m_ami486 = - {"[486] AMI 486 clone", ROM_AMI486, "ami486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, MODEL_GFX_NONE | MODEL_AT | MODEL_HAS_IDE, 1, 256, 1, at_ali1429_init, NULL}; -MODEL m_win486 = - {"[486] AMI WinBIOS 486", ROM_WIN486, "win486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, MODEL_GFX_NONE | MODEL_AT | MODEL_HAS_IDE, 1, 256, 1, at_ali1429_init, - NULL}; -MODEL m_sis496 = {"[486] Award SiS 496/497", ROM_SIS496, "sis496", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, MODEL_GFX_NONE | MODEL_AT | MODEL_PCI | MODEL_HAS_IDE, 1, 256, 1, - at_sis496_init, NULL}; -MODEL m_elx_pc425x = {"[486] Elonex PC-425X", ROM_ELX_PC425X, "elx_pc425x", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, MODEL_GFX_FIXED | MODEL_AT | MODEL_HAS_IDE, 1, 256, 1, - at_sl82c460_init, NULL}; -MODEL m_ibmps1_2133 = - {"[486] IBM PS/1 Model 2133 (EMEA 451)", ROM_IBMPS1_2133_451, "ibmps1_2133", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, MODEL_GFX_FIXED | MODEL_AT | MODEL_PS2, 2, 64, - 2, ps1_m2133_init, NULL}; -MODEL m_ibmps2_m70_type4 = {"[486] IBM PS/2 Model 70 (type 4)", ROM_IBMPS2_M70_TYPE4, "ibmps2_m70_type4", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, - MODEL_GFX_DISABLE_SW | MODEL_AT | MODEL_PS2 | MODEL_MCA, 2, 16, 2, ps2_model_70_init, NULL}; -MODEL m_pb410a = - {"[486] Packard Bell PB410A", ROM_PB410A, "pb410a", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, MODEL_GFX_DISABLE_SW | MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 64, 1, - at_pb410a_init, NULL}; +MODEL m_ami486 = {"[486] AMI 486 clone", + ROM_AMI486, + "ami486", + {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, + MODEL_GFX_NONE | MODEL_AT | MODEL_HAS_IDE, + 1, + 256, + 1, + at_ali1429_init, + NULL}; +MODEL m_win486 = {"[486] AMI WinBIOS 486", + ROM_WIN486, + "win486", + {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, + MODEL_GFX_NONE | MODEL_AT | MODEL_HAS_IDE, + 1, + 256, + 1, + at_ali1429_init, + NULL}; +MODEL m_sis496 = {"[486] Award SiS 496/497", + ROM_SIS496, + "sis496", + {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, + MODEL_GFX_NONE | MODEL_AT | MODEL_PCI | MODEL_HAS_IDE, + 1, + 256, + 1, + at_sis496_init, + NULL}; +MODEL m_elx_pc425x = {"[486] Elonex PC-425X", + ROM_ELX_PC425X, + "elx_pc425x", + {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, + MODEL_GFX_FIXED | MODEL_AT | MODEL_HAS_IDE, + 1, + 256, + 1, + at_sl82c460_init, + NULL}; +MODEL m_ibmps1_2133 = {"[486] IBM PS/1 Model 2133 (EMEA 451)", + ROM_IBMPS1_2133_451, + "ibmps1_2133", + {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, + MODEL_GFX_FIXED | MODEL_AT | MODEL_PS2, + 2, + 64, + 2, + ps1_m2133_init, + NULL}; +MODEL m_ibmps2_m70_type4 = {"[486] IBM PS/2 Model 70 (type 4)", + ROM_IBMPS2_M70_TYPE4, + "ibmps2_m70_type4", + {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, + MODEL_GFX_DISABLE_SW | MODEL_AT | MODEL_PS2 | MODEL_MCA, + 2, + 16, + 2, + ps2_model_70_init, + NULL}; +MODEL m_pb410a = {"[486] Packard Bell PB410A", + ROM_PB410A, + "pb410a", + {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}}, + MODEL_GFX_DISABLE_SW | MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, + 1, + 64, + 1, + at_pb410a_init, + NULL}; /* Socket 4 PC's */ -MODEL m_revenge = - {"[Socket 4] Intel Premiere/PCI", ROM_REVENGE, "revenge", {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}}, MODEL_GFX_NONE | MODEL_AT | MODEL_PCI | MODEL_PS2 | MODEL_HAS_IDE, 1, 128, 1, - at_batman_init, NULL}; -MODEL m_pb520r = - {"[Socket 4] Packard Bell PB520R", ROM_PB520R, "pb520r", {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}}, MODEL_GFX_DISABLE_SW | MODEL_AT | MODEL_PCI | MODEL_PS2 | MODEL_HAS_IDE, 1, 128, - 1, at_pb520r_init, NULL}; +MODEL m_revenge = {"[Socket 4] Intel Premiere/PCI", + ROM_REVENGE, + "revenge", + {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}}, + MODEL_GFX_NONE | MODEL_AT | MODEL_PCI | MODEL_PS2 | MODEL_HAS_IDE, + 1, + 128, + 1, + at_batman_init, + NULL}; +MODEL m_pb520r = {"[Socket 4] Packard Bell PB520R", + ROM_PB520R, + "pb520r", + {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}}, + MODEL_GFX_DISABLE_SW | MODEL_AT | MODEL_PCI | MODEL_PS2 | MODEL_HAS_IDE, + 1, + 128, + 1, + at_pb520r_init, + NULL}; /* Socket 5 PC's */ -MODEL m_endeavor = - {"[Socket 5] Intel Advanced/EV", ROM_ENDEAVOR, "endeavor", {{"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"", NULL}}, MODEL_GFX_NONE | MODEL_AT | MODEL_PCI | MODEL_PS2 | MODEL_HAS_IDE, 1, - 128, 1, at_endeavor_init, NULL}; -MODEL m_zappa = - {"[Socket 5] Intel Advanced/ZP", ROM_ZAPPA, "zappa", {{"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"", NULL}}, MODEL_GFX_NONE | MODEL_AT | MODEL_PCI | MODEL_PS2 | MODEL_HAS_IDE, 1, 128, - 1, at_zappa_init, NULL}; -MODEL m_infowaym = {"[Socket 5] Itautec Infoway Multimidia", ROM_ITAUTEC_INFOWAYM, "infowaym", {{"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"", NULL}}, - MODEL_GFX_NONE | MODEL_AT | MODEL_PCI | MODEL_PS2 | MODEL_HAS_IDE, 8, 128, 1, at_zappa_init, NULL}; -MODEL m_pb570 = - {"[Socket 5] Packard Bell PB570", ROM_PB570, "pb570", {{"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"", NULL}}, MODEL_GFX_DISABLE_SW | MODEL_AT | MODEL_PCI | MODEL_PS2 | MODEL_HAS_IDE, - 1, 128, 1, at_pb570_init, NULL}; +MODEL m_endeavor = {"[Socket 5] Intel Advanced/EV", + ROM_ENDEAVOR, + "endeavor", + {{"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"", NULL}}, + MODEL_GFX_NONE | MODEL_AT | MODEL_PCI | MODEL_PS2 | MODEL_HAS_IDE, + 1, + 128, + 1, + at_endeavor_init, + NULL}; +MODEL m_zappa = {"[Socket 5] Intel Advanced/ZP", + ROM_ZAPPA, + "zappa", + {{"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"", NULL}}, + MODEL_GFX_NONE | MODEL_AT | MODEL_PCI | MODEL_PS2 | MODEL_HAS_IDE, + 1, + 128, + 1, + at_zappa_init, + NULL}; +MODEL m_infowaym = {"[Socket 5] Itautec Infoway Multimidia", + ROM_ITAUTEC_INFOWAYM, + "infowaym", + {{"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"", NULL}}, + MODEL_GFX_NONE | MODEL_AT | MODEL_PCI | MODEL_PS2 | MODEL_HAS_IDE, + 8, + 128, + 1, + at_zappa_init, + NULL}; +MODEL m_pb570 = {"[Socket 5] Packard Bell PB570", + ROM_PB570, + "pb570", + {{"Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"", NULL}}, + MODEL_GFX_DISABLE_SW | MODEL_AT | MODEL_PCI | MODEL_PS2 | MODEL_HAS_IDE, + 1, + 128, + 1, + at_pb570_init, + NULL}; /* Socket 7 PC's */ -MODEL m_p55tvp4 = {"[Socket 7] ASUS P/I-P55TVP4", ROM_P55TVP4, "p55tvp4", {{"Intel", cpus_Pentium}, {"AMD", cpus_K6_S7}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, - MODEL_GFX_NONE | MODEL_AT | MODEL_PCI | MODEL_PS2 | MODEL_HAS_IDE, 8, 128, 1, at_p55tvp4_init, NULL}; -MODEL m_p55t2p4 = {"[Socket 7] ASUS P/I-P55T2P4", ROM_P55T2P4, "p55t2p4", {{"Intel", cpus_Pentium}, {"AMD", cpus_K6_S7}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, - MODEL_GFX_NONE | MODEL_AT | MODEL_PCI | MODEL_PS2 | MODEL_HAS_IDE, 8, 256, 1, at_p55t2p4_init, NULL}; -MODEL m_p55va = {"[Socket 7] Epox P55-VA", ROM_P55VA, "p55va", {{"Intel", cpus_Pentium}, {"AMD", cpus_K6_S7}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, - MODEL_GFX_NONE | MODEL_AT | MODEL_PCI | MODEL_PS2 | MODEL_HAS_IDE, 8, 128, 1, at_p55va_init, NULL}; -MODEL m_430vx = {"[Socket 7] Shuttle HOT-557", ROM_430VX, "430vx", {{"Intel", cpus_Pentium}, {"AMD", cpus_K6_S7}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, - MODEL_GFX_NONE | MODEL_AT | MODEL_PCI | MODEL_PS2 | MODEL_HAS_IDE, 8, 128, 1, at_i430vx_init, NULL}; +MODEL m_p55tvp4 = {"[Socket 7] ASUS P/I-P55TVP4", + ROM_P55TVP4, + "p55tvp4", + {{"Intel", cpus_Pentium}, {"AMD", cpus_K6_S7}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, + MODEL_GFX_NONE | MODEL_AT | MODEL_PCI | MODEL_PS2 | MODEL_HAS_IDE, + 8, + 128, + 1, + at_p55tvp4_init, + NULL}; +MODEL m_p55t2p4 = {"[Socket 7] ASUS P/I-P55T2P4", + ROM_P55T2P4, + "p55t2p4", + {{"Intel", cpus_Pentium}, {"AMD", cpus_K6_S7}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, + MODEL_GFX_NONE | MODEL_AT | MODEL_PCI | MODEL_PS2 | MODEL_HAS_IDE, + 8, + 256, + 1, + at_p55t2p4_init, + NULL}; +MODEL m_p55va = {"[Socket 7] Epox P55-VA", + ROM_P55VA, + "p55va", + {{"Intel", cpus_Pentium}, {"AMD", cpus_K6_S7}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, + MODEL_GFX_NONE | MODEL_AT | MODEL_PCI | MODEL_PS2 | MODEL_HAS_IDE, + 8, + 128, + 1, + at_p55va_init, + NULL}; +MODEL m_430vx = {"[Socket 7] Shuttle HOT-557", + ROM_430VX, + "430vx", + {{"Intel", cpus_Pentium}, {"AMD", cpus_K6_S7}, {"IDT", cpus_WinChip}, {"Cyrix", cpus_6x86}}, + MODEL_GFX_NONE | MODEL_AT | MODEL_PCI | MODEL_PS2 | MODEL_HAS_IDE, + 8, + 128, + 1, + at_i430vx_init, + NULL}; /* Super 7 PC's */ -MODEL m_fic_va503p = {"[Super 7] FIC VA-503+", ROM_FIC_VA503P, "fic_va503p", {{"Intel", cpus_Pentium}, {"AMD", cpus_K6_SS7}, {"IDT", cpus_WinChip_SS7}, {"Cyrix", cpus_6x86_SS7}}, - MODEL_GFX_NONE | MODEL_AT | MODEL_PCI | MODEL_PS2 | MODEL_HAS_IDE, 1, 512, 1, at_mvp3_init, NULL}; +MODEL m_fic_va503p = {"[Super 7] FIC VA-503+", + ROM_FIC_VA503P, + "fic_va503p", + {{"Intel", cpus_Pentium}, {"AMD", cpus_K6_SS7}, {"IDT", cpus_WinChip_SS7}, {"Cyrix", cpus_6x86_SS7}}, + MODEL_GFX_NONE | MODEL_AT | MODEL_PCI | MODEL_PS2 | MODEL_HAS_IDE, + 1, + 512, + 1, + at_mvp3_init, + NULL}; /* Socket 8 PC's */ -MODEL m_vs440fx = - {"[Socket 8] Intel VS440FX", ROM_VS440FX, "vs440fx", {{"Intel", cpus_PentiumPro}}, MODEL_GFX_NONE | MODEL_AT | MODEL_PCI | MODEL_PS2 | MODEL_HAS_IDE, 8, 256, 8, at_vs440fx_init, NULL}; +MODEL m_vs440fx = {"[Socket 8] Intel VS440FX", + ROM_VS440FX, + "vs440fx", + {{"Intel", cpus_PentiumPro}}, + MODEL_GFX_NONE | MODEL_AT | MODEL_PCI | MODEL_PS2 | MODEL_HAS_IDE, + 8, + 256, + 8, + at_vs440fx_init, + NULL}; /* Slot 1 PC's */ -MODEL m_ga686bx = - {"[Slot 1] Gigabyte GA-686BX", ROM_GA686BX, "ga686bx", {{"Intel", cpus_Slot1_100MHz}, {"VIA", cpus_VIA_100MHz}}, MODEL_GFX_NONE | MODEL_AT | MODEL_PCI | MODEL_PS2 | MODEL_HAS_IDE, 8, 512, 8, - at_ga686bx_init, NULL}; +MODEL m_ga686bx = {"[Slot 1] Gigabyte GA-686BX", + ROM_GA686BX, + "ga686bx", + {{"Intel", cpus_Slot1_100MHz}, {"VIA", cpus_VIA_100MHz}}, + MODEL_GFX_NONE | MODEL_AT | MODEL_PCI | MODEL_PS2 | MODEL_HAS_IDE, + 8, + 512, + 8, + at_ga686bx_init, + NULL}; void model_init_builtin() { - /* 8088 PC's */ - pcem_add_model(&m_amixt); - pcem_add_model(&m_ataripc3); - pcem_add_model(&m_cbm_pc10); - pcem_add_model(&m_compaq_pip); - pcem_add_model(&m_dtk); - pcem_add_model(&m_genxt); - pcem_add_model(&m_hyundaixt); - pcem_add_model(&m_hyundaixte); - pcem_add_model(&m_ibmpc); - pcem_add_model(&m_ibmpcjr); - pcem_add_model(&m_ibmxt); - pcem_add_model(&m_jukopc); - pcem_add_model(&m_ledge_modelm); - pcem_add_model(&m_ncr_pc4i); - pcem_add_model(&m_pxxt); - pcem_add_model(&m_europc); - pcem_add_model(&m_tandy); - pcem_add_model(&m_tandy1000hx); - pcem_add_model(&m_to16_pc); - pcem_add_model(&m_t1000); - pcem_add_model(&m_ltxt); - pcem_add_model(&m_xi8088); - pcem_add_model(&m_zdsupers); + /* 8088 PC's */ + pcem_add_model(&m_amixt); + pcem_add_model(&m_ataripc3); + pcem_add_model(&m_cbm_pc10); + pcem_add_model(&m_compaq_pip); + pcem_add_model(&m_dtk); + pcem_add_model(&m_genxt); + pcem_add_model(&m_hyundaixt); + pcem_add_model(&m_hyundaixte); + pcem_add_model(&m_ibmpc); + pcem_add_model(&m_ibmpcjr); + pcem_add_model(&m_ibmxt); + pcem_add_model(&m_jukopc); + pcem_add_model(&m_ledge_modelm); + pcem_add_model(&m_ncr_pc4i); + pcem_add_model(&m_pxxt); + pcem_add_model(&m_europc); + pcem_add_model(&m_tandy); + pcem_add_model(&m_tandy1000hx); + pcem_add_model(&m_to16_pc); + pcem_add_model(&m_t1000); + pcem_add_model(&m_ltxt); + pcem_add_model(&m_xi8088); + pcem_add_model(&m_zdsupers); - /* 8086 PC's */ - pcem_add_model(&m_pc1512); - pcem_add_model(&m_pc1640); - pcem_add_model(&m_pc2086); - pcem_add_model(&m_pc3086); - pcem_add_model(&m_pc5086); - pcem_add_model(&m_ppc512); - pcem_add_model(&m_deskpro); - pcem_add_model(&m_olivetti_m24); - pcem_add_model(&m_pc200); - pcem_add_model(&m_tandy1000sl2); - pcem_add_model(&m_t1200); - pcem_add_model(&m_lxt3); + /* 8086 PC's */ + pcem_add_model(&m_pc1512); + pcem_add_model(&m_pc1640); + pcem_add_model(&m_pc2086); + pcem_add_model(&m_pc3086); + pcem_add_model(&m_pc5086); + pcem_add_model(&m_ppc512); + pcem_add_model(&m_deskpro); + pcem_add_model(&m_olivetti_m24); + pcem_add_model(&m_pc200); + pcem_add_model(&m_tandy1000sl2); + pcem_add_model(&m_t1200); + pcem_add_model(&m_lxt3); - /* 286 PC's */ - pcem_add_model(&m_ami286); - pcem_add_model(&m_award286); - pcem_add_model(&m_bull_micral_45); - pcem_add_model(&m_cmdpc30); - pcem_add_model(&m_compaq_pii); - pcem_add_model(&m_dells200); - pcem_add_model(&m_epson_pcax); - pcem_add_model(&m_epson_pcax2e); - pcem_add_model(&m_gdc212m); - pcem_add_model(&m_gw286ct); - pcem_add_model(&m_super286tr); - pcem_add_model(&m_ibmat); - pcem_add_model(&m_ibmps1es); - pcem_add_model(&m_ibmps2_m30_286); - pcem_add_model(&m_ibmps2_m50); - pcem_add_model(&m_ibmxt286); - pcem_add_model(&m_spc4200p); - pcem_add_model(&m_spc4216p); - pcem_add_model(&m_spc4620p); - pcem_add_model(&m_t3100e); - pcem_add_model(&m_tg286m); - pcem_add_model(&m_tulip_tc7); + /* 286 PC's */ + pcem_add_model(&m_ami286); + pcem_add_model(&m_award286); + pcem_add_model(&m_bull_micral_45); + pcem_add_model(&m_cmdpc30); + pcem_add_model(&m_compaq_pii); + pcem_add_model(&m_dells200); + pcem_add_model(&m_epson_pcax); + pcem_add_model(&m_epson_pcax2e); + pcem_add_model(&m_gdc212m); + pcem_add_model(&m_gw286ct); + pcem_add_model(&m_super286tr); + pcem_add_model(&m_ibmat); + pcem_add_model(&m_ibmps1es); + pcem_add_model(&m_ibmps2_m30_286); + pcem_add_model(&m_ibmps2_m50); + pcem_add_model(&m_ibmxt286); + pcem_add_model(&m_spc4200p); + pcem_add_model(&m_spc4216p); + pcem_add_model(&m_spc4620p); + pcem_add_model(&m_t3100e); + pcem_add_model(&m_tg286m); + pcem_add_model(&m_tulip_tc7); - /* 386SX PC's */ - pcem_add_model(&m_acer386); - pcem_add_model(&m_ama932j); - pcem_add_model(&m_ami386); - pcem_add_model(&m_megapc); - pcem_add_model(&m_cbm_sl386sx25); - pcem_add_model(&m_dtk386); - pcem_add_model(&m_epson_pcax3); - pcem_add_model(&m_ibmps1_2121); - pcem_add_model(&m_ibmps2_m55sx); - pcem_add_model(&m_kmxc02); - pcem_add_model(&m_pb_l300sx); - pcem_add_model(&m_spc6033p); + /* 386SX PC's */ + pcem_add_model(&m_acer386); + pcem_add_model(&m_ama932j); + pcem_add_model(&m_ami386); + pcem_add_model(&m_megapc); + pcem_add_model(&m_cbm_sl386sx25); + pcem_add_model(&m_dtk386); + pcem_add_model(&m_epson_pcax3); + pcem_add_model(&m_ibmps1_2121); + pcem_add_model(&m_ibmps2_m55sx); + pcem_add_model(&m_kmxc02); + pcem_add_model(&m_pb_l300sx); + pcem_add_model(&m_spc6033p); - /* 386DX PC's */ - pcem_add_model(&m_ami386dx); - pcem_add_model(&m_deskpro386); - pcem_add_model(&m_ecs_386_32); - pcem_add_model(&m_ibmps2_m70_type3); - pcem_add_model(&m_ibmps2_m80); - pcem_add_model(&m_mr386dx); - pcem_add_model(&m_spc6000a); + /* 386DX PC's */ + pcem_add_model(&m_ami386dx); + pcem_add_model(&m_deskpro386); + pcem_add_model(&m_ecs_386_32); + pcem_add_model(&m_ibmps2_m70_type3); + pcem_add_model(&m_ibmps2_m80); + pcem_add_model(&m_mr386dx); + pcem_add_model(&m_spc6000a); - /* 486 PC's */ - pcem_add_model(&m_ami486); - pcem_add_model(&m_win486); - pcem_add_model(&m_sis496); - pcem_add_model(&m_elx_pc425x); - pcem_add_model(&m_ibmps1_2133); - pcem_add_model(&m_ibmps2_m70_type4); - pcem_add_model(&m_pb410a); + /* 486 PC's */ + pcem_add_model(&m_ami486); + pcem_add_model(&m_win486); + pcem_add_model(&m_sis496); + pcem_add_model(&m_elx_pc425x); + pcem_add_model(&m_ibmps1_2133); + pcem_add_model(&m_ibmps2_m70_type4); + pcem_add_model(&m_pb410a); - /* Socket 4 PC's */ - pcem_add_model(&m_revenge); - pcem_add_model(&m_pb520r); + /* Socket 4 PC's */ + pcem_add_model(&m_revenge); + pcem_add_model(&m_pb520r); - /* Socket 5 PC's */ - pcem_add_model(&m_endeavor); - pcem_add_model(&m_zappa); - pcem_add_model(&m_infowaym); - pcem_add_model(&m_pb570); + /* Socket 5 PC's */ + pcem_add_model(&m_endeavor); + pcem_add_model(&m_zappa); + pcem_add_model(&m_infowaym); + pcem_add_model(&m_pb570); - /* Socket 7 PC's */ - pcem_add_model(&m_p55tvp4); - pcem_add_model(&m_p55t2p4); - pcem_add_model(&m_p55va); - pcem_add_model(&m_430vx); + /* Socket 7 PC's */ + pcem_add_model(&m_p55tvp4); + pcem_add_model(&m_p55t2p4); + pcem_add_model(&m_p55va); + pcem_add_model(&m_430vx); - /* Super 7 PC's */ - pcem_add_model(&m_fic_va503p); + /* Super 7 PC's */ + pcem_add_model(&m_fic_va503p); - /* Socket 8 PC's */ - pcem_add_model(&m_vs440fx); + /* Socket 8 PC's */ + pcem_add_model(&m_vs440fx); - /* Slot 1 PC's */ - pcem_add_model(&m_ga686bx); + /* Slot 1 PC's */ + pcem_add_model(&m_ga686bx); } diff --git a/src/models/mvp3.c b/src/models/mvp3.c index e00962cc..19924735 100644 --- a/src/models/mvp3.c +++ b/src/models/mvp3.c @@ -8,216 +8,218 @@ #include "mvp3.h" static struct { - uint8_t host_bridge_regs[256]; - uint8_t pci_bridge_regs[256]; + uint8_t host_bridge_regs[256]; + uint8_t pci_bridge_regs[256]; } mvp3; static void mvp3_map(uint32_t addr, uint32_t size, int state) { - pclog("mvp3_map: addr=%08x size=%08x state=%i\n", addr, size, 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_EXTERNAL | MEM_WRITE_INTERNAL); - break; - case 2:mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); - break; - case 3:mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - break; - } - flushmmucache_nopc(); + pclog("mvp3_map: addr=%08x size=%08x state=%i\n", addr, size, 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_EXTERNAL | MEM_WRITE_INTERNAL); + break; + case 2: + mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); + break; + case 3: + mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + break; + } + flushmmucache_nopc(); } static uint8_t mvp3_read(int func, int addr, void *priv) { - switch (func) { - case 0:return mvp3.host_bridge_regs[addr]; + switch (func) { + case 0: + return mvp3.host_bridge_regs[addr]; - case 1:return mvp3.pci_bridge_regs[addr]; + case 1: + return mvp3.pci_bridge_regs[addr]; - default:return 0xff; - } + default: + return 0xff; + } } static void mvp3_host_bridge_write(int addr, uint8_t val) { - /*Read-only addresses*/ - if ((addr < 4) || (addr >= 5 && addr < 7) - || (addr >= 8 && addr < 0xd) - || (addr >= 0xe && addr < 0x12) - || (addr >= 0x14 && addr < 0x50) - || (addr >= 0x79 && addr < 0x7e) - || (addr >= 0x85 && addr < 0x88) - || (addr >= 0x8c && addr < 0xa8) - || (addr >= 0xad && addr < 0xfd)) - return; + /*Read-only addresses*/ + if ((addr < 4) || (addr >= 5 && addr < 7) || (addr >= 8 && addr < 0xd) || (addr >= 0xe && addr < 0x12) || + (addr >= 0x14 && addr < 0x50) || (addr >= 0x79 && addr < 0x7e) || (addr >= 0x85 && addr < 0x88) || + (addr >= 0x8c && addr < 0xa8) || (addr >= 0xad && addr < 0xfd)) + return; - switch (addr) { - case 0x04: /*Command*/ - mvp3.host_bridge_regs[0x04] = (mvp3.host_bridge_regs[0x04] & ~0x40) | (val & 0x40); - break; - case 0x07: /*Status*/ - mvp3.host_bridge_regs[0x07] &= ~(val & 0xb0); - break; + switch (addr) { + case 0x04: /*Command*/ + mvp3.host_bridge_regs[0x04] = (mvp3.host_bridge_regs[0x04] & ~0x40) | (val & 0x40); + break; + case 0x07: /*Status*/ + mvp3.host_bridge_regs[0x07] &= ~(val & 0xb0); + break; - case 0x12: /*Graphics Aperture Base*/ - mvp3.host_bridge_regs[0x12] = (val & 0xf0); - break; - case 0x13: /*Graphics Aperture Base*/ - mvp3.host_bridge_regs[0x13] = val; - break; + case 0x12: /*Graphics Aperture Base*/ + mvp3.host_bridge_regs[0x12] = (val & 0xf0); + break; + case 0x13: /*Graphics Aperture Base*/ + mvp3.host_bridge_regs[0x13] = val; + break; - case 0x61: /*Shadow RAM Control 1*/ - if ((mvp3.host_bridge_regs[0x61] ^ val) & 0x03) - mvp3_map(0xc0000, 0x04000, val & 0x03); - if ((mvp3.host_bridge_regs[0x61] ^ val) & 0x0c) - mvp3_map(0xc4000, 0x04000, (val & 0x0c) >> 2); - if ((mvp3.host_bridge_regs[0x61] ^ val) & 0x30) - mvp3_map(0xc8000, 0x04000, (val & 0x30) >> 4); - if ((mvp3.host_bridge_regs[0x61] ^ val) & 0xc0) - mvp3_map(0xcc000, 0x04000, (val & 0xc0) >> 6); - mvp3.host_bridge_regs[0x61] = val; - return; - case 0x62: /*Shadow RAM Control 2*/ - if ((mvp3.host_bridge_regs[0x62] ^ val) & 0x03) - mvp3_map(0xd0000, 0x04000, val & 0x03); - if ((mvp3.host_bridge_regs[0x62] ^ val) & 0x0c) - mvp3_map(0xd4000, 0x04000, (val & 0x0c) >> 2); - if ((mvp3.host_bridge_regs[0x62] ^ val) & 0x30) - mvp3_map(0xd8000, 0x04000, (val & 0x30) >> 4); - if ((mvp3.host_bridge_regs[0x62] ^ val) & 0xc0) - mvp3_map(0xdc000, 0x04000, (val & 0xc0) >> 6); - mvp3.host_bridge_regs[0x62] = val; - return; - case 0x63: /*Shadow RAM Control 3*/ - if ((mvp3.host_bridge_regs[0x63] ^ val) & 0x30) - mvp3_map(0xf0000, 0x10000, (val & 0x30) >> 4); - if ((mvp3.host_bridge_regs[0x63] ^ val) & 0xc0) - mvp3_map(0xe0000, 0x10000, (val & 0xc0) >> 6); - mvp3.host_bridge_regs[0x63] = val; - if ((val & 3) == 1 || ((val & 3) == 3 && (cpu_cur_status & CPU_STATUS_SMM))) /*SMRAM enabled*/ - { - pclog("Enable SMRAM\n"); - mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - } else { - pclog("Disable SMRAM\n"); - mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - } -// if (val == 0xb0) -// output = 3; - return; + case 0x61: /*Shadow RAM Control 1*/ + if ((mvp3.host_bridge_regs[0x61] ^ val) & 0x03) + mvp3_map(0xc0000, 0x04000, val & 0x03); + if ((mvp3.host_bridge_regs[0x61] ^ val) & 0x0c) + mvp3_map(0xc4000, 0x04000, (val & 0x0c) >> 2); + if ((mvp3.host_bridge_regs[0x61] ^ val) & 0x30) + mvp3_map(0xc8000, 0x04000, (val & 0x30) >> 4); + if ((mvp3.host_bridge_regs[0x61] ^ val) & 0xc0) + mvp3_map(0xcc000, 0x04000, (val & 0xc0) >> 6); + mvp3.host_bridge_regs[0x61] = val; + return; + case 0x62: /*Shadow RAM Control 2*/ + if ((mvp3.host_bridge_regs[0x62] ^ val) & 0x03) + mvp3_map(0xd0000, 0x04000, val & 0x03); + if ((mvp3.host_bridge_regs[0x62] ^ val) & 0x0c) + mvp3_map(0xd4000, 0x04000, (val & 0x0c) >> 2); + if ((mvp3.host_bridge_regs[0x62] ^ val) & 0x30) + mvp3_map(0xd8000, 0x04000, (val & 0x30) >> 4); + if ((mvp3.host_bridge_regs[0x62] ^ val) & 0xc0) + mvp3_map(0xdc000, 0x04000, (val & 0xc0) >> 6); + mvp3.host_bridge_regs[0x62] = val; + return; + case 0x63: /*Shadow RAM Control 3*/ + if ((mvp3.host_bridge_regs[0x63] ^ val) & 0x30) + mvp3_map(0xf0000, 0x10000, (val & 0x30) >> 4); + if ((mvp3.host_bridge_regs[0x63] ^ val) & 0xc0) + mvp3_map(0xe0000, 0x10000, (val & 0xc0) >> 6); + mvp3.host_bridge_regs[0x63] = val; + if ((val & 3) == 1 || ((val & 3) == 3 && (cpu_cur_status & CPU_STATUS_SMM))) /*SMRAM enabled*/ + { + pclog("Enable SMRAM\n"); + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } else { + pclog("Disable SMRAM\n"); + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + } + // if (val == 0xb0) + // output = 3; + return; - default:mvp3.host_bridge_regs[addr] = val; - break; - } + default: + mvp3.host_bridge_regs[addr] = val; + break; + } } static void mvp3_pci_bridge_write(int addr, uint8_t val) { - /*Read-only addresses*/ - if ((addr < 4) || (addr >= 5 && addr < 7) - || (addr >= 8 && addr < 0x18) - || (addr == 0x1b) - || (addr >= 0x1e && addr < 0x20) - || (addr >= 0x28 && addr < 0x3e) - || (addr >= 0x43)) - return; + /*Read-only addresses*/ + if ((addr < 4) || (addr >= 5 && addr < 7) || (addr >= 8 && addr < 0x18) || (addr == 0x1b) || + (addr >= 0x1e && addr < 0x20) || (addr >= 0x28 && addr < 0x3e) || (addr >= 0x43)) + return; - switch (addr) { - case 0x04: /*Command*/ - mvp3.pci_bridge_regs[0x04] = (mvp3.pci_bridge_regs[0x04] & ~0x47) | (val & 0x47); - break; - case 0x07: /*Status*/ - mvp3.pci_bridge_regs[0x07] &= ~(val & 0x30); - break; + switch (addr) { + case 0x04: /*Command*/ + mvp3.pci_bridge_regs[0x04] = (mvp3.pci_bridge_regs[0x04] & ~0x47) | (val & 0x47); + break; + case 0x07: /*Status*/ + mvp3.pci_bridge_regs[0x07] &= ~(val & 0x30); + break; - case 0x20: /*Memory Base*/ - mvp3.pci_bridge_regs[0x20] = val & 0xf0; - break; - case 0x22: /*Memory Limit*/ - mvp3.pci_bridge_regs[0x22] = val & 0xf0; - break; - case 0x24: /*Prefetchable Memory Base*/ - mvp3.pci_bridge_regs[0x24] = val & 0xf0; - break; - case 0x26: /*Prefetchable Memory Limit*/ - mvp3.pci_bridge_regs[0x26] = val & 0xf0; - break; + case 0x20: /*Memory Base*/ + mvp3.pci_bridge_regs[0x20] = val & 0xf0; + break; + case 0x22: /*Memory Limit*/ + mvp3.pci_bridge_regs[0x22] = val & 0xf0; + break; + case 0x24: /*Prefetchable Memory Base*/ + mvp3.pci_bridge_regs[0x24] = val & 0xf0; + break; + case 0x26: /*Prefetchable Memory Limit*/ + mvp3.pci_bridge_regs[0x26] = val & 0xf0; + break; - default:mvp3.pci_bridge_regs[addr] = val; - break; - } + default: + mvp3.pci_bridge_regs[addr] = val; + break; + } } static void mvp3_write(int func, int addr, uint8_t val, void *priv) { - switch (func) { - case 0:mvp3_host_bridge_write(addr, val); - break; + switch (func) { + case 0: + mvp3_host_bridge_write(addr, val); + break; - case 1:mvp3_pci_bridge_write(addr, val); - break; - } + case 1: + mvp3_pci_bridge_write(addr, val); + break; + } } static void mvp3_smram_enable(void) { - if ((mvp3.host_bridge_regs[0x63] & 3) == 3) - mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + if ((mvp3.host_bridge_regs[0x63] & 3) == 3) + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); } static void mvp3_smram_disable(void) { - if ((mvp3.host_bridge_regs[0x63] & 3) != 1) - mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + if ((mvp3.host_bridge_regs[0x63] & 3) != 1) + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); } void mvp3_init() { - pci_add_specific(0, mvp3_read, mvp3_write, NULL); + pci_add_specific(0, mvp3_read, mvp3_write, NULL); - memset(&mvp3, 0, sizeof(mvp3)); - mvp3.host_bridge_regs[0x00] = 0x06; - mvp3.host_bridge_regs[0x01] = 0x11; /*VIA*/ - mvp3.host_bridge_regs[0x02] = 0x98; - mvp3.host_bridge_regs[0x03] = 0x05; /*VT82C598MVP*/ - mvp3.host_bridge_regs[0x04] = 0x06; - mvp3.host_bridge_regs[0x05] = 0x00; - mvp3.host_bridge_regs[0x06] = 0x90; - mvp3.host_bridge_regs[0x07] = 0x02; - mvp3.host_bridge_regs[0x0b] = 0x06; - mvp3.host_bridge_regs[0x10] = 0x08; - mvp3.host_bridge_regs[0x34] = 0xa0; + memset(&mvp3, 0, sizeof(mvp3)); + mvp3.host_bridge_regs[0x00] = 0x06; + mvp3.host_bridge_regs[0x01] = 0x11; /*VIA*/ + mvp3.host_bridge_regs[0x02] = 0x98; + mvp3.host_bridge_regs[0x03] = 0x05; /*VT82C598MVP*/ + mvp3.host_bridge_regs[0x04] = 0x06; + mvp3.host_bridge_regs[0x05] = 0x00; + mvp3.host_bridge_regs[0x06] = 0x90; + mvp3.host_bridge_regs[0x07] = 0x02; + mvp3.host_bridge_regs[0x0b] = 0x06; + mvp3.host_bridge_regs[0x10] = 0x08; + mvp3.host_bridge_regs[0x34] = 0xa0; - mvp3.host_bridge_regs[0x5a] = 0x01; - mvp3.host_bridge_regs[0x5b] = 0x01; - mvp3.host_bridge_regs[0x5c] = 0x01; - mvp3.host_bridge_regs[0x5d] = 0x01; - mvp3.host_bridge_regs[0x5e] = 0x01; - mvp3.host_bridge_regs[0x5f] = 0x01; + mvp3.host_bridge_regs[0x5a] = 0x01; + mvp3.host_bridge_regs[0x5b] = 0x01; + mvp3.host_bridge_regs[0x5c] = 0x01; + mvp3.host_bridge_regs[0x5d] = 0x01; + mvp3.host_bridge_regs[0x5e] = 0x01; + mvp3.host_bridge_regs[0x5f] = 0x01; - mvp3.host_bridge_regs[0x64] = 0xec; - mvp3.host_bridge_regs[0x65] = 0xec; - mvp3.host_bridge_regs[0x66] = 0xec; - mvp3.host_bridge_regs[0x6b] = 0x01; + mvp3.host_bridge_regs[0x64] = 0xec; + mvp3.host_bridge_regs[0x65] = 0xec; + mvp3.host_bridge_regs[0x66] = 0xec; + mvp3.host_bridge_regs[0x6b] = 0x01; - mvp3.host_bridge_regs[0xa0] = 0x02; - mvp3.host_bridge_regs[0xa2] = 0x10; - mvp3.host_bridge_regs[0xa4] = 0x03; - mvp3.host_bridge_regs[0xa5] = 0x02; - mvp3.host_bridge_regs[0xa6] = 0x00; - mvp3.host_bridge_regs[0xa7] = 0x07; + mvp3.host_bridge_regs[0xa0] = 0x02; + mvp3.host_bridge_regs[0xa2] = 0x10; + mvp3.host_bridge_regs[0xa4] = 0x03; + mvp3.host_bridge_regs[0xa5] = 0x02; + mvp3.host_bridge_regs[0xa6] = 0x00; + mvp3.host_bridge_regs[0xa7] = 0x07; - mvp3.pci_bridge_regs[0x00] = 0x06; - mvp3.pci_bridge_regs[0x01] = 0x11; /*VIA*/ - mvp3.pci_bridge_regs[0x02] = 0x98; - mvp3.pci_bridge_regs[0x03] = 0x85; /*VT82C598MVP*/ - mvp3.pci_bridge_regs[0x04] = 0x07; - mvp3.pci_bridge_regs[0x05] = 0x00; - mvp3.pci_bridge_regs[0x06] = 0x20; - mvp3.pci_bridge_regs[0x07] = 0x02; - mvp3.pci_bridge_regs[0x0a] = 0x04; - mvp3.pci_bridge_regs[0x0b] = 0x06; - mvp3.pci_bridge_regs[0x0e] = 0x01; + mvp3.pci_bridge_regs[0x00] = 0x06; + mvp3.pci_bridge_regs[0x01] = 0x11; /*VIA*/ + mvp3.pci_bridge_regs[0x02] = 0x98; + mvp3.pci_bridge_regs[0x03] = 0x85; /*VT82C598MVP*/ + mvp3.pci_bridge_regs[0x04] = 0x07; + mvp3.pci_bridge_regs[0x05] = 0x00; + mvp3.pci_bridge_regs[0x06] = 0x20; + mvp3.pci_bridge_regs[0x07] = 0x02; + mvp3.pci_bridge_regs[0x0a] = 0x04; + mvp3.pci_bridge_regs[0x0b] = 0x06; + mvp3.pci_bridge_regs[0x0e] = 0x01; - mvp3.pci_bridge_regs[0x1c] = 0xf0; + mvp3.pci_bridge_regs[0x1c] = 0xf0; - mvp3.pci_bridge_regs[0x20] = 0xf0; - mvp3.pci_bridge_regs[0x21] = 0xff; + mvp3.pci_bridge_regs[0x20] = 0xf0; + mvp3.pci_bridge_regs[0x21] = 0xff; - mvp3.pci_bridge_regs[0x24] = 0xf0; - mvp3.pci_bridge_regs[0x25] = 0xff; + mvp3.pci_bridge_regs[0x24] = 0xf0; + mvp3.pci_bridge_regs[0x25] = 0xff; - smram_enable = mvp3_smram_enable; - smram_disable = mvp3_smram_disable; + smram_enable = mvp3_smram_enable; + smram_disable = mvp3_smram_disable; } diff --git a/src/models/neat.c b/src/models/neat.c index a0a6bba5..82236ba6 100644 --- a/src/models/neat.c +++ b/src/models/neat.c @@ -8,54 +8,55 @@ static int neat_index; static int neat_emspage[4]; void neat_write(uint16_t port, uint8_t val, void *priv) { - switch (port) { - case 0x22:neat_index = val; - break; + 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 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; - } + 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; + } } uint8_t neat_read(uint16_t port, void *priv) { - switch (port) { - case 0x22:return neat_index; + switch (port) { + case 0x22: + return neat_index; - case 0x23:return neat_regs[neat_index]; - } - return 0xff; + case 0x23: + return neat_regs[neat_index]; + } + return 0xff; } -void neat_writeems(uint32_t addr, uint8_t val) { - ram[(neat_emspage[(addr >> 14) & 3] << 14) + (addr & 0x3FFF)] = val; -} +void neat_writeems(uint32_t addr, uint8_t val) { ram[(neat_emspage[(addr >> 14) & 3] << 14) + (addr & 0x3FFF)] = val; } -uint8_t neat_readems(uint32_t addr) { - return ram[(neat_emspage[(addr >> 14) & 3] << 14) + (addr & 0x3FFF)]; -} +uint8_t neat_readems(uint32_t addr) { return ram[(neat_emspage[(addr >> 14) & 3] << 14) + (addr & 0x3FFF)]; } void neat_init() { - 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); + 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); } diff --git a/src/models/nmi.c b/src/models/nmi.c index d3f4cc73..a0ef7a6a 100644 --- a/src/models/nmi.c +++ b/src/models/nmi.c @@ -4,11 +4,9 @@ int nmi_mask; -void nmi_write(uint16_t port, uint8_t val, void *p) { - nmi_mask = val & 0x80; -} +void nmi_write(uint16_t port, uint8_t val, void *p) { nmi_mask = val & 0x80; } void nmi_init() { - io_sethandler(0x00a0, 0x0001, NULL, NULL, NULL, nmi_write, NULL, NULL, NULL); - nmi_mask = 0; + io_sethandler(0x00a0, 0x0001, NULL, NULL, NULL, nmi_write, NULL, NULL, NULL); + nmi_mask = 0; } diff --git a/src/models/nvr_tc8521.c b/src/models/nvr_tc8521.c index fa18f9be..ee3a9b9a 100644 --- a/src/models/nvr_tc8521.c +++ b/src/models/nvr_tc8521.c @@ -15,79 +15,85 @@ static pc_timer_t nvr_onesec_timer; static int nvr_onesec_cnt = 0; static void tc8521_onesec(void *p) { - nvr_onesec_cnt++; - if (nvr_onesec_cnt >= 100) { - tc8521_tick(); - nvr_onesec_cnt = 0; - } - timer_advance_u64(&nvr_onesec_timer, 10000 * TIMER_USEC); + nvr_onesec_cnt++; + if (nvr_onesec_cnt >= 100) { + tc8521_tick(); + nvr_onesec_cnt = 0; + } + timer_advance_u64(&nvr_onesec_timer, 10000 * TIMER_USEC); } void write_tc8521(uint16_t addr, uint8_t val, void *priv) { - uint8_t page = nvrram[0x0D] & 3; + uint8_t page = nvrram[0x0D] & 3; - addr &= 0x0F; - if (addr < 0x0D) - addr += 16 * page; + addr &= 0x0F; + if (addr < 0x0D) + addr += 16 * page; - if (addr >= 0x10 && nvrram[addr] != val) - nvr_dosave = 1; + if (addr >= 0x10 && nvrram[addr] != val) + nvr_dosave = 1; - nvrram[addr] = val; + nvrram[addr] = val; } uint8_t read_tc8521(uint16_t addr, void *priv) { - uint8_t page = nvrram[0x0D] & 3; + uint8_t page = nvrram[0x0D] & 3; - addr &= 0x0F; - if (addr < 0x0D) - addr += 16 * page; + addr &= 0x0F; + if (addr < 0x0D) + addr += 16 * page; - return nvrram[addr]; + return nvrram[addr]; } void tc8521_loadnvr() { - FILE *f; + FILE *f; - nvrmask = 63; - oldromset = romset; - switch (romset) { - case ROM_T1000: f = nvrfopen("t1000.nvr", "rb"); - break; - case ROM_T1200: f = nvrfopen("t1200.nvr", "rb"); - break; - default: return; - } - if (!f) { - memset(nvrram, 0xFF, 64); - nvrram[0x0E] = 0; /* Test register */ - if (!enable_sync) { - memset(nvrram, 0, 16); - } - return; - } - fread(nvrram, 64, 1, f); - if (enable_sync) - tc8521_internal_sync(nvrram); - else - tc8521_internal_set_nvrram(nvrram); /* Update the internal clock state based on the NVR registers. */ - fclose(f); + nvrmask = 63; + oldromset = romset; + switch (romset) { + case ROM_T1000: + f = nvrfopen("t1000.nvr", "rb"); + break; + case ROM_T1200: + f = nvrfopen("t1200.nvr", "rb"); + break; + default: + return; + } + if (!f) { + memset(nvrram, 0xFF, 64); + nvrram[0x0E] = 0; /* Test register */ + if (!enable_sync) { + memset(nvrram, 0, 16); + } + return; + } + fread(nvrram, 64, 1, f); + if (enable_sync) + tc8521_internal_sync(nvrram); + else + tc8521_internal_set_nvrram(nvrram); /* Update the internal clock state based on the NVR registers. */ + fclose(f); } void tc8521_savenvr() { - FILE *f; - switch (oldromset) { - case ROM_T1000: f = nvrfopen("t1000.nvr", "wb"); - break; - case ROM_T1200: f = nvrfopen("t1200.nvr", "wb"); - break; - default: return; - } - fwrite(nvrram, 64, 1, f); - fclose(f); + FILE *f; + switch (oldromset) { + case ROM_T1000: + f = nvrfopen("t1000.nvr", "wb"); + break; + case ROM_T1200: + f = nvrfopen("t1200.nvr", "wb"); + break; + default: + return; + } + fwrite(nvrram, 64, 1, f); + fclose(f); } void nvr_tc8521_init() { - io_sethandler(0x2C0, 0x10, read_tc8521, NULL, NULL, write_tc8521, NULL, NULL, NULL); - timer_add(&nvr_onesec_timer, tc8521_onesec, NULL, 1); + io_sethandler(0x2C0, 0x10, read_tc8521, NULL, NULL, write_tc8521, NULL, NULL, NULL); + timer_add(&nvr_onesec_timer, tc8521_onesec, NULL, 1); } diff --git a/src/models/olivetti_m24.c b/src/models/olivetti_m24.c index 3f06ca54..917891ea 100644 --- a/src/models/olivetti_m24.c +++ b/src/models/olivetti_m24.c @@ -3,13 +3,13 @@ #include "olivetti_m24.h" uint8_t olivetti_m24_read(uint16_t port, void *priv) { - switch (port) { - case 0x66:return 0x00; - case 0x67:return 0x20 | 0x40 | 0x0C; - } - return 0xff; + switch (port) { + case 0x66: + return 0x00; + case 0x67: + return 0x20 | 0x40 | 0x0C; + } + return 0xff; } -void olivetti_m24_init() { - io_sethandler(0x0066, 0x0002, olivetti_m24_read, NULL, NULL, NULL, NULL, NULL, NULL); -} +void olivetti_m24_init() { io_sethandler(0x0066, 0x0002, olivetti_m24_read, NULL, NULL, NULL, NULL, NULL, NULL); } diff --git a/src/models/opti495.c b/src/models/opti495.c index 506b4c82..57507e8c 100644 --- a/src/models/opti495.c +++ b/src/models/opti495.c @@ -9,56 +9,58 @@ 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:printf("Writing OPTI reg %02X %02X\n", optireg, val); - if (optireg >= 0x20 && optireg <= 0x2C) { - optiregs[optireg - 0x20] = val; - if (optireg == 0x21) { - cpu_cache_ext_enabled = val & 0x10; - cpu_update_waitstates(); - } - if (optireg == 0x22) { - if (!(val & 0x80)) - 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; - } + switch (addr) { + case 0x22: + optireg = val; + break; + case 0x24: + printf("Writing OPTI reg %02X %02X\n", optireg, val); + if (optireg >= 0x20 && optireg <= 0x2C) { + optiregs[optireg - 0x20] = val; + if (optireg == 0x21) { + cpu_cache_ext_enabled = val & 0x10; + cpu_update_waitstates(); + } + if (optireg == 0x22) { + if (!(val & 0x80)) + 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: - //printf("Read OPTI reg %02X\n",optireg); - if (optireg >= 0x20 && optireg <= 0x2C) - return optiregs[optireg - 0x20]; - break; - } - return 0xFF; + switch (addr) { + case 0x24: + // printf("Read OPTI reg %02X\n",optireg); + if (optireg >= 0x20 && optireg <= 0x2C) + return optiregs[optireg - 0x20]; + break; + } + return 0xFF; } void opti495_init() { - 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; + 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; } /*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). + 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 + even if the same register is being accessed a second time SeeAlso: PORT 0022h"82C206" 0022 ?W configuration register index (see #P0178) @@ -83,78 +85,78 @@ 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) + 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) + 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) + 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 = 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 + 0 = disable (default) + 1 = enable 6 Emulation Keyboard Reset Delay Control - 0 = Generate reset pulse 2us later (default) - 1 = Generate reset pulse immediately + 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 + 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 + 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 = 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 + 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) + 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 + 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 + 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 + 0 = disable (default) + 1 = enable 3 enable write-protect for Shadow RAM at E0000h - EFFFFh Area - 0 = disable (default) - 1 = enable + 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 + (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) + (default is 0 = disable) SeeAlso: #P0182 Bitfields for OPTi-82C493 Shadow RAM Control Register 2: @@ -172,72 +174,72 @@ 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 + 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 + 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) + 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) + 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) + 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 + 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. + 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 + 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 + 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 @@ -251,50 +253,50 @@ 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) + 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 + 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) + 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 + (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 + ignoring the appropriate number of the least-significant bits SeeAlso: #P0178,#P0187 */ diff --git a/src/models/pc87306.c b/src/models/pc87306.c index 8fa88ea6..2bf1f718 100644 --- a/src/models/pc87306.c +++ b/src/models/pc87306.c @@ -7,174 +7,194 @@ #include "pc87306.h" typedef struct pc87306_t { - int first_read; - int cur_addr; + int first_read; + int cur_addr; - uint8_t regs[32]; + uint8_t regs[32]; - uint8_t gpio_1, gpio_2; + uint8_t gpio_1, gpio_2; } pc87306_t; static pc87306_t pc87306_global; -#define REG_FER 0x00 -#define REG_FAR 0x01 +#define REG_FER 0x00 +#define REG_FAR 0x01 #define REG_GPBA 0x0f #define REG_SCF0 0x12 #define REG_PNP0 0x1b -#define FER_LPT_ENA (1 << 0) +#define FER_LPT_ENA (1 << 0) #define FER_COM1_ENA (1 << 1) #define FER_COM2_ENA (1 << 2) -#define FER_FDC_ENA (1 << 3) +#define FER_FDC_ENA (1 << 3) static uint16_t get_com_addr(pc87306_t *pc87306, int reg) { - switch (reg) { - case 0:return 0x3f8; - case 1:return 0x2f8; - case 2: - switch (pc87306->regs[REG_FAR] >> 6) { - case 0:return 0x3e8; - case 1:return 0x338; - case 2:return 0x2e8; - case 3:return 0x220; - } - break; - case 3: - switch (pc87306->regs[REG_FAR] >> 6) { - case 0:return 0x2e8; - case 1:return 0x238; - case 2:return 0x2e0; - case 3:return 0x228; - } - break; - } - fatal("get_com_addr invalid\n"); - return 0xff; + switch (reg) { + case 0: + return 0x3f8; + case 1: + return 0x2f8; + case 2: + switch (pc87306->regs[REG_FAR] >> 6) { + case 0: + return 0x3e8; + case 1: + return 0x338; + case 2: + return 0x2e8; + case 3: + return 0x220; + } + break; + case 3: + switch (pc87306->regs[REG_FAR] >> 6) { + case 0: + return 0x2e8; + case 1: + return 0x238; + case 2: + return 0x2e0; + case 3: + return 0x228; + } + break; + } + fatal("get_com_addr invalid\n"); + return 0xff; } static uint8_t pc87306_gpio_read(uint16_t port, void *p) { - pc87306_t *pc87306 = (pc87306_t *)p; - uint8_t temp; + pc87306_t *pc87306 = (pc87306_t *)p; + uint8_t temp; - if (!(port & 1)) - temp = pc87306->gpio_1; - else - temp = pc87306->gpio_2; + if (!(port & 1)) + temp = pc87306->gpio_1; + else + temp = pc87306->gpio_2; -// pclog("Read GPIO %04x %02x\n", port, temp); - return temp; + // pclog("Read GPIO %04x %02x\n", port, temp); + return temp; } static void pc87306_gpio_write(uint16_t port, uint8_t val, void *p) { - pc87306_t *pc87306 = (pc87306_t *)p; + pc87306_t *pc87306 = (pc87306_t *)p; -// pclog("Write GPIO %04x %02x\n", port, val); - if (!(port & 1)) - pc87306->gpio_1 = val; + // pclog("Write GPIO %04x %02x\n", port, val); + if (!(port & 1)) + pc87306->gpio_1 = val; } static uint8_t pc87306_read(uint16_t port, void *p) { - pc87306_t *pc87306 = (pc87306_t *)p; + pc87306_t *pc87306 = (pc87306_t *)p; - if (!(port & 1)) { - if (pc87306->first_read) { - pc87306->first_read = 0; - return 0x88; /*ID*/ - } - return pc87306->cur_addr; - } else { - pc87306->regs[8] = 0x70; -// pclog("PC87306 read %02x %02x %04x:%04x\n", pc87306->cur_addr, pc87306->regs[pc87306->cur_addr], CS,cpu_state.pc); -// if (pc87306->cur_addr == 0) -// output = 3; - return pc87306->regs[pc87306->cur_addr]; - } + if (!(port & 1)) { + if (pc87306->first_read) { + pc87306->first_read = 0; + return 0x88; /*ID*/ + } + return pc87306->cur_addr; + } else { + pc87306->regs[8] = 0x70; + // pclog("PC87306 read %02x %02x %04x:%04x\n", pc87306->cur_addr, pc87306->regs[pc87306->cur_addr], + // CS,cpu_state.pc); if (pc87306->cur_addr == 0) + // output = 3; + return pc87306->regs[pc87306->cur_addr]; + } } static void pc87306_write(uint16_t port, uint8_t val, void *p) { - pc87306_t *pc87306 = (pc87306_t *)p; -//pclog("pc87306_write: port=%04x val=%02x %04x:%04x\n", port, val, CS,cpu_state.pc); - if (!(port & 1)) - pc87306->cur_addr = val & 0x1f; - else { - uint16_t old_gpio_addr = pc87306_global.regs[REG_GPBA] << 2; + pc87306_t *pc87306 = (pc87306_t *)p; + // pclog("pc87306_write: port=%04x val=%02x %04x:%04x\n", port, val, CS,cpu_state.pc); + if (!(port & 1)) + pc87306->cur_addr = val & 0x1f; + else { + uint16_t old_gpio_addr = pc87306_global.regs[REG_GPBA] << 2; - pc87306->regs[pc87306->cur_addr] = val; + pc87306->regs[pc87306->cur_addr] = val; -// pclog("PC87306 write %02x %02x\n", pc87306->cur_addr, val); + // pclog("PC87306 write %02x %02x\n", pc87306->cur_addr, val); - fdc_remove(); - if (pc87306->regs[REG_FER] & FER_FDC_ENA) - fdc_add(); - serial1_remove(); - if (pc87306->regs[REG_FER] & FER_COM1_ENA) { - uint16_t addr = get_com_addr(pc87306, (pc87306->regs[REG_FAR] >> 2) & 3); + fdc_remove(); + if (pc87306->regs[REG_FER] & FER_FDC_ENA) + fdc_add(); + serial1_remove(); + if (pc87306->regs[REG_FER] & FER_COM1_ENA) { + uint16_t addr = get_com_addr(pc87306, (pc87306->regs[REG_FAR] >> 2) & 3); - switch ((pc87306->regs[REG_FAR] >> 2) & 3) { - case 0: - case 2:serial1_set(addr, 4); - break; - case 1: - case 3:serial1_set(addr, 3); - break; - } - } - serial2_remove(); - if (pc87306->regs[REG_FER] & FER_COM2_ENA) { - uint16_t addr = get_com_addr(pc87306, (pc87306->regs[REG_FAR] >> 4) & 3); + switch ((pc87306->regs[REG_FAR] >> 2) & 3) { + case 0: + case 2: + serial1_set(addr, 4); + break; + case 1: + case 3: + serial1_set(addr, 3); + break; + } + } + serial2_remove(); + if (pc87306->regs[REG_FER] & FER_COM2_ENA) { + uint16_t addr = get_com_addr(pc87306, (pc87306->regs[REG_FAR] >> 4) & 3); - switch ((pc87306->regs[REG_FAR] >> 4) & 3) { - case 0: - case 2:serial2_set(addr, 4); - break; - case 1: - case 3:serial2_set(addr, 3); - break; - } - } - lpt1_remove(); - lpt2_remove(); - if (pc87306->regs[REG_FER] & FER_LPT_ENA) { - int reg; + switch ((pc87306->regs[REG_FAR] >> 4) & 3) { + case 0: + case 2: + serial2_set(addr, 4); + break; + case 1: + case 3: + serial2_set(addr, 3); + break; + } + } + lpt1_remove(); + lpt2_remove(); + if (pc87306->regs[REG_FER] & FER_LPT_ENA) { + int reg; - reg = pc87306->regs[REG_FAR] & 3; - reg |= (pc87306->regs[REG_PNP0] & 0x30) >> 2; + reg = pc87306->regs[REG_FAR] & 3; + reg |= (pc87306->regs[REG_PNP0] & 0x30) >> 2; - switch (reg) { - case 0x0: - case 0x8: - case 0x4: - case 0x5: - case 0x6: - case 0x7:lpt1_init(0x378); - break; - case 0x1: - case 0x9:lpt1_init(0x3bc); - break; - case 0x2: - case 0xa: - case 0xc: - case 0xd: - case 0xe: - case 0xf:lpt1_init(0x278); - break; - } - } - io_removehandler(old_gpio_addr, 0x0002, pc87306_gpio_read, NULL, NULL, pc87306_gpio_write, NULL, NULL, &pc87306_global); - io_sethandler(pc87306_global.regs[REG_GPBA] << 2, 0x0002, pc87306_gpio_read, NULL, NULL, pc87306_gpio_write, NULL, NULL, &pc87306_global); - } + switch (reg) { + case 0x0: + case 0x8: + case 0x4: + case 0x5: + case 0x6: + case 0x7: + lpt1_init(0x378); + break; + case 0x1: + case 0x9: + lpt1_init(0x3bc); + break; + case 0x2: + case 0xa: + case 0xc: + case 0xd: + case 0xe: + case 0xf: + lpt1_init(0x278); + break; + } + } + io_removehandler(old_gpio_addr, 0x0002, pc87306_gpio_read, NULL, NULL, pc87306_gpio_write, NULL, NULL, + &pc87306_global); + io_sethandler(pc87306_global.regs[REG_GPBA] << 2, 0x0002, pc87306_gpio_read, NULL, NULL, pc87306_gpio_write, NULL, + NULL, &pc87306_global); + } } void pc87306_init(uint16_t port) { - memset(&pc87306_global, 0, sizeof(pc87306_t)); + memset(&pc87306_global, 0, sizeof(pc87306_t)); - pc87306_global.first_read = 1; - io_sethandler(port, 0x0002, pc87306_read, NULL, NULL, pc87306_write, NULL, NULL, &pc87306_global); - pc87306_global.regs[REG_FER] = 0; - pc87306_global.regs[REG_FAR] = 0x10; - pc87306_global.regs[REG_GPBA] = 0x78 >> 2; - pc87306_global.regs[REG_SCF0] = 0x30; - pc87306_global.gpio_2 = 0xff; // this is a mask only, output will be defined by zappa_brdconfig and endeavor_brdconfig in intel.c - io_sethandler(0x0078, 0x0002, pc87306_gpio_read, NULL, NULL, pc87306_gpio_write, NULL, NULL, &pc87306_global); + pc87306_global.first_read = 1; + io_sethandler(port, 0x0002, pc87306_read, NULL, NULL, pc87306_write, NULL, NULL, &pc87306_global); + pc87306_global.regs[REG_FER] = 0; + pc87306_global.regs[REG_FAR] = 0x10; + pc87306_global.regs[REG_GPBA] = 0x78 >> 2; + pc87306_global.regs[REG_SCF0] = 0x30; + pc87306_global.gpio_2 = + 0xff; // this is a mask only, output will be defined by zappa_brdconfig and endeavor_brdconfig in intel.c + io_sethandler(0x0078, 0x0002, pc87306_gpio_read, NULL, NULL, pc87306_gpio_write, NULL, NULL, &pc87306_global); } diff --git a/src/models/pc87307.c b/src/models/pc87307.c index 7b70aa12..fc93cd98 100644 --- a/src/models/pc87307.c +++ b/src/models/pc87307.c @@ -7,122 +7,138 @@ #include "pc87307.h" typedef struct pc87307_t { - int cur_reg; - int cur_device; + int cur_reg; + int cur_device; - uint8_t superio_cfg1, superio_cfg2; + uint8_t superio_cfg1, superio_cfg2; - struct { - int enable; - uint16_t addr; - int irq; - int dma; - } dev[9]; + struct { + int enable; + uint16_t addr; + int irq; + int dma; + } dev[9]; } pc87307_t; static pc87307_t pc87307_global; -#define DEV_KBC 0 +#define DEV_KBC 0 #define DEV_MOUSE 1 -#define DEV_RTC 2 -#define DEV_FDC 3 -#define DEV_LPT 4 -#define DEV_COM2 5 -#define DEV_COM1 6 -#define DEV_GPIO 7 +#define DEV_RTC 2 +#define DEV_FDC 3 +#define DEV_LPT 4 +#define DEV_COM2 5 +#define DEV_COM1 6 +#define DEV_GPIO 7 #define DEV_POWER 8 #define REG_DEVICE 0x07 -#define REG_SID 0x20 +#define REG_SID 0x20 #define REG_SUPERIO_CFG1 0x21 #define REG_SUPERIO_CFG2 0x22 #define REG_ENABLE 0x30 #define REG_ADDRHI 0x60 #define REG_ADDRLO 0x61 -#define REG_IRQ 0x70 -#define REG_DMA 0x74 +#define REG_IRQ 0x70 +#define REG_DMA 0x74 void pc87307_write(uint16_t port, uint8_t val, void *p) { - pc87307_t *pc87307 = (pc87307_t *)p; + pc87307_t *pc87307 = (pc87307_t *)p; - if (port == 0x2e) - pc87307->cur_reg = val; - else { - if (pc87307->cur_reg == REG_DEVICE) - pc87307->cur_device = val & 0xf; - else { -// pclog("Write pc87307 %02x [%02x] %02x\n", pc87307->cur_reg, pc87307->cur_device, val); - switch (pc87307->cur_reg) { - case REG_ENABLE: - if (pc87307->cur_device <= DEV_POWER) - pc87307->dev[pc87307->cur_device].enable = val; - break; - case REG_ADDRLO: - if (pc87307->cur_device <= DEV_POWER) - pc87307->dev[pc87307->cur_device].addr = (pc87307->dev[pc87307->cur_device].addr & 0xff00) | val; - break; - case REG_ADDRHI: - if (pc87307->cur_device <= DEV_POWER) - pc87307->dev[pc87307->cur_device].addr = (pc87307->dev[pc87307->cur_device].addr & 0x00ff) | (val << 8); - break; - case REG_IRQ: - if (pc87307->cur_device <= DEV_POWER) - pc87307->dev[pc87307->cur_device].irq = val; - break; - case REG_DMA: - if (pc87307->cur_device <= DEV_POWER) - pc87307->dev[pc87307->cur_device].dma = val; - break; - } + if (port == 0x2e) + pc87307->cur_reg = val; + else { + if (pc87307->cur_reg == REG_DEVICE) + pc87307->cur_device = val & 0xf; + else { + // pclog("Write pc87307 %02x [%02x] %02x\n", pc87307->cur_reg, pc87307->cur_device, + // val); + switch (pc87307->cur_reg) { + case REG_ENABLE: + if (pc87307->cur_device <= DEV_POWER) + pc87307->dev[pc87307->cur_device].enable = val; + break; + case REG_ADDRLO: + if (pc87307->cur_device <= DEV_POWER) + pc87307->dev[pc87307->cur_device].addr = + (pc87307->dev[pc87307->cur_device].addr & 0xff00) | val; + break; + case REG_ADDRHI: + if (pc87307->cur_device <= DEV_POWER) + pc87307->dev[pc87307->cur_device].addr = + (pc87307->dev[pc87307->cur_device].addr & 0x00ff) | (val << 8); + break; + case REG_IRQ: + if (pc87307->cur_device <= DEV_POWER) + pc87307->dev[pc87307->cur_device].irq = val; + break; + case REG_DMA: + if (pc87307->cur_device <= DEV_POWER) + pc87307->dev[pc87307->cur_device].dma = val; + break; + } - switch (pc87307->cur_device) { - case DEV_FDC:fdc_remove(); - if (pc87307->dev[DEV_FDC].enable & 1) - fdc_add(); - break; - case DEV_COM1:serial1_remove(); - if (pc87307->dev[DEV_COM1].enable & 1) - serial1_set(pc87307->dev[DEV_COM1].addr, pc87307->dev[DEV_COM1].irq); - break; - case DEV_COM2:serial2_remove(); - if (pc87307->dev[DEV_COM2].enable & 1) - serial2_set(pc87307->dev[DEV_COM2].addr, pc87307->dev[DEV_COM2].irq); - break; - case DEV_LPT:lpt1_remove(); - lpt2_remove(); - if (pc87307->dev[DEV_LPT].enable & 1) - lpt1_init(pc87307->dev[DEV_LPT].addr); - break; - } - } - } + switch (pc87307->cur_device) { + case DEV_FDC: + fdc_remove(); + if (pc87307->dev[DEV_FDC].enable & 1) + fdc_add(); + break; + case DEV_COM1: + serial1_remove(); + if (pc87307->dev[DEV_COM1].enable & 1) + serial1_set(pc87307->dev[DEV_COM1].addr, pc87307->dev[DEV_COM1].irq); + break; + case DEV_COM2: + serial2_remove(); + if (pc87307->dev[DEV_COM2].enable & 1) + serial2_set(pc87307->dev[DEV_COM2].addr, pc87307->dev[DEV_COM2].irq); + break; + case DEV_LPT: + lpt1_remove(); + lpt2_remove(); + if (pc87307->dev[DEV_LPT].enable & 1) + lpt1_init(pc87307->dev[DEV_LPT].addr); + break; + } + } + } } uint8_t pc87307_read(uint16_t port, void *p) { - pc87307_t *pc87307 = (pc87307_t *)p; + pc87307_t *pc87307 = (pc87307_t *)p; -// pclog("Read pc87307 %02x\n", pc87307->cur_reg); + // pclog("Read pc87307 %02x\n", pc87307->cur_reg); - switch (pc87307->cur_reg) { - case REG_DEVICE:return pc87307->cur_device; - case REG_SID:return 0x20; /*PC87307*/ - case REG_SUPERIO_CFG1:return pc87307->superio_cfg1; - case REG_SUPERIO_CFG2:return pc87307->superio_cfg2; - case REG_ENABLE:return pc87307->dev[pc87307->cur_device].enable; - case REG_ADDRLO:return pc87307->dev[pc87307->cur_device].addr & 0xff; - case REG_ADDRHI:return pc87307->dev[pc87307->cur_device].addr >> 8; - case REG_IRQ:return pc87307->dev[pc87307->cur_device].irq; - case REG_DMA:return pc87307->dev[pc87307->cur_device].dma; - } + switch (pc87307->cur_reg) { + case REG_DEVICE: + return pc87307->cur_device; + case REG_SID: + return 0x20; /*PC87307*/ + case REG_SUPERIO_CFG1: + return pc87307->superio_cfg1; + case REG_SUPERIO_CFG2: + return pc87307->superio_cfg2; + case REG_ENABLE: + return pc87307->dev[pc87307->cur_device].enable; + case REG_ADDRLO: + return pc87307->dev[pc87307->cur_device].addr & 0xff; + case REG_ADDRHI: + return pc87307->dev[pc87307->cur_device].addr >> 8; + case REG_IRQ: + return pc87307->dev[pc87307->cur_device].irq; + case REG_DMA: + return pc87307->dev[pc87307->cur_device].dma; + } - return 0xff; + return 0xff; } void pc87307_init(uint16_t base) { - memset(&pc87307_global, 0, sizeof(pc87307_t)); + memset(&pc87307_global, 0, sizeof(pc87307_t)); - pc87307_global.superio_cfg1 = 0x04; - pc87307_global.superio_cfg2 = 0x03; + pc87307_global.superio_cfg1 = 0x04; + pc87307_global.superio_cfg2 = 0x03; - io_sethandler(base, 0x0002, pc87307_read, NULL, NULL, pc87307_write, NULL, NULL, &pc87307_global); + io_sethandler(base, 0x0002, pc87307_read, NULL, NULL, pc87307_write, NULL, NULL, &pc87307_global); } diff --git a/src/models/pic.c b/src/models/pic.c index 10d08332..da1d1ff9 100644 --- a/src/models/pic.c +++ b/src/models/pic.c @@ -9,386 +9,389 @@ int keywaiting = 0; int pic_intpending; void pic_updatepending() { - if (AT || romset == ROM_XI8088) { - if ((pic2.pend & ~pic2.mask) & ~pic2.mask2) - pic.pend |= (1 << 2); - else - pic.pend &= ~(1 << 2); - pic_intpending = (pic.pend & ~pic.mask) & ~pic.mask2; - if (!((pic.mask | pic.mask2) & (1 << 2))) - pic_intpending |= ((pic2.pend & ~pic2.mask) & ~pic2.mask2); - } else - pic_intpending = (pic.pend & ~pic.mask) & ~pic.mask2; + if (AT || romset == ROM_XI8088) { + if ((pic2.pend & ~pic2.mask) & ~pic2.mask2) + pic.pend |= (1 << 2); + else + pic.pend &= ~(1 << 2); + pic_intpending = (pic.pend & ~pic.mask) & ~pic.mask2; + if (!((pic.mask | pic.mask2) & (1 << 2))) + pic_intpending |= ((pic2.pend & ~pic2.mask) & ~pic2.mask2); + } else + pic_intpending = (pic.pend & ~pic.mask) & ~pic.mask2; -/* pclog("pic_intpending = %i %02X %02X %02X %02X\n", pic_intpending, pic.ins, pic.pend, pic.mask, pic.mask2); - pclog(" %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));*/ + /* pclog("pic_intpending = %i %02X %02X %02X %02X\n", pic_intpending, pic.ins, pic.pend, pic.mask, pic.mask2); + pclog(" %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; - pic.level_sensitive = 0; - pic2.level_sensitive = 0; + 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; + pic.level_sensitive = 0; + pic2.level_sensitive = 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; - } - } + int c; + *mask = 0; + for (c = 0; c < 8; c++) { + if (ins & (1 << c)) { + *mask = 0xff << c; + return; + } + } } static void pic_autoeoi() { - int c; + int c; - for (c = 0; c < 8; c++) { - if (pic.ins & (1 << c)) { - pic.ins &= ~(1 << c); - pic_update_mask(&pic.mask2, pic.ins); + for (c = 0; c < 8; c++) { + if (pic.ins & (1 << c)) { + pic.ins &= ~(1 << c); + pic_update_mask(&pic.mask2, pic.ins); - if ((AT || romset == ROM_XI8088) && c == 2 && (pic2.pend & ~pic2.mask) & ~pic2.mask2) - pic.pend |= (1 << 2); + if ((AT || romset == ROM_XI8088) && c == 2 && (pic2.pend & ~pic2.mask) & ~pic2.mask2) + pic.pend |= (1 << 2); - pic_updatepending(); - return; - } - } + pic_updatepending(); + return; + } + } } void pic_write(uint16_t addr, uint8_t val, void *priv) { - int c; -// pclog("Write PIC %04X %02X %04X(%06X):%04X\n",addr,val,CS,cs,pc); - if (addr & 1) { - switch (pic.icw) { - case 0: /*OCW1*/ -// printf("Write mask %02X %04X:%04X\n",val,CS,pc); - pic.mask = val; - pic_updatepending(); - break; - case 1: /*ICW2*/ - pic.vector = val & 0xF8; -// printf("PIC vector now %02X\n",pic.vector); - // output=1; - if (pic.icw1 & 2) - pic.icw = 3; - else - pic.icw = 2; - break; - case 2: /*ICW3*/ - if (pic.icw1 & 1) - pic.icw = 3; - else - pic.icw = 0; - break; - case 3: /*ICW4*/ - pic.icw4 = val; -// pclog("ICW4 = %02x\n", 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*/ - { -// printf("Clear ints - %02X %02X\n",pic.ins,val); - if ((val & 0xE0) == 0x60) { -// pclog("Specific EOI - %02X %i\n",pic.ins,1<<(val&7)); - pic.ins &= ~(1 << (val & 7)); - pic_update_mask(&pic.mask2, pic.ins); - if (val == 2 && (pic2.pend & ~pic2.mask) & ~pic2.mask2) - pic.pend |= (1 << 2); -// pic.pend&=(1<<(val&7)); -// if ((val&7)==1) pollkeywaiting(); - 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); + int c; + // pclog("Write PIC %04X %02X %04X(%06X):%04X\n",addr,val,CS,cs,pc); + if (addr & 1) { + switch (pic.icw) { + case 0: /*OCW1*/ + // printf("Write mask %02X %04X:%04X\n",val,CS,pc); + pic.mask = val; + pic_updatepending(); + break; + case 1: /*ICW2*/ + pic.vector = val & 0xF8; + // printf("PIC vector now %02X\n",pic.vector); + // output=1; + if (pic.icw1 & 2) + pic.icw = 3; + else + pic.icw = 2; + break; + case 2: /*ICW3*/ + if (pic.icw1 & 1) + pic.icw = 3; + else + pic.icw = 0; + break; + case 3: /*ICW4*/ + pic.icw4 = val; + // pclog("ICW4 = %02x\n", 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*/ + { + // printf("Clear ints - %02X %02X\n",pic.ins,val); + if ((val & 0xE0) == 0x60) { + // pclog("Specific EOI - %02X %i\n",pic.ins,1<<(val&7)); + pic.ins &= ~(1 << (val & 7)); + pic_update_mask(&pic.mask2, pic.ins); + if (val == 2 && (pic2.pend & ~pic2.mask) & ~pic2.mask2) + pic.pend |= (1 << 2); + // pic.pend&=(1<<(val&7)); + // if ((val&7)==1) pollkeywaiting(); + 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 (c == 2 && (pic2.pend & ~pic2.mask) & ~pic2.mask2) - pic.pend |= (1 << 2); + if (c == 2 && (pic2.pend & ~pic2.mask) & ~pic2.mask2) + pic.pend |= (1 << 2); - if (c == 1 && keywaiting) { - intclear &= ~1; -// pollkeywaiting(); - } - pic_updatepending(); -// pclog("Generic EOI - Cleared int %i\n",c); - return; - } - } - } - } else /*OCW3*/ - { - // if (val&4) fatal("PIC1 write OCW3 4 %02X\n",val); - if (val & 2) - pic.read = (val & 1); - if (val & 0x40) { - } //fatal("PIC 1 write OCW3 40 %02X\n",val); - } - } + if (c == 1 && keywaiting) { + intclear &= ~1; + // pollkeywaiting(); + } + pic_updatepending(); + // pclog("Generic EOI - Cleared int + // %i\n",c); + return; + } + } + } + } else /*OCW3*/ + { + // if (val&4) fatal("PIC1 write OCW3 4 %02X\n",val); + if (val & 2) + pic.read = (val & 1); + if (val & 0x40) { + } // fatal("PIC 1 write OCW3 40 %02X\n",val); + } + } } uint8_t pic_read(uint16_t addr, void *priv) { - if (addr & 1) { /*pclog("Read PIC mask %02X\n",pic.mask);*/ return pic.mask; - } - if (pic.read) { /*pclog("Read PIC ins %02X\n",pic.ins);*/ return pic.ins | (pic2.ins ? 4 : 0); - } -// pclog("Read PIC pend %02X %08X\n",pic.pend,EDX); - return pic.pend; + if (addr & 1) { /*pclog("Read PIC mask %02X\n",pic.mask);*/ + return pic.mask; + } + if (pic.read) { /*pclog("Read PIC ins %02X\n",pic.ins);*/ + return pic.ins | (pic2.ins ? 4 : 0); + } + // pclog("Read PIC pend %02X %08X\n",pic.pend,EDX); + return pic.pend; } -void pic_init() { - io_sethandler(0x0020, 0x0002, pic_read, NULL, NULL, pic_write, NULL, NULL, NULL); -} +void pic_init() { io_sethandler(0x0020, 0x0002, pic_read, NULL, NULL, pic_write, NULL, NULL, NULL); } static void pic2_autoeoi() { - int c; + int c; - for (c = 0; c < 8; c++) { - if (pic2.ins & (1 << c)) { - pic2.ins &= ~(1 << c); - pic_update_mask(&pic2.mask2, pic2.ins); + for (c = 0; c < 8; c++) { + if (pic2.ins & (1 << c)) { + pic2.ins &= ~(1 << c); + pic_update_mask(&pic2.mask2, pic2.ins); - pic_updatepending(); - return; - } - } + pic_updatepending(); + return; + } + } } void pic2_write(uint16_t addr, uint8_t val, void *priv) { - int c; -// pclog("Write PIC2 %04X %02X %04X:%04X %i\n",addr,val,CS,pc,ins); - if (addr & 1) { - switch (pic2.icw) { - case 0: /*OCW1*/ -// printf("PIC2 Write mask %02X %04X:%04X\n",val,CS,pc); - pic2.mask = val; - pic_updatepending(); - break; - case 1: /*ICW2*/ - pic2.vector = val & 0xF8; -// pclog("PIC2 vector %02X\n", val & 0xf8); - if (pic2.icw1 & 2) - pic2.icw = 3; - else - pic2.icw = 2; - break; - case 2: /*ICW3*/ - 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); + int c; + // pclog("Write PIC2 %04X %02X %04X:%04X %i\n",addr,val,CS,pc,ins); + if (addr & 1) { + switch (pic2.icw) { + case 0: /*OCW1*/ + // printf("PIC2 Write mask %02X %04X:%04X\n",val,CS,pc); + pic2.mask = val; + pic_updatepending(); + break; + case 1: /*ICW2*/ + pic2.vector = val & 0xF8; + // pclog("PIC2 vector %02X\n", val & 0xf8); + if (pic2.icw1 & 2) + pic2.icw = 3; + else + pic2.icw = 2; + break; + case 2: /*ICW3*/ + 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); - pic_updatepending(); - } else { - for (c = 0; c < 8; c++) { - if (pic2.ins & (1 << c)) { - pic2.ins &= ~(1 << c); - pic_update_mask(&pic2.mask2, pic2.ins); + pic_updatepending(); + } else { + for (c = 0; c < 8; c++) { + if (pic2.ins & (1 << c)) { + pic2.ins &= ~(1 << c); + pic_update_mask(&pic2.mask2, pic2.ins); - pic_updatepending(); - return; - } - } - } - } else /*OCW3*/ - { - if (val & 2) - pic2.read = (val & 1); - } - } + pic_updatepending(); + return; + } + } + } + } else /*OCW3*/ + { + if (val & 2) + pic2.read = (val & 1); + } + } } uint8_t pic2_read(uint16_t addr, void *priv) { - if (addr & 1) { /*pclog("Read PIC2 mask %02X %04X:%08X\n",pic2.mask,CS,pc);*/ return pic2.mask; - } - if (pic2.read) { /*pclog("Read PIC2 ins %02X %04X:%08X\n",pic2.ins,CS,pc);*/ return pic2.ins; - } - /*pclog("Read PIC2 pend %02X %04X:%08X\n",pic2.pend,CS,pc);*/ - return pic2.pend; + if (addr & 1) { /*pclog("Read PIC2 mask %02X %04X:%08X\n",pic2.mask,CS,pc);*/ + return pic2.mask; + } + if (pic2.read) { /*pclog("Read PIC2 ins %02X %04X:%08X\n",pic2.ins,CS,pc);*/ + return pic2.ins; + } + /*pclog("Read PIC2 pend %02X %04X:%08X\n",pic2.pend,CS,pc);*/ + return pic2.pend; } -void pic2_init() { - io_sethandler(0x00a0, 0x0002, pic2_read, NULL, NULL, pic2_write, NULL, NULL, NULL); -} +void pic2_init() { io_sethandler(0x00a0, 0x0002, pic2_read, NULL, NULL, pic2_write, NULL, NULL, NULL); } static uint8_t pic_elcrx_read(uint16_t addr, void *p) { - uint8_t temp = 0xff; + uint8_t temp = 0xff; - switch (addr) { - case 0x4d0:temp = pic.level_sensitive; - break; - case 0x4d1:temp = pic2.level_sensitive; - break; - } + switch (addr) { + case 0x4d0: + temp = pic.level_sensitive; + break; + case 0x4d1: + temp = pic2.level_sensitive; + break; + } - return temp; + return temp; } static void pic_elcrx_write(uint16_t addr, uint8_t val, void *p) { -// pclog("pic_elcrx_write: addr=%04x val=%02x\n", addr, val); - switch (addr) { - case 0x4d0:pic.level_sensitive = val & 0xf8; - break; - case 0x4d1:pic2.level_sensitive = val & 0xde; - break; - } + // pclog("pic_elcrx_write: addr=%04x val=%02x\n", addr, val); + switch (addr) { + case 0x4d0: + pic.level_sensitive = val & 0xf8; + break; + case 0x4d1: + pic2.level_sensitive = val & 0xde; + break; + } } -void pic_init_elcrx() { - io_sethandler(0x04d0, 0x0002, pic_elcrx_read, NULL, NULL, pic_elcrx_write, NULL, NULL, NULL); -} +void pic_init_elcrx() { io_sethandler(0x04d0, 0x0002, pic_elcrx_read, NULL, NULL, pic_elcrx_write, NULL, NULL, NULL); } void clearpic() { - pic.pend = pic.ins = 0; - pic_updatepending(); -// pclog("Clear PIC\n"); + pic.pend = pic.ins = 0; + pic_updatepending(); + // pclog("Clear PIC\n"); } int pic_current[16]; void picint(uint16_t num) { - if ((AT || romset == ROM_XI8088) && num == (1 << 2)) - num = 1 << 9; -// pclog("picint : %04X\n", num); - if ((AT || romset == ROM_XI8088) && num > 0xFF) { - pic2.pend |= (num >> 8); - if ((pic2.pend & ~pic2.mask) & ~pic2.mask2) - pic.pend |= (1 << 2); - } else if (num <= 0xff) { - pic.pend |= num; - } -// pclog("picint : PEND now %02X %02X\n", pic.pend, pic2.pend); - pic_updatepending(); + if ((AT || romset == ROM_XI8088) && num == (1 << 2)) + num = 1 << 9; + // pclog("picint : %04X\n", num); + if ((AT || romset == ROM_XI8088) && num > 0xFF) { + pic2.pend |= (num >> 8); + if ((pic2.pend & ~pic2.mask) & ~pic2.mask2) + pic.pend |= (1 << 2); + } else if (num <= 0xff) { + pic.pend |= num; + } + // pclog("picint : PEND now %02X %02X\n", pic.pend, pic2.pend); + pic_updatepending(); } void picintlevel(uint16_t num) { - int c = 0; - while (!(num & (1 << c))) - c++; - if ((AT || romset == ROM_XI8088) && num == (1 << 2)) { - c = 9; - num = 1 << 9; - } -// pclog("INTLEVEL %04X %i\n", num, c); - if (!pic_current[c]) { - pic_current[c] = 1; - if (num > 0xFF) { - pic2.pend |= (num >> 8); - } else { - pic.pend |= num; - } - } - pic_updatepending(); + int c = 0; + while (!(num & (1 << c))) + c++; + if ((AT || romset == ROM_XI8088) && num == (1 << 2)) { + c = 9; + num = 1 << 9; + } + // pclog("INTLEVEL %04X %i\n", num, c); + if (!pic_current[c]) { + pic_current[c] = 1; + if (num > 0xFF) { + pic2.pend |= (num >> 8); + } else { + pic.pend |= num; + } + } + pic_updatepending(); } void picintc(uint16_t num) { - int c = 0; - if (!num) - return; - while (!(num & (1 << c))) - c++; - if ((AT || romset == ROM_XI8088) && num == (1 << 2)) { - c = 9; - num = 1 << 9; - } -// pclog("INTC %04X %i\n", num, c); - pic_current[c] = 0; + int c = 0; + if (!num) + return; + while (!(num & (1 << c))) + c++; + if ((AT || romset == ROM_XI8088) && num == (1 << 2)) { + c = 9; + num = 1 << 9; + } + // pclog("INTC %04X %i\n", num, c); + pic_current[c] = 0; - if ((AT || romset == ROM_XI8088) && num > 0xff) { - pic2.pend &= ~(num >> 8); - if (!((pic2.pend & ~pic2.mask) & ~pic2.mask2)) - pic.pend &= ~(1 << 2); - } else if (num <= 0xff) { - pic.pend &= ~num; - } - pic_updatepending(); + if ((AT || romset == ROM_XI8088) && num > 0xff) { + pic2.pend &= ~(num >> 8); + if (!((pic2.pend & ~pic2.mask) & ~pic2.mask2)) + pic.pend &= ~(1 << 2); + } else if (num <= 0xff) { + pic.pend &= ~num; + } + pic_updatepending(); } uint8_t picinterrupt() { - uint8_t temp = pic.pend & ~pic.mask; - int c; - for (c = 0; c < 8; c++) { - if ((AT || romset == ROM_XI8088) && (temp & (1 << 2))) { - uint8_t temp2 = pic2.pend & ~pic2.mask; - for (c = 0; c < 8; c++) { - if (temp2 & (1 << c)) { - if (!(pic2.level_sensitive & (1 << c))) - pic2.pend &= ~(1 << c); - pic2.ins |= (1 << c); - pic_update_mask(&pic2.mask2, pic2.ins); + uint8_t temp = pic.pend & ~pic.mask; + int c; + for (c = 0; c < 8; c++) { + if ((AT || romset == ROM_XI8088) && (temp & (1 << 2))) { + uint8_t temp2 = pic2.pend & ~pic2.mask; + for (c = 0; c < 8; c++) { + if (temp2 & (1 << c)) { + if (!(pic2.level_sensitive & (1 << c))) + pic2.pend &= ~(1 << c); + pic2.ins |= (1 << c); + pic_update_mask(&pic2.mask2, pic2.ins); - if (!(pic2.level_sensitive & (1 << c))) - pic.pend &= ~(1 << c); - pic.ins |= (1 << 2); /*Cascade IRQ*/ - pic_update_mask(&pic.mask2, pic.ins); + if (!(pic2.level_sensitive & (1 << c))) + pic.pend &= ~(1 << c); + pic.ins |= (1 << 2); /*Cascade IRQ*/ + pic_update_mask(&pic.mask2, pic.ins); - pic_updatepending(); + pic_updatepending(); - if (pic2.icw4 & 0x02) - pic2_autoeoi(); + if (pic2.icw4 & 0x02) + pic2_autoeoi(); - return c + pic2.vector; - } - } - } else if (temp & (1 << c)) { - if (!(pic.level_sensitive & (1 << c))) - pic.pend &= ~(1 << c); - pic.ins |= (1 << c); - pic_update_mask(&pic.mask2, pic.ins); - pic_updatepending(); + return c + pic2.vector; + } + } + } else if (temp & (1 << c)) { + if (!(pic.level_sensitive & (1 << c))) + pic.pend &= ~(1 << c); + pic.ins |= (1 << c); + pic_update_mask(&pic.mask2, pic.ins); + pic_updatepending(); - if (pic.icw4 & 0x02) - pic_autoeoi(); - return c + pic.vector; - } - } - return 0xFF; + if (pic.icw4 & 0x02) + pic_autoeoi(); + return c + pic.vector; + } + } + return 0xFF; } void dumppic() { - pclog("PIC1 : MASK %02X PEND %02X INS %02X VECTOR %02X\n", pic.mask, pic.pend, pic.ins, pic.vector); - pclog("PIC2 : MASK %02X PEND %02X INS %02X VECTOR %02X\n", pic2.mask, pic2.pend, pic2.ins, pic2.vector); + pclog("PIC1 : MASK %02X PEND %02X INS %02X VECTOR %02X\n", pic.mask, pic.pend, pic.ins, pic.vector); + pclog("PIC2 : MASK %02X PEND %02X INS %02X VECTOR %02X\n", pic2.mask, pic2.pend, pic2.ins, pic2.vector); } - diff --git a/src/models/piix.c b/src/models/piix.c index 3cee3566..1e8eed09 100644 --- a/src/models/piix.c +++ b/src/models/piix.c @@ -1,5 +1,5 @@ /*PRD format : - + word 0 - base address word 1 - bits 1 - 15 = byte count, bit 31 = end of transfer */ @@ -16,11 +16,7 @@ #include "piix.h" #include "piix_pm.h" -enum { - TYPE_PIIX = 0, - TYPE_PIIX3, - TYPE_PIIX4 -}; +enum { TYPE_PIIX = 0, TYPE_PIIX3, TYPE_PIIX4 }; static piix_t piix; static uint8_t card_piix[256], card_piix_ide[256]; @@ -33,300 +29,311 @@ static void (*piix_nb_reset)(); #define REG_SMIREQ 0xaa #define SMICNTL_CSMIGATE (1 << 0) -#define SMIEN_APMC (1 << 7) +#define SMIEN_APMC (1 << 7) #define SMIREQ_RAPMC (1 << 7) void piix_write(int func, int addr, uint8_t val, void *priv) { -// pclog("piix_write: func=%d addr=%02x val=%02x %04x:%08x\n", func, addr, val, CS, pc); - if (func > ((piix.type == TYPE_PIIX4) ? 3 : 1)) - return; + // pclog("piix_write: func=%d addr=%02x val=%02x %04x:%08x\n", func, addr, val, CS, pc); + if (func > ((piix.type == TYPE_PIIX4) ? 3 : 1)) + return; - if (func == 1) /*IDE*/ - { - switch (addr) { - case 0x04:card_piix_ide[0x04] = (card_piix_ide[0x04] & ~5) | (val & 5); - break; - case 0x07:card_piix_ide[0x07] = (card_piix_ide[0x07] & ~0x38) | (val & 0x38); - break; - case 0x0d:card_piix_ide[0x0d] = val; - break; + if (func == 1) /*IDE*/ + { + switch (addr) { + case 0x04: + card_piix_ide[0x04] = (card_piix_ide[0x04] & ~5) | (val & 5); + break; + case 0x07: + card_piix_ide[0x07] = (card_piix_ide[0x07] & ~0x38) | (val & 0x38); + break; + case 0x0d: + card_piix_ide[0x0d] = val; + break; - case 0x20:card_piix_ide[0x20] = (val & ~0x0f) | 1; - break; - case 0x21:card_piix_ide[0x21] = val; - break; + case 0x20: + card_piix_ide[0x20] = (val & ~0x0f) | 1; + break; + case 0x21: + card_piix_ide[0x21] = val; + break; - case 0x40:card_piix_ide[0x40] = val; - break; - case 0x41:card_piix_ide[0x41] = val; - break; - case 0x42:card_piix_ide[0x42] = val; - break; - case 0x43:card_piix_ide[0x43] = val; - break; - } - if (addr == 4 || (addr & ~3) == 0x20) /*Bus master base address*/ - { - uint16_t base = (card_piix_ide[0x20] & 0xf0) | (card_piix_ide[0x21] << 8); - io_removehandler(0, 0x10000, sff_bus_master_read, NULL, NULL, sff_bus_master_write, NULL, NULL, piix_busmaster); - if (card_piix_ide[0x04] & 1) - io_sethandler(base, 0x10, sff_bus_master_read, NULL, NULL, sff_bus_master_write, NULL, NULL, piix_busmaster); - } - if (addr == 4 || addr == 0x41 || addr == 0x43) { - ide_pri_disable(); - ide_sec_disable(); - if (card_piix_ide[0x04] & 1) { - if (card_piix_ide[0x41] & 0x80) - ide_pri_enable(); - if (card_piix_ide[0x43] & 0x80) - ide_sec_enable(); - } - } -// pclog("PIIX write %02X %02X\n", addr, val); - } else if (func == 2) /*USB*/ - { - /*Not implemented*/ - } else if (func == 3) /*PM*/ - { - piix_pm_pci_write(addr, val, &piix); - } else { - if (addr >= 0x0f && addr < 0x4c) - return; + case 0x40: + card_piix_ide[0x40] = val; + break; + case 0x41: + card_piix_ide[0x41] = val; + break; + case 0x42: + card_piix_ide[0x42] = val; + break; + case 0x43: + card_piix_ide[0x43] = val; + break; + } + if (addr == 4 || (addr & ~3) == 0x20) /*Bus master base address*/ + { + uint16_t base = (card_piix_ide[0x20] & 0xf0) | (card_piix_ide[0x21] << 8); + io_removehandler(0, 0x10000, sff_bus_master_read, NULL, NULL, sff_bus_master_write, NULL, NULL, + piix_busmaster); + if (card_piix_ide[0x04] & 1) + io_sethandler(base, 0x10, sff_bus_master_read, NULL, NULL, sff_bus_master_write, NULL, NULL, + piix_busmaster); + } + if (addr == 4 || addr == 0x41 || addr == 0x43) { + ide_pri_disable(); + ide_sec_disable(); + if (card_piix_ide[0x04] & 1) { + if (card_piix_ide[0x41] & 0x80) + ide_pri_enable(); + if (card_piix_ide[0x43] & 0x80) + ide_sec_enable(); + } + } + // pclog("PIIX write %02X %02X\n", addr, val); + } else if (func == 2) /*USB*/ + { + /*Not implemented*/ + } else if (func == 3) /*PM*/ + { + piix_pm_pci_write(addr, val, &piix); + } else { + 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; + switch (addr) { + case 0x00: + case 0x01: + case 0x02: + case 0x03: + case 0x08: + case 0x09: + case 0x0a: + case 0x0b: + case 0x0e: + return; - case 0x60: -// pclog("IRQ routing %02x %02x\n", addr, 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("IRQ routing %02x %02x\n", addr, 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("IRQ routing %02x %02x\n", addr, 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("IRQ routing %02x %02x\n", addr, val); - if (val & 0x80) - pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); - else - pci_set_irq_routing(PCI_INTD, val & 0xf); - break; - case REG_SMIREQ: - if (piix.type <= TYPE_PIIX3) { - card_piix[addr] &= val; - return; - } - break; - case REG_SMIREQ + 1: - if (piix.type <= TYPE_PIIX3) { - card_piix[addr] &= val; - return; - } - break; - - } - card_piix[addr] = val; - } + case 0x60: + // pclog("IRQ routing %02x %02x\n", addr, 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("IRQ routing %02x %02x\n", addr, 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("IRQ routing %02x %02x\n", addr, 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("IRQ routing %02x %02x\n", addr, val); + if (val & 0x80) + pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); + else + pci_set_irq_routing(PCI_INTD, val & 0xf); + break; + case REG_SMIREQ: + if (piix.type <= TYPE_PIIX3) { + card_piix[addr] &= val; + return; + } + break; + case REG_SMIREQ + 1: + if (piix.type <= TYPE_PIIX3) { + card_piix[addr] &= val; + return; + } + break; + } + card_piix[addr] = val; + } } uint8_t piix_read(int func, int addr, void *priv) { -// pclog("piix_read: func=%d addr=%02x %04x:%08x\n", func, addr, CS, pc); - if (func > ((piix.type == TYPE_PIIX4) ? 3 : 1)) - return 0xff; + // pclog("piix_read: func=%d addr=%02x %04x:%08x\n", func, addr, CS, pc); + if (func > ((piix.type == TYPE_PIIX4) ? 3 : 1)) + return 0xff; - if (func == 1) /*IDE*/ - { -// pclog("PIIX IDE read %02X %02X\n", addr, card_piix_ide[addr]); - return card_piix_ide[addr]; - } else if (func == 2) /*USB*/ - return 0xff; /*Not implemented*/ - else if (func == 3) - return piix_pm_pci_read(addr, &piix); - else - return card_piix[addr]; + if (func == 1) /*IDE*/ + { + // pclog("PIIX IDE read %02X %02X\n", addr, card_piix_ide[addr]); + return card_piix_ide[addr]; + } else if (func == 2) /*USB*/ + return 0xff; /*Not implemented*/ + else if (func == 3) + return piix_pm_pci_read(addr, &piix); + else + return card_piix[addr]; } -uint8_t piix_rc_read(uint16_t port, void *p) { - return piix_rc; -} +uint8_t piix_rc_read(uint16_t port, void *p) { return piix_rc; } void piix_rc_write(uint16_t port, uint8_t val, void *p) { - if (val & 4) { - if (val & 2) /*Hard reset*/ - { - piix_nb_reset(); - keyboard_at_reset(); /*Reset keyboard controller to reset system flag*/ - ide_reset_devices(); - piix.pm.timer_offset = tsc; - resetx86(); - piix.pm.apmc = piix.pm.apms = 0; - } else - softresetx86(); - } + if (val & 4) { + if (val & 2) /*Hard reset*/ + { + piix_nb_reset(); + keyboard_at_reset(); /*Reset keyboard controller to reset system flag*/ + ide_reset_devices(); + piix.pm.timer_offset = tsc; + resetx86(); + piix.pm.apmc = piix.pm.apms = 0; + } else + softresetx86(); + } - piix_rc = val & ~4; + piix_rc = val & ~4; } -static uint8_t piix_92_read(uint16_t port, void *p) { - return piix.port_92; -} +static uint8_t piix_92_read(uint16_t port, void *p) { return piix.port_92; } static void piix_92_write(uint16_t port, uint8_t val, void *p) { - if ((mem_a20_alt ^ val) & 2) { - mem_a20_alt = val & 2; - mem_a20_recalc(); - } - if ((~piix.port_92 & val) & 1) { - softresetx86(); - cpu_set_edx(); - } - piix.port_92 = val; + if ((mem_a20_alt ^ val) & 2) { + mem_a20_alt = val & 2; + mem_a20_recalc(); + } + if ((~piix.port_92 & val) & 1) { + softresetx86(); + cpu_set_edx(); + } + piix.port_92 = val; } static uint8_t piix_apm_read(uint16_t port, void *p) { - piix_t *piix = (piix_t *)p; - uint8_t ret = 0xff; + piix_t *piix = (piix_t *)p; + uint8_t ret = 0xff; - switch (port) { - case 0xb2:ret = piix->pm.apmc; - break; + switch (port) { + case 0xb2: + ret = piix->pm.apmc; + break; - case 0xb3:ret = piix->pm.apms; - break; - } -// pclog("piix_apm_read: port=%04x ret=%02x\n", port, ret); - return ret; + case 0xb3: + ret = piix->pm.apms; + break; + } + // pclog("piix_apm_read: port=%04x ret=%02x\n", port, ret); + return ret; } static void piix_apm_write(uint16_t port, uint8_t val, void *p) { - piix_t *piix = (piix_t *)p; + piix_t *piix = (piix_t *)p; -// pclog("piix_apm_write: port=%04x val=%02x\n", port, val); + // pclog("piix_apm_write: port=%04x val=%02x\n", port, val); - switch (port) { - case 0xb2:piix->pm.apmc = val; - if (card_piix[REG_SMIEN] & SMIEN_APMC) { - card_piix[REG_SMIREQ] |= SMIREQ_RAPMC; -// pclog("APMC write causes SMI\n"); - if (card_piix[REG_SMICNTL] & SMICNTL_CSMIGATE) - x86_smi_trigger(); - } - break; + switch (port) { + case 0xb2: + piix->pm.apmc = val; + if (card_piix[REG_SMIEN] & SMIEN_APMC) { + card_piix[REG_SMIREQ] |= SMIREQ_RAPMC; + // pclog("APMC write causes SMI\n"); + if (card_piix[REG_SMICNTL] & SMICNTL_CSMIGATE) + x86_smi_trigger(); + } + break; - case 0xb3:piix->pm.apms = val; - break; - } + case 0xb3: + piix->pm.apms = val; + break; + } } static void piix_common_init(int card, int pci_a, int pci_b, int pci_c, int pci_d, void (*nb_reset)()) { - memset(&piix, 0, sizeof(piix_t)); + memset(&piix, 0, sizeof(piix_t)); - pci_add_specific(card, piix_read, piix_write, NULL); + pci_add_specific(card, piix_read, piix_write, NULL); - memset(card_piix, 0, 256); - card_piix[0x00] = 0x86; - card_piix[0x01] = 0x80; /*Intel*/ - card_piix[0x02] = 0x2e; - card_piix[0x03] = 0x12; /*82371FB (PIIX)*/ - card_piix[0x04] = 0x07; - card_piix[0x05] = 0x00; - card_piix[0x06] = 0x80; - card_piix[0x07] = 0x02; - card_piix[0x08] = 0x00; /*A0 stepping*/ - card_piix[0x09] = 0x00; - card_piix[0x0a] = 0x01; - card_piix[0x0b] = 0x06; - card_piix[0x0e] = 0x80; /*Multi-function device*/ - card_piix[0x4c] = 0x4d; - card_piix[0x4e] = 0x03; - card_piix[0x60] = card_piix[0x61] = card_piix[0x62] = card_piix[0x63] = 0x80; - card_piix[0x69] = 0x02; - card_piix[0x70] = card_piix[0x71] = 0x80; - card_piix[0x76] = card_piix[0x77] = 0x0c; - card_piix[0x78] = 0x02; - card_piix[0x79] = 0x00; - card_piix[0xa0] = 0x08; - card_piix[0xa2] = card_piix[0xa3] = 0x00; - card_piix[0xa4] = card_piix[0xa5] = card_piix[0xa6] = card_piix[0xa7] = 0x00; - card_piix[0xa8] = 0x0f; - card_piix[0xaa] = card_piix[0xab] = 0x00; - card_piix[0xac] = 0x00; - card_piix[0xae] = 0x00; + memset(card_piix, 0, 256); + card_piix[0x00] = 0x86; + card_piix[0x01] = 0x80; /*Intel*/ + card_piix[0x02] = 0x2e; + card_piix[0x03] = 0x12; /*82371FB (PIIX)*/ + card_piix[0x04] = 0x07; + card_piix[0x05] = 0x00; + card_piix[0x06] = 0x80; + card_piix[0x07] = 0x02; + card_piix[0x08] = 0x00; /*A0 stepping*/ + card_piix[0x09] = 0x00; + card_piix[0x0a] = 0x01; + card_piix[0x0b] = 0x06; + card_piix[0x0e] = 0x80; /*Multi-function device*/ + card_piix[0x4c] = 0x4d; + card_piix[0x4e] = 0x03; + card_piix[0x60] = card_piix[0x61] = card_piix[0x62] = card_piix[0x63] = 0x80; + card_piix[0x69] = 0x02; + card_piix[0x70] = card_piix[0x71] = 0x80; + card_piix[0x76] = card_piix[0x77] = 0x0c; + card_piix[0x78] = 0x02; + card_piix[0x79] = 0x00; + card_piix[0xa0] = 0x08; + card_piix[0xa2] = card_piix[0xa3] = 0x00; + card_piix[0xa4] = card_piix[0xa5] = card_piix[0xa6] = card_piix[0xa7] = 0x00; + card_piix[0xa8] = 0x0f; + card_piix[0xaa] = card_piix[0xab] = 0x00; + card_piix[0xac] = 0x00; + card_piix[0xae] = 0x00; - card_piix_ide[0x00] = 0x86; - card_piix_ide[0x01] = 0x80; /*Intel*/ - card_piix_ide[0x02] = 0x30; - card_piix_ide[0x03] = 0x12; /*82371FB (PIIX)*/ - card_piix_ide[0x04] = 0x02; - card_piix_ide[0x05] = 0x00; - card_piix_ide[0x06] = 0x80; - card_piix_ide[0x07] = 0x02; - card_piix_ide[0x08] = 0x00; - card_piix_ide[0x09] = 0x80; - card_piix_ide[0x0a] = 0x01; - card_piix_ide[0x0b] = 0x01; - card_piix_ide[0x0d] = 0x00; - card_piix_ide[0x0e] = 0x00; - card_piix_ide[0x20] = 0x01; - card_piix_ide[0x21] = card_piix_ide[0x22] = card_piix_ide[0x23] = 0x00; /*Bus master interface base address*/ - card_piix_ide[0x40] = card_piix_ide[0x41] = 0x00; - card_piix_ide[0x42] = card_piix_ide[0x43] = 0x00; + card_piix_ide[0x00] = 0x86; + card_piix_ide[0x01] = 0x80; /*Intel*/ + card_piix_ide[0x02] = 0x30; + card_piix_ide[0x03] = 0x12; /*82371FB (PIIX)*/ + card_piix_ide[0x04] = 0x02; + card_piix_ide[0x05] = 0x00; + card_piix_ide[0x06] = 0x80; + card_piix_ide[0x07] = 0x02; + card_piix_ide[0x08] = 0x00; + card_piix_ide[0x09] = 0x80; + card_piix_ide[0x0a] = 0x01; + card_piix_ide[0x0b] = 0x01; + card_piix_ide[0x0d] = 0x00; + card_piix_ide[0x0e] = 0x00; + card_piix_ide[0x20] = 0x01; + card_piix_ide[0x21] = card_piix_ide[0x22] = card_piix_ide[0x23] = 0x00; /*Bus master interface base address*/ + card_piix_ide[0x40] = card_piix_ide[0x41] = 0x00; + card_piix_ide[0x42] = card_piix_ide[0x43] = 0x00; - sff_bus_master_init(piix_busmaster); + sff_bus_master_init(piix_busmaster); - pci_set_card_routing(pci_a, PCI_INTA); - pci_set_card_routing(pci_b, PCI_INTB); - pci_set_card_routing(pci_c, PCI_INTC); - pci_set_card_routing(pci_d, PCI_INTD); + pci_set_card_routing(pci_a, PCI_INTA); + pci_set_card_routing(pci_b, PCI_INTB); + pci_set_card_routing(pci_c, PCI_INTC); + pci_set_card_routing(pci_d, PCI_INTD); - ide_pri_disable(); - ide_sec_disable(); + ide_pri_disable(); + ide_sec_disable(); - pic_init_elcrx(); + pic_init_elcrx(); - io_sethandler(0x0cf9, 0x0001, piix_rc_read, NULL, NULL, piix_rc_write, NULL, NULL, NULL); - piix_nb_reset = nb_reset; + io_sethandler(0x0cf9, 0x0001, piix_rc_read, NULL, NULL, piix_rc_write, NULL, NULL, NULL); + piix_nb_reset = nb_reset; - piix.type = TYPE_PIIX3; + piix.type = TYPE_PIIX3; } void piix_init(int card, int pci_a, int pci_b, int pci_c, int pci_d, void (*nb_reset)()) { - piix_common_init(card, pci_a, pci_b, pci_c, pci_d, nb_reset); + piix_common_init(card, pci_a, pci_b, pci_c, pci_d, nb_reset); - io_sethandler(0x00b2, 0x0002, piix_apm_read, NULL, NULL, piix_apm_write, NULL, NULL, &piix); + io_sethandler(0x00b2, 0x0002, piix_apm_read, NULL, NULL, piix_apm_write, NULL, NULL, &piix); } void piix4_init(int card, int pci_a, int pci_b, int pci_c, int pci_d, void (*nb_reset)()) { - piix_init(card, pci_a, pci_b, pci_c, pci_d, nb_reset); + piix_init(card, pci_a, pci_b, pci_c, pci_d, nb_reset); - piix.type = TYPE_PIIX4; + piix.type = TYPE_PIIX4; - card_piix[0x02] = 0x10; - card_piix[0x03] = 0x71; /*82371EB (PIIX4)*/ + card_piix[0x02] = 0x10; + card_piix[0x03] = 0x71; /*82371EB (PIIX4)*/ - card_piix_ide[0x02] = 0x11; - card_piix_ide[0x03] = 0x71; /*82371EB (PIIX4)*/ + card_piix_ide[0x02] = 0x11; + card_piix_ide[0x03] = 0x71; /*82371EB (PIIX4)*/ - io_sethandler(0x0092, 0x0001, piix_92_read, NULL, NULL, piix_92_write, NULL, NULL, NULL); - piix_pm_init(&piix); + io_sethandler(0x0092, 0x0001, piix_92_read, NULL, NULL, piix_92_write, NULL, NULL, NULL); + piix_pm_init(&piix); } diff --git a/src/models/piix_pm.c b/src/models/piix_pm.c index 5b21abe6..e4c0c9b2 100644 --- a/src/models/piix_pm.c +++ b/src/models/piix_pm.c @@ -11,358 +11,413 @@ #define GLBSTS_APM_STS (1 << 5) static uint8_t dev13_read(uint16_t addr, void *p) { - piix_t *piix = (piix_t *)p; + piix_t *piix = (piix_t *)p; -// pclog("dev13_read: addr=%04x %08x\n", addr, piix.pm.devctl); - if (piix->pm.devctl & DEVCTL_TRP_EN_DEV13) { - piix->pm.devsts |= DEVSTS_TRP_STS_DEV13; - x86_smi_trigger(); - } - return 0xff; + // pclog("dev13_read: addr=%04x %08x\n", addr, piix.pm.devctl); + if (piix->pm.devctl & DEVCTL_TRP_EN_DEV13) { + piix->pm.devsts |= DEVSTS_TRP_STS_DEV13; + x86_smi_trigger(); + } + return 0xff; } static void dev13_write(uint16_t addr, uint8_t val, void *p) { - piix_t *piix = (piix_t *)p; + piix_t *piix = (piix_t *)p; -// pclog("dev13_write: addr=%04x val=%02x %08x\n", addr, val, piix.pm.devctl); - if (piix->pm.devctl & DEVCTL_TRP_EN_DEV13) { - piix->pm.devsts |= DEVSTS_TRP_STS_DEV13; - x86_smi_trigger(); - } + // pclog("dev13_write: addr=%04x val=%02x %08x\n", addr, val, piix.pm.devctl); + if (piix->pm.devctl & DEVCTL_TRP_EN_DEV13) { + piix->pm.devsts |= DEVSTS_TRP_STS_DEV13; + x86_smi_trigger(); + } } static void dev13_recalc(piix_t *piix) { - if (piix->pm.dev13_enable) - io_removehandler(piix->pm.dev13_base, piix->pm.dev13_size, - dev13_read, NULL, NULL, - dev13_write, NULL, NULL, piix); - piix->pm.dev13_base = piix->card_pm[0x70] | (piix->card_pm[0x71] << 8); - piix->pm.dev13_size = (piix->card_pm[0x72] & 0xf) + 1; - piix->pm.dev13_enable = piix->card_pm[0x72] & 0x10; - if (piix->pm.dev13_enable) - io_sethandler(piix->pm.dev13_base, piix->pm.dev13_size, - dev13_read, NULL, NULL, - dev13_write, NULL, NULL, piix); + if (piix->pm.dev13_enable) + io_removehandler(piix->pm.dev13_base, piix->pm.dev13_size, dev13_read, NULL, NULL, dev13_write, NULL, NULL, piix); + piix->pm.dev13_base = piix->card_pm[0x70] | (piix->card_pm[0x71] << 8); + piix->pm.dev13_size = (piix->card_pm[0x72] & 0xf) + 1; + piix->pm.dev13_enable = piix->card_pm[0x72] & 0x10; + if (piix->pm.dev13_enable) + io_sethandler(piix->pm.dev13_base, piix->pm.dev13_size, dev13_read, NULL, NULL, dev13_write, NULL, NULL, piix); } static void piix_pm_write(uint16_t port, uint8_t val, void *p) { - piix_t *piix = (piix_t *)p; + piix_t *piix = (piix_t *)p; -// pclog("piix_pm_write: port=%04x val=%02x\n", port, val); - switch (port & 0x3f) { - case 0x00:piix->pm.pmsts &= ~(val & 0x31); - break; - case 0x01:piix->pm.pmsts &= ~((val & 0x8d) << 8); - break; + // pclog("piix_pm_write: port=%04x val=%02x\n", port, val); + switch (port & 0x3f) { + case 0x00: + piix->pm.pmsts &= ~(val & 0x31); + break; + case 0x01: + piix->pm.pmsts &= ~((val & 0x8d) << 8); + break; - case 0x02:piix->pm.pmen = (piix->pm.pmen & ~0xff) | (val & 0x21); - break; - case 0x03:piix->pm.pmen = (piix->pm.pmen & ~0xff00) | ((val & 0x05) << 8); - break; + case 0x02: + piix->pm.pmen = (piix->pm.pmen & ~0xff) | (val & 0x21); + break; + case 0x03: + piix->pm.pmen = (piix->pm.pmen & ~0xff00) | ((val & 0x05) << 8); + break; - case 0x04:piix->pm.pmcntrl = (piix->pm.pmcntrl & ~0xff) | (val & 0x03); - break; - case 0x05:pclog("PM reg 5 write %02x\n", val); - if (val & 0x20) { - pclog("PIIX transition to power state %i\n", (val >> 2) & 7); - if (val == 0x20) { - pclog("Power off\n"); - stop_emulation_now(); - } - } - piix->pm.pmcntrl = (piix->pm.pmcntrl & ~0xff00) | ((val & 0x1c) << 8); - break; + case 0x04: + piix->pm.pmcntrl = (piix->pm.pmcntrl & ~0xff) | (val & 0x03); + break; + case 0x05: + pclog("PM reg 5 write %02x\n", val); + if (val & 0x20) { + pclog("PIIX transition to power state %i\n", (val >> 2) & 7); + if (val == 0x20) { + pclog("Power off\n"); + stop_emulation_now(); + } + } + piix->pm.pmcntrl = (piix->pm.pmcntrl & ~0xff00) | ((val & 0x1c) << 8); + break; - case 0x0c: - case 0x0d:piix->pm.gpsts &= ~(val << ((port & 1) * 8)); - break; + case 0x0c: + case 0x0d: + piix->pm.gpsts &= ~(val << ((port & 1) * 8)); + break; - case 0x0e:piix->pm.pmen = (piix->pm.pmen & ~0xff) | (val & 0x01); - break; - case 0x0f:piix->pm.pmen = (piix->pm.pmen & ~0xff00) | ((val & 0x0f) << 8); - break; + case 0x0e: + piix->pm.pmen = (piix->pm.pmen & ~0xff) | (val & 0x01); + break; + case 0x0f: + piix->pm.pmen = (piix->pm.pmen & ~0xff00) | ((val & 0x0f) << 8); + break; - case 0x10:piix->pm.pcntrl = (piix->pm.pcntrl & ~0xff) | (val & 0x1e); - break; - case 0x11:piix->pm.pcntrl = (piix->pm.pcntrl & ~0xff00) | ((val & 0x3e) << 8); - break; + case 0x10: + piix->pm.pcntrl = (piix->pm.pcntrl & ~0xff) | (val & 0x1e); + break; + case 0x11: + piix->pm.pcntrl = (piix->pm.pcntrl & ~0xff00) | ((val & 0x3e) << 8); + break; - case 0x18:piix->pm.glbsts &= ~(val & 0x25); - break; - case 0x19:piix->pm.glbsts &= ~((val & 0x0d) << 8); - break; + case 0x18: + piix->pm.glbsts &= ~(val & 0x25); + break; + case 0x19: + piix->pm.glbsts &= ~((val & 0x0d) << 8); + break; - case 0x1c: - case 0x1d: - case 0x1e: - case 0x1f:piix->pm.devsts &= ~(val << ((port & 3) * 8)); - break; + case 0x1c: + case 0x1d: + case 0x1e: + case 0x1f: + piix->pm.devsts &= ~(val << ((port & 3) * 8)); + break; - case 0x20:piix->pm.glben = (piix->pm.glben & ~0xff) | (val & 0x01); - break; - case 0x21:piix->pm.glben = (piix->pm.glben & ~0xff00) | ((val & 0x0f) << 8); - break; + case 0x20: + piix->pm.glben = (piix->pm.glben & ~0xff) | (val & 0x01); + break; + case 0x21: + piix->pm.glben = (piix->pm.glben & ~0xff00) | ((val & 0x0f) << 8); + break; - case 0x28:piix->pm.glbctl = (piix->pm.glbctl & ~0xff) | (val & 0x05); - break; - case 0x29:piix->pm.glbctl = (piix->pm.glbctl & ~0xff00) | ((val & 0xff) << 8); - break; - case 0x2a:piix->pm.glbctl = (piix->pm.glbctl & ~0xff0000) | ((val & 0x01) << 16); - break; - case 0x2b:piix->pm.glbctl = (piix->pm.glbctl & ~0xff000000) | ((val & 0x07) << 24); - break; + case 0x28: + piix->pm.glbctl = (piix->pm.glbctl & ~0xff) | (val & 0x05); + break; + case 0x29: + piix->pm.glbctl = (piix->pm.glbctl & ~0xff00) | ((val & 0xff) << 8); + break; + case 0x2a: + piix->pm.glbctl = (piix->pm.glbctl & ~0xff0000) | ((val & 0x01) << 16); + break; + case 0x2b: + piix->pm.glbctl = (piix->pm.glbctl & ~0xff000000) | ((val & 0x07) << 24); + break; - case 0x2c:piix->pm.devctl = (piix->pm.devctl & ~0xff) | val; - break; - case 0x2d:piix->pm.devctl = (piix->pm.devctl & ~0xff00) | (val << 8); - break; - case 0x2e:piix->pm.devctl = (piix->pm.devctl & ~0xff0000) | (val << 16); - break; - case 0x2f:piix->pm.devctl = (piix->pm.devctl & ~0xff000000) | ((val & 0x0f) << 24); - break; + case 0x2c: + piix->pm.devctl = (piix->pm.devctl & ~0xff) | val; + break; + case 0x2d: + piix->pm.devctl = (piix->pm.devctl & ~0xff00) | (val << 8); + break; + case 0x2e: + piix->pm.devctl = (piix->pm.devctl & ~0xff0000) | (val << 16); + break; + case 0x2f: + piix->pm.devctl = (piix->pm.devctl & ~0xff000000) | ((val & 0x0f) << 24); + break; - case 0x34:piix->pm.gporeg = (piix->pm.gporeg & ~0xff) | val; - break; - case 0x35:piix->pm.gporeg = (piix->pm.gporeg & ~0xff00) | (val << 8); - break; - case 0x36:piix->pm.gporeg = (piix->pm.gporeg & ~0xff0000) | (val << 16); - break; - case 0x37:piix->pm.gporeg = (piix->pm.gporeg & ~0xff000000) | (val << 24); - break; - } + case 0x34: + piix->pm.gporeg = (piix->pm.gporeg & ~0xff) | val; + break; + case 0x35: + piix->pm.gporeg = (piix->pm.gporeg & ~0xff00) | (val << 8); + break; + case 0x36: + piix->pm.gporeg = (piix->pm.gporeg & ~0xff0000) | (val << 16); + break; + case 0x37: + piix->pm.gporeg = (piix->pm.gporeg & ~0xff000000) | (val << 24); + break; + } } static uint8_t piix_pm_read(uint16_t port, void *p) { - piix_t *piix = (piix_t *)p; - uint8_t ret = 0xff; + piix_t *piix = (piix_t *)p; + uint8_t ret = 0xff; - switch (port & 0x3f) { - case 0x00: - case 0x01:ret = piix->pm.pmsts >> ((port & 1) * 8); - break; + switch (port & 0x3f) { + case 0x00: + case 0x01: + ret = piix->pm.pmsts >> ((port & 1) * 8); + break; - case 0x02: - case 0x03:ret = piix->pm.pmen >> ((port & 1) * 8); - break; + case 0x02: + case 0x03: + ret = piix->pm.pmen >> ((port & 1) * 8); + break; - case 0x04: - case 0x05:ret = piix->pm.pmcntrl >> ((port & 1) * 8); - break; + case 0x04: + case 0x05: + ret = piix->pm.pmcntrl >> ((port & 1) * 8); + break; - case 0x08: - case 0x09: - case 0x0a: - case 0x0b: { - uint64_t timer = tsc - piix->pm.timer_offset; - uint32_t pm_timer = (timer * 3579545) / cpu_get_speed(); + case 0x08: + case 0x09: + case 0x0a: + case 0x0b: { + uint64_t timer = tsc - piix->pm.timer_offset; + uint32_t pm_timer = (timer * 3579545) / cpu_get_speed(); - ret = pm_timer >> ((port & 3) * 8); - break; - } + ret = pm_timer >> ((port & 3) * 8); + break; + } - case 0x0c: - case 0x0d:ret = piix->pm.gpsts >> ((port & 1) * 8); - break; + case 0x0c: + case 0x0d: + ret = piix->pm.gpsts >> ((port & 1) * 8); + break; - case 0x0e: - case 0x0f:ret = piix->pm.pmen >> ((port & 1) * 8); - break; + case 0x0e: + case 0x0f: + ret = piix->pm.pmen >> ((port & 1) * 8); + break; - case 0x10: - case 0x11: - case 0x12: - case 0x13:ret = piix->pm.pcntrl >> ((port & 3) * 8); - break; + case 0x10: + case 0x11: + case 0x12: + case 0x13: + ret = piix->pm.pcntrl >> ((port & 3) * 8); + break; - case 0x14:ret = 0; - break; - case 0x15:ret = 0; - break; + case 0x14: + ret = 0; + break; + case 0x15: + ret = 0; + break; - case 0x18: - case 0x19:ret = piix->pm.glbsts >> ((port & 1) * 8); - break; + case 0x18: + case 0x19: + ret = piix->pm.glbsts >> ((port & 1) * 8); + break; - case 0x1c: - case 0x1d: - case 0x1e: - case 0x1f:ret = piix->pm.devsts >> ((port & 3) * 8); - break; + case 0x1c: + case 0x1d: + case 0x1e: + case 0x1f: + ret = piix->pm.devsts >> ((port & 3) * 8); + break; - case 0x20: - case 0x21:ret = piix->pm.glben >> ((port & 1) * 8); - break; + case 0x20: + case 0x21: + ret = piix->pm.glben >> ((port & 1) * 8); + break; - case 0x28: - case 0x29: - case 0x2a: - case 0x2b:ret = piix->pm.glbctl >> ((port & 3) * 8); - break; + case 0x28: + case 0x29: + case 0x2a: + case 0x2b: + ret = piix->pm.glbctl >> ((port & 3) * 8); + break; - case 0x2c: - case 0x2d: - case 0x2e: - case 0x2f:ret = piix->pm.devctl >> ((port & 3) * 8); - break; + case 0x2c: + case 0x2d: + case 0x2e: + case 0x2f: + ret = piix->pm.devctl >> ((port & 3) * 8); + break; - case 0x30:ret = 0x00; - break; - case 0x31:ret = 0x00; - break; - case 0x32: - /*GA686BX - bit 1 = low battery*/ - ret = 0x00; - break; + case 0x30: + ret = 0x00; + break; + case 0x31: + ret = 0x00; + break; + case 0x32: + /*GA686BX - bit 1 = low battery*/ + ret = 0x00; + break; - case 0x34: - case 0x35: - case 0x36: - case 0x37:ret = piix->pm.gporeg >> ((port & 3) * 8); - break; + case 0x34: + case 0x35: + case 0x36: + case 0x37: + ret = piix->pm.gporeg >> ((port & 3) * 8); + break; -// default: -// fatal("piix_pm_read: unknown read %04x\n", port); - } + // default: + // fatal("piix_pm_read: unknown read %04x\n", port); + } -// pclog("piix_pm_read: port=%04x val=%02x\n", port, ret); - return ret; + // pclog("piix_pm_read: port=%04x val=%02x\n", port, ret); + return ret; } static void piix_smbus_write(uint16_t port, uint8_t val, void *p) { - piix_t *piix = (piix_t *)p; -// pclog("piix_smbus_write: port=%04x val=%02x\n", port, val); + piix_t *piix = (piix_t *)p; + // pclog("piix_smbus_write: port=%04x val=%02x\n", port, val); - switch (port & 0xf) { - case 0x2:piix->smbus.host_ctrl = (val & 0x5f) | (piix->smbus.host_ctrl & 0x40); - break; - } + switch (port & 0xf) { + case 0x2: + piix->smbus.host_ctrl = (val & 0x5f) | (piix->smbus.host_ctrl & 0x40); + break; + } } static uint8_t piix_smbus_read(uint16_t port, void *p) { - piix_t *piix = (piix_t *)p; - uint8_t ret = 0xff; + piix_t *piix = (piix_t *)p; + uint8_t ret = 0xff; - switch (port & 0x0f) { - case 0x0:ret = 0; - break; + switch (port & 0x0f) { + case 0x0: + ret = 0; + break; - case 0x2:ret = piix->smbus.host_ctrl; - break; + case 0x2: + ret = piix->smbus.host_ctrl; + break; - case 0x5:ret = 0; - break; + case 0x5: + ret = 0; + break; -// default: -// fatal("piix_smbus_read: unknown read %04x\n", port); - } + // default: + // fatal("piix_smbus_read: unknown read %04x\n", port); + } - return ret; + return ret; } static uint8_t piix4_apm_read(uint16_t port, void *p) { - piix_t *piix = (piix_t *)p; - uint8_t ret = 0xff; + piix_t *piix = (piix_t *)p; + uint8_t ret = 0xff; - switch (port) { - case 0xb2:ret = piix->pm.apmc; - break; + switch (port) { + case 0xb2: + ret = piix->pm.apmc; + break; - case 0xb3:ret = piix->pm.apms; - break; - } -// pclog("piix_apm_read: port=%04x ret=%02x\n", port, ret); - return ret; + case 0xb3: + ret = piix->pm.apms; + break; + } + // pclog("piix_apm_read: port=%04x ret=%02x\n", port, ret); + return ret; } static void piix4_apm_write(uint16_t port, uint8_t val, void *p) { - piix_t *piix = (piix_t *)p; + piix_t *piix = (piix_t *)p; -// pclog("piix_apm_write: port=%04x val=%02x\n", port, val); + // pclog("piix_apm_write: port=%04x val=%02x\n", port, val); - switch (port) { - case 0xb2:piix->pm.apmc = val; - if (piix->card_pm[0x5b] & (1 << 1)) { - piix->pm.glbsts |= GLBSTS_APM_STS; -// pclog("APMC write causes SMI\n"); - x86_smi_trigger(); - } - break; + switch (port) { + case 0xb2: + piix->pm.apmc = val; + if (piix->card_pm[0x5b] & (1 << 1)) { + piix->pm.glbsts |= GLBSTS_APM_STS; + // pclog("APMC write causes SMI\n"); + x86_smi_trigger(); + } + break; - case 0xb3:piix->pm.apms = val; - break; - } + case 0xb3: + piix->pm.apms = val; + break; + } } static void pm_clear_io(piix_t *piix) { - io_removehandler(piix->pmba, 0x0040, piix_pm_read, NULL, NULL, piix_pm_write, NULL, NULL, piix); - io_removehandler(piix->smbba, 0x0010, piix_smbus_read, NULL, NULL, piix_smbus_write, NULL, NULL, piix); + io_removehandler(piix->pmba, 0x0040, piix_pm_read, NULL, NULL, piix_pm_write, NULL, NULL, piix); + io_removehandler(piix->smbba, 0x0010, piix_smbus_read, NULL, NULL, piix_smbus_write, NULL, NULL, piix); } static void pm_set_io(piix_t *piix) { -// pclog("pm_set_io: %02x %04x\n", piix.card_pm[0x04], piix.smbba); - if ((piix->card_pm[0x04] & 0x01) && piix->pmba) { -// pclog("PMBA=%04x\n", piix.pmba); - io_sethandler(piix->pmba, 0x0040, piix_pm_read, NULL, NULL, piix_pm_write, NULL, NULL, piix); - } - if ((piix->card_pm[0x04] & 0x01) && piix->smbba) { -// pclog("SMBBA=%04x\n", piix.smbba); - io_sethandler(piix->smbba, 0x0010, piix_smbus_read, NULL, NULL, piix_smbus_write, NULL, NULL, piix); - } + // pclog("pm_set_io: %02x %04x\n", piix.card_pm[0x04], piix.smbba); + if ((piix->card_pm[0x04] & 0x01) && piix->pmba) { + // pclog("PMBA=%04x\n", piix.pmba); + io_sethandler(piix->pmba, 0x0040, piix_pm_read, NULL, NULL, piix_pm_write, NULL, NULL, piix); + } + if ((piix->card_pm[0x04] & 0x01) && piix->smbba) { + // pclog("SMBBA=%04x\n", piix.smbba); + io_sethandler(piix->smbba, 0x0010, piix_smbus_read, NULL, NULL, piix_smbus_write, NULL, NULL, piix); + } } void piix_pm_pci_write(int addr, uint8_t val, void *p) { - piix_t *piix = (piix_t *)p; + piix_t *piix = (piix_t *)p; - switch (addr) { - case 0x04:pm_clear_io(piix); - piix->card_pm[0x04] = val & 1; - pm_set_io(piix); - break; - case 0x40:pm_clear_io(piix); - piix->pmba = (piix->pmba & 0xff00) | (val & 0xc0); - pm_set_io(piix); - break; - case 0x41:pm_clear_io(piix); - piix->pmba = (piix->pmba & 0xc0) | (val << 8); - pm_set_io(piix); - break; - case 0x58: - case 0x59: - case 0x5b: - case 0x5c:piix->card_pm[addr] = val; - break; - case 0x70: - case 0x71: - case 0x72:piix->card_pm[addr] = val; - dev13_recalc(piix); - break; - case 0x90:pm_clear_io(piix); - piix->smbba = (piix->smbba & 0xff00) | (val & 0xf0); - pm_set_io(piix); - break; - case 0x91:pm_clear_io(piix); - piix->smbba = (piix->smbba & 0xf0) | (val << 8); - pm_set_io(piix); - break; - } + switch (addr) { + case 0x04: + pm_clear_io(piix); + piix->card_pm[0x04] = val & 1; + pm_set_io(piix); + break; + case 0x40: + pm_clear_io(piix); + piix->pmba = (piix->pmba & 0xff00) | (val & 0xc0); + pm_set_io(piix); + break; + case 0x41: + pm_clear_io(piix); + piix->pmba = (piix->pmba & 0xc0) | (val << 8); + pm_set_io(piix); + break; + case 0x58: + case 0x59: + case 0x5b: + case 0x5c: + piix->card_pm[addr] = val; + break; + case 0x70: + case 0x71: + case 0x72: + piix->card_pm[addr] = val; + dev13_recalc(piix); + break; + case 0x90: + pm_clear_io(piix); + piix->smbba = (piix->smbba & 0xff00) | (val & 0xf0); + pm_set_io(piix); + break; + case 0x91: + pm_clear_io(piix); + piix->smbba = (piix->smbba & 0xf0) | (val << 8); + pm_set_io(piix); + break; + } } uint8_t piix_pm_pci_read(int addr, void *p) { - piix_t *piix = (piix_t *)p; + piix_t *piix = (piix_t *)p; - return piix->card_pm[addr]; + return piix->card_pm[addr]; } void piix_pm_init(piix_t *piix) { - memset(&piix->card_pm, 0, sizeof(piix->card_pm)); - piix->card_pm[0x00] = 0x86; - piix->card_pm[0x01] = 0x80; /*Intel*/ - piix->card_pm[0x02] = 0x13; - piix->card_pm[0x03] = 0x71; /*82371EB (PIIX4)*/ - piix->card_pm[0x06] = 0x80; - piix->card_pm[0x07] = 0x02; - piix->card_pm[0x09] = 0x00; - piix->card_pm[0x0a] = 0x80; - piix->card_pm[0x0b] = 0x06; /*Bridge device*/ - piix->card_pm[0x3d] = 0x01; /*IRQA*/ - piix->card_pm[0x40] = 0x01; - piix->card_pm[0x90] = 0x01; - piix->pm.timer_offset = 0; - piix->pm.gporeg = 0x7fffbfff; + memset(&piix->card_pm, 0, sizeof(piix->card_pm)); + piix->card_pm[0x00] = 0x86; + piix->card_pm[0x01] = 0x80; /*Intel*/ + piix->card_pm[0x02] = 0x13; + piix->card_pm[0x03] = 0x71; /*82371EB (PIIX4)*/ + piix->card_pm[0x06] = 0x80; + piix->card_pm[0x07] = 0x02; + piix->card_pm[0x09] = 0x00; + piix->card_pm[0x0a] = 0x80; + piix->card_pm[0x0b] = 0x06; /*Bridge device*/ + piix->card_pm[0x3d] = 0x01; /*IRQA*/ + piix->card_pm[0x40] = 0x01; + piix->card_pm[0x90] = 0x01; + piix->pm.timer_offset = 0; + piix->pm.gporeg = 0x7fffbfff; - io_sethandler(0x00b2, 0x0002, piix4_apm_read, NULL, NULL, piix4_apm_write, NULL, NULL, piix); + io_sethandler(0x00b2, 0x0002, piix4_apm_read, NULL, NULL, piix4_apm_write, NULL, NULL, piix); } diff --git a/src/models/pit.c b/src/models/pit.c index bcaa259c..eb3b1608 100644 --- a/src/models/pit.c +++ b/src/models/pit.c @@ -18,7 +18,7 @@ #include "model.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!*/ -//Tyrian writes 4300 or 17512 +// Tyrian writes 4300 or 17512 int displine; uint64_t PITCONST; @@ -32,579 +32,587 @@ float isa_timing, bus_timing; int firsttime = 1; void setpitclock(float clock) { -// printf("PIT clock %f\n",clock); - cpuclock = clock; - PITCONST = (uint64_t)(clock / 1193182.0 * (float)(1ull << 32)); - CGACONST = (uint64_t)((clock / (19687503.0 / 11.0)) * (float)(1ull << 32)); - MDACONST = (uint64_t)((clock / 2032125.0) * (float)(1ull << 32)); - VGACONST1 = (uint64_t)((clock / 25175000.0) * (float)(1ull << 32)); - VGACONST2 = (uint64_t)((clock / 28322000.0) * (float)(1ull << 32)); - isa_timing = clock / 8000000.0; - bus_timing = clock / (double)cpu_busspeed; - video_updatetiming(); -// pclog("PITCONST=%f CGACONST=%f\n", PITCONST, CGACONST); -// pclog("CPUMULTI=%g\n", ((14318184.0*(double)(1 << TIMER_SHIFT)) / (double)models[model]->cpu[cpu_manufacturer].cpus[cpu].rspeed)); + // printf("PIT clock %f\n",clock); + cpuclock = clock; + PITCONST = (uint64_t)(clock / 1193182.0 * (float)(1ull << 32)); + CGACONST = (uint64_t)((clock / (19687503.0 / 11.0)) * (float)(1ull << 32)); + MDACONST = (uint64_t)((clock / 2032125.0) * (float)(1ull << 32)); + VGACONST1 = (uint64_t)((clock / 25175000.0) * (float)(1ull << 32)); + VGACONST2 = (uint64_t)((clock / 28322000.0) * (float)(1ull << 32)); + isa_timing = clock / 8000000.0; + bus_timing = clock / (double)cpu_busspeed; + video_updatetiming(); + // pclog("PITCONST=%f CGACONST=%f\n", PITCONST, CGACONST); + // pclog("CPUMULTI=%g\n", ((14318184.0*(double)(1 << TIMER_SHIFT)) / + // (double)models[model]->cpu[cpu_manufacturer].cpus[cpu].rspeed)); - xt_cpu_multi = (uint64_t)((14318184.0 * (double)(1ull << 32)) / (double)cpu_get_speed()); -// pclog("egacycles %i egacycles2 %i temp %f clock %f\n",egacycles,egacycles2,temp,clock); -/* if (video_recalctimings) - video_recalctimings();*/ - RTCCONST = (uint64_t)((clock / 32768.0) * (float)(1ull << 32)); - TIMER_USEC = (uint64_t)((clock / 1000000.0) * (float)(1ull << 32)); - device_speed_changed(); + xt_cpu_multi = (uint64_t)((14318184.0 * (double)(1ull << 32)) / (double)cpu_get_speed()); + // pclog("egacycles %i egacycles2 %i temp %f clock %f\n",egacycles,egacycles2,temp,clock); + /* if (video_recalctimings) + video_recalctimings();*/ + RTCCONST = (uint64_t)((clock / 32768.0) * (float)(1ull << 32)); + TIMER_USEC = (uint64_t)((clock / 1000000.0) * (float)(1ull << 32)); + device_speed_changed(); } //#define PITCONST (8000000.0/1193000.0) //#define PITCONST (cpuclock/1193000.0) void pit_reset(PIT *pit) { - memset(pit, 0, sizeof(PIT)); - pit->l[0] = 0xFFFF; - pit->l[1] = 0xFFFF; - pit->l[2] = 0xFFFF; - 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; + memset(pit, 0, sizeof(PIT)); + pit->l[0] = 0xFFFF; + pit->l[1] = 0xFFFF; + pit->l[2] = 0xFFFF; + 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; } float pit_timer0_freq() { - if (pit.l[0]) - return 1193182.0f / (float)pit.l[0]; - else - return 1193182.0f / (float)0x10000; + if (pit.l[0]) + return 1193182.0f / (float)pit.l[0]; + else + return 1193182.0f / (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; + pit->set_out_funcs[t](out, pit->out[t]); + pit->out[t] = out; } static int pit_read_timer(PIT *pit, int t) { -// pclog("pit_read_timer: t=%i using_timer=%i m=%i enabled=%i\n", t, pit->using_timer[t], pit->m[t], timer_is_enabled(&pit->timer[t])); - if (pit->using_timer[t] && !(pit->m[t] == 3 && !pit->gate[t]) && timer_is_enabled(&pit->timer[t])) { - int read = (int)((timer_get_remaining_u64(&pit->timer[t])) / PITCONST); -// pclog(" read %i %08x %016llx\n", t, read, timer_get_remaining_u64(&pit->timer[t])); - 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]; + // pclog("pit_read_timer: t=%i using_timer=%i m=%i enabled=%i\n", t, pit->using_timer[t], pit->m[t], + // timer_is_enabled(&pit->timer[t])); + if (pit->using_timer[t] && !(pit->m[t] == 3 && !pit->gate[t]) && timer_is_enabled(&pit->timer[t])) { + int read = (int)((timer_get_remaining_u64(&pit->timer[t])) / PITCONST); + // pclog(" read %i %08x %016llx\n", t, read, timer_get_remaining_u64(&pit->timer[t])); + 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]; } /*Dump timer count back to pit->count[], and disable timer. This should be used when stopping a PIT timer, to ensure the correct value can be read back.*/ static void pit_dump_and_disable_timer(PIT *pit, int t) { - if (pit->using_timer[t] && timer_is_enabled(&pit->timer[t])) { - pit->count[t] = pit_read_timer(pit, t); - timer_disable(&pit->timer[t]); - } + if (pit->using_timer[t] && timer_is_enabled(&pit->timer[t])) { + pit->count[t] = pit_read_timer(pit, t); + timer_disable(&pit->timer[t]); + } } static void pit_load(PIT *pit, int t) { - int l = pit->l[t] ? pit->l[t] : 0x10000; + int l = pit->l[t] ? pit->l[t] : 0x10000; - pit->newcount[t] = 0; - pit->disabled[t] = 0; -// pclog("pit_load: t=%i l=%x m=%i %016llx\n", t, l, pit->m[t], PITCONST); - switch (pit->m[t]) { - case 0: /*Interrupt on terminal count*/ - pit->count[t] = l; - if (pit->using_timer[t]) - timer_set_delay_u64(&pit->timer[t], (uint64_t)(l * 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; - if (pit->using_timer[t]) - timer_set_delay_u64(&pit->timer[t], (uint64_t)((l - 1) * 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; - if (pit->using_timer[t]) - timer_set_delay_u64(&pit->timer[t], (uint64_t)(((l + 1) >> 1) * PITCONST)); - pit_set_out(pit, t, 1); - pit->thit[t] = 0; - } - pit->enabled[t] = pit->gate[t]; -// pclog("pit_load: square wave mode c=%x\n", ); - break; - case 4: /*Software triggered stobe*/ - if (!pit->thit[t] && !pit->initial[t]) - pit->newcount[t] = 1; - else { - pit->count[t] = l; - if (pit->using_timer[t]) - timer_set_delay_u64(&pit->timer[t], (uint64_t)(l * 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]; - if (pit->using_timer[t] && !pit->running[t]) - pit_dump_and_disable_timer(pit, t); + pit->newcount[t] = 0; + pit->disabled[t] = 0; + // pclog("pit_load: t=%i l=%x m=%i %016llx\n", t, l, pit->m[t], PITCONST); + switch (pit->m[t]) { + case 0: /*Interrupt on terminal count*/ + pit->count[t] = l; + if (pit->using_timer[t]) + timer_set_delay_u64(&pit->timer[t], (uint64_t)(l * 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; + if (pit->using_timer[t]) + timer_set_delay_u64(&pit->timer[t], (uint64_t)((l - 1) * 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; + if (pit->using_timer[t]) + timer_set_delay_u64(&pit->timer[t], (uint64_t)(((l + 1) >> 1) * PITCONST)); + pit_set_out(pit, t, 1); + pit->thit[t] = 0; + } + pit->enabled[t] = pit->gate[t]; + // pclog("pit_load: square wave mode c=%x\n", ); + break; + case 4: /*Software triggered stobe*/ + if (!pit->thit[t] && !pit->initial[t]) + pit->newcount[t] = 1; + else { + pit->count[t] = l; + if (pit->using_timer[t]) + timer_set_delay_u64(&pit->timer[t], (uint64_t)(l * 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]; + if (pit->using_timer[t] && !pit->running[t]) + pit_dump_and_disable_timer(pit, t); -// pclog("pit_load: t=%i running=%i thit=%i enabled=%i m=%i l=%x c=%g gate=%i\n", t, pit.running[t], pit.thit[t], pit.enabled[t], pit.m[t], pit.l[t], pit.c[t], pit.gate[t]); + // pclog("pit_load: t=%i running=%i thit=%i enabled=%i m=%i l=%x c=%g gate=%i\n", t, pit.running[t], pit.thit[t], + // pit.enabled[t], pit.m[t], pit.l[t], pit.c[t], pit.gate[t]); } void pit_set_gate_no_timer(PIT *pit, int t, int gate) { - int l = pit->l[t] ? pit->l[t] : 0x10000; + int l = pit->l[t] ? pit->l[t] : 0x10000; - if (pit->disabled[t]) { - pit->gate[t] = gate; - return; - } + if (pit->disabled[t]) { + pit->gate[t] = gate; + return; + } - switch (pit->m[t]) { - case 0: /*Interrupt on terminal count*/ - case 4: /*Software triggered stobe*/ - if (pit->using_timer[t] && !pit->running[t]) - timer_set_delay_u64(&pit->timer[t], (uint64_t)(l * PITCONST)); - 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; - if (pit->using_timer[t]) - timer_set_delay_u64(&pit->timer[t], (uint64_t)(l * 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; - if (pit->using_timer[t]) - timer_set_delay_u64(&pit->timer[t], (uint64_t)(l * 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; - if (pit->using_timer[t]) - timer_set_delay_u64(&pit->timer[t], (uint64_t)(((l + 1) >> 1) * 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]; - if (pit->using_timer[t] && !pit->running[t]) - pit_dump_and_disable_timer(pit, t); -// pclog("pit_set_gate: t=%i gate=%i\n", t, gate); + switch (pit->m[t]) { + case 0: /*Interrupt on terminal count*/ + case 4: /*Software triggered stobe*/ + if (pit->using_timer[t] && !pit->running[t]) + timer_set_delay_u64(&pit->timer[t], (uint64_t)(l * PITCONST)); + 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; + if (pit->using_timer[t]) + timer_set_delay_u64(&pit->timer[t], (uint64_t)(l * 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; + if (pit->using_timer[t]) + timer_set_delay_u64(&pit->timer[t], (uint64_t)(l * 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; + if (pit->using_timer[t]) + timer_set_delay_u64(&pit->timer[t], (uint64_t)(((l + 1) >> 1) * 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]; + if (pit->using_timer[t] && !pit->running[t]) + pit_dump_and_disable_timer(pit, t); + // pclog("pit_set_gate: t=%i gate=%i\n", t, gate); } void pit_set_gate(PIT *pit, int t, int gate) { -// pclog("pit_set_gate: t=%i gate=%i\n", t, gate); - if (pit->disabled[t]) { - pit->gate[t] = gate; - return; - } + // pclog("pit_set_gate: t=%i gate=%i\n", t, gate); + if (pit->disabled[t]) { + pit->gate[t] = gate; + return; + } - pit_set_gate_no_timer(pit, t, gate); + pit_set_gate_no_timer(pit, t, gate); } static void pit_over(PIT *pit, int t) { - int l = pit->l[t] ? pit->l[t] : 0x10000; - if (pit->disabled[t]) { - pit->count[t] += 0xffff; - if (pit->using_timer[t]) - timer_advance_u64(&pit->timer[t], (uint64_t)(0xffff * PITCONST)); - return; - } + int l = pit->l[t] ? pit->l[t] : 0x10000; + if (pit->disabled[t]) { + pit->count[t] += 0xffff; + if (pit->using_timer[t]) + timer_advance_u64(&pit->timer[t], (uint64_t)(0xffff * PITCONST)); + return; + } -// if (t == 2) pclog("pit_over: t=%i l=%x c=%llx hit=%i %016llx\n", t, pit->l[t], timer_get_remaining_u64(&pit->timer[t]), pit->thit[t], tsc); - 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; - if (pit->using_timer[t]) - timer_advance_u64(&pit->timer[t], (uint64_t)(0xffff * PITCONST)); - break; - case 2: /*Rate generator*/ - pit->count[t] += l; - if (pit->using_timer[t]) - timer_advance_u64(&pit->timer[t], (uint64_t)(l * 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); - if (pit->using_timer[t]) - timer_advance_u64(&pit->timer[t], (uint64_t)((l >> 1) * PITCONST)); - } else { - pit_set_out(pit, t, 1); - pit->count[t] += ((l + 1) >> 1); - if (pit->using_timer[t]) - timer_advance_u64(&pit->timer[t], (uint64_t)(((l + 1) >> 1) * PITCONST)); - } -// if (!t) pclog("pit_over: square wave mode c=%x %lli %f\n", pit.c[t], tsc, 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; - if (pit->using_timer[t]) - timer_advance_u64(&pit->timer[t], (uint64_t)(l * PITCONST)); - } else { - pit->thit[t] = 1; - pit->count[t] += 0xffff; - if (pit->using_timer[t]) - timer_advance_u64(&pit->timer[t], (uint64_t)(0xffff * 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; - if (pit->using_timer[t]) - timer_advance_u64(&pit->timer[t], (uint64_t)(0xffff * PITCONST)); - break; - } - pit->running[t] = pit->enabled[t] && pit->using_timer[t] && !pit->disabled[t]; - if (pit->using_timer[t] && !pit->running[t]) - pit_dump_and_disable_timer(pit, t); + // if (t == 2) pclog("pit_over: t=%i l=%x c=%llx hit=%i %016llx\n", t, pit->l[t], + // timer_get_remaining_u64(&pit->timer[t]), pit->thit[t], tsc); + 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; + if (pit->using_timer[t]) + timer_advance_u64(&pit->timer[t], (uint64_t)(0xffff * PITCONST)); + break; + case 2: /*Rate generator*/ + pit->count[t] += l; + if (pit->using_timer[t]) + timer_advance_u64(&pit->timer[t], (uint64_t)(l * 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); + if (pit->using_timer[t]) + timer_advance_u64(&pit->timer[t], (uint64_t)((l >> 1) * PITCONST)); + } else { + pit_set_out(pit, t, 1); + pit->count[t] += ((l + 1) >> 1); + if (pit->using_timer[t]) + timer_advance_u64(&pit->timer[t], (uint64_t)(((l + 1) >> 1) * PITCONST)); + } + // if (!t) pclog("pit_over: square wave mode c=%x %lli %f\n", pit.c[t], tsc, 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; + if (pit->using_timer[t]) + timer_advance_u64(&pit->timer[t], (uint64_t)(l * PITCONST)); + } else { + pit->thit[t] = 1; + pit->count[t] += 0xffff; + if (pit->using_timer[t]) + timer_advance_u64(&pit->timer[t], (uint64_t)(0xffff * 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; + if (pit->using_timer[t]) + timer_advance_u64(&pit->timer[t], (uint64_t)(0xffff * PITCONST)); + break; + } + pit->running[t] = pit->enabled[t] && pit->using_timer[t] && !pit->disabled[t]; + if (pit->using_timer[t] && !pit->running[t]) + pit_dump_and_disable_timer(pit, t); } void pit_write(uint16_t addr, uint8_t val, void *p) { - PIT *pit = (PIT *)p; - int t; -// /*if (val != 0x40) */pclog("Write PIT %04X %02X %04X:%08X %i %i\n",addr,val,CS,cpu_state.pc,ins, pit->gate[0]); + PIT *pit = (PIT *)p; + int t; + // /*if (val != 0x40) */pclog("Write PIT %04X %02X %04X:%08X %i %i\n",addr,val,CS,cpu_state.pc,ins, pit->gate[0]); - 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) { - printf("Bad PIT reg select\n"); - return; -// dumpregs(); -// exit(-1); - } -// printf("CTRL write %02X\n",val); - if (!(pit->ctrl & 0x30)) { - pit->rl[t] = pit_read_timer(pit, t); -// pclog("Timer latch %f %04X %04X\n",pit->c[0],pit->rl[0],pit->l[0]); - 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; -// pclog("ppispeakon %i\n",ppispeakon); - } - pit->wp = 0; - pit->thit[t] = 0; - break; - case 0: - case 1: - case 2: /*Timers*/ - t = addr & 3; -// if (t==2) ppispeakon=speakon=0; -// pclog("Write timer %02X %i\n",pit.ctrls[t],pit.wm[t]); - 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; -// printf("Speakval now %i\n",speakval); -// if (speakval>0x2000) -// printf("Speaker overflow - %i %i %04X %04X\n",pit.l[0],pit.l[2],pit.l[0],pit.l[2]); - if (speakval > 0x2000) - speakval = 0x2000; -/* if (!pit.l[t]) - { - pit.l[t]|=0x10000; - pit.c[t]=pit.l[t]*PITCONST; - }*/ - break; - } + 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) { + printf("Bad PIT reg select\n"); + return; + // dumpregs(); + // exit(-1); + } + // printf("CTRL write %02X\n",val); + if (!(pit->ctrl & 0x30)) { + pit->rl[t] = pit_read_timer(pit, t); + // pclog("Timer latch %f %04X %04X\n",pit->c[0],pit->rl[0],pit->l[0]); + 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; + // pclog("ppispeakon %i\n",ppispeakon); + } + pit->wp = 0; + pit->thit[t] = 0; + break; + case 0: + case 1: + case 2: /*Timers*/ + t = addr & 3; + // if (t==2) ppispeakon=speakon=0; + // pclog("Write timer %02X %i\n",pit.ctrls[t],pit.wm[t]); + 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; + // printf("Speakval now %i\n",speakval); + // if (speakval>0x2000) + // printf("Speaker overflow - %i %i %04X %04X\n",pit.l[0],pit.l[2],pit.l[0],pit.l[2]); + if (speakval > 0x2000) + speakval = 0x2000; + /* if (!pit.l[t]) + { + pit.l[t]|=0x10000; + pit.c[t]=pit.l[t]*PITCONST; + }*/ + break; + } } uint8_t pit_read(uint16_t addr, void *p) { - PIT *pit = (PIT *)p; - int t; - uint8_t temp = 0xff; -// printf("Read PIT %04X\n",addr); - 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; - } -// pclog("%02X\n", temp); -// printf("%02X %i %i %04X:%04X %i\n",temp,pit.rm[addr&3],pit.wp,cs>>4,pc, ins); - return temp; + PIT *pit = (PIT *)p; + int t; + uint8_t temp = 0xff; + // printf("Read PIT %04X\n",addr); + 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; + } + // pclog("%02X\n", temp); + // printf("%02X %i %i %04X:%04X %i\n",temp,pit.rm[addr&3],pit.wp,cs>>4,pc, ins); + return temp; } void pit_timer_over(void *p) { - PIT_nr *pit_nr = (PIT_nr *)p; - PIT *pit = pit_nr->pit; - int timer = pit_nr->nr; -// pclog("pit_timer_over %i\n", timer); + PIT_nr *pit_nr = (PIT_nr *)p; + PIT *pit = pit_nr->pit; + int timer = pit_nr->nr; + // pclog("pit_timer_over %i\n", timer); - pit_over(pit, timer); + pit_over(pit, timer); } void pit_clock(PIT *pit, int t) { - if (pit->thit[t] || !pit->enabled[t]) - return; + if (pit->thit[t] || !pit->enabled[t]) + return; - if (pit->using_timer[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); + 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) { -// pclog("pit_set_using_timer: t=%i using_timer=%i\n", t, using_timer); - timer_process(); - if (pit->using_timer[t] && !using_timer) - pit->count[t] = pit_read_timer(pit, t); - pit->running[t] = pit->enabled[t] && using_timer && !pit->disabled[t]; - if (!pit->using_timer[t] && using_timer && pit->running[t]) - timer_set_delay_u64(&pit->timer[t], (uint64_t)(pit->count[t] * PITCONST)); - else if (!pit->running[t]) - timer_disable(&pit->timer[t]); - pit->using_timer[t] = using_timer; + // pclog("pit_set_using_timer: t=%i using_timer=%i\n", t, using_timer); + timer_process(); + if (pit->using_timer[t] && !using_timer) + pit->count[t] = pit_read_timer(pit, t); + pit->running[t] = pit->enabled[t] && using_timer && !pit->disabled[t]; + if (!pit->using_timer[t] && using_timer && pit->running[t]) + timer_set_delay_u64(&pit->timer[t], (uint64_t)(pit->count[t] * PITCONST)); + else if (!pit->running[t]) + timer_disable(&pit->timer[t]); + pit->using_timer[t] = using_timer; } -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_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_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); + 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); + 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) { - //pclog("pit_irq0_ps2 %i %i\n", new_out, 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); + // pclog("pit_irq0_ps2 %i %i\n", new_out, 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); + 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; + if (new_out && !old_out) + ppi.pb ^= 0x10; } void pit_speaker_timer(int new_out, int old_out) { - int l; + int l; - speaker_update(); + speaker_update(); - l = pit.l[2] ? pit.l[2] : 0x10000; - if (l < 25) - speakon = 0; - else - speakon = new_out; - ppispeakon = new_out; + 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; + nmi = new_out; + if (nmi) + nmi_auto_clear = 1; } void pit_init() { - pit_reset(&pit); + 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; + 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; + 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[0], pit_timer_over, (void *)&pit.pit_nr[0], 0); - timer_add(&pit.timer[1], pit_timer_over, (void *)&pit.pit_nr[1], 0); - timer_add(&pit.timer[2], pit_timer_over, (void *)&pit.pit_nr[2], 0); + timer_add(&pit.timer[0], pit_timer_over, (void *)&pit.pit_nr[0], 0); + timer_add(&pit.timer[1], pit_timer_over, (void *)&pit.pit_nr[1], 0); + timer_add(&pit.timer[2], pit_timer_over, (void *)&pit.pit_nr[2], 0); - 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); + 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); + 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); + 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.gate[0] = 0; + pit2.using_timer[0] = 0; + pit2.disabled[0] = 1; - pit2.pit_nr[0].nr = 0; - pit2.pit_nr[0].pit = &pit2; + pit2.pit_nr[0].nr = 0; + pit2.pit_nr[0].pit = &pit2; - timer_add(&pit2.timer[0], pit_timer_over, (void *)&pit2.pit_nr[0], 0); + timer_add(&pit2.timer[0], pit_timer_over, (void *)&pit2.pit_nr[0], 0); - pit_set_out_func(&pit, 0, pit_irq0_ps2); - pit_set_out_func(&pit2, 0, pit_nmi_ps2); + pit_set_out_func(&pit, 0, pit_irq0_ps2); + pit_set_out_func(&pit2, 0, pit_nmi_ps2); } - diff --git a/src/models/ps1.c b/src/models/ps1.c index 946d1df4..1e816200 100644 --- a/src/models/ps1.c +++ b/src/models/ps1.c @@ -14,116 +14,133 @@ static int ps1_e0_addr; static uint8_t ps1_e0_regs[256]; static struct { - uint8_t status, int_status; - uint8_t attention, ctrl; + uint8_t status, int_status; + uint8_t attention, ctrl; } ps1_hd; uint8_t ps1_read(uint16_t port, void *p) { - uint8_t temp; + uint8_t temp; - switch (port) { - case 0x91:return 0; - case 0x92:return ps1_92; - case 0x94:return ps1_94; - case 0x102:return ps1_102 | 8; - case 0x103:return ps1_103; - case 0x104:return ps1_104; - case 0x105:return ps1_105; - case 0x190:return ps1_190; + switch (port) { + case 0x91: + return 0; + case 0x92: + return ps1_92; + case 0x94: + return ps1_94; + case 0x102: + return ps1_102 | 8; + case 0x103: + return ps1_103; + case 0x104: + return ps1_104; + case 0x105: + return ps1_105; + case 0x190: + return ps1_190; - case 0x322:temp = ps1_hd.status; - break; - case 0x324:temp = ps1_hd.int_status; - ps1_hd.int_status &= ~0x02; - break; + case 0x322: + temp = ps1_hd.status; + break; + case 0x324: + temp = ps1_hd.int_status; + ps1_hd.int_status &= ~0x02; + break; - default:temp = 0xff; - break; - } + default: + temp = 0xff; + break; + } - return temp; + return temp; } void ps1_write(uint16_t port, uint8_t val, void *p) { - switch (port) { - case 0x0092:ps1_92 = val; - mem_a20_alt = val & 2; - mem_a20_recalc(); - break; - case 0x94:ps1_94 = val; - break; - case 0x102:lpt1_remove(); - if (val & 0x04) - serial1_init(0x3f8, 4, 1); - else - serial1_remove(); - 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; - } - } - ps1_102 = val; - break; - case 0x103:ps1_103 = val; - break; - case 0x104:ps1_104 = val; - break; - case 0x105:ps1_105 = val; - break; - case 0x190:ps1_190 = val; - break; + switch (port) { + case 0x0092: + ps1_92 = val; + mem_a20_alt = val & 2; + mem_a20_recalc(); + break; + case 0x94: + ps1_94 = val; + break; + case 0x102: + lpt1_remove(); + if (val & 0x04) + serial1_init(0x3f8, 4, 1); + else + serial1_remove(); + 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; + } + } + ps1_102 = val; + break; + case 0x103: + ps1_103 = val; + break; + case 0x104: + ps1_104 = val; + break; + case 0x105: + ps1_105 = val; + break; + case 0x190: + ps1_190 = val; + break; - case 0x322:ps1_hd.ctrl = val; - if (val & 0x80) - ps1_hd.status |= 0x02; - break; - case 0x324:ps1_hd.attention = val & 0xf0; - if (ps1_hd.attention) - ps1_hd.status = 0x14; - break; - } + case 0x322: + ps1_hd.ctrl = val; + if (val & 0x80) + ps1_hd.status |= 0x02; + break; + case 0x324: + ps1_hd.attention = val & 0xf0; + if (ps1_hd.attention) + ps1_hd.status = 0x14; + break; + } } void ps1mb_init() { - io_sethandler(0x0091, 0x0001, ps1_read, NULL, NULL, ps1_write, NULL, NULL, NULL); - io_sethandler(0x0092, 0x0001, ps1_read, NULL, NULL, ps1_write, NULL, NULL, NULL); - io_sethandler(0x0094, 0x0001, ps1_read, NULL, NULL, ps1_write, NULL, NULL, NULL); - io_sethandler(0x0102, 0x0004, ps1_read, NULL, NULL, ps1_write, NULL, NULL, NULL); - io_sethandler(0x0190, 0x0001, ps1_read, NULL, NULL, ps1_write, NULL, NULL, NULL); - io_sethandler(0x0320, 0x0001, ps1_read, NULL, NULL, ps1_write, NULL, NULL, NULL); - io_sethandler(0x0322, 0x0001, ps1_read, NULL, NULL, ps1_write, NULL, NULL, NULL); - io_sethandler(0x0324, 0x0001, ps1_read, NULL, NULL, ps1_write, NULL, NULL, NULL); + io_sethandler(0x0091, 0x0001, ps1_read, NULL, NULL, ps1_write, NULL, NULL, NULL); + io_sethandler(0x0092, 0x0001, ps1_read, NULL, NULL, ps1_write, NULL, NULL, NULL); + io_sethandler(0x0094, 0x0001, ps1_read, NULL, NULL, ps1_write, NULL, NULL, NULL); + io_sethandler(0x0102, 0x0004, ps1_read, NULL, NULL, ps1_write, NULL, NULL, NULL); + io_sethandler(0x0190, 0x0001, ps1_read, NULL, NULL, ps1_write, NULL, NULL, NULL); + io_sethandler(0x0320, 0x0001, ps1_read, NULL, NULL, ps1_write, NULL, NULL, NULL); + io_sethandler(0x0322, 0x0001, ps1_read, NULL, NULL, ps1_write, NULL, NULL, NULL); + io_sethandler(0x0324, 0x0001, ps1_read, NULL, NULL, ps1_write, NULL, NULL, NULL); - rom_init(&ps1_high_rom, - "ibmps1es/f80000.bin", - 0xf80000, - 0x80000, - 0x7ffff, - 0, - MEM_MAPPING_EXTERNAL); -/* rom_init_interleaved(&ps1_high_rom, - "ibmps1es/ibm_1057757_24-05-90.bin", - "ibmps1es/ibm_1057757_29-15-90.bin", - 0xfc0000, - 0x40000, - 0x3ffff, - 0, - MEM_MAPPING_EXTERNAL);*/ - ps1_190 = 0; + rom_init(&ps1_high_rom, "ibmps1es/f80000.bin", 0xf80000, 0x80000, 0x7ffff, 0, MEM_MAPPING_EXTERNAL); + /* rom_init_interleaved(&ps1_high_rom, + "ibmps1es/ibm_1057757_24-05-90.bin", + "ibmps1es/ibm_1057757_29-15-90.bin", + 0xfc0000, + 0x40000, + 0x3ffff, + 0, + MEM_MAPPING_EXTERNAL);*/ + ps1_190 = 0; - lpt1_remove(); - lpt2_remove(); - lpt1_init(0x3bc); + lpt1_remove(); + lpt2_remove(); + lpt1_init(0x3bc); - serial1_remove(); - serial2_remove(); + serial1_remove(); + serial2_remove(); - memset(&ps1_hd, 0, sizeof(ps1_hd)); + memset(&ps1_hd, 0, sizeof(ps1_hd)); } /*PS/1 Model 2121. @@ -132,163 +149,182 @@ void ps1mb_init() { chip at ports 0xe0 (index)/0xe1 (data). The only functions I have identified are enables for the first 512kb and next 128kb of RAM, in bits 0 of registers 0 and 1 respectively. - + Port 0x105 has bit 7 forced high. Without this 128kb of memory will be missed by the BIOS on cold boots. - + The reserved 384kb is remapped to the top of extended memory. If this is not done then you get an error on startup. */ static uint8_t ps1_m2121_read(uint16_t port, void *p) { - uint8_t temp; + uint8_t temp; - switch (port) { - case 0x91:return 0; - case 0x92:return ps1_92; - case 0x94:return ps1_94; - case 0xe1:return ps1_e0_regs[ps1_e0_addr]; - case 0x102:return ps1_102; - case 0x103:return ps1_103; - case 0x104:return ps1_104; - case 0x105:return ps1_105 | 0x80; - case 0x190:return ps1_190; + switch (port) { + case 0x91: + return 0; + case 0x92: + return ps1_92; + case 0x94: + return ps1_94; + case 0xe1: + return ps1_e0_regs[ps1_e0_addr]; + case 0x102: + return ps1_102; + case 0x103: + return ps1_103; + case 0x104: + return ps1_104; + case 0x105: + return ps1_105 | 0x80; + case 0x190: + return ps1_190; - default:temp = 0xff; - break; - } + default: + temp = 0xff; + break; + } - return temp; + return temp; } static void ps1_m2121_recalc_memory() { - /*Enable first 512kb*/ - mem_set_mem_state(0x00000, 0x80000, (ps1_e0_regs[0] & 0x01) ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL)); - /*Enable 512-640kb*/ - mem_set_mem_state(0x80000, 0x20000, (ps1_e0_regs[1] & 0x01) ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL)); + /*Enable first 512kb*/ + mem_set_mem_state(0x00000, 0x80000, + (ps1_e0_regs[0] & 0x01) ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) + : (MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL)); + /*Enable 512-640kb*/ + mem_set_mem_state(0x80000, 0x20000, + (ps1_e0_regs[1] & 0x01) ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) + : (MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL)); } void ps1_m2121_write(uint16_t port, uint8_t val, void *p) { - switch (port) { - case 0x0092: - if (val & 1) { - softresetx86(); - cpu_set_edx(); - } - ps1_92 = val & ~1; - mem_a20_alt = val & 2; - mem_a20_recalc(); - break; - case 0x94:ps1_94 = val; - break; - case 0xe0:ps1_e0_addr = val; - break; - case 0xe1:ps1_e0_regs[ps1_e0_addr] = val; - ps1_m2121_recalc_memory(); - break; - case 0x102:lpt1_remove(); - if (val & 0x04) - serial1_init(0x3f8, 4, 1); - else - serial1_remove(); - 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; - } - } - ps1_102 = val; - break; - case 0x103:ps1_103 = val; - break; - case 0x104:ps1_104 = val; - break; - case 0x105:ps1_105 = val; - break; - case 0x190:ps1_190 = val; - break; - } + switch (port) { + case 0x0092: + if (val & 1) { + softresetx86(); + cpu_set_edx(); + } + ps1_92 = val & ~1; + mem_a20_alt = val & 2; + mem_a20_recalc(); + break; + case 0x94: + ps1_94 = val; + break; + case 0xe0: + ps1_e0_addr = val; + break; + case 0xe1: + ps1_e0_regs[ps1_e0_addr] = val; + ps1_m2121_recalc_memory(); + break; + case 0x102: + lpt1_remove(); + if (val & 0x04) + serial1_init(0x3f8, 4, 1); + else + serial1_remove(); + 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; + } + } + ps1_102 = val; + break; + case 0x103: + ps1_103 = val; + break; + case 0x104: + ps1_104 = val; + break; + case 0x105: + ps1_105 = val; + break; + case 0x190: + ps1_190 = val; + break; + } } void ps1mb_m2121_init() { - io_sethandler(0x0091, 0x0001, ps1_m2121_read, NULL, NULL, ps1_m2121_write, NULL, NULL, NULL); - io_sethandler(0x0092, 0x0001, ps1_m2121_read, NULL, NULL, ps1_m2121_write, NULL, NULL, NULL); - io_sethandler(0x0094, 0x0001, ps1_m2121_read, NULL, NULL, ps1_m2121_write, NULL, NULL, NULL); - io_sethandler(0x00e0, 0x0002, ps1_m2121_read, NULL, NULL, ps1_m2121_write, NULL, NULL, NULL); - io_sethandler(0x0102, 0x0004, ps1_m2121_read, NULL, NULL, ps1_m2121_write, NULL, NULL, NULL); - io_sethandler(0x0190, 0x0001, ps1_m2121_read, NULL, NULL, ps1_m2121_write, NULL, NULL, NULL); + io_sethandler(0x0091, 0x0001, ps1_m2121_read, NULL, NULL, ps1_m2121_write, NULL, NULL, NULL); + io_sethandler(0x0092, 0x0001, ps1_m2121_read, NULL, NULL, ps1_m2121_write, NULL, NULL, NULL); + io_sethandler(0x0094, 0x0001, ps1_m2121_read, NULL, NULL, ps1_m2121_write, NULL, NULL, NULL); + io_sethandler(0x00e0, 0x0002, ps1_m2121_read, NULL, NULL, ps1_m2121_write, NULL, NULL, NULL); + io_sethandler(0x0102, 0x0004, ps1_m2121_read, NULL, NULL, ps1_m2121_write, NULL, NULL, NULL); + io_sethandler(0x0190, 0x0001, ps1_m2121_read, NULL, NULL, ps1_m2121_write, NULL, NULL, NULL); - rom_init(&ps1_high_rom, - "ibmps1_2121/fc0000.bin", - 0xfc0000, - 0x40000, - 0x3ffff, - 0, - MEM_MAPPING_EXTERNAL); - ps1_92 = 0; - ps1_190 = 0; + rom_init(&ps1_high_rom, "ibmps1_2121/fc0000.bin", 0xfc0000, 0x40000, 0x3ffff, 0, MEM_MAPPING_EXTERNAL); + ps1_92 = 0; + ps1_190 = 0; - lpt1_remove(); - lpt2_remove(); - lpt1_init(0x3bc); + lpt1_remove(); + lpt2_remove(); + lpt1_init(0x3bc); - serial1_remove(); - serial2_remove(); + serial1_remove(); + serial2_remove(); - mem_remap_top_384k(); + mem_remap_top_384k(); } /*Not sure what this SuperIO chip is, so define it here for now*/ static struct { - int idx; - uint8_t regs[3]; + int idx; + uint8_t regs[3]; } ps1_m2133_superio; static uint16_t ps1_lpt_io[4] = {0x378, 0x3bc, 0x278, 0x378}; static uint16_t ps1_com_io[4] = {0x3f8, 0x2f8, 0x3e8, 0x2e8}; static uint8_t ps1_m2133_read(uint16_t port, void *p) { - uint8_t ret = 0xff; - switch (port) { - case 0x398:ret = ps1_m2133_superio.idx; - break; + uint8_t ret = 0xff; + switch (port) { + case 0x398: + ret = ps1_m2133_superio.idx; + break; - case 0x399: - if (ps1_m2133_superio.idx < 3) - ret = ps1_m2133_superio.regs[ps1_m2133_superio.idx]; - break; - } - return ret; + case 0x399: + if (ps1_m2133_superio.idx < 3) + ret = ps1_m2133_superio.regs[ps1_m2133_superio.idx]; + break; + } + return ret; } static void ps1_m2133_write(uint16_t port, uint8_t val, void *p) { -// pclog("ps1_m2133_write: port=%04x val=%02x\n", port, val); - switch (port) { - case 0x398:ps1_m2133_superio.idx = val; - break; + // pclog("ps1_m2133_write: port=%04x val=%02x\n", port, val); + switch (port) { + case 0x398: + ps1_m2133_superio.idx = val; + break; - case 0x399: - if (ps1_m2133_superio.idx < 3) { - ps1_m2133_superio.regs[ps1_m2133_superio.idx] = val; + case 0x399: + if (ps1_m2133_superio.idx < 3) { + ps1_m2133_superio.regs[ps1_m2133_superio.idx] = val; - lpt1_remove(); - serial1_remove(); - serial2_remove(); + lpt1_remove(); + serial1_remove(); + serial2_remove(); - if (ps1_m2133_superio.regs[0] & 1) - lpt1_init(ps1_lpt_io[ps1_m2133_superio.regs[1] & 3]); - if (ps1_m2133_superio.regs[0] & 2) - serial1_set(ps1_com_io[(ps1_m2133_superio.regs[1] >> 2) & 3], 4); - if (ps1_m2133_superio.regs[0] & 4) - serial2_set(ps1_com_io[(ps1_m2133_superio.regs[1] >> 4) & 3], 3); - } - break; - } + if (ps1_m2133_superio.regs[0] & 1) + lpt1_init(ps1_lpt_io[ps1_m2133_superio.regs[1] & 3]); + if (ps1_m2133_superio.regs[0] & 2) + serial1_set(ps1_com_io[(ps1_m2133_superio.regs[1] >> 2) & 3], 4); + if (ps1_m2133_superio.regs[0] & 4) + serial2_set(ps1_com_io[(ps1_m2133_superio.regs[1] >> 4) & 3], 3); + } + break; + } } -void ps1mb_m2133_init(void) { - io_sethandler(0x0398, 0x0002, ps1_m2133_read, NULL, NULL, ps1_m2133_write, NULL, NULL, NULL); -} +void ps1mb_m2133_init(void) { io_sethandler(0x0398, 0x0002, ps1_m2133_read, NULL, NULL, ps1_m2133_write, NULL, NULL, NULL); } diff --git a/src/models/ps2.c b/src/models/ps2.c index 9f0640a2..3d6083ba 100644 --- a/src/models/ps2.c +++ b/src/models/ps2.c @@ -9,100 +9,123 @@ static uint8_t ps2_92, ps2_94, ps2_102, ps2_103, ps2_104, ps2_105, ps2_190; static struct { - uint8_t status, int_status; - uint8_t attention, ctrl; + uint8_t status, int_status; + uint8_t attention, ctrl; } ps2_hd; uint8_t ps2_read(uint16_t port, void *p) { - uint8_t temp; + uint8_t temp; - switch (port) { - case 0x91:return 0; - case 0x92:return ps2_92; - 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; + switch (port) { + case 0x91: + return 0; + case 0x92: + return ps2_92; + 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; + case 0x322: + temp = ps2_hd.status; + break; + case 0x324: + temp = ps2_hd.int_status; + ps2_hd.int_status &= ~0x02; + break; - default:temp = 0xff; - break; - } + default: + temp = 0xff; + break; + } - return temp; + return temp; } void ps2_write(uint16_t port, uint8_t val, void *p) { - switch (port) { - case 0x0092:ps2_92 = val; - mem_a20_alt = val & 2; - mem_a20_recalc(); - break; - case 0x94:ps2_94 = val; - break; - case 0x102:lpt1_remove(); - if (val & 0x04) - serial1_init(0x3f8, 4, 1); - else - serial1_remove(); - 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; + switch (port) { + case 0x0092: + ps2_92 = val; + mem_a20_alt = val & 2; + mem_a20_recalc(); + break; + case 0x94: + ps2_94 = val; + break; + case 0x102: + lpt1_remove(); + if (val & 0x04) + serial1_init(0x3f8, 4, 1); + else + serial1_remove(); + 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; - } + 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; + } } void ps2board_init() { - io_sethandler(0x0091, 0x0001, ps2_read, NULL, NULL, ps2_write, NULL, NULL, NULL); - io_sethandler(0x0092, 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); + io_sethandler(0x0091, 0x0001, ps2_read, NULL, NULL, ps2_write, NULL, NULL, NULL); + io_sethandler(0x0092, 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); - ps2_92 = 0; - ps2_190 = 0; + ps2_92 = 0; + ps2_190 = 0; - lpt1_remove(); - lpt2_remove(); - lpt1_init(0x3bc); + lpt1_remove(); + lpt2_remove(); + lpt1_init(0x3bc); - serial1_remove(); - serial2_remove(); + serial1_remove(); + serial2_remove(); - memset(&ps2_hd, 0, sizeof(ps2_hd)); + memset(&ps2_hd, 0, sizeof(ps2_hd)); } diff --git a/src/models/ps2_mca.c b/src/models/ps2_mca.c index 6594b265..3917afaa 100644 --- a/src/models/ps2_mca.c +++ b/src/models/ps2_mca.c @@ -12,7 +12,7 @@ #include "vid_vga.h" #include "x86.h" -//static uint8_t ps2_92, ps2_94, ps2_102, ps2_103, ps2_104, ps2_105, ps2_190; +// static uint8_t ps2_92, ps2_94, ps2_102, ps2_103, ps2_104, ps2_105, ps2_190; /*static struct { @@ -21,37 +21,37 @@ } ps2_hd;*/ 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 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 memory_bank[8]; - uint8_t io_id; + uint8_t io_id; - mem_mapping_t shadow_mapping; - mem_mapping_t split_mapping; - mem_mapping_t expansion_mapping; - mem_mapping_t cache_mapping; + 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 (*planar_read)(uint16_t port); + void (*planar_write)(uint16_t port, uint8_t val); - uint8_t mem_regs[3]; + uint8_t mem_regs[3]; - uint32_t split_addr; + uint32_t split_addr; - uint8_t mem_pos_regs[8]; + uint8_t mem_pos_regs[8]; - int pending_cache_miss; + int pending_cache_miss; } ps2; /*The model 70 type 3/4 BIOS performs cache testing. Since PCem 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 : @@ -69,7 +69,7 @@ static struct { 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, PCem uses some basic heuristics : - If cache is enabled but RAM is disabled, accesses to low memory go directly to cache memory. @@ -85,850 +85,908 @@ static uint8_t ps2_cache[65536]; static int ps2_cache_valid[65536 / 8]; static uint8_t ps2_read_cache_ram(uint32_t addr, void *priv) { -// pclog("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; + // pclog("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]; + return ps2_cache[addr]; } static uint16_t ps2_read_cache_ramw(uint32_t addr, void *priv) { -// pclog("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; + // pclog("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]; + return *(uint16_t *)&ps2_cache[addr]; } static uint32_t ps2_read_cache_raml(uint32_t addr, void *priv) { -// pclog("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; + // pclog("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]; + return *(uint32_t *)&ps2_cache[addr]; } static void ps2_write_cache_ram(uint32_t addr, uint8_t val, void *priv) { -// pclog("ps2_write_cache_ram: addr=%08x val=%02x %04x:%04x %i\n", addr, val, CS,cpu_state.pc, ins); - ps2_cache[addr] = val; + // pclog("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() { - memset(ps2_cache_valid, 0, sizeof(ps2_cache_valid)); -} +void ps2_cache_clean() { 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); + 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); + 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); + 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); + 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); + 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); + addr = (addr & 0x1ffff) + 0xe0000; + mem_write_raml(addr, val, priv); } static uint8_t ps2_read_split_ram(uint32_t addr, void *priv) { - addr = (addr & 0x3ffff) + 0xa0000; - return mem_read_ram(addr, priv); + addr = (addr & 0x3ffff) + 0xa0000; + return mem_read_ram(addr, priv); } static uint16_t ps2_read_split_ramw(uint32_t addr, void *priv) { - addr = (addr & 0x3ffff) + 0xa0000; - return mem_read_ramw(addr, priv); + addr = (addr & 0x3ffff) + 0xa0000; + return mem_read_ramw(addr, priv); } static uint32_t ps2_read_split_raml(uint32_t addr, void *priv) { - addr = (addr & 0x3ffff) + 0xa0000; - return mem_read_raml(addr, priv); + addr = (addr & 0x3ffff) + 0xa0000; + return mem_read_raml(addr, priv); } static void ps2_write_split_ram(uint32_t addr, uint8_t val, void *priv) { - addr = (addr & 0x3ffff) + 0xa0000; - mem_write_ram(addr, val, priv); + addr = (addr & 0x3ffff) + 0xa0000; + mem_write_ram(addr, val, priv); } static void ps2_write_split_ramw(uint32_t addr, uint16_t val, void *priv) { - addr = (addr & 0x3ffff) + 0xa0000; - mem_write_ramw(addr, val, priv); + addr = (addr & 0x3ffff) + 0xa0000; + mem_write_ramw(addr, val, priv); } static void ps2_write_split_raml(uint32_t addr, uint32_t val, void *priv) { - addr = (addr & 0x3ffff) + 0xa0000; - mem_write_raml(addr, val, priv); + addr = (addr & 0x3ffff) + 0xa0000; + mem_write_raml(addr, val, priv); } -#define PS2_SETUP_IO 0x80 +#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; + 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];//ps2.option[2]; - case 0x105:return ps2.option[3]; - case 0x106:return ps2.subaddr_lo; - case 0x107:return ps2.subaddr_hi; - } - return 0xff; + 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]; // 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_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; + 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; + 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(); - serial1_remove(); - if (val & 0x04) { - if (val & 0x08) - serial1_init(0x3f8, 4, 1); - else - serial1_init(0x2f8, 3, 1); - } else - serial1_remove(); - 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; - } + switch (port) { + case 0x100: + ps2.io_id = val; + break; + case 0x101: + break; + case 0x102: + lpt1_remove(); + serial1_remove(); + if (val & 0x04) { + if (val & 0x08) + serial1_init(0x3f8, 4, 1); + else + serial1_init(0x2f8, 3, 1); + } else + serial1_remove(); + 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(); - serial1_remove(); - if (val & 0x04) { - if (val & 0x08) - serial1_init(0x3f8, 4, 1); - else - serial1_init(0x2f8, 3, 1); - } else - serial1_remove(); - 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); - pclog("Write memory bank %i %02x\n", ps2.option[3] & 7, val); - break; - case 0x105:pclog("Write POS3 %02x\n", val); - ps2.option[3] = val; + switch (port) { + case 0x100: + ps2.io_id = val; + break; + case 0x101: + break; + case 0x102: + lpt1_remove(); + serial1_remove(); + if (val & 0x04) { + if (val & 0x08) + serial1_init(0x3f8, 4, 1); + else + serial1_init(0x2f8, 3, 1); + } else + serial1_remove(); + 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); + pclog("Write memory bank %i %02x\n", ps2.option[3] & 7, val); + break; + case 0x105: + pclog("Write POS3 %02x\n", val); + ps2.option[3] = val; - if (!(val & 0x10)) { - 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 (!(val & 0x10)) { + 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; - } + 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(); - serial1_remove(); - if (val & 0x04) { - if (val & 0x08) - serial1_init(0x3f8, 4, 1); - else - serial1_init(0x2f8, 3, 1); - } else - serial1_remove(); - 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; - } + switch (port) { + case 0x100: + break; + case 0x101: + break; + case 0x102: + lpt1_remove(); + serial1_remove(); + if (val & 0x04) { + if (val & 0x08) + serial1_init(0x3f8, 4, 1); + else + serial1_init(0x2f8, 3, 1); + } else + serial1_remove(); + 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(); - serial1_remove(); - if (val & 0x04) { - if (val & 0x08) - serial1_init(0x3f8, 4, 1); - else - serial1_init(0x2f8, 3, 1); - } else - serial1_remove(); - 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; - } + switch (port) { + case 0x100: + break; + case 0x101: + break; + case 0x102: + lpt1_remove(); + serial1_remove(); + if (val & 0x04) { + if (val & 0x08) + serial1_init(0x3f8, 4, 1); + else + serial1_init(0x2f8, 3, 1); + } else + serial1_remove(); + 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; + uint8_t temp; - switch (port) { - case 0x91:fatal("Read 91 setup=%02x adapter=%02x\n", ps2.setup, ps2.adapter_setup); - case 0x92:temp = ps2.sys_ctrl_port_a; - break; - 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; + switch (port) { + case 0x91: + fatal("Read 91 setup=%02x adapter=%02x\n", ps2.setup, ps2.adapter_setup); + case 0x92: + temp = ps2.sys_ctrl_port_a; + break; + 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; - } + default: + temp = 0xff; + break; + } -// pclog("ps2_read: port=%04x temp=%02x %04x:%04x %i\n", port, temp, CS, cpu_state.pc, ins); + // pclog("ps2_read: port=%04x temp=%02x %04x:%04x %i\n", port, temp, CS, cpu_state.pc, ins); - return temp; + return temp; } static void ps2_mca_write(uint16_t port, uint8_t val, void *p) { -// pclog("ps2_write: port=%04x val=%02x %04x:%04x\n", port, val, CS,cpu_state.pc); + // pclog("ps2_write: port=%04x val=%02x %04x:%04x\n", port, val, CS,cpu_state.pc); - switch (port) { - case 0x0092: - if ((val & 1) && !(ps2.sys_ctrl_port_a & 1)) { - softresetx86(); - cpu_set_edx(); - } - ps2.sys_ctrl_port_a = val; - mem_a20_alt = val & 2; - mem_a20_recalc(); - break; - case 0x94:ps2.setup = val; - break; - case 0x96: - if ((val & 0x80) && !(ps2.adapter_setup & 0x80)) - mca_reset(); - 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)) { - if (mb_vga) { - vga_disable(mb_vga); - if (val & 1) - vga_enable(mb_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; - } + switch (port) { + case 0x0092: + if ((val & 1) && !(ps2.sys_ctrl_port_a & 1)) { + softresetx86(); + cpu_set_edx(); + } + ps2.sys_ctrl_port_a = val; + mem_a20_alt = val & 2; + mem_a20_recalc(); + break; + case 0x94: + ps2.setup = val; + break; + case 0x96: + if ((val & 0x80) && !(ps2.adapter_setup & 0x80)) + mca_reset(); + 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)) { + if (mb_vga) { + vga_disable(mb_vga); + if (val & 1) + vga_enable(mb_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, 0x0002, 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); + io_sethandler(0x0091, 0x0002, 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); - ps2.setup = 0xff; + ps2.setup = 0xff; - lpt1_remove(); - lpt2_remove(); - lpt1_init(0x3bc); + lpt1_remove(); + lpt2_remove(); + lpt1_init(0x3bc); - serial1_remove(); - serial2_remove(); + serial1_remove(); + serial2_remove(); } void ps2_mca_board_model_50_init() { - ps2_mca_board_common_init(); + ps2_mca_board_common_init(); - mem_remap_top_384k(); - mca_init(4); + mem_remap_top_384k(); + mca_init(4); - ps2.planar_read = model_50_read; - ps2.planar_write = model_50_write; + ps2.planar_read = model_50_read; + ps2.planar_write = model_50_write; } void ps2_mca_board_model_55sx_init() { - ps2_mca_board_common_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_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_384k(); + mem_remap_top_256k(); + ps2.option[3] = 0x10; -// mem_remap_top_384k(); - 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; + } - 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); - mca_init(4); - - ps2.planar_read = model_55sx_read; - ps2.planar_write = model_55sx_write; + ps2.planar_read = model_55sx_read; + ps2.planar_write = model_55sx_write; } static void mem_encoding_update() { - if (ps2.split_addr >= mem_size * 1024) - mem_mapping_disable(&ps2.split_mapping); + if (ps2.split_addr >= mem_size * 1024) + mem_mapping_disable(&ps2.split_mapping); - ps2.split_addr = (ps2.mem_regs[0] & 0xf) << 20; + ps2.split_addr = (ps2.mem_regs[0] & 0xf) << 20; - if (ps2.mem_regs[1] & 2) - mem_set_mem_state(0xe0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); - else - mem_set_mem_state(0xe0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED); + if (ps2.mem_regs[1] & 2) + mem_set_mem_state(0xe0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); + else + mem_set_mem_state(0xe0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED); - if (!(ps2.mem_regs[1] & 8)) { - if (ps2.split_addr >= mem_size * 1024) - mem_mapping_set_addr(&ps2.split_mapping, ps2.split_addr, 256 * 1024); - } + if (!(ps2.mem_regs[1] & 8)) { + if (ps2.split_addr >= mem_size * 1024) + mem_mapping_set_addr(&ps2.split_mapping, ps2.split_addr, 256 * 1024); + } } 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; + 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(); + 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; + 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; + 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) { -// pclog("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; - } + 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) { + // pclog("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; - } -// pclog("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(); - } + 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; + } + // pclog("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 uint8_t ps2_mem_expansion_read(int port, void *p) { - return ps2.mem_pos_regs[port & 7]; -} +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; + if (port < 0x102 || port == 0x104) + return; - ps2.mem_pos_regs[port & 7] = val; + 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); + if (ps2.mem_pos_regs[2] & 1) + mem_mapping_enable(&ps2.expansion_mapping); + else + mem_mapping_disable(&ps2.expansion_mapping); } void ps2_mca_board_model_70_type34_init(int is_type4) { - ps2_mca_board_common_init(); + ps2_mca_board_common_init(); - mem_remap_top_256k(); - ps2.split_addr = mem_size * 1024; - mca_init(4); + mem_remap_top_256k(); + ps2.split_addr = mem_size * 1024; + mca_init(4); - ps2.planar_read = model_70_type3_read; - ps2.planar_write = model_70_type3_write; + ps2.planar_read = model_70_type3_read; + ps2.planar_write = model_70_type3_write; - device_add(&ps2_nvr_device); + device_add(&ps2_nvr_device); - io_sethandler(0x00e0, 0x0003, mem_encoding_read_cached, NULL, NULL, mem_encoding_write_cached, NULL, NULL, NULL); + io_sethandler(0x00e0, 0x0003, mem_encoding_read_cached, NULL, NULL, mem_encoding_write_cached, NULL, NULL, NULL); - ps2.mem_regs[1] = 2; + 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; - } + 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*/ + 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.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); + 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 */ - mem_mapping_set_addr(&ram_high_mapping, 0x100000, 0x700000); + if (mem_size > 8192) { + /* Only 8 MB supported on planar, create a memory expansion card for the rest */ + mem_mapping_set_addr(&ram_high_mapping, 0x100000, 0x700000); - ps2.mem_pos_regs[0] = 0xff; - ps2.mem_pos_regs[1] = 0xfc; + ps2.mem_pos_regs[0] = 0xff; + ps2.mem_pos_regs[1] = 0xfc; - switch (mem_size / 1024) { - case 10:ps2.mem_pos_regs[4] = 0xfe; - break; - case 12:ps2.mem_pos_regs[4] = 0xfa; - break; - case 14:ps2.mem_pos_regs[4] = 0xea; - break; - case 16:ps2.mem_pos_regs[4] = 0xaa; - break; - } + switch (mem_size / 1024) { + case 10: + ps2.mem_pos_regs[4] = 0xfe; + break; + case 12: + ps2.mem_pos_regs[4] = 0xfa; + break; + case 14: + ps2.mem_pos_regs[4] = 0xea; + break; + case 16: + ps2.mem_pos_regs[4] = 0xaa; + break; + } - mca_add(ps2_mem_expansion_read, ps2_mem_expansion_write, NULL, NULL); - mem_mapping_add(&ps2.expansion_mapping, - 0x800000, - (mem_size - 8192) * 1024, - mem_read_ram, - mem_read_ramw, - mem_read_raml, - mem_write_ram, - mem_write_ramw, - mem_write_raml, - &ram[0x800000], - MEM_MAPPING_INTERNAL, - NULL); - mem_mapping_disable(&ps2.expansion_mapping); - } + mca_add(ps2_mem_expansion_read, ps2_mem_expansion_write, NULL, NULL); + mem_mapping_add(&ps2.expansion_mapping, 0x800000, (mem_size - 8192) * 1024, mem_read_ram, mem_read_ramw, + mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, &ram[0x800000], + MEM_MAPPING_INTERNAL, NULL); + mem_mapping_disable(&ps2.expansion_mapping); + } } void ps2_mca_board_model_80_type2_init() { - ps2_mca_board_common_init(); + ps2_mca_board_common_init(); - mem_remap_top_256k(); - ps2.split_addr = mem_size * 1024; - mca_init(8); + mem_remap_top_256k(); + ps2.split_addr = mem_size * 1024; + mca_init(8); - ps2.planar_read = model_80_read; - ps2.planar_write = model_80_write; + ps2.planar_read = model_80_read; + ps2.planar_write = model_80_write; - device_add(&ps2_nvr_device); + device_add(&ps2_nvr_device); - io_sethandler(0x00e0, 0x0002, mem_encoding_read, NULL, NULL, mem_encoding_write, NULL, NULL, NULL); + io_sethandler(0x00e0, 0x0002, mem_encoding_read, NULL, NULL, mem_encoding_write, NULL, NULL, NULL); - ps2.mem_regs[1] = 2; + ps2.mem_regs[1] = 2; - switch (mem_size / 1024) { - case 1:ps2.option[1] = 0x0c; - break; - case 2:ps2.option[1] = 0x0e; - break; - case 3:ps2.option[1] = 0x02; - break; - case 4: - default:ps2.option[1] = 0x0a; - break; - } + switch (mem_size / 1024) { + case 1: + ps2.option[1] = 0x0c; + break; + case 2: + ps2.option[1] = 0x0e; + break; + case 3: + ps2.option[1] = 0x02; + break; + case 4: + default: + ps2.option[1] = 0x0a; + break; + } - 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.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) { - /* Only 4 MB supported on planar, create a memory expansion card for the rest */ - mem_mapping_set_addr(&ram_high_mapping, 0x100000, 0x300000); + if (mem_size > 4096) { + /* Only 4 MB supported on planar, create a memory expansion card for the rest */ + mem_mapping_set_addr(&ram_high_mapping, 0x100000, 0x300000); - ps2.mem_pos_regs[0] = 0xff; - ps2.mem_pos_regs[1] = 0xfc; + ps2.mem_pos_regs[0] = 0xff; + ps2.mem_pos_regs[1] = 0xfc; - switch (mem_size / 1024) { - case 5:ps2.mem_pos_regs[4] = 0xfc; - break; - case 6:ps2.mem_pos_regs[4] = 0xfe; - break; - case 7:ps2.mem_pos_regs[4] = 0xf2; - break; - case 8:ps2.mem_pos_regs[4] = 0xfa; - break; - case 9:ps2.mem_pos_regs[4] = 0xca; - break; - case 10:ps2.mem_pos_regs[4] = 0xea; - break; - case 11:ps2.mem_pos_regs[4] = 0x2a; - break; - case 12:ps2.mem_pos_regs[4] = 0xaa; - break; - } + switch (mem_size / 1024) { + case 5: + ps2.mem_pos_regs[4] = 0xfc; + break; + case 6: + ps2.mem_pos_regs[4] = 0xfe; + break; + case 7: + ps2.mem_pos_regs[4] = 0xf2; + break; + case 8: + ps2.mem_pos_regs[4] = 0xfa; + break; + case 9: + ps2.mem_pos_regs[4] = 0xca; + break; + case 10: + ps2.mem_pos_regs[4] = 0xea; + break; + case 11: + ps2.mem_pos_regs[4] = 0x2a; + break; + case 12: + ps2.mem_pos_regs[4] = 0xaa; + break; + } - mca_add(ps2_mem_expansion_read, ps2_mem_expansion_write, NULL, NULL); - mem_mapping_add(&ps2.expansion_mapping, - 0x400000, - (mem_size - 4096) * 1024, - mem_read_ram, - mem_read_ramw, - mem_read_raml, - mem_write_ram, - mem_write_ramw, - mem_write_raml, - &ram[0x400000], - MEM_MAPPING_INTERNAL, - NULL); - mem_mapping_disable(&ps2.expansion_mapping); - } + mca_add(ps2_mem_expansion_read, ps2_mem_expansion_write, NULL, NULL); + mem_mapping_add(&ps2.expansion_mapping, 0x400000, (mem_size - 4096) * 1024, mem_read_ram, mem_read_ramw, + mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, &ram[0x400000], + MEM_MAPPING_INTERNAL, NULL); + mem_mapping_disable(&ps2.expansion_mapping); + } } diff --git a/src/models/scamp.c b/src/models/scamp.c index 594abd63..c8981a45 100644 --- a/src/models/scamp.c +++ b/src/models/scamp.c @@ -4,814 +4,809 @@ #include "scamp.h" static struct { - int cfg_index; - uint8_t cfg_regs[256]; - int cfg_enable; + int cfg_index; + uint8_t cfg_regs[256]; + int cfg_enable; - int ems_index; - int ems_autoinc; - uint16_t ems[0x24]; - mem_mapping_t ems_mappings[20]; /*a0000-effff*/ - uint32_t mappings[20]; + int ems_index; + int ems_autoinc; + uint16_t ems[0x24]; + mem_mapping_t ems_mappings[20]; /*a0000-effff*/ + uint32_t mappings[20]; - int ram_config; + int ram_config; - mem_mapping_t ram_mapping[2]; - uint32_t ram_virt_base[2], ram_phys_base[2]; - uint32_t ram_mask[2]; - int row_virt_shift[2], row_phys_shift[2]; - int ram_interleaved[2]; - int ibank_shift[2]; + mem_mapping_t ram_mapping[2]; + uint32_t ram_virt_base[2], ram_phys_base[2]; + uint32_t ram_mask[2]; + int row_virt_shift[2], row_phys_shift[2]; + int ram_interleaved[2]; + int ibank_shift[2]; - uint8_t port_92; + uint8_t port_92; } scamp; -#define CFG_ID 0x00 +#define CFG_ID 0x00 #define CFG_SLTPTR 0x02 #define CFG_RAMMAP 0x03 #define CFG_EMSEN1 0x0b #define CFG_EMSEN2 0x0c -#define CFG_ABAXS 0x0e -#define CFG_CAXS 0x0f -#define CFG_DAXS 0x10 -#define CFG_FEAXS 0x11 +#define CFG_ABAXS 0x0e +#define CFG_CAXS 0x0f +#define CFG_DAXS 0x10 +#define CFG_FEAXS 0x11 #define ID_VL82C311 0xd6 #define RAMMAP_REMP386 (1 << 4) -#define EMSEN1_EMSMAP (1 << 4) +#define EMSEN1_EMSMAP (1 << 4) #define EMSEN1_EMSENAB (1 << 7) /*Commodore SL386SX requires proper memory slot decoding to detect memory size. Therefore we emulate the SCAMP memory address decoding, and therefore are limited to the DRAM combinations supported by the actual chip*/ -enum { - BANK_NONE, - BANK_256K, - BANK_256K_INTERLEAVED, - BANK_1M, - BANK_1M_INTERLEAVED, - BANK_4M, - BANK_4M_INTERLEAVED +enum { BANK_NONE, BANK_256K, BANK_256K_INTERLEAVED, BANK_1M, BANK_1M_INTERLEAVED, BANK_4M, BANK_4M_INTERLEAVED }; + +static const struct { + int size_kb; + int rammap; + int bank[2]; +} ram_configs[] = { + {512, 0x0, {BANK_256K, BANK_NONE}}, + {1024, 0x1, {BANK_256K_INTERLEAVED, BANK_NONE}}, + {1536, 0x2, {BANK_256K_INTERLEAVED, BANK_256K}}, + {2048, 0x3, {BANK_256K_INTERLEAVED, BANK_256K_INTERLEAVED}}, + {3072, 0xc, {BANK_256K_INTERLEAVED, BANK_1M}}, + {4096, 0x5, {BANK_1M_INTERLEAVED, BANK_NONE}}, + {5120, 0xd, {BANK_256K_INTERLEAVED, BANK_1M_INTERLEAVED}}, + {6144, 0x6, {BANK_1M_INTERLEAVED, BANK_1M}}, + {8192, 0x7, {BANK_1M_INTERLEAVED, BANK_1M_INTERLEAVED}}, + {12288, 0xe, {BANK_1M_INTERLEAVED, BANK_4M}}, + {16384, 0x9, {BANK_4M_INTERLEAVED, BANK_NONE}}, }; static const struct { - int size_kb; - int rammap; - int bank[2]; -} ram_configs[] = - { - {512, 0x0, {BANK_256K, BANK_NONE}}, - {1024, 0x1, {BANK_256K_INTERLEAVED, BANK_NONE}}, - {1536, 0x2, {BANK_256K_INTERLEAVED, BANK_256K}}, - {2048, 0x3, {BANK_256K_INTERLEAVED, BANK_256K_INTERLEAVED}}, - {3072, 0xc, {BANK_256K_INTERLEAVED, BANK_1M}}, - {4096, 0x5, {BANK_1M_INTERLEAVED, BANK_NONE}}, - {5120, 0xd, {BANK_256K_INTERLEAVED, BANK_1M_INTERLEAVED}}, - {6144, 0x6, {BANK_1M_INTERLEAVED, BANK_1M}}, - {8192, 0x7, {BANK_1M_INTERLEAVED, BANK_1M_INTERLEAVED}}, - {12288, 0xe, {BANK_1M_INTERLEAVED, BANK_4M}}, - {16384, 0x9, {BANK_4M_INTERLEAVED, BANK_NONE}}, - }; + int bank[2]; + int remapped; +} rammap[16] = { + {{BANK_256K, BANK_NONE}, 0}, + {{BANK_256K_INTERLEAVED, BANK_NONE}, 0}, + {{BANK_256K_INTERLEAVED, BANK_256K}, 0}, + {{BANK_256K_INTERLEAVED, BANK_256K_INTERLEAVED}, 0}, -static const struct { - int bank[2]; - int remapped; -} rammap[16] = - { - {{BANK_256K, BANK_NONE}, 0}, - {{BANK_256K_INTERLEAVED, BANK_NONE}, 0}, - {{BANK_256K_INTERLEAVED, BANK_256K}, 0}, - {{BANK_256K_INTERLEAVED, BANK_256K_INTERLEAVED}, 0}, + {{BANK_1M, BANK_NONE}, 0}, + {{BANK_1M_INTERLEAVED, BANK_NONE}, 0}, + {{BANK_1M_INTERLEAVED, BANK_1M}, 0}, + {{BANK_1M_INTERLEAVED, BANK_1M_INTERLEAVED}, 0}, - {{BANK_1M, BANK_NONE}, 0}, - {{BANK_1M_INTERLEAVED, BANK_NONE}, 0}, - {{BANK_1M_INTERLEAVED, BANK_1M}, 0}, - {{BANK_1M_INTERLEAVED, BANK_1M_INTERLEAVED}, 0}, + {{BANK_4M, BANK_NONE}, 0}, + {{BANK_4M_INTERLEAVED, BANK_NONE}, 0}, + {{BANK_NONE, BANK_4M}, 1}, /*Bank 2 remapped to 0*/ + {{BANK_NONE, BANK_4M_INTERLEAVED}, 1}, /*Banks 2/3 remapped to 0/1*/ - {{BANK_4M, BANK_NONE}, 0}, - {{BANK_4M_INTERLEAVED, BANK_NONE}, 0}, - {{BANK_NONE, BANK_4M}, 1}, /*Bank 2 remapped to 0*/ - {{BANK_NONE, BANK_4M_INTERLEAVED}, 1}, /*Banks 2/3 remapped to 0/1*/ - - {{BANK_256K_INTERLEAVED, BANK_1M}, 0}, - {{BANK_256K_INTERLEAVED, BANK_1M_INTERLEAVED}, 0}, - {{BANK_1M_INTERLEAVED, BANK_4M}, 0}, - {{BANK_1M_INTERLEAVED, BANK_4M_INTERLEAVED}, 0}, /*Undocumented - probably wrong!*/ - }; + {{BANK_256K_INTERLEAVED, BANK_1M}, 0}, + {{BANK_256K_INTERLEAVED, BANK_1M_INTERLEAVED}, 0}, + {{BANK_1M_INTERLEAVED, BANK_4M}, 0}, + {{BANK_1M_INTERLEAVED, BANK_4M_INTERLEAVED}, 0}, /*Undocumented - probably wrong!*/ +}; /*The column bits masked when using 256kbit DRAMs in 4Mbit mode aren't contiguous, so we use separate routines for that special case*/ static uint8_t ram_mirrored_256k_in_4mi_read(uint32_t addr, void *p) { - int bank = (intptr_t)p; - int row, column, byte; + int bank = (intptr_t)p; + int row, column, byte; - addr -= scamp.ram_virt_base[bank]; - byte = addr & 1; - if (!scamp.ram_interleaved[bank]) { - if (addr & 0x400) - return 0xff; + addr -= scamp.ram_virt_base[bank]; + byte = addr & 1; + if (!scamp.ram_interleaved[bank]) { + if (addr & 0x400) + return 0xff; - addr = (addr & 0x3ff) | ((addr & ~0x7ff) >> 1); - column = (addr >> 1) & scamp.ram_mask[bank]; - row = ((addr & 0xff000) >> 13) | (((addr & 0x200000) >> 22) << 9); + addr = (addr & 0x3ff) | ((addr & ~0x7ff) >> 1); + column = (addr >> 1) & scamp.ram_mask[bank]; + row = ((addr & 0xff000) >> 13) | (((addr & 0x200000) >> 22) << 9); - addr = byte | (column << 1) | (row << scamp.row_phys_shift[bank]); - } else { - column = (addr >> 1) & ((scamp.ram_mask[bank] << 1) | 1); - row = ((addr & 0x1fe000) >> 13) | (((addr & 0x400000) >> 22) << 9); + addr = byte | (column << 1) | (row << scamp.row_phys_shift[bank]); + } else { + column = (addr >> 1) & ((scamp.ram_mask[bank] << 1) | 1); + row = ((addr & 0x1fe000) >> 13) | (((addr & 0x400000) >> 22) << 9); - addr = byte | (column << 1) | (row << (scamp.row_phys_shift[bank] + 1)); - } + addr = byte | (column << 1) | (row << (scamp.row_phys_shift[bank] + 1)); + } - return ram[addr + scamp.ram_phys_base[bank]]; + return ram[addr + scamp.ram_phys_base[bank]]; } static void ram_mirrored_256k_in_4mi_write(uint32_t addr, uint8_t val, void *p) { - int bank = (intptr_t)p; - int row, column, byte; + int bank = (intptr_t)p; + int row, column, byte; - addr -= scamp.ram_virt_base[bank]; - byte = addr & 1; - if (!scamp.ram_interleaved[bank]) { - if (addr & 0x400) - return; + addr -= scamp.ram_virt_base[bank]; + byte = addr & 1; + if (!scamp.ram_interleaved[bank]) { + if (addr & 0x400) + return; - addr = (addr & 0x3ff) | ((addr & ~0x7ff) >> 1); - column = (addr >> 1) & scamp.ram_mask[bank]; - row = ((addr & 0xff000) >> 13) | (((addr & 0x200000) >> 22) << 9); + addr = (addr & 0x3ff) | ((addr & ~0x7ff) >> 1); + column = (addr >> 1) & scamp.ram_mask[bank]; + row = ((addr & 0xff000) >> 13) | (((addr & 0x200000) >> 22) << 9); - addr = byte | (column << 1) | (row << scamp.row_phys_shift[bank]); - } else { - column = (addr >> 1) & ((scamp.ram_mask[bank] << 1) | 1); - row = ((addr & 0x1fe000) >> 13) | (((addr & 0x400000) >> 22) << 9); + addr = byte | (column << 1) | (row << scamp.row_phys_shift[bank]); + } else { + column = (addr >> 1) & ((scamp.ram_mask[bank] << 1) | 1); + row = ((addr & 0x1fe000) >> 13) | (((addr & 0x400000) >> 22) << 9); - addr = byte | (column << 1) | (row << (scamp.row_phys_shift[bank] + 1)); - } + addr = byte | (column << 1) | (row << (scamp.row_phys_shift[bank] + 1)); + } - ram[addr + scamp.ram_phys_base[bank]] = val; + ram[addr + scamp.ram_phys_base[bank]] = val; } /*Read/write handlers for interleaved memory banks. We must keep CPU and ram array mapping linear, otherwise we won't be able to execute code from interleaved banks*/ static uint8_t ram_mirrored_interleaved_read(uint32_t addr, void *p) { - int bank = (intptr_t)p; - int row, column, byte; + int bank = (intptr_t)p; + int row, column, byte; - addr -= scamp.ram_virt_base[bank]; - byte = addr & 1; - if (!scamp.ram_interleaved[bank]) { - if (addr & 0x400) - return 0xff; + addr -= scamp.ram_virt_base[bank]; + byte = addr & 1; + if (!scamp.ram_interleaved[bank]) { + if (addr & 0x400) + return 0xff; - addr = (addr & 0x3ff) | ((addr & ~0x7ff) >> 1); - column = (addr >> 1) & scamp.ram_mask[bank]; - row = (addr >> scamp.row_virt_shift[bank]) & scamp.ram_mask[bank]; + addr = (addr & 0x3ff) | ((addr & ~0x7ff) >> 1); + column = (addr >> 1) & scamp.ram_mask[bank]; + row = (addr >> scamp.row_virt_shift[bank]) & scamp.ram_mask[bank]; - addr = byte | (column << 1) | (row << scamp.row_phys_shift[bank]); - } else { - column = (addr >> 1) & ((scamp.ram_mask[bank] << 1) | 1); - row = (addr >> (scamp.row_virt_shift[bank] + 1)) & scamp.ram_mask[bank]; + addr = byte | (column << 1) | (row << scamp.row_phys_shift[bank]); + } else { + column = (addr >> 1) & ((scamp.ram_mask[bank] << 1) | 1); + row = (addr >> (scamp.row_virt_shift[bank] + 1)) & scamp.ram_mask[bank]; - addr = byte | (column << 1) | (row << (scamp.row_phys_shift[bank] + 1)); - } + addr = byte | (column << 1) | (row << (scamp.row_phys_shift[bank] + 1)); + } - return ram[addr + scamp.ram_phys_base[bank]]; + return ram[addr + scamp.ram_phys_base[bank]]; } static void ram_mirrored_interleaved_write(uint32_t addr, uint8_t val, void *p) { - int bank = (intptr_t)p; - int row, column, byte; + int bank = (intptr_t)p; + int row, column, byte; - addr -= scamp.ram_virt_base[bank]; - byte = addr & 1; - if (!scamp.ram_interleaved[bank]) { - if (addr & 0x400) - return; + addr -= scamp.ram_virt_base[bank]; + byte = addr & 1; + if (!scamp.ram_interleaved[bank]) { + if (addr & 0x400) + return; - addr = (addr & 0x3ff) | ((addr & ~0x7ff) >> 1); - column = (addr >> 1) & scamp.ram_mask[bank]; - row = (addr >> scamp.row_virt_shift[bank]) & scamp.ram_mask[bank]; + addr = (addr & 0x3ff) | ((addr & ~0x7ff) >> 1); + column = (addr >> 1) & scamp.ram_mask[bank]; + row = (addr >> scamp.row_virt_shift[bank]) & scamp.ram_mask[bank]; - addr = byte | (column << 1) | (row << scamp.row_phys_shift[bank]); - } else { - column = (addr >> 1) & ((scamp.ram_mask[bank] << 1) | 1); - row = (addr >> (scamp.row_virt_shift[bank] + 1)) & scamp.ram_mask[bank]; + addr = byte | (column << 1) | (row << scamp.row_phys_shift[bank]); + } else { + column = (addr >> 1) & ((scamp.ram_mask[bank] << 1) | 1); + row = (addr >> (scamp.row_virt_shift[bank] + 1)) & scamp.ram_mask[bank]; - addr = byte | (column << 1) | (row << (scamp.row_phys_shift[bank] + 1)); - } + addr = byte | (column << 1) | (row << (scamp.row_phys_shift[bank] + 1)); + } - ram[addr + scamp.ram_phys_base[bank]] = val; + ram[addr + scamp.ram_phys_base[bank]] = val; } static uint8_t ram_mirrored_read(uint32_t addr, void *p) { - int bank = (intptr_t)p; - int row, column, byte; + int bank = (intptr_t)p; + int row, column, byte; - addr -= scamp.ram_virt_base[bank]; - byte = addr & 1; - column = (addr >> 1) & scamp.ram_mask[bank]; - row = (addr >> scamp.row_virt_shift[bank]) & scamp.ram_mask[bank]; - addr = byte | (column << 1) | (row << scamp.row_phys_shift[bank]); + addr -= scamp.ram_virt_base[bank]; + byte = addr & 1; + column = (addr >> 1) & scamp.ram_mask[bank]; + row = (addr >> scamp.row_virt_shift[bank]) & scamp.ram_mask[bank]; + addr = byte | (column << 1) | (row << scamp.row_phys_shift[bank]); - return ram[addr + scamp.ram_phys_base[bank]]; + return ram[addr + scamp.ram_phys_base[bank]]; } static void ram_mirrored_write(uint32_t addr, uint8_t val, void *p) { - int bank = (intptr_t)p; - int row, column, byte; + int bank = (intptr_t)p; + int row, column, byte; - addr -= scamp.ram_virt_base[bank]; - byte = addr & 1; - column = (addr >> 1) & scamp.ram_mask[bank]; - row = (addr >> scamp.row_virt_shift[bank]) & scamp.ram_mask[bank]; - addr = byte | (column << 1) | (row << scamp.row_phys_shift[bank]); + addr -= scamp.ram_virt_base[bank]; + byte = addr & 1; + column = (addr >> 1) & scamp.ram_mask[bank]; + row = (addr >> scamp.row_virt_shift[bank]) & scamp.ram_mask[bank]; + addr = byte | (column << 1) | (row << scamp.row_phys_shift[bank]); - ram[addr + scamp.ram_phys_base[bank]] = val; + ram[addr + scamp.ram_phys_base[bank]] = val; } static void recalc_mappings(void) { - int c; - uint32_t virt_base = 0; - uint8_t cur_rammap = scamp.cfg_regs[CFG_RAMMAP] & 0xf; - intptr_t bank_nr = 0; + int c; + uint32_t virt_base = 0; + uint8_t cur_rammap = scamp.cfg_regs[CFG_RAMMAP] & 0xf; + intptr_t bank_nr = 0; - for (c = 0; c < 2; c++) - mem_mapping_disable(&scamp.ram_mapping[c]); + for (c = 0; c < 2; c++) + mem_mapping_disable(&scamp.ram_mapping[c]); - /*Once the BIOS programs the correct DRAM configuration, switch to regular - linear memory mapping*/ - if (cur_rammap == ram_configs[scamp.ram_config].rammap) { - mem_mapping_set_handler(&ram_low_mapping, - mem_read_ram, mem_read_ramw, mem_read_raml, - mem_write_ram, mem_write_ramw, mem_write_raml); - mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000); - mem_mapping_enable(&ram_high_mapping); - return; - } else { - mem_mapping_set_handler(&ram_low_mapping, - ram_mirrored_read, NULL, NULL, - ram_mirrored_write, NULL, NULL); - mem_mapping_disable(&ram_low_mapping); - } + /*Once the BIOS programs the correct DRAM configuration, switch to regular + linear memory mapping*/ + if (cur_rammap == ram_configs[scamp.ram_config].rammap) { + mem_mapping_set_handler(&ram_low_mapping, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, + mem_write_ramw, mem_write_raml); + mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000); + mem_mapping_enable(&ram_high_mapping); + return; + } else { + mem_mapping_set_handler(&ram_low_mapping, ram_mirrored_read, NULL, NULL, ram_mirrored_write, NULL, NULL); + mem_mapping_disable(&ram_low_mapping); + } - if (rammap[cur_rammap].bank[0] == BANK_NONE) - bank_nr = 1; + if (rammap[cur_rammap].bank[0] == BANK_NONE) + bank_nr = 1; - pclog("Bank remap, cur_rammap=%x\n", cur_rammap); + pclog("Bank remap, cur_rammap=%x\n", cur_rammap); - for (; bank_nr < 2; bank_nr++) { - uint32_t old_virt_base = virt_base; - int phys_bank = ram_configs[scamp.ram_config].bank[bank_nr]; + for (; bank_nr < 2; bank_nr++) { + uint32_t old_virt_base = virt_base; + int phys_bank = ram_configs[scamp.ram_config].bank[bank_nr]; - pclog(" Bank %i: phys_bank=%i rammap_bank=%i virt_base=%08x phys_base=%08x\n", bank_nr, phys_bank, rammap[cur_rammap].bank[bank_nr], virt_base, scamp.ram_phys_base[bank_nr]); - scamp.ram_virt_base[bank_nr] = virt_base; + pclog(" Bank %i: phys_bank=%i rammap_bank=%i virt_base=%08x phys_base=%08x\n", bank_nr, phys_bank, + rammap[cur_rammap].bank[bank_nr], virt_base, scamp.ram_phys_base[bank_nr]); + scamp.ram_virt_base[bank_nr] = virt_base; - if (virt_base == 0) { - switch (rammap[cur_rammap].bank[bank_nr]) { - case BANK_NONE:fatal("Bank 0 is empty!\n"); - break; + if (virt_base == 0) { + switch (rammap[cur_rammap].bank[bank_nr]) { + case BANK_NONE: + fatal("Bank 0 is empty!\n"); + break; - case BANK_256K: - if (phys_bank != BANK_NONE) { - mem_mapping_set_addr(&ram_low_mapping, 0, 0x80000); - mem_mapping_set_p(&ram_low_mapping, (void *)bank_nr); - } - virt_base += 512 * 1024; - scamp.row_virt_shift[bank_nr] = 10; - break; + case BANK_256K: + if (phys_bank != BANK_NONE) { + mem_mapping_set_addr(&ram_low_mapping, 0, 0x80000); + mem_mapping_set_p(&ram_low_mapping, (void *)bank_nr); + } + virt_base += 512 * 1024; + scamp.row_virt_shift[bank_nr] = 10; + break; - case BANK_256K_INTERLEAVED: - if (phys_bank != BANK_NONE) { - mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000); - mem_mapping_set_p(&ram_low_mapping, (void *)bank_nr); - } - virt_base += 512 * 1024 * 2; - scamp.row_virt_shift[bank_nr] = 10; - break; + case BANK_256K_INTERLEAVED: + if (phys_bank != BANK_NONE) { + mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000); + mem_mapping_set_p(&ram_low_mapping, (void *)bank_nr); + } + virt_base += 512 * 1024 * 2; + scamp.row_virt_shift[bank_nr] = 10; + break; - case BANK_1M: - if (phys_bank != BANK_NONE) { - mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000); - mem_mapping_set_p(&ram_low_mapping, (void *)bank_nr); - mem_mapping_set_addr(&scamp.ram_mapping[bank_nr], 0x100000, 0x100000); - mem_mapping_set_exec(&scamp.ram_mapping[bank_nr], &ram[scamp.ram_phys_base[bank_nr] + 0x100000]); - } - virt_base += 2048 * 1024; - scamp.row_virt_shift[bank_nr] = 11; - break; + case BANK_1M: + if (phys_bank != BANK_NONE) { + mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000); + mem_mapping_set_p(&ram_low_mapping, (void *)bank_nr); + mem_mapping_set_addr(&scamp.ram_mapping[bank_nr], 0x100000, 0x100000); + mem_mapping_set_exec(&scamp.ram_mapping[bank_nr], + &ram[scamp.ram_phys_base[bank_nr] + 0x100000]); + } + virt_base += 2048 * 1024; + scamp.row_virt_shift[bank_nr] = 11; + break; - case BANK_1M_INTERLEAVED: - if (phys_bank != BANK_NONE) { - mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000); - mem_mapping_set_p(&ram_low_mapping, (void *)bank_nr); - mem_mapping_set_addr(&scamp.ram_mapping[bank_nr], 0x100000, 0x300000); - mem_mapping_set_exec(&scamp.ram_mapping[bank_nr], &ram[scamp.ram_phys_base[bank_nr] + 0x100000]); - } - virt_base += 2048 * 1024 * 2; - scamp.row_virt_shift[bank_nr] = 11; - break; + case BANK_1M_INTERLEAVED: + if (phys_bank != BANK_NONE) { + mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000); + mem_mapping_set_p(&ram_low_mapping, (void *)bank_nr); + mem_mapping_set_addr(&scamp.ram_mapping[bank_nr], 0x100000, 0x300000); + mem_mapping_set_exec(&scamp.ram_mapping[bank_nr], + &ram[scamp.ram_phys_base[bank_nr] + 0x100000]); + } + virt_base += 2048 * 1024 * 2; + scamp.row_virt_shift[bank_nr] = 11; + break; - case BANK_4M: - if (phys_bank != BANK_NONE) { - mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000); - mem_mapping_set_p(&ram_low_mapping, (void *)bank_nr); - mem_mapping_set_addr(&scamp.ram_mapping[bank_nr], 0x100000, 0x700000); - mem_mapping_set_exec(&scamp.ram_mapping[bank_nr], &ram[scamp.ram_phys_base[bank_nr] + 0x100000]); - } - virt_base += 8192 * 1024; - scamp.row_virt_shift[bank_nr] = 12; - break; + case BANK_4M: + if (phys_bank != BANK_NONE) { + mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000); + mem_mapping_set_p(&ram_low_mapping, (void *)bank_nr); + mem_mapping_set_addr(&scamp.ram_mapping[bank_nr], 0x100000, 0x700000); + mem_mapping_set_exec(&scamp.ram_mapping[bank_nr], + &ram[scamp.ram_phys_base[bank_nr] + 0x100000]); + } + virt_base += 8192 * 1024; + scamp.row_virt_shift[bank_nr] = 12; + break; - case BANK_4M_INTERLEAVED: - if (phys_bank != BANK_NONE) { - mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000); - mem_mapping_set_p(&ram_low_mapping, (void *)bank_nr); - mem_mapping_set_addr(&scamp.ram_mapping[bank_nr], 0x100000, 0xf00000); - mem_mapping_set_exec(&scamp.ram_mapping[bank_nr], &ram[scamp.ram_phys_base[bank_nr] + 0x100000]); - } - virt_base += 8192 * 1024 * 2; - scamp.row_virt_shift[bank_nr] = 12; - break; - } - } else { - switch (rammap[cur_rammap].bank[bank_nr]) { - case BANK_NONE:break; + case BANK_4M_INTERLEAVED: + if (phys_bank != BANK_NONE) { + mem_mapping_set_addr(&ram_low_mapping, 0, 0xa0000); + mem_mapping_set_p(&ram_low_mapping, (void *)bank_nr); + mem_mapping_set_addr(&scamp.ram_mapping[bank_nr], 0x100000, 0xf00000); + mem_mapping_set_exec(&scamp.ram_mapping[bank_nr], + &ram[scamp.ram_phys_base[bank_nr] + 0x100000]); + } + virt_base += 8192 * 1024 * 2; + scamp.row_virt_shift[bank_nr] = 12; + break; + } + } else { + switch (rammap[cur_rammap].bank[bank_nr]) { + case BANK_NONE: + break; - case BANK_256K: - if (phys_bank != BANK_NONE) { - mem_mapping_set_addr(&scamp.ram_mapping[bank_nr], virt_base, 0x80000); - mem_mapping_set_exec(&scamp.ram_mapping[bank_nr], &ram[scamp.ram_phys_base[bank_nr]]); - } - virt_base += 512 * 1024; - scamp.row_virt_shift[bank_nr] = 10; - break; + case BANK_256K: + if (phys_bank != BANK_NONE) { + mem_mapping_set_addr(&scamp.ram_mapping[bank_nr], virt_base, 0x80000); + mem_mapping_set_exec(&scamp.ram_mapping[bank_nr], &ram[scamp.ram_phys_base[bank_nr]]); + } + virt_base += 512 * 1024; + scamp.row_virt_shift[bank_nr] = 10; + break; - case BANK_256K_INTERLEAVED: - if (phys_bank != BANK_NONE) { - mem_mapping_set_addr(&scamp.ram_mapping[bank_nr], virt_base, 0x100000); - mem_mapping_set_exec(&scamp.ram_mapping[bank_nr], &ram[scamp.ram_phys_base[bank_nr]]); - } - virt_base += 512 * 1024 * 2; - scamp.row_virt_shift[bank_nr] = 10; - break; + case BANK_256K_INTERLEAVED: + if (phys_bank != BANK_NONE) { + mem_mapping_set_addr(&scamp.ram_mapping[bank_nr], virt_base, 0x100000); + mem_mapping_set_exec(&scamp.ram_mapping[bank_nr], &ram[scamp.ram_phys_base[bank_nr]]); + } + virt_base += 512 * 1024 * 2; + scamp.row_virt_shift[bank_nr] = 10; + break; - case BANK_1M: - if (phys_bank != BANK_NONE) { - mem_mapping_set_addr(&scamp.ram_mapping[bank_nr], virt_base, 0x200000); - mem_mapping_set_exec(&scamp.ram_mapping[bank_nr], &ram[scamp.ram_phys_base[bank_nr]]); - } - virt_base += 2048 * 1024; - scamp.row_virt_shift[bank_nr] = 11; - break; + case BANK_1M: + if (phys_bank != BANK_NONE) { + mem_mapping_set_addr(&scamp.ram_mapping[bank_nr], virt_base, 0x200000); + mem_mapping_set_exec(&scamp.ram_mapping[bank_nr], &ram[scamp.ram_phys_base[bank_nr]]); + } + virt_base += 2048 * 1024; + scamp.row_virt_shift[bank_nr] = 11; + break; - case BANK_1M_INTERLEAVED: - if (phys_bank != BANK_NONE) { - mem_mapping_set_addr(&scamp.ram_mapping[bank_nr], virt_base, 0x400000); - mem_mapping_set_exec(&scamp.ram_mapping[bank_nr], &ram[scamp.ram_phys_base[bank_nr]]); - } - virt_base += 2048 * 1024 * 2; - scamp.row_virt_shift[bank_nr] = 11; - break; + case BANK_1M_INTERLEAVED: + if (phys_bank != BANK_NONE) { + mem_mapping_set_addr(&scamp.ram_mapping[bank_nr], virt_base, 0x400000); + mem_mapping_set_exec(&scamp.ram_mapping[bank_nr], &ram[scamp.ram_phys_base[bank_nr]]); + } + virt_base += 2048 * 1024 * 2; + scamp.row_virt_shift[bank_nr] = 11; + break; - case BANK_4M: - if (phys_bank != BANK_NONE) { - mem_mapping_set_addr(&scamp.ram_mapping[bank_nr], virt_base, 0x800000); - mem_mapping_set_exec(&scamp.ram_mapping[bank_nr], &ram[scamp.ram_phys_base[bank_nr]]); - } - virt_base += 8192 * 1024; - scamp.row_virt_shift[bank_nr] = 12; - break; + case BANK_4M: + if (phys_bank != BANK_NONE) { + mem_mapping_set_addr(&scamp.ram_mapping[bank_nr], virt_base, 0x800000); + mem_mapping_set_exec(&scamp.ram_mapping[bank_nr], &ram[scamp.ram_phys_base[bank_nr]]); + } + virt_base += 8192 * 1024; + scamp.row_virt_shift[bank_nr] = 12; + break; - case BANK_4M_INTERLEAVED: - if (phys_bank != BANK_NONE) { - mem_mapping_set_addr(&scamp.ram_mapping[bank_nr], virt_base, 0x1000000); - mem_mapping_set_exec(&scamp.ram_mapping[bank_nr], &ram[scamp.ram_phys_base[bank_nr]]); - } - virt_base += 8192 * 1024 * 2; - scamp.row_virt_shift[bank_nr] = 12; - break; - } - } - switch (rammap[cur_rammap].bank[bank_nr]) { - case BANK_256K: - case BANK_1M: - case BANK_4M: - mem_mapping_set_handler(&scamp.ram_mapping[bank_nr], - ram_mirrored_read, NULL, NULL, - ram_mirrored_write, NULL, NULL); - if (!old_virt_base) - mem_mapping_set_handler(&ram_low_mapping, - ram_mirrored_read, NULL, NULL, - ram_mirrored_write, NULL, NULL); - pclog(" not interleaved\n"); - break; + case BANK_4M_INTERLEAVED: + if (phys_bank != BANK_NONE) { + mem_mapping_set_addr(&scamp.ram_mapping[bank_nr], virt_base, 0x1000000); + mem_mapping_set_exec(&scamp.ram_mapping[bank_nr], &ram[scamp.ram_phys_base[bank_nr]]); + } + virt_base += 8192 * 1024 * 2; + scamp.row_virt_shift[bank_nr] = 12; + break; + } + } + switch (rammap[cur_rammap].bank[bank_nr]) { + case BANK_256K: + case BANK_1M: + case BANK_4M: + mem_mapping_set_handler(&scamp.ram_mapping[bank_nr], ram_mirrored_read, NULL, NULL, ram_mirrored_write, + NULL, NULL); + if (!old_virt_base) + mem_mapping_set_handler(&ram_low_mapping, ram_mirrored_read, NULL, NULL, ram_mirrored_write, NULL, + NULL); + pclog(" not interleaved\n"); + break; - case BANK_256K_INTERLEAVED: - case BANK_1M_INTERLEAVED: - mem_mapping_set_handler(&scamp.ram_mapping[bank_nr], - ram_mirrored_interleaved_read, NULL, NULL, - ram_mirrored_interleaved_write, NULL, NULL); - if (!old_virt_base) - mem_mapping_set_handler(&ram_low_mapping, - ram_mirrored_interleaved_read, NULL, NULL, - ram_mirrored_interleaved_write, NULL, NULL); - pclog(" interleaved\n"); - break; + case BANK_256K_INTERLEAVED: + case BANK_1M_INTERLEAVED: + mem_mapping_set_handler(&scamp.ram_mapping[bank_nr], ram_mirrored_interleaved_read, NULL, NULL, + ram_mirrored_interleaved_write, NULL, NULL); + if (!old_virt_base) + mem_mapping_set_handler(&ram_low_mapping, ram_mirrored_interleaved_read, NULL, NULL, + ram_mirrored_interleaved_write, NULL, NULL); + pclog(" interleaved\n"); + break; - case BANK_4M_INTERLEAVED: - if (phys_bank == BANK_256K || phys_bank == BANK_256K_INTERLEAVED) { - mem_mapping_set_handler(&scamp.ram_mapping[bank_nr], - ram_mirrored_256k_in_4mi_read, NULL, NULL, - ram_mirrored_256k_in_4mi_write, NULL, NULL); - if (!old_virt_base) - mem_mapping_set_handler(&ram_low_mapping, - ram_mirrored_256k_in_4mi_read, NULL, NULL, - ram_mirrored_256k_in_4mi_write, NULL, NULL); - pclog(" 256k in 4mi\n"); - } else { - mem_mapping_set_handler(&scamp.ram_mapping[bank_nr], - ram_mirrored_interleaved_read, NULL, NULL, - ram_mirrored_interleaved_write, NULL, NULL); - if (!old_virt_base) - mem_mapping_set_handler(&ram_low_mapping, - ram_mirrored_interleaved_read, NULL, NULL, - ram_mirrored_interleaved_write, NULL, NULL); - pclog(" interleaved\n"); - } - break; - } - } + case BANK_4M_INTERLEAVED: + if (phys_bank == BANK_256K || phys_bank == BANK_256K_INTERLEAVED) { + mem_mapping_set_handler(&scamp.ram_mapping[bank_nr], ram_mirrored_256k_in_4mi_read, NULL, NULL, + ram_mirrored_256k_in_4mi_write, NULL, NULL); + if (!old_virt_base) + mem_mapping_set_handler(&ram_low_mapping, ram_mirrored_256k_in_4mi_read, NULL, NULL, + ram_mirrored_256k_in_4mi_write, NULL, NULL); + pclog(" 256k in 4mi\n"); + } else { + mem_mapping_set_handler(&scamp.ram_mapping[bank_nr], ram_mirrored_interleaved_read, NULL, NULL, + ram_mirrored_interleaved_write, NULL, NULL); + if (!old_virt_base) + mem_mapping_set_handler(&ram_low_mapping, ram_mirrored_interleaved_read, NULL, NULL, + ram_mirrored_interleaved_write, NULL, NULL); + pclog(" interleaved\n"); + } + break; + } + } } static void recalc_sltptr(void) { - uint32_t sltptr = scamp.cfg_regs[CFG_SLTPTR] << 16; + uint32_t sltptr = scamp.cfg_regs[CFG_SLTPTR] << 16; - if (sltptr >= 0xa0000 && sltptr < 0x100000) - sltptr = 0x100000; - if (sltptr > 0xfe0000) - sltptr = 0xfe0000; + if (sltptr >= 0xa0000 && sltptr < 0x100000) + sltptr = 0x100000; + if (sltptr > 0xfe0000) + sltptr = 0xfe0000; -// pclog("sltptr=%06x\n", sltptr); - if (sltptr >= 0xa0000) { - mem_set_mem_state(0, 0xa0000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - mem_set_mem_state(0x100000, sltptr - 0x100000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - mem_set_mem_state(sltptr, 0x1000000 - sltptr, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - } else { - mem_set_mem_state(0, sltptr, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - mem_set_mem_state(sltptr, 0xa0000 - sltptr, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - mem_set_mem_state(0x100000, 0xf00000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - } + // pclog("sltptr=%06x\n", sltptr); + if (sltptr >= 0xa0000) { + mem_set_mem_state(0, 0xa0000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + mem_set_mem_state(0x100000, sltptr - 0x100000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + mem_set_mem_state(sltptr, 0x1000000 - sltptr, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + } else { + mem_set_mem_state(0, sltptr, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + mem_set_mem_state(sltptr, 0xa0000 - sltptr, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + mem_set_mem_state(0x100000, 0xf00000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + } } static uint8_t scamp_ems_read(uint32_t addr, void *p) { - int segment = (intptr_t)p; + int segment = (intptr_t)p; - addr = (addr & 0x3fff) | scamp.mappings[segment]; - return ram[addr]; + addr = (addr & 0x3fff) | scamp.mappings[segment]; + return ram[addr]; } static void scamp_ems_write(uint32_t addr, uint8_t val, void *p) { - int segment = (intptr_t)p; + int segment = (intptr_t)p; - addr = (addr & 0x3fff) | scamp.mappings[segment]; - ram[addr] = val; + addr = (addr & 0x3fff) | scamp.mappings[segment]; + ram[addr] = val; } static void recalc_ems(void) { - const uint32_t ems_base[12] = - { - 0xc0000, 0xc4000, 0xc8000, 0xcc000, - 0xd0000, 0xd4000, 0xd8000, 0xdc000, - 0xe0000, 0xe4000, 0xe8000, 0xec000 - }; - uint32_t new_mappings[20]; - uint16_t ems_enable; + const uint32_t ems_base[12] = {0xc0000, 0xc4000, 0xc8000, 0xcc000, 0xd0000, 0xd4000, + 0xd8000, 0xdc000, 0xe0000, 0xe4000, 0xe8000, 0xec000}; + uint32_t new_mappings[20]; + uint16_t ems_enable; - for (int segment = 0; segment < 20; segment++) - new_mappings[segment] = 0xa0000 + segment * 0x4000; + for (int segment = 0; segment < 20; segment++) + new_mappings[segment] = 0xa0000 + segment * 0x4000; - if (scamp.cfg_regs[CFG_EMSEN1] & EMSEN1_EMSENAB) - ems_enable = scamp.cfg_regs[CFG_EMSEN2] | ((scamp.cfg_regs[CFG_EMSEN1] & 0xf) << 8); - else - ems_enable = 0; + if (scamp.cfg_regs[CFG_EMSEN1] & EMSEN1_EMSENAB) + ems_enable = scamp.cfg_regs[CFG_EMSEN2] | ((scamp.cfg_regs[CFG_EMSEN1] & 0xf) << 8); + else + ems_enable = 0; - for (int segment = 0; segment < 12; segment++) { - if (ems_enable & (1 << segment)) { - uint32_t phys_addr = scamp.ems[segment] << 14; + for (int segment = 0; segment < 12; segment++) { + if (ems_enable & (1 << segment)) { + uint32_t phys_addr = scamp.ems[segment] << 14; - /*If physical address is in remapped memory then adjust down to a0000-fffff range*/ - if ((scamp.cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386) && phys_addr >= (mem_size * 1024) - && phys_addr < ((mem_size + 384) * 1024)) - phys_addr = (phys_addr - mem_size * 1024) + 0xa0000; - new_mappings[(ems_base[segment] - 0xa0000) >> 14] = phys_addr; - } - } + /*If physical address is in remapped memory then adjust down to a0000-fffff range*/ + if ((scamp.cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386) && phys_addr >= (mem_size * 1024) && + phys_addr < ((mem_size + 384) * 1024)) + phys_addr = (phys_addr - mem_size * 1024) + 0xa0000; + new_mappings[(ems_base[segment] - 0xa0000) >> 14] = phys_addr; + } + } - for (int segment = 0; segment < 20; segment++) { - if (new_mappings[segment] != scamp.mappings[segment]) { - scamp.mappings[segment] = new_mappings[segment]; - if (new_mappings[segment] < (mem_size * 1024)) { - mem_mapping_set_exec(&scamp.ems_mappings[segment], ram + scamp.mappings[segment]); - mem_mapping_enable(&scamp.ems_mappings[segment]); - } else - mem_mapping_disable(&scamp.ems_mappings[segment]); - } - } + for (int segment = 0; segment < 20; segment++) { + if (new_mappings[segment] != scamp.mappings[segment]) { + scamp.mappings[segment] = new_mappings[segment]; + if (new_mappings[segment] < (mem_size * 1024)) { + mem_mapping_set_exec(&scamp.ems_mappings[segment], ram + scamp.mappings[segment]); + mem_mapping_enable(&scamp.ems_mappings[segment]); + } else + mem_mapping_disable(&scamp.ems_mappings[segment]); + } + } } #define NR_ELEMS(x) (sizeof(x) / sizeof(x[0])) static void shadow_control(uint32_t addr, uint32_t size, int state, int ems_enable) { -// pclog("shadow_control: addr=%08x size=%04x state=%i\n", addr, size, state); - if (ems_enable) - mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - else - switch (state) { - 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_EXTERNAL | MEM_WRITE_INTERNAL); - break; - case 2:mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); - break; - case 3:mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - break; - } - flushmmucache_nopc(); + // pclog("shadow_control: addr=%08x size=%04x state=%i\n", addr, size, state); + if (ems_enable) + mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + else + switch (state) { + 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_EXTERNAL | MEM_WRITE_INTERNAL); + break; + case 2: + mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); + break; + case 3: + mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + break; + } + flushmmucache_nopc(); } static void shadow_recalc(void) { - uint8_t abaxs = (scamp.cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386) ? 0 : scamp.cfg_regs[CFG_ABAXS]; - uint8_t caxs = (scamp.cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386) ? 0 : scamp.cfg_regs[CFG_CAXS]; - uint8_t daxs = (scamp.cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386) ? 0 : scamp.cfg_regs[CFG_DAXS]; - uint8_t feaxs = (scamp.cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386) ? 0 : scamp.cfg_regs[CFG_FEAXS]; - uint32_t ems_enable; + uint8_t abaxs = (scamp.cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386) ? 0 : scamp.cfg_regs[CFG_ABAXS]; + uint8_t caxs = (scamp.cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386) ? 0 : scamp.cfg_regs[CFG_CAXS]; + uint8_t daxs = (scamp.cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386) ? 0 : scamp.cfg_regs[CFG_DAXS]; + uint8_t feaxs = (scamp.cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386) ? 0 : scamp.cfg_regs[CFG_FEAXS]; + uint32_t ems_enable; - if (scamp.cfg_regs[CFG_EMSEN1] & EMSEN1_EMSENAB) { - if (scamp.cfg_regs[CFG_EMSEN1] & EMSEN1_EMSMAP) /*Axxx/Bxxx/Dxxx*/ - ems_enable = (scamp.cfg_regs[CFG_EMSEN2] & 0xf) | ((scamp.cfg_regs[CFG_EMSEN1] & 0xf) << 4) | ((scamp.cfg_regs[CFG_EMSEN2] & 0xf0) << 8); - else /*Cxxx/Dxxx/Exxx*/ - ems_enable = (scamp.cfg_regs[CFG_EMSEN2] << 8) | ((scamp.cfg_regs[CFG_EMSEN1] & 0xf) << 16); - } else - ems_enable = 0; + if (scamp.cfg_regs[CFG_EMSEN1] & EMSEN1_EMSENAB) { + if (scamp.cfg_regs[CFG_EMSEN1] & EMSEN1_EMSMAP) /*Axxx/Bxxx/Dxxx*/ + ems_enable = (scamp.cfg_regs[CFG_EMSEN2] & 0xf) | ((scamp.cfg_regs[CFG_EMSEN1] & 0xf) << 4) | + ((scamp.cfg_regs[CFG_EMSEN2] & 0xf0) << 8); + else /*Cxxx/Dxxx/Exxx*/ + ems_enable = (scamp.cfg_regs[CFG_EMSEN2] << 8) | ((scamp.cfg_regs[CFG_EMSEN1] & 0xf) << 16); + } else + ems_enable = 0; - /*Enabling remapping will disable all shadowing*/ - if (scamp.cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386) - mem_remap_top_384k(); + /*Enabling remapping will disable all shadowing*/ + if (scamp.cfg_regs[CFG_RAMMAP] & RAMMAP_REMP386) + mem_remap_top_384k(); - shadow_control(0xa0000, 0x4000, abaxs & 3, ems_enable & 0x00001); - shadow_control(0xa0000, 0x4000, abaxs & 3, ems_enable & 0x00002); - shadow_control(0xa8000, 0x4000, (abaxs >> 2) & 3, ems_enable & 0x00004); - shadow_control(0xa8000, 0x4000, (abaxs >> 2) & 3, ems_enable & 0x00008); + shadow_control(0xa0000, 0x4000, abaxs & 3, ems_enable & 0x00001); + shadow_control(0xa0000, 0x4000, abaxs & 3, ems_enable & 0x00002); + shadow_control(0xa8000, 0x4000, (abaxs >> 2) & 3, ems_enable & 0x00004); + shadow_control(0xa8000, 0x4000, (abaxs >> 2) & 3, ems_enable & 0x00008); - shadow_control(0xb0000, 0x4000, (abaxs >> 4) & 3, ems_enable & 0x00010); - shadow_control(0xb0000, 0x4000, (abaxs >> 4) & 3, ems_enable & 0x00020); - shadow_control(0xb8000, 0x4000, (abaxs >> 6) & 3, ems_enable & 0x00040); - shadow_control(0xb8000, 0x4000, (abaxs >> 6) & 3, ems_enable & 0x00080); + shadow_control(0xb0000, 0x4000, (abaxs >> 4) & 3, ems_enable & 0x00010); + shadow_control(0xb0000, 0x4000, (abaxs >> 4) & 3, ems_enable & 0x00020); + shadow_control(0xb8000, 0x4000, (abaxs >> 6) & 3, ems_enable & 0x00040); + shadow_control(0xb8000, 0x4000, (abaxs >> 6) & 3, ems_enable & 0x00080); - shadow_control(0xc0000, 0x4000, caxs & 3, ems_enable & 0x00100); - shadow_control(0xc4000, 0x4000, (caxs >> 2) & 3, ems_enable & 0x00200); - shadow_control(0xc8000, 0x4000, (caxs >> 4) & 3, ems_enable & 0x00400); - shadow_control(0xcc000, 0x4000, (caxs >> 6) & 3, ems_enable & 0x00800); + shadow_control(0xc0000, 0x4000, caxs & 3, ems_enable & 0x00100); + shadow_control(0xc4000, 0x4000, (caxs >> 2) & 3, ems_enable & 0x00200); + shadow_control(0xc8000, 0x4000, (caxs >> 4) & 3, ems_enable & 0x00400); + shadow_control(0xcc000, 0x4000, (caxs >> 6) & 3, ems_enable & 0x00800); - shadow_control(0xd0000, 0x4000, daxs & 3, ems_enable & 0x01000); - shadow_control(0xd4000, 0x4000, (daxs >> 2) & 3, ems_enable & 0x02000); - shadow_control(0xd8000, 0x4000, (daxs >> 4) & 3, ems_enable & 0x04000); - shadow_control(0xdc000, 0x4000, (daxs >> 6) & 3, ems_enable & 0x08000); + shadow_control(0xd0000, 0x4000, daxs & 3, ems_enable & 0x01000); + shadow_control(0xd4000, 0x4000, (daxs >> 2) & 3, ems_enable & 0x02000); + shadow_control(0xd8000, 0x4000, (daxs >> 4) & 3, ems_enable & 0x04000); + shadow_control(0xdc000, 0x4000, (daxs >> 6) & 3, ems_enable & 0x08000); - shadow_control(0xe0000, 0x4000, feaxs & 3, ems_enable & 0x10000); - shadow_control(0xe4000, 0x4000, feaxs & 3, ems_enable & 0x20000); - shadow_control(0xe8000, 0x4000, (feaxs >> 2) & 3, ems_enable & 0x40000); - shadow_control(0xec000, 0x4000, (feaxs >> 2) & 3, ems_enable & 0x80000); + shadow_control(0xe0000, 0x4000, feaxs & 3, ems_enable & 0x10000); + shadow_control(0xe4000, 0x4000, feaxs & 3, ems_enable & 0x20000); + shadow_control(0xe8000, 0x4000, (feaxs >> 2) & 3, ems_enable & 0x40000); + shadow_control(0xec000, 0x4000, (feaxs >> 2) & 3, ems_enable & 0x80000); - shadow_control(0xf0000, 0x8000, (feaxs >> 4) & 3, 0); - shadow_control(0xf8000, 0x8000, (feaxs >> 6) & 3, 0); + shadow_control(0xf0000, 0x8000, (feaxs >> 4) & 3, 0); + shadow_control(0xf8000, 0x8000, (feaxs >> 6) & 3, 0); } void scamp_write(uint16_t addr, uint8_t val, void *p) { -// pclog("scamp_write: addr=%04x val=%02x\n", addr, val); - switch (addr) { - case 0x92: - if ((mem_a20_alt ^ val) & 2) { - mem_a20_alt = val & 2; - mem_a20_recalc(); - } - if ((~scamp.port_92 & val) & 1) { - softresetx86(); - cpu_set_edx(); - } - scamp.port_92 = val; - break; + // pclog("scamp_write: addr=%04x val=%02x\n", addr, val); + switch (addr) { + case 0x92: + if ((mem_a20_alt ^ val) & 2) { + mem_a20_alt = val & 2; + mem_a20_recalc(); + } + if ((~scamp.port_92 & val) & 1) { + softresetx86(); + cpu_set_edx(); + } + scamp.port_92 = val; + break; - case 0xe8:scamp.ems_index = val & 0x1f; - scamp.ems_autoinc = val & 0x40; - break; + case 0xe8: + scamp.ems_index = val & 0x1f; + scamp.ems_autoinc = val & 0x40; + break; - case 0xea: - if (scamp.ems_index < 0x24) { - scamp.ems[scamp.ems_index] = (scamp.ems[scamp.ems_index] & 0x300) | val; - recalc_ems(); - } -// pclog("EMS[%02x]=%03x (l)\n", scamp.ems_index, scamp.ems[scamp.ems_index]); - break; - case 0xeb: - if (scamp.ems_index < 0x24) { - scamp.ems[scamp.ems_index] = (scamp.ems[scamp.ems_index] & 0x0ff) | ((val & 3) << 8); - recalc_ems(); - } -// pclog("EMS[%02x]=%03x (h)\n", scamp.ems_index, scamp.ems[scamp.ems_index]); - if (scamp.ems_autoinc) - scamp.ems_index = (scamp.ems_index + 1) & 0x3f; - break; + case 0xea: + if (scamp.ems_index < 0x24) { + scamp.ems[scamp.ems_index] = (scamp.ems[scamp.ems_index] & 0x300) | val; + recalc_ems(); + } + // pclog("EMS[%02x]=%03x (l)\n", scamp.ems_index, scamp.ems[scamp.ems_index]); + break; + case 0xeb: + if (scamp.ems_index < 0x24) { + scamp.ems[scamp.ems_index] = (scamp.ems[scamp.ems_index] & 0x0ff) | ((val & 3) << 8); + recalc_ems(); + } + // pclog("EMS[%02x]=%03x (h)\n", scamp.ems_index, scamp.ems[scamp.ems_index]); + if (scamp.ems_autoinc) + scamp.ems_index = (scamp.ems_index + 1) & 0x3f; + break; - case 0xec: - if (scamp.cfg_enable) - scamp.cfg_index = val; - break; + case 0xec: + if (scamp.cfg_enable) + scamp.cfg_index = val; + break; - case 0xed: - if (scamp.cfg_enable) { - if (scamp.cfg_index >= 0x02 && scamp.cfg_index <= 0x16) { - scamp.cfg_regs[scamp.cfg_index] = val; -// pclog("SCAMP CFG[%02x]=%02x\n", scamp.cfg_index, val); - switch (scamp.cfg_index) { - case CFG_SLTPTR:recalc_sltptr(); - break; + case 0xed: + if (scamp.cfg_enable) { + if (scamp.cfg_index >= 0x02 && scamp.cfg_index <= 0x16) { + scamp.cfg_regs[scamp.cfg_index] = val; + // pclog("SCAMP CFG[%02x]=%02x\n", scamp.cfg_index, val); + switch (scamp.cfg_index) { + case CFG_SLTPTR: + recalc_sltptr(); + break; - case CFG_RAMMAP:recalc_mappings(); - mem_mapping_disable(&ram_remapped_mapping); - shadow_recalc(); - break; + case CFG_RAMMAP: + recalc_mappings(); + mem_mapping_disable(&ram_remapped_mapping); + shadow_recalc(); + break; - case CFG_EMSEN1: - case CFG_EMSEN2:shadow_recalc(); - recalc_ems(); - break; + case CFG_EMSEN1: + case CFG_EMSEN2: + shadow_recalc(); + recalc_ems(); + break; - case CFG_ABAXS: - case CFG_CAXS: - case CFG_DAXS: - case CFG_FEAXS:shadow_recalc(); - break; - } - } - } - break; + case CFG_ABAXS: + case CFG_CAXS: + case CFG_DAXS: + case CFG_FEAXS: + shadow_recalc(); + break; + } + } + } + break; - case 0xee: - if (scamp.cfg_enable && mem_a20_alt) { - scamp.port_92 &= ~2; - mem_a20_alt = 0; - mem_a20_recalc(); - } - break; - } + case 0xee: + if (scamp.cfg_enable && mem_a20_alt) { + scamp.port_92 &= ~2; + mem_a20_alt = 0; + mem_a20_recalc(); + } + break; + } } uint8_t scamp_read(uint16_t addr, void *p) { - uint8_t ret = 0xff; + uint8_t ret = 0xff; - switch (addr) { - case 0x92:ret = scamp.port_92; - break; + switch (addr) { + case 0x92: + ret = scamp.port_92; + break; - case 0xe8:ret = scamp.ems_index | scamp.ems_autoinc; - break; + case 0xe8: + ret = scamp.ems_index | scamp.ems_autoinc; + break; - case 0xea: - if (scamp.ems_index < 0x24) - ret = scamp.ems[scamp.ems_index] & 0xff; - break; - case 0xeb: - if (scamp.ems_index < 0x24) - ret = (scamp.ems[scamp.ems_index] >> 8) | 0xfc; - if (scamp.ems_autoinc) - scamp.ems_index = (scamp.ems_index + 1) & 0x3f; - break; + case 0xea: + if (scamp.ems_index < 0x24) + ret = scamp.ems[scamp.ems_index] & 0xff; + break; + case 0xeb: + if (scamp.ems_index < 0x24) + ret = (scamp.ems[scamp.ems_index] >> 8) | 0xfc; + if (scamp.ems_autoinc) + scamp.ems_index = (scamp.ems_index + 1) & 0x3f; + break; - case 0xed: - if (scamp.cfg_enable) { - if (scamp.cfg_index >= 0x00 && scamp.cfg_index <= 0x16) - ret = scamp.cfg_regs[scamp.cfg_index]; - } - break; + case 0xed: + if (scamp.cfg_enable) { + if (scamp.cfg_index >= 0x00 && scamp.cfg_index <= 0x16) + ret = scamp.cfg_regs[scamp.cfg_index]; + } + break; - case 0xee: - if (!mem_a20_alt) { - scamp.port_92 |= 2; - mem_a20_alt = 1; - mem_a20_recalc(); - } - break; + case 0xee: + if (!mem_a20_alt) { + scamp.port_92 |= 2; + mem_a20_alt = 1; + mem_a20_recalc(); + } + break; - case 0xef:softresetx86(); - cpu_set_edx(); - break; - } + case 0xef: + softresetx86(); + cpu_set_edx(); + break; + } -// pclog("scamp_read: addr=%04x ret=%02x\n", addr, ret); - return ret; + // pclog("scamp_read: addr=%04x ret=%02x\n", addr, ret); + return ret; } void scamp_init(void) { - uint32_t addr; - intptr_t c; + uint32_t addr; + intptr_t c; - memset(&scamp, 0, sizeof(scamp)); - scamp.cfg_regs[CFG_ID] = ID_VL82C311; - scamp.cfg_enable = 1; + memset(&scamp, 0, sizeof(scamp)); + scamp.cfg_regs[CFG_ID] = ID_VL82C311; + scamp.cfg_enable = 1; - io_sethandler(0x0092, 0x0001, scamp_read, NULL, NULL, scamp_write, NULL, NULL, NULL); - io_sethandler(0x00e8, 0x0001, scamp_read, NULL, NULL, scamp_write, NULL, NULL, NULL); - io_sethandler(0x00ea, 0x0006, scamp_read, NULL, NULL, scamp_write, NULL, NULL, NULL); - io_sethandler(0x00f4, 0x0002, scamp_read, NULL, NULL, scamp_write, NULL, NULL, NULL); - io_sethandler(0x00f9, 0x0001, scamp_read, NULL, NULL, scamp_write, NULL, NULL, NULL); - io_sethandler(0x00fb, 0x0001, scamp_read, NULL, NULL, scamp_write, NULL, NULL, NULL); + io_sethandler(0x0092, 0x0001, scamp_read, NULL, NULL, scamp_write, NULL, NULL, NULL); + io_sethandler(0x00e8, 0x0001, scamp_read, NULL, NULL, scamp_write, NULL, NULL, NULL); + io_sethandler(0x00ea, 0x0006, scamp_read, NULL, NULL, scamp_write, NULL, NULL, NULL); + io_sethandler(0x00f4, 0x0002, scamp_read, NULL, NULL, scamp_write, NULL, NULL, NULL); + io_sethandler(0x00f9, 0x0001, scamp_read, NULL, NULL, scamp_write, NULL, NULL, NULL); + io_sethandler(0x00fb, 0x0001, scamp_read, NULL, NULL, scamp_write, NULL, NULL, NULL); - scamp.ram_config = 0; + scamp.ram_config = 0; - /*Find best fit configuration for the requested memory size*/ - for (c = 0; c < NR_ELEMS(ram_configs); c++) { - if (mem_size < ram_configs[c].size_kb) - break; + /*Find best fit configuration for the requested memory size*/ + for (c = 0; c < NR_ELEMS(ram_configs); c++) { + if (mem_size < ram_configs[c].size_kb) + break; - scamp.ram_config = c; - } + scamp.ram_config = c; + } - mem_mapping_set_handler(&ram_low_mapping, - ram_mirrored_read, NULL, NULL, - ram_mirrored_write, NULL, NULL); - mem_mapping_disable(&ram_high_mapping); - mem_mapping_set_addr(&ram_mid_mapping, 0xf0000, 0x10000); - mem_mapping_set_exec(&ram_mid_mapping, ram + 0xf0000); + mem_mapping_set_handler(&ram_low_mapping, ram_mirrored_read, NULL, NULL, ram_mirrored_write, NULL, NULL); + mem_mapping_disable(&ram_high_mapping); + mem_mapping_set_addr(&ram_mid_mapping, 0xf0000, 0x10000); + mem_mapping_set_exec(&ram_mid_mapping, ram + 0xf0000); - mem_mapping_disable(&bios_mapping[0]); - mem_mapping_disable(&bios_mapping[1]); - mem_mapping_disable(&bios_mapping[2]); - mem_mapping_disable(&bios_mapping[3]); + mem_mapping_disable(&bios_mapping[0]); + mem_mapping_disable(&bios_mapping[1]); + mem_mapping_disable(&bios_mapping[2]); + mem_mapping_disable(&bios_mapping[3]); - addr = 0; - for (c = 0; c < 2; c++) { - mem_mapping_add(&scamp.ram_mapping[c], 0, 0, - ram_mirrored_read, NULL, NULL, - ram_mirrored_write, NULL, NULL, - &ram[addr], MEM_MAPPING_INTERNAL, (void *)c); - mem_mapping_disable(&scamp.ram_mapping[c]); + addr = 0; + for (c = 0; c < 2; c++) { + mem_mapping_add(&scamp.ram_mapping[c], 0, 0, ram_mirrored_read, NULL, NULL, ram_mirrored_write, NULL, NULL, + &ram[addr], MEM_MAPPING_INTERNAL, (void *)c); + mem_mapping_disable(&scamp.ram_mapping[c]); - scamp.ram_phys_base[c] = addr; -// pclog("Bank calc : %i = %08x\n", c ,addr); + scamp.ram_phys_base[c] = addr; + // pclog("Bank calc : %i = %08x\n", c ,addr); - switch (ram_configs[scamp.ram_config].bank[c]) { - case BANK_NONE:scamp.ram_mask[c] = 0; - scamp.ram_interleaved[c] = 0; - break; + switch (ram_configs[scamp.ram_config].bank[c]) { + case BANK_NONE: + scamp.ram_mask[c] = 0; + scamp.ram_interleaved[c] = 0; + break; - case BANK_256K:addr += 512 * 1024; - scamp.ram_mask[c] = 0x1ff; - scamp.row_phys_shift[c] = 10; - scamp.ram_interleaved[c] = 0; - break; + case BANK_256K: + addr += 512 * 1024; + scamp.ram_mask[c] = 0x1ff; + scamp.row_phys_shift[c] = 10; + scamp.ram_interleaved[c] = 0; + break; - case BANK_256K_INTERLEAVED:addr += 512 * 1024 * 2; - scamp.ram_mask[c] = 0x1ff; - scamp.row_phys_shift[c] = 10; - scamp.ibank_shift[c] = 19; - scamp.ram_interleaved[c] = 1; - break; + case BANK_256K_INTERLEAVED: + addr += 512 * 1024 * 2; + scamp.ram_mask[c] = 0x1ff; + scamp.row_phys_shift[c] = 10; + scamp.ibank_shift[c] = 19; + scamp.ram_interleaved[c] = 1; + break; - case BANK_1M:addr += 2048 * 1024; - scamp.ram_mask[c] = 0x3ff; - scamp.row_phys_shift[c] = 11; - scamp.ram_interleaved[c] = 0; - break; + case BANK_1M: + addr += 2048 * 1024; + scamp.ram_mask[c] = 0x3ff; + scamp.row_phys_shift[c] = 11; + scamp.ram_interleaved[c] = 0; + break; - case BANK_1M_INTERLEAVED:addr += 2048 * 1024 * 2; - scamp.ram_mask[c] = 0x3ff; - scamp.row_phys_shift[c] = 11; - scamp.ibank_shift[c] = 21; - scamp.ram_interleaved[c] = 1; - break; + case BANK_1M_INTERLEAVED: + addr += 2048 * 1024 * 2; + scamp.ram_mask[c] = 0x3ff; + scamp.row_phys_shift[c] = 11; + scamp.ibank_shift[c] = 21; + scamp.ram_interleaved[c] = 1; + break; - case BANK_4M:addr += 8192 * 1024; - scamp.ram_mask[c] = 0x7ff; - scamp.row_phys_shift[c] = 12; - scamp.ram_interleaved[c] = 0; - break; + case BANK_4M: + addr += 8192 * 1024; + scamp.ram_mask[c] = 0x7ff; + scamp.row_phys_shift[c] = 12; + scamp.ram_interleaved[c] = 0; + break; - case BANK_4M_INTERLEAVED:addr += 8192 * 1024 * 2; - scamp.ram_mask[c] = 0x7ff; - scamp.row_phys_shift[c] = 12; - scamp.ibank_shift[c] = 23; - scamp.ram_interleaved[c] = 1; - break; - } - } + case BANK_4M_INTERLEAVED: + addr += 8192 * 1024 * 2; + scamp.ram_mask[c] = 0x7ff; + scamp.row_phys_shift[c] = 12; + scamp.ibank_shift[c] = 23; + scamp.ram_interleaved[c] = 1; + break; + } + } - mem_set_mem_state(0xfe0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + mem_set_mem_state(0xfe0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - for (c = 0; c < 20; c++) { - mem_mapping_add(&scamp.ems_mappings[c], - 0xa0000 + c * 0x4000, 0x4000, - scamp_ems_read, NULL, NULL, - scamp_ems_write, NULL, NULL, - ram + 0xa0000 + c * 0x4000, MEM_MAPPING_INTERNAL, (void *)c); - scamp.mappings[c] = 0xa0000 + c * 0x4000; - } + for (c = 0; c < 20; c++) { + mem_mapping_add(&scamp.ems_mappings[c], 0xa0000 + c * 0x4000, 0x4000, scamp_ems_read, NULL, NULL, scamp_ems_write, + NULL, NULL, ram + 0xa0000 + c * 0x4000, MEM_MAPPING_INTERNAL, (void *)c); + scamp.mappings[c] = 0xa0000 + c * 0x4000; + } } diff --git a/src/models/scat.c b/src/models/scat.c index 5acab235..b4032310 100644 --- a/src/models/scat.c +++ b/src/models/scat.c @@ -20,1410 +20,1383 @@ 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 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 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}; uint8_t scat_read(uint16_t port, void *priv); void scat_write(uint16_t port, uint8_t val, void *priv); 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; - } + 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; - } + 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; + } } void scat_shadow_state_update() { - int i, val; + int i, val; - if ((scat_regs[SCAT_DRAM_CONFIGURATION] & 0xF) < 4) { - /*Less than 1MB low memory, no shadow RAM available*/ - for (i = 0; i < 24; i++) - mem_set_mem_state((i + 40) << 14, 0x4000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - } else { - 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); - } - } + if ((scat_regs[SCAT_DRAM_CONFIGURATION] & 0xF) < 4) { + /*Less than 1MB low memory, no shadow RAM available*/ + for (i = 0; i < 24; i++) + mem_set_mem_state((i + 40) << 14, 0x4000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + } else { + 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(); + flushmmucache(); } 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; + 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; - } + 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; -// pclog("Set XMS bound(%02X) = %06X(%dKbytes for EMS access)\n", val, scat_xms_bound, (0x160000 - scat_xms_bound) >> 10); - 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; -// pclog("Set XMS bound(%02X) = %06X(%dKbytes for EMS access)\n", val, scat_xms_bound, ((mem_size << 10) - scat_xms_bound) >> 10); - 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); - } + 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; + // pclog("Set XMS bound(%02X) = %06X(%dKbytes for EMS access)\n", val, scat_xms_bound, (0x160000 - + // scat_xms_bound) >> 10); + 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; + // pclog("Set XMS bound(%02X) = %06X(%dKbytes for EMS access)\n", val, scat_xms_bound, ((mem_size + // << 10) - scat_xms_bound) >> 10); + 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]); - } - } + 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]); + } + } } uint32_t get_scat_addr(uint32_t addr, scat_t *p) { - int nbank; + 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 (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 ((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 (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; - } + 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; + 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; - } - } + 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; + 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; } void scat_set_global_EMS_state(int state) { - int i; - uint32_t base_addr, virt_addr; + 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]); + 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(); + 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(); } void scat_memmap_state_update() { - int i; - uint32_t addr; + 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); -// pclog("scat_memmap_state_update : Address %06X to %06X\n", 0x40000 + (i << 14), addr); - } - addr = get_scat_addr(0, NULL); -// pclog("scat_memmap_state_update : Address 000000 to %06X\n", addr); - mem_mapping_set_exec(&scat_low_mapping[0], addr < (mem_size << 10) ? ram + addr : NULL); - addr = get_scat_addr(0xF0000, NULL); -// pclog("scat_memmap_state_update : Address 0F0000 to %06X\n", addr); - 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); -// pclog("scat_memmap_state_update : Address %06X to %06X\n", i << 19, 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); + // pclog("scat_memmap_state_update : Address %06X to %06X\n", 0x40000 + (i << 14), addr); + } + addr = get_scat_addr(0, NULL); + // pclog("scat_memmap_state_update : Address 000000 to %06X\n", addr); + mem_mapping_set_exec(&scat_low_mapping[0], addr < (mem_size << 10) ? ram + addr : NULL); + addr = get_scat_addr(0xF0000, NULL); + // pclog("scat_memmap_state_update : Address 0F0000 to %06X\n", addr); + 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); + // pclog("scat_memmap_state_update : Address %06X to %06X\n", i << 19, addr); + } - 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]); + 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] & 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]); - } - } + 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]); -// pclog("scat_memmap_state_update : Address %06X to %06X\n", 0x100000 + (i << 16), addr); - } - } 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]); - } + 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]); + // pclog("scat_memmap_state_update : Address %06X to %06X\n", + // 0x100000 + (i << 16), addr); + } + } 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); + scat_set_global_EMS_state(scat_regs[SCAT_EMS_CONTROL] & 0x80); } 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; + 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; + 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:cpu_set_nonturbo_divider((val & 0xc) > 0 ? 1 << ((val & 0xc) >> 2) : 0); - scat_reg_valid = 1; - break; - case SCAT_DRAM_CONFIGURATION:scat_map_update = 1; - scat_shadow_update = 1; + 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: + cpu_set_nonturbo_divider((val & 0xc) > 0 ? 1 << ((val & 0xc) >> 2) : 0); + scat_reg_valid = 1; + break; + case SCAT_DRAM_CONFIGURATION: + scat_map_update = 1; + scat_shadow_update = 1; - if ((scat_regs[SCAT_VERSION] & 0xF0) == 0) { - cpu_waitstates = (val & 0x70) == 0 ? 1 : 2; - cpu_update_waitstates(); - } + 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; - else - pclog("Attemped to write unimplemented SCAT register %02X at %04X:%04X\n", scat_index, val, CS, cpu_state.oldpc); - if (scat_shadow_update) - scat_shadow_state_update(); - if (scat_map_update) - scat_memmap_state_update(); -// pclog("Write SCAT Register %02X to %02X at %04X:%04X\n", scat_index, val, CS, cpu_state.pc); - break; + 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; + else + pclog("Attemped to write unimplemented SCAT register %02X at %04X:%04X\n", scat_index, val, CS, + cpu_state.oldpc); + if (scat_shadow_update) + scat_shadow_state_update(); + if (scat_map_update) + scat_memmap_state_update(); + // pclog("Write SCAT Register %02X to %02X at %04X:%04X\n", scat_index, val, CS, cpu_state.pc); + 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 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))) { -// pclog("Write SCAT EMS Control Port %04X to %02X at %04X:%04X\n", port, val, CS, cpu_state.pc); - 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; + case 0x208: + case 0x218: + if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == (0x40 | ((port & 0x10) >> 4))) { + // pclog("Write SCAT EMS Control Port %04X to %02X at %04X:%04X\n", port, val, CS, + // cpu_state.pc); + 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))) { -// pclog("Write SCAT EMS Control Port %04X to %02X at %04X:%04X\n", port, val, CS, cpu_state.pc); - 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) && (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))) { + // pclog("Write SCAT EMS Control Port %04X to %02X at %04X:%04X\n", port, val, CS, + // cpu_state.pc); + 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]); -// pclog("Map page %d(address %05X) to address %06X\n", index, base_addr, virt_addr); - } 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]); -// pclog("Unmap page %d(address %06X)\n", index, base_addr); - } - flushmmucache(); - } + 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]); + // pclog("Map page %d(address %05X) to address + // %06X\n", index, base_addr, virt_addr); + } 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]); + // pclog("Unmap page %d(address %06X)\n", index, + // base_addr); + } + 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))) { -// pclog("Write SCAT EMS Control Port %04X to %02X at %04X:%04X\n", port, val, CS, cpu_state.pc); - scat_ems_reg_2xA = ((scat_regs[SCAT_VERSION] & 0xF0) == 0) ? val : val & 0xc3; - } - break; - } + 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))) { + // pclog("Write SCAT EMS Control Port %04X to %02X at %04X:%04X\n", port, val, CS, + // cpu_state.pc); + scat_ems_reg_2xA = ((scat_regs[SCAT_VERSION] & 0xF0) == 0) ? val : val & 0xc3; + } + break; + } } 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_POWER_MANAGEMENT:val = (scat_regs[scat_index] & (cpu_get_turbo() ? 0xF3 : 0xFF)); - 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; - } -// pclog("Read SCAT Register %02X at %04X:%04X\n", scat_index, CS, cpu_state.pc); - break; + 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_POWER_MANAGEMENT: + val = (scat_regs[scat_index] & (cpu_get_turbo() ? 0xF3 : 0xFF)); + 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; + } + // pclog("Read SCAT Register %02X at %04X:%04X\n", scat_index, CS, cpu_state.pc); + break; - case 0x92:val = scat_port_92; - break; + case 0x92: + val = scat_port_92; + break; - case 0x208: - case 0x218: - if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == (0x40 | ((port & 0x10) >> 4))) { -// pclog("Read SCAT EMS Control Port %04X at %04X:%04X\n", port, CS, cpu_state.pc); - 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))) { -// pclog("Read SCAT EMS Control Port %04X at %04X:%04X\n", port, CS, cpu_state.pc); - 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))) { -// pclog("Read SCAT EMS Control Port %04X at %04X:%04X\n", port, CS, cpu_state.pc); - val = scat_ems_reg_2xA; - } - break; - } - return val; + case 0x208: + case 0x218: + if ((scat_regs[SCAT_EMS_CONTROL] & 0x41) == (0x40 | ((port & 0x10) >> 4))) { + // pclog("Read SCAT EMS Control Port %04X at %04X:%04X\n", port, CS, cpu_state.pc); + 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))) { + // pclog("Read SCAT EMS Control Port %04X at %04X:%04X\n", port, CS, cpu_state.pc); + 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))) { + // pclog("Read SCAT EMS Control Port %04X at %04X:%04X\n", port, CS, cpu_state.pc); + val = scat_ems_reg_2xA; + } + break; + } + return val; } uint8_t mem_read_scatb(uint32_t addr, void *priv) { - uint8_t val = 0xff; - scat_t *stat = (scat_t *)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]; + addr = get_scat_addr(addr, stat); + if (addr < (mem_size << 10)) + val = ram[addr]; - return val; + return val; } void mem_write_scatb(uint32_t addr, uint8_t val, void *priv) { - scat_t *stat = (scat_t *)priv; - uint32_t oldaddr = addr, chkaddr; + 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; + 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; } uint16_t mem_read_scatw(uint32_t addr, void *priv) { - uint16_t val = 0xffff; - scat_t *stat = (scat_t *)priv; + uint16_t val = 0xffff; + scat_t *stat = (scat_t *)priv; - if ((addr & 0x3FFF) == 0x3FFF) - pclog("mem_read_scatw(%08X, %p) called.\n", addr, priv); - addr = get_scat_addr(addr, stat); - if (addr < (mem_size << 10)) - val = *(uint16_t *)&ram[addr]; + if ((addr & 0x3FFF) == 0x3FFF) + pclog("mem_read_scatw(%08X, %p) called.\n", addr, priv); + addr = get_scat_addr(addr, stat); + if (addr < (mem_size << 10)) + val = *(uint16_t *)&ram[addr]; - return val; + return val; } void mem_write_scatw(uint32_t addr, uint16_t val, void *priv) { - scat_t *stat = (scat_t *)priv; - uint32_t oldaddr = addr, chkaddr; + scat_t *stat = (scat_t *)priv; + uint32_t oldaddr = addr, chkaddr; - if ((addr & 0x3FFF) == 0x3FFF) - pclog("mem_write_scatw(%08X, %04X, %p) called.\n", addr, val, priv); - 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; + if ((addr & 0x3FFF) == 0x3FFF) + pclog("mem_write_scatw(%08X, %04X, %p) called.\n", addr, val, priv); + 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; } uint32_t mem_read_scatl(uint32_t addr, void *priv) { - uint32_t val = 0xffffffff; - scat_t *stat = (scat_t *)priv; + uint32_t val = 0xffffffff; + scat_t *stat = (scat_t *)priv; - if ((addr & 0x3FFF) > 0x3FFC) - pclog("mem_read_scatl(%08X, %p) called.\n", addr, priv); - addr = get_scat_addr(addr, stat); - if (addr < (mem_size << 10)) - val = *(uint32_t *)&ram[addr]; + if ((addr & 0x3FFF) > 0x3FFC) + pclog("mem_read_scatl(%08X, %p) called.\n", addr, priv); + addr = get_scat_addr(addr, stat); + if (addr < (mem_size << 10)) + val = *(uint32_t *)&ram[addr]; - return val; + return val; } void mem_write_scatl(uint32_t addr, uint32_t val, void *priv) { - scat_t *stat = (scat_t *)priv; - uint32_t oldaddr = addr, chkaddr; + scat_t *stat = (scat_t *)priv; + uint32_t oldaddr = addr, chkaddr; - if ((addr & 0x3FFF) > 0x3FFC) - pclog("mem_write_scatl(%08X, %08X, %p) called.\n", addr, val, priv); - 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; + if ((addr & 0x3FFF) > 0x3FFC) + pclog("mem_write_scatl(%08X, %08X, %p) called.\n", addr, val, priv); + 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; } void scat_init() { - int i; + 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); + 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; - } + 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: - case ROM_SPC4620P: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; + scat_regs[SCAT_DMA_WAIT_STATE_CONTROL] = 0; + switch (romset) { + case ROM_GW286CT: + case ROM_SPC4216P: + case ROM_SPC4620P: + 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); + 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 < 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 = 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 = (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 = (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); + 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; + 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(); + scat_set_xms_bound(0); + scat_memmap_state_update(); + scat_shadow_state_update(); } void scatsx_init() { - int i; + 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); + 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; - } + 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; + 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); + 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 = 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 = 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 < 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); + 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]; + external_is_RAS = scatsx_external_is_RAS[mem_size >> 9]; - scat_set_xms_bound(0); - scat_memmap_state_update(); - scat_shadow_state_update(); + scat_set_xms_bound(0); + scat_memmap_state_update(); + scat_shadow_state_update(); } diff --git a/src/models/serial.c b/src/models/serial.c index 8bf82b18..d21096dd 100644 --- a/src/models/serial.c +++ b/src/models/serial.c @@ -5,256 +5,252 @@ #include "serial.h" #include "timer.h" -enum { - SERIAL_INT_LSR = 1, - SERIAL_INT_RECEIVE = 2, - SERIAL_INT_TRANSMIT = 4, - SERIAL_INT_MSR = 8 -}; +enum { SERIAL_INT_LSR = 1, SERIAL_INT_RECEIVE = 2, SERIAL_INT_TRANSMIT = 4, SERIAL_INT_MSR = 8 }; SERIAL serial1, serial2; 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; + 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; + int stat = 0; - serial->iir = 1; + 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)) /*Received 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 ((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)) /*Received 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); + if (stat && ((serial->mctrl & 8) || PCJR)) + picintlevel(1 << serial->irq); + else + picintc(1 << serial->irq); } void serial_write_fifo(SERIAL *serial, uint8_t dat) { -// pclog("serial_write_fifo %02X\n", serial->lsr); - 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); - } + // pclog("serial_write_fifo %02X\n", serial->lsr); + 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; + 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; -// pclog("Write serial %03X %02X %04X:%04X\n",addr,val,CS,pc); - 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: - if (serial->has_fifo) - 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); -// pclog("RCR raised! sending M\n"); - } - serial->mctrl = val; - if (val & 0x10) { - uint8_t new_msr; + SERIAL *serial = (SERIAL *)p; + // pclog("Write serial %03X %02X %04X:%04X\n",addr,val,CS,pc); + 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: + if (serial->has_fifo) + 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); + // pclog("RCR raised! sending M\n"); + } + 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; + 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; + 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; - } + 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; -// pclog("Read serial %03X %04X(%08X):%04X %i %i ", addr, CS, cs, pc, mousedelay, ins); - switch (addr & 7) { - case 0: - if (serial->lcr & 0x80) { - temp = serial->dlab1; - break; - } + SERIAL *serial = (SERIAL *)p; + uint8_t temp = 0; + // pclog("Read serial %03X %04X(%08X):%04X %i %i ", addr, CS, cs, pc, mousedelay, ins); + 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) - timer_set_delay_u64(&serial->receive_timer, 1000 * 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.lsr |= 0x60; - 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; - } -// pclog("%02X\n",temp); - return temp; + 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) + timer_set_delay_u64(&serial->receive_timer, 1000 * 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.lsr |= 0x60; + 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; + } + // pclog("%02X\n",temp); + return temp; } void serial_receive_callback(void *p) { - SERIAL *serial = (SERIAL *)p; + SERIAL *serial = (SERIAL *)p; - if (serial->fifo_read != serial->fifo_write) { - serial->lsr |= 1; - serial->int_status |= SERIAL_INT_RECEIVE; - serial_update_ints(serial); - } + if (serial->fifo_read != serial->fifo_write) { + serial->lsr |= 1; + serial->int_status |= SERIAL_INT_RECEIVE; + serial_update_ints(serial); + } } /*Tandy might need COM1 at 2f8*/ void serial1_init(uint16_t addr, int irq, int has_fifo) { - memset(&serial1, 0, sizeof(serial1)); - io_sethandler(addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); - serial1.irq = irq; - serial1.addr = addr; - serial1.rcr_callback = NULL; - timer_add(&serial1.receive_timer, serial_receive_callback, &serial1, 0); - serial1.has_fifo = has_fifo; + memset(&serial1, 0, sizeof(serial1)); + io_sethandler(addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); + serial1.irq = irq; + serial1.addr = addr; + serial1.rcr_callback = NULL; + timer_add(&serial1.receive_timer, serial_receive_callback, &serial1, 0); + serial1.has_fifo = has_fifo; } void serial1_set(uint16_t addr, int irq) { - serial1_remove(); - io_sethandler(addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); - serial1.irq = irq; - serial1.addr = addr; -} -void serial1_set_has_fifo(int has_fifo) { - serial1.has_fifo = has_fifo; -} -void serial1_remove() { - io_removehandler(serial1.addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); + serial1_remove(); + io_sethandler(addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); + serial1.irq = irq; + serial1.addr = addr; } +void serial1_set_has_fifo(int has_fifo) { serial1.has_fifo = has_fifo; } +void serial1_remove() { io_removehandler(serial1.addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); } void serial2_init(uint16_t addr, int irq, int has_fifo) { - memset(&serial2, 0, sizeof(serial2)); - io_sethandler(addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); - serial2.irq = irq; - serial2.addr = addr; - serial2.rcr_callback = NULL; - timer_add(&serial2.receive_timer, serial_receive_callback, &serial2, 0); - serial2.has_fifo = has_fifo; + memset(&serial2, 0, sizeof(serial2)); + io_sethandler(addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); + serial2.irq = irq; + serial2.addr = addr; + serial2.rcr_callback = NULL; + timer_add(&serial2.receive_timer, serial_receive_callback, &serial2, 0); + serial2.has_fifo = has_fifo; } void serial2_set(uint16_t addr, int irq) { - serial2_remove(); - io_sethandler(addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); - serial2.irq = irq; - serial2.addr = addr; -} -void serial2_set_has_fifo(int has_fifo) { - serial2.has_fifo = has_fifo; -} -void serial2_remove() { - io_removehandler(serial2.addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); + serial2_remove(); + io_sethandler(addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); + serial2.irq = irq; + serial2.addr = addr; } +void serial2_set_has_fifo(int has_fifo) { serial2.has_fifo = has_fifo; } +void serial2_remove() { io_removehandler(serial2.addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); } diff --git a/src/models/sio.c b/src/models/sio.c index d260ab07..888c38ab 100644 --- a/src/models/sio.c +++ b/src/models/sio.c @@ -9,183 +9,192 @@ #include "sio.h" typedef struct sio_t { - struct { - uint8_t apmc, apms; - } pm; + struct { + uint8_t apmc, apms; + } pm; } sio_t; static sio_t sio; static uint8_t card_sio[256]; -//static int pci_cards_ids[4]; +// static int pci_cards_ids[4]; #define REG_SMIEN 0xa2 #define REG_SMIREQ 0xaa -#define SMIEN_APMC (1 << 7) +#define SMIEN_APMC (1 << 7) #define SMIREQ_RAPMC (1 << 7) void sio_write(int func, int addr, uint8_t val, void *priv) { -// pclog("sio_write: func=%d addr=%02x val=%02x %04x:%08x\n", func, addr, val, CS, cpu_state.pc); - if (func > 0) - return; + // pclog("sio_write: func=%d addr=%02x val=%02x %04x:%08x\n", func, addr, val, CS, cpu_state.pc); + if (func > 0) + return; - if (addr >= 0x0f && addr < 0x4c) - 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; + 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 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 0x06: /*Status*/ + val = 0; + break; + case 0x07: + val = 0x02; + break; - case 0x60: -// pclog("IRQ routing %02x %02x\n", addr, 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("IRQ routing %02x %02x\n", addr, val); - if (val & 0x80) - pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED); - else - pci_set_irq_routing(PCI_INTC, val & 0xf); - break; - case 0x62: -// pclog("IRQ routing %02x %02x\n", addr, val); - if (val & 0x80) - pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED); - else - pci_set_irq_routing(PCI_INTB, val & 0xf); - break; - case 0x63: -// pclog("IRQ routing %02x %02x\n", addr, val); - if (val & 0x80) - pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); - else - pci_set_irq_routing(PCI_INTD, val & 0xf); - break; + case 0x60: + // pclog("IRQ routing %02x %02x\n", addr, 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("IRQ routing %02x %02x\n", addr, val); + if (val & 0x80) + pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED); + else + pci_set_irq_routing(PCI_INTC, val & 0xf); + break; + case 0x62: + // pclog("IRQ routing %02x %02x\n", addr, val); + if (val & 0x80) + pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED); + else + pci_set_irq_routing(PCI_INTB, val & 0xf); + break; + case 0x63: + // pclog("IRQ routing %02x %02x\n", addr, val); + if (val & 0x80) + pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); + else + pci_set_irq_routing(PCI_INTD, val & 0xf); + break; - case REG_SMIREQ:card_sio[addr] &= val; - return; - case REG_SMIREQ + 1:card_sio[addr] &= val; - return; - } - card_sio[addr] = val; + case REG_SMIREQ: + card_sio[addr] &= val; + return; + case REG_SMIREQ + 1: + card_sio[addr] &= val; + return; + } + card_sio[addr] = val; } uint8_t sio_read(int func, int addr, void *priv) { -// pclog("sio_read: func=%d addr=%02x %04x:%08x\n", func, addr, CS, pc); - if (func > 0) - return 0xff; + // pclog("sio_read: func=%d addr=%02x %04x:%08x\n", func, addr, CS, pc); + if (func > 0) + return 0xff; - return card_sio[addr]; + return card_sio[addr]; } static uint8_t sio_apm_read(uint16_t port, void *p) { - sio_t *sio = (sio_t *)p; - uint8_t ret = 0xff; + sio_t *sio = (sio_t *)p; + uint8_t ret = 0xff; - switch (port) { - case 0xb2:ret = sio->pm.apmc; - break; + switch (port) { + case 0xb2: + ret = sio->pm.apmc; + break; - case 0xb3:ret = sio->pm.apms; - break; - } -// pclog("sio_apm_read: port=%04x ret=%02x\n", port, ret); - return ret; + case 0xb3: + ret = sio->pm.apms; + break; + } + // pclog("sio_apm_read: port=%04x ret=%02x\n", port, ret); + return ret; } static void sio_apm_write(uint16_t port, uint8_t val, void *p) { - sio_t *sio = (sio_t *)p; + sio_t *sio = (sio_t *)p; -// pclog("sio_apm_write: port=%04x val=%02x\n", port, val); + // pclog("sio_apm_write: port=%04x val=%02x\n", port, val); - switch (port) { - case 0xb2:sio->pm.apmc = val; - if (card_sio[REG_SMIEN] & SMIEN_APMC) { - card_sio[REG_SMIREQ] |= SMIREQ_RAPMC; -// pclog("APMC write causes SMI\n"); - x86_smi_trigger(); - } - break; + switch (port) { + case 0xb2: + sio->pm.apmc = val; + if (card_sio[REG_SMIEN] & SMIEN_APMC) { + card_sio[REG_SMIREQ] |= SMIREQ_RAPMC; + // pclog("APMC write causes SMI\n"); + x86_smi_trigger(); + } + break; - case 0xb3:sio->pm.apms = val; - break; - } + case 0xb3: + sio->pm.apms = val; + break; + } } void sio_init(int card, int pci_a, int pci_b, int pci_c, int pci_d) { - memset(&sio, 0, sizeof(sio_t)); + memset(&sio, 0, sizeof(sio_t)); - pci_add_specific(card, sio_read, sio_write, NULL); + pci_add_specific(card, sio_read, sio_write, NULL); - memset(card_sio, 0, 256); - card_sio[0x00] = 0x86; - card_sio[0x01] = 0x80; /*Intel*/ - card_sio[0x02] = 0x84; - card_sio[0x03] = 0x04; /*82378IB (SIO)*/ - card_sio[0x04] = 0x07; - card_sio[0x05] = 0x00; - card_sio[0x06] = 0x00; - card_sio[0x07] = 0x02; - card_sio[0x08] = 0x03; /*A0 stepping*/ + memset(card_sio, 0, 256); + card_sio[0x00] = 0x86; + card_sio[0x01] = 0x80; /*Intel*/ + card_sio[0x02] = 0x84; + card_sio[0x03] = 0x04; /*82378IB (SIO)*/ + card_sio[0x04] = 0x07; + card_sio[0x05] = 0x00; + card_sio[0x06] = 0x00; + card_sio[0x07] = 0x02; + card_sio[0x08] = 0x03; /*A0 stepping*/ - card_sio[0x40] = 0x20; - card_sio[0x41] = 0x00; - card_sio[0x42] = 0x04; - card_sio[0x43] = 0x00; - card_sio[0x44] = 0x20; - card_sio[0x45] = 0x10; - card_sio[0x46] = 0x0f; - card_sio[0x47] = 0x00; - card_sio[0x48] = 0x01; - card_sio[0x49] = 0x10; - card_sio[0x4a] = 0x10; - card_sio[0x4b] = 0x0f; - card_sio[0x4c] = 0x56; - card_sio[0x4d] = 0x40; - card_sio[0x4e] = 0x07; - card_sio[0x4f] = 0x4f; - card_sio[0x54] = 0x00; - card_sio[0x55] = 0x00; - card_sio[0x56] = 0x00; - card_sio[0x60] = 0x80; - card_sio[0x61] = 0x80; - card_sio[0x62] = 0x80; - card_sio[0x63] = 0x80; - card_sio[0x80] = 0x78; - card_sio[0x81] = 0x00; - card_sio[0xa0] = 0x08; - card_sio[0xa8] = 0x0f; + card_sio[0x40] = 0x20; + card_sio[0x41] = 0x00; + card_sio[0x42] = 0x04; + card_sio[0x43] = 0x00; + card_sio[0x44] = 0x20; + card_sio[0x45] = 0x10; + card_sio[0x46] = 0x0f; + card_sio[0x47] = 0x00; + card_sio[0x48] = 0x01; + card_sio[0x49] = 0x10; + card_sio[0x4a] = 0x10; + card_sio[0x4b] = 0x0f; + card_sio[0x4c] = 0x56; + card_sio[0x4d] = 0x40; + card_sio[0x4e] = 0x07; + card_sio[0x4f] = 0x4f; + card_sio[0x54] = 0x00; + card_sio[0x55] = 0x00; + card_sio[0x56] = 0x00; + card_sio[0x60] = 0x80; + card_sio[0x61] = 0x80; + card_sio[0x62] = 0x80; + card_sio[0x63] = 0x80; + card_sio[0x80] = 0x78; + card_sio[0x81] = 0x00; + card_sio[0xa0] = 0x08; + card_sio[0xa8] = 0x0f; - if (pci_a) - pci_set_card_routing(pci_a, PCI_INTA); - if (pci_b) - pci_set_card_routing(pci_b, PCI_INTB); - if (pci_c) - pci_set_card_routing(pci_c, PCI_INTC); - if (pci_d) - pci_set_card_routing(pci_d, PCI_INTD); + if (pci_a) + pci_set_card_routing(pci_a, PCI_INTA); + if (pci_b) + pci_set_card_routing(pci_b, PCI_INTB); + if (pci_c) + pci_set_card_routing(pci_c, PCI_INTC); + if (pci_d) + pci_set_card_routing(pci_d, PCI_INTD); - io_sethandler(0x00b2, 0x0002, sio_apm_read, NULL, NULL, sio_apm_write, NULL, NULL, &sio); + io_sethandler(0x00b2, 0x0002, sio_apm_read, NULL, NULL, sio_apm_write, NULL, NULL, &sio); } diff --git a/src/models/sl82c460.c b/src/models/sl82c460.c index a2b09ecb..4e8f05bd 100644 --- a/src/models/sl82c460.c +++ b/src/models/sl82c460.c @@ -4,61 +4,65 @@ #include "sl82c460.h" static struct { - int reg_idx; - uint8_t regs[256]; + int reg_idx; + uint8_t regs[256]; } sl82c460; static void sl82c460_shadow_set(uint32_t base, uint32_t size, int state) { - switch (state) { - case 0:mem_set_mem_state(base, size, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - break; - case 1:mem_set_mem_state(base, size, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); - break; - case 2:mem_set_mem_state(base, size, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); - break; - case 3:mem_set_mem_state(base, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - break; - } - + switch (state) { + case 0: + mem_set_mem_state(base, size, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + break; + case 1: + mem_set_mem_state(base, size, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); + break; + case 2: + mem_set_mem_state(base, size, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); + break; + case 3: + mem_set_mem_state(base, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + break; + } } static void sl82c460_shadow_recalc() { - sl82c460_shadow_set(0xc0000, 0x4000, sl82c460.regs[0x18] & 3); - sl82c460_shadow_set(0xc4000, 0x4000, (sl82c460.regs[0x18] >> 2) & 3); - sl82c460_shadow_set(0xc8000, 0x4000, (sl82c460.regs[0x18] >> 4) & 3); - sl82c460_shadow_set(0xcc000, 0x4000, (sl82c460.regs[0x18] >> 6) & 3); - sl82c460_shadow_set(0xd0000, 0x4000, sl82c460.regs[0x19] & 3); - sl82c460_shadow_set(0xd4000, 0x4000, (sl82c460.regs[0x19] >> 2) & 3); - sl82c460_shadow_set(0xd8000, 0x4000, (sl82c460.regs[0x19] >> 4) & 3); - sl82c460_shadow_set(0xdc000, 0x4000, (sl82c460.regs[0x19] >> 6) & 3); - sl82c460_shadow_set(0xe0000, 0x10000, (sl82c460.regs[0x1b] >> 4) & 3); - sl82c460_shadow_set(0xf0000, 0x10000, (sl82c460.regs[0x1b] >> 2) & 3); + sl82c460_shadow_set(0xc0000, 0x4000, sl82c460.regs[0x18] & 3); + sl82c460_shadow_set(0xc4000, 0x4000, (sl82c460.regs[0x18] >> 2) & 3); + sl82c460_shadow_set(0xc8000, 0x4000, (sl82c460.regs[0x18] >> 4) & 3); + sl82c460_shadow_set(0xcc000, 0x4000, (sl82c460.regs[0x18] >> 6) & 3); + sl82c460_shadow_set(0xd0000, 0x4000, sl82c460.regs[0x19] & 3); + sl82c460_shadow_set(0xd4000, 0x4000, (sl82c460.regs[0x19] >> 2) & 3); + sl82c460_shadow_set(0xd8000, 0x4000, (sl82c460.regs[0x19] >> 4) & 3); + sl82c460_shadow_set(0xdc000, 0x4000, (sl82c460.regs[0x19] >> 6) & 3); + sl82c460_shadow_set(0xe0000, 0x10000, (sl82c460.regs[0x1b] >> 4) & 3); + sl82c460_shadow_set(0xf0000, 0x10000, (sl82c460.regs[0x1b] >> 2) & 3); } static void sl82c460_write(uint16_t addr, uint8_t val, void *p) { - if (!(addr & 1)) - sl82c460.reg_idx = val; - else { -// pclog("SL82C460 write %02x %02x\n", sl82c460.reg_idx, val); - sl82c460.regs[sl82c460.reg_idx] = val; + if (!(addr & 1)) + sl82c460.reg_idx = val; + else { + // pclog("SL82C460 write %02x %02x\n", sl82c460.reg_idx, val); + sl82c460.regs[sl82c460.reg_idx] = val; - switch (sl82c460.reg_idx) { - case 0x18: - case 0x19: - case 0x1b:sl82c460_shadow_recalc(); - break; - } - } + switch (sl82c460.reg_idx) { + case 0x18: + case 0x19: + case 0x1b: + sl82c460_shadow_recalc(); + break; + } + } } static uint8_t sl82c460_read(uint16_t addr, void *p) { - if (!(addr & 1)) - return sl82c460.reg_idx; + if (!(addr & 1)) + return sl82c460.reg_idx; - return sl82c460.regs[sl82c460.reg_idx]; + return sl82c460.regs[sl82c460.reg_idx]; } void sl82c460_init() { - memset(&sl82c460, 0, sizeof(sl82c460)); - io_sethandler(0x00a8, 0x0002, sl82c460_read, NULL, NULL, sl82c460_write, NULL, NULL, NULL); + memset(&sl82c460, 0, sizeof(sl82c460)); + io_sethandler(0x00a8, 0x0002, sl82c460_read, NULL, NULL, sl82c460_write, NULL, NULL, NULL); } diff --git a/src/models/superxt.c b/src/models/superxt.c index b570c840..dd2dc6c5 100644 --- a/src/models/superxt.c +++ b/src/models/superxt.c @@ -9,47 +9,53 @@ static int superxt_index; static int superxt_emspage[4]; void superxt_write(uint16_t port, uint8_t val, void *priv) { - switch (port) { - case 0x22:superxt_index = val; - break; + switch (port) { + case 0x22: + superxt_index = val; + break; - case 0x23:superxt_regs[superxt_index] = val; + case 0x23: + superxt_regs[superxt_index] = val; - case 0x0208: - case 0x4208: - case 0x8208: - case 0xC208:superxt_emspage[port >> 14] = val; - break; + case 0x0208: + case 0x4208: + case 0x8208: + case 0xC208: + superxt_emspage[port >> 14] = val; + break; - // default: - // pclog("%04X:%04X SUPERXT WRITE : %04X, %02X\n", CS, cpu_state.pc, port, val); - } + // default: + // pclog("%04X:%04X SUPERXT WRITE : %04X, %02X\n", CS, cpu_state.pc, port, val); + } } uint8_t superxt_read(uint16_t port, void *priv) { - switch (port) { - case 0x22:return superxt_index; + switch (port) { + case 0x22: + return superxt_index; - case 0x23:return superxt_regs[superxt_index]; + case 0x23: + return superxt_regs[superxt_index]; - case 0x0208: - case 0x4208: - case 0x8208: - case 0xC208:return superxt_emspage[port >> 14]; + case 0x0208: + case 0x4208: + case 0x8208: + case 0xC208: + return superxt_emspage[port >> 14]; - // default: - // pclog("%04X:%04X SUPERXT READ : %04X\n", CS, cpu_state.pc, port); - } - return 0xff; + // default: + // pclog("%04X:%04X SUPERXT READ : %04X\n", CS, cpu_state.pc, port); + } + return 0xff; } void superxt_init() { - /* Set register 0x42 to invalid configuration at startup */ - superxt_regs[0x42] = 0; + /* Set register 0x42 to invalid configuration at startup */ + superxt_regs[0x42] = 0; - io_sethandler(0x0022, 0x0002, superxt_read, NULL, NULL, superxt_write, NULL, NULL, NULL); - io_sethandler(0x0208, 0x0001, superxt_read, NULL, NULL, superxt_write, NULL, NULL, NULL); - io_sethandler(0x4208, 0x0001, superxt_read, NULL, NULL, superxt_write, NULL, NULL, NULL); - io_sethandler(0x8208, 0x0001, superxt_read, NULL, NULL, superxt_write, NULL, NULL, NULL); - io_sethandler(0xc208, 0x0001, superxt_read, NULL, NULL, superxt_write, NULL, NULL, NULL); + io_sethandler(0x0022, 0x0002, superxt_read, NULL, NULL, superxt_write, NULL, NULL, NULL); + io_sethandler(0x0208, 0x0001, superxt_read, NULL, NULL, superxt_write, NULL, NULL, NULL); + io_sethandler(0x4208, 0x0001, superxt_read, NULL, NULL, superxt_write, NULL, NULL, NULL); + io_sethandler(0x8208, 0x0001, superxt_read, NULL, NULL, superxt_write, NULL, NULL, NULL); + io_sethandler(0xc208, 0x0001, superxt_read, NULL, NULL, superxt_write, NULL, NULL, NULL); } diff --git a/src/models/t1000.c b/src/models/t1000.c index 948c62b5..6670f5d9 100644 --- a/src/models/t1000.c +++ b/src/models/t1000.c @@ -15,18 +15,18 @@ #include "keyboard_xt.h" #include "vid_t1000.h" -/* The T1000 is the T3100e's little brother -- a real laptop with a - * rechargeable battery. +/* 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 + * 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 + * 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. * @@ -36,15 +36,15 @@ * > 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 + * 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 + * 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]. + * 01F2h: If hard drive is present, low 4 bits are 0Ch [20Mb] or 0Dh [10Mb]. * */ @@ -54,358 +54,358 @@ uint8_t t1000_nvram[160]; uint8_t t1200_nvram[2048]; static struct t1000_system { - /* ROM drive */ - uint8_t *romdrive; - uint8_t rom_ctl; - uint32_t rom_offset; - mem_mapping_t rom_mapping; + /* ROM drive */ + uint8_t *romdrive; + uint8_t rom_ctl; + uint32_t rom_offset; + mem_mapping_t rom_mapping; - /* System control registers */ - uint8_t sys_ctl[16]; - uint8_t syskeys; - uint8_t turbo; + /* 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 */ + /* 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; + /* 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; } t1000; -#define T1000_ROMSIZE (512 * 1024) /* Maximum ROM drive size is 512k */ +#define T1000_ROMSIZE (512 * 1024) /* Maximum ROM drive size is 512k */ -/* The CONFIG.SYS storage (160 bytes) and battery-backed EMS (all RAM +/* The CONFIG.SYS storage (160 bytes) and battery-backed EMS (all RAM * above 512k) are implemented as NVR devices */ void t1000_configsys_loadnvr() { - FILE *f; + FILE *f; - memset(t1000_nvram, 0x1A, sizeof(t1000_nvram)); - f = nvrfopen("t1000_config.nvr", "rb"); - if (f) { - fread(t1000_nvram, sizeof(t1000_nvram), 1, f); - fclose(f); - } + memset(t1000_nvram, 0x1A, sizeof(t1000_nvram)); + f = nvrfopen("t1000_config.nvr", "rb"); + if (f) { + fread(t1000_nvram, sizeof(t1000_nvram), 1, f); + fclose(f); + } } void t1200_state_loadnvr() { - FILE *f; + FILE *f; - memset(t1200_nvram, 0, sizeof(t1200_nvram)); - f = nvrfopen("t1200_state.nvr", "rb"); - if (f) { - fread(t1200_nvram, sizeof(t1200_nvram), 1, f); - fclose(f); - } + memset(t1200_nvram, 0, sizeof(t1200_nvram)); + f = nvrfopen("t1200_state.nvr", "rb"); + if (f) { + fread(t1200_nvram, sizeof(t1200_nvram), 1, f); + fclose(f); + } } /* All RAM beyond 512k is non-volatile */ void t1000_emsboard_loadnvr() { - FILE *f; + FILE *f; - if (mem_size > 512) { - f = nvrfopen("t1000_ems.nvr", "rb"); - if (f) { - fread(&ram[512 * 1024], - 1024, (mem_size - 512), f); - fclose(f); - } - } + if (mem_size > 512) { + f = nvrfopen("t1000_ems.nvr", "rb"); + if (f) { + fread(&ram[512 * 1024], 1024, (mem_size - 512), f); + fclose(f); + } + } } void t1000_configsys_savenvr() { - FILE *f; + FILE *f; - f = nvrfopen("t1000_config.nvr", "wb"); - if (f) { - fwrite(t1000_nvram, sizeof(t1000_nvram), 1, f); - fclose(f); - } + f = nvrfopen("t1000_config.nvr", "wb"); + if (f) { + fwrite(t1000_nvram, sizeof(t1000_nvram), 1, f); + fclose(f); + } } void t1200_state_savenvr() { - FILE *f; + FILE *f; - f = nvrfopen("t1200_state.nvr", "wb"); - if (f) { - fwrite(t1200_nvram, sizeof(t1200_nvram), 1, f); - fclose(f); - } + f = nvrfopen("t1200_state.nvr", "wb"); + if (f) { + fwrite(t1200_nvram, sizeof(t1200_nvram), 1, f); + fclose(f); + } } void t1000_emsboard_savenvr() { - FILE *f; + FILE *f; - if (mem_size > 512) { - f = nvrfopen("t1000_ems.nvr", "wb"); - if (f) { - fwrite(&ram[512 * 1024], - 1024, (mem_size - 512), f); - fclose(f); - } - } + if (mem_size > 512) { + f = nvrfopen("t1000_ems.nvr", "wb"); + if (f) { + fwrite(&ram[512 * 1024], 1024, (mem_size - 512), f); + fclose(f); + } + } } /* Given an EMS page ID, return its physical address in RAM. */ uint32_t ems_execaddr(struct t1000_system *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 */ + 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; + val &= 0x7F; -/* pclog("Select EMS page: %d of %d\n", val, sys->ems_pages); */ - 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; + /* pclog("Select EMS page: %d of %d\n", val, sys->ems_pages); */ + 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) { - struct t1000_system *sys = (struct t1000_system *)priv; + struct t1000_system *sys = (struct t1000_system *)priv; -/* pclog("ems_in(%04x)=%02x\n", addr, sys->ems_reg[(addr >> 14) & 3]); */ - return sys->ems_reg[(addr >> 14) & 3]; + /* pclog("ems_in(%04x)=%02x\n", addr, sys->ems_reg[(addr >> 14) & 3]); */ + return sys->ems_reg[(addr >> 14) & 3]; } static void ems_out(uint16_t addr, uint8_t val, void *priv) { - struct t1000_system *sys = (struct t1000_system *)priv; - int pg = (addr >> 14) & 3; + struct t1000_system *sys = (struct t1000_system *)priv; + int pg = (addr >> 14) & 3; -/* pclog("ems_out(%04x, %02x) pg=%d\n", addr, val, pg); */ - 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]); - } + /* pclog("ems_out(%04x, %02x) pg=%d\n", addr, val, pg); */ + 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(struct t1000_system *sys, uint8_t val) { - int n; + int n; - val &= 0x1F; /* Mask off pageframe address */ - if (val && mem_size > 512) { - sys->ems_base = val; - } else { - sys->ems_base = 0; - } -/* pclog("EMS base set to %02x\n", val); */ - sys->ems_pages = ((mem_size - 512) / 16) - 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); - } + val &= 0x1F; /* Mask off pageframe address */ + if (val && mem_size > 512) { + sys->ems_base = val; + } else { + sys->ems_base = 0; + } + /* pclog("EMS base set to %02x\n", val); */ + sys->ems_pages = ((mem_size - 512) / 16) - 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(struct t1000_system *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; - } + 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(struct t1000_system *sys, uint8_t val) { - int n; + int n; -/* pclog("ems_set_port(%d)", val & 0x0F); */ - if (sys->ems_port) { - for (n = 0; n <= 0xC000; n += 0x4000) { - io_removehandler(sys->ems_port + n, 0x01, - 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, 0x01, - ems_in, NULL, NULL, ems_out, NULL, NULL, sys); - } - sys->ems_port = 0; - } -/* pclog(" -> %04x\n", sys->ems_port); */ + /* pclog("ems_set_port(%d)", val & 0x0F); */ + if (sys->ems_port) { + for (n = 0; n <= 0xC000; n += 0x4000) { + io_removehandler(sys->ems_port + n, 0x01, 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, 0x01, ems_in, NULL, NULL, ems_out, NULL, NULL, sys); + } + sys->ems_port = 0; + } + /* pclog(" -> %04x\n", sys->ems_port); */ } -static int addr_to_page(uint32_t addr) { - return (addr - 0xD0000) / 0x4000; -} +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) { - struct t1000_system *sys = (struct t1000_system *)priv; - int pg = addr_to_page(addr); + struct t1000_system *sys = (struct t1000_system *)priv; + int pg = addr_to_page(addr); - if (pg < 0) - return 0xFF; - addr = sys->page_exec[pg] + (addr & 0x3FFF); - return ram[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) { - struct t1000_system *sys = (struct t1000_system *)priv; - int pg = addr_to_page(addr); + struct t1000_system *sys = (struct t1000_system *)priv; + int pg = addr_to_page(addr); - if (pg < 0) - return 0xFF; - /* pclog("ems_read_ramw addr=%05x ", addr); */ - addr = sys->page_exec[pg] + (addr & 0x3FFF); - /* pclog("-> %06x val=%04x\n", addr, *(uint16_t *)&ram[addr]); */ - return *(uint16_t *)&ram[addr]; + if (pg < 0) + return 0xFF; + /* pclog("ems_read_ramw addr=%05x ", addr); */ + addr = sys->page_exec[pg] + (addr & 0x3FFF); + /* pclog("-> %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 t1000_system *sys = (struct t1000_system *)priv; - int pg = addr_to_page(addr); + struct t1000_system *sys = (struct t1000_system *)priv; + int pg = addr_to_page(addr); - if (pg < 0) - return 0xFF; - addr = sys->page_exec[pg] + (addr & 0x3FFF); - return *(uint32_t *)&ram[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) { - struct t1000_system *sys = (struct t1000_system *)priv; - int pg = addr_to_page(addr); + struct t1000_system *sys = (struct t1000_system *)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; + 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) { - struct t1000_system *sys = (struct t1000_system *)priv; - int pg = addr_to_page(addr); + struct t1000_system *sys = (struct t1000_system *)priv; + int pg = addr_to_page(addr); - if (pg < 0) - return; - /* pclog("ems_write_ramw addr=%05x ", addr); */ - addr = sys->page_exec[pg] + (addr & 0x3FFF); - /* pclog("-> %06x val=%04x\n", addr, val); */ + if (pg < 0) + return; + /* pclog("ems_write_ramw addr=%05x ", addr); */ + addr = sys->page_exec[pg] + (addr & 0x3FFF); + /* pclog("-> %06x val=%04x\n", addr, val); */ - if (*(uint16_t *)&ram[addr] != val) - nvr_dosave = 1; - *(uint16_t *)&ram[addr] = val; + 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) { - struct t1000_system *sys = (struct t1000_system *)priv; - int pg = addr_to_page(addr); + struct t1000_system *sys = (struct t1000_system *)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; + 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; } void t1000_syskey(uint8_t andmask, uint8_t ormask, uint8_t xormask) { - t1000.syskeys &= ~andmask; - t1000.syskeys |= ormask; - t1000.syskeys ^= xormask; + t1000.syskeys &= ~andmask; + t1000.syskeys |= ormask; + t1000.syskeys ^= xormask; } static uint8_t read_t1000_ctl(uint16_t addr, void *priv) { - struct t1000_system *sys = (struct t1000_system *)priv; + struct t1000_system *sys = (struct t1000_system *)priv; - switch (addr & 0x0F) { - case 1: return sys->syskeys; -/* Detect EMS board */ - case 0x0F: - switch (sys->sys_ctl[0x0E]) { - case 0x50: - if (mem_size <= 512) - return 0xFF; - return 0x90 | sys->ems_port_index; -/* 0x60 is the page frame address: (0xD000 - 0xC400) / 0x20 */ - case 0x51: return sys->ems_base | 0x60; - case 0x52: return sys->is_640k ? 0x80 : 0; - } - return 0xFF; - default: return sys->sys_ctl[addr & 0x0F]; - } + switch (addr & 0x0F) { + case 1: + return sys->syskeys; + /* Detect EMS board */ + case 0x0F: + switch (sys->sys_ctl[0x0E]) { + case 0x50: + if (mem_size <= 512) + return 0xFF; + return 0x90 | sys->ems_port_index; + /* 0x60 is the page frame address: (0xD000 - 0xC400) / 0x20 */ + case 0x51: + return sys->ems_base | 0x60; + case 0x52: + return sys->is_640k ? 0x80 : 0; + } + return 0xFF; + default: + return sys->sys_ctl[addr & 0x0F]; + } } static void t1200_turbo_set(uint8_t value) { - if (value == t1000.turbo) { - return; - } - t1000.turbo = value; - if (!value) - cpu_set_turbo(0); - else - cpu_set_turbo(1); + if (value == t1000.turbo) { + return; + } + t1000.turbo = value; + if (!value) + cpu_set_turbo(0); + else + cpu_set_turbo(1); } static void write_t1000_ctl(uint16_t addr, uint8_t val, void *priv) { - struct t1000_system *sys = (struct t1000_system *)priv; + struct t1000_system *sys = (struct t1000_system *)priv; - sys->sys_ctl[addr & 0x0F] = val; - switch (addr & 0x0F) { - /* Video control */ - case 4: - 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; - /* It looks as if the T1200, like the T3100, can disable - * its builtin video chipset if it detects the presence of - * another video card. */ - case 6: - if (romset == ROM_T1200) { - t1000_video_enable(val & 0x01 ? 0 : 1); - } - break; - /* EMS control*/ - case 0x0F: - 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; - - } + sys->sys_ctl[addr & 0x0F] = val; + switch (addr & 0x0F) { + /* Video control */ + case 4: + 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; + /* It looks as if the T1200, like the T3100, can disable + * its builtin video chipset if it detects the presence of + * another video card. */ + case 6: + if (romset == ROM_T1200) { + t1000_video_enable(val & 0x01 ? 0 : 1); + } + break; + /* EMS control*/ + case 0x0F: + 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: @@ -416,209 +416,192 @@ static void write_t1000_ctl(uint16_t addr, uint8_t val, void *priv) { * */ static uint8_t read_t1000_nvram(uint16_t addr, void *priv) { - struct t1000_system *sys = (struct t1000_system *)priv; - uint8_t tmp; + struct t1000_system *sys = (struct t1000_system *)priv; + uint8_t tmp; - switch (addr) { - case 0xC2: /* Read next byte from NVRAM */ - tmp = 0xFF; - if (sys->nvr_addr >= 0 && sys->nvr_addr < 160) - tmp = t1000_nvram[sys->nvr_addr]; - ++sys->nvr_addr; - return tmp; + switch (addr) { + case 0xC2: /* Read next byte from NVRAM */ + tmp = 0xFF; + if (sys->nvr_addr >= 0 && sys->nvr_addr < 160) + tmp = t1000_nvram[sys->nvr_addr]; + ++sys->nvr_addr; + return tmp; - case 0xC3: /* Read floppy changeline and NVRAM ready state */ - tmp = fdc_read(0x3F7, NULL); + case 0xC3: /* Read floppy changeline and NVRAM ready state */ + tmp = fdc_read(0x3F7, NULL); - 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 */ - return tmp; - } - return 0xFF; + 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 */ + return tmp; + } + return 0xFF; } static void write_t1000_nvram(uint16_t addr, uint8_t val, void *priv) { - struct t1000_system *sys = (struct t1000_system *)priv; + struct t1000_system *sys = (struct t1000_system *)priv; - switch (addr) { -/* 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. */ - case 0xC0: sys->nvr_c0 = val; - break; -/* Write next byte to NVRAM */ - case 0xC1: - if (sys->nvr_addr >= 0 && sys->nvr_addr < 160) { - if (t1000_nvram[sys->nvr_addr] != val) - nvr_dosave = 1; - t1000_nvram[sys->nvr_addr] = val; - } - ++sys->nvr_addr; - break; - case 0xC2: break; -/* 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 */ - case 0xC3: sys->nvr_active = val; - if (val == 0x80) - sys->nvr_addr = -1; - break; - } + switch (addr) { + /* 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. */ + case 0xC0: + sys->nvr_c0 = val; + break; + /* Write next byte to NVRAM */ + case 0xC1: + if (sys->nvr_addr >= 0 && sys->nvr_addr < 160) { + if (t1000_nvram[sys->nvr_addr] != val) + nvr_dosave = 1; + t1000_nvram[sys->nvr_addr] = val; + } + ++sys->nvr_addr; + break; + case 0xC2: + break; + /* 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 */ + case 0xC3: + sys->nvr_active = val; + if (val == 0x80) + sys->nvr_addr = -1; + break; + } } /* Port 0xC8 controls the ROM drive */ static uint8_t read_t1000_rom_ctl(uint16_t addr, void *priv) { - struct t1000_system *sys = (struct t1000_system *)priv; + struct t1000_system *sys = (struct t1000_system *)priv; - return sys->rom_ctl; + return sys->rom_ctl; } static void write_t1000_rom_ctl(uint16_t addr, uint8_t val, void *priv) { - struct t1000_system *sys = (struct t1000_system *)priv; + struct t1000_system *sys = (struct t1000_system *)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); - } + 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) { - struct t1000_system *sys = (struct t1000_system *)priv; + struct t1000_system *sys = (struct t1000_system *)priv; - if (!sys->romdrive) - return 0xFF; - return sys->romdrive[sys->rom_offset + (addr & 0xFFFF)]; + if (!sys->romdrive) + return 0xFF; + return sys->romdrive[sys->rom_offset + (addr & 0xFFFF)]; } static uint16_t t1000_read_romw(uint32_t addr, void *priv) { - struct t1000_system *sys = (struct t1000_system *)priv; + struct t1000_system *sys = (struct t1000_system *)priv; - if (!sys->romdrive) - return 0xFFFF; - return *(uint16_t *)(&sys->romdrive[sys->rom_offset + (addr & 0xFFFF)]); + 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) { - struct t1000_system *sys = (struct t1000_system *)priv; + struct t1000_system *sys = (struct t1000_system *)priv; - if (!sys->romdrive) - return 0xFFFFFFFF; - return *(uint32_t *)(&sys->romdrive[sys->rom_offset + (addr & 0xFFFF)]); + if (!sys->romdrive) + return 0xFFFFFFFF; + return *(uint32_t *)(&sys->romdrive[sys->rom_offset + (addr & 0xFFFF)]); } -static uint8_t read_t1200_nvram(uint32_t addr, void *priv) { - return t1200_nvram[addr & 0x7FF]; -} +static uint8_t read_t1200_nvram(uint32_t addr, void *priv) { return t1200_nvram[addr & 0x7FF]; } static void write_t1200_nvram(uint32_t addr, uint8_t value, void *priv) { - if (t1200_nvram[addr & 0x7FF] != value) { - nvr_dosave = 1; - } - t1200_nvram[addr & 0x7FF] = value; + if (t1200_nvram[addr & 0x7FF] != value) { + nvr_dosave = 1; + } + t1200_nvram[addr & 0x7FF] = value; } void xt_t1000_init() { - FILE *f; - int pg; + FILE *f; + int pg; - memset(&t1000, 0, sizeof(t1000)); - t1000.turbo = 0xff; - t1000.ems_port_index = 7; /* EMS disabled */ -/* 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. */ + memset(&t1000, 0, sizeof(t1000)); + t1000.turbo = 0xff; + t1000.ems_port_index = 7; /* EMS disabled */ + /* 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 = romfopen("t1000/t1000dos.rom", "rb"); - if (f) { - 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); + f = romfopen("t1000/t1000dos.rom", "rb"); + if (f) { + 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]); - } + /* 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, read_t1000_nvram, NULL, NULL, - write_t1000_nvram, NULL, NULL, &t1000); - /* ROM drive */ - io_sethandler(0xC8, 1, read_t1000_rom_ctl, NULL, NULL, - write_t1000_rom_ctl, NULL, NULL, &t1000); - /* System control functions, and add-on memory board */ - io_sethandler(0xE0, 0x10, read_t1000_ctl, NULL, NULL, - write_t1000_ctl, NULL, NULL, &t1000); + /* Non-volatile RAM for CONFIG.SYS */ + io_sethandler(0xC0, 4, read_t1000_nvram, NULL, NULL, write_t1000_nvram, NULL, NULL, &t1000); + /* ROM drive */ + io_sethandler(0xC8, 1, read_t1000_rom_ctl, NULL, NULL, write_t1000_rom_ctl, NULL, NULL, &t1000); + /* System control functions, and add-on memory board */ + io_sethandler(0xE0, 0x10, read_t1000_ctl, NULL, NULL, write_t1000_ctl, NULL, NULL, &t1000); - common_init(); - mem_add_bios(); - pit_set_out_func(&pit, 1, pit_refresh_timer_xt); - keyboard_xt_init(); - nmi_init(); - nvr_tc8521_init(); -/* No gameport, and no provision to fit one device_add(&gameport_device); */ + common_init(); + mem_add_bios(); + pit_set_out_func(&pit, 1, pit_refresh_timer_xt); + keyboard_xt_init(); + nmi_init(); + nvr_tc8521_init(); + /* No gameport, and no provision to fit one device_add(&gameport_device); */ } void xt_t1200_init() { - int pg; + int pg; - memset(&t1000, 0, sizeof(t1000)); - t1000.ems_port_index = 7; /* EMS disabled */ + memset(&t1000, 0, sizeof(t1000)); + t1000.ems_port_index = 7; /* EMS disabled */ - 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); + 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]); - } + /* 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, 0x10, read_t1000_ctl, NULL, NULL, - write_t1000_ctl, NULL, NULL, &t1000); + /* System control functions, and add-on memory board */ + io_sethandler(0xE0, 0x10, read_t1000_ctl, NULL, NULL, write_t1000_ctl, NULL, NULL, &t1000); - common_init(); - mem_add_bios(); - mem_mapping_add(&t1000.nvr_mapping, - 0xF0000, 2048, read_t1200_nvram, NULL, NULL, - write_t1200_nvram, NULL, NULL, - NULL, 0, &t1000); - pit_set_out_func(&pit, 1, pit_refresh_timer_xt); - keyboard_xt_init(); - nmi_init(); - nvr_tc8521_init(); -/* No gameport, and no provision to fit one device_add(&gameport_device); */ + common_init(); + mem_add_bios(); + mem_mapping_add(&t1000.nvr_mapping, 0xF0000, 2048, read_t1200_nvram, NULL, NULL, write_t1200_nvram, NULL, NULL, NULL, 0, + &t1000); + pit_set_out_func(&pit, 1, pit_refresh_timer_xt); + keyboard_xt_init(); + nmi_init(); + nvr_tc8521_init(); + /* No gameport, and no provision to fit one device_add(&gameport_device); */ } - diff --git a/src/models/t3100e.c b/src/models/t3100e.c index b6b3fd67..8c35b043 100644 --- a/src/models/t3100e.c +++ b/src/models/t3100e.c @@ -15,21 +15,21 @@ * * 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 + * - Upper memory: Either 512k or 384k, depending on amount of + * conventional memory. Upper memory can be * used either 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 + * + * 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 + * 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. * @@ -38,15 +38,15 @@ * Bit 6: Always 1 } These bits select which motherboard function to * Bit 5: Always 0 } access. * Bit 4: Set to treat upper RAM as XMS - * Bit 3: Enable external RAM boards? + * 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 + * 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 + * 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: @@ -66,22 +66,22 @@ * 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 + * + * 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. * */ static const int t3100e_log = 0; -extern uint8_t *ram; /* Physical RAM */ +extern uint8_t *ram; /* Physical RAM */ /* 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 + * 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: * @@ -106,7 +106,7 @@ extern uint8_t *ram; /* Physical RAM */ * 01 0 => 3, 4, 5 * 01 1 => 3, 5, 4 * 10 0 => 4, -, 3 - * 10 1 => 3, -, 4 + * 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? @@ -128,39 +128,50 @@ void at_init(); 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_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_mid_mapping; /* This will not be used */ -extern mem_mapping_t ram_high_mapping; /* This is RAM beyond 1Mb if any */ +extern mem_mapping_t ram_high_mapping; /* This is RAM beyond 1Mb if any */ extern mem_mapping_t ram_remapped_mapping; /* This will not be used */ 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, - }; +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 */ + 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); @@ -168,489 +179,486 @@ void t3100e_ems_out(uint16_t addr, uint8_t val, void *p); /* 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; + if ((addr & 0xF0000) == 0xD0000) { + return ((addr >> 14) & 3); + } + return -1; } -/* And vice versa: Given a page slot, which memory address does it +/* 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); -} +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; +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 */ + 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 */ + 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); + /* 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; + 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; + 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; + 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 (!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]; - } + 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]; + } - pclog(" %p | base=%05x size=%05x %c @ %06x %s\n", mm, - mm->base, mm->size, mm->enable ? 'Y' : 'N', - offset, name); + pclog(" %p | base=%05x size=%05x %c @ %06x %s\n", mm, + mm->base, mm->size, mm->enable ? 'Y' : 'N', + offset, name); - mm = mm->next; - } + mm = mm->next; + } }*/ void t3100e_map_ram(uint8_t val) { - int n; - int32_t upper_len; + int n; + int32_t upper_len; - if (t3100e_log) { - pclog("OUT 0x8084, %02x [ set memory mapping :", val | 0x40); - if (val & 1) - pclog("ENABLE_EMS "); - if (val & 2) - pclog("ENABLE_XMS "); - if (val & 4) - pclog("640K "); - if (val & 8) - pclog("X8X "); - if (val & 16) - pclog("UPPER_IS_XMS "); - pclog("\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; + if (t3100e_log) { + pclog("OUT 0x8084, %02x [ set memory mapping :", val | 0x40); + if (val & 1) + pclog("ENABLE_EMS "); + if (val & 2) + pclog("ENABLE_XMS "); + if (val & 4) + pclog("640K "); + if (val & 8) + pclog("X8X "); + if (val & 16) + pclog("UPPER_IS_XMS "); + pclog("\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); + 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 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 + /* 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); - } + 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(); + // dump_mappings(); } -void t3100e_notify_set(uint8_t value) { - t3100e_ems.notify = value; -} +void t3100e_notify_set(uint8_t value) { t3100e_ems.notify = value; } -void t3100e_mono_set(uint8_t value) { - t3100e_ems.mono = value; -} +void t3100e_mono_set(uint8_t value) { t3100e_ems.mono = value; } -uint8_t t3100e_mono_get(void) { - return t3100e_ems.mono; -} +uint8_t t3100e_mono_get(void) { return t3100e_ems.mono; } void t3100e_turbo_set(uint8_t value) { - t3100e_ems.turbo = value; - if (!value) - cpu_set_turbo(0); - else - cpu_set_turbo(1); + t3100e_ems.turbo = value; + if (!value) + cpu_set_turbo(0); + else + cpu_set_turbo(1); } uint8_t t3100e_sys_in(uint16_t addr, void *p) { - struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *)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 */ - if (t3100e_log) - pclog("IN 0x8084\n"); - return 0x0C | (regs->notify << 4); + /* 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 */ + if (t3100e_log) + pclog("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; + // struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *)p; - switch (val & 0xE0) { - case 0x00: /* Set serial port IRQs. Not implemented */ - if (t3100e_log) - pclog("OUT 0x8084, %02x [ set serial port IRQs]\n", val); - break; - case 0x40: /* Set RAM mappings. */ - t3100e_map_ram(val & 0x1F); - break; + switch (val & 0xE0) { + case 0x00: /* Set serial port IRQs. Not implemented */ + if (t3100e_log) + pclog("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; + case 0x80: /* Set video options. */ + t3100e_video_options_set(val & 0x1F); + break; - /* Other options not implemented. */ - default: - if (t3100e_log) - pclog("OUT 0x8084, %02x\n", val); - break; - } + /* Other options not implemented. */ + default: + if (t3100e_log) + pclog("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. */ + /* 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 */ + 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; + /* Get display setting */ + if (t3100e_display_get()) + value |= 0x80; + if (!t3100e_ems.turbo) + value |= 0x40; -/* Try to determine the floppy types.*/ + /* 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; + 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)]; + 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); + 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); - if (t3100e_log) - pclog("EMS: page %d %02x -> %02x [%06x]\n", - pg, regs->page[pg], val, regs->page_exec[pg & 3]); - regs->page[pg] = val; + regs->page_exec[pg & 3] = t3100e_ems_execaddr(regs, pg, val); + if (t3100e_log) + pclog("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]) { - if (t3100e_log) - pclog("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 { - if (t3100e_log) - pclog("Disabling EMS RAM at %05x\n", - page_to_addr(pg)); - mem_mapping_disable(®s->mapping[pg]); - } + pg &= 3; + /* Bit 7 set if page is enabled, reset if page is disabled */ + if (regs->page_exec[pg]) { + if (t3100e_log) + pclog("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 { + if (t3100e_log) + pclog("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); + 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]; + 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); + struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *)priv; + int pg = addr_to_page(addr); - if (pg < 0) - return 0xFF; - //pclog("ems_read_ramw addr=%05x ", addr); - addr = regs->page_exec[pg] + (addr & 0x3FFF); - //pclog("-> %06x val=%04x\n", addr, *(uint16_t *)&ram[addr]); - return *(uint16_t *)&ram[addr]; + if (pg < 0) + return 0xFF; + // pclog("ems_read_ramw addr=%05x ", addr); + addr = regs->page_exec[pg] + (addr & 0x3FFF); + // pclog("-> %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); + 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]; + 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); + 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; + 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); + struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *)priv; + int pg = addr_to_page(addr); - if (pg < 0) - return; - //pclog("ems_write_ramw addr=%05x ", addr); - addr = regs->page_exec[pg] + (addr & 0x3FFF); - //pclog("-> %06x val=%04x\n", addr, val); + if (pg < 0) + return; + // pclog("ems_write_ramw addr=%05x ", addr); + addr = regs->page_exec[pg] + (addr & 0x3FFF); + // pclog("-> %06x val=%04x\n", addr, val); - *(uint16_t *)&ram[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); + 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; + 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; + struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *)priv; - addr = (addr - (1024 * mem_size)) + regs->upper_base; - return ram[addr]; + 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; + struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *)priv; - addr = (addr - (1024 * mem_size)) + regs->upper_base; - return *(uint16_t *)&ram[addr]; + 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; + struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *)priv; - addr = (addr - (1024 * mem_size)) + regs->upper_base; - return *(uint32_t *)&ram[addr]; + 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; + struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *)priv; - addr = (addr - (1024 * mem_size)) + regs->upper_base; - ram[addr] = val; + 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; + struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *)priv; - addr = (addr - (1024 * mem_size)) + regs->upper_base; - *(uint16_t *)&ram[addr] = val; + 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; + struct t3100e_ems_regs *regs = (struct t3100e_ems_regs *)priv; - addr = (addr - (1024 * mem_size)) + regs->upper_base; - *(uint32_t *)&ram[addr] = val; + addr = (addr - (1024 * mem_size)) + regs->upper_base; + *(uint32_t *)&ram[addr] = val; } void at_t3100e_init() { - int pg; + int pg; - memset(&t3100e_ems, 0, sizeof(t3100e_ems)); + memset(&t3100e_ems, 0, sizeof(t3100e_ems)); - at_init(); - /* Hook up system control port */ - io_sethandler(0x8084, 0x0001, - t3100e_sys_in, NULL, NULL, - t3100e_sys_out, NULL, NULL, &t3100e_ems); + at_init(); + /* 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); - } + /* 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++) { - if (t3100e_log) - pclog("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); - mem_mapping_disable(&ram_remapped_mapping); + /* Map the EMS page frame */ + for (pg = 0; pg < 4; pg++) { + if (t3100e_log) + pclog("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); + mem_mapping_disable(&ram_remapped_mapping); } diff --git a/src/models/um8669f.c b/src/models/um8669f.c index 99bc3e58..39c9c95b 100644 --- a/src/models/um8669f.c +++ b/src/models/um8669f.c @@ -1,10 +1,10 @@ /*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 @@ -30,23 +30,23 @@ PnP registers : #include "um8669f.h" typedef struct um8669f_t { - int locked; - int cur_reg_108; - uint8_t regs_108[256]; + 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]; + int cur_reg; + int cur_device; + struct { + int enable; + uint16_t addr; + int irq; + int dma; + } dev[8]; } um8669f_t; static um8669f_t um8669f_global; -#define DEV_FDC 0 +#define DEV_FDC 0 #define DEV_COM1 1 #define DEV_COM2 2 #define DEV_LPT1 3 @@ -56,117 +56,136 @@ static um8669f_t um8669f_global; #define REG_ENABLE 0x30 #define REG_ADDRHI 0x60 #define REG_ADDRLO 0x61 -#define REG_IRQ 0x70 -#define REG_DMA 0x74 +#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; + um8669f_t *um8669f = (um8669f_t *)p; - if (port == 0x279) - um8669f->cur_reg = val; - else { - if (um8669f->cur_reg == REG_DEVICE) - um8669f->cur_device = val & 7; - else { -// pclog("Write UM8669F %02x [%02x] %02x\n", um8669f->cur_reg, um8669f->cur_device, val); - switch (um8669f->cur_reg) { - case REG_ENABLE:um8669f->dev[um8669f->cur_device].enable = val; - break; - case REG_ADDRLO:um8669f->dev[um8669f->cur_device].addr = (um8669f->dev[um8669f->cur_device].addr & 0xff00) | val; - break; - case REG_ADDRHI:um8669f->dev[um8669f->cur_device].addr = (um8669f->dev[um8669f->cur_device].addr & 0x00ff) | (val << 8); - break; - case REG_IRQ:um8669f->dev[um8669f->cur_device].irq = val; - break; - case REG_DMA:um8669f->dev[um8669f->cur_device].dma = val; - break; - } + if (port == 0x279) + um8669f->cur_reg = val; + else { + if (um8669f->cur_reg == REG_DEVICE) + um8669f->cur_device = val & 7; + else { + // pclog("Write UM8669F %02x [%02x] %02x\n", um8669f->cur_reg, um8669f->cur_device, + // val); + switch (um8669f->cur_reg) { + case REG_ENABLE: + um8669f->dev[um8669f->cur_device].enable = val; + break; + case REG_ADDRLO: + um8669f->dev[um8669f->cur_device].addr = (um8669f->dev[um8669f->cur_device].addr & 0xff00) | val; + break; + case REG_ADDRHI: + um8669f->dev[um8669f->cur_device].addr = + (um8669f->dev[um8669f->cur_device].addr & 0x00ff) | (val << 8); + break; + case REG_IRQ: + um8669f->dev[um8669f->cur_device].irq = val; + break; + case REG_DMA: + um8669f->dev[um8669f->cur_device].dma = val; + break; + } - switch (um8669f->cur_device) { - case DEV_FDC:fdc_remove(); - if (um8669f->dev[DEV_FDC].enable & 1) - fdc_add(); - break; - case DEV_COM1:serial1_remove(); - if (um8669f->dev[DEV_COM1].enable & 1) - serial1_set(um8669f->dev[DEV_COM1].addr, um8669f->dev[DEV_COM1].irq); - break; - case DEV_COM2:serial2_remove(); - if (um8669f->dev[DEV_COM2].enable & 1) - serial2_set(um8669f->dev[DEV_COM2].addr, um8669f->dev[DEV_COM2].irq); - break; - case DEV_LPT1:lpt1_remove(); - lpt2_remove(); - if (um8669f->dev[DEV_LPT1].enable & 1) - lpt1_init(um8669f->dev[DEV_LPT1].addr); - break; - } - } - } + switch (um8669f->cur_device) { + case DEV_FDC: + fdc_remove(); + if (um8669f->dev[DEV_FDC].enable & 1) + fdc_add(); + break; + case DEV_COM1: + serial1_remove(); + if (um8669f->dev[DEV_COM1].enable & 1) + serial1_set(um8669f->dev[DEV_COM1].addr, um8669f->dev[DEV_COM1].irq); + break; + case DEV_COM2: + serial2_remove(); + if (um8669f->dev[DEV_COM2].enable & 1) + serial2_set(um8669f->dev[DEV_COM2].addr, um8669f->dev[DEV_COM2].irq); + break; + case DEV_LPT1: + lpt1_remove(); + lpt2_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; + um8669f_t *um8669f = (um8669f_t *)p; -// pclog("Read UM8669F %02x\n", um8669f->cur_reg); + // pclog("Read UM8669F %02x\n", um8669f->cur_reg); - 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; - } + 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; + return 0xff; } void um8669f_write(uint16_t port, uint8_t val, void *p) { - um8669f_t *um8669f = (um8669f_t *)p; + um8669f_t *um8669f = (um8669f_t *)p; - 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 { -// pclog("Write UM8669f register %02x %02x %04x:%04x %i\n", um8669f_curreg, val, CS,cpu_state.pc, ins); - um8669f->regs_108[um8669f->cur_reg_108] = val; + 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 { + // pclog("Write UM8669f register %02x %02x %04x:%04x %i\n", um8669f_curreg, val, + // CS,cpu_state.pc, ins); + um8669f->regs_108[um8669f->cur_reg_108] = val; - 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); - if (um8669f->regs_108[0xc1] & 0x80) { - 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); - } - } - } + 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); + if (um8669f->regs_108[0xc1] & 0x80) { + 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); + } + } + } } uint8_t um8669f_read(uint16_t port, void *p) { - um8669f_t *um8669f = (um8669f_t *)p; + um8669f_t *um8669f = (um8669f_t *)p; -// pclog("um8669f_read : port=%04x reg %02X locked=%i %02x\n", port, um8669f_curreg, um8669f_locked, um8669f_regs[um8669f_curreg]); - if (um8669f->locked) - return 0xff; + // pclog("um8669f_read : port=%04x reg %02X locked=%i %02x\n", port, um8669f_curreg, um8669f_locked, + // um8669f_regs[um8669f_curreg]); + if (um8669f->locked) + return 0xff; - if (port == 0x108) - return um8669f->cur_reg_108; /*???*/ - else - return um8669f->regs_108[um8669f->cur_reg_108]; + if (port == 0x108) + return um8669f->cur_reg_108; /*???*/ + else + return um8669f->regs_108[um8669f->cur_reg_108]; } void um8669f_init() { - memset(&um8669f_global, 0, sizeof(um8669f_t)); + memset(&um8669f_global, 0, sizeof(um8669f_t)); - um8669f_global.locked = 1; + um8669f_global.locked = 1; - io_sethandler(0x0108, 0x0002, um8669f_read, NULL, NULL, um8669f_write, NULL, NULL, &um8669f_global); + io_sethandler(0x0108, 0x0002, um8669f_read, NULL, NULL, um8669f_write, NULL, NULL, &um8669f_global); } diff --git a/src/models/um8881f.c b/src/models/um8881f.c index 8899afa8..aadb26ae 100644 --- a/src/models/um8881f.c +++ b/src/models/um8881f.c @@ -9,55 +9,51 @@ static uint8_t card_16[256]; static uint8_t card_18[256]; void um8881f_write(int func, int addr, uint8_t val, void *priv) { -// pclog("um8881f_write : addr=%02x val=%02x %04x:%04x\n", addr, val, CS, pc); - if (addr == 0x54) { -/* if ((card_16[0x54] ^ val) & 0x01) - { - if (val & 1) - mem_bios_set_state(0xe0000, 0x10000, 1, 1); - else - mem_bios_set_state(0xe0000, 0x10000, 0, 0); - }*/ - flushmmucache_nopc(); - } - if (addr == 0x55) { - if ((card_16[0x55] ^ val) & 0xc0) { -/* switch (val & 0xc0) - { - case 0x00: mem_bios_set_state(0xf0000, 0x10000, 0, 1); break; - case 0x40: mem_bios_set_state(0xf0000, 0x10000, 0, 0); break; - case 0x80: mem_bios_set_state(0xf0000, 0x10000, 1, 1); break; - case 0xc0: mem_bios_set_state(0xf0000, 0x10000, 1, 0); break; - }*/ -// shadowbios = val & 0x80; - flushmmucache_nopc(); - } - } - if (addr >= 4) - card_16[addr] = val; + // pclog("um8881f_write : addr=%02x val=%02x %04x:%04x\n", addr, val, CS, pc); + if (addr == 0x54) { + /* if ((card_16[0x54] ^ val) & 0x01) + { + if (val & 1) + mem_bios_set_state(0xe0000, 0x10000, 1, 1); + else + mem_bios_set_state(0xe0000, 0x10000, 0, 0); + }*/ + flushmmucache_nopc(); + } + if (addr == 0x55) { + if ((card_16[0x55] ^ val) & 0xc0) { + /* switch (val & 0xc0) + { + case 0x00: mem_bios_set_state(0xf0000, 0x10000, 0, 1); break; + case 0x40: mem_bios_set_state(0xf0000, 0x10000, 0, 0); break; + case 0x80: mem_bios_set_state(0xf0000, 0x10000, 1, 1); break; + case 0xc0: mem_bios_set_state(0xf0000, 0x10000, 1, 0); break; + }*/ + // shadowbios = val & 0x80; + flushmmucache_nopc(); + } + } + if (addr >= 4) + card_16[addr] = val; } -uint8_t um8881f_read(int func, int addr, void *priv) { - return card_16[addr]; -} +uint8_t um8881f_read(int func, int addr, void *priv) { return card_16[addr]; } void um8886f_write(int func, int addr, uint8_t val, void *priv) { - if (addr >= 4) - card_18[addr] = val; + if (addr >= 4) + card_18[addr] = val; } -uint8_t um8886f_read(int func, int addr, void *priv) { - return card_18[addr]; -} +uint8_t um8886f_read(int func, int addr, void *priv) { return card_18[addr]; } void um8881f_init() { - pci_add_specific(16, um8881f_read, um8881f_write, NULL); - pci_add_specific(18, um8886f_read, um8886f_write, NULL); + pci_add_specific(16, um8881f_read, um8881f_write, NULL); + pci_add_specific(18, um8886f_read, um8886f_write, NULL); - card_16[0] = card_18[0] = 0x60; /*UMC*/ - card_16[1] = card_18[1] = 0x10; - card_16[2] = 0x81; - card_16[3] = 0x88; /*UM8881 Host - PCI bridge*/ - card_18[2] = 0x86; - card_18[3] = 0x88; /*UM8886 PCI - ISA bridge*/ + card_16[0] = card_18[0] = 0x60; /*UMC*/ + card_16[1] = card_18[1] = 0x10; + card_16[2] = 0x81; + card_16[3] = 0x88; /*UM8881 Host - PCI bridge*/ + card_18[2] = 0x86; + card_18[3] = 0x88; /*UM8886 PCI - ISA bridge*/ } diff --git a/src/models/vl82c480.c b/src/models/vl82c480.c index 7c8ebf44..50977428 100644 --- a/src/models/vl82c480.c +++ b/src/models/vl82c480.c @@ -4,137 +4,152 @@ #include "vl82c480.h" static struct { - int cfg_index; - uint8_t cfg_regs[256]; + int cfg_index; + uint8_t cfg_regs[256]; - uint8_t port_92; + uint8_t port_92; } vl82c480; -#define CFG_ID 0x00 -#define CFG_AAXS 0x0d -#define CFG_BAXS 0x0e -#define CFG_CAXS 0x0f -#define CFG_DAXS 0x10 -#define CFG_EAXS 0x11 -#define CFG_FAXS 0x12 +#define CFG_ID 0x00 +#define CFG_AAXS 0x0d +#define CFG_BAXS 0x0e +#define CFG_CAXS 0x0f +#define CFG_DAXS 0x10 +#define CFG_EAXS 0x11 +#define CFG_FAXS 0x12 #define ID_VL82C480 0x90 static void shadow_control(uint32_t addr, uint32_t size, int state) { -// pclog("shadow_control: addr=%08x size=%04x state=%i\n", addr, size, state); - switch (state) { - 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_EXTERNAL | MEM_WRITE_INTERNAL); - break; - case 2:mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); - break; - case 3:mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - break; - } - flushmmucache_nopc(); + // pclog("shadow_control: addr=%08x size=%04x state=%i\n", addr, size, state); + switch (state) { + 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_EXTERNAL | MEM_WRITE_INTERNAL); + break; + case 2: + mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL); + break; + case 3: + mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + break; + } + flushmmucache_nopc(); } void vl82c480_write(uint16_t addr, uint8_t val, void *p) { -// if (addr != 0x92) pclog("vl82c480_write: addr=%04x val=%02x\n", addr, val); - switch (addr) { - case 0x92: - if ((mem_a20_alt ^ val) & 2) { - mem_a20_alt = val & 2; - mem_a20_recalc(); - } - if ((~vl82c480.port_92 & val) & 1) { - softresetx86(); - cpu_set_edx(); - } - vl82c480.port_92 = val; - break; + // if (addr != 0x92) pclog("vl82c480_write: addr=%04x val=%02x\n", addr, val); + switch (addr) { + case 0x92: + if ((mem_a20_alt ^ val) & 2) { + mem_a20_alt = val & 2; + mem_a20_recalc(); + } + if ((~vl82c480.port_92 & val) & 1) { + softresetx86(); + cpu_set_edx(); + } + vl82c480.port_92 = val; + break; - case 0xec:vl82c480.cfg_index = val; - break; + case 0xec: + vl82c480.cfg_index = val; + break; - case 0xed: - if (vl82c480.cfg_index >= 0x01 && vl82c480.cfg_index <= 0x24) { - vl82c480.cfg_regs[vl82c480.cfg_index] = val; - switch (vl82c480.cfg_index) { - case CFG_AAXS:shadow_control(0xa0000, 0x4000, val & 3); - shadow_control(0xa4000, 0x4000, (val >> 2) & 3); - shadow_control(0xa8000, 0x4000, (val >> 4) & 3); - shadow_control(0xac000, 0x4000, (val >> 6) & 3); - break; - case CFG_BAXS:shadow_control(0xb0000, 0x4000, val & 3); - shadow_control(0xb4000, 0x4000, (val >> 2) & 3); - shadow_control(0xb8000, 0x4000, (val >> 4) & 3); - shadow_control(0xbc000, 0x4000, (val >> 6) & 3); - break; - case CFG_CAXS:shadow_control(0xc0000, 0x4000, val & 3); - shadow_control(0xc4000, 0x4000, (val >> 2) & 3); - shadow_control(0xc8000, 0x4000, (val >> 4) & 3); - shadow_control(0xcc000, 0x4000, (val >> 6) & 3); - break; - case CFG_DAXS:shadow_control(0xd0000, 0x4000, val & 3); - shadow_control(0xd4000, 0x4000, (val >> 2) & 3); - shadow_control(0xd8000, 0x4000, (val >> 4) & 3); - shadow_control(0xdc000, 0x4000, (val >> 6) & 3); - break; - case CFG_EAXS:shadow_control(0xe0000, 0x4000, val & 3); - shadow_control(0xe4000, 0x4000, (val >> 2) & 3); - shadow_control(0xe8000, 0x4000, (val >> 4) & 3); - shadow_control(0xec000, 0x4000, (val >> 6) & 3); - break; - case CFG_FAXS:shadow_control(0xf0000, 0x4000, val & 3); - shadow_control(0xf4000, 0x4000, (val >> 2) & 3); - shadow_control(0xf8000, 0x4000, (val >> 4) & 3); - shadow_control(0xfc000, 0x4000, (val >> 6) & 3); - break; - } - } - break; + case 0xed: + if (vl82c480.cfg_index >= 0x01 && vl82c480.cfg_index <= 0x24) { + vl82c480.cfg_regs[vl82c480.cfg_index] = val; + switch (vl82c480.cfg_index) { + case CFG_AAXS: + shadow_control(0xa0000, 0x4000, val & 3); + shadow_control(0xa4000, 0x4000, (val >> 2) & 3); + shadow_control(0xa8000, 0x4000, (val >> 4) & 3); + shadow_control(0xac000, 0x4000, (val >> 6) & 3); + break; + case CFG_BAXS: + shadow_control(0xb0000, 0x4000, val & 3); + shadow_control(0xb4000, 0x4000, (val >> 2) & 3); + shadow_control(0xb8000, 0x4000, (val >> 4) & 3); + shadow_control(0xbc000, 0x4000, (val >> 6) & 3); + break; + case CFG_CAXS: + shadow_control(0xc0000, 0x4000, val & 3); + shadow_control(0xc4000, 0x4000, (val >> 2) & 3); + shadow_control(0xc8000, 0x4000, (val >> 4) & 3); + shadow_control(0xcc000, 0x4000, (val >> 6) & 3); + break; + case CFG_DAXS: + shadow_control(0xd0000, 0x4000, val & 3); + shadow_control(0xd4000, 0x4000, (val >> 2) & 3); + shadow_control(0xd8000, 0x4000, (val >> 4) & 3); + shadow_control(0xdc000, 0x4000, (val >> 6) & 3); + break; + case CFG_EAXS: + shadow_control(0xe0000, 0x4000, val & 3); + shadow_control(0xe4000, 0x4000, (val >> 2) & 3); + shadow_control(0xe8000, 0x4000, (val >> 4) & 3); + shadow_control(0xec000, 0x4000, (val >> 6) & 3); + break; + case CFG_FAXS: + shadow_control(0xf0000, 0x4000, val & 3); + shadow_control(0xf4000, 0x4000, (val >> 2) & 3); + shadow_control(0xf8000, 0x4000, (val >> 4) & 3); + shadow_control(0xfc000, 0x4000, (val >> 6) & 3); + break; + } + } + break; - case 0xee: - if (mem_a20_alt) { - vl82c480.port_92 &= ~2; - mem_a20_alt = 0; - mem_a20_recalc(); - } - break; - } + case 0xee: + if (mem_a20_alt) { + vl82c480.port_92 &= ~2; + mem_a20_alt = 0; + mem_a20_recalc(); + } + break; + } } uint8_t vl82c480_read(uint16_t addr, void *p) { - uint8_t ret = 0xff; + uint8_t ret = 0xff; - switch (addr) { - case 0x92:ret = vl82c480.port_92; - break; + switch (addr) { + case 0x92: + ret = vl82c480.port_92; + break; - case 0xec:ret = vl82c480.cfg_index; - break; + case 0xec: + ret = vl82c480.cfg_index; + break; - case 0xed:ret = vl82c480.cfg_regs[vl82c480.cfg_index]; - break; + case 0xed: + ret = vl82c480.cfg_regs[vl82c480.cfg_index]; + break; - case 0xee: - if (!mem_a20_alt) { - vl82c480.port_92 |= 2; - mem_a20_alt = 1; - mem_a20_recalc(); - } - break; + case 0xee: + if (!mem_a20_alt) { + vl82c480.port_92 |= 2; + mem_a20_alt = 1; + mem_a20_recalc(); + } + break; - case 0xef:softresetx86(); - cpu_set_edx(); - break; - } + case 0xef: + softresetx86(); + cpu_set_edx(); + break; + } -// pclog("vl82c480_read: addr=%04x ret=%02x\n", addr, ret); - return ret; + // pclog("vl82c480_read: addr=%04x ret=%02x\n", addr, ret); + return ret; } void vl82c480_init(void) { - memset(&vl82c480, 0, sizeof(vl82c480)); - vl82c480.cfg_regs[CFG_ID] = ID_VL82C480; + memset(&vl82c480, 0, sizeof(vl82c480)); + vl82c480.cfg_regs[CFG_ID] = ID_VL82C480; - io_sethandler(0x0092, 0x0001, vl82c480_read, NULL, NULL, vl82c480_write, NULL, NULL, NULL); - io_sethandler(0x00ec, 0x0004, vl82c480_read, NULL, NULL, vl82c480_write, NULL, NULL, NULL); + io_sethandler(0x0092, 0x0001, vl82c480_read, NULL, NULL, vl82c480_write, NULL, NULL, NULL); + io_sethandler(0x00ec, 0x0004, vl82c480_read, NULL, NULL, vl82c480_write, NULL, NULL, NULL); } diff --git a/src/models/vt82c586b.c b/src/models/vt82c586b.c index 23263496..b0da8960 100644 --- a/src/models/vt82c586b.c +++ b/src/models/vt82c586b.c @@ -11,474 +11,499 @@ #include "vt82c586b.h" static struct { - uint8_t pci_isa_bridge_regs[256]; - uint8_t ide_regs[256]; - uint8_t usb_regs[256]; - uint8_t power_regs[256]; + uint8_t pci_isa_bridge_regs[256]; + uint8_t ide_regs[256]; + uint8_t usb_regs[256]; + uint8_t power_regs[256]; - uint8_t sysctrl; + uint8_t sysctrl; - sff_busmaster_t busmaster[2]; + sff_busmaster_t busmaster[2]; - struct { - uint16_t io_base; - } usb; - struct { - uint16_t io_base; + struct { + uint16_t io_base; + } usb; + struct { + uint16_t io_base; - uint16_t pm_status; - uint16_t pm_enable; - uint16_t pm_ctrl; + uint16_t pm_status; + uint16_t pm_enable; + uint16_t pm_ctrl; - uint16_t gbl_status; - uint16_t gbl_enable; - uint16_t gbl_ctrl; + uint16_t gbl_status; + uint16_t gbl_enable; + uint16_t gbl_ctrl; - uint8_t smi_cmd; - } power; + uint8_t smi_cmd; + } power; } vt82c586b; #define ACPI_TIMER_FREQ 3579545 -#define ACPI_IO_ENABLE (1 << 7) +#define ACPI_IO_ENABLE (1 << 7) #define ACPI_TIMER_32BIT (1 << 3) #define GBL_SW_SMI_STS (1 << 6) -#define GBL_SW_SMI_EN (1 << 6) +#define GBL_SW_SMI_EN (1 << 6) #define PM_CTRL_SLP_EN (1 << 13) #define PM_CTRL_SLP_TYP_MASK (7 << 10) static uint8_t vt82c586b_read(int func, int addr, void *priv) { - switch (func) { - case 0:return vt82c586b.pci_isa_bridge_regs[addr]; + switch (func) { + case 0: + return vt82c586b.pci_isa_bridge_regs[addr]; - case 1:return vt82c586b.ide_regs[addr]; + case 1: + return vt82c586b.ide_regs[addr]; - case 2:return vt82c586b.usb_regs[addr]; + case 2: + return vt82c586b.usb_regs[addr]; - case 3:return vt82c586b.power_regs[addr]; + case 3: + return vt82c586b.power_regs[addr]; - default:return 0xff; - } + default: + return 0xff; + } } static void vt82c586b_pci_isa_bridge_write(int addr, uint8_t val) { - /*Read-only addresses*/ - if ((addr < 4) || (addr == 5) || (addr == 6) - || (addr >= 8 && addr < 0x40) - || (addr == 0x49) - || (addr == 0x4b) - || (addr >= 0x51 && addr < 0x54) - || (addr >= 0x5d && addr < 0x60) - || (addr >= 0x68 && addr < 0x6a) - || (addr >= 0x71)) - return; + /*Read-only addresses*/ + if ((addr < 4) || (addr == 5) || (addr == 6) || (addr >= 8 && addr < 0x40) || (addr == 0x49) || (addr == 0x4b) || + (addr >= 0x51 && addr < 0x54) || (addr >= 0x5d && addr < 0x60) || (addr >= 0x68 && addr < 0x6a) || (addr >= 0x71)) + return; - switch (addr) { - case 4:vt82c586b.pci_isa_bridge_regs[4] = (val & 8) | 7; - break; - case 6:vt82c586b.pci_isa_bridge_regs[6] &= ~(val & 0xb0); - break; + switch (addr) { + case 4: + vt82c586b.pci_isa_bridge_regs[4] = (val & 8) | 7; + break; + case 6: + vt82c586b.pci_isa_bridge_regs[6] &= ~(val & 0xb0); + break; - case 0x47: - if ((val & 0x81) == 0x81) - resetx86(); - vt82c586b.pci_isa_bridge_regs[0x47] = val & 0xfe; - break; + case 0x47: + if ((val & 0x81) == 0x81) + resetx86(); + vt82c586b.pci_isa_bridge_regs[0x47] = val & 0xfe; + break; - case 0x55: - if (!(val & 0xf0)) - pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); - else - pci_set_irq_routing(PCI_INTD, val >> 4); - vt82c586b.pci_isa_bridge_regs[0x55] = val; - break; - case 0x56: - if (!(val & 0xf0)) - pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED); - else - pci_set_irq_routing(PCI_INTA, val >> 4); - if (!(val & 0x0f)) - pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED); - else - pci_set_irq_routing(PCI_INTB, val & 0xf); - vt82c586b.pci_isa_bridge_regs[0x56] = val; - break; - case 0x57: - if (!(val & 0xf0)) - pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED); - else - pci_set_irq_routing(PCI_INTC, val >> 4); - vt82c586b.pci_isa_bridge_regs[0x57] = val; - break; + case 0x55: + if (!(val & 0xf0)) + pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); + else + pci_set_irq_routing(PCI_INTD, val >> 4); + vt82c586b.pci_isa_bridge_regs[0x55] = val; + break; + case 0x56: + if (!(val & 0xf0)) + pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED); + else + pci_set_irq_routing(PCI_INTA, val >> 4); + if (!(val & 0x0f)) + pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED); + else + pci_set_irq_routing(PCI_INTB, val & 0xf); + vt82c586b.pci_isa_bridge_regs[0x56] = val; + break; + case 0x57: + if (!(val & 0xf0)) + pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED); + else + pci_set_irq_routing(PCI_INTC, val >> 4); + vt82c586b.pci_isa_bridge_regs[0x57] = val; + break; - default:vt82c586b.pci_isa_bridge_regs[addr] = val; - break; - } + default: + vt82c586b.pci_isa_bridge_regs[addr] = val; + break; + } } static void vt82c586b_ide_write(int addr, uint8_t val) { - /*Read-only addresses*/ - if ((addr < 4) || (addr == 5) || (addr == 8) - || (addr >= 0xa && addr < 0x0d) - || (addr >= 0x0e && addr < 0x20) - || (addr >= 0x22 && addr < 0x3c) - || (addr >= 0x3d && addr < 0x40) - || (addr >= 0x54 && addr < 0x60) - || (addr >= 0x52 && addr < 0x68) - || (addr >= 0x62)) - return; + /*Read-only addresses*/ + if ((addr < 4) || (addr == 5) || (addr == 8) || (addr >= 0xa && addr < 0x0d) || (addr >= 0x0e && addr < 0x20) || + (addr >= 0x22 && addr < 0x3c) || (addr >= 0x3d && addr < 0x40) || (addr >= 0x54 && addr < 0x60) || + (addr >= 0x52 && addr < 0x68) || (addr >= 0x62)) + return; - switch (addr) { - case 4:vt82c586b.ide_regs[4] = val & 0x85; - break; - case 6:vt82c586b.ide_regs[6] &= ~(val & 0xb0); - break; + switch (addr) { + case 4: + vt82c586b.ide_regs[4] = val & 0x85; + break; + case 6: + vt82c586b.ide_regs[6] &= ~(val & 0xb0); + break; - case 9:vt82c586b.ide_regs[9] = (vt82c586b.pci_isa_bridge_regs[9] & ~0x70) | 0x8a; - break; + case 9: + vt82c586b.ide_regs[9] = (vt82c586b.pci_isa_bridge_regs[9] & ~0x70) | 0x8a; + break; - case 0x20:vt82c586b.ide_regs[0x20] = (val & ~0xf) | 1; - break; + case 0x20: + vt82c586b.ide_regs[0x20] = (val & ~0xf) | 1; + break; - default:vt82c586b.ide_regs[addr] = val; - break; - } + default: + vt82c586b.ide_regs[addr] = val; + break; + } - if (addr == 4 || (addr & ~3) == 0x20) /*Bus master base address*/ - { - uint16_t base = (vt82c586b.ide_regs[0x20] & 0xf0) | (vt82c586b.ide_regs[0x21] << 8); - io_removehandler(0, 0x10000, sff_bus_master_read, NULL, NULL, sff_bus_master_write, NULL, NULL, vt82c586b.busmaster); - if (vt82c586b.ide_regs[0x04] & 1) - io_sethandler(base, 0x10, sff_bus_master_read, NULL, NULL, sff_bus_master_write, NULL, NULL, vt82c586b.busmaster); - } - if (addr == 4 || addr == 0x40) { - ide_pri_disable(); - ide_sec_disable(); - if (vt82c586b.ide_regs[0x04] & 1) { - if (vt82c586b.ide_regs[0x40] & 0x02) - ide_pri_enable(); - if (vt82c586b.ide_regs[0x40] & 0x01) - ide_sec_enable(); - } - } + if (addr == 4 || (addr & ~3) == 0x20) /*Bus master base address*/ + { + uint16_t base = (vt82c586b.ide_regs[0x20] & 0xf0) | (vt82c586b.ide_regs[0x21] << 8); + io_removehandler(0, 0x10000, sff_bus_master_read, NULL, NULL, sff_bus_master_write, NULL, NULL, + vt82c586b.busmaster); + if (vt82c586b.ide_regs[0x04] & 1) + io_sethandler(base, 0x10, sff_bus_master_read, NULL, NULL, sff_bus_master_write, NULL, NULL, + vt82c586b.busmaster); + } + if (addr == 4 || addr == 0x40) { + ide_pri_disable(); + ide_sec_disable(); + if (vt82c586b.ide_regs[0x04] & 1) { + if (vt82c586b.ide_regs[0x40] & 0x02) + ide_pri_enable(); + if (vt82c586b.ide_regs[0x40] & 0x01) + ide_sec_enable(); + } + } } static uint8_t usb_reg_read(uint16_t addr, void *p) { -// pclog("usb_reg_read: addr=%04x\n", addr); - switch (addr & 0x1f) { - case 0x10: - case 0x11: - case 0x12: - case 0x13: /*Port status*/ - return 0; - } - return 0xff; + // pclog("usb_reg_read: addr=%04x\n", addr); + switch (addr & 0x1f) { + case 0x10: + case 0x11: + case 0x12: + case 0x13: /*Port status*/ + return 0; + } + return 0xff; } static void usb_reg_write(uint16_t addr, uint8_t val, void *p) { -// pclog("usb_reg_write: addr=%04x val=%02x\n", addr, val); + // pclog("usb_reg_write: addr=%04x val=%02x\n", addr, val); } static void usb_update_io_mapping() { - io_removehandler(vt82c586b.usb.io_base, 0x20, usb_reg_read, NULL, NULL, usb_reg_write, NULL, NULL, NULL); - vt82c586b.usb.io_base = (vt82c586b.usb_regs[0x20] & ~0x1f) | (vt82c586b.usb_regs[0x21] << 8); - if (vt82c586b.usb_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) - io_sethandler(vt82c586b.usb.io_base, 0x20, usb_reg_read, NULL, NULL, usb_reg_write, NULL, NULL, NULL); + io_removehandler(vt82c586b.usb.io_base, 0x20, usb_reg_read, NULL, NULL, usb_reg_write, NULL, NULL, NULL); + vt82c586b.usb.io_base = (vt82c586b.usb_regs[0x20] & ~0x1f) | (vt82c586b.usb_regs[0x21] << 8); + if (vt82c586b.usb_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) + io_sethandler(vt82c586b.usb.io_base, 0x20, usb_reg_read, NULL, NULL, usb_reg_write, NULL, NULL, NULL); } static void vt82c586b_usb_write(int addr, uint8_t val) { - /*Read-only addresses*/ - if ((addr < 4) || (addr == 5) || (addr == 6) - || (addr >= 8 && addr < 0xd) - || (addr >= 0xe && addr < 0x20) - || (addr >= 0x22 && addr < 0x3c) - || (addr >= 0x3e && addr < 0x40) - || (addr >= 0x42 && addr < 0x44) - || (addr >= 0x46 && addr < 0xc0) - || (addr >= 0xc2)) - return; + /*Read-only addresses*/ + if ((addr < 4) || (addr == 5) || (addr == 6) || (addr >= 8 && addr < 0xd) || (addr >= 0xe && addr < 0x20) || + (addr >= 0x22 && addr < 0x3c) || (addr >= 0x3e && addr < 0x40) || (addr >= 0x42 && addr < 0x44) || + (addr >= 0x46 && addr < 0xc0) || (addr >= 0xc2)) + return; - switch (addr) { - case 4:vt82c586b.usb_regs[4] = val & 0x97; - usb_update_io_mapping(); - break; - case 7:vt82c586b.usb_regs[7] = val & 0x7f; - break; + switch (addr) { + case 4: + vt82c586b.usb_regs[4] = val & 0x97; + usb_update_io_mapping(); + break; + case 7: + vt82c586b.usb_regs[7] = val & 0x7f; + break; - case 0x20:vt82c586b.usb_regs[0x20] = (val & ~0x1f) | 1; - usb_update_io_mapping(); - break; - case 0x21:vt82c586b.usb_regs[0x21] = val; - usb_update_io_mapping(); - break; + case 0x20: + vt82c586b.usb_regs[0x20] = (val & ~0x1f) | 1; + usb_update_io_mapping(); + break; + case 0x21: + vt82c586b.usb_regs[0x21] = val; + usb_update_io_mapping(); + break; - default:vt82c586b.usb_regs[addr] = val; - break; - } -// pclog(" USB write %02x %02x\n", addr, val); + default: + vt82c586b.usb_regs[addr] = val; + break; + } + // pclog(" USB write %02x %02x\n", addr, val); } static uint8_t power_reg_read(uint16_t addr, void *p) { - uint32_t timer; - uint8_t ret = 0xff; + uint32_t timer; + uint8_t ret = 0xff; - switch (addr & 0xff) { - case 0x00: - case 0x01:ret = vt82c586b.power.pm_status >> ((addr & 1) * 8); - break; - case 0x02: - case 0x03:ret = vt82c586b.power.pm_enable >> ((addr & 1) * 8); - break; - case 0x04: - case 0x05:ret = vt82c586b.power.pm_ctrl >> ((addr & 1) * 8); - break; + switch (addr & 0xff) { + case 0x00: + case 0x01: + ret = vt82c586b.power.pm_status >> ((addr & 1) * 8); + break; + case 0x02: + case 0x03: + ret = vt82c586b.power.pm_enable >> ((addr & 1) * 8); + break; + case 0x04: + case 0x05: + ret = vt82c586b.power.pm_ctrl >> ((addr & 1) * 8); + break; - case 0x08: - case 0x09: - case 0x0a: - case 0x0b: /*ACPI timer*/ - timer = (tsc * ACPI_TIMER_FREQ) / cpu_get_speed(); - if (!(vt82c586b.power_regs[0x41] & ACPI_TIMER_32BIT)) - timer &= 0x00ffffff; - return (timer >> (8 * (addr & 3))) & 0xff; + case 0x08: + case 0x09: + case 0x0a: + case 0x0b: /*ACPI timer*/ + timer = (tsc * ACPI_TIMER_FREQ) / cpu_get_speed(); + if (!(vt82c586b.power_regs[0x41] & ACPI_TIMER_32BIT)) + timer &= 0x00ffffff; + return (timer >> (8 * (addr & 3))) & 0xff; - case 0x28: - case 0x29:ret = vt82c586b.power.gbl_status >> ((addr & 1) * 8); - break; - case 0x2a: - case 0x2b:ret = vt82c586b.power.gbl_enable >> ((addr & 1) * 8); - break; - case 0x2c: - case 0x2d:ret = vt82c586b.power.gbl_ctrl >> ((addr & 1) * 8); - break; + case 0x28: + case 0x29: + ret = vt82c586b.power.gbl_status >> ((addr & 1) * 8); + break; + case 0x2a: + case 0x2b: + ret = vt82c586b.power.gbl_enable >> ((addr & 1) * 8); + break; + case 0x2c: + case 0x2d: + ret = vt82c586b.power.gbl_ctrl >> ((addr & 1) * 8); + break; - case 0x2f:ret = vt82c586b.power.smi_cmd; - break; - } -// pclog("power_reg_read: addr=%04x ret=%02x\n", addr, ret); - return ret; + case 0x2f: + ret = vt82c586b.power.smi_cmd; + break; + } + // pclog("power_reg_read: addr=%04x ret=%02x\n", addr, ret); + return ret; } static void power_reg_write(uint16_t addr, uint8_t val, void *p) { -// pclog("power_reg_write: addr=%04x val=%02x\n", addr, val); - switch (addr & 0xff) { - case 0x00:vt82c586b.power.pm_status &= ~(val & 0x31); - break; - case 0x01:vt82c586b.power.pm_status &= ~((val & 0x8d) << 8); - break; + // pclog("power_reg_write: addr=%04x val=%02x\n", addr, val); + switch (addr & 0xff) { + case 0x00: + vt82c586b.power.pm_status &= ~(val & 0x31); + break; + case 0x01: + vt82c586b.power.pm_status &= ~((val & 0x8d) << 8); + break; - case 0x02:vt82c586b.power.pm_enable = (vt82c586b.power.pm_enable & ~0xff) | (val & 0x21); - break; - case 0x03:vt82c586b.power.pm_enable = (vt82c586b.power.pm_enable & ~0xff00) | ((val & 0x05) << 8); - break; + case 0x02: + vt82c586b.power.pm_enable = (vt82c586b.power.pm_enable & ~0xff) | (val & 0x21); + break; + case 0x03: + vt82c586b.power.pm_enable = (vt82c586b.power.pm_enable & ~0xff00) | ((val & 0x05) << 8); + break; - case 0x04:vt82c586b.power.pm_ctrl = (vt82c586b.power.pm_ctrl & ~0xff) | (val & 0x07); - if (val & (1 << 2)) - pclog("VT82C586B set GBL_RLS\n"); - break; - case 0x05:vt82c586b.power.pm_ctrl = (vt82c586b.power.pm_ctrl & ~0xff00) | ((val & 0x1c) << 8); - /*Note: PM_CTRL_SLP_EN is write-only, hence not stored in pm_ctrl*/ - if (val & (PM_CTRL_SLP_EN >> 8)) { - pclog("VT82C586B transition to power state %i\n", (val >> 2) & 7); - if (!(vt82c586b.power.pm_ctrl & PM_CTRL_SLP_TYP_MASK)) { - pclog("Power off\n"); - stop_emulation_now(); - } - } - break; + case 0x04: + vt82c586b.power.pm_ctrl = (vt82c586b.power.pm_ctrl & ~0xff) | (val & 0x07); + if (val & (1 << 2)) + pclog("VT82C586B set GBL_RLS\n"); + break; + case 0x05: + vt82c586b.power.pm_ctrl = (vt82c586b.power.pm_ctrl & ~0xff00) | ((val & 0x1c) << 8); + /*Note: PM_CTRL_SLP_EN is write-only, hence not stored in pm_ctrl*/ + if (val & (PM_CTRL_SLP_EN >> 8)) { + pclog("VT82C586B transition to power state %i\n", (val >> 2) & 7); + if (!(vt82c586b.power.pm_ctrl & PM_CTRL_SLP_TYP_MASK)) { + pclog("Power off\n"); + stop_emulation_now(); + } + } + break; - case 0x28:vt82c586b.power.gbl_status &= ~(val & 0x7f); - break; + case 0x28: + vt82c586b.power.gbl_status &= ~(val & 0x7f); + break; - case 0x2a:vt82c586b.power.gbl_enable = (vt82c586b.power.gbl_enable & ~0xff) | (val & 0x7f); - break; + case 0x2a: + vt82c586b.power.gbl_enable = (vt82c586b.power.gbl_enable & ~0xff) | (val & 0x7f); + break; - case 0x2c:vt82c586b.power.gbl_ctrl = (vt82c586b.power.gbl_ctrl & ~0xff) | (val & 0x17); - if (val & (1 << 1)) - pclog("VT82C586B set BIOS_RLS\n"); - break; - case 0x2d: - if (val & 1) - vt82c586b.power.gbl_ctrl &= ~0x100; - break; + case 0x2c: + vt82c586b.power.gbl_ctrl = (vt82c586b.power.gbl_ctrl & ~0xff) | (val & 0x17); + if (val & (1 << 1)) + pclog("VT82C586B set BIOS_RLS\n"); + break; + case 0x2d: + if (val & 1) + vt82c586b.power.gbl_ctrl &= ~0x100; + break; - case 0x2f:vt82c586b.power.smi_cmd = val; - vt82c586b.power_regs[0x47] = val; - if (vt82c586b.power.gbl_enable & GBL_SW_SMI_EN) { - vt82c586b.power.gbl_status |= GBL_SW_SMI_STS; - x86_smi_trigger(); - } - pclog("SMI_CMD write %02x\n", val); - break; - } + case 0x2f: + vt82c586b.power.smi_cmd = val; + vt82c586b.power_regs[0x47] = val; + if (vt82c586b.power.gbl_enable & GBL_SW_SMI_EN) { + vt82c586b.power.gbl_status |= GBL_SW_SMI_STS; + x86_smi_trigger(); + } + pclog("SMI_CMD write %02x\n", val); + break; + } } static void vt82c586b_power_write(int addr, uint8_t val) { - /*Read-only addresses*/ - if ((addr < 0xd) || (addr >= 0xe && addr < 0x40) - || (addr == 0x43) - || (addr == 0x48) - || (addr >= 0x4a && addr < 0x50) - || (addr >= 0x54)) - return; + /*Read-only addresses*/ + if ((addr < 0xd) || (addr >= 0xe && addr < 0x40) || (addr == 0x43) || (addr == 0x48) || (addr >= 0x4a && addr < 0x50) || + (addr >= 0x54)) + return; - switch (addr) { - case 0x41:io_removehandler(vt82c586b.power.io_base, 0x0100, power_reg_read, NULL, NULL, power_reg_write, NULL, NULL, NULL); - vt82c586b.power_regs[addr] = val; - if (vt82c586b.power_regs[0x41] & ACPI_IO_ENABLE) - io_sethandler(vt82c586b.power.io_base, 0x0100, power_reg_read, NULL, NULL, power_reg_write, NULL, NULL, NULL); - break; + switch (addr) { + case 0x41: + io_removehandler(vt82c586b.power.io_base, 0x0100, power_reg_read, NULL, NULL, power_reg_write, NULL, NULL, NULL); + vt82c586b.power_regs[addr] = val; + if (vt82c586b.power_regs[0x41] & ACPI_IO_ENABLE) + io_sethandler(vt82c586b.power.io_base, 0x0100, power_reg_read, NULL, NULL, power_reg_write, NULL, NULL, + NULL); + break; - case 0x49:io_removehandler(vt82c586b.power.io_base, 0x0100, power_reg_read, NULL, NULL, power_reg_write, NULL, NULL, NULL); - vt82c586b.power_regs[addr] = val; - vt82c586b.power.io_base = val << 8; - if (vt82c586b.power_regs[0x41] & ACPI_IO_ENABLE) - io_sethandler(vt82c586b.power.io_base, 0x0100, power_reg_read, NULL, NULL, power_reg_write, NULL, NULL, NULL); - break; + case 0x49: + io_removehandler(vt82c586b.power.io_base, 0x0100, power_reg_read, NULL, NULL, power_reg_write, NULL, NULL, NULL); + vt82c586b.power_regs[addr] = val; + vt82c586b.power.io_base = val << 8; + if (vt82c586b.power_regs[0x41] & ACPI_IO_ENABLE) + io_sethandler(vt82c586b.power.io_base, 0x0100, power_reg_read, NULL, NULL, power_reg_write, NULL, NULL, + NULL); + break; - default:vt82c586b.power_regs[addr] = val; - break; - } + default: + vt82c586b.power_regs[addr] = val; + break; + } } static void vt82c586b_write(int func, int addr, uint8_t val, void *priv) { - switch (func) { - case 0:vt82c586b_pci_isa_bridge_write(addr, val); - break; + switch (func) { + case 0: + vt82c586b_pci_isa_bridge_write(addr, val); + break; - case 1:vt82c586b_ide_write(addr, val); - break; + case 1: + vt82c586b_ide_write(addr, val); + break; - case 2:vt82c586b_usb_write(addr, val); - break; + case 2: + vt82c586b_usb_write(addr, val); + break; - case 3:vt82c586b_power_write(addr, val); - break; - } + case 3: + vt82c586b_power_write(addr, val); + break; + } } -uint8_t vt82c586b_read_sysctrl(uint16_t port, void *p) { - return vt82c586b.sysctrl; -} +uint8_t vt82c586b_read_sysctrl(uint16_t port, void *p) { return vt82c586b.sysctrl; } void vt82c586b_write_sysctrl(uint16_t port, uint8_t val, void *p) { - if ((mem_a20_alt ^ val) & 2) { - mem_a20_alt = val & 2; - mem_a20_recalc(); - } - if ((~vt82c586b.sysctrl & val) & 1) { - softresetx86(); - cpu_set_edx(); - } - vt82c586b.sysctrl = val; + if ((mem_a20_alt ^ val) & 2) { + mem_a20_alt = val & 2; + mem_a20_recalc(); + } + if ((~vt82c586b.sysctrl & val) & 1) { + softresetx86(); + cpu_set_edx(); + } + vt82c586b.sysctrl = val; } void vt82c586b_init(int card, int pci_a, int pci_b, int pci_c, int pci_d) { - pci_add_specific(card, vt82c586b_read, vt82c586b_write, NULL); - io_sethandler(0x0092, 0x0001, vt82c586b_read_sysctrl, NULL, NULL, vt82c586b_write_sysctrl, NULL, NULL, NULL); + pci_add_specific(card, vt82c586b_read, vt82c586b_write, NULL); + io_sethandler(0x0092, 0x0001, vt82c586b_read_sysctrl, NULL, NULL, vt82c586b_write_sysctrl, NULL, NULL, NULL); - memset(&vt82c586b, 0, sizeof(vt82c586b)); - vt82c586b.pci_isa_bridge_regs[0x00] = 0x06; - vt82c586b.pci_isa_bridge_regs[0x01] = 0x11; /*VIA*/ - vt82c586b.pci_isa_bridge_regs[0x02] = 0x86; - vt82c586b.pci_isa_bridge_regs[0x03] = 0x05; /*VT82C586B*/ - vt82c586b.pci_isa_bridge_regs[0x04] = 0x0f; - vt82c586b.pci_isa_bridge_regs[0x05] = 0x00; - vt82c586b.pci_isa_bridge_regs[0x06] = 0x00; - vt82c586b.pci_isa_bridge_regs[0x07] = 0x02; - vt82c586b.pci_isa_bridge_regs[0x0a] = 0x01; - vt82c586b.pci_isa_bridge_regs[0x0b] = 0x06; - vt82c586b.pci_isa_bridge_regs[0x0e] = 0x80; + memset(&vt82c586b, 0, sizeof(vt82c586b)); + vt82c586b.pci_isa_bridge_regs[0x00] = 0x06; + vt82c586b.pci_isa_bridge_regs[0x01] = 0x11; /*VIA*/ + vt82c586b.pci_isa_bridge_regs[0x02] = 0x86; + vt82c586b.pci_isa_bridge_regs[0x03] = 0x05; /*VT82C586B*/ + vt82c586b.pci_isa_bridge_regs[0x04] = 0x0f; + vt82c586b.pci_isa_bridge_regs[0x05] = 0x00; + vt82c586b.pci_isa_bridge_regs[0x06] = 0x00; + vt82c586b.pci_isa_bridge_regs[0x07] = 0x02; + vt82c586b.pci_isa_bridge_regs[0x0a] = 0x01; + vt82c586b.pci_isa_bridge_regs[0x0b] = 0x06; + vt82c586b.pci_isa_bridge_regs[0x0e] = 0x80; - /*ISA bus control*/ - vt82c586b.pci_isa_bridge_regs[0x48] = 0x01; - vt82c586b.pci_isa_bridge_regs[0x4a] = 0x04; - vt82c586b.pci_isa_bridge_regs[0x4f] = 0x03; + /*ISA bus control*/ + vt82c586b.pci_isa_bridge_regs[0x48] = 0x01; + vt82c586b.pci_isa_bridge_regs[0x4a] = 0x04; + vt82c586b.pci_isa_bridge_regs[0x4f] = 0x03; - /*Plug and Play control*/ - vt82c586b.pci_isa_bridge_regs[0x50] = 0x24; - vt82c586b.pci_isa_bridge_regs[0x59] = 0x04; + /*Plug and Play control*/ + vt82c586b.pci_isa_bridge_regs[0x50] = 0x24; + vt82c586b.pci_isa_bridge_regs[0x59] = 0x04; - vt82c586b.ide_regs[0x00] = 0x06; - vt82c586b.ide_regs[0x01] = 0x11; /*VIA*/ - vt82c586b.ide_regs[0x02] = 0x71; - vt82c586b.ide_regs[0x03] = 0x05; - vt82c586b.ide_regs[0x04] = 0x80; - vt82c586b.ide_regs[0x05] = 0x00; - vt82c586b.ide_regs[0x06] = 0x80; - vt82c586b.ide_regs[0x07] = 0x02; - vt82c586b.ide_regs[0x09] = 0x85; - vt82c586b.ide_regs[0x0a] = 0x01; - vt82c586b.ide_regs[0x0b] = 0x01; + vt82c586b.ide_regs[0x00] = 0x06; + vt82c586b.ide_regs[0x01] = 0x11; /*VIA*/ + vt82c586b.ide_regs[0x02] = 0x71; + vt82c586b.ide_regs[0x03] = 0x05; + vt82c586b.ide_regs[0x04] = 0x80; + vt82c586b.ide_regs[0x05] = 0x00; + vt82c586b.ide_regs[0x06] = 0x80; + vt82c586b.ide_regs[0x07] = 0x02; + vt82c586b.ide_regs[0x09] = 0x85; + vt82c586b.ide_regs[0x0a] = 0x01; + vt82c586b.ide_regs[0x0b] = 0x01; - vt82c586b.ide_regs[0x10] = 0xf1; - vt82c586b.ide_regs[0x11] = 0x01; - vt82c586b.ide_regs[0x14] = 0xf5; - vt82c586b.ide_regs[0x15] = 0x03; - vt82c586b.ide_regs[0x18] = 0x71; - vt82c586b.ide_regs[0x19] = 0x01; - vt82c586b.ide_regs[0x1c] = 0x75; - vt82c586b.ide_regs[0x1d] = 0x03; - vt82c586b.ide_regs[0x20] = 0x01; - vt82c586b.ide_regs[0x21] = 0xcc; - vt82c586b.ide_regs[0x3c] = 0x0e; + vt82c586b.ide_regs[0x10] = 0xf1; + vt82c586b.ide_regs[0x11] = 0x01; + vt82c586b.ide_regs[0x14] = 0xf5; + vt82c586b.ide_regs[0x15] = 0x03; + vt82c586b.ide_regs[0x18] = 0x71; + vt82c586b.ide_regs[0x19] = 0x01; + vt82c586b.ide_regs[0x1c] = 0x75; + vt82c586b.ide_regs[0x1d] = 0x03; + vt82c586b.ide_regs[0x20] = 0x01; + vt82c586b.ide_regs[0x21] = 0xcc; + vt82c586b.ide_regs[0x3c] = 0x0e; - vt82c586b.ide_regs[0x40] = 0x08; - vt82c586b.ide_regs[0x41] = 0x02; - vt82c586b.ide_regs[0x42] = 0x09; - vt82c586b.ide_regs[0x43] = 0x3a; - vt82c586b.ide_regs[0x44] = 0x68; - vt82c586b.ide_regs[0x46] = 0xc0; - vt82c586b.ide_regs[0x48] = 0xa8; - vt82c586b.ide_regs[0x49] = 0xa8; - vt82c586b.ide_regs[0x4a] = 0xa8; - vt82c586b.ide_regs[0x4b] = 0xa8; - vt82c586b.ide_regs[0x4c] = 0xff; - vt82c586b.ide_regs[0x4e] = 0xff; - vt82c586b.ide_regs[0x4f] = 0xff; - vt82c586b.ide_regs[0x50] = 0x03; - vt82c586b.ide_regs[0x51] = 0x03; - vt82c586b.ide_regs[0x52] = 0x03; - vt82c586b.ide_regs[0x53] = 0x03; - vt82c586b.ide_regs[0x61] = 0x02; - vt82c586b.ide_regs[0x68] = 0x02; + vt82c586b.ide_regs[0x40] = 0x08; + vt82c586b.ide_regs[0x41] = 0x02; + vt82c586b.ide_regs[0x42] = 0x09; + vt82c586b.ide_regs[0x43] = 0x3a; + vt82c586b.ide_regs[0x44] = 0x68; + vt82c586b.ide_regs[0x46] = 0xc0; + vt82c586b.ide_regs[0x48] = 0xa8; + vt82c586b.ide_regs[0x49] = 0xa8; + vt82c586b.ide_regs[0x4a] = 0xa8; + vt82c586b.ide_regs[0x4b] = 0xa8; + vt82c586b.ide_regs[0x4c] = 0xff; + vt82c586b.ide_regs[0x4e] = 0xff; + vt82c586b.ide_regs[0x4f] = 0xff; + vt82c586b.ide_regs[0x50] = 0x03; + vt82c586b.ide_regs[0x51] = 0x03; + vt82c586b.ide_regs[0x52] = 0x03; + vt82c586b.ide_regs[0x53] = 0x03; + vt82c586b.ide_regs[0x61] = 0x02; + vt82c586b.ide_regs[0x68] = 0x02; - vt82c586b.usb_regs[0x00] = 0x06; - vt82c586b.usb_regs[0x01] = 0x11; /*VIA*/ - vt82c586b.usb_regs[0x02] = 0x38; - vt82c586b.usb_regs[0x03] = 0x30; - vt82c586b.usb_regs[0x04] = 0x00; - vt82c586b.usb_regs[0x05] = 0x00; - vt82c586b.usb_regs[0x06] = 0x00; - vt82c586b.usb_regs[0x07] = 0x02; - vt82c586b.usb_regs[0x0a] = 0x03; - vt82c586b.usb_regs[0x0b] = 0x0c; - vt82c586b.usb_regs[0x0d] = 0x16; - vt82c586b.usb_regs[0x20] = 0x01; - vt82c586b.usb_regs[0x21] = 0x03; - vt82c586b.usb_regs[0x3d] = 0x04; + vt82c586b.usb_regs[0x00] = 0x06; + vt82c586b.usb_regs[0x01] = 0x11; /*VIA*/ + vt82c586b.usb_regs[0x02] = 0x38; + vt82c586b.usb_regs[0x03] = 0x30; + vt82c586b.usb_regs[0x04] = 0x00; + vt82c586b.usb_regs[0x05] = 0x00; + vt82c586b.usb_regs[0x06] = 0x00; + vt82c586b.usb_regs[0x07] = 0x02; + vt82c586b.usb_regs[0x0a] = 0x03; + vt82c586b.usb_regs[0x0b] = 0x0c; + vt82c586b.usb_regs[0x0d] = 0x16; + vt82c586b.usb_regs[0x20] = 0x01; + vt82c586b.usb_regs[0x21] = 0x03; + vt82c586b.usb_regs[0x3d] = 0x04; - vt82c586b.usb_regs[0x60] = 0x10; - vt82c586b.usb_regs[0xc1] = 0x20; + vt82c586b.usb_regs[0x60] = 0x10; + vt82c586b.usb_regs[0xc1] = 0x20; - vt82c586b.power_regs[0x00] = 0x06; - vt82c586b.power_regs[0x01] = 0x11; /*VIA*/ - vt82c586b.power_regs[0x02] = 0x40; - vt82c586b.power_regs[0x03] = 0x30; - vt82c586b.power_regs[0x04] = 0x00; - vt82c586b.power_regs[0x05] = 0x00; - vt82c586b.power_regs[0x06] = 0x80; - vt82c586b.power_regs[0x07] = 0x02; - vt82c586b.power_regs[0x08] = 0x10; /*Production version (3041)*/ - vt82c586b.power_regs[0x48] = 0x01; + vt82c586b.power_regs[0x00] = 0x06; + vt82c586b.power_regs[0x01] = 0x11; /*VIA*/ + vt82c586b.power_regs[0x02] = 0x40; + vt82c586b.power_regs[0x03] = 0x30; + vt82c586b.power_regs[0x04] = 0x00; + vt82c586b.power_regs[0x05] = 0x00; + vt82c586b.power_regs[0x06] = 0x80; + vt82c586b.power_regs[0x07] = 0x02; + vt82c586b.power_regs[0x08] = 0x10; /*Production version (3041)*/ + vt82c586b.power_regs[0x48] = 0x01; - if (pci_a) - pci_set_card_routing(pci_a, PCI_INTA); - if (pci_b) - pci_set_card_routing(pci_b, PCI_INTB); - if (pci_c) - pci_set_card_routing(pci_c, PCI_INTC); - if (pci_d) - pci_set_card_routing(pci_d, PCI_INTD); + if (pci_a) + pci_set_card_routing(pci_a, PCI_INTA); + if (pci_b) + pci_set_card_routing(pci_b, PCI_INTB); + if (pci_c) + pci_set_card_routing(pci_c, PCI_INTC); + if (pci_d) + pci_set_card_routing(pci_d, PCI_INTD); - sff_bus_master_init(vt82c586b.busmaster); + sff_bus_master_init(vt82c586b.busmaster); - ide_pri_disable(); - ide_sec_disable(); + ide_pri_disable(); + ide_sec_disable(); } diff --git a/src/models/w83877tf.c b/src/models/w83877tf.c index 86d1ad8a..3828adf1 100644 --- a/src/models/w83877tf.c +++ b/src/models/w83877tf.c @@ -6,18 +6,15 @@ #include "serial.h" #include "w83877tf.h" -enum { - CHIP_W83877F, - CHIP_W83877TF -}; +enum { CHIP_W83877F, CHIP_W83877TF }; typedef struct w83877tf_t { - int enable_regs; - uint8_t key[2]; - uint8_t unlock_key; - int index; - uint8_t regs[256]; - int chip; + int enable_regs; + uint8_t key[2]; + uint8_t unlock_key; + int index; + uint8_t regs[256]; + int chip; } w83877tf_t; static w83877tf_t w83877tf_global; @@ -28,208 +25,209 @@ static void w83877tf_write_3fx(uint16_t port, uint8_t val, void *p); static uint8_t w83877tf_read_3fx(uint16_t port, void *p); static void w83877tf_write_reg(w83877tf_t *w83877tf, int index, uint8_t val) { -// pclog("w83877tf_write: index=%02x val=%02x\n", index, val); - switch (index) { - case 0x0c: - if (w83877tf->regs[0x16] & 1) - w83877tf->unlock_key = (val & (1 << 5)) ? 0x87 : 0x86; - else - w83877tf->unlock_key = (val & (1 << 5)) ? 0x89 : 0x88; - break; + // pclog("w83877tf_write: index=%02x val=%02x\n", index, val); + switch (index) { + case 0x0c: + if (w83877tf->regs[0x16] & 1) + w83877tf->unlock_key = (val & (1 << 5)) ? 0x87 : 0x86; + else + w83877tf->unlock_key = (val & (1 << 5)) ? 0x89 : 0x88; + break; - case 0x16: - if (val == 2) /*Written by VA-503+ BIOS. Apparently should not change IO mapping*/ - return; + case 0x16: + if (val == 2) /*Written by VA-503+ BIOS. Apparently should not change IO mapping*/ + return; - io_removehandler(0x0250, 0x0003, w83877tf_read_25x, NULL, NULL, w83877tf_write_25x, NULL, NULL, &w83877tf_global); - io_removehandler(0x03f0, 0x0002, w83877tf_read_3fx, NULL, NULL, w83877tf_write_3fx, NULL, NULL, &w83877tf_global); - if (val & 0x01) { - io_sethandler(0x03f0, 0x0002, w83877tf_read_3fx, NULL, NULL, w83877tf_write_3fx, NULL, NULL, &w83877tf_global); - w83877tf->unlock_key = (w83877tf->regs[0xc] & (1 << 5)) ? 0x87 : 0x86; - } else { - io_sethandler(0x0250, 0x0003, w83877tf_read_25x, NULL, NULL, w83877tf_write_25x, NULL, NULL, &w83877tf_global); - w83877tf->unlock_key = (w83877tf->regs[0xc] & (1 << 5)) ? 0x89 : 0x88; - } + io_removehandler(0x0250, 0x0003, w83877tf_read_25x, NULL, NULL, w83877tf_write_25x, NULL, NULL, &w83877tf_global); + io_removehandler(0x03f0, 0x0002, w83877tf_read_3fx, NULL, NULL, w83877tf_write_3fx, NULL, NULL, &w83877tf_global); + if (val & 0x01) { + io_sethandler(0x03f0, 0x0002, w83877tf_read_3fx, NULL, NULL, w83877tf_write_3fx, NULL, NULL, + &w83877tf_global); + w83877tf->unlock_key = (w83877tf->regs[0xc] & (1 << 5)) ? 0x87 : 0x86; + } else { + io_sethandler(0x0250, 0x0003, w83877tf_read_25x, NULL, NULL, w83877tf_write_25x, NULL, NULL, + &w83877tf_global); + w83877tf->unlock_key = (w83877tf->regs[0xc] & (1 << 5)) ? 0x89 : 0x88; + } - if ((w83877tf->regs[0x16] & 4) && !(val & 4)) { - w83877tf->regs[0x20] = 0; - w83877tf->regs[0x23] = 0; - w83877tf->regs[0x24] = 0; - w83877tf->regs[0x25] = 0; - w83877tf->regs[0x26] = 0; - w83877tf->regs[0x27] = 0; - w83877tf->regs[0x28] = 0; - w83877tf->regs[0x29] = 0; - } - break; - } + if ((w83877tf->regs[0x16] & 4) && !(val & 4)) { + w83877tf->regs[0x20] = 0; + w83877tf->regs[0x23] = 0; + w83877tf->regs[0x24] = 0; + w83877tf->regs[0x25] = 0; + w83877tf->regs[0x26] = 0; + w83877tf->regs[0x27] = 0; + w83877tf->regs[0x28] = 0; + w83877tf->regs[0x29] = 0; + } + break; + } - w83877tf->regs[index] = val; + w83877tf->regs[index] = val; - fdc_remove(); - if (w83877tf->regs[0x20] >= 0x40) - fdc_add(); + fdc_remove(); + if (w83877tf->regs[0x20] >= 0x40) + fdc_add(); - lpt1_remove(); - lpt2_remove(); - if (w83877tf->regs[0x23] >= 0x40) - lpt1_init(w83877tf->regs[0x23] << 2); + lpt1_remove(); + lpt2_remove(); + if (w83877tf->regs[0x23] >= 0x40) + lpt1_init(w83877tf->regs[0x23] << 2); - serial1_remove(); - if (w83877tf->regs[0x24] >= 0x40) - serial1_set((w83877tf->regs[0x24] & ~1) << 2, w83877tf->regs[0x28] >> 4); + serial1_remove(); + if (w83877tf->regs[0x24] >= 0x40) + serial1_set((w83877tf->regs[0x24] & ~1) << 2, w83877tf->regs[0x28] >> 4); - serial2_remove(); - if (w83877tf->regs[0x25] >= 0x40) - serial2_set((w83877tf->regs[0x25] & ~1) << 2, w83877tf->regs[0x28] & 0xf); + serial2_remove(); + if (w83877tf->regs[0x25] >= 0x40) + serial2_set((w83877tf->regs[0x25] & ~1) << 2, w83877tf->regs[0x28] & 0xf); -// pclog("LPT at %04x\n", w83877tf->regs[0x23] << 2); -// pclog("Serial1 at %04x %i\n", (w83877tf->regs[0x24] & ~1) << 2, w83877tf->regs[0x28] >> 4); -// pclog("Serial2 at %04x %i\n", (w83877tf->regs[0x25] & ~1) << 2, w83877tf->regs[0x28] & 0xf); + // pclog("LPT at %04x\n", w83877tf->regs[0x23] << 2); + // pclog("Serial1 at %04x %i\n", (w83877tf->regs[0x24] & ~1) << 2, w83877tf->regs[0x28] >> 4); + // pclog("Serial2 at %04x %i\n", (w83877tf->regs[0x25] & ~1) << 2, w83877tf->regs[0x28] & 0xf); } static uint8_t w83877tf_read_reg(w83877tf_t *w83877tf, int index) { - switch (w83877tf->index) { - case 0x09: - switch (w83877tf->chip) { - case CHIP_W83877F:return 0x0a; /*W83877F ID*/ - case CHIP_W83877TF:return 0x0c; /*W83877TF ID*/ - } - break; - } - return w83877tf->regs[index]; + switch (w83877tf->index) { + case 0x09: + switch (w83877tf->chip) { + case CHIP_W83877F: + return 0x0a; /*W83877F ID*/ + case CHIP_W83877TF: + return 0x0c; /*W83877TF ID*/ + } + break; + } + return w83877tf->regs[index]; } static void w83877tf_write_25x(uint16_t port, uint8_t val, void *p) { - w83877tf_t *w83877tf = (w83877tf_t *)p; + w83877tf_t *w83877tf = (w83877tf_t *)p; -// pclog("w83877tf_write: port=%04x val=%02x\n", port, val); + // pclog("w83877tf_write: port=%04x val=%02x\n", port, val); - switch (port) { - case 0x250: /*Enable register*/ - w83877tf->enable_regs = (val == w83877tf->unlock_key) ? 1 : 0; - break; - case 0x251: /*Index*/ - if (w83877tf->enable_regs) - w83877tf->index = val; - break; - case 0x252: /*Data*/ - if (w83877tf->enable_regs) - w83877tf_write_reg(w83877tf, w83877tf->index, val); - break; - } + switch (port) { + case 0x250: /*Enable register*/ + w83877tf->enable_regs = (val == w83877tf->unlock_key) ? 1 : 0; + break; + case 0x251: /*Index*/ + if (w83877tf->enable_regs) + w83877tf->index = val; + break; + case 0x252: /*Data*/ + if (w83877tf->enable_regs) + w83877tf_write_reg(w83877tf, w83877tf->index, val); + break; + } } static uint8_t w83877tf_read_25x(uint16_t port, void *p) { - w83877tf_t *w83877tf = (w83877tf_t *)p; + w83877tf_t *w83877tf = (w83877tf_t *)p; - switch (port) { - case 0x251: /*Index*/ - if (w83877tf->enable_regs) - return w83877tf->index; - break; + switch (port) { + case 0x251: /*Index*/ + if (w83877tf->enable_regs) + return w83877tf->index; + break; - case 0x252: /*Data*/ - if (w83877tf->enable_regs) - return w83877tf_read_reg(w83877tf, w83877tf->index); - break; - } + case 0x252: /*Data*/ + if (w83877tf->enable_regs) + return w83877tf_read_reg(w83877tf, w83877tf->index); + break; + } - return 0xff; + return 0xff; } static void w83877tf_write_3fx(uint16_t port, uint8_t val, void *p) { - w83877tf_t *w83877tf = (w83877tf_t *)p; + w83877tf_t *w83877tf = (w83877tf_t *)p; -// pclog("w83877tf_write: port=%04x val=%02x\n", port, val); + // pclog("w83877tf_write: port=%04x val=%02x\n", port, val); - switch (port) { - case 0x3f0: /*Enable/index register*/ - if (val == 0xaa) { - fdc_3f1_enable(1); - w83877tf->enable_regs = 0; - } else if (!w83877tf->enable_regs) { - w83877tf->key[1] = w83877tf->key[0]; - w83877tf->key[0] = val; - w83877tf->enable_regs = (w83877tf->key[0] == w83877tf->unlock_key && w83877tf->key[1] == w83877tf->unlock_key); - /*The FDC conflicts with the 3fx config registers, so disable - it when enabling config registers*/ - if (w83877tf->enable_regs) - fdc_3f1_enable(0); - } else - w83877tf->index = val; - break; - case 0x3f1: /*Data*/ - if (w83877tf->enable_regs) - w83877tf_write_reg(w83877tf, w83877tf->index, val); - break; - } + switch (port) { + case 0x3f0: /*Enable/index register*/ + if (val == 0xaa) { + fdc_3f1_enable(1); + w83877tf->enable_regs = 0; + } else if (!w83877tf->enable_regs) { + w83877tf->key[1] = w83877tf->key[0]; + w83877tf->key[0] = val; + w83877tf->enable_regs = + (w83877tf->key[0] == w83877tf->unlock_key && w83877tf->key[1] == w83877tf->unlock_key); + /*The FDC conflicts with the 3fx config registers, so disable + it when enabling config registers*/ + if (w83877tf->enable_regs) + fdc_3f1_enable(0); + } else + w83877tf->index = val; + break; + case 0x3f1: /*Data*/ + if (w83877tf->enable_regs) + w83877tf_write_reg(w83877tf, w83877tf->index, val); + break; + } } static uint8_t w83877tf_read_3fx(uint16_t port, void *p) { - w83877tf_t *w83877tf = (w83877tf_t *)p; - uint8_t ret = 0xff; + w83877tf_t *w83877tf = (w83877tf_t *)p; + uint8_t ret = 0xff; - switch (port) { - case 0x3f0: /*Index*/ - if (w83877tf->enable_regs) - ret = w83877tf->index; - break; + switch (port) { + case 0x3f0: /*Index*/ + if (w83877tf->enable_regs) + ret = w83877tf->index; + break; - case 0x3f1: /*Data*/ - if (w83877tf->enable_regs) - ret = w83877tf_read_reg(w83877tf, w83877tf->index); - break; - } + case 0x3f1: /*Data*/ + if (w83877tf->enable_regs) + ret = w83877tf_read_reg(w83877tf, w83877tf->index); + break; + } -// pclog("w83877tf_read: port=%04x val=%02x\n", port, ret); + // pclog("w83877tf_read: port=%04x val=%02x\n", port, ret); - return ret; + return ret; } static void w83877_common_init(int chip, uint16_t base, uint8_t key) { - memset(&w83877tf_global, 0, sizeof(w83877tf_t)); + memset(&w83877tf_global, 0, sizeof(w83877tf_t)); - if (base == 0x250) - io_sethandler(0x0250, 0x0003, w83877tf_read_25x, NULL, NULL, w83877tf_write_25x, NULL, NULL, &w83877tf_global); - else - io_sethandler(0x03f0, 0x0002, w83877tf_read_3fx, NULL, NULL, w83877tf_write_3fx, NULL, NULL, &w83877tf_global); + if (base == 0x250) + io_sethandler(0x0250, 0x0003, w83877tf_read_25x, NULL, NULL, w83877tf_write_25x, NULL, NULL, &w83877tf_global); + else + io_sethandler(0x03f0, 0x0002, w83877tf_read_3fx, NULL, NULL, w83877tf_write_3fx, NULL, NULL, &w83877tf_global); - /*Defaults*/ - w83877tf_global.regs[0x03] = 0x30; - w83877tf_global.regs[0x09] = 0x0c; - w83877tf_global.regs[0x0b] = 0x0c; - if (key == 0x88 || key == 0x86) - w83877tf_global.regs[0x0c] = 0x08; - else - w83877tf_global.regs[0x0c] = 0x28; - w83877tf_global.regs[0x0d] = 0xa3; - if (base == 0x250) - w83877tf_global.regs[0x16] = 0x04; - else - w83877tf_global.regs[0x16] = 0x05; - w83877tf_global.regs[0x20] = 0; - w83877tf_global.regs[0x23] = 0; - w83877tf_global.regs[0x24] = 0; - w83877tf_global.regs[0x25] = 0; - w83877tf_global.regs[0x26] = 0; - w83877tf_global.regs[0x27] = 0; - w83877tf_global.regs[0x28] = 0; - w83877tf_global.regs[0x29] = 0; + /*Defaults*/ + w83877tf_global.regs[0x03] = 0x30; + w83877tf_global.regs[0x09] = 0x0c; + w83877tf_global.regs[0x0b] = 0x0c; + if (key == 0x88 || key == 0x86) + w83877tf_global.regs[0x0c] = 0x08; + else + w83877tf_global.regs[0x0c] = 0x28; + w83877tf_global.regs[0x0d] = 0xa3; + if (base == 0x250) + w83877tf_global.regs[0x16] = 0x04; + else + w83877tf_global.regs[0x16] = 0x05; + w83877tf_global.regs[0x20] = 0; + w83877tf_global.regs[0x23] = 0; + w83877tf_global.regs[0x24] = 0; + w83877tf_global.regs[0x25] = 0; + w83877tf_global.regs[0x26] = 0; + w83877tf_global.regs[0x27] = 0; + w83877tf_global.regs[0x28] = 0; + w83877tf_global.regs[0x29] = 0; - fdc_remove(); - lpt1_remove(); - lpt2_remove(); - serial1_remove(); - serial2_remove(); + fdc_remove(); + lpt1_remove(); + lpt2_remove(); + serial1_remove(); + serial2_remove(); - w83877tf_global.chip = chip; - w83877tf_global.unlock_key = key; + w83877tf_global.chip = chip; + w83877tf_global.unlock_key = key; } -void w83877f_init(uint16_t base, uint8_t key) { - w83877_common_init(CHIP_W83877F, base, key); -} -void w83877tf_init(uint16_t base, uint8_t key) { - w83877_common_init(CHIP_W83877TF, base, key); -} +void w83877f_init(uint16_t base, uint8_t key) { w83877_common_init(CHIP_W83877F, base, key); } +void w83877tf_init(uint16_t base, uint8_t key) { w83877_common_init(CHIP_W83877TF, base, key); } diff --git a/src/models/w83977tf.c b/src/models/w83977tf.c index 733d3014..1dbe90d0 100644 --- a/src/models/w83977tf.c +++ b/src/models/w83977tf.c @@ -7,162 +7,175 @@ #include "w83977tf.h" typedef struct winbond_t { - int cur_reg; - int cur_device; - int index; + int cur_reg; + int cur_device; + int index; - uint8_t unlock_key; - uint8_t key[2]; - int enable_regs; + uint8_t unlock_key; + uint8_t key[2]; + int enable_regs; - struct { - int enable; - uint16_t addr; - int irq; - int dma; - } dev[11]; + struct { + int enable; + uint16_t addr; + int irq; + int dma; + } dev[11]; } winbond_t; static winbond_t winbond_global; -#define DEV_FDC 0x0 -#define DEV_LPT 0x1 -#define DEV_COM1 0x2 -#define DEV_COM2 0x3 -#define DEV_KBC 0x5 -#define DEV_GPIO 0x7 -#define DEV_GPIO_II 0x8 -#define DEV_GPIO_III 0x9 -#define DEV_ACPI 0xa +#define DEV_FDC 0x0 +#define DEV_LPT 0x1 +#define DEV_COM1 0x2 +#define DEV_COM2 0x3 +#define DEV_KBC 0x5 +#define DEV_GPIO 0x7 +#define DEV_GPIO_II 0x8 +#define DEV_GPIO_III 0x9 +#define DEV_ACPI 0xa -#define REG_DEVICE 0x07 -#define REG_DEVICE_ID 0x20 -#define REG_DEVICE_REV 0x21 -#define REG_ENABLE 0x30 -#define REG_ADDRHI 0x60 -#define REG_ADDRLO 0x61 -#define REG_IRQ 0x70 -#define REG_DMA 0x74 +#define REG_DEVICE 0x07 +#define REG_DEVICE_ID 0x20 +#define REG_DEVICE_REV 0x21 +#define REG_ENABLE 0x30 +#define REG_ADDRHI 0x60 +#define REG_ADDRLO 0x61 +#define REG_IRQ 0x70 +#define REG_DMA 0x74 void winbond_write_reg(winbond_t *winbond, int index, uint8_t val) { - if (index == REG_DEVICE) - winbond->cur_device = val & 0xf; - else { -// pclog("Write winbond %02x [%02x] %02x\n", winbond->cur_reg, winbond->cur_device, val); - switch (index) { - case REG_ENABLE: - if (winbond->cur_device <= DEV_ACPI) - winbond->dev[winbond->cur_device].enable = val; - break; - case REG_ADDRLO: - if (winbond->cur_device <= DEV_ACPI) - winbond->dev[winbond->cur_device].addr = (winbond->dev[winbond->cur_device].addr & 0xff00) | val; - break; - case REG_ADDRHI: - if (winbond->cur_device <= DEV_ACPI) - winbond->dev[winbond->cur_device].addr = (winbond->dev[winbond->cur_device].addr & 0x00ff) | (val << 8); - break; - case REG_IRQ: - if (winbond->cur_device <= DEV_ACPI) - winbond->dev[winbond->cur_device].irq = val; - break; - case REG_DMA: - if (winbond->cur_device <= DEV_ACPI) - winbond->dev[winbond->cur_device].dma = val; - break; - } + if (index == REG_DEVICE) + winbond->cur_device = val & 0xf; + else { + // pclog("Write winbond %02x [%02x] %02x\n", winbond->cur_reg, winbond->cur_device, val); + switch (index) { + case REG_ENABLE: + if (winbond->cur_device <= DEV_ACPI) + winbond->dev[winbond->cur_device].enable = val; + break; + case REG_ADDRLO: + if (winbond->cur_device <= DEV_ACPI) + winbond->dev[winbond->cur_device].addr = (winbond->dev[winbond->cur_device].addr & 0xff00) | val; + break; + case REG_ADDRHI: + if (winbond->cur_device <= DEV_ACPI) + winbond->dev[winbond->cur_device].addr = + (winbond->dev[winbond->cur_device].addr & 0x00ff) | (val << 8); + break; + case REG_IRQ: + if (winbond->cur_device <= DEV_ACPI) + winbond->dev[winbond->cur_device].irq = val; + break; + case REG_DMA: + if (winbond->cur_device <= DEV_ACPI) + winbond->dev[winbond->cur_device].dma = val; + break; + } - switch (winbond->cur_device) { - case DEV_FDC:fdc_remove(); - if (winbond->dev[DEV_FDC].enable & 1) - fdc_add(); - break; - case DEV_COM1:serial1_remove(); - if (winbond->dev[DEV_COM1].enable & 1) - serial1_set(winbond->dev[DEV_COM1].addr, winbond->dev[DEV_COM1].irq); - break; - case DEV_COM2:serial2_remove(); - if (winbond->dev[DEV_COM2].enable & 1) - serial2_set(winbond->dev[DEV_COM2].addr, winbond->dev[DEV_COM2].irq); - break; - case DEV_LPT:lpt1_remove(); - lpt2_remove(); - if (winbond->dev[DEV_LPT].enable & 1) - lpt1_init(winbond->dev[DEV_LPT].addr); - break; - } - } + switch (winbond->cur_device) { + case DEV_FDC: + fdc_remove(); + if (winbond->dev[DEV_FDC].enable & 1) + fdc_add(); + break; + case DEV_COM1: + serial1_remove(); + if (winbond->dev[DEV_COM1].enable & 1) + serial1_set(winbond->dev[DEV_COM1].addr, winbond->dev[DEV_COM1].irq); + break; + case DEV_COM2: + serial2_remove(); + if (winbond->dev[DEV_COM2].enable & 1) + serial2_set(winbond->dev[DEV_COM2].addr, winbond->dev[DEV_COM2].irq); + break; + case DEV_LPT: + lpt1_remove(); + lpt2_remove(); + if (winbond->dev[DEV_LPT].enable & 1) + lpt1_init(winbond->dev[DEV_LPT].addr); + break; + } + } } uint8_t winbond_read_reg(winbond_t *winbond, int index) { -// pclog("Read winbond %02x\n", winbond->cur_reg); + // pclog("Read winbond %02x\n", winbond->cur_reg); - switch (index) { - case REG_DEVICE:return winbond->cur_device; - case REG_DEVICE_ID:return 0x97; - case REG_DEVICE_REV:return 0x73; - case REG_ENABLE:return winbond->dev[winbond->cur_device].enable; - case REG_ADDRLO:return winbond->dev[winbond->cur_device].addr & 0xff; - case REG_ADDRHI:return winbond->dev[winbond->cur_device].addr >> 8; - case REG_IRQ:return winbond->dev[winbond->cur_device].irq; - case REG_DMA:return winbond->dev[winbond->cur_device].dma; - } + switch (index) { + case REG_DEVICE: + return winbond->cur_device; + case REG_DEVICE_ID: + return 0x97; + case REG_DEVICE_REV: + return 0x73; + case REG_ENABLE: + return winbond->dev[winbond->cur_device].enable; + case REG_ADDRLO: + return winbond->dev[winbond->cur_device].addr & 0xff; + case REG_ADDRHI: + return winbond->dev[winbond->cur_device].addr >> 8; + case REG_IRQ: + return winbond->dev[winbond->cur_device].irq; + case REG_DMA: + return winbond->dev[winbond->cur_device].dma; + } - return 0xff; + return 0xff; } static void winbond_write_3fx(uint16_t port, uint8_t val, void *p) { - winbond_t *winbond = (winbond_t *)p; + winbond_t *winbond = (winbond_t *)p; -// pclog("winbond_write: port=%04x val=%02x\n", port, val); + // pclog("winbond_write: port=%04x val=%02x\n", port, val); - switch (port) { - case 0x3f0: /*Enable/index register*/ - if (val == 0xaa) { - fdc_3f1_enable(1); - winbond->enable_regs = 0; - } else if (!winbond->enable_regs) { - winbond->key[1] = winbond->key[0]; - winbond->key[0] = val; - winbond->enable_regs = (winbond->key[0] == winbond->unlock_key && winbond->key[1] == winbond->unlock_key); - /*The FDC conflicts with the 3fx config registers, so disable - it when enabling config registers*/ - if (winbond->enable_regs) - fdc_3f1_enable(0); - } else - winbond->index = val; - break; - case 0x3f1: /*Data*/ - if (winbond->enable_regs) - winbond_write_reg(winbond, winbond->index, val); - break; - } + switch (port) { + case 0x3f0: /*Enable/index register*/ + if (val == 0xaa) { + fdc_3f1_enable(1); + winbond->enable_regs = 0; + } else if (!winbond->enable_regs) { + winbond->key[1] = winbond->key[0]; + winbond->key[0] = val; + winbond->enable_regs = (winbond->key[0] == winbond->unlock_key && winbond->key[1] == winbond->unlock_key); + /*The FDC conflicts with the 3fx config registers, so disable + it when enabling config registers*/ + if (winbond->enable_regs) + fdc_3f1_enable(0); + } else + winbond->index = val; + break; + case 0x3f1: /*Data*/ + if (winbond->enable_regs) + winbond_write_reg(winbond, winbond->index, val); + break; + } } static uint8_t winbond_read_3fx(uint16_t port, void *p) { - winbond_t *winbond = (winbond_t *)p; - uint8_t ret = 0xff; + winbond_t *winbond = (winbond_t *)p; + uint8_t ret = 0xff; - switch (port) { - case 0x3f0: /*Index*/ - if (winbond->enable_regs) - ret = winbond->index; - break; + switch (port) { + case 0x3f0: /*Index*/ + if (winbond->enable_regs) + ret = winbond->index; + break; - case 0x3f1: /*Data*/ - if (winbond->enable_regs) - ret = winbond_read_reg(winbond, winbond->index); - break; - } + case 0x3f1: /*Data*/ + if (winbond->enable_regs) + ret = winbond_read_reg(winbond, winbond->index); + break; + } -// pclog("winbond_read: port=%04x val=%02x\n", port, ret); + // pclog("winbond_read: port=%04x val=%02x\n", port, ret); - return ret; + return ret; } void w83977tf_init(uint16_t base, uint8_t key) { - memset(&winbond_global, 0, sizeof(winbond_t)); + memset(&winbond_global, 0, sizeof(winbond_t)); - winbond_global.unlock_key = key; - io_sethandler(base, 0x0002, winbond_read_3fx, NULL, NULL, winbond_write_3fx, NULL, NULL, &winbond_global); + winbond_global.unlock_key = key; + io_sethandler(base, 0x0002, winbond_read_3fx, NULL, NULL, winbond_write_3fx, NULL, NULL, &winbond_global); } diff --git a/src/models/wd76c10.c b/src/models/wd76c10.c index 3fb283bb..47b318d4 100644 --- a/src/models/wd76c10.c +++ b/src/models/wd76c10.c @@ -13,96 +13,116 @@ static uint16_t wd76c10_5872; static uint16_t wd76c10_6072; uint16_t wd76c10_read(uint16_t port, void *priv) { - switch (port) { - case 0x0092:return wd76c10_0092; + switch (port) { + case 0x0092: + return wd76c10_0092; - case 0x2072:return wd76c10_2072; + case 0x2072: + return wd76c10_2072; - case 0x2872:return wd76c10_2872; + case 0x2872: + return wd76c10_2872; - case 0x5872:return wd76c10_5872; + case 0x5872: + return wd76c10_5872; - case 0x6072:return wd76c10_6072; - } - return 0; + case 0x6072: + return wd76c10_6072; + } + return 0; } void wd76c10_write(uint16_t port, uint16_t val, void *priv) { - pclog("WD76C10 write %04X %04X\n", port, val); - switch (port) { - case 0x0092:wd76c10_0092 = val; + pclog("WD76C10 write %04X %04X\n", port, val); + switch (port) { + case 0x0092: + wd76c10_0092 = val; - mem_a20_alt = val & 2; - mem_a20_recalc(); - break; + mem_a20_alt = val & 2; + mem_a20_recalc(); + break; - case 0x2072:wd76c10_2072 = val; + case 0x2072: + wd76c10_2072 = val; - serial1_remove(); - if (!(val & 0x10)) { - switch ((val >> 5) & 7) { - case 1: serial1_set(0x3f8, 4); - break; - case 2: serial1_set(0x2f8, 4); - break; - case 3: serial1_set(0x3e8, 4); - break; - case 4: serial1_set(0x2e8, 4); - break; - default: serial1_remove(); - break; - } - } - serial2_remove(); - if (!(val & 0x01)) { - switch ((val >> 1) & 7) { - case 1: serial2_set(0x3f8, 3); - break; - case 2: serial2_set(0x2f8, 3); - break; - case 3: serial2_set(0x3e8, 3); - break; - case 4: serial2_set(0x2e8, 3); - break; - default: serial2_remove(); - break; - } - } - break; + serial1_remove(); + if (!(val & 0x10)) { + switch ((val >> 5) & 7) { + case 1: + serial1_set(0x3f8, 4); + break; + case 2: + serial1_set(0x2f8, 4); + break; + case 3: + serial1_set(0x3e8, 4); + break; + case 4: + serial1_set(0x2e8, 4); + break; + default: + serial1_remove(); + break; + } + } + serial2_remove(); + if (!(val & 0x01)) { + switch ((val >> 1) & 7) { + case 1: + serial2_set(0x3f8, 3); + break; + case 2: + serial2_set(0x2f8, 3); + break; + case 3: + serial2_set(0x3e8, 3); + break; + case 4: + serial2_set(0x2e8, 3); + break; + default: + serial2_remove(); + break; + } + } + break; - case 0x2872:wd76c10_2872 = val; + case 0x2872: + wd76c10_2872 = val; - fdc_remove(); - if (!(val & 1)) - fdc_add(); - break; + fdc_remove(); + if (!(val & 1)) + fdc_add(); + break; - case 0x5872:wd76c10_5872 = val; - break; + case 0x5872: + wd76c10_5872 = val; + break; - case 0x6072:wd76c10_6072 = val; - break; - } + case 0x6072: + wd76c10_6072 = val; + break; + } } 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; + if (port & 1) + return wd76c10_read(port & ~1, priv) >> 8; + return wd76c10_read(port, priv) & 0xff; } 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); + 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); } void wd76c10_init() { - io_sethandler(0x0092, 0x0002, wd76c10_readb, wd76c10_read, NULL, wd76c10_writeb, wd76c10_write, NULL, NULL); - io_sethandler(0x2072, 0x0002, wd76c10_readb, wd76c10_read, NULL, wd76c10_writeb, wd76c10_write, NULL, NULL); - io_sethandler(0x2872, 0x0002, wd76c10_readb, wd76c10_read, NULL, wd76c10_writeb, wd76c10_write, NULL, NULL); - io_sethandler(0x5872, 0x0002, wd76c10_readb, wd76c10_read, NULL, wd76c10_writeb, wd76c10_write, NULL, NULL); - io_sethandler(0x6072, 0x0002, wd76c10_readb, wd76c10_read, NULL, wd76c10_writeb, wd76c10_write, NULL, NULL); + io_sethandler(0x0092, 0x0002, wd76c10_readb, wd76c10_read, NULL, wd76c10_writeb, wd76c10_write, NULL, NULL); + io_sethandler(0x2072, 0x0002, wd76c10_readb, wd76c10_read, NULL, wd76c10_writeb, wd76c10_write, NULL, NULL); + io_sethandler(0x2872, 0x0002, wd76c10_readb, wd76c10_read, NULL, wd76c10_writeb, wd76c10_write, NULL, NULL); + io_sethandler(0x5872, 0x0002, wd76c10_readb, wd76c10_read, NULL, wd76c10_writeb, wd76c10_write, NULL, NULL); + io_sethandler(0x6072, 0x0002, wd76c10_readb, wd76c10_read, NULL, wd76c10_writeb, wd76c10_write, NULL, NULL); } diff --git a/src/models/xi8088.c b/src/models/xi8088.c index 9f01024a..e063164f 100644 --- a/src/models/xi8088.c +++ b/src/models/xi8088.c @@ -6,130 +6,59 @@ #include "xi8088.h" typedef struct xi8088_t { - uint8_t turbo; + uint8_t turbo; - int turbo_setting; - int bios_128kb; + int turbo_setting; + int bios_128kb; } xi8088_t; static xi8088_t xi8088; -uint8_t xi8088_turbo_get() { - return xi8088.turbo; -} +uint8_t xi8088_turbo_get() { return xi8088.turbo; } void xi8088_turbo_set(uint8_t value) { - if (!xi8088.turbo_setting) - return; + if (!xi8088.turbo_setting) + return; - xi8088.turbo = value; - if (!value) { -// pclog("Xi8088 turbo off\n"); - cpu_set_turbo(0); - } else { -// pclog("Xi8088 turbo on\n"); - cpu_set_turbo(1); - } + xi8088.turbo = value; + if (!value) { + // pclog("Xi8088 turbo off\n"); + cpu_set_turbo(0); + } else { + // pclog("Xi8088 turbo on\n"); + cpu_set_turbo(1); + } } -int xi8088_bios_128kb() { - return xi8088.bios_128kb; -} +int xi8088_bios_128kb() { return xi8088.bios_128kb; } static void *xi8088_init() { - xi8088.turbo = 1; - xi8088.turbo_setting = device_get_config_int("turbo_setting"); - xi8088.bios_128kb = device_get_config_int("bios_128kb"); + xi8088.turbo = 1; + xi8088.turbo_setting = device_get_config_int("turbo_setting"); + xi8088.bios_128kb = device_get_config_int("bios_128kb"); - return &xi8088; + return &xi8088; } -static device_config_t xi8088_config[] = - { - { - .name = "turbo_setting", - .description = "Turbo", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "Always at selected speed", - .value = 0 - }, - { - .description = "BIOS setting + Hotkeys (off during POST)", - .value = 1 - } - }, - .default_int = 0 - }, - { - .name = "bios_128kb", - .description = "BIOS size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "64KB starting from 0xF0000", - .value = 0 - }, - { - .description = "128KB starting from 0xE0000 (address MSB inverted, last 64KB first)", - .value = 1 - } - }, - .default_int = 1 - }, - { - .name = "umb_c0000h_c7fff", - .description = "Map 0xc0000-0xc7fff as UMB", - .type = CONFIG_BINARY, - .default_int = 0 - }, - { - .name = "umb_c8000h_cffff", - .description = "Map 0xc8000-0xcffff as UMB", - .type = CONFIG_BINARY, - .default_int = 0 - }, - { - .name = "umb_d0000h_d7fff", - .description = "Map 0xd0000-0xd7fff as UMB", - .type = CONFIG_BINARY, - .default_int = 0 - }, - { - .name = "umb_d8000h_dffff", - .description = "Map 0xd8000-0xdffff as UMB", - .type = CONFIG_BINARY, - .default_int = 0 - }, - { - .name = "umb_e0000h_e7fff", - .description = "Map 0xe0000-0xe7fff as UMB", - .type = CONFIG_BINARY, - .default_int = 0 - }, - { - .name = "umb_e8000h_effff", - .description = "Map 0xe8000-0xeffff as UMB", - .type = CONFIG_BINARY, - .default_int = 0 - }, - { - .type = -1 - } - }; +static device_config_t xi8088_config[] = { + {.name = "turbo_setting", + .description = "Turbo", + .type = CONFIG_SELECTION, + .selection = {{.description = "Always at selected speed", .value = 0}, + {.description = "BIOS setting + Hotkeys (off during POST)", .value = 1}}, + .default_int = 0}, + {.name = "bios_128kb", + .description = "BIOS size", + .type = CONFIG_SELECTION, + .selection = {{.description = "64KB starting from 0xF0000", .value = 0}, + {.description = "128KB starting from 0xE0000 (address MSB inverted, last 64KB first)", .value = 1}}, + .default_int = 1}, + {.name = "umb_c0000h_c7fff", .description = "Map 0xc0000-0xc7fff as UMB", .type = CONFIG_BINARY, .default_int = 0}, + {.name = "umb_c8000h_cffff", .description = "Map 0xc8000-0xcffff as UMB", .type = CONFIG_BINARY, .default_int = 0}, + {.name = "umb_d0000h_d7fff", .description = "Map 0xd0000-0xd7fff as UMB", .type = CONFIG_BINARY, .default_int = 0}, + {.name = "umb_d8000h_dffff", .description = "Map 0xd8000-0xdffff as UMB", .type = CONFIG_BINARY, .default_int = 0}, + {.name = "umb_e0000h_e7fff", .description = "Map 0xe0000-0xe7fff as UMB", .type = CONFIG_BINARY, .default_int = 0}, + {.name = "umb_e8000h_effff", .description = "Map 0xe8000-0xeffff as UMB", .type = CONFIG_BINARY, .default_int = 0}, + {.type = -1}}; -device_t xi8088_device = - { - "Xi8088", - 0, - xi8088_init, - NULL, - NULL, - NULL, - NULL, - NULL, - xi8088_config - }; +device_t xi8088_device = {"Xi8088", 0, xi8088_init, NULL, NULL, NULL, NULL, NULL, xi8088_config}; diff --git a/src/models/zenith.c b/src/models/zenith.c index d424f0fb..db184189 100644 --- a/src/models/zenith.c +++ b/src/models/zenith.c @@ -7,40 +7,22 @@ static uint8_t *zenith_scratchpad_ram; static mem_mapping_t zenith_scratchpad_mapping; -static uint8_t zenith_scratchpad_read(uint32_t addr, void *p) { - return zenith_scratchpad_ram[addr & 0x3fff]; -} -static void zenith_scratchpad_write(uint32_t addr, uint8_t val, void *p) { - zenith_scratchpad_ram[addr & 0x3fff] = val; -} +static uint8_t zenith_scratchpad_read(uint32_t addr, void *p) { return zenith_scratchpad_ram[addr & 0x3fff]; } +static void zenith_scratchpad_write(uint32_t addr, uint8_t val, void *p) { zenith_scratchpad_ram[addr & 0x3fff] = val; } static void *zenith_scratchpad_init() { - zenith_scratchpad_ram = malloc(0x4000); + zenith_scratchpad_ram = malloc(0x4000); - mem_mapping_disable(&bios_mapping[4]); - mem_mapping_disable(&bios_mapping[5]); + mem_mapping_disable(&bios_mapping[4]); + mem_mapping_disable(&bios_mapping[5]); - mem_mapping_add(&zenith_scratchpad_mapping, 0xf0000, 0x4000, - zenith_scratchpad_read, NULL, NULL, - zenith_scratchpad_write, NULL, NULL, - zenith_scratchpad_ram, MEM_MAPPING_EXTERNAL, NULL); + mem_mapping_add(&zenith_scratchpad_mapping, 0xf0000, 0x4000, zenith_scratchpad_read, NULL, NULL, zenith_scratchpad_write, + NULL, NULL, zenith_scratchpad_ram, MEM_MAPPING_EXTERNAL, NULL); - return zenith_scratchpad_ram; + return zenith_scratchpad_ram; } -static void zenith_scratchpad_close(void *p) { - free(p); -} +static void zenith_scratchpad_close(void *p) { free(p); } -device_t zenith_scratchpad_device = - { - "Zenith scratchpad RAM", - 0, - zenith_scratchpad_init, - zenith_scratchpad_close, - NULL, - NULL, - NULL, - NULL, - NULL - }; +device_t zenith_scratchpad_device = { + "Zenith scratchpad RAM", 0, zenith_scratchpad_init, zenith_scratchpad_close, NULL, NULL, NULL, NULL, NULL}; diff --git a/src/mouse/mouse.c b/src/mouse/mouse.c index 2dad216d..80a756e0 100644 --- a/src/mouse/mouse.c +++ b/src/mouse/mouse.c @@ -6,42 +6,37 @@ #include "mouse_serial.h" #include "keyboard_olim24.h" -static mouse_t *mouse_list[] = - { - &mouse_serial_microsoft, - &mouse_serial_msystems, - &mouse_ps2_2_button, - &mouse_intellimouse, - &mouse_amstrad, - &mouse_olim24, - NULL - }; +static mouse_t *mouse_list[] = {&mouse_serial_microsoft, + &mouse_serial_msystems, + &mouse_ps2_2_button, + &mouse_intellimouse, + &mouse_amstrad, + &mouse_olim24, + NULL}; static mouse_t *cur_mouse; static void *mouse_p; int mouse_type = 0; void mouse_emu_init() { - cur_mouse = mouse_list[mouse_type]; - mouse_p = cur_mouse->init(); + cur_mouse = mouse_list[mouse_type]; + mouse_p = cur_mouse->init(); } void mouse_emu_close() { - if (cur_mouse) - cur_mouse->close(mouse_p); - cur_mouse = NULL; + if (cur_mouse) + cur_mouse->close(mouse_p); + cur_mouse = NULL; } void mouse_poll(int x, int y, int z, int b) { - if (cur_mouse) - cur_mouse->poll(x, y, z, b, mouse_p); + if (cur_mouse) + cur_mouse->poll(x, y, z, b, mouse_p); } char *mouse_get_name(int mouse) { - if (!mouse_list[mouse]) - return NULL; - return mouse_list[mouse]->name; -} -int mouse_get_type(int mouse) { - return mouse_list[mouse]->type; + if (!mouse_list[mouse]) + return NULL; + return mouse_list[mouse]->name; } +int mouse_get_type(int mouse) { return mouse_list[mouse]->type; } diff --git a/src/mouse/mouse_msystems.c b/src/mouse/mouse_msystems.c index c4b65489..e13d371d 100644 --- a/src/mouse/mouse_msystems.c +++ b/src/mouse/mouse_msystems.c @@ -6,78 +6,72 @@ #include "timer.h" typedef struct mouse_msystems_t { - int mousepos, mousedelay; - int oldb; - SERIAL *serial; + int mousepos, mousedelay; + int oldb; + SERIAL *serial; } mouse_msystems_t; static void mouse_msystems_poll(int x, int y, int z, int b, void *p) { - mouse_msystems_t *mouse = (mouse_msystems_t *)p; - SERIAL *serial = mouse->serial; - uint8_t mousedat[5]; + mouse_msystems_t *mouse = (mouse_msystems_t *)p; + SERIAL *serial = mouse->serial; + uint8_t mousedat[5]; - if (!x && !y && b == mouse->oldb) - return; + if (!x && !y && b == mouse->oldb) + return; - mouse->oldb = b; - y = -y; - if (x > 127) - x = 127; - if (y > 127) - y = 127; - if (x < -128) - x = -128; - if (y < -128) - y = -128; + mouse->oldb = b; + y = -y; + if (x > 127) + x = 127; + if (y > 127) + y = 127; + if (x < -128) + x = -128; + if (y < -128) + y = -128; - /*Use Mouse Systems format*/ - mousedat[0] = 0x87; - if (b & 1) - mousedat[0] &= ~0x04; - if (b & 2) - mousedat[0] &= ~0x01; - if (b & 4) - mousedat[0] &= ~0x02; + /*Use Mouse Systems format*/ + mousedat[0] = 0x87; + if (b & 1) + mousedat[0] &= ~0x04; + if (b & 2) + mousedat[0] &= ~0x01; + if (b & 4) + mousedat[0] &= ~0x02; - mousedat[1] = x; - mousedat[2] = y; - mousedat[3] = 0; - mousedat[4] = 0; + mousedat[1] = x; + mousedat[2] = y; + mousedat[3] = 0; + mousedat[4] = 0; - if (!(serial->mctrl & 0x10)) { -// pclog("Serial data %02X %02X %02X\n", mousedat[0], mousedat[1], mousedat[2]); - serial_write_fifo(mouse->serial, mousedat[0]); - serial_write_fifo(mouse->serial, mousedat[1]); - serial_write_fifo(mouse->serial, mousedat[2]); - serial_write_fifo(mouse->serial, mousedat[3]); - serial_write_fifo(mouse->serial, mousedat[4]); - } + if (!(serial->mctrl & 0x10)) { + // pclog("Serial data %02X %02X %02X\n", mousedat[0], mousedat[1], mousedat[2]); + serial_write_fifo(mouse->serial, mousedat[0]); + serial_write_fifo(mouse->serial, mousedat[1]); + serial_write_fifo(mouse->serial, mousedat[2]); + serial_write_fifo(mouse->serial, mousedat[3]); + serial_write_fifo(mouse->serial, mousedat[4]); + } } static void *mouse_msystems_init() { - mouse_msystems_t *mouse = (mouse_msystems_t *)malloc(sizeof(mouse_msystems_t)); - memset(mouse, 0, sizeof(mouse_msystems_t)); + mouse_msystems_t *mouse = (mouse_msystems_t *)malloc(sizeof(mouse_msystems_t)); + memset(mouse, 0, sizeof(mouse_msystems_t)); - mouse->serial = &serial1; - serial1.rcr_callback = NULL; - serial1.rcr_callback_p = NULL; + mouse->serial = &serial1; + serial1.rcr_callback = NULL; + serial1.rcr_callback_p = NULL; - return mouse; + return mouse; } static void mouse_msystems_close(void *p) { - mouse_msystems_t *mouse = (mouse_msystems_t *)p; + mouse_msystems_t *mouse = (mouse_msystems_t *)p; - free(mouse); + free(mouse); - serial1.rcr_callback = NULL; + serial1.rcr_callback = NULL; } -mouse_t mouse_serial_msystems = - { - "Mouse Systems 3-button mouse (serial)", - mouse_msystems_init, - mouse_msystems_close, - mouse_msystems_poll, - MOUSE_TYPE_SERIAL | MOUSE_TYPE_3BUTTON - }; +mouse_t mouse_serial_msystems = {"Mouse Systems 3-button mouse (serial)", mouse_msystems_init, mouse_msystems_close, + mouse_msystems_poll, MOUSE_TYPE_SERIAL | MOUSE_TYPE_3BUTTON}; diff --git a/src/mouse/mouse_ps2.c b/src/mouse/mouse_ps2.c index 71e6aa72..c1b32acb 100644 --- a/src/mouse/mouse_ps2.c +++ b/src/mouse/mouse_ps2.c @@ -9,258 +9,240 @@ int mouse_scan = 0; -enum { - MOUSE_STREAM, - MOUSE_REMOTE, - MOUSE_ECHO -}; +enum { MOUSE_STREAM, MOUSE_REMOTE, MOUSE_ECHO }; #define MOUSE_ENABLE 0x20 -#define MOUSE_SCALE 0x10 +#define MOUSE_SCALE 0x10 typedef struct mouse_ps2_t { - int mode; + int mode; - uint8_t flags; - uint8_t resolution; - uint8_t sample_rate; + uint8_t flags; + uint8_t resolution; + uint8_t sample_rate; - uint8_t command; + uint8_t command; - int cd; + int cd; - int x, y, z, b; + int x, y, z, b; - int is_intellimouse; - int intellimouse_mode; + int is_intellimouse; + int intellimouse_mode; - uint8_t last_data[6]; + uint8_t last_data[6]; } mouse_ps2_t; void mouse_ps2_write(uint8_t val, void *p) { - mouse_ps2_t *mouse = (mouse_ps2_t *)p; + mouse_ps2_t *mouse = (mouse_ps2_t *)p; - if (mouse->cd) { - mouse->cd = 0; - switch (mouse->command) { - case 0xe8: /*Set mouse resolution*/ - mouse->resolution = val; - keyboard_at_adddata_mouse(0xfa); - break; + if (mouse->cd) { + mouse->cd = 0; + switch (mouse->command) { + case 0xe8: /*Set mouse resolution*/ + mouse->resolution = val; + keyboard_at_adddata_mouse(0xfa); + break; - case 0xf3: /*Set sample rate*/ - mouse->sample_rate = val; - keyboard_at_adddata_mouse(0xfa); - break; + case 0xf3: /*Set sample rate*/ + mouse->sample_rate = val; + keyboard_at_adddata_mouse(0xfa); + break; -// default: -// fatal("mouse_ps2 : Bad data write %02X for command %02X\n", val, mouse->command); - } - } else { - uint8_t temp; + // default: + // fatal("mouse_ps2 : Bad data write %02X for command %02X\n", val, + // mouse->command); + } + } else { + uint8_t temp; - mouse->command = val; - switch (mouse->command) { - case 0xe6: /*Set scaling to 1:1*/ - mouse->flags &= ~MOUSE_SCALE; - keyboard_at_adddata_mouse(0xfa); - break; + mouse->command = val; + switch (mouse->command) { + case 0xe6: /*Set scaling to 1:1*/ + mouse->flags &= ~MOUSE_SCALE; + keyboard_at_adddata_mouse(0xfa); + break; - case 0xe7: /*Set scaling to 2:1*/ - mouse->flags |= MOUSE_SCALE; - keyboard_at_adddata_mouse(0xfa); - break; + case 0xe7: /*Set scaling to 2:1*/ + mouse->flags |= MOUSE_SCALE; + keyboard_at_adddata_mouse(0xfa); + break; - case 0xe8: /*Set mouse resolution*/ - mouse->cd = 1; - keyboard_at_adddata_mouse(0xfa); - break; + case 0xe8: /*Set mouse resolution*/ + mouse->cd = 1; + keyboard_at_adddata_mouse(0xfa); + break; - case 0xe9: /*Status request*/ - keyboard_at_adddata_mouse(0xfa); - temp = mouse->flags; - if (mouse_buttons & 1) - temp |= 1; - if (mouse_buttons & 2) - temp |= 2; - if (mouse_buttons & 4) - temp |= 3; - keyboard_at_adddata_mouse(temp); - keyboard_at_adddata_mouse(mouse->resolution); - keyboard_at_adddata_mouse(mouse->sample_rate); - break; + case 0xe9: /*Status request*/ + keyboard_at_adddata_mouse(0xfa); + temp = mouse->flags; + if (mouse_buttons & 1) + temp |= 1; + if (mouse_buttons & 2) + temp |= 2; + if (mouse_buttons & 4) + temp |= 3; + keyboard_at_adddata_mouse(temp); + keyboard_at_adddata_mouse(mouse->resolution); + keyboard_at_adddata_mouse(mouse->sample_rate); + break; - case 0xeb: /*Get mouse data*/ - keyboard_at_adddata_mouse(0xfa); + case 0xeb: /*Get mouse data*/ + keyboard_at_adddata_mouse(0xfa); - temp = 0; - if (mouse->x < 0) - temp |= 0x10; - if (mouse->y < 0) - temp |= 0x20; - if (mouse_buttons & 1) - temp |= 1; - if (mouse_buttons & 2) - temp |= 2; - if ((mouse_buttons & 4) && (mouse_get_type(mouse_type) & MOUSE_TYPE_3BUTTON)) - temp |= 4; - keyboard_at_adddata_mouse(temp); - keyboard_at_adddata_mouse(mouse->x & 0xff); - keyboard_at_adddata_mouse(mouse->y & 0xff); - if (mouse->intellimouse_mode) - keyboard_at_adddata_mouse(mouse->z); - break; + temp = 0; + if (mouse->x < 0) + temp |= 0x10; + if (mouse->y < 0) + temp |= 0x20; + if (mouse_buttons & 1) + temp |= 1; + if (mouse_buttons & 2) + temp |= 2; + if ((mouse_buttons & 4) && (mouse_get_type(mouse_type) & MOUSE_TYPE_3BUTTON)) + temp |= 4; + keyboard_at_adddata_mouse(temp); + keyboard_at_adddata_mouse(mouse->x & 0xff); + keyboard_at_adddata_mouse(mouse->y & 0xff); + if (mouse->intellimouse_mode) + keyboard_at_adddata_mouse(mouse->z); + break; - case 0xf2: /*Read ID*/ - keyboard_at_adddata_mouse(0xfa); - if (mouse->intellimouse_mode) - keyboard_at_adddata_mouse(0x03); - else - keyboard_at_adddata_mouse(0x00); - break; + case 0xf2: /*Read ID*/ + keyboard_at_adddata_mouse(0xfa); + if (mouse->intellimouse_mode) + keyboard_at_adddata_mouse(0x03); + else + keyboard_at_adddata_mouse(0x00); + break; - case 0xf3: /*Set sample rate*/ - mouse->cd = 1; - keyboard_at_adddata_mouse(0xfa); - break; + case 0xf3: /*Set sample rate*/ + mouse->cd = 1; + keyboard_at_adddata_mouse(0xfa); + break; - case 0xf4: /*Enable*/ - mouse->flags |= MOUSE_ENABLE; - keyboard_at_adddata_mouse(0xfa); - break; + case 0xf4: /*Enable*/ + mouse->flags |= MOUSE_ENABLE; + keyboard_at_adddata_mouse(0xfa); + break; - case 0xf5: /*Disable*/ - mouse->flags &= ~MOUSE_ENABLE; - keyboard_at_adddata_mouse(0xfa); - break; + case 0xf5: /*Disable*/ + mouse->flags &= ~MOUSE_ENABLE; + keyboard_at_adddata_mouse(0xfa); + break; - case 0xff: /*Reset*/ - mouse->mode = MOUSE_STREAM; - mouse->flags = 0; - mouse->intellimouse_mode = 0; - mouse_queue_start = mouse_queue_end = 0; - keyboard_at_adddata_mouse(0xfa); - keyboard_at_adddata_mouse(0xaa); - keyboard_at_adddata_mouse(0x00); - break; + case 0xff: /*Reset*/ + mouse->mode = MOUSE_STREAM; + mouse->flags = 0; + mouse->intellimouse_mode = 0; + mouse_queue_start = mouse_queue_end = 0; + keyboard_at_adddata_mouse(0xfa); + keyboard_at_adddata_mouse(0xaa); + keyboard_at_adddata_mouse(0x00); + break; -// default: -// fatal("mouse_ps2 : Bad command %02X\n", val, mouse->command); - } - } + // default: + // fatal("mouse_ps2 : Bad command %02X\n", val, mouse->command); + } + } - if (mouse->is_intellimouse) { - int c; + if (mouse->is_intellimouse) { + int c; - for (c = 0; c < 5; c++) - mouse->last_data[c] = mouse->last_data[c + 1]; + for (c = 0; c < 5; c++) + mouse->last_data[c] = mouse->last_data[c + 1]; - mouse->last_data[5] = val; + mouse->last_data[5] = val; - if (mouse->last_data[0] == 0xf3 && mouse->last_data[1] == 0xc8 && - mouse->last_data[2] == 0xf3 && mouse->last_data[3] == 0x64 && - mouse->last_data[4] == 0xf3 && mouse->last_data[5] == 0x50) - mouse->intellimouse_mode = 1; - } + if (mouse->last_data[0] == 0xf3 && mouse->last_data[1] == 0xc8 && mouse->last_data[2] == 0xf3 && + mouse->last_data[3] == 0x64 && mouse->last_data[4] == 0xf3 && mouse->last_data[5] == 0x50) + mouse->intellimouse_mode = 1; + } } void mouse_ps2_poll(int x, int y, int z, int b, void *p) { - mouse_ps2_t *mouse = (mouse_ps2_t *)p; - uint8_t packet[3] = {0x08, 0, 0}; + mouse_ps2_t *mouse = (mouse_ps2_t *)p; + uint8_t packet[3] = {0x08, 0, 0}; - if (!x && !y && !z && b == mouse->b) - return; + if (!x && !y && !z && b == mouse->b) + return; - if (!mouse_scan) - return; + if (!mouse_scan) + return; - mouse->x += x; - mouse->y -= y; - mouse->z -= z; - if (mouse->mode == MOUSE_STREAM && (mouse->flags & MOUSE_ENABLE) && - ((mouse_queue_end - mouse_queue_start) & 0xf) < 13) { - mouse->b = b; - // pclog("Send packet : %i %i\n", ps2_x, ps2_y); - if (mouse->x > 255) - mouse->x = 255; - if (mouse->x < -256) - mouse->x = -256; - if (mouse->y > 255) - mouse->y = 255; - if (mouse->y < -256) - mouse->y = -256; - if (mouse->z < -8) - mouse->z = -8; - if (mouse->z > 7) - mouse->z = 7; - if (mouse->x < 0) - packet[0] |= 0x10; - if (mouse->y < 0) - packet[0] |= 0x20; - if (mouse_buttons & 1) - packet[0] |= 1; - if (mouse_buttons & 2) - packet[0] |= 2; - if ((mouse_buttons & 4) && (mouse_get_type(mouse_type) & MOUSE_TYPE_3BUTTON)) - packet[0] |= 4; - packet[1] = mouse->x & 0xff; - packet[2] = mouse->y & 0xff; + mouse->x += x; + mouse->y -= y; + mouse->z -= z; + if (mouse->mode == MOUSE_STREAM && (mouse->flags & MOUSE_ENABLE) && ((mouse_queue_end - mouse_queue_start) & 0xf) < 13) { + mouse->b = b; + // pclog("Send packet : %i %i\n", ps2_x, ps2_y); + if (mouse->x > 255) + mouse->x = 255; + if (mouse->x < -256) + mouse->x = -256; + if (mouse->y > 255) + mouse->y = 255; + if (mouse->y < -256) + mouse->y = -256; + if (mouse->z < -8) + mouse->z = -8; + if (mouse->z > 7) + mouse->z = 7; + if (mouse->x < 0) + packet[0] |= 0x10; + if (mouse->y < 0) + packet[0] |= 0x20; + if (mouse_buttons & 1) + packet[0] |= 1; + if (mouse_buttons & 2) + packet[0] |= 2; + if ((mouse_buttons & 4) && (mouse_get_type(mouse_type) & MOUSE_TYPE_3BUTTON)) + packet[0] |= 4; + packet[1] = mouse->x & 0xff; + packet[2] = mouse->y & 0xff; - keyboard_at_adddata_mouse(packet[0]); - keyboard_at_adddata_mouse(packet[1]); - keyboard_at_adddata_mouse(packet[2]); - if (mouse->intellimouse_mode) - keyboard_at_adddata_mouse(mouse->z); + keyboard_at_adddata_mouse(packet[0]); + keyboard_at_adddata_mouse(packet[1]); + keyboard_at_adddata_mouse(packet[2]); + if (mouse->intellimouse_mode) + keyboard_at_adddata_mouse(mouse->z); - mouse->x = mouse->y = mouse->z = 0; - } + mouse->x = mouse->y = mouse->z = 0; + } } void *mouse_ps2_init() { - mouse_ps2_t *mouse = (mouse_ps2_t *)malloc(sizeof(mouse_ps2_t)); - memset(mouse, 0, sizeof(mouse_ps2_t)); + mouse_ps2_t *mouse = (mouse_ps2_t *)malloc(sizeof(mouse_ps2_t)); + memset(mouse, 0, sizeof(mouse_ps2_t)); -// mouse_poll = mouse_ps2_poll; -// mouse_write = mouse_ps2_write; - mouse->cd = 0; - mouse->flags = 0; - mouse->mode = MOUSE_STREAM; + // mouse_poll = mouse_ps2_poll; + // mouse_write = mouse_ps2_write; + mouse->cd = 0; + mouse->flags = 0; + mouse->mode = MOUSE_STREAM; - if (romset == ROM_PC5086) - upc_set_mouse(mouse_ps2_write, mouse); - else - keyboard_at_set_mouse(mouse_ps2_write, mouse); + if (romset == ROM_PC5086) + upc_set_mouse(mouse_ps2_write, mouse); + else + keyboard_at_set_mouse(mouse_ps2_write, mouse); - return mouse; + return mouse; } void *mouse_intellimouse_init() { - mouse_ps2_t *mouse = mouse_ps2_init(); + mouse_ps2_t *mouse = mouse_ps2_init(); - mouse->is_intellimouse = 1; + mouse->is_intellimouse = 1; - return mouse; + return mouse; } void mouse_ps2_close(void *p) { - mouse_ps2_t *mouse = (mouse_ps2_t *)p; + mouse_ps2_t *mouse = (mouse_ps2_t *)p; - free(mouse); + free(mouse); } -mouse_t mouse_ps2_2_button = - { - "2-button mouse (PS/2)", - mouse_ps2_init, - mouse_ps2_close, - mouse_ps2_poll, - MOUSE_TYPE_PS2 - }; -mouse_t mouse_intellimouse = - { - "Microsoft Intellimouse (PS/2)", - mouse_intellimouse_init, - mouse_ps2_close, - mouse_ps2_poll, - MOUSE_TYPE_PS2 | MOUSE_TYPE_3BUTTON - }; +mouse_t mouse_ps2_2_button = {"2-button mouse (PS/2)", mouse_ps2_init, mouse_ps2_close, mouse_ps2_poll, MOUSE_TYPE_PS2}; +mouse_t mouse_intellimouse = {"Microsoft Intellimouse (PS/2)", mouse_intellimouse_init, mouse_ps2_close, mouse_ps2_poll, + MOUSE_TYPE_PS2 | MOUSE_TYPE_3BUTTON}; diff --git a/src/mouse/mouse_serial.c b/src/mouse/mouse_serial.c index 44935f80..413f6182 100644 --- a/src/mouse/mouse_serial.c +++ b/src/mouse/mouse_serial.c @@ -6,92 +6,86 @@ #include "timer.h" typedef struct mouse_serial_t { - int mousepos; - pc_timer_t mousedelay_timer; - int oldb; - SERIAL *serial; + int mousepos; + pc_timer_t mousedelay_timer; + int oldb; + SERIAL *serial; } mouse_serial_t; void mouse_serial_poll(int x, int y, int z, int b, void *p) { - mouse_serial_t *mouse = (mouse_serial_t *)p; - SERIAL *serial = mouse->serial; - uint8_t mousedat[3]; + mouse_serial_t *mouse = (mouse_serial_t *)p; + SERIAL *serial = mouse->serial; + uint8_t mousedat[3]; - if (!(serial->ier & 1)) - return; - if (!x && !y && b == mouse->oldb) - return; + if (!(serial->ier & 1)) + return; + if (!x && !y && b == mouse->oldb) + return; - mouse->oldb = b; - if (x > 127) - x = 127; - if (y > 127) - y = 127; - if (x < -128) - x = -128; - if (y < -128) - y = -128; + mouse->oldb = b; + if (x > 127) + x = 127; + if (y > 127) + y = 127; + if (x < -128) + x = -128; + if (y < -128) + y = -128; - /*Use Microsoft format*/ - mousedat[0] = 0x40; - mousedat[0] |= (((y >> 6) & 3) << 2); - mousedat[0] |= ((x >> 6) & 3); - if (b & 1) - mousedat[0] |= 0x20; - if (b & 2) - mousedat[0] |= 0x10; - mousedat[1] = x & 0x3F; - mousedat[2] = y & 0x3F; + /*Use Microsoft format*/ + mousedat[0] = 0x40; + mousedat[0] |= (((y >> 6) & 3) << 2); + mousedat[0] |= ((x >> 6) & 3); + if (b & 1) + mousedat[0] |= 0x20; + if (b & 2) + mousedat[0] |= 0x10; + mousedat[1] = x & 0x3F; + mousedat[2] = y & 0x3F; - if (!(serial->mctrl & 0x10)) { -// pclog("Serial data %02X %02X %02X\n", mousedat[0], mousedat[1], mousedat[2]); - serial_write_fifo(mouse->serial, mousedat[0]); - serial_write_fifo(mouse->serial, mousedat[1]); - serial_write_fifo(mouse->serial, mousedat[2]); - } + if (!(serial->mctrl & 0x10)) { + // pclog("Serial data %02X %02X %02X\n", mousedat[0], mousedat[1], mousedat[2]); + serial_write_fifo(mouse->serial, mousedat[0]); + serial_write_fifo(mouse->serial, mousedat[1]); + serial_write_fifo(mouse->serial, mousedat[2]); + } } void mouse_serial_rcr(struct SERIAL *serial, void *p) { - mouse_serial_t *mouse = (mouse_serial_t *)p; + mouse_serial_t *mouse = (mouse_serial_t *)p; - mouse->mousepos = -1; - timer_set_delay_u64(&mouse->mousedelay_timer, TIMER_USEC * 5000); + mouse->mousepos = -1; + timer_set_delay_u64(&mouse->mousedelay_timer, TIMER_USEC * 5000); } void mousecallback(void *p) { - mouse_serial_t *mouse = (mouse_serial_t *)p; + mouse_serial_t *mouse = (mouse_serial_t *)p; - if (mouse->mousepos == -1) { - mouse->mousepos = 0; - serial_write_fifo(mouse->serial, 'M'); - } + if (mouse->mousepos == -1) { + mouse->mousepos = 0; + serial_write_fifo(mouse->serial, 'M'); + } } void *mouse_serial_init() { - mouse_serial_t *mouse = (mouse_serial_t *)malloc(sizeof(mouse_serial_t)); - memset(mouse, 0, sizeof(mouse_serial_t)); + mouse_serial_t *mouse = (mouse_serial_t *)malloc(sizeof(mouse_serial_t)); + memset(mouse, 0, sizeof(mouse_serial_t)); - mouse->serial = &serial1; - serial1.rcr_callback = mouse_serial_rcr; - serial1.rcr_callback_p = mouse; - timer_add(&mouse->mousedelay_timer, mousecallback, mouse, 0); + mouse->serial = &serial1; + serial1.rcr_callback = mouse_serial_rcr; + serial1.rcr_callback_p = mouse; + timer_add(&mouse->mousedelay_timer, mousecallback, mouse, 0); - return mouse; + return mouse; } void mouse_serial_close(void *p) { - mouse_serial_t *mouse = (mouse_serial_t *)p; + mouse_serial_t *mouse = (mouse_serial_t *)p; - free(mouse); + free(mouse); - serial1.rcr_callback = NULL; + serial1.rcr_callback = NULL; } -mouse_t mouse_serial_microsoft = - { - "Microsoft 2-button mouse (serial)", - mouse_serial_init, - mouse_serial_close, - mouse_serial_poll, - MOUSE_TYPE_SERIAL - }; +mouse_t mouse_serial_microsoft = {"Microsoft 2-button mouse (serial)", mouse_serial_init, mouse_serial_close, mouse_serial_poll, + MOUSE_TYPE_SERIAL}; diff --git a/src/networking/ne2000.c b/src/networking/ne2000.c index bf35dd68..9dabadb5 100644 --- a/src/networking/ne2000.c +++ b/src/networking/ne2000.c @@ -53,14 +53,11 @@ /*MAC address*/ uint8_t maclocal[6]; -typedef enum { - NE2000_NE2000, - NE2000_RTL8029AS -} ne2000_type; +typedef enum { NE2000_NE2000, NE2000_RTL8029AS } ne2000_type; #define NE2000_PCI_IRQ -1 -#define NETBLOCKING 0 //we won't block our pcap +#define NETBLOCKING 0 // we won't block our pcap //#define NE2000_DEBUG @@ -71,272 +68,270 @@ pcap_t *net_pcap; queueADT slirpq; int net_slirp_inited = 0; -int net_is_slirp = 1; //by default we go with slirp -int net_is_pcap = 0; //and pretend pcap is dead. +int net_is_slirp = 1; // by default we go with slirp +int net_is_pcap = 0; // and pretend pcap is dead. int fizz = 0; void slirp_tic(); #define BX_RESET_HARDWARE 0 #define BX_RESET_SOFTWARE 1 -//Never completely fill the ne2k ring so that we never +// Never completely fill the ne2k ring so that we never // hit the unclear completely full buffer condition. #define BX_NE2K_NEVER_FULL_RING (1) -#define BX_NE2K_MEMSIZ (32*1024) -#define BX_NE2K_MEMSTART (16*1024) -#define BX_NE2K_MEMEND (BX_NE2K_MEMSTART + BX_NE2K_MEMSIZ) +#define BX_NE2K_MEMSIZ (32 * 1024) +#define BX_NE2K_MEMSTART (16 * 1024) +#define BX_NE2K_MEMEND (BX_NE2K_MEMSTART + BX_NE2K_MEMSIZ) typedef struct ne2000_t { - // - // ne2k register state + // + // ne2k register state - // - // 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 transmitted with no errors - int rx_err; // RXE - packet received with 1 or more errors - int tx_err; // TXE - packet tx'd " " " " " - 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 packets 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; + // + // 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 transmitted with no errors + int rx_err; // RXE - packet received with 1 or more errors + int tx_err; // TXE - packet tx'd " " " " " + 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 packets 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 register - uint8_t page_stop; // 02h write ; page stop register - uint8_t bound_ptr; // 03h read/write ; boundary pointer - uint8_t tx_page_start; // 04h write ; transmit page start register - uint8_t num_coll; // 05h read ; number-of-collisions register - uint16_t tx_bytes; // 05,06h write ; transmit byte-count register - 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 register - uint16_t remote_bytes; // 0a,0bh write ; remote byte-count register - uint8_t tallycnt_0; // 0dh read ; tally counter 0 (frame align errors) - uint8_t tallycnt_1; // 0eh read ; tally counter 1 (CRC errors) - uint8_t tallycnt_2; // 0fh read ; tally counter 2 (missed pkt errors) + uint16_t local_dma; // 01,02h read ; current local DMA addr + uint8_t page_start; // 01h write ; page start register + uint8_t page_stop; // 02h write ; page stop register + uint8_t bound_ptr; // 03h read/write ; boundary pointer + uint8_t tx_page_start; // 04h write ; transmit page start register + uint8_t num_coll; // 05h read ; number-of-collisions register + uint16_t tx_bytes; // 05,06h write ; transmit byte-count register + 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 register + uint16_t remote_bytes; // 0a,0bh write ; remote byte-count register + uint8_t tallycnt_0; // 0dh read ; tally counter 0 (frame align errors) + uint8_t tallycnt_1; // 0eh read ; tally counter 1 (CRC errors) + uint8_t tallycnt_2; // 0fh read ; tally counter 2 (missed pkt errors) - // - // 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 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 ; remote next-packet pointer - uint8_t localpkt_ptr; // 05h read/write ; local next-packet pointer - uint16_t address_cnt; // 06,07h read/write ; address counter + // + // 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 ; remote next-packet pointer + uint8_t localpkt_ptr; // 05h read/write ; local next-packet pointer + uint16_t address_cnt; // 06,07h read/write ; address counter - // - // Page 3 - should never be modified. - // + // + // Page 3 - should never be modified. + // - // Novell ASIC state - uint8_t macaddr[32]; // ASIC ROM'd MAC address, even bytes - uint8_t mem[BX_NE2K_MEMSIZ]; // on-chip packet memory + // Novell ASIC state + uint8_t macaddr[32]; // ASIC ROM'd MAC address, even bytes + uint8_t mem[BX_NE2K_MEMSIZ]; // on-chip packet memory - // ne2k internal state - uint32_t base_address; - int base_irq; - int tx_timer_index; - int tx_timer_active; + // ne2k internal state + uint32_t base_address; + int base_irq; + int tx_timer_index; + int tx_timer_active; - ne2000_type type; + ne2000_type type; - /*PCI stuff*/ - int is_pci; - int card; - uint32_t base_addr; - uint8_t pci_command; - uint8_t int_line; + /*PCI stuff*/ + int is_pci; + int card; + uint32_t base_addr; + uint8_t pci_command; + uint8_t int_line; - /*RTL8029AS registers*/ - uint8_t config0, config2, config3; - uint8_t _9346cr; + /*RTL8029AS registers*/ + uint8_t config0, config2, config3; + uint8_t _9346cr; } ne2000_t; static void ne2000_tx_event(int val, void *p); void ne2000_rx_frame(void *p, const void *buf, int io_len); -static void ne2000_setirq(ne2000_t *ne2000, int irq) { - ne2000->base_irq = irq; -} +static void ne2000_setirq(ne2000_t *ne2000, int irq) { ne2000->base_irq = irq; } static void ne2000_raise_irq(ne2000_t *ne2000) { - if (ne2000->is_pci) - pci_set_irq(ne2000->card, PCI_INTA); - else - picint(1 << ne2000->base_irq); + if (ne2000->is_pci) + pci_set_irq(ne2000->card, PCI_INTA); + else + picint(1 << ne2000->base_irq); } static void ne2000_lower_irq(ne2000_t *ne2000) { - if (ne2000->is_pci) - pci_clear_irq(ne2000->card, PCI_INTA); - else - picintc(1 << ne2000->base_irq); + if (ne2000->is_pci) + pci_clear_irq(ne2000->card, PCI_INTA); + else + picintc(1 << ne2000->base_irq); } // // reset - restore state to power-up, cancelling all i/o // static void ne2000_reset(int type, void *p) { - ne2000_t *ne2000 = (ne2000_t *)p; - int i; + ne2000_t *ne2000 = (ne2000_t *)p; + int i; - pclog("ne2000 reset\n"); + pclog("ne2000 reset\n"); - // Initialise the mac address area by doubling the physical address - ne2000->macaddr[0] = ne2000->physaddr[0]; - ne2000->macaddr[1] = ne2000->physaddr[0]; - ne2000->macaddr[2] = ne2000->physaddr[1]; - ne2000->macaddr[3] = ne2000->physaddr[1]; - ne2000->macaddr[4] = ne2000->physaddr[2]; - ne2000->macaddr[5] = ne2000->physaddr[2]; - ne2000->macaddr[6] = ne2000->physaddr[3]; - ne2000->macaddr[7] = ne2000->physaddr[3]; - ne2000->macaddr[8] = ne2000->physaddr[4]; - ne2000->macaddr[9] = ne2000->physaddr[4]; - ne2000->macaddr[10] = ne2000->physaddr[5]; - ne2000->macaddr[11] = ne2000->physaddr[5]; + // Initialise the mac address area by doubling the physical address + ne2000->macaddr[0] = ne2000->physaddr[0]; + ne2000->macaddr[1] = ne2000->physaddr[0]; + ne2000->macaddr[2] = ne2000->physaddr[1]; + ne2000->macaddr[3] = ne2000->physaddr[1]; + ne2000->macaddr[4] = ne2000->physaddr[2]; + ne2000->macaddr[5] = ne2000->physaddr[2]; + ne2000->macaddr[6] = ne2000->physaddr[3]; + ne2000->macaddr[7] = ne2000->physaddr[3]; + ne2000->macaddr[8] = ne2000->physaddr[4]; + ne2000->macaddr[9] = ne2000->physaddr[4]; + ne2000->macaddr[10] = ne2000->physaddr[5]; + ne2000->macaddr[11] = ne2000->physaddr[5]; - // ne2k signature - for (i = 12; i < 32; i++) - ne2000->macaddr[i] = 0x57; + // ne2k signature + for (i = 12; i < 32; i++) + ne2000->macaddr[i] = 0x57; - // Zero out registers and memory - memset(&ne2000->CR, 0, sizeof(ne2000->CR)); - memset(&ne2000->ISR, 0, sizeof(ne2000->ISR)); - memset(&ne2000->IMR, 0, sizeof(ne2000->IMR)); - memset(&ne2000->DCR, 0, sizeof(ne2000->DCR)); - memset(&ne2000->TCR, 0, sizeof(ne2000->TCR)); - memset(&ne2000->TSR, 0, sizeof(ne2000->TSR)); - //memset( & ne2000->RCR, 0, sizeof(ne2000->RCR)); - memset(&ne2000->RSR, 0, sizeof(ne2000->RSR)); - ne2000->tx_timer_active = 0; - ne2000->local_dma = 0; - ne2000->page_start = 0; - ne2000->page_stop = 0; - ne2000->bound_ptr = 0; - ne2000->tx_page_start = 0; - ne2000->num_coll = 0; - ne2000->tx_bytes = 0; - ne2000->fifo = 0; - ne2000->remote_dma = 0; - ne2000->remote_start = 0; - ne2000->remote_bytes = 0; - ne2000->tallycnt_0 = 0; - ne2000->tallycnt_1 = 0; - ne2000->tallycnt_2 = 0; + // Zero out registers and memory + memset(&ne2000->CR, 0, sizeof(ne2000->CR)); + memset(&ne2000->ISR, 0, sizeof(ne2000->ISR)); + memset(&ne2000->IMR, 0, sizeof(ne2000->IMR)); + memset(&ne2000->DCR, 0, sizeof(ne2000->DCR)); + memset(&ne2000->TCR, 0, sizeof(ne2000->TCR)); + memset(&ne2000->TSR, 0, sizeof(ne2000->TSR)); + // memset( & ne2000->RCR, 0, sizeof(ne2000->RCR)); + memset(&ne2000->RSR, 0, sizeof(ne2000->RSR)); + ne2000->tx_timer_active = 0; + ne2000->local_dma = 0; + ne2000->page_start = 0; + ne2000->page_stop = 0; + ne2000->bound_ptr = 0; + ne2000->tx_page_start = 0; + ne2000->num_coll = 0; + ne2000->tx_bytes = 0; + ne2000->fifo = 0; + ne2000->remote_dma = 0; + ne2000->remote_start = 0; + ne2000->remote_bytes = 0; + ne2000->tallycnt_0 = 0; + ne2000->tallycnt_1 = 0; + ne2000->tallycnt_2 = 0; - //memset( & ne2000->physaddr, 0, sizeof(ne2000->physaddr)); - //memset( & ne2000->mchash, 0, sizeof(ne2000->mchash)); - ne2000->curr_page = 0; + // memset( & ne2000->physaddr, 0, sizeof(ne2000->physaddr)); + // memset( & ne2000->mchash, 0, sizeof(ne2000->mchash)); + ne2000->curr_page = 0; - ne2000->rempkt_ptr = 0; - ne2000->localpkt_ptr = 0; - ne2000->address_cnt = 0; + ne2000->rempkt_ptr = 0; + ne2000->localpkt_ptr = 0; + ne2000->address_cnt = 0; - memset(&ne2000->mem, 0, sizeof(ne2000->mem)); + memset(&ne2000->mem, 0, sizeof(ne2000->mem)); - // Set power-up conditions - ne2000->CR.stop = 1; - ne2000->CR.rdma_cmd = 4; - ne2000->ISR.reset = 1; - ne2000->DCR.longaddr = 1; - ne2000_raise_irq(ne2000); - ne2000_lower_irq(ne2000); + // Set power-up conditions + ne2000->CR.stop = 1; + ne2000->CR.rdma_cmd = 4; + ne2000->ISR.reset = 1; + ne2000->DCR.longaddr = 1; + ne2000_raise_irq(ne2000); + ne2000_lower_irq(ne2000); - //DEV_pic_lower_irq(ne2000->base_irq); + // DEV_pic_lower_irq(ne2000->base_irq); } #include "bswap.h" @@ -350,35 +345,35 @@ static void ne2000_reset(int type, void *p) { // and there is 16K of buffer memory starting at 16K // static inline uint8_t ne2000_chipmem_read_b(uint32_t address, ne2000_t *ne2000) { - // ROM'd MAC address - if ((address >= 0) && (address <= 31)) - return ne2000->macaddr[address]; + // ROM'd MAC address + if ((address >= 0) && (address <= 31)) + return ne2000->macaddr[address]; - if ((address >= BX_NE2K_MEMSTART) && (address < BX_NE2K_MEMEND)) - return ne2000->mem[address - BX_NE2K_MEMSTART]; - else - return 0xff; + if ((address >= BX_NE2K_MEMSTART) && (address < BX_NE2K_MEMEND)) + return ne2000->mem[address - BX_NE2K_MEMSTART]; + else + return 0xff; } static inline uint16_t ne2000_chipmem_read_w(uint32_t address, ne2000_t *ne2000) { - // ROM'd MAC address - if ((address >= 0) && (address <= 31)) - return le16_to_cpu(*(uint16_t *)(ne2000->macaddr + address)); + // ROM'd MAC address + if ((address >= 0) && (address <= 31)) + return le16_to_cpu(*(uint16_t *)(ne2000->macaddr + address)); - if ((address >= BX_NE2K_MEMSTART) && (address < BX_NE2K_MEMEND)) - return le16_to_cpu(*(uint16_t *)(ne2000->mem + (address - BX_NE2K_MEMSTART))); - else - return 0xffff; + if ((address >= BX_NE2K_MEMSTART) && (address < BX_NE2K_MEMEND)) + return le16_to_cpu(*(uint16_t *)(ne2000->mem + (address - BX_NE2K_MEMSTART))); + else + return 0xffff; } static inline void ne2000_chipmem_write_b(uint32_t address, uint8_t value, ne2000_t *ne2000) { - if ((address >= BX_NE2K_MEMSTART) && (address < BX_NE2K_MEMEND)) - ne2000->mem[address - BX_NE2K_MEMSTART] = value & 0xff; + if ((address >= BX_NE2K_MEMSTART) && (address < BX_NE2K_MEMEND)) + ne2000->mem[address - BX_NE2K_MEMSTART] = value & 0xff; } static inline void ne2000_chipmem_write_w(uint32_t address, uint16_t value, ne2000_t *ne2000) { - if ((address >= BX_NE2K_MEMSTART) && (address < BX_NE2K_MEMEND)) - *(uint16_t *)(ne2000->mem + (address - BX_NE2K_MEMSTART)) = cpu_to_le16(value); + if ((address >= BX_NE2K_MEMSTART) && (address < BX_NE2K_MEMEND)) + *(uint16_t *)(ne2000->mem + (address - BX_NE2K_MEMSTART)) = cpu_to_le16(value); } // @@ -392,113 +387,112 @@ static inline void ne2000_chipmem_write_w(uint32_t address, uint16_t value, ne20 // the appropriate number of bytes to/from the device. // uint16_t ne2000_dma_read(int io_len, void *p) { - ne2000_t *ne2000 = (ne2000_t *)p; + ne2000_t *ne2000 = (ne2000_t *)p; - // - // 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). - // - ne2000->remote_dma += io_len; - if (ne2000->remote_dma == ne2000->page_stop << 8) - ne2000->remote_dma = ne2000->page_start << 8; + // + // 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). + // + ne2000->remote_dma += io_len; + if (ne2000->remote_dma == ne2000->page_stop << 8) + ne2000->remote_dma = ne2000->page_start << 8; - // keep s.remote_bytes from underflowing - if (ne2000->remote_bytes > 1) - ne2000->remote_bytes -= io_len; - else - ne2000->remote_bytes = 0; + // keep s.remote_bytes from underflowing + if (ne2000->remote_bytes > 1) + ne2000->remote_bytes -= io_len; + else + ne2000->remote_bytes = 0; - // If all bytes have been written, signal remote-DMA complete - if (ne2000->remote_bytes == 0) { - ne2000->ISR.rdma_done = 1; - if (ne2000->IMR.rdma_inte) { - ne2000_raise_irq(ne2000); - } - } + // If all bytes have been written, signal remote-DMA complete + if (ne2000->remote_bytes == 0) { + ne2000->ISR.rdma_done = 1; + if (ne2000->IMR.rdma_inte) { + ne2000_raise_irq(ne2000); + } + } - return 0; + return 0; } uint16_t ne2000_asic_read_w(uint16_t offset, void *p) { - ne2000_t *ne2000 = (ne2000_t *)p; - int retval; + ne2000_t *ne2000 = (ne2000_t *)p; + int retval; - if (ne2000->DCR.wdsize & 0x01) { - /* 16 bit access */ - retval = ne2000_chipmem_read_w(ne2000->remote_dma, ne2000); - ne2000_dma_read(2, ne2000); - } else { - /* 8 bit access */ - retval = ne2000_chipmem_read_b(ne2000->remote_dma, ne2000); - ne2000_dma_read(1, ne2000); - } + if (ne2000->DCR.wdsize & 0x01) { + /* 16 bit access */ + retval = ne2000_chipmem_read_w(ne2000->remote_dma, ne2000); + ne2000_dma_read(2, ne2000); + } else { + /* 8 bit access */ + retval = ne2000_chipmem_read_b(ne2000->remote_dma, ne2000); + ne2000_dma_read(1, ne2000); + } #ifdef NE2000_DEBUG - pclog("asic read val=0x%04x\n", retval); + pclog("asic read val=0x%04x\n", retval); #endif - return retval; + return retval; } void ne2000_dma_write(int io_len, void *p) { - ne2000_t *ne2000 = (ne2000_t *)p; + ne2000_t *ne2000 = (ne2000_t *)p; - // is this right ??? asic_read uses DCR.wordsize - ne2000->remote_dma += io_len; - if (ne2000->remote_dma == ne2000->page_stop << 8) - ne2000->remote_dma = ne2000->page_start << 8; + // is this right ??? asic_read uses DCR.wordsize + ne2000->remote_dma += io_len; + if (ne2000->remote_dma == ne2000->page_stop << 8) + ne2000->remote_dma = ne2000->page_start << 8; - ne2000->remote_bytes -= io_len; - if (ne2000->remote_bytes > BX_NE2K_MEMSIZ) - ne2000->remote_bytes = 0; + ne2000->remote_bytes -= io_len; + if (ne2000->remote_bytes > BX_NE2K_MEMSIZ) + ne2000->remote_bytes = 0; - // If all bytes have been written, signal remote-DMA complete - if (ne2000->remote_bytes == 0) { - ne2000->ISR.rdma_done = 1; - if (ne2000->IMR.rdma_inte) { - ne2000_raise_irq(ne2000); - } - } + // If all bytes have been written, signal remote-DMA complete + if (ne2000->remote_bytes == 0) { + ne2000->ISR.rdma_done = 1; + if (ne2000->IMR.rdma_inte) { + ne2000_raise_irq(ne2000); + } + } } void ne2000_asic_write_w(uint16_t offset, uint16_t value, void *p) { - ne2000_t *ne2000 = (ne2000_t *)p; + ne2000_t *ne2000 = (ne2000_t *)p; #ifdef NE2000_DEBUG - pclog("asic write val=0x%04x\n", value); + pclog("asic write val=0x%04x\n", value); #endif - if (ne2000->remote_bytes == 0) - return; - if (ne2000->DCR.wdsize & 0x01) { - /* 16 bit access */ - ne2000_chipmem_write_w(ne2000->remote_dma, value, ne2000); - ne2000_dma_write(2, ne2000); - } else { - /* 8 bit access */ - ne2000_chipmem_write_b(ne2000->remote_dma, value, ne2000); - ne2000_dma_write(1, ne2000); - } + if (ne2000->remote_bytes == 0) + return; + if (ne2000->DCR.wdsize & 0x01) { + /* 16 bit access */ + ne2000_chipmem_write_w(ne2000->remote_dma, value, ne2000); + ne2000_dma_write(2, ne2000); + } else { + /* 8 bit access */ + ne2000_chipmem_write_b(ne2000->remote_dma, value, ne2000); + ne2000_dma_write(1, ne2000); + } } uint8_t ne2000_asic_read_b(uint16_t offset, void *p) { - if (offset & 1) - return ne2000_asic_read_w(offset & ~1, p) >> 1; - return ne2000_asic_read_w(offset, p) & 0xff; + if (offset & 1) + return ne2000_asic_read_w(offset & ~1, p) >> 1; + return ne2000_asic_read_w(offset, p) & 0xff; } void ne2000_asic_write_b(uint16_t offset, uint8_t value, void *p) { - if (offset & 1) - ne2000_asic_write_w(offset & ~1, value << 8, p); - else - ne2000_asic_write_w(offset, value, p); + if (offset & 1) + ne2000_asic_write_w(offset & ~1, value << 8, p); + else + ne2000_asic_write_w(offset, value, p); } uint8_t ne2000_reset_read(uint16_t offset, void *p) { - ne2000_t *ne2000 = (ne2000_t *)p; - ne2000_reset(BX_RESET_SOFTWARE, ne2000); - return 0; + ne2000_t *ne2000 = (ne2000_t *)p; + ne2000_reset(BX_RESET_SOFTWARE, ne2000); + return 0; } -void ne2000_reset_write(uint16_t offset, uint8_t value, void *p) { -} +void ne2000_reset_write(uint16_t offset, uint8_t value, void *p) {} // // read_handler/read - i/o 'catcher' function called from BOCHS @@ -506,238 +500,210 @@ void ne2000_reset_write(uint16_t offset, uint8_t value, void *p) { // by this ne2000 instance // uint8_t ne2000_read(uint16_t address, void *p) { - ne2000_t *ne2000 = (ne2000_t *)p; - int ret = 0; + ne2000_t *ne2000 = (ne2000_t *)p; + int ret = 0; #ifdef NE2000_DEBUG - pclog("read addr %x\n", address); + pclog("read addr %x\n", address); #endif - address &= 0xf; + address &= 0xf; - if (address == 0x00) { - ret = (((ne2000->CR.pgsel & 0x03) << 6) | - ((ne2000->CR.rdma_cmd & 0x07) << 3) | - (ne2000->CR.tx_packet << 2) | - (ne2000->CR.start << 1) | - (ne2000->CR.stop)); + if (address == 0x00) { + ret = (((ne2000->CR.pgsel & 0x03) << 6) | ((ne2000->CR.rdma_cmd & 0x07) << 3) | (ne2000->CR.tx_packet << 2) | + (ne2000->CR.start << 1) | (ne2000->CR.stop)); #ifdef NE2000_DEBUG - pclog("read CR returns 0x%08x\n", ret); + pclog("read CR returns 0x%08x\n", ret); #endif - } else { - switch (ne2000->CR.pgsel) { - case 0x00: + } else { + switch (ne2000->CR.pgsel) { + case 0x00: #ifdef NE2000_DEBUG - pclog("page 0 read from port %04x\n", address); + pclog("page 0 read from port %04x\n", address); #endif - switch (address) { - case 0x1: // CLDA0 - return ne2000->local_dma & 0xff; + switch (address) { + case 0x1: // CLDA0 + return ne2000->local_dma & 0xff; - case 0x2: // CLDA1 - return ne2000->local_dma >> 8; + case 0x2: // CLDA1 + return ne2000->local_dma >> 8; - case 0x3: // BNRY - return ne2000->bound_ptr; + case 0x3: // BNRY + return ne2000->bound_ptr; - case 0x4: // TSR - return ((ne2000->TSR.ow_coll << 7) | - (ne2000->TSR.cd_hbeat << 6) | - (ne2000->TSR.fifo_ur << 5) | - (ne2000->TSR.no_carrier << 4) | - (ne2000->TSR.aborted << 3) | - (ne2000->TSR.collided << 2) | - (ne2000->TSR.tx_ok)); + case 0x4: // TSR + return ((ne2000->TSR.ow_coll << 7) | (ne2000->TSR.cd_hbeat << 6) | (ne2000->TSR.fifo_ur << 5) | + (ne2000->TSR.no_carrier << 4) | (ne2000->TSR.aborted << 3) | (ne2000->TSR.collided << 2) | + (ne2000->TSR.tx_ok)); - case 0x5: // NCR - return ne2000->num_coll; + case 0x5: // NCR + return ne2000->num_coll; - case 0x6: // FIFO - // reading FIFO is only valid in loopback mode + case 0x6: // FIFO + // reading FIFO is only valid in loopback mode #ifdef NE2000_DEBUG - pclog("reading FIFO not supported yet\n"); + pclog("reading FIFO not supported yet\n"); #endif - return ne2000->fifo; + return ne2000->fifo; - case 0x7: // ISR - return ((ne2000->ISR.reset << 7) | - (ne2000->ISR.rdma_done << 6) | - (ne2000->ISR.cnt_oflow << 5) | - (ne2000->ISR.overwrite << 4) | - (ne2000->ISR.tx_err << 3) | - (ne2000->ISR.rx_err << 2) | - (ne2000->ISR.pkt_tx << 1) | - (ne2000->ISR.pkt_rx)); + case 0x7: // ISR + return ((ne2000->ISR.reset << 7) | (ne2000->ISR.rdma_done << 6) | (ne2000->ISR.cnt_oflow << 5) | + (ne2000->ISR.overwrite << 4) | (ne2000->ISR.tx_err << 3) | (ne2000->ISR.rx_err << 2) | + (ne2000->ISR.pkt_tx << 1) | (ne2000->ISR.pkt_rx)); - case 0x8: // CRDA0 - return ne2000->remote_dma & 0xff; + case 0x8: // CRDA0 + return ne2000->remote_dma & 0xff; - case 0x9: // CRDA1 - return ne2000->remote_dma >> 8; + case 0x9: // CRDA1 + return ne2000->remote_dma >> 8; - case 0xa: // reserved + case 0xa: // reserved #ifdef NE2000_DEBUG - pclog("reserved read - page 0, 0xa\n"); + pclog("reserved read - page 0, 0xa\n"); #endif - return 0xff; + return 0xff; - case 0xb: // reserved + case 0xb: // reserved #ifdef NE2000_DEBUG - pclog("reserved read - page 0, 0xb\n"); + pclog("reserved read - page 0, 0xb\n"); #endif - return 0xff; + return 0xff; - case 0xc: // RSR - return ((ne2000->RSR.deferred << 7) | - (ne2000->RSR.rx_disabled << 6) | - (ne2000->RSR.rx_mbit << 5) | - (ne2000->RSR.rx_missed << 4) | - (ne2000->RSR.fifo_or << 3) | - (ne2000->RSR.bad_falign << 2) | - (ne2000->RSR.bad_crc << 1) | - (ne2000->RSR.rx_ok)); + case 0xc: // RSR + return ((ne2000->RSR.deferred << 7) | (ne2000->RSR.rx_disabled << 6) | + (ne2000->RSR.rx_mbit << 5) | (ne2000->RSR.rx_missed << 4) | (ne2000->RSR.fifo_or << 3) | + (ne2000->RSR.bad_falign << 2) | (ne2000->RSR.bad_crc << 1) | (ne2000->RSR.rx_ok)); - case 0xd: // CNTR0 - return ne2000->tallycnt_0; + case 0xd: // CNTR0 + return ne2000->tallycnt_0; - case 0xe: // CNTR1 - return ne2000->tallycnt_1; + case 0xe: // CNTR1 + return ne2000->tallycnt_1; - case 0xf: // CNTR2 - return ne2000->tallycnt_2; - } + case 0xf: // CNTR2 + return ne2000->tallycnt_2; + } - return 0; + return 0; - case 0x01: + case 0x01: #ifdef NE2000_DEBUG - pclog("page 1 read from port %04x\n", address); + pclog("page 1 read from port %04x\n", address); #endif - switch (address) { - case 0x1: // PAR0-5 - case 0x2: - case 0x3: - case 0x4: - case 0x5: - case 0x6:return ne2000->physaddr[address - 1]; + switch (address) { + case 0x1: // PAR0-5 + case 0x2: + case 0x3: + case 0x4: + case 0x5: + case 0x6: + return ne2000->physaddr[address - 1]; - case 0x7: // CURR + case 0x7: // CURR #ifdef NE2000_DEBUG - pclog("returning current page: %02x\n", (ne2000->curr_page)); + pclog("returning current page: %02x\n", (ne2000->curr_page)); #endif - return ne2000->curr_page; + return ne2000->curr_page; - case 0x8: // MAR0-7 - case 0x9: - case 0xa: - case 0xb: - case 0xc: - case 0xd: - case 0xe: - case 0xf:return ne2000->mchash[address - 8]; - } + case 0x8: // MAR0-7 + case 0x9: + case 0xa: + case 0xb: + case 0xc: + case 0xd: + case 0xe: + case 0xf: + return ne2000->mchash[address - 8]; + } - return 0; + return 0; - case 0x02: + case 0x02: #ifdef NE2000_DEBUG - pclog("page 2 read from port %04x\n", address); + pclog("page 2 read from port %04x\n", address); #endif - switch (address) { - case 0x1: // PSTART - return (ne2000->page_start); + switch (address) { + case 0x1: // PSTART + return (ne2000->page_start); - case 0x2: // PSTOP - return ne2000->page_stop; + case 0x2: // PSTOP + return ne2000->page_stop; - case 0x3: // Remote Next-packet pointer - return ne2000->rempkt_ptr; + case 0x3: // Remote Next-packet pointer + return ne2000->rempkt_ptr; - case 0x4: // TPSR - return ne2000->tx_page_start; + case 0x4: // TPSR + return ne2000->tx_page_start; - case 0x5: // Local Next-packet pointer - return ne2000->localpkt_ptr; + case 0x5: // Local Next-packet pointer + return ne2000->localpkt_ptr; - case 0x6: // Address counter (upper) - return ne2000->address_cnt >> 8; + case 0x6: // Address counter (upper) + return ne2000->address_cnt >> 8; - case 0x7: // Address counter (lower) - return ne2000->address_cnt & 0xff; + case 0x7: // Address counter (lower) + return ne2000->address_cnt & 0xff; - case 0x8: // Reserved - case 0x9: - case 0xa: - case 0xb: + case 0x8: // Reserved + case 0x9: + case 0xa: + case 0xb: #ifdef NE2000_DEBUG - pclog("reserved read - page 2, 0x%02x\n", address); + pclog("reserved read - page 2, 0x%02x\n", address); #endif - break; + break; - case 0xc: // RCR - return ((ne2000->RCR.monitor << 5) | - (ne2000->RCR.promisc << 4) | - (ne2000->RCR.multicast << 3) | - (ne2000->RCR.broadcast << 2) | - (ne2000->RCR.runts_ok << 1) | - (ne2000->RCR.errors_ok)); + case 0xc: // RCR + return ((ne2000->RCR.monitor << 5) | (ne2000->RCR.promisc << 4) | (ne2000->RCR.multicast << 3) | + (ne2000->RCR.broadcast << 2) | (ne2000->RCR.runts_ok << 1) | (ne2000->RCR.errors_ok)); - case 0xd: // TCR - return ((ne2000->TCR.coll_prio << 4) | - (ne2000->TCR.ext_stoptx << 3) | - ((ne2000->TCR.loop_cntl & 0x3) << 1) | - (ne2000->TCR.crc_disable)); + case 0xd: // TCR + return ((ne2000->TCR.coll_prio << 4) | (ne2000->TCR.ext_stoptx << 3) | + ((ne2000->TCR.loop_cntl & 0x3) << 1) | (ne2000->TCR.crc_disable)); - case 0xe: // DCR - return (((ne2000->DCR.fifo_size & 0x3) << 5) | - (ne2000->DCR.auto_rx << 4) | - (ne2000->DCR.loop << 3) | - (ne2000->DCR.longaddr << 2) | - (ne2000->DCR.endian << 1) | - (ne2000->DCR.wdsize)); + case 0xe: // DCR + return (((ne2000->DCR.fifo_size & 0x3) << 5) | (ne2000->DCR.auto_rx << 4) | + (ne2000->DCR.loop << 3) | (ne2000->DCR.longaddr << 2) | (ne2000->DCR.endian << 1) | + (ne2000->DCR.wdsize)); - case 0xf: // IMR - return ((ne2000->IMR.rdma_inte << 6) | - (ne2000->IMR.cofl_inte << 5) | - (ne2000->IMR.overw_inte << 4) | - (ne2000->IMR.txerr_inte << 3) | - (ne2000->IMR.rxerr_inte << 2) | - (ne2000->IMR.tx_inte << 1) | - (ne2000->IMR.rx_inte)); - } - break; + case 0xf: // IMR + return ((ne2000->IMR.rdma_inte << 6) | (ne2000->IMR.cofl_inte << 5) | + (ne2000->IMR.overw_inte << 4) | (ne2000->IMR.txerr_inte << 3) | + (ne2000->IMR.rxerr_inte << 2) | (ne2000->IMR.tx_inte << 1) | (ne2000->IMR.rx_inte)); + } + break; - case 0x03: - if (ne2000->type != NE2000_RTL8029AS) - fatal("ne2000 unknown value of pgsel in read - %d\n", ne2000->CR.pgsel); + case 0x03: + if (ne2000->type != NE2000_RTL8029AS) + fatal("ne2000 unknown value of pgsel in read - %d\n", ne2000->CR.pgsel); #ifdef NE2000_DEBUG - pclog("page 3 read from port %04x\n", address); + pclog("page 3 read from port %04x\n", address); #endif - switch (address) { - case 0x1: /*9346CR*/ - return ne2000->_9346cr; + switch (address) { + case 0x1: /*9346CR*/ + return ne2000->_9346cr; - case 0x3: /*CONFIG0*/ - return 0x00; /*Cable not BNC*/ + case 0x3: /*CONFIG0*/ + return 0x00; /*Cable not BNC*/ - case 0x5: /*CONFIG2*/ - return ne2000->config2 & 0xe0; /*No boot ROM*/ + case 0x5: /*CONFIG2*/ + return ne2000->config2 & 0xe0; /*No boot ROM*/ - case 0x6: /*CONFIG3*/ - return ne2000->config3 & 0x46; + case 0x6: /*CONFIG3*/ + return ne2000->config3 & 0x46; - case 0xe: /*8029ASID0*/ - return 0x29; + case 0xe: /*8029ASID0*/ + return 0x29; - case 0xf: /*8029ASID1*/ - return 0x08; - } + case 0xf: /*8029ASID1*/ + return 0x08; + } - pclog("reserved read - page 3, 0x%02x\n", address); - break; - } - } + pclog("reserved read - page 3, 0x%02x\n", address); + break; + } + } - return ret; + return ret; } // @@ -746,467 +712,449 @@ uint8_t ne2000_read(uint16_t address, void *p) { // by this ne2000 instance // void ne2000_write(uint16_t address, uint8_t value, void *p) { - ne2000_t *ne2000 = (ne2000_t *)p; + ne2000_t *ne2000 = (ne2000_t *)p; #ifdef NE2000_DEBUG - pclog("write address %x, val=%x\n", address, value); + pclog("write address %x, val=%x\n", address, value); #endif - address &= 0xf; + address &= 0xf; - // - // 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 (address == 0x00) { + // + // 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 (address == 0x00) { #ifdef NE2000_DEBUG - pclog("wrote 0x%02x to CR\n", value); + pclog("wrote 0x%02x to CR\n", value); #endif - // Validate remote-DMA - if ((value & 0x38) == 0x00) { + // Validate remote-DMA + if ((value & 0x38) == 0x00) { #ifdef NE2000_DEBUG - pclog("CR write - invalid rDMA value 0\n"); + pclog("CR write - invalid rDMA value 0\n"); #endif - value |= 0x20; /* dma_cmd == 4 is a safe default */ - //value = 0x22; /* dma_cmd == 4 is a safe default */ - } + value |= 0x20; /* dma_cmd == 4 is a safe default */ + // value = 0x22; /* dma_cmd == 4 is a safe default */ + } - // Check for s/w reset - if (value & 0x01) { - ne2000->ISR.reset = 1; - ne2000->CR.stop = 1; - } else - ne2000->CR.stop = 0; + // Check for s/w reset + if (value & 0x01) { + ne2000->ISR.reset = 1; + ne2000->CR.stop = 1; + } else + ne2000->CR.stop = 0; - ne2000->CR.rdma_cmd = (value & 0x38) >> 3; + ne2000->CR.rdma_cmd = (value & 0x38) >> 3; - // If start command issued, the RST bit in the ISR - // must be cleared - if ((value & 0x02) && !ne2000->CR.start) - ne2000->ISR.reset = 0; + // If start command issued, the RST bit in the ISR + // must be cleared + if ((value & 0x02) && !ne2000->CR.start) + ne2000->ISR.reset = 0; - ne2000->CR.start = ((value & 0x02) == 0x02); - ne2000->CR.pgsel = (value & 0xc0) >> 6; + ne2000->CR.start = ((value & 0x02) == 0x02); + ne2000->CR.pgsel = (value & 0xc0) >> 6; - // Check for send-packet command - if (ne2000->CR.rdma_cmd == 3) { - // Set up DMA read from receive ring - ne2000->remote_start = ne2000->remote_dma = - ne2000->bound_ptr * 256; - ne2000->remote_bytes = *((uint16_t *)& - ne2000->mem[ne2000->bound_ptr * 256 + 2 - BX_NE2K_MEMSTART]); + // Check for send-packet command + if (ne2000->CR.rdma_cmd == 3) { + // Set up DMA read from receive ring + ne2000->remote_start = ne2000->remote_dma = ne2000->bound_ptr * 256; + ne2000->remote_bytes = *((uint16_t *)&ne2000->mem[ne2000->bound_ptr * 256 + 2 - BX_NE2K_MEMSTART]); #ifdef NE2000_DEBUG - pclog("Sending buffer #x%x length %d\n", - ne2000->remote_start, - ne2000->remote_bytes); + pclog("Sending buffer #x%x length %d\n", ne2000->remote_start, ne2000->remote_bytes); #endif - } + } - // Check for start-tx - if ((value & 0x04) && ne2000->TCR.loop_cntl) { - // loopback mode - if (ne2000->TCR.loop_cntl != 1) { + // Check for start-tx + if ((value & 0x04) && ne2000->TCR.loop_cntl) { + // loopback mode + if (ne2000->TCR.loop_cntl != 1) { #ifdef NE2000_DEBUG - pclog("Loop mode %d not supported.\n", ne2000->TCR.loop_cntl); + pclog("Loop mode %d not supported.\n", ne2000->TCR.loop_cntl); #endif - } else { - ne2000_rx_frame(ne2000, &ne2000->mem[ne2000->tx_page_start * 256 - - BX_NE2K_MEMSTART], - ne2000->tx_bytes); + } else { + ne2000_rx_frame(ne2000, &ne2000->mem[ne2000->tx_page_start * 256 - BX_NE2K_MEMSTART], + ne2000->tx_bytes); - // do a TX interrupt - // Generate an interrupt if not masked and not one in progress - if (ne2000->IMR.tx_inte && !ne2000->ISR.pkt_tx) { - //LOG_MSG("tx complete interrupt"); - ne2000_raise_irq(ne2000); - } - ne2000->ISR.pkt_tx = 1; - } - } else if (value & 0x04) { - // start-tx and no loopback + // do a TX interrupt + // Generate an interrupt if not masked and not one in progress + if (ne2000->IMR.tx_inte && !ne2000->ISR.pkt_tx) { + // LOG_MSG("tx complete interrupt"); + ne2000_raise_irq(ne2000); + } + ne2000->ISR.pkt_tx = 1; + } + } else if (value & 0x04) { + // start-tx and no loopback #ifdef NE2000_DEBUG - if (ne2000->CR.stop || !ne2000->CR.start) - pclog("CR write - tx start, dev in reset\n"); + if (ne2000->CR.stop || !ne2000->CR.start) + pclog("CR write - tx start, dev in reset\n"); - if (ne2000->tx_bytes == 0) - pclog("CR write - tx start, tx bytes == 0\n"); + if (ne2000->tx_bytes == 0) + pclog("CR write - tx start, tx bytes == 0\n"); #endif - // Send the packet to the system driver - /* TODO: Transmit packet */ - //BX_NE2K_THIS ethdev->sendpkt(& ne2000->mem[ne2000->tx_page_start*256 - BX_NE2K_MEMSTART], ne2000->tx_bytes); - //pcap_sendpacket(adhandle,&ne2000->mem[ne2000->tx_page_start*256 - BX_NE2K_MEMSTART], ne2000->tx_bytes); - if (net_is_slirp) { - slirp_input(&ne2000->mem[ne2000->tx_page_start * 256 - BX_NE2K_MEMSTART], ne2000->tx_bytes); + // Send the packet to the system driver + /* TODO: Transmit packet */ + // BX_NE2K_THIS ethdev->sendpkt(& ne2000->mem[ne2000->tx_page_start*256 - BX_NE2K_MEMSTART], + // ne2000->tx_bytes); pcap_sendpacket(adhandle,&ne2000->mem[ne2000->tx_page_start*256 - BX_NE2K_MEMSTART], + // ne2000->tx_bytes); + if (net_is_slirp) { + slirp_input(&ne2000->mem[ne2000->tx_page_start * 256 - BX_NE2K_MEMSTART], ne2000->tx_bytes); #ifdef NE2000_DEBUG - pclog("ne2000 slirp sending packet\n"); + pclog("ne2000 slirp sending packet\n"); #endif - } + } #ifdef USE_PCAP_NETWORKING - if(net_is_pcap && net_pcap!=NULL) - { - pcap_sendpacket(net_pcap, &ne2000->mem[ne2000->tx_page_start*256 - BX_NE2K_MEMSTART], ne2000->tx_bytes); + if (net_is_pcap && net_pcap != NULL) { + pcap_sendpacket(net_pcap, &ne2000->mem[ne2000->tx_page_start * 256 - BX_NE2K_MEMSTART], + ne2000->tx_bytes); #ifdef NE2000_DEBUG - pclog("ne2000 pcap sending packet\n"); + pclog("ne2000 pcap sending packet\n"); #endif - } + } #endif - ne2000_tx_event(value, ne2000); - // Schedule a timer to trigger a tx-complete interrupt - // The number of microseconds is the bit-time / 10. - // The bit-time is the preamble+sfd (64 bits), the - // inter-frame gap (96 bits), the CRC (4 bytes), and the - // the number of bits in the frame (s.tx_bytes * 8). - // + ne2000_tx_event(value, ne2000); + // Schedule a timer to trigger a tx-complete interrupt + // The number of microseconds is the bit-time / 10. + // The bit-time is the preamble+sfd (64 bits), the + // inter-frame gap (96 bits), the CRC (4 bytes), and the + // the number of bits in the frame (s.tx_bytes * 8). + // - /* TODO: Code transmit timer */ - /* - bx_pc_system.activate_timer(ne2000->tx_timer_index, - (64 + 96 + 4*8 + ne2000->tx_bytes*8)/10, - 0); // not continuous - */ - } // end transmit-start branch + /* TODO: Code transmit timer */ + /* + bx_pc_system.activate_timer(ne2000->tx_timer_index, + (64 + 96 + 4*8 + ne2000->tx_bytes*8)/10, + 0); // not continuous + */ + } // end transmit-start branch - // 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 (ne2000->CR.rdma_cmd == 0x01 && - ne2000->CR.start && - ne2000->remote_bytes == 0) { - ne2000->ISR.rdma_done = 1; - if (ne2000->IMR.rdma_inte) { - ne2000_raise_irq(ne2000); - //DEV_pic_raise_irq(ne2000->base_irq); - } - } - } else { - switch (ne2000->CR.pgsel) { - case 0x00: + // 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 (ne2000->CR.rdma_cmd == 0x01 && ne2000->CR.start && ne2000->remote_bytes == 0) { + ne2000->ISR.rdma_done = 1; + if (ne2000->IMR.rdma_inte) { + ne2000_raise_irq(ne2000); + // DEV_pic_raise_irq(ne2000->base_irq); + } + } + } else { + switch (ne2000->CR.pgsel) { + case 0x00: #ifdef NE2000_DEBUG - pclog("page 0 write to port %04x\n", address); + pclog("page 0 write to port %04x\n", address); #endif - // It appears to be a common practice to use outw on page0 regs... + // It appears to be a common practice to use outw on page0 regs... - switch (address) { - case 0x1: // PSTART - ne2000->page_start = value; - break; + switch (address) { + case 0x1: // PSTART + ne2000->page_start = value; + break; - case 0x2: // PSTOP - // BX_INFO(("Writing to PSTOP: %02x", value)); - ne2000->page_stop = value; - break; + case 0x2: // PSTOP + // BX_INFO(("Writing to PSTOP: %02x", value)); + ne2000->page_stop = value; + break; - case 0x3: // BNRY - ne2000->bound_ptr = value; - break; + case 0x3: // BNRY + ne2000->bound_ptr = value; + break; - case 0x4: // TPSR - ne2000->tx_page_start = value; - break; + case 0x4: // TPSR + ne2000->tx_page_start = value; + break; - case 0x5: // TBCR0 - // Clear out low byte and re-insert - ne2000->tx_bytes &= 0xff00; - ne2000->tx_bytes |= (value & 0xff); - break; + case 0x5: // TBCR0 + // Clear out low byte and re-insert + ne2000->tx_bytes &= 0xff00; + ne2000->tx_bytes |= (value & 0xff); + break; - case 0x6: // TBCR1 - // Clear out high byte and re-insert - ne2000->tx_bytes &= 0x00ff; - ne2000->tx_bytes |= ((value & 0xff) << 8); - break; + case 0x6: // TBCR1 + // Clear out high byte and re-insert + ne2000->tx_bytes &= 0x00ff; + ne2000->tx_bytes |= ((value & 0xff) << 8); + break; - case 0x7: // ISR - value &= 0x7f; // clear RST bit - status-only bit - // All other values are cleared iff the ISR bit is 1 - ne2000->ISR.pkt_rx &= ~((int)((value & 0x01) == 0x01)); - ne2000->ISR.pkt_tx &= ~((int)((value & 0x02) == 0x02)); - ne2000->ISR.rx_err &= ~((int)((value & 0x04) == 0x04)); - ne2000->ISR.tx_err &= ~((int)((value & 0x08) == 0x08)); - ne2000->ISR.overwrite &= ~((int)((value & 0x10) == 0x10)); - ne2000->ISR.cnt_oflow &= ~((int)((value & 0x20) == 0x20)); - ne2000->ISR.rdma_done &= ~((int)((value & 0x40) == 0x40)); - value = ((ne2000->ISR.rdma_done << 6) | - (ne2000->ISR.cnt_oflow << 5) | - (ne2000->ISR.overwrite << 4) | - (ne2000->ISR.tx_err << 3) | - (ne2000->ISR.rx_err << 2) | - (ne2000->ISR.pkt_tx << 1) | - (ne2000->ISR.pkt_rx)); - value &= ((ne2000->IMR.rdma_inte << 6) | - (ne2000->IMR.cofl_inte << 5) | - (ne2000->IMR.overw_inte << 4) | - (ne2000->IMR.txerr_inte << 3) | - (ne2000->IMR.rxerr_inte << 2) | - (ne2000->IMR.tx_inte << 1) | - (ne2000->IMR.rx_inte)); - if (value == 0) - ne2000_lower_irq(ne2000); - //DEV_pic_lower_irq(ne2000->base_irq); - break; + case 0x7: // ISR + value &= 0x7f; // clear RST bit - status-only bit + // All other values are cleared iff the ISR bit is 1 + ne2000->ISR.pkt_rx &= ~((int)((value & 0x01) == 0x01)); + ne2000->ISR.pkt_tx &= ~((int)((value & 0x02) == 0x02)); + ne2000->ISR.rx_err &= ~((int)((value & 0x04) == 0x04)); + ne2000->ISR.tx_err &= ~((int)((value & 0x08) == 0x08)); + ne2000->ISR.overwrite &= ~((int)((value & 0x10) == 0x10)); + ne2000->ISR.cnt_oflow &= ~((int)((value & 0x20) == 0x20)); + ne2000->ISR.rdma_done &= ~((int)((value & 0x40) == 0x40)); + value = ((ne2000->ISR.rdma_done << 6) | (ne2000->ISR.cnt_oflow << 5) | + (ne2000->ISR.overwrite << 4) | (ne2000->ISR.tx_err << 3) | (ne2000->ISR.rx_err << 2) | + (ne2000->ISR.pkt_tx << 1) | (ne2000->ISR.pkt_rx)); + value &= ((ne2000->IMR.rdma_inte << 6) | (ne2000->IMR.cofl_inte << 5) | + (ne2000->IMR.overw_inte << 4) | (ne2000->IMR.txerr_inte << 3) | + (ne2000->IMR.rxerr_inte << 2) | (ne2000->IMR.tx_inte << 1) | (ne2000->IMR.rx_inte)); + if (value == 0) + ne2000_lower_irq(ne2000); + // DEV_pic_lower_irq(ne2000->base_irq); + break; - case 0x8: // RSAR0 - // Clear out low byte and re-insert - ne2000->remote_start &= 0xff00; - ne2000->remote_start |= (value & 0xff); - ne2000->remote_dma = ne2000->remote_start; - break; + case 0x8: // RSAR0 + // Clear out low byte and re-insert + ne2000->remote_start &= 0xff00; + ne2000->remote_start |= (value & 0xff); + ne2000->remote_dma = ne2000->remote_start; + break; - case 0x9: // RSAR1 - // Clear out high byte and re-insert - ne2000->remote_start &= 0x00ff; - ne2000->remote_start |= ((value & 0xff) << 8); - ne2000->remote_dma = ne2000->remote_start; - break; + case 0x9: // RSAR1 + // Clear out high byte and re-insert + ne2000->remote_start &= 0x00ff; + ne2000->remote_start |= ((value & 0xff) << 8); + ne2000->remote_dma = ne2000->remote_start; + break; - case 0xa: // RBCR0 - // Clear out low byte and re-insert - ne2000->remote_bytes &= 0xff00; - ne2000->remote_bytes |= (value & 0xff); - break; + case 0xa: // RBCR0 + // Clear out low byte and re-insert + ne2000->remote_bytes &= 0xff00; + ne2000->remote_bytes |= (value & 0xff); + break; - case 0xb: // RBCR1 - // Clear out high byte and re-insert - ne2000->remote_bytes &= 0x00ff; - ne2000->remote_bytes |= ((value & 0xff) << 8); - break; + case 0xb: // RBCR1 + // Clear out high byte and re-insert + ne2000->remote_bytes &= 0x00ff; + ne2000->remote_bytes |= ((value & 0xff) << 8); + break; - case 0xc: // RCR - // Check if the reserved bits are set + case 0xc: // RCR + // Check if the reserved bits are set #ifdef NE2000_DEBUG - if (value & 0xc0) - pclog("RCR write, reserved bits set\n"); + if (value & 0xc0) + pclog("RCR write, reserved bits set\n"); #endif - // Set all other bit-fields - ne2000->RCR.errors_ok = ((value & 0x01) == 0x01); - ne2000->RCR.runts_ok = ((value & 0x02) == 0x02); - ne2000->RCR.broadcast = ((value & 0x04) == 0x04); - ne2000->RCR.multicast = ((value & 0x08) == 0x08); - ne2000->RCR.promisc = ((value & 0x10) == 0x10); - ne2000->RCR.monitor = ((value & 0x20) == 0x20); + // Set all other bit-fields + ne2000->RCR.errors_ok = ((value & 0x01) == 0x01); + ne2000->RCR.runts_ok = ((value & 0x02) == 0x02); + ne2000->RCR.broadcast = ((value & 0x04) == 0x04); + ne2000->RCR.multicast = ((value & 0x08) == 0x08); + ne2000->RCR.promisc = ((value & 0x10) == 0x10); + ne2000->RCR.monitor = ((value & 0x20) == 0x20); - // Monitor bit is a little suspicious... + // Monitor bit is a little suspicious... #ifdef NE2000_DEBUG - if (value & 0x20) - pclog("RCR write, monitor bit set!\n"); + if (value & 0x20) + pclog("RCR write, monitor bit set!\n"); #endif - break; + break; - case 0xd: // TCR - // Check reserved bits + case 0xd: // TCR + // Check reserved bits #ifdef NE2000_DEBUG - if (value & 0xe0) - pclog("TCR write, reserved bits set\n"); + if (value & 0xe0) + pclog("TCR write, reserved bits set\n"); #endif - // Test loop mode (not supported) - if (value & 0x06) { - ne2000->TCR.loop_cntl = (value & 0x6) >> 1; + // Test loop mode (not supported) + if (value & 0x06) { + ne2000->TCR.loop_cntl = (value & 0x6) >> 1; #ifdef NE2000_DEBUG - pclog("TCR write, loop mode %d not supported\n", ne2000->TCR.loop_cntl); + pclog("TCR write, loop mode %d not supported\n", ne2000->TCR.loop_cntl); #endif - } else - ne2000->TCR.loop_cntl = 0; + } else + ne2000->TCR.loop_cntl = 0; - // Inhibit-CRC not supported. - if (value & 0x01) { - //fatal("ne2000 TCR write, inhibit-CRC not supported\n"); + // Inhibit-CRC not supported. + if (value & 0x01) { + // fatal("ne2000 TCR write, inhibit-CRC not supported\n"); #ifdef NE2000_DEBUG - pclog("ne2000 TCR write, inhibit-CRC not supported\n"); + pclog("ne2000 TCR write, inhibit-CRC not supported\n"); #endif - return; - } + return; + } - // Auto-transmit disable very suspicious - if (value & 0x08) { - //fatal("ne2000 TCR write, auto transmit disable not supported\n"); + // Auto-transmit disable very suspicious + if (value & 0x08) { + // fatal("ne2000 TCR write, auto transmit disable not supported\n"); #ifdef NE2000_DEBUG - pclog("ne2000 TCR write, auto transmit disable not supported\n"); + pclog("ne2000 TCR write, auto transmit disable not supported\n"); #endif - } + } - // Allow collision-offset to be set, although not used - ne2000->TCR.coll_prio = ((value & 0x08) == 0x08); - break; + // Allow collision-offset to be set, although not used + ne2000->TCR.coll_prio = ((value & 0x08) == 0x08); + break; - case 0xe: // DCR - // the loopback mode is not suppported yet + case 0xe: // DCR + // the loopback mode is not suppported yet #ifdef NE2000_DEBUG - if (!(value & 0x08)) - pclog("DCR write, loopback mode selected\n"); + if (!(value & 0x08)) + pclog("DCR write, loopback mode selected\n"); - // It is questionable to set longaddr and auto_rx, since they - // aren't supported on the ne2000. Print a warning and continue - if (value & 0x04) - pclog("DCR write - LAS set ???\n"); - if (value & 0x10) - pclog("DCR write - AR set ???\n"); + // It is questionable to set longaddr and auto_rx, since they + // aren't supported on the ne2000. Print a warning and continue + if (value & 0x04) + pclog("DCR write - LAS set ???\n"); + if (value & 0x10) + pclog("DCR write - AR set ???\n"); #endif - // Set other values. - ne2000->DCR.wdsize = ((value & 0x01) == 0x01); - ne2000->DCR.endian = ((value & 0x02) == 0x02); - ne2000->DCR.longaddr = ((value & 0x04) == 0x04); // illegal ? - ne2000->DCR.loop = ((value & 0x08) == 0x08); - ne2000->DCR.auto_rx = ((value & 0x10) == 0x10); // also illegal ? - ne2000->DCR.fifo_size = (value & 0x50) >> 5; - break; + // Set other values. + ne2000->DCR.wdsize = ((value & 0x01) == 0x01); + ne2000->DCR.endian = ((value & 0x02) == 0x02); + ne2000->DCR.longaddr = ((value & 0x04) == 0x04); // illegal ? + ne2000->DCR.loop = ((value & 0x08) == 0x08); + ne2000->DCR.auto_rx = ((value & 0x10) == 0x10); // also illegal ? + ne2000->DCR.fifo_size = (value & 0x50) >> 5; + break; - case 0xf: // IMR - // Check for reserved bit + case 0xf: // IMR + // Check for reserved bit #ifdef NE2000_DEBUG - if (value & 0x80) - pclog("IMR write, reserved bit set\n"); + if (value & 0x80) + pclog("IMR write, reserved bit set\n"); #endif - // Set other values - ne2000->IMR.rx_inte = ((value & 0x01) == 0x01); - ne2000->IMR.tx_inte = ((value & 0x02) == 0x02); - ne2000->IMR.rxerr_inte = ((value & 0x04) == 0x04); - ne2000->IMR.txerr_inte = ((value & 0x08) == 0x08); - ne2000->IMR.overw_inte = ((value & 0x10) == 0x10); - ne2000->IMR.cofl_inte = ((value & 0x20) == 0x20); - ne2000->IMR.rdma_inte = ((value & 0x40) == 0x40); - value = ((ne2000->ISR.rdma_done << 6) | - (ne2000->ISR.cnt_oflow << 5) | - (ne2000->ISR.overwrite << 4) | - (ne2000->ISR.tx_err << 3) | - (ne2000->ISR.rx_err << 2) | - (ne2000->ISR.pkt_tx << 1) | - (ne2000->ISR.pkt_rx)); - value &= ((ne2000->IMR.rdma_inte << 6) | - (ne2000->IMR.cofl_inte << 5) | - (ne2000->IMR.overw_inte << 4) | - (ne2000->IMR.txerr_inte << 3) | - (ne2000->IMR.rxerr_inte << 2) | - (ne2000->IMR.tx_inte << 1) | - (ne2000->IMR.rx_inte)); - if (value) - ne2000_raise_irq(ne2000); - else - ne2000_lower_irq(ne2000); - break; - } - break; + // Set other values + ne2000->IMR.rx_inte = ((value & 0x01) == 0x01); + ne2000->IMR.tx_inte = ((value & 0x02) == 0x02); + ne2000->IMR.rxerr_inte = ((value & 0x04) == 0x04); + ne2000->IMR.txerr_inte = ((value & 0x08) == 0x08); + ne2000->IMR.overw_inte = ((value & 0x10) == 0x10); + ne2000->IMR.cofl_inte = ((value & 0x20) == 0x20); + ne2000->IMR.rdma_inte = ((value & 0x40) == 0x40); + value = ((ne2000->ISR.rdma_done << 6) | (ne2000->ISR.cnt_oflow << 5) | + (ne2000->ISR.overwrite << 4) | (ne2000->ISR.tx_err << 3) | (ne2000->ISR.rx_err << 2) | + (ne2000->ISR.pkt_tx << 1) | (ne2000->ISR.pkt_rx)); + value &= ((ne2000->IMR.rdma_inte << 6) | (ne2000->IMR.cofl_inte << 5) | + (ne2000->IMR.overw_inte << 4) | (ne2000->IMR.txerr_inte << 3) | + (ne2000->IMR.rxerr_inte << 2) | (ne2000->IMR.tx_inte << 1) | (ne2000->IMR.rx_inte)); + if (value) + ne2000_raise_irq(ne2000); + else + ne2000_lower_irq(ne2000); + break; + } + break; - case 0x01: + case 0x01: #ifdef NE2000_DEBUG - pclog("page 1 w offset %04x\n", address); + pclog("page 1 w offset %04x\n", address); #endif - switch (address) { - case 0x1: // PAR0-5 - case 0x2: - case 0x3: - case 0x4: - case 0x5: - case 0x6:ne2000->physaddr[address - 1] = value; - break; + switch (address) { + case 0x1: // PAR0-5 + case 0x2: + case 0x3: + case 0x4: + case 0x5: + case 0x6: + ne2000->physaddr[address - 1] = value; + break; - case 0x7: // CURR - ne2000->curr_page = value; - break; + case 0x7: // CURR + ne2000->curr_page = value; + break; - case 0x8: // MAR0-7 - case 0x9: - case 0xa: - case 0xb: - case 0xc: - case 0xd: - case 0xe: - case 0xf:ne2000->mchash[address - 8] = value; - break; - } - break; + case 0x8: // MAR0-7 + case 0x9: + case 0xa: + case 0xb: + case 0xc: + case 0xd: + case 0xe: + case 0xf: + ne2000->mchash[address - 8] = value; + break; + } + break; - case 0x02: + case 0x02: #ifdef NE2000_DEBUG - if (address != 0) - pclog("page 2 write ?\n"); + if (address != 0) + pclog("page 2 write ?\n"); #endif - switch (address) { - case 0x1: // CLDA0 - // Clear out low byte and re-insert - ne2000->local_dma &= 0xff00; - ne2000->local_dma |= (value & 0xff); - break; + switch (address) { + case 0x1: // CLDA0 + // Clear out low byte and re-insert + ne2000->local_dma &= 0xff00; + ne2000->local_dma |= (value & 0xff); + break; - case 0x2: // CLDA1 - // Clear out high byte and re-insert - ne2000->local_dma &= 0x00ff; - ne2000->local_dma |= ((value & 0xff) << 8); - break; + case 0x2: // CLDA1 + // Clear out high byte and re-insert + ne2000->local_dma &= 0x00ff; + ne2000->local_dma |= ((value & 0xff) << 8); + break; - case 0x3: // Remote Next-pkt pointer - ne2000->rempkt_ptr = value; - break; + case 0x3: // Remote Next-pkt pointer + ne2000->rempkt_ptr = value; + break; - case 0x4: - //fatal("page 2 write to reserved offset 4\n"); - //OS/2 Warp can cause this to freak out. + case 0x4: + // fatal("page 2 write to reserved offset 4\n"); + // OS/2 Warp can cause this to freak out. #ifdef NE2000_DEBUG - pclog("ne2000 page 2 write to reserved offset 4\n"); + pclog("ne2000 page 2 write to reserved offset 4\n"); #endif - break; + break; - case 0x5: // Local Next-packet pointer - ne2000->localpkt_ptr = value; - break; + case 0x5: // Local Next-packet pointer + ne2000->localpkt_ptr = value; + break; - case 0x6: // Address counter (upper) - // Clear out high byte and re-insert - ne2000->address_cnt &= 0x00ff; - ne2000->address_cnt |= ((value & 0xff) << 8); - break; + case 0x6: // Address counter (upper) + // Clear out high byte and re-insert + ne2000->address_cnt &= 0x00ff; + ne2000->address_cnt |= ((value & 0xff) << 8); + break; - case 0x7: // Address counter (lower) - // Clear out low byte and re-insert - ne2000->address_cnt &= 0xff00; - ne2000->address_cnt |= (value & 0xff); - break; + case 0x7: // Address counter (lower) + // Clear out low byte and re-insert + ne2000->address_cnt &= 0xff00; + ne2000->address_cnt |= (value & 0xff); + break; - case 0x8: - case 0x9: - case 0xa: - case 0xb: - case 0xc: - case 0xd: - case 0xe: - case 0xf: - //fatal("page 2 write to reserved offset %0x\n", address); + case 0x8: + case 0x9: + case 0xa: + case 0xb: + case 0xc: + case 0xd: + case 0xe: + case 0xf: + // fatal("page 2 write to reserved offset %0x\n", address); #ifdef NE2000_DEBUG - pclog("ne2000 page 2 write to reserved offset %0x\n", address); + pclog("ne2000 page 2 write to reserved offset %0x\n", address); #endif - default:break; - } - break; + default: + break; + } + break; - case 0x03: - if (ne2000->type != NE2000_RTL8029AS) { - pclog("ne2000 unknown value of pgsel in write - %d\n", ne2000->CR.pgsel); - break; - } + case 0x03: + if (ne2000->type != NE2000_RTL8029AS) { + pclog("ne2000 unknown value of pgsel in write - %d\n", ne2000->CR.pgsel); + break; + } #ifdef NE2000_DEBUG - pclog("page 3 write to port %04x\n", address); + pclog("page 3 write to port %04x\n", address); #endif - switch (address) { - case 0x1: /*9346CR*/ - ne2000->_9346cr = value & 0xfe; - break; + switch (address) { + case 0x1: /*9346CR*/ + ne2000->_9346cr = value & 0xfe; + break; - case 0x5: /*CONFIG2*/ - ne2000->config2 = value & 0xe0; - break; + case 0x5: /*CONFIG2*/ + ne2000->config2 = value & 0xe0; + break; - case 0x6: /*CONFIG3*/ - ne2000->config3 = value & 0x46; - break; + case 0x6: /*CONFIG3*/ + ne2000->config3 = value & 0x46; + break; - case 0x9: /*HLTCLK*/ - break; + case 0x9: /*HLTCLK*/ + break; - default:pclog("reserved write - page 3, 0x%02x\n", address); - break; - } - break; - } - } + default: + pclog("reserved write - page 3, 0x%02x\n", address); + break; + } + break; + } + } } /* @@ -1215,22 +1163,22 @@ void ne2000_write(uint16_t address, uint8_t value, void *p) { */ static int mcast_index(const void *dst) { #define POLYNOMIAL 0x04c11db6 - unsigned long crc = 0xffffffffL; - int carry, i, j; - unsigned char b; - unsigned char *ep = (unsigned char *)dst; + unsigned long crc = 0xffffffffL; + int carry, i, j; + unsigned char b; + unsigned char *ep = (unsigned char *)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; + 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 } @@ -1242,696 +1190,617 @@ static int mcast_index(const void *dst) { * the receive process is updated */ void ne2000_rx_frame(void *p, const void *buf, int io_len) { - ne2000_t *ne2000 = (ne2000_t *)p; + ne2000_t *ne2000 = (ne2000_t *)p; - int pages; - int avail; - int idx; - int nextpage; - uint8_t pkthdr[4]; - uint8_t *pktbuf = (uint8_t *)buf; - uint8_t *startptr; - static uint8_t bcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + int pages; + int avail; + int idx; + int nextpage; + uint8_t pkthdr[4]; + uint8_t *pktbuf = (uint8_t *)buf; + uint8_t *startptr; + static uint8_t bcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; #ifdef NE2000_DEBUG - if(io_len != 60) - pclog("rx_frame with length %d\n", io_len); + if (io_len != 60) + pclog("rx_frame with length %d\n", io_len); #endif - //LOG_MSG("stop=%d, pagestart=%x, dcr_loop=%x, tcr_loopcntl=%x", - // ne2000->CR.stop, ne2000->page_start, - // ne2000->DCR.loop, ne2000->TCR.loop_cntl); - if ((ne2000->CR.stop != 0) || + // LOG_MSG("stop=%d, pagestart=%x, dcr_loop=%x, tcr_loopcntl=%x", + // ne2000->CR.stop, ne2000->page_start, + // ne2000->DCR.loop, ne2000->TCR.loop_cntl); + if ((ne2000->CR.stop != 0) || (ne2000->page_start == 0) /*|| ((ne2000->DCR.loop == 0) && (ne2000->TCR.loop_cntl != 0))*/) - return; + return; - // Add the pkt header + CRC to the length, and work - // out how many 256-byte pages the frame would occupy - pages = (io_len + 4 + 4 + 255) / 256; + // Add the pkt header + CRC to the length, and work + // out how many 256-byte pages the frame would occupy + pages = (io_len + 4 + 4 + 255) / 256; - if (ne2000->curr_page < ne2000->bound_ptr) - avail = ne2000->bound_ptr - ne2000->curr_page; - else - avail = (ne2000->page_stop - ne2000->page_start) - - (ne2000->curr_page - ne2000->bound_ptr); + if (ne2000->curr_page < ne2000->bound_ptr) + avail = ne2000->bound_ptr - ne2000->curr_page; + else + avail = (ne2000->page_stop - ne2000->page_start) - (ne2000->curr_page - ne2000->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) + // 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 BX_NE2K_NEVER_FULL_RING - || (avail == pages) + || (avail == pages) #endif - ) { + ) { #ifdef NE2000_DEBUG - pclog("no space\n"); + pclog("no space\n"); #endif - return; - } + return; + } - if ((io_len < 40/*60*/) && !ne2000->RCR.runts_ok) { + if ((io_len < 40 /*60*/) && !ne2000->RCR.runts_ok) { #ifdef NE2000_DEBUG - pclog("rejected small packet, length %d\n", io_len); + pclog("rejected small packet, length %d\n", io_len); #endif - return; - } - // some computers don't care... - if (io_len < 60) - io_len = 60; + return; + } + // some computers don't care... + if (io_len < 60) + io_len = 60; - // Do address filtering if not in promiscuous mode - if (!ne2000->RCR.promisc) { - if (!memcmp(buf, bcast_addr, 6)) { - if (!ne2000->RCR.broadcast) - return; - } else if (pktbuf[0] & 0x01) { - if (!ne2000->RCR.multicast) - return; - idx = mcast_index(buf); - if (!(ne2000->mchash[idx >> 3] & (1 << (idx & 0x7)))) - return; - } else if (0 != memcmp(buf, ne2000->physaddr, 6)) - return; - } + // Do address filtering if not in promiscuous mode + if (!ne2000->RCR.promisc) { + if (!memcmp(buf, bcast_addr, 6)) { + if (!ne2000->RCR.broadcast) + return; + } else if (pktbuf[0] & 0x01) { + if (!ne2000->RCR.multicast) + return; + idx = mcast_index(buf); + if (!(ne2000->mchash[idx >> 3] & (1 << (idx & 0x7)))) + return; + } else if (0 != memcmp(buf, ne2000->physaddr, 6)) + return; + } #ifdef NE2000_DEBUG - else - pclog("rx_frame promiscuous receive\n"); + else + pclog("rx_frame promiscuous receive\n"); - pclog("rx_frame %d to %x:%x:%x:%x:%x:%x from %x:%x:%x:%x:%x:%x\n", - io_len, - pktbuf[0], pktbuf[1], pktbuf[2], pktbuf[3], pktbuf[4], pktbuf[5], - pktbuf[6], pktbuf[7], pktbuf[8], pktbuf[9], pktbuf[10], pktbuf[11]); + pclog("rx_frame %d to %x:%x:%x:%x:%x:%x from %x:%x:%x:%x:%x:%x\n", io_len, pktbuf[0], pktbuf[1], pktbuf[2], pktbuf[3], + pktbuf[4], pktbuf[5], pktbuf[6], pktbuf[7], pktbuf[8], pktbuf[9], pktbuf[10], pktbuf[11]); #endif - nextpage = ne2000->curr_page + pages; - if (nextpage >= ne2000->page_stop) - nextpage -= ne2000->page_stop - ne2000->page_start; + nextpage = ne2000->curr_page + pages; + if (nextpage >= ne2000->page_stop) + nextpage -= ne2000->page_stop - ne2000->page_start; - // Setup packet header - pkthdr[0] = 0; // rx status - old behavior - pkthdr[0] = 1; // Probably better to set it all the time - // rather than set it to 0, which is clearly wrong. - if (pktbuf[0] & 0x01) - pkthdr[0] |= 0x20; // rx status += multicast packet + // Setup packet header + pkthdr[0] = 0; // rx status - old behavior + pkthdr[0] = 1; // Probably better to set it all the time + // rather than set it to 0, which is clearly wrong. + if (pktbuf[0] & 0x01) + pkthdr[0] |= 0x20; // rx status += multicast packet - pkthdr[1] = nextpage; // ptr to next packet - pkthdr[2] = (io_len + 4) & 0xff; // length-low - pkthdr[3] = (io_len + 4) >> 8; // length-hi + pkthdr[1] = nextpage; // ptr to next packet + pkthdr[2] = (io_len + 4) & 0xff; // length-low + pkthdr[3] = (io_len + 4) >> 8; // length-hi - // copy into buffer, update curpage, and signal interrupt if config'd - startptr = &ne2000->mem[ne2000->curr_page * 256 - - BX_NE2K_MEMSTART]; - if ((nextpage > ne2000->curr_page) || - ((ne2000->curr_page + pages) == ne2000->page_stop)) { - memcpy(startptr, pkthdr, 4); - memcpy(startptr + 4, buf, io_len); - ne2000->curr_page = nextpage; - } else { - int endbytes = (ne2000->page_stop - ne2000->curr_page) - * 256; - memcpy(startptr, pkthdr, 4); - memcpy(startptr + 4, buf, endbytes - 4); - startptr = &ne2000->mem[ne2000->page_start * 256 - - BX_NE2K_MEMSTART]; - memcpy(startptr, (void *)(pktbuf + endbytes - 4), - io_len - endbytes + 8); - ne2000->curr_page = nextpage; - } + // copy into buffer, update curpage, and signal interrupt if config'd + startptr = &ne2000->mem[ne2000->curr_page * 256 - BX_NE2K_MEMSTART]; + if ((nextpage > ne2000->curr_page) || ((ne2000->curr_page + pages) == ne2000->page_stop)) { + memcpy(startptr, pkthdr, 4); + memcpy(startptr + 4, buf, io_len); + ne2000->curr_page = nextpage; + } else { + int endbytes = (ne2000->page_stop - ne2000->curr_page) * 256; + memcpy(startptr, pkthdr, 4); + memcpy(startptr + 4, buf, endbytes - 4); + startptr = &ne2000->mem[ne2000->page_start * 256 - BX_NE2K_MEMSTART]; + memcpy(startptr, (void *)(pktbuf + endbytes - 4), io_len - endbytes + 8); + ne2000->curr_page = nextpage; + } - ne2000->RSR.rx_ok = 1; - if (pktbuf[0] & 0x80) - ne2000->RSR.rx_mbit = 1; + ne2000->RSR.rx_ok = 1; + if (pktbuf[0] & 0x80) + ne2000->RSR.rx_mbit = 1; - ne2000->ISR.pkt_rx = 1; + ne2000->ISR.pkt_rx = 1; - if (ne2000->IMR.rx_inte) { - //LOG_MSG("packet rx interrupt"); - ne2000_raise_irq(ne2000); - //DEV_pic_raise_irq(ne2000->base_irq); - } - //else LOG_MSG("no packet rx interrupt"); + if (ne2000->IMR.rx_inte) { + // LOG_MSG("packet rx interrupt"); + ne2000_raise_irq(ne2000); + // DEV_pic_raise_irq(ne2000->base_irq); + } + // else LOG_MSG("no packet rx interrupt"); } void ne2000_tx_timer(void *p) { - ne2000_t *ne2000 = (ne2000_t *)p; + ne2000_t *ne2000 = (ne2000_t *)p; #ifdef NE2000_DEBUG - pclog("tx_timer\n"); + pclog("tx_timer\n"); #endif - ne2000->TSR.tx_ok = 1; - // Generate an interrupt if not masked and not one in progress - if (ne2000->IMR.tx_inte && !ne2000->ISR.pkt_tx) { - //LOG_MSG("tx complete interrupt"); - ne2000_raise_irq(ne2000); - //DEV_pic_raise_irq(ne2000->base_irq); - } - //else LOG_MSG("no tx complete interrupt"); - ne2000->ISR.pkt_tx = 1; - ne2000->tx_timer_active = 0; + ne2000->TSR.tx_ok = 1; + // Generate an interrupt if not masked and not one in progress + if (ne2000->IMR.tx_inte && !ne2000->ISR.pkt_tx) { + // LOG_MSG("tx complete interrupt"); + ne2000_raise_irq(ne2000); + // DEV_pic_raise_irq(ne2000->base_irq); + } + // else LOG_MSG("no tx complete interrupt"); + ne2000->ISR.pkt_tx = 1; + ne2000->tx_timer_active = 0; } static void ne2000_tx_event(int val, void *p) { - ne2000_t *ne2000 = (ne2000_t *)p; - ne2000_tx_timer(ne2000); + ne2000_t *ne2000 = (ne2000_t *)p; + ne2000_tx_timer(ne2000); } static void ne2000_pci_add(ne2000_t *ne2000) { - io_sethandler(ne2000->base_addr, 0x0010, ne2000_read, NULL, NULL, ne2000_write, NULL, NULL, ne2000); - io_sethandler(ne2000->base_addr + 0x10, 0x000f, ne2000_asic_read_b, ne2000_asic_read_w, NULL, ne2000_asic_write_b, ne2000_asic_write_w, NULL, ne2000); - io_sethandler(ne2000->base_addr + 0x1f, 0x0001, ne2000_reset_read, NULL, NULL, ne2000_reset_write, NULL, NULL, ne2000); + io_sethandler(ne2000->base_addr, 0x0010, ne2000_read, NULL, NULL, ne2000_write, NULL, NULL, ne2000); + io_sethandler(ne2000->base_addr + 0x10, 0x000f, ne2000_asic_read_b, ne2000_asic_read_w, NULL, ne2000_asic_write_b, + ne2000_asic_write_w, NULL, ne2000); + io_sethandler(ne2000->base_addr + 0x1f, 0x0001, ne2000_reset_read, NULL, NULL, ne2000_reset_write, NULL, NULL, ne2000); } static void ne2000_pci_remove(ne2000_t *ne2000) { - io_removehandler(ne2000->base_addr, 0x0010, ne2000_read, NULL, NULL, ne2000_write, NULL, NULL, ne2000); - io_removehandler(ne2000->base_addr + 0x10, 0x000f, ne2000_asic_read_b, ne2000_asic_read_w, NULL, ne2000_asic_write_b, ne2000_asic_write_w, NULL, ne2000); - io_removehandler(ne2000->base_addr + 0x1f, 0x0001, ne2000_reset_read, NULL, NULL, ne2000_reset_write, NULL, NULL, ne2000); + io_removehandler(ne2000->base_addr, 0x0010, ne2000_read, NULL, NULL, ne2000_write, NULL, NULL, ne2000); + io_removehandler(ne2000->base_addr + 0x10, 0x000f, ne2000_asic_read_b, ne2000_asic_read_w, NULL, ne2000_asic_write_b, + ne2000_asic_write_w, NULL, ne2000); + io_removehandler(ne2000->base_addr + 0x1f, 0x0001, ne2000_reset_read, NULL, NULL, ne2000_reset_write, NULL, NULL, ne2000); } static uint8_t rtl8029_pci_read(int func, int addr, void *p) { - ne2000_t *ne2000 = (ne2000_t *)p; + ne2000_t *ne2000 = (ne2000_t *)p; - if (func) - return 0; + if (func) + return 0; -// pclog("RTL8029 PCI read %08X PC=%08x\n", addr, cpu_state.pc); + // pclog("RTL8029 PCI read %08X PC=%08x\n", addr, cpu_state.pc); - switch (addr) { - case 0x00: return 0xec; /*Realtek*/ - case 0x01: return 0x10; + switch (addr) { + case 0x00: + return 0xec; /*Realtek*/ + case 0x01: + return 0x10; - case 0x02: return 0x29; /*RTL8029AS*/ - case 0x03: return 0x80; + case 0x02: + return 0x29; /*RTL8029AS*/ + case 0x03: + return 0x80; - case 0x04: return ne2000->pci_command; + case 0x04: + return ne2000->pci_command; - case 0x07: return 0x02; + case 0x07: + return 0x02; - case 0x08: return 0; /*Revision ID*/ - case 0x09: return 0; /*Programming interface*/ - case 0x0a: return 0; /*Ethernet controller*/ - case 0x0b: return 0x02; /*Network controller*/ + case 0x08: + return 0; /*Revision ID*/ + case 0x09: + return 0; /*Programming interface*/ + case 0x0a: + return 0; /*Ethernet controller*/ + case 0x0b: + return 0x02; /*Network controller*/ - case 0x10: return 0x01 | (ne2000->base_addr & 0xe0); /*memBaseAddr*/ - case 0x11: return ne2000->base_addr >> 8; - case 0x12: return ne2000->base_addr >> 16; - case 0x13: return ne2000->base_addr >> 24; + case 0x10: + return 0x01 | (ne2000->base_addr & 0xe0); /*memBaseAddr*/ + case 0x11: + return ne2000->base_addr >> 8; + case 0x12: + return ne2000->base_addr >> 16; + case 0x13: + return ne2000->base_addr >> 24; - case 0x2c: return 0xec; /*Subsystem vendor - Realtek*/ - case 0x2d: return 0x10; + case 0x2c: + return 0xec; /*Subsystem vendor - Realtek*/ + case 0x2d: + return 0x10; - case 0x2e: return 0x29; /*Subsystem ID - RTL8029AS*/ - case 0x2f: return 0x80; + case 0x2e: + return 0x29; /*Subsystem ID - RTL8029AS*/ + case 0x2f: + return 0x80; - case 0x3c: return ne2000->int_line; - case 0x3d: return 0x01; /*INTA*/ - } - return 0; + case 0x3c: + return ne2000->int_line; + case 0x3d: + return 0x01; /*INTA*/ + } + return 0; } static void rtl8029_pci_write(int func, int addr, uint8_t val, void *p) { - ne2000_t *ne2000 = (ne2000_t *)p; + ne2000_t *ne2000 = (ne2000_t *)p; - if (func) - return; + if (func) + return; -// pclog("RTL8029 PCI write %04X %02X PC=%08x\n", addr, val, cpu_state.pc); + // pclog("RTL8029 PCI write %04X %02X PC=%08x\n", addr, val, cpu_state.pc); - switch (addr) { - case 0x04: - if (ne2000->pci_command & PCI_COMMAND_IO) - ne2000_pci_remove(ne2000); - ne2000->pci_command = val & 3; - if (ne2000->pci_command & PCI_COMMAND_IO) - ne2000_pci_add(ne2000); - break; + switch (addr) { + case 0x04: + if (ne2000->pci_command & PCI_COMMAND_IO) + ne2000_pci_remove(ne2000); + ne2000->pci_command = val & 3; + if (ne2000->pci_command & PCI_COMMAND_IO) + ne2000_pci_add(ne2000); + break; - case 0x10: - if (ne2000->pci_command & PCI_COMMAND_IO) - ne2000_pci_remove(ne2000); - ne2000->base_addr = (ne2000->base_addr & 0xffffff00) | (val & 0xe0); - if (ne2000->pci_command & PCI_COMMAND_IO) - ne2000_pci_add(ne2000); - break; - case 0x11: - if (ne2000->pci_command & PCI_COMMAND_IO) - ne2000_pci_remove(ne2000); - ne2000->base_addr = (ne2000->base_addr & 0xffff00e0) | (val << 8); - if (ne2000->pci_command & PCI_COMMAND_IO) - ne2000_pci_add(ne2000); - break; - case 0x12:ne2000->base_addr = (ne2000->base_addr & 0xff00ffe0) | (val << 16); - break; - case 0x13:ne2000->base_addr = (ne2000->base_addr & 0x00ffffe0) | (val << 24); - break; + case 0x10: + if (ne2000->pci_command & PCI_COMMAND_IO) + ne2000_pci_remove(ne2000); + ne2000->base_addr = (ne2000->base_addr & 0xffffff00) | (val & 0xe0); + if (ne2000->pci_command & PCI_COMMAND_IO) + ne2000_pci_add(ne2000); + break; + case 0x11: + if (ne2000->pci_command & PCI_COMMAND_IO) + ne2000_pci_remove(ne2000); + ne2000->base_addr = (ne2000->base_addr & 0xffff00e0) | (val << 8); + if (ne2000->pci_command & PCI_COMMAND_IO) + ne2000_pci_add(ne2000); + break; + case 0x12: + ne2000->base_addr = (ne2000->base_addr & 0xff00ffe0) | (val << 16); + break; + case 0x13: + ne2000->base_addr = (ne2000->base_addr & 0x00ffffe0) | (val << 24); + break; - case 0x3c:ne2000->int_line = val; - break; - } + case 0x3c: + ne2000->int_line = val; + break; + } } static void ne2000_poller(void *p) { - ne2000_t *ne2000 = (ne2000_t *)p; - struct queuepacket *qp; - const unsigned char *data; + ne2000_t *ne2000 = (ne2000_t *)p; + struct queuepacket *qp; + const unsigned char *data; #ifdef USE_PCAP_NETWORKING - struct pcap_pkthdr h; + struct pcap_pkthdr h; #endif - if (net_is_slirp) { - while (QueuePeek(slirpq) > 0) { - qp = QueueDelete(slirpq); - if ((ne2000->DCR.loop == 0) || (ne2000->TCR.loop_cntl != 0)) { - free(qp); - return; - } - ne2000_rx_frame(ne2000, &qp->data, qp->len); + if (net_is_slirp) { + while (QueuePeek(slirpq) > 0) { + qp = QueueDelete(slirpq); + if ((ne2000->DCR.loop == 0) || (ne2000->TCR.loop_cntl != 0)) { + free(qp); + return; + } + ne2000_rx_frame(ne2000, &qp->data, qp->len); #ifdef NE2000_DEBUG - pclog("ne2000 inQ:%d got a %dbyte packet @%d\n",QueuePeek(slirpq),qp->len,qp); + pclog("ne2000 inQ:%d got a %dbyte packet @%d\n", QueuePeek(slirpq), qp->len, qp); #endif - free(qp); - } - fizz++; - if (fizz > 1200) { - fizz = 0; - slirp_tic(); - } - }//end slirp + free(qp); + } + fizz++; + if (fizz > 1200) { + fizz = 0; + slirp_tic(); + } + } // end slirp #ifdef USE_PCAP_NETWORKING - if (net_is_pcap && net_pcap!=NULL) - { - data = pcap_next(net_pcap,&h); - if (data == 0x0) - return; - if ((memcmp(data+6,maclocal,6)) == 0) - pclog("ne2000 we just saw ourselves\n"); - else - { - if((ne2000->DCR.loop == 0) || (ne2000->TCR.loop_cntl != 0)) - return; + if (net_is_pcap && net_pcap != NULL) { + data = pcap_next(net_pcap, &h); + if (data == 0x0) + return; + if ((memcmp(data + 6, maclocal, 6)) == 0) + pclog("ne2000 we just saw ourselves\n"); + else { + if ((ne2000->DCR.loop == 0) || (ne2000->TCR.loop_cntl != 0)) + return; #ifdef NE2000_DEBUG - pclog("ne2000 pcap received a frame %d bytes\n",h.caplen); + pclog("ne2000 pcap received a frame %d bytes\n", h.caplen); #endif - ne2000_rx_frame(ne2000,data,h.caplen); - } - } + ne2000_rx_frame(ne2000, data, h.caplen); + } + } #endif } void *ne2000_common_init() { - struct in_addr myaddr; - int rc; - unsigned int macint[6]; - char *macstring; + struct in_addr myaddr; + int rc; + unsigned int macint[6]; + char *macstring; - ne2000_t *ne2000 = malloc(sizeof(ne2000_t)); - memset(ne2000, 0, sizeof(ne2000_t)); + ne2000_t *ne2000 = malloc(sizeof(ne2000_t)); + memset(ne2000, 0, sizeof(ne2000_t)); - macstring = config_get_string(CFG_MACHINE, NULL, "macaddr", ""); + macstring = config_get_string(CFG_MACHINE, NULL, "macaddr", ""); - if (sscanf(macstring, "%02x:%02x:%02x:%02x:%02x:%02x", - &macint[0], &macint[1], &macint[2], &macint[3], &macint[4], &macint[5]) != 6) { - maclocal[0] = 0xac; - maclocal[1] = 0xde; - maclocal[2] = 0x48; - maclocal[3] = 0x88; - maclocal[4] = 0xbb; - maclocal[5] = 0xaa; - pclog("ne2000: Using default MAC address (AC:DE:48:88:BB:AA)\n"); - } else { - maclocal[0] = macint[0]; - maclocal[1] = macint[1]; - maclocal[2] = macint[2]; - maclocal[3] = macint[3]; - maclocal[4] = macint[4]; - maclocal[5] = macint[5]; - pclog("ne2000: Using MAC address from pcem.cfg: %s\n", macstring); - } + if (sscanf(macstring, "%02x:%02x:%02x:%02x:%02x:%02x", &macint[0], &macint[1], &macint[2], &macint[3], &macint[4], + &macint[5]) != 6) { + maclocal[0] = 0xac; + maclocal[1] = 0xde; + maclocal[2] = 0x48; + maclocal[3] = 0x88; + maclocal[4] = 0xbb; + maclocal[5] = 0xaa; + pclog("ne2000: Using default MAC address (AC:DE:48:88:BB:AA)\n"); + } else { + maclocal[0] = macint[0]; + maclocal[1] = macint[1]; + maclocal[2] = macint[2]; + maclocal[3] = macint[3]; + maclocal[4] = macint[4]; + maclocal[5] = macint[5]; + pclog("ne2000: Using MAC address from pcem.cfg: %s\n", macstring); + } - //net_type - //0 pcap - //1 slirp - // + // net_type + // 0 pcap + // 1 slirp + // #ifdef USE_PCAP_NETWORKING - net_is_slirp = (config_get_int(CFG_GLOBAL, NULL, "net_type", NET_SLIRP) == NET_SLIRP) ? 1 : 0; - pclog("ne2000 pcap device %s\n",config_get_string(CFG_GLOBAL, NULL,"pcap_device","nothing")); + net_is_slirp = (config_get_int(CFG_GLOBAL, NULL, "net_type", NET_SLIRP) == NET_SLIRP) ? 1 : 0; + pclog("ne2000 pcap device %s\n", config_get_string(CFG_GLOBAL, NULL, "pcap_device", "nothing")); - //Check that we have a string setup, otherwise turn pcap off - if (!strcmp("nothing",config_get_string(CFG_GLOBAL, NULL,"pcap_device","nothing"))) - net_is_pcap = 0; - else if (net_is_slirp == 0) - net_is_pcap = 1; + // Check that we have a string setup, otherwise turn pcap off + if (!strcmp("nothing", config_get_string(CFG_GLOBAL, NULL, "pcap_device", "nothing"))) + net_is_pcap = 0; + else if (net_is_slirp == 0) + net_is_pcap = 1; #else - net_is_slirp = 1; - net_is_pcap = 0; + net_is_slirp = 1; + net_is_pcap = 0; #endif - memcpy(ne2000->physaddr, maclocal, 6); + memcpy(ne2000->physaddr, maclocal, 6); - ne2000_reset(BX_RESET_HARDWARE, ne2000); - vlan_handler(ne2000_poller, ne2000); + ne2000_reset(BX_RESET_HARDWARE, ne2000); + vlan_handler(ne2000_poller, ne2000); - pclog("ne2000 init\tslirp is %d net_is_pcap is %d\n", net_is_slirp, net_is_pcap); + pclog("ne2000 init\tslirp is %d net_is_pcap is %d\n", net_is_slirp, net_is_pcap); - //need a switch statment for more network types. + // need a switch statment for more network types. - if (net_is_slirp) { - pclog("ne2000 initalizing SLiRP\n"); - net_is_pcap = 0; - rc = slirp_init(); - pclog("ne2000 slirp_init returned: %d\n", rc); - if (rc == 0) { - pclog("ne2000 slirp initalized!\n"); - inet_aton("10.0.2.15", &myaddr); - //YES THIS NEEDS TO PULL FROM A CONFIG FILE... but for now. - rc = slirp_redir(0, 42323, myaddr, 23); - pclog("ne2000 slirp redir returned %d on port 42323 -> 23\n", rc); - rc = slirp_redir(0, 42380, myaddr, 80); - pclog("ne2000 slirp redir returned %d on port 42380 -> 80\n", rc); - rc = slirp_redir(0, 42443, myaddr, 443); - pclog("ne2000 slirp redir returned %d on port 42443 -> 443\n", rc); - rc = slirp_redir(0, 42322, myaddr, 22); - pclog("ne2000 slirp redir returned %d on port 42322 -> 22\n", rc); + if (net_is_slirp) { + pclog("ne2000 initalizing SLiRP\n"); + net_is_pcap = 0; + rc = slirp_init(); + pclog("ne2000 slirp_init returned: %d\n", rc); + if (rc == 0) { + pclog("ne2000 slirp initalized!\n"); + inet_aton("10.0.2.15", &myaddr); + // YES THIS NEEDS TO PULL FROM A CONFIG FILE... but for now. + rc = slirp_redir(0, 42323, myaddr, 23); + pclog("ne2000 slirp redir returned %d on port 42323 -> 23\n", rc); + rc = slirp_redir(0, 42380, myaddr, 80); + pclog("ne2000 slirp redir returned %d on port 42380 -> 80\n", rc); + rc = slirp_redir(0, 42443, myaddr, 443); + pclog("ne2000 slirp redir returned %d on port 42443 -> 443\n", rc); + rc = slirp_redir(0, 42322, myaddr, 22); + pclog("ne2000 slirp redir returned %d on port 42322 -> 22\n", rc); - //Kali - rc = slirp_redir(1, 2213, myaddr, 2213); - pclog("ne2000 slirp redir returned %d on port 2213 -> 2213\n", rc); - rc = slirp_redir(1, 2231, myaddr, 2231); - pclog("ne2000 slirp redir returned %d on port 2231 -> 2231\n", rc); - rc = slirp_redir(1, 2271, myaddr, 2271); - pclog("ne2000 slirp redir returned %d on port 2271 -> 2271\n", rc); + // Kali + rc = slirp_redir(1, 2213, myaddr, 2213); + pclog("ne2000 slirp redir returned %d on port 2213 -> 2213\n", rc); + rc = slirp_redir(1, 2231, myaddr, 2231); + pclog("ne2000 slirp redir returned %d on port 2231 -> 2231\n", rc); + rc = slirp_redir(1, 2271, myaddr, 2271); + pclog("ne2000 slirp redir returned %d on port 2271 -> 2271\n", rc); - net_slirp_inited = 1; - slirpq = QueueCreate(); - net_is_slirp = 1; - fizz = 0; - pclog("ne2000 slirpq is %x\n", &slirpq); - } else { - net_slirp_inited = 0; - net_is_slirp = 0; - } - } + net_slirp_inited = 1; + slirpq = QueueCreate(); + net_is_slirp = 1; + fizz = 0; + pclog("ne2000 slirpq is %x\n", &slirpq); + } else { + net_slirp_inited = 0; + net_is_slirp = 0; + } + } #ifdef USE_PCAP_NETWORKING - if (net_is_pcap) - { //pcap - char errbuf[32768]; + if (net_is_pcap) { // pcap + char errbuf[32768]; - pclog("ne2000 initalizing libpcap\n"); - net_is_slirp=0; + pclog("ne2000 initalizing libpcap\n"); + net_is_slirp = 0; - if (pcap_lib_version && pcap_open_live && pcap_sendpacket && pcap_setnonblock && pcap_next && pcap_close && pcap_getnonblock) - { - pclog("ne2000 Pcap version [%s]\n", pcap_lib_version()); + if (pcap_lib_version && pcap_open_live && pcap_sendpacket && pcap_setnonblock && pcap_next && pcap_close && + pcap_getnonblock) { + pclog("ne2000 Pcap version [%s]\n", pcap_lib_version()); - if ((net_pcap=pcap_open_live(config_get_string(CFG_GLOBAL, NULL,"pcap_device","nothing"),1518,1,15,errbuf))==0) - { - pclog("ne2000 pcap_open_live error on %s!\n",config_get_string(CFG_GLOBAL, NULL,"pcap_device","whatever the ethernet is")); - net_is_pcap=0; return(ne2000); //YUCK!!! - } - } - else - { - pclog("%d %d %d %d %d %d %d\n",pcap_lib_version, pcap_open_live,pcap_sendpacket,pcap_setnonblock,pcap_next,pcap_close,pcap_getnonblock); - net_is_pcap=1; - } + if ((net_pcap = pcap_open_live(config_get_string(CFG_GLOBAL, NULL, "pcap_device", "nothing"), 1518, 1, 15, + errbuf)) == 0) { + pclog("ne2000 pcap_open_live error on %s!\n", + config_get_string(CFG_GLOBAL, NULL, "pcap_device", "whatever the ethernet is")); + net_is_pcap = 0; + return (ne2000); // YUCK!!! + } + } else { + pclog("%d %d %d %d %d %d %d\n", pcap_lib_version, pcap_open_live, pcap_sendpacket, pcap_setnonblock, + pcap_next, pcap_close, pcap_getnonblock); + net_is_pcap = 1; + } - //Time to check that we are in non-blocking mode. - rc=pcap_getnonblock(net_pcap,errbuf); - pclog("ne2000 pcap is currently in %s mode\n",rc? "non-blocking":"blocking"); - switch(rc) - { - case 0: - pclog("ne2000 Setting interface to non-blocking mode.."); - rc=pcap_setnonblock(net_pcap,1,errbuf); - if (rc==0) - { - pclog(".."); - rc=pcap_getnonblock(net_pcap,errbuf); - if (rc==1) - { - pclog("..!",rc); - net_is_pcap=1; - } - else - { - pclog("\tunable to set pcap into non-blocking mode!\nContinuining without pcap.\n"); - net_is_pcap=0; - } - } - else - { - pclog("There was an unexpected error of [%s]\n\nexiting.\n",errbuf); - net_is_pcap=0; - } - pclog("\n"); - break; - case 1: - pclog("non blocking\n"); - break; - default: - pclog("this isn't right!!!\n"); - net_is_pcap=0; - break; - } - if( net_is_pcap ) - { - if(pcap_compile && pcap_setfilter) - { - struct bpf_program fp; - char filter_exp[255]; + // Time to check that we are in non-blocking mode. + rc = pcap_getnonblock(net_pcap, errbuf); + pclog("ne2000 pcap is currently in %s mode\n", rc ? "non-blocking" : "blocking"); + switch (rc) { + case 0: + pclog("ne2000 Setting interface to non-blocking mode.."); + rc = pcap_setnonblock(net_pcap, 1, errbuf); + if (rc == 0) { + pclog(".."); + rc = pcap_getnonblock(net_pcap, errbuf); + if (rc == 1) { + pclog("..!", rc); + net_is_pcap = 1; + } else { + pclog("\tunable to set pcap into non-blocking mode!\nContinuining without pcap.\n"); + net_is_pcap = 0; + } + } else { + pclog("There was an unexpected error of [%s]\n\nexiting.\n", errbuf); + net_is_pcap = 0; + } + pclog("\n"); + break; + case 1: + pclog("non blocking\n"); + break; + default: + pclog("this isn't right!!!\n"); + net_is_pcap = 0; + break; + } + if (net_is_pcap) { + if (pcap_compile && pcap_setfilter) { + struct bpf_program fp; + char filter_exp[255]; - pclog("ne2000 Building packet filter..."); - 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) )", - maclocal[0], maclocal[1], maclocal[2], maclocal[3], maclocal[4], maclocal[5], - maclocal[0], maclocal[1], maclocal[2], maclocal[3], maclocal[4], maclocal[5]); + pclog("ne2000 Building packet filter..."); + 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) )", + maclocal[0], maclocal[1], maclocal[2], maclocal[3], maclocal[4], maclocal[5], maclocal[0], + maclocal[1], maclocal[2], maclocal[3], maclocal[4], maclocal[5]); - //I'm doing a MAC level filter so TCP/IP doesn't matter. - if (pcap_compile(net_pcap, &fp, filter_exp, 0, 0xffffffff) == -1) - { - pclog("\nne2000 Couldn't compile filter\n"); - } - else - { - pclog("..."); - if (pcap_setfilter(net_pcap, &fp) == -1) - { - pclog("\nError installing pcap filter.\n"); - } - else - { - pclog("...!\n"); - } - } - pclog("ne2000 Using filter\t[%s]\n",filter_exp); - } - else - { - pclog("ne2000 Your platform lacks pcap_compile & pcap_setfilter\n"); - net_is_pcap=0; - } - pclog("ne2000 net_is_pcap is %d and net_pcap is %x\n",net_is_pcap,net_pcap); - } - } //end pcap setup + // I'm doing a MAC level filter so TCP/IP doesn't matter. + if (pcap_compile(net_pcap, &fp, filter_exp, 0, 0xffffffff) == -1) { + pclog("\nne2000 Couldn't compile filter\n"); + } else { + pclog("..."); + if (pcap_setfilter(net_pcap, &fp) == -1) { + pclog("\nError installing pcap filter.\n"); + } else { + pclog("...!\n"); + } + } + pclog("ne2000 Using filter\t[%s]\n", filter_exp); + } else { + pclog("ne2000 Your platform lacks pcap_compile & pcap_setfilter\n"); + net_is_pcap = 0; + } + pclog("ne2000 net_is_pcap is %d and net_pcap is %x\n", net_is_pcap, net_pcap); + } + } // end pcap setup #endif - pclog("ne2000 is_slirp %d is_pcap %d\n", net_is_slirp, net_is_pcap); + pclog("ne2000 is_slirp %d is_pcap %d\n", net_is_slirp, net_is_pcap); - return ne2000; + return ne2000; } void *ne2000_init() { - ne2000_t *ne2000 = ne2000_common_init(); - uint16_t addr; + ne2000_t *ne2000 = ne2000_common_init(); + uint16_t addr; - ne2000->type = NE2000_NE2000; + ne2000->type = NE2000_NE2000; - ne2000_setirq(ne2000, device_get_config_int("irq")); + ne2000_setirq(ne2000, device_get_config_int("irq")); - addr = device_get_config_int("addr"); - io_sethandler(addr, 0x0010, ne2000_read, NULL, NULL, ne2000_write, NULL, NULL, ne2000); - io_sethandler(addr + 0x10, 0x0010, ne2000_asic_read_b, ne2000_asic_read_w, NULL, ne2000_asic_write_b, ne2000_asic_write_w, NULL, ne2000); - io_sethandler(addr + 0x1f, 0x0001, ne2000_reset_read, NULL, NULL, ne2000_reset_write, NULL, NULL, ne2000); + addr = device_get_config_int("addr"); + io_sethandler(addr, 0x0010, ne2000_read, NULL, NULL, ne2000_write, NULL, NULL, ne2000); + io_sethandler(addr + 0x10, 0x0010, ne2000_asic_read_b, ne2000_asic_read_w, NULL, ne2000_asic_write_b, ne2000_asic_write_w, + NULL, ne2000); + io_sethandler(addr + 0x1f, 0x0001, ne2000_reset_read, NULL, NULL, ne2000_reset_write, NULL, NULL, ne2000); - return ne2000; + return ne2000; } void *rtl8029_init() { - ne2000_t *ne2000 = ne2000_common_init(); + ne2000_t *ne2000 = ne2000_common_init(); - ne2000->is_pci = 1; - ne2000->type = NE2000_RTL8029AS; + ne2000->is_pci = 1; + ne2000->type = NE2000_RTL8029AS; - ne2000->card = pci_add(rtl8029_pci_read, rtl8029_pci_write, ne2000); + ne2000->card = pci_add(rtl8029_pci_read, rtl8029_pci_write, ne2000); - ne2000_setirq(ne2000, NE2000_PCI_IRQ); + ne2000_setirq(ne2000, NE2000_PCI_IRQ); - return ne2000; + return ne2000; } void ne2000_close(void *p) { - ne2000_t *ne2000 = (ne2000_t *)p; - free(ne2000); - if (net_is_slirp) { - QueueDestroy(slirpq); - slirp_exit(0); - net_slirp_inited = 0; - pclog("ne2000 exiting slirp\n"); - } + ne2000_t *ne2000 = (ne2000_t *)p; + free(ne2000); + if (net_is_slirp) { + QueueDestroy(slirpq); + slirp_exit(0); + net_slirp_inited = 0; + pclog("ne2000 exiting slirp\n"); + } #ifdef USE_PCAP_NETWORKING - if(net_is_pcap && net_pcap!=NULL) - { - pcap_close(net_pcap); - pclog("ne2000 closing pcap\n"); - } + if (net_is_pcap && net_pcap != NULL) { + pcap_close(net_pcap); + pclog("ne2000 closing pcap\n"); + } #endif - pclog("ne2000 close\n"); + pclog("ne2000 close\n"); } -static device_config_t ne2000_config[] = - { - { - .name = "addr", - .description = "Address", - .type = CONFIG_BINARY, - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "0x280", - .value = 0x280 - }, - { - .description = "0x300", - .value = 0x300 - }, - { - .description = "0x320", - .value = 0x320 - }, - { - .description = "0x340", - .value = 0x340 - }, - { - .description = "0x360", - .value = 0x360 - }, - { - .description = "0x380", - .value = 0x380 - }, - { - .description = "" - } - }, - .default_int = 0x300 - }, - { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "IRQ 3", - .value = 3 - }, - { - .description = "IRQ 5", - .value = 5 - }, - { - .description = "IRQ 7", - .value = 7 - }, - { - .description = "IRQ 10", - .value = 10 - }, - { - .description = "IRQ 11", - .value = 11 - }, - { - .description = "IRQ 12", - .value = 12 - }, - { - .description = "" - } - }, - .default_int = 10 - }, - { - .type = -1 - } - }; +static device_config_t ne2000_config[] = {{.name = "addr", + .description = "Address", + .type = CONFIG_BINARY, + .type = CONFIG_SELECTION, + .selection = {{.description = "0x280", .value = 0x280}, + {.description = "0x300", .value = 0x300}, + {.description = "0x320", .value = 0x320}, + {.description = "0x340", .value = 0x340}, + {.description = "0x360", .value = 0x360}, + {.description = "0x380", .value = 0x380}, + {.description = ""}}, + .default_int = 0x300}, + {.name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .selection = {{.description = "IRQ 3", .value = 3}, + {.description = "IRQ 5", .value = 5}, + {.description = "IRQ 7", .value = 7}, + {.description = "IRQ 10", .value = 10}, + {.description = "IRQ 11", .value = 11}, + {.description = "IRQ 12", .value = 12}, + {.description = ""}}, + .default_int = 10}, + {.type = -1}}; -device_t ne2000_device = - { - "Novell NE2000", - 0, - ne2000_init, - ne2000_close, - NULL, - NULL, - NULL, - NULL, - ne2000_config - }; +device_t ne2000_device = {"Novell NE2000", 0, ne2000_init, ne2000_close, NULL, NULL, NULL, NULL, ne2000_config}; -device_t rtl8029as_device = - { - "Realtek RTL8029AS", - DEVICE_PCI, - rtl8029_init, - ne2000_close, - NULL, - NULL, - NULL, - NULL, - NULL - }; +device_t rtl8029as_device = {"Realtek RTL8029AS", DEVICE_PCI, rtl8029_init, ne2000_close, NULL, NULL, NULL, NULL, NULL}; -//SLIRP stuff -int slirp_can_output(void) { - return net_slirp_inited; -} +// SLIRP stuff +int slirp_can_output(void) { return net_slirp_inited; } void slirp_output(const unsigned char *pkt, int pkt_len) { - struct queuepacket *p; - p = (struct queuepacket *)malloc(sizeof(struct queuepacket)); - p->len = pkt_len; - memcpy(p->data, pkt, pkt_len); - QueueEnter(slirpq, p); + struct queuepacket *p; + p = (struct queuepacket *)malloc(sizeof(struct queuepacket)); + p->len = pkt_len; + memcpy(p->data, pkt, pkt_len); + QueueEnter(slirpq, p); #ifdef NE2000_DEBUG - pclog("ne2000 slirp_output %d @%d\n",pkt_len,p); + pclog("ne2000 slirp_output %d @%d\n", pkt_len, p); #endif } // Instead of calling this and crashing some times -// or experencing jitter, this is called by the +// or experencing jitter, this is called by the // 60Hz clock which seems to do the job. void slirp_tic() { - int ret2, nfds; - struct timeval tv; - fd_set rfds, wfds, xfds; - int timeout; - nfds = -1; + int ret2, nfds; + struct timeval tv; + fd_set rfds, wfds, xfds; + int timeout; + nfds = -1; - if (net_slirp_inited) { - FD_ZERO(&rfds); - FD_ZERO(&wfds); - FD_ZERO(&xfds); - timeout = slirp_select_fill(&nfds, &rfds, &wfds, &xfds); //this can crash + if (net_slirp_inited) { + FD_ZERO(&rfds); + FD_ZERO(&wfds); + FD_ZERO(&xfds); + timeout = slirp_select_fill(&nfds, &rfds, &wfds, &xfds); // this can crash - if (timeout < 0) - timeout = 500; - tv.tv_sec = 0; - tv.tv_usec = timeout; //basilisk default 10000 + if (timeout < 0) + timeout = 500; + tv.tv_sec = 0; + tv.tv_usec = timeout; // basilisk default 10000 - ret2 = select(nfds + 1, &rfds, &wfds, &xfds, &tv); - if (ret2 >= 0) { - slirp_select_poll(&rfds, &wfds, &xfds); - } - //pclog("ne2000 slirp_tic()\n"); - }//end if slirp inited + ret2 = select(nfds + 1, &rfds, &wfds, &xfds, &tv); + if (ret2 >= 0) { + slirp_select_poll(&rfds, &wfds, &xfds); + } + // pclog("ne2000 slirp_tic()\n"); + } // end if slirp inited } diff --git a/src/networking/nethandler.c b/src/networking/nethandler.c index 25201dbd..f135de17 100644 --- a/src/networking/nethandler.c +++ b/src/networking/nethandler.c @@ -27,57 +27,57 @@ NETWORK_CARD n_ne2000 = {"Novell NE2000", "ne2000", &ne2000_device}; NETWORK_CARD n_rtl8029as = {"Realtek RTL8029AS", "rtl8029as", &rtl8029as_device}; int network_card_available(int card) { - if (network_cards[card] != NULL && network_cards[card]->device) - return device_available(network_cards[card]->device); + if (network_cards[card] != NULL && network_cards[card]->device) + return device_available(network_cards[card]->device); - return 1; + return 1; } char *network_card_getname(int card) { - if (network_cards[card] != NULL) - return network_cards[card]->name; - return ""; + if (network_cards[card] != NULL) + return network_cards[card]->name; + return ""; } device_t *network_card_getdevice(int card) { - if (network_cards[card] != NULL) - return network_cards[card]->device; - return NULL; + if (network_cards[card] != NULL) + return network_cards[card]->device; + return NULL; } int network_card_has_config(int card) { - if (network_cards[card] == NULL || !network_cards[card]->device) - return 0; - return network_cards[card]->device->config ? 1 : 0; + if (network_cards[card] == NULL || !network_cards[card]->device) + return 0; + return network_cards[card]->device->config ? 1 : 0; } char *network_card_get_internal_name(int card) { - if (network_cards[card] != NULL) - return network_cards[card]->internal_name; - return ""; + if (network_cards[card] != NULL) + return network_cards[card]->internal_name; + return ""; } int network_card_get_from_internal_name(char *s) { - int c = 0; + int c = 0; - while (network_cards[c] != NULL) { - if (!strcmp(network_cards[c]->internal_name, s)) - return c; - c++; - } + while (network_cards[c] != NULL) { + if (!strcmp(network_cards[c]->internal_name, s)) + return c; + c++; + } - return 0; + return 0; } void network_card_init() { - if (network_cards[network_card_current] != NULL && network_cards[network_card_current]->device) - device_add(network_cards[network_card_current]->device); - network_card_last = network_card_current; + if (network_cards[network_card_current] != NULL && network_cards[network_card_current]->device) + device_add(network_cards[network_card_current]->device); + network_card_last = network_card_current; } static struct { - void (*poller)(void *p); - void *priv; + void (*poller)(void *p); + void *priv; } vlan_handlers[8]; static int vlan_handlers_num; @@ -85,31 +85,31 @@ static int vlan_handlers_num; static pc_timer_t vlan_poller_timer; void vlan_handler(void (*poller)(void *p), void *p) -//void vlan_handler(int (*can_receive)(void *p), void (*receive)(void *p, const uint8_t *buf, int size), void *p) +// void vlan_handler(int (*can_receive)(void *p), void (*receive)(void *p, const uint8_t *buf, int size), void *p) { - /* vlan_handlers[vlan_handlers_num].can_receive = can_receive; */ - vlan_handlers[vlan_handlers_num].poller = poller; - vlan_handlers[vlan_handlers_num].priv = p; - vlan_handlers_num++; + /* vlan_handlers[vlan_handlers_num].can_receive = can_receive; */ + vlan_handlers[vlan_handlers_num].poller = poller; + vlan_handlers[vlan_handlers_num].priv = p; + vlan_handlers_num++; } void vlan_poller(void *priv) { - int c; + int c; - timer_advance_u64(&vlan_poller_timer, (uint64_t)((double)TIMER_USEC * (1000000.0 / 8.0 / 1500.0))); + timer_advance_u64(&vlan_poller_timer, (uint64_t)((double)TIMER_USEC * (1000000.0 / 8.0 / 1500.0))); - for (c = 0; c < vlan_handlers_num; c++) - vlan_handlers[c].poller(vlan_handlers[c].priv); + for (c = 0; c < vlan_handlers_num; c++) + vlan_handlers[c].poller(vlan_handlers[c].priv); } void vlan_reset() { - timer_add(&vlan_poller_timer, vlan_poller, NULL, 1); + timer_add(&vlan_poller_timer, vlan_poller, NULL, 1); - vlan_handlers_num = 0; + vlan_handlers_num = 0; } void network_card_init_builtin() { - pcem_add_networkcard(&n_none); - pcem_add_networkcard(&n_ne2000); - pcem_add_networkcard(&n_rtl8029as); + pcem_add_networkcard(&n_none); + pcem_add_networkcard(&n_ne2000); + pcem_add_networkcard(&n_rtl8029as); } diff --git a/src/networking/slirp/bootp.c b/src/networking/slirp/bootp.c index da67d773..2c50d7e5 100644 --- a/src/networking/slirp/bootp.c +++ b/src/networking/slirp/bootp.c @@ -1,8 +1,8 @@ /* * 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 @@ -32,8 +32,8 @@ #define LEASE_TIME (24 * 3600) typedef struct { - uint8_t allocated; - uint8_t macaddr[6]; + uint8_t allocated; + uint8_t macaddr[6]; } BOOTPClient; BOOTPClient bootp_clients[NB_ADDR]; @@ -41,196 +41,193 @@ 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; + 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; + 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; + 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; + 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; +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; + *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++; + 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; - } - } + 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; + 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); + /* 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 == 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 (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 ((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; - } - } + 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); + 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); + 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_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 */ + 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; + 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) { + *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; + 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_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_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++ = 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; + *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; + 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); + 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 *); + struct bootp_t *bp = mtod(m, struct bootp_t *); - if (bp->bp_op == BOOTP_REQUEST) { - bootp_reply(bp); - } + if (bp->bp_op == BOOTP_REQUEST) { + bootp_reply(bp); + } } diff --git a/src/networking/slirp/cksum.c b/src/networking/slirp/cksum.c index fb9aa7b0..7d88c0c1 100644 --- a/src/networking/slirp/cksum.c +++ b/src/networking/slirp/cksum.c @@ -37,115 +37,120 @@ * * 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);} +#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; + 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; + 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 *); + if (m->m_len == 0) + goto cont; + w = mtod(m, u_int16_t *); - mlen = m->m_len; + mlen = m->m_len; - if (len < mlen) - mlen = len; - len -= mlen; - /* - * Force to even boundary. - */ - if ((1 & (long)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 (len < mlen) + mlen = len; + len -= mlen; + /* + * Force to even boundary. + */ + if ((1 & (long)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 + 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; + mlen = -1; + } else if (mlen == -1) + s_util.c[0] = *(u_int8_t *)w; - cont: +cont: #ifdef SLIRP_DEBUG - if (len) { - DEBUG_ERROR((dfd, "cksum: out of data\n")); - DEBUG_ERROR((dfd, " len = %d\n", len)); - } + 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); + 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/networking/slirp/debug.c b/src/networking/slirp/debug.c index 0047f9eb..126751d5 100644 --- a/src/networking/slirp/debug.c +++ b/src/networking/slirp/debug.c @@ -1,8 +1,8 @@ /* * Copyright (c) 1995 Danny Gasparovski. * Portions copyright (c) 2000 Kelly Price. - * - * Please read the file COPYRIGHT for the + * + * Please read the file COPYRIGHT for the * terms and conditions of the copyright. */ @@ -18,55 +18,50 @@ int slirp_debug = 0; extern char *strerror _P((int)); -/* Carry over one item from main.c so that the tty's restored. +/* 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; +void debug_init(file, dbg) char *file; +int dbg; { - /* Close the old debugging file */ - if (dfd) - fclose(dfd); + /* Close the old debugging file */ + if (dfd) + fclose(dfd); - dfd = fopen(file, "w"); - if (dfd != NULL) { + dfd = fopen(file, "w"); + if (dfd != NULL) { #if 1 - fprintf(dfd, "Slirp %s - Debugging Started.\n", SLIRP_VERSION); + 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)); - } + 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; +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); - } + 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 @@ -128,27 +123,25 @@ allttystats() } #endif -void -ipstats() { - lprint(" \r\n"); +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); + 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 @@ -170,259 +163,219 @@ vjstats() } #endif -void -tcpstats() { - lprint(" \r\n"); +void tcpstats() { + lprint(" \r\n"); - lprint("TCP stats:\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 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 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 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); */ + 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"); +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); + 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 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; +void mbufstats() { + struct SLIRPmbuf *m; + int i; - lprint(" \r\n"); + lprint(" \r\n"); - lprint("Mbuf stats:\r\n"); + lprint("Mbuf stats:\r\n"); - lprint(" %6d mbufs allocated (%d max)\r\n", mbuf_alloced, mbuf_max); + 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_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); + 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; + char buff[256]; + int n; + struct SLIRPsocket *so; - lprint(" \r\n"); + lprint(" \r\n"); - lprint( - "Proto[state] Sock Local Address, Port Remote Address, Port RecvQ SendQ\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) { + 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); + 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) { - 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); - } + 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; + char buff[256]; + int n; + struct SLIRPsocket *so; - printf(" \r\n"); + printf(" \r\n"); - printf( - "Proto[state] Sock Local Address, Port Remote Address, Port RecvQ SendQ\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) { + 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); + 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) { - 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"); + 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.. +// Simple code to purge and close open sockets. +// This way we can open/close/open/close.. void purgesocks(void) { - struct SLIRPsocket *so; + struct SLIRPsocket *so; - for (so = tcb.so_next; so != &tcb; so = so->so_next) { + for (so = tcb.so_next; so != &tcb; so = so->so_next) { - closesocket(so->s); //close the socket - } + closesocket(so->s); // close the socket + } } #if 1 -void -slirp_exit(exit_status) - int exit_status; +void slirp_exit(exit_status) int exit_status; { -// struct ttys *ttyp; + // struct ttys *ttyp; - DEBUG_CALL("slirp_exit"); - DEBUG_ARG("exit_status = %d", exit_status); + 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; + 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(); - } + ipstats(); + tcpstats(); + udpstats(); + icmpstats(); + mbufstats(); + sockstats(); + fclose(dfd); + // allttystats(); + // vjstats(); + } -// for (ttyp = ttys; ttyp; ttyp = ttyp->next) -// tty_detached(ttyp, 1); + // 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()); -// } + // 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(); + /* 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/networking/slirp/if.c b/src/networking/slirp/if.c index c0b56e90..88e651ce 100644 --- a/src/networking/slirp/if.c +++ b/src/networking/slirp/if.c @@ -10,36 +10,31 @@ 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) */ +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 */ +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; +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; + 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; +void ifs_remque(ifm) struct SLIRPmbuf *ifm; { - ifm->ifs_prev->ifs_next = ifm->ifs_next; - ifm->ifs_next->ifs_prev = ifm->ifs_prev; + ifm->ifs_prev->ifs_next = ifm->ifs_next; + ifm->ifs_next->ifs_prev = ifm->ifs_prev; } -void -if_init() { +void if_init() { #if 0 /* * Set if_maxlinkhdr to 48 because it's 40 bytes for TCP/IP, @@ -51,16 +46,16 @@ if_init() { if_maxlinkhdr = 40; #endif #else - /* 2 for alignment, 14 for ethernet, 40 for TCP/IP */ - if_maxlinkhdr = 2 + 14 + 40; + /* 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_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 @@ -144,109 +139,106 @@ if_input(ttyp) /* * if_output: Queue packet into an output queue. - * There are 2 output queue's, if_fastq and if_batchq. + * 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 + * 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; +void if_output(so, ifm) struct SLIRPsocket *so; +struct SLIRPmbuf *ifm; { - struct SLIRPmbuf *ifq; - int on_fastq = 1; + struct SLIRPmbuf *ifq; + int on_fastq = 1; - DEBUG_CALL("if_output"); - DEBUG_ARG("so = %lx", (long)so); - DEBUG_ARG("ifm = %lx", (long)ifm); + 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; - } + /* + * 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; - } - } + /* + * 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; + /* 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); + /* Create a new doubly linked list for this session */ + ifm->ifq_so = so; + ifs_init(ifm); + insque(ifm, ifq); - diddit: - ++if_queued; +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)) { + 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); + /* Remove from current queue... */ + remque(ifm->ifs_next); - /* ...And insert in the new. That'll teach ya! */ - insque(ifm->ifs_next, &if_batchq); - } - } + /* ...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(); - } + /* + * This prevents us from malloc()ing too many SLIRPmbufs + */ + if (link_up) { + /* if_start will check towrite */ + if_start(); + } #endif } @@ -262,59 +254,58 @@ if_output(so, ifm) * 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; +void if_start(void) { + struct SLIRPmbuf *ifm, *ifqt; - DEBUG_CALL("if_start"); + DEBUG_CALL("if_start"); - if (if_queued == 0) - return; /* Nothing to do */ + if (if_queued == 0) + return; /* Nothing to do */ - again: - /* check if we can really output */ - if (!slirp_can_output()) - return; +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; + /* + * 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; + /* 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); - } + /* 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; - } + /* 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); + /* Encapsulate the packet for sending */ + if_encap((uint8_t *)ifm->m_data, ifm->m_len); - m_free(ifm); + m_free(ifm); - if (if_queued) - goto again; + if (if_queued) + goto again; } diff --git a/src/networking/slirp/ip_icmp.c b/src/networking/slirp/ip_icmp.c index 918c0a7f..5d2b1ef7 100644 --- a/src/networking/slirp/ip_icmp.c +++ b/src/networking/slirp/ip_icmp.c @@ -41,142 +41,141 @@ char icmp_ping_msg[] = "This is a psuedo-PING packet used by Slirp to emulate IC /* 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 -}; + /* 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; +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; */ + 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); + DEBUG_CALL("icmp_input"); + DEBUG_ARG("m = %lx", (long)m); + DEBUG_ARG("m_len = %d", m->m_len); - icmpstat.icps_received++; + 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; - } + /* + * 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; + 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; */ + /* 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; + 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; + /* 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 */ + 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; +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 * @@ -191,185 +190,182 @@ icmp_input(m, hlen) * 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 + * 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(msrc, type, code, minsize, message) - struct SLIRPmbuf *msrc; - u_char type; - u_char code; - int minsize; - char *message; +#define ICMP_MAXDATALEN (IP_MSS - 28) +void icmp_error(msrc, type, code, minsize, message) 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; + 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); + 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; + if (type != ICMP_UNREACH && type != ICMP_TIMXCEED) + goto end_error; - /* check msrc */ - if (!msrc) - goto end_error; - ip = mtod(msrc, struct ip *); + /* 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)); - } + { + 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 */ + 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; - } + 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 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 */ + /* 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; + /* fill in icmp */ + m->m_data += hlen; + m->m_len -= hlen; - icp = mtod(m, struct icmp *); + 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; + 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 */ + m->m_len = ICMP_MINLEN + s_ip_len; /* 8 bytes ICMP header */ - /* min. size = 8+sizeof(struct ip)+8 */ + /* min. size = 8+sizeof(struct ip)+8 */ - icp->icmp_type = type; - icp->icmp_code = code; - icp->icmp_id = 0; - icp->icmp_seq = 0; + 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); + 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; - } + 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); + icp->icmp_cksum = 0; + icp->icmp_cksum = cksum(m, m->m_len); - m->m_data -= hlen; - m->m_len += hlen; + 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; + /* 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_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; + 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); + (void)ip_output((struct SLIRPsocket *)NULL, m); - icmpstat.icps_reflect++; + icmpstat.icps_reflect++; - end_error: - return; +end_error: + return; } #undef ICMP_MAXDATALEN /* * Reflect the ip packet back to the source */ -void -icmp_reflect(m) - struct SLIRPmbuf *m; +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; + 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 *); + /* + * 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); + icp->icmp_cksum = 0; + icp->icmp_cksum = cksum(m, ip->ip_len - hlen); - m->m_data -= hlen; - m->m_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; - } + /* 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; - } + 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); + (void)ip_output((struct SLIRPsocket *)NULL, m); - icmpstat.icps_reflect++; + icmpstat.icps_reflect++; } diff --git a/src/networking/slirp/ip_input.c b/src/networking/slirp/ip_input.c index 3226b158..429eea65 100644 --- a/src/networking/slirp/ip_input.c +++ b/src/networking/slirp/ip_input.c @@ -33,7 +33,7 @@ /* * 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. */ @@ -50,180 +50,179 @@ 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.ip_link.next = ipq.ip_link.prev = &ipq.ip_link; - ip_id = tt.tv_sec & 0xffff; - udp_init(); - tcp_init(); - ip_defttl = IPDEFTTL; +void ip_init() { + ipq.ip_link.next = ipq.ip_link.prev = &ipq.ip_link; + 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; +void ip_input(m) struct SLIRPmbuf *m; { - register struct ip *ip; - u_int hlen; + 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); + DEBUG_CALL("ip_input"); + DEBUG_ARG("m = %lx", (long)m); + DEBUG_ARG("m_len = %d", m->m_len); - ipstat.ips_total++; + ipstat.ips_total++; - if (m->m_len < sizeof(struct ip)) { - ipstat.ips_toosmall++; - return; - } + if (m->m_len < sizeof(struct ip)) { + ipstat.ips_toosmall++; + return; + } - ip = mtod(m, struct ip *); + ip = mtod(m, struct ip *); - if (ip->ip_v != IPVERSION) { - ipstat.ips_badvers++; - goto bad; - } + if (ip->ip_v != IPVERSION) { + ipstat.ips_badvers++; + goto bad; + } - hlen = ip->ip_hl << 2; - if (hlen < sizeof(struct ip) || hlen > m->m_len) {/* min header length */ - ipstat.ips_badhlen++; /* or packet too short */ - goto bad; - } + hlen = ip->ip_hl << 2; + if (hlen < sizeof(struct ip) || hlen > m->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; - } + /* 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); + /* + * 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 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; - } + /* 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) { - struct ipq *fp; - struct qlink *l; - /* - * Look for queue of fragments - * of this datagram. - */ - for (l = (struct qlink *)(ipq.ip_link.next); l != &ipq.ip_link; l = (struct qlink *)(l->next)) { - fp = container_of(l, struct ipq, ip_link); - 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 = NULL; - found: + /* + * 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) { + struct ipq *fp; + struct qlink *l; + /* + * Look for queue of fragments + * of this datagram. + */ + for (l = (struct qlink *)(ipq.ip_link.next); l != &ipq.ip_link; l = (struct qlink *)(l->next)) { + fp = container_of(l, struct ipq, ip_link); + 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 = NULL; + 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) - ip->ip_tos |= 1; - else - ip->ip_tos &= ~1; + /* + * 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) + ip->ip_tos |= 1; + else + ip->ip_tos &= ~1; - ip->ip_off <<= 3; + 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 ((ip->ip_tos & 1) || ip->ip_off) { - ipstat.ips_fragments++; - ip = ip_reass(ip, fp); - if (ip == 0) - return; - ipstat.ips_reassembled++; - m = dtom(ip); - } else if (fp) - ip_freef(fp); + /* + * If datagram marked as having more fragments + * or if this is not the first fragment, + * attempt reassembly; if it succeeds, proceed. + */ + if ((ip->ip_tos & 1) || ip->ip_off) { + ipstat.ips_fragments++; + ip = ip_reass(ip, fp); + if (ip == 0) + return; + ipstat.ips_reassembled++; + m = dtom(ip); + } else if (fp) + ip_freef(fp); - } else - ip->ip_len -= hlen; + } 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; + /* + * 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; } -#define iptofrag(P) ((struct ipasfrag *)(((char*)(P)) - sizeof(struct qlink))) -#define fragtoip(P) ((struct ip*)(((char*)(P)) + sizeof(struct qlink))) +#define iptofrag(P) ((struct ipasfrag *)(((char *)(P)) - sizeof(struct qlink))) +#define fragtoip(P) ((struct ip *)(((char *)(P)) + sizeof(struct qlink))) /* * Take incoming datagram fragment and try to @@ -232,200 +231,195 @@ ip_input(m) * is given as fp; otherwise have to make a chain. */ struct ip *ip_reass(struct ip *ip, struct ipq *fp) { - register struct SLIRPmbuf *m = dtom(ip); - register struct ipasfrag *q; - int hlen = ip->ip_hl << 2; - int i, next; + 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); + 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. + /* + * Presence of header sizes in SLIRPmbufs + * would confuse code below. * Fragment m_data is concatenated. - */ - m->m_data += hlen; - m->m_len -= hlen; + */ + 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(&fp->ip_link, &ipq.ip_link); - fp->ipq_ttl = IPFRAGTTL; - fp->ipq_p = ip->ip_p; - fp->ipq_id = ip->ip_id; - fp->frag_link.next = fp->frag_link.prev = &fp->frag_link; - fp->ipq_src = ip->ip_src; - fp->ipq_dst = ip->ip_dst; - q = (struct ipasfrag *)fp; - goto insert; - } + /* + * 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(&fp->ip_link, &ipq.ip_link); + fp->ipq_ttl = IPFRAGTTL; + fp->ipq_p = ip->ip_p; + fp->ipq_id = ip->ip_id; + fp->frag_link.next = fp->frag_link.prev = &fp->frag_link; + fp->ipq_src = ip->ip_src; + fp->ipq_dst = ip->ip_dst; + q = (struct ipasfrag *)fp; + goto insert; + } - /* - * Find a segment which begins after this one does. - */ - for (q = (struct ipasfrag *)fp->frag_link.next; q != (struct ipasfrag *)&fp->frag_link; q = (struct ipasfrag *)(q->ipf_next)) { - if (q->ipf_off > ip->ip_off) - break; - } + /* + * Find a segment which begins after this one does. + */ + for (q = (struct ipasfrag *)fp->frag_link.next; q != (struct ipasfrag *)&fp->frag_link; + q = (struct ipasfrag *)(q->ipf_next)) { + if (q->ipf_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 != &fp->frag_link) { - struct ipasfrag *pq = (struct ipasfrag *)(q->ipf_prev); - i = pq->ipf_off + pq->ipf_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; - } - } + /* + * 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 != &fp->frag_link) { + struct ipasfrag *pq = (struct ipasfrag *)(q->ipf_prev); + i = pq->ipf_off + pq->ipf_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->frag_link && - ip->ip_off + ip->ip_len > q->ipf_off) { - i = (ip->ip_off + ip->ip_len) - q->ipf_off; - if (i < q->ipf_len) { - q->ipf_len -= i; - q->ipf_off += i; - m_adj(dtom(q), i); - break; - } - q = (struct ipasfrag *)(q->ipf_next); - m_freem(dtom(q->ipf_prev)); - ip_deq((struct ipasfrag *)(q->ipf_prev)); - } + /* + * While we overlap succeeding segments trim them or, + * if they are completely covered, dequeue them. + */ + while (q != (struct ipasfrag *)&fp->frag_link && ip->ip_off + ip->ip_len > q->ipf_off) { + i = (ip->ip_off + ip->ip_len) - q->ipf_off; + if (i < q->ipf_len) { + q->ipf_len -= i; + q->ipf_off += i; + m_adj(dtom(q), i); + break; + } + q = (struct ipasfrag *)(q->ipf_next); + m_freem(dtom(q->ipf_prev)); + ip_deq((struct ipasfrag *)(q->ipf_prev)); + } - insert: - /* - * Stick new segment in its place; - * check for complete reassembly. - */ - ip_enq(iptofrag(ip), (struct ipasfrag *)(q->ipf_prev)); - next = 0; - for (q = (struct ipasfrag *)(fp->frag_link.next); q != (struct ipasfrag *)&fp->frag_link; q = (struct ipasfrag *)(q->ipf_next)) { - if (q->ipf_off != next) - return 0; - next += q->ipf_len; - } - if (((struct ipasfrag *)(q->ipf_prev))->ipf_tos & 1) - return (0); +insert: + /* + * Stick new segment in its place; + * check for complete reassembly. + */ + ip_enq(iptofrag(ip), (struct ipasfrag *)(q->ipf_prev)); + next = 0; + for (q = (struct ipasfrag *)(fp->frag_link.next); q != (struct ipasfrag *)&fp->frag_link; + q = (struct ipasfrag *)(q->ipf_next)) { + if (q->ipf_off != next) + return 0; + next += q->ipf_len; + } + if (((struct ipasfrag *)(q->ipf_prev))->ipf_tos & 1) + return (0); - /* - * Reassembly is complete; concatenate fragments. - */ - q = (struct ipasfrag *)(fp->frag_link.next); - m = dtom(q); + /* + * Reassembly is complete; concatenate fragments. + */ + q = (struct ipasfrag *)(fp->frag_link.next); + m = dtom(q); - q = (struct ipasfrag *)q->ipf_next; - while (q != (struct ipasfrag *)&fp->frag_link) { - struct SLIRPmbuf *t = dtom(q); - q = (struct ipasfrag *)q->ipf_next; - m_cat(m, t); - } + q = (struct ipasfrag *)q->ipf_next; + while (q != (struct ipasfrag *)&fp->frag_link) { + struct SLIRPmbuf *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. - */ - q = (struct ipasfrag *)(fp->frag_link.next); + /* + * Create header for new ip packet by + * modifying header of first packet; + * dequeue and discard fragment reassembly header. + * Make header visible. + */ + q = (struct ipasfrag *)(fp->frag_link.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; - q = (struct ipasfrag *)(m->m_ext + delta); - } + /* + * 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; + q = (struct ipasfrag *)(m->m_ext + delta); + } - /* DEBUG_ARG("ip = %lx", (long)ip); - * ip=(struct ipasfrag *)m->m_data; */ + /* DEBUG_ARG("ip = %lx", (long)ip); + * ip=(struct ipasfrag *)m->m_data; */ - ip = fragtoip(q); - ip->ip_len = next; - ip->ip_tos &= ~1; - ip->ip_src = fp->ipq_src; - ip->ip_dst = fp->ipq_dst; - remque(&fp->ip_link); - (void)m_free(dtom(fp)); - m->m_len += (ip->ip_hl << 2); - m->m_data -= (ip->ip_hl << 2); + ip = fragtoip(q); + ip->ip_len = next; + ip->ip_tos &= ~1; + ip->ip_src = fp->ipq_src; + ip->ip_dst = fp->ipq_dst; + remque(&fp->ip_link); + (void)m_free(dtom(fp)); + m->m_len += (ip->ip_hl << 2); + m->m_data -= (ip->ip_hl << 2); - return ip; + return ip; - dropfrag: - ipstat.ips_fragdropped++; - m_freem(m); - return (0); +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; +void ip_freef(fp) struct ipq *fp; { - register struct ipasfrag *q, *p; + register struct ipasfrag *q, *p; - for (q = (struct ipasfrag *)(fp->frag_link.next); q != (struct ipasfrag *)&fp->frag_link; q = p) { - p = (struct ipasfrag *)(q->ipf_next); - ip_deq(q); - m_freem(dtom(q)); - } - remque(&fp->ip_link); - (void)m_free(dtom(fp)); + for (q = (struct ipasfrag *)(fp->frag_link.next); q != (struct ipasfrag *)&fp->frag_link; q = p) { + p = (struct ipasfrag *)(q->ipf_next); + ip_deq(q); + m_freem(dtom(q)); + } + remque(&fp->ip_link); + (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; +void ip_enq(p, prev) register struct ipasfrag *p, *prev; { - DEBUG_CALL("ip_enq"); - DEBUG_ARG("prev = %lx", (long)prev); - p->ipf_prev = prev; - p->ipf_next = prev->ipf_next; - ((struct ipasfrag *)(prev->ipf_next))->ipf_prev = p; - prev->ipf_next = p; + DEBUG_CALL("ip_enq"); + DEBUG_ARG("prev = %lx", (long)prev); + p->ipf_prev = prev; + p->ipf_next = prev->ipf_next; + ((struct ipasfrag *)(prev->ipf_next))->ipf_prev = p; + prev->ipf_next = p; } /* * To ip_enq as remque is to insque. */ -void -ip_deq(p) - register struct ipasfrag *p; +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; + ((struct ipasfrag *)(p->ipf_prev))->ipf_next = p->ipf_next; + ((struct ipasfrag *)(p->ipf_next))->ipf_prev = p->ipf_prev; } /* @@ -434,23 +428,23 @@ ip_deq(p) * queue, discard it. */ void ip_slowtimo() { - struct qlink *l; + struct qlink *l; - DEBUG_CALL("ip_slowtimo"); + DEBUG_CALL("ip_slowtimo"); - l = (struct qlink *)(ipq.ip_link.next); + l = (struct qlink *)(ipq.ip_link.next); - if (l == 0) - return; + if (l == 0) + return; - while (l != &ipq.ip_link) { - struct ipq *fp = container_of(l, struct ipq, ip_link); - l = (struct qlink *)(l->next); - if (--fp->ipq_ttl == 0) { - ipstat.ips_fragtimeout++; - ip_freef(fp); - } - } + while (l != &ipq.ip_link) { + struct ipq *fp = container_of(l, struct ipq, ip_link); + l = (struct qlink *)(l->next); + if (--fp->ipq_ttl == 0) { + ipstat.ips_fragtimeout++; + ip_freef(fp); + } + } } /* @@ -463,199 +457,184 @@ void ip_slowtimo() { #ifdef notdef -int -ip_dooptions(m) - struct SLIRPmbuf *m; +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; + 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) { + 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; + 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; + /* + * 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_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: + 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_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_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; + 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 */ + 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); + /* Not yet */ + icmp_error(m, type, code, 0, 0); - ipstat.ips_badoptions++; - return (1); +ipstat.ips_badoptions++; +return (1); } #endif /* notdef */ @@ -667,21 +646,19 @@ bad: * 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; +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; + 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; + 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; + ip->ip_hl = sizeof(struct ip) >> 2; } diff --git a/src/networking/slirp/ip_output.c b/src/networking/slirp/ip_output.c index 092aa4ce..a27faabf 100644 --- a/src/networking/slirp/ip_output.c +++ b/src/networking/slirp/ip_output.c @@ -48,155 +48,153 @@ u_int16_t ip_id; * 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; +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; + 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); + 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++; + /* 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; - * } - */ + /* + * 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 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; - } + 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; - } + /* + * 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; - } + 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; + { + 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; + /* + * 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)); + /* 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; - } + 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); - } + 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++; - } + if (error == 0) + ipstat.ips_fragmented++; + } - done: - return (error); +done: + return (error); - bad: - m_freem(m0); - goto done; +bad: + m_freem(m0); + goto done; } diff --git a/src/networking/slirp/mbuf.c b/src/networking/slirp/mbuf.c index 46ca3f2d..a3b49210 100644 --- a/src/networking/slirp/mbuf.c +++ b/src/networking/slirp/mbuf.c @@ -26,96 +26,90 @@ 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 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; + /* + * 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; + struct SLIRPmbuf *m; + int flags = 0; - DEBUG_CALL("m_get"); + 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); - } + 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); + /* 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; + /* 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; +// 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); + 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 (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); - - /* 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) */ + /* + * 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) */ } /* @@ -123,125 +117,108 @@ m_free(m) * 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; +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); + /* + * 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; + memcpy(m->m_data + m->m_len, n->m_data, n->m_len); + m->m_len += n->m_len; - m_free(n); + m_free(n); } - /* make m size bytes large */ -void -m_inc(m, size) - struct SLIRPmbuf *m; - int size; +void m_inc(m, size) struct SLIRPmbuf *m; +int size; { - int datasize; + int datasize; - /* some compiles throw up on gotos. This one we can fake. */ - if (m->m_size > size) - return; + /* 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); + 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; + 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; +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; - } + 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; +int m_copy(n, m, off, len) struct SLIRPmbuf *n, *m; +int off, len; { - if (len > M_FREEROOM(n)) - return -1; + 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; + 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 *dtom(dat) void *dat; { - struct SLIRPmbuf *m; + struct SLIRPmbuf *m; - DEBUG_CALL("dtom"); - DEBUG_ARG("dat = %lx", (long)dat); + 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; - } - } + /* 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")); + DEBUG_ERROR((dfd, "dtom failed")); - return (struct SLIRPmbuf *)0; + return (struct SLIRPmbuf *)0; } - diff --git a/src/networking/slirp/misc.c b/src/networking/slirp/misc.c index 4af7df0e..de42d469 100644 --- a/src/networking/slirp/misc.c +++ b/src/networking/slirp/misc.c @@ -1,6 +1,6 @@ /* * Copyright (c) 1995 Danny Gasparovski. - * + * * Please read the file COPYRIGHT for the * terms and conditions of the copyright. */ @@ -10,7 +10,7 @@ #include "slirp/slirp.h" u_int curtime, time_fasttimo, last_slowtimo, detach_time; -u_int detach_wait = 600000; /* 10 minutes */ +u_int detach_wait = 600000; /* 10 minutes */ #if 0 int x_port = -1; @@ -69,109 +69,96 @@ redir_x(inaddr, start_port, display, screen) #endif #ifndef HAVE_INET_ATON -int -inet_aton(cp, ia) - const char *cp; - struct in_addr *ia; +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; + u_int32_t addr = inet_addr(cp); + if (addr == 0xffffffff) + return 0; + ia->s_addr = addr; + return 1; } #endif /* * Get our IP address and put it in our_addr */ -void -getouraddr() { - char buff[512]; - struct hostent *he = NULL; +void getouraddr() { + char buff[512]; + struct hostent *he = NULL; #define ANCIENT #ifdef ANCIENT - if (gethostname((char *)&buff, 500) == 0) - he = gethostbyname((char *)&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; + if (gethostname((char *)&buff, 500) == 0) + he = gethostbyname((char *)&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; + 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 } struct quehead { - struct quehead *qh_link; - struct quehead *qh_rlink; + struct quehead *qh_link; + struct quehead *qh_rlink; }; -void -insque(a, b) - void *a, *b; +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; + 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; +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 ? */ + 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; +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; + 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; - } + /* 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; + 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 @@ -181,98 +168,88 @@ add_exec(ex_ptr, do_pty, exec, addr, port) */ #ifdef WIN32 -//extern int sys_nerr; -//extern char *sys_errlist[]; +// extern int sys_nerr; +// extern char *sys_errlist[]; #endif -char * -SLIRPstrerror(error) - int error; +char *SLIRPstrerror(error) int error; { - if (error < sys_nerr) - return sys_errlist[error]; - else - return "Unknown 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; +int fork_exec(so, ex, do_pty) struct SLIRPsocket *so; +char *ex; +int do_pty; { - /* not implemented */ - return 0; + /* not implemented */ + return 0; } #else -int -slirp_openpty(amaster, aslave) - int *amaster, *aslave; +int slirp_openpty(amaster, aslave) int *amaster, *aslave; { - register int master, slave; + 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; - + 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); + + 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); + (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); + 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 } @@ -282,86 +259,83 @@ slirp_openpty(amaster, aslave) * 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 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]; + 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; + /* 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); + 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 (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); + 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; - } - } + return 0; + } + } - switch(fork()) { - case -1: - lprint("Error: fork failed: %s\n", strerror(errno)); - close(s); - if (do_pty == 2) - close(master); - 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); + case 0: + /* Set the DISPLAY */ + if (do_pty == 2) { + (void)close(master); #ifdef TIOCSCTTY /* XXXXX */ - (void) setsid(); - ioctl(s, TIOCSCTTY, (char *)NULL); + (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); - } + } 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) { @@ -374,87 +348,87 @@ fork_exec(so, ex, do_pty) #endif } #endif - dup2(s, 0); - dup2(s, 1); - dup2(s, 2); - for (s = 3; s <= 255; s++) - close(s); + 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); + 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); + argv[i] = 0; + execvp(argv[0], argv); - /* Ooops, failed, let's tell the user why */ - { - char buff[256]; + /* 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); + 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; - } + 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; +char *strdup(char *str) { + char *bptr; + + bptr = (char *)malloc(strlen(str) + 1); + strcpy(bptr, str); + + return bptr; } #endif @@ -588,11 +562,11 @@ relay(s) } #endif -int (*lprint_print)_P((void *, const char *, va_list)); +int(*lprint_print) _P((void *, const char *, va_list)); char *lprint_ptr, *lprint_ptr2, **lprint_arg; -#ifdef _MSC_VER //aren't we -#define __STDC__ +#ifdef _MSC_VER // aren't we +#define __STDC__ #endif void @@ -602,14 +576,14 @@ lprint(const char *format, ...) lprint(va_alist) va_dcl #endif { - va_list args; + va_list args; #ifdef __STDC__ - va_start(args, format); + va_start(args, format); #else - char *format; - va_start(args); - format = va_arg(args, char *); + 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 */ @@ -633,115 +607,112 @@ lprint(va_alist) va_dcl } } #endif - if (lprint_print) - lprint_ptr += (*lprint_print)(*lprint_arg, format, args); + 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; + /* 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); + 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); + 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; +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; + 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(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(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 (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 (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; - } + 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; - } - } + /* 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; + /* 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; - } - } + /* 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); + lprint("Adding emulation for %s to port %d/%d\r\n", buff1, emup->lport, emup->fport); } #ifdef BAD_SPRINTF @@ -753,14 +724,12 @@ add_emu(buff) * Some BSD-derived systems have a sprintf which returns char * */ -int -vsprintf_len(string, format, args) - char *string; - const char *format; - va_list args; +int vsprintf_len(string, format, args) char *string; +const char *format; +va_list args; { - vsprintf(string, format, args); - return strlen(string); + vsprintf(string, format, args); + return strlen(string); } int @@ -770,72 +739,66 @@ sprintf_len(char *string, const char *format, ...) sprintf_len(va_alist) va_dcl #endif { - va_list args; + va_list args; #ifdef __STDC__ - va_start(args, format); + va_start(args, format); #else - char *string; - char *format; - va_start(args); - string = va_arg(args, char *); - format = va_arg(args, char *); + 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); + vsprintf(string, format, args); + return strlen(string); } #endif -void -u_sleep(usec) - int usec; +void u_sleep(usec) int usec; { - struct timeval t; - fd_set fdset; + struct timeval t; + fd_set fdset; - FD_ZERO(&fdset); + FD_ZERO(&fdset); - t.tv_sec = 0; - t.tv_usec = usec * 1000; + t.tv_sec = 0; + t.tv_usec = usec * 1000; - select(0, &fdset, &fdset, &fdset, &t); + select(0, &fdset, &fdset, &fdset, &t); } /* * Set fd blocking and non-blocking */ -void -fd_nonblock(fd) - int fd; +void fd_nonblock(fd) int fd; { #if defined USE_FIONBIO && defined FIONBIO - ioctlsockopt_t opt = 1; + ioctlsockopt_t opt = 1; - ioctlsocket(fd, FIONBIO, &opt); + ioctlsocket(fd, FIONBIO, &opt); #else - int opt; - - opt = fcntl(fd, F_GETFL, 0); - opt |= O_NONBLOCK; - fcntl(fd, F_SETFL, opt); + int opt; + + opt = fcntl(fd, F_GETFL, 0); + opt |= O_NONBLOCK; + fcntl(fd, F_SETFL, opt); #endif } -void -fd_block(fd) - int fd; +void fd_block(fd) int fd; { #if defined USE_FIONBIO && defined FIONBIO - ioctlsockopt_t opt = 0; + ioctlsockopt_t opt = 0; - ioctlsocket(fd, FIONBIO, &opt); + ioctlsocket(fd, FIONBIO, &opt); #else - int opt; - - opt = fcntl(fd, F_GETFL, 0); - opt &= ~O_NONBLOCK; - fcntl(fd, F_SETFL, opt); + int opt; + + opt = fcntl(fd, F_GETFL, 0); + opt &= ~O_NONBLOCK; + fcntl(fd, F_SETFL, opt); #endif } diff --git a/src/networking/slirp/queue.c b/src/networking/slirp/queue.c index 31b33f22..2ad3472f 100644 --- a/src/networking/slirp/queue.c +++ b/src/networking/slirp/queue.c @@ -16,94 +16,85 @@ * MAX_QUEUE_SIZE = Largest number of items queue can hold. */ -#define MAX_QUEUE_SIZE 100 +#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; + queueElementT contents[MAX_QUEUE_SIZE]; + int front; + int count; } queueCDT; queueADT QueueCreate(void) { - queueADT queue; + queueADT queue; - queue = (queueADT)malloc(sizeof(queueCDT)); + queue = (queueADT)malloc(sizeof(queueCDT)); - if (queue == NULL) { - fprintf(stderr, "Insufficient Memory for new Queue.\n"); - exit(ERROR_MEMORY); /* Exit program, returning error code. */ - } + 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; + queue->front = 0; + queue->count = 0; - return queue; + return queue; } -void QueueDestroy(queueADT queue) { - free(queue); -} +void QueueDestroy(queueADT queue) { free(queue); } void QueueEnter(queueADT queue, queueElementT element) { - int newElementIndex; + int newElementIndex; - if (queue->count >= MAX_QUEUE_SIZE) { -// fprintf(stderr, "QueueEnter on Full Queue.\n"); -// exit(ERROR_QUEUE); /* Exit program, returning error code. */ - return; - } + 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); + /* + * 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++; + queue->count++; } -int QueuePeek(queueADT queue) { - return queue->count; -} +int QueuePeek(queueADT queue) { return queue->count; } queueElementT QueueDelete(queueADT queue) { - queueElementT oldElement; + queueElementT oldElement; - if (queue->count <= 0) { - //fprintf(stderr, "QueueDelete on Empty Queue.\n"); - //exit(ERROR_QUEUE); /* Exit program, returning error code. */ - return NULL; - } + 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]; + /* 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; + /* + * 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); + // printf("dequing @%d [%s]\n",oldElement,oldElement); - queue->count--; + queue->count--; - return oldElement; + return oldElement; } -int QueueIsEmpty(queueADT queue) { - return queue->count <= 0; -} +int QueueIsEmpty(queueADT queue) { return queue->count <= 0; } -int QueueIsFull(queueADT queue) { - return queue->count >= MAX_QUEUE_SIZE; -} +int QueueIsFull(queueADT queue) { return queue->count >= MAX_QUEUE_SIZE; } diff --git a/src/networking/slirp/sbuf.c b/src/networking/slirp/sbuf.c index a96ef84c..d2d1b1b5 100644 --- a/src/networking/slirp/sbuf.c +++ b/src/networking/slirp/sbuf.c @@ -1,7 +1,7 @@ /* * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the + * + * Please read the file COPYRIGHT for the * terms and conditions of the copyright. */ @@ -10,60 +10,51 @@ /* Done as a macro in socket.h */ /* int - * sbspace(struct sockbuff *sb) + * sbspace(struct sockbuff *sb) * { * return SB_DATALEN - sb->sb_cc; * } */ -void -sbfree(sb) - struct sbuf *sb; +void sbfree(sb) struct sbuf *sb; +{ free(sb->sb_data); } + +void sbdrop(sb, num) struct sbuf *sb; +int num; { - free(sb->sb_data); + /* + * 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 -sbdrop(sb, num) - struct sbuf *sb; - int num; +void sbreserve(sb, size) struct sbuf *sb; +int size; { - /* - * 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; - } + 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; + } } /* @@ -72,103 +63,99 @@ sbreserve(sb, size) * 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; +void sbappend(so, m) struct SLIRPsocket *so; +struct SLIRPmbuf *m; { - int ret = 0; + 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); + 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; - } + /* 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; - } + /* + * 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); + /* + * 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); + 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; +void sbappendsb(sb, m) struct sbuf *sb; +struct SLIRPmbuf *m; { - int len, n, nn; + int len, n, nn; - len = m->m_len; + 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; - } - } + 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; + sb->sb_cc += n; + sb->sb_wptr += n; + if (sb->sb_wptr >= sb->sb_data + sb->sb_datalen) + sb->sb_wptr -= sb->sb_datalen; } /* @@ -176,32 +163,29 @@ sbappendsb(sb, m) * 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; +void sbcopy(sb, off, len, to) struct sbuf *sb; +int off; +int len; +char *to; { - char *from; + char *from; - from = sb->sb_rptr + off; - if (from >= sb->sb_data + sb->sb_datalen) - from -= sb->sb_datalen; + 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); - } + 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/networking/slirp/slirp.c b/src/networking/slirp/slirp.c index 075d8310..118a0017 100644 --- a/src/networking/slirp/slirp.c +++ b/src/networking/slirp/slirp.c @@ -12,9 +12,7 @@ struct in_addr special_addr; /* virtual address alias for host */ struct in_addr alias_addr; -const uint8_t special_ethaddr[6] = { - 0x52, 0x54, 0x00, 0x12, 0x35, 0x00 -}; +const uint8_t special_ethaddr[6] = {0x52, 0x54, 0x00, 0x12, 0x35, 0x00}; uint8_t client_ethaddr[6]; @@ -32,35 +30,35 @@ char slirp_hostname[33]; #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; + 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); + 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 (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; - } + 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; + pIPAddr = &(FixedInfo->DnsServerList); + inet_aton(pIPAddr->IpAddress.String, &tmp_addr); + *pdns_addr = tmp_addr; #if 0 printf( "DNS Servers:\n" ); printf( "DNS Addr:%s\n", pIPAddr->IpAddress.String ); @@ -71,595 +69,587 @@ static int get_dns_addr(struct in_addr *pdns_addr) { pIPAddr = pIPAddr ->Next; } #endif - if (FixedInfo) { - GlobalFree(FixedInfo); - FixedInfo = NULL; - } - return 0; + 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; +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; - 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; + 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(); -} +void slirp_cleanup(void) { WSACleanup(); } #endif int slirp_init(void) { #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); + // 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); - } + { + WSADATA Data; + WSAStartup(MAKEWORD(2, 0), &Data); + atexit(slirp_cleanup); + } #endif - link_up = 1; + link_up = 1; - if_init(); - ip_init(); + if_init(); + ip_init(); - /* Initialise mbufs *after* setting the MTU */ - m_init(); + /* Initialise mbufs *after* setting the MTU */ + m_init(); - /* set default addresses */ - inet_aton("127.0.0.1", &loopback_addr); + /* set default addresses */ + inet_aton("127.0.0.1", &loopback_addr); - if (get_dns_addr(&dns_addr) < 0) - return -1; + 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(); - return 0; + inet_aton(CTL_SPECIAL, &special_addr); + alias_addr.s_addr = special_addr.s_addr | htonl(CTL_ALIAS); + getouraddr(); + 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) +#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; + struct _timeb tb; - _ftime(&tb); - curtime = (u_int)tb.time * (u_int)1000; - curtime += (u_int)tb.millitm; + _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++; +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; +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; + /* 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) || (&ipq.ip_link != ipq.ip_link.next)); + 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) || (&ipq.ip_link != ipq.ip_link.next)); - for (so = tcb.so_next; (so != &tcb); so = so_next) { - so_next = so->so_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->t_flags != 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 */ - /* - * See if we need a tcp_fasttimo - */ - if (&so->so_tcpcb->t_flags != 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; + } - /* - * 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 writing sockets which are connecting + */ + if (so->so_state & SS_ISFCONNECTING) { + FD_SET(so->s, writefds); + UPD_NFDS(so->s); + 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 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 writing sockets which are connecting - */ - if (so->so_state & SS_ISFCONNECTING) { - FD_SET(so->s, writefds); - UPD_NFDS(so->s); - continue; - } + /* + * 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); + } + } - /* - * 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); - } + /* + * UDP sockets + */ + for (so = udb.so_next; so != &udb; so = so_next) { + so_next = so->so_next; - /* - * 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); - } - } + /* + * 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 */ + } - /* - * UDP sockets - */ - for (so = udb.so_next; so != &udb; so = so_next) { - so_next = so->so_next; + /* + * 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); + } + } + } - /* - * 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 */ - } + /* + * Setup timeout to use minimum CPU usage, especially when idle + */ - /* - * 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); - } - } - } + timeout = -1; - /* - * Setup timeout to use minimum CPU usage, especially when idle - */ + /* + * 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; - timeout = -1; + /* 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; - /* - * 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; + /* Choose the smallest of the 2 */ + if (tmp_time < timeout) + timeout = tmp_time; + } + } + *pnfds = nfds; - /* 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; + /* + * Adjust the timeout to make the minimum timeout + * 2ms (XXX?) to lessen the CPU load + */ + if (timeout < (FAST_TIMO * 1000)) + timeout = FAST_TIMO * 1000; - /* 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; + return timeout; } void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds) { - struct SLIRPsocket *so, *so_next; - int ret; + struct SLIRPsocket *so, *so_next; + int ret; - global_readfds = readfds; - global_writefds = writefds; - global_xfds = xfds; + global_readfds = readfds; + global_writefds = writefds; + global_xfds = xfds; - /* Update time */ - updtime(); + /* 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; - } - } + /* + * 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; + /* + * 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; + /* + * 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); + /* + * 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)); - } + /* 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; + /* + * 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, &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; + // 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, &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; */ + /* 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 - */ - } + /* + * 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 - */ + /* + * 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 (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 */ + if (ret < 0) { + /* XXX */ + if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINPROGRESS || errno == ENOTCONN) + continue; /* Still connecting, continue */ - /* else failed */ - so->so_state = SS_NOFDREF; + /* else failed */ + so->so_state = SS_NOFDREF; - /* tcp_input will take care of it */ - } else { - ret = send(so->s, &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 */ + /* tcp_input will take care of it */ + } else { + ret = send(so->s, &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; + /* + * 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); - } - } - } + if (so->s != -1 && FD_ISSET(so->s, readfds)) { + sorecvfrom(so); + } + } + } - /* - * See if we can start outputting - */ - if (if_queued && link_up) - if_start(); + /* + * 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; + /* 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 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 */ +#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 */ + 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) */ + 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 */ + /* + * 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; + 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); + 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); + /* 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; - } + 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; + struct SLIRPmbuf *m; + int proto; - if (pkt_len < ETH_HLEN) - return; + 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); + 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; + m->m_data += 2 + ETH_HLEN; + m->m_len -= 2 + ETH_HLEN; - ip_input(m); - break; - default:break; - } + 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; + uint8_t buf[1600]; + struct ethhdr *eh = (struct ethhdr *)buf; - if (ip_data_len + ETH_HLEN > sizeof(buf)) - return; + 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); + 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_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)); +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/networking/slirp/socket.c b/src/networking/slirp/socket.c index e97d81e8..bfcc5fb8 100644 --- a/src/networking/slirp/socket.c +++ b/src/networking/slirp/socket.c @@ -1,7 +1,7 @@ /* * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the + * + * Please read the file COPYRIGHT for the * terms and conditions of the copyright. */ @@ -18,33 +18,25 @@ #include #endif -void -so_init() { - /* Nothing yet */ -} +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 *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; + 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; + 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; } /* @@ -52,42 +44,39 @@ solookup(head, laddr, lport, faddr, fport) * It is the responsibility of the caller to * insque() it into the correct linked-list */ -struct SLIRPsocket * -socreate() { - struct SLIRPsocket *so; +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); + 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; +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_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_m != NULL) + m_free(so->so_m); - if (so->so_next && so->so_prev) - remque(so); /* crashes if so is not in a queue */ + if (so->so_next && so->so_prev) + remque(so); /* crashes if so is not in a queue */ - free(so); + free(so); } /* @@ -95,546 +84,526 @@ sofree(so) * 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 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; + 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; + mss = so->so_tcpcb->t_maxseg; - DEBUG_CALL("soread"); - DEBUG_ARG("so = %lx", (long)so); + 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 - */ + /* + * 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; + 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; - } - } + 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)); + 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); + 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; - } - } + 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; - } + /* + * 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)); + 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; + /* 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; +void sorecvoob(so) struct SLIRPsocket *so; { - struct tcpcb *tp = sototcpcb(so); + struct tcpcb *tp = sototcpcb(so); - DEBUG_CALL("sorecvoob"); - DEBUG_ARG("so = %lx", (long)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; + /* + * 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; +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 */ + struct sbuf *sb = &so->so_rcv; + char buff[2048]; /* XXX Shouldn't be sending more oob data than this */ - int n, len; + int n, len; - DEBUG_CALL("sosendoob"); - DEBUG_ARG("so = %lx", (long)so); - DEBUG_ARG("sb->sb_cc = %d", sb->sb_cc); + 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 (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; + 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)); */ + 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")); + 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)); - } + 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; + 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; + return n; } /* - * Write data from so_rcv to so's socket, + * Write data from so_rcv to so's socket, * updating all sbuf field as necessary */ -int -sowrite(so) - struct SLIRPsocket *so; +int sowrite(so) struct SLIRPsocket *so; { - int n, nn; - struct sbuf *sb = &so->so_rcv; - int len = sb->sb_cc; - struct iovec iov[2]; + 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); + DEBUG_CALL("sowrite"); + DEBUG_ARG("so = %lx", (long)so); - if (so->so_urgc) { - sosendoob(so); - if (sb->sb_cc == 0) - return 0; - } + 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 - */ + /* + * No need to check if there's something to write, + * sowrite wouldn't have been called otherwise + */ - len = sb->sb_cc; + 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 */ + 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; + nn = writev(so->s, (const struct iovec *)iov, n); - 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; - } + 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)); + 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; + /* 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); + /* + * 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; + return nn; } /* * recvfrom() a UDP socket */ -void -sorecvfrom(so) - struct SLIRPsocket *so; +void sorecvfrom(so) struct SLIRPsocket *so; { - struct sockaddr_in addr; - socklen_t addrlen = sizeof(struct sockaddr_in); + struct sockaddr_in addr; + socklen_t addrlen = sizeof(struct sockaddr_in); - DEBUG_CALL("sorecvfrom"); - DEBUG_ARG("so = %lx", (long)so); + 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; + 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"? */ + 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 (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; + 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; + 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; + 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); + /* + * 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); - } - /* } */ + 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; + 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; + 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; - } + 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 (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 */ + /* + * 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 sosendto(so, m) struct SLIRPsocket *so; +struct SLIRPmbuf *m; { - int ret; - struct sockaddr_in addr; + int ret; + struct sockaddr_in addr; - DEBUG_CALL("sosendto"); - DEBUG_ARG("so = %lx", (long)so); - DEBUG_ARG("m = %lx", (long)m); + 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; + 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))); + 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; + /* 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; + /* + * 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 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; + 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); + 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; - } + 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); + /* 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; + /* + * 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 */ + 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; + 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 */ + 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 */ + close(s); + sofree(so); + /* Restore the real errno */ #ifdef _WIN32 - WSASetLastError(tmperrno); + WSASetLastError(tmperrno); #else - errno = tmperrno; + errno = tmperrno; #endif - return NULL; - } - setsockopt(s, SOL_SOCKET, SO_OOBINLINE, (char *)&opt, sizeof(int)); + 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; + 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; + 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; +void sorwakeup(so) struct SLIRPsocket *so; { -/* sowrite(so); */ -/* FD_CLR(so->s,&writefds); */ + /* sowrite(so); */ + /* FD_CLR(so->s,&writefds); */ } /* @@ -642,12 +611,8 @@ sorwakeup(so) * 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 */ -} +void sowwakeup(so) struct SLIRPsocket *so; +{ /* Nothing, yet */ } /* * Various session state calls @@ -655,83 +620,69 @@ sowwakeup(so) * 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; +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 */ + 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; +void soisfconnected(so) register struct SLIRPsocket *so; { - so->so_state &= ~(SS_ISFCONNECTING | SS_FWDRAIN | SS_NOFDREF); - so->so_state |= SS_ISFCONNECTED; /* Clobber other states */ + so->so_state &= ~(SS_ISFCONNECTING | SS_FWDRAIN | SS_NOFDREF); + so->so_state |= SS_ISFCONNECTED; /* Clobber other states */ } -void -sofcantrcvmore(so) - struct SLIRPsocket *so; +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; + 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; +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; + 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; +void soisfdisconnected(so) struct SLIRPsocket *so; { -/* so->so_state &= ~(SS_ISFCONNECTING|SS_ISFCONNECTED); */ -/* close(so->s); */ -/* so->so_state = SS_ISFDISCONNECTED; */ - /* - * XXX Do nothing ... ? - */ + /* 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; +void sofwdrain(so) struct SLIRPsocket *so; { - if (so->so_rcv.sb_cc) - so->so_state |= SS_FWDRAIN; - else - sofcantsendmore(so); + if (so->so_rcv.sb_cc) + so->so_state |= SS_FWDRAIN; + else + sofcantsendmore(so); } - diff --git a/src/networking/slirp/tcp_input.c b/src/networking/slirp/tcp_input.c index 94ec1781..668463d6 100644 --- a/src/networking/slirp/tcp_input.c +++ b/src/networking/slirp/tcp_input.c @@ -33,8 +33,8 @@ /* * Changes and additions relating to SLiRP * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the + * + * Please read the file COPYRIGHT for the * terms and conditions of the copyright. */ @@ -47,13 +47,13 @@ struct SLIRPsocket tcb; int tcprexmtthresh = 3; struct SLIRPsocket *tcp_last_so = &tcb; -tcp_seq tcp_iss; /* tcp initial send seq # */ +tcp_seq tcp_iss; /* tcp initial send seq # */ -#define TCP_PAWS_IDLE (24 * 24 * 60 * 60 * PR_SLOWHZ) +#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) +#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 @@ -66,766 +66,743 @@ tcp_seq tcp_iss; /* tcp initial send seq # */ * 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 && \ - tcpfrag_list_empty(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; \ - } \ -} +#define TCP_REASS(tp, ti, m, so, flags) \ + { \ + if ((ti)->ti_seq == (tp)->rcv_nxt && tcpfrag_list_empty(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 && \ - tcpfrag_list_empty(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; \ - } \ -} +#define TCP_REASS(tp, ti, m, so, flags) \ + { \ + if ((ti)->ti_seq == (tp)->rcv_nxt && tcpfrag_list_empty(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; +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; + 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; + /* + * 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 = tcpfrag_list_first(tp); !tcpfrag_list_end(q, tp); - q = tcpiphdr_next(q)) - if (SEQ_GT(q->ti_seq, ti->ti_seq)) - break; + /* + * Find a segment which begins after this one does. + */ + for (q = tcpfrag_list_first(tp); !tcpfrag_list_end(q, tp); q = tcpiphdr_next(q)) + 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 (!tcpfrag_list_end(tcpiphdr_prev(q), tp)) { - int i; - q = tcpiphdr_prev(q); - /* 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 = tcpiphdr_next(q); - } - tcpstat.tcps_rcvoopack++; - tcpstat.tcps_rcvoobyte += ti->ti_len; - ti->ti_mbuf = (struct mbuf *)m; + /* + * 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 (!tcpfrag_list_end(tcpiphdr_prev(q), tp)) { + int i; + q = tcpiphdr_prev(q); + /* 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 = tcpiphdr_next(q); + } + tcpstat.tcps_rcvoopack++; + tcpstat.tcps_rcvoobyte += ti->ti_len; + ti->ti_mbuf = (struct mbuf *)m; - /* - * While we overlap succeeding segments trim them or, - * if they are completely covered, dequeue them. - */ - while (!tcpfrag_list_end(q, 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 *)q->ti_mbuf, i); - break; - } - q = tcpiphdr_next(q); - m = (struct SLIRPmbuf *)tcpiphdr_prev(q)->ti_mbuf; - remque(tcpiphdr2qlink(tcpiphdr_prev(q))); - m_freem(m); - } + /* + * While we overlap succeeding segments trim them or, + * if they are completely covered, dequeue them. + */ + while (!tcpfrag_list_end(q, 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 *)q->ti_mbuf, i); + break; + } + q = tcpiphdr_next(q); + m = (struct SLIRPmbuf *)tcpiphdr_prev(q)->ti_mbuf; + remque(tcpiphdr2qlink(tcpiphdr_prev(q))); + m_freem(m); + } - /* - * Stick new segment in its place. - */ - insque(tcpiphdr2qlink(ti), tcpiphdr2qlink(tcpiphdr_prev(q))); + /* + * Stick new segment in its place. + */ + insque(tcpiphdr2qlink(ti), tcpiphdr2qlink(tcpiphdr_prev(q))); - present: - /* - * Present data to user, advancing rcv_nxt through - * completed sequence space. - */ - if (!TCPS_HAVEESTABLISHED(tp->t_state)) - return (0); - ti = tcpfrag_list_first(tp); - if (tcpfrag_list_end(ti, 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(tcpiphdr2qlink(ti)); - m = (struct SLIRPmbuf *)ti->ti_mbuf; - ti = tcpiphdr_next(ti); -/* 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); +present: + /* + * Present data to user, advancing rcv_nxt through + * completed sequence space. + */ + if (!TCPS_HAVEESTABLISHED(tp->t_state)) + return (0); + ti = tcpfrag_list_first(tp); + if (tcpfrag_list_end(ti, 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(tcpiphdr2qlink(ti)); + m = (struct SLIRPmbuf *)ti->ti_mbuf; + ti = tcpiphdr_next(ti); + /* 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; +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; */ + 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)); + 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; + /* + * 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; + /* 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; - } + 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 */ + 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; - /* - * 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; + tcpiphdr2qlink(ti)->next = tcpiphdr2qlink(ti)->prev = 0; + memset(&ti->ti_i.ih_mbuf, 0, sizeof(struct mbuf_ptr)); + 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; + } - /* - * Checksum extended TCP header and data. - */ - tlen = ((struct ip *)ti)->ip_len; - tcpiphdr2qlink(ti)->next = tcpiphdr2qlink(ti)->prev = 0; - memset(&ti->ti_i.ih_mbuf, 0, sizeof(struct mbuf_ptr)); - 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); - /* - * 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; - /* - * 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); - /* - * 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); - /* - * 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; + } - /* - * 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 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; + } - 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); - sbreserve(&so->so_snd, tcp_sndspace); - sbreserve(&so->so_rcv, tcp_rcvspace); + /* tcp_last_so = so; */ /* XXX ? */ + /* tp = sototcpcb(so); */ - /* 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; - 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; - if ((so->so_iptos = tcp_tos(so)) == 0) - so->so_iptos = ((struct ip *)ti)->ip_tos; + tp = sototcpcb(so); + tp->t_state = TCPS_LISTEN; + } - 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; - /* - * 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); - tp = sototcpcb(so); + /* XXX Should never fail */ + if (tp == 0) + goto dropwithreset; + if (tp->t_state == TCPS_CLOSED) + goto drop; - /* 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; - /* 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; - /* - * 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); */ - /* - * 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); - /* - * 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; - /* - * 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); - /* - * 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 && tcpfrag_list_empty(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); - return; - } - } else if (ti->ti_ack == tp->snd_una && - tcpfrag_list_empty(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); */ - /* - * 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)); + } - /* - * 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) { - 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 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; - 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 :) + */ - /* - * 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 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 */ - } + { + /* 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 (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; + 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); + 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 (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 (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 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_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; - } + 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; + 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; + /* 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) { - */ /* + 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 @@ -836,731 +813,716 @@ tcp_input(m, iphlen, inso) * * 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; - * } - * } - */ + /* 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; + 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; - } + /* + * 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 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 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) { + /* + * 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_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_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; - } + 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 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; + /* + * 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: + /* + * 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); - } + 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 ... */ + /* 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: + /* + * 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 (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 (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 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 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 << tp->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; + if (cw > tp->snd_ssthresh) + incr = incr * incr / cw; + tp->snd_cwnd = min(cw + incr, TCP_MAXWIN << tp->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) { + 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 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 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 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) */ + /* + * 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; - } +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; + /* + * 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: - } - } 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; + } - /* - * 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 + /* + * 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); + * 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) { + 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; + /* + * 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; + /* + * 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 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; - } - } + /* + * 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; - } + /* + * 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; + /* + * 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; +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); - } +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; + return; - drop: - /* - * Drop space held by incoming segment and return. - */ - m_free(m); +drop: + /* + * Drop space held by incoming segment and return. + */ + m_free(m); - return; + 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; +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; + u_int16_t mss; + int opt, optlen; - DEBUG_CALL("tcp_dooptions"); - DEBUG_ARGS((dfd, " tp = %lx cnt=%i \n", (long)tp, cnt)); + 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) { + 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; + 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_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); - * - */ /* + /* 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; - } - } + /* 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. @@ -1570,31 +1532,29 @@ tcp_dooptions(tp, cp, cnt, ti) #ifdef notdef -void -tcp_pulloutofband(so, ti, m) - struct SLIRPsocket *so; - struct tcpiphdr *ti; - struct SLIRPmbuf *m; +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); + int cnt = ti->ti_urp - 1; - 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"); + 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 */ @@ -1604,78 +1564,75 @@ tcp_pulloutofband(so, ti, m) * and update averages and current timeout. */ -void -tcp_xmit_timer(tp, rtt) - struct tcpcb *tp; - int rtt; +void tcp_xmit_timer(tp, rtt) struct tcpcb *tp; +int rtt; { - short delta; + short delta; - DEBUG_CALL("tcp_xmit_timer"); - DEBUG_ARG("tp = %lx", (long)tp); - DEBUG_ARG("rtt = %d", rtt); + 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; + 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 */ + /* + * 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; + /* + * 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; } /* @@ -1694,31 +1651,29 @@ tcp_xmit_timer(tp, rtt) * parameters from pre-set or cached values in the routing entry. */ -int -tcp_mss(tp, offer) - struct tcpcb *tp; - u_int offer; +int tcp_mss(tp, offer) struct tcpcb *tp; +u_int offer; { - struct SLIRPsocket *so = tp->t_socket; - int mss; + struct SLIRPsocket *so = tp->t_socket; + int mss; - DEBUG_CALL("tcp_mss"); - DEBUG_ARG("tp = %lx", (long)tp); - DEBUG_ARG("offer = %d", offer); + 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; + 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; + 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)); + 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)); + DEBUG_MISC((dfd, " returning mss = %d\n", mss)); - return mss; + return mss; } diff --git a/src/networking/slirp/tcp_output.c b/src/networking/slirp/tcp_output.c index c44871ab..2fe0776b 100644 --- a/src/networking/slirp/tcp_output.c +++ b/src/networking/slirp/tcp_output.c @@ -33,8 +33,8 @@ /* * Changes and additions relating to SLiRP * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the + * + * Please read the file COPYRIGHT for the * terms and conditions of the copyright. */ @@ -45,555 +45,540 @@ * 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", + /* "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, + 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 */ +#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; +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; + 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); + 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); + /* + * 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]; + flags = tcp_outflags[tp->t_state]; - DEBUG_MISC((dfd, " --- tcp_output flags = 0x%x\n", flags)); + 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; - } - } + /* + * 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; + 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 < 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; + 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); + 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; - } + /* + * 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); + /* + * 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; - } + 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; + /* + * 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); - } + /* + * 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++; + /* + * No reason to send a segment, just return. + */ + tcpstat.tcps_didnuttin++; - return (0); + 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; +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; + 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; - * } - */ - } - } + /* 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; + /* + * 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; - } + /* + * 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; - } + /* + * 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; + 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) { */ + /* + * 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; + 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++; + /* } 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; - } + 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 *); + ti = mtod(m, struct tcpiphdr *); - memcpy((SLIRPcaddr_t)ti, &tp->t_template, sizeof(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)); + /* + * 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))); + 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)); + 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 */ + 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)); + /* + * 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; + /* + * 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++; - } - } + /* + * 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; + /* + * 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 */ + /* + * 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_len = m->m_len; - ((struct ip *)ti)->ip_ttl = ip_defttl; - ((struct ip *)ti)->ip_tos = so->so_iptos; + ((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); + /* #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++; + /* #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; + /* + * 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); -} + return (0); + } -void -tcp_setpersist(tp) - struct tcpcb *tp; -{ - int t = ((tp->t_srtt >> 2) + tp->t_rttvar) >> 1; + 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++; -} + /* 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/networking/slirp/tcp_subr.c b/src/networking/slirp/tcp_subr.c index 6a79d40c..7c6ca2c3 100644 --- a/src/networking/slirp/tcp_subr.c +++ b/src/networking/slirp/tcp_subr.c @@ -33,8 +33,8 @@ /* * Changes and additions relating to SLiRP * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the + * + * Please read the file COPYRIGHT for the * terms and conditions of the copyright. */ @@ -45,25 +45,24 @@ /* 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 */ +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; +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; + /* 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)); + /* 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)); } /* @@ -73,30 +72,28 @@ tcp_init() { * necessary when the connection is used. */ /* struct tcpiphdr * */ -void -tcp_template(tp) - struct tcpcb *tp; +void tcp_template(tp) struct tcpcb *tp; { - struct SLIRPsocket *so = tp->t_socket; - struct tcpiphdr *n = &tp->t_template; + struct SLIRPsocket *so = tp->t_socket; + struct tcpiphdr *n = &tp->t_template; - n->ti_mbuf = NULL; - 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_mbuf = NULL; + 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; + 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; } /* @@ -112,79 +109,83 @@ tcp_template(tp) * 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; +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; + 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); + 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; + if (tp) + win = sbspace(&tp->t_socket->so_rcv); + if (m == 0) { + if ((m = m_get()) == NULL) + return; #ifdef TCP_COMPAT_42 - tlen = 1; + tlen = 1; #else - tlen = 0; + 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_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); + 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_len = htons((u_short)(sizeof(struct tcphdr) + tlen)); + tlen += sizeof(struct tcpiphdr); + m->m_len = tlen; - ti->ti_mbuf = 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; + ti->ti_mbuf = 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; + 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); + (void)ip_output((struct SLIRPsocket *)0, m); } /* @@ -192,43 +193,39 @@ tcp_respond(tp, ti, m, ack, seq, flags) * empty reassembly queue and hooking it to the argument * protocol control block. */ -struct tcpcb * -tcp_newtcpcb(so) - struct SLIRPsocket *so; +struct tcpcb *tcp_newtcpcb(so) struct SLIRPsocket *so; { - struct tcpcb *tp; + struct tcpcb *tp; - tp = (struct tcpcb *)malloc(sizeof(*tp)); - if (tp == NULL) - return ((struct tcpcb *)0); + 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 = (struct tcpiphdr *)tp; - tp->t_maxseg = tcp_mssdflt; + memset((char *)tp, 0, sizeof(struct tcpcb)); + tp->seg_next = tp->seg_prev = (struct tcpiphdr *)tp; + tp->t_maxseg = tcp_mssdflt; - tp->t_flags = tcp_do_rfc1323 ? (TF_REQ_SCALE | TF_REQ_TSTMP) : 0; - tp->t_socket = so; + 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; + /* + * 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); + 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; + 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; + so->so_tcpcb = tp; - return (tp); + return (tp); } /* @@ -237,27 +234,27 @@ tcp_newtcpcb(so) * then send a RST to peer. */ struct tcpcb *tcp_drop(struct tcpcb *tp, int err) { -/* tcp_drop(tp, errno) - struct tcpcb *tp; - int errno; -{ -*/ + /* tcp_drop(tp, errno) + struct tcpcb *tp; + int errno; + { + */ - DEBUG_CALL("tcp_drop"); - DEBUG_ARG("tp = %lx", (long)tp); - DEBUG_ARG("errno = %d", 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)); + 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)); } /* @@ -266,48 +263,43 @@ struct tcpcb *tcp_drop(struct tcpcb *tp, int err) { * discard internet protocol block * wake up any sleepers */ -struct tcpcb * -tcp_close(tp) - struct tcpcb *tp; +struct tcpcb *tcp_close(tp) struct tcpcb *tp; { - struct tcpiphdr *t; - struct SLIRPsocket *so = tp->t_socket; - struct SLIRPmbuf *m; + struct tcpiphdr *t; + struct SLIRPsocket *so = tp->t_socket; + struct SLIRPmbuf *m; - DEBUG_CALL("tcp_close"); - DEBUG_ARG("tp = %lx", (long)tp); + DEBUG_CALL("tcp_close"); + DEBUG_ARG("tp = %lx", (long)tp); - /* free the reassembly queue, if any */ - t = tcpfrag_list_first(tp); - while (!tcpfrag_list_end(t, tp)) { - t = tcpiphdr_next(t); - m = (struct SLIRPmbuf *)tcpiphdr_prev(t)->ti_mbuf; - remque(tcpiphdr2qlink(tcpiphdr_prev(t))); - 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); + /* free the reassembly queue, if any */ + t = tcpfrag_list_first(tp); + while (!tcpfrag_list_end(t, tp)) { + t = tcpiphdr_next(t); + m = (struct SLIRPmbuf *)tcpiphdr_prev(t)->ti_mbuf; + remque(tcpiphdr2qlink(tcpiphdr_prev(t))); + 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 */ -} +void tcp_drain() { /* XXX */ } /* * When a source quench is received, close congestion window @@ -316,15 +308,14 @@ tcp_drain() { #ifdef notdef -void -tcp_quench(i, errno) +void tcp_quench(i, errno) - int errno; + int errno; { - struct tcpcb *tp = intotcpcb(inp); + struct tcpcb *tp = intotcpcb(inp); - if (tp) - tp->snd_cwnd = tp->t_maxseg; + if (tp) + tp->snd_cwnd = tp->t_maxseg; } #endif /* notdef */ @@ -343,256 +334,251 @@ tcp_quench(i, errno) * 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; +void tcp_sockclosed(tp) struct tcpcb *tp; { - DEBUG_CALL("tcp_sockclosed"); - DEBUG_ARG("tp = %lx", (long)tp); + DEBUG_CALL("tcp_sockclosed"); + DEBUG_ARG("tp = %lx", (long)tp); - switch (tp->t_state) { + 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_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_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); + 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 + * nonblocking. Connect returns after the SYN is sent, and does * not wait for ACK+SYN. */ -int tcp_fconnect(so) - struct SLIRPsocket *so; +int tcp_fconnect(so) struct SLIRPsocket *so; { - int ret = 0; + int ret = 0; - DEBUG_CALL("tcp_fconnect"); - DEBUG_ARG("so = %lx", (long)so); + 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)); + 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)); + 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; + 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)); + 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); - } + /* + * If it's not in progress, it failed, so we just return 0, + * without clearing SS_NOFDREF + */ + soisfconnecting(so); + } - return (ret); + 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 + * 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; +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; + 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); + 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; - } + /* + * 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); + (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)); + 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; + 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; + /* 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); + so->so_iptos = tcp_tos(so); + tp = sototcpcb(so); - tcp_template(tp); + 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++; - */ + /* 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++; + /* 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); + 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; +int tcp_attach(so) struct SLIRPsocket *so; { - if ((so->so_tcpcb = tcp_newtcpcb(so)) == NULL) - return -1; + if ((so->so_tcpcb = tcp_newtcpcb(so)) == NULL) + return -1; - insque(so, &tcb); + insque(so, &tcb); - return 0; + 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 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; +u_int8_t tcp_tos(so) struct SLIRPsocket *so; { - int i = 0; - struct emu_t *emup; + 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++; - } + 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; - } - } + /* 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; + return 0; } int do_echo = -1; @@ -602,82 +588,77 @@ int do_echo = -1; * 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 + * + * 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; +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; + 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); + DEBUG_CALL("tcp_emu"); + DEBUG_ARG("so = %lx", (long)so); + DEBUG_ARG("m = %lx", (long)m); - switch (so->so_emu) { - int x, i; + switch (so->so_emu) { + int x, i; - case EMU_IDENT: - /* - * Identification protocol as per rfc-1413 - */ + 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; + { + 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; - } + 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: @@ -975,260 +956,252 @@ tcp_emu(so, m) 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; + 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)); + 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; + if ((so = solisten(0, laddr, lport, SS_FACCEPTONCE)) == NULL) + return 1; - n6 = ntohs(so->so_fport); + n6 = ntohs(so->so_fport); - n5 = (n6 >> 8) & 0xff; - n6 &= 0xff; + n5 = (n6 >> 8) & 0xff; + n6 &= 0xff; - laddr = ntohl(so->so_faddr.s_addr); + laddr = ntohl(so->so_faddr.s_addr); - n1 = ((laddr >> 24) & 0xff); - n2 = ((laddr >> 16) & 0xff); - n3 = ((laddr >> 8) & 0xff); - n4 = (laddr & 0xff); + 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; + 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)); + 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; + if ((so = solisten(0, laddr, lport, SS_FACCEPTONCE)) == NULL) + return 1; - n6 = ntohs(so->so_fport); + n6 = ntohs(so->so_fport); - n5 = (n6 >> 8) & 0xff; - n6 &= 0xff; + n5 = (n6 >> 8) & 0xff; + n6 &= 0xff; - laddr = ntohl(so->so_faddr.s_addr); + laddr = ntohl(so->so_faddr.s_addr); - n1 = ((laddr >> 24) & 0xff); - n2 = ((laddr >> 16) & 0xff); - n3 = ((laddr >> 8) & 0xff); - n4 = (laddr & 0xff); + 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 : ""); + 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; + } - 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_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; + 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; + /* 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 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 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; + 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 .......glc..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 .guxc..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. - */ + 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 .......glc..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 .guxc..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]; + 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; + 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; + 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 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 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 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 */ + 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; + /* 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: + ra = 0; + } + ra++; + } + return 1; - default: - /* Ooops, not emulated, won't call tcp_emu again */ - so->so_emu = 0; - return 1; - } + default: + /* Ooops, not emulated, won't call tcp_emu again */ + so->so_emu = 0; + return 1; + } } /* @@ -1236,18 +1209,16 @@ tcp_emu(so, m) * 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; +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; + 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); + DEBUG_CALL("tcp_ctl"); + DEBUG_ARG("so = %lx", (long)so); #if 0 /* @@ -1259,37 +1230,35 @@ tcp_ctl(so) return 0; } #endif - command = (ntohl(so->so_faddr.s_addr) & 0xff); + command = (ntohl(so->so_faddr.s_addr) & 0xff); - switch (command) { - default: /* Check for exec's */ + 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; - } - } + /* + * 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); */ + /* + * 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); + /* 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)); + 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: @@ -1311,5 +1280,5 @@ tcp_ctl(so) do_echo=-1; return(2); #endif - } + } } diff --git a/src/networking/slirp/tcp_timer.c b/src/networking/slirp/tcp_timer.c index fcd88c16..8f81f86d 100644 --- a/src/networking/slirp/tcp_timer.c +++ b/src/networking/slirp/tcp_timer.c @@ -37,29 +37,27 @@ 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 */ +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; +void tcp_fasttimo() { + register struct SLIRPsocket *so; + register struct tcpcb *tp; - DEBUG_CALL("tcp_fasttimo"); + 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); - } + 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); + } } /* @@ -67,251 +65,243 @@ tcp_fasttimo() { * 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; +void tcp_slowtimo() { + register struct SLIRPsocket *ip, *ipnxt; + register struct tcpcb *tp; + register int i; - DEBUG_CALL("tcp_slowtimo"); + 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 */ + 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 */ + if ((int)tcp_iss < 0) + tcp_iss = 0; /* XXX */ #endif - tcp_now++; /* for timestamps */ + tcp_now++; /* for timestamps */ } /* * Cancel all timers for TCP tp. */ -void -tcp_canceltimers(tp) - struct tcpcb *tp; +void tcp_canceltimers(tp) struct tcpcb *tp; { - register int i; + register int i; - for (i = 0; i < TCPT_NTIMERS; i++) - tp->t_timer[i] = 0; + 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}; +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; +struct tcpcb *tcp_timers(tp, timer) struct tcpcb *tp; +int timer; { - int rexmt; + int rexmt; - DEBUG_CALL("tcp_timers"); + DEBUG_CALL("tcp_timers"); - switch (timer) { + 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; + /* + * 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: + /* + * 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. - */ + /* + * 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* - */ + 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 */ - } + 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; + /* + * 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; + /* + * 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; + /* + * 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++; + /* 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); + /* + * 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); + 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; + 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; - } + dropit: + tcpstat.tcps_keepdrops++; + tp = tcp_drop(tp, 0); /* ETIMEDOUT); */ + break; + } - return (tp); + return (tp); } diff --git a/src/networking/slirp/tftp.c b/src/networking/slirp/tftp.c index 195f8777..d94a3397 100644 --- a/src/networking/slirp/tftp.c +++ b/src/networking/slirp/tftp.c @@ -1,8 +1,8 @@ /* * 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 @@ -25,13 +25,13 @@ #include "slirp/slirp.h" struct tftp_session { - int in_use; - char filename[TFTP_FILENAME_MAX]; + int in_use; + char filename[TFTP_FILENAME_MAX]; - struct in_addr client_ip; - u_int16_t client_port; + struct in_addr client_ip; + u_int16_t client_port; - int timestamp; + int timestamp; }; struct tftp_session tftp_sessions[TFTP_SESSIONS_MAX]; @@ -39,279 +39,267 @@ 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; + spt->timestamp = curtime; + spt->in_use = 1; } -static void tftp_session_terminate(struct tftp_session *spt) { - spt->in_use = 0; -} +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; + struct tftp_session *spt; + int k; - for (k = 0; k < TFTP_SESSIONS_MAX; k++) { - spt = &tftp_sessions[k]; + for (k = 0; k < TFTP_SESSIONS_MAX; k++) { + spt = &tftp_sessions[k]; - if (!spt->in_use) - goto found; + if (!spt->in_use) + goto found; - /* sessions time out after 5 inactive seconds */ - if ((int)(curtime - spt->timestamp) > 5000) - goto found; - } + /* sessions time out after 5 inactive seconds */ + if ((int)(curtime - spt->timestamp) > 5000) + goto found; + } - return -1; + 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; +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); + tftp_session_update(spt); - return k; + return k; } static int tftp_session_find(struct tftp_t *tp) { - struct tftp_session *spt; - int k; + struct tftp_session *spt; + int k; - for (k = 0; k < TFTP_SESSIONS_MAX; k++) { - spt = &tftp_sessions[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; - } - } - } - } + 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; + 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; +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; - fd = open(spt->filename, O_RDONLY | O_BINARY); + fd = open(spt->filename, O_RDONLY | O_BINARY); - if (fd < 0) { - return -1; - } + if (fd < 0) { + return -1; + } - if (len) { - lseek(fd, block_nr * 512, SEEK_SET); + if (len) { + lseek(fd, block_nr * 512, SEEK_SET); - bytes_read = read(fd, buf, len); - } + bytes_read = read(fd, buf, len); + } - close(fd); + close(fd); - return bytes_read; + 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; +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; - m = m_get(); + m = m_get(); - if (!m) { - return -1; - } + if (!m) { + return -1; + } - memset(m->m_data, 0, m->m_size); + memset(m->m_data, 0, m->m_size); - m->m_data += if_maxlinkhdr; - tp = (void *)m->m_data; - m->m_data += sizeof(struct udpiphdr); + 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; + 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; + 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; + daddr.sin_addr = spt->client_ip; + daddr.sin_port = spt->client_port; - m->m_len = sizeof(struct tftp_t) - 514 + 3 + strlen(msg) - - sizeof(struct ip) - sizeof(struct udphdr); + 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); + udp_output2(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY); - tftp_session_terminate(spt); + tftp_session_terminate(spt); - return 0; + 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; +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; - } + if (block_nr < 1) { + return -1; + } - m = m_get(); + m = m_get(); - if (!m) { - return -1; - } + if (!m) { + return -1; + } - memset(m->m_data, 0, m->m_size); + memset(m->m_data, 0, m->m_size); - m->m_data += if_maxlinkhdr; - tp = (void *)m->m_data; - m->m_data += sizeof(struct udpiphdr); + 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); + 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; + 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; + 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); + nobytes = tftp_read_data(spt, block_nr - 1, tp->x.tp_data.tp_buf, 512); - if (nobytes < 0) { - m_free(m); + if (nobytes < 0) { + m_free(m); - /* send "file not found" error back */ + /* send "file not found" error back */ - tftp_send_error(spt, 1, "File not found", tp); + tftp_send_error(spt, 1, "File not found", tp); - return -1; - } + return -1; + } - m->m_len = sizeof(struct tftp_t) - (512 - nobytes) - - sizeof(struct ip) - sizeof(struct udphdr); + m->m_len = sizeof(struct tftp_t) - (512 - nobytes) - sizeof(struct ip) - sizeof(struct udphdr); - udp_output2(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY); + udp_output2(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY); - if (nobytes == 512) { - tftp_session_update(spt); - } else { - tftp_session_terminate(spt); - } + if (nobytes == 512) { + tftp_session_update(spt); + } else { + tftp_session_terminate(spt); + } - return 0; + 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; + struct tftp_session *spt; + int s, k, n; + u_int8_t *src, *dst; - s = tftp_session_allocate(tp); + s = tftp_session_allocate(tp); - if (s < 0) { - return; - } + if (s < 0) { + return; + } - spt = &tftp_sessions[s]; + 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); + 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 */ + /* get name */ - for (k = 0; k < n; k++) { - if (k < TFTP_FILENAME_MAX) { - dst[k] = src[k]; - } else { - return; - } + for (k = 0; k < n; k++) { + if (k < TFTP_FILENAME_MAX) { + dst[k] = src[k]; + } else { + return; + } - if (src[k] == '\0') { - break; - } - } + if (src[k] == '\0') { + break; + } + } - if (k >= n) { - return; - } + if (k >= n) { + return; + } - k++; + k++; - /* check mode */ - if ((n - k) < 6) { - return; - } + /* 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; - } + if (memcmp(&src[k], "octet\0", 6) != 0) { + tftp_send_error(spt, 4, "Unsupported transfer mode", tp); + return; + } - /* do sanity checks on the filename */ + /* do sanity checks on the filename */ - if ((spt->filename[0] != '/') - || (spt->filename[strlen(spt->filename) - 1] == '/') - || strstr(spt->filename, "/../")) { - tftp_send_error(spt, 2, "Access violation", tp); - return; - } + if ((spt->filename[0] != '/') || (spt->filename[strlen(spt->filename) - 1] == '/') || strstr(spt->filename, "/../")) { + tftp_send_error(spt, 2, "Access violation", tp); + return; + } - /* only allow exported prefixes */ + /* only allow exported prefixes */ - if (!tftp_prefix - || (strncmp(spt->filename, tftp_prefix, strlen(tftp_prefix)) != 0)) { - tftp_send_error(spt, 2, "Access violation", tp); - return; - } + if (!tftp_prefix || (strncmp(spt->filename, tftp_prefix, strlen(tftp_prefix)) != 0)) { + tftp_send_error(spt, 2, "Access violation", tp); + return; + } - /* check if the file exists */ + /* 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; - } + 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); + tftp_send_data(spt, 1, tp); } static void tftp_handle_ack(struct tftp_t *tp, int pktlen) { - int s; + int s; - s = tftp_session_find(tp); + s = tftp_session_find(tp); - if (s < 0) { - return; - } + if (s < 0) { + return; + } - if (tftp_send_data(&tftp_sessions[s], - ntohs(tp->x.tp_data.tp_block_nr) + 1, - tp) < 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; + 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; + 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; - } + case TFTP_ACK: + tftp_handle_ack(tp, m->m_len); + break; + } } diff --git a/src/networking/slirp/udp.c b/src/networking/slirp/udp.c index b0cf49c0..22ff2691 100644 --- a/src/networking/slirp/udp.c +++ b/src/networking/slirp/udp.c @@ -33,8 +33,8 @@ /* * Changes and additions relating to SLiRP * Copyright (c) 1995 Danny Gasparovski. - * - * Please read the file COPYRIGHT for the + * + * Please read the file COPYRIGHT for the * terms and conditions of the copyright. */ @@ -50,341 +50,322 @@ struct SLIRPsocket udb; * UDP protocol implementation. * Per RFC 768, August, 1980. */ -#ifndef COMPAT_42 +#ifndef COMPAT_42 int udpcksum = 1; #else -int udpcksum = 0; /* XXX */ +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 +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; +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; + 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); + DEBUG_CALL("udp_input"); + DEBUG_ARG("m = %lx", (long)m); + DEBUG_ARG("iphlen = %d", iphlen); - udpstat.udps_ipackets++; + 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); - } + /* + * 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); + /* + * 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); + /* + * 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; - } + 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 */ + /* + * 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) { - memset(&((struct ipovly *)ip)->ih_mbuf, 0, sizeof(struct mbuf_ptr)); - ((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; - } - } + /* + * Checksum extended UDP header and data. + */ + if (udpcksum && uh->uh_sum) { + memset(&((struct ipovly *)ip)->ih_mbuf, 0, sizeof(struct mbuf_ptr)); + ((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; - } + /* + * handle DHCP/BOOTP + */ + if (ntohs(uh->uh_dport) == BOOTP_SERVER) { + bootp_input(m); + goto bad; + } - /* - * handle TFTP - */ - if (ntohs(uh->uh_dport) == TFTP_SERVER) { - tftp_input(m); - goto bad; - } + /* + * handle TFTP + */ + if (ntohs(uh->uh_dport) == TFTP_SERVER) { + tftp_input(m); + goto bad; + } - /* - * 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; + /* + * 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; - } - } + 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; - } + 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; + /* + * 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; + 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. - */ - } + /* + * 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 */ + 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; + 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); + /* + * 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)); - } + 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 */ + 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 */ + /* 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; + 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; +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); + 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); + /* + * 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 *); - memset(&ui->ui_i.ih_mbuf, 0, sizeof(struct mbuf_ptr)); - 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; + /* + * Fill in SLIRPmbuf with extended UDP header + * and addresses and length put into network format. + */ + ui = mtod(m, struct udpiphdr *); + memset(&ui->ui_i.ih_mbuf, 0, sizeof(struct mbuf_ptr)); + 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; + /* + * 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; + ((struct ip *)ui)->ip_ttl = ip_defttl; + ((struct ip *)ui)->ip_tos = iptos; - udpstat.udps_opackets++; + udpstat.udps_opackets++; - error = ip_output(so, m); + error = ip_output(so, m); - return (error); + return (error); } -int udp_output(struct SLIRPsocket *so, struct SLIRPmbuf *m, - struct sockaddr_in *addr) { - struct sockaddr_in saddr, daddr; +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; + 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); + return udp_output2(so, m, &saddr, &daddr, so->so_iptos); } -int -udp_attach(so) - struct SLIRPsocket *so; +int udp_attach(so) struct SLIRPsocket *so; { - struct sockaddr_in addr; + 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; + 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); + WSASetLastError(lasterrno); #else - errno=lasterrno; + errno = lasterrno; #endif - } else { - /* success, insert in queue */ - so->so_expire = curtime + SO_EXPIRE; - insque(so, &udb); - } - } - return (so->s); + } else { + /* success, insert in queue */ + so->so_expire = curtime + SO_EXPIRE; + insque(so, &udb); + } + } + return (so->s); } -void -udp_detach(so) - struct SLIRPsocket *so; +void udp_detach(so) struct SLIRPsocket *so; { - closesocket(so->s); - /* if (so->so_m) m_free(so->so_m); done by sofree */ + closesocket(so->s); + /* if (so->so_m) m_free(so->so_m); done by sofree */ - sofree(so); + 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} -}; +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; +u_int8_t udp_tos(so) struct SLIRPsocket *so; { - int i = 0; + 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++; - } + 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; + return 0; } #ifdef EMULATE_TALK @@ -394,279 +375,268 @@ udp_tos(so) /* * Here, talk/ytalk/ntalk requests must be emulated */ -void -udp_emu(so, m) - struct SLIRPsocket *so; - struct SLIRPmbuf *m; +void udp_emu(so, m) struct SLIRPsocket *so; +struct SLIRPmbuf *m; { - struct sockaddr_in addr; - socklen_t addrlen = sizeof(addr); + 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; + 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; + 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) { + 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; + 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 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 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 */ + /* 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 (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 (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 (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 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; - 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 */ - 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; + } - 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; - /* 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; - /* 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); - 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; + } - 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 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; - 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; - 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); - 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; - 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; + } + } + } + } - /* 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; + return; #endif - case EMU_CUSEEME: + 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; - } + /* + * 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; - } + return; + } } -struct SLIRPsocket * -udp_listen(port, laddr, lport, flags) - u_int port; - u_int32_t laddr; - u_int lport; - int flags; +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; + 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); + 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; + 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)); */ + 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; + 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_lport = lport; + so->so_laddr.s_addr = laddr; + if (flags != SS_FACCEPTONCE) + so->so_expire = 0; - so->so_state = SS_ISFCONNECTED; + so->so_state = SS_ISFCONNECTED; - return so; + return so; } diff --git a/src/pc.c b/src/pc.c index ed560eb2..b3906297 100644 --- a/src/pc.c +++ b/src/pc.c @@ -64,7 +64,7 @@ #ifdef USE_NETWORKING #include "nethandler.h" #include "plugin.h" -#define NE2000 1 +#define NE2000 1 uint8_t ethif; int inum; #endif @@ -99,16 +99,16 @@ uint8_t cgastat; int pollmouse_delay = 2; void pollmouse() { - int x, y, z; -// return; - pollmouse_delay--; - if (pollmouse_delay) - return; - pollmouse_delay = 2; - mouse_poll_host(); - mouse_get_mickeys(&x, &y, &z); - mouse_poll(x, y, z, mouse_buttons); -// if (mousecapture) position_mouse(64,64); + int x, y, z; + // return; + pollmouse_delay--; + if (pollmouse_delay) + return; + pollmouse_delay = 2; + mouse_poll_host(); + mouse_get_mickeys(&x, &y, &z); + mouse_poll(x, y, z, mouse_buttons); + // if (mousecapture) position_mouse(64,64); } /*PC1512 languages - @@ -124,322 +124,320 @@ void pollmouse() { int cpuspeed2; -int clocks[3][12][4] = - { - { - {4772728, 13920, 59660, 5965}, /*4.77MHz*/ - {8000000, 23333, 110000, 0}, /*8MHz*/ - {10000000, 29166, 137500, 0}, /*10MHz*/ - {12000000, 35000, 165000, 0}, /*12MHz*/ - {16000000, 46666, 220000, 0}, /*16MHz*/ - }, - { - {8000000, 23333, 110000, 0}, /*8MHz*/ - {12000000, 35000, 165000, 0}, /*12MHz*/ - {16000000, 46666, 220000, 0}, /*16MHz*/ - {20000000, 58333, 275000, 0}, /*20MHz*/ - {25000000, 72916, 343751, 0}, /*25MHz*/ - }, - { - {16000000, 46666, 220000, 0}, /*16MHz*/ - {20000000, 58333, 275000, 0}, /*20MHz*/ - {25000000, 72916, 343751, 0}, /*25MHz*/ - {33000000, 96000, 454000, 0}, /*33MHz*/ - {40000000, 116666, 550000, 0}, /*40MHz*/ - {50000000, 72916 * 2, 343751 * 2, 0}, /*50MHz*/ - {33000000 * 2, 96000 * 2, 454000 * 2, 0}, /*66MHz*/ - {75000000, 72916 * 3, 343751 * 3, 0}, /*75MHz*/ - {80000000, 116666 * 2, 550000 * 2, 0}, /*80MHz*/ - {100000000, 72916 * 4, 343751 * 4, 0}, /*100MHz*/ - {120000000, 116666 * 3, 550000 * 3, 0}, /*120MHz*/ - {133000000, 96000 * 4, 454000 * 4, 0}, /*133MHz*/ - } - }; +int clocks[3][12][4] = {{ + {4772728, 13920, 59660, 5965}, /*4.77MHz*/ + {8000000, 23333, 110000, 0}, /*8MHz*/ + {10000000, 29166, 137500, 0}, /*10MHz*/ + {12000000, 35000, 165000, 0}, /*12MHz*/ + {16000000, 46666, 220000, 0}, /*16MHz*/ + }, + { + {8000000, 23333, 110000, 0}, /*8MHz*/ + {12000000, 35000, 165000, 0}, /*12MHz*/ + {16000000, 46666, 220000, 0}, /*16MHz*/ + {20000000, 58333, 275000, 0}, /*20MHz*/ + {25000000, 72916, 343751, 0}, /*25MHz*/ + }, + { + {16000000, 46666, 220000, 0}, /*16MHz*/ + {20000000, 58333, 275000, 0}, /*20MHz*/ + {25000000, 72916, 343751, 0}, /*25MHz*/ + {33000000, 96000, 454000, 0}, /*33MHz*/ + {40000000, 116666, 550000, 0}, /*40MHz*/ + {50000000, 72916 * 2, 343751 * 2, 0}, /*50MHz*/ + {33000000 * 2, 96000 * 2, 454000 * 2, 0}, /*66MHz*/ + {75000000, 72916 * 3, 343751 * 3, 0}, /*75MHz*/ + {80000000, 116666 * 2, 550000 * 2, 0}, /*80MHz*/ + {100000000, 72916 * 4, 343751 * 4, 0}, /*100MHz*/ + {120000000, 116666 * 3, 550000 * 3, 0}, /*120MHz*/ + {133000000, 96000 * 4, 454000 * 4, 0}, /*133MHz*/ + }}; int updatestatus; int win_title_update = 0; void onesec() { - fps = framecount; - framecount = 0; - video_refresh_rate = video_frames; - video_frames = 0; - win_title_update = 1; + fps = framecount; + framecount = 0; + video_refresh_rate = video_frames; + video_frames = 0; + win_title_update = 1; } void pc_reset() { - resetx86(); - //timer_reset(); - dma_reset(); - fdc_reset(); - pic_reset(); - serial_reset(); + resetx86(); + // timer_reset(); + dma_reset(); + fdc_reset(); + pic_reset(); + serial_reset(); - if (AT) - setpitclock(models[model]->cpu[cpu_manufacturer].cpus[cpu].rspeed); - else - setpitclock(14318184.0); + if (AT) + setpitclock(models[model]->cpu[cpu_manufacturer].cpus[cpu].rspeed); + else + setpitclock(14318184.0); -// sb_reset(); + // sb_reset(); - ali1429_reset(); -// video_init(); + ali1429_reset(); + // video_init(); } #undef printf void initpc(int argc, char *argv[]) { - //char *p; -// char *config_file = NULL; - int c; + // char *p; + // char *config_file = NULL; + int c; - for (c = 1; c < argc; c++) { - if (!strcasecmp(argv[c], "--help")) { - printf("PCem command line options :\n\n"); - printf("--config file.cfg - use given config file as initial configuration\n"); - printf("--fullscreen - start in fullscreen mode\n"); - printf("--load_drive_a file.img - load drive A: with the given disc image\n"); - printf("--load_drive_b file.img - load drive B: with the given disc image\n"); - exit(-1); - } else if (!strcasecmp(argv[c], "--fullscreen")) { - start_in_fullscreen = 1; - } else if (!strcasecmp(argv[c], "--config")) { - char *ext; + for (c = 1; c < argc; c++) { + if (!strcasecmp(argv[c], "--help")) { + printf("PCem command line options :\n\n"); + printf("--config file.cfg - use given config file as initial configuration\n"); + printf("--fullscreen - start in fullscreen mode\n"); + printf("--load_drive_a file.img - load drive A: with the given disc image\n"); + printf("--load_drive_b file.img - load drive B: with the given disc image\n"); + exit(-1); + } else if (!strcasecmp(argv[c], "--fullscreen")) { + start_in_fullscreen = 1; + } else if (!strcasecmp(argv[c], "--config")) { + char *ext; - if ((c + 1) == argc) - break; - strncpy(config_file_default, argv[c + 1], 256); - strcpy(config_name, get_filename(config_file_default)); + if ((c + 1) == argc) + break; + strncpy(config_file_default, argv[c + 1], 256); + strcpy(config_name, get_filename(config_file_default)); - ext = get_extension(config_name); - if (ext && ext[0]) { - ext--; - *ext = 0; - } + ext = get_extension(config_name); + if (ext && ext[0]) { + ext--; + *ext = 0; + } - config_override = 1; - c++; - } else if (!strcasecmp(argv[c], "--load_drive_a")) { - if ((c + 1) == argc) - break; + config_override = 1; + c++; + } else if (!strcasecmp(argv[c], "--load_drive_a")) { + if ((c + 1) == argc) + break; - strncpy(discfns[0], argv[c + 1], 256); - c++; - override_drive_a = 1; - } else if (!strcasecmp(argv[c], "--load_drive_b")) { - if ((c + 1) == argc) - break; + strncpy(discfns[0], argv[c + 1], 256); + c++; + override_drive_a = 1; + } else if (!strcasecmp(argv[c], "--load_drive_b")) { + if ((c + 1) == argc) + break; - strncpy(discfns[1], argv[c + 1], 256); - c++; - override_drive_b = 1; - } - } + strncpy(discfns[1], argv[c + 1], 256); + c++; + override_drive_b = 1; + } + } -// append_filename(config_file_default, pcempath, "pcem.cfg", 511); + // append_filename(config_file_default, pcempath, "pcem.cfg", 511); - loadconfig(NULL); - pclog("Config loaded\n"); + loadconfig(NULL); + pclog("Config loaded\n"); - load_plugins(); + load_plugins(); -// if (config_file) -// saveconfig(); + // if (config_file) + // saveconfig(); - cpuspeed2 = (AT) ? 2 : 1; -// cpuspeed2=cpuspeed; - atfullspeed = 0; + cpuspeed2 = (AT) ? 2 : 1; + // cpuspeed2=cpuspeed; + atfullspeed = 0; - device_init(); + device_init(); - initvideo(); - mem_init(); - loadbios(); + initvideo(); + mem_init(); + loadbios(); - // this is now done per-model - //mem_add_bios(); + // this is now done per-model + // mem_add_bios(); #if defined(__APPLE__) && defined(__aarch64__) - pthread_jit_write_protect_np(0); + pthread_jit_write_protect_np(0); #endif - codegen_init(); + codegen_init(); #if defined(__APPLE__) && defined(__aarch64__) - pthread_jit_write_protect_np(1); + pthread_jit_write_protect_np(1); #endif - timer_reset(); - sound_reset(); - io_init(); - fdc_init(); - disc_init(); - fdi_init(); - img_init(); + timer_reset(); + sound_reset(); + io_init(); + fdc_init(); + disc_init(); + fdi_init(); + img_init(); #ifdef USE_NETWORKING - vlan_reset(); //NETWORK - network_card_init(network_card_current); + vlan_reset(); // NETWORK + network_card_init(network_card_current); #endif - //loadfont(); - loadnvr(); - resetide(); + // loadfont(); + loadnvr(); + resetide(); #if __unix - if (cdrom_drive == -1) - cdrom_null_open(cdrom_drive); - else + if (cdrom_drive == -1) + cdrom_null_open(cdrom_drive); + else #endif - { - if (cdrom_drive == CDROM_IMAGE) { - FILE *ff = fopen(image_path, "rb"); - if (ff) { - fclose(ff); - image_open(image_path); - } else { + { + if (cdrom_drive == CDROM_IMAGE) { + FILE *ff = fopen(image_path, "rb"); + if (ff) { + fclose(ff); + image_open(image_path); + } else { #if __unix - cdrom_drive = -1; - cdrom_null_open(cdrom_drive); + cdrom_drive = -1; + cdrom_null_open(cdrom_drive); #else - cdrom_drive = 0; - ioctl_set_drive(cdrom_drive); + cdrom_drive = 0; + ioctl_set_drive(cdrom_drive); #endif - } - } else { - ioctl_set_drive(cdrom_drive); - } - } + } + } else { + ioctl_set_drive(cdrom_drive); + } + } -/* if (romset==ROM_AMI386 || romset==ROM_AMI486) */fullspeed(); - ali1429_reset(); -// CPUID=(is486 && (cpuspeed==7 || cpuspeed>=9)); -// pclog("Init - CPUID %i %i\n",CPUID,cpuspeed); + /* if (romset==ROM_AMI386 || romset==ROM_AMI486) */ fullspeed(); + ali1429_reset(); + // CPUID=(is486 && (cpuspeed==7 || cpuspeed>=9)); + // pclog("Init - CPUID %i %i\n",CPUID,cpuspeed); #if __unix - if (cdrom_drive == -1) - cdrom_null_reset(); - else + if (cdrom_drive == -1) + cdrom_null_reset(); + else #endif - { - if (cdrom_drive == CDROM_IMAGE) { - image_reset(); - } else { - ioctl_reset(); - } - } + { + if (cdrom_drive == CDROM_IMAGE) { + image_reset(); + } else { + ioctl_reset(); + } + } } void resetpc() { - cpu_set(); - pc_reset(); - cpu_set_turbo(1); -// cpuspeed2=(AT)?2:1; -// atfullspeed=0; -///* if (romset==ROM_AMI386 || romset==ROM_AMI486) */fullspeed(); + cpu_set(); + pc_reset(); + cpu_set_turbo(1); + // cpuspeed2=(AT)?2:1; + // atfullspeed=0; + ///* if (romset==ROM_AMI386 || romset==ROM_AMI486) */fullspeed(); } void resetpc_cad() { - keyboard_send_scancode(29, 0); /* Ctrl key pressed */ - keyboard_send_scancode(56, 0); /* Alt key pressed */ - keyboard_send_scancode(83, 0); /* Delete key pressed */ - keyboard_send_scancode(29, 1); /* Ctrl key released */ - keyboard_send_scancode(56, 1); /* Alt key released */ - keyboard_send_scancode(83, 1); /* Delete key released */ + keyboard_send_scancode(29, 0); /* Ctrl key pressed */ + keyboard_send_scancode(56, 0); /* Alt key pressed */ + keyboard_send_scancode(83, 0); /* Delete key pressed */ + keyboard_send_scancode(29, 1); /* Ctrl key released */ + keyboard_send_scancode(56, 1); /* Alt key released */ + keyboard_send_scancode(83, 1); /* Delete key released */ } void resetpchard() { - device_close_all(); - mouse_emu_close(); - device_init(); + device_close_all(); + mouse_emu_close(); + device_init(); - timer_reset(); - sound_reset(); - io_init(); - cpu_set(); - mem_alloc(); - fdc_init(); - disc_reset(); - disc_load(0, discfns[0]); - disc_load(1, discfns[1]); + timer_reset(); + sound_reset(); + io_init(); + cpu_set(); + mem_alloc(); + fdc_init(); + disc_reset(); + disc_load(0, discfns[0]); + disc_load(1, discfns[1]); - if (!AT && models[model]->max_ram > 640 && models[model]->max_ram <= 768 && !video_is_ega_vga()) - mem_set_704kb(); - model_init(); - mouse_emu_init(); - video_init(); - speaker_init(); - lpt1_device_init(); + if (!AT && models[model]->max_ram > 640 && models[model]->max_ram <= 768 && !video_is_ega_vga()) + mem_set_704kb(); + model_init(); + mouse_emu_init(); + video_init(); + speaker_init(); + lpt1_device_init(); #ifdef USE_NETWORKING - vlan_reset(); //NETWORK - network_card_init(network_card_current); + vlan_reset(); // NETWORK + network_card_init(network_card_current); #endif - sound_card_init(sound_card_current); - if (GUS) - device_add(&gus_device); - if (GAMEBLASTER) - device_add(&cms_device); - if (SSI2001) - device_add(&ssi2001_device); - if (voodoo_enabled) - device_add(&voodoo_device); - hdd_controller_init(hdd_controller_name); - pc_reset(); + sound_card_init(sound_card_current); + if (GUS) + device_add(&gus_device); + if (GAMEBLASTER) + device_add(&cms_device); + if (SSI2001) + device_add(&ssi2001_device); + if (voodoo_enabled) + device_add(&voodoo_device); + hdd_controller_init(hdd_controller_name); + pc_reset(); - resetide(); + resetide(); - loadnvr(); + loadnvr(); -// cpuspeed2 = (AT)?2:1; -// atfullspeed = 0; -// setpitclock(models[model]->cpu[cpu_manufacturer].cpus[cpu].rspeed); + // cpuspeed2 = (AT)?2:1; + // atfullspeed = 0; + // setpitclock(models[model]->cpu[cpu_manufacturer].cpus[cpu].rspeed); - ali1429_reset(); + ali1429_reset(); - keyboard_at_reset(); + keyboard_at_reset(); - cpu_cache_int_enabled = cpu_cache_ext_enabled = 0; + cpu_cache_int_enabled = cpu_cache_ext_enabled = 0; -// output=3; + // output=3; - image_close(); + image_close(); #if __unix - if (cdrom_drive == -1) - cdrom_null_reset(); - else + if (cdrom_drive == -1) + cdrom_null_reset(); + else #endif - { - if (cdrom_drive == CDROM_IMAGE) { - FILE *ff = fopen(image_path, "rb"); - if (ff) { - fclose(ff); - image_open(image_path); - } else { + { + if (cdrom_drive == CDROM_IMAGE) { + FILE *ff = fopen(image_path, "rb"); + if (ff) { + fclose(ff); + image_open(image_path); + } else { #if __unix - cdrom_drive = -1; - cdrom_null_open(cdrom_drive); + cdrom_drive = -1; + cdrom_null_open(cdrom_drive); #else - cdrom_drive = 0; - ioctl_set_drive(cdrom_drive); + cdrom_drive = 0; + ioctl_set_drive(cdrom_drive); #endif - } - } else { - ioctl_set_drive(cdrom_drive); - ioctl_reset(); - } - } + } + } else { + ioctl_set_drive(cdrom_drive); + ioctl_reset(); + } + } - sound_update_buf_length(); - cpu_set_turbo(1); + sound_update_buf_length(); + cpu_set_turbo(1); - cycles = cycles_main = 0; + cycles = cycles_main = 0; } -char romsets[17][40] = {"IBM PC", "IBM XT", "Generic Turbo XT", "Euro PC", "Tandy 1000", "Amstrad PC1512", "Sinclair PC200", "Amstrad PC1640", "IBM AT", "AMI 286 clone", "Dell System 200", - "Misc 286", "IBM AT 386", "Misc 386", "386 clone", "486 clone", "486 clone 2"}; -char clockspeeds[3][12][16] = - { - {"4.77MHz", "8MHz", "10MHz", "12MHz", "16MHz"}, - {"8MHz", "12MHz", "16MHz", "20MHz", "25MHz"}, - {"16MHz", "20MHz", "25MHz", "33MHz", "40MHz", "50MHz", "66MHz", "75MHz", "80MHz", "100MHz", "120MHz", "133MHz"}, - }; +char romsets[17][40] = {"IBM PC", "IBM XT", "Generic Turbo XT", "Euro PC", "Tandy 1000", + "Amstrad PC1512", "Sinclair PC200", "Amstrad PC1640", "IBM AT", "AMI 286 clone", + "Dell System 200", "Misc 286", "IBM AT 386", "Misc 386", "386 clone", + "486 clone", "486 clone 2"}; +char clockspeeds[3][12][16] = { + {"4.77MHz", "8MHz", "10MHz", "12MHz", "16MHz"}, + {"8MHz", "12MHz", "16MHz", "20MHz", "25MHz"}, + {"16MHz", "20MHz", "25MHz", "33MHz", "40MHz", "50MHz", "66MHz", "75MHz", "80MHz", "100MHz", "120MHz", "133MHz"}, +}; int framecountx = 0; int sndcount = 0; int oldat70hz; @@ -451,136 +449,134 @@ int serial_fifo_read, serial_fifo_write; int emu_fps = 0; #ifdef __APPLE__ -static void _set_window_title(void *s) -{ - set_window_title((const char *)s); - free(s); +static void _set_window_title(void *s) { + set_window_title((const char *)s); + free(s); } #endif void runpc() { - char s[200]; - int done = 0; - int cycles_to_run = cpu_get_speed() / 100; + char s[200]; + int done = 0; + int cycles_to_run = cpu_get_speed() / 100; - override_drive_a = override_drive_b = 0; + override_drive_a = override_drive_b = 0; - startblit(); + startblit(); - if (is386) { - if (cpu_use_dynarec) - exec386_dynarec(cycles_to_run); - else - exec386(cycles_to_run); - } else if (AT) - exec386(cycles_to_run); - else - execx86(cycles_to_run); + if (is386) { + if (cpu_use_dynarec) + exec386_dynarec(cycles_to_run); + else + exec386(cycles_to_run); + } else if (AT) + exec386(cycles_to_run); + else + execx86(cycles_to_run); - keyboard_poll_host(); - keyboard_process(); -// checkkeys(); - pollmouse(); - joystick_poll(); - endblit(); + keyboard_poll_host(); + keyboard_process(); + // checkkeys(); + pollmouse(); + joystick_poll(); + endblit(); - framecountx++; - framecount++; - if (framecountx >= 100) { - pclog("onesec\n"); - framecountx = 0; - mips = (float)insc / 1000000.0f; - insc = 0; - flops = (float)fpucount / 1000000.0f; - fpucount = 0; - sreadlnum = readlnum; - swritelnum = writelnum; - segareads = egareads; - segawrites = egawrites; - scycles_lost = cycles_lost; + framecountx++; + framecount++; + if (framecountx >= 100) { + pclog("onesec\n"); + framecountx = 0; + mips = (float)insc / 1000000.0f; + insc = 0; + flops = (float)fpucount / 1000000.0f; + fpucount = 0; + sreadlnum = readlnum; + swritelnum = writelnum; + segareads = egareads; + segawrites = egawrites; + scycles_lost = cycles_lost; - cpu_recomp_blocks_latched = cpu_recomp_blocks; - cpu_recomp_ins_latched = cpu_state.cpu_recomp_ins; - cpu_recomp_full_ins_latched = cpu_recomp_full_ins; - cpu_new_blocks_latched = cpu_new_blocks; - cpu_recomp_flushes_latched = cpu_recomp_flushes; - cpu_recomp_evicted_latched = cpu_recomp_evicted; - cpu_recomp_reuse_latched = cpu_recomp_reuse; - cpu_recomp_removed_latched = cpu_recomp_removed; + cpu_recomp_blocks_latched = cpu_recomp_blocks; + cpu_recomp_ins_latched = cpu_state.cpu_recomp_ins; + cpu_recomp_full_ins_latched = cpu_recomp_full_ins; + cpu_new_blocks_latched = cpu_new_blocks; + cpu_recomp_flushes_latched = cpu_recomp_flushes; + cpu_recomp_evicted_latched = cpu_recomp_evicted; + cpu_recomp_reuse_latched = cpu_recomp_reuse; + cpu_recomp_removed_latched = cpu_recomp_removed; - cpu_recomp_blocks = 0; - cpu_state.cpu_recomp_ins = 0; - cpu_recomp_full_ins = 0; - cpu_new_blocks = 0; - cpu_recomp_flushes = 0; - cpu_recomp_evicted = 0; - cpu_recomp_reuse = 0; - cpu_recomp_removed = 0; + cpu_recomp_blocks = 0; + cpu_state.cpu_recomp_ins = 0; + cpu_recomp_full_ins = 0; + cpu_new_blocks = 0; + cpu_recomp_flushes = 0; + cpu_recomp_evicted = 0; + cpu_recomp_reuse = 0; + cpu_recomp_removed = 0; - updatestatus = 1; - readlnum = writelnum = 0; - egareads = egawrites = 0; - cycles_lost = 0; - mmuflush = 0; - emu_fps = frames; - frames = 0; - } - if (win_title_update) { - win_title_update = 0; - sprintf(s, - "PCem " PCEM_VERSION_STRING " - %i%% - %s - %s - %s", - fps, - model_getname(), - models[model]->cpu[cpu_manufacturer].cpus[cpu].name, - (!mousecapture) ? "Click to capture mouse" : (( - mouse_get_type(mouse_type) & MOUSE_TYPE_3BUTTON) ? "Press CTRL-END to release mouse" : "Press CTRL-END or middle button to release mouse")); + updatestatus = 1; + readlnum = writelnum = 0; + egareads = egawrites = 0; + cycles_lost = 0; + mmuflush = 0; + emu_fps = frames; + frames = 0; + } + if (win_title_update) { + win_title_update = 0; + sprintf(s, "PCem " PCEM_VERSION_STRING " - %i%% - %s - %s - %s", fps, model_getname(), + models[model]->cpu[cpu_manufacturer].cpus[cpu].name, + (!mousecapture) ? "Click to capture mouse" + : ((mouse_get_type(mouse_type) & MOUSE_TYPE_3BUTTON) + ? "Press CTRL-END to release mouse" + : "Press CTRL-END or middle button to release mouse")); #ifdef __APPLE__ - // Needed due to modifying the UI on the non-main thread is a big no-no. - dispatch_async_f(dispatch_get_main_queue(), strdup(s), _set_window_title); + // Needed due to modifying the UI on the non-main thread is a big no-no. + dispatch_async_f(dispatch_get_main_queue(), strdup(s), _set_window_title); #else - set_window_title(s); + set_window_title(s); #endif - } - done++; + } + done++; } void fullspeed() { - cpuspeed2 = cpuspeed; - if (!atfullspeed) { - pclog("Set fullspeed - %i %i %i\n", is386, AT, cpuspeed2); - if (AT) - setpitclock(models[model]->cpu[cpu_manufacturer].cpus[cpu].rspeed); - else - setpitclock(14318184.0); -// if (is386) setpitclock(clocks[2][cpuspeed2][0]); -// else setpitclock(clocks[AT?1:0][cpuspeed2][0]); - } - atfullspeed = 1; + cpuspeed2 = cpuspeed; + if (!atfullspeed) { + pclog("Set fullspeed - %i %i %i\n", is386, AT, cpuspeed2); + if (AT) + setpitclock(models[model]->cpu[cpu_manufacturer].cpus[cpu].rspeed); + else + setpitclock(14318184.0); + // if (is386) setpitclock(clocks[2][cpuspeed2][0]); + // else setpitclock(clocks[AT?1:0][cpuspeed2][0]); + } + atfullspeed = 1; } void speedchanged() { - if (AT) - setpitclock(models[model]->cpu[cpu_manufacturer].cpus[cpu].rspeed); - else - setpitclock(14318184.0); + if (AT) + setpitclock(models[model]->cpu[cpu_manufacturer].cpus[cpu].rspeed); + else + setpitclock(14318184.0); } void closepc() { - codegen_close(); - atapi->exit(); -// ioctl_close(); - dumppic(); -// output=7; -// setpitclock(clocks[0][0][0]); -// while (1) runpc(); - disc_close(0); - disc_close(1); - dumpregs(); - closevideo(); - lpt1_device_close(); - mouse_emu_close(); - device_close_all(); - zip_eject(); + codegen_close(); + atapi->exit(); + // ioctl_close(); + dumppic(); + // output=7; + // setpitclock(clocks[0][0][0]); + // while (1) runpc(); + disc_close(0); + disc_close(1); + dumpregs(); + closevideo(); + lpt1_device_close(); + mouse_emu_close(); + device_close_all(); + zip_eject(); } /*int main() @@ -596,374 +592,376 @@ void closepc() { END_OF_MAIN();*/ - - void loadconfig(char *fn) { - int c, d; - char s[512]; - char global_config_file[512]; - char *p; + int c, d; + char s[512]; + char global_config_file[512]; + char *p; - append_filename(global_config_file, pcem_path, "pcem.cfg", 511); + append_filename(global_config_file, pcem_path, "pcem.cfg", 511); - config_load(CFG_GLOBAL, global_config_file); + config_load(CFG_GLOBAL, global_config_file); - if (!fn) - config_load(CFG_MACHINE, config_file_default); - else - config_load(CFG_MACHINE, fn); + if (!fn) + config_load(CFG_MACHINE, config_file_default); + else + config_load(CFG_MACHINE, fn); - vid_resize = config_get_int(CFG_GLOBAL, NULL, "vid_resize", 0); - video_force_aspect_ration = config_get_int(CFG_GLOBAL, NULL, "vid_force_aspect_ratio", 0); - vid_disc_indicator = config_get_int(CFG_GLOBAL, NULL, "vid_disc_indicator", 1); - vid_api = config_get_int(CFG_GLOBAL, NULL, "vid_api", 0); - video_fullscreen_scale = config_get_int(CFG_GLOBAL, NULL, "video_fullscreen_scale", 0); - video_fullscreen_first = config_get_int(CFG_GLOBAL, NULL, "video_fullscreen_first", 1); + vid_resize = config_get_int(CFG_GLOBAL, NULL, "vid_resize", 0); + video_force_aspect_ration = config_get_int(CFG_GLOBAL, NULL, "vid_force_aspect_ratio", 0); + vid_disc_indicator = config_get_int(CFG_GLOBAL, NULL, "vid_disc_indicator", 1); + vid_api = config_get_int(CFG_GLOBAL, NULL, "vid_api", 0); + video_fullscreen_scale = config_get_int(CFG_GLOBAL, NULL, "video_fullscreen_scale", 0); + video_fullscreen_first = config_get_int(CFG_GLOBAL, NULL, "video_fullscreen_first", 1); - window_w = config_get_int(CFG_GLOBAL, NULL, "window_w", 0); - window_h = config_get_int(CFG_GLOBAL, NULL, "window_h", 0); - window_x = config_get_int(CFG_GLOBAL, NULL, "window_x", 0); - window_y = config_get_int(CFG_GLOBAL, NULL, "window_y", 0); - window_remember = config_get_int(CFG_GLOBAL, NULL, "window_remember", 0); + window_w = config_get_int(CFG_GLOBAL, NULL, "window_w", 0); + window_h = config_get_int(CFG_GLOBAL, NULL, "window_h", 0); + window_x = config_get_int(CFG_GLOBAL, NULL, "window_x", 0); + window_y = config_get_int(CFG_GLOBAL, NULL, "window_y", 0); + window_remember = config_get_int(CFG_GLOBAL, NULL, "window_remember", 0); - sound_buf_len = config_get_int(CFG_GLOBAL, NULL, "sound_buf_len", 200); - sound_gain = config_get_int(CFG_GLOBAL, NULL, "sound_gain", 0); + sound_buf_len = config_get_int(CFG_GLOBAL, NULL, "sound_buf_len", 200); + sound_gain = config_get_int(CFG_GLOBAL, NULL, "sound_gain", 0); - GAMEBLASTER = config_get_int(CFG_MACHINE, NULL, "gameblaster", 0); - GUS = config_get_int(CFG_MACHINE, NULL, "gus", 0); - SSI2001 = config_get_int(CFG_MACHINE, NULL, "ssi2001", 0); - voodoo_enabled = config_get_int(CFG_MACHINE, NULL, "voodoo", 0); + GAMEBLASTER = config_get_int(CFG_MACHINE, NULL, "gameblaster", 0); + GUS = config_get_int(CFG_MACHINE, NULL, "gus", 0); + SSI2001 = config_get_int(CFG_MACHINE, NULL, "ssi2001", 0); + voodoo_enabled = config_get_int(CFG_MACHINE, NULL, "voodoo", 0); - p = (char *)config_get_string(CFG_MACHINE, NULL, "model", ""); - if (p) - model = model_get_model_from_internal_name(p); - else - model = 0; + p = (char *)config_get_string(CFG_MACHINE, NULL, "model", ""); + if (p) + model = model_get_model_from_internal_name(p); + else + model = 0; - if (model >= model_count()) - model = model_count() - 1; + if (model >= model_count()) + model = model_count() - 1; - romset = model_getromset(); - cpu_manufacturer = config_get_int(CFG_MACHINE, NULL, "cpu_manufacturer", 0); - cpu = config_get_int(CFG_MACHINE, NULL, "cpu", 0); - p = (char *)config_get_string(CFG_MACHINE, NULL, "fpu", "none"); - fpu_type = fpu_get_type(model, cpu_manufacturer, cpu, p); - cpu_use_dynarec = config_get_int(CFG_MACHINE, NULL, "cpu_use_dynarec", 0); - cpu_waitstates = config_get_int(CFG_MACHINE, NULL, "cpu_waitstates", 0); + romset = model_getromset(); + cpu_manufacturer = config_get_int(CFG_MACHINE, NULL, "cpu_manufacturer", 0); + cpu = config_get_int(CFG_MACHINE, NULL, "cpu", 0); + p = (char *)config_get_string(CFG_MACHINE, NULL, "fpu", "none"); + fpu_type = fpu_get_type(model, cpu_manufacturer, cpu, p); + cpu_use_dynarec = config_get_int(CFG_MACHINE, NULL, "cpu_use_dynarec", 0); + cpu_waitstates = config_get_int(CFG_MACHINE, NULL, "cpu_waitstates", 0); - p = (char *)config_get_string(CFG_MACHINE, NULL, "gfxcard", ""); - if (p) - gfxcard = video_get_video_from_internal_name(p); - else - gfxcard = 0; - video_speed = config_get_int(CFG_MACHINE, NULL, "video_speed", -1); - p = (char *)config_get_string(CFG_MACHINE, NULL, "sndcard", ""); - if (p) - sound_card_current = sound_card_get_from_internal_name(p); - else - sound_card_current = 0; + p = (char *)config_get_string(CFG_MACHINE, NULL, "gfxcard", ""); + if (p) + gfxcard = video_get_video_from_internal_name(p); + else + gfxcard = 0; + video_speed = config_get_int(CFG_MACHINE, NULL, "video_speed", -1); + p = (char *)config_get_string(CFG_MACHINE, NULL, "sndcard", ""); + if (p) + sound_card_current = sound_card_get_from_internal_name(p); + else + sound_card_current = 0; - if (!override_drive_a) { - p = (char *)config_get_string(CFG_MACHINE, NULL, "disc_a", ""); - if (p) - strcpy(discfns[0], p); - else - strcpy(discfns[0], ""); - } + if (!override_drive_a) { + p = (char *)config_get_string(CFG_MACHINE, NULL, "disc_a", ""); + if (p) + strcpy(discfns[0], p); + else + strcpy(discfns[0], ""); + } - if (!override_drive_b) { - p = (char *)config_get_string(CFG_MACHINE, NULL, "disc_b", ""); - if (p) - strcpy(discfns[1], p); - else - strcpy(discfns[1], ""); - } + if (!override_drive_b) { + p = (char *)config_get_string(CFG_MACHINE, NULL, "disc_b", ""); + if (p) + strcpy(discfns[1], p); + else + strcpy(discfns[1], ""); + } - p = (char *)config_get_string(CFG_MACHINE, NULL, "hdd_controller", ""); - if (p) - strncpy(hdd_controller_name, p, sizeof(hdd_controller_name) - 1); - else - strncpy(hdd_controller_name, "none", sizeof(hdd_controller_name) - 1); + p = (char *)config_get_string(CFG_MACHINE, NULL, "hdd_controller", ""); + if (p) + strncpy(hdd_controller_name, p, sizeof(hdd_controller_name) - 1); + else + strncpy(hdd_controller_name, "none", sizeof(hdd_controller_name) - 1); - mem_size = config_get_int(CFG_MACHINE, NULL, "mem_size", 4096); - if (mem_size < (((models[model]->flags & MODEL_AT) && models[model]->ram_granularity < 128) ? models[model]->min_ram * 1024 : models[model]->min_ram)) - mem_size = (((models[model]->flags & MODEL_AT) && models[model]->ram_granularity < 128) ? models[model]->min_ram * 1024 : models[model]->min_ram); + mem_size = config_get_int(CFG_MACHINE, NULL, "mem_size", 4096); + if (mem_size < (((models[model]->flags & MODEL_AT) && models[model]->ram_granularity < 128) + ? models[model]->min_ram * 1024 + : models[model]->min_ram)) + mem_size = (((models[model]->flags & MODEL_AT) && models[model]->ram_granularity < 128) + ? models[model]->min_ram * 1024 + : models[model]->min_ram); - cdrom_drive = config_get_int(CFG_MACHINE, NULL, "cdrom_drive", 0); - cdrom_channel = config_get_int(CFG_MACHINE, NULL, "cdrom_channel", 2); + cdrom_drive = config_get_int(CFG_MACHINE, NULL, "cdrom_drive", 0); + cdrom_channel = config_get_int(CFG_MACHINE, NULL, "cdrom_channel", 2); - zip_channel = config_get_int(CFG_MACHINE, NULL, "zip_channel", -1); + zip_channel = config_get_int(CFG_MACHINE, NULL, "zip_channel", -1); - p = (char *)config_get_string(CFG_MACHINE, NULL, "cdrom_path", ""); - if (p) - strcpy(image_path, p); - else - strcpy(image_path, ""); + p = (char *)config_get_string(CFG_MACHINE, NULL, "cdrom_path", ""); + if (p) + strcpy(image_path, p); + else + strcpy(image_path, ""); - hdc[0].spt = config_get_int(CFG_MACHINE, NULL, "hdc_sectors", 0); - hdc[0].hpc = config_get_int(CFG_MACHINE, NULL, "hdc_heads", 0); - hdc[0].tracks = config_get_int(CFG_MACHINE, NULL, "hdc_cylinders", 0); - p = (char *)config_get_string(CFG_MACHINE, NULL, "hdc_fn", ""); - if (p) - strcpy(ide_fn[0], p); - else - strcpy(ide_fn[0], ""); - hdc[1].spt = config_get_int(CFG_MACHINE, NULL, "hdd_sectors", 0); - hdc[1].hpc = config_get_int(CFG_MACHINE, NULL, "hdd_heads", 0); - hdc[1].tracks = config_get_int(CFG_MACHINE, NULL, "hdd_cylinders", 0); - p = (char *)config_get_string(CFG_MACHINE, NULL, "hdd_fn", ""); - if (p) - strcpy(ide_fn[1], p); - else - strcpy(ide_fn[1], ""); - hdc[2].spt = config_get_int(CFG_MACHINE, NULL, "hde_sectors", 0); - hdc[2].hpc = config_get_int(CFG_MACHINE, NULL, "hde_heads", 0); - hdc[2].tracks = config_get_int(CFG_MACHINE, NULL, "hde_cylinders", 0); - p = (char *)config_get_string(CFG_MACHINE, NULL, "hde_fn", ""); - if (p) - strcpy(ide_fn[2], p); - else - strcpy(ide_fn[2], ""); - hdc[3].spt = config_get_int(CFG_MACHINE, NULL, "hdf_sectors", 0); - hdc[3].hpc = config_get_int(CFG_MACHINE, NULL, "hdf_heads", 0); - hdc[3].tracks = config_get_int(CFG_MACHINE, NULL, "hdf_cylinders", 0); - p = (char *)config_get_string(CFG_MACHINE, NULL, "hdf_fn", ""); - if (p) - strcpy(ide_fn[3], p); - else - strcpy(ide_fn[3], ""); - hdc[4].spt = config_get_int(CFG_MACHINE, NULL, "hdg_sectors", 0); - hdc[4].hpc = config_get_int(CFG_MACHINE, NULL, "hdg_heads", 0); - hdc[4].tracks = config_get_int(CFG_MACHINE, NULL, "hdg_cylinders", 0); - p = (char *)config_get_string(CFG_MACHINE, NULL, "hdg_fn", ""); - if (p) - strcpy(ide_fn[4], p); - else - strcpy(ide_fn[4], ""); - hdc[5].spt = config_get_int(CFG_MACHINE, NULL, "hdh_sectors", 0); - hdc[5].hpc = config_get_int(CFG_MACHINE, NULL, "hdh_heads", 0); - hdc[5].tracks = config_get_int(CFG_MACHINE, NULL, "hdh_cylinders", 0); - p = (char *)config_get_string(CFG_MACHINE, NULL, "hdh_fn", ""); - if (p) - strcpy(ide_fn[5], p); - else - strcpy(ide_fn[5], ""); - hdc[6].spt = config_get_int(CFG_MACHINE, NULL, "hdi_sectors", 0); - hdc[6].hpc = config_get_int(CFG_MACHINE, NULL, "hdi_heads", 0); - hdc[6].tracks = config_get_int(CFG_MACHINE, NULL, "hdi_cylinders", 0); - p = (char *)config_get_string(CFG_MACHINE, NULL, "hdi_fn", ""); - if (p) - strcpy(ide_fn[6], p); - else - strcpy(ide_fn[6], ""); + hdc[0].spt = config_get_int(CFG_MACHINE, NULL, "hdc_sectors", 0); + hdc[0].hpc = config_get_int(CFG_MACHINE, NULL, "hdc_heads", 0); + hdc[0].tracks = config_get_int(CFG_MACHINE, NULL, "hdc_cylinders", 0); + p = (char *)config_get_string(CFG_MACHINE, NULL, "hdc_fn", ""); + if (p) + strcpy(ide_fn[0], p); + else + strcpy(ide_fn[0], ""); + hdc[1].spt = config_get_int(CFG_MACHINE, NULL, "hdd_sectors", 0); + hdc[1].hpc = config_get_int(CFG_MACHINE, NULL, "hdd_heads", 0); + hdc[1].tracks = config_get_int(CFG_MACHINE, NULL, "hdd_cylinders", 0); + p = (char *)config_get_string(CFG_MACHINE, NULL, "hdd_fn", ""); + if (p) + strcpy(ide_fn[1], p); + else + strcpy(ide_fn[1], ""); + hdc[2].spt = config_get_int(CFG_MACHINE, NULL, "hde_sectors", 0); + hdc[2].hpc = config_get_int(CFG_MACHINE, NULL, "hde_heads", 0); + hdc[2].tracks = config_get_int(CFG_MACHINE, NULL, "hde_cylinders", 0); + p = (char *)config_get_string(CFG_MACHINE, NULL, "hde_fn", ""); + if (p) + strcpy(ide_fn[2], p); + else + strcpy(ide_fn[2], ""); + hdc[3].spt = config_get_int(CFG_MACHINE, NULL, "hdf_sectors", 0); + hdc[3].hpc = config_get_int(CFG_MACHINE, NULL, "hdf_heads", 0); + hdc[3].tracks = config_get_int(CFG_MACHINE, NULL, "hdf_cylinders", 0); + p = (char *)config_get_string(CFG_MACHINE, NULL, "hdf_fn", ""); + if (p) + strcpy(ide_fn[3], p); + else + strcpy(ide_fn[3], ""); + hdc[4].spt = config_get_int(CFG_MACHINE, NULL, "hdg_sectors", 0); + hdc[4].hpc = config_get_int(CFG_MACHINE, NULL, "hdg_heads", 0); + hdc[4].tracks = config_get_int(CFG_MACHINE, NULL, "hdg_cylinders", 0); + p = (char *)config_get_string(CFG_MACHINE, NULL, "hdg_fn", ""); + if (p) + strcpy(ide_fn[4], p); + else + strcpy(ide_fn[4], ""); + hdc[5].spt = config_get_int(CFG_MACHINE, NULL, "hdh_sectors", 0); + hdc[5].hpc = config_get_int(CFG_MACHINE, NULL, "hdh_heads", 0); + hdc[5].tracks = config_get_int(CFG_MACHINE, NULL, "hdh_cylinders", 0); + p = (char *)config_get_string(CFG_MACHINE, NULL, "hdh_fn", ""); + if (p) + strcpy(ide_fn[5], p); + else + strcpy(ide_fn[5], ""); + hdc[6].spt = config_get_int(CFG_MACHINE, NULL, "hdi_sectors", 0); + hdc[6].hpc = config_get_int(CFG_MACHINE, NULL, "hdi_heads", 0); + hdc[6].tracks = config_get_int(CFG_MACHINE, NULL, "hdi_cylinders", 0); + p = (char *)config_get_string(CFG_MACHINE, NULL, "hdi_fn", ""); + if (p) + strcpy(ide_fn[6], p); + else + strcpy(ide_fn[6], ""); - fdd_set_type(0, config_get_int(CFG_MACHINE, NULL, "drive_a_type", 7)); - fdd_set_type(1, config_get_int(CFG_MACHINE, NULL, "drive_b_type", 7)); - bpb_disable = config_get_int(CFG_MACHINE, NULL, "bpb_disable", 0); + fdd_set_type(0, config_get_int(CFG_MACHINE, NULL, "drive_a_type", 7)); + fdd_set_type(1, config_get_int(CFG_MACHINE, NULL, "drive_b_type", 7)); + bpb_disable = config_get_int(CFG_MACHINE, NULL, "bpb_disable", 0); - cd_speed = config_get_int(CFG_MACHINE, NULL, "cd_speed", 24); - cd_model = cd_model_from_config((char *)config_get_string(CFG_MACHINE, NULL, "cd_model", cd_get_config_model(0))); + cd_speed = config_get_int(CFG_MACHINE, NULL, "cd_speed", 24); + cd_model = cd_model_from_config((char *)config_get_string(CFG_MACHINE, NULL, "cd_model", cd_get_config_model(0))); - joystick_type = config_get_int(CFG_MACHINE, NULL, "joystick_type", 0); - mouse_type = config_get_int(CFG_MACHINE, NULL, "mouse_type", 0); + joystick_type = config_get_int(CFG_MACHINE, NULL, "joystick_type", 0); + mouse_type = config_get_int(CFG_MACHINE, NULL, "mouse_type", 0); - for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) { - sprintf(s, "joystick_%i_nr", c); - joystick_state[c].plat_joystick_nr = config_get_int(CFG_MACHINE, "Joysticks", s, 0); + for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) { + sprintf(s, "joystick_%i_nr", c); + joystick_state[c].plat_joystick_nr = config_get_int(CFG_MACHINE, "Joysticks", s, 0); - if (joystick_state[c].plat_joystick_nr) { - for (d = 0; d < joystick_get_axis_count(joystick_type); d++) { - sprintf(s, "joystick_%i_axis_%i", c, d); - joystick_state[c].axis_mapping[d] = config_get_int(CFG_MACHINE, "Joysticks", s, d); - } - for (d = 0; d < joystick_get_button_count(joystick_type); d++) { - sprintf(s, "joystick_%i_button_%i", c, d); - joystick_state[c].button_mapping[d] = config_get_int(CFG_MACHINE, "Joysticks", s, d); - } - for (d = 0; d < joystick_get_pov_count(joystick_type); d++) { - sprintf(s, "joystick_%i_pov_%i_x", c, d); - joystick_state[c].pov_mapping[d][0] = config_get_int(CFG_MACHINE, "Joysticks", s, d); - sprintf(s, "joystick_%i_pov_%i_y", c, d); - joystick_state[c].pov_mapping[d][1] = config_get_int(CFG_MACHINE, "Joysticks", s, d); - } - } - } + if (joystick_state[c].plat_joystick_nr) { + for (d = 0; d < joystick_get_axis_count(joystick_type); d++) { + sprintf(s, "joystick_%i_axis_%i", c, d); + joystick_state[c].axis_mapping[d] = config_get_int(CFG_MACHINE, "Joysticks", s, d); + } + for (d = 0; d < joystick_get_button_count(joystick_type); d++) { + sprintf(s, "joystick_%i_button_%i", c, d); + joystick_state[c].button_mapping[d] = config_get_int(CFG_MACHINE, "Joysticks", s, d); + } + for (d = 0; d < joystick_get_pov_count(joystick_type); d++) { + sprintf(s, "joystick_%i_pov_%i_x", c, d); + joystick_state[c].pov_mapping[d][0] = config_get_int(CFG_MACHINE, "Joysticks", s, d); + sprintf(s, "joystick_%i_pov_%i_y", c, d); + joystick_state[c].pov_mapping[d][1] = config_get_int(CFG_MACHINE, "Joysticks", s, d); + } + } + } - enable_sync = config_get_int(CFG_MACHINE, NULL, "enable_sync", 1); + enable_sync = config_get_int(CFG_MACHINE, NULL, "enable_sync", 1); - p = (char *)config_get_string(CFG_MACHINE, NULL, "lpt1_device", ""); - if (p) - strcpy(lpt1_device_name, p); - else - strcpy(lpt1_device_name, ""); - if (p) - lpt1_current = lpt_device_get_from_internal_name(p); - else - lpt1_current = 0; + p = (char *)config_get_string(CFG_MACHINE, NULL, "lpt1_device", ""); + if (p) + strcpy(lpt1_device_name, p); + else + strcpy(lpt1_device_name, ""); + if (p) + lpt1_current = lpt_device_get_from_internal_name(p); + else + lpt1_current = 0; #ifdef USE_NETWORKING - //network - ethif = config_get_int(CFG_GLOBAL, NULL, "netinterface", 1); - if (ethif >= inum) - inum = ethif + 1; + // network + ethif = config_get_int(CFG_GLOBAL, NULL, "netinterface", 1); + if (ethif >= inum) + inum = ethif + 1; - p = (char*)config_get_string(CFG_MACHINE, NULL, "netcard", ""); - if (p) - network_card_current = network_card_get_from_internal_name(p); - else - network_card_current = 0; + p = (char *)config_get_string(CFG_MACHINE, NULL, "netcard", ""); + if (p) + network_card_current = network_card_get_from_internal_name(p); + else + network_card_current = 0; #endif - for (d = 0; d < num_config_callbacks; ++d) - if (config_callbacks[d].loadconfig) - config_callbacks[d].loadconfig(); + for (d = 0; d < num_config_callbacks; ++d) + if (config_callbacks[d].loadconfig) + config_callbacks[d].loadconfig(); - for (d = 0; d < num_config_callbacks; ++d) - if (config_callbacks[d].onloaded) - config_callbacks[d].onloaded(); + for (d = 0; d < num_config_callbacks; ++d) + if (config_callbacks[d].onloaded) + config_callbacks[d].onloaded(); - config_dump(CFG_GLOBAL); - config_dump(CFG_MACHINE); + config_dump(CFG_GLOBAL); + config_dump(CFG_MACHINE); } void saveconfig(char *fn) { - int c, d; - char global_config_file[512]; + int c, d; + char global_config_file[512]; - append_filename(global_config_file, pcem_path, "pcem.cfg", 511); + append_filename(global_config_file, pcem_path, "pcem.cfg", 511); - config_set_int(CFG_GLOBAL, NULL, "vid_resize", vid_resize); - config_set_int(CFG_GLOBAL, NULL, "vid_force_aspect_ratio", video_force_aspect_ration); - config_set_int(CFG_GLOBAL, NULL, "vid_disc_indicator", vid_disc_indicator); - config_set_int(CFG_GLOBAL, NULL, "vid_api", vid_api); - config_set_int(CFG_GLOBAL, NULL, "video_fullscreen_scale", video_fullscreen_scale); - config_set_int(CFG_GLOBAL, NULL, "video_fullscreen_first", video_fullscreen_first); + config_set_int(CFG_GLOBAL, NULL, "vid_resize", vid_resize); + config_set_int(CFG_GLOBAL, NULL, "vid_force_aspect_ratio", video_force_aspect_ration); + config_set_int(CFG_GLOBAL, NULL, "vid_disc_indicator", vid_disc_indicator); + config_set_int(CFG_GLOBAL, NULL, "vid_api", vid_api); + config_set_int(CFG_GLOBAL, NULL, "video_fullscreen_scale", video_fullscreen_scale); + config_set_int(CFG_GLOBAL, NULL, "video_fullscreen_first", video_fullscreen_first); - config_set_int(CFG_GLOBAL, NULL, "window_w", window_w); - config_set_int(CFG_GLOBAL, NULL, "window_h", window_h); - config_set_int(CFG_GLOBAL, NULL, "window_x", window_x); - config_set_int(CFG_GLOBAL, NULL, "window_y", window_y); - config_set_int(CFG_GLOBAL, NULL, "window_remember", window_remember); + config_set_int(CFG_GLOBAL, NULL, "window_w", window_w); + config_set_int(CFG_GLOBAL, NULL, "window_h", window_h); + config_set_int(CFG_GLOBAL, NULL, "window_x", window_x); + config_set_int(CFG_GLOBAL, NULL, "window_y", window_y); + config_set_int(CFG_GLOBAL, NULL, "window_remember", window_remember); - config_set_int(CFG_GLOBAL, NULL, "sound_buf_len", sound_buf_len); - config_set_int(CFG_GLOBAL, NULL, "sound_gain", sound_gain); + config_set_int(CFG_GLOBAL, NULL, "sound_buf_len", sound_buf_len); + config_set_int(CFG_GLOBAL, NULL, "sound_gain", sound_gain); - config_set_int(CFG_MACHINE, NULL, "gameblaster", GAMEBLASTER); - config_set_int(CFG_MACHINE, NULL, "gus", GUS); - config_set_int(CFG_MACHINE, NULL, "ssi2001", SSI2001); - config_set_int(CFG_MACHINE, NULL, "voodoo", voodoo_enabled); + config_set_int(CFG_MACHINE, NULL, "gameblaster", GAMEBLASTER); + config_set_int(CFG_MACHINE, NULL, "gus", GUS); + config_set_int(CFG_MACHINE, NULL, "ssi2001", SSI2001); + config_set_int(CFG_MACHINE, NULL, "voodoo", voodoo_enabled); - config_set_string(CFG_MACHINE, NULL, "model", model_get_internal_name()); - config_set_int(CFG_MACHINE, NULL, "cpu_manufacturer", cpu_manufacturer); - config_set_int(CFG_MACHINE, NULL, "cpu", cpu); - config_set_string(CFG_MACHINE, NULL, "fpu", (char *)fpu_get_internal_name(model, cpu_manufacturer, cpu, fpu_type)); - config_set_int(CFG_MACHINE, NULL, "cpu_use_dynarec", cpu_use_dynarec); - config_set_int(CFG_MACHINE, NULL, "cpu_waitstates", cpu_waitstates); + config_set_string(CFG_MACHINE, NULL, "model", model_get_internal_name()); + config_set_int(CFG_MACHINE, NULL, "cpu_manufacturer", cpu_manufacturer); + config_set_int(CFG_MACHINE, NULL, "cpu", cpu); + config_set_string(CFG_MACHINE, NULL, "fpu", (char *)fpu_get_internal_name(model, cpu_manufacturer, cpu, fpu_type)); + config_set_int(CFG_MACHINE, NULL, "cpu_use_dynarec", cpu_use_dynarec); + config_set_int(CFG_MACHINE, NULL, "cpu_waitstates", cpu_waitstates); - config_set_string(CFG_MACHINE, NULL, "gfxcard", video_get_internal_name(video_old_to_new(gfxcard))); - config_set_int(CFG_MACHINE, NULL, "video_speed", video_speed); - config_set_string(CFG_MACHINE, NULL, "sndcard", sound_card_get_internal_name(sound_card_current)); - config_set_int(CFG_MACHINE, NULL, "cpu_speed", cpuspeed); - config_set_string(CFG_MACHINE, NULL, "disc_a", discfns[0]); - config_set_string(CFG_MACHINE, NULL, "disc_b", discfns[1]); - config_set_string(CFG_MACHINE, NULL, "hdd_controller", hdd_controller_name); + config_set_string(CFG_MACHINE, NULL, "gfxcard", video_get_internal_name(video_old_to_new(gfxcard))); + config_set_int(CFG_MACHINE, NULL, "video_speed", video_speed); + config_set_string(CFG_MACHINE, NULL, "sndcard", sound_card_get_internal_name(sound_card_current)); + config_set_int(CFG_MACHINE, NULL, "cpu_speed", cpuspeed); + config_set_string(CFG_MACHINE, NULL, "disc_a", discfns[0]); + config_set_string(CFG_MACHINE, NULL, "disc_b", discfns[1]); + config_set_string(CFG_MACHINE, NULL, "hdd_controller", hdd_controller_name); - config_set_int(CFG_MACHINE, NULL, "mem_size", mem_size); - config_set_int(CFG_MACHINE, NULL, "cdrom_drive", cdrom_drive); - config_set_int(CFG_MACHINE, NULL, "cdrom_channel", cdrom_channel); - config_set_string(CFG_MACHINE, NULL, "cdrom_path", image_path); + config_set_int(CFG_MACHINE, NULL, "mem_size", mem_size); + config_set_int(CFG_MACHINE, NULL, "cdrom_drive", cdrom_drive); + config_set_int(CFG_MACHINE, NULL, "cdrom_channel", cdrom_channel); + config_set_string(CFG_MACHINE, NULL, "cdrom_path", image_path); - config_set_int(CFG_MACHINE, NULL, "zip_channel", zip_channel); + config_set_int(CFG_MACHINE, NULL, "zip_channel", zip_channel); - config_set_int(CFG_MACHINE, NULL, "hdc_sectors", hdc[0].spt); - config_set_int(CFG_MACHINE, NULL, "hdc_heads", hdc[0].hpc); - config_set_int(CFG_MACHINE, NULL, "hdc_cylinders", hdc[0].tracks); - config_set_string(CFG_MACHINE, NULL, "hdc_fn", ide_fn[0]); - config_set_int(CFG_MACHINE, NULL, "hdd_sectors", hdc[1].spt); - config_set_int(CFG_MACHINE, NULL, "hdd_heads", hdc[1].hpc); - config_set_int(CFG_MACHINE, NULL, "hdd_cylinders", hdc[1].tracks); - config_set_string(CFG_MACHINE, NULL, "hdd_fn", ide_fn[1]); - config_set_int(CFG_MACHINE, NULL, "hde_sectors", hdc[2].spt); - config_set_int(CFG_MACHINE, NULL, "hde_heads", hdc[2].hpc); - config_set_int(CFG_MACHINE, NULL, "hde_cylinders", hdc[2].tracks); - config_set_string(CFG_MACHINE, NULL, "hde_fn", ide_fn[2]); - config_set_int(CFG_MACHINE, NULL, "hdf_sectors", hdc[3].spt); - config_set_int(CFG_MACHINE, NULL, "hdf_heads", hdc[3].hpc); - config_set_int(CFG_MACHINE, NULL, "hdf_cylinders", hdc[3].tracks); - config_set_string(CFG_MACHINE, NULL, "hdf_fn", ide_fn[3]); - config_set_int(CFG_MACHINE, NULL, "hdg_sectors", hdc[4].spt); - config_set_int(CFG_MACHINE, NULL, "hdg_heads", hdc[4].hpc); - config_set_int(CFG_MACHINE, NULL, "hdg_cylinders", hdc[4].tracks); - config_set_string(CFG_MACHINE, NULL, "hdg_fn", ide_fn[4]); - config_set_int(CFG_MACHINE, NULL, "hdh_sectors", hdc[5].spt); - config_set_int(CFG_MACHINE, NULL, "hdh_heads", hdc[5].hpc); - config_set_int(CFG_MACHINE, NULL, "hdh_cylinders", hdc[5].tracks); - config_set_string(CFG_MACHINE, NULL, "hdh_fn", ide_fn[5]); - config_set_int(CFG_MACHINE, NULL, "hdi_sectors", hdc[6].spt); - config_set_int(CFG_MACHINE, NULL, "hdi_heads", hdc[6].hpc); - config_set_int(CFG_MACHINE, NULL, "hdi_cylinders", hdc[6].tracks); - config_set_string(CFG_MACHINE, NULL, "hdi_fn", ide_fn[6]); + config_set_int(CFG_MACHINE, NULL, "hdc_sectors", hdc[0].spt); + config_set_int(CFG_MACHINE, NULL, "hdc_heads", hdc[0].hpc); + config_set_int(CFG_MACHINE, NULL, "hdc_cylinders", hdc[0].tracks); + config_set_string(CFG_MACHINE, NULL, "hdc_fn", ide_fn[0]); + config_set_int(CFG_MACHINE, NULL, "hdd_sectors", hdc[1].spt); + config_set_int(CFG_MACHINE, NULL, "hdd_heads", hdc[1].hpc); + config_set_int(CFG_MACHINE, NULL, "hdd_cylinders", hdc[1].tracks); + config_set_string(CFG_MACHINE, NULL, "hdd_fn", ide_fn[1]); + config_set_int(CFG_MACHINE, NULL, "hde_sectors", hdc[2].spt); + config_set_int(CFG_MACHINE, NULL, "hde_heads", hdc[2].hpc); + config_set_int(CFG_MACHINE, NULL, "hde_cylinders", hdc[2].tracks); + config_set_string(CFG_MACHINE, NULL, "hde_fn", ide_fn[2]); + config_set_int(CFG_MACHINE, NULL, "hdf_sectors", hdc[3].spt); + config_set_int(CFG_MACHINE, NULL, "hdf_heads", hdc[3].hpc); + config_set_int(CFG_MACHINE, NULL, "hdf_cylinders", hdc[3].tracks); + config_set_string(CFG_MACHINE, NULL, "hdf_fn", ide_fn[3]); + config_set_int(CFG_MACHINE, NULL, "hdg_sectors", hdc[4].spt); + config_set_int(CFG_MACHINE, NULL, "hdg_heads", hdc[4].hpc); + config_set_int(CFG_MACHINE, NULL, "hdg_cylinders", hdc[4].tracks); + config_set_string(CFG_MACHINE, NULL, "hdg_fn", ide_fn[4]); + config_set_int(CFG_MACHINE, NULL, "hdh_sectors", hdc[5].spt); + config_set_int(CFG_MACHINE, NULL, "hdh_heads", hdc[5].hpc); + config_set_int(CFG_MACHINE, NULL, "hdh_cylinders", hdc[5].tracks); + config_set_string(CFG_MACHINE, NULL, "hdh_fn", ide_fn[5]); + config_set_int(CFG_MACHINE, NULL, "hdi_sectors", hdc[6].spt); + config_set_int(CFG_MACHINE, NULL, "hdi_heads", hdc[6].hpc); + config_set_int(CFG_MACHINE, NULL, "hdi_cylinders", hdc[6].tracks); + config_set_string(CFG_MACHINE, NULL, "hdi_fn", ide_fn[6]); - config_set_int(CFG_MACHINE, NULL, "drive_a_type", fdd_get_type(0)); - config_set_int(CFG_MACHINE, NULL, "drive_b_type", fdd_get_type(1)); - config_set_int(CFG_MACHINE, NULL, "bpb_disable", bpb_disable); + config_set_int(CFG_MACHINE, NULL, "drive_a_type", fdd_get_type(0)); + config_set_int(CFG_MACHINE, NULL, "drive_b_type", fdd_get_type(1)); + config_set_int(CFG_MACHINE, NULL, "bpb_disable", bpb_disable); - config_set_int(CFG_MACHINE, NULL, "cd_speed", cd_speed); - config_set_string(CFG_MACHINE, NULL, "cd_model", cd_model_to_config(cd_model)); + config_set_int(CFG_MACHINE, NULL, "cd_speed", cd_speed); + config_set_string(CFG_MACHINE, NULL, "cd_model", cd_model_to_config(cd_model)); - config_set_int(CFG_MACHINE, NULL, "joystick_type", joystick_type); - config_set_int(CFG_MACHINE, NULL, "mouse_type", mouse_type); + config_set_int(CFG_MACHINE, NULL, "joystick_type", joystick_type); + config_set_int(CFG_MACHINE, NULL, "mouse_type", mouse_type); - for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) { - char s[80]; + for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) { + char s[80]; - sprintf(s, "joystick_%i_nr", c); - config_set_int(CFG_MACHINE, "Joysticks", s, joystick_state[c].plat_joystick_nr); + sprintf(s, "joystick_%i_nr", c); + config_set_int(CFG_MACHINE, "Joysticks", s, joystick_state[c].plat_joystick_nr); - if (joystick_state[c].plat_joystick_nr) { - for (d = 0; d < joystick_get_axis_count(joystick_type); d++) { - sprintf(s, "joystick_%i_axis_%i", c, d); - config_set_int(CFG_MACHINE, "Joysticks", s, joystick_state[c].axis_mapping[d]); - } - for (d = 0; d < joystick_get_button_count(joystick_type); d++) { - sprintf(s, "joystick_%i_button_%i", c, d); - config_set_int(CFG_MACHINE, "Joysticks", s, joystick_state[c].button_mapping[d]); - } - for (d = 0; d < joystick_get_pov_count(joystick_type); d++) { - sprintf(s, "joystick_%i_pov_%i_x", c, d); - config_set_int(CFG_MACHINE, "Joysticks", s, joystick_state[c].pov_mapping[d][0]); - sprintf(s, "joystick_%i_pov_%i_y", c, d); - config_set_int(CFG_MACHINE, "Joysticks", s, joystick_state[c].pov_mapping[d][1]); - } - } - } + if (joystick_state[c].plat_joystick_nr) { + for (d = 0; d < joystick_get_axis_count(joystick_type); d++) { + sprintf(s, "joystick_%i_axis_%i", c, d); + config_set_int(CFG_MACHINE, "Joysticks", s, joystick_state[c].axis_mapping[d]); + } + for (d = 0; d < joystick_get_button_count(joystick_type); d++) { + sprintf(s, "joystick_%i_button_%i", c, d); + config_set_int(CFG_MACHINE, "Joysticks", s, joystick_state[c].button_mapping[d]); + } + for (d = 0; d < joystick_get_pov_count(joystick_type); d++) { + sprintf(s, "joystick_%i_pov_%i_x", c, d); + config_set_int(CFG_MACHINE, "Joysticks", s, joystick_state[c].pov_mapping[d][0]); + sprintf(s, "joystick_%i_pov_%i_y", c, d); + config_set_int(CFG_MACHINE, "Joysticks", s, joystick_state[c].pov_mapping[d][1]); + } + } + } - config_set_int(CFG_MACHINE, NULL, "enable_sync", enable_sync); + config_set_int(CFG_MACHINE, NULL, "enable_sync", enable_sync); #ifdef USE_NETWORKING - config_set_int(CFG_GLOBAL, NULL, "netinterface", ethif); - config_set_string(CFG_MACHINE, NULL, "netcard", network_card_get_internal_name(network_card_current)); + config_set_int(CFG_GLOBAL, NULL, "netinterface", ethif); + config_set_string(CFG_MACHINE, NULL, "netcard", network_card_get_internal_name(network_card_current)); #endif - config_set_string(CFG_MACHINE, NULL, "lpt1_device", lpt1_device_name); + config_set_string(CFG_MACHINE, NULL, "lpt1_device", lpt1_device_name); - for (d = 0; d < num_config_callbacks; ++d) - if (config_callbacks[d].saveconfig) - config_callbacks[d].saveconfig(); + for (d = 0; d < num_config_callbacks; ++d) + if (config_callbacks[d].saveconfig) + config_callbacks[d].saveconfig(); - pclog("config_save(%s)\n", config_file_default); - if (fn) - config_save(CFG_MACHINE, fn); - else if (strlen(config_file_default)) - config_save(CFG_MACHINE, config_file_default); + pclog("config_save(%s)\n", config_file_default); + if (fn) + config_save(CFG_MACHINE, fn); + else if (strlen(config_file_default)) + config_save(CFG_MACHINE, config_file_default); - config_save(CFG_GLOBAL, global_config_file); + config_save(CFG_GLOBAL, global_config_file); } void saveconfig_global_only() { - char global_config_file[512]; + char global_config_file[512]; - append_filename(global_config_file, pcem_path, "pcem.cfg", 511); + append_filename(global_config_file, pcem_path, "pcem.cfg", 511); - config_save(CFG_GLOBAL, global_config_file); + config_save(CFG_GLOBAL, global_config_file); } diff --git a/src/plugin-api/config.c b/src/plugin-api/config.c index 415fb0c5..0725046c 100644 --- a/src/plugin-api/config.c +++ b/src/plugin-api/config.c @@ -11,454 +11,453 @@ int num_config_callbacks = 0; static char config_file[256]; typedef struct list_t { - struct list_t *next; + struct list_t *next; } list_t; static list_t global_config_head; static list_t machine_config_head; typedef struct section_t { - struct list_t list; + struct list_t list; - char name[256]; + char name[256]; - struct list_t entry_head; + struct list_t entry_head; } section_t; typedef struct entry_t { - struct list_t list; + struct list_t list; - char name[256]; - char data[256]; + char name[256]; + char data[256]; } entry_t; -#define list_add(new, head) \ - { \ - struct list_t *next = head; \ - \ - while (next->next) \ - next = next->next; \ - \ - (next)->next = new; \ - (new)->next = NULL; \ +#define list_add(new, head) \ + { \ + struct list_t *next = head; \ + \ + while (next->next) \ + next = next->next; \ + \ + (next)->next = new; \ + (new)->next = NULL; \ } void config_dump(int is_global) { - section_t *current_section; - list_t *head = is_global ? &global_config_head : &machine_config_head; + section_t *current_section; + list_t *head = is_global ? &global_config_head : &machine_config_head; - pclog("Config data :\n"); + pclog("Config data :\n"); - current_section = (section_t *)head->next; + current_section = (section_t *)head->next; - while (current_section) { - entry_t *current_entry; + while (current_section) { + entry_t *current_entry; - pclog("[%s]\n", current_section->name); + pclog("[%s]\n", current_section->name); - current_entry = (entry_t *)current_section->entry_head.next; + current_entry = (entry_t *)current_section->entry_head.next; - while (current_entry) { - pclog("%s = %s\n", current_entry->name, current_entry->data); + while (current_entry) { + pclog("%s = %s\n", current_entry->name, current_entry->data); - current_entry = (entry_t *)current_entry->list.next; - } + current_entry = (entry_t *)current_entry->list.next; + } - current_section = (section_t *)current_section->list.next; - } + current_section = (section_t *)current_section->list.next; + } } void config_free(int is_global) { - section_t *current_section; - list_t *head = is_global ? &global_config_head : &machine_config_head; - current_section = (section_t *)head->next; + section_t *current_section; + list_t *head = is_global ? &global_config_head : &machine_config_head; + current_section = (section_t *)head->next; - while (current_section) { - section_t *next_section = (section_t *)current_section->list.next; - entry_t *current_entry; + while (current_section) { + section_t *next_section = (section_t *)current_section->list.next; + entry_t *current_entry; - current_entry = (entry_t *)current_section->entry_head.next; + current_entry = (entry_t *)current_section->entry_head.next; - while (current_entry) { - entry_t *next_entry = (entry_t *)current_entry->list.next; + while (current_entry) { + entry_t *next_entry = (entry_t *)current_entry->list.next; - free(current_entry); - current_entry = next_entry; - } + free(current_entry); + current_entry = next_entry; + } - free(current_section); - current_section = next_section; - } + free(current_section); + current_section = next_section; + } } int config_free_section(int is_global, char *name) { - section_t *current_section, *prev_section; - list_t *head = is_global ? &global_config_head : &machine_config_head; - current_section = (section_t *)head->next; - prev_section = 0; + section_t *current_section, *prev_section; + list_t *head = is_global ? &global_config_head : &machine_config_head; + current_section = (section_t *)head->next; + prev_section = 0; - while (current_section) { - section_t *next_section = (section_t *)current_section->list.next; - if (!strcmp(current_section->name, name)) { - entry_t *current_entry; + while (current_section) { + section_t *next_section = (section_t *)current_section->list.next; + if (!strcmp(current_section->name, name)) { + entry_t *current_entry; - current_entry = (entry_t *)current_section->entry_head.next; + current_entry = (entry_t *)current_section->entry_head.next; - while (current_entry) { - entry_t *next_entry = (entry_t *)current_entry->list.next; + while (current_entry) { + entry_t *next_entry = (entry_t *)current_entry->list.next; - free(current_entry); - current_entry = next_entry; - } + free(current_entry); + current_entry = next_entry; + } - free(current_section); - if (!prev_section) - head->next = (list_t *)next_section; - else - prev_section->list.next = (list_t *)next_section; - return 1; - } - prev_section = current_section; - current_section = next_section; - } - return 0; + free(current_section); + if (!prev_section) + head->next = (list_t *)next_section; + else + prev_section->list.next = (list_t *)next_section; + return 1; + } + prev_section = current_section; + current_section = next_section; + } + return 0; } void config_load(int is_global, char *fn) { - FILE *f = fopen(fn, "rt"); - section_t *current_section; - list_t *head = is_global ? &global_config_head : &machine_config_head; + FILE *f = fopen(fn, "rt"); + section_t *current_section; + list_t *head = is_global ? &global_config_head : &machine_config_head; - memset(head, 0, sizeof(list_t)); + memset(head, 0, sizeof(list_t)); - current_section = malloc(sizeof(section_t)); - memset(current_section, 0, sizeof(section_t)); - list_add(¤t_section->list, head); + current_section = malloc(sizeof(section_t)); + memset(current_section, 0, sizeof(section_t)); + list_add(¤t_section->list, head); - if (!f) - return; + if (!f) + return; - while (1) { - int c; - char buffer[256]; + while (1) { + int c; + char buffer[256]; - fgets(buffer, 255, f); - if (feof(f)) - break; + fgets(buffer, 255, f); + if (feof(f)) + break; - c = 0; + c = 0; - while (buffer[c] == ' ' && buffer[c]) - c++; + while (buffer[c] == ' ' && buffer[c]) + c++; - if (!buffer[c]) - continue; + if (!buffer[c]) + continue; - if (buffer[c] == '#') /*Comment*/ - continue; + if (buffer[c] == '#') /*Comment*/ + continue; - if (buffer[c] == '[') /*Section*/ - { - section_t *new_section; - char name[256]; - int d = 0; + if (buffer[c] == '[') /*Section*/ + { + section_t *new_section; + char name[256]; + int d = 0; - c++; - while (buffer[c] != ']' && buffer[c]) - name[d++] = buffer[c++]; + c++; + while (buffer[c] != ']' && buffer[c]) + name[d++] = buffer[c++]; - if (buffer[c] != ']') - continue; - name[d] = 0; + if (buffer[c] != ']') + continue; + name[d] = 0; - new_section = malloc(sizeof(section_t)); - memset(new_section, 0, sizeof(section_t)); - strncpy(new_section->name, name, 256); - list_add(&new_section->list, head); + new_section = malloc(sizeof(section_t)); + memset(new_section, 0, sizeof(section_t)); + strncpy(new_section->name, name, 256); + list_add(&new_section->list, head); - current_section = new_section; + current_section = new_section; -// pclog("New section : %s %p\n", name, (void *)current_section); - } else { - entry_t *new_entry; - char name[256]; - int d = 0, data_pos; + // pclog("New section : %s %p\n", name, (void *)current_section); + } else { + entry_t *new_entry; + char name[256]; + int d = 0, data_pos; - while (buffer[c] != '=' && buffer[c] != ' ' && buffer[c]) - name[d++] = buffer[c++]; + while (buffer[c] != '=' && buffer[c] != ' ' && buffer[c]) + name[d++] = buffer[c++]; - if (!buffer[c]) - continue; - name[d] = 0; + if (!buffer[c]) + continue; + name[d] = 0; - while ((buffer[c] == '=' || buffer[c] == ' ') && buffer[c]) - c++; + while ((buffer[c] == '=' || buffer[c] == ' ') && buffer[c]) + c++; - if (!buffer[c]) - continue; + if (!buffer[c]) + continue; - data_pos = c; - while (buffer[c]) { - if (buffer[c] == '\n') - buffer[c] = 0; - c++; - } + data_pos = c; + while (buffer[c]) { + if (buffer[c] == '\n') + buffer[c] = 0; + c++; + } - new_entry = malloc(sizeof(entry_t)); - memset(new_entry, 0, sizeof(entry_t)); - strncpy(new_entry->name, name, 256); - strncpy(new_entry->data, &buffer[data_pos], 256); - list_add(&new_entry->list, ¤t_section->entry_head); + new_entry = malloc(sizeof(entry_t)); + memset(new_entry, 0, sizeof(entry_t)); + strncpy(new_entry->name, name, 256); + strncpy(new_entry->data, &buffer[data_pos], 256); + list_add(&new_entry->list, ¤t_section->entry_head); -// pclog("New data under section [%s] : %s = %s\n", current_section->name, new_entry->name, new_entry->data); - } - } + // pclog("New data under section [%s] : %s = %s\n", current_section->name, + // new_entry->name, new_entry->data); + } + } - fclose(f); + fclose(f); } void config_new() { - FILE *f = fopen(config_file, "wt"); - fclose(f); + FILE *f = fopen(config_file, "wt"); + fclose(f); } static section_t *find_section(char *name, int is_global) { - section_t *current_section; - char blank[] = ""; - list_t *head = is_global ? &global_config_head : &machine_config_head; + section_t *current_section; + char blank[] = ""; + list_t *head = is_global ? &global_config_head : &machine_config_head; - current_section = (section_t *)head->next; - if (!name) - name = blank; + current_section = (section_t *)head->next; + if (!name) + name = blank; - while (current_section) { - if (!strncmp(current_section->name, name, 256)) - return current_section; + while (current_section) { + if (!strncmp(current_section->name, name, 256)) + return current_section; - current_section = (section_t *)current_section->list.next; - } - return NULL; + current_section = (section_t *)current_section->list.next; + } + return NULL; } static entry_t *find_entry(section_t *section, char *name) { - entry_t *current_entry; + entry_t *current_entry; - current_entry = (entry_t *)section->entry_head.next; + current_entry = (entry_t *)section->entry_head.next; - while (current_entry) { - if (!strncmp(current_entry->name, name, 256)) - return current_entry; + while (current_entry) { + if (!strncmp(current_entry->name, name, 256)) + return current_entry; - current_entry = (entry_t *)current_entry->list.next; - } - return NULL; + current_entry = (entry_t *)current_entry->list.next; + } + return NULL; } static section_t *create_section(char *name, int is_global) { - section_t *new_section = malloc(sizeof(section_t)); - list_t *head = is_global ? &global_config_head : &machine_config_head; + section_t *new_section = malloc(sizeof(section_t)); + list_t *head = is_global ? &global_config_head : &machine_config_head; - memset(new_section, 0, sizeof(section_t)); - strncpy(new_section->name, name, 256); - list_add(&new_section->list, head); + memset(new_section, 0, sizeof(section_t)); + strncpy(new_section->name, name, 256); + list_add(&new_section->list, head); - return new_section; + return new_section; } static entry_t *create_entry(section_t *section, char *name) { - entry_t *new_entry = malloc(sizeof(entry_t)); - memset(new_entry, 0, sizeof(entry_t)); - strncpy(new_entry->name, name, 256); - list_add(&new_entry->list, §ion->entry_head); + entry_t *new_entry = malloc(sizeof(entry_t)); + memset(new_entry, 0, sizeof(entry_t)); + strncpy(new_entry->name, name, 256); + list_add(&new_entry->list, §ion->entry_head); - return new_entry; + return new_entry; } int config_get_int(int is_global, char *head, char *name, int def) { - section_t *section; - entry_t *entry; - int value; + section_t *section; + entry_t *entry; + int value; - section = find_section(head, is_global); + section = find_section(head, is_global); - if (!section) - return def; + if (!section) + return def; - entry = find_entry(section, name); + entry = find_entry(section, name); - if (!entry) - return def; + if (!entry) + return def; - sscanf(entry->data, "%i", &value); + sscanf(entry->data, "%i", &value); - return value; + return value; } float config_get_float(int is_global, char *head, char *name, float def) { - section_t *section; - entry_t *entry; - float value; + section_t *section; + entry_t *entry; + float value; - section = find_section(head, is_global); + section = find_section(head, is_global); - if (!section) - return def; + if (!section) + return def; - entry = find_entry(section, name); + entry = find_entry(section, name); - if (!entry) - return def; + if (!entry) + return def; - sscanf(entry->data, "%f", &value); + sscanf(entry->data, "%f", &value); - return value; + return value; } char *config_get_string(int is_global, char *head, char *name, char *def) { - section_t *section; - entry_t *entry; + section_t *section; + entry_t *entry; - section = find_section(head, is_global); + section = find_section(head, is_global); - if (!section) - return def; + if (!section) + return def; - entry = find_entry(section, name); + entry = find_entry(section, name); - if (!entry) - return def; + if (!entry) + return def; - return entry->data; + return entry->data; } void config_set_int(int is_global, char *head, char *name, int val) { - section_t *section; - entry_t *entry; + section_t *section; + entry_t *entry; - section = find_section(head, is_global); + section = find_section(head, is_global); - if (!section) - section = create_section(head, is_global); + if (!section) + section = create_section(head, is_global); - entry = find_entry(section, name); + entry = find_entry(section, name); - if (!entry) - entry = create_entry(section, name); + if (!entry) + entry = create_entry(section, name); - sprintf(entry->data, "%i", val); + sprintf(entry->data, "%i", val); } void config_set_float(int is_global, char *head, char *name, float val) { - section_t *section; - entry_t *entry; + section_t *section; + entry_t *entry; - section = find_section(head, is_global); + section = find_section(head, is_global); - if (!section) - section = create_section(head, is_global); + if (!section) + section = create_section(head, is_global); - entry = find_entry(section, name); + entry = find_entry(section, name); - if (!entry) - entry = create_entry(section, name); + if (!entry) + entry = create_entry(section, name); - sprintf(entry->data, "%f", val); + sprintf(entry->data, "%f", val); } void config_set_string(int is_global, char *head, char *name, char *val) { - section_t *section; - entry_t *entry; + section_t *section; + entry_t *entry; - section = find_section(head, is_global); + section = find_section(head, is_global); - if (!section) - section = create_section(head, is_global); + if (!section) + section = create_section(head, is_global); - entry = find_entry(section, name); + entry = find_entry(section, name); - if (!entry) - entry = create_entry(section, name); + if (!entry) + entry = create_entry(section, name); - strncpy(entry->data, val, 256); + strncpy(entry->data, val, 256); } char *get_filename(char *s) { - int c = strlen(s) - 1; - while (c > 0) { - if (s[c] == '/' || s[c] == '\\') - return &s[c + 1]; - c--; - } - return s; + int c = strlen(s) - 1; + while (c > 0) { + if (s[c] == '/' || s[c] == '\\') + return &s[c + 1]; + c--; + } + return s; } -void append_filename(char *dest, char *s1, char *s2, int size) { - sprintf(dest, "%s%s", s1, s2); -} +void append_filename(char *dest, char *s1, char *s2, int size) { sprintf(dest, "%s%s", s1, s2); } void append_slash(char *s, int size) { - int c = strlen(s) - 1; - if (s[c] != '/' && s[c] != '\\') { - if (c < size - 2) - strcat(s, "/"); - else - s[c] = '/'; - } + int c = strlen(s) - 1; + if (s[c] != '/' && s[c] != '\\') { + if (c < size - 2) + strcat(s, "/"); + else + s[c] = '/'; + } } void put_backslash(char *s) { - int c = strlen(s) - 1; - if (s[c] != '/' && s[c] != '\\') { - s[c + 1] = '/'; - s[c + 2] = 0; - } + int c = strlen(s) - 1; + if (s[c] != '/' && s[c] != '\\') { + s[c + 1] = '/'; + s[c + 2] = 0; + } } char *get_extension(char *s) { - int c = strlen(s) - 1; + int c = strlen(s) - 1; - if (c <= 0) - return s; + if (c <= 0) + return s; - while (c && s[c] != '.') - c--; + while (c && s[c] != '.') + c--; - if (!c) - return &s[strlen(s)]; + if (!c) + return &s[strlen(s)]; - return &s[c + 1]; + return &s[c + 1]; } void config_save(int is_global, char *fn) { - FILE *f = fopen(fn, "wt"); - section_t *current_section; - list_t *head = is_global ? &global_config_head : &machine_config_head; + FILE *f = fopen(fn, "wt"); + section_t *current_section; + list_t *head = is_global ? &global_config_head : &machine_config_head; - current_section = (section_t *)head->next; + current_section = (section_t *)head->next; - while (current_section) { - entry_t *current_entry; + while (current_section) { + entry_t *current_entry; - if (current_section->name[0]) - fprintf(f, "\n[%s]\n", current_section->name); + if (current_section->name[0]) + fprintf(f, "\n[%s]\n", current_section->name); - current_entry = (entry_t *)current_section->entry_head.next; + current_entry = (entry_t *)current_section->entry_head.next; - while (current_entry) { - fprintf(f, "%s = %s\n", current_entry->name, current_entry->data); + while (current_entry) { + fprintf(f, "%s = %s\n", current_entry->name, current_entry->data); - current_entry = (entry_t *)current_entry->list.next; - } + current_entry = (entry_t *)current_entry->list.next; + } - current_section = (section_t *)current_section->list.next; - } + current_section = (section_t *)current_section->list.next; + } - fclose(f); + fclose(f); } -void add_config_callback(void(*loadconfig)(), void(*saveconfig)(), void(*onloaded)()) { - config_callbacks[num_config_callbacks].loadconfig = loadconfig; - config_callbacks[num_config_callbacks].saveconfig = saveconfig; - config_callbacks[num_config_callbacks].onloaded = onloaded; - num_config_callbacks++; +void add_config_callback(void (*loadconfig)(), void (*saveconfig)(), void (*onloaded)()) { + config_callbacks[num_config_callbacks].loadconfig = loadconfig; + config_callbacks[num_config_callbacks].saveconfig = saveconfig; + config_callbacks[num_config_callbacks].onloaded = onloaded; + num_config_callbacks++; } diff --git a/src/plugin-api/device.c b/src/plugin-api/device.c index e1358c4a..2aff086c 100644 --- a/src/plugin-api/device.c +++ b/src/plugin-api/device.c @@ -25,300 +25,294 @@ void *device_priv[DEV_MAX]; void (*_sound_speed_changed)(); -device_t *model_getdevice(int model) { - return models[model]->device; -} +device_t *model_getdevice(int model) { return models[model]->device; } -void device_init() { - memset(devices, 0, sizeof(devices)); -} +void device_init() { memset(devices, 0, sizeof(devices)); } -void device_add(device_t *d) { - pcem_add_device(d); -} +void device_add(device_t *d) { pcem_add_device(d); } void device_close_all() { - int c; + int c; - for (c = 0; c < 256; c++) { - if (devices[c] != NULL) { - if (devices[c]->close != NULL) - devices[c]->close(device_priv[c]); - devices[c] = device_priv[c] = NULL; - } - } + for (c = 0; c < 256; c++) { + if (devices[c] != NULL) { + if (devices[c]->close != NULL) + devices[c]->close(device_priv[c]); + devices[c] = device_priv[c] = NULL; + } + } } int device_available(device_t *d) { #ifdef RELEASE_BUILD - if (d->flags & DEVICE_NOT_WORKING) - return 0; + if (d->flags & DEVICE_NOT_WORKING) + return 0; #endif - if (d->available) - return d->available(); + if (d->available) + return d->available(); - return 1; + return 1; } void device_speed_changed() { - int c; + int c; - for (c = 0; c < 256; c++) { - if (devices[c] != NULL) { - if (devices[c]->speed_changed != NULL) { - devices[c]->speed_changed(device_priv[c]); - } - } - } + for (c = 0; c < 256; c++) { + if (devices[c] != NULL) { + if (devices[c]->speed_changed != NULL) { + devices[c]->speed_changed(device_priv[c]); + } + } + } - _sound_speed_changed(); + _sound_speed_changed(); } void device_force_redraw() { - int c; + int c; - for (c = 0; c < 256; c++) { - if (devices[c] != NULL) { - if (devices[c]->force_redraw != NULL) { - devices[c]->force_redraw(device_priv[c]); - } - } - } + for (c = 0; c < 256; c++) { + if (devices[c] != NULL) { + if (devices[c]->force_redraw != NULL) { + devices[c]->force_redraw(device_priv[c]); + } + } + } } void device_add_status_info(char *s, int max_len) { - int c; + int c; - for (c = 0; c < 256; c++) { - if (devices[c] != NULL) { - if (devices[c]->add_status_info != NULL) - devices[c]->add_status_info(s, max_len, device_priv[c]); - } - } + for (c = 0; c < 256; c++) { + if (devices[c] != NULL) { + if (devices[c]->add_status_info != NULL) + devices[c]->add_status_info(s, max_len, device_priv[c]); + } + } } int device_get_config_int(char *s) { - device_config_t *config = current_device->config; + device_config_t *config = current_device->config; - while (config->type != -1) { - if (!strcmp(s, config->name)) - return config_get_int(CFG_MACHINE, current_device->name, s, config->default_int); + while (config->type != -1) { + if (!strcmp(s, config->name)) + return config_get_int(CFG_MACHINE, current_device->name, s, config->default_int); - config++; - } - return 0; + config++; + } + return 0; } char *device_get_config_string(char *s) { - device_config_t *config = current_device->config; + device_config_t *config = current_device->config; - while (config->type != -1) { - if (!strcmp(s, config->name)) - return config_get_string(CFG_MACHINE, current_device->name, s, config->default_string); + while (config->type != -1) { + if (!strcmp(s, config->name)) + return config_get_string(CFG_MACHINE, current_device->name, s, config->default_string); - config++; - } - return NULL; + config++; + } + return NULL; } int model_get_config_int(char *s) { - device_t *device = model_getdevice(model); - device_config_t *config; + device_t *device = model_getdevice(model); + device_config_t *config; - if (!device) - return 0; + if (!device) + return 0; - config = device->config; + config = device->config; - while (config->type != -1) { - if (!strcmp(s, config->name)) - return config_get_int(CFG_MACHINE, device->name, s, config->default_int); + while (config->type != -1) { + if (!strcmp(s, config->name)) + return config_get_int(CFG_MACHINE, device->name, s, config->default_int); - config++; - } - return 0; + config++; + } + return 0; } char *model_get_config_string(char *s) { - device_t *device = model_getdevice(model); - device_config_t *config; + device_t *device = model_getdevice(model); + device_config_t *config; - if (!device) - return 0; + if (!device) + return 0; - config = device->config; + config = device->config; - while (config->type != -1) { - if (!strcmp(s, config->name)) - return config_get_string(CFG_MACHINE, device->name, s, config->default_string); + while (config->type != -1) { + if (!strcmp(s, config->name)) + return config_get_string(CFG_MACHINE, device->name, s, config->default_string); - config++; - } - return NULL; + config++; + } + return NULL; } int pcem_device_get_config_int(device_t *device, char *s) { - device_config_t *config = device->config; + device_config_t *config = device->config; - while (config->type != -1) { - if (!strcmp(s, config->name)) - return config_get_int(CFG_MACHINE, device->name, s, config->default_int); + while (config->type != -1) { + if (!strcmp(s, config->name)) + return config_get_int(CFG_MACHINE, device->name, s, config->default_int); - config++; - } - return 0; + config++; + } + return 0; } char *pcem_device_get_config_string(device_t *device, char *s) { - device_config_t *config = device->config; + device_config_t *config = device->config; - while (config->type != -1) { - if (!strcmp(s, config->name)) - return config_get_string(CFG_MACHINE, device->name, s, config->default_string); + while (config->type != -1) { + if (!strcmp(s, config->name)) + return config_get_string(CFG_MACHINE, device->name, s, config->default_string); - config++; - } - return NULL; + config++; + } + return NULL; } int pcem_model_get_config_int(device_t *device, char *s) { - device_config_t *config; + device_config_t *config; - if (!device) - return 0; + if (!device) + return 0; - config = device->config; + config = device->config; - while (config->type != -1) { - if (!strcmp(s, config->name)) - return config_get_int(CFG_MACHINE, device->name, s, config->default_int); + while (config->type != -1) { + if (!strcmp(s, config->name)) + return config_get_int(CFG_MACHINE, device->name, s, config->default_int); - config++; - } - return 0; + config++; + } + return 0; } char *pcem_model_get_config_string(device_t *device, char *s) { - device_config_t *config; + device_config_t *config; - if (!device) - return 0; + if (!device) + return 0; - config = device->config; + config = device->config; - while (config->type != -1) { - if (!strcmp(s, config->name)) - return config_get_string(CFG_MACHINE, device->name, s, config->default_string); + while (config->type != -1) { + if (!strcmp(s, config->name)) + return config_get_string(CFG_MACHINE, device->name, s, config->default_string); - config++; - } - return NULL; + config++; + } + return NULL; } int model_count() { - int ret = 0; + int ret = 0; - while (models[ret] != NULL && ret < ROM_MAX) - ret++; + while (models[ret] != NULL && ret < ROM_MAX) + ret++; - return ret; + return ret; } void pcem_add_model(MODEL *model) { - //TODO: Add sanity check to not go past MAX amount - models[model_count()] = model; + // TODO: Add sanity check to not go past MAX amount + models[model_count()] = model; } int video_count() { - int ret = 0; + int ret = 0; - while (video_cards[ret] != NULL && ret < GFX_MAX) - ret++; + while (video_cards[ret] != NULL && ret < GFX_MAX) + ret++; - return ret; + return ret; } void pcem_add_video(VIDEO_CARD *video) { - //TODO: Add sanity check to not go past MAX amount - video_cards[video_count()] = video; + // TODO: Add sanity check to not go past MAX amount + video_cards[video_count()] = video; } int lpt_count() { - int ret = 0; + int ret = 0; - while (lpt_devices[ret] != NULL && ret < LPT_MAX) - ret++; + while (lpt_devices[ret] != NULL && ret < LPT_MAX) + ret++; - return ret; + return ret; } void pcem_add_lpt(LPT_DEVICE *lpt) { - //TODO: Add sanity check to not go past MAX amount - lpt_devices[lpt_count()] = lpt; + // TODO: Add sanity check to not go past MAX amount + lpt_devices[lpt_count()] = lpt; } int sound_count() { - int ret = 0; + int ret = 0; - while (sound_cards[ret] != NULL && ret < SOUND_MAX) - ret++; + while (sound_cards[ret] != NULL && ret < SOUND_MAX) + ret++; - return ret; + return ret; } void pcem_add_sound(SOUND_CARD *sound) { - //TODO: Add sanity check to not go past MAX amount - sound_cards[sound_count()] = sound; + // TODO: Add sanity check to not go past MAX amount + sound_cards[sound_count()] = sound; } int hdd_controller_count() { - int ret = 0; + int ret = 0; - while (hdd_controllers[ret] != NULL && ret < HDDCONTROLLERS_MAX) - ret++; + while (hdd_controllers[ret] != NULL && ret < HDDCONTROLLERS_MAX) + ret++; - return ret; + return ret; } void pcem_add_hddcontroller(HDD_CONTROLLER *hddcontroller) { - //TODO: Add sanity check to not go past MAX amount - hdd_controllers[hdd_controller_count()] = hddcontroller; + // TODO: Add sanity check to not go past MAX amount + hdd_controllers[hdd_controller_count()] = hddcontroller; } int network_card_count() { - int ret = 0; + int ret = 0; - while (network_cards[ret] != NULL && ret < NETWORK_CARD_MAX) - ret++; + while (network_cards[ret] != NULL && ret < NETWORK_CARD_MAX) + ret++; - return ret; + return ret; } void pcem_add_networkcard(NETWORK_CARD *netcard) { - //TODO: Add sanity check to not go past MAX amount - network_cards[network_card_count()] = netcard; + // TODO: Add sanity check to not go past MAX amount + network_cards[network_card_count()] = netcard; } void pcem_add_device(device_t *d) { - int c = 0; - void *priv = NULL; + int c = 0; + void *priv = NULL; - while (devices[c] != NULL && c < 256) - c++; + while (devices[c] != NULL && c < 256) + c++; - if (c >= 256) - fatal("device_add : too many devices\n"); + if (c >= 256) + fatal("device_add : too many devices\n"); - current_device = d; - current_device_name = d->name; + current_device = d; + current_device_name = d->name; - if (d->init != NULL) { - priv = d->init(); - if (priv == NULL) - fatal("device_add : device init failed\n"); - } + if (d->init != NULL) { + priv = d->init(); + if (priv == NULL) + fatal("device_add : device init failed\n"); + } - devices[c] = d; - device_priv[c] = priv; - current_device_name = NULL; + devices[c] = d; + device_priv[c] = priv; + current_device_name = NULL; } diff --git a/src/plugin-api/logging.c b/src/plugin-api/logging.c index 59abcf18..f4cd82ad 100644 --- a/src/plugin-api/logging.c +++ b/src/plugin-api/logging.c @@ -18,113 +18,109 @@ FILE *pclogf = NULL; uint8_t pclog_start() { #ifndef RELEASE_BUILD - if (!pclogf) { - char buf[1024]; - strcpy(buf, logs_path); - put_backslash(buf); - strcat(buf, "pcem.log"); - pclogf = fopen(buf, "wt"); + if (!pclogf) { + char buf[1024]; + strcpy(buf, logs_path); + put_backslash(buf); + strcat(buf, "pcem.log"); + pclogf = fopen(buf, "wt"); - if (NULL == pclogf) { - fprintf(stderr, "Could not open log file for writing: %s", strerror(errno)); - return 0; - } - } - return 1; -#else - return 0; + if (NULL == pclogf) { + fprintf(stderr, "Could not open log file for writing: %s", strerror(errno)); + return 0; + } + } + return 1; +#else + return 0; #endif } void pclog_flush() { #ifndef RELEASE_BUILD - if (pclogf) { - fflush(pclogf); - } + if (pclogf) { + fflush(pclogf); + } #endif - } void pclog_end() { #ifndef RELEASE_BUILD - if (pclogf) { - fflush(pclogf); - fclose(pclogf); - pclogf = NULL; - } + if (pclogf) { + fflush(pclogf); + fclose(pclogf); + pclogf = NULL; + } #endif } - - void error(const char *format, ...) { #ifndef RELEASE_BUILD - char buf[1024]; - //return; - if (!pclog_start()) { - return; - } - //return; - va_list ap; - va_start(ap, format); - vsprintf(buf, format, ap); - va_end(ap); - fputs(buf, pclogf); - fputs(buf, stderr); - //fflush(pclogf); + char buf[1024]; + // return; + if (!pclog_start()) { + return; + } + // return; + va_list ap; + va_start(ap, format); + vsprintf(buf, format, ap); + va_end(ap); + fputs(buf, pclogf); + fputs(buf, stderr); + // fflush(pclogf); #endif } void fatal(const char *format, ...) { #ifndef RELEASE_BUILD - char buf[1024]; - //return; - if (!pclog_start()) { - return; - } - //return; - va_list ap; - va_start(ap, format); - vsprintf(buf, format, ap); - va_end(ap); - fputs(buf, pclogf); - fputs(buf, stderr); - fflush(pclogf); + char buf[1024]; + // return; + if (!pclog_start()) { + return; + } + // return; + va_list ap; + va_start(ap, format); + vsprintf(buf, format, ap); + va_end(ap); + fputs(buf, pclogf); + fputs(buf, stderr); + fflush(pclogf); #endif - _savenvr(); - _dumppic(); - _dumpregs(); - pclog_end(); - exit(-1); + _savenvr(); + _dumppic(); + _dumpregs(); + pclog_end(); + exit(-1); } void warning(const char *format, ...) { - char buf[1024]; - va_list ap; + char buf[1024]; + va_list ap; - va_start(ap, format); - vsprintf(buf, format, ap); - va_end(ap); + va_start(ap, format); + vsprintf(buf, format, ap); + va_end(ap); - //wx_messagebox(NULL, buf, "PCem", WX_MB_OK); //FIX: Fix it + // wx_messagebox(NULL, buf, "PCem", WX_MB_OK); //FIX: Fix it } void pclog(const char *format, ...) { #ifndef RELEASE_BUILD - char buf[1024]; - //return; - if (!pclog_start()) { - return; - } - //return; - va_list ap; - va_start(ap, format); - vsprintf(buf, format, ap); - va_end(ap); - fputs(buf, pclogf); - fputs(buf, stdout); - //fflush(pclogf); + char buf[1024]; + // return; + if (!pclog_start()) { + return; + } + // return; + va_list ap; + va_start(ap, format); + vsprintf(buf, format, ap); + va_end(ap); + fputs(buf, pclogf); + fputs(buf, stdout); + // fflush(pclogf); #endif } - diff --git a/src/plugin-api/paths.c b/src/plugin-api/paths.c index 025791a6..7e56e5b1 100644 --- a/src/plugin-api/paths.c +++ b/src/plugin-api/paths.c @@ -30,245 +30,215 @@ char plugins_default_path[512]; char nvr_default_path[512]; -char get_path_separator() -{ +char get_path_separator() { #ifdef _WIN32 - return ';'; + return ';'; #else - return ':'; + return ':'; #endif } -int get_roms_path(int pos, char *s, int size) -{ - int j, i, z, len; - char path_separator; +int get_roms_path(int pos, char *s, int size) { + int j, i, z, len; + char path_separator; - path_separator = get_path_separator(); - len = strlen(roms_paths); - j = 0; - for (i = 0; i < len; i++) - { - if (roms_paths[i] == path_separator || i == len - 1) - { - if ((pos--) == 0) - { - z = (i - j) + ((i == len - 1) ? 1 : 0); - safe_strncpy(s, roms_paths + j, size); - s[(size - 1 < z) ? size - 1 : z] = 0; - return 1; - } - j = i + 1; - } - } - return 0; + path_separator = get_path_separator(); + len = strlen(roms_paths); + j = 0; + for (i = 0; i < len; i++) { + if (roms_paths[i] == path_separator || i == len - 1) { + if ((pos--) == 0) { + z = (i - j) + ((i == len - 1) ? 1 : 0); + safe_strncpy(s, roms_paths + j, size); + s[(size - 1 < z) ? size - 1 : z] = 0; + return 1; + } + j = i + 1; + } + } + return 0; } -void set_roms_paths(char *path) -{ - char s[512]; - int j, i, z, len; - char path_separator[2]; +void set_roms_paths(char *path) { + char s[512]; + int j, i, z, len; + char path_separator[2]; - roms_paths[0] = 0; - path_separator[0] = get_path_separator(); - path_separator[1] = 0; - len = strlen(path); - j = 0; - num_roms_paths = 0; - for (i = 0; i < len; i++) - { - if (path[i] == path_separator[0] || i == len - 1) - { - z = (i - j) + ((i == len - 1) ? 1 : 0) + 1; - safe_strncpy(s, path + j, z); - s[(511 < z) ? 511 : z] = 0; - append_slash(s, 512); - if (dir_exists(s)) - { - if (num_roms_paths > 0) - strcat(roms_paths, path_separator); - strcat(roms_paths, s); - num_roms_paths++; - } - j = i + 1; - } - } + roms_paths[0] = 0; + path_separator[0] = get_path_separator(); + path_separator[1] = 0; + len = strlen(path); + j = 0; + num_roms_paths = 0; + for (i = 0; i < len; i++) { + if (path[i] == path_separator[0] || i == len - 1) { + z = (i - j) + ((i == len - 1) ? 1 : 0) + 1; + safe_strncpy(s, path + j, z); + s[(511 < z) ? 511 : z] = 0; + append_slash(s, 512); + if (dir_exists(s)) { + if (num_roms_paths > 0) + strcat(roms_paths, path_separator); + strcat(roms_paths, s); + num_roms_paths++; + } + j = i + 1; + } + } } -int dir_exists(char *path) -{ - return wx_dir_exists(path); +int dir_exists(char *path) { return wx_dir_exists(path); } + +void set_nvr_path(char *s) { + safe_strncpy(nvr_path, s, 512); + append_slash(nvr_path, 512); } -void set_nvr_path(char *s) -{ - safe_strncpy(nvr_path, s, 512); - append_slash(nvr_path, 512); +void set_logs_path(char *s) { + safe_strncpy(logs_path, s, 512); + append_slash(logs_path, 512); } -void set_logs_path(char *s) -{ - safe_strncpy(logs_path, s, 512); - append_slash(logs_path, 512); +void set_configs_path(char *s) { + safe_strncpy(configs_path, s, 512); + append_slash(configs_path, 512); } -void set_configs_path(char *s) -{ - safe_strncpy(configs_path, s, 512); - append_slash(configs_path, 512); -} - -void set_screenshots_path(char *s) -{ - safe_strncpy(screenshots_path, s, 512); - append_slash(screenshots_path, 512); +void set_screenshots_path(char *s) { + safe_strncpy(screenshots_path, s, 512); + append_slash(screenshots_path, 512); } /* set the default roms paths, this makes them permanent */ -void set_default_roms_paths(char *s) -{ - safe_strncpy(default_roms_paths, s, 4096); - set_roms_paths(s); +void set_default_roms_paths(char *s) { + safe_strncpy(default_roms_paths, s, 4096); + set_roms_paths(s); } /* set the default nvr path, this makes it permanent */ -void set_default_nvr_path(char *s) -{ - safe_strncpy(default_nvr_path, s, 512); - set_nvr_path(s); +void set_default_nvr_path(char *s) { + safe_strncpy(default_nvr_path, s, 512); + set_nvr_path(s); } -void set_default_nvr_default_path(char *s) -{ - safe_strncpy(nvr_default_path, s, 512); -} +void set_default_nvr_default_path(char *s) { safe_strncpy(nvr_default_path, s, 512); } /* set the default logs path, this makes it permanent */ -void set_default_logs_path(char *s) -{ - safe_strncpy(default_logs_path, s, 512); - set_logs_path(s); +void set_default_logs_path(char *s) { + safe_strncpy(default_logs_path, s, 512); + set_logs_path(s); } /* set the default configs path, this makes it permanent */ -void set_default_configs_path(char *s) -{ - safe_strncpy(default_configs_path, s, 512); - set_configs_path(s); +void set_default_configs_path(char *s) { + safe_strncpy(default_configs_path, s, 512); + set_configs_path(s); } /* set the default screenshots path, this makes it permanent */ -void set_default_screenshots_path(char *s) -{ - safe_strncpy(default_screenshots_path, s, 512); - set_screenshots_path(s); +void set_default_screenshots_path(char *s) { + safe_strncpy(default_screenshots_path, s, 512); + set_screenshots_path(s); } -void paths_loadconfig() -{ - char *cfg_roms_paths = config_get_string(CFG_GLOBAL, "Paths", "roms_paths", 0); - char *cfg_nvr_path = config_get_string(CFG_GLOBAL, "Paths", "nvr_path", 0); - char *cfg_configs_path = config_get_string(CFG_GLOBAL, "Paths", "configs_path", 0); - char *cfg_logs_path = config_get_string(CFG_GLOBAL, "Paths", "logs_path", 0); - char *cfg_screenshots_path = config_get_string(CFG_GLOBAL, "Paths", "screenshots_path", 0); +void paths_loadconfig() { + char *cfg_roms_paths = config_get_string(CFG_GLOBAL, "Paths", "roms_paths", 0); + char *cfg_nvr_path = config_get_string(CFG_GLOBAL, "Paths", "nvr_path", 0); + char *cfg_configs_path = config_get_string(CFG_GLOBAL, "Paths", "configs_path", 0); + char *cfg_logs_path = config_get_string(CFG_GLOBAL, "Paths", "logs_path", 0); + char *cfg_screenshots_path = config_get_string(CFG_GLOBAL, "Paths", "screenshots_path", 0); - if (cfg_roms_paths) - safe_strncpy(default_roms_paths, cfg_roms_paths, 4096); - if (cfg_nvr_path) - safe_strncpy(default_nvr_path, cfg_nvr_path, 512); - if (cfg_configs_path) - safe_strncpy(default_configs_path, cfg_configs_path, 512); - if (cfg_logs_path) - safe_strncpy(default_logs_path, cfg_logs_path, 512); - if (cfg_screenshots_path) - safe_strncpy(default_screenshots_path, cfg_screenshots_path, 512); + if (cfg_roms_paths) + safe_strncpy(default_roms_paths, cfg_roms_paths, 4096); + if (cfg_nvr_path) + safe_strncpy(default_nvr_path, cfg_nvr_path, 512); + if (cfg_configs_path) + safe_strncpy(default_configs_path, cfg_configs_path, 512); + if (cfg_logs_path) + safe_strncpy(default_logs_path, cfg_logs_path, 512); + if (cfg_screenshots_path) + safe_strncpy(default_screenshots_path, cfg_screenshots_path, 512); } -void paths_saveconfig() -{ - config_set_string(CFG_GLOBAL, "Paths", "roms_paths", default_roms_paths); - config_set_string(CFG_GLOBAL, "Paths", "nvr_path", default_nvr_path); - config_set_string(CFG_GLOBAL, "Paths", "configs_path", default_configs_path); - config_set_string(CFG_GLOBAL, "Paths", "logs_path", default_logs_path); - config_set_string(CFG_GLOBAL, "Paths", "screenshots_path", default_screenshots_path); +void paths_saveconfig() { + config_set_string(CFG_GLOBAL, "Paths", "roms_paths", default_roms_paths); + config_set_string(CFG_GLOBAL, "Paths", "nvr_path", default_nvr_path); + config_set_string(CFG_GLOBAL, "Paths", "configs_path", default_configs_path); + config_set_string(CFG_GLOBAL, "Paths", "logs_path", default_logs_path); + config_set_string(CFG_GLOBAL, "Paths", "screenshots_path", default_screenshots_path); } -void paths_onconfigloaded() -{ - if (strlen(default_roms_paths) > 0) - set_roms_paths(default_roms_paths); +void paths_onconfigloaded() { + if (strlen(default_roms_paths) > 0) + set_roms_paths(default_roms_paths); - if (strlen(default_nvr_path) > 0) - set_nvr_path(default_nvr_path); + if (strlen(default_nvr_path) > 0) + set_nvr_path(default_nvr_path); - if (strlen(default_configs_path) > 0) - set_configs_path(default_configs_path); + if (strlen(default_configs_path) > 0) + set_configs_path(default_configs_path); - if (strlen(default_logs_path) > 0) - set_logs_path(default_logs_path); + if (strlen(default_logs_path) > 0) + set_logs_path(default_logs_path); - if (strlen(default_screenshots_path) > 0) - set_screenshots_path(default_screenshots_path); + if (strlen(default_screenshots_path) > 0) + set_screenshots_path(default_screenshots_path); - pclog("path = %s\n", pcem_path); + pclog("path = %s\n", pcem_path); } /* initialize default paths */ -void paths_init() -{ - char s[512]; +void paths_init() { + char s[512]; - char *p; + char *p; - get_pcem_path(pcem_path, 512); - /* pcem_path may be path to executable */ - p = get_filename(pcem_path); - *p = 0; + get_pcem_path(pcem_path, 512); + /* pcem_path may be path to executable */ + p = get_filename(pcem_path); + *p = 0; - /* set up default paths for this session */ - append_filename(s, pcem_path, "roms/", 512); - set_roms_paths(s); - set_default_roms_paths(s); - append_filename(s, pcem_path, "nvr/", 512); - set_nvr_path(s); - set_default_nvr_path(s); - append_filename(s, pcem_path, "configs/", 512); - set_configs_path(s); - set_default_configs_path(s); - append_filename(s, pcem_path, "screenshots/", 512); - set_screenshots_path(s); - set_default_screenshots_path(s); - append_filename(s, pcem_path, "logs/", 512); - set_logs_path(s); - set_default_logs_path(s); - append_filename(s, pcem_path, "nvr/default/", 512); - set_default_nvr_default_path(s); + /* set up default paths for this session */ + append_filename(s, pcem_path, "roms/", 512); + set_roms_paths(s); + set_default_roms_paths(s); + append_filename(s, pcem_path, "nvr/", 512); + set_nvr_path(s); + set_default_nvr_path(s); + append_filename(s, pcem_path, "configs/", 512); + set_configs_path(s); + set_default_configs_path(s); + append_filename(s, pcem_path, "screenshots/", 512); + set_screenshots_path(s); + set_default_screenshots_path(s); + append_filename(s, pcem_path, "logs/", 512); + set_logs_path(s); + set_default_logs_path(s); + append_filename(s, pcem_path, "nvr/default/", 512); + set_default_nvr_default_path(s); - add_config_callback(paths_loadconfig, paths_saveconfig, paths_onconfigloaded); + add_config_callback(paths_loadconfig, paths_saveconfig, paths_onconfigloaded); } -void get_pcem_path(char *s, int size) -{ +void get_pcem_path(char *s, int size) { #ifdef __linux - wx_get_home_directory(s); - strcat(s, ".pcem/"); + wx_get_home_directory(s); + strcat(s, ".pcem/"); #elif defined(__APPLE__) - /*TODO: Use CoreFoundation functions to get proper directory, in case - the Application Support directory is different (I.E., with signing)*/ - wx_get_home_directory(s); - strcat(s, "Library/Application Support/PCem/"); + /*TODO: Use CoreFoundation functions to get proper directory, in case + the Application Support directory is different (I.E., with signing)*/ + wx_get_home_directory(s); + strcat(s, "Library/Application Support/PCem/"); - struct stat st = {0}; + struct stat st = {0}; - // create ~/Library/Application Support/PCem/ - // if it doesn't exist - if (stat(s, &st) == -1) - { - mkdir(s, 0700); - } + // create ~/Library/Application Support/PCem/ + // if it doesn't exist + if (stat(s, &st) == -1) { + mkdir(s, 0700); + } #else - char *path = SDL_GetBasePath(); - strcpy(s, path); + char *path = SDL_GetBasePath(); + strcpy(s, path); #endif } diff --git a/src/plugin-api/plugin.c b/src/plugin-api/plugin.c index 848e471a..3994c33e 100644 --- a/src/plugin-api/plugin.c +++ b/src/plugin-api/plugin.c @@ -24,93 +24,88 @@ char plugin_path[512]; #ifdef PLUGIN_ENGINE void set_plugin_path(char *s) { - safe_strncpy(plugin_path, s, 512); - set_screenshots_path(s); + safe_strncpy(plugin_path, s, 512); + set_screenshots_path(s); } -void pluginengine_load_config() -{ - char* cfg_plugin_path = config_get_string(CFG_GLOBAL, "Paths", "plugin_path", 0); +void pluginengine_load_config() { + char *cfg_plugin_path = config_get_string(CFG_GLOBAL, "Paths", "plugin_path", 0); - if (cfg_plugin_path) - set_plugin_path(cfg_plugin_path); + if (cfg_plugin_path) + set_plugin_path(cfg_plugin_path); } -void pluginengine_save_config() -{ - config_set_string(CFG_GLOBAL, "Paths", "plugin_path", plugin_path); -} +void pluginengine_save_config() { config_set_string(CFG_GLOBAL, "Paths", "plugin_path", plugin_path); } -void pluginengine_init_config() -{ - char s[512]; - append_filename(s, pcem_path, "plugins/", 512); - set_plugin_path(s); +void pluginengine_init_config() { + char s[512]; + append_filename(s, pcem_path, "plugins/", 512); + set_plugin_path(s); } #endif void init_plugin_engine() { - memset(models, 0, sizeof(models)); - memset(video_cards, 0, sizeof(video_cards)); - memset(lpt_devices, 0, sizeof(lpt_devices)); - memset(sound_cards, 0, sizeof(sound_cards)); - memset(hdd_controllers, 0, sizeof(hdd_controllers)); - memset(network_cards, 0, sizeof(network_cards)); + memset(models, 0, sizeof(models)); + memset(video_cards, 0, sizeof(video_cards)); + memset(lpt_devices, 0, sizeof(lpt_devices)); + memset(sound_cards, 0, sizeof(sound_cards)); + memset(hdd_controllers, 0, sizeof(hdd_controllers)); + memset(network_cards, 0, sizeof(network_cards)); - #ifdef PLUGIN_ENGINE - add_config_callback(pluginengine_load_config, pluginengine_save_config, pluginengine_init_config); - #endif +#ifdef PLUGIN_ENGINE + add_config_callback(pluginengine_load_config, pluginengine_save_config, pluginengine_init_config); +#endif } void load_plugins() { #ifdef PLUGIN_ENGINE - tinydir_dir dir; - tinydir_open(&dir, plugin_path); + tinydir_dir dir; + tinydir_open(&dir, plugin_path); - while (dir.has_next) { - tinydir_file file; - tinydir_readfile(&dir, &file); + while (dir.has_next) { + tinydir_file file; + tinydir_readfile(&dir, &file); - if (!strcmp(file.extension, "pplg")) { - pclog("plugin loading: %s\n", file.name); - void (* initialize_loaded_plugin)(); + if (!strcmp(file.extension, "pplg")) { + pclog("plugin loading: %s\n", file.name); + void (*initialize_loaded_plugin)(); #if defined(linux) - void* handle; - char *plugin_name; + void *handle; + char *plugin_name; - handle = dlopen(file.path, RTLD_NOW); - if (!handle) { - error("Error: %s\n", dlerror()); - } else { - *(void**)(&initialize_loaded_plugin) = dlsym(handle, "init_plugin"); + handle = dlopen(file.path, RTLD_NOW); + if (!handle) { + error("Error: %s\n", dlerror()); + } else { + *(void **)(&initialize_loaded_plugin) = dlsym(handle, "init_plugin"); - if (!initialize_loaded_plugin) { - error("Error: %s\n", dlerror()); - dlclose(handle); - } else { - initialize_loaded_plugin(); - } - } + if (!initialize_loaded_plugin) { + error("Error: %s\n", dlerror()); + dlclose(handle); + } else { + initialize_loaded_plugin(); + } + } #elif defined(WIN32) - HMODULE handle = LoadLibrary(file.path); + HMODULE handle = LoadLibrary(file.path); - if(!handle) { - error("Cannot load DLL: %s", file.path); - } else { - *(void**)(&initialize_loaded_plugin) = GetProcAddress(handle, "init_plugin"); - if(!initialize_loaded_plugin) { - error("Cannot load init_plugin function from: %s", file.path); - } else { - initialize_loaded_plugin(); - } - } + if (!handle) { + error("Cannot load DLL: %s", file.path); + } else { + *(void **)(&initialize_loaded_plugin) = GetProcAddress(handle, "init_plugin"); + if (!initialize_loaded_plugin) { + error("Cannot load init_plugin function from: %s", file.path); + } else { + initialize_loaded_plugin(); + } + } #endif - pclog("plugin finished loading: %s\n", file.name); - } + pclog("plugin finished loading: %s\n", file.name); + } - tinydir_next(&dir); - } + tinydir_next(&dir); + } - tinydir_close(&dir); + tinydir_close(&dir); #endif } diff --git a/src/plugin-api/wx-utils.cc b/src/plugin-api/wx-utils.cc index 4a206cad..1f17c990 100644 --- a/src/plugin-api/wx-utils.cc +++ b/src/plugin-api/wx-utils.cc @@ -3,14 +3,14 @@ #include int wx_dir_exists(char *path) { - wxFileName p(path); - return p.DirExists(); + wxFileName p(path); + return p.DirExists(); } void wx_get_home_directory(char *path) { - wxString home = wxFileName::GetHomeDir(); - if (!home.EndsWith(wxFileName::GetPathSeparator())) { - home.Append(wxFileName::GetPathSeparator()); - } - strcpy(path, home.mb_str()); + wxString home = wxFileName::GetHomeDir(); + if (!home.EndsWith(wxFileName::GetPathSeparator())) { + home.Append(wxFileName::GetPathSeparator()); + } + strcpy(path, home.mb_str()); } \ No newline at end of file diff --git a/src/ppi.c b/src/ppi.c index 96f24e2b..9f8d30bc 100644 --- a/src/ppi.c +++ b/src/ppi.c @@ -12,7 +12,6 @@ #include "plat-mouse.h" void ppi_reset() { - ppi.pa = 0x0;//0x1D; - ppi.pb = 0x40; + ppi.pa = 0x0; // 0x1D; + ppi.pb = 0x40; } - diff --git a/src/pzx.c b/src/pzx.c index abb110e3..126c22b0 100644 --- a/src/pzx.c +++ b/src/pzx.c @@ -24,338 +24,330 @@ #include "ibm.h" #include "pzx.h" -/* This module is intended to abstract all the details of a PZX file and +/* This module is intended to abstract all the details of a PZX file and * emit its contents as a bitstream in a form suitable for PCem. Similar - * modules could be written to add support for other tape formats such as TZX, + * modules could be written to add support for other tape formats such as TZX, * TAP or CSW. */ #define CAS_LOG(x) pclog x /* #define CAS_LOG(x) */ -static uint32_t peek2(uint8_t *data) { - return (((uint32_t)data[1]) << 8) | data[0]; -} +static uint32_t peek2(uint8_t *data) { return (((uint32_t)data[1]) << 8) | data[0]; } static uint32_t peek4(uint8_t *data) { - return (((uint32_t)data[3]) << 24) | - (((uint32_t)data[2]) << 16) | - (((uint32_t)data[1]) << 8) | data[0]; + return (((uint32_t)data[3]) << 24) | (((uint32_t)data[2]) << 16) | (((uint32_t)data[1]) << 8) | data[0]; } /* Cue up the next pulse definition from the current PULS block. */ static void pzx_parse_pulse(pzxfile_t *pzx) { - pzx->puls_duration = peek2(pzx->curblock + pzx->puls_ptr); - pzx->puls_ptr += 2; - if (pzx->puls_duration > 0x8000) { - pzx->puls_count = pzx->puls_duration & 0x7FFF; - pzx->puls_duration = peek2(pzx->curblock + pzx->puls_ptr); - pzx->puls_ptr += 2; - } - if (pzx->puls_duration >= 0x8000) { - pzx->puls_duration &= 0x7FFF; - pzx->puls_duration <<= 16; - pzx->puls_duration |= peek2(pzx->curblock + pzx->puls_ptr); - pzx->puls_ptr += 2; - } - if (!pzx->puls_count) - pzx->puls_count = 1; + pzx->puls_duration = peek2(pzx->curblock + pzx->puls_ptr); + pzx->puls_ptr += 2; + if (pzx->puls_duration > 0x8000) { + pzx->puls_count = pzx->puls_duration & 0x7FFF; + pzx->puls_duration = peek2(pzx->curblock + pzx->puls_ptr); + pzx->puls_ptr += 2; + } + if (pzx->puls_duration >= 0x8000) { + pzx->puls_duration &= 0x7FFF; + pzx->puls_duration <<= 16; + pzx->puls_duration |= peek2(pzx->curblock + pzx->puls_ptr); + pzx->puls_ptr += 2; + } + if (!pzx->puls_count) + pzx->puls_count = 1; } void pzx_init(pzxfile_t *pzx) { - memset(pzx, 0, sizeof(pzxfile_t)); - pzx->state = PZX_CLOSED; + memset(pzx, 0, sizeof(pzxfile_t)); + pzx->state = PZX_CLOSED; } -/* Load the next block from a PZX-format file. +/* Load the next block from a PZX-format file. * * Returns block if successful, NULL if end of file or error * Caller must free the block with free(). */ uint8_t *pzx_load_block(FILE *fp) { - uint8_t block_header[8]; - uint8_t *block_data; - uint32_t block_len; + uint8_t block_header[8]; + uint8_t *block_data; + uint32_t block_len; - /* The first 8 bytes of a PZX block are fixed: the first 4 give - * the ID, the second 4 the length (excluding the header itself) */ - if (fread(block_header, 1, 8, fp) < 8) - return NULL; /* EoF */ + /* The first 8 bytes of a PZX block are fixed: the first 4 give + * the ID, the second 4 the length (excluding the header itself) */ + if (fread(block_header, 1, 8, fp) < 8) + return NULL; /* EoF */ - block_len = peek4(block_header + 4); - block_data = malloc(8 + block_len); - if (!block_data) - return NULL; - memcpy(block_data, block_header, 8); - if (!block_len) /* Block is only the header */ - { -/* CAS_LOG(("Loaded PZX block: %-4.4s\n", block_data)); */ - return block_data; - } - if (fread(block_data + 8, 1, block_len, fp) < block_len) { - free(block_data); /* Unexpected EoF */ - return NULL; - } -/* CAS_LOG(("Loaded PZX block: %-4.4s\n", block_data)); */ - return block_data; + block_len = peek4(block_header + 4); + block_data = malloc(8 + block_len); + if (!block_data) + return NULL; + memcpy(block_data, block_header, 8); + if (!block_len) /* Block is only the header */ + { + /* CAS_LOG(("Loaded PZX block: %-4.4s\n", block_data)); */ + return block_data; + } + if (fread(block_data + 8, 1, block_len, fp) < block_len) { + free(block_data); /* Unexpected EoF */ + return NULL; + } + /* CAS_LOG(("Loaded PZX block: %-4.4s\n", block_data)); */ + return block_data; } /* Search the current file for PZX version headers and check they're all 1.x */ static const char *pzx_check_version(FILE *fp) { - uint8_t *block; - static char message[80]; + uint8_t *block; + static char message[80]; - rewind(fp); - while ((block = pzx_load_block(fp))) { - if (!memcmp(block, "PZXT", 4)) { - CAS_LOG(("PZX version %d.%d\n", block[8], block[9])); - if (block[8] != 1) { - sprintf(message, "Unsupported PZX version %d.%d\n", block[8], block[9]); - free(block); - return message; - } - } - free(block); - } - rewind(fp); - return NULL; + rewind(fp); + while ((block = pzx_load_block(fp))) { + if (!memcmp(block, "PZXT", 4)) { + CAS_LOG(("PZX version %d.%d\n", block[8], block[9])); + if (block[8] != 1) { + sprintf(message, "Unsupported PZX version %d.%d\n", block[8], block[9]); + free(block); + return message; + } + } + free(block); + } + rewind(fp); + return NULL; } const char *pzx_open(pzxfile_t *pzx, FILE *fp) { - const char *result; + const char *result; - rewind(fp); - /* Check that this file is compatible */ - result = pzx_check_version(fp); - if (result) - return result; + rewind(fp); + /* Check that this file is compatible */ + result = pzx_check_version(fp); + if (result) + return result; - pzx->level = 0; - pzx->state = PZX_IDLE; - pzx->input = fp; - return NULL; + pzx->level = 0; + pzx->state = PZX_IDLE; + pzx->input = fp; + return NULL; } void pzx_close(pzxfile_t *pzx) { - if (pzx->input) { - fclose(pzx->input); - pzx->input = NULL; - } - if (pzx->curblock) { - free(pzx->curblock); - pzx->curblock = NULL; - } - pzx->state = PZX_CLOSED; + if (pzx->input) { + fclose(pzx->input); + pzx->input = NULL; + } + if (pzx->curblock) { + free(pzx->curblock); + pzx->curblock = NULL; + } + pzx->state = PZX_CLOSED; } /* Read the next block of type DATA, PAUS or PULS */ int pzx_next_block(pzxfile_t *pzx) { - long pos; + long pos; - pos = ftell(pzx->input); - while (pzx->state == PZX_IDLE) { - uint8_t *blk; + pos = ftell(pzx->input); + while (pzx->state == PZX_IDLE) { + uint8_t *blk; - /* In idle state there should be no current block. But - * make sure of that */ - if (pzx->curblock) { - free(pzx->curblock); - pzx->curblock = NULL; - } + /* In idle state there should be no current block. But + * make sure of that */ + if (pzx->curblock) { + free(pzx->curblock); + pzx->curblock = NULL; + } - /* Load the next block */ - blk = pzx_load_block(pzx->input); + /* Load the next block */ + blk = pzx_load_block(pzx->input); - /* If that didn't load we've reached the end of file; wrap to - * beginning. */ - if (!blk) { - rewind(pzx->input); - blk = pzx_load_block(pzx->input); - if (!blk) /* Couldn't even load first block */ - { - pzx_close(pzx); - return 0; - } - /* Have we read the whole file and come back to where - * we were? */ - if (ftell(pzx->input) == pos) { - free(blk); - pzx_close(pzx); - return 0; - } - } - /* We have loaded the next block. What is it? */ - if (!memcmp(blk, "PULS", 4)) { - pzx->state = PZX_IN_PULS; - pzx->curblock = blk; - pzx->puls_len = 8 + peek4(blk + 4); - pzx->puls_ptr = 8; - pzx->puls_count = 0; - pzx->puls_remain = 0; - pzx->puls_duration = 0; - pzx->level = 0; - CAS_LOG(("Beginning PULS block\n")); - } else if (!memcmp(blk, "PAUS", 4)) { - pzx->state = PZX_IN_PAUS; - pzx->curblock = blk; - pzx->paus_remain = peek4(blk + 8); - pzx->level = (pzx->paus_remain >> 31); - pzx->paus_remain &= 0x7FFFFFFF; - CAS_LOG(("Beginning PAUS block, duration=%d\n", - pzx->paus_remain)); - } else if (!memcmp(blk, "DATA", 4)) { - pzx->state = PZX_IN_DATA; - pzx->curblock = blk; - pzx->data_bits = peek4(blk + 8); - pzx->level = (pzx->data_bits >> 31); - pzx->data_bits &= 0x7FFFFFFF; - pzx->data_tail = peek2(blk + 12); - pzx->data_p0 = blk[14]; - pzx->data_p1 = blk[15]; - pzx->data_p = 0; - pzx->data_w = 16; - pzx->data_remain = 0; - pzx->data_ptr = 16 + 2 * (pzx->data_p0 + pzx->data_p1); - pzx->data_mask = 0x80; - CAS_LOG(("Beginning DATA block, length=%d p0=%d p1=%d" - " data_ptr=%d\n", - pzx->data_bits, - pzx->data_p0, pzx->data_p1, - pzx->data_ptr)); - } - } - return 1; + /* If that didn't load we've reached the end of file; wrap to + * beginning. */ + if (!blk) { + rewind(pzx->input); + blk = pzx_load_block(pzx->input); + if (!blk) /* Couldn't even load first block */ + { + pzx_close(pzx); + return 0; + } + /* Have we read the whole file and come back to where + * we were? */ + if (ftell(pzx->input) == pos) { + free(blk); + pzx_close(pzx); + return 0; + } + } + /* We have loaded the next block. What is it? */ + if (!memcmp(blk, "PULS", 4)) { + pzx->state = PZX_IN_PULS; + pzx->curblock = blk; + pzx->puls_len = 8 + peek4(blk + 4); + pzx->puls_ptr = 8; + pzx->puls_count = 0; + pzx->puls_remain = 0; + pzx->puls_duration = 0; + pzx->level = 0; + CAS_LOG(("Beginning PULS block\n")); + } else if (!memcmp(blk, "PAUS", 4)) { + pzx->state = PZX_IN_PAUS; + pzx->curblock = blk; + pzx->paus_remain = peek4(blk + 8); + pzx->level = (pzx->paus_remain >> 31); + pzx->paus_remain &= 0x7FFFFFFF; + CAS_LOG(("Beginning PAUS block, duration=%d\n", pzx->paus_remain)); + } else if (!memcmp(blk, "DATA", 4)) { + pzx->state = PZX_IN_DATA; + pzx->curblock = blk; + pzx->data_bits = peek4(blk + 8); + pzx->level = (pzx->data_bits >> 31); + pzx->data_bits &= 0x7FFFFFFF; + pzx->data_tail = peek2(blk + 12); + pzx->data_p0 = blk[14]; + pzx->data_p1 = blk[15]; + pzx->data_p = 0; + pzx->data_w = 16; + pzx->data_remain = 0; + pzx->data_ptr = 16 + 2 * (pzx->data_p0 + pzx->data_p1); + pzx->data_mask = 0x80; + CAS_LOG(("Beginning DATA block, length=%d p0=%d p1=%d" + " data_ptr=%d\n", + pzx->data_bits, pzx->data_p0, pzx->data_p1, pzx->data_ptr)); + } + } + return 1; } static void pzx_endblock(pzxfile_t *pzx) { - if (pzx->curblock) - free(pzx->curblock); - pzx->curblock = NULL; - pzx->state = PZX_IDLE; + if (pzx->curblock) + free(pzx->curblock); + pzx->curblock = NULL; + pzx->state = PZX_IDLE; } /* PAUS is easy - just run the timer down */ static int pzx_advance_paus(pzxfile_t *pzx, int time) { - if (pzx->paus_remain > time) { - pzx->paus_remain -= time; - return 0; - } - time -= pzx->paus_remain; - pzx_endblock(pzx); - return time; + if (pzx->paus_remain > time) { + pzx->paus_remain -= time; + return 0; + } + time -= pzx->paus_remain; + pzx_endblock(pzx); + return time; } static int pzx_advance_puls(pzxfile_t *pzx, int time) { - /* At the start of a pulse sequence? */ - if (pzx->puls_count == 0) { - pzx_parse_pulse(pzx); - pzx->puls_remain = pzx->puls_duration; - } - /* Does sample trigger a pulse change? If not, that's easy. */ - if (time < pzx->puls_remain) { - pzx->puls_remain -= time; - return 0; - } - /* Sample does trigger a pulse change */ - time -= pzx->puls_remain; - /* If there's another pulse in the current sequence, that's - * straightforward; just flip the level and continue */ - --pzx->puls_count; - pzx->level = !pzx->level; - if (pzx->puls_count) { - pzx->puls_remain = pzx->puls_duration; - return time; - } - /* If we've reached the end of the pulse sequence, there may be - * another one */ - if (pzx->puls_ptr < pzx->puls_len) { - return time; - } - /* If there isn't another one, it's the end of the block */ - pzx_endblock(pzx); - return time; + /* At the start of a pulse sequence? */ + if (pzx->puls_count == 0) { + pzx_parse_pulse(pzx); + pzx->puls_remain = pzx->puls_duration; + } + /* Does sample trigger a pulse change? If not, that's easy. */ + if (time < pzx->puls_remain) { + pzx->puls_remain -= time; + return 0; + } + /* Sample does trigger a pulse change */ + time -= pzx->puls_remain; + /* If there's another pulse in the current sequence, that's + * straightforward; just flip the level and continue */ + --pzx->puls_count; + pzx->level = !pzx->level; + if (pzx->puls_count) { + pzx->puls_remain = pzx->puls_duration; + return time; + } + /* If we've reached the end of the pulse sequence, there may be + * another one */ + if (pzx->puls_ptr < pzx->puls_len) { + return time; + } + /* If there isn't another one, it's the end of the block */ + pzx_endblock(pzx); + return time; } /* Decode a DATA block */ static int pzx_advance_data(pzxfile_t *pzx, int time) { - uint8_t bit; + uint8_t bit; - /* Reached end of data? */ - if (pzx->data_bits == 0) { - /* Time interval is covered by the tail bit */ - if (pzx->data_tail > time) { - pzx->data_tail -= time; - return 0; - } - /* Have run out of block */ - time -= pzx->data_tail; - pzx_endblock(pzx); - return time; - } - /* No more time remaining on the current bit? */ - if (pzx->data_p < 1 && !pzx->data_remain) { - bit = pzx->curblock[pzx->data_ptr] & pzx->data_mask; - pzx->data_mask >>= 1; - if (!pzx->data_mask) { - pzx->data_mask = 0x80; - ++pzx->data_ptr; - } - --pzx->data_bits; + /* Reached end of data? */ + if (pzx->data_bits == 0) { + /* Time interval is covered by the tail bit */ + if (pzx->data_tail > time) { + pzx->data_tail -= time; + return 0; + } + /* Have run out of block */ + time -= pzx->data_tail; + pzx_endblock(pzx); + return time; + } + /* No more time remaining on the current bit? */ + if (pzx->data_p < 1 && !pzx->data_remain) { + bit = pzx->curblock[pzx->data_ptr] & pzx->data_mask; + pzx->data_mask >>= 1; + if (!pzx->data_mask) { + pzx->data_mask = 0x80; + ++pzx->data_ptr; + } + --pzx->data_bits; - if (bit) { - pzx->data_p = pzx->data_p1; - pzx->data_w = 16 + 2 * pzx->data_p0; - pzx->data_remain = 0; - } else { - pzx->data_p = pzx->data_p0; - pzx->data_w = 16; - pzx->data_remain = 0; - } - } - /* See if we've started processing the current waveform. If not, - * load its first element (assuming that there is one) */ - if (!pzx->data_remain) { - if (pzx->data_p) { - pzx->data_remain = peek2(pzx->curblock + pzx->data_w); - pzx->data_w += 2; - pzx->data_p--; - } - } - if (pzx->data_remain > time) { - /* Time advance is contained within current wave */ - pzx->data_remain -= time; - return 0; - } else /* Move on to next element of wave / next bit / next block */ - { - time -= pzx->data_remain; - pzx->data_remain = 0; - pzx->level = !pzx->level; - } + if (bit) { + pzx->data_p = pzx->data_p1; + pzx->data_w = 16 + 2 * pzx->data_p0; + pzx->data_remain = 0; + } else { + pzx->data_p = pzx->data_p0; + pzx->data_w = 16; + pzx->data_remain = 0; + } + } + /* See if we've started processing the current waveform. If not, + * load its first element (assuming that there is one) */ + if (!pzx->data_remain) { + if (pzx->data_p) { + pzx->data_remain = peek2(pzx->curblock + pzx->data_w); + pzx->data_w += 2; + pzx->data_p--; + } + } + if (pzx->data_remain > time) { + /* Time advance is contained within current wave */ + pzx->data_remain -= time; + return 0; + } else /* Move on to next element of wave / next bit / next block */ + { + time -= pzx->data_remain; + pzx->data_remain = 0; + pzx->level = !pzx->level; + } - return time; + return time; } int pzx_advance(pzxfile_t *pzx, int time) { - if (pzx->state == PZX_CLOSED) - return 0; /* No tape loaded */ + if (pzx->state == PZX_CLOSED) + return 0; /* No tape loaded */ - while (time) { - switch (pzx->state) { - case PZX_IDLE: - if (!pzx_next_block(pzx)) - return 0; - break; - case PZX_IN_PULS:time = pzx_advance_puls(pzx, time); - break; - case PZX_IN_PAUS:time = pzx_advance_paus(pzx, time); - break; - case PZX_IN_DATA:time = pzx_advance_data(pzx, time); - break; - case PZX_CLOSED: /*Should never get here*/ - return 0; - - } - } - return pzx->level; + while (time) { + switch (pzx->state) { + case PZX_IDLE: + if (!pzx_next_block(pzx)) + return 0; + break; + case PZX_IN_PULS: + time = pzx_advance_puls(pzx, time); + break; + case PZX_IN_PAUS: + time = pzx_advance_paus(pzx, time); + break; + case PZX_IN_DATA: + time = pzx_advance_data(pzx, time); + break; + case PZX_CLOSED: /*Should never get here*/ + return 0; + } + } + return pzx->level; } - - - diff --git a/src/rtc.c b/src/rtc.c index b6c94391..40321d9c 100644 --- a/src/rtc.c +++ b/src/rtc.c @@ -3,7 +3,7 @@ http://datasheets.maximintegrated.com/en/ds/DS12885-DS12C887A.pdf - http://dev-docs.atariforge.org/files/MC146818A_RTC_1984.pdf + http://dev-docs.atariforge.org/files/MC146818A_RTC_1984.pdf */ #include @@ -17,12 +17,12 @@ int enable_sync; struct { - int sec; - int min; - int hour; - int mday; - int mon; - int year; + int sec; + int min; + int hour; + int mday; + int mon; + int year; } internal_clock; /* Table for days in each month */ @@ -30,187 +30,193 @@ static int rtc_days_in_month[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, /* Called to determine whether the year is leap or not */ static int rtc_is_leap(int org_year) { - if (org_year % 400 == 0) - return 1; - if (org_year % 100 == 0) - return 0; - if (org_year % 4 == 0) - return 1; - return 0; + if (org_year % 400 == 0) + return 1; + if (org_year % 100 == 0) + return 0; + if (org_year % 4 == 0) + return 1; + return 0; } /* Called to determine the days in the current month */ static int rtc_get_days(int org_month, int org_year) { - if (org_month != 2) - return rtc_days_in_month[org_month - 1]; - else - return rtc_is_leap(org_year) ? 29 : 28; + if (org_month != 2) + return rtc_days_in_month[org_month - 1]; + else + return rtc_is_leap(org_year) ? 29 : 28; } /* Called when the internal clock gets updated */ static void rtc_recalc() { - if (internal_clock.sec == 60) { - internal_clock.sec = 0; - internal_clock.min++; - } - if (internal_clock.min == 60) { - internal_clock.min = 0; - internal_clock.hour++; - } - if (internal_clock.hour == 24) { - internal_clock.hour = 0; - internal_clock.mday++; - } - if (internal_clock.mday == (rtc_get_days(internal_clock.mon, internal_clock.year) + 1)) { - internal_clock.mday = 1; - internal_clock.mon++; - } - if (internal_clock.mon == 13) { - internal_clock.mon = 1; - internal_clock.year++; - } + if (internal_clock.sec == 60) { + internal_clock.sec = 0; + internal_clock.min++; + } + if (internal_clock.min == 60) { + internal_clock.min = 0; + internal_clock.hour++; + } + if (internal_clock.hour == 24) { + internal_clock.hour = 0; + internal_clock.mday++; + } + if (internal_clock.mday == (rtc_get_days(internal_clock.mon, internal_clock.year) + 1)) { + internal_clock.mday = 1; + internal_clock.mon++; + } + if (internal_clock.mon == 13) { + internal_clock.mon = 1; + internal_clock.year++; + } } /* Called when ticking the second */ void rtc_tick() { - internal_clock.sec++; - rtc_recalc(); + internal_clock.sec++; + rtc_recalc(); } /* Called when modifying the NVR registers */ void time_update(uint8_t *nvrram, int reg) { - int temp; + int temp; - switch (reg) { - case RTC_SECONDS:internal_clock.sec = (nvrram[RTC_REGB] & RTC_DM) ? nvrram[RTC_SECONDS] : DCB(nvrram[RTC_SECONDS]); - break; - case RTC_MINUTES:internal_clock.min = (nvrram[RTC_REGB] & RTC_DM) ? nvrram[RTC_MINUTES] : DCB(nvrram[RTC_MINUTES]); - break; - case RTC_HOURS:temp = (nvrram[RTC_REGB] & RTC_DM) ? nvrram[RTC_HOURS] : DCB(nvrram[RTC_HOURS]); + switch (reg) { + case RTC_SECONDS: + internal_clock.sec = (nvrram[RTC_REGB] & RTC_DM) ? nvrram[RTC_SECONDS] : DCB(nvrram[RTC_SECONDS]); + break; + case RTC_MINUTES: + internal_clock.min = (nvrram[RTC_REGB] & RTC_DM) ? nvrram[RTC_MINUTES] : DCB(nvrram[RTC_MINUTES]); + break; + case RTC_HOURS: + temp = (nvrram[RTC_REGB] & RTC_DM) ? nvrram[RTC_HOURS] : DCB(nvrram[RTC_HOURS]); - if (nvrram[RTC_REGB] & RTC_2412) - internal_clock.hour = temp; - else - internal_clock.hour = ((temp & ~RTC_AMPM) % 12) + ((temp & RTC_AMPM) ? 12 : 0); - break; - case RTC_DOM:internal_clock.mday = (nvrram[RTC_REGB] & RTC_DM) ? nvrram[RTC_DOM] : DCB(nvrram[RTC_DOM]); - break; - case RTC_MONTH:internal_clock.mon = (nvrram[RTC_REGB] & RTC_DM) ? nvrram[RTC_MONTH] : DCB(nvrram[RTC_MONTH]); - break; - case RTC_YEAR:internal_clock.year = (nvrram[RTC_REGB] & RTC_DM) ? nvrram[RTC_YEAR] : DCB(nvrram[RTC_YEAR]); - internal_clock.year += (nvrram[RTC_REGB] & RTC_DM) ? 1900 : (DCB(nvrram[RTC_CENTURY]) * 100); - break; - case RTC_CENTURY: - if (nvrram[RTC_REGB] & RTC_DM) - return; - internal_clock.year %= 100; - internal_clock.year += (DCB(nvrram[RTC_CENTURY]) * 100); - break; - } + if (nvrram[RTC_REGB] & RTC_2412) + internal_clock.hour = temp; + else + internal_clock.hour = ((temp & ~RTC_AMPM) % 12) + ((temp & RTC_AMPM) ? 12 : 0); + break; + case RTC_DOM: + internal_clock.mday = (nvrram[RTC_REGB] & RTC_DM) ? nvrram[RTC_DOM] : DCB(nvrram[RTC_DOM]); + break; + case RTC_MONTH: + internal_clock.mon = (nvrram[RTC_REGB] & RTC_DM) ? nvrram[RTC_MONTH] : DCB(nvrram[RTC_MONTH]); + break; + case RTC_YEAR: + internal_clock.year = (nvrram[RTC_REGB] & RTC_DM) ? nvrram[RTC_YEAR] : DCB(nvrram[RTC_YEAR]); + internal_clock.year += (nvrram[RTC_REGB] & RTC_DM) ? 1900 : (DCB(nvrram[RTC_CENTURY]) * 100); + break; + case RTC_CENTURY: + if (nvrram[RTC_REGB] & RTC_DM) + return; + internal_clock.year %= 100; + internal_clock.year += (DCB(nvrram[RTC_CENTURY]) * 100); + break; + } } /* Called to obtain the current day of the week based on the internal clock */ static int time_week_day() { - int day_of_month = internal_clock.mday; - int month2 = internal_clock.mon; - int year2 = internal_clock.year % 100; - int century = ((internal_clock.year - year2) / 100) % 4; - int sum = day_of_month + month2 + year2 + century; - /* (Sum mod 7) gives 0 for Saturday, we need it for Sunday, so +6 for Saturday to get 6 and Sunday 0 */ - int raw_wd = ((sum + 6) % 7); - return raw_wd; + int day_of_month = internal_clock.mday; + int month2 = internal_clock.mon; + int year2 = internal_clock.year % 100; + int century = ((internal_clock.year - year2) / 100) % 4; + int sum = day_of_month + month2 + year2 + century; + /* (Sum mod 7) gives 0 for Saturday, we need it for Sunday, so +6 for Saturday to get 6 and Sunday 0 */ + int raw_wd = ((sum + 6) % 7); + return raw_wd; } /* Called to get time into the internal clock */ static void time_internal_get(struct tm *time_var) { - time_var->tm_sec = internal_clock.sec; - time_var->tm_min = internal_clock.min; - time_var->tm_hour = internal_clock.hour; - time_var->tm_wday = time_week_day(); - time_var->tm_mday = internal_clock.mday; - time_var->tm_mon = internal_clock.mon - 1; - time_var->tm_year = internal_clock.year - 1900; + time_var->tm_sec = internal_clock.sec; + time_var->tm_min = internal_clock.min; + time_var->tm_hour = internal_clock.hour; + time_var->tm_wday = time_week_day(); + time_var->tm_mday = internal_clock.mday; + time_var->tm_mon = internal_clock.mon - 1; + time_var->tm_year = internal_clock.year - 1900; } static void time_internal_set(struct tm *time_var) { - internal_clock.sec = time_var->tm_sec; - internal_clock.min = time_var->tm_min; - internal_clock.hour = time_var->tm_hour; - internal_clock.mday = time_var->tm_mday; - internal_clock.mon = time_var->tm_mon + 1; - internal_clock.year = time_var->tm_year + 1900; + internal_clock.sec = time_var->tm_sec; + internal_clock.min = time_var->tm_min; + internal_clock.hour = time_var->tm_hour; + internal_clock.mday = time_var->tm_mday; + internal_clock.mon = time_var->tm_mon + 1; + internal_clock.year = time_var->tm_year + 1900; } static void time_set_nvrram(uint8_t *nvrram, struct tm *cur_time_tm) { - if (nvrram[RTC_REGB] & RTC_DM) { - nvrram[RTC_SECONDS] = cur_time_tm->tm_sec; - nvrram[RTC_MINUTES] = cur_time_tm->tm_min; - nvrram[RTC_DOW] = cur_time_tm->tm_wday + 1; - nvrram[RTC_DOM] = cur_time_tm->tm_mday; - nvrram[RTC_MONTH] = cur_time_tm->tm_mon + 1; - nvrram[RTC_YEAR] = cur_time_tm->tm_year % 100; + if (nvrram[RTC_REGB] & RTC_DM) { + nvrram[RTC_SECONDS] = cur_time_tm->tm_sec; + nvrram[RTC_MINUTES] = cur_time_tm->tm_min; + nvrram[RTC_DOW] = cur_time_tm->tm_wday + 1; + nvrram[RTC_DOM] = cur_time_tm->tm_mday; + nvrram[RTC_MONTH] = cur_time_tm->tm_mon + 1; + nvrram[RTC_YEAR] = cur_time_tm->tm_year % 100; - if (nvrram[RTC_REGB] & RTC_2412) { - nvrram[RTC_HOURS] = cur_time_tm->tm_hour; - } else { - nvrram[RTC_HOURS] = (cur_time_tm->tm_hour % 12) ? (cur_time_tm->tm_hour % 12) : 12; - if (cur_time_tm->tm_hour > 11) - nvrram[RTC_HOURS] |= RTC_AMPM; - } - } else { - nvrram[RTC_SECONDS] = BCD(cur_time_tm->tm_sec); - nvrram[RTC_MINUTES] = BCD(cur_time_tm->tm_min); - nvrram[RTC_DOW] = BCD(cur_time_tm->tm_wday + 1); - nvrram[RTC_DOM] = BCD(cur_time_tm->tm_mday); - nvrram[RTC_MONTH] = BCD(cur_time_tm->tm_mon + 1); - nvrram[RTC_YEAR] = BCD(cur_time_tm->tm_year % 100); + if (nvrram[RTC_REGB] & RTC_2412) { + nvrram[RTC_HOURS] = cur_time_tm->tm_hour; + } else { + nvrram[RTC_HOURS] = (cur_time_tm->tm_hour % 12) ? (cur_time_tm->tm_hour % 12) : 12; + if (cur_time_tm->tm_hour > 11) + nvrram[RTC_HOURS] |= RTC_AMPM; + } + } else { + nvrram[RTC_SECONDS] = BCD(cur_time_tm->tm_sec); + nvrram[RTC_MINUTES] = BCD(cur_time_tm->tm_min); + nvrram[RTC_DOW] = BCD(cur_time_tm->tm_wday + 1); + nvrram[RTC_DOM] = BCD(cur_time_tm->tm_mday); + nvrram[RTC_MONTH] = BCD(cur_time_tm->tm_mon + 1); + nvrram[RTC_YEAR] = BCD(cur_time_tm->tm_year % 100); - if (nvrram[RTC_REGB] & RTC_2412) { - nvrram[RTC_HOURS] = BCD(cur_time_tm->tm_hour); - } else { - nvrram[RTC_HOURS] = (cur_time_tm->tm_hour % 12) ? BCD(cur_time_tm->tm_hour % 12) : BCD(12); - if (cur_time_tm->tm_hour > 11) - nvrram[RTC_HOURS] |= RTC_AMPM; - } - } + if (nvrram[RTC_REGB] & RTC_2412) { + nvrram[RTC_HOURS] = BCD(cur_time_tm->tm_hour); + } else { + nvrram[RTC_HOURS] = (cur_time_tm->tm_hour % 12) ? BCD(cur_time_tm->tm_hour % 12) : BCD(12); + if (cur_time_tm->tm_hour > 11) + nvrram[RTC_HOURS] |= RTC_AMPM; + } + } } void time_internal_set_nvrram(uint8_t *nvrram) { - int temp; + int temp; - /* Load the entire internal clock state from the NVR. */ - internal_clock.sec = (nvrram[RTC_REGB] & RTC_DM) ? nvrram[RTC_SECONDS] : DCB(nvrram[RTC_SECONDS]); - internal_clock.min = (nvrram[RTC_REGB] & RTC_DM) ? nvrram[RTC_MINUTES] : DCB(nvrram[RTC_MINUTES]); + /* Load the entire internal clock state from the NVR. */ + internal_clock.sec = (nvrram[RTC_REGB] & RTC_DM) ? nvrram[RTC_SECONDS] : DCB(nvrram[RTC_SECONDS]); + internal_clock.min = (nvrram[RTC_REGB] & RTC_DM) ? nvrram[RTC_MINUTES] : DCB(nvrram[RTC_MINUTES]); - temp = (nvrram[RTC_REGB] & RTC_DM) ? nvrram[RTC_HOURS] : DCB(nvrram[RTC_HOURS]); + temp = (nvrram[RTC_REGB] & RTC_DM) ? nvrram[RTC_HOURS] : DCB(nvrram[RTC_HOURS]); - if (nvrram[RTC_REGB] & RTC_2412) - internal_clock.hour = temp; - else - internal_clock.hour = ((temp & ~RTC_AMPM) % 12) + ((temp & RTC_AMPM) ? 12 : 0); + if (nvrram[RTC_REGB] & RTC_2412) + internal_clock.hour = temp; + else + internal_clock.hour = ((temp & ~RTC_AMPM) % 12) + ((temp & RTC_AMPM) ? 12 : 0); - internal_clock.mday = (nvrram[RTC_REGB] & RTC_DM) ? nvrram[RTC_DOM] : DCB(nvrram[RTC_DOM]); - internal_clock.mon = (nvrram[RTC_REGB] & RTC_DM) ? nvrram[RTC_MONTH] : DCB(nvrram[RTC_MONTH]); - internal_clock.year = (nvrram[RTC_REGB] & RTC_DM) ? nvrram[RTC_YEAR] : DCB(nvrram[RTC_YEAR]); - internal_clock.year += (nvrram[RTC_REGB] & RTC_DM) ? 1900 : (DCB(nvrram[RTC_CENTURY]) * 100); + internal_clock.mday = (nvrram[RTC_REGB] & RTC_DM) ? nvrram[RTC_DOM] : DCB(nvrram[RTC_DOM]); + internal_clock.mon = (nvrram[RTC_REGB] & RTC_DM) ? nvrram[RTC_MONTH] : DCB(nvrram[RTC_MONTH]); + internal_clock.year = (nvrram[RTC_REGB] & RTC_DM) ? nvrram[RTC_YEAR] : DCB(nvrram[RTC_YEAR]); + internal_clock.year += (nvrram[RTC_REGB] & RTC_DM) ? 1900 : (DCB(nvrram[RTC_CENTURY]) * 100); } void time_internal_sync(uint8_t *nvrram) { - struct tm *cur_time_tm; - time_t cur_time; + struct tm *cur_time_tm; + time_t cur_time; - time(&cur_time); - cur_time_tm = localtime(&cur_time); + time(&cur_time); + cur_time_tm = localtime(&cur_time); - time_internal_set(cur_time_tm); + time_internal_set(cur_time_tm); - time_set_nvrram(nvrram, cur_time_tm); + time_set_nvrram(nvrram, cur_time_tm); } void time_get(uint8_t *nvrram) { - struct tm cur_time_tm; + struct tm cur_time_tm; - time_internal_get(&cur_time_tm); + time_internal_get(&cur_time_tm); - time_set_nvrram(nvrram, &cur_time_tm); + time_set_nvrram(nvrram, &cur_time_tm); } diff --git a/src/rtc_tc8521.c b/src/rtc_tc8521.c index 2a98b92e..92650903 100644 --- a/src/rtc_tc8521.c +++ b/src/rtc_tc8521.c @@ -12,12 +12,12 @@ #define peek2(a) (nvrram[(a##1)] + 10 * nvrram[(a##10)]) struct { - int sec; - int min; - int hour; - int mday; - int mon; - int year; + int sec; + int min; + int hour; + int mday; + int mon; + int year; } internal_clock; /* Table for days in each month */ @@ -25,168 +25,172 @@ static int rtc_days_in_month[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, /* Called to determine whether the year is leap or not */ static int rtc_is_leap(int org_year) { - if (org_year % 400 == 0) - return 1; - if (org_year % 100 == 0) - return 0; - if (org_year % 4 == 0) - return 1; - return 0; + if (org_year % 400 == 0) + return 1; + if (org_year % 100 == 0) + return 0; + if (org_year % 4 == 0) + return 1; + return 0; } /* Called to determine the days in the current month */ static int rtc_get_days(int org_month, int org_year) { - if (org_month != 2) - return rtc_days_in_month[org_month - 1]; - else - return rtc_is_leap(org_year) ? 29 : 28; + if (org_month != 2) + return rtc_days_in_month[org_month - 1]; + else + return rtc_is_leap(org_year) ? 29 : 28; } /* Called when the internal clock gets updated */ static void tc8521_recalc() { - if (internal_clock.sec == 60) { - internal_clock.sec = 0; - internal_clock.min++; - } - if (internal_clock.min == 60) { - internal_clock.min = 0; - internal_clock.hour++; - } - if (internal_clock.hour == 24) { - internal_clock.hour = 0; - internal_clock.mday++; - } - if (internal_clock.mday == (rtc_get_days(internal_clock.mon, internal_clock.year) + 1)) { - internal_clock.mday = 1; - internal_clock.mon++; - } - if (internal_clock.mon == 13) { - internal_clock.mon = 1; - internal_clock.year++; - } + if (internal_clock.sec == 60) { + internal_clock.sec = 0; + internal_clock.min++; + } + if (internal_clock.min == 60) { + internal_clock.min = 0; + internal_clock.hour++; + } + if (internal_clock.hour == 24) { + internal_clock.hour = 0; + internal_clock.mday++; + } + if (internal_clock.mday == (rtc_get_days(internal_clock.mon, internal_clock.year) + 1)) { + internal_clock.mday = 1; + internal_clock.mon++; + } + if (internal_clock.mon == 13) { + internal_clock.mon = 1; + internal_clock.year++; + } } /* Called when ticking the second */ void tc8521_tick() { - internal_clock.sec++; - tc8521_recalc(); + internal_clock.sec++; + tc8521_recalc(); } /* Called when modifying the NVR registers */ void tc8521_update(uint8_t *nvrram, int reg) { - int temp; + int temp; - switch (reg) { - case TC8521_SECOND1: - case TC8521_SECOND10:internal_clock.sec = peek2(TC8521_SECOND); - break; - case TC8521_MINUTE1: - case TC8521_MINUTE10:internal_clock.min = peek2(TC8521_MINUTE); - break; - case TC8521_HOUR1: - case TC8521_HOUR10:temp = peek2(TC8521_HOUR); - if (nvrram[TC8521_24HR] & 1) - internal_clock.hour = temp; - else - internal_clock.hour = ((temp & ~0x20) % 12) + ((temp & 0x20) ? 12 : 0); - break; - case TC8521_DAY1: - case TC8521_DAY10:internal_clock.mday = peek2(TC8521_DAY); - break; - case TC8521_MONTH1: - case TC8521_MONTH10:internal_clock.mon = peek2(TC8521_MONTH); - break; - case TC8521_YEAR1: - case TC8521_YEAR10:internal_clock.year = 1980 + peek2(TC8521_YEAR); - break; - } + switch (reg) { + case TC8521_SECOND1: + case TC8521_SECOND10: + internal_clock.sec = peek2(TC8521_SECOND); + break; + case TC8521_MINUTE1: + case TC8521_MINUTE10: + internal_clock.min = peek2(TC8521_MINUTE); + break; + case TC8521_HOUR1: + case TC8521_HOUR10: + temp = peek2(TC8521_HOUR); + if (nvrram[TC8521_24HR] & 1) + internal_clock.hour = temp; + else + internal_clock.hour = ((temp & ~0x20) % 12) + ((temp & 0x20) ? 12 : 0); + break; + case TC8521_DAY1: + case TC8521_DAY10: + internal_clock.mday = peek2(TC8521_DAY); + break; + case TC8521_MONTH1: + case TC8521_MONTH10: + internal_clock.mon = peek2(TC8521_MONTH); + break; + case TC8521_YEAR1: + case TC8521_YEAR10: + internal_clock.year = 1980 + peek2(TC8521_YEAR); + break; + } } /* Called to obtain the current day of the week based on the internal clock */ static int time_week_day() { - int day_of_month = internal_clock.mday; - int month2 = internal_clock.mon; - int year2 = internal_clock.year % 100; - int century = ((internal_clock.year - year2) / 100) % 4; - int sum = day_of_month + month2 + year2 + century; - /* (Sum mod 7) gives 0 for Saturday, we need it for Sunday, so +6 for Saturday to get 6 and Sunday 0 */ - int raw_wd = ((sum + 6) % 7); - return raw_wd; + int day_of_month = internal_clock.mday; + int month2 = internal_clock.mon; + int year2 = internal_clock.year % 100; + int century = ((internal_clock.year - year2) / 100) % 4; + int sum = day_of_month + month2 + year2 + century; + /* (Sum mod 7) gives 0 for Saturday, we need it for Sunday, so +6 for Saturday to get 6 and Sunday 0 */ + int raw_wd = ((sum + 6) % 7); + return raw_wd; } /* Called to get time into the internal clock */ static void tc8521_internal_get(struct tm *time_var) { - time_var->tm_sec = internal_clock.sec; - time_var->tm_min = internal_clock.min; - time_var->tm_hour = internal_clock.hour; - time_var->tm_wday = time_week_day(); - time_var->tm_mday = internal_clock.mday; - time_var->tm_mon = internal_clock.mon - 1; - time_var->tm_year = internal_clock.year - 1900; + time_var->tm_sec = internal_clock.sec; + time_var->tm_min = internal_clock.min; + time_var->tm_hour = internal_clock.hour; + time_var->tm_wday = time_week_day(); + time_var->tm_mday = internal_clock.mday; + time_var->tm_mon = internal_clock.mon - 1; + time_var->tm_year = internal_clock.year - 1900; } static void tc8521_internal_set(struct tm *time_var) { - internal_clock.sec = time_var->tm_sec; - internal_clock.min = time_var->tm_min; - internal_clock.hour = time_var->tm_hour; - internal_clock.mday = time_var->tm_mday; - internal_clock.mon = time_var->tm_mon + 1; - internal_clock.year = time_var->tm_year + 1900; + internal_clock.sec = time_var->tm_sec; + internal_clock.min = time_var->tm_min; + internal_clock.hour = time_var->tm_hour; + internal_clock.mday = time_var->tm_mday; + internal_clock.mon = time_var->tm_mon + 1; + internal_clock.year = time_var->tm_year + 1900; } static void tc8521_set_nvrram(uint8_t *nvrram, struct tm *cur_time_tm) { - nvrram[TC8521_SECOND1] = cur_time_tm->tm_sec % 10; - nvrram[TC8521_SECOND10] = cur_time_tm->tm_sec / 10; - nvrram[TC8521_MINUTE1] = cur_time_tm->tm_min % 10; - nvrram[TC8521_MINUTE10] = cur_time_tm->tm_min / 10; - if (nvrram[TC8521_24HR] & 1) { - nvrram[TC8521_HOUR1] = cur_time_tm->tm_hour % 10; - nvrram[TC8521_HOUR10] = cur_time_tm->tm_hour / 10; - } else { - nvrram[TC8521_HOUR1] = (cur_time_tm->tm_hour % 12) % 10; - nvrram[TC8521_HOUR10] = ((cur_time_tm->tm_hour % 12) / 10) - | (cur_time_tm->tm_hour >= 12) ? 2 : 0; - } - nvrram[TC8521_WEEKDAY] = cur_time_tm->tm_wday; - nvrram[TC8521_DAY1] = cur_time_tm->tm_mday % 10; - nvrram[TC8521_DAY10] = cur_time_tm->tm_mday / 10; - nvrram[TC8521_MONTH1] = (cur_time_tm->tm_mon + 1) / 10; - nvrram[TC8521_MONTH10] = (cur_time_tm->tm_mon + 1) % 10; - nvrram[TC8521_YEAR1] = (cur_time_tm->tm_year - 80) % 10; - nvrram[TC8521_YEAR10] = ((cur_time_tm->tm_year - 80) % 100) / 10; + nvrram[TC8521_SECOND1] = cur_time_tm->tm_sec % 10; + nvrram[TC8521_SECOND10] = cur_time_tm->tm_sec / 10; + nvrram[TC8521_MINUTE1] = cur_time_tm->tm_min % 10; + nvrram[TC8521_MINUTE10] = cur_time_tm->tm_min / 10; + if (nvrram[TC8521_24HR] & 1) { + nvrram[TC8521_HOUR1] = cur_time_tm->tm_hour % 10; + nvrram[TC8521_HOUR10] = cur_time_tm->tm_hour / 10; + } else { + nvrram[TC8521_HOUR1] = (cur_time_tm->tm_hour % 12) % 10; + nvrram[TC8521_HOUR10] = ((cur_time_tm->tm_hour % 12) / 10) | (cur_time_tm->tm_hour >= 12) ? 2 : 0; + } + nvrram[TC8521_WEEKDAY] = cur_time_tm->tm_wday; + nvrram[TC8521_DAY1] = cur_time_tm->tm_mday % 10; + nvrram[TC8521_DAY10] = cur_time_tm->tm_mday / 10; + nvrram[TC8521_MONTH1] = (cur_time_tm->tm_mon + 1) / 10; + nvrram[TC8521_MONTH10] = (cur_time_tm->tm_mon + 1) % 10; + nvrram[TC8521_YEAR1] = (cur_time_tm->tm_year - 80) % 10; + nvrram[TC8521_YEAR10] = ((cur_time_tm->tm_year - 80) % 100) / 10; } void tc8521_internal_set_nvrram(uint8_t *nvrram) { - /* Load the entire internal clock state from the NVR. */ - internal_clock.sec = peek2(TC8521_SECOND); - internal_clock.min = peek2(TC8521_MINUTE); - if (nvrram[TC8521_24HR] & 1) { - internal_clock.hour = peek2(TC8521_HOUR); - } else { - internal_clock.hour = (peek2(TC8521_HOUR) % 12) - + (nvrram[TC8521_HOUR10] & 2) ? 12 : 0; - } - internal_clock.mday = peek2(TC8521_DAY); - internal_clock.mon = peek2(TC8521_MONTH); - internal_clock.year = 1980 + peek2(TC8521_YEAR); + /* Load the entire internal clock state from the NVR. */ + internal_clock.sec = peek2(TC8521_SECOND); + internal_clock.min = peek2(TC8521_MINUTE); + if (nvrram[TC8521_24HR] & 1) { + internal_clock.hour = peek2(TC8521_HOUR); + } else { + internal_clock.hour = (peek2(TC8521_HOUR) % 12) + (nvrram[TC8521_HOUR10] & 2) ? 12 : 0; + } + internal_clock.mday = peek2(TC8521_DAY); + internal_clock.mon = peek2(TC8521_MONTH); + internal_clock.year = 1980 + peek2(TC8521_YEAR); } void tc8521_internal_sync(uint8_t *nvrram) { - struct tm *cur_time_tm; - time_t cur_time; + struct tm *cur_time_tm; + time_t cur_time; - time(&cur_time); - cur_time_tm = localtime(&cur_time); + time(&cur_time); + cur_time_tm = localtime(&cur_time); - tc8521_internal_set(cur_time_tm); + tc8521_internal_set(cur_time_tm); - tc8521_set_nvrram(nvrram, cur_time_tm); + tc8521_set_nvrram(nvrram, cur_time_tm); } void tc8521_get(uint8_t *nvrram) { - struct tm cur_time_tm; + struct tm cur_time_tm; - tc8521_internal_get(&cur_time_tm); + tc8521_internal_get(&cur_time_tm); - tc8521_set_nvrram(nvrram, &cur_time_tm); + tc8521_set_nvrram(nvrram, &cur_time_tm); } diff --git a/src/scsi/scsi.c b/src/scsi/scsi.c index 97ace10a..4dbb8076 100644 --- a/src/scsi/scsi.c +++ b/src/scsi/scsi.c @@ -15,325 +15,338 @@ #define STATE_MESSAGEIN 6 #define STATE_PHASESEL 7 -#define SET_BUS_STATE(bus, state) bus->bus_out = (bus->bus_out & ~(BUS_CD | BUS_IO | BUS_MSG)) | (state & (BUS_CD | BUS_IO | BUS_MSG)) +#define SET_BUS_STATE(bus, state) \ + bus->bus_out = (bus->bus_out & ~(BUS_CD | BUS_IO | BUS_MSG)) | (state & (BUS_CD | BUS_IO | BUS_MSG)) static int cmd_len[8] = {6, 10, 10, 6, 16, 12, 6, 6}; static int get_dev_id(uint8_t data) { - int c; + int c; - for (c = 0; c < 8; c++) { - if (data & (1 << c)) - return c; - } + for (c = 0; c < 8; c++) { + if (data & (1 << c)) + return c; + } - return -1; + return -1; } int scsi_bus_update(scsi_bus_t *bus, int bus_assert) { - scsi_device_t *dev = NULL; - void *dev_data = NULL; + scsi_device_t *dev = NULL; + void *dev_data = NULL; -// pclog("scsi_hd_bus_update: state=%d bus_assert=%04x bus_in=%02x %i %02x %p\n", bus->state, bus_assert, bus->bus_in, bus->clear_req, bus->bus_out, bus); + // pclog("scsi_hd_bus_update: state=%d bus_assert=%04x bus_in=%02x %i %02x %p\n", bus->state, bus_assert, + // bus->bus_in, bus->clear_req, bus->bus_out, bus); - if (bus_assert & BUS_ARB) - bus->state = STATE_IDLE; + if (bus_assert & BUS_ARB) + bus->state = STATE_IDLE; - if (bus->dev_id != -1) { - dev = bus->devices[bus->dev_id]; - dev_data = bus->device_data[bus->dev_id]; - } + if (bus->dev_id != -1) { + dev = bus->devices[bus->dev_id]; + dev_data = bus->device_data[bus->dev_id]; + } - switch (bus->state) { - case STATE_IDLE: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); + switch (bus->state) { + case STATE_IDLE: + 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->state = STATE_PHASESEL; - bus->dev_id = get_dev_id(sel_data); -// pclog("PHASESEL %02x %2x %i %p\n", sel_data, bus->bus_out, bus->dev_id, bus->devices[bus->dev_id]); - if (bus->dev_id != -1 && bus->devices[bus->dev_id]) { - bus->bus_out |= BUS_BSY; - bus->state = STATE_PHASESEL; -// pclog("Move to phase sel\n"); - } - break; - } - break; - case STATE_PHASESEL: - if (!(bus_assert & BUS_SEL)) { - if (!(bus_assert & BUS_ATN)) { -/* uint8_t sel_data = BUS_GETDATA(bus_assert); - - bus->dev_id = get_dev_id(sel_data);*/ -// pclog("STATE_PHASESEL: %i %p\n", bus->dev_id, bus->devices[bus->dev_id]); - if (bus->dev_id != -1 && bus->devices[bus->dev_id]) { - bus->state = STATE_COMMAND; - bus->bus_out = BUS_BSY | BUS_REQ; - bus->command_pos = 0; - SET_BUS_STATE(bus, BUS_CD); - } 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)) { -// pclog(" get data %02x\n", BUS_GETDATA(bus_assert)); - bus->command[bus->command_pos++] = BUS_GETDATA(bus_assert); - bus->clear_req = 3; - bus->new_state = bus->bus_out & (BUS_IO | BUS_CD | BUS_MSG); - bus->bus_out &= ~BUS_REQ; + // bus->state = STATE_PHASESEL; + bus->dev_id = get_dev_id(sel_data); + // pclog("PHASESEL %02x %2x %i %p\n", sel_data, bus->bus_out, bus->dev_id, + // bus->devices[bus->dev_id]); + if (bus->dev_id != -1 && bus->devices[bus->dev_id]) { + bus->bus_out |= BUS_BSY; + bus->state = STATE_PHASESEL; + // pclog("Move to phase sel\n"); + } + break; + } + break; + case STATE_PHASESEL: + if (!(bus_assert & BUS_SEL)) { + if (!(bus_assert & BUS_ATN)) { + /* uint8_t sel_data = BUS_GETDATA(bus_assert); - if (bus->command_pos == (bus->is_atapi ? 12 : cmd_len[bus->command[0] >> 5])) { - int new_state; + bus->dev_id = get_dev_id(sel_data);*/ + // pclog("STATE_PHASESEL: %i %p\n", bus->dev_id, + // bus->devices[bus->dev_id]); + if (bus->dev_id != -1 && bus->devices[bus->dev_id]) { + bus->state = STATE_COMMAND; + bus->bus_out = BUS_BSY | BUS_REQ; + bus->command_pos = 0; + SET_BUS_STATE(bus, BUS_CD); + } 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)) { + // pclog(" get data %02x\n", BUS_GETDATA(bus_assert)); + bus->command[bus->command_pos++] = BUS_GETDATA(bus_assert); + bus->clear_req = 3; + bus->new_state = bus->bus_out & (BUS_IO | BUS_CD | BUS_MSG); + bus->bus_out &= ~BUS_REQ; - dev->start_command(dev_data); - new_state = dev->command(bus->command, dev_data); -// pclog("COMMAND new_state = %x\n", new_state); - if ((new_state & (BUS_IO | BUS_CD | BUS_MSG)) == BUS_CD) { - bus->state = STATE_COMMANDWAIT; - bus->clear_req = 0; - } else { -// pclog("Set change_state_delay COMMAND\n"); - bus->new_state = new_state; - bus->change_state_delay = 4; - } - } - } - break; + if (bus->command_pos == (bus->is_atapi ? 12 : cmd_len[bus->command[0] >> 5])) { + int new_state; - case STATE_COMMANDWAIT: { - int new_state; + dev->start_command(dev_data); + new_state = dev->command(bus->command, dev_data); + // pclog("COMMAND new_state = %x\n", new_state); + if ((new_state & (BUS_IO | BUS_CD | BUS_MSG)) == BUS_CD) { + bus->state = STATE_COMMANDWAIT; + bus->clear_req = 0; + } else { + // pclog("Set change_state_delay COMMAND\n"); + bus->new_state = new_state; + bus->change_state_delay = 4; + } + } + } + break; -// pclog("COMMANDWAIT\n"); - new_state = dev->command(bus->command, dev_data); -// pclog("new_state=%x\n", new_state); - if ((new_state & (BUS_IO | BUS_CD | BUS_MSG)) != BUS_CD) { -// pclog("Set change_state_delay\n"); - bus->new_state = new_state; - bus->change_state_delay = 4; - bus->clear_req = 4; - } - } - break; + case STATE_COMMANDWAIT: { + int new_state; - case STATE_DATAIN: - if ((bus_assert & BUS_ACK) && !(bus->bus_in & BUS_ACK)) { - if (dev->read_complete(dev_data)) { -// pclog("Read complete\n"); - bus->bus_out &= ~BUS_REQ; - //bus->clear_req = 3; - bus->new_state = BUS_CD | BUS_IO; -// pclog("change_state_delay STATE_DATAIN\n"); - bus->change_state_delay = 4; - bus->new_req_delay = 8; -// SET_BUS_STATE(data, BUS_CD | BUS_IO); - } else { - uint8_t val = dev->read(dev_data); + // pclog("COMMANDWAIT\n"); + new_state = dev->command(bus->command, dev_data); + // pclog("new_state=%x\n", new_state); + if ((new_state & (BUS_IO | BUS_CD | BUS_MSG)) != BUS_CD) { + // pclog("Set change_state_delay\n"); + bus->new_state = new_state; + bus->change_state_delay = 4; + bus->clear_req = 4; + } + } break; -// pclog(" Read data pos %04x %02x %x %x\n", bus->data_pos_read, bus->data_in[bus->data_pos_read], bus->data_pos_read, bus->data_pos_write); - bus->bus_out = (bus->bus_out & ~BUS_DATAMASK) | BUS_SETDATA(val) | BUS_DBP | BUS_REQ; -// bus->bus_out |= BUS_REQ; - bus->clear_req = 3; - bus->bus_out &= ~BUS_REQ; - bus->new_state = BUS_IO; - } -// scsi_hd_command(bus->command, data); - } - break; + case STATE_DATAIN: + if ((bus_assert & BUS_ACK) && !(bus->bus_in & BUS_ACK)) { + if (dev->read_complete(dev_data)) { + // pclog("Read complete\n"); + bus->bus_out &= ~BUS_REQ; + // bus->clear_req = 3; + bus->new_state = BUS_CD | BUS_IO; + // pclog("change_state_delay STATE_DATAIN\n"); + bus->change_state_delay = 4; + bus->new_req_delay = 8; + // SET_BUS_STATE(data, BUS_CD | BUS_IO); + } else { + uint8_t val = dev->read(dev_data); - case STATE_DATAOUT: - if ((bus_assert & BUS_ACK) && !(bus->bus_in & BUS_ACK)) { - dev->write(BUS_GETDATA(bus_assert), dev_data); -// pclog("Got data %02x\n", BUS_GETDATA(bus_assert)); -// pclog(" Write data pos %04x %02x %08x %08x\n", bus->data_pos_write-1, bus->data_out[bus->data_pos_write-1], cpu_getd(5), cpu_getd(6)); + // pclog(" Read data pos %04x %02x %x %x\n", bus->data_pos_read, + // bus->data_in[bus->data_pos_read], bus->data_pos_read, + // bus->data_pos_write); + bus->bus_out = (bus->bus_out & ~BUS_DATAMASK) | BUS_SETDATA(val) | BUS_DBP | BUS_REQ; + // bus->bus_out |= BUS_REQ; + bus->clear_req = 3; + bus->bus_out &= ~BUS_REQ; + bus->new_state = BUS_IO; + } + // scsi_hd_command(bus->command, data); + } + break; - if (dev->write_complete(dev_data)) { - int new_state; - //pclog(" Write data, command complete\n"); - bus->bus_out &= ~BUS_REQ; - new_state = dev->command(bus->command, dev_data); + case STATE_DATAOUT: + if ((bus_assert & BUS_ACK) && !(bus->bus_in & BUS_ACK)) { + dev->write(BUS_GETDATA(bus_assert), dev_data); + // pclog("Got data %02x\n", BUS_GETDATA(bus_assert)); + // pclog(" Write data pos %04x %02x %08x %08x\n", bus->data_pos_write-1, + // bus->data_out[bus->data_pos_write-1], cpu_getd(5), cpu_getd(6)); - bus->new_state = new_state; -// pclog("change_state_delay STATE_DATAOUT\n"); - bus->change_state_delay = 4; - bus->new_req_delay = 8; - } else { - bus->bus_out |= BUS_REQ; - } - } - break; + if (dev->write_complete(dev_data)) { + int new_state; + // pclog(" Write data, command complete\n"); + bus->bus_out &= ~BUS_REQ; + new_state = dev->command(bus->command, dev_data); - case STATE_STATUS: - if ((bus_assert & BUS_ACK) && !(bus->bus_in & BUS_ACK)) { - bus->bus_out &= ~BUS_REQ; -/* bus->clear_req = 3;*/ - bus->new_state = BUS_CD | BUS_IO | BUS_MSG; -// pclog("change_state_delay STATE_STATUS\n"); - bus->change_state_delay = 4; - bus->new_req_delay = 8; -/* bus->state = STATE_MESSAGEIN;*/ - } - break; + bus->new_state = new_state; + // pclog("change_state_delay STATE_DATAOUT\n"); + bus->change_state_delay = 4; + bus->new_req_delay = 8; + } else { + bus->bus_out |= BUS_REQ; + } + } + break; - case STATE_MESSAGEIN: - if ((bus_assert & BUS_ACK) && !(bus->bus_in & BUS_ACK)) { -// pclog("Scheduling change to idle\n"); - bus->bus_out &= ~BUS_REQ; - bus->new_state = BUS_IDLE; -// pclog("change_state_delay STATE_MESSAGEIN\n"); - bus->change_state_delay = 4; -/* bus->bus_out &= ~BUS_BSY; - SET_BUS_STATE(bus, BUS_CD | BUS_IO); - bus->state = STATE_IDLE;*/ - } - break; - } - bus->bus_in = bus_assert; + case STATE_STATUS: + if ((bus_assert & BUS_ACK) && !(bus->bus_in & BUS_ACK)) { + bus->bus_out &= ~BUS_REQ; + /* bus->clear_req = 3;*/ + bus->new_state = BUS_CD | BUS_IO | BUS_MSG; + // pclog("change_state_delay STATE_STATUS\n"); + bus->change_state_delay = 4; + bus->new_req_delay = 8; + /* bus->state = STATE_MESSAGEIN;*/ + } + break; - return bus->bus_out | bus->bus_in; + case STATE_MESSAGEIN: + if ((bus_assert & BUS_ACK) && !(bus->bus_in & BUS_ACK)) { + // pclog("Scheduling change to idle\n"); + bus->bus_out &= ~BUS_REQ; + bus->new_state = BUS_IDLE; + // pclog("change_state_delay STATE_MESSAGEIN\n"); + bus->change_state_delay = 4; + /* bus->bus_out &= ~BUS_BSY; + SET_BUS_STATE(bus, BUS_CD | BUS_IO); + bus->state = STATE_IDLE;*/ + } + 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 = NULL; - void *dev_data = NULL; + scsi_device_t *dev = NULL; + void *dev_data = NULL; - if (bus->dev_id != -1) { - dev = bus->devices[bus->dev_id]; - dev_data = bus->device_data[bus->dev_id]; - } + if (bus->dev_id != -1) { + dev = bus->devices[bus->dev_id]; + dev_data = bus->device_data[bus->dev_id]; + } -// pclog("scsi_hd_bus_read: bus_out=%02x bus_in=%02x %i %i %i\n", bus->bus_out, bus->bus_in, bus->clear_req, bus->change_state_delay, bus->new_req_delay); + // pclog("scsi_hd_bus_read: bus_out=%02x bus_in=%02x %i %i %i\n", bus->bus_out, bus->bus_in, bus->clear_req, + // bus->change_state_delay, bus->new_req_delay); - if (bus->clear_req) { - bus->clear_req--; - if (!bus->clear_req) { - SET_BUS_STATE(bus, bus->new_state); -// pclog("clear_req\n"); - bus->bus_out |= BUS_REQ; - } - } + if (bus->clear_req) { + bus->clear_req--; + if (!bus->clear_req) { + SET_BUS_STATE(bus, bus->new_state); + // pclog("clear_req\n"); + bus->bus_out |= BUS_REQ; + } + } - if (bus->change_state_delay) { - bus->change_state_delay--; - if (!bus->change_state_delay) { - uint8_t val; + if (bus->change_state_delay) { + bus->change_state_delay--; + if (!bus->change_state_delay) { + uint8_t val; -// pclog("change_state_delay %08x\n", bus->bus_out & (BUS_IO | BUS_CD | BUS_MSG | BUS_IDLE)); - SET_BUS_STATE(bus, bus->new_state); + // pclog("change_state_delay %08x\n", bus->bus_out & (BUS_IO | BUS_CD | BUS_MSG | + // BUS_IDLE)); + SET_BUS_STATE(bus, bus->new_state); - switch (bus->bus_out & (BUS_IO | BUS_CD | BUS_MSG)) { - case BUS_IO:bus->state = STATE_DATAIN; - val = dev->read(dev_data); - bus->bus_out = (bus->bus_out & ~BUS_DATAMASK) | BUS_SETDATA(val) | BUS_DBP; - break; + switch (bus->bus_out & (BUS_IO | BUS_CD | BUS_MSG)) { + case BUS_IO: + bus->state = STATE_DATAIN; + val = dev->read(dev_data); + bus->bus_out = (bus->bus_out & ~BUS_DATAMASK) | BUS_SETDATA(val) | BUS_DBP; + break; - case 0: - if (bus->new_state & BUS_IDLE) { - bus->state = STATE_IDLE; - bus->bus_out &= ~BUS_BSY; - } else - bus->state = STATE_DATAOUT; - break; + case 0: + if (bus->new_state & BUS_IDLE) { + bus->state = STATE_IDLE; + bus->bus_out &= ~BUS_BSY; + } else + bus->state = STATE_DATAOUT; + break; - case (BUS_IO | BUS_CD):bus->state = STATE_STATUS; - bus->bus_out = (bus->bus_out & ~BUS_DATAMASK) | BUS_SETDATA(dev->get_status(dev_data)) | BUS_DBP; - break; + case (BUS_IO | BUS_CD): + bus->state = STATE_STATUS; + bus->bus_out = (bus->bus_out & ~BUS_DATAMASK) | BUS_SETDATA(dev->get_status(dev_data)) | BUS_DBP; + break; - case (BUS_CD | BUS_IO | BUS_MSG):bus->state = STATE_MESSAGEIN; - bus->bus_out = (bus->bus_out & ~BUS_DATAMASK) | BUS_SETDATA(0) | BUS_DBP; - break; + case (BUS_CD | BUS_IO | BUS_MSG): + 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); - } + 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) { + // pclog("new_req_delay\n"); + bus->bus_out |= BUS_REQ; + } + } - } - } - if (bus->new_req_delay) { - bus->new_req_delay--; - if (!bus->new_req_delay) { -// pclog("new_req_delay\n"); - bus->bus_out |= BUS_REQ; - } - } - -// pclog(" bus_out now %02x\n", bus->bus_out); - return bus->bus_out;// | bus->bus_in; + // pclog(" bus_out now %02x\n", bus->bus_out); + return bus->bus_out; // | bus->bus_in; } int scsi_bus_match(scsi_bus_t *bus, int bus_assert) { -// pclog("bus_match %02x %02x\n", bus_assert & (BUS_CD | BUS_IO | BUS_MSG), bus->bus_out & (BUS_CD | BUS_IO | BUS_MSG)); + // pclog("bus_match %02x %02x\n", bus_assert & (BUS_CD | BUS_IO | BUS_MSG), bus->bus_out & (BUS_CD | BUS_IO | + // BUS_MSG)); - return (bus_assert & (BUS_CD | BUS_IO | BUS_MSG)) == (bus->bus_out & (BUS_CD | BUS_IO | BUS_MSG)); + return (bus_assert & (BUS_CD | BUS_IO | BUS_MSG)) == (bus->bus_out & (BUS_CD | BUS_IO | BUS_MSG)); } void scsi_bus_kick(scsi_bus_t *bus) { -// pclog("scsi_bus_kick\n"); - scsi_bus_update(bus, 0); + // pclog("scsi_bus_kick\n"); + scsi_bus_update(bus, 0); } void scsi_bus_atapi_init(scsi_bus_t *bus, scsi_device_t *device, int id, atapi_device_t *atapi_dev) { - memset(bus->devices, 0, sizeof(bus->devices)); - memset(bus->device_data, 0, sizeof(bus->device_data)); + memset(bus->devices, 0, sizeof(bus->devices)); + memset(bus->device_data, 0, sizeof(bus->device_data)); - bus->devices[0] = device; - bus->device_data[0] = bus->devices[0]->atapi_init(bus, id, atapi_dev); - if (!bus->device_data[0]) - bus->devices[0] = NULL; + bus->devices[0] = device; + bus->device_data[0] = bus->devices[0]->atapi_init(bus, id, atapi_dev); + if (!bus->device_data[0]) + bus->devices[0] = NULL; - bus->is_atapi = 1; + bus->is_atapi = 1; } void scsi_bus_init(scsi_bus_t *bus) { - int c; + int c; - memset(bus->devices, 0, sizeof(bus->devices)); - memset(bus->device_data, 0, sizeof(bus->device_data)); + memset(bus->devices, 0, sizeof(bus->devices)); + memset(bus->device_data, 0, sizeof(bus->device_data)); - for (c = 0; c < 7; c++) { - if (cdrom_channel == c) - bus->devices[c] = &scsi_cd; - else if (zip_channel == c) - bus->devices[c] = &scsi_zip; - else - bus->devices[c] = &scsi_hd; + for (c = 0; c < 7; c++) { + if (cdrom_channel == c) + bus->devices[c] = &scsi_cd; + else if (zip_channel == c) + bus->devices[c] = &scsi_zip; + else + bus->devices[c] = &scsi_hd; - bus->device_data[c] = bus->devices[c]->init(bus, c); - if (!bus->device_data[c]) - bus->devices[c] = NULL; - } + bus->device_data[c] = bus->devices[c]->init(bus, c); + if (!bus->device_data[c]) + bus->devices[c] = NULL; + } - bus->is_atapi = 0; + bus->is_atapi = 0; } void scsi_bus_close(scsi_bus_t *bus) { - int c; + int c; - memset(bus->devices, 0, sizeof(bus->devices)); - memset(bus->device_data, 0, sizeof(bus->device_data)); + memset(bus->devices, 0, sizeof(bus->devices)); + memset(bus->device_data, 0, sizeof(bus->device_data)); - for (c = 0; c < 8; c++) { - if (bus->device_data[c]) - bus->devices[c]->close(bus->device_data[c]); - } + for (c = 0; c < 8; c++) { + if (bus->device_data[c]) + bus->devices[c]->close(bus->device_data[c]); + } } void scsi_bus_reset(scsi_bus_t *bus) { - int c; + int c; - bus->state = STATE_IDLE; - bus->clear_req = 0; - bus->change_state_delay = 0; - bus->new_req_delay = 0; - bus->bus_in = bus->bus_out = 0; - bus->command_pos = 0; + bus->state = STATE_IDLE; + bus->clear_req = 0; + bus->change_state_delay = 0; + bus->new_req_delay = 0; + bus->bus_in = bus->bus_out = 0; + bus->command_pos = 0; - for (c = 0; c < 8; c++) { - if (bus->device_data[c] && bus->devices[c]->reset) - bus->devices[c]->reset(bus->device_data[c]); - } + for (c = 0; c < 8; c++) { + if (bus->device_data[c] && bus->devices[c]->reset) + bus->devices[c]->reset(bus->device_data[c]); + } } diff --git a/src/scsi/scsi_53c400.c b/src/scsi/scsi_53c400.c index bcab955d..b49e6657 100644 --- a/src/scsi/scsi_53c400.c +++ b/src/scsi/scsi_53c400.c @@ -12,65 +12,65 @@ #define MAX_BYTES_TRANSFERRED_PER_POLL 50 typedef struct ncr5380_t { - uint8_t output_data; - uint8_t icr; - uint8_t mode; - uint8_t tcr; - uint8_t ser; - uint8_t isr; + uint8_t output_data; + uint8_t icr; + uint8_t mode; + uint8_t tcr; + uint8_t ser; + uint8_t isr; - int target_id; - int target_bsy; - int target_req; + int target_id; + int target_bsy; + int target_req; - uint8_t bus_status; + uint8_t bus_status; - int dma_mode; + int dma_mode; - void (*dma_changed)(struct ncr5380_t *ncr, int mode, int enable); - void *p; + void (*dma_changed)(struct ncr5380_t *ncr, int mode, int enable); + void *p; - scsi_bus_t bus; + scsi_bus_t bus; } ncr5380_t; typedef struct lcs6821n_t { - rom_t bios_rom; + rom_t bios_rom; - mem_mapping_t mapping; + mem_mapping_t mapping; - uint8_t block_count; - int block_count_loaded; + uint8_t block_count; + int block_count_loaded; - uint8_t status_ctrl; + uint8_t status_ctrl; - uint8_t buffer[0x80]; - int buffer_pos; - int buffer_host_pos; + uint8_t buffer[0x80]; + int buffer_pos; + int buffer_host_pos; - uint8_t int_ram[0x40]; - uint8_t ext_ram[0x600]; + uint8_t int_ram[0x40]; + uint8_t ext_ram[0x600]; - ncr5380_t ncr; + ncr5380_t ncr; - int ncr5380_dma_enabled; + int ncr5380_dma_enabled; - pc_timer_t dma_timer; + pc_timer_t dma_timer; - int ncr_busy; + int ncr_busy; } lcs6821n_t; -#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_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 MODE_DMA 0x02 +#define MODE_MONITOR_BUSY 0x04 +#define MODE_ENA_EOP_INT 0x08 #define STATUS_ACK 0x01 #define STATUS_BUSY_ERROR 0x04 @@ -78,214 +78,208 @@ typedef struct lcs6821n_t { #define STATUS_DRQ 0x40 #define STATUS_END_OF_DMA 0x80 -#define TCR_IO 0x01 -#define TCR_CD 0x02 +#define TCR_IO 0x01 +#define TCR_CD 0x02 #define TCR_MSG 0x04 #define TCR_REQ 0x08 #define TCR_LAST_BYTE_SENT 0x80 -enum { - DMA_IDLE = 0, - DMA_SEND, - DMA_TARGET_RECEIVE, - DMA_INITIATOR_RECEIVE -}; +enum { DMA_IDLE = 0, DMA_SEND, DMA_TARGET_RECEIVE, DMA_INITIATOR_RECEIVE }; static void set_dma_enable(lcs6821n_t *scsi, int enable) { - if (enable) { - if (!timer_is_enabled(&scsi->dma_timer)) - timer_set_delay_u64(&scsi->dma_timer, TIMER_USEC * POLL_TIME_US); - } else - timer_disable(&scsi->dma_timer); + if (enable) { + if (!timer_is_enabled(&scsi->dma_timer)) + timer_set_delay_u64(&scsi->dma_timer, TIMER_USEC * POLL_TIME_US); + } else + timer_disable(&scsi->dma_timer); } static void ncr53c400_dma_changed(ncr5380_t *ncr, int mode, int enable) { - lcs6821n_t *scsi = (lcs6821n_t *)ncr->p; + lcs6821n_t *scsi = (lcs6821n_t *)ncr->p; - scsi->ncr5380_dma_enabled = (mode && enable); + scsi->ncr5380_dma_enabled = (mode && enable); - set_dma_enable(scsi, scsi->ncr5380_dma_enabled && scsi->block_count_loaded); + set_dma_enable(scsi, scsi->ncr5380_dma_enabled && scsi->block_count_loaded); } -void ncr5380_reset(ncr5380_t *ncr) { - memset(ncr, 0, sizeof(ncr5380_t)); -} +void ncr5380_reset(ncr5380_t *ncr) { memset(ncr, 0, sizeof(ncr5380_t)); } static uint32_t get_bus_host(ncr5380_t *ncr) { - uint32_t bus_host = 0; + 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; -// pclog("get_bus_host %02x %08x\n", ncr->output_data, BUS_SETDATA(ncr->output_data)); - return bus_host | BUS_SETDATA(ncr->output_data); + 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; + // pclog("get_bus_host %02x %08x\n", ncr->output_data, BUS_SETDATA(ncr->output_data)); + return bus_host | BUS_SETDATA(ncr->output_data); } void ncr5380_write(uint32_t addr, uint8_t val, void *p) { - ncr5380_t *ncr = (ncr5380_t *)p; - int bus_host = 0; + ncr5380_t *ncr = (ncr5380_t *)p; + int bus_host = 0; -// pclog("ncr5380_write: addr=%06x val=%02x %04x:%04x\n", addr, val, CS,cpu_state.pc); - switch (addr & 7) { - case 0: /*Output data register*/ - ncr->output_data = val; - break; + // pclog("ncr5380_write: addr=%06x val=%02x %04x:%04x\n", addr, val, CS,cpu_state.pc); + switch (addr & 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; + 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++; - } -// pclog("Select - target ID = %i\n", ncr->target_id); + ncr->target_id = -1; + while (temp) { + temp >>= 1; + ncr->target_id++; + } + // pclog("Select - target ID = %i\n", ncr->target_id); - if (!ncr->target_id) - ncr->target_bsy = 1; - } + if (!ncr->target_id) + ncr->target_bsy = 1; + } - ncr->icr = val; - break; + 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; - } + case 2: /*Mode register*/ + if ((val & MODE_ARBITRATE) && !(ncr->mode & MODE_ARBITRATE)) { + ncr->icr &= ~ICR_ARB_LOST; + ncr->icr |= ICR_ARB_IN_PROGRESS; + } -// output = 1; - ncr->mode = val; - ncr->dma_changed(ncr, 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; + // output = 1; + ncr->mode = val; + ncr->dma_changed(ncr, 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; -/* switch (val & (TCR_MSG | TCR_CD | TCR_IO)) - { - case TCR_CD: - ncr->target_req = 1; - break; - }*/ - break; - case 4: /*Select Enable Register*/ - ncr->ser = val; - break; + case 3: /*Target Command Register*/ + ncr->tcr = val; + /* switch (val & (TCR_MSG | TCR_CD | TCR_IO)) + { + case TCR_CD: + ncr->target_req = 1; + break; + }*/ + break; + case 4: /*Select Enable Register*/ + ncr->ser = val; + break; - case 5: /*Start DMA Send*/ - ncr->dma_mode = DMA_SEND; - ncr->dma_changed(ncr, ncr->dma_mode, ncr->mode & MODE_DMA); - break; + case 5: /*Start DMA Send*/ + ncr->dma_mode = DMA_SEND; + ncr->dma_changed(ncr, ncr->dma_mode, ncr->mode & MODE_DMA); + break; - case 7: /*Start DMA Initiator Receive*/ - ncr->dma_mode = DMA_INITIATOR_RECEIVE; - ncr->dma_changed(ncr, ncr->dma_mode, ncr->mode & MODE_DMA); - break; + case 7: /*Start DMA Initiator Receive*/ + ncr->dma_mode = DMA_INITIATOR_RECEIVE; + ncr->dma_changed(ncr, ncr->dma_mode, ncr->mode & MODE_DMA); + break; - default:pclog("Bad NCR5380 write %06x %02x\n", addr, val); - } + default: + pclog("Bad NCR5380 write %06x %02x\n", addr, val); + } - bus_host = get_bus_host(ncr); + bus_host = get_bus_host(ncr); - scsi_bus_update(&ncr->bus, bus_host); + scsi_bus_update(&ncr->bus, bus_host); } uint8_t ncr5380_read(uint32_t addr, void *p) { - ncr5380_t *ncr = (ncr5380_t *)p; - uint32_t bus = 0; - uint8_t temp = 0xff; + ncr5380_t *ncr = (ncr5380_t *)p; + uint32_t bus = 0; + uint8_t temp = 0xff; - switch (addr & 7) { - case 0: /*Current SCSI Data*/ - //output = 3; - //fatal("Here\n"); - if (ncr->icr & ICR_DBP) - temp = ncr->output_data; - else { - bus = scsi_bus_read(&ncr->bus); - temp = BUS_GETDATA(bus); - } - break; - case 1: /*Initiator Command Register*/ - temp = ncr->icr; - break; - case 2: /*Mode Register*/ - temp = ncr->mode; - break; - case 3: /*Target Command Register*/ - temp = ncr->tcr; - break; + switch (addr & 7) { + case 0: /*Current SCSI Data*/ + // output = 3; + // fatal("Here\n"); + if (ncr->icr & ICR_DBP) + temp = ncr->output_data; + else { + bus = scsi_bus_read(&ncr->bus); + temp = BUS_GETDATA(bus); + } + break; + case 1: /*Initiator Command Register*/ + temp = ncr->icr; + break; + case 2: /*Mode Register*/ + temp = ncr->mode; + break; + case 3: /*Target Command Register*/ + temp = ncr->tcr; + break; - case 4: /*Current SCSI Bus Status*/ - temp = 0;//get_bus_host(ncr); - bus = scsi_bus_read(&ncr->bus); -// pclog(" SCSI bus status = %02x %02x\n", temp, bus); - temp |= (bus & 0xff); -// pclog(" SCSI bus status = %02x\n", temp); - break; + case 4: /*Current SCSI Bus Status*/ + temp = 0; // get_bus_host(ncr); + bus = scsi_bus_read(&ncr->bus); + // pclog(" SCSI bus status = %02x %02x\n", temp, bus); + temp |= (bus & 0xff); + // pclog(" SCSI bus status = %02x\n", temp); + break; - case 5: /*Bus and Status Register*/ - temp = 0; + case 5: /*Bus and Status Register*/ + temp = 0; - bus = get_bus_host(ncr); - if (scsi_bus_match(&ncr->bus, bus)) - temp |= 8; - bus = scsi_bus_read(&ncr->bus); + bus = get_bus_host(ncr); + if (scsi_bus_match(&ncr->bus, bus)) + temp |= 8; + bus = scsi_bus_read(&ncr->bus); - if (bus & BUS_ACK) - temp |= STATUS_ACK; - if ((bus & BUS_REQ) && (ncr->mode & MODE_DMA)) - temp |= 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)) - temp |= STATUS_BUSY_ERROR; - temp |= (ncr->isr & (STATUS_INT | STATUS_END_OF_DMA)); + if (bus & BUS_ACK) + temp |= STATUS_ACK; + if ((bus & BUS_REQ) && (ncr->mode & MODE_DMA)) + temp |= 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)) + temp |= STATUS_BUSY_ERROR; + temp |= (ncr->isr & (STATUS_INT | STATUS_END_OF_DMA)); -// pclog(" bus and status register = %02x\n", temp); - break; + // pclog(" bus and status register = %02x\n", temp); + break; - case 7: /*Reset Parity/Interrupt*/ - ncr->isr &= ~STATUS_INT; - break; + case 7: /*Reset Parity/Interrupt*/ + ncr->isr &= ~STATUS_INT; + break; - default:pclog("Bad NCR5380 read %06x\n", addr); - } -// pclog("ncr5380_read: addr=%06x temp=%02x pc=%04x:%04x\n", addr, temp, CS,cpu_state.pc); - return temp; + default: + pclog("Bad NCR5380 read %06x\n", addr); + } + // pclog("ncr5380_read: addr=%06x temp=%02x pc=%04x:%04x\n", addr, temp, CS,cpu_state.pc); + return temp; } #define CTRL_DATA_DIR (1 << 6) @@ -294,489 +288,452 @@ uint8_t ncr5380_read(uint32_t addr, void *p) { #define STATUS_53C80_ACCESSIBLE (1 << 7) static uint8_t lcs6821n_read(uint32_t addr, void *p) { - lcs6821n_t *scsi = (lcs6821n_t *)p; - uint8_t temp = 0xff; -//if (addr >= 0xca000) - addr &= 0x3fff; -// pclog("lcs6821n_read %08x\n", addr); - if (addr < 0x2000) - temp = scsi->bios_rom.rom[addr & 0x1fff]; - else if (addr < 0x3800) - temp = 0xff; - else if (addr >= 0x3a00) - temp = scsi->ext_ram[addr - 0x3a00]; - else - switch (addr & 0x3f80) { - case 0x3800: -// pclog("Read intRAM %02x %02x\n", addr & 0x3f, scsi->int_ram[addr & 0x3f]); - temp = scsi->int_ram[addr & 0x3f]; - break; + lcs6821n_t *scsi = (lcs6821n_t *)p; + uint8_t temp = 0xff; + // if (addr >= 0xca000) + addr &= 0x3fff; + // pclog("lcs6821n_read %08x\n", addr); + if (addr < 0x2000) + temp = scsi->bios_rom.rom[addr & 0x1fff]; + else if (addr < 0x3800) + temp = 0xff; + else if (addr >= 0x3a00) + temp = scsi->ext_ram[addr - 0x3a00]; + else + switch (addr & 0x3f80) { + case 0x3800: + // pclog("Read intRAM %02x %02x\n", addr & 0x3f, scsi->int_ram[addr & 0x3f]); + temp = scsi->int_ram[addr & 0x3f]; + break; - case 0x3880: -// pclog("Read 53c80 %04x\n", addr); - temp = ncr5380_read(addr, &scsi->ncr); - break; + case 0x3880: + // pclog("Read 53c80 %04x\n", addr); + temp = ncr5380_read(addr, &scsi->ncr); + break; - case 0x3900: -//pclog(" Read 3900 %i %02x\n", scsi->buffer_host_pos, scsi->status_ctrl); - if (scsi->buffer_host_pos >= 128 || !(scsi->status_ctrl & CTRL_DATA_DIR)) - temp = 0xff; - else { - temp = scsi->buffer[scsi->buffer_host_pos++]; + case 0x3900: + // pclog(" Read 3900 %i %02x\n", scsi->buffer_host_pos, scsi->status_ctrl); + if (scsi->buffer_host_pos >= 128 || !(scsi->status_ctrl & CTRL_DATA_DIR)) + temp = 0xff; + else { + temp = scsi->buffer[scsi->buffer_host_pos++]; - if (scsi->buffer_host_pos == 128) - scsi->status_ctrl |= STATUS_BUFFER_NOT_READY; - } - break; + if (scsi->buffer_host_pos == 128) + scsi->status_ctrl |= STATUS_BUFFER_NOT_READY; + } + break; - case 0x3980: - switch (addr) { - case 0x3980: /*Status*/ - temp = scsi->status_ctrl;// | 0x80; - if (!scsi->ncr_busy) - temp |= STATUS_53C80_ACCESSIBLE; - break; - case 0x3981: /*Block counter register*/ - temp = scsi->block_count; - break; - case 0x3982: /*Switch register read*/ -// temp = 7 | (7 << 3); - temp = 0xff; - break; - case 0x3983:temp = 0xff; - break; - } - break; - } + case 0x3980: + switch (addr) { + case 0x3980: /*Status*/ + temp = scsi->status_ctrl; // | 0x80; + if (!scsi->ncr_busy) + temp |= STATUS_53C80_ACCESSIBLE; + break; + case 0x3981: /*Block counter register*/ + temp = scsi->block_count; + break; + case 0x3982: /*Switch register read*/ + // temp = 7 | (7 << 3); + temp = 0xff; + break; + case 0x3983: + temp = 0xff; + break; + } + break; + } -// if (addr >= 0x3880) pclog("lcs6821n_read: addr=%05x val=%02x %04x:%04x\n", addr, temp, CS,cpu_state.pc); + // if (addr >= 0x3880) pclog("lcs6821n_read: addr=%05x val=%02x %04x:%04x\n", addr, temp, CS,cpu_state.pc); - return temp; + return temp; } static void lcs6821n_write(uint32_t addr, uint8_t val, void *p) { - lcs6821n_t *scsi = (lcs6821n_t *)p; + lcs6821n_t *scsi = (lcs6821n_t *)p; - addr &= 0x3fff; + addr &= 0x3fff; -// /*if (addr >= 0x3880) */pclog("lcs6821n_write: addr=%05x val=%02x %04x:%04x %i %02x\n", addr, val, CS,cpu_state.pc, scsi->buffer_host_pos, scsi->status_ctrl); + // /*if (addr >= 0x3880) */pclog("lcs6821n_write: addr=%05x val=%02x %04x:%04x %i %02x\n", addr, val, + // CS,cpu_state.pc, scsi->buffer_host_pos, scsi->status_ctrl); - if (addr >= 0x3a00) - scsi->ext_ram[addr - 0x3a00] = val; - else - switch (addr & 0x3f80) { - case 0x3800: -// pclog("Write intram %02x %02x\n", addr & 0x3f, val); - scsi->int_ram[addr & 0x3f] = val; - break; + if (addr >= 0x3a00) + scsi->ext_ram[addr - 0x3a00] = val; + else + switch (addr & 0x3f80) { + case 0x3800: + // pclog("Write intram %02x %02x\n", addr & 0x3f, val); + scsi->int_ram[addr & 0x3f] = val; + break; - case 0x3880: -// pclog("Write 53c80 %04x %02x\n", addr, val); - ncr5380_write(addr, val, &scsi->ncr); - break; + case 0x3880: + // pclog("Write 53c80 %04x %02x\n", addr, val); + ncr5380_write(addr, val, &scsi->ncr); + break; - case 0x3900: - if (!(scsi->status_ctrl & CTRL_DATA_DIR) && scsi->buffer_host_pos < 128) { -// pclog(" Write %i %02x\n", scsi->buffer_host_pos, val); - 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 0x3900: + if (!(scsi->status_ctrl & CTRL_DATA_DIR) && scsi->buffer_host_pos < 128) { + // pclog(" Write %i %02x\n", scsi->buffer_host_pos, val); + 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; - set_dma_enable(scsi, 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; - } + 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; + set_dma_enable(scsi, 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; + } } static uint8_t t130b_read(uint32_t addr, void *p) { - lcs6821n_t *scsi = (lcs6821n_t *)p; - uint8_t temp = 0xff; -//if (addr >= 0xca000) - addr &= 0x3fff; + lcs6821n_t *scsi = (lcs6821n_t *)p; + uint8_t temp = 0xff; + // if (addr >= 0xca000) + addr &= 0x3fff; - if (addr < 0x1800) - temp = scsi->bios_rom.rom[addr & 0x1fff]; - else if (addr < 0x1880) - temp = scsi->ext_ram[addr & 0x7f]; -// else -// pclog("Bad T130B read %04x\n", addr); + if (addr < 0x1800) + temp = scsi->bios_rom.rom[addr & 0x1fff]; + else if (addr < 0x1880) + temp = scsi->ext_ram[addr & 0x7f]; + // else + // pclog("Bad T130B read %04x\n", addr); -// if (addr >= 0x3880) pclog("lcs6821n_read: addr=%05x val=%02x %04x:%04x\n", addr, temp, CS,cpu_state.pc); + // if (addr >= 0x3880) pclog("lcs6821n_read: addr=%05x val=%02x %04x:%04x\n", addr, temp, CS,cpu_state.pc); - return temp; + return temp; } static void t130b_write(uint32_t addr, uint8_t val, void *p) { - lcs6821n_t *scsi = (lcs6821n_t *)p; + lcs6821n_t *scsi = (lcs6821n_t *)p; - addr &= 0x3fff; + addr &= 0x3fff; -// if (addr >= 0x3880) pclog("lcs6821n_write: addr=%05x val=%02x %04x:%04x %i %02x\n", addr, val, CS,cpu_state.pc, scsi->buffer_host_pos, scsi->status_ctrl); + // if (addr >= 0x3880) pclog("lcs6821n_write: addr=%05x val=%02x %04x:%04x %i %02x\n", addr, val, CS,cpu_state.pc, + // scsi->buffer_host_pos, scsi->status_ctrl); - if (addr >= 0x1800 && addr < 0x1880) - scsi->ext_ram[addr & 0x7f] = val; -// else -// pclog("Bad T130B write %04x %02x\n", addr, val); + if (addr >= 0x1800 && addr < 0x1880) + scsi->ext_ram[addr & 0x7f] = val; + // else + // pclog("Bad T130B write %04x %02x\n", addr, val); } static uint8_t t130b_in(uint16_t port, void *p) { - lcs6821n_t *scsi = (lcs6821n_t *)p; - uint8_t temp = 0xff; + lcs6821n_t *scsi = (lcs6821n_t *)p; + uint8_t temp = 0xff; - switch (port & 0xf) { - case 0x0: - case 0x1: - case 0x2: - case 0x3:temp = lcs6821n_read((port & 7) | 0x3980, scsi); - break; + switch (port & 0xf) { + case 0x0: + case 0x1: + case 0x2: + case 0x3: + temp = lcs6821n_read((port & 7) | 0x3980, scsi); + break; - case 0x4: - case 0x5:temp = lcs6821n_read(0x3900, scsi); - break; + case 0x4: + case 0x5: + temp = lcs6821n_read(0x3900, scsi); + break; - case 0x8: - case 0x9: - case 0xa: - case 0xb: - case 0xc: - case 0xd: - case 0xe: - case 0xf:temp = ncr5380_read(port, &scsi->ncr); - break; - } + case 0x8: + case 0x9: + case 0xa: + case 0xb: + case 0xc: + case 0xd: + case 0xe: + case 0xf: + temp = ncr5380_read(port, &scsi->ncr); + break; + } - if (CS != 0xdc00) { - //pclog("t130b_in: port=%04x val=%02x %04x:%04x\n", port, temp, CS,cpu_state.pc); - //output = 3; - //fatal("Here\n"); - } - return temp; + if (CS != 0xdc00) { + // pclog("t130b_in: port=%04x val=%02x %04x:%04x\n", port, temp, CS,cpu_state.pc); + // output = 3; + // fatal("Here\n"); + } + return temp; } static void t130b_out(uint16_t port, uint8_t val, void *p) { - lcs6821n_t *scsi = (lcs6821n_t *)p; + lcs6821n_t *scsi = (lcs6821n_t *)p; - //if (CS != 0xdc00) pclog("t130b_out: port=%04x val=%02x %04x:%04x\n", port, val, CS,cpu_state.pc); + // if (CS != 0xdc00) pclog("t130b_out: port=%04x val=%02x %04x:%04x\n", port, val, CS,cpu_state.pc); - switch (port & 0xf) { - case 0x0: - case 0x1: - case 0x2: - case 0x3:lcs6821n_write((port & 7) | 0x3980, val, scsi); - break; + switch (port & 0xf) { + case 0x0: + case 0x1: + case 0x2: + case 0x3: + lcs6821n_write((port & 7) | 0x3980, val, scsi); + break; - case 0x4: - case 0x5:lcs6821n_write(0x3900, val, scsi); - break; + case 0x4: + case 0x5: + lcs6821n_write(0x3900, val, scsi); + break; - case 0x8: - case 0x9: - case 0xa: - case 0xb: - case 0xc: - case 0xd: - case 0xe: - case 0xf:ncr5380_write(port, val, &scsi->ncr); - break; - } + case 0x8: + case 0x9: + case 0xa: + case 0xb: + case 0xc: + case 0xd: + case 0xe: + case 0xf: + ncr5380_write(port, val, &scsi->ncr); + break; + } } static void ncr53c400_dma_callback(void *p) { - lcs6821n_t *scsi = (lcs6821n_t *)p; - ncr5380_t *ncr = &scsi->ncr; - int c; - int bytes_transferred = 0; + lcs6821n_t *scsi = (lcs6821n_t *)p; + ncr5380_t *ncr = &scsi->ncr; + int c; + int bytes_transferred = 0; -//pclog("dma_Callback poll\n"); - timer_advance_u64(&scsi->dma_timer, TIMER_USEC * POLL_TIME_US); + // pclog("dma_Callback poll\n"); + timer_advance_u64(&scsi->dma_timer, TIMER_USEC * POLL_TIME_US); - switch (scsi->ncr.dma_mode) { - case DMA_SEND: - if (scsi->status_ctrl & CTRL_DATA_DIR) { - pclog("DMA_SEND with DMA direction set wrong\n"); - break; - } + switch (scsi->ncr.dma_mode) { + case DMA_SEND: + if (scsi->status_ctrl & CTRL_DATA_DIR) { + pclog("DMA_SEND with DMA direction set wrong\n"); + break; + } -// if (!device_data[ncr->target_id]) -// fatal("DMA with no device\n"); + // if (!device_data[ncr->target_id]) + // fatal("DMA with no device\n"); - if (!(scsi->status_ctrl & STATUS_BUFFER_NOT_READY)) { -// pclog(" !(scsi->status_ctrl & STATUS_BUFFER_NOT_READY)\n"); - break; - } + if (!(scsi->status_ctrl & STATUS_BUFFER_NOT_READY)) { + // pclog(" !(scsi->status_ctrl & STATUS_BUFFER_NOT_READY)\n"); + break; + } - if (!scsi->block_count_loaded) { -// pclog("!scsi->block_count_loaded\n"); - break; - } + if (!scsi->block_count_loaded) { + // pclog("!scsi->block_count_loaded\n"); + break; + } - while (bytes_transferred < MAX_BYTES_TRANSFERRED_PER_POLL) { - int bus; - uint8_t data; + 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); + for (c = 0; c < 10; c++) { + uint8_t status = scsi_bus_read(&ncr->bus); - if (status & BUS_REQ) - break; - } - if (c == 10) { -// pclog(" No req\n"); - break; - } + if (status & BUS_REQ) + break; + } + if (c == 10) { + // pclog(" No req\n"); + break; + } - /*Data ready*/ - data = scsi->buffer[scsi->buffer_pos]; - bus = get_bus_host(ncr) & ~BUS_DATAMASK; - bus |= BUS_SETDATA(data); + /*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); -// pclog(" Sent data %02x %i\n", data, scsi->buffer_pos); + scsi_bus_update(&ncr->bus, bus | BUS_ACK); + scsi_bus_update(&ncr->bus, bus & ~BUS_ACK); + // pclog(" Sent data %02x %i\n", data, scsi->buffer_pos); - scsi->buffer_pos++; - bytes_transferred++; + scsi->buffer_pos++; + 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; -// pclog("Sent buffer %i\n", scsi->block_count); - if (!scsi->block_count) { - scsi->block_count_loaded = 0; - set_dma_enable(scsi, 0); -// scsi->buffer_host_pos = 128; -// scsi->status_ctrl |= STATUS_BUFFER_NOT_READY; + 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; + // pclog("Sent buffer %i\n", scsi->block_count); + if (!scsi->block_count) { + scsi->block_count_loaded = 0; + set_dma_enable(scsi, 0); + // scsi->buffer_host_pos = 128; + // scsi->status_ctrl |= STATUS_BUFFER_NOT_READY; - 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; + 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)) { - pclog("DMA_INITIATOR_RECEIVE with DMA direction set wrong\n"); - break; - } + case DMA_INITIATOR_RECEIVE: + if (!(scsi->status_ctrl & CTRL_DATA_DIR)) { + pclog("DMA_INITIATOR_RECEIVE with DMA direction set wrong\n"); + break; + } - if (!(scsi->status_ctrl & STATUS_BUFFER_NOT_READY)) - break; + if (!(scsi->status_ctrl & STATUS_BUFFER_NOT_READY)) + break; - if (!scsi->block_count_loaded) - break; + if (!scsi->block_count_loaded) + break; - while (bytes_transferred < MAX_BYTES_TRANSFERRED_PER_POLL) { - int bus; - uint8_t temp; + 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); + for (c = 0; c < 10; c++) { + uint8_t status = scsi_bus_read(&ncr->bus); - if (status & BUS_REQ) - break; - } - if (c == 10) - break; + if (status & BUS_REQ) + break; + } + if (c == 10) + break; - /*Data ready*/ - bus = scsi_bus_read(&ncr->bus); - temp = BUS_GETDATA(bus); -// pclog(" Got data %02x %i\n", temp, scsi->buffer_pos); + /*Data ready*/ + bus = scsi_bus_read(&ncr->bus); + temp = BUS_GETDATA(bus); + // pclog(" Got data %02x %i\n", temp, scsi->buffer_pos); - bus = get_bus_host(ncr); + bus = get_bus_host(ncr); - scsi_bus_update(&ncr->bus, bus | BUS_ACK); - scsi_bus_update(&ncr->bus, bus & ~BUS_ACK); + scsi_bus_update(&ncr->bus, bus | BUS_ACK); + scsi_bus_update(&ncr->bus, bus & ~BUS_ACK); - scsi->buffer[scsi->buffer_pos++] = temp; - bytes_transferred++; + scsi->buffer[scsi->buffer_pos++] = temp; + 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; -// pclog("Got buffer %i\n", scsi->block_count); - if (!scsi->block_count) { - scsi->block_count_loaded = 0; - set_dma_enable(scsi, 0); + 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; + // pclog("Got buffer %i\n", scsi->block_count); + if (!scsi->block_count) { + scsi->block_count_loaded = 0; + set_dma_enable(scsi, 0); -// output=3; - ncr->isr |= STATUS_END_OF_DMA; - if (ncr->mode & MODE_ENA_EOP_INT) - ncr->isr |= STATUS_INT; - } - break; - } - } - break; + // output=3; + ncr->isr |= STATUS_END_OF_DMA; + if (ncr->mode & MODE_ENA_EOP_INT) + ncr->isr |= STATUS_INT; + } + break; + } + } + break; - default:pclog("DMA callback bad mode %i\n", scsi->ncr.dma_mode); - break; - } + default: + pclog("DMA callback bad mode %i\n", scsi->ncr.dma_mode); + break; + } - { - int bus = scsi_bus_read(&ncr->bus); + { + int bus = scsi_bus_read(&ncr->bus); - if (!(bus & BUS_BSY) && (ncr->mode & MODE_MONITOR_BUSY)) { - ncr->mode &= ~MODE_DMA; - ncr->dma_mode = DMA_IDLE; - ncr->dma_changed(ncr, ncr->dma_mode, ncr->mode & MODE_DMA); - } - } + if (!(bus & BUS_BSY) && (ncr->mode & MODE_MONITOR_BUSY)) { + ncr->mode &= ~MODE_DMA; + ncr->dma_mode = DMA_IDLE; + ncr->dma_changed(ncr, ncr->dma_mode, ncr->mode & MODE_DMA); + } + } } static void *scsi_53c400_init(char *bios_fn) { - lcs6821n_t *scsi = malloc(sizeof(lcs6821n_t)); - memset(scsi, 0, sizeof(lcs6821n_t)); + lcs6821n_t *scsi = malloc(sizeof(lcs6821n_t)); + memset(scsi, 0, sizeof(lcs6821n_t)); - rom_init(&scsi->bios_rom, bios_fn, 0xdc000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); - mem_mapping_disable(&scsi->bios_rom.mapping); + rom_init(&scsi->bios_rom, bios_fn, 0xdc000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + mem_mapping_disable(&scsi->bios_rom.mapping); - mem_mapping_add(&scsi->mapping, 0xdc000, 0x4000, - lcs6821n_read, NULL, NULL, - lcs6821n_write, NULL, NULL, - scsi->bios_rom.rom, 0, scsi); + mem_mapping_add(&scsi->mapping, 0xdc000, 0x4000, lcs6821n_read, NULL, NULL, lcs6821n_write, NULL, NULL, + scsi->bios_rom.rom, 0, scsi); - ncr5380_reset(&scsi->ncr); + ncr5380_reset(&scsi->ncr); - scsi->ncr.dma_changed = ncr53c400_dma_changed; - scsi->ncr.p = scsi; + scsi->ncr.dma_changed = ncr53c400_dma_changed; + scsi->ncr.p = scsi; - scsi->status_ctrl = STATUS_BUFFER_NOT_READY; - scsi->buffer_host_pos = 128; + scsi->status_ctrl = STATUS_BUFFER_NOT_READY; + scsi->buffer_host_pos = 128; - scsi_bus_init(&scsi->ncr.bus); + scsi_bus_init(&scsi->ncr.bus); - timer_add(&scsi->dma_timer, ncr53c400_dma_callback, scsi, 0); + timer_add(&scsi->dma_timer, ncr53c400_dma_callback, scsi, 0); - return scsi; + return scsi; } -static void *scsi_lcs6821n_init() { - return scsi_53c400_init("Longshine LCS-6821N - BIOS version 1.04.bin"); -} -static void *scsi_rt1000b_init() { - return scsi_53c400_init("Rancho_RT1000_RTBios_version_8.10R.bin"); -} +static void *scsi_lcs6821n_init() { return scsi_53c400_init("Longshine LCS-6821N - BIOS version 1.04.bin"); } +static void *scsi_rt1000b_init() { return scsi_53c400_init("Rancho_RT1000_RTBios_version_8.10R.bin"); } static void *scsi_t130b_init(char *bios_fn) { - lcs6821n_t *scsi = malloc(sizeof(lcs6821n_t)); - memset(scsi, 0, sizeof(lcs6821n_t)); + lcs6821n_t *scsi = malloc(sizeof(lcs6821n_t)); + memset(scsi, 0, sizeof(lcs6821n_t)); - rom_init(&scsi->bios_rom, "trantor_t130b_bios_v2.14.bin", 0xdc000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&scsi->bios_rom, "trantor_t130b_bios_v2.14.bin", 0xdc000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); - mem_mapping_add(&scsi->mapping, 0xdc000, 0x4000, - t130b_read, NULL, NULL, - t130b_write, NULL, NULL, - scsi->bios_rom.rom, 0, scsi); - io_sethandler(0x0350, 0x0010, - t130b_in, NULL, NULL, - t130b_out, NULL, NULL, - scsi); + mem_mapping_add(&scsi->mapping, 0xdc000, 0x4000, t130b_read, NULL, NULL, t130b_write, NULL, NULL, scsi->bios_rom.rom, 0, + scsi); + io_sethandler(0x0350, 0x0010, t130b_in, NULL, NULL, t130b_out, NULL, NULL, scsi); - ncr5380_reset(&scsi->ncr); + ncr5380_reset(&scsi->ncr); - scsi->ncr.dma_changed = ncr53c400_dma_changed; - scsi->ncr.p = scsi; + scsi->ncr.dma_changed = ncr53c400_dma_changed; + scsi->ncr.p = scsi; - scsi->status_ctrl = STATUS_BUFFER_NOT_READY; - scsi->buffer_host_pos = 128; + scsi->status_ctrl = STATUS_BUFFER_NOT_READY; + scsi->buffer_host_pos = 128; - scsi_bus_init(&scsi->ncr.bus); + scsi_bus_init(&scsi->ncr.bus); - timer_add(&scsi->dma_timer, ncr53c400_dma_callback, scsi, 0); + timer_add(&scsi->dma_timer, ncr53c400_dma_callback, scsi, 0); - return scsi; + return scsi; } static void scsi_53c400_close(void *p) { - lcs6821n_t *scsi = (lcs6821n_t *)p; + lcs6821n_t *scsi = (lcs6821n_t *)p; - scsi_bus_close(&scsi->ncr.bus); + scsi_bus_close(&scsi->ncr.bus); - free(scsi); + free(scsi); } -static int scsi_lcs6821n_available() { - return rom_present("Longshine LCS-6821N - BIOS version 1.04.bin"); -} +static int scsi_lcs6821n_available() { return rom_present("Longshine LCS-6821N - BIOS version 1.04.bin"); } -static int scsi_rt1000b_available() { - return rom_present("Rancho_RT1000_RTBios_version_8.10R.bin"); -} +static int scsi_rt1000b_available() { return rom_present("Rancho_RT1000_RTBios_version_8.10R.bin"); } -static int scsi_t130b_available() { - return rom_present("trantor_t130b_bios_v2.14.bin"); -} +static int scsi_t130b_available() { return rom_present("trantor_t130b_bios_v2.14.bin"); } -device_t scsi_lcs6821n_device = - { - "Longshine LCS-6821N (SCSI)", - 0, - scsi_lcs6821n_init, - scsi_53c400_close, - scsi_lcs6821n_available, - NULL, - NULL, - NULL, - NULL - }; +device_t scsi_lcs6821n_device = { + "Longshine LCS-6821N (SCSI)", 0, scsi_lcs6821n_init, scsi_53c400_close, scsi_lcs6821n_available, NULL, NULL, NULL, NULL}; -device_t scsi_rt1000b_device = - { - "Ranco RT1000B (SCSI)", - 0, - scsi_rt1000b_init, - scsi_53c400_close, - scsi_rt1000b_available, - NULL, - NULL, - NULL, - NULL - }; +device_t scsi_rt1000b_device = { + "Ranco RT1000B (SCSI)", 0, scsi_rt1000b_init, scsi_53c400_close, scsi_rt1000b_available, NULL, NULL, NULL, NULL}; -device_t scsi_t130b_device = - { - "Trantor T130B (SCSI)", - 0, - scsi_t130b_init, - scsi_53c400_close, - scsi_t130b_available, - NULL, - NULL, - NULL, - NULL - }; +device_t scsi_t130b_device = { + "Trantor T130B (SCSI)", 0, scsi_t130b_init, scsi_53c400_close, scsi_t130b_available, NULL, NULL, NULL, NULL}; diff --git a/src/scsi/scsi_aha1540.c b/src/scsi/scsi_aha1540.c index a4797396..9a9e44ae 100644 --- a/src/scsi/scsi_aha1540.c +++ b/src/scsi/scsi_aha1540.c @@ -1,11 +1,11 @@ /*AH1542C firmware notes : - + d1a - command dispatch 193c - send data 1954 - get data FW data - 164e - + BIOS command table - f4b*/ #include #include "ibm.h" @@ -20,10 +20,7 @@ #include "timer.h" int primed = 0; -typedef enum { - SCSI_AHA1542C, - SCSI_BT545S -} scsi_type_t; +typedef enum { SCSI_AHA1542C, SCSI_BT545S } scsi_type_t; /*Firmware emulation is implemented via three state machines : @@ -31,230 +28,227 @@ typedef enum { - CCB state - CCB/mailbox processing - triggered by commands 0x02/0x82 - SCSI state - SCSI bus handling / data transfer*/ typedef enum { - CMD_STATE_RESET, - CMD_STATE_IDLE, - CMD_STATE_GET_PARAMS, - CMD_STATE_CMD_IN_PROGRESS, - CMD_STATE_SEND_RESULT + CMD_STATE_RESET, + CMD_STATE_IDLE, + CMD_STATE_GET_PARAMS, + CMD_STATE_CMD_IN_PROGRESS, + CMD_STATE_SEND_RESULT } cmd_state_t; typedef enum { - CCB_STATE_IDLE, - CCB_STATE_SEND_COMMAND, - CCB_STATE_WAIT_COMMAND, - CCB_STATE_SEND_REQUEST_SENSE, - CCB_STATE_WAIT_REQUEST_SENSE + CCB_STATE_IDLE, + CCB_STATE_SEND_COMMAND, + CCB_STATE_WAIT_COMMAND, + CCB_STATE_SEND_REQUEST_SENSE, + CCB_STATE_WAIT_REQUEST_SENSE } ccb_state_t; typedef enum { - SCSI_STATE_IDLE, - SCSI_STATE_SELECT, - SCSI_STATE_SELECT_FAILED, - SCSI_STATE_SEND_COMMAND, - SCSI_STATE_NEXT_PHASE, - SCSI_STATE_END_PHASE, - SCSI_STATE_READ_DATA, - SCSI_STATE_WRITE_DATA, - SCSI_STATE_READ_STATUS, - SCSI_STATE_READ_MESSAGE + SCSI_STATE_IDLE, + SCSI_STATE_SELECT, + SCSI_STATE_SELECT_FAILED, + SCSI_STATE_SEND_COMMAND, + SCSI_STATE_NEXT_PHASE, + SCSI_STATE_END_PHASE, + SCSI_STATE_READ_DATA, + SCSI_STATE_WRITE_DATA, + SCSI_STATE_READ_STATUS, + SCSI_STATE_READ_MESSAGE } scsi_state_t; -typedef enum { - MB_FORMAT_4, - MB_FORMAT_8 -} mb_format_t; +typedef enum { MB_FORMAT_4, MB_FORMAT_8 } mb_format_t; typedef struct aha154x_t { - rom_t bios_rom; - mem_mapping_t mapping; - uint32_t bios_addr; + rom_t bios_rom; + mem_mapping_t mapping; + uint32_t bios_addr; - uint8_t shadow_ram[0x4000]; - uint8_t shadow; + uint8_t shadow_ram[0x4000]; + uint8_t shadow; - uint32_t bios_bank; + uint32_t bios_bank; - uint8_t eeprom[256]; - char fn[256]; + uint8_t eeprom[256]; + char fn[256]; - scsi_type_t type; + scsi_type_t type; - scsi_bus_t bus; + scsi_bus_t bus; - uint8_t isr; - uint8_t isr_pending; - uint8_t status; + uint8_t isr; + uint8_t isr_pending; + uint8_t status; - int mbo_irq_enable; + int mbo_irq_enable; - uint8_t cmd_data; - uint8_t data_in; + uint8_t cmd_data; + uint8_t data_in; - uint8_t command; - int command_len; - int cur_param; - uint8_t params[64]; + uint8_t command; + int command_len; + int cur_param; + uint8_t params[64]; - int result_pos, result_len; - uint8_t result[256]; + int result_pos, result_len; + uint8_t result[256]; - uint8_t dma_buffer[64]; + uint8_t dma_buffer[64]; - uint8_t bon, boff; - uint8_t atbs; + uint8_t bon, boff; + uint8_t atbs; - int mbc; - uint32_t mba; - uint32_t mba_i; - int mbo_req; - mb_format_t mb_format; + int mbc; + uint32_t mba; + uint32_t mba_i; + int mbo_req; + mb_format_t mb_format; - int bios_mbc; - uint32_t bios_mba; - int bios_mbo_req; - int bios_mbo_inited; + int bios_mbc; + uint32_t bios_mba; + int bios_mbo_req; + int bios_mbo_inited; - cmd_state_t cmd_state; - ccb_state_t ccb_state; - scsi_state_t scsi_state; + cmd_state_t cmd_state; + ccb_state_t ccb_state; + scsi_state_t scsi_state; - int bios_cmd_state; + int bios_cmd_state; - pc_timer_t timer; + pc_timer_t timer; - int current_mbo; - int current_mbo_is_bios; - int current_mbi; + int current_mbo; + int current_mbo_is_bios; + int current_mbi; - uint8_t mblt, mbu; + uint8_t mblt, mbu; - uint8_t int_buffer[512]; + uint8_t int_buffer[512]; - uint8_t e_d; - uint16_t to; + uint8_t e_d; + uint16_t to; - uint8_t dipsw; - int irq, dma, host_id; + uint8_t dipsw; + int irq, dma, host_id; - struct { - uint32_t addr; + struct { + uint32_t addr; - uint8_t opcode; - int target_id, transfer_dir, lun; - int scsi_cmd_len; - int req_sense_len; - uint32_t data_len; - uint32_t data_pointer; - uint32_t link_pointer; - uint8_t link_id; + uint8_t opcode; + int target_id, transfer_dir, lun; + int scsi_cmd_len; + int req_sense_len; + uint32_t data_len; + uint32_t data_pointer; + uint32_t link_pointer; + uint8_t link_id; - uint8_t cdb[256]; + uint8_t cdb[256]; - uint8_t status; + uint8_t status; - int from_mailbox; + int from_mailbox; - uint32_t data_seg_list_pointer; - uint32_t data_seg_list_len; - uint32_t data_seg_list_idx; + uint32_t data_seg_list_pointer; + uint32_t data_seg_list_len; + uint32_t data_seg_list_idx; - int residual; + int residual; - int bytes_transferred; - uint32_t total_data_len; - } ccb; + int bytes_transferred; + uint32_t total_data_len; + } ccb; - struct { - int idx, len; - uint8_t data[256]; + struct { + int idx, len; + uint8_t data[256]; - int data_idx, data_len; - uint32_t data_pointer; + int data_idx, data_len; + uint32_t data_pointer; - uint8_t last_status; + uint8_t last_status; - uint32_t data_seg_list_pointer; - uint32_t data_seg_list_len; - uint32_t data_seg_list_idx; + uint32_t data_seg_list_pointer; + uint32_t data_seg_list_len; + uint32_t data_seg_list_idx; - int scatter_gather; - int bytes_transferred; - } cdb; + int scatter_gather; + int bytes_transferred; + } cdb; - int reg3_idx; + int reg3_idx; } aha154x_t; #define STATUS_INVDCMD 0x01 -#define STATUS_DF 0x04 -#define STATUS_CDF 0x08 -#define STATUS_IDLE 0x10 -#define STATUS_INIT 0x20 -#define STATUS_STST 0x80 +#define STATUS_DF 0x04 +#define STATUS_CDF 0x08 +#define STATUS_IDLE 0x10 +#define STATUS_INIT 0x20 +#define STATUS_STST 0x80 -#define CTRL_BRST 0x10 -#define CTRL_IRST 0x20 -#define CTRL_SRST 0x40 +#define CTRL_BRST 0x10 +#define CTRL_IRST 0x20 +#define CTRL_SRST 0x40 #define CTRL_RESET 0x80 -#define ISR_MBIF 0x01 -#define ISR_MBOA 0x02 -#define ISR_HACC 0x04 +#define ISR_MBIF 0x01 +#define ISR_MBOA 0x02 +#define ISR_HACC 0x04 #define ISR_ANYINTR 0x80 -#define COMMAND_NOP 0x00 -#define COMMAND_MAILBOX_INITIALIZATION 0x01 -#define COMMAND_START_SCSI_COMMAND 0x02 -#define COMMAND_START_BIOS_COMMAND 0x03 -#define COMMAND_ADAPTER_INQUIRY 0x04 -#define COMMAND_MAILBOX_OUT_IRQ_ENA 0x05 -#define COMMAND_SET_SELECTION_TIMEOUT 0x06 -#define COMMAND_SET_BUS_ON_TIME 0x07 -#define COMMAND_SET_BUS_OFF_TIME 0x08 -#define COMMAND_SET_AT_BUS_SPEED 0x09 +#define COMMAND_NOP 0x00 +#define COMMAND_MAILBOX_INITIALIZATION 0x01 +#define COMMAND_START_SCSI_COMMAND 0x02 +#define COMMAND_START_BIOS_COMMAND 0x03 +#define COMMAND_ADAPTER_INQUIRY 0x04 +#define COMMAND_MAILBOX_OUT_IRQ_ENA 0x05 +#define COMMAND_SET_SELECTION_TIMEOUT 0x06 +#define COMMAND_SET_BUS_ON_TIME 0x07 +#define COMMAND_SET_BUS_OFF_TIME 0x08 +#define COMMAND_SET_AT_BUS_SPEED 0x09 #define COMMAND_INQUIRE_INSTALLED_DEVICES 0x0a -#define COMMAND_RETURN_CONFIG_DATA 0x0b -#define COMMAND_RETURN_SETUP_DATA 0x0d -#define COMMAND_WRITE_CHANNEL_2_BUF 0x1a -#define COMMAND_READ_CHANNEL_2_BUF 0x1b -#define COMMAND_ECHO 0x1f +#define COMMAND_RETURN_CONFIG_DATA 0x0b +#define COMMAND_RETURN_SETUP_DATA 0x0d +#define COMMAND_WRITE_CHANNEL_2_BUF 0x1a +#define COMMAND_READ_CHANNEL_2_BUF 0x1b +#define COMMAND_ECHO 0x1f -#define COMMAND_ADAPTEC_PROGRAM_EEPROM 0x22 -#define COMMAND_ADAPTEC_RETURN_EEPROM_DATA 0x23 -#define COMMAND_ADAPTEC_SET_SHADOW_PARAMS 0x24 -#define COMMAND_ADAPTEC_BIOS_MAILBOX_INIT 0x25 -#define COMMAND_ADAPTEC_SET_BIOS_BANK_1 0x26 -#define COMMAND_ADAPTEC_SET_BIOS_BANK_2 0x27 -#define COMMAND_ADAPTEC_GET_EXT_BIOS_INFO 0x28 -#define COMMAND_ENABLE_MAILBOX_INTERFACE 0x29 +#define COMMAND_ADAPTEC_PROGRAM_EEPROM 0x22 +#define COMMAND_ADAPTEC_RETURN_EEPROM_DATA 0x23 +#define COMMAND_ADAPTEC_SET_SHADOW_PARAMS 0x24 +#define COMMAND_ADAPTEC_BIOS_MAILBOX_INIT 0x25 +#define COMMAND_ADAPTEC_SET_BIOS_BANK_1 0x26 +#define COMMAND_ADAPTEC_SET_BIOS_BANK_2 0x27 +#define COMMAND_ADAPTEC_GET_EXT_BIOS_INFO 0x28 +#define COMMAND_ENABLE_MAILBOX_INTERFACE 0x29 #define COMMAND_ADAPTEC_START_BIOS_SCSI_CMD 0x82 -#define COMMAND_BUSLOGIC_22 0x22 -#define COMMAND_BUSLOGIC_81 0x81 -#define COMMAND_BUSLOGIC_84 0x84 -#define COMMAND_BUSLOGIC_85 0x85 -#define COMMAND_BUSLOGIC_ADAPTER_MODEL_NR 0x8b +#define COMMAND_BUSLOGIC_22 0x22 +#define COMMAND_BUSLOGIC_81 0x81 +#define COMMAND_BUSLOGIC_84 0x84 +#define COMMAND_BUSLOGIC_85 0x85 +#define COMMAND_BUSLOGIC_ADAPTER_MODEL_NR 0x8b #define COMMAND_BUSLOGIC_INQUIRY_SYNC_PERIOD 0x8c #define COMMAND_BUSLOGIC_EXTENDED_SETUP_INFO 0x8d -#define COMMAND_BUSLOGIC_STRICT_RR 0x8f -#define COMMAND_BUSLOGIC_SET_CCB_FORMAT 0x96 +#define COMMAND_BUSLOGIC_STRICT_RR 0x8f +#define COMMAND_BUSLOGIC_SET_CCB_FORMAT 0x96 -#define COMMAND_FREE_CCB 0 +#define COMMAND_FREE_CCB 0 #define COMMAND_START_CCB 1 #define COMMAND_ABORT_CCB 2 -#define CCB_INITIATOR 0 -#define CCB_INITIATOR_SCATTER_GATHER 2 -#define CCB_INITIATOR_RESIDUAL 3 +#define CCB_INITIATOR 0 +#define CCB_INITIATOR_SCATTER_GATHER 2 +#define CCB_INITIATOR_RESIDUAL 3 #define CCB_INITIATOR_SCATTER_GATHER_RESIDUAL 4 -#define CCB_SENSE_14 0x00 +#define CCB_SENSE_14 0x00 #define CCB_SENSE_NONE 0x01 -#define MBI_CCB_COMPLETE 0x01 -#define MBI_CCB_ABORTED 0x02 +#define MBI_CCB_COMPLETE 0x01 +#define MBI_CCB_ABORTED 0x02 #define MBI_CCB_COMPLETE_WITH_ERROR 0x04 -#define HOST_STATUS_COMMAND_COMPLETE 0x00 +#define HOST_STATUS_COMMAND_COMPLETE 0x00 #define HOST_STATUS_SELECTION_TIME_OUT 0x11 #define POLL_TIME_US 10 @@ -265,2115 +259,2041 @@ static void aha1542c_eeprom_save(aha154x_t *scsi); static void process_cmd(aha154x_t *scsi); static void set_irq(aha154x_t *scsi, uint8_t val) { - picint(1 << scsi->irq); - scsi->isr |= val | ISR_ANYINTR; + picint(1 << scsi->irq); + scsi->isr |= val | ISR_ANYINTR; } -static void clear_irq(aha154x_t *scsi) { - picintc(1 << scsi->irq); -} +static void clear_irq(aha154x_t *scsi) { picintc(1 << scsi->irq); } static void aha154x_out(uint16_t port, uint8_t val, void *p) { - aha154x_t *scsi = (aha154x_t *)p; + aha154x_t *scsi = (aha154x_t *)p; - if (CS != 0xc800) { -// pclog("aha154x_out: port=%04x val=%02x %04x:%04x %i\n", port, val, CS, cpu_state.pc, scsi->cmd_state); - } + if (CS != 0xc800) { + // pclog("aha154x_out: port=%04x val=%02x %04x:%04x %i\n", port, val, CS, cpu_state.pc, + // scsi->cmd_state); + } - switch (port & 3) { - case 0: /*Control register*/ - if (val & CTRL_RESET) { - scsi->isr = 0; - clear_irq(scsi); - scsi->status = STATUS_STST; - pclog("hardware reset\n"); - scsi->cmd_state = CMD_STATE_RESET; - scsi->ccb_state = CCB_STATE_IDLE; - scsi->scsi_state = SCSI_STATE_IDLE; - scsi->mb_format = MB_FORMAT_4; - scsi->current_mbi = 0; - scsi->mbo_irq_enable = 0; - } - if (val & CTRL_SRST) { - scsi->isr = 0; - clear_irq(scsi); - scsi->status = STATUS_INIT; -// pclog("software reset\n"); - scsi->cmd_state = CMD_STATE_IDLE; - scsi->ccb_state = CCB_STATE_IDLE; - scsi->scsi_state = SCSI_STATE_IDLE; - scsi->mb_format = MB_FORMAT_4; - scsi->current_mbi = 0; - scsi->mbo_irq_enable = 0; - } - if (val & CTRL_IRST) { - scsi->isr = 0; - clear_irq(scsi); -// update_irq(scsi); - if (scsi->type == SCSI_AHA1542C) - scsi->status &= ~STATUS_INVDCMD; - } - if (val & CTRL_BRST) { - scsi->ccb_state = CCB_STATE_IDLE; - scsi->scsi_state = SCSI_STATE_IDLE; -// output = 3; - } - break; + switch (port & 3) { + case 0: /*Control register*/ + if (val & CTRL_RESET) { + scsi->isr = 0; + clear_irq(scsi); + scsi->status = STATUS_STST; + pclog("hardware reset\n"); + scsi->cmd_state = CMD_STATE_RESET; + scsi->ccb_state = CCB_STATE_IDLE; + scsi->scsi_state = SCSI_STATE_IDLE; + scsi->mb_format = MB_FORMAT_4; + scsi->current_mbi = 0; + scsi->mbo_irq_enable = 0; + } + if (val & CTRL_SRST) { + scsi->isr = 0; + clear_irq(scsi); + scsi->status = STATUS_INIT; + // pclog("software reset\n"); + scsi->cmd_state = CMD_STATE_IDLE; + scsi->ccb_state = CCB_STATE_IDLE; + scsi->scsi_state = SCSI_STATE_IDLE; + scsi->mb_format = MB_FORMAT_4; + scsi->current_mbi = 0; + scsi->mbo_irq_enable = 0; + } + if (val & CTRL_IRST) { + scsi->isr = 0; + clear_irq(scsi); + // update_irq(scsi); + if (scsi->type == SCSI_AHA1542C) + scsi->status &= ~STATUS_INVDCMD; + } + if (val & CTRL_BRST) { + scsi->ccb_state = CCB_STATE_IDLE; + scsi->scsi_state = SCSI_STATE_IDLE; + // output = 3; + } + break; - case 1: /*Command/data register*/ - if (scsi->status & STATUS_CDF) - break; - if (scsi->type == SCSI_BT545S) - scsi->status &= ~STATUS_INVDCMD; -// fatal("Write command reg while full\n"); - scsi->status |= STATUS_CDF; - scsi->cmd_data = val; -// pclog("Write command %02x %04x(%08x):%08x\n", val, CS,cs,cpu_state.pc); - process_cmd(scsi); - break; + case 1: /*Command/data register*/ + if (scsi->status & STATUS_CDF) + break; + if (scsi->type == SCSI_BT545S) + scsi->status &= ~STATUS_INVDCMD; + // fatal("Write command reg while full\n"); + scsi->status |= STATUS_CDF; + scsi->cmd_data = val; + // pclog("Write command %02x %04x(%08x):%08x\n", val, CS,cs,cpu_state.pc); + process_cmd(scsi); + break; - case 2: - if (scsi->type == SCSI_BT545S) - scsi->isr = val; - break; - } + case 2: + if (scsi->type == SCSI_BT545S) + scsi->isr = val; + break; + } } static uint8_t aha154x_in(uint16_t port, void *p) { - aha154x_t *scsi = (aha154x_t *)p; - uint8_t temp = 0xff; + aha154x_t *scsi = (aha154x_t *)p; + uint8_t temp = 0xff; -// if (primed) -// output = 3; - switch (port & 3) { - case 0: /*Status register*/ - temp = scsi->status; - if (scsi->cmd_state == CMD_STATE_IDLE && scsi->ccb_state == CCB_STATE_IDLE && scsi->scsi_state == SCSI_STATE_IDLE) - temp |= STATUS_IDLE; - break; + // if (primed) + // output = 3; + switch (port & 3) { + case 0: /*Status register*/ + temp = scsi->status; + if (scsi->cmd_state == CMD_STATE_IDLE && scsi->ccb_state == CCB_STATE_IDLE && scsi->scsi_state == SCSI_STATE_IDLE) + temp |= STATUS_IDLE; + break; - case 1: /*Data in register*/ -/* if (!(scsi->status & STATUS_DF)) - fatal("Read data in while empty\n");*/ - scsi->status &= ~STATUS_DF; - temp = scsi->data_in; - break; + case 1: /*Data in register*/ + /* if (!(scsi->status & STATUS_DF)) + fatal("Read data in while empty\n");*/ + scsi->status &= ~STATUS_DF; + temp = scsi->data_in; + break; - case 2: /*Interrupt status register*/ - if (scsi->type == SCSI_BT545S) - temp = scsi->isr; - else - temp = scsi->isr & ~0x70; - break; + case 2: /*Interrupt status register*/ + if (scsi->type == SCSI_BT545S) + temp = scsi->isr; + else + temp = scsi->isr & ~0x70; + break; - case 3: /*???*/ - if (scsi->type == SCSI_BT545S) - temp = 0x29; /*BT-545S BIOS expects this to return not zero or 0xff for six consecutive reads*/ - else { - scsi->reg3_idx++; - switch (scsi->reg3_idx & 3) { - case 0:temp = 'A'; - break; - case 1:temp = 'D'; - break; - case 2:temp = 'A'; - break; - case 3:temp = 'P'; - break; - } - } - break; - } - if (CS != 0xc800) { -// pclog("aha154x_in: port=%04x val=%02x %04x(%08x):%04x %i %i\n", port, temp, CS, cs, cpu_state.pc, ins, scsi->cmd_state); - } + case 3: /*???*/ + if (scsi->type == SCSI_BT545S) + temp = 0x29; /*BT-545S BIOS expects this to return not zero or 0xff for six consecutive reads*/ + else { + scsi->reg3_idx++; + switch (scsi->reg3_idx & 3) { + case 0: + temp = 'A'; + break; + case 1: + temp = 'D'; + break; + case 2: + temp = 'A'; + break; + case 3: + temp = 'P'; + break; + } + } + break; + } + if (CS != 0xc800) { + // pclog("aha154x_in: port=%04x val=%02x %04x(%08x):%04x %i %i\n", port, temp, CS, cs, + // cpu_state.pc, ins, scsi->cmd_state); + } - return temp; + return temp; } static int wait_for_bus(scsi_bus_t *bus, int state, int req_needed) { - int c; + int c; - for (c = 0; c < 20; c++) { - int bus_state = scsi_bus_read(bus); + for (c = 0; c < 20; c++) { + int bus_state = scsi_bus_read(bus); - if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) == state && (bus_state & BUS_BSY)) { - if (!req_needed || (bus_state & BUS_REQ)) - return 1; - } - } + if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) == state && (bus_state & BUS_BSY)) { + if (!req_needed || (bus_state & BUS_REQ)) + return 1; + } + } - return 0; + return 0; } static void process_cdb(aha154x_t *scsi) { - int c; - uint8_t temp; + int c; + uint8_t temp; - scsi->ccb.opcode = mem_readb_phys(scsi->ccb.addr); - switch (scsi->ccb.opcode) { - case CCB_INITIATOR: - case CCB_INITIATOR_RESIDUAL:temp = mem_readb_phys(scsi->ccb.addr + 0x01); -// pclog("Read addr+ctrl %02x %06x\n", temp, scsi->ccb.addr+0x01); - scsi->ccb.transfer_dir = (temp >> 3) & 3; - scsi->ccb.scsi_cmd_len = mem_readb_phys(scsi->ccb.addr + 0x02); - scsi->ccb.req_sense_len = mem_readb_phys(scsi->ccb.addr + 0x03); + scsi->ccb.opcode = mem_readb_phys(scsi->ccb.addr); + switch (scsi->ccb.opcode) { + case CCB_INITIATOR: + case CCB_INITIATOR_RESIDUAL: + temp = mem_readb_phys(scsi->ccb.addr + 0x01); + // pclog("Read addr+ctrl %02x %06x\n", temp, scsi->ccb.addr+0x01); + scsi->ccb.transfer_dir = (temp >> 3) & 3; + scsi->ccb.scsi_cmd_len = mem_readb_phys(scsi->ccb.addr + 0x02); + scsi->ccb.req_sense_len = mem_readb_phys(scsi->ccb.addr + 0x03); - if (scsi->mb_format == MB_FORMAT_4) { - scsi->ccb.lun = temp & 7; - scsi->ccb.target_id = (temp >> 5) & 7; + if (scsi->mb_format == MB_FORMAT_4) { + scsi->ccb.lun = temp & 7; + scsi->ccb.target_id = (temp >> 5) & 7; - scsi->ccb.data_len = mem_readb_phys(scsi->ccb.addr + 0x06) | (mem_readb_phys(scsi->ccb.addr + 0x05) << 8) | (mem_readb_phys(scsi->ccb.addr + 0x04) << 16); - scsi->ccb.data_pointer = mem_readb_phys(scsi->ccb.addr + 0x09) | (mem_readb_phys(scsi->ccb.addr + 0x08) << 8) | (mem_readb_phys(scsi->ccb.addr + 0x07) << 16); - scsi->ccb.link_pointer = mem_readb_phys(scsi->ccb.addr + 0x0c) | (mem_readb_phys(scsi->ccb.addr + 0x0b) << 8) | (mem_readb_phys(scsi->ccb.addr + 0x0a) << 16); - scsi->ccb.link_id = mem_readb_phys(scsi->ccb.addr + 0x0d); - } else { - scsi->ccb.data_len = mem_readl_phys(scsi->ccb.addr + 0x04); - scsi->ccb.data_pointer = mem_readl_phys(scsi->ccb.addr + 0x08); + scsi->ccb.data_len = mem_readb_phys(scsi->ccb.addr + 0x06) | + (mem_readb_phys(scsi->ccb.addr + 0x05) << 8) | + (mem_readb_phys(scsi->ccb.addr + 0x04) << 16); + scsi->ccb.data_pointer = mem_readb_phys(scsi->ccb.addr + 0x09) | + (mem_readb_phys(scsi->ccb.addr + 0x08) << 8) | + (mem_readb_phys(scsi->ccb.addr + 0x07) << 16); + scsi->ccb.link_pointer = mem_readb_phys(scsi->ccb.addr + 0x0c) | + (mem_readb_phys(scsi->ccb.addr + 0x0b) << 8) | + (mem_readb_phys(scsi->ccb.addr + 0x0a) << 16); + scsi->ccb.link_id = mem_readb_phys(scsi->ccb.addr + 0x0d); + } else { + scsi->ccb.data_len = mem_readl_phys(scsi->ccb.addr + 0x04); + scsi->ccb.data_pointer = mem_readl_phys(scsi->ccb.addr + 0x08); - scsi->ccb.target_id = mem_readb_phys(scsi->ccb.addr + 0x10); - scsi->ccb.lun = mem_readb_phys(scsi->ccb.addr + 0x11) & 0x1f; -// pclog("Target ID = %02x addr=%08x len=%08x\n", scsi->ccb.target_id, scsi->ccb.data_pointer, scsi->ccb.data_len); - } - for (c = 0; c < scsi->ccb.scsi_cmd_len; c++) - scsi->ccb.cdb[c] = mem_readb_phys(scsi->ccb.addr + 0x12 + c); -// pclog("CCB_INITIATOR: target=%i lun=%i\n", scsi->ccb.target_id, scsi->ccb.lun); -// pclog(" scsi_len=%i data_len=%06x data_pointer=%06x\n", scsi->ccb.scsi_cmd_len, scsi->ccb.data_len, scsi->ccb.data_pointer); - scsi->ccb_state = CCB_STATE_SEND_COMMAND; - scsi->ccb.status = 0; - scsi->ccb.from_mailbox = 1; - scsi->ccb.residual = (scsi->ccb.opcode == CCB_INITIATOR_RESIDUAL); - scsi->ccb.total_data_len = scsi->ccb.data_len; - break; + scsi->ccb.target_id = mem_readb_phys(scsi->ccb.addr + 0x10); + scsi->ccb.lun = mem_readb_phys(scsi->ccb.addr + 0x11) & 0x1f; + // pclog("Target ID = %02x addr=%08x len=%08x\n", scsi->ccb.target_id, + // scsi->ccb.data_pointer, scsi->ccb.data_len); + } + for (c = 0; c < scsi->ccb.scsi_cmd_len; c++) + scsi->ccb.cdb[c] = mem_readb_phys(scsi->ccb.addr + 0x12 + c); + // pclog("CCB_INITIATOR: target=%i lun=%i\n", scsi->ccb.target_id, scsi->ccb.lun); + // pclog(" scsi_len=%i data_len=%06x data_pointer=%06x\n", scsi->ccb.scsi_cmd_len, + // scsi->ccb.data_len, scsi->ccb.data_pointer); + scsi->ccb_state = CCB_STATE_SEND_COMMAND; + scsi->ccb.status = 0; + scsi->ccb.from_mailbox = 1; + scsi->ccb.residual = (scsi->ccb.opcode == CCB_INITIATOR_RESIDUAL); + scsi->ccb.total_data_len = scsi->ccb.data_len; + break; - case CCB_INITIATOR_SCATTER_GATHER: - case CCB_INITIATOR_SCATTER_GATHER_RESIDUAL: -// pclog("Scatter-gather : %08x %08x %08x %08x %08x %i %02x\n", mem_readl_phys(scsi->ccb.addr),mem_readl_phys(scsi->ccb.addr+4),mem_readl_phys(scsi->ccb.addr+8),mem_readl_phys(scsi->ccb.addr+12),mem_readl_phys(scsi->ccb.addr+16), scsi->mb_format == MB_FORMAT_4, scsi->ccb.opcode); - temp = mem_readb_phys(scsi->ccb.addr + 0x01); -// pclog("Read addr+ctrl %02x %06x\n", temp, scsi->ccb.addr+0x01); - scsi->ccb.transfer_dir = (temp >> 3) & 3; - scsi->ccb.scsi_cmd_len = mem_readb_phys(scsi->ccb.addr + 0x02); - scsi->ccb.req_sense_len = mem_readb_phys(scsi->ccb.addr + 0x03); + case CCB_INITIATOR_SCATTER_GATHER: + case CCB_INITIATOR_SCATTER_GATHER_RESIDUAL: + // pclog("Scatter-gather : %08x %08x %08x %08x %08x %i %02x\n", + // mem_readl_phys(scsi->ccb.addr),mem_readl_phys(scsi->ccb.addr+4),mem_readl_phys(scsi->ccb.addr+8),mem_readl_phys(scsi->ccb.addr+12),mem_readl_phys(scsi->ccb.addr+16), + // scsi->mb_format == MB_FORMAT_4, scsi->ccb.opcode); + temp = mem_readb_phys(scsi->ccb.addr + 0x01); + // pclog("Read addr+ctrl %02x %06x\n", temp, scsi->ccb.addr+0x01); + scsi->ccb.transfer_dir = (temp >> 3) & 3; + scsi->ccb.scsi_cmd_len = mem_readb_phys(scsi->ccb.addr + 0x02); + scsi->ccb.req_sense_len = mem_readb_phys(scsi->ccb.addr + 0x03); - if (scsi->mb_format == MB_FORMAT_4) { - scsi->ccb.lun = temp & 7; - scsi->ccb.target_id = (temp >> 5) & 7; + if (scsi->mb_format == MB_FORMAT_4) { + scsi->ccb.lun = temp & 7; + scsi->ccb.target_id = (temp >> 5) & 7; - scsi->ccb.data_seg_list_len = mem_readb_phys(scsi->ccb.addr + 0x06) | (mem_readb_phys(scsi->ccb.addr + 0x05) << 8) | (mem_readb_phys(scsi->ccb.addr + 0x04) << 16); - scsi->ccb.data_seg_list_pointer = mem_readb_phys(scsi->ccb.addr + 0x09) | (mem_readb_phys(scsi->ccb.addr + 0x08) << 8) | (mem_readb_phys(scsi->ccb.addr + 0x07) << 16); - scsi->ccb.data_seg_list_idx = 0; - if (scsi->ccb.data_seg_list_len < 6) - pclog("Scatter gather table < 6 bytes\n"); + scsi->ccb.data_seg_list_len = mem_readb_phys(scsi->ccb.addr + 0x06) | + (mem_readb_phys(scsi->ccb.addr + 0x05) << 8) | + (mem_readb_phys(scsi->ccb.addr + 0x04) << 16); + scsi->ccb.data_seg_list_pointer = mem_readb_phys(scsi->ccb.addr + 0x09) | + (mem_readb_phys(scsi->ccb.addr + 0x08) << 8) | + (mem_readb_phys(scsi->ccb.addr + 0x07) << 16); + scsi->ccb.data_seg_list_idx = 0; + if (scsi->ccb.data_seg_list_len < 6) + pclog("Scatter gather table < 6 bytes\n"); - scsi->ccb.link_pointer = mem_readb_phys(scsi->ccb.addr + 0x0c) | (mem_readb_phys(scsi->ccb.addr + 0x0b) << 8) | (mem_readb_phys(scsi->ccb.addr + 0x0a) << 16); - scsi->ccb.link_id = mem_readb_phys(scsi->ccb.addr + 0x0d); - } else { - scsi->ccb.data_seg_list_len = mem_readl_phys(scsi->ccb.addr + 0x04); - scsi->ccb.data_seg_list_pointer = mem_readl_phys(scsi->ccb.addr + 0x08); - scsi->ccb.data_seg_list_idx = 0; - if (scsi->ccb.data_seg_list_len < 8) - pclog("Scatter gather table < 8 bytes\n"); + scsi->ccb.link_pointer = mem_readb_phys(scsi->ccb.addr + 0x0c) | + (mem_readb_phys(scsi->ccb.addr + 0x0b) << 8) | + (mem_readb_phys(scsi->ccb.addr + 0x0a) << 16); + scsi->ccb.link_id = mem_readb_phys(scsi->ccb.addr + 0x0d); + } else { + scsi->ccb.data_seg_list_len = mem_readl_phys(scsi->ccb.addr + 0x04); + scsi->ccb.data_seg_list_pointer = mem_readl_phys(scsi->ccb.addr + 0x08); + scsi->ccb.data_seg_list_idx = 0; + if (scsi->ccb.data_seg_list_len < 8) + pclog("Scatter gather table < 8 bytes\n"); - scsi->ccb.target_id = mem_readb_phys(scsi->ccb.addr + 0x10); - scsi->ccb.lun = mem_readb_phys(scsi->ccb.addr + 0x11) & 0x1f; -// pclog("Target ID = %02x\n", scsi->ccb.target_id); - } - for (c = 0; c < scsi->ccb.scsi_cmd_len; c++) - scsi->ccb.cdb[c] = mem_readb_phys(scsi->ccb.addr + 0x12 + c); -// pclog("CCB_INITIATOR_SCATTER_GATHER: target=%i lun=%i\n", scsi->ccb.target_id, scsi->ccb.lun); -// pclog(" scsi_len=%i data_len=%06x data_pointer=%06x\n", scsi->ccb.scsi_cmd_len, scsi->ccb.data_len, scsi->ccb.data_pointer); - scsi->ccb_state = CCB_STATE_SEND_COMMAND; - scsi->ccb.status = 0; - scsi->ccb.from_mailbox = 1; - scsi->ccb.residual = (scsi->ccb.opcode == CCB_INITIATOR_SCATTER_GATHER_RESIDUAL); + scsi->ccb.target_id = mem_readb_phys(scsi->ccb.addr + 0x10); + scsi->ccb.lun = mem_readb_phys(scsi->ccb.addr + 0x11) & 0x1f; + // pclog("Target ID = %02x\n", scsi->ccb.target_id); + } + for (c = 0; c < scsi->ccb.scsi_cmd_len; c++) + scsi->ccb.cdb[c] = mem_readb_phys(scsi->ccb.addr + 0x12 + c); + // pclog("CCB_INITIATOR_SCATTER_GATHER: target=%i lun=%i\n", scsi->ccb.target_id, scsi->ccb.lun); + // pclog(" scsi_len=%i data_len=%06x data_pointer=%06x\n", scsi->ccb.scsi_cmd_len, + // scsi->ccb.data_len, scsi->ccb.data_pointer); + scsi->ccb_state = CCB_STATE_SEND_COMMAND; + scsi->ccb.status = 0; + scsi->ccb.from_mailbox = 1; + scsi->ccb.residual = (scsi->ccb.opcode == CCB_INITIATOR_SCATTER_GATHER_RESIDUAL); - if (scsi->ccb.residual) { - /*Read total data length from scatter list, to use when calculating residual*/ - uint32_t addr = scsi->ccb.data_seg_list_pointer; + if (scsi->ccb.residual) { + /*Read total data length from scatter list, to use when calculating residual*/ + uint32_t addr = scsi->ccb.data_seg_list_pointer; - scsi->ccb.total_data_len = 0; + scsi->ccb.total_data_len = 0; - if (scsi->mb_format == MB_FORMAT_4) { - for (c = 0; c < scsi->ccb.data_seg_list_len; c += 6) { - uint32_t len = mem_readb_phys(addr + c + 2) | - (mem_readb_phys(addr + c + 1) << 8) | - (mem_readb_phys(addr + c) << 16); + if (scsi->mb_format == MB_FORMAT_4) { + for (c = 0; c < scsi->ccb.data_seg_list_len; c += 6) { + uint32_t len = mem_readb_phys(addr + c + 2) | (mem_readb_phys(addr + c + 1) << 8) | + (mem_readb_phys(addr + c) << 16); - scsi->ccb.total_data_len += len; - } - } else { - for (c = 0; c < scsi->ccb.data_seg_list_len; c += 6) { - uint32_t len = mem_readl_phys(addr + c); + scsi->ccb.total_data_len += len; + } + } else { + for (c = 0; c < scsi->ccb.data_seg_list_len; c += 6) { + uint32_t len = mem_readl_phys(addr + c); - scsi->ccb.total_data_len += len; - } - } - } - break; + scsi->ccb.total_data_len += len; + } + } + } + break; - default:fatal("Unknown CCD opcode %02x\n", scsi->ccb.opcode); - } - pclog("Start CCB at %06x\n", scsi->ccb.addr); + default: + fatal("Unknown CCD opcode %02x\n", scsi->ccb.opcode); + } + pclog("Start CCB at %06x\n", scsi->ccb.addr); } static void process_cmd(aha154x_t *scsi) { - uint32_t addr; - int c; - - switch (scsi->cmd_state) { - case CMD_STATE_RESET:scsi->status = STATUS_INIT; - scsi->cmd_state = CMD_STATE_IDLE; - pclog("AHA154x reset complete\n"); - break; - - case CMD_STATE_IDLE: - if (scsi->status & STATUS_CDF) { - int invalid = 0; - - scsi->status &= ~STATUS_CDF; - - scsi->command = scsi->cmd_data; - pclog("New command %02x\n", scsi->command); -// if (scsi->command == 0x22) -// fatal("Here\n"); -// output = 3; - switch (scsi->command) { - case COMMAND_NOP: - case COMMAND_START_SCSI_COMMAND: - case COMMAND_ADAPTER_INQUIRY: - case COMMAND_INQUIRE_INSTALLED_DEVICES: - case COMMAND_RETURN_CONFIG_DATA:scsi->command_len = 0; - break; - - case COMMAND_ADAPTEC_SET_BIOS_BANK_1: - case COMMAND_ADAPTEC_SET_BIOS_BANK_2: - case COMMAND_ADAPTEC_GET_EXT_BIOS_INFO: - case COMMAND_ADAPTEC_START_BIOS_SCSI_CMD: - if (scsi->type == SCSI_AHA1542C) - scsi->command_len = 0; - else - invalid = 1; - break; - - case COMMAND_BUSLOGIC_84: - case COMMAND_BUSLOGIC_85: - if (scsi->type == SCSI_BT545S) - scsi->command_len = 0; - else - invalid = 1; - break; - - case COMMAND_ECHO: - case COMMAND_MAILBOX_OUT_IRQ_ENA: - case COMMAND_SET_BUS_ON_TIME: - case COMMAND_SET_BUS_OFF_TIME: - case COMMAND_SET_AT_BUS_SPEED: - case COMMAND_RETURN_SETUP_DATA:scsi->command_len = 1; - break; - - case COMMAND_ADAPTEC_SET_SHADOW_PARAMS: - if (scsi->type == SCSI_AHA1542C) - scsi->command_len = 1; - else - invalid = 1; - break; - - case 0x22: - if (scsi->type == SCSI_AHA1542C) - scsi->command_len = 35; /*COMMAND_ADAPTEC_PROGRAM_EEPROM*/ - else { -// scsi->command_len = 1; /*COMMAND_BUSLOGIC_22*/ - pclog("Get 22\n"); -// scsi->command_len = 0; - invalid = 1; - primed = 1; - } - break; - - case COMMAND_BUSLOGIC_SET_CCB_FORMAT: - case COMMAND_BUSLOGIC_STRICT_RR: - case COMMAND_BUSLOGIC_EXTENDED_SETUP_INFO: - case COMMAND_BUSLOGIC_ADAPTER_MODEL_NR: - case COMMAND_BUSLOGIC_INQUIRY_SYNC_PERIOD: - if (scsi->type == SCSI_BT545S) - scsi->command_len = 1; - else - invalid = 1; - break; - - case COMMAND_ENABLE_MAILBOX_INTERFACE: - if (scsi->type == SCSI_AHA1542C) - scsi->command_len = 2; - else - invalid = 1; - break; - - case COMMAND_WRITE_CHANNEL_2_BUF: - case COMMAND_READ_CHANNEL_2_BUF:scsi->command_len = 3; - break; - - case COMMAND_SET_SELECTION_TIMEOUT:scsi->command_len = 4; - break; - - case COMMAND_ADAPTEC_RETURN_EEPROM_DATA: - if (scsi->type == SCSI_AHA1542C) - scsi->command_len = 3; - else - invalid = 1; - break; - - case COMMAND_MAILBOX_INITIALIZATION:scsi->command_len = 4; - break; - - case COMMAND_BUSLOGIC_81: - if (scsi->type == SCSI_BT545S) - scsi->command_len = 5; - else - invalid = 1; - break; - - case COMMAND_START_BIOS_COMMAND:scsi->command_len = 10; - scsi->bios_cmd_state = 0; - break; - - case COMMAND_ADAPTEC_BIOS_MAILBOX_INIT: - if (scsi->type == SCSI_AHA1542C) - scsi->command_len = 4; - else - invalid = 1; - break; - -/* case 0x40: case 0x42: case 0x44: case 0xff: - invalid = 1; - break;*/ - - default: - if (scsi->type == SCSI_AHA1542C) { - if ((scsi->command > 0xd && scsi->command < 0x1a) || (scsi->command > 0x2a && scsi->command != 0x82)) - invalid = 1; - else - fatal("Bad AHA154x command %02x\n", scsi->command); - } else { - if (scsi->command > 0x22 && (scsi->command < 0xfa || scsi->command > 0xfc) && - !(scsi->command >= 0x81 && scsi->command <= 0x9d) && - scsi->command != 0xda && scsi->command != 0xdc) - invalid = 1; - else - fatal("Bad BT545S command %02x\n", scsi->command); - } - break; - } - - if (invalid) { - scsi->status |= STATUS_INVDCMD; - set_irq(scsi, ISR_HACC); - scsi->cmd_state = CMD_STATE_IDLE; - } else if (!scsi->command_len) - scsi->cmd_state = CMD_STATE_CMD_IN_PROGRESS; - else { - scsi->cmd_state = CMD_STATE_GET_PARAMS; - scsi->cur_param = 0; - } - } - if (scsi->cmd_state != CMD_STATE_CMD_IN_PROGRESS) { -// pclog("Command not fallthrough\n"); - break; - } -// pclog("Command fallthrough\n"); - /*Fallthrough*/ - - case CMD_STATE_CMD_IN_PROGRESS: - switch (scsi->command) { - case COMMAND_NOP: -// pclog("NOP complete\n"); - set_irq(scsi, ISR_HACC); - scsi->cmd_state = CMD_STATE_IDLE; - break; - - case COMMAND_MAILBOX_INITIALIZATION:scsi->mbc = scsi->params[0]; - scsi->mba = scsi->params[3] | (scsi->params[2] << 8) | (scsi->params[1] << 16); - scsi->mba_i = scsi->mba + scsi->mbc * 4; - scsi->mb_format = MB_FORMAT_4; - scsi->current_mbo = 0; - scsi->current_mbi = 0; - pclog("Mailbox init: MBC=%02x MBC=%06x\n", scsi->mbc, scsi->mba); - scsi->status &= ~STATUS_INIT; - set_irq(scsi, ISR_HACC); - scsi->cmd_state = CMD_STATE_IDLE; - break; - - case COMMAND_START_SCSI_COMMAND:pclog("START_SCSI_COMMAND %i %i\n", scsi->ccb_state, scsi->scsi_state); - scsi->mbo_req++; - scsi->cmd_state = CMD_STATE_IDLE; - /*Don't send IRQ until we actually start processing a mailbox*/ - break; - - case COMMAND_START_BIOS_COMMAND: - if (scsi->ccb_state != CCB_STATE_IDLE) - break; - if (!scsi->bios_cmd_state) - pclog("Start BIOS command %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", - scsi->params[0], scsi->params[1], scsi->params[2], scsi->params[3], scsi->params[4], - scsi->params[5], scsi->params[6], scsi->params[7], scsi->params[8], scsi->params[9]); - if (scsi->params[0] >= 0x16) { - /*Only commands below 0x16 are implemented*/ - scsi->status |= STATUS_INVDCMD; - set_irq(scsi, ISR_HACC); - scsi->cmd_state = CMD_STATE_IDLE; - } else - switch (scsi->params[0]) { - case 0x00: /*Reset Disk System*/ - scsi->data_in = 0; - set_irq(scsi, ISR_HACC); - scsi->status |= STATUS_DF; - scsi->cmd_state = CMD_STATE_IDLE; - break; - - case 0x01: /*Get Status of Last Operation*/ - scsi->data_in = 0; - set_irq(scsi, ISR_HACC); - scsi->status |= STATUS_DF; - scsi->cmd_state = CMD_STATE_IDLE; - break; - - case 0x02: /*Read Sector(s) Into Memory*/ - switch (scsi->bios_cmd_state) { - case 0: { - int sector = scsi->params[5]; - int head = (scsi->params[4] & 0xf) | ((scsi->params[3] & 3) << 4); - int cylinder = (scsi->params[3] >> 2) | ((scsi->params[2] & 0xf) << 6); - - pclog("Cylinder=%i head=%i sector=%i\n", cylinder, head, sector); - addr = sector + (head * 32) + (cylinder * 64 * 32); - } - scsi->ccb.cdb[0] = SCSI_READ_10; - scsi->ccb.cdb[1] = 0; - scsi->ccb.cdb[2] = addr >> 24; - scsi->ccb.cdb[3] = addr >> 16; - scsi->ccb.cdb[4] = addr >> 8; - scsi->ccb.cdb[5] = addr & 0xff; - scsi->ccb.cdb[6] = 0; - scsi->ccb.cdb[7] = 0; - scsi->ccb.cdb[8] = scsi->params[6]; - scsi->ccb.cdb[9] = 0; - scsi->ccb.lun = 0; - scsi->ccb.target_id = scsi->params[1] & 7; - scsi->ccb.scsi_cmd_len = 10; - scsi->ccb.data_pointer = scsi->params[9] | (scsi->params[8] << 8) | (scsi->params[7] << 16);; - scsi->ccb.data_len = 512 * scsi->params[6]; - scsi->ccb.req_sense_len = CCB_SENSE_14; - scsi->ccb_state = CCB_STATE_SEND_COMMAND; - pclog("Read sector %08x %06x\n", addr, scsi->ccb.data_pointer); - scsi->bios_cmd_state++; - break; - case 1: - if (scsi->ccb.status) - fatal("Read sector fail %02x\n", scsi->ccb.status); - scsi->data_in = 0x00; - set_irq(scsi, ISR_HACC); - scsi->status |= STATUS_DF; - scsi->cmd_state = CMD_STATE_IDLE; - break; - } - break; - - case 0x03: /*Write Disk Sector(s)*/ - switch (scsi->bios_cmd_state) { - case 0: { - int sector = scsi->params[5]; - int head = (scsi->params[4] & 0xf) | ((scsi->params[3] & 3) << 4); - int cylinder = (scsi->params[3] >> 2) | ((scsi->params[2] & 0xf) << 6); - - addr = sector + (head * 32) + (cylinder * 64 * 32); - } - scsi->ccb.cdb[0] = SCSI_WRITE_10; - scsi->ccb.cdb[1] = 0; - scsi->ccb.cdb[2] = addr >> 24; - scsi->ccb.cdb[3] = addr >> 16; - scsi->ccb.cdb[4] = addr >> 8; - scsi->ccb.cdb[5] = addr & 0xff; - scsi->ccb.cdb[6] = 0; - scsi->ccb.cdb[7] = 0; - scsi->ccb.cdb[8] = scsi->params[6]; - scsi->ccb.cdb[9] = 0; - scsi->ccb.lun = 0; - scsi->ccb.target_id = scsi->params[1] & 7; - scsi->ccb.scsi_cmd_len = 10; - scsi->ccb.data_pointer = scsi->params[9] | (scsi->params[8] << 8) | (scsi->params[7] << 16);; - scsi->ccb.data_len = 512 * scsi->params[6]; - scsi->ccb.req_sense_len = CCB_SENSE_14; - scsi->ccb_state = CCB_STATE_SEND_COMMAND; - pclog("Write sector %08x %06x\n", addr, scsi->ccb.data_pointer); - scsi->bios_cmd_state++; - break; - case 1: - if (scsi->ccb.status) - fatal("Write sector fail %02x\n", scsi->ccb.status); - scsi->data_in = 0x00; - set_irq(scsi, ISR_HACC); - scsi->status |= STATUS_DF; - scsi->cmd_state = CMD_STATE_IDLE; - break; - } - break; - - case 0x04: /*Verify Disk Sector(s)*/ - switch (scsi->bios_cmd_state) { - case 0: { - int sector = scsi->params[5]; - int head = (scsi->params[4] & 0xf) | ((scsi->params[3] & 3) << 4); - int cylinder = (scsi->params[3] >> 2) | ((scsi->params[2] & 0xf) << 6); - - addr = sector + (head * 32) + (cylinder * 64 * 32); - } - scsi->ccb.cdb[0] = SCSI_VERIFY_10; - scsi->ccb.cdb[1] = 0; - scsi->ccb.cdb[2] = addr >> 24; - scsi->ccb.cdb[3] = addr >> 16; - scsi->ccb.cdb[4] = addr >> 8; - scsi->ccb.cdb[5] = addr & 0xff; - scsi->ccb.cdb[6] = 0; - scsi->ccb.cdb[7] = 0; - scsi->ccb.cdb[8] = scsi->params[6]; - scsi->ccb.cdb[9] = 0; - scsi->ccb.lun = 0; - scsi->ccb.target_id = scsi->params[1] & 7; - scsi->ccb.scsi_cmd_len = 10; - scsi->ccb.data_pointer = scsi->params[9] | (scsi->params[8] << 8) | (scsi->params[7] << 16);; - scsi->ccb.data_len = 512 * scsi->params[6]; - scsi->ccb.req_sense_len = CCB_SENSE_14; - scsi->ccb_state = CCB_STATE_SEND_COMMAND; - pclog("Verify sector %08x %06x\n", addr, scsi->ccb.data_pointer); - scsi->bios_cmd_state++; - break; - case 1: - if (scsi->ccb.status) - fatal("Verify sector fail %02x\n", scsi->ccb.status); - scsi->data_in = 0x00; - set_irq(scsi, ISR_HACC); - scsi->status |= STATUS_DF; - scsi->cmd_state = CMD_STATE_IDLE; - break; - } - break; - - /*AHA1542C firmware just fails all of these*/ - case 0x05: - case 0x06: - case 0x07: - case 0x0a: - case 0x0b: - case 0x12: - case 0x13:scsi->status |= STATUS_INVDCMD; - set_irq(scsi, ISR_HACC); - scsi->cmd_state = CMD_STATE_IDLE; - break; - - case 0x08: /*Get Drive Parameters*/ - switch (scsi->bios_cmd_state) { - case 0:scsi->ccb.cdb[0] = SCSI_READ_CAPACITY_10; - scsi->ccb.cdb[1] = 0; - scsi->ccb.cdb[2] = 0; - scsi->ccb.cdb[3] = 0; - scsi->ccb.cdb[4] = 0; - scsi->ccb.cdb[5] = 0; - scsi->ccb.cdb[6] = 0; - scsi->ccb.cdb[7] = 0; - scsi->ccb.cdb[8] = 0; - scsi->ccb.cdb[9] = 0; - scsi->ccb.lun = 0; - scsi->ccb.target_id = scsi->params[1] & 7; - scsi->ccb.scsi_cmd_len = 10; - scsi->ccb.data_pointer = -1; - scsi->ccb.data_len = 8; - scsi->ccb.req_sense_len = CCB_SENSE_NONE; - scsi->ccb_state = CCB_STATE_SEND_COMMAND; - scsi->bios_cmd_state++; - break; - case 1:addr = scsi->params[9] | (scsi->params[8] << 8) | (scsi->params[7] << 16); - mem_writeb_phys(addr, scsi->int_buffer[0]); - mem_writeb_phys(addr + 1, scsi->int_buffer[1]); - mem_writeb_phys(addr + 2, scsi->int_buffer[2]); - mem_writeb_phys(addr + 3, scsi->int_buffer[3]); - pclog("Got size %06x %02x%02x%02x%02x\n", addr, scsi->int_buffer[3], scsi->int_buffer[2], scsi->int_buffer[1], scsi->int_buffer[0]); - scsi->data_in = 0; - set_irq(scsi, ISR_HACC); - scsi->status |= STATUS_DF; - scsi->cmd_state = CMD_STATE_IDLE; - break; - } - break; - - case 0x09: /*Initialize Drive Parameters*/ - case 0x0c: /*Seek To Cylinder*/ - case 0x0d: /*Reset Hard Disks*/ - case 0x0e: /*Read Sector Buffer*/ - case 0x0f: /*Write Sector Buffer*/ - case 0x10: /*Check If Drive Ready*/ - case 0x11: /*Recalibrate Drive*/ - case 0x14: /*Controller Internal Diagnostic*/ - pclog("Unimplemented AHA1542 BIOS command - 0x%02x\n", scsi->params[0]); - scsi->data_in = 0; - set_irq(scsi, ISR_HACC); - scsi->status |= STATUS_DF; - scsi->cmd_state = CMD_STATE_IDLE; - break; - - case 0x15: /*Get Disk Type*/ - switch (scsi->bios_cmd_state) { - case 0:scsi->ccb.cdb[0] = SCSI_INQUIRY; - scsi->ccb.cdb[1] = 0; - scsi->ccb.cdb[2] = 0; - scsi->ccb.cdb[3] = 0; - scsi->ccb.cdb[4] = 36; - scsi->ccb.cdb[5] = 0; - scsi->ccb.lun = 0; - scsi->ccb.target_id = scsi->params[1] & 7; - scsi->ccb.scsi_cmd_len = 6; - scsi->ccb.data_pointer = -1; - scsi->ccb.data_len = 36; - scsi->ccb.req_sense_len = CCB_SENSE_NONE; - scsi->ccb_state = CCB_STATE_SEND_COMMAND; - scsi->ccb.from_mailbox = 0; - scsi->bios_cmd_state++; - break; - case 1: - if (scsi->int_buffer[0] & 0x1f) { - /*Not a direct-access device*/ - fatal("Not a direct-access device\n"); - } - scsi->ccb.cdb[0] = SCSI_READ_CAPACITY_10; - scsi->ccb.cdb[1] = 0; - scsi->ccb.cdb[2] = 0; - scsi->ccb.cdb[3] = 0; - scsi->ccb.cdb[4] = 0; - scsi->ccb.cdb[5] = 0; - scsi->ccb.cdb[6] = 0; - scsi->ccb.cdb[7] = 0; - scsi->ccb.cdb[8] = 0; - scsi->ccb.cdb[9] = 0; - scsi->ccb.lun = 0; - scsi->ccb.target_id = scsi->params[1] & 7; - scsi->ccb.scsi_cmd_len = 10; - scsi->ccb.data_pointer = -1; - scsi->ccb.data_len = 8; - scsi->ccb.req_sense_len = CCB_SENSE_NONE; - scsi->ccb_state = CCB_STATE_SEND_COMMAND; - scsi->bios_cmd_state++; - break; - case 2:addr = scsi->params[9] | (scsi->params[8] << 8) | (scsi->params[7] << 16); - mem_writeb_phys(addr, scsi->int_buffer[0]); - mem_writeb_phys(addr + 1, scsi->int_buffer[1]); - mem_writeb_phys(addr + 2, scsi->int_buffer[2]); - mem_writeb_phys(addr + 3, scsi->int_buffer[3]); - pclog("Got size %06x %02x%02x%02x%02x\n", addr, scsi->int_buffer[3], scsi->int_buffer[2], scsi->int_buffer[1], scsi->int_buffer[0]); - scsi->data_in = 0; - set_irq(scsi, ISR_HACC); - scsi->status |= STATUS_DF; - scsi->cmd_state = CMD_STATE_IDLE; - break; - - default:fatal("Get Disk Type state %i\n", scsi->bios_cmd_state); - } - //fatal("data_pointer %06x\n", scsi->ccb.data_pointer); - break; - - default:scsi->status |= STATUS_INVDCMD; - set_irq(scsi, ISR_HACC); - scsi->cmd_state = CMD_STATE_IDLE; - break; - } - break; - - case COMMAND_ADAPTER_INQUIRY: - if (scsi->type == SCSI_BT545S) { - scsi->result[0] = 0x41; - scsi->result[1] = 0x41; /*Standard model*/ - scsi->result[2] = 0x33; /*Firmware revision*/ - scsi->result[3] = 0x33; - } else { - scsi->result[0] = 0x44; /*AHA-1542CF*/ - scsi->result[1] = 0x30; - scsi->result[2] = 0x30; /*Firmware revision*/ - scsi->result[3] = 0x31; - } - scsi->cmd_state = CMD_STATE_SEND_RESULT; - scsi->result_pos = 0; - scsi->result_len = 4; - break; - - case COMMAND_MAILBOX_OUT_IRQ_ENA:scsi->mbo_irq_enable = scsi->params[0]; - set_irq(scsi, ISR_HACC); - scsi->cmd_state = CMD_STATE_IDLE; - break; - - case COMMAND_SET_SELECTION_TIMEOUT:scsi->e_d = scsi->params[0]; - scsi->to = (scsi->params[1] << 8) | scsi->params[2]; - set_irq(scsi, ISR_HACC); - scsi->cmd_state = CMD_STATE_IDLE; - break; - - case COMMAND_SET_BUS_ON_TIME:scsi->bon = scsi->params[0]; - set_irq(scsi, ISR_HACC); - scsi->cmd_state = CMD_STATE_IDLE; - break; - - case COMMAND_SET_BUS_OFF_TIME:scsi->boff = scsi->params[0]; - set_irq(scsi, ISR_HACC); - scsi->cmd_state = CMD_STATE_IDLE; - break; - - case COMMAND_SET_AT_BUS_SPEED:scsi->atbs = scsi->params[0]; - set_irq(scsi, ISR_HACC); - scsi->cmd_state = CMD_STATE_IDLE; - break; - - case COMMAND_INQUIRE_INSTALLED_DEVICES: - for (c = 0; c < 8; c++) - scsi->result[c] = scsi->bus.devices[c] ? 1 : 0; - scsi->cmd_state = CMD_STATE_SEND_RESULT; - scsi->result_pos = 0; - scsi->result_len = 8; - break; - - case COMMAND_RETURN_CONFIG_DATA:scsi->result[0] = 1 << scsi->dma; - scsi->result[1] = 1 << (scsi->irq - 9); - scsi->result[2] = scsi->host_id; - scsi->cmd_state = CMD_STATE_SEND_RESULT; - scsi->result_pos = 0; - scsi->result_len = 3; - break; - - case COMMAND_ECHO:pclog("ECHO\n"); - scsi->result[0] = scsi->params[0]; - scsi->cmd_state = CMD_STATE_SEND_RESULT; - scsi->result_pos = 0; - scsi->result_len = 1; - break; - - case COMMAND_RETURN_SETUP_DATA:pclog("Return setup data %i %02x %06x\n", scsi->params[0], scsi->mbc, scsi->mba); - scsi->result[0] = 0x00; /*SPS*/ - scsi->result[1] = scsi->atbs; /*AT bus speed*/ - scsi->result[2] = scsi->bon; /*BON*/ - scsi->result[3] = scsi->boff; /*BOFF*/ - scsi->result[4] = scsi->mbc; /*DS:E8 - mailbox count*/ - scsi->result[5] = scsi->mba >> 16; /*DS:DA - set by command 0x81?*/ - scsi->result[6] = scsi->mba >> 8; /*DS:DB*/ - scsi->result[7] = scsi->mba & 0xff; /*DS:DC*/ - scsi->result[8] = 0x00; /*STA0*/ - scsi->result[9] = 0x00; /*STA1*/ - scsi->result[10] = 0x00; /*STA2*/ - scsi->result[11] = 0x00; /*STA3*/ - scsi->result[12] = 0x00; /*STA4*/ - scsi->result[13] = 0x00; /*STA5*/ - scsi->result[14] = 0x00; /*STA6*/ - scsi->result[15] = 0x00; /*STA7*/ - scsi->result[16] = 0x00; /*DS (DS:1e5b)*/ - if (scsi->type == SCSI_BT545S) { - scsi->result[17] = 0x42; /*Firmware version*/ - scsi->result[18] = 0x44; - scsi->result[19] = 0x41; - } else { - for (c = 0; c < 20; c++) - scsi->result[c + 17] = 0; /*Customer signature*/ - scsi->result[37] = 0; /*Auto-retry*/ - scsi->result[38] = 0; /*Board switches*/ - scsi->result[39] = 0xa3; /*Checksum*/ - scsi->result[40] = 0xc2; - scsi->result[41] = scsi->bios_mba >> 16; - scsi->result[42] = scsi->bios_mba >> 8; - scsi->result[43] = scsi->bios_mba & 0xff; - } - scsi->cmd_state = CMD_STATE_SEND_RESULT; - scsi->result_pos = 0; - scsi->result_len = MIN(scsi->params[0], 20); - for (; scsi->result_len < scsi->params[0]; scsi->result_len++) - scsi->result[scsi->result_len] = 0; - break; - - case COMMAND_WRITE_CHANNEL_2_BUF:addr = scsi->params[2] | (scsi->params[1] << 8) | (scsi->params[0] << 16); - pclog("WRITE_CHANNEL_2_BUF %06x\n", addr); - for (c = 0; c < 64; c++) - scsi->dma_buffer[c] = mem_readb_phys(addr + c); - set_irq(scsi, ISR_HACC); - scsi->cmd_state = CMD_STATE_IDLE; - pclog("Command complete\n"); - break; - - case COMMAND_READ_CHANNEL_2_BUF:addr = scsi->params[2] | (scsi->params[1] << 8) | (scsi->params[0] << 16); - pclog("READ_CHANNEL_2_BUF %06x\n", addr); - for (c = 0; c < 64; c++) - mem_writeb_phys(addr + c, scsi->dma_buffer[c]); - set_irq(scsi, ISR_HACC); - scsi->cmd_state = CMD_STATE_IDLE; - pclog("Command complete\n"); - break; - - case 0x22: - if (scsi->type == SCSI_AHA1542C) { - /*COMMAND_ADAPTEC_PROGRAM_EEPROM*/ - for (c = 0; c < scsi->params[1]; c++) { - pclog("EEPROM %02x = %02x\n", (scsi->params[2] + c) & 0xff, scsi->params[c + 3]); - scsi->eeprom[(scsi->params[2] + c) & 0xff] = scsi->params[c + 3]; - } - scsi->host_id = scsi->eeprom[0] & 7; - scsi->dma = (scsi->eeprom[1] >> 4) & 7; - scsi->irq = (scsi->eeprom[1] & 7) + 9; - pclog("Program EEPROM: IRQ=%i DMA=%i host_id=%i\n", scsi->irq, scsi->dma, scsi->host_id); - - aha1542c_eeprom_save(scsi); - set_irq(scsi, ISR_HACC); - scsi->cmd_state = CMD_STATE_IDLE; - } else { - /*COMMAND_BUSLOGIC_22*/ - pclog("BUSLOGIC_22\n"); - set_irq(scsi, ISR_HACC); - scsi->cmd_state = CMD_STATE_IDLE; - primed = 1; -// scsi->result[0] = 1 << scsi->dma; /*DMA7*/ -// scsi->result[1] = 1 << (scsi->irq-9); /*IRQ10*/ -// scsi->result[2] = scsi->host_id; /*SCSI ID*/ -// scsi->cmd_state = CMD_STATE_SEND_RESULT; -// scsi->result_pos = 0; -// scsi->result_len = 3; - } - break; - - case COMMAND_ADAPTEC_RETURN_EEPROM_DATA:pclog("Return EEPROM data %02x %02x %02x\n", scsi->params[0], scsi->params[1], scsi->params[2]); - for (c = 0; c < scsi->params[1]; c++) { - scsi->result[c] = scsi->eeprom[(scsi->params[2] + c) & 0xff]; - pclog(" EEPROM data %02x %02x\n", (scsi->params[2] + c) & 0xff, scsi->result[c]); - } - scsi->cmd_state = CMD_STATE_SEND_RESULT; - scsi->result_pos = 0; - scsi->result_len = c; - break; - - case COMMAND_ADAPTEC_SET_SHADOW_PARAMS:pclog("Set shadow params %02x\n", scsi->params[0]); - scsi->shadow = scsi->params[0]; - set_irq(scsi, ISR_HACC); - scsi->cmd_state = CMD_STATE_IDLE; - break; - - case COMMAND_ADAPTEC_BIOS_MAILBOX_INIT:scsi->bios_mbc = scsi->params[0]; - scsi->bios_mba = scsi->params[3] | (scsi->params[2] << 8) | (scsi->params[1] << 16); - scsi->bios_mbo_inited = 1; - pclog("BIOS mailbox init: MBC=%02x MBC=%06x\n", scsi->bios_mbc, scsi->bios_mba); - set_irq(scsi, ISR_HACC); - scsi->cmd_state = CMD_STATE_IDLE; - break; - - case COMMAND_ADAPTEC_SET_BIOS_BANK_1:mem_mapping_set_exec(&scsi->mapping, &scsi->bios_rom.rom[0]); - scsi->bios_bank = 0x0000; - set_irq(scsi, ISR_HACC); - scsi->cmd_state = CMD_STATE_IDLE; - break; - - case COMMAND_ADAPTEC_SET_BIOS_BANK_2:mem_mapping_set_exec(&scsi->mapping, &scsi->bios_rom.rom[0x4000]); - scsi->bios_bank = 0x4000; - set_irq(scsi, ISR_HACC); - scsi->cmd_state = CMD_STATE_IDLE; - break; - - case COMMAND_ADAPTEC_GET_EXT_BIOS_INFO:scsi->result[0] = 0; - scsi->result[1] = scsi->mblt; - scsi->cmd_state = CMD_STATE_SEND_RESULT; - scsi->result_pos = 0; - scsi->result_len = 2; - break; - - case COMMAND_ENABLE_MAILBOX_INTERFACE:scsi->mbu = scsi->params[0]; - scsi->mblt = scsi->params[1]; - set_irq(scsi, ISR_HACC); - scsi->cmd_state = CMD_STATE_IDLE; - break; - - case COMMAND_ADAPTEC_START_BIOS_SCSI_CMD:pclog("START_BIOS_SCSI_COMMAND %02x %08x %i\n", scsi->bios_mbc, scsi->bios_mba, scsi->ccb_state); - scsi->bios_mbo_req++; - scsi->cmd_state = CMD_STATE_IDLE; - break; - - case COMMAND_BUSLOGIC_81:scsi->mbc = scsi->params[0]; - scsi->mba = scsi->params[1] | (scsi->params[2] << 8) | (scsi->params[3] << 16) | (scsi->params[4] << 24); - scsi->mba_i = scsi->mba + scsi->mbc * 8; - scsi->mb_format = MB_FORMAT_8; - scsi->current_mbo = 0; - scsi->current_mbi = 0; - pclog("Mailbox init: MBC=%02x MBC=%08x\n", scsi->mbc, scsi->mba); - scsi->status &= ~STATUS_INIT; - set_irq(scsi, ISR_HACC); - scsi->cmd_state = CMD_STATE_IDLE; - break; - - case COMMAND_BUSLOGIC_84:scsi->result[0] = 0x31; /*Firmware sub-version?*/ - scsi->cmd_state = CMD_STATE_SEND_RESULT; - scsi->result_pos = 0; - scsi->result_len = 1; - break; - - case COMMAND_BUSLOGIC_85:scsi->result[0] = 0x20; /*???*/ - scsi->cmd_state = CMD_STATE_SEND_RESULT; - scsi->result_pos = 0; - scsi->result_len = 1; - break; - - case COMMAND_BUSLOGIC_ADAPTER_MODEL_NR:scsi->result[0] = '5'; - scsi->result[1] = '4'; - scsi->result[2] = '2'; - scsi->result[3] = 'B'; - scsi->result[4] = 'H'; - scsi->cmd_state = CMD_STATE_SEND_RESULT; - scsi->result_pos = 0; - scsi->result_len = MIN(scsi->params[0], 5); - for (; scsi->result_len < scsi->params[0]; scsi->result_len++) - scsi->result[scsi->result_len] = 0; - break; - - case COMMAND_BUSLOGIC_INQUIRY_SYNC_PERIOD: - for (c = 0; c < 8; c++) - scsi->result[c] = 0; - scsi->cmd_state = CMD_STATE_SEND_RESULT; - scsi->result_pos = 0; - scsi->result_len = MIN(scsi->params[0], 8); - for (; scsi->result_len < scsi->params[0]; scsi->result_len++) - scsi->result[scsi->result_len] = 0; - break; - - case COMMAND_BUSLOGIC_EXTENDED_SETUP_INFO:pclog("Extended setup info %i\n", scsi->params[0]); - scsi->result[0] = 0x41; - scsi->result[1] = scsi->bios_addr >> 12; /*BIOS addr*/ - scsi->result[2] = 0x00; - scsi->result[3] = 0x20; - scsi->result[4] = 0x00; /*DS:E8 >> 3*/ - scsi->result[5] = 0x00; /*DS:DA - set by command 0x81?*/ - scsi->result[6] = 0x00; /*DS:DB*/ - scsi->result[7] = 0x00; /*DS:DC*/ - scsi->result[8] = 0x00; /*DS:DD*/ - scsi->result[9] = 0x33; /*FFFF:9*/ - scsi->result[10] = 0x33; /*FFFF:A*/ - scsi->result[11] = 0x31; /*FFFF:B*/ - scsi->cmd_state = CMD_STATE_SEND_RESULT; - scsi->result_pos = 0; - scsi->result_len = MIN(scsi->params[0], 12); - for (; scsi->result_len < scsi->params[0]; scsi->result_len++) - scsi->result[scsi->result_len] = 0; - break; - - case COMMAND_BUSLOGIC_STRICT_RR:set_irq(scsi, ISR_HACC); - scsi->cmd_state = CMD_STATE_IDLE; - break; - - case COMMAND_BUSLOGIC_SET_CCB_FORMAT:set_irq(scsi, ISR_HACC); - scsi->cmd_state = CMD_STATE_IDLE; - break; - - default:fatal("Bad AHA154x command in progress %02x\n", scsi->command); - } - break; - - case CMD_STATE_GET_PARAMS: - if (scsi->status & STATUS_CDF) { - scsi->status &= ~STATUS_CDF; - - scsi->params[scsi->cur_param++] = scsi->cmd_data; - - if (scsi->cur_param == scsi->command_len) - scsi->cmd_state = CMD_STATE_CMD_IN_PROGRESS; - } - break; - - case CMD_STATE_SEND_RESULT: - if (!(scsi->status & STATUS_DF)) { - if (scsi->result_pos == scsi->result_len) { - set_irq(scsi, ISR_HACC); - scsi->cmd_state = CMD_STATE_IDLE; - pclog("Command complete\n"); - } else { - scsi->status |= STATUS_DF; - scsi->data_in = scsi->result[scsi->result_pos++]; - pclog("Return data %02x %i %i\n", scsi->data_in, scsi->result_pos - 1, scsi->result_len); - } - } - break; - - default:fatal("Unknown state %d\n", scsi->cmd_state); - } + uint32_t addr; + int c; + + switch (scsi->cmd_state) { + case CMD_STATE_RESET: + scsi->status = STATUS_INIT; + scsi->cmd_state = CMD_STATE_IDLE; + pclog("AHA154x reset complete\n"); + break; + + case CMD_STATE_IDLE: + if (scsi->status & STATUS_CDF) { + int invalid = 0; + + scsi->status &= ~STATUS_CDF; + + scsi->command = scsi->cmd_data; + pclog("New command %02x\n", scsi->command); + // if (scsi->command == 0x22) + // fatal("Here\n"); + // output = 3; + switch (scsi->command) { + case COMMAND_NOP: + case COMMAND_START_SCSI_COMMAND: + case COMMAND_ADAPTER_INQUIRY: + case COMMAND_INQUIRE_INSTALLED_DEVICES: + case COMMAND_RETURN_CONFIG_DATA: + scsi->command_len = 0; + break; + + case COMMAND_ADAPTEC_SET_BIOS_BANK_1: + case COMMAND_ADAPTEC_SET_BIOS_BANK_2: + case COMMAND_ADAPTEC_GET_EXT_BIOS_INFO: + case COMMAND_ADAPTEC_START_BIOS_SCSI_CMD: + if (scsi->type == SCSI_AHA1542C) + scsi->command_len = 0; + else + invalid = 1; + break; + + case COMMAND_BUSLOGIC_84: + case COMMAND_BUSLOGIC_85: + if (scsi->type == SCSI_BT545S) + scsi->command_len = 0; + else + invalid = 1; + break; + + case COMMAND_ECHO: + case COMMAND_MAILBOX_OUT_IRQ_ENA: + case COMMAND_SET_BUS_ON_TIME: + case COMMAND_SET_BUS_OFF_TIME: + case COMMAND_SET_AT_BUS_SPEED: + case COMMAND_RETURN_SETUP_DATA: + scsi->command_len = 1; + break; + + case COMMAND_ADAPTEC_SET_SHADOW_PARAMS: + if (scsi->type == SCSI_AHA1542C) + scsi->command_len = 1; + else + invalid = 1; + break; + + case 0x22: + if (scsi->type == SCSI_AHA1542C) + scsi->command_len = 35; /*COMMAND_ADAPTEC_PROGRAM_EEPROM*/ + else { + // scsi->command_len = 1; /*COMMAND_BUSLOGIC_22*/ + pclog("Get 22\n"); + // scsi->command_len = 0; + invalid = 1; + primed = 1; + } + break; + + case COMMAND_BUSLOGIC_SET_CCB_FORMAT: + case COMMAND_BUSLOGIC_STRICT_RR: + case COMMAND_BUSLOGIC_EXTENDED_SETUP_INFO: + case COMMAND_BUSLOGIC_ADAPTER_MODEL_NR: + case COMMAND_BUSLOGIC_INQUIRY_SYNC_PERIOD: + if (scsi->type == SCSI_BT545S) + scsi->command_len = 1; + else + invalid = 1; + break; + + case COMMAND_ENABLE_MAILBOX_INTERFACE: + if (scsi->type == SCSI_AHA1542C) + scsi->command_len = 2; + else + invalid = 1; + break; + + case COMMAND_WRITE_CHANNEL_2_BUF: + case COMMAND_READ_CHANNEL_2_BUF: + scsi->command_len = 3; + break; + + case COMMAND_SET_SELECTION_TIMEOUT: + scsi->command_len = 4; + break; + + case COMMAND_ADAPTEC_RETURN_EEPROM_DATA: + if (scsi->type == SCSI_AHA1542C) + scsi->command_len = 3; + else + invalid = 1; + break; + + case COMMAND_MAILBOX_INITIALIZATION: + scsi->command_len = 4; + break; + + case COMMAND_BUSLOGIC_81: + if (scsi->type == SCSI_BT545S) + scsi->command_len = 5; + else + invalid = 1; + break; + + case COMMAND_START_BIOS_COMMAND: + scsi->command_len = 10; + scsi->bios_cmd_state = 0; + break; + + case COMMAND_ADAPTEC_BIOS_MAILBOX_INIT: + if (scsi->type == SCSI_AHA1542C) + scsi->command_len = 4; + else + invalid = 1; + break; + + /* case 0x40: case 0x42: case 0x44: case 0xff: + invalid = 1; + break;*/ + + default: + if (scsi->type == SCSI_AHA1542C) { + if ((scsi->command > 0xd && scsi->command < 0x1a) || + (scsi->command > 0x2a && scsi->command != 0x82)) + invalid = 1; + else + fatal("Bad AHA154x command %02x\n", scsi->command); + } else { + if (scsi->command > 0x22 && (scsi->command < 0xfa || scsi->command > 0xfc) && + !(scsi->command >= 0x81 && scsi->command <= 0x9d) && scsi->command != 0xda && + scsi->command != 0xdc) + invalid = 1; + else + fatal("Bad BT545S command %02x\n", scsi->command); + } + break; + } + + if (invalid) { + scsi->status |= STATUS_INVDCMD; + set_irq(scsi, ISR_HACC); + scsi->cmd_state = CMD_STATE_IDLE; + } else if (!scsi->command_len) + scsi->cmd_state = CMD_STATE_CMD_IN_PROGRESS; + else { + scsi->cmd_state = CMD_STATE_GET_PARAMS; + scsi->cur_param = 0; + } + } + if (scsi->cmd_state != CMD_STATE_CMD_IN_PROGRESS) { + // pclog("Command not fallthrough\n"); + break; + } + // pclog("Command fallthrough\n"); + /*Fallthrough*/ + + case CMD_STATE_CMD_IN_PROGRESS: + switch (scsi->command) { + case COMMAND_NOP: + // pclog("NOP complete\n"); + set_irq(scsi, ISR_HACC); + scsi->cmd_state = CMD_STATE_IDLE; + break; + + case COMMAND_MAILBOX_INITIALIZATION: + scsi->mbc = scsi->params[0]; + scsi->mba = scsi->params[3] | (scsi->params[2] << 8) | (scsi->params[1] << 16); + scsi->mba_i = scsi->mba + scsi->mbc * 4; + scsi->mb_format = MB_FORMAT_4; + scsi->current_mbo = 0; + scsi->current_mbi = 0; + pclog("Mailbox init: MBC=%02x MBC=%06x\n", scsi->mbc, scsi->mba); + scsi->status &= ~STATUS_INIT; + set_irq(scsi, ISR_HACC); + scsi->cmd_state = CMD_STATE_IDLE; + break; + + case COMMAND_START_SCSI_COMMAND: + pclog("START_SCSI_COMMAND %i %i\n", scsi->ccb_state, scsi->scsi_state); + scsi->mbo_req++; + scsi->cmd_state = CMD_STATE_IDLE; + /*Don't send IRQ until we actually start processing a mailbox*/ + break; + + case COMMAND_START_BIOS_COMMAND: + if (scsi->ccb_state != CCB_STATE_IDLE) + break; + if (!scsi->bios_cmd_state) + pclog("Start BIOS command %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", scsi->params[0], + scsi->params[1], scsi->params[2], scsi->params[3], scsi->params[4], scsi->params[5], + scsi->params[6], scsi->params[7], scsi->params[8], scsi->params[9]); + if (scsi->params[0] >= 0x16) { + /*Only commands below 0x16 are implemented*/ + scsi->status |= STATUS_INVDCMD; + set_irq(scsi, ISR_HACC); + scsi->cmd_state = CMD_STATE_IDLE; + } else + switch (scsi->params[0]) { + case 0x00: /*Reset Disk System*/ + scsi->data_in = 0; + set_irq(scsi, ISR_HACC); + scsi->status |= STATUS_DF; + scsi->cmd_state = CMD_STATE_IDLE; + break; + + case 0x01: /*Get Status of Last Operation*/ + scsi->data_in = 0; + set_irq(scsi, ISR_HACC); + scsi->status |= STATUS_DF; + scsi->cmd_state = CMD_STATE_IDLE; + break; + + case 0x02: /*Read Sector(s) Into Memory*/ + switch (scsi->bios_cmd_state) { + case 0: { + int sector = scsi->params[5]; + int head = (scsi->params[4] & 0xf) | ((scsi->params[3] & 3) << 4); + int cylinder = (scsi->params[3] >> 2) | ((scsi->params[2] & 0xf) << 6); + + pclog("Cylinder=%i head=%i sector=%i\n", cylinder, head, sector); + addr = sector + (head * 32) + (cylinder * 64 * 32); + } + scsi->ccb.cdb[0] = SCSI_READ_10; + scsi->ccb.cdb[1] = 0; + scsi->ccb.cdb[2] = addr >> 24; + scsi->ccb.cdb[3] = addr >> 16; + scsi->ccb.cdb[4] = addr >> 8; + scsi->ccb.cdb[5] = addr & 0xff; + scsi->ccb.cdb[6] = 0; + scsi->ccb.cdb[7] = 0; + scsi->ccb.cdb[8] = scsi->params[6]; + scsi->ccb.cdb[9] = 0; + scsi->ccb.lun = 0; + scsi->ccb.target_id = scsi->params[1] & 7; + scsi->ccb.scsi_cmd_len = 10; + scsi->ccb.data_pointer = + scsi->params[9] | (scsi->params[8] << 8) | (scsi->params[7] << 16); + ; + scsi->ccb.data_len = 512 * scsi->params[6]; + scsi->ccb.req_sense_len = CCB_SENSE_14; + scsi->ccb_state = CCB_STATE_SEND_COMMAND; + pclog("Read sector %08x %06x\n", addr, scsi->ccb.data_pointer); + scsi->bios_cmd_state++; + break; + case 1: + if (scsi->ccb.status) + fatal("Read sector fail %02x\n", scsi->ccb.status); + scsi->data_in = 0x00; + set_irq(scsi, ISR_HACC); + scsi->status |= STATUS_DF; + scsi->cmd_state = CMD_STATE_IDLE; + break; + } + break; + + case 0x03: /*Write Disk Sector(s)*/ + switch (scsi->bios_cmd_state) { + case 0: { + int sector = scsi->params[5]; + int head = (scsi->params[4] & 0xf) | ((scsi->params[3] & 3) << 4); + int cylinder = (scsi->params[3] >> 2) | ((scsi->params[2] & 0xf) << 6); + + addr = sector + (head * 32) + (cylinder * 64 * 32); + } + scsi->ccb.cdb[0] = SCSI_WRITE_10; + scsi->ccb.cdb[1] = 0; + scsi->ccb.cdb[2] = addr >> 24; + scsi->ccb.cdb[3] = addr >> 16; + scsi->ccb.cdb[4] = addr >> 8; + scsi->ccb.cdb[5] = addr & 0xff; + scsi->ccb.cdb[6] = 0; + scsi->ccb.cdb[7] = 0; + scsi->ccb.cdb[8] = scsi->params[6]; + scsi->ccb.cdb[9] = 0; + scsi->ccb.lun = 0; + scsi->ccb.target_id = scsi->params[1] & 7; + scsi->ccb.scsi_cmd_len = 10; + scsi->ccb.data_pointer = + scsi->params[9] | (scsi->params[8] << 8) | (scsi->params[7] << 16); + ; + scsi->ccb.data_len = 512 * scsi->params[6]; + scsi->ccb.req_sense_len = CCB_SENSE_14; + scsi->ccb_state = CCB_STATE_SEND_COMMAND; + pclog("Write sector %08x %06x\n", addr, scsi->ccb.data_pointer); + scsi->bios_cmd_state++; + break; + case 1: + if (scsi->ccb.status) + fatal("Write sector fail %02x\n", scsi->ccb.status); + scsi->data_in = 0x00; + set_irq(scsi, ISR_HACC); + scsi->status |= STATUS_DF; + scsi->cmd_state = CMD_STATE_IDLE; + break; + } + break; + + case 0x04: /*Verify Disk Sector(s)*/ + switch (scsi->bios_cmd_state) { + case 0: { + int sector = scsi->params[5]; + int head = (scsi->params[4] & 0xf) | ((scsi->params[3] & 3) << 4); + int cylinder = (scsi->params[3] >> 2) | ((scsi->params[2] & 0xf) << 6); + + addr = sector + (head * 32) + (cylinder * 64 * 32); + } + scsi->ccb.cdb[0] = SCSI_VERIFY_10; + scsi->ccb.cdb[1] = 0; + scsi->ccb.cdb[2] = addr >> 24; + scsi->ccb.cdb[3] = addr >> 16; + scsi->ccb.cdb[4] = addr >> 8; + scsi->ccb.cdb[5] = addr & 0xff; + scsi->ccb.cdb[6] = 0; + scsi->ccb.cdb[7] = 0; + scsi->ccb.cdb[8] = scsi->params[6]; + scsi->ccb.cdb[9] = 0; + scsi->ccb.lun = 0; + scsi->ccb.target_id = scsi->params[1] & 7; + scsi->ccb.scsi_cmd_len = 10; + scsi->ccb.data_pointer = + scsi->params[9] | (scsi->params[8] << 8) | (scsi->params[7] << 16); + ; + scsi->ccb.data_len = 512 * scsi->params[6]; + scsi->ccb.req_sense_len = CCB_SENSE_14; + scsi->ccb_state = CCB_STATE_SEND_COMMAND; + pclog("Verify sector %08x %06x\n", addr, scsi->ccb.data_pointer); + scsi->bios_cmd_state++; + break; + case 1: + if (scsi->ccb.status) + fatal("Verify sector fail %02x\n", scsi->ccb.status); + scsi->data_in = 0x00; + set_irq(scsi, ISR_HACC); + scsi->status |= STATUS_DF; + scsi->cmd_state = CMD_STATE_IDLE; + break; + } + break; + + /*AHA1542C firmware just fails all of these*/ + case 0x05: + case 0x06: + case 0x07: + case 0x0a: + case 0x0b: + case 0x12: + case 0x13: + scsi->status |= STATUS_INVDCMD; + set_irq(scsi, ISR_HACC); + scsi->cmd_state = CMD_STATE_IDLE; + break; + + case 0x08: /*Get Drive Parameters*/ + switch (scsi->bios_cmd_state) { + case 0: + scsi->ccb.cdb[0] = SCSI_READ_CAPACITY_10; + scsi->ccb.cdb[1] = 0; + scsi->ccb.cdb[2] = 0; + scsi->ccb.cdb[3] = 0; + scsi->ccb.cdb[4] = 0; + scsi->ccb.cdb[5] = 0; + scsi->ccb.cdb[6] = 0; + scsi->ccb.cdb[7] = 0; + scsi->ccb.cdb[8] = 0; + scsi->ccb.cdb[9] = 0; + scsi->ccb.lun = 0; + scsi->ccb.target_id = scsi->params[1] & 7; + scsi->ccb.scsi_cmd_len = 10; + scsi->ccb.data_pointer = -1; + scsi->ccb.data_len = 8; + scsi->ccb.req_sense_len = CCB_SENSE_NONE; + scsi->ccb_state = CCB_STATE_SEND_COMMAND; + scsi->bios_cmd_state++; + break; + case 1: + addr = scsi->params[9] | (scsi->params[8] << 8) | (scsi->params[7] << 16); + mem_writeb_phys(addr, scsi->int_buffer[0]); + mem_writeb_phys(addr + 1, scsi->int_buffer[1]); + mem_writeb_phys(addr + 2, scsi->int_buffer[2]); + mem_writeb_phys(addr + 3, scsi->int_buffer[3]); + pclog("Got size %06x %02x%02x%02x%02x\n", addr, scsi->int_buffer[3], + scsi->int_buffer[2], scsi->int_buffer[1], scsi->int_buffer[0]); + scsi->data_in = 0; + set_irq(scsi, ISR_HACC); + scsi->status |= STATUS_DF; + scsi->cmd_state = CMD_STATE_IDLE; + break; + } + break; + + case 0x09: /*Initialize Drive Parameters*/ + case 0x0c: /*Seek To Cylinder*/ + case 0x0d: /*Reset Hard Disks*/ + case 0x0e: /*Read Sector Buffer*/ + case 0x0f: /*Write Sector Buffer*/ + case 0x10: /*Check If Drive Ready*/ + case 0x11: /*Recalibrate Drive*/ + case 0x14: /*Controller Internal Diagnostic*/ + pclog("Unimplemented AHA1542 BIOS command - 0x%02x\n", scsi->params[0]); + scsi->data_in = 0; + set_irq(scsi, ISR_HACC); + scsi->status |= STATUS_DF; + scsi->cmd_state = CMD_STATE_IDLE; + break; + + case 0x15: /*Get Disk Type*/ + switch (scsi->bios_cmd_state) { + case 0: + scsi->ccb.cdb[0] = SCSI_INQUIRY; + scsi->ccb.cdb[1] = 0; + scsi->ccb.cdb[2] = 0; + scsi->ccb.cdb[3] = 0; + scsi->ccb.cdb[4] = 36; + scsi->ccb.cdb[5] = 0; + scsi->ccb.lun = 0; + scsi->ccb.target_id = scsi->params[1] & 7; + scsi->ccb.scsi_cmd_len = 6; + scsi->ccb.data_pointer = -1; + scsi->ccb.data_len = 36; + scsi->ccb.req_sense_len = CCB_SENSE_NONE; + scsi->ccb_state = CCB_STATE_SEND_COMMAND; + scsi->ccb.from_mailbox = 0; + scsi->bios_cmd_state++; + break; + case 1: + if (scsi->int_buffer[0] & 0x1f) { + /*Not a direct-access device*/ + fatal("Not a direct-access device\n"); + } + scsi->ccb.cdb[0] = SCSI_READ_CAPACITY_10; + scsi->ccb.cdb[1] = 0; + scsi->ccb.cdb[2] = 0; + scsi->ccb.cdb[3] = 0; + scsi->ccb.cdb[4] = 0; + scsi->ccb.cdb[5] = 0; + scsi->ccb.cdb[6] = 0; + scsi->ccb.cdb[7] = 0; + scsi->ccb.cdb[8] = 0; + scsi->ccb.cdb[9] = 0; + scsi->ccb.lun = 0; + scsi->ccb.target_id = scsi->params[1] & 7; + scsi->ccb.scsi_cmd_len = 10; + scsi->ccb.data_pointer = -1; + scsi->ccb.data_len = 8; + scsi->ccb.req_sense_len = CCB_SENSE_NONE; + scsi->ccb_state = CCB_STATE_SEND_COMMAND; + scsi->bios_cmd_state++; + break; + case 2: + addr = scsi->params[9] | (scsi->params[8] << 8) | (scsi->params[7] << 16); + mem_writeb_phys(addr, scsi->int_buffer[0]); + mem_writeb_phys(addr + 1, scsi->int_buffer[1]); + mem_writeb_phys(addr + 2, scsi->int_buffer[2]); + mem_writeb_phys(addr + 3, scsi->int_buffer[3]); + pclog("Got size %06x %02x%02x%02x%02x\n", addr, scsi->int_buffer[3], + scsi->int_buffer[2], scsi->int_buffer[1], scsi->int_buffer[0]); + scsi->data_in = 0; + set_irq(scsi, ISR_HACC); + scsi->status |= STATUS_DF; + scsi->cmd_state = CMD_STATE_IDLE; + break; + + default: + fatal("Get Disk Type state %i\n", scsi->bios_cmd_state); + } + // fatal("data_pointer %06x\n", scsi->ccb.data_pointer); + break; + + default: + scsi->status |= STATUS_INVDCMD; + set_irq(scsi, ISR_HACC); + scsi->cmd_state = CMD_STATE_IDLE; + break; + } + break; + + case COMMAND_ADAPTER_INQUIRY: + if (scsi->type == SCSI_BT545S) { + scsi->result[0] = 0x41; + scsi->result[1] = 0x41; /*Standard model*/ + scsi->result[2] = 0x33; /*Firmware revision*/ + scsi->result[3] = 0x33; + } else { + scsi->result[0] = 0x44; /*AHA-1542CF*/ + scsi->result[1] = 0x30; + scsi->result[2] = 0x30; /*Firmware revision*/ + scsi->result[3] = 0x31; + } + scsi->cmd_state = CMD_STATE_SEND_RESULT; + scsi->result_pos = 0; + scsi->result_len = 4; + break; + + case COMMAND_MAILBOX_OUT_IRQ_ENA: + scsi->mbo_irq_enable = scsi->params[0]; + set_irq(scsi, ISR_HACC); + scsi->cmd_state = CMD_STATE_IDLE; + break; + + case COMMAND_SET_SELECTION_TIMEOUT: + scsi->e_d = scsi->params[0]; + scsi->to = (scsi->params[1] << 8) | scsi->params[2]; + set_irq(scsi, ISR_HACC); + scsi->cmd_state = CMD_STATE_IDLE; + break; + + case COMMAND_SET_BUS_ON_TIME: + scsi->bon = scsi->params[0]; + set_irq(scsi, ISR_HACC); + scsi->cmd_state = CMD_STATE_IDLE; + break; + + case COMMAND_SET_BUS_OFF_TIME: + scsi->boff = scsi->params[0]; + set_irq(scsi, ISR_HACC); + scsi->cmd_state = CMD_STATE_IDLE; + break; + + case COMMAND_SET_AT_BUS_SPEED: + scsi->atbs = scsi->params[0]; + set_irq(scsi, ISR_HACC); + scsi->cmd_state = CMD_STATE_IDLE; + break; + + case COMMAND_INQUIRE_INSTALLED_DEVICES: + for (c = 0; c < 8; c++) + scsi->result[c] = scsi->bus.devices[c] ? 1 : 0; + scsi->cmd_state = CMD_STATE_SEND_RESULT; + scsi->result_pos = 0; + scsi->result_len = 8; + break; + + case COMMAND_RETURN_CONFIG_DATA: + scsi->result[0] = 1 << scsi->dma; + scsi->result[1] = 1 << (scsi->irq - 9); + scsi->result[2] = scsi->host_id; + scsi->cmd_state = CMD_STATE_SEND_RESULT; + scsi->result_pos = 0; + scsi->result_len = 3; + break; + + case COMMAND_ECHO: + pclog("ECHO\n"); + scsi->result[0] = scsi->params[0]; + scsi->cmd_state = CMD_STATE_SEND_RESULT; + scsi->result_pos = 0; + scsi->result_len = 1; + break; + + case COMMAND_RETURN_SETUP_DATA: + pclog("Return setup data %i %02x %06x\n", scsi->params[0], scsi->mbc, scsi->mba); + scsi->result[0] = 0x00; /*SPS*/ + scsi->result[1] = scsi->atbs; /*AT bus speed*/ + scsi->result[2] = scsi->bon; /*BON*/ + scsi->result[3] = scsi->boff; /*BOFF*/ + scsi->result[4] = scsi->mbc; /*DS:E8 - mailbox count*/ + scsi->result[5] = scsi->mba >> 16; /*DS:DA - set by command 0x81?*/ + scsi->result[6] = scsi->mba >> 8; /*DS:DB*/ + scsi->result[7] = scsi->mba & 0xff; /*DS:DC*/ + scsi->result[8] = 0x00; /*STA0*/ + scsi->result[9] = 0x00; /*STA1*/ + scsi->result[10] = 0x00; /*STA2*/ + scsi->result[11] = 0x00; /*STA3*/ + scsi->result[12] = 0x00; /*STA4*/ + scsi->result[13] = 0x00; /*STA5*/ + scsi->result[14] = 0x00; /*STA6*/ + scsi->result[15] = 0x00; /*STA7*/ + scsi->result[16] = 0x00; /*DS (DS:1e5b)*/ + if (scsi->type == SCSI_BT545S) { + scsi->result[17] = 0x42; /*Firmware version*/ + scsi->result[18] = 0x44; + scsi->result[19] = 0x41; + } else { + for (c = 0; c < 20; c++) + scsi->result[c + 17] = 0; /*Customer signature*/ + scsi->result[37] = 0; /*Auto-retry*/ + scsi->result[38] = 0; /*Board switches*/ + scsi->result[39] = 0xa3; /*Checksum*/ + scsi->result[40] = 0xc2; + scsi->result[41] = scsi->bios_mba >> 16; + scsi->result[42] = scsi->bios_mba >> 8; + scsi->result[43] = scsi->bios_mba & 0xff; + } + scsi->cmd_state = CMD_STATE_SEND_RESULT; + scsi->result_pos = 0; + scsi->result_len = MIN(scsi->params[0], 20); + for (; scsi->result_len < scsi->params[0]; scsi->result_len++) + scsi->result[scsi->result_len] = 0; + break; + + case COMMAND_WRITE_CHANNEL_2_BUF: + addr = scsi->params[2] | (scsi->params[1] << 8) | (scsi->params[0] << 16); + pclog("WRITE_CHANNEL_2_BUF %06x\n", addr); + for (c = 0; c < 64; c++) + scsi->dma_buffer[c] = mem_readb_phys(addr + c); + set_irq(scsi, ISR_HACC); + scsi->cmd_state = CMD_STATE_IDLE; + pclog("Command complete\n"); + break; + + case COMMAND_READ_CHANNEL_2_BUF: + addr = scsi->params[2] | (scsi->params[1] << 8) | (scsi->params[0] << 16); + pclog("READ_CHANNEL_2_BUF %06x\n", addr); + for (c = 0; c < 64; c++) + mem_writeb_phys(addr + c, scsi->dma_buffer[c]); + set_irq(scsi, ISR_HACC); + scsi->cmd_state = CMD_STATE_IDLE; + pclog("Command complete\n"); + break; + + case 0x22: + if (scsi->type == SCSI_AHA1542C) { + /*COMMAND_ADAPTEC_PROGRAM_EEPROM*/ + for (c = 0; c < scsi->params[1]; c++) { + pclog("EEPROM %02x = %02x\n", (scsi->params[2] + c) & 0xff, scsi->params[c + 3]); + scsi->eeprom[(scsi->params[2] + c) & 0xff] = scsi->params[c + 3]; + } + scsi->host_id = scsi->eeprom[0] & 7; + scsi->dma = (scsi->eeprom[1] >> 4) & 7; + scsi->irq = (scsi->eeprom[1] & 7) + 9; + pclog("Program EEPROM: IRQ=%i DMA=%i host_id=%i\n", scsi->irq, scsi->dma, scsi->host_id); + + aha1542c_eeprom_save(scsi); + set_irq(scsi, ISR_HACC); + scsi->cmd_state = CMD_STATE_IDLE; + } else { + /*COMMAND_BUSLOGIC_22*/ + pclog("BUSLOGIC_22\n"); + set_irq(scsi, ISR_HACC); + scsi->cmd_state = CMD_STATE_IDLE; + primed = 1; + // scsi->result[0] = 1 << scsi->dma; /*DMA7*/ + // scsi->result[1] = 1 << (scsi->irq-9); /*IRQ10*/ + // scsi->result[2] = scsi->host_id; /*SCSI ID*/ + // scsi->cmd_state = CMD_STATE_SEND_RESULT; + // scsi->result_pos = 0; + // scsi->result_len = 3; + } + break; + + case COMMAND_ADAPTEC_RETURN_EEPROM_DATA: + pclog("Return EEPROM data %02x %02x %02x\n", scsi->params[0], scsi->params[1], scsi->params[2]); + for (c = 0; c < scsi->params[1]; c++) { + scsi->result[c] = scsi->eeprom[(scsi->params[2] + c) & 0xff]; + pclog(" EEPROM data %02x %02x\n", (scsi->params[2] + c) & 0xff, scsi->result[c]); + } + scsi->cmd_state = CMD_STATE_SEND_RESULT; + scsi->result_pos = 0; + scsi->result_len = c; + break; + + case COMMAND_ADAPTEC_SET_SHADOW_PARAMS: + pclog("Set shadow params %02x\n", scsi->params[0]); + scsi->shadow = scsi->params[0]; + set_irq(scsi, ISR_HACC); + scsi->cmd_state = CMD_STATE_IDLE; + break; + + case COMMAND_ADAPTEC_BIOS_MAILBOX_INIT: + scsi->bios_mbc = scsi->params[0]; + scsi->bios_mba = scsi->params[3] | (scsi->params[2] << 8) | (scsi->params[1] << 16); + scsi->bios_mbo_inited = 1; + pclog("BIOS mailbox init: MBC=%02x MBC=%06x\n", scsi->bios_mbc, scsi->bios_mba); + set_irq(scsi, ISR_HACC); + scsi->cmd_state = CMD_STATE_IDLE; + break; + + case COMMAND_ADAPTEC_SET_BIOS_BANK_1: + mem_mapping_set_exec(&scsi->mapping, &scsi->bios_rom.rom[0]); + scsi->bios_bank = 0x0000; + set_irq(scsi, ISR_HACC); + scsi->cmd_state = CMD_STATE_IDLE; + break; + + case COMMAND_ADAPTEC_SET_BIOS_BANK_2: + mem_mapping_set_exec(&scsi->mapping, &scsi->bios_rom.rom[0x4000]); + scsi->bios_bank = 0x4000; + set_irq(scsi, ISR_HACC); + scsi->cmd_state = CMD_STATE_IDLE; + break; + + case COMMAND_ADAPTEC_GET_EXT_BIOS_INFO: + scsi->result[0] = 0; + scsi->result[1] = scsi->mblt; + scsi->cmd_state = CMD_STATE_SEND_RESULT; + scsi->result_pos = 0; + scsi->result_len = 2; + break; + + case COMMAND_ENABLE_MAILBOX_INTERFACE: + scsi->mbu = scsi->params[0]; + scsi->mblt = scsi->params[1]; + set_irq(scsi, ISR_HACC); + scsi->cmd_state = CMD_STATE_IDLE; + break; + + case COMMAND_ADAPTEC_START_BIOS_SCSI_CMD: + pclog("START_BIOS_SCSI_COMMAND %02x %08x %i\n", scsi->bios_mbc, scsi->bios_mba, scsi->ccb_state); + scsi->bios_mbo_req++; + scsi->cmd_state = CMD_STATE_IDLE; + break; + + case COMMAND_BUSLOGIC_81: + scsi->mbc = scsi->params[0]; + scsi->mba = scsi->params[1] | (scsi->params[2] << 8) | (scsi->params[3] << 16) | (scsi->params[4] << 24); + scsi->mba_i = scsi->mba + scsi->mbc * 8; + scsi->mb_format = MB_FORMAT_8; + scsi->current_mbo = 0; + scsi->current_mbi = 0; + pclog("Mailbox init: MBC=%02x MBC=%08x\n", scsi->mbc, scsi->mba); + scsi->status &= ~STATUS_INIT; + set_irq(scsi, ISR_HACC); + scsi->cmd_state = CMD_STATE_IDLE; + break; + + case COMMAND_BUSLOGIC_84: + scsi->result[0] = 0x31; /*Firmware sub-version?*/ + scsi->cmd_state = CMD_STATE_SEND_RESULT; + scsi->result_pos = 0; + scsi->result_len = 1; + break; + + case COMMAND_BUSLOGIC_85: + scsi->result[0] = 0x20; /*???*/ + scsi->cmd_state = CMD_STATE_SEND_RESULT; + scsi->result_pos = 0; + scsi->result_len = 1; + break; + + case COMMAND_BUSLOGIC_ADAPTER_MODEL_NR: + scsi->result[0] = '5'; + scsi->result[1] = '4'; + scsi->result[2] = '2'; + scsi->result[3] = 'B'; + scsi->result[4] = 'H'; + scsi->cmd_state = CMD_STATE_SEND_RESULT; + scsi->result_pos = 0; + scsi->result_len = MIN(scsi->params[0], 5); + for (; scsi->result_len < scsi->params[0]; scsi->result_len++) + scsi->result[scsi->result_len] = 0; + break; + + case COMMAND_BUSLOGIC_INQUIRY_SYNC_PERIOD: + for (c = 0; c < 8; c++) + scsi->result[c] = 0; + scsi->cmd_state = CMD_STATE_SEND_RESULT; + scsi->result_pos = 0; + scsi->result_len = MIN(scsi->params[0], 8); + for (; scsi->result_len < scsi->params[0]; scsi->result_len++) + scsi->result[scsi->result_len] = 0; + break; + + case COMMAND_BUSLOGIC_EXTENDED_SETUP_INFO: + pclog("Extended setup info %i\n", scsi->params[0]); + scsi->result[0] = 0x41; + scsi->result[1] = scsi->bios_addr >> 12; /*BIOS addr*/ + scsi->result[2] = 0x00; + scsi->result[3] = 0x20; + scsi->result[4] = 0x00; /*DS:E8 >> 3*/ + scsi->result[5] = 0x00; /*DS:DA - set by command 0x81?*/ + scsi->result[6] = 0x00; /*DS:DB*/ + scsi->result[7] = 0x00; /*DS:DC*/ + scsi->result[8] = 0x00; /*DS:DD*/ + scsi->result[9] = 0x33; /*FFFF:9*/ + scsi->result[10] = 0x33; /*FFFF:A*/ + scsi->result[11] = 0x31; /*FFFF:B*/ + scsi->cmd_state = CMD_STATE_SEND_RESULT; + scsi->result_pos = 0; + scsi->result_len = MIN(scsi->params[0], 12); + for (; scsi->result_len < scsi->params[0]; scsi->result_len++) + scsi->result[scsi->result_len] = 0; + break; + + case COMMAND_BUSLOGIC_STRICT_RR: + set_irq(scsi, ISR_HACC); + scsi->cmd_state = CMD_STATE_IDLE; + break; + + case COMMAND_BUSLOGIC_SET_CCB_FORMAT: + set_irq(scsi, ISR_HACC); + scsi->cmd_state = CMD_STATE_IDLE; + break; + + default: + fatal("Bad AHA154x command in progress %02x\n", scsi->command); + } + break; + + case CMD_STATE_GET_PARAMS: + if (scsi->status & STATUS_CDF) { + scsi->status &= ~STATUS_CDF; + + scsi->params[scsi->cur_param++] = scsi->cmd_data; + + if (scsi->cur_param == scsi->command_len) + scsi->cmd_state = CMD_STATE_CMD_IN_PROGRESS; + } + break; + + case CMD_STATE_SEND_RESULT: + if (!(scsi->status & STATUS_DF)) { + if (scsi->result_pos == scsi->result_len) { + set_irq(scsi, ISR_HACC); + scsi->cmd_state = CMD_STATE_IDLE; + pclog("Command complete\n"); + } else { + scsi->status |= STATUS_DF; + scsi->data_in = scsi->result[scsi->result_pos++]; + pclog("Return data %02x %i %i\n", scsi->data_in, scsi->result_pos - 1, scsi->result_len); + } + } + break; + + default: + fatal("Unknown state %d\n", scsi->cmd_state); + } } static void process_ccb(aha154x_t *scsi) { - int c; + int c; - switch (scsi->ccb_state) { - case CCB_STATE_IDLE: - if (!(scsi->status & STATUS_INIT) && scsi->mbo_req) { -// pclog("mbo_req %i\n", scsi->mbc); - for (c = 0; c < scsi->mbc; c++) { - uint32_t ccb; - uint8_t command; + switch (scsi->ccb_state) { + case CCB_STATE_IDLE: + if (!(scsi->status & STATUS_INIT) && scsi->mbo_req) { + // pclog("mbo_req %i\n", scsi->mbc); + for (c = 0; c < scsi->mbc; c++) { + uint32_t ccb; + uint8_t command; - if (scsi->mb_format == MB_FORMAT_4) { - uint32_t mbo = mem_readl_phys(scsi->mba + c * 4); - command = mbo & 0xff; - ccb = (mbo >> 24) | ((mbo >> 8) & 0xff00) | ((mbo << 8) & 0xff0000); -// pclog("MBO%02x = %08x\n", c, mbo); - } else { - ccb = mem_readl_phys(scsi->mba + c * 8); - command = mem_readb_phys(scsi->mba + c * 8 + 7); -// pclog("MBO%02x = %08x %02x\n", c, ccb, command); - } + if (scsi->mb_format == MB_FORMAT_4) { + uint32_t mbo = mem_readl_phys(scsi->mba + c * 4); + command = mbo & 0xff; + ccb = (mbo >> 24) | ((mbo >> 8) & 0xff00) | ((mbo << 8) & 0xff0000); + // pclog("MBO%02x = %08x\n", c, mbo); + } else { + ccb = mem_readl_phys(scsi->mba + c * 8); + command = mem_readb_phys(scsi->mba + c * 8 + 7); + // pclog("MBO%02x = %08x %02x\n", c, ccb, command); + } - if (command == COMMAND_START_CCB) { - pclog("Start CCB %08x %i\n", ccb, c); + if (command == COMMAND_START_CCB) { + pclog("Start CCB %08x %i\n", ccb, c); - scsi->current_mbo = c; - scsi->current_mbo_is_bios = 0; - scsi->ccb.addr = ccb; + scsi->current_mbo = c; + scsi->current_mbo_is_bios = 0; + scsi->ccb.addr = ccb; - process_cdb(scsi); + process_cdb(scsi); - scsi->mbo_req--; + scsi->mbo_req--; - //set_irq(scsi, ISR_HACC); - break; - } else if (command == COMMAND_ABORT_CCB) { -// fatal("Abort command\n"); - scsi->mbo_req--; + // set_irq(scsi, ISR_HACC); + break; + } else if (command == COMMAND_ABORT_CCB) { + // fatal("Abort command\n"); + scsi->mbo_req--; - if (scsi->mb_format == MB_FORMAT_4) { - mem_writeb_phys(scsi->mba + c * 8, 0); + if (scsi->mb_format == MB_FORMAT_4) { + mem_writeb_phys(scsi->mba + c * 8, 0); - mem_writeb_phys(scsi->mba_i + scsi->current_mbi * 4, MBI_CCB_ABORTED); - mem_writeb_phys(scsi->mba_i + scsi->current_mbi * 4 + 1, ccb >> 16); - mem_writeb_phys(scsi->mba_i + scsi->current_mbi * 4 + 2, ccb >> 8); - mem_writeb_phys(scsi->mba_i + scsi->current_mbi * 4 + 3, ccb & 0xff); - } else { - mem_writeb_phys(scsi->mba + c * 8 + 7, 0); + mem_writeb_phys(scsi->mba_i + scsi->current_mbi * 4, MBI_CCB_ABORTED); + mem_writeb_phys(scsi->mba_i + scsi->current_mbi * 4 + 1, ccb >> 16); + mem_writeb_phys(scsi->mba_i + scsi->current_mbi * 4 + 2, ccb >> 8); + mem_writeb_phys(scsi->mba_i + scsi->current_mbi * 4 + 3, ccb & 0xff); + } else { + mem_writeb_phys(scsi->mba + c * 8 + 7, 0); - mem_writel_phys(scsi->mba_i + scsi->current_mbi * 8, ccb); - mem_writel_phys(scsi->mba_i + scsi->current_mbi * 8 + 4, MBI_CCB_ABORTED); - } + mem_writel_phys(scsi->mba_i + scsi->current_mbi * 8, ccb); + mem_writel_phys(scsi->mba_i + scsi->current_mbi * 8 + 4, MBI_CCB_ABORTED); + } - scsi->current_mbi++; - if (scsi->current_mbi >= scsi->mbc) - scsi->current_mbi = 0; - set_irq(scsi, (scsi->mbo_irq_enable ? ISR_MBOA : 0) | ISR_MBIF | ISR_HACC); - break; - } - } - } - if (scsi->bios_mbo_inited && scsi->bios_mbo_req) { - for (c = 0; c < scsi->bios_mbc; c++) { - uint32_t ccb; - uint8_t command; + scsi->current_mbi++; + if (scsi->current_mbi >= scsi->mbc) + scsi->current_mbi = 0; + set_irq(scsi, (scsi->mbo_irq_enable ? ISR_MBOA : 0) | ISR_MBIF | ISR_HACC); + break; + } + } + } + if (scsi->bios_mbo_inited && scsi->bios_mbo_req) { + for (c = 0; c < scsi->bios_mbc; c++) { + uint32_t ccb; + uint8_t command; - uint32_t mbo = mem_readl_phys(scsi->bios_mba + c * 4); - command = mbo & 0xff; - ccb = (mbo >> 24) | ((mbo >> 8) & 0xff00) | ((mbo << 8) & 0xff0000); + uint32_t mbo = mem_readl_phys(scsi->bios_mba + c * 4); + command = mbo & 0xff; + ccb = (mbo >> 24) | ((mbo >> 8) & 0xff00) | ((mbo << 8) & 0xff0000); - if (command == COMMAND_START_CCB) { - pclog("Start BIOS CCB %08x %i\n", ccb, c); + if (command == COMMAND_START_CCB) { + pclog("Start BIOS CCB %08x %i\n", ccb, c); - scsi->current_mbo = c; - scsi->current_mbo_is_bios = 1; - scsi->ccb.addr = ccb; + scsi->current_mbo = c; + scsi->current_mbo_is_bios = 1; + scsi->ccb.addr = ccb; - process_cdb(scsi); + process_cdb(scsi); - scsi->bios_mbo_req--; - set_irq(scsi, ISR_HACC); - break; - } - } - } - break; + scsi->bios_mbo_req--; + set_irq(scsi, ISR_HACC); + break; + } + } + } + break; - case CCB_STATE_SEND_COMMAND: - if (scsi->scsi_state != SCSI_STATE_IDLE) - break; /*Wait until SCSI state machine is ready for new command*/ - for (c = 0; c < scsi->ccb.scsi_cmd_len; c++) { - scsi->cdb.data[c] = scsi->ccb.cdb[c]; -// pclog(" CDB[%02x]=%02x\n", c, scsi->cdb.data[c]); - } - scsi->cdb.len = scsi->ccb.scsi_cmd_len; - scsi->cdb.idx = 0; - if (scsi->ccb.opcode == CCB_INITIATOR_SCATTER_GATHER || scsi->ccb.opcode == CCB_INITIATOR_SCATTER_GATHER_RESIDUAL) { - scsi->cdb.data_seg_list_len = scsi->ccb.data_seg_list_len; - scsi->cdb.data_seg_list_pointer = scsi->ccb.data_seg_list_pointer; - scsi->cdb.data_seg_list_idx = 0; - scsi->cdb.scatter_gather = 1; - scsi->cdb.data_len = 0; - scsi->cdb.data_idx = 0; - } else { - scsi->cdb.data_pointer = scsi->ccb.data_pointer; - scsi->cdb.data_len = scsi->ccb.data_len; - scsi->cdb.scatter_gather = 0; - } - scsi->cdb.bytes_transferred = 0; - scsi->cdb.data_idx = 0; - scsi->scsi_state = SCSI_STATE_SELECT; - /*SCSI will now select the device and execute the command*/ - scsi->ccb_state = CCB_STATE_WAIT_COMMAND; - break; + case CCB_STATE_SEND_COMMAND: + if (scsi->scsi_state != SCSI_STATE_IDLE) + break; /*Wait until SCSI state machine is ready for new command*/ + for (c = 0; c < scsi->ccb.scsi_cmd_len; c++) { + scsi->cdb.data[c] = scsi->ccb.cdb[c]; + // pclog(" CDB[%02x]=%02x\n", c, scsi->cdb.data[c]); + } + scsi->cdb.len = scsi->ccb.scsi_cmd_len; + scsi->cdb.idx = 0; + if (scsi->ccb.opcode == CCB_INITIATOR_SCATTER_GATHER || + scsi->ccb.opcode == CCB_INITIATOR_SCATTER_GATHER_RESIDUAL) { + scsi->cdb.data_seg_list_len = scsi->ccb.data_seg_list_len; + scsi->cdb.data_seg_list_pointer = scsi->ccb.data_seg_list_pointer; + scsi->cdb.data_seg_list_idx = 0; + scsi->cdb.scatter_gather = 1; + scsi->cdb.data_len = 0; + scsi->cdb.data_idx = 0; + } else { + scsi->cdb.data_pointer = scsi->ccb.data_pointer; + scsi->cdb.data_len = scsi->ccb.data_len; + scsi->cdb.scatter_gather = 0; + } + scsi->cdb.bytes_transferred = 0; + scsi->cdb.data_idx = 0; + scsi->scsi_state = SCSI_STATE_SELECT; + /*SCSI will now select the device and execute the command*/ + scsi->ccb_state = CCB_STATE_WAIT_COMMAND; + break; - case CCB_STATE_WAIT_COMMAND: - if (scsi->scsi_state == SCSI_STATE_SELECT_FAILED) { - pclog("Command select has failed\n"); - if (scsi->ccb.from_mailbox) { - mem_writeb_phys(scsi->ccb.addr + 0xe, HOST_STATUS_SELECTION_TIME_OUT); + case CCB_STATE_WAIT_COMMAND: + if (scsi->scsi_state == SCSI_STATE_SELECT_FAILED) { + pclog("Command select has failed\n"); + if (scsi->ccb.from_mailbox) { + mem_writeb_phys(scsi->ccb.addr + 0xe, HOST_STATUS_SELECTION_TIME_OUT); - if (scsi->mb_format == MB_FORMAT_4) { - if (scsi->current_mbo_is_bios) { - mem_writeb_phys(scsi->bios_mba + scsi->current_mbo * 4, COMMAND_FREE_CCB); - mem_writeb_phys(scsi->ccb.addr + 0xd, MBI_CCB_COMPLETE_WITH_ERROR); - } else { - mem_writeb_phys(scsi->mba + scsi->current_mbo * 4, COMMAND_FREE_CCB); + if (scsi->mb_format == MB_FORMAT_4) { + if (scsi->current_mbo_is_bios) { + mem_writeb_phys(scsi->bios_mba + scsi->current_mbo * 4, COMMAND_FREE_CCB); + mem_writeb_phys(scsi->ccb.addr + 0xd, MBI_CCB_COMPLETE_WITH_ERROR); + } else { + mem_writeb_phys(scsi->mba + scsi->current_mbo * 4, COMMAND_FREE_CCB); - mem_writeb_phys(scsi->mba_i + scsi->current_mbi * 4, MBI_CCB_COMPLETE_WITH_ERROR); - mem_writeb_phys(scsi->mba_i + scsi->current_mbi * 4 + 1, scsi->ccb.addr >> 16); - mem_writeb_phys(scsi->mba_i + scsi->current_mbi * 4 + 2, scsi->ccb.addr >> 8); - mem_writeb_phys(scsi->mba_i + scsi->current_mbi * 4 + 3, scsi->ccb.addr & 0xff); - } - } else { - if (scsi->current_mbo_is_bios) - fatal("MBO_IS_BIOS MB_FORMAT_8\n"); - mem_writeb_phys(scsi->mba + scsi->current_mbo * 8 + 7, COMMAND_FREE_CCB); + mem_writeb_phys(scsi->mba_i + scsi->current_mbi * 4, MBI_CCB_COMPLETE_WITH_ERROR); + mem_writeb_phys(scsi->mba_i + scsi->current_mbi * 4 + 1, scsi->ccb.addr >> 16); + mem_writeb_phys(scsi->mba_i + scsi->current_mbi * 4 + 2, scsi->ccb.addr >> 8); + mem_writeb_phys(scsi->mba_i + scsi->current_mbi * 4 + 3, scsi->ccb.addr & 0xff); + } + } else { + if (scsi->current_mbo_is_bios) + fatal("MBO_IS_BIOS MB_FORMAT_8\n"); + mem_writeb_phys(scsi->mba + scsi->current_mbo * 8 + 7, COMMAND_FREE_CCB); - mem_writel_phys(scsi->mba_i + scsi->current_mbi * 8, scsi->ccb.addr); - mem_writel_phys(scsi->mba_i + scsi->current_mbi * 8 + 4, MBI_CCB_COMPLETE_WITH_ERROR << 24); - } + mem_writel_phys(scsi->mba_i + scsi->current_mbi * 8, scsi->ccb.addr); + mem_writel_phys(scsi->mba_i + scsi->current_mbi * 8 + 4, + MBI_CCB_COMPLETE_WITH_ERROR << 24); + } - if (!scsi->current_mbo_is_bios) { - scsi->current_mbi++; - if (scsi->current_mbi >= scsi->mbc) - scsi->current_mbi = 0; - set_irq(scsi, (scsi->mbo_irq_enable ? ISR_MBOA : 0) | ISR_MBIF); - } else if (scsi->mbo_irq_enable) - set_irq(scsi, ISR_MBOA); - } -// set_irq(scsi, ISR_HACC); - scsi->ccb_state = CCB_STATE_IDLE; - scsi->scsi_state = SCSI_STATE_IDLE; - break; - } - if (scsi->scsi_state != SCSI_STATE_IDLE) - break; /*Wait until SCSI state machine has completed command*/ - scsi->ccb.status = scsi->cdb.last_status; - scsi->ccb.bytes_transferred = scsi->cdb.bytes_transferred; - scsi->ccb_state = CCB_STATE_SEND_REQUEST_SENSE; - break; + if (!scsi->current_mbo_is_bios) { + scsi->current_mbi++; + if (scsi->current_mbi >= scsi->mbc) + scsi->current_mbi = 0; + set_irq(scsi, (scsi->mbo_irq_enable ? ISR_MBOA : 0) | ISR_MBIF); + } else if (scsi->mbo_irq_enable) + set_irq(scsi, ISR_MBOA); + } + // set_irq(scsi, ISR_HACC); + scsi->ccb_state = CCB_STATE_IDLE; + scsi->scsi_state = SCSI_STATE_IDLE; + break; + } + if (scsi->scsi_state != SCSI_STATE_IDLE) + break; /*Wait until SCSI state machine has completed command*/ + scsi->ccb.status = scsi->cdb.last_status; + scsi->ccb.bytes_transferred = scsi->cdb.bytes_transferred; + scsi->ccb_state = CCB_STATE_SEND_REQUEST_SENSE; + break; - case CCB_STATE_SEND_REQUEST_SENSE: - if (scsi->ccb.req_sense_len == CCB_SENSE_NONE) { -// pclog("No sense data\n"); - if (scsi->ccb.from_mailbox) { - uint32_t residue = scsi->ccb.total_data_len - scsi->ccb.bytes_transferred; + case CCB_STATE_SEND_REQUEST_SENSE: + if (scsi->ccb.req_sense_len == CCB_SENSE_NONE) { + // pclog("No sense data\n"); + if (scsi->ccb.from_mailbox) { + uint32_t residue = scsi->ccb.total_data_len - scsi->ccb.bytes_transferred; -// pclog("Residue=%08x %x %x %i MBI=%i\n", residue, scsi->ccb.total_data_len, scsi->ccb.bytes_transferred, scsi->ccb.residual, scsi->current_mbi); - mem_writeb_phys(scsi->ccb.addr + 0xe, HOST_STATUS_COMMAND_COMPLETE); - mem_writeb_phys(scsi->ccb.addr + 0xf, scsi->ccb.status); + // pclog("Residue=%08x %x %x %i MBI=%i\n", residue, + // scsi->ccb.total_data_len, scsi->ccb.bytes_transferred, + // scsi->ccb.residual, scsi->current_mbi); + mem_writeb_phys(scsi->ccb.addr + 0xe, HOST_STATUS_COMMAND_COMPLETE); + mem_writeb_phys(scsi->ccb.addr + 0xf, scsi->ccb.status); - if (scsi->mb_format == MB_FORMAT_4) { - if (scsi->ccb.residual) { - mem_writeb_phys(scsi->ccb.addr + 0x4, residue >> 16); - mem_writeb_phys(scsi->ccb.addr + 0x5, residue >> 8); - mem_writeb_phys(scsi->ccb.addr + 0x6, residue & 0xff); - } + if (scsi->mb_format == MB_FORMAT_4) { + if (scsi->ccb.residual) { + mem_writeb_phys(scsi->ccb.addr + 0x4, residue >> 16); + mem_writeb_phys(scsi->ccb.addr + 0x5, residue >> 8); + mem_writeb_phys(scsi->ccb.addr + 0x6, residue & 0xff); + } - if (scsi->current_mbo_is_bios) { - mem_writeb_phys(scsi->bios_mba + scsi->current_mbo * 4, COMMAND_FREE_CCB); + if (scsi->current_mbo_is_bios) { + mem_writeb_phys(scsi->bios_mba + scsi->current_mbo * 4, COMMAND_FREE_CCB); - if (scsi->ccb.status == STATUS_GOOD) - mem_writeb_phys(scsi->ccb.addr + 0xd, MBI_CCB_COMPLETE); - else - mem_writeb_phys(scsi->ccb.addr + 0xd, MBI_CCB_COMPLETE_WITH_ERROR); - } else { - mem_writeb_phys(scsi->mba + scsi->current_mbo * 4, COMMAND_FREE_CCB); + if (scsi->ccb.status == STATUS_GOOD) + mem_writeb_phys(scsi->ccb.addr + 0xd, MBI_CCB_COMPLETE); + else + mem_writeb_phys(scsi->ccb.addr + 0xd, MBI_CCB_COMPLETE_WITH_ERROR); + } else { + mem_writeb_phys(scsi->mba + scsi->current_mbo * 4, COMMAND_FREE_CCB); - if (scsi->ccb.status == STATUS_GOOD) - mem_writeb_phys(scsi->mba_i + scsi->current_mbi * 4, MBI_CCB_COMPLETE); - else - mem_writeb_phys(scsi->mba_i + scsi->current_mbi * 4, MBI_CCB_COMPLETE_WITH_ERROR); - mem_writeb_phys(scsi->mba_i + scsi->current_mbi * 4 + 1, scsi->ccb.addr >> 16); - mem_writeb_phys(scsi->mba_i + scsi->current_mbi * 4 + 2, scsi->ccb.addr >> 8); - mem_writeb_phys(scsi->mba_i + scsi->current_mbi * 4 + 3, scsi->ccb.addr & 0xff); - } - } else { - if (scsi->current_mbo_is_bios) - fatal("MBO_IS_BIOS MB_FORMAT_8\n"); + if (scsi->ccb.status == STATUS_GOOD) + mem_writeb_phys(scsi->mba_i + scsi->current_mbi * 4, MBI_CCB_COMPLETE); + else + mem_writeb_phys(scsi->mba_i + scsi->current_mbi * 4, + MBI_CCB_COMPLETE_WITH_ERROR); + mem_writeb_phys(scsi->mba_i + scsi->current_mbi * 4 + 1, scsi->ccb.addr >> 16); + mem_writeb_phys(scsi->mba_i + scsi->current_mbi * 4 + 2, scsi->ccb.addr >> 8); + mem_writeb_phys(scsi->mba_i + scsi->current_mbi * 4 + 3, scsi->ccb.addr & 0xff); + } + } else { + if (scsi->current_mbo_is_bios) + fatal("MBO_IS_BIOS MB_FORMAT_8\n"); - if (scsi->ccb.residual) - mem_writel_phys(scsi->ccb.addr + 0x4, residue); + if (scsi->ccb.residual) + mem_writel_phys(scsi->ccb.addr + 0x4, residue); - mem_writeb_phys(scsi->mba + scsi->current_mbo * 8 + 7, COMMAND_FREE_CCB); + mem_writeb_phys(scsi->mba + scsi->current_mbo * 8 + 7, COMMAND_FREE_CCB); - mem_writel_phys(scsi->mba_i + scsi->current_mbi * 8, scsi->ccb.addr); - if (scsi->ccb.status == STATUS_GOOD) - mem_writel_phys(scsi->mba_i + scsi->current_mbi * 8 + 4, MBI_CCB_COMPLETE << 24); - else - mem_writel_phys(scsi->mba_i + scsi->current_mbi * 8 + 4, (MBI_CCB_COMPLETE_WITH_ERROR << 24) | (scsi->ccb.status << 8)); - } + mem_writel_phys(scsi->mba_i + scsi->current_mbi * 8, scsi->ccb.addr); + if (scsi->ccb.status == STATUS_GOOD) + mem_writel_phys(scsi->mba_i + scsi->current_mbi * 8 + 4, MBI_CCB_COMPLETE << 24); + else + mem_writel_phys(scsi->mba_i + scsi->current_mbi * 8 + 4, + (MBI_CCB_COMPLETE_WITH_ERROR << 24) | (scsi->ccb.status << 8)); + } - if (!scsi->current_mbo_is_bios) { - scsi->current_mbi++; - if (scsi->current_mbi >= scsi->mbc) - scsi->current_mbi = 0; - set_irq(scsi, (scsi->mbo_irq_enable ? ISR_MBOA : 0) | ISR_MBIF); - } else if (scsi->mbo_irq_enable) - set_irq(scsi, ISR_MBOA); - } - scsi->ccb_state = CCB_STATE_IDLE; - break; - } - /*Build request sense command*/ - scsi->cdb.data[0] = SCSI_REQUEST_SENSE; - scsi->cdb.data[1] = scsi->ccb.lun << 5; - scsi->cdb.data[2] = 0x00; - scsi->cdb.data[3] = 0x00; - if (scsi->ccb.req_sense_len == CCB_SENSE_14) - scsi->cdb.data[4] = 14; - else - scsi->cdb.data[4] = scsi->ccb.req_sense_len; - scsi->cdb.data[5] = 14; - scsi->cdb.len = 6; - scsi->cdb.idx = 0; - if (scsi->ccb.from_mailbox) - scsi->cdb.data_pointer = -1; - else - scsi->cdb.data_pointer = scsi->ccb.addr + 0x12 + scsi->ccb.scsi_cmd_len; - scsi->cdb.data_idx = 0; - scsi->cdb.data_len = scsi->cdb.data[4]; - scsi->cdb.scatter_gather = 0; - scsi->scsi_state = SCSI_STATE_SELECT; - scsi->ccb_state = CCB_STATE_WAIT_REQUEST_SENSE; - break; + if (!scsi->current_mbo_is_bios) { + scsi->current_mbi++; + if (scsi->current_mbi >= scsi->mbc) + scsi->current_mbi = 0; + set_irq(scsi, (scsi->mbo_irq_enable ? ISR_MBOA : 0) | ISR_MBIF); + } else if (scsi->mbo_irq_enable) + set_irq(scsi, ISR_MBOA); + } + scsi->ccb_state = CCB_STATE_IDLE; + break; + } + /*Build request sense command*/ + scsi->cdb.data[0] = SCSI_REQUEST_SENSE; + scsi->cdb.data[1] = scsi->ccb.lun << 5; + scsi->cdb.data[2] = 0x00; + scsi->cdb.data[3] = 0x00; + if (scsi->ccb.req_sense_len == CCB_SENSE_14) + scsi->cdb.data[4] = 14; + else + scsi->cdb.data[4] = scsi->ccb.req_sense_len; + scsi->cdb.data[5] = 14; + scsi->cdb.len = 6; + scsi->cdb.idx = 0; + if (scsi->ccb.from_mailbox) + scsi->cdb.data_pointer = -1; + else + scsi->cdb.data_pointer = scsi->ccb.addr + 0x12 + scsi->ccb.scsi_cmd_len; + scsi->cdb.data_idx = 0; + scsi->cdb.data_len = scsi->cdb.data[4]; + scsi->cdb.scatter_gather = 0; + scsi->scsi_state = SCSI_STATE_SELECT; + scsi->ccb_state = CCB_STATE_WAIT_REQUEST_SENSE; + break; - case CCB_STATE_WAIT_REQUEST_SENSE: - if (scsi->scsi_state != SCSI_STATE_IDLE) - break; /*Wait until SCSI state machine has completed command*/ + case CCB_STATE_WAIT_REQUEST_SENSE: + if (scsi->scsi_state != SCSI_STATE_IDLE) + break; /*Wait until SCSI state machine has completed command*/ - if (scsi->ccb.from_mailbox) { - uint32_t residue = scsi->ccb.total_data_len - scsi->ccb.bytes_transferred; -// pclog("residue=%x %x %x\n", residue, scsi->ccb.total_data_len, scsi->ccb.bytes_transferred); - mem_writeb_phys(scsi->ccb.addr + 0xe, HOST_STATUS_COMMAND_COMPLETE); - mem_writeb_phys(scsi->ccb.addr + 0xf, scsi->ccb.status); + if (scsi->ccb.from_mailbox) { + uint32_t residue = scsi->ccb.total_data_len - scsi->ccb.bytes_transferred; + // pclog("residue=%x %x %x\n", residue, scsi->ccb.total_data_len, + // scsi->ccb.bytes_transferred); + mem_writeb_phys(scsi->ccb.addr + 0xe, HOST_STATUS_COMMAND_COMPLETE); + mem_writeb_phys(scsi->ccb.addr + 0xf, scsi->ccb.status); - if (scsi->mb_format == MB_FORMAT_4) { - if (scsi->ccb.residual) { - mem_writeb_phys(scsi->ccb.addr + 0x4, residue >> 16); - mem_writeb_phys(scsi->ccb.addr + 0x5, residue >> 8); - mem_writeb_phys(scsi->ccb.addr + 0x6, residue & 0xff); - } + if (scsi->mb_format == MB_FORMAT_4) { + if (scsi->ccb.residual) { + mem_writeb_phys(scsi->ccb.addr + 0x4, residue >> 16); + mem_writeb_phys(scsi->ccb.addr + 0x5, residue >> 8); + mem_writeb_phys(scsi->ccb.addr + 0x6, residue & 0xff); + } - if (scsi->current_mbo_is_bios) { - mem_writeb_phys(scsi->bios_mba + scsi->current_mbo * 4, COMMAND_FREE_CCB); + if (scsi->current_mbo_is_bios) { + mem_writeb_phys(scsi->bios_mba + scsi->current_mbo * 4, COMMAND_FREE_CCB); - if (scsi->ccb.status == STATUS_GOOD) - mem_writeb_phys(scsi->ccb.addr + 0xd, MBI_CCB_COMPLETE); - else - mem_writeb_phys(scsi->ccb.addr + 0xd, MBI_CCB_COMPLETE_WITH_ERROR); - } else { - mem_writeb_phys(scsi->mba + scsi->current_mbo * 4, COMMAND_FREE_CCB); + if (scsi->ccb.status == STATUS_GOOD) + mem_writeb_phys(scsi->ccb.addr + 0xd, MBI_CCB_COMPLETE); + else + mem_writeb_phys(scsi->ccb.addr + 0xd, MBI_CCB_COMPLETE_WITH_ERROR); + } else { + mem_writeb_phys(scsi->mba + scsi->current_mbo * 4, COMMAND_FREE_CCB); -// pclog("CCB status %02x\n", scsi->ccb.status); - if (scsi->ccb.status == STATUS_GOOD) - mem_writeb_phys(scsi->mba_i + scsi->current_mbi * 4, MBI_CCB_COMPLETE); - else - mem_writeb_phys(scsi->mba_i + scsi->current_mbi * 4, MBI_CCB_COMPLETE_WITH_ERROR); - mem_writeb_phys(scsi->mba_i + scsi->current_mbi * 4 + 1, scsi->ccb.addr >> 16); - mem_writeb_phys(scsi->mba_i + scsi->current_mbi * 4 + 2, scsi->ccb.addr >> 8); - mem_writeb_phys(scsi->mba_i + scsi->current_mbi * 4 + 3, scsi->ccb.addr & 0xff); - } - } else { - if (scsi->current_mbo_is_bios) - fatal("MBO_IS_BIOS MB_FORMAT_8\n"); + // pclog("CCB status %02x\n", scsi->ccb.status); + if (scsi->ccb.status == STATUS_GOOD) + mem_writeb_phys(scsi->mba_i + scsi->current_mbi * 4, MBI_CCB_COMPLETE); + else + mem_writeb_phys(scsi->mba_i + scsi->current_mbi * 4, MBI_CCB_COMPLETE_WITH_ERROR); + mem_writeb_phys(scsi->mba_i + scsi->current_mbi * 4 + 1, scsi->ccb.addr >> 16); + mem_writeb_phys(scsi->mba_i + scsi->current_mbi * 4 + 2, scsi->ccb.addr >> 8); + mem_writeb_phys(scsi->mba_i + scsi->current_mbi * 4 + 3, scsi->ccb.addr & 0xff); + } + } else { + if (scsi->current_mbo_is_bios) + fatal("MBO_IS_BIOS MB_FORMAT_8\n"); - if (scsi->ccb.residual) - mem_writel_phys(scsi->ccb.addr + 0x4, residue); + if (scsi->ccb.residual) + mem_writel_phys(scsi->ccb.addr + 0x4, residue); - mem_writeb_phys(scsi->mba + scsi->current_mbo * 8 + 7, COMMAND_FREE_CCB); + mem_writeb_phys(scsi->mba + scsi->current_mbo * 8 + 7, COMMAND_FREE_CCB); - mem_writel_phys(scsi->mba_i + scsi->current_mbi * 8, scsi->ccb.addr); - if (scsi->ccb.status == STATUS_GOOD) - mem_writel_phys(scsi->mba_i + scsi->current_mbi * 8 + 4, MBI_CCB_COMPLETE << 24); - else - mem_writel_phys(scsi->mba_i + scsi->current_mbi * 8 + 4, (MBI_CCB_COMPLETE_WITH_ERROR << 24) | (scsi->ccb.status << 8)); - } + mem_writel_phys(scsi->mba_i + scsi->current_mbi * 8, scsi->ccb.addr); + if (scsi->ccb.status == STATUS_GOOD) + mem_writel_phys(scsi->mba_i + scsi->current_mbi * 8 + 4, MBI_CCB_COMPLETE << 24); + else + mem_writel_phys(scsi->mba_i + scsi->current_mbi * 8 + 4, + (MBI_CCB_COMPLETE_WITH_ERROR << 24) | (scsi->ccb.status << 8)); + } - if (!scsi->current_mbo_is_bios) { - scsi->current_mbi++; - if (scsi->current_mbi >= scsi->mbc) - scsi->current_mbi = 0; - set_irq(scsi, (scsi->mbo_irq_enable ? ISR_MBOA : 0) | ISR_MBIF); - } else if (scsi->mbo_irq_enable) - set_irq(scsi, ISR_MBOA); - } -// pclog("CCB_STATE_WAIT_REQUEST_SENSE over %i\n", scsi->ccb.from_mailbox); - scsi->ccb_state = CCB_STATE_IDLE; - break; + if (!scsi->current_mbo_is_bios) { + scsi->current_mbi++; + if (scsi->current_mbi >= scsi->mbc) + scsi->current_mbi = 0; + set_irq(scsi, (scsi->mbo_irq_enable ? ISR_MBOA : 0) | ISR_MBIF); + } else if (scsi->mbo_irq_enable) + set_irq(scsi, ISR_MBOA); + } + // pclog("CCB_STATE_WAIT_REQUEST_SENSE over %i\n", scsi->ccb.from_mailbox); + scsi->ccb_state = CCB_STATE_IDLE; + break; - default:fatal("Unknown CCB_state %d\n", scsi->ccb_state); - } + default: + fatal("Unknown CCB_state %d\n", scsi->ccb_state); + } } static void process_scsi(aha154x_t *scsi) { - int c; - int bytes_transferred = 0; + int c; + int bytes_transferred = 0; - switch (scsi->scsi_state) { - case SCSI_STATE_IDLE:break; + switch (scsi->scsi_state) { + case SCSI_STATE_IDLE: + break; - case SCSI_STATE_SELECT:scsi->cdb.last_status = 0; -// pclog("Select target ID %i\n", scsi->ccb.target_id); - scsi_bus_update(&scsi->bus, BUS_SEL | BUS_SETDATA(1 << scsi->ccb.target_id)); - if (!(scsi_bus_read(&scsi->bus) & BUS_BSY) || scsi->ccb.target_id > 6) { - pclog("STATE_SCSI_SELECT failed to select target %i\n", scsi->ccb.target_id); - scsi->scsi_state = SCSI_STATE_SELECT_FAILED; - break; - } + case SCSI_STATE_SELECT: + scsi->cdb.last_status = 0; + // pclog("Select target ID %i\n", scsi->ccb.target_id); + scsi_bus_update(&scsi->bus, BUS_SEL | BUS_SETDATA(1 << scsi->ccb.target_id)); + if (!(scsi_bus_read(&scsi->bus) & BUS_BSY) || scsi->ccb.target_id > 6) { + pclog("STATE_SCSI_SELECT failed to select target %i\n", scsi->ccb.target_id); + scsi->scsi_state = SCSI_STATE_SELECT_FAILED; + break; + } - scsi_bus_update(&scsi->bus, 0); - if (!(scsi_bus_read(&scsi->bus) & BUS_BSY)) { - pclog("STATE_SCSI_SELECT failed to select target %i 2\n", scsi->ccb.target_id); - scsi->scsi_state = SCSI_STATE_SELECT_FAILED; - break; - } + scsi_bus_update(&scsi->bus, 0); + if (!(scsi_bus_read(&scsi->bus) & BUS_BSY)) { + pclog("STATE_SCSI_SELECT failed to select target %i 2\n", scsi->ccb.target_id); + scsi->scsi_state = SCSI_STATE_SELECT_FAILED; + break; + } - /*Device should now be selected*/ - if (!wait_for_bus(&scsi->bus, BUS_CD, 1)) { - pclog("Device failed to request command\n"); - scsi->scsi_state = SCSI_STATE_SELECT_FAILED; - break; - } + /*Device should now be selected*/ + if (!wait_for_bus(&scsi->bus, BUS_CD, 1)) { + pclog("Device failed to request command\n"); + scsi->scsi_state = SCSI_STATE_SELECT_FAILED; + break; + } - scsi->scsi_state = SCSI_STATE_SEND_COMMAND; - break; + scsi->scsi_state = SCSI_STATE_SEND_COMMAND; + break; - case SCSI_STATE_SELECT_FAILED:break; + case SCSI_STATE_SELECT_FAILED: + break; - case SCSI_STATE_SEND_COMMAND: - while (scsi->cdb.idx < scsi->cdb.len && bytes_transferred < MAX_BYTES_TRANSFERRED_PER_POLL) { - int bus_out; + case SCSI_STATE_SEND_COMMAND: + while (scsi->cdb.idx < scsi->cdb.len && bytes_transferred < MAX_BYTES_TRANSFERRED_PER_POLL) { + int bus_out; - for (c = 0; c < 20; c++) { - int bus_state = scsi_bus_read(&scsi->bus); + for (c = 0; c < 20; c++) { + int bus_state = scsi_bus_read(&scsi->bus); - if (!(bus_state & BUS_BSY)) - fatal("SEND_COMMAND - dropped BSY\n"); - if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) != BUS_CD) - fatal("SEND_COMMAND - bus phase incorrect\n"); - if (bus_state & BUS_REQ) - break; - } - if (c == 20) { - pclog("SEND_COMMAND timed out\n"); - break; - } + if (!(bus_state & BUS_BSY)) + fatal("SEND_COMMAND - dropped BSY\n"); + if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) != BUS_CD) + fatal("SEND_COMMAND - bus phase incorrect\n"); + if (bus_state & BUS_REQ) + break; + } + if (c == 20) { + pclog("SEND_COMMAND timed out\n"); + break; + } - bus_out = BUS_SETDATA(scsi->cdb.data[scsi->cdb.idx]); -// pclog(" Command send %02x %i\n", scsi->cdb.data[scsi->cdb.idx], scsi->cdb.len); -// if (!scsi->cdb.idx && scsi->cdb.data[scsi->cdb.idx] == 0x25 && scsi->current_mbo == 1) -// output = 3; - scsi->cdb.idx++; - bytes_transferred++; + bus_out = BUS_SETDATA(scsi->cdb.data[scsi->cdb.idx]); + // pclog(" Command send %02x %i\n", scsi->cdb.data[scsi->cdb.idx], scsi->cdb.len); + // if (!scsi->cdb.idx && scsi->cdb.data[scsi->cdb.idx] == 0x25 && scsi->current_mbo + // == 1) + // output = 3; + scsi->cdb.idx++; + bytes_transferred++; - scsi_bus_update(&scsi->bus, bus_out | BUS_ACK); - scsi_bus_update(&scsi->bus, bus_out & ~BUS_ACK); - } - if (scsi->cdb.idx == scsi->cdb.len) - scsi->scsi_state = SCSI_STATE_NEXT_PHASE; - break; + scsi_bus_update(&scsi->bus, bus_out | BUS_ACK); + scsi_bus_update(&scsi->bus, bus_out & ~BUS_ACK); + } + if (scsi->cdb.idx == scsi->cdb.len) + scsi->scsi_state = SCSI_STATE_NEXT_PHASE; + break; - case SCSI_STATE_NEXT_PHASE: - /*Wait for SCSI command to move to next phase*/ - for (c = 0; c < 20; c++) { - int bus_state = scsi_bus_read(&scsi->bus); + case SCSI_STATE_NEXT_PHASE: + /*Wait for SCSI command to move to next phase*/ + for (c = 0; c < 20; c++) { + int bus_state = scsi_bus_read(&scsi->bus); - if (!(bus_state & BUS_BSY)) - fatal("NEXT_PHASE - dropped BSY waiting\n"); + if (!(bus_state & BUS_BSY)) + fatal("NEXT_PHASE - dropped BSY waiting\n"); - if (bus_state & BUS_REQ) { - int bus_out; -// pclog("SCSI next phase - %x\n", bus_state); - switch (bus_state & (BUS_IO | BUS_CD | BUS_MSG)) { - case 0: -// pclog("Move to write data\n"); - scsi->scsi_state = SCSI_STATE_WRITE_DATA; - break; + if (bus_state & BUS_REQ) { + int bus_out; + // pclog("SCSI next phase - %x\n", bus_state); + switch (bus_state & (BUS_IO | BUS_CD | BUS_MSG)) { + case 0: + // pclog("Move to write data\n"); + scsi->scsi_state = SCSI_STATE_WRITE_DATA; + break; - case BUS_IO: -// pclog("Move to read data\n"); - scsi->scsi_state = SCSI_STATE_READ_DATA; - break; + case BUS_IO: + // pclog("Move to read data\n"); + scsi->scsi_state = SCSI_STATE_READ_DATA; + break; - case (BUS_CD | BUS_IO): -// pclog("Move to read status\n"); - scsi->scsi_state = SCSI_STATE_READ_STATUS; - break; + case (BUS_CD | BUS_IO): + // pclog("Move to read status\n"); + scsi->scsi_state = SCSI_STATE_READ_STATUS; + break; - case (BUS_CD | BUS_IO | BUS_MSG): -// pclog("Move to read message\n"); - scsi->scsi_state = SCSI_STATE_READ_MESSAGE; - break; + case (BUS_CD | BUS_IO | BUS_MSG): + // pclog("Move to read message\n"); + scsi->scsi_state = SCSI_STATE_READ_MESSAGE; + break; - case BUS_CD:bus_out = BUS_SETDATA(0); + case BUS_CD: + bus_out = BUS_SETDATA(0); - scsi_bus_update(&scsi->bus, bus_out | BUS_ACK); - scsi_bus_update(&scsi->bus, bus_out & ~BUS_ACK); - break; + scsi_bus_update(&scsi->bus, bus_out | BUS_ACK); + scsi_bus_update(&scsi->bus, bus_out & ~BUS_ACK); + break; - default:fatal(" Bad new phase %x\n", bus_state); - } - break; - } - } - break; + default: + fatal(" Bad new phase %x\n", bus_state); + } + break; + } + } + break; - case SCSI_STATE_END_PHASE: - /*Wait for SCSI command to move to next phase*/ - for (c = 0; c < 20; c++) { - int bus_state = scsi_bus_read(&scsi->bus); + case SCSI_STATE_END_PHASE: + /*Wait for SCSI command to move to next phase*/ + for (c = 0; c < 20; c++) { + int bus_state = scsi_bus_read(&scsi->bus); - if (!(bus_state & BUS_BSY)) { - pclog("END_PHASE - dropped BSY waiting\n"); -// if (scsi->ccb.req_sense_len == CCB_SENSE_NONE) -// fatal("No sense data\n"); - scsi->scsi_state = SCSI_STATE_IDLE; - break; - } + if (!(bus_state & BUS_BSY)) { + pclog("END_PHASE - dropped BSY waiting\n"); + // if (scsi->ccb.req_sense_len == CCB_SENSE_NONE) + // fatal("No sense data\n"); + scsi->scsi_state = SCSI_STATE_IDLE; + break; + } - if (bus_state & BUS_REQ) - fatal("END_PHASE - unexpected REQ\n"); - } - break; + if (bus_state & BUS_REQ) + fatal("END_PHASE - unexpected REQ\n"); + } + break; - case SCSI_STATE_READ_DATA: -//pclog("READ_DATA %i,%i %i\n", scsi->cdb.data_idx,scsi->cdb.data_len, scsi->cdb.scatter_gather); - while (scsi->cdb.data_idx < scsi->cdb.data_len && scsi->scsi_state == SCSI_STATE_READ_DATA && bytes_transferred < MAX_BYTES_TRANSFERRED_PER_POLL) { - int d; + case SCSI_STATE_READ_DATA: + // pclog("READ_DATA %i,%i %i\n", scsi->cdb.data_idx,scsi->cdb.data_len, scsi->cdb.scatter_gather); + while (scsi->cdb.data_idx < scsi->cdb.data_len && scsi->scsi_state == SCSI_STATE_READ_DATA && + bytes_transferred < MAX_BYTES_TRANSFERRED_PER_POLL) { + int d; - for (d = 0; d < 20; d++) { - int bus_state = scsi_bus_read(&scsi->bus); + for (d = 0; d < 20; d++) { + int bus_state = scsi_bus_read(&scsi->bus); - if (!(bus_state & BUS_BSY)) - fatal("READ_DATA - dropped BSY waiting\n"); + if (!(bus_state & BUS_BSY)) + fatal("READ_DATA - dropped BSY waiting\n"); - if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) != BUS_IO) { - pclog("READ_DATA - changed phase\n"); - scsi->scsi_state = SCSI_STATE_NEXT_PHASE; - break; - } + if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) != BUS_IO) { + pclog("READ_DATA - changed phase\n"); + scsi->scsi_state = SCSI_STATE_NEXT_PHASE; + break; + } - if (bus_state & BUS_REQ) { - uint8_t data = BUS_GETDATA(bus_state); - int bus_out = 0; + if (bus_state & BUS_REQ) { + uint8_t data = BUS_GETDATA(bus_state); + int bus_out = 0; - if (scsi->cdb.data_pointer == -1) - scsi->int_buffer[scsi->cdb.data_idx] = data; - else - mem_writeb_phys(scsi->cdb.data_pointer + scsi->cdb.data_idx, data); - scsi->cdb.data_idx++; - scsi->cdb.bytes_transferred++; + if (scsi->cdb.data_pointer == -1) + scsi->int_buffer[scsi->cdb.data_idx] = data; + else + mem_writeb_phys(scsi->cdb.data_pointer + scsi->cdb.data_idx, data); + scsi->cdb.data_idx++; + scsi->cdb.bytes_transferred++; -// pclog("Read data %02x %i %06x\n", data, scsi->cdb.data_idx, scsi->cdb.data_pointer + scsi->cdb.data_idx); - scsi_bus_update(&scsi->bus, bus_out | BUS_ACK); - scsi_bus_update(&scsi->bus, bus_out & ~BUS_ACK); - break; - } - } + // pclog("Read data %02x %i %06x\n", data, + // scsi->cdb.data_idx, scsi->cdb.data_pointer + + // scsi->cdb.data_idx); + scsi_bus_update(&scsi->bus, bus_out | BUS_ACK); + scsi_bus_update(&scsi->bus, bus_out & ~BUS_ACK); + break; + } + } - bytes_transferred++; - } - if (scsi->cdb.data_idx == scsi->cdb.data_len) { - if (scsi->cdb.scatter_gather) { - if (scsi->cdb.data_seg_list_idx >= scsi->cdb.data_seg_list_len) - scsi->scsi_state = SCSI_STATE_NEXT_PHASE; - else { - if (scsi->mb_format == MB_FORMAT_4) { - scsi->cdb.data_len = mem_readb_phys(scsi->cdb.data_seg_list_pointer + scsi->cdb.data_seg_list_idx + 2) | - (mem_readb_phys(scsi->cdb.data_seg_list_pointer + scsi->cdb.data_seg_list_idx + 1) << 8) | - (mem_readb_phys(scsi->cdb.data_seg_list_pointer + scsi->cdb.data_seg_list_idx) << 16); - scsi->cdb.data_pointer = mem_readb_phys(scsi->cdb.data_seg_list_pointer + scsi->cdb.data_seg_list_idx + 5) | - (mem_readb_phys(scsi->cdb.data_seg_list_pointer + scsi->cdb.data_seg_list_idx + 4) << 8) | - (mem_readb_phys(scsi->cdb.data_seg_list_pointer + scsi->cdb.data_seg_list_idx + 3) << 16); - scsi->cdb.data_idx = 0; - scsi->cdb.data_seg_list_idx += 6; - } else { - scsi->cdb.data_len = mem_readl_phys(scsi->cdb.data_seg_list_pointer + scsi->cdb.data_seg_list_idx); - scsi->cdb.data_pointer = mem_readl_phys(scsi->cdb.data_seg_list_pointer + scsi->cdb.data_seg_list_idx + 4); - scsi->cdb.data_idx = 0; - scsi->cdb.data_seg_list_idx += 8; -// output = 3; - } - pclog("Got scatter gather %08x %08x\n", scsi->cdb.data_pointer, scsi->cdb.data_len); - } - } else - scsi->scsi_state = SCSI_STATE_NEXT_PHASE; - } - break; + bytes_transferred++; + } + if (scsi->cdb.data_idx == scsi->cdb.data_len) { + if (scsi->cdb.scatter_gather) { + if (scsi->cdb.data_seg_list_idx >= scsi->cdb.data_seg_list_len) + scsi->scsi_state = SCSI_STATE_NEXT_PHASE; + else { + if (scsi->mb_format == MB_FORMAT_4) { + scsi->cdb.data_len = mem_readb_phys(scsi->cdb.data_seg_list_pointer + + scsi->cdb.data_seg_list_idx + 2) | + (mem_readb_phys(scsi->cdb.data_seg_list_pointer + + scsi->cdb.data_seg_list_idx + 1) + << 8) | + (mem_readb_phys(scsi->cdb.data_seg_list_pointer + + scsi->cdb.data_seg_list_idx) + << 16); + scsi->cdb.data_pointer = mem_readb_phys(scsi->cdb.data_seg_list_pointer + + scsi->cdb.data_seg_list_idx + 5) | + (mem_readb_phys(scsi->cdb.data_seg_list_pointer + + scsi->cdb.data_seg_list_idx + 4) + << 8) | + (mem_readb_phys(scsi->cdb.data_seg_list_pointer + + scsi->cdb.data_seg_list_idx + 3) + << 16); + scsi->cdb.data_idx = 0; + scsi->cdb.data_seg_list_idx += 6; + } else { + scsi->cdb.data_len = mem_readl_phys(scsi->cdb.data_seg_list_pointer + + scsi->cdb.data_seg_list_idx); + scsi->cdb.data_pointer = mem_readl_phys(scsi->cdb.data_seg_list_pointer + + scsi->cdb.data_seg_list_idx + 4); + scsi->cdb.data_idx = 0; + scsi->cdb.data_seg_list_idx += 8; + // output = 3; + } + pclog("Got scatter gather %08x %08x\n", scsi->cdb.data_pointer, scsi->cdb.data_len); + } + } else + scsi->scsi_state = SCSI_STATE_NEXT_PHASE; + } + break; - case SCSI_STATE_WRITE_DATA: - while (scsi->cdb.data_idx < scsi->cdb.data_len && bytes_transferred < MAX_BYTES_TRANSFERRED_PER_POLL) { - int d; + case SCSI_STATE_WRITE_DATA: + while (scsi->cdb.data_idx < scsi->cdb.data_len && bytes_transferred < MAX_BYTES_TRANSFERRED_PER_POLL) { + int d; - for (d = 0; d < 20; d++) { - int bus_state = scsi_bus_read(&scsi->bus); + for (d = 0; d < 20; d++) { + int bus_state = scsi_bus_read(&scsi->bus); - if (!(bus_state & BUS_BSY)) - fatal("WRITE_DATA - dropped BSY waiting\n"); + if (!(bus_state & BUS_BSY)) + fatal("WRITE_DATA - dropped BSY waiting\n"); - if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) != 0) { - pclog("WRITE_DATA - changed phase\n"); - scsi->scsi_state = SCSI_STATE_NEXT_PHASE; - break; - } + if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) != 0) { + pclog("WRITE_DATA - changed phase\n"); + scsi->scsi_state = SCSI_STATE_NEXT_PHASE; + break; + } - if (bus_state & BUS_REQ) { - uint8_t data;// = BUS_GETDATA(bus_state); - int bus_out; + if (bus_state & BUS_REQ) { + uint8_t data; // = BUS_GETDATA(bus_state); + int bus_out; - if (scsi->cdb.data_pointer == -1) - data = scsi->int_buffer[scsi->cdb.data_idx]; - else - data = mem_readb_phys(scsi->cdb.data_pointer + scsi->cdb.data_idx); - scsi->cdb.data_idx++; - scsi->cdb.bytes_transferred++; + if (scsi->cdb.data_pointer == -1) + data = scsi->int_buffer[scsi->cdb.data_idx]; + else + data = mem_readb_phys(scsi->cdb.data_pointer + scsi->cdb.data_idx); + scsi->cdb.data_idx++; + scsi->cdb.bytes_transferred++; -// pclog("Write data %02x %i\n", data, scsi->cdb.data_idx); - bus_out = BUS_SETDATA(data); - scsi_bus_update(&scsi->bus, bus_out | BUS_ACK); - scsi_bus_update(&scsi->bus, bus_out & ~BUS_ACK); - break; - } - } + // pclog("Write data %02x %i\n", data, + // scsi->cdb.data_idx); + bus_out = BUS_SETDATA(data); + scsi_bus_update(&scsi->bus, bus_out | BUS_ACK); + scsi_bus_update(&scsi->bus, bus_out & ~BUS_ACK); + break; + } + } - bytes_transferred++; - } - if (scsi->cdb.data_idx == scsi->cdb.data_len) { - if (scsi->cdb.scatter_gather) { - if (scsi->cdb.data_seg_list_idx >= scsi->cdb.data_seg_list_len) - scsi->scsi_state = SCSI_STATE_NEXT_PHASE; - else { - if (scsi->mb_format == MB_FORMAT_4) { - scsi->cdb.data_len = mem_readb_phys(scsi->cdb.data_seg_list_pointer + scsi->cdb.data_seg_list_idx + 2) | - (mem_readb_phys(scsi->cdb.data_seg_list_pointer + scsi->cdb.data_seg_list_idx + 1) << 8) | - (mem_readb_phys(scsi->cdb.data_seg_list_pointer + scsi->cdb.data_seg_list_idx) << 16); - scsi->cdb.data_pointer = mem_readb_phys(scsi->cdb.data_seg_list_pointer + scsi->cdb.data_seg_list_idx + 5) | - (mem_readb_phys(scsi->cdb.data_seg_list_pointer + scsi->cdb.data_seg_list_idx + 4) << 8) | - (mem_readb_phys(scsi->cdb.data_seg_list_pointer + scsi->cdb.data_seg_list_idx + 3) << 16); - scsi->cdb.data_idx = 0; - scsi->cdb.data_seg_list_idx += 6; - } else { - scsi->cdb.data_len = mem_readl_phys(scsi->cdb.data_seg_list_pointer + scsi->cdb.data_seg_list_idx); - scsi->cdb.data_pointer = mem_readl_phys(scsi->cdb.data_seg_list_pointer + scsi->cdb.data_seg_list_idx + 4); - scsi->cdb.data_idx = 0; - scsi->cdb.data_seg_list_idx += 8; - } - pclog("Got scatter gather %08x %08x\n", scsi->cdb.data_pointer, scsi->cdb.data_len); - } - } else - scsi->scsi_state = SCSI_STATE_NEXT_PHASE; - } - break; + bytes_transferred++; + } + if (scsi->cdb.data_idx == scsi->cdb.data_len) { + if (scsi->cdb.scatter_gather) { + if (scsi->cdb.data_seg_list_idx >= scsi->cdb.data_seg_list_len) + scsi->scsi_state = SCSI_STATE_NEXT_PHASE; + else { + if (scsi->mb_format == MB_FORMAT_4) { + scsi->cdb.data_len = mem_readb_phys(scsi->cdb.data_seg_list_pointer + + scsi->cdb.data_seg_list_idx + 2) | + (mem_readb_phys(scsi->cdb.data_seg_list_pointer + + scsi->cdb.data_seg_list_idx + 1) + << 8) | + (mem_readb_phys(scsi->cdb.data_seg_list_pointer + + scsi->cdb.data_seg_list_idx) + << 16); + scsi->cdb.data_pointer = mem_readb_phys(scsi->cdb.data_seg_list_pointer + + scsi->cdb.data_seg_list_idx + 5) | + (mem_readb_phys(scsi->cdb.data_seg_list_pointer + + scsi->cdb.data_seg_list_idx + 4) + << 8) | + (mem_readb_phys(scsi->cdb.data_seg_list_pointer + + scsi->cdb.data_seg_list_idx + 3) + << 16); + scsi->cdb.data_idx = 0; + scsi->cdb.data_seg_list_idx += 6; + } else { + scsi->cdb.data_len = mem_readl_phys(scsi->cdb.data_seg_list_pointer + + scsi->cdb.data_seg_list_idx); + scsi->cdb.data_pointer = mem_readl_phys(scsi->cdb.data_seg_list_pointer + + scsi->cdb.data_seg_list_idx + 4); + scsi->cdb.data_idx = 0; + scsi->cdb.data_seg_list_idx += 8; + } + pclog("Got scatter gather %08x %08x\n", scsi->cdb.data_pointer, scsi->cdb.data_len); + } + } else + scsi->scsi_state = SCSI_STATE_NEXT_PHASE; + } + break; - case SCSI_STATE_READ_STATUS: - for (c = 0; c < 20; c++) { - int bus_state = scsi_bus_read(&scsi->bus); + case SCSI_STATE_READ_STATUS: + for (c = 0; c < 20; c++) { + int bus_state = scsi_bus_read(&scsi->bus); - if (!(bus_state & BUS_BSY)) - fatal("READ_STATUS - dropped BSY waiting\n"); + if (!(bus_state & BUS_BSY)) + fatal("READ_STATUS - dropped BSY waiting\n"); - if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) != (BUS_CD | BUS_IO)) { - pclog("READ_STATUS - changed phase\n"); - scsi->scsi_state = SCSI_STATE_NEXT_PHASE; - break; - } + if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) != (BUS_CD | BUS_IO)) { + pclog("READ_STATUS - changed phase\n"); + scsi->scsi_state = SCSI_STATE_NEXT_PHASE; + break; + } - if (bus_state & BUS_REQ) { - uint8_t status = BUS_GETDATA(bus_state); - int bus_out = 0; + if (bus_state & BUS_REQ) { + uint8_t status = BUS_GETDATA(bus_state); + int bus_out = 0; -// pclog("Read status %02x\n", status); - if (scsi->ccb.from_mailbox) - mem_writeb_phys(scsi->ccb.addr + 0xf, status); - scsi->cdb.last_status = status; + // pclog("Read status %02x\n", status); + if (scsi->ccb.from_mailbox) + mem_writeb_phys(scsi->ccb.addr + 0xf, status); + scsi->cdb.last_status = status; - scsi_bus_update(&scsi->bus, bus_out | BUS_ACK); - scsi_bus_update(&scsi->bus, bus_out & ~BUS_ACK); + scsi_bus_update(&scsi->bus, bus_out | BUS_ACK); + scsi_bus_update(&scsi->bus, bus_out & ~BUS_ACK); - scsi->scsi_state = SCSI_STATE_NEXT_PHASE; - break; - } - } - break; + scsi->scsi_state = SCSI_STATE_NEXT_PHASE; + break; + } + } + break; - case SCSI_STATE_READ_MESSAGE: - for (c = 0; c < 20; c++) { - int bus_state = scsi_bus_read(&scsi->bus); + case SCSI_STATE_READ_MESSAGE: + for (c = 0; c < 20; c++) { + int bus_state = scsi_bus_read(&scsi->bus); - if (!(bus_state & BUS_BSY)) - fatal("READ_MESSAGE - dropped BSY waiting\n"); + if (!(bus_state & BUS_BSY)) + fatal("READ_MESSAGE - dropped BSY waiting\n"); - if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) != (BUS_CD | BUS_IO | BUS_MSG)) { - pclog("READ_MESSAGE - changed phase\n"); - scsi->scsi_state = SCSI_STATE_NEXT_PHASE; - break; - } + if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) != (BUS_CD | BUS_IO | BUS_MSG)) { + pclog("READ_MESSAGE - changed phase\n"); + scsi->scsi_state = SCSI_STATE_NEXT_PHASE; + break; + } - if (bus_state & BUS_REQ) { - uint8_t msg = BUS_GETDATA(bus_state); - int bus_out = 0; + if (bus_state & BUS_REQ) { + uint8_t msg = BUS_GETDATA(bus_state); + int bus_out = 0; -// pclog("Read message %02x\n", msg); - scsi_bus_update(&scsi->bus, bus_out | BUS_ACK); - scsi_bus_update(&scsi->bus, bus_out & ~BUS_ACK); + // pclog("Read message %02x\n", msg); + scsi_bus_update(&scsi->bus, bus_out | BUS_ACK); + scsi_bus_update(&scsi->bus, bus_out & ~BUS_ACK); - switch (msg) { - case MSG_COMMAND_COMPLETE:scsi->scsi_state = SCSI_STATE_END_PHASE; - break; + switch (msg) { + case MSG_COMMAND_COMPLETE: + scsi->scsi_state = SCSI_STATE_END_PHASE; + break; - default:fatal("READ_MESSAGE - unknown message %02x\n", msg); - } - break; - } - } - break; + default: + fatal("READ_MESSAGE - unknown message %02x\n", msg); + } + break; + } + } + break; - default:fatal("Unknown SCSI_state %d\n", scsi->scsi_state); - } + default: + fatal("Unknown SCSI_state %d\n", scsi->scsi_state); + } } static void aha154x_callback(void *p) { - aha154x_t *scsi = (aha154x_t *)p; + aha154x_t *scsi = (aha154x_t *)p; - timer_advance_u64(&scsi->timer, TIMER_USEC * POLL_TIME_US); + timer_advance_u64(&scsi->timer, TIMER_USEC * POLL_TIME_US); -// pclog("poll %i\n", scsi->cmd_state); - process_cmd(scsi); - process_ccb(scsi); - process_scsi(scsi); + // pclog("poll %i\n", scsi->cmd_state); + process_cmd(scsi); + process_ccb(scsi); + process_scsi(scsi); } static uint8_t aha1542c_read(uint32_t addr, void *p) { - aha154x_t *scsi = (aha154x_t *)p; - uint8_t temp = 0xff; + aha154x_t *scsi = (aha154x_t *)p; + uint8_t temp = 0xff; - addr &= 0x3fff; + addr &= 0x3fff; - if (addr == 0x3f7e) /*DIP switches*/ - temp = scsi->dipsw; - else if (addr == 0x3f7f) /*Negation of DIP switches, to satisfy BIOS checksum!*/ - temp = (scsi->dipsw ^ 0xff) + 1; - else if (addr >= 0x3f80 && (scsi->shadow & 2)) - temp = scsi->shadow_ram[addr]; - else - temp = scsi->bios_rom.rom[addr | scsi->bios_bank]; + if (addr == 0x3f7e) /*DIP switches*/ + temp = scsi->dipsw; + else if (addr == 0x3f7f) /*Negation of DIP switches, to satisfy BIOS checksum!*/ + temp = (scsi->dipsw ^ 0xff) + 1; + else if (addr >= 0x3f80 && (scsi->shadow & 2)) + temp = scsi->shadow_ram[addr]; + else + temp = scsi->bios_rom.rom[addr | scsi->bios_bank]; - return temp; + return temp; } static void aha1542c_write(uint32_t addr, uint8_t val, void *p) { - aha154x_t *scsi = (aha154x_t *)p; + aha154x_t *scsi = (aha154x_t *)p; - addr &= 0x3fff; + addr &= 0x3fff; - if (addr >= 0x3f80 && (scsi->shadow & 1)) - scsi->shadow_ram[addr] = val; + if (addr >= 0x3f80 && (scsi->shadow & 1)) + scsi->shadow_ram[addr] = val; } static void aha1542c_eeprom_load(aha154x_t *scsi, char *fn) { - FILE *f; + FILE *f; - strcpy(scsi->fn, fn); - f = nvrfopen(scsi->fn, "rb"); - if (!f) { - memset(scsi->eeprom, 0, 35); - return; - } - fread(scsi->eeprom, 1, 32, f); - fclose(f); + strcpy(scsi->fn, fn); + f = nvrfopen(scsi->fn, "rb"); + if (!f) { + memset(scsi->eeprom, 0, 35); + return; + } + fread(scsi->eeprom, 1, 32, f); + fclose(f); } static void aha1542c_eeprom_save(aha154x_t *scsi) { - FILE *f = nvrfopen(scsi->fn, "wb"); + FILE *f = nvrfopen(scsi->fn, "wb"); - if (!f) - return; - fwrite(scsi->eeprom, 1, 32, f); - fclose(f); + if (!f) + return; + fwrite(scsi->eeprom, 1, 32, f); + fclose(f); } -static uint16_t port_sw_mapping[8] = - { - 0x330, 0x334, 0x230, 0x234, 0x130, 0x134, -1, -1 - }; +static uint16_t port_sw_mapping[8] = {0x330, 0x334, 0x230, 0x234, 0x130, 0x134, -1, -1}; static void *scsi_aha1542c_init(char *bios_fn) { - aha154x_t *scsi = malloc(sizeof(aha154x_t)); - uint32_t addr; - int c; - memset(scsi, 0, sizeof(aha154x_t)); + aha154x_t *scsi = malloc(sizeof(aha154x_t)); + uint32_t addr; + int c; + memset(scsi, 0, sizeof(aha154x_t)); - rom_init(&scsi->bios_rom, "adaptec_aha1542c_bios_534201-00.bin", 0xd8000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - mem_mapping_disable(&scsi->bios_rom.mapping); + rom_init(&scsi->bios_rom, "adaptec_aha1542c_bios_534201-00.bin", 0xd8000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + mem_mapping_disable(&scsi->bios_rom.mapping); - addr = device_get_config_int("bios_addr"); - mem_mapping_add(&scsi->mapping, addr, 0x4000, - aha1542c_read, NULL, NULL, - aha1542c_write, NULL, NULL, - scsi->bios_rom.rom, 0, scsi); + addr = device_get_config_int("bios_addr"); + mem_mapping_add(&scsi->mapping, addr, 0x4000, aha1542c_read, NULL, NULL, aha1542c_write, NULL, NULL, scsi->bios_rom.rom, + 0, scsi); - scsi->status = 0; - scsi->cmd_state = CMD_STATE_IDLE; - scsi->ccb_state = CCB_STATE_IDLE; - scsi->scsi_state = SCSI_STATE_IDLE; + scsi->status = 0; + scsi->cmd_state = CMD_STATE_IDLE; + scsi->ccb_state = CCB_STATE_IDLE; + scsi->scsi_state = SCSI_STATE_IDLE; - timer_add(&scsi->timer, aha154x_callback, scsi, 1); + timer_add(&scsi->timer, aha154x_callback, scsi, 1); - addr = device_get_config_int("addr"); - io_sethandler(addr, 0x0004, - aha154x_in, NULL, NULL, - aha154x_out, NULL, NULL, - scsi); - for (c = 0; c < 8; c++) { - if (port_sw_mapping[c] == addr) { - scsi->dipsw = c; - break; - } - } + addr = device_get_config_int("addr"); + io_sethandler(addr, 0x0004, aha154x_in, NULL, NULL, aha154x_out, NULL, NULL, scsi); + for (c = 0; c < 8; c++) { + if (port_sw_mapping[c] == addr) { + scsi->dipsw = c; + break; + } + } - scsi_bus_init(&scsi->bus); + scsi_bus_init(&scsi->bus); - scsi->type = SCSI_AHA1542C; + scsi->type = SCSI_AHA1542C; - aha1542c_eeprom_load(scsi, "aha1542c.nvr"); + aha1542c_eeprom_load(scsi, "aha1542c.nvr"); - scsi->host_id = scsi->eeprom[0] & 7; - scsi->dma = (scsi->eeprom[1] >> 4) & 7; - scsi->irq = (scsi->eeprom[1] & 7) + 9; - pclog("Init IRQ=%i DMA=%i ID=%i\n", scsi->irq, scsi->dma, scsi->host_id); + scsi->host_id = scsi->eeprom[0] & 7; + scsi->dma = (scsi->eeprom[1] >> 4) & 7; + scsi->irq = (scsi->eeprom[1] & 7) + 9; + pclog("Init IRQ=%i DMA=%i ID=%i\n", scsi->irq, scsi->dma, scsi->host_id); - return scsi; + return scsi; } static void *scsi_bt545s_init(char *bios_fn) { - aha154x_t *scsi = malloc(sizeof(aha154x_t)); - uint32_t addr; - memset(scsi, 0, sizeof(aha154x_t)); + aha154x_t *scsi = malloc(sizeof(aha154x_t)); + uint32_t addr; + memset(scsi, 0, sizeof(aha154x_t)); - addr = device_get_config_int("bios_addr"); - rom_init(&scsi->bios_rom, "BusLogic_BT-545S_U15_27128_5002026-4.50.bin", addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); - scsi->bios_addr = addr; + addr = device_get_config_int("bios_addr"); + rom_init(&scsi->bios_rom, "BusLogic_BT-545S_U15_27128_5002026-4.50.bin", addr, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + scsi->bios_addr = addr; - scsi->status = 0; - scsi->cmd_state = CMD_STATE_IDLE; - scsi->ccb_state = CCB_STATE_IDLE; - scsi->scsi_state = SCSI_STATE_IDLE; + scsi->status = 0; + scsi->cmd_state = CMD_STATE_IDLE; + scsi->ccb_state = CCB_STATE_IDLE; + scsi->scsi_state = SCSI_STATE_IDLE; - timer_add(&scsi->timer, aha154x_callback, scsi, 1); + timer_add(&scsi->timer, aha154x_callback, scsi, 1); - addr = device_get_config_int("addr"); - io_sethandler(addr, 0x0004, - aha154x_in, NULL, NULL, - aha154x_out, NULL, NULL, - scsi); + addr = device_get_config_int("addr"); + io_sethandler(addr, 0x0004, aha154x_in, NULL, NULL, aha154x_out, NULL, NULL, scsi); - scsi_bus_init(&scsi->bus); + scsi_bus_init(&scsi->bus); - scsi->type = SCSI_BT545S; + scsi->type = SCSI_BT545S; - scsi->host_id = device_get_config_int("host_id"); - scsi->dma = device_get_config_int("dma"); - scsi->irq = device_get_config_int("irq"); + scsi->host_id = device_get_config_int("host_id"); + scsi->dma = device_get_config_int("dma"); + scsi->irq = device_get_config_int("irq"); - return scsi; + return scsi; } static void scsi_aha1542c_close(void *p) { - aha154x_t *scsi = (aha154x_t *)p; + aha154x_t *scsi = (aha154x_t *)p; - scsi_bus_close(&scsi->bus); + scsi_bus_close(&scsi->bus); - free(scsi); + free(scsi); } -static int scsi_aha1542c_available() { - return rom_present("adaptec_aha1542c_bios_534201-00.bin"); -} +static int scsi_aha1542c_available() { return rom_present("adaptec_aha1542c_bios_534201-00.bin"); } -static int scsi_bt545s_available() { - return rom_present("BusLogic_BT-545S_U15_27128_5002026-4.50.bin"); -} +static int scsi_bt545s_available() { return rom_present("BusLogic_BT-545S_U15_27128_5002026-4.50.bin"); } -static device_config_t aha1542c_config[] = - { - { - .name = "addr", - .description = "Address", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "130", - .value = 0x130 - }, - { - .description = "134", - .value = 0x134 - }, - { - .description = "230", - .value = 0x230 - }, - { - .description = "234", - .value = 0x234 - }, - { - .description = "330", - .value = 0x330 - }, - { - .description = "334", - .value = 0x334 - }, - { - .description = "" - } - }, - .default_int = 0x334 - }, - { - .name = "bios_addr", - .description = "BIOS address", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "C8000", - .value = 0xc8000 - }, - { - .description = "CC000", - .value = 0xcc000 - }, - { - .description = "D0000", - .value = 0xd0000 - }, - { - .description = "D4000", - .value = 0xd4000 - }, - { - .description = "D8000", - .value = 0xd8000 - }, - { - .description = "DC000", - .value = 0xdc000 - }, - { - .description = "" - } - }, - .default_int = 0xdc000 - }, - { - .type = -1 - } - }; +static device_config_t aha1542c_config[] = {{.name = "addr", + .description = "Address", + .type = CONFIG_SELECTION, + .selection = {{.description = "130", .value = 0x130}, + {.description = "134", .value = 0x134}, + {.description = "230", .value = 0x230}, + {.description = "234", .value = 0x234}, + {.description = "330", .value = 0x330}, + {.description = "334", .value = 0x334}, + {.description = ""}}, + .default_int = 0x334}, + {.name = "bios_addr", + .description = "BIOS address", + .type = CONFIG_SELECTION, + .selection = {{.description = "C8000", .value = 0xc8000}, + {.description = "CC000", .value = 0xcc000}, + {.description = "D0000", .value = 0xd0000}, + {.description = "D4000", .value = 0xd4000}, + {.description = "D8000", .value = 0xd8000}, + {.description = "DC000", .value = 0xdc000}, + {.description = ""}}, + .default_int = 0xdc000}, + {.type = -1}}; -static device_config_t bt545s_config[] = - { - { - .name = "addr", - .description = "Address", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "130", - .value = 0x130 - }, - { - .description = "134", - .value = 0x134 - }, - { - .description = "230", - .value = 0x230 - }, - { - .description = "234", - .value = 0x234 - }, - { - .description = "330", - .value = 0x330 - }, - { - .description = "334", - .value = 0x334 - }, - { - .description = "" - } - }, - .default_int = 0x334 - }, - { - .name = "bios_addr", - .description = "BIOS address", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "C8000", - .value = 0xc8000 - }, - { - .description = "D8000", - .value = 0xd8000 - }, - { - .description = "DC000", - .value = 0xdc000 - }, - { - .description = "" - } - }, - .default_int = 0xdc000 - }, - { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "IRQ 9", - .value = 9 - }, - { - .description = "IRQ 10", - .value = 10 - }, - { - .description = "IRQ 11", - .value = 11 - }, - { - .description = "IRQ 12", - .value = 12 - }, - { - .description = "IRQ 14", - .value = 14 - }, - { - .description = "IRQ 15", - .value = 15 - }, - { - .description = "" - } - }, - .default_int = 10 - }, - { - .name = "dma", - .description = "DMA", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "DMA 5", - .value = 5 - }, - { - .description = "DMA 6", - .value = 6 - }, - { - .description = "DMA 7", - .value = 7 - }, - { - .description = "" - } - }, - .default_int = 7 - }, - { - .name = "host_id", - .description = "Host ID", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "ID 0", - .value = 0 - }, - { - .description = "ID 1", - .value = 1 - }, - { - .description = "ID 2", - .value = 2 - }, - { - .description = "ID 3", - .value = 3 - }, - { - .description = "ID 4", - .value = 4 - }, - { - .description = "ID 5", - .value = 5 - }, - { - .description = "ID 6", - .value = 6 - }, - { - .description = "ID 7", - .value = 7 - }, - { - .description = "" - } - }, - .default_int = 7 - }, - { - .type = -1 - } - }; +static device_config_t bt545s_config[] = {{.name = "addr", + .description = "Address", + .type = CONFIG_SELECTION, + .selection = {{.description = "130", .value = 0x130}, + {.description = "134", .value = 0x134}, + {.description = "230", .value = 0x230}, + {.description = "234", .value = 0x234}, + {.description = "330", .value = 0x330}, + {.description = "334", .value = 0x334}, + {.description = ""}}, + .default_int = 0x334}, + {.name = "bios_addr", + .description = "BIOS address", + .type = CONFIG_SELECTION, + .selection = {{.description = "C8000", .value = 0xc8000}, + {.description = "D8000", .value = 0xd8000}, + {.description = "DC000", .value = 0xdc000}, + {.description = ""}}, + .default_int = 0xdc000}, + {.name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .selection = {{.description = "IRQ 9", .value = 9}, + {.description = "IRQ 10", .value = 10}, + {.description = "IRQ 11", .value = 11}, + {.description = "IRQ 12", .value = 12}, + {.description = "IRQ 14", .value = 14}, + {.description = "IRQ 15", .value = 15}, + {.description = ""}}, + .default_int = 10}, + {.name = "dma", + .description = "DMA", + .type = CONFIG_SELECTION, + .selection = {{.description = "DMA 5", .value = 5}, + {.description = "DMA 6", .value = 6}, + {.description = "DMA 7", .value = 7}, + {.description = ""}}, + .default_int = 7}, + {.name = "host_id", + .description = "Host ID", + .type = CONFIG_SELECTION, + .selection = {{.description = "ID 0", .value = 0}, + {.description = "ID 1", .value = 1}, + {.description = "ID 2", .value = 2}, + {.description = "ID 3", .value = 3}, + {.description = "ID 4", .value = 4}, + {.description = "ID 5", .value = 5}, + {.description = "ID 6", .value = 6}, + {.description = "ID 7", .value = 7}, + {.description = ""}}, + .default_int = 7}, + {.type = -1}}; -device_t scsi_aha1542c_device = - { - "Adaptec AHA-1542C (SCSI)", - DEVICE_AT, - scsi_aha1542c_init, - scsi_aha1542c_close, - scsi_aha1542c_available, - NULL, - NULL, - NULL, - aha1542c_config - }; -device_t scsi_bt545s_device = - { - "BusLogic BT-545S (SCSI)", - DEVICE_AT, - scsi_bt545s_init, - scsi_aha1542c_close, - scsi_bt545s_available, - NULL, - NULL, - NULL, - bt545s_config - }; +device_t scsi_aha1542c_device = {"Adaptec AHA-1542C (SCSI)", + DEVICE_AT, + scsi_aha1542c_init, + scsi_aha1542c_close, + scsi_aha1542c_available, + NULL, + NULL, + NULL, + aha1542c_config}; +device_t scsi_bt545s_device = {"BusLogic BT-545S (SCSI)", + DEVICE_AT, + scsi_bt545s_init, + scsi_aha1542c_close, + scsi_bt545s_available, + NULL, + NULL, + NULL, + bt545s_config}; diff --git a/src/scsi/scsi_cd.c b/src/scsi/scsi_cd.c index d80c3063..d5bdbe2b 100644 --- a/src/scsi/scsi_cd.c +++ b/src/scsi/scsi_cd.c @@ -11,197 +11,186 @@ #define MIN(a, b) ((a) < (b) ? (a) : (b)) -#define BUFFER_SIZE (256*1024) +#define BUFFER_SIZE (256 * 1024) #define MAX_NR_SECTORS 16 -enum { - CMD_POS_IDLE = 0, - CMD_POS_WAIT, - CMD_POS_START_SECTOR, - CMD_POS_TRANSFER, - CMD_POS_COMPLETE -}; +enum { CMD_POS_IDLE = 0, CMD_POS_WAIT, CMD_POS_START_SECTOR, CMD_POS_TRANSFER, CMD_POS_COMPLETE }; /* ATAPI Commands */ -#define GPCMD_TEST_UNIT_READY 0x00 -#define GPCMD_REQUEST_SENSE 0x03 -#define GPCMD_READ_6 0x08 -#define GPCMD_INQUIRY 0x12 -#define GPCMD_MODE_SELECT_6 0x15 -#define GPCMD_MODE_SENSE_6 0x1a -#define GPCMD_START_STOP_UNIT 0x1b -#define GPCMD_PREVENT_REMOVAL 0x1e -#define GPCMD_READ_CDROM_CAPACITY 0x25 -#define GPCMD_READ_10 0x28 -#define GPCMD_SEEK 0x2b -#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_PLAY_AUDIO_MSF 0x47 -#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_MODE_SELECT_10 0x55 -#define GPCMD_MODE_SENSE_10 0x5a -#define GPCMD_PLAY_AUDIO_12 0xa5 -#define GPCMD_READ_12 0xa8 -#define GPCMD_SEND_DVD_STRUCTURE 0xad -#define GPCMD_SET_SPEED 0xbb -#define GPCMD_MECHANISM_STATUS 0xbd -#define GPCMD_READ_CD 0xbe +#define GPCMD_TEST_UNIT_READY 0x00 +#define GPCMD_REQUEST_SENSE 0x03 +#define GPCMD_READ_6 0x08 +#define GPCMD_INQUIRY 0x12 +#define GPCMD_MODE_SELECT_6 0x15 +#define GPCMD_MODE_SENSE_6 0x1a +#define GPCMD_START_STOP_UNIT 0x1b +#define GPCMD_PREVENT_REMOVAL 0x1e +#define GPCMD_READ_CDROM_CAPACITY 0x25 +#define GPCMD_READ_10 0x28 +#define GPCMD_SEEK 0x2b +#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_PLAY_AUDIO_MSF 0x47 +#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_MODE_SELECT_10 0x55 +#define GPCMD_MODE_SENSE_10 0x5a +#define GPCMD_PLAY_AUDIO_12 0xa5 +#define GPCMD_READ_12 0xa8 +#define GPCMD_SEND_DVD_STRUCTURE 0xad +#define GPCMD_SET_SPEED 0xbb +#define GPCMD_MECHANISM_STATUS 0xbd +#define GPCMD_READ_CD 0xbe /* 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 +#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 /* ATAPI Sense Keys */ -#define SENSE_NONE 0 -#define SENSE_NOT_READY 2 -#define SENSE_ILLEGAL_REQUEST 5 -#define SENSE_UNIT_ATTENTION 6 +#define SENSE_NONE 0 +#define SENSE_NOT_READY 2 +#define SENSE_ILLEGAL_REQUEST 5 +#define SENSE_UNIT_ATTENTION 6 -#define ASCQ_AUDIO_PLAY_OPERATION_IN_PROGRESS 0x11 -#define ASCQ_AUDIO_PLAY_OPERATION_PAUSED 0x12 -#define ASCQ_AUDIO_PLAY_OPERATION_COMPLETED 0x13 +#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 +#define CDROM_SPEED 706 /* 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 +#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 +#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 -#define CHECK_READY 2 -#define ALLOW_UA 1 +#define CHECK_READY 2 +#define ALLOW_UA 1 /* Table of all ATAPI commands and their flags, needed for the new disc change / not ready handler. */ -static uint8_t atapi_cmd_table[0x100] = - { - [GPCMD_TEST_UNIT_READY] = CHECK_READY, - [GPCMD_REQUEST_SENSE] = ALLOW_UA, - [GPCMD_READ_6] = CHECK_READY, - [GPCMD_INQUIRY] = ALLOW_UA, - [GPCMD_MODE_SELECT_6] = 0, - [GPCMD_MODE_SENSE_6] = 0, - [GPCMD_START_STOP_UNIT] = 0, - [GPCMD_PREVENT_REMOVAL] = CHECK_READY, - [GPCMD_READ_CDROM_CAPACITY] = CHECK_READY, - [GPCMD_READ_10] = CHECK_READY, - [GPCMD_SEEK] = CHECK_READY, - [GPCMD_READ_SUBCHANNEL] = CHECK_READY, - [GPCMD_READ_TOC_PMA_ATIP] = CHECK_READY | ALLOW_UA, /* Read TOC - can get through UNIT_ATTENTION, per VIDE-CDD.SYS */ - [GPCMD_READ_HEADER] = CHECK_READY, - [GPCMD_PLAY_AUDIO_10] = CHECK_READY, - [GPCMD_PLAY_AUDIO_MSF] = CHECK_READY, - [GPCMD_GET_EVENT_STATUS_NOTIFICATION] = ALLOW_UA, - [GPCMD_PAUSE_RESUME] = CHECK_READY, - [GPCMD_STOP_PLAY_SCAN] = CHECK_READY, - [GPCMD_READ_DISC_INFORMATION] = CHECK_READY, - [GPCMD_MODE_SELECT_10] = 0, - [GPCMD_MODE_SENSE_10] = 0, - [GPCMD_PLAY_AUDIO_12] = CHECK_READY, - [GPCMD_READ_12] = CHECK_READY, - [GPCMD_SEND_DVD_STRUCTURE] = CHECK_READY, /* Read DVD structure (NOT IMPLEMENTED YET) */ - [GPCMD_SET_SPEED] = 0, - [GPCMD_MECHANISM_STATUS] = 0, - [GPCMD_READ_CD] = CHECK_READY, - [0xBF] = CHECK_READY /* Send DVD structure (NOT IMPLEMENTED YET) */ - }; +static uint8_t atapi_cmd_table[0x100] = { + [GPCMD_TEST_UNIT_READY] = CHECK_READY, + [GPCMD_REQUEST_SENSE] = ALLOW_UA, + [GPCMD_READ_6] = CHECK_READY, + [GPCMD_INQUIRY] = ALLOW_UA, + [GPCMD_MODE_SELECT_6] = 0, + [GPCMD_MODE_SENSE_6] = 0, + [GPCMD_START_STOP_UNIT] = 0, + [GPCMD_PREVENT_REMOVAL] = CHECK_READY, + [GPCMD_READ_CDROM_CAPACITY] = CHECK_READY, + [GPCMD_READ_10] = CHECK_READY, + [GPCMD_SEEK] = CHECK_READY, + [GPCMD_READ_SUBCHANNEL] = CHECK_READY, + [GPCMD_READ_TOC_PMA_ATIP] = CHECK_READY | ALLOW_UA, /* Read TOC - can get through UNIT_ATTENTION, per VIDE-CDD.SYS */ + [GPCMD_READ_HEADER] = CHECK_READY, + [GPCMD_PLAY_AUDIO_10] = CHECK_READY, + [GPCMD_PLAY_AUDIO_MSF] = CHECK_READY, + [GPCMD_GET_EVENT_STATUS_NOTIFICATION] = ALLOW_UA, + [GPCMD_PAUSE_RESUME] = CHECK_READY, + [GPCMD_STOP_PLAY_SCAN] = CHECK_READY, + [GPCMD_READ_DISC_INFORMATION] = CHECK_READY, + [GPCMD_MODE_SELECT_10] = 0, + [GPCMD_MODE_SENSE_10] = 0, + [GPCMD_PLAY_AUDIO_12] = CHECK_READY, + [GPCMD_READ_12] = CHECK_READY, + [GPCMD_SEND_DVD_STRUCTURE] = CHECK_READY, /* Read DVD structure (NOT IMPLEMENTED YET) */ + [GPCMD_SET_SPEED] = 0, + [GPCMD_MECHANISM_STATUS] = 0, + [GPCMD_READ_CD] = CHECK_READY, + [0xBF] = CHECK_READY /* Send DVD structure (NOT IMPLEMENTED YET) */ +}; -#define IMPLEMENTED 1 +#define IMPLEMENTED 1 -static uint8_t mode_sense_pages[0x40] = - { - [GPMODE_R_W_ERROR_PAGE] = IMPLEMENTED, - [GPMODE_CDROM_PAGE] = IMPLEMENTED, - [GPMODE_CDROM_AUDIO_PAGE] = IMPLEMENTED, - [GPMODE_CAPABILITIES_PAGE] = IMPLEMENTED, - [GPMODE_ALL_PAGES] = IMPLEMENTED - }; +static uint8_t mode_sense_pages[0x40] = {[GPMODE_R_W_ERROR_PAGE] = IMPLEMENTED, + [GPMODE_CDROM_PAGE] = IMPLEMENTED, + [GPMODE_CDROM_AUDIO_PAGE] = IMPLEMENTED, + [GPMODE_CAPABILITIES_PAGE] = IMPLEMENTED, + [GPMODE_ALL_PAGES] = IMPLEMENTED}; uint8_t mode_pages_in[256][256]; -#define PAGE_CHANGEABLE 1 -#define PAGE_CHANGED 2 -static uint8_t page_flags[256] = - { - [GPMODE_R_W_ERROR_PAGE] = 0, - [GPMODE_CDROM_PAGE] = 0, - [GPMODE_CDROM_AUDIO_PAGE] = PAGE_CHANGEABLE, - [GPMODE_CAPABILITIES_PAGE] = 0, - }; +#define PAGE_CHANGEABLE 1 +#define PAGE_CHANGED 2 +static uint8_t page_flags[256] = { + [GPMODE_R_W_ERROR_PAGE] = 0, + [GPMODE_CDROM_PAGE] = 0, + [GPMODE_CDROM_AUDIO_PAGE] = PAGE_CHANGEABLE, + [GPMODE_CAPABILITIES_PAGE] = 0, +}; extern int cd_status; typedef struct scsi_cd_data_t { - uint8_t data_in[BUFFER_SIZE]; - uint8_t data_out[BUFFER_SIZE]; + uint8_t data_in[BUFFER_SIZE]; + uint8_t data_out[BUFFER_SIZE]; - int blocks; + int blocks; - int cmd_pos, new_cmd_pos; - pc_timer_t callback_timer; - int wait_time; - scsi_bus_t *bus; + int cmd_pos, new_cmd_pos; + pc_timer_t callback_timer; + int wait_time; + scsi_bus_t *bus; - int addr, len; - int sector_pos; + int addr, len; + int sector_pos; - uint8_t buf[512]; + uint8_t buf[512]; - uint8_t status; + uint8_t status; - int data_pos_read, data_pos_write; - int data_bytes_read, bytes_expected; + int data_pos_read, data_pos_write; + int data_bytes_read, bytes_expected; - int cdlen, cdpos; + int cdlen, cdpos; - int bytes_received, bytes_required; + int bytes_received, bytes_required; - int sense_key, asc, ascq; + int sense_key, asc, ascq; - int id; + int id; - int received_cdb; - uint8_t cdb[CDB_MAX_LEN]; + int received_cdb; + uint8_t cdb[CDB_MAX_LEN]; - int prev_status; - int cd_status; + int prev_status; + int cd_status; - uint8_t prefix_len; - uint8_t page_current; + uint8_t prefix_len; + uint8_t page_current; - int is_atapi; - atapi_device_t *atapi_dev; + int is_atapi; + atapi_device_t *atapi_dev; - int pio_mode, mdma_mode; + int pio_mode, mdma_mode; - int short_seek, long_seek; - int max_speed, cur_speed; + int short_seek, long_seek; + int max_speed, cur_speed; - int cur_model; + int cur_model; } scsi_cd_data_t; static scsi_cd_data_t *cd_data = NULL; @@ -209,365 +198,338 @@ static scsi_cd_data_t *cd_data = NULL; /*Note - all transfer speeds currently assume CAV behaviour. Drives above about 8x should use CLV instead, but this is not currently supported.*/ static struct { - int speed; - int short_seek; - int long_seek; -} cd_speeds[] = - { - {1, 240, 1446}, - {2, 160, 1000}, - {3, 150, 900}, - {4, 112, 675}, - {6, 112, 675}, - {8, 112, 675}, - {12, 75, 400}, - {16, 58, 350}, - {20, 50, 300}, - {24, 45, 270}, - {32, 45, 270}, - {36, 45, 270}, - {40, 50, 300}, - {44, 50, 300}, - {48, 50, 300}, - {52, 45, 270}, - {56, 45, 270}, - {72, 45, 270}, - }; + int speed; + int short_seek; + int long_seek; +} cd_speeds[] = { + {1, 240, 1446}, {2, 160, 1000}, {3, 150, 900}, {4, 112, 675}, {6, 112, 675}, {8, 112, 675}, + {12, 75, 400}, {16, 58, 350}, {20, 50, 300}, {24, 45, 270}, {32, 45, 270}, {36, 45, 270}, + {40, 50, 300}, {44, 50, 300}, {48, 50, 300}, {52, 45, 270}, {56, 45, 270}, {72, 45, 270}, +}; int cd_speed; -int cd_get_speed(int i) { - return cd_speeds[i].speed; -} +int cd_get_speed(int i) { return cd_speeds[i].speed; } void cd_set_speed(int speed) { - if (cd_data) { - int c = 0; + if (cd_data) { + int c = 0; - while (1) { - if (cd_speeds[c].speed == speed) - break; - if (cd_speeds[c].speed >= MAX_CD_SPEED) - break; + while (1) { + if (cd_speeds[c].speed == speed) + break; + if (cd_speeds[c].speed >= MAX_CD_SPEED) + break; - c++; - } + c++; + } - cd_data->max_speed = speed; - cd_data->cur_speed = speed; - cd_data->short_seek = cd_speeds[c].short_seek; - cd_data->long_seek = cd_speeds[c].long_seek; - } + cd_data->max_speed = speed; + cd_data->cur_speed = speed; + cd_data->short_seek = cd_speeds[c].short_seek; + cd_data->long_seek = cd_speeds[c].long_seek; + } } static struct { - // suffix numbers are sizes from the specs - char *vendor_8; - char *model_and_firmware_40; - char *serial_20; - char *model_16; - char *firmware_4; + // suffix numbers are sizes from the specs + char *vendor_8; + char *model_and_firmware_40; + char *serial_20; + char *model_16; + char *firmware_4; - char *serial2_20; - char *firmware2_8; - char *model2_40; + char *serial2_20; + char *firmware2_8; + char *model2_40; - // for PCem config only - char *model_string_40; - char *model_config_string_40; - int interfaces; - int speed; // Not an index, but a "speed" value. -1 == allow override -} const cd_models[] = - { - { - // Generic PCem CD - "PCem", - "PCemCD v1.0", - "53R141", - "PCemCD", - "1.0", + // for PCem config only + char *model_string_40; + char *model_config_string_40; + int interfaces; + int speed; // Not an index, but a "speed" value. -1 == allow override +} const cd_models[] = { + { + // Generic PCem CD + "PCem", + "PCemCD v1.0", + "53R141", + "PCemCD", + "1.0", - "", - "v1.0", - "PCemCD", - "PCemCD", - "pcemcd", - CD_MODEL_INTERFACE_ALL, - -1, - }, + "", + "v1.0", + "PCemCD", + "PCemCD", + "pcemcd", + CD_MODEL_INTERFACE_ALL, + -1, + }, - { - // A 4x CD-ROM drive from Aztech. Choose if your system image has the SGIDECD.SYS driver - "AZT", - "AZT 46802I v1.15", - "53R141", // TODO: clone serial from my real one - "46802I", - "1.15", + { + // A 4x CD-ROM drive from Aztech. Choose if your system image has the SGIDECD.SYS driver + "AZT", + "AZT 46802I v1.15", + "53R141", // TODO: clone serial from my real one + "46802I", + "1.15", - "", - "v1.15", - "CDA46802I", - "AZT CDA 468-02I (4X)", - "azt_cda_468_02i_4x", - CD_MODEL_INTERFACE_IDE, - 4, - }, + "", + "v1.15", + "CDA46802I", + "AZT CDA 468-02I (4X)", + "azt_cda_468_02i_4x", + CD_MODEL_INTERFACE_IDE, + 4, + }, - { - // A 6X CD-ROM drive from NEC. - "NEC", - "NEC CDR-1300A 1.05", - "63K3320T113", // - "CDR-1300A", - "1.05", + { + // A 6X CD-ROM drive from NEC. + "NEC", + "NEC CDR-1300A 1.05", + "63K3320T113", // + "CDR-1300A", + "1.05", - "", - "v1.05", - "CDR-1300A", - "NEC CDR-1300A (6X)", - "cdr1300a", - CD_MODEL_INTERFACE_IDE, - 6, - }, + "", + "v1.05", + "CDR-1300A", + "NEC CDR-1300A (6X)", + "cdr1300a", + CD_MODEL_INTERFACE_IDE, + 6, + }, - { - // An 8X CD-ROM drive from Sony. - "Sony", - "Sony CDU311 3.0h", - "5345074", - "CD-ROM CDU311", - "3.0h", + { + // An 8X CD-ROM drive from Sony. + "Sony", + "Sony CDU311 3.0h", + "5345074", + "CD-ROM CDU311", + "3.0h", - "", - "3.0h", - "SONY CDU311", - "Sony CDU311 (8X)", - "cdu311", - CD_MODEL_INTERFACE_IDE, - 8, - }, + "", + "3.0h", + "SONY CDU311", + "Sony CDU311 (8X)", + "cdu311", + CD_MODEL_INTERFACE_IDE, + 8, + }, - { - // A 12X CD-ROM drive from Toshiba. - "Toshiba", - "Toshiba XM-5702B TA70", - "784P009803", - "CD-ROM XM-5702B", - "TA70", + { + // A 12X CD-ROM drive from Toshiba. + "Toshiba", + "Toshiba XM-5702B TA70", + "784P009803", + "CD-ROM XM-5702B", + "TA70", - "", - "TA70", - "TOSHIBA XM-5702B", - "Toshiba XM-5702B (12X)", - "xm5702b", - CD_MODEL_INTERFACE_IDE, - 12, - }, + "", + "TA70", + "TOSHIBA XM-5702B", + "Toshiba XM-5702B (12X)", + "xm5702b", + CD_MODEL_INTERFACE_IDE, + 12, + }, - { - // A 16X CD-ROM drive from Goldstar. - "GoldStar", - "GoldStar CRD-8160B 3.14", - "11S02K1151ZJ13VG108019", - "CD-ROM CRD-8160B", - "3.14", + { + // A 16X CD-ROM drive from Goldstar. + "GoldStar", + "GoldStar CRD-8160B 3.14", + "11S02K1151ZJ13VG108019", + "CD-ROM CRD-8160B", + "3.14", - "", - "3.14", - "GOLDSTAR CRD-8160B", - "GoldStar CRD-8160B (16X)", - "crd-8160b", - CD_MODEL_INTERFACE_IDE, - 16, - }, + "", + "3.14", + "GOLDSTAR CRD-8160B", + "GoldStar CRD-8160B (16X)", + "crd-8160b", + CD_MODEL_INTERFACE_IDE, + 16, + }, - { - // A 24X CD-ROM drive from Creative Labs by Matshita. - "MATSHITA", - "Matshita CR-587-B 7S13", - "8307DDB76196", - "CR-587", - "7S13", + { + // A 24X CD-ROM drive from Creative Labs by Matshita. + "MATSHITA", + "Matshita CR-587-B 7S13", + "8307DDB76196", + "CR-587", + "7S13", - "", - "7S13", - "MATSHITA CR-587-B", - "Creative CR-587-B (24X)", - "cr-587-b", - CD_MODEL_INTERFACE_IDE, - 24, - }, + "", + "7S13", + "MATSHITA CR-587-B", + "Creative CR-587-B (24X)", + "cr-587-b", + CD_MODEL_INTERFACE_IDE, + 24, + }, - { - // A 32X CD-ROM drive from Creative Labs by Matshita. - "MATSHITA", - "Matshita CR-588-B LS15", - "8516DFA30742", - "CR-588-B", - "LS15", + { + // A 32X CD-ROM drive from Creative Labs by Matshita. + "MATSHITA", + "Matshita CR-588-B LS15", + "8516DFA30742", + "CR-588-B", + "LS15", - "", - "LS15", - "MATSHITA CR-588-B", - "Creative CR-588-B (32X)", - "cr-588-b", - CD_MODEL_INTERFACE_IDE, - 32, - }, + "", + "LS15", + "MATSHITA CR-588-B", + "Creative CR-588-B (32X)", + "cr-588-b", + CD_MODEL_INTERFACE_IDE, + 32, + }, - { - // A 36X CD-ROM drive from BTC. - "BTC", - "BTC BCD36XH U1.0", - "P81729496", - "CD-ROM BCD36XH", - "U1.0", + { + // A 36X CD-ROM drive from BTC. + "BTC", + "BTC BCD36XH U1.0", + "P81729496", + "CD-ROM BCD36XH", + "U1.0", - "", - "U1.0", - "BCD36XH", - "BTC BCD36XH (36X)", - "bcd36xh", - CD_MODEL_INTERFACE_IDE, - 36, - }, + "", + "U1.0", + "BCD36XH", + "BTC BCD36XH (36X)", + "bcd36xh", + CD_MODEL_INTERFACE_IDE, + 36, + }, - { - // A 40X CD-ROM drive from Philips. - "Philips", - "Philips PCA403CD U31P", - "P66839-20942 B1", - "CD-ROM PCA403CD", - "U31P", + { + // A 40X CD-ROM drive from Philips. + "Philips", + "Philips PCA403CD U31P", + "P66839-20942 B1", + "CD-ROM PCA403CD", + "U31P", - "", - "U31P", - "PHILIPS PCA403CD", - "Philips PCA403CD (40X)", - "pca403cd", - CD_MODEL_INTERFACE_IDE, - 40, - }, + "", + "U31P", + "PHILIPS PCA403CD", + "Philips PCA403CD (40X)", + "pca403cd", + CD_MODEL_INTERFACE_IDE, + 40, + }, - { - // A 48X CD-ROM drive from Mitsumi. - "Mitsumi", - "Mitsumi CRMC-FX4820T D02A", - "10600125426", - "CRMC-FX4820T", - "D02A", + { + // A 48X CD-ROM drive from Mitsumi. + "Mitsumi", + "Mitsumi CRMC-FX4820T D02A", + "10600125426", + "CRMC-FX4820T", + "D02A", - "", - "D02A", - "MITSUMI CRMC-FX4820T", - "Mitsumi CRMC-FX4820T (48X)", - "crmc-fx4820t", - CD_MODEL_INTERFACE_IDE, - 48, - }, - { - // A 72X CD-ROM drive from Kenwood. - "KENWOOD", - "KENWOOD UCR-421 208E", - "9Z18612480", - "CD-ROM UCR-421", - "208E", + "", + "D02A", + "MITSUMI CRMC-FX4820T", + "Mitsumi CRMC-FX4820T (48X)", + "crmc-fx4820t", + CD_MODEL_INTERFACE_IDE, + 48, + }, + { + // A 72X CD-ROM drive from Kenwood. + "KENWOOD", + "KENWOOD UCR-421 208E", + "9Z18612480", + "CD-ROM UCR-421", + "208E", - "", - "208E", - "KENWOOD UCR-421", - "Kenwood True-X UCR-421 (72X)", - "ucr421", - CD_MODEL_INTERFACE_IDE, - 72, - }, + "", + "208E", + "KENWOOD UCR-421", + "Kenwood True-X UCR-421 (72X)", + "ucr421", + CD_MODEL_INTERFACE_IDE, + 72, + }, - }; +}; char *cd_model = NULL; -char *cd_get_model(int i) { - return cd_models[i].model_string_40; -} +char *cd_get_model(int i) { return cd_models[i].model_string_40; } -char *cd_get_config_model(int i) { - return cd_models[i].model_config_string_40; -} +char *cd_get_config_model(int i) { return cd_models[i].model_config_string_40; } void cd_set_model(char *model) { - if (cd_data) { - int c = 0; + if (cd_data) { + int c = 0; - while (1) { - if (!model) - break; - if (c > MAX_CD_MODEL) - break; - if (!strncmp(cd_models[c].model_string_40, model, 40)) - break; + while (1) { + if (!model) + break; + if (c > MAX_CD_MODEL) + break; + if (!strncmp(cd_models[c].model_string_40, model, 40)) + break; - c++; - } + c++; + } - cd_data->cur_model = c; - } + cd_data->cur_model = c; + } } -int cd_get_model_interfaces(int i) { - return cd_models[i].interfaces; -} +int cd_get_model_interfaces(int i) { return cd_models[i].interfaces; } -int cd_get_model_speed(int i) { - return cd_models[i].speed; -} +int cd_get_model_speed(int i) { return cd_models[i].speed; } char *cd_model_to_config(char *model) { - int c = 0; + int c = 0; - while (1) { - if (!model) - break; - if (c > MAX_CD_MODEL) { - c = 0; // default - break; - } - if (!strncmp(cd_models[c].model_string_40, model, 40)) - break; + while (1) { + if (!model) + break; + if (c > MAX_CD_MODEL) { + c = 0; // default + break; + } + if (!strncmp(cd_models[c].model_string_40, model, 40)) + break; - c++; - } - return cd_models[c].model_config_string_40; + c++; + } + return cd_models[c].model_config_string_40; } char *cd_model_from_config(char *config) { - int c = 0; + int c = 0; - while (1) { - if (!config) - break; - if (c > MAX_CD_MODEL) { - c = 0; // default - break; - } - if (!strncmp(cd_models[c].model_config_string_40, config, 40)) - break; + while (1) { + if (!config) + break; + if (c > MAX_CD_MODEL) { + c = 0; // default + break; + } + if (!strncmp(cd_models[c].model_config_string_40, config, 40)) + break; - c++; - } - return cd_models[c].model_string_40; + c++; + } + return cd_models[c].model_string_40; } static void scsi_cd_callback(void *p) { - scsi_cd_data_t *data = p; + scsi_cd_data_t *data = p; - if (data->cmd_pos == CMD_POS_WAIT) { - data->wait_time--; - if (!data->wait_time) { - data->cmd_pos = data->new_cmd_pos; - scsi_bus_kick(data->bus); - } else - timer_advance_u64(&data->callback_timer, 1000 * TIMER_USEC); - } + if (data->cmd_pos == CMD_POS_WAIT) { + data->wait_time--; + if (!data->wait_time) { + data->cmd_pos = data->new_cmd_pos; + scsi_bus_kick(data->bus); + } else + timer_advance_u64(&data->callback_timer, 1000 * TIMER_USEC); + } } //#define SECTOR_TIME 13333 /*Time between sectors on 1x drive*/ @@ -576,131 +538,129 @@ static void scsi_cd_callback(void *p) { /*The seek model is currently very basic. Seeks of less than MIN_SEEK sectors are treated as immediate. Seeks between MIN_SEEK and MAX_SEEK sectors scale linearly between short_seek and long seek. - + This really shouldn't be a linear scale, but this is a good enough approximation for now.*/ -#define MIN_SEEK 2000 +#define MIN_SEEK 2000 #define MAX_SEEK 333000 static int get_seek_time(scsi_cd_data_t *data, uint32_t start, uint32_t dest) { - uint32_t diff = ABS((int)(start - dest)); + uint32_t diff = ABS((int)(start - dest)); - if (diff < MIN_SEEK) - return 0; - if (diff > MAX_SEEK) - diff = MAX_SEEK; + if (diff < MIN_SEEK) + return 0; + if (diff > MAX_SEEK) + diff = MAX_SEEK; - diff -= MIN_SEEK; + diff -= MIN_SEEK; - return data->short_seek + ((data->long_seek * diff) / (MAX_SEEK - MIN_SEEK)); + return data->short_seek + ((data->long_seek * diff) / (MAX_SEEK - MIN_SEEK)); } static void scsi_add_data(scsi_cd_data_t *data, uint8_t val) { - data->data_in[data->data_pos_write++] = val; - data->bytes_expected++; + data->data_in[data->data_pos_write++] = val; + data->bytes_expected++; } static void atapi_cmd_error(scsi_cd_data_t *data, int sensekey, int asc, int ascq) { - data->status = STATUS_CHECK_CONDITION; - data->sense_key = sensekey; - data->asc = asc; - data->ascq = ascq; + data->status = STATUS_CHECK_CONDITION; + data->sense_key = sensekey; + data->asc = asc; + data->ascq = ascq; } static void atapi_sense_clear(scsi_cd_data_t *data, int command, int ignore_ua) { - if ((data->sense_key == SENSE_UNIT_ATTENTION) || ignore_ua) { - data->sense_key = 0; - data->asc = 0; - data->ascq = 0; - } + if ((data->sense_key == SENSE_UNIT_ATTENTION) || ignore_ua) { + data->sense_key = 0; + data->asc = 0; + data->ascq = 0; + } } static int atapi_event_status(uint8_t *buffer) { - uint8_t event_code, media_status = 0; + uint8_t event_code, media_status = 0; - if (buffer[5]) { - media_status = MS_TRAY_OPEN; - atapi->stop(); - } else { - media_status = MS_MEDIA_PRESENT; - } + if (buffer[5]) { + media_status = MS_TRAY_OPEN; + atapi->stop(); + } else { + media_status = MS_MEDIA_PRESENT; + } - event_code = MEC_NO_CHANGE; - if (media_status != MS_TRAY_OPEN) { - if (!buffer[4]) { - event_code = MEC_NEW_MEDIA; - atapi->load(); - } else if (buffer[4] == 2) { - event_code = MEC_EJECT_REQUESTED; - atapi->eject(); - } - } + event_code = MEC_NO_CHANGE; + if (media_status != MS_TRAY_OPEN) { + if (!buffer[4]) { + event_code = MEC_NEW_MEDIA; + atapi->load(); + } else if (buffer[4] == 2) { + event_code = MEC_EJECT_REQUESTED; + atapi->eject(); + } + } - buffer[4] = event_code; - buffer[5] = media_status; - buffer[6] = 0; - buffer[7] = 0; + buffer[4] = event_code; + buffer[5] = media_status; + buffer[6] = 0; + buffer[7] = 0; - return 8; + return 8; } static void ide_padstr8(uint8_t *buf, int buf_size, const char *src) { - int i; + int i; - for (i = 0; i < buf_size; i++) { - if (*src != '\0') { - buf[i] = *src++; - } else { - buf[i] = ' '; - } - } + for (i = 0; i < buf_size; i++) { + if (*src != '\0') { + buf[i] = *src++; + } else { + buf[i] = ' '; + } + } } static void *scsi_cd_init(scsi_bus_t *bus, int id) { - scsi_cd_data_t *data = malloc(sizeof(scsi_cd_data_t)); - memset(data, 0, sizeof(scsi_cd_data_t)); + scsi_cd_data_t *data = malloc(sizeof(scsi_cd_data_t)); + memset(data, 0, sizeof(scsi_cd_data_t)); - data->bus = bus; - data->id = id; + data->bus = bus; + data->id = id; - page_flags[GPMODE_CDROM_AUDIO_PAGE] &= 0xFD; /* Clear changed flag for CDROM AUDIO mode page. */ - memset(mode_pages_in[GPMODE_CDROM_AUDIO_PAGE], 0, 256); /* Clear the page itself. */ - page_flags[GPMODE_CDROM_AUDIO_PAGE] &= ~PAGE_CHANGED; + page_flags[GPMODE_CDROM_AUDIO_PAGE] &= 0xFD; /* Clear changed flag for CDROM AUDIO mode page. */ + memset(mode_pages_in[GPMODE_CDROM_AUDIO_PAGE], 0, 256); /* Clear the page itself. */ + page_flags[GPMODE_CDROM_AUDIO_PAGE] &= ~PAGE_CHANGED; - timer_add(&data->callback_timer, scsi_cd_callback, data, 0); + timer_add(&data->callback_timer, scsi_cd_callback, data, 0); - cd_data = data; - cd_set_speed(cd_speed); - cd_set_model(cd_model); + cd_data = data; + cd_set_speed(cd_speed); + cd_set_model(cd_model); - return data; + return data; } static void *scsi_cd_atapi_init(scsi_bus_t *bus, int id, atapi_device_t *atapi_dev) { - scsi_cd_data_t *data = scsi_cd_init(bus, id); + scsi_cd_data_t *data = scsi_cd_init(bus, id); - data->is_atapi = 1; - data->atapi_dev = atapi_dev; + data->is_atapi = 1; + data->atapi_dev = atapi_dev; - return data; + return data; } static void scsi_cd_close(void *p) { - scsi_cd_data_t *data = p; + scsi_cd_data_t *data = p; - cd_data = NULL; - free(data); + cd_data = NULL; + free(data); } static void scsi_cd_reset(void *p) { - scsi_cd_data_t *data = p; + scsi_cd_data_t *data = p; - timer_disable(&data->callback_timer); - data->cmd_pos = CMD_POS_IDLE; + timer_disable(&data->callback_timer); + data->cmd_pos = CMD_POS_IDLE; } -static void scsi_cd_illegal(scsi_cd_data_t *data) { - atapi_cmd_error(data, KEY_ILLEGAL_REQ, ASC_INVALID_LUN, 0); -} +static void scsi_cd_illegal(scsi_cd_data_t *data) { atapi_cmd_error(data, KEY_ILLEGAL_REQ, ASC_INVALID_LUN, 0); } /** * Fill in ide->buffer with the output of the ATAPI "MODE SENSE" command @@ -710,1014 +670,1038 @@ static void scsi_cd_illegal(scsi_cd_data_t *data) { * @return Offset within the buffer after the end of the data */ static uint32_t ide_atapi_mode_sense(scsi_cd_data_t *data, uint32_t pos, uint8_t type) { - uint8_t *buf = (uint8_t *)data->data_in; -// pclog("ide_atapi_mode_sense %02X\n",type); - if (type == GPMODE_ALL_PAGES || type == GPMODE_R_W_ERROR_PAGE) { - /* &01 - Read error recovery */ - buf[pos++] = GPMODE_R_W_ERROR_PAGE; - buf[pos++] = 6; /* Page length */ - buf[pos++] = 0; /* Error recovery parameters */ - buf[pos++] = 5; /* Read retry count */ - buf[pos++] = 0; /* Reserved */ - buf[pos++] = 0; /* Reserved */ - buf[pos++] = 0; /* Reserved */ - buf[pos++] = 0; /* Reserved */ - } + uint8_t *buf = (uint8_t *)data->data_in; + // pclog("ide_atapi_mode_sense %02X\n",type); + if (type == GPMODE_ALL_PAGES || type == GPMODE_R_W_ERROR_PAGE) { + /* &01 - Read error recovery */ + buf[pos++] = GPMODE_R_W_ERROR_PAGE; + buf[pos++] = 6; /* Page length */ + buf[pos++] = 0; /* Error recovery parameters */ + buf[pos++] = 5; /* Read retry count */ + buf[pos++] = 0; /* Reserved */ + buf[pos++] = 0; /* Reserved */ + buf[pos++] = 0; /* Reserved */ + buf[pos++] = 0; /* Reserved */ + } - if (type == GPMODE_ALL_PAGES || type == GPMODE_CDROM_PAGE) { - /* &0D - CD-ROM Parameters */ - buf[pos++] = GPMODE_CDROM_PAGE; - buf[pos++] = 6; /* Page length */ - buf[pos++] = 0; /* Reserved */ - buf[pos++] = 1; /* Inactivity time multiplier *NEEDED BY RISCOS* value is a guess */ - buf[pos++] = 0; - buf[pos++] = 60; /* MSF settings */ - buf[pos++] = 0; - buf[pos++] = 75; /* MSF settings */ - } + if (type == GPMODE_ALL_PAGES || type == GPMODE_CDROM_PAGE) { + /* &0D - CD-ROM Parameters */ + buf[pos++] = GPMODE_CDROM_PAGE; + buf[pos++] = 6; /* Page length */ + buf[pos++] = 0; /* Reserved */ + buf[pos++] = 1; /* Inactivity time multiplier *NEEDED BY RISCOS* value is a guess */ + buf[pos++] = 0; + buf[pos++] = 60; /* MSF settings */ + buf[pos++] = 0; + buf[pos++] = 75; /* MSF settings */ + } - if (type == GPMODE_ALL_PAGES || type == GPMODE_CDROM_AUDIO_PAGE) { - /* &0e - CD-ROM Audio Control Parameters */ - buf[pos++] = GPMODE_CDROM_AUDIO_PAGE; - buf[pos++] = 0xE; /* Page length */ - if (page_flags[GPMODE_CDROM_AUDIO_PAGE] & PAGE_CHANGED) { - int i; + if (type == GPMODE_ALL_PAGES || type == GPMODE_CDROM_AUDIO_PAGE) { + /* &0e - CD-ROM Audio Control Parameters */ + buf[pos++] = GPMODE_CDROM_AUDIO_PAGE; + buf[pos++] = 0xE; /* Page length */ + if (page_flags[GPMODE_CDROM_AUDIO_PAGE] & PAGE_CHANGED) { + int i; - for (i = 0; i < 14; i++) { - buf[pos++] = mode_pages_in[GPMODE_CDROM_AUDIO_PAGE][i]; - } - } else { - buf[pos++] = 5; /* Reserved */ - buf[pos++] = 4; /* Reserved */ - buf[pos++] = 0; /* Reserved */ - buf[pos++] = 0x80; /* Reserved */ - buf[pos++] = 0; - buf[pos++] = 75; /* Logical audio block per second */ - buf[pos++] = 1; /* CDDA Output Port 0 Channel Selection */ - buf[pos++] = 0xFF; /* CDDA Output Port 0 Volume */ - buf[pos++] = 2; /* CDDA Output Port 1 Channel Selection */ - buf[pos++] = 0xFF; /* CDDA Output Port 1 Volume */ - buf[pos++] = 0; /* CDDA Output Port 2 Channel Selection */ - buf[pos++] = 0; /* CDDA Output Port 2 Volume */ - buf[pos++] = 0; /* CDDA Output Port 3 Channel Selection */ - buf[pos++] = 0; /* CDDA Output Port 3 Volume */ - } - } + for (i = 0; i < 14; i++) { + buf[pos++] = mode_pages_in[GPMODE_CDROM_AUDIO_PAGE][i]; + } + } else { + buf[pos++] = 5; /* Reserved */ + buf[pos++] = 4; /* Reserved */ + buf[pos++] = 0; /* Reserved */ + buf[pos++] = 0x80; /* Reserved */ + buf[pos++] = 0; + buf[pos++] = 75; /* Logical audio block per second */ + buf[pos++] = 1; /* CDDA Output Port 0 Channel Selection */ + buf[pos++] = 0xFF; /* CDDA Output Port 0 Volume */ + buf[pos++] = 2; /* CDDA Output Port 1 Channel Selection */ + buf[pos++] = 0xFF; /* CDDA Output Port 1 Volume */ + buf[pos++] = 0; /* CDDA Output Port 2 Channel Selection */ + buf[pos++] = 0; /* CDDA Output Port 2 Volume */ + buf[pos++] = 0; /* CDDA Output Port 3 Channel Selection */ + buf[pos++] = 0; /* CDDA Output Port 3 Volume */ + } + } - if (type == GPMODE_ALL_PAGES || type == GPMODE_CAPABILITIES_PAGE) { -// pclog("Capabilities page\n"); - /* &2A - CD-ROM capabilities and mechanical status */ - buf[pos++] = GPMODE_CAPABILITIES_PAGE; - buf[pos++] = 0x12; /* Page length */ - buf[pos++] = 0; - buf[pos++] = 0; /* CD-R methods */ - buf[pos++] = 1; /* Supports audio play, not multisession */ - buf[pos++] = 0; /* Some other stuff not supported */ - buf[pos++] = 0; /* Some other stuff not supported (lock state + eject) */ - buf[pos++] = 0x03; /* Some other stuff not supported */ - buf[pos++] = (uint8_t)((data->max_speed * 176) >> 8); - buf[pos++] = (uint8_t)(data->max_speed * 176); /* Maximum speed */ - buf[pos++] = 1; - buf[pos++] = 0; /* Number of audio levels - on and off only */ - buf[pos++] = 0; - buf[pos++] = 0; /* Buffer size - none */ - buf[pos++] = (uint8_t)((data->cur_speed * 176) >> 8); - buf[pos++] = (uint8_t)(data->cur_speed * 176); /* Current speed */ - buf[pos++] = 0; /* Reserved */ - buf[pos++] = 0; /* Drive digital format */ - buf[pos++] = 0; /* Reserved */ - buf[pos++] = 0; /* Reserved */ - } + if (type == GPMODE_ALL_PAGES || type == GPMODE_CAPABILITIES_PAGE) { + // pclog("Capabilities page\n"); + /* &2A - CD-ROM capabilities and mechanical status */ + buf[pos++] = GPMODE_CAPABILITIES_PAGE; + buf[pos++] = 0x12; /* Page length */ + buf[pos++] = 0; + buf[pos++] = 0; /* CD-R methods */ + buf[pos++] = 1; /* Supports audio play, not multisession */ + buf[pos++] = 0; /* Some other stuff not supported */ + buf[pos++] = 0; /* Some other stuff not supported (lock state + eject) */ + buf[pos++] = 0x03; /* Some other stuff not supported */ + buf[pos++] = (uint8_t)((data->max_speed * 176) >> 8); + buf[pos++] = (uint8_t)(data->max_speed * 176); /* Maximum speed */ + buf[pos++] = 1; + buf[pos++] = 0; /* Number of audio levels - on and off only */ + buf[pos++] = 0; + buf[pos++] = 0; /* Buffer size - none */ + buf[pos++] = (uint8_t)((data->cur_speed * 176) >> 8); + buf[pos++] = (uint8_t)(data->cur_speed * 176); /* Current speed */ + buf[pos++] = 0; /* Reserved */ + buf[pos++] = 0; /* Drive digital format */ + buf[pos++] = 0; /* Reserved */ + buf[pos++] = 0; /* Reserved */ + } - return pos; + return pos; } static void cdrom_mode_select(scsi_cd_data_t *data, int data_len) { - int len = data->data_out[1] | (data->data_out[0] << 8); - int pos = 8 + len; /*Skip over mode parameter header*/ + int len = data->data_out[1] | (data->data_out[0] << 8); + int pos = 8 + len; /*Skip over mode parameter header*/ - while (pos < data_len) { - int page_code = data->data_out[pos] & 0x3f; - len = data->data_out[pos + 1]; + while (pos < data_len) { + int page_code = data->data_out[pos] & 0x3f; + len = data->data_out[pos + 1]; - pos += 2; + pos += 2; - switch (page_code) { - case GPMODE_CDROM_AUDIO_PAGE: - if (len != 0xe) { - atapi_cmd_error(data, KEY_ILLEGAL_REQ, ASC_INV_FIELD_IN_CMD_PACKET, 0); - return; - } - memcpy(mode_pages_in[GPMODE_CDROM_AUDIO_PAGE], &data->data_out[pos], 0xe); - page_flags[GPMODE_CDROM_AUDIO_PAGE] |= PAGE_CHANGED; - pos += len; - break; + switch (page_code) { + case GPMODE_CDROM_AUDIO_PAGE: + if (len != 0xe) { + atapi_cmd_error(data, KEY_ILLEGAL_REQ, ASC_INV_FIELD_IN_CMD_PACKET, 0); + return; + } + memcpy(mode_pages_in[GPMODE_CDROM_AUDIO_PAGE], &data->data_out[pos], 0xe); + page_flags[GPMODE_CDROM_AUDIO_PAGE] |= PAGE_CHANGED; + pos += len; + break; - case GPMODE_R_W_ERROR_PAGE: - if (len != 0x6) { - atapi_cmd_error(data, KEY_ILLEGAL_REQ, ASC_INV_FIELD_IN_CMD_PACKET, 0); - return; - } - pos += len; - break; + case GPMODE_R_W_ERROR_PAGE: + if (len != 0x6) { + atapi_cmd_error(data, KEY_ILLEGAL_REQ, ASC_INV_FIELD_IN_CMD_PACKET, 0); + return; + } + pos += len; + break; - case GPMODE_CDROM_PAGE: - if (len != 0x6) { - atapi_cmd_error(data, KEY_ILLEGAL_REQ, ASC_INV_FIELD_IN_CMD_PACKET, 0); - return; - } - pos += len; - break; + case GPMODE_CDROM_PAGE: + if (len != 0x6) { + atapi_cmd_error(data, KEY_ILLEGAL_REQ, ASC_INV_FIELD_IN_CMD_PACKET, 0); + return; + } + pos += len; + break; - case GPMODE_CAPABILITIES_PAGE: - if (len != 0x12) { - atapi_cmd_error(data, KEY_ILLEGAL_REQ, ASC_INV_FIELD_IN_CMD_PACKET, 0); - return; - } - pos += len; - break; + case GPMODE_CAPABILITIES_PAGE: + if (len != 0x12) { + atapi_cmd_error(data, KEY_ILLEGAL_REQ, ASC_INV_FIELD_IN_CMD_PACKET, 0); + return; + } + pos += len; + break; - default:atapi_cmd_error(data, KEY_ILLEGAL_REQ, ASC_INV_FIELD_IN_CMD_PACKET, 0); - return; - } - } + default: + atapi_cmd_error(data, KEY_ILLEGAL_REQ, ASC_INV_FIELD_IN_CMD_PACKET, 0); + return; + } + } } uint32_t atapi_get_cd_channel(int channel) { - return (page_flags[GPMODE_CDROM_AUDIO_PAGE] & PAGE_CHANGED) ? mode_pages_in[GPMODE_CDROM_AUDIO_PAGE][channel ? 8 : 6] : (channel + 1); + return (page_flags[GPMODE_CDROM_AUDIO_PAGE] & PAGE_CHANGED) ? mode_pages_in[GPMODE_CDROM_AUDIO_PAGE][channel ? 8 : 6] + : (channel + 1); } uint32_t atapi_get_cd_volume(int channel) { - return (page_flags[GPMODE_CDROM_AUDIO_PAGE] & PAGE_CHANGED) ? mode_pages_in[GPMODE_CDROM_AUDIO_PAGE][channel ? 9 : 7] : 0xFF; + return (page_flags[GPMODE_CDROM_AUDIO_PAGE] & PAGE_CHANGED) ? mode_pages_in[GPMODE_CDROM_AUDIO_PAGE][channel ? 9 : 7] + : 0xFF; } static int scsi_cd_command(uint8_t *cdb, void *p) { - scsi_cd_data_t *data = p; - uint8_t rcdmode = 0; - int c; - int len; - int msf; - int pos = 0; -// unsigned char temp; - uint32_t size; - int is_error; - uint8_t page_code; - int max_len; - unsigned idx = 0; - unsigned size_idx; - unsigned preamble_len; - int toc_format; - int temp_command; - int alloc_length; - int completed; - int changed; - - if (!data->received_cdb) - memcpy(data->cdb, cdb, CDB_MAX_LEN); - - if ((cdb[0] != SCSI_REQUEST_SENSE/* && cdb[0] != SCSI_INQUIRY*/) && (cdb[1] & 0xe0)) { - pclog("non-zero LUN\n"); - /*Non-zero LUN - abort command*/ - scsi_cd_illegal(data); - return BUS_CD | BUS_IO; - } - - pclog("New CD command %02X %i\n", cdb[0], ins); - msf = cdb[1] & 2; - - is_error = 0; - changed = atapi->medium_changed(); - - /*If UNIT_ATTENTION is set, error out with NOT_READY. - VIDE-CDD.SYS will then issue a READ_TOC, which can pass through UNIT_ATTENTION and will clear sense. - NT 3.1 / AZTIDECD.SYS will then issue a REQUEST_SENSE, which can also pass through UNIT_ATTENTION but will clear sense AFTER sending it back. - In any case, if the command cannot pass through, set our state to errored.*/ - if (!(atapi_cmd_table[cdb[0]] & ALLOW_UA) && data->sense_key == SENSE_UNIT_ATTENTION) { -// fatal("atapi_cmd_error(ide, data->sense_key, data->asc);\n"); - is_error = 1; - } - /*Unless the command issued was a REQUEST_SENSE or TEST_UNIT_READY, clear sense. - This is important because both VIDE-CDD.SYS and NT 3.1 / AZTIDECD.SYS rely on this behaving VERY specifically. - VIDE-CDD.SYS will clear sense through READ_TOC, while NT 3.1 / AZTIDECD.SYS will issue a REQUEST_SENSE.*/ - if ((cdb[0] != GPCMD_REQUEST_SENSE) && (cdb[0] != GPCMD_TEST_UNIT_READY)) { - /* GPCMD_TEST_UNIT_READY is NOT supposed to clear sense! */ - atapi_sense_clear(data, cdb[0], 1); - } - - /*If our state has been set to errored, clear it, and return.*/ - if (is_error) { -// fatal("Clear error state\n"); - is_error = 0; - return SCSI_PHASE_STATUS; - } - - if ((atapi_cmd_table[cdb[0]] & CHECK_READY) && !atapi->ready()) { - atapi_cmd_error(data, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT, 0); - return SCSI_PHASE_STATUS; - } - if ((atapi_cmd_table[cdb[0]] & CHECK_READY) && changed) { - pclog("Medium changed\n"); - atapi_cmd_error(data, SENSE_UNIT_ATTENTION, ASC_MEDIUM_MAY_HAVE_CHANGED, 0); - return SCSI_PHASE_STATUS; - } - - data->prev_status = data->cd_status; - data->cd_status = atapi->status(); - if (((data->prev_status == CD_STATUS_PLAYING) || (data->prev_status == CD_STATUS_PAUSED)) && ((data->cd_status != CD_STATUS_PLAYING) && (data->cd_status != CD_STATUS_PAUSED))) - completed = 1; - else - completed = 0; - -// pclog(" msf %i completed %i\n", msf, completed); - - data->status = STATUS_GOOD; - - switch (cdb[0]) { - case GPCMD_TEST_UNIT_READY:data->cmd_pos = CMD_POS_IDLE; - return SCSI_PHASE_STATUS; - - case SCSI_REZERO_UNIT: - if (data->cmd_pos == CMD_POS_IDLE) { - uint32_t old_pos = data->cdpos; - int seek_time; - - data->cdpos = 0; - - seek_time = get_seek_time(data, old_pos, data->cdpos); - if (seek_time) { - data->cmd_pos = CMD_POS_WAIT; - data->new_cmd_pos = CMD_POS_COMPLETE; - data->wait_time = seek_time; - timer_set_delay_u64(&data->callback_timer, 1000 * TIMER_USEC); - return SCSI_PHASE_COMMAND; - } - } - data->cmd_pos = CMD_POS_IDLE; - return SCSI_PHASE_STATUS; - - case SCSI_REQUEST_SENSE: /* Used by ROS 4+ */ -// pclog("CD REQ SENSE\n"); - alloc_length = cdb[4]; - temp_command = cdb[0]; - //atapi_command_send_init(ide, temp_command, 18, alloc_length); - - /*Will return 18 bytes of 0*/ - memset(data->data_in, 0, 512); - - data->data_in[0] = 0x80 | 0x70; - - if ((data->sense_key > 0) || (data->cd_status < CD_STATUS_PLAYING)) { - if (completed) { -// pclog("completed\n"); - data->data_in[2] = SENSE_ILLEGAL_REQUEST; - data->data_in[12] = ASC_AUDIO_PLAY_OPERATION; - data->data_in[13] = ASCQ_AUDIO_PLAY_OPERATION_COMPLETED; - } else { -// pclog("!completed %02x %02x %02x\n", data->sense_key, data->asc, data->ascq); - data->data_in[2] = data->sense_key; - data->data_in[12] = data->asc; - data->data_in[13] = data->ascq; - } - } else { - data->data_in[2] = SENSE_ILLEGAL_REQUEST; - data->data_in[12] = ASC_AUDIO_PLAY_OPERATION; - data->data_in[13] = (data->cd_status == CD_STATUS_PLAYING) ? ASCQ_AUDIO_PLAY_OPERATION_IN_PROGRESS : ASCQ_AUDIO_PLAY_OPERATION_PAUSED; - } - - data->data_in[7] = 0; - - /* Clear the sense stuff as per the spec. */ - atapi_sense_clear(data, temp_command, 0); - - data->bytes_expected = data->data_pos_write = MIN(alloc_length, 18); - return alloc_length ? SCSI_PHASE_DATA_IN : SCSI_PHASE_STATUS; - - case SCSI_SEEK_6: - if (data->cmd_pos == CMD_POS_IDLE) { - uint32_t old_pos = data->cdpos; - int seek_time; - - data->cdpos = (((uint32_t)cdb[1] & 0x1f) << 16) | ((uint32_t)cdb[2] << 8) | (uint32_t)cdb[3]; - - seek_time = get_seek_time(data, old_pos, data->cdpos); - if (seek_time) { - data->cmd_pos = CMD_POS_WAIT; - data->new_cmd_pos = CMD_POS_COMPLETE; - data->wait_time = seek_time; - timer_set_delay_u64(&data->callback_timer, 1000 * TIMER_USEC); - return SCSI_PHASE_COMMAND; - } - } - data->cmd_pos = CMD_POS_IDLE; - return SCSI_PHASE_STATUS; - - case GPCMD_SET_SPEED:data->cur_speed = (cdb[3] | (cdb[2] << 8)) / 176; - if (data->cur_speed < 1) - data->cur_speed = 1; - else if (data->cur_speed > data->max_speed) - data->cur_speed = data->max_speed; - data->cmd_pos = CMD_POS_IDLE; - return SCSI_PHASE_STATUS; - - case GPCMD_MECHANISM_STATUS: /*0xbd*/ - alloc_length = (cdb[7] << 16) | (cdb[8] << 8) | cdb[9]; - - if (alloc_length == 0) - fatal("Zero allocation length to MECHANISM STATUS not impl.\n"); - - data->data_in[0] = 0; - data->data_in[1] = 0; - data->data_in[2] = 0; - data->data_in[3] = 0; - data->data_in[4] = 0; - data->data_in[5] = 1; - data->data_in[6] = 0; - data->data_in[7] = 0; - // len = 8; - - data->data_pos_read = 0; - data->bytes_expected = data->data_pos_write = MIN(alloc_length, 8); - return alloc_length ? SCSI_PHASE_DATA_IN : SCSI_PHASE_STATUS; - - case GPCMD_READ_TOC_PMA_ATIP: -// pclog("Read TOC ready? %08X\n",ide); - toc_format = cdb[2] & 0xf; - if (toc_format == 0) - toc_format = (cdb[9] >> 6) & 3; - alloc_length = cdb[8] + (cdb[7] << 8); - switch (toc_format) { - case 0: /*Normal*/ -// pclog("ATAPI: READ TOC type requested: Normal\n"); - len = atapi->readtoc(data->data_in, cdb[6], msf, alloc_length, 0); - break; - case 1: /*Multi session*/ -// pclog("ATAPI: READ TOC type requested: Multi-session\n"); - len = atapi->readtoc_session(data->data_in, msf, alloc_length); - data->data_in[0] = 0; - data->data_in[1] = 0xA; - break; - case 2: /*Raw*/ -// pclog("ATAPI: READ TOC type requested: Raw TOC\n"); - len = atapi->readtoc_raw(data->data_in, alloc_length); - break; - default:atapi_cmd_error(data, SENSE_ILLEGAL_REQUEST, ASC_LBA_OUT_OF_RANGE, 0); - data->cmd_pos = CMD_POS_IDLE; - return SCSI_PHASE_STATUS; - } - data->data_pos_read = 0; - data->bytes_expected = data->data_pos_write = MIN(alloc_length, len); - return alloc_length ? SCSI_PHASE_DATA_IN : SCSI_PHASE_STATUS; - - case GPCMD_READ_CD: -// pclog("Read CD : start LBA %02X%02X%02X%02X Length %02X%02X%02X Flags %02X\n",cdb[2],cdb[3],cdb[4],cdb[5],cdb[6],cdb[7],cdb[8],cdb[9]); - rcdmode = cdb[9] & 0xF8; - if ((rcdmode != 0x10) && (rcdmode != 0xF8)) { - atapi_cmd_error(data, SENSE_ILLEGAL_REQUEST, ASC_ILLEGAL_OPCODE, 0); - data->cmd_pos = CMD_POS_IDLE; - return SCSI_PHASE_STATUS; - } - - if (data->cmd_pos == CMD_POS_IDLE) { - uint32_t old_pos = data->cdpos; - int seek_time; - - data->cdlen = (cdb[6] << 16) | (cdb[7] << 8) | cdb[8]; - data->cdpos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - - data->cmd_pos = CMD_POS_START_SECTOR; - data->bytes_expected = data->cdlen * ((rcdmode == 0x10) ? 2048 : 2352); - if (data->is_atapi) { - if (rcdmode == 0x10) - atapi_set_transfer_granularity(data->atapi_dev, 2048); - else - atapi_set_transfer_granularity(data->atapi_dev, 2352); - } - - seek_time = get_seek_time(data, old_pos, data->cdpos); - if (seek_time) { - data->cmd_pos = CMD_POS_WAIT; - data->new_cmd_pos = CMD_POS_START_SECTOR; - data->wait_time = seek_time; - timer_set_delay_u64(&data->callback_timer, 1000 * TIMER_USEC); - return SCSI_PHASE_COMMAND; - } - } - if (data->cmd_pos == CMD_POS_WAIT) - return SCSI_PHASE_COMMAND; - if (!data->cdlen) { - data->cmd_pos = CMD_POS_IDLE; - return SCSI_PHASE_STATUS; - } - if (data->cmd_pos == CMD_POS_START_SECTOR) { - uint64_t time = (((uint64_t)SECTOR_TIME * TIMER_USEC) / data->cur_speed) * (uint64_t)data->cdlen; - - data->cmd_pos = CMD_POS_WAIT; - data->new_cmd_pos = CMD_POS_TRANSFER; - - if (time > (TIMER_USEC * 1000ull)) { - data->wait_time = (int)(time / (TIMER_USEC * 1000ull)); - timer_set_delay_u64(&data->callback_timer, time % (TIMER_USEC * 1000ull)); - } else { - timer_set_delay_u64(&data->callback_timer, time); - data->wait_time = 1; - } - return SCSI_PHASE_COMMAND; - } - - if (rcdmode == 0x10) { - c = MIN(data->cdlen, MAX_NR_SECTORS); - if (atapi->readsector(data->data_in, data->cdpos, c)) { -// pclog("Read sector failed\n"); - atapi_cmd_error(data, SENSE_ILLEGAL_REQUEST, ASC_LBA_OUT_OF_RANGE, 0); - data->cmd_pos = CMD_POS_IDLE; - return SCSI_PHASE_STATUS; - } - data->cdpos += c; - data->cdlen -= c; - } else { - for (c = 0; c < MAX_NR_SECTORS; c++) { - atapi->readsector_raw(&data->data_in[c * 2352], data->cdpos); - - data->cdpos++; - data->cdlen--; - if (!data->cdlen) { - c++; - break; - } - } - } - readflash_set(READFLASH_HDC, data->id); - - data->data_pos_read = 0; - data->data_pos_write = c * ((rcdmode == 0x10) ? 2048 : 2352); - return SCSI_PHASE_DATA_IN; - - case GPCMD_READ_6: - case GPCMD_READ_10: - case GPCMD_READ_12: -// pclog("Read: cmd_pos=%i cdlen=%i %p\n", data->cmd_pos, data->cdlen, &data->data_in[0]); - -// readcdmode = 0; - if (data->cmd_pos == CMD_POS_IDLE) { - uint32_t old_pos = data->cdpos; - int seek_time; - - if (cdb[0] == GPCMD_READ_6) { - data->cdlen = cdb[4]; - data->cdpos = (((uint32_t)cdb[1] & 0x1f) << 16) | ((uint32_t)cdb[2] << 8) | (uint32_t)cdb[3]; - } else if (cdb[0] == GPCMD_READ_10) { - data->cdlen = (cdb[7] << 8) | cdb[8]; - data->cdpos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - } else { - data->cdlen = ((uint32_t)cdb[6] << 24) | ((uint32_t)cdb[7] << 16) | ((uint32_t)cdb[8] << 8) | (uint32_t)cdb[9]; - data->cdpos = ((uint32_t)cdb[2] << 24) | ((uint32_t)cdb[3] << 16) | ((uint32_t)cdb[4] << 8) | (uint32_t)cdb[5]; - } -// pclog("cdpos=%08x cdlen=%08x\n", data->cdpos, data->cdlen); - - data->cmd_pos = CMD_POS_START_SECTOR; - data->bytes_expected = data->cdlen * 2048; - if (data->is_atapi) - atapi_set_transfer_granularity(data->atapi_dev, 2048); - - seek_time = get_seek_time(data, old_pos, data->cdpos); - - if (seek_time) { - data->cmd_pos = CMD_POS_WAIT; - data->new_cmd_pos = CMD_POS_START_SECTOR; - data->wait_time = seek_time; - timer_set_delay_u64(&data->callback_timer, 1000 * TIMER_USEC); - return SCSI_PHASE_COMMAND; - } - } - if (data->cmd_pos == CMD_POS_WAIT) - return SCSI_PHASE_COMMAND; - if (!data->cdlen) { - data->cmd_pos = CMD_POS_IDLE; - return SCSI_PHASE_STATUS; - } - if (data->cmd_pos == CMD_POS_START_SECTOR) { - uint64_t time = (((uint64_t)SECTOR_TIME * TIMER_USEC) / data->cur_speed) * (uint64_t)data->cdlen; - - data->cmd_pos = CMD_POS_WAIT; - data->new_cmd_pos = CMD_POS_TRANSFER; - - if (time > (TIMER_USEC * 1000ull)) { - data->wait_time = (int)(time / (TIMER_USEC * 1000ull)); - timer_set_delay_u64(&data->callback_timer, time % (TIMER_USEC * 1000ull)); - } else { - timer_set_delay_u64(&data->callback_timer, time); - data->wait_time = 1; - } - return SCSI_PHASE_COMMAND; - } - - readflash_set(READFLASH_HDC, data->id); - c = MIN(data->cdlen, MAX_NR_SECTORS); - if (atapi->readsector(data->data_in, data->cdpos, c)) { -// pclog("Read sector failed\n"); - atapi_cmd_error(data, SENSE_ILLEGAL_REQUEST, ASC_LBA_OUT_OF_RANGE, 0); - data->cmd_pos = CMD_POS_IDLE; - return SCSI_PHASE_STATUS; - } - data->cdpos += c; - data->cdlen -= c; - - data->data_pos_read = 0; - data->data_pos_write = c * 2048; - return SCSI_PHASE_DATA_IN; - - case GPCMD_READ_HEADER:alloc_length = cdb[8] | (cdb[7] << 8); - if (msf) { - atapi_cmd_error(data, SENSE_ILLEGAL_REQUEST, ASC_ILLEGAL_OPCODE, 0); - return SCSI_PHASE_STATUS; - } - for (c = 0; c < 4; c++) - data->data_in[c + 4] = cdb[c + 2]; - data->data_in[0] = 1; /*2048 bytes user data*/ - data->data_in[1] = data->data_in[2] = data->data_in[3] = 0; - - data->bytes_expected = data->data_pos_write = MIN(6, alloc_length); - return alloc_length ? SCSI_PHASE_DATA_IN : SCSI_PHASE_STATUS; - - case GPCMD_MODE_SENSE_6: - case GPCMD_MODE_SENSE_10:temp_command = cdb[0]; - - if (temp_command == GPCMD_MODE_SENSE_6) - len = cdb[4]; - else - len = cdb[8] | (cdb[7] << 8); - - c = cdb[2] & 0x3F; - - memset(data->data_in, 0, len); - alloc_length = len; - // for (c=0;cdata_in[0] = len - 1; - data->data_in[1] = 3; /*120mm data CD-ROM*/ - } else { - len = ide_atapi_mode_sense(data, 8, c); - data->data_in[0] = (len - 2) >> 8; - data->data_in[1] = (len - 2) & 255; - data->data_in[2] = 3; /*120mm data CD-ROM*/ - } - - data->bytes_expected = data->data_pos_write = MIN(len, alloc_length); - data->cmd_pos = CMD_POS_IDLE; - return alloc_length ? SCSI_PHASE_DATA_IN : SCSI_PHASE_STATUS; - - case GPCMD_MODE_SELECT_6: - case GPCMD_MODE_SELECT_10: - if (data->cmd_pos == CMD_POS_IDLE) { - int len; - - if (cdb[0] == GPCMD_MODE_SELECT_6) { - len = cdb[4]; - data->prefix_len = 6; - } else { - len = (cdb[7] << 8) | cdb[8]; - data->prefix_len = 10; - } - - data->cmd_pos = CMD_POS_TRANSFER; - data->bytes_required = len; - return SCSI_PHASE_DATA_OUT; - } - if (data->bytes_received == data->bytes_required) { - cdrom_mode_select(data, data->bytes_required); - data->cmd_pos = CMD_POS_IDLE; - return SCSI_PHASE_STATUS; - } - return SCSI_PHASE_DATA_OUT; - - case GPCMD_GET_EVENT_STATUS_NOTIFICATION: /*0x4a*/ - temp_command = cdb[0]; - alloc_length = (cdb[7] << 16) | (cdb[8] << 8) | cdb[9]; - - { - struct __attribute__((__packed__)) { - 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; - - struct __attribute__((__packed__)) { - uint16_t len; - uint8_t notification_class; - uint8_t supported_events; - } *gesn_event_header; - unsigned int used_len; - - gesn_cdb = (void *)cdb; - gesn_event_header = (void *)data->data_in; - - /* 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. */ - atapi_cmd_error(data, SENSE_ILLEGAL_REQUEST, ASC_ILLEGAL_OPCODE, 0); - return SCSI_PHASE_STATUS; - } - - /* polling mode operation */ - - /* - * 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; - used_len = atapi_event_status(data->data_in); - } else { - gesn_event_header->notification_class = 0x80; /* No event available */ - used_len = sizeof(*gesn_event_header); - } - len = used_len; - gesn_event_header->len = used_len - sizeof(*gesn_event_header); - } - - data->bytes_expected = data->data_pos_write = MIN(alloc_length, len); - data->cmd_pos = CMD_POS_IDLE; - return alloc_length ? SCSI_PHASE_DATA_IN : SCSI_PHASE_STATUS; - - case GPCMD_READ_DISC_INFORMATION:alloc_length = cdb[8] | (cdb[7] << 8); - - data->data_in[1] = 32; - data->data_in[2] = 0xe; /* last session complete, disc finalized */ - data->data_in[3] = 1; /* first track on disc */ - data->data_in[4] = 1; /* # of sessions */ - data->data_in[5] = 1; /* first track of last session */ - data->data_in[6] = 1; /* last track of last session */ - data->data_in[7] = 0x20; /* unrestricted use */ - data->data_in[8] = 0x00; /* CD-ROM */ - - data->bytes_expected = data->data_pos_write = MIN(alloc_length, 34); - data->cmd_pos = CMD_POS_IDLE; - return alloc_length ? SCSI_PHASE_DATA_IN : SCSI_PHASE_STATUS; - - case GPCMD_PLAY_AUDIO_10: - case GPCMD_PLAY_AUDIO_12: - 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*/ - if (cdb[0] == GPCMD_PLAY_AUDIO_10) { - pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - len = (cdb[7] << 8) | cdb[8]; - } else if (cdb[0] == GPCMD_PLAY_AUDIO_MSF) { - pos = (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - len = (cdb[6] << 16) | (cdb[7] << 8) | cdb[8]; - } else { - pos = (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - len = (cdb[7] << 16) | (cdb[8] << 8) | cdb[9]; - } - - if ((cdrom_drive < 1) || (data->cd_status <= CD_STATUS_DATA_ONLY) || - !atapi->is_track_audio(pos, (cdb[0] == GPCMD_PLAY_AUDIO_MSF) ? 1 : 0)) { - atapi_cmd_error(data, SENSE_ILLEGAL_REQUEST, ASC_ILLEGAL_MODE_FOR_THIS_TRACK, 0); - return SCSI_PHASE_STATUS; - } - - atapi->playaudio(pos, len, (cdb[0] == GPCMD_PLAY_AUDIO_MSF) ? 1 : 0); - data->cmd_pos = CMD_POS_IDLE; - return SCSI_PHASE_STATUS; - - case GPCMD_READ_SUBCHANNEL:alloc_length = cdb[8] | (cdb[7] << 8); - if (cdb[3] != 1) { - atapi_cmd_error(data, SENSE_ILLEGAL_REQUEST, ASC_ILLEGAL_OPCODE, 0); - return SCSI_PHASE_STATUS; - } - pos = 0; - data->data_in[pos++] = 0; - data->data_in[pos++] = 0; /*Audio status*/ - data->data_in[pos++] = 0; - data->data_in[pos++] = 0; /*Subchannel length*/ - data->data_in[pos++] = 1; /*Format code*/ - data->data_in[1] = atapi->getcurrentsubchannel(&data->data_in[5], msf); -// pclog("Read subchannel complete - audio status %02X\n",idebufferb[1]); - len = 11 + 5; - if (!(cdb[2] & 0x40)) - len = 4; - - data->bytes_expected = data->data_pos_write = MIN(alloc_length, len); - return alloc_length ? SCSI_PHASE_DATA_IN : SCSI_PHASE_STATUS; - - case GPCMD_START_STOP_UNIT: - if (!cdb[4]) - atapi->stop(); - else if (cdb[4] == 2) - atapi->eject(); - else if (cdb[4] == 3) - atapi->load(); - data->cmd_pos = CMD_POS_IDLE; - return SCSI_PHASE_STATUS; - - case GPCMD_INQUIRY:page_code = cdb[2]; - max_len = cdb[4]; - alloc_length = max_len; - temp_command = cdb[0]; - - if (cdb[1] & 1) { - preamble_len = 4; - size_idx = 3; - - data->data_in[idx++] = 05; - data->data_in[idx++] = page_code; - data->data_in[idx++] = 0; - - idx++; - - switch (page_code) { - case 0x00:data->data_in[idx++] = 0x00; - data->data_in[idx++] = 0x83; - break; - - case 0x83: - if (idx + 24 > max_len) { - atapi_cmd_error(data, SENSE_ILLEGAL_REQUEST, ASC_DATA_PHASE_ERROR, 0); - return SCSI_PHASE_STATUS; - } - data->data_in[idx++] = 0x02; - data->data_in[idx++] = 0x00; - data->data_in[idx++] = 0x00; - data->data_in[idx++] = 20; - ide_padstr8(data->data_in + idx, 20, "53R141"); /* Serial */ - idx += 20; - - if (idx + 72 > max_len) { - goto atapi_out; - } - data->data_in[idx++] = 0x02; - data->data_in[idx++] = 0x01; - data->data_in[idx++] = 0x00; - data->data_in[idx++] = 68; - ide_padstr8(data->data_in + idx, 8, cd_models[cd_data->cur_model].vendor_8); /* Vendor */ - idx += 8; - ide_padstr8(data->data_in + idx, 40, cd_models[cd_data->cur_model].model_and_firmware_40); /* Product */ - idx += 40; - ide_padstr8(data->data_in + idx, 20, cd_models[cd_data->cur_model].serial_20); /* Product */ - idx += 20; - break; - - default:atapi_cmd_error(data, SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET, 0); - return SCSI_PHASE_STATUS; - } - } else { - preamble_len = 5; - size_idx = 4; - - data->data_in[0] = 5; /*CD-ROM*/ - data->data_in[1] = 0x80; /*Removable*/ - if (data->is_atapi) { - data->data_in[2] = 0; /*Not ANSI compliant*/ - data->data_in[3] = 0x21; /*ATAPI compliant*/ - } else { - data->data_in[2] = 2; /*SCSI-2 compliant*/ - data->data_in[3] = 0x02; - } - data->data_in[4] = 31; - data->data_in[5] = 0; - data->data_in[6] = 0; - data->data_in[7] = 0; - - ide_padstr8(data->data_in + 8, 8, cd_models[cd_data->cur_model].vendor_8); /* Vendor */ - ide_padstr8(data->data_in + 16, 16, cd_models[cd_data->cur_model].model_16); /* Product */ - ide_padstr8(data->data_in + 32, 4, cd_models[cd_data->cur_model].firmware_4); /* Revision */ - - idx = 36; - } - - atapi_out: - data->data_in[size_idx] = idx - preamble_len; - - data->bytes_expected = data->data_pos_write = MIN(alloc_length, idx); - return alloc_length ? SCSI_PHASE_DATA_IN : SCSI_PHASE_STATUS; - - case GPCMD_PREVENT_REMOVAL:data->cmd_pos = CMD_POS_IDLE; - return SCSI_PHASE_STATUS; - - case GPCMD_PAUSE_RESUME: - if (cdb[8] & 1) - atapi->resume(); - else - atapi->pause(); - data->cmd_pos = CMD_POS_IDLE; - return SCSI_PHASE_STATUS; - - case GPCMD_SEEK: - if (data->cmd_pos == CMD_POS_IDLE) { - uint32_t old_pos = data->cdpos; - int seek_time; - - data->cdpos = (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; - - atapi->seek(data->cdpos); - - seek_time = get_seek_time(data, old_pos, data->cdpos); - if (seek_time) { - data->cmd_pos = CMD_POS_WAIT; - data->new_cmd_pos = CMD_POS_COMPLETE; - data->wait_time = seek_time; - timer_set_delay_u64(&data->callback_timer, 1000 * TIMER_USEC); - return SCSI_PHASE_COMMAND; - } - } - data->cmd_pos = CMD_POS_IDLE; - return SCSI_PHASE_STATUS; - - case GPCMD_READ_CDROM_CAPACITY:size = atapi->size(); - scsi_add_data(data, (size >> 24) & 0xff); - scsi_add_data(data, (size >> 16) & 0xff); - scsi_add_data(data, (size >> 8) & 0xff); - scsi_add_data(data, size & 0xff); - scsi_add_data(data, (2048 >> 24) & 0xff); - scsi_add_data(data, (2048 >> 16) & 0xff); - scsi_add_data(data, (2048 >> 8) & 0xff); - scsi_add_data(data, 2048 & 0xff); - pclog("READ_CDROM_CAPACITY %08x\n", size); - data->cmd_pos = CMD_POS_IDLE; - return SCSI_PHASE_DATA_IN; - - case GPCMD_STOP_PLAY_SCAN:atapi->stop(); - data->cmd_pos = CMD_POS_IDLE; - return SCSI_PHASE_STATUS; - - case GPCMD_SEND_DVD_STRUCTURE: - default:atapi_cmd_error(data, SENSE_ILLEGAL_REQUEST, ASC_ILLEGAL_OPCODE, 0); - return SCSI_PHASE_STATUS; - } + scsi_cd_data_t *data = p; + uint8_t rcdmode = 0; + int c; + int len; + int msf; + int pos = 0; + // unsigned char temp; + uint32_t size; + int is_error; + uint8_t page_code; + int max_len; + unsigned idx = 0; + unsigned size_idx; + unsigned preamble_len; + int toc_format; + int temp_command; + int alloc_length; + int completed; + int changed; + + if (!data->received_cdb) + memcpy(data->cdb, cdb, CDB_MAX_LEN); + + if ((cdb[0] != SCSI_REQUEST_SENSE /* && cdb[0] != SCSI_INQUIRY*/) && (cdb[1] & 0xe0)) { + pclog("non-zero LUN\n"); + /*Non-zero LUN - abort command*/ + scsi_cd_illegal(data); + return BUS_CD | BUS_IO; + } + + pclog("New CD command %02X %i\n", cdb[0], ins); + msf = cdb[1] & 2; + + is_error = 0; + changed = atapi->medium_changed(); + + /*If UNIT_ATTENTION is set, error out with NOT_READY. + VIDE-CDD.SYS will then issue a READ_TOC, which can pass through UNIT_ATTENTION and will clear sense. + NT 3.1 / AZTIDECD.SYS will then issue a REQUEST_SENSE, which can also pass through UNIT_ATTENTION but will clear sense + AFTER sending it back. In any case, if the command cannot pass through, set our state to errored.*/ + if (!(atapi_cmd_table[cdb[0]] & ALLOW_UA) && data->sense_key == SENSE_UNIT_ATTENTION) { + // fatal("atapi_cmd_error(ide, data->sense_key, data->asc);\n"); + is_error = 1; + } + /*Unless the command issued was a REQUEST_SENSE or TEST_UNIT_READY, clear sense. + This is important because both VIDE-CDD.SYS and NT 3.1 / AZTIDECD.SYS rely on this behaving VERY specifically. + VIDE-CDD.SYS will clear sense through READ_TOC, while NT 3.1 / AZTIDECD.SYS will issue a REQUEST_SENSE.*/ + if ((cdb[0] != GPCMD_REQUEST_SENSE) && (cdb[0] != GPCMD_TEST_UNIT_READY)) { + /* GPCMD_TEST_UNIT_READY is NOT supposed to clear sense! */ + atapi_sense_clear(data, cdb[0], 1); + } + + /*If our state has been set to errored, clear it, and return.*/ + if (is_error) { + // fatal("Clear error state\n"); + is_error = 0; + return SCSI_PHASE_STATUS; + } + + if ((atapi_cmd_table[cdb[0]] & CHECK_READY) && !atapi->ready()) { + atapi_cmd_error(data, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT, 0); + return SCSI_PHASE_STATUS; + } + if ((atapi_cmd_table[cdb[0]] & CHECK_READY) && changed) { + pclog("Medium changed\n"); + atapi_cmd_error(data, SENSE_UNIT_ATTENTION, ASC_MEDIUM_MAY_HAVE_CHANGED, 0); + return SCSI_PHASE_STATUS; + } + + data->prev_status = data->cd_status; + data->cd_status = atapi->status(); + if (((data->prev_status == CD_STATUS_PLAYING) || (data->prev_status == CD_STATUS_PAUSED)) && + ((data->cd_status != CD_STATUS_PLAYING) && (data->cd_status != CD_STATUS_PAUSED))) + completed = 1; + else + completed = 0; + + // pclog(" msf %i completed %i\n", msf, completed); + + data->status = STATUS_GOOD; + + switch (cdb[0]) { + case GPCMD_TEST_UNIT_READY: + data->cmd_pos = CMD_POS_IDLE; + return SCSI_PHASE_STATUS; + + case SCSI_REZERO_UNIT: + if (data->cmd_pos == CMD_POS_IDLE) { + uint32_t old_pos = data->cdpos; + int seek_time; + + data->cdpos = 0; + + seek_time = get_seek_time(data, old_pos, data->cdpos); + if (seek_time) { + data->cmd_pos = CMD_POS_WAIT; + data->new_cmd_pos = CMD_POS_COMPLETE; + data->wait_time = seek_time; + timer_set_delay_u64(&data->callback_timer, 1000 * TIMER_USEC); + return SCSI_PHASE_COMMAND; + } + } + data->cmd_pos = CMD_POS_IDLE; + return SCSI_PHASE_STATUS; + + case SCSI_REQUEST_SENSE: /* Used by ROS 4+ */ + // pclog("CD REQ SENSE\n"); + alloc_length = cdb[4]; + temp_command = cdb[0]; + // atapi_command_send_init(ide, temp_command, 18, alloc_length); + + /*Will return 18 bytes of 0*/ + memset(data->data_in, 0, 512); + + data->data_in[0] = 0x80 | 0x70; + + if ((data->sense_key > 0) || (data->cd_status < CD_STATUS_PLAYING)) { + if (completed) { + // pclog("completed\n"); + data->data_in[2] = SENSE_ILLEGAL_REQUEST; + data->data_in[12] = ASC_AUDIO_PLAY_OPERATION; + data->data_in[13] = ASCQ_AUDIO_PLAY_OPERATION_COMPLETED; + } else { + // pclog("!completed %02x %02x %02x\n", data->sense_key, data->asc, + // data->ascq); + data->data_in[2] = data->sense_key; + data->data_in[12] = data->asc; + data->data_in[13] = data->ascq; + } + } else { + data->data_in[2] = SENSE_ILLEGAL_REQUEST; + data->data_in[12] = ASC_AUDIO_PLAY_OPERATION; + data->data_in[13] = (data->cd_status == CD_STATUS_PLAYING) ? ASCQ_AUDIO_PLAY_OPERATION_IN_PROGRESS + : ASCQ_AUDIO_PLAY_OPERATION_PAUSED; + } + + data->data_in[7] = 0; + + /* Clear the sense stuff as per the spec. */ + atapi_sense_clear(data, temp_command, 0); + + data->bytes_expected = data->data_pos_write = MIN(alloc_length, 18); + return alloc_length ? SCSI_PHASE_DATA_IN : SCSI_PHASE_STATUS; + + case SCSI_SEEK_6: + if (data->cmd_pos == CMD_POS_IDLE) { + uint32_t old_pos = data->cdpos; + int seek_time; + + data->cdpos = (((uint32_t)cdb[1] & 0x1f) << 16) | ((uint32_t)cdb[2] << 8) | (uint32_t)cdb[3]; + + seek_time = get_seek_time(data, old_pos, data->cdpos); + if (seek_time) { + data->cmd_pos = CMD_POS_WAIT; + data->new_cmd_pos = CMD_POS_COMPLETE; + data->wait_time = seek_time; + timer_set_delay_u64(&data->callback_timer, 1000 * TIMER_USEC); + return SCSI_PHASE_COMMAND; + } + } + data->cmd_pos = CMD_POS_IDLE; + return SCSI_PHASE_STATUS; + + case GPCMD_SET_SPEED: + data->cur_speed = (cdb[3] | (cdb[2] << 8)) / 176; + if (data->cur_speed < 1) + data->cur_speed = 1; + else if (data->cur_speed > data->max_speed) + data->cur_speed = data->max_speed; + data->cmd_pos = CMD_POS_IDLE; + return SCSI_PHASE_STATUS; + + case GPCMD_MECHANISM_STATUS: /*0xbd*/ + alloc_length = (cdb[7] << 16) | (cdb[8] << 8) | cdb[9]; + + if (alloc_length == 0) + fatal("Zero allocation length to MECHANISM STATUS not impl.\n"); + + data->data_in[0] = 0; + data->data_in[1] = 0; + data->data_in[2] = 0; + data->data_in[3] = 0; + data->data_in[4] = 0; + data->data_in[5] = 1; + data->data_in[6] = 0; + data->data_in[7] = 0; + // len = 8; + + data->data_pos_read = 0; + data->bytes_expected = data->data_pos_write = MIN(alloc_length, 8); + return alloc_length ? SCSI_PHASE_DATA_IN : SCSI_PHASE_STATUS; + + case GPCMD_READ_TOC_PMA_ATIP: + // pclog("Read TOC ready? %08X\n",ide); + toc_format = cdb[2] & 0xf; + if (toc_format == 0) + toc_format = (cdb[9] >> 6) & 3; + alloc_length = cdb[8] + (cdb[7] << 8); + switch (toc_format) { + case 0: /*Normal*/ + // pclog("ATAPI: READ TOC type requested: Normal\n"); + len = atapi->readtoc(data->data_in, cdb[6], msf, alloc_length, 0); + break; + case 1: /*Multi session*/ + // pclog("ATAPI: READ TOC type requested: Multi-session\n"); + len = atapi->readtoc_session(data->data_in, msf, alloc_length); + data->data_in[0] = 0; + data->data_in[1] = 0xA; + break; + case 2: /*Raw*/ + // pclog("ATAPI: READ TOC type requested: Raw TOC\n"); + len = atapi->readtoc_raw(data->data_in, alloc_length); + break; + default: + atapi_cmd_error(data, SENSE_ILLEGAL_REQUEST, ASC_LBA_OUT_OF_RANGE, 0); + data->cmd_pos = CMD_POS_IDLE; + return SCSI_PHASE_STATUS; + } + data->data_pos_read = 0; + data->bytes_expected = data->data_pos_write = MIN(alloc_length, len); + return alloc_length ? SCSI_PHASE_DATA_IN : SCSI_PHASE_STATUS; + + case GPCMD_READ_CD: + // pclog("Read CD : start LBA %02X%02X%02X%02X Length %02X%02X%02X Flags + // %02X\n",cdb[2],cdb[3],cdb[4],cdb[5],cdb[6],cdb[7],cdb[8],cdb[9]); + rcdmode = cdb[9] & 0xF8; + if ((rcdmode != 0x10) && (rcdmode != 0xF8)) { + atapi_cmd_error(data, SENSE_ILLEGAL_REQUEST, ASC_ILLEGAL_OPCODE, 0); + data->cmd_pos = CMD_POS_IDLE; + return SCSI_PHASE_STATUS; + } + + if (data->cmd_pos == CMD_POS_IDLE) { + uint32_t old_pos = data->cdpos; + int seek_time; + + data->cdlen = (cdb[6] << 16) | (cdb[7] << 8) | cdb[8]; + data->cdpos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + + data->cmd_pos = CMD_POS_START_SECTOR; + data->bytes_expected = data->cdlen * ((rcdmode == 0x10) ? 2048 : 2352); + if (data->is_atapi) { + if (rcdmode == 0x10) + atapi_set_transfer_granularity(data->atapi_dev, 2048); + else + atapi_set_transfer_granularity(data->atapi_dev, 2352); + } + + seek_time = get_seek_time(data, old_pos, data->cdpos); + if (seek_time) { + data->cmd_pos = CMD_POS_WAIT; + data->new_cmd_pos = CMD_POS_START_SECTOR; + data->wait_time = seek_time; + timer_set_delay_u64(&data->callback_timer, 1000 * TIMER_USEC); + return SCSI_PHASE_COMMAND; + } + } + if (data->cmd_pos == CMD_POS_WAIT) + return SCSI_PHASE_COMMAND; + if (!data->cdlen) { + data->cmd_pos = CMD_POS_IDLE; + return SCSI_PHASE_STATUS; + } + if (data->cmd_pos == CMD_POS_START_SECTOR) { + uint64_t time = (((uint64_t)SECTOR_TIME * TIMER_USEC) / data->cur_speed) * (uint64_t)data->cdlen; + + data->cmd_pos = CMD_POS_WAIT; + data->new_cmd_pos = CMD_POS_TRANSFER; + + if (time > (TIMER_USEC * 1000ull)) { + data->wait_time = (int)(time / (TIMER_USEC * 1000ull)); + timer_set_delay_u64(&data->callback_timer, time % (TIMER_USEC * 1000ull)); + } else { + timer_set_delay_u64(&data->callback_timer, time); + data->wait_time = 1; + } + return SCSI_PHASE_COMMAND; + } + + if (rcdmode == 0x10) { + c = MIN(data->cdlen, MAX_NR_SECTORS); + if (atapi->readsector(data->data_in, data->cdpos, c)) { + // pclog("Read sector failed\n"); + atapi_cmd_error(data, SENSE_ILLEGAL_REQUEST, ASC_LBA_OUT_OF_RANGE, 0); + data->cmd_pos = CMD_POS_IDLE; + return SCSI_PHASE_STATUS; + } + data->cdpos += c; + data->cdlen -= c; + } else { + for (c = 0; c < MAX_NR_SECTORS; c++) { + atapi->readsector_raw(&data->data_in[c * 2352], data->cdpos); + + data->cdpos++; + data->cdlen--; + if (!data->cdlen) { + c++; + break; + } + } + } + readflash_set(READFLASH_HDC, data->id); + + data->data_pos_read = 0; + data->data_pos_write = c * ((rcdmode == 0x10) ? 2048 : 2352); + return SCSI_PHASE_DATA_IN; + + case GPCMD_READ_6: + case GPCMD_READ_10: + case GPCMD_READ_12: + // pclog("Read: cmd_pos=%i cdlen=%i %p\n", data->cmd_pos, data->cdlen, &data->data_in[0]); + + // readcdmode = 0; + if (data->cmd_pos == CMD_POS_IDLE) { + uint32_t old_pos = data->cdpos; + int seek_time; + + if (cdb[0] == GPCMD_READ_6) { + data->cdlen = cdb[4]; + data->cdpos = (((uint32_t)cdb[1] & 0x1f) << 16) | ((uint32_t)cdb[2] << 8) | (uint32_t)cdb[3]; + } else if (cdb[0] == GPCMD_READ_10) { + data->cdlen = (cdb[7] << 8) | cdb[8]; + data->cdpos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + } else { + data->cdlen = ((uint32_t)cdb[6] << 24) | ((uint32_t)cdb[7] << 16) | ((uint32_t)cdb[8] << 8) | + (uint32_t)cdb[9]; + data->cdpos = ((uint32_t)cdb[2] << 24) | ((uint32_t)cdb[3] << 16) | ((uint32_t)cdb[4] << 8) | + (uint32_t)cdb[5]; + } + // pclog("cdpos=%08x cdlen=%08x\n", data->cdpos, data->cdlen); + + data->cmd_pos = CMD_POS_START_SECTOR; + data->bytes_expected = data->cdlen * 2048; + if (data->is_atapi) + atapi_set_transfer_granularity(data->atapi_dev, 2048); + + seek_time = get_seek_time(data, old_pos, data->cdpos); + + if (seek_time) { + data->cmd_pos = CMD_POS_WAIT; + data->new_cmd_pos = CMD_POS_START_SECTOR; + data->wait_time = seek_time; + timer_set_delay_u64(&data->callback_timer, 1000 * TIMER_USEC); + return SCSI_PHASE_COMMAND; + } + } + if (data->cmd_pos == CMD_POS_WAIT) + return SCSI_PHASE_COMMAND; + if (!data->cdlen) { + data->cmd_pos = CMD_POS_IDLE; + return SCSI_PHASE_STATUS; + } + if (data->cmd_pos == CMD_POS_START_SECTOR) { + uint64_t time = (((uint64_t)SECTOR_TIME * TIMER_USEC) / data->cur_speed) * (uint64_t)data->cdlen; + + data->cmd_pos = CMD_POS_WAIT; + data->new_cmd_pos = CMD_POS_TRANSFER; + + if (time > (TIMER_USEC * 1000ull)) { + data->wait_time = (int)(time / (TIMER_USEC * 1000ull)); + timer_set_delay_u64(&data->callback_timer, time % (TIMER_USEC * 1000ull)); + } else { + timer_set_delay_u64(&data->callback_timer, time); + data->wait_time = 1; + } + return SCSI_PHASE_COMMAND; + } + + readflash_set(READFLASH_HDC, data->id); + c = MIN(data->cdlen, MAX_NR_SECTORS); + if (atapi->readsector(data->data_in, data->cdpos, c)) { + // pclog("Read sector failed\n"); + atapi_cmd_error(data, SENSE_ILLEGAL_REQUEST, ASC_LBA_OUT_OF_RANGE, 0); + data->cmd_pos = CMD_POS_IDLE; + return SCSI_PHASE_STATUS; + } + data->cdpos += c; + data->cdlen -= c; + + data->data_pos_read = 0; + data->data_pos_write = c * 2048; + return SCSI_PHASE_DATA_IN; + + case GPCMD_READ_HEADER: + alloc_length = cdb[8] | (cdb[7] << 8); + if (msf) { + atapi_cmd_error(data, SENSE_ILLEGAL_REQUEST, ASC_ILLEGAL_OPCODE, 0); + return SCSI_PHASE_STATUS; + } + for (c = 0; c < 4; c++) + data->data_in[c + 4] = cdb[c + 2]; + data->data_in[0] = 1; /*2048 bytes user data*/ + data->data_in[1] = data->data_in[2] = data->data_in[3] = 0; + + data->bytes_expected = data->data_pos_write = MIN(6, alloc_length); + return alloc_length ? SCSI_PHASE_DATA_IN : SCSI_PHASE_STATUS; + + case GPCMD_MODE_SENSE_6: + case GPCMD_MODE_SENSE_10: + temp_command = cdb[0]; + + if (temp_command == GPCMD_MODE_SENSE_6) + len = cdb[4]; + else + len = cdb[8] | (cdb[7] << 8); + + c = cdb[2] & 0x3F; + + memset(data->data_in, 0, len); + alloc_length = len; + // for (c=0;cdata_in[0] = len - 1; + data->data_in[1] = 3; /*120mm data CD-ROM*/ + } else { + len = ide_atapi_mode_sense(data, 8, c); + data->data_in[0] = (len - 2) >> 8; + data->data_in[1] = (len - 2) & 255; + data->data_in[2] = 3; /*120mm data CD-ROM*/ + } + + data->bytes_expected = data->data_pos_write = MIN(len, alloc_length); + data->cmd_pos = CMD_POS_IDLE; + return alloc_length ? SCSI_PHASE_DATA_IN : SCSI_PHASE_STATUS; + + case GPCMD_MODE_SELECT_6: + case GPCMD_MODE_SELECT_10: + if (data->cmd_pos == CMD_POS_IDLE) { + int len; + + if (cdb[0] == GPCMD_MODE_SELECT_6) { + len = cdb[4]; + data->prefix_len = 6; + } else { + len = (cdb[7] << 8) | cdb[8]; + data->prefix_len = 10; + } + + data->cmd_pos = CMD_POS_TRANSFER; + data->bytes_required = len; + return SCSI_PHASE_DATA_OUT; + } + if (data->bytes_received == data->bytes_required) { + cdrom_mode_select(data, data->bytes_required); + data->cmd_pos = CMD_POS_IDLE; + return SCSI_PHASE_STATUS; + } + return SCSI_PHASE_DATA_OUT; + + case GPCMD_GET_EVENT_STATUS_NOTIFICATION: /*0x4a*/ + temp_command = cdb[0]; + alloc_length = (cdb[7] << 16) | (cdb[8] << 8) | cdb[9]; + + { + struct __attribute__((__packed__)) { + 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; + + struct __attribute__((__packed__)) { + uint16_t len; + uint8_t notification_class; + uint8_t supported_events; + } * gesn_event_header; + unsigned int used_len; + + gesn_cdb = (void *)cdb; + gesn_event_header = (void *)data->data_in; + + /* 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. */ + atapi_cmd_error(data, SENSE_ILLEGAL_REQUEST, ASC_ILLEGAL_OPCODE, 0); + return SCSI_PHASE_STATUS; + } + + /* polling mode operation */ + + /* + * 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; + used_len = atapi_event_status(data->data_in); + } else { + gesn_event_header->notification_class = 0x80; /* No event available */ + used_len = sizeof(*gesn_event_header); + } + len = used_len; + gesn_event_header->len = used_len - sizeof(*gesn_event_header); + } + + data->bytes_expected = data->data_pos_write = MIN(alloc_length, len); + data->cmd_pos = CMD_POS_IDLE; + return alloc_length ? SCSI_PHASE_DATA_IN : SCSI_PHASE_STATUS; + + case GPCMD_READ_DISC_INFORMATION: + alloc_length = cdb[8] | (cdb[7] << 8); + + data->data_in[1] = 32; + data->data_in[2] = 0xe; /* last session complete, disc finalized */ + data->data_in[3] = 1; /* first track on disc */ + data->data_in[4] = 1; /* # of sessions */ + data->data_in[5] = 1; /* first track of last session */ + data->data_in[6] = 1; /* last track of last session */ + data->data_in[7] = 0x20; /* unrestricted use */ + data->data_in[8] = 0x00; /* CD-ROM */ + + data->bytes_expected = data->data_pos_write = MIN(alloc_length, 34); + data->cmd_pos = CMD_POS_IDLE; + return alloc_length ? SCSI_PHASE_DATA_IN : SCSI_PHASE_STATUS; + + case GPCMD_PLAY_AUDIO_10: + case GPCMD_PLAY_AUDIO_12: + 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*/ + if (cdb[0] == GPCMD_PLAY_AUDIO_10) { + pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + len = (cdb[7] << 8) | cdb[8]; + } else if (cdb[0] == GPCMD_PLAY_AUDIO_MSF) { + pos = (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + len = (cdb[6] << 16) | (cdb[7] << 8) | cdb[8]; + } else { + pos = (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + len = (cdb[7] << 16) | (cdb[8] << 8) | cdb[9]; + } + + if ((cdrom_drive < 1) || (data->cd_status <= CD_STATUS_DATA_ONLY) || + !atapi->is_track_audio(pos, (cdb[0] == GPCMD_PLAY_AUDIO_MSF) ? 1 : 0)) { + atapi_cmd_error(data, SENSE_ILLEGAL_REQUEST, ASC_ILLEGAL_MODE_FOR_THIS_TRACK, 0); + return SCSI_PHASE_STATUS; + } + + atapi->playaudio(pos, len, (cdb[0] == GPCMD_PLAY_AUDIO_MSF) ? 1 : 0); + data->cmd_pos = CMD_POS_IDLE; + return SCSI_PHASE_STATUS; + + case GPCMD_READ_SUBCHANNEL: + alloc_length = cdb[8] | (cdb[7] << 8); + if (cdb[3] != 1) { + atapi_cmd_error(data, SENSE_ILLEGAL_REQUEST, ASC_ILLEGAL_OPCODE, 0); + return SCSI_PHASE_STATUS; + } + pos = 0; + data->data_in[pos++] = 0; + data->data_in[pos++] = 0; /*Audio status*/ + data->data_in[pos++] = 0; + data->data_in[pos++] = 0; /*Subchannel length*/ + data->data_in[pos++] = 1; /*Format code*/ + data->data_in[1] = atapi->getcurrentsubchannel(&data->data_in[5], msf); + // pclog("Read subchannel complete - audio status %02X\n",idebufferb[1]); + len = 11 + 5; + if (!(cdb[2] & 0x40)) + len = 4; + + data->bytes_expected = data->data_pos_write = MIN(alloc_length, len); + return alloc_length ? SCSI_PHASE_DATA_IN : SCSI_PHASE_STATUS; + + case GPCMD_START_STOP_UNIT: + if (!cdb[4]) + atapi->stop(); + else if (cdb[4] == 2) + atapi->eject(); + else if (cdb[4] == 3) + atapi->load(); + data->cmd_pos = CMD_POS_IDLE; + return SCSI_PHASE_STATUS; + + case GPCMD_INQUIRY: + page_code = cdb[2]; + max_len = cdb[4]; + alloc_length = max_len; + temp_command = cdb[0]; + + if (cdb[1] & 1) { + preamble_len = 4; + size_idx = 3; + + data->data_in[idx++] = 05; + data->data_in[idx++] = page_code; + data->data_in[idx++] = 0; + + idx++; + + switch (page_code) { + case 0x00: + data->data_in[idx++] = 0x00; + data->data_in[idx++] = 0x83; + break; + + case 0x83: + if (idx + 24 > max_len) { + atapi_cmd_error(data, SENSE_ILLEGAL_REQUEST, ASC_DATA_PHASE_ERROR, 0); + return SCSI_PHASE_STATUS; + } + data->data_in[idx++] = 0x02; + data->data_in[idx++] = 0x00; + data->data_in[idx++] = 0x00; + data->data_in[idx++] = 20; + ide_padstr8(data->data_in + idx, 20, "53R141"); /* Serial */ + idx += 20; + + if (idx + 72 > max_len) { + goto atapi_out; + } + data->data_in[idx++] = 0x02; + data->data_in[idx++] = 0x01; + data->data_in[idx++] = 0x00; + data->data_in[idx++] = 68; + ide_padstr8(data->data_in + idx, 8, cd_models[cd_data->cur_model].vendor_8); /* Vendor */ + idx += 8; + ide_padstr8(data->data_in + idx, 40, + cd_models[cd_data->cur_model].model_and_firmware_40); /* Product */ + idx += 40; + ide_padstr8(data->data_in + idx, 20, cd_models[cd_data->cur_model].serial_20); /* Product */ + idx += 20; + break; + + default: + atapi_cmd_error(data, SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET, 0); + return SCSI_PHASE_STATUS; + } + } else { + preamble_len = 5; + size_idx = 4; + + data->data_in[0] = 5; /*CD-ROM*/ + data->data_in[1] = 0x80; /*Removable*/ + if (data->is_atapi) { + data->data_in[2] = 0; /*Not ANSI compliant*/ + data->data_in[3] = 0x21; /*ATAPI compliant*/ + } else { + data->data_in[2] = 2; /*SCSI-2 compliant*/ + data->data_in[3] = 0x02; + } + data->data_in[4] = 31; + data->data_in[5] = 0; + data->data_in[6] = 0; + data->data_in[7] = 0; + + ide_padstr8(data->data_in + 8, 8, cd_models[cd_data->cur_model].vendor_8); /* Vendor */ + ide_padstr8(data->data_in + 16, 16, cd_models[cd_data->cur_model].model_16); /* Product */ + ide_padstr8(data->data_in + 32, 4, cd_models[cd_data->cur_model].firmware_4); /* Revision */ + + idx = 36; + } + + atapi_out: + data->data_in[size_idx] = idx - preamble_len; + + data->bytes_expected = data->data_pos_write = MIN(alloc_length, idx); + return alloc_length ? SCSI_PHASE_DATA_IN : SCSI_PHASE_STATUS; + + case GPCMD_PREVENT_REMOVAL: + data->cmd_pos = CMD_POS_IDLE; + return SCSI_PHASE_STATUS; + + case GPCMD_PAUSE_RESUME: + if (cdb[8] & 1) + atapi->resume(); + else + atapi->pause(); + data->cmd_pos = CMD_POS_IDLE; + return SCSI_PHASE_STATUS; + + case GPCMD_SEEK: + if (data->cmd_pos == CMD_POS_IDLE) { + uint32_t old_pos = data->cdpos; + int seek_time; + + data->cdpos = (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + + atapi->seek(data->cdpos); + + seek_time = get_seek_time(data, old_pos, data->cdpos); + if (seek_time) { + data->cmd_pos = CMD_POS_WAIT; + data->new_cmd_pos = CMD_POS_COMPLETE; + data->wait_time = seek_time; + timer_set_delay_u64(&data->callback_timer, 1000 * TIMER_USEC); + return SCSI_PHASE_COMMAND; + } + } + data->cmd_pos = CMD_POS_IDLE; + return SCSI_PHASE_STATUS; + + case GPCMD_READ_CDROM_CAPACITY: + size = atapi->size(); + scsi_add_data(data, (size >> 24) & 0xff); + scsi_add_data(data, (size >> 16) & 0xff); + scsi_add_data(data, (size >> 8) & 0xff); + scsi_add_data(data, size & 0xff); + scsi_add_data(data, (2048 >> 24) & 0xff); + scsi_add_data(data, (2048 >> 16) & 0xff); + scsi_add_data(data, (2048 >> 8) & 0xff); + scsi_add_data(data, 2048 & 0xff); + pclog("READ_CDROM_CAPACITY %08x\n", size); + data->cmd_pos = CMD_POS_IDLE; + return SCSI_PHASE_DATA_IN; + + case GPCMD_STOP_PLAY_SCAN: + atapi->stop(); + data->cmd_pos = CMD_POS_IDLE; + return SCSI_PHASE_STATUS; + + case GPCMD_SEND_DVD_STRUCTURE: + default: + atapi_cmd_error(data, SENSE_ILLEGAL_REQUEST, ASC_ILLEGAL_OPCODE, 0); + return SCSI_PHASE_STATUS; + } } static uint8_t scsi_cd_read(void *p) { - scsi_cd_data_t *data = p; - uint8_t temp; + scsi_cd_data_t *data = p; + uint8_t temp; - data->data_bytes_read++; - temp = data->data_in[data->data_pos_read++]; + data->data_bytes_read++; + temp = data->data_in[data->data_pos_read++]; - if (data->data_pos_read == data->data_pos_write && data->data_bytes_read < data->bytes_expected) - scsi_cd_command(data->cdb, data); + if (data->data_pos_read == data->data_pos_write && data->data_bytes_read < data->bytes_expected) + scsi_cd_command(data->cdb, data); - return temp; + return temp; } static void scsi_cd_write(uint8_t val, void *p) { - scsi_cd_data_t *data = p; + scsi_cd_data_t *data = p; - data->data_out[data->data_pos_write++] = val; + data->data_out[data->data_pos_write++] = val; - data->bytes_received++; + data->bytes_received++; - if (data->data_pos_write > BUFFER_SIZE) - fatal("Exceeded data_out buffer size\n"); + if (data->data_pos_write > BUFFER_SIZE) + fatal("Exceeded data_out buffer size\n"); } static int scsi_cd_read_complete(void *p) { - scsi_cd_data_t *data = p; + scsi_cd_data_t *data = p; - return (data->data_bytes_read == data->bytes_expected); + return (data->data_bytes_read == data->bytes_expected); } static int scsi_cd_write_complete(void *p) { - scsi_cd_data_t *data = p; + scsi_cd_data_t *data = p; - return (data->bytes_received == data->bytes_required); + return (data->bytes_received == data->bytes_required); } static void scsi_cd_start_command(void *p) { - scsi_cd_data_t *data = p; + scsi_cd_data_t *data = p; - data->bytes_received = 0; - data->bytes_required = 0; - data->data_pos_read = data->data_pos_write = 0; - data->data_bytes_read = data->bytes_expected = 0; + data->bytes_received = 0; + data->bytes_required = 0; + data->data_pos_read = data->data_pos_write = 0; + data->data_bytes_read = data->bytes_expected = 0; - data->received_cdb = 0; + data->received_cdb = 0; - data->cmd_pos = CMD_POS_IDLE; - memset(data->data_in, 0, 256); + data->cmd_pos = CMD_POS_IDLE; + memset(data->data_in, 0, 256); } static uint8_t scsi_cd_get_status(void *p) { - scsi_cd_data_t *data = p; + scsi_cd_data_t *data = p; - return data->status; + return data->status; } static uint8_t scsi_cd_get_sense_key(void *p) { - scsi_cd_data_t *data = p; + scsi_cd_data_t *data = p; - return data->sense_key; + return data->sense_key; } static int scsi_cd_get_bytes_required(void *p) { - scsi_cd_data_t *data = p; + scsi_cd_data_t *data = p; - return data->bytes_required - data->bytes_received; + return data->bytes_required - data->bytes_received; } static void scsi_cd_atapi_identify(uint16_t *buffer, void *p) { - scsi_cd_data_t *data = p; + scsi_cd_data_t *data = p; - memset(buffer, 0, 512); + memset(buffer, 0, 512); - buffer[0] = 0x8000 | (5 << 8) | 0x80 | (2 << 5); /* ATAPI device, CD-ROM drive, removable media, accelerated DRQ */ - ide_padstr((char *)(buffer + 10), cd_models[cd_data->cur_model].serial2_20, 20); /* Serial Number */ - ide_padstr((char *)(buffer + 23), cd_models[cd_data->cur_model].firmware2_8, 8); /* Firmware */ - ide_padstr((char *)(buffer + 27), cd_models[cd_data->cur_model].model2_40, 40); /* Model */ - buffer[49] = 0x300; /*DMA and LBA supported*/ - buffer[51] = 120; - buffer[52] = 120; - buffer[53] = 2; /*Words 64-70 are valid*/ - buffer[62] = 0x0000; - buffer[63] = 0x0007 | (0x100 << data->mdma_mode); /*Multi-word DMA 0, 1 & 2*/ - buffer[64] = 0x0003; /*PIO Modes 3 & 4*/ - if (data->pio_mode >= 3) - buffer[64] |= (0x100 << (data->pio_mode - 3)); - buffer[65] = 120; /*Minimum multi-word cycle time*/ - buffer[66] = 120; /*Recommended multi-word cycle time*/ - buffer[67] = 120; /*Minimum PIO cycle time*/ - buffer[126] = 0xfffe; /* Interpret zero byte count limit as maximum length */ + buffer[0] = 0x8000 | (5 << 8) | 0x80 | (2 << 5); /* ATAPI device, CD-ROM drive, removable media, accelerated DRQ */ + ide_padstr((char *)(buffer + 10), cd_models[cd_data->cur_model].serial2_20, 20); /* Serial Number */ + ide_padstr((char *)(buffer + 23), cd_models[cd_data->cur_model].firmware2_8, 8); /* Firmware */ + ide_padstr((char *)(buffer + 27), cd_models[cd_data->cur_model].model2_40, 40); /* Model */ + buffer[49] = 0x300; /*DMA and LBA supported*/ + buffer[51] = 120; + buffer[52] = 120; + buffer[53] = 2; /*Words 64-70 are valid*/ + buffer[62] = 0x0000; + buffer[63] = 0x0007 | (0x100 << data->mdma_mode); /*Multi-word DMA 0, 1 & 2*/ + buffer[64] = 0x0003; /*PIO Modes 3 & 4*/ + if (data->pio_mode >= 3) + buffer[64] |= (0x100 << (data->pio_mode - 3)); + buffer[65] = 120; /*Minimum multi-word cycle time*/ + buffer[66] = 120; /*Recommended multi-word cycle time*/ + buffer[67] = 120; /*Minimum PIO cycle time*/ + buffer[126] = 0xfffe; /* Interpret zero byte count limit as maximum length */ } static int scsi_cd_atapi_set_feature(uint8_t feature, uint8_t val, void *p) { - scsi_cd_data_t *data = p; + scsi_cd_data_t *data = p; - switch (feature) { - case FEATURE_SET_TRANSFER_MODE: - if (!(val & 0xfe)) { - /*Default transfer mode*/ - data->pio_mode = 0; - return 1; - } else if ((val & 0xf8) == 0x08) { - /*PIO transfer mode*/ - if ((val & 7) > 4) - return 0; - data->pio_mode = (val & 7); - return 1; - } else if ((val & 0xf8) == 0x20) { - /*Multi-word DMA transfer mode*/ - if ((val & 7) > 2) - return 0; - data->mdma_mode = (val & 7); - return 1; - } - return 0; /*Invalid data*/ + switch (feature) { + case FEATURE_SET_TRANSFER_MODE: + if (!(val & 0xfe)) { + /*Default transfer mode*/ + data->pio_mode = 0; + return 1; + } else if ((val & 0xf8) == 0x08) { + /*PIO transfer mode*/ + if ((val & 7) > 4) + return 0; + data->pio_mode = (val & 7); + return 1; + } else if ((val & 0xf8) == 0x20) { + /*Multi-word DMA transfer mode*/ + if ((val & 7) > 2) + return 0; + data->mdma_mode = (val & 7); + return 1; + } + return 0; /*Invalid data*/ - case FEATURE_ENABLE_IRQ_OVERLAPPED: - case FEATURE_ENABLE_IRQ_SERVICE: - case FEATURE_DISABLE_REVERT: - case FEATURE_DISABLE_IRQ_OVERLAPPED: - case FEATURE_DISABLE_IRQ_SERVICE: - case FEATURE_ENABLE_REVERT:return 1; - } + case FEATURE_ENABLE_IRQ_OVERLAPPED: + case FEATURE_ENABLE_IRQ_SERVICE: + case FEATURE_DISABLE_REVERT: + case FEATURE_DISABLE_IRQ_OVERLAPPED: + case FEATURE_DISABLE_IRQ_SERVICE: + case FEATURE_ENABLE_REVERT: + return 1; + } - return 0; /*Feature not supported*/ + return 0; /*Feature not supported*/ } -scsi_device_t scsi_cd = - { - scsi_cd_init, - scsi_cd_atapi_init, - scsi_cd_close, - scsi_cd_reset, +scsi_device_t scsi_cd = { + scsi_cd_init, + scsi_cd_atapi_init, + scsi_cd_close, + scsi_cd_reset, - scsi_cd_start_command, - scsi_cd_command, + scsi_cd_start_command, + scsi_cd_command, - scsi_cd_get_status, - scsi_cd_get_sense_key, - scsi_cd_get_bytes_required, + scsi_cd_get_status, + scsi_cd_get_sense_key, + scsi_cd_get_bytes_required, - scsi_cd_atapi_identify, - scsi_cd_atapi_set_feature, + scsi_cd_atapi_identify, + scsi_cd_atapi_set_feature, - scsi_cd_read, - scsi_cd_write, - scsi_cd_read_complete, - scsi_cd_write_complete, - }; + scsi_cd_read, + scsi_cd_write, + scsi_cd_read_complete, + scsi_cd_write_complete, +}; diff --git a/src/scsi/scsi_hd.c b/src/scsi/scsi_hd.c index 3dc7fe02..098f7cd7 100644 --- a/src/scsi/scsi_hd.c +++ b/src/scsi/scsi_hd.c @@ -10,769 +10,779 @@ extern char ide_fn[7][512]; -#define BUFFER_SIZE (256*1024) +#define BUFFER_SIZE (256 * 1024) #define RW_DELAY (TIMER_USEC * 500) -enum { - CMD_POS_IDLE = 0, - CMD_POS_WAIT, - CMD_POS_START_SECTOR, - CMD_POS_TRANSFER -}; +enum { CMD_POS_IDLE = 0, CMD_POS_WAIT, CMD_POS_START_SECTOR, CMD_POS_TRANSFER }; typedef struct scsi_hd_data { - int blocks; + int blocks; - int cmd_pos, new_cmd_pos; + int cmd_pos, new_cmd_pos; - int addr, len; - int sector_pos; + int addr, len; + int sector_pos; - uint8_t buf[512]; + uint8_t buf[512]; - uint8_t status; + uint8_t status; - uint8_t data_in[BUFFER_SIZE]; - uint8_t data_out[BUFFER_SIZE]; - int data_pos_read, data_pos_write; + uint8_t data_in[BUFFER_SIZE]; + uint8_t data_out[BUFFER_SIZE]; + int data_pos_read, data_pos_write; - int bytes_received, bytes_required; + int bytes_received, bytes_required; - hdd_file_t hdd; + hdd_file_t hdd; - int sense_key, asc, ascq; + int sense_key, asc, ascq; - int hd_id; + int hd_id; - pc_timer_t callback_timer; + pc_timer_t callback_timer; - scsi_bus_t *bus; + scsi_bus_t *bus; } scsi_hd_data; static void scsi_hd_callback(void *p) { - scsi_hd_data *data = p; + scsi_hd_data *data = p; - if (data->cmd_pos == CMD_POS_WAIT) { - data->cmd_pos = data->new_cmd_pos; - scsi_bus_kick(data->bus); - } + if (data->cmd_pos == CMD_POS_WAIT) { + data->cmd_pos = data->new_cmd_pos; + scsi_bus_kick(data->bus); + } } static void *scsi_hd_init(scsi_bus_t *bus, int id) { - scsi_hd_data *data = malloc(sizeof(scsi_hd_data)); - memset(data, 0, sizeof(scsi_hd_data)); + scsi_hd_data *data = malloc(sizeof(scsi_hd_data)); + memset(data, 0, sizeof(scsi_hd_data)); - hdd_load(&data->hdd, id, ide_fn[id]); + hdd_load(&data->hdd, id, ide_fn[id]); - if (!data->hdd.f) { - free(data); - return NULL; - } + if (!data->hdd.f) { + free(data); + return NULL; + } - data->hd_id = id; - data->bus = bus; - timer_add(&data->callback_timer, scsi_hd_callback, data, 0); + data->hd_id = id; + data->bus = bus; + timer_add(&data->callback_timer, scsi_hd_callback, data, 0); - return data; + return data; } static void scsi_hd_close(void *p) { - scsi_hd_data *data = p; + scsi_hd_data *data = p; - hdd_close(&data->hdd); - free(data); + hdd_close(&data->hdd); + free(data); } static int scsi_add_data(uint8_t val, void *p) { - scsi_hd_data *data = p; + scsi_hd_data *data = p; -// pclog("scsi_add_data : %04x %02x\n", data->data_pos_write, val); + // pclog("scsi_add_data : %04x %02x\n", data->data_pos_write, val); - data->data_in[data->data_pos_write++] = val; + data->data_in[data->data_pos_write++] = val; -// if (data->bus_out & BUS_REQ) -// return -1; + // if (data->bus_out & BUS_REQ) + // return -1; -// data->bus_out = (data->bus_out & ~BUS_DATAMASK) | BUS_SETDATA(val) | BUS_DBP | BUS_REQ; + // data->bus_out = (data->bus_out & ~BUS_DATAMASK) | BUS_SETDATA(val) | BUS_DBP | BUS_REQ; - return 0; + return 0; } static int scsi_get_data(void *p) { - scsi_hd_data *data = p; - uint8_t val = data->data_out[data->data_pos_read++]; + scsi_hd_data *data = p; + uint8_t val = data->data_out[data->data_pos_read++]; - if (data->data_pos_read > BUFFER_SIZE) - fatal("scsi_get_data beyond buffer limits\n"); + if (data->data_pos_read > BUFFER_SIZE) + fatal("scsi_get_data beyond buffer limits\n"); - return val; + return val; } static void scsi_hd_illegal(scsi_hd_data *data) { - data->status = STATUS_CHECK_CONDITION; - data->sense_key = KEY_ILLEGAL_REQ; - data->asc = ASC_INVALID_LUN; - data->ascq = 0; + data->status = STATUS_CHECK_CONDITION; + data->sense_key = KEY_ILLEGAL_REQ; + data->asc = ASC_INVALID_LUN; + data->ascq = 0; } -#define add_data_len(v) \ - if (i < len) \ - scsi_add_data(v, data); \ +#define add_data_len(v) \ + if (i < len) \ + scsi_add_data(v, data); \ i++; static int scsi_hd_command(uint8_t *cdb, void *p) { - scsi_hd_data *data = p; - int /*addr, */len; - int i = 0; - int desc; - int bus_state = 0; + scsi_hd_data *data = p; + int /*addr, */ len; + int i = 0; + int desc; + int bus_state = 0; -// if (data->cmd_pos == CMD_POS_IDLE) -// pclog("SCSI HD command %02x\n", cdb[0]); - data->status = STATUS_GOOD; - data->data_pos_read = data->data_pos_write = 0; + // if (data->cmd_pos == CMD_POS_IDLE) + // pclog("SCSI HD command %02x\n", cdb[0]); + data->status = STATUS_GOOD; + data->data_pos_read = data->data_pos_write = 0; - if ((cdb[0] != SCSI_REQUEST_SENSE/* && cdb[0] != SCSI_INQUIRY*/) && (cdb[1] & 0xe0)) { -// pclog("non-zero LUN\n"); - /*Non-zero LUN - abort command*/ - scsi_hd_illegal(data); - bus_state = BUS_CD | BUS_IO; - return bus_state; - } + if ((cdb[0] != SCSI_REQUEST_SENSE /* && cdb[0] != SCSI_INQUIRY*/) && (cdb[1] & 0xe0)) { + // pclog("non-zero LUN\n"); + /*Non-zero LUN - abort command*/ + scsi_hd_illegal(data); + bus_state = BUS_CD | BUS_IO; + return bus_state; + } - switch (cdb[0]) { - case SCSI_TEST_UNIT_READY:bus_state = BUS_CD | BUS_IO; - break; + switch (cdb[0]) { + case SCSI_TEST_UNIT_READY: + bus_state = BUS_CD | BUS_IO; + break; - case SCSI_REZERO_UNIT:bus_state = BUS_CD | BUS_IO; - break; + case SCSI_REZERO_UNIT: + bus_state = BUS_CD | BUS_IO; + break; - case SCSI_REQUEST_SENSE:desc = cdb[1] & 1; - len = cdb[4]; + case SCSI_REQUEST_SENSE: + desc = cdb[1] & 1; + len = cdb[4]; - if (!desc) { - add_data_len(0x70); - add_data_len(0); - add_data_len(data->sense_key); /*Sense key*/ - add_data_len(0); /*Information (4 bytes)*/ - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); /*Additional sense length*/ - add_data_len(0); /*Command specific information (4 bytes)*/ - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(data->asc); /*ASC*/ - add_data_len(data->ascq); /*ASCQ*/ - add_data_len(0); /*FRU code*/ - add_data_len(0); /*Sense key specific (3 bytes)*/ - add_data_len(0); - add_data_len(0); - } else { - add_data_len(0x72); - add_data_len(data->sense_key); /*Sense Key*/ - add_data_len(data->asc); /*ASC*/ - add_data_len(data->ascq); /*ASCQ*/ - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); /*additional sense length*/ - } + if (!desc) { + add_data_len(0x70); + add_data_len(0); + add_data_len(data->sense_key); /*Sense key*/ + add_data_len(0); /*Information (4 bytes)*/ + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); /*Additional sense length*/ + add_data_len(0); /*Command specific information (4 bytes)*/ + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(data->asc); /*ASC*/ + add_data_len(data->ascq); /*ASCQ*/ + add_data_len(0); /*FRU code*/ + add_data_len(0); /*Sense key specific (3 bytes)*/ + add_data_len(0); + add_data_len(0); + } else { + add_data_len(0x72); + add_data_len(data->sense_key); /*Sense Key*/ + add_data_len(data->asc); /*ASC*/ + add_data_len(data->ascq); /*ASCQ*/ + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); /*additional sense length*/ + } - data->sense_key = data->asc = data->ascq = 0; + data->sense_key = data->asc = data->ascq = 0; - data->cmd_pos = CMD_POS_IDLE; - bus_state = BUS_IO; - break; + data->cmd_pos = CMD_POS_IDLE; + bus_state = BUS_IO; + break; - case SCSI_INQUIRY:len = cdb[4] | (cdb[3] << 8); -// pclog("INQUIRY %d %02x %02x %02x %02x %02x %02x %i\n", len, cdb[0],cdb[1],cdb[2],cdb[3],cdb[4],cdb[5], data->hd_id); + case SCSI_INQUIRY: + len = cdb[4] | (cdb[3] << 8); + // pclog("INQUIRY %d %02x %02x %02x %02x %02x %02x %i\n", len, + // cdb[0],cdb[1],cdb[2],cdb[3],cdb[4],cdb[5], data->hd_id); - if (cdb[1] & 0xe0) { - add_data_len(0 | (3 << 5)); /*No physical device on this LUN*/ - } else { - add_data_len(0 | (0 << 5)); /*Hard disc*/ - } - add_data_len(0); /*Not removeable*/ - add_data_len(0); /*No version*/ - add_data_len(2); /*Response data*/ - add_data_len(0); /*Additional length*/ - add_data_len(0); - add_data_len(0); - add_data_len(2); + if (cdb[1] & 0xe0) { + add_data_len(0 | (3 << 5)); /*No physical device on this LUN*/ + } else { + add_data_len(0 | (0 << 5)); /*Hard disc*/ + } + add_data_len(0); /*Not removeable*/ + add_data_len(0); /*No version*/ + add_data_len(2); /*Response data*/ + add_data_len(0); /*Additional length*/ + add_data_len(0); + add_data_len(0); + add_data_len(2); - add_data_len('P'); - add_data_len('C'); - add_data_len('e'); - add_data_len('m'); - add_data_len(' '); - add_data_len(' '); - add_data_len(' '); - add_data_len(' '); + add_data_len('P'); + add_data_len('C'); + add_data_len('e'); + add_data_len('m'); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); - add_data_len('S'); - add_data_len('C'); - add_data_len('S'); - add_data_len('I'); - add_data_len('_'); - add_data_len('H'); - add_data_len('D'); - add_data_len(' '); + add_data_len('S'); + add_data_len('C'); + add_data_len('S'); + add_data_len('I'); + add_data_len('_'); + add_data_len('H'); + add_data_len('D'); + add_data_len(' '); - add_data_len(' '); - add_data_len(' '); - add_data_len(' '); - add_data_len(' '); - add_data_len(' '); - add_data_len(' '); - add_data_len(' '); - add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); - add_data_len(0); /*Product revision level*/ - add_data_len(0); - add_data_len(0); - add_data_len(0); + add_data_len(0); /*Product revision level*/ + add_data_len(0); + add_data_len(0); + add_data_len(0); - add_data_len(0); /*Drive serial number*/ - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); + add_data_len(0); /*Drive serial number*/ + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); - add_data_len(0); /*Vendor unique*/ - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); + add_data_len(0); /*Vendor unique*/ + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); - add_data_len(0); - add_data_len(0); + add_data_len(0); + add_data_len(0); - add_data_len(0); /*Vendor descriptor*/ - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); + add_data_len(0); /*Vendor descriptor*/ + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); - add_data_len(0); /*Reserved*/ - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); + add_data_len(0); /*Reserved*/ + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); - data->cmd_pos = CMD_POS_IDLE; - bus_state = BUS_IO; - break; + data->cmd_pos = CMD_POS_IDLE; + bus_state = BUS_IO; + break; - case SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL:bus_state = BUS_CD | BUS_IO; - break; + case SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL: + bus_state = BUS_CD | BUS_IO; + break; - case SCSI_MODE_SENSE_6:len = cdb[4]; + case SCSI_MODE_SENSE_6: + len = cdb[4]; - add_data_len(0); - add_data_len(0); + add_data_len(0); + add_data_len(0); - add_data_len(0x08); - add_data_len(0); + add_data_len(0x08); + add_data_len(0); - add_data_len((data->hdd.sectors >> 24) & 0xff); - add_data_len((data->hdd.sectors >> 16) & 0xff); - add_data_len((data->hdd.sectors >> 8) & 0xff); - add_data_len(data->hdd.sectors & 0xff); - add_data_len((512 >> 24) & 0xff); - add_data_len((512 >> 16) & 0xff); - add_data_len((512 >> 8) & 0xff); - add_data_len(512 & 0xff); + add_data_len((data->hdd.sectors >> 24) & 0xff); + add_data_len((data->hdd.sectors >> 16) & 0xff); + add_data_len((data->hdd.sectors >> 8) & 0xff); + add_data_len(data->hdd.sectors & 0xff); + add_data_len((512 >> 24) & 0xff); + add_data_len((512 >> 16) & 0xff); + add_data_len((512 >> 8) & 0xff); + add_data_len(512 & 0xff); - if ((cdb[2] & 0x3f) == 0x03 || (cdb[2] & 0x3f) == 0x3f) { - add_data_len(3); - add_data_len(0x16); - add_data_len(0); - add_data_len(1); /*Tracks per zone*/ - add_data_len(0); - add_data_len(1); /*Alternate sectors per zone*/ - add_data_len(0); - add_data_len(1); /*Alternate tracks per zone*/ - add_data_len(0); - add_data_len(1); /*Alternate tracks per volume*/ - add_data_len(1); - add_data_len(0); /*Sectors per track*/ - add_data_len(2); - add_data_len(0); /*Data bytes per physical sector*/ - add_data_len(0); - add_data_len(0); /*Interleave*/ - add_data_len(0); - add_data_len(0); /*Track skew*/ - add_data_len(0); - add_data_len(0); /*Cylinder skew*/ - add_data_len(0); /*Drive type*/ - add_data_len(0); - add_data_len(0); - add_data_len(0); - } + if ((cdb[2] & 0x3f) == 0x03 || (cdb[2] & 0x3f) == 0x3f) { + add_data_len(3); + add_data_len(0x16); + add_data_len(0); + add_data_len(1); /*Tracks per zone*/ + add_data_len(0); + add_data_len(1); /*Alternate sectors per zone*/ + add_data_len(0); + add_data_len(1); /*Alternate tracks per zone*/ + add_data_len(0); + add_data_len(1); /*Alternate tracks per volume*/ + add_data_len(1); + add_data_len(0); /*Sectors per track*/ + add_data_len(2); + add_data_len(0); /*Data bytes per physical sector*/ + add_data_len(0); + add_data_len(0); /*Interleave*/ + add_data_len(0); + add_data_len(0); /*Track skew*/ + add_data_len(0); + add_data_len(0); /*Cylinder skew*/ + add_data_len(0); /*Drive type*/ + add_data_len(0); + add_data_len(0); + add_data_len(0); + } - if ((cdb[2] & 0x3f) == 0x04 || (cdb[2] & 0x3f) == 0x3f) { - add_data_len(4); - add_data_len(0x16); - add_data_len(0); - add_data_len(0x10); - add_data_len(0); /*Cylinder count*/ - add_data_len(64); /*Heads*/ - add_data_len(0); - add_data_len(0); - add_data_len(0); /*Write recomp*/ - add_data_len(0); - add_data_len(0); - add_data_len(0); /*Reduced write current*/ - add_data_len(0); - add_data_len(0); /*Drive step rate*/ - add_data_len(0); - add_data_len(0); - add_data_len(0); /*Landing zone cylinder*/ - add_data_len(0); /*RPL*/ - add_data_len(0); /*Rotational offset*/ - add_data_len(0); - add_data_len(0x10); - add_data_len(0); /*Rotain rate*/ - add_data_len(0); - add_data_len(0); - } + if ((cdb[2] & 0x3f) == 0x04 || (cdb[2] & 0x3f) == 0x3f) { + add_data_len(4); + add_data_len(0x16); + add_data_len(0); + add_data_len(0x10); + add_data_len(0); /*Cylinder count*/ + add_data_len(64); /*Heads*/ + add_data_len(0); + add_data_len(0); + add_data_len(0); /*Write recomp*/ + add_data_len(0); + add_data_len(0); + add_data_len(0); /*Reduced write current*/ + add_data_len(0); + add_data_len(0); /*Drive step rate*/ + add_data_len(0); + add_data_len(0); + add_data_len(0); /*Landing zone cylinder*/ + add_data_len(0); /*RPL*/ + add_data_len(0); /*Rotational offset*/ + add_data_len(0); + add_data_len(0x10); + add_data_len(0); /*Rotain rate*/ + add_data_len(0); + add_data_len(0); + } - if ((cdb[2] & 0x3f) == 0x30 || (cdb[2] & 0x3f) == 0x3f) { - add_data_len(0xb0); - add_data_len(0x16); - add_data_len('P'); - add_data_len('C'); - add_data_len('E'); - add_data_len('M'); - add_data_len(' '); - add_data_len(' '); - add_data_len(' '); - add_data_len(' '); - add_data_len(' '); - add_data_len(' '); - add_data_len(' '); - add_data_len(' '); - add_data_len(' '); - add_data_len(' '); - add_data_len(' '); - add_data_len(' '); - add_data_len(' '); - add_data_len(' '); - add_data_len(' '); - add_data_len(' '); - add_data_len(' '); - add_data_len(' '); - } + if ((cdb[2] & 0x3f) == 0x30 || (cdb[2] & 0x3f) == 0x3f) { + add_data_len(0xb0); + add_data_len(0x16); + add_data_len('P'); + add_data_len('C'); + add_data_len('E'); + add_data_len('M'); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + } - for (; len >= 0; len--) { - add_data_len(0); - } + for (; len >= 0; len--) { + add_data_len(0); + } - len = data->data_pos_write; - if (cdb[0] == SCSI_MODE_SENSE_6) { - data->data_in[0] = len - 1; - } else { - data->data_in[0] = (len - 2) >> 8; - data->data_in[1] = (len - 2) & 255; - } -// scsi_illegal_field(); - data->cmd_pos = CMD_POS_IDLE; - bus_state = BUS_IO; - break; + len = data->data_pos_write; + if (cdb[0] == SCSI_MODE_SENSE_6) { + data->data_in[0] = len - 1; + } else { + data->data_in[0] = (len - 2) >> 8; + data->data_in[1] = (len - 2) & 255; + } + // scsi_illegal_field(); + data->cmd_pos = CMD_POS_IDLE; + bus_state = BUS_IO; + break; - case SCSI_READ_CAPACITY_10:scsi_add_data((data->hdd.sectors >> 24) & 0xff, data); - scsi_add_data((data->hdd.sectors >> 16) & 0xff, data); - scsi_add_data((data->hdd.sectors >> 8) & 0xff, data); - scsi_add_data(data->hdd.sectors & 0xff, data); - scsi_add_data((512 >> 24) & 0xff, data); - scsi_add_data((512 >> 16) & 0xff, data); - scsi_add_data((512 >> 8) & 0xff, data); - scsi_add_data(512 & 0xff, data); - data->cmd_pos = CMD_POS_IDLE; - bus_state = BUS_IO; - break; + case SCSI_READ_CAPACITY_10: + scsi_add_data((data->hdd.sectors >> 24) & 0xff, data); + scsi_add_data((data->hdd.sectors >> 16) & 0xff, data); + scsi_add_data((data->hdd.sectors >> 8) & 0xff, data); + scsi_add_data(data->hdd.sectors & 0xff, data); + scsi_add_data((512 >> 24) & 0xff, data); + scsi_add_data((512 >> 16) & 0xff, data); + scsi_add_data((512 >> 8) & 0xff, data); + scsi_add_data(512 & 0xff, data); + data->cmd_pos = CMD_POS_IDLE; + bus_state = BUS_IO; + break; - case SCSI_READ_6: -// pclog("SCSI_READ_6 %i\n", data->cmd_pos); - if (data->cmd_pos == CMD_POS_WAIT) { - bus_state = BUS_CD; - break; - } + case SCSI_READ_6: + // pclog("SCSI_READ_6 %i\n", data->cmd_pos); + if (data->cmd_pos == CMD_POS_WAIT) { + bus_state = BUS_CD; + break; + } - if (data->cmd_pos == CMD_POS_IDLE) { - readflash_set(READFLASH_HDC, data->hd_id); - data->addr = cdb[3] | (cdb[2] << 8) | ((cdb[1] & 0x1f) << 16); - data->len = cdb[4]; - if (!data->len) - data->len = 256; -// pclog("SCSI_READ_6: addr=%08x len=%04x\n", data->addr, data->len); + if (data->cmd_pos == CMD_POS_IDLE) { + readflash_set(READFLASH_HDC, data->hd_id); + data->addr = cdb[3] | (cdb[2] << 8) | ((cdb[1] & 0x1f) << 16); + data->len = cdb[4]; + if (!data->len) + data->len = 256; + // pclog("SCSI_READ_6: addr=%08x len=%04x\n", data->addr, data->len); - data->cmd_pos = CMD_POS_WAIT; - timer_set_delay_u64(&data->callback_timer, RW_DELAY); - data->new_cmd_pos = CMD_POS_START_SECTOR; - data->sector_pos = 0; + data->cmd_pos = CMD_POS_WAIT; + timer_set_delay_u64(&data->callback_timer, RW_DELAY); + data->new_cmd_pos = CMD_POS_START_SECTOR; + data->sector_pos = 0; - bus_state = BUS_CD; - break; - } -// else -// pclog("SCSI_READ_6 continue addr=%08x len=%04x sector_pos=%02x\n", data->addr, data->len, data->sector_pos); - while (data->len) { - if (data->cmd_pos == CMD_POS_START_SECTOR) { - hdd_read_sectors(&data->hdd, data->addr, 1, data->buf); - readflash_set(READFLASH_HDC, data->hd_id); - } + bus_state = BUS_CD; + break; + } + // else + // pclog("SCSI_READ_6 continue addr=%08x len=%04x sector_pos=%02x\n", data->addr, + // data->len, data->sector_pos); + while (data->len) { + if (data->cmd_pos == CMD_POS_START_SECTOR) { + hdd_read_sectors(&data->hdd, data->addr, 1, data->buf); + readflash_set(READFLASH_HDC, data->hd_id); + } - data->cmd_pos = CMD_POS_TRANSFER; - for (; data->sector_pos < 512; data->sector_pos++) { - int ret = scsi_add_data(data->buf[data->sector_pos], data); + data->cmd_pos = CMD_POS_TRANSFER; + for (; data->sector_pos < 512; data->sector_pos++) { + int ret = scsi_add_data(data->buf[data->sector_pos], data); - if (ret == -1) { - fatal("scsi_add_data -1\n"); - break; - } - if (ret & 0x100) { - fatal("scsi_add_data 0x100\n"); - data->len = 1; - break; - } - } - data->cmd_pos = CMD_POS_START_SECTOR; + if (ret == -1) { + fatal("scsi_add_data -1\n"); + break; + } + if (ret & 0x100) { + fatal("scsi_add_data 0x100\n"); + data->len = 1; + break; + } + } + data->cmd_pos = CMD_POS_START_SECTOR; - data->sector_pos = 0; - data->len--; - data->addr++; - } - data->cmd_pos = CMD_POS_IDLE; - bus_state = BUS_IO; - break; + data->sector_pos = 0; + data->len--; + data->addr++; + } + data->cmd_pos = CMD_POS_IDLE; + bus_state = BUS_IO; + break; - case SCSI_READ_10: -// pclog("SCSI_READ_10 %i\n", data->cmd_pos); - if (data->cmd_pos == CMD_POS_WAIT) { - bus_state = BUS_CD; - break; - } + case SCSI_READ_10: + // pclog("SCSI_READ_10 %i\n", data->cmd_pos); + if (data->cmd_pos == CMD_POS_WAIT) { + bus_state = BUS_CD; + break; + } - if (data->cmd_pos == CMD_POS_IDLE) { - readflash_set(READFLASH_HDC, data->hd_id); - data->addr = cdb[5] | (cdb[4] << 8) | (cdb[3] << 16) | (cdb[2] << 24); - data->len = cdb[8] | (cdb[7] << 8); -// pclog("SCSI_READ_10: addr=%08x len=%04x\n", data->addr, data->len); + if (data->cmd_pos == CMD_POS_IDLE) { + readflash_set(READFLASH_HDC, data->hd_id); + data->addr = cdb[5] | (cdb[4] << 8) | (cdb[3] << 16) | (cdb[2] << 24); + data->len = cdb[8] | (cdb[7] << 8); + // pclog("SCSI_READ_10: addr=%08x len=%04x\n", data->addr, data->len); - data->cmd_pos = CMD_POS_WAIT; - timer_set_delay_u64(&data->callback_timer, RW_DELAY); - data->new_cmd_pos = CMD_POS_START_SECTOR; - data->sector_pos = 0; + data->cmd_pos = CMD_POS_WAIT; + timer_set_delay_u64(&data->callback_timer, RW_DELAY); + data->new_cmd_pos = CMD_POS_START_SECTOR; + data->sector_pos = 0; - bus_state = BUS_CD; - break; - } -// else -// pclog("SCSI_READ_10 continue addr=%08x len=%04x sector_pos=%02x\n", data->addr, data->len, data->sector_pos); - while (data->len) { - if (data->cmd_pos == CMD_POS_START_SECTOR) { - hdd_read_sectors(&data->hdd, data->addr, 1, data->buf); - readflash_set(READFLASH_HDC, data->hd_id); - } - data->cmd_pos = CMD_POS_TRANSFER; - for (; data->sector_pos < 512; data->sector_pos++) { - int ret = scsi_add_data(data->buf[data->sector_pos], data); -// pclog("SCSI_READ_10 sector_pos=%i\n", data->sector_pos); - if (ret == -1) { - fatal("scsi_add_data -1\n"); - break; - } - if (ret & 0x100) { - fatal("scsi_add_data 0x100\n"); - data->len = 1; - break; - } - } - data->cmd_pos = CMD_POS_START_SECTOR; + bus_state = BUS_CD; + break; + } + // else + // pclog("SCSI_READ_10 continue addr=%08x len=%04x sector_pos=%02x\n", data->addr, + // data->len, data->sector_pos); + while (data->len) { + if (data->cmd_pos == CMD_POS_START_SECTOR) { + hdd_read_sectors(&data->hdd, data->addr, 1, data->buf); + readflash_set(READFLASH_HDC, data->hd_id); + } + data->cmd_pos = CMD_POS_TRANSFER; + for (; data->sector_pos < 512; data->sector_pos++) { + int ret = scsi_add_data(data->buf[data->sector_pos], data); + // pclog("SCSI_READ_10 sector_pos=%i\n", data->sector_pos); + if (ret == -1) { + fatal("scsi_add_data -1\n"); + break; + } + if (ret & 0x100) { + fatal("scsi_add_data 0x100\n"); + data->len = 1; + break; + } + } + data->cmd_pos = CMD_POS_START_SECTOR; - data->sector_pos = 0; - data->len--; - data->addr++; - } - data->cmd_pos = CMD_POS_IDLE; - bus_state = BUS_IO; - break; + data->sector_pos = 0; + data->len--; + data->addr++; + } + data->cmd_pos = CMD_POS_IDLE; + bus_state = BUS_IO; + break; - case SCSI_WRITE_6: -// pclog("SCSI_WRITE_6 %i\n", data->cmd_pos); - if (data->cmd_pos == CMD_POS_WAIT) { - bus_state = BUS_CD; - break; - } - if (data->cmd_pos == CMD_POS_IDLE) { - data->addr = cdb[3] | (cdb[2] << 8) | ((cdb[1] & 0x1f) << 16); - data->len = cdb[4]; - if (!data->len) - data->len = 256; - readflash_set(READFLASH_HDC, data->hd_id); -// pclog("SCSI_WRITE_6: addr=%08x len=%04x\n", data->addr, data->len); - data->bytes_required = data->len * 512; + case SCSI_WRITE_6: + // pclog("SCSI_WRITE_6 %i\n", data->cmd_pos); + if (data->cmd_pos == CMD_POS_WAIT) { + bus_state = BUS_CD; + break; + } + if (data->cmd_pos == CMD_POS_IDLE) { + data->addr = cdb[3] | (cdb[2] << 8) | ((cdb[1] & 0x1f) << 16); + data->len = cdb[4]; + if (!data->len) + data->len = 256; + readflash_set(READFLASH_HDC, data->hd_id); + // pclog("SCSI_WRITE_6: addr=%08x len=%04x\n", data->addr, data->len); + data->bytes_required = data->len * 512; - data->cmd_pos = CMD_POS_WAIT; - timer_set_delay_u64(&data->callback_timer, RW_DELAY); - data->new_cmd_pos = CMD_POS_TRANSFER; - data->sector_pos = 0; + data->cmd_pos = CMD_POS_WAIT; + timer_set_delay_u64(&data->callback_timer, RW_DELAY); + data->new_cmd_pos = CMD_POS_TRANSFER; + data->sector_pos = 0; - bus_state = BUS_CD; - break; - } - if (data->cmd_pos == CMD_POS_TRANSFER && data->bytes_received != data->bytes_required) { - bus_state = 0; - break; - } + bus_state = BUS_CD; + break; + } + if (data->cmd_pos == CMD_POS_TRANSFER && data->bytes_received != data->bytes_required) { + bus_state = 0; + break; + } - while (data->len) { - for (; data->sector_pos < 512; data->sector_pos++) { - int ret = scsi_get_data(data); - if (ret == -1) { - fatal("scsi_get_data -1\n"); - break; - } - data->buf[data->sector_pos] = ret & 0xff; - if (ret & 0x100) { - fatal("scsi_get_data 0x100\n"); - data->len = 1; - break; - } - } + while (data->len) { + for (; data->sector_pos < 512; data->sector_pos++) { + int ret = scsi_get_data(data); + if (ret == -1) { + fatal("scsi_get_data -1\n"); + break; + } + data->buf[data->sector_pos] = ret & 0xff; + if (ret & 0x100) { + fatal("scsi_get_data 0x100\n"); + data->len = 1; + break; + } + } - hdd_write_sectors(&data->hdd, data->addr, 1, data->buf); - readflash_set(READFLASH_HDC, data->hd_id); + hdd_write_sectors(&data->hdd, data->addr, 1, data->buf); + readflash_set(READFLASH_HDC, data->hd_id); - data->sector_pos = 0; - data->len--; - data->addr++; - } - data->cmd_pos = CMD_POS_IDLE; - bus_state = BUS_CD | BUS_IO; - break; + data->sector_pos = 0; + data->len--; + data->addr++; + } + data->cmd_pos = CMD_POS_IDLE; + bus_state = BUS_CD | BUS_IO; + break; - case SCSI_WRITE_10: -// pclog("SCSI_WRITE_10 %i\n", data->cmd_pos); - if (data->cmd_pos == CMD_POS_WAIT) { - bus_state = BUS_CD; - break; - } - if (data->cmd_pos == CMD_POS_IDLE) { - data->addr = cdb[5] | (cdb[4] << 8) | (cdb[3] << 16) | (cdb[2] << 24); - data->len = cdb[8] | (cdb[7] << 8); - readflash_set(READFLASH_HDC, data->hd_id); -// pclog("SCSI_WRITE_10: addr=%08x len=%04x\n", data->addr, data->len); - data->bytes_required = data->len * 512; + case SCSI_WRITE_10: + // pclog("SCSI_WRITE_10 %i\n", data->cmd_pos); + if (data->cmd_pos == CMD_POS_WAIT) { + bus_state = BUS_CD; + break; + } + if (data->cmd_pos == CMD_POS_IDLE) { + data->addr = cdb[5] | (cdb[4] << 8) | (cdb[3] << 16) | (cdb[2] << 24); + data->len = cdb[8] | (cdb[7] << 8); + readflash_set(READFLASH_HDC, data->hd_id); + // pclog("SCSI_WRITE_10: addr=%08x len=%04x\n", data->addr, data->len); + data->bytes_required = data->len * 512; - data->cmd_pos = CMD_POS_WAIT; - timer_set_delay_u64(&data->callback_timer, RW_DELAY); - data->new_cmd_pos = CMD_POS_TRANSFER; - data->sector_pos = 0; + data->cmd_pos = CMD_POS_WAIT; + timer_set_delay_u64(&data->callback_timer, RW_DELAY); + data->new_cmd_pos = CMD_POS_TRANSFER; + data->sector_pos = 0; - bus_state = BUS_CD; - break; - } - if (data->cmd_pos == CMD_POS_TRANSFER && data->bytes_received != data->bytes_required) { - bus_state = 0; - break; - } + bus_state = BUS_CD; + break; + } + if (data->cmd_pos == CMD_POS_TRANSFER && data->bytes_received != data->bytes_required) { + bus_state = 0; + break; + } - while (data->len) { - for (; data->sector_pos < 512; data->sector_pos++) { - int ret = scsi_get_data(data); -// pclog("SCSI_WRITE_10 sector_pos=%i\n", data->sector_pos); - if (ret == -1) { - fatal("scsi_get_data -1\n"); - break; - } - data->buf[data->sector_pos] = ret & 0xff; - if (ret & 0x100) { - fatal("scsi_get_data 0x100\n"); - data->len = 1; - break; - } - } + while (data->len) { + for (; data->sector_pos < 512; data->sector_pos++) { + int ret = scsi_get_data(data); + // pclog("SCSI_WRITE_10 sector_pos=%i\n", data->sector_pos); + if (ret == -1) { + fatal("scsi_get_data -1\n"); + break; + } + data->buf[data->sector_pos] = ret & 0xff; + if (ret & 0x100) { + fatal("scsi_get_data 0x100\n"); + data->len = 1; + break; + } + } - hdd_write_sectors(&data->hdd, data->addr, 1, data->buf); - readflash_set(READFLASH_HDC, data->hd_id); + hdd_write_sectors(&data->hdd, data->addr, 1, data->buf); + readflash_set(READFLASH_HDC, data->hd_id); - data->sector_pos = 0; - data->len--; - data->addr++; - } - data->cmd_pos = CMD_POS_IDLE; - bus_state = BUS_CD | BUS_IO; -// output = 3; - break; + data->sector_pos = 0; + data->len--; + data->addr++; + } + data->cmd_pos = CMD_POS_IDLE; + bus_state = BUS_CD | BUS_IO; + // output = 3; + break; - case SCSI_VERIFY_10:data->cmd_pos = CMD_POS_IDLE; - bus_state = BUS_CD | BUS_IO; - break; + case SCSI_VERIFY_10: + data->cmd_pos = CMD_POS_IDLE; + bus_state = BUS_CD | BUS_IO; + break; - case SCSI_MODE_SELECT_6: - if (!data->bytes_received) { - data->bytes_required = cdb[4]; -// pclog("SCSI_MODE_SELECT_6 bytes_required=%i\n", data->bytes_required); - bus_state = 0; - break; - } -// pclog("SCSI_MODE_SELECT_6 complete\n"); - data->cmd_pos = CMD_POS_IDLE; - bus_state = BUS_CD | BUS_IO; - break; + case SCSI_MODE_SELECT_6: + if (!data->bytes_received) { + data->bytes_required = cdb[4]; + // pclog("SCSI_MODE_SELECT_6 bytes_required=%i\n", data->bytes_required); + bus_state = 0; + break; + } + // pclog("SCSI_MODE_SELECT_6 complete\n"); + data->cmd_pos = CMD_POS_IDLE; + bus_state = BUS_CD | BUS_IO; + break; - case SCSI_FORMAT:bus_state = BUS_CD | BUS_IO; - break; + case SCSI_FORMAT: + bus_state = BUS_CD | BUS_IO; + break; - case SCSI_START_STOP_UNIT:bus_state = BUS_CD | BUS_IO; - break; + case SCSI_START_STOP_UNIT: + bus_state = BUS_CD | BUS_IO; + break; - /*These aren't really meaningful in a single initiator system, so just return*/ - case SCSI_RESERVE: - case SCSI_RELEASE:bus_state = BUS_CD | BUS_IO; - break; + /*These aren't really meaningful in a single initiator system, so just return*/ + case SCSI_RESERVE: + case SCSI_RELEASE: + bus_state = BUS_CD | BUS_IO; + break; - case SCSI_SEEK_6: - case SCSI_SEEK_10:bus_state = BUS_CD | BUS_IO; - break; + case SCSI_SEEK_6: + case SCSI_SEEK_10: + bus_state = BUS_CD | BUS_IO; + break; - case SEND_DIAGNOSTIC: - if (cdb[1] & (1 << 2)) { - /*Self-test*/ - /*Always passes*/ - bus_state = BUS_CD | BUS_IO; - } else { - /*Treat all other diagnostic requests as illegal*/ - scsi_hd_illegal(data); - bus_state = BUS_CD | BUS_IO; - } - break; + case SEND_DIAGNOSTIC: + if (cdb[1] & (1 << 2)) { + /*Self-test*/ + /*Always passes*/ + bus_state = BUS_CD | BUS_IO; + } else { + /*Treat all other diagnostic requests as illegal*/ + scsi_hd_illegal(data); + bus_state = BUS_CD | BUS_IO; + } + break; - default:pclog("Bad SCSI HD command %02x\n", cdb[0]); - scsi_hd_illegal(data); - bus_state = BUS_CD | BUS_IO; - break; - } + default: + pclog("Bad SCSI HD command %02x\n", cdb[0]); + scsi_hd_illegal(data); + bus_state = BUS_CD | BUS_IO; + break; + } - return bus_state; + return bus_state; } static uint8_t scsi_hd_read(void *p) { - scsi_hd_data *data = p; + scsi_hd_data *data = p; - return data->data_in[data->data_pos_read++]; + return data->data_in[data->data_pos_read++]; } static void scsi_hd_write(uint8_t val, void *p) { - scsi_hd_data *data = p; + scsi_hd_data *data = p; - data->data_out[data->data_pos_write++] = val; + data->data_out[data->data_pos_write++] = val; - data->bytes_received++; + data->bytes_received++; - if (data->data_pos_write > BUFFER_SIZE) - fatal("Exceeded data_out buffer size\n"); + if (data->data_pos_write > BUFFER_SIZE) + fatal("Exceeded data_out buffer size\n"); } static int scsi_hd_read_complete(void *p) { - scsi_hd_data *data = p; + scsi_hd_data *data = p; - return (data->data_pos_read == data->data_pos_write); + return (data->data_pos_read == data->data_pos_write); } static int scsi_hd_write_complete(void *p) { - scsi_hd_data *data = p; + scsi_hd_data *data = p; - return (data->bytes_received == data->bytes_required); + return (data->bytes_received == data->bytes_required); } static void scsi_hd_start_command(void *p) { - scsi_hd_data *data = p; + scsi_hd_data *data = p; - data->bytes_received = 0; - data->bytes_required = 0; - data->data_pos_read = data->data_pos_write = 0; + data->bytes_received = 0; + data->bytes_required = 0; + data->data_pos_read = data->data_pos_write = 0; } static uint8_t scsi_hd_get_status(void *p) { - scsi_hd_data *data = p; + scsi_hd_data *data = p; - return data->status; + return data->status; } static uint8_t scsi_hd_get_sense_key(void *p) { - scsi_hd_data *data = p; + scsi_hd_data *data = p; - return data->sense_key; + return data->sense_key; } static int scsi_hd_get_bytes_required(void *p) { - scsi_hd_data *data = p; + scsi_hd_data *data = p; - return data->bytes_required - data->bytes_received; + return data->bytes_required - data->bytes_received; } -scsi_device_t scsi_hd = - { - scsi_hd_init, - NULL, - scsi_hd_close, - NULL, +scsi_device_t scsi_hd = { + scsi_hd_init, + NULL, + scsi_hd_close, + NULL, - scsi_hd_start_command, - scsi_hd_command, + scsi_hd_start_command, + scsi_hd_command, - scsi_hd_get_status, - scsi_hd_get_sense_key, - scsi_hd_get_bytes_required, + scsi_hd_get_status, + scsi_hd_get_sense_key, + scsi_hd_get_bytes_required, - NULL, - NULL, + NULL, + NULL, - scsi_hd_read, - scsi_hd_write, - scsi_hd_read_complete, - scsi_hd_write_complete, - }; + scsi_hd_read, + scsi_hd_write, + scsi_hd_read_complete, + scsi_hd_write_complete, +}; diff --git a/src/scsi/scsi_ibm.c b/src/scsi/scsi_ibm.c index 8b71f996..aa50ddad 100644 --- a/src/scsi/scsi_ibm.c +++ b/src/scsi/scsi_ibm.c @@ -20,1140 +20,1165 @@ extern char ide_fn[4][512]; -typedef enum { - SCB_STATE_IDLE, - SCB_STATE_START, - SCB_STATE_WAIT, - SCB_STATE_COMPLETE -} sbc_state_t; +typedef enum { SCB_STATE_IDLE, SCB_STATE_START, SCB_STATE_WAIT, SCB_STATE_COMPLETE } sbc_state_t; typedef enum { - SCSI_STATE_IDLE, - SCSI_STATE_SELECT, - SCSI_STATE_SELECT_FAILED, - SCSI_STATE_SEND_COMMAND, - SCSI_STATE_NEXT_PHASE, - SCSI_STATE_END_PHASE, - SCSI_STATE_READ_DATA, - SCSI_STATE_WRITE_DATA, - SCSI_STATE_READ_STATUS, - SCSI_STATE_READ_MESSAGE + SCSI_STATE_IDLE, + SCSI_STATE_SELECT, + SCSI_STATE_SELECT_FAILED, + SCSI_STATE_SEND_COMMAND, + SCSI_STATE_NEXT_PHASE, + SCSI_STATE_END_PHASE, + SCSI_STATE_READ_DATA, + SCSI_STATE_WRITE_DATA, + SCSI_STATE_READ_STATUS, + SCSI_STATE_READ_MESSAGE } scsi_state_t; typedef struct scb_t { - uint16_t command; - uint16_t enable; - uint32_t lba_addr; - uint32_t sys_buf_addr; - uint32_t sys_buf_byte_count; - uint32_t term_status_block_addr; - uint32_t scb_chain_addr; - uint16_t block_count; - uint16_t block_length; + uint16_t command; + uint16_t enable; + uint32_t lba_addr; + uint32_t sys_buf_addr; + uint32_t sys_buf_byte_count; + uint32_t term_status_block_addr; + uint32_t scb_chain_addr; + uint16_t block_count; + uint16_t block_length; } scb_t; typedef struct scsi_ibm_t { - rom_t bios_rom; + rom_t bios_rom; - uint8_t pos_regs[8]; + uint8_t pos_regs[8]; - uint8_t basic_ctrl; - uint32_t command; + uint8_t basic_ctrl; + uint32_t command; - uint8_t attention; - uint8_t attention_pending; - int attention_waiting; + uint8_t attention; + uint8_t attention_pending; + int attention_waiting; - uint8_t cir[4]; - uint8_t cir_pending[4]; + uint8_t cir[4]; + uint8_t cir_pending[4]; - uint8_t irq_status; + uint8_t irq_status; - uint32_t scb_addr; + uint32_t scb_addr; - uint8_t status; + uint8_t status; - int in_invalid; - int in_reset; - sbc_state_t scb_state; + int in_invalid; + int in_reset; + sbc_state_t scb_state; - scb_t scb; - int scb_id; + scb_t scb; + int scb_id; - int cmd_status; - int cir_status; + int cmd_status; + int cir_status; - uint8_t pacing; + uint8_t pacing; - uint8_t buf[0x600]; + uint8_t buf[0x600]; - uint8_t int_buffer[512]; + uint8_t int_buffer[512]; - struct { - int phys_id; - int lun_id; - } dev_id[16]; + struct { + int phys_id; + int lun_id; + } dev_id[16]; - struct { - int idx, len; - uint8_t data[256]; + struct { + int idx, len; + uint8_t data[256]; - int data_idx, data_len; - uint32_t data_pointer; + int data_idx, data_len; + uint32_t data_pointer; - uint8_t last_status; + uint8_t last_status; - int bytes_transferred; + int bytes_transferred; - int target_id; - } cdb; + int target_id; + } cdb; - int irq_requests[16]; + int irq_requests[16]; - int cmd_timer; - pc_timer_t callback_timer; + int cmd_timer; + pc_timer_t callback_timer; - scsi_state_t scsi_state; - scsi_bus_t bus; + scsi_state_t scsi_state; + scsi_bus_t bus; } scsi_ibm_t; -#define CTRL_RESET (1 << 7) +#define CTRL_RESET (1 << 7) #define CTRL_DMA_ENA (1 << 1) #define CTRL_IRQ_ENA (1 << 0) -#define STATUS_CMD_FULL (1 << 3) +#define STATUS_CMD_FULL (1 << 3) #define STATUS_CMD_EMPTY (1 << 2) -#define STATUS_IRQ (1 << 1) -#define STATUS_BUSY (1 << 0) +#define STATUS_IRQ (1 << 1) +#define STATUS_BUSY (1 << 0) #define ENABLE_PT (1 << 12) -#define CMD_MASK 0xff3f -#define CMD_ASSIGN 0x040e -#define CMD_DEVICE_INQUIRY 0x1c0b -#define CMD_DMA_PACING_CONTROL 0x040d -#define CMD_FEATURE_CONTROL 0x040c -#define CMD_GET_POS_INFO 0x1c0a -#define CMD_INVALID_412 0x0412 -#define CMD_GET_COMPLETE_STATUS 0x1c07 -#define CMD_READ_DATA 0x1c01 +#define CMD_MASK 0xff3f +#define CMD_ASSIGN 0x040e +#define CMD_DEVICE_INQUIRY 0x1c0b +#define CMD_DMA_PACING_CONTROL 0x040d +#define CMD_FEATURE_CONTROL 0x040c +#define CMD_GET_POS_INFO 0x1c0a +#define CMD_INVALID_412 0x0412 +#define CMD_GET_COMPLETE_STATUS 0x1c07 +#define CMD_READ_DATA 0x1c01 #define CMD_READ_DEVICE_CAPACITY 0x1c09 -#define CMD_REQUEST_SENSE 0x1c08 -#define CMD_RESET 0x0400 -#define CMD_SEND_OTHER_SCSI 0x241f -#define CMD_UNKNOWN_1c10 0x1c10 -#define CMD_UNKNOWN_1c11 0x1c11 -#define CMD_WRITE_DATA 0x1c02 -#define CMD_VERIFY 0x1c03 +#define CMD_REQUEST_SENSE 0x1c08 +#define CMD_RESET 0x0400 +#define CMD_SEND_OTHER_SCSI 0x241f +#define CMD_UNKNOWN_1c10 0x1c10 +#define CMD_UNKNOWN_1c11 0x1c11 +#define CMD_WRITE_DATA 0x1c02 +#define CMD_VERIFY 0x1c03 -#define IRQ_TYPE_NONE 0x0 -#define IRQ_TYPE_SCB_COMPLETE 0x1 +#define IRQ_TYPE_NONE 0x0 +#define IRQ_TYPE_SCB_COMPLETE 0x1 #define IRQ_TYPE_SCB_COMPLETE_RETRY 0x5 #define IRQ_TYPE_ADAPTER_HW_FAILURE 0x7 -#define IRQ_TYPE_IMM_CMD_COMPLETE 0xa -#define IRQ_TYPE_COMMAND_FAIL 0xc -#define IRQ_TYPE_COMMAND_ERROR 0xe -#define IRQ_TYPE_SW_SEQ_ERROR 0xf -#define IRQ_TYPE_RESET_COMPLETE 0x10 +#define IRQ_TYPE_IMM_CMD_COMPLETE 0xa +#define IRQ_TYPE_COMMAND_FAIL 0xc +#define IRQ_TYPE_COMMAND_ERROR 0xe +#define IRQ_TYPE_SW_SEQ_ERROR 0xf +#define IRQ_TYPE_RESET_COMPLETE 0x10 static void scsi_rethink_irqs(scsi_ibm_t *scsi) { - int irq_pending = 0; - int c; + int irq_pending = 0; + int c; -/* pclog("scsi_rethink_irqs: basic_ctrl=%02x status=%02x\n", scsi->basic_ctrl, scsi->irq_status); - pclog(" "); - for (c = 0; c < 16; c++) - pclog(" %02x", scsi->irq_requests[c]); - pclog("\n");*/ + /* pclog("scsi_rethink_irqs: basic_ctrl=%02x status=%02x\n", scsi->basic_ctrl, scsi->irq_status); + pclog(" "); + for (c = 0; c < 16; c++) + pclog(" %02x", scsi->irq_requests[c]); + pclog("\n");*/ - if (!scsi->irq_status) { - for (c = 0; c < 16; c++) { - if (scsi->irq_requests[c] != IRQ_TYPE_NONE) { -// pclog(" Found IRQ on %i\n", c); - /*Found IRQ*/ - scsi->irq_status = c | (scsi->irq_requests[c] << 4); - scsi->status |= STATUS_IRQ; - irq_pending = 1; - break; - } - } - } else - irq_pending = 1; + if (!scsi->irq_status) { + for (c = 0; c < 16; c++) { + if (scsi->irq_requests[c] != IRQ_TYPE_NONE) { + // pclog(" Found IRQ on %i\n", c); + /*Found IRQ*/ + scsi->irq_status = c | (scsi->irq_requests[c] << 4); + scsi->status |= STATUS_IRQ; + irq_pending = 1; + break; + } + } + } else + irq_pending = 1; - if (scsi->basic_ctrl & CTRL_IRQ_ENA) { - if (irq_pending) { - picintlevel(1 << 14); -// pclog(" SCSI assert INT\n"); - } else { - /*No IRQs pending, clear IRQ state*/ - scsi->irq_status = 0; - scsi->status &= ~STATUS_IRQ; - picintc(1 << 14); -// pclog(" SCSI clear INT - no IRQ\n"); - } - } else { - picintc(1 << 14); -// pclog(" SCSI clear INT - IRQs disabled\n"); - } + if (scsi->basic_ctrl & CTRL_IRQ_ENA) { + if (irq_pending) { + picintlevel(1 << 14); + // pclog(" SCSI assert INT\n"); + } else { + /*No IRQs pending, clear IRQ state*/ + scsi->irq_status = 0; + scsi->status &= ~STATUS_IRQ; + picintc(1 << 14); + // pclog(" SCSI clear INT - no IRQ\n"); + } + } else { + picintc(1 << 14); + // pclog(" SCSI clear INT - IRQs disabled\n"); + } } static inline void scsi_ibm_set_irq(scsi_ibm_t *scsi, int id, int type) { -// pclog("scsi_ibm_set_irq id=%i type=%x %02x\n", id, type, scsi->irq_status); - scsi->irq_requests[id] = type; - if (!scsi->irq_status) /*Don't change IRQ status if one is currently being processed*/ - scsi_rethink_irqs(scsi); + // pclog("scsi_ibm_set_irq id=%i type=%x %02x\n", id, type, scsi->irq_status); + scsi->irq_requests[id] = type; + if (!scsi->irq_status) /*Don't change IRQ status if one is currently being processed*/ + scsi_rethink_irqs(scsi); } static inline void scsi_clear_irq(scsi_ibm_t *scsi, int id) { - scsi->irq_requests[id] = IRQ_TYPE_NONE; - scsi_rethink_irqs(scsi); + scsi->irq_requests[id] = IRQ_TYPE_NONE; + scsi_rethink_irqs(scsi); } static uint8_t scsi_read(uint16_t port, void *p) { - scsi_ibm_t *scsi = (scsi_ibm_t *)p; - uint8_t temp = 0xff; + scsi_ibm_t *scsi = (scsi_ibm_t *)p; + uint8_t temp = 0xff; - switch (port & 7) { - case 0: - case 1: - case 2: - case 3: /*Command Interface Register*/ - temp = scsi->cir_pending[port & 3]; - break; + switch (port & 7) { + case 0: + case 1: + case 2: + case 3: /*Command Interface Register*/ + temp = scsi->cir_pending[port & 3]; + break; - case 4: /*Attention Register*/ - temp = scsi->attention_pending; - break; - case 5: /*Basic Control Register*/ - temp = scsi->basic_ctrl; - break; - case 6: /*IRQ status*/ - temp = scsi->irq_status; - break; - case 7: /*Status*/ - temp = scsi->status; - if (scsi->cir_status == 0) - temp |= STATUS_CMD_EMPTY; - if (scsi->cir_status == 3) - temp |= STATUS_CMD_FULL; - break; - } + case 4: /*Attention Register*/ + temp = scsi->attention_pending; + break; + case 5: /*Basic Control Register*/ + temp = scsi->basic_ctrl; + break; + case 6: /*IRQ status*/ + temp = scsi->irq_status; + break; + case 7: /*Status*/ + temp = scsi->status; + if (scsi->cir_status == 0) + temp |= STATUS_CMD_EMPTY; + if (scsi->cir_status == 3) + temp |= STATUS_CMD_FULL; + break; + } -// pclog("scsi_read: port=%04x val=%02x %04x(%05x):%04x %i %02x\n", port, temp,CS,cs,cpu_state.pc, 0/*scsi->callback*/, BH); - return temp; + // pclog("scsi_read: port=%04x val=%02x %04x(%05x):%04x %i %02x\n", port, temp,CS,cs,cpu_state.pc, + // 0/*scsi->callback*/, BH); + return temp; } static void scsi_write(uint16_t port, uint8_t val, void *p) { - scsi_ibm_t *scsi = (scsi_ibm_t *)p; + scsi_ibm_t *scsi = (scsi_ibm_t *)p; -// pclog("scsi_write: port=%04x val=%02x %04x:%04x\n", port, val,CS,cpu_state.pc); + // pclog("scsi_write: port=%04x val=%02x %04x:%04x\n", port, val,CS,cpu_state.pc); - switch (port & 7) { - case 0: - case 1: - case 2: - case 3: /*Command Interface Register*/ - scsi->cir_pending[port & 3] = val; - if (port & 2) - scsi->cir_status |= 2; - else - scsi->cir_status |= 1; - break; + switch (port & 7) { + case 0: + case 1: + case 2: + case 3: /*Command Interface Register*/ + scsi->cir_pending[port & 3] = val; + if (port & 2) + scsi->cir_status |= 2; + else + scsi->cir_status |= 1; + break; - case 4: /*Attention Register*/ - scsi->attention_pending = val; - scsi->attention_waiting = 2; - scsi->status |= STATUS_BUSY; - break; + case 4: /*Attention Register*/ + scsi->attention_pending = val; + scsi->attention_waiting = 2; + scsi->status |= STATUS_BUSY; + break; - case 5: /*Basic Control Register*/ - if ((scsi->basic_ctrl & CTRL_RESET) && !(val & CTRL_RESET)) { -// pclog("SCSI reset\n"); - scsi->in_reset = 1; - scsi->cmd_timer = SCSI_TIME * 2; - scsi->status |= STATUS_BUSY; - } - scsi->basic_ctrl = val; - scsi_rethink_irqs(scsi); - break; + case 5: /*Basic Control Register*/ + if ((scsi->basic_ctrl & CTRL_RESET) && !(val & CTRL_RESET)) { + // pclog("SCSI reset\n"); + scsi->in_reset = 1; + scsi->cmd_timer = SCSI_TIME * 2; + scsi->status |= STATUS_BUSY; + } + scsi->basic_ctrl = val; + scsi_rethink_irqs(scsi); + break; -// default: -// fatal("scsi_write port=%04x val=%02x\n", port, val); - } + // default: + // fatal("scsi_write port=%04x val=%02x\n", port, val); + } } static uint16_t scsi_readw(uint16_t port, void *p) { - scsi_ibm_t *scsi = (scsi_ibm_t *)p; - uint16_t temp = 0xffff; + scsi_ibm_t *scsi = (scsi_ibm_t *)p; + uint16_t temp = 0xffff; - switch (port & 7) { - case 0: /*Command Interface Register*/ - temp = scsi->cir_pending[0] | (scsi->cir_pending[1] << 8); - break; - case 2: /*Command Interface Register*/ - temp = scsi->cir_pending[2] | (scsi->cir_pending[3] << 8); - break; + switch (port & 7) { + case 0: /*Command Interface Register*/ + temp = scsi->cir_pending[0] | (scsi->cir_pending[1] << 8); + break; + case 2: /*Command Interface Register*/ + temp = scsi->cir_pending[2] | (scsi->cir_pending[3] << 8); + break; -// default: -// fatal("scsi_readw port=%04x\n", port); - } + // default: + // fatal("scsi_readw port=%04x\n", port); + } -// pclog("scsi_readw: port=%04x val=%04x\n", port, temp); - return temp; + // pclog("scsi_readw: port=%04x val=%04x\n", port, temp); + return temp; } static void scsi_writew(uint16_t port, uint16_t val, void *p) { - scsi_ibm_t *scsi = (scsi_ibm_t *)p; + scsi_ibm_t *scsi = (scsi_ibm_t *)p; - switch (port & 7) { - case 0: /*Command Interface Register*/ - scsi->cir_pending[0] = val & 0xff; - scsi->cir_pending[1] = val >> 8; - scsi->cir_status |= 1; - break; - case 2: /*Command Interface Register*/ - scsi->cir_pending[2] = val & 0xff; - scsi->cir_pending[3] = val >> 8; - scsi->cir_status |= 2; - break; + switch (port & 7) { + case 0: /*Command Interface Register*/ + scsi->cir_pending[0] = val & 0xff; + scsi->cir_pending[1] = val >> 8; + scsi->cir_status |= 1; + break; + case 2: /*Command Interface Register*/ + scsi->cir_pending[2] = val & 0xff; + scsi->cir_pending[3] = val >> 8; + scsi->cir_status |= 2; + break; -// default: -// fatal("scsi_writew port=%04x val=%04x\n", port, val); - } + // default: + // fatal("scsi_writew port=%04x val=%04x\n", port, val); + } -// pclog("scsi_writew: port=%04x val=%04x\n", port, val); + // pclog("scsi_writew: port=%04x val=%04x\n", port, val); } static void sg_fetch_next(scsi_ibm_t *scsi) { - if (scsi->scb.sys_buf_byte_count > 0) { - scsi->cdb.data_idx = 0; - scsi->cdb.data_pointer = mem_readl_phys(scsi->scb.sys_buf_addr); - scsi->cdb.data_len = mem_readl_phys(scsi->scb.sys_buf_addr + 4); -// pclog("SG list: from %08x addr=%08x len=%08x\n", scsi->scb.sys_buf_addr, scsi->cdb.data_pointer, scsi->cdb.data_len); - scsi->scb.sys_buf_addr += 8; - scsi->scb.sys_buf_byte_count -= 8; - } + if (scsi->scb.sys_buf_byte_count > 0) { + scsi->cdb.data_idx = 0; + scsi->cdb.data_pointer = mem_readl_phys(scsi->scb.sys_buf_addr); + scsi->cdb.data_len = mem_readl_phys(scsi->scb.sys_buf_addr + 4); + // pclog("SG list: from %08x addr=%08x len=%08x\n", scsi->scb.sys_buf_addr, + // scsi->cdb.data_pointer, scsi->cdb.data_len); + scsi->scb.sys_buf_addr += 8; + scsi->scb.sys_buf_byte_count -= 8; + } } static void process_ibm_cmd(void *p) { - scsi_ibm_t *scsi = (scsi_ibm_t *)p; - scb_t *scb = &scsi->scb; - int c; - int old_scb_state; + scsi_ibm_t *scsi = (scsi_ibm_t *)p; + scb_t *scb = &scsi->scb; + int c; + int old_scb_state; -// pclog("scsi_callback: in_reset=%i command=%x\n", scsi->in_reset, scsi->command); - if (scsi->in_reset) { - scsi->status &= ~STATUS_BUSY; + // pclog("scsi_callback: in_reset=%i command=%x\n", scsi->in_reset, scsi->command); + if (scsi->in_reset) { + scsi->status &= ~STATUS_BUSY; - scsi->irq_status = 0; - for (c = 0; c < 16; c++) - scsi_clear_irq(scsi, c); - if (scsi->in_reset == 1) { - scsi->basic_ctrl |= CTRL_IRQ_ENA; - scsi_ibm_set_irq(scsi, 0xf, IRQ_TYPE_RESET_COMPLETE); - } else - scsi_ibm_set_irq(scsi, 0xf, IRQ_TYPE_RESET_COMPLETE); + scsi->irq_status = 0; + for (c = 0; c < 16; c++) + scsi_clear_irq(scsi, c); + if (scsi->in_reset == 1) { + scsi->basic_ctrl |= CTRL_IRQ_ENA; + scsi_ibm_set_irq(scsi, 0xf, IRQ_TYPE_RESET_COMPLETE); + } else + scsi_ibm_set_irq(scsi, 0xf, IRQ_TYPE_RESET_COMPLETE); - /*Reset device mappings*/ - for (c = 0; c < 7; c++) { - scsi->dev_id[c].phys_id = c; - scsi->dev_id[c].lun_id = 0; - } - for (; c < 15; c++) - scsi->dev_id[c].phys_id = -1; + /*Reset device mappings*/ + for (c = 0; c < 7; c++) { + scsi->dev_id[c].phys_id = c; + scsi->dev_id[c].lun_id = 0; + } + for (; c < 15; c++) + scsi->dev_id[c].phys_id = -1; - scsi->in_reset = 0; -// pclog("scsi reset complete\n"); - return; - } - if (scsi->in_invalid) { - scsi_ibm_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_COMMAND_ERROR); - scsi->in_invalid = 0; - return; - } - do { - old_scb_state = scsi->scb_state; + scsi->in_reset = 0; + // pclog("scsi reset complete\n"); + return; + } + if (scsi->in_invalid) { + scsi_ibm_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_COMMAND_ERROR); + scsi->in_invalid = 0; + return; + } + do { + old_scb_state = scsi->scb_state; -// pclog("scb_state=%i\n", scsi->scb_state); - switch (scsi->scb_state) { - case SCB_STATE_IDLE:break; + // pclog("scb_state=%i\n", scsi->scb_state); + switch (scsi->scb_state) { + case SCB_STATE_IDLE: + break; - case SCB_STATE_START: - if (scsi->dev_id[scsi->scb_id].phys_id == -1) { - scsi_ibm_set_irq(scsi, scsi->scb_id, IRQ_TYPE_COMMAND_FAIL); - scsi->scb_state = SCB_STATE_IDLE; - mem_writew_phys(scb->term_status_block_addr + 0x7 * 2, (0xe << 8) | 0); - mem_writew_phys(scb->term_status_block_addr + 0x8 * 2, (0xa << 8) | 0); - break; - } + case SCB_STATE_START: + if (scsi->dev_id[scsi->scb_id].phys_id == -1) { + scsi_ibm_set_irq(scsi, scsi->scb_id, IRQ_TYPE_COMMAND_FAIL); + scsi->scb_state = SCB_STATE_IDLE; + mem_writew_phys(scb->term_status_block_addr + 0x7 * 2, (0xe << 8) | 0); + mem_writew_phys(scb->term_status_block_addr + 0x8 * 2, (0xa << 8) | 0); + break; + } - scb->command = mem_readw_phys(scsi->scb_addr); - scb->enable = mem_readw_phys(scsi->scb_addr + 0x02); - scb->lba_addr = mem_readl_phys(scsi->scb_addr + 0x04); - scb->sys_buf_addr = mem_readl_phys(scsi->scb_addr + 0x08); - scb->sys_buf_byte_count = mem_readl_phys(scsi->scb_addr + 0x0c); - scb->term_status_block_addr = mem_readl_phys(scsi->scb_addr + 0x10); - scb->scb_chain_addr = mem_readl_phys(scsi->scb_addr + 0x14); - scb->block_count = mem_readw_phys(scsi->scb_addr + 0x18); - scb->block_length = mem_readw_phys(scsi->scb_addr + 0x1a); + scb->command = mem_readw_phys(scsi->scb_addr); + scb->enable = mem_readw_phys(scsi->scb_addr + 0x02); + scb->lba_addr = mem_readl_phys(scsi->scb_addr + 0x04); + scb->sys_buf_addr = mem_readl_phys(scsi->scb_addr + 0x08); + scb->sys_buf_byte_count = mem_readl_phys(scsi->scb_addr + 0x0c); + scb->term_status_block_addr = mem_readl_phys(scsi->scb_addr + 0x10); + scb->scb_chain_addr = mem_readl_phys(scsi->scb_addr + 0x14); + scb->block_count = mem_readw_phys(scsi->scb_addr + 0x18); + scb->block_length = mem_readw_phys(scsi->scb_addr + 0x1a); -/* pclog("SCB : \n" - " Command = %04x\n" - " Enable = %04x\n" - " LBA addr = %08x\n" - " System buffer addr = %08x\n" - " System buffer byte count = %08x\n" - " Terminate status block addr = %08x\n" - " SCB chain address = %08x\n" - " Block count = %04x\n" - " Block length = %04x\n", - scb->command, scb->enable, scb->lba_addr, - scb->sys_buf_addr, scb->sys_buf_byte_count, - scb->term_status_block_addr, scb->scb_chain_addr, - scb->block_count, scb->block_length);*/ + /* pclog("SCB : \n" + " Command = %04x\n" + " Enable = %04x\n" + " LBA addr = %08x\n" + " System buffer addr = %08x\n" + " System buffer byte count = %08x\n" + " Terminate status block addr = %08x\n" + " SCB chain address = %08x\n" + " Block count = %04x\n" + " Block length = %04x\n", + scb->command, scb->enable, scb->lba_addr, + scb->sys_buf_addr, scb->sys_buf_byte_count, + scb->term_status_block_addr, scb->scb_chain_addr, + scb->block_count, scb->block_length);*/ - if (scb->enable & ENABLE_PT) - sg_fetch_next(scsi); - else { - scsi->cdb.data_idx = 0; - scsi->cdb.data_pointer = scb->sys_buf_addr; - scsi->cdb.data_len = scb->sys_buf_byte_count; - } + if (scb->enable & ENABLE_PT) + sg_fetch_next(scsi); + else { + scsi->cdb.data_idx = 0; + scsi->cdb.data_pointer = scb->sys_buf_addr; + scsi->cdb.data_len = scb->sys_buf_byte_count; + } - switch (scb->command & CMD_MASK) { - case CMD_GET_COMPLETE_STATUS:mem_writew_phys(scb->sys_buf_addr + 0x0 * 2, 0x201); /*SCB status*/ - mem_writew_phys(scb->sys_buf_addr + 0x1 * 2, 0); /*Retry counts*/ - mem_writel_phys(scb->sys_buf_addr + 0x2 * 2, 0); /*Residual byte count*/ - mem_writel_phys(scb->sys_buf_addr + 0x4 * 2, 0); /*Scatter/gather list element address*/ - mem_writew_phys(scb->sys_buf_addr + 0x6 * 2, 0xc); /*Device dependent status length*/ - mem_writew_phys(scb->sys_buf_addr + 0x7 * 2, scsi->cmd_status << 8); - mem_writew_phys(scb->sys_buf_addr + 0x8 * 2, 0); /*Error*/ - mem_writew_phys(scb->sys_buf_addr + 0x9 * 2, 0); /*Reserved*/ - mem_writew_phys(scb->sys_buf_addr + 0xa * 2, 0); /*Cache information status*/ - mem_writel_phys(scb->sys_buf_addr + 0xb * 2, scsi->scb_addr); - scsi->scb_state = SCB_STATE_COMPLETE; - break; + switch (scb->command & CMD_MASK) { + case CMD_GET_COMPLETE_STATUS: + mem_writew_phys(scb->sys_buf_addr + 0x0 * 2, 0x201); /*SCB status*/ + mem_writew_phys(scb->sys_buf_addr + 0x1 * 2, 0); /*Retry counts*/ + mem_writel_phys(scb->sys_buf_addr + 0x2 * 2, 0); /*Residual byte count*/ + mem_writel_phys(scb->sys_buf_addr + 0x4 * 2, 0); /*Scatter/gather list element address*/ + mem_writew_phys(scb->sys_buf_addr + 0x6 * 2, 0xc); /*Device dependent status length*/ + mem_writew_phys(scb->sys_buf_addr + 0x7 * 2, scsi->cmd_status << 8); + mem_writew_phys(scb->sys_buf_addr + 0x8 * 2, 0); /*Error*/ + mem_writew_phys(scb->sys_buf_addr + 0x9 * 2, 0); /*Reserved*/ + mem_writew_phys(scb->sys_buf_addr + 0xa * 2, 0); /*Cache information status*/ + mem_writel_phys(scb->sys_buf_addr + 0xb * 2, scsi->scb_addr); + scsi->scb_state = SCB_STATE_COMPLETE; + break; - case CMD_UNKNOWN_1c10: - for (c = 0; c < 0x600 && c < scb->sys_buf_byte_count; c++) - scsi->buf[c] = mem_readb_phys(scb->sys_buf_addr + c); - scsi->scb_state = SCB_STATE_COMPLETE; - break; - case CMD_UNKNOWN_1c11: - for (c = 0; c < 0x600 && c < scb->sys_buf_byte_count; c++) - mem_writeb_phys(scb->sys_buf_addr + c, scsi->buf[c]); - scsi->scb_state = SCB_STATE_COMPLETE; - break; + case CMD_UNKNOWN_1c10: + for (c = 0; c < 0x600 && c < scb->sys_buf_byte_count; c++) + scsi->buf[c] = mem_readb_phys(scb->sys_buf_addr + c); + scsi->scb_state = SCB_STATE_COMPLETE; + break; + case CMD_UNKNOWN_1c11: + for (c = 0; c < 0x600 && c < scb->sys_buf_byte_count; c++) + mem_writeb_phys(scb->sys_buf_addr + c, scsi->buf[c]); + scsi->scb_state = SCB_STATE_COMPLETE; + break; - case CMD_GET_POS_INFO:mem_writew_phys(scb->sys_buf_addr + 0x0 * 2, 0x8eff); - mem_writew_phys(scb->sys_buf_addr + 0x1 * 2, scsi->pos_regs[3] | (scsi->pos_regs[2] << 8)); - mem_writew_phys(scb->sys_buf_addr + 0x2 * 2, 0x0e | (scsi->pos_regs[4] << 8)); - mem_writew_phys(scb->sys_buf_addr + 0x3 * 2, 1 << 12); - mem_writew_phys(scb->sys_buf_addr + 0x4 * 2, (7 << 8) | 8); - mem_writew_phys(scb->sys_buf_addr + 0x5 * 2, (16 << 8) | scsi->pacing); - mem_writew_phys(scb->sys_buf_addr + 0x6 * 2, (30 << 8) | 1); - mem_writew_phys(scb->sys_buf_addr + 0x7 * 2, 0); - mem_writew_phys(scb->sys_buf_addr + 0x8 * 2, 0); - scsi->scb_state = SCB_STATE_COMPLETE; - break; + case CMD_GET_POS_INFO: + mem_writew_phys(scb->sys_buf_addr + 0x0 * 2, 0x8eff); + mem_writew_phys(scb->sys_buf_addr + 0x1 * 2, scsi->pos_regs[3] | (scsi->pos_regs[2] << 8)); + mem_writew_phys(scb->sys_buf_addr + 0x2 * 2, 0x0e | (scsi->pos_regs[4] << 8)); + mem_writew_phys(scb->sys_buf_addr + 0x3 * 2, 1 << 12); + mem_writew_phys(scb->sys_buf_addr + 0x4 * 2, (7 << 8) | 8); + mem_writew_phys(scb->sys_buf_addr + 0x5 * 2, (16 << 8) | scsi->pacing); + mem_writew_phys(scb->sys_buf_addr + 0x6 * 2, (30 << 8) | 1); + mem_writew_phys(scb->sys_buf_addr + 0x7 * 2, 0); + mem_writew_phys(scb->sys_buf_addr + 0x8 * 2, 0); + scsi->scb_state = SCB_STATE_COMPLETE; + break; - case CMD_DEVICE_INQUIRY:scsi->cdb.data[0] = SCSI_INQUIRY; - scsi->cdb.data[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/ - scsi->cdb.data[2] = 0; /*Page code*/ - scsi->cdb.data[3] = 0; - scsi->cdb.data[4] = scb->sys_buf_byte_count; /*Allocation length*/ - scsi->cdb.data[5] = 0; /*Control*/ - scsi->cdb.idx = 0; - scsi->cdb.len = 6; - scsi->cdb.target_id = scsi->dev_id[scsi->scb_id].phys_id; - scsi->cdb.data_pointer = scb->sys_buf_addr; - scsi->cdb.data_idx = 0; - scsi->cdb.data_len = scb->sys_buf_byte_count; - scsi->scsi_state = SCSI_STATE_SELECT; - scsi->scb_state = SCB_STATE_WAIT; - return; + case CMD_DEVICE_INQUIRY: + scsi->cdb.data[0] = SCSI_INQUIRY; + scsi->cdb.data[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/ + scsi->cdb.data[2] = 0; /*Page code*/ + scsi->cdb.data[3] = 0; + scsi->cdb.data[4] = scb->sys_buf_byte_count; /*Allocation length*/ + scsi->cdb.data[5] = 0; /*Control*/ + scsi->cdb.idx = 0; + scsi->cdb.len = 6; + scsi->cdb.target_id = scsi->dev_id[scsi->scb_id].phys_id; + scsi->cdb.data_pointer = scb->sys_buf_addr; + scsi->cdb.data_idx = 0; + scsi->cdb.data_len = scb->sys_buf_byte_count; + scsi->scsi_state = SCSI_STATE_SELECT; + scsi->scb_state = SCB_STATE_WAIT; + return; - case CMD_SEND_OTHER_SCSI: -// pclog("SEND_OTHER_SCSI:"); - for (c = 0; c < 12; c++) { - scsi->cdb.data[c] = mem_readb_phys(scsi->scb_addr + 0x18 + c); -// pclog(" %02x", scsi->cdb.data[c]); - } -// pclog("\n"); - scsi->cdb.data[1] = (scsi->cdb.data[1] & 0x1f) | (scsi->dev_id[scsi->scb_id].lun_id << 5); /*Patch correct LUN into command*/ - scsi->cdb.idx = 0; - scsi->cdb.len = (scb->lba_addr & 0xff) ? (scb->lba_addr & 0xff) : 6; -// pclog("SEND_OTHER_SCSI: %04x\n", scb->lba_addr & 0xffff); - scsi->cdb.target_id = scsi->dev_id[scsi->scb_id].phys_id; - scsi->scsi_state = SCSI_STATE_SELECT; - scsi->scb_state = SCB_STATE_WAIT; - return; + case CMD_SEND_OTHER_SCSI: + // pclog("SEND_OTHER_SCSI:"); + for (c = 0; c < 12; c++) { + scsi->cdb.data[c] = mem_readb_phys(scsi->scb_addr + 0x18 + c); + // pclog(" %02x", scsi->cdb.data[c]); + } + // pclog("\n"); + scsi->cdb.data[1] = (scsi->cdb.data[1] & 0x1f) | + (scsi->dev_id[scsi->scb_id].lun_id << 5); /*Patch correct LUN into command*/ + scsi->cdb.idx = 0; + scsi->cdb.len = (scb->lba_addr & 0xff) ? (scb->lba_addr & 0xff) : 6; + // pclog("SEND_OTHER_SCSI: %04x\n", scb->lba_addr & 0xffff); + scsi->cdb.target_id = scsi->dev_id[scsi->scb_id].phys_id; + scsi->scsi_state = SCSI_STATE_SELECT; + scsi->scb_state = SCB_STATE_WAIT; + return; - case CMD_READ_DEVICE_CAPACITY:scsi->cdb.data[0] = SCSI_READ_CAPACITY_10; - scsi->cdb.data[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/ - scsi->cdb.data[2] = 0; /*LBA*/ - scsi->cdb.data[3] = 0; - scsi->cdb.data[4] = 0; - scsi->cdb.data[5] = 0; - scsi->cdb.data[6] = 0; /*Reserved*/ - scsi->cdb.data[7] = 0; - scsi->cdb.data[8] = 0; - scsi->cdb.data[9] = 0; /*Control*/ - scsi->cdb.idx = 0; - scsi->cdb.len = 10; - scsi->cdb.target_id = scsi->dev_id[scsi->scb_id].phys_id; - scsi->scsi_state = SCSI_STATE_SELECT; - scsi->scb_state = SCB_STATE_WAIT; - return; + case CMD_READ_DEVICE_CAPACITY: + scsi->cdb.data[0] = SCSI_READ_CAPACITY_10; + scsi->cdb.data[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/ + scsi->cdb.data[2] = 0; /*LBA*/ + scsi->cdb.data[3] = 0; + scsi->cdb.data[4] = 0; + scsi->cdb.data[5] = 0; + scsi->cdb.data[6] = 0; /*Reserved*/ + scsi->cdb.data[7] = 0; + scsi->cdb.data[8] = 0; + scsi->cdb.data[9] = 0; /*Control*/ + scsi->cdb.idx = 0; + scsi->cdb.len = 10; + scsi->cdb.target_id = scsi->dev_id[scsi->scb_id].phys_id; + scsi->scsi_state = SCSI_STATE_SELECT; + scsi->scb_state = SCB_STATE_WAIT; + return; - case CMD_READ_DATA:scsi->cdb.data[0] = SCSI_READ_10; - scsi->cdb.data[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/ - scsi->cdb.data[2] = (scb->lba_addr >> 24) & 0xff; /*LBA*/ - scsi->cdb.data[3] = (scb->lba_addr >> 16) & 0xff; - scsi->cdb.data[4] = (scb->lba_addr >> 8) & 0xff; - scsi->cdb.data[5] = scb->lba_addr & 0xff; - scsi->cdb.data[6] = 0; /*Reserved*/ - scsi->cdb.data[7] = (scb->block_count >> 8) & 0xff; - scsi->cdb.data[8] = scb->block_count & 0xff; - scsi->cdb.data[9] = 0; /*Control*/ - scsi->cdb.idx = 0; - scsi->cdb.len = 10; - scsi->cdb.target_id = scsi->dev_id[scsi->scb_id].phys_id; - scsi->scsi_state = SCSI_STATE_SELECT; - scsi->scb_state = SCB_STATE_WAIT; - return; + case CMD_READ_DATA: + scsi->cdb.data[0] = SCSI_READ_10; + scsi->cdb.data[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/ + scsi->cdb.data[2] = (scb->lba_addr >> 24) & 0xff; /*LBA*/ + scsi->cdb.data[3] = (scb->lba_addr >> 16) & 0xff; + scsi->cdb.data[4] = (scb->lba_addr >> 8) & 0xff; + scsi->cdb.data[5] = scb->lba_addr & 0xff; + scsi->cdb.data[6] = 0; /*Reserved*/ + scsi->cdb.data[7] = (scb->block_count >> 8) & 0xff; + scsi->cdb.data[8] = scb->block_count & 0xff; + scsi->cdb.data[9] = 0; /*Control*/ + scsi->cdb.idx = 0; + scsi->cdb.len = 10; + scsi->cdb.target_id = scsi->dev_id[scsi->scb_id].phys_id; + scsi->scsi_state = SCSI_STATE_SELECT; + scsi->scb_state = SCB_STATE_WAIT; + return; - case CMD_REQUEST_SENSE:scsi->cdb.data[0] = SCSI_REQUEST_SENSE; - scsi->cdb.data[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/ - scsi->cdb.data[2] = 0; - scsi->cdb.data[3] = 0; - scsi->cdb.data[4] = scb->block_count & 0xff; /*Allocation length*/ - scsi->cdb.data[5] = 0; - scsi->cdb.idx = 0; - scsi->cdb.len = 6; - scsi->cdb.target_id = scsi->dev_id[scsi->scb_id].phys_id; - scsi->scsi_state = SCSI_STATE_SELECT; - scsi->scb_state = SCB_STATE_WAIT; - return; + case CMD_REQUEST_SENSE: + scsi->cdb.data[0] = SCSI_REQUEST_SENSE; + scsi->cdb.data[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/ + scsi->cdb.data[2] = 0; + scsi->cdb.data[3] = 0; + scsi->cdb.data[4] = scb->block_count & 0xff; /*Allocation length*/ + scsi->cdb.data[5] = 0; + scsi->cdb.idx = 0; + scsi->cdb.len = 6; + scsi->cdb.target_id = scsi->dev_id[scsi->scb_id].phys_id; + scsi->scsi_state = SCSI_STATE_SELECT; + scsi->scb_state = SCB_STATE_WAIT; + return; - case CMD_WRITE_DATA:scsi->cdb.data[0] = SCSI_WRITE_10; - scsi->cdb.data[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/ - scsi->cdb.data[2] = (scb->lba_addr >> 24) & 0xff; /*LBA*/ - scsi->cdb.data[3] = (scb->lba_addr >> 16) & 0xff; - scsi->cdb.data[4] = (scb->lba_addr >> 8) & 0xff; - scsi->cdb.data[5] = scb->lba_addr & 0xff; - scsi->cdb.data[6] = 0; /*Reserved*/ - scsi->cdb.data[7] = (scb->block_count >> 8) & 0xff; - scsi->cdb.data[8] = scb->block_count & 0xff; - scsi->cdb.data[9] = 0; /*Control*/ - scsi->cdb.idx = 0; - scsi->cdb.len = 10; - scsi->cdb.target_id = scsi->dev_id[scsi->scb_id].phys_id; - scsi->scsi_state = SCSI_STATE_SELECT; - scsi->scb_state = SCB_STATE_WAIT; - return; + case CMD_WRITE_DATA: + scsi->cdb.data[0] = SCSI_WRITE_10; + scsi->cdb.data[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/ + scsi->cdb.data[2] = (scb->lba_addr >> 24) & 0xff; /*LBA*/ + scsi->cdb.data[3] = (scb->lba_addr >> 16) & 0xff; + scsi->cdb.data[4] = (scb->lba_addr >> 8) & 0xff; + scsi->cdb.data[5] = scb->lba_addr & 0xff; + scsi->cdb.data[6] = 0; /*Reserved*/ + scsi->cdb.data[7] = (scb->block_count >> 8) & 0xff; + scsi->cdb.data[8] = scb->block_count & 0xff; + scsi->cdb.data[9] = 0; /*Control*/ + scsi->cdb.idx = 0; + scsi->cdb.len = 10; + scsi->cdb.target_id = scsi->dev_id[scsi->scb_id].phys_id; + scsi->scsi_state = SCSI_STATE_SELECT; + scsi->scb_state = SCB_STATE_WAIT; + return; - case CMD_VERIFY:scsi->cdb.data[0] = SCSI_VERIFY_10; - scsi->cdb.data[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/ - scsi->cdb.data[2] = (scb->lba_addr >> 24) & 0xff; /*LBA*/ - scsi->cdb.data[3] = (scb->lba_addr >> 16) & 0xff; - scsi->cdb.data[4] = (scb->lba_addr >> 8) & 0xff; - scsi->cdb.data[5] = scb->lba_addr & 0xff; - scsi->cdb.data[6] = 0; /*Reserved*/ - scsi->cdb.data[7] = (scb->block_count >> 8) & 0xff; - scsi->cdb.data[8] = scb->block_count & 0xff; - scsi->cdb.data[9] = 0; /*Control*/ - scsi->cdb.idx = 0; - scsi->cdb.len = 10; - scsi->cdb.target_id = scsi->dev_id[scsi->scb_id].phys_id; - scsi->cdb.data_len = 0; - scsi->scsi_state = SCSI_STATE_SELECT; - scsi->scb_state = SCB_STATE_WAIT; - return; + case CMD_VERIFY: + scsi->cdb.data[0] = SCSI_VERIFY_10; + scsi->cdb.data[1] = scsi->dev_id[scsi->scb_id].lun_id << 5; /*LUN*/ + scsi->cdb.data[2] = (scb->lba_addr >> 24) & 0xff; /*LBA*/ + scsi->cdb.data[3] = (scb->lba_addr >> 16) & 0xff; + scsi->cdb.data[4] = (scb->lba_addr >> 8) & 0xff; + scsi->cdb.data[5] = scb->lba_addr & 0xff; + scsi->cdb.data[6] = 0; /*Reserved*/ + scsi->cdb.data[7] = (scb->block_count >> 8) & 0xff; + scsi->cdb.data[8] = scb->block_count & 0xff; + scsi->cdb.data[9] = 0; /*Control*/ + scsi->cdb.idx = 0; + scsi->cdb.len = 10; + scsi->cdb.target_id = scsi->dev_id[scsi->scb_id].phys_id; + scsi->cdb.data_len = 0; + scsi->scsi_state = SCSI_STATE_SELECT; + scsi->scb_state = SCB_STATE_WAIT; + return; #ifndef RELEASE_BUILD - default:fatal("SCB command %04x\n", scb->command); + default: + fatal("SCB command %04x\n", scb->command); #endif - } - break; + } + break; - case SCB_STATE_WAIT: - if (scsi->scsi_state == SCSI_STATE_IDLE) { - if (scsi->cdb.last_status == STATUS_GOOD) - scsi->scb_state = SCB_STATE_COMPLETE; - else if (scsi->cdb.last_status == STATUS_CHECK_CONDITION) { - scsi_ibm_set_irq(scsi, scsi->scb_id, IRQ_TYPE_COMMAND_FAIL); - scsi->scb_state = SCB_STATE_IDLE; - mem_writew_phys(scb->term_status_block_addr + 0x7 * 2, (0xc << 8) | 2); - mem_writew_phys(scb->term_status_block_addr + 0x8 * 2, 0x20); - mem_writew_phys(scb->term_status_block_addr + 0xb * 2, scsi->scb_addr & 0xffff); - mem_writew_phys(scb->term_status_block_addr + 0xc * 2, scsi->scb_addr >> 16); - } + case SCB_STATE_WAIT: + if (scsi->scsi_state == SCSI_STATE_IDLE) { + if (scsi->cdb.last_status == STATUS_GOOD) + scsi->scb_state = SCB_STATE_COMPLETE; + else if (scsi->cdb.last_status == STATUS_CHECK_CONDITION) { + scsi_ibm_set_irq(scsi, scsi->scb_id, IRQ_TYPE_COMMAND_FAIL); + scsi->scb_state = SCB_STATE_IDLE; + mem_writew_phys(scb->term_status_block_addr + 0x7 * 2, (0xc << 8) | 2); + mem_writew_phys(scb->term_status_block_addr + 0x8 * 2, 0x20); + mem_writew_phys(scb->term_status_block_addr + 0xb * 2, scsi->scb_addr & 0xffff); + mem_writew_phys(scb->term_status_block_addr + 0xc * 2, scsi->scb_addr >> 16); + } #ifndef RELEASE_BUILD - else - fatal("SCB unknown result %02x\n", scsi->cdb.last_status); + else + fatal("SCB unknown result %02x\n", scsi->cdb.last_status); #endif - } else if (scsi->scsi_state == SCSI_STATE_SELECT_FAILED) { -// pclog("SCB_STATE_WAIT SELECT_FAILED\n"); - scsi_ibm_set_irq(scsi, scsi->scb_id, IRQ_TYPE_COMMAND_FAIL); - scsi->scb_state = SCB_STATE_IDLE; - mem_writew_phys(scb->term_status_block_addr + 0x7 * 2, (0xc << 8) | 2); - mem_writew_phys(scb->term_status_block_addr + 0x8 * 2, 0x10); - } + } else if (scsi->scsi_state == SCSI_STATE_SELECT_FAILED) { + // pclog("SCB_STATE_WAIT SELECT_FAILED\n"); + scsi_ibm_set_irq(scsi, scsi->scb_id, IRQ_TYPE_COMMAND_FAIL); + scsi->scb_state = SCB_STATE_IDLE; + mem_writew_phys(scb->term_status_block_addr + 0x7 * 2, (0xc << 8) | 2); + mem_writew_phys(scb->term_status_block_addr + 0x8 * 2, 0x10); + } #ifndef RELEASE_BUILD - else - fatal("SCB_STATE_WAIT other %i\n", scsi->scsi_state); + else + fatal("SCB_STATE_WAIT other %i\n", scsi->scsi_state); #endif - break; + break; - case SCB_STATE_COMPLETE: - if (scb->enable & 1) { - scsi->scb_state = SCB_STATE_START; - scsi->scb_addr = scb->scb_chain_addr; -// pclog("Next SCB - %08x\n", scsi->scb_addr); - } else { - scsi_ibm_set_irq(scsi, scsi->scb_id, IRQ_TYPE_SCB_COMPLETE); - scsi->scb_state = SCB_STATE_IDLE; - } - break; - } - } while (scsi->scb_state != old_scb_state); + case SCB_STATE_COMPLETE: + if (scb->enable & 1) { + scsi->scb_state = SCB_STATE_START; + scsi->scb_addr = scb->scb_chain_addr; + // pclog("Next SCB - %08x\n", scsi->scb_addr); + } else { + scsi_ibm_set_irq(scsi, scsi->scb_id, IRQ_TYPE_SCB_COMPLETE); + scsi->scb_state = SCB_STATE_IDLE; + } + break; + } + } while (scsi->scb_state != old_scb_state); } static void process_immediate_command(scsi_ibm_t *scsi) { - switch (scsi->command & CMD_MASK) { - case CMD_ASSIGN: -// pclog("Assign: adapter dev=%x scsi ID=%i LUN=%i\n", (scsi->command >> 16) & 0xf, (scsi->command >> 20) & 7, (scsi->command >> 24) & 7); - if (((scsi->command >> 16) & 0xf) == 0xf && ((scsi->command >> 20) & 7) == 7) /*Device 15 always adapter*/ - scsi_ibm_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE); - else if (((scsi->command >> 16) & 0xf) == 0xf) /*Can not re-assign device 15 (always adapter)*/ - scsi_ibm_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_COMMAND_FAIL); - else if (scsi->command & (1 << 23)) { - scsi->dev_id[(scsi->command >> 16) & 0xf].phys_id = -1; - scsi_ibm_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE); - } else if (((scsi->command >> 20) & 7) == 7) /*Can not assign adapter*/ - scsi_ibm_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_COMMAND_FAIL); - else { - scsi->dev_id[(scsi->command >> 16) & 0xf].phys_id = (scsi->command >> 20) & 7; - scsi->dev_id[(scsi->command >> 16) & 0xf].lun_id = (scsi->command >> 24) & 7; - scsi_ibm_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE); - } - break; + switch (scsi->command & CMD_MASK) { + case CMD_ASSIGN: + // pclog("Assign: adapter dev=%x scsi ID=%i LUN=%i\n", (scsi->command >> 16) & 0xf, (scsi->command + // >> 20) & 7, (scsi->command >> 24) & 7); + if (((scsi->command >> 16) & 0xf) == 0xf && ((scsi->command >> 20) & 7) == 7) /*Device 15 always adapter*/ + scsi_ibm_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE); + else if (((scsi->command >> 16) & 0xf) == 0xf) /*Can not re-assign device 15 (always adapter)*/ + scsi_ibm_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_COMMAND_FAIL); + else if (scsi->command & (1 << 23)) { + scsi->dev_id[(scsi->command >> 16) & 0xf].phys_id = -1; + scsi_ibm_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE); + } else if (((scsi->command >> 20) & 7) == 7) /*Can not assign adapter*/ + scsi_ibm_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_COMMAND_FAIL); + else { + scsi->dev_id[(scsi->command >> 16) & 0xf].phys_id = (scsi->command >> 20) & 7; + scsi->dev_id[(scsi->command >> 16) & 0xf].lun_id = (scsi->command >> 24) & 7; + scsi_ibm_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE); + } + break; - case CMD_DMA_PACING_CONTROL:scsi->pacing = scsi->cir[2]; -// pclog("Pacing control: %i\n", scsi->pacing); - scsi_ibm_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE); - break; + case CMD_DMA_PACING_CONTROL: + scsi->pacing = scsi->cir[2]; + // pclog("Pacing control: %i\n", scsi->pacing); + scsi_ibm_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE); + break; - case CMD_FEATURE_CONTROL: -// pclog("Feature control: timeout=%is d-rate=%i\n", (scsi->command >> 16) & 0x1fff, scsi->command >> 29); - scsi_ibm_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE); - break; + case CMD_FEATURE_CONTROL: + // pclog("Feature control: timeout=%is d-rate=%i\n", (scsi->command >> 16) & 0x1fff, scsi->command + // >> 29); + scsi_ibm_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE); + break; - case CMD_INVALID_412:scsi_ibm_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE); - break; + case CMD_INVALID_412: + scsi_ibm_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE); + break; - case CMD_RESET: - if ((scsi->attention & 0xf) == 0xf) /*Adapter reset*/ - { - scsi_bus_reset(&scsi->bus); - scsi->scb_state = SCB_STATE_IDLE; - } else /*Device reset*/ - { - } - scsi_ibm_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE); - break; + case CMD_RESET: + if ((scsi->attention & 0xf) == 0xf) /*Adapter reset*/ + { + scsi_bus_reset(&scsi->bus); + scsi->scb_state = SCB_STATE_IDLE; + } else /*Device reset*/ + { + } + scsi_ibm_set_irq(scsi, scsi->attention & 0x0f, IRQ_TYPE_IMM_CMD_COMPLETE); + break; - default:fatal("scsi_callback: Bad command %02x\n", scsi->command); - } + default: + fatal("scsi_callback: Bad command %02x\n", scsi->command); + } } static int wait_for_bus(scsi_bus_t *bus, int state, int req_needed) { - int c; + int c; - for (c = 0; c < 20; c++) { - int bus_state = scsi_bus_read(bus); + for (c = 0; c < 20; c++) { + int bus_state = scsi_bus_read(bus); - if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) == state && (bus_state & BUS_BSY)) { - if (!req_needed || (bus_state & BUS_REQ)) - return 1; - } - } + if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) == state && (bus_state & BUS_BSY)) { + if (!req_needed || (bus_state & BUS_REQ)) + return 1; + } + } - return 0; + return 0; } static void process_scsi(scsi_ibm_t *scsi) { - int c; - int bytes_transferred = 0; + int c; + int bytes_transferred = 0; - switch (scsi->scsi_state) { - case SCSI_STATE_IDLE:break; + switch (scsi->scsi_state) { + case SCSI_STATE_IDLE: + break; - case SCSI_STATE_SELECT:scsi->cdb.last_status = 0; -// pclog("Select target ID %i\n", scsi->cdb.target_id); - scsi_bus_update(&scsi->bus, BUS_SEL | BUS_SETDATA(1 << scsi->cdb.target_id)); - if (!(scsi_bus_read(&scsi->bus) & BUS_BSY) || scsi->cdb.target_id > 6) { -// pclog("STATE_SCSI_SELECT failed to select target %i\n", scsi->cdb.target_id); - scsi->scsi_state = SCSI_STATE_SELECT_FAILED; - if (!scsi->cmd_timer) - scsi->cmd_timer = 1; - break; - } + case SCSI_STATE_SELECT: + scsi->cdb.last_status = 0; + // pclog("Select target ID %i\n", scsi->cdb.target_id); + scsi_bus_update(&scsi->bus, BUS_SEL | BUS_SETDATA(1 << scsi->cdb.target_id)); + if (!(scsi_bus_read(&scsi->bus) & BUS_BSY) || scsi->cdb.target_id > 6) { + // pclog("STATE_SCSI_SELECT failed to select target %i\n", scsi->cdb.target_id); + scsi->scsi_state = SCSI_STATE_SELECT_FAILED; + if (!scsi->cmd_timer) + scsi->cmd_timer = 1; + break; + } - scsi_bus_update(&scsi->bus, 0); - if (!(scsi_bus_read(&scsi->bus) & BUS_BSY)) { -// pclog("STATE_SCSI_SELECT failed to select target %i 2\n", scsi->cdb.target_id); - scsi->scsi_state = SCSI_STATE_SELECT_FAILED; - if (!scsi->cmd_timer) - scsi->cmd_timer = 1; - break; - } + scsi_bus_update(&scsi->bus, 0); + if (!(scsi_bus_read(&scsi->bus) & BUS_BSY)) { + // pclog("STATE_SCSI_SELECT failed to select target %i 2\n", scsi->cdb.target_id); + scsi->scsi_state = SCSI_STATE_SELECT_FAILED; + if (!scsi->cmd_timer) + scsi->cmd_timer = 1; + break; + } - /*Device should now be selected*/ - if (!wait_for_bus(&scsi->bus, BUS_CD, 1)) { -// pclog("Device failed to request command\n"); - scsi->scsi_state = SCSI_STATE_SELECT_FAILED; - if (!scsi->cmd_timer) - scsi->cmd_timer = 1; - break; - } + /*Device should now be selected*/ + if (!wait_for_bus(&scsi->bus, BUS_CD, 1)) { + // pclog("Device failed to request command\n"); + scsi->scsi_state = SCSI_STATE_SELECT_FAILED; + if (!scsi->cmd_timer) + scsi->cmd_timer = 1; + break; + } - scsi->scsi_state = SCSI_STATE_SEND_COMMAND; - break; + scsi->scsi_state = SCSI_STATE_SEND_COMMAND; + break; - case SCSI_STATE_SELECT_FAILED:break; + case SCSI_STATE_SELECT_FAILED: + break; - case SCSI_STATE_SEND_COMMAND: - while (scsi->cdb.idx < scsi->cdb.len && bytes_transferred < MAX_BYTES_TRANSFERRED_PER_POLL) { - int bus_out; + case SCSI_STATE_SEND_COMMAND: + while (scsi->cdb.idx < scsi->cdb.len && bytes_transferred < MAX_BYTES_TRANSFERRED_PER_POLL) { + int bus_out; - for (c = 0; c < 20; c++) { - int bus_state = scsi_bus_read(&scsi->bus); + for (c = 0; c < 20; c++) { + int bus_state = scsi_bus_read(&scsi->bus); #ifndef RELEASE_BUILD - if (!(bus_state & BUS_BSY)) - fatal("SEND_COMMAND - dropped BSY\n"); - if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) != BUS_CD) - fatal("SEND_COMMAND - bus phase incorrect\n"); + if (!(bus_state & BUS_BSY)) + fatal("SEND_COMMAND - dropped BSY\n"); + if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) != BUS_CD) + fatal("SEND_COMMAND - bus phase incorrect\n"); #endif - if (bus_state & BUS_REQ) - break; - } - if (c == 20) { -// pclog("SEND_COMMAND timed out\n"); - break; - } + if (bus_state & BUS_REQ) + break; + } + if (c == 20) { + // pclog("SEND_COMMAND timed out\n"); + break; + } - bus_out = BUS_SETDATA(scsi->cdb.data[scsi->cdb.idx]); -// pclog(" Command send %02x %i\n", scsi->cdb.data[scsi->cdb.idx], scsi->cdb.len); - scsi->cdb.idx++; - bytes_transferred++; + bus_out = BUS_SETDATA(scsi->cdb.data[scsi->cdb.idx]); + // pclog(" Command send %02x %i\n", scsi->cdb.data[scsi->cdb.idx], scsi->cdb.len); + scsi->cdb.idx++; + bytes_transferred++; - scsi_bus_update(&scsi->bus, bus_out | BUS_ACK); - scsi_bus_update(&scsi->bus, bus_out & ~BUS_ACK); - } - if (scsi->cdb.idx == scsi->cdb.len) - scsi->scsi_state = SCSI_STATE_NEXT_PHASE; - break; + scsi_bus_update(&scsi->bus, bus_out | BUS_ACK); + scsi_bus_update(&scsi->bus, bus_out & ~BUS_ACK); + } + if (scsi->cdb.idx == scsi->cdb.len) + scsi->scsi_state = SCSI_STATE_NEXT_PHASE; + break; - case SCSI_STATE_NEXT_PHASE: - /*Wait for SCSI command to move to next phase*/ - for (c = 0; c < 20; c++) { - int bus_state = scsi_bus_read(&scsi->bus); + case SCSI_STATE_NEXT_PHASE: + /*Wait for SCSI command to move to next phase*/ + for (c = 0; c < 20; c++) { + int bus_state = scsi_bus_read(&scsi->bus); #ifndef RELEASE_BUILD - if (!(bus_state & BUS_BSY)) - fatal("NEXT_PHASE - dropped BSY waiting\n"); + if (!(bus_state & BUS_BSY)) + fatal("NEXT_PHASE - dropped BSY waiting\n"); #endif - if (bus_state & BUS_REQ) { - int bus_out; -// pclog("SCSI next phase - %x\n", bus_state); - switch (bus_state & (BUS_IO | BUS_CD | BUS_MSG)) { - case 0: -// pclog("Move to write data\n"); - scsi->scsi_state = SCSI_STATE_WRITE_DATA; - break; + if (bus_state & BUS_REQ) { + int bus_out; + // pclog("SCSI next phase - %x\n", bus_state); + switch (bus_state & (BUS_IO | BUS_CD | BUS_MSG)) { + case 0: + // pclog("Move to write data\n"); + scsi->scsi_state = SCSI_STATE_WRITE_DATA; + break; - case BUS_IO: -// pclog("Move to read data\n"); - scsi->scsi_state = SCSI_STATE_READ_DATA; - break; + case BUS_IO: + // pclog("Move to read data\n"); + scsi->scsi_state = SCSI_STATE_READ_DATA; + break; - case (BUS_CD | BUS_IO): -// pclog("Move to read status\n"); - scsi->scsi_state = SCSI_STATE_READ_STATUS; - break; + case (BUS_CD | BUS_IO): + // pclog("Move to read status\n"); + scsi->scsi_state = SCSI_STATE_READ_STATUS; + break; - case (BUS_CD | BUS_IO | BUS_MSG): -// pclog("Move to read message\n"); - scsi->scsi_state = SCSI_STATE_READ_MESSAGE; - break; + case (BUS_CD | BUS_IO | BUS_MSG): + // pclog("Move to read message\n"); + scsi->scsi_state = SCSI_STATE_READ_MESSAGE; + break; - case BUS_CD:bus_out = BUS_SETDATA(0); + case BUS_CD: + bus_out = BUS_SETDATA(0); - scsi_bus_update(&scsi->bus, bus_out | BUS_ACK); - scsi_bus_update(&scsi->bus, bus_out & ~BUS_ACK); - break; + scsi_bus_update(&scsi->bus, bus_out | BUS_ACK); + scsi_bus_update(&scsi->bus, bus_out & ~BUS_ACK); + break; #ifndef RELEASE_BUILD - default:fatal(" Bad new phase %x\n", bus_state); + default: + fatal(" Bad new phase %x\n", bus_state); #endif - } - break; - } - } - break; + } + break; + } + } + break; - case SCSI_STATE_END_PHASE: - /*Wait for SCSI command to move to next phase*/ - for (c = 0; c < 20; c++) { - int bus_state = scsi_bus_read(&scsi->bus); + case SCSI_STATE_END_PHASE: + /*Wait for SCSI command to move to next phase*/ + for (c = 0; c < 20; c++) { + int bus_state = scsi_bus_read(&scsi->bus); - if (!(bus_state & BUS_BSY)) { -// pclog("END_PHASE - dropped BSY waiting\n"); -// if (scsi->ccb.req_sense_len == CCB_SENSE_NONE) -// fatal("No sense data\n"); - scsi->scsi_state = SCSI_STATE_IDLE; -// pclog("End of command\n"); - if (!scsi->cmd_timer) - scsi->cmd_timer = 1; - break; - } + if (!(bus_state & BUS_BSY)) { + // pclog("END_PHASE - dropped BSY waiting\n"); + // if (scsi->ccb.req_sense_len == CCB_SENSE_NONE) + // fatal("No sense data\n"); + scsi->scsi_state = SCSI_STATE_IDLE; + // pclog("End of command\n"); + if (!scsi->cmd_timer) + scsi->cmd_timer = 1; + break; + } #ifndef RELEASE_BUILD - if (bus_state & BUS_REQ) - fatal("END_PHASE - unexpected REQ\n"); + if (bus_state & BUS_REQ) + fatal("END_PHASE - unexpected REQ\n"); #endif - } - break; + } + break; - case SCSI_STATE_READ_DATA: - while (scsi->scsi_state == SCSI_STATE_READ_DATA && bytes_transferred < MAX_BYTES_TRANSFERRED_PER_POLL) { - int d; + case SCSI_STATE_READ_DATA: + while (scsi->scsi_state == SCSI_STATE_READ_DATA && bytes_transferred < MAX_BYTES_TRANSFERRED_PER_POLL) { + int d; - for (d = 0; d < 20; d++) { - int bus_state = scsi_bus_read(&scsi->bus); + for (d = 0; d < 20; d++) { + int bus_state = scsi_bus_read(&scsi->bus); #ifndef RELEASE_BUILD - if (!(bus_state & BUS_BSY)) - fatal("READ_DATA - dropped BSY waiting\n"); + if (!(bus_state & BUS_BSY)) + fatal("READ_DATA - dropped BSY waiting\n"); #endif - if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) != BUS_IO) { -// pclog("READ_DATA - changed phase\n"); - scsi->scsi_state = SCSI_STATE_NEXT_PHASE; - break; - } + if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) != BUS_IO) { + // pclog("READ_DATA - changed phase\n"); + scsi->scsi_state = SCSI_STATE_NEXT_PHASE; + break; + } - if (bus_state & BUS_REQ) { - uint8_t data = BUS_GETDATA(bus_state); - int bus_out = 0; + if (bus_state & BUS_REQ) { + uint8_t data = BUS_GETDATA(bus_state); + int bus_out = 0; - if (scsi->cdb.data_idx < scsi->cdb.data_len) { - if (scsi->cdb.data_pointer == -1) - scsi->int_buffer[scsi->cdb.data_idx] = data; - else - mem_writeb_phys(scsi->cdb.data_pointer + scsi->cdb.data_idx, data); - scsi->cdb.data_idx++; + if (scsi->cdb.data_idx < scsi->cdb.data_len) { + if (scsi->cdb.data_pointer == -1) + scsi->int_buffer[scsi->cdb.data_idx] = data; + else + mem_writeb_phys(scsi->cdb.data_pointer + scsi->cdb.data_idx, data); + scsi->cdb.data_idx++; - if ((scsi->scb.enable & ENABLE_PT) && scsi->cdb.data_idx == scsi->cdb.data_len) - sg_fetch_next(scsi); - } - scsi->cdb.bytes_transferred++; + if ((scsi->scb.enable & ENABLE_PT) && scsi->cdb.data_idx == scsi->cdb.data_len) + sg_fetch_next(scsi); + } + scsi->cdb.bytes_transferred++; -// pclog("Read data %02x %i %06x\n", data, scsi->cdb.data_idx, scsi->cdb.data_pointer + scsi->cdb.data_idx); - scsi_bus_update(&scsi->bus, bus_out | BUS_ACK); - scsi_bus_update(&scsi->bus, bus_out & ~BUS_ACK); - break; - } - } + // pclog("Read data %02x %i %06x\n", data, + // scsi->cdb.data_idx, scsi->cdb.data_pointer + + // scsi->cdb.data_idx); + scsi_bus_update(&scsi->bus, bus_out | BUS_ACK); + scsi_bus_update(&scsi->bus, bus_out & ~BUS_ACK); + break; + } + } - bytes_transferred++; - } - break; + bytes_transferred++; + } + break; - case SCSI_STATE_WRITE_DATA: - while (scsi->scsi_state == SCSI_STATE_WRITE_DATA && bytes_transferred < MAX_BYTES_TRANSFERRED_PER_POLL) { - int d; + case SCSI_STATE_WRITE_DATA: + while (scsi->scsi_state == SCSI_STATE_WRITE_DATA && bytes_transferred < MAX_BYTES_TRANSFERRED_PER_POLL) { + int d; - for (d = 0; d < 20; d++) { - int bus_state = scsi_bus_read(&scsi->bus); + for (d = 0; d < 20; d++) { + int bus_state = scsi_bus_read(&scsi->bus); #ifndef RELEASE_BUILD - if (!(bus_state & BUS_BSY)) - fatal("WRITE_DATA - dropped BSY waiting\n"); + if (!(bus_state & BUS_BSY)) + fatal("WRITE_DATA - dropped BSY waiting\n"); #endif - if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) != 0) { -// pclog("WRITE_DATA - changed phase\n"); - scsi->scsi_state = SCSI_STATE_NEXT_PHASE; - break; - } + if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) != 0) { + // pclog("WRITE_DATA - changed phase\n"); + scsi->scsi_state = SCSI_STATE_NEXT_PHASE; + break; + } - if (bus_state & BUS_REQ) { - uint8_t data;// = BUS_GETDATA(bus_state); - int bus_out; + if (bus_state & BUS_REQ) { + uint8_t data; // = BUS_GETDATA(bus_state); + int bus_out; - if (scsi->cdb.data_idx < scsi->cdb.data_len) { - if (scsi->cdb.data_pointer == -1) - data = scsi->int_buffer[scsi->cdb.data_idx]; - else - data = mem_readb_phys(scsi->cdb.data_pointer + scsi->cdb.data_idx); + if (scsi->cdb.data_idx < scsi->cdb.data_len) { + if (scsi->cdb.data_pointer == -1) + data = scsi->int_buffer[scsi->cdb.data_idx]; + else + data = mem_readb_phys(scsi->cdb.data_pointer + scsi->cdb.data_idx); - scsi->cdb.data_idx++; - if ((scsi->scb.enable & ENABLE_PT) && scsi->cdb.data_idx == scsi->cdb.data_len) - sg_fetch_next(scsi); - } else - data = 0xff; - scsi->cdb.bytes_transferred++; + scsi->cdb.data_idx++; + if ((scsi->scb.enable & ENABLE_PT) && scsi->cdb.data_idx == scsi->cdb.data_len) + sg_fetch_next(scsi); + } else + data = 0xff; + scsi->cdb.bytes_transferred++; -// pclog("Write data %02x %i\n", data, scsi->cdb.data_idx); - bus_out = BUS_SETDATA(data); - scsi_bus_update(&scsi->bus, bus_out | BUS_ACK); - scsi_bus_update(&scsi->bus, bus_out & ~BUS_ACK); - break; - } - } + // pclog("Write data %02x %i\n", data, + // scsi->cdb.data_idx); + bus_out = BUS_SETDATA(data); + scsi_bus_update(&scsi->bus, bus_out | BUS_ACK); + scsi_bus_update(&scsi->bus, bus_out & ~BUS_ACK); + break; + } + } - bytes_transferred++; - } -// if (scsi->cdb.data_idx == scsi->cdb.data_len) -// scsi->scsi_state = SCSI_STATE_NEXT_PHASE; - break; + bytes_transferred++; + } + // if (scsi->cdb.data_idx == scsi->cdb.data_len) + // scsi->scsi_state = SCSI_STATE_NEXT_PHASE; + break; - case SCSI_STATE_READ_STATUS: - for (c = 0; c < 20; c++) { - int bus_state = scsi_bus_read(&scsi->bus); + case SCSI_STATE_READ_STATUS: + for (c = 0; c < 20; c++) { + int bus_state = scsi_bus_read(&scsi->bus); #ifndef RELEASE_BUILD - if (!(bus_state & BUS_BSY)) - fatal("READ_STATUS - dropped BSY waiting\n"); + if (!(bus_state & BUS_BSY)) + fatal("READ_STATUS - dropped BSY waiting\n"); #endif - if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) != (BUS_CD | BUS_IO)) { -// pclog("READ_STATUS - changed phase\n"); - scsi->scsi_state = SCSI_STATE_NEXT_PHASE; - break; - } + if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) != (BUS_CD | BUS_IO)) { + // pclog("READ_STATUS - changed phase\n"); + scsi->scsi_state = SCSI_STATE_NEXT_PHASE; + break; + } - if (bus_state & BUS_REQ) { - uint8_t status = BUS_GETDATA(bus_state); - int bus_out = 0; + if (bus_state & BUS_REQ) { + uint8_t status = BUS_GETDATA(bus_state); + int bus_out = 0; -// pclog("Read status %02x\n", status); - scsi->cdb.last_status = status; + // pclog("Read status %02x\n", status); + scsi->cdb.last_status = status; - scsi_bus_update(&scsi->bus, bus_out | BUS_ACK); - scsi_bus_update(&scsi->bus, bus_out & ~BUS_ACK); + scsi_bus_update(&scsi->bus, bus_out | BUS_ACK); + scsi_bus_update(&scsi->bus, bus_out & ~BUS_ACK); - scsi->scsi_state = SCSI_STATE_NEXT_PHASE; - break; - } - } - break; + scsi->scsi_state = SCSI_STATE_NEXT_PHASE; + break; + } + } + break; - case SCSI_STATE_READ_MESSAGE: - for (c = 0; c < 20; c++) { - int bus_state = scsi_bus_read(&scsi->bus); + case SCSI_STATE_READ_MESSAGE: + for (c = 0; c < 20; c++) { + int bus_state = scsi_bus_read(&scsi->bus); #ifndef RELEASE_BUILD - if (!(bus_state & BUS_BSY)) - fatal("READ_MESSAGE - dropped BSY waiting\n"); + if (!(bus_state & BUS_BSY)) + fatal("READ_MESSAGE - dropped BSY waiting\n"); #endif - if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) != (BUS_CD | BUS_IO | BUS_MSG)) { -// pclog("READ_MESSAGE - changed phase\n"); - scsi->scsi_state = SCSI_STATE_NEXT_PHASE; - break; - } + if ((bus_state & (BUS_IO | BUS_CD | BUS_MSG)) != (BUS_CD | BUS_IO | BUS_MSG)) { + // pclog("READ_MESSAGE - changed phase\n"); + scsi->scsi_state = SCSI_STATE_NEXT_PHASE; + break; + } - if (bus_state & BUS_REQ) { - uint8_t msg = BUS_GETDATA(bus_state); - int bus_out = 0; + if (bus_state & BUS_REQ) { + uint8_t msg = BUS_GETDATA(bus_state); + int bus_out = 0; -// pclog("Read message %02x\n", msg); - scsi_bus_update(&scsi->bus, bus_out | BUS_ACK); - scsi_bus_update(&scsi->bus, bus_out & ~BUS_ACK); + // pclog("Read message %02x\n", msg); + scsi_bus_update(&scsi->bus, bus_out | BUS_ACK); + scsi_bus_update(&scsi->bus, bus_out & ~BUS_ACK); - switch (msg) { - case MSG_COMMAND_COMPLETE:scsi->scsi_state = SCSI_STATE_END_PHASE; - break; + switch (msg) { + case MSG_COMMAND_COMPLETE: + scsi->scsi_state = SCSI_STATE_END_PHASE; + break; #ifndef RELEASE_BUILD - default:fatal("READ_MESSAGE - unknown message %02x\n", msg); + default: + fatal("READ_MESSAGE - unknown message %02x\n", msg); #endif - } - break; - } - } - break; + } + break; + } + } + break; #ifndef RELEASE_BUILD - default:fatal("Unknown SCSI_state %d\n", scsi->scsi_state); + default: + fatal("Unknown SCSI_state %d\n", scsi->scsi_state); #endif - } + } } static void scsi_callback(void *p) { - scsi_ibm_t *scsi = (scsi_ibm_t *)p; + scsi_ibm_t *scsi = (scsi_ibm_t *)p; - timer_advance_u64(&scsi->callback_timer, POLL_TIME); + timer_advance_u64(&scsi->callback_timer, POLL_TIME); -// pclog("poll %i\n", scsi->cmd_state); - if (scsi->cmd_timer) { - scsi->cmd_timer--; - if (!scsi->cmd_timer) - process_ibm_cmd(scsi); - } - if (scsi->attention_waiting && - (scsi->scb_state == SCB_STATE_IDLE || (scsi->attention_pending & 0xf0) == 0xe0)) { - scsi->attention_waiting--; - if (!scsi->attention_waiting) { -// pclog("Process attention request\n"); - scsi->attention = scsi->attention_pending; - scsi->status &= ~STATUS_BUSY; - scsi->cir[0] = scsi->cir_pending[0]; - scsi->cir[1] = scsi->cir_pending[1]; - scsi->cir[2] = scsi->cir_pending[2]; - scsi->cir[3] = scsi->cir_pending[3]; - scsi->cir_status = 0; + // pclog("poll %i\n", scsi->cmd_state); + if (scsi->cmd_timer) { + scsi->cmd_timer--; + if (!scsi->cmd_timer) + process_ibm_cmd(scsi); + } + if (scsi->attention_waiting && (scsi->scb_state == SCB_STATE_IDLE || (scsi->attention_pending & 0xf0) == 0xe0)) { + scsi->attention_waiting--; + if (!scsi->attention_waiting) { + // pclog("Process attention request\n"); + scsi->attention = scsi->attention_pending; + scsi->status &= ~STATUS_BUSY; + scsi->cir[0] = scsi->cir_pending[0]; + scsi->cir[1] = scsi->cir_pending[1]; + scsi->cir[2] = scsi->cir_pending[2]; + scsi->cir[3] = scsi->cir_pending[3]; + scsi->cir_status = 0; - switch (scsi->attention >> 4) { - case 0x1: /*Immediate command*/ - scsi->cmd_status = 0xa; - scsi->command = scsi->cir[0] | (scsi->cir[1] << 8) | (scsi->cir[2] << 16) | (scsi->cir[3] << 24); - switch (scsi->command & CMD_MASK) { - case CMD_ASSIGN: - case CMD_DMA_PACING_CONTROL: - case CMD_FEATURE_CONTROL: - case CMD_INVALID_412: - case CMD_RESET:process_immediate_command(scsi); - break; + switch (scsi->attention >> 4) { + case 0x1: /*Immediate command*/ + scsi->cmd_status = 0xa; + scsi->command = scsi->cir[0] | (scsi->cir[1] << 8) | (scsi->cir[2] << 16) | (scsi->cir[3] << 24); + switch (scsi->command & CMD_MASK) { + case CMD_ASSIGN: + case CMD_DMA_PACING_CONTROL: + case CMD_FEATURE_CONTROL: + case CMD_INVALID_412: + case CMD_RESET: + process_immediate_command(scsi); + break; #ifndef RELEASE_BUILD - default:fatal("Unknown immediate command %08x\n", scsi->command); + default: + fatal("Unknown immediate command %08x\n", scsi->command); #endif - } - break; + } + break; - case 0x3: - case 0x4: - case 0xf: /*Start SCB*/ - scsi->cmd_status = 0x1; - scsi->scb_addr = scsi->cir[0] | (scsi->cir[1] << 8) | (scsi->cir[2] << 16) | (scsi->cir[3] << 24); - scsi->scb_state = SCB_STATE_START; - scsi->scb_id = scsi->attention & 0xf; - scsi->cmd_timer = SCSI_TIME * 2; -// pclog("Start SCB at %08x\n", scsi->scb_addr); - break; + case 0x3: + case 0x4: + case 0xf: /*Start SCB*/ + scsi->cmd_status = 0x1; + scsi->scb_addr = scsi->cir[0] | (scsi->cir[1] << 8) | (scsi->cir[2] << 16) | (scsi->cir[3] << 24); + scsi->scb_state = SCB_STATE_START; + scsi->scb_id = scsi->attention & 0xf; + scsi->cmd_timer = SCSI_TIME * 2; + // pclog("Start SCB at %08x\n", scsi->scb_addr); + break; - case 5: /*Invalid*/ - case 0xa: /*Invalid*/ - scsi->in_invalid = 1; - scsi->cmd_timer = SCSI_TIME * 2; - break; + case 5: /*Invalid*/ + case 0xa: /*Invalid*/ + scsi->in_invalid = 1; + scsi->cmd_timer = SCSI_TIME * 2; + break; - case 0xe: /*EOI*/ - scsi->irq_status = 0; - scsi_clear_irq(scsi, scsi->attention & 0xf); - break; + case 0xe: /*EOI*/ + scsi->irq_status = 0; + scsi_clear_irq(scsi, scsi->attention & 0xf); + break; #ifndef RELEASE_BUILD - default:fatal("Attention Register 5 %02x\n", scsi->attention); + default: + fatal("Attention Register 5 %02x\n", scsi->attention); #endif - } - } - } - process_scsi(scsi); + } + } + } + process_scsi(scsi); } static uint8_t scsi_ibm_mca_read(int port, void *p) { - scsi_ibm_t *scsi = (scsi_ibm_t *)p; + scsi_ibm_t *scsi = (scsi_ibm_t *)p; -// pclog("scsi_mca_read: port=%04x %02x %04x:%04x\n", port, scsi->pos_regs[port & 7], CS,cpu_state.pc); + // pclog("scsi_mca_read: port=%04x %02x %04x:%04x\n", port, scsi->pos_regs[port & 7], CS,cpu_state.pc); - return scsi->pos_regs[port & 7]; + return scsi->pos_regs[port & 7]; } static void scsi_ibm_mca_write(int port, uint8_t val, void *p) { - scsi_ibm_t *scsi = (scsi_ibm_t *)p; + scsi_ibm_t *scsi = (scsi_ibm_t *)p; - if (port < 0x102) - return; + if (port < 0x102) + return; -// pclog("scsi_mca_write: port=%04x val=%02x %04x:%04x\n", port, val, CS, cpu_state.pc); + // pclog("scsi_mca_write: port=%04x val=%02x %04x:%04x\n", port, val, CS, cpu_state.pc); - io_removehandler((((scsi->pos_regs[2] >> 1) & 7) * 8) + 0x3540, 0x0008, scsi_read, scsi_readw, NULL, scsi_write, scsi_writew, NULL, scsi); - mem_mapping_disable(&scsi->bios_rom.mapping); + io_removehandler((((scsi->pos_regs[2] >> 1) & 7) * 8) + 0x3540, 0x0008, scsi_read, scsi_readw, NULL, scsi_write, + scsi_writew, NULL, scsi); + mem_mapping_disable(&scsi->bios_rom.mapping); - scsi->pos_regs[port & 7] = val; + scsi->pos_regs[port & 7] = val; - if (scsi->pos_regs[2] & 1) { -// pclog(" scsi io = %04x\n", (((scsi->pos_regs[2] >> 1) & 7) * 8) + 0x3540); - io_sethandler((((scsi->pos_regs[2] >> 1) & 7) * 8) + 0x3540, 0x0008, scsi_read, scsi_readw, NULL, scsi_write, scsi_writew, NULL, scsi); - if ((scsi->pos_regs[2] & 0xf0) != 0xf0) { - mem_mapping_enable(&scsi->bios_rom.mapping); - mem_mapping_set_addr(&scsi->bios_rom.mapping, ((scsi->pos_regs[2] >> 4) * 0x2000) + 0xc0000, 0x8000); -// pclog("SCSI BIOS ROM at %05x %02x\n", ((scsi->pos_regs[2] >> 4) * 0x2000) + 0xc0000, scsi->pos_regs[2]); - } - } + if (scsi->pos_regs[2] & 1) { + // pclog(" scsi io = %04x\n", (((scsi->pos_regs[2] >> 1) & 7) * 8) + 0x3540); + io_sethandler((((scsi->pos_regs[2] >> 1) & 7) * 8) + 0x3540, 0x0008, scsi_read, scsi_readw, NULL, scsi_write, + scsi_writew, NULL, scsi); + if ((scsi->pos_regs[2] & 0xf0) != 0xf0) { + mem_mapping_enable(&scsi->bios_rom.mapping); + mem_mapping_set_addr(&scsi->bios_rom.mapping, ((scsi->pos_regs[2] >> 4) * 0x2000) + 0xc0000, 0x8000); + // pclog("SCSI BIOS ROM at %05x %02x\n", ((scsi->pos_regs[2] >> 4) * 0x2000) + + // 0xc0000, scsi->pos_regs[2]); + } + } } static void scsi_ibm_reset(void *p) { - scsi_ibm_t *scsi = (scsi_ibm_t *)p; + scsi_ibm_t *scsi = (scsi_ibm_t *)p; -// pclog("scsi_ibm_reset\n"); - scsi->in_reset = 2; - scsi->cmd_timer = SCSI_TIME * 50; - scsi->status = STATUS_BUSY; - scsi->scsi_state = SCSI_STATE_IDLE; - scsi->scb_state = SCB_STATE_IDLE; - scsi->in_invalid = 0; - scsi->attention_waiting = 0; - scsi->basic_ctrl = 0; - scsi_bus_reset(&scsi->bus); + // pclog("scsi_ibm_reset\n"); + scsi->in_reset = 2; + scsi->cmd_timer = SCSI_TIME * 50; + scsi->status = STATUS_BUSY; + scsi->scsi_state = SCSI_STATE_IDLE; + scsi->scb_state = SCB_STATE_IDLE; + scsi->in_invalid = 0; + scsi->attention_waiting = 0; + scsi->basic_ctrl = 0; + scsi_bus_reset(&scsi->bus); } static void *scsi_ibm_init() { - int c; - scsi_ibm_t *scsi = malloc(sizeof(scsi_ibm_t)); - memset(scsi, 0, sizeof(scsi_ibm_t)); + int c; + scsi_ibm_t *scsi = malloc(sizeof(scsi_ibm_t)); + memset(scsi, 0, sizeof(scsi_ibm_t)); - rom_init_interleaved(&scsi->bios_rom, "92F2244.U68", "92F2245.U69", 0xc8000, 0x8000, 0x7fff, 0x4000, MEM_MAPPING_EXTERNAL); - mem_mapping_disable(&scsi->bios_rom.mapping); + rom_init_interleaved(&scsi->bios_rom, "92F2244.U68", "92F2245.U69", 0xc8000, 0x8000, 0x7fff, 0x4000, + MEM_MAPPING_EXTERNAL); + mem_mapping_disable(&scsi->bios_rom.mapping); - timer_add(&scsi->callback_timer, scsi_callback, scsi, 1); + timer_add(&scsi->callback_timer, scsi_callback, scsi, 1); - mca_add(scsi_ibm_mca_read, scsi_ibm_mca_write, scsi_ibm_reset, scsi); + mca_add(scsi_ibm_mca_read, scsi_ibm_mca_write, scsi_ibm_reset, scsi); - scsi->pos_regs[0] = 0xff; - scsi->pos_regs[1] = 0x8e; + scsi->pos_regs[0] = 0xff; + scsi->pos_regs[1] = 0x8e; - scsi->in_reset = 2; - scsi->cmd_timer = SCSI_TIME * 50; - scsi->status = STATUS_BUSY; + scsi->in_reset = 2; + scsi->cmd_timer = SCSI_TIME * 50; + scsi->status = STATUS_BUSY; - scsi_bus_init(&scsi->bus); + scsi_bus_init(&scsi->bus); -/* for (c = 0; c < 7; c++) - { - scsi->dev_id[c].phys_id = c; - scsi->dev_id[c].lun_id = 0; - }*/ - for (c = 0; c < 15; c++) - scsi->dev_id[c].phys_id = -1; - scsi->dev_id[15].phys_id = 7; + /* for (c = 0; c < 7; c++) + { + scsi->dev_id[c].phys_id = c; + scsi->dev_id[c].lun_id = 0; + }*/ + for (c = 0; c < 15; c++) + scsi->dev_id[c].phys_id = -1; + scsi->dev_id[15].phys_id = 7; - return scsi; + return scsi; } static void scsi_ibm_close(void *p) { - scsi_ibm_t *scsi = (scsi_ibm_t *)p; + scsi_ibm_t *scsi = (scsi_ibm_t *)p; - free(scsi); + free(scsi); } -static int scsi_ibm_available() { - return rom_present("92F2244.U68") && rom_present("92F2245.U69"); -} +static int scsi_ibm_available() { return rom_present("92F2244.U68") && rom_present("92F2245.U69"); } -device_t scsi_ibm_device = - { - "IBM SCSI Adapter with Cache (MCA)", - DEVICE_MCA, - scsi_ibm_init, - scsi_ibm_close, - scsi_ibm_available, - NULL, - NULL, - NULL, - NULL - }; +device_t scsi_ibm_device = {"IBM SCSI Adapter with Cache (MCA)", + DEVICE_MCA, + scsi_ibm_init, + scsi_ibm_close, + scsi_ibm_available, + NULL, + NULL, + NULL, + NULL}; diff --git a/src/scsi/scsi_zip.c b/src/scsi/scsi_zip.c index b1723d4b..cbb79a6f 100644 --- a/src/scsi/scsi_zip.c +++ b/src/scsi/scsi_zip.c @@ -10,14 +10,14 @@ #include "scsi_zip.h" #include "timer.h" -#define BUFFER_SIZE (256*1024) +#define BUFFER_SIZE (256 * 1024) -#define ZIP_SECTORS (96*2048) +#define ZIP_SECTORS (96 * 2048) #define RW_DELAY (TIMER_USEC * 500) -#define SCSI_IOMEGA_SENSE 0x06 -#define SCSI_IOMEGA_EJECT 0x0d /*ATAPI only?*/ +#define SCSI_IOMEGA_SENSE 0x06 +#define SCSI_IOMEGA_EJECT 0x0d /*ATAPI only?*/ /*Page 1 - 0x58 bytes*/ /*Page 2 (Disk Status Page) - 0x3d bytes @@ -27,1078 +27,1085 @@ 3 - password write-protected Bytes 22 - 61 - serial number */ -#define SCSI_IOMEGA_SET_PROTECTION_MODE 0x0c +#define SCSI_IOMEGA_SET_PROTECTION_MODE 0x0c /*cmd[1] = mode cmd[6-x] = password*/ -#define ATAPI_READ_FORMAT_CAPACITIES 0x23 +#define ATAPI_READ_FORMAT_CAPACITIES 0x23 -enum { - CMD_POS_IDLE = 0, - CMD_POS_WAIT, - CMD_POS_START_SECTOR, - CMD_POS_TRANSFER -}; +enum { CMD_POS_IDLE = 0, CMD_POS_WAIT, CMD_POS_START_SECTOR, CMD_POS_TRANSFER }; typedef struct scsi_zip_data { - int blocks; + int blocks; - int cmd_pos, new_cmd_pos; + int cmd_pos, new_cmd_pos; - int addr, len; - int sector_pos; + int addr, len; + int sector_pos; - uint8_t buf[512]; + uint8_t buf[512]; - uint8_t status; + uint8_t status; - uint8_t data_in[BUFFER_SIZE]; - uint8_t data_out[BUFFER_SIZE]; - int data_pos_read, data_pos_write; + uint8_t data_in[BUFFER_SIZE]; + uint8_t data_out[BUFFER_SIZE]; + int data_pos_read, data_pos_write; - int bytes_received, bytes_required; + int bytes_received, bytes_required; - hdd_file_t hdd; - int disc_loaded; - int disc_changed; + hdd_file_t hdd; + int disc_loaded; + int disc_changed; - int sense_key, asc, ascq; + int sense_key, asc, ascq; - int hd_id; + int hd_id; - pc_timer_t callback_timer; + pc_timer_t callback_timer; - scsi_bus_t *bus; + scsi_bus_t *bus; - int is_atapi; - atapi_device_t *atapi_dev; + int is_atapi; + atapi_device_t *atapi_dev; - int read_only; + int read_only; - int pio_mode, mdma_mode; + int pio_mode, mdma_mode; } scsi_zip_data; static scsi_zip_data *zip_data; -#define CHECK_READY 2 +#define CHECK_READY 2 -static uint8_t scsi_zip_cmd_flags[0x100] = - { - [SCSI_TEST_UNIT_READY] = CHECK_READY, - [SCSI_REQUEST_SENSE] = 0, - [SCSI_READ_6] = CHECK_READY, - [SCSI_INQUIRY] = 0, - [SCSI_MODE_SELECT_6] = 0, - [SCSI_MODE_SENSE_6] = 0, - [SCSI_START_STOP_UNIT] = 0, - [SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL] = CHECK_READY, - [SCSI_READ_10] = CHECK_READY, - [SCSI_SEEK_6] = CHECK_READY, - [SCSI_SEEK_10] = CHECK_READY, - [SCSI_IOMEGA_SENSE] = 0, - [SCSI_REZERO_UNIT] = CHECK_READY, - [SCSI_READ_CAPACITY_10] = CHECK_READY, - [SCSI_WRITE_6] = CHECK_READY, - [SCSI_WRITE_10] = CHECK_READY, - [SCSI_WRITE_AND_VERIFY] = CHECK_READY, - [SCSI_VERIFY_10] = CHECK_READY, - [SCSI_FORMAT] = CHECK_READY, - [SCSI_RESERVE] = 0, - [SCSI_RELEASE] = 0, - [SEND_DIAGNOSTIC] = 0 +static uint8_t scsi_zip_cmd_flags[0x100] = {[SCSI_TEST_UNIT_READY] = CHECK_READY, + [SCSI_REQUEST_SENSE] = 0, + [SCSI_READ_6] = CHECK_READY, + [SCSI_INQUIRY] = 0, + [SCSI_MODE_SELECT_6] = 0, + [SCSI_MODE_SENSE_6] = 0, + [SCSI_START_STOP_UNIT] = 0, + [SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL] = CHECK_READY, + [SCSI_READ_10] = CHECK_READY, + [SCSI_SEEK_6] = CHECK_READY, + [SCSI_SEEK_10] = CHECK_READY, + [SCSI_IOMEGA_SENSE] = 0, + [SCSI_REZERO_UNIT] = CHECK_READY, + [SCSI_READ_CAPACITY_10] = CHECK_READY, + [SCSI_WRITE_6] = CHECK_READY, + [SCSI_WRITE_10] = CHECK_READY, + [SCSI_WRITE_AND_VERIFY] = CHECK_READY, + [SCSI_VERIFY_10] = CHECK_READY, + [SCSI_FORMAT] = CHECK_READY, + [SCSI_RESERVE] = 0, + [SCSI_RELEASE] = 0, + [SEND_DIAGNOSTIC] = 0 - }; +}; void zip_load(char *fn) { - if (zip_data) { - FILE *f; - int read_only = 0; + if (zip_data) { + FILE *f; + int read_only = 0; - f = fopen(fn, "rb+"); - if (!f) { - f = fopen(fn, "rb"); - read_only = 1; - } - if (f) { - int size; + f = fopen(fn, "rb+"); + if (!f) { + f = fopen(fn, "rb"); + read_only = 1; + } + if (f) { + int size; - fseek(f, -1, SEEK_END); - size = ftell(f) + 1; - fclose(f); + fseek(f, -1, SEEK_END); + size = ftell(f) + 1; + fclose(f); - if (size != ZIP_SECTORS * 512) { - warning("File is incorrect size for Zip image\nMust be exactly %i bytes\n", ZIP_SECTORS * 512); - return; - } + if (size != ZIP_SECTORS * 512) { + warning("File is incorrect size for Zip image\nMust be exactly %i bytes\n", ZIP_SECTORS * 512); + return; + } - if (zip_data->disc_loaded) - hdd_close(&zip_data->hdd); + if (zip_data->disc_loaded) + hdd_close(&zip_data->hdd); - hdd_load_ext(&zip_data->hdd, fn, 2048, 1, 96, read_only); + hdd_load_ext(&zip_data->hdd, fn, 2048, 1, 96, read_only); - if (zip_data->hdd.f) { - zip_data->disc_loaded = 1; - zip_data->disc_changed = 1; - zip_data->read_only = read_only; - } - } - } + if (zip_data->hdd.f) { + zip_data->disc_loaded = 1; + zip_data->disc_changed = 1; + zip_data->read_only = read_only; + } + } + } } void zip_eject() { - if (zip_data) { - if (zip_data->disc_loaded) { - hdd_close(&zip_data->hdd); - zip_data->disc_loaded = 0; - } - } + if (zip_data) { + if (zip_data->disc_loaded) { + hdd_close(&zip_data->hdd); + zip_data->disc_loaded = 0; + } + } } int zip_loaded() { - if (zip_data) - return zip_data->disc_loaded; - return 0; + if (zip_data) + return zip_data->disc_loaded; + return 0; } static void scsi_zip_callback(void *p) { - scsi_zip_data *data = p; + scsi_zip_data *data = p; - if (data->cmd_pos == CMD_POS_WAIT) { - data->cmd_pos = data->new_cmd_pos; - scsi_bus_kick(data->bus); - } + if (data->cmd_pos == CMD_POS_WAIT) { + data->cmd_pos = data->new_cmd_pos; + scsi_bus_kick(data->bus); + } } static void *scsi_zip_init(scsi_bus_t *bus, int id) { - scsi_zip_data *data = malloc(sizeof(scsi_zip_data)); - memset(data, 0, sizeof(scsi_zip_data)); + scsi_zip_data *data = malloc(sizeof(scsi_zip_data)); + memset(data, 0, sizeof(scsi_zip_data)); - data->disc_loaded = 0; + data->disc_loaded = 0; - data->hd_id = id; - data->bus = bus; - timer_add(&data->callback_timer, scsi_zip_callback, data, 0); + data->hd_id = id; + data->bus = bus; + timer_add(&data->callback_timer, scsi_zip_callback, data, 0); - zip_data = data; - return data; + zip_data = data; + return data; } static void *scsi_zip_atapi_init(scsi_bus_t *bus, int id, atapi_device_t *atapi_dev) { - scsi_zip_data *data = scsi_zip_init(bus, id); + scsi_zip_data *data = scsi_zip_init(bus, id); - data->is_atapi = 1; - data->atapi_dev = atapi_dev; + data->is_atapi = 1; + data->atapi_dev = atapi_dev; - return data; + return data; } static void scsi_zip_close(void *p) { - scsi_zip_data *data = p; + scsi_zip_data *data = p; - if (data->disc_loaded) - hdd_close(&data->hdd); - free(data); - zip_data = NULL; + if (data->disc_loaded) + hdd_close(&data->hdd); + free(data); + zip_data = NULL; } static void scsi_zip_reset(void *p) { - scsi_zip_data *data = p; + scsi_zip_data *data = p; - timer_disable(&data->callback_timer); - data->cmd_pos = CMD_POS_IDLE; + timer_disable(&data->callback_timer); + data->cmd_pos = CMD_POS_IDLE; } static int scsi_add_data(uint8_t val, void *p) { - scsi_zip_data *data = p; + scsi_zip_data *data = p; -// pclog("scsi_add_data : %04x %02x\n", data->data_pos_write, val); + // pclog("scsi_add_data : %04x %02x\n", data->data_pos_write, val); - data->data_in[data->data_pos_write++] = val; + data->data_in[data->data_pos_write++] = val; -// if (data->bus_out & BUS_REQ) -// return -1; + // if (data->bus_out & BUS_REQ) + // return -1; -// data->bus_out = (data->bus_out & ~BUS_DATAMASK) | BUS_SETDATA(val) | BUS_DBP | BUS_REQ; + // data->bus_out = (data->bus_out & ~BUS_DATAMASK) | BUS_SETDATA(val) | BUS_DBP | BUS_REQ; - return 0; + return 0; } static int scsi_get_data(void *p) { - scsi_zip_data *data = p; - uint8_t val = data->data_out[data->data_pos_read++]; + scsi_zip_data *data = p; + uint8_t val = data->data_out[data->data_pos_read++]; - if (data->data_pos_read > BUFFER_SIZE) - fatal("scsi_get_data beyond buffer limits\n"); + if (data->data_pos_read > BUFFER_SIZE) + fatal("scsi_get_data beyond buffer limits\n"); - return val; + return val; } static void scsi_zip_illegal(scsi_zip_data *data) { - data->status = STATUS_CHECK_CONDITION; - data->sense_key = KEY_ILLEGAL_REQ; - data->asc = ASC_INVALID_LUN; - data->ascq = 0; + data->status = STATUS_CHECK_CONDITION; + data->sense_key = KEY_ILLEGAL_REQ; + data->asc = ASC_INVALID_LUN; + data->ascq = 0; } static void scsi_zip_cmd_error(scsi_zip_data *data, int sensekey, int asc, int ascq) { - data->status = STATUS_CHECK_CONDITION; - data->sense_key = sensekey; - data->asc = asc; - data->ascq = ascq; + data->status = STATUS_CHECK_CONDITION; + data->sense_key = sensekey; + data->asc = asc; + data->ascq = ascq; } -#define add_data_len(v) \ - do \ - { \ - if (i < len) \ - scsi_add_data(v, data); \ - i++; \ +#define add_data_len(v) \ + do { \ + if (i < len) \ + scsi_add_data(v, data); \ + i++; \ } while (0) static int scsi_zip_command(uint8_t *cdb, void *p) { - scsi_zip_data *data = p; - int /*addr, */len; - int i = 0, c; - int desc; - int bus_state = 0; - - if (data->cmd_pos == CMD_POS_IDLE) - pclog("SCSI ZIP command %02x %i %p\n", cdb[0], data->disc_loaded, data); - data->status = STATUS_GOOD; - data->data_pos_read = data->data_pos_write = 0; - - if ((cdb[0] != SCSI_REQUEST_SENSE/* && cdb[0] != SCSI_INQUIRY*/) && (cdb[1] & 0xe0)) { - pclog("non-zero LUN\n"); - /*Non-zero LUN - abort command*/ - scsi_zip_illegal(data); - bus_state = BUS_CD | BUS_IO; - return bus_state; - } - - if ((scsi_zip_cmd_flags[cdb[0]] & CHECK_READY) && !data->disc_loaded) { - pclog("Disc not loaded\n"); - scsi_zip_cmd_error(data, KEY_NOT_READY, ASC_MEDIUM_NOT_PRESENT, 0); - bus_state = BUS_CD | BUS_IO; - return bus_state; - } - if ((scsi_zip_cmd_flags[cdb[0]] & CHECK_READY) && data->disc_changed) { - pclog("Disc changed\n"); - scsi_zip_cmd_error(data, KEY_UNIT_ATTENTION, ASC_MEDIUM_MAY_HAVE_CHANGED, 0); - data->disc_changed = 0; - bus_state = BUS_CD | BUS_IO; - return bus_state; - } - - switch (cdb[0]) { - case SCSI_TEST_UNIT_READY:bus_state = BUS_CD | BUS_IO; - break; - - case SCSI_IOMEGA_SENSE:len = cdb[4]; - if (cdb[2] == 1) { - pclog("SCSI_IOMEGA_SENSE 1 %02x\n", len); - add_data_len(0x58); - add_data_len(0); - /*This page is related to disc health status - setting this page to 0 - makes disc health read as 'marginal'*/ - for (c = 2; c < 0x58; c++) - add_data_len(0xff); - while (i < len) - add_data_len(0); - data->cmd_pos = CMD_POS_IDLE; - bus_state = BUS_IO; - } else if (cdb[2] == 2) { - pclog("SCSI_IOMEGA_SENSE 2 %02x\n", len); - add_data_len(0x3d); - add_data_len(0); - for (c = 0; c < 19; c++) - add_data_len(0); - if (data->read_only) - add_data_len(2); - else - add_data_len(0); - for (c = 0; c < 39; c++) - add_data_len(0); - while (i < len) - add_data_len(0); - data->cmd_pos = CMD_POS_IDLE; - bus_state = BUS_IO; - } else { - pclog("IOMEGA_SENSE %02x %02x\n", cdb[2], len); - scsi_zip_illegal(data); - bus_state = BUS_CD | BUS_IO; - } - break; - - case SCSI_REZERO_UNIT:bus_state = BUS_CD | BUS_IO; - break; - - case SCSI_REQUEST_SENSE:desc = cdb[1] & 1; - len = cdb[4]; - - if (!desc) { - add_data_len(0x70); - add_data_len(0); - add_data_len(data->sense_key); /*Sense key*/ - add_data_len(0); /*Information (4 bytes)*/ - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); /*Additional sense length*/ - add_data_len(0); /*Command specific information (4 bytes)*/ - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(data->asc); /*ASC*/ - add_data_len(data->ascq); /*ASCQ*/ - add_data_len(0); /*FRU code*/ - add_data_len(0); /*Sense key specific (3 bytes)*/ - add_data_len(0); - add_data_len(0); - } else { - add_data_len(0x72); - add_data_len(data->sense_key); /*Sense Key*/ - add_data_len(data->asc); /*ASC*/ - add_data_len(data->ascq); /*ASCQ*/ - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); /*additional sense length*/ - } - - data->sense_key = data->asc = data->ascq = 0; - - data->cmd_pos = CMD_POS_IDLE; - bus_state = BUS_IO; - break; - - case SCSI_INQUIRY:len = cdb[4] | (cdb[3] << 8); -// pclog("INQUIRY %d %02x %02x %02x %02x %02x %02x %i\n", len, cdb[0],cdb[1],cdb[2],cdb[3],cdb[4],cdb[5], data->hd_id); - - if (cdb[1] & 0xe0) { - add_data_len(0 | (3 << 5)); /*No physical device on this LUN*/ - } else { - add_data_len(0 | (0 << 5)); /*Hard disc*/ - } - add_data_len(0x80); /*Removeable device*/ - if (data->is_atapi) { - add_data_len(0); /*Not ANSI compliant*/ - add_data_len(0x21); /*ATAPI compliant*/ - } else { - add_data_len(2); /*SCSI-2 compliant*/ - add_data_len(0x02); - } -// add_data_len(0); /*No version*/ -// add_data_len(2); /*Response data*/ - add_data_len(0); /*Additional length*/ - add_data_len(0); - add_data_len(0); - add_data_len(2); - - add_data_len('I'); - add_data_len('O'); - add_data_len('M'); - add_data_len('E'); - add_data_len('G'); - add_data_len('A'); - add_data_len(' '); - add_data_len(' '); - - add_data_len('Z'); - add_data_len('I'); - add_data_len('P'); - add_data_len(' '); - add_data_len('1'); - add_data_len('0'); - add_data_len('0'); - add_data_len(' '); - - add_data_len(' '); - add_data_len(' '); - add_data_len(' '); - add_data_len(' '); - add_data_len(' '); - add_data_len(' '); - add_data_len(' '); - add_data_len(' '); - - add_data_len('E'); /*Product revision level*/ - add_data_len('.'); - add_data_len('0'); - add_data_len('8'); - - add_data_len(0); /*Drive serial number*/ - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - - add_data_len(0); /*Vendor unique*/ - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - - add_data_len(0); - add_data_len(0); - - add_data_len(0); /*Vendor descriptor*/ - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - - add_data_len(0); /*Reserved*/ - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - - data->cmd_pos = CMD_POS_IDLE; - bus_state = BUS_IO; - break; - - case SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL:bus_state = BUS_CD | BUS_IO; - break; - - case SCSI_MODE_SENSE_6: - case SCSI_MODE_SENSE_10:pclog("MODE_SENSE_6 %02x %02x\n", cdb[2], cdb[4]); - if ((cdb[2] & 0x3f) != 0x01 && (cdb[2] & 0x3f) != 0x02 && (cdb[2] & 0x3f) != 0x2f && (cdb[2] & 0x3f) != 0x3f) { - pclog("Invalid MODE_SENSE\n"); - scsi_zip_cmd_error(data, KEY_ILLEGAL_REQ, ASC_INV_FIELD_IN_CMD_PACKET, 0); - bus_state = BUS_CD | BUS_IO; - break; - } - if (cdb[0] == SCSI_MODE_SENSE_6) { - len = cdb[4]; - - add_data_len(0); - add_data_len(0); - - if (data->read_only) - add_data_len(0x80); - else - add_data_len(0); - add_data_len(0x08); - } else { - len = cdb[8] | (cdb[7] << 8); - - add_data_len(0); - add_data_len(0); - add_data_len(0); - - if (data->read_only) - add_data_len(0x80); - else - add_data_len(0); - - add_data_len(0); - add_data_len(0); - - add_data_len(0); - add_data_len(0x08); - } - - add_data_len((ZIP_SECTORS >> 24) & 0xff); - add_data_len((ZIP_SECTORS >> 16) & 0xff); - add_data_len((ZIP_SECTORS >> 8) & 0xff); - add_data_len(ZIP_SECTORS & 0xff); - add_data_len((512 >> 24) & 0xff); - add_data_len((512 >> 16) & 0xff); - add_data_len((512 >> 8) & 0xff); - add_data_len(512 & 0xff); - - if ((cdb[2] & 0x3f) == 0x01 || (cdb[2] & 0x3f) == 0x3f) { - add_data_len(0x01); - add_data_len(0x0a); - add_data_len(0xc8); /*Automatic read and write allocation enable, most expedient error recovery*/ - add_data_len(22); /*Read retry count = 22*/ - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(90); /*Write retry count = 90*/ - add_data_len(0); - add_data_len(20512 >> 8); - add_data_len(20512 & 0xff); - } - - if ((cdb[2] & 0x3f) == 0x02 || (cdb[2] & 0x3f) == 0x3f) { - add_data_len(0x02); - add_data_len(0x0e); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - add_data_len(0); - } - - if ((cdb[2] & 0x3f) == 0x2f || (cdb[2] & 0x3f) == 0x3f) { - add_data_len(0x2f); - add_data_len(0x04); - add_data_len(0x5c); - add_data_len(0x0f); - add_data_len(0xff); - add_data_len(0x0f); - } - - while (i < len) - add_data_len(0); - - len = data->data_pos_write; - if (cdb[0] == SCSI_MODE_SENSE_6) { - data->data_in[0] = len - 1; - } else { - data->data_in[0] = (len - 2) >> 8; - data->data_in[1] = (len - 2) & 255; - } - -// scsi_illegal_field(); - data->cmd_pos = CMD_POS_IDLE; - bus_state = BUS_IO; - break; - - case SCSI_READ_CAPACITY_10: -// len = 96 * 2048; - scsi_add_data((ZIP_SECTORS >> 24) & 0xff, data); - scsi_add_data((ZIP_SECTORS >> 16) & 0xff, data); - scsi_add_data((ZIP_SECTORS >> 8) & 0xff, data); - scsi_add_data(ZIP_SECTORS & 0xff, data); - scsi_add_data((512 >> 24) & 0xff, data); - scsi_add_data((512 >> 16) & 0xff, data); - scsi_add_data((512 >> 8) & 0xff, data); - scsi_add_data(512 & 0xff, data); - data->cmd_pos = CMD_POS_IDLE; - bus_state = BUS_IO; - break; - - case SCSI_READ_6: -// pclog("SCSI_READ_6 %i\n", data->cmd_pos); - if (data->cmd_pos == CMD_POS_WAIT) { - bus_state = BUS_CD; - break; - } - - if (data->cmd_pos == CMD_POS_IDLE) { - readflash_set(READFLASH_HDC, data->hd_id); - data->addr = cdb[3] | (cdb[2] << 8) | ((cdb[1] & 0x1f) << 16); - data->len = cdb[4]; - if (!data->len) - data->len = 256; -// pclog("SCSI_READ_6: addr=%08x len=%04x\n", data->addr, data->len); - - data->cmd_pos = CMD_POS_WAIT; - timer_set_delay_u64(&data->callback_timer, RW_DELAY); - data->new_cmd_pos = CMD_POS_START_SECTOR; - data->sector_pos = 0; - - bus_state = BUS_CD; - atapi_set_transfer_granularity(data->atapi_dev, 512); - break; - } -// else -// pclog("SCSI_READ_6 continue addr=%08x len=%04x sector_pos=%02x\n", data->addr, data->len, data->sector_pos); - while (data->len) { - if (data->cmd_pos == CMD_POS_START_SECTOR) { - hdd_read_sectors(&data->hdd, data->addr, 1, data->buf); - readflash_set(READFLASH_HDC, data->hd_id); - } - - data->cmd_pos = CMD_POS_TRANSFER; - for (; data->sector_pos < 512; data->sector_pos++) { - int ret = scsi_add_data(data->buf[data->sector_pos], data); - - if (ret == -1) { - fatal("scsi_add_data -1\n"); - break; - } - if (ret & 0x100) { - fatal("scsi_add_data 0x100\n"); - data->len = 1; - break; - } - } - data->cmd_pos = CMD_POS_START_SECTOR; - - data->sector_pos = 0; - data->len--; - data->addr++; - } - data->cmd_pos = CMD_POS_IDLE; - bus_state = BUS_IO; - break; - - case SCSI_READ_10: -// pclog("SCSI_READ_10 %i\n", data->cmd_pos); - if (data->cmd_pos == CMD_POS_WAIT) { - bus_state = BUS_CD; - break; - } - - if (data->cmd_pos == CMD_POS_IDLE) { - readflash_set(READFLASH_HDC, data->hd_id); - data->addr = cdb[5] | (cdb[4] << 8) | (cdb[3] << 16) | (cdb[2] << 24); - data->len = cdb[8] | (cdb[7] << 8); -// pclog("SCSI_READ_10: addr=%08x len=%04x\n", data->addr, data->len); - - data->cmd_pos = CMD_POS_WAIT; - timer_set_delay_u64(&data->callback_timer, RW_DELAY); - data->new_cmd_pos = CMD_POS_START_SECTOR; - data->sector_pos = 0; - - bus_state = BUS_CD; - atapi_set_transfer_granularity(data->atapi_dev, 512); - break; - } -// else -// pclog("SCSI_READ_10 continue addr=%08x len=%04x sector_pos=%02x\n", data->addr, data->len, data->sector_pos); - while (data->len) { - if (data->cmd_pos == CMD_POS_START_SECTOR) { - hdd_read_sectors(&data->hdd, data->addr, 1, data->buf); - readflash_set(READFLASH_HDC, data->hd_id); - } - data->cmd_pos = CMD_POS_TRANSFER; - for (; data->sector_pos < 512; data->sector_pos++) { - int ret = scsi_add_data(data->buf[data->sector_pos], data); -// pclog("SCSI_READ_10 sector_pos=%i\n", data->sector_pos); - if (ret == -1) { - fatal("scsi_add_data -1\n"); - break; - } - if (ret & 0x100) { - fatal("scsi_add_data 0x100\n"); - data->len = 1; - break; - } - } - data->cmd_pos = CMD_POS_START_SECTOR; - - data->sector_pos = 0; - data->len--; - data->addr++; - } - data->cmd_pos = CMD_POS_IDLE; - bus_state = BUS_IO; - break; - - case SCSI_WRITE_6: - if (data->read_only) { - pclog("zip read only\n"); - scsi_zip_cmd_error(data, KEY_DATA_PROTECT, ASC_WRITE_PROTECT, 0); - bus_state = BUS_CD | BUS_IO; - break; - } -// pclog("SCSI_WRITE_6 %i\n", data->cmd_pos); - if (data->cmd_pos == CMD_POS_WAIT) { - bus_state = BUS_CD; - break; - } - if (data->cmd_pos == CMD_POS_IDLE) { - data->addr = cdb[3] | (cdb[2] << 8) | ((cdb[1] & 0x1f) << 16); - data->len = cdb[4]; - if (!data->len) - data->len = 256; - readflash_set(READFLASH_HDC, data->hd_id); -// pclog("SCSI_WRITE_6: addr=%08x len=%04x\n", data->addr, data->len); - data->bytes_required = data->len * 512; - - data->cmd_pos = CMD_POS_WAIT; - timer_set_delay_u64(&data->callback_timer, RW_DELAY); - data->new_cmd_pos = CMD_POS_TRANSFER; - data->sector_pos = 0; - - bus_state = BUS_CD; - atapi_set_transfer_granularity(data->atapi_dev, 512); - break; - } - if (data->cmd_pos == CMD_POS_TRANSFER && data->bytes_received != data->bytes_required) { - bus_state = 0; - break; - } - - while (data->len) { - for (; data->sector_pos < 512; data->sector_pos++) { - int ret = scsi_get_data(data); - if (ret == -1) { - fatal("scsi_get_data -1\n"); - break; - } - data->buf[data->sector_pos] = ret & 0xff; - if (ret & 0x100) { - fatal("scsi_get_data 0x100\n"); - data->len = 1; - break; - } - } - - hdd_write_sectors(&data->hdd, data->addr, 1, data->buf); - readflash_set(READFLASH_HDC, data->hd_id); - - data->sector_pos = 0; - data->len--; - data->addr++; - } - data->cmd_pos = CMD_POS_IDLE; - bus_state = BUS_CD | BUS_IO; - break; - - case SCSI_WRITE_10: - case SCSI_WRITE_AND_VERIFY: - if (data->read_only) { - pclog("zip read only\n"); - scsi_zip_cmd_error(data, KEY_DATA_PROTECT, ASC_WRITE_PROTECT, 0); - bus_state = BUS_CD | BUS_IO; - break; - } -// pclog("SCSI_WRITE_10 %i\n", data->cmd_pos); - if (data->cmd_pos == CMD_POS_WAIT) { - bus_state = BUS_CD; - break; - } - if (data->cmd_pos == CMD_POS_IDLE) { - data->addr = cdb[5] | (cdb[4] << 8) | (cdb[3] << 16) | (cdb[2] << 24); - data->len = cdb[8] | (cdb[7] << 8); - readflash_set(READFLASH_HDC, data->hd_id); -// pclog("SCSI_WRITE_10: addr=%08x len=%04x\n", data->addr, data->len); - data->bytes_required = data->len * 512; - - data->cmd_pos = CMD_POS_WAIT; - timer_set_delay_u64(&data->callback_timer, RW_DELAY); - data->new_cmd_pos = CMD_POS_TRANSFER; - data->sector_pos = 0; - - bus_state = BUS_CD; - atapi_set_transfer_granularity(data->atapi_dev, 512); - break; - } - if (data->cmd_pos == CMD_POS_TRANSFER && data->bytes_received != data->bytes_required) { - bus_state = 0; - break; - } - - while (data->len) { - for (; data->sector_pos < 512; data->sector_pos++) { - int ret = scsi_get_data(data); -// pclog("SCSI_WRITE_10 sector_pos=%i\n", data->sector_pos); - if (ret == -1) { - fatal("scsi_get_data -1\n"); - break; - } - data->buf[data->sector_pos] = ret & 0xff; - if (ret & 0x100) { - fatal("scsi_get_data 0x100\n"); - data->len = 1; - break; - } - } - - hdd_write_sectors(&data->hdd, data->addr, 1, data->buf); - readflash_set(READFLASH_HDC, data->hd_id); - - data->sector_pos = 0; - data->len--; - data->addr++; - } - data->cmd_pos = CMD_POS_IDLE; - bus_state = BUS_CD | BUS_IO; -// output = 3; - break; - - case SCSI_VERIFY_10:data->cmd_pos = CMD_POS_IDLE; - bus_state = BUS_CD | BUS_IO; - break; - - case SCSI_MODE_SELECT_6: - if (!data->bytes_received) { - data->bytes_required = cdb[4]; -// pclog("SCSI_MODE_SELECT_6 bytes_required=%i\n", data->bytes_required); - bus_state = 0; - break; - } -// pclog("SCSI_MODE_SELECT_6 complete\n"); - data->cmd_pos = CMD_POS_IDLE; - bus_state = BUS_CD | BUS_IO; - break; - - case SCSI_FORMAT: - if (data->read_only) { - scsi_zip_cmd_error(data, KEY_DATA_PROTECT, ASC_WRITE_PROTECT, 0); - bus_state = BUS_CD | BUS_IO; - break; - } - readflash_set(READFLASH_HDC, 0); - hdd_format_sectors(&data->hdd, 0, ZIP_SECTORS); - - data->cmd_pos = CMD_POS_IDLE; - bus_state = BUS_CD | BUS_IO; - break; - - case SCSI_START_STOP_UNIT: - /*if ((cdb[4] & (START_STOP_LOEJ | START_STOP_START)) == START_STOP_LOEJ)*/ - /*This is incorrect based on the SCSI spec, but it's what the Iomega Win9x drivers send to eject a disc*/ - if ((cdb[4] & (START_STOP_LOEJ | START_STOP_START)) == 0) - zip_eject(); - bus_state = BUS_CD | BUS_IO; - break; - - /*These aren't really meaningful in a single initiator system, so just return*/ - case SCSI_RESERVE: - case SCSI_RELEASE:bus_state = BUS_CD | BUS_IO; - break; - - case SCSI_SEEK_6: - case SCSI_SEEK_10:bus_state = BUS_CD | BUS_IO; - break; - - case SEND_DIAGNOSTIC: - if (cdb[1] & (1 << 2)) { - /*Self-test*/ - /*Always passes*/ - bus_state = BUS_CD | BUS_IO; - } else { - /*Treat all other diagnostic requests as illegal*/ - scsi_zip_illegal(data); - bus_state = BUS_CD | BUS_IO; - } - break; - - case SCSI_IOMEGA_EJECT: - if (data->is_atapi) - zip_eject(); - else - scsi_zip_illegal(data); - - bus_state = BUS_CD | BUS_IO; - break; - - case ATAPI_READ_FORMAT_CAPACITIES: - if (data->is_atapi) { - len = cdb[8] | (cdb[7] << 8); - - /*List header*/ - scsi_add_data(0, data); - scsi_add_data(0, data); - scsi_add_data(0, data); - scsi_add_data(16, data); /*list length*/ - - /*Current/Maximum capacity header*/ - scsi_add_data((ZIP_SECTORS >> 24) & 0xff, data); - scsi_add_data((ZIP_SECTORS >> 16) & 0xff, data); - scsi_add_data((ZIP_SECTORS >> 8) & 0xff, data); - scsi_add_data(ZIP_SECTORS & 0xff, data); - if (data->disc_loaded) - scsi_add_data(2, data); /*Formatted media - current media capacity*/ - else - scsi_add_data(3, data); /*Maximum formattable capacity*/ - scsi_add_data(512 >> 16, data); - scsi_add_data(512 >> 8, data); - scsi_add_data(512 & 0xff, data); - - /*Formattable capacity descriptor*/ - scsi_add_data((ZIP_SECTORS >> 24) & 0xff, data); - scsi_add_data((ZIP_SECTORS >> 16) & 0xff, data); - scsi_add_data((ZIP_SECTORS >> 8) & 0xff, data); - scsi_add_data(ZIP_SECTORS & 0xff, data); - scsi_add_data(0, data); - scsi_add_data(512 >> 16, data); - scsi_add_data(512 >> 8, data); - scsi_add_data(512 & 0xff, data); - - data->cmd_pos = CMD_POS_IDLE; - bus_state = BUS_IO; - } else { - scsi_zip_illegal(data); - bus_state = BUS_CD | BUS_IO; - } - break; - - default:pclog("Bad SCSI ZIP command %02x\n", cdb[0]); - scsi_zip_illegal(data); - bus_state = BUS_CD | BUS_IO; - break; - } - - return bus_state; + scsi_zip_data *data = p; + int /*addr, */ len; + int i = 0, c; + int desc; + int bus_state = 0; + + if (data->cmd_pos == CMD_POS_IDLE) + pclog("SCSI ZIP command %02x %i %p\n", cdb[0], data->disc_loaded, data); + data->status = STATUS_GOOD; + data->data_pos_read = data->data_pos_write = 0; + + if ((cdb[0] != SCSI_REQUEST_SENSE /* && cdb[0] != SCSI_INQUIRY*/) && (cdb[1] & 0xe0)) { + pclog("non-zero LUN\n"); + /*Non-zero LUN - abort command*/ + scsi_zip_illegal(data); + bus_state = BUS_CD | BUS_IO; + return bus_state; + } + + if ((scsi_zip_cmd_flags[cdb[0]] & CHECK_READY) && !data->disc_loaded) { + pclog("Disc not loaded\n"); + scsi_zip_cmd_error(data, KEY_NOT_READY, ASC_MEDIUM_NOT_PRESENT, 0); + bus_state = BUS_CD | BUS_IO; + return bus_state; + } + if ((scsi_zip_cmd_flags[cdb[0]] & CHECK_READY) && data->disc_changed) { + pclog("Disc changed\n"); + scsi_zip_cmd_error(data, KEY_UNIT_ATTENTION, ASC_MEDIUM_MAY_HAVE_CHANGED, 0); + data->disc_changed = 0; + bus_state = BUS_CD | BUS_IO; + return bus_state; + } + + switch (cdb[0]) { + case SCSI_TEST_UNIT_READY: + bus_state = BUS_CD | BUS_IO; + break; + + case SCSI_IOMEGA_SENSE: + len = cdb[4]; + if (cdb[2] == 1) { + pclog("SCSI_IOMEGA_SENSE 1 %02x\n", len); + add_data_len(0x58); + add_data_len(0); + /*This page is related to disc health status - setting this page to 0 + makes disc health read as 'marginal'*/ + for (c = 2; c < 0x58; c++) + add_data_len(0xff); + while (i < len) + add_data_len(0); + data->cmd_pos = CMD_POS_IDLE; + bus_state = BUS_IO; + } else if (cdb[2] == 2) { + pclog("SCSI_IOMEGA_SENSE 2 %02x\n", len); + add_data_len(0x3d); + add_data_len(0); + for (c = 0; c < 19; c++) + add_data_len(0); + if (data->read_only) + add_data_len(2); + else + add_data_len(0); + for (c = 0; c < 39; c++) + add_data_len(0); + while (i < len) + add_data_len(0); + data->cmd_pos = CMD_POS_IDLE; + bus_state = BUS_IO; + } else { + pclog("IOMEGA_SENSE %02x %02x\n", cdb[2], len); + scsi_zip_illegal(data); + bus_state = BUS_CD | BUS_IO; + } + break; + + case SCSI_REZERO_UNIT: + bus_state = BUS_CD | BUS_IO; + break; + + case SCSI_REQUEST_SENSE: + desc = cdb[1] & 1; + len = cdb[4]; + + if (!desc) { + add_data_len(0x70); + add_data_len(0); + add_data_len(data->sense_key); /*Sense key*/ + add_data_len(0); /*Information (4 bytes)*/ + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); /*Additional sense length*/ + add_data_len(0); /*Command specific information (4 bytes)*/ + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(data->asc); /*ASC*/ + add_data_len(data->ascq); /*ASCQ*/ + add_data_len(0); /*FRU code*/ + add_data_len(0); /*Sense key specific (3 bytes)*/ + add_data_len(0); + add_data_len(0); + } else { + add_data_len(0x72); + add_data_len(data->sense_key); /*Sense Key*/ + add_data_len(data->asc); /*ASC*/ + add_data_len(data->ascq); /*ASCQ*/ + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); /*additional sense length*/ + } + + data->sense_key = data->asc = data->ascq = 0; + + data->cmd_pos = CMD_POS_IDLE; + bus_state = BUS_IO; + break; + + case SCSI_INQUIRY: + len = cdb[4] | (cdb[3] << 8); + // pclog("INQUIRY %d %02x %02x %02x %02x %02x %02x %i\n", len, + // cdb[0],cdb[1],cdb[2],cdb[3],cdb[4],cdb[5], data->hd_id); + + if (cdb[1] & 0xe0) { + add_data_len(0 | (3 << 5)); /*No physical device on this LUN*/ + } else { + add_data_len(0 | (0 << 5)); /*Hard disc*/ + } + add_data_len(0x80); /*Removeable device*/ + if (data->is_atapi) { + add_data_len(0); /*Not ANSI compliant*/ + add_data_len(0x21); /*ATAPI compliant*/ + } else { + add_data_len(2); /*SCSI-2 compliant*/ + add_data_len(0x02); + } + // add_data_len(0); /*No version*/ + // add_data_len(2); /*Response data*/ + add_data_len(0); /*Additional length*/ + add_data_len(0); + add_data_len(0); + add_data_len(2); + + add_data_len('I'); + add_data_len('O'); + add_data_len('M'); + add_data_len('E'); + add_data_len('G'); + add_data_len('A'); + add_data_len(' '); + add_data_len(' '); + + add_data_len('Z'); + add_data_len('I'); + add_data_len('P'); + add_data_len(' '); + add_data_len('1'); + add_data_len('0'); + add_data_len('0'); + add_data_len(' '); + + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + add_data_len(' '); + + add_data_len('E'); /*Product revision level*/ + add_data_len('.'); + add_data_len('0'); + add_data_len('8'); + + add_data_len(0); /*Drive serial number*/ + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + + add_data_len(0); /*Vendor unique*/ + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + + add_data_len(0); + add_data_len(0); + + add_data_len(0); /*Vendor descriptor*/ + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + + add_data_len(0); /*Reserved*/ + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + + data->cmd_pos = CMD_POS_IDLE; + bus_state = BUS_IO; + break; + + case SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL: + bus_state = BUS_CD | BUS_IO; + break; + + case SCSI_MODE_SENSE_6: + case SCSI_MODE_SENSE_10: + pclog("MODE_SENSE_6 %02x %02x\n", cdb[2], cdb[4]); + if ((cdb[2] & 0x3f) != 0x01 && (cdb[2] & 0x3f) != 0x02 && (cdb[2] & 0x3f) != 0x2f && (cdb[2] & 0x3f) != 0x3f) { + pclog("Invalid MODE_SENSE\n"); + scsi_zip_cmd_error(data, KEY_ILLEGAL_REQ, ASC_INV_FIELD_IN_CMD_PACKET, 0); + bus_state = BUS_CD | BUS_IO; + break; + } + if (cdb[0] == SCSI_MODE_SENSE_6) { + len = cdb[4]; + + add_data_len(0); + add_data_len(0); + + if (data->read_only) + add_data_len(0x80); + else + add_data_len(0); + add_data_len(0x08); + } else { + len = cdb[8] | (cdb[7] << 8); + + add_data_len(0); + add_data_len(0); + add_data_len(0); + + if (data->read_only) + add_data_len(0x80); + else + add_data_len(0); + + add_data_len(0); + add_data_len(0); + + add_data_len(0); + add_data_len(0x08); + } + + add_data_len((ZIP_SECTORS >> 24) & 0xff); + add_data_len((ZIP_SECTORS >> 16) & 0xff); + add_data_len((ZIP_SECTORS >> 8) & 0xff); + add_data_len(ZIP_SECTORS & 0xff); + add_data_len((512 >> 24) & 0xff); + add_data_len((512 >> 16) & 0xff); + add_data_len((512 >> 8) & 0xff); + add_data_len(512 & 0xff); + + if ((cdb[2] & 0x3f) == 0x01 || (cdb[2] & 0x3f) == 0x3f) { + add_data_len(0x01); + add_data_len(0x0a); + add_data_len(0xc8); /*Automatic read and write allocation enable, most expedient error recovery*/ + add_data_len(22); /*Read retry count = 22*/ + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(90); /*Write retry count = 90*/ + add_data_len(0); + add_data_len(20512 >> 8); + add_data_len(20512 & 0xff); + } + + if ((cdb[2] & 0x3f) == 0x02 || (cdb[2] & 0x3f) == 0x3f) { + add_data_len(0x02); + add_data_len(0x0e); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + add_data_len(0); + } + + if ((cdb[2] & 0x3f) == 0x2f || (cdb[2] & 0x3f) == 0x3f) { + add_data_len(0x2f); + add_data_len(0x04); + add_data_len(0x5c); + add_data_len(0x0f); + add_data_len(0xff); + add_data_len(0x0f); + } + + while (i < len) + add_data_len(0); + + len = data->data_pos_write; + if (cdb[0] == SCSI_MODE_SENSE_6) { + data->data_in[0] = len - 1; + } else { + data->data_in[0] = (len - 2) >> 8; + data->data_in[1] = (len - 2) & 255; + } + + // scsi_illegal_field(); + data->cmd_pos = CMD_POS_IDLE; + bus_state = BUS_IO; + break; + + case SCSI_READ_CAPACITY_10: + // len = 96 * 2048; + scsi_add_data((ZIP_SECTORS >> 24) & 0xff, data); + scsi_add_data((ZIP_SECTORS >> 16) & 0xff, data); + scsi_add_data((ZIP_SECTORS >> 8) & 0xff, data); + scsi_add_data(ZIP_SECTORS & 0xff, data); + scsi_add_data((512 >> 24) & 0xff, data); + scsi_add_data((512 >> 16) & 0xff, data); + scsi_add_data((512 >> 8) & 0xff, data); + scsi_add_data(512 & 0xff, data); + data->cmd_pos = CMD_POS_IDLE; + bus_state = BUS_IO; + break; + + case SCSI_READ_6: + // pclog("SCSI_READ_6 %i\n", data->cmd_pos); + if (data->cmd_pos == CMD_POS_WAIT) { + bus_state = BUS_CD; + break; + } + + if (data->cmd_pos == CMD_POS_IDLE) { + readflash_set(READFLASH_HDC, data->hd_id); + data->addr = cdb[3] | (cdb[2] << 8) | ((cdb[1] & 0x1f) << 16); + data->len = cdb[4]; + if (!data->len) + data->len = 256; + // pclog("SCSI_READ_6: addr=%08x len=%04x\n", data->addr, data->len); + + data->cmd_pos = CMD_POS_WAIT; + timer_set_delay_u64(&data->callback_timer, RW_DELAY); + data->new_cmd_pos = CMD_POS_START_SECTOR; + data->sector_pos = 0; + + bus_state = BUS_CD; + atapi_set_transfer_granularity(data->atapi_dev, 512); + break; + } + // else + // pclog("SCSI_READ_6 continue addr=%08x len=%04x sector_pos=%02x\n", data->addr, + // data->len, data->sector_pos); + while (data->len) { + if (data->cmd_pos == CMD_POS_START_SECTOR) { + hdd_read_sectors(&data->hdd, data->addr, 1, data->buf); + readflash_set(READFLASH_HDC, data->hd_id); + } + + data->cmd_pos = CMD_POS_TRANSFER; + for (; data->sector_pos < 512; data->sector_pos++) { + int ret = scsi_add_data(data->buf[data->sector_pos], data); + + if (ret == -1) { + fatal("scsi_add_data -1\n"); + break; + } + if (ret & 0x100) { + fatal("scsi_add_data 0x100\n"); + data->len = 1; + break; + } + } + data->cmd_pos = CMD_POS_START_SECTOR; + + data->sector_pos = 0; + data->len--; + data->addr++; + } + data->cmd_pos = CMD_POS_IDLE; + bus_state = BUS_IO; + break; + + case SCSI_READ_10: + // pclog("SCSI_READ_10 %i\n", data->cmd_pos); + if (data->cmd_pos == CMD_POS_WAIT) { + bus_state = BUS_CD; + break; + } + + if (data->cmd_pos == CMD_POS_IDLE) { + readflash_set(READFLASH_HDC, data->hd_id); + data->addr = cdb[5] | (cdb[4] << 8) | (cdb[3] << 16) | (cdb[2] << 24); + data->len = cdb[8] | (cdb[7] << 8); + // pclog("SCSI_READ_10: addr=%08x len=%04x\n", data->addr, data->len); + + data->cmd_pos = CMD_POS_WAIT; + timer_set_delay_u64(&data->callback_timer, RW_DELAY); + data->new_cmd_pos = CMD_POS_START_SECTOR; + data->sector_pos = 0; + + bus_state = BUS_CD; + atapi_set_transfer_granularity(data->atapi_dev, 512); + break; + } + // else + // pclog("SCSI_READ_10 continue addr=%08x len=%04x sector_pos=%02x\n", data->addr, + // data->len, data->sector_pos); + while (data->len) { + if (data->cmd_pos == CMD_POS_START_SECTOR) { + hdd_read_sectors(&data->hdd, data->addr, 1, data->buf); + readflash_set(READFLASH_HDC, data->hd_id); + } + data->cmd_pos = CMD_POS_TRANSFER; + for (; data->sector_pos < 512; data->sector_pos++) { + int ret = scsi_add_data(data->buf[data->sector_pos], data); + // pclog("SCSI_READ_10 sector_pos=%i\n", data->sector_pos); + if (ret == -1) { + fatal("scsi_add_data -1\n"); + break; + } + if (ret & 0x100) { + fatal("scsi_add_data 0x100\n"); + data->len = 1; + break; + } + } + data->cmd_pos = CMD_POS_START_SECTOR; + + data->sector_pos = 0; + data->len--; + data->addr++; + } + data->cmd_pos = CMD_POS_IDLE; + bus_state = BUS_IO; + break; + + case SCSI_WRITE_6: + if (data->read_only) { + pclog("zip read only\n"); + scsi_zip_cmd_error(data, KEY_DATA_PROTECT, ASC_WRITE_PROTECT, 0); + bus_state = BUS_CD | BUS_IO; + break; + } + // pclog("SCSI_WRITE_6 %i\n", data->cmd_pos); + if (data->cmd_pos == CMD_POS_WAIT) { + bus_state = BUS_CD; + break; + } + if (data->cmd_pos == CMD_POS_IDLE) { + data->addr = cdb[3] | (cdb[2] << 8) | ((cdb[1] & 0x1f) << 16); + data->len = cdb[4]; + if (!data->len) + data->len = 256; + readflash_set(READFLASH_HDC, data->hd_id); + // pclog("SCSI_WRITE_6: addr=%08x len=%04x\n", data->addr, data->len); + data->bytes_required = data->len * 512; + + data->cmd_pos = CMD_POS_WAIT; + timer_set_delay_u64(&data->callback_timer, RW_DELAY); + data->new_cmd_pos = CMD_POS_TRANSFER; + data->sector_pos = 0; + + bus_state = BUS_CD; + atapi_set_transfer_granularity(data->atapi_dev, 512); + break; + } + if (data->cmd_pos == CMD_POS_TRANSFER && data->bytes_received != data->bytes_required) { + bus_state = 0; + break; + } + + while (data->len) { + for (; data->sector_pos < 512; data->sector_pos++) { + int ret = scsi_get_data(data); + if (ret == -1) { + fatal("scsi_get_data -1\n"); + break; + } + data->buf[data->sector_pos] = ret & 0xff; + if (ret & 0x100) { + fatal("scsi_get_data 0x100\n"); + data->len = 1; + break; + } + } + + hdd_write_sectors(&data->hdd, data->addr, 1, data->buf); + readflash_set(READFLASH_HDC, data->hd_id); + + data->sector_pos = 0; + data->len--; + data->addr++; + } + data->cmd_pos = CMD_POS_IDLE; + bus_state = BUS_CD | BUS_IO; + break; + + case SCSI_WRITE_10: + case SCSI_WRITE_AND_VERIFY: + if (data->read_only) { + pclog("zip read only\n"); + scsi_zip_cmd_error(data, KEY_DATA_PROTECT, ASC_WRITE_PROTECT, 0); + bus_state = BUS_CD | BUS_IO; + break; + } + // pclog("SCSI_WRITE_10 %i\n", data->cmd_pos); + if (data->cmd_pos == CMD_POS_WAIT) { + bus_state = BUS_CD; + break; + } + if (data->cmd_pos == CMD_POS_IDLE) { + data->addr = cdb[5] | (cdb[4] << 8) | (cdb[3] << 16) | (cdb[2] << 24); + data->len = cdb[8] | (cdb[7] << 8); + readflash_set(READFLASH_HDC, data->hd_id); + // pclog("SCSI_WRITE_10: addr=%08x len=%04x\n", data->addr, data->len); + data->bytes_required = data->len * 512; + + data->cmd_pos = CMD_POS_WAIT; + timer_set_delay_u64(&data->callback_timer, RW_DELAY); + data->new_cmd_pos = CMD_POS_TRANSFER; + data->sector_pos = 0; + + bus_state = BUS_CD; + atapi_set_transfer_granularity(data->atapi_dev, 512); + break; + } + if (data->cmd_pos == CMD_POS_TRANSFER && data->bytes_received != data->bytes_required) { + bus_state = 0; + break; + } + + while (data->len) { + for (; data->sector_pos < 512; data->sector_pos++) { + int ret = scsi_get_data(data); + // pclog("SCSI_WRITE_10 sector_pos=%i\n", data->sector_pos); + if (ret == -1) { + fatal("scsi_get_data -1\n"); + break; + } + data->buf[data->sector_pos] = ret & 0xff; + if (ret & 0x100) { + fatal("scsi_get_data 0x100\n"); + data->len = 1; + break; + } + } + + hdd_write_sectors(&data->hdd, data->addr, 1, data->buf); + readflash_set(READFLASH_HDC, data->hd_id); + + data->sector_pos = 0; + data->len--; + data->addr++; + } + data->cmd_pos = CMD_POS_IDLE; + bus_state = BUS_CD | BUS_IO; + // output = 3; + break; + + case SCSI_VERIFY_10: + data->cmd_pos = CMD_POS_IDLE; + bus_state = BUS_CD | BUS_IO; + break; + + case SCSI_MODE_SELECT_6: + if (!data->bytes_received) { + data->bytes_required = cdb[4]; + // pclog("SCSI_MODE_SELECT_6 bytes_required=%i\n", data->bytes_required); + bus_state = 0; + break; + } + // pclog("SCSI_MODE_SELECT_6 complete\n"); + data->cmd_pos = CMD_POS_IDLE; + bus_state = BUS_CD | BUS_IO; + break; + + case SCSI_FORMAT: + if (data->read_only) { + scsi_zip_cmd_error(data, KEY_DATA_PROTECT, ASC_WRITE_PROTECT, 0); + bus_state = BUS_CD | BUS_IO; + break; + } + readflash_set(READFLASH_HDC, 0); + hdd_format_sectors(&data->hdd, 0, ZIP_SECTORS); + + data->cmd_pos = CMD_POS_IDLE; + bus_state = BUS_CD | BUS_IO; + break; + + case SCSI_START_STOP_UNIT: + /*if ((cdb[4] & (START_STOP_LOEJ | START_STOP_START)) == START_STOP_LOEJ)*/ + /*This is incorrect based on the SCSI spec, but it's what the Iomega Win9x drivers send to eject a disc*/ + if ((cdb[4] & (START_STOP_LOEJ | START_STOP_START)) == 0) + zip_eject(); + bus_state = BUS_CD | BUS_IO; + break; + + /*These aren't really meaningful in a single initiator system, so just return*/ + case SCSI_RESERVE: + case SCSI_RELEASE: + bus_state = BUS_CD | BUS_IO; + break; + + case SCSI_SEEK_6: + case SCSI_SEEK_10: + bus_state = BUS_CD | BUS_IO; + break; + + case SEND_DIAGNOSTIC: + if (cdb[1] & (1 << 2)) { + /*Self-test*/ + /*Always passes*/ + bus_state = BUS_CD | BUS_IO; + } else { + /*Treat all other diagnostic requests as illegal*/ + scsi_zip_illegal(data); + bus_state = BUS_CD | BUS_IO; + } + break; + + case SCSI_IOMEGA_EJECT: + if (data->is_atapi) + zip_eject(); + else + scsi_zip_illegal(data); + + bus_state = BUS_CD | BUS_IO; + break; + + case ATAPI_READ_FORMAT_CAPACITIES: + if (data->is_atapi) { + len = cdb[8] | (cdb[7] << 8); + + /*List header*/ + scsi_add_data(0, data); + scsi_add_data(0, data); + scsi_add_data(0, data); + scsi_add_data(16, data); /*list length*/ + + /*Current/Maximum capacity header*/ + scsi_add_data((ZIP_SECTORS >> 24) & 0xff, data); + scsi_add_data((ZIP_SECTORS >> 16) & 0xff, data); + scsi_add_data((ZIP_SECTORS >> 8) & 0xff, data); + scsi_add_data(ZIP_SECTORS & 0xff, data); + if (data->disc_loaded) + scsi_add_data(2, data); /*Formatted media - current media capacity*/ + else + scsi_add_data(3, data); /*Maximum formattable capacity*/ + scsi_add_data(512 >> 16, data); + scsi_add_data(512 >> 8, data); + scsi_add_data(512 & 0xff, data); + + /*Formattable capacity descriptor*/ + scsi_add_data((ZIP_SECTORS >> 24) & 0xff, data); + scsi_add_data((ZIP_SECTORS >> 16) & 0xff, data); + scsi_add_data((ZIP_SECTORS >> 8) & 0xff, data); + scsi_add_data(ZIP_SECTORS & 0xff, data); + scsi_add_data(0, data); + scsi_add_data(512 >> 16, data); + scsi_add_data(512 >> 8, data); + scsi_add_data(512 & 0xff, data); + + data->cmd_pos = CMD_POS_IDLE; + bus_state = BUS_IO; + } else { + scsi_zip_illegal(data); + bus_state = BUS_CD | BUS_IO; + } + break; + + default: + pclog("Bad SCSI ZIP command %02x\n", cdb[0]); + scsi_zip_illegal(data); + bus_state = BUS_CD | BUS_IO; + break; + } + + return bus_state; } static uint8_t scsi_zip_read(void *p) { - scsi_zip_data *data = p; + scsi_zip_data *data = p; - return data->data_in[data->data_pos_read++]; + return data->data_in[data->data_pos_read++]; } static void scsi_zip_write(uint8_t val, void *p) { - scsi_zip_data *data = p; + scsi_zip_data *data = p; - data->data_out[data->data_pos_write++] = val; + data->data_out[data->data_pos_write++] = val; - data->bytes_received++; + data->bytes_received++; - if (data->data_pos_write > BUFFER_SIZE) - fatal("Exceeded data_out buffer size\n"); + if (data->data_pos_write > BUFFER_SIZE) + fatal("Exceeded data_out buffer size\n"); } static int scsi_zip_read_complete(void *p) { - scsi_zip_data *data = p; + scsi_zip_data *data = p; - return (data->data_pos_read == data->data_pos_write); + return (data->data_pos_read == data->data_pos_write); } static int scsi_zip_write_complete(void *p) { - scsi_zip_data *data = p; + scsi_zip_data *data = p; - return (data->bytes_received == data->bytes_required); + return (data->bytes_received == data->bytes_required); } static void scsi_zip_start_command(void *p) { - scsi_zip_data *data = p; + scsi_zip_data *data = p; - data->bytes_received = 0; - data->bytes_required = 0; - data->data_pos_read = data->data_pos_write = 0; + data->bytes_received = 0; + data->bytes_required = 0; + data->data_pos_read = data->data_pos_write = 0; } static uint8_t scsi_zip_get_status(void *p) { - scsi_zip_data *data = p; + scsi_zip_data *data = p; - return data->status; + return data->status; } static uint8_t scsi_zip_get_sense_key(void *p) { - scsi_zip_data *data = p; + scsi_zip_data *data = p; - return data->sense_key; + return data->sense_key; } static int scsi_zip_get_bytes_required(void *p) { - scsi_zip_data *data = p; + scsi_zip_data *data = p; - return data->bytes_required - data->bytes_received; + return data->bytes_required - data->bytes_received; } static void scsi_zip_atapi_identify(uint16_t *buffer, void *p) { - scsi_zip_data *data = p; + scsi_zip_data *data = p; - memset(buffer, 0, 512); + memset(buffer, 0, 512); - buffer[0] = 0x8000 | (0 << 8) | 0x80 | (2 << 5); /* ATAPI device, direct-access device, removable media, accelerated DRQ */ - ide_padstr((char *)(buffer + 10), "", 20); /* Serial Number */ - ide_padstr((char *)(buffer + 23), "E.08", 8); /* Firmware */ - ide_padstr((char *)(buffer + 27), "IOMEGA ZIP 100 ATAPI", 40); /* Model */ - buffer[49] = 0x300; /*DMA and LBA supported*/ - buffer[51] = 120; - buffer[52] = 120; - buffer[53] = 2; /*Words 64-70 are valid*/ - buffer[62] = 0x0000; - buffer[63] = 0x0003 | (0x100 << data->mdma_mode); /*Multi-word DMA 0 & 1*/ - buffer[64] = 0x0001; /*PIO Mode 3*/ - if (data->pio_mode >= 3) - buffer[64] |= (0x100 << (data->pio_mode - 3)); - buffer[65] = 120; /*Minimum multi-word cycle time*/ - buffer[66] = 120; /*Recommended multi-word cycle time*/ - buffer[67] = 120; /*Minimum PIO cycle time*/ - buffer[126] = 0xfffe; /* Interpret zero byte count limit as maximum length */ + buffer[0] = + 0x8000 | (0 << 8) | 0x80 | (2 << 5); /* ATAPI device, direct-access device, removable media, accelerated DRQ */ + ide_padstr((char *)(buffer + 10), "", 20); /* Serial Number */ + ide_padstr((char *)(buffer + 23), "E.08", 8); /* Firmware */ + ide_padstr((char *)(buffer + 27), "IOMEGA ZIP 100 ATAPI", 40); /* Model */ + buffer[49] = 0x300; /*DMA and LBA supported*/ + buffer[51] = 120; + buffer[52] = 120; + buffer[53] = 2; /*Words 64-70 are valid*/ + buffer[62] = 0x0000; + buffer[63] = 0x0003 | (0x100 << data->mdma_mode); /*Multi-word DMA 0 & 1*/ + buffer[64] = 0x0001; /*PIO Mode 3*/ + if (data->pio_mode >= 3) + buffer[64] |= (0x100 << (data->pio_mode - 3)); + buffer[65] = 120; /*Minimum multi-word cycle time*/ + buffer[66] = 120; /*Recommended multi-word cycle time*/ + buffer[67] = 120; /*Minimum PIO cycle time*/ + buffer[126] = 0xfffe; /* Interpret zero byte count limit as maximum length */ } static int scsi_zip_atapi_set_feature(uint8_t feature, uint8_t val, void *p) { - scsi_zip_data *data = p; + scsi_zip_data *data = p; - switch (feature) { - case FEATURE_SET_TRANSFER_MODE: - if (!(val & 0xfe)) { - /*Default transfer mode*/ - data->pio_mode = 0; - return 1; - } else if ((val & 0xf8) == 0x08) { - /*PIO transfer mode*/ - if ((val & 7) > 3) - return 0; - data->pio_mode = (val & 7); - return 1; - } else if ((val & 0xf8) == 0x20) { - /*Multi-word DMA transfer mode*/ - if ((val & 7) > 1) - return 0; - data->mdma_mode = (val & 7); - return 1; - } - return 0; /*Invalid data*/ + switch (feature) { + case FEATURE_SET_TRANSFER_MODE: + if (!(val & 0xfe)) { + /*Default transfer mode*/ + data->pio_mode = 0; + return 1; + } else if ((val & 0xf8) == 0x08) { + /*PIO transfer mode*/ + if ((val & 7) > 3) + return 0; + data->pio_mode = (val & 7); + return 1; + } else if ((val & 0xf8) == 0x20) { + /*Multi-word DMA transfer mode*/ + if ((val & 7) > 1) + return 0; + data->mdma_mode = (val & 7); + return 1; + } + return 0; /*Invalid data*/ - case FEATURE_ENABLE_IRQ_OVERLAPPED: - case FEATURE_ENABLE_IRQ_SERVICE: - case FEATURE_DISABLE_REVERT: - case FEATURE_DISABLE_IRQ_OVERLAPPED: - case FEATURE_DISABLE_IRQ_SERVICE: - case FEATURE_ENABLE_REVERT:return 1; - } + case FEATURE_ENABLE_IRQ_OVERLAPPED: + case FEATURE_ENABLE_IRQ_SERVICE: + case FEATURE_DISABLE_REVERT: + case FEATURE_DISABLE_IRQ_OVERLAPPED: + case FEATURE_DISABLE_IRQ_SERVICE: + case FEATURE_ENABLE_REVERT: + return 1; + } - return 0; /*Feature not supported*/ + return 0; /*Feature not supported*/ } -scsi_device_t scsi_zip = - { - scsi_zip_init, - scsi_zip_atapi_init, - scsi_zip_close, - scsi_zip_reset, +scsi_device_t scsi_zip = { + scsi_zip_init, + scsi_zip_atapi_init, + scsi_zip_close, + scsi_zip_reset, - scsi_zip_start_command, - scsi_zip_command, + scsi_zip_start_command, + scsi_zip_command, - scsi_zip_get_status, - scsi_zip_get_sense_key, - scsi_zip_get_bytes_required, + scsi_zip_get_status, + scsi_zip_get_sense_key, + scsi_zip_get_bytes_required, - scsi_zip_atapi_identify, - scsi_zip_atapi_set_feature, + scsi_zip_atapi_identify, + scsi_zip_atapi_set_feature, - scsi_zip_read, - scsi_zip_write, - scsi_zip_read_complete, - scsi_zip_write_complete, - }; + scsi_zip_read, + scsi_zip_write, + scsi_zip_read_complete, + scsi_zip_write_complete, +}; diff --git a/src/sound/midi_alsa.c b/src/sound/midi_alsa.c index e2b4d5c7..cc99e241 100644 --- a/src/sound/midi_alsa.c +++ b/src/sound/midi_alsa.c @@ -6,10 +6,10 @@ #define MAX_MIDI_DEVICES 128 static struct { - int card; - int device; - int sub; - char name[50]; + int card; + int device; + int sub; + char name[50]; } midi_devices[MAX_MIDI_DEVICES]; static int midi_device_count = 0; @@ -19,92 +19,91 @@ static int midi_queried = 0; static snd_rawmidi_t *midiout = NULL; static void midi_query() { - int status; - int card = -1; + int status; + int card = -1; - midi_queried = 1; + midi_queried = 1; - if ((status = snd_card_next(&card)) < 0) - return; + if ((status = snd_card_next(&card)) < 0) + return; - if (card < 0) - return; /*No cards*/ + if (card < 0) + return; /*No cards*/ - while (card >= 0) { - char *shortname; + while (card >= 0) { + char *shortname; - if ((status = snd_card_get_name(card, &shortname)) >= 0) { - snd_ctl_t *ctl; - char name[32]; + if ((status = snd_card_get_name(card, &shortname)) >= 0) { + snd_ctl_t *ctl; + char name[32]; - sprintf(name, "hw:%i", card); + sprintf(name, "hw:%i", card); - if ((status = snd_ctl_open(&ctl, name, 0)) >= 0) { - int device = -1; + if ((status = snd_ctl_open(&ctl, name, 0)) >= 0) { + int device = -1; - do { - status = snd_ctl_rawmidi_next_device(ctl, &device); - if (status >= 0 && device != -1) { - snd_rawmidi_info_t *info; - int sub_nr, sub; + do { + status = snd_ctl_rawmidi_next_device(ctl, &device); + if (status >= 0 && device != -1) { + snd_rawmidi_info_t *info; + int sub_nr, sub; - snd_rawmidi_info_alloca(&info); - snd_rawmidi_info_set_device(info, device); - snd_rawmidi_info_set_stream(info, SND_RAWMIDI_STREAM_OUTPUT); - snd_ctl_rawmidi_info(ctl, info); - sub_nr = snd_rawmidi_info_get_subdevices_count(info); - pclog("sub_nr=%i\n", sub_nr); + snd_rawmidi_info_alloca(&info); + snd_rawmidi_info_set_device(info, device); + snd_rawmidi_info_set_stream(info, SND_RAWMIDI_STREAM_OUTPUT); + snd_ctl_rawmidi_info(ctl, info); + sub_nr = snd_rawmidi_info_get_subdevices_count(info); + pclog("sub_nr=%i\n", sub_nr); - for (sub = 0; sub < sub_nr; sub++) { - snd_rawmidi_info_set_subdevice(info, sub); + for (sub = 0; sub < sub_nr; sub++) { + snd_rawmidi_info_set_subdevice(info, sub); - if (snd_ctl_rawmidi_info(ctl, info) == 0) { - pclog("%s: MIDI device=%i:%i:%i\n", shortname, card, device, sub); + if (snd_ctl_rawmidi_info(ctl, info) == 0) { + pclog("%s: MIDI device=%i:%i:%i\n", shortname, card, device, sub); - midi_devices[midi_device_count].card = card; - midi_devices[midi_device_count].device = device; - midi_devices[midi_device_count].sub = sub; - snprintf(midi_devices[midi_device_count].name, 50, "%s (%i:%i:%i)", shortname, card, device, sub); - midi_device_count++; - if (midi_device_count >= MAX_MIDI_DEVICES) - return; - } - } - } - } while (device >= 0); - } - } + midi_devices[midi_device_count].card = card; + midi_devices[midi_device_count].device = device; + midi_devices[midi_device_count].sub = sub; + snprintf(midi_devices[midi_device_count].name, 50, + "%s (%i:%i:%i)", shortname, card, device, sub); + midi_device_count++; + if (midi_device_count >= MAX_MIDI_DEVICES) + return; + } + } + } + } while (device >= 0); + } + } - if (snd_card_next(&card) < 0) - break; - } + if (snd_card_next(&card) < 0) + break; + } } void midi_init() { - char portname[32]; - int midi_id; + char portname[32]; + int midi_id; - if (!midi_queried) - midi_query(); + if (!midi_queried) + midi_query(); - midi_id = config_get_int(CFG_MACHINE, NULL, "midi", 0); + midi_id = config_get_int(CFG_MACHINE, NULL, "midi", 0); - sprintf(portname, "hw:%i,%i,%i", midi_devices[midi_id].card, - midi_devices[midi_id].device, - midi_devices[midi_id].sub); - pclog("Opening MIDI port %s\n", portname); + sprintf(portname, "hw:%i,%i,%i", midi_devices[midi_id].card, midi_devices[midi_id].device, midi_devices[midi_id].sub); + pclog("Opening MIDI port %s\n", portname); - if (snd_rawmidi_open(NULL, &midiout, portname, SND_RAWMIDI_SYNC) < 0) { - pclog("Failed to open MIDI\n"); - return; - } + if (snd_rawmidi_open(NULL, &midiout, portname, SND_RAWMIDI_SYNC) < 0) { + pclog("Failed to open MIDI\n"); + return; + } } void midi_close() { - if (midiout != NULL) { - snd_rawmidi_close(midiout); - midiout = NULL; - } + if (midiout != NULL) { + snd_rawmidi_close(midiout); + midiout = NULL; + } } static int midi_pos, midi_len; @@ -114,52 +113,51 @@ static int midi_insysex; static uint8_t midi_sysex_data[65536]; void midi_write(uint8_t val) { - //pclog("Write MIDI %02x\n", val); + // pclog("Write MIDI %02x\n", val); - if ((val & 0x80) && !(val == 0xf7 && midi_insysex)) { - midi_pos = 0; - midi_len = midi_lengths[(val >> 4) & 7]; - midi_command[0] = midi_command[1] = midi_command[2] = midi_command[3] = 0; - if (val == 0xf0) - midi_insysex = 1; - } + if ((val & 0x80) && !(val == 0xf7 && midi_insysex)) { + midi_pos = 0; + midi_len = midi_lengths[(val >> 4) & 7]; + midi_command[0] = midi_command[1] = midi_command[2] = midi_command[3] = 0; + if (val == 0xf0) + midi_insysex = 1; + } - if (midi_insysex) { - midi_sysex_data[midi_pos++] = val; + if (midi_insysex) { + midi_sysex_data[midi_pos++] = val; - if (val == 0xf7 || midi_pos >= 65536) { -/* pclog("MIDI send sysex %i: ", midi_pos); - for (int i = 0; i < midi_pos; i++) - pclog("%02x ", midi_sysex_data[i]); - pclog("\n");*/ - snd_rawmidi_write(midiout, midi_sysex_data, midi_pos); -// pclog("Sent sysex\n"); - midi_insysex = 0; - } - return; - } + if (val == 0xf7 || midi_pos >= 65536) { + /* pclog("MIDI send sysex %i: ", midi_pos); + for (int i = 0; i < midi_pos; i++) + pclog("%02x ", midi_sysex_data[i]); + pclog("\n");*/ + snd_rawmidi_write(midiout, midi_sysex_data, midi_pos); + // pclog("Sent sysex\n"); + midi_insysex = 0; + } + return; + } - if (midi_len) { - if (midi_pos < 3) { - midi_command[midi_pos] = val; + if (midi_len) { + if (midi_pos < 3) { + midi_command[midi_pos] = val; - midi_pos++; + midi_pos++; - if (midi_pos == midi_len) { -// pclog("MIDI send %i: %02x %02x %02x %02x\n", midi_len, midi_command[0], midi_command[1], midi_command[2], midi_command[3]); - snd_rawmidi_write(midiout, midi_command, midi_len); - } - } - } + if (midi_pos == midi_len) { + // pclog("MIDI send %i: %02x %02x %02x %02x\n", midi_len, midi_command[0], + //midi_command[1], midi_command[2], midi_command[3]); + snd_rawmidi_write(midiout, midi_command, midi_len); + } + } + } } int midi_get_num_devs() { - if (!midi_queried) - midi_query(); + if (!midi_queried) + midi_query(); - return midi_device_count; + return midi_device_count; } -void midi_get_dev_name(int num, char *s) { - strcpy(s, midi_devices[num].name); -} +void midi_get_dev_name(int num, char *s) { strcpy(s, midi_devices[num].name); } diff --git a/src/sound/resid-fp/convolve-sse.cc b/src/sound/resid-fp/convolve-sse.cc index 009d6d3a..de50ba84 100644 --- a/src/sound/resid-fp/convolve-sse.cc +++ b/src/sound/resid-fp/convolve-sse.cc @@ -24,52 +24,52 @@ #include float convolve_sse(const float *a, const float *b, int n) { - float out = 0.f; - __m128 out4 = {0, 0, 0, 0}; + 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; + /* 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; - } + /* 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; - } - } + 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; + 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; + n &= 3; - while (n--) - out += (*(a++)) * (*(b++)); + while (n--) + out += (*(a++)) * (*(b++)); - return out; + return out; } #endif diff --git a/src/sound/resid-fp/convolve.cc b/src/sound/resid-fp/convolve.cc index 950c2492..b3b33001 100644 --- a/src/sound/resid-fp/convolve.cc +++ b/src/sound/resid-fp/convolve.cc @@ -18,9 +18,8 @@ // --------------------------------------------------------------------------- float convolve(const float *a, const float *b, int n) { - float out = 0.f; - while (n--) - out += (*(a++)) * (*(b++)); - return out; + float out = 0.f; + while (n--) + out += (*(a++)) * (*(b++)); + return out; } - diff --git a/src/sound/resid-fp/envelope.cc b/src/sound/resid-fp/envelope.cc index dc969b8d..18f979e5 100644 --- a/src/sound/resid-fp/envelope.cc +++ b/src/sound/resid-fp/envelope.cc @@ -23,36 +23,34 @@ // ---------------------------------------------------------------------------- // Constructor. // ---------------------------------------------------------------------------- -EnvelopeGeneratorFP::EnvelopeGeneratorFP() { - reset(); -} +EnvelopeGeneratorFP::EnvelopeGeneratorFP() { reset(); } // ---------------------------------------------------------------------------- // SID reset. // ---------------------------------------------------------------------------- void EnvelopeGeneratorFP::reset() { - envelope_counter = 0; + envelope_counter = 0; - attack = 0; - decay = 0; - sustain = 0; - release = 0; + attack = 0; + decay = 0; + sustain = 0; + release = 0; - gate = 0; + gate = 0; - rate_counter = 0; - exponential_counter = 0; - exponential_counter_period = 1; + rate_counter = 0; + exponential_counter = 0; + exponential_counter_period = 1; - state = RELEASE; - rate_period = rate_counter_period[release]; - hold_zero = true; + 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 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 @@ -94,25 +92,24 @@ void EnvelopeGeneratorFP::reset() { // 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 + 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 @@ -145,100 +142,82 @@ reg16 EnvelopeGeneratorFP::rate_counter_period[] = { // 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, + 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; + 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). + // 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]); + // 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]); - } + // 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; + 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]); - } + 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]); - } + sustain = (sustain_release >> 4) & 0x0f; + release = sustain_release & 0x0f; + if (state == RELEASE) { + update_rate_period(rate_counter_period[release]); + } } -reg8 EnvelopeGeneratorFP::readENV() { - return output(); -} +reg8 EnvelopeGeneratorFP::readENV() { return output(); } void EnvelopeGeneratorFP::update_rate_period(reg16 newperiod) { - rate_period = 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. */ + /* 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; + /* 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; + /* 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... */ + /* at this point it should be impossible for + * rate_counter >= rate_period. If it is, there is a bug... */ } diff --git a/src/sound/resid-fp/extfilt.cc b/src/sound/resid-fp/extfilt.cc index ce5468a9..7fe230de 100644 --- a/src/sound/resid-fp/extfilt.cc +++ b/src/sound/resid-fp/extfilt.cc @@ -24,61 +24,59 @@ // Constructor. // ---------------------------------------------------------------------------- ExternalFilterFP::ExternalFilterFP() { - reset(); - enable_filter(true); - set_chip_model(MOS6581FP); - set_clock_frequency(1e6f); - set_sampling_parameter(15915.6f); + 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; -} +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(); + clock_frequency = clock; + _set_sampling_parameter(); } void ExternalFilterFP::set_sampling_parameter(float freq) { - pass_frequency = freq; - _set_sampling_parameter(); + 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; + // 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; - } + 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; + // State of filter. + Vlp = 0; + Vhp = 0; + Vo = 0; } diff --git a/src/sound/resid-fp/filter.cc b/src/sound/resid-fp/filter.cc index 30e5780a..dd6c96c1 100644 --- a/src/sound/resid-fp/filter.cc +++ b/src/sound/resid-fp/filter.cc @@ -31,147 +31,139 @@ extern float expf(float val); #endif #ifndef HAVE_LOGF -float logf(float val) -{ - return (float)log((double)val); -} +float logf(float val) { return (float)log((double)val); } #endif #ifndef HAVE_EXPF -float expf(float val) -{ - return (float)exp((double)val); -} +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); + 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; -} +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(); + 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(); + 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(); + 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; + 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; + 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(); + 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(); + 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(); + fc = (fc & 0x7f8) | (fc_lo & 0x007); + set_w0(); } void FilterFP::writeFC_HI(reg8 fc_hi) { - fc = ((fc_hi << 3) & 0x7f8) | (fc & 0x007); - set_w0(); + fc = ((fc_hi << 3) & 0x7f8) | (fc & 0x007); + set_w0(); } void FilterFP::writeRES_FILT(reg8 res_filt) { - res = (res_filt >> 4) & 0x0f; - set_Q(); + res = (res_filt >> 4) & 0x0f; + set_Q(); - filt = res_filt & 0x0f; + filt = res_filt & 0x0f; } void FilterFP::writeMODE_VOL(reg8 mode_vol) { - voice3off = mode_vol & 0x80; + voice3off = mode_vol & 0x80; - hp_bp_lp = (mode_vol >> 4) & 0x07; + hp_bp_lp = (mode_vol >> 4) & 0x07; - vol = mode_vol & 0x0f; - volf = (float)vol / 15.f; + 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(); - } + 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); + float Q = res / 15.f; + _1_div_Q = 1.f / (0.707f + Q * 1.5f); } diff --git a/src/sound/resid-fp/pot.cc b/src/sound/resid-fp/pot.cc index 2d13e36a..b143e47c 100644 --- a/src/sound/resid-fp/pot.cc +++ b/src/sound/resid-fp/pot.cc @@ -20,6 +20,6 @@ #include "resid-fp/pot.h" reg8 PotentiometerFP::readPOT() { - // NB! Not modeled. - return 0xff; + // NB! Not modeled. + return 0xff; } diff --git a/src/sound/resid-fp/sid.cc b/src/sound/resid-fp/sid.cc index a5256bc6..892e1c85 100644 --- a/src/sound/resid-fp/sid.cc +++ b/src/sound/resid-fp/sid.cc @@ -24,86 +24,72 @@ 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 -}; +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; + 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; + cpu_x86_regs_t retval; #if defined(_MSC_VER) /* MSVC assembly */ - __asm { + __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"); + 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; + return retval; } static int host_cpu_features_by_cpuid(void) { - cpu_x86_regs_t regs = get_cpuid_regs(1); + 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; + 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; + return features; } static int host_cpu_features(void) { - static int features = 0; - static int features_detected = 0; + static int features = 0; + static int features_detected = 0; /* 32-bit only */ #if defined(__i386__) || (defined(_MSC_VER) && defined(_WIN32)) - unsigned long temp1, temp2; + unsigned long temp1, temp2; #endif - if (features_detected) - return features; - features_detected = 1; + 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 { + /* see if we are dealing with a cpu that has the cpuid instruction */ + __asm { pushf pop eax mov [temp1], eax @@ -115,55 +101,52 @@ static int host_cpu_features(void) { 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"); + 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; - } + 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; - } + /* 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; + features = host_cpu_features_by_cpuid(); + return features; } #else /* !__x86_64__ && !__i386__ && !_MSC_VER */ -static int host_cpu_features(void) -{ - return 0; -} +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; + 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; - } + 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); + return value / (weight / nonlinearity) * (1 << max); } // ---------------------------------------------------------------------------- @@ -171,66 +154,66 @@ float SIDFP::kinked_dac(const int x, const float nonlinearity, const int max) { // ---------------------------------------------------------------------------- SIDFP::SIDFP() { #if (RESID_USE_SSE == 1) - can_use_sse = (host_cpu_features() & HOST_CPU_SSE) != 0; + can_use_sse = (host_cpu_features() & HOST_CPU_SSE) != 0; #else - can_use_sse = false; + can_use_sse = false; #endif - // Initialize pointers. - sample = 0; - fir = 0; + // 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]); + 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); + set_sampling_parameters(985248, SAMPLE_INTERPOLATE, 44100); - bus_value = 0; - bus_value_ttl = 0; + bus_value = 0; + bus_value_ttl = 0; - input(0); + input(0); } // ---------------------------------------------------------------------------- // Destructor. // ---------------------------------------------------------------------------- SIDFP::~SIDFP() { - delete[] sample; - delete[] fir; + 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); - } + for (int i = 0; i < 3; i++) { + voice[i].set_chip_model(model); + } - filter.set_chip_model(model); - extfilt.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); - } + 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(); + for (int i = 0; i < 3; i++) { + voice[i].reset(); + } + filter.reset(); + extfilt.reset(); - bus_value = 0; - bus_value_ttl = 0; + bus_value = 0; + bus_value_ttl = 0; } // ---------------------------------------------------------------------------- @@ -240,14 +223,14 @@ void SIDFP::reset() { // 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); + // 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); + const float range = 1 << 15; + return extfilt.output() / (4095.f * 255.f * 3.f * 1.5f / range); } // ---------------------------------------------------------------------------- @@ -268,226 +251,245 @@ float SIDFP::output() { // 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; - } + 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; + 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; - } + 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; + int i; - for (i = 0; i < 0x20; i++) { - sid_register[i] = 0; - } + for (i = 0; i < 0x20; i++) { + sid_register[i] = 0; + } - bus_value = 0; - bus_value_ttl = 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; - } + 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; + 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; - } + 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; + 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; - } + // 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; + 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; - } + 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; + return state; } // ---------------------------------------------------------------------------- // Write state. // ---------------------------------------------------------------------------- void SIDFP::write_state(const State &state) { - int i; + int i; - for (i = 0; i <= 0x18; i++) { - write(i, state.sid_register[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; + 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]; - } + 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); -} +void SIDFP::enable_filter(bool enable) { filter.enable_filter(enable); } // ---------------------------------------------------------------------------- // Enable external filter. // ---------------------------------------------------------------------------- -void SIDFP::enable_external_filter(bool enable) { - extfilt.enable_filter(enable); -} +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; + // 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; + double sum, u, halfx, temp; + int n; - sum = u = n = 1; - halfx = x / 2.0; + sum = u = n = 1; + halfx = x / 2.0; - do { - temp = halfx / n++; - u *= temp * temp; - sum += u; - } while (u >= I0e * sum); + do { + temp = halfx / n++; + u *= temp * temp; + sum += u; + } while (u >= I0e * sum); - return sum; + return sum; } - // ---------------------------------------------------------------------------- // Setting of SID sampling parameters. // @@ -502,7 +504,7 @@ double SIDFP::I0(double x) { // 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 @@ -510,109 +512,106 @@ double SIDFP::I0(double x) { // 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; +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); + filter.set_clock_frequency(clock_freq); + extfilt.set_clock_frequency(clock_freq); + adjust_sampling_frequency(sample_freq); - sample_offset = 0; - sample_prev = 0; + 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; - } + // 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; + 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; + 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)); + // 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); + // 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; + 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; + /* 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. */ + 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; + 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; + // 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; + // 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); - } + /* 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]; + // 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; + // 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); - } - } + // 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; + // 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; + return true; } // ---------------------------------------------------------------------------- @@ -627,43 +626,41 @@ bool SIDFP::set_sampling_parameters(float clock_freq, sampling_method method, // 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::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; - } - } + 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; + int i; - // Clock amplitude modulators. - for (i = 0; i < 3; i++) { - voice[i].envelope.clock(); - } + // 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(); - } + // Clock oscillators. + for (i = 0; i < 3; i++) { + voice[i].wave.clock(); + } - // Synchronize oscillators. - for (i = 0; i < 3; i++) { - voice[i].wave.synchronize(); - } + // 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)); + // Clock filter. + extfilt.clock(filter.clock(voice[0].output(), voice[1].output(), voice[2].output(), ext_in)); } // ---------------------------------------------------------------------------- @@ -678,24 +675,26 @@ void SIDFP::clock() { // 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; - } + /* 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(); + filter.nuke_denormals(); + extfilt.nuke_denormals(); - return res; + return res; } // ---------------------------------------------------------------------------- @@ -708,54 +707,53 @@ int SIDFP::clock(cycle_count &delta_t, short *buf, int n, int interleave) { // sampling noise. // ---------------------------------------------------------------------------- RESID_INLINE -int SIDFP::clock_interpolate(cycle_count &delta_t, short *buf, int n, - int interleave) { - int s = 0; - int i; +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(); - } + 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; + 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; - } + 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; + 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; } // ---------------------------------------------------------------------------- @@ -795,79 +793,78 @@ int SIDFP::clock_interpolate(cycle_count &delta_t, short *buf, int n, // 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; +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; + 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; + /* 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; + /* 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 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; + /* 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 = + float v1 = #if (RESID_USE_SSE == 1) - can_use_sse ? convolve_sse(sample_start, fir + fir_offset * fir_N, fir_N) : + 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); + 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 = + // 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) : + 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); + 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)); + // 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; - } + // 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; - } + 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; + /* 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/sound/resid-fp/voice.cc b/src/sound/resid-fp/voice.cc index f617eb1f..61b1df01 100644 --- a/src/sound/resid-fp/voice.cc +++ b/src/sound/resid-fp/voice.cc @@ -25,70 +25,68 @@ // Constructor. // ---------------------------------------------------------------------------- VoiceFP::VoiceFP() { - nonlinearity = 1.f; - set_chip_model(MOS6581FP); + 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(); + nonlinearity = nl; + calculate_dac_tables(); } // ---------------------------------------------------------------------------- // Set chip model. // ---------------------------------------------------------------------------- void VoiceFP::set_chip_model(chip_model model) { - wave.set_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(); - } + 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; + 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); -} +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); + wave.writeCONTROL_REG(control); + envelope.writeCONTROL_REG(control); } // ---------------------------------------------------------------------------- // SID reset. // ---------------------------------------------------------------------------- void VoiceFP::reset() { - wave.reset(); - envelope.reset(); + wave.reset(); + envelope.reset(); } diff --git a/src/sound/resid-fp/wave.cc b/src/sound/resid-fp/wave.cc index b1494696..2d5a8a9e 100644 --- a/src/sound/resid-fp/wave.cc +++ b/src/sound/resid-fp/wave.cc @@ -24,114 +24,109 @@ // Constructor. // ---------------------------------------------------------------------------- WaveformGeneratorFP::WaveformGeneratorFP() { - sync_source = this; + sync_source = this; - set_chip_model(MOS6581FP); + set_chip_model(MOS6581FP); - reset(); + reset(); } // ---------------------------------------------------------------------------- // Set sync source. // ---------------------------------------------------------------------------- void WaveformGeneratorFP::set_sync_source(WaveformGeneratorFP *source) { - sync_source = source; - source->sync_dest = this; + 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; - } + 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_LO(reg8 freq_lo) { freq = (freq & 0xff00) | (freq_lo & 0x00ff); } -void WaveformGeneratorFP::writeFREQ_HI(reg8 freq_hi) { - freq = ((freq_hi << 8) & 0xff00) | (freq & 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; + 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; + 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; + waveform = (control >> 4) & 0x0f; + ring_mod = control & 0x04; + sync = control & 0x02; - reg8 test_next = control & 0x08; + 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. */ + /* 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); - } + // 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; + test = test_next; - /* update noise anyway, just in case the above paths triggered */ - noise_output_cached = outputN___(); + /* update noise anyway, just in case the above paths triggered */ + noise_output_cached = outputN___(); } -reg8 WaveformGeneratorFP::readOSC() { - return output() >> 4; -} +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; + 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/sound/resid-fp/wave6581_PST.cc b/src/sound/resid-fp/wave6581_PST.cc index 96384e74..3cc06772 100644 --- a/src/sound/resid-fp/wave6581_PST.cc +++ b/src/sound/resid-fp/wave6581_PST.cc @@ -19,518 +19,517 @@ #include "resid-fp/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, - }; +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/sound/resid-fp/wave6581_PS_.cc b/src/sound/resid-fp/wave6581_PS_.cc index 54ccb5f9..828ecc66 100644 --- a/src/sound/resid-fp/wave6581_PS_.cc +++ b/src/sound/resid-fp/wave6581_PS_.cc @@ -19,518 +19,517 @@ #include "resid-fp/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, - }; +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/sound/resid-fp/wave6581_P_T.cc b/src/sound/resid-fp/wave6581_P_T.cc index b657c6ab..f2102c1e 100644 --- a/src/sound/resid-fp/wave6581_P_T.cc +++ b/src/sound/resid-fp/wave6581_P_T.cc @@ -19,518 +19,517 @@ #include "resid-fp/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, - }; +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/sound/resid-fp/wave6581__ST.cc b/src/sound/resid-fp/wave6581__ST.cc index 0977afa2..5df1bfea 100644 --- a/src/sound/resid-fp/wave6581__ST.cc +++ b/src/sound/resid-fp/wave6581__ST.cc @@ -19,518 +19,517 @@ #include "resid-fp/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, - }; +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/sound/resid-fp/wave8580_PST.cc b/src/sound/resid-fp/wave8580_PST.cc index bb272819..b104a6ce 100644 --- a/src/sound/resid-fp/wave8580_PST.cc +++ b/src/sound/resid-fp/wave8580_PST.cc @@ -19,518 +19,517 @@ #include "resid-fp/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, - }; +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/sound/resid-fp/wave8580_PS_.cc b/src/sound/resid-fp/wave8580_PS_.cc index 95bdf4b8..eac34b05 100644 --- a/src/sound/resid-fp/wave8580_PS_.cc +++ b/src/sound/resid-fp/wave8580_PS_.cc @@ -19,518 +19,517 @@ #include "resid-fp/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, - }; +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/sound/resid-fp/wave8580_P_T.cc b/src/sound/resid-fp/wave8580_P_T.cc index e1cf4872..f25cc33b 100644 --- a/src/sound/resid-fp/wave8580_P_T.cc +++ b/src/sound/resid-fp/wave8580_P_T.cc @@ -19,518 +19,517 @@ #include "resid-fp/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, - }; +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/sound/resid-fp/wave8580__ST.cc b/src/sound/resid-fp/wave8580__ST.cc index 619fb7f6..ad58ccee 100644 --- a/src/sound/resid-fp/wave8580__ST.cc +++ b/src/sound/resid-fp/wave8580__ST.cc @@ -19,518 +19,517 @@ #include "resid-fp/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, - }; +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/sound/sdl2-midi.c b/src/sound/sdl2-midi.c index 9b7a5a48..82eb37a7 100644 --- a/src/sound/sdl2-midi.c +++ b/src/sound/sdl2-midi.c @@ -1,18 +1,12 @@ #include #include "plat-midi.h" -void midi_init() { -} +void midi_init() {} -void midi_close() { -} +void midi_close() {} -void midi_write(uint8_t val) { -} +void midi_write(uint8_t val) {} -int midi_get_num_devs() { - return 0; -} +int midi_get_num_devs() { return 0; } -void midi_get_dev_name(int num, char *s) { -} +void midi_get_dev_name(int num, char *s) {} diff --git a/src/sound/sound.c b/src/sound/sound.c index 3a58b80d..3c55b52d 100644 --- a/src/sound/sound.c +++ b/src/sound/sound.c @@ -52,58 +52,58 @@ SOUND_CARD sc_es1371 = {"Ensoniq AudioPCI (ES1371)", "es1371", &es1371_device}; SOUND_CARD sc_sbpci128 = {"Sound Blaster PCI 128", "sbpci128", &es1371_device}; int sound_card_available(int card) { - if (sound_cards[card] != NULL && sound_cards[card]->device != NULL) - return device_available(sound_cards[card]->device); + if (sound_cards[card] != NULL && sound_cards[card]->device != NULL) + return device_available(sound_cards[card]->device); - return 1; + return 1; } char *sound_card_getname(int card) { - if (sound_cards[card] != NULL) - return sound_cards[card]->name; + if (sound_cards[card] != NULL) + return sound_cards[card]->name; - return ""; + return ""; } device_t *sound_card_getdevice(int card) { - if (sound_cards[card] != NULL) - return sound_cards[card]->device; + if (sound_cards[card] != NULL) + return sound_cards[card]->device; - return NULL; + return NULL; } int sound_card_has_config(int card) { - if (sound_cards[card] != NULL || !sound_cards[card]->device) - return 0; - return sound_cards[card]->device->config ? 1 : 0; + if (sound_cards[card] != NULL || !sound_cards[card]->device) + return 0; + return sound_cards[card]->device->config ? 1 : 0; } char *sound_card_get_internal_name(int card) { - if (sound_cards[card] != NULL) - return sound_cards[card]->internal_name; + if (sound_cards[card] != NULL) + return sound_cards[card]->internal_name; } int sound_card_get_from_internal_name(char *s) { - int c = 0; + int c = 0; - while (sound_cards[c] != NULL) { - if (!strcmp(sound_cards[c]->internal_name, s)) - return c; - c++; - } + while (sound_cards[c] != NULL) { + if (!strcmp(sound_cards[c]->internal_name, s)) + return c; + c++; + } - return 0; + return 0; } void sound_card_init() { - if (sound_cards[sound_card_current]->device) - device_add(sound_cards[sound_card_current]->device); - sound_card_last = sound_card_current; + if (sound_cards[sound_card_current]->device) + device_add(sound_cards[sound_card_current]->device); + sound_card_last = sound_card_current; } static struct { - void (*get_buffer)(int32_t *buffer, int len, void *p); - void *priv; + void (*get_buffer)(int32_t *buffer, int len, void *p); + void *priv; } sound_handlers[8]; static int sound_handlers_num; @@ -123,167 +123,164 @@ int sound_buf_len = 48000 / 10; int sound_gain = 0; void sound_update_buf_length() { - int new_buf_len = (48000 / (1000 / sound_buf_len)) / 4; + int new_buf_len = (48000 / (1000 / sound_buf_len)) / 4; - if (new_buf_len > MAXSOUNDBUFLEN) - new_buf_len = MAXSOUNDBUFLEN; + if (new_buf_len > MAXSOUNDBUFLEN) + new_buf_len = MAXSOUNDBUFLEN; - SOUNDBUFLEN = new_buf_len; + SOUNDBUFLEN = new_buf_len; } void sound_set_cd_volume(unsigned int vol_l, unsigned int vol_r) { - cd_vol_l = vol_l; - cd_vol_r = vol_r; + cd_vol_l = vol_l; + cd_vol_r = vol_r; } static void sound_cd_thread(void *param) { - while (1) { - int c; + while (1) { + int c; - thread_wait_event(sound_cd_event, -1); - thread_reset_event(sound_cd_event); - memset(cd_buffer, 0, CD_BUFLEN * 2 * 2); - ioctl_audio_callback(cd_buffer, CD_BUFLEN * 2); - image_audio_callback(cd_buffer, CD_BUFLEN * 2); - if (soundon) { - int32_t atapi_vol_l = atapi_get_cd_volume(0); - int32_t atapi_vol_r = atapi_get_cd_volume(1); - int channel_select[2]; + thread_wait_event(sound_cd_event, -1); + thread_reset_event(sound_cd_event); + memset(cd_buffer, 0, CD_BUFLEN * 2 * 2); + ioctl_audio_callback(cd_buffer, CD_BUFLEN * 2); + image_audio_callback(cd_buffer, CD_BUFLEN * 2); + if (soundon) { + int32_t atapi_vol_l = atapi_get_cd_volume(0); + int32_t atapi_vol_r = atapi_get_cd_volume(1); + int channel_select[2]; - channel_select[0] = atapi_get_cd_channel(0); - channel_select[1] = atapi_get_cd_channel(1); + channel_select[0] = atapi_get_cd_channel(0); + channel_select[1] = atapi_get_cd_channel(1); - for (c = 0; c < CD_BUFLEN * 2; c += 2) { - int32_t cd_buffer_temp[2] = {0, 0}; + for (c = 0; c < CD_BUFLEN * 2; c += 2) { + int32_t cd_buffer_temp[2] = {0, 0}; - /*First, adjust input from drive according to ATAPI volume.*/ - cd_buffer[c] = ((int32_t)cd_buffer[c] * atapi_vol_l) / 255; - cd_buffer[c + 1] = ((int32_t)cd_buffer[c + 1] * atapi_vol_r) / 255; + /*First, adjust input from drive according to ATAPI volume.*/ + cd_buffer[c] = ((int32_t)cd_buffer[c] * atapi_vol_l) / 255; + cd_buffer[c + 1] = ((int32_t)cd_buffer[c + 1] * atapi_vol_r) / 255; - /*Apply ATAPI channel select*/ - if (channel_select[0] & 1) - cd_buffer_temp[0] += cd_buffer[c]; - if (channel_select[0] & 2) - cd_buffer_temp[1] += cd_buffer[c]; - if (channel_select[1] & 1) - cd_buffer_temp[0] += cd_buffer[c + 1]; - if (channel_select[1] & 2) - cd_buffer_temp[1] += cd_buffer[c + 1]; + /*Apply ATAPI channel select*/ + if (channel_select[0] & 1) + cd_buffer_temp[0] += cd_buffer[c]; + if (channel_select[0] & 2) + cd_buffer_temp[1] += cd_buffer[c]; + if (channel_select[1] & 1) + cd_buffer_temp[0] += cd_buffer[c + 1]; + if (channel_select[1] & 2) + cd_buffer_temp[1] += cd_buffer[c + 1]; - /*Apply sound card CD volume*/ - cd_buffer_temp[0] = (cd_buffer_temp[0] * (int)cd_vol_l) / 65535; - cd_buffer_temp[1] = (cd_buffer_temp[1] * (int)cd_vol_r) / 65535; + /*Apply sound card CD volume*/ + cd_buffer_temp[0] = (cd_buffer_temp[0] * (int)cd_vol_l) / 65535; + cd_buffer_temp[1] = (cd_buffer_temp[1] * (int)cd_vol_r) / 65535; - if (cd_buffer_temp[0] > 32767) - cd_buffer_temp[0] = 32767; - if (cd_buffer_temp[0] < -32768) - cd_buffer_temp[0] = -32768; - if (cd_buffer_temp[1] > 32767) - cd_buffer_temp[1] = 32767; - if (cd_buffer_temp[1] < -32768) - cd_buffer_temp[1] = -32768; + if (cd_buffer_temp[0] > 32767) + cd_buffer_temp[0] = 32767; + if (cd_buffer_temp[0] < -32768) + cd_buffer_temp[0] = -32768; + if (cd_buffer_temp[1] > 32767) + cd_buffer_temp[1] = 32767; + if (cd_buffer_temp[1] < -32768) + cd_buffer_temp[1] = -32768; - cd_buffer[c] = cd_buffer_temp[0]; - cd_buffer[c + 1] = cd_buffer_temp[1]; - } + cd_buffer[c] = cd_buffer_temp[0]; + cd_buffer[c + 1] = cd_buffer_temp[1]; + } - givealbuffer_cd(cd_buffer); - } - } + givealbuffer_cd(cd_buffer); + } + } } static int32_t *outbuffer; void sound_init() { - initalmain(0, NULL); - inital(); + initalmain(0, NULL); + inital(); - outbuffer = malloc(MAXSOUNDBUFLEN * 2 * sizeof(int32_t)); + outbuffer = malloc(MAXSOUNDBUFLEN * 2 * sizeof(int32_t)); - sound_cd_event = thread_create_event(); - sound_cd_thread_h = thread_create(sound_cd_thread, NULL); + sound_cd_event = thread_create_event(); + sound_cd_thread_h = thread_create(sound_cd_thread, NULL); } 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++; + sound_handlers[sound_handlers_num].get_buffer = get_buffer; + sound_handlers[sound_handlers_num].priv = p; + sound_handlers_num++; } static int cd_pos = 0; void sound_poll(void *priv) { - timer_advance_u64(&sound_poll_timer, sound_poll_latch); + timer_advance_u64(&sound_poll_timer, sound_poll_latch); - cd_pos++; - if (cd_pos == (CD_BUFLEN * 48000) / CD_FREQ) { - cd_pos = 0; - thread_set_event(sound_cd_event); - } + cd_pos++; + if (cd_pos == (CD_BUFLEN * 48000) / CD_FREQ) { + cd_pos = 0; + thread_set_event(sound_cd_event); + } - sound_pos_global++; - if (sound_pos_global == SOUNDBUFLEN) { - int c; -/* int16_t buf16[SOUNDBUFLEN * 2 ];*/ + sound_pos_global++; + if (sound_pos_global == SOUNDBUFLEN) { + int c; + /* int16_t buf16[SOUNDBUFLEN * 2 ];*/ - memset(outbuffer, 0, SOUNDBUFLEN * 2 * sizeof(int32_t)); + 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 < sound_handlers_num; c++) + sound_handlers[c].get_buffer(outbuffer, SOUNDBUFLEN, sound_handlers[c].priv); + /* for (c=0;c 32767) + buf16[c] = 32767; + else + buf16[c] = outbuffer[c]; + } -/* for (c=0;c 32767) - buf16[c] = 32767; - else - buf16[c] = outbuffer[c]; - } + if (!soundf) soundf=fopen("sound.pcm","wb"); + fwrite(buf16,(SOUNDBUFLEN)*2*2,1,soundf);*/ - if (!soundf) soundf=fopen("sound.pcm","wb"); - fwrite(buf16,(SOUNDBUFLEN)*2*2,1,soundf);*/ + if (soundon) + givealbuffer(outbuffer); - if (soundon) - givealbuffer(outbuffer); - - sound_pos_global = 0; - sound_update_buf_length(); - } + sound_pos_global = 0; + sound_update_buf_length(); + } } -void sound_speed_changed() { - sound_poll_latch = (uint64_t)((double)TIMER_USEC * (1000000.0 / 48000.0)); -} +void sound_speed_changed() { sound_poll_latch = (uint64_t)((double)TIMER_USEC * (1000000.0 / 48000.0)); } void sound_reset() { - timer_add(&sound_poll_timer, sound_poll, NULL, 1); + timer_add(&sound_poll_timer, sound_poll, NULL, 1); - sound_handlers_num = 0; + sound_handlers_num = 0; - sound_set_cd_volume(65535, 65535); - ioctl_audio_stop(); - image_audio_stop(); + sound_set_cd_volume(65535, 65535); + ioctl_audio_stop(); + image_audio_stop(); } void sound_init_builtin() { - pcem_add_sound(&sc_none); - pcem_add_sound(&sc_adlib); - pcem_add_sound(&sc_adlib_mca); - pcem_add_sound(&sc_sb); - pcem_add_sound(&sc_sb1_5); - pcem_add_sound(&sc_sbmcv); - pcem_add_sound(&sc_sb2_0); - pcem_add_sound(&sc_sbprov1); - pcem_add_sound(&sc_sbprov2); - pcem_add_sound(&sc_sbpromcv); - pcem_add_sound(&sc_sb16); - pcem_add_sound(&sc_sbawe32); - pcem_add_sound(&sc_adlibgold); - pcem_add_sound(&sc_wss); - pcem_add_sound(&sc_azt2316a); - pcem_add_sound(&sc_azt1605); - pcem_add_sound(&sc_pas16); - pcem_add_sound(&sc_es1371); - pcem_add_sound(&sc_sbpci128); + pcem_add_sound(&sc_none); + pcem_add_sound(&sc_adlib); + pcem_add_sound(&sc_adlib_mca); + pcem_add_sound(&sc_sb); + pcem_add_sound(&sc_sb1_5); + pcem_add_sound(&sc_sbmcv); + pcem_add_sound(&sc_sb2_0); + pcem_add_sound(&sc_sbprov1); + pcem_add_sound(&sc_sbprov2); + pcem_add_sound(&sc_sbpromcv); + pcem_add_sound(&sc_sb16); + pcem_add_sound(&sc_sbawe32); + pcem_add_sound(&sc_adlibgold); + pcem_add_sound(&sc_wss); + pcem_add_sound(&sc_azt2316a); + pcem_add_sound(&sc_azt1605); + pcem_add_sound(&sc_pas16); + pcem_add_sound(&sc_es1371); + pcem_add_sound(&sc_sbpci128); } diff --git a/src/sound/sound_ad1848.c b/src/sound/sound_ad1848.c index fa61d727..73497686 100644 --- a/src/sound/sound_ad1848.c +++ b/src/sound/sound_ad1848.c @@ -9,266 +9,281 @@ static int ad1848_vols_6bits[64]; static uint32_t ad1848_vols_5bits_aux_gain[32]; -void ad1848_setirq(ad1848_t *ad1848, int irq) { - ad1848->irq = irq; -} +void ad1848_setirq(ad1848_t *ad1848, int irq) { ad1848->irq = irq; } -void ad1848_setdma(ad1848_t *ad1848, int dma) { - ad1848->dma = dma; -} +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; + 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; - } -// if ((addr & 3) == 1 && (ad1848->index & 0x1f) > 0x0f) -// pclog("ad1848_read_EXTENDED - addr %04X %04X(%08X):%08X return %02X\n", addr, CS, cs, cpu_state.pc, temp); -// else -// pclog("ad1848_read - addr %04X %04X(%08X):%08X return %02X\n", addr, CS, cs, cpu_state.pc, temp); - return temp; + 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; + } + // if ((addr & 3) == 1 && (ad1848->index & 0x1f) > 0x0f) + // pclog("ad1848_read_EXTENDED - addr %04X %04X(%08X):%08X return %02X\n", addr, CS, cs, cpu_state.pc, + // temp); + // else + // pclog("ad1848_read - addr %04X %04X(%08X):%08X return %02X\n", addr, CS, cs, cpu_state.pc, temp); + return temp; } void ad1848_write(uint16_t addr, uint8_t val, void *p) { - ad1848_t *ad1848 = (ad1848_t *)p; - double freq; - uint32_t new_cd_vol_l, new_cd_vol_r; -// if ((addr & 3) == 0 && (val & 0x1f) > 0x0f) -// pclog("ad1848_write_EXTENDED - addr %04X val %02X %04X(%08X):%08X\n", addr, val, CS, cs, cpu_state.pc); -// else -// pclog("ad1848_write - addr %04X val %02X %04X(%08X):%08X\n", addr, val, CS, cs, cpu_state.pc); - switch (addr & 3) { - case 0: /*Index*/ - if (ad1848->regs[12] & 0x40 && ad1848->type == AD1848_TYPE_CS4231) - ad1848->index = val & 0x1f; // cs4231a extended mode enabled - else - ad1848->index = val & 0x0f; // ad1848/cs4248 mode TODO: some variants/clones DO NOT mirror, just ignore the writes? - ad1848->trd = val & 0x20; - ad1848->mce = val & 0x40; - break; - case 1: - switch (ad1848->index) { - case 8:freq = (val & 1) ? 16934400 : 24576000; - 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 = (uint64_t)((double)TIMER_USEC * (1000000.0 / (double)ad1848->freq)); - break; + ad1848_t *ad1848 = (ad1848_t *)p; + double freq; + uint32_t new_cd_vol_l, new_cd_vol_r; + // if ((addr & 3) == 0 && (val & 0x1f) > 0x0f) + // pclog("ad1848_write_EXTENDED - addr %04X val %02X %04X(%08X):%08X\n", addr, val, CS, cs, cpu_state.pc); + // else + // pclog("ad1848_write - addr %04X val %02X %04X(%08X):%08X\n", addr, val, CS, cs, cpu_state.pc); + switch (addr & 3) { + case 0: /*Index*/ + if (ad1848->regs[12] & 0x40 && ad1848->type == AD1848_TYPE_CS4231) + ad1848->index = val & 0x1f; // cs4231a extended mode enabled + else + ad1848->index = + val & + 0x0f; // ad1848/cs4248 mode TODO: some variants/clones DO NOT mirror, just ignore the writes? + ad1848->trd = val & 0x20; + ad1848->mce = val & 0x40; + break; + case 1: + switch (ad1848->index) { + case 8: + freq = (val & 1) ? 16934400 : 24576000; + 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 = (uint64_t)((double)TIMER_USEC * (1000000.0 / (double)ad1848->freq)); + break; - case 9: - if (!ad1848->enable && (val & 0x41) == 0x01) { - if (ad1848->timer_latch) - timer_set_delay_u64(&ad1848->timer, ad1848->timer_latch); - else - timer_set_delay_u64(&ad1848->timer, TIMER_USEC); - } - ad1848->enable = ((val & 0x41) == 0x01); - if (!ad1848->enable) { - timer_disable(&ad1848->timer); - ad1848->out_l = ad1848->out_r = 0; - } - break; + case 9: + if (!ad1848->enable && (val & 0x41) == 0x01) { + if (ad1848->timer_latch) + timer_set_delay_u64(&ad1848->timer, ad1848->timer_latch); + else + timer_set_delay_u64(&ad1848->timer, TIMER_USEC); + } + ad1848->enable = ((val & 0x41) == 0x01); + if (!ad1848->enable) { + timer_disable(&ad1848->timer); + ad1848->out_l = ad1848->out_r = 0; + } + break; - case 12:ad1848->regs[12] = ((ad1848->regs[12] & 0x0f) + (val & 0xf0)) | 0x80; - return; + case 12: + ad1848->regs[12] = ((ad1848->regs[12] & 0x0f) + (val & 0xf0)) | 0x80; + return; - case 14:ad1848->count = ad1848->regs[15] | (val << 8); - break; - // TODO: see which of the extended registers should be read only - } - ad1848->regs[ad1848->index] = val; + case 14: + ad1848->count = ad1848->regs[15] | (val << 8); + break; + // TODO: see which of the extended registers should be read only + } + ad1848->regs[ad1848->index] = val; - if (ad1848->type == AD1848_TYPE_CS4231) // TODO: configure CD volume for CS4248/AD1848 too - { - if (ad1848->regs[0x12] & 0x80) - new_cd_vol_l = 0; - else - new_cd_vol_l = ad1848_vols_5bits_aux_gain[ad1848->regs[0x12] & 0x1f]; - if (ad1848->regs[0x13] & 0x80) - new_cd_vol_r = 0; - else - new_cd_vol_r = ad1848_vols_5bits_aux_gain[ad1848->regs[0x13] & 0x1f]; + if (ad1848->type == AD1848_TYPE_CS4231) // TODO: configure CD volume for CS4248/AD1848 too + { + if (ad1848->regs[0x12] & 0x80) + new_cd_vol_l = 0; + else + new_cd_vol_l = ad1848_vols_5bits_aux_gain[ad1848->regs[0x12] & 0x1f]; + if (ad1848->regs[0x13] & 0x80) + new_cd_vol_r = 0; + else + new_cd_vol_r = ad1848_vols_5bits_aux_gain[ad1848->regs[0x13] & 0x1f]; - // Apparently there is no master volume to modulate here - // (The windows mixer just adjusts all registers at the same - // time when the master slider is adjusted) - sound_set_cd_volume(new_cd_vol_l, new_cd_vol_r); - } + // Apparently there is no master volume to modulate here + // (The windows mixer just adjusts all registers at the same + // time when the master slider is adjusted) + sound_set_cd_volume(new_cd_vol_l, new_cd_vol_r); + } - break; - case 2:ad1848->status &= 0xfe; - break; - } + break; + case 2: + ad1848->status &= 0xfe; + break; + } } void ad1848_speed_changed(ad1848_t *ad1848) { - ad1848->timer_latch = (uint64_t)((double)TIMER_USEC * (1000000.0 / (double)ad1848->freq)); + ad1848->timer_latch = (uint64_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; - } + 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; + ad1848_t *ad1848 = (ad1848_t *)p; - if (ad1848->timer_latch) - timer_advance_u64(&ad1848->timer, ad1848->timer_latch); - else - timer_advance_u64(&ad1848->timer, TIMER_USEC * 1000); + if (ad1848->timer_latch) + timer_advance_u64(&ad1848->timer, ad1848->timer_latch); + else + timer_advance_u64(&ad1848->timer, TIMER_USEC * 1000); - ad1848_update(ad1848); - // TODO: line in, mic, etc... - if (ad1848->enable) { - int32_t temp; + ad1848_update(ad1848); + // TODO: line in, mic, etc... + 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; + 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; - } + 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_6bits[ad1848->regs[6] & 0x3f]) >> 16; + if (ad1848->regs[6] & 0x80) + ad1848->out_l = 0; + else + ad1848->out_l = (ad1848->out_l * ad1848_vols_6bits[ad1848->regs[6] & 0x3f]) >> 16; - if (ad1848->regs[7] & 0x80) - ad1848->out_r = 0; - else - ad1848->out_r = (ad1848->out_r * ad1848_vols_6bits[ad1848->regs[7] & 0x3f]) >> 16; + if (ad1848->regs[7] & 0x80) + ad1848->out_r = 0; + else + ad1848->out_r = (ad1848->out_r * ad1848_vols_6bits[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); - } - } + 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--; -// pclog("ad1848_poll : enable %X %X %X %X %X %X\n", ad1848->pcm_buffer[0][ad1848->pos], ad1848->pcm_buffer[1][ad1848->pos], ad1848->out_l[0], ad1848->out_r[0], ad1848->out_l[1], ad1848->out_r[1]); - } else { - ad1848->out_l = ad1848->out_r = 0; - sound_set_cd_volume(0, 0); -// pclog("ad1848_poll : not enable\n"); - } + ad1848->count--; + // pclog("ad1848_poll : enable %X %X %X %X %X %X\n", ad1848->pcm_buffer[0][ad1848->pos], + // ad1848->pcm_buffer[1][ad1848->pos], ad1848->out_l[0], ad1848->out_r[0], ad1848->out_l[1], + // ad1848->out_r[1]); + } else { + ad1848->out_l = ad1848->out_r = 0; + sound_set_cd_volume(0, 0); + // pclog("ad1848_poll : not enable\n"); + } } void ad1848_init(ad1848_t *ad1848, int type) { - int c; - double attenuation; + int c; + double attenuation; - ad1848->type = type; - ad1848->enable = 0; + ad1848->type = type; + ad1848->enable = 0; - ad1848->status = 0xcc; - ad1848->index = ad1848->trd = 0; - ad1848->mce = 0x40; + 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; // AZT2316A Line-in - ad1848->regs[4] = ad1848->regs[5] = 0x80; - ad1848->regs[6] = ad1848->regs[7] = 0x80; // AZT2316A Master? - ad1848->regs[8] = 0; - ad1848->regs[9] = 0x08; - ad1848->regs[10] = ad1848->regs[11] = 0; - if (ad1848->type == AD1848_TYPE_CS4248 || ad1848->type == AD1848_TYPE_CS4231) - ad1848->regs[12] = 0x8a; - else - ad1848->regs[12] = 0xa; - ad1848->regs[13] = 0; - ad1848->regs[14] = ad1848->regs[15] = 0; + ad1848->regs[0] = ad1848->regs[1] = 0; + ad1848->regs[2] = ad1848->regs[3] = 0x80; // AZT2316A Line-in + ad1848->regs[4] = ad1848->regs[5] = 0x80; + ad1848->regs[6] = ad1848->regs[7] = 0x80; // AZT2316A Master? + ad1848->regs[8] = 0; + ad1848->regs[9] = 0x08; + ad1848->regs[10] = ad1848->regs[11] = 0; + if (ad1848->type == AD1848_TYPE_CS4248 || ad1848->type == AD1848_TYPE_CS4231) + ad1848->regs[12] = 0x8a; + else + ad1848->regs[12] = 0xa; + ad1848->regs[13] = 0; + ad1848->regs[14] = ad1848->regs[15] = 0; - if (ad1848->type == AD1848_TYPE_CS4231) { - ad1848->regs[0x12] = ad1848->regs[0x13] = 0x80; // AZT2316A CD - ad1848->regs[0x1A] = 0x80; // AZT2316A Mic - } + if (ad1848->type == AD1848_TYPE_CS4231) { + ad1848->regs[0x12] = ad1848->regs[0x13] = 0x80; // AZT2316A CD + ad1848->regs[0x1A] = 0x80; // AZT2316A Mic + } - ad1848->out_l = 0; - ad1848->out_r = 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; + 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); + attenuation = pow(10, attenuation / 10); - ad1848_vols_6bits[c] = (int)(attenuation * 65536); -// pclog("ad1848_vols_6bits %i = %f %i\n", c, attenuation, ad1848_vols_6bits[c]); - } - for (c = 0; c < 32; c++) { - attenuation = 12.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; + ad1848_vols_6bits[c] = (int)(attenuation * 65536); + // pclog("ad1848_vols_6bits %i = %f %i\n", c, attenuation, ad1848_vols_6bits[c]); + } + for (c = 0; c < 32; c++) { + attenuation = 12.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; - attenuation = pow(10, attenuation / 10); + attenuation = pow(10, attenuation / 10); - ad1848_vols_5bits_aux_gain[c] = (int)(attenuation * 65536); -// pclog("ad1848_vols_5bits_aux_gain %i = %f %i\n", c, attenuation, ad1848_vols_5bits_aux_gain[c]); - } + ad1848_vols_5bits_aux_gain[c] = (int)(attenuation * 65536); + // pclog("ad1848_vols_5bits_aux_gain %i = %f %i\n", c, attenuation, ad1848_vols_5bits_aux_gain[c]); + } - timer_add(&ad1848->timer, ad1848_poll, ad1848, 0); + timer_add(&ad1848->timer, ad1848_poll, ad1848, 0); } diff --git a/src/sound/sound_adlib.c b/src/sound/sound_adlib.c index 7aec9690..1b695ffb 100644 --- a/src/sound/sound_adlib.c +++ b/src/sound/sound_adlib.c @@ -9,99 +9,79 @@ #include "sound_opl.h" typedef struct adlib_t { - opl_t opl; + opl_t opl; - uint8_t pos_regs[8]; + 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; + adlib_t *adlib = (adlib_t *)p; + int c; - opl2_update2(&adlib->opl); + opl2_update2(&adlib->opl); - for (c = 0; c < len * 2; c++) - buffer[c] += (int32_t)adlib->opl.buffer[c]; + for (c = 0; c < len * 2; c++) + buffer[c] += (int32_t)adlib->opl.buffer[c]; - adlib->opl.pos = 0; + adlib->opl.pos = 0; } uint8_t adlib_mca_read(int port, void *p) { - adlib_t *adlib = (adlib_t *)p; + adlib_t *adlib = (adlib_t *)p; - pclog("adlib_mca_read: port=%04x\n", port); + pclog("adlib_mca_read: port=%04x\n", port); - return adlib->pos_regs[port & 7]; + return adlib->pos_regs[port & 7]; } void adlib_mca_write(int port, uint8_t val, void *p) { - adlib_t *adlib = (adlib_t *)p; + adlib_t *adlib = (adlib_t *)p; - if (port < 0x102) - return; + if (port < 0x102) + return; - pclog("adlib_mca_write: port=%04x val=%02x\n", port, val); + pclog("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; + 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() { - adlib_t *adlib = malloc(sizeof(adlib_t)); - memset(adlib, 0, sizeof(adlib_t)); + adlib_t *adlib = malloc(sizeof(adlib_t)); + memset(adlib, 0, sizeof(adlib_t)); - pclog("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); + pclog("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; + return adlib; } void *adlib_mca_init() { - adlib_t *adlib = adlib_init(); + adlib_t *adlib = adlib_init(); - io_removehandler(0x0388, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &adlib->opl); - mca_add(adlib_mca_read, adlib_mca_write, NULL, adlib); - adlib->pos_regs[0] = 0xd7; - adlib->pos_regs[1] = 0x70; + io_removehandler(0x0388, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &adlib->opl); + mca_add(adlib_mca_read, adlib_mca_write, NULL, adlib); + adlib->pos_regs[0] = 0xd7; + adlib->pos_regs[1] = 0x70; - return adlib; + return adlib; } void adlib_close(void *p) { - adlib_t *adlib = (adlib_t *)p; + adlib_t *adlib = (adlib_t *)p; - free(adlib); + free(adlib); } -device_t adlib_device = - { - "AdLib", - 0, - adlib_init, - adlib_close, - NULL, - NULL, - NULL, - NULL - }; +device_t adlib_device = {"AdLib", 0, adlib_init, adlib_close, NULL, NULL, NULL, NULL}; -device_t adlib_mca_device = - { - "AdLib (MCA)", - DEVICE_MCA, - adlib_init, - adlib_close, - NULL, - NULL, - NULL, - NULL - }; +device_t adlib_mca_device = {"AdLib (MCA)", DEVICE_MCA, adlib_init, adlib_close, NULL, NULL, NULL, NULL}; diff --git a/src/sound/sound_adlibgold.c b/src/sound/sound_adlibgold.c index 5461de4a..8d27eadf 100644 --- a/src/sound/sound_adlibgold.c +++ b/src/sound/sound_adlibgold.c @@ -16,802 +16,804 @@ #include "filters.h" typedef struct adgold_t { - int adgold_irq_status; + int adgold_irq_status; - uint8_t adgold_eeprom[0x19]; + uint8_t adgold_eeprom[0x19]; - uint8_t adgold_status; - int adgold_38x_state, adgold_38x_addr; - uint8_t adgold_38x_regs[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_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; + 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]; + int16_t adgold_mma_out[2]; + int adgold_mma_intpos[2]; - pc_timer_t adgold_mma_timer; + pc_timer_t adgold_mma_timer; - struct { - int timer0_latch, timer0_count; - int timerbase_latch, timerbase_count; - int timer1_latch, timer1_count; - int timer2_latch, timer2_count, timer2_read; + 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; + int voice_count[2], voice_latch[2]; + } adgold_mma; - opl_t opl; - ym7128_t ym7128; + 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; + 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[MAXSOUNDBUFLEN * 2]; - int16_t mma_buffer[2][MAXSOUNDBUFLEN]; + int16_t opl_buffer[MAXSOUNDBUFLEN * 2]; + int16_t mma_buffer[2][MAXSOUNDBUFLEN]; - int pos; + int pos; - int surround_enabled; + 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_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 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_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*/ - }; +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; + 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_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_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) { -// pclog("adgold irq %02X\n", adgold->adgold_status); - picint(0x80); - } + if ((adgold->adgold_status ^ 0xf) && !adgold->adgold_irq_status) { + // pclog("adgold irq %02X\n", adgold->adgold_status); + picint(0x80); + } - adgold->adgold_irq_status = adgold->adgold_status ^ 0xf; + adgold->adgold_irq_status = adgold->adgold_status ^ 0xf; } void adgold_getsamp_dma(adgold_t *adgold, int channel) { - int temp; + 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; + 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); -// pclog("adgold DMA1 return %02X %i L\n", temp, channel); - 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); -// pclog("adgold DMA1 return %02X %i H\n", temp, channel); - 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); - } + temp = dma_channel_read(1); + // pclog("adgold DMA1 return %02X %i L\n", temp, channel); + 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); + // pclog("adgold DMA1 return %02X %i H\n", temp, channel); + 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; -// if (addr > 0x389) pclog("adgold_write : addr %04X val %02X %04X:%04X\n", addr, val, CS, pc); - switch (addr & 7) { - case 0: - case 1:opl3_write(addr, val, &adgold->opl); - break; + adgold_t *adgold = (adgold_t *)p; + // if (addr > 0x389) pclog("adgold_write : addr %04X val %02X %04X:%04X\n", addr, val, CS, pc); + 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 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 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 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; + 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; + 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; + 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 & 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 & 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; + 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]; + 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]; -// pclog("adgold start! FIFO fill %i %i %i %02X\n", (adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255, adgold->adgold_mma_fifo_end[0], adgold->adgold_mma_fifo_start[0], adgold->adgold_mma_regs[0][0xc]); - if (adgold->adgold_mma_regs[0][0xc] & 1) { - if (adgold->adgold_mma_regs[0][0xc] & 0x80) { -// pclog("adgold start interleaved %i %i - adgold->adgold_mma_enable[1] = 1; - adgold->adgold_mma.voice_count[1] = adgold->adgold_mma.voice_latch[1]; + // pclog("adgold start! FIFO fill %i %i %i %02X\n", + // (adgold->adgold_mma_fifo_end[0] - + // adgold->adgold_mma_fifo_start[0]) & 255, + // adgold->adgold_mma_fifo_end[0], + // adgold->adgold_mma_fifo_start[0], + // adgold->adgold_mma_regs[0][0xc]); + if (adgold->adgold_mma_regs[0][0xc] & 1) { + if (adgold->adgold_mma_regs[0][0xc] & 0x80) { + // pclog("adgold start interleaved + // %i %i + 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); - } - } - } -// pclog("adgold end\n"); - } - adgold->adgold_mma_enable[0] = val & 0x01; - break; + 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); + } + } + } + // pclog("adgold end\n"); + } + 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 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]; + 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]; -// pclog("adgold start! FIFO fill %i %i %i %02X\n", (adgold->adgold_mma_fifo_end[1] - adgold->adgold_mma_fifo_start[1]) & 255, adgold->adgold_mma_fifo_end[1], adgold->adgold_mma_fifo_start[1], adgold->adgold_mma_regs[1][0xc]); - 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); - } - } -// pclog("adgold end\n"); - } - adgold->adgold_mma_enable[1] = val & 0x01; - break; + // pclog("adgold start! FIFO fill %i %i %i %02X\n", + // (adgold->adgold_mma_fifo_end[1] - + // adgold->adgold_mma_fifo_start[1]) & 255, + // adgold->adgold_mma_fifo_end[1], + // adgold->adgold_mma_fifo_start[1], + // adgold->adgold_mma_regs[1][0xc]); + 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); + } + } + // pclog("adgold end\n"); + } + 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 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; - } + 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; + adgold_t *adgold = (adgold_t *)p; + uint8_t temp; - switch (addr & 7) { - case 0: - case 1:temp = opl3_read(addr, &adgold->opl); - break; + 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 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; + 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; + 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; + 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; - } -// if (addr > 0x389) pclog("adgold_read : addr %04X %02X\n", addr, temp); - return temp; + 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; + } + // if (addr > 0x389) pclog("adgold_read : addr %04X %02X\n", addr, temp); + 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; + 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[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; - } + 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; + int16_t dat; - adgold_update(adgold); + 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; + 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; + 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; - } + 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)) { -// pclog("adgold_mma_poll - IRQ! %i\n", channel); - 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; - } + 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)) { + // pclog("adgold_mma_poll - IRQ! %i\n", channel); + 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; + adgold_t *adgold = (adgold_t *)p; - timer_advance_u64(&adgold->adgold_mma_timer, (uint64_t)((double)TIMER_USEC * 1.88964)); -// while (adgold->adgold_mma_timer_count <= 0) -// { -// adgold->adgold_mma_timer_count += (int)((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; -// pclog("Timer 0 interrupt\n"); - 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; -// pclog("Timer 1 interrupt\n"); - 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; -// pclog("Timer 2 interrupt\n"); - adgold->adgold_mma_status |= 0x40; - adgold_update_irq_status(adgold); - } - } - } - } + timer_advance_u64(&adgold->adgold_mma_timer, (uint64_t)((double)TIMER_USEC * 1.88964)); + // while (adgold->adgold_mma_timer_count <= 0) + // { + // adgold->adgold_mma_timer_count += (int)((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; + // pclog("Timer 0 interrupt\n"); + 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; + // pclog("Timer 1 interrupt\n"); + 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; + // pclog("Timer 2 interrupt\n"); + 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); - } - } -// } + 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]; + adgold_t *adgold = (adgold_t *)p; + int16_t adgold_buffer[len * 2]; - int c; + int c; - opl3_update2(&adgold->opl); - adgold_update(adgold); + 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; - } + 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); + 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] & 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]; + 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; - } + 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; + 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; + /*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; - } + 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; + adgold->opl.pos = 0; + adgold->pos = 0; } void *adgold_init() { - FILE *f; - int c; - double out; - int opl_emu; - adgold_t *adgold = malloc(sizeof(adgold_t)); - memset(adgold, 0, sizeof(adgold_t)); + FILE *f; + int c; + double out; + int opl_emu; + adgold_t *adgold = malloc(sizeof(adgold_t)); + memset(adgold, 0, sizeof(adgold_t)); - adgold->surround_enabled = device_get_config_int("surround"); - opl_emu = device_get_config_int("opl_emu"); + adgold->surround_enabled = device_get_config_int("surround"); + opl_emu = device_get_config_int("opl_emu"); - opl3_init(&adgold->opl, opl_emu); - if (adgold->surround_enabled) - ym7128_init(&adgold->ym7128); + opl3_init(&adgold->opl, opl_emu); + 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; + 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 = nvrfopen("adgold.bin", "rb"); - if (f) { - fread(adgold->adgold_eeprom, 0x18, 1, f); - fclose(f); - } + f = nvrfopen("adgold.bin", "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_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; + 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); + /*388/389 are handled by adlib_init*/ + io_sethandler(0x0388, 0x0008, adgold_read, NULL, NULL, adgold_write, NULL, NULL, adgold); - timer_add(&adgold->adgold_mma_timer, adgold_timer_poll, adgold, 1); + timer_add(&adgold->adgold_mma_timer, adgold_timer_poll, adgold, 1); - sound_add_handler(adgold_get_buffer, adgold); + sound_add_handler(adgold_get_buffer, adgold); - return adgold; + return adgold; } void adgold_close(void *p) { - FILE *f; - adgold_t *adgold = (adgold_t *)p; + FILE *f; + adgold_t *adgold = (adgold_t *)p; - f = nvrfopen("adgold.bin", "wb"); - if (f) { - fwrite(adgold->adgold_eeprom, 0x18, 1, f); - fclose(f); - } + f = nvrfopen("adgold.bin", "wb"); + if (f) { + fwrite(adgold->adgold_eeprom, 0x18, 1, f); + fclose(f); + } - free(adgold); + free(adgold); } -static device_config_t adgold_config[] = - { - { - .name = "surround", - .description = "Surround module", - .type = CONFIG_BINARY, - .default_int = 1 - }, - { - .name = "opl_emu", - .description = "OPL emulator", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "DBOPL", - .value = OPL_DBOPL - }, - { - .description = "NukedOPL", - .value = OPL_NUKED - }, - }, - .default_int = OPL_DBOPL - }, - { - .type = -1 - } - }; +static device_config_t adgold_config[] = { + {.name = "surround", .description = "Surround module", .type = CONFIG_BINARY, .default_int = 1}, + {.name = "opl_emu", + .description = "OPL emulator", + .type = CONFIG_SELECTION, + .selection = + { + {.description = "DBOPL", .value = OPL_DBOPL}, + {.description = "NukedOPL", .value = OPL_NUKED}, + }, + .default_int = OPL_DBOPL}, + {.type = -1}}; -device_t adgold_device = - { - "AdLib Gold", - 0, - adgold_init, - adgold_close, - NULL, - NULL, - NULL, - NULL, - adgold_config - }; +device_t adgold_device = {"AdLib Gold", 0, adgold_init, adgold_close, NULL, NULL, NULL, NULL, adgold_config}; diff --git a/src/sound/sound_audiopci.c b/src/sound/sound_audiopci.c index 67535de3..f6fcf820 100644 --- a/src/sound/sound_audiopci.c +++ b/src/sound/sound_audiopci.c @@ -15,94 +15,94 @@ static float low_fir_es1371_coef[ES1371_NCoef]; typedef struct es1371_t { - uint8_t pci_command, pci_serr; + uint8_t pci_command, pci_serr; - uint32_t base_addr; + uint32_t base_addr; - uint8_t int_line; + uint8_t int_line; - uint16_t pmcsr; + uint16_t pmcsr; - uint32_t int_ctrl; - uint32_t int_status; + uint32_t int_ctrl; + uint32_t int_status; - uint32_t legacy_ctrl; + uint32_t legacy_ctrl; - int mem_page; + int mem_page; - uint32_t si_cr; + uint32_t si_cr; - uint32_t sr_cir; - uint16_t sr_ram[128]; + uint32_t sr_cir; + uint16_t sr_ram[128]; - uint8_t uart_ctrl; - uint8_t uart_status; + uint8_t uart_ctrl; + uint8_t uart_status; - uint16_t codec_regs[64]; - uint32_t codec_ctrl; + uint16_t codec_regs[64]; + uint32_t codec_ctrl; - struct { - uint32_t addr, addr_latch; - uint16_t count, size; + struct { + uint32_t addr, addr_latch; + uint16_t count, size; - uint16_t samp_ct; - int curr_samp_ct; + uint16_t samp_ct; + int curr_samp_ct; - pc_timer_t timer; - uint64_t latch; + pc_timer_t timer; + uint64_t latch; - uint32_t vf, ac; + uint32_t vf, ac; - int16_t buffer_l[64], buffer_r[64]; - int buffer_pos, buffer_pos_end; + int16_t buffer_l[64], buffer_r[64]; + int buffer_pos, buffer_pos_end; - int filtered_l[32], filtered_r[32]; - int f_pos; + int filtered_l[32], filtered_r[32]; + int f_pos; - int16_t out_l, out_r; + int16_t out_l, out_r; - int32_t vol_l, vol_r; - } dac[2], adc; + int32_t vol_l, vol_r; + } dac[2], adc; - int dac_latch, dac_time; + int dac_latch, dac_time; - int master_vol_l, master_vol_r; + int master_vol_l, master_vol_r; - int card; + int card; - int pos; - int16_t buffer[MAXSOUNDBUFLEN * 2]; + int pos; + int16_t buffer[MAXSOUNDBUFLEN * 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_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_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_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_EVENT_TYPE_RW (1 << 2) #define LEGACY_INT (1 << 0) #define SRC_RAM_WE (1 << 24) -#define CODEC_READ (1 << 23) +#define CODEC_READ (1 << 23) #define CODEC_READY (1 << 31) #define INT_DAC1_EN (1 << 6) @@ -115,1041 +115,1178 @@ typedef struct es1371_t { #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_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 - }; +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, uint32_t old_legacy_ctrl); static void es1371_update_irqs(es1371_t *es1371) { - int irq = 0; + 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 ((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 (irq) + es1371->int_status |= INT_STATUS_INTR; + else + es1371->int_status &= ~INT_STATUS_INTR; - if (es1371->legacy_ctrl & LEGACY_FORCE_IRQ) - irq = 1; + if (es1371->legacy_ctrl & LEGACY_FORCE_IRQ) + irq = 1; - if (irq) { - pci_set_irq(es1371->card, PCI_INTA); -// pclog("Raise IRQ\n"); - } else { - pci_clear_irq(es1371->card, PCI_INTA); -// pclog("Drop IRQ\n"); - } + if (irq) { + pci_set_irq(es1371->card, PCI_INTA); + // pclog("Raise IRQ\n"); + } else { + pci_clear_irq(es1371->card, PCI_INTA); + // pclog("Drop IRQ\n"); + } } static uint8_t es1371_inb(uint16_t port, void *p) { - es1371_t *es1371 = (es1371_t *)p; - uint8_t ret = 0; + 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; + 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 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 0x09: + ret = es1371->uart_status; + break; - case 0x0c:ret = es1371->mem_page; - 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 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; + 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:pclog("Bad es1371_inb: port=%04x\n", port); - } + default: + pclog("Bad es1371_inb: port=%04x\n", port); + } -// pclog("es1371_inb: port=%04x ret=%02x\n", port, ret); -// output = 3; - return ret; + // pclog("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; + 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; + 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; -// pclog("Read legacy ctrl %04x\n", ret); - break; + case 0x18: + ret = es1371->legacy_ctrl & 0xffff; + // pclog("Read legacy ctrl %04x\n", ret); + break; - case 0x26:ret = es1371->dac[0].curr_samp_ct; - break; + case 0x26: + ret = es1371->dac[0].curr_samp_ct; + break; - case 0x2a:ret = es1371->dac[1].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; + case 0x36: + switch (es1371->mem_page) { + case 0xc: + ret = es1371->dac[0].count; + break; - default:pclog("Bad es1371_inw: mem_page=%x port=%04x\n", es1371->mem_page, port); - } - break; + default: + pclog("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; + case 0x3e: + switch (es1371->mem_page) { + case 0xc: + ret = es1371->dac[1].count; + break; - default:pclog("Bad es1371_inw: mem_page=%x port=%04x\n", es1371->mem_page, port); - } - break; + default: + pclog("Bad es1371_inw: mem_page=%x port=%04x\n", es1371->mem_page, port); + } + break; - default:pclog("Bad es1371_inw: port=%04x\n", port); - } + default: + pclog("Bad es1371_inw: port=%04x\n", port); + } -// pclog("es1371_inw: port=%04x ret=%04x %04x:%08x\n", port, ret, CS,cpu_state.pc); - return ret; + // pclog("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; + 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; + 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 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 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 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; + case 0xd: + ret = es1371->adc.size | (es1371->adc.count << 16); + break; - default:pclog("Bad es1371_inl: mem_page=%x port=%04x\n", es1371->mem_page, port); - } - break; + default: + pclog("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; + case 0x3c: + switch (es1371->mem_page) { + case 0xc: + ret = es1371->dac[1].size | (es1371->dac[1].count << 16); + break; - default:pclog("Bad es1371_inl: mem_page=%x port=%04x\n", es1371->mem_page, port); - } - break; + default: + pclog("Bad es1371_inl: mem_page=%x port=%04x\n", es1371->mem_page, port); + } + break; - default:pclog("Bad es1371_inl: port=%04x\n", port); - } + default: + pclog("Bad es1371_inl: port=%04x\n", port); + } -// pclog("es1371_inl: port=%04x ret=%08x %08x\n", port, ret, cpu_state.pc); - return ret; + // pclog("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; - uint32_t old_legacy_ctrl; + es1371_t *es1371 = (es1371_t *)p; + uint32_t old_legacy_ctrl; -// pclog("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; + // pclog("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 0x09: + es1371->uart_ctrl = val; + break; - case 0x0c:es1371->mem_page = val & 0xf; - break; + case 0x0c: + es1371->mem_page = val & 0xf; + break; - case 0x18:es1371->legacy_ctrl |= LEGACY_INT; - nmi = 0; - break; - case 0x1a:old_legacy_ctrl = es1371->legacy_ctrl; - es1371->legacy_ctrl = (es1371->legacy_ctrl & 0xff00ffff) | (val << 16); - update_legacy(es1371, old_legacy_ctrl); - break; - case 0x1b:old_legacy_ctrl = es1371->legacy_ctrl; - es1371->legacy_ctrl = (es1371->legacy_ctrl & 0x00ffffff) | (val << 24); - es1371_update_irqs(es1371); -// output = 3; - update_legacy(es1371, old_legacy_ctrl); - break; + case 0x18: + es1371->legacy_ctrl |= LEGACY_INT; + nmi = 0; + break; + case 0x1a: + old_legacy_ctrl = es1371->legacy_ctrl; + es1371->legacy_ctrl = (es1371->legacy_ctrl & 0xff00ffff) | (val << 16); + update_legacy(es1371, old_legacy_ctrl); + break; + case 0x1b: + old_legacy_ctrl = es1371->legacy_ctrl; + es1371->legacy_ctrl = (es1371->legacy_ctrl & 0x00ffffff) | (val << 24); + es1371_update_irqs(es1371); + // output = 3; + update_legacy(es1371, old_legacy_ctrl); + 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; + 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:pclog("Bad es1371_outb: port=%04x val=%02x\n", port, val); - } + default: + pclog("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; + es1371_t *es1371 = (es1371_t *)p; -// pclog("es1371_outw: port=%04x val=%04x\n", port, val); - switch (port & 0x3f) { - case 0x0c:es1371->mem_page = val & 0xf; - break; + // pclog("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 0x24: + es1371->dac[0].samp_ct = val; + break; - case 0x28:es1371->dac[1].samp_ct = val; - break; + case 0x28: + es1371->dac[1].samp_ct = val; + break; - default:pclog("Bad es1371_outw: port=%04x val=%04x\n", port, val); - } + default: + pclog("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; + es1371_t *es1371 = (es1371_t *)p; -// pclog("es1371_outl: port=%04x val=%08x %04x:%08x\n", port, val, CS, cpu_state.pc); - switch (port & 0x3f) { - case 0x04:break; + // pclog("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 0x0c: + es1371->mem_page = val & 0xf; + break; - case 0x10:es1371->sr_cir = val; - if (es1371->sr_cir & SRC_RAM_WE) { -// pclog("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 0x10: + es1371->sr_cir = val; + if (es1371->sr_cir & SRC_RAM_WE) { + // pclog("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 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 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)) { -// pclog("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 0x14: + es1371->codec_ctrl = val; + if (!(val & CODEC_READ)) { + // pclog("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 0x24: + es1371->dac[0].samp_ct = val & 0xffff; + break; - case 0x28:es1371->dac[1].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 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; -// pclog("DAC1 addr %08x\n", val); - break; + case 0xc: + es1371->dac[0].addr_latch = val; + // pclog("DAC1 addr %08x\n", val); + break; - default:pclog("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; + default: + pclog("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; - break; + case 0xc: + es1371->dac[0].size = val & 0xffff; + es1371->dac[0].count = val >> 16; + break; - case 0xd:es1371->adc.size = val & 0xffff; - es1371->adc.count = val >> 16; - break; + case 0xd: + es1371->adc.size = val & 0xffff; + es1371->adc.count = val >> 16; + break; - default:pclog("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; + default: + pclog("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 0xc: + es1371->dac[1].addr_latch = val; + break; - case 0xd:break; + case 0xd: + break; - default:pclog("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; + default: + pclog("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; + case 0xc: + es1371->dac[1].size = val & 0xffff; + es1371->dac[1].count = val >> 16; + break; - default:pclog("Bad es1371_outl: mem_page=%x port=%04x val=%08x\n", es1371->mem_page, port, val); - } - break; + default: + pclog("Bad es1371_outl: mem_page=%x port=%04x val=%08x\n", es1371->mem_page, port, val); + } + break; - default:pclog("Bad es1371_outl: port=%04x val=%08x\n", port, val); - } + default: + pclog("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; -// pclog("Event! %s %04x\n", rw ? "write" : "read", 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; + // pclog("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 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + capture_event(p, LEGACY_EVENT_SLAVE_DMA, 0, port); + return 0xff; } static void update_legacy(es1371_t *es1371, uint32_t old_legacy_ctrl) { - if (old_legacy_ctrl & LEGACY_CAPTURE_SSCAPE) { - switch ((old_legacy_ctrl >> LEGACY_SSCAPE_ADDR_SHIFT) & 3) { - case 0:io_removehandler(0x0320, 0x0008, capture_read_sscape, NULL, NULL, capture_write_sscape, NULL, NULL, es1371); - break; - case 1:io_removehandler(0x0330, 0x0008, capture_read_sscape, NULL, NULL, capture_write_sscape, NULL, NULL, es1371); - break; - case 2:io_removehandler(0x0340, 0x0008, capture_read_sscape, NULL, NULL, capture_write_sscape, NULL, NULL, es1371); - break; - case 3:io_removehandler(0x0350, 0x0008, capture_read_sscape, NULL, NULL, capture_write_sscape, NULL, NULL, es1371); - break; - } - } - if (old_legacy_ctrl & LEGACY_CAPTURE_CODEC) { - switch ((old_legacy_ctrl >> LEGACY_CODEC_ADDR_SHIFT) & 3) { - case 0:io_removehandler(0x5300, 0x0080, capture_read_codec, NULL, NULL, capture_write_codec, NULL, NULL, es1371); - break; - case 2:io_removehandler(0xe800, 0x0080, capture_read_codec, NULL, NULL, capture_write_codec, NULL, NULL, es1371); - break; - case 3:io_removehandler(0xf400, 0x0080, capture_read_codec, NULL, NULL, capture_write_codec, NULL, NULL, es1371); - break; - } - } - if (old_legacy_ctrl & LEGACY_CAPTURE_SB) { - if (!(old_legacy_ctrl & LEGACY_SB_ADDR)) - io_removehandler(0x0220, 0x0010, capture_read_sb, NULL, NULL, capture_write_sb, NULL, NULL, es1371); - else - io_removehandler(0x0240, 0x0010, capture_read_sb, NULL, NULL, capture_write_sb, NULL, NULL, es1371); - } - if (old_legacy_ctrl & LEGACY_CAPTURE_ADLIB) - io_removehandler(0x0388, 0x0004, capture_read_adlib, NULL, NULL, capture_write_adlib, NULL, NULL, es1371); - if (old_legacy_ctrl & LEGACY_CAPTURE_MASTER_PIC) - io_removehandler(0x0020, 0x0002, capture_read_master_pic, NULL, NULL, capture_write_master_pic, NULL, NULL, es1371); - if (old_legacy_ctrl & LEGACY_CAPTURE_MASTER_DMA) - io_removehandler(0x0000, 0x0010, capture_read_master_dma, NULL, NULL, capture_write_master_dma, NULL, NULL, es1371); - if (old_legacy_ctrl & LEGACY_CAPTURE_SLAVE_PIC) - io_removehandler(0x00a0, 0x0002, capture_read_slave_pic, NULL, NULL, capture_write_slave_pic, NULL, NULL, es1371); - if (old_legacy_ctrl & LEGACY_CAPTURE_SLAVE_DMA) - io_removehandler(0x00c0, 0x0020, capture_read_slave_dma, NULL, NULL, capture_write_slave_dma, NULL, NULL, es1371); + if (old_legacy_ctrl & LEGACY_CAPTURE_SSCAPE) { + switch ((old_legacy_ctrl >> LEGACY_SSCAPE_ADDR_SHIFT) & 3) { + case 0: + io_removehandler(0x0320, 0x0008, capture_read_sscape, NULL, NULL, capture_write_sscape, NULL, NULL, + es1371); + break; + case 1: + io_removehandler(0x0330, 0x0008, capture_read_sscape, NULL, NULL, capture_write_sscape, NULL, NULL, + es1371); + break; + case 2: + io_removehandler(0x0340, 0x0008, capture_read_sscape, NULL, NULL, capture_write_sscape, NULL, NULL, + es1371); + break; + case 3: + io_removehandler(0x0350, 0x0008, capture_read_sscape, NULL, NULL, capture_write_sscape, NULL, NULL, + es1371); + break; + } + } + if (old_legacy_ctrl & LEGACY_CAPTURE_CODEC) { + switch ((old_legacy_ctrl >> LEGACY_CODEC_ADDR_SHIFT) & 3) { + case 0: + io_removehandler(0x5300, 0x0080, capture_read_codec, NULL, NULL, capture_write_codec, NULL, NULL, es1371); + break; + case 2: + io_removehandler(0xe800, 0x0080, capture_read_codec, NULL, NULL, capture_write_codec, NULL, NULL, es1371); + break; + case 3: + io_removehandler(0xf400, 0x0080, capture_read_codec, NULL, NULL, capture_write_codec, NULL, NULL, es1371); + break; + } + } + if (old_legacy_ctrl & LEGACY_CAPTURE_SB) { + if (!(old_legacy_ctrl & LEGACY_SB_ADDR)) + io_removehandler(0x0220, 0x0010, capture_read_sb, NULL, NULL, capture_write_sb, NULL, NULL, es1371); + else + io_removehandler(0x0240, 0x0010, capture_read_sb, NULL, NULL, capture_write_sb, NULL, NULL, es1371); + } + if (old_legacy_ctrl & LEGACY_CAPTURE_ADLIB) + io_removehandler(0x0388, 0x0004, capture_read_adlib, NULL, NULL, capture_write_adlib, NULL, NULL, es1371); + if (old_legacy_ctrl & LEGACY_CAPTURE_MASTER_PIC) + io_removehandler(0x0020, 0x0002, capture_read_master_pic, NULL, NULL, capture_write_master_pic, NULL, NULL, + es1371); + if (old_legacy_ctrl & LEGACY_CAPTURE_MASTER_DMA) + io_removehandler(0x0000, 0x0010, capture_read_master_dma, NULL, NULL, capture_write_master_dma, NULL, NULL, + es1371); + if (old_legacy_ctrl & LEGACY_CAPTURE_SLAVE_PIC) + io_removehandler(0x00a0, 0x0002, capture_read_slave_pic, NULL, NULL, capture_write_slave_pic, NULL, NULL, es1371); + if (old_legacy_ctrl & LEGACY_CAPTURE_SLAVE_DMA) + 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); + 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; + es1371_t *es1371 = (es1371_t *)p; - if (func) - return 0; + if (func) + return 0; - //pclog("ES1371 PCI read %08X PC=%08x\n", addr, cpu_state.pc); + // pclog("ES1371 PCI read %08X PC=%08x\n", addr, cpu_state.pc); - switch (addr) { - case 0x00:return 0x74; /*Ensoniq*/ - case 0x01:return 0x12; + switch (addr) { + case 0x00: + return 0x74; /*Ensoniq*/ + case 0x01: + return 0x12; - case 0x02:return 0x71; /*ES1371*/ - case 0x03:return 0x13; + case 0x02: + return 0x71; /*ES1371*/ + case 0x03: + return 0x13; - case 0x04:return es1371->pci_command; - case 0x05:return es1371->pci_serr; + case 0x04: + return es1371->pci_command; + case 0x05: + return es1371->pci_serr; - case 0x06:return 0x10; /*Supports ACPI*/ - case 0x07:return 0; + 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 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 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 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 0x34: + return 0xdc; /*Capabilites pointer*/ - case 0x3c:return es1371->int_line; - case 0x3d:return 0x01; /*INTA*/ + case 0x3c: + return es1371->int_line; + case 0x3d: + return 0x01; /*INTA*/ - case 0x3e:return 0xc; /*Minimum grant*/ - case 0x3f:return 0x80; /*Maximum latency*/ + 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 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; + 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; + es1371_t *es1371 = (es1371_t *)p; - if (func) - return; + if (func) + return; -// pclog("ES1371 PCI write %04X %02X PC=%08x\n", addr, val, cpu_state.pc); + // pclog("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; + 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 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 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; - } -// pclog("es1371->base_addr %08x\n", es1371->base_addr); + case 0xe0: + es1371->pmcsr = (es1371->pmcsr & 0xff00) | (val & 0x03); + break; + case 0xe1: + es1371->pmcsr = (es1371->pmcsr & 0x00ff) | ((val & 0x01) << 8); + break; + } + // pclog("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; + int format = dac_nr ? ((es1371->si_cr >> 2) & 3) : (es1371->si_cr & 3); + int pos = es1371->dac[dac_nr].buffer_pos & 63; + int c; -//pclog("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; + // pclog("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 += 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_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); -// pclog("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 += 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); + // pclog("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; - } + 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]; + 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; + 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; + /*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; - } + 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; - } + 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; + return out; } static void es1371_next_sample_filtered(es1371_t *es1371, int dac_nr, int out_idx) { - int out_l, out_r; - int c; + 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); - } + 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]; + 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); - } + 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); + } -// pclog("Use %02x %04x %04x\n", es1371->dac[dac_nr].buffer_pos & 63, es1371->dac[dac_nr].out_l, es1371->dac[dac_nr].out_r); + // pclog("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++; -// pclog("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); + es1371->dac[dac_nr].buffer_pos++; + // pclog("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 FILE *es1371_f;//,*es1371_f2; static void es1371_update(es1371_t *es1371) { - int32_t l, r; + 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 = (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 >>= 1; + r >>= 1; - l = (l * es1371->master_vol_l) >> 15; - r = (r * es1371->master_vol_r) >> 15; + 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; + 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; - } + 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_t *es1371 = (es1371_t *)p; - timer_advance_u64(&es1371->dac[1].timer, es1371->dac[1].latch); + timer_advance_u64(&es1371->dac[1].timer, es1371->dac[1].latch); - es1371_update(es1371); + 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]; + 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; -// pclog("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].out_l = ((samp1_l * (0x8000 - frac)) + (samp2_l * frac)) >> 15; + es1371->dac[0].out_r = ((samp1_r * (0x8000 - frac)) + (samp2_r * frac)) >> 15; + // pclog("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 < 0) { -// pclog("DAC1 IRQ\n"); - es1371->int_status |= INT_STATUS_DAC1; - es1371_update_irqs(es1371); - es1371->dac[0].curr_samp_ct = es1371->dac[0].samp_ct; - } - } - } + es1371->dac[0].curr_samp_ct--; + if (es1371->dac[0].curr_samp_ct < 0) { + // pclog("DAC1 IRQ\n"); + es1371->int_status |= INT_STATUS_DAC1; + es1371_update_irqs(es1371); + es1371->dac[0].curr_samp_ct = es1371->dac[0].samp_ct; + } + } + } - 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]; + 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; -// pclog("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].out_l = ((samp1_l * (0x8000 - frac)) + (samp2_l * frac)) >> 15; + es1371->dac[1].out_r = ((samp1_r * (0x8000 - frac)) + (samp2_r * frac)) >> 15; + // pclog("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 < 0) { -// pclog("DAC2 IRQ\n"); - es1371->int_status |= INT_STATUS_DAC2; - es1371_update_irqs(es1371); - es1371->dac[1].curr_samp_ct = es1371->dac[1].samp_ct; - } - } - } + es1371->dac[1].curr_samp_ct--; + if (es1371->dac[1].curr_samp_ct < 0) { + // pclog("DAC2 IRQ\n"); + es1371->int_status |= INT_STATUS_DAC2; + es1371_update_irqs(es1371); + es1371->dac[1].curr_samp_ct = es1371->dac[1].samp_ct; + } + } + } } static void es1371_get_buffer(int32_t *buffer, int len, void *p) { - es1371_t *es1371 = (es1371_t *)p; - int c; + es1371_t *es1371 = (es1371_t *)p; + int c; - es1371_update(es1371); + es1371_update(es1371); - for (c = 0; c < len * 2; c++) - buffer[c] += (es1371->buffer[c] / 2); + for (c = 0; c < len * 2; c++) + buffer[c] += (es1371->buffer[c] / 2); - es1371->pos = 0; + es1371->pos = 0; } -static inline double sinc(double x) { - return sin(M_PI * x) / (M_PI * x); -} +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; + /*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))); + 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; - } + /*Create windowed-sinc filter*/ + low_fir_es1371_coef[n] = w * h; + } - low_fir_es1371_coef[(ES1371_NCoef - 1) / 2] = 1.0; + 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.0; + for (n = 0; n < ES1371_NCoef; n++) + gain += low_fir_es1371_coef[n] / (float)N; - gain /= 0.95; + gain /= 0.95; - /*Normalise filter, to produce unity gain*/ - for (n = 0; n < ES1371_NCoef; n++) - low_fir_es1371_coef[n] /= gain; + /*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)); + es1371_t *es1371 = malloc(sizeof(es1371_t)); + memset(es1371, 0, sizeof(es1371_t)); - sound_add_handler(es1371_get_buffer, es1371); + sound_add_handler(es1371_get_buffer, es1371); - es1371->card = pci_add(es1371_pci_read, es1371_pci_write, es1371); + es1371->card = pci_add(es1371_pci_read, es1371_pci_write, es1371); - timer_add(&es1371->dac[1].timer, es1371_poll, es1371, 1); + timer_add(&es1371->dac[1].timer, es1371_poll, es1371, 1); - generate_es1371_filter(); + generate_es1371_filter(); - return es1371; + return es1371; } static void es1371_close(void *p) { - es1371_t *es1371 = (es1371_t *)p; + es1371_t *es1371 = (es1371_t *)p; - free(es1371); + free(es1371); } static void es1371_speed_changed(void *p) { - es1371_t *es1371 = (es1371_t *)p; + es1371_t *es1371 = (es1371_t *)p; - es1371->dac[1].latch = (uint64_t)((double)TIMER_USEC * (1000000.0 / 48000.0)); + es1371->dac[1].latch = (uint64_t)((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]; + 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)); + 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; - } + 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); + 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); - } + 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); + } } void es1371_add_status_info(char *s, int max_len, void *p) { - es1371_t *es1371 = (es1371_t *)p; + es1371_t *es1371 = (es1371_t *)p; - es1371_add_status_info_dac(es1371, s, max_len, 0); - es1371_add_status_info_dac(es1371, s, max_len, 1); + es1371_add_status_info_dac(es1371, s, max_len, 0); + es1371_add_status_info_dac(es1371, s, max_len, 1); } -device_t es1371_device = - { - "Ensoniq AudioPCI (ES1371)", - 0, - es1371_init, - es1371_close, - NULL, - es1371_speed_changed, - NULL, - es1371_add_status_info, - NULL - }; +device_t es1371_device = {"Ensoniq AudioPCI (ES1371)", 0, es1371_init, es1371_close, NULL, es1371_speed_changed, NULL, + es1371_add_status_info, NULL}; diff --git a/src/sound/sound_azt2316a.c b/src/sound/sound_azt2316a.c index aa935457..5e7c991c 100644 --- a/src/sound/sound_azt2316a.c +++ b/src/sound/sound_azt2316a.c @@ -160,1288 +160,1346 @@ /*e80, 11, 1 - 530=22*/ /*f40, 11, 1 - 530=22*/ - static int azt2316a_wss_dma[4] = {0, 0, 1, 3}; static int azt2316a_wss_irq[8] = {5, 7, 9, 10, 11, 12, 14, 15}; /* W95 only uses 7-10, others may be wrong */ -//static uint16_t azt2316a_wss_addr[4] = {0x530, 0x604, 0xe80, 0xf40}; +// static uint16_t azt2316a_wss_addr[4] = {0x530, 0x604, 0xe80, 0xf40}; typedef struct azt2316a_t { - int type; - int wss_interrupt_after_config; + int type; + int wss_interrupt_after_config; - uint8_t wss_config; + uint8_t wss_config; - uint16_t cur_addr, cur_wss_addr, cur_mpu401_addr; + uint16_t cur_addr, cur_wss_addr, cur_mpu401_addr; - uint8_t cur_irq, cur_dma, opl_emu; // sb - uint8_t cur_wss_enabled, cur_wss_irq, cur_wss_dma; - uint8_t cur_mpu401_irq; + uint8_t cur_irq, cur_dma, opl_emu; // sb + uint8_t cur_wss_enabled, cur_wss_irq, cur_wss_dma; + uint8_t cur_mpu401_irq; - uint32_t config_word; - uint32_t config_word_unlocked; + uint32_t config_word; + uint32_t config_word_unlocked; - uint8_t cur_mode; + uint8_t cur_mode; - ad1848_t ad1848; + ad1848_t ad1848; - sb_t *sb; + sb_t *sb; } azt2316a_t; uint8_t azt2316a_wss_read(uint16_t addr, void *p) { - azt2316a_t *azt2316a = (azt2316a_t *)p; - uint8_t temp; -// pclog("azt2316a_read - addr %04X\n", addr); - // TODO: when windows is initializing, writing 0x48, 0x58 and 0x60 to - // 0x530 makes reading from 0x533 return 0x44, but writing 0x50 - // makes this return 0x04. Why? - if (addr & 1) - temp = 4 | (azt2316a->wss_config & 0x40); - else - temp = 4 | (azt2316a->wss_config & 0xC0); -// pclog("return %02X\n", temp); - return temp; + azt2316a_t *azt2316a = (azt2316a_t *)p; + uint8_t temp; + // pclog("azt2316a_read - addr %04X\n", addr); + // TODO: when windows is initializing, writing 0x48, 0x58 and 0x60 to + // 0x530 makes reading from 0x533 return 0x44, but writing 0x50 + // makes this return 0x04. Why? + if (addr & 1) + temp = 4 | (azt2316a->wss_config & 0x40); + else + temp = 4 | (azt2316a->wss_config & 0xC0); + // pclog("return %02X\n", temp); + return temp; } void azt2316a_wss_write(uint16_t addr, uint8_t val, void *p) { - int interrupt = 0; - azt2316a_t *azt2316a = (azt2316a_t *)p; -// pclog("azt2316a_write - addr %04X val %02X\n", addr, val); + int interrupt = 0; + azt2316a_t *azt2316a = (azt2316a_t *)p; + // pclog("azt2316a_write - addr %04X val %02X\n", addr, val); - if (azt2316a->wss_interrupt_after_config) - if ((azt2316a->wss_config & 0x40) && !(val & 0x40)) // TODO: is this the right edge? - interrupt = 1; + if (azt2316a->wss_interrupt_after_config) + if ((azt2316a->wss_config & 0x40) && !(val & 0x40)) // TODO: is this the right edge? + interrupt = 1; - azt2316a->wss_config = val; - azt2316a->cur_wss_dma = azt2316a_wss_dma[val & 3]; - azt2316a->cur_wss_irq = azt2316a_wss_irq[(val >> 3) & 7]; - ad1848_setdma(&azt2316a->ad1848, azt2316a_wss_dma[val & 3]); - ad1848_setirq(&azt2316a->ad1848, azt2316a_wss_irq[(val >> 3) & 7]); + azt2316a->wss_config = val; + azt2316a->cur_wss_dma = azt2316a_wss_dma[val & 3]; + azt2316a->cur_wss_irq = azt2316a_wss_irq[(val >> 3) & 7]; + ad1848_setdma(&azt2316a->ad1848, azt2316a_wss_dma[val & 3]); + ad1848_setirq(&azt2316a->ad1848, azt2316a_wss_irq[(val >> 3) & 7]); - if (interrupt) - picint(1 << azt2316a->cur_wss_irq); + if (interrupt) + picint(1 << azt2316a->cur_wss_irq); } // generate a config word based on current settings void azt1605_create_config_word(void *p) { - azt2316a_t *azt2316a = (azt2316a_t *)p; - uint32_t temp = 0; + azt2316a_t *azt2316a = (azt2316a_t *)p; + uint32_t temp = 0; - // not implemented / hardcoded - uint8_t game_enable = 1; - uint8_t mpu401_enable = 1; - uint8_t cd_type = 0; // TODO: see if the cd-rom was originally connected there on the real machines emulated by PCem (Packard Bell Legend 100CD, Itautec Infoway Multimidia, etc) - uint8_t cd_dma8 = -1; - uint8_t cd_irq = 0; + // not implemented / hardcoded + uint8_t game_enable = 1; + uint8_t mpu401_enable = 1; + uint8_t cd_type = 0; // TODO: see if the cd-rom was originally connected there on the real machines emulated by PCem + // (Packard Bell Legend 100CD, Itautec Infoway Multimidia, etc) + uint8_t cd_dma8 = -1; + uint8_t cd_irq = 0; - switch (azt2316a->cur_addr) { - case 0x220: - // do nothing - //temp += 0 << 0; - break; - case 0x240:temp += 1 << 0; - break; -/* - case 0x260: // TODO: INVALID? - temp += 2 << 0; + switch (azt2316a->cur_addr) { + case 0x220: + // do nothing + // temp += 0 << 0; break; - case 0x280: // TODO: INVALID? - temp += 3 << 0; + case 0x240: + temp += 1 << 0; break; -*/ - default:fatal("Bad AZT1605 addr %04X\n", azt2316a->cur_addr); - } - switch (azt2316a->cur_irq) { - case 2:temp += 1 << 8; - break; - case 3:temp += 1 << 9; - break; - case 5:temp += 1 << 10; - break; - case 7:temp += 1 << 11; - break; - default:fatal("Bad AZT1605 irq %02X\n", azt2316a->cur_irq); - } - switch (azt2316a->cur_wss_addr) { - case 0x530: - // do nothing - //temp += 0 << 16; - break; - case 0x604:temp += 1 << 16; - break; - case 0xE80:temp += 2 << 16; - break; - case 0xF40:temp += 3 << 16; - break; - default:fatal("Bad AZT1605 WSS addr %04X\n", azt2316a->cur_wss_addr); - } - if (azt2316a->cur_wss_enabled) - temp += 1 << 18; - if (game_enable) - temp += 1 << 4; - switch (azt2316a->cur_mpu401_addr) { - case 0x300: - // do nothing - //temp += 0 << 2; - break; - case 0x330:temp += 1 << 2; - break; - default:fatal("Bad AZT1605 MPU401 addr %04X\n", azt2316a->cur_mpu401_addr); - } - if (mpu401_enable) - temp += 1 << 3; - switch (cd_type) { - case 0: // disabled - // do nothing - //temp += 0 << 5; - break; - case 1: // panasonic - temp += 1 << 5; - break; - case 2: // mitsumi/sony/aztech - temp += 2 << 5; - break; - case 3: // all enabled - temp += 3 << 5; - break; - case 4: // unused - temp += 4 << 5; - break; - case 5: // unused - temp += 5 << 5; - break; - case 6: // unused - temp += 6 << 5; - break; - case 7: // unused - temp += 7 << 5; - break; - default:fatal("Bad AZT1605 CD type %02X\n", cd_type); - } - switch (cd_dma8) { - case 0xFF: // -1 - // do nothing - //temp += 0 << 22; - break; - case 0:temp += 1 << 22; - break; - case 1:temp += 2 << 22; - break; - case 3:temp += 3 << 22; - break; - default:fatal("Bad AZT1605 cd dma8 %02X\n", cd_dma8); + /* + case 0x260: // TODO: INVALID? + temp += 2 << 0; + break; + case 0x280: // TODO: INVALID? + temp += 3 << 0; + break; + */ + default: + fatal("Bad AZT1605 addr %04X\n", azt2316a->cur_addr); + } + switch (azt2316a->cur_irq) { + case 2: + temp += 1 << 8; + break; + case 3: + temp += 1 << 9; + break; + case 5: + temp += 1 << 10; + break; + case 7: + temp += 1 << 11; + break; + default: + fatal("Bad AZT1605 irq %02X\n", azt2316a->cur_irq); + } + switch (azt2316a->cur_wss_addr) { + case 0x530: + // do nothing + // temp += 0 << 16; + break; + case 0x604: + temp += 1 << 16; + break; + case 0xE80: + temp += 2 << 16; + break; + case 0xF40: + temp += 3 << 16; + break; + default: + fatal("Bad AZT1605 WSS addr %04X\n", azt2316a->cur_wss_addr); + } + if (azt2316a->cur_wss_enabled) + temp += 1 << 18; + if (game_enable) + temp += 1 << 4; + switch (azt2316a->cur_mpu401_addr) { + case 0x300: + // do nothing + // temp += 0 << 2; + break; + case 0x330: + temp += 1 << 2; + break; + default: + fatal("Bad AZT1605 MPU401 addr %04X\n", azt2316a->cur_mpu401_addr); + } + if (mpu401_enable) + temp += 1 << 3; + switch (cd_type) { + case 0: // disabled + // do nothing + // temp += 0 << 5; + break; + case 1: // panasonic + temp += 1 << 5; + break; + case 2: // mitsumi/sony/aztech + temp += 2 << 5; + break; + case 3: // all enabled + temp += 3 << 5; + break; + case 4: // unused + temp += 4 << 5; + break; + case 5: // unused + temp += 5 << 5; + break; + case 6: // unused + temp += 6 << 5; + break; + case 7: // unused + temp += 7 << 5; + break; + default: + fatal("Bad AZT1605 CD type %02X\n", cd_type); + } + switch (cd_dma8) { + case 0xFF: // -1 + // do nothing + // temp += 0 << 22; + break; + case 0: + temp += 1 << 22; + break; + case 1: + temp += 2 << 22; + break; + case 3: + temp += 3 << 22; + break; + default: + fatal("Bad AZT1605 cd dma8 %02X\n", cd_dma8); + } + switch (azt2316a->cur_mpu401_irq) { + case 2: + temp += 1 << 12; + break; + case 3: + temp += 1 << 13; + break; + case 5: + temp += 1 << 14; + break; + case 7: + temp += 1 << 15; + break; + default: + fatal("Bad AZT1605 mpu401 irq %02X\n", azt2316a->cur_mpu401_irq); + } + switch (cd_irq) { + case 0: // disabled + // do nothing + break; + case 11: + temp += 1 << 19; + break; + case 12: + temp += 1 << 20; + break; + case 15: + temp += 1 << 21; + break; + default: + fatal("Bad AZT1605 cd irq %02X\n", cd_irq); + } - } - switch (azt2316a->cur_mpu401_irq) { - case 2:temp += 1 << 12; - break; - case 3:temp += 1 << 13; - break; - case 5:temp += 1 << 14; - break; - case 7:temp += 1 << 15; - break; - default:fatal("Bad AZT1605 mpu401 irq %02X\n", azt2316a->cur_mpu401_irq); - } - switch (cd_irq) { - case 0: // disabled - // do nothing - break; - case 11:temp += 1 << 19; - break; - case 12:temp += 1 << 20; - break; - case 15:temp += 1 << 21; - break; - default:fatal("Bad AZT1605 cd irq %02X\n", cd_irq); - } - - azt2316a->config_word = temp; + azt2316a->config_word = temp; } void azt2316a_create_config_word(void *p) { - azt2316a_t *azt2316a = (azt2316a_t *)p; - uint32_t temp = 0; + azt2316a_t *azt2316a = (azt2316a_t *)p; + uint32_t temp = 0; - // not implemented / hardcoded - uint8_t game_enable = 1; - uint8_t mpu401_enable = 1; - uint16_t cd_addr = 0x310; - uint8_t cd_type = 0; // TODO: see if the cd-rom was originally connected there on the real machines emulated by PCem (Packard Bell Legend 100CD, Itautec Infoway Multimidia, etc) - uint8_t cd_dma8 = -1; - uint8_t cd_dma16 = -1; - uint8_t cd_irq = 15; + // not implemented / hardcoded + uint8_t game_enable = 1; + uint8_t mpu401_enable = 1; + uint16_t cd_addr = 0x310; + uint8_t cd_type = 0; // TODO: see if the cd-rom was originally connected there on the real machines emulated by PCem + // (Packard Bell Legend 100CD, Itautec Infoway Multimidia, etc) + uint8_t cd_dma8 = -1; + uint8_t cd_dma16 = -1; + uint8_t cd_irq = 15; - if (azt2316a->type == SB_SUBTYPE_CLONE_AZT1605_0X0C) { - azt1605_create_config_word(p); - return; - } + if (azt2316a->type == SB_SUBTYPE_CLONE_AZT1605_0X0C) { + azt1605_create_config_word(p); + return; + } - switch (azt2316a->cur_addr) { - case 0x220: - // do nothing - //temp += 0 << 0; - break; - case 0x240:temp += 1 << 0; - break; -/* - case 0x260: // TODO: INVALID? - temp += 2 << 0; - break; - case 0x280: // TODO: INVALID? - temp += 3 << 0; - break; -*/ - default:fatal("Bad AZT2316A addr %04X\n", azt2316a->cur_addr); - } - switch (azt2316a->cur_irq) { - case 2:temp += 1 << 2; - break; - case 5:temp += 1 << 3; - break; - case 7:temp += 1 << 4; - break; - case 10:temp += 1 << 5; - break; - default:fatal("Bad AZT2316A irq %02X\n", azt2316a->cur_irq); - } - switch (azt2316a->cur_dma) { -/* - // TODO: INVALID? - case 0xFF: // -1 + switch (azt2316a->cur_addr) { + case 0x220: // do nothing - //temp += 0 << 6; + // temp += 0 << 0; break; -*/ - case 0:temp += 1 << 6; - break; - case 1:temp += 2 << 6; - break; - case 3:temp += 3 << 6; - break; - default:fatal("Bad AZT2316A dma %02X\n", azt2316a->cur_dma); - } - switch (azt2316a->cur_wss_addr) { - case 0x530: - // do nothing - //temp += 0 << 8; - break; - case 0x604:temp += 1 << 8; - break; - case 0xE80:temp += 2 << 8; - break; - case 0xF40:temp += 3 << 8; - break; - default:fatal("Bad AZT2316A WSS addr %04X\n", azt2316a->cur_wss_addr); - } - if (azt2316a->cur_wss_enabled) - temp += 1 << 10; - if (game_enable) - temp += 1 << 11; - switch (azt2316a->cur_mpu401_addr) { - case 0x300: - // do nothing - //temp += 0 << 12; - break; - case 0x330:temp += 1 << 12; - break; - default:fatal("Bad AZT2316A MPU401 addr %04X\n", azt2316a->cur_mpu401_addr); - } - if (mpu401_enable) - temp += 1 << 13; - switch (cd_addr) { - case 0x310: - // do nothing - //temp += 0 << 14; - break; - case 0x320:temp += 1 << 14; - break; - case 0x340:temp += 2 << 14; - break; - case 0x350:temp += 3 << 14; - break; - default:fatal("Bad AZT2316A CD addr %04X\n", cd_addr); - } - switch (cd_type) { - case 0: // disabled - // do nothing - //temp += 0 << 16; - break; - case 1: // panasonic - temp += 1 << 16; - break; - case 2: // sony - temp += 2 << 16; - break; - case 3: // mitsumi - temp += 3 << 16; - break; - case 4: // aztech - temp += 4 << 16; - break; - case 5: // unused - temp += 5 << 16; - break; - case 6: // unused - temp += 6 << 16; - break; - case 7: // unused - temp += 7 << 16; - break; - default:fatal("Bad AZT2316A CD type %02X\n", cd_type); - } - switch (cd_dma8) { - case 0xFF: // -1 - // do nothing - //temp += 0 << 20; - break; - case 0:temp += 1 << 20; - break; -/* - case 1: // TODO: INVALID? - temp += 2 << 20; + case 0x240: + temp += 1 << 0; break; -*/ - case 3:temp += 3 << 20; - break; - default:fatal("Bad AZT2316A cd dma8 %02X\n", cd_dma8); - } - switch (cd_dma16) { - case 0xFF: // -1 - // do nothing - //temp += 0 << 22; - break; - case 5:temp += 1 << 22; - break; - case 6:temp += 2 << 22; - break; - case 7:temp += 3 << 22; - break; - default:fatal("Bad AZT2316A cd dma16 %02X\n", cd_dma16); - } - switch (azt2316a->cur_mpu401_irq) { - case 2:temp += 1 << 24; - break; - case 5:temp += 1 << 25; - break; - case 7:temp += 1 << 26; - break; - case 10:temp += 1 << 27; - break; - default:fatal("Bad AZT2316A mpu401 irq %02X\n", azt2316a->cur_mpu401_irq); - } - switch (cd_irq) { - case 5:temp += 1 << 28; - break; - case 11:temp += 1 << 29; - break; - case 12:temp += 1 << 30; - break; - case 15:temp += 1 << 31; - break; - default:fatal("Bad AZT2316A cd irq %02X\n", cd_irq); - } + /* + case 0x260: // TODO: INVALID? + temp += 2 << 0; + break; + case 0x280: // TODO: INVALID? + temp += 3 << 0; + break; + */ + default: + fatal("Bad AZT2316A addr %04X\n", azt2316a->cur_addr); + } + switch (azt2316a->cur_irq) { + case 2: + temp += 1 << 2; + break; + case 5: + temp += 1 << 3; + break; + case 7: + temp += 1 << 4; + break; + case 10: + temp += 1 << 5; + break; + default: + fatal("Bad AZT2316A irq %02X\n", azt2316a->cur_irq); + } + switch (azt2316a->cur_dma) { + /* + // TODO: INVALID? + case 0xFF: // -1 + // do nothing + //temp += 0 << 6; + break; + */ + case 0: + temp += 1 << 6; + break; + case 1: + temp += 2 << 6; + break; + case 3: + temp += 3 << 6; + break; + default: + fatal("Bad AZT2316A dma %02X\n", azt2316a->cur_dma); + } + switch (azt2316a->cur_wss_addr) { + case 0x530: + // do nothing + // temp += 0 << 8; + break; + case 0x604: + temp += 1 << 8; + break; + case 0xE80: + temp += 2 << 8; + break; + case 0xF40: + temp += 3 << 8; + break; + default: + fatal("Bad AZT2316A WSS addr %04X\n", azt2316a->cur_wss_addr); + } + if (azt2316a->cur_wss_enabled) + temp += 1 << 10; + if (game_enable) + temp += 1 << 11; + switch (azt2316a->cur_mpu401_addr) { + case 0x300: + // do nothing + // temp += 0 << 12; + break; + case 0x330: + temp += 1 << 12; + break; + default: + fatal("Bad AZT2316A MPU401 addr %04X\n", azt2316a->cur_mpu401_addr); + } + if (mpu401_enable) + temp += 1 << 13; + switch (cd_addr) { + case 0x310: + // do nothing + // temp += 0 << 14; + break; + case 0x320: + temp += 1 << 14; + break; + case 0x340: + temp += 2 << 14; + break; + case 0x350: + temp += 3 << 14; + break; + default: + fatal("Bad AZT2316A CD addr %04X\n", cd_addr); + } + switch (cd_type) { + case 0: // disabled + // do nothing + // temp += 0 << 16; + break; + case 1: // panasonic + temp += 1 << 16; + break; + case 2: // sony + temp += 2 << 16; + break; + case 3: // mitsumi + temp += 3 << 16; + break; + case 4: // aztech + temp += 4 << 16; + break; + case 5: // unused + temp += 5 << 16; + break; + case 6: // unused + temp += 6 << 16; + break; + case 7: // unused + temp += 7 << 16; + break; + default: + fatal("Bad AZT2316A CD type %02X\n", cd_type); + } + switch (cd_dma8) { + case 0xFF: // -1 + // do nothing + // temp += 0 << 20; + break; + case 0: + temp += 1 << 20; + break; + /* + case 1: // TODO: INVALID? + temp += 2 << 20; + break; + */ + case 3: + temp += 3 << 20; + break; + default: + fatal("Bad AZT2316A cd dma8 %02X\n", cd_dma8); + } + switch (cd_dma16) { + case 0xFF: // -1 + // do nothing + // temp += 0 << 22; + break; + case 5: + temp += 1 << 22; + break; + case 6: + temp += 2 << 22; + break; + case 7: + temp += 3 << 22; + break; + default: + fatal("Bad AZT2316A cd dma16 %02X\n", cd_dma16); + } + switch (azt2316a->cur_mpu401_irq) { + case 2: + temp += 1 << 24; + break; + case 5: + temp += 1 << 25; + break; + case 7: + temp += 1 << 26; + break; + case 10: + temp += 1 << 27; + break; + default: + fatal("Bad AZT2316A mpu401 irq %02X\n", azt2316a->cur_mpu401_irq); + } + switch (cd_irq) { + case 5: + temp += 1 << 28; + break; + case 11: + temp += 1 << 29; + break; + case 12: + temp += 1 << 30; + break; + case 15: + temp += 1 << 31; + break; + default: + fatal("Bad AZT2316A cd irq %02X\n", cd_irq); + } - azt2316a->config_word = temp; + azt2316a->config_word = temp; } uint8_t azt2316a_config_read(uint16_t addr, void *p) { - azt2316a_t *azt2316a = (azt2316a_t *)p; - uint8_t temp; -// pclog("azt2316a_config_read - addr %04X\n", addr); + azt2316a_t *azt2316a = (azt2316a_t *)p; + uint8_t temp; + // pclog("azt2316a_config_read - addr %04X\n", addr); - // Some WSS config here + config change enable bit - // (setting bit 7 and writing back) - if (addr == azt2316a->cur_addr + 0x404) { - // TODO: what is the real meaning of the read value? - // I got a mention of bit 0x10 for WSS from disassembling the source - // code of the driver, and when playing with the I/O ports on real - // hardware after doing some configuration, but didn't dig into it. - // Bit 0x08 seems to be a busy flag and generates a timeout - // (continuous re-reading when initializing windows 98) - temp = azt2316a->cur_mode ? 0x07 : 0x0F; - if (azt2316a->config_word_unlocked) - temp |= 0x80; - } else { - // Rest of config. These are documented in the Linux driver. - switch (addr & 0x3) { - case 0:temp = azt2316a->config_word & 0xFF; - break; - case 1:temp = (azt2316a->config_word >> 8) & 0xFF; - break; - case 2:temp = (azt2316a->config_word >> 16) & 0xFF; - break; - case 3:temp = (azt2316a->config_word >> 24) & 0xFF; - break; - } - } + // Some WSS config here + config change enable bit + // (setting bit 7 and writing back) + if (addr == azt2316a->cur_addr + 0x404) { + // TODO: what is the real meaning of the read value? + // I got a mention of bit 0x10 for WSS from disassembling the source + // code of the driver, and when playing with the I/O ports on real + // hardware after doing some configuration, but didn't dig into it. + // Bit 0x08 seems to be a busy flag and generates a timeout + // (continuous re-reading when initializing windows 98) + temp = azt2316a->cur_mode ? 0x07 : 0x0F; + if (azt2316a->config_word_unlocked) + temp |= 0x80; + } else { + // Rest of config. These are documented in the Linux driver. + switch (addr & 0x3) { + case 0: + temp = azt2316a->config_word & 0xFF; + break; + case 1: + temp = (azt2316a->config_word >> 8) & 0xFF; + break; + case 2: + temp = (azt2316a->config_word >> 16) & 0xFF; + break; + case 3: + temp = (azt2316a->config_word >> 24) & 0xFF; + break; + } + } -// pclog("return %02X\n", temp); - return temp; + // pclog("return %02X\n", temp); + return temp; } void azt1605_config_write(uint16_t addr, uint8_t val, void *p) { - azt2316a_t *azt2316a = (azt2316a_t *)p; - uint8_t temp; -// pclog("azt2316a_config_write - addr %04X val %02X\n", addr, val); + azt2316a_t *azt2316a = (azt2316a_t *)p; + uint8_t temp; + // pclog("azt2316a_config_write - addr %04X val %02X\n", addr, val); - if (addr == azt2316a->cur_addr + 0x404) { - if (val & 0x80) - azt2316a->config_word_unlocked = 1; - else - azt2316a->config_word_unlocked = 0; - } else if (azt2316a->config_word_unlocked) { - if (val == 0xFF) // TODO: check if this still happens on eeprom.sys after having more complete emulation! - return; - switch (addr & 0x3) { - case 0:azt2316a->config_word = (azt2316a->config_word & 0xFFFFFF00) + val; + if (addr == azt2316a->cur_addr + 0x404) { + if (val & 0x80) + azt2316a->config_word_unlocked = 1; + else + azt2316a->config_word_unlocked = 0; + } else if (azt2316a->config_word_unlocked) { + if (val == 0xFF) // TODO: check if this still happens on eeprom.sys after having more complete emulation! + return; + switch (addr & 0x3) { + case 0: + azt2316a->config_word = (azt2316a->config_word & 0xFFFFFF00) + val; - temp = val & 0x3; - if (temp == 0) - azt2316a->cur_addr = 0x220; - else if (temp == 1) - azt2316a->cur_addr = 0x240; -/* + temp = val & 0x3; + if (temp == 0) + azt2316a->cur_addr = 0x220; + else if (temp == 1) + azt2316a->cur_addr = 0x240; + /* + else if (temp == 2) + azt2316a->cur_addr = 0x260; // TODO: INVALID + else if (temp == 3) + azt2316a->cur_addr = 0x280; // TODO: INVALID + */ + + if (val & 0x4) + azt2316a->cur_mpu401_addr = 0x330; + else + azt2316a->cur_mpu401_addr = 0x300; + + // mpu401_enabled is harcoded + // if (val & 0x8) + // azt2316a->cur_mpu401_enabled = 1; + // else + // azt2316a->cur_mpu401_enabled = 0; + + // game_enabled is hardcoded + // if (val & 0x10) + // azt2316a->cur_game_enabled = 1; + // else + // azt2316a->cur_game_enabled = 0; + + // cd_type is hardcoded + // azt2316a->cur_cd_type = (val >> 5) & 0x7; + break; + case 1: + azt2316a->config_word = (azt2316a->config_word & 0xFFFF00FF) + (val << 8); + + if (val & 0x1) + azt2316a->cur_irq = 2; + else if (val & 0x2) + azt2316a->cur_irq = 3; + else if (val & 0x4) + azt2316a->cur_irq = 5; + else if (val & 0x8) + azt2316a->cur_irq = 7; + // else undefined? + + if (val & 0x10) + azt2316a->cur_mpu401_irq = 2; + else if (val & 0x20) + azt2316a->cur_mpu401_irq = 3; + else if (val & 0x40) + azt2316a->cur_mpu401_irq = 5; + else if (val & 0x80) + azt2316a->cur_mpu401_irq = 7; + // else undefined? + break; + case 2: + azt2316a->config_word = (azt2316a->config_word & 0xFF00FFFF) + (val << 16); + + io_removehandler(azt2316a->cur_wss_addr, 0x0004, azt2316a_wss_read, NULL, NULL, azt2316a_wss_write, NULL, + NULL, azt2316a); + io_removehandler(azt2316a->cur_wss_addr + 0x0004, 0x0004, ad1848_read, NULL, NULL, ad1848_write, NULL, + NULL, &azt2316a->ad1848); + + temp = val & 0x3; + if (temp == 0) + azt2316a->cur_wss_addr = 0x530; + else if (temp == 1) + azt2316a->cur_wss_addr = 0x604; else if (temp == 2) - azt2316a->cur_addr = 0x260; // TODO: INVALID + azt2316a->cur_wss_addr = 0xE80; else if (temp == 3) - azt2316a->cur_addr = 0x280; // TODO: INVALID -*/ + azt2316a->cur_wss_addr = 0xF40; - if (val & 0x4) - azt2316a->cur_mpu401_addr = 0x330; - else - azt2316a->cur_mpu401_addr = 0x300; + io_sethandler(azt2316a->cur_wss_addr, 0x0004, azt2316a_wss_read, NULL, NULL, azt2316a_wss_write, NULL, + NULL, azt2316a); + io_sethandler(azt2316a->cur_wss_addr + 0x0004, 0x0004, ad1848_read, NULL, NULL, ad1848_write, NULL, NULL, + &azt2316a->ad1848); - // mpu401_enabled is harcoded - //if (val & 0x8) - // azt2316a->cur_mpu401_enabled = 1; - //else - // azt2316a->cur_mpu401_enabled = 0; + // no actual effect + if (val & 0x4) + azt2316a->cur_wss_enabled = 1; + else + azt2316a->cur_wss_enabled = 0; - // game_enabled is hardcoded - //if (val & 0x10) - // azt2316a->cur_game_enabled = 1; - //else - // azt2316a->cur_game_enabled = 0; + // cd_irq is hardcoded + // if (val & 0x8) + // azt2316a->cur_cd_irq = 11; + // else if (val & 0x10) + // azt2316a->cur_cd_irq = 12; + // else if (val & 0x20) + // azt2316a->cur_cd_irq = 15; + // else disable? - // cd_type is hardcoded - //azt2316a->cur_cd_type = (val >> 5) & 0x7; - break; - case 1:azt2316a->config_word = (azt2316a->config_word & 0xFFFF00FF) + (val << 8); + // cd_dma8 is hardcoded + // temp = (val >> 6) & 0x3; + // if (temp == 0) + // azt2316a->cur_cd_dma8 = -1; + // else if (temp == 1) + // azt2316a->cur_cd_dma8 = 0; + // else if (temp == 3) + // azt2316a->cur_cd_dma8 = 3; + // else error + break; + case 3: + break; + } + // update sbprov2 configs + sb_dsp_setaddr(&azt2316a->sb->dsp, azt2316a->cur_addr); + sb_dsp_setirq(&azt2316a->sb->dsp, azt2316a->cur_irq); + sb_dsp_setdma8(&azt2316a->sb->dsp, azt2316a->cur_dma); - if (val & 0x1) - azt2316a->cur_irq = 2; - else if (val & 0x2) - azt2316a->cur_irq = 3; - else if (val & 0x4) - azt2316a->cur_irq = 5; - else if (val & 0x8) - azt2316a->cur_irq = 7; - // else undefined? - - if (val & 0x10) - azt2316a->cur_mpu401_irq = 2; - else if (val & 0x20) - azt2316a->cur_mpu401_irq = 3; - else if (val & 0x40) - azt2316a->cur_mpu401_irq = 5; - else if (val & 0x80) - azt2316a->cur_mpu401_irq = 7; - // else undefined? - break; - case 2:azt2316a->config_word = (azt2316a->config_word & 0xFF00FFFF) + (val << 16); - - io_removehandler(azt2316a->cur_wss_addr, 0x0004, azt2316a_wss_read, NULL, NULL, azt2316a_wss_write, NULL, NULL, azt2316a); - io_removehandler(azt2316a->cur_wss_addr + 0x0004, 0x0004, ad1848_read, NULL, NULL, ad1848_write, NULL, NULL, &azt2316a->ad1848); - - temp = val & 0x3; - if (temp == 0) - azt2316a->cur_wss_addr = 0x530; - else if (temp == 1) - azt2316a->cur_wss_addr = 0x604; - else if (temp == 2) - azt2316a->cur_wss_addr = 0xE80; - else if (temp == 3) - azt2316a->cur_wss_addr = 0xF40; - - io_sethandler(azt2316a->cur_wss_addr, 0x0004, azt2316a_wss_read, NULL, NULL, azt2316a_wss_write, NULL, NULL, azt2316a); - io_sethandler(azt2316a->cur_wss_addr + 0x0004, 0x0004, ad1848_read, NULL, NULL, ad1848_write, NULL, NULL, &azt2316a->ad1848); - - // no actual effect - if (val & 0x4) - azt2316a->cur_wss_enabled = 1; - else - azt2316a->cur_wss_enabled = 0; - - // cd_irq is hardcoded - //if (val & 0x8) - // azt2316a->cur_cd_irq = 11; - //else if (val & 0x10) - // azt2316a->cur_cd_irq = 12; - //else if (val & 0x20) - // azt2316a->cur_cd_irq = 15; - // else disable? - - // cd_dma8 is hardcoded - //temp = (val >> 6) & 0x3; - //if (temp == 0) - // azt2316a->cur_cd_dma8 = -1; - //else if (temp == 1) - // azt2316a->cur_cd_dma8 = 0; - //else if (temp == 3) - // azt2316a->cur_cd_dma8 = 3; - //else error - break; - case 3:break; - } - // update sbprov2 configs - sb_dsp_setaddr(&azt2316a->sb->dsp, azt2316a->cur_addr); - sb_dsp_setirq(&azt2316a->sb->dsp, azt2316a->cur_irq); - sb_dsp_setdma8(&azt2316a->sb->dsp, azt2316a->cur_dma); - - mpu401_uart_update_addr(&azt2316a->sb->mpu, azt2316a->cur_mpu401_addr); - mpu401_uart_update_irq(&azt2316a->sb->mpu, azt2316a->cur_mpu401_irq); - } + mpu401_uart_update_addr(&azt2316a->sb->mpu, azt2316a->cur_mpu401_addr); + mpu401_uart_update_irq(&azt2316a->sb->mpu, azt2316a->cur_mpu401_irq); + } } void azt2316a_config_write(uint16_t addr, uint8_t val, void *p) { - azt2316a_t *azt2316a = (azt2316a_t *)p; - uint8_t temp; -// pclog("azt2316a_config_write - addr %04X val %02X\n", addr, val); + azt2316a_t *azt2316a = (azt2316a_t *)p; + uint8_t temp; + // pclog("azt2316a_config_write - addr %04X val %02X\n", addr, val); - if (azt2316a->type == SB_SUBTYPE_CLONE_AZT1605_0X0C) { - azt1605_config_write(addr, val, p); - return; - } + if (azt2316a->type == SB_SUBTYPE_CLONE_AZT1605_0X0C) { + azt1605_config_write(addr, val, p); + return; + } - if (addr == azt2316a->cur_addr + 0x404) { - if (val & 0x80) - azt2316a->config_word_unlocked = 1; - else - azt2316a->config_word_unlocked = 0; - } else if (azt2316a->config_word_unlocked) { - if (val == 0xFF) // TODO: check if this still happens on eeprom.sys after having more complete emulation! - return; - switch (addr & 0x3) { - case 0:azt2316a->config_word = (azt2316a->config_word & 0xFFFFFF00) + val; + if (addr == azt2316a->cur_addr + 0x404) { + if (val & 0x80) + azt2316a->config_word_unlocked = 1; + else + azt2316a->config_word_unlocked = 0; + } else if (azt2316a->config_word_unlocked) { + if (val == 0xFF) // TODO: check if this still happens on eeprom.sys after having more complete emulation! + return; + switch (addr & 0x3) { + case 0: + azt2316a->config_word = (azt2316a->config_word & 0xFFFFFF00) + val; - temp = val & 0x3; - if (temp == 0) - azt2316a->cur_addr = 0x220; - else if (temp == 1) - azt2316a->cur_addr = 0x240; -/* - else if (temp == 2) - azt2316a->cur_addr = 0x260; // TODO: INVALID - else if (temp == 3) - azt2316a->cur_addr = 0x280; // TODO: INVALID -*/ - - if (val & 0x4) - azt2316a->cur_irq = 2; - else if (val & 0x8) - azt2316a->cur_irq = 5; - else if (val & 0x10) - azt2316a->cur_irq = 7; - else if (val & 0x20) - azt2316a->cur_irq = 10; - // else undefined? - - temp = (val >> 6) & 0x3; -/* + temp = val & 0x3; if (temp == 0) - azt2316a->cur_dma = -1; // TODO: INVALID? - else */if (temp == 1) - azt2316a->cur_dma = 0; - else if (temp == 2) - azt2316a->cur_dma = 1; - else if (temp == 3) - azt2316a->cur_dma = 3; - break; - case 1:azt2316a->config_word = (azt2316a->config_word & 0xFFFF00FF) + (val << 8); + azt2316a->cur_addr = 0x220; + else if (temp == 1) + azt2316a->cur_addr = 0x240; + /* + else if (temp == 2) + azt2316a->cur_addr = 0x260; // TODO: INVALID + else if (temp == 3) + azt2316a->cur_addr = 0x280; // TODO: INVALID + */ - io_removehandler(azt2316a->cur_wss_addr, 0x0004, azt2316a_wss_read, NULL, NULL, azt2316a_wss_write, NULL, NULL, azt2316a); - io_removehandler(azt2316a->cur_wss_addr + 0x0004, 0x0004, ad1848_read, NULL, NULL, ad1848_write, NULL, NULL, &azt2316a->ad1848); + if (val & 0x4) + azt2316a->cur_irq = 2; + else if (val & 0x8) + azt2316a->cur_irq = 5; + else if (val & 0x10) + azt2316a->cur_irq = 7; + else if (val & 0x20) + azt2316a->cur_irq = 10; + // else undefined? - temp = val & 0x3; - if (temp == 0) - azt2316a->cur_wss_addr = 0x530; - else if (temp == 1) - azt2316a->cur_wss_addr = 0x604; - else if (temp == 2) - azt2316a->cur_wss_addr = 0xE80; - else if (temp == 3) - azt2316a->cur_wss_addr = 0xF40; + temp = (val >> 6) & 0x3; + /* + if (temp == 0) + azt2316a->cur_dma = -1; // TODO: INVALID? + else */ + if (temp == 1) + azt2316a->cur_dma = 0; + else if (temp == 2) + azt2316a->cur_dma = 1; + else if (temp == 3) + azt2316a->cur_dma = 3; + break; + case 1: + azt2316a->config_word = (azt2316a->config_word & 0xFFFF00FF) + (val << 8); - io_sethandler(azt2316a->cur_wss_addr, 0x0004, azt2316a_wss_read, NULL, NULL, azt2316a_wss_write, NULL, NULL, azt2316a); - io_sethandler(azt2316a->cur_wss_addr + 0x0004, 0x0004, ad1848_read, NULL, NULL, ad1848_write, NULL, NULL, &azt2316a->ad1848); + io_removehandler(azt2316a->cur_wss_addr, 0x0004, azt2316a_wss_read, NULL, NULL, azt2316a_wss_write, NULL, + NULL, azt2316a); + io_removehandler(azt2316a->cur_wss_addr + 0x0004, 0x0004, ad1848_read, NULL, NULL, ad1848_write, NULL, + NULL, &azt2316a->ad1848); - // no actual effect - if (val & 0x4) - azt2316a->cur_wss_enabled = 1; - else - azt2316a->cur_wss_enabled = 0; + temp = val & 0x3; + if (temp == 0) + azt2316a->cur_wss_addr = 0x530; + else if (temp == 1) + azt2316a->cur_wss_addr = 0x604; + else if (temp == 2) + azt2316a->cur_wss_addr = 0xE80; + else if (temp == 3) + azt2316a->cur_wss_addr = 0xF40; - // game_enabled is hardcoded - //if (val & 0x8) - // azt2316a->cur_game_enabled = 1; - //else - // azt2316a->cur_game_enabled = 0; + io_sethandler(azt2316a->cur_wss_addr, 0x0004, azt2316a_wss_read, NULL, NULL, azt2316a_wss_write, NULL, + NULL, azt2316a); + io_sethandler(azt2316a->cur_wss_addr + 0x0004, 0x0004, ad1848_read, NULL, NULL, ad1848_write, NULL, NULL, + &azt2316a->ad1848); - if (val & 0x10) - azt2316a->cur_mpu401_addr = 0x330; - else - azt2316a->cur_mpu401_addr = 0x300; + // no actual effect + if (val & 0x4) + azt2316a->cur_wss_enabled = 1; + else + azt2316a->cur_wss_enabled = 0; - // mpu401_enabled is harcoded - //if (val & 0x20) - // azt2316a->cur_mpu401_enabled = 1; - //else - // azt2316a->cur_mpu401_enabled = 0; + // game_enabled is hardcoded + // if (val & 0x8) + // azt2316a->cur_game_enabled = 1; + // else + // azt2316a->cur_game_enabled = 0; - // cd_addr is hardcoded - //temp = (val >> 6) & 0x3; - //if (temp == 0) - // azt2316a->cur_cd_addr = 0x310; - //else if (temp == 1) - // azt2316a->cur_cd_addr = 0x320; - //else if (temp == 2) - // azt2316a->cur_cd_addr = 0x340; - //else if (temp == 3) - // azt2316a->cur_cd_addr = 0x350; - break; - case 2:azt2316a->config_word = (azt2316a->config_word & 0xFF00FFFF) + (val << 16); + if (val & 0x10) + azt2316a->cur_mpu401_addr = 0x330; + else + azt2316a->cur_mpu401_addr = 0x300; - // cd_type is hardcoded - //azt2316a->cur_cd_type = val & 0x7; + // mpu401_enabled is harcoded + // if (val & 0x20) + // azt2316a->cur_mpu401_enabled = 1; + // else + // azt2316a->cur_mpu401_enabled = 0; - // cd_dma8 is hardcoded - //temp = (val >> 4) & 0x3; - //if (temp == 0) - // azt2316a->cur_cd_dma8 = -1; - //else if (temp == 1) - // azt2316a->cur_cd_dma8 = 0; - //else if (temp == 2) - // azt2316a->cur_cd_dma8 = 1; - //else if (temp == 3) - // azt2316a->cur_cd_dma8 = 3; + // cd_addr is hardcoded + // temp = (val >> 6) & 0x3; + // if (temp == 0) + // azt2316a->cur_cd_addr = 0x310; + // else if (temp == 1) + // azt2316a->cur_cd_addr = 0x320; + // else if (temp == 2) + // azt2316a->cur_cd_addr = 0x340; + // else if (temp == 3) + // azt2316a->cur_cd_addr = 0x350; + break; + case 2: + azt2316a->config_word = (azt2316a->config_word & 0xFF00FFFF) + (val << 16); - // cd_dma16 is hardcoded - //temp = (val >> 6) & 0x3; - //if (temp == 0) - // azt2316a->cur_cd_dma16 = -1; - //else if (temp == 1) - // azt2316a->cur_cd_dma16 = 5; - //else if (temp == 2) - // azt2316a->cur_cd_dma16 = 6; - //else if (temp == 3) - // azt2316a->cur_cd_dma16 = 7; - break; - case 3:azt2316a->config_word = (azt2316a->config_word & 0x00FFFFFF) + (val << 24); + // cd_type is hardcoded + // azt2316a->cur_cd_type = val & 0x7; - if (val & 0x1) - azt2316a->cur_mpu401_irq = 2; - else if (val & 0x2) - azt2316a->cur_mpu401_irq = 5; - else if (val & 0x4) - azt2316a->cur_mpu401_irq = 7; - else if (val & 0x8) - azt2316a->cur_mpu401_irq = 10; - // else undefined? + // cd_dma8 is hardcoded + // temp = (val >> 4) & 0x3; + // if (temp == 0) + // azt2316a->cur_cd_dma8 = -1; + // else if (temp == 1) + // azt2316a->cur_cd_dma8 = 0; + // else if (temp == 2) + // azt2316a->cur_cd_dma8 = 1; + // else if (temp == 3) + // azt2316a->cur_cd_dma8 = 3; - // cd_irq is hardcoded - //if (val & 0x10) - // azt2316a->cur_cd_irq = 5; - //else if (val & 0x20) - // azt2316a->cur_cd_irq = 11; - //else if (val & 0x40) - // azt2316a->cur_cd_irq = 12; - //else if (val & 0x80) - // azt2316a->cur_cd_irq = 15; - // else undefined? - break; - } - // update sbprov2 configs - sb_dsp_setaddr(&azt2316a->sb->dsp, azt2316a->cur_addr); - sb_dsp_setirq(&azt2316a->sb->dsp, azt2316a->cur_irq); - sb_dsp_setdma8(&azt2316a->sb->dsp, azt2316a->cur_dma); + // cd_dma16 is hardcoded + // temp = (val >> 6) & 0x3; + // if (temp == 0) + // azt2316a->cur_cd_dma16 = -1; + // else if (temp == 1) + // azt2316a->cur_cd_dma16 = 5; + // else if (temp == 2) + // azt2316a->cur_cd_dma16 = 6; + // else if (temp == 3) + // azt2316a->cur_cd_dma16 = 7; + break; + case 3: + azt2316a->config_word = (azt2316a->config_word & 0x00FFFFFF) + (val << 24); - mpu401_uart_update_addr(&azt2316a->sb->mpu, azt2316a->cur_mpu401_addr); - mpu401_uart_update_irq(&azt2316a->sb->mpu, azt2316a->cur_mpu401_irq); - } + if (val & 0x1) + azt2316a->cur_mpu401_irq = 2; + else if (val & 0x2) + azt2316a->cur_mpu401_irq = 5; + else if (val & 0x4) + azt2316a->cur_mpu401_irq = 7; + else if (val & 0x8) + azt2316a->cur_mpu401_irq = 10; + // else undefined? + + // cd_irq is hardcoded + // if (val & 0x10) + // azt2316a->cur_cd_irq = 5; + // else if (val & 0x20) + // azt2316a->cur_cd_irq = 11; + // else if (val & 0x40) + // azt2316a->cur_cd_irq = 12; + // else if (val & 0x80) + // azt2316a->cur_cd_irq = 15; + // else undefined? + break; + } + // update sbprov2 configs + sb_dsp_setaddr(&azt2316a->sb->dsp, azt2316a->cur_addr); + sb_dsp_setirq(&azt2316a->sb->dsp, azt2316a->cur_irq); + sb_dsp_setdma8(&azt2316a->sb->dsp, azt2316a->cur_dma); + + mpu401_uart_update_addr(&azt2316a->sb->mpu, azt2316a->cur_mpu401_addr); + mpu401_uart_update_irq(&azt2316a->sb->mpu, azt2316a->cur_mpu401_irq); + } } -// How it behaves when one or another is activated may affect games auto-detecting (and will also use more of the limited system resources!) +// How it behaves when one or another is activated may affect games auto-detecting (and will also use more of the limited system +// resources!) void azt2316a_enable_wss(uint8_t enable, void *p) { - azt2316a_t *azt2316a = (azt2316a_t *)p; + azt2316a_t *azt2316a = (azt2316a_t *)p; - if (enable) { - azt2316a->cur_mode = 1; - if (!azt2316a->cur_wss_enabled) { -// apparently it doesn't work like this! -// azt2316a->cur_wss_enabled = 1; -// azt2316a->config_word |= 1 << 10; - } - } else { - azt2316a->cur_mode = 0; - if (azt2316a->cur_wss_enabled) { -// apparently it doesn't work like this! -// azt2316a->cur_wss_enabled = 0; -// azt2316a->config_word &= 0xFFFFFFFF - (1 << 10); - } - } + if (enable) { + azt2316a->cur_mode = 1; + if (!azt2316a->cur_wss_enabled) { + // apparently it doesn't work like this! + // azt2316a->cur_wss_enabled = 1; + // azt2316a->config_word |= 1 << 10; + } + } else { + azt2316a->cur_mode = 0; + if (azt2316a->cur_wss_enabled) { + // apparently it doesn't work like this! + // azt2316a->cur_wss_enabled = 0; + // azt2316a->config_word &= 0xFFFFFFFF - (1 << 10); + } + } } static void azt2316a_get_buffer(int32_t *buffer, int len, void *p) { - azt2316a_t *azt2316a = (azt2316a_t *)p; + azt2316a_t *azt2316a = (azt2316a_t *)p; - int c; + int c; - // wss part - ad1848_update(&azt2316a->ad1848); - for (c = 0; c < len * 2; c++) { - buffer[c] += (azt2316a->ad1848.buffer[c] / 2); - } + // wss part + ad1848_update(&azt2316a->ad1848); + for (c = 0; c < len * 2; c++) { + buffer[c] += (azt2316a->ad1848.buffer[c] / 2); + } - azt2316a->ad1848.pos = 0; + azt2316a->ad1848.pos = 0; - // sbprov2 part - sb_get_buffer_sbpro(buffer, len, azt2316a->sb); + // sbprov2 part + sb_get_buffer_sbpro(buffer, len, azt2316a->sb); } void *azt_common_init(const int type, char *nvr_filename) { - int i; - int loaded_from_eeprom = 0; - uint16_t addr_setting; - uint8_t read_eeprom[AZTECH_EEPROM_SIZE]; - azt2316a_t *azt2316a = malloc(sizeof(azt2316a_t)); - memset(azt2316a, 0, sizeof(azt2316a_t)); + int i; + int loaded_from_eeprom = 0; + uint16_t addr_setting; + uint8_t read_eeprom[AZTECH_EEPROM_SIZE]; + azt2316a_t *azt2316a = malloc(sizeof(azt2316a_t)); + memset(azt2316a, 0, sizeof(azt2316a_t)); - // load configs from eeprom - FILE *f; - f = nvrfopen(nvr_filename, "rb"); - if (f) { - uint8_t checksum = 0x7F; - uint8_t saved_checksum; - size_t res; // avoid warning + // load configs from eeprom + FILE *f; + f = nvrfopen(nvr_filename, "rb"); + if (f) { + uint8_t checksum = 0x7F; + uint8_t saved_checksum; + size_t res; // avoid warning - res = fread(read_eeprom, AZTECH_EEPROM_SIZE, 1, f); - for (i = 0; i < AZTECH_EEPROM_SIZE; i++) - checksum += read_eeprom[i]; + res = fread(read_eeprom, AZTECH_EEPROM_SIZE, 1, f); + for (i = 0; i < AZTECH_EEPROM_SIZE; i++) + checksum += read_eeprom[i]; - res = fread(&saved_checksum, sizeof(saved_checksum), 1, f); - (void)res; + res = fread(&saved_checksum, sizeof(saved_checksum), 1, f); + (void)res; - fclose(f); + fclose(f); - if (checksum == saved_checksum) - loaded_from_eeprom = 1; - } + if (checksum == saved_checksum) + loaded_from_eeprom = 1; + } - // no eeprom saved or invalid checksum, load defaults - if (!loaded_from_eeprom) { - if (type == SB_SUBTYPE_CLONE_AZT2316A_0X11) { - read_eeprom[0] = 0x00; - read_eeprom[1] = 0x00; - read_eeprom[2] = 0x00; - read_eeprom[3] = 0x00; - read_eeprom[4] = 0x00; - read_eeprom[5] = 0x00; - read_eeprom[6] = 0x00; - read_eeprom[7] = 0x00; - read_eeprom[8] = 0x00; - read_eeprom[9] = 0x00; - read_eeprom[10] = 0x00; - read_eeprom[11] = 0x88; - read_eeprom[12] = 0xbc; - read_eeprom[13] = 0x00; - read_eeprom[14] = 0x01; - read_eeprom[15] = 0x00; - } else if (type == SB_SUBTYPE_CLONE_AZT1605_0X0C) { - read_eeprom[0] = 0x80; - read_eeprom[1] = 0x80; - read_eeprom[2] = 0x9F; - read_eeprom[3] = 0x13; - read_eeprom[4] = 0x16; - read_eeprom[5] = 0x13; - read_eeprom[6] = 0x00; - read_eeprom[7] = 0x00; - read_eeprom[8] = 0x16; - read_eeprom[9] = 0x0B; - read_eeprom[10] = 0x06; - read_eeprom[11] = 0x01; - read_eeprom[12] = 0x1C; - read_eeprom[13] = 0x14; - read_eeprom[14] = 0x04; - read_eeprom[15] = 0x1C; - } else - fatal("Aztech: unknown type %d\n", type); - } + // no eeprom saved or invalid checksum, load defaults + if (!loaded_from_eeprom) { + if (type == SB_SUBTYPE_CLONE_AZT2316A_0X11) { + read_eeprom[0] = 0x00; + read_eeprom[1] = 0x00; + read_eeprom[2] = 0x00; + read_eeprom[3] = 0x00; + read_eeprom[4] = 0x00; + read_eeprom[5] = 0x00; + read_eeprom[6] = 0x00; + read_eeprom[7] = 0x00; + read_eeprom[8] = 0x00; + read_eeprom[9] = 0x00; + read_eeprom[10] = 0x00; + read_eeprom[11] = 0x88; + read_eeprom[12] = 0xbc; + read_eeprom[13] = 0x00; + read_eeprom[14] = 0x01; + read_eeprom[15] = 0x00; + } else if (type == SB_SUBTYPE_CLONE_AZT1605_0X0C) { + read_eeprom[0] = 0x80; + read_eeprom[1] = 0x80; + read_eeprom[2] = 0x9F; + read_eeprom[3] = 0x13; + read_eeprom[4] = 0x16; + read_eeprom[5] = 0x13; + read_eeprom[6] = 0x00; + read_eeprom[7] = 0x00; + read_eeprom[8] = 0x16; + read_eeprom[9] = 0x0B; + read_eeprom[10] = 0x06; + read_eeprom[11] = 0x01; + read_eeprom[12] = 0x1C; + read_eeprom[13] = 0x14; + read_eeprom[14] = 0x04; + read_eeprom[15] = 0x1C; + } else + fatal("Aztech: unknown type %d\n", type); + } - // restore settings from EEPROM bytes - if (type == SB_SUBTYPE_CLONE_AZT2316A_0X11) { - azt2316a->config_word = read_eeprom[11] + (read_eeprom[12] << 8) + (read_eeprom[13] << 16) + (read_eeprom[14] << 24); - switch (azt2316a->config_word & (3 << 0)) { - case 0:azt2316a->cur_addr = 0x220; - break; - case 1:azt2316a->cur_addr = 0x240; - break; - default:fatal("AZT2316A: invalid sb addr in config word %08X\n", azt2316a->config_word); - } + // restore settings from EEPROM bytes + if (type == SB_SUBTYPE_CLONE_AZT2316A_0X11) { + azt2316a->config_word = + read_eeprom[11] + (read_eeprom[12] << 8) + (read_eeprom[13] << 16) + (read_eeprom[14] << 24); + switch (azt2316a->config_word & (3 << 0)) { + case 0: + azt2316a->cur_addr = 0x220; + break; + case 1: + azt2316a->cur_addr = 0x240; + break; + default: + fatal("AZT2316A: invalid sb addr in config word %08X\n", azt2316a->config_word); + } - if (azt2316a->config_word & (1 << 2)) - azt2316a->cur_irq = 2; - else if (azt2316a->config_word & (1 << 3)) - azt2316a->cur_irq = 5; - else if (azt2316a->config_word & (1 << 4)) - azt2316a->cur_irq = 7; - else if (azt2316a->config_word & (1 << 5)) - azt2316a->cur_irq = 10; - else - fatal("AZT2316A: invalid sb irq in config word %08X\n", azt2316a->config_word); + if (azt2316a->config_word & (1 << 2)) + azt2316a->cur_irq = 2; + else if (azt2316a->config_word & (1 << 3)) + azt2316a->cur_irq = 5; + else if (azt2316a->config_word & (1 << 4)) + azt2316a->cur_irq = 7; + else if (azt2316a->config_word & (1 << 5)) + azt2316a->cur_irq = 10; + else + fatal("AZT2316A: invalid sb irq in config word %08X\n", azt2316a->config_word); - switch (azt2316a->config_word & (3 << 6)) { - case 1 << 6:azt2316a->cur_dma = 0; - break; - case 2 << 6:azt2316a->cur_dma = 1; - break; - case 3 << 6:azt2316a->cur_dma = 3; - break; - default:fatal("AZT2316A: invalid sb dma in config word %08X\n", azt2316a->config_word); - } + switch (azt2316a->config_word & (3 << 6)) { + case 1 << 6: + azt2316a->cur_dma = 0; + break; + case 2 << 6: + azt2316a->cur_dma = 1; + break; + case 3 << 6: + azt2316a->cur_dma = 3; + break; + default: + fatal("AZT2316A: invalid sb dma in config word %08X\n", azt2316a->config_word); + } - switch (azt2316a->config_word & (3 << 8)) { - case 0:azt2316a->cur_wss_addr = 0x530; - break; - case 1 << 8:azt2316a->cur_wss_addr = 0x604; - break; - case 2 << 8:azt2316a->cur_wss_addr = 0xE80; - break; - case 3 << 8:azt2316a->cur_wss_addr = 0xF40; - break; - default:fatal("AZT2316A: invalid wss addr in config word %08X\n", azt2316a->config_word); - } + switch (azt2316a->config_word & (3 << 8)) { + case 0: + azt2316a->cur_wss_addr = 0x530; + break; + case 1 << 8: + azt2316a->cur_wss_addr = 0x604; + break; + case 2 << 8: + azt2316a->cur_wss_addr = 0xE80; + break; + case 3 << 8: + azt2316a->cur_wss_addr = 0xF40; + break; + default: + fatal("AZT2316A: invalid wss addr in config word %08X\n", azt2316a->config_word); + } - if (azt2316a->config_word & (1 << 10)) - azt2316a->cur_wss_enabled = 1; - else - azt2316a->cur_wss_enabled = 0; + if (azt2316a->config_word & (1 << 10)) + azt2316a->cur_wss_enabled = 1; + else + azt2316a->cur_wss_enabled = 0; - // game_enabled is hardcoded - //if (azt2316a->config_word & (1 << 11)) - // azt2316a->cur_game_enabled = 1; - //else - // azt2316a->cur_game_enabled = 0; + // game_enabled is hardcoded + // if (azt2316a->config_word & (1 << 11)) + // azt2316a->cur_game_enabled = 1; + // else + // azt2316a->cur_game_enabled = 0; - if (azt2316a->config_word & (1 << 12)) - azt2316a->cur_mpu401_addr = 0x330; - else - azt2316a->cur_mpu401_addr = 0x300; + if (azt2316a->config_word & (1 << 12)) + azt2316a->cur_mpu401_addr = 0x330; + else + azt2316a->cur_mpu401_addr = 0x300; - // mpu401_enabled is hardcoded - //if (azt2316a->config_word & (1 << 13)) - // azt2316a->cur_mpu401_enabled = 1; - //else - // azt2316a->cur_mpu401_enabled = 0; + // mpu401_enabled is hardcoded + // if (azt2316a->config_word & (1 << 13)) + // azt2316a->cur_mpu401_enabled = 1; + // else + // azt2316a->cur_mpu401_enabled = 0; - // cd_addr is hardcoded - //switch (azt2316a->config_word & (3 << 14)) - //{ - // case 0: - // azt2316a->cur_cd_addr = 0x310; - // break; - // case 1 << 14: - // azt2316a->cur_cd_addr = 0x320; - // break; - // case 2 << 14: - // azt2316a->cur_cd_addr = 0x340; - // break; - // case 3 << 14: - // azt2316a->cur_cd_addr = 0x350; - // break; - // default: - // fatal("AZT2316A: invalid cd addr in config word %08X\n", azt2316a->config_word); - //} + // cd_addr is hardcoded + // switch (azt2316a->config_word & (3 << 14)) + //{ + // case 0: + // azt2316a->cur_cd_addr = 0x310; + // break; + // case 1 << 14: + // azt2316a->cur_cd_addr = 0x320; + // break; + // case 2 << 14: + // azt2316a->cur_cd_addr = 0x340; + // break; + // case 3 << 14: + // azt2316a->cur_cd_addr = 0x350; + // break; + // default: + // fatal("AZT2316A: invalid cd addr in config word %08X\n", azt2316a->config_word); + //} - // cd_type is hardcoded - //azt2316a->cur_cd_type = (azt2316a->config_word >> 16) & 0x7; + // cd_type is hardcoded + // azt2316a->cur_cd_type = (azt2316a->config_word >> 16) & 0x7; - // cd_dma8 is hardcoded - //switch (azt2316a->config_word & (3 << 20)) - //{ - // case 0: - // azt2316a->cur_cd_dma8 = -1; - // break; - // case 1 << 20: - // azt2316a->cur_cd_dma8 = 0; - // break; - // case 2 << 20: - // azt2316a->cur_cd_dma8 = 1; - // break; - // case 3 << 20: - // azt2316a->cur_cd_dma8 = 3; - // break; - // default: - // fatal("AZT2316A: invalid cd dma8 in config word %08X\n", azt2316a->config_word); - //} + // cd_dma8 is hardcoded + // switch (azt2316a->config_word & (3 << 20)) + //{ + // case 0: + // azt2316a->cur_cd_dma8 = -1; + // break; + // case 1 << 20: + // azt2316a->cur_cd_dma8 = 0; + // break; + // case 2 << 20: + // azt2316a->cur_cd_dma8 = 1; + // break; + // case 3 << 20: + // azt2316a->cur_cd_dma8 = 3; + // break; + // default: + // fatal("AZT2316A: invalid cd dma8 in config word %08X\n", azt2316a->config_word); + //} - // cd_dma16 is hardcoded - //switch (azt2316a->config_word & (3 << 22)) - //{ - // case 0: - // azt2316a->cur_cd_dma16 = -1; - // break; - // case 1 << 22: - // azt2316a->cur_cd_dma16 = 5; - // break; - // case 2 << 22: - // azt2316a->cur_cd_dma16 = 6; - // break; - // case 3 << 22: - // azt2316a->cur_cd_dma16 = 7; - // break; - // default: - // fatal("AZT2316A: invalid cd dma16 in config word %08X\n", azt2316a->config_word); - //} + // cd_dma16 is hardcoded + // switch (azt2316a->config_word & (3 << 22)) + //{ + // case 0: + // azt2316a->cur_cd_dma16 = -1; + // break; + // case 1 << 22: + // azt2316a->cur_cd_dma16 = 5; + // break; + // case 2 << 22: + // azt2316a->cur_cd_dma16 = 6; + // break; + // case 3 << 22: + // azt2316a->cur_cd_dma16 = 7; + // break; + // default: + // fatal("AZT2316A: invalid cd dma16 in config word %08X\n", azt2316a->config_word); + //} - if (azt2316a->config_word & (1 << 24)) - azt2316a->cur_mpu401_irq = 2; - else if (azt2316a->config_word & (1 << 25)) - azt2316a->cur_mpu401_irq = 5; - else if (azt2316a->config_word & (1 << 26)) - azt2316a->cur_mpu401_irq = 7; - else if (azt2316a->config_word & (1 << 27)) - azt2316a->cur_mpu401_irq = 10; - else - fatal("AZT2316A: invalid mpu401 irq in config word %08X\n", azt2316a->config_word); + if (azt2316a->config_word & (1 << 24)) + azt2316a->cur_mpu401_irq = 2; + else if (azt2316a->config_word & (1 << 25)) + azt2316a->cur_mpu401_irq = 5; + else if (azt2316a->config_word & (1 << 26)) + azt2316a->cur_mpu401_irq = 7; + else if (azt2316a->config_word & (1 << 27)) + azt2316a->cur_mpu401_irq = 10; + else + fatal("AZT2316A: invalid mpu401 irq in config word %08X\n", azt2316a->config_word); - // cd_irq is hardcoded - //if (azt2316a->config_word & (1 << 28)) - // azt2316a->cur_cd_irq = 5; - //else if (azt2316a->config_word & (1 << 29)) - // azt2316a->cur_cd_irq = 11; - //else if (azt2316a->config_word & (1 << 30)) - // azt2316a->cur_cd_irq = 12; - //else if (azt2316a->config_word & (1 << 31)) - // azt2316a->cur_cd_irq = 15; - //else - // fatal("AZT2316A: invalid cd irq in config word %08X\n", azt2316a->config_word); + // cd_irq is hardcoded + // if (azt2316a->config_word & (1 << 28)) + // azt2316a->cur_cd_irq = 5; + // else if (azt2316a->config_word & (1 << 29)) + // azt2316a->cur_cd_irq = 11; + // else if (azt2316a->config_word & (1 << 30)) + // azt2316a->cur_cd_irq = 12; + // else if (azt2316a->config_word & (1 << 31)) + // azt2316a->cur_cd_irq = 15; + // else + // fatal("AZT2316A: invalid cd irq in config word %08X\n", azt2316a->config_word); - // these are not present on the EEPROM - azt2316a->cur_wss_irq = 10; - azt2316a->cur_wss_dma = 0; - azt2316a->cur_mode = 0; - } else if (type == SB_SUBTYPE_CLONE_AZT1605_0X0C) { - azt2316a->config_word = read_eeprom[12] + (read_eeprom[13] << 8) + (read_eeprom[14] << 16); - switch (azt2316a->config_word & (3 << 0)) { - case 0:azt2316a->cur_addr = 0x220; - break; - case 1:azt2316a->cur_addr = 0x240; - break; - default:fatal("AZT1605: invalid sb addr in config word %08X\n", azt2316a->config_word); - } + // these are not present on the EEPROM + azt2316a->cur_wss_irq = 10; + azt2316a->cur_wss_dma = 0; + azt2316a->cur_mode = 0; + } else if (type == SB_SUBTYPE_CLONE_AZT1605_0X0C) { + azt2316a->config_word = read_eeprom[12] + (read_eeprom[13] << 8) + (read_eeprom[14] << 16); + switch (azt2316a->config_word & (3 << 0)) { + case 0: + azt2316a->cur_addr = 0x220; + break; + case 1: + azt2316a->cur_addr = 0x240; + break; + default: + fatal("AZT1605: invalid sb addr in config word %08X\n", azt2316a->config_word); + } - if (azt2316a->config_word & (1 << 2)) - azt2316a->cur_mpu401_addr = 0x330; - else - azt2316a->cur_mpu401_addr = 0x300; + if (azt2316a->config_word & (1 << 2)) + azt2316a->cur_mpu401_addr = 0x330; + else + azt2316a->cur_mpu401_addr = 0x300; - // mpu401_enabled is hardcoded - //if (azt2316a->config_word & (1 << 3)) - // azt2316a->cur_mpu401_enabled = 1; - //else - // azt2316a->cur_mpu401_enabled = 0; + // mpu401_enabled is hardcoded + // if (azt2316a->config_word & (1 << 3)) + // azt2316a->cur_mpu401_enabled = 1; + // else + // azt2316a->cur_mpu401_enabled = 0; - // game_enabled is hardcoded - //if (azt2316a->config_word & (1 << 4)) - // azt2316a->cur_game_enabled = 1; - //else - // azt2316a->cur_game_enabled = 0; + // game_enabled is hardcoded + // if (azt2316a->config_word & (1 << 4)) + // azt2316a->cur_game_enabled = 1; + // else + // azt2316a->cur_game_enabled = 0; - // cd_type is hardcoded - //azt2316a->cur_cd_type = (azt2316a->config_word >> 5) & 0x7; + // cd_type is hardcoded + // azt2316a->cur_cd_type = (azt2316a->config_word >> 5) & 0x7; - if (azt2316a->config_word & (1 << 8)) - azt2316a->cur_irq = 2; - else if (azt2316a->config_word & (1 << 9)) - azt2316a->cur_irq = 3; - else if (azt2316a->config_word & (1 << 10)) - azt2316a->cur_irq = 5; - else if (azt2316a->config_word & (1 << 11)) - azt2316a->cur_irq = 7; - else - fatal("AZT1605: invalid sb irq in config word %08X\n", azt2316a->config_word); + if (azt2316a->config_word & (1 << 8)) + azt2316a->cur_irq = 2; + else if (azt2316a->config_word & (1 << 9)) + azt2316a->cur_irq = 3; + else if (azt2316a->config_word & (1 << 10)) + azt2316a->cur_irq = 5; + else if (azt2316a->config_word & (1 << 11)) + azt2316a->cur_irq = 7; + else + fatal("AZT1605: invalid sb irq in config word %08X\n", azt2316a->config_word); - if (azt2316a->config_word & (1 << 12)) - azt2316a->cur_mpu401_irq = 2; - else if (azt2316a->config_word & (1 << 13)) - azt2316a->cur_mpu401_irq = 3; - else if (azt2316a->config_word & (1 << 14)) - azt2316a->cur_mpu401_irq = 5; - else if (azt2316a->config_word & (1 << 15)) - azt2316a->cur_mpu401_irq = 7; - else - fatal("AZT1605: invalid mpu401 irq in config word %08X\n", azt2316a->config_word); + if (azt2316a->config_word & (1 << 12)) + azt2316a->cur_mpu401_irq = 2; + else if (azt2316a->config_word & (1 << 13)) + azt2316a->cur_mpu401_irq = 3; + else if (azt2316a->config_word & (1 << 14)) + azt2316a->cur_mpu401_irq = 5; + else if (azt2316a->config_word & (1 << 15)) + azt2316a->cur_mpu401_irq = 7; + else + fatal("AZT1605: invalid mpu401 irq in config word %08X\n", azt2316a->config_word); - switch (azt2316a->config_word & (3 << 16)) { - case 0:azt2316a->cur_wss_addr = 0x530; - break; - case 1 << 16:azt2316a->cur_wss_addr = 0x604; - break; - case 2 << 16:azt2316a->cur_wss_addr = 0xE80; - break; - case 3 << 16:azt2316a->cur_wss_addr = 0xF40; - break; - default:fatal("AZT1605: invalid wss addr in config word %08X\n", azt2316a->config_word); - } + switch (azt2316a->config_word & (3 << 16)) { + case 0: + azt2316a->cur_wss_addr = 0x530; + break; + case 1 << 16: + azt2316a->cur_wss_addr = 0x604; + break; + case 2 << 16: + azt2316a->cur_wss_addr = 0xE80; + break; + case 3 << 16: + azt2316a->cur_wss_addr = 0xF40; + break; + default: + fatal("AZT1605: invalid wss addr in config word %08X\n", azt2316a->config_word); + } - if (azt2316a->config_word & (1 << 18)) - azt2316a->cur_wss_enabled = 1; - else - azt2316a->cur_wss_enabled = 0; + if (azt2316a->config_word & (1 << 18)) + azt2316a->cur_wss_enabled = 1; + else + azt2316a->cur_wss_enabled = 0; - // cd_irq is hardcoded - //if (azt2316a->config_word & (1 << 19)) - // azt2316a->cur_cd_irq = 11; - //else if (azt2316a->config_word & (1 << 20)) - // azt2316a->cur_cd_irq = 12; - //else if (azt2316a->config_word & (1 << 21)) - // azt2316a->cur_cd_irq = 15; - //else - // fatal("AZT1605: invalid cd irq in config word %08X\n", azt2316a->config_word); + // cd_irq is hardcoded + // if (azt2316a->config_word & (1 << 19)) + // azt2316a->cur_cd_irq = 11; + // else if (azt2316a->config_word & (1 << 20)) + // azt2316a->cur_cd_irq = 12; + // else if (azt2316a->config_word & (1 << 21)) + // azt2316a->cur_cd_irq = 15; + // else + // fatal("AZT1605: invalid cd irq in config word %08X\n", azt2316a->config_word); - // cd_dma8 is hardcoded - //switch (azt2316a->config_word & (3 << 22)) - //{ - // case 0: - // azt2316a->cur_cd_dma8 = -1; - // break; - // case 1 << 22: - // azt2316a->cur_cd_dma8 = 0; - // break; - // case 2 << 22: - // azt2316a->cur_cd_dma8 = 1; - // break; - // case 3 << 22: - // azt2316a->cur_cd_dma8 = 3; - // break; - // default: - // fatal("AZT1605: invalid cd dma8 in config word %08X\n", azt2316a->config_word); - //} + // cd_dma8 is hardcoded + // switch (azt2316a->config_word & (3 << 22)) + //{ + // case 0: + // azt2316a->cur_cd_dma8 = -1; + // break; + // case 1 << 22: + // azt2316a->cur_cd_dma8 = 0; + // break; + // case 2 << 22: + // azt2316a->cur_cd_dma8 = 1; + // break; + // case 3 << 22: + // azt2316a->cur_cd_dma8 = 3; + // break; + // default: + // fatal("AZT1605: invalid cd dma8 in config word %08X\n", azt2316a->config_word); + //} - // these are not present on the EEPROM - azt2316a->cur_dma = 1; // TODO: investigate TSR to make this work with it - there is no software configurable DMA8? - azt2316a->cur_wss_irq = 10; - azt2316a->cur_wss_dma = 0; - azt2316a->cur_mode = 0; - } else - fatal("Aztech: unknown type %d\n", type); + // these are not present on the EEPROM + azt2316a->cur_dma = + 1; // TODO: investigate TSR to make this work with it - there is no software configurable DMA8? + azt2316a->cur_wss_irq = 10; + azt2316a->cur_wss_dma = 0; + azt2316a->cur_mode = 0; + } else + fatal("Aztech: unknown type %d\n", type); - // check for sb addr override jumper - addr_setting = device_get_config_int("addr"); - if (addr_setting) - azt2316a->cur_addr = addr_setting; + // check for sb addr override jumper + addr_setting = device_get_config_int("addr"); + if (addr_setting) + azt2316a->cur_addr = addr_setting; - // now we can continue initializing - azt2316a->opl_emu = device_get_config_int("opl_emu"); - azt2316a->wss_interrupt_after_config = device_get_config_int("wss_interrupt_after_config"); + // now we can continue initializing + azt2316a->opl_emu = device_get_config_int("opl_emu"); + azt2316a->wss_interrupt_after_config = device_get_config_int("wss_interrupt_after_config"); - azt2316a->type = type; + azt2316a->type = type; - // wss part - ad1848_init(&azt2316a->ad1848, device_get_config_int("codec")); + // wss part + ad1848_init(&azt2316a->ad1848, device_get_config_int("codec")); - ad1848_setirq(&azt2316a->ad1848, azt2316a->cur_wss_irq); - ad1848_setdma(&azt2316a->ad1848, azt2316a->cur_wss_dma); + ad1848_setirq(&azt2316a->ad1848, azt2316a->cur_wss_irq); + ad1848_setdma(&azt2316a->ad1848, azt2316a->cur_wss_dma); - io_sethandler(azt2316a->cur_addr + 0x0400, 0x0040, azt2316a_config_read, NULL, NULL, azt2316a_config_write, NULL, NULL, azt2316a); - io_sethandler(azt2316a->cur_wss_addr, 0x0004, azt2316a_wss_read, NULL, NULL, azt2316a_wss_write, NULL, NULL, azt2316a); - io_sethandler(azt2316a->cur_wss_addr + 0x0004, 0x0004, ad1848_read, NULL, NULL, ad1848_write, NULL, NULL, &azt2316a->ad1848); + io_sethandler(azt2316a->cur_addr + 0x0400, 0x0040, azt2316a_config_read, NULL, NULL, azt2316a_config_write, NULL, NULL, + azt2316a); + io_sethandler(azt2316a->cur_wss_addr, 0x0004, azt2316a_wss_read, NULL, NULL, azt2316a_wss_write, NULL, NULL, azt2316a); + io_sethandler(azt2316a->cur_wss_addr + 0x0004, 0x0004, ad1848_read, NULL, NULL, ad1848_write, NULL, NULL, + &azt2316a->ad1848); - // sbprov2 part - /*sbpro port mappings. 220h or 240h. - 2x0 to 2x3 -> FM chip (18 voices) - 2x4 to 2x5 -> Mixer interface - 2x6, 2xA, 2xC, 2xE -> DSP chip + // sbprov2 part + /*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).*/ - azt2316a->sb = malloc(sizeof(sb_t)); - memset(azt2316a->sb, 0, sizeof(sb_t)); + 2x8, 2x9, 388 and 389 FM chip (9 voices).*/ + azt2316a->sb = malloc(sizeof(sb_t)); + memset(azt2316a->sb, 0, sizeof(sb_t)); - for (i = 0; i < AZTECH_EEPROM_SIZE; i++) - azt2316a->sb->dsp.azt_eeprom[i] = read_eeprom[i]; + for (i = 0; i < AZTECH_EEPROM_SIZE; i++) + azt2316a->sb->dsp.azt_eeprom[i] = read_eeprom[i]; - azt2316a->sb->opl_emu = azt2316a->opl_emu; - opl3_init(&azt2316a->sb->opl, azt2316a->sb->opl_emu); - sb_dsp_init(&azt2316a->sb->dsp, SBPRO2, azt2316a->type, azt2316a); - sb_dsp_setaddr(&azt2316a->sb->dsp, azt2316a->cur_addr); - sb_dsp_setirq(&azt2316a->sb->dsp, azt2316a->cur_irq); - sb_dsp_setdma8(&azt2316a->sb->dsp, azt2316a->cur_dma); - sb_ct1345_mixer_reset(azt2316a->sb); - /* DSP I/O handler is activated in sb_dsp_setaddr */ - io_sethandler(azt2316a->cur_addr + 0, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &azt2316a->sb->opl); - io_sethandler(azt2316a->cur_addr + 8, 0x0002, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &azt2316a->sb->opl); - io_sethandler(0x0388, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &azt2316a->sb->opl); - io_sethandler(azt2316a->cur_addr + 4, 0x0002, sb_ct1345_mixer_read, NULL, NULL, sb_ct1345_mixer_write, NULL, NULL, azt2316a->sb); - mpu401_uart_init(&azt2316a->sb->mpu, azt2316a->cur_mpu401_addr, azt2316a->cur_mpu401_irq, 1); + azt2316a->sb->opl_emu = azt2316a->opl_emu; + opl3_init(&azt2316a->sb->opl, azt2316a->sb->opl_emu); + sb_dsp_init(&azt2316a->sb->dsp, SBPRO2, azt2316a->type, azt2316a); + sb_dsp_setaddr(&azt2316a->sb->dsp, azt2316a->cur_addr); + sb_dsp_setirq(&azt2316a->sb->dsp, azt2316a->cur_irq); + sb_dsp_setdma8(&azt2316a->sb->dsp, azt2316a->cur_dma); + sb_ct1345_mixer_reset(azt2316a->sb); + /* DSP I/O handler is activated in sb_dsp_setaddr */ + io_sethandler(azt2316a->cur_addr + 0, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &azt2316a->sb->opl); + io_sethandler(azt2316a->cur_addr + 8, 0x0002, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &azt2316a->sb->opl); + io_sethandler(0x0388, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &azt2316a->sb->opl); + io_sethandler(azt2316a->cur_addr + 4, 0x0002, sb_ct1345_mixer_read, NULL, NULL, sb_ct1345_mixer_write, NULL, NULL, + azt2316a->sb); + mpu401_uart_init(&azt2316a->sb->mpu, azt2316a->cur_mpu401_addr, azt2316a->cur_mpu401_irq, 1); - azt2316a_create_config_word(azt2316a); // recreate even if we have read it from EEPROM, because we have some overrides (CD interfaces always off, etc) - sound_add_handler(azt2316a_get_buffer, azt2316a); + azt2316a_create_config_word(azt2316a); // recreate even if we have read it from EEPROM, because we have some overrides (CD + // interfaces always off, etc) + sound_add_handler(azt2316a_get_buffer, azt2316a); - return azt2316a; + return azt2316a; } -void *azt2316a_init() { - return azt_common_init(SB_SUBTYPE_CLONE_AZT2316A_0X11, "azt2316a.nvr"); -} +void *azt2316a_init() { return azt_common_init(SB_SUBTYPE_CLONE_AZT2316A_0X11, "azt2316a.nvr"); } -void *azt1605_init() { - return azt_common_init(SB_SUBTYPE_CLONE_AZT1605_0X0C, "azt1605.nvr"); -} +void *azt1605_init() { return azt_common_init(SB_SUBTYPE_CLONE_AZT1605_0X0C, "azt1605.nvr"); } void azt_common_close(void *p, char *nvr_filename) { - azt2316a_t *azt2316a = (azt2316a_t *)p; - int i; - uint8_t checksum = 0x7F; + azt2316a_t *azt2316a = (azt2316a_t *)p; + int i; + uint8_t checksum = 0x7F; - // always save to eeprom (recover from bad values) - FILE *f = nvrfopen(nvr_filename, "wb"); - if (f) { - for (i = 0; i < AZTECH_EEPROM_SIZE; i++) - checksum += azt2316a->sb->dsp.azt_eeprom[i]; - fwrite(azt2316a->sb->dsp.azt_eeprom, AZTECH_EEPROM_SIZE, 1, f); + // always save to eeprom (recover from bad values) + FILE *f = nvrfopen(nvr_filename, "wb"); + if (f) { + for (i = 0; i < AZTECH_EEPROM_SIZE; i++) + checksum += azt2316a->sb->dsp.azt_eeprom[i]; + fwrite(azt2316a->sb->dsp.azt_eeprom, AZTECH_EEPROM_SIZE, 1, f); - // TODO: confirm any models saving mixer settings to EEPROM and implement reading back - // TODO: should remember to save wss duplex setting if PCem has voice recording implemented in the future? Also, default azt2316a->wss_config - // TODO: azt2316a->cur_mode is not saved to EEPROM? - fwrite(&checksum, sizeof(checksum), 1, f); + // TODO: confirm any models saving mixer settings to EEPROM and implement reading back + // TODO: should remember to save wss duplex setting if PCem has voice recording implemented in the future? Also, + // default azt2316a->wss_config + // TODO: azt2316a->cur_mode is not saved to EEPROM? + fwrite(&checksum, sizeof(checksum), 1, f); - fclose(f); - } + fclose(f); + } - sb_close(azt2316a->sb); + sb_close(azt2316a->sb); - free(azt2316a); + free(azt2316a); } -void azt2316a_close(void *p) { - azt_common_close(p, "azt2316a.nvr"); -} +void azt2316a_close(void *p) { azt_common_close(p, "azt2316a.nvr"); } -void azt1605_close(void *p) { - azt_common_close(p, "azt1605.nvr"); -} +void azt1605_close(void *p) { azt_common_close(p, "azt1605.nvr"); } void azt2316a_speed_changed(void *p) { - azt2316a_t *azt2316a = (azt2316a_t *)p; + azt2316a_t *azt2316a = (azt2316a_t *)p; - ad1848_speed_changed(&azt2316a->ad1848); - sb_speed_changed(azt2316a->sb); + ad1848_speed_changed(&azt2316a->ad1848); + sb_speed_changed(azt2316a->sb); } void azt2316a_add_status_info(char *s, int max_len, void *p) { - azt2316a_t *azt2316a = (azt2316a_t *)p; + azt2316a_t *azt2316a = (azt2316a_t *)p; - sb_dsp_add_status_info(s, max_len, &azt2316a->sb->dsp); + sb_dsp_add_status_info(s, max_len, &azt2316a->sb->dsp); } -static device_config_t azt2316a_config[] = - { - { - .name = "codec", - .description = "CODEC", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "CS4248", - .value = AD1848_TYPE_CS4248 - }, - { - .description = "CS4231", - .value = AD1848_TYPE_CS4231 - }, - }, - .default_int = AD1848_TYPE_CS4248 - }, - { - .name = "wss_interrupt_after_config", - .description = "Raise CODEC interrupt on CODEC setup (needed by some drivers)", - .type = CONFIG_BINARY, - .default_int = 0 - }, - { - .name = "addr", - .description = "SB Address", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "0x220", - .value = 0x220 - }, - { - .description = "0x240", - .value = 0x240 - }, - { - .description = "Use EEPROM setting", - .value = 0 - }, - { - .description = "" - } - }, - .default_int = 0 - }, - { - .name = "midi", - .description = "MIDI out device", - .type = CONFIG_MIDI, - .default_int = 0 - }, - { - .name = "opl_emu", - .description = "OPL emulator", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "DBOPL", - .value = OPL_DBOPL - }, - { - .description = "NukedOPL", - .value = OPL_NUKED - }, - }, - .default_int = OPL_DBOPL - }, - { - .type = -1 - } - }; +static device_config_t azt2316a_config[] = { + {.name = "codec", + .description = "CODEC", + .type = CONFIG_SELECTION, + .selection = + { + {.description = "CS4248", .value = AD1848_TYPE_CS4248}, + {.description = "CS4231", .value = AD1848_TYPE_CS4231}, + }, + .default_int = AD1848_TYPE_CS4248}, + {.name = "wss_interrupt_after_config", + .description = "Raise CODEC interrupt on CODEC setup (needed by some drivers)", + .type = CONFIG_BINARY, + .default_int = 0}, + {.name = "addr", + .description = "SB Address", + .type = CONFIG_SELECTION, + .selection = {{.description = "0x220", .value = 0x220}, + {.description = "0x240", .value = 0x240}, + {.description = "Use EEPROM setting", .value = 0}, + {.description = ""}}, + .default_int = 0}, + {.name = "midi", .description = "MIDI out device", .type = CONFIG_MIDI, .default_int = 0}, + {.name = "opl_emu", + .description = "OPL emulator", + .type = CONFIG_SELECTION, + .selection = + { + {.description = "DBOPL", .value = OPL_DBOPL}, + {.description = "NukedOPL", .value = OPL_NUKED}, + }, + .default_int = OPL_DBOPL}, + {.type = -1}}; -device_t azt2316a_device = - { - "Aztech Sound Galaxy Pro 16 AB (Washington)", - 0, - azt2316a_init, - azt2316a_close, - NULL, - azt2316a_speed_changed, - NULL, - azt2316a_add_status_info, - azt2316a_config - }; +device_t azt2316a_device = {"Aztech Sound Galaxy Pro 16 AB (Washington)", + 0, + azt2316a_init, + azt2316a_close, + NULL, + azt2316a_speed_changed, + NULL, + azt2316a_add_status_info, + azt2316a_config}; -device_t azt1605_device = - { - "Aztech Sound Galaxy Nova 16 Extra (Clinton)", - DEVICE_NOT_WORKING, - azt1605_init, - azt1605_close, - NULL, - azt2316a_speed_changed, - NULL, - azt2316a_add_status_info, - azt2316a_config - }; +device_t azt1605_device = {"Aztech Sound Galaxy Nova 16 Extra (Clinton)", + DEVICE_NOT_WORKING, + azt1605_init, + azt1605_close, + NULL, + azt2316a_speed_changed, + NULL, + azt2316a_add_status_info, + azt2316a_config}; diff --git a/src/sound/sound_cms.c b/src/sound/sound_cms.c index 3898f5ac..30084ab6 100644 --- a/src/sound/sound_cms.c +++ b/src/sound/sound_cms.c @@ -10,185 +10,192 @@ #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]; + 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; + uint8_t latched_data; - int16_t buffer[MAXSOUNDBUFLEN * 2]; + int16_t buffer[MAXSOUNDBUFLEN * 2]; - int pos; + 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 (; 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; - } + 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; + cms_t *cms = (cms_t *)p; - int c; + int c; - cms_update(cms); + cms_update(cms); - for (c = 0; c < len * 2; c++) - buffer[c] += cms->buffer[c]; + for (c = 0; c < len * 2; c++) + buffer[c] += cms->buffer[c]; - cms->pos = 0; + 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; + cms_t *cms = (cms_t *)p; + int voice; + int chip = (addr & 2) >> 1; -// pclog("cms_write : addr %04X val %02X\n", addr, val); + // pclog("cms_write : addr %04X val %02X\n", addr, val); - switch (addr & 0xf) { - case 1:cms->addrs[0] = val & 31; - break; - case 3:cms->addrs[1] = val & 31; - break; + 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; - } + 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; + cms_t *cms = (cms_t *)p; -// pclog("cms_read : addr %04X\n", addr); - 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; + // pclog("cms_read : addr %04X\n", addr); + 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() { - cms_t *cms = malloc(sizeof(cms_t)); - memset(cms, 0, sizeof(cms_t)); + cms_t *cms = malloc(sizeof(cms_t)); + memset(cms, 0, sizeof(cms_t)); - pclog("cms_init\n"); - io_sethandler(0x0220, 0x0010, cms_read, NULL, NULL, cms_write, NULL, NULL, cms); - sound_add_handler(cms_get_buffer, cms); - return cms; + pclog("cms_init\n"); + 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; + cms_t *cms = (cms_t *)p; - free(cms); + free(cms); } -device_t cms_device = - { - "Creative Music System / Game Blaster", - 0, - cms_init, - cms_close, - NULL, - NULL, - NULL, - NULL - }; +device_t cms_device = {"Creative Music System / Game Blaster", 0, cms_init, cms_close, NULL, NULL, NULL, NULL}; diff --git a/src/sound/sound_dbopl.cc b/src/sound/sound_dbopl.cc index 2acf1b7d..a4cd256c 100644 --- a/src/sound/sound_dbopl.cc +++ b/src/sound/sound_dbopl.cc @@ -3,143 +3,139 @@ #include "sound_dbopl.h" static struct { - DBOPL::Chip chip; - struct opl3_chip opl3chip; - int addr; - int timer[2]; - uint8_t timer_ctrl; - uint8_t status_mask; - uint8_t status; - int is_opl3; - int opl_emu; + DBOPL::Chip chip; + struct opl3_chip opl3chip; + int addr; + int timer[2]; + uint8_t timer_ctrl; + uint8_t status_mask; + uint8_t status; + int is_opl3; + int opl_emu; - void (*timer_callback)(void *param, int timer, int64_t period); - void *timer_param; + 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 { 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 + 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, int opl_emu) { - if (!is_opl3 || !opl_emu) { - DBOPL::InitTables(); - opl[nr].chip.Setup(48000, is_opl3); - opl[nr].timer_callback = timer_callback; - opl[nr].timer_param = timer_param; - opl[nr].is_opl3 = is_opl3; - opl[nr].opl_emu = opl_emu; - } else { - OPL3_Reset(&opl[nr].opl3chip, 48000); - opl[nr].timer_callback = timer_callback; - opl[nr].timer_param = timer_param; - opl[nr].is_opl3 = is_opl3; - opl[nr].opl_emu = opl_emu; - } +void opl_init(void (*timer_callback)(void *param, int timer, int64_t period), void *timer_param, int nr, int is_opl3, + int opl_emu) { + if (!is_opl3 || !opl_emu) { + DBOPL::InitTables(); + opl[nr].chip.Setup(48000, is_opl3); + opl[nr].timer_callback = timer_callback; + opl[nr].timer_param = timer_param; + opl[nr].is_opl3 = is_opl3; + opl[nr].opl_emu = opl_emu; + } else { + OPL3_Reset(&opl[nr].opl3chip, 48000); + opl[nr].timer_callback = timer_callback; + opl[nr].timer_param = timer_param; + opl[nr].is_opl3 = is_opl3; + opl[nr].opl_emu = opl_emu; + } } 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; + 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); - } + 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); + opl_status_update(nr); } void opl_write(int nr, uint16_t addr, uint8_t val) { - if (!(addr & 1)) { - if (!opl[nr].is_opl3 || !opl[nr].opl_emu) - opl[nr].addr = (int)opl[nr].chip.WriteAddr(addr, val) & (opl[nr].is_opl3 ? 0x1ff : 0xff); - else - opl[nr].addr = (int)OPL3_WriteAddr(&opl[nr].opl3chip, addr, val) & 0x1ff; - } else { - if (!opl[nr].is_opl3 || !opl[nr].opl_emu) - opl[nr].chip.WriteReg(opl[nr].addr, val); - else - OPL3_WriteReg(&opl[nr].opl3chip, opl[nr].addr, val); - - 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; - } - } + if (!(addr & 1)) { + if (!opl[nr].is_opl3 || !opl[nr].opl_emu) + opl[nr].addr = (int)opl[nr].chip.WriteAddr(addr, val) & (opl[nr].is_opl3 ? 0x1ff : 0xff); + else + opl[nr].addr = (int)OPL3_WriteAddr(&opl[nr].opl3chip, addr, val) & 0x1ff; + } else { + if (!opl[nr].is_opl3 || !opl[nr].opl_emu) + opl[nr].chip.WriteReg(opl[nr].addr, val); + else + OPL3_WriteReg(&opl[nr].opl3chip, opl[nr].addr, val); + 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; + 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[samples]; + int c; + Bit32s buffer_32[samples]; - opl[nr].chip.GenerateBlock2(samples, buffer_32); + opl[nr].chip.GenerateBlock2(samples, buffer_32); - for (c = 0; c < samples; c++) - buffer[c * 2] = (int16_t)buffer_32[c]; + 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[samples * 2]; + int c; + Bit32s buffer_32[samples * 2]; - if (opl[nr].opl_emu) { - OPL3_GenerateStream(&opl[nr].opl3chip, buffer, samples); - } else { - opl[nr].chip.GenerateBlock3(samples, buffer_32); + if (opl[nr].opl_emu) { + 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]; - } + for (c = 0; c < samples * 2; c++) + buffer[c] = (int16_t)buffer_32[c]; + } } diff --git a/src/sound/sound_emu8k.c b/src/sound/sound_emu8k.c index 9669410a..f1de740d 100644 --- a/src/sound/sound_emu8k.c +++ b/src/sound/sound_emu8k.c @@ -21,97 +21,100 @@ //#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, - }, - }; +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 + 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<> 16) & 0xffff; break; \ - } +#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; \ - } +#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; @@ -226,1878 +231,2007 @@ 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) \ - { \ - /*pclog("EMU8K READ %04X-%02X(%d): %04X\n",addr,(emu8k->cur_reg)<<5|emu8k->cur_voice, emu8k->cur_voice,ret);*/ \ - } \ - else \ - { \ - pclog("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) \ - { \ - /*pclog("EMU8K WRITE %04X-%02X(%d): %04X\n",addr,(emu8k->cur_reg)<<5|emu8k->cur_voice,emu8k->cur_voice, val);*/ \ - } \ - else \ - { \ - pclog("EMU8K WRITE %s(%d) (%d): %04X\n",name, (addr&0x2), emu8k->cur_voice,val); \ - }\ - } +#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) { \ + /*pclog("EMU8K READ %04X-%02X(%d): %04X\n",addr,(emu8k->cur_reg)<<5|emu8k->cur_voice, \ + * emu8k->cur_voice,ret);*/ \ + } else { \ + pclog("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) { \ + /*pclog("EMU8K WRITE %04X-%02X(%d): %04X\n",addr,(emu8k->cur_reg)<<5|emu8k->cur_voice,emu8k->cur_voice, \ + * val);*/ \ + } else { \ + pclog("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 +#define READ16(addr, var) READ16_SWITCH(addr, var) +#define WRITE16(addr, var, val) WRITE16_SWITCH(addr, var, val) +#endif // EMU8K_DEBUG_REGISTERS 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]; + const register emu8k_mem_pointers_t addrmem = {{addr}}; + return emu8k->ram_pointers[addrmem.hb_address][addrmem.lw_address]; } 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; + /* 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; } 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; + /*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) {} + /* 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; + /* 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; + 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; + /* 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; + 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; + emu8k_t *emu8k = (emu8k_t *)p; + uint16_t ret = 0xffff; #ifdef EMU8K_DEBUG_REGISTERS - if (addr == 0xE22) - { - pclog("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) - { - pclog("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) - { - pclog("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) - { - pclog("EMU8K ...... for %d times\n", rep_count_r); - rep_count_r=0; - } - last_read=tmpz; - pclog("EMU8K READ RAM I/O or configuration or clock \n"); - } - //pclog("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) - { - pclog("EMU8K ...... for %d times\n", rep_count_r); - rep_count_r=0; - } - last_read=tmpz; - pclog("EMU8K READ INIT \n"); - } - //pclog("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) - { - pclog("EMU8K ...... for %d times\n", rep_count_r); - } - if (name == 0) - { - pclog("EMU8K READ %04X-%02X(%d/%d): %04X\n",addr,(emu8k->cur_reg)<<5|emu8k->cur_voice, emu8k->cur_reg, emu8k->cur_voice,val); - } - else - { - pclog("EMU8K READ %s (%d): %04X\n",name,emu8k->cur_voice, val); - } + if (addr == 0xE22) { + pclog("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) { + pclog("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) { + pclog("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) { + pclog("EMU8K ...... for %d times\n", rep_count_r); + rep_count_r = 0; + } + last_read = tmpz; + pclog("EMU8K READ RAM I/O or configuration or clock \n"); + } + // pclog("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) { + pclog("EMU8K ...... for %d times\n", rep_count_r); + rep_count_r = 0; + } + last_read = tmpz; + pclog("EMU8K READ INIT \n"); + } + // pclog("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) { + pclog("EMU8K ...... for %d times\n", rep_count_r); + } + if (name == 0) { + pclog("EMU8K READ %04X-%02X(%d/%d): %04X\n", addr, (emu8k->cur_reg) << 5 | emu8k->cur_voice, + emu8k->cur_reg, emu8k->cur_voice, val); + } else { + pclog("EMU8K READ %s (%d): %04X\n", name, emu8k->cur_voice, val); + } - rep_count_r=0; - last_read=tmpz; - } - rep_count_r++; - } + 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; + 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 1: + READ16(addr, emu8k->voice[emu8k->cur_voice].ptrx); + return ret; - case 2:READ16(addr, emu8k->voice[emu8k->cur_voice].cvcf); - 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 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 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 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 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 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 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 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 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; - } + 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; + /*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 2: + return emu8k->init1[emu8k->cur_voice]; - case 3:return emu8k->init3[emu8k->cur_voice]; + case 3: + return emu8k->init3[emu8k->cur_voice]; - case 4:return emu8k->voice[emu8k->cur_voice].envvol; + case 4: + return emu8k->voice[emu8k->cur_voice].envvol; - case 5:return emu8k->voice[emu8k->cur_voice].dcysusv; + case 5: + return emu8k->voice[emu8k->cur_voice].dcysusv; - case 6:return emu8k->voice[emu8k->cur_voice].envval; + case 6: + return emu8k->voice[emu8k->cur_voice].envval; - case 7:return emu8k->voice[emu8k->cur_voice].dcysus; - } - break; + 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 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; + 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; + /* 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 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 2: + return emu8k->init2[emu8k->cur_voice]; - case 3:return emu8k->init4[emu8k->cur_voice]; + case 3: + return emu8k->init4[emu8k->cur_voice]; - case 4:return emu8k->voice[emu8k->cur_voice].atkhldv; + case 4: + return emu8k->voice[emu8k->cur_voice].atkhldv; - case 5:return emu8k->voice[emu8k->cur_voice].lfo1val; + case 5: + return emu8k->voice[emu8k->cur_voice].lfo1val; - case 6:return emu8k->voice[emu8k->cur_voice].atkhld; + case 6: + return emu8k->voice[emu8k->cur_voice].atkhld; - case 7:return emu8k->voice[emu8k->cur_voice].lfo2val; - } - break; + 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 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 1: + return emu8k->voice[emu8k->cur_voice].ifatn; - case 2:return emu8k->voice[emu8k->cur_voice].pefe; + case 2: + return emu8k->voice[emu8k->cur_voice].pefe; - case 3:return emu8k->voice[emu8k->cur_voice].fmmod; + case 3: + return emu8k->voice[emu8k->cur_voice].fmmod; - case 4:return emu8k->voice[emu8k->cur_voice].tremfrq; + case 4: + return emu8k->voice[emu8k->cur_voice].tremfrq; - case 5:return emu8k->voice[emu8k->cur_voice].fm2frq2; + case 5: + return emu8k->voice[emu8k->cur_voice].fm2frq2; - case 6:return 0xffff; + case 6: + return 0xffff; - case 7: /*ID?*/ - return 0x1c | ((emu8k->id & 0x0002) ? 0xff02 : 0); - } - break; + 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; - } - pclog("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; + 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; + } + pclog("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; + 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); + /*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) - { - //pclog("EMU8K WRITE POINTER: %d\n", val); - } - else if ((addr&0xF00) == 0x600) - { - /* These are automatically reported by WRITE16 */ - if (rep_count_w>1) - { - pclog("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) - { - pclog("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) - { - pclog("EMU8K ...... for %d times\n", rep_count_w); - rep_count_w=0; - } - last_write=tmpz; - pclog("EMU8K WRITE RAM I/O or configuration \n"); - } - //pclog("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) - { - pclog("EMU8K ...... for %d times\n", rep_count_w); - rep_count_w=0; - } - last_write=tmpz; - pclog("EMU8K WRITE INIT \n"); - } - //pclog("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 (addr == 0xE22) { + // pclog("EMU8K WRITE POINTER: %d\n", val); + } else if ((addr & 0xF00) == 0x600) { + /* These are automatically reported by WRITE16 */ + if (rep_count_w > 1) { + pclog("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) { + pclog("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) { + pclog("EMU8K ...... for %d times\n", rep_count_w); + rep_count_w = 0; + } + last_write = tmpz; + pclog("EMU8K WRITE RAM I/O or configuration \n"); + } + // pclog("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) { + pclog("EMU8K ...... for %d times\n", rep_count_w); + rep_count_w = 0; + } + last_write = tmpz; + pclog("EMU8K WRITE INIT \n"); + } + // pclog("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) - { - pclog("EMU8K ...... for %d times\n", rep_count_w); - } - if (name == 0) - { - pclog("EMU8K WRITE %04X-%02X(%d/%d): %04X\n",addr,(emu8k->cur_reg)<<5|emu8k->cur_voice,emu8k->cur_reg,emu8k->cur_voice, val); - } - else - { - pclog("EMU8K WRITE %s (%d): %04X\n",name,emu8k->cur_voice, val); - } + if (rep_count_w > 1) { + pclog("EMU8K ...... for %d times\n", rep_count_w); + } + if (name == 0) { + pclog("EMU8K WRITE %04X-%02X(%d/%d): %04X\n", addr, (emu8k->cur_reg) << 5 | emu8k->cur_voice, + emu8k->cur_reg, emu8k->cur_voice, val); + } else { + pclog("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 + 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; + 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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); + 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; - } + 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; - }*/ - } - } + // 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; - }*/ - } - } - } + 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; + } - /* 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; - 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 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; + } - 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; - 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 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; + 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; + /*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 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 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 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; + 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; + } break; - case 0x1F:emu8k->reverb_engine.link_return_amp = val & 0xFF; - break; - } - } - return; + 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; + 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; + 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 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 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); + case 7: + emu8k->voice[emu8k->cur_voice].lfo2val = val; + emu8k->voice[emu8k->cur_voice].lfo2_delay_samples = LFOxVAL_TO_EMU_SAMPLES(val); - return; - } - break; + 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 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]; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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]; + 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; + 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]; + 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; + 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; - } - pclog("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); + 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; + } + pclog("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; + /* 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: 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]; + 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; + 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; + /* 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); + 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; - /* 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->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++; - } + ++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; + 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; + if (++comb->read_pos >= comb->bufsize) + comb->read_pos = 0; - return output * comb->output_gain; + 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; + 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; + if (++comb->read_pos >= comb->bufsize) + comb->read_pos = 0; - return output; + 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; + 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); + // 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; + if (++comb->read_pos >= comb->bufsize) + comb->read_pos = 0; - return output; + 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; + /* 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); + 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; + 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; + (*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; + 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; - } - } + (*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 + // 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; + 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}; +// 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; + 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; + 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])); + /* 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]; + /* 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; + for (pos = emu8k->pos; pos < new_pos; pos++) { + int32_t dat; - if (emu_voice->cvcf_curr_volume) { - /* Waveform oscillator */ + if (emu_voice->cvcf_curr_volume) { + /* Waveform oscillator */ #ifdef RESAMPLER_LINEAR - dat = EMU8K_READ_INTERP_LINEAR(emu8k, emu_voice->addr.int_address, - emu_voice->addr.fract_address); + 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); + 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 */ + /* 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; + 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; } + 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; + /*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]); + 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 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]); + 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[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); + 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; - } + 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; + /* 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] = + (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]); + 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; } + 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; - } - 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; - (*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; + } + } + } - /* 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; - 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_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_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_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_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_SUSTAIN:attenuation += volenv->value_db_oct; - break; + case ENV_STOPPED: + attenuation = 0x1FFFFF; + 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; - 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_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_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_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; + } - 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; + } - /* 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_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_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_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_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 (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; - 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 - 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; + - 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. - } -/* -I've recopilated these sentences to get an idea of how to loop + -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). -- 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. + -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; + } --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). + /* 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; + } --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; - } + /* 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; - /* 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; - } + // if ( emu_voice->cvcf_curr_volume != old_vol[c]) { + // pclog("EMUVOL (%d):%d\n", c, emu_voice->cvcf_curr_volume); + // old_vol[c]=emu_voice->cvcf_curr_volume; + //} + // pclog("EMUFILT :%d\n", emu_voice->cvcf_curr_filt_ctoff); + } - /* 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; + 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); - //if ( emu_voice->cvcf_curr_volume != old_vol[c]) { - // pclog("EMUVOL (%d):%d\n", c, emu_voice->cvcf_curr_volume); - // old_vol[c]=emu_voice->cvcf_curr_volume; - //} - //pclog("EMUFILT :%d\n", emu_voice->cvcf_curr_filt_ctoff); - } + // 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; - 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); + if (buf[1] < -32768) + buf[1] = -32768; + else if (buf[1] > 32767) + buf[1] = 32767; - // 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; + buf += 2; + } - if (buf[1] < -32768) - buf[1] = -32768; - else if (buf[1] > 32767) - buf[1] = 32767; + /* Update EMU clock. */ + emu8k->wc += (new_pos - emu8k->pos); - buf += 2; - } - - /* Update EMU clock. */ - emu8k->wc += (new_pos - emu8k->pos); - - emu8k->pos = new_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; + uint32_t const BLOCK_SIZE_WORDS = 0x10000; + FILE *f; + int c; + double out; - f = romfopen("awe32.raw", "rb"); - if (!f) - fatal("AWE32.RAW not found\n"); + f = romfopen("awe32.raw", "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->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); + 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; - } + 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 (; i < i_end; i++, j++) { - emu8k->ram_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; + 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 (; i < i_end; i++, j++) { + emu8k->ram_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); - 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; - /*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; - /* 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; - /* 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 = -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; - 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)) */ + } - /* 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))); + /* 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; + } - env_attack_to_samples[c] = 44.1 * millis; - /* This is an alternate formula with linear increments, but probably incorrect: - * millis = (256+4096*(0x7F-c)) */ - } + for (c = 0; c < 65536; c++) { + chortable[c] = sin(c * M_PI / 32768.0); + } - /* 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++) { + /* 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); + 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; + 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; - } + /*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; + /* 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); + free(emu8k->rom); + free(emu8k->ram); } - diff --git a/src/sound/sound_gus.c b/src/sound/sound_gus.c index 0f55205d..aeecab3a 100644 --- a/src/sound/sound_gus.c +++ b/src/sound/sound_gus.c @@ -12,1090 +12,1135 @@ #include "timer.h" typedef struct gus_t { - int reset; + 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; + 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; + int32_t out_l, out_r; - int16_t buffer[2][MAXSOUNDBUFLEN]; - int pos; + int16_t buffer[2][MAXSOUNDBUFLEN]; + int pos; - pc_timer_t samp_timer; - uint64_t samp_latch; + pc_timer_t samp_timer; + uint64_t samp_latch; - uint8_t *ram; + uint8_t *ram; - int irqnext; + int irqnext; - pc_timer_t timer_1, timer_2; + pc_timer_t timer_1, timer_2; - int irq, dma, irq_midi; - int latch_enable; + 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 sb_2xa, sb_2xc, sb_2xe; + uint8_t sb_ctrl; + int sb_nmi; - uint8_t reg_ctrl; + uint8_t reg_ctrl; - uint8_t ad_status, ad_data; - uint8_t ad_timer_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 midi_ctrl, midi_status; + uint8_t midi_data; + int midi_loopback; - uint8_t gp1, gp2; - uint16_t gp1_addr, gp2_addr; + uint8_t gp1, gp2; + uint16_t gp1_addr, gp2_addr; - uint8_t usrr; + 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 - }; +int gusfreqs[] = {44100, 41160, 38587, 36317, 34300, 32494, 30870, 29400, 28063, 26843, + 25725, 24696, 23746, 22866, 22050, 21289, 20580, 19916, 19293}; double vol16bit[4096]; -enum { - MIDI_INT_RECEIVE = 0x01, - MIDI_INT_TRANSMIT = 0x02, - MIDI_INT_MASTER = 0x80 -}; +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 { 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_INT_MIDI_TRANSMIT = 0x01, GUS_INT_MIDI_RECEIVE = 0x02 }; -enum { - GUS_TIMER_CTRL_AUTO = 0x01 -}; +enum { GUS_TIMER_CTRL_AUTO = 0x01 }; void gus_update_int_status(gus_t *gus) { - int c; - int irq_pending = 0; - int midi_irq_pending = 0; + int c; + int irq_pending = 0; + int midi_irq_pending = 0; - gus->irqstatus &= ~0x60; - gus->irqstatus2 = 0xE0; - for (c = 0; c < 32; c++) { - if (gus->waveirqs[c]) { -// gus->waveirqs[c]=0; - gus->irqstatus2 = 0x60 | c; - if (gus->rampirqs[c]) - gus->irqstatus2 |= 0x80; - gus->irqstatus |= 0x20; -// printf(" Voice IRQ %i %02X %i\n",c,gus->irqstatus2,ins); - irq_pending = 1; - break; - } - if (gus->rampirqs[c]) { -// gus->rampirqs[c]=0; - gus->irqstatus2 = 0xA0 | c; - gus->irqstatus |= 0x40; -// printf(" Ramp IRQ %i %02X %i\n",c,gus->irqstatus2,ins); - irq_pending = 1; - break; - } - } - if ((gus->tctrl & 4) && (gus->irqstatus & 0x04)) - irq_pending = 1; /*Timer 1 interrupt pending*/ - if ((gus->tctrl & 8) && (gus->irqstatus & 0x08)) - irq_pending = 1; /*Timer 2 interrupt pending*/ - if ((gus->irqstatus & 0x80) && (gus->dmactrl & 0x20)) - irq_pending = 1; /*DMA TC interrupt pending*/ + gus->irqstatus &= ~0x60; + gus->irqstatus2 = 0xE0; + for (c = 0; c < 32; c++) { + if (gus->waveirqs[c]) { + // gus->waveirqs[c]=0; + gus->irqstatus2 = 0x60 | c; + if (gus->rampirqs[c]) + gus->irqstatus2 |= 0x80; + gus->irqstatus |= 0x20; + // printf(" Voice IRQ %i %02X %i\n",c,gus->irqstatus2,ins); + irq_pending = 1; + break; + } + if (gus->rampirqs[c]) { + // gus->rampirqs[c]=0; + gus->irqstatus2 = 0xA0 | c; + gus->irqstatus |= 0x40; + // printf(" Ramp IRQ %i %02X %i\n",c,gus->irqstatus2,ins); + irq_pending = 1; + break; + } + } + if ((gus->tctrl & 4) && (gus->irqstatus & 0x04)) + irq_pending = 1; /*Timer 1 interrupt pending*/ + if ((gus->tctrl & 8) && (gus->irqstatus & 0x08)) + irq_pending = 1; /*Timer 2 interrupt pending*/ + if ((gus->irqstatus & 0x80) && (gus->dmactrl & 0x20)) + irq_pending = 1; /*DMA TC interrupt pending*/ - midi_irq_pending = gus->midi_status & MIDI_INT_MASTER; + midi_irq_pending = gus->midi_status & MIDI_INT_MASTER; -// pclog("gus_update_int_status: tctrl=%02x irqstatus=%02x irq_pending=%i midi_irq_pending=%i gus->irq=%i gus->irq_midi=%i\n", -// gus->tctrl, gus->irqstatus, irq_pending, midi_irq_pending, gus->irq, gus->irq_midi); - if (gus->irq == gus->irq_midi && gus->irq != -1) { - if (irq_pending || midi_irq_pending) - picintlevel(1 << gus->irq); - else - picintc(1 << gus->irq); - } else { - if (gus->irq != -1) { - if (irq_pending) - picintlevel(1 << gus->irq); - else - picintc(1 << gus->irq); - } - if (gus->irq_midi != -1) { - if (midi_irq_pending) - picintlevel(1 << gus->irq_midi); - else - picintc(1 << gus->irq_midi); - } - } + // pclog("gus_update_int_status: tctrl=%02x irqstatus=%02x irq_pending=%i midi_irq_pending=%i gus->irq=%i + // gus->irq_midi=%i\n", + // gus->tctrl, gus->irqstatus, irq_pending, midi_irq_pending, gus->irq, gus->irq_midi); + if (gus->irq == gus->irq_midi && gus->irq != -1) { + if (irq_pending || midi_irq_pending) + picintlevel(1 << gus->irq); + else + picintc(1 << gus->irq); + } else { + if (gus->irq != -1) { + if (irq_pending) + picintlevel(1 << gus->irq); + else + picintc(1 << gus->irq); + } + if (gus->irq_midi != -1) { + if (midi_irq_pending) + picintlevel(1 << gus->irq_midi); + else + picintc(1 << gus->irq_midi); + } + } } 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; + 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_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; - gus_update_int_status(gus); + gus_update_int_status(gus); } void writegus(uint16_t addr, uint8_t val, void *p) { - gus_t *gus = (gus_t *)p; - int c, d; - int old; -// pclog("Write GUS %04X %02X %04X:%04X\n",addr,val,CS,pc); - if (gus->latch_enable && addr != 0x24b) - gus->latch_enable = 0; - switch (addr) { - case 0x340: /*MIDI control*/ - old = gus->midi_ctrl; - gus->midi_ctrl = val; + gus_t *gus = (gus_t *)p; + int c, d; + int old; + // pclog("Write GUS %04X %02X %04X:%04X\n",addr,val,CS,pc); + 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; -// pclog("MIDI_INT_TRANSMIT\n"); - } - gus_midi_update_int_status(gus); - break; + if ((val & 3) == 3) + gus->midi_status = 0; + else if ((old & 3) == 3) { + gus->midi_status |= MIDI_INT_TRANSMIT; + // pclog("MIDI_INT_TRANSMIT\n"); + } + 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 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*/ -// if (gus->global!=0x43 && gus->global!=0x44) printf("Writing register %02X %02X %02X %i\n",gus->global,gus->voice,val, ins); - switch (gus->global) { - case 0: /*Voice control*/ -// if (val&1 && !(gus->ctrl[gus->voice]&1)) printf("Voice on %i\n",gus->voice); - 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); -// printf("Write %i start %08X %08X\n",gus->voice,gus->start[gus->voice],gus->startx[gus->voice]); - break; - case 3: /*Start addr low*/ - gus->start[gus->voice] = (gus->start[gus->voice] & 0x1FFFFF00) | val; -// printf("Write %i start %08X %08X\n",gus->voice,gus->start[gus->voice],gus->startx[gus->voice]); - 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); -// printf("Write %i end %08X %08X\n",gus->voice,gus->end[gus->voice],gus->endx[gus->voice]); - break; - case 5: /*End addr low*/ - gus->end[gus->voice] = (gus->end[gus->voice] & 0x1FFFFF00) | val; -// printf("Write %i end %08X %08X\n",gus->voice,gus->end[gus->voice],gus->endx[gus->voice]); - break; + case 0x342: /*Voice select*/ + gus->voice = val & 31; + break; + case 0x343: /*Global select*/ + gus->global = val; + break; + case 0x344: /*Global low*/ + // if (gus->global!=0x43 && gus->global!=0x44) printf("Writing register %02X %02X %02X + // %i\n",gus->global,gus->voice,val, ins); + switch (gus->global) { + case 0: /*Voice control*/ + // if (val&1 && !(gus->ctrl[gus->voice]&1)) printf("Voice on %i\n",gus->voice); + 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); + // printf("Write %i start %08X + // %08X\n",gus->voice,gus->start[gus->voice],gus->startx[gus->voice]); + break; + case 3: /*Start addr low*/ + gus->start[gus->voice] = (gus->start[gus->voice] & 0x1FFFFF00) | val; + // printf("Write %i start %08X + // %08X\n",gus->voice,gus->start[gus->voice],gus->startx[gus->voice]); + 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); + // printf("Write %i end %08X + // %08X\n",gus->voice,gus->end[gus->voice],gus->endx[gus->voice]); + break; + case 5: /*End addr low*/ + gus->end[gus->voice] = (gus->end[gus->voice] & 0x1FFFFF00) | val; + // printf("Write %i end %08X + // %08X\n",gus->voice,gus->end[gus->voice],gus->endx[gus->voice]); + break; - case 0x6: /*Ramp frequency*/ - gus->rfreq[gus->voice] = (int)((double)((val & 63) * 512) / (double)(1 << (3 * (val >> 6)))); -// printf("RFREQ %02X %i %i %f\n",val,gus->voice,gus->rfreq[gus->voice],(double)(val & 63)/(double)(1 << (3*(val >> 6)))); - break; + case 0x6: /*Ramp frequency*/ + gus->rfreq[gus->voice] = (int)((double)((val & 63) * 512) / (double)(1 << (3 * (val >> 6)))); + // printf("RFREQ %02X %i %i + // %f\n",val,gus->voice,gus->rfreq[gus->voice],(double)(val & 63)/(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); -// printf("Vol %i is %04X\n",gus->voice,gus->curvol[gus->voice]); - break; + case 0x9: /*Current volume*/ + gus->curvol[gus->voice] = gus->rcur[gus->voice] = (gus->rcur[gus->voice] & ~(0xff << 6)) | (val << 6); + // printf("Vol %i is %04X\n",gus->voice,gus->curvol[gus->voice]); + 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); -// gus->cur[gus->voice]=(gus->cur[gus->voice]&0x0F807F00)|((val<<7)<<8); -// printf("Write %i cur %08X\n",gus->voice,gus->cur[gus->voice],gus->curx[gus->voice]); - break; - case 0xB: /*Current addr low*/ - gus->cur[gus->voice] = (gus->cur[gus->voice] & 0x1FFFFF00) | val; -// printf("Write %i cur %08X\n",gus->voice,gus->cur[gus->voice],gus->curx[gus->voice]); - 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); + // gus->cur[gus->voice]=(gus->cur[gus->voice]&0x0F807F00)|((val<<7)<<8); + // printf("Write %i cur + // %08X\n",gus->voice,gus->cur[gus->voice],gus->curx[gus->voice]); + break; + case 0xB: /*Current addr low*/ + gus->cur[gus->voice] = (gus->cur[gus->voice] & 0x1FFFFF00) | val; + // printf("Write %i cur + // %08X\n",gus->voice,gus->cur[gus->voice],gus->curx[gus->voice]); + break; - case 0x42: /*DMA address low*/ - gus->dmaaddr = (gus->dmaaddr & 0xFF000) | (val << 4); - 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*/ -// printf("Timer control %02X\n",val); - gus->tctrl = val; - gus_update_int_status(gus); - break; - } - break; - case 0x345: /*Global high*/ -// if (gus->global!=0x43 && gus->global!=0x44) printf("HWriting register %02X %02X %02X %04X:%04X %i %X\n",gus->global,gus->voice,val,CS,pc, ins, gus->rcur[1] >> 10); - switch (gus->global) { - case 0: /*Voice control*/ - if (!(val & 1) && gus->ctrl[gus->voice] & 1) { -// printf("Voice on %i - start %05X end %05X freq %04X\n",gus->voice,gus->start[gus->voice],gus->end[gus->voice],gus->freq[gus->voice]); -// if (val&0x40) gus->cur[gus->voice]=gus->end[gus->voice]<<8; -// else gus->cur[gus->voice]=gus->start[gus->voice]<<8; - } + case 0x43: /*Address low*/ + gus->addr = (gus->addr & 0xFFF00) | val; + break; + case 0x45: /*Timer control*/ + // printf("Timer control %02X\n",val); + gus->tctrl = val; + gus_update_int_status(gus); + break; + } + break; + case 0x345: /*Global high*/ + // if (gus->global!=0x43 && gus->global!=0x44) printf("HWriting register %02X %02X %02X %04X:%04X + // %i %X\n",gus->global,gus->voice,val,CS,pc, ins, gus->rcur[1] >> 10); + switch (gus->global) { + case 0: /*Voice control*/ + if (!(val & 1) && gus->ctrl[gus->voice] & 1) { + // printf("Voice on %i - start %05X end %05X freq + // %04X\n",gus->voice,gus->start[gus->voice],gus->end[gus->voice],gus->freq[gus->voice]); + // if (val&0x40) gus->cur[gus->voice]=gus->end[gus->voice]<<8; + // else gus->cur[gus->voice]=gus->start[gus->voice]<<8; + } - gus->ctrl[gus->voice] = val & 0x7f; + 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) - gus_update_int_status(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); -// printf("Write %i start %08X %08X %02X\n",gus->voice,gus->start[gus->voice],gus->startx[gus->voice],val); - 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); -// printf("Write %i start %08X %08X\n",gus->voice,gus->start[gus->voice],gus->startx[gus->voice]); - 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); -// printf("Write %i end %08X %08X %02X\n",gus->voice,gus->end[gus->voice],gus->endx[gus->voice],val); - 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); -// printf("Write %i end %08X %08X\n",gus->voice,gus->end[gus->voice],gus->endx[gus->voice]); - break; + old = gus->waveirqs[gus->voice]; + gus->waveirqs[gus->voice] = ((val & 0xa0) == 0xa0) ? 1 : 0; + if (gus->waveirqs[gus->voice] != old) + gus_update_int_status(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); + // printf("Write %i start %08X %08X + // %02X\n",gus->voice,gus->start[gus->voice],gus->startx[gus->voice],val); + 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); + // printf("Write %i start %08X + // %08X\n",gus->voice,gus->start[gus->voice],gus->startx[gus->voice]); + 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); + // printf("Write %i end %08X %08X + // %02X\n",gus->voice,gus->end[gus->voice],gus->endx[gus->voice],val); + 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); + // printf("Write %i end %08X + // %08X\n",gus->voice,gus->end[gus->voice],gus->endx[gus->voice]); + break; - case 0x6: /*Ramp frequency*/ - gus->rfreq[gus->voice] = (int)((double)((val & 63) * (1 << 10)) / (double)(1 << (3 * (val >> 6)))); -// pclog("Ramp freq %02X %i %i %f %i\n", val, gus->voice, gus->rfreq[gus->voice], (double)(val & 63)/(double)(1 << (3*(val >> 6))), ins); - break; - case 0x7: /*Ramp start*/ - gus->rstart[gus->voice] = val << 14; -// pclog("Ramp start %04X\n", gus->rstart[gus->voice] >> 10); - break; - case 0x8: /*Ramp end*/ - gus->rend[gus->voice] = val << 14; -// pclog("Ramp end %04X\n", gus->rend[gus->voice] >> 10); - break; - case 0x9: /*Current volume*/ - gus->curvol[gus->voice] = gus->rcur[gus->voice] = (gus->rcur[gus->voice] & ~(0xff << 14)) | (val << 14); -// printf("Vol %i is %04X\n",gus->voice,gus->curvol[gus->voice]); - break; + case 0x6: /*Ramp frequency*/ + gus->rfreq[gus->voice] = (int)((double)((val & 63) * (1 << 10)) / (double)(1 << (3 * (val >> 6)))); + // pclog("Ramp freq %02X %i %i %f %i\n", val, gus->voice, gus->rfreq[gus->voice], + // (double)(val & 63)/(double)(1 << (3*(val >> 6))), ins); + break; + case 0x7: /*Ramp start*/ + gus->rstart[gus->voice] = val << 14; + // pclog("Ramp start %04X\n", gus->rstart[gus->voice] >> 10); + break; + case 0x8: /*Ramp end*/ + gus->rend[gus->voice] = val << 14; + // pclog("Ramp end %04X\n", gus->rend[gus->voice] >> 10); + break; + case 0x9: /*Current volume*/ + gus->curvol[gus->voice] = gus->rcur[gus->voice] = (gus->rcur[gus->voice] & ~(0xff << 14)) | (val << 14); + // printf("Vol %i is %04X\n",gus->voice,gus->curvol[gus->voice]); + 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); -// printf("Write %i cur %08X %08X %02X\n",gus->voice,gus->cur[gus->voice],gus->curx[gus->voice],val); -// gus->cur[gus->voice]=(gus->cur[gus->voice]&0x007FFF00)|((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); -// gus->cur[gus->voice]=(gus->cur[gus->voice]&0x0FFF8000)|((val&0x7F)<<8); -// printf("Write %i cur %08X %08X\n",gus->voice,gus->cur[gus->voice],gus->curx[gus->voice]); - 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) - gus_update_int_status(gus); -// printf("Ramp control %02i %02X %02X %i\n",gus->voice,val,gus->rampirqs[gus->voice],ins); - 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); + // printf("Write %i cur %08X %08X + // %02X\n",gus->voice,gus->cur[gus->voice],gus->curx[gus->voice],val); + // gus->cur[gus->voice]=(gus->cur[gus->voice]&0x007FFF00)|((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); + // gus->cur[gus->voice]=(gus->cur[gus->voice]&0x0FFF8000)|((val&0x7F)<<8); + // printf("Write %i cur %08X + // %08X\n",gus->voice,gus->cur[gus->voice],gus->curx[gus->voice]); + 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) + gus_update_int_status(gus); + // printf("Ramp control %02i %02X %02X + // %i\n",gus->voice,val,gus->rampirqs[gus->voice],ins); + 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; -// printf("GUS voices %i\n",val&31); - if (gus->voices < 14) - gus->samp_latch = (uint64_t)(TIMER_USEC * (1000000.0 / 44100.0)); - else - gus->samp_latch = (uint64_t)(TIMER_USEC * (1000000.0 / gusfreqs[gus->voices - 14])); - 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; + // printf("GUS voices %i\n",val&31); + if (gus->voices < 14) + gus->samp_latch = (uint64_t)(TIMER_USEC * (1000000.0 / 44100.0)); + else + gus->samp_latch = (uint64_t)(TIMER_USEC * (1000000.0 / gusfreqs[gus->voices - 14])); + break; - case 0x41: /*DMA*/ - if (val & 1 && gus->dma != -1) { -// printf("DMA start! %05X %02X\n",gus->dmaaddr,val); - 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; - } -// printf("GUS->MEM Transferred %i bytes\n",c); - gus->dmactrl = val & ~0x40; - 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; - } -// printf("MEM->GUS Transferred %i bytes\n",c); - gus->dmactrl = val & ~0x40; - gus->irqnext = 1; - } -// exit(-1); - } - break; + case 0x41: /*DMA*/ + if (val & 1 && gus->dma != -1) { + // printf("DMA start! %05X %02X\n",gus->dmaaddr,val); + 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; + } + // printf("GUS->MEM Transferred %i bytes\n",c); + gus->dmactrl = val & ~0x40; + 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; + } + // printf("MEM->GUS Transferred %i bytes\n",c); + gus->dmactrl = val & ~0x40; + gus->irqnext = 1; + } + // exit(-1); + } + break; - case 0x42: /*DMA address low*/ - gus->dmaaddr = (gus->dmaaddr & 0xFF0) | (val << 12); - 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; - } -// printf("Timer control %02X\n",val); -/* if ((val&4) && !(gus->tctrl&4)) - { - gus->t1=gus->t1l; - gus->t1on=1; - }*/ - gus->tctrl = val; - gus->sb_ctrl = val; - gus_update_int_status(gus); - break; - case 0x46: /*Timer 1*/ - gus->t1 = gus->t1l = val; - gus->t1on = 1; -// printf("GUS timer 1 %i\n",val); - break; - case 0x47: /*Timer 2*/ - gus->t2 = gus->t2l = val; - gus->t2on = 1; -// printf("GUS timer 2 %i\n",val); - 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; + } + // printf("Timer control %02X\n",val); + /* if ((val&4) && !(gus->tctrl&4)) + { + gus->t1=gus->t1l; + gus->t1on=1; + }*/ + gus->tctrl = val; + gus->sb_ctrl = val; + gus_update_int_status(gus); + break; + case 0x46: /*Timer 1*/ + gus->t1 = gus->t1l = val; + gus->t1on = 1; + // printf("GUS timer 1 %i\n",val); + break; + case 0x47: /*Timer 2*/ + gus->t2 = gus->t2l = val; + gus->t2on = 1; + // printf("GUS timer 2 %i\n",val); + break; - case 0x4c: /*Reset*/ - gus->reset = val; - break; - } - break; - case 0x347: /*DRAM access*/ - gus->ram[gus->addr] = val; -// pclog("GUS RAM write %05X %02X\n",gus->addr,val); - gus->addr &= 0xFFFFF; - break; - case 0x248: - case 0x388:gus->adcommand = val; -// pclog("Setting ad command %02X %02X %p\n", val, gus->adcommand, &gus->adcommand); - break; + case 0x4c: /*Reset*/ + gus->reset = val; + break; + } + break; + case 0x347: /*DRAM access*/ + gus->ram[gus->addr] = val; + // pclog("GUS RAM write %05X %02X\n",gus->addr,val); + gus->addr &= 0xFFFFF; + break; + case 0x248: + case 0x388: + gus->adcommand = val; + // pclog("Setting ad command %02X %02X %p\n", val, gus->adcommand, &gus->adcommand); + 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; + 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 & 0x01) + gus->t1on = 1; + else + gus->t1 = gus->t1l; - if (val & 0x02) - gus->t2on = 1; - else - gus->t2 = gus->t2l; - } - } - break; + 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 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]; + 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]; + 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; -// pclog("IRQ %i DMA %i\n", gus->irq, gus->dma); - 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; + gus->sb_nmi = val & 0x80; + } + gus->latch_enable = 0; + // pclog("IRQ %i DMA %i\n", gus->irq, gus->dma); + 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; - } + 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; -// /*if (addr!=0x246) */printf("Read GUS %04X %04X(%06X):%04X %02X\n",addr,CS,cs,pc,gus->global); - switch (addr) { - case 0x340: /*MIDI status*/ - val = gus->midi_status; -// pclog("Read MIDI status %02X\n", val); - break; + gus_t *gus = (gus_t *)p; + uint8_t val = 0xff; + // /*if (addr!=0x246) */printf("Read GUS %04X %04X(%06X):%04X %02X\n",addr,CS,cs,pc,gus->global); + switch (addr) { + case 0x340: /*MIDI status*/ + val = gus->midi_status; + // pclog("Read MIDI status %02X\n", val); + break; - case 0x341: /*MIDI data*/ - val = gus->midi_data; - gus->midi_status &= ~MIDI_INT_RECEIVE; - gus_midi_update_int_status(gus); - 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; -// pclog("Read IRQ status %02X\n", val); - return val; + case 0x240: + return 0; + case 0x246: /*IRQ status*/ + val = gus->irqstatus & ~0x10; + if (gus->ad_status & 0x19) + val |= 0x10; + // pclog("Read IRQ status %02X\n", val); + return val; - case 0x24F:return 0; - case 0x342:return gus->voice; - case 0x343:return gus->global; - case 0x344: /*Global low*/ -// /*if (gus->global!=0x43 && gus->global!=0x44) */printf("Reading register %02X %02X\n",gus->global,gus->voice); - 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 0x24F: + return 0; + case 0x342: + return gus->voice; + case 0x343: + return gus->global; + case 0x344: /*Global low*/ + // /*if (gus->global!=0x43 && gus->global!=0x44) */printf("Reading register %02X + // %02X\n",gus->global,gus->voice); + 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 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; -// pclog("Read IRQ status - %02X\n",val); - gus->rampirqs[gus->irqstatus2 & 0x1F] = 0; - gus->waveirqs[gus->irqstatus2 & 0x1F] = 0; - gus_update_int_status(gus); - return val; + case 0x8F: /*IRQ status*/ + val = gus->irqstatus2; + // pclog("Read IRQ status - %02X\n",val); + gus->rampirqs[gus->irqstatus2 & 0x1F] = 0; + gus->waveirqs[gus->irqstatus2 & 0x1F] = 0; + gus_update_int_status(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; + 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; -// default: -// fatal("Bad GUS global low read %02X\n",gus->global); - } - break; - case 0x345: /*Global high*/ -// /*if (gus->global!=0x43 && gus->global!=0x44) */printf("HReading register %02X %02X\n",gus->global,gus->voice); - switch (gus->global) { - case 0x80: /*Voice control*/ -// pclog("Read voice control %02i %02X\n", gus->voice, gus->ctrl[gus->voice]|(gus->waveirqs[gus->voice]?0x80:0)); - return gus->ctrl[gus->voice] | (gus->waveirqs[gus->voice] ? 0x80 : 0); + // default: + // fatal("Bad GUS global low read %02X\n",gus->global); + } + break; + case 0x345: /*Global high*/ + // /*if (gus->global!=0x43 && gus->global!=0x44) */printf("HReading register %02X + // %02X\n",gus->global,gus->voice); + switch (gus->global) { + case 0x80: /*Voice control*/ + // pclog("Read voice control %02i %02X\n", gus->voice, + // gus->ctrl[gus->voice]|(gus->waveirqs[gus->voice]?0x80:0)); + 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 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*/ -// pclog("Read current volume %i\n", gus->rcur[gus->voice] >> 14); - return gus->rcur[gus->voice] >> 14; + case 0x89: /*Current volume*/ + // pclog("Read current volume %i\n", gus->rcur[gus->voice] >> 14); + 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 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 0x8C: /*Pan*/ + return gus->pan_r[gus->voice]; - case 0x8D: -// pclog("Read ramp control %02X %04X %08X %08X %08X\n",gus->rctrl[gus->voice]|(gus->rampirqs[gus->voice]?0x80:0),gus->rcur[gus->voice] >> 14,gus->rfreq[gus->voice],gus->rstart[gus->voice],gus->rend[gus->voice]); - return gus->rctrl[gus->voice] | (gus->rampirqs[gus->voice] ? 0x80 : 0); + case 0x8D: + // pclog("Read ramp control %02X %04X %08X %08X + // %08X\n",gus->rctrl[gus->voice]|(gus->rampirqs[gus->voice]?0x80:0),gus->rcur[gus->voice] + // >> 14,gus->rfreq[gus->voice],gus->rstart[gus->voice],gus->rend[gus->voice]); + return gus->rctrl[gus->voice] | (gus->rampirqs[gus->voice] ? 0x80 : 0); - case 0x8F: /*IRQ status*/ -// pclog("Read IRQ 1\n"); - val = gus->irqstatus2; - gus->rampirqs[gus->irqstatus2 & 0x1F] = 0; - gus->waveirqs[gus->irqstatus2 & 0x1F] = 0; - gus_update_int_status(gus); -// pclog("Read IRQ status - %02X %i %i\n",val, gus->waveirqs[gus->irqstatus2&0x1F], gus->rampirqs[gus->irqstatus2&0x1F]); - return val; + case 0x8F: /*IRQ status*/ + // pclog("Read IRQ 1\n"); + val = gus->irqstatus2; + gus->rampirqs[gus->irqstatus2 & 0x1F] = 0; + gus->waveirqs[gus->irqstatus2 & 0x1F] = 0; + gus_update_int_status(gus); + // pclog("Read IRQ status - %02X %i %i\n",val, + // gus->waveirqs[gus->irqstatus2&0x1F], gus->rampirqs[gus->irqstatus2&0x1F]); + 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 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; + 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; -// default: -// fatal("Bad GUS global high read %02X\n",gus->global); - } - break; - case 0x346:return 0xff; - case 0x347: /*DRAM access*/ - val = gus->ram[gus->addr]; -// pclog("GUS RAM read %05X %02X\n",gus->addr,val); - gus->addr &= 0xFFFFF; - return val; - case 0x349:return 0; - case 0x746: /*Revision level*/ - return 0xff; /*Pre 3.7 - no mixer*/ + // default: + // fatal("Bad GUS global high read %02X\n",gus->global); + } + break; + case 0x346: + return 0xff; + case 0x347: /*DRAM access*/ + val = gus->ram[gus->addr]; + // pclog("GUS RAM read %05X %02X\n",gus->addr,val); + 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 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: -/* gus->ad_status |= 0x10; - if (gus->reg_ctrl & 0x80) - { - gus->reg_ctrl_r |= 0x80; - if (gus->sb_nmi) - nmi = 1; - else - picint(1 << gus->irq); - }*/ - return gus->sb_2xe; + case 0x24c: + val = gus->sb_2xc; + if (gus->reg_ctrl & 0x20) + gus->sb_2xc &= 0x80; + break; + case 0x24e: + /* gus->ad_status |= 0x10; + if (gus->reg_ctrl & 0x80) + { + gus->reg_ctrl_r |= 0x80; + if (gus->sb_nmi) + nmi = 1; + else + picint(1 << gus->irq); + }*/ + return gus->sb_2xe; - case 0x248: - case 0x388: -// pclog("Read ad_status %02X\n", gus->ad_status); - 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 0x248: + case 0x388: + // pclog("Read ad_status %02X\n", gus->ad_status); + 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 0x249: + gus->ad_status &= ~0x01; + nmi = 0; + case 0x389: + val = gus->ad_data; + break; - case 0x24A:val = gus->adcommand; -// pclog("Read ad command %02X %02X %p\n", gus->adcommand, val, &gus->adcommand); - break; - - } -// printf("Bad GUS read %04X! %02X\n",addr,gus->global); -// exit(-1); - return val; + case 0x24A: + val = gus->adcommand; + // pclog("Read ad command %02X %02X %p\n", gus->adcommand, val, &gus->adcommand); + break; + } + // printf("Bad GUS read %04X! %02X\n",addr,gus->global); + // exit(-1); + return val; } void gus_poll_timer_1(void *p) { - gus_t *gus = (gus_t *)p; + gus_t *gus = (gus_t *)p; - timer_advance_u64(&gus->timer_1, (uint64_t)(TIMER_USEC * 80)); -// pclog("gus_poll_timer_1 %i %i %i %i %02X\n", gustime, gus->t1on, gus->t1, gus->t1l, gus->tctrl); - if (gus->t1on) { - gus->t1++; - if (gus->t1 > 0xFF) { -// gus->t1on=0; - gus->t1 = gus->t1l; - gus->ad_status |= 0x40; - if (gus->tctrl & 4) { - gus->ad_status |= 0x04; - gus->irqstatus |= 0x04; -// pclog("GUS T1 IRQ!\n"); - } - } - } - if (gus->irqnext) { -// pclog("Take IRQ\n"); - gus->irqnext = 0; - gus->irqstatus |= 0x80; - } - gus_midi_update_int_status(gus); - gus_update_int_status(gus); + timer_advance_u64(&gus->timer_1, (uint64_t)(TIMER_USEC * 80)); + // pclog("gus_poll_timer_1 %i %i %i %i %02X\n", gustime, gus->t1on, gus->t1, gus->t1l, gus->tctrl); + if (gus->t1on) { + gus->t1++; + if (gus->t1 > 0xFF) { + // gus->t1on=0; + gus->t1 = gus->t1l; + gus->ad_status |= 0x40; + if (gus->tctrl & 4) { + gus->ad_status |= 0x04; + gus->irqstatus |= 0x04; + // pclog("GUS T1 IRQ!\n"); + } + } + } + if (gus->irqnext) { + // pclog("Take IRQ\n"); + gus->irqnext = 0; + gus->irqstatus |= 0x80; + } + gus_midi_update_int_status(gus); + gus_update_int_status(gus); } void gus_poll_timer_2(void *p) { - gus_t *gus = (gus_t *)p; + gus_t *gus = (gus_t *)p; - timer_advance_u64(&gus->timer_2, (uint64_t)(TIMER_USEC * 320)); -// pclog("pollgus2 %i %i %i %i %02X\n", gustime, gus->t2on, gus->t2, gus->t2l, gus->tctrl); - if (gus->t2on) { - gus->t2++; - if (gus->t2 > 0xFF) { -// gus->t2on=0; - gus->t2 = gus->t2l; - gus->ad_status |= 0x20; - if (gus->tctrl & 8) { - gus->ad_status |= 0x02; - gus->irqstatus |= 0x08; -// pclog("GUS T2 IRQ!\n"); - } - } - } - if (gus->irqnext) { -// pclog("Take IRQ\n"); - gus->irqnext = 0; - gus->irqstatus |= 0x80; - } - gus_update_int_status(gus); + timer_advance_u64(&gus->timer_2, (uint64_t)(TIMER_USEC * 320)); + // pclog("pollgus2 %i %i %i %i %02X\n", gustime, gus->t2on, gus->t2, gus->t2l, gus->tctrl); + if (gus->t2on) { + gus->t2++; + if (gus->t2 > 0xFF) { + // gus->t2on=0; + gus->t2 = gus->t2l; + gus->ad_status |= 0x20; + if (gus->tctrl & 8) { + gus->ad_status |= 0x02; + gus->irqstatus |= 0x08; + // pclog("GUS T2 IRQ!\n"); + } + } + } + if (gus->irqnext) { + // pclog("Take IRQ\n"); + gus->irqnext = 0; + gus->irqstatus |= 0x80; + } + gus_update_int_status(gus); } 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; - } + 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_t *gus = (gus_t *)p; + uint32_t addr; + int d; + int16_t v; + int32_t vl; + int update_irqs = 0; - gus_update(gus); + gus_update(gus); - timer_advance_u64(&gus->samp_timer, gus->samp_latch); + timer_advance_u64(&gus->samp_timer, gus->samp_latch); - gus->out_l = gus->out_r = 0; + gus->out_l = gus->out_r = 0; - if ((gus->reset & 3) != 3) - return; -//pclog("gus_poll_wave\n"); - 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->reset & 3) != 3) + return; + // pclog("gus_poll_wave\n"); + 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); + } -// pclog("Voice %i : %04X %05X %04X ", d, v, gus->cur[d] >> 9, gus->rcur[d] >> 10); - 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]; -// pclog("%f %04X\n", vol16bit[(gus->rcur[d]>>10) & 4095], v); + // pclog("Voice %i : %04X %05X %04X ", d, v, gus->cur[d] >> 9, gus->rcur[d] >> 10); + 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]; + // pclog("%f %04X\n", vol16bit[(gus->rcur[d]>>10) & 4095], v); - gus->out_l += (v * gus->pan_l[d]) / 7; - gus->out_r += (v * gus->pan_r[d]) / 7; + 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] & 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] & 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; -// pclog("Causing wave IRQ %02X %i\n", gus->ctrl[d], d); - } - } - } else { - gus->cur[d] += (gus->freq[d] >> 1); + if ((gus->ctrl[d] & 0x20) && !gus->waveirqs[d]) { + gus->waveirqs[d] = 1; + update_irqs = 1; + // pclog("Causing wave IRQ %02X + // %i\n", gus->ctrl[d], d); + } + } + } 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->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] & 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; -// pclog("Causing wave IRQ %02X %i\n", gus->ctrl[d], d); - } - } - } - } - 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->ctrl[d] & 0x20) && !gus->waveirqs[d]) { + gus->waveirqs[d] = 1; + update_irqs = 1; + // pclog("Causing wave IRQ %02X + // %i\n", gus->ctrl[d], d); + } + } + } + } + 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; -// pclog("Causing ramp IRQ %02X %i\n",gus->rctrl[d], d); - } - } - } else { - gus->rcur[d] += gus->rfreq[d]; -// if (d == 1) printf("RCUR+ %i %08X %08X %08X %08X\n",d,gus->rfreq[d],gus->rcur[d],gus->rstart[d],gus->rend[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; + // pclog("Causing ramp IRQ %02X + // %i\n",gus->rctrl[d], d); + } + } + } else { + gus->rcur[d] += gus->rfreq[d]; + // if (d == 1) printf("RCUR+ %i %08X %08X %08X + // %08X\n",d,gus->rfreq[d],gus->rcur[d],gus->rstart[d],gus->rend[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; -// pclog("Causing ramp IRQ %02X %i\n",gus->rctrl[d], d); - } - } - } - } - } + if ((gus->rctrl[d] & 0x20) && !gus->rampirqs[d]) { + gus->rampirqs[d] = 1; + update_irqs = 1; + // pclog("Causing ramp IRQ + // %02X + // %i\n",gus->rctrl[d], d); + } + } + } + } + } - if (update_irqs) - gus_update_int_status(gus); + if (update_irqs) + gus_update_int_status(gus); } static void gus_get_buffer(int32_t *buffer, int len, void *p) { - gus_t *gus = (gus_t *)p; - int c; + gus_t *gus = (gus_t *)p; + int c; - gus_update(gus); + gus_update(gus); - for (c = 0; c < len * 2; c++) { - buffer[c] += (int32_t)gus->buffer[c & 1][c >> 1]; - } + for (c = 0; c < len * 2; c++) { + buffer[c] += (int32_t)gus->buffer[c & 1][c >> 1]; + } - gus->pos = 0; + gus->pos = 0; } void *gus_init() { - int c; - double out = 1.0; - gus_t *gus = malloc(sizeof(gus_t)); - memset(gus, 0, sizeof(gus_t)); + 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); + gus->ram = malloc(1 << 20); + memset(gus->ram, 0, 1 << 20); - pclog("gus_init\n"); + pclog("gus_init\n"); - for (c = 0; c < 32; c++) { - gus->ctrl[c] = 1; - gus->rctrl[c] = 1; - gus->rfreq[c] = 63 * 512; - } + 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;//(float)c/4095.0;//out; - out /= 1.002709201; /* 0.0235 dB Steps */ - } + for (c = 4095; c >= 0; c--) { + vol16bit[c] = out; //(float)c/4095.0;//out; + out /= 1.002709201; /* 0.0235 dB Steps */ + } - printf("Top volume %f %f %f %f\n", vol16bit[4095], vol16bit[3800], vol16bit[3000], vol16bit[2048]); - gus->voices = 14; + printf("Top volume %f %f %f %f\n", vol16bit[4095], vol16bit[3800], vol16bit[3000], vol16bit[2048]); + gus->voices = 14; - gus->samp_latch = (uint64_t)(TIMER_USEC * (1000000.0 / 44100.0)); + gus->samp_latch = (uint64_t)(TIMER_USEC * (1000000.0 / 44100.0)); - gus->t1l = gus->t2l = 0xff; + 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->samp_timer, gus_poll_wave, gus, 1); - timer_add(&gus->timer_1, gus_poll_timer_1, gus, 1); - timer_add(&gus->timer_2, gus_poll_timer_2, gus, 1); + 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->samp_timer, gus_poll_wave, gus, 1); + timer_add(&gus->timer_1, gus_poll_timer_1, gus, 1); + timer_add(&gus->timer_2, gus_poll_timer_2, gus, 1); - sound_add_handler(gus_get_buffer, gus); + sound_add_handler(gus_get_buffer, gus); - return gus; + return gus; } void gus_close(void *p) { - gus_t *gus = (gus_t *)p; + gus_t *gus = (gus_t *)p; - free(gus->ram); - free(gus); + free(gus->ram); + free(gus); } void gus_speed_changed(void *p) { - gus_t *gus = (gus_t *)p; + gus_t *gus = (gus_t *)p; - if (gus->voices < 14) - gus->samp_latch = (uint64_t)(TIMER_USEC * (1000000.0 / 44100.0)); - else - gus->samp_latch = (uint64_t)(TIMER_USEC * (1000000.0 / gusfreqs[gus->voices - 14])); + if (gus->voices < 14) + gus->samp_latch = (uint64_t)(TIMER_USEC * (1000000.0 / 44100.0)); + else + gus->samp_latch = (uint64_t)(TIMER_USEC * (1000000.0 / gusfreqs[gus->voices - 14])); } static void gus_add_status_info(char *s, int max_len, void *p) { - gus_t *gus = (gus_t *)p; - char temps[256]; + gus_t *gus = (gus_t *)p; + char temps[256]; - sprintf(temps, "GUS max voices : %i\nGUS playback frequency : %iHz\n\n", - gus->voices, gusfreqs[gus->voices - 14]); - strncat(s, temps, max_len); + sprintf(temps, "GUS max voices : %i\nGUS playback frequency : %iHz\n\n", gus->voices, gusfreqs[gus->voices - 14]); + strncat(s, temps, max_len); } -device_t gus_device = - { - "Gravis UltraSound", - 0, - gus_init, - gus_close, - NULL, - gus_speed_changed, - NULL, - gus_add_status_info - }; +device_t gus_device = {"Gravis UltraSound", 0, gus_init, gus_close, NULL, gus_speed_changed, NULL, gus_add_status_info}; diff --git a/src/sound/sound_mpu401_uart.c b/src/sound/sound_mpu401_uart.c index b6193457..07e5486d 100644 --- a/src/sound/sound_mpu401_uart.c +++ b/src/sound/sound_mpu401_uart.c @@ -4,85 +4,79 @@ #include "plat-midi.h" #include "sound_mpu401_uart.h" -enum { - STATUS_OUTPUT_NOT_READY = 0x40, - STATUS_INPUT_NOT_READY = 0x80 -}; +enum { STATUS_OUTPUT_NOT_READY = 0x40, STATUS_INPUT_NOT_READY = 0x80 }; static void mpu401_uart_raise_irq(void *p) { - mpu401_uart_t *mpu = (mpu401_uart_t *)p; + mpu401_uart_t *mpu = (mpu401_uart_t *)p; - if (mpu->irq != -1) - picint(1 << mpu->irq); + if (mpu->irq != -1) + picint(1 << mpu->irq); } static void mpu401_uart_write(uint16_t addr, uint8_t val, void *p) { - mpu401_uart_t *mpu = (mpu401_uart_t *)p; + mpu401_uart_t *mpu = (mpu401_uart_t *)p; - if (addr & 1) /*Command*/ - { - switch (val) { - case 0xff: /*Reset*/ - // From Roland: "An ACK will not be sent back upon sending a SYSTEM RESET to leave the UART MODE ($3F)." - // But actual behaviour is weird. For example, the MPU401 port test in the AZT1605 drivers for Windows NT - // want this to return an Ack but the IRQ test in the same driver wants this to raise no interrupts! - mpu->rx_data = 0xfe; /*Acknowledge*/ - mpu->uart_mode = 0; - if (mpu->is_aztech) - mpu->status = STATUS_OUTPUT_NOT_READY; - else { - mpu->status = 0; - mpu401_uart_raise_irq(p); - } - break; + if (addr & 1) /*Command*/ + { + switch (val) { + case 0xff: /*Reset*/ + // From Roland: "An ACK will not be sent back upon sending a SYSTEM RESET to leave the UART MODE ($3F)." + // But actual behaviour is weird. For example, the MPU401 port test in the AZT1605 drivers for Windows NT + // want this to return an Ack but the IRQ test in the same driver wants this to raise no interrupts! + mpu->rx_data = 0xfe; /*Acknowledge*/ + mpu->uart_mode = 0; + if (mpu->is_aztech) + mpu->status = STATUS_OUTPUT_NOT_READY; + else { + mpu->status = 0; + mpu401_uart_raise_irq(p); + } + break; - case 0x3f: /*Enter UART mode*/ - mpu->rx_data = 0xfe; /*Acknowledge*/ - mpu->uart_mode = 1; - if (mpu->is_aztech) { - mpu->status = STATUS_OUTPUT_NOT_READY; - mpu401_uart_raise_irq(p); - } else - mpu->status = 0; - break; - } - return; - } + case 0x3f: /*Enter UART mode*/ + mpu->rx_data = 0xfe; /*Acknowledge*/ + mpu->uart_mode = 1; + if (mpu->is_aztech) { + mpu->status = STATUS_OUTPUT_NOT_READY; + mpu401_uart_raise_irq(p); + } else + mpu->status = 0; + break; + } + return; + } - /*Data*/ - if (mpu->uart_mode) - midi_write(val); + /*Data*/ + if (mpu->uart_mode) + midi_write(val); } static uint8_t mpu401_uart_read(uint16_t addr, void *p) { - mpu401_uart_t *mpu = (mpu401_uart_t *)p; + mpu401_uart_t *mpu = (mpu401_uart_t *)p; - if (addr & 1) /*Status*/ - return mpu->status; + if (addr & 1) /*Status*/ + return mpu->status; - /*Data*/ - mpu->status = STATUS_INPUT_NOT_READY; - return mpu->rx_data; + /*Data*/ + mpu->status = STATUS_INPUT_NOT_READY; + return mpu->rx_data; } void mpu401_uart_init(mpu401_uart_t *mpu, uint16_t addr, int irq, int is_aztech) { - mpu->status = STATUS_INPUT_NOT_READY; - mpu->uart_mode = 0; - mpu->addr = addr; - mpu->irq = irq; - mpu->is_aztech = is_aztech; + mpu->status = STATUS_INPUT_NOT_READY; + mpu->uart_mode = 0; + mpu->addr = addr; + mpu->irq = irq; + mpu->is_aztech = is_aztech; - io_sethandler(addr, 0x0002, mpu401_uart_read, NULL, NULL, mpu401_uart_write, NULL, NULL, mpu); + io_sethandler(addr, 0x0002, mpu401_uart_read, NULL, NULL, mpu401_uart_write, NULL, NULL, mpu); } void mpu401_uart_update_addr(mpu401_uart_t *mpu, uint16_t addr) { - io_removehandler(mpu->addr, 0x0002, mpu401_uart_read, NULL, NULL, mpu401_uart_write, NULL, NULL, mpu); - mpu->addr = addr; - if (addr != 0) - io_sethandler(addr, 0x0002, mpu401_uart_read, NULL, NULL, mpu401_uart_write, NULL, NULL, mpu); -} - -void mpu401_uart_update_irq(mpu401_uart_t *mpu, int irq) { - mpu->irq = irq; + io_removehandler(mpu->addr, 0x0002, mpu401_uart_read, NULL, NULL, mpu401_uart_write, NULL, NULL, mpu); + mpu->addr = addr; + if (addr != 0) + io_sethandler(addr, 0x0002, mpu401_uart_read, NULL, NULL, mpu401_uart_write, NULL, NULL, mpu); } +void mpu401_uart_update_irq(mpu401_uart_t *mpu, int irq) { mpu->irq = irq; } diff --git a/src/sound/sound_opl.c b/src/sound/sound_opl.c index 8f09b97b..556ee219 100644 --- a/src/sound/sound_opl.c +++ b/src/sound/sound_opl.c @@ -9,136 +9,126 @@ /*Interfaces between PCem and the actual OPL emulator*/ - uint8_t opl2_read(uint16_t a, void *priv) { - opl_t *opl = (opl_t *)priv; + opl_t *opl = (opl_t *)priv; - cycles -= (int)(isa_timing * 8); - opl2_update2(opl); - return opl_read(0, a); + 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; + opl_t *opl = (opl_t *)priv; - opl2_update2(opl); - opl_write(0, a, v); - opl_write(1, a, v); + 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; + opl_t *opl = (opl_t *)priv; - cycles -= (int)(isa_timing * 8); - opl2_update2(opl); - return opl_read(0, a); + 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; + opl_t *opl = (opl_t *)priv; - opl2_update2(opl); - opl_write(0, a, v); + opl2_update2(opl); + opl_write(0, a, v); } uint8_t opl2_r_read(uint16_t a, void *priv) { - opl_t *opl = (opl_t *)priv; + opl_t *opl = (opl_t *)priv; - cycles -= (int)(isa_timing * 8); - opl2_update2(opl); - return opl_read(1, a); + 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; + opl_t *opl = (opl_t *)priv; - opl2_update2(opl); - opl_write(1, a, v); + opl2_update2(opl); + opl_write(1, a, v); } uint8_t opl3_read(uint16_t a, void *priv) { - opl_t *opl = (opl_t *)priv; + opl_t *opl = (opl_t *)priv; - cycles -= (int)(isa_timing * 8); - opl3_update2(opl); - return opl_read(0, a); + 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; + opl_t *opl = (opl_t *)priv; - opl3_update2(opl); - opl_write(0, a, v); + 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); - } - } + 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); - } - } + 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_t *opl = (opl_t *)param; - if (period) - timer_set_delay_u64(&opl->timers[0][timer], period * TIMER_USEC * 20); - else - timer_disable(&opl->timers[0][timer]); + if (period) + timer_set_delay_u64(&opl->timers[0][timer], period * TIMER_USEC * 20); + else + timer_disable(&opl->timers[0][timer]); } void ym3812_timer_set_1(void *param, int timer, int64_t period) { - opl_t *opl = (opl_t *)param; + opl_t *opl = (opl_t *)param; - if (period) - timer_set_delay_u64(&opl->timers[1][timer], period * TIMER_USEC * 20); - else - timer_disable(&opl->timers[1][timer]); + if (period) + timer_set_delay_u64(&opl->timers[1][timer], period * TIMER_USEC * 20); + else + timer_disable(&opl->timers[1][timer]); } void ymf262_timer_set(void *param, int timer, int64_t period) { - opl_t *opl = (opl_t *)param; + opl_t *opl = (opl_t *)param; - if (period) - timer_set_delay_u64(&opl->timers[0][timer], period * TIMER_USEC * 20); - else - timer_disable(&opl->timers[0][timer]); + if (period) + timer_set_delay_u64(&opl->timers[0][timer], period * TIMER_USEC * 20); + else + timer_disable(&opl->timers[0][timer]); } -static void opl_timer_callback00(void *p) { - opl_timer_over(0, 0); -} -static void opl_timer_callback01(void *p) { - opl_timer_over(0, 1); -} -static void opl_timer_callback10(void *p) { - opl_timer_over(1, 0); -} -static void opl_timer_callback11(void *p) { - opl_timer_over(1, 1); -} +static void opl_timer_callback00(void *p) { opl_timer_over(0, 0); } +static void opl_timer_callback01(void *p) { opl_timer_over(0, 1); } +static void opl_timer_callback10(void *p) { opl_timer_over(1, 0); } +static void opl_timer_callback11(void *p) { opl_timer_over(1, 1); } void opl2_init(opl_t *opl) { - opl_init(ym3812_timer_set_0, opl, 0, 0, 0); - opl_init(ym3812_timer_set_1, opl, 1, 0, 0); - timer_add(&opl->timers[0][0], opl_timer_callback00, (void *)opl, 0); - timer_add(&opl->timers[0][1], opl_timer_callback01, (void *)opl, 0); - timer_add(&opl->timers[1][0], opl_timer_callback10, (void *)opl, 0); - timer_add(&opl->timers[1][1], opl_timer_callback11, (void *)opl, 0); + opl_init(ym3812_timer_set_0, opl, 0, 0, 0); + opl_init(ym3812_timer_set_1, opl, 1, 0, 0); + timer_add(&opl->timers[0][0], opl_timer_callback00, (void *)opl, 0); + timer_add(&opl->timers[0][1], opl_timer_callback01, (void *)opl, 0); + timer_add(&opl->timers[1][0], opl_timer_callback10, (void *)opl, 0); + timer_add(&opl->timers[1][1], opl_timer_callback11, (void *)opl, 0); } void opl3_init(opl_t *opl, int opl_emu) { - opl_init(ymf262_timer_set, opl, 0, 1, opl_emu); - timer_add(&opl->timers[0][0], opl_timer_callback00, (void *)opl, 0); - timer_add(&opl->timers[0][1], opl_timer_callback01, (void *)opl, 0); + opl_init(ymf262_timer_set, opl, 0, 1, opl_emu); + timer_add(&opl->timers[0][0], opl_timer_callback00, (void *)opl, 0); + timer_add(&opl->timers[0][1], opl_timer_callback01, (void *)opl, 0); } - diff --git a/src/sound/sound_pas16.c b/src/sound/sound_pas16.c index 24b55003..f5fbcc9e 100644 --- a/src/sound/sound_pas16.c +++ b/src/sound/sound_pas16.c @@ -19,122 +19,122 @@ 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 - + + 178b - 2789 - board revision - + 8389 - bit 2 - 8/16 bit - + BF88 - wait states - + EF8B - bit 3 - 16 bits okay ? - - F388 - + + 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; + uint16_t base; - int irq, dma; + int irq, dma; - uint8_t audiofilt; + uint8_t audiofilt; - uint8_t audio_mixer; + uint8_t audio_mixer; - uint8_t compat, compat_base; + uint8_t compat, compat_base; - uint8_t enhancedscsi; + uint8_t enhancedscsi; - uint8_t io_conf_1, io_conf_2, io_conf_3, io_conf_4; + uint8_t io_conf_1, io_conf_2, io_conf_3, io_conf_4; - uint8_t irq_stat, irq_ena; + uint8_t irq_stat, irq_ena; - uint8_t pcm_ctrl; - uint16_t pcm_dat; + uint8_t pcm_ctrl; + uint16_t pcm_dat; - uint16_t pcm_dat_l, pcm_dat_r; + uint16_t pcm_dat_l, pcm_dat_r; - uint8_t sb_irqdma; + uint8_t sb_irqdma; - int stereo_lr; + int stereo_lr; - uint8_t sys_conf_1, sys_conf_2, sys_conf_3, sys_conf_4; + uint8_t sys_conf_1, sys_conf_2, sys_conf_3, sys_conf_4; - struct { - uint32_t l[3]; - int c[3]; - pc_timer_t timer[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]; - int enable[3]; - } pit; + struct { + uint32_t l[3]; + int c[3]; + pc_timer_t timer[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]; + int enable[3]; + } pit; - opl_t opl; - sb_dsp_t dsp; + opl_t opl; + sb_dsp_t dsp; - int16_t pcm_buffer[2][MAXSOUNDBUFLEN]; + int16_t pcm_buffer[2][MAXSOUNDBUFLEN]; - int pos; + int pos; } pas16_t; static uint8_t pas16_pit_in(uint16_t port, void *priv); @@ -147,537 +147,569 @@ 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, + PAS16_INT_SAMP = 0x04, + PAS16_INT_PCM = 0x08, }; -enum { - PAS16_PCM_MONO = 0x20, - PAS16_PCM_ENA = 0x40 -}; +enum { PAS16_PCM_MONO = 0x20, PAS16_PCM_ENA = 0x40 }; -enum { - PAS16_SC2_16BIT = 0x04, - PAS16_SC2_MSBINV = 0x10 -}; +enum { PAS16_SC2_16BIT = 0x04, PAS16_SC2_MSBINV = 0x10 }; -enum { - PAS16_FILT_MUTE = 0x20 -}; +enum { PAS16_FILT_MUTE = 0x20 }; static uint8_t pas16_in(uint16_t port, void *p) { - pas16_t *pas16 = (pas16_t *)p; - uint8_t temp = 0xff; -/* 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; + pas16_t *pas16 = (pas16_t *)p; + uint8_t temp = 0xff; + /* 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 0xb88: + temp = pas16->audio_mixer; + break; - case 0xb89:temp = pas16->irq_stat; - break; + case 0xb89: + temp = pas16->irq_stat; + break; - case 0xb8a:temp = pas16->audiofilt; - break; + case 0xb8a: + temp = pas16->audiofilt; + break; - case 0xb8b:temp = (pas16->irq_ena & ~0xe0) | 0x20; - break; + case 0xb8b: + temp = (pas16->irq_ena & ~0xe0) | 0x20; + break; - case 0xf8a:temp = pas16->pcm_ctrl; - break; + case 0xf8a: + temp = pas16->pcm_ctrl; + break; - case 0x1388: - case 0x1389: - case 0x138a: - case 0x138b:temp = pas16_pit_in(port, pas16); - break; + case 0x1388: + case 0x1389: + case 0x138a: + case 0x138b: + temp = pas16_pit_in(port, pas16); + break; - case 0x2789: /*Board revision*/ - temp = 0; - break; + case 0x2789: /*Board revision*/ + temp = 0; + break; - case 0x7f89:temp = pas16->enhancedscsi & ~1; - 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 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 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 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 0xf788: + temp = pas16->compat; + break; + case 0xf789: + temp = pas16->compat_base; + break; - case 0xfb8a:temp = pas16->sb_irqdma; - 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; - } -/* if (port != 0x388 && port != 0x389 && port != 0xb8b) */pclog("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; + case 0xff88: /*Board model*/ + temp = 4; /*PAS16*/ + break; + case 0xff8b: /*Master mode read*/ + temp = 0x20 | 0x10 | 0x01; /*AT bus, XT/AT timing*/ + break; + } + /* if (port != 0x388 && port != 0x389 && port != 0xb8b) */ pclog("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) */pclog("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; + pas16_t *pas16 = (pas16_t *)p; + /* if (port != 0x388 && port != 0x389) */ pclog("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 0xb88: + pas16->audio_mixer = val; + break; - case 0xb89:pas16->irq_stat &= ~val; -// pas16_update_irqs(); - break; + case 0xb89: + pas16->irq_stat &= ~val; + // pas16_update_irqs(); + break; - case 0xb8a:pas16_update(pas16); - pas16->audiofilt = val; - break; + case 0xb8a: + pas16_update(pas16); + pas16->audiofilt = val; + break; - case 0xb8b:pas16->irq_ena = val; -// pas16_update_irqs(); - break; + case 0xb8b: + pas16->irq_ena = val; + // pas16_update_irqs(); + 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 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 0x1388: + case 0x1389: + case 0x138a: + case 0x138b: + pas16_pit_out(port, val, pas16); + break; - case 0x7f89:pas16->enhancedscsi = val; - 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 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]; - pclog("pas16_out : set PAS DMA %i\n", pas16->dma); - break; - case 0xf38a:pas16->io_conf_3 = val; - pas16->irq = pas16_irqs[val & 0xf]; - pclog("pas16_out : set PAS IRQ %i\n", pas16->irq); - break; - case 0xf38b:pas16->io_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]; + pclog("pas16_out : set PAS DMA %i\n", pas16->dma); + break; + case 0xf38a: + pas16->io_conf_3 = val; + pas16->irq = pas16_irqs[val & 0xf]; + pclog("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 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]); - pclog("pas16_out : set SB IRQ %i DMA %i\n", pas16_sb_irqs[(val >> 3) & 7], pas16_sb_dmas[(val >> 6) & 3]); - 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]); + pclog("pas16_out : set SB IRQ %i DMA %i\n", pas16_sb_irqs[(val >> 3) & 7], pas16_sb_dmas[(val >> 6) & 3]); + break; - default:pclog("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;*/ + default: + pclog("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] = timer_get_remaining_u64(&pit.timer[0]) / PITCONST;; - 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) { - printf("Bad PIT reg select\n"); - return; - } - if (!(pas16->pit.ctrl & 0x30)) { - if (!t) - pas16->pit.rl[t] = timer_get_remaining_u64(&pit.timer[t]) / PITCONST; - else { - pas16->pit.rl[t] = pas16->pit.c[t]; - 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; - if (!t) - pas16->pit.rl[t] = timer_get_remaining_u64(&pit.timer[t]) / PITCONST; - else - pas16->pit.rl[t] = pas16->pit.c[t]; - } - 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) - timer_set_delay_u64(&pas16->pit.timer[t], pas16->pit.c[t] * PITCONST); - 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) - timer_set_delay_u64(&pas16->pit.timer[t], pas16->pit.c[t] * PITCONST); - 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) - timer_set_delay_u64(&pas16->pit.timer[t], pas16->pit.c[t] * PITCONST); - 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) - timer_set_delay_u64(&pas16->pit.timer[t], pas16->pit.c[t] * PITCONST); - } - break; - } + 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] = timer_get_remaining_u64(&pit.timer[0]) / PITCONST; + ; + 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) { + printf("Bad PIT reg select\n"); + return; + } + if (!(pas16->pit.ctrl & 0x30)) { + if (!t) + pas16->pit.rl[t] = timer_get_remaining_u64(&pit.timer[t]) / PITCONST; + else { + pas16->pit.rl[t] = pas16->pit.c[t]; + 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; + if (!t) + pas16->pit.rl[t] = timer_get_remaining_u64(&pit.timer[t]) / PITCONST; + else + pas16->pit.rl[t] = pas16->pit.c[t]; + } + 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) + timer_set_delay_u64(&pas16->pit.timer[t], pas16->pit.c[t] * PITCONST); + 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) + timer_set_delay_u64(&pas16->pit.timer[t], pas16->pit.c[t] * PITCONST); + 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) + timer_set_delay_u64(&pas16->pit.timer[t], pas16->pit.c[t] * PITCONST); + 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) + timer_set_delay_u64(&pas16->pit.timer[t], pas16->pit.c[t] * PITCONST); + } + 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; -// printf("Read PIT %04X ",addr); - 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] = timer_get_remaining_u64(&pit.timer[t]) / PITCONST; - if ((timer_get_remaining_u64(&pit.timer[t]) / PITCONST) > 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; - } -// printf("%02X %i %i %04X:%04X\n",temp,pit.rm[addr&3],pit.wp,cs>>4,pc); - return temp; + pas16_t *pas16 = (pas16_t *)p; + uint8_t temp = 0xff; + int t = port & 3; + // printf("Read PIT %04X ",addr); + 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] = timer_get_remaining_u64(&pit.timer[t]) / PITCONST; + if ((timer_get_remaining_u64(&pit.timer[t]) / PITCONST) > 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; + } + // printf("%02X %i %i %04X:%04X\n",temp,pit.rm[addr&3],pit.wp,cs>>4,pc); + return temp; } -static uint8_t pas16_readdma(pas16_t *pas16) { - return dma_channel_read(pas16->dma); -} +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_t *pas16 = (pas16_t *)p; - pas16_update(pas16); -// if (pas16->pcm_ctrl & PAS16_PCM_ENA) -// pclog("pas16_pcm_poll : poll %i %i ", pas16->pit.c[0], pas16->pit.l[0]); - if (pas16->pit.m[0] & 2) { - if (pas16->pit.l[0]) - timer_advance_u64(&pas16->pit.timer[0], pas16->pit.l[0] * PITCONST); - else - timer_advance_u64(&pas16->pit.timer[0], 0x10000 * PITCONST); - } else { - pas16->pit.enable[0] = 0; - } -// if (pas16->pcm_ctrl & PAS16_PCM_ENA) -// pclog(" %i\n", pas16->pit.c[0]); + pas16_update(pas16); + // if (pas16->pcm_ctrl & PAS16_PCM_ENA) + // pclog("pas16_pcm_poll : poll %i %i ", pas16->pit.c[0], pas16->pit.l[0]); + if (pas16->pit.m[0] & 2) { + if (pas16->pit.l[0]) + timer_advance_u64(&pas16->pit.timer[0], pas16->pit.l[0] * PITCONST); + else + timer_advance_u64(&pas16->pit.timer[0], 0x10000 * PITCONST); + } else { + pas16->pit.enable[0] = 0; + } + // if (pas16->pcm_ctrl & PAS16_PCM_ENA) + // pclog(" %i\n", pas16->pit.c[0]); - pas16->irq_stat |= PAS16_INT_SAMP; - if (pas16->irq_ena & PAS16_INT_SAMP) - picint(1 << pas16->irq); -// pas16_update_irqs(); + pas16->irq_stat |= PAS16_INT_SAMP; + if (pas16->irq_ena & PAS16_INT_SAMP) + picint(1 << pas16->irq); + // pas16_update_irqs(); - /*Update sample rate counter*/ - if (pas16->pit.enable[1]) { - if (pas16->pcm_ctrl & PAS16_PCM_ENA) { - uint16_t temp; + /*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_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; + 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; - } -// pclog("pas16_pcm_poll : %04X %i\n", temp, pas16->stereo_lr); -// pclog("pas16_pcm_poll : %i %02X %i\n", pas16->pit.c[1], temp, pas16->pit.c[0]); -/* if (!pas16_pcm) - pas16_pcm=fopen("pas16->pcm", "wb"); - putc(temp, pas16_pcm);*/ - } - 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->pcm_ctrl & PAS16_PCM_ENA) -// pclog("pas16_pcm_poll : buffer over\n"); - 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->stereo_lr = !pas16->stereo_lr; + } + // pclog("pas16_pcm_poll : %04X %i\n", temp, pas16->stereo_lr); + // pclog("pas16_pcm_poll : %i %02X %i\n", pas16->pit.c[1], temp, pas16->pit.c[0]); + /* if (!pas16_pcm) + pas16_pcm=fopen("pas16->pcm", "wb"); + putc(temp, pas16_pcm);*/ + } + 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->pcm_ctrl & PAS16_PCM_ENA) + // pclog("pas16_pcm_poll : buffer over\n"); + 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) { - pclog("pas16_pcm_poll : cause IRQ %i %02X\n", pas16->irq, 1 << pas16->irq); - picint(1 << pas16->irq); - } - } - } + pas16->irq_stat |= PAS16_INT_PCM; + if (pas16->irq_ena & PAS16_INT_PCM) { + pclog("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; + 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); + 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; - pclog("pas16_write_base : PAS16 base now at %04X\n", pas16->base); + pas16->base = val << 2; + pclog("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); + 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; - } - } + 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; + 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); - } + 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; + pas16->pos = 0; + pas16->opl.pos = 0; + pas16->dsp.pos = 0; } void *pas16_init() { - pas16_t *pas16 = malloc(sizeof(pas16_t)); - memset(pas16, 0, sizeof(pas16_t)); + pas16_t *pas16 = malloc(sizeof(pas16_t)); + memset(pas16, 0, sizeof(pas16_t)); - opl3_init(&pas16->opl, 0); - sb_dsp_init(&pas16->dsp, SB2, SB_SUBTYPE_DEFAULT, pas16); + opl3_init(&pas16->opl, 0); + sb_dsp_init(&pas16->dsp, SB2, SB_SUBTYPE_DEFAULT, pas16); - io_sethandler(0x9a01, 0x0001, NULL, NULL, NULL, pas16_out_base, NULL, NULL, pas16); + io_sethandler(0x9a01, 0x0001, NULL, NULL, NULL, pas16_out_base, NULL, NULL, pas16); - timer_add(&pas16->pit.timer[0], pas16_pcm_poll, pas16, 0); + timer_add(&pas16->pit.timer[0], pas16_pcm_poll, pas16, 0); - sound_add_handler(pas16_get_buffer, pas16); + sound_add_handler(pas16_get_buffer, pas16); - return pas16; + return pas16; } void pas16_close(void *p) { - pas16_t *pas16 = (pas16_t *)p; + pas16_t *pas16 = (pas16_t *)p; - free(pas16); + free(pas16); } -device_t pas16_device = - { - "Pro Audio Spectrum 16", - DEVICE_NOT_WORKING, - pas16_init, - pas16_close, - NULL, - NULL, - NULL, - NULL - }; +device_t pas16_device = {"Pro Audio Spectrum 16", DEVICE_NOT_WORKING, pas16_init, pas16_close, NULL, NULL, NULL, NULL}; diff --git a/src/sound/sound_ps1.c b/src/sound/sound_ps1.c index d6f87273..1c197183 100644 --- a/src/sound/sound_ps1.c +++ b/src/sound/sound_ps1.c @@ -8,159 +8,151 @@ #include "sound_sn76489.h" typedef struct ps1_audio_t { - sn76489_t sn76489; + sn76489_t sn76489; - uint8_t status, ctrl; + uint8_t status, ctrl; - uint64_t timer_latch; - pc_timer_t timer; + uint64_t timer_latch; + pc_timer_t timer; - uint8_t fifo[2048]; - int fifo_read_idx, fifo_write_idx; - int fifo_threshold; + uint8_t fifo[2048]; + int fifo_read_idx, fifo_write_idx; + int fifo_threshold; - uint8_t dac_val; + uint8_t dac_val; - int16_t buffer[MAXSOUNDBUFLEN]; - int pos; + int16_t buffer[MAXSOUNDBUFLEN]; + int pos; } ps1_audio_t; static void ps1_update_irq_status(ps1_audio_t *ps1) { - if (((ps1->status & ps1->ctrl) & 0x12) && (ps1->ctrl & 0x01)) - picint(1 << 7); - else - picintc(1 << 7); + if (((ps1->status & ps1->ctrl) & 0x12) && (ps1->ctrl & 0x01)) + picint(1 << 7); + else + picintc(1 << 7); } static uint8_t ps1_audio_read(uint16_t port, void *p) { - ps1_audio_t *ps1 = (ps1_audio_t *)p; - uint8_t temp; + ps1_audio_t *ps1 = (ps1_audio_t *)p; + uint8_t temp; -// pclog("ps1_audio_read %04x %04x:%04x\n", port, CS, pc); + // pclog("ps1_audio_read %04x %04x:%04x\n", port, CS, pc); - switch (port & 7) { - case 0: /*ADC data*/ - ps1->status &= ~0x10; - ps1_update_irq_status(ps1); - return 0; - case 2: /*Status*/ - temp = ps1->status; - temp |= (ps1->ctrl & 0x01); - if ((ps1->fifo_write_idx - ps1->fifo_read_idx) >= 2048) - temp |= 0x08; /*FIFO full*/ - if (ps1->fifo_read_idx == ps1->fifo_write_idx) - temp |= 0x04; /*FIFO empty*/ -// pclog("Return status %02x\n", temp); - return temp; - case 3: /*FIFO timer*/ - /*PS/1 technical reference says this should return the current value, - but the PS/1 BIOS and Stunt Island expect it not to change*/ - return ps1->timer_latch; - case 4: - case 5: - case 6: - case 7:return 0; - } - return 0xff; + switch (port & 7) { + case 0: /*ADC data*/ + ps1->status &= ~0x10; + ps1_update_irq_status(ps1); + return 0; + case 2: /*Status*/ + temp = ps1->status; + temp |= (ps1->ctrl & 0x01); + if ((ps1->fifo_write_idx - ps1->fifo_read_idx) >= 2048) + temp |= 0x08; /*FIFO full*/ + if (ps1->fifo_read_idx == ps1->fifo_write_idx) + temp |= 0x04; /*FIFO empty*/ + // pclog("Return status %02x\n", temp); + return temp; + case 3: /*FIFO timer*/ + /*PS/1 technical reference says this should return the current value, + but the PS/1 BIOS and Stunt Island expect it not to change*/ + return ps1->timer_latch; + case 4: + case 5: + case 6: + case 7: + return 0; + } + return 0xff; } static void ps1_audio_write(uint16_t port, uint8_t val, void *p) { - ps1_audio_t *ps1 = (ps1_audio_t *)p; + ps1_audio_t *ps1 = (ps1_audio_t *)p; -// pclog("ps1_audio_write %04x %02x\n", port, val); + // pclog("ps1_audio_write %04x %02x\n", port, val); - switch (port & 7) { - case 0: /*DAC output*/ -// pclog("DAC write %08x %08x %i\n", ps1->fifo_write_idx, ps1->fifo_read_idx, ps1->fifo_write_idx - ps1->fifo_read_idx); - if ((ps1->fifo_write_idx - ps1->fifo_read_idx) < 2048) { - ps1->fifo[ps1->fifo_write_idx & 2047] = val; - ps1->fifo_write_idx++; - } - break; - case 2: /*Control*/ - ps1->ctrl = val; - if (!(val & 0x02)) - ps1->status &= ~0x02; - ps1_update_irq_status(ps1); - break; - case 3: /*Timer reload value*/ - ps1->timer_latch = val; - if (val) - timer_set_delay_u64(&ps1->timer, (0xff - val) * TIMER_USEC); - else - timer_disable(&ps1->timer); - break; - case 4: /*Almost empty*/ - ps1->fifo_threshold = val * 4; - break; - } + switch (port & 7) { + case 0: /*DAC output*/ + // pclog("DAC write %08x %08x %i\n", ps1->fifo_write_idx, ps1->fifo_read_idx, ps1->fifo_write_idx - + // ps1->fifo_read_idx); + if ((ps1->fifo_write_idx - ps1->fifo_read_idx) < 2048) { + ps1->fifo[ps1->fifo_write_idx & 2047] = val; + ps1->fifo_write_idx++; + } + break; + case 2: /*Control*/ + ps1->ctrl = val; + if (!(val & 0x02)) + ps1->status &= ~0x02; + ps1_update_irq_status(ps1); + break; + case 3: /*Timer reload value*/ + ps1->timer_latch = val; + if (val) + timer_set_delay_u64(&ps1->timer, (0xff - val) * TIMER_USEC); + else + timer_disable(&ps1->timer); + break; + case 4: /*Almost empty*/ + ps1->fifo_threshold = val * 4; + break; + } } static void ps1_audio_update(ps1_audio_t *ps1) { - for (; ps1->pos < sound_pos_global; ps1->pos++) - ps1->buffer[ps1->pos] = (int8_t)(ps1->dac_val ^ 0x80) * 0x20; + for (; ps1->pos < sound_pos_global; ps1->pos++) + ps1->buffer[ps1->pos] = (int8_t)(ps1->dac_val ^ 0x80) * 0x20; } static void ps1_audio_callback(void *p) { - ps1_audio_t *ps1 = (ps1_audio_t *)p; + ps1_audio_t *ps1 = (ps1_audio_t *)p; - ps1_audio_update(ps1); + ps1_audio_update(ps1); - if (ps1->fifo_read_idx != ps1->fifo_write_idx) { - ps1->dac_val = ps1->fifo[ps1->fifo_read_idx & 2047]; - ps1->fifo_read_idx++; - } -// pclog("ps1_callback %08x %08x %08x\n", ps1->fifo_write_idx, ps1->fifo_read_idx, ps1->fifo_threshold); - if ((ps1->fifo_write_idx - ps1->fifo_read_idx) == ps1->fifo_threshold) { -// pclog("FIFO almost empty\n"); - ps1->status |= 0x02; /*FIFO almost empty*/ - } - ps1->status |= 0x10; /*ADC data ready*/ - ps1_update_irq_status(ps1); + if (ps1->fifo_read_idx != ps1->fifo_write_idx) { + ps1->dac_val = ps1->fifo[ps1->fifo_read_idx & 2047]; + ps1->fifo_read_idx++; + } + // pclog("ps1_callback %08x %08x %08x\n", ps1->fifo_write_idx, ps1->fifo_read_idx, ps1->fifo_threshold); + if ((ps1->fifo_write_idx - ps1->fifo_read_idx) == ps1->fifo_threshold) { + // pclog("FIFO almost empty\n"); + ps1->status |= 0x02; /*FIFO almost empty*/ + } + ps1->status |= 0x10; /*ADC data ready*/ + ps1_update_irq_status(ps1); - timer_advance_u64(&ps1->timer, ps1->timer_latch * TIMER_USEC); + timer_advance_u64(&ps1->timer, ps1->timer_latch * TIMER_USEC); } static void ps1_audio_get_buffer(int32_t *buffer, int len, void *p) { - ps1_audio_t *ps1 = (ps1_audio_t *)p; - int c; + ps1_audio_t *ps1 = (ps1_audio_t *)p; + int c; - ps1_audio_update(ps1); + ps1_audio_update(ps1); - for (c = 0; c < len * 2; c++) - buffer[c] += ps1->buffer[c >> 1]; + for (c = 0; c < len * 2; c++) + buffer[c] += ps1->buffer[c >> 1]; - ps1->pos = 0; + ps1->pos = 0; } static void *ps1_audio_init() { - ps1_audio_t *ps1 = malloc(sizeof(ps1_audio_t)); - memset(ps1, 0, sizeof(ps1_audio_t)); + ps1_audio_t *ps1 = malloc(sizeof(ps1_audio_t)); + memset(ps1, 0, sizeof(ps1_audio_t)); - sn76489_init(&ps1->sn76489, 0x0205, 0x0001, SN76496, 4000000); + sn76489_init(&ps1->sn76489, 0x0205, 0x0001, SN76496, 4000000); - io_sethandler(0x0200, 0x0001, ps1_audio_read, NULL, NULL, ps1_audio_write, NULL, NULL, ps1); - io_sethandler(0x0202, 0x0006, ps1_audio_read, NULL, NULL, ps1_audio_write, NULL, NULL, ps1); - timer_add(&ps1->timer, ps1_audio_callback, ps1, 0); - sound_add_handler(ps1_audio_get_buffer, ps1); + io_sethandler(0x0200, 0x0001, ps1_audio_read, NULL, NULL, ps1_audio_write, NULL, NULL, ps1); + io_sethandler(0x0202, 0x0006, ps1_audio_read, NULL, NULL, ps1_audio_write, NULL, NULL, ps1); + timer_add(&ps1->timer, ps1_audio_callback, ps1, 0); + sound_add_handler(ps1_audio_get_buffer, ps1); - return ps1; + return ps1; } static void ps1_audio_close(void *p) { - ps1_audio_t *ps1 = (ps1_audio_t *)p; + ps1_audio_t *ps1 = (ps1_audio_t *)p; - free(ps1); + free(ps1); } -device_t ps1_audio_device = - { - "PS/1 Audio Card", - 0, - ps1_audio_init, - ps1_audio_close, - NULL, - NULL, - NULL, - NULL - }; +device_t ps1_audio_device = {"PS/1 Audio Card", 0, ps1_audio_init, ps1_audio_close, NULL, NULL, NULL, NULL}; diff --git a/src/sound/sound_pssj.c b/src/sound/sound_pssj.c index 039384b9..e3d61e6c 100644 --- a/src/sound/sound_pssj.c +++ b/src/sound/sound_pssj.c @@ -11,182 +11,180 @@ #include "timer.h" typedef struct pssj_t { - sn76489_t sn76489; + sn76489_t sn76489; - uint8_t ctrl; - uint8_t wave; - uint8_t dac_val; - uint16_t freq; - int amplitude; + uint8_t ctrl; + uint8_t wave; + uint8_t dac_val; + uint16_t freq; + int amplitude; - int irq; - pc_timer_t timer; - int enable; + int irq; + pc_timer_t timer; + int enable; - int wave_pos; - int pulse_width; + int wave_pos; + int pulse_width; - int16_t buffer[MAXSOUNDBUFLEN]; - int pos; + int16_t buffer[MAXSOUNDBUFLEN]; + int pos; } pssj_t; static void pssj_update_irq(pssj_t *pssj) { - if (pssj->irq && (pssj->ctrl & 0x10) && (pssj->ctrl & 0x08)) - picint(1 << 7); + 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; + pssj_t *pssj = (pssj_t *)p; -// pclog("pssj_write: port=%04x val=%02x\n", port, val); - switch (port & 3) { - case 0:pssj->ctrl = val; + // pclog("pssj_write: port=%04x val=%02x\n", port, val); + switch (port & 3) { + case 0: + pssj->ctrl = val; - if (!pssj->enable && ((val & 4) && (pssj->ctrl & 3))) - timer_set_delay_u64(&pssj->timer, (TIMER_USEC * (1000000.0 / 3579545.0) * (double)(pssj->freq ? pssj->freq : 0x400))); - pssj->enable = (val & 4) && (pssj->ctrl & 3); - if (!pssj->enable) - timer_disable(&pssj->timer); + if (!pssj->enable && ((val & 4) && (pssj->ctrl & 3))) + timer_set_delay_u64(&pssj->timer, + (TIMER_USEC * (1000000.0 / 3579545.0) * (double)(pssj->freq ? pssj->freq : 0x400))); + pssj->enable = (val & 4) && (pssj->ctrl & 3); + if (!pssj->enable) + timer_disable(&pssj->timer); - 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; - } + 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; + pssj_t *pssj = (pssj_t *)p; -// pclog("pssj_read: port=%04x %02x\n", port, (pssj->ctrl & ~0x88) | (pssj->irq ? 8 : 0)); - 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); - } + // pclog("pssj_read: port=%04x %02x\n", port, (pssj->ctrl & ~0x88) | (pssj->irq ? 8 : 0)); + 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); + } - 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; + 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_t *pssj = (pssj_t *)p; + int data; - pssj_update(pssj); - if (pssj->ctrl & 2) { - if ((pssj->ctrl & 3) == 3) { - data = dma_channel_read(1); + 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; -// pclog("DAC_val=%02x\n", data); - } - } else { - data = dma_channel_write(1, 0x80); - } + if (data != DMA_NODATA) { + pssj->dac_val = data & 0xff; + // pclog("DAC_val=%02x\n", data); + } + } else { + data = dma_channel_write(1, 0x80); + } - if ((data & DMA_OVER) && data != DMA_NODATA) { -// pclog("Check IRQ %i %02x\n", pssj->irq, pssj->ctrl); - 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; - } + if ((data & DMA_OVER) && data != DMA_NODATA) { + // pclog("Check IRQ %i %02x\n", pssj->irq, pssj->ctrl); + 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; + } - timer_advance_u64(&pssj->timer, (TIMER_USEC * (1000000.0 / 3579545.0) * (double)(pssj->freq ? pssj->freq : 0x400))); + timer_advance_u64(&pssj->timer, (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_t *pssj = (pssj_t *)p; + int c; - pssj_update(pssj); + pssj_update(pssj); - for (c = 0; c < len * 2; c++) - buffer[c] += pssj->buffer[c >> 1]; + for (c = 0; c < len * 2; c++) + buffer[c] += pssj->buffer[c >> 1]; - pssj->pos = 0; + pssj->pos = 0; } void *pssj_init() { - pssj_t *pssj = malloc(sizeof(pssj_t)); - memset(pssj, 0, sizeof(pssj_t)); + pssj_t *pssj = malloc(sizeof(pssj_t)); + memset(pssj, 0, sizeof(pssj_t)); - sn76489_init(&pssj->sn76489, 0x00c0, 0x0004, PSSJ, 3579545); + sn76489_init(&pssj->sn76489, 0x00c0, 0x0004, PSSJ, 3579545); - io_sethandler(0x00C4, 0x0004, pssj_read, NULL, NULL, pssj_write, NULL, NULL, pssj); - timer_add(&pssj->timer, pssj_callback, pssj, 0); - sound_add_handler(pssj_get_buffer, pssj); + io_sethandler(0x00C4, 0x0004, pssj_read, NULL, NULL, pssj_write, NULL, NULL, pssj); + timer_add(&pssj->timer, pssj_callback, pssj, 0); + sound_add_handler(pssj_get_buffer, pssj); - return pssj; + return pssj; } void pssj_close(void *p) { - pssj_t *pssj = (pssj_t *)p; + pssj_t *pssj = (pssj_t *)p; - free(pssj); + free(pssj); } -device_t pssj_device = - { - "Tandy PSSJ", - 0, - pssj_init, - pssj_close, - NULL, - NULL, - NULL, - NULL - }; +device_t pssj_device = {"Tandy PSSJ", 0, pssj_init, pssj_close, NULL, NULL, NULL, NULL}; diff --git a/src/sound/sound_resid.cc b/src/sound/sound_resid.cc index 95df8d42..1ebdac29 100644 --- a/src/sound/sound_resid.cc +++ b/src/sound/sound_resid.cc @@ -6,93 +6,92 @@ #include "sound_resid.h" typedef struct psid_t { - /* resid sid implementation */ - SIDFP *sid; - int16_t last_sample; + /* resid sid implementation */ + SIDFP *sid; + int16_t last_sample; } psid_t; psid_t *psid; void *sid_init() { -// psid_t *psid; - int c; - sampling_method method = SAMPLE_INTERPOLATE; - float cycles_per_sec = 14318180.0 / 16.0; + // 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 = new psid_t; + // psid = (psid_t *)malloc(sizeof(sound_t)); + psid->sid = new SIDFP; - psid->sid->set_chip_model(MOS8580FP); + 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->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->enable_filter(true); + psid->sid->enable_external_filter(true); - psid->sid->reset(); + psid->sid->reset(); - for (c = 0; c < 32; c++) - psid->sid->write(c, 0); + 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"); - } + 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->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); + psid->sid->input(0); + psid->sid->get_filter().set_type3_properties(1.33e6f, 2.2e9f, 1.0056f, 7e3f); - return (void *)psid; + return (void *)psid; } void sid_close(void *p) { -// psid_t *psid = (psid_t *)p; - delete psid->sid; -// free(psid); + // psid_t *psid = (psid_t *)p; + delete psid->sid; + // free(psid); } void sid_reset(void *p) { -// psid_t *psid = (psid_t *)p; - int c; + // psid_t *psid = (psid_t *)p; + int c; - psid->sid->reset(); + psid->sid->reset(); - for (c = 0; c < 32; c++) - psid->sid->write(c, 0); + for (c = 0; c < 32; c++) + psid->sid->write(c, 0); } uint8_t sid_read(uint16_t addr, void *p) { -// psid_t *psid = (psid_t *)p; + // psid_t *psid = (psid_t *)p; - return psid->sid->read(addr & 0x1f); -// return 0xFF; + return psid->sid->read(addr & 0x1f); + // return 0xFF; } void sid_write(uint16_t addr, uint8_t val, void *p) { -// psid_t *psid = (psid_t *)p; + // psid_t *psid = (psid_t *)p; - psid->sid->write(addr & 0x1f, val); + 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; + 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, void *p) { -// psid_t *psid = (psid_t *)p; - int x = CLOCK_DELTA(len); + // psid_t *psid = (psid_t *)p; + int x = CLOCK_DELTA(len); - fillbuf2(x, buf, len); + fillbuf2(x, buf, len); } diff --git a/src/sound/sound_sb.c b/src/sound/sound_sb.c index 0dec822e..02689883 100644 --- a/src/sound/sound_sb.c +++ b/src/sound/sound_sb.c @@ -17,1783 +17,1336 @@ //#define SB_DSP_RECORD_DEBUG #ifdef SB_DSP_RECORD_DEBUG -FILE* soundfsb = 0/*NULL*/; -FILE* soundfsbin = 0/*NULL*/; +FILE *soundfsb = 0 /*NULL*/; +FILE *soundfsbin = 0 /*NULL*/; #endif /* 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 -}; +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 +/* 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 - }; +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}; /* 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; + sb_t *sb = (sb_t *)p; - int c; + int c; - opl2_update2(&sb->opl); - sb_dsp_update(&sb->dsp); - for (c = 0; c < len * 2; c += 2) { - int32_t out; - 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; + opl2_update2(&sb->opl); + sb_dsp_update(&sb->dsp); + for (c = 0; c < len * 2; c += 2) { + int32_t out; + 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; - } + buffer[c] += out; + buffer[c + 1] += out; + } - sb->pos = 0; - sb->opl.pos = 0; - sb->dsp.pos = 0; + 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; + sb_t *sb = (sb_t *)p; + sb_ct1335_mixer_t *mixer = &sb->mixer_sb2; - int c; + int c; - opl2_update2(&sb->opl); - sb_dsp_update(&sb->dsp); - for (c = 0; c < len * 2; c += 2) { - int32_t out; + opl2_update2(&sb->opl); + sb_dsp_update(&sb->dsp); + for (c = 0; c < len * 2; c += 2) { + int32_t out; - 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 = ((((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; + out = (out * mixer->master) >> 15; - buffer[c] += out; - buffer[c + 1] += out; - } + buffer[c] += out; + buffer[c + 1] += out; + } - sb->pos = 0; - sb->opl.pos = 0; - sb->dsp.pos = 0; + sb->pos = 0; + sb->opl.pos = 0; + sb->dsp.pos = 0; } 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; + sb_t *sb = (sb_t *)p; + sb_ct1345_mixer_t *mixer = &sb->mixer_sbpro; - int c; + int c; - if (sb->dsp.sb_type == SBPRO) - opl2_update2(&sb->opl); - else - opl3_update2(&sb->opl); + 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, out_r; + sb_dsp_update(&sb->dsp); + for (c = 0; c < len * 2; c += 2) { + int32_t out_l, out_r; - 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); + 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. + /*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; + 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; - } + buffer[c] += out_l; + buffer[c + 1] += out_r; + } - sb->pos = 0; - sb->opl.pos = 0; - sb->dsp.pos = 0; + sb->pos = 0; + sb->opl.pos = 0; + sb->dsp.pos = 0; } 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; + sb_t *sb = (sb_t *)p; + sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; - int c; + int c; - 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, out_r, in_l, in_r; + 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, out_r, in_l, in_r; - 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); + 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; + /*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 += ((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; + 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 (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; - } + 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; + 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; + sb->pos = 0; + sb->opl.pos = 0; + sb->dsp.pos = 0; } #ifdef SB_DSP_RECORD_DEBUG -int old_dsp_rec_pos=0; -int buf_written=0; -int last_crecord=0; +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; + sb_t *sb = (sb_t *)p; + sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; - int c; + int c; - 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, out_r, in_l, in_r; - int c_emu8k = (((c / 2) * 44100) / 48000) * 2; + 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, out_r, in_l, in_r; + int c_emu8k = (((c / 2) * 44100) / 48000) * 2; - 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->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); + 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; + /*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 += ((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; + 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; + 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; + 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=fopen("sound_sb.pcm","wb"); - fwrite(sb->dsp.record_buffer,2,0x10000,soundfsb); - old_dsp_rec_pos = dsp_rec_pos; - buf_written=1; - } + if (c_record > 0xFFFF && !buf_written) { + if (!soundfsb) + soundfsb = fopen("sound_sb.pcm", "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; + 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; + 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=fopen("sound_sb_in.pcm","wb"); - fwrite(&sb->dsp.record_buffer[c_record&0xFFFF],2,2,soundfsbin); - last_crecord=c_record; - } + if (c_record != last_crecord) { + if (!soundfsbin) + soundfsbin = fopen("sound_sb_in.pcm", "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); - } + 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; - } + 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; + 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; } 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; + 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; + 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:pclog("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]; + default: + pclog("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); - } + 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; + sb_t *sb = (sb_t *)p; + sb_ct1335_mixer_t *mixer = &sb->mixer_sb2; - if (!(addr & 1)) - return mixer->index; + 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:pclog("sb_ct1335: Unknown register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); - break; - } + switch (mixer->index) { + case 0x00: + case 0x02: + case 0x06: + case 0x08: + case 0x0A: + return mixer->regs[mixer->index]; + default: + pclog("sb_ct1335: Unknown register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + break; + } - return 0xff; + return 0xff; } void sb_ct1335_mixer_reset(sb_t *sb) { - sb_ct1335_mixer_write(0x254, 0, sb); - sb_ct1335_mixer_write(0x255, 0, 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; + 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] = (0 << 5) | (0 << 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:mixer->regs[mixer->index + 0x20] = ((val & 0xE) << 4) | (val & 0xE); - break; + 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] = (0 << 5) | (0 << 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: + mixer->regs[mixer->index + 0x20] = ((val & 0xE) << 4) | (val & 0xE); + break; - case 0x22: - case 0x26:mixer->regs[mixer->index - 0x20] = (val & 0xE); - break; + case 0x22: + case 0x26: + 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; + /* 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 0x28: - case 0x2e:break; + case 0x00: + case 0x04: + case 0x0a: + case 0x0c: + case 0x0e: + case 0x28: + case 0x2e: + break; - default:pclog("sb_ct1345: Unknown register WRITE: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); - break; - } - } + default: + pclog("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->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->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); + 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; - } + 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); - } + /* 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; + sb_t *sb = (sb_t *)p; + sb_ct1345_mixer_t *mixer = &sb->mixer_sbpro; - if (!(addr & 1)) - return mixer->index; + 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]; + 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:pclog("sb_ct1345: Unknown register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); - break; - } + default: + pclog("sb_ct1345: Unknown register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + break; + } - return 0xff; + return 0xff; } void sb_ct1345_mixer_reset(sb_t *sb) { - sb_ct1345_mixer_write(4, 0, sb); - sb_ct1345_mixer_write(5, 0, 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; + 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 (!(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] = 0 << 3; - mixer->regs[0x37] = 0 << 3; - mixer->regs[0x38] = 0 << 3; - mixer->regs[0x39] = 0 << 3; + 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] = 0 << 3; + mixer->regs[0x37] = 0 << 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[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[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[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 0x2E:mixer->regs[0x38] = (mixer->regs[0x2E] & 0xF0) | 0x8; - mixer->regs[0x39] = ((mixer->regs[0x2E] & 0xf) << 4) | 0x8; - break; - case 0x0A:mixer->regs[0x3A] = (mixer->regs[0x0A] * 3) + 10; - break; + 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 0x2E: + mixer->regs[0x38] = (mixer->regs[0x2E] & 0xF0) | 0x8; + mixer->regs[0x39] = ((mixer->regs[0x2E] & 0xf) << 4) | 0x8; + break; + case 0x0A: + mixer->regs[0x3A] = (mixer->regs[0x0A] * 3) + 10; + 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. + /* + (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; + 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; - } + 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->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->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->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->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; + 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); -// pclog("sb_ct1745: Received register WRITE: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); - } + /*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); + // pclog("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; + sb_t *sb = (sb_t *)p; + sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; - if (!(addr & 1)) - return mixer->index; + if (!(addr & 1)) + return mixer->index; -// pclog("sb_ct1745: received register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + // pclog("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]; + 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); + /*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 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. - */ + 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; + 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.*/ + 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; - } + 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; + /* 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. */ + /* TODO: creative drivers read and write on 0xFE and 0xFF. not sure what they are supposed to be. */ + default: + pclog("sb_ct1745: Unknown register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); + break; + } - default:pclog("sb_ct1745: Unknown register READ: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]); - break; - } - - return 0xff; + return 0xff; } void sb_ct1745_mixer_reset(sb_t *sb) { - sb_ct1745_mixer_write(4, 0, sb); - sb_ct1745_mixer_write(5, 0, 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_t *sb = (sb_t *)p; - pclog("sb_mcv_read: port=%04x\n", port); + pclog("sb_mcv_read: port=%04x\n", port); - return sb->pos_regs[port & 7]; + 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; + uint16_t addr; + sb_t *sb = (sb_t *)p; - if (port < 0x102) - return; + if (port < 0x102) + return; - pclog("sb_mcv_write: port=%04x val=%02x\n", port, val); + pclog("sb_mcv_write: port=%04x val=%02x\n", port, val); - addr = sb_mcv_addr[sb->pos_regs[4] & 7]; - 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); + addr = sb_mcv_addr[sb->pos_regs[4] & 7]; + 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; + sb->pos_regs[port & 7] = val; - if (sb->pos_regs[2] & 1) { - addr = sb_mcv_addr[sb->pos_regs[4] & 7]; + if (sb->pos_regs[2] & 1) { + addr = sb_mcv_addr[sb->pos_regs[4] & 7]; - 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); - } + 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_t *sb = (sb_t *)p; - pclog("sb_pro_mcv_read: port=%04x\n", port); + pclog("sb_pro_mcv_read: port=%04x\n", port); - return sb->pos_regs[port & 7]; + 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; + uint16_t addr; + sb_t *sb = (sb_t *)p; - if (port < 0x102) - return; + if (port < 0x102) + return; - pclog("sb_pro_mcv_write: port=%04x val=%02x\n", port, val); + pclog("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); + 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; + sb->pos_regs[port & 7] = val; - if (sb->pos_regs[2] & 1) { - addr = (sb->pos_regs[2] & 0x20) ? 0x220 : 0x240; + 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); + 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_int("addr"); - memset(sb, 0, sizeof(sb_t)); + /*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_int("addr"); + memset(sb, 0, sizeof(sb_t)); - opl2_init(&sb->opl); - sb_dsp_init(&sb->dsp, SB1, SB_SUBTYPE_DEFAULT, sb); - 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 */ - 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; + opl2_init(&sb->opl); + sb_dsp_init(&sb->dsp, SB1, SB_SUBTYPE_DEFAULT, sb); + 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 */ + 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_int("addr"); - memset(sb, 0, sizeof(sb_t)); + /*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_int("addr"); + memset(sb, 0, sizeof(sb_t)); - opl2_init(&sb->opl); - sb_dsp_init(&sb->dsp, SB15, SB_SUBTYPE_DEFAULT, sb); - 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 */ - 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; + opl2_init(&sb->opl); + sb_dsp_init(&sb->dsp, SB15, SB_SUBTYPE_DEFAULT, sb); + 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 */ + 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)); + /*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)); - opl2_init(&sb->opl); - sb_dsp_init(&sb->dsp, SB15, SB_SUBTYPE_DEFAULT, sb); - 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")); - sound_add_handler(sb_get_buffer_sb2, sb); - /* I/O handlers activated in sb_mcv_write */ - mca_add(sb_mcv_read, sb_mcv_write, NULL, sb); - sb->pos_regs[0] = 0x84; - sb->pos_regs[1] = 0x50; - return sb; + opl2_init(&sb->opl); + sb_dsp_init(&sb->dsp, SB15, SB_SUBTYPE_DEFAULT, sb); + 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")); + sound_add_handler(sb_get_buffer_sb2, sb); + /* I/O handlers activated in sb_mcv_write */ + mca_add(sb_mcv_read, sb_mcv_write, NULL, 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_int("addr"); - memset(sb, 0, sizeof(sb_t)); + /*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_int("addr"); + memset(sb, 0, sizeof(sb_t)); - opl2_init(&sb->opl); - sb_dsp_init(&sb->dsp, SB2, SB_SUBTYPE_DEFAULT, sb); - 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_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 (!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); + opl2_init(&sb->opl); + sb_dsp_init(&sb->dsp, SB2, SB_SUBTYPE_DEFAULT, sb); + 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_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 (!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); + 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; + 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_int("addr"); - memset(sb, 0, sizeof(sb_t)); + /*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_int("addr"); + memset(sb, 0, sizeof(sb_t)); - opl2_init(&sb->opl); - sb_dsp_init(&sb->dsp, SBPRO, SB_SUBTYPE_DEFAULT, sb); - 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_ct1345_mixer_reset(sb); - /* DSP I/O handler is activated in sb_dsp_setaddr */ - 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); + opl2_init(&sb->opl); + sb_dsp_init(&sb->dsp, SBPRO, SB_SUBTYPE_DEFAULT, sb); + 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_ct1345_mixer_reset(sb); + /* DSP I/O handler is activated in sb_dsp_setaddr */ + 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; + 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)); - memset(sb, 0, sizeof(sb_t)); + /*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)); + memset(sb, 0, sizeof(sb_t)); - uint16_t addr = device_get_config_int("addr"); - sb->opl_emu = device_get_config_int("opl_emu"); - opl3_init(&sb->opl, sb->opl_emu); - sb_dsp_init(&sb->dsp, SBPRO2, SB_SUBTYPE_DEFAULT, sb); - 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_ct1345_mixer_reset(sb); - /* DSP I/O handler is activated in sb_dsp_setaddr */ - 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); + uint16_t addr = device_get_config_int("addr"); + sb->opl_emu = device_get_config_int("opl_emu"); + opl3_init(&sb->opl, sb->opl_emu); + sb_dsp_init(&sb->dsp, SBPRO2, SB_SUBTYPE_DEFAULT, sb); + 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_ct1345_mixer_reset(sb); + /* DSP I/O handler is activated in sb_dsp_setaddr */ + 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; + 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)); + /*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_emu = device_get_config_int("opl_emu"); - opl3_init(&sb->opl, sb->opl_emu); - sb_dsp_init(&sb->dsp, SBPRO2, SB_SUBTYPE_DEFAULT, sb); - sb_ct1345_mixer_reset(sb); - /* I/O handlers activated in sb_mcv_write */ - sound_add_handler(sb_get_buffer_sbpro, sb); + sb->opl_emu = device_get_config_int("opl_emu"); + opl3_init(&sb->opl, sb->opl_emu); + sb_dsp_init(&sb->dsp, SBPRO2, SB_SUBTYPE_DEFAULT, sb); + 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, NULL, sb); - sb->pos_regs[0] = 0x03; - sb->pos_regs[1] = 0x51; + /* I/O handlers activated in sb_pro_mcv_write */ + mca_add(sb_pro_mcv_read, sb_pro_mcv_write, NULL, sb); + sb->pos_regs[0] = 0x03; + sb->pos_regs[1] = 0x51; - return sb; + return sb; } void *sb_16_init() { - sb_t *sb = malloc(sizeof(sb_t)); - memset(sb, 0, sizeof(sb_t)); + sb_t *sb = malloc(sizeof(sb_t)); + memset(sb, 0, sizeof(sb_t)); - uint16_t addr = device_get_config_int("addr"); - sb->opl_emu = device_get_config_int("opl_emu"); - opl3_init(&sb->opl, sb->opl_emu); - sb_dsp_init(&sb->dsp, SB16, SB_SUBTYPE_DEFAULT, sb); - sb_dsp_setaddr(&sb->dsp, addr); - // TODO: irq and dma options too? - sb_ct1745_mixer_reset(sb); - 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); - mpu401_uart_init(&sb->mpu, 0x330, -1, 0); + uint16_t addr = device_get_config_int("addr"); + sb->opl_emu = device_get_config_int("opl_emu"); + opl3_init(&sb->opl, sb->opl_emu); + sb_dsp_init(&sb->dsp, SB16, SB_SUBTYPE_DEFAULT, sb); + sb_dsp_setaddr(&sb->dsp, addr); + // TODO: irq and dma options too? + sb_ct1745_mixer_reset(sb); + 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); + mpu401_uart_init(&sb->mpu, 0x330, -1, 0); - return sb; + return sb; } -int sb_awe32_available() { - return rom_present("awe32.raw"); -} +int sb_awe32_available() { return rom_present("awe32.raw"); } void *sb_awe32_init() { - sb_t *sb = malloc(sizeof(sb_t)); - int onboard_ram = device_get_config_int("onboard_ram"); - memset(sb, 0, sizeof(sb_t)); + sb_t *sb = malloc(sizeof(sb_t)); + int onboard_ram = device_get_config_int("onboard_ram"); + memset(sb, 0, sizeof(sb_t)); - uint16_t addr = device_get_config_int("addr"); - uint16_t emu_addr = device_get_config_int("emu_addr"); - sb->opl_emu = device_get_config_int("opl_emu"); - opl3_init(&sb->opl, sb->opl_emu); - sb_dsp_init(&sb->dsp, SB16 + 1, SB_SUBTYPE_DEFAULT, sb); - sb_dsp_setaddr(&sb->dsp, addr); - // TODO: irq and dma options too? - sb_ct1745_mixer_reset(sb); - 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); - mpu401_uart_init(&sb->mpu, 0x330, -1, 0); - emu8k_init(&sb->emu8k, emu_addr, onboard_ram); + uint16_t addr = device_get_config_int("addr"); + uint16_t emu_addr = device_get_config_int("emu_addr"); + sb->opl_emu = device_get_config_int("opl_emu"); + opl3_init(&sb->opl, sb->opl_emu); + sb_dsp_init(&sb->dsp, SB16 + 1, SB_SUBTYPE_DEFAULT, sb); + sb_dsp_setaddr(&sb->dsp, addr); + // TODO: irq and dma options too? + sb_ct1745_mixer_reset(sb); + 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); + mpu401_uart_init(&sb->mpu, 0x330, -1, 0); + emu8k_init(&sb->emu8k, emu_addr, onboard_ram); - return sb; + return sb; } void sb_close(void *p) { - sb_t *sb = (sb_t *)p; - sb_dsp_close(&sb->dsp); + 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; - } + if (soundfsb != 0) { + fclose(soundfsb); + soundfsb = 0; + } + if (soundfsbin != 0) { + fclose(soundfsbin); + soundfsbin = 0; + } #endif - free(sb); + free(sb); } void sb_awe32_close(void *p) { - sb_t *sb = (sb_t *)p; + sb_t *sb = (sb_t *)p; - emu8k_close(&sb->emu8k); + emu8k_close(&sb->emu8k); - sb_close(sb); + sb_close(sb); } void sb_speed_changed(void *p) { - sb_t *sb = (sb_t *)p; + sb_t *sb = (sb_t *)p; - sb_dsp_speed_changed(&sb->dsp); + sb_dsp_speed_changed(&sb->dsp); } void sb_add_status_info(char *s, int max_len, void *p) { - sb_t *sb = (sb_t *)p; + sb_t *sb = (sb_t *)p; - sb_dsp_add_status_info(s, max_len, &sb->dsp); + sb_dsp_add_status_info(s, max_len, &sb->dsp); } -static device_config_t sb_config[] = - { - { - .name = "addr", - .description = "Address", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "0x210", - .value = 0x210 - }, - { - .description = "0x220", - .value = 0x220 - }, - { - .description = "0x230", - .value = 0x230 - }, - { - .description = "0x240", - .value = 0x240 - }, - { - .description = "0x250", - .value = 0x250 - }, - { - .description = "0x260", - .value = 0x260 - }, - { - .description = "" - } - }, - .default_int = 0x220 - }, - { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "IRQ 2", - .value = 2 - }, - { - .description = "IRQ 3", - .value = 3 - }, - { - .description = "IRQ 5", - .value = 5 - }, - { - .description = "IRQ 7", - .value = 7 - }, - { - .description = "" - } - }, - .default_int = 7 - }, - { - .name = "dma", - .description = "DMA", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "DMA 1", - .value = 1 - }, - { - .description = "DMA 3", - .value = 3 - }, - { - .description = "" - } - }, - .default_int = 1 - }, - { - .type = -1 - } - }; +static device_config_t sb_config[] = { + {.name = "addr", + .description = "Address", + .type = CONFIG_SELECTION, + .selection = {{.description = "0x210", .value = 0x210}, + {.description = "0x220", .value = 0x220}, + {.description = "0x230", .value = 0x230}, + {.description = "0x240", .value = 0x240}, + {.description = "0x250", .value = 0x250}, + {.description = "0x260", .value = 0x260}, + {.description = ""}}, + .default_int = 0x220}, + {.name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .selection = {{.description = "IRQ 2", .value = 2}, + {.description = "IRQ 3", .value = 3}, + {.description = "IRQ 5", .value = 5}, + {.description = "IRQ 7", .value = 7}, + {.description = ""}}, + .default_int = 7}, + {.name = "dma", + .description = "DMA", + .type = CONFIG_SELECTION, + .selection = {{.description = "DMA 1", .value = 1}, {.description = "DMA 3", .value = 3}, {.description = ""}}, + .default_int = 1}, + {.type = -1}}; -static device_config_t sb2_config[] = - { - { - .name = "addr", - .description = "Address", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "0x220", - .value = 0x220 - }, - { - .description = "0x240", - .value = 0x240 - }, - { - .description = "" - } - }, - .default_int = 0x220 - }, - { - .name = "mixaddr", - .description = "Mixer Address", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "No mixer", - .value = 0 - }, - { - .description = "0x250", - .value = 0x250 - }, - { - .description = "0x260", - .value = 0x260 - }, - { - .description = "" - } - }, - .default_int = 0 - }, - { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "IRQ 2", - .value = 2 - }, - { - .description = "IRQ 3", - .value = 3 - }, - { - .description = "IRQ 5", - .value = 5 - }, - { - .description = "IRQ 7", - .value = 7 - }, - { - .description = "" - } - }, - .default_int = 7 - }, - { - .name = "dma", - .description = "DMA", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "DMA 1", - .value = 1 - }, - { - .description = "DMA 3", - .value = 3 - }, - { - .description = "" - } - }, - .default_int = 1 - }, - { - .type = -1 - } - }; +static device_config_t sb2_config[] = { + {.name = "addr", + .description = "Address", + .type = CONFIG_SELECTION, + .selection = {{.description = "0x220", .value = 0x220}, {.description = "0x240", .value = 0x240}, {.description = ""}}, + .default_int = 0x220}, + {.name = "mixaddr", + .description = "Mixer Address", + .type = CONFIG_SELECTION, + .selection = {{.description = "No mixer", .value = 0}, + {.description = "0x250", .value = 0x250}, + {.description = "0x260", .value = 0x260}, + {.description = ""}}, + .default_int = 0}, + {.name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .selection = {{.description = "IRQ 2", .value = 2}, + {.description = "IRQ 3", .value = 3}, + {.description = "IRQ 5", .value = 5}, + {.description = "IRQ 7", .value = 7}, + {.description = ""}}, + .default_int = 7}, + {.name = "dma", + .description = "DMA", + .type = CONFIG_SELECTION, + .selection = {{.description = "DMA 1", .value = 1}, {.description = "DMA 3", .value = 3}, {.description = ""}}, + .default_int = 1}, + {.type = -1}}; -static device_config_t sb_mcv_config[] = - { - { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "IRQ 3", - .value = 3 - }, - { - .description = "IRQ 5", - .value = 5 - }, - { - .description = "IRQ 7", - .value = 7 - }, - { - .description = "" - } - }, - .default_int = 7 - }, - { - .name = "dma", - .description = "DMA", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "DMA 1", - .value = 1 - }, - { - .description = "DMA 3", - .value = 3 - }, - { - .description = "" - } - }, - .default_int = 1 - }, - { - .type = -1 - } - }; +static device_config_t sb_mcv_config[] = { + {.name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .selection = {{.description = "IRQ 3", .value = 3}, + {.description = "IRQ 5", .value = 5}, + {.description = "IRQ 7", .value = 7}, + {.description = ""}}, + .default_int = 7}, + {.name = "dma", + .description = "DMA", + .type = CONFIG_SELECTION, + .selection = {{.description = "DMA 1", .value = 1}, {.description = "DMA 3", .value = 3}, {.description = ""}}, + .default_int = 1}, + {.type = -1}}; -static device_config_t sb_pro_v1_config[] = - { - { - .name = "addr", - .description = "Address", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "0x220", - .value = 0x220 - }, - { - .description = "0x240", - .value = 0x240 - }, - { - .description = "" - } - }, - .default_int = 0x220 - }, - { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "IRQ 2", - .value = 2 - }, - { - .description = "IRQ 5", - .value = 5 - }, - { - .description = "IRQ 7", - .value = 7 - }, - { - .description = "IRQ 10", - .value = 10 - }, - { - .description = "" - } - }, - .default_int = 7 - }, - { - .name = "dma", - .description = "DMA", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "DMA 1", - .value = 1 - }, - { - .description = "DMA 3", - .value = 3 - }, - { - .description = "" - } - }, - .default_int = 1 - }, - { - .type = -1 - } - }; +static device_config_t sb_pro_v1_config[] = { + {.name = "addr", + .description = "Address", + .type = CONFIG_SELECTION, + .selection = {{.description = "0x220", .value = 0x220}, {.description = "0x240", .value = 0x240}, {.description = ""}}, + .default_int = 0x220}, + {.name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .selection = {{.description = "IRQ 2", .value = 2}, + {.description = "IRQ 5", .value = 5}, + {.description = "IRQ 7", .value = 7}, + {.description = "IRQ 10", .value = 10}, + {.description = ""}}, + .default_int = 7}, + {.name = "dma", + .description = "DMA", + .type = CONFIG_SELECTION, + .selection = {{.description = "DMA 1", .value = 1}, {.description = "DMA 3", .value = 3}, {.description = ""}}, + .default_int = 1}, + {.type = -1}}; -static device_config_t sb_pro_v2_config[] = - { - { - .name = "addr", - .description = "Address", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "0x220", - .value = 0x220 - }, - { - .description = "0x240", - .value = 0x240 - }, - { - .description = "" - } - }, - .default_int = 0x220 - }, - { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "IRQ 2", - .value = 2 - }, - { - .description = "IRQ 5", - .value = 5 - }, - { - .description = "IRQ 7", - .value = 7 - }, - { - .description = "IRQ 10", - .value = 10 - }, - { - .description = "" - } - }, - .default_int = 7 - }, - { - .name = "dma", - .description = "DMA", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "DMA 1", - .value = 1 - }, - { - .description = "DMA 3", - .value = 3 - }, - { - .description = "" - } - }, - .default_int = 1 - }, - { - .name = "opl_emu", - .description = "OPL emulator", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "DBOPL", - .value = OPL_DBOPL - }, - { - .description = "NukedOPL", - .value = OPL_NUKED - }, - }, - .default_int = OPL_DBOPL - }, - { - .type = -1 - } - }; +static device_config_t sb_pro_v2_config[] = { + {.name = "addr", + .description = "Address", + .type = CONFIG_SELECTION, + .selection = {{.description = "0x220", .value = 0x220}, {.description = "0x240", .value = 0x240}, {.description = ""}}, + .default_int = 0x220}, + {.name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .selection = {{.description = "IRQ 2", .value = 2}, + {.description = "IRQ 5", .value = 5}, + {.description = "IRQ 7", .value = 7}, + {.description = "IRQ 10", .value = 10}, + {.description = ""}}, + .default_int = 7}, + {.name = "dma", + .description = "DMA", + .type = CONFIG_SELECTION, + .selection = {{.description = "DMA 1", .value = 1}, {.description = "DMA 3", .value = 3}, {.description = ""}}, + .default_int = 1}, + {.name = "opl_emu", + .description = "OPL emulator", + .type = CONFIG_SELECTION, + .selection = + { + {.description = "DBOPL", .value = OPL_DBOPL}, + {.description = "NukedOPL", .value = OPL_NUKED}, + }, + .default_int = OPL_DBOPL}, + {.type = -1}}; -static device_config_t sb_pro_mcv_config[] = - { - { - .name = "opl_emu", - .description = "OPL emulator", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "DBOPL", - .value = OPL_DBOPL - }, - { - .description = "NukedOPL", - .value = OPL_NUKED - }, - }, - .default_int = OPL_DBOPL - }, - { - .type = -1 - } - }; +static device_config_t sb_pro_mcv_config[] = {{.name = "opl_emu", + .description = "OPL emulator", + .type = CONFIG_SELECTION, + .selection = + { + {.description = "DBOPL", .value = OPL_DBOPL}, + {.description = "NukedOPL", .value = OPL_NUKED}, + }, + .default_int = OPL_DBOPL}, + {.type = -1}}; -static device_config_t sb_16_config[] = - { - { - .name = "addr", - .description = "Address", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "0x220", - .value = 0x220 - }, - { - .description = "0x240", - .value = 0x240 - }, - { - .description = "0x260", - .value = 0x260 - }, - { - .description = "0x280", - .value = 0x280 - }, - { - .description = "" - } - }, - .default_int = 0x220 - }, - { - .name = "midi", - .description = "MIDI out device", - .type = CONFIG_MIDI, - .default_int = 0 - }, - { - .name = "opl_emu", - .description = "OPL emulator", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "DBOPL", - .value = OPL_DBOPL - }, - { - .description = "NukedOPL", - .value = OPL_NUKED - }, - }, - .default_int = OPL_DBOPL - }, - { - .type = -1 - } - }; +static device_config_t sb_16_config[] = { + {.name = "addr", + .description = "Address", + .type = CONFIG_SELECTION, + .selection = {{.description = "0x220", .value = 0x220}, + {.description = "0x240", .value = 0x240}, + {.description = "0x260", .value = 0x260}, + {.description = "0x280", .value = 0x280}, + {.description = ""}}, + .default_int = 0x220}, + {.name = "midi", .description = "MIDI out device", .type = CONFIG_MIDI, .default_int = 0}, + {.name = "opl_emu", + .description = "OPL emulator", + .type = CONFIG_SELECTION, + .selection = + { + {.description = "DBOPL", .value = OPL_DBOPL}, + {.description = "NukedOPL", .value = OPL_NUKED}, + }, + .default_int = OPL_DBOPL}, + {.type = -1}}; -static device_config_t sb_awe32_config[] = - { - { - .name = "addr", - .description = "Address", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "0x220", - .value = 0x220 - }, - { - .description = "0x240", - .value = 0x240 - }, - { - .description = "0x260", - .value = 0x260 - }, - { - .description = "0x280", - .value = 0x280 - }, - { - .description = "" - } - }, - .default_int = 0x220 - }, - { - .name = "emu_addr", - .description = "EMU8000 Address", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "0x620", - .value = 0x620 - }, - { - .description = "0x640", - .value = 0x640 - }, - { - .description = "0x660", - .value = 0x660 - }, - { - .description = "0x680", - .value = 0x680 - }, - { - .description = "" - } - }, - .default_int = 0x620 - }, - {.name = "midi", - .description = "MIDI out device", - .type = CONFIG_MIDI, - .default_int = 0 - }, - { - .name = "onboard_ram", - .description = "Onboard RAM", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "None", - .value = 0 - }, - { - .description = "512 KB", - .value = 512 - }, - { - .description = "2 MB", - .value = 2048 - }, - { - .description = "8 MB", - .value = 8192 - }, - { - .description = "28 MB", - .value = 28 * 1024 - }, - { - .description = "" - } - }, - .default_int = 512 - }, - { - .name = "opl_emu", - .description = "OPL emulator", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "DBOPL", - .value = OPL_DBOPL - }, - { - .description = "NukedOPL", - .value = OPL_NUKED - }, - }, - .default_int = OPL_DBOPL - }, - { - .type = -1 - } - }; +static device_config_t sb_awe32_config[] = { + {.name = "addr", + .description = "Address", + .type = CONFIG_SELECTION, + .selection = {{.description = "0x220", .value = 0x220}, + {.description = "0x240", .value = 0x240}, + {.description = "0x260", .value = 0x260}, + {.description = "0x280", .value = 0x280}, + {.description = ""}}, + .default_int = 0x220}, + {.name = "emu_addr", + .description = "EMU8000 Address", + .type = CONFIG_SELECTION, + .selection = {{.description = "0x620", .value = 0x620}, + {.description = "0x640", .value = 0x640}, + {.description = "0x660", .value = 0x660}, + {.description = "0x680", .value = 0x680}, + {.description = ""}}, + .default_int = 0x620}, + {.name = "midi", .description = "MIDI out device", .type = CONFIG_MIDI, .default_int = 0}, + {.name = "onboard_ram", + .description = "Onboard RAM", + .type = CONFIG_SELECTION, + .selection = {{.description = "None", .value = 0}, + {.description = "512 KB", .value = 512}, + {.description = "2 MB", .value = 2048}, + {.description = "8 MB", .value = 8192}, + {.description = "28 MB", .value = 28 * 1024}, + {.description = ""}}, + .default_int = 512}, + {.name = "opl_emu", + .description = "OPL emulator", + .type = CONFIG_SELECTION, + .selection = + { + {.description = "DBOPL", .value = OPL_DBOPL}, + {.description = "NukedOPL", .value = OPL_NUKED}, + }, + .default_int = OPL_DBOPL}, + {.type = -1}}; -device_t sb_1_device = - { - "Sound Blaster v1.0", - 0, - sb_1_init, - sb_close, - NULL, - sb_speed_changed, - NULL, - sb_add_status_info, - sb_config - }; -device_t sb_15_device = - { - "Sound Blaster v1.5", - 0, - sb_15_init, - sb_close, - NULL, - sb_speed_changed, - NULL, - sb_add_status_info, - sb_config - }; -device_t sb_mcv_device = - { - "Sound Blaster MCV", - DEVICE_MCA, - sb_mcv_init, - sb_close, - NULL, - sb_speed_changed, - NULL, - sb_add_status_info, - sb_mcv_config - }; -device_t sb_2_device = - { - "Sound Blaster v2.0", - 0, - sb_2_init, - sb_close, - NULL, - sb_speed_changed, - NULL, - sb_add_status_info, - sb2_config - }; -device_t sb_pro_v1_device = - { - "Sound Blaster Pro v1", - 0, - sb_pro_v1_init, - sb_close, - NULL, - sb_speed_changed, - NULL, - sb_add_status_info, - sb_pro_v1_config - }; -device_t sb_pro_v2_device = - { - "Sound Blaster Pro v2", - 0, - sb_pro_v2_init, - sb_close, - NULL, - sb_speed_changed, - NULL, - sb_add_status_info, - sb_pro_v2_config - }; -device_t sb_pro_mcv_device = - { - "Sound Blaster Pro MCV", - DEVICE_MCA, - sb_pro_mcv_init, - sb_close, - NULL, - sb_speed_changed, - NULL, - sb_add_status_info, - sb_pro_mcv_config - }; -device_t sb_16_device = - { - "Sound Blaster 16", - 0, - sb_16_init, - sb_close, - NULL, - sb_speed_changed, - NULL, - sb_add_status_info, - sb_16_config - }; -device_t sb_awe32_device = - { - "Sound Blaster AWE32", - 0, - sb_awe32_init, - sb_awe32_close, - sb_awe32_available, - sb_speed_changed, - NULL, - sb_add_status_info, - sb_awe32_config - }; +device_t sb_1_device = {"Sound Blaster v1.0", 0, sb_1_init, sb_close, NULL, + sb_speed_changed, NULL, sb_add_status_info, sb_config}; +device_t sb_15_device = {"Sound Blaster v1.5", 0, sb_15_init, sb_close, NULL, + sb_speed_changed, NULL, sb_add_status_info, sb_config}; +device_t sb_mcv_device = {"Sound Blaster MCV", DEVICE_MCA, sb_mcv_init, sb_close, NULL, + sb_speed_changed, NULL, sb_add_status_info, sb_mcv_config}; +device_t sb_2_device = {"Sound Blaster v2.0", 0, sb_2_init, sb_close, NULL, + sb_speed_changed, NULL, sb_add_status_info, sb2_config}; +device_t sb_pro_v1_device = {"Sound Blaster Pro v1", 0, sb_pro_v1_init, sb_close, NULL, + sb_speed_changed, NULL, sb_add_status_info, sb_pro_v1_config}; +device_t sb_pro_v2_device = {"Sound Blaster Pro v2", 0, sb_pro_v2_init, sb_close, NULL, + sb_speed_changed, NULL, sb_add_status_info, sb_pro_v2_config}; +device_t sb_pro_mcv_device = {"Sound Blaster Pro MCV", DEVICE_MCA, sb_pro_mcv_init, sb_close, NULL, + sb_speed_changed, NULL, sb_add_status_info, sb_pro_mcv_config}; +device_t sb_16_device = {"Sound Blaster 16", 0, sb_16_init, sb_close, NULL, + sb_speed_changed, NULL, sb_add_status_info, sb_16_config}; +device_t sb_awe32_device = {"Sound Blaster AWE32", 0, sb_awe32_init, sb_awe32_close, sb_awe32_available, + sb_speed_changed, NULL, sb_add_status_info, sb_awe32_config}; diff --git a/src/sound/sound_sb_dsp.c b/src/sound/sound_sb_dsp.c index 2b5634ea..80e4783e 100644 --- a/src/sound/sound_sb_dsp.c +++ b/src/sound/sound_sb_dsp.c @@ -30,713 +30,678 @@ void sb_poll_i(void *p); //#define SB_TEST_RECORDING_SAW #ifdef SB_DSP_RECORD_DEBUG -FILE* soundf = 0/*NULL*/; +FILE *soundf = 0 /*NULL*/; #endif #ifdef SB_TEST_RECORDING_SAW int counttest; #endif -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 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 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 - }; +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 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 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 -}; +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]; -static inline double sinc(double x) { - return sin(M_PI * x) / (M_PI * x); -} +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; + /*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))); + 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; - } + /*Create windowed-sinc filter*/ + low_fir_sb16_coef[n] = w * h; + } - low_fir_sb16_coef[(SB16_NCoef - 1) / 2] = 1.0; + 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]; + 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; + /*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) { -// pclog("IRQ %i %02X\n",irq8,pic.mask); - if (irq8) - dsp->sb_irq8 = 1; - else - dsp->sb_irq16 = 1; - picint(1 << dsp->sb_irqnum); + // pclog("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); + if (irq8) + dsp->sb_irq8 = 0; + else + dsp->sb_irq16 = 0; + picintc(1 << dsp->sb_irqnum); } void sb_dsp_reset(sb_dsp_t *dsp) { - timer_disable(&dsp->output_timer); - timer_disable(&dsp->input_timer); + timer_disable(&dsp->output_timer); + timer_disable(&dsp->input_timer); - dsp->sb_command = 0; + dsp->sb_command = 0; - dsp->sb_8_length = 0xffff; - dsp->sb_8_autolen = 0xffff; + 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 = -1; - dsp->sbe2 = 0xAA; - dsp->sbe2count = 0; + 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 = -1; + dsp->sbe2 = 0xAA; + dsp->sbe2count = 0; - dsp->sbreset = 0; + dsp->sbreset = 0; - dsp->record_pos_read = 0; - dsp->record_pos_write = SB_DSP_REC_SAFEFTY_MARGIN; + dsp->record_pos_read = 0; + dsp->record_pos_write = SB_DSP_REC_SAFEFTY_MARGIN; - picintc(1 << dsp->sb_irqnum); + picintc(1 << dsp->sb_irqnum); - dsp->asp_data_len = 0; + dsp->asp_data_len = 0; #ifdef SB_DSP_RECORD_DEBUG - if (soundf != 0) - { - fclose(soundf); - soundf=0; - } + if (soundf != 0) { + fclose(soundf); + soundf = 0; + } #endif } void sb_doreset(sb_dsp_t *dsp) { - int c; + int c; - sb_dsp_reset(dsp); + sb_dsp_reset(dsp); - if (IS_AZTECH(dsp)) { - sb_commands[8] = 1; - sb_commands[9] = 1; - } else { - if (dsp->sb_type == SB16) - sb_commands[8] = 1; - else - sb_commands[8] = -1; - } + if (IS_AZTECH(dsp)) { + sb_commands[8] = 1; + sb_commands[9] = 1; + } else { + 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; + 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 < 256) - dsp->sblatcho = TIMER_USEC * (256 - dsp->sb_timeo); - else - dsp->sblatcho = (uint64_t)(TIMER_USEC * (1000000.0f / (float)(dsp->sb_timeo - 256))); + if (dsp->sb_timeo < 256) + dsp->sblatcho = TIMER_USEC * (256 - dsp->sb_timeo); + else + dsp->sblatcho = (uint64_t)(TIMER_USEC * (1000000.0f / (float)(dsp->sb_timeo - 256))); - if (dsp->sb_timei < 256) - dsp->sblatchi = TIMER_USEC * (256 - dsp->sb_timei); - else - dsp->sblatchi = (uint64_t)(TIMER_USEC * (1000000.0f / (float)(dsp->sb_timei - 256))); + if (dsp->sb_timei < 256) + dsp->sblatchi = TIMER_USEC * (256 - dsp->sb_timei); + else + dsp->sblatchi = (uint64_t)(TIMER_USEC * (1000000.0f / (float)(dsp->sb_timei - 256))); } 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; + dsp->sb_read_data[dsp->sb_read_wp++] = v; + dsp->sb_read_wp &= 0xff; } -#define ADPCM_4 1 +#define ADPCM_4 1 #define ADPCM_26 2 -#define ADPCM_2 3 +#define ADPCM_2 3 void sb_start_dma(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) { - dsp->sb_pausetime = -1; - 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; - if (!timer_is_enabled(&dsp->output_timer)) - timer_set_delay_u64(&dsp->output_timer, dsp->sblatcho); - dsp->sbleftright = 0; - dsp->sbdacpos = 0; -// pclog("Start 8-bit DMA addr %06X len %04X\n",dma.ac[1]+(dma.page[1]<<16),len); - } 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; - if (!timer_is_enabled(&dsp->output_timer)) - timer_set_delay_u64(&dsp->output_timer, dsp->sblatcho); -// pclog("Start 16-bit DMA addr %06X len %04X\n",dma16.ac[1]+(dma16.page[1]<<16),len); - } + dsp->sb_pausetime = -1; + 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; + if (!timer_is_enabled(&dsp->output_timer)) + timer_set_delay_u64(&dsp->output_timer, dsp->sblatcho); + dsp->sbleftright = 0; + dsp->sbdacpos = 0; + // pclog("Start 8-bit DMA addr %06X len %04X\n",dma.ac[1]+(dma.page[1]<<16),len); + } 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; + if (!timer_is_enabled(&dsp->output_timer)) + timer_set_delay_u64(&dsp->output_timer, dsp->sblatcho); + // pclog("Start 16-bit DMA addr %06X len %04X\n",dma16.ac[1]+(dma16.page[1]<<16),len); + } } void sb_start_dma_i(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len) { - if (dma8) { + if (dma8) { #ifdef SB_TEST_RECORDING_SAW - switch (dsp->sb_8_format) - { - case 00:case 20:counttest=0x80;break; - case 10:case 30:counttest=0;break; - } + switch (dsp->sb_8_format) { + case 00: + case 20: + counttest = 0x80; + break; + case 10: + case 30: + counttest = 0; + break; + } #endif - 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; - if (!timer_is_enabled(&dsp->input_timer)) - timer_set_delay_u64(&dsp->input_timer, dsp->sblatchi); -// pclog("Start 8-bit input DMA addr %06X len %04X\n",dma.ac[1]+(dma.page[1]<<16),len); - } else { + 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; + if (!timer_is_enabled(&dsp->input_timer)) + timer_set_delay_u64(&dsp->input_timer, dsp->sblatchi); + // pclog("Start 8-bit input DMA addr %06X len %04X\n",dma.ac[1]+(dma.page[1]<<16),len); + } else { #ifdef SB_TEST_RECORDING_SAW - switch (dsp->sb_16_format) - { - case 00:case 20:counttest=0x8000;break; - case 10:case 30:counttest=0;break; - } + switch (dsp->sb_16_format) { + case 00: + case 20: + counttest = 0x8000; + break; + case 10: + case 30: + counttest = 0; + break; + } #endif - 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; - if (!timer_is_enabled(&dsp->input_timer)) - timer_set_delay_u64(&dsp->input_timer, dsp->sblatchi); -// pclog("Start 16-bit input DMA addr %06X len %04X\n",dma.ac[1]+(dma.page[1]<<16),len); - } - memset(dsp->record_buffer, 0, sizeof(dsp->record_buffer)); + 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; + if (!timer_is_enabled(&dsp->input_timer)) + timer_set_delay_u64(&dsp->input_timer, dsp->sblatchi); + // pclog("Start 16-bit input DMA addr %06X len %04X\n",dma.ac[1]+(dma.page[1]<<16),len); + } + memset(dsp->record_buffer, 0, sizeof(dsp->record_buffer)); #ifdef SB_DSP_RECORD_DEBUG - if (soundf != 0) - { - fclose(soundf); - soundf=0; - } + if (soundf != 0) { + fclose(soundf); + soundf = 0; + } #endif - } -int sb_8_read_dma(sb_dsp_t *dsp) { - return dma_channel_read(dsp->sb_8_dmanum); -} +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); + dma_channel_write(dsp->sb_8_dmanum, val); #ifdef SB_DSP_RECORD_DEBUG - if (!soundf) soundf=fopen("sound_dsp.pcm","wb"); - fwrite(&val,1,1,soundf); + if (!soundf) + soundf = fopen("sound_dsp.pcm", "wb"); + fwrite(&val, 1, 1, soundf); #endif } -int sb_16_read_dma(sb_dsp_t *dsp) { - return dma_channel_read(dsp->sb_16_dmanum); -} +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); + int ret = dma_channel_write(dsp->sb_16_dmanum, val); #ifdef SB_DSP_RECORD_DEBUG - if (!soundf) soundf=fopen("sound_dsp.pcm","wb"); - fwrite(&val,2,1,soundf); + if (!soundf) + soundf = fopen("sound_dsp.pcm", "wb"); + fwrite(&val, 2, 1, soundf); #endif - return (ret == DMA_NODATA); + return (ret == DMA_NODATA); } -void sb_dsp_setirq(sb_dsp_t *dsp, int irq) { - dsp->sb_irqnum = irq; -} +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_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_dsp_setdma16(sb_dsp_t *dsp, int dma) { dsp->sb_16_dmanum = dma; } void sb_exec_command(sb_dsp_t *dsp) { - int temp, c; -// pclog("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; -// pclog("Ref byte 2 %02X\n",sbref); - 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 (!timer_is_enabled(&dsp->input_timer)) { - dsp->sb_timei = 256 - 22; - dsp->sblatchi = TIMER_USEC * 22; - temp = 1000000 / 22; - dsp->sb_freq = temp; - timer_set_delay_u64(&dsp->input_timer, dsp->sblatchi); - } - 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 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; -// pclog("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 = (uint64_t)(TIMER_USEC * (1000000.0f / (float)(dsp->sb_data[1] + (dsp->sb_data[0] << 8)))); -// pclog("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 = 256 + 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; -// pclog("Ref byte 4 %02X\n",sbref); - 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; -// pclog("Ref byte 26 %02X\n",sbref); - 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); -// pclog("SB pause %04X\n",sb_pausetime); - if (!timer_is_enabled(&dsp->output_timer)) - timer_set_delay_u64(&dsp->output_timer, dsp->sblatcho); - 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*/ - if (IS_AZTECH(dsp)) { - if (dsp->sb_subtype == SB_SUBTYPE_CLONE_AZT2316A_0X11) { - sb_add_data(dsp, 0x3); - sb_add_data(dsp, 0x1); - } else if (dsp->sb_subtype == SB_SUBTYPE_CLONE_AZT1605_0X0C) { - sb_add_data(dsp, 0x2); - sb_add_data(dsp, 0x1); - } - break; - } - 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*/ -// pclog("Trigger IRQ\n"); - sb_irq(dsp, 1); - break; - case 0xF3: /*Trigger 16-bit IRQ*/ -// pclog("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 (IS_AZTECH(dsp)) { - if ((dsp->sb_data[0] == 0x55 || dsp->sb_data[0] == 0x05) && dsp->sb_subtype == SB_SUBTYPE_CLONE_AZT2316A_0X11) - sb_add_data(dsp, 0x11); /* AZTECH get type, WASHINGTON/latest - according to devkit. E.g.: The one in the Itautec Infoway Multimidia */ - else if ((dsp->sb_data[0] == 0x55 || dsp->sb_data[0] == 0x05) && dsp->sb_subtype == SB_SUBTYPE_CLONE_AZT1605_0X0C) - sb_add_data(dsp, 0x0C); /* AZTECH get type, CLINTON - according to devkit. E.g.: The one in the Packard Bell Legend 100CD */ - else if (dsp->sb_data[0] == 0x08) { - // EEPROM address to write followed by byte - if (dsp->sb_data[1] < 0 || dsp->sb_data[1] >= AZTECH_EEPROM_SIZE) - fatal("AZT EEPROM: out of bounds write to %02X\n", dsp->sb_data[1]); - dsp->azt_eeprom[dsp->sb_data[1]] = dsp->sb_data[2]; - break; - } else if (dsp->sb_data[0] == 0x07) { - // EEPROM address to read - if (dsp->sb_data[1] < 0 || dsp->sb_data[1] >= AZTECH_EEPROM_SIZE) - fatal("AZT EEPROM: out of bounds read to %02X\n", dsp->sb_data[1]); - sb_add_data(dsp, dsp->azt_eeprom[dsp->sb_data[1]]); - break; - } else - pclog("AZT2316A: UNKNOWN 0x08 COMMAND: %02X\n", dsp->sb_data[0]); // 0x08 (when shutting down, driver tries to read 1 byte of response), 0x55, 0x0D, 0x08D seen - break; - } - 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]; -// pclog("ASP write reg %02X %02X\n", sb_data[0], sb_data[1]); - break; - case 0x0F: /*ASP get register*/ - if (dsp->sb_type < SB16) - break; -// sb_add_data(0); - sb_add_data(dsp, dsp->sb_asp_regs[dsp->sb_data[0]]); -// pclog("ASP read reg %02X %02X\n", sb_data[0], sb_asp_regs[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; - case 0x09: /*AZTECH mode set*/ - if (IS_AZTECH(dsp)) { - if (dsp->sb_data[0] == 0x00) { - pclog("AZT2316A: WSS MODE!\n"); - azt2316a_enable_wss(1, dsp->parent); - } else if (dsp->sb_data[0] == 0x01) { - pclog("AZT2316A: SB8PROV2 MODE!\n"); - azt2316a_enable_wss(0, dsp->parent); - } else - pclog("AZT2316A: UNKNOWN MODE!\n"); // sequences 0x02->0xFF, 0x04->0xFF seen - } - break; - case 0x38: /*TODO: AZTECH MIDI-related? */ - break; -// default: -// fatal("Exec bad SB command %02X\n",dsp->sb_command); + int temp, c; + // pclog("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; + // pclog("Ref byte 2 %02X\n",sbref); + 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 (!timer_is_enabled(&dsp->input_timer)) { + dsp->sb_timei = 256 - 22; + dsp->sblatchi = TIMER_USEC * 22; + temp = 1000000 / 22; + dsp->sb_freq = temp; + timer_set_delay_u64(&dsp->input_timer, dsp->sblatchi); + } + 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 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; + // pclog("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 = (uint64_t)(TIMER_USEC * (1000000.0f / (float)(dsp->sb_data[1] + (dsp->sb_data[0] << 8)))); + // pclog("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 = 256 + 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; + // pclog("Ref byte 4 %02X\n",sbref); + 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; + // pclog("Ref byte 26 %02X\n",sbref); + 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); + // pclog("SB pause %04X\n",sb_pausetime); + if (!timer_is_enabled(&dsp->output_timer)) + timer_set_delay_u64(&dsp->output_timer, dsp->sblatcho); + 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*/ + if (IS_AZTECH(dsp)) { + if (dsp->sb_subtype == SB_SUBTYPE_CLONE_AZT2316A_0X11) { + sb_add_data(dsp, 0x3); + sb_add_data(dsp, 0x1); + } else if (dsp->sb_subtype == SB_SUBTYPE_CLONE_AZT1605_0X0C) { + sb_add_data(dsp, 0x2); + sb_add_data(dsp, 0x1); + } + break; + } + 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*/ + // pclog("Trigger IRQ\n"); + sb_irq(dsp, 1); + break; + case 0xF3: /*Trigger 16-bit IRQ*/ + // pclog("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 (IS_AZTECH(dsp)) { + if ((dsp->sb_data[0] == 0x55 || dsp->sb_data[0] == 0x05) && + dsp->sb_subtype == SB_SUBTYPE_CLONE_AZT2316A_0X11) + sb_add_data(dsp, 0x11); /* AZTECH get type, WASHINGTON/latest - according to devkit. E.g.: The one + in the Itautec Infoway Multimidia */ + else if ((dsp->sb_data[0] == 0x55 || dsp->sb_data[0] == 0x05) && + dsp->sb_subtype == SB_SUBTYPE_CLONE_AZT1605_0X0C) + sb_add_data(dsp, 0x0C); /* AZTECH get type, CLINTON - according to devkit. E.g.: The one in the + Packard Bell Legend 100CD */ + else if (dsp->sb_data[0] == 0x08) { + // EEPROM address to write followed by byte + if (dsp->sb_data[1] < 0 || dsp->sb_data[1] >= AZTECH_EEPROM_SIZE) + fatal("AZT EEPROM: out of bounds write to %02X\n", dsp->sb_data[1]); + dsp->azt_eeprom[dsp->sb_data[1]] = dsp->sb_data[2]; + break; + } else if (dsp->sb_data[0] == 0x07) { + // EEPROM address to read + if (dsp->sb_data[1] < 0 || dsp->sb_data[1] >= AZTECH_EEPROM_SIZE) + fatal("AZT EEPROM: out of bounds read to %02X\n", dsp->sb_data[1]); + sb_add_data(dsp, dsp->azt_eeprom[dsp->sb_data[1]]); + break; + } else + pclog("AZT2316A: UNKNOWN 0x08 COMMAND: %02X\n", + dsp->sb_data[0]); // 0x08 (when shutting down, driver tries to read 1 byte of response), + // 0x55, 0x0D, 0x08D seen + break; + } + 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]; + // pclog("ASP write reg %02X %02X\n", sb_data[0], sb_data[1]); + break; + case 0x0F: /*ASP get register*/ + if (dsp->sb_type < SB16) + break; + // sb_add_data(0); + sb_add_data(dsp, dsp->sb_asp_regs[dsp->sb_data[0]]); + // pclog("ASP read reg %02X %02X\n", sb_data[0], sb_asp_regs[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; + case 0x09: /*AZTECH mode set*/ + if (IS_AZTECH(dsp)) { + if (dsp->sb_data[0] == 0x00) { + pclog("AZT2316A: WSS MODE!\n"); + azt2316a_enable_wss(1, dsp->parent); + } else if (dsp->sb_data[0] == 0x01) { + pclog("AZT2316A: SB8PROV2 MODE!\n"); + azt2316a_enable_wss(0, dsp->parent); + } else + pclog("AZT2316A: UNKNOWN MODE!\n"); // sequences 0x02->0xFF, 0x04->0xFF seen + } + break; + case 0x38: /*TODO: AZTECH MIDI-related? */ + break; + // default: + // fatal("Exec bad SB command %02X\n",dsp->sb_command); - - /*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/ + /*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 @@ -745,617 +710,617 @@ void sb_exec_command(sb_dsp_t *dsp) { 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; -// pclog("sb_write : Write soundblaster %04X %02X %04X:%04X %02X\n",a,v,CS,pc,dsp->sb_command); - 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*/ - timer_set_delay_u64(&dsp->wb_timer, TIMER_USEC * 1); - if (dsp->asp_data_len) { -// pclog("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); -// if (sb_commands[v]==-1) -// fatal("Bad SB command %02X\n",v); - dsp->sb_data_stat++; - } else { - dsp->sb_data[dsp->sb_data_stat++] = v; - if (IS_AZTECH(dsp)) { - // variable length commands - if (dsp->sb_command == 0x08 && dsp->sb_data_stat == 1 && dsp->sb_data[0] == 0x08) - sb_commands[dsp->sb_command] = 3; - else if (dsp->sb_command == 0x08 && dsp->sb_data_stat == 1 && dsp->sb_data[0] == 0x07) - sb_commands[dsp->sb_command] = 2; - } - } - 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; - if (IS_AZTECH(dsp)) { - // variable length commands - if (dsp->sb_command == 0x08) - sb_commands[dsp->sb_command] = 1; - } - } - break; - } + sb_dsp_t *dsp = (sb_dsp_t *)priv; + // pclog("sb_write : Write soundblaster %04X %02X %04X:%04X %02X\n",a,v,CS,pc,dsp->sb_command); + 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*/ + timer_set_delay_u64(&dsp->wb_timer, TIMER_USEC * 1); + if (dsp->asp_data_len) { + // pclog("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); + // if (sb_commands[v]==-1) + // fatal("Bad SB command %02X\n",v); + dsp->sb_data_stat++; + } else { + dsp->sb_data[dsp->sb_data_stat++] = v; + if (IS_AZTECH(dsp)) { + // variable length commands + if (dsp->sb_command == 0x08 && dsp->sb_data_stat == 1 && dsp->sb_data[0] == 0x08) + sb_commands[dsp->sb_command] = 3; + else if (dsp->sb_command == 0x08 && dsp->sb_data_stat == 1 && dsp->sb_data[0] == 0x07) + sb_commands[dsp->sb_command] = 2; + } + } + 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; + if (IS_AZTECH(dsp)) { + // variable length commands + if (dsp->sb_command == 0x08) + sb_commands[dsp->sb_command] = 1; + } + } + break; + } } uint8_t sb_read(uint16_t a, void *priv) { - sb_dsp_t *dsp = (sb_dsp_t *)priv; -// pclog("sb_read : Read soundblaster %04X %04X:%04X\n",a,CS,pc); - switch (a & 0xf) { - case 0xA: /*Read data*/ - 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; - } -// pclog("SB read %02X\n",sbreaddat); - 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 = timer_is_enabled(&dsp->wb_timer); -// pclog("SB read 0x80\n"); - if (IS_AZTECH(dsp)) - return 0x80; - else - return 0xFF; - } -// pclog("SB read 0x00\n"); - if (IS_AZTECH(dsp)) - return 0x00; - else - return 0x7F; - case 0xE: /*Read data ready*/ - picintc(1 << dsp->sb_irqnum); - dsp->sb_irq8 = dsp->sb_irq16 = 0; - // Only bit 7 is defined but aztech diagnostics fail if the others are set. Keep the original behavior to not interfere with what's already working. - if (IS_AZTECH(dsp)) { -// pclog("SB read %02X\n",(dsp->sb_read_rp == dsp->sb_read_wp) ? 0x00 : 0x80); - return (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x00 : 0x80; - } else { -// pclog("SB read %02X\n",(dsp->sb_read_rp == dsp->sb_read_wp) ? 0x7F : 0xFF); - 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; + sb_dsp_t *dsp = (sb_dsp_t *)priv; + // pclog("sb_read : Read soundblaster %04X %04X:%04X\n",a,CS,pc); + switch (a & 0xf) { + case 0xA: /*Read data*/ + 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; + } + // pclog("SB read %02X\n",sbreaddat); + 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 = timer_is_enabled(&dsp->wb_timer); + // pclog("SB read 0x80\n"); + if (IS_AZTECH(dsp)) + return 0x80; + else + return 0xFF; + } + // pclog("SB read 0x00\n"); + if (IS_AZTECH(dsp)) + return 0x00; + else + return 0x7F; + case 0xE: /*Read data ready*/ + picintc(1 << dsp->sb_irqnum); + dsp->sb_irq8 = dsp->sb_irq16 = 0; + // Only bit 7 is defined but aztech diagnostics fail if the others are set. Keep the original behavior to not + // interfere with what's already working. + if (IS_AZTECH(dsp)) { + // pclog("SB read %02X\n",(dsp->sb_read_rp == dsp->sb_read_wp) ? 0x00 : 0x80); + return (dsp->sb_read_rp == dsp->sb_read_wp) ? 0x00 : 0x80; + } else { + // pclog("SB read %02X\n",(dsp->sb_read_rp == dsp->sb_read_wp) ? 0x7F : 0xFF); + 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) { -} +static void sb_wb_clear(void *p) {} void sb_dsp_init(sb_dsp_t *dsp, int type, int subtype, void *parent) { - dsp->sb_type = type; - dsp->sb_subtype = subtype; - dsp->parent = parent; + dsp->sb_type = type; + dsp->sb_subtype = subtype; + dsp->parent = parent; - // Default values. Use sb_dsp_setxxx() methods to change. - dsp->sb_irqnum = 7; - dsp->sb_8_dmanum = 1; - dsp->sb_16_dmanum = 5; + // 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); + sb_doreset(dsp); - timer_add(&dsp->output_timer, pollsb, dsp, 0); - timer_add(&dsp->input_timer, sb_poll_i, dsp, 0); - timer_add(&dsp->wb_timer, sb_wb_clear, dsp, 0); + timer_add(&dsp->output_timer, pollsb, dsp, 0); + timer_add(&dsp->input_timer, sb_poll_i, dsp, 0); + timer_add(&dsp->wb_timer, sb_wb_clear, dsp, 0); - /*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); + /*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) { -// pclog("sb_dsp_setaddr : %04X\n", addr); - 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); - } + // pclog("sb_dsp_setaddr : %04X\n", addr); + 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 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; + sb_dsp_t *dsp = (sb_dsp_t *)p; + int tempi, ref; - timer_advance_u64(&dsp->output_timer, dsp->sblatcho); + timer_advance_u64(&dsp->output_timer, dsp->sblatcho); -// pclog("PollSB %i %i %i %i\n",sb_8_enable,sb_8_pause,sb_pausetime,sb_8_output); - if (dsp->sb_8_enable && !dsp->sb_8_pause && dsp->sb_pausetime < 0 && dsp->sb_8_output) { - int data[2]; + // pclog("PollSB %i %i %i %i\n",sb_8_enable,sb_8_pause,sb_pausetime,sb_8_output); + if (dsp->sb_8_enable && !dsp->sb_8_pause && dsp->sb_pausetime < 0 && dsp->sb_8_output) { + int data[2]; - sb_dsp_update(dsp); -// pclog("Dopoll %i %02X %i\n", sb_8_length, sb_8_format, sblatcho); - 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; + sb_dsp_update(dsp); + // pclog("Dopoll %i %02X %i\n", sb_8_length, sb_8_format, sblatcho); + 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; + 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; + 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->sbstep = (dsp->sbstep + adjustMap4[tempi]) & 0xff; - dsp->sbdat = (dsp->sbref ^ 0x80) << 8; + 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--; - } + 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; + 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; + 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; + 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; + 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->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--; - } + 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; + 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; + 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; + 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->sbdat = (dsp->sbref ^ 0x80) << 8; - dsp->sbdacpos++; - if (dsp->sbdacpos >= 4) { - dsp->sbdacpos = 0; - dsp->sbdat2 = sb_8_read_dma(dsp); - } + 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; + 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); - } + // 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 = 0; - timer_disable(&dsp->output_timer); - } - sb_irq(dsp, 1); - } - } - if (dsp->sb_16_enable && !dsp->sb_16_pause && dsp->sb_pausetime < 0 && dsp->sb_16_output) { - int data[2]; + if (dsp->sb_8_length < 0) { + if (dsp->sb_8_autoinit) + dsp->sb_8_length = dsp->sb_8_autolen; + else { + dsp->sb_8_enable = 0; + timer_disable(&dsp->output_timer); + } + sb_irq(dsp, 1); + } + } + if (dsp->sb_16_enable && !dsp->sb_16_pause && dsp->sb_pausetime < 0 && dsp->sb_16_output) { + int data[2]; - sb_dsp_update(dsp); + 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; -// default: -// fatal("Unrecognised SB 16-bit format %02X\n",sb_16_format); - } + 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; + // default: + // fatal("Unrecognised SB 16-bit format %02X\n",sb_16_format); + } - if (dsp->sb_16_length < 0) { -// pclog("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 = 0; - timer_disable(&dsp->output_timer); - } - sb_irq(dsp, 0); - } - } - if (dsp->sb_pausetime > -1) { - dsp->sb_pausetime--; - if (dsp->sb_pausetime < 0) { - sb_irq(dsp, 1); - if (!dsp->sb_8_enable) - timer_disable(&dsp->output_timer); -// pclog("SB pause over\n"); - } - } + if (dsp->sb_16_length < 0) { + // pclog("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 = 0; + timer_disable(&dsp->output_timer); + } + sb_irq(dsp, 0); + } + } + if (dsp->sb_pausetime > -1) { + dsp->sb_pausetime--; + if (dsp->sb_pausetime < 0) { + sb_irq(dsp, 1); + if (!dsp->sb_8_enable) + timer_disable(&dsp->output_timer); + // pclog("SB pause over\n"); + } + } } void sb_poll_i(void *p) { - sb_dsp_t *dsp = (sb_dsp_t *)p; - int processed = 0; + sb_dsp_t *dsp = (sb_dsp_t *)p; + int processed = 0; - timer_advance_u64(&dsp->input_timer, dsp->sblatchi); + timer_advance_u64(&dsp->input_timer, dsp->sblatchi); -// pclog("PollSBi %i %i %i %i\n",sb_8_enable,sb_8_pause,sb_pausetime,sb_8_output); - if (dsp->sb_8_enable && !dsp->sb_8_pause && dsp->sb_pausetime < 0 && !dsp->sb_8_output) { - switch (dsp->sb_8_format) { + // pclog("PollSBi %i %i %i %i\n",sb_8_enable,sb_8_pause,sb_pausetime,sb_8_output); + if (dsp->sb_8_enable && !dsp->sb_8_pause && dsp->sb_pausetime < 0 && !dsp->sb_8_output) { + switch (dsp->sb_8_format) { #ifdef SB_TEST_RECORDING_SAW - case 0x00: /*Unsigned mono. As the manual says, only the left channel is recorded*/ - case 0x10: /*Signed mono. As the manual says, only the left channel is recorded*/ - sb_8_write_dma(dsp, counttest); - counttest+=0x10; - counttest&=0xFF; - dsp->sb_8_length--; - break; - case 0x20: /*Unsigned stereo*/ - case 0x30: /*Signed stereo*/ - sb_8_write_dma(dsp, counttest); - sb_8_write_dma(dsp, counttest); - counttest+=0x10; - counttest&=0xFF; - dsp->sb_8_length -= 2; - break; + case 0x00: /*Unsigned mono. As the manual says, only the left channel is recorded*/ + case 0x10: /*Signed mono. As the manual says, only the left channel is recorded*/ + sb_8_write_dma(dsp, counttest); + counttest += 0x10; + counttest &= 0xFF; + dsp->sb_8_length--; + break; + case 0x20: /*Unsigned stereo*/ + case 0x30: /*Signed stereo*/ + sb_8_write_dma(dsp, counttest); + sb_8_write_dma(dsp, counttest); + counttest += 0x10; + counttest &= 0xFF; + dsp->sb_8_length -= 2; + break; #else - 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; + 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; #endif -// default: -// fatal("Unrecognised SB 8-bit input format %02X\n",sb_8_format); - } + // default: + // fatal("Unrecognised SB 8-bit input format %02X\n",sb_8_format); + } - if (dsp->sb_8_length < 0) { -// pclog("Input DMA over %i\n",sb_8_autoinit); - if (dsp->sb_8_autoinit) - dsp->sb_8_length = dsp->sb_8_autolen; - else { - dsp->sb_8_enable = 0; - timer_disable(&dsp->input_timer); - } - sb_irq(dsp, 1); - } - processed = 1; - } - if (dsp->sb_16_enable && !dsp->sb_16_pause && dsp->sb_pausetime < 0 && !dsp->sb_16_output) { - switch (dsp->sb_16_format) { + if (dsp->sb_8_length < 0) { + // pclog("Input DMA over %i\n",sb_8_autoinit); + if (dsp->sb_8_autoinit) + dsp->sb_8_length = dsp->sb_8_autolen; + else { + dsp->sb_8_enable = 0; + timer_disable(&dsp->input_timer); + } + sb_irq(dsp, 1); + } + processed = 1; + } + if (dsp->sb_16_enable && !dsp->sb_16_pause && dsp->sb_pausetime < 0 && !dsp->sb_16_output) { + switch (dsp->sb_16_format) { #ifdef SB_TEST_RECORDING_SAW - case 0x00: /*Unsigned mono. As the manual says, only the left channel is recorded*/ - case 0x10: /*Signed mono. As the manual says, only the left channel is recorded*/ - if (sb_16_write_dma(dsp, counttest)) - return; - counttest+=0x1000; - counttest&=0xFFFF; - dsp->sb_16_length--; - break; - case 0x20: /*Unsigned stereo*/ - case 0x30: /*Signed stereo*/ - if (sb_16_write_dma(dsp, counttest)) - return; - sb_16_write_dma(dsp, counttest); - counttest+=0x1000; - counttest&=0xFFFF; - dsp->sb_16_length -= 2; - break; + case 0x00: /*Unsigned mono. As the manual says, only the left channel is recorded*/ + case 0x10: /*Signed mono. As the manual says, only the left channel is recorded*/ + if (sb_16_write_dma(dsp, counttest)) + return; + counttest += 0x1000; + counttest &= 0xFFFF; + dsp->sb_16_length--; + break; + case 0x20: /*Unsigned stereo*/ + case 0x30: /*Signed stereo*/ + if (sb_16_write_dma(dsp, counttest)) + return; + sb_16_write_dma(dsp, counttest); + counttest += 0x1000; + counttest &= 0xFFFF; + dsp->sb_16_length -= 2; + break; #else - 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; + 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; #endif -// default: -// fatal("Unrecognised SB 16-bit input format %02X\n",sb_16_format); - } + // default: + // fatal("Unrecognised SB 16-bit input format %02X\n",sb_16_format); + } - if (dsp->sb_16_length < 0) { -// pclog("16iDMA over %i\n",sb_16_autoinit); - if (dsp->sb_16_autoinit) - dsp->sb_16_length = dsp->sb_16_autolen; - else { - dsp->sb_16_enable = 0; - timer_disable(&dsp->input_timer); - } - sb_irq(dsp, 0); - } - processed = 1; - } - //Assume this is direct mode - if (!processed) { - dsp->record_pos_read += 2; - dsp->record_pos_read &= 0xFFFF; - } + if (dsp->sb_16_length < 0) { + // pclog("16iDMA over %i\n",sb_16_autoinit); + if (dsp->sb_16_autoinit) + dsp->sb_16_length = dsp->sb_16_autolen; + else { + dsp->sb_16_enable = 0; + timer_disable(&dsp->input_timer); + } + 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; - } + 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) { #ifdef SB_DSP_RECORD_DEBUG - if (soundf != 0) - { - fclose(soundf); - soundf=0; - } + if (soundf != 0) { + fclose(soundf); + soundf = 0; + } #endif } void sb_dsp_add_status_info(char *s, int max_len, sb_dsp_t *dsp) { - char temps[128]; - int freq; + char temps[128]; + int freq; - if (dsp->sb_timeo < 256) - freq = 1000000 / (256 - dsp->sb_timeo); - else - freq = dsp->sb_timeo - 256; + if (dsp->sb_timeo < 256) + freq = 1000000 / (256 - dsp->sb_timeo); + else + freq = dsp->sb_timeo - 256; - if (dsp->sb_8_enable && dsp->sb_8_output) { - switch (dsp->sb_8_format) { - case 0x00: /*Mono unsigned*/ - case 0x10: /*Mono signed*/ - if (dsp->sb_type >= SBPRO && dsp->sb_type < SB16 && dsp->stereo) { - strcpy(temps, "SB playback format : 8-bit stereo\n"); - freq /= 2; - } else - strcpy(temps, "SB playback format : 8-bit mono\n"); - break; - case 0x20: /*Stereo unsigned*/ - case 0x30: /*Stereo signed*/ - strcpy(temps, "SB playback format : 8-bit stereo\n"); - break; - case ADPCM_4:strcpy(temps, "SB playback format : 4-bit ADPCM\n"); - break; - case ADPCM_26:strcpy(temps, "SB playback format : 2.6-bit ADPCM\n"); - break; - case ADPCM_2:strcpy(temps, "SB playback format : 2-bit ADPCM\n"); - break; - } - } else if (dsp->sb_16_enable && dsp->sb_16_output) { - switch (dsp->sb_16_format) { - case 0x00: /*Mono unsigned*/ - case 0x10: /*Mono signed*/ - strcpy(temps, "SB playback format : 16-bit mono\n"); - break; - case 0x20: /*Stereo unsigned*/ - case 0x30: /*Stereo signed*/ - strcpy(temps, "SB playback format : 16-bit stereo\n"); - break; - } - } else - strcpy(temps, "SB playback stopped\n"); - strncat(s, temps, max_len); + if (dsp->sb_8_enable && dsp->sb_8_output) { + switch (dsp->sb_8_format) { + case 0x00: /*Mono unsigned*/ + case 0x10: /*Mono signed*/ + if (dsp->sb_type >= SBPRO && dsp->sb_type < SB16 && dsp->stereo) { + strcpy(temps, "SB playback format : 8-bit stereo\n"); + freq /= 2; + } else + strcpy(temps, "SB playback format : 8-bit mono\n"); + break; + case 0x20: /*Stereo unsigned*/ + case 0x30: /*Stereo signed*/ + strcpy(temps, "SB playback format : 8-bit stereo\n"); + break; + case ADPCM_4: + strcpy(temps, "SB playback format : 4-bit ADPCM\n"); + break; + case ADPCM_26: + strcpy(temps, "SB playback format : 2.6-bit ADPCM\n"); + break; + case ADPCM_2: + strcpy(temps, "SB playback format : 2-bit ADPCM\n"); + break; + } + } else if (dsp->sb_16_enable && dsp->sb_16_output) { + switch (dsp->sb_16_format) { + case 0x00: /*Mono unsigned*/ + case 0x10: /*Mono signed*/ + strcpy(temps, "SB playback format : 16-bit mono\n"); + break; + case 0x20: /*Stereo unsigned*/ + case 0x30: /*Stereo signed*/ + strcpy(temps, "SB playback format : 16-bit stereo\n"); + break; + } + } else + strcpy(temps, "SB playback stopped\n"); + strncat(s, temps, max_len); - if ((dsp->sb_8_enable && dsp->sb_8_output) || (dsp->sb_16_enable && dsp->sb_16_output)) { - sprintf(temps, "SB playback frequency : %iHz\n", freq); - strncat(s, temps, max_len); - } - strncat(s, "\n", max_len); + if ((dsp->sb_8_enable && dsp->sb_8_output) || (dsp->sb_16_enable && dsp->sb_16_output)) { + sprintf(temps, "SB playback frequency : %iHz\n", freq); + strncat(s, temps, max_len); + } + strncat(s, "\n", max_len); } diff --git a/src/sound/sound_sn76489.c b/src/sound/sound_sn76489.c index 1b5f7e79..9d6998c1 100644 --- a/src/sound/sound_sn76489.c +++ b/src/sound/sound_sn76489.c @@ -7,217 +7,197 @@ 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 - }; +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}; //#define PSGCONST ((3579545.0 / 64.0) / 48000.0) void sn76489_update(sn76489_t *sn76489) { - for (; sn76489->pos < sound_pos_global; sn76489->pos++) { - int c; - int16_t result = 0; + 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); + 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[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->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; - } + sn76489->buffer[sn76489->pos] = result; + } } void sn76489_get_buffer(int32_t *buffer, int len, void *p) { - sn76489_t *sn76489 = (sn76489_t *)p; + sn76489_t *sn76489 = (sn76489_t *)p; - int c; + int c; - sn76489_update(sn76489); + sn76489_update(sn76489); - if (!sn76489_mute) { - for (c = 0; c < len * 2; c++) - buffer[c] += sn76489->buffer[c >> 1]; - } + if (!sn76489_mute) { + for (c = 0; c < len * 2; c++) + buffer[c] += sn76489->buffer[c >> 1]; + } - sn76489->pos = 0; + sn76489->pos = 0; } void sn76489_write(uint16_t addr, uint8_t data, void *p) { - sn76489_t *sn76489 = (sn76489_t *)p; - int freq; + sn76489_t *sn76489 = (sn76489_t *)p; + int freq; - sn76489_update(sn76489); + 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->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; - } - } + 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->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 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); + 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; - 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->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; + 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; + sn76489_mute = 0; - io_sethandler(base, size, NULL, NULL, NULL, sn76489_write, NULL, NULL, sn76489); + io_sethandler(base, size, NULL, NULL, NULL, sn76489_write, NULL, NULL, sn76489); } void *sn76489_device_init() { - sn76489_t *sn76489 = malloc(sizeof(sn76489_t)); - memset(sn76489, 0, sizeof(sn76489_t)); + sn76489_t *sn76489 = malloc(sizeof(sn76489_t)); + memset(sn76489, 0, sizeof(sn76489_t)); - sn76489_init(sn76489, 0x00c0, 0x0008, SN76496, 3579545); + sn76489_init(sn76489, 0x00c0, 0x0008, SN76496, 3579545); - return sn76489; + return sn76489; } void *ncr8496_device_init() { - sn76489_t *sn76489 = malloc(sizeof(sn76489_t)); - memset(sn76489, 0, sizeof(sn76489_t)); + sn76489_t *sn76489 = malloc(sizeof(sn76489_t)); + memset(sn76489, 0, sizeof(sn76489_t)); - sn76489_init(sn76489, 0x00c0, 0x0008, NCR8496, 3579545); + sn76489_init(sn76489, 0x00c0, 0x0008, NCR8496, 3579545); - return sn76489; + return sn76489; } void sn76489_device_close(void *p) { - sn76489_t *sn76489 = (sn76489_t *)p; + sn76489_t *sn76489 = (sn76489_t *)p; - free(sn76489); + free(sn76489); } -device_t sn76489_device = - { - "TI SN74689 PSG", - 0, - sn76489_device_init, - sn76489_device_close, - NULL, - NULL, - NULL, - NULL - }; -device_t ncr8496_device = - { - "NCR8496 PSG", - 0, - ncr8496_device_init, - sn76489_device_close, - NULL, - NULL, - NULL, - NULL - }; +device_t sn76489_device = {"TI SN74689 PSG", 0, sn76489_device_init, sn76489_device_close, NULL, NULL, NULL, NULL}; +device_t ncr8496_device = {"NCR8496 PSG", 0, ncr8496_device_init, sn76489_device_close, NULL, NULL, NULL, NULL}; diff --git a/src/sound/sound_speaker.c b/src/sound/sound_speaker.c index 55c06ba6..57aa32dc 100644 --- a/src/sound/sound_speaker.c +++ b/src/sound/sound_speaker.c @@ -12,41 +12,41 @@ int speaker_gated = 0; int speaker_enable = 0, was_speaker_enable = 0; void speaker_update() { - int16_t val; + int16_t val; -// printf("SPeaker - %i %i %i %02X\n",speakval,gated,speakon,pit.m[2]); - 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; + // printf("SPeaker - %i %i %i %02X\n",speakval,gated,speakon,pit.m[2]); + 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; + if (!speaker_enable) + was_speaker_enable = 0; - speaker_buffer[speaker_pos] = val; - } + speaker_buffer[speaker_pos] = val; + } } static void speaker_get_buffer(int32_t *buffer, int len, void *p) { - int c; + int c; - speaker_update(); + speaker_update(); - if (!speaker_mute) { - for (c = 0; c < len * 2; c++) - buffer[c] += speaker_buffer[c >> 1]; - } + if (!speaker_mute) { + for (c = 0; c < len * 2; c++) + buffer[c] += speaker_buffer[c >> 1]; + } - speaker_pos = 0; + speaker_pos = 0; } void speaker_init() { - sound_add_handler(speaker_get_buffer, NULL); - speaker_mute = 0; + sound_add_handler(speaker_get_buffer, NULL); + speaker_mute = 0; } diff --git a/src/sound/sound_ssi2001.c b/src/sound/sound_ssi2001.c index b0f981ef..670e33b1 100644 --- a/src/sound/sound_ssi2001.c +++ b/src/sound/sound_ssi2001.c @@ -8,74 +8,64 @@ #include "sound_ssi2001.h" typedef struct ssi2001_t { - void *psid; - int16_t buffer[MAXSOUNDBUFLEN * 2]; - int pos; + void *psid; + int16_t buffer[MAXSOUNDBUFLEN * 2]; + int pos; } ssi2001_t; static void ssi2001_update(ssi2001_t *ssi2001) { - if (ssi2001->pos >= sound_pos_global) - return; + 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; + 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_t *ssi2001 = (ssi2001_t *)p; + int c; - ssi2001_update(ssi2001); + ssi2001_update(ssi2001); - for (c = 0; c < len * 2; c++) - buffer[c] += ssi2001->buffer[c >> 1] / 2; + for (c = 0; c < len * 2; c++) + buffer[c] += ssi2001->buffer[c >> 1] / 2; - ssi2001->pos = 0; + ssi2001->pos = 0; } static uint8_t ssi2001_read(uint16_t addr, void *p) { - ssi2001_t *ssi2001 = (ssi2001_t *)p; + ssi2001_t *ssi2001 = (ssi2001_t *)p; - ssi2001_update(ssi2001); + ssi2001_update(ssi2001); - return sid_read(addr, p); + return sid_read(addr, p); } static void ssi2001_write(uint16_t addr, uint8_t val, void *p) { - ssi2001_t *ssi2001 = (ssi2001_t *)p; + ssi2001_t *ssi2001 = (ssi2001_t *)p; - ssi2001_update(ssi2001); - sid_write(addr, val, p); + ssi2001_update(ssi2001); + sid_write(addr, val, p); } void *ssi2001_init() { - ssi2001_t *ssi2001 = malloc(sizeof(ssi2001_t)); - memset(ssi2001, 0, sizeof(ssi2001_t)); + ssi2001_t *ssi2001 = malloc(sizeof(ssi2001_t)); + memset(ssi2001, 0, sizeof(ssi2001_t)); - pclog("ssi2001_init\n"); - 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; + pclog("ssi2001_init\n"); + 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; + ssi2001_t *ssi2001 = (ssi2001_t *)p; - sid_close(ssi2001->psid); + sid_close(ssi2001->psid); - free(ssi2001); + free(ssi2001); } -device_t ssi2001_device = - { - "Innovation SSI-2001", - 0, - ssi2001_init, - ssi2001_close, - NULL, - NULL, - NULL, - NULL - }; +device_t ssi2001_device = {"Innovation SSI-2001", 0, ssi2001_init, ssi2001_close, NULL, NULL, NULL, NULL}; diff --git a/src/sound/sound_wss.c b/src/sound/sound_wss.c index e5d8f14a..dc44d3e3 100644 --- a/src/sound/sound_wss.c +++ b/src/sound/sound_wss.c @@ -25,118 +25,93 @@ /*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*/ -//static uint16_t wss_addr[4] = {0x530, 0x604, 0xe80, 0xf40}; +// static uint16_t wss_addr[4] = {0x530, 0x604, 0xe80, 0xf40}; typedef struct wss_t { - uint8_t config; + uint8_t config; - ad1848_t ad1848; - opl_t opl; + 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; -// pclog("wss_read - addr %04X %04X(%08X):%08X ", addr, CS, cs, pc); - temp = 4 | (wss->config & 0x40); -// pclog("return %02X\n", temp); - return temp; + wss_t *wss = (wss_t *)p; + uint8_t temp; + // pclog("wss_read - addr %04X %04X(%08X):%08X ", addr, CS, cs, pc); + temp = 4 | (wss->config & 0x40); + // pclog("return %02X\n", temp); + return temp; } void wss_write(uint16_t addr, uint8_t val, void *p) { - wss_t *wss = (wss_t *)p; -// pclog("wss_write - addr %04X val %02X %04X(%08X):%08X\n", addr, val, CS, cs, pc); + wss_t *wss = (wss_t *)p; + // pclog("wss_write - addr %04X val %02X %04X(%08X):%08X\n", addr, val, CS, cs, pc); - wss->config = val; - ad1848_setdma(&wss->ad1848, wss_dma[val & 3]); - ad1848_setirq(&wss->ad1848, wss_irq[(val >> 3) & 7]); + 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; + wss_t *wss = (wss_t *)p; - int c; + 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); - } + 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; + wss->opl.pos = 0; + wss->ad1848.pos = 0; } void *wss_init() { - int opl_emu; - wss_t *wss = malloc(sizeof(wss_t)); - memset(wss, 0, sizeof(wss_t)); + int opl_emu; + wss_t *wss = malloc(sizeof(wss_t)); + memset(wss, 0, sizeof(wss_t)); - opl_emu = device_get_config_int("opl_emu"); - opl3_init(&wss->opl, opl_emu); - ad1848_init(&wss->ad1848, AD1848_TYPE_DEFAULT); + opl_emu = device_get_config_int("opl_emu"); + opl3_init(&wss->opl, opl_emu); + ad1848_init(&wss->ad1848, AD1848_TYPE_DEFAULT); - ad1848_setirq(&wss->ad1848, 7); - ad1848_setdma(&wss->ad1848, 3); + 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); + 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); + sound_add_handler(wss_get_buffer, wss); - return wss; + return wss; } void wss_close(void *p) { - wss_t *wss = (wss_t *)p; + wss_t *wss = (wss_t *)p; - free(wss); + free(wss); } void wss_speed_changed(void *p) { - wss_t *wss = (wss_t *)p; + wss_t *wss = (wss_t *)p; - ad1848_speed_changed(&wss->ad1848); + ad1848_speed_changed(&wss->ad1848); } -static device_config_t wss_config[] = - { - { - .name = "opl_emu", - .description = "OPL emulator", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "DBOPL", - .value = OPL_DBOPL - }, - { - .description = "NukedOPL", - .value = OPL_NUKED - }, - }, - .default_int = OPL_DBOPL - }, - { - .type = -1 - } - }; +static device_config_t wss_config[] = {{.name = "opl_emu", + .description = "OPL emulator", + .type = CONFIG_SELECTION, + .selection = + { + {.description = "DBOPL", .value = OPL_DBOPL}, + {.description = "NukedOPL", .value = OPL_NUKED}, + }, + .default_int = OPL_DBOPL}, + {.type = -1}}; -device_t wss_device = - { - "Windows Sound System", - 0, - wss_init, - wss_close, - NULL, - wss_speed_changed, - NULL, - NULL, - wss_config - }; +device_t wss_device = {"Windows Sound System", 0, wss_init, wss_close, NULL, wss_speed_changed, NULL, NULL, wss_config}; diff --git a/src/sound/sound_ym7128.c b/src/sound/sound_ym7128.c index 5ca2ad41..22a6c8d4 100644 --- a/src/sound/sound_ym7128.c +++ b/src/sound/sound_ym7128.c @@ -5,139 +5,154 @@ static int attenuation[32]; static int tap_position[32]; void ym7128_init(ym7128_t *ym7128) { - int c; - double out = 65536.0; + int c; + double out = 65536.0; - for (c = 0; c < 32; c++) - tap_position[c] = c * (2400 / 31); + 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; + 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; -// pclog("ym7128_write %i %i %i\n", new_dat, new_sci, new_a0); - if (!ym7128->sci && new_sci) - ym7128->dat = (ym7128->dat << 1) | new_dat; + int new_dat = val & 1; + int new_sci = val & 2; + int new_a0 = val & 4; + // pclog("ym7128_write %i %i %i\n", new_dat, new_sci, new_a0); + if (!ym7128->sci && new_sci) + ym7128->dat = (ym7128->dat << 1) | new_dat; - if (ym7128->a0 != new_a0) { -// pclog("ym7128 write %i %02x\n", ym7128->a0, ym7128->dat); - if (!ym7128->a0) - ym7128->reg_sel = ym7128->dat & 0x1f; - else { -// pclog("YM7128 write %02x %02x\n", ym7128->reg_sel, ym7128->dat); - 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); -// pclog(" GL[%i] = %04x\n", 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); -// pclog(" GR[%i] = %04x\n", ym7128->reg_sel & 7, GET_ATTENUATION(ym7128->dat)); - break; + if (ym7128->a0 != new_a0) { + // pclog("ym7128 write %i %02x\n", ym7128->a0, ym7128->dat); + if (!ym7128->a0) + ym7128->reg_sel = ym7128->dat & 0x1f; + else { + // pclog("YM7128 write %02x %02x\n", ym7128->reg_sel, ym7128->dat); + 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); + // pclog(" GL[%i] = %04x\n", 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); + // pclog(" GR[%i] = %04x\n", ym7128->reg_sel & 7, + // GET_ATTENUATION(ym7128->dat)); + break; - case 0x10:ym7128->vm = GET_ATTENUATION(ym7128->dat); -// pclog(" VM = %04x\n", GET_ATTENUATION(ym7128->dat)); - break; - case 0x11:ym7128->vc = GET_ATTENUATION(ym7128->dat); -// pclog(" VC = %04x\n", GET_ATTENUATION(ym7128->dat)); - break; - case 0x12:ym7128->vl = GET_ATTENUATION(ym7128->dat); -// pclog(" VL = %04x\n", GET_ATTENUATION(ym7128->dat)); - break; - case 0x13:ym7128->vr = GET_ATTENUATION(ym7128->dat); -// pclog(" VR = %04x\n", GET_ATTENUATION(ym7128->dat)); - break; + case 0x10: + ym7128->vm = GET_ATTENUATION(ym7128->dat); + // pclog(" VM = %04x\n", GET_ATTENUATION(ym7128->dat)); + break; + case 0x11: + ym7128->vc = GET_ATTENUATION(ym7128->dat); + // pclog(" VC = %04x\n", GET_ATTENUATION(ym7128->dat)); + break; + case 0x12: + ym7128->vl = GET_ATTENUATION(ym7128->dat); + // pclog(" VL = %04x\n", GET_ATTENUATION(ym7128->dat)); + break; + case 0x13: + ym7128->vr = GET_ATTENUATION(ym7128->dat); + // pclog(" VR = %04x\n", 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 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]; -// pclog(" T[%i] = %i\n", ym7128->reg_sel - 0x16, tap_position[ym7128->dat & 0x1f]); - break; - } - ym7128->regs[ym7128->reg_sel] = ym7128->dat; - } - ym7128->dat = 0; - } + 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]; + // pclog(" T[%i] = %i\n", 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; + 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]) +#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; + 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; + 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; + 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; + samp = (samp * ym7128->vm) >> 16; + samp += filter_out; - ym7128->delay_buffer[ym7128->delay_pos] = samp; + 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; - } + 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; + 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; + 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->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; - } + ym7128->filter_dat = filter_temp; + ym7128->prev_l = samp_l; + ym7128->prev_r = samp_r; + } } diff --git a/src/sound/soundopenal.c b/src/sound/soundopenal.c index 9b08444e..cb7954db 100644 --- a/src/sound/soundopenal.c +++ b/src/sound/soundopenal.c @@ -17,9 +17,9 @@ FILE *allog; #ifdef USE_OPENAL -ALuint buffers[4]; // front and back buffers -ALuint buffers_cd[4]; // front and back buffers -static ALuint source[2]; // audio source +ALuint buffers[4]; // front and back buffers +ALuint buffers_cd[4]; // front and back buffers +static ALuint source[2]; // audio source #endif #define FREQ 48000 @@ -29,232 +29,232 @@ int SOUNDBUFLEN = 48000 / 20; void closeal(); ALvoid alutInit(ALint *argc, ALbyte **argv) { - ALCcontext *Context; - ALCdevice *Device; + ALCcontext *Context; + ALCdevice *Device; - //Open device -// Device=alcOpenDevice((ALubyte*)""); - Device = alcOpenDevice((void *)""); - //Create context(s) - Context = alcCreateContext(Device, NULL); - //Set active context - alcMakeContextCurrent(Context); - //Register extensions + // Open device + // Device=alcOpenDevice((ALubyte*)""); + Device = alcOpenDevice((void *)""); + // Create context(s) + Context = alcCreateContext(Device, NULL); + // Set active context + alcMakeContextCurrent(Context); + // Register extensions } ALvoid alutExit(ALvoid) { - ALCcontext *Context; - ALCdevice *Device; + ALCcontext *Context; + ALCdevice *Device; - //Unregister extensions + // Unregister extensions - //Get active context - Context = alcGetCurrentContext(); - //Get device for active context - Device = alcGetContextsDevice(Context); - //Disable context - alcMakeContextCurrent(NULL); - //Release context(s) - alcDestroyContext(Context); - //Close device - alcCloseDevice(Device); + // Get active context + Context = alcGetCurrentContext(); + // Get device for active context + Device = alcGetContextsDevice(Context); + // Disable context + alcMakeContextCurrent(NULL); + // Release context(s) + alcDestroyContext(Context); + // Close device + alcCloseDevice(Device); } void initalmain(int argc, char *argv[]) { #ifdef USE_OPENAL - alutInit(0, 0); -// printf("AlutInit\n"); - atexit(closeal); + alutInit(0, 0); + // printf("AlutInit\n"); + atexit(closeal); // printf("AlutInit\n"); #endif } void closeal() { #ifdef USE_OPENAL - alutExit(); + alutExit(); #endif } void check() { #ifdef USE_OPENAL - ALenum error; - if ((error = alGetError()) != AL_NO_ERROR) { -// printf("Error : %08X\n", error); -// exit(-1); - } + ALenum error; + if ((error = alGetError()) != AL_NO_ERROR) { + // printf("Error : %08X\n", error); + // exit(-1); + } #endif } void inital() { #ifdef USE_OPENAL - int c; - int16_t buf[BUFLEN * 2]; - int16_t cd_buf[CD_BUFLEN * 2]; + int c; + int16_t buf[BUFLEN * 2]; + int16_t cd_buf[CD_BUFLEN * 2]; -// printf("1\n"); - check(); + // printf("1\n"); + check(); -// printf("2\n"); - alGenBuffers(4, buffers); - check(); - alGenBuffers(4, buffers_cd); - check(); + // printf("2\n"); + alGenBuffers(4, buffers); + check(); + alGenBuffers(4, buffers_cd); + check(); -// printf("3\n"); - alGenSources(2, source); - check(); + // printf("3\n"); + alGenSources(2, source); + check(); -// printf("4\n"); - 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); - check(); - 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); - check(); + // printf("4\n"); + 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); + check(); + 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); + check(); - memset(buf, 0, BUFLEN * 4); - memset(cd_buf, 0, CD_BUFLEN * 4); + memset(buf, 0, BUFLEN * 4); + memset(cd_buf, 0, CD_BUFLEN * 4); -// printf("5\n"); - for (c = 0; c < 4; c++) { - alBufferData(buffers[c], AL_FORMAT_STEREO16, buf, BUFLEN * 2 * 2, FREQ); - alBufferData(buffers_cd[c], AL_FORMAT_STEREO16, cd_buf, CD_BUFLEN * 2 * 2, CD_FREQ); - } + // printf("5\n"); + for (c = 0; c < 4; c++) { + alBufferData(buffers[c], AL_FORMAT_STEREO16, buf, BUFLEN * 2 * 2, FREQ); + alBufferData(buffers_cd[c], AL_FORMAT_STEREO16, cd_buf, CD_BUFLEN * 2 * 2, CD_FREQ); + } - alSourceQueueBuffers(source[0], 4, buffers); - check(); - alSourceQueueBuffers(source[1], 4, buffers_cd); - check(); -// printf("6 %08X\n",source); - alSourcePlay(source[0]); - check(); - alSourcePlay(source[1]); - check(); + alSourceQueueBuffers(source[0], 4, buffers); + check(); + alSourceQueueBuffers(source[1], 4, buffers_cd); + check(); + // printf("6 %08X\n",source); + alSourcePlay(source[0]); + check(); + alSourcePlay(source[1]); + check(); // printf("InitAL!!! %08X\n",source); #endif } void givealbuffer(int32_t *buf) { #ifdef USE_OPENAL - int16_t buf16[BUFLEN * 2]; - int processed; - int state; + int16_t buf16[BUFLEN * 2]; + int processed; + int state; - //return; + // return; -// printf("Start\n"); - check(); + // printf("Start\n"); + check(); -// printf("GiveALBuffer %08X\n",source); + // printf("GiveALBuffer %08X\n",source); - alGetSourcei(source[0], AL_SOURCE_STATE, &state); + alGetSourcei(source[0], AL_SOURCE_STATE, &state); - check(); + check(); - if (state == 0x1014) { - alSourcePlay(source[0]); -// printf("Resetting sound\n"); - } -// printf("State - %i %08X\n",state,state); - alGetSourcei(source[0], AL_BUFFERS_PROCESSED, &processed); + if (state == 0x1014) { + alSourcePlay(source[0]); + // printf("Resetting sound\n"); + } + // printf("State - %i %08X\n",state,state); + alGetSourcei(source[0], AL_BUFFERS_PROCESSED, &processed); -// printf("P "); - check(); -// printf("Processed - %i\n",processed); + // printf("P "); + check(); + // printf("Processed - %i\n",processed); - if (processed >= 1) { - int c; - ALuint buffer; - double gain = pow(10.0, (double)sound_gain / 20.0); + if (processed >= 1) { + int c; + ALuint buffer; + double gain = pow(10.0, (double)sound_gain / 20.0); - alListenerf(AL_GAIN, gain); + alListenerf(AL_GAIN, gain); - alSourceUnqueueBuffers(source[0], 1, &buffer); -// printf("U "); - check(); + alSourceUnqueueBuffers(source[0], 1, &buffer); + // printf("U "); + check(); - for (c = 0; c < BUFLEN * 2; c++) { - if (buf[c] < -32768) - buf16[c] = -32768; - else if (buf[c] > 32767) - buf16[c] = 32767; - else - buf16[c] = buf[c]; - } -// for (c=0;c 32767) + buf16[c] = 32767; + else + buf16[c] = buf[c]; + } + // for (c=0;c= 1) { - ALuint buffer; - double gain = pow(10.0, (double)sound_gain / 20.0); + if (processed >= 1) { + ALuint buffer; + double gain = pow(10.0, (double)sound_gain / 20.0); - alListenerf(AL_GAIN, gain); + alListenerf(AL_GAIN, gain); - alSourceUnqueueBuffers(source[1], 1, &buffer); -// printf("U "); - check(); + alSourceUnqueueBuffers(source[1], 1, &buffer); + // printf("U "); + check(); -// for (c=0;c> 4) & 7]; - midi_command = 0; - if (val == 0xf0) - midi_insysex = 1; - } + if ((val & 0x80) && !(val == 0xf7 && midi_insysex)) { + midi_pos = 0; + midi_len = midi_lengths[(val >> 4) & 7]; + midi_command = 0; + if (val == 0xf0) + midi_insysex = 1; + } - if (midi_insysex) { - midi_sysex_data[midi_pos++] = val; + if (midi_insysex) { + midi_sysex_data[midi_pos++] = val; - if (val == 0xf7 || midi_pos >= 1024 + 2) - midi_send_sysex(); - return; - } + if (val == 0xf7 || midi_pos >= 1024 + 2) + midi_send_sysex(); + return; + } - if (midi_len) { - midi_command |= (val << (midi_pos * 8)); + if (midi_len) { + midi_command |= (val << (midi_pos * 8)); - midi_pos++; + midi_pos++; - if (midi_pos == midi_len) - midiOutShortMsg(midi_out_device, midi_command); - } + if (midi_pos == midi_len) + midiOutShortMsg(midi_out_device, midi_command); + } } diff --git a/src/thread-pthread.c b/src/thread-pthread.c index 575bbfb3..c380962e 100644 --- a/src/thread-pthread.c +++ b/src/thread-pthread.c @@ -5,78 +5,75 @@ #include "thread.h" typedef struct event_pthread_t { - pthread_cond_t cond; - pthread_mutex_t mutex; + pthread_cond_t cond; + pthread_mutex_t mutex; } event_pthread_t; thread_t *thread_create(void (*thread_rout)(void *param), void *param) { - pthread_t *thread = malloc(sizeof(pthread_t)); + pthread_t *thread = malloc(sizeof(pthread_t)); - pthread_create(thread, NULL, (void *)thread_rout, param); + pthread_create(thread, NULL, (void *)thread_rout, param); - return thread; + return thread; } void thread_kill(thread_t *handle) { - pthread_t *thread = (pthread_t *)handle; + pthread_t *thread = (pthread_t *)handle; - pthread_cancel(*thread); - pthread_join(*thread, NULL); + pthread_cancel(*thread); + pthread_join(*thread, NULL); - free(thread); + free(thread); } event_t *thread_create_event() { - event_pthread_t *event = malloc(sizeof(event_pthread_t)); + event_pthread_t *event = malloc(sizeof(event_pthread_t)); - pthread_cond_init(&event->cond, NULL); - pthread_mutex_init(&event->mutex, NULL); + pthread_cond_init(&event->cond, NULL); + pthread_mutex_init(&event->mutex, NULL); - return (event_t *)event; + return (event_t *)event; } void thread_set_event(event_t *handle) { - event_pthread_t *event = (event_pthread_t *)handle; + event_pthread_t *event = (event_pthread_t *)handle; - pthread_mutex_lock(&event->mutex); - pthread_cond_broadcast(&event->cond); - pthread_mutex_unlock(&event->mutex); + pthread_mutex_lock(&event->mutex); + pthread_cond_broadcast(&event->cond); + pthread_mutex_unlock(&event->mutex); } -void thread_reset_event(event_t *handle) { -} +void thread_reset_event(event_t *handle) {} int thread_wait_event(event_t *handle, int timeout) { - event_pthread_t *event = (event_pthread_t *)handle; - struct timespec abstime; + event_pthread_t *event = (event_pthread_t *)handle; + struct timespec abstime; - clock_gettime(CLOCK_REALTIME, &abstime); - abstime.tv_nsec += (timeout % 1000) * 1000000; - abstime.tv_sec += (timeout / 1000); - if (abstime.tv_nsec > 1000000000) { - abstime.tv_nsec -= 1000000000; - abstime.tv_sec++; - } + clock_gettime(CLOCK_REALTIME, &abstime); + abstime.tv_nsec += (timeout % 1000) * 1000000; + abstime.tv_sec += (timeout / 1000); + if (abstime.tv_nsec > 1000000000) { + abstime.tv_nsec -= 1000000000; + abstime.tv_sec++; + } - pthread_mutex_lock(&event->mutex); - if (timeout == -1) - pthread_cond_wait(&event->cond, &event->mutex); - else - pthread_cond_timedwait(&event->cond, &event->mutex, &abstime); - pthread_mutex_unlock(&event->mutex); + pthread_mutex_lock(&event->mutex); + if (timeout == -1) + pthread_cond_wait(&event->cond, &event->mutex); + else + pthread_cond_timedwait(&event->cond, &event->mutex, &abstime); + pthread_mutex_unlock(&event->mutex); - return 0; + return 0; } void thread_destroy_event(event_t *handle) { - event_pthread_t *event = (event_pthread_t *)handle; + event_pthread_t *event = (event_pthread_t *)handle; - pthread_cond_destroy(&event->cond); - pthread_mutex_destroy(&event->mutex); + pthread_cond_destroy(&event->cond); + pthread_mutex_destroy(&event->mutex); - free(event); + free(event); } -void thread_sleep(int t) { - usleep(t * 1000); -} +void thread_sleep(int t) { usleep(t * 1000); } diff --git a/src/timer.c b/src/timer.c index dd5c8de5..11ab2f71 100644 --- a/src/timer.c +++ b/src/timer.c @@ -10,112 +10,112 @@ uint32_t timer_target; static pc_timer_t *timer_head = NULL; void timer_enable(pc_timer_t *timer) { - pc_timer_t *timer_node = timer_head; + pc_timer_t *timer_node = timer_head; -// pclog("timer->enable %p %i\n", timer, timer->enabled); - if (timer->enabled) - timer_disable(timer); + // pclog("timer->enable %p %i\n", timer, timer->enabled); + if (timer->enabled) + timer_disable(timer); - if (timer->next || timer->prev) - fatal("timer_enable - timer->next\n"); + if (timer->next || timer->prev) + fatal("timer_enable - timer->next\n"); - timer->enabled = 1; + timer->enabled = 1; - /*List currently empty - add to head*/ - if (!timer_head) { - timer_head = timer; - timer->next = timer->prev = NULL; - timer_target = timer_head->ts_integer; - return; - } + /*List currently empty - add to head*/ + if (!timer_head) { + timer_head = timer; + timer->next = timer->prev = NULL; + timer_target = timer_head->ts_integer; + return; + } - timer_node = timer_head; + timer_node = timer_head; - while (1) { - /*Timer expires before timer_node. Add to list in front of timer_node*/ - if (TIMER_LESS_THAN(timer, timer_node)) { - timer->next = timer_node; - timer->prev = timer_node->prev; - timer_node->prev = timer; - if (timer->prev) - timer->prev->next = timer; - else { - timer_head = timer; - timer_target = timer_head->ts_integer; - } - return; - } + while (1) { + /*Timer expires before timer_node. Add to list in front of timer_node*/ + if (TIMER_LESS_THAN(timer, timer_node)) { + timer->next = timer_node; + timer->prev = timer_node->prev; + timer_node->prev = timer; + if (timer->prev) + timer->prev->next = timer; + else { + timer_head = timer; + timer_target = timer_head->ts_integer; + } + return; + } - /*timer_node is last in the list. Add timer to end of list*/ - if (!timer_node->next) { - timer_node->next = timer; - timer->prev = timer_node; - return; - } + /*timer_node is last in the list. Add timer to end of list*/ + if (!timer_node->next) { + timer_node->next = timer; + timer->prev = timer_node; + return; + } - timer_node = timer_node->next; - } + timer_node = timer_node->next; + } } void timer_disable(pc_timer_t *timer) { -// pclog("timer->disable %p\n", timer); - if (!timer->enabled) - return; + // pclog("timer->disable %p\n", timer); + if (!timer->enabled) + return; - if (!timer->next && !timer->prev && timer != timer_head) - fatal("timer_disable - !timer->next\n"); + if (!timer->next && !timer->prev && timer != timer_head) + fatal("timer_disable - !timer->next\n"); - timer->enabled = 0; + timer->enabled = 0; - if (timer->prev) - timer->prev->next = timer->next; - else - timer_head = timer->next; - if (timer->next) - timer->next->prev = timer->prev; - timer->prev = timer->next = NULL; + if (timer->prev) + timer->prev->next = timer->next; + else + timer_head = timer->next; + if (timer->next) + timer->next->prev = timer->prev; + timer->prev = timer->next = NULL; } static void timer_remove_head() { - if (timer_head) { - pc_timer_t *timer = timer_head; -// pclog("timer_remove_head %p %p\n", timer_head, timer_head->next); - timer_head = timer->next; - timer_head->prev = NULL; - timer->next = timer->prev = NULL; - timer->enabled = 0; - } + if (timer_head) { + pc_timer_t *timer = timer_head; + // pclog("timer_remove_head %p %p\n", timer_head, timer_head->next); + timer_head = timer->next; + timer_head->prev = NULL; + timer->next = timer->prev = NULL; + timer->enabled = 0; + } } void timer_process() { - if (!timer_head) - return; + if (!timer_head) + return; - while (1) { - pc_timer_t *timer = timer_head; + while (1) { + pc_timer_t *timer = timer_head; - if (!TIMER_LESS_THAN_VAL(timer, (uint32_t)tsc)) - break; + if (!TIMER_LESS_THAN_VAL(timer, (uint32_t)tsc)) + break; - timer_remove_head(); - timer->callback(timer->p); - } + timer_remove_head(); + timer->callback(timer->p); + } - timer_target = timer_head->ts_integer; + timer_target = timer_head->ts_integer; } void timer_reset() { - pclog("timer_reset\n"); - timer_target = 0; - tsc = 0; - timer_head = NULL; + pclog("timer_reset\n"); + timer_target = 0; + tsc = 0; + timer_head = NULL; } void timer_add(pc_timer_t *timer, void (*callback)(void *p), void *p, int start_timer) { - memset(timer, 0, sizeof(pc_timer_t)); + memset(timer, 0, sizeof(pc_timer_t)); - timer->callback = callback; - timer->p = p; - timer->enabled = 0; - timer->prev = timer->next = NULL; - if (start_timer) - timer_set_delay_u64(timer, 0); + timer->callback = callback; + timer->p = p; + timer->enabled = 0; + timer->prev = timer->next = NULL; + if (start_timer) + timer_set_delay_u64(timer, 0); } diff --git a/src/video/vid_ati18800.c b/src/video/vid_ati18800.c index b1ad9fd6..3e329d25 100644 --- a/src/video/vid_ati18800.c +++ b/src/video/vid_ati18800.c @@ -11,272 +11,272 @@ #include "vid_svga.h" typedef struct ati18800_t { - svga_t svga; - ati_eeprom_t eeprom; + svga_t svga; + ati_eeprom_t eeprom; - rom_t bios_rom; + rom_t bios_rom; - uint8_t regs[256]; - int index; + uint8_t regs[256]; + int index; - int is_ega; - int ega_switches; - int ega_switch_read; + int is_ega; + int ega_switches; + int ega_switch_read; } ati18800_t; void ati18800_out(uint16_t addr, uint8_t val, void *p) { - ati18800_t *ati18800 = (ati18800_t *)p; - svga_t *svga = &ati18800->svga; - uint8_t old; + ati18800_t *ati18800 = (ati18800_t *)p; + svga_t *svga = &ati18800->svga; + uint8_t old; -// pclog("ati18800_out : %04X %02X %04X:%04X\n", addr, val, CS,pc); + // pclog("ati18800_out : %04X %02X %04X:%04X\n", addr, val, CS,pc); - if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1)) - addr ^= 0x60; + if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1)) + addr ^= 0x60; - switch (addr) { - case 0x1ce:ati18800->index = val; - break; - case 0x1cf:ati18800->regs[ati18800->index] = val; - switch (ati18800->index) { - case 0xb2: - case 0xbe: - if (ati18800->regs[0xbe] & 8) /*Read/write bank mode*/ - { - svga->read_bank = ((ati18800->regs[0xb2] >> 5) & 7) * 0x10000; - svga->write_bank = ((ati18800->regs[0xb2] >> 1) & 7) * 0x10000; - } else /*Single bank mode*/ - svga->read_bank = svga->write_bank = ((ati18800->regs[0xb2] >> 1) & 7) * 0x10000; - break; - case 0xb3:ati_eeprom_write(&ati18800->eeprom, val & 8, val & 2, val & 1); - break; - } - break; + switch (addr) { + case 0x1ce: + ati18800->index = val; + break; + case 0x1cf: + ati18800->regs[ati18800->index] = val; + switch (ati18800->index) { + case 0xb2: + case 0xbe: + if (ati18800->regs[0xbe] & 8) /*Read/write bank mode*/ + { + svga->read_bank = ((ati18800->regs[0xb2] >> 5) & 7) * 0x10000; + svga->write_bank = ((ati18800->regs[0xb2] >> 1) & 7) * 0x10000; + } else /*Single bank mode*/ + svga->read_bank = svga->write_bank = ((ati18800->regs[0xb2] >> 1) & 7) * 0x10000; + break; + case 0xb3: + ati_eeprom_write(&ati18800->eeprom, val & 8, val & 2, val & 1); + break; + } + break; - case 0x3c2: - if (ati18800->is_ega) { - if ((val & 0x80) != (svga->miscout & 0x80)) { - int c; + case 0x3c2: + if (ati18800->is_ega) { + if ((val & 0x80) != (svga->miscout & 0x80)) { + int c; - if (val & 0x80) { - for (c = 0; c < 256; c++) { - ati18800->svga.pallook[c] = makecol32(((c >> 2) & 1) * 0xaa, ((c >> 1) & 1) * 0xaa, (c & 1) * 0xaa); - ati18800->svga.pallook[c] += makecol32(((c >> 5) & 1) * 0x55, ((c >> 4) & 1) * 0x55, ((c >> 3) & 1) * 0x55); - } - ati18800->svga.vertical_linedbl = 0; - } else { - for (c = 0; c < 256; c++) { - if ((c & 0x17) == 6) - ati18800->svga.pallook[c] = makecol32(0xaa, 0x55, 0x00); - else { - ati18800->svga.pallook[c] = makecol32(((c >> 2) & 1) * 0xaa, ((c >> 1) & 1) * 0xaa, (c & 1) * 0xaa); - ati18800->svga.pallook[c] += makecol32(((c >> 4) & 1) * 0x55, ((c >> 4) & 1) * 0x55, ((c >> 4) & 1) * 0x55); - } - } - ati18800->svga.vertical_linedbl = 1; - } + if (val & 0x80) { + for (c = 0; c < 256; c++) { + ati18800->svga.pallook[c] = + makecol32(((c >> 2) & 1) * 0xaa, ((c >> 1) & 1) * 0xaa, (c & 1) * 0xaa); + ati18800->svga.pallook[c] += makecol32( + ((c >> 5) & 1) * 0x55, ((c >> 4) & 1) * 0x55, ((c >> 3) & 1) * 0x55); + } + ati18800->svga.vertical_linedbl = 0; + } else { + for (c = 0; c < 256; c++) { + if ((c & 0x17) == 6) + ati18800->svga.pallook[c] = makecol32(0xaa, 0x55, 0x00); + else { + ati18800->svga.pallook[c] = makecol32( + ((c >> 2) & 1) * 0xaa, ((c >> 1) & 1) * 0xaa, (c & 1) * 0xaa); + ati18800->svga.pallook[c] += + makecol32(((c >> 4) & 1) * 0x55, ((c >> 4) & 1) * 0x55, + ((c >> 4) & 1) * 0x55); + } + } + ati18800->svga.vertical_linedbl = 1; + } - svga->fullchange = changeframecount; - } - ati18800->ega_switch_read = val & 0xc; - } - break; + svga->fullchange = changeframecount; + } + ati18800->ega_switch_read = val & 0xc; + } + break; - case 0x3D4:svga->crtcreg = val & 0x3f; - return; - case 0x3D5: - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) - return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); - old = svga->crtc[svga->crtcreg]; - svga->crtc[svga->crtcreg] = val; - if (old != val) { - if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - } - break; - } - svga_out(addr, val, svga); + case 0x3D4: + svga->crtcreg = val & 0x3f; + return; + case 0x3D5: + if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) + return; + if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) + val = (svga->crtc[7] & ~0x10) | (val & 0x10); + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; + if (old != val) { + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } + } + break; + } + svga_out(addr, val, svga); } uint8_t ati18800_in(uint16_t addr, void *p) { - ati18800_t *ati18800 = (ati18800_t *)p; - svga_t *svga = &ati18800->svga; - uint8_t temp = 0xff; + ati18800_t *ati18800 = (ati18800_t *)p; + svga_t *svga = &ati18800->svga; + uint8_t temp = 0xff; -// if (addr != 0x3da) pclog("ati18800_in : %04X ", addr); + // if (addr != 0x3da) pclog("ati18800_in : %04X ", addr); - if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1)) - addr ^= 0x60; + if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1)) + addr ^= 0x60; - switch (addr) { - case 0x1ce:temp = ati18800->index; - break; - case 0x1cf: - switch (ati18800->index) { - case 0xb7:temp = ati18800->regs[ati18800->index] & ~8; - if (ati_eeprom_read(&ati18800->eeprom)) - temp |= 8; - break; + switch (addr) { + case 0x1ce: + temp = ati18800->index; + break; + case 0x1cf: + switch (ati18800->index) { + case 0xb7: + temp = ati18800->regs[ati18800->index] & ~8; + if (ati_eeprom_read(&ati18800->eeprom)) + temp |= 8; + break; - default:temp = ati18800->regs[ati18800->index]; - break; - } - break; + default: + temp = ati18800->regs[ati18800->index]; + break; + } + break; - case 0x3c2: - if (ati18800->is_ega) { - switch (ati18800->ega_switch_read) { - case 0xc:return (ati18800->ega_switches & 1) ? 0x10 : 0; - case 0x8:return (ati18800->ega_switches & 2) ? 0x10 : 0; - case 0x4:return (ati18800->ega_switches & 4) ? 0x10 : 0; - case 0x0:return (ati18800->ega_switches & 8) ? 0x10 : 0; - } - } - break; + case 0x3c2: + if (ati18800->is_ega) { + switch (ati18800->ega_switch_read) { + case 0xc: + return (ati18800->ega_switches & 1) ? 0x10 : 0; + case 0x8: + return (ati18800->ega_switches & 2) ? 0x10 : 0; + case 0x4: + return (ati18800->ega_switches & 4) ? 0x10 : 0; + case 0x0: + return (ati18800->ega_switches & 8) ? 0x10 : 0; + } + } + break; - case 0x3D4:temp = svga->crtcreg; - break; - case 0x3D5:temp = svga->crtc[svga->crtcreg]; - break; - default:temp = svga_in(addr, svga); - break; - } -// if (addr != 0x3da) pclog("%02X %04X:%04X\n", temp, CS,cpu_state.pc); - return temp; + case 0x3D4: + temp = svga->crtcreg; + break; + case 0x3D5: + temp = svga->crtc[svga->crtcreg]; + break; + default: + temp = svga_in(addr, svga); + break; + } + // if (addr != 0x3da) pclog("%02X %04X:%04X\n", temp, CS,cpu_state.pc); + return temp; } static void ega_wonder_800_recalctimings(svga_t *svga) { - ati18800_t *ati18800 = (ati18800_t *)svga->p; - int clksel = ((svga->miscout & 0xc) >> 2) | ((ati18800->regs[0xbe] & 0x10) ? 4 : 0); + ati18800_t *ati18800 = (ati18800_t *)svga->p; + int clksel = ((svga->miscout & 0xc) >> 2) | ((ati18800->regs[0xbe] & 0x10) ? 4 : 0); - switch (clksel) { - case 0:svga->clock = (cpuclock * (double)(1ull << 32)) / 25175000.0; - break; - case 1:svga->clock = (cpuclock * (double)(1ull << 32)) / 28322000.0; - break; - case 4:svga->clock = (cpuclock * (double)(1ull << 32)) / 14318181.0; - break; - case 5:svga->clock = (cpuclock * (double)(1ull << 32)) / 16257000.0; - break; - case 7: - default:svga->clock = (cpuclock * (double)(1ull << 32)) / 36000000.0; - break; - } + switch (clksel) { + case 0: + svga->clock = (cpuclock * (double)(1ull << 32)) / 25175000.0; + break; + case 1: + svga->clock = (cpuclock * (double)(1ull << 32)) / 28322000.0; + break; + case 4: + svga->clock = (cpuclock * (double)(1ull << 32)) / 14318181.0; + break; + case 5: + svga->clock = (cpuclock * (double)(1ull << 32)) / 16257000.0; + break; + case 7: + default: + svga->clock = (cpuclock * (double)(1ull << 32)) / 36000000.0; + break; + } } void *ati18800_init() { - ati18800_t *ati18800 = malloc(sizeof(ati18800_t)); - memset(ati18800, 0, sizeof(ati18800_t)); + ati18800_t *ati18800 = malloc(sizeof(ati18800_t)); + memset(ati18800, 0, sizeof(ati18800_t)); - rom_init(&ati18800->bios_rom, "vgaedge16.vbi", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&ati18800->bios_rom, "vgaedge16.vbi", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - svga_init(&ati18800->svga, ati18800, 1 << 19, /*512kb*/ - NULL, - ati18800_in, ati18800_out, - NULL, - NULL); + svga_init(&ati18800->svga, ati18800, 1 << 19, /*512kb*/ + NULL, ati18800_in, ati18800_out, NULL, NULL); - io_sethandler(0x01ce, 0x0002, ati18800_in, NULL, NULL, ati18800_out, NULL, NULL, ati18800); - io_sethandler(0x03c0, 0x0020, ati18800_in, NULL, NULL, ati18800_out, NULL, NULL, ati18800); + io_sethandler(0x01ce, 0x0002, ati18800_in, NULL, NULL, ati18800_out, NULL, NULL, ati18800); + io_sethandler(0x03c0, 0x0020, ati18800_in, NULL, NULL, ati18800_out, NULL, NULL, ati18800); - ati18800->svga.miscout = 1; + ati18800->svga.miscout = 1; - ati_eeprom_load(&ati18800->eeprom, "ati18800.nvr", 0); + ati_eeprom_load(&ati18800->eeprom, "ati18800.nvr", 0); - return ati18800; + return ati18800; } void *ega_wonder_800_init() { - int c; + int c; - ati18800_t *ati18800 = malloc(sizeof(ati18800_t)); - memset(ati18800, 0, sizeof(ati18800_t)); + ati18800_t *ati18800 = malloc(sizeof(ati18800_t)); + memset(ati18800, 0, sizeof(ati18800_t)); - rom_init(&ati18800->bios_rom, "ATI EGA Wonder 800+ N1.00.BIN", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&ati18800->bios_rom, "ATI EGA Wonder 800+ N1.00.BIN", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - svga_init(&ati18800->svga, ati18800, 1 << 18, /*256kb*/ - ega_wonder_800_recalctimings, - ati18800_in, ati18800_out, - NULL, - NULL); + svga_init(&ati18800->svga, ati18800, 1 << 18, /*256kb*/ + ega_wonder_800_recalctimings, ati18800_in, ati18800_out, NULL, NULL); - io_sethandler(0x01ce, 0x0002, ati18800_in, NULL, NULL, ati18800_out, NULL, NULL, ati18800); - io_sethandler(0x03c0, 0x0006, ati18800_in, NULL, NULL, ati18800_out, NULL, NULL, ati18800); - io_sethandler(0x03ca, 0x0016, ati18800_in, NULL, NULL, ati18800_out, NULL, NULL, ati18800); + io_sethandler(0x01ce, 0x0002, ati18800_in, NULL, NULL, ati18800_out, NULL, NULL, ati18800); + io_sethandler(0x03c0, 0x0006, ati18800_in, NULL, NULL, ati18800_out, NULL, NULL, ati18800); + io_sethandler(0x03ca, 0x0016, ati18800_in, NULL, NULL, ati18800_out, NULL, NULL, ati18800); - ati18800->svga.miscout = 1; + ati18800->svga.miscout = 1; - for (c = 0; c < 256; c++) { - ati18800->svga.pallook[c] = makecol32(((c >> 2) & 1) * 0xaa, ((c >> 1) & 1) * 0xaa, (c & 1) * 0xaa); - ati18800->svga.pallook[c] += makecol32(((c >> 5) & 1) * 0x55, ((c >> 4) & 1) * 0x55, ((c >> 3) & 1) * 0x55); - } + for (c = 0; c < 256; c++) { + ati18800->svga.pallook[c] = makecol32(((c >> 2) & 1) * 0xaa, ((c >> 1) & 1) * 0xaa, (c & 1) * 0xaa); + ati18800->svga.pallook[c] += makecol32(((c >> 5) & 1) * 0x55, ((c >> 4) & 1) * 0x55, ((c >> 3) & 1) * 0x55); + } - ati_eeprom_load(&ati18800->eeprom, "egawonder800.nvr", 0); + ati_eeprom_load(&ati18800->eeprom, "egawonder800.nvr", 0); - ati18800->is_ega = 1; - ati18800->ega_switches = 9; + ati18800->is_ega = 1; + ati18800->ega_switches = 9; - return ati18800; + return ati18800; } -static int ati18800_available() { - return rom_present("vgaedge16.vbi"); -} +static int ati18800_available() { return rom_present("vgaedge16.vbi"); } -static int ega_wonder_800_available() { - return rom_present("ATI EGA Wonder 800+ N1.00.BIN"); -} +static int ega_wonder_800_available() { return rom_present("ATI EGA Wonder 800+ N1.00.BIN"); } void ati18800_close(void *p) { - ati18800_t *ati18800 = (ati18800_t *)p; + ati18800_t *ati18800 = (ati18800_t *)p; - svga_close(&ati18800->svga); + svga_close(&ati18800->svga); - free(ati18800); + free(ati18800); } void ati18800_speed_changed(void *p) { - ati18800_t *ati18800 = (ati18800_t *)p; + ati18800_t *ati18800 = (ati18800_t *)p; - svga_recalctimings(&ati18800->svga); + svga_recalctimings(&ati18800->svga); } void ati18800_force_redraw(void *p) { - ati18800_t *ati18800 = (ati18800_t *)p; + ati18800_t *ati18800 = (ati18800_t *)p; - ati18800->svga.fullchange = changeframecount; + ati18800->svga.fullchange = changeframecount; } void ati18800_add_status_info(char *s, int max_len, void *p) { - ati18800_t *ati18800 = (ati18800_t *)p; + ati18800_t *ati18800 = (ati18800_t *)p; - svga_add_status_info(s, max_len, &ati18800->svga); + svga_add_status_info(s, max_len, &ati18800->svga); } -device_t ati18800_device = - { - "ATI-18800", - 0, - ati18800_init, - ati18800_close, - ati18800_available, - ati18800_speed_changed, - ati18800_force_redraw, - ati18800_add_status_info - }; +device_t ati18800_device = {"ATI-18800", 0, + ati18800_init, ati18800_close, + ati18800_available, ati18800_speed_changed, + ati18800_force_redraw, ati18800_add_status_info}; -device_t ati_ega_wonder_800_device = - { - "ATI EGA Wonder 800+", - 0, - ega_wonder_800_init, - ati18800_close, - ega_wonder_800_available, - ati18800_speed_changed, - ati18800_force_redraw, - ati18800_add_status_info - }; +device_t ati_ega_wonder_800_device = {"ATI EGA Wonder 800+", 0, + ega_wonder_800_init, ati18800_close, + ega_wonder_800_available, ati18800_speed_changed, + ati18800_force_redraw, ati18800_add_status_info}; diff --git a/src/video/vid_ati28800.c b/src/video/vid_ati28800.c index 6fdfbe71..a39fab9a 100644 --- a/src/video/vid_ati28800.c +++ b/src/video/vid_ati28800.c @@ -12,502 +12,505 @@ #include "vid_svga_render.h" typedef struct ati28800_t { - svga_t svga; - ati_eeprom_t eeprom; + svga_t svga; + ati_eeprom_t eeprom; - rom_t bios_rom; + rom_t bios_rom; - uint8_t regs[256]; - int index; + uint8_t regs[256]; + int index; - uint8_t port_03dd_val; - uint16_t get_korean_font_kind; - int in_get_korean_font_kind_set; - int get_korean_font_enabled; - int get_korean_font_index; - uint16_t get_korean_font_base; - int ksc5601_mode_enabled; + uint8_t port_03dd_val; + uint16_t get_korean_font_kind; + int in_get_korean_font_kind_set; + int get_korean_font_enabled; + int get_korean_font_index; + uint16_t get_korean_font_base; + int ksc5601_mode_enabled; } ati28800_t; void ati28800_out(uint16_t addr, uint8_t val, void *p) { - ati28800_t *ati28800 = (ati28800_t *)p; - svga_t *svga = &ati28800->svga; - uint8_t old; + ati28800_t *ati28800 = (ati28800_t *)p; + svga_t *svga = &ati28800->svga; + uint8_t old; -// pclog("ati28800_out : %04X %02X %04X:%04X\n", addr, val, CS,pc); + // pclog("ati28800_out : %04X %02X %04X:%04X\n", addr, val, CS,pc); - if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1)) - addr ^= 0x60; + if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1)) + addr ^= 0x60; - switch (addr) { - case 0x1ce:ati28800->index = val; - break; - case 0x1cf:old = ati28800->regs[ati28800->index]; - ati28800->regs[ati28800->index] = val; - switch (ati28800->index) { - case 0xb2: - case 0xbe: - if (ati28800->regs[0xbe] & 8) /*Read/write bank mode*/ - { - svga->read_bank = ((ati28800->regs[0xb2] >> 5) & 7) * 0x10000; - svga->write_bank = ((ati28800->regs[0xb2] >> 1) & 7) * 0x10000; - } else /*Single bank mode*/ - svga->read_bank = svga->write_bank = ((ati28800->regs[0xb2] >> 1) & 7) * 0x10000; - if (ati28800->index == 0xbe && ((old ^ val) & 0x10)) - svga_recalctimings(svga); - break; - case 0xb3:ati_eeprom_write(&ati28800->eeprom, val & 8, val & 2, val & 1); - break; - case 0xb6: - if ((old ^ val) & 0x10) - svga_recalctimings(svga); - break; - case 0xb8: - if ((old ^ val) & 0x40) - svga_recalctimings(svga); - break; - case 0xb9: - if ((old ^ val) & 2) - svga_recalctimings(svga); - break; - } - break; + switch (addr) { + case 0x1ce: + ati28800->index = val; + break; + case 0x1cf: + old = ati28800->regs[ati28800->index]; + ati28800->regs[ati28800->index] = val; + switch (ati28800->index) { + case 0xb2: + case 0xbe: + if (ati28800->regs[0xbe] & 8) /*Read/write bank mode*/ + { + svga->read_bank = ((ati28800->regs[0xb2] >> 5) & 7) * 0x10000; + svga->write_bank = ((ati28800->regs[0xb2] >> 1) & 7) * 0x10000; + } else /*Single bank mode*/ + svga->read_bank = svga->write_bank = ((ati28800->regs[0xb2] >> 1) & 7) * 0x10000; + if (ati28800->index == 0xbe && ((old ^ val) & 0x10)) + svga_recalctimings(svga); + break; + case 0xb3: + ati_eeprom_write(&ati28800->eeprom, val & 8, val & 2, val & 1); + break; + case 0xb6: + if ((old ^ val) & 0x10) + svga_recalctimings(svga); + break; + case 0xb8: + if ((old ^ val) & 0x40) + svga_recalctimings(svga); + break; + case 0xb9: + if ((old ^ val) & 2) + svga_recalctimings(svga); + break; + } + break; - case 0x3D4:svga->crtcreg = val & 0x3f; - return; - case 0x3D5: - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) - return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); - old = svga->crtc[svga->crtcreg]; - svga->crtc[svga->crtcreg] = val; - if (old != val) { - if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - } - break; - } - svga_out(addr, val, svga); + case 0x3D4: + svga->crtcreg = val & 0x3f; + return; + case 0x3D5: + if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) + return; + if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) + val = (svga->crtc[7] & ~0x10) | (val & 0x10); + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; + if (old != val) { + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } + } + break; + } + svga_out(addr, val, svga); } void ati28800k_out(uint16_t addr, uint8_t val, void *p) { - ati28800_t *ati28800 = (ati28800_t *)p; - svga_t *svga = &ati28800->svga; - uint16_t oldaddr = addr; + ati28800_t *ati28800 = (ati28800_t *)p; + svga_t *svga = &ati28800->svga; + uint16_t oldaddr = addr; - if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1)) - addr ^= 0x60; + if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1)) + addr ^= 0x60; - switch (addr) { - case 0x1CF: - if (ati28800->index == 0xBF && ((ati28800->regs[0xBF] ^ val) & 0x20)) { - ati28800->ksc5601_mode_enabled = val & 0x20; -// pclog("Switching mode to %s at %04X:%04X\n", ksc5601_mode_enabled ? "DBCS" : "SBCS", CS, cpu_state.oldpc); - svga_recalctimings(svga); - } - ati28800_out(oldaddr, val, p); - break; - case 0x3DD: -// pclog("ati28800k_out : set port 03DD to %02X at %04X:%04X\n", val, CS, cpu_state.oldpc); - ati28800->port_03dd_val = val; - if (val == 1) - ati28800->get_korean_font_enabled = 0; - if (ati28800->in_get_korean_font_kind_set) { - ati28800->get_korean_font_kind = (val << 8) | (ati28800->get_korean_font_kind & 0xFF); - ati28800->get_korean_font_enabled = 1; - ati28800->get_korean_font_index = 0; - ati28800->in_get_korean_font_kind_set = 0; - } - break; - case 0x3DE: -// pclog("ati28800k_out : set port 03DE to %02X at %04X:%04X\n", val, CS, cpu_state.oldpc); - ati28800->in_get_korean_font_kind_set = 0; - if (ati28800->get_korean_font_enabled) { - if ((ati28800->get_korean_font_base & 0x7F) > 0x20 && (ati28800->get_korean_font_base & 0x7F) < 0x7F) - fontdatksc5601_user[(ati28800->get_korean_font_kind & 4) * 24 + (ati28800->get_korean_font_base & 0x7F) - 0x20][ati28800->get_korean_font_index] = val; - ati28800->get_korean_font_index++; - ati28800->get_korean_font_index &= 0x1F; - } else { - switch (ati28800->port_03dd_val) { - case 0x10:ati28800->get_korean_font_base = ((val & 0x7F) << 7) | (ati28800->get_korean_font_base & 0x7F); - break; - case 8:ati28800->get_korean_font_base = (ati28800->get_korean_font_base & 0x3F80) | (val & 0x7F); - break; - case 1:ati28800->get_korean_font_kind = (ati28800->get_korean_font_kind & 0xFF00) | val; - if (val & 2) - ati28800->in_get_korean_font_kind_set = 1; - break; - default:break; - } - } - break; - default:ati28800_out(oldaddr, val, p); - break; - } + switch (addr) { + case 0x1CF: + if (ati28800->index == 0xBF && ((ati28800->regs[0xBF] ^ val) & 0x20)) { + ati28800->ksc5601_mode_enabled = val & 0x20; + // pclog("Switching mode to %s at %04X:%04X\n", ksc5601_mode_enabled ? "DBCS" : + // "SBCS", CS, cpu_state.oldpc); + svga_recalctimings(svga); + } + ati28800_out(oldaddr, val, p); + break; + case 0x3DD: + // pclog("ati28800k_out : set port 03DD to %02X at %04X:%04X\n", val, CS, cpu_state.oldpc); + ati28800->port_03dd_val = val; + if (val == 1) + ati28800->get_korean_font_enabled = 0; + if (ati28800->in_get_korean_font_kind_set) { + ati28800->get_korean_font_kind = (val << 8) | (ati28800->get_korean_font_kind & 0xFF); + ati28800->get_korean_font_enabled = 1; + ati28800->get_korean_font_index = 0; + ati28800->in_get_korean_font_kind_set = 0; + } + break; + case 0x3DE: + // pclog("ati28800k_out : set port 03DE to %02X at %04X:%04X\n", val, CS, cpu_state.oldpc); + ati28800->in_get_korean_font_kind_set = 0; + if (ati28800->get_korean_font_enabled) { + if ((ati28800->get_korean_font_base & 0x7F) > 0x20 && (ati28800->get_korean_font_base & 0x7F) < 0x7F) + fontdatksc5601_user[(ati28800->get_korean_font_kind & 4) * 24 + + (ati28800->get_korean_font_base & 0x7F) - + 0x20][ati28800->get_korean_font_index] = val; + ati28800->get_korean_font_index++; + ati28800->get_korean_font_index &= 0x1F; + } else { + switch (ati28800->port_03dd_val) { + case 0x10: + ati28800->get_korean_font_base = ((val & 0x7F) << 7) | (ati28800->get_korean_font_base & 0x7F); + break; + case 8: + ati28800->get_korean_font_base = (ati28800->get_korean_font_base & 0x3F80) | (val & 0x7F); + break; + case 1: + ati28800->get_korean_font_kind = (ati28800->get_korean_font_kind & 0xFF00) | val; + if (val & 2) + ati28800->in_get_korean_font_kind_set = 1; + break; + default: + break; + } + } + break; + default: + ati28800_out(oldaddr, val, p); + break; + } } uint8_t ati28800_in(uint16_t addr, void *p) { - ati28800_t *ati28800 = (ati28800_t *)p; - svga_t *svga = &ati28800->svga; - uint8_t temp; + ati28800_t *ati28800 = (ati28800_t *)p; + svga_t *svga = &ati28800->svga; + uint8_t temp; -// if (addr != 0x3da) pclog("ati28800_in : %04X ", addr); + // if (addr != 0x3da) pclog("ati28800_in : %04X ", addr); - if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1)) - addr ^= 0x60; + if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1)) + addr ^= 0x60; - switch (addr) { - case 0x1ce:temp = ati28800->index; - break; - case 0x1cf: - switch (ati28800->index) { - case 0xb7:temp = ati28800->regs[ati28800->index] & ~8; - if (ati_eeprom_read(&ati28800->eeprom)) - temp |= 8; - break; + switch (addr) { + case 0x1ce: + temp = ati28800->index; + break; + case 0x1cf: + switch (ati28800->index) { + case 0xb7: + temp = ati28800->regs[ati28800->index] & ~8; + if (ati_eeprom_read(&ati28800->eeprom)) + temp |= 8; + break; - default:temp = ati28800->regs[ati28800->index]; - break; - } - break; + default: + temp = ati28800->regs[ati28800->index]; + break; + } + break; - case 0x3c2: - if ((svga->vgapal[0].r + svga->vgapal[0].g + svga->vgapal[0].b) >= 0x50) - temp = 0; - else - temp = 0x10; - break; - case 0x3D4:temp = svga->crtcreg; - break; - case 0x3D5:temp = svga->crtc[svga->crtcreg]; - break; - default:temp = svga_in(addr, svga); - break; - } -// if (addr != 0x3da) pclog("%02X %04X:%04X\n", temp, CS,cpu_state.pc); - return temp; + case 0x3c2: + if ((svga->vgapal[0].r + svga->vgapal[0].g + svga->vgapal[0].b) >= 0x50) + temp = 0; + else + temp = 0x10; + break; + case 0x3D4: + temp = svga->crtcreg; + break; + case 0x3D5: + temp = svga->crtc[svga->crtcreg]; + break; + default: + temp = svga_in(addr, svga); + break; + } + // if (addr != 0x3da) pclog("%02X %04X:%04X\n", temp, CS,cpu_state.pc); + return temp; } uint8_t ati28800k_in(uint16_t addr, void *p) { - ati28800_t *ati28800 = (ati28800_t *)p; - svga_t *svga = &ati28800->svga; - uint16_t oldaddr = addr; - uint8_t temp = 0xFF; + ati28800_t *ati28800 = (ati28800_t *)p; + svga_t *svga = &ati28800->svga; + uint16_t oldaddr = addr; + uint8_t temp = 0xFF; -// if (addr != 0x3da) pclog("ati28800_in : %04X ", addr); + // if (addr != 0x3da) pclog("ati28800_in : %04X ", addr); - if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1)) - addr ^= 0x60; + if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1)) + addr ^= 0x60; - switch (addr) { - case 0x3DE: - if (ati28800->get_korean_font_enabled) { - switch (ati28800->get_korean_font_kind >> 8) { - case 4: /* ROM font */ - temp = fontdatksc5601[ati28800->get_korean_font_base][ati28800->get_korean_font_index++]; - break; - case 2: /* User defined font */ - if ((ati28800->get_korean_font_base & 0x7F) > 0x20 && (ati28800->get_korean_font_base & 0x7F) < 0x7F) - temp = fontdatksc5601_user[(ati28800->get_korean_font_kind & 4) * 24 + (ati28800->get_korean_font_base & 0x7F) - 0x20][ati28800->get_korean_font_index]; - else - temp = 0xFF; - ati28800->get_korean_font_index++; - break; - default:break; - } - ati28800->get_korean_font_index &= 0x1F; - } - break; - default:temp = ati28800_in(oldaddr, p); - break; - } -// if (addr != 0x3da) pclog("%02X %04X:%04X\n", temp, CS,cpu_state.pc); - return temp; + switch (addr) { + case 0x3DE: + if (ati28800->get_korean_font_enabled) { + switch (ati28800->get_korean_font_kind >> 8) { + case 4: /* ROM font */ + temp = fontdatksc5601[ati28800->get_korean_font_base][ati28800->get_korean_font_index++]; + break; + case 2: /* User defined font */ + if ((ati28800->get_korean_font_base & 0x7F) > 0x20 && + (ati28800->get_korean_font_base & 0x7F) < 0x7F) + temp = fontdatksc5601_user[(ati28800->get_korean_font_kind & 4) * 24 + + (ati28800->get_korean_font_base & 0x7F) - + 0x20][ati28800->get_korean_font_index]; + else + temp = 0xFF; + ati28800->get_korean_font_index++; + break; + default: + break; + } + ati28800->get_korean_font_index &= 0x1F; + } + break; + default: + temp = ati28800_in(oldaddr, p); + break; + } + // if (addr != 0x3da) pclog("%02X %04X:%04X\n", temp, CS,cpu_state.pc); + return temp; } void ati28800_recalctimings(svga_t *svga) { - ati28800_t *ati28800 = (ati28800_t *)svga->p; - //pclog("ati28800_recalctimings\n"); + ati28800_t *ati28800 = (ati28800_t *)svga->p; + // pclog("ati28800_recalctimings\n"); - switch (((ati28800->regs[0xbe] & 0x10) >> 1) | ((ati28800->regs[0xb9] & 2) << 1) | ((svga->miscout & 0x0C) >> 2)) { - case 0x00:svga->clock = (cpuclock * (double)(1ull << 32)) / 42954000.0; - break; - case 0x01:svga->clock = (cpuclock * (double)(1ull << 32)) / 48771000.0; - break; - case 0x03:svga->clock = (cpuclock * (double)(1ull << 32)) / 36000000.0; - break; - case 0x04:svga->clock = (cpuclock * (double)(1ull << 32)) / 50350000.0; - break; - case 0x05:svga->clock = (cpuclock * (double)(1ull << 32)) / 56640000.0; - break; - case 0x07:svga->clock = (cpuclock * (double)(1ull << 32)) / 44900000.0; - break; - case 0x08:svga->clock = (cpuclock * (double)(1ull << 32)) / 30240000.0; - break; - case 0x09:svga->clock = (cpuclock * (double)(1ull << 32)) / 32000000.0; - break; - case 0x0A:svga->clock = (cpuclock * (double)(1ull << 32)) / 37500000.0; - break; - case 0x0B:svga->clock = (cpuclock * (double)(1ull << 32)) / 39000000.0; - break; - case 0x0C:svga->clock = (cpuclock * (double)(1ull << 32)) / 50350000.0; - break; - case 0x0D:svga->clock = (cpuclock * (double)(1ull << 32)) / 56644000.0; - break; - case 0x0E:svga->clock = (cpuclock * (double)(1ull << 32)) / 75000000.0; - break; - case 0x0F:svga->clock = (cpuclock * (double)(1ull << 32)) / 65000000.0; - break; - default:break; - } - if (ati28800->regs[0xb8] & 0x40) - svga->clock *= 2; - if (ati28800->regs[0xb6] & 0x10) { - svga->hdisp <<= 1; - svga->htotal <<= 1; - svga->rowoffset <<= 1; - } + switch (((ati28800->regs[0xbe] & 0x10) >> 1) | ((ati28800->regs[0xb9] & 2) << 1) | ((svga->miscout & 0x0C) >> 2)) { + case 0x00: + svga->clock = (cpuclock * (double)(1ull << 32)) / 42954000.0; + break; + case 0x01: + svga->clock = (cpuclock * (double)(1ull << 32)) / 48771000.0; + break; + case 0x03: + svga->clock = (cpuclock * (double)(1ull << 32)) / 36000000.0; + break; + case 0x04: + svga->clock = (cpuclock * (double)(1ull << 32)) / 50350000.0; + break; + case 0x05: + svga->clock = (cpuclock * (double)(1ull << 32)) / 56640000.0; + break; + case 0x07: + svga->clock = (cpuclock * (double)(1ull << 32)) / 44900000.0; + break; + case 0x08: + svga->clock = (cpuclock * (double)(1ull << 32)) / 30240000.0; + break; + case 0x09: + svga->clock = (cpuclock * (double)(1ull << 32)) / 32000000.0; + break; + case 0x0A: + svga->clock = (cpuclock * (double)(1ull << 32)) / 37500000.0; + break; + case 0x0B: + svga->clock = (cpuclock * (double)(1ull << 32)) / 39000000.0; + break; + case 0x0C: + svga->clock = (cpuclock * (double)(1ull << 32)) / 50350000.0; + break; + case 0x0D: + svga->clock = (cpuclock * (double)(1ull << 32)) / 56644000.0; + break; + case 0x0E: + svga->clock = (cpuclock * (double)(1ull << 32)) / 75000000.0; + break; + case 0x0F: + svga->clock = (cpuclock * (double)(1ull << 32)) / 65000000.0; + break; + default: + break; + } + if (ati28800->regs[0xb8] & 0x40) + svga->clock *= 2; + if (ati28800->regs[0xb6] & 0x10) { + svga->hdisp <<= 1; + svga->htotal <<= 1; + svga->rowoffset <<= 1; + } - if (!svga->scrblank && (ati28800->regs[0xb0] & 0x20)) /*Extended 256 colour modes*/ - { - //pclog("8bpp_highres\n"); - svga->render = svga_render_8bpp_highres; - svga->rowoffset <<= 1; - svga->ma <<= 1; - } + if (!svga->scrblank && (ati28800->regs[0xb0] & 0x20)) /*Extended 256 colour modes*/ + { + // pclog("8bpp_highres\n"); + svga->render = svga_render_8bpp_highres; + svga->rowoffset <<= 1; + svga->ma <<= 1; + } } void ati28800k_recalctimings(svga_t *svga) { - ati28800_t *ati28800 = (ati28800_t *)svga->p; + ati28800_t *ati28800 = (ati28800_t *)svga->p; - ati28800_recalctimings(svga); + ati28800_recalctimings(svga); - if (svga->render == svga_render_text_80 && ati28800->ksc5601_mode_enabled) { - svga->render = svga_render_text_80_ksc5601; - } + if (svga->render == svga_render_text_80 && ati28800->ksc5601_mode_enabled) { + svga->render = svga_render_text_80_ksc5601; + } } void *ati28800_init() { - ati28800_t *ati28800 = malloc(sizeof(ati28800_t)); - memset(ati28800, 0, sizeof(ati28800_t)); + ati28800_t *ati28800 = malloc(sizeof(ati28800_t)); + memset(ati28800, 0, sizeof(ati28800_t)); - rom_init(&ati28800->bios_rom, "bios.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&ati28800->bios_rom, "bios.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - svga_init(&ati28800->svga, ati28800, 1 << 19, /*512kb*/ - ati28800_recalctimings, - ati28800_in, ati28800_out, - NULL, - NULL); + svga_init(&ati28800->svga, ati28800, 1 << 19, /*512kb*/ + ati28800_recalctimings, ati28800_in, ati28800_out, NULL, NULL); - io_sethandler(0x01ce, 0x0002, ati28800_in, NULL, NULL, ati28800_out, NULL, NULL, ati28800); - io_sethandler(0x03c0, 0x0020, ati28800_in, NULL, NULL, ati28800_out, NULL, NULL, ati28800); + io_sethandler(0x01ce, 0x0002, ati28800_in, NULL, NULL, ati28800_out, NULL, NULL, ati28800); + io_sethandler(0x03c0, 0x0020, ati28800_in, NULL, NULL, ati28800_out, NULL, NULL, ati28800); - ati28800->svga.miscout = 1; + ati28800->svga.miscout = 1; - ati_eeprom_load(&ati28800->eeprom, "ati28800.nvr", 0); + ati_eeprom_load(&ati28800->eeprom, "ati28800.nvr", 0); - return ati28800; + return ati28800; } void *ati28800k_init() { - ati28800_t *ati28800 = malloc(sizeof(ati28800_t)); - memset(ati28800, 0, sizeof(ati28800_t)); + ati28800_t *ati28800 = malloc(sizeof(ati28800_t)); + memset(ati28800, 0, sizeof(ati28800_t)); - ati28800->port_03dd_val = 0; - ati28800->get_korean_font_base = 0; - ati28800->get_korean_font_index = 0; - ati28800->get_korean_font_enabled = 0; - ati28800->get_korean_font_kind = 0; - ati28800->in_get_korean_font_kind_set = 0; - ati28800->ksc5601_mode_enabled = 0; + ati28800->port_03dd_val = 0; + ati28800->get_korean_font_base = 0; + ati28800->get_korean_font_index = 0; + ati28800->get_korean_font_enabled = 0; + ati28800->get_korean_font_kind = 0; + ati28800->in_get_korean_font_kind_set = 0; + ati28800->ksc5601_mode_enabled = 0; - rom_init(&ati28800->bios_rom, "atikorvga.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - loadfont("ati_ksc5601.rom", FONT_KSC5601); + rom_init(&ati28800->bios_rom, "atikorvga.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + loadfont("ati_ksc5601.rom", FONT_KSC5601); - svga_init(&ati28800->svga, ati28800, 1 << 19, /*512kb*/ - ati28800k_recalctimings, - ati28800k_in, ati28800k_out, - NULL, - NULL); + svga_init(&ati28800->svga, ati28800, 1 << 19, /*512kb*/ + ati28800k_recalctimings, ati28800k_in, ati28800k_out, NULL, NULL); - io_sethandler(0x01ce, 0x0002, ati28800k_in, NULL, NULL, ati28800k_out, NULL, NULL, ati28800); - io_sethandler(0x03c0, 0x0020, ati28800k_in, NULL, NULL, ati28800k_out, NULL, NULL, ati28800); + io_sethandler(0x01ce, 0x0002, ati28800k_in, NULL, NULL, ati28800k_out, NULL, NULL, ati28800); + io_sethandler(0x03c0, 0x0020, ati28800k_in, NULL, NULL, ati28800k_out, NULL, NULL, ati28800); - ati28800->svga.miscout = 1; - ati28800->svga.ksc5601_sbyte_mask = 0; - ati28800->svga.ksc5601_udc_area_msb[0] = 0xC9; - ati28800->svga.ksc5601_udc_area_msb[1] = 0xFE; - ati28800->svga.ksc5601_swap_mode = 0; - ati28800->svga.ksc5601_english_font_type = 0; + ati28800->svga.miscout = 1; + ati28800->svga.ksc5601_sbyte_mask = 0; + ati28800->svga.ksc5601_udc_area_msb[0] = 0xC9; + ati28800->svga.ksc5601_udc_area_msb[1] = 0xFE; + ati28800->svga.ksc5601_swap_mode = 0; + ati28800->svga.ksc5601_english_font_type = 0; - ati_eeprom_load(&ati28800->eeprom, "atikorvga.nvr", 0); + ati_eeprom_load(&ati28800->eeprom, "atikorvga.nvr", 0); - return ati28800; + return ati28800; } void *ati28800k_spc4620p_init() { - ati28800_t *ati28800 = malloc(sizeof(ati28800_t)); - memset(ati28800, 0, sizeof(ati28800_t)); + ati28800_t *ati28800 = malloc(sizeof(ati28800_t)); + memset(ati28800, 0, sizeof(ati28800_t)); - ati28800->port_03dd_val = 0; - ati28800->get_korean_font_base = 0; - ati28800->get_korean_font_index = 0; - ati28800->get_korean_font_enabled = 0; - ati28800->get_korean_font_kind = 0; - ati28800->in_get_korean_font_kind_set = 0; - ati28800->ksc5601_mode_enabled = 0; + ati28800->port_03dd_val = 0; + ati28800->get_korean_font_base = 0; + ati28800->get_korean_font_index = 0; + ati28800->get_korean_font_enabled = 0; + ati28800->get_korean_font_kind = 0; + ati28800->in_get_korean_font_kind_set = 0; + ati28800->ksc5601_mode_enabled = 0; - rom_init_interleaved(&ati28800->bios_rom, "spc4620p/31005h.u8", "spc4620p/31005h.u10", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - loadfont("spc4620p/svb6120a_font.rom", 6); + rom_init_interleaved(&ati28800->bios_rom, "spc4620p/31005h.u8", "spc4620p/31005h.u10", 0xc0000, 0x8000, 0x7fff, 0, + MEM_MAPPING_EXTERNAL); + loadfont("spc4620p/svb6120a_font.rom", 6); - svga_init(&ati28800->svga, ati28800, 1 << 19, /*512kb*/ - ati28800k_recalctimings, - ati28800k_in, ati28800k_out, - NULL, - NULL); + svga_init(&ati28800->svga, ati28800, 1 << 19, /*512kb*/ + ati28800k_recalctimings, ati28800k_in, ati28800k_out, NULL, NULL); - io_sethandler(0x01ce, 0x0002, ati28800k_in, NULL, NULL, ati28800k_out, NULL, NULL, ati28800); - io_sethandler(0x03c0, 0x0020, ati28800k_in, NULL, NULL, ati28800k_out, NULL, NULL, ati28800); + io_sethandler(0x01ce, 0x0002, ati28800k_in, NULL, NULL, ati28800k_out, NULL, NULL, ati28800); + io_sethandler(0x03c0, 0x0020, ati28800k_in, NULL, NULL, ati28800k_out, NULL, NULL, ati28800); - ati28800->svga.miscout = 1; - ati28800->svga.ksc5601_sbyte_mask = 0; - ati28800->svga.ksc5601_udc_area_msb[0] = 0xC9; - ati28800->svga.ksc5601_udc_area_msb[1] = 0xFE; - ati28800->svga.ksc5601_swap_mode = 0; - ati28800->svga.ksc5601_english_font_type = 0; + ati28800->svga.miscout = 1; + ati28800->svga.ksc5601_sbyte_mask = 0; + ati28800->svga.ksc5601_udc_area_msb[0] = 0xC9; + ati28800->svga.ksc5601_udc_area_msb[1] = 0xFE; + ati28800->svga.ksc5601_swap_mode = 0; + ati28800->svga.ksc5601_english_font_type = 0; - ati_eeprom_load(&ati28800->eeprom, "svb6120a.nvr", 0); + ati_eeprom_load(&ati28800->eeprom, "svb6120a.nvr", 0); - return ati28800; + return ati28800; } void *ati28800k_spc6033p_init() { - ati28800_t *ati28800 = malloc(sizeof(ati28800_t)); - memset(ati28800, 0, sizeof(ati28800_t)); + ati28800_t *ati28800 = malloc(sizeof(ati28800_t)); + memset(ati28800, 0, sizeof(ati28800_t)); - ati28800->port_03dd_val = 0; - ati28800->get_korean_font_base = 0; - ati28800->get_korean_font_index = 0; - ati28800->get_korean_font_enabled = 0; - ati28800->get_korean_font_kind = 0; - ati28800->in_get_korean_font_kind_set = 0; - ati28800->ksc5601_mode_enabled = 0; + ati28800->port_03dd_val = 0; + ati28800->get_korean_font_base = 0; + ati28800->get_korean_font_index = 0; + ati28800->get_korean_font_enabled = 0; + ati28800->get_korean_font_kind = 0; + ati28800->in_get_korean_font_kind_set = 0; + ati28800->ksc5601_mode_enabled = 0; - rom_init(&ati28800->bios_rom, "spc6033p/phoenix.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - loadfont("spc6033p/svb6120a_font.rom", 6); + rom_init(&ati28800->bios_rom, "spc6033p/phoenix.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + loadfont("spc6033p/svb6120a_font.rom", 6); - svga_init(&ati28800->svga, ati28800, 1 << 19, /*512kb*/ - ati28800k_recalctimings, - ati28800k_in, ati28800k_out, - NULL, - NULL); + svga_init(&ati28800->svga, ati28800, 1 << 19, /*512kb*/ + ati28800k_recalctimings, ati28800k_in, ati28800k_out, NULL, NULL); - io_sethandler(0x01ce, 0x0002, ati28800k_in, NULL, NULL, ati28800k_out, NULL, NULL, ati28800); - io_sethandler(0x03c0, 0x0020, ati28800k_in, NULL, NULL, ati28800k_out, NULL, NULL, ati28800); + io_sethandler(0x01ce, 0x0002, ati28800k_in, NULL, NULL, ati28800k_out, NULL, NULL, ati28800); + io_sethandler(0x03c0, 0x0020, ati28800k_in, NULL, NULL, ati28800k_out, NULL, NULL, ati28800); - ati28800->svga.miscout = 1; - ati28800->svga.ksc5601_sbyte_mask = 0; - ati28800->svga.ksc5601_udc_area_msb[0] = 0xC9; - ati28800->svga.ksc5601_udc_area_msb[1] = 0xFE; - ati28800->svga.ksc5601_swap_mode = 0; - ati28800->svga.ksc5601_english_font_type = 0; + ati28800->svga.miscout = 1; + ati28800->svga.ksc5601_sbyte_mask = 0; + ati28800->svga.ksc5601_udc_area_msb[0] = 0xC9; + ati28800->svga.ksc5601_udc_area_msb[1] = 0xFE; + ati28800->svga.ksc5601_swap_mode = 0; + ati28800->svga.ksc5601_english_font_type = 0; - ati_eeprom_load(&ati28800->eeprom, "svb6120a_spc6033p.nvr", 0); + ati_eeprom_load(&ati28800->eeprom, "svb6120a_spc6033p.nvr", 0); - return ati28800; + return ati28800; } -static int ati28800_available() { - return rom_present("bios.bin"); -} +static int ati28800_available() { return rom_present("bios.bin"); } -static int ati28800k_available() { - return rom_present("atikorvga.bin") && rom_present("ati_ksc5601.rom"); -} +static int ati28800k_available() { return rom_present("atikorvga.bin") && rom_present("ati_ksc5601.rom"); } void ati28800_close(void *p) { - ati28800_t *ati28800 = (ati28800_t *)p; + ati28800_t *ati28800 = (ati28800_t *)p; - svga_close(&ati28800->svga); + svga_close(&ati28800->svga); - free(ati28800); + free(ati28800); } void ati28800_speed_changed(void *p) { - ati28800_t *ati28800 = (ati28800_t *)p; + ati28800_t *ati28800 = (ati28800_t *)p; - svga_recalctimings(&ati28800->svga); + svga_recalctimings(&ati28800->svga); } void ati28800_force_redraw(void *p) { - ati28800_t *ati28800 = (ati28800_t *)p; + ati28800_t *ati28800 = (ati28800_t *)p; - ati28800->svga.fullchange = changeframecount; + ati28800->svga.fullchange = changeframecount; } void ati28800_add_status_info(char *s, int max_len, void *p) { - ati28800_t *ati28800 = (ati28800_t *)p; + ati28800_t *ati28800 = (ati28800_t *)p; - svga_add_status_info(s, max_len, &ati28800->svga); + svga_add_status_info(s, max_len, &ati28800->svga); } void ati28800k_add_status_info(char *s, int max_len, void *p) { - ati28800_t *ati28800 = (ati28800_t *)p; - char temps[128]; + ati28800_t *ati28800 = (ati28800_t *)p; + char temps[128]; - ati28800_add_status_info(s, max_len, p); + ati28800_add_status_info(s, max_len, p); - sprintf(temps, "Korean SVGA mode enabled : %s\n\n", ati28800->ksc5601_mode_enabled ? "Yes" : "No"); - strncat(s, temps, max_len); + sprintf(temps, "Korean SVGA mode enabled : %s\n\n", ati28800->ksc5601_mode_enabled ? "Yes" : "No"); + strncat(s, temps, max_len); } -device_t ati28800_device = - { - "ATI-28800", - 0, - ati28800_init, - ati28800_close, - ati28800_available, - ati28800_speed_changed, - ati28800_force_redraw, - ati28800_add_status_info - }; +device_t ati28800_device = {"ATI-28800", 0, + ati28800_init, ati28800_close, + ati28800_available, ati28800_speed_changed, + ati28800_force_redraw, ati28800_add_status_info}; -device_t ati28800k_device = - { - "ATI Korean VGA", - 0, - ati28800k_init, - ati28800_close, - ati28800k_available, - ati28800_speed_changed, - ati28800_force_redraw, - ati28800k_add_status_info - }; +device_t ati28800k_device = {"ATI Korean VGA", 0, + ati28800k_init, ati28800_close, + ati28800k_available, ati28800_speed_changed, + ati28800_force_redraw, ati28800k_add_status_info}; -device_t ati28800k_spc4620p_device = - { - "SVB-6120A", - 0, - ati28800k_spc4620p_init, - ati28800_close, - NULL, - ati28800_speed_changed, - ati28800_force_redraw, - ati28800k_add_status_info - }; +device_t ati28800k_spc4620p_device = {"SVB-6120A", + 0, + ati28800k_spc4620p_init, + ati28800_close, + NULL, + ati28800_speed_changed, + ati28800_force_redraw, + ati28800k_add_status_info}; -device_t ati28800k_spc6033p_device = - { - "SVB-6120A", - 0, - ati28800k_spc6033p_init, - ati28800_close, - NULL, - ati28800_speed_changed, - ati28800_force_redraw, - ati28800k_add_status_info - }; +device_t ati28800k_spc6033p_device = {"SVB-6120A", + 0, + ati28800k_spc6033p_init, + ati28800_close, + NULL, + ati28800_speed_changed, + ati28800_force_redraw, + ati28800k_add_status_info}; diff --git a/src/video/vid_ati68860_ramdac.c b/src/video/vid_ati68860_ramdac.c index a4ace2ac..5696dcea 100644 --- a/src/video/vid_ati68860_ramdac.c +++ b/src/video/vid_ati68860_ramdac.c @@ -26,121 +26,150 @@ bit 0 Controls 6/8bit DAC. 0: 8bit DAC/LUT, 1: 6bit DAC/LUT #include "vid_svga_render.h" void ati68860_ramdac_out(uint16_t addr, uint8_t val, ati68860_ramdac_t *ramdac, svga_t *svga) { -// pclog("ati68860_out : addr %04X val %02X %04X:%04X\n", addr, val, CS,pc); - switch (addr) { - case 0:svga_out(0x3c8, val, svga); - break; - case 1:svga_out(0x3c9, val, svga); - break; - case 2:svga_out(0x3c6, val, svga); - break; - case 3:svga_out(0x3c7, val, svga); - break; - default:ramdac->regs[addr & 0xf] = val; - switch (addr & 0xf) { - case 0x4:ramdac->dac_write = val; - ramdac->dac_pos = 0; - break; - case 0x5: - switch (ramdac->dac_pos) { - case 0:ramdac->dac_r = val; - ramdac->dac_pos++; - break; - case 1:ramdac->dac_g = val; - ramdac->dac_pos++; - break; - case 2: - if (ramdac->dac_write > 1) - break; - ramdac->pal[ramdac->dac_write].r = ramdac->dac_r; - ramdac->pal[ramdac->dac_write].g = ramdac->dac_g; - ramdac->pal[ramdac->dac_write].b = val; - if (ramdac->ramdac_type == RAMDAC_8BIT) - ramdac->pallook[ramdac->dac_write] = makecol32(ramdac->pal[ramdac->dac_write].r, ramdac->pal[ramdac->dac_write].g, ramdac->pal[ramdac->dac_write].b); - else - ramdac->pallook[ramdac->dac_write] = makecol32( - (ramdac->pal[ramdac->dac_write].r & 0x3f) * 4, (ramdac->pal[ramdac->dac_write].g & 0x3f) * 4, (ramdac->pal[ramdac->dac_write].b & 0x3f) * 4); - ramdac->dac_pos = 0; - ramdac->dac_write = (ramdac->dac_write + 1) & 255; - break; - } - break; + // pclog("ati68860_out : addr %04X val %02X %04X:%04X\n", addr, val, CS,pc); + switch (addr) { + case 0: + svga_out(0x3c8, val, svga); + break; + case 1: + svga_out(0x3c9, val, svga); + break; + case 2: + svga_out(0x3c6, val, svga); + break; + case 3: + svga_out(0x3c7, val, svga); + break; + default: + ramdac->regs[addr & 0xf] = val; + switch (addr & 0xf) { + case 0x4: + ramdac->dac_write = val; + ramdac->dac_pos = 0; + break; + case 0x5: + switch (ramdac->dac_pos) { + case 0: + ramdac->dac_r = val; + ramdac->dac_pos++; + break; + case 1: + ramdac->dac_g = val; + ramdac->dac_pos++; + break; + case 2: + if (ramdac->dac_write > 1) + break; + ramdac->pal[ramdac->dac_write].r = ramdac->dac_r; + ramdac->pal[ramdac->dac_write].g = ramdac->dac_g; + ramdac->pal[ramdac->dac_write].b = val; + if (ramdac->ramdac_type == RAMDAC_8BIT) + ramdac->pallook[ramdac->dac_write] = + makecol32(ramdac->pal[ramdac->dac_write].r, ramdac->pal[ramdac->dac_write].g, + ramdac->pal[ramdac->dac_write].b); + else + ramdac->pallook[ramdac->dac_write] = + makecol32((ramdac->pal[ramdac->dac_write].r & 0x3f) * 4, + (ramdac->pal[ramdac->dac_write].g & 0x3f) * 4, + (ramdac->pal[ramdac->dac_write].b & 0x3f) * 4); + ramdac->dac_pos = 0; + ramdac->dac_write = (ramdac->dac_write + 1) & 255; + break; + } + break; - case 0xb: - switch (val) { - case 0x82:ramdac->render = svga_render_4bpp_highres; - break; - case 0x83:ramdac->render = svga_render_8bpp_highres; - break; - case 0xa0: - case 0xb0:ramdac->render = svga_render_15bpp_highres; - break; - case 0xa1: - case 0xb1:ramdac->render = svga_render_16bpp_highres; - break; - case 0xc0: - case 0xd0:ramdac->render = svga_render_24bpp_highres; - break; - case 0xe2: - case 0xf7:ramdac->render = svga_render_32bpp_highres; - break; - case 0xe3:ramdac->render = svga_render_ABGR8888_highres; - break; - case 0xf2:ramdac->render = svga_render_RGBA8888_highres; - break; - default:ramdac->render = svga_render_8bpp_highres; - break; - } - break; - case 0xc:svga_set_ramdac_type(svga, (val & 1) ? RAMDAC_6BIT : RAMDAC_8BIT); - break; - } - break; - } + case 0xb: + switch (val) { + case 0x82: + ramdac->render = svga_render_4bpp_highres; + break; + case 0x83: + ramdac->render = svga_render_8bpp_highres; + break; + case 0xa0: + case 0xb0: + ramdac->render = svga_render_15bpp_highres; + break; + case 0xa1: + case 0xb1: + ramdac->render = svga_render_16bpp_highres; + break; + case 0xc0: + case 0xd0: + ramdac->render = svga_render_24bpp_highres; + break; + case 0xe2: + case 0xf7: + ramdac->render = svga_render_32bpp_highres; + break; + case 0xe3: + ramdac->render = svga_render_ABGR8888_highres; + break; + case 0xf2: + ramdac->render = svga_render_RGBA8888_highres; + break; + default: + ramdac->render = svga_render_8bpp_highres; + break; + } + break; + case 0xc: + svga_set_ramdac_type(svga, (val & 1) ? RAMDAC_6BIT : RAMDAC_8BIT); + break; + } + break; + } } uint8_t ati68860_ramdac_in(uint16_t addr, ati68860_ramdac_t *ramdac, svga_t *svga) { - uint8_t ret = 0; - switch (addr) { - case 0:ret = svga_in(0x3c8, svga); - break; - case 1:ret = svga_in(0x3c9, svga); - break; - case 2:ret = svga_in(0x3c6, svga); - break; - case 3:ret = svga_in(0x3c7, svga); - break; - case 4: - case 8:ret = 2; - break; - case 6: - case 0xa:ret = 0x1d; - break; - case 0xf:ret = 0xd0; - break; + uint8_t ret = 0; + switch (addr) { + case 0: + ret = svga_in(0x3c8, svga); + break; + case 1: + ret = svga_in(0x3c9, svga); + break; + case 2: + ret = svga_in(0x3c6, svga); + break; + case 3: + ret = svga_in(0x3c7, svga); + break; + case 4: + case 8: + ret = 2; + break; + case 6: + case 0xa: + ret = 0x1d; + break; + case 0xf: + ret = 0xd0; + break; - default:ret = ramdac->regs[addr & 0xf]; - break; - } -// pclog("ati68860_in : addr %04X ret %02X %04X:%04X\n", addr, ret, CS,pc); - return ret; + default: + ret = ramdac->regs[addr & 0xf]; + break; + } + // pclog("ati68860_in : addr %04X ret %02X %04X:%04X\n", addr, ret, CS,pc); + return ret; } -void ati68860_ramdac_init(ati68860_ramdac_t *ramdac) { - ramdac->render = svga_render_8bpp_highres; -} +void ati68860_ramdac_init(ati68860_ramdac_t *ramdac) { ramdac->render = svga_render_8bpp_highres; } void ati68860_set_ramdac_type(ati68860_ramdac_t *ramdac, int type) { - int c; + int c; - if (ramdac->ramdac_type != type) { - ramdac->ramdac_type = type; + if (ramdac->ramdac_type != type) { + ramdac->ramdac_type = type; - for (c = 0; c < 2; c++) { - if (ramdac->ramdac_type == RAMDAC_8BIT) - ramdac->pallook[c] = makecol32(ramdac->pal[c].r, ramdac->pal[c].g, ramdac->pal[c].b); - else - ramdac->pallook[c] = makecol32((ramdac->pal[c].r & 0x3f) * 4, (ramdac->pal[c].g & 0x3f) * 4, (ramdac->pal[c].b & 0x3f) * 4); - } - } + for (c = 0; c < 2; c++) { + if (ramdac->ramdac_type == RAMDAC_8BIT) + ramdac->pallook[c] = makecol32(ramdac->pal[c].r, ramdac->pal[c].g, ramdac->pal[c].b); + else + ramdac->pallook[c] = makecol32((ramdac->pal[c].r & 0x3f) * 4, (ramdac->pal[c].g & 0x3f) * 4, + (ramdac->pal[c].b & 0x3f) * 4); + } + } } diff --git a/src/video/vid_ati_eeprom.c b/src/video/vid_ati_eeprom.c index 5f058be7..159d4549 100644 --- a/src/video/vid_ati_eeprom.c +++ b/src/video/vid_ati_eeprom.c @@ -2,182 +2,187 @@ #include "nvr.h" #include "vid_ati_eeprom.h" -enum { - EEPROM_IDLE, - EEPROM_WAIT, - EEPROM_OPCODE, - EEPROM_INPUT, - EEPROM_OUTPUT -}; +enum { EEPROM_IDLE, EEPROM_WAIT, EEPROM_OPCODE, EEPROM_INPUT, EEPROM_OUTPUT }; enum { - EEPROM_OP_EW = 4, - EEPROM_OP_WRITE = 5, - EEPROM_OP_READ = 6, - EEPROM_OP_ERASE = 7, + EEPROM_OP_EW = 4, + EEPROM_OP_WRITE = 5, + EEPROM_OP_READ = 6, + EEPROM_OP_ERASE = 7, - EEPROM_OP_WRALMAIN = -1 + EEPROM_OP_WRALMAIN = -1 }; -enum { - EEPROM_OP_EWDS = 0, - EEPROM_OP_WRAL = 1, - EEPROM_OP_ERAL = 2, - EEPROM_OP_EWEN = 3 -}; +enum { EEPROM_OP_EWDS = 0, EEPROM_OP_WRAL = 1, EEPROM_OP_ERAL = 2, EEPROM_OP_EWEN = 3 }; void ati_eeprom_load(ati_eeprom_t *eeprom, char *fn, int type) { - FILE *f; - eeprom->type = type; - strcpy(eeprom->fn, fn); - f = nvrfopen(eeprom->fn, "rb"); - if (!f) { - memset(eeprom->data, 0xff, eeprom->type ? 512 : 128); - return; - } - fread(eeprom->data, 1, eeprom->type ? 512 : 128, f); - fclose(f); + FILE *f; + eeprom->type = type; + strcpy(eeprom->fn, fn); + f = nvrfopen(eeprom->fn, "rb"); + if (!f) { + memset(eeprom->data, 0xff, eeprom->type ? 512 : 128); + return; + } + fread(eeprom->data, 1, eeprom->type ? 512 : 128, f); + fclose(f); } void ati_eeprom_save(ati_eeprom_t *eeprom) { - FILE *f = nvrfopen(eeprom->fn, "wb"); - if (!f) - return; - fwrite(eeprom->data, 1, eeprom->type ? 512 : 128, f); - fclose(f); + FILE *f = nvrfopen(eeprom->fn, "wb"); + if (!f) + return; + fwrite(eeprom->data, 1, eeprom->type ? 512 : 128, f); + fclose(f); } void ati_eeprom_write(ati_eeprom_t *eeprom, int ena, int clk, int dat) { - int c; -// pclog("EEPROM write %i %i %i\n", ena, clk, dat); - if (!ena) { - eeprom->out = 1; - } - if (clk && !eeprom->oldclk) { - if (ena && !eeprom->oldena) { - eeprom->state = EEPROM_WAIT; - eeprom->opcode = 0; - eeprom->count = 3; - eeprom->out = 1; - } else if (ena) { -// pclog("EEPROM receive %i %i %i\n", ena, clk, dat); - switch (eeprom->state) { - case EEPROM_WAIT: - if (!dat) - break; - eeprom->state = EEPROM_OPCODE; - /* fall through */ - case EEPROM_OPCODE:eeprom->opcode = (eeprom->opcode << 1) | (dat ? 1 : 0); - eeprom->count--; - if (!eeprom->count) { -// pclog("EEPROM opcode - %i\n", eeprom->opcode); - switch (eeprom->opcode) { - case EEPROM_OP_WRITE:eeprom->count = eeprom->type ? 24 : 22; - eeprom->state = EEPROM_INPUT; - eeprom->dat = 0; - break; - case EEPROM_OP_READ:eeprom->count = eeprom->type ? 8 : 6; - eeprom->state = EEPROM_INPUT; - eeprom->dat = 0; - break; - case EEPROM_OP_EW:eeprom->count = 2; - eeprom->state = EEPROM_INPUT; - eeprom->dat = 0; - break; - case EEPROM_OP_ERASE:eeprom->count = eeprom->type ? 8 : 6; - eeprom->state = EEPROM_INPUT; - eeprom->dat = 0; - break; - } - } - break; + int c; + // pclog("EEPROM write %i %i %i\n", ena, clk, dat); + if (!ena) { + eeprom->out = 1; + } + if (clk && !eeprom->oldclk) { + if (ena && !eeprom->oldena) { + eeprom->state = EEPROM_WAIT; + eeprom->opcode = 0; + eeprom->count = 3; + eeprom->out = 1; + } else if (ena) { + // pclog("EEPROM receive %i %i %i\n", ena, clk, dat); + switch (eeprom->state) { + case EEPROM_WAIT: + if (!dat) + break; + eeprom->state = EEPROM_OPCODE; + /* fall through */ + case EEPROM_OPCODE: + eeprom->opcode = (eeprom->opcode << 1) | (dat ? 1 : 0); + eeprom->count--; + if (!eeprom->count) { + // pclog("EEPROM opcode - %i\n", eeprom->opcode); + switch (eeprom->opcode) { + case EEPROM_OP_WRITE: + eeprom->count = eeprom->type ? 24 : 22; + eeprom->state = EEPROM_INPUT; + eeprom->dat = 0; + break; + case EEPROM_OP_READ: + eeprom->count = eeprom->type ? 8 : 6; + eeprom->state = EEPROM_INPUT; + eeprom->dat = 0; + break; + case EEPROM_OP_EW: + eeprom->count = 2; + eeprom->state = EEPROM_INPUT; + eeprom->dat = 0; + break; + case EEPROM_OP_ERASE: + eeprom->count = eeprom->type ? 8 : 6; + eeprom->state = EEPROM_INPUT; + eeprom->dat = 0; + break; + } + } + break; - case EEPROM_INPUT:eeprom->dat = (eeprom->dat << 1) | (dat ? 1 : 0); - eeprom->count--; - if (!eeprom->count) { -// pclog("EEPROM dat - %02X\n", eeprom->dat); - switch (eeprom->opcode) { - case EEPROM_OP_WRITE: -// pclog("EEPROM_OP_WRITE addr %02X eeprom_dat %04X\n", (eeprom->dat >> 16) & (eeprom->type ? 255 : 63), eeprom->dat & 0xffff); - if (!eeprom->wp) { - eeprom->data[(eeprom->dat >> 16) & (eeprom->type ? 255 : 63)] = eeprom->dat & 0xffff; - ati_eeprom_save(eeprom); - } - eeprom->state = EEPROM_IDLE; - eeprom->out = 1; - break; + case EEPROM_INPUT: + eeprom->dat = (eeprom->dat << 1) | (dat ? 1 : 0); + eeprom->count--; + if (!eeprom->count) { + // pclog("EEPROM dat - %02X\n", eeprom->dat); + switch (eeprom->opcode) { + case EEPROM_OP_WRITE: + // pclog("EEPROM_OP_WRITE addr %02X + // eeprom_dat %04X\n", (eeprom->dat + // >> 16) & (eeprom->type ? 255 : + // 63), eeprom->dat & 0xffff); + if (!eeprom->wp) { + eeprom->data[(eeprom->dat >> 16) & (eeprom->type ? 255 : 63)] = + eeprom->dat & 0xffff; + ati_eeprom_save(eeprom); + } + eeprom->state = EEPROM_IDLE; + eeprom->out = 1; + break; - case EEPROM_OP_READ:eeprom->count = 17; - eeprom->state = EEPROM_OUTPUT; - eeprom->dat = eeprom->data[eeprom->dat]; -// pclog("Trigger EEPROM_OUTPUT %04X\n", eeprom->dat); - break; - case EEPROM_OP_EW: -// pclog("EEPROM_OP_EW %i\n", eeprom->dat); - switch (eeprom->dat) { - case EEPROM_OP_EWDS:eeprom->wp = 1; - break; - case EEPROM_OP_WRAL:eeprom->opcode = EEPROM_OP_WRALMAIN; - eeprom->count = 20; - break; - case EEPROM_OP_ERAL: - if (!eeprom->wp) { - memset(eeprom->data, 0xff, 128); - ati_eeprom_save(eeprom); - } - break; - case EEPROM_OP_EWEN:eeprom->wp = 0; - break; - } - eeprom->state = EEPROM_IDLE; - eeprom->out = 1; - break; + case EEPROM_OP_READ: + eeprom->count = 17; + eeprom->state = EEPROM_OUTPUT; + eeprom->dat = eeprom->data[eeprom->dat]; + // pclog("Trigger EEPROM_OUTPUT + // %04X\n", eeprom->dat); + break; + case EEPROM_OP_EW: + // pclog("EEPROM_OP_EW %i\n", + // eeprom->dat); + switch (eeprom->dat) { + case EEPROM_OP_EWDS: + eeprom->wp = 1; + break; + case EEPROM_OP_WRAL: + eeprom->opcode = EEPROM_OP_WRALMAIN; + eeprom->count = 20; + break; + case EEPROM_OP_ERAL: + if (!eeprom->wp) { + memset(eeprom->data, 0xff, 128); + ati_eeprom_save(eeprom); + } + break; + case EEPROM_OP_EWEN: + eeprom->wp = 0; + break; + } + eeprom->state = EEPROM_IDLE; + eeprom->out = 1; + break; - case EEPROM_OP_ERASE: -// pclog("EEPROM_OP_ERASE %i\n", eeprom->dat); - if (!eeprom->wp) { - eeprom->data[eeprom->dat] = 0xffff; - ati_eeprom_save(eeprom); - } - eeprom->state = EEPROM_IDLE; - eeprom->out = 1; - break; + case EEPROM_OP_ERASE: + // pclog("EEPROM_OP_ERASE %i\n", + // eeprom->dat); + if (!eeprom->wp) { + eeprom->data[eeprom->dat] = 0xffff; + ati_eeprom_save(eeprom); + } + eeprom->state = EEPROM_IDLE; + eeprom->out = 1; + break; - case EEPROM_OP_WRALMAIN: -// pclog("EEPROM_OP_WRAL %04X\n", eeprom->dat); - if (!eeprom->wp) { - for (c = 0; c < 256; c++) - eeprom->data[c] = eeprom->dat; - ati_eeprom_save(eeprom); - } - eeprom->state = EEPROM_IDLE; - eeprom->out = 1; - break; - } - } - break; - } - } - eeprom->oldena = ena; - } else if (!clk && eeprom->oldclk) { - if (ena) { - switch (eeprom->state) { - case EEPROM_OUTPUT:eeprom->out = (eeprom->dat & 0x10000) ? 1 : 0; - eeprom->dat <<= 1; -// pclog("EEPROM_OUTPUT - data %i\n", eeprom->out); - eeprom->count--; - if (!eeprom->count) { -// pclog("EEPROM_OUTPUT complete\n"); - eeprom->state = EEPROM_IDLE; - } - break; - } - } - } - eeprom->oldclk = clk; -} - -int ati_eeprom_read(ati_eeprom_t *eeprom) { - return eeprom->out; + case EEPROM_OP_WRALMAIN: + // pclog("EEPROM_OP_WRAL %04X\n", + // eeprom->dat); + if (!eeprom->wp) { + for (c = 0; c < 256; c++) + eeprom->data[c] = eeprom->dat; + ati_eeprom_save(eeprom); + } + eeprom->state = EEPROM_IDLE; + eeprom->out = 1; + break; + } + } + break; + } + } + eeprom->oldena = ena; + } else if (!clk && eeprom->oldclk) { + if (ena) { + switch (eeprom->state) { + case EEPROM_OUTPUT: + eeprom->out = (eeprom->dat & 0x10000) ? 1 : 0; + eeprom->dat <<= 1; + // pclog("EEPROM_OUTPUT - data %i\n", eeprom->out); + eeprom->count--; + if (!eeprom->count) { + // pclog("EEPROM_OUTPUT complete\n"); + eeprom->state = EEPROM_IDLE; + } + break; + } + } + } + eeprom->oldclk = clk; } +int ati_eeprom_read(ati_eeprom_t *eeprom) { return eeprom->out; } diff --git a/src/video/vid_ati_mach64.c b/src/video/vid_ati_mach64.c index 332880ec..77c6aabd 100644 --- a/src/video/vid_ati_mach64.c +++ b/src/video/vid_ati_mach64.c @@ -26,258 +26,226 @@ #define FIFO_ENTRY_SIZE (1 << 31) #define FIFO_ENTRIES (mach64->fifo_write_idx - mach64->fifo_read_idx) -#define FIFO_FULL ((mach64->fifo_write_idx - mach64->fifo_read_idx) >= FIFO_SIZE) -#define FIFO_EMPTY (mach64->fifo_read_idx == mach64->fifo_write_idx) +#define FIFO_FULL ((mach64->fifo_write_idx - mach64->fifo_read_idx) >= FIFO_SIZE) +#define FIFO_EMPTY (mach64->fifo_read_idx == mach64->fifo_write_idx) #define FIFO_TYPE 0xff000000 #define FIFO_ADDR 0x00ffffff enum { - FIFO_INVALID = (0x00 << 24), - FIFO_WRITE_BYTE = (0x01 << 24), - FIFO_WRITE_WORD = (0x02 << 24), - FIFO_WRITE_DWORD = (0x03 << 24) + FIFO_INVALID = (0x00 << 24), + FIFO_WRITE_BYTE = (0x01 << 24), + FIFO_WRITE_WORD = (0x02 << 24), + FIFO_WRITE_DWORD = (0x03 << 24) }; typedef struct { - uint32_t addr_type; - uint32_t val; + uint32_t addr_type; + uint32_t val; } fifo_entry_t; -enum { - MACH64_GX = 0, - MACH64_VT2 -}; +enum { MACH64_GX = 0, MACH64_VT2 }; typedef struct mach64_t { - mem_mapping_t linear_mapping; - mem_mapping_t mmio_mapping; - mem_mapping_t mmio_linear_mapping; - mem_mapping_t mmio_linear_mapping_2; + mem_mapping_t linear_mapping; + mem_mapping_t mmio_mapping; + mem_mapping_t mmio_linear_mapping; + mem_mapping_t mmio_linear_mapping_2; - ati68860_ramdac_t ramdac; - ati_eeprom_t eeprom; - ics2595_t ics2595; - svga_t svga; + ati68860_ramdac_t ramdac; + ati_eeprom_t eeprom; + ics2595_t ics2595; + svga_t svga; - rom_t bios_rom; + rom_t bios_rom; - uint8_t regs[256]; - int index; + uint8_t regs[256]; + int index; - int type; + int type; - uint8_t pci_regs[256]; - uint8_t int_line; - int card; + uint8_t pci_regs[256]; + uint8_t int_line; + int card; - int bank_r[2]; - int bank_w[2]; + int bank_r[2]; + int bank_w[2]; - uint32_t vram_size; - uint32_t vram_mask; + uint32_t vram_size; + uint32_t vram_mask; - uint32_t config_cntl; + uint32_t config_cntl; - uint32_t context_load_cntl; - uint32_t context_mask; + uint32_t context_load_cntl; + uint32_t context_mask; - uint32_t crtc_gen_cntl; - uint8_t crtc_int_cntl; - uint32_t crtc_h_total_disp; - uint32_t crtc_v_sync_strt_wid; - uint32_t crtc_v_total_disp; - uint32_t crtc_off_pitch; + uint32_t crtc_gen_cntl; + uint8_t crtc_int_cntl; + uint32_t crtc_h_total_disp; + uint32_t crtc_v_sync_strt_wid; + uint32_t crtc_v_total_disp; + uint32_t crtc_off_pitch; - uint32_t clock_cntl; + uint32_t clock_cntl; - uint32_t clr_cmp_clr; - uint32_t clr_cmp_cntl; - uint32_t clr_cmp_mask; + uint32_t clr_cmp_clr; + uint32_t clr_cmp_cntl; + uint32_t clr_cmp_mask; - uint32_t cur_horz_vert_off; - uint32_t cur_horz_vert_posn; - uint32_t cur_offset; + uint32_t cur_horz_vert_off; + uint32_t cur_horz_vert_posn; + uint32_t cur_offset; - uint32_t dac_cntl; + uint32_t dac_cntl; - uint32_t dp_bkgd_clr; - uint32_t dp_frgd_clr; - uint32_t dp_mix; - uint32_t dp_pix_width; - uint32_t dp_src; + uint32_t dp_bkgd_clr; + uint32_t dp_frgd_clr; + uint32_t dp_mix; + uint32_t dp_pix_width; + uint32_t dp_src; - uint32_t dst_bres_lnth; - uint32_t dst_bres_dec; - uint32_t dst_bres_err; - uint32_t dst_bres_inc; + uint32_t dst_bres_lnth; + uint32_t dst_bres_dec; + uint32_t dst_bres_err; + uint32_t dst_bres_inc; - uint32_t dst_cntl; - uint32_t dst_height_width; - uint32_t dst_off_pitch; - uint32_t dst_y_x; + uint32_t dst_cntl; + uint32_t dst_height_width; + uint32_t dst_off_pitch; + uint32_t dst_y_x; - uint32_t gen_test_cntl; + uint32_t gen_test_cntl; - uint32_t gui_traj_cntl; + uint32_t gui_traj_cntl; - uint32_t host_cntl; + uint32_t host_cntl; - uint32_t mem_cntl; + uint32_t mem_cntl; - uint32_t ovr_clr; - uint32_t ovr_wid_left_right; - uint32_t ovr_wid_top_bottom; + uint32_t ovr_clr; + uint32_t ovr_wid_left_right; + uint32_t ovr_wid_top_bottom; - uint32_t pat_cntl; - uint32_t pat_reg0, pat_reg1; + uint32_t pat_cntl; + uint32_t pat_reg0, pat_reg1; - uint32_t sc_left_right, sc_top_bottom; + uint32_t sc_left_right, sc_top_bottom; - uint32_t scratch_reg0, scratch_reg1; + uint32_t scratch_reg0, scratch_reg1; - uint32_t src_cntl; - uint32_t src_off_pitch; - uint32_t src_y_x; - uint32_t src_y_x_start; - uint32_t src_height1_width1, src_height2_width2; + uint32_t src_cntl; + uint32_t src_off_pitch; + uint32_t src_y_x; + uint32_t src_y_x_start; + uint32_t src_height1_width1, src_height2_width2; - uint32_t linear_base, old_linear_base; + uint32_t linear_base, old_linear_base; - struct { - int op; + struct { + int op; - int dst_x, dst_y; - int dst_x_start, dst_y_start; - int src_x, src_y; - int src_x_start, src_y_start; - int xinc, yinc; - int x_count, y_count; - int src_x_count, src_y_count; - int src_width1, src_height1; - int src_width2, src_height2; - uint32_t src_offset, src_pitch; - uint32_t dst_offset, dst_pitch; - int mix_bg, mix_fg; - int source_bg, source_fg, source_mix; - int source_host; - int dst_width, dst_height; - int busy; - int pattern[8][8]; - int sc_left, sc_right, sc_top, sc_bottom; - int dst_pix_width, src_pix_width, host_pix_width; - int dst_size, src_size, host_size; + int dst_x, dst_y; + int dst_x_start, dst_y_start; + int src_x, src_y; + int src_x_start, src_y_start; + int xinc, yinc; + int x_count, y_count; + int src_x_count, src_y_count; + int src_width1, src_height1; + int src_width2, src_height2; + uint32_t src_offset, src_pitch; + uint32_t dst_offset, dst_pitch; + int mix_bg, mix_fg; + int source_bg, source_fg, source_mix; + int source_host; + int dst_width, dst_height; + int busy; + int pattern[8][8]; + int sc_left, sc_right, sc_top, sc_bottom; + int dst_pix_width, src_pix_width, host_pix_width; + int dst_size, src_size, host_size; - uint32_t dp_bkgd_clr; - uint32_t dp_frgd_clr; + uint32_t dp_bkgd_clr; + uint32_t dp_frgd_clr; - uint32_t clr_cmp_clr; - uint32_t clr_cmp_mask; - int clr_cmp_fn; - int clr_cmp_src; + uint32_t clr_cmp_clr; + uint32_t clr_cmp_mask; + int clr_cmp_fn; + int clr_cmp_src; - int err; - int poly_draw; - } accel; + int err; + int poly_draw; + } accel; - fifo_entry_t fifo[FIFO_SIZE]; - volatile int fifo_read_idx, fifo_write_idx; + fifo_entry_t fifo[FIFO_SIZE]; + volatile int fifo_read_idx, fifo_write_idx; - thread_t *fifo_thread; - event_t *wake_fifo_thread; - event_t *fifo_not_full_event; + thread_t *fifo_thread; + event_t *wake_fifo_thread; + event_t *fifo_not_full_event; - int blitter_busy; - uint64_t blitter_time; - uint64_t status_time; + int blitter_busy; + uint64_t blitter_time; + uint64_t status_time; - uint16_t pci_id; - uint32_t config_chip_id; - uint32_t block_decoded_io; - int use_block_decoded_io; + uint16_t pci_id; + uint32_t config_chip_id; + uint32_t block_decoded_io; + int use_block_decoded_io; - int pll_addr; - uint8_t pll_regs[16]; - double pll_freq[4]; + int pll_addr; + uint8_t pll_regs[16]; + double pll_freq[4]; - uint32_t config_stat0; + uint32_t config_stat0; - uint32_t cur_clr0, cur_clr1; + uint32_t cur_clr0, cur_clr1; - uint32_t overlay_dat[1024]; - uint32_t overlay_graphics_key_clr, overlay_graphics_key_msk; - uint32_t overlay_video_key_clr, overlay_video_key_msk; - uint32_t overlay_key_cntl; - uint32_t overlay_scale_inc; - uint32_t overlay_scale_cntl; - uint32_t overlay_y_x_start, overlay_y_x_end; + uint32_t overlay_dat[1024]; + uint32_t overlay_graphics_key_clr, overlay_graphics_key_msk; + uint32_t overlay_video_key_clr, overlay_video_key_msk; + uint32_t overlay_key_cntl; + uint32_t overlay_scale_inc; + uint32_t overlay_scale_cntl; + uint32_t overlay_y_x_start, overlay_y_x_end; - uint32_t scaler_height_width; - int scaler_format; - int scaler_update; + uint32_t scaler_height_width; + int scaler_format; + int scaler_update; - uint32_t buf_offset[2], buf_pitch[2]; + uint32_t buf_offset[2], buf_pitch[2]; - int overlay_v_acc; + int overlay_v_acc; } mach64_t; -enum { - SRC_BG = 0, - SRC_FG = 1, - SRC_HOST = 2, - SRC_BLITSRC = 3, - SRC_PAT = 4 -}; +enum { SRC_BG = 0, SRC_FG = 1, SRC_HOST = 2, SRC_BLITSRC = 3, SRC_PAT = 4 }; -enum { - MONO_SRC_1 = 0, - MONO_SRC_PAT = 1, - MONO_SRC_HOST = 2, - MONO_SRC_BLITSRC = 3 -}; +enum { MONO_SRC_1 = 0, MONO_SRC_PAT = 1, MONO_SRC_HOST = 2, MONO_SRC_BLITSRC = 3 }; -enum { - BPP_1 = 0, - BPP_4 = 1, - BPP_8 = 2, - BPP_15 = 3, - BPP_16 = 4, - BPP_32 = 5 -}; +enum { BPP_1 = 0, BPP_4 = 1, BPP_8 = 2, BPP_15 = 3, BPP_16 = 4, BPP_32 = 5 }; -enum { - OP_RECT, - OP_LINE -}; +enum { OP_RECT, OP_LINE }; -enum { - SRC_PATT_EN = 1, - SRC_PATT_ROT_EN = 2, - SRC_LINEAR_EN = 4 -}; +enum { SRC_PATT_EN = 1, SRC_PATT_ROT_EN = 2, SRC_LINEAR_EN = 4 }; -enum { - DP_BYTE_PIX_ORDER = (1 << 24) -}; +enum { DP_BYTE_PIX_ORDER = (1 << 24) }; #define WIDTH_1BIT 3 static int mach64_width[8] = {WIDTH_1BIT, 0, 0, 1, 1, 2, 2, 0}; enum { - DST_X_DIR = 0x01, - DST_Y_DIR = 0x02, - DST_Y_MAJOR = 0x04, - DST_X_TILE = 0x08, - DST_Y_TILE = 0x10, - DST_LAST_PEL = 0x20, - DST_POLYGON_EN = 0x40, - DST_24_ROT_EN = 0x80 + DST_X_DIR = 0x01, + DST_Y_DIR = 0x02, + DST_Y_MAJOR = 0x04, + DST_X_TILE = 0x08, + DST_Y_TILE = 0x10, + DST_LAST_PEL = 0x20, + DST_POLYGON_EN = 0x40, + DST_24_ROT_EN = 0x80 }; -enum { - HOST_BYTE_ALIGN = (1 << 0) -}; +enum { HOST_BYTE_ALIGN = (1 << 0) }; void mach64_write(uint32_t addr, uint8_t val, void *priv); void mach64_writew(uint32_t addr, uint16_t val, void *priv); @@ -300,3546 +268,3926 @@ void mach64_ext_writew(uint32_t addr, uint16_t val, void *priv); void mach64_ext_writel(uint32_t addr, uint32_t val, void *priv); void mach64_out(uint16_t addr, uint8_t val, void *p) { - mach64_t *mach64 = p; - svga_t *svga = &mach64->svga; - uint8_t old; + mach64_t *mach64 = p; + svga_t *svga = &mach64->svga; + uint8_t old; - if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1)) - addr ^= 0x60; + if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1)) + addr ^= 0x60; -// pclog("mach64 out %04X %02X\n", addr, val); + // pclog("mach64 out %04X %02X\n", addr, val); - switch (addr) { - case 0x1ce:mach64->index = val; - break; - case 0x1cf:mach64->regs[mach64->index & 0x3f] = val; - if ((mach64->index & 0x3f) == 0x36) - mach64_recalctimings(svga); - break; + switch (addr) { + case 0x1ce: + mach64->index = val; + break; + case 0x1cf: + mach64->regs[mach64->index & 0x3f] = val; + if ((mach64->index & 0x3f) == 0x36) + mach64_recalctimings(svga); + break; - case 0x3C6: - case 0x3C7: - case 0x3C8: - case 0x3C9: - if (mach64->type == MACH64_GX) - ati68860_ramdac_out((addr & 3) | ((mach64->dac_cntl & 3) << 2), val, &mach64->ramdac, svga); - else - svga_out(addr, val, svga); - return; + case 0x3C6: + case 0x3C7: + case 0x3C8: + case 0x3C9: + if (mach64->type == MACH64_GX) + ati68860_ramdac_out((addr & 3) | ((mach64->dac_cntl & 3) << 2), val, &mach64->ramdac, svga); + else + svga_out(addr, val, svga); + return; - case 0x3cf: - if (svga->gdcaddr == 6) { - uint8_t old_val = svga->gdcreg[6]; - svga->gdcreg[6] = val; - if ((svga->gdcreg[6] & 0xc) != (old_val & 0xc)) - mach64_updatemapping(mach64); - return; - } - break; + case 0x3cf: + if (svga->gdcaddr == 6) { + uint8_t old_val = svga->gdcreg[6]; + svga->gdcreg[6] = val; + if ((svga->gdcreg[6] & 0xc) != (old_val & 0xc)) + mach64_updatemapping(mach64); + return; + } + break; - case 0x3D4:svga->crtcreg = val & 0x3f; - return; - case 0x3D5: - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) - return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); - if (svga->crtcreg > 0x18) - return; - old = svga->crtc[svga->crtcreg]; - svga->crtc[svga->crtcreg] = val; + case 0x3D4: + svga->crtcreg = val & 0x3f; + return; + case 0x3D5: + if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) + return; + if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) + val = (svga->crtc[7] & ~0x10) | (val & 0x10); + if (svga->crtcreg > 0x18) + return; + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; - if (old != val) { - if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - } - break; - } - svga_out(addr, val, svga); + if (old != val) { + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } + } + break; + } + svga_out(addr, val, svga); } uint8_t mach64_in(uint16_t addr, void *p) { - mach64_t *mach64 = p; - svga_t *svga = &mach64->svga; + mach64_t *mach64 = p; + svga_t *svga = &mach64->svga; - if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1)) - addr ^= 0x60; + if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1)) + addr ^= 0x60; -// pclog("IN mach64 %04X\n", addr); + // pclog("IN mach64 %04X\n", addr); - switch (addr) { - case 0x1ce:return mach64->index; - case 0x1cf:return mach64->regs[mach64->index & 0x3f]; + switch (addr) { + case 0x1ce: + return mach64->index; + case 0x1cf: + return mach64->regs[mach64->index & 0x3f]; - case 0x3C6: - case 0x3C7: - case 0x3C8: - case 0x3C9: - if (mach64->type == MACH64_GX) - return ati68860_ramdac_in((addr & 3) | ((mach64->dac_cntl & 3) << 2), &mach64->ramdac, svga); - return svga_in(addr, svga); + case 0x3C6: + case 0x3C7: + case 0x3C8: + case 0x3C9: + if (mach64->type == MACH64_GX) + return ati68860_ramdac_in((addr & 3) | ((mach64->dac_cntl & 3) << 2), &mach64->ramdac, svga); + return svga_in(addr, svga); - case 0x3D4:return svga->crtcreg; - case 0x3D5: - if (svga->crtcreg > 0x18) - return 0xff; - return svga->crtc[svga->crtcreg]; - } - return svga_in(addr, svga); + case 0x3D4: + return svga->crtcreg; + case 0x3D5: + if (svga->crtcreg > 0x18) + return 0xff; + return svga->crtc[svga->crtcreg]; + } + return svga_in(addr, svga); } void mach64_recalctimings(svga_t *svga) { - mach64_t *mach64 = (mach64_t *)svga->p; + mach64_t *mach64 = (mach64_t *)svga->p; - if (((mach64->crtc_gen_cntl >> 24) & 3) == 3) { - svga->vtotal = (mach64->crtc_v_total_disp & 2047) + 1; - svga->dispend = ((mach64->crtc_v_total_disp >> 16) & 2047) + 1; - svga->htotal = (mach64->crtc_h_total_disp & 255) + 1; - svga->hdisp_time = svga->hdisp = ((mach64->crtc_h_total_disp >> 16) & 255) + 1; - svga->vsyncstart = (mach64->crtc_v_sync_strt_wid & 2047) + 1; - svga->rowoffset = (mach64->crtc_off_pitch >> 22); - svga->clock = (cpuclock * (float)(1ull << 32)) / mach64->ics2595.output_clock; - svga->ma_latch = (mach64->crtc_off_pitch & 0x1fffff) * 2; - svga->linedbl = svga->rowcount = 0; - svga->split = 0xffffff; - svga->vblankstart = svga->dispend; - svga->rowcount = mach64->crtc_gen_cntl & 1; -// svga_htotal <<= 1; -// svga_hdisp <<= 1; - svga->rowoffset <<= 1; - if (mach64->type == MACH64_GX) - svga->render = mach64->ramdac.render; - switch ((mach64->crtc_gen_cntl >> 8) & 7) { - case 1: - if (mach64->type != MACH64_GX) - svga->render = svga_render_4bpp_highres; - svga->hdisp *= 8; - break; - case 2: - if (mach64->type != MACH64_GX) - svga->render = svga_render_8bpp_highres; - svga->hdisp *= 8; - svga->rowoffset /= 2; - break; - case 3: - if (mach64->type != MACH64_GX) - svga->render = svga_render_15bpp_highres; - svga->hdisp *= 8; - //svga_rowoffset *= 2; - break; - case 4: - if (mach64->type != MACH64_GX) - svga->render = svga_render_16bpp_highres; - svga->hdisp *= 8; - //svga_rowoffset *= 2; - break; - case 5: - if (mach64->type != MACH64_GX) - svga->render = svga_render_24bpp_highres; - svga->hdisp *= 8; - svga->rowoffset = (svga->rowoffset * 3) / 2; - break; - case 6: - if (mach64->type != MACH64_GX) - svga->render = svga_render_32bpp_highres; - svga->hdisp *= 8; - svga->rowoffset *= 2; - break; - } + if (((mach64->crtc_gen_cntl >> 24) & 3) == 3) { + svga->vtotal = (mach64->crtc_v_total_disp & 2047) + 1; + svga->dispend = ((mach64->crtc_v_total_disp >> 16) & 2047) + 1; + svga->htotal = (mach64->crtc_h_total_disp & 255) + 1; + svga->hdisp_time = svga->hdisp = ((mach64->crtc_h_total_disp >> 16) & 255) + 1; + svga->vsyncstart = (mach64->crtc_v_sync_strt_wid & 2047) + 1; + svga->rowoffset = (mach64->crtc_off_pitch >> 22); + svga->clock = (cpuclock * (float)(1ull << 32)) / mach64->ics2595.output_clock; + svga->ma_latch = (mach64->crtc_off_pitch & 0x1fffff) * 2; + svga->linedbl = svga->rowcount = 0; + svga->split = 0xffffff; + svga->vblankstart = svga->dispend; + svga->rowcount = mach64->crtc_gen_cntl & 1; + // svga_htotal <<= 1; + // svga_hdisp <<= 1; + svga->rowoffset <<= 1; + if (mach64->type == MACH64_GX) + svga->render = mach64->ramdac.render; + switch ((mach64->crtc_gen_cntl >> 8) & 7) { + case 1: + if (mach64->type != MACH64_GX) + svga->render = svga_render_4bpp_highres; + svga->hdisp *= 8; + break; + case 2: + if (mach64->type != MACH64_GX) + svga->render = svga_render_8bpp_highres; + svga->hdisp *= 8; + svga->rowoffset /= 2; + break; + case 3: + if (mach64->type != MACH64_GX) + svga->render = svga_render_15bpp_highres; + svga->hdisp *= 8; + // svga_rowoffset *= 2; + break; + case 4: + if (mach64->type != MACH64_GX) + svga->render = svga_render_16bpp_highres; + svga->hdisp *= 8; + // svga_rowoffset *= 2; + break; + case 5: + if (mach64->type != MACH64_GX) + svga->render = svga_render_24bpp_highres; + svga->hdisp *= 8; + svga->rowoffset = (svga->rowoffset * 3) / 2; + break; + case 6: + if (mach64->type != MACH64_GX) + svga->render = svga_render_32bpp_highres; + svga->hdisp *= 8; + svga->rowoffset *= 2; + break; + } - svga->vram_display_mask = mach64->vram_mask; -// pclog("mach64_recalctimings : frame %i,%i disp %i,%i vsync at %i rowoffset %i pixel clock %f MA %08X\n", svga->htotal, svga->vtotal, svga->hdisp, svga->dispend, svga->vsyncstart, svga->rowoffset, svga->clock, svga->ma); - } else { - svga->vram_display_mask = (mach64->regs[0x36] & 0x01) ? mach64->vram_mask : 0x3ffff; - } + svga->vram_display_mask = mach64->vram_mask; + // pclog("mach64_recalctimings : frame %i,%i disp %i,%i vsync at %i rowoffset %i pixel clock %f MA + // %08X\n", svga->htotal, svga->vtotal, svga->hdisp, svga->dispend, svga->vsyncstart, + // svga->rowoffset, svga->clock, svga->ma); + } else { + svga->vram_display_mask = (mach64->regs[0x36] & 0x01) ? mach64->vram_mask : 0x3ffff; + } } void mach64_updatemapping(mach64_t *mach64) { - svga_t *svga = &mach64->svga; + svga_t *svga = &mach64->svga; - if (!(mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) { - pclog("Update mapping - PCI disabled\n"); - mem_mapping_disable(&svga->mapping); - mem_mapping_disable(&mach64->linear_mapping); - mem_mapping_disable(&mach64->mmio_mapping); - mem_mapping_disable(&mach64->mmio_linear_mapping); - mem_mapping_disable(&mach64->mmio_linear_mapping_2); - return; - } + if (!(mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) { + pclog("Update mapping - PCI disabled\n"); + mem_mapping_disable(&svga->mapping); + mem_mapping_disable(&mach64->linear_mapping); + mem_mapping_disable(&mach64->mmio_mapping); + mem_mapping_disable(&mach64->mmio_linear_mapping); + mem_mapping_disable(&mach64->mmio_linear_mapping_2); + return; + } - mem_mapping_disable(&mach64->mmio_mapping); -// pclog("Write mapping %02X\n", val); - switch (svga->gdcreg[6] & 0xc) { - case 0x0: /*128k at A0000*/ - mem_mapping_set_handler(&mach64->svga.mapping, mach64_read, mach64_readw, mach64_readl, mach64_write, mach64_writew, mach64_writel); - mem_mapping_set_p(&mach64->svga.mapping, mach64); - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); - mem_mapping_enable(&mach64->mmio_mapping); - svga->banked_mask = 0xffff; - break; - case 0x4: /*64k at A0000*/ - mem_mapping_set_handler(&mach64->svga.mapping, mach64_read, mach64_readw, mach64_readl, mach64_write, mach64_writew, mach64_writel); - mem_mapping_set_p(&mach64->svga.mapping, mach64); - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - svga->banked_mask = 0xffff; - break; - case 0x8: /*32k at B0000*/ - mem_mapping_set_handler(&mach64->svga.mapping, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel); - mem_mapping_set_p(&mach64->svga.mapping, svga); - mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); - svga->banked_mask = 0x7fff; - break; - case 0xC: /*32k at B8000*/ - mem_mapping_set_handler(&mach64->svga.mapping, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel); - mem_mapping_set_p(&mach64->svga.mapping, svga); - mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); - svga->banked_mask = 0x7fff; - break; - } - if (mach64->linear_base) { - if (mach64->type == MACH64_GX) { - if ((mach64->config_cntl & 3) == 2) { - /*8 MB aperture*/ - mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, (8 << 20) - 0x4000); - mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + ((8 << 20) - 0x4000), 0x4000); - } else { - /*4 MB aperture*/ - mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, (4 << 20) - 0x4000); - mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + ((4 << 20) - 0x4000), 0x4000); - } - } else { - /*2*8 MB aperture*/ - mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, (8 << 20) - 0x4000); - mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + ((8 << 20) - 0x4000), 0x4000); - mem_mapping_set_addr(&mach64->mmio_linear_mapping_2, mach64->linear_base + ((16 << 20) - 0x4000), 0x4000); - } - } else { - mem_mapping_disable(&mach64->linear_mapping); - mem_mapping_disable(&mach64->mmio_linear_mapping); - mem_mapping_disable(&mach64->mmio_linear_mapping_2); - } + mem_mapping_disable(&mach64->mmio_mapping); + // pclog("Write mapping %02X\n", val); + switch (svga->gdcreg[6] & 0xc) { + case 0x0: /*128k at A0000*/ + mem_mapping_set_handler(&mach64->svga.mapping, mach64_read, mach64_readw, mach64_readl, mach64_write, + mach64_writew, mach64_writel); + mem_mapping_set_p(&mach64->svga.mapping, mach64); + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); + mem_mapping_enable(&mach64->mmio_mapping); + svga->banked_mask = 0xffff; + break; + case 0x4: /*64k at A0000*/ + mem_mapping_set_handler(&mach64->svga.mapping, mach64_read, mach64_readw, mach64_readl, mach64_write, + mach64_writew, mach64_writel); + mem_mapping_set_p(&mach64->svga.mapping, mach64); + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + svga->banked_mask = 0xffff; + break; + case 0x8: /*32k at B0000*/ + mem_mapping_set_handler(&mach64->svga.mapping, svga_read, svga_readw, svga_readl, svga_write, svga_writew, + svga_writel); + mem_mapping_set_p(&mach64->svga.mapping, svga); + mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); + svga->banked_mask = 0x7fff; + break; + case 0xC: /*32k at B8000*/ + mem_mapping_set_handler(&mach64->svga.mapping, svga_read, svga_readw, svga_readl, svga_write, svga_writew, + svga_writel); + mem_mapping_set_p(&mach64->svga.mapping, svga); + mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); + svga->banked_mask = 0x7fff; + break; + } + if (mach64->linear_base) { + if (mach64->type == MACH64_GX) { + if ((mach64->config_cntl & 3) == 2) { + /*8 MB aperture*/ + mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, (8 << 20) - 0x4000); + mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + ((8 << 20) - 0x4000), + 0x4000); + } else { + /*4 MB aperture*/ + mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, (4 << 20) - 0x4000); + mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + ((4 << 20) - 0x4000), + 0x4000); + } + } else { + /*2*8 MB aperture*/ + mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, (8 << 20) - 0x4000); + mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + ((8 << 20) - 0x4000), 0x4000); + mem_mapping_set_addr(&mach64->mmio_linear_mapping_2, mach64->linear_base + ((16 << 20) - 0x4000), 0x4000); + } + } else { + mem_mapping_disable(&mach64->linear_mapping); + mem_mapping_disable(&mach64->mmio_linear_mapping); + mem_mapping_disable(&mach64->mmio_linear_mapping_2); + } } static void mach64_update_irqs(mach64_t *mach64) { - if ((mach64->crtc_int_cntl & 0xaa0024) & ((mach64->crtc_int_cntl << 1) & 0xaa0024)) - pci_set_irq(mach64->card, PCI_INTA); - else - pci_clear_irq(mach64->card, PCI_INTA); + if ((mach64->crtc_int_cntl & 0xaa0024) & ((mach64->crtc_int_cntl << 1) & 0xaa0024)) + pci_set_irq(mach64->card, PCI_INTA); + else + pci_clear_irq(mach64->card, PCI_INTA); } static inline void wake_fifo_thread(mach64_t *mach64) { - thread_set_event(mach64->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ + thread_set_event(mach64->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ } static void mach64_wait_fifo_idle(mach64_t *mach64) { - while (!FIFO_EMPTY) { - wake_fifo_thread(mach64); - thread_wait_event(mach64->fifo_not_full_event, 1); - } + while (!FIFO_EMPTY) { + wake_fifo_thread(mach64); + thread_wait_event(mach64->fifo_not_full_event, 1); + } } -#define READ8(addr, var) switch ((addr) & 3) \ - { \ - case 0: ret = (var) & 0xff; break; \ - case 1: ret = ((var) >> 8) & 0xff; break; \ - case 2: ret = ((var) >> 16) & 0xff; break; \ - case 3: ret = ((var) >> 24) & 0xff; break; \ - } +#define READ8(addr, var) \ + switch ((addr)&3) { \ + case 0: \ + ret = (var)&0xff; \ + break; \ + case 1: \ + ret = ((var) >> 8) & 0xff; \ + break; \ + case 2: \ + ret = ((var) >> 16) & 0xff; \ + break; \ + case 3: \ + ret = ((var) >> 24) & 0xff; \ + break; \ + } -#define WRITE8(addr, var, val) switch ((addr) & 3) \ - { \ - case 0: var = (var & 0xffffff00) | (val); break; \ - case 1: var = (var & 0xffff00ff) | ((val) << 8); break; \ - case 2: var = (var & 0xff00ffff) | ((val) << 16); break; \ - case 3: var = (var & 0x00ffffff) | ((val) << 24); break; \ - } +#define WRITE8(addr, var, val) \ + switch ((addr)&3) { \ + case 0: \ + var = (var & 0xffffff00) | (val); \ + break; \ + case 1: \ + var = (var & 0xffff00ff) | ((val) << 8); \ + break; \ + case 2: \ + var = (var & 0xff00ffff) | ((val) << 16); \ + break; \ + case 3: \ + var = (var & 0x00ffffff) | ((val) << 24); \ + break; \ + } static void mach64_accel_write_fifo(mach64_t *mach64, uint32_t addr, uint8_t val) { -// pclog("mach64_accel_write_fifo: addr=%08x val=%02x\n", addr, val); - switch (addr & 0x3ff) { - case 0x100: - case 0x101: - case 0x102: - case 0x103:WRITE8(addr, mach64->dst_off_pitch, val); - break; - case 0x104: - case 0x105: - case 0x11c: - case 0x11d:WRITE8(addr + 2, mach64->dst_y_x, val); - break; - case 0x108: - case 0x109:WRITE8(addr, mach64->dst_y_x, val); - break; - case 0x10c: - case 0x10d: - case 0x10e: - case 0x10f:WRITE8(addr, mach64->dst_y_x, val); - break; - case 0x110: - case 0x111:WRITE8(addr + 2, mach64->dst_height_width, val); - break; - case 0x114: - case 0x115: - case 0x118: - case 0x119: - case 0x11a: - case 0x11b: - case 0x11e: - case 0x11f:WRITE8(addr, mach64->dst_height_width, val); - case 0x113: - if (((addr & 0x3ff) == 0x11b || (addr & 0x3ff) == 0x11f || - (addr & 0x3ff) == 0x113) && !(val & 0x80)) { - mach64_start_fill(mach64); + // pclog("mach64_accel_write_fifo: addr=%08x val=%02x\n", addr, val); + switch (addr & 0x3ff) { + case 0x100: + case 0x101: + case 0x102: + case 0x103: + WRITE8(addr, mach64->dst_off_pitch, val); + break; + case 0x104: + case 0x105: + case 0x11c: + case 0x11d: + WRITE8(addr + 2, mach64->dst_y_x, val); + break; + case 0x108: + case 0x109: + WRITE8(addr, mach64->dst_y_x, val); + break; + case 0x10c: + case 0x10d: + case 0x10e: + case 0x10f: + WRITE8(addr, mach64->dst_y_x, val); + break; + case 0x110: + case 0x111: + WRITE8(addr + 2, mach64->dst_height_width, val); + break; + case 0x114: + case 0x115: + case 0x118: + case 0x119: + case 0x11a: + case 0x11b: + case 0x11e: + case 0x11f: + WRITE8(addr, mach64->dst_height_width, val); + case 0x113: + if (((addr & 0x3ff) == 0x11b || (addr & 0x3ff) == 0x11f || (addr & 0x3ff) == 0x113) && !(val & 0x80)) { + mach64_start_fill(mach64); #ifdef MACH64_DEBUG - pclog("%i %i %i %i %i %08x\n", (mach64->dst_height_width & 0x7ff), (mach64->dst_height_width & 0x7ff0000), - ((mach64->dp_src & 7) != SRC_HOST), (((mach64->dp_src >> 8) & 7) != SRC_HOST), - (((mach64->dp_src >> 16) & 3) != MONO_SRC_HOST), mach64->dp_src); + pclog("%i %i %i %i %i %08x\n", (mach64->dst_height_width & 0x7ff), (mach64->dst_height_width & 0x7ff0000), + ((mach64->dp_src & 7) != SRC_HOST), (((mach64->dp_src >> 8) & 7) != SRC_HOST), + (((mach64->dp_src >> 16) & 3) != MONO_SRC_HOST), mach64->dp_src); #endif - if ((mach64->dst_height_width & 0x7ff) && (mach64->dst_height_width & 0x7ff0000) && - ((mach64->dp_src & 7) != SRC_HOST) && (((mach64->dp_src >> 8) & 7) != SRC_HOST) && - (((mach64->dp_src >> 16) & 3) != MONO_SRC_HOST)) - mach64_blit(0, -1, mach64); - } - break; + if ((mach64->dst_height_width & 0x7ff) && (mach64->dst_height_width & 0x7ff0000) && + ((mach64->dp_src & 7) != SRC_HOST) && (((mach64->dp_src >> 8) & 7) != SRC_HOST) && + (((mach64->dp_src >> 16) & 3) != MONO_SRC_HOST)) + mach64_blit(0, -1, mach64); + } + break; - case 0x120: - case 0x121: - case 0x122: - case 0x123:WRITE8(addr, mach64->dst_bres_lnth, val); - if ((addr & 0x3ff) == 0x123 && !(val & 0x80)) { - mach64_start_line(mach64); + case 0x120: + case 0x121: + case 0x122: + case 0x123: + WRITE8(addr, mach64->dst_bres_lnth, val); + if ((addr & 0x3ff) == 0x123 && !(val & 0x80)) { + mach64_start_line(mach64); - if ((mach64->dst_bres_lnth & 0x7fff) && - ((mach64->dp_src & 7) != SRC_HOST) && (((mach64->dp_src >> 8) & 7) != SRC_HOST) && - (((mach64->dp_src >> 16) & 3) != MONO_SRC_HOST)) - mach64_blit(0, -1, mach64); - } - break; - case 0x124: - case 0x125: - case 0x126: - case 0x127:WRITE8(addr, mach64->dst_bres_err, val); - break; - case 0x128: - case 0x129: - case 0x12a: - case 0x12b:WRITE8(addr, mach64->dst_bres_inc, val); - break; - case 0x12c: - case 0x12d: - case 0x12e: - case 0x12f:WRITE8(addr, mach64->dst_bres_dec, val); - break; + if ((mach64->dst_bres_lnth & 0x7fff) && ((mach64->dp_src & 7) != SRC_HOST) && + (((mach64->dp_src >> 8) & 7) != SRC_HOST) && (((mach64->dp_src >> 16) & 3) != MONO_SRC_HOST)) + mach64_blit(0, -1, mach64); + } + break; + case 0x124: + case 0x125: + case 0x126: + case 0x127: + WRITE8(addr, mach64->dst_bres_err, val); + break; + case 0x128: + case 0x129: + case 0x12a: + case 0x12b: + WRITE8(addr, mach64->dst_bres_inc, val); + break; + case 0x12c: + case 0x12d: + case 0x12e: + case 0x12f: + WRITE8(addr, mach64->dst_bres_dec, val); + break; - case 0x130: - case 0x131: - case 0x132: - case 0x133:WRITE8(addr, mach64->dst_cntl, val); - break; + case 0x130: + case 0x131: + case 0x132: + case 0x133: + WRITE8(addr, mach64->dst_cntl, val); + break; - case 0x180: - case 0x181: - case 0x182: - case 0x183:WRITE8(addr, mach64->src_off_pitch, val); - break; - case 0x184: - case 0x185:WRITE8(addr, mach64->src_y_x, val); - break; - case 0x188: - case 0x189:WRITE8(addr + 2, mach64->src_y_x, val); - break; - case 0x18c: - case 0x18d: - case 0x18e: - case 0x18f:WRITE8(addr, mach64->src_y_x, val); - break; - case 0x190: - case 0x191:WRITE8(addr + 2, mach64->src_height1_width1, val); - break; - case 0x194: - case 0x195:WRITE8(addr, mach64->src_height1_width1, val); - break; - case 0x198: - case 0x199: - case 0x19a: - case 0x19b:WRITE8(addr, mach64->src_height1_width1, val); - break; - case 0x19c: - case 0x19d:WRITE8(addr, mach64->src_y_x_start, val); - break; - case 0x1a0: - case 0x1a1:WRITE8(addr + 2, mach64->src_y_x_start, val); - break; - case 0x1a4: - case 0x1a5: - case 0x1a6: - case 0x1a7:WRITE8(addr, mach64->src_y_x_start, val); - break; - case 0x1a8: - case 0x1a9:WRITE8(addr + 2, mach64->src_height2_width2, val); - break; - case 0x1ac: - case 0x1ad:WRITE8(addr, mach64->src_height2_width2, val); - break; - case 0x1b0: - case 0x1b1: - case 0x1b2: - case 0x1b3:WRITE8(addr, mach64->src_height2_width2, val); - break; + case 0x180: + case 0x181: + case 0x182: + case 0x183: + WRITE8(addr, mach64->src_off_pitch, val); + break; + case 0x184: + case 0x185: + WRITE8(addr, mach64->src_y_x, val); + break; + case 0x188: + case 0x189: + WRITE8(addr + 2, mach64->src_y_x, val); + break; + case 0x18c: + case 0x18d: + case 0x18e: + case 0x18f: + WRITE8(addr, mach64->src_y_x, val); + break; + case 0x190: + case 0x191: + WRITE8(addr + 2, mach64->src_height1_width1, val); + break; + case 0x194: + case 0x195: + WRITE8(addr, mach64->src_height1_width1, val); + break; + case 0x198: + case 0x199: + case 0x19a: + case 0x19b: + WRITE8(addr, mach64->src_height1_width1, val); + break; + case 0x19c: + case 0x19d: + WRITE8(addr, mach64->src_y_x_start, val); + break; + case 0x1a0: + case 0x1a1: + WRITE8(addr + 2, mach64->src_y_x_start, val); + break; + case 0x1a4: + case 0x1a5: + case 0x1a6: + case 0x1a7: + WRITE8(addr, mach64->src_y_x_start, val); + break; + case 0x1a8: + case 0x1a9: + WRITE8(addr + 2, mach64->src_height2_width2, val); + break; + case 0x1ac: + case 0x1ad: + WRITE8(addr, mach64->src_height2_width2, val); + break; + case 0x1b0: + case 0x1b1: + case 0x1b2: + case 0x1b3: + WRITE8(addr, mach64->src_height2_width2, val); + break; - case 0x1b4: - case 0x1b5: - case 0x1b6: - case 0x1b7:WRITE8(addr, mach64->src_cntl, val); - break; + case 0x1b4: + case 0x1b5: + case 0x1b6: + case 0x1b7: + WRITE8(addr, mach64->src_cntl, val); + 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: - case 0x210: - case 0x211: - case 0x212: - case 0x213: - case 0x214: - case 0x215: - case 0x216: - case 0x217: - case 0x218: - case 0x219: - case 0x21a: - case 0x21b: - case 0x21c: - case 0x21d: - case 0x21e: - case 0x21f: - case 0x220: - case 0x221: - case 0x222: - case 0x223: - case 0x224: - case 0x225: - case 0x226: - case 0x227: - case 0x228: - case 0x229: - case 0x22a: - case 0x22b: - case 0x22c: - case 0x22d: - case 0x22e: - case 0x22f: - case 0x230: - case 0x231: - case 0x232: - case 0x233: - case 0x234: - case 0x235: - case 0x236: - case 0x237: - case 0x238: - case 0x239: - case 0x23a: - case 0x23b: - case 0x23c: - case 0x23d: - case 0x23e: - case 0x23f:mach64_blit(val, 8, mach64); - 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: + case 0x210: + case 0x211: + case 0x212: + case 0x213: + case 0x214: + case 0x215: + case 0x216: + case 0x217: + case 0x218: + case 0x219: + case 0x21a: + case 0x21b: + case 0x21c: + case 0x21d: + case 0x21e: + case 0x21f: + case 0x220: + case 0x221: + case 0x222: + case 0x223: + case 0x224: + case 0x225: + case 0x226: + case 0x227: + case 0x228: + case 0x229: + case 0x22a: + case 0x22b: + case 0x22c: + case 0x22d: + case 0x22e: + case 0x22f: + case 0x230: + case 0x231: + case 0x232: + case 0x233: + case 0x234: + case 0x235: + case 0x236: + case 0x237: + case 0x238: + case 0x239: + case 0x23a: + case 0x23b: + case 0x23c: + case 0x23d: + case 0x23e: + case 0x23f: + mach64_blit(val, 8, mach64); + break; - case 0x240: - case 0x241: - case 0x242: - case 0x243:WRITE8(addr, mach64->host_cntl, val); - break; + case 0x240: + case 0x241: + case 0x242: + case 0x243: + WRITE8(addr, mach64->host_cntl, val); + break; - case 0x280: - case 0x281: - case 0x282: - case 0x283:WRITE8(addr, mach64->pat_reg0, val); - break; - case 0x284: - case 0x285: - case 0x286: - case 0x287:WRITE8(addr, mach64->pat_reg1, val); - break; + case 0x280: + case 0x281: + case 0x282: + case 0x283: + WRITE8(addr, mach64->pat_reg0, val); + break; + case 0x284: + case 0x285: + case 0x286: + case 0x287: + WRITE8(addr, mach64->pat_reg1, val); + break; - case 0x2a0: - case 0x2a1: - case 0x2a8: - case 0x2a9:WRITE8(addr, mach64->sc_left_right, val); - break; - case 0x2a4: - case 0x2a5:addr += 2; - case 0x2aa: - case 0x2ab:WRITE8(addr, mach64->sc_left_right, val); - break; + case 0x2a0: + case 0x2a1: + case 0x2a8: + case 0x2a9: + WRITE8(addr, mach64->sc_left_right, val); + break; + case 0x2a4: + case 0x2a5: + addr += 2; + case 0x2aa: + case 0x2ab: + WRITE8(addr, mach64->sc_left_right, val); + break; - case 0x2ac: - case 0x2ad: - case 0x2b4: - case 0x2b5:WRITE8(addr, mach64->sc_top_bottom, val); - break; - case 0x2b0: - case 0x2b1:addr += 2; - case 0x2b6: - case 0x2b7:WRITE8(addr, mach64->sc_top_bottom, val); - break; + case 0x2ac: + case 0x2ad: + case 0x2b4: + case 0x2b5: + WRITE8(addr, mach64->sc_top_bottom, val); + break; + case 0x2b0: + case 0x2b1: + addr += 2; + case 0x2b6: + case 0x2b7: + WRITE8(addr, mach64->sc_top_bottom, val); + break; - case 0x2c0: - case 0x2c1: - case 0x2c2: - case 0x2c3:WRITE8(addr, mach64->dp_bkgd_clr, val); - break; - case 0x2c4: - case 0x2c5: - case 0x2c6: - case 0x2c7:WRITE8(addr, mach64->dp_frgd_clr, val); - break; + case 0x2c0: + case 0x2c1: + case 0x2c2: + case 0x2c3: + WRITE8(addr, mach64->dp_bkgd_clr, val); + break; + case 0x2c4: + case 0x2c5: + case 0x2c6: + case 0x2c7: + WRITE8(addr, mach64->dp_frgd_clr, val); + break; - case 0x2d0: - case 0x2d1: - case 0x2d2: - case 0x2d3:WRITE8(addr, mach64->dp_pix_width, val); - break; - case 0x2d4: - case 0x2d5: - case 0x2d6: - case 0x2d7:WRITE8(addr, mach64->dp_mix, val); - break; - case 0x2d8: - case 0x2d9: - case 0x2da: - case 0x2db:WRITE8(addr, mach64->dp_src, val); - break; + case 0x2d0: + case 0x2d1: + case 0x2d2: + case 0x2d3: + WRITE8(addr, mach64->dp_pix_width, val); + break; + case 0x2d4: + case 0x2d5: + case 0x2d6: + case 0x2d7: + WRITE8(addr, mach64->dp_mix, val); + break; + case 0x2d8: + case 0x2d9: + case 0x2da: + case 0x2db: + WRITE8(addr, mach64->dp_src, val); + break; - case 0x300: - case 0x301: - case 0x302: - case 0x303:WRITE8(addr, mach64->clr_cmp_clr, val); - break; - case 0x304: - case 0x305: - case 0x306: - case 0x307:WRITE8(addr, mach64->clr_cmp_mask, val); - break; - case 0x308: - case 0x309: - case 0x30a: - case 0x30b:WRITE8(addr, mach64->clr_cmp_cntl, val); - break; + case 0x300: + case 0x301: + case 0x302: + case 0x303: + WRITE8(addr, mach64->clr_cmp_clr, val); + break; + case 0x304: + case 0x305: + case 0x306: + case 0x307: + WRITE8(addr, mach64->clr_cmp_mask, val); + break; + case 0x308: + case 0x309: + case 0x30a: + case 0x30b: + WRITE8(addr, mach64->clr_cmp_cntl, val); + break; - case 0x320: - case 0x321: - case 0x322: - case 0x323:WRITE8(addr, mach64->context_mask, val); - break; + case 0x320: + case 0x321: + case 0x322: + case 0x323: + WRITE8(addr, mach64->context_mask, val); + break; - case 0x330: - case 0x331:WRITE8(addr, mach64->dst_cntl, val); - break; - case 0x332:WRITE8(addr - 2, mach64->src_cntl, val); - break; - case 0x333:WRITE8(addr - 3, mach64->pat_cntl, val & 7); - if (val & 0x10) - mach64->host_cntl |= HOST_BYTE_ALIGN; - else - mach64->host_cntl &= ~HOST_BYTE_ALIGN; - break; - } + case 0x330: + case 0x331: + WRITE8(addr, mach64->dst_cntl, val); + break; + case 0x332: + WRITE8(addr - 2, mach64->src_cntl, val); + break; + case 0x333: + WRITE8(addr - 3, mach64->pat_cntl, val & 7); + if (val & 0x10) + mach64->host_cntl |= HOST_BYTE_ALIGN; + else + mach64->host_cntl &= ~HOST_BYTE_ALIGN; + break; + } } static void mach64_accel_write_fifo_w(mach64_t *mach64, uint32_t addr, uint16_t val) { -// pclog("mach64_accel_write_fifo_w: addr=%08x val=%04x\n", addr, val); - switch (addr & 0x3fe) { - case 0x200: - case 0x202: - case 0x204: - case 0x206: - case 0x208: - case 0x20a: - case 0x20c: - case 0x20e: - case 0x210: - case 0x212: - case 0x214: - case 0x216: - case 0x218: - case 0x21a: - case 0x21c: - case 0x21e: - case 0x220: - case 0x222: - case 0x224: - case 0x226: - case 0x228: - case 0x22a: - case 0x22c: - case 0x22e: - case 0x230: - case 0x232: - case 0x234: - case 0x236: - case 0x238: - case 0x23a: - case 0x23c: - case 0x23e:mach64_blit(val, 16, mach64); - break; + // pclog("mach64_accel_write_fifo_w: addr=%08x val=%04x\n", addr, val); + switch (addr & 0x3fe) { + case 0x200: + case 0x202: + case 0x204: + case 0x206: + case 0x208: + case 0x20a: + case 0x20c: + case 0x20e: + case 0x210: + case 0x212: + case 0x214: + case 0x216: + case 0x218: + case 0x21a: + case 0x21c: + case 0x21e: + case 0x220: + case 0x222: + case 0x224: + case 0x226: + case 0x228: + case 0x22a: + case 0x22c: + case 0x22e: + case 0x230: + case 0x232: + case 0x234: + case 0x236: + case 0x238: + case 0x23a: + case 0x23c: + case 0x23e: + mach64_blit(val, 16, mach64); + break; - default: + default: #ifdef MACH64_DEBUG - pclog(" "); + pclog(" "); #endif - mach64_accel_write_fifo(mach64, addr, val); + mach64_accel_write_fifo(mach64, addr, val); #ifdef MACH64_DEBUG - pclog(" "); + pclog(" "); #endif - mach64_accel_write_fifo(mach64, addr + 1, val >> 8); - break; - } + mach64_accel_write_fifo(mach64, addr + 1, val >> 8); + break; + } } static void mach64_accel_write_fifo_l(mach64_t *mach64, uint32_t addr, uint32_t val) { -// pclog("mach64_accel_write_fifo_l: addr=%08x %02x val=%08x\n", addr, addr >> 2, val); - switch (addr & 0x3fc) { - case 0x32c:mach64->context_load_cntl = val; - if (val & 0x30000) - mach64_load_context(mach64); - break; + // pclog("mach64_accel_write_fifo_l: addr=%08x %02x val=%08x\n", addr, addr >> 2, val); + switch (addr & 0x3fc) { + case 0x32c: + mach64->context_load_cntl = val; + if (val & 0x30000) + mach64_load_context(mach64); + break; - case 0x200: - case 0x204: - case 0x208: - case 0x20c: - case 0x210: - case 0x214: - case 0x218: - case 0x21c: - case 0x220: - case 0x224: - case 0x228: - case 0x22c: - case 0x230: - case 0x234: - case 0x238: - case 0x23c: - if (mach64->accel.source_host || (mach64->dp_pix_width & DP_BYTE_PIX_ORDER)) - mach64_blit(val, 32, mach64); - else - mach64_blit(((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24), 32, mach64); - break; + case 0x200: + case 0x204: + case 0x208: + case 0x20c: + case 0x210: + case 0x214: + case 0x218: + case 0x21c: + case 0x220: + case 0x224: + case 0x228: + case 0x22c: + case 0x230: + case 0x234: + case 0x238: + case 0x23c: + if (mach64->accel.source_host || (mach64->dp_pix_width & DP_BYTE_PIX_ORDER)) + mach64_blit(val, 32, mach64); + else + mach64_blit(((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | + ((val & 0x000000ff) << 24), + 32, mach64); + break; - default: + default: #ifdef MACH64_DEBUG - pclog(" "); + pclog(" "); #endif - mach64_accel_write_fifo_w(mach64, addr, val); + mach64_accel_write_fifo_w(mach64, addr, val); #ifdef MACH64_DEBUG - pclog(" "); + pclog(" "); #endif - mach64_accel_write_fifo_w(mach64, addr + 2, val >> 16); - break; - } + mach64_accel_write_fifo_w(mach64, addr + 2, val >> 16); + break; + } } static void fifo_thread(void *param) { - mach64_t *mach64 = (mach64_t *)param; + mach64_t *mach64 = (mach64_t *)param; - while (1) { - thread_set_event(mach64->fifo_not_full_event); - thread_wait_event(mach64->wake_fifo_thread, -1); - thread_reset_event(mach64->wake_fifo_thread); - mach64->blitter_busy = 1; - while (!FIFO_EMPTY) { - uint64_t start_time = timer_read(); - uint64_t end_time; - fifo_entry_t *fifo = &mach64->fifo[mach64->fifo_read_idx & FIFO_MASK]; + while (1) { + thread_set_event(mach64->fifo_not_full_event); + thread_wait_event(mach64->wake_fifo_thread, -1); + thread_reset_event(mach64->wake_fifo_thread); + mach64->blitter_busy = 1; + while (!FIFO_EMPTY) { + uint64_t start_time = timer_read(); + uint64_t end_time; + fifo_entry_t *fifo = &mach64->fifo[mach64->fifo_read_idx & FIFO_MASK]; - switch (fifo->addr_type & FIFO_TYPE) { - case FIFO_WRITE_BYTE:mach64_accel_write_fifo(mach64, fifo->addr_type & FIFO_ADDR, fifo->val); - break; - case FIFO_WRITE_WORD:mach64_accel_write_fifo_w(mach64, fifo->addr_type & FIFO_ADDR, fifo->val); - break; - case FIFO_WRITE_DWORD:mach64_accel_write_fifo_l(mach64, fifo->addr_type & FIFO_ADDR, fifo->val); - break; - } + switch (fifo->addr_type & FIFO_TYPE) { + case FIFO_WRITE_BYTE: + mach64_accel_write_fifo(mach64, fifo->addr_type & FIFO_ADDR, fifo->val); + break; + case FIFO_WRITE_WORD: + mach64_accel_write_fifo_w(mach64, fifo->addr_type & FIFO_ADDR, fifo->val); + break; + case FIFO_WRITE_DWORD: + mach64_accel_write_fifo_l(mach64, fifo->addr_type & FIFO_ADDR, fifo->val); + break; + } - mach64->fifo_read_idx++; - fifo->addr_type = FIFO_INVALID; + mach64->fifo_read_idx++; + fifo->addr_type = FIFO_INVALID; - if (FIFO_ENTRIES > 0xe000) - thread_set_event(mach64->fifo_not_full_event); + if (FIFO_ENTRIES > 0xe000) + thread_set_event(mach64->fifo_not_full_event); - end_time = timer_read(); - mach64->blitter_time += end_time - start_time; - } - mach64->blitter_busy = 0; - } + end_time = timer_read(); + mach64->blitter_time += end_time - start_time; + } + mach64->blitter_busy = 0; + } } static void mach64_queue(mach64_t *mach64, uint32_t addr, uint32_t val, uint32_t type) { - fifo_entry_t *fifo = &mach64->fifo[mach64->fifo_write_idx & FIFO_MASK]; + fifo_entry_t *fifo = &mach64->fifo[mach64->fifo_write_idx & FIFO_MASK]; - if (FIFO_FULL) { - thread_reset_event(mach64->fifo_not_full_event); - if (FIFO_FULL) { - thread_wait_event(mach64->fifo_not_full_event, -1); /*Wait for room in ringbuffer*/ - } - } + if (FIFO_FULL) { + thread_reset_event(mach64->fifo_not_full_event); + if (FIFO_FULL) { + thread_wait_event(mach64->fifo_not_full_event, -1); /*Wait for room in ringbuffer*/ + } + } - fifo->val = val; - fifo->addr_type = (addr & FIFO_ADDR) | type; + fifo->val = val; + fifo->addr_type = (addr & FIFO_ADDR) | type; - mach64->fifo_write_idx++; + mach64->fifo_write_idx++; - if (FIFO_ENTRIES > 0xe000 || FIFO_ENTRIES < 8) - wake_fifo_thread(mach64); + if (FIFO_ENTRIES > 0xe000 || FIFO_ENTRIES < 8) + wake_fifo_thread(mach64); } void mach64_cursor_dump(mach64_t *mach64) { -/* pclog("Mach64 cursor :\n"); - pclog("Ena = %i X = %i Y = %i Addr = %05X Xoff = %i Yoff = %i\n", svga->hwcursor.ena, svga->hwcursor.x, svga->hwcursor.y, svga->hwcursor.addr, svga->hwcursor.xoff, svga->hwcursor.yoff);*/ + /* pclog("Mach64 cursor :\n"); + pclog("Ena = %i X = %i Y = %i Addr = %05X Xoff = %i Yoff = %i\n", svga->hwcursor.ena, svga->hwcursor.x, + svga->hwcursor.y, svga->hwcursor.addr, svga->hwcursor.xoff, svga->hwcursor.yoff);*/ } void mach64_start_fill(mach64_t *mach64) { - int x, y; + int x, y; - mach64->accel.dst_x = 0; - mach64->accel.dst_y = 0; - mach64->accel.dst_x_start = (mach64->dst_y_x >> 16) & 0xfff; - mach64->accel.dst_y_start = mach64->dst_y_x & 0xfff; + mach64->accel.dst_x = 0; + mach64->accel.dst_y = 0; + mach64->accel.dst_x_start = (mach64->dst_y_x >> 16) & 0xfff; + mach64->accel.dst_y_start = mach64->dst_y_x & 0xfff; - mach64->accel.dst_width = (mach64->dst_height_width >> 16) & 0x1fff; - mach64->accel.dst_height = mach64->dst_height_width & 0x1fff; - mach64->accel.x_count = mach64->accel.dst_width; + mach64->accel.dst_width = (mach64->dst_height_width >> 16) & 0x1fff; + mach64->accel.dst_height = mach64->dst_height_width & 0x1fff; + mach64->accel.x_count = mach64->accel.dst_width; - mach64->accel.src_x = 0; - mach64->accel.src_y = 0; - mach64->accel.src_x_start = (mach64->src_y_x >> 16) & 0xfff; - mach64->accel.src_y_start = mach64->src_y_x & 0xfff; - if (mach64->src_cntl & SRC_LINEAR_EN) - mach64->accel.src_x_count = 0x7ffffff; /*Essentially infinite*/ - else - mach64->accel.src_x_count = (mach64->src_height1_width1 >> 16) & 0x7fff; - if (!(mach64->src_cntl & SRC_PATT_EN)) - mach64->accel.src_y_count = 0x7ffffff; /*Essentially infinite*/ - else - mach64->accel.src_y_count = mach64->src_height1_width1 & 0x1fff; - - mach64->accel.src_width1 = (mach64->src_height1_width1 >> 16) & 0x7fff; - mach64->accel.src_height1 = mach64->src_height1_width1 & 0x1fff; - mach64->accel.src_width2 = (mach64->src_height2_width2 >> 16) & 0x7fff; - mach64->accel.src_height2 = mach64->src_height2_width2 & 0x1fff; - -#ifdef MACH64_DEBUG - pclog("src %i %i %i %i %08X %08X\n", mach64->accel.src_x_count, - mach64->accel.src_y_count, - mach64->accel.src_width1, - mach64->accel.src_height1, - mach64->src_height1_width1, - mach64->src_height2_width2); -#endif - - mach64->accel.src_pitch = (mach64->src_off_pitch >> 22) * 8; - mach64->accel.src_offset = (mach64->src_off_pitch & 0xfffff) * 8; - - mach64->accel.dst_pitch = (mach64->dst_off_pitch >> 22) * 8; - mach64->accel.dst_offset = (mach64->dst_off_pitch & 0xfffff) * 8; - - mach64->accel.mix_fg = (mach64->dp_mix >> 16) & 0x1f; - mach64->accel.mix_bg = mach64->dp_mix & 0x1f; - - mach64->accel.source_bg = mach64->dp_src & 7; - mach64->accel.source_fg = (mach64->dp_src >> 8) & 7; - mach64->accel.source_mix = (mach64->dp_src >> 16) & 7; - - mach64->accel.dst_pix_width = mach64->dp_pix_width & 7; - mach64->accel.src_pix_width = (mach64->dp_pix_width >> 8) & 7; - mach64->accel.host_pix_width = (mach64->dp_pix_width >> 16) & 7; - - mach64->accel.dst_size = mach64_width[mach64->accel.dst_pix_width]; - mach64->accel.src_size = mach64_width[mach64->accel.src_pix_width]; - mach64->accel.host_size = mach64_width[mach64->accel.host_pix_width]; - -/* mach64->accel.src_x *= mach64_inc[mach64->accel.src_pix_width]; - mach64->accel.src_pitch *= mach64_inc[mach64->accel.src_pix_width]; - mach64->accel.dst_x *= mach64_inc[mach64->accel.dst_pix_width]; - mach64->accel.dst_pitch *= mach64_inc[mach64->accel.dst_pix_width];*/ - - if (mach64->accel.src_size == WIDTH_1BIT) - mach64->accel.src_offset <<= 3; - else - mach64->accel.src_offset >>= mach64->accel.src_size; - - if (mach64->accel.dst_size == WIDTH_1BIT) - mach64->accel.dst_offset <<= 3; - else - mach64->accel.dst_offset >>= mach64->accel.dst_size; - -/* if (mach64->accel.source_fg == SRC_BLITSRC || mach64->accel.source_bg == SRC_BLITSRC) - {*/ - mach64->accel.xinc = (mach64->dst_cntl & DST_X_DIR) ? 1 : -1; - mach64->accel.yinc = (mach64->dst_cntl & DST_Y_DIR) ? 1 : -1; -/* } + mach64->accel.src_x = 0; + mach64->accel.src_y = 0; + mach64->accel.src_x_start = (mach64->src_y_x >> 16) & 0xfff; + mach64->accel.src_y_start = mach64->src_y_x & 0xfff; + if (mach64->src_cntl & SRC_LINEAR_EN) + mach64->accel.src_x_count = 0x7ffffff; /*Essentially infinite*/ else - { - mach64->accel.xinc = mach64_inc[mach64->accel.src_pix_width]; - mach64->accel.yinc = 1; - }*/ + mach64->accel.src_x_count = (mach64->src_height1_width1 >> 16) & 0x7fff; + if (!(mach64->src_cntl & SRC_PATT_EN)) + mach64->accel.src_y_count = 0x7ffffff; /*Essentially infinite*/ + else + mach64->accel.src_y_count = mach64->src_height1_width1 & 0x1fff; - mach64->accel.source_host = ((mach64->dp_src & 7) == SRC_HOST) || (((mach64->dp_src >> 8) & 7) == SRC_HOST); + mach64->accel.src_width1 = (mach64->src_height1_width1 >> 16) & 0x7fff; + mach64->accel.src_height1 = mach64->src_height1_width1 & 0x1fff; + mach64->accel.src_width2 = (mach64->src_height2_width2 >> 16) & 0x7fff; + mach64->accel.src_height2 = mach64->src_height2_width2 & 0x1fff; - -// pclog("mach64_start_fill : pattern %08X %08X\n", mach64->pat_reg0, mach64->pat_reg1); - for (y = 0; y < 8; y++) { - for (x = 0; x < 8; x++) { - uint32_t temp = (y & 4) ? mach64->pat_reg1 : mach64->pat_reg0; - mach64->accel.pattern[y][x] = (temp >> (x + ((y & 3) * 8))) & 1; -// pclog("%i ", mach64->accel.pattern[y][x]); - } -// pclog("\n"); - } - - mach64->accel.sc_left = mach64->sc_left_right & 0x1fff; - mach64->accel.sc_right = (mach64->sc_left_right >> 16) & 0x1fff; - mach64->accel.sc_top = mach64->sc_top_bottom & 0x7fff; - mach64->accel.sc_bottom = (mach64->sc_top_bottom >> 16) & 0x7fff; - -/* mach64->accel.sc_left *= mach64_inc[mach64->accel.dst_pix_width]; - mach64->accel.sc_right *= mach64_inc[mach64->accel.dst_pix_width];*/ - - mach64->accel.dp_frgd_clr = mach64->dp_frgd_clr; - mach64->accel.dp_bkgd_clr = mach64->dp_bkgd_clr; - - mach64->accel.clr_cmp_clr = mach64->clr_cmp_clr & mach64->clr_cmp_mask; - mach64->accel.clr_cmp_mask = mach64->clr_cmp_mask; - mach64->accel.clr_cmp_fn = mach64->clr_cmp_cntl & 7; - mach64->accel.clr_cmp_src = mach64->clr_cmp_cntl & (1 << 24); - - mach64->accel.poly_draw = 0; - - mach64->accel.busy = 1; #ifdef MACH64_DEBUG - pclog("mach64_start_fill : dst %i, %i src %i, %i size %i, %i src pitch %i offset %X dst pitch %i offset %X scissor %i %i %i %i src_fg %i mix %02X %02X\n", mach64->accel.dst_x_start, mach64->accel.dst_y_start, mach64->accel.src_x_start, mach64->accel.src_y_start, mach64->accel.dst_width, mach64->accel.dst_height, mach64->accel.src_pitch, mach64->accel.src_offset, mach64->accel.dst_pitch, mach64->accel.dst_offset, mach64->accel.sc_left, mach64->accel.sc_right, mach64->accel.sc_top, mach64->accel.sc_bottom, mach64->accel.source_fg, mach64->accel.mix_fg, mach64->accel.mix_bg); + pclog("src %i %i %i %i %08X %08X\n", mach64->accel.src_x_count, mach64->accel.src_y_count, mach64->accel.src_width1, + mach64->accel.src_height1, mach64->src_height1_width1, mach64->src_height2_width2); #endif - mach64->accel.op = OP_RECT; + + mach64->accel.src_pitch = (mach64->src_off_pitch >> 22) * 8; + mach64->accel.src_offset = (mach64->src_off_pitch & 0xfffff) * 8; + + mach64->accel.dst_pitch = (mach64->dst_off_pitch >> 22) * 8; + mach64->accel.dst_offset = (mach64->dst_off_pitch & 0xfffff) * 8; + + mach64->accel.mix_fg = (mach64->dp_mix >> 16) & 0x1f; + mach64->accel.mix_bg = mach64->dp_mix & 0x1f; + + mach64->accel.source_bg = mach64->dp_src & 7; + mach64->accel.source_fg = (mach64->dp_src >> 8) & 7; + mach64->accel.source_mix = (mach64->dp_src >> 16) & 7; + + mach64->accel.dst_pix_width = mach64->dp_pix_width & 7; + mach64->accel.src_pix_width = (mach64->dp_pix_width >> 8) & 7; + mach64->accel.host_pix_width = (mach64->dp_pix_width >> 16) & 7; + + mach64->accel.dst_size = mach64_width[mach64->accel.dst_pix_width]; + mach64->accel.src_size = mach64_width[mach64->accel.src_pix_width]; + mach64->accel.host_size = mach64_width[mach64->accel.host_pix_width]; + + /* mach64->accel.src_x *= mach64_inc[mach64->accel.src_pix_width]; + mach64->accel.src_pitch *= mach64_inc[mach64->accel.src_pix_width]; + mach64->accel.dst_x *= mach64_inc[mach64->accel.dst_pix_width]; + mach64->accel.dst_pitch *= mach64_inc[mach64->accel.dst_pix_width];*/ + + if (mach64->accel.src_size == WIDTH_1BIT) + mach64->accel.src_offset <<= 3; + else + mach64->accel.src_offset >>= mach64->accel.src_size; + + if (mach64->accel.dst_size == WIDTH_1BIT) + mach64->accel.dst_offset <<= 3; + else + mach64->accel.dst_offset >>= mach64->accel.dst_size; + + /* if (mach64->accel.source_fg == SRC_BLITSRC || mach64->accel.source_bg == SRC_BLITSRC) + {*/ + mach64->accel.xinc = (mach64->dst_cntl & DST_X_DIR) ? 1 : -1; + mach64->accel.yinc = (mach64->dst_cntl & DST_Y_DIR) ? 1 : -1; + /* } + else + { + mach64->accel.xinc = mach64_inc[mach64->accel.src_pix_width]; + mach64->accel.yinc = 1; + }*/ + + mach64->accel.source_host = ((mach64->dp_src & 7) == SRC_HOST) || (((mach64->dp_src >> 8) & 7) == SRC_HOST); + + // pclog("mach64_start_fill : pattern %08X %08X\n", mach64->pat_reg0, mach64->pat_reg1); + for (y = 0; y < 8; y++) { + for (x = 0; x < 8; x++) { + uint32_t temp = (y & 4) ? mach64->pat_reg1 : mach64->pat_reg0; + mach64->accel.pattern[y][x] = (temp >> (x + ((y & 3) * 8))) & 1; + // pclog("%i ", mach64->accel.pattern[y][x]); + } + // pclog("\n"); + } + + mach64->accel.sc_left = mach64->sc_left_right & 0x1fff; + mach64->accel.sc_right = (mach64->sc_left_right >> 16) & 0x1fff; + mach64->accel.sc_top = mach64->sc_top_bottom & 0x7fff; + mach64->accel.sc_bottom = (mach64->sc_top_bottom >> 16) & 0x7fff; + + /* mach64->accel.sc_left *= mach64_inc[mach64->accel.dst_pix_width]; + mach64->accel.sc_right *= mach64_inc[mach64->accel.dst_pix_width];*/ + + mach64->accel.dp_frgd_clr = mach64->dp_frgd_clr; + mach64->accel.dp_bkgd_clr = mach64->dp_bkgd_clr; + + mach64->accel.clr_cmp_clr = mach64->clr_cmp_clr & mach64->clr_cmp_mask; + mach64->accel.clr_cmp_mask = mach64->clr_cmp_mask; + mach64->accel.clr_cmp_fn = mach64->clr_cmp_cntl & 7; + mach64->accel.clr_cmp_src = mach64->clr_cmp_cntl & (1 << 24); + + mach64->accel.poly_draw = 0; + + mach64->accel.busy = 1; +#ifdef MACH64_DEBUG + pclog("mach64_start_fill : dst %i, %i src %i, %i size %i, %i src pitch %i offset %X dst pitch %i offset %X scissor " + "%i %i %i %i src_fg %i mix %02X %02X\n", + mach64->accel.dst_x_start, mach64->accel.dst_y_start, mach64->accel.src_x_start, mach64->accel.src_y_start, + mach64->accel.dst_width, mach64->accel.dst_height, mach64->accel.src_pitch, mach64->accel.src_offset, + mach64->accel.dst_pitch, mach64->accel.dst_offset, mach64->accel.sc_left, mach64->accel.sc_right, + mach64->accel.sc_top, mach64->accel.sc_bottom, mach64->accel.source_fg, mach64->accel.mix_fg, mach64->accel.mix_bg); +#endif + mach64->accel.op = OP_RECT; } void mach64_start_line(mach64_t *mach64) { - int x, y; + int x, y; - mach64->accel.dst_x = (mach64->dst_y_x >> 16) & 0xfff; - mach64->accel.dst_y = mach64->dst_y_x & 0xfff; + mach64->accel.dst_x = (mach64->dst_y_x >> 16) & 0xfff; + mach64->accel.dst_y = mach64->dst_y_x & 0xfff; - mach64->accel.src_x = (mach64->src_y_x >> 16) & 0xfff; - mach64->accel.src_y = mach64->src_y_x & 0xfff; + mach64->accel.src_x = (mach64->src_y_x >> 16) & 0xfff; + mach64->accel.src_y = mach64->src_y_x & 0xfff; - mach64->accel.src_pitch = (mach64->src_off_pitch >> 22) * 8; - mach64->accel.src_offset = (mach64->src_off_pitch & 0xfffff) * 8; + mach64->accel.src_pitch = (mach64->src_off_pitch >> 22) * 8; + mach64->accel.src_offset = (mach64->src_off_pitch & 0xfffff) * 8; - mach64->accel.dst_pitch = (mach64->dst_off_pitch >> 22) * 8; - mach64->accel.dst_offset = (mach64->dst_off_pitch & 0xfffff) * 8; + mach64->accel.dst_pitch = (mach64->dst_off_pitch >> 22) * 8; + mach64->accel.dst_offset = (mach64->dst_off_pitch & 0xfffff) * 8; - mach64->accel.mix_fg = (mach64->dp_mix >> 16) & 0x1f; - mach64->accel.mix_bg = mach64->dp_mix & 0x1f; + mach64->accel.mix_fg = (mach64->dp_mix >> 16) & 0x1f; + mach64->accel.mix_bg = mach64->dp_mix & 0x1f; - mach64->accel.source_bg = mach64->dp_src & 7; - mach64->accel.source_fg = (mach64->dp_src >> 8) & 7; - mach64->accel.source_mix = (mach64->dp_src >> 16) & 7; + mach64->accel.source_bg = mach64->dp_src & 7; + mach64->accel.source_fg = (mach64->dp_src >> 8) & 7; + mach64->accel.source_mix = (mach64->dp_src >> 16) & 7; - mach64->accel.dst_pix_width = mach64->dp_pix_width & 7; - mach64->accel.src_pix_width = (mach64->dp_pix_width >> 8) & 7; - mach64->accel.host_pix_width = (mach64->dp_pix_width >> 16) & 7; + mach64->accel.dst_pix_width = mach64->dp_pix_width & 7; + mach64->accel.src_pix_width = (mach64->dp_pix_width >> 8) & 7; + mach64->accel.host_pix_width = (mach64->dp_pix_width >> 16) & 7; - mach64->accel.dst_size = mach64_width[mach64->accel.dst_pix_width]; - mach64->accel.src_size = mach64_width[mach64->accel.src_pix_width]; - mach64->accel.host_size = mach64_width[mach64->accel.host_pix_width]; + mach64->accel.dst_size = mach64_width[mach64->accel.dst_pix_width]; + mach64->accel.src_size = mach64_width[mach64->accel.src_pix_width]; + mach64->accel.host_size = mach64_width[mach64->accel.host_pix_width]; - if (mach64->accel.src_size == WIDTH_1BIT) - mach64->accel.src_offset <<= 3; - else - mach64->accel.src_offset >>= mach64->accel.src_size; + if (mach64->accel.src_size == WIDTH_1BIT) + mach64->accel.src_offset <<= 3; + else + mach64->accel.src_offset >>= mach64->accel.src_size; - if (mach64->accel.dst_size == WIDTH_1BIT) - mach64->accel.dst_offset <<= 3; - else - mach64->accel.dst_offset >>= mach64->accel.dst_size; + if (mach64->accel.dst_size == WIDTH_1BIT) + mach64->accel.dst_offset <<= 3; + else + mach64->accel.dst_offset >>= mach64->accel.dst_size; -/* mach64->accel.src_pitch *= mach64_inc[mach64->accel.src_pix_width]; - mach64->accel.dst_pitch *= mach64_inc[mach64->accel.dst_pix_width];*/ + /* mach64->accel.src_pitch *= mach64_inc[mach64->accel.src_pix_width]; + mach64->accel.dst_pitch *= mach64_inc[mach64->accel.dst_pix_width];*/ - mach64->accel.source_host = ((mach64->dp_src & 7) == SRC_HOST) || (((mach64->dp_src >> 8) & 7) == SRC_HOST); + mach64->accel.source_host = ((mach64->dp_src & 7) == SRC_HOST) || (((mach64->dp_src >> 8) & 7) == SRC_HOST); - for (y = 0; y < 8; y++) { - for (x = 0; x < 8; x++) { - uint32_t temp = (y & 4) ? mach64->pat_reg1 : mach64->pat_reg0; - mach64->accel.pattern[y][x] = (temp >> (x + ((y & 3) * 8))) & 1; - } - } + for (y = 0; y < 8; y++) { + for (x = 0; x < 8; x++) { + uint32_t temp = (y & 4) ? mach64->pat_reg1 : mach64->pat_reg0; + mach64->accel.pattern[y][x] = (temp >> (x + ((y & 3) * 8))) & 1; + } + } - mach64->accel.sc_left = mach64->sc_left_right & 0x1fff; - mach64->accel.sc_right = (mach64->sc_left_right >> 16) & 0x1fff; - mach64->accel.sc_top = mach64->sc_top_bottom & 0x7fff; - mach64->accel.sc_bottom = (mach64->sc_top_bottom >> 16) & 0x7fff; + mach64->accel.sc_left = mach64->sc_left_right & 0x1fff; + mach64->accel.sc_right = (mach64->sc_left_right >> 16) & 0x1fff; + mach64->accel.sc_top = mach64->sc_top_bottom & 0x7fff; + mach64->accel.sc_bottom = (mach64->sc_top_bottom >> 16) & 0x7fff; - mach64->accel.dp_frgd_clr = mach64->dp_frgd_clr; - mach64->accel.dp_bkgd_clr = mach64->dp_bkgd_clr; + mach64->accel.dp_frgd_clr = mach64->dp_frgd_clr; + mach64->accel.dp_bkgd_clr = mach64->dp_bkgd_clr; - mach64->accel.x_count = mach64->dst_bres_lnth & 0x7fff; - mach64->accel.err = (mach64->dst_bres_err & 0x3ffff) | ((mach64->dst_bres_err & 0x40000) ? 0xfffc0000 : 0); + mach64->accel.x_count = mach64->dst_bres_lnth & 0x7fff; + mach64->accel.err = (mach64->dst_bres_err & 0x3ffff) | ((mach64->dst_bres_err & 0x40000) ? 0xfffc0000 : 0); - mach64->accel.clr_cmp_clr = mach64->clr_cmp_clr & mach64->clr_cmp_mask; - mach64->accel.clr_cmp_mask = mach64->clr_cmp_mask; - mach64->accel.clr_cmp_fn = mach64->clr_cmp_cntl & 7; - mach64->accel.clr_cmp_src = mach64->clr_cmp_cntl & (1 << 24); + mach64->accel.clr_cmp_clr = mach64->clr_cmp_clr & mach64->clr_cmp_mask; + mach64->accel.clr_cmp_mask = mach64->clr_cmp_mask; + mach64->accel.clr_cmp_fn = mach64->clr_cmp_cntl & 7; + mach64->accel.clr_cmp_src = mach64->clr_cmp_cntl & (1 << 24); - mach64->accel.busy = 1; + mach64->accel.busy = 1; #ifdef MACH64_DEBUG - pclog("mach64_start_line\n"); + pclog("mach64_start_line\n"); #endif - mach64->accel.op = OP_LINE; + mach64->accel.op = OP_LINE; } -#define READ(addr, dat, width) if (width == 0) dat = svga->vram[((addr)) & mach64->vram_mask]; \ - else if (width == 1) dat = *(uint16_t *)&svga->vram[((addr) << 1) & mach64->vram_mask]; \ - else if (width == 2) dat = *(uint32_t *)&svga->vram[((addr) << 2) & mach64->vram_mask]; \ - else dat = (svga->vram[((addr) >> 3) & mach64->vram_mask] >> ((addr) & 7)) & 1; +#define READ(addr, dat, width) \ + if (width == 0) \ + dat = svga->vram[((addr)) & mach64->vram_mask]; \ + else if (width == 1) \ + dat = *(uint16_t *)&svga->vram[((addr) << 1) & mach64->vram_mask]; \ + else if (width == 2) \ + dat = *(uint32_t *)&svga->vram[((addr) << 2) & mach64->vram_mask]; \ + else \ + dat = (svga->vram[((addr) >> 3) & mach64->vram_mask] >> ((addr)&7)) & 1; -#define MIX switch (mix ? mach64->accel.mix_fg : mach64->accel.mix_bg) \ - { \ - case 0x0: dest_dat = ~dest_dat; break; \ - case 0x1: dest_dat = 0; break; \ - case 0x2: dest_dat = 0xffffffff; break; \ - case 0x3: dest_dat = dest_dat; break; \ - case 0x4: dest_dat = ~src_dat; break; \ - case 0x5: dest_dat = src_dat ^ dest_dat; break; \ - case 0x6: dest_dat = ~(src_dat ^ dest_dat); break; \ - case 0x7: dest_dat = src_dat; break; \ - case 0x8: dest_dat = ~(src_dat & dest_dat); break; \ - case 0x9: dest_dat = ~src_dat | dest_dat; break; \ - case 0xa: dest_dat = src_dat | ~dest_dat; break; \ - case 0xb: dest_dat = src_dat | dest_dat; break; \ - case 0xc: dest_dat = src_dat & dest_dat; break; \ - case 0xd: dest_dat = src_dat & ~dest_dat; break; \ - case 0xe: dest_dat = ~src_dat & dest_dat; break; \ - case 0xf: dest_dat = ~(src_dat | dest_dat); break; \ - } +#define MIX \ + switch (mix ? mach64->accel.mix_fg : mach64->accel.mix_bg) { \ + case 0x0: \ + dest_dat = ~dest_dat; \ + break; \ + case 0x1: \ + dest_dat = 0; \ + break; \ + case 0x2: \ + dest_dat = 0xffffffff; \ + break; \ + case 0x3: \ + dest_dat = dest_dat; \ + break; \ + case 0x4: \ + dest_dat = ~src_dat; \ + break; \ + case 0x5: \ + dest_dat = src_dat ^ dest_dat; \ + break; \ + case 0x6: \ + dest_dat = ~(src_dat ^ dest_dat); \ + break; \ + case 0x7: \ + dest_dat = src_dat; \ + break; \ + case 0x8: \ + dest_dat = ~(src_dat & dest_dat); \ + break; \ + case 0x9: \ + dest_dat = ~src_dat | dest_dat; \ + break; \ + case 0xa: \ + dest_dat = src_dat | ~dest_dat; \ + break; \ + case 0xb: \ + dest_dat = src_dat | dest_dat; \ + break; \ + case 0xc: \ + dest_dat = src_dat & dest_dat; \ + break; \ + case 0xd: \ + dest_dat = src_dat & ~dest_dat; \ + break; \ + case 0xe: \ + dest_dat = ~src_dat & dest_dat; \ + break; \ + case 0xf: \ + dest_dat = ~(src_dat | dest_dat); \ + break; \ + } -#define WRITE(addr, width) if (width == 0) \ - { \ - svga->vram[(addr) & mach64->vram_mask] = dest_dat; \ - svga->changedvram[((addr) & mach64->vram_mask) >> 12] = changeframecount; \ - } \ - else if (width == 1) \ - { \ - *(uint16_t *)&svga->vram[((addr) << 1) & mach64->vram_mask] = dest_dat; \ - svga->changedvram[(((addr) << 1) & mach64->vram_mask) >> 12] = changeframecount; \ - } \ - else if (width == 2) \ - { \ - *(uint32_t *)&svga->vram[((addr) << 2) & mach64->vram_mask] = dest_dat; \ - svga->changedvram[(((addr) << 2) & mach64->vram_mask) >> 12] = changeframecount; \ - } \ - else \ - { \ - if (dest_dat & 1) \ - svga->vram[((addr) >> 3) & mach64->vram_mask] |= 1 << ((addr) & 7); \ - else \ - svga->vram[((addr) >> 3) & mach64->vram_mask] &= ~(1 << ((addr) & 7)); \ - svga->changedvram[(((addr) >> 3) & mach64->vram_mask) >> 12] = changeframecount; \ - } +#define WRITE(addr, width) \ + if (width == 0) { \ + svga->vram[(addr)&mach64->vram_mask] = dest_dat; \ + svga->changedvram[((addr)&mach64->vram_mask) >> 12] = changeframecount; \ + } else if (width == 1) { \ + *(uint16_t *)&svga->vram[((addr) << 1) & mach64->vram_mask] = dest_dat; \ + svga->changedvram[(((addr) << 1) & mach64->vram_mask) >> 12] = changeframecount; \ + } else if (width == 2) { \ + *(uint32_t *)&svga->vram[((addr) << 2) & mach64->vram_mask] = dest_dat; \ + svga->changedvram[(((addr) << 2) & mach64->vram_mask) >> 12] = changeframecount; \ + } else { \ + if (dest_dat & 1) \ + svga->vram[((addr) >> 3) & mach64->vram_mask] |= 1 << ((addr)&7); \ + else \ + svga->vram[((addr) >> 3) & mach64->vram_mask] &= ~(1 << ((addr)&7)); \ + svga->changedvram[(((addr) >> 3) & mach64->vram_mask) >> 12] = changeframecount; \ + } void mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) { - svga_t *svga = &mach64->svga; - int cmp_clr = 0; + svga_t *svga = &mach64->svga; + int cmp_clr = 0; - if (!mach64->accel.busy) { + if (!mach64->accel.busy) { #ifdef MACH64_DEBUG - pclog("mach64_blit : return as not busy\n"); + pclog("mach64_blit : return as not busy\n"); #endif - return; - } - switch (mach64->accel.op) { - case OP_RECT: - while (count) { - uint32_t src_dat, dest_dat; - uint32_t host_dat = 0; - int mix = 0; - int dst_x = (mach64->accel.dst_x + mach64->accel.dst_x_start) & 0xfff; - int dst_y = (mach64->accel.dst_y + mach64->accel.dst_y_start) & 0xfff; - int src_x; - int src_y = (mach64->accel.src_y + mach64->accel.src_y_start) & 0xfff; + return; + } + switch (mach64->accel.op) { + case OP_RECT: + while (count) { + uint32_t src_dat, dest_dat; + uint32_t host_dat = 0; + int mix = 0; + int dst_x = (mach64->accel.dst_x + mach64->accel.dst_x_start) & 0xfff; + int dst_y = (mach64->accel.dst_y + mach64->accel.dst_y_start) & 0xfff; + int src_x; + int src_y = (mach64->accel.src_y + mach64->accel.src_y_start) & 0xfff; - if (mach64->src_cntl & SRC_LINEAR_EN) - src_x = mach64->accel.src_x; - else - src_x = (mach64->accel.src_x + mach64->accel.src_x_start) & 0xfff; + if (mach64->src_cntl & SRC_LINEAR_EN) + src_x = mach64->accel.src_x; + else + src_x = (mach64->accel.src_x + mach64->accel.src_x_start) & 0xfff; - if (mach64->accel.source_host) { - host_dat = cpu_dat; - switch (mach64->accel.host_size) { - case 0:cpu_dat >>= 8; - count -= 8; - break; - case 1:cpu_dat >>= 16; - count -= 16; - break; - case 2:count -= 32; - break; - } - } else - count--; + if (mach64->accel.source_host) { + host_dat = cpu_dat; + switch (mach64->accel.host_size) { + case 0: + cpu_dat >>= 8; + count -= 8; + break; + case 1: + cpu_dat >>= 16; + count -= 16; + break; + case 2: + count -= 32; + break; + } + } else + count--; - switch (mach64->accel.source_mix) { - case MONO_SRC_HOST: - if (mach64->dp_pix_width & DP_BYTE_PIX_ORDER) { - mix = cpu_dat & 1; - cpu_dat >>= 1; - } else { - mix = cpu_dat >> 31; - cpu_dat <<= 1; - } - break; - case MONO_SRC_PAT:mix = mach64->accel.pattern[dst_y & 7][dst_x & 7]; - break; - case MONO_SRC_1:mix = 1; - break; - case MONO_SRC_BLITSRC: - if (mach64->src_cntl & SRC_LINEAR_EN) { - READ(mach64->accel.src_offset + src_x, mix, WIDTH_1BIT); - } else { - READ(mach64->accel.src_offset + (src_y * mach64->accel.src_pitch) + src_x, mix, WIDTH_1BIT); - } - break; - } + switch (mach64->accel.source_mix) { + case MONO_SRC_HOST: + if (mach64->dp_pix_width & DP_BYTE_PIX_ORDER) { + mix = cpu_dat & 1; + cpu_dat >>= 1; + } else { + mix = cpu_dat >> 31; + cpu_dat <<= 1; + } + break; + case MONO_SRC_PAT: + mix = mach64->accel.pattern[dst_y & 7][dst_x & 7]; + break; + case MONO_SRC_1: + mix = 1; + break; + case MONO_SRC_BLITSRC: + if (mach64->src_cntl & SRC_LINEAR_EN) { + READ(mach64->accel.src_offset + src_x, mix, WIDTH_1BIT); + } else { + READ(mach64->accel.src_offset + (src_y * mach64->accel.src_pitch) + src_x, mix, + WIDTH_1BIT); + } + break; + } - if (dst_x >= mach64->accel.sc_left && dst_x <= mach64->accel.sc_right && - dst_y >= mach64->accel.sc_top && dst_y <= mach64->accel.sc_bottom) { - switch (mix ? mach64->accel.source_fg : mach64->accel.source_bg) { - case SRC_HOST:src_dat = host_dat; - break; - case SRC_BLITSRC:READ(mach64->accel.src_offset + (src_y * mach64->accel.src_pitch) + src_x, src_dat, mach64->accel.src_size); - break; - case SRC_FG:src_dat = mach64->accel.dp_frgd_clr; - break; - case SRC_BG:src_dat = mach64->accel.dp_bkgd_clr; - break; - default:src_dat = 0; - break; - } - if (mach64->dst_cntl & DST_POLYGON_EN) { - int poly_src; - READ(mach64->accel.src_offset + (src_y * mach64->accel.src_pitch) + src_x, poly_src, mach64->accel.src_size); - if (poly_src) - mach64->accel.poly_draw = !mach64->accel.poly_draw; - } - if (!(mach64->dst_cntl & DST_POLYGON_EN) || mach64->accel.poly_draw) { - READ(mach64->accel.dst_offset + (dst_y * mach64->accel.dst_pitch) + dst_x, dest_dat, mach64->accel.dst_size); + if (dst_x >= mach64->accel.sc_left && dst_x <= mach64->accel.sc_right && dst_y >= mach64->accel.sc_top && + dst_y <= mach64->accel.sc_bottom) { + switch (mix ? mach64->accel.source_fg : mach64->accel.source_bg) { + case SRC_HOST: + src_dat = host_dat; + break; + case SRC_BLITSRC: + READ(mach64->accel.src_offset + (src_y * mach64->accel.src_pitch) + src_x, src_dat, + mach64->accel.src_size); + break; + case SRC_FG: + src_dat = mach64->accel.dp_frgd_clr; + break; + case SRC_BG: + src_dat = mach64->accel.dp_bkgd_clr; + break; + default: + src_dat = 0; + break; + } + if (mach64->dst_cntl & DST_POLYGON_EN) { + int poly_src; + READ(mach64->accel.src_offset + (src_y * mach64->accel.src_pitch) + src_x, poly_src, + mach64->accel.src_size); + if (poly_src) + mach64->accel.poly_draw = !mach64->accel.poly_draw; + } + if (!(mach64->dst_cntl & DST_POLYGON_EN) || mach64->accel.poly_draw) { + READ(mach64->accel.dst_offset + (dst_y * mach64->accel.dst_pitch) + dst_x, dest_dat, + mach64->accel.dst_size); - switch (mach64->accel.clr_cmp_fn) { - case 1: /*TRUE*/ - cmp_clr = 1; - break; - case 4: /*DST_CLR != CLR_CMP_CLR*/ - cmp_clr = (((mach64->accel.clr_cmp_src) ? src_dat : dest_dat) & mach64->accel.clr_cmp_mask) != mach64->accel.clr_cmp_clr; - break; - case 5: /*DST_CLR == CLR_CMP_CLR*/ - cmp_clr = (((mach64->accel.clr_cmp_src) ? src_dat : dest_dat) & mach64->accel.clr_cmp_mask) == mach64->accel.clr_cmp_clr; - break; - } + switch (mach64->accel.clr_cmp_fn) { + case 1: /*TRUE*/ + cmp_clr = 1; + break; + case 4: /*DST_CLR != CLR_CMP_CLR*/ + cmp_clr = (((mach64->accel.clr_cmp_src) ? src_dat : dest_dat) & + mach64->accel.clr_cmp_mask) != mach64->accel.clr_cmp_clr; + break; + case 5: /*DST_CLR == CLR_CMP_CLR*/ + cmp_clr = (((mach64->accel.clr_cmp_src) ? src_dat : dest_dat) & + mach64->accel.clr_cmp_mask) == mach64->accel.clr_cmp_clr; + break; + } - if (!cmp_clr) - MIX + if (!cmp_clr) + MIX - WRITE(mach64->accel.dst_offset + (dst_y * mach64->accel.dst_pitch) + dst_x, mach64->accel.dst_size); - } - } + WRITE(mach64->accel.dst_offset + (dst_y * mach64->accel.dst_pitch) + + dst_x, + mach64->accel.dst_size); + } + } - if (mach64->dst_cntl & DST_24_ROT_EN) { - mach64->accel.dp_frgd_clr = ((mach64->accel.dp_frgd_clr >> 8) & 0xffff) | (mach64->accel.dp_frgd_clr << 16); - mach64->accel.dp_bkgd_clr = ((mach64->accel.dp_bkgd_clr >> 8) & 0xffff) | (mach64->accel.dp_bkgd_clr << 16); - } + if (mach64->dst_cntl & DST_24_ROT_EN) { + mach64->accel.dp_frgd_clr = + ((mach64->accel.dp_frgd_clr >> 8) & 0xffff) | (mach64->accel.dp_frgd_clr << 16); + mach64->accel.dp_bkgd_clr = + ((mach64->accel.dp_bkgd_clr >> 8) & 0xffff) | (mach64->accel.dp_bkgd_clr << 16); + } - mach64->accel.src_x += mach64->accel.xinc; - mach64->accel.dst_x += mach64->accel.xinc; - if (!(mach64->src_cntl & SRC_LINEAR_EN)) { - mach64->accel.src_x_count--; - if (mach64->accel.src_x_count <= 0) { - mach64->accel.src_x = 0; - if ((mach64->src_cntl & (SRC_PATT_ROT_EN | SRC_PATT_EN)) == (SRC_PATT_ROT_EN | SRC_PATT_EN)) { - mach64->accel.src_x_start = (mach64->src_y_x_start >> 16) & 0xfff; - mach64->accel.src_x_count = mach64->accel.src_width2; - } else - mach64->accel.src_x_count = mach64->accel.src_width1; - } - } + mach64->accel.src_x += mach64->accel.xinc; + mach64->accel.dst_x += mach64->accel.xinc; + if (!(mach64->src_cntl & SRC_LINEAR_EN)) { + mach64->accel.src_x_count--; + if (mach64->accel.src_x_count <= 0) { + mach64->accel.src_x = 0; + if ((mach64->src_cntl & (SRC_PATT_ROT_EN | SRC_PATT_EN)) == + (SRC_PATT_ROT_EN | SRC_PATT_EN)) { + mach64->accel.src_x_start = (mach64->src_y_x_start >> 16) & 0xfff; + mach64->accel.src_x_count = mach64->accel.src_width2; + } else + mach64->accel.src_x_count = mach64->accel.src_width1; + } + } - mach64->accel.x_count--; + mach64->accel.x_count--; - if (mach64->accel.x_count <= 0) { - mach64->accel.x_count = mach64->accel.dst_width; - mach64->accel.dst_x = 0; - mach64->accel.dst_y += mach64->accel.yinc; - mach64->accel.src_x_start = (mach64->src_y_x >> 16) & 0xfff; - mach64->accel.src_x_count = mach64->accel.src_width1; + if (mach64->accel.x_count <= 0) { + mach64->accel.x_count = mach64->accel.dst_width; + mach64->accel.dst_x = 0; + mach64->accel.dst_y += mach64->accel.yinc; + mach64->accel.src_x_start = (mach64->src_y_x >> 16) & 0xfff; + mach64->accel.src_x_count = mach64->accel.src_width1; - if (!(mach64->src_cntl & SRC_LINEAR_EN)) { - mach64->accel.src_x = 0; - mach64->accel.src_y += mach64->accel.yinc; - mach64->accel.src_y_count--; - if (mach64->accel.src_y_count <= 0) { - mach64->accel.src_y = 0; - if ((mach64->src_cntl & (SRC_PATT_ROT_EN | SRC_PATT_EN)) == (SRC_PATT_ROT_EN | SRC_PATT_EN)) { - mach64->accel.src_y_start = mach64->src_y_x_start & 0xfff; - mach64->accel.src_y_count = mach64->accel.src_height2; - } else - mach64->accel.src_y_count = mach64->accel.src_height1; - } - } + if (!(mach64->src_cntl & SRC_LINEAR_EN)) { + mach64->accel.src_x = 0; + mach64->accel.src_y += mach64->accel.yinc; + mach64->accel.src_y_count--; + if (mach64->accel.src_y_count <= 0) { + mach64->accel.src_y = 0; + if ((mach64->src_cntl & (SRC_PATT_ROT_EN | SRC_PATT_EN)) == + (SRC_PATT_ROT_EN | SRC_PATT_EN)) { + mach64->accel.src_y_start = mach64->src_y_x_start & 0xfff; + mach64->accel.src_y_count = mach64->accel.src_height2; + } else + mach64->accel.src_y_count = mach64->accel.src_height1; + } + } - mach64->accel.poly_draw = 0; + mach64->accel.poly_draw = 0; - mach64->accel.dst_height--; + mach64->accel.dst_height--; - if (mach64->accel.dst_height <= 0) { - /*Blit finished*/ + if (mach64->accel.dst_height <= 0) { + /*Blit finished*/ #ifdef MACH64_DEBUG - pclog("mach64 blit finished\n"); + pclog("mach64 blit finished\n"); #endif - mach64->accel.busy = 0; - if (mach64->dst_cntl & DST_X_TILE) - mach64->dst_y_x = (mach64->dst_y_x & 0xfff) | ((mach64->dst_y_x + (mach64->accel.dst_width << 16)) & 0xfff0000); - if (mach64->dst_cntl & DST_Y_TILE) - mach64->dst_y_x = (mach64->dst_y_x & 0xfff0000) | ((mach64->dst_y_x + (mach64->dst_height_width & 0x1fff)) & 0xfff); - return; - } - if (mach64->host_cntl & HOST_BYTE_ALIGN) { - if (mach64->accel.source_mix == MONO_SRC_HOST) { - if (mach64->dp_pix_width & DP_BYTE_PIX_ORDER) - cpu_dat >>= (count & 7); - else - cpu_dat <<= (count & 7); - count &= ~7; - } - } - } - } - break; + mach64->accel.busy = 0; + if (mach64->dst_cntl & DST_X_TILE) + mach64->dst_y_x = + (mach64->dst_y_x & 0xfff) | + ((mach64->dst_y_x + (mach64->accel.dst_width << 16)) & 0xfff0000); + if (mach64->dst_cntl & DST_Y_TILE) + mach64->dst_y_x = + (mach64->dst_y_x & 0xfff0000) | + ((mach64->dst_y_x + (mach64->dst_height_width & 0x1fff)) & 0xfff); + return; + } + if (mach64->host_cntl & HOST_BYTE_ALIGN) { + if (mach64->accel.source_mix == MONO_SRC_HOST) { + if (mach64->dp_pix_width & DP_BYTE_PIX_ORDER) + cpu_dat >>= (count & 7); + else + cpu_dat <<= (count & 7); + count &= ~7; + } + } + } + } + break; - case OP_LINE: - while (count) { - uint32_t src_dat = 0, dest_dat; - uint32_t host_dat = 0; - int mix = 0; - int draw_pixel = !(mach64->dst_cntl & DST_POLYGON_EN); + case OP_LINE: + while (count) { + uint32_t src_dat = 0, dest_dat; + uint32_t host_dat = 0; + int mix = 0; + int draw_pixel = !(mach64->dst_cntl & DST_POLYGON_EN); - if (mach64->accel.source_host) { - host_dat = cpu_dat; - switch (mach64->accel.src_size) { - case 0:cpu_dat >>= 8; - count -= 8; - break; - case 1:cpu_dat >>= 16; - count -= 16; - break; - case 2:count -= 32; - break; - } - } else - count--; + if (mach64->accel.source_host) { + host_dat = cpu_dat; + switch (mach64->accel.src_size) { + case 0: + cpu_dat >>= 8; + count -= 8; + break; + case 1: + cpu_dat >>= 16; + count -= 16; + break; + case 2: + count -= 32; + break; + } + } else + count--; - switch (mach64->accel.source_mix) { - case MONO_SRC_HOST:mix = cpu_dat >> 31; - cpu_dat <<= 1; - break; - case MONO_SRC_PAT:mix = mach64->accel.pattern[mach64->accel.dst_y & 7][mach64->accel.dst_x & 7]; - break; - case MONO_SRC_1: - default:mix = 1; - break; - } + switch (mach64->accel.source_mix) { + case MONO_SRC_HOST: + mix = cpu_dat >> 31; + cpu_dat <<= 1; + break; + case MONO_SRC_PAT: + mix = mach64->accel.pattern[mach64->accel.dst_y & 7][mach64->accel.dst_x & 7]; + break; + case MONO_SRC_1: + default: + mix = 1; + break; + } - if (mach64->dst_cntl & DST_POLYGON_EN) { - if (mach64->dst_cntl & DST_Y_MAJOR) - draw_pixel = 1; - else if ((mach64->dst_cntl & DST_X_DIR) && mach64->accel.err < (mach64->dst_bres_dec + mach64->dst_bres_inc)) /*X+*/ - draw_pixel = 1; - else if (!(mach64->dst_cntl & DST_X_DIR) && mach64->accel.err >= 0) /*X-*/ - draw_pixel = 1; - } + if (mach64->dst_cntl & DST_POLYGON_EN) { + if (mach64->dst_cntl & DST_Y_MAJOR) + draw_pixel = 1; + else if ((mach64->dst_cntl & DST_X_DIR) && + mach64->accel.err < (mach64->dst_bres_dec + mach64->dst_bres_inc)) /*X+*/ + draw_pixel = 1; + else if (!(mach64->dst_cntl & DST_X_DIR) && mach64->accel.err >= 0) /*X-*/ + draw_pixel = 1; + } - if (mach64->accel.x_count == 1 && !(mach64->dst_cntl & DST_LAST_PEL)) - draw_pixel = 0; + if (mach64->accel.x_count == 1 && !(mach64->dst_cntl & DST_LAST_PEL)) + draw_pixel = 0; - if (mach64->accel.dst_x >= mach64->accel.sc_left && mach64->accel.dst_x <= mach64->accel.sc_right && - mach64->accel.dst_y >= mach64->accel.sc_top && mach64->accel.dst_y <= mach64->accel.sc_bottom && draw_pixel) { - switch (mix ? mach64->accel.source_fg : mach64->accel.source_bg) { - case SRC_HOST:src_dat = host_dat; - break; - case SRC_BLITSRC:READ(mach64->accel.src_offset + (mach64->accel.src_y * mach64->accel.src_pitch) + mach64->accel.src_x, src_dat, mach64->accel.src_size); - break; - case SRC_FG:src_dat = mach64->accel.dp_frgd_clr; - break; - case SRC_BG:src_dat = mach64->accel.dp_bkgd_clr; - break; - default:src_dat = 0; - break; - } + if (mach64->accel.dst_x >= mach64->accel.sc_left && mach64->accel.dst_x <= mach64->accel.sc_right && + mach64->accel.dst_y >= mach64->accel.sc_top && mach64->accel.dst_y <= mach64->accel.sc_bottom && + draw_pixel) { + switch (mix ? mach64->accel.source_fg : mach64->accel.source_bg) { + case SRC_HOST: + src_dat = host_dat; + break; + case SRC_BLITSRC: + READ(mach64->accel.src_offset + (mach64->accel.src_y * mach64->accel.src_pitch) + + mach64->accel.src_x, + src_dat, mach64->accel.src_size); + break; + case SRC_FG: + src_dat = mach64->accel.dp_frgd_clr; + break; + case SRC_BG: + src_dat = mach64->accel.dp_bkgd_clr; + break; + default: + src_dat = 0; + break; + } - READ(mach64->accel.dst_offset + (mach64->accel.dst_y * mach64->accel.dst_pitch) + mach64->accel.dst_x, dest_dat, mach64->accel.dst_size); + READ(mach64->accel.dst_offset + (mach64->accel.dst_y * mach64->accel.dst_pitch) + + mach64->accel.dst_x, + dest_dat, mach64->accel.dst_size); -// pclog("Blit %i,%i %i,%i %X %X %i %02X %02X %i ", mach64->accel.src_x, mach64->accel.src_y, mach64->accel.dst_x, mach64->accel.dst_y, (mach64->accel.src_offset + (mach64->accel.src_y * mach64->accel.src_pitch) + mach64->accel.src_x) & 0x7fffff, (mach64->accel.dst_offset + (mach64->accel.dst_y * mach64->accel.dst_pitch) + mach64->accel.dst_x) & 0x7fffff, count, src_dat, dest_dat, mix); + // pclog("Blit %i,%i %i,%i %X %X %i %02X %02X %i ", + // mach64->accel.src_x, mach64->accel.src_y, mach64->accel.dst_x, + // mach64->accel.dst_y, (mach64->accel.src_offset + + // (mach64->accel.src_y * mach64->accel.src_pitch) + + // mach64->accel.src_x) & 0x7fffff, (mach64->accel.dst_offset + + // (mach64->accel.dst_y * mach64->accel.dst_pitch) + + // mach64->accel.dst_x) & 0x7fffff, count, src_dat, dest_dat, mix); - switch (mach64->accel.clr_cmp_fn) { - case 1: /*TRUE*/ - cmp_clr = 1; - break; - case 4: /*DST_CLR != CLR_CMP_CLR*/ - cmp_clr = (((mach64->accel.clr_cmp_src) ? src_dat : dest_dat) & mach64->accel.clr_cmp_mask) != mach64->accel.clr_cmp_clr; - break; - case 5: /*DST_CLR == CLR_CMP_CLR*/ - cmp_clr = (((mach64->accel.clr_cmp_src) ? src_dat : dest_dat) & mach64->accel.clr_cmp_mask) == mach64->accel.clr_cmp_clr; - break; - } + switch (mach64->accel.clr_cmp_fn) { + case 1: /*TRUE*/ + cmp_clr = 1; + break; + case 4: /*DST_CLR != CLR_CMP_CLR*/ + cmp_clr = (((mach64->accel.clr_cmp_src) ? src_dat : dest_dat) & + mach64->accel.clr_cmp_mask) != mach64->accel.clr_cmp_clr; + break; + case 5: /*DST_CLR == CLR_CMP_CLR*/ + cmp_clr = (((mach64->accel.clr_cmp_src) ? src_dat : dest_dat) & + mach64->accel.clr_cmp_mask) == mach64->accel.clr_cmp_clr; + break; + } - if (!cmp_clr) - MIX + if (!cmp_clr) + MIX -// pclog("%02X %i\n", dest_dat, mach64->accel.dst_height); + // pclog("%02X %i\n", dest_dat, + // mach64->accel.dst_height); - WRITE(mach64->accel.dst_offset + (mach64->accel.dst_y * mach64->accel.dst_pitch) + mach64->accel.dst_x, mach64->accel.dst_size); - } + WRITE(mach64->accel.dst_offset + + (mach64->accel.dst_y * mach64->accel.dst_pitch) + + mach64->accel.dst_x, + mach64->accel.dst_size); + } - mach64->accel.x_count--; - if (mach64->accel.x_count <= 0) { - /*Blit finished*/ + mach64->accel.x_count--; + if (mach64->accel.x_count <= 0) { + /*Blit finished*/ #ifdef MACH64_DEBUG - pclog("mach64 blit finished\n"); + pclog("mach64 blit finished\n"); #endif - mach64->accel.busy = 0; - return; - } + mach64->accel.busy = 0; + return; + } - switch (mach64->dst_cntl & 7) { - case 0: - case 2:mach64->accel.src_x--; - mach64->accel.dst_x--; - break; - case 1: - case 3:mach64->accel.src_x++; - mach64->accel.dst_x++; - break; - case 4: - case 5:mach64->accel.src_y--; - mach64->accel.dst_y--; - break; - case 6: - case 7:mach64->accel.src_y++; - mach64->accel.dst_y++; - break; - } + switch (mach64->dst_cntl & 7) { + case 0: + case 2: + mach64->accel.src_x--; + mach64->accel.dst_x--; + break; + case 1: + case 3: + mach64->accel.src_x++; + mach64->accel.dst_x++; + break; + case 4: + case 5: + mach64->accel.src_y--; + mach64->accel.dst_y--; + break; + case 6: + case 7: + mach64->accel.src_y++; + mach64->accel.dst_y++; + break; + } #ifdef MACH64_DEBUG - pclog("x %i y %i err %i inc %i dec %i\n", mach64->accel.dst_x, mach64->accel.dst_y, mach64->accel.err, mach64->dst_bres_inc, mach64->dst_bres_dec); + pclog("x %i y %i err %i inc %i dec %i\n", mach64->accel.dst_x, mach64->accel.dst_y, mach64->accel.err, + mach64->dst_bres_inc, mach64->dst_bres_dec); #endif - if (mach64->accel.err >= 0) { - mach64->accel.err += mach64->dst_bres_dec; + if (mach64->accel.err >= 0) { + mach64->accel.err += mach64->dst_bres_dec; - switch (mach64->dst_cntl & 7) { - case 0: - case 1:mach64->accel.src_y--; - mach64->accel.dst_y--; - break; - case 2: - case 3:mach64->accel.src_y++; - mach64->accel.dst_y++; - break; - case 4: - case 6:mach64->accel.src_x--; - mach64->accel.dst_x--; - break; - case 5: - case 7:mach64->accel.src_x++; - mach64->accel.dst_x++; - break; - } - } else - mach64->accel.err += mach64->dst_bres_inc; - } - break; - } + switch (mach64->dst_cntl & 7) { + case 0: + case 1: + mach64->accel.src_y--; + mach64->accel.dst_y--; + break; + case 2: + case 3: + mach64->accel.src_y++; + mach64->accel.dst_y++; + break; + case 4: + case 6: + mach64->accel.src_x--; + mach64->accel.dst_x--; + break; + case 5: + case 7: + mach64->accel.src_x++; + mach64->accel.dst_x++; + break; + } + } else + mach64->accel.err += mach64->dst_bres_inc; + } + break; + } } void mach64_load_context(mach64_t *mach64) { - svga_t *svga = &mach64->svga; - uint32_t addr; + svga_t *svga = &mach64->svga; + uint32_t addr; - while (mach64->context_load_cntl & 0x30000) { - addr = ((0x3fff - (mach64->context_load_cntl & 0x3fff)) * 256) & mach64->vram_mask; - mach64->context_mask = *(uint32_t *)&svga->vram[addr]; + while (mach64->context_load_cntl & 0x30000) { + addr = ((0x3fff - (mach64->context_load_cntl & 0x3fff)) * 256) & mach64->vram_mask; + mach64->context_mask = *(uint32_t *)&svga->vram[addr]; #ifdef MACH64_DEBUG - pclog("mach64_load_context %08X from %08X : mask %08X\n", mach64->context_load_cntl, addr, mach64->context_mask); + pclog("mach64_load_context %08X from %08X : mask %08X\n", mach64->context_load_cntl, addr, mach64->context_mask); #endif - if (mach64->context_mask & (1 << 2)) - mach64_accel_write_fifo_l(mach64, 0x100, *(uint32_t *)&svga->vram[addr + 0x08]); - if (mach64->context_mask & (1 << 3)) - mach64_accel_write_fifo_l(mach64, 0x10c, *(uint32_t *)&svga->vram[addr + 0x0c]); - if (mach64->context_mask & (1 << 4)) - mach64_accel_write_fifo_l(mach64, 0x118, *(uint32_t *)&svga->vram[addr + 0x10]); - if (mach64->context_mask & (1 << 5)) - mach64_accel_write_fifo_l(mach64, 0x124, *(uint32_t *)&svga->vram[addr + 0x14]); - if (mach64->context_mask & (1 << 6)) - mach64_accel_write_fifo_l(mach64, 0x128, *(uint32_t *)&svga->vram[addr + 0x18]); - if (mach64->context_mask & (1 << 7)) - mach64_accel_write_fifo_l(mach64, 0x12c, *(uint32_t *)&svga->vram[addr + 0x1c]); - if (mach64->context_mask & (1 << 8)) - mach64_accel_write_fifo_l(mach64, 0x180, *(uint32_t *)&svga->vram[addr + 0x20]); - if (mach64->context_mask & (1 << 9)) - mach64_accel_write_fifo_l(mach64, 0x18c, *(uint32_t *)&svga->vram[addr + 0x24]); - if (mach64->context_mask & (1 << 10)) - mach64_accel_write_fifo_l(mach64, 0x198, *(uint32_t *)&svga->vram[addr + 0x28]); - if (mach64->context_mask & (1 << 11)) - mach64_accel_write_fifo_l(mach64, 0x1a4, *(uint32_t *)&svga->vram[addr + 0x2c]); - if (mach64->context_mask & (1 << 12)) - mach64_accel_write_fifo_l(mach64, 0x1b0, *(uint32_t *)&svga->vram[addr + 0x30]); - if (mach64->context_mask & (1 << 13)) - mach64_accel_write_fifo_l(mach64, 0x280, *(uint32_t *)&svga->vram[addr + 0x34]); - if (mach64->context_mask & (1 << 14)) - mach64_accel_write_fifo_l(mach64, 0x284, *(uint32_t *)&svga->vram[addr + 0x38]); - if (mach64->context_mask & (1 << 15)) - mach64_accel_write_fifo_l(mach64, 0x2a8, *(uint32_t *)&svga->vram[addr + 0x3c]); - if (mach64->context_mask & (1 << 16)) - mach64_accel_write_fifo_l(mach64, 0x2b4, *(uint32_t *)&svga->vram[addr + 0x40]); - if (mach64->context_mask & (1 << 17)) - mach64_accel_write_fifo_l(mach64, 0x2c0, *(uint32_t *)&svga->vram[addr + 0x44]); - if (mach64->context_mask & (1 << 18)) - mach64_accel_write_fifo_l(mach64, 0x2c4, *(uint32_t *)&svga->vram[addr + 0x48]); - if (mach64->context_mask & (1 << 19)) - mach64_accel_write_fifo_l(mach64, 0x2c8, *(uint32_t *)&svga->vram[addr + 0x4c]); - if (mach64->context_mask & (1 << 20)) - mach64_accel_write_fifo_l(mach64, 0x2cc, *(uint32_t *)&svga->vram[addr + 0x50]); - if (mach64->context_mask & (1 << 21)) - mach64_accel_write_fifo_l(mach64, 0x2d0, *(uint32_t *)&svga->vram[addr + 0x54]); - if (mach64->context_mask & (1 << 22)) - mach64_accel_write_fifo_l(mach64, 0x2d4, *(uint32_t *)&svga->vram[addr + 0x58]); - if (mach64->context_mask & (1 << 23)) - mach64_accel_write_fifo_l(mach64, 0x2d8, *(uint32_t *)&svga->vram[addr + 0x5c]); - if (mach64->context_mask & (1 << 24)) - mach64_accel_write_fifo_l(mach64, 0x300, *(uint32_t *)&svga->vram[addr + 0x60]); - if (mach64->context_mask & (1 << 25)) - mach64_accel_write_fifo_l(mach64, 0x304, *(uint32_t *)&svga->vram[addr + 0x64]); - if (mach64->context_mask & (1 << 26)) - mach64_accel_write_fifo_l(mach64, 0x308, *(uint32_t *)&svga->vram[addr + 0x68]); - if (mach64->context_mask & (1 << 27)) - mach64_accel_write_fifo_l(mach64, 0x330, *(uint32_t *)&svga->vram[addr + 0x6c]); + if (mach64->context_mask & (1 << 2)) + mach64_accel_write_fifo_l(mach64, 0x100, *(uint32_t *)&svga->vram[addr + 0x08]); + if (mach64->context_mask & (1 << 3)) + mach64_accel_write_fifo_l(mach64, 0x10c, *(uint32_t *)&svga->vram[addr + 0x0c]); + if (mach64->context_mask & (1 << 4)) + mach64_accel_write_fifo_l(mach64, 0x118, *(uint32_t *)&svga->vram[addr + 0x10]); + if (mach64->context_mask & (1 << 5)) + mach64_accel_write_fifo_l(mach64, 0x124, *(uint32_t *)&svga->vram[addr + 0x14]); + if (mach64->context_mask & (1 << 6)) + mach64_accel_write_fifo_l(mach64, 0x128, *(uint32_t *)&svga->vram[addr + 0x18]); + if (mach64->context_mask & (1 << 7)) + mach64_accel_write_fifo_l(mach64, 0x12c, *(uint32_t *)&svga->vram[addr + 0x1c]); + if (mach64->context_mask & (1 << 8)) + mach64_accel_write_fifo_l(mach64, 0x180, *(uint32_t *)&svga->vram[addr + 0x20]); + if (mach64->context_mask & (1 << 9)) + mach64_accel_write_fifo_l(mach64, 0x18c, *(uint32_t *)&svga->vram[addr + 0x24]); + if (mach64->context_mask & (1 << 10)) + mach64_accel_write_fifo_l(mach64, 0x198, *(uint32_t *)&svga->vram[addr + 0x28]); + if (mach64->context_mask & (1 << 11)) + mach64_accel_write_fifo_l(mach64, 0x1a4, *(uint32_t *)&svga->vram[addr + 0x2c]); + if (mach64->context_mask & (1 << 12)) + mach64_accel_write_fifo_l(mach64, 0x1b0, *(uint32_t *)&svga->vram[addr + 0x30]); + if (mach64->context_mask & (1 << 13)) + mach64_accel_write_fifo_l(mach64, 0x280, *(uint32_t *)&svga->vram[addr + 0x34]); + if (mach64->context_mask & (1 << 14)) + mach64_accel_write_fifo_l(mach64, 0x284, *(uint32_t *)&svga->vram[addr + 0x38]); + if (mach64->context_mask & (1 << 15)) + mach64_accel_write_fifo_l(mach64, 0x2a8, *(uint32_t *)&svga->vram[addr + 0x3c]); + if (mach64->context_mask & (1 << 16)) + mach64_accel_write_fifo_l(mach64, 0x2b4, *(uint32_t *)&svga->vram[addr + 0x40]); + if (mach64->context_mask & (1 << 17)) + mach64_accel_write_fifo_l(mach64, 0x2c0, *(uint32_t *)&svga->vram[addr + 0x44]); + if (mach64->context_mask & (1 << 18)) + mach64_accel_write_fifo_l(mach64, 0x2c4, *(uint32_t *)&svga->vram[addr + 0x48]); + if (mach64->context_mask & (1 << 19)) + mach64_accel_write_fifo_l(mach64, 0x2c8, *(uint32_t *)&svga->vram[addr + 0x4c]); + if (mach64->context_mask & (1 << 20)) + mach64_accel_write_fifo_l(mach64, 0x2cc, *(uint32_t *)&svga->vram[addr + 0x50]); + if (mach64->context_mask & (1 << 21)) + mach64_accel_write_fifo_l(mach64, 0x2d0, *(uint32_t *)&svga->vram[addr + 0x54]); + if (mach64->context_mask & (1 << 22)) + mach64_accel_write_fifo_l(mach64, 0x2d4, *(uint32_t *)&svga->vram[addr + 0x58]); + if (mach64->context_mask & (1 << 23)) + mach64_accel_write_fifo_l(mach64, 0x2d8, *(uint32_t *)&svga->vram[addr + 0x5c]); + if (mach64->context_mask & (1 << 24)) + mach64_accel_write_fifo_l(mach64, 0x300, *(uint32_t *)&svga->vram[addr + 0x60]); + if (mach64->context_mask & (1 << 25)) + mach64_accel_write_fifo_l(mach64, 0x304, *(uint32_t *)&svga->vram[addr + 0x64]); + if (mach64->context_mask & (1 << 26)) + mach64_accel_write_fifo_l(mach64, 0x308, *(uint32_t *)&svga->vram[addr + 0x68]); + if (mach64->context_mask & (1 << 27)) + mach64_accel_write_fifo_l(mach64, 0x330, *(uint32_t *)&svga->vram[addr + 0x6c]); - mach64->context_load_cntl = *(uint32_t *)&svga->vram[addr + 0x70]; - } + mach64->context_load_cntl = *(uint32_t *)&svga->vram[addr + 0x70]; + } } -#define PLL_REF_DIV 0x2 +#define PLL_REF_DIV 0x2 #define VCLK_POST_DIV 0x6 -#define VCLK0_FB_DIV 0x7 +#define VCLK0_FB_DIV 0x7 static void pll_write(mach64_t *mach64, uint32_t addr, uint8_t val) { - int c; + int c; - switch (addr & 3) { - case 0: /*Clock sel*/ - break; - case 1: /*Addr*/ - mach64->pll_addr = (val >> 2) & 0xf; - break; - case 2: /*Data*/ - mach64->pll_regs[mach64->pll_addr] = val; - pclog("pll_write %02x,%02x\n", mach64->pll_addr, val); + switch (addr & 3) { + case 0: /*Clock sel*/ + break; + case 1: /*Addr*/ + mach64->pll_addr = (val >> 2) & 0xf; + break; + case 2: /*Data*/ + mach64->pll_regs[mach64->pll_addr] = val; + pclog("pll_write %02x,%02x\n", mach64->pll_addr, val); - for (c = 0; c < 4; c++) { - double m = (double)mach64->pll_regs[PLL_REF_DIV]; - double n = (double)mach64->pll_regs[VCLK0_FB_DIV + c]; - double r = 14318184.0; - double p = (double)(1 << ((mach64->pll_regs[VCLK_POST_DIV] >> (c * 2)) & 3)); + for (c = 0; c < 4; c++) { + double m = (double)mach64->pll_regs[PLL_REF_DIV]; + double n = (double)mach64->pll_regs[VCLK0_FB_DIV + c]; + double r = 14318184.0; + double p = (double)(1 << ((mach64->pll_regs[VCLK_POST_DIV] >> (c * 2)) & 3)); - pclog("PLLfreq %i = %g %g m=%02x n=%02x p=%02x\n", c, - (2.0 * r * n) / (m * p), p, mach64->pll_regs[PLL_REF_DIV], mach64->pll_regs[VCLK0_FB_DIV + c], mach64->pll_regs[VCLK_POST_DIV]); - mach64->pll_freq[c] = (2.0 * r * n) / (m * p); - pclog(" %g\n", mach64->pll_freq[c]); - } - break; - } + pclog("PLLfreq %i = %g %g m=%02x n=%02x p=%02x\n", c, (2.0 * r * n) / (m * p), p, + mach64->pll_regs[PLL_REF_DIV], mach64->pll_regs[VCLK0_FB_DIV + c], mach64->pll_regs[VCLK_POST_DIV]); + mach64->pll_freq[c] = (2.0 * r * n) / (m * p); + pclog(" %g\n", mach64->pll_freq[c]); + } + break; + } } #define OVERLAY_EN (1 << 30) static void mach64_vblank_start(svga_t *svga) { - mach64_t *mach64 = (mach64_t *)svga->p; - int overlay_cmp_mix = (mach64->overlay_key_cntl >> 8) & 0xf; + mach64_t *mach64 = (mach64_t *)svga->p; + int overlay_cmp_mix = (mach64->overlay_key_cntl >> 8) & 0xf; - mach64->crtc_int_cntl |= 4; - mach64_update_irqs(mach64); + mach64->crtc_int_cntl |= 4; + mach64_update_irqs(mach64); - svga->overlay.x = (mach64->overlay_y_x_start >> 16) & 0x7ff; - svga->overlay.y = mach64->overlay_y_x_start & 0x7ff; + svga->overlay.x = (mach64->overlay_y_x_start >> 16) & 0x7ff; + svga->overlay.y = mach64->overlay_y_x_start & 0x7ff; - svga->overlay.xsize = ((mach64->overlay_y_x_end >> 16) & 0x7ff) - svga->overlay.x; - svga->overlay.ysize = (mach64->overlay_y_x_end & 0x7ff) - svga->overlay.y; + svga->overlay.xsize = ((mach64->overlay_y_x_end >> 16) & 0x7ff) - svga->overlay.x; + svga->overlay.ysize = (mach64->overlay_y_x_end & 0x7ff) - svga->overlay.y; - svga->overlay.addr = mach64->buf_offset[0] & 0x3ffff8; - svga->overlay.pitch = mach64->buf_pitch[0] & 0xfff; + svga->overlay.addr = mach64->buf_offset[0] & 0x3ffff8; + svga->overlay.pitch = mach64->buf_pitch[0] & 0xfff; - svga->overlay.ena = (mach64->overlay_scale_cntl & OVERLAY_EN) && (overlay_cmp_mix != 1); + svga->overlay.ena = (mach64->overlay_scale_cntl & OVERLAY_EN) && (overlay_cmp_mix != 1); - mach64->overlay_v_acc = 0; - mach64->scaler_update = 1; + mach64->overlay_v_acc = 0; + mach64->scaler_update = 1; -// pclog("Latch overlay - X=%i Y=%i xsize=%i ysize=%i ena=%i\n", svga->overlay.x,svga->overlay.y,svga->overlay.xsize,svga->overlay.ysize,svga->overlay.ena); + // pclog("Latch overlay - X=%i Y=%i xsize=%i ysize=%i ena=%i\n", + // svga->overlay.x,svga->overlay.y,svga->overlay.xsize,svga->overlay.ysize,svga->overlay.ena); } uint8_t mach64_ext_readb(uint32_t addr, void *p) { - mach64_t *mach64 = (mach64_t *)p; - uint8_t ret; - if (!(addr & 0x400)) { + mach64_t *mach64 = (mach64_t *)p; + uint8_t ret; + if (!(addr & 0x400)) { #ifdef MACH64_DEBUG - pclog("nmach64_ext_readb: addr=%04x %04x(%08x):%08x\n", addr, CS, cs, cpu_state.pc); + pclog("nmach64_ext_readb: addr=%04x %04x(%08x):%08x\n", addr, CS, cs, cpu_state.pc); #endif - switch (addr & 0x3ff) { - case 0x00: - case 0x01: - case 0x02: - case 0x03:READ8(addr, mach64->overlay_y_x_start); - break; - case 0x04: - case 0x05: - case 0x06: - case 0x07:READ8(addr, mach64->overlay_y_x_end); - break; - case 0x08: - case 0x09: - case 0x0a: - case 0x0b:READ8(addr, mach64->overlay_video_key_clr); - break; - case 0x0c: - case 0x0d: - case 0x0e: - case 0x0f:READ8(addr, mach64->overlay_video_key_msk); - break; - case 0x10: - case 0x11: - case 0x12: - case 0x13:READ8(addr, mach64->overlay_graphics_key_clr); - break; - case 0x14: - case 0x15: - case 0x16: - case 0x17:READ8(addr, mach64->overlay_graphics_key_msk); - break; - case 0x18: - case 0x19: - case 0x1a: - case 0x1b:READ8(addr, mach64->overlay_key_cntl); - break; + switch (addr & 0x3ff) { + case 0x00: + case 0x01: + case 0x02: + case 0x03: + READ8(addr, mach64->overlay_y_x_start); + break; + case 0x04: + case 0x05: + case 0x06: + case 0x07: + READ8(addr, mach64->overlay_y_x_end); + break; + case 0x08: + case 0x09: + case 0x0a: + case 0x0b: + READ8(addr, mach64->overlay_video_key_clr); + break; + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + READ8(addr, mach64->overlay_video_key_msk); + break; + case 0x10: + case 0x11: + case 0x12: + case 0x13: + READ8(addr, mach64->overlay_graphics_key_clr); + break; + case 0x14: + case 0x15: + case 0x16: + case 0x17: + READ8(addr, mach64->overlay_graphics_key_msk); + break; + case 0x18: + case 0x19: + case 0x1a: + case 0x1b: + READ8(addr, mach64->overlay_key_cntl); + break; - case 0x20: - case 0x21: - case 0x22: - case 0x23:READ8(addr, mach64->overlay_scale_inc); - break; - case 0x24: - case 0x25: - case 0x26: - case 0x27:READ8(addr, mach64->overlay_scale_cntl); - break; - case 0x28: - case 0x29: - case 0x2a: - case 0x2b:READ8(addr, mach64->scaler_height_width); - break; + case 0x20: + case 0x21: + case 0x22: + case 0x23: + READ8(addr, mach64->overlay_scale_inc); + break; + case 0x24: + case 0x25: + case 0x26: + case 0x27: + READ8(addr, mach64->overlay_scale_cntl); + break; + case 0x28: + case 0x29: + case 0x2a: + case 0x2b: + READ8(addr, mach64->scaler_height_width); + break; - case 0x4a:ret = mach64->scaler_format; - break; + case 0x4a: + ret = mach64->scaler_format; + break; - default:ret = 0xff; - break; - } - } else - switch (addr & 0x3ff) { - case 0x00: - case 0x01: - case 0x02: - case 0x03:READ8(addr, mach64->crtc_h_total_disp); - break; - case 0x08: - case 0x09: - case 0x0a: - case 0x0b:READ8(addr, mach64->crtc_v_total_disp); - break; - case 0x0c: - case 0x0d: - case 0x0e: - case 0x0f:READ8(addr, mach64->crtc_v_sync_strt_wid); - break; + default: + ret = 0xff; + break; + } + } else + switch (addr & 0x3ff) { + case 0x00: + case 0x01: + case 0x02: + case 0x03: + READ8(addr, mach64->crtc_h_total_disp); + break; + case 0x08: + case 0x09: + case 0x0a: + case 0x0b: + READ8(addr, mach64->crtc_v_total_disp); + break; + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + READ8(addr, mach64->crtc_v_sync_strt_wid); + break; - case 0x12: - case 0x13:READ8(addr - 2, mach64->svga.vc); - break; + case 0x12: + case 0x13: + READ8(addr - 2, mach64->svga.vc); + break; - case 0x14: - case 0x15: - case 0x16: - case 0x17:READ8(addr, mach64->crtc_off_pitch); - break; + case 0x14: + case 0x15: + case 0x16: + case 0x17: + READ8(addr, mach64->crtc_off_pitch); + break; - case 0x18:ret = mach64->crtc_int_cntl & ~1; - if (mach64->svga.cgastat & 8) - ret |= 1; - break; + case 0x18: + ret = mach64->crtc_int_cntl & ~1; + if (mach64->svga.cgastat & 8) + ret |= 1; + break; - case 0x1c: - case 0x1d: - case 0x1e: - case 0x1f:READ8(addr, mach64->crtc_gen_cntl); - break; + case 0x1c: + case 0x1d: + case 0x1e: + case 0x1f: + READ8(addr, mach64->crtc_gen_cntl); + break; - case 0x40: - case 0x41: - case 0x42: - case 0x43:READ8(addr, mach64->ovr_clr); - break; - case 0x44: - case 0x45: - case 0x46: - case 0x47:READ8(addr, mach64->ovr_wid_left_right); - break; - case 0x48: - case 0x49: - case 0x4a: - case 0x4b:READ8(addr, mach64->ovr_wid_top_bottom); - break; + case 0x40: + case 0x41: + case 0x42: + case 0x43: + READ8(addr, mach64->ovr_clr); + break; + case 0x44: + case 0x45: + case 0x46: + case 0x47: + READ8(addr, mach64->ovr_wid_left_right); + break; + case 0x48: + case 0x49: + case 0x4a: + case 0x4b: + READ8(addr, mach64->ovr_wid_top_bottom); + break; - case 0x60: - case 0x61: - case 0x62: - case 0x63:READ8(addr, mach64->cur_clr0); - break; - case 0x64: - case 0x65: - case 0x66: - case 0x67:READ8(addr, mach64->cur_clr1); - break; - case 0x68: - case 0x69: - case 0x6a: - case 0x6b:READ8(addr, mach64->cur_offset); - break; - case 0x6c: - case 0x6d: - case 0x6e: - case 0x6f:READ8(addr, mach64->cur_horz_vert_posn); - break; - case 0x70: - case 0x71: - case 0x72: - case 0x73:READ8(addr, mach64->cur_horz_vert_off); - break; + case 0x60: + case 0x61: + case 0x62: + case 0x63: + READ8(addr, mach64->cur_clr0); + break; + case 0x64: + case 0x65: + case 0x66: + case 0x67: + READ8(addr, mach64->cur_clr1); + break; + case 0x68: + case 0x69: + case 0x6a: + case 0x6b: + READ8(addr, mach64->cur_offset); + break; + case 0x6c: + case 0x6d: + case 0x6e: + case 0x6f: + READ8(addr, mach64->cur_horz_vert_posn); + break; + case 0x70: + case 0x71: + case 0x72: + case 0x73: + READ8(addr, mach64->cur_horz_vert_off); + break; - case 0x79:ret = 0x30; - break; + case 0x79: + ret = 0x30; + break; - case 0x80: - case 0x81: - case 0x82: - case 0x83:READ8(addr, mach64->scratch_reg0); - break; - case 0x84: - case 0x85: - case 0x86: - case 0x87:READ8(addr, mach64->scratch_reg1); - break; + case 0x80: + case 0x81: + case 0x82: + case 0x83: + READ8(addr, mach64->scratch_reg0); + break; + case 0x84: + case 0x85: + case 0x86: + case 0x87: + READ8(addr, mach64->scratch_reg1); + break; - case 0x90: - case 0x91: - case 0x92: - case 0x93:READ8(addr, mach64->clock_cntl); - break; + case 0x90: + case 0x91: + case 0x92: + case 0x93: + READ8(addr, mach64->clock_cntl); + break; - case 0xb0: - case 0xb1: - case 0xb2: - case 0xb3:READ8(addr, mach64->mem_cntl); - break; + case 0xb0: + case 0xb1: + case 0xb2: + case 0xb3: + READ8(addr, mach64->mem_cntl); + break; - case 0xc0: - case 0xc1: - case 0xc2: - case 0xc3: - if (mach64->type == MACH64_GX) - ret = ati68860_ramdac_in((addr & 3) | ((mach64->dac_cntl & 3) << 2), &mach64->ramdac, &mach64->svga); - else - ret = ati68860_ramdac_in(addr & 3, &mach64->ramdac, &mach64->svga); - break; - case 0xc4: - case 0xc5: - case 0xc6:READ8(addr, mach64->dac_cntl); - break; - case 0xc7:READ8(addr, mach64->dac_cntl); - if (mach64->type == MACH64_VT2) { - uint8_t gpio_state = 6; + case 0xc0: + case 0xc1: + case 0xc2: + case 0xc3: + if (mach64->type == MACH64_GX) + ret = ati68860_ramdac_in((addr & 3) | ((mach64->dac_cntl & 3) << 2), &mach64->ramdac, + &mach64->svga); + else + ret = ati68860_ramdac_in(addr & 3, &mach64->ramdac, &mach64->svga); + break; + case 0xc4: + case 0xc5: + case 0xc6: + READ8(addr, mach64->dac_cntl); + break; + case 0xc7: + READ8(addr, mach64->dac_cntl); + if (mach64->type == MACH64_VT2) { + uint8_t gpio_state = 6; - if ((ret & (1 << 4)) && !(ret & (1 << 1))) - gpio_state &= ~(1 << 1); - if (!(ret & (1 << 4)) && !ddc_read_data()) - gpio_state &= ~(1 << 1); - if ((ret & (1 << 5)) && !(ret & (1 << 2))) - gpio_state &= ~(1 << 2); - if (!(ret & (1 << 5)) && !ddc_read_clock()) - gpio_state &= ~(1 << 2); + if ((ret & (1 << 4)) && !(ret & (1 << 1))) + gpio_state &= ~(1 << 1); + if (!(ret & (1 << 4)) && !ddc_read_data()) + gpio_state &= ~(1 << 1); + if ((ret & (1 << 5)) && !(ret & (1 << 2))) + gpio_state &= ~(1 << 2); + if (!(ret & (1 << 5)) && !ddc_read_clock()) + gpio_state &= ~(1 << 2); - ret = (ret & ~6) | gpio_state; - } - break; + ret = (ret & ~6) | gpio_state; + } + break; - case 0xd0: - case 0xd1: - case 0xd2: - case 0xd3:READ8(addr, mach64->gen_test_cntl); - break; + case 0xd0: + case 0xd1: + case 0xd2: + case 0xd3: + READ8(addr, mach64->gen_test_cntl); + break; - case 0xdc: - case 0xdd: - case 0xde: - case 0xdf: - if (mach64->type == MACH64_GX) - mach64->config_cntl = (mach64->config_cntl & ~0x3ff0) | ((mach64->linear_base >> 22) << 4); - else - mach64->config_cntl = (mach64->config_cntl & ~0x3ff0) | ((mach64->linear_base >> 24) << 4); - READ8(addr, mach64->config_cntl); - break; - case 0xe0: - case 0xe1: - case 0xe2: - case 0xe3:READ8(addr, mach64->config_chip_id); - break; - case 0xe4: - case 0xe5: - case 0xe6: - case 0xe7:READ8(addr, mach64->config_stat0); - break; + case 0xdc: + case 0xdd: + case 0xde: + case 0xdf: + if (mach64->type == MACH64_GX) + mach64->config_cntl = (mach64->config_cntl & ~0x3ff0) | ((mach64->linear_base >> 22) << 4); + else + mach64->config_cntl = (mach64->config_cntl & ~0x3ff0) | ((mach64->linear_base >> 24) << 4); + READ8(addr, mach64->config_cntl); + break; + case 0xe0: + case 0xe1: + case 0xe2: + case 0xe3: + READ8(addr, mach64->config_chip_id); + break; + case 0xe4: + case 0xe5: + case 0xe6: + case 0xe7: + READ8(addr, mach64->config_stat0); + break; - case 0x100: - case 0x101: - case 0x102: - case 0x103:mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->dst_off_pitch); - break; - case 0x104: - case 0x105:mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->dst_y_x); - break; - case 0x108: - case 0x109: - case 0x11c: - case 0x11d:mach64_wait_fifo_idle(mach64); - READ8(addr + 2, mach64->dst_y_x); - break; - case 0x10c: - case 0x10d: - case 0x10e: - case 0x10f:mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->dst_y_x); - break; - case 0x110: - case 0x111:addr += 2; - case 0x114: - case 0x115: - case 0x118: - case 0x119: - case 0x11a: - case 0x11b: - case 0x11e: - case 0x11f:mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->dst_height_width); - break; + case 0x100: + case 0x101: + case 0x102: + case 0x103: + mach64_wait_fifo_idle(mach64); + READ8(addr, mach64->dst_off_pitch); + break; + case 0x104: + case 0x105: + mach64_wait_fifo_idle(mach64); + READ8(addr, mach64->dst_y_x); + break; + case 0x108: + case 0x109: + case 0x11c: + case 0x11d: + mach64_wait_fifo_idle(mach64); + READ8(addr + 2, mach64->dst_y_x); + break; + case 0x10c: + case 0x10d: + case 0x10e: + case 0x10f: + mach64_wait_fifo_idle(mach64); + READ8(addr, mach64->dst_y_x); + break; + case 0x110: + case 0x111: + addr += 2; + case 0x114: + case 0x115: + case 0x118: + case 0x119: + case 0x11a: + case 0x11b: + case 0x11e: + case 0x11f: + mach64_wait_fifo_idle(mach64); + READ8(addr, mach64->dst_height_width); + break; - case 0x120: - case 0x121: - case 0x122: - case 0x123:mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->dst_bres_lnth); - break; - case 0x124: - case 0x125: - case 0x126: - case 0x127:mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->dst_bres_err); - break; - case 0x128: - case 0x129: - case 0x12a: - case 0x12b:mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->dst_bres_inc); - break; - case 0x12c: - case 0x12d: - case 0x12e: - case 0x12f:mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->dst_bres_dec); - break; + case 0x120: + case 0x121: + case 0x122: + case 0x123: + mach64_wait_fifo_idle(mach64); + READ8(addr, mach64->dst_bres_lnth); + break; + case 0x124: + case 0x125: + case 0x126: + case 0x127: + mach64_wait_fifo_idle(mach64); + READ8(addr, mach64->dst_bres_err); + break; + case 0x128: + case 0x129: + case 0x12a: + case 0x12b: + mach64_wait_fifo_idle(mach64); + READ8(addr, mach64->dst_bres_inc); + break; + case 0x12c: + case 0x12d: + case 0x12e: + case 0x12f: + mach64_wait_fifo_idle(mach64); + READ8(addr, mach64->dst_bres_dec); + break; - case 0x130: - case 0x131: - case 0x132: - case 0x133:mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->dst_cntl); - break; + case 0x130: + case 0x131: + case 0x132: + case 0x133: + mach64_wait_fifo_idle(mach64); + READ8(addr, mach64->dst_cntl); + break; - case 0x180: - case 0x181: - case 0x182: - case 0x183:mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->src_off_pitch); - break; - case 0x184: - case 0x185:mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->src_y_x); - break; - case 0x188: - case 0x189:mach64_wait_fifo_idle(mach64); - READ8(addr + 2, mach64->src_y_x); - break; - case 0x18c: - case 0x18d: - case 0x18e: - case 0x18f:mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->src_y_x); - break; - case 0x190: - case 0x191:mach64_wait_fifo_idle(mach64); - READ8(addr + 2, mach64->src_height1_width1); - break; - case 0x194: - case 0x195:mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->src_height1_width1); - break; - case 0x198: - case 0x199: - case 0x19a: - case 0x19b:mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->src_height1_width1); - break; - case 0x19c: - case 0x19d:mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->src_y_x_start); - break; - case 0x1a0: - case 0x1a1:mach64_wait_fifo_idle(mach64); - READ8(addr + 2, mach64->src_y_x_start); - break; - case 0x1a4: - case 0x1a5: - case 0x1a6: - case 0x1a7:mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->src_y_x_start); - break; - case 0x1a8: - case 0x1a9:mach64_wait_fifo_idle(mach64); - READ8(addr + 2, mach64->src_height2_width2); - break; - case 0x1ac: - case 0x1ad:mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->src_height2_width2); - break; - case 0x1b0: - case 0x1b1: - case 0x1b2: - case 0x1b3:mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->src_height2_width2); - break; + case 0x180: + case 0x181: + case 0x182: + case 0x183: + mach64_wait_fifo_idle(mach64); + READ8(addr, mach64->src_off_pitch); + break; + case 0x184: + case 0x185: + mach64_wait_fifo_idle(mach64); + READ8(addr, mach64->src_y_x); + break; + case 0x188: + case 0x189: + mach64_wait_fifo_idle(mach64); + READ8(addr + 2, mach64->src_y_x); + break; + case 0x18c: + case 0x18d: + case 0x18e: + case 0x18f: + mach64_wait_fifo_idle(mach64); + READ8(addr, mach64->src_y_x); + break; + case 0x190: + case 0x191: + mach64_wait_fifo_idle(mach64); + READ8(addr + 2, mach64->src_height1_width1); + break; + case 0x194: + case 0x195: + mach64_wait_fifo_idle(mach64); + READ8(addr, mach64->src_height1_width1); + break; + case 0x198: + case 0x199: + case 0x19a: + case 0x19b: + mach64_wait_fifo_idle(mach64); + READ8(addr, mach64->src_height1_width1); + break; + case 0x19c: + case 0x19d: + mach64_wait_fifo_idle(mach64); + READ8(addr, mach64->src_y_x_start); + break; + case 0x1a0: + case 0x1a1: + mach64_wait_fifo_idle(mach64); + READ8(addr + 2, mach64->src_y_x_start); + break; + case 0x1a4: + case 0x1a5: + case 0x1a6: + case 0x1a7: + mach64_wait_fifo_idle(mach64); + READ8(addr, mach64->src_y_x_start); + break; + case 0x1a8: + case 0x1a9: + mach64_wait_fifo_idle(mach64); + READ8(addr + 2, mach64->src_height2_width2); + break; + case 0x1ac: + case 0x1ad: + mach64_wait_fifo_idle(mach64); + READ8(addr, mach64->src_height2_width2); + break; + case 0x1b0: + case 0x1b1: + case 0x1b2: + case 0x1b3: + mach64_wait_fifo_idle(mach64); + READ8(addr, mach64->src_height2_width2); + break; - case 0x1b4: - case 0x1b5: - case 0x1b6: - case 0x1b7:mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->src_cntl); - break; + case 0x1b4: + case 0x1b5: + case 0x1b6: + case 0x1b7: + mach64_wait_fifo_idle(mach64); + READ8(addr, mach64->src_cntl); + break; - case 0x240: - case 0x241: - case 0x242: - case 0x243:mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->host_cntl); - break; + case 0x240: + case 0x241: + case 0x242: + case 0x243: + mach64_wait_fifo_idle(mach64); + READ8(addr, mach64->host_cntl); + break; - case 0x280: - case 0x281: - case 0x282: - case 0x283:mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->pat_reg0); - break; - case 0x284: - case 0x285: - case 0x286: - case 0x287:mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->pat_reg1); - break; + case 0x280: + case 0x281: + case 0x282: + case 0x283: + mach64_wait_fifo_idle(mach64); + READ8(addr, mach64->pat_reg0); + break; + case 0x284: + case 0x285: + case 0x286: + case 0x287: + mach64_wait_fifo_idle(mach64); + READ8(addr, mach64->pat_reg1); + break; - case 0x2a0: - case 0x2a1: - case 0x2a8: - case 0x2a9:mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->sc_left_right); - break; - case 0x2a4: - case 0x2a5:addr += 2; - case 0x2aa: - case 0x2ab:mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->sc_left_right); - break; + case 0x2a0: + case 0x2a1: + case 0x2a8: + case 0x2a9: + mach64_wait_fifo_idle(mach64); + READ8(addr, mach64->sc_left_right); + break; + case 0x2a4: + case 0x2a5: + addr += 2; + case 0x2aa: + case 0x2ab: + mach64_wait_fifo_idle(mach64); + READ8(addr, mach64->sc_left_right); + break; - case 0x2ac: - case 0x2ad: - case 0x2b4: - case 0x2b5:mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->sc_top_bottom); - break; - case 0x2b0: - case 0x2b1:addr += 2; - case 0x2b6: - case 0x2b7:mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->sc_top_bottom); - break; + case 0x2ac: + case 0x2ad: + case 0x2b4: + case 0x2b5: + mach64_wait_fifo_idle(mach64); + READ8(addr, mach64->sc_top_bottom); + break; + case 0x2b0: + case 0x2b1: + addr += 2; + case 0x2b6: + case 0x2b7: + mach64_wait_fifo_idle(mach64); + READ8(addr, mach64->sc_top_bottom); + break; - case 0x2c0: - case 0x2c1: - case 0x2c2: - case 0x2c3:mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->dp_bkgd_clr); - break; - case 0x2c4: - case 0x2c5: - case 0x2c6: - case 0x2c7:mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->dp_frgd_clr); - break; + case 0x2c0: + case 0x2c1: + case 0x2c2: + case 0x2c3: + mach64_wait_fifo_idle(mach64); + READ8(addr, mach64->dp_bkgd_clr); + break; + case 0x2c4: + case 0x2c5: + case 0x2c6: + case 0x2c7: + mach64_wait_fifo_idle(mach64); + READ8(addr, mach64->dp_frgd_clr); + break; - case 0x2d0: - case 0x2d1: - case 0x2d2: - case 0x2d3:mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->dp_pix_width); - break; - case 0x2d4: - case 0x2d5: - case 0x2d6: - case 0x2d7:mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->dp_mix); - break; - case 0x2d8: - case 0x2d9: - case 0x2da: - case 0x2db:mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->dp_src); - break; + case 0x2d0: + case 0x2d1: + case 0x2d2: + case 0x2d3: + mach64_wait_fifo_idle(mach64); + READ8(addr, mach64->dp_pix_width); + break; + case 0x2d4: + case 0x2d5: + case 0x2d6: + case 0x2d7: + mach64_wait_fifo_idle(mach64); + READ8(addr, mach64->dp_mix); + break; + case 0x2d8: + case 0x2d9: + case 0x2da: + case 0x2db: + mach64_wait_fifo_idle(mach64); + READ8(addr, mach64->dp_src); + break; - case 0x300: - case 0x301: - case 0x302: - case 0x303:mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->clr_cmp_clr); - break; - case 0x304: - case 0x305: - case 0x306: - case 0x307:mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->clr_cmp_mask); - break; - case 0x308: - case 0x309: - case 0x30a: - case 0x30b:mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->clr_cmp_cntl); - break; + case 0x300: + case 0x301: + case 0x302: + case 0x303: + mach64_wait_fifo_idle(mach64); + READ8(addr, mach64->clr_cmp_clr); + break; + case 0x304: + case 0x305: + case 0x306: + case 0x307: + mach64_wait_fifo_idle(mach64); + READ8(addr, mach64->clr_cmp_mask); + break; + case 0x308: + case 0x309: + case 0x30a: + case 0x30b: + mach64_wait_fifo_idle(mach64); + READ8(addr, mach64->clr_cmp_cntl); + break; - case 0x310: - case 0x311: - if (!FIFO_EMPTY) - wake_fifo_thread(mach64); - ret = 0; - if (FIFO_FULL) - ret = 0xff; - break; + case 0x310: + case 0x311: + if (!FIFO_EMPTY) + wake_fifo_thread(mach64); + ret = 0; + if (FIFO_FULL) + ret = 0xff; + break; - case 0x320: - case 0x321: - case 0x322: - case 0x323:mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->context_mask); - break; + case 0x320: + case 0x321: + case 0x322: + case 0x323: + mach64_wait_fifo_idle(mach64); + READ8(addr, mach64->context_mask); + break; - case 0x330: - case 0x331:mach64_wait_fifo_idle(mach64); - READ8(addr, mach64->dst_cntl); - break; - case 0x332:mach64_wait_fifo_idle(mach64); - READ8(addr - 2, mach64->src_cntl); - break; - case 0x333:mach64_wait_fifo_idle(mach64); - READ8(addr - 3, mach64->pat_cntl); - break; + case 0x330: + case 0x331: + mach64_wait_fifo_idle(mach64); + READ8(addr, mach64->dst_cntl); + break; + case 0x332: + mach64_wait_fifo_idle(mach64); + READ8(addr - 2, mach64->src_cntl); + break; + case 0x333: + mach64_wait_fifo_idle(mach64); + READ8(addr - 3, mach64->pat_cntl); + break; - case 0x338: -/* if (!FIFO_EMPTY) - wake_fifo_thread(mach64);*/ - ret = FIFO_EMPTY ? 0 : 1; - break; + case 0x338: + /* if (!FIFO_EMPTY) + wake_fifo_thread(mach64);*/ + ret = FIFO_EMPTY ? 0 : 1; + break; - default:ret = 0; - break; - } + default: + ret = 0; + break; + } #ifdef MACH64_DEBUG - if ((addr & 0x3fc) != 0x018) pclog("mach64_ext_readb : addr %08X ret %02X\n", addr, ret); + if ((addr & 0x3fc) != 0x018) + pclog("mach64_ext_readb : addr %08X ret %02X\n", addr, ret); #endif - return ret; + return ret; } uint16_t mach64_ext_readw(uint32_t addr, void *p) { - uint16_t ret; - if (!(addr & 0x400)) { + uint16_t ret; + if (!(addr & 0x400)) { #ifdef MACH64_DEBUG - pclog("nmach64_ext_readw: addr=%04x %04x(%08x):%08x\n", addr, CS, cs, cpu_state.pc); + pclog("nmach64_ext_readw: addr=%04x %04x(%08x):%08x\n", addr, CS, cs, cpu_state.pc); #endif - ret = 0xffff; - } else - switch (addr & 0x3ff) { - default: + ret = 0xffff; + } else + switch (addr & 0x3ff) { + default: #ifdef MACH64_DEBUG - pclog(" "); + pclog(" "); #endif - ret = mach64_ext_readb(addr, p); + ret = mach64_ext_readb(addr, p); #ifdef MACH64_DEBUG - pclog(" "); + pclog(" "); #endif - ret |= mach64_ext_readb(addr + 1, p) << 8; - break; - } + ret |= mach64_ext_readb(addr + 1, p) << 8; + break; + } #ifdef MACH64_DEBUG - if ((addr & 0x3fc) != 0x018) pclog("mach64_ext_readw : addr %08X ret %04X\n", addr, ret); + if ((addr & 0x3fc) != 0x018) + pclog("mach64_ext_readw : addr %08X ret %04X\n", addr, ret); #endif - return ret; + return ret; } uint32_t mach64_ext_readl(uint32_t addr, void *p) { - mach64_t *mach64 = (mach64_t *)p; - uint32_t ret; - if (!(addr & 0x400)) { + mach64_t *mach64 = (mach64_t *)p; + uint32_t ret; + if (!(addr & 0x400)) { #ifdef MACH64_DEBUG - pclog("nmach64_ext_readl: addr=%04x %04x(%08x):%08x\n", addr, CS, cs, cpu_state.pc); + pclog("nmach64_ext_readl: addr=%04x %04x(%08x):%08x\n", addr, CS, cs, cpu_state.pc); #endif - ret = 0xffffffff; - } else - switch (addr & 0x3ff) { - case 0x18:ret = mach64->crtc_int_cntl & ~1; - if (mach64->svga.cgastat & 8) - ret |= 1; - break; + ret = 0xffffffff; + } else + switch (addr & 0x3ff) { + case 0x18: + ret = mach64->crtc_int_cntl & ~1; + if (mach64->svga.cgastat & 8) + ret |= 1; + break; - case 0xb4:ret = (mach64->bank_w[0] >> 15) | ((mach64->bank_w[1] >> 15) << 16); - break; - case 0xb8:ret = (mach64->bank_r[0] >> 15) | ((mach64->bank_r[1] >> 15) << 16); - break; + case 0xb4: + ret = (mach64->bank_w[0] >> 15) | ((mach64->bank_w[1] >> 15) << 16); + break; + case 0xb8: + ret = (mach64->bank_r[0] >> 15) | ((mach64->bank_r[1] >> 15) << 16); + break; - default: + default: #ifdef MACH64_DEBUG - pclog(" "); + pclog(" "); #endif - ret = mach64_ext_readw(addr, p); + ret = mach64_ext_readw(addr, p); #ifdef MACH64_DEBUG - pclog(" "); + pclog(" "); #endif - ret |= mach64_ext_readw(addr + 2, p) << 16; - break; - } + ret |= mach64_ext_readw(addr + 2, p) << 16; + break; + } #ifdef MACH64_DEBUG - if ((addr & 0x3fc) != 0x018) pclog("mach64_ext_readl : addr %08X ret %08X\n", addr, ret); + if ((addr & 0x3fc) != 0x018) + pclog("mach64_ext_readl : addr %08X ret %08X\n", addr, ret); #endif - return ret; + return ret; } void mach64_ext_writeb(uint32_t addr, uint8_t val, void *p) { - mach64_t *mach64 = (mach64_t *)p; - svga_t *svga = &mach64->svga; + mach64_t *mach64 = (mach64_t *)p; + svga_t *svga = &mach64->svga; #ifdef MACH64_DEBUG - pclog("mach64_ext_writeb : addr %08X val %02X %04x(%08x):%08x\n", addr, val, CS,cs,cpu_state.pc); + pclog("mach64_ext_writeb : addr %08X val %02X %04x(%08x):%08x\n", addr, val, CS, cs, cpu_state.pc); #endif - if (!(addr & 0x400)) { - switch (addr & 0x3ff) { - case 0x00: - case 0x01: - case 0x02: - case 0x03:WRITE8(addr, mach64->overlay_y_x_start, val); - break; - case 0x04: - case 0x05: - case 0x06: - case 0x07:WRITE8(addr, mach64->overlay_y_x_end, val); - break; - case 0x08: - case 0x09: - case 0x0a: - case 0x0b:WRITE8(addr, mach64->overlay_video_key_clr, val); - break; - case 0x0c: - case 0x0d: - case 0x0e: - case 0x0f:WRITE8(addr, mach64->overlay_video_key_msk, val); - break; - case 0x10: - case 0x11: - case 0x12: - case 0x13:WRITE8(addr, mach64->overlay_graphics_key_clr, val); - break; - case 0x14: - case 0x15: - case 0x16: - case 0x17:WRITE8(addr, mach64->overlay_graphics_key_msk, val); - break; - case 0x18: - case 0x19: - case 0x1a: - case 0x1b:WRITE8(addr, mach64->overlay_key_cntl, val); - break; + if (!(addr & 0x400)) { + switch (addr & 0x3ff) { + case 0x00: + case 0x01: + case 0x02: + case 0x03: + WRITE8(addr, mach64->overlay_y_x_start, val); + break; + case 0x04: + case 0x05: + case 0x06: + case 0x07: + WRITE8(addr, mach64->overlay_y_x_end, val); + break; + case 0x08: + case 0x09: + case 0x0a: + case 0x0b: + WRITE8(addr, mach64->overlay_video_key_clr, val); + break; + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + WRITE8(addr, mach64->overlay_video_key_msk, val); + break; + case 0x10: + case 0x11: + case 0x12: + case 0x13: + WRITE8(addr, mach64->overlay_graphics_key_clr, val); + break; + case 0x14: + case 0x15: + case 0x16: + case 0x17: + WRITE8(addr, mach64->overlay_graphics_key_msk, val); + break; + case 0x18: + case 0x19: + case 0x1a: + case 0x1b: + WRITE8(addr, mach64->overlay_key_cntl, val); + break; - case 0x20: - case 0x21: - case 0x22: - case 0x23:WRITE8(addr, mach64->overlay_scale_inc, val); - break; - case 0x24: - case 0x25: - case 0x26: - case 0x27:WRITE8(addr, mach64->overlay_scale_cntl, val); - break; - case 0x28: - case 0x29: - case 0x2a: - case 0x2b:WRITE8(addr, mach64->scaler_height_width, val); - break; + case 0x20: + case 0x21: + case 0x22: + case 0x23: + WRITE8(addr, mach64->overlay_scale_inc, val); + break; + case 0x24: + case 0x25: + case 0x26: + case 0x27: + WRITE8(addr, mach64->overlay_scale_cntl, val); + break; + case 0x28: + case 0x29: + case 0x2a: + case 0x2b: + WRITE8(addr, mach64->scaler_height_width, val); + break; - case 0x4a:mach64->scaler_format = val & 0xf; - break; + case 0x4a: + mach64->scaler_format = val & 0xf; + break; - case 0x80: - case 0x81: - case 0x82: - case 0x83:WRITE8(addr, mach64->buf_offset[0], val); - break; + case 0x80: + case 0x81: + case 0x82: + case 0x83: + WRITE8(addr, mach64->buf_offset[0], val); + break; - case 0x8c: - case 0x8d: - case 0x8e: - case 0x8f:WRITE8(addr, mach64->buf_pitch[0], val); - break; + case 0x8c: + case 0x8d: + case 0x8e: + case 0x8f: + WRITE8(addr, mach64->buf_pitch[0], val); + break; - case 0x98: - case 0x99: - case 0x9a: - case 0x9b:WRITE8(addr, mach64->buf_offset[1], val); - break; + case 0x98: + case 0x99: + case 0x9a: + case 0x9b: + WRITE8(addr, mach64->buf_offset[1], val); + break; - case 0xa4: - case 0xa5: - case 0xa6: - case 0xa7:WRITE8(addr, mach64->buf_pitch[1], val); - break; - } + case 0xa4: + case 0xa5: + case 0xa6: + case 0xa7: + WRITE8(addr, mach64->buf_pitch[1], val); + break; + } #ifdef MACH64_DEBUG - pclog("nmach64_ext_writeb: addr=%04x val=%02x\n", addr, val); + pclog("nmach64_ext_writeb: addr=%04x val=%02x\n", addr, val); #endif - } else if (addr & 0x300) { - mach64_queue(mach64, addr & 0x3ff, val, FIFO_WRITE_BYTE); - } else - switch (addr & 0x3ff) { - case 0x00: - case 0x01: - case 0x02: - case 0x03:WRITE8(addr, mach64->crtc_h_total_disp, val); - svga_recalctimings(&mach64->svga); - break; - case 0x08: - case 0x09: - case 0x0a: - case 0x0b:WRITE8(addr, mach64->crtc_v_total_disp, val); - svga_recalctimings(&mach64->svga); - break; - case 0x0c: - case 0x0d: - case 0x0e: - case 0x0f:WRITE8(addr, mach64->crtc_v_sync_strt_wid, val); - svga_recalctimings(&mach64->svga); - break; + } else if (addr & 0x300) { + mach64_queue(mach64, addr & 0x3ff, val, FIFO_WRITE_BYTE); + } else + switch (addr & 0x3ff) { + case 0x00: + case 0x01: + case 0x02: + case 0x03: + WRITE8(addr, mach64->crtc_h_total_disp, val); + svga_recalctimings(&mach64->svga); + break; + case 0x08: + case 0x09: + case 0x0a: + case 0x0b: + WRITE8(addr, mach64->crtc_v_total_disp, val); + svga_recalctimings(&mach64->svga); + break; + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + WRITE8(addr, mach64->crtc_v_sync_strt_wid, val); + svga_recalctimings(&mach64->svga); + break; - case 0x14: - case 0x15: - case 0x16: - case 0x17:WRITE8(addr, mach64->crtc_off_pitch, val); - svga_recalctimings(&mach64->svga); - svga->fullchange = changeframecount; - break; + case 0x14: + case 0x15: + case 0x16: + case 0x17: + WRITE8(addr, mach64->crtc_off_pitch, val); + svga_recalctimings(&mach64->svga); + svga->fullchange = changeframecount; + break; - case 0x18:mach64->crtc_int_cntl = (mach64->crtc_int_cntl & 0x75) | (val & ~0x75); - if (val & 4) - mach64->crtc_int_cntl &= ~4; - mach64_update_irqs(mach64); - break; + case 0x18: + mach64->crtc_int_cntl = (mach64->crtc_int_cntl & 0x75) | (val & ~0x75); + if (val & 4) + mach64->crtc_int_cntl &= ~4; + mach64_update_irqs(mach64); + break; - case 0x1c: - case 0x1d: - case 0x1e: - case 0x1f:WRITE8(addr, mach64->crtc_gen_cntl, val); - if (((mach64->crtc_gen_cntl >> 24) & 3) == 3) - svga->fb_only = 1; - else - svga->fb_only = 0; - svga_recalctimings(&mach64->svga); - break; + case 0x1c: + case 0x1d: + case 0x1e: + case 0x1f: + WRITE8(addr, mach64->crtc_gen_cntl, val); + if (((mach64->crtc_gen_cntl >> 24) & 3) == 3) + svga->fb_only = 1; + else + svga->fb_only = 0; + svga_recalctimings(&mach64->svga); + break; - case 0x40: - case 0x41: - case 0x42: - case 0x43:WRITE8(addr, mach64->ovr_clr, val); - break; - case 0x44: - case 0x45: - case 0x46: - case 0x47:WRITE8(addr, mach64->ovr_wid_left_right, val); - break; - case 0x48: - case 0x49: - case 0x4a: - case 0x4b:WRITE8(addr, mach64->ovr_wid_top_bottom, val); - break; + case 0x40: + case 0x41: + case 0x42: + case 0x43: + WRITE8(addr, mach64->ovr_clr, val); + break; + case 0x44: + case 0x45: + case 0x46: + case 0x47: + WRITE8(addr, mach64->ovr_wid_left_right, val); + break; + case 0x48: + case 0x49: + case 0x4a: + case 0x4b: + WRITE8(addr, mach64->ovr_wid_top_bottom, val); + break; - case 0x60: - case 0x61: - case 0x62: - case 0x63:WRITE8(addr, mach64->cur_clr0, val); - if (mach64->type == MACH64_VT2) - mach64->ramdac.pallook[0] = makecol32((mach64->cur_clr0 >> 24) & 0xff, (mach64->cur_clr0 >> 16) & 0xff, (mach64->cur_clr0 >> 8) & 0xff); - break; - case 0x64: - case 0x65: - case 0x66: - case 0x67:WRITE8(addr, mach64->cur_clr1, val); - if (mach64->type == MACH64_VT2) - mach64->ramdac.pallook[1] = makecol32((mach64->cur_clr1 >> 24) & 0xff, (mach64->cur_clr1 >> 16) & 0xff, (mach64->cur_clr1 >> 8) & 0xff); - break; - case 0x68: - case 0x69: - case 0x6a: - case 0x6b:WRITE8(addr, mach64->cur_offset, val); - svga->hwcursor.addr = (mach64->cur_offset & 0xfffff) * 8; - mach64_cursor_dump(mach64); - break; - case 0x6c: - case 0x6d: - case 0x6e: - case 0x6f:WRITE8(addr, mach64->cur_horz_vert_posn, val); - svga->hwcursor.x = mach64->cur_horz_vert_posn & 0x7ff; - svga->hwcursor.y = (mach64->cur_horz_vert_posn >> 16) & 0x7ff; - mach64_cursor_dump(mach64); - break; - case 0x70: - case 0x71: - case 0x72: - case 0x73:WRITE8(addr, mach64->cur_horz_vert_off, val); - svga->hwcursor.xoff = mach64->cur_horz_vert_off & 0x3f; - svga->hwcursor.yoff = (mach64->cur_horz_vert_off >> 16) & 0x3f; - mach64_cursor_dump(mach64); - break; + case 0x60: + case 0x61: + case 0x62: + case 0x63: + WRITE8(addr, mach64->cur_clr0, val); + if (mach64->type == MACH64_VT2) + mach64->ramdac.pallook[0] = + makecol32((mach64->cur_clr0 >> 24) & 0xff, (mach64->cur_clr0 >> 16) & 0xff, + (mach64->cur_clr0 >> 8) & 0xff); + break; + case 0x64: + case 0x65: + case 0x66: + case 0x67: + WRITE8(addr, mach64->cur_clr1, val); + if (mach64->type == MACH64_VT2) + mach64->ramdac.pallook[1] = + makecol32((mach64->cur_clr1 >> 24) & 0xff, (mach64->cur_clr1 >> 16) & 0xff, + (mach64->cur_clr1 >> 8) & 0xff); + break; + case 0x68: + case 0x69: + case 0x6a: + case 0x6b: + WRITE8(addr, mach64->cur_offset, val); + svga->hwcursor.addr = (mach64->cur_offset & 0xfffff) * 8; + mach64_cursor_dump(mach64); + break; + case 0x6c: + case 0x6d: + case 0x6e: + case 0x6f: + WRITE8(addr, mach64->cur_horz_vert_posn, val); + svga->hwcursor.x = mach64->cur_horz_vert_posn & 0x7ff; + svga->hwcursor.y = (mach64->cur_horz_vert_posn >> 16) & 0x7ff; + mach64_cursor_dump(mach64); + break; + case 0x70: + case 0x71: + case 0x72: + case 0x73: + WRITE8(addr, mach64->cur_horz_vert_off, val); + svga->hwcursor.xoff = mach64->cur_horz_vert_off & 0x3f; + svga->hwcursor.yoff = (mach64->cur_horz_vert_off >> 16) & 0x3f; + mach64_cursor_dump(mach64); + break; - case 0x80: - case 0x81: - case 0x82: - case 0x83:WRITE8(addr, mach64->scratch_reg0, val); - break; - case 0x84: - case 0x85: - case 0x86: - case 0x87:WRITE8(addr, mach64->scratch_reg1, val); - break; + case 0x80: + case 0x81: + case 0x82: + case 0x83: + WRITE8(addr, mach64->scratch_reg0, val); + break; + case 0x84: + case 0x85: + case 0x86: + case 0x87: + WRITE8(addr, mach64->scratch_reg1, val); + break; - case 0x90: - case 0x91: - case 0x92: - case 0x93:WRITE8(addr, mach64->clock_cntl, val); - if (mach64->type == MACH64_GX) - ics2595_write(&mach64->ics2595, val & 0x40, val & 0xf); - else { - pll_write(mach64, addr, val); - mach64->ics2595.output_clock = mach64->pll_freq[mach64->clock_cntl & 3]; - } - svga_recalctimings(&mach64->svga); - break; + case 0x90: + case 0x91: + case 0x92: + case 0x93: + WRITE8(addr, mach64->clock_cntl, val); + if (mach64->type == MACH64_GX) + ics2595_write(&mach64->ics2595, val & 0x40, val & 0xf); + else { + pll_write(mach64, addr, val); + mach64->ics2595.output_clock = mach64->pll_freq[mach64->clock_cntl & 3]; + } + svga_recalctimings(&mach64->svga); + break; - case 0xb0: - case 0xb1: - case 0xb2: - case 0xb3:WRITE8(addr, mach64->mem_cntl, val); - break; + case 0xb0: + case 0xb1: + case 0xb2: + case 0xb3: + WRITE8(addr, mach64->mem_cntl, val); + break; - case 0xb4:mach64->bank_w[0] = val * 32768; + case 0xb4: + mach64->bank_w[0] = val * 32768; #ifdef MACH64_DEBUG - pclog("mach64 : write bank A0000-A7FFF set to %08X\n", mach64->bank_w[0]); + pclog("mach64 : write bank A0000-A7FFF set to %08X\n", mach64->bank_w[0]); #endif - break; - case 0xb5: - case 0xb6:mach64->bank_w[1] = val * 32768; + break; + case 0xb5: + case 0xb6: + mach64->bank_w[1] = val * 32768; #ifdef MACH64_DEBUG - pclog("mach64 : write bank A8000-AFFFF set to %08X\n", mach64->bank_w[1]); + pclog("mach64 : write bank A8000-AFFFF set to %08X\n", mach64->bank_w[1]); #endif - break; - case 0xb8:mach64->bank_r[0] = val * 32768; + break; + case 0xb8: + mach64->bank_r[0] = val * 32768; #ifdef MACH64_DEBUG - pclog("mach64 : read bank A0000-A7FFF set to %08X\n", mach64->bank_r[0]); + pclog("mach64 : read bank A0000-A7FFF set to %08X\n", mach64->bank_r[0]); #endif - break; - case 0xb9: - case 0xba:mach64->bank_r[1] = val * 32768; + break; + case 0xb9: + case 0xba: + mach64->bank_r[1] = val * 32768; #ifdef MACH64_DEBUG - pclog("mach64 : read bank A8000-AFFFF set to %08X\n", mach64->bank_r[1]); + pclog("mach64 : read bank A8000-AFFFF set to %08X\n", mach64->bank_r[1]); #endif - break; + break; - case 0xc0: - case 0xc1: - case 0xc2: - case 0xc3: - if (mach64->type == MACH64_GX) - ati68860_ramdac_out((addr & 3) | ((mach64->dac_cntl & 3) << 2), val, &mach64->ramdac, &mach64->svga); - else - ati68860_ramdac_out(addr & 3, val, &mach64->ramdac, &mach64->svga); - break; - case 0xc4: - case 0xc5: - case 0xc6: - case 0xc7:WRITE8(addr, mach64->dac_cntl, val); - svga_set_ramdac_type(svga, (mach64->dac_cntl & 0x100) ? RAMDAC_8BIT : RAMDAC_6BIT); - ati68860_set_ramdac_type(&mach64->ramdac, (mach64->dac_cntl & 0x100) ? RAMDAC_8BIT : RAMDAC_6BIT); - { - int data = (val & (1 << 4)) ? ((val & (1 << 1)) ? 1 : 0) : 1; - int clk = (val & (1 << 5)) ? ((val & (1 << 2)) ? 1 : 0) : 1; + case 0xc0: + case 0xc1: + case 0xc2: + case 0xc3: + if (mach64->type == MACH64_GX) + ati68860_ramdac_out((addr & 3) | ((mach64->dac_cntl & 3) << 2), val, &mach64->ramdac, + &mach64->svga); + else + ati68860_ramdac_out(addr & 3, val, &mach64->ramdac, &mach64->svga); + break; + case 0xc4: + case 0xc5: + case 0xc6: + case 0xc7: + WRITE8(addr, mach64->dac_cntl, val); + svga_set_ramdac_type(svga, (mach64->dac_cntl & 0x100) ? RAMDAC_8BIT : RAMDAC_6BIT); + ati68860_set_ramdac_type(&mach64->ramdac, (mach64->dac_cntl & 0x100) ? RAMDAC_8BIT : RAMDAC_6BIT); + { + int data = (val & (1 << 4)) ? ((val & (1 << 1)) ? 1 : 0) : 1; + int clk = (val & (1 << 5)) ? ((val & (1 << 2)) ? 1 : 0) : 1; - ddc_i2c_change(clk, data); - } - break; + ddc_i2c_change(clk, data); + } + break; - case 0xd0: - case 0xd1: - case 0xd2: - case 0xd3:WRITE8(addr, mach64->gen_test_cntl, val); -// if (val == 2) output = 3; - ati_eeprom_write(&mach64->eeprom, mach64->gen_test_cntl & 0x10, mach64->gen_test_cntl & 2, mach64->gen_test_cntl & 1); - mach64->gen_test_cntl = (mach64->gen_test_cntl & ~8) | (ati_eeprom_read(&mach64->eeprom) ? 8 : 0); - svga->hwcursor.ena = mach64->gen_test_cntl & 0x80; - mach64_cursor_dump(mach64); - break; + case 0xd0: + case 0xd1: + case 0xd2: + case 0xd3: + WRITE8(addr, mach64->gen_test_cntl, val); + // if (val == 2) output = 3; + ati_eeprom_write(&mach64->eeprom, mach64->gen_test_cntl & 0x10, mach64->gen_test_cntl & 2, + mach64->gen_test_cntl & 1); + mach64->gen_test_cntl = (mach64->gen_test_cntl & ~8) | (ati_eeprom_read(&mach64->eeprom) ? 8 : 0); + svga->hwcursor.ena = mach64->gen_test_cntl & 0x80; + mach64_cursor_dump(mach64); + break; - case 0xdc: - case 0xdd: - case 0xde: - case 0xdf:WRITE8(addr, mach64->config_cntl, val); - mach64_updatemapping(mach64); - break; + case 0xdc: + case 0xdd: + case 0xde: + case 0xdf: + WRITE8(addr, mach64->config_cntl, val); + mach64_updatemapping(mach64); + break; - case 0xe4: - case 0xe5: - case 0xe6: - case 0xe7: - if (mach64->type != MACH64_GX) - WRITE8(addr, mach64->config_stat0, val); - break; - } + case 0xe4: + case 0xe5: + case 0xe6: + case 0xe7: + if (mach64->type != MACH64_GX) + WRITE8(addr, mach64->config_stat0, val); + break; + } } void mach64_ext_writew(uint32_t addr, uint16_t val, void *p) { - mach64_t *mach64 = (mach64_t *)p; + mach64_t *mach64 = (mach64_t *)p; #ifdef MACH64_DEBUG - pclog("mach64_ext_writew : addr %08X val %04X\n", addr, val); + pclog("mach64_ext_writew : addr %08X val %04X\n", addr, val); #endif - if (!(addr & 0x400)) { + if (!(addr & 0x400)) { #ifdef MACH64_DEBUG - pclog("nmach64_ext_writew: addr=%04x val=%04x %04x(%08x):%08x\n", addr, val, CS, cs, cpu_state.pc); + pclog("nmach64_ext_writew: addr=%04x val=%04x %04x(%08x):%08x\n", addr, val, CS, cs, cpu_state.pc); #endif - mach64_ext_writeb(addr, val, p); - mach64_ext_writeb(addr + 1, val >> 8, p); - } else if (addr & 0x300) { - mach64_queue(mach64, addr & 0x3fe, val, FIFO_WRITE_WORD); - } else - switch (addr & 0x3fe) { - default: + mach64_ext_writeb(addr, val, p); + mach64_ext_writeb(addr + 1, val >> 8, p); + } else if (addr & 0x300) { + mach64_queue(mach64, addr & 0x3fe, val, FIFO_WRITE_WORD); + } else + switch (addr & 0x3fe) { + default: #ifdef MACH64_DEBUG - pclog(" "); + pclog(" "); #endif - mach64_ext_writeb(addr, val, p); + mach64_ext_writeb(addr, val, p); #ifdef MACH64_DEBUG - pclog(" "); + pclog(" "); #endif - mach64_ext_writeb(addr + 1, val >> 8, p); - break; - } + mach64_ext_writeb(addr + 1, val >> 8, p); + break; + } } void mach64_ext_writel(uint32_t addr, uint32_t val, void *p) { - mach64_t *mach64 = (mach64_t *)p; + mach64_t *mach64 = (mach64_t *)p; #ifdef MACH64_DEBUG - if ((addr & 0x3c0) != 0x200) + if ((addr & 0x3c0) != 0x200) pclog("mach64_ext_writel : addr %08X val %08X\n", addr, val); #endif - if (!(addr & 0x400)) { + if (!(addr & 0x400)) { #ifdef MACH64_DEBUG - pclog("nmach64_ext_writel: addr=%04x val=%08x %04x(%08x):%08x\n", addr, val, CS, cs, cpu_state.pc); + pclog("nmach64_ext_writel: addr=%04x val=%08x %04x(%08x):%08x\n", addr, val, CS, cs, cpu_state.pc); #endif - mach64_ext_writew(addr, val, p); - mach64_ext_writew(addr + 2, val >> 16, p); - } else if (addr & 0x300) { - mach64_queue(mach64, addr & 0x3fc, val, FIFO_WRITE_DWORD); - } else - switch (addr & 0x3fc) { - default: + mach64_ext_writew(addr, val, p); + mach64_ext_writew(addr + 2, val >> 16, p); + } else if (addr & 0x300) { + mach64_queue(mach64, addr & 0x3fc, val, FIFO_WRITE_DWORD); + } else + switch (addr & 0x3fc) { + default: #ifdef MACH64_DEBUG - pclog(" "); + pclog(" "); #endif - mach64_ext_writew(addr, val, p); + mach64_ext_writew(addr, val, p); #ifdef MACH64_DEBUG - pclog(" "); + pclog(" "); #endif - mach64_ext_writew(addr + 2, val >> 16, p); - break; - } + mach64_ext_writew(addr + 2, val >> 16, p); + break; + } } uint8_t mach64_ext_inb(uint16_t port, void *p) { - mach64_t *mach64 = (mach64_t *)p; - uint8_t ret; -// if (CS == 0x2be7) output = 3; - switch (port) { - case 0x02ec: - case 0x02ed: - case 0x02ee: - case 0x02ef: - case 0x7eec: - case 0x7eed: - case 0x7eee: - case 0x7eef:ret = mach64_ext_readb(0x400 | 0x00 | (port & 3), p); - break; - case 0x0aec: - case 0x0aed: - case 0x0aee: - case 0x0aef:ret = mach64_ext_readb(0x400 | 0x08 | (port & 3), p); - break; - case 0x0eec: - case 0x0eed: - case 0x0eee: - case 0x0eef:ret = mach64_ext_readb(0x400 | 0x0c | (port & 3), p); - break; + mach64_t *mach64 = (mach64_t *)p; + uint8_t ret; + // if (CS == 0x2be7) output = 3; + switch (port) { + case 0x02ec: + case 0x02ed: + case 0x02ee: + case 0x02ef: + case 0x7eec: + case 0x7eed: + case 0x7eee: + case 0x7eef: + ret = mach64_ext_readb(0x400 | 0x00 | (port & 3), p); + break; + case 0x0aec: + case 0x0aed: + case 0x0aee: + case 0x0aef: + ret = mach64_ext_readb(0x400 | 0x08 | (port & 3), p); + break; + case 0x0eec: + case 0x0eed: + case 0x0eee: + case 0x0eef: + ret = mach64_ext_readb(0x400 | 0x0c | (port & 3), p); + break; - case 0x12ec: - case 0x12ed: - case 0x12ee: - case 0x12ef:ret = mach64_ext_readb(0x400 | 0x10 | (port & 3), p); - break; + case 0x12ec: + case 0x12ed: + case 0x12ee: + case 0x12ef: + ret = mach64_ext_readb(0x400 | 0x10 | (port & 3), p); + break; - case 0x16ec: - case 0x16ed: - case 0x16ee: - case 0x16ef:ret = mach64_ext_readb(0x400 | 0x14 | (port & 3), p); - break; + case 0x16ec: + case 0x16ed: + case 0x16ee: + case 0x16ef: + ret = mach64_ext_readb(0x400 | 0x14 | (port & 3), p); + break; - case 0x1aec:ret = mach64_ext_readb(0x400 | 0x18, p); - break; + case 0x1aec: + ret = mach64_ext_readb(0x400 | 0x18, p); + break; - case 0x1eec: - case 0x1eed: - case 0x1eee: - case 0x1eef:ret = mach64_ext_readb(0x400 | 0x1c | (port & 3), p); - break; + case 0x1eec: + case 0x1eed: + case 0x1eee: + case 0x1eef: + ret = mach64_ext_readb(0x400 | 0x1c | (port & 3), p); + break; - case 0x22ec: - case 0x22ed: - case 0x22ee: - case 0x22ef:ret = mach64_ext_readb(0x400 | 0x40 | (port & 3), p); - break; - case 0x26ec: - case 0x26ed: - case 0x26ee: - case 0x26ef:ret = mach64_ext_readb(0x400 | 0x44 | (port & 3), p); - break; - case 0x2aec: - case 0x2aed: - case 0x2aee: - case 0x2aef:ret = mach64_ext_readb(0x400 | 0x48 | (port & 3), p); - break; - case 0x2eec: - case 0x2eed: - case 0x2eee: - case 0x2eef:ret = mach64_ext_readb(0x400 | 0x60 | (port & 3), p); - break; + case 0x22ec: + case 0x22ed: + case 0x22ee: + case 0x22ef: + ret = mach64_ext_readb(0x400 | 0x40 | (port & 3), p); + break; + case 0x26ec: + case 0x26ed: + case 0x26ee: + case 0x26ef: + ret = mach64_ext_readb(0x400 | 0x44 | (port & 3), p); + break; + case 0x2aec: + case 0x2aed: + case 0x2aee: + case 0x2aef: + ret = mach64_ext_readb(0x400 | 0x48 | (port & 3), p); + break; + case 0x2eec: + case 0x2eed: + case 0x2eee: + case 0x2eef: + ret = mach64_ext_readb(0x400 | 0x60 | (port & 3), p); + break; - case 0x32ec: - case 0x32ed: - case 0x32ee: - case 0x32ef:ret = mach64_ext_readb(0x400 | 0x64 | (port & 3), p); - break; - case 0x36ec: - case 0x36ed: - case 0x36ee: - case 0x36ef:ret = mach64_ext_readb(0x400 | 0x68 | (port & 3), p); - break; - case 0x3aec: - case 0x3aed: - case 0x3aee: - case 0x3aef:ret = mach64_ext_readb(0x400 | 0x6c | (port & 3), p); - break; - case 0x3eec: - case 0x3eed: - case 0x3eee: - case 0x3eef:ret = mach64_ext_readb(0x400 | 0x70 | (port & 3), p); - break; + case 0x32ec: + case 0x32ed: + case 0x32ee: + case 0x32ef: + ret = mach64_ext_readb(0x400 | 0x64 | (port & 3), p); + break; + case 0x36ec: + case 0x36ed: + case 0x36ee: + case 0x36ef: + ret = mach64_ext_readb(0x400 | 0x68 | (port & 3), p); + break; + case 0x3aec: + case 0x3aed: + case 0x3aee: + case 0x3aef: + ret = mach64_ext_readb(0x400 | 0x6c | (port & 3), p); + break; + case 0x3eec: + case 0x3eed: + case 0x3eee: + case 0x3eef: + ret = mach64_ext_readb(0x400 | 0x70 | (port & 3), p); + break; - case 0x42ec: - case 0x42ed: - case 0x42ee: - case 0x42ef:ret = mach64_ext_readb(0x400 | 0x80 | (port & 3), p); - break; - case 0x46ec: - case 0x46ed: - case 0x46ee: - case 0x46ef:ret = mach64_ext_readb(0x400 | 0x84 | (port & 3), p); - break; - case 0x4aec: - case 0x4aed: - case 0x4aee: - case 0x4aef:ret = mach64_ext_readb(0x400 | 0x90 | (port & 3), p); - break; + case 0x42ec: + case 0x42ed: + case 0x42ee: + case 0x42ef: + ret = mach64_ext_readb(0x400 | 0x80 | (port & 3), p); + break; + case 0x46ec: + case 0x46ed: + case 0x46ee: + case 0x46ef: + ret = mach64_ext_readb(0x400 | 0x84 | (port & 3), p); + break; + case 0x4aec: + case 0x4aed: + case 0x4aee: + case 0x4aef: + ret = mach64_ext_readb(0x400 | 0x90 | (port & 3), p); + break; - case 0x52ec: - case 0x52ed: - case 0x52ee: - case 0x52ef:ret = mach64_ext_readb(0x400 | 0xb0 | (port & 3), p); - break; + case 0x52ec: + case 0x52ed: + case 0x52ee: + case 0x52ef: + ret = mach64_ext_readb(0x400 | 0xb0 | (port & 3), p); + break; - case 0x56ec:ret = mach64_ext_readb(0x400 | 0xb4, p); - break; - case 0x56ed: - case 0x56ee:ret = mach64_ext_readb(0x400 | 0xb5, p); - break; - case 0x5aec:ret = mach64_ext_readb(0x400 | 0xb8, p); - break; - case 0x5aed: - case 0x5aee:ret = mach64_ext_readb(0x400 | 0xb9, p); - break; + case 0x56ec: + ret = mach64_ext_readb(0x400 | 0xb4, p); + break; + case 0x56ed: + case 0x56ee: + ret = mach64_ext_readb(0x400 | 0xb5, p); + break; + case 0x5aec: + ret = mach64_ext_readb(0x400 | 0xb8, p); + break; + case 0x5aed: + case 0x5aee: + ret = mach64_ext_readb(0x400 | 0xb9, p); + break; - case 0x5eec: - case 0x5eed: - case 0x5eee: - case 0x5eef: - if (mach64->type == MACH64_GX) - ret = ati68860_ramdac_in((port & 3) | ((mach64->dac_cntl & 3) << 2), &mach64->ramdac, &mach64->svga); - else - ret = ati68860_ramdac_in(port & 3, &mach64->ramdac, &mach64->svga); - break; + case 0x5eec: + case 0x5eed: + case 0x5eee: + case 0x5eef: + if (mach64->type == MACH64_GX) + ret = ati68860_ramdac_in((port & 3) | ((mach64->dac_cntl & 3) << 2), &mach64->ramdac, &mach64->svga); + else + ret = ati68860_ramdac_in(port & 3, &mach64->ramdac, &mach64->svga); + break; - case 0x62ec: - case 0x62ed: - case 0x62ee: - case 0x62ef:ret = mach64_ext_readb(0x400 | 0xc4 | (port & 3), p); - break; + case 0x62ec: + case 0x62ed: + case 0x62ee: + case 0x62ef: + ret = mach64_ext_readb(0x400 | 0xc4 | (port & 3), p); + break; - case 0x66ec: - case 0x66ed: - case 0x66ee: - case 0x66ef:ret = mach64_ext_readb(0x400 | 0xd0 | (port & 3), p); - break; + case 0x66ec: + case 0x66ed: + case 0x66ee: + case 0x66ef: + ret = mach64_ext_readb(0x400 | 0xd0 | (port & 3), p); + break; - case 0x6aec: - case 0x6aed: - case 0x6aee: - case 0x6aef:mach64->config_cntl = (mach64->config_cntl & ~0x3ff0) | ((mach64->linear_base >> 22) << 4); - READ8(port, mach64->config_cntl); - break; + case 0x6aec: + case 0x6aed: + case 0x6aee: + case 0x6aef: + mach64->config_cntl = (mach64->config_cntl & ~0x3ff0) | ((mach64->linear_base >> 22) << 4); + READ8(port, mach64->config_cntl); + break; - case 0x6eec: - case 0x6eed: - case 0x6eee: - case 0x6eef:ret = mach64_ext_readb(0x400 | 0xe0 | (port & 3), p); - break; + case 0x6eec: + case 0x6eed: + case 0x6eee: + case 0x6eef: + ret = mach64_ext_readb(0x400 | 0xe0 | (port & 3), p); + break; - case 0x72ec: - case 0x72ed: - case 0x72ee: - case 0x72ef:ret = mach64_ext_readb(0x400 | 0xe4 | (port & 3), p); - break; + case 0x72ec: + case 0x72ed: + case 0x72ee: + case 0x72ef: + ret = mach64_ext_readb(0x400 | 0xe4 | (port & 3), p); + break; - default:ret = 0; - break; - } + default: + ret = 0; + break; + } #ifdef MACH64_DEBUG - pclog("mach64_ext_inb : port %04X ret %02X %04X:%04X\n", port, ret, CS,cpu_state.pc); + pclog("mach64_ext_inb : port %04X ret %02X %04X:%04X\n", port, ret, CS, cpu_state.pc); #endif - return ret; + return ret; } uint16_t mach64_ext_inw(uint16_t port, void *p) { - uint16_t ret; - switch (port) { - default: + uint16_t ret; + switch (port) { + default: #ifdef MACH64_DEBUG - pclog(" "); + pclog(" "); #endif - ret = mach64_ext_inb(port, p); + ret = mach64_ext_inb(port, p); #ifdef MACH64_DEBUG - pclog(" "); + pclog(" "); #endif - ret |= (mach64_ext_inb(port + 1, p) << 8); - break; - } + ret |= (mach64_ext_inb(port + 1, p) << 8); + break; + } #ifdef MACH64_DEBUG - pclog("mach64_ext_inw : port %04X ret %04X\n", port, ret); + pclog("mach64_ext_inw : port %04X ret %04X\n", port, ret); #endif - return ret; + return ret; } uint32_t mach64_ext_inl(uint16_t port, void *p) { - uint32_t ret; - switch (port) { - case 0x56ec:ret = mach64_ext_readl(0x400 | 0xb4, p); - break; - case 0x5aec:ret = mach64_ext_readl(0x400 | 0xb8, p); - break; + uint32_t ret; + switch (port) { + case 0x56ec: + ret = mach64_ext_readl(0x400 | 0xb4, p); + break; + case 0x5aec: + ret = mach64_ext_readl(0x400 | 0xb8, p); + break; - default: + default: #ifdef MACH64_DEBUG - pclog(" "); + pclog(" "); #endif - ret = mach64_ext_inw(port, p); + ret = mach64_ext_inw(port, p); #ifdef MACH64_DEBUG - pclog(" "); + pclog(" "); #endif - ret |= (mach64_ext_inw(port + 2, p) << 16); - break; - } + ret |= (mach64_ext_inw(port + 2, p) << 16); + break; + } #ifdef MACH64_DEBUG - pclog("mach64_ext_inl : port %04X ret %08X\n", port, ret); + pclog("mach64_ext_inl : port %04X ret %08X\n", port, ret); #endif - return ret; + return ret; } void mach64_ext_outb(uint16_t port, uint8_t val, void *p) { - mach64_t *mach64 = (mach64_t *)p; + mach64_t *mach64 = (mach64_t *)p; #ifdef MACH64_DEBUG - pclog("mach64_ext_outb : port %04X val %02X %04X:%04X\n", port, val, CS,cpu_state.pc); + pclog("mach64_ext_outb : port %04X val %02X %04X:%04X\n", port, val, CS, cpu_state.pc); #endif - switch (port) { - case 0x02ec: - case 0x02ed: - case 0x02ee: - case 0x02ef: - case 0x7eec: - case 0x7eed: - case 0x7eee: - case 0x7eef:mach64_ext_writeb(0x400 | 0x00 | (port & 3), val, p); - break; - case 0x0aec: - case 0x0aed: - case 0x0aee: - case 0x0aef:mach64_ext_writeb(0x400 | 0x08 | (port & 3), val, p); - break; - case 0x0eec: - case 0x0eed: - case 0x0eee: - case 0x0eef:mach64_ext_writeb(0x400 | 0x0c | (port & 3), val, p); - break; + switch (port) { + case 0x02ec: + case 0x02ed: + case 0x02ee: + case 0x02ef: + case 0x7eec: + case 0x7eed: + case 0x7eee: + case 0x7eef: + mach64_ext_writeb(0x400 | 0x00 | (port & 3), val, p); + break; + case 0x0aec: + case 0x0aed: + case 0x0aee: + case 0x0aef: + mach64_ext_writeb(0x400 | 0x08 | (port & 3), val, p); + break; + case 0x0eec: + case 0x0eed: + case 0x0eee: + case 0x0eef: + mach64_ext_writeb(0x400 | 0x0c | (port & 3), val, p); + break; - case 0x16ec: - case 0x16ed: - case 0x16ee: - case 0x16ef:mach64_ext_writeb(0x400 | 0x14 | (port & 3), val, p); - break; + case 0x16ec: + case 0x16ed: + case 0x16ee: + case 0x16ef: + mach64_ext_writeb(0x400 | 0x14 | (port & 3), val, p); + break; - case 0x1aec:mach64_ext_writeb(0x400 | 0x18, val, p); - break; + case 0x1aec: + mach64_ext_writeb(0x400 | 0x18, val, p); + break; - case 0x1eec: - case 0x1eed: - case 0x1eee: - case 0x1eef:mach64_ext_writeb(0x400 | 0x1c | (port & 3), val, p); - break; + case 0x1eec: + case 0x1eed: + case 0x1eee: + case 0x1eef: + mach64_ext_writeb(0x400 | 0x1c | (port & 3), val, p); + break; - case 0x22ec: - case 0x22ed: - case 0x22ee: - case 0x22ef:mach64_ext_writeb(0x400 | 0x40 | (port & 3), val, p); - break; - case 0x26ec: - case 0x26ed: - case 0x26ee: - case 0x26ef:mach64_ext_writeb(0x400 | 0x44 | (port & 3), val, p); - break; - case 0x2aec: - case 0x2aed: - case 0x2aee: - case 0x2aef:mach64_ext_writeb(0x400 | 0x48 | (port & 3), val, p); - break; - case 0x2eec: - case 0x2eed: - case 0x2eee: - case 0x2eef:mach64_ext_writeb(0x400 | 0x60 | (port & 3), val, p); - break; + case 0x22ec: + case 0x22ed: + case 0x22ee: + case 0x22ef: + mach64_ext_writeb(0x400 | 0x40 | (port & 3), val, p); + break; + case 0x26ec: + case 0x26ed: + case 0x26ee: + case 0x26ef: + mach64_ext_writeb(0x400 | 0x44 | (port & 3), val, p); + break; + case 0x2aec: + case 0x2aed: + case 0x2aee: + case 0x2aef: + mach64_ext_writeb(0x400 | 0x48 | (port & 3), val, p); + break; + case 0x2eec: + case 0x2eed: + case 0x2eee: + case 0x2eef: + mach64_ext_writeb(0x400 | 0x60 | (port & 3), val, p); + break; - case 0x32ec: - case 0x32ed: - case 0x32ee: - case 0x32ef:mach64_ext_writeb(0x400 | 0x64 | (port & 3), val, p); - break; - case 0x36ec: - case 0x36ed: - case 0x36ee: - case 0x36ef:mach64_ext_writeb(0x400 | 0x68 | (port & 3), val, p); - break; - case 0x3aec: - case 0x3aed: - case 0x3aee: - case 0x3aef:mach64_ext_writeb(0x400 | 0x6c | (port & 3), val, p); - break; - case 0x3eec: - case 0x3eed: - case 0x3eee: - case 0x3eef:mach64_ext_writeb(0x400 | 0x70 | (port & 3), val, p); - break; + case 0x32ec: + case 0x32ed: + case 0x32ee: + case 0x32ef: + mach64_ext_writeb(0x400 | 0x64 | (port & 3), val, p); + break; + case 0x36ec: + case 0x36ed: + case 0x36ee: + case 0x36ef: + mach64_ext_writeb(0x400 | 0x68 | (port & 3), val, p); + break; + case 0x3aec: + case 0x3aed: + case 0x3aee: + case 0x3aef: + mach64_ext_writeb(0x400 | 0x6c | (port & 3), val, p); + break; + case 0x3eec: + case 0x3eed: + case 0x3eee: + case 0x3eef: + mach64_ext_writeb(0x400 | 0x70 | (port & 3), val, p); + break; - case 0x42ec: - case 0x42ed: - case 0x42ee: - case 0x42ef:mach64_ext_writeb(0x400 | 0x80 | (port & 3), val, p); - break; - case 0x46ec: - case 0x46ed: - case 0x46ee: - case 0x46ef:mach64_ext_writeb(0x400 | 0x84 | (port & 3), val, p); - break; - case 0x4aec: - case 0x4aed: - case 0x4aee: - case 0x4aef:mach64_ext_writeb(0x400 | 0x90 | (port & 3), val, p); - break; + case 0x42ec: + case 0x42ed: + case 0x42ee: + case 0x42ef: + mach64_ext_writeb(0x400 | 0x80 | (port & 3), val, p); + break; + case 0x46ec: + case 0x46ed: + case 0x46ee: + case 0x46ef: + mach64_ext_writeb(0x400 | 0x84 | (port & 3), val, p); + break; + case 0x4aec: + case 0x4aed: + case 0x4aee: + case 0x4aef: + mach64_ext_writeb(0x400 | 0x90 | (port & 3), val, p); + break; - case 0x52ec: - case 0x52ed: - case 0x52ee: - case 0x52ef:mach64_ext_writeb(0x400 | 0xb0 | (port & 3), val, p); - break; + case 0x52ec: + case 0x52ed: + case 0x52ee: + case 0x52ef: + mach64_ext_writeb(0x400 | 0xb0 | (port & 3), val, p); + break; - case 0x56ec:mach64_ext_writeb(0x400 | 0xb4, val, p); - break; - case 0x56ed: - case 0x56ee:mach64_ext_writeb(0x400 | 0xb5, val, p); - break; - case 0x5aec:mach64_ext_writeb(0x400 | 0xb8, val, p); - break; - case 0x5aed: - case 0x5aee:mach64_ext_writeb(0x400 | 0xb9, val, p); - break; + case 0x56ec: + mach64_ext_writeb(0x400 | 0xb4, val, p); + break; + case 0x56ed: + case 0x56ee: + mach64_ext_writeb(0x400 | 0xb5, val, p); + break; + case 0x5aec: + mach64_ext_writeb(0x400 | 0xb8, val, p); + break; + case 0x5aed: + case 0x5aee: + mach64_ext_writeb(0x400 | 0xb9, val, p); + break; - case 0x5eec: - case 0x5eed: - case 0x5eee: - case 0x5eef: - if (mach64->type == MACH64_GX) - ati68860_ramdac_out((port & 3) | ((mach64->dac_cntl & 3) << 2), val, &mach64->ramdac, &mach64->svga); - else - ati68860_ramdac_out(port & 3, val, &mach64->ramdac, &mach64->svga); - break; + case 0x5eec: + case 0x5eed: + case 0x5eee: + case 0x5eef: + if (mach64->type == MACH64_GX) + ati68860_ramdac_out((port & 3) | ((mach64->dac_cntl & 3) << 2), val, &mach64->ramdac, &mach64->svga); + else + ati68860_ramdac_out(port & 3, val, &mach64->ramdac, &mach64->svga); + break; - case 0x62ec: - case 0x62ed: - case 0x62ee: - case 0x62ef:mach64_ext_writeb(0x400 | 0xc4 | (port & 3), val, p); - break; + case 0x62ec: + case 0x62ed: + case 0x62ee: + case 0x62ef: + mach64_ext_writeb(0x400 | 0xc4 | (port & 3), val, p); + break; - case 0x66ec: - case 0x66ed: - case 0x66ee: - case 0x66ef:mach64_ext_writeb(0x400 | 0xd0 | (port & 3), val, p); - break; + case 0x66ec: + case 0x66ed: + case 0x66ee: + case 0x66ef: + mach64_ext_writeb(0x400 | 0xd0 | (port & 3), val, p); + break; - case 0x6aec: - case 0x6aed: - case 0x6aee: - case 0x6aef:WRITE8(port, mach64->config_cntl, val); - mach64_updatemapping(mach64); - break; - } + case 0x6aec: + case 0x6aed: + case 0x6aee: + case 0x6aef: + WRITE8(port, mach64->config_cntl, val); + mach64_updatemapping(mach64); + break; + } } void mach64_ext_outw(uint16_t port, uint16_t val, void *p) { #ifdef MACH64_DEBUG - pclog("mach64_ext_outw : port %04X val %04X\n", port, val); + pclog("mach64_ext_outw : port %04X val %04X\n", port, val); #endif - switch (port) { - default: + switch (port) { + default: #ifdef MACH64_DEBUG - pclog(" "); + pclog(" "); #endif - mach64_ext_outb(port, val, p); + mach64_ext_outb(port, val, p); #ifdef MACH64_DEBUG - pclog(" "); + pclog(" "); #endif - mach64_ext_outb(port + 1, val >> 8, p); - break; - } + mach64_ext_outb(port + 1, val >> 8, p); + break; + } } void mach64_ext_outl(uint16_t port, uint32_t val, void *p) { - pclog("mach64_ext_outl : port %04X val %08X\n", port, val); - switch (port) { - default: + pclog("mach64_ext_outl : port %04X val %08X\n", port, val); + switch (port) { + default: #ifdef MACH64_DEBUG - pclog(" "); + pclog(" "); #endif - mach64_ext_outw(port, val, p); + mach64_ext_outw(port, val, p); #ifdef MACH64_DEBUG - pclog(" "); + pclog(" "); #endif - mach64_ext_outw(port + 2, val >> 16, p); - break; - } + mach64_ext_outw(port + 2, val >> 16, p); + break; + } } static uint8_t mach64_block_inb(uint16_t port, void *p) { - mach64_t *mach64 = (mach64_t *)p; - uint8_t ret; + mach64_t *mach64 = (mach64_t *)p; + uint8_t ret; - ret = mach64_ext_readb(0x400 | (port & 0x3ff), mach64); + ret = mach64_ext_readb(0x400 | (port & 0x3ff), mach64); #ifdef MACH64_DEBUG - pclog("mach64_block_inb : port %04X ret %02X %04x:%04x\n", port, ret, CS,cpu_state.pc); + pclog("mach64_block_inb : port %04X ret %02X %04x:%04x\n", port, ret, CS, cpu_state.pc); #endif - return ret; + return ret; } static uint16_t mach64_block_inw(uint16_t port, void *p) { - mach64_t *mach64 = (mach64_t *)p; - uint16_t ret; + mach64_t *mach64 = (mach64_t *)p; + uint16_t ret; - ret = mach64_ext_readw(0x400 | (port & 0x3ff), mach64); + ret = mach64_ext_readw(0x400 | (port & 0x3ff), mach64); #ifdef MACH64_DEBUG - pclog("mach64_block_inw : port %04X ret %04X\n", port, ret); + pclog("mach64_block_inw : port %04X ret %04X\n", port, ret); #endif - return ret; + return ret; } static uint32_t mach64_block_inl(uint16_t port, void *p) { - mach64_t *mach64 = (mach64_t *)p; - uint32_t ret; + mach64_t *mach64 = (mach64_t *)p; + uint32_t ret; - ret = mach64_ext_readl(0x400 | (port & 0x3ff), mach64); + ret = mach64_ext_readl(0x400 | (port & 0x3ff), mach64); #ifdef MACH64_DEBUG - pclog("mach64_block_inl : port %04X ret %08X\n", port, ret); + pclog("mach64_block_inl : port %04X ret %08X\n", port, ret); #endif - return ret; + return ret; } static void mach64_block_outb(uint16_t port, uint8_t val, void *p) { - mach64_t *mach64 = (mach64_t *)p; + mach64_t *mach64 = (mach64_t *)p; #ifdef MACH64_DEBUG - pclog("mach64_block_outb : port %04X val %02X\n ", port, val); + pclog("mach64_block_outb : port %04X val %02X\n ", port, val); #endif - mach64_ext_writeb(0x400 | (port & 0x3ff), val, mach64); + mach64_ext_writeb(0x400 | (port & 0x3ff), val, mach64); } static void mach64_block_outw(uint16_t port, uint16_t val, void *p) { - mach64_t *mach64 = (mach64_t *)p; + mach64_t *mach64 = (mach64_t *)p; #ifdef MACH64_DEBUG - pclog("mach64_block_outw : port %04X val %04X\n ", port, val); + pclog("mach64_block_outw : port %04X val %04X\n ", port, val); #endif - mach64_ext_writew(0x400 | (port & 0x3ff), val, mach64); + mach64_ext_writew(0x400 | (port & 0x3ff), val, mach64); } static void mach64_block_outl(uint16_t port, uint32_t val, void *p) { - mach64_t *mach64 = (mach64_t *)p; + mach64_t *mach64 = (mach64_t *)p; #ifdef MACH64_DEBUG - pclog("mach64_block_outl : port %04X val %08X\n ", port, val); + pclog("mach64_block_outl : port %04X val %08X\n ", port, val); #endif - mach64_ext_writel(0x400 | (port & 0x3ff), val, mach64); + mach64_ext_writel(0x400 | (port & 0x3ff), val, mach64); } void mach64_write(uint32_t addr, uint8_t val, void *p) { - mach64_t *mach64 = (mach64_t *)p; - svga_t *svga = &mach64->svga; -// pclog("mach64_write : %05X %02X ", addr, val); - addr = (addr & 0x7fff) + mach64->bank_w[(addr >> 15) & 1]; -// pclog("%08X\n", addr); - svga_write_linear(addr, val, svga); + mach64_t *mach64 = (mach64_t *)p; + svga_t *svga = &mach64->svga; + // pclog("mach64_write : %05X %02X ", addr, val); + addr = (addr & 0x7fff) + mach64->bank_w[(addr >> 15) & 1]; + // pclog("%08X\n", addr); + svga_write_linear(addr, val, svga); } void mach64_writew(uint32_t addr, uint16_t val, void *p) { - mach64_t *mach64 = (mach64_t *)p; - svga_t *svga = &mach64->svga; + mach64_t *mach64 = (mach64_t *)p; + svga_t *svga = &mach64->svga; - addr = (addr & 0x7fff) + mach64->bank_w[(addr >> 15) & 1]; - svga_writew_linear(addr, val, svga); + addr = (addr & 0x7fff) + mach64->bank_w[(addr >> 15) & 1]; + svga_writew_linear(addr, val, svga); } void mach64_writel(uint32_t addr, uint32_t val, void *p) { - mach64_t *mach64 = (mach64_t *)p; - svga_t *svga = &mach64->svga; + mach64_t *mach64 = (mach64_t *)p; + svga_t *svga = &mach64->svga; - addr = (addr & 0x7fff) + mach64->bank_w[(addr >> 15) & 1]; - svga_writel_linear(addr, val, svga); + addr = (addr & 0x7fff) + mach64->bank_w[(addr >> 15) & 1]; + svga_writel_linear(addr, val, svga); } uint8_t mach64_read(uint32_t addr, void *p) { - mach64_t *mach64 = (mach64_t *)p; - svga_t *svga = &mach64->svga; - uint8_t ret; -// pclog("mach64_read : %05X ", addr); - addr = (addr & 0x7fff) + mach64->bank_r[(addr >> 15) & 1]; - ret = svga_read_linear(addr, svga); -// pclog("%08X %02X\n", addr, ret); - return ret; + mach64_t *mach64 = (mach64_t *)p; + svga_t *svga = &mach64->svga; + uint8_t ret; + // pclog("mach64_read : %05X ", addr); + addr = (addr & 0x7fff) + mach64->bank_r[(addr >> 15) & 1]; + ret = svga_read_linear(addr, svga); + // pclog("%08X %02X\n", addr, ret); + return ret; } uint16_t mach64_readw(uint32_t addr, void *p) { - mach64_t *mach64 = (mach64_t *)p; - svga_t *svga = &mach64->svga; + mach64_t *mach64 = (mach64_t *)p; + svga_t *svga = &mach64->svga; - addr = (addr & 0x7fff) + mach64->bank_r[(addr >> 15) & 1]; - return svga_readw_linear(addr, svga); + addr = (addr & 0x7fff) + mach64->bank_r[(addr >> 15) & 1]; + return svga_readw_linear(addr, svga); } uint32_t mach64_readl(uint32_t addr, void *p) { - mach64_t *mach64 = (mach64_t *)p; - svga_t *svga = &mach64->svga; + mach64_t *mach64 = (mach64_t *)p; + svga_t *svga = &mach64->svga; - addr = (addr & 0x7fff) + mach64->bank_r[(addr >> 15) & 1]; - return svga_readl_linear(addr, svga); + addr = (addr & 0x7fff) + mach64->bank_r[(addr >> 15) & 1]; + return svga_readl_linear(addr, svga); } void mach64_hwcursor_draw(svga_t *svga, int displine) { - mach64_t *mach64 = (mach64_t *)svga->p; - int x, offset; - uint8_t dat; - uint32_t col0 = mach64->ramdac.pallook[0]; - uint32_t col1 = mach64->ramdac.pallook[1]; + mach64_t *mach64 = (mach64_t *)svga->p; + int x, offset; + uint8_t dat; + uint32_t col0 = mach64->ramdac.pallook[0]; + uint32_t col1 = mach64->ramdac.pallook[1]; - offset = svga->hwcursor_latch.xoff; - for (x = 0; x < 64 - svga->hwcursor_latch.xoff; x += 4) { - dat = svga->vram[svga->hwcursor_latch.addr + (offset >> 2)]; - if (!(dat & 2)) - ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 32] = (dat & 1) ? col1 : col0; - else if ((dat & 3) == 3) - ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 32] ^= 0xFFFFFF; - dat >>= 2; - if (!(dat & 2)) - ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 33] = (dat & 1) ? col1 : col0; - else if ((dat & 3) == 3) - ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 33] ^= 0xFFFFFF; - dat >>= 2; - if (!(dat & 2)) - ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 34] = (dat & 1) ? col1 : col0; - else if ((dat & 3) == 3) - ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 34] ^= 0xFFFFFF; - dat >>= 2; - if (!(dat & 2)) - ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 35] = (dat & 1) ? col1 : col0; - else if ((dat & 3) == 3) - ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 35] ^= 0xFFFFFF; - dat >>= 2; - offset += 4; - } - svga->hwcursor_latch.addr += 16; + offset = svga->hwcursor_latch.xoff; + for (x = 0; x < 64 - svga->hwcursor_latch.xoff; x += 4) { + dat = svga->vram[svga->hwcursor_latch.addr + (offset >> 2)]; + if (!(dat & 2)) + ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 32] = (dat & 1) ? col1 : col0; + else if ((dat & 3) == 3) + ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 32] ^= 0xFFFFFF; + dat >>= 2; + if (!(dat & 2)) + ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 33] = (dat & 1) ? col1 : col0; + else if ((dat & 3) == 3) + ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 33] ^= 0xFFFFFF; + dat >>= 2; + if (!(dat & 2)) + ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 34] = (dat & 1) ? col1 : col0; + else if ((dat & 3) == 3) + ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 34] ^= 0xFFFFFF; + dat >>= 2; + if (!(dat & 2)) + ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 35] = (dat & 1) ? col1 : col0; + else if ((dat & 3) == 3) + ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 35] ^= 0xFFFFFF; + dat >>= 2; + offset += 4; + } + svga->hwcursor_latch.addr += 16; } -#define CLAMP(x) do \ - { \ - if ((x) & ~0xff) \ - x = ((x) < 0) ? 0 : 0xff; \ - } \ - while (0) - -#define DECODE_ARGB1555() \ - do \ - { \ - for (x = 0; x < mach64->svga.overlay_latch.xsize; x++) \ - { \ - uint16_t dat = ((uint16_t *)src)[x]; \ - \ - int b = dat & 0x1f; \ - int g = (dat >> 5) & 0x1f; \ - int r = (dat >> 10) & 0x1f; \ - \ - b = (b << 3) | (b >> 2); \ - g = (g << 3) | (g >> 2); \ - r = (r << 3) | (r >> 2); \ - \ - mach64->overlay_dat[x] = (r << 16) | (g << 8) | b; \ - } \ +#define CLAMP(x) \ + do { \ + if ((x) & ~0xff) \ + x = ((x) < 0) ? 0 : 0xff; \ } while (0) -#define DECODE_RGB565() \ - do \ - { \ - for (x = 0; x < mach64->svga.overlay_latch.xsize; x++) \ - { \ - uint16_t dat = ((uint16_t *)src)[x]; \ - \ - int b = dat & 0x1f; \ - int g = (dat >> 5) & 0x3f; \ - int r = (dat >> 11) & 0x1f; \ - \ - b = (b << 3) | (b >> 2); \ - g = (g << 2) | (g >> 4); \ - r = (r << 3) | (r >> 2); \ - \ - mach64->overlay_dat[x] = (r << 16) | (g << 8) | b; \ - } \ +#define DECODE_ARGB1555() \ + do { \ + for (x = 0; x < mach64->svga.overlay_latch.xsize; x++) { \ + uint16_t dat = ((uint16_t *)src)[x]; \ + \ + int b = dat & 0x1f; \ + int g = (dat >> 5) & 0x1f; \ + int r = (dat >> 10) & 0x1f; \ + \ + b = (b << 3) | (b >> 2); \ + g = (g << 3) | (g >> 2); \ + r = (r << 3) | (r >> 2); \ + \ + mach64->overlay_dat[x] = (r << 16) | (g << 8) | b; \ + } \ } while (0) -#define DECODE_ARGB8888() \ - do \ - { \ - for (x = 0; x < mach64->svga.overlay_latch.xsize; x++) \ - { \ - int b = src[0]; \ - int g = src[1]; \ - int r = src[2]; \ - src += 4; \ - \ - mach64->overlay_dat[x] = (r << 16) | (g << 8) | b; \ - } \ +#define DECODE_RGB565() \ + do { \ + for (x = 0; x < mach64->svga.overlay_latch.xsize; x++) { \ + uint16_t dat = ((uint16_t *)src)[x]; \ + \ + int b = dat & 0x1f; \ + int g = (dat >> 5) & 0x3f; \ + int r = (dat >> 11) & 0x1f; \ + \ + b = (b << 3) | (b >> 2); \ + g = (g << 2) | (g >> 4); \ + r = (r << 3) | (r >> 2); \ + \ + mach64->overlay_dat[x] = (r << 16) | (g << 8) | b; \ + } \ } while (0) -#define DECODE_VYUY422() \ - do \ - { \ - for (x = 0; x < mach64->svga.overlay_latch.xsize; x += 2) \ - { \ - uint8_t y1, y2; \ - int8_t u, v; \ - int dR, dG, dB; \ - int r, g, b; \ - \ - y1 = src[0]; \ - u = src[1] - 0x80; \ - y2 = src[2]; \ - v = src[3] - 0x80; \ - src += 4; \ - \ - dR = (359*v) >> 8; \ - dG = (88*u + 183*v) >> 8; \ - dB = (453*u) >> 8; \ - \ - r = y1 + dR; \ - CLAMP(r); \ - g = y1 - dG; \ - CLAMP(g); \ - b = y1 + dB; \ - CLAMP(b); \ - mach64->overlay_dat[x] = (r << 16) | (g << 8) | b; \ - \ - r = y2 + dR; \ - CLAMP(r); \ - g = y2 - dG; \ - CLAMP(g); \ - b = y2 + dB; \ - CLAMP(b); \ - mach64->overlay_dat[x+1] = (r << 16) | (g << 8) | b; \ - } \ +#define DECODE_ARGB8888() \ + do { \ + for (x = 0; x < mach64->svga.overlay_latch.xsize; x++) { \ + int b = src[0]; \ + int g = src[1]; \ + int r = src[2]; \ + src += 4; \ + \ + mach64->overlay_dat[x] = (r << 16) | (g << 8) | b; \ + } \ } while (0) -#define DECODE_YVYU422() \ - do \ - { \ - for (x = 0; x < mach64->svga.overlay_latch.xsize; x += 2) \ - { \ - uint8_t y1, y2; \ - int8_t u, v; \ - int dR, dG, dB; \ - int r, g, b; \ - \ - u = src[0] - 0x80; \ - y1 = src[1]; \ - v = src[2] - 0x80; \ - y2 = src[3]; \ - src += 4; \ - \ - dR = (359*v) >> 8; \ - dG = (88*u + 183*v) >> 8; \ - dB = (453*u) >> 8; \ - \ - r = y1 + dR; \ - CLAMP(r); \ - g = y1 - dG; \ - CLAMP(g); \ - b = y1 + dB; \ - CLAMP(b); \ - mach64->overlay_dat[x] = (r << 16) | (g << 8) | b; \ - \ - r = y2 + dR; \ - CLAMP(r); \ - g = y2 - dG; \ - CLAMP(g); \ - b = y2 + dB; \ - CLAMP(b); \ - mach64->overlay_dat[x+1] = (r << 16) | (g << 8) | b; \ - } \ +#define DECODE_VYUY422() \ + do { \ + for (x = 0; x < mach64->svga.overlay_latch.xsize; x += 2) { \ + uint8_t y1, y2; \ + int8_t u, v; \ + int dR, dG, dB; \ + int r, g, b; \ + \ + y1 = src[0]; \ + u = src[1] - 0x80; \ + y2 = src[2]; \ + v = src[3] - 0x80; \ + src += 4; \ + \ + dR = (359 * v) >> 8; \ + dG = (88 * u + 183 * v) >> 8; \ + dB = (453 * u) >> 8; \ + \ + r = y1 + dR; \ + CLAMP(r); \ + g = y1 - dG; \ + CLAMP(g); \ + b = y1 + dB; \ + CLAMP(b); \ + mach64->overlay_dat[x] = (r << 16) | (g << 8) | b; \ + \ + r = y2 + dR; \ + CLAMP(r); \ + g = y2 - dG; \ + CLAMP(g); \ + b = y2 + dB; \ + CLAMP(b); \ + mach64->overlay_dat[x + 1] = (r << 16) | (g << 8) | b; \ + } \ + } while (0) + +#define DECODE_YVYU422() \ + do { \ + for (x = 0; x < mach64->svga.overlay_latch.xsize; x += 2) { \ + uint8_t y1, y2; \ + int8_t u, v; \ + int dR, dG, dB; \ + int r, g, b; \ + \ + u = src[0] - 0x80; \ + y1 = src[1]; \ + v = src[2] - 0x80; \ + y2 = src[3]; \ + src += 4; \ + \ + dR = (359 * v) >> 8; \ + dG = (88 * u + 183 * v) >> 8; \ + dB = (453 * u) >> 8; \ + \ + r = y1 + dR; \ + CLAMP(r); \ + g = y1 - dG; \ + CLAMP(g); \ + b = y1 + dB; \ + CLAMP(b); \ + mach64->overlay_dat[x] = (r << 16) | (g << 8) | b; \ + \ + r = y2 + dR; \ + CLAMP(r); \ + g = y2 - dG; \ + CLAMP(g); \ + b = y2 + dB; \ + CLAMP(b); \ + mach64->overlay_dat[x + 1] = (r << 16) | (g << 8) | b; \ + } \ } while (0) void mach64_overlay_draw(svga_t *svga, int displine) { - mach64_t *mach64 = (mach64_t *)svga->p; - int x; - int h_acc = 0; - int h_max = (mach64->scaler_height_width >> 16) & 0x3ff; - int h_inc = mach64->overlay_scale_inc >> 16; - int v_max = mach64->scaler_height_width & 0x3ff; - int v_inc = mach64->overlay_scale_inc & 0xffff; - uint32_t *p; - uint8_t *src = &svga->vram[svga->overlay.addr]; - int old_y = mach64->overlay_v_acc; - int y_diff; - int video_key_fn = mach64->overlay_key_cntl & 5; - int graphics_key_fn = (mach64->overlay_key_cntl >> 4) & 5; - int overlay_cmp_mix = (mach64->overlay_key_cntl >> 8) & 0xf; + mach64_t *mach64 = (mach64_t *)svga->p; + int x; + int h_acc = 0; + int h_max = (mach64->scaler_height_width >> 16) & 0x3ff; + int h_inc = mach64->overlay_scale_inc >> 16; + int v_max = mach64->scaler_height_width & 0x3ff; + int v_inc = mach64->overlay_scale_inc & 0xffff; + uint32_t *p; + uint8_t *src = &svga->vram[svga->overlay.addr]; + int old_y = mach64->overlay_v_acc; + int y_diff; + int video_key_fn = mach64->overlay_key_cntl & 5; + int graphics_key_fn = (mach64->overlay_key_cntl >> 4) & 5; + int overlay_cmp_mix = (mach64->overlay_key_cntl >> 8) & 0xf; - p = &((uint32_t *)buffer32->line[displine])[32 + mach64->svga.overlay_latch.x]; + p = &((uint32_t *)buffer32->line[displine])[32 + mach64->svga.overlay_latch.x]; - if (mach64->scaler_update) { - switch (mach64->scaler_format) { - case 0x3:DECODE_ARGB1555(); - break; - case 0x4:DECODE_RGB565(); - break; - case 0x6:DECODE_ARGB8888(); - break; - case 0xb:DECODE_VYUY422(); - break; - case 0xc:DECODE_YVYU422(); - break; + if (mach64->scaler_update) { + switch (mach64->scaler_format) { + case 0x3: + DECODE_ARGB1555(); + break; + case 0x4: + DECODE_RGB565(); + break; + case 0x6: + DECODE_ARGB8888(); + break; + case 0xb: + DECODE_VYUY422(); + break; + case 0xc: + DECODE_YVYU422(); + break; - default:pclog("Unknown Mach64 scaler format %x\n", mach64->scaler_format); - /*Fill buffer with something recognisably wrong*/ - for (x = 0; x < mach64->svga.overlay_latch.xsize; x++) - mach64->overlay_dat[x] = 0xff00ff; - break; - } - } + default: + pclog("Unknown Mach64 scaler format %x\n", mach64->scaler_format); + /*Fill buffer with something recognisably wrong*/ + for (x = 0; x < mach64->svga.overlay_latch.xsize; x++) + mach64->overlay_dat[x] = 0xff00ff; + break; + } + } - if (overlay_cmp_mix == 2) { - for (x = 0; x < mach64->svga.overlay_latch.xsize; x++) { - int h = h_acc >> 12; + if (overlay_cmp_mix == 2) { + for (x = 0; x < mach64->svga.overlay_latch.xsize; x++) { + int h = h_acc >> 12; - p[x] = mach64->overlay_dat[h]; + p[x] = mach64->overlay_dat[h]; - h_acc += h_inc; - if (h_acc > (h_max << 12)) - h_acc = (h_max << 12); - } - } else { - for (x = 0; x < mach64->svga.overlay_latch.xsize; x++) { - int h = h_acc >> 12; - int gr_cmp = 0, vid_cmp = 0; - int use_video; + h_acc += h_inc; + if (h_acc > (h_max << 12)) + h_acc = (h_max << 12); + } + } else { + for (x = 0; x < mach64->svga.overlay_latch.xsize; x++) { + int h = h_acc >> 12; + int gr_cmp = 0, vid_cmp = 0; + int use_video; - switch (video_key_fn) { - case 0:vid_cmp = 0; - break; - case 1:vid_cmp = 1; - break; - case 4:vid_cmp = ((mach64->overlay_dat[h] ^ mach64->overlay_video_key_clr) & mach64->overlay_video_key_msk); - break; - case 5:vid_cmp = !((mach64->overlay_dat[h] ^ mach64->overlay_video_key_clr) & mach64->overlay_video_key_msk); - break; - } - switch (graphics_key_fn) { - case 0:gr_cmp = 0; - break; - case 1:gr_cmp = 1; - break; - case 4:gr_cmp = (((p[x]) ^ mach64->overlay_graphics_key_clr) & mach64->overlay_graphics_key_msk & 0xffffff); - break; - case 5:gr_cmp = !(((p[x]) ^ mach64->overlay_graphics_key_clr) & mach64->overlay_graphics_key_msk & 0xffffff); - break; - } - vid_cmp = vid_cmp ? -1 : 0; - gr_cmp = gr_cmp ? -1 : 0; + switch (video_key_fn) { + case 0: + vid_cmp = 0; + break; + case 1: + vid_cmp = 1; + break; + case 4: + vid_cmp = ((mach64->overlay_dat[h] ^ mach64->overlay_video_key_clr) & + mach64->overlay_video_key_msk); + break; + case 5: + vid_cmp = !((mach64->overlay_dat[h] ^ mach64->overlay_video_key_clr) & + mach64->overlay_video_key_msk); + break; + } + switch (graphics_key_fn) { + case 0: + gr_cmp = 0; + break; + case 1: + gr_cmp = 1; + break; + case 4: + gr_cmp = (((p[x]) ^ mach64->overlay_graphics_key_clr) & mach64->overlay_graphics_key_msk & + 0xffffff); + break; + case 5: + gr_cmp = !(((p[x]) ^ mach64->overlay_graphics_key_clr) & mach64->overlay_graphics_key_msk & + 0xffffff); + break; + } + vid_cmp = vid_cmp ? -1 : 0; + gr_cmp = gr_cmp ? -1 : 0; - switch (overlay_cmp_mix) { - case 0x0:use_video = gr_cmp; - break; - case 0x1:use_video = 0; - break; - case 0x2:use_video = ~0; - break; - case 0x3:use_video = ~gr_cmp; - break; - case 0x4:use_video = ~vid_cmp; - break; - case 0x5:use_video = gr_cmp ^ vid_cmp; - break; - case 0x6:use_video = ~gr_cmp ^ vid_cmp; - break; - case 0x7:use_video = vid_cmp; - break; - case 0x8:use_video = ~gr_cmp | ~vid_cmp; - break; - case 0x9:use_video = gr_cmp | ~vid_cmp; - break; - case 0xa:use_video = ~gr_cmp | vid_cmp; - break; - case 0xb:use_video = gr_cmp | vid_cmp; - break; - case 0xc:use_video = gr_cmp & vid_cmp; - break; - case 0xd:use_video = ~gr_cmp & vid_cmp; - break; - case 0xe:use_video = gr_cmp & ~vid_cmp; - break; - case 0xf:use_video = ~gr_cmp & ~vid_cmp; - break; - } + switch (overlay_cmp_mix) { + case 0x0: + use_video = gr_cmp; + break; + case 0x1: + use_video = 0; + break; + case 0x2: + use_video = ~0; + break; + case 0x3: + use_video = ~gr_cmp; + break; + case 0x4: + use_video = ~vid_cmp; + break; + case 0x5: + use_video = gr_cmp ^ vid_cmp; + break; + case 0x6: + use_video = ~gr_cmp ^ vid_cmp; + break; + case 0x7: + use_video = vid_cmp; + break; + case 0x8: + use_video = ~gr_cmp | ~vid_cmp; + break; + case 0x9: + use_video = gr_cmp | ~vid_cmp; + break; + case 0xa: + use_video = ~gr_cmp | vid_cmp; + break; + case 0xb: + use_video = gr_cmp | vid_cmp; + break; + case 0xc: + use_video = gr_cmp & vid_cmp; + break; + case 0xd: + use_video = ~gr_cmp & vid_cmp; + break; + case 0xe: + use_video = gr_cmp & ~vid_cmp; + break; + case 0xf: + use_video = ~gr_cmp & ~vid_cmp; + break; + } - if (use_video) - p[x] = mach64->overlay_dat[h]; + if (use_video) + p[x] = mach64->overlay_dat[h]; - h_acc += h_inc; - if (h_acc > (h_max << 12)) - h_acc = (h_max << 12); - } - } + h_acc += h_inc; + if (h_acc > (h_max << 12)) + h_acc = (h_max << 12); + } + } - mach64->overlay_v_acc += v_inc; - if (mach64->overlay_v_acc > (v_max << 12)) - mach64->overlay_v_acc = v_max << 12; + mach64->overlay_v_acc += v_inc; + if (mach64->overlay_v_acc > (v_max << 12)) + mach64->overlay_v_acc = v_max << 12; - y_diff = (mach64->overlay_v_acc >> 12) - (old_y >> 12); + y_diff = (mach64->overlay_v_acc >> 12) - (old_y >> 12); - if (mach64->scaler_format == 6) - svga->overlay.addr += svga->overlay.pitch * 4 * y_diff; - else - svga->overlay.addr += svga->overlay.pitch * 2 * y_diff; + if (mach64->scaler_format == 6) + svga->overlay.addr += svga->overlay.pitch * 4 * y_diff; + else + svga->overlay.addr += svga->overlay.pitch * 2 * y_diff; - mach64->scaler_update = y_diff; + mach64->scaler_update = y_diff; } static void mach64_io_remove(mach64_t *mach64) { - int c; + int c; - io_removehandler(0x03c0, 0x0020, mach64_in, NULL, NULL, mach64_out, NULL, NULL, mach64); + io_removehandler(0x03c0, 0x0020, mach64_in, NULL, NULL, mach64_out, NULL, NULL, mach64); - for (c = 0; c < 8; c++) { - io_removehandler((c * 0x1000) + 0x2ec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); - io_removehandler((c * 0x1000) + 0x6ec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); - io_removehandler((c * 0x1000) + 0xaec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); - io_removehandler((c * 0x1000) + 0xeec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); - } + for (c = 0; c < 8; c++) { + io_removehandler((c * 0x1000) + 0x2ec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, + mach64_ext_outw, mach64_ext_outl, mach64); + io_removehandler((c * 0x1000) + 0x6ec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, + mach64_ext_outw, mach64_ext_outl, mach64); + io_removehandler((c * 0x1000) + 0xaec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, + mach64_ext_outw, mach64_ext_outl, mach64); + io_removehandler((c * 0x1000) + 0xeec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, + mach64_ext_outw, mach64_ext_outl, mach64); + } - io_removehandler(0x01ce, 0x0002, mach64_in, NULL, NULL, mach64_out, NULL, NULL, mach64); + io_removehandler(0x01ce, 0x0002, mach64_in, NULL, NULL, mach64_out, NULL, NULL, mach64); - if (mach64->block_decoded_io && mach64->block_decoded_io < 0x10000) - io_removehandler(mach64->block_decoded_io, 0x0400, mach64_block_inb, mach64_block_inw, mach64_block_inl, mach64_block_outb, mach64_block_outw, mach64_block_outl, mach64); + if (mach64->block_decoded_io && mach64->block_decoded_io < 0x10000) + io_removehandler(mach64->block_decoded_io, 0x0400, mach64_block_inb, mach64_block_inw, mach64_block_inl, + mach64_block_outb, mach64_block_outw, mach64_block_outl, mach64); } static void mach64_io_set(mach64_t *mach64) { - int c; + int c; - mach64_io_remove(mach64); + mach64_io_remove(mach64); - io_sethandler(0x03c0, 0x0020, mach64_in, NULL, NULL, mach64_out, NULL, NULL, mach64); + io_sethandler(0x03c0, 0x0020, mach64_in, NULL, NULL, mach64_out, NULL, NULL, mach64); - if (!mach64->use_block_decoded_io) { - for (c = 0; c < 8; c++) { - io_sethandler((c * 0x1000) + 0x2ec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); - io_sethandler((c * 0x1000) + 0x6ec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); - io_sethandler((c * 0x1000) + 0xaec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); - io_sethandler((c * 0x1000) + 0xeec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); - } - } + if (!mach64->use_block_decoded_io) { + for (c = 0; c < 8; c++) { + io_sethandler((c * 0x1000) + 0x2ec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, + mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); + io_sethandler((c * 0x1000) + 0x6ec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, + mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); + io_sethandler((c * 0x1000) + 0xaec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, + mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); + io_sethandler((c * 0x1000) + 0xeec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, + mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); + } + } - io_sethandler(0x01ce, 0x0002, mach64_in, NULL, NULL, mach64_out, NULL, NULL, mach64); + io_sethandler(0x01ce, 0x0002, mach64_in, NULL, NULL, mach64_out, NULL, NULL, mach64); - if (mach64->use_block_decoded_io && mach64->block_decoded_io && mach64->block_decoded_io < 0x10000) - io_sethandler(mach64->block_decoded_io, 0x0400, mach64_block_inb, mach64_block_inw, mach64_block_inl, mach64_block_outb, mach64_block_outw, mach64_block_outl, mach64); + if (mach64->use_block_decoded_io && mach64->block_decoded_io && mach64->block_decoded_io < 0x10000) + io_sethandler(mach64->block_decoded_io, 0x0400, mach64_block_inb, mach64_block_inw, mach64_block_inl, + mach64_block_outb, mach64_block_outw, mach64_block_outl, mach64); } uint8_t mach64_pci_read(int func, int addr, void *p) { - mach64_t *mach64 = (mach64_t *)p; + mach64_t *mach64 = (mach64_t *)p; -// pclog("Mach64 PCI read %08X\n", addr); + // pclog("Mach64 PCI read %08X\n", addr); - switch (addr) { - case 0x00:return 0x02; /*ATi*/ - case 0x01:return 0x10; + switch (addr) { + case 0x00: + return 0x02; /*ATi*/ + case 0x01: + return 0x10; - case 0x02:return mach64->pci_id & 0xff; - case 0x03:return mach64->pci_id >> 8; + case 0x02: + return mach64->pci_id & 0xff; + case 0x03: + return mach64->pci_id >> 8; - case PCI_REG_COMMAND:return mach64->pci_regs[PCI_REG_COMMAND]; /*Respond to IO and memory accesses*/ + case PCI_REG_COMMAND: + return mach64->pci_regs[PCI_REG_COMMAND]; /*Respond to IO and memory accesses*/ - case 0x07:return 1 << 1; /*Medium DEVSEL timing*/ + case 0x07: + return 1 << 1; /*Medium DEVSEL timing*/ - case 0x08: /*Revision ID*/ - if (mach64->type == MACH64_GX) - return 0; - return 0x40; + case 0x08: /*Revision ID*/ + if (mach64->type == MACH64_GX) + return 0; + return 0x40; - case 0x09:return 0; /*Programming interface*/ + case 0x09: + return 0; /*Programming interface*/ - case 0x0a:return 0x01; /*Supports VGA interface, XGA compatible*/ - case 0x0b:return 0x03; + case 0x0a: + return 0x01; /*Supports VGA interface, XGA compatible*/ + case 0x0b: + return 0x03; - case 0x10:return 0x00; /*Linear frame buffer address*/ - case 0x11:return 0x00; - case 0x12:return mach64->linear_base >> 16; - case 0x13:return mach64->linear_base >> 24; + case 0x10: + return 0x00; /*Linear frame buffer address*/ + case 0x11: + return 0x00; + case 0x12: + return mach64->linear_base >> 16; + case 0x13: + return mach64->linear_base >> 24; - case 0x14: - if (mach64->type == MACH64_VT2) - return 0x01; /*Block decoded IO address*/ - return 0; - case 0x15:return mach64->block_decoded_io >> 8; - case 0x16:return mach64->block_decoded_io >> 16; - case 0x17:return mach64->block_decoded_io >> 24; + case 0x14: + if (mach64->type == MACH64_VT2) + return 0x01; /*Block decoded IO address*/ + return 0; + case 0x15: + return mach64->block_decoded_io >> 8; + case 0x16: + return mach64->block_decoded_io >> 16; + case 0x17: + return mach64->block_decoded_io >> 24; - case 0x30:return mach64->pci_regs[0x30] & 0x01; /*BIOS ROM address*/ - case 0x31:return 0x00; - case 0x32:return mach64->pci_regs[0x32]; - case 0x33:return mach64->pci_regs[0x33]; + case 0x30: + return mach64->pci_regs[0x30] & 0x01; /*BIOS ROM address*/ + case 0x31: + return 0x00; + case 0x32: + return mach64->pci_regs[0x32]; + case 0x33: + return mach64->pci_regs[0x33]; - case 0x3c:return mach64->int_line; - case 0x3d:return PCI_INTA; + case 0x3c: + return mach64->int_line; + case 0x3d: + return PCI_INTA; - case 0x40:return mach64->use_block_decoded_io; - } - return 0; + case 0x40: + return mach64->use_block_decoded_io; + } + return 0; } void mach64_pci_write(int func, int addr, uint8_t val, void *p) { - mach64_t *mach64 = (mach64_t *)p; + mach64_t *mach64 = (mach64_t *)p; -// pclog("Mach64 PCI write %08X %02X\n", addr, val); + // pclog("Mach64 PCI write %08X %02X\n", addr, val); - switch (addr) { - case PCI_REG_COMMAND:mach64->pci_regs[PCI_REG_COMMAND] = val & 0x27; - if (val & PCI_COMMAND_IO) - mach64_io_set(mach64); - else - mach64_io_remove(mach64); - mach64_updatemapping(mach64); - break; + switch (addr) { + case PCI_REG_COMMAND: + mach64->pci_regs[PCI_REG_COMMAND] = val & 0x27; + if (val & PCI_COMMAND_IO) + mach64_io_set(mach64); + else + mach64_io_remove(mach64); + mach64_updatemapping(mach64); + break; - case 0x12: - if (mach64->type == MACH64_VT2) - val = 0; - mach64->linear_base = (mach64->linear_base & 0xff000000) | ((val & 0x80) << 16); - mach64_updatemapping(mach64); - break; - case 0x13:mach64->linear_base = (mach64->linear_base & 0x800000) | (val << 24); - mach64_updatemapping(mach64); - break; + case 0x12: + if (mach64->type == MACH64_VT2) + val = 0; + mach64->linear_base = (mach64->linear_base & 0xff000000) | ((val & 0x80) << 16); + mach64_updatemapping(mach64); + break; + case 0x13: + mach64->linear_base = (mach64->linear_base & 0x800000) | (val << 24); + mach64_updatemapping(mach64); + break; - case 0x15: - if (mach64->type == MACH64_VT2) { - if (mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) - mach64_io_remove(mach64); - mach64->block_decoded_io = (mach64->block_decoded_io & 0xffff0000) | ((val & 0xfc) << 8); - if (mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) - mach64_io_set(mach64); - } - break; - case 0x16: - if (mach64->type == MACH64_VT2) { - if (mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) - mach64_io_remove(mach64); - mach64->block_decoded_io = (mach64->block_decoded_io & 0xff00fc00) | (val << 16); - if (mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) - mach64_io_set(mach64); - } - break; - case 0x17: - if (mach64->type == MACH64_VT2) { - if (mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) - mach64_io_remove(mach64); - mach64->block_decoded_io = (mach64->block_decoded_io & 0x00fffc00) | (val << 24); - if (mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) - mach64_io_set(mach64); - } - break; + case 0x15: + if (mach64->type == MACH64_VT2) { + if (mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) + mach64_io_remove(mach64); + mach64->block_decoded_io = (mach64->block_decoded_io & 0xffff0000) | ((val & 0xfc) << 8); + if (mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) + mach64_io_set(mach64); + } + break; + case 0x16: + if (mach64->type == MACH64_VT2) { + if (mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) + mach64_io_remove(mach64); + mach64->block_decoded_io = (mach64->block_decoded_io & 0xff00fc00) | (val << 16); + if (mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) + mach64_io_set(mach64); + } + break; + case 0x17: + if (mach64->type == MACH64_VT2) { + if (mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) + mach64_io_remove(mach64); + mach64->block_decoded_io = (mach64->block_decoded_io & 0x00fffc00) | (val << 24); + if (mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) + mach64_io_set(mach64); + } + break; - case 0x30: - case 0x32: - case 0x33:mach64->pci_regs[addr] = val; - if (mach64->pci_regs[0x30] & 0x01) { - uint32_t addr = (mach64->pci_regs[0x32] << 16) | (mach64->pci_regs[0x33] << 24); - pclog("Mach64 bios_rom enabled at %08x\n", addr); - mem_mapping_set_addr(&mach64->bios_rom.mapping, addr, 0x8000); - } else { - pclog("Mach64 bios_rom disabled\n"); - mem_mapping_disable(&mach64->bios_rom.mapping); - } - return; + case 0x30: + case 0x32: + case 0x33: + mach64->pci_regs[addr] = val; + if (mach64->pci_regs[0x30] & 0x01) { + uint32_t addr = (mach64->pci_regs[0x32] << 16) | (mach64->pci_regs[0x33] << 24); + pclog("Mach64 bios_rom enabled at %08x\n", addr); + mem_mapping_set_addr(&mach64->bios_rom.mapping, addr, 0x8000); + } else { + pclog("Mach64 bios_rom disabled\n"); + mem_mapping_disable(&mach64->bios_rom.mapping); + } + return; - case 0x3c:mach64->int_line = val; - break; + case 0x3c: + mach64->int_line = val; + break; - case 0x40: - if (mach64->type == MACH64_VT2) { - if (mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) - mach64_io_remove(mach64); - mach64->use_block_decoded_io = val & 0x04; - if (mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) - mach64_io_set(mach64); - } - break; - } + case 0x40: + if (mach64->type == MACH64_VT2) { + if (mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) + mach64_io_remove(mach64); + mach64->use_block_decoded_io = val & 0x04; + if (mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) + mach64_io_set(mach64); + } + break; + } } static void *mach64_common_init() { - mach64_t *mach64 = malloc(sizeof(mach64_t)); - memset(mach64, 0, sizeof(mach64_t)); + mach64_t *mach64 = malloc(sizeof(mach64_t)); + memset(mach64, 0, sizeof(mach64_t)); - mach64->vram_size = device_get_config_int("memory"); - mach64->vram_mask = (mach64->vram_size << 20) - 1; + mach64->vram_size = device_get_config_int("memory"); + mach64->vram_mask = (mach64->vram_size << 20) - 1; - svga_init(&mach64->svga, mach64, mach64->vram_size << 20, - mach64_recalctimings, - mach64_in, mach64_out, - mach64_hwcursor_draw, - mach64_overlay_draw); + svga_init(&mach64->svga, mach64, mach64->vram_size << 20, mach64_recalctimings, mach64_in, mach64_out, + mach64_hwcursor_draw, mach64_overlay_draw); - if (PCI) - mem_mapping_disable(&mach64->bios_rom.mapping); + if (PCI) + mem_mapping_disable(&mach64->bios_rom.mapping); - mem_mapping_add(&mach64->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL, 0, &mach64->svga); - mem_mapping_add(&mach64->mmio_linear_mapping, 0, 0, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel, NULL, 0, mach64); - mem_mapping_add(&mach64->mmio_linear_mapping_2, 0, 0, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel, NULL, 0, mach64); - mem_mapping_add(&mach64->mmio_mapping, 0xbc000, 0x04000, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel, NULL, 0, mach64); - mem_mapping_disable(&mach64->mmio_mapping); + mem_mapping_add(&mach64->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, + svga_writew_linear, svga_writel_linear, NULL, 0, &mach64->svga); + mem_mapping_add(&mach64->mmio_linear_mapping, 0, 0, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, + mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel, NULL, 0, mach64); + mem_mapping_add(&mach64->mmio_linear_mapping_2, 0, 0, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, + mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel, NULL, 0, mach64); + mem_mapping_add(&mach64->mmio_mapping, 0xbc000, 0x04000, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, + mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel, NULL, 0, mach64); + mem_mapping_disable(&mach64->mmio_mapping); - mach64_io_set(mach64); + mach64_io_set(mach64); - mach64->card = pci_add(mach64_pci_read, mach64_pci_write, mach64); + mach64->card = pci_add(mach64_pci_read, mach64_pci_write, mach64); - mach64->pci_regs[PCI_REG_COMMAND] = 3; - mach64->pci_regs[0x30] = 0x00; - mach64->pci_regs[0x32] = 0x0c; - mach64->pci_regs[0x33] = 0x00; + mach64->pci_regs[PCI_REG_COMMAND] = 3; + mach64->pci_regs[0x30] = 0x00; + mach64->pci_regs[0x32] = 0x0c; + mach64->pci_regs[0x33] = 0x00; - ati68860_ramdac_init(&mach64->ramdac); + ati68860_ramdac_init(&mach64->ramdac); - mach64->dst_cntl = 3; + mach64->dst_cntl = 3; - mach64->wake_fifo_thread = thread_create_event(); - mach64->fifo_not_full_event = thread_create_event(); - mach64->fifo_thread = thread_create(fifo_thread, mach64); + mach64->wake_fifo_thread = thread_create_event(); + mach64->fifo_not_full_event = thread_create_event(); + mach64->fifo_thread = thread_create(fifo_thread, mach64); - ddc_init(); + ddc_init(); - return mach64; + return mach64; } static void *mach64gx_init() { - mach64_t *mach64 = mach64_common_init(); + mach64_t *mach64 = mach64_common_init(); - mach64->type = MACH64_GX; - mach64->pci_id = (int)'X' | ((int)'G' << 8); - mach64->config_chip_id = 0x020000d7; - mach64->dac_cntl = 5 << 16; /*ATI 68860 RAMDAC*/ - mach64->config_stat0 = (5 << 9) | (3 << 3); /*ATI-68860, 256Kx16 DRAM*/ - if (PCI) - mach64->config_stat0 |= 0; /*PCI, 256Kx16 DRAM*/ - else - mach64->config_stat0 |= 1; /*VLB, 256Kx16 DRAM*/ + mach64->type = MACH64_GX; + mach64->pci_id = (int)'X' | ((int)'G' << 8); + mach64->config_chip_id = 0x020000d7; + mach64->dac_cntl = 5 << 16; /*ATI 68860 RAMDAC*/ + mach64->config_stat0 = (5 << 9) | (3 << 3); /*ATI-68860, 256Kx16 DRAM*/ + if (PCI) + mach64->config_stat0 |= 0; /*PCI, 256Kx16 DRAM*/ + else + mach64->config_stat0 |= 1; /*VLB, 256Kx16 DRAM*/ - ati_eeprom_load(&mach64->eeprom, "mach64.nvr", 1); + ati_eeprom_load(&mach64->eeprom, "mach64.nvr", 1); - rom_init(&mach64->bios_rom, "mach64gx/bios.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&mach64->bios_rom, "mach64gx/bios.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - return mach64; + return mach64; } static void *mach64vt2_init() { - mach64_t *mach64 = mach64_common_init(); - svga_t *svga = &mach64->svga; + mach64_t *mach64 = mach64_common_init(); + svga_t *svga = &mach64->svga; - mach64->type = MACH64_VT2; - mach64->pci_id = 0x5654; - mach64->config_chip_id = 0x40005654; - mach64->dac_cntl = 1 << 16; /*Internal 24-bit DAC*/ - mach64->config_stat0 = 4; - mach64->use_block_decoded_io = PCI ? 4 : 0; + mach64->type = MACH64_VT2; + mach64->pci_id = 0x5654; + mach64->config_chip_id = 0x40005654; + mach64->dac_cntl = 1 << 16; /*Internal 24-bit DAC*/ + mach64->config_stat0 = 4; + mach64->use_block_decoded_io = PCI ? 4 : 0; - ati_eeprom_load(&mach64->eeprom, "mach64vt.nvr", 1); + ati_eeprom_load(&mach64->eeprom, "mach64vt.nvr", 1); - rom_init(&mach64->bios_rom, "atimach64vt2pci.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&mach64->bios_rom, "atimach64vt2pci.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - svga->vblank_start = mach64_vblank_start; + svga->vblank_start = mach64_vblank_start; - return mach64; + return mach64; } -int mach64gx_available() { - return rom_present("mach64gx/bios.bin"); -} -int mach64vt2_available() { - return rom_present("atimach64vt2pci.bin"); -} +int mach64gx_available() { return rom_present("mach64gx/bios.bin"); } +int mach64vt2_available() { return rom_present("atimach64vt2pci.bin"); } void mach64_close(void *p) { - mach64_t *mach64 = (mach64_t *)p; + mach64_t *mach64 = (mach64_t *)p; - svga_close(&mach64->svga); + svga_close(&mach64->svga); - thread_kill(mach64->fifo_thread); - thread_destroy_event(mach64->wake_fifo_thread); - thread_destroy_event(mach64->fifo_not_full_event); + thread_kill(mach64->fifo_thread); + thread_destroy_event(mach64->wake_fifo_thread); + thread_destroy_event(mach64->fifo_not_full_event); - free(mach64); + free(mach64); } void mach64_speed_changed(void *p) { - mach64_t *mach64 = (mach64_t *)p; + mach64_t *mach64 = (mach64_t *)p; - svga_recalctimings(&mach64->svga); + svga_recalctimings(&mach64->svga); } void mach64_force_redraw(void *p) { - mach64_t *mach64 = (mach64_t *)p; + mach64_t *mach64 = (mach64_t *)p; - mach64->svga.fullchange = changeframecount; + mach64->svga.fullchange = changeframecount; } void mach64_add_status_info(char *s, int max_len, void *p) { - mach64_t *mach64 = (mach64_t *)p; - char temps[256]; - uint64_t new_time = timer_read(); - uint64_t status_diff = new_time - mach64->status_time; - mach64->status_time = new_time; + mach64_t *mach64 = (mach64_t *)p; + char temps[256]; + uint64_t new_time = timer_read(); + uint64_t status_diff = new_time - mach64->status_time; + mach64->status_time = new_time; - if (((mach64->crtc_gen_cntl >> 24) & 3) == 3) { - svga_t *svga = &mach64->svga; - char temps[128]; - int bpp = 4; + if (((mach64->crtc_gen_cntl >> 24) & 3) == 3) { + svga_t *svga = &mach64->svga; + char temps[128]; + int bpp = 4; - strncat(s, "Mach64 in native mode\n", max_len); + strncat(s, "Mach64 in native mode\n", max_len); - switch ((mach64->crtc_gen_cntl >> 8) & 7) { - case 1:bpp = 4; - break; - case 2:bpp = 8; - break; - case 3:bpp = 15; - break; - case 4:bpp = 16; - break; - case 5:bpp = 24; - break; - case 6:bpp = 32; - break; - } + switch ((mach64->crtc_gen_cntl >> 8) & 7) { + case 1: + bpp = 4; + break; + case 2: + bpp = 8; + break; + case 3: + bpp = 15; + break; + case 4: + bpp = 16; + break; + case 5: + bpp = 24; + break; + case 6: + bpp = 32; + break; + } - sprintf(temps, "Mach64 colour depth : %i bpp\n", bpp); - strncat(s, temps, max_len); + sprintf(temps, "Mach64 colour depth : %i bpp\n", bpp); + strncat(s, temps, max_len); - sprintf(temps, "Mach64 resolution : %i x %i\n", svga->hdisp, svga->dispend); - strncat(s, temps, max_len); + sprintf(temps, "Mach64 resolution : %i x %i\n", svga->hdisp, svga->dispend); + strncat(s, temps, max_len); - sprintf(temps, "Mach64 refresh rate : %i Hz\n\n", svga->frames); - svga->frames = 0; - strncat(s, temps, max_len); - } else { - strncat(s, "Mach64 in SVGA mode\n", max_len); - svga_add_status_info(s, max_len, &mach64->svga); - } + sprintf(temps, "Mach64 refresh rate : %i Hz\n\n", svga->frames); + svga->frames = 0; + strncat(s, temps, max_len); + } else { + strncat(s, "Mach64 in SVGA mode\n", max_len); + svga_add_status_info(s, max_len, &mach64->svga); + } - sprintf(temps, "%f%% CPU\n%f%% CPU (real)\n\n", ((double)mach64->blitter_time * 100.0) / timer_freq, ((double)mach64->blitter_time * 100.0) / status_diff); - strncat(s, temps, max_len); + sprintf(temps, "%f%% CPU\n%f%% CPU (real)\n\n", ((double)mach64->blitter_time * 100.0) / timer_freq, + ((double)mach64->blitter_time * 100.0) / status_diff); + strncat(s, temps, max_len); - mach64->blitter_time = 0; + mach64->blitter_time = 0; } -static device_config_t mach64gx_config[] = - { - { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "1 MB", - .value = 1 - }, - { - .description = "2 MB", - .value = 2 - }, - { - .description = "4 MB", - .value = 4 - }, - { - .description = "" - } - }, - .default_int = 4 - }, - { - .type = -1 - } - }; -static device_config_t mach64vt2_config[] = - { - { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "2 MB", - .value = 2 - }, - { - .description = "4 MB", - .value = 4 - }, - { - .description = "" - } - }, - .default_int = 4 - }, - { - .type = -1 - } - }; +static device_config_t mach64gx_config[] = {{.name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .selection = {{.description = "1 MB", .value = 1}, + {.description = "2 MB", .value = 2}, + {.description = "4 MB", .value = 4}, + {.description = ""}}, + .default_int = 4}, + {.type = -1}}; +static device_config_t mach64vt2_config[] = { + {.name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .selection = {{.description = "2 MB", .value = 2}, {.description = "4 MB", .value = 4}, {.description = ""}}, + .default_int = 4}, + {.type = -1}}; -device_t mach64gx_device = - { - "ATI Mach64GX", - 0, - mach64gx_init, - mach64_close, - mach64gx_available, - mach64_speed_changed, - mach64_force_redraw, - mach64_add_status_info, - mach64gx_config - }; -device_t mach64vt2_device = - { - "ATI Mach64VT2", - DEVICE_PCI, - mach64vt2_init, - mach64_close, - mach64vt2_available, - mach64_speed_changed, - mach64_force_redraw, - mach64_add_status_info, - mach64vt2_config - }; +device_t mach64gx_device = {"ATI Mach64GX", 0, + mach64gx_init, mach64_close, + mach64gx_available, mach64_speed_changed, + mach64_force_redraw, mach64_add_status_info, + mach64gx_config}; +device_t mach64vt2_device = {"ATI Mach64VT2", DEVICE_PCI, mach64vt2_init, mach64_close, + mach64vt2_available, mach64_speed_changed, mach64_force_redraw, mach64_add_status_info, + mach64vt2_config}; diff --git a/src/video/vid_cga.c b/src/video/vid_cga.c index 6ff01569..8da15734 100644 --- a/src/video/vid_cga.c +++ b/src/video/vid_cga.c @@ -13,503 +13,465 @@ #define COMPOSITE_OLD 0 #define COMPOSITE_NEW 1 -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[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}; void cga_recalctimings(cga_t *cga); void cga_out(uint16_t addr, uint8_t val, void *p) { - cga_t *cga = (cga_t *)p; - uint8_t old; -// pclog("CGA_OUT %04X %02X\n", addr, val); - switch (addr) { - case 0x3d0: - case 0x3d2: - case 0x3d4: - case 0x3d6:cga->crtcreg = val & 31; - return; - case 0x3d1: - case 0x3d3: - case 0x3d5: - case 0x3d7:old = cga->crtc[cga->crtcreg]; - cga->crtc[cga->crtcreg] = val & crtcmask[cga->crtcreg]; - if (old != val) { - if (cga->crtcreg < 0xe || cga->crtcreg > 0x10) { - fullchange = changeframecount; - cga_recalctimings(cga); - } - } - return; - case 0x3D8: - if (((cga->cgamode ^ val) & 5) != 0) { - cga->cgamode = val; - update_cga16_color(cga->cgamode); - } - cga->cgamode = val; - return; - case 0x3D9:cga->cgacol = val; - return; - } + cga_t *cga = (cga_t *)p; + uint8_t old; + // pclog("CGA_OUT %04X %02X\n", addr, val); + switch (addr) { + case 0x3d0: + case 0x3d2: + case 0x3d4: + case 0x3d6: + cga->crtcreg = val & 31; + return; + case 0x3d1: + case 0x3d3: + case 0x3d5: + case 0x3d7: + old = cga->crtc[cga->crtcreg]; + cga->crtc[cga->crtcreg] = val & crtcmask[cga->crtcreg]; + if (old != val) { + if (cga->crtcreg < 0xe || cga->crtcreg > 0x10) { + fullchange = changeframecount; + cga_recalctimings(cga); + } + } + return; + case 0x3D8: + if (((cga->cgamode ^ val) & 5) != 0) { + cga->cgamode = val; + update_cga16_color(cga->cgamode); + } + cga->cgamode = val; + return; + case 0x3D9: + cga->cgacol = val; + return; + } } uint8_t cga_in(uint16_t addr, void *p) { - cga_t *cga = (cga_t *)p; -// pclog("CGA_IN %04X\n", addr); - switch (addr) { - case 0x3D4:return cga->crtcreg; - case 0x3D5:return cga->crtc[cga->crtcreg]; - case 0x3DA:return cga->cgastat; - } - return 0xFF; + cga_t *cga = (cga_t *)p; + // pclog("CGA_IN %04X\n", addr); + switch (addr) { + case 0x3D4: + return cga->crtcreg; + case 0x3D5: + return cga->crtc[cga->crtcreg]; + case 0x3DA: + return cga->cgastat; + } + return 0xFF; } void cga_write(uint32_t addr, uint8_t val, void *p) { - cga_t *cga = (cga_t *)p; -// pclog("CGA_WRITE %04X %02X\n", addr, val); - cga->vram[addr & 0x3fff] = val; - if (cga->snow_enabled) { - int offset = ((timer_get_remaining_u64(&cga->timer) / CGACONST) * 2) & 0xfc; - cga->charbuffer[offset] = cga->vram[addr & 0x3fff]; - cga->charbuffer[offset | 1] = cga->vram[addr & 0x3fff]; - } - egawrites++; - cycles -= 4; + cga_t *cga = (cga_t *)p; + // pclog("CGA_WRITE %04X %02X\n", addr, val); + cga->vram[addr & 0x3fff] = val; + if (cga->snow_enabled) { + int offset = ((timer_get_remaining_u64(&cga->timer) / CGACONST) * 2) & 0xfc; + cga->charbuffer[offset] = cga->vram[addr & 0x3fff]; + cga->charbuffer[offset | 1] = cga->vram[addr & 0x3fff]; + } + egawrites++; + cycles -= 4; } uint8_t cga_read(uint32_t addr, void *p) { - cga_t *cga = (cga_t *)p; - cycles -= 4; - if (cga->snow_enabled) { - int offset = ((timer_get_remaining_u64(&cga->timer) / CGACONST) * 2) & 0xfc; - cga->charbuffer[offset] = cga->vram[addr & 0x3fff]; - cga->charbuffer[offset | 1] = cga->vram[addr & 0x3fff]; - } - egareads++; -// pclog("CGA_READ %04X\n", addr); - return cga->vram[addr & 0x3fff]; + cga_t *cga = (cga_t *)p; + cycles -= 4; + if (cga->snow_enabled) { + int offset = ((timer_get_remaining_u64(&cga->timer) / CGACONST) * 2) & 0xfc; + cga->charbuffer[offset] = cga->vram[addr & 0x3fff]; + cga->charbuffer[offset | 1] = cga->vram[addr & 0x3fff]; + } + egareads++; + // pclog("CGA_READ %04X\n", addr); + return cga->vram[addr & 0x3fff]; } void cga_recalctimings(cga_t *cga) { - double disptime; - double _dispontime, _dispofftime; - pclog("Recalc - %i %i %i\n", cga->crtc[0], cga->crtc[1], cga->cgamode & 1); - if (cga->cgamode & 1) { - disptime = cga->crtc[0] + 1; - _dispontime = cga->crtc[1]; - } else { - disptime = (cga->crtc[0] + 1) << 1; - _dispontime = cga->crtc[1] << 1; - } - _dispofftime = disptime - _dispontime; -// printf("%i %f %f %f %i %i\n",cgamode&1,disptime,dispontime,dispofftime,crtc[0],crtc[1]); - _dispontime *= CGACONST; - _dispofftime *= CGACONST; -// printf("Timings - on %f off %f frame %f second %f\n",dispontime,dispofftime,(dispontime+dispofftime)*262.0,(dispontime+dispofftime)*262.0*59.92); - cga->dispontime = (uint64_t)_dispontime; - cga->dispofftime = (uint64_t)_dispofftime; + double disptime; + double _dispontime, _dispofftime; + pclog("Recalc - %i %i %i\n", cga->crtc[0], cga->crtc[1], cga->cgamode & 1); + if (cga->cgamode & 1) { + disptime = cga->crtc[0] + 1; + _dispontime = cga->crtc[1]; + } else { + disptime = (cga->crtc[0] + 1) << 1; + _dispontime = cga->crtc[1] << 1; + } + _dispofftime = disptime - _dispontime; + // printf("%i %f %f %f %i %i\n",cgamode&1,disptime,dispontime,dispofftime,crtc[0],crtc[1]); + _dispontime *= CGACONST; + _dispofftime *= CGACONST; + // printf("Timings - on %f off %f frame %f second + // %f\n",dispontime,dispofftime,(dispontime+dispofftime)*262.0,(dispontime+dispofftime)*262.0*59.92); + cga->dispontime = (uint64_t)_dispontime; + cga->dispofftime = (uint64_t)_dispofftime; } void cga_poll(void *p) { - cga_t *cga = (cga_t *)p; - uint16_t ca = (cga->crtc[15] | (cga->crtc[14] << 8)) & 0x3fff; - int drawcursor; - int x, c; - int oldvc; - uint8_t chr, attr; - uint16_t dat; - uint32_t cols[4]; - int col; - int oldsc; + cga_t *cga = (cga_t *)p; + uint16_t ca = (cga->crtc[15] | (cga->crtc[14] << 8)) & 0x3fff; + int drawcursor; + int x, c; + int oldvc; + uint8_t chr, attr; + uint16_t dat; + uint32_t cols[4]; + int col; + int oldsc; - if (!cga->linepos) { - timer_advance_u64(&cga->timer, cga->dispofftime); - cga->cgastat |= 1; - cga->linepos = 1; - oldsc = cga->sc; - if ((cga->crtc[8] & 3) == 3) - cga->sc = ((cga->sc << 1) + cga->oddeven) & 7; - if (cga->cgadispon) { - if (cga->displine < cga->firstline) { - cga->firstline = cga->displine; - video_wait_for_buffer(); -// printf("Firstline %i\n",firstline); - } - cga->lastline = cga->displine; + if (!cga->linepos) { + timer_advance_u64(&cga->timer, cga->dispofftime); + cga->cgastat |= 1; + cga->linepos = 1; + oldsc = cga->sc; + if ((cga->crtc[8] & 3) == 3) + cga->sc = ((cga->sc << 1) + cga->oddeven) & 7; + if (cga->cgadispon) { + if (cga->displine < cga->firstline) { + cga->firstline = cga->displine; + video_wait_for_buffer(); + // printf("Firstline %i\n",firstline); + } + cga->lastline = cga->displine; - cols[0] = ((cga->cgamode & 0x12) == 0x12) ? 0 : (cga->cgacol & 15); - for (c = 0; c < 8; c++) { - ((uint32_t *)buffer32->line[cga->displine])[c] = cols[0]; - if (cga->cgamode & 1) - ((uint32_t *)buffer32->line[cga->displine])[c + (cga->crtc[1] << 3) + 8] = cols[0]; - else - ((uint32_t *)buffer32->line[cga->displine])[c + (cga->crtc[1] << 4) + 8] = cols[0]; - } - if (cga->cgamode & 1) { - for (x = 0; x < cga->crtc[1]; x++) { - if (cga->cgamode & 8) { - chr = cga->charbuffer[x << 1]; - attr = cga->charbuffer[(x << 1) + 1]; - } else - chr = attr = 0; - drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron); - if (cga->cgamode & 0x20) { - cols[1] = attr & 15; - cols[0] = (attr >> 4) & 7; - if ((cga->cgablink & 8) && (attr & 0x80) && !cga->drawcursor) - cols[1] = cols[0]; - } else { - cols[1] = attr & 15; - cols[0] = attr >> 4; - } - if (drawcursor) { - for (c = 0; c < 8; c++) - ((uint32_t *)buffer32->line[cga->displine])[(x << 3) + c + 8] = - cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 0xffffff; - } else { - for (c = 0; c < 8; c++) - ((uint32_t *)buffer32->line[cga->displine])[(x << 3) + c + 8] = cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; - } - cga->ma++; - } - } else if (!(cga->cgamode & 2)) { - for (x = 0; x < cga->crtc[1]; x++) { - if (cga->cgamode & 8) { - chr = cga->vram[((cga->ma << 1) & 0x3fff)]; - attr = cga->vram[(((cga->ma << 1) + 1) & 0x3fff)]; - } else - chr = attr = 0; - drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron); - if (cga->cgamode & 0x20) { - cols[1] = attr & 15; - cols[0] = (attr >> 4) & 7; - if ((cga->cgablink & 8) && (attr & 0x80) && !cga->drawcursor) - cols[1] = cols[0]; - } else { - cols[1] = attr & 15; - cols[0] = attr >> 4; - } - cga->ma++; - if (drawcursor) { - for (c = 0; c < 8; c++) - ((uint32_t *)buffer32->line[cga->displine])[(x << 4) + (c << 1) + 8] = - ((uint32_t *)buffer32->line[cga->displine])[(x << 4) + (c << 1) + 1 + 8] = - cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 0xffffff; - } else { - for (c = 0; c < 8; c++) - ((uint32_t *)buffer32->line[cga->displine])[(x << 4) + (c << 1) + 8] = - ((uint32_t *)buffer32->line[cga->displine])[(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr + cga->fontbase][cga->sc & 7] - & (1 << (c ^ 7))) ? 1 : 0]; - } - } - } else if (!(cga->cgamode & 16)) { - cols[0] = cga->cgacol & 15; - col = (cga->cgacol & 16) ? 8 : 0; - if (cga->cgamode & 4) { - cols[1] = col | 3; - cols[2] = col | 4; - cols[3] = col | 7; - } else if (cga->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 < cga->crtc[1]; x++) { - if (cga->cgamode & 8) - dat = (cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000)] << 8) | cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000) + 1]; - else - dat = 0; - cga->ma++; - for (c = 0; c < 8; c++) { - ((uint32_t *)buffer32->line[cga->displine])[(x << 4) + (c << 1) + 8] = - ((uint32_t *)buffer32->line[cga->displine])[(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14]; - dat <<= 2; - } - } - } else { - cols[0] = 0; - cols[1] = cga->cgacol & 15; - for (x = 0; x < cga->crtc[1]; x++) { - if (cga->cgamode & 8) - dat = (cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000)] << 8) | cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000) + 1]; - else - dat = 0; - cga->ma++; - for (c = 0; c < 16; c++) { - ((uint32_t *)buffer32->line[cga->displine])[(x << 4) + c + 8] = cols[dat >> 15]; - dat <<= 1; - } - } - } - } else { - cols[0] = ((cga->cgamode & 0x12) == 0x12) ? 0 : (cga->cgacol & 15); - if (cga->cgamode & 1) - hline(buffer32, 0, cga->displine, (cga->crtc[1] << 3) + 16, cols[0]); - else - hline(buffer32, 0, cga->displine, (cga->crtc[1] << 4) + 16, cols[0]); - } + cols[0] = ((cga->cgamode & 0x12) == 0x12) ? 0 : (cga->cgacol & 15); + for (c = 0; c < 8; c++) { + ((uint32_t *)buffer32->line[cga->displine])[c] = cols[0]; + if (cga->cgamode & 1) + ((uint32_t *)buffer32->line[cga->displine])[c + (cga->crtc[1] << 3) + 8] = cols[0]; + else + ((uint32_t *)buffer32->line[cga->displine])[c + (cga->crtc[1] << 4) + 8] = cols[0]; + } + if (cga->cgamode & 1) { + for (x = 0; x < cga->crtc[1]; x++) { + if (cga->cgamode & 8) { + chr = cga->charbuffer[x << 1]; + attr = cga->charbuffer[(x << 1) + 1]; + } else + chr = attr = 0; + drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron); + if (cga->cgamode & 0x20) { + cols[1] = attr & 15; + cols[0] = (attr >> 4) & 7; + if ((cga->cgablink & 8) && (attr & 0x80) && !cga->drawcursor) + cols[1] = cols[0]; + } else { + cols[1] = attr & 15; + cols[0] = attr >> 4; + } + if (drawcursor) { + for (c = 0; c < 8; c++) + ((uint32_t *)buffer32->line[cga->displine])[(x << 3) + c + 8] = + cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) + ? 1 + : 0] ^ + 0xffffff; + } else { + for (c = 0; c < 8; c++) + ((uint32_t *)buffer32->line[cga->displine])[(x << 3) + c + 8] = + cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) + ? 1 + : 0]; + } + cga->ma++; + } + } else if (!(cga->cgamode & 2)) { + for (x = 0; x < cga->crtc[1]; x++) { + if (cga->cgamode & 8) { + chr = cga->vram[((cga->ma << 1) & 0x3fff)]; + attr = cga->vram[(((cga->ma << 1) + 1) & 0x3fff)]; + } else + chr = attr = 0; + drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron); + if (cga->cgamode & 0x20) { + cols[1] = attr & 15; + cols[0] = (attr >> 4) & 7; + if ((cga->cgablink & 8) && (attr & 0x80) && !cga->drawcursor) + cols[1] = cols[0]; + } else { + cols[1] = attr & 15; + cols[0] = attr >> 4; + } + cga->ma++; + if (drawcursor) { + for (c = 0; c < 8; c++) + ((uint32_t *)buffer32->line[cga->displine])[(x << 4) + (c << 1) + 8] = + ((uint32_t *)buffer32 + ->line[cga->displine])[(x << 4) + (c << 1) + 1 + 8] = + cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & + (1 << (c ^ 7))) + ? 1 + : 0] ^ + 0xffffff; + } else { + for (c = 0; c < 8; c++) + ((uint32_t *)buffer32->line[cga->displine])[(x << 4) + (c << 1) + 8] = + ((uint32_t *)buffer32 + ->line[cga->displine])[(x << 4) + (c << 1) + 1 + 8] = + cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & + (1 << (c ^ 7))) + ? 1 + : 0]; + } + } + } else if (!(cga->cgamode & 16)) { + cols[0] = cga->cgacol & 15; + col = (cga->cgacol & 16) ? 8 : 0; + if (cga->cgamode & 4) { + cols[1] = col | 3; + cols[2] = col | 4; + cols[3] = col | 7; + } else if (cga->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 < cga->crtc[1]; x++) { + if (cga->cgamode & 8) + dat = (cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000)] << 8) | + cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000) + 1]; + else + dat = 0; + cga->ma++; + for (c = 0; c < 8; c++) { + ((uint32_t *)buffer32->line[cga->displine])[(x << 4) + (c << 1) + 8] = + ((uint32_t *)buffer32->line[cga->displine])[(x << 4) + (c << 1) + 1 + 8] = + cols[dat >> 14]; + dat <<= 2; + } + } + } else { + cols[0] = 0; + cols[1] = cga->cgacol & 15; + for (x = 0; x < cga->crtc[1]; x++) { + if (cga->cgamode & 8) + dat = (cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000)] << 8) | + cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000) + 1]; + else + dat = 0; + cga->ma++; + for (c = 0; c < 16; c++) { + ((uint32_t *)buffer32->line[cga->displine])[(x << 4) + c + 8] = cols[dat >> 15]; + dat <<= 1; + } + } + } + } else { + cols[0] = ((cga->cgamode & 0x12) == 0x12) ? 0 : (cga->cgacol & 15); + if (cga->cgamode & 1) + hline(buffer32, 0, cga->displine, (cga->crtc[1] << 3) + 16, cols[0]); + else + hline(buffer32, 0, cga->displine, (cga->crtc[1] << 4) + 16, cols[0]); + } - if (cga->cgamode & 1) - x = (cga->crtc[1] << 3) + 16; - else - x = (cga->crtc[1] << 4) + 16; + if (cga->cgamode & 1) + x = (cga->crtc[1] << 3) + 16; + else + x = (cga->crtc[1] << 4) + 16; - if (cga->composite) { - for (c = 0; c < x; c++) - buffer32->line[cga->displine][c] = ((uint32_t *)buffer32->line[cga->displine])[c] & 0xf; + if (cga->composite) { + for (c = 0; c < x; c++) + buffer32->line[cga->displine][c] = ((uint32_t *)buffer32->line[cga->displine])[c] & 0xf; - Composite_Process(cga->cgamode, 0, x >> 2, buffer32->line[cga->displine]); - } else { - for (c = 0; c < x; c++) - ((uint32_t *)buffer32->line[cga->displine])[c] = cgapal[((uint32_t *)buffer32->line[cga->displine])[c] & 0xf]; - } + Composite_Process(cga->cgamode, 0, x >> 2, buffer32->line[cga->displine]); + } else { + for (c = 0; c < x; c++) + ((uint32_t *)buffer32->line[cga->displine])[c] = + cgapal[((uint32_t *)buffer32->line[cga->displine])[c] & 0xf]; + } - cga->sc = oldsc; - if (cga->vc == cga->crtc[7] && !cga->sc) - cga->cgastat |= 8; - cga->displine++; - if (cga->displine >= 360) - cga->displine = 0; - } else { - timer_advance_u64(&cga->timer, cga->dispontime); - cga->linepos = 0; - if (cga->vsynctime) { - cga->vsynctime--; - if (!cga->vsynctime) - cga->cgastat &= ~8; - } - if (cga->sc == (cga->crtc[11] & 31) || ((cga->crtc[8] & 3) == 3 && cga->sc == ((cga->crtc[11] & 31) >> 1))) { - cga->con = 0; - cga->coff = 1; - } - if ((cga->crtc[8] & 3) == 3 && cga->sc == (cga->crtc[9] >> 1)) - cga->maback = cga->ma; - if (cga->vadj) { - cga->sc++; - cga->sc &= 31; - cga->ma = cga->maback; - cga->vadj--; - if (!cga->vadj) { - cga->cgadispon = 1; - cga->ma = cga->maback = (cga->crtc[13] | (cga->crtc[12] << 8)) & 0x3fff; - cga->sc = 0; - } - } else if (cga->sc == cga->crtc[9]) { - cga->maback = cga->ma; - cga->sc = 0; - oldvc = cga->vc; - cga->vc++; - cga->vc &= 127; + cga->sc = oldsc; + if (cga->vc == cga->crtc[7] && !cga->sc) + cga->cgastat |= 8; + cga->displine++; + if (cga->displine >= 360) + cga->displine = 0; + } else { + timer_advance_u64(&cga->timer, cga->dispontime); + cga->linepos = 0; + if (cga->vsynctime) { + cga->vsynctime--; + if (!cga->vsynctime) + cga->cgastat &= ~8; + } + if (cga->sc == (cga->crtc[11] & 31) || ((cga->crtc[8] & 3) == 3 && cga->sc == ((cga->crtc[11] & 31) >> 1))) { + cga->con = 0; + cga->coff = 1; + } + if ((cga->crtc[8] & 3) == 3 && cga->sc == (cga->crtc[9] >> 1)) + cga->maback = cga->ma; + if (cga->vadj) { + cga->sc++; + cga->sc &= 31; + cga->ma = cga->maback; + cga->vadj--; + if (!cga->vadj) { + cga->cgadispon = 1; + cga->ma = cga->maback = (cga->crtc[13] | (cga->crtc[12] << 8)) & 0x3fff; + cga->sc = 0; + } + } else if (cga->sc == cga->crtc[9]) { + cga->maback = cga->ma; + cga->sc = 0; + oldvc = cga->vc; + cga->vc++; + cga->vc &= 127; - if (cga->vc == cga->crtc[6]) - cga->cgadispon = 0; + if (cga->vc == cga->crtc[6]) + cga->cgadispon = 0; - if (oldvc == cga->crtc[4]) { - cga->vc = 0; - cga->vadj = cga->crtc[5]; - if (!cga->vadj) - cga->cgadispon = 1; - if (!cga->vadj) - cga->ma = cga->maback = (cga->crtc[13] | (cga->crtc[12] << 8)) & 0x3fff; - if ((cga->crtc[10] & 0x60) == 0x20) - cga->cursoron = 0; - else - cga->cursoron = cga->cgablink & 8; - } + if (oldvc == cga->crtc[4]) { + cga->vc = 0; + cga->vadj = cga->crtc[5]; + if (!cga->vadj) + cga->cgadispon = 1; + if (!cga->vadj) + cga->ma = cga->maback = (cga->crtc[13] | (cga->crtc[12] << 8)) & 0x3fff; + if ((cga->crtc[10] & 0x60) == 0x20) + cga->cursoron = 0; + else + cga->cursoron = cga->cgablink & 8; + } - if (cga->vc == cga->crtc[7]) { - cga->cgadispon = 0; - cga->displine = 0; - cga->vsynctime = 16; - if (cga->crtc[7]) { - if (cga->cgamode & 1) - x = (cga->crtc[1] << 3) + 16; - else - x = (cga->crtc[1] << 4) + 16; - cga->lastline++; - if (x != xsize || (cga->lastline - cga->firstline) != ysize) { - xsize = x; - ysize = cga->lastline - cga->firstline; - if (xsize < 64) - xsize = 656; - if (ysize < 32) - ysize = 200; - updatewindowsize(xsize, (ysize << 1) + 16); - } + if (cga->vc == cga->crtc[7]) { + cga->cgadispon = 0; + cga->displine = 0; + cga->vsynctime = 16; + if (cga->crtc[7]) { + if (cga->cgamode & 1) + x = (cga->crtc[1] << 3) + 16; + else + x = (cga->crtc[1] << 4) + 16; + cga->lastline++; + if (x != xsize || (cga->lastline - cga->firstline) != ysize) { + xsize = x; + ysize = cga->lastline - cga->firstline; + if (xsize < 64) + xsize = 656; + if (ysize < 32) + ysize = 200; + updatewindowsize(xsize, (ysize << 1) + 16); + } - video_blit_memtoscreen(0, cga->firstline - 4, 0, (cga->lastline - cga->firstline) + 8, xsize, (cga->lastline - cga->firstline) + 8); - frames++; + video_blit_memtoscreen(0, cga->firstline - 4, 0, (cga->lastline - cga->firstline) + 8, + xsize, (cga->lastline - cga->firstline) + 8); + frames++; - video_res_x = xsize - 16; - video_res_y = ysize; - if (cga->cgamode & 1) { - video_res_x /= 8; - video_res_y /= cga->crtc[9] + 1; - video_bpp = 0; - } else if (!(cga->cgamode & 2)) { - video_res_x /= 16; - video_res_y /= cga->crtc[9] + 1; - video_bpp = 0; - } else if (!(cga->cgamode & 16)) { - video_res_x /= 2; - video_bpp = 2; - } else { - video_bpp = 1; - } - } - cga->firstline = 1000; - cga->lastline = 0; - cga->cgablink++; - cga->oddeven ^= 1; - } - } else { - cga->sc++; - cga->sc &= 31; - cga->ma = cga->maback; - } - if (cga->cgadispon) - cga->cgastat &= ~1; - if ((cga->sc == (cga->crtc[10] & 31) || ((cga->crtc[8] & 3) == 3 && cga->sc == ((cga->crtc[10] & 31) >> 1)))) - cga->con = 1; - if (cga->cgadispon && (cga->cgamode & 1)) { - for (x = 0; x < (cga->crtc[1] << 1); x++) - cga->charbuffer[x] = cga->vram[(((cga->ma << 1) + x) & 0x3fff)]; - } - } + video_res_x = xsize - 16; + video_res_y = ysize; + if (cga->cgamode & 1) { + video_res_x /= 8; + video_res_y /= cga->crtc[9] + 1; + video_bpp = 0; + } else if (!(cga->cgamode & 2)) { + video_res_x /= 16; + video_res_y /= cga->crtc[9] + 1; + video_bpp = 0; + } else if (!(cga->cgamode & 16)) { + video_res_x /= 2; + video_bpp = 2; + } else { + video_bpp = 1; + } + } + cga->firstline = 1000; + cga->lastline = 0; + cga->cgablink++; + cga->oddeven ^= 1; + } + } else { + cga->sc++; + cga->sc &= 31; + cga->ma = cga->maback; + } + if (cga->cgadispon) + cga->cgastat &= ~1; + if ((cga->sc == (cga->crtc[10] & 31) || ((cga->crtc[8] & 3) == 3 && cga->sc == ((cga->crtc[10] & 31) >> 1)))) + cga->con = 1; + if (cga->cgadispon && (cga->cgamode & 1)) { + for (x = 0; x < (cga->crtc[1] << 1); x++) + cga->charbuffer[x] = cga->vram[(((cga->ma << 1) + x) & 0x3fff)]; + } + } } void cga_init(cga_t *cga) { - timer_add(&cga->timer, cga_poll, cga, 1); - cga->composite = 0; + timer_add(&cga->timer, cga_poll, cga, 1); + cga->composite = 0; } void *cga_standalone_init() { - int display_type, contrast; - cga_t *cga = malloc(sizeof(cga_t)); - memset(cga, 0, sizeof(cga_t)); + int display_type, contrast; + cga_t *cga = malloc(sizeof(cga_t)); + memset(cga, 0, sizeof(cga_t)); - display_type = device_get_config_int("display_type"); - cga->composite = (display_type == DISPLAY_COMPOSITE); - cga->revision = device_get_config_int("composite_type"); - cga->snow_enabled = device_get_config_int("snow_enabled"); - contrast = device_get_config_int("contrast"); + display_type = device_get_config_int("display_type"); + cga->composite = (display_type == DISPLAY_COMPOSITE); + cga->revision = device_get_config_int("composite_type"); + cga->snow_enabled = device_get_config_int("snow_enabled"); + contrast = device_get_config_int("contrast"); - cga->vram = malloc(0x4000); + cga->vram = malloc(0x4000); - cga_comp_init(cga->revision); + cga_comp_init(cga->revision); - timer_add(&cga->timer, cga_poll, cga, 1); - mem_mapping_add(&cga->mapping, 0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, cga); - io_sethandler(0x03d0, 0x0010, cga_in, NULL, NULL, cga_out, NULL, NULL, cga); + timer_add(&cga->timer, cga_poll, cga, 1); + mem_mapping_add(&cga->mapping, 0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, + cga); + io_sethandler(0x03d0, 0x0010, cga_in, NULL, NULL, cga_out, NULL, NULL, cga); - cgapal_rebuild(display_type, contrast); + cgapal_rebuild(display_type, contrast); - return cga; + return cga; } void cga_close(void *p) { - cga_t *cga = (cga_t *)p; + cga_t *cga = (cga_t *)p; - free(cga->vram); - free(cga); + free(cga->vram); + free(cga); } void cga_speed_changed(void *p) { - cga_t *cga = (cga_t *)p; + cga_t *cga = (cga_t *)p; - cga_recalctimings(cga); + cga_recalctimings(cga); } -device_config_t cga_config[] = - { - { - .name = "display_type", - .description = "Display type", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "RGB", - .value = DISPLAY_RGB - }, - { - .description = "RGB (no brown)", - .value = DISPLAY_RGB_NO_BROWN - }, - { - .description = "Green Monochrome", - .value = DISPLAY_GREEN - }, - { - .description = "Amber Monochrome", - .value = DISPLAY_AMBER - }, - { - .description = "White Monochrome", - .value = DISPLAY_WHITE - }, - { - .description = "Composite", - .value = DISPLAY_COMPOSITE - }, - { - .description = "" - } - }, - .default_int = DISPLAY_RGB - }, - { - .name = "composite_type", - .description = "Composite type", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "Old", - .value = COMPOSITE_OLD - }, - { - .description = "New", - .value = COMPOSITE_NEW - }, - { - .description = "" - } - }, - .default_int = COMPOSITE_OLD - }, - { - .name = "snow_enabled", - .description = "Snow emulation", - .type = CONFIG_BINARY, - .default_int = 1 - }, - { - .name = "contrast", - .description = "Alternate monochrome contrast", - .type = CONFIG_BINARY, - .default_int = 0 - }, - { - .type = -1 - } - }; +device_config_t cga_config[] = { + {.name = "display_type", + .description = "Display type", + .type = CONFIG_SELECTION, + .selection = {{.description = "RGB", .value = DISPLAY_RGB}, + {.description = "RGB (no brown)", .value = DISPLAY_RGB_NO_BROWN}, + {.description = "Green Monochrome", .value = DISPLAY_GREEN}, + {.description = "Amber Monochrome", .value = DISPLAY_AMBER}, + {.description = "White Monochrome", .value = DISPLAY_WHITE}, + {.description = "Composite", .value = DISPLAY_COMPOSITE}, + {.description = ""}}, + .default_int = DISPLAY_RGB}, + {.name = "composite_type", + .description = "Composite type", + .type = CONFIG_SELECTION, + .selection = {{.description = "Old", .value = COMPOSITE_OLD}, + {.description = "New", .value = COMPOSITE_NEW}, + {.description = ""}}, + .default_int = COMPOSITE_OLD}, + {.name = "snow_enabled", .description = "Snow emulation", .type = CONFIG_BINARY, .default_int = 1}, + {.name = "contrast", .description = "Alternate monochrome contrast", .type = CONFIG_BINARY, .default_int = 0}, + {.type = -1}}; -device_t cga_device = - { - "CGA", - 0, - cga_standalone_init, - cga_close, - NULL, - cga_speed_changed, - NULL, - NULL, - cga_config - }; +device_t cga_device = {"CGA", 0, cga_standalone_init, cga_close, NULL, cga_speed_changed, NULL, NULL, cga_config}; diff --git a/src/video/vid_cl5429.c b/src/video/vid_cl5429.c index 6338baef..0537d008 100644 --- a/src/video/vid_cl5429.c +++ b/src/video/vid_cl5429.c @@ -1,5 +1,5 @@ /*Cirrus Logic CL-GD5429 emulation*/ -//SR7.0 = "true packed-pixel memory addressing" +// SR7.0 = "true packed-pixel memory addressing" #include #include "ibm.h" #include "cpu.h" @@ -16,86 +16,79 @@ #include "vid_vga.h" #include "vid_unk_ramdac.h" -enum { - CL_TYPE_AVGA2 = 0, - CL_TYPE_GD5426, - CL_TYPE_GD5428, - CL_TYPE_GD5429, - CL_TYPE_GD5430, - CL_TYPE_GD5434 -}; +enum { CL_TYPE_AVGA2 = 0, CL_TYPE_GD5426, CL_TYPE_GD5428, CL_TYPE_GD5429, CL_TYPE_GD5430, CL_TYPE_GD5434 }; -#define BLIT_DEPTH_8 0 +#define BLIT_DEPTH_8 0 #define BLIT_DEPTH_16 1 #define BLIT_DEPTH_32 3 -#define CL_GD5428_SYSTEM_BUS_MCA 5 +#define CL_GD5428_SYSTEM_BUS_MCA 5 #define CL_GD5428_SYSTEM_BUS_VESA 6 -#define CL_GD5428_SYSTEM_BUS_ISA 7 +#define CL_GD5428_SYSTEM_BUS_ISA 7 #define CL_GD5429_SYSTEM_BUS_VESA 5 -#define CL_GD5429_SYSTEM_BUS_ISA 7 +#define CL_GD5429_SYSTEM_BUS_ISA 7 -#define CL_GD543X_SYSTEM_BUS_PCI 4 +#define CL_GD543X_SYSTEM_BUS_PCI 4 #define CL_GD543X_SYSTEM_BUS_VESA 6 -#define CL_GD543X_SYSTEM_BUS_ISA 7 +#define CL_GD543X_SYSTEM_BUS_ISA 7 typedef struct gd5429_t { - mem_mapping_t mmio_mapping; - mem_mapping_t linear_mapping; + mem_mapping_t mmio_mapping; + mem_mapping_t linear_mapping; - svga_t svga; + svga_t svga; - rom_t bios_rom; + rom_t bios_rom; - uint32_t bank[2]; - uint32_t mask; + uint32_t bank[2]; + uint32_t mask; - uint32_t vram_mask; + uint32_t vram_mask; - int type; + int type; - struct { - uint32_t bg_col, fg_col; - uint16_t trans_col, trans_mask; - uint16_t width, height; - uint16_t dst_pitch, src_pitch; - uint32_t dst_addr, src_addr; - uint8_t mask, mode, rop; + struct { + uint32_t bg_col, fg_col; + uint16_t trans_col, trans_mask; + uint16_t width, height; + uint16_t dst_pitch, src_pitch; + uint32_t dst_addr, src_addr; + uint8_t mask, mode, rop; - uint32_t dst_addr_backup, src_addr_backup; - uint16_t width_backup, height_internal; - int x_count, y_count; - int depth; + uint32_t dst_addr_backup, src_addr_backup; + uint16_t width_backup, height_internal; + int x_count, y_count; + int depth; - int mem_word_sel; - uint16_t mem_word_save; - } blt; + int mem_word_sel; + uint16_t mem_word_save; + } blt; - uint8_t hidden_dac_reg; - int dac_3c6_count; + uint8_t hidden_dac_reg; + int dac_3c6_count; - uint8_t pci_regs[256]; - uint8_t int_line; - int card; + uint8_t pci_regs[256]; + uint8_t int_line; + int card; - uint8_t pos_regs[8]; - svga_t *mb_vga; + uint8_t pos_regs[8]; + svga_t *mb_vga; - uint32_t lfb_base; + uint32_t lfb_base; - int mmio_vram_overlap; + int mmio_vram_overlap; - uint8_t sr10_read, sr11_read; + uint8_t sr10_read, sr11_read; - uint8_t latch_ext[4]; + uint8_t latch_ext[4]; - int vidsys_ena; + int vidsys_ena; } gd5429_t; -#define GRB_X8_ADDRESSING (1 << 1) -#define GRB_WRITEMODE_EXT (1 << 2) -#define GRB_8B_LATCHES (1 << 3) +#define GRB_X8_ADDRESSING (1 << 1) +#define GRB_WRITEMODE_EXT (1 << 2) +#define GRB_8B_LATCHES (1 << 3) #define GRB_ENHANCED_16BIT (1 << 4) static void gd5429_mmio_write(uint32_t addr, uint8_t val, void *p); @@ -116,2105 +109,2093 @@ uint8_t gd5429_read_linear(uint32_t addr, void *p); static void ibm_gd5428_mapping_update(gd5429_t *gd5429); void gd5429_out(uint16_t addr, uint8_t val, void *p) { - gd5429_t *gd5429 = (gd5429_t *)p; - svga_t *svga = &gd5429->svga; - uint8_t old; + gd5429_t *gd5429 = (gd5429_t *)p; + svga_t *svga = &gd5429->svga; + uint8_t old; - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; -// pclog("gd5429 out %04X %02X\n", addr, val); + // pclog("gd5429 out %04X %02X\n", addr, val); - switch (addr) { - case 0x3c3: - if (MCA) { - gd5429->vidsys_ena = val & 1; - ibm_gd5428_mapping_update(gd5429); - } - break; + switch (addr) { + case 0x3c3: + if (MCA) { + gd5429->vidsys_ena = val & 1; + ibm_gd5428_mapping_update(gd5429); + } + break; - case 0x3c4:svga->seqaddr = val; - break; - case 0x3c5: - if (svga->seqaddr > 5) { - svga->seqregs[svga->seqaddr & 0x1f] = val; - switch (svga->seqaddr & 0x1f) { - case 0x10: - case 0x30: - case 0x50: - case 0x70: - case 0x90: - case 0xb0: - case 0xd0: - case 0xf0:svga->hwcursor.x = (val << 3) | ((svga->seqaddr >> 5) & 7); - gd5429->sr10_read = svga->seqaddr & 0xe0; -// pclog("svga->hwcursor.x = %i\n", svga->hwcursor.x); - break; - case 0x11: - case 0x31: - case 0x51: - case 0x71: - case 0x91: - case 0xb1: - case 0xd1: - case 0xf1:svga->hwcursor.y = (val << 3) | ((svga->seqaddr >> 5) & 7); - gd5429->sr11_read = svga->seqaddr & 0xe0; -// pclog("svga->hwcursor.y = %i\n", svga->hwcursor.y); - break; - case 0x12:svga->hwcursor.ena = val & 1; - svga->hwcursor.ysize = (val & 4) ? 64 : 32; - svga->hwcursor.yoff = 0; - if (svga->hwcursor.ysize == 64) - svga->hwcursor.addr = (0x3fc000 + ((svga->seqregs[0x13] & 0x3c) * 256)) & svga->vram_mask; - else - svga->hwcursor.addr = (0x3fc000 + ((svga->seqregs[0x13] & 0x3f) * 256)) & svga->vram_mask; -// pclog("svga->hwcursor.ena = %i\n", svga->hwcursor.ena); - break; - case 0x13: - if (svga->hwcursor.ysize == 64) - svga->hwcursor.addr = (0x3fc000 + ((val & 0x3c) * 256)) & svga->vram_mask; - else - svga->hwcursor.addr = (0x3fc000 + ((val & 0x3f) * 256)) & svga->vram_mask; -// pclog("svga->hwcursor.addr = %x\n", svga->hwcursor.addr); - break; + case 0x3c4: + svga->seqaddr = val; + break; + case 0x3c5: + if (svga->seqaddr > 5) { + svga->seqregs[svga->seqaddr & 0x1f] = val; + switch (svga->seqaddr & 0x1f) { + case 0x10: + case 0x30: + case 0x50: + case 0x70: + case 0x90: + case 0xb0: + case 0xd0: + case 0xf0: + svga->hwcursor.x = (val << 3) | ((svga->seqaddr >> 5) & 7); + gd5429->sr10_read = svga->seqaddr & 0xe0; + // pclog("svga->hwcursor.x = %i\n", svga->hwcursor.x); + break; + case 0x11: + case 0x31: + case 0x51: + case 0x71: + case 0x91: + case 0xb1: + case 0xd1: + case 0xf1: + svga->hwcursor.y = (val << 3) | ((svga->seqaddr >> 5) & 7); + gd5429->sr11_read = svga->seqaddr & 0xe0; + // pclog("svga->hwcursor.y = %i\n", svga->hwcursor.y); + break; + case 0x12: + svga->hwcursor.ena = val & 1; + svga->hwcursor.ysize = (val & 4) ? 64 : 32; + svga->hwcursor.yoff = 0; + if (svga->hwcursor.ysize == 64) + svga->hwcursor.addr = (0x3fc000 + ((svga->seqregs[0x13] & 0x3c) * 256)) & svga->vram_mask; + else + svga->hwcursor.addr = (0x3fc000 + ((svga->seqregs[0x13] & 0x3f) * 256)) & svga->vram_mask; + // pclog("svga->hwcursor.ena = %i\n", svga->hwcursor.ena); + break; + case 0x13: + if (svga->hwcursor.ysize == 64) + svga->hwcursor.addr = (0x3fc000 + ((val & 0x3c) * 256)) & svga->vram_mask; + else + svga->hwcursor.addr = (0x3fc000 + ((val & 0x3f) * 256)) & svga->vram_mask; + // pclog("svga->hwcursor.addr = %x\n", svga->hwcursor.addr); + break; - case 0x07:svga->set_reset_disabled = svga->seqregs[7] & 1; - svga->packed_chain4 = svga->seqregs[7] & 1; - svga_recalctimings(svga); - case 0x17: - if (gd5429->type >= CL_TYPE_GD5429) - gd5429_recalc_mapping(gd5429); - break; - } - return; - } - break; + case 0x07: + svga->set_reset_disabled = svga->seqregs[7] & 1; + svga->packed_chain4 = svga->seqregs[7] & 1; + svga_recalctimings(svga); + case 0x17: + if (gd5429->type >= CL_TYPE_GD5429) + gd5429_recalc_mapping(gd5429); + break; + } + return; + } + break; - case 0x3c6: -// pclog("CL write 3c6 %02x %i\n", val, gd5429->dac_3c6_count); - if (gd5429->dac_3c6_count == 4) { - gd5429->dac_3c6_count = 0; - gd5429->hidden_dac_reg = val; - svga_recalctimings(svga); - return; - } - gd5429->dac_3c6_count = 0; - break; - case 0x3c7: - case 0x3c8: - case 0x3c9:gd5429->dac_3c6_count = 0; - break; + case 0x3c6: + // pclog("CL write 3c6 %02x %i\n", val, gd5429->dac_3c6_count); + if (gd5429->dac_3c6_count == 4) { + gd5429->dac_3c6_count = 0; + gd5429->hidden_dac_reg = val; + svga_recalctimings(svga); + return; + } + gd5429->dac_3c6_count = 0; + break; + case 0x3c7: + case 0x3c8: + case 0x3c9: + gd5429->dac_3c6_count = 0; + break; - case 0x3cf: -// pclog("Write GDC %02x %02x\n", svga->gdcaddr, val); - if (svga->gdcaddr == 0) - gd5429_mmio_write(0xb8000, val, gd5429); - if (svga->gdcaddr == 1) - gd5429_mmio_write(0xb8004, val, gd5429); - if (svga->gdcaddr == 5) { - svga->gdcreg[5] = val; - if (svga->gdcreg[0xb] & 0x04) - svga->writemode = svga->gdcreg[5] & 7; - else - svga->writemode = svga->gdcreg[5] & 3; - svga->readmode = val & 8; - svga->chain2_read = val & 0x10; -// pclog("writemode = %i\n", svga->writemode); - return; - } - if (svga->gdcaddr == 6) { - if ((svga->gdcreg[6] & 0xc) != (val & 0xc)) { - svga->gdcreg[6] = val; - gd5429_recalc_mapping(gd5429); - } + case 0x3cf: + // pclog("Write GDC %02x %02x\n", svga->gdcaddr, val); + if (svga->gdcaddr == 0) + gd5429_mmio_write(0xb8000, val, gd5429); + if (svga->gdcaddr == 1) + gd5429_mmio_write(0xb8004, val, gd5429); + if (svga->gdcaddr == 5) { + svga->gdcreg[5] = val; + if (svga->gdcreg[0xb] & 0x04) + svga->writemode = svga->gdcreg[5] & 7; + else + svga->writemode = svga->gdcreg[5] & 3; + svga->readmode = val & 8; + svga->chain2_read = val & 0x10; + // pclog("writemode = %i\n", svga->writemode); + return; + } + if (svga->gdcaddr == 6) { + if ((svga->gdcreg[6] & 0xc) != (val & 0xc)) { + svga->gdcreg[6] = val; + gd5429_recalc_mapping(gd5429); + } - /*Hack - the Windows 3.x drivers for the GD5426/8 require VRAM wraparound - for pattern & cursor writes to work correctly, but the BIOSes require - no wrapping to detect memory size - albeit with odd/even mode enabled. - This may be a quirk of address mapping. So change wrapping mode based on - odd/even mode for now*/ - if (gd5429->type == CL_TYPE_GD5426 || gd5429->type == CL_TYPE_GD5428) { - if (val & 2) /*Odd/Even*/ - svga->decode_mask = 0x1fffff; - else - svga->decode_mask = svga->vram_mask; - } + /*Hack - the Windows 3.x drivers for the GD5426/8 require VRAM wraparound + for pattern & cursor writes to work correctly, but the BIOSes require + no wrapping to detect memory size - albeit with odd/even mode enabled. + This may be a quirk of address mapping. So change wrapping mode based on + odd/even mode for now*/ + if (gd5429->type == CL_TYPE_GD5426 || gd5429->type == CL_TYPE_GD5428) { + if (val & 2) /*Odd/Even*/ + svga->decode_mask = 0x1fffff; + else + svga->decode_mask = svga->vram_mask; + } - svga->gdcreg[6] = val; - return; - } - if (svga->gdcaddr > 8) { - svga->gdcreg[svga->gdcaddr & 0x3f] = val; - if (gd5429->type < CL_TYPE_GD5426 && (svga->gdcaddr > 0xb)) - return; - switch (svga->gdcaddr) { - case 0x09: - case 0x0a: - case 0x0b:gd5429_recalc_banking(gd5429); - if (svga->gdcreg[0xb] & 0x04) - svga->writemode = svga->gdcreg[5] & 7; - else - svga->writemode = svga->gdcreg[5] & 3; - break; + svga->gdcreg[6] = val; + return; + } + if (svga->gdcaddr > 8) { + svga->gdcreg[svga->gdcaddr & 0x3f] = val; + if (gd5429->type < CL_TYPE_GD5426 && (svga->gdcaddr > 0xb)) + return; + switch (svga->gdcaddr) { + case 0x09: + case 0x0a: + case 0x0b: + gd5429_recalc_banking(gd5429); + if (svga->gdcreg[0xb] & 0x04) + svga->writemode = svga->gdcreg[5] & 7; + else + svga->writemode = svga->gdcreg[5] & 3; + break; - case 0x10:gd5429_mmio_write(0xb8001, val, gd5429); - break; - case 0x11:gd5429_mmio_write(0xb8005, val, gd5429); - break; - case 0x12:gd5429_mmio_write(0xb8002, val, gd5429); - break; - case 0x13:gd5429_mmio_write(0xb8006, val, gd5429); - break; - case 0x14:gd5429_mmio_write(0xb8003, val, gd5429); - break; - case 0x15:gd5429_mmio_write(0xb8007, val, gd5429); - break; + case 0x10: + gd5429_mmio_write(0xb8001, val, gd5429); + break; + case 0x11: + gd5429_mmio_write(0xb8005, val, gd5429); + break; + case 0x12: + gd5429_mmio_write(0xb8002, val, gd5429); + break; + case 0x13: + gd5429_mmio_write(0xb8006, val, gd5429); + break; + case 0x14: + gd5429_mmio_write(0xb8003, val, gd5429); + break; + case 0x15: + gd5429_mmio_write(0xb8007, val, gd5429); + break; - case 0x20:gd5429_mmio_write(0xb8008, val, gd5429); - break; - case 0x21:gd5429_mmio_write(0xb8009, val, gd5429); - break; - case 0x22:gd5429_mmio_write(0xb800a, val, gd5429); - break; - case 0x23:gd5429_mmio_write(0xb800b, val, gd5429); - break; - case 0x24:gd5429_mmio_write(0xb800c, val, gd5429); - break; - case 0x25:gd5429_mmio_write(0xb800d, val, gd5429); - break; - case 0x26:gd5429_mmio_write(0xb800e, val, gd5429); - break; - case 0x27:gd5429_mmio_write(0xb800f, val, gd5429); - break; + case 0x20: + gd5429_mmio_write(0xb8008, val, gd5429); + break; + case 0x21: + gd5429_mmio_write(0xb8009, val, gd5429); + break; + case 0x22: + gd5429_mmio_write(0xb800a, val, gd5429); + break; + case 0x23: + gd5429_mmio_write(0xb800b, val, gd5429); + break; + case 0x24: + gd5429_mmio_write(0xb800c, val, gd5429); + break; + case 0x25: + gd5429_mmio_write(0xb800d, val, gd5429); + break; + case 0x26: + gd5429_mmio_write(0xb800e, val, gd5429); + break; + case 0x27: + gd5429_mmio_write(0xb800f, val, gd5429); + break; - case 0x28:gd5429_mmio_write(0xb8010, val, gd5429); - break; - case 0x29:gd5429_mmio_write(0xb8011, val, gd5429); - break; - case 0x2a:gd5429_mmio_write(0xb8012, val, gd5429); - break; + case 0x28: + gd5429_mmio_write(0xb8010, val, gd5429); + break; + case 0x29: + gd5429_mmio_write(0xb8011, val, gd5429); + break; + case 0x2a: + gd5429_mmio_write(0xb8012, val, gd5429); + break; - case 0x2c:gd5429_mmio_write(0xb8014, val, gd5429); - break; - case 0x2d:gd5429_mmio_write(0xb8015, val, gd5429); - break; - case 0x2e:gd5429_mmio_write(0xb8016, val, gd5429); - break; + case 0x2c: + gd5429_mmio_write(0xb8014, val, gd5429); + break; + case 0x2d: + gd5429_mmio_write(0xb8015, val, gd5429); + break; + case 0x2e: + gd5429_mmio_write(0xb8016, val, gd5429); + break; - case 0x2f:gd5429_mmio_write(0xb8017, val, gd5429); - break; - case 0x30:gd5429_mmio_write(0xb8018, val, gd5429); - break; + case 0x2f: + gd5429_mmio_write(0xb8017, val, gd5429); + break; + case 0x30: + gd5429_mmio_write(0xb8018, val, gd5429); + break; - case 0x32:gd5429_mmio_write(0xb801a, val, gd5429); - break; + case 0x32: + gd5429_mmio_write(0xb801a, val, gd5429); + break; - case 0x31:gd5429_mmio_write(0xb8040, val, gd5429); - break; + case 0x31: + gd5429_mmio_write(0xb8040, val, gd5429); + break; - case 0x34: - if (gd5429->type <= CL_TYPE_GD5428) - gd5429->blt.trans_col = (gd5429->blt.trans_col & 0xff00) | val; - break; - case 0x35: - if (gd5429->type <= CL_TYPE_GD5428) - gd5429->blt.trans_col = (gd5429->blt.trans_col & 0x00ff) | (val << 8); - break; - case 0x36: - if (gd5429->type <= CL_TYPE_GD5428) - gd5429->blt.trans_mask = (gd5429->blt.trans_mask & 0xff00) | val; - break; - case 0x37: - if (gd5429->type <= CL_TYPE_GD5428) - gd5429->blt.trans_mask = (gd5429->blt.trans_mask & 0x00ff) | (val << 8); - break; - } - return; - } - break; + case 0x34: + if (gd5429->type <= CL_TYPE_GD5428) + gd5429->blt.trans_col = (gd5429->blt.trans_col & 0xff00) | val; + break; + case 0x35: + if (gd5429->type <= CL_TYPE_GD5428) + gd5429->blt.trans_col = (gd5429->blt.trans_col & 0x00ff) | (val << 8); + break; + case 0x36: + if (gd5429->type <= CL_TYPE_GD5428) + gd5429->blt.trans_mask = (gd5429->blt.trans_mask & 0xff00) | val; + break; + case 0x37: + if (gd5429->type <= CL_TYPE_GD5428) + gd5429->blt.trans_mask = (gd5429->blt.trans_mask & 0x00ff) | (val << 8); + break; + } + return; + } + break; - case 0x3D4:svga->crtcreg = val & 0x3f; - return; - case 0x3D5: - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) - return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); - old = svga->crtc[svga->crtcreg]; - svga->crtc[svga->crtcreg] = val; + case 0x3D4: + svga->crtcreg = val & 0x3f; + return; + case 0x3D5: + if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) + return; + if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) + val = (svga->crtc[7] & ~0x10) | (val & 0x10); + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; - if (old != val) { - if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - } - break; - } - svga_out(addr, val, svga); + if (old != val) { + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } + } + break; + } + svga_out(addr, val, svga); } uint8_t gd5429_in(uint16_t addr, void *p) { - gd5429_t *gd5429 = (gd5429_t *)p; - svga_t *svga = &gd5429->svga; + gd5429_t *gd5429 = (gd5429_t *)p; + svga_t *svga = &gd5429->svga; - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; -// if (addr != 0x3da) pclog("IN gd5429 %04X\n", addr); + // if (addr != 0x3da) pclog("IN gd5429 %04X\n", addr); - switch (addr) { - case 0x3c3: - if (MCA) - return gd5429->vidsys_ena; - break; + switch (addr) { + case 0x3c3: + if (MCA) + return gd5429->vidsys_ena; + break; - case 0x3c4: - if ((svga->seqaddr & 0x1f) == 0x10) - return (svga->seqaddr & 0x1f) | gd5429->sr10_read; - if ((svga->seqaddr & 0x1f) == 0x11) - return (svga->seqaddr & 0x1f) | gd5429->sr11_read; - return svga->seqaddr & 0x1f; + case 0x3c4: + if ((svga->seqaddr & 0x1f) == 0x10) + return (svga->seqaddr & 0x1f) | gd5429->sr10_read; + if ((svga->seqaddr & 0x1f) == 0x11) + return (svga->seqaddr & 0x1f) | gd5429->sr11_read; + return svga->seqaddr & 0x1f; - case 0x3c5: - if (svga->seqaddr > 5) { - uint8_t temp; + case 0x3c5: + if (svga->seqaddr > 5) { + uint8_t temp; - switch (svga->seqaddr) { - case 6:return ((svga->seqregs[6] & 0x17) == 0x12) ? 0x12 : 0x0f; + switch (svga->seqaddr) { + case 6: + return ((svga->seqregs[6] & 0x17) == 0x12) ? 0x12 : 0x0f; - case 0x17: - if (gd5429->type < CL_TYPE_GD5426) - break; - temp = svga->seqregs[0x17]; - temp &= ~(7 << 3); - if (gd5429->type == CL_TYPE_GD5426 || gd5429->type == CL_TYPE_GD5428) { - if (MCA) - temp |= (CL_GD5428_SYSTEM_BUS_MCA << 3); - else if (has_vlb) - temp |= (CL_GD5428_SYSTEM_BUS_VESA << 3); - else - temp |= (CL_GD5428_SYSTEM_BUS_ISA << 3); - } else if (gd5429->type == CL_TYPE_GD5429) { - if (has_vlb) - temp |= (CL_GD5429_SYSTEM_BUS_VESA << 3); - else - temp |= (CL_GD5429_SYSTEM_BUS_ISA << 3); - } else { - if (PCI) - temp |= (CL_GD543X_SYSTEM_BUS_PCI << 3); - else if (has_vlb) - temp |= (CL_GD543X_SYSTEM_BUS_VESA << 3); - else - temp |= (CL_GD543X_SYSTEM_BUS_ISA << 3); - } - return temp; - } - return svga->seqregs[svga->seqaddr & 0x3f]; - } - break; + case 0x17: + if (gd5429->type < CL_TYPE_GD5426) + break; + temp = svga->seqregs[0x17]; + temp &= ~(7 << 3); + if (gd5429->type == CL_TYPE_GD5426 || gd5429->type == CL_TYPE_GD5428) { + if (MCA) + temp |= (CL_GD5428_SYSTEM_BUS_MCA << 3); + else if (has_vlb) + temp |= (CL_GD5428_SYSTEM_BUS_VESA << 3); + else + temp |= (CL_GD5428_SYSTEM_BUS_ISA << 3); + } else if (gd5429->type == CL_TYPE_GD5429) { + if (has_vlb) + temp |= (CL_GD5429_SYSTEM_BUS_VESA << 3); + else + temp |= (CL_GD5429_SYSTEM_BUS_ISA << 3); + } else { + if (PCI) + temp |= (CL_GD543X_SYSTEM_BUS_PCI << 3); + else if (has_vlb) + temp |= (CL_GD543X_SYSTEM_BUS_VESA << 3); + else + temp |= (CL_GD543X_SYSTEM_BUS_ISA << 3); + } + return temp; + } + return svga->seqregs[svga->seqaddr & 0x3f]; + } + break; - case 0x3c6: -// pclog("CL read 3c6 %i\n", gd5429->dac_3c6_count); - if (gd5429->dac_3c6_count == 4) { - gd5429->dac_3c6_count = 0; - return gd5429->hidden_dac_reg; - } - gd5429->dac_3c6_count++; - break; - case 0x3c7: - case 0x3c8: - case 0x3c9:gd5429->dac_3c6_count = 0; - break; + case 0x3c6: + // pclog("CL read 3c6 %i\n", gd5429->dac_3c6_count); + if (gd5429->dac_3c6_count == 4) { + gd5429->dac_3c6_count = 0; + return gd5429->hidden_dac_reg; + } + gd5429->dac_3c6_count++; + break; + case 0x3c7: + case 0x3c8: + case 0x3c9: + gd5429->dac_3c6_count = 0; + break; - case 0x3cf: - if (svga->gdcaddr > 8) { - return svga->gdcreg[svga->gdcaddr & 0x3f]; - } - break; + case 0x3cf: + if (svga->gdcaddr > 8) { + return svga->gdcreg[svga->gdcaddr & 0x3f]; + } + break; - case 0x3D4:return svga->crtcreg; - case 0x3D5: - switch (svga->crtcreg) { - case 0x27: /*ID*/ - switch (gd5429->type) { - case CL_TYPE_AVGA2:return 0x18; /*AVGA2*/ - case CL_TYPE_GD5426:return 0x90; /*GD5426*/ - case CL_TYPE_GD5428:return 0x98; /*GD5428*/ - case CL_TYPE_GD5429:return 0x9c; /*GD5429*/ - case CL_TYPE_GD5430:return 0xa0; /*GD5430*/ - case CL_TYPE_GD5434:return 0xa8; /*GD5434*/ - } - break; - case 0x28: /*Class ID*/ - if (gd5429->type == CL_TYPE_GD5430) - return 0xff; /*Standard CL-GD5430*/ - break; - } - return svga->crtc[svga->crtcreg]; - } - return svga_in(addr, svga); + case 0x3D4: + return svga->crtcreg; + case 0x3D5: + switch (svga->crtcreg) { + case 0x27: /*ID*/ + switch (gd5429->type) { + case CL_TYPE_AVGA2: + return 0x18; /*AVGA2*/ + case CL_TYPE_GD5426: + return 0x90; /*GD5426*/ + case CL_TYPE_GD5428: + return 0x98; /*GD5428*/ + case CL_TYPE_GD5429: + return 0x9c; /*GD5429*/ + case CL_TYPE_GD5430: + return 0xa0; /*GD5430*/ + case CL_TYPE_GD5434: + return 0xa8; /*GD5434*/ + } + break; + case 0x28: /*Class ID*/ + if (gd5429->type == CL_TYPE_GD5430) + return 0xff; /*Standard CL-GD5430*/ + break; + } + return svga->crtc[svga->crtcreg]; + } + return svga_in(addr, svga); } void gd5429_recalc_banking(gd5429_t *gd5429) { - svga_t *svga = &gd5429->svga; + svga_t *svga = &gd5429->svga; - if (svga->gdcreg[0xb] & 0x20) - gd5429->bank[0] = (svga->gdcreg[0x09] & 0xff) << 14; - else - gd5429->bank[0] = svga->gdcreg[0x09] << 12; + if (svga->gdcreg[0xb] & 0x20) + gd5429->bank[0] = (svga->gdcreg[0x09] & 0xff) << 14; + else + gd5429->bank[0] = svga->gdcreg[0x09] << 12; - if (svga->gdcreg[0xb] & 0x01) { - if (svga->gdcreg[0xb] & 0x20) - gd5429->bank[1] = (svga->gdcreg[0x0a] & 0xff) << 14; - else - gd5429->bank[1] = svga->gdcreg[0x0a] << 12; - } else - gd5429->bank[1] = gd5429->bank[0] + 0x8000; + if (svga->gdcreg[0xb] & 0x01) { + if (svga->gdcreg[0xb] & 0x20) + gd5429->bank[1] = (svga->gdcreg[0x0a] & 0xff) << 14; + else + gd5429->bank[1] = svga->gdcreg[0x0a] << 12; + } else + gd5429->bank[1] = gd5429->bank[0] + 0x8000; } void gd5429_recalc_mapping(gd5429_t *gd5429) { - svga_t *svga = &gd5429->svga; + svga_t *svga = &gd5429->svga; - if ((PCI && gd5429->type >= CL_TYPE_GD5430 && !(gd5429->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) || - (MCA && (!(gd5429->pos_regs[2] & 0x01) || !gd5429->vidsys_ena))) { - mem_mapping_disable(&svga->mapping); - mem_mapping_disable(&gd5429->linear_mapping); - mem_mapping_disable(&gd5429->mmio_mapping); - return; - } + if ((PCI && gd5429->type >= CL_TYPE_GD5430 && !(gd5429->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) || + (MCA && (!(gd5429->pos_regs[2] & 0x01) || !gd5429->vidsys_ena))) { + mem_mapping_disable(&svga->mapping); + mem_mapping_disable(&gd5429->linear_mapping); + mem_mapping_disable(&gd5429->mmio_mapping); + return; + } - gd5429->mmio_vram_overlap = 0; + gd5429->mmio_vram_overlap = 0; -// pclog("Write mapping %02X %i\n", svga->gdcreg[6], svga->seqregs[0x17] & 0x04); - if (!(svga->seqregs[7] & 0xf0)) { - mem_mapping_disable(&gd5429->linear_mapping); - switch (svga->gdcreg[6] & 0x0C) { - case 0x0: /*128k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - svga->banked_mask = 0xffff; - break; - case 0x4: /*64k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - svga->banked_mask = 0xffff; - break; - case 0x8: /*32k at B0000*/ - mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); - svga->banked_mask = 0x7fff; - break; - case 0xC: /*32k at B8000*/ - mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); - svga->banked_mask = 0x7fff; - gd5429->mmio_vram_overlap = 1; - break; - } - if (gd5429->type >= CL_TYPE_GD5429 && svga->seqregs[0x17] & 0x04) - mem_mapping_set_addr(&gd5429->mmio_mapping, 0xb8000, 0x00100); - else - mem_mapping_disable(&gd5429->mmio_mapping); - } else { - uint32_t base, size; + // pclog("Write mapping %02X %i\n", svga->gdcreg[6], svga->seqregs[0x17] & 0x04); + if (!(svga->seqregs[7] & 0xf0)) { + mem_mapping_disable(&gd5429->linear_mapping); + switch (svga->gdcreg[6] & 0x0C) { + case 0x0: /*128k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + svga->banked_mask = 0xffff; + break; + case 0x4: /*64k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + svga->banked_mask = 0xffff; + break; + case 0x8: /*32k at B0000*/ + mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); + svga->banked_mask = 0x7fff; + break; + case 0xC: /*32k at B8000*/ + mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); + svga->banked_mask = 0x7fff; + gd5429->mmio_vram_overlap = 1; + break; + } + if (gd5429->type >= CL_TYPE_GD5429 && svga->seqregs[0x17] & 0x04) + mem_mapping_set_addr(&gd5429->mmio_mapping, 0xb8000, 0x00100); + else + mem_mapping_disable(&gd5429->mmio_mapping); + } else { + uint32_t base, size; - if (gd5429->type <= CL_TYPE_GD5429 || (!PCI && !has_vlb)) { - base = (svga->seqregs[7] & 0xf0) << 16; - if (svga->gdcreg[0xb] & 0x20) - size = 1 * 1024 * 1024; - else - size = 2 * 1024 * 1024; - } else if (PCI) { - base = gd5429->lfb_base; - size = 4 * 1024 * 1024; - } else /*VLB*/ - { - base = 128 * 1024 * 1024; - size = 4 * 1024 * 1024; - } - mem_mapping_disable(&svga->mapping); - mem_mapping_set_addr(&gd5429->linear_mapping, base, size); - if (gd5429->type >= CL_TYPE_GD5429 && svga->seqregs[0x17] & 0x04) - mem_mapping_set_addr(&gd5429->mmio_mapping, 0xb8000, 0x00100); - else - mem_mapping_disable(&gd5429->mmio_mapping); - } + if (gd5429->type <= CL_TYPE_GD5429 || (!PCI && !has_vlb)) { + base = (svga->seqregs[7] & 0xf0) << 16; + if (svga->gdcreg[0xb] & 0x20) + size = 1 * 1024 * 1024; + else + size = 2 * 1024 * 1024; + } else if (PCI) { + base = gd5429->lfb_base; + size = 4 * 1024 * 1024; + } else /*VLB*/ + { + base = 128 * 1024 * 1024; + size = 4 * 1024 * 1024; + } + mem_mapping_disable(&svga->mapping); + mem_mapping_set_addr(&gd5429->linear_mapping, base, size); + if (gd5429->type >= CL_TYPE_GD5429 && svga->seqregs[0x17] & 0x04) + mem_mapping_set_addr(&gd5429->mmio_mapping, 0xb8000, 0x00100); + else + mem_mapping_disable(&gd5429->mmio_mapping); + } } void gd5429_recalctimings(svga_t *svga) { - gd5429_t *gd5429 = (gd5429_t *)svga->p; - int clock = (svga->miscout >> 2) & 3; - int n, d, p; - double vclk; + gd5429_t *gd5429 = (gd5429_t *)svga->p; + int clock = (svga->miscout >> 2) & 3; + int n, d, p; + double vclk; - if (svga->crtc[0x1b] & 0x10) - svga->rowoffset |= 0x100; + if (svga->crtc[0x1b] & 0x10) + svga->rowoffset |= 0x100; - if (!svga->rowoffset) - svga->rowoffset = 0x100; + if (!svga->rowoffset) + svga->rowoffset = 0x100; - svga->interlace = svga->crtc[0x1a] & 1; + svga->interlace = svga->crtc[0x1a] & 1; - if (svga->seqregs[7] & 0x01) - svga->render = svga_render_8bpp_highres; + if (svga->seqregs[7] & 0x01) + svga->render = svga_render_8bpp_highres; - svga->ma_latch |= ((svga->crtc[0x1b] & 0x01) << 16) | ((svga->crtc[0x1b] & 0xc) << 15); -// pclog("MA now %05X %02X\n", svga->ma_latch, svga->crtc[0x1b]); + svga->ma_latch |= ((svga->crtc[0x1b] & 0x01) << 16) | ((svga->crtc[0x1b] & 0xc) << 15); + // pclog("MA now %05X %02X\n", svga->ma_latch, svga->crtc[0x1b]); - svga->bpp = 8; - if (gd5429->hidden_dac_reg & 0x80) { - if (gd5429->hidden_dac_reg & 0x40) { - switch (gd5429->hidden_dac_reg & 0xf) { - case 0x0:svga->render = svga_render_15bpp_highres; - svga->bpp = 15; - break; - case 0x1:svga->render = svga_render_16bpp_highres; - svga->bpp = 16; - break; - case 0x5: - if (gd5429->type >= CL_TYPE_GD5434 && (svga->seqregs[7] & 8)) { - svga->render = svga_render_32bpp_highres; - svga->bpp = 32; - svga->rowoffset *= 2; - } else { - svga->render = svga_render_24bpp_highres; - svga->bpp = 24; - } - break; - } - } else { - svga->render = svga_render_15bpp_highres; - svga->bpp = 15; - } - } + svga->bpp = 8; + if (gd5429->hidden_dac_reg & 0x80) { + if (gd5429->hidden_dac_reg & 0x40) { + switch (gd5429->hidden_dac_reg & 0xf) { + case 0x0: + svga->render = svga_render_15bpp_highres; + svga->bpp = 15; + break; + case 0x1: + svga->render = svga_render_16bpp_highres; + svga->bpp = 16; + break; + case 0x5: + if (gd5429->type >= CL_TYPE_GD5434 && (svga->seqregs[7] & 8)) { + svga->render = svga_render_32bpp_highres; + svga->bpp = 32; + svga->rowoffset *= 2; + } else { + svga->render = svga_render_24bpp_highres; + svga->bpp = 24; + } + break; + } + } else { + svga->render = svga_render_15bpp_highres; + svga->bpp = 15; + } + } - n = svga->seqregs[0xb + clock] & 0x7f; - d = (svga->seqregs[0x1b + clock] >> 1) & 0x1f; - p = svga->seqregs[0x1b + clock] & 1; + n = svga->seqregs[0xb + clock] & 0x7f; + d = (svga->seqregs[0x1b + clock] >> 1) & 0x1f; + p = svga->seqregs[0x1b + clock] & 1; - /*Prevent divide by zero during clock setup*/ - if (d && n) - vclk = (14318184.0 * ((float)n / (float)d)) / (float)(1 + p); - else - vclk = 14318184.0; - switch (svga->seqregs[7] & ((gd5429->type >= CL_TYPE_GD5434) ? 0xe : 0x6)) { - case 2:vclk /= 2.0; - break; - case 4:vclk /= 3.0; - break; - } - svga->clock = (cpuclock * (float)(1ull << 32)) / vclk; + /*Prevent divide by zero during clock setup*/ + if (d && n) + vclk = (14318184.0 * ((float)n / (float)d)) / (float)(1 + p); + else + vclk = 14318184.0; + switch (svga->seqregs[7] & ((gd5429->type >= CL_TYPE_GD5434) ? 0xe : 0x6)) { + case 2: + vclk /= 2.0; + break; + case 4: + vclk /= 3.0; + break; + } + svga->clock = (cpuclock * (float)(1ull << 32)) / vclk; - svga->vram_display_mask = (svga->crtc[0x1b] & 2) ? gd5429->vram_mask : 0x3ffff; + svga->vram_display_mask = (svga->crtc[0x1b] & 2) ? gd5429->vram_mask : 0x3ffff; } void gd5429_hwcursor_draw(svga_t *svga, int displine) { - int x; - uint8_t dat[2]; - int xx; - int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; - int line_offset = (svga->seqregs[0x12] & 0x04) ? 16 : 4; + int x; + uint8_t dat[2]; + int xx; + int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; + int line_offset = (svga->seqregs[0x12] & 0x04) ? 16 : 4; - if (svga->interlace && svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += line_offset; + if (svga->interlace && svga->hwcursor_oddeven) + svga->hwcursor_latch.addr += line_offset; - if (svga->seqregs[0x12] & 0x04) { - for (x = 0; x < 64; x += 8) { - dat[0] = svga->vram[svga->hwcursor_latch.addr]; - dat[1] = svga->vram[svga->hwcursor_latch.addr + 8]; - for (xx = 0; xx < 8; xx++) { - if (offset >= svga->hwcursor_latch.x) { - if (dat[1] & 0x80) - ((uint32_t *)buffer32->line[displine])[offset + 32] = 0; - if (dat[0] & 0x80) - ((uint32_t *)buffer32->line[displine])[offset + 32] ^= 0xffffff; - } + if (svga->seqregs[0x12] & 0x04) { + for (x = 0; x < 64; x += 8) { + dat[0] = svga->vram[svga->hwcursor_latch.addr]; + dat[1] = svga->vram[svga->hwcursor_latch.addr + 8]; + for (xx = 0; xx < 8; xx++) { + if (offset >= svga->hwcursor_latch.x) { + if (dat[1] & 0x80) + ((uint32_t *)buffer32->line[displine])[offset + 32] = 0; + if (dat[0] & 0x80) + ((uint32_t *)buffer32->line[displine])[offset + 32] ^= 0xffffff; + } - offset++; - dat[0] <<= 1; - dat[1] <<= 1; - } - svga->hwcursor_latch.addr++; - } - svga->hwcursor_latch.addr += 8; - } else { - for (x = 0; x < 32; x += 8) { - dat[0] = svga->vram[svga->hwcursor_latch.addr]; - dat[1] = svga->vram[svga->hwcursor_latch.addr + 0x80]; - for (xx = 0; xx < 8; xx++) { - if (offset >= svga->hwcursor_latch.x) { - if (dat[1] & 0x80) - ((uint32_t *)buffer32->line[displine])[offset + 32] = 0; - if (dat[0] & 0x80) - ((uint32_t *)buffer32->line[displine])[offset + 32] ^= 0xffffff; - } + offset++; + dat[0] <<= 1; + dat[1] <<= 1; + } + svga->hwcursor_latch.addr++; + } + svga->hwcursor_latch.addr += 8; + } else { + for (x = 0; x < 32; x += 8) { + dat[0] = svga->vram[svga->hwcursor_latch.addr]; + dat[1] = svga->vram[svga->hwcursor_latch.addr + 0x80]; + for (xx = 0; xx < 8; xx++) { + if (offset >= svga->hwcursor_latch.x) { + if (dat[1] & 0x80) + ((uint32_t *)buffer32->line[displine])[offset + 32] = 0; + if (dat[0] & 0x80) + ((uint32_t *)buffer32->line[displine])[offset + 32] ^= 0xffffff; + } - offset++; - dat[0] <<= 1; - dat[1] <<= 1; - } - svga->hwcursor_latch.addr++; - } - } + offset++; + dat[0] <<= 1; + dat[1] <<= 1; + } + svga->hwcursor_latch.addr++; + } + } - if (svga->interlace && !svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += line_offset; + if (svga->interlace && !svga->hwcursor_oddeven) + svga->hwcursor_latch.addr += line_offset; } void gd5429_write_linear(uint32_t addr, uint8_t val, void *p); static void gd5429_write(uint32_t addr, uint8_t val, void *p) { - gd5429_t *gd5429 = (gd5429_t *)p; - svga_t *svga = &gd5429->svga; + gd5429_t *gd5429 = (gd5429_t *)p; + svga_t *svga = &gd5429->svga; - addr &= svga->banked_mask; - addr = (addr & 0x7fff) + gd5429->bank[(addr >> 15) & 1]; + addr &= svga->banked_mask; + addr = (addr & 0x7fff) + gd5429->bank[(addr >> 15) & 1]; - gd5429_write_linear(addr, val, p); + gd5429_write_linear(addr, val, p); } static void gd5429_writew(uint32_t addr, uint16_t val, void *p) { - gd5429_t *gd5429 = (gd5429_t *)p; - svga_t *svga = &gd5429->svga; + gd5429_t *gd5429 = (gd5429_t *)p; + svga_t *svga = &gd5429->svga; - addr &= svga->banked_mask; - addr = (addr & 0x7fff) + gd5429->bank[(addr >> 15) & 1]; + addr &= svga->banked_mask; + addr = (addr & 0x7fff) + gd5429->bank[(addr >> 15) & 1]; - if ((svga->writemode < 4) && !(svga->gdcreg[0xb] & (GRB_X8_ADDRESSING | GRB_8B_LATCHES))) - svga_writew_linear(addr, val, svga); - else { - gd5429_write_linear(addr, val, p); - gd5429_write_linear(addr + 1, val >> 8, p); - } + if ((svga->writemode < 4) && !(svga->gdcreg[0xb] & (GRB_X8_ADDRESSING | GRB_8B_LATCHES))) + svga_writew_linear(addr, val, svga); + else { + gd5429_write_linear(addr, val, p); + gd5429_write_linear(addr + 1, val >> 8, p); + } } static void gd5429_writel(uint32_t addr, uint32_t val, void *p) { - gd5429_t *gd5429 = (gd5429_t *)p; - svga_t *svga = &gd5429->svga; + gd5429_t *gd5429 = (gd5429_t *)p; + svga_t *svga = &gd5429->svga; - addr &= svga->banked_mask; - addr = (addr & 0x7fff) + gd5429->bank[(addr >> 15) & 1]; + addr &= svga->banked_mask; + addr = (addr & 0x7fff) + gd5429->bank[(addr >> 15) & 1]; - if ((svga->writemode < 4) && !(svga->gdcreg[0xb] & (GRB_X8_ADDRESSING | GRB_8B_LATCHES))) - svga_writel_linear(addr, val, svga); - else { - gd5429_write_linear(addr, val, p); - gd5429_write_linear(addr + 1, val >> 8, p); - gd5429_write_linear(addr + 2, val >> 16, p); - gd5429_write_linear(addr + 3, val >> 24, p); - } + if ((svga->writemode < 4) && !(svga->gdcreg[0xb] & (GRB_X8_ADDRESSING | GRB_8B_LATCHES))) + svga_writel_linear(addr, val, svga); + else { + gd5429_write_linear(addr, val, p); + gd5429_write_linear(addr + 1, val >> 8, p); + gd5429_write_linear(addr + 2, val >> 16, p); + gd5429_write_linear(addr + 3, val >> 24, p); + } } static uint8_t gd5429_read(uint32_t addr, void *p) { - gd5429_t *gd5429 = (gd5429_t *)p; - svga_t *svga = &gd5429->svga; + gd5429_t *gd5429 = (gd5429_t *)p; + svga_t *svga = &gd5429->svga; - addr &= svga->banked_mask; - addr = (addr & 0x7fff) + gd5429->bank[(addr >> 15) & 1]; - return gd5429_read_linear(addr, gd5429); + addr &= svga->banked_mask; + addr = (addr & 0x7fff) + gd5429->bank[(addr >> 15) & 1]; + return gd5429_read_linear(addr, gd5429); } static uint16_t gd5429_readw(uint32_t addr, void *p) { - gd5429_t *gd5429 = (gd5429_t *)p; - svga_t *svga = &gd5429->svga; + gd5429_t *gd5429 = (gd5429_t *)p; + svga_t *svga = &gd5429->svga; - addr &= svga->banked_mask; - addr = (addr & 0x7fff) + gd5429->bank[(addr >> 15) & 1]; + addr &= svga->banked_mask; + addr = (addr & 0x7fff) + gd5429->bank[(addr >> 15) & 1]; - if (!(svga->gdcreg[0xb] & (GRB_X8_ADDRESSING | GRB_8B_LATCHES))) - return svga_readw_linear(addr, &gd5429->svga); - return gd5429_read_linear(addr, gd5429) | (gd5429_read_linear(addr + 1, gd5429) << 8); + if (!(svga->gdcreg[0xb] & (GRB_X8_ADDRESSING | GRB_8B_LATCHES))) + return svga_readw_linear(addr, &gd5429->svga); + return gd5429_read_linear(addr, gd5429) | (gd5429_read_linear(addr + 1, gd5429) << 8); } static uint32_t gd5429_readl(uint32_t addr, void *p) { - gd5429_t *gd5429 = (gd5429_t *)p; - svga_t *svga = &gd5429->svga; + gd5429_t *gd5429 = (gd5429_t *)p; + svga_t *svga = &gd5429->svga; - addr &= svga->banked_mask; - addr = (addr & 0x7fff) + gd5429->bank[(addr >> 15) & 1]; + addr &= svga->banked_mask; + addr = (addr & 0x7fff) + gd5429->bank[(addr >> 15) & 1]; - if (!(svga->gdcreg[0xb] & (GRB_X8_ADDRESSING | GRB_8B_LATCHES))) - return svga_readl_linear(addr, &gd5429->svga); - return gd5429_read_linear(addr, gd5429) | (gd5429_read_linear(addr + 1, gd5429) << 8) | - (gd5429_read_linear(addr + 2, gd5429) << 16) | (gd5429_read_linear(addr + 3, gd5429) << 24); + if (!(svga->gdcreg[0xb] & (GRB_X8_ADDRESSING | GRB_8B_LATCHES))) + return svga_readl_linear(addr, &gd5429->svga); + return gd5429_read_linear(addr, gd5429) | (gd5429_read_linear(addr + 1, gd5429) << 8) | + (gd5429_read_linear(addr + 2, gd5429) << 16) | (gd5429_read_linear(addr + 3, gd5429) << 24); } void gd5429_write_linear(uint32_t addr, uint8_t val, void *p) { - gd5429_t *gd5429 = (gd5429_t *)p; - svga_t *svga = &gd5429->svga; - uint8_t vala, valb, valc, vald, wm = svga->writemask; - int writemask2 = svga->seqregs[2]; + gd5429_t *gd5429 = (gd5429_t *)p; + svga_t *svga = &gd5429->svga; + uint8_t vala, valb, valc, vald, wm = svga->writemask; + int writemask2 = svga->seqregs[2]; - cycles -= video_timing_write_b; - cycles_lost += video_timing_write_b; + cycles -= video_timing_write_b; + cycles_lost += video_timing_write_b; - egawrites++; + egawrites++; -// if (svga_output) pclog("Write LFB %08X %02X ", addr, val); - if (!(svga->gdcreg[6] & 1)) - svga->fullchange = 2; - if (svga->gdcreg[0xb] & GRB_ENHANCED_16BIT) - addr <<= 4; - else if (svga->gdcreg[0xb] & GRB_X8_ADDRESSING) - addr <<= 3; - else if (((svga->chain4 && svga->packed_chain4) || svga->fb_only) && (svga->writemode < 4)) { - writemask2 = 1 << (addr & 3); - addr &= ~3; - } else if (svga->chain4) { - writemask2 = 1 << (addr & 3); - addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff); - } else if (svga->chain2_write) { - writemask2 &= ~0xa; - if (addr & 1) - writemask2 <<= 1; - addr &= ~1; - addr <<= 2; - } else { - addr <<= 2; - } - addr &= svga->decode_mask; - if (addr >= svga->vram_max) - return; - addr &= svga->vram_mask; -// if (svga_output) pclog("%08X\n", addr); - svga->changedvram[addr >> 12] = changeframecount; + // if (svga_output) pclog("Write LFB %08X %02X ", addr, val); + if (!(svga->gdcreg[6] & 1)) + svga->fullchange = 2; + if (svga->gdcreg[0xb] & GRB_ENHANCED_16BIT) + addr <<= 4; + else if (svga->gdcreg[0xb] & GRB_X8_ADDRESSING) + addr <<= 3; + else if (((svga->chain4 && svga->packed_chain4) || svga->fb_only) && (svga->writemode < 4)) { + writemask2 = 1 << (addr & 3); + addr &= ~3; + } else if (svga->chain4) { + writemask2 = 1 << (addr & 3); + addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff); + } else if (svga->chain2_write) { + writemask2 &= ~0xa; + if (addr & 1) + writemask2 <<= 1; + addr &= ~1; + addr <<= 2; + } else { + addr <<= 2; + } + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return; + addr &= svga->vram_mask; + // if (svga_output) pclog("%08X\n", addr); + svga->changedvram[addr >> 12] = changeframecount; - switch (svga->writemode) { - case 4: - if (svga->gdcreg[0xb] & GRB_ENHANCED_16BIT) { -// pclog("Writemode 4 : %X ", addr); - svga->changedvram[addr >> 12] = changeframecount; -// pclog("%X %X %02x\n", addr, val, svga->gdcreg[0xb]); - if (val & svga->seqregs[2] & 0x80) { - svga->vram[addr + 0] = svga->gdcreg[1]; - svga->vram[addr + 1] = svga->gdcreg[0x11]; - } - if (val & svga->seqregs[2] & 0x40) { - svga->vram[addr + 2] = svga->gdcreg[1]; - svga->vram[addr + 3] = svga->gdcreg[0x11]; - } - if (val & svga->seqregs[2] & 0x20) { - svga->vram[addr + 4] = svga->gdcreg[1]; - svga->vram[addr + 5] = svga->gdcreg[0x11]; - } - if (val & svga->seqregs[2] & 0x10) { - svga->vram[addr + 6] = svga->gdcreg[1]; - svga->vram[addr + 7] = svga->gdcreg[0x11]; - } - if (val & svga->seqregs[2] & 0x08) { - svga->vram[addr + 8] = svga->gdcreg[1]; - svga->vram[addr + 9] = svga->gdcreg[0x11]; - } - if (val & svga->seqregs[2] & 0x04) { - svga->vram[addr + 10] = svga->gdcreg[1]; - svga->vram[addr + 11] = svga->gdcreg[0x11]; - } - if (val & svga->seqregs[2] & 0x02) { - svga->vram[addr + 12] = svga->gdcreg[1]; - svga->vram[addr + 13] = svga->gdcreg[0x11]; - } - if (val & svga->seqregs[2] & 0x01) { - svga->vram[addr + 14] = svga->gdcreg[1]; - svga->vram[addr + 15] = svga->gdcreg[0x11]; - } - } else { -// pclog("Writemode 4 : %X ", addr); - svga->changedvram[addr >> 12] = changeframecount; -// pclog("%X %X %02x\n", addr, val, svga->gdcreg[0xb]); - if (val & svga->seqregs[2] & 0x80) - svga->vram[addr + 0] = svga->gdcreg[1]; - if (val & svga->seqregs[2] & 0x40) - svga->vram[addr + 1] = svga->gdcreg[1]; - if (val & svga->seqregs[2] & 0x20) - svga->vram[addr + 2] = svga->gdcreg[1]; - if (val & svga->seqregs[2] & 0x10) - svga->vram[addr + 3] = svga->gdcreg[1]; - if (val & svga->seqregs[2] & 0x08) - svga->vram[addr + 4] = svga->gdcreg[1]; - if (val & svga->seqregs[2] & 0x04) - svga->vram[addr + 5] = svga->gdcreg[1]; - if (val & svga->seqregs[2] & 0x02) - svga->vram[addr + 6] = svga->gdcreg[1]; - if (val & svga->seqregs[2] & 0x01) - svga->vram[addr + 7] = svga->gdcreg[1]; - } - break; + switch (svga->writemode) { + case 4: + if (svga->gdcreg[0xb] & GRB_ENHANCED_16BIT) { + // pclog("Writemode 4 : %X ", addr); + svga->changedvram[addr >> 12] = changeframecount; + // pclog("%X %X %02x\n", addr, val, svga->gdcreg[0xb]); + if (val & svga->seqregs[2] & 0x80) { + svga->vram[addr + 0] = svga->gdcreg[1]; + svga->vram[addr + 1] = svga->gdcreg[0x11]; + } + if (val & svga->seqregs[2] & 0x40) { + svga->vram[addr + 2] = svga->gdcreg[1]; + svga->vram[addr + 3] = svga->gdcreg[0x11]; + } + if (val & svga->seqregs[2] & 0x20) { + svga->vram[addr + 4] = svga->gdcreg[1]; + svga->vram[addr + 5] = svga->gdcreg[0x11]; + } + if (val & svga->seqregs[2] & 0x10) { + svga->vram[addr + 6] = svga->gdcreg[1]; + svga->vram[addr + 7] = svga->gdcreg[0x11]; + } + if (val & svga->seqregs[2] & 0x08) { + svga->vram[addr + 8] = svga->gdcreg[1]; + svga->vram[addr + 9] = svga->gdcreg[0x11]; + } + if (val & svga->seqregs[2] & 0x04) { + svga->vram[addr + 10] = svga->gdcreg[1]; + svga->vram[addr + 11] = svga->gdcreg[0x11]; + } + if (val & svga->seqregs[2] & 0x02) { + svga->vram[addr + 12] = svga->gdcreg[1]; + svga->vram[addr + 13] = svga->gdcreg[0x11]; + } + if (val & svga->seqregs[2] & 0x01) { + svga->vram[addr + 14] = svga->gdcreg[1]; + svga->vram[addr + 15] = svga->gdcreg[0x11]; + } + } else { + // pclog("Writemode 4 : %X ", addr); + svga->changedvram[addr >> 12] = changeframecount; + // pclog("%X %X %02x\n", addr, val, svga->gdcreg[0xb]); + if (val & svga->seqregs[2] & 0x80) + svga->vram[addr + 0] = svga->gdcreg[1]; + if (val & svga->seqregs[2] & 0x40) + svga->vram[addr + 1] = svga->gdcreg[1]; + if (val & svga->seqregs[2] & 0x20) + svga->vram[addr + 2] = svga->gdcreg[1]; + if (val & svga->seqregs[2] & 0x10) + svga->vram[addr + 3] = svga->gdcreg[1]; + if (val & svga->seqregs[2] & 0x08) + svga->vram[addr + 4] = svga->gdcreg[1]; + if (val & svga->seqregs[2] & 0x04) + svga->vram[addr + 5] = svga->gdcreg[1]; + if (val & svga->seqregs[2] & 0x02) + svga->vram[addr + 6] = svga->gdcreg[1]; + if (val & svga->seqregs[2] & 0x01) + svga->vram[addr + 7] = svga->gdcreg[1]; + } + break; - case 5: - if (svga->gdcreg[0xb] & GRB_ENHANCED_16BIT) { -// pclog("Writemode 5 : %X ", addr); - svga->changedvram[addr >> 12] = changeframecount; -// pclog("%X %X %02x\n", addr, val, svga->gdcreg[0xb]); - if (svga->seqregs[2] & 0x80) { - svga->vram[addr + 0] = (val & 0x80) ? svga->gdcreg[1] : svga->gdcreg[0]; - svga->vram[addr + 1] = (val & 0x80) ? svga->gdcreg[0x11] : svga->gdcreg[0x10]; - } - if (svga->seqregs[2] & 0x40) { - svga->vram[addr + 2] = (val & 0x40) ? svga->gdcreg[1] : svga->gdcreg[0]; - svga->vram[addr + 3] = (val & 0x40) ? svga->gdcreg[0x11] : svga->gdcreg[0x10]; - } - if (svga->seqregs[2] & 0x20) { - svga->vram[addr + 4] = (val & 0x20) ? svga->gdcreg[1] : svga->gdcreg[0]; - svga->vram[addr + 5] = (val & 0x20) ? svga->gdcreg[0x11] : svga->gdcreg[0x10]; - } - if (svga->seqregs[2] & 0x10) { - svga->vram[addr + 6] = (val & 0x10) ? svga->gdcreg[1] : svga->gdcreg[0]; - svga->vram[addr + 7] = (val & 0x10) ? svga->gdcreg[0x11] : svga->gdcreg[0x10]; - } - if (svga->seqregs[2] & 0x08) { - svga->vram[addr + 8] = (val & 0x08) ? svga->gdcreg[1] : svga->gdcreg[0]; - svga->vram[addr + 9] = (val & 0x08) ? svga->gdcreg[0x11] : svga->gdcreg[0x10]; - } - if (svga->seqregs[2] & 0x04) { - svga->vram[addr + 10] = (val & 0x04) ? svga->gdcreg[1] : svga->gdcreg[0]; - svga->vram[addr + 11] = (val & 0x04) ? svga->gdcreg[0x11] : svga->gdcreg[0x10]; - } - if (svga->seqregs[2] & 0x02) { - svga->vram[addr + 12] = (val & 0x02) ? svga->gdcreg[1] : svga->gdcreg[0]; - svga->vram[addr + 13] = (val & 0x02) ? svga->gdcreg[0x11] : svga->gdcreg[0x10]; - } - if (svga->seqregs[2] & 0x01) { - svga->vram[addr + 14] = (val & 0x01) ? svga->gdcreg[1] : svga->gdcreg[0]; - svga->vram[addr + 15] = (val & 0x01) ? svga->gdcreg[0x11] : svga->gdcreg[0x10]; - } - } else { -// pclog("Writemode 5 : %X ", addr); - svga->changedvram[addr >> 12] = changeframecount; -// pclog("%X %X %02x\n", addr, val, svga->gdcreg[0xb]); - if (svga->seqregs[2] & 0x80) - svga->vram[addr + 0] = (val & 0x80) ? svga->gdcreg[1] : svga->gdcreg[0]; - if (svga->seqregs[2] & 0x40) - svga->vram[addr + 1] = (val & 0x40) ? svga->gdcreg[1] : svga->gdcreg[0]; - if (svga->seqregs[2] & 0x20) - svga->vram[addr + 2] = (val & 0x20) ? svga->gdcreg[1] : svga->gdcreg[0]; - if (svga->seqregs[2] & 0x10) - svga->vram[addr + 3] = (val & 0x10) ? svga->gdcreg[1] : svga->gdcreg[0]; - if (svga->seqregs[2] & 0x08) - svga->vram[addr + 4] = (val & 0x08) ? svga->gdcreg[1] : svga->gdcreg[0]; - if (svga->seqregs[2] & 0x04) - svga->vram[addr + 5] = (val & 0x04) ? svga->gdcreg[1] : svga->gdcreg[0]; - if (svga->seqregs[2] & 0x02) - svga->vram[addr + 6] = (val & 0x02) ? svga->gdcreg[1] : svga->gdcreg[0]; - if (svga->seqregs[2] & 0x01) - svga->vram[addr + 7] = (val & 0x01) ? svga->gdcreg[1] : svga->gdcreg[0]; - } - break; + case 5: + if (svga->gdcreg[0xb] & GRB_ENHANCED_16BIT) { + // pclog("Writemode 5 : %X ", addr); + svga->changedvram[addr >> 12] = changeframecount; + // pclog("%X %X %02x\n", addr, val, svga->gdcreg[0xb]); + if (svga->seqregs[2] & 0x80) { + svga->vram[addr + 0] = (val & 0x80) ? svga->gdcreg[1] : svga->gdcreg[0]; + svga->vram[addr + 1] = (val & 0x80) ? svga->gdcreg[0x11] : svga->gdcreg[0x10]; + } + if (svga->seqregs[2] & 0x40) { + svga->vram[addr + 2] = (val & 0x40) ? svga->gdcreg[1] : svga->gdcreg[0]; + svga->vram[addr + 3] = (val & 0x40) ? svga->gdcreg[0x11] : svga->gdcreg[0x10]; + } + if (svga->seqregs[2] & 0x20) { + svga->vram[addr + 4] = (val & 0x20) ? svga->gdcreg[1] : svga->gdcreg[0]; + svga->vram[addr + 5] = (val & 0x20) ? svga->gdcreg[0x11] : svga->gdcreg[0x10]; + } + if (svga->seqregs[2] & 0x10) { + svga->vram[addr + 6] = (val & 0x10) ? svga->gdcreg[1] : svga->gdcreg[0]; + svga->vram[addr + 7] = (val & 0x10) ? svga->gdcreg[0x11] : svga->gdcreg[0x10]; + } + if (svga->seqregs[2] & 0x08) { + svga->vram[addr + 8] = (val & 0x08) ? svga->gdcreg[1] : svga->gdcreg[0]; + svga->vram[addr + 9] = (val & 0x08) ? svga->gdcreg[0x11] : svga->gdcreg[0x10]; + } + if (svga->seqregs[2] & 0x04) { + svga->vram[addr + 10] = (val & 0x04) ? svga->gdcreg[1] : svga->gdcreg[0]; + svga->vram[addr + 11] = (val & 0x04) ? svga->gdcreg[0x11] : svga->gdcreg[0x10]; + } + if (svga->seqregs[2] & 0x02) { + svga->vram[addr + 12] = (val & 0x02) ? svga->gdcreg[1] : svga->gdcreg[0]; + svga->vram[addr + 13] = (val & 0x02) ? svga->gdcreg[0x11] : svga->gdcreg[0x10]; + } + if (svga->seqregs[2] & 0x01) { + svga->vram[addr + 14] = (val & 0x01) ? svga->gdcreg[1] : svga->gdcreg[0]; + svga->vram[addr + 15] = (val & 0x01) ? svga->gdcreg[0x11] : svga->gdcreg[0x10]; + } + } else { + // pclog("Writemode 5 : %X ", addr); + svga->changedvram[addr >> 12] = changeframecount; + // pclog("%X %X %02x\n", addr, val, svga->gdcreg[0xb]); + if (svga->seqregs[2] & 0x80) + svga->vram[addr + 0] = (val & 0x80) ? svga->gdcreg[1] : svga->gdcreg[0]; + if (svga->seqregs[2] & 0x40) + svga->vram[addr + 1] = (val & 0x40) ? svga->gdcreg[1] : svga->gdcreg[0]; + if (svga->seqregs[2] & 0x20) + svga->vram[addr + 2] = (val & 0x20) ? svga->gdcreg[1] : svga->gdcreg[0]; + if (svga->seqregs[2] & 0x10) + svga->vram[addr + 3] = (val & 0x10) ? svga->gdcreg[1] : svga->gdcreg[0]; + if (svga->seqregs[2] & 0x08) + svga->vram[addr + 4] = (val & 0x08) ? svga->gdcreg[1] : svga->gdcreg[0]; + if (svga->seqregs[2] & 0x04) + svga->vram[addr + 5] = (val & 0x04) ? svga->gdcreg[1] : svga->gdcreg[0]; + if (svga->seqregs[2] & 0x02) + svga->vram[addr + 6] = (val & 0x02) ? svga->gdcreg[1] : svga->gdcreg[0]; + if (svga->seqregs[2] & 0x01) + svga->vram[addr + 7] = (val & 0x01) ? svga->gdcreg[1] : svga->gdcreg[0]; + } + break; - case 1: - if (svga->gdcreg[0xb] & GRB_WRITEMODE_EXT) { - if (writemask2 & 0x80) - svga->vram[addr] = svga->la; - if (writemask2 & 0x40) - svga->vram[addr | 0x1] = svga->lb; - if (writemask2 & 0x20) - svga->vram[addr | 0x2] = svga->lc; - if (writemask2 & 0x10) - svga->vram[addr | 0x3] = svga->ld; - if (svga->gdcreg[0xb] & GRB_8B_LATCHES) { - if (writemask2 & 0x08) - svga->vram[addr | 0x4] = gd5429->latch_ext[0]; - if (writemask2 & 0x04) - svga->vram[addr | 0x5] = gd5429->latch_ext[1]; - if (writemask2 & 0x02) - svga->vram[addr | 0x6] = gd5429->latch_ext[2]; - if (writemask2 & 0x01) - svga->vram[addr | 0x7] = gd5429->latch_ext[3]; - } - } else { - if (writemask2 & 1) - svga->vram[addr] = svga->la; - if (writemask2 & 2) - svga->vram[addr | 0x1] = svga->lb; - if (writemask2 & 4) - svga->vram[addr | 0x2] = svga->lc; - if (writemask2 & 8) - svga->vram[addr | 0x3] = svga->ld; - } - break; - case 0: - if (svga->gdcreg[3] & 7) - val = svga_rotate[svga->gdcreg[3] & 7][val]; - if (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && (!svga->gdcreg[1] || svga->set_reset_disabled)) { - if (writemask2 & 1) - svga->vram[addr] = val; - if (writemask2 & 2) - svga->vram[addr | 0x1] = val; - if (writemask2 & 4) - svga->vram[addr | 0x2] = val; - if (writemask2 & 8) - svga->vram[addr | 0x3] = val; - } else { - if (svga->gdcreg[1] & 1) - vala = (svga->gdcreg[0] & 1) ? 0xff : 0; - else - vala = val; - if (svga->gdcreg[1] & 2) - valb = (svga->gdcreg[0] & 2) ? 0xff : 0; - else - valb = val; - if (svga->gdcreg[1] & 4) - valc = (svga->gdcreg[0] & 4) ? 0xff : 0; - else - valc = val; - if (svga->gdcreg[1] & 8) - vald = (svga->gdcreg[0] & 8) ? 0xff : 0; - else - vald = val; + case 1: + if (svga->gdcreg[0xb] & GRB_WRITEMODE_EXT) { + if (writemask2 & 0x80) + svga->vram[addr] = svga->la; + if (writemask2 & 0x40) + svga->vram[addr | 0x1] = svga->lb; + if (writemask2 & 0x20) + svga->vram[addr | 0x2] = svga->lc; + if (writemask2 & 0x10) + svga->vram[addr | 0x3] = svga->ld; + if (svga->gdcreg[0xb] & GRB_8B_LATCHES) { + if (writemask2 & 0x08) + svga->vram[addr | 0x4] = gd5429->latch_ext[0]; + if (writemask2 & 0x04) + svga->vram[addr | 0x5] = gd5429->latch_ext[1]; + if (writemask2 & 0x02) + svga->vram[addr | 0x6] = gd5429->latch_ext[2]; + if (writemask2 & 0x01) + svga->vram[addr | 0x7] = gd5429->latch_ext[3]; + } + } else { + if (writemask2 & 1) + svga->vram[addr] = svga->la; + if (writemask2 & 2) + svga->vram[addr | 0x1] = svga->lb; + if (writemask2 & 4) + svga->vram[addr | 0x2] = svga->lc; + if (writemask2 & 8) + svga->vram[addr | 0x3] = svga->ld; + } + break; + case 0: + if (svga->gdcreg[3] & 7) + val = svga_rotate[svga->gdcreg[3] & 7][val]; + if (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && (!svga->gdcreg[1] || svga->set_reset_disabled)) { + if (writemask2 & 1) + svga->vram[addr] = val; + if (writemask2 & 2) + svga->vram[addr | 0x1] = val; + if (writemask2 & 4) + svga->vram[addr | 0x2] = val; + if (writemask2 & 8) + svga->vram[addr | 0x3] = val; + } else { + if (svga->gdcreg[1] & 1) + vala = (svga->gdcreg[0] & 1) ? 0xff : 0; + else + vala = val; + if (svga->gdcreg[1] & 2) + valb = (svga->gdcreg[0] & 2) ? 0xff : 0; + else + valb = val; + if (svga->gdcreg[1] & 4) + valc = (svga->gdcreg[0] & 4) ? 0xff : 0; + else + valc = val; + if (svga->gdcreg[1] & 8) + vald = (svga->gdcreg[0] & 8) ? 0xff : 0; + else + vald = val; - switch (svga->gdcreg[3] & 0x18) { - case 0: /*Set*/ - if (writemask2 & 1) - svga->vram[addr] = (vala & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]); - if (writemask2 & 2) - svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]); - if (writemask2 & 4) - svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]); - if (writemask2 & 8) - svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]); - break; - case 8: /*AND*/ - if (writemask2 & 1) - svga->vram[addr] = (vala | ~svga->gdcreg[8]) & svga->la; - if (writemask2 & 2) - svga->vram[addr | 0x1] = (valb | ~svga->gdcreg[8]) & svga->lb; - if (writemask2 & 4) - svga->vram[addr | 0x2] = (valc | ~svga->gdcreg[8]) & svga->lc; - if (writemask2 & 8) - svga->vram[addr | 0x3] = (vald | ~svga->gdcreg[8]) & svga->ld; - break; - case 0x10: /*OR*/ - if (writemask2 & 1) - svga->vram[addr] = (vala & svga->gdcreg[8]) | svga->la; - if (writemask2 & 2) - svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | svga->lb; - if (writemask2 & 4) - svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | svga->lc; - if (writemask2 & 8) - svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | svga->ld; - break; - case 0x18: /*XOR*/ - if (writemask2 & 1) - svga->vram[addr] = (vala & svga->gdcreg[8]) ^ svga->la; - if (writemask2 & 2) - svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) ^ svga->lb; - if (writemask2 & 4) - svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) ^ svga->lc; - if (writemask2 & 8) - svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) ^ svga->ld; - break; - } -// pclog("- %02X %02X %02X %02X %08X\n",vram[addr],vram[addr|0x1],vram[addr|0x2],vram[addr|0x3],addr); - } - break; - case 2: - if (!(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) { - if (writemask2 & 1) - svga->vram[addr] = (((val & 1) ? 0xff : 0) & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]); - if (writemask2 & 2) - svga->vram[addr | 0x1] = (((val & 2) ? 0xff : 0) & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]); - if (writemask2 & 4) - svga->vram[addr | 0x2] = (((val & 4) ? 0xff : 0) & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]); - if (writemask2 & 8) - svga->vram[addr | 0x3] = (((val & 8) ? 0xff : 0) & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]); - } else { - vala = ((val & 1) ? 0xff : 0); - valb = ((val & 2) ? 0xff : 0); - valc = ((val & 4) ? 0xff : 0); - vald = ((val & 8) ? 0xff : 0); - switch (svga->gdcreg[3] & 0x18) { - case 0: /*Set*/ - if (writemask2 & 1) - svga->vram[addr] = (vala & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]); - if (writemask2 & 2) - svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]); - if (writemask2 & 4) - svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]); - if (writemask2 & 8) - svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]); - break; - case 8: /*AND*/ - if (writemask2 & 1) - svga->vram[addr] = (vala | ~svga->gdcreg[8]) & svga->la; - if (writemask2 & 2) - svga->vram[addr | 0x1] = (valb | ~svga->gdcreg[8]) & svga->lb; - if (writemask2 & 4) - svga->vram[addr | 0x2] = (valc | ~svga->gdcreg[8]) & svga->lc; - if (writemask2 & 8) - svga->vram[addr | 0x3] = (vald | ~svga->gdcreg[8]) & svga->ld; - break; - case 0x10: /*OR*/ - if (writemask2 & 1) - svga->vram[addr] = (vala & svga->gdcreg[8]) | svga->la; - if (writemask2 & 2) - svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | svga->lb; - if (writemask2 & 4) - svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | svga->lc; - if (writemask2 & 8) - svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | svga->ld; - break; - case 0x18: /*XOR*/ - if (writemask2 & 1) - svga->vram[addr] = (vala & svga->gdcreg[8]) ^ svga->la; - if (writemask2 & 2) - svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) ^ svga->lb; - if (writemask2 & 4) - svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) ^ svga->lc; - if (writemask2 & 8) - svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) ^ svga->ld; - break; - } - } - break; - case 3: - if (svga->gdcreg[3] & 7) - val = svga_rotate[svga->gdcreg[3] & 7][val]; - wm = svga->gdcreg[8]; - svga->gdcreg[8] &= val; + switch (svga->gdcreg[3] & 0x18) { + case 0: /*Set*/ + if (writemask2 & 1) + svga->vram[addr] = (vala & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]); + if (writemask2 & 2) + svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]); + if (writemask2 & 4) + svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]); + if (writemask2 & 8) + svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]); + break; + case 8: /*AND*/ + if (writemask2 & 1) + svga->vram[addr] = (vala | ~svga->gdcreg[8]) & svga->la; + if (writemask2 & 2) + svga->vram[addr | 0x1] = (valb | ~svga->gdcreg[8]) & svga->lb; + if (writemask2 & 4) + svga->vram[addr | 0x2] = (valc | ~svga->gdcreg[8]) & svga->lc; + if (writemask2 & 8) + svga->vram[addr | 0x3] = (vald | ~svga->gdcreg[8]) & svga->ld; + break; + case 0x10: /*OR*/ + if (writemask2 & 1) + svga->vram[addr] = (vala & svga->gdcreg[8]) | svga->la; + if (writemask2 & 2) + svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | svga->lb; + if (writemask2 & 4) + svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | svga->lc; + if (writemask2 & 8) + svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | svga->ld; + break; + case 0x18: /*XOR*/ + if (writemask2 & 1) + svga->vram[addr] = (vala & svga->gdcreg[8]) ^ svga->la; + if (writemask2 & 2) + svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) ^ svga->lb; + if (writemask2 & 4) + svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) ^ svga->lc; + if (writemask2 & 8) + svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) ^ svga->ld; + break; + } + // pclog("- %02X %02X %02X %02X + // %08X\n",vram[addr],vram[addr|0x1],vram[addr|0x2],vram[addr|0x3],addr); + } + break; + case 2: + if (!(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) { + if (writemask2 & 1) + svga->vram[addr] = (((val & 1) ? 0xff : 0) & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]); + if (writemask2 & 2) + svga->vram[addr | 0x1] = + (((val & 2) ? 0xff : 0) & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]); + if (writemask2 & 4) + svga->vram[addr | 0x2] = + (((val & 4) ? 0xff : 0) & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]); + if (writemask2 & 8) + svga->vram[addr | 0x3] = + (((val & 8) ? 0xff : 0) & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]); + } else { + vala = ((val & 1) ? 0xff : 0); + valb = ((val & 2) ? 0xff : 0); + valc = ((val & 4) ? 0xff : 0); + vald = ((val & 8) ? 0xff : 0); + switch (svga->gdcreg[3] & 0x18) { + case 0: /*Set*/ + if (writemask2 & 1) + svga->vram[addr] = (vala & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]); + if (writemask2 & 2) + svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]); + if (writemask2 & 4) + svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]); + if (writemask2 & 8) + svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]); + break; + case 8: /*AND*/ + if (writemask2 & 1) + svga->vram[addr] = (vala | ~svga->gdcreg[8]) & svga->la; + if (writemask2 & 2) + svga->vram[addr | 0x1] = (valb | ~svga->gdcreg[8]) & svga->lb; + if (writemask2 & 4) + svga->vram[addr | 0x2] = (valc | ~svga->gdcreg[8]) & svga->lc; + if (writemask2 & 8) + svga->vram[addr | 0x3] = (vald | ~svga->gdcreg[8]) & svga->ld; + break; + case 0x10: /*OR*/ + if (writemask2 & 1) + svga->vram[addr] = (vala & svga->gdcreg[8]) | svga->la; + if (writemask2 & 2) + svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | svga->lb; + if (writemask2 & 4) + svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | svga->lc; + if (writemask2 & 8) + svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | svga->ld; + break; + case 0x18: /*XOR*/ + if (writemask2 & 1) + svga->vram[addr] = (vala & svga->gdcreg[8]) ^ svga->la; + if (writemask2 & 2) + svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) ^ svga->lb; + if (writemask2 & 4) + svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) ^ svga->lc; + if (writemask2 & 8) + svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) ^ svga->ld; + break; + } + } + break; + case 3: + if (svga->gdcreg[3] & 7) + val = svga_rotate[svga->gdcreg[3] & 7][val]; + wm = svga->gdcreg[8]; + svga->gdcreg[8] &= val; - vala = (svga->gdcreg[0] & 1) ? 0xff : 0; - valb = (svga->gdcreg[0] & 2) ? 0xff : 0; - valc = (svga->gdcreg[0] & 4) ? 0xff : 0; - vald = (svga->gdcreg[0] & 8) ? 0xff : 0; - switch (svga->gdcreg[3] & 0x18) { - case 0: /*Set*/ - if (writemask2 & 1) - svga->vram[addr] = (vala & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]); - if (writemask2 & 2) - svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]); - if (writemask2 & 4) - svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]); - if (writemask2 & 8) - svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]); - break; - case 8: /*AND*/ - if (writemask2 & 1) - svga->vram[addr] = (vala | ~svga->gdcreg[8]) & svga->la; - if (writemask2 & 2) - svga->vram[addr | 0x1] = (valb | ~svga->gdcreg[8]) & svga->lb; - if (writemask2 & 4) - svga->vram[addr | 0x2] = (valc | ~svga->gdcreg[8]) & svga->lc; - if (writemask2 & 8) - svga->vram[addr | 0x3] = (vald | ~svga->gdcreg[8]) & svga->ld; - break; - case 0x10: /*OR*/ - if (writemask2 & 1) - svga->vram[addr] = (vala & svga->gdcreg[8]) | svga->la; - if (writemask2 & 2) - svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | svga->lb; - if (writemask2 & 4) - svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | svga->lc; - if (writemask2 & 8) - svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | svga->ld; - break; - case 0x18: /*XOR*/ - if (writemask2 & 1) - svga->vram[addr] = (vala & svga->gdcreg[8]) ^ svga->la; - if (writemask2 & 2) - svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) ^ svga->lb; - if (writemask2 & 4) - svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) ^ svga->lc; - if (writemask2 & 8) - svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) ^ svga->ld; - break; - } - svga->gdcreg[8] = wm; - break; - } + vala = (svga->gdcreg[0] & 1) ? 0xff : 0; + valb = (svga->gdcreg[0] & 2) ? 0xff : 0; + valc = (svga->gdcreg[0] & 4) ? 0xff : 0; + vald = (svga->gdcreg[0] & 8) ? 0xff : 0; + switch (svga->gdcreg[3] & 0x18) { + case 0: /*Set*/ + if (writemask2 & 1) + svga->vram[addr] = (vala & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]); + if (writemask2 & 2) + svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]); + if (writemask2 & 4) + svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]); + if (writemask2 & 8) + svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]); + break; + case 8: /*AND*/ + if (writemask2 & 1) + svga->vram[addr] = (vala | ~svga->gdcreg[8]) & svga->la; + if (writemask2 & 2) + svga->vram[addr | 0x1] = (valb | ~svga->gdcreg[8]) & svga->lb; + if (writemask2 & 4) + svga->vram[addr | 0x2] = (valc | ~svga->gdcreg[8]) & svga->lc; + if (writemask2 & 8) + svga->vram[addr | 0x3] = (vald | ~svga->gdcreg[8]) & svga->ld; + break; + case 0x10: /*OR*/ + if (writemask2 & 1) + svga->vram[addr] = (vala & svga->gdcreg[8]) | svga->la; + if (writemask2 & 2) + svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | svga->lb; + if (writemask2 & 4) + svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | svga->lc; + if (writemask2 & 8) + svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | svga->ld; + break; + case 0x18: /*XOR*/ + if (writemask2 & 1) + svga->vram[addr] = (vala & svga->gdcreg[8]) ^ svga->la; + if (writemask2 & 2) + svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) ^ svga->lb; + if (writemask2 & 4) + svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) ^ svga->lc; + if (writemask2 & 8) + svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) ^ svga->ld; + break; + } + svga->gdcreg[8] = wm; + break; + } } uint8_t gd5429_read_linear(uint32_t addr, void *p) { - gd5429_t *gd5429 = (gd5429_t *)p; - svga_t *svga = &gd5429->svga; - uint8_t temp, temp2, temp3, temp4; - int readplane = svga->readplane; - uint32_t latch_addr; + gd5429_t *gd5429 = (gd5429_t *)p; + svga_t *svga = &gd5429->svga; + uint8_t temp, temp2, temp3, temp4; + int readplane = svga->readplane; + uint32_t latch_addr; - cycles -= video_timing_read_b; - cycles_lost += video_timing_read_b; + cycles -= video_timing_read_b; + cycles_lost += video_timing_read_b; - egareads++; + egareads++; - if (svga->gdcreg[0xb] & GRB_ENHANCED_16BIT) - latch_addr = (addr << 4) & svga->decode_mask; - else if (svga->gdcreg[0xb] & GRB_X8_ADDRESSING) - latch_addr = (addr << 3) & svga->decode_mask; - else - latch_addr = (addr << 2) & svga->decode_mask; + if (svga->gdcreg[0xb] & GRB_ENHANCED_16BIT) + latch_addr = (addr << 4) & svga->decode_mask; + else if (svga->gdcreg[0xb] & GRB_X8_ADDRESSING) + latch_addr = (addr << 3) & svga->decode_mask; + else + latch_addr = (addr << 2) & svga->decode_mask; - if (svga->gdcreg[0xb] & GRB_ENHANCED_16BIT) - addr <<= 4; - else if (svga->gdcreg[0xb] & GRB_X8_ADDRESSING) - addr <<= 3; - else if ((svga->chain4 && svga->packed_chain4) || svga->fb_only) { - addr &= svga->decode_mask; - if (addr >= svga->vram_max) - return 0xff; - return svga->vram[addr & svga->vram_mask]; - } else if (svga->chain4) { - readplane = addr & 3; - addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff); - } else if (svga->chain2_read) { - readplane = (readplane & 2) | (addr & 1); - addr &= ~1; - addr <<= 2; - } else - addr <<= 2; + if (svga->gdcreg[0xb] & GRB_ENHANCED_16BIT) + addr <<= 4; + else if (svga->gdcreg[0xb] & GRB_X8_ADDRESSING) + addr <<= 3; + else if ((svga->chain4 && svga->packed_chain4) || svga->fb_only) { + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return 0xff; + return svga->vram[addr & svga->vram_mask]; + } else if (svga->chain4) { + readplane = addr & 3; + addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff); + } else if (svga->chain2_read) { + readplane = (readplane & 2) | (addr & 1); + addr &= ~1; + addr <<= 2; + } else + addr <<= 2; - addr &= svga->decode_mask; + addr &= svga->decode_mask; - if (latch_addr >= svga->vram_max) { - svga->la = svga->lb = svga->lc = svga->ld = 0xff; - if (svga->gdcreg[0xb] & GRB_8B_LATCHES) - gd5429->latch_ext[0] = gd5429->latch_ext[1] = gd5429->latch_ext[2] = gd5429->latch_ext[3] = 0xff; - } else { - latch_addr &= svga->vram_mask; - svga->la = svga->vram[latch_addr]; - svga->lb = svga->vram[latch_addr | 0x1]; - svga->lc = svga->vram[latch_addr | 0x2]; - svga->ld = svga->vram[latch_addr | 0x3]; - if (svga->gdcreg[0xb] & GRB_8B_LATCHES) { - gd5429->latch_ext[0] = svga->vram[latch_addr | 0x4]; - gd5429->latch_ext[1] = svga->vram[latch_addr | 0x5]; - gd5429->latch_ext[2] = svga->vram[latch_addr | 0x6]; - gd5429->latch_ext[3] = svga->vram[latch_addr | 0x7]; - } - } + if (latch_addr >= svga->vram_max) { + svga->la = svga->lb = svga->lc = svga->ld = 0xff; + if (svga->gdcreg[0xb] & GRB_8B_LATCHES) + gd5429->latch_ext[0] = gd5429->latch_ext[1] = gd5429->latch_ext[2] = gd5429->latch_ext[3] = 0xff; + } else { + latch_addr &= svga->vram_mask; + svga->la = svga->vram[latch_addr]; + svga->lb = svga->vram[latch_addr | 0x1]; + svga->lc = svga->vram[latch_addr | 0x2]; + svga->ld = svga->vram[latch_addr | 0x3]; + if (svga->gdcreg[0xb] & GRB_8B_LATCHES) { + gd5429->latch_ext[0] = svga->vram[latch_addr | 0x4]; + gd5429->latch_ext[1] = svga->vram[latch_addr | 0x5]; + gd5429->latch_ext[2] = svga->vram[latch_addr | 0x6]; + gd5429->latch_ext[3] = svga->vram[latch_addr | 0x7]; + } + } - if (addr >= svga->vram_max) - return 0xff; + if (addr >= svga->vram_max) + return 0xff; - addr &= svga->vram_mask; + addr &= svga->vram_mask; - if (svga->readmode) { - temp = svga->la; - temp ^= (svga->colourcompare & 1) ? 0xff : 0; - temp &= (svga->colournocare & 1) ? 0xff : 0; - temp2 = svga->lb; - temp2 ^= (svga->colourcompare & 2) ? 0xff : 0; - temp2 &= (svga->colournocare & 2) ? 0xff : 0; - temp3 = svga->lc; - temp3 ^= (svga->colourcompare & 4) ? 0xff : 0; - temp3 &= (svga->colournocare & 4) ? 0xff : 0; - temp4 = svga->ld; - temp4 ^= (svga->colourcompare & 8) ? 0xff : 0; - temp4 &= (svga->colournocare & 8) ? 0xff : 0; - return ~(temp | temp2 | temp3 | temp4); - } -//printf("Read %02X %04X %04X\n",vram[addr|svga->readplane],addr,svga->readplane); - return svga->vram[addr | readplane]; + if (svga->readmode) { + temp = svga->la; + temp ^= (svga->colourcompare & 1) ? 0xff : 0; + temp &= (svga->colournocare & 1) ? 0xff : 0; + temp2 = svga->lb; + temp2 ^= (svga->colourcompare & 2) ? 0xff : 0; + temp2 &= (svga->colournocare & 2) ? 0xff : 0; + temp3 = svga->lc; + temp3 ^= (svga->colourcompare & 4) ? 0xff : 0; + temp3 &= (svga->colournocare & 4) ? 0xff : 0; + temp4 = svga->ld; + temp4 ^= (svga->colourcompare & 8) ? 0xff : 0; + temp4 &= (svga->colournocare & 8) ? 0xff : 0; + return ~(temp | temp2 | temp3 | temp4); + } + // printf("Read %02X %04X %04X\n",vram[addr|svga->readplane],addr,svga->readplane); + return svga->vram[addr | readplane]; } static void gd5429_writeb_linear(uint32_t addr, uint8_t val, void *p) { - gd5429_t *gd5429 = (gd5429_t *)p; - svga_t *svga = &gd5429->svga; + gd5429_t *gd5429 = (gd5429_t *)p; + svga_t *svga = &gd5429->svga; - if ((svga->writemode < 4) && !(svga->gdcreg[0xb] & (GRB_X8_ADDRESSING | GRB_8B_LATCHES))) - svga_write_linear(addr, val, svga); - else - gd5429_write_linear(addr, val & 0xff, gd5429); + if ((svga->writemode < 4) && !(svga->gdcreg[0xb] & (GRB_X8_ADDRESSING | GRB_8B_LATCHES))) + svga_write_linear(addr, val, svga); + else + gd5429_write_linear(addr, val & 0xff, gd5429); } static void gd5429_writew_linear(uint32_t addr, uint16_t val, void *p) { - gd5429_t *gd5429 = (gd5429_t *)p; - svga_t *svga = &gd5429->svga; + gd5429_t *gd5429 = (gd5429_t *)p; + svga_t *svga = &gd5429->svga; - if ((svga->writemode < 4) && !(svga->gdcreg[0xb] & (GRB_X8_ADDRESSING | GRB_8B_LATCHES))) - svga_writew_linear(addr, val, svga); - else { - gd5429_write_linear(addr, val & 0xff, gd5429); - gd5429_write_linear(addr + 1, val >> 8, gd5429); - } + if ((svga->writemode < 4) && !(svga->gdcreg[0xb] & (GRB_X8_ADDRESSING | GRB_8B_LATCHES))) + svga_writew_linear(addr, val, svga); + else { + gd5429_write_linear(addr, val & 0xff, gd5429); + gd5429_write_linear(addr + 1, val >> 8, gd5429); + } } static void gd5429_writel_linear(uint32_t addr, uint32_t val, void *p) { - gd5429_t *gd5429 = (gd5429_t *)p; - svga_t *svga = &gd5429->svga; + gd5429_t *gd5429 = (gd5429_t *)p; + svga_t *svga = &gd5429->svga; - if ((svga->writemode < 4) && !(svga->gdcreg[0xb] & (GRB_X8_ADDRESSING | GRB_8B_LATCHES))) - svga_writel_linear(addr, val, svga); - else { - gd5429_write_linear(addr, val & 0xff, gd5429); - gd5429_write_linear(addr + 1, val >> 8, gd5429); - gd5429_write_linear(addr + 2, val >> 16, gd5429); - gd5429_write_linear(addr + 3, val >> 24, gd5429); - } + if ((svga->writemode < 4) && !(svga->gdcreg[0xb] & (GRB_X8_ADDRESSING | GRB_8B_LATCHES))) + svga_writel_linear(addr, val, svga); + else { + gd5429_write_linear(addr, val & 0xff, gd5429); + gd5429_write_linear(addr + 1, val >> 8, gd5429); + gd5429_write_linear(addr + 2, val >> 16, gd5429); + gd5429_write_linear(addr + 3, val >> 24, gd5429); + } } static uint8_t gd5429_readb_linear(uint32_t addr, void *p) { - gd5429_t *gd5429 = (gd5429_t *)p; - svga_t *svga = &gd5429->svga; + gd5429_t *gd5429 = (gd5429_t *)p; + svga_t *svga = &gd5429->svga; - if (!(svga->gdcreg[0xb] & (GRB_X8_ADDRESSING | GRB_8B_LATCHES))) - return svga_read_linear(addr, &gd5429->svga); - return gd5429_read_linear(addr, gd5429); + if (!(svga->gdcreg[0xb] & (GRB_X8_ADDRESSING | GRB_8B_LATCHES))) + return svga_read_linear(addr, &gd5429->svga); + return gd5429_read_linear(addr, gd5429); } static uint16_t gd5429_readw_linear(uint32_t addr, void *p) { - gd5429_t *gd5429 = (gd5429_t *)p; - svga_t *svga = &gd5429->svga; + gd5429_t *gd5429 = (gd5429_t *)p; + svga_t *svga = &gd5429->svga; - if (!(svga->gdcreg[0xb] & (GRB_X8_ADDRESSING | GRB_8B_LATCHES))) - return svga_readw_linear(addr, &gd5429->svga); - return gd5429_read_linear(addr, gd5429) | (gd5429_read_linear(addr + 1, gd5429) << 8); + if (!(svga->gdcreg[0xb] & (GRB_X8_ADDRESSING | GRB_8B_LATCHES))) + return svga_readw_linear(addr, &gd5429->svga); + return gd5429_read_linear(addr, gd5429) | (gd5429_read_linear(addr + 1, gd5429) << 8); } static uint32_t gd5429_readl_linear(uint32_t addr, void *p) { - gd5429_t *gd5429 = (gd5429_t *)p; - svga_t *svga = &gd5429->svga; + gd5429_t *gd5429 = (gd5429_t *)p; + svga_t *svga = &gd5429->svga; - if (!(svga->gdcreg[0xb] & (GRB_X8_ADDRESSING | GRB_8B_LATCHES))) - return svga_readl_linear(addr, &gd5429->svga); - return gd5429_read_linear(addr, gd5429) | (gd5429_read_linear(addr + 1, gd5429) << 8) | - (gd5429_read_linear(addr + 2, gd5429) << 16) | (gd5429_read_linear(addr + 3, gd5429) << 24); + if (!(svga->gdcreg[0xb] & (GRB_X8_ADDRESSING | GRB_8B_LATCHES))) + return svga_readl_linear(addr, &gd5429->svga); + return gd5429_read_linear(addr, gd5429) | (gd5429_read_linear(addr + 1, gd5429) << 8) | + (gd5429_read_linear(addr + 2, gd5429) << 16) | (gd5429_read_linear(addr + 3, gd5429) << 24); } void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) { - gd5429_t *gd5429 = (gd5429_t *)p; - svga_t *svga = &gd5429->svga; - int blt_mask = gd5429->blt.mask & 7; - int x_max = 0; + gd5429_t *gd5429 = (gd5429_t *)p; + svga_t *svga = &gd5429->svga; + int blt_mask = gd5429->blt.mask & 7; + int x_max = 0; - switch (gd5429->blt.depth) { - case BLIT_DEPTH_8:x_max = 8; - break; - case BLIT_DEPTH_16:x_max = 16; - blt_mask *= 2; - break; - case BLIT_DEPTH_32:x_max = 32; - blt_mask *= 4; - break; - } + switch (gd5429->blt.depth) { + case BLIT_DEPTH_8: + x_max = 8; + break; + case BLIT_DEPTH_16: + x_max = 16; + blt_mask *= 2; + break; + case BLIT_DEPTH_32: + x_max = 32; + blt_mask *= 4; + break; + } -// pclog("gd5429_start_blit %i\n", count); - if (count == -1) { - gd5429->blt.dst_addr_backup = gd5429->blt.dst_addr; - gd5429->blt.src_addr_backup = gd5429->blt.src_addr; - gd5429->blt.width_backup = gd5429->blt.width; - gd5429->blt.height_internal = gd5429->blt.height; - gd5429->blt.x_count = 0; - if ((gd5429->blt.mode & 0xc0) == 0xc0) - gd5429->blt.y_count = gd5429->blt.src_addr & 7; - else - gd5429->blt.y_count = 0; -// pclog("gd5429_start_blit : size %i, %i %i\n", gd5429->blt.width, gd5429->blt.height, gd5429->blt.x_count); + // pclog("gd5429_start_blit %i\n", count); + if (count == -1) { + gd5429->blt.dst_addr_backup = gd5429->blt.dst_addr; + gd5429->blt.src_addr_backup = gd5429->blt.src_addr; + gd5429->blt.width_backup = gd5429->blt.width; + gd5429->blt.height_internal = gd5429->blt.height; + gd5429->blt.x_count = 0; + if ((gd5429->blt.mode & 0xc0) == 0xc0) + gd5429->blt.y_count = gd5429->blt.src_addr & 7; + else + gd5429->blt.y_count = 0; + // pclog("gd5429_start_blit : size %i, %i %i\n", gd5429->blt.width, gd5429->blt.height, + // gd5429->blt.x_count); - if (gd5429->blt.mode & 0x04) { -// pclog("blt.mode & 0x04\n"); - if (!(svga->seqregs[7] & 0xf0)) { - mem_mapping_set_handler(&svga->mapping, NULL, NULL, NULL, NULL, gd5429_blt_write_w, gd5429_blt_write_l); - mem_mapping_set_p(&svga->mapping, gd5429); - } else { - mem_mapping_set_handler(&gd5429->linear_mapping, NULL, NULL, NULL, NULL, gd5429_blt_write_w, gd5429_blt_write_l); - mem_mapping_set_p(&gd5429->linear_mapping, gd5429); - } - gd5429_recalc_mapping(gd5429); - return; - } else { - if (!(svga->seqregs[7] & 0xf0)) - mem_mapping_set_handler(&svga->mapping, gd5429_read, gd5429_readw, gd5429_readl, gd5429_write, gd5429_writew, gd5429_writel); - else - mem_mapping_set_handler(&gd5429->linear_mapping, - gd5429_readb_linear, - gd5429_readw_linear, - gd5429_readl_linear, - gd5429_writeb_linear, - gd5429_writew_linear, - gd5429_writel_linear); - gd5429_recalc_mapping(gd5429); - } - } else if (gd5429->blt.height_internal == 0xffff) - return; + if (gd5429->blt.mode & 0x04) { + // pclog("blt.mode & 0x04\n"); + if (!(svga->seqregs[7] & 0xf0)) { + mem_mapping_set_handler(&svga->mapping, NULL, NULL, NULL, NULL, gd5429_blt_write_w, + gd5429_blt_write_l); + mem_mapping_set_p(&svga->mapping, gd5429); + } else { + mem_mapping_set_handler(&gd5429->linear_mapping, NULL, NULL, NULL, NULL, gd5429_blt_write_w, + gd5429_blt_write_l); + mem_mapping_set_p(&gd5429->linear_mapping, gd5429); + } + gd5429_recalc_mapping(gd5429); + return; + } else { + if (!(svga->seqregs[7] & 0xf0)) + mem_mapping_set_handler(&svga->mapping, gd5429_read, gd5429_readw, gd5429_readl, gd5429_write, + gd5429_writew, gd5429_writel); + else + mem_mapping_set_handler(&gd5429->linear_mapping, gd5429_readb_linear, gd5429_readw_linear, + gd5429_readl_linear, gd5429_writeb_linear, gd5429_writew_linear, + gd5429_writel_linear); + gd5429_recalc_mapping(gd5429); + } + } else if (gd5429->blt.height_internal == 0xffff) + return; - while (count) { - uint8_t src = 0, dst; - int mask = 0; - int shift; + while (count) { + uint8_t src = 0, dst; + int mask = 0; + int shift; - if (gd5429->blt.depth == BLIT_DEPTH_32) - shift = (gd5429->blt.x_count & 3) * 8; - else if (gd5429->blt.depth == BLIT_DEPTH_8) - shift = 0; - else - shift = (gd5429->blt.x_count & 1) * 8; + if (gd5429->blt.depth == BLIT_DEPTH_32) + shift = (gd5429->blt.x_count & 3) * 8; + else if (gd5429->blt.depth == BLIT_DEPTH_8) + shift = 0; + else + shift = (gd5429->blt.x_count & 1) * 8; - if (gd5429->blt.mode & 0x04) { - if (gd5429->blt.mode & 0x80) { - mask = cpu_dat & 0x80; + if (gd5429->blt.mode & 0x04) { + if (gd5429->blt.mode & 0x80) { + mask = cpu_dat & 0x80; - switch (gd5429->blt.depth) { - case BLIT_DEPTH_8:src = mask ? gd5429->blt.fg_col : gd5429->blt.bg_col; - cpu_dat <<= 1; - count--; - break; - case BLIT_DEPTH_16:src = mask ? (gd5429->blt.fg_col >> shift) : (gd5429->blt.bg_col >> shift); - if (gd5429->blt.x_count & 1) { - cpu_dat <<= 1; - count--; - } - break; - case BLIT_DEPTH_32:src = mask ? (gd5429->blt.fg_col >> shift) : (gd5429->blt.bg_col >> shift); - if ((gd5429->blt.x_count & 3) == 3) { - cpu_dat <<= 1; - count--; - } - break; - } - } else { - src = cpu_dat & 0xff; - cpu_dat >>= 8; - count -= 8; - mask = 1; - } - } else { - switch (gd5429->blt.mode & 0xc0) { - case 0x00:src = svga->vram[gd5429->blt.src_addr & svga->vram_mask]; - gd5429->blt.src_addr += ((gd5429->blt.mode & 0x01) ? -1 : 1); - mask = 1; - break; - case 0x40: - switch (gd5429->blt.depth) { - case BLIT_DEPTH_8:src = svga->vram[(gd5429->blt.src_addr & (svga->vram_mask & ~7)) + (gd5429->blt.y_count << 3) + (gd5429->blt.x_count & 7)]; - break; - case BLIT_DEPTH_16:src = svga->vram[(gd5429->blt.src_addr & (svga->vram_mask & ~3)) + (gd5429->blt.y_count << 4) + (gd5429->blt.x_count & 15)]; - break; - case BLIT_DEPTH_32:src = svga->vram[(gd5429->blt.src_addr & (svga->vram_mask & ~3)) + (gd5429->blt.y_count << 5) + (gd5429->blt.x_count & 31)]; - break; - } - mask = 1; - break; - case 0x80: - switch (gd5429->blt.depth) { - case BLIT_DEPTH_8:mask = svga->vram[gd5429->blt.src_addr & svga->vram_mask] & (0x80 >> gd5429->blt.x_count); - src = mask ? gd5429->blt.fg_col : gd5429->blt.bg_col; - break; - case BLIT_DEPTH_16:mask = svga->vram[gd5429->blt.src_addr & svga->vram_mask] & (0x80 >> (gd5429->blt.x_count >> 1)); - src = mask ? (gd5429->blt.fg_col >> shift) : (gd5429->blt.bg_col >> shift); - break; - case BLIT_DEPTH_32:mask = svga->vram[gd5429->blt.src_addr & svga->vram_mask] & (0x80 >> (gd5429->blt.x_count >> 2)); - src = mask ? (gd5429->blt.fg_col >> shift) : (gd5429->blt.bg_col >> shift); - break; - } - break; - case 0xc0: - switch (gd5429->blt.depth) { - case BLIT_DEPTH_8:mask = svga->vram[(gd5429->blt.src_addr & svga->vram_mask & ~7) | gd5429->blt.y_count] & (0x80 >> gd5429->blt.x_count); - src = mask ? gd5429->blt.fg_col : gd5429->blt.bg_col; - break; - case BLIT_DEPTH_16:mask = svga->vram[(gd5429->blt.src_addr & svga->vram_mask & ~7) | gd5429->blt.y_count] & (0x80 >> (gd5429->blt.x_count >> 1)); - src = mask ? (gd5429->blt.fg_col >> shift) : (gd5429->blt.bg_col >> shift); - break; - case BLIT_DEPTH_32:mask = svga->vram[(gd5429->blt.src_addr & svga->vram_mask & ~7) | gd5429->blt.y_count] & (0x80 >> (gd5429->blt.x_count >> 2)); - src = mask ? (gd5429->blt.fg_col >> shift) : (gd5429->blt.bg_col >> shift); - break; - } - break; - } - count--; - } - dst = svga->vram[gd5429->blt.dst_addr & svga->vram_mask]; - svga->changedvram[(gd5429->blt.dst_addr & svga->vram_mask) >> 12] = changeframecount; + switch (gd5429->blt.depth) { + case BLIT_DEPTH_8: + src = mask ? gd5429->blt.fg_col : gd5429->blt.bg_col; + cpu_dat <<= 1; + count--; + break; + case BLIT_DEPTH_16: + src = mask ? (gd5429->blt.fg_col >> shift) : (gd5429->blt.bg_col >> shift); + if (gd5429->blt.x_count & 1) { + cpu_dat <<= 1; + count--; + } + break; + case BLIT_DEPTH_32: + src = mask ? (gd5429->blt.fg_col >> shift) : (gd5429->blt.bg_col >> shift); + if ((gd5429->blt.x_count & 3) == 3) { + cpu_dat <<= 1; + count--; + } + break; + } + } else { + src = cpu_dat & 0xff; + cpu_dat >>= 8; + count -= 8; + mask = 1; + } + } else { + switch (gd5429->blt.mode & 0xc0) { + case 0x00: + src = svga->vram[gd5429->blt.src_addr & svga->vram_mask]; + gd5429->blt.src_addr += ((gd5429->blt.mode & 0x01) ? -1 : 1); + mask = 1; + break; + case 0x40: + switch (gd5429->blt.depth) { + case BLIT_DEPTH_8: + src = svga->vram[(gd5429->blt.src_addr & (svga->vram_mask & ~7)) + + (gd5429->blt.y_count << 3) + (gd5429->blt.x_count & 7)]; + break; + case BLIT_DEPTH_16: + src = svga->vram[(gd5429->blt.src_addr & (svga->vram_mask & ~3)) + + (gd5429->blt.y_count << 4) + (gd5429->blt.x_count & 15)]; + break; + case BLIT_DEPTH_32: + src = svga->vram[(gd5429->blt.src_addr & (svga->vram_mask & ~3)) + + (gd5429->blt.y_count << 5) + (gd5429->blt.x_count & 31)]; + break; + } + mask = 1; + break; + case 0x80: + switch (gd5429->blt.depth) { + case BLIT_DEPTH_8: + mask = svga->vram[gd5429->blt.src_addr & svga->vram_mask] & (0x80 >> gd5429->blt.x_count); + src = mask ? gd5429->blt.fg_col : gd5429->blt.bg_col; + break; + case BLIT_DEPTH_16: + mask = svga->vram[gd5429->blt.src_addr & svga->vram_mask] & + (0x80 >> (gd5429->blt.x_count >> 1)); + src = mask ? (gd5429->blt.fg_col >> shift) : (gd5429->blt.bg_col >> shift); + break; + case BLIT_DEPTH_32: + mask = svga->vram[gd5429->blt.src_addr & svga->vram_mask] & + (0x80 >> (gd5429->blt.x_count >> 2)); + src = mask ? (gd5429->blt.fg_col >> shift) : (gd5429->blt.bg_col >> shift); + break; + } + break; + case 0xc0: + switch (gd5429->blt.depth) { + case BLIT_DEPTH_8: + mask = svga->vram[(gd5429->blt.src_addr & svga->vram_mask & ~7) | gd5429->blt.y_count] & + (0x80 >> gd5429->blt.x_count); + src = mask ? gd5429->blt.fg_col : gd5429->blt.bg_col; + break; + case BLIT_DEPTH_16: + mask = svga->vram[(gd5429->blt.src_addr & svga->vram_mask & ~7) | gd5429->blt.y_count] & + (0x80 >> (gd5429->blt.x_count >> 1)); + src = mask ? (gd5429->blt.fg_col >> shift) : (gd5429->blt.bg_col >> shift); + break; + case BLIT_DEPTH_32: + mask = svga->vram[(gd5429->blt.src_addr & svga->vram_mask & ~7) | gd5429->blt.y_count] & + (0x80 >> (gd5429->blt.x_count >> 2)); + src = mask ? (gd5429->blt.fg_col >> shift) : (gd5429->blt.bg_col >> shift); + break; + } + break; + } + count--; + } + dst = svga->vram[gd5429->blt.dst_addr & svga->vram_mask]; + svga->changedvram[(gd5429->blt.dst_addr & svga->vram_mask) >> 12] = changeframecount; -// pclog("Blit %i,%i %06X %06X %06X %02X %02X %02X %02X ", gd5429->blt.width, gd5429->blt.height_internal, gd5429->blt.src_addr, gd5429->blt.dst_addr, gd5429->blt.src_addr & svga->vram_mask, svga->vram[gd5429->blt.src_addr & svga->vram_mask], 0x80 >> (gd5429->blt.dst_addr & 7), src, dst); - switch (gd5429->blt.rop) { - case 0x00:dst = 0; - break; - case 0x05:dst = src & dst; - break; - case 0x06:dst = dst; - break; - case 0x09:dst = src & ~dst; - break; - case 0x0b:dst = ~dst; - break; - case 0x0d:dst = src; - break; - case 0x0e:dst = 0xff; - break; - case 0x50:dst = ~src & dst; - break; - case 0x59:dst = src ^ dst; - break; - case 0x6d:dst = src | dst; - break; - case 0x90:dst = ~(src | dst); - break; - case 0x95:dst = ~(src ^ dst); - break; - case 0xad:dst = src | ~dst; - break; - case 0xd0:dst = ~src; - break; - case 0xd6:dst = ~src | dst; - break; - case 0xda:dst = ~(src & dst); - break; - } - //pclog("%02X %02X\n", dst, mask); + // pclog("Blit %i,%i %06X %06X %06X %02X %02X %02X %02X ", gd5429->blt.width, + // gd5429->blt.height_internal, gd5429->blt.src_addr, gd5429->blt.dst_addr, gd5429->blt.src_addr & + // svga->vram_mask, svga->vram[gd5429->blt.src_addr & svga->vram_mask], 0x80 >> + // (gd5429->blt.dst_addr & 7), src, dst); + switch (gd5429->blt.rop) { + case 0x00: + dst = 0; + break; + case 0x05: + dst = src & dst; + break; + case 0x06: + dst = dst; + break; + case 0x09: + dst = src & ~dst; + break; + case 0x0b: + dst = ~dst; + break; + case 0x0d: + dst = src; + break; + case 0x0e: + dst = 0xff; + break; + case 0x50: + dst = ~src & dst; + break; + case 0x59: + dst = src ^ dst; + break; + case 0x6d: + dst = src | dst; + break; + case 0x90: + dst = ~(src | dst); + break; + case 0x95: + dst = ~(src ^ dst); + break; + case 0xad: + dst = src | ~dst; + break; + case 0xd0: + dst = ~src; + break; + case 0xd6: + dst = ~src | dst; + break; + case 0xda: + dst = ~(src & dst); + break; + } + // pclog("%02X %02X\n", dst, mask); - if (gd5429->type <= CL_TYPE_GD5428) { - if ((gd5429->blt.width_backup - gd5429->blt.width) >= blt_mask && - (!(gd5429->blt.mode & 0x08) || (dst & gd5429->blt.trans_mask) != gd5429->blt.trans_col)) - svga->vram[gd5429->blt.dst_addr & svga->vram_mask] = dst; - } else { - if ((gd5429->blt.width_backup - gd5429->blt.width) >= blt_mask && - !((gd5429->blt.mode & 0x08) && !mask)) - svga->vram[gd5429->blt.dst_addr & svga->vram_mask] = dst; - } + if (gd5429->type <= CL_TYPE_GD5428) { + if ((gd5429->blt.width_backup - gd5429->blt.width) >= blt_mask && + (!(gd5429->blt.mode & 0x08) || (dst & gd5429->blt.trans_mask) != gd5429->blt.trans_col)) + svga->vram[gd5429->blt.dst_addr & svga->vram_mask] = dst; + } else { + if ((gd5429->blt.width_backup - gd5429->blt.width) >= blt_mask && !((gd5429->blt.mode & 0x08) && !mask)) + svga->vram[gd5429->blt.dst_addr & svga->vram_mask] = dst; + } - gd5429->blt.dst_addr += ((gd5429->blt.mode & 0x01) ? -1 : 1); + gd5429->blt.dst_addr += ((gd5429->blt.mode & 0x01) ? -1 : 1); - gd5429->blt.x_count++; - if (gd5429->blt.x_count == x_max) { - gd5429->blt.x_count = 0; - if ((gd5429->blt.mode & 0xc0) == 0x80) - gd5429->blt.src_addr++; - } + gd5429->blt.x_count++; + if (gd5429->blt.x_count == x_max) { + gd5429->blt.x_count = 0; + if ((gd5429->blt.mode & 0xc0) == 0x80) + gd5429->blt.src_addr++; + } - gd5429->blt.width--; + gd5429->blt.width--; - if (gd5429->blt.width == 0xffff) { - gd5429->blt.width = gd5429->blt.width_backup; + if (gd5429->blt.width == 0xffff) { + gd5429->blt.width = gd5429->blt.width_backup; - gd5429->blt.dst_addr = gd5429->blt.dst_addr_backup = gd5429->blt.dst_addr_backup + ((gd5429->blt.mode & 0x01) ? -gd5429->blt.dst_pitch : gd5429->blt.dst_pitch); + gd5429->blt.dst_addr = gd5429->blt.dst_addr_backup = + gd5429->blt.dst_addr_backup + + ((gd5429->blt.mode & 0x01) ? -gd5429->blt.dst_pitch : gd5429->blt.dst_pitch); - switch (gd5429->blt.mode & 0xc0) { - case 0x00:gd5429->blt.src_addr = gd5429->blt.src_addr_backup = gd5429->blt.src_addr_backup + ((gd5429->blt.mode & 0x01) ? -gd5429->blt.src_pitch : gd5429->blt.src_pitch); - break; - case 0x80: - if (gd5429->blt.x_count != 0) - gd5429->blt.src_addr++; - break; - } + switch (gd5429->blt.mode & 0xc0) { + case 0x00: + gd5429->blt.src_addr = gd5429->blt.src_addr_backup = + gd5429->blt.src_addr_backup + + ((gd5429->blt.mode & 0x01) ? -gd5429->blt.src_pitch : gd5429->blt.src_pitch); + break; + case 0x80: + if (gd5429->blt.x_count != 0) + gd5429->blt.src_addr++; + break; + } - gd5429->blt.x_count = 0; - if (gd5429->blt.mode & 0x01) - gd5429->blt.y_count = (gd5429->blt.y_count - 1) & 7; - else - gd5429->blt.y_count = (gd5429->blt.y_count + 1) & 7; + gd5429->blt.x_count = 0; + if (gd5429->blt.mode & 0x01) + gd5429->blt.y_count = (gd5429->blt.y_count - 1) & 7; + else + gd5429->blt.y_count = (gd5429->blt.y_count + 1) & 7; - gd5429->blt.height_internal--; - if (gd5429->blt.height_internal == 0xffff) { - if (gd5429->blt.mode & 0x04) { - if (!(svga->seqregs[7] & 0xf0)) - mem_mapping_set_handler(&svga->mapping, gd5429_read, gd5429_readw, gd5429_readl, gd5429_write, gd5429_writew, gd5429_writel); - else - mem_mapping_set_handler(&gd5429->linear_mapping, - gd5429_readb_linear, - gd5429_readw_linear, - gd5429_readl_linear, - gd5429_writeb_linear, - gd5429_writew_linear, - gd5429_writel_linear); -// mem_mapping_set_handler(&gd5429->svga.mapping, gd5429_read, NULL, NULL, gd5429_write, NULL, NULL); -// mem_mapping_set_p(&gd5429->svga.mapping, gd5429); - gd5429_recalc_mapping(gd5429); - } - return; - } + gd5429->blt.height_internal--; + if (gd5429->blt.height_internal == 0xffff) { + if (gd5429->blt.mode & 0x04) { + if (!(svga->seqregs[7] & 0xf0)) + mem_mapping_set_handler(&svga->mapping, gd5429_read, gd5429_readw, gd5429_readl, + gd5429_write, gd5429_writew, gd5429_writel); + else + mem_mapping_set_handler(&gd5429->linear_mapping, gd5429_readb_linear, + gd5429_readw_linear, gd5429_readl_linear, + gd5429_writeb_linear, gd5429_writew_linear, + gd5429_writel_linear); + // mem_mapping_set_handler(&gd5429->svga.mapping, + // gd5429_read, NULL, NULL, gd5429_write, NULL, + // NULL); mem_mapping_set_p(&gd5429->svga.mapping, + // gd5429); + gd5429_recalc_mapping(gd5429); + } + return; + } - if (gd5429->blt.mode & 0x04) - return; - } - } + if (gd5429->blt.mode & 0x04) + return; + } + } } static void gd5429_mmio_write(uint32_t addr, uint8_t val, void *p) { - gd5429_t *gd5429 = (gd5429_t *)p; + gd5429_t *gd5429 = (gd5429_t *)p; - if ((addr & ~0xff) == 0xb8000) { - // pclog("MMIO write %08X %02X\n", addr, val); - switch (addr & 0xff) { - case 0x00: - if (gd5429->type >= CL_TYPE_GD5434) - gd5429->blt.bg_col = (gd5429->blt.bg_col & 0xffffff00) | val; - else - gd5429->blt.bg_col = (gd5429->blt.bg_col & 0xff00) | val; - break; - case 0x01: - if (gd5429->type >= CL_TYPE_GD5434) - gd5429->blt.bg_col = (gd5429->blt.bg_col & 0xffff00ff) | (val << 8); - else - gd5429->blt.bg_col = (gd5429->blt.bg_col & 0x00ff) | (val << 8); - break; - case 0x02: - if (gd5429->type >= CL_TYPE_GD5434) - gd5429->blt.bg_col = (gd5429->blt.bg_col & 0xff00ffff) | (val << 16); - break; - case 0x03: - if (gd5429->type >= CL_TYPE_GD5434) - gd5429->blt.bg_col = (gd5429->blt.bg_col & 0x00ffffff) | (val << 24); - break; + if ((addr & ~0xff) == 0xb8000) { + // pclog("MMIO write %08X %02X\n", addr, val); + switch (addr & 0xff) { + case 0x00: + if (gd5429->type >= CL_TYPE_GD5434) + gd5429->blt.bg_col = (gd5429->blt.bg_col & 0xffffff00) | val; + else + gd5429->blt.bg_col = (gd5429->blt.bg_col & 0xff00) | val; + break; + case 0x01: + if (gd5429->type >= CL_TYPE_GD5434) + gd5429->blt.bg_col = (gd5429->blt.bg_col & 0xffff00ff) | (val << 8); + else + gd5429->blt.bg_col = (gd5429->blt.bg_col & 0x00ff) | (val << 8); + break; + case 0x02: + if (gd5429->type >= CL_TYPE_GD5434) + gd5429->blt.bg_col = (gd5429->blt.bg_col & 0xff00ffff) | (val << 16); + break; + case 0x03: + if (gd5429->type >= CL_TYPE_GD5434) + gd5429->blt.bg_col = (gd5429->blt.bg_col & 0x00ffffff) | (val << 24); + break; - case 0x04: - if (gd5429->type >= CL_TYPE_GD5434) - gd5429->blt.fg_col = (gd5429->blt.fg_col & 0xffffff00) | val; - else - gd5429->blt.fg_col = (gd5429->blt.fg_col & 0xff00) | val; - break; - case 0x05: - if (gd5429->type >= CL_TYPE_GD5434) - gd5429->blt.fg_col = (gd5429->blt.fg_col & 0xffff00ff) | (val << 8); - else - gd5429->blt.fg_col = (gd5429->blt.fg_col & 0x00ff) | (val << 8); - break; - case 0x06: - if (gd5429->type >= CL_TYPE_GD5434) - gd5429->blt.fg_col = (gd5429->blt.fg_col & 0xff00ffff) | (val << 16); - break; - case 0x07: - if (gd5429->type >= CL_TYPE_GD5434) - gd5429->blt.fg_col = (gd5429->blt.fg_col & 0x00ffffff) | (val << 24); - break; + case 0x04: + if (gd5429->type >= CL_TYPE_GD5434) + gd5429->blt.fg_col = (gd5429->blt.fg_col & 0xffffff00) | val; + else + gd5429->blt.fg_col = (gd5429->blt.fg_col & 0xff00) | val; + break; + case 0x05: + if (gd5429->type >= CL_TYPE_GD5434) + gd5429->blt.fg_col = (gd5429->blt.fg_col & 0xffff00ff) | (val << 8); + else + gd5429->blt.fg_col = (gd5429->blt.fg_col & 0x00ff) | (val << 8); + break; + case 0x06: + if (gd5429->type >= CL_TYPE_GD5434) + gd5429->blt.fg_col = (gd5429->blt.fg_col & 0xff00ffff) | (val << 16); + break; + case 0x07: + if (gd5429->type >= CL_TYPE_GD5434) + gd5429->blt.fg_col = (gd5429->blt.fg_col & 0x00ffffff) | (val << 24); + break; - case 0x08:gd5429->blt.width = (gd5429->blt.width & 0xff00) | val; - break; - case 0x09:gd5429->blt.width = (gd5429->blt.width & 0x00ff) | (val << 8); - if (gd5429->type >= CL_TYPE_GD5434) - gd5429->blt.width &= 0x1fff; - else - gd5429->blt.width &= 0x07ff; - break; - case 0x0a:gd5429->blt.height = (gd5429->blt.height & 0xff00) | val; - break; - case 0x0b:gd5429->blt.height = (gd5429->blt.height & 0x00ff) | (val << 8); - gd5429->blt.height &= 0x03ff; - break; - case 0x0c:gd5429->blt.dst_pitch = (gd5429->blt.dst_pitch & 0xff00) | val; - break; - case 0x0d:gd5429->blt.dst_pitch = (gd5429->blt.dst_pitch & 0x00ff) | (val << 8); - break; - case 0x0e:gd5429->blt.src_pitch = (gd5429->blt.src_pitch & 0xff00) | val; - break; - case 0x0f:gd5429->blt.src_pitch = (gd5429->blt.src_pitch & 0x00ff) | (val << 8); - break; + case 0x08: + gd5429->blt.width = (gd5429->blt.width & 0xff00) | val; + break; + case 0x09: + gd5429->blt.width = (gd5429->blt.width & 0x00ff) | (val << 8); + if (gd5429->type >= CL_TYPE_GD5434) + gd5429->blt.width &= 0x1fff; + else + gd5429->blt.width &= 0x07ff; + break; + case 0x0a: + gd5429->blt.height = (gd5429->blt.height & 0xff00) | val; + break; + case 0x0b: + gd5429->blt.height = (gd5429->blt.height & 0x00ff) | (val << 8); + gd5429->blt.height &= 0x03ff; + break; + case 0x0c: + gd5429->blt.dst_pitch = (gd5429->blt.dst_pitch & 0xff00) | val; + break; + case 0x0d: + gd5429->blt.dst_pitch = (gd5429->blt.dst_pitch & 0x00ff) | (val << 8); + break; + case 0x0e: + gd5429->blt.src_pitch = (gd5429->blt.src_pitch & 0xff00) | val; + break; + case 0x0f: + gd5429->blt.src_pitch = (gd5429->blt.src_pitch & 0x00ff) | (val << 8); + break; - case 0x10:gd5429->blt.dst_addr = (gd5429->blt.dst_addr & 0xffff00) | val; - break; - case 0x11:gd5429->blt.dst_addr = (gd5429->blt.dst_addr & 0xff00ff) | (val << 8); - break; - case 0x12:gd5429->blt.dst_addr = (gd5429->blt.dst_addr & 0x00ffff) | (val << 16); - if (gd5429->type >= CL_TYPE_GD5434) - gd5429->blt.dst_addr &= 0x3fffff; - else - gd5429->blt.dst_addr &= 0x1fffff; - break; + case 0x10: + gd5429->blt.dst_addr = (gd5429->blt.dst_addr & 0xffff00) | val; + break; + case 0x11: + gd5429->blt.dst_addr = (gd5429->blt.dst_addr & 0xff00ff) | (val << 8); + break; + case 0x12: + gd5429->blt.dst_addr = (gd5429->blt.dst_addr & 0x00ffff) | (val << 16); + if (gd5429->type >= CL_TYPE_GD5434) + gd5429->blt.dst_addr &= 0x3fffff; + else + gd5429->blt.dst_addr &= 0x1fffff; + break; - case 0x14:gd5429->blt.src_addr = (gd5429->blt.src_addr & 0xffff00) | val; - break; - case 0x15:gd5429->blt.src_addr = (gd5429->blt.src_addr & 0xff00ff) | (val << 8); - break; - case 0x16:gd5429->blt.src_addr = (gd5429->blt.src_addr & 0x00ffff) | (val << 16); - if (gd5429->type >= CL_TYPE_GD5434) - gd5429->blt.src_addr &= 0x3fffff; - else - gd5429->blt.src_addr &= 0x1fffff; - break; + case 0x14: + gd5429->blt.src_addr = (gd5429->blt.src_addr & 0xffff00) | val; + break; + case 0x15: + gd5429->blt.src_addr = (gd5429->blt.src_addr & 0xff00ff) | (val << 8); + break; + case 0x16: + gd5429->blt.src_addr = (gd5429->blt.src_addr & 0x00ffff) | (val << 16); + if (gd5429->type >= CL_TYPE_GD5434) + gd5429->blt.src_addr &= 0x3fffff; + else + gd5429->blt.src_addr &= 0x1fffff; + break; - case 0x17:gd5429->blt.mask = val; - break; - case 0x18:gd5429->blt.mode = val; - if (gd5429->type >= CL_TYPE_GD5434) - gd5429->blt.depth = (val >> 4) & 3; - else - gd5429->blt.depth = (val >> 4) & 1; - break; + case 0x17: + gd5429->blt.mask = val; + break; + case 0x18: + gd5429->blt.mode = val; + if (gd5429->type >= CL_TYPE_GD5434) + gd5429->blt.depth = (val >> 4) & 3; + else + gd5429->blt.depth = (val >> 4) & 1; + break; - case 0x1a:gd5429->blt.rop = val; - break; + case 0x1a: + gd5429->blt.rop = val; + break; - case 0x40: - if (val & 0x02) - gd5429_start_blit(0, -1, gd5429); - break; - } - } else if (gd5429->mmio_vram_overlap) - gd5429_write(addr, val, gd5429); + case 0x40: + if (val & 0x02) + gd5429_start_blit(0, -1, gd5429); + break; + } + } else if (gd5429->mmio_vram_overlap) + gd5429_write(addr, val, gd5429); } static void gd5429_mmio_writew(uint32_t addr, uint16_t val, void *p) { - gd5429_t *gd5429 = (gd5429_t *)p; + gd5429_t *gd5429 = (gd5429_t *)p; - if ((addr & ~0xff) == 0xb8000) { - gd5429_mmio_write(addr, val & 0xff, gd5429); - gd5429_mmio_write(addr + 1, val >> 8, gd5429); - } else if (gd5429->mmio_vram_overlap) - gd5429_writew(addr, val, gd5429); + if ((addr & ~0xff) == 0xb8000) { + gd5429_mmio_write(addr, val & 0xff, gd5429); + gd5429_mmio_write(addr + 1, val >> 8, gd5429); + } else if (gd5429->mmio_vram_overlap) + gd5429_writew(addr, val, gd5429); } static void gd5429_mmio_writel(uint32_t addr, uint32_t val, void *p) { - gd5429_t *gd5429 = (gd5429_t *)p; + gd5429_t *gd5429 = (gd5429_t *)p; - if ((addr & ~0xff) == 0xb8000) { - gd5429_mmio_writew(addr, val & 0xffff, gd5429); - gd5429_mmio_writew(addr + 2, val >> 16, gd5429); - } else if (gd5429->mmio_vram_overlap) - gd5429_writel(addr, val, gd5429); + if ((addr & ~0xff) == 0xb8000) { + gd5429_mmio_writew(addr, val & 0xffff, gd5429); + gd5429_mmio_writew(addr + 2, val >> 16, gd5429); + } else if (gd5429->mmio_vram_overlap) + gd5429_writel(addr, val, gd5429); } static uint8_t gd5429_mmio_read(uint32_t addr, void *p) { - gd5429_t *gd5429 = (gd5429_t *)p; + gd5429_t *gd5429 = (gd5429_t *)p; - if ((addr & ~0xff) == 0xb8000) { -// pclog("MMIO read %08X\n", addr); - switch (addr & 0xff) { - case 0x40: /*BLT status*/ - return 0; - } - return 0xff; /*All other registers read-only*/ - } - if (gd5429->mmio_vram_overlap) - return gd5429_read(addr, gd5429); - return 0xff; + if ((addr & ~0xff) == 0xb8000) { + // pclog("MMIO read %08X\n", addr); + switch (addr & 0xff) { + case 0x40: /*BLT status*/ + return 0; + } + return 0xff; /*All other registers read-only*/ + } + if (gd5429->mmio_vram_overlap) + return gd5429_read(addr, gd5429); + return 0xff; } static uint16_t gd5429_mmio_readw(uint32_t addr, void *p) { - gd5429_t *gd5429 = (gd5429_t *)p; + gd5429_t *gd5429 = (gd5429_t *)p; - if ((addr & ~0xff) == 0xb8000) - return gd5429_mmio_read(addr, gd5429) | (gd5429_mmio_read(addr + 1, gd5429) << 8); - if (gd5429->mmio_vram_overlap) - return gd5429_readw(addr, gd5429); - return 0xffff; + if ((addr & ~0xff) == 0xb8000) + return gd5429_mmio_read(addr, gd5429) | (gd5429_mmio_read(addr + 1, gd5429) << 8); + if (gd5429->mmio_vram_overlap) + return gd5429_readw(addr, gd5429); + return 0xffff; } static uint32_t gd5429_mmio_readl(uint32_t addr, void *p) { - gd5429_t *gd5429 = (gd5429_t *)p; + gd5429_t *gd5429 = (gd5429_t *)p; - if ((addr & ~0xff) == 0xb8000) - return gd5429_mmio_readw(addr, gd5429) | (gd5429_mmio_readw(addr + 2, gd5429) << 16); - if (gd5429->mmio_vram_overlap) - return gd5429_readl(addr, gd5429); - return 0xffffffff; + if ((addr & ~0xff) == 0xb8000) + return gd5429_mmio_readw(addr, gd5429) | (gd5429_mmio_readw(addr + 2, gd5429) << 16); + if (gd5429->mmio_vram_overlap) + return gd5429_readl(addr, gd5429); + return 0xffffffff; } void gd5429_blt_write_w(uint32_t addr, uint16_t val, void *p) { - gd5429_t *gd5429 = (gd5429_t *)p; - -// pclog("gd5429_blt_write_w %08X %08X\n", addr, val); - if (!gd5429->blt.mem_word_sel) - gd5429->blt.mem_word_save = val; - else - gd5429_start_blit(gd5429->blt.mem_word_save | (val << 16), 32, p); - gd5429->blt.mem_word_sel = !gd5429->blt.mem_word_sel; + gd5429_t *gd5429 = (gd5429_t *)p; + // pclog("gd5429_blt_write_w %08X %08X\n", addr, val); + if (!gd5429->blt.mem_word_sel) + gd5429->blt.mem_word_save = val; + else + gd5429_start_blit(gd5429->blt.mem_word_save | (val << 16), 32, p); + gd5429->blt.mem_word_sel = !gd5429->blt.mem_word_sel; } void gd5429_blt_write_l(uint32_t addr, uint32_t val, void *p) { - gd5429_t *gd5429 = (gd5429_t *)p; + gd5429_t *gd5429 = (gd5429_t *)p; - gd5429->blt.mem_word_sel = 0; -// pclog("gd5429_blt_write_l %08X %08X %04X %04X\n", addr, val, ((val >> 8) & 0x00ff) | ((val << 8) & 0xff00), ((val >> 24) & 0x00ff) | ((val >> 8) & 0xff00)); - if ((gd5429->blt.mode & 0x84) == 0x84) { - gd5429_start_blit(val & 0xff, 8, p); - gd5429_start_blit((val >> 8) & 0xff, 8, p); - gd5429_start_blit((val >> 16) & 0xff, 8, p); - gd5429_start_blit((val >> 24) & 0xff, 8, p); - } else - gd5429_start_blit(val, 32, p); + gd5429->blt.mem_word_sel = 0; + // pclog("gd5429_blt_write_l %08X %08X %04X %04X\n", addr, val, ((val >> 8) & 0x00ff) | ((val << 8) & 0xff00), + // ((val >> 24) & 0x00ff) | ((val >> 8) & 0xff00)); + if ((gd5429->blt.mode & 0x84) == 0x84) { + gd5429_start_blit(val & 0xff, 8, p); + gd5429_start_blit((val >> 8) & 0xff, 8, p); + gd5429_start_blit((val >> 16) & 0xff, 8, p); + gd5429_start_blit((val >> 24) & 0xff, 8, p); + } else + gd5429_start_blit(val, 32, p); } uint8_t ibm_gd5428_mca_read(int port, void *p) { - gd5429_t *gd5429 = (gd5429_t *)p; + gd5429_t *gd5429 = (gd5429_t *)p; -// pclog("gd5429_pro_mcv_read: port=%04x %02x %04x:%04x\n", port, gd5429->pos_regs[port & 7], CS, cpu_state.pc); + // pclog("gd5429_pro_mcv_read: port=%04x %02x %04x:%04x\n", port, gd5429->pos_regs[port & 7], CS, cpu_state.pc); - return gd5429->pos_regs[port & 7]; + return gd5429->pos_regs[port & 7]; } static void ibm_gd5428_mapping_update(gd5429_t *gd5429) { - gd5429_recalc_mapping(gd5429); + gd5429_recalc_mapping(gd5429); - io_removehandler(0x03a0, 0x0023, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); - io_removehandler(0x03c4, 0x001c, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); - if ((gd5429->pos_regs[2] & 0x01) && gd5429->vidsys_ena) { -// pclog(" GD5429 enable registers\n"); - io_sethandler(0x03c0, 0x0003, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); - io_sethandler(0x03c4, 0x001c, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); - if (!(gd5429->svga.miscout & 1)) - io_sethandler(0x03a0, 0x0020, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); - gd5429->svga.override = 0; - if (mb_vga) - svga_set_override(mb_vga, 1); - } else { -// pclog(" GD5429 disable registers\n"); - gd5429->svga.override = 1; - if (mb_vga) - svga_set_override(mb_vga, 0); - } + io_removehandler(0x03a0, 0x0023, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); + io_removehandler(0x03c4, 0x001c, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); + if ((gd5429->pos_regs[2] & 0x01) && gd5429->vidsys_ena) { + // pclog(" GD5429 enable registers\n"); + io_sethandler(0x03c0, 0x0003, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); + io_sethandler(0x03c4, 0x001c, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); + if (!(gd5429->svga.miscout & 1)) + io_sethandler(0x03a0, 0x0020, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); + gd5429->svga.override = 0; + if (mb_vga) + svga_set_override(mb_vga, 1); + } else { + // pclog(" GD5429 disable registers\n"); + gd5429->svga.override = 1; + if (mb_vga) + svga_set_override(mb_vga, 0); + } } void ibm_gd5428_mca_write(int port, uint8_t val, void *p) { -// svga_set_override(voodoo->svga, val & 1); - gd5429_t *gd5429 = (gd5429_t *)p; + // svga_set_override(voodoo->svga, val & 1); + gd5429_t *gd5429 = (gd5429_t *)p; -// pclog("gd5429_pro_mcv_write: port=%04x val=%02x\n", port, val); + // pclog("gd5429_pro_mcv_write: port=%04x val=%02x\n", port, val); - if (port < 0x102) - return; - gd5429->pos_regs[port & 7] = val; + if (port < 0x102) + return; + gd5429->pos_regs[port & 7] = val; - if ((port & 7) == 2) { - mem_mapping_disable(&gd5429->bios_rom.mapping); - io_removehandler(0x03c3, 0x0001, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); - if (gd5429->pos_regs[2] & 0x01) { -// pclog("Enable BIOS mapping\n"); - mem_mapping_enable(&gd5429->bios_rom.mapping); - io_sethandler(0x03c3, 0x0001, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); - } -// else -// pclog("Disable BIOS mapping\n"); - } + if ((port & 7) == 2) { + mem_mapping_disable(&gd5429->bios_rom.mapping); + io_removehandler(0x03c3, 0x0001, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); + if (gd5429->pos_regs[2] & 0x01) { + // pclog("Enable BIOS mapping\n"); + mem_mapping_enable(&gd5429->bios_rom.mapping); + io_sethandler(0x03c3, 0x0001, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); + } + // else + // pclog("Disable BIOS mapping\n"); + } - ibm_gd5428_mapping_update(gd5429); + ibm_gd5428_mapping_update(gd5429); } static void ibm_gd5428_mca_reset(void *p) { - gd5429_t *gd5429 = (gd5429_t *)p; + gd5429_t *gd5429 = (gd5429_t *)p; -// pclog("ibm_gd5428_mca_reset\n"); - gd5429->vidsys_ena = 0; - ibm_gd5428_mca_write(0x102, 0, gd5429); + // pclog("ibm_gd5428_mca_reset\n"); + gd5429->vidsys_ena = 0; + ibm_gd5428_mca_write(0x102, 0, gd5429); } static uint8_t cl_pci_read(int func, int addr, void *p) { - gd5429_t *gd5429 = (gd5429_t *)p; + gd5429_t *gd5429 = (gd5429_t *)p; -// pclog("CL PCI read %08X\n", addr); - switch (addr) { - case 0x00:return 0x13; /*Cirrus Logic*/ - case 0x01:return 0x10; + // pclog("CL PCI read %08X\n", addr); + switch (addr) { + case 0x00: + return 0x13; /*Cirrus Logic*/ + case 0x01: + return 0x10; - case 0x02: - switch (gd5429->type) { - case CL_TYPE_GD5430:return 0xa0; - case CL_TYPE_GD5434:return 0xa8; - } - return 0xff; - case 0x03:return 0x00; + case 0x02: + switch (gd5429->type) { + case CL_TYPE_GD5430: + return 0xa0; + case CL_TYPE_GD5434: + return 0xa8; + } + return 0xff; + case 0x03: + return 0x00; - case PCI_REG_COMMAND:return gd5429->pci_regs[PCI_REG_COMMAND]; /*Respond to IO and memory accesses*/ + case PCI_REG_COMMAND: + return gd5429->pci_regs[PCI_REG_COMMAND]; /*Respond to IO and memory accesses*/ - case 0x07:return 0 << 1; /*Fast DEVSEL timing*/ + case 0x07: + return 0 << 1; /*Fast DEVSEL timing*/ - case 0x08:return 0; /*Revision ID*/ - case 0x09:return 0; /*Programming interface*/ + case 0x08: + return 0; /*Revision ID*/ + case 0x09: + return 0; /*Programming interface*/ - case 0x0a:return 0x00; /*Supports VGA interface*/ - case 0x0b:return 0x03; + case 0x0a: + return 0x00; /*Supports VGA interface*/ + case 0x0b: + return 0x03; - case 0x10:return 0x08; /*Linear frame buffer address*/ - case 0x11:return 0x00; - case 0x12:return 0x00; - case 0x13:return gd5429->lfb_base >> 24; + case 0x10: + return 0x08; /*Linear frame buffer address*/ + case 0x11: + return 0x00; + case 0x12: + return 0x00; + case 0x13: + return gd5429->lfb_base >> 24; - case 0x30:return gd5429->pci_regs[0x30] & 0x01; /*BIOS ROM address*/ - case 0x31:return 0x00; - case 0x32:return gd5429->pci_regs[0x32]; - case 0x33:return gd5429->pci_regs[0x33]; + case 0x30: + return gd5429->pci_regs[0x30] & 0x01; /*BIOS ROM address*/ + case 0x31: + return 0x00; + case 0x32: + return gd5429->pci_regs[0x32]; + case 0x33: + return gd5429->pci_regs[0x33]; - case 0x3c:return gd5429->int_line; - case 0x3d:return PCI_INTA; - } - return 0; + case 0x3c: + return gd5429->int_line; + case 0x3d: + return PCI_INTA; + } + return 0; } static void cl_pci_write(int func, int addr, uint8_t val, void *p) { - gd5429_t *gd5429 = (gd5429_t *)p; + gd5429_t *gd5429 = (gd5429_t *)p; -// pclog("cl_pci_write: addr=%02x val=%02x\n", addr, val); - switch (addr) { - case PCI_REG_COMMAND:gd5429->pci_regs[PCI_REG_COMMAND] = val & 0x23; - io_removehandler(0x03c0, 0x0020, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); - if (val & PCI_COMMAND_IO) - io_sethandler(0x03c0, 0x0020, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); - gd5429_recalc_mapping(gd5429); - break; + // pclog("cl_pci_write: addr=%02x val=%02x\n", addr, val); + switch (addr) { + case PCI_REG_COMMAND: + gd5429->pci_regs[PCI_REG_COMMAND] = val & 0x23; + io_removehandler(0x03c0, 0x0020, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); + if (val & PCI_COMMAND_IO) + io_sethandler(0x03c0, 0x0020, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); + gd5429_recalc_mapping(gd5429); + break; - case 0x13:gd5429->lfb_base = val << 24; - gd5429_recalc_mapping(gd5429); - break; + case 0x13: + gd5429->lfb_base = val << 24; + gd5429_recalc_mapping(gd5429); + break; - case 0x30: - case 0x32: - case 0x33:gd5429->pci_regs[addr] = val; - if (gd5429->pci_regs[0x30] & 0x01) { - uint32_t addr = (gd5429->pci_regs[0x32] << 16) | (gd5429->pci_regs[0x33] << 24); - mem_mapping_set_addr(&gd5429->bios_rom.mapping, addr, 0x8000); - } else - mem_mapping_disable(&gd5429->bios_rom.mapping); - return; + case 0x30: + case 0x32: + case 0x33: + gd5429->pci_regs[addr] = val; + if (gd5429->pci_regs[0x30] & 0x01) { + uint32_t addr = (gd5429->pci_regs[0x32] << 16) | (gd5429->pci_regs[0x33] << 24); + mem_mapping_set_addr(&gd5429->bios_rom.mapping, addr, 0x8000); + } else + mem_mapping_disable(&gd5429->bios_rom.mapping); + return; - case 0x3c:gd5429->int_line = val; - return; - } + case 0x3c: + gd5429->int_line = val; + return; + } } static void *cl_init(int type, char *fn, int pci_card, uint32_t force_vram_size) { - gd5429_t *gd5429 = malloc(sizeof(gd5429_t)); - svga_t *svga = &gd5429->svga; - int vram_size; - memset(gd5429, 0, sizeof(gd5429_t)); + gd5429_t *gd5429 = malloc(sizeof(gd5429_t)); + svga_t *svga = &gd5429->svga; + int vram_size; + memset(gd5429, 0, sizeof(gd5429_t)); - if (force_vram_size) - vram_size = force_vram_size; - else - vram_size = device_get_config_int("memory"); - if (vram_size >= 256) - gd5429->vram_mask = (vram_size << 10) - 1; - else - gd5429->vram_mask = (vram_size << 20) - 1; + if (force_vram_size) + vram_size = force_vram_size; + else + vram_size = device_get_config_int("memory"); + if (vram_size >= 256) + gd5429->vram_mask = (vram_size << 10) - 1; + else + gd5429->vram_mask = (vram_size << 20) - 1; - gd5429->type = type; + gd5429->type = type; - if (fn) - rom_init(&gd5429->bios_rom, fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + if (fn) + rom_init(&gd5429->bios_rom, fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - svga_init(&gd5429->svga, gd5429, (vram_size >= 256) ? (vram_size << 10) : (vram_size << 20), - gd5429_recalctimings, - gd5429_in, gd5429_out, - gd5429_hwcursor_draw, - NULL); + svga_init(&gd5429->svga, gd5429, (vram_size >= 256) ? (vram_size << 10) : (vram_size << 20), gd5429_recalctimings, + gd5429_in, gd5429_out, gd5429_hwcursor_draw, NULL); - mem_mapping_set_handler(&gd5429->svga.mapping, gd5429_read, gd5429_readw, gd5429_readl, gd5429_write, gd5429_writew, gd5429_writel); - mem_mapping_set_p(&gd5429->svga.mapping, gd5429); + mem_mapping_set_handler(&gd5429->svga.mapping, gd5429_read, gd5429_readw, gd5429_readl, gd5429_write, gd5429_writew, + gd5429_writel); + mem_mapping_set_p(&gd5429->svga.mapping, gd5429); - mem_mapping_add(&gd5429->mmio_mapping, 0, 0, gd5429_mmio_read, gd5429_mmio_readw, gd5429_mmio_readl, gd5429_mmio_write, gd5429_mmio_writew, gd5429_mmio_writel, NULL, 0, gd5429); - mem_mapping_add(&gd5429->linear_mapping, - 0, - 0, - gd5429_readb_linear, - gd5429_readw_linear, - gd5429_readl_linear, - gd5429_writeb_linear, - gd5429_writew_linear, - gd5429_writel_linear, - NULL, - 0, - gd5429); + mem_mapping_add(&gd5429->mmio_mapping, 0, 0, gd5429_mmio_read, gd5429_mmio_readw, gd5429_mmio_readl, gd5429_mmio_write, + gd5429_mmio_writew, gd5429_mmio_writel, NULL, 0, gd5429); + mem_mapping_add(&gd5429->linear_mapping, 0, 0, gd5429_readb_linear, gd5429_readw_linear, gd5429_readl_linear, + gd5429_writeb_linear, gd5429_writew_linear, gd5429_writel_linear, NULL, 0, gd5429); - io_sethandler(0x03c0, 0x0020, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); - if (type == CL_TYPE_AVGA2) { - io_sethandler(0x0102, 0x0001, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); - io_sethandler(0x46e8, 0x0002, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); - svga->decode_mask = svga->vram_mask; - } + io_sethandler(0x03c0, 0x0020, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); + if (type == CL_TYPE_AVGA2) { + io_sethandler(0x0102, 0x0001, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); + io_sethandler(0x46e8, 0x0002, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); + svga->decode_mask = svga->vram_mask; + } - svga->hwcursor.yoff = 32; - svga->hwcursor.xoff = 0; + svga->hwcursor.yoff = 32; + svga->hwcursor.xoff = 0; - gd5429->bank[1] = 0x8000; + gd5429->bank[1] = 0x8000; - /*Default VCLK values*/ - svga->seqregs[0xb] = 0x66; - svga->seqregs[0xc] = 0x5b; - svga->seqregs[0xd] = 0x45; - svga->seqregs[0xe] = 0x7e; - svga->seqregs[0x1b] = 0x3b; - svga->seqregs[0x1c] = 0x2f; - svga->seqregs[0x1d] = 0x30; - svga->seqregs[0x1e] = 0x33; + /*Default VCLK values*/ + svga->seqregs[0xb] = 0x66; + svga->seqregs[0xc] = 0x5b; + svga->seqregs[0xd] = 0x45; + svga->seqregs[0xe] = 0x7e; + svga->seqregs[0x1b] = 0x3b; + svga->seqregs[0x1c] = 0x2f; + svga->seqregs[0x1d] = 0x30; + svga->seqregs[0x1e] = 0x33; - if (PCI && type >= CL_TYPE_GD5430) { - if (pci_card != -1) { - pci_add_specific(pci_card, cl_pci_read, cl_pci_write, gd5429); - gd5429->card = pci_card; - } else - gd5429->card = pci_add(cl_pci_read, cl_pci_write, gd5429); + if (PCI && type >= CL_TYPE_GD5430) { + if (pci_card != -1) { + pci_add_specific(pci_card, cl_pci_read, cl_pci_write, gd5429); + gd5429->card = pci_card; + } else + gd5429->card = pci_add(cl_pci_read, cl_pci_write, gd5429); - gd5429->pci_regs[0x04] = 7; + gd5429->pci_regs[0x04] = 7; - gd5429->pci_regs[0x30] = 0x00; - gd5429->pci_regs[0x32] = 0x0c; - gd5429->pci_regs[0x33] = 0x00; - } + gd5429->pci_regs[0x30] = 0x00; + gd5429->pci_regs[0x32] = 0x0c; + gd5429->pci_regs[0x33] = 0x00; + } - return gd5429; + return gd5429; } -static void *avga2_init() { - return cl_init(CL_TYPE_AVGA2, "avga2vram.vbi", -1, 0); -} -static void *avga2_cbm_sl386sx_init() { - return cl_init(CL_TYPE_AVGA2, "cbm_sl386sx25/c000.rom", -1, 0); -} -static void *gd5426_ps1_init() { - return cl_init(CL_TYPE_GD5426, NULL, -1, 1); -} -static void *gd5428_init() { - return cl_init(CL_TYPE_GD5428, "Machspeed_VGA_GUI_2100_VLB.vbi", -1, 0); -} +static void *avga2_init() { return cl_init(CL_TYPE_AVGA2, "avga2vram.vbi", -1, 0); } +static void *avga2_cbm_sl386sx_init() { return cl_init(CL_TYPE_AVGA2, "cbm_sl386sx25/c000.rom", -1, 0); } +static void *gd5426_ps1_init() { return cl_init(CL_TYPE_GD5426, NULL, -1, 1); } +static void *gd5428_init() { return cl_init(CL_TYPE_GD5428, "Machspeed_VGA_GUI_2100_VLB.vbi", -1, 0); } static void *ibm_gd5428_init() { - gd5429_t *gd5429; - svga_t *mb_vga = svga_get_pri(); + gd5429_t *gd5429; + svga_t *mb_vga = svga_get_pri(); - gd5429 = cl_init(CL_TYPE_GD5428, "SVGA141.ROM", -1, 1); /*Only supports 1MB*/ - gd5429->mb_vga = mb_vga; + gd5429 = cl_init(CL_TYPE_GD5428, "SVGA141.ROM", -1, 1); /*Only supports 1MB*/ + gd5429->mb_vga = mb_vga; - mca_add(ibm_gd5428_mca_read, ibm_gd5428_mca_write, ibm_gd5428_mca_reset, gd5429); - gd5429->pos_regs[0] = 0x7b; - gd5429->pos_regs[1] = 0x91; - gd5429->pos_regs[2] = 0; + mca_add(ibm_gd5428_mca_read, ibm_gd5428_mca_write, ibm_gd5428_mca_reset, gd5429); + gd5429->pos_regs[0] = 0x7b; + gd5429->pos_regs[1] = 0x91; + gd5429->pos_regs[2] = 0; - gd5429_recalc_mapping(gd5429); - io_removehandler(0x03a0, 0x0040, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); - gd5429->svga.override = 1; - mem_mapping_disable(&gd5429->bios_rom.mapping); - io_sethandler(0x46e8, 0x0001, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); + gd5429_recalc_mapping(gd5429); + io_removehandler(0x03a0, 0x0040, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); + gd5429->svga.override = 1; + mem_mapping_disable(&gd5429->bios_rom.mapping); + io_sethandler(0x46e8, 0x0001, gd5429_in, NULL, NULL, gd5429_out, NULL, NULL, gd5429); - return gd5429; -} -static void *gd5429_init() { - return cl_init(CL_TYPE_GD5429, "5429.vbi", -1, 0); -} -static void *gd5430_init() { - return cl_init(CL_TYPE_GD5430, "gd5430/pci.bin", -1, 0); -} -static void *gd5430_pb570_init() { - return cl_init(CL_TYPE_GD5430, "pb570/gd5430.bin", 8, 0); -} -static void *gd5434_init() { - return cl_init(CL_TYPE_GD5434, "gd5434.bin", -1, 0); -} -static void *gd5434_pb520r_init() { - return cl_init(CL_TYPE_GD5434, "pb520r/gd5434.bin", 3, 0); + return gd5429; } +static void *gd5429_init() { return cl_init(CL_TYPE_GD5429, "5429.vbi", -1, 0); } +static void *gd5430_init() { return cl_init(CL_TYPE_GD5430, "gd5430/pci.bin", -1, 0); } +static void *gd5430_pb570_init() { return cl_init(CL_TYPE_GD5430, "pb570/gd5430.bin", 8, 0); } +static void *gd5434_init() { return cl_init(CL_TYPE_GD5434, "gd5434.bin", -1, 0); } +static void *gd5434_pb520r_init() { return cl_init(CL_TYPE_GD5434, "pb520r/gd5434.bin", 3, 0); } -static int avga2_available() { - return rom_present("avga2vram.vbi"); -} -static int gd5428_available() { - return rom_present("Machspeed_VGA_GUI_2100_VLB.vbi"); -} -static int ibm_gd5428_available() { - return rom_present(/*"FILE.ROM"*/"SVGA141.ROM"); -} -static int gd5429_available() { - return rom_present("5429.vbi"); -} -static int gd5430_available() { - return rom_present("gd5430/pci.bin"); -} -static int gd5434_available() { - return rom_present("gd5434.bin"); -} +static int avga2_available() { return rom_present("avga2vram.vbi"); } +static int gd5428_available() { return rom_present("Machspeed_VGA_GUI_2100_VLB.vbi"); } +static int ibm_gd5428_available() { return rom_present(/*"FILE.ROM"*/ "SVGA141.ROM"); } +static int gd5429_available() { return rom_present("5429.vbi"); } +static int gd5430_available() { return rom_present("gd5430/pci.bin"); } +static int gd5434_available() { return rom_present("gd5434.bin"); } void gd5429_close(void *p) { - gd5429_t *gd5429 = (gd5429_t *)p; + gd5429_t *gd5429 = (gd5429_t *)p; - svga_close(&gd5429->svga); + svga_close(&gd5429->svga); - free(gd5429); + free(gd5429); } void gd5429_speed_changed(void *p) { - gd5429_t *gd5429 = (gd5429_t *)p; + gd5429_t *gd5429 = (gd5429_t *)p; - svga_recalctimings(&gd5429->svga); + svga_recalctimings(&gd5429->svga); } void gd5429_force_redraw(void *p) { - gd5429_t *gd5429 = (gd5429_t *)p; + gd5429_t *gd5429 = (gd5429_t *)p; - gd5429->svga.fullchange = changeframecount; + gd5429->svga.fullchange = changeframecount; } void gd5429_add_status_info(char *s, int max_len, void *p) { - gd5429_t *gd5429 = (gd5429_t *)p; + gd5429_t *gd5429 = (gd5429_t *)p; - svga_add_status_info(s, max_len, &gd5429->svga); + svga_add_status_info(s, max_len, &gd5429->svga); } -static device_config_t avga2_config[] = - { - { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "256 kB", - .value = 256 - }, - { - .description = "512 kB", - .value = 512 - }, - { - .description = "" - } - }, - .default_int = 512 - }, - { - .type = -1 - } - }; +static device_config_t avga2_config[] = { + {.name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .selection = {{.description = "256 kB", .value = 256}, {.description = "512 kB", .value = 512}, {.description = ""}}, + .default_int = 512}, + {.type = -1}}; -static device_config_t gd5429_config[] = - { - { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "1 MB", - .value = 1 - }, - { - .description = "2 MB", - .value = 2 - }, - { - .description = "" - } - }, - .default_int = 2 - }, - { - .type = -1 - } - }; -static device_config_t gd5434_config[] = - { - { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "2 MB", - .value = 2 - }, - { - .description = "4 MB", - .value = 4 - }, - { - .description = "" - } - }, - .default_int = 4 - }, - { - .type = -1 - } - }; +static device_config_t gd5429_config[] = { + {.name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .selection = {{.description = "1 MB", .value = 1}, {.description = "2 MB", .value = 2}, {.description = ""}}, + .default_int = 2}, + {.type = -1}}; +static device_config_t gd5434_config[] = { + {.name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .selection = {{.description = "2 MB", .value = 2}, {.description = "4 MB", .value = 4}, {.description = ""}}, + .default_int = 4}, + {.type = -1}}; -device_t avga2_device = - { - "AVGA2 / Cirrus Logic GD5402", - 0, - avga2_init, - gd5429_close, - avga2_available, - gd5429_speed_changed, - gd5429_force_redraw, - gd5429_add_status_info, - avga2_config - }; +device_t avga2_device = {"AVGA2 / Cirrus Logic GD5402", + 0, + avga2_init, + gd5429_close, + avga2_available, + gd5429_speed_changed, + gd5429_force_redraw, + gd5429_add_status_info, + avga2_config}; -device_t avga2_cbm_sl386sx_device = - { - "AVGA2 (Commodore SL386SX-25)", - 0, - avga2_cbm_sl386sx_init, - gd5429_close, - gd5430_available, - gd5429_speed_changed, - gd5429_force_redraw, - gd5429_add_status_info, - avga2_config - }; +device_t avga2_cbm_sl386sx_device = {"AVGA2 (Commodore SL386SX-25)", + 0, + avga2_cbm_sl386sx_init, + gd5429_close, + gd5430_available, + gd5429_speed_changed, + gd5429_force_redraw, + gd5429_add_status_info, + avga2_config}; -device_t gd5426_ps1_device = - { - "Cirrus Logic GD5426 (IBM PS/1)", - 0, - gd5426_ps1_init, - gd5429_close, - NULL, - gd5429_speed_changed, - gd5429_force_redraw, - gd5429_add_status_info, - NULL - }; +device_t gd5426_ps1_device = { + "Cirrus Logic GD5426 (IBM PS/1)", 0, gd5426_ps1_init, gd5429_close, NULL, gd5429_speed_changed, gd5429_force_redraw, + gd5429_add_status_info, NULL}; -device_t gd5428_device = - { - "Cirrus Logic GD5428", - 0, - gd5428_init, - gd5429_close, - gd5428_available, - gd5429_speed_changed, - gd5429_force_redraw, - gd5429_add_status_info, - gd5429_config - }; +device_t gd5428_device = {"Cirrus Logic GD5428", 0, + gd5428_init, gd5429_close, + gd5428_available, gd5429_speed_changed, + gd5429_force_redraw, gd5429_add_status_info, + gd5429_config}; -device_t ibm_gd5428_device = - { - "IBM 1MB SVGA Adapter/A (Cirrus Logic GD5428)", - DEVICE_MCA, - ibm_gd5428_init, - gd5429_close, - ibm_gd5428_available, - gd5429_speed_changed, - gd5429_force_redraw, - gd5429_add_status_info, - NULL - }; +device_t ibm_gd5428_device = {"IBM 1MB SVGA Adapter/A (Cirrus Logic GD5428)", + DEVICE_MCA, + ibm_gd5428_init, + gd5429_close, + ibm_gd5428_available, + gd5429_speed_changed, + gd5429_force_redraw, + gd5429_add_status_info, + NULL}; -device_t gd5429_device = - { - "Cirrus Logic GD5429", - 0, - gd5429_init, - gd5429_close, - gd5429_available, - gd5429_speed_changed, - gd5429_force_redraw, - gd5429_add_status_info, - gd5429_config - }; +device_t gd5429_device = {"Cirrus Logic GD5429", 0, + gd5429_init, gd5429_close, + gd5429_available, gd5429_speed_changed, + gd5429_force_redraw, gd5429_add_status_info, + gd5429_config}; -device_t gd5430_device = - { - "Cirrus Logic GD5430", - 0, - gd5430_init, - gd5429_close, - gd5430_available, - gd5429_speed_changed, - gd5429_force_redraw, - gd5429_add_status_info, - gd5429_config - }; +device_t gd5430_device = {"Cirrus Logic GD5430", 0, + gd5430_init, gd5429_close, + gd5430_available, gd5429_speed_changed, + gd5429_force_redraw, gd5429_add_status_info, + gd5429_config}; -device_t gd5430_pb570_device = - { - "Cirrus Logic GD5430 (PB570)", - 0, - gd5430_pb570_init, - gd5429_close, - gd5430_available, - gd5429_speed_changed, - gd5429_force_redraw, - gd5429_add_status_info, - gd5429_config - }; +device_t gd5430_pb570_device = {"Cirrus Logic GD5430 (PB570)", + 0, + gd5430_pb570_init, + gd5429_close, + gd5430_available, + gd5429_speed_changed, + gd5429_force_redraw, + gd5429_add_status_info, + gd5429_config}; -device_t gd5434_device = - { - "Cirrus Logic GD5434", - 0, - gd5434_init, - gd5429_close, - gd5434_available, - gd5429_speed_changed, - gd5429_force_redraw, - gd5429_add_status_info, - gd5434_config - }; +device_t gd5434_device = {"Cirrus Logic GD5434", 0, + gd5434_init, gd5429_close, + gd5434_available, gd5429_speed_changed, + gd5429_force_redraw, gd5429_add_status_info, + gd5434_config}; -device_t gd5434_pb520r_device = - { - "Cirrus Logic GD5434 (PB520r)", - 0, - gd5434_pb520r_init, - gd5429_close, - gd5434_available, - gd5429_speed_changed, - gd5429_force_redraw, - gd5429_add_status_info, - gd5434_config - }; +device_t gd5434_pb520r_device = {"Cirrus Logic GD5434 (PB520r)", + 0, + gd5434_pb520r_init, + gd5429_close, + gd5434_available, + gd5429_speed_changed, + gd5429_force_redraw, + gd5429_add_status_info, + gd5434_config}; diff --git a/src/video/vid_colorplus.c b/src/video/vid_colorplus.c index 8c892b1c..e43fbd3a 100644 --- a/src/video/vid_colorplus.c +++ b/src/video/vid_colorplus.c @@ -11,370 +11,337 @@ #include "vid_colorplus.h" typedef struct colorplus_t { - cga_t cga; - uint8_t control; + cga_t cga; + uint8_t control; } colorplus_t; /* Bits in the colorplus control register: */ -#define COLORPLUS_PLANE_SWAP 0x40 /* Swap planes at 0000h and 4000h */ -#define COLORPLUS_640x200_MODE 0x20 /* 640x200x4 mode active */ -#define COLORPLUS_320x200_MODE 0x10 /* 320x200x16 mode active */ -#define COLORPLUS_EITHER_MODE 0x30 /* Either mode active */ +#define COLORPLUS_PLANE_SWAP 0x40 /* Swap planes at 0000h and 4000h */ +#define COLORPLUS_640x200_MODE 0x20 /* 640x200x4 mode active */ +#define COLORPLUS_320x200_MODE 0x10 /* 320x200x16 mode active */ +#define COLORPLUS_EITHER_MODE 0x30 /* Either mode active */ /* Bits in the CGA graphics mode register */ -#define CGA_GRAPHICS_MODE 0x02 /* CGA graphics mode selected? */ +#define CGA_GRAPHICS_MODE 0x02 /* CGA graphics mode selected? */ void colorplus_out(uint16_t addr, uint8_t val, void *p) { - colorplus_t *colorplus = (colorplus_t *)p; + colorplus_t *colorplus = (colorplus_t *)p; -// pclog("COLORPLUS_OUT %04X %02X\n", addr, val); - if (addr == 0x3DD) { - colorplus->control = val & 0x70; - } else { - cga_out(addr, val, &colorplus->cga); - } + // pclog("COLORPLUS_OUT %04X %02X\n", addr, val); + if (addr == 0x3DD) { + colorplus->control = val & 0x70; + } else { + cga_out(addr, val, &colorplus->cga); + } } uint8_t colorplus_in(uint16_t addr, void *p) { - colorplus_t *colorplus = (colorplus_t *)p; + colorplus_t *colorplus = (colorplus_t *)p; - return cga_in(addr, &colorplus->cga); + return cga_in(addr, &colorplus->cga); } void colorplus_write(uint32_t addr, uint8_t val, void *p) { - colorplus_t *colorplus = (colorplus_t *)p; + colorplus_t *colorplus = (colorplus_t *)p; -// pclog("COLORPLUS_WRITE %04X %02X\n", addr, val); - if ((colorplus->control & COLORPLUS_PLANE_SWAP) && - (colorplus->control & COLORPLUS_EITHER_MODE) && - (colorplus->cga.cgamode & CGA_GRAPHICS_MODE)) { - addr ^= 0x4000; - } else if (!(colorplus->control & COLORPLUS_EITHER_MODE)) { - addr &= 0x3FFF; - } - colorplus->cga.vram[addr & 0x7fff] = val; - egawrites++; - cycles -= 4; + // pclog("COLORPLUS_WRITE %04X %02X\n", addr, val); + if ((colorplus->control & COLORPLUS_PLANE_SWAP) && (colorplus->control & COLORPLUS_EITHER_MODE) && + (colorplus->cga.cgamode & CGA_GRAPHICS_MODE)) { + addr ^= 0x4000; + } else if (!(colorplus->control & COLORPLUS_EITHER_MODE)) { + addr &= 0x3FFF; + } + colorplus->cga.vram[addr & 0x7fff] = val; + egawrites++; + cycles -= 4; } uint8_t colorplus_read(uint32_t addr, void *p) { - colorplus_t *colorplus = (colorplus_t *)p; + colorplus_t *colorplus = (colorplus_t *)p; - if ((colorplus->control & COLORPLUS_PLANE_SWAP) && - (colorplus->control & COLORPLUS_EITHER_MODE) && - (colorplus->cga.cgamode & CGA_GRAPHICS_MODE)) { - addr ^= 0x4000; - } else if (!(colorplus->control & COLORPLUS_EITHER_MODE)) { - addr &= 0x3FFF; - } - cycles -= 4; - egareads++; -// pclog("COLORPLUS_READ %04X\n", addr); - return colorplus->cga.vram[addr & 0x7fff]; + if ((colorplus->control & COLORPLUS_PLANE_SWAP) && (colorplus->control & COLORPLUS_EITHER_MODE) && + (colorplus->cga.cgamode & CGA_GRAPHICS_MODE)) { + addr ^= 0x4000; + } else if (!(colorplus->control & COLORPLUS_EITHER_MODE)) { + addr &= 0x3FFF; + } + cycles -= 4; + egareads++; + // pclog("COLORPLUS_READ %04X\n", addr); + return colorplus->cga.vram[addr & 0x7fff]; } -void colorplus_recalctimings(colorplus_t *colorplus) { - cga_recalctimings(&colorplus->cga); -} +void colorplus_recalctimings(colorplus_t *colorplus) { cga_recalctimings(&colorplus->cga); } void colorplus_poll(void *p) { - colorplus_t *colorplus = (colorplus_t *)p; - int x, c; - int oldvc; - uint16_t dat0, dat1; - int cols[4]; - int col; - int oldsc; - static const int cols16[16] = {0x0, 0x2, 0x4, 0x6, - 0x8, 0xA, 0xC, 0xE, - 0x1, 0x3, 0x5, 0x7, - 0x9, 0xB, 0xD, 0xF}; - uint8_t *plane0 = colorplus->cga.vram; - uint8_t *plane1 = colorplus->cga.vram + 0x4000; + colorplus_t *colorplus = (colorplus_t *)p; + int x, c; + int oldvc; + uint16_t dat0, dat1; + int cols[4]; + int col; + int oldsc; + static const int cols16[16] = {0x0, 0x2, 0x4, 0x6, 0x8, 0xA, 0xC, 0xE, 0x1, 0x3, 0x5, 0x7, 0x9, 0xB, 0xD, 0xF}; + uint8_t *plane0 = colorplus->cga.vram; + uint8_t *plane1 = colorplus->cga.vram + 0x4000; - /* If one of the extra modes is not selected, drop down to the CGA - * drawing code. */ - if (!((colorplus->control & COLORPLUS_EITHER_MODE) && - (colorplus->cga.cgamode & CGA_GRAPHICS_MODE))) { - cga_poll(&colorplus->cga); - return; - } + /* If one of the extra modes is not selected, drop down to the CGA + * drawing code. */ + if (!((colorplus->control & COLORPLUS_EITHER_MODE) && (colorplus->cga.cgamode & CGA_GRAPHICS_MODE))) { + cga_poll(&colorplus->cga); + return; + } - if (!colorplus->cga.linepos) { - timer_advance_u64(&colorplus->cga.timer, colorplus->cga.dispofftime); - colorplus->cga.cgastat |= 1; - colorplus->cga.linepos = 1; - oldsc = colorplus->cga.sc; - if ((colorplus->cga.crtc[8] & 3) == 3) - colorplus->cga.sc = ((colorplus->cga.sc << 1) + colorplus->cga.oddeven) & 7; - if (colorplus->cga.cgadispon) { - if (colorplus->cga.displine < colorplus->cga.firstline) { - colorplus->cga.firstline = colorplus->cga.displine; - video_wait_for_buffer(); -// printf("Firstline %i\n",firstline); - } - colorplus->cga.lastline = colorplus->cga.displine; - /* Left / right border */ - for (c = 0; c < 8; c++) { - ((uint32_t *)buffer32->line[colorplus->cga.displine])[c] = - ((uint32_t *)buffer32->line[colorplus->cga.displine])[c + (colorplus->cga.crtc[1] << 4) + 8] = cgapal[colorplus->cga.cgacol & 15]; - } - if (colorplus->control & COLORPLUS_320x200_MODE) { - for (x = 0; x < colorplus->cga.crtc[1]; x++) { - dat0 = (plane0[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000)] << 8) | - plane0[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000) + 1]; - dat1 = (plane1[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000)] << 8) | - plane1[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000) + 1]; - colorplus->cga.ma++; - for (c = 0; c < 8; c++) { - ((uint32_t *)buffer32->line[colorplus->cga.displine])[(x << 4) + (c << 1) + 8] = - ((uint32_t *)buffer32->line[colorplus->cga.displine])[(x << 4) + (c << 1) + 1 + 8] = - cgapal[cols16[(dat0 >> 14) | ((dat1 >> 14) << 2)]]; - dat0 <<= 2; - dat1 <<= 2; - } - } - } else if (colorplus->control & COLORPLUS_640x200_MODE) { - cols[0] = cgapal[colorplus->cga.cgacol & 15]; - col = (colorplus->cga.cgacol & 16) ? 8 : 0; - if (colorplus->cga.cgamode & 4) { - cols[1] = cgapal[col | 3]; - cols[2] = cgapal[col | 4]; - cols[3] = cgapal[col | 7]; - } else if (colorplus->cga.cgacol & 32) { - cols[1] = cgapal[col | 3]; - cols[2] = cgapal[col | 5]; - cols[3] = cgapal[col | 7]; - } else { - cols[1] = cgapal[col | 2]; - cols[2] = cgapal[col | 4]; - cols[3] = cgapal[col | 6]; - } - for (x = 0; x < colorplus->cga.crtc[1]; x++) { - dat0 = (plane0[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000)] << 8) | - plane0[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000) + 1]; - dat1 = (plane1[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000)] << 8) | - plane1[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000) + 1]; - colorplus->cga.ma++; - for (c = 0; c < 16; c++) { - ((uint32_t *)buffer32->line[colorplus->cga.displine])[(x << 4) + c + 8] = - cols[(dat0 >> 15) | ((dat1 >> 15) << 1)]; - dat0 <<= 1; - dat1 <<= 1; - } - } - } - } else /* Top / bottom border */ - { - cols[0] = cgapal[colorplus->cga.cgacol & 15]; - hline(buffer32, 0, colorplus->cga.displine, (colorplus->cga.crtc[1] << 4) + 16, cols[0]); - } + if (!colorplus->cga.linepos) { + timer_advance_u64(&colorplus->cga.timer, colorplus->cga.dispofftime); + colorplus->cga.cgastat |= 1; + colorplus->cga.linepos = 1; + oldsc = colorplus->cga.sc; + if ((colorplus->cga.crtc[8] & 3) == 3) + colorplus->cga.sc = ((colorplus->cga.sc << 1) + colorplus->cga.oddeven) & 7; + if (colorplus->cga.cgadispon) { + if (colorplus->cga.displine < colorplus->cga.firstline) { + colorplus->cga.firstline = colorplus->cga.displine; + video_wait_for_buffer(); + // printf("Firstline %i\n",firstline); + } + colorplus->cga.lastline = colorplus->cga.displine; + /* Left / right border */ + for (c = 0; c < 8; c++) { + ((uint32_t *)buffer32->line[colorplus->cga.displine])[c] = + ((uint32_t *) + buffer32->line[colorplus->cga.displine])[c + (colorplus->cga.crtc[1] << 4) + 8] = + cgapal[colorplus->cga.cgacol & 15]; + } + if (colorplus->control & COLORPLUS_320x200_MODE) { + for (x = 0; x < colorplus->cga.crtc[1]; x++) { + dat0 = (plane0[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000)] + << 8) | + plane0[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000) + + 1]; + dat1 = (plane1[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000)] + << 8) | + plane1[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000) + + 1]; + colorplus->cga.ma++; + for (c = 0; c < 8; c++) { + ((uint32_t *)buffer32->line[colorplus->cga.displine])[(x << 4) + (c << 1) + 8] = + ((uint32_t *)buffer32 + ->line[colorplus->cga.displine])[(x << 4) + (c << 1) + 1 + 8] = + cgapal[cols16[(dat0 >> 14) | ((dat1 >> 14) << 2)]]; + dat0 <<= 2; + dat1 <<= 2; + } + } + } else if (colorplus->control & COLORPLUS_640x200_MODE) { + cols[0] = cgapal[colorplus->cga.cgacol & 15]; + col = (colorplus->cga.cgacol & 16) ? 8 : 0; + if (colorplus->cga.cgamode & 4) { + cols[1] = cgapal[col | 3]; + cols[2] = cgapal[col | 4]; + cols[3] = cgapal[col | 7]; + } else if (colorplus->cga.cgacol & 32) { + cols[1] = cgapal[col | 3]; + cols[2] = cgapal[col | 5]; + cols[3] = cgapal[col | 7]; + } else { + cols[1] = cgapal[col | 2]; + cols[2] = cgapal[col | 4]; + cols[3] = cgapal[col | 6]; + } + for (x = 0; x < colorplus->cga.crtc[1]; x++) { + dat0 = (plane0[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000)] + << 8) | + plane0[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000) + + 1]; + dat1 = (plane1[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000)] + << 8) | + plane1[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000) + + 1]; + colorplus->cga.ma++; + for (c = 0; c < 16; c++) { + ((uint32_t *)buffer32->line[colorplus->cga.displine])[(x << 4) + c + 8] = + cols[(dat0 >> 15) | ((dat1 >> 15) << 1)]; + dat0 <<= 1; + dat1 <<= 1; + } + } + } + } else /* Top / bottom border */ + { + cols[0] = cgapal[colorplus->cga.cgacol & 15]; + hline(buffer32, 0, colorplus->cga.displine, (colorplus->cga.crtc[1] << 4) + 16, cols[0]); + } - x = (colorplus->cga.crtc[1] << 4) + 16; + x = (colorplus->cga.crtc[1] << 4) + 16; - colorplus->cga.sc = oldsc; - if (colorplus->cga.vc == colorplus->cga.crtc[7] && !colorplus->cga.sc) - colorplus->cga.cgastat |= 8; - colorplus->cga.displine++; - if (colorplus->cga.displine >= 360) - colorplus->cga.displine = 0; - } else { - timer_advance_u64(&colorplus->cga.timer, colorplus->cga.dispontime); - colorplus->cga.linepos = 0; - if (colorplus->cga.vsynctime) { - colorplus->cga.vsynctime--; - if (!colorplus->cga.vsynctime) - colorplus->cga.cgastat &= ~8; - } - if (colorplus->cga.sc == (colorplus->cga.crtc[11] & 31) || ((colorplus->cga.crtc[8] & 3) == 3 && colorplus->cga.sc == ((colorplus->cga.crtc[11] & 31) >> 1))) { - colorplus->cga.con = 0; - colorplus->cga.coff = 1; - } - if ((colorplus->cga.crtc[8] & 3) == 3 && colorplus->cga.sc == (colorplus->cga.crtc[9] >> 1)) - colorplus->cga.maback = colorplus->cga.ma; - if (colorplus->cga.vadj) { - colorplus->cga.sc++; - colorplus->cga.sc &= 31; - colorplus->cga.ma = colorplus->cga.maback; - colorplus->cga.vadj--; - if (!colorplus->cga.vadj) { - colorplus->cga.cgadispon = 1; - colorplus->cga.ma = colorplus->cga.maback = (colorplus->cga.crtc[13] | (colorplus->cga.crtc[12] << 8)) & 0x3fff; - colorplus->cga.sc = 0; - } - } else if (colorplus->cga.sc == colorplus->cga.crtc[9]) { - colorplus->cga.maback = colorplus->cga.ma; - colorplus->cga.sc = 0; - oldvc = colorplus->cga.vc; - colorplus->cga.vc++; - colorplus->cga.vc &= 127; + colorplus->cga.sc = oldsc; + if (colorplus->cga.vc == colorplus->cga.crtc[7] && !colorplus->cga.sc) + colorplus->cga.cgastat |= 8; + colorplus->cga.displine++; + if (colorplus->cga.displine >= 360) + colorplus->cga.displine = 0; + } else { + timer_advance_u64(&colorplus->cga.timer, colorplus->cga.dispontime); + colorplus->cga.linepos = 0; + if (colorplus->cga.vsynctime) { + colorplus->cga.vsynctime--; + if (!colorplus->cga.vsynctime) + colorplus->cga.cgastat &= ~8; + } + if (colorplus->cga.sc == (colorplus->cga.crtc[11] & 31) || + ((colorplus->cga.crtc[8] & 3) == 3 && colorplus->cga.sc == ((colorplus->cga.crtc[11] & 31) >> 1))) { + colorplus->cga.con = 0; + colorplus->cga.coff = 1; + } + if ((colorplus->cga.crtc[8] & 3) == 3 && colorplus->cga.sc == (colorplus->cga.crtc[9] >> 1)) + colorplus->cga.maback = colorplus->cga.ma; + if (colorplus->cga.vadj) { + colorplus->cga.sc++; + colorplus->cga.sc &= 31; + colorplus->cga.ma = colorplus->cga.maback; + colorplus->cga.vadj--; + if (!colorplus->cga.vadj) { + colorplus->cga.cgadispon = 1; + colorplus->cga.ma = colorplus->cga.maback = + (colorplus->cga.crtc[13] | (colorplus->cga.crtc[12] << 8)) & 0x3fff; + colorplus->cga.sc = 0; + } + } else if (colorplus->cga.sc == colorplus->cga.crtc[9]) { + colorplus->cga.maback = colorplus->cga.ma; + colorplus->cga.sc = 0; + oldvc = colorplus->cga.vc; + colorplus->cga.vc++; + colorplus->cga.vc &= 127; - if (colorplus->cga.vc == colorplus->cga.crtc[6]) - colorplus->cga.cgadispon = 0; + if (colorplus->cga.vc == colorplus->cga.crtc[6]) + colorplus->cga.cgadispon = 0; - if (oldvc == colorplus->cga.crtc[4]) { - colorplus->cga.vc = 0; - colorplus->cga.vadj = colorplus->cga.crtc[5]; - if (!colorplus->cga.vadj) - colorplus->cga.cgadispon = 1; - if (!colorplus->cga.vadj) - colorplus->cga.ma = colorplus->cga.maback = (colorplus->cga.crtc[13] | (colorplus->cga.crtc[12] << 8)) & 0x3fff; - if ((colorplus->cga.crtc[10] & 0x60) == 0x20) - colorplus->cga.cursoron = 0; - else - colorplus->cga.cursoron = colorplus->cga.cgablink & 8; - } + if (oldvc == colorplus->cga.crtc[4]) { + colorplus->cga.vc = 0; + colorplus->cga.vadj = colorplus->cga.crtc[5]; + if (!colorplus->cga.vadj) + colorplus->cga.cgadispon = 1; + if (!colorplus->cga.vadj) + colorplus->cga.ma = colorplus->cga.maback = + (colorplus->cga.crtc[13] | (colorplus->cga.crtc[12] << 8)) & 0x3fff; + if ((colorplus->cga.crtc[10] & 0x60) == 0x20) + colorplus->cga.cursoron = 0; + else + colorplus->cga.cursoron = colorplus->cga.cgablink & 8; + } - if (colorplus->cga.vc == colorplus->cga.crtc[7]) { - colorplus->cga.cgadispon = 0; - colorplus->cga.displine = 0; - colorplus->cga.vsynctime = 16; - if (colorplus->cga.crtc[7]) { - if (colorplus->cga.cgamode & 1) - x = (colorplus->cga.crtc[1] << 3) + 16; - else - x = (colorplus->cga.crtc[1] << 4) + 16; - colorplus->cga.lastline++; - if (x != xsize || (colorplus->cga.lastline - colorplus->cga.firstline) != ysize) { - xsize = x; - ysize = colorplus->cga.lastline - colorplus->cga.firstline; - if (xsize < 64) - xsize = 656; - if (ysize < 32) - ysize = 200; - updatewindowsize(xsize, (ysize << 1) + 16); - } + if (colorplus->cga.vc == colorplus->cga.crtc[7]) { + colorplus->cga.cgadispon = 0; + colorplus->cga.displine = 0; + colorplus->cga.vsynctime = 16; + if (colorplus->cga.crtc[7]) { + if (colorplus->cga.cgamode & 1) + x = (colorplus->cga.crtc[1] << 3) + 16; + else + x = (colorplus->cga.crtc[1] << 4) + 16; + colorplus->cga.lastline++; + if (x != xsize || (colorplus->cga.lastline - colorplus->cga.firstline) != ysize) { + xsize = x; + ysize = colorplus->cga.lastline - colorplus->cga.firstline; + if (xsize < 64) + xsize = 656; + if (ysize < 32) + ysize = 200; + updatewindowsize(xsize, (ysize << 1) + 16); + } - video_blit_memtoscreen(0, - colorplus->cga.firstline - 4, 0, - (colorplus->cga.lastline - colorplus->cga.firstline) + 8, xsize, (colorplus->cga.lastline - colorplus->cga.firstline) + 8); - frames++; + video_blit_memtoscreen(0, colorplus->cga.firstline - 4, 0, + (colorplus->cga.lastline - colorplus->cga.firstline) + 8, xsize, + (colorplus->cga.lastline - colorplus->cga.firstline) + 8); + frames++; - video_res_x = xsize - 16; - video_res_y = ysize; - if (colorplus->cga.cgamode & 1) { - video_res_x /= 8; - video_res_y /= colorplus->cga.crtc[9] + 1; - video_bpp = 0; - } else if (!(colorplus->cga.cgamode & 2)) { - video_res_x /= 16; - video_res_y /= colorplus->cga.crtc[9] + 1; - video_bpp = 0; - } else if (!(colorplus->cga.cgamode & 16)) { - video_res_x /= 2; - video_bpp = 2; - } else { - video_bpp = 1; - } - } - colorplus->cga.firstline = 1000; - colorplus->cga.lastline = 0; - colorplus->cga.cgablink++; - colorplus->cga.oddeven ^= 1; - } - } else { - colorplus->cga.sc++; - colorplus->cga.sc &= 31; - colorplus->cga.ma = colorplus->cga.maback; - } - if (colorplus->cga.cgadispon) - colorplus->cga.cgastat &= ~1; - if ((colorplus->cga.sc == (colorplus->cga.crtc[10] & 31) || ((colorplus->cga.crtc[8] & 3) == 3 && colorplus->cga.sc == ((colorplus->cga.crtc[10] & 31) >> 1)))) - colorplus->cga.con = 1; - if (colorplus->cga.cgadispon && (colorplus->cga.cgamode & 1)) { - for (x = 0; x < (colorplus->cga.crtc[1] << 1); x++) - colorplus->cga.charbuffer[x] = colorplus->cga.vram[(((colorplus->cga.ma << 1) + x) & 0x3fff)]; - } - } + video_res_x = xsize - 16; + video_res_y = ysize; + if (colorplus->cga.cgamode & 1) { + video_res_x /= 8; + video_res_y /= colorplus->cga.crtc[9] + 1; + video_bpp = 0; + } else if (!(colorplus->cga.cgamode & 2)) { + video_res_x /= 16; + video_res_y /= colorplus->cga.crtc[9] + 1; + video_bpp = 0; + } else if (!(colorplus->cga.cgamode & 16)) { + video_res_x /= 2; + video_bpp = 2; + } else { + video_bpp = 1; + } + } + colorplus->cga.firstline = 1000; + colorplus->cga.lastline = 0; + colorplus->cga.cgablink++; + colorplus->cga.oddeven ^= 1; + } + } else { + colorplus->cga.sc++; + colorplus->cga.sc &= 31; + colorplus->cga.ma = colorplus->cga.maback; + } + if (colorplus->cga.cgadispon) + colorplus->cga.cgastat &= ~1; + if ((colorplus->cga.sc == (colorplus->cga.crtc[10] & 31) || + ((colorplus->cga.crtc[8] & 3) == 3 && colorplus->cga.sc == ((colorplus->cga.crtc[10] & 31) >> 1)))) + colorplus->cga.con = 1; + if (colorplus->cga.cgadispon && (colorplus->cga.cgamode & 1)) { + for (x = 0; x < (colorplus->cga.crtc[1] << 1); x++) + colorplus->cga.charbuffer[x] = colorplus->cga.vram[(((colorplus->cga.ma << 1) + x) & 0x3fff)]; + } + } } void *colorplus_init() { - int display_type, contrast; - colorplus_t *colorplus = malloc(sizeof(colorplus_t)); - memset(colorplus, 0, sizeof(colorplus_t)); + int display_type, contrast; + colorplus_t *colorplus = malloc(sizeof(colorplus_t)); + memset(colorplus, 0, sizeof(colorplus_t)); - colorplus->cga.vram = malloc(0x8000); - colorplus->cga.composite = colorplus->cga.snow_enabled = 0; + colorplus->cga.vram = malloc(0x8000); + colorplus->cga.composite = colorplus->cga.snow_enabled = 0; - display_type = device_get_config_int("display_type"); - contrast = device_get_config_int("contrast"); + display_type = device_get_config_int("display_type"); + contrast = device_get_config_int("contrast"); - timer_add(&colorplus->cga.timer, colorplus_poll, colorplus, 1); - mem_mapping_add(&colorplus->cga.mapping, 0xb8000, 0x08000, colorplus_read, NULL, NULL, colorplus_write, NULL, NULL, NULL, 0, colorplus); - io_sethandler(0x03d0, 0x0010, colorplus_in, NULL, NULL, colorplus_out, NULL, NULL, colorplus); + timer_add(&colorplus->cga.timer, colorplus_poll, colorplus, 1); + mem_mapping_add(&colorplus->cga.mapping, 0xb8000, 0x08000, colorplus_read, NULL, NULL, colorplus_write, NULL, NULL, NULL, + 0, colorplus); + io_sethandler(0x03d0, 0x0010, colorplus_in, NULL, NULL, colorplus_out, NULL, NULL, colorplus); - cgapal_rebuild(display_type, contrast); + cgapal_rebuild(display_type, contrast); - return colorplus; + return colorplus; } void colorplus_close(void *p) { - colorplus_t *colorplus = (colorplus_t *)p; + colorplus_t *colorplus = (colorplus_t *)p; - free(colorplus->cga.vram); - free(colorplus); + free(colorplus->cga.vram); + free(colorplus); } void colorplus_speed_changed(void *p) { - colorplus_t *colorplus = (colorplus_t *)p; + colorplus_t *colorplus = (colorplus_t *)p; - cga_recalctimings(&colorplus->cga); + cga_recalctimings(&colorplus->cga); } -device_config_t colorplus_config[] = - { - { - .name = "display_type", - .description = "Display type", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "RGB", - .value = DISPLAY_RGB - }, - { - .description = "RGB (no brown)", - .value = DISPLAY_RGB_NO_BROWN - }, - { - .description = "Green Monochrome", - .value = DISPLAY_GREEN - }, - { - .description = "Amber Monochrome", - .value = DISPLAY_AMBER - }, - { - .description = "White Monochrome", - .value = DISPLAY_WHITE - }, - { - .description = "" - } - }, - .default_int = DISPLAY_RGB - }, - { - .name = "contrast", - .description = "Alternate monochrome contrast", - .type = CONFIG_BINARY, - .default_int = 0 - }, - { - .type = -1 - } - }; +device_config_t colorplus_config[] = { + {.name = "display_type", + .description = "Display type", + .type = CONFIG_SELECTION, + .selection = {{.description = "RGB", .value = DISPLAY_RGB}, + {.description = "RGB (no brown)", .value = DISPLAY_RGB_NO_BROWN}, + {.description = "Green Monochrome", .value = DISPLAY_GREEN}, + {.description = "Amber Monochrome", .value = DISPLAY_AMBER}, + {.description = "White Monochrome", .value = DISPLAY_WHITE}, + {.description = ""}}, + .default_int = DISPLAY_RGB}, + {.name = "contrast", .description = "Alternate monochrome contrast", .type = CONFIG_BINARY, .default_int = 0}, + {.type = -1}}; -device_t colorplus_device = - { - "Colorplus", - 0, - colorplus_init, - colorplus_close, - NULL, - colorplus_speed_changed, - NULL, - NULL, - colorplus_config - }; +device_t colorplus_device = {"Colorplus", 0, colorplus_init, colorplus_close, NULL, colorplus_speed_changed, + NULL, NULL, colorplus_config}; diff --git a/src/video/vid_compaq_cga.c b/src/video/vid_compaq_cga.c index 3a0387fb..73274fc9 100644 --- a/src/video/vid_compaq_cga.c +++ b/src/video/vid_compaq_cga.c @@ -10,341 +10,367 @@ #include "vid_compaq_cga.h" typedef struct compaq_cga_t { - cga_t cga; + cga_t cga; } compaq_cga_t; static uint8_t mdaattr[256][2][2]; void compaq_cga_recalctimings(compaq_cga_t *self) { - double _dispontime, _dispofftime, disptime; - disptime = self->cga.crtc[0] + 1; - _dispontime = self->cga.crtc[1]; - _dispofftime = disptime - _dispontime; - _dispontime *= MDACONST; - _dispofftime *= MDACONST; - self->cga.dispontime = (uint64_t)_dispontime; - self->cga.dispofftime = (uint64_t)_dispofftime; + double _dispontime, _dispofftime, disptime; + disptime = self->cga.crtc[0] + 1; + _dispontime = self->cga.crtc[1]; + _dispofftime = disptime - _dispontime; + _dispontime *= MDACONST; + _dispofftime *= MDACONST; + self->cga.dispontime = (uint64_t)_dispontime; + self->cga.dispofftime = (uint64_t)_dispofftime; } void compaq_cga_poll(void *p) { - compaq_cga_t *self = (compaq_cga_t *)p; - uint16_t ca = (self->cga.crtc[15] | (self->cga.crtc[14] << 8)) & 0x3fff; - int drawcursor; - int x, c; - int oldvc; - uint8_t chr, attr; - uint32_t cols[4]; - int oldsc; - int underline; - int blink; + compaq_cga_t *self = (compaq_cga_t *)p; + uint16_t ca = (self->cga.crtc[15] | (self->cga.crtc[14] << 8)) & 0x3fff; + int drawcursor; + int x, c; + int oldvc; + uint8_t chr, attr; + uint32_t cols[4]; + int oldsc; + int underline; + int blink; - /* If in graphics mode or character height is not 13, behave as CGA */ - if ((self->cga.cgamode & 0x12) || (self->cga.crtc[9] != 13)) { - cga_poll(&self->cga); - return; - } + /* If in graphics mode or character height is not 13, behave as CGA */ + if ((self->cga.cgamode & 0x12) || (self->cga.crtc[9] != 13)) { + cga_poll(&self->cga); + return; + } -/* We are in Compaq 350-line CGA territory */ - if (!self->cga.linepos) { - timer_advance_u64(&self->cga.timer, self->cga.dispofftime); - self->cga.cgastat |= 1; - self->cga.linepos = 1; - oldsc = self->cga.sc; - if ((self->cga.crtc[8] & 3) == 3) - self->cga.sc = ((self->cga.sc << 1) + self->cga.oddeven) & 7; - if (self->cga.cgadispon) { - if (self->cga.displine < self->cga.firstline) { - self->cga.firstline = self->cga.displine; - video_wait_for_buffer(); -// printf("Firstline %i\n",firstline); - } - self->cga.lastline = self->cga.displine; + /* We are in Compaq 350-line CGA territory */ + if (!self->cga.linepos) { + timer_advance_u64(&self->cga.timer, self->cga.dispofftime); + self->cga.cgastat |= 1; + self->cga.linepos = 1; + oldsc = self->cga.sc; + if ((self->cga.crtc[8] & 3) == 3) + self->cga.sc = ((self->cga.sc << 1) + self->cga.oddeven) & 7; + if (self->cga.cgadispon) { + if (self->cga.displine < self->cga.firstline) { + self->cga.firstline = self->cga.displine; + video_wait_for_buffer(); + // printf("Firstline %i\n",firstline); + } + self->cga.lastline = self->cga.displine; - cols[0] = (self->cga.cgacol & 15); + cols[0] = (self->cga.cgacol & 15); - for (c = 0; c < 8; c++) { - ((uint32_t *)buffer32->line[self->cga.displine])[c] = cols[0]; - if (self->cga.cgamode & 1) - ((uint32_t *)buffer32->line[self->cga.displine])[c + (self->cga.crtc[1] << 3) + 8] = cols[0]; - else - ((uint32_t *)buffer32->line[self->cga.displine])[c + (self->cga.crtc[1] << 4) + 8] = cols[0]; - } - if (self->cga.cgamode & 1) { - for (x = 0; x < self->cga.crtc[1]; x++) { - chr = self->cga.charbuffer[x << 1]; - attr = self->cga.charbuffer[(x << 1) + 1]; - drawcursor = ((self->cga.ma == ca) && self->cga.con && self->cga.cursoron); - underline = 0; - blink = ((self->cga.cgablink & 8) && (self->cga.cgamode & 0x20) && (attr & 0x80) && !drawcursor); - if (self->cga.cgamode & 0x80) { - cols[0] = mdaattr[attr][blink][0]; - cols[1] = mdaattr[attr][blink][1]; - if (self->cga.sc == 12 && (attr & 7) == 1) - underline = 1; - } else if (self->cga.cgamode & 0x20) { - cols[1] = attr & 15; - cols[0] = (attr >> 4) & 7; - if (blink) - cols[1] = cols[0]; - } else { - cols[1] = attr & 15; - cols[0] = attr >> 4; - } - if (underline) { - for (c = 0; c < 8; c++) - ((uint32_t *)buffer32->line[self->cga.displine])[(x << 3) + c + 8] = mdaattr[attr][blink][1]; - } else if (drawcursor) { - for (c = 0; c < 8; c++) - ((uint32_t *)buffer32->line[self->cga.displine])[(x << 3) + c + 8] = - cols[(fontdatm[chr + self->cga.fontbase][self->cga.sc & 15] & (1 << (c ^ 7))) ? 1 : 0] ^ 0xffffff; - } else { - for (c = 0; c < 8; c++) - ((uint32_t *)buffer32->line[self->cga.displine])[(x << 3) + c + 8] = cols[(fontdatm[chr + self->cga.fontbase][self->cga.sc & 15] - & (1 << (c ^ 7))) ? 1 : 0]; - } - self->cga.ma++; - } - } else { - for (x = 0; x < self->cga.crtc[1]; x++) { - chr = self->cga.vram[((self->cga.ma << 1) & 0x3fff)]; - attr = self->cga.vram[(((self->cga.ma << 1) + 1) & 0x3fff)]; - drawcursor = ((self->cga.ma == ca) && self->cga.con && self->cga.cursoron); - underline = 0; - blink = ((self->cga.cgablink & 8) && (self->cga.cgamode & 0x20) && (attr & 0x80) && !drawcursor); - if (self->cga.cgamode & 0x80) { - cols[0] = mdaattr[attr][blink][0]; - cols[1] = mdaattr[attr][blink][1]; - if (self->cga.sc == 12 && (attr & 7) == 1) - underline = 1; - } else if (self->cga.cgamode & 0x20) { - cols[1] = attr & 15; - cols[0] = (attr >> 4) & 7; - if (blink) - cols[1] = cols[0]; - } else { - cols[1] = attr & 15; - cols[0] = attr >> 4; - } - self->cga.ma++; - if (underline) { - for (c = 0; c < 8; c++) - ((uint32_t *)buffer32->line[self->cga.displine])[(x << 4) + (c << 1) + 8] = - ((uint32_t *)buffer32->line[self->cga.displine])[(x << 4) + (c << 1) + 9] = mdaattr[attr][blink][1]; - } else if (drawcursor) { - for (c = 0; c < 8; c++) - ((uint32_t *)buffer32->line[self->cga.displine])[(x << 4) + (c << 1) + 8] = - ((uint32_t *)buffer32->line[self->cga.displine])[(x << 4) + (c << 1) + 1 + 8] = - cols[(fontdatm[chr + self->cga.fontbase][self->cga.sc & 15] & (1 << (c ^ 7))) ? 1 : 0] ^ 0xffffff; - } else { - for (c = 0; c < 8; c++) - ((uint32_t *)buffer32->line[self->cga.displine])[(x << 4) + (c << 1) + 8] = - ((uint32_t *)buffer32->line[self->cga.displine])[(x << 4) + (c << 1) + 1 + 8] = cols[( - fontdatm[chr + self->cga.fontbase][self->cga.sc & 15] & (1 << (c ^ 7))) ? 1 : 0]; - } - } - } - } else { - cols[0] = (self->cga.cgacol & 15); - if (self->cga.cgamode & 1) - hline(buffer32, 0, self->cga.displine, (self->cga.crtc[1] << 3) + 16, cols[0]); - else - hline(buffer32, 0, self->cga.displine, (self->cga.crtc[1] << 4) + 16, cols[0]); - } + for (c = 0; c < 8; c++) { + ((uint32_t *)buffer32->line[self->cga.displine])[c] = cols[0]; + if (self->cga.cgamode & 1) + ((uint32_t *)buffer32->line[self->cga.displine])[c + (self->cga.crtc[1] << 3) + 8] = + cols[0]; + else + ((uint32_t *)buffer32->line[self->cga.displine])[c + (self->cga.crtc[1] << 4) + 8] = + cols[0]; + } + if (self->cga.cgamode & 1) { + for (x = 0; x < self->cga.crtc[1]; x++) { + chr = self->cga.charbuffer[x << 1]; + attr = self->cga.charbuffer[(x << 1) + 1]; + drawcursor = ((self->cga.ma == ca) && self->cga.con && self->cga.cursoron); + underline = 0; + blink = ((self->cga.cgablink & 8) && (self->cga.cgamode & 0x20) && (attr & 0x80) && + !drawcursor); + if (self->cga.cgamode & 0x80) { + cols[0] = mdaattr[attr][blink][0]; + cols[1] = mdaattr[attr][blink][1]; + if (self->cga.sc == 12 && (attr & 7) == 1) + underline = 1; + } else if (self->cga.cgamode & 0x20) { + cols[1] = attr & 15; + cols[0] = (attr >> 4) & 7; + if (blink) + cols[1] = cols[0]; + } else { + cols[1] = attr & 15; + cols[0] = attr >> 4; + } + if (underline) { + for (c = 0; c < 8; c++) + ((uint32_t *)buffer32->line[self->cga.displine])[(x << 3) + c + 8] = + mdaattr[attr][blink][1]; + } else if (drawcursor) { + for (c = 0; c < 8; c++) + ((uint32_t *)buffer32->line[self->cga.displine])[(x << 3) + c + 8] = + cols[(fontdatm[chr + self->cga.fontbase][self->cga.sc & 15] & + (1 << (c ^ 7))) + ? 1 + : 0] ^ + 0xffffff; + } else { + for (c = 0; c < 8; c++) + ((uint32_t *)buffer32->line[self->cga.displine])[(x << 3) + c + 8] = + cols[(fontdatm[chr + self->cga.fontbase][self->cga.sc & 15] & + (1 << (c ^ 7))) + ? 1 + : 0]; + } + self->cga.ma++; + } + } else { + for (x = 0; x < self->cga.crtc[1]; x++) { + chr = self->cga.vram[((self->cga.ma << 1) & 0x3fff)]; + attr = self->cga.vram[(((self->cga.ma << 1) + 1) & 0x3fff)]; + drawcursor = ((self->cga.ma == ca) && self->cga.con && self->cga.cursoron); + underline = 0; + blink = ((self->cga.cgablink & 8) && (self->cga.cgamode & 0x20) && (attr & 0x80) && + !drawcursor); + if (self->cga.cgamode & 0x80) { + cols[0] = mdaattr[attr][blink][0]; + cols[1] = mdaattr[attr][blink][1]; + if (self->cga.sc == 12 && (attr & 7) == 1) + underline = 1; + } else if (self->cga.cgamode & 0x20) { + cols[1] = attr & 15; + cols[0] = (attr >> 4) & 7; + if (blink) + cols[1] = cols[0]; + } else { + cols[1] = attr & 15; + cols[0] = attr >> 4; + } + self->cga.ma++; + if (underline) { + for (c = 0; c < 8; c++) + ((uint32_t *) + buffer32->line[self->cga.displine])[(x << 4) + (c << 1) + 8] = + ((uint32_t *)buffer32 + ->line[self->cga.displine])[(x << 4) + (c << 1) + 9] = + mdaattr[attr][blink][1]; + } else if (drawcursor) { + for (c = 0; c < 8; c++) + ((uint32_t *) + buffer32->line[self->cga.displine])[(x << 4) + (c << 1) + 8] = + ((uint32_t *) + buffer32->line[self->cga.displine])[(x << 4) + (c << 1) + + 1 + 8] = + cols[(fontdatm[chr + self->cga.fontbase] + [self->cga.sc & 15] & + (1 << (c ^ 7))) + ? 1 + : 0] ^ + 0xffffff; + } else { + for (c = 0; c < 8; c++) + ((uint32_t *) + buffer32->line[self->cga.displine])[(x << 4) + (c << 1) + 8] = + ((uint32_t *) + buffer32->line[self->cga.displine])[(x << 4) + (c << 1) + + 1 + 8] = + cols[(fontdatm[chr + self->cga.fontbase] + [self->cga.sc & 15] & + (1 << (c ^ 7))) + ? 1 + : 0]; + } + } + } + } else { + cols[0] = (self->cga.cgacol & 15); + if (self->cga.cgamode & 1) + hline(buffer32, 0, self->cga.displine, (self->cga.crtc[1] << 3) + 16, cols[0]); + else + hline(buffer32, 0, self->cga.displine, (self->cga.crtc[1] << 4) + 16, cols[0]); + } - if (self->cga.cgamode & 1) - x = (self->cga.crtc[1] << 3) + 16; - else - x = (self->cga.crtc[1] << 4) + 16; + if (self->cga.cgamode & 1) + x = (self->cga.crtc[1] << 3) + 16; + else + x = (self->cga.crtc[1] << 4) + 16; - for (c = 0; c < x; c++) - ((uint32_t *)buffer32->line[self->cga.displine])[c] = cgapal[((uint32_t *)buffer32->line[self->cga.displine])[c] & 0xf]; + for (c = 0; c < x; c++) + ((uint32_t *)buffer32->line[self->cga.displine])[c] = + cgapal[((uint32_t *)buffer32->line[self->cga.displine])[c] & 0xf]; - self->cga.sc = oldsc; - if (self->cga.vc == self->cga.crtc[7] && !self->cga.sc) - self->cga.cgastat |= 8; - self->cga.displine++; - if (self->cga.displine >= 500) - self->cga.displine = 0; - } else { - timer_advance_u64(&self->cga.timer, self->cga.dispontime); - self->cga.linepos = 0; - if (self->cga.vsynctime) { - self->cga.vsynctime--; - if (!self->cga.vsynctime) - self->cga.cgastat &= ~8; - } - if (self->cga.sc == (self->cga.crtc[11] & 31) || ((self->cga.crtc[8] & 3) == 3 && self->cga.sc == ((self->cga.crtc[11] & 31) >> 1))) { - self->cga.con = 0; - self->cga.coff = 1; - } - if ((self->cga.crtc[8] & 3) == 3 && self->cga.sc == (self->cga.crtc[9] >> 1)) - self->cga.maback = self->cga.ma; - if (self->cga.vadj) { - self->cga.sc++; - self->cga.sc &= 31; - self->cga.ma = self->cga.maback; - self->cga.vadj--; - if (!self->cga.vadj) { - self->cga.cgadispon = 1; - self->cga.ma = self->cga.maback = (self->cga.crtc[13] | (self->cga.crtc[12] << 8)) & 0x3fff; - self->cga.sc = 0; - } - } else if (self->cga.sc == self->cga.crtc[9]) { - self->cga.maback = self->cga.ma; - self->cga.sc = 0; - oldvc = self->cga.vc; - self->cga.vc++; - self->cga.vc &= 127; + self->cga.sc = oldsc; + if (self->cga.vc == self->cga.crtc[7] && !self->cga.sc) + self->cga.cgastat |= 8; + self->cga.displine++; + if (self->cga.displine >= 500) + self->cga.displine = 0; + } else { + timer_advance_u64(&self->cga.timer, self->cga.dispontime); + self->cga.linepos = 0; + if (self->cga.vsynctime) { + self->cga.vsynctime--; + if (!self->cga.vsynctime) + self->cga.cgastat &= ~8; + } + if (self->cga.sc == (self->cga.crtc[11] & 31) || + ((self->cga.crtc[8] & 3) == 3 && self->cga.sc == ((self->cga.crtc[11] & 31) >> 1))) { + self->cga.con = 0; + self->cga.coff = 1; + } + if ((self->cga.crtc[8] & 3) == 3 && self->cga.sc == (self->cga.crtc[9] >> 1)) + self->cga.maback = self->cga.ma; + if (self->cga.vadj) { + self->cga.sc++; + self->cga.sc &= 31; + self->cga.ma = self->cga.maback; + self->cga.vadj--; + if (!self->cga.vadj) { + self->cga.cgadispon = 1; + self->cga.ma = self->cga.maback = (self->cga.crtc[13] | (self->cga.crtc[12] << 8)) & 0x3fff; + self->cga.sc = 0; + } + } else if (self->cga.sc == self->cga.crtc[9]) { + self->cga.maback = self->cga.ma; + self->cga.sc = 0; + oldvc = self->cga.vc; + self->cga.vc++; + self->cga.vc &= 127; - if (self->cga.vc == self->cga.crtc[6]) - self->cga.cgadispon = 0; + if (self->cga.vc == self->cga.crtc[6]) + self->cga.cgadispon = 0; - if (oldvc == self->cga.crtc[4]) { - self->cga.vc = 0; - self->cga.vadj = self->cga.crtc[5]; - if (!self->cga.vadj) - self->cga.cgadispon = 1; - if (!self->cga.vadj) - self->cga.ma = self->cga.maback = (self->cga.crtc[13] | (self->cga.crtc[12] << 8)) & 0x3fff; - if ((self->cga.crtc[10] & 0x60) == 0x20) - self->cga.cursoron = 0; - else - self->cga.cursoron = self->cga.cgablink & 8; - } + if (oldvc == self->cga.crtc[4]) { + self->cga.vc = 0; + self->cga.vadj = self->cga.crtc[5]; + if (!self->cga.vadj) + self->cga.cgadispon = 1; + if (!self->cga.vadj) + self->cga.ma = self->cga.maback = + (self->cga.crtc[13] | (self->cga.crtc[12] << 8)) & 0x3fff; + if ((self->cga.crtc[10] & 0x60) == 0x20) + self->cga.cursoron = 0; + else + self->cga.cursoron = self->cga.cgablink & 8; + } - if (self->cga.vc == self->cga.crtc[7]) { - self->cga.cgadispon = 0; - self->cga.displine = 0; - self->cga.vsynctime = 16; - if (self->cga.crtc[7]) { - if (self->cga.cgamode & 1) - x = (self->cga.crtc[1] << 3) + 16; - else - x = (self->cga.crtc[1] << 4) + 16; - self->cga.lastline++; - if (x != xsize || (self->cga.lastline - self->cga.firstline) != ysize) { - xsize = x; - ysize = self->cga.lastline - self->cga.firstline; + if (self->cga.vc == self->cga.crtc[7]) { + self->cga.cgadispon = 0; + self->cga.displine = 0; + self->cga.vsynctime = 16; + if (self->cga.crtc[7]) { + if (self->cga.cgamode & 1) + x = (self->cga.crtc[1] << 3) + 16; + else + x = (self->cga.crtc[1] << 4) + 16; + self->cga.lastline++; + if (x != xsize || (self->cga.lastline - self->cga.firstline) != ysize) { + xsize = x; + ysize = self->cga.lastline - self->cga.firstline; - if (xsize < 64) - xsize = 656; - if (ysize < 32) - ysize = 200; - updatewindowsize(xsize, ysize + 16); - } + if (xsize < 64) + xsize = 656; + if (ysize < 32) + ysize = 200; + updatewindowsize(xsize, ysize + 16); + } - video_blit_memtoscreen(0, self->cga.firstline - 4, 0, (self->cga.lastline - self->cga.firstline) + 8, xsize, (self->cga.lastline - self->cga.firstline) + 8); - frames++; - - video_res_x = xsize - 16; - video_res_y = ysize; - if (self->cga.cgamode & 1) { - video_res_x /= 8; - video_res_y /= self->cga.crtc[9] + 1; - video_bpp = 0; - } else if (!(self->cga.cgamode & 2)) { - video_res_x /= 16; - video_res_y /= self->cga.crtc[9] + 1; - video_bpp = 0; - } else if (!(self->cga.cgamode & 16)) { - video_res_x /= 2; - video_bpp = 2; - } else { - video_bpp = 1; - } - } - self->cga.firstline = 1000; - self->cga.lastline = 0; - self->cga.cgablink++; - self->cga.oddeven ^= 1; - } - } else { - self->cga.sc++; - self->cga.sc &= 31; - self->cga.ma = self->cga.maback; - } - if (self->cga.cgadispon) - self->cga.cgastat &= ~1; - if ((self->cga.sc == (self->cga.crtc[10] & 31) || ((self->cga.crtc[8] & 3) == 3 && self->cga.sc == ((self->cga.crtc[10] & 31) >> 1)))) - self->cga.con = 1; - if (self->cga.cgadispon && (self->cga.cgamode & 1)) { - for (x = 0; x < (self->cga.crtc[1] << 1); x++) - self->cga.charbuffer[x] = self->cga.vram[(((self->cga.ma << 1) + x) & 0x3fff)]; - } - } + video_blit_memtoscreen(0, self->cga.firstline - 4, 0, + (self->cga.lastline - self->cga.firstline) + 8, xsize, + (self->cga.lastline - self->cga.firstline) + 8); + frames++; + video_res_x = xsize - 16; + video_res_y = ysize; + if (self->cga.cgamode & 1) { + video_res_x /= 8; + video_res_y /= self->cga.crtc[9] + 1; + video_bpp = 0; + } else if (!(self->cga.cgamode & 2)) { + video_res_x /= 16; + video_res_y /= self->cga.crtc[9] + 1; + video_bpp = 0; + } else if (!(self->cga.cgamode & 16)) { + video_res_x /= 2; + video_bpp = 2; + } else { + video_bpp = 1; + } + } + self->cga.firstline = 1000; + self->cga.lastline = 0; + self->cga.cgablink++; + self->cga.oddeven ^= 1; + } + } else { + self->cga.sc++; + self->cga.sc &= 31; + self->cga.ma = self->cga.maback; + } + if (self->cga.cgadispon) + self->cga.cgastat &= ~1; + if ((self->cga.sc == (self->cga.crtc[10] & 31) || + ((self->cga.crtc[8] & 3) == 3 && self->cga.sc == ((self->cga.crtc[10] & 31) >> 1)))) + self->cga.con = 1; + if (self->cga.cgadispon && (self->cga.cgamode & 1)) { + for (x = 0; x < (self->cga.crtc[1] << 1); x++) + self->cga.charbuffer[x] = self->cga.vram[(((self->cga.ma << 1) + x) & 0x3fff)]; + } + } } void *compaq_cga_init() { - int display_type; - int contrast; - int c; - compaq_cga_t *self = malloc(sizeof(compaq_cga_t)); - memset(self, 0, sizeof(compaq_cga_t)); + int display_type; + int contrast; + int c; + compaq_cga_t *self = malloc(sizeof(compaq_cga_t)); + memset(self, 0, sizeof(compaq_cga_t)); - self->cga.vram = malloc(0x4000); + self->cga.vram = malloc(0x4000); - timer_add(&self->cga.timer, compaq_cga_poll, self, 1); - mem_mapping_add(&self->cga.mapping, 0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, self); - io_sethandler(0x03d0, 0x0010, cga_in, NULL, NULL, cga_out, NULL, NULL, self); + timer_add(&self->cga.timer, compaq_cga_poll, self, 1); + mem_mapping_add(&self->cga.mapping, 0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL, + MEM_MAPPING_EXTERNAL, self); + io_sethandler(0x03d0, 0x0010, cga_in, NULL, NULL, cga_out, NULL, NULL, self); - display_type = device_get_config_int("display_type"); - contrast = device_get_config_int("contrast"); - cgapal_rebuild(display_type, contrast); + display_type = device_get_config_int("display_type"); + contrast = device_get_config_int("contrast"); + cgapal_rebuild(display_type, contrast); - for (c = 0; c < 256; c++) { - mdaattr[c][0][0] = mdaattr[c][1][0] = mdaattr[c][1][1] = 0; - if (c & 8) - mdaattr[c][0][1] = 0xf; - else - mdaattr[c][0][1] = 0x7; - } - mdaattr[0x70][0][1] = 0; - mdaattr[0x70][0][0] = mdaattr[0x70][1][0] = mdaattr[0x70][1][1] = 0xf; - mdaattr[0xF0][0][1] = 0; - mdaattr[0xF0][0][0] = mdaattr[0xF0][1][0] = mdaattr[0xF0][1][1] = 0xf; - mdaattr[0x78][0][1] = 0x7; - mdaattr[0x78][0][0] = mdaattr[0x78][1][0] = mdaattr[0x78][1][1] = 0xf; - mdaattr[0xF8][0][1] = 0x7; - mdaattr[0xF8][0][0] = mdaattr[0xF8][1][0] = mdaattr[0xF8][1][1] = 0xf; - mdaattr[0x00][0][1] = mdaattr[0x00][1][1] = 0; - mdaattr[0x08][0][1] = mdaattr[0x08][1][1] = 0; - mdaattr[0x80][0][1] = mdaattr[0x80][1][1] = 0; - mdaattr[0x88][0][1] = mdaattr[0x88][1][1] = 0; + for (c = 0; c < 256; c++) { + mdaattr[c][0][0] = mdaattr[c][1][0] = mdaattr[c][1][1] = 0; + if (c & 8) + mdaattr[c][0][1] = 0xf; + else + mdaattr[c][0][1] = 0x7; + } + mdaattr[0x70][0][1] = 0; + mdaattr[0x70][0][0] = mdaattr[0x70][1][0] = mdaattr[0x70][1][1] = 0xf; + mdaattr[0xF0][0][1] = 0; + mdaattr[0xF0][0][0] = mdaattr[0xF0][1][0] = mdaattr[0xF0][1][1] = 0xf; + mdaattr[0x78][0][1] = 0x7; + mdaattr[0x78][0][0] = mdaattr[0x78][1][0] = mdaattr[0x78][1][1] = 0xf; + mdaattr[0xF8][0][1] = 0x7; + mdaattr[0xF8][0][0] = mdaattr[0xF8][1][0] = mdaattr[0xF8][1][1] = 0xf; + mdaattr[0x00][0][1] = mdaattr[0x00][1][1] = 0; + mdaattr[0x08][0][1] = mdaattr[0x08][1][1] = 0; + mdaattr[0x80][0][1] = mdaattr[0x80][1][1] = 0; + mdaattr[0x88][0][1] = mdaattr[0x88][1][1] = 0; - return self; + return self; } void compaq_cga_close(void *p) { - compaq_cga_t *self = (compaq_cga_t *)p; + compaq_cga_t *self = (compaq_cga_t *)p; - free(self->cga.vram); - free(self); + free(self->cga.vram); + free(self); } void compaq_cga_speed_changed(void *p) { - compaq_cga_t *self = (compaq_cga_t *)p; + compaq_cga_t *self = (compaq_cga_t *)p; - if (self->cga.crtc[9] == 13) /* Character height */ - { - compaq_cga_recalctimings(self); - } else { - cga_recalctimings(&self->cga); - } + if (self->cga.crtc[9] == 13) /* Character height */ + { + compaq_cga_recalctimings(self); + } else { + cga_recalctimings(&self->cga); + } } extern device_config_t cga_config[]; -device_t compaq_cga_device = - { - "Compaq CGA", - 0, - compaq_cga_init, - compaq_cga_close, - NULL, - compaq_cga_speed_changed, - NULL, - NULL, - cga_config - }; +device_t compaq_cga_device = {"Compaq CGA", 0, compaq_cga_init, compaq_cga_close, NULL, compaq_cga_speed_changed, + NULL, NULL, cga_config}; diff --git a/src/video/vid_ddc.c b/src/video/vid_ddc.c index 45180f7a..7c13c199 100644 --- a/src/video/vid_ddc.c +++ b/src/video/vid_ddc.c @@ -2,279 +2,256 @@ #include "vid_ddc.h" #include "x86.h" -static uint8_t edid_data[128] = - { - 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, /*Fixed header pattern*/ - 0x65, 0x40, /*Manufacturer "PCE" - apparently unassigned by UEFI*/ - 0x00, 0x00, /*Product code*/ - 0x12, 0x34, 0x56, 0x78, /*Serial number*/ - 0x01, 9, /*Manufacturer week and year*/ - 0x01, 0x03, /*EDID version (1.3)*/ +static uint8_t edid_data[128] = { + 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, /*Fixed header pattern*/ + 0x65, 0x40, /*Manufacturer "PCE" - apparently unassigned by UEFI*/ + 0x00, 0x00, /*Product code*/ + 0x12, 0x34, 0x56, 0x78, /*Serial number*/ + 0x01, 9, /*Manufacturer week and year*/ + 0x01, 0x03, /*EDID version (1.3)*/ - 0x08, /*Analogue input, separate sync*/ - 34, 0, /*Landscape, 4:3*/ - 0, /*Gamma*/ - 0x08, /*RGB colour*/ - 0x81, 0xf1, 0xa3, 0x57, 0x53, 0x9f, 0x27, 0x0a, 0x50, /*Chromaticity*/ + 0x08, /*Analogue input, separate sync*/ + 34, 0, /*Landscape, 4:3*/ + 0, /*Gamma*/ + 0x08, /*RGB colour*/ + 0x81, 0xf1, 0xa3, 0x57, 0x53, 0x9f, 0x27, 0x0a, 0x50, /*Chromaticity*/ - 0xff, 0xff, 0xff, /*Established timing bitmap*/ - 0x00, 0x00, /*Standard timing information*/ - 0x00, 0x00, - 0x00, 0x00, - 0x00, 0x00, - 0x00, 0x00, - 0x00, 0x00, - 0x00, 0x00, - 0x00, 0x00, + 0xff, 0xff, 0xff, /*Established timing bitmap*/ + 0x00, 0x00, /*Standard timing information*/ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - /*Detailed mode descriptions*/ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /*Detailed mode descriptions*/ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, /*No extensions*/ - 0x00 - }; + 0x00, /*No extensions*/ + 0x00}; /*This should probably be split off into a separate I2C module*/ -enum { - TRANSMITTER_MONITOR = 1, - TRANSMITTER_HOST = -1 -}; +enum { TRANSMITTER_MONITOR = 1, TRANSMITTER_HOST = -1 }; enum { - I2C_IDLE = 0, - I2C_RECEIVE, - I2C_RECEIVE_WAIT, - I2C_TRANSMIT_START, - I2C_TRANSMIT, - I2C_ACKNOWLEDGE, - I2C_TRANSACKNOWLEDGE, - I2C_TRANSMIT_WAIT + I2C_IDLE = 0, + I2C_RECEIVE, + I2C_RECEIVE_WAIT, + I2C_TRANSMIT_START, + I2C_TRANSMIT, + I2C_ACKNOWLEDGE, + I2C_TRANSACKNOWLEDGE, + I2C_TRANSMIT_WAIT }; -enum { - PROM_IDLE = 0, - PROM_RECEIVEADDR, - PROM_RECEIVEDATA, - PROM_SENDDATA, - PROM_INVALID -}; +enum { PROM_IDLE = 0, PROM_RECEIVEADDR, PROM_RECEIVEDATA, PROM_SENDDATA, PROM_INVALID }; static struct { - int clock, data; - int state; - int last_data; - int pos; - int transmit; - uint8_t byte; + int clock, data; + int state; + int last_data; + int pos; + int transmit; + uint8_t byte; } i2c; static struct { - int state; - int addr; - int rw; + int state; + int addr; + int rw; } prom; static void prom_stop(void) { -// pclog("prom_stop()\n"); - prom.state = PROM_IDLE; - i2c.transmit = TRANSMITTER_HOST; + // pclog("prom_stop()\n"); + prom.state = PROM_IDLE; + i2c.transmit = TRANSMITTER_HOST; } static void prom_next_byte(void) { -// pclog("prom_next_byte(%d)\n", prom.addr); - i2c.byte = edid_data[(prom.addr++) & 0x7F]; + // pclog("prom_next_byte(%d)\n", prom.addr); + i2c.byte = edid_data[(prom.addr++) & 0x7F]; } static void prom_write(uint8_t byte) { -// pclog("prom_write: byte=%02x\n", byte); - switch (prom.state) { - case PROM_IDLE: - if ((byte & 0xfe) != 0xa0) { -// pclog("I2C address not PROM\n"); - prom.state = PROM_INVALID; - break; - } - prom.rw = byte & 1; - if (prom.rw) { - prom.state = PROM_SENDDATA; - i2c.transmit = TRANSMITTER_MONITOR; - i2c.byte = edid_data[(prom.addr++) & 0x7F]; -// pclog("PROM - %02X from %02X\n",i2c.byte, prom.addr-1); -// pclog("Transmitter now PROM\n"); - } else { - prom.state = PROM_RECEIVEADDR; - i2c.transmit = TRANSMITTER_HOST; - } -// pclog("PROM R/W=%i\n",promrw); - return; + // pclog("prom_write: byte=%02x\n", byte); + switch (prom.state) { + case PROM_IDLE: + if ((byte & 0xfe) != 0xa0) { + // pclog("I2C address not PROM\n"); + prom.state = PROM_INVALID; + break; + } + prom.rw = byte & 1; + if (prom.rw) { + prom.state = PROM_SENDDATA; + i2c.transmit = TRANSMITTER_MONITOR; + i2c.byte = edid_data[(prom.addr++) & 0x7F]; + // pclog("PROM - %02X from %02X\n",i2c.byte, prom.addr-1); + // pclog("Transmitter now PROM\n"); + } else { + prom.state = PROM_RECEIVEADDR; + i2c.transmit = TRANSMITTER_HOST; + } + // pclog("PROM R/W=%i\n",promrw); + return; - case PROM_RECEIVEADDR: -// pclog("PROM addr=%02X\n",byte); - prom.addr = byte; - if (prom.rw) - prom.state = PROM_SENDDATA; - else - prom.state = PROM_RECEIVEDATA; - break; + case PROM_RECEIVEADDR: + // pclog("PROM addr=%02X\n",byte); + prom.addr = byte; + if (prom.rw) + prom.state = PROM_SENDDATA; + else + prom.state = PROM_RECEIVEDATA; + break; - case PROM_RECEIVEDATA: -// pclog("PROM write %02X %02X\n",promaddr,byte); - break; + case PROM_RECEIVEDATA: + // pclog("PROM write %02X %02X\n",promaddr,byte); + break; - case PROM_SENDDATA:break; - } + case PROM_SENDDATA: + break; + } } void ddc_i2c_change(int new_clock, int new_data) { -// pclog("I2C update clock %i->%i data %i->%i state %i\n",i2c.clock,new_clock,i2c.last_data,new_data,i2c.state); - switch (i2c.state) { - case I2C_IDLE: - if (i2c.clock && new_clock) { - if (i2c.last_data && !new_data) /*Start bit*/ - { -// pclog("Start bit received\n"); - i2c.state = I2C_RECEIVE; - i2c.pos = 0; - } - } - break; + // pclog("I2C update clock %i->%i data %i->%i state %i\n",i2c.clock,new_clock,i2c.last_data,new_data,i2c.state); + switch (i2c.state) { + case I2C_IDLE: + if (i2c.clock && new_clock) { + if (i2c.last_data && !new_data) /*Start bit*/ + { + // pclog("Start bit received\n"); + i2c.state = I2C_RECEIVE; + i2c.pos = 0; + } + } + break; - case I2C_RECEIVE_WAIT: - if (!i2c.clock && new_clock) - i2c.state = I2C_RECEIVE; - case I2C_RECEIVE: - if (!i2c.clock && new_clock) { - i2c.byte <<= 1; - if (new_data) - i2c.byte |= 1; - else - i2c.byte &= 0xFE; - i2c.pos++; - if (i2c.pos == 8) { - prom_write(i2c.byte); - i2c.state = I2C_ACKNOWLEDGE; - } - } else if (i2c.clock && new_clock && new_data && !i2c.last_data) /*Stop bit*/ - { -// pclog("Stop bit received\n"); - i2c.state = I2C_IDLE; - prom_stop(); - } else if (i2c.clock && new_clock && !new_data && i2c.last_data) /*Start bit*/ - { -// pclog("Start bit received\n"); - i2c.pos = 0; - prom.state = PROM_IDLE; - } - break; + case I2C_RECEIVE_WAIT: + if (!i2c.clock && new_clock) + i2c.state = I2C_RECEIVE; + case I2C_RECEIVE: + if (!i2c.clock && new_clock) { + i2c.byte <<= 1; + if (new_data) + i2c.byte |= 1; + else + i2c.byte &= 0xFE; + i2c.pos++; + if (i2c.pos == 8) { + prom_write(i2c.byte); + i2c.state = I2C_ACKNOWLEDGE; + } + } else if (i2c.clock && new_clock && new_data && !i2c.last_data) /*Stop bit*/ + { + // pclog("Stop bit received\n"); + i2c.state = I2C_IDLE; + prom_stop(); + } else if (i2c.clock && new_clock && !new_data && i2c.last_data) /*Start bit*/ + { + // pclog("Start bit received\n"); + i2c.pos = 0; + prom.state = PROM_IDLE; + } + break; - case I2C_ACKNOWLEDGE: - if (!i2c.clock && new_clock) { -// pclog("Acknowledging transfer\n"); - new_data = 0; - i2c.pos = 0; - if (i2c.transmit == TRANSMITTER_HOST) - i2c.state = I2C_RECEIVE_WAIT; - else - i2c.state = I2C_TRANSMIT; - } - break; + case I2C_ACKNOWLEDGE: + if (!i2c.clock && new_clock) { + // pclog("Acknowledging transfer\n"); + new_data = 0; + i2c.pos = 0; + if (i2c.transmit == TRANSMITTER_HOST) + i2c.state = I2C_RECEIVE_WAIT; + else + i2c.state = I2C_TRANSMIT; + } + break; - case I2C_TRANSACKNOWLEDGE: - if (!i2c.clock && new_clock) { - if (new_data) /*It's not acknowledged - must be end of transfer*/ - { -// pclog("End of transfer\n"); - i2c.state = I2C_IDLE; - prom_stop(); - } else /*Next byte to transfer*/ - { - i2c.state = I2C_TRANSMIT_START; - prom_next_byte(); - i2c.pos = 0; -// pclog("Next byte - %02X\n",i2c.byte); - } - } - break; + case I2C_TRANSACKNOWLEDGE: + if (!i2c.clock && new_clock) { + if (new_data) /*It's not acknowledged - must be end of transfer*/ + { + // pclog("End of transfer\n"); + i2c.state = I2C_IDLE; + prom_stop(); + } else /*Next byte to transfer*/ + { + i2c.state = I2C_TRANSMIT_START; + prom_next_byte(); + i2c.pos = 0; + // pclog("Next byte - %02X\n",i2c.byte); + } + } + break; - case I2C_TRANSMIT_WAIT: - if (i2c.clock && new_clock) { - if (i2c.last_data && !new_data) /*Start bit*/ - { - prom_next_byte(); - i2c.pos = 0; -// pclog("Next byte - %02X\n",i2c.byte); - } - if (!i2c.last_data && new_data) /*Stop bit*/ - { -// pclog("Stop bit received\n"); - i2c.state = I2C_IDLE; - prom_stop(); - } - } - break; + case I2C_TRANSMIT_WAIT: + if (i2c.clock && new_clock) { + if (i2c.last_data && !new_data) /*Start bit*/ + { + prom_next_byte(); + i2c.pos = 0; + // pclog("Next byte - %02X\n",i2c.byte); + } + if (!i2c.last_data && new_data) /*Stop bit*/ + { + // pclog("Stop bit received\n"); + i2c.state = I2C_IDLE; + prom_stop(); + } + } + break; - case I2C_TRANSMIT_START: - if (!i2c.clock && new_clock) - i2c.state = I2C_TRANSMIT; - if (i2c.clock && new_clock && !i2c.last_data && new_data) /*Stop bit*/ - { -// pclog("Stop bit received\n"); - i2c.state = I2C_IDLE; - prom_stop(); - } - case I2C_TRANSMIT: - if (!i2c.clock && new_clock) { - i2c.clock = new_clock; -// if (!i2c.pos) -// pclog("Transmit byte %02x\n", i2c.byte); - i2c.data = new_data = i2c.byte & 0x80; -// pclog("Transmit bit %i %i\n", i2c.byte, i2c.pos); - i2c.byte <<= 1; - i2c.pos++; - return; - } - if (i2c.clock && !new_clock && i2c.pos == 8) { - i2c.state = I2C_TRANSACKNOWLEDGE; -// pclog("Acknowledge mode\n"); - } - break; - - } - if (!i2c.clock && new_clock) - i2c.data = new_data; - i2c.last_data = new_data; - i2c.clock = new_clock; + case I2C_TRANSMIT_START: + if (!i2c.clock && new_clock) + i2c.state = I2C_TRANSMIT; + if (i2c.clock && new_clock && !i2c.last_data && new_data) /*Stop bit*/ + { + // pclog("Stop bit received\n"); + i2c.state = I2C_IDLE; + prom_stop(); + } + case I2C_TRANSMIT: + if (!i2c.clock && new_clock) { + i2c.clock = new_clock; + // if (!i2c.pos) + // pclog("Transmit byte %02x\n", i2c.byte); + i2c.data = new_data = i2c.byte & 0x80; + // pclog("Transmit bit %i %i\n", i2c.byte, i2c.pos); + i2c.byte <<= 1; + i2c.pos++; + return; + } + if (i2c.clock && !new_clock && i2c.pos == 8) { + i2c.state = I2C_TRANSACKNOWLEDGE; + // pclog("Acknowledge mode\n"); + } + break; + } + if (!i2c.clock && new_clock) + i2c.data = new_data; + i2c.last_data = new_data; + i2c.clock = new_clock; } -int ddc_read_clock(void) { - return i2c.clock; -} +int ddc_read_clock(void) { return i2c.clock; } int ddc_read_data(void) { - if (i2c.state == I2C_TRANSMIT || i2c.state == I2C_ACKNOWLEDGE) - return i2c.data; - if (i2c.state == I2C_RECEIVE_WAIT) - return 0; /*ACK*/ - return 1; + if (i2c.state == I2C_TRANSMIT || i2c.state == I2C_ACKNOWLEDGE) + return i2c.data; + if (i2c.state == I2C_RECEIVE_WAIT) + return 0; /*ACK*/ + return 1; } void ddc_init(void) { - int c; - uint8_t checksum = 0; + int c; + uint8_t checksum = 0; - for (c = 0; c < 127; c++) - checksum += edid_data[c]; - edid_data[127] = 256 - checksum; + for (c = 0; c < 127; c++) + checksum += edid_data[c]; + edid_data[127] = 256 - checksum; - i2c.clock = 1; - i2c.data = 1; + i2c.clock = 1; + i2c.data = 1; } diff --git a/src/video/vid_ega.c b/src/video/vid_ega.c index 6db9af8b..979f2e5e 100644 --- a/src/video/vid_ega.c +++ b/src/video/vid_ega.c @@ -19,1074 +19,1105 @@ static uint32_t pallook16[256], pallook64[256]; int egaswitchread, egaswitches = 9; /*7=CGA mode (200 lines), 9=EGA mode (350 lines), 8=EGA mode (200 lines)*/ void ega_out(uint16_t addr, uint8_t val, void *p) { - ega_t *ega = (ega_t *)p; - int c; - uint8_t o, old; + ega_t *ega = (ega_t *)p; + int c; + uint8_t o, old; - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(ega->miscout & 1)) - addr ^= 0x60; + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(ega->miscout & 1)) + addr ^= 0x60; - switch (addr) { - case 0x3c0: - if (!ega->attrff) - ega->attraddr = val & 31; - else { - ega->attrregs[ega->attraddr & 31] = val; - if (ega->attraddr < 16) - fullchange = changeframecount; - if (ega->attraddr == 0x10 || ega->attraddr == 0x14 || ega->attraddr < 0x10) { - for (c = 0; c < 16; c++) { - if (ega->attrregs[0x10] & 0x80) - ega->egapal[c] = (ega->attrregs[c] & 0xf) | ((ega->attrregs[0x14] & 0xf) << 4); - else - ega->egapal[c] = (ega->attrregs[c] & 0x3f) | ((ega->attrregs[0x14] & 0xc) << 4); - } - } - } - ega->attrff ^= 1; - break; - case 0x3c2:egaswitchread = val & 0xc; - ega->vres = !(val & 0x80); - ega->pallook = ega->vres ? pallook16 : pallook64; - ega->vidclock = val & 4; /*printf("3C2 write %02X\n",val);*/ - ega->miscout = val; - break; - case 0x3c4:ega->seqaddr = val; - break; - case 0x3c5:o = ega->seqregs[ega->seqaddr & 0xf]; - ega->seqregs[ega->seqaddr & 0xf] = val; - if (o != val && (ega->seqaddr & 0xf) == 1) - ega_recalctimings(ega); - switch (ega->seqaddr & 0xf) { - case 1: - if (ega->scrblank && !(val & 0x20)) - fullchange = 3; - ega->scrblank = (ega->scrblank & ~0x20) | (val & 0x20); - break; - case 2:ega->writemask = val & 0xf; - break; - case 3:ega->charsetb = (((val >> 2) & 3) * 0x10000) + 2; - ega->charseta = ((val & 3) * 0x10000) + 2; - break; - case 4:ega->chain2_write = !(val & 4); - break; - } - break; - case 0x3ce:ega->gdcaddr = val; - break; - case 0x3cf:ega->gdcreg[ega->gdcaddr & 15] = val; - switch (ega->gdcaddr & 15) { - case 2:ega->colourcompare = val; - break; - case 4:ega->readplane = val & 3; - break; - case 5:ega->writemode = val & 3; - ega->readmode = val & 8; - ega->chain2_read = val & 0x10; - break; - case 6: -// pclog("Write mapping %02X\n", val); - switch (val & 0xc) { - case 0x0: /*128k at A0000*/ - mem_mapping_set_addr(&ega->mapping, 0xa0000, 0x20000); - break; - case 0x4: /*64k at A0000*/ - mem_mapping_set_addr(&ega->mapping, 0xa0000, 0x10000); - break; - case 0x8: /*32k at B0000*/ - mem_mapping_set_addr(&ega->mapping, 0xb0000, 0x08000); - break; - case 0xC: /*32k at B8000*/ - mem_mapping_set_addr(&ega->mapping, 0xb8000, 0x08000); - break; - } - break; - case 7:ega->colournocare = val; - break; - } - break; - case 0x3d4:pclog("Write 3d4 %02X %04X:%04X\n", val, CS, cpu_state.pc); - ega->crtcreg = val & 31; - return; - case 0x3d5:pclog("Write 3d5 %02X %02X %02X\n", ega->crtcreg, val, ega->crtc[0x11]); -// if (ega->crtcreg == 1 && val == 0x14) -// fatal("Here\n"); - if (ega->crtcreg <= 7 && ega->crtc[0x11] & 0x80) - return; - old = ega->crtc[ega->crtcreg]; - ega->crtc[ega->crtcreg] = val; - if (old != val) { - if (ega->crtcreg < 0xe || ega->crtcreg > 0x10) { - fullchange = changeframecount; - ega_recalctimings(ega); - } - } - break; - } + switch (addr) { + case 0x3c0: + if (!ega->attrff) + ega->attraddr = val & 31; + else { + ega->attrregs[ega->attraddr & 31] = val; + if (ega->attraddr < 16) + fullchange = changeframecount; + if (ega->attraddr == 0x10 || ega->attraddr == 0x14 || ega->attraddr < 0x10) { + for (c = 0; c < 16; c++) { + if (ega->attrregs[0x10] & 0x80) + ega->egapal[c] = (ega->attrregs[c] & 0xf) | ((ega->attrregs[0x14] & 0xf) << 4); + else + ega->egapal[c] = (ega->attrregs[c] & 0x3f) | ((ega->attrregs[0x14] & 0xc) << 4); + } + } + } + ega->attrff ^= 1; + break; + case 0x3c2: + egaswitchread = val & 0xc; + ega->vres = !(val & 0x80); + ega->pallook = ega->vres ? pallook16 : pallook64; + ega->vidclock = val & 4; /*printf("3C2 write %02X\n",val);*/ + ega->miscout = val; + break; + case 0x3c4: + ega->seqaddr = val; + break; + case 0x3c5: + o = ega->seqregs[ega->seqaddr & 0xf]; + ega->seqregs[ega->seqaddr & 0xf] = val; + if (o != val && (ega->seqaddr & 0xf) == 1) + ega_recalctimings(ega); + switch (ega->seqaddr & 0xf) { + case 1: + if (ega->scrblank && !(val & 0x20)) + fullchange = 3; + ega->scrblank = (ega->scrblank & ~0x20) | (val & 0x20); + break; + case 2: + ega->writemask = val & 0xf; + break; + case 3: + ega->charsetb = (((val >> 2) & 3) * 0x10000) + 2; + ega->charseta = ((val & 3) * 0x10000) + 2; + break; + case 4: + ega->chain2_write = !(val & 4); + break; + } + break; + case 0x3ce: + ega->gdcaddr = val; + break; + case 0x3cf: + ega->gdcreg[ega->gdcaddr & 15] = val; + switch (ega->gdcaddr & 15) { + case 2: + ega->colourcompare = val; + break; + case 4: + ega->readplane = val & 3; + break; + case 5: + ega->writemode = val & 3; + ega->readmode = val & 8; + ega->chain2_read = val & 0x10; + break; + case 6: + // pclog("Write mapping %02X\n", val); + switch (val & 0xc) { + case 0x0: /*128k at A0000*/ + mem_mapping_set_addr(&ega->mapping, 0xa0000, 0x20000); + break; + case 0x4: /*64k at A0000*/ + mem_mapping_set_addr(&ega->mapping, 0xa0000, 0x10000); + break; + case 0x8: /*32k at B0000*/ + mem_mapping_set_addr(&ega->mapping, 0xb0000, 0x08000); + break; + case 0xC: /*32k at B8000*/ + mem_mapping_set_addr(&ega->mapping, 0xb8000, 0x08000); + break; + } + break; + case 7: + ega->colournocare = val; + break; + } + break; + case 0x3d4: + pclog("Write 3d4 %02X %04X:%04X\n", val, CS, cpu_state.pc); + ega->crtcreg = val & 31; + return; + case 0x3d5: + pclog("Write 3d5 %02X %02X %02X\n", ega->crtcreg, val, ega->crtc[0x11]); + // if (ega->crtcreg == 1 && val == 0x14) + // fatal("Here\n"); + if (ega->crtcreg <= 7 && ega->crtc[0x11] & 0x80) + return; + old = ega->crtc[ega->crtcreg]; + ega->crtc[ega->crtcreg] = val; + if (old != val) { + if (ega->crtcreg < 0xe || ega->crtcreg > 0x10) { + fullchange = changeframecount; + ega_recalctimings(ega); + } + } + break; + } } uint8_t ega_in(uint16_t addr, void *p) { - ega_t *ega = (ega_t *)p; + ega_t *ega = (ega_t *)p; - if (addr != 0x3da && addr != 0x3ba) - pclog("ega_in %04X\n", addr); - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(ega->miscout & 1)) - addr ^= 0x60; + if (addr != 0x3da && addr != 0x3ba) + pclog("ega_in %04X\n", addr); + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(ega->miscout & 1)) + addr ^= 0x60; - switch (addr) { - case 0x3c0:return ega->attraddr; - case 0x3c1:return ega->attrregs[ega->attraddr]; - case 0x3c2: -// printf("Read egaswitch %02X %02X %i\n",egaswitchread,egaswitches,VGA); - switch (egaswitchread) { - case 0xc:return (egaswitches & 1) ? 0x10 : 0; - case 0x8:return (egaswitches & 2) ? 0x10 : 0; - case 0x4:return (egaswitches & 4) ? 0x10 : 0; - case 0x0:return (egaswitches & 8) ? 0x10 : 0; - } - break; - case 0x3c4:return ega->seqaddr; - case 0x3c5:return ega->seqregs[ega->seqaddr & 0xf]; - case 0x3ce:return ega->gdcaddr; - case 0x3cf:return ega->gdcreg[ega->gdcaddr & 0xf]; - case 0x3d4:return ega->crtcreg; - case 0x3d5:return ega->crtc[ega->crtcreg]; - case 0x3da:ega->attrff = 0; - ega->stat ^= 0x30; /*Fools IBM EGA video BIOS self-test*/ - return ega->stat; - } -// printf("Bad EGA read %04X %04X:%04X\n",addr,cs>>4,pc); - return 0xff; + switch (addr) { + case 0x3c0: + return ega->attraddr; + case 0x3c1: + return ega->attrregs[ega->attraddr]; + case 0x3c2: + // printf("Read egaswitch %02X %02X %i\n",egaswitchread,egaswitches,VGA); + switch (egaswitchread) { + case 0xc: + return (egaswitches & 1) ? 0x10 : 0; + case 0x8: + return (egaswitches & 2) ? 0x10 : 0; + case 0x4: + return (egaswitches & 4) ? 0x10 : 0; + case 0x0: + return (egaswitches & 8) ? 0x10 : 0; + } + break; + case 0x3c4: + return ega->seqaddr; + case 0x3c5: + return ega->seqregs[ega->seqaddr & 0xf]; + case 0x3ce: + return ega->gdcaddr; + case 0x3cf: + return ega->gdcreg[ega->gdcaddr & 0xf]; + case 0x3d4: + return ega->crtcreg; + case 0x3d5: + return ega->crtc[ega->crtcreg]; + case 0x3da: + ega->attrff = 0; + ega->stat ^= 0x30; /*Fools IBM EGA video BIOS self-test*/ + return ega->stat; + } + // printf("Bad EGA read %04X %04X:%04X\n",addr,cs>>4,pc); + return 0xff; } void ega_recalctimings(ega_t *ega) { - double _dispontime, _dispofftime, disptime; - double crtcconst; + double _dispontime, _dispofftime, disptime; + double crtcconst; - ega->vtotal = ega->crtc[6]; - ega->dispend = ega->crtc[0x12]; - ega->vsyncstart = ega->crtc[0x10]; - ega->split = ega->crtc[0x18]; + ega->vtotal = ega->crtc[6]; + ega->dispend = ega->crtc[0x12]; + ega->vsyncstart = ega->crtc[0x10]; + ega->split = ega->crtc[0x18]; - if (ega->crtc[7] & 1) - ega->vtotal |= 0x100; - if (ega->crtc[7] & 32) - ega->vtotal |= 0x200; - ega->vtotal++; + if (ega->crtc[7] & 1) + ega->vtotal |= 0x100; + if (ega->crtc[7] & 32) + ega->vtotal |= 0x200; + ega->vtotal++; - if (ega->crtc[7] & 2) - ega->dispend |= 0x100; - if (ega->crtc[7] & 64) - ega->dispend |= 0x200; - ega->dispend++; + if (ega->crtc[7] & 2) + ega->dispend |= 0x100; + if (ega->crtc[7] & 64) + ega->dispend |= 0x200; + ega->dispend++; - if (ega->crtc[7] & 4) - ega->vsyncstart |= 0x100; - if (ega->crtc[7] & 128) - ega->vsyncstart |= 0x200; - ega->vsyncstart++; + if (ega->crtc[7] & 4) + ega->vsyncstart |= 0x100; + if (ega->crtc[7] & 128) + ega->vsyncstart |= 0x200; + ega->vsyncstart++; - if (ega->crtc[7] & 0x10) - ega->split |= 0x100; - if (ega->crtc[9] & 0x40) - ega->split |= 0x200; - ega->split += 2; + if (ega->crtc[7] & 0x10) + ega->split |= 0x100; + if (ega->crtc[9] & 0x40) + ega->split |= 0x200; + ega->split += 2; - ega->hdisp = ega->crtc[1]; - ega->hdisp++; + ega->hdisp = ega->crtc[1]; + ega->hdisp++; - ega->rowoffset = ega->crtc[0x13]; + ega->rowoffset = ega->crtc[0x13]; - printf("Recalc! %i %i %i %i %i %02X\n", ega->vtotal, ega->dispend, ega->vsyncstart, ega->split, ega->hdisp, ega->attrregs[0x16]); + printf("Recalc! %i %i %i %i %i %02X\n", ega->vtotal, ega->dispend, ega->vsyncstart, ega->split, ega->hdisp, + ega->attrregs[0x16]); - if (ega->vidclock) - crtcconst = (ega->seqregs[1] & 1) ? MDACONST : (MDACONST * (9.0 / 8.0)); - else - crtcconst = (ega->seqregs[1] & 1) ? CGACONST : (CGACONST * (9.0 / 8.0)); + if (ega->vidclock) + crtcconst = (ega->seqregs[1] & 1) ? MDACONST : (MDACONST * (9.0 / 8.0)); + else + crtcconst = (ega->seqregs[1] & 1) ? CGACONST : (CGACONST * (9.0 / 8.0)); - disptime = ega->crtc[0] + 2; - _dispontime = ega->crtc[1] + 1; + disptime = ega->crtc[0] + 2; + _dispontime = ega->crtc[1] + 1; - printf("Disptime %f dispontime %f hdisp %i\n", disptime, _dispontime, ega->crtc[1] * 8); - if (ega->seqregs[1] & 8) { - disptime *= 2; - _dispontime *= 2; - } - _dispofftime = disptime - _dispontime; - _dispontime *= crtcconst; - _dispofftime *= crtcconst; + printf("Disptime %f dispontime %f hdisp %i\n", disptime, _dispontime, ega->crtc[1] * 8); + if (ega->seqregs[1] & 8) { + disptime *= 2; + _dispontime *= 2; + } + _dispofftime = disptime - _dispontime; + _dispontime *= crtcconst; + _dispofftime *= crtcconst; - ega->dispontime = (uint64_t)_dispontime; - ega->dispofftime = (uint64_t)_dispofftime; - pclog("dispontime %i (%f) dispofftime %i (%f)\n", ega->dispontime, (float)ega->dispontime, - ega->dispofftime, (float)ega->dispofftime); -// printf("EGA horiz total %i display end %i clock rate %i vidclock %i %i\n",crtc[0],crtc[1],egaswitchread,vidclock,((ega3c2>>2)&3) | ((tridentnewctrl2<<2)&4)); -// printf("EGA vert total %i display end %i max row %i vsync %i\n",ega_vtotal,ega_dispend,(crtc[9]&31)+1,ega_vsyncstart); -// printf("total %f on %f cycles off %f cycles frame %f sec %f %02X\n",disptime*crtcconst,dispontime,dispofftime,(dispontime+dispofftime)*ega_vtotal,(dispontime+dispofftime)*ega_vtotal*70,seqregs[1]); + ega->dispontime = (uint64_t)_dispontime; + ega->dispofftime = (uint64_t)_dispofftime; + pclog("dispontime %i (%f) dispofftime %i (%f)\n", ega->dispontime, (float)ega->dispontime, ega->dispofftime, + (float)ega->dispofftime); + // printf("EGA horiz total %i display end %i clock rate %i vidclock %i + // %i\n",crtc[0],crtc[1],egaswitchread,vidclock,((ega3c2>>2)&3) | ((tridentnewctrl2<<2)&4)); printf("EGA vert total + // %i display end %i max row %i vsync %i\n",ega_vtotal,ega_dispend,(crtc[9]&31)+1,ega_vsyncstart); printf("total %f + // on %f cycles off %f cycles frame %f sec %f + // %02X\n",disptime*crtcconst,dispontime,dispofftime,(dispontime+dispofftime)*ega_vtotal,(dispontime+dispofftime)*ega_vtotal*70,seqregs[1]); } static void ega_draw_text(ega_t *ega) { - int x, xx; + int x, xx; - for (x = 0; x < ega->hdisp; x++) { - int drawcursor = ((ega->ma == ega->ca) && ega->con && ega->cursoron); - uint8_t chr = ega->vram[(ega->ma << 1) & ega->vrammask]; - uint8_t attr = ega->vram[((ega->ma << 1) + 1) & ega->vrammask]; - uint8_t dat; - uint32_t fg, bg; - uint32_t charaddr; + for (x = 0; x < ega->hdisp; x++) { + int drawcursor = ((ega->ma == ega->ca) && ega->con && ega->cursoron); + uint8_t chr = ega->vram[(ega->ma << 1) & ega->vrammask]; + uint8_t attr = ega->vram[((ega->ma << 1) + 1) & ega->vrammask]; + uint8_t dat; + uint32_t fg, bg; + uint32_t charaddr; - if (attr & 8) - charaddr = ega->charsetb + (chr * 128); - else - charaddr = ega->charseta + (chr * 128); + if (attr & 8) + charaddr = ega->charsetb + (chr * 128); + else + charaddr = ega->charseta + (chr * 128); - if (drawcursor) { - bg = ega->pallook[ega->egapal[attr & 15]]; - fg = ega->pallook[ega->egapal[attr >> 4]]; - } else { - fg = ega->pallook[ega->egapal[attr & 15]]; - bg = ega->pallook[ega->egapal[attr >> 4]]; - if (attr & 0x80 && ega->attrregs[0x10] & 8) { - bg = ega->pallook[ega->egapal[(attr >> 4) & 7]]; - if (ega->blink & 16) - fg = bg; - } - } + if (drawcursor) { + bg = ega->pallook[ega->egapal[attr & 15]]; + fg = ega->pallook[ega->egapal[attr >> 4]]; + } else { + fg = ega->pallook[ega->egapal[attr & 15]]; + bg = ega->pallook[ega->egapal[attr >> 4]]; + if (attr & 0x80 && ega->attrregs[0x10] & 8) { + bg = ega->pallook[ega->egapal[(attr >> 4) & 7]]; + if (ega->blink & 16) + fg = bg; + } + } - dat = ega->vram[charaddr + (ega->sc << 2)]; - if (ega->seqregs[1] & 8) { - if (ega->seqregs[1] & 1) { - for (xx = 0; xx < 8; xx++) - ((uint32_t *)buffer32->line[ega->displine])[((x << 4) + 32 + (xx << 1)) & 2047] = - ((uint32_t *)buffer32->line[ega->displine])[((x << 4) + 33 + (xx << 1)) & 2047] = (dat & (0x80 >> xx)) ? fg : bg; - } else { - for (xx = 0; xx < 8; xx++) - ((uint32_t *)buffer32->line[ega->displine])[((x * 18) + 32 + (xx << 1)) & 2047] = - ((uint32_t *)buffer32->line[ega->displine])[((x * 18) + 33 + (xx << 1)) & 2047] = (dat & (0x80 >> xx)) ? fg : bg; - if ((chr & ~0x1f) != 0xc0 || !(ega->attrregs[0x10] & 4)) - ((uint32_t *)buffer32->line[ega->displine])[((x * 18) + 32 + 16) & 2047] = - ((uint32_t *)buffer32->line[ega->displine])[((x * 18) + 32 + 17) & 2047] = bg; - else - ((uint32_t *)buffer32->line[ega->displine])[((x * 18) + 32 + 16) & 2047] = - ((uint32_t *)buffer32->line[ega->displine])[((x * 18) + 32 + 17) & 2047] = (dat & 1) ? fg : bg; - } - } else { - if (ega->seqregs[1] & 1) { - for (xx = 0; xx < 8; xx++) - ((uint32_t *)buffer32->line[ega->displine])[((x << 3) + 32 + xx) & 2047] = (dat & (0x80 >> xx)) ? fg : bg; - } else { - for (xx = 0; xx < 8; xx++) - ((uint32_t *)buffer32->line[ega->displine])[((x * 9) + 32 + xx) & 2047] = (dat & (0x80 >> xx)) ? fg : bg; - if ((chr & ~0x1f) != 0xc0 || !(ega->attrregs[0x10] & 4)) - ((uint32_t *)buffer32->line[ega->displine])[((x * 9) + 32 + 8) & 2047] = bg; - else - ((uint32_t *)buffer32->line[ega->displine])[((x * 9) + 32 + 8) & 2047] = (dat & 1) ? fg : bg; - } - } - ega->ma += 4; - ega->ma &= ega->vrammask; - } + dat = ega->vram[charaddr + (ega->sc << 2)]; + if (ega->seqregs[1] & 8) { + if (ega->seqregs[1] & 1) { + for (xx = 0; xx < 8; xx++) + ((uint32_t *)buffer32->line[ega->displine])[((x << 4) + 32 + (xx << 1)) & 2047] = + ((uint32_t *)buffer32->line[ega->displine])[((x << 4) + 33 + (xx << 1)) & 2047] = + (dat & (0x80 >> xx)) ? fg : bg; + } else { + for (xx = 0; xx < 8; xx++) + ((uint32_t *)buffer32->line[ega->displine])[((x * 18) + 32 + (xx << 1)) & 2047] = + ((uint32_t *)buffer32->line[ega->displine])[((x * 18) + 33 + (xx << 1)) & 2047] = + (dat & (0x80 >> xx)) ? fg : bg; + if ((chr & ~0x1f) != 0xc0 || !(ega->attrregs[0x10] & 4)) + ((uint32_t *)buffer32->line[ega->displine])[((x * 18) + 32 + 16) & 2047] = + ((uint32_t *)buffer32->line[ega->displine])[((x * 18) + 32 + 17) & 2047] = bg; + else + ((uint32_t *)buffer32->line[ega->displine])[((x * 18) + 32 + 16) & 2047] = + ((uint32_t *)buffer32->line[ega->displine])[((x * 18) + 32 + 17) & 2047] = + (dat & 1) ? fg : bg; + } + } else { + if (ega->seqregs[1] & 1) { + for (xx = 0; xx < 8; xx++) + ((uint32_t *)buffer32->line[ega->displine])[((x << 3) + 32 + xx) & 2047] = + (dat & (0x80 >> xx)) ? fg : bg; + } else { + for (xx = 0; xx < 8; xx++) + ((uint32_t *)buffer32->line[ega->displine])[((x * 9) + 32 + xx) & 2047] = + (dat & (0x80 >> xx)) ? fg : bg; + if ((chr & ~0x1f) != 0xc0 || !(ega->attrregs[0x10] & 4)) + ((uint32_t *)buffer32->line[ega->displine])[((x * 9) + 32 + 8) & 2047] = bg; + else + ((uint32_t *)buffer32->line[ega->displine])[((x * 9) + 32 + 8) & 2047] = + (dat & 1) ? fg : bg; + } + } + ega->ma += 4; + ega->ma &= ega->vrammask; + } } static void ega_draw_2bpp(ega_t *ega) { - int x; - int offset = ((8 - ega->scrollcache) << 1) + 16; + int x; + int offset = ((8 - ega->scrollcache) << 1) + 16; - for (x = 0; x <= ega->hdisp; x++) { - uint8_t edat[2]; - uint32_t addr = ega->ma; + for (x = 0; x <= ega->hdisp; x++) { + uint8_t edat[2]; + uint32_t addr = ega->ma; - if (!(ega->crtc[0x17] & 0x40)) { - addr = (addr << 1) & ega->vrammask; - addr &= ~7; - if ((ega->crtc[0x17] & 0x20) && (ega->ma & 0x20000)) - addr |= 4; - if (!(ega->crtc[0x17] & 0x20) && (ega->ma & 0x8000)) - addr |= 4; - } - if (!(ega->crtc[0x17] & 0x01)) - addr = (addr & ~0x8000) | ((ega->sc & 1) ? 0x8000 : 0); - if (!(ega->crtc[0x17] & 0x02)) - addr = (addr & ~0x10000) | ((ega->sc & 2) ? 0x10000 : 0); + if (!(ega->crtc[0x17] & 0x40)) { + addr = (addr << 1) & ega->vrammask; + addr &= ~7; + if ((ega->crtc[0x17] & 0x20) && (ega->ma & 0x20000)) + addr |= 4; + if (!(ega->crtc[0x17] & 0x20) && (ega->ma & 0x8000)) + addr |= 4; + } + if (!(ega->crtc[0x17] & 0x01)) + addr = (addr & ~0x8000) | ((ega->sc & 1) ? 0x8000 : 0); + if (!(ega->crtc[0x17] & 0x02)) + addr = (addr & ~0x10000) | ((ega->sc & 2) ? 0x10000 : 0); - edat[0] = ega->vram[addr]; - edat[1] = ega->vram[addr | 0x1]; - if (ega->seqregs[1] & 4) - ega->ma += 2; - else - ega->ma += 4; + edat[0] = ega->vram[addr]; + edat[1] = ega->vram[addr | 0x1]; + if (ega->seqregs[1] & 4) + ega->ma += 2; + else + ega->ma += 4; - ega->ma &= ega->vrammask; + ega->ma &= ega->vrammask; - ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 14 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 15 + offset] = ega->pallook[ega->egapal[edat[1] & 3]]; - ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 12 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 13 + offset] = - ega->pallook[ega->egapal[(edat[1] >> 2) & 3]]; - ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 10 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 11 + offset] = - ega->pallook[ega->egapal[(edat[1] >> 4) & 3]]; - ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 8 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 9 + offset] = ega->pallook[ega->egapal[(edat[1] >> 6) & 3]]; - ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 6 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 7 + offset] = ega->pallook[ega->egapal[(edat[0] >> 0) & 3]]; - ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 4 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 5 + offset] = ega->pallook[ega->egapal[(edat[0] >> 2) & 3]]; - ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 2 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 3 + offset] = ega->pallook[ega->egapal[(edat[0] >> 4) & 3]]; - ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 1 + offset] = ega->pallook[ega->egapal[(edat[0] >> 6) & 3]]; - } + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 14 + offset] = + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 15 + offset] = + ega->pallook[ega->egapal[edat[1] & 3]]; + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 12 + offset] = + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 13 + offset] = + ega->pallook[ega->egapal[(edat[1] >> 2) & 3]]; + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 10 + offset] = + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 11 + offset] = + ega->pallook[ega->egapal[(edat[1] >> 4) & 3]]; + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 8 + offset] = + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 9 + offset] = + ega->pallook[ega->egapal[(edat[1] >> 6) & 3]]; + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 6 + offset] = + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 7 + offset] = + ega->pallook[ega->egapal[(edat[0] >> 0) & 3]]; + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 4 + offset] = + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 5 + offset] = + ega->pallook[ega->egapal[(edat[0] >> 2) & 3]]; + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 2 + offset] = + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 3 + offset] = + ega->pallook[ega->egapal[(edat[0] >> 4) & 3]]; + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + offset] = + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 1 + offset] = + ega->pallook[ega->egapal[(edat[0] >> 6) & 3]]; + } } static void ega_draw_4bpp_lowres(ega_t *ega) { - int x; - int offset = ((8 - ega->scrollcache) << 1) + 16; + int x; + int offset = ((8 - ega->scrollcache) << 1) + 16; - for (x = 0; x <= ega->hdisp; x++) { - uint8_t edat[4]; - uint8_t dat; - uint32_t addr = ega->ma; - int oddeven = 0; + for (x = 0; x <= ega->hdisp; x++) { + uint8_t edat[4]; + uint8_t dat; + uint32_t addr = ega->ma; + int oddeven = 0; - if (!(ega->crtc[0x17] & 0x40)) { - addr = (addr << 1) & ega->vrammask; - if (ega->seqregs[1] & 4) - oddeven = (addr & 4) ? 1 : 0; - addr &= ~7; - if ((ega->crtc[0x17] & 0x20) && (ega->ma & 0x20000)) - addr |= 4; - if (!(ega->crtc[0x17] & 0x20) && (ega->ma & 0x8000)) - addr |= 4; - } - if (!(ega->crtc[0x17] & 0x01)) - addr = (addr & ~0x8000) | ((ega->sc & 1) ? 0x8000 : 0); - if (!(ega->crtc[0x17] & 0x02)) - addr = (addr & ~0x10000) | ((ega->sc & 2) ? 0x10000 : 0); + if (!(ega->crtc[0x17] & 0x40)) { + addr = (addr << 1) & ega->vrammask; + if (ega->seqregs[1] & 4) + oddeven = (addr & 4) ? 1 : 0; + addr &= ~7; + if ((ega->crtc[0x17] & 0x20) && (ega->ma & 0x20000)) + addr |= 4; + if (!(ega->crtc[0x17] & 0x20) && (ega->ma & 0x8000)) + addr |= 4; + } + if (!(ega->crtc[0x17] & 0x01)) + addr = (addr & ~0x8000) | ((ega->sc & 1) ? 0x8000 : 0); + if (!(ega->crtc[0x17] & 0x02)) + addr = (addr & ~0x10000) | ((ega->sc & 2) ? 0x10000 : 0); - if (ega->seqregs[1] & 4) { - edat[0] = ega->vram[addr | oddeven]; - edat[2] = ega->vram[addr | oddeven | 0x2]; - edat[1] = edat[3] = 0; - ega->ma += 2; - } else { - edat[0] = ega->vram[addr]; - edat[1] = ega->vram[addr | 0x1]; - edat[2] = ega->vram[addr | 0x2]; - edat[3] = ega->vram[addr | 0x3]; - ega->ma += 4; - } - ega->ma &= ega->vrammask; + if (ega->seqregs[1] & 4) { + edat[0] = ega->vram[addr | oddeven]; + edat[2] = ega->vram[addr | oddeven | 0x2]; + edat[1] = edat[3] = 0; + ega->ma += 2; + } else { + edat[0] = ega->vram[addr]; + edat[1] = ega->vram[addr | 0x1]; + edat[2] = ega->vram[addr | 0x2]; + edat[3] = ega->vram[addr | 0x3]; + ega->ma += 4; + } + ega->ma &= ega->vrammask; - dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); - ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 14 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 15 + offset] = ega->pallook[ega->egapal[(dat & 0xf) - & ega->attrregs[0x12]]]; - ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 12 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 13 + offset] = ega->pallook[ega->egapal[(dat >> 4) - & ega->attrregs[0x12]]]; - dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); - ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 10 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 11 + offset] = ega->pallook[ega->egapal[(dat & 0xf) - & ega->attrregs[0x12]]]; - ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 8 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 9 + offset] = ega->pallook[ega->egapal[(dat >> 4) - & ega->attrregs[0x12]]]; - dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); - ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 6 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 7 + offset] = ega->pallook[ega->egapal[(dat & 0xf) - & ega->attrregs[0x12]]]; - ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 4 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 5 + offset] = ega->pallook[ega->egapal[(dat >> 4) - & ega->attrregs[0x12]]]; - dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); - ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 2 + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 3 + offset] = ega->pallook[ega->egapal[(dat & 0xf) - & ega->attrregs[0x12]]]; - ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + offset] = ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 1 + offset] = ega->pallook[ega->egapal[(dat >> 4) - & ega->attrregs[0x12]]]; - } + dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 14 + offset] = + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 15 + offset] = + ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 12 + offset] = + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 13 + offset] = + ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; + dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | + (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 10 + offset] = + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 11 + offset] = + ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 8 + offset] = + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 9 + offset] = + ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; + dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | + (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 6 + offset] = + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 7 + offset] = + ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 4 + offset] = + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 5 + offset] = + ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; + dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 2 + offset] = + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 3 + offset] = + ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + offset] = + ((uint32_t *)buffer32->line[ega->displine])[(x << 4) + 1 + offset] = + ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; + } } static void ega_draw_4bpp_highres(ega_t *ega) { - int x; - int offset = (8 - ega->scrollcache) + 24; + int x; + int offset = (8 - ega->scrollcache) + 24; - for (x = 0; x <= ega->hdisp; x++) { - uint8_t edat[4]; - uint8_t dat; - uint32_t addr = ega->ma; - int oddeven = 0; + for (x = 0; x <= ega->hdisp; x++) { + uint8_t edat[4]; + uint8_t dat; + uint32_t addr = ega->ma; + int oddeven = 0; - if (!(ega->crtc[0x17] & 0x40)) { - addr = (addr << 1) & ega->vrammask; - if (ega->seqregs[1] & 4) - oddeven = (addr & 4) ? 1 : 0; - addr &= ~7; - if ((ega->crtc[0x17] & 0x20) && (ega->ma & 0x20000)) - addr |= 4; - if (!(ega->crtc[0x17] & 0x20) && (ega->ma & 0x8000)) - addr |= 4; - } - if (!(ega->crtc[0x17] & 0x01)) - addr = (addr & ~0x8000) | ((ega->sc & 1) ? 0x8000 : 0); - if (!(ega->crtc[0x17] & 0x02)) - addr = (addr & ~0x10000) | ((ega->sc & 2) ? 0x10000 : 0); + if (!(ega->crtc[0x17] & 0x40)) { + addr = (addr << 1) & ega->vrammask; + if (ega->seqregs[1] & 4) + oddeven = (addr & 4) ? 1 : 0; + addr &= ~7; + if ((ega->crtc[0x17] & 0x20) && (ega->ma & 0x20000)) + addr |= 4; + if (!(ega->crtc[0x17] & 0x20) && (ega->ma & 0x8000)) + addr |= 4; + } + if (!(ega->crtc[0x17] & 0x01)) + addr = (addr & ~0x8000) | ((ega->sc & 1) ? 0x8000 : 0); + if (!(ega->crtc[0x17] & 0x02)) + addr = (addr & ~0x10000) | ((ega->sc & 2) ? 0x10000 : 0); - if (ega->seqregs[1] & 4) { - edat[0] = ega->vram[addr | oddeven]; - edat[2] = ega->vram[addr | oddeven | 0x2]; - edat[1] = edat[3] = 0; - ega->ma += 2; - } else { - edat[0] = ega->vram[addr]; - edat[1] = ega->vram[addr | 0x1]; - edat[2] = ega->vram[addr | 0x2]; - edat[3] = ega->vram[addr | 0x3]; - ega->ma += 4; - } - ega->ma &= ega->vrammask; + if (ega->seqregs[1] & 4) { + edat[0] = ega->vram[addr | oddeven]; + edat[2] = ega->vram[addr | oddeven | 0x2]; + edat[1] = edat[3] = 0; + ega->ma += 2; + } else { + edat[0] = ega->vram[addr]; + edat[1] = ega->vram[addr | 0x1]; + edat[2] = ega->vram[addr | 0x2]; + edat[3] = ega->vram[addr | 0x3]; + ega->ma += 4; + } + ega->ma &= ega->vrammask; - dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); - ((uint32_t *)buffer32->line[ega->displine])[(x << 3) + 7 + offset] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; - ((uint32_t *)buffer32->line[ega->displine])[(x << 3) + 6 + offset] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; - dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); - ((uint32_t *)buffer32->line[ega->displine])[(x << 3) + 5 + offset] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; - ((uint32_t *)buffer32->line[ega->displine])[(x << 3) + 4 + offset] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; - dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); - ((uint32_t *)buffer32->line[ega->displine])[(x << 3) + 3 + offset] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; - ((uint32_t *)buffer32->line[ega->displine])[(x << 3) + 2 + offset] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; - dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); - ((uint32_t *)buffer32->line[ega->displine])[(x << 3) + 1 + offset] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; - ((uint32_t *)buffer32->line[ega->displine])[(x << 3) + offset] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; - } + dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); + ((uint32_t *)buffer32->line[ega->displine])[(x << 3) + 7 + offset] = + ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[ega->displine])[(x << 3) + 6 + offset] = + ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; + dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | + (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); + ((uint32_t *)buffer32->line[ega->displine])[(x << 3) + 5 + offset] = + ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[ega->displine])[(x << 3) + 4 + offset] = + ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; + dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | + (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); + ((uint32_t *)buffer32->line[ega->displine])[(x << 3) + 3 + offset] = + ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[ega->displine])[(x << 3) + 2 + offset] = + ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; + dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); + ((uint32_t *)buffer32->line[ega->displine])[(x << 3) + 1 + offset] = + ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[ega->displine])[(x << 3) + offset] = + ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; + } } void ega_poll(void *p) { - ega_t *ega = (ega_t *)p; - int x, xx; + ega_t *ega = (ega_t *)p; + int x, xx; - if (!ega->linepos) { - timer_advance_u64(&ega->timer, ega->dispofftime); + if (!ega->linepos) { + timer_advance_u64(&ega->timer, ega->dispofftime); - ega->stat |= 1; - ega->linepos = 1; + ega->stat |= 1; + ega->linepos = 1; - if (ega->dispon) { - if (ega->firstline == 2000) { - ega->firstline = ega->displine; - video_wait_for_buffer(); - } + if (ega->dispon) { + if (ega->firstline == 2000) { + ega->firstline = ega->displine; + video_wait_for_buffer(); + } - if (ega->scrblank) { - for (x = 0; x < ega->hdisp; x++) { - switch (ega->seqregs[1] & 9) { - case 0: - for (xx = 0; xx < 9; xx++) - ((uint32_t *)buffer32->line[ega->displine])[(x * 9) + xx + 32] = 0; - break; - case 1: - for (xx = 0; xx < 8; xx++) - ((uint32_t *)buffer32->line[ega->displine])[(x * 8) + xx + 32] = 0; - break; - case 8: - for (xx = 0; xx < 18; xx++) - ((uint32_t *)buffer32->line[ega->displine])[(x * 18) + xx + 32] = 0; - break; - case 9: - for (xx = 0; xx < 16; xx++) - ((uint32_t *)buffer32->line[ega->displine])[(x * 16) + xx + 32] = 0; - break; - } - } - } else if (!(ega->gdcreg[6] & 1)) { - if (fullchange) - ega_draw_text(ega); - } else { - switch (ega->gdcreg[5] & 0x20) { - case 0x00: - if (ega->seqregs[1] & 8) - ega_draw_4bpp_lowres(ega); - else - ega_draw_4bpp_highres(ega); - break; - case 0x20:ega_draw_2bpp(ega); - break; - } - } - if (ega->lastline < ega->displine) - ega->lastline = ega->displine; - } + if (ega->scrblank) { + for (x = 0; x < ega->hdisp; x++) { + switch (ega->seqregs[1] & 9) { + case 0: + for (xx = 0; xx < 9; xx++) + ((uint32_t *)buffer32->line[ega->displine])[(x * 9) + xx + 32] = 0; + break; + case 1: + for (xx = 0; xx < 8; xx++) + ((uint32_t *)buffer32->line[ega->displine])[(x * 8) + xx + 32] = 0; + break; + case 8: + for (xx = 0; xx < 18; xx++) + ((uint32_t *)buffer32->line[ega->displine])[(x * 18) + xx + 32] = 0; + break; + case 9: + for (xx = 0; xx < 16; xx++) + ((uint32_t *)buffer32->line[ega->displine])[(x * 16) + xx + 32] = 0; + break; + } + } + } else if (!(ega->gdcreg[6] & 1)) { + if (fullchange) + ega_draw_text(ega); + } else { + switch (ega->gdcreg[5] & 0x20) { + case 0x00: + if (ega->seqregs[1] & 8) + ega_draw_4bpp_lowres(ega); + else + ega_draw_4bpp_highres(ega); + break; + case 0x20: + ega_draw_2bpp(ega); + break; + } + } + if (ega->lastline < ega->displine) + ega->lastline = ega->displine; + } - ega->displine++; - if ((ega->stat & 8) && ((ega->displine & 15) == (ega->crtc[0x11] & 15)) && ega->vslines) - ega->stat &= ~8; - ega->vslines++; - if (ega->displine > 500) - ega->displine = 0; - } else { - timer_advance_u64(&ega->timer, ega->dispontime); -// if (output) printf("Display on %f\n",vidtime); - if (ega->dispon) - ega->stat &= ~1; - ega->linepos = 0; - if (ega->sc == (ega->crtc[11] & 31)) - ega->con = 0; - if (ega->dispon) { - if (ega->sc == (ega->crtc[9] & 31)) { - ega->sc = 0; - if (ega->sc == (ega->crtc[11] & 31)) - ega->con = 0; + ega->displine++; + if ((ega->stat & 8) && ((ega->displine & 15) == (ega->crtc[0x11] & 15)) && ega->vslines) + ega->stat &= ~8; + ega->vslines++; + if (ega->displine > 500) + ega->displine = 0; + } else { + timer_advance_u64(&ega->timer, ega->dispontime); + // if (output) printf("Display on %f\n",vidtime); + if (ega->dispon) + ega->stat &= ~1; + ega->linepos = 0; + if (ega->sc == (ega->crtc[11] & 31)) + ega->con = 0; + if (ega->dispon) { + if (ega->sc == (ega->crtc[9] & 31)) { + ega->sc = 0; + if (ega->sc == (ega->crtc[11] & 31)) + ega->con = 0; - ega->maback += (ega->rowoffset << 3); - ega->maback &= ega->vrammask; - ega->ma = ega->maback; - } else { - ega->sc++; - ega->sc &= 31; - ega->ma = ega->maback; - } - } - ega->vc++; - ega->vc &= 1023; -// printf("Line now %i %i ma %05X\n",vc,displine,ma); - if (ega->vc == ega->split) { -// printf("Split at line %i %i\n",displine,vc); - ega->ma = ega->maback = 0; - if (ega->attrregs[0x10] & 0x20) - ega->scrollcache = 0; - } - if (ega->vc == ega->dispend) { -// printf("Display over at line %i %i\n",displine,vc); - ega->dispon = 0; - if (ega->crtc[10] & 0x20) - ega->cursoron = 0; - else - ega->cursoron = ega->blink & 16; - if (!(ega->gdcreg[6] & 1) && !(ega->blink & 15)) - fullchange = 2; - ega->blink++; + ega->maback += (ega->rowoffset << 3); + ega->maback &= ega->vrammask; + ega->ma = ega->maback; + } else { + ega->sc++; + ega->sc &= 31; + ega->ma = ega->maback; + } + } + ega->vc++; + ega->vc &= 1023; + // printf("Line now %i %i ma %05X\n",vc,displine,ma); + if (ega->vc == ega->split) { + // printf("Split at line %i %i\n",displine,vc); + ega->ma = ega->maback = 0; + if (ega->attrregs[0x10] & 0x20) + ega->scrollcache = 0; + } + if (ega->vc == ega->dispend) { + // printf("Display over at line %i %i\n",displine,vc); + ega->dispon = 0; + if (ega->crtc[10] & 0x20) + ega->cursoron = 0; + else + ega->cursoron = ega->blink & 16; + if (!(ega->gdcreg[6] & 1) && !(ega->blink & 15)) + fullchange = 2; + ega->blink++; - if (fullchange) - fullchange--; - } - if (ega->vc == ega->vsyncstart) { - ega->dispon = 0; -// printf("Vsync on at line %i %i\n",displine,vc); - ega->stat |= 8; - if (ega->seqregs[1] & 8) - x = ega->hdisp * ((ega->seqregs[1] & 1) ? 8 : 9) * 2; - else - x = ega->hdisp * ((ega->seqregs[1] & 1) ? 8 : 9); -// pclog("Cursor %02X %02X\n",crtc[10],crtc[11]); -// pclog("Firstline %i Lastline %i wx %i %i\n",firstline,lastline,wx,oddeven); -// doblit(); - if (x != xsize || (ega->lastline - ega->firstline) != ysize) { - xsize = x; - ysize = ega->lastline - ega->firstline; - if (xsize < 64) - xsize = 656; - if (ysize < 32) - ysize = 200; - if (ega->vres || ysize <= 200) - updatewindowsize(xsize, ysize << 1); - else - updatewindowsize(xsize, ysize); - } + if (fullchange) + fullchange--; + } + if (ega->vc == ega->vsyncstart) { + ega->dispon = 0; + // printf("Vsync on at line %i %i\n",displine,vc); + ega->stat |= 8; + if (ega->seqregs[1] & 8) + x = ega->hdisp * ((ega->seqregs[1] & 1) ? 8 : 9) * 2; + else + x = ega->hdisp * ((ega->seqregs[1] & 1) ? 8 : 9); + // pclog("Cursor %02X %02X\n",crtc[10],crtc[11]); + // pclog("Firstline %i Lastline %i wx %i %i\n",firstline,lastline,wx,oddeven); + // doblit(); + if (x != xsize || (ega->lastline - ega->firstline) != ysize) { + xsize = x; + ysize = ega->lastline - ega->firstline; + if (xsize < 64) + xsize = 656; + if (ysize < 32) + ysize = 200; + if (ega->vres || ysize <= 200) + updatewindowsize(xsize, ysize << 1); + else + updatewindowsize(xsize, ysize); + } - video_blit_memtoscreen(32, 0, ega->firstline, ega->lastline, xsize, ega->lastline - ega->firstline); + video_blit_memtoscreen(32, 0, ega->firstline, ega->lastline, xsize, ega->lastline - ega->firstline); - ega->frames++; - ega->video_res_x = xsize; - ega->video_res_y = ysize + 1; - if (!(ega->gdcreg[6] & 1)) /*Text mode*/ - { - ega->video_res_x /= (ega->seqregs[1] & 1) ? 8 : 9; - ega->video_res_y /= (ega->crtc[9] & 31) + 1; - ega->video_bpp = 0; - } else { - if (ega->crtc[9] & 0x80) - ega->video_res_y /= 2; - if (!(ega->crtc[0x17] & 1)) - ega->video_res_y *= 2; - ega->video_res_y /= (ega->crtc[9] & 31) + 1; - if (ega->seqregs[1] & 8) - ega->video_res_x /= 2; - ega->video_bpp = (ega->gdcreg[5] & 0x20) ? 2 : 4; - } + ega->frames++; + ega->video_res_x = xsize; + ega->video_res_y = ysize + 1; + if (!(ega->gdcreg[6] & 1)) /*Text mode*/ + { + ega->video_res_x /= (ega->seqregs[1] & 1) ? 8 : 9; + ega->video_res_y /= (ega->crtc[9] & 31) + 1; + ega->video_bpp = 0; + } else { + if (ega->crtc[9] & 0x80) + ega->video_res_y /= 2; + if (!(ega->crtc[0x17] & 1)) + ega->video_res_y *= 2; + ega->video_res_y /= (ega->crtc[9] & 31) + 1; + if (ega->seqregs[1] & 8) + ega->video_res_x /= 2; + ega->video_bpp = (ega->gdcreg[5] & 0x20) ? 2 : 4; + } -// wakeupblit(); - readflash = 0; - //framecount++; - ega->firstline = 2000; - ega->lastline = 0; + // wakeupblit(); + readflash = 0; + // framecount++; + ega->firstline = 2000; + ega->lastline = 0; - ega->maback = ega->ma = (ega->crtc[0xc] << 8) | ega->crtc[0xd]; - ega->ca = (ega->crtc[0xe] << 8) | ega->crtc[0xf]; - ega->ma <<= 2; - ega->maback <<= 2; - ega->ca <<= 2; - changeframecount = 2; - ega->vslines = 0; - } - if (ega->vc == ega->vtotal) { - ega->vc = 0; - ega->sc = ega->crtc[8] & 0x1f; - ega->dispon = 1; - ega->displine = 0; - ega->scrollcache = ega->attrregs[0x13] & 7; - } - if (ega->sc == (ega->crtc[10] & 31)) - ega->con = 1; - } + ega->maback = ega->ma = (ega->crtc[0xc] << 8) | ega->crtc[0xd]; + ega->ca = (ega->crtc[0xe] << 8) | ega->crtc[0xf]; + ega->ma <<= 2; + ega->maback <<= 2; + ega->ca <<= 2; + changeframecount = 2; + ega->vslines = 0; + } + if (ega->vc == ega->vtotal) { + ega->vc = 0; + ega->sc = ega->crtc[8] & 0x1f; + ega->dispon = 1; + ega->displine = 0; + ega->scrollcache = ega->attrregs[0x13] & 7; + } + if (ega->sc == (ega->crtc[10] & 31)) + ega->con = 1; + } } void ega_write(uint32_t addr, uint8_t val, void *p) { - ega_t *ega = (ega_t *)p; - uint8_t vala, valb, valc, vald; - int writemask2 = ega->writemask; + ega_t *ega = (ega_t *)p; + uint8_t vala, valb, valc, vald; + int writemask2 = ega->writemask; - egawrites++; - cycles -= video_timing_write_b; - cycles_lost += video_timing_write_b; + egawrites++; + cycles -= video_timing_write_b; + cycles_lost += video_timing_write_b; - if (addr >= 0xB0000) - addr &= 0x7fff; - else - addr &= 0xffff; + if (addr >= 0xB0000) + addr &= 0x7fff; + else + addr &= 0xffff; - if (ega->chain2_write) { - writemask2 &= ~0xa; - if (addr & 1) - writemask2 <<= 1; - addr &= ~1; - if (addr & 0x4000) - addr |= 1; - addr &= ~0x4000; - } + if (ega->chain2_write) { + writemask2 &= ~0xa; + if (addr & 1) + writemask2 <<= 1; + addr &= ~1; + if (addr & 0x4000) + addr |= 1; + addr &= ~0x4000; + } - addr <<= 2; + addr <<= 2; - if (addr >= ega->vram_limit) - return; + if (addr >= ega->vram_limit) + return; - if (!(ega->gdcreg[6] & 1)) - fullchange = 2; + if (!(ega->gdcreg[6] & 1)) + fullchange = 2; -// pclog("%i %08X %i %i %02X %02X %02X %02X %02X\n",chain4,addr,writemode,writemask,gdcreg[8],vram[0],vram[1],vram[2],vram[3]); - switch (ega->writemode) { - case 1: - if (writemask2 & 1) - ega->vram[addr] = ega->la; - if (writemask2 & 2) - ega->vram[addr | 0x1] = ega->lb; - if (writemask2 & 4) - ega->vram[addr | 0x2] = ega->lc; - if (writemask2 & 8) - ega->vram[addr | 0x3] = ega->ld; - break; - case 0: - if (ega->gdcreg[3] & 7) - val = ega_rotate[ega->gdcreg[3] & 7][val]; + // pclog("%i %08X %i %i %02X %02X %02X %02X + // %02X\n",chain4,addr,writemode,writemask,gdcreg[8],vram[0],vram[1],vram[2],vram[3]); + switch (ega->writemode) { + case 1: + if (writemask2 & 1) + ega->vram[addr] = ega->la; + if (writemask2 & 2) + ega->vram[addr | 0x1] = ega->lb; + if (writemask2 & 4) + ega->vram[addr | 0x2] = ega->lc; + if (writemask2 & 8) + ega->vram[addr | 0x3] = ega->ld; + break; + case 0: + if (ega->gdcreg[3] & 7) + val = ega_rotate[ega->gdcreg[3] & 7][val]; - if (ega->gdcreg[8] == 0xff && !(ega->gdcreg[3] & 0x18) && !ega->gdcreg[1]) { - if (writemask2 & 1) - ega->vram[addr] = val; - if (writemask2 & 2) - ega->vram[addr | 0x1] = val; - if (writemask2 & 4) - ega->vram[addr | 0x2] = val; - if (writemask2 & 8) - ega->vram[addr | 0x3] = val; - } else { - if (ega->gdcreg[1] & 1) - vala = (ega->gdcreg[0] & 1) ? 0xff : 0; - else - vala = val; - if (ega->gdcreg[1] & 2) - valb = (ega->gdcreg[0] & 2) ? 0xff : 0; - else - valb = val; - if (ega->gdcreg[1] & 4) - valc = (ega->gdcreg[0] & 4) ? 0xff : 0; - else - valc = val; - if (ega->gdcreg[1] & 8) - vald = (ega->gdcreg[0] & 8) ? 0xff : 0; - else - vald = val; -// pclog("Write %02X %01X %02X %02X %02X %02X %02X\n",gdcreg[3]&0x18,writemask,vala,valb,valc,vald,gdcreg[8]); - switch (ega->gdcreg[3] & 0x18) { - case 0: /*Set*/ - if (writemask2 & 1) - ega->vram[addr] = (vala & ega->gdcreg[8]) | (ega->la & ~ega->gdcreg[8]); - if (writemask2 & 2) - ega->vram[addr | 0x1] = (valb & ega->gdcreg[8]) | (ega->lb & ~ega->gdcreg[8]); - if (writemask2 & 4) - ega->vram[addr | 0x2] = (valc & ega->gdcreg[8]) | (ega->lc & ~ega->gdcreg[8]); - if (writemask2 & 8) - ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) | (ega->ld & ~ega->gdcreg[8]); - break; - case 8: /*AND*/ - if (writemask2 & 1) - ega->vram[addr] = (vala | ~ega->gdcreg[8]) & ega->la; - if (writemask2 & 2) - ega->vram[addr | 0x1] = (valb | ~ega->gdcreg[8]) & ega->lb; - if (writemask2 & 4) - ega->vram[addr | 0x2] = (valc | ~ega->gdcreg[8]) & ega->lc; - if (writemask2 & 8) - ega->vram[addr | 0x3] = (vald | ~ega->gdcreg[8]) & ega->ld; - break; - case 0x10: /*OR*/ - if (writemask2 & 1) - ega->vram[addr] = (vala & ega->gdcreg[8]) | ega->la; - if (writemask2 & 2) - ega->vram[addr | 0x1] = (valb & ega->gdcreg[8]) | ega->lb; - if (writemask2 & 4) - ega->vram[addr | 0x2] = (valc & ega->gdcreg[8]) | ega->lc; - if (writemask2 & 8) - ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) | ega->ld; - break; - case 0x18: /*XOR*/ - if (writemask2 & 1) - ega->vram[addr] = (vala & ega->gdcreg[8]) ^ ega->la; - if (writemask2 & 2) - ega->vram[addr | 0x1] = (valb & ega->gdcreg[8]) ^ ega->lb; - if (writemask2 & 4) - ega->vram[addr | 0x2] = (valc & ega->gdcreg[8]) ^ ega->lc; - if (writemask2 & 8) - ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) ^ ega->ld; - break; - } -// pclog("- %02X %02X %02X %02X %08X\n",vram[addr],vram[addr|0x1],vram[addr|0x2],vram[addr|0x3],addr); - } - break; - case 2: - if (!(ega->gdcreg[3] & 0x18) && !ega->gdcreg[1]) { - if (writemask2 & 1) - ega->vram[addr] = (((val & 1) ? 0xff : 0) & ega->gdcreg[8]) | (ega->la & ~ega->gdcreg[8]); - if (writemask2 & 2) - ega->vram[addr | 0x1] = (((val & 2) ? 0xff : 0) & ega->gdcreg[8]) | (ega->lb & ~ega->gdcreg[8]); - if (writemask2 & 4) - ega->vram[addr | 0x2] = (((val & 4) ? 0xff : 0) & ega->gdcreg[8]) | (ega->lc & ~ega->gdcreg[8]); - if (writemask2 & 8) - ega->vram[addr | 0x3] = (((val & 8) ? 0xff : 0) & ega->gdcreg[8]) | (ega->ld & ~ega->gdcreg[8]); - } else { - vala = ((val & 1) ? 0xff : 0); - valb = ((val & 2) ? 0xff : 0); - valc = ((val & 4) ? 0xff : 0); - vald = ((val & 8) ? 0xff : 0); - switch (ega->gdcreg[3] & 0x18) { - case 0: /*Set*/ - if (writemask2 & 1) - ega->vram[addr] = (vala & ega->gdcreg[8]) | (ega->la & ~ega->gdcreg[8]); - if (writemask2 & 2) - ega->vram[addr | 0x1] = (valb & ega->gdcreg[8]) | (ega->lb & ~ega->gdcreg[8]); - if (writemask2 & 4) - ega->vram[addr | 0x2] = (valc & ega->gdcreg[8]) | (ega->lc & ~ega->gdcreg[8]); - if (writemask2 & 8) - ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) | (ega->ld & ~ega->gdcreg[8]); - break; - case 8: /*AND*/ - if (writemask2 & 1) - ega->vram[addr] = (vala | ~ega->gdcreg[8]) & ega->la; - if (writemask2 & 2) - ega->vram[addr | 0x1] = (valb | ~ega->gdcreg[8]) & ega->lb; - if (writemask2 & 4) - ega->vram[addr | 0x2] = (valc | ~ega->gdcreg[8]) & ega->lc; - if (writemask2 & 8) - ega->vram[addr | 0x3] = (vald | ~ega->gdcreg[8]) & ega->ld; - break; - case 0x10: /*OR*/ - if (writemask2 & 1) - ega->vram[addr] = (vala & ega->gdcreg[8]) | ega->la; - if (writemask2 & 2) - ega->vram[addr | 0x1] = (valb & ega->gdcreg[8]) | ega->lb; - if (writemask2 & 4) - ega->vram[addr | 0x2] = (valc & ega->gdcreg[8]) | ega->lc; - if (writemask2 & 8) - ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) | ega->ld; - break; - case 0x18: /*XOR*/ - if (writemask2 & 1) - ega->vram[addr] = (vala & ega->gdcreg[8]) ^ ega->la; - if (writemask2 & 2) - ega->vram[addr | 0x1] = (valb & ega->gdcreg[8]) ^ ega->lb; - if (writemask2 & 4) - ega->vram[addr | 0x2] = (valc & ega->gdcreg[8]) ^ ega->lc; - if (writemask2 & 8) - ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) ^ ega->ld; - break; - } - } - break; - } + if (ega->gdcreg[8] == 0xff && !(ega->gdcreg[3] & 0x18) && !ega->gdcreg[1]) { + if (writemask2 & 1) + ega->vram[addr] = val; + if (writemask2 & 2) + ega->vram[addr | 0x1] = val; + if (writemask2 & 4) + ega->vram[addr | 0x2] = val; + if (writemask2 & 8) + ega->vram[addr | 0x3] = val; + } else { + if (ega->gdcreg[1] & 1) + vala = (ega->gdcreg[0] & 1) ? 0xff : 0; + else + vala = val; + if (ega->gdcreg[1] & 2) + valb = (ega->gdcreg[0] & 2) ? 0xff : 0; + else + valb = val; + if (ega->gdcreg[1] & 4) + valc = (ega->gdcreg[0] & 4) ? 0xff : 0; + else + valc = val; + if (ega->gdcreg[1] & 8) + vald = (ega->gdcreg[0] & 8) ? 0xff : 0; + else + vald = val; + // pclog("Write %02X %01X %02X %02X %02X %02X + // %02X\n",gdcreg[3]&0x18,writemask,vala,valb,valc,vald,gdcreg[8]); + switch (ega->gdcreg[3] & 0x18) { + case 0: /*Set*/ + if (writemask2 & 1) + ega->vram[addr] = (vala & ega->gdcreg[8]) | (ega->la & ~ega->gdcreg[8]); + if (writemask2 & 2) + ega->vram[addr | 0x1] = (valb & ega->gdcreg[8]) | (ega->lb & ~ega->gdcreg[8]); + if (writemask2 & 4) + ega->vram[addr | 0x2] = (valc & ega->gdcreg[8]) | (ega->lc & ~ega->gdcreg[8]); + if (writemask2 & 8) + ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) | (ega->ld & ~ega->gdcreg[8]); + break; + case 8: /*AND*/ + if (writemask2 & 1) + ega->vram[addr] = (vala | ~ega->gdcreg[8]) & ega->la; + if (writemask2 & 2) + ega->vram[addr | 0x1] = (valb | ~ega->gdcreg[8]) & ega->lb; + if (writemask2 & 4) + ega->vram[addr | 0x2] = (valc | ~ega->gdcreg[8]) & ega->lc; + if (writemask2 & 8) + ega->vram[addr | 0x3] = (vald | ~ega->gdcreg[8]) & ega->ld; + break; + case 0x10: /*OR*/ + if (writemask2 & 1) + ega->vram[addr] = (vala & ega->gdcreg[8]) | ega->la; + if (writemask2 & 2) + ega->vram[addr | 0x1] = (valb & ega->gdcreg[8]) | ega->lb; + if (writemask2 & 4) + ega->vram[addr | 0x2] = (valc & ega->gdcreg[8]) | ega->lc; + if (writemask2 & 8) + ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) | ega->ld; + break; + case 0x18: /*XOR*/ + if (writemask2 & 1) + ega->vram[addr] = (vala & ega->gdcreg[8]) ^ ega->la; + if (writemask2 & 2) + ega->vram[addr | 0x1] = (valb & ega->gdcreg[8]) ^ ega->lb; + if (writemask2 & 4) + ega->vram[addr | 0x2] = (valc & ega->gdcreg[8]) ^ ega->lc; + if (writemask2 & 8) + ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) ^ ega->ld; + break; + } + // pclog("- %02X %02X %02X %02X + // %08X\n",vram[addr],vram[addr|0x1],vram[addr|0x2],vram[addr|0x3],addr); + } + break; + case 2: + if (!(ega->gdcreg[3] & 0x18) && !ega->gdcreg[1]) { + if (writemask2 & 1) + ega->vram[addr] = (((val & 1) ? 0xff : 0) & ega->gdcreg[8]) | (ega->la & ~ega->gdcreg[8]); + if (writemask2 & 2) + ega->vram[addr | 0x1] = (((val & 2) ? 0xff : 0) & ega->gdcreg[8]) | (ega->lb & ~ega->gdcreg[8]); + if (writemask2 & 4) + ega->vram[addr | 0x2] = (((val & 4) ? 0xff : 0) & ega->gdcreg[8]) | (ega->lc & ~ega->gdcreg[8]); + if (writemask2 & 8) + ega->vram[addr | 0x3] = (((val & 8) ? 0xff : 0) & ega->gdcreg[8]) | (ega->ld & ~ega->gdcreg[8]); + } else { + vala = ((val & 1) ? 0xff : 0); + valb = ((val & 2) ? 0xff : 0); + valc = ((val & 4) ? 0xff : 0); + vald = ((val & 8) ? 0xff : 0); + switch (ega->gdcreg[3] & 0x18) { + case 0: /*Set*/ + if (writemask2 & 1) + ega->vram[addr] = (vala & ega->gdcreg[8]) | (ega->la & ~ega->gdcreg[8]); + if (writemask2 & 2) + ega->vram[addr | 0x1] = (valb & ega->gdcreg[8]) | (ega->lb & ~ega->gdcreg[8]); + if (writemask2 & 4) + ega->vram[addr | 0x2] = (valc & ega->gdcreg[8]) | (ega->lc & ~ega->gdcreg[8]); + if (writemask2 & 8) + ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) | (ega->ld & ~ega->gdcreg[8]); + break; + case 8: /*AND*/ + if (writemask2 & 1) + ega->vram[addr] = (vala | ~ega->gdcreg[8]) & ega->la; + if (writemask2 & 2) + ega->vram[addr | 0x1] = (valb | ~ega->gdcreg[8]) & ega->lb; + if (writemask2 & 4) + ega->vram[addr | 0x2] = (valc | ~ega->gdcreg[8]) & ega->lc; + if (writemask2 & 8) + ega->vram[addr | 0x3] = (vald | ~ega->gdcreg[8]) & ega->ld; + break; + case 0x10: /*OR*/ + if (writemask2 & 1) + ega->vram[addr] = (vala & ega->gdcreg[8]) | ega->la; + if (writemask2 & 2) + ega->vram[addr | 0x1] = (valb & ega->gdcreg[8]) | ega->lb; + if (writemask2 & 4) + ega->vram[addr | 0x2] = (valc & ega->gdcreg[8]) | ega->lc; + if (writemask2 & 8) + ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) | ega->ld; + break; + case 0x18: /*XOR*/ + if (writemask2 & 1) + ega->vram[addr] = (vala & ega->gdcreg[8]) ^ ega->la; + if (writemask2 & 2) + ega->vram[addr | 0x1] = (valb & ega->gdcreg[8]) ^ ega->lb; + if (writemask2 & 4) + ega->vram[addr | 0x2] = (valc & ega->gdcreg[8]) ^ ega->lc; + if (writemask2 & 8) + ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) ^ ega->ld; + break; + } + } + break; + } } uint8_t ega_read(uint32_t addr, void *p) { - ega_t *ega = (ega_t *)p; - uint8_t temp, temp2, temp3, temp4; - int readplane = ega->readplane; + ega_t *ega = (ega_t *)p; + uint8_t temp, temp2, temp3, temp4; + int readplane = ega->readplane; - egareads++; - cycles -= video_timing_read_b; - cycles_lost += video_timing_read_b; -// pclog("Readega %06X ",addr); - if (addr >= 0xb0000) - addr &= 0x7fff; - else - addr &= 0xffff; + egareads++; + cycles -= video_timing_read_b; + cycles_lost += video_timing_read_b; + // pclog("Readega %06X ",addr); + if (addr >= 0xb0000) + addr &= 0x7fff; + else + addr &= 0xffff; - if (ega->chain2_read) { - readplane = (readplane & 2) | (addr & 1); - addr &= ~1; - if (addr & 0x4000) - addr |= 1; - addr &= ~0x4000; - } + if (ega->chain2_read) { + readplane = (readplane & 2) | (addr & 1); + addr &= ~1; + if (addr & 0x4000) + addr |= 1; + addr &= ~0x4000; + } - addr <<= 2; - if (addr >= ega->vram_limit) - return 0xff; + addr <<= 2; + if (addr >= ega->vram_limit) + return 0xff; - ega->la = ega->vram[addr]; - ega->lb = ega->vram[addr | 0x1]; - ega->lc = ega->vram[addr | 0x2]; - ega->ld = ega->vram[addr | 0x3]; - if (ega->readmode) { - temp = ega->la; - temp ^= (ega->colourcompare & 1) ? 0xff : 0; - temp &= (ega->colournocare & 1) ? 0xff : 0; - temp2 = ega->lb; - temp2 ^= (ega->colourcompare & 2) ? 0xff : 0; - temp2 &= (ega->colournocare & 2) ? 0xff : 0; - temp3 = ega->lc; - temp3 ^= (ega->colourcompare & 4) ? 0xff : 0; - temp3 &= (ega->colournocare & 4) ? 0xff : 0; - temp4 = ega->ld; - temp4 ^= (ega->colourcompare & 8) ? 0xff : 0; - temp4 &= (ega->colournocare & 8) ? 0xff : 0; - return ~(temp | temp2 | temp3 | temp4); - } - return ega->vram[addr | readplane]; + ega->la = ega->vram[addr]; + ega->lb = ega->vram[addr | 0x1]; + ega->lc = ega->vram[addr | 0x2]; + ega->ld = ega->vram[addr | 0x3]; + if (ega->readmode) { + temp = ega->la; + temp ^= (ega->colourcompare & 1) ? 0xff : 0; + temp &= (ega->colournocare & 1) ? 0xff : 0; + temp2 = ega->lb; + temp2 ^= (ega->colourcompare & 2) ? 0xff : 0; + temp2 &= (ega->colournocare & 2) ? 0xff : 0; + temp3 = ega->lc; + temp3 ^= (ega->colourcompare & 4) ? 0xff : 0; + temp3 &= (ega->colournocare & 4) ? 0xff : 0; + temp4 = ega->ld; + temp4 ^= (ega->colourcompare & 8) ? 0xff : 0; + temp4 &= (ega->colournocare & 8) ? 0xff : 0; + return ~(temp | temp2 | temp3 | temp4); + } + return ega->vram[addr | readplane]; } void ega_init(ega_t *ega, int monitor_type, int is_mono) { - int c, d, e; + int c, d, e; - ega->vram = malloc(0x40000); - ega->vrammask = 0x3ffff; + ega->vram = malloc(0x40000); + ega->vrammask = 0x3ffff; - for (c = 0; c < 256; c++) { - e = c; - for (d = 0; d < 8; d++) { - ega_rotate[d][c] = e; - e = (e >> 1) | ((e & 1) ? 0x80 : 0); - } - } + for (c = 0; c < 256; c++) { + e = c; + for (d = 0; d < 8; d++) { + ega_rotate[d][c] = e; + e = (e >> 1) | ((e & 1) ? 0x80 : 0); + } + } - for (c = 0; c < 4; c++) { - for (d = 0; d < 4; d++) { - edatlookup[c][d] = 0; - if (c & 1) - edatlookup[c][d] |= 1; - if (d & 1) - edatlookup[c][d] |= 2; - if (c & 2) - edatlookup[c][d] |= 0x10; - if (d & 2) - edatlookup[c][d] |= 0x20; - } - } + for (c = 0; c < 4; c++) { + for (d = 0; d < 4; d++) { + edatlookup[c][d] = 0; + if (c & 1) + edatlookup[c][d] |= 1; + if (d & 1) + edatlookup[c][d] |= 2; + if (c & 2) + edatlookup[c][d] |= 0x10; + if (d & 2) + edatlookup[c][d] |= 0x20; + } + } - if (is_mono) { - for (c = 0; c < 256; c++) { - switch (monitor_type >> 4) { - case DISPLAY_GREEN: - switch ((c >> 3) & 3) { - case 0:pallook64[c] = pallook16[c] = makecol32(0, 0, 0); - break; - case 2:pallook64[c] = pallook16[c] = makecol32(0x04, 0x8a, 0x20); - break; - case 1:pallook64[c] = pallook16[c] = makecol32(0x08, 0xc7, 0x2c); - break; - case 3:pallook64[c] = pallook16[c] = makecol32(0x34, 0xff, 0x5d); - break; - } - break; - case DISPLAY_AMBER: - switch ((c >> 3) & 3) { - case 0:pallook64[c] = pallook16[c] = makecol32(0, 0, 0); - break; - case 2:pallook64[c] = pallook16[c] = makecol32(0xb2, 0x4d, 0x00); - break; - case 1:pallook64[c] = pallook16[c] = makecol32(0xef, 0x79, 0x00); - break; - case 3:pallook64[c] = pallook16[c] = makecol32(0xff, 0xe3, 0x34); - break; - } - break; - case DISPLAY_WHITE: - default: - switch ((c >> 3) & 3) { - case 0:pallook64[c] = pallook16[c] = makecol32(0, 0, 0); - break; - case 2:pallook64[c] = pallook16[c] = makecol32(0x7a, 0x81, 0x83); - break; - case 1:pallook64[c] = pallook16[c] = makecol32(0xaf, 0xb3, 0xb0); - break; - case 3:pallook64[c] = pallook16[c] = makecol32(0xff, 0xfd, 0xed); - break; - } - break; - } - } - } else { - for (c = 0; c < 256; c++) { - pallook64[c] = makecol32(((c >> 2) & 1) * 0xaa, ((c >> 1) & 1) * 0xaa, (c & 1) * 0xaa); - pallook64[c] += makecol32(((c >> 5) & 1) * 0x55, ((c >> 4) & 1) * 0x55, ((c >> 3) & 1) * 0x55); - pallook16[c] = makecol32(((c >> 2) & 1) * 0xaa, ((c >> 1) & 1) * 0xaa, (c & 1) * 0xaa); - pallook16[c] += makecol32(((c >> 4) & 1) * 0x55, ((c >> 4) & 1) * 0x55, ((c >> 4) & 1) * 0x55); - if ((c & 0x17) == 6) - pallook16[c] = makecol32(0xaa, 0x55, 0); - } - } - ega->pallook = pallook16; + if (is_mono) { + for (c = 0; c < 256; c++) { + switch (monitor_type >> 4) { + case DISPLAY_GREEN: + switch ((c >> 3) & 3) { + case 0: + pallook64[c] = pallook16[c] = makecol32(0, 0, 0); + break; + case 2: + pallook64[c] = pallook16[c] = makecol32(0x04, 0x8a, 0x20); + break; + case 1: + pallook64[c] = pallook16[c] = makecol32(0x08, 0xc7, 0x2c); + break; + case 3: + pallook64[c] = pallook16[c] = makecol32(0x34, 0xff, 0x5d); + break; + } + break; + case DISPLAY_AMBER: + switch ((c >> 3) & 3) { + case 0: + pallook64[c] = pallook16[c] = makecol32(0, 0, 0); + break; + case 2: + pallook64[c] = pallook16[c] = makecol32(0xb2, 0x4d, 0x00); + break; + case 1: + pallook64[c] = pallook16[c] = makecol32(0xef, 0x79, 0x00); + break; + case 3: + pallook64[c] = pallook16[c] = makecol32(0xff, 0xe3, 0x34); + break; + } + break; + case DISPLAY_WHITE: + default: + switch ((c >> 3) & 3) { + case 0: + pallook64[c] = pallook16[c] = makecol32(0, 0, 0); + break; + case 2: + pallook64[c] = pallook16[c] = makecol32(0x7a, 0x81, 0x83); + break; + case 1: + pallook64[c] = pallook16[c] = makecol32(0xaf, 0xb3, 0xb0); + break; + case 3: + pallook64[c] = pallook16[c] = makecol32(0xff, 0xfd, 0xed); + break; + } + break; + } + } + } else { + for (c = 0; c < 256; c++) { + pallook64[c] = makecol32(((c >> 2) & 1) * 0xaa, ((c >> 1) & 1) * 0xaa, (c & 1) * 0xaa); + pallook64[c] += makecol32(((c >> 5) & 1) * 0x55, ((c >> 4) & 1) * 0x55, ((c >> 3) & 1) * 0x55); + pallook16[c] = makecol32(((c >> 2) & 1) * 0xaa, ((c >> 1) & 1) * 0xaa, (c & 1) * 0xaa); + pallook16[c] += makecol32(((c >> 4) & 1) * 0x55, ((c >> 4) & 1) * 0x55, ((c >> 4) & 1) * 0x55); + if ((c & 0x17) == 6) + pallook16[c] = makecol32(0xaa, 0x55, 0); + } + } + ega->pallook = pallook16; - egaswitches = monitor_type & 0xf; - ega->vram_limit = 256 * 1024; - ega->vrammask = ega->vram_limit - 1; + egaswitches = monitor_type & 0xf; + ega->vram_limit = 256 * 1024; + ega->vrammask = ega->vram_limit - 1; - timer_add(&ega->timer, ega_poll, ega, 1); + timer_add(&ega->timer, ega_poll, ega, 1); } void *ega_standalone_init() { - ega_t *ega = malloc(sizeof(ega_t)); - memset(ega, 0, sizeof(ega_t)); - int monitor_type; + ega_t *ega = malloc(sizeof(ega_t)); + memset(ega, 0, sizeof(ega_t)); + int monitor_type; - rom_init(&ega->bios_rom, "ibm_6277356_ega_card_u44_27128.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&ega->bios_rom, "ibm_6277356_ega_card_u44_27128.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - if (ega->bios_rom.rom[0x3ffe] == 0xaa && ega->bios_rom.rom[0x3fff] == 0x55) { - int c; - pclog("Read EGA ROM in reverse\n"); + if (ega->bios_rom.rom[0x3ffe] == 0xaa && ega->bios_rom.rom[0x3fff] == 0x55) { + int c; + pclog("Read EGA ROM in reverse\n"); - for (c = 0; c < 0x2000; c++) { - uint8_t temp = ega->bios_rom.rom[c]; - ega->bios_rom.rom[c] = ega->bios_rom.rom[0x3fff - c]; - ega->bios_rom.rom[0x3fff - c] = temp; - } - } + for (c = 0; c < 0x2000; c++) { + uint8_t temp = ega->bios_rom.rom[c]; + ega->bios_rom.rom[c] = ega->bios_rom.rom[0x3fff - c]; + ega->bios_rom.rom[0x3fff - c] = temp; + } + } - monitor_type = device_get_config_int("monitor_type"); - ega_init(ega, monitor_type, (monitor_type & 0xf) == 10); + monitor_type = device_get_config_int("monitor_type"); + ega_init(ega, monitor_type, (monitor_type & 0xf) == 10); - ega->vram_limit = device_get_config_int("memory") * 1024; - ega->vrammask = ega->vram_limit - 1; + ega->vram_limit = device_get_config_int("memory") * 1024; + ega->vrammask = ega->vram_limit - 1; - mem_mapping_add(&ega->mapping, 0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, ega); - io_sethandler(0x03a0, 0x0040, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); + mem_mapping_add(&ega->mapping, 0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, + ega); + io_sethandler(0x03a0, 0x0040, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); - return ega; + return ega; } -static int ega_standalone_available() { - return rom_present("ibm_6277356_ega_card_u44_27128.bin"); -} +static int ega_standalone_available() { return rom_present("ibm_6277356_ega_card_u44_27128.bin"); } void ega_close(void *p) { - ega_t *ega = (ega_t *)p; + ega_t *ega = (ega_t *)p; - free(ega->vram); - free(ega); + free(ega->vram); + free(ega); } void ega_speed_changed(void *p) { - ega_t *ega = (ega_t *)p; + ega_t *ega = (ega_t *)p; - ega_recalctimings(ega); + ega_recalctimings(ega); } void ega_add_status_info(char *s, int max_len, void *p) { - ega_t *ega = (ega_t *)p; - char temps[128]; + ega_t *ega = (ega_t *)p; + char temps[128]; - if (!ega->video_bpp) - strcpy(temps, "EGA in text mode\n"); - else - sprintf(temps, "EGA colour depth : %i bpp\n", ega->video_bpp); - strncat(s, temps, max_len); + if (!ega->video_bpp) + strcpy(temps, "EGA in text mode\n"); + else + sprintf(temps, "EGA colour depth : %i bpp\n", ega->video_bpp); + strncat(s, temps, max_len); - sprintf(temps, "EGA resolution : %i x %i\n", ega->video_res_x, ega->video_res_y); - strncat(s, temps, max_len); + sprintf(temps, "EGA resolution : %i x %i\n", ega->video_res_x, ega->video_res_y); + strncat(s, temps, max_len); - sprintf(temps, "EGA refresh rate : %i Hz\n\n", ega->frames); - ega->frames = 0; - strncat(s, temps, max_len); + sprintf(temps, "EGA refresh rate : %i Hz\n\n", ega->frames); + ega->frames = 0; + strncat(s, temps, max_len); } -static device_config_t ega_config[] = - { - { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "64 kB", - .value = 64 - }, - { - .description = "128 kB", - .value = 128 - }, - { - .description = "256 kB", - .value = 256 - }, - { - .description = "" - } - }, - .default_int = 256 - }, - { - .name = "monitor_type", - .description = "Monitor type", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "EGA Colour, 40x25", - .value = 6 - }, - { - .description = "EGA Colour, 80x25", - .value = 7 - }, - { - .description = "EGA Colour, ECD", - .value = 9 - }, - { - .description = "EGA Monochrome (white)", - .value = 10 | (DISPLAY_WHITE << 4) - }, - { - .description = "EGA Monochrome (green)", - .value = 10 | (DISPLAY_GREEN << 4) - }, - { - .description = "EGA Monochrome (amber)", - .value = 10 | (DISPLAY_AMBER << 4) - }, - { - .description = "" - } - }, - .default_int = 9 - }, - { - .type = -1 - } - }; +static device_config_t ega_config[] = { + {.name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .selection = {{.description = "64 kB", .value = 64}, + {.description = "128 kB", .value = 128}, + {.description = "256 kB", .value = 256}, + {.description = ""}}, + .default_int = 256}, + {.name = "monitor_type", + .description = "Monitor type", + .type = CONFIG_SELECTION, + .selection = {{.description = "EGA Colour, 40x25", .value = 6}, + {.description = "EGA Colour, 80x25", .value = 7}, + {.description = "EGA Colour, ECD", .value = 9}, + {.description = "EGA Monochrome (white)", .value = 10 | (DISPLAY_WHITE << 4)}, + {.description = "EGA Monochrome (green)", .value = 10 | (DISPLAY_GREEN << 4)}, + {.description = "EGA Monochrome (amber)", .value = 10 | (DISPLAY_AMBER << 4)}, + {.description = ""}}, + .default_int = 9}, + {.type = -1}}; -device_t ega_device = - { - "EGA", - 0, - ega_standalone_init, - ega_close, - ega_standalone_available, - ega_speed_changed, - NULL, - ega_add_status_info, - ega_config - }; +device_t ega_device = { + "EGA", 0, ega_standalone_init, ega_close, ega_standalone_available, ega_speed_changed, NULL, ega_add_status_info, + ega_config}; diff --git a/src/video/vid_et4000.c b/src/video/vid_et4000.c index a8b43814..70bbaa23 100644 --- a/src/video/vid_et4000.c +++ b/src/video/vid_et4000.c @@ -13,574 +13,596 @@ #include "vid_et4000.h" typedef struct et4000_t { - svga_t svga; - unk_ramdac_t ramdac; + svga_t svga; + unk_ramdac_t ramdac; - rom_t bios_rom; + rom_t bios_rom; - uint8_t banking; - uint8_t port_22cb_val; - uint8_t port_32cb_val; - int get_korean_font_enabled; - int get_korean_font_index; - uint16_t get_korean_font_base; + uint8_t banking; + uint8_t port_22cb_val; + uint8_t port_32cb_val; + int get_korean_font_enabled; + int get_korean_font_index; + uint16_t get_korean_font_base; - uint8_t kasan_cfg_index; - uint8_t kasan_cfg_regs[16]; - uint16_t kasan_access_addr; - uint8_t kasan_font_data[4]; + uint8_t kasan_cfg_index; + uint8_t kasan_cfg_regs[16]; + uint16_t kasan_access_addr; + uint8_t kasan_font_data[4]; } et4000_t; -static uint8_t crtc_mask[0x40] = - { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0x0f, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; +static uint8_t crtc_mask[0x40] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0x0f, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; void et4000_kasan_out(uint16_t addr, uint8_t val, void *p); uint8_t et4000_kasan_in(uint16_t addr, void *p); void et4000_out(uint16_t addr, uint8_t val, void *p) { - et4000_t *et4000 = (et4000_t *)p; - svga_t *svga = &et4000->svga; + et4000_t *et4000 = (et4000_t *)p; + svga_t *svga = &et4000->svga; - uint8_t old; + uint8_t old; - if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1)) - addr ^= 0x60; + if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1)) + addr ^= 0x60; -// pclog("ET4000 out %04X %02X\n", addr, val); + // pclog("ET4000 out %04X %02X\n", addr, val); - switch (addr) { - case 0x3C6: - case 0x3C7: - case 0x3C8: - case 0x3C9:unk_ramdac_out(addr, val, &et4000->ramdac, svga); - return; + switch (addr) { + case 0x3C6: + case 0x3C7: + case 0x3C8: + case 0x3C9: + unk_ramdac_out(addr, val, &et4000->ramdac, svga); + return; - case 0x3CD: /*Banking*/ - svga->write_bank = (val & 0xf) * 0x10000; - svga->read_bank = ((val >> 4) & 0xf) * 0x10000; - et4000->banking = val; -// pclog("Banking write %08X %08X %02X\n", svga->write_bank, svga->read_bank, val); - return; + case 0x3CD: /*Banking*/ + svga->write_bank = (val & 0xf) * 0x10000; + svga->read_bank = ((val >> 4) & 0xf) * 0x10000; + et4000->banking = val; + // pclog("Banking write %08X %08X %02X\n", svga->write_bank, svga->read_bank, val); + return; - case 0x3cf: - if ((svga->gdcaddr & 15) == 6) { - old = svga->gdcreg[6]; - svga_out(addr, val, svga); - if ((old & 0xc) != 0 && (val & 0xc) == 0) { - /*override mask - ET4000 supports linear 128k at A0000*/ - svga->banked_mask = 0x1ffff; - } - return; - } - break; + case 0x3cf: + if ((svga->gdcaddr & 15) == 6) { + old = svga->gdcreg[6]; + svga_out(addr, val, svga); + if ((old & 0xc) != 0 && (val & 0xc) == 0) { + /*override mask - ET4000 supports linear 128k at A0000*/ + svga->banked_mask = 0x1ffff; + } + return; + } + break; - case 0x3D4:svga->crtcreg = val & 0x3f; - return; - case 0x3D5: - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) - return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); - old = svga->crtc[svga->crtcreg]; - val &= crtc_mask[svga->crtcreg]; - svga->crtc[svga->crtcreg] = val; - if (old != val) { - if (svga->crtcreg < 0xE || svga->crtcreg > 0x10) { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - } - break; - } - svga_out(addr, val, svga); + case 0x3D4: + svga->crtcreg = val & 0x3f; + return; + case 0x3D5: + if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) + return; + if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) + val = (svga->crtc[7] & ~0x10) | (val & 0x10); + old = svga->crtc[svga->crtcreg]; + val &= crtc_mask[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; + if (old != val) { + if (svga->crtcreg < 0xE || svga->crtcreg > 0x10) { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } + } + break; + } + svga_out(addr, val, svga); } void et4000k_out(uint16_t addr, uint8_t val, void *p) { - et4000_t *et4000 = (et4000_t *)p; + et4000_t *et4000 = (et4000_t *)p; -// pclog("ET4000k out %04X %02X\n", addr, val); + // pclog("ET4000k out %04X %02X\n", addr, val); - switch (addr) { - case 0x22CB:et4000->port_22cb_val = (et4000->port_22cb_val & 0xF0) | (val & 0x0F); - et4000->get_korean_font_enabled = val & 7; - if (et4000->get_korean_font_enabled == 3) - et4000->get_korean_font_index = 0; - break; - case 0x22CF: - switch (et4000->get_korean_font_enabled) { - case 1:et4000->get_korean_font_base = ((val & 0x7F) << 7) | (et4000->get_korean_font_base & 0x7F); - break; - case 2:et4000->get_korean_font_base = (et4000->get_korean_font_base & 0x3F80) | (val & 0x7F) | (((val ^ 0x80) & 0x80) << 8); - break; - case 3: - if ((et4000->port_32cb_val & 0x30) == 0x20 && (et4000->get_korean_font_base & 0x7F) > 0x20 && (et4000->get_korean_font_base & 0x7F) < 0x7F) { - switch (et4000->get_korean_font_base & 0x3F80) { - case 0x2480: - if (et4000->get_korean_font_index < 16) - fontdatksc5601_user[(et4000->get_korean_font_base & 0x7F) - 0x20][et4000->get_korean_font_index] = val; - else if (et4000->get_korean_font_index >= 24 && et4000->get_korean_font_index < 40) - fontdatksc5601_user[(et4000->get_korean_font_base & 0x7F) - 0x20][et4000->get_korean_font_index - 8] = val; - break; - case 0x3F00: - if (et4000->get_korean_font_index < 16) - fontdatksc5601_user[96 + (et4000->get_korean_font_base & 0x7F) - 0x20][et4000->get_korean_font_index] = val; - else if (et4000->get_korean_font_index >= 24 && et4000->get_korean_font_index < 40) - fontdatksc5601_user[96 + (et4000->get_korean_font_base & 0x7F) - 0x20][et4000->get_korean_font_index - 8] = val; - break; - } - et4000->get_korean_font_index++; - } - break; - } - break; - case 0x32CB:et4000->port_32cb_val = val; - svga_recalctimings(&et4000->svga); - break; - default:et4000_out(addr, val, p); - break; - } + switch (addr) { + case 0x22CB: + et4000->port_22cb_val = (et4000->port_22cb_val & 0xF0) | (val & 0x0F); + et4000->get_korean_font_enabled = val & 7; + if (et4000->get_korean_font_enabled == 3) + et4000->get_korean_font_index = 0; + break; + case 0x22CF: + switch (et4000->get_korean_font_enabled) { + case 1: + et4000->get_korean_font_base = ((val & 0x7F) << 7) | (et4000->get_korean_font_base & 0x7F); + break; + case 2: + et4000->get_korean_font_base = + (et4000->get_korean_font_base & 0x3F80) | (val & 0x7F) | (((val ^ 0x80) & 0x80) << 8); + break; + case 3: + if ((et4000->port_32cb_val & 0x30) == 0x20 && (et4000->get_korean_font_base & 0x7F) > 0x20 && + (et4000->get_korean_font_base & 0x7F) < 0x7F) { + switch (et4000->get_korean_font_base & 0x3F80) { + case 0x2480: + if (et4000->get_korean_font_index < 16) + fontdatksc5601_user[(et4000->get_korean_font_base & 0x7F) - 0x20] + [et4000->get_korean_font_index] = val; + else if (et4000->get_korean_font_index >= 24 && et4000->get_korean_font_index < 40) + fontdatksc5601_user[(et4000->get_korean_font_base & 0x7F) - 0x20] + [et4000->get_korean_font_index - 8] = val; + break; + case 0x3F00: + if (et4000->get_korean_font_index < 16) + fontdatksc5601_user[96 + (et4000->get_korean_font_base & 0x7F) - 0x20] + [et4000->get_korean_font_index] = val; + else if (et4000->get_korean_font_index >= 24 && et4000->get_korean_font_index < 40) + fontdatksc5601_user[96 + (et4000->get_korean_font_base & 0x7F) - 0x20] + [et4000->get_korean_font_index - 8] = val; + break; + } + et4000->get_korean_font_index++; + } + break; + } + break; + case 0x32CB: + et4000->port_32cb_val = val; + svga_recalctimings(&et4000->svga); + break; + default: + et4000_out(addr, val, p); + break; + } } void et4000_kasan_out(uint16_t addr, uint8_t val, void *p) { - et4000_t *et4000 = (et4000_t *)p; + et4000_t *et4000 = (et4000_t *)p; -// pclog("ET4000k out %04X %02X\n", addr, val); + // pclog("ET4000k out %04X %02X\n", addr, val); - - if (addr == 0x258) { - //pclog("Write port %04X to %02X at %04X:%04X\n", addr, val, CS, cpu_state.oldpc); - et4000->kasan_cfg_index = val; - } else if (addr == 0x259) { - //pclog("Write port %04X to %02X at %04X:%04X\n", addr, val, CS, cpu_state.oldpc); - if (et4000->kasan_cfg_index >= 0xF0) { - switch (et4000->kasan_cfg_index - 0xF0) { - case 0: - if (et4000->kasan_cfg_regs[4] & 8) - val = (val & 0xFC) | (et4000->kasan_cfg_regs[0] & 3); - et4000->kasan_cfg_regs[0] = val; - svga_recalctimings(&et4000->svga); - break; - case 1: - case 2:et4000->kasan_cfg_regs[et4000->kasan_cfg_index - 0xF0] = val; - io_removehandler(et4000->kasan_access_addr, 0x0008, et4000_kasan_in, NULL, NULL, et4000_kasan_out, NULL, NULL, et4000); - et4000->kasan_access_addr = (et4000->kasan_cfg_regs[2] << 8) | et4000->kasan_cfg_regs[1]; - io_sethandler(et4000->kasan_access_addr, 0x0008, et4000_kasan_in, NULL, NULL, et4000_kasan_out, NULL, NULL, et4000); - //pclog("Set font access address to %04X\n", et4000->kasan_access_addr); - break; - case 4: - if (et4000->kasan_cfg_regs[0] & 0x20) - val |= 0x80; - et4000->svga.ksc5601_swap_mode = (val & 4) >> 2; - et4000->kasan_cfg_regs[4] = val; - svga_recalctimings(&et4000->svga); - break; - case 5:et4000->kasan_cfg_regs[5] = val; - et4000->svga.ksc5601_english_font_type = 0x100 | val; - break; - case 6: - case 7:et4000->svga.ksc5601_udc_area_msb[et4000->kasan_cfg_index - 0xF6] = val; - default:et4000->kasan_cfg_regs[et4000->kasan_cfg_index - 0xF0] = val; - svga_recalctimings(&et4000->svga); - break; - } - } - } else if (addr >= et4000->kasan_access_addr && addr < et4000->kasan_access_addr + 8) { - switch (addr - ((et4000->kasan_cfg_regs[2] << 8) | (et4000->kasan_cfg_regs[1]))) { - case 0: - if (et4000->kasan_cfg_regs[0] & 2) { - et4000->get_korean_font_index = ((val & 1) << 4) | ((val & 0x1E) >> 1); - et4000->get_korean_font_base = (et4000->get_korean_font_base & ~7) | (val >> 5); - } - break; - case 1: - if (et4000->kasan_cfg_regs[0] & 2) { - et4000->get_korean_font_base = (et4000->get_korean_font_base & ~0x7F8) | (val << 3); - } - break; - case 2: - if (et4000->kasan_cfg_regs[0] & 2) { - et4000->get_korean_font_base = (et4000->get_korean_font_base & ~0x7F800) | ((val & 7) << 11); - } - break; - case 3: - case 4: - case 5: - if (et4000->kasan_cfg_regs[0] & 1) { - et4000->kasan_font_data[addr - (((et4000->kasan_cfg_regs[2] << 8) | (et4000->kasan_cfg_regs[1])) + 3)] = val; - } - break; - case 6: - if ((et4000->kasan_cfg_regs[0] & 1) && (et4000->kasan_font_data[3] & !val & 0x80) && (et4000->get_korean_font_base & 0x7F) >= 0x20 - && (et4000->get_korean_font_base & 0x7F) < 0x7F) { - if (((et4000->get_korean_font_base >> 7) & 0x7F) == (et4000->svga.ksc5601_udc_area_msb[0] & 0x7F) && (et4000->svga.ksc5601_udc_area_msb[0] & 0x80)) { - fontdatksc5601_user[(et4000->get_korean_font_base & 0x7F) - 0x20][et4000->get_korean_font_index] = et4000->kasan_font_data[2]; - } else if (((et4000->get_korean_font_base >> 7) & 0x7F) == (et4000->svga.ksc5601_udc_area_msb[1] & 0x7F) && (et4000->svga.ksc5601_udc_area_msb[1] & 0x80)) { - fontdatksc5601_user[96 + (et4000->get_korean_font_base & 0x7F) - 0x20][et4000->get_korean_font_index] = et4000->kasan_font_data[2]; - } - } - et4000->kasan_font_data[3] = val; - break; - default:break; - } - //pclog("Write port %04X at %04X:%04X\n", addr, CS, cpu_state.oldpc); - } else { - et4000_out(addr, val, p); - } + if (addr == 0x258) { + // pclog("Write port %04X to %02X at %04X:%04X\n", addr, val, CS, cpu_state.oldpc); + et4000->kasan_cfg_index = val; + } else if (addr == 0x259) { + // pclog("Write port %04X to %02X at %04X:%04X\n", addr, val, CS, cpu_state.oldpc); + if (et4000->kasan_cfg_index >= 0xF0) { + switch (et4000->kasan_cfg_index - 0xF0) { + case 0: + if (et4000->kasan_cfg_regs[4] & 8) + val = (val & 0xFC) | (et4000->kasan_cfg_regs[0] & 3); + et4000->kasan_cfg_regs[0] = val; + svga_recalctimings(&et4000->svga); + break; + case 1: + case 2: + et4000->kasan_cfg_regs[et4000->kasan_cfg_index - 0xF0] = val; + io_removehandler(et4000->kasan_access_addr, 0x0008, et4000_kasan_in, NULL, NULL, et4000_kasan_out, + NULL, NULL, et4000); + et4000->kasan_access_addr = (et4000->kasan_cfg_regs[2] << 8) | et4000->kasan_cfg_regs[1]; + io_sethandler(et4000->kasan_access_addr, 0x0008, et4000_kasan_in, NULL, NULL, et4000_kasan_out, + NULL, NULL, et4000); + // pclog("Set font access address to %04X\n", et4000->kasan_access_addr); + break; + case 4: + if (et4000->kasan_cfg_regs[0] & 0x20) + val |= 0x80; + et4000->svga.ksc5601_swap_mode = (val & 4) >> 2; + et4000->kasan_cfg_regs[4] = val; + svga_recalctimings(&et4000->svga); + break; + case 5: + et4000->kasan_cfg_regs[5] = val; + et4000->svga.ksc5601_english_font_type = 0x100 | val; + break; + case 6: + case 7: + et4000->svga.ksc5601_udc_area_msb[et4000->kasan_cfg_index - 0xF6] = val; + default: + et4000->kasan_cfg_regs[et4000->kasan_cfg_index - 0xF0] = val; + svga_recalctimings(&et4000->svga); + break; + } + } + } else if (addr >= et4000->kasan_access_addr && addr < et4000->kasan_access_addr + 8) { + switch (addr - ((et4000->kasan_cfg_regs[2] << 8) | (et4000->kasan_cfg_regs[1]))) { + case 0: + if (et4000->kasan_cfg_regs[0] & 2) { + et4000->get_korean_font_index = ((val & 1) << 4) | ((val & 0x1E) >> 1); + et4000->get_korean_font_base = (et4000->get_korean_font_base & ~7) | (val >> 5); + } + break; + case 1: + if (et4000->kasan_cfg_regs[0] & 2) { + et4000->get_korean_font_base = (et4000->get_korean_font_base & ~0x7F8) | (val << 3); + } + break; + case 2: + if (et4000->kasan_cfg_regs[0] & 2) { + et4000->get_korean_font_base = (et4000->get_korean_font_base & ~0x7F800) | ((val & 7) << 11); + } + break; + case 3: + case 4: + case 5: + if (et4000->kasan_cfg_regs[0] & 1) { + et4000->kasan_font_data[addr - (((et4000->kasan_cfg_regs[2] << 8) | (et4000->kasan_cfg_regs[1])) + + 3)] = val; + } + break; + case 6: + if ((et4000->kasan_cfg_regs[0] & 1) && (et4000->kasan_font_data[3] & !val & 0x80) && + (et4000->get_korean_font_base & 0x7F) >= 0x20 && (et4000->get_korean_font_base & 0x7F) < 0x7F) { + if (((et4000->get_korean_font_base >> 7) & 0x7F) == + (et4000->svga.ksc5601_udc_area_msb[0] & 0x7F) && + (et4000->svga.ksc5601_udc_area_msb[0] & 0x80)) { + fontdatksc5601_user[(et4000->get_korean_font_base & 0x7F) - 0x20] + [et4000->get_korean_font_index] = et4000->kasan_font_data[2]; + } else if (((et4000->get_korean_font_base >> 7) & 0x7F) == + (et4000->svga.ksc5601_udc_area_msb[1] & 0x7F) && + (et4000->svga.ksc5601_udc_area_msb[1] & 0x80)) { + fontdatksc5601_user[96 + (et4000->get_korean_font_base & 0x7F) - 0x20] + [et4000->get_korean_font_index] = et4000->kasan_font_data[2]; + } + } + et4000->kasan_font_data[3] = val; + break; + default: + break; + } + // pclog("Write port %04X at %04X:%04X\n", addr, CS, cpu_state.oldpc); + } else { + et4000_out(addr, val, p); + } } uint8_t et4000_in(uint16_t addr, void *p) { - et4000_t *et4000 = (et4000_t *)p; - svga_t *svga = &et4000->svga; + et4000_t *et4000 = (et4000_t *)p; + svga_t *svga = &et4000->svga; - if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1)) - addr ^= 0x60; + if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1)) + addr ^= 0x60; -// if (addr != 0x3da) pclog("IN ET4000 %04X\n", addr); + // if (addr != 0x3da) pclog("IN ET4000 %04X\n", addr); - switch (addr) { - case 0x3C5: - if ((svga->seqaddr & 0xf) == 7) - return svga->seqregs[svga->seqaddr & 0xf] | 4; - break; + switch (addr) { + case 0x3C5: + if ((svga->seqaddr & 0xf) == 7) + return svga->seqregs[svga->seqaddr & 0xf] | 4; + break; - case 0x3C6: - case 0x3C7: - case 0x3C8: - case 0x3C9:return unk_ramdac_in(addr, &et4000->ramdac, svga); + case 0x3C6: + case 0x3C7: + case 0x3C8: + case 0x3C9: + return unk_ramdac_in(addr, &et4000->ramdac, svga); - case 0x3CD: /*Banking*/ - return et4000->banking; - case 0x3D4:return svga->crtcreg; - case 0x3D5:return svga->crtc[svga->crtcreg]; - } - return svga_in(addr, svga); + case 0x3CD: /*Banking*/ + return et4000->banking; + case 0x3D4: + return svga->crtcreg; + case 0x3D5: + return svga->crtc[svga->crtcreg]; + } + return svga_in(addr, svga); } uint8_t et4000k_in(uint16_t addr, void *p) { - uint8_t val = 0xFF; - et4000_t *et4000 = (et4000_t *)p; + uint8_t val = 0xFF; + et4000_t *et4000 = (et4000_t *)p; -// if (addr != 0x3da) pclog("IN ET4000 %04X\n", addr); + // if (addr != 0x3da) pclog("IN ET4000 %04X\n", addr); - switch (addr) { - case 0x22CB:return et4000->port_22cb_val; - case 0x22CF:val = 0; - switch (et4000->get_korean_font_enabled) { - case 3: - if ((et4000->port_32cb_val & 0x30) == 0x30) { - val = fontdatksc5601[et4000->get_korean_font_base][et4000->get_korean_font_index++]; - et4000->get_korean_font_index &= 0x1F; - } else if ((et4000->port_32cb_val & 0x30) == 0x20 && (et4000->get_korean_font_base & 0x7F) > 0x20 && (et4000->get_korean_font_base & 0x7F) < 0x7F) { - switch (et4000->get_korean_font_base & 0x3F80) { - case 0x2480: - if (et4000->get_korean_font_index < 16) - val = fontdatksc5601_user[(et4000->get_korean_font_base & 0x7F) - 0x20][et4000->get_korean_font_index]; - else if (et4000->get_korean_font_index >= 24 && et4000->get_korean_font_index < 40) - val = fontdatksc5601_user[(et4000->get_korean_font_base & 0x7F) - 0x20][et4000->get_korean_font_index - 8]; - break; - case 0x3F00: - if (et4000->get_korean_font_index < 16) - val = fontdatksc5601_user[96 + (et4000->get_korean_font_base & 0x7F) - 0x20][et4000->get_korean_font_index]; - else if (et4000->get_korean_font_index >= 24 && et4000->get_korean_font_index < 40) - val = fontdatksc5601_user[96 + (et4000->get_korean_font_base & 0x7F) - 0x20][et4000->get_korean_font_index - 8]; - break; - } - et4000->get_korean_font_index++; - et4000->get_korean_font_index %= 72; - } - break; - case 4:val = 0x0F; - break; - } - return val; - case 0x32CB:return et4000->port_32cb_val; - } + switch (addr) { + case 0x22CB: + return et4000->port_22cb_val; + case 0x22CF: + val = 0; + switch (et4000->get_korean_font_enabled) { + case 3: + if ((et4000->port_32cb_val & 0x30) == 0x30) { + val = fontdatksc5601[et4000->get_korean_font_base][et4000->get_korean_font_index++]; + et4000->get_korean_font_index &= 0x1F; + } else if ((et4000->port_32cb_val & 0x30) == 0x20 && (et4000->get_korean_font_base & 0x7F) > 0x20 && + (et4000->get_korean_font_base & 0x7F) < 0x7F) { + switch (et4000->get_korean_font_base & 0x3F80) { + case 0x2480: + if (et4000->get_korean_font_index < 16) + val = fontdatksc5601_user[(et4000->get_korean_font_base & 0x7F) - 0x20] + [et4000->get_korean_font_index]; + else if (et4000->get_korean_font_index >= 24 && et4000->get_korean_font_index < 40) + val = fontdatksc5601_user[(et4000->get_korean_font_base & 0x7F) - 0x20] + [et4000->get_korean_font_index - 8]; + break; + case 0x3F00: + if (et4000->get_korean_font_index < 16) + val = fontdatksc5601_user[96 + (et4000->get_korean_font_base & 0x7F) - 0x20] + [et4000->get_korean_font_index]; + else if (et4000->get_korean_font_index >= 24 && et4000->get_korean_font_index < 40) + val = fontdatksc5601_user[96 + (et4000->get_korean_font_base & 0x7F) - 0x20] + [et4000->get_korean_font_index - 8]; + break; + } + et4000->get_korean_font_index++; + et4000->get_korean_font_index %= 72; + } + break; + case 4: + val = 0x0F; + break; + } + return val; + case 0x32CB: + return et4000->port_32cb_val; + } - return et4000_in(addr, p); + return et4000_in(addr, p); } uint8_t et4000_kasan_in(uint16_t addr, void *p) { - uint8_t val = 0xFF; - et4000_t *et4000 = (et4000_t *)p; + uint8_t val = 0xFF; + et4000_t *et4000 = (et4000_t *)p; - if (addr == 0x258) { - //pclog("Read port %04X at %04X:%04X\n", addr, CS, cpu_state.oldpc); - val = et4000->kasan_cfg_index; - } else if (addr == 0x259) { - //pclog("Read port %04X at %04X:%04X\n", addr, CS, cpu_state.oldpc); - if (et4000->kasan_cfg_index >= 0xF0) { - val = et4000->kasan_cfg_regs[et4000->kasan_cfg_index - 0xF0]; - if (et4000->kasan_cfg_index == 0xF4 && et4000->kasan_cfg_regs[0] & 0x20) - val |= 0x80; - } - } else if (addr >= et4000->kasan_access_addr && addr < et4000->kasan_access_addr + 8) { - switch (addr - ((et4000->kasan_cfg_regs[2] << 8) | (et4000->kasan_cfg_regs[1]))) { - case 2:val = 0; - break; - case 5: - if (((et4000->get_korean_font_base >> 7) & 0x7F) == (et4000->svga.ksc5601_udc_area_msb[0] & 0x7F) && (et4000->svga.ksc5601_udc_area_msb[0] & 0x80)) { - val = fontdatksc5601_user[(et4000->get_korean_font_base & 0x7F) - 0x20][et4000->get_korean_font_index]; - } else if (((et4000->get_korean_font_base >> 7) & 0x7F) == (et4000->svga.ksc5601_udc_area_msb[1] & 0x7F) && (et4000->svga.ksc5601_udc_area_msb[1] & 0x80)) { - val = fontdatksc5601_user[96 + (et4000->get_korean_font_base & 0x7F) - 0x20][et4000->get_korean_font_index]; - } else { - val = fontdatksc5601[et4000->get_korean_font_base][et4000->get_korean_font_index]; - } - break; - default:break; - } - //pclog(stderr, "Read port %04X at %04X:%04X\n", addr, CS, cpu_state.oldpc); - } else { - val = et4000_in(addr, p); - } - return val; + if (addr == 0x258) { + // pclog("Read port %04X at %04X:%04X\n", addr, CS, cpu_state.oldpc); + val = et4000->kasan_cfg_index; + } else if (addr == 0x259) { + // pclog("Read port %04X at %04X:%04X\n", addr, CS, cpu_state.oldpc); + if (et4000->kasan_cfg_index >= 0xF0) { + val = et4000->kasan_cfg_regs[et4000->kasan_cfg_index - 0xF0]; + if (et4000->kasan_cfg_index == 0xF4 && et4000->kasan_cfg_regs[0] & 0x20) + val |= 0x80; + } + } else if (addr >= et4000->kasan_access_addr && addr < et4000->kasan_access_addr + 8) { + switch (addr - ((et4000->kasan_cfg_regs[2] << 8) | (et4000->kasan_cfg_regs[1]))) { + case 2: + val = 0; + break; + case 5: + if (((et4000->get_korean_font_base >> 7) & 0x7F) == (et4000->svga.ksc5601_udc_area_msb[0] & 0x7F) && + (et4000->svga.ksc5601_udc_area_msb[0] & 0x80)) { + val = fontdatksc5601_user[(et4000->get_korean_font_base & 0x7F) - 0x20] + [et4000->get_korean_font_index]; + } else if (((et4000->get_korean_font_base >> 7) & 0x7F) == + (et4000->svga.ksc5601_udc_area_msb[1] & 0x7F) && + (et4000->svga.ksc5601_udc_area_msb[1] & 0x80)) { + val = fontdatksc5601_user[96 + (et4000->get_korean_font_base & 0x7F) - 0x20] + [et4000->get_korean_font_index]; + } else { + val = fontdatksc5601[et4000->get_korean_font_base][et4000->get_korean_font_index]; + } + break; + default: + break; + } + // pclog(stderr, "Read port %04X at %04X:%04X\n", addr, CS, cpu_state.oldpc); + } else { + val = et4000_in(addr, p); + } + return val; } void et4000_recalctimings(svga_t *svga) { - svga->ma_latch |= (svga->crtc[0x33] & 3) << 16; - if (svga->crtc[0x35] & 1) - svga->vblankstart += 0x400; - if (svga->crtc[0x35] & 2) - svga->vtotal += 0x400; - if (svga->crtc[0x35] & 4) - svga->dispend += 0x400; - if (svga->crtc[0x35] & 8) - svga->vsyncstart += 0x400; - if (svga->crtc[0x35] & 0x10) - svga->split += 0x400; - if (!svga->rowoffset) - svga->rowoffset = 0x100; - if (svga->crtc[0x3f] & 1) - svga->htotal += 256; - if (svga->attrregs[0x16] & 0x20) - svga->hdisp <<= 1; + svga->ma_latch |= (svga->crtc[0x33] & 3) << 16; + if (svga->crtc[0x35] & 1) + svga->vblankstart += 0x400; + if (svga->crtc[0x35] & 2) + svga->vtotal += 0x400; + if (svga->crtc[0x35] & 4) + svga->dispend += 0x400; + if (svga->crtc[0x35] & 8) + svga->vsyncstart += 0x400; + if (svga->crtc[0x35] & 0x10) + svga->split += 0x400; + if (!svga->rowoffset) + svga->rowoffset = 0x100; + if (svga->crtc[0x3f] & 1) + svga->htotal += 256; + if (svga->attrregs[0x16] & 0x20) + svga->hdisp <<= 1; -// pclog("Rowoffset %i\n",svga_rowoffset); + // pclog("Rowoffset %i\n",svga_rowoffset); - switch (((svga->miscout >> 2) & 3) | ((svga->crtc[0x34] << 1) & 4)) { - case 0: - case 1:break; - case 3:svga->clock = (cpuclock * (double)(1ull << 32)) / 40000000.0; - break; - case 5:svga->clock = (cpuclock * (double)(1ull << 32)) / 65000000.0; - break; - default:svga->clock = (cpuclock * (double)(1ull << 32)) / 36000000.0; - break; - } + switch (((svga->miscout >> 2) & 3) | ((svga->crtc[0x34] << 1) & 4)) { + case 0: + case 1: + break; + case 3: + svga->clock = (cpuclock * (double)(1ull << 32)) / 40000000.0; + break; + case 5: + svga->clock = (cpuclock * (double)(1ull << 32)) / 65000000.0; + break; + default: + svga->clock = (cpuclock * (double)(1ull << 32)) / 36000000.0; + break; + } - switch (svga->bpp) { - case 15: - case 16:svga->hdisp /= 2; - break; - case 24:svga->hdisp /= 3; - break; - } + switch (svga->bpp) { + case 15: + case 16: + svga->hdisp /= 2; + break; + case 24: + svga->hdisp /= 3; + break; + } } void et4000k_recalctimings(svga_t *svga) { - et4000_t *et4000 = (et4000_t *)svga->p; + et4000_t *et4000 = (et4000_t *)svga->p; - et4000_recalctimings(svga); + et4000_recalctimings(svga); - if (svga->render == svga_render_text_80 && ((svga->crtc[0x37] & 0x0A) == 0x0A)) { - if (et4000->port_32cb_val & 0x80) { - svga->ma_latch -= 2; - svga->ca_adj = -2; - } - if ((et4000->port_32cb_val & 0xB4) == ((svga->crtc[0x37] & 3) == 2 ? 0xB4 : 0xB0)) { - svga->render = svga_render_text_80_ksc5601; - } - } + if (svga->render == svga_render_text_80 && ((svga->crtc[0x37] & 0x0A) == 0x0A)) { + if (et4000->port_32cb_val & 0x80) { + svga->ma_latch -= 2; + svga->ca_adj = -2; + } + if ((et4000->port_32cb_val & 0xB4) == ((svga->crtc[0x37] & 3) == 2 ? 0xB4 : 0xB0)) { + svga->render = svga_render_text_80_ksc5601; + } + } } void et4000_kasan_recalctimings(svga_t *svga) { - et4000_t *et4000 = (et4000_t *)svga->p; + et4000_t *et4000 = (et4000_t *)svga->p; - et4000_recalctimings(svga); + et4000_recalctimings(svga); - if (svga->render == svga_render_text_80 && (et4000->kasan_cfg_regs[0] & 8)) { - svga->ma_latch -= 3; - svga->ca_adj = (et4000->kasan_cfg_regs[0] >> 6) - 3; - svga->ksc5601_sbyte_mask = (et4000->kasan_cfg_regs[0] & 4) << 5; - if ((et4000->kasan_cfg_regs[0] & 0x23) == 0x20 && (et4000->kasan_cfg_regs[4] & 0x80) && ((svga->crtc[0x37] & 0x0B) == 0x0A)) - svga->render = svga_render_text_80_ksc5601; - } + if (svga->render == svga_render_text_80 && (et4000->kasan_cfg_regs[0] & 8)) { + svga->ma_latch -= 3; + svga->ca_adj = (et4000->kasan_cfg_regs[0] >> 6) - 3; + svga->ksc5601_sbyte_mask = (et4000->kasan_cfg_regs[0] & 4) << 5; + if ((et4000->kasan_cfg_regs[0] & 0x23) == 0x20 && (et4000->kasan_cfg_regs[4] & 0x80) && + ((svga->crtc[0x37] & 0x0B) == 0x0A)) + svga->render = svga_render_text_80_ksc5601; + } } void *et4000_init() { - et4000_t *et4000 = malloc(sizeof(et4000_t)); - memset(et4000, 0, sizeof(et4000_t)); + et4000_t *et4000 = malloc(sizeof(et4000_t)); + memset(et4000, 0, sizeof(et4000_t)); - rom_init(&et4000->bios_rom, "et4000.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&et4000->bios_rom, "et4000.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - io_sethandler(0x03c0, 0x0020, et4000_in, NULL, NULL, et4000_out, NULL, NULL, et4000); + io_sethandler(0x03c0, 0x0020, et4000_in, NULL, NULL, et4000_out, NULL, NULL, et4000); - svga_init(&et4000->svga, et4000, 1 << 20, /*1mb*/ - et4000_recalctimings, - et4000_in, et4000_out, - NULL, - NULL); + svga_init(&et4000->svga, et4000, 1 << 20, /*1mb*/ + et4000_recalctimings, et4000_in, et4000_out, NULL, NULL); - et4000->svga.packed_chain4 = 1; + et4000->svga.packed_chain4 = 1; - return et4000; + return et4000; } void *et4000k_init() { - et4000_t *et4000 = malloc(sizeof(et4000_t)); - memset(et4000, 0, sizeof(et4000_t)); + et4000_t *et4000 = malloc(sizeof(et4000_t)); + memset(et4000, 0, sizeof(et4000_t)); - rom_init(&et4000->bios_rom, "tgkorvga.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - loadfont("tg_ksc5601.rom", 6); + rom_init(&et4000->bios_rom, "tgkorvga.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + loadfont("tg_ksc5601.rom", 6); - io_sethandler(0x03c0, 0x0020, et4000_in, NULL, NULL, et4000_out, NULL, NULL, et4000); + io_sethandler(0x03c0, 0x0020, et4000_in, NULL, NULL, et4000_out, NULL, NULL, et4000); - io_sethandler(0x22cb, 0x0001, et4000k_in, NULL, NULL, et4000k_out, NULL, NULL, et4000); - io_sethandler(0x22cf, 0x0001, et4000k_in, NULL, NULL, et4000k_out, NULL, NULL, et4000); - io_sethandler(0x32cb, 0x0001, et4000k_in, NULL, NULL, et4000k_out, NULL, NULL, et4000); - et4000->port_22cb_val = 0x60; - et4000->port_32cb_val = 0; + io_sethandler(0x22cb, 0x0001, et4000k_in, NULL, NULL, et4000k_out, NULL, NULL, et4000); + io_sethandler(0x22cf, 0x0001, et4000k_in, NULL, NULL, et4000k_out, NULL, NULL, et4000); + io_sethandler(0x32cb, 0x0001, et4000k_in, NULL, NULL, et4000k_out, NULL, NULL, et4000); + et4000->port_22cb_val = 0x60; + et4000->port_32cb_val = 0; - svga_init(&et4000->svga, et4000, 1 << 20, /*1mb*/ - et4000k_recalctimings, - et4000k_in, et4000k_out, - NULL, - NULL); + svga_init(&et4000->svga, et4000, 1 << 20, /*1mb*/ + et4000k_recalctimings, et4000k_in, et4000k_out, NULL, NULL); - et4000->svga.ksc5601_sbyte_mask = 0x80; - et4000->svga.ksc5601_udc_area_msb[0] = 0xC9; - et4000->svga.ksc5601_udc_area_msb[1] = 0xFE; - et4000->svga.ksc5601_swap_mode = 0; - et4000->svga.ksc5601_english_font_type = 0; + et4000->svga.ksc5601_sbyte_mask = 0x80; + et4000->svga.ksc5601_udc_area_msb[0] = 0xC9; + et4000->svga.ksc5601_udc_area_msb[1] = 0xFE; + et4000->svga.ksc5601_swap_mode = 0; + et4000->svga.ksc5601_english_font_type = 0; - et4000->svga.packed_chain4 = 1; + et4000->svga.packed_chain4 = 1; - return et4000; + return et4000; } void *et4000_kasan_init() { - int i; - et4000_t *et4000 = malloc(sizeof(et4000_t)); - memset(et4000, 0, sizeof(et4000_t)); + int i; + et4000_t *et4000 = malloc(sizeof(et4000_t)); + memset(et4000, 0, sizeof(et4000_t)); - rom_init(&et4000->bios_rom, "et4000_kasan16.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - loadfont("kasan_ksc5601.rom", 6); + rom_init(&et4000->bios_rom, "et4000_kasan16.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + loadfont("kasan_ksc5601.rom", 6); - io_sethandler(0x03c0, 0x0020, et4000_in, NULL, NULL, et4000_out, NULL, NULL, et4000); + io_sethandler(0x03c0, 0x0020, et4000_in, NULL, NULL, et4000_out, NULL, NULL, et4000); - io_sethandler(0x0258, 0x0002, et4000_kasan_in, NULL, NULL, et4000_kasan_out, NULL, NULL, et4000); + io_sethandler(0x0258, 0x0002, et4000_kasan_in, NULL, NULL, et4000_kasan_out, NULL, NULL, et4000); - svga_init(&et4000->svga, et4000, 1 << 20, /*1mb*/ - et4000_kasan_recalctimings, - et4000_in, et4000_out, - NULL, - NULL); + svga_init(&et4000->svga, et4000, 1 << 20, /*1mb*/ + et4000_kasan_recalctimings, et4000_in, et4000_out, NULL, NULL); - et4000->svga.ksc5601_sbyte_mask = 0; - et4000->kasan_cfg_index = 0; - for (i = 0; i < 16; i++) - et4000->kasan_cfg_regs[i] = 0; - for (i = 0; i < 4; i++) - et4000->kasan_font_data[i] = 0; - et4000->kasan_cfg_regs[1] = 0x50; - et4000->kasan_cfg_regs[2] = 2; - et4000->kasan_cfg_regs[3] = 6; - et4000->kasan_cfg_regs[4] = 0x78; - et4000->kasan_cfg_regs[5] = 0xFF; - et4000->kasan_cfg_regs[6] = 0xC9; - et4000->kasan_cfg_regs[7] = 0xFE; - et4000->kasan_access_addr = 0x250; - io_sethandler(0x250, 0x0008, et4000_kasan_in, NULL, NULL, et4000_kasan_out, NULL, NULL, et4000); + et4000->svga.ksc5601_sbyte_mask = 0; + et4000->kasan_cfg_index = 0; + for (i = 0; i < 16; i++) + et4000->kasan_cfg_regs[i] = 0; + for (i = 0; i < 4; i++) + et4000->kasan_font_data[i] = 0; + et4000->kasan_cfg_regs[1] = 0x50; + et4000->kasan_cfg_regs[2] = 2; + et4000->kasan_cfg_regs[3] = 6; + et4000->kasan_cfg_regs[4] = 0x78; + et4000->kasan_cfg_regs[5] = 0xFF; + et4000->kasan_cfg_regs[6] = 0xC9; + et4000->kasan_cfg_regs[7] = 0xFE; + et4000->kasan_access_addr = 0x250; + io_sethandler(0x250, 0x0008, et4000_kasan_in, NULL, NULL, et4000_kasan_out, NULL, NULL, et4000); - et4000->svga.ksc5601_sbyte_mask = 0; - et4000->svga.ksc5601_udc_area_msb[0] = 0xC9; - et4000->svga.ksc5601_udc_area_msb[1] = 0xFE; - et4000->svga.ksc5601_swap_mode = 0; - et4000->svga.ksc5601_english_font_type = 0x1FF; + et4000->svga.ksc5601_sbyte_mask = 0; + et4000->svga.ksc5601_udc_area_msb[0] = 0xC9; + et4000->svga.ksc5601_udc_area_msb[1] = 0xFE; + et4000->svga.ksc5601_swap_mode = 0; + et4000->svga.ksc5601_english_font_type = 0x1FF; - et4000->svga.packed_chain4 = 1; + et4000->svga.packed_chain4 = 1; - return et4000; + return et4000; } -static int et4000_available() { - return rom_present("et4000.bin"); -} +static int et4000_available() { return rom_present("et4000.bin"); } static int et4000k_available() { - return rom_present("tgkorvga.bin") && rom_present("tg_ksc5601.rom");; + return rom_present("tgkorvga.bin") && rom_present("tg_ksc5601.rom"); + ; } static int et4000_kasan_available() { - return rom_present("et4000_kasan16.bin") && rom_present("kasan_ksc5601.rom");; + return rom_present("et4000_kasan16.bin") && rom_present("kasan_ksc5601.rom"); + ; } void et4000_close(void *p) { - et4000_t *et4000 = (et4000_t *)p; + et4000_t *et4000 = (et4000_t *)p; - svga_close(&et4000->svga); + svga_close(&et4000->svga); - free(et4000); + free(et4000); } void et4000_speed_changed(void *p) { - et4000_t *et4000 = (et4000_t *)p; + et4000_t *et4000 = (et4000_t *)p; - svga_recalctimings(&et4000->svga); + svga_recalctimings(&et4000->svga); } void et4000_force_redraw(void *p) { - et4000_t *et4000 = (et4000_t *)p; + et4000_t *et4000 = (et4000_t *)p; - et4000->svga.fullchange = changeframecount; + et4000->svga.fullchange = changeframecount; } void et4000_add_status_info(char *s, int max_len, void *p) { - et4000_t *et4000 = (et4000_t *)p; + et4000_t *et4000 = (et4000_t *)p; - svga_add_status_info(s, max_len, &et4000->svga); + svga_add_status_info(s, max_len, &et4000->svga); } -device_t et4000_device = - { - "Tseng Labs ET4000AX", - 0, - et4000_init, - et4000_close, - et4000_available, - et4000_speed_changed, - et4000_force_redraw, - et4000_add_status_info - }; +device_t et4000_device = { + "Tseng Labs ET4000AX", 0, et4000_init, et4000_close, et4000_available, et4000_speed_changed, et4000_force_redraw, + et4000_add_status_info}; -device_t et4000k_device = - { - "Trigem Korean VGA(Tseng Labs ET4000AX)", - 0, - et4000k_init, - et4000_close, - et4000k_available, - et4000_speed_changed, - et4000_force_redraw, - et4000_add_status_info - }; +device_t et4000k_device = {"Trigem Korean VGA(Tseng Labs ET4000AX)", + 0, + et4000k_init, + et4000_close, + et4000k_available, + et4000_speed_changed, + et4000_force_redraw, + et4000_add_status_info}; -device_t et4000_kasan_device = - { - "Kasan Hangulmadang-16(Tseng Labs ET4000AX)", - 0, - et4000_kasan_init, - et4000_close, - et4000_kasan_available, - et4000_speed_changed, - et4000_force_redraw, - et4000_add_status_info - }; +device_t et4000_kasan_device = {"Kasan Hangulmadang-16(Tseng Labs ET4000AX)", + 0, + et4000_kasan_init, + et4000_close, + et4000_kasan_available, + et4000_speed_changed, + et4000_force_redraw, + et4000_add_status_info}; diff --git a/src/video/vid_et4000w32.c b/src/video/vid_et4000w32.c index b0d96683..243fb4fc 100644 --- a/src/video/vid_et4000w32.c +++ b/src/video/vid_et4000w32.c @@ -21,85 +21,81 @@ #define FIFO_ENTRY_SIZE (1 << 31) #define FIFO_ENTRIES (et4000->fifo_write_idx - et4000->fifo_read_idx) -#define FIFO_FULL ((et4000->fifo_write_idx - et4000->fifo_read_idx) >= (FIFO_SIZE-1)) -#define FIFO_EMPTY (et4000->fifo_read_idx == et4000->fifo_write_idx) +#define FIFO_FULL ((et4000->fifo_write_idx - et4000->fifo_read_idx) >= (FIFO_SIZE - 1)) +#define FIFO_EMPTY (et4000->fifo_read_idx == et4000->fifo_write_idx) #define FIFO_TYPE 0xff000000 #define FIFO_ADDR 0x00ffffff -enum { - FIFO_INVALID = (0x00 << 24), - FIFO_WRITE_BYTE = (0x01 << 24), - FIFO_WRITE_MMU = (0x02 << 24) -}; +enum { FIFO_INVALID = (0x00 << 24), FIFO_WRITE_BYTE = (0x01 << 24), FIFO_WRITE_MMU = (0x02 << 24) }; typedef struct { - uint32_t addr_type; - uint32_t val; + uint32_t addr_type; + uint32_t val; } fifo_entry_t; typedef struct et4000w32p_t { - mem_mapping_t linear_mapping; - mem_mapping_t mmu_mapping; + mem_mapping_t linear_mapping; + mem_mapping_t mmu_mapping; - rom_t bios_rom; + rom_t bios_rom; - svga_t svga; - stg_ramdac_t ramdac; - icd2061_t icd2061; + svga_t svga; + stg_ramdac_t ramdac; + icd2061_t icd2061; - int index; - uint8_t regs[256]; - uint32_t linearbase, linearbase_old; + int index; + uint8_t regs[256]; + uint32_t linearbase, linearbase_old; - uint8_t banking, banking2; + uint8_t banking, banking2; - uint8_t pci_regs[256]; + uint8_t pci_regs[256]; - int interleaved; + int interleaved; - /*Accelerator*/ - struct { - struct { - uint32_t pattern_addr, source_addr, dest_addr, mix_addr; - uint16_t pattern_off, source_off, dest_off, mix_off; - uint8_t pixel_depth, xy_dir; - uint8_t pattern_wrap, source_wrap; - uint16_t count_x, count_y; - uint8_t ctrl_routing, ctrl_reload; - uint8_t rop_fg, rop_bg; - uint16_t pos_x, pos_y; - uint16_t error; - uint16_t dmin, dmaj; - } queued, internal; - uint32_t pattern_addr, source_addr, dest_addr, mix_addr; - uint32_t pattern_back, source_back, dest_back, mix_back; - int pattern_x, source_x; - int pattern_x_back, source_x_back; - int pattern_y, source_y; - uint8_t status; - uint64_t cpu_dat; - int cpu_dat_pos; - int pix_pos; - } acl; + /*Accelerator*/ + struct { + struct { + uint32_t pattern_addr, source_addr, dest_addr, mix_addr; + uint16_t pattern_off, source_off, dest_off, mix_off; + uint8_t pixel_depth, xy_dir; + uint8_t pattern_wrap, source_wrap; + uint16_t count_x, count_y; + uint8_t ctrl_routing, ctrl_reload; + uint8_t rop_fg, rop_bg; + uint16_t pos_x, pos_y; + uint16_t error; + uint16_t dmin, dmaj; + } queued, internal; + uint32_t pattern_addr, source_addr, dest_addr, mix_addr; + uint32_t pattern_back, source_back, dest_back, mix_back; + int pattern_x, source_x; + int pattern_x_back, source_x_back; + int pattern_y, source_y; + uint8_t status; + uint64_t cpu_dat; + int cpu_dat_pos; + int pix_pos; + } acl; - struct { - uint32_t base[3]; - uint8_t ctrl; - } mmu; + struct { + uint32_t base[3]; + uint8_t ctrl; + } mmu; - fifo_entry_t fifo[FIFO_SIZE]; - volatile int fifo_read_idx, fifo_write_idx; + fifo_entry_t fifo[FIFO_SIZE]; + volatile int fifo_read_idx, fifo_write_idx; - thread_t *fifo_thread; - event_t *wake_fifo_thread; - event_t *fifo_not_full_event; + thread_t *fifo_thread; + event_t *wake_fifo_thread; + event_t *fifo_not_full_event; - int blitter_busy; - uint64_t blitter_time; - uint64_t status_time; + int blitter_busy; + uint64_t blitter_time; + uint64_t status_time; - int is_pci; + int is_pci; } et4000w32p_t; void et4000w32p_recalcmapping(et4000w32p_t *et4000); @@ -111,618 +107,739 @@ void et4000w32_blit_start(et4000w32p_t *et4000); void et4000w32_blit(int count, uint32_t mix, uint32_t sdat, int cpu_input, et4000w32p_t *et4000); void et4000w32p_out(uint16_t addr, uint8_t val, void *p) { - et4000w32p_t *et4000 = (et4000w32p_t *)p; - svga_t *svga = &et4000->svga; - uint8_t old; + et4000w32p_t *et4000 = (et4000w32p_t *)p; + svga_t *svga = &et4000->svga; + uint8_t old; -// pclog("et4000w32p_out: addr %04X val %02X %04X:%04X %02X %02X\n", addr, val, CS, pc, ram[0x487], ram[0x488]); + // pclog("et4000w32p_out: addr %04X val %02X %04X:%04X %02X %02X\n", addr, val, CS, pc, ram[0x487], ram[0x488]); -/* if (ram[0x487] == 0x62) - fatal("mono\n");*/ -// if (!(addr==0x3D4 && (val&~1)==0xE) && !(addr==0x3D5 && (crtcreg&~1)==0xE)) pclog("ET4000W32p out %04X %02X %04X:%04X ",addr,val,CS,pc); + /* if (ram[0x487] == 0x62) + fatal("mono\n");*/ + // if (!(addr==0x3D4 && (val&~1)==0xE) && !(addr==0x3D5 && (crtcreg&~1)==0xE)) pclog("ET4000W32p out %04X %02X + // %04X:%04X ",addr,val,CS,pc); - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; -// if (!(addr==0x3D4 && (val&~1)==0xE) && !(addr==0x3D5 && (crtcreg&~1)==0xE)) pclog("%04X\n",addr); + // if (!(addr==0x3D4 && (val&~1)==0xE) && !(addr==0x3D5 && (crtcreg&~1)==0xE)) pclog("%04X\n",addr); - switch (addr) { - case 0x3c2:icd2061_write(&et4000->icd2061, (val >> 2) & 3); - break; + switch (addr) { + case 0x3c2: + icd2061_write(&et4000->icd2061, (val >> 2) & 3); + break; - case 0x3C6: - case 0x3C7: - case 0x3C8: - case 0x3C9:stg_ramdac_out(addr, val, &et4000->ramdac, svga); - return; + case 0x3C6: + case 0x3C7: + case 0x3C8: + case 0x3C9: + stg_ramdac_out(addr, val, &et4000->ramdac, svga); + return; - case 0x3CB: /*Banking extension*/ - svga->write_bank = (svga->write_bank & 0xfffff) | ((val & 1) << 20); - svga->read_bank = (svga->read_bank & 0xfffff) | ((val & 0x10) << 16); - et4000->banking2 = val; - return; - case 0x3CD: /*Banking*/ - svga->write_bank = (svga->write_bank & 0x100000) | ((val & 0xf) * 65536); - svga->read_bank = (svga->read_bank & 0x100000) | (((val >> 4) & 0xf) * 65536); - et4000->banking = val; - return; - case 0x3CF: - switch (svga->gdcaddr & 15) { - case 6:svga->gdcreg[svga->gdcaddr & 15] = val; - et4000w32p_recalcmapping(et4000); - return; - } - break; - case 0x3D4:svga->crtcreg = val & 63; - return; - case 0x3D5: -// pclog("Write CRTC R%02X %02X\n", crtcreg, val); - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) - return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); - old = svga->crtc[svga->crtcreg]; - svga->crtc[svga->crtcreg] = val; - if (old != val) { - if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - } - if (svga->crtcreg == 0x30) { - et4000->linearbase = val * 0x400000; -// pclog("Linear base now at %08X %02X\n", et4000w32p_linearbase, val); - et4000w32p_recalcmapping(et4000); - } - if (svga->crtcreg == 0x32 || svga->crtcreg == 0x36) - et4000w32p_recalcmapping(et4000); - break; + case 0x3CB: /*Banking extension*/ + svga->write_bank = (svga->write_bank & 0xfffff) | ((val & 1) << 20); + svga->read_bank = (svga->read_bank & 0xfffff) | ((val & 0x10) << 16); + et4000->banking2 = val; + return; + case 0x3CD: /*Banking*/ + svga->write_bank = (svga->write_bank & 0x100000) | ((val & 0xf) * 65536); + svga->read_bank = (svga->read_bank & 0x100000) | (((val >> 4) & 0xf) * 65536); + et4000->banking = val; + return; + case 0x3CF: + switch (svga->gdcaddr & 15) { + case 6: + svga->gdcreg[svga->gdcaddr & 15] = val; + et4000w32p_recalcmapping(et4000); + return; + } + break; + case 0x3D4: + svga->crtcreg = val & 63; + return; + case 0x3D5: + // pclog("Write CRTC R%02X %02X\n", crtcreg, val); + if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) + return; + if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) + val = (svga->crtc[7] & ~0x10) | (val & 0x10); + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; + if (old != val) { + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } + } + if (svga->crtcreg == 0x30) { + et4000->linearbase = val * 0x400000; + // pclog("Linear base now at %08X %02X\n", et4000w32p_linearbase, val); + et4000w32p_recalcmapping(et4000); + } + if (svga->crtcreg == 0x32 || svga->crtcreg == 0x36) + et4000w32p_recalcmapping(et4000); + break; - case 0x210A: - case 0x211A: - case 0x212A: - case 0x213A: - case 0x214A: - case 0x215A: - case 0x216A: - case 0x217A:et4000->index = val; - return; - case 0x210B: - case 0x211B: - case 0x212B: - case 0x213B: - case 0x214B: - case 0x215B: - case 0x216B: - case 0x217B:et4000->regs[et4000->index] = val; - svga->hwcursor.x = et4000->regs[0xE0] | ((et4000->regs[0xE1] & 7) << 8); - svga->hwcursor.y = et4000->regs[0xE4] | ((et4000->regs[0xE5] & 7) << 8); - svga->hwcursor.addr = (et4000->regs[0xE8] | (et4000->regs[0xE9] << 8) | ((et4000->regs[0xEA] & 7) << 16)) << 2; - svga->hwcursor.addr += (et4000->regs[0xE6] & 63) * 16; - svga->hwcursor.ena = et4000->regs[0xF7] & 0x80; - svga->hwcursor.xoff = et4000->regs[0xE2] & 63; - svga->hwcursor.yoff = et4000->regs[0xE6] & 63; -// pclog("HWCURSOR X %i Y %i\n",svga->hwcursor_x,svga->hwcursor_y); - return; - - } - svga_out(addr, val, svga); + case 0x210A: + case 0x211A: + case 0x212A: + case 0x213A: + case 0x214A: + case 0x215A: + case 0x216A: + case 0x217A: + et4000->index = val; + return; + case 0x210B: + case 0x211B: + case 0x212B: + case 0x213B: + case 0x214B: + case 0x215B: + case 0x216B: + case 0x217B: + et4000->regs[et4000->index] = val; + svga->hwcursor.x = et4000->regs[0xE0] | ((et4000->regs[0xE1] & 7) << 8); + svga->hwcursor.y = et4000->regs[0xE4] | ((et4000->regs[0xE5] & 7) << 8); + svga->hwcursor.addr = (et4000->regs[0xE8] | (et4000->regs[0xE9] << 8) | ((et4000->regs[0xEA] & 7) << 16)) << 2; + svga->hwcursor.addr += (et4000->regs[0xE6] & 63) * 16; + svga->hwcursor.ena = et4000->regs[0xF7] & 0x80; + svga->hwcursor.xoff = et4000->regs[0xE2] & 63; + svga->hwcursor.yoff = et4000->regs[0xE6] & 63; + // pclog("HWCURSOR X %i Y %i\n",svga->hwcursor_x,svga->hwcursor_y); + return; + } + svga_out(addr, val, svga); } uint8_t et4000w32p_in(uint16_t addr, void *p) { - et4000w32p_t *et4000 = (et4000w32p_t *)p; - svga_t *svga = &et4000->svga; - uint8_t temp; -// if (addr==0x3DA) pclog("In 3DA %04X(%06X):%04X\n",CS,cs,pc); + et4000w32p_t *et4000 = (et4000w32p_t *)p; + svga_t *svga = &et4000->svga; + uint8_t temp; + // if (addr==0x3DA) pclog("In 3DA %04X(%06X):%04X\n",CS,cs,pc); -// pclog("ET4000W32p in %04X %04X:%04X ",addr,CS,pc); + // pclog("ET4000W32p in %04X %04X:%04X ",addr,CS,pc); -// if (addr != 0x3da && addr != 0x3ba) -// pclog("et4000w32p_in: addr %04X %04X:%04X %02X %02X\n", addr, CS, pc, ram[0x487], ram[0x488]); + // if (addr != 0x3da && addr != 0x3ba) + // pclog("et4000w32p_in: addr %04X %04X:%04X %02X %02X\n", addr, CS, pc, ram[0x487], ram[0x488]); - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; -// pclog("%04X\n",addr); + // pclog("%04X\n",addr); - switch (addr) { - case 0x3c5: - if ((svga->seqaddr & 0xf) == 7) - return svga->seqregs[svga->seqaddr & 0xf] | 4; - break; + switch (addr) { + case 0x3c5: + if ((svga->seqaddr & 0xf) == 7) + return svga->seqregs[svga->seqaddr & 0xf] | 4; + break; - case 0x3C6: - case 0x3C7: - case 0x3C8: - case 0x3C9:return stg_ramdac_in(addr, &et4000->ramdac, svga); + case 0x3C6: + case 0x3C7: + case 0x3C8: + case 0x3C9: + return stg_ramdac_in(addr, &et4000->ramdac, svga); - case 0x3CB:return et4000->banking2; - case 0x3CD:return et4000->banking; - case 0x3D4:return svga->crtcreg; - case 0x3D5: -// pclog("Read CRTC R%02X %02X\n", crtcreg, crtc[crtcreg]); - return svga->crtc[svga->crtcreg]; + case 0x3CB: + return et4000->banking2; + case 0x3CD: + return et4000->banking; + case 0x3D4: + return svga->crtcreg; + case 0x3D5: + // pclog("Read CRTC R%02X %02X\n", crtcreg, crtc[crtcreg]); + return svga->crtc[svga->crtcreg]; - case 0x3DA:svga->attrff = 0; - svga->cgastat ^= 0x30; - temp = svga->cgastat & 0x39; - if (svga->hdisp_on) - temp |= 2; - if (!(svga->cgastat & 8)) - temp |= 0x80; -// pclog("3DA in %02X\n",temp); - return temp; + case 0x3DA: + svga->attrff = 0; + svga->cgastat ^= 0x30; + temp = svga->cgastat & 0x39; + if (svga->hdisp_on) + temp |= 2; + if (!(svga->cgastat & 8)) + temp |= 0x80; + // pclog("3DA in %02X\n",temp); + return temp; - case 0x210A: - case 0x211A: - case 0x212A: - case 0x213A: - case 0x214A: - case 0x215A: - case 0x216A: - case 0x217A:return et4000->index; - case 0x210B: - case 0x211B: - case 0x212B: - case 0x213B: - case 0x214B: - case 0x215B: - case 0x216B: - case 0x217B: - if (et4000->index == 0xec) - return (et4000->regs[0xec] & 0xf) | 0x60; /*ET4000/W32p rev D*/ - if (et4000->index == 0xef) { - if (PCI && et4000->is_pci) - return et4000->regs[0xef] | 0xe0; /*PCI*/ - else - return et4000->regs[0xef] | 0x60; /*VESA local bus*/ - } - return et4000->regs[et4000->index]; - } - return svga_in(addr, svga); + case 0x210A: + case 0x211A: + case 0x212A: + case 0x213A: + case 0x214A: + case 0x215A: + case 0x216A: + case 0x217A: + return et4000->index; + case 0x210B: + case 0x211B: + case 0x212B: + case 0x213B: + case 0x214B: + case 0x215B: + case 0x216B: + case 0x217B: + if (et4000->index == 0xec) + return (et4000->regs[0xec] & 0xf) | 0x60; /*ET4000/W32p rev D*/ + if (et4000->index == 0xef) { + if (PCI && et4000->is_pci) + return et4000->regs[0xef] | 0xe0; /*PCI*/ + else + return et4000->regs[0xef] | 0x60; /*VESA local bus*/ + } + return et4000->regs[et4000->index]; + } + return svga_in(addr, svga); } void et4000w32p_recalctimings(svga_t *svga) { - et4000w32p_t *et4000 = (et4000w32p_t *)svga->p; -// pclog("Recalc %08X ",svga_ma); - svga->ma_latch |= (svga->crtc[0x33] & 0x7) << 16; -// pclog("SVGA_MA %08X %i\n", svga_ma, (svga_miscout >> 2) & 3); - if (svga->crtc[0x35] & 0x01) - svga->vblankstart += 0x400; - if (svga->crtc[0x35] & 0x02) - svga->vtotal += 0x400; - if (svga->crtc[0x35] & 0x04) - svga->dispend += 0x400; - if (svga->crtc[0x35] & 0x08) - svga->vsyncstart += 0x400; - if (svga->crtc[0x35] & 0x10) - svga->split += 0x400; - if (svga->crtc[0x3F] & 0x80) - svga->rowoffset += 0x100; - if (svga->crtc[0x3F] & 0x01) - svga->htotal += 256; - if (svga->attrregs[0x16] & 0x20) - svga->hdisp <<= 1; + et4000w32p_t *et4000 = (et4000w32p_t *)svga->p; + // pclog("Recalc %08X ",svga_ma); + svga->ma_latch |= (svga->crtc[0x33] & 0x7) << 16; + // pclog("SVGA_MA %08X %i\n", svga_ma, (svga_miscout >> 2) & 3); + if (svga->crtc[0x35] & 0x01) + svga->vblankstart += 0x400; + if (svga->crtc[0x35] & 0x02) + svga->vtotal += 0x400; + if (svga->crtc[0x35] & 0x04) + svga->dispend += 0x400; + if (svga->crtc[0x35] & 0x08) + svga->vsyncstart += 0x400; + if (svga->crtc[0x35] & 0x10) + svga->split += 0x400; + if (svga->crtc[0x3F] & 0x80) + svga->rowoffset += 0x100; + if (svga->crtc[0x3F] & 0x01) + svga->htotal += 256; + if (svga->attrregs[0x16] & 0x20) + svga->hdisp <<= 1; - switch ((svga->miscout >> 2) & 3) { - case 0: - case 1:break; - case 2: - case 3:svga->clock = (cpuclock * (double)(1ull << 32)) / icd2061_getfreq(&et4000->icd2061, 2); - break; - } + switch ((svga->miscout >> 2) & 3) { + case 0: + case 1: + break; + case 2: + case 3: + svga->clock = (cpuclock * (double)(1ull << 32)) / icd2061_getfreq(&et4000->icd2061, 2); + break; + } - switch (svga->bpp) { - case 15: - case 16:svga->hdisp >>= 1; - break; - case 24:svga->hdisp /= 3; - break; - } + switch (svga->bpp) { + case 15: + case 16: + svga->hdisp >>= 1; + break; + case 24: + svga->hdisp /= 3; + break; + } } void et4000w32p_recalcmapping(et4000w32p_t *et4000) { - svga_t *svga = &et4000->svga; + svga_t *svga = &et4000->svga; - if (!(et4000->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) { - pclog("Update mapping - PCI disabled\n"); - mem_mapping_disable(&svga->mapping); - mem_mapping_disable(&et4000->linear_mapping); - mem_mapping_disable(&et4000->mmu_mapping); - return; - } + if (!(et4000->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) { + pclog("Update mapping - PCI disabled\n"); + mem_mapping_disable(&svga->mapping); + mem_mapping_disable(&et4000->linear_mapping); + mem_mapping_disable(&et4000->mmu_mapping); + return; + } - pclog("recalcmapping %p\n", svga); - if (svga->crtc[0x36] & 0x10) /*Linear frame buffer*/ - { - mem_mapping_set_addr(&et4000->linear_mapping, et4000->linearbase, 0x200000); - mem_mapping_disable(&svga->mapping); - mem_mapping_disable(&et4000->mmu_mapping); - } else { - int map = (svga->gdcreg[6] & 0xc) >> 2; - if (svga->crtc[0x36] & 0x20) - map |= 4; - if (svga->crtc[0x36] & 0x08) - map |= 8; - switch (map) { - case 0x0: - case 0x4: - case 0x8: - case 0xC: /*128k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); - mem_mapping_disable(&et4000->mmu_mapping); - svga->banked_mask = 0x1ffff; - break; - case 0x1: /*64k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - mem_mapping_disable(&et4000->mmu_mapping); - svga->banked_mask = 0xffff; - break; - case 0x2: /*32k at B0000*/ - mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); - mem_mapping_disable(&et4000->mmu_mapping); - svga->banked_mask = 0x7fff; - break; - case 0x3: /*32k at B8000*/ - mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); - mem_mapping_disable(&et4000->mmu_mapping); - svga->banked_mask = 0x7fff; - break; - case 0x5: - case 0x9: - case 0xD: /*64k at A0000, MMU at B8000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - mem_mapping_set_addr(&et4000->mmu_mapping, 0xb8000, 0x08000); - svga->banked_mask = 0xffff; - break; - case 0x6: - case 0xA: - case 0xE: /*32k at B0000, MMU at A8000*/ - mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); - mem_mapping_set_addr(&et4000->mmu_mapping, 0xa8000, 0x08000); - svga->banked_mask = 0x7fff; - break; - case 0x7: - case 0xB: - case 0xF: /*32k at B8000, MMU at A8000*/ - mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); - mem_mapping_set_addr(&et4000->mmu_mapping, 0xa8000, 0x08000); - svga->banked_mask = 0x7fff; - break; - } + pclog("recalcmapping %p\n", svga); + if (svga->crtc[0x36] & 0x10) /*Linear frame buffer*/ + { + mem_mapping_set_addr(&et4000->linear_mapping, et4000->linearbase, 0x200000); + mem_mapping_disable(&svga->mapping); + mem_mapping_disable(&et4000->mmu_mapping); + } else { + int map = (svga->gdcreg[6] & 0xc) >> 2; + if (svga->crtc[0x36] & 0x20) + map |= 4; + if (svga->crtc[0x36] & 0x08) + map |= 8; + switch (map) { + case 0x0: + case 0x4: + case 0x8: + case 0xC: /*128k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); + mem_mapping_disable(&et4000->mmu_mapping); + svga->banked_mask = 0x1ffff; + break; + case 0x1: /*64k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + mem_mapping_disable(&et4000->mmu_mapping); + svga->banked_mask = 0xffff; + break; + case 0x2: /*32k at B0000*/ + mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); + mem_mapping_disable(&et4000->mmu_mapping); + svga->banked_mask = 0x7fff; + break; + case 0x3: /*32k at B8000*/ + mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); + mem_mapping_disable(&et4000->mmu_mapping); + svga->banked_mask = 0x7fff; + break; + case 0x5: + case 0x9: + case 0xD: /*64k at A0000, MMU at B8000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + mem_mapping_set_addr(&et4000->mmu_mapping, 0xb8000, 0x08000); + svga->banked_mask = 0xffff; + break; + case 0x6: + case 0xA: + case 0xE: /*32k at B0000, MMU at A8000*/ + mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); + mem_mapping_set_addr(&et4000->mmu_mapping, 0xa8000, 0x08000); + svga->banked_mask = 0x7fff; + break; + case 0x7: + case 0xB: + case 0xF: /*32k at B8000, MMU at A8000*/ + mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); + mem_mapping_set_addr(&et4000->mmu_mapping, 0xa8000, 0x08000); + svga->banked_mask = 0x7fff; + break; + } - mem_mapping_disable(&et4000->linear_mapping); -// pclog("ET4K map %02X\n", map); - } - et4000->linearbase_old = et4000->linearbase; + mem_mapping_disable(&et4000->linear_mapping); + // pclog("ET4K map %02X\n", map); + } + et4000->linearbase_old = et4000->linearbase; - if (!et4000->interleaved && (et4000->svga.crtc[0x32] & 0x80)) - mem_mapping_disable(&svga->mapping); + if (!et4000->interleaved && (et4000->svga.crtc[0x32] & 0x80)) + mem_mapping_disable(&svga->mapping); } #define ACL_WRST 1 #define ACL_RDST 2 #define ACL_XYST 4 -#define ACL_SSO 8 +#define ACL_SSO 8 static void et4000w32p_accel_write_fifo(et4000w32p_t *et4000, uint32_t addr, uint8_t val) { - switch (addr & 0x7fff) { - case 0x7f80:et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0xFFFFFF00) | val; - break; - case 0x7f81:et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0xFFFF00FF) | (val << 8); - break; - case 0x7f82:et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0xFF00FFFF) | (val << 16); - break; - case 0x7f83:et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0x00FFFFFF) | (val << 24); - break; - case 0x7f84:et4000->acl.queued.source_addr = (et4000->acl.queued.source_addr & 0xFFFFFF00) | val; - break; - case 0x7f85:et4000->acl.queued.source_addr = (et4000->acl.queued.source_addr & 0xFFFF00FF) | (val << 8); - break; - case 0x7f86:et4000->acl.queued.source_addr = (et4000->acl.queued.source_addr & 0xFF00FFFF) | (val << 16); - break; - case 0x7f87:et4000->acl.queued.source_addr = (et4000->acl.queued.source_addr & 0x00FFFFFF) | (val << 24); - break; - case 0x7f88:et4000->acl.queued.pattern_off = (et4000->acl.queued.pattern_off & 0xFF00) | val; - break; - case 0x7f89:et4000->acl.queued.pattern_off = (et4000->acl.queued.pattern_off & 0x00FF) | (val << 8); - break; - case 0x7f8a:et4000->acl.queued.source_off = (et4000->acl.queued.source_off & 0xFF00) | val; - break; - case 0x7f8b:et4000->acl.queued.source_off = (et4000->acl.queued.source_off & 0x00FF) | (val << 8); - break; - case 0x7f8c:et4000->acl.queued.dest_off = (et4000->acl.queued.dest_off & 0xFF00) | val; - break; - case 0x7f8d:et4000->acl.queued.dest_off = (et4000->acl.queued.dest_off & 0x00FF) | (val << 8); - break; - case 0x7f8e:et4000->acl.queued.pixel_depth = val; - break; - case 0x7f8f:et4000->acl.queued.xy_dir = val; - break; - case 0x7f90:et4000->acl.queued.pattern_wrap = val; - break; - case 0x7f92:et4000->acl.queued.source_wrap = val; - break; - case 0x7f98:et4000->acl.queued.count_x = (et4000->acl.queued.count_x & 0xFF00) | val; - break; - case 0x7f99:et4000->acl.queued.count_x = (et4000->acl.queued.count_x & 0x00FF) | (val << 8); - break; - case 0x7f9a:et4000->acl.queued.count_y = (et4000->acl.queued.count_y & 0xFF00) | val; - break; - case 0x7f9b:et4000->acl.queued.count_y = (et4000->acl.queued.count_y & 0x00FF) | (val << 8); - break; - case 0x7f9c:et4000->acl.queued.ctrl_routing = val; - break; - case 0x7f9d:et4000->acl.queued.ctrl_reload = val; - break; - case 0x7f9e:et4000->acl.queued.rop_bg = val; - break; - case 0x7f9f:et4000->acl.queued.rop_fg = val; - break; - case 0x7fa0:et4000->acl.queued.dest_addr = (et4000->acl.queued.dest_addr & 0xFFFFFF00) | val; - break; - case 0x7fa1:et4000->acl.queued.dest_addr = (et4000->acl.queued.dest_addr & 0xFFFF00FF) | (val << 8); - break; - case 0x7fa2:et4000->acl.queued.dest_addr = (et4000->acl.queued.dest_addr & 0xFF00FFFF) | (val << 16); - break; - case 0x7fa3:et4000->acl.queued.dest_addr = (et4000->acl.queued.dest_addr & 0x00FFFFFF) | (val << 24); - et4000->acl.internal = et4000->acl.queued; - et4000w32_blit_start(et4000); - if (!(et4000->acl.queued.ctrl_routing & 0x43)) { - et4000w32_blit(0xFFFFFF, ~0, 0, 0, et4000); - } - if ((et4000->acl.queued.ctrl_routing & 0x40) && !(et4000->acl.internal.ctrl_routing & 3)) - et4000w32_blit(4, ~0, 0, 0, et4000); - break; - case 0x7fa4:et4000->acl.queued.mix_addr = (et4000->acl.queued.mix_addr & 0xFFFFFF00) | val; - break; - case 0x7fa5:et4000->acl.queued.mix_addr = (et4000->acl.queued.mix_addr & 0xFFFF00FF) | (val << 8); - break; - case 0x7fa6:et4000->acl.queued.mix_addr = (et4000->acl.queued.mix_addr & 0xFF00FFFF) | (val << 16); - break; - case 0x7fa7:et4000->acl.queued.mix_addr = (et4000->acl.queued.mix_addr & 0x00FFFFFF) | (val << 24); - break; - case 0x7fa8:et4000->acl.queued.mix_off = (et4000->acl.queued.mix_off & 0xFF00) | val; - break; - case 0x7fa9:et4000->acl.queued.mix_off = (et4000->acl.queued.mix_off & 0x00FF) | (val << 8); - break; - case 0x7faa:et4000->acl.queued.error = (et4000->acl.queued.error & 0xFF00) | val; - break; - case 0x7fab:et4000->acl.queued.error = (et4000->acl.queued.error & 0x00FF) | (val << 8); - break; - case 0x7fac:et4000->acl.queued.dmin = (et4000->acl.queued.dmin & 0xFF00) | val; - break; - case 0x7fad:et4000->acl.queued.dmin = (et4000->acl.queued.dmin & 0x00FF) | (val << 8); - break; - case 0x7fae:et4000->acl.queued.dmaj = (et4000->acl.queued.dmaj & 0xFF00) | val; - break; - case 0x7faf:et4000->acl.queued.dmaj = (et4000->acl.queued.dmaj & 0x00FF) | (val << 8); - break; - } + switch (addr & 0x7fff) { + case 0x7f80: + et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0xFFFFFF00) | val; + break; + case 0x7f81: + et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0xFFFF00FF) | (val << 8); + break; + case 0x7f82: + et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0xFF00FFFF) | (val << 16); + break; + case 0x7f83: + et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0x00FFFFFF) | (val << 24); + break; + case 0x7f84: + et4000->acl.queued.source_addr = (et4000->acl.queued.source_addr & 0xFFFFFF00) | val; + break; + case 0x7f85: + et4000->acl.queued.source_addr = (et4000->acl.queued.source_addr & 0xFFFF00FF) | (val << 8); + break; + case 0x7f86: + et4000->acl.queued.source_addr = (et4000->acl.queued.source_addr & 0xFF00FFFF) | (val << 16); + break; + case 0x7f87: + et4000->acl.queued.source_addr = (et4000->acl.queued.source_addr & 0x00FFFFFF) | (val << 24); + break; + case 0x7f88: + et4000->acl.queued.pattern_off = (et4000->acl.queued.pattern_off & 0xFF00) | val; + break; + case 0x7f89: + et4000->acl.queued.pattern_off = (et4000->acl.queued.pattern_off & 0x00FF) | (val << 8); + break; + case 0x7f8a: + et4000->acl.queued.source_off = (et4000->acl.queued.source_off & 0xFF00) | val; + break; + case 0x7f8b: + et4000->acl.queued.source_off = (et4000->acl.queued.source_off & 0x00FF) | (val << 8); + break; + case 0x7f8c: + et4000->acl.queued.dest_off = (et4000->acl.queued.dest_off & 0xFF00) | val; + break; + case 0x7f8d: + et4000->acl.queued.dest_off = (et4000->acl.queued.dest_off & 0x00FF) | (val << 8); + break; + case 0x7f8e: + et4000->acl.queued.pixel_depth = val; + break; + case 0x7f8f: + et4000->acl.queued.xy_dir = val; + break; + case 0x7f90: + et4000->acl.queued.pattern_wrap = val; + break; + case 0x7f92: + et4000->acl.queued.source_wrap = val; + break; + case 0x7f98: + et4000->acl.queued.count_x = (et4000->acl.queued.count_x & 0xFF00) | val; + break; + case 0x7f99: + et4000->acl.queued.count_x = (et4000->acl.queued.count_x & 0x00FF) | (val << 8); + break; + case 0x7f9a: + et4000->acl.queued.count_y = (et4000->acl.queued.count_y & 0xFF00) | val; + break; + case 0x7f9b: + et4000->acl.queued.count_y = (et4000->acl.queued.count_y & 0x00FF) | (val << 8); + break; + case 0x7f9c: + et4000->acl.queued.ctrl_routing = val; + break; + case 0x7f9d: + et4000->acl.queued.ctrl_reload = val; + break; + case 0x7f9e: + et4000->acl.queued.rop_bg = val; + break; + case 0x7f9f: + et4000->acl.queued.rop_fg = val; + break; + case 0x7fa0: + et4000->acl.queued.dest_addr = (et4000->acl.queued.dest_addr & 0xFFFFFF00) | val; + break; + case 0x7fa1: + et4000->acl.queued.dest_addr = (et4000->acl.queued.dest_addr & 0xFFFF00FF) | (val << 8); + break; + case 0x7fa2: + et4000->acl.queued.dest_addr = (et4000->acl.queued.dest_addr & 0xFF00FFFF) | (val << 16); + break; + case 0x7fa3: + et4000->acl.queued.dest_addr = (et4000->acl.queued.dest_addr & 0x00FFFFFF) | (val << 24); + et4000->acl.internal = et4000->acl.queued; + et4000w32_blit_start(et4000); + if (!(et4000->acl.queued.ctrl_routing & 0x43)) { + et4000w32_blit(0xFFFFFF, ~0, 0, 0, et4000); + } + if ((et4000->acl.queued.ctrl_routing & 0x40) && !(et4000->acl.internal.ctrl_routing & 3)) + et4000w32_blit(4, ~0, 0, 0, et4000); + break; + case 0x7fa4: + et4000->acl.queued.mix_addr = (et4000->acl.queued.mix_addr & 0xFFFFFF00) | val; + break; + case 0x7fa5: + et4000->acl.queued.mix_addr = (et4000->acl.queued.mix_addr & 0xFFFF00FF) | (val << 8); + break; + case 0x7fa6: + et4000->acl.queued.mix_addr = (et4000->acl.queued.mix_addr & 0xFF00FFFF) | (val << 16); + break; + case 0x7fa7: + et4000->acl.queued.mix_addr = (et4000->acl.queued.mix_addr & 0x00FFFFFF) | (val << 24); + break; + case 0x7fa8: + et4000->acl.queued.mix_off = (et4000->acl.queued.mix_off & 0xFF00) | val; + break; + case 0x7fa9: + et4000->acl.queued.mix_off = (et4000->acl.queued.mix_off & 0x00FF) | (val << 8); + break; + case 0x7faa: + et4000->acl.queued.error = (et4000->acl.queued.error & 0xFF00) | val; + break; + case 0x7fab: + et4000->acl.queued.error = (et4000->acl.queued.error & 0x00FF) | (val << 8); + break; + case 0x7fac: + et4000->acl.queued.dmin = (et4000->acl.queued.dmin & 0xFF00) | val; + break; + case 0x7fad: + et4000->acl.queued.dmin = (et4000->acl.queued.dmin & 0x00FF) | (val << 8); + break; + case 0x7fae: + et4000->acl.queued.dmaj = (et4000->acl.queued.dmaj & 0xFF00) | val; + break; + case 0x7faf: + et4000->acl.queued.dmaj = (et4000->acl.queued.dmaj & 0x00FF) | (val << 8); + break; + } } static void et4000w32p_accel_write_mmu(et4000w32p_t *et4000, uint32_t addr, uint8_t val) { - if (!(et4000->acl.status & ACL_XYST)) - return; - if (et4000->acl.internal.ctrl_routing & 3) { - if ((et4000->acl.internal.ctrl_routing & 3) == 2) { - if (et4000->acl.mix_addr & 7) - et4000w32_blit(8 - (et4000->acl.mix_addr & 7), val >> (et4000->acl.mix_addr & 7), 0, 1, et4000); - else - et4000w32_blit(8, val, 0, 1, et4000); - } else if ((et4000->acl.internal.ctrl_routing & 3) == 1) - et4000w32_blit(1, ~0, val, 2, et4000); - } + if (!(et4000->acl.status & ACL_XYST)) + return; + if (et4000->acl.internal.ctrl_routing & 3) { + if ((et4000->acl.internal.ctrl_routing & 3) == 2) { + if (et4000->acl.mix_addr & 7) + et4000w32_blit(8 - (et4000->acl.mix_addr & 7), val >> (et4000->acl.mix_addr & 7), 0, 1, et4000); + else + et4000w32_blit(8, val, 0, 1, et4000); + } else if ((et4000->acl.internal.ctrl_routing & 3) == 1) + et4000w32_blit(1, ~0, val, 2, et4000); + } } static void fifo_thread(void *param) { - et4000w32p_t *et4000 = (et4000w32p_t *)param; + et4000w32p_t *et4000 = (et4000w32p_t *)param; - while (1) { - thread_set_event(et4000->fifo_not_full_event); - thread_wait_event(et4000->wake_fifo_thread, -1); - thread_reset_event(et4000->wake_fifo_thread); - et4000->blitter_busy = 1; - while (!FIFO_EMPTY) { - uint64_t start_time = timer_read(); - uint64_t end_time; - fifo_entry_t *fifo = &et4000->fifo[et4000->fifo_read_idx & FIFO_MASK]; + while (1) { + thread_set_event(et4000->fifo_not_full_event); + thread_wait_event(et4000->wake_fifo_thread, -1); + thread_reset_event(et4000->wake_fifo_thread); + et4000->blitter_busy = 1; + while (!FIFO_EMPTY) { + uint64_t start_time = timer_read(); + uint64_t end_time; + fifo_entry_t *fifo = &et4000->fifo[et4000->fifo_read_idx & FIFO_MASK]; - switch (fifo->addr_type & FIFO_TYPE) { - case FIFO_WRITE_BYTE:et4000w32p_accel_write_fifo(et4000, fifo->addr_type & FIFO_ADDR, fifo->val); - break; - case FIFO_WRITE_MMU:et4000w32p_accel_write_mmu(et4000, fifo->addr_type & FIFO_ADDR, fifo->val); - break; - } + switch (fifo->addr_type & FIFO_TYPE) { + case FIFO_WRITE_BYTE: + et4000w32p_accel_write_fifo(et4000, fifo->addr_type & FIFO_ADDR, fifo->val); + break; + case FIFO_WRITE_MMU: + et4000w32p_accel_write_mmu(et4000, fifo->addr_type & FIFO_ADDR, fifo->val); + break; + } - et4000->fifo_read_idx++; - fifo->addr_type = FIFO_INVALID; + et4000->fifo_read_idx++; + fifo->addr_type = FIFO_INVALID; - if (FIFO_ENTRIES > 0xe000) - thread_set_event(et4000->fifo_not_full_event); + if (FIFO_ENTRIES > 0xe000) + thread_set_event(et4000->fifo_not_full_event); - end_time = timer_read(); - et4000->blitter_time += end_time - start_time; - } - et4000->blitter_busy = 0; - } + end_time = timer_read(); + et4000->blitter_time += end_time - start_time; + } + et4000->blitter_busy = 0; + } } static inline void wake_fifo_thread(et4000w32p_t *et4000) { - thread_set_event(et4000->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ + thread_set_event(et4000->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ } static void et4000w32p_wait_fifo_idle(et4000w32p_t *et4000) { - while (!FIFO_EMPTY) { - wake_fifo_thread(et4000); - thread_wait_event(et4000->fifo_not_full_event, 1); - } + while (!FIFO_EMPTY) { + wake_fifo_thread(et4000); + thread_wait_event(et4000->fifo_not_full_event, 1); + } } static void et4000w32p_queue(et4000w32p_t *et4000, uint32_t addr, uint32_t val, uint32_t type) { - fifo_entry_t *fifo = &et4000->fifo[et4000->fifo_write_idx & FIFO_MASK]; + fifo_entry_t *fifo = &et4000->fifo[et4000->fifo_write_idx & FIFO_MASK]; - if (FIFO_FULL) { - thread_reset_event(et4000->fifo_not_full_event); - if (FIFO_FULL) { - thread_wait_event(et4000->fifo_not_full_event, -1); /*Wait for room in ringbuffer*/ - } - } + if (FIFO_FULL) { + thread_reset_event(et4000->fifo_not_full_event); + if (FIFO_FULL) { + thread_wait_event(et4000->fifo_not_full_event, -1); /*Wait for room in ringbuffer*/ + } + } - fifo->val = val; - fifo->addr_type = (addr & FIFO_ADDR) | type; + fifo->val = val; + fifo->addr_type = (addr & FIFO_ADDR) | type; - et4000->fifo_write_idx++; + et4000->fifo_write_idx++; - if (FIFO_ENTRIES > 0xe000 || FIFO_ENTRIES < 8) - wake_fifo_thread(et4000); + if (FIFO_ENTRIES > 0xe000 || FIFO_ENTRIES < 8) + wake_fifo_thread(et4000); } void et4000w32p_mmu_write(uint32_t addr, uint8_t val, void *p) { - et4000w32p_t *et4000 = (et4000w32p_t *)p; - svga_t *svga = &et4000->svga; - int bank; -// pclog("ET4K write %08X %02X %02X %04X(%08X):%08X\n",addr,val,et4000->acl.status,et4000->acl.internal.ctrl_routing,CS,cs,pc); -// et4000->acl.status |= ACL_RDST; - switch (addr & 0x6000) { - case 0x0000: /*MMU 0*/ - case 0x2000: /*MMU 1*/ - case 0x4000: /*MMU 2*/ - bank = (addr >> 13) & 3; - if (et4000->mmu.ctrl & (1 << bank)) { - et4000w32p_queue(et4000, addr & 0x7fff, val, FIFO_WRITE_MMU); - } else { - if ((addr & 0x1fff) + et4000->mmu.base[bank] < svga->vram_max) { - svga->vram[(addr & 0x1fff) + et4000->mmu.base[bank]] = val; - svga->changedvram[((addr & 0x1fff) + et4000->mmu.base[bank]) >> 12] = changeframecount; - } - } - break; - case 0x6000: - if ((addr & 0x7fff) >= 0x7f80) { - et4000w32p_queue(et4000, addr & 0x7fff, val, FIFO_WRITE_BYTE); - } else - switch (addr & 0x7fff) { - case 0x7f00:et4000->mmu.base[0] = (et4000->mmu.base[0] & 0xFFFFFF00) | val; - break; - case 0x7f01:et4000->mmu.base[0] = (et4000->mmu.base[0] & 0xFFFF00FF) | (val << 8); - break; - case 0x7f02:et4000->mmu.base[0] = (et4000->mmu.base[0] & 0xFF00FFFF) | (val << 16); - break; - case 0x7f03:et4000->mmu.base[0] = (et4000->mmu.base[0] & 0x00FFFFFF) | (val << 24); - break; - case 0x7f04:et4000->mmu.base[1] = (et4000->mmu.base[1] & 0xFFFFFF00) | val; - break; - case 0x7f05:et4000->mmu.base[1] = (et4000->mmu.base[1] & 0xFFFF00FF) | (val << 8); - break; - case 0x7f06:et4000->mmu.base[1] = (et4000->mmu.base[1] & 0xFF00FFFF) | (val << 16); - break; - case 0x7f07:et4000->mmu.base[1] = (et4000->mmu.base[1] & 0x00FFFFFF) | (val << 24); - break; - case 0x7f08:et4000->mmu.base[2] = (et4000->mmu.base[2] & 0xFFFFFF00) | val; - break; - case 0x7f09:et4000->mmu.base[2] = (et4000->mmu.base[2] & 0xFFFF00FF) | (val << 8); - break; - case 0x7f0a:et4000->mmu.base[2] = (et4000->mmu.base[2] & 0xFF00FFFF) | (val << 16); - break; - case 0x7f0d:et4000->mmu.base[2] = (et4000->mmu.base[2] & 0x00FFFFFF) | (val << 24); - break; - case 0x7f13:et4000->mmu.ctrl = val; - break; - } - break; - } + et4000w32p_t *et4000 = (et4000w32p_t *)p; + svga_t *svga = &et4000->svga; + int bank; + // pclog("ET4K write %08X %02X %02X + // %04X(%08X):%08X\n",addr,val,et4000->acl.status,et4000->acl.internal.ctrl_routing,CS,cs,pc); et4000->acl.status + // |= ACL_RDST; + switch (addr & 0x6000) { + case 0x0000: /*MMU 0*/ + case 0x2000: /*MMU 1*/ + case 0x4000: /*MMU 2*/ + bank = (addr >> 13) & 3; + if (et4000->mmu.ctrl & (1 << bank)) { + et4000w32p_queue(et4000, addr & 0x7fff, val, FIFO_WRITE_MMU); + } else { + if ((addr & 0x1fff) + et4000->mmu.base[bank] < svga->vram_max) { + svga->vram[(addr & 0x1fff) + et4000->mmu.base[bank]] = val; + svga->changedvram[((addr & 0x1fff) + et4000->mmu.base[bank]) >> 12] = changeframecount; + } + } + break; + case 0x6000: + if ((addr & 0x7fff) >= 0x7f80) { + et4000w32p_queue(et4000, addr & 0x7fff, val, FIFO_WRITE_BYTE); + } else + switch (addr & 0x7fff) { + case 0x7f00: + et4000->mmu.base[0] = (et4000->mmu.base[0] & 0xFFFFFF00) | val; + break; + case 0x7f01: + et4000->mmu.base[0] = (et4000->mmu.base[0] & 0xFFFF00FF) | (val << 8); + break; + case 0x7f02: + et4000->mmu.base[0] = (et4000->mmu.base[0] & 0xFF00FFFF) | (val << 16); + break; + case 0x7f03: + et4000->mmu.base[0] = (et4000->mmu.base[0] & 0x00FFFFFF) | (val << 24); + break; + case 0x7f04: + et4000->mmu.base[1] = (et4000->mmu.base[1] & 0xFFFFFF00) | val; + break; + case 0x7f05: + et4000->mmu.base[1] = (et4000->mmu.base[1] & 0xFFFF00FF) | (val << 8); + break; + case 0x7f06: + et4000->mmu.base[1] = (et4000->mmu.base[1] & 0xFF00FFFF) | (val << 16); + break; + case 0x7f07: + et4000->mmu.base[1] = (et4000->mmu.base[1] & 0x00FFFFFF) | (val << 24); + break; + case 0x7f08: + et4000->mmu.base[2] = (et4000->mmu.base[2] & 0xFFFFFF00) | val; + break; + case 0x7f09: + et4000->mmu.base[2] = (et4000->mmu.base[2] & 0xFFFF00FF) | (val << 8); + break; + case 0x7f0a: + et4000->mmu.base[2] = (et4000->mmu.base[2] & 0xFF00FFFF) | (val << 16); + break; + case 0x7f0d: + et4000->mmu.base[2] = (et4000->mmu.base[2] & 0x00FFFFFF) | (val << 24); + break; + case 0x7f13: + et4000->mmu.ctrl = val; + break; + } + break; + } } uint8_t et4000w32p_mmu_read(uint32_t addr, void *p) { - et4000w32p_t *et4000 = (et4000w32p_t *)p; - svga_t *svga = &et4000->svga; - int bank; - uint8_t temp; -// pclog("ET4K read %08X %04X(%08X):%08X\n",addr,CS,cs,pc); - switch (addr & 0x6000) { - case 0x0000: /*MMU 0*/ - case 0x2000: /*MMU 1*/ - case 0x4000: /*MMU 2*/ - bank = (addr >> 13) & 3; - if (et4000->mmu.ctrl & (1 << bank)) { - et4000w32p_wait_fifo_idle(et4000); - temp = 0xff; - if (et4000->acl.cpu_dat_pos) { - et4000->acl.cpu_dat_pos--; - temp = et4000->acl.cpu_dat & 0xff; - et4000->acl.cpu_dat >>= 8; - } - if ((et4000->acl.queued.ctrl_routing & 0x40) && !et4000->acl.cpu_dat_pos && !(et4000->acl.internal.ctrl_routing & 3)) - et4000w32_blit(4, ~0, 0, 0, et4000); - /*???*/ - return temp; - } - if ((addr & 0x1fff) + et4000->mmu.base[bank] >= svga->vram_max) - return 0xff; - return svga->vram[(addr & 0x1fff) + et4000->mmu.base[bank]]; + et4000w32p_t *et4000 = (et4000w32p_t *)p; + svga_t *svga = &et4000->svga; + int bank; + uint8_t temp; + // pclog("ET4K read %08X %04X(%08X):%08X\n",addr,CS,cs,pc); + switch (addr & 0x6000) { + case 0x0000: /*MMU 0*/ + case 0x2000: /*MMU 1*/ + case 0x4000: /*MMU 2*/ + bank = (addr >> 13) & 3; + if (et4000->mmu.ctrl & (1 << bank)) { + et4000w32p_wait_fifo_idle(et4000); + temp = 0xff; + if (et4000->acl.cpu_dat_pos) { + et4000->acl.cpu_dat_pos--; + temp = et4000->acl.cpu_dat & 0xff; + et4000->acl.cpu_dat >>= 8; + } + if ((et4000->acl.queued.ctrl_routing & 0x40) && !et4000->acl.cpu_dat_pos && + !(et4000->acl.internal.ctrl_routing & 3)) + et4000w32_blit(4, ~0, 0, 0, et4000); + /*???*/ + return temp; + } + if ((addr & 0x1fff) + et4000->mmu.base[bank] >= svga->vram_max) + return 0xff; + return svga->vram[(addr & 0x1fff) + et4000->mmu.base[bank]]; - case 0x6000: - if ((addr & 0x7fff) >= 0x7f80) - et4000w32p_wait_fifo_idle(et4000); - switch (addr & 0x7fff) { - case 0x7f00:return et4000->mmu.base[0]; - case 0x7f01:return et4000->mmu.base[0] >> 8; - case 0x7f02:return et4000->mmu.base[0] >> 16; - case 0x7f03:return et4000->mmu.base[0] >> 24; - case 0x7f04:return et4000->mmu.base[1]; - case 0x7f05:return et4000->mmu.base[1] >> 8; - case 0x7f06:return et4000->mmu.base[1] >> 16; - case 0x7f07:return et4000->mmu.base[1] >> 24; - case 0x7f08:return et4000->mmu.base[2]; - case 0x7f09:return et4000->mmu.base[2] >> 8; - case 0x7f0a:return et4000->mmu.base[2] >> 16; - case 0x7f0b:return et4000->mmu.base[2] >> 24; - case 0x7f13:return et4000->mmu.ctrl; + case 0x6000: + if ((addr & 0x7fff) >= 0x7f80) + et4000w32p_wait_fifo_idle(et4000); + switch (addr & 0x7fff) { + case 0x7f00: + return et4000->mmu.base[0]; + case 0x7f01: + return et4000->mmu.base[0] >> 8; + case 0x7f02: + return et4000->mmu.base[0] >> 16; + case 0x7f03: + return et4000->mmu.base[0] >> 24; + case 0x7f04: + return et4000->mmu.base[1]; + case 0x7f05: + return et4000->mmu.base[1] >> 8; + case 0x7f06: + return et4000->mmu.base[1] >> 16; + case 0x7f07: + return et4000->mmu.base[1] >> 24; + case 0x7f08: + return et4000->mmu.base[2]; + case 0x7f09: + return et4000->mmu.base[2] >> 8; + case 0x7f0a: + return et4000->mmu.base[2] >> 16; + case 0x7f0b: + return et4000->mmu.base[2] >> 24; + case 0x7f13: + return et4000->mmu.ctrl; - case 0x7f36:temp = et4000->acl.status; -// et4000->acl.status &= ~ACL_RDST; - temp &= ~0x03; - if (!FIFO_EMPTY) - temp |= 0x02; - if (FIFO_FULL) - temp |= 0x01; -// if (et4000->acl.internal.pos_x!=et4000->acl.internal.count_x || et4000->acl.internal.pos_y!=et4000->acl.internal.count_y) return et4000->acl.status | ACL_XYST; - return temp; - case 0x7f80:return et4000->acl.internal.pattern_addr; - case 0x7f81:return et4000->acl.internal.pattern_addr >> 8; - case 0x7f82:return et4000->acl.internal.pattern_addr >> 16; - case 0x7f83:return et4000->acl.internal.pattern_addr >> 24; - case 0x7f84:return et4000->acl.internal.source_addr; - case 0x7f85:return et4000->acl.internal.source_addr >> 8; - case 0x7f86:return et4000->acl.internal.source_addr >> 16; - case 0x7f87:return et4000->acl.internal.source_addr >> 24; - case 0x7f88:return et4000->acl.internal.pattern_off; - case 0x7f89:return et4000->acl.internal.pattern_off >> 8; - case 0x7f8a:return et4000->acl.internal.source_off; - case 0x7f8b:return et4000->acl.internal.source_off >> 8; - case 0x7f8c:return et4000->acl.internal.dest_off; - case 0x7f8d:return et4000->acl.internal.dest_off >> 8; - case 0x7f8e:return et4000->acl.internal.pixel_depth; - case 0x7f8f:return et4000->acl.internal.xy_dir; - case 0x7f90:return et4000->acl.internal.pattern_wrap; - case 0x7f92:return et4000->acl.internal.source_wrap; - case 0x7f98:return et4000->acl.internal.count_x; - case 0x7f99:return et4000->acl.internal.count_x >> 8; - case 0x7f9a:return et4000->acl.internal.count_y; - case 0x7f9b:return et4000->acl.internal.count_y >> 8; - case 0x7f9c:return et4000->acl.internal.ctrl_routing; - case 0x7f9d:return et4000->acl.internal.ctrl_reload; - case 0x7f9e:return et4000->acl.internal.rop_bg; - case 0x7f9f:return et4000->acl.internal.rop_fg; - case 0x7fa0:return et4000->acl.internal.dest_addr; - case 0x7fa1:return et4000->acl.internal.dest_addr >> 8; - case 0x7fa2:return et4000->acl.internal.dest_addr >> 16; - case 0x7fa3:return et4000->acl.internal.dest_addr >> 24; - } - return 0xff; - } - return 0xff; + case 0x7f36: + temp = et4000->acl.status; + // et4000->acl.status &= ~ACL_RDST; + temp &= ~0x03; + if (!FIFO_EMPTY) + temp |= 0x02; + if (FIFO_FULL) + temp |= 0x01; + // if (et4000->acl.internal.pos_x!=et4000->acl.internal.count_x || + // et4000->acl.internal.pos_y!=et4000->acl.internal.count_y) return + // et4000->acl.status | ACL_XYST; + return temp; + case 0x7f80: + return et4000->acl.internal.pattern_addr; + case 0x7f81: + return et4000->acl.internal.pattern_addr >> 8; + case 0x7f82: + return et4000->acl.internal.pattern_addr >> 16; + case 0x7f83: + return et4000->acl.internal.pattern_addr >> 24; + case 0x7f84: + return et4000->acl.internal.source_addr; + case 0x7f85: + return et4000->acl.internal.source_addr >> 8; + case 0x7f86: + return et4000->acl.internal.source_addr >> 16; + case 0x7f87: + return et4000->acl.internal.source_addr >> 24; + case 0x7f88: + return et4000->acl.internal.pattern_off; + case 0x7f89: + return et4000->acl.internal.pattern_off >> 8; + case 0x7f8a: + return et4000->acl.internal.source_off; + case 0x7f8b: + return et4000->acl.internal.source_off >> 8; + case 0x7f8c: + return et4000->acl.internal.dest_off; + case 0x7f8d: + return et4000->acl.internal.dest_off >> 8; + case 0x7f8e: + return et4000->acl.internal.pixel_depth; + case 0x7f8f: + return et4000->acl.internal.xy_dir; + case 0x7f90: + return et4000->acl.internal.pattern_wrap; + case 0x7f92: + return et4000->acl.internal.source_wrap; + case 0x7f98: + return et4000->acl.internal.count_x; + case 0x7f99: + return et4000->acl.internal.count_x >> 8; + case 0x7f9a: + return et4000->acl.internal.count_y; + case 0x7f9b: + return et4000->acl.internal.count_y >> 8; + case 0x7f9c: + return et4000->acl.internal.ctrl_routing; + case 0x7f9d: + return et4000->acl.internal.ctrl_reload; + case 0x7f9e: + return et4000->acl.internal.rop_bg; + case 0x7f9f: + return et4000->acl.internal.rop_fg; + case 0x7fa0: + return et4000->acl.internal.dest_addr; + case 0x7fa1: + return et4000->acl.internal.dest_addr >> 8; + case 0x7fa2: + return et4000->acl.internal.dest_addr >> 16; + case 0x7fa3: + return et4000->acl.internal.dest_addr >> 24; + } + return 0xff; + } + return 0xff; } static int et4000w32_max_x[8] = {0, 0, 4, 8, 16, 32, 64, 0x70000000}; @@ -731,586 +848,602 @@ static int et4000w32_wrap_y[8] = {1, 2, 4, 8, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF int bltout = 0; void et4000w32_blit_start(et4000w32p_t *et4000) { -// if (et4000->acl.queued.xy_dir&0x80) -// pclog("Blit - %02X %08X (%i,%i) %08X (%i,%i) %08X (%i,%i) %i %i %i %02X %02X %02X\n",et4000->acl.queued.xy_dir,et4000->acl.internal.pattern_addr,(et4000->acl.internal.pattern_addr/3)%640,(et4000->acl.internal.pattern_addr/3)/640,et4000->acl.internal.source_addr,(et4000->acl.internal.source_addr/3)%640,(et4000->acl.internal.source_addr/3)/640,et4000->acl.internal.dest_addr,(et4000->acl.internal.dest_addr/3)%640,(et4000->acl.internal.dest_addr/3)/640,et4000->acl.internal.xy_dir,et4000->acl.internal.count_x,et4000->acl.internal.count_y,et4000->acl.internal.rop_fg,et4000->acl.internal.rop_bg, et4000->acl.internal.ctrl_routing); -// bltout=1; -// bltout=(et4000->acl.internal.count_x==1541); - if (!(et4000->acl.queued.xy_dir & 0x20)) - et4000->acl.internal.error = et4000->acl.internal.dmaj / 2; - et4000->acl.pattern_addr = et4000->acl.internal.pattern_addr; - et4000->acl.source_addr = et4000->acl.internal.source_addr; - et4000->acl.mix_addr = et4000->acl.internal.mix_addr; - et4000->acl.mix_back = et4000->acl.mix_addr; - et4000->acl.dest_addr = et4000->acl.internal.dest_addr; - et4000->acl.dest_back = et4000->acl.dest_addr; - et4000->acl.internal.pos_x = et4000->acl.internal.pos_y = 0; - et4000->acl.pattern_x = et4000->acl.source_x = et4000->acl.pattern_y = et4000->acl.source_y = 0; - et4000->acl.status |= ACL_XYST; - if ((!(et4000->acl.internal.ctrl_routing & 7) || (et4000->acl.internal.ctrl_routing & 4)) && !(et4000->acl.internal.ctrl_routing & 0x40)) - et4000->acl.status |= ACL_SSO; + // if (et4000->acl.queued.xy_dir&0x80) + // pclog("Blit - %02X %08X (%i,%i) %08X (%i,%i) %08X (%i,%i) %i %i %i %02X %02X + // %02X\n",et4000->acl.queued.xy_dir,et4000->acl.internal.pattern_addr,(et4000->acl.internal.pattern_addr/3)%640,(et4000->acl.internal.pattern_addr/3)/640,et4000->acl.internal.source_addr,(et4000->acl.internal.source_addr/3)%640,(et4000->acl.internal.source_addr/3)/640,et4000->acl.internal.dest_addr,(et4000->acl.internal.dest_addr/3)%640,(et4000->acl.internal.dest_addr/3)/640,et4000->acl.internal.xy_dir,et4000->acl.internal.count_x,et4000->acl.internal.count_y,et4000->acl.internal.rop_fg,et4000->acl.internal.rop_bg, + // et4000->acl.internal.ctrl_routing); bltout=1; + // bltout=(et4000->acl.internal.count_x==1541); + if (!(et4000->acl.queued.xy_dir & 0x20)) + et4000->acl.internal.error = et4000->acl.internal.dmaj / 2; + et4000->acl.pattern_addr = et4000->acl.internal.pattern_addr; + et4000->acl.source_addr = et4000->acl.internal.source_addr; + et4000->acl.mix_addr = et4000->acl.internal.mix_addr; + et4000->acl.mix_back = et4000->acl.mix_addr; + et4000->acl.dest_addr = et4000->acl.internal.dest_addr; + et4000->acl.dest_back = et4000->acl.dest_addr; + et4000->acl.internal.pos_x = et4000->acl.internal.pos_y = 0; + et4000->acl.pattern_x = et4000->acl.source_x = et4000->acl.pattern_y = et4000->acl.source_y = 0; + et4000->acl.status |= ACL_XYST; + if ((!(et4000->acl.internal.ctrl_routing & 7) || (et4000->acl.internal.ctrl_routing & 4)) && + !(et4000->acl.internal.ctrl_routing & 0x40)) + et4000->acl.status |= ACL_SSO; - if (et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7]) { - et4000->acl.pattern_x = et4000->acl.pattern_addr & et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7]; - et4000->acl.pattern_addr &= ~et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7]; - } - et4000->acl.pattern_back = et4000->acl.pattern_addr; - if (!(et4000->acl.internal.pattern_wrap & 0x40)) { - et4000->acl.pattern_y = - (et4000->acl.pattern_addr / (et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] + 1)) & (et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7] - 1); - et4000->acl.pattern_back &= ~(((et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] + 1) * et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7]) - 1); - } - et4000->acl.pattern_x_back = et4000->acl.pattern_x; + if (et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7]) { + et4000->acl.pattern_x = et4000->acl.pattern_addr & et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7]; + et4000->acl.pattern_addr &= ~et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7]; + } + et4000->acl.pattern_back = et4000->acl.pattern_addr; + if (!(et4000->acl.internal.pattern_wrap & 0x40)) { + et4000->acl.pattern_y = + (et4000->acl.pattern_addr / (et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] + 1)) & + (et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7] - 1); + et4000->acl.pattern_back &= ~(((et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] + 1) * + et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7]) - + 1); + } + et4000->acl.pattern_x_back = et4000->acl.pattern_x; - if (et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7]) { - et4000->acl.source_x = et4000->acl.source_addr & et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7]; - et4000->acl.source_addr &= ~et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7]; - } - et4000->acl.source_back = et4000->acl.source_addr; - if (!(et4000->acl.internal.source_wrap & 0x40)) { - et4000->acl.source_y = (et4000->acl.source_addr / (et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] + 1)) & (et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7] - 1); - et4000->acl.source_back &= ~(((et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] + 1) * et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7]) - 1); - } - et4000->acl.source_x_back = et4000->acl.source_x; + if (et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7]) { + et4000->acl.source_x = et4000->acl.source_addr & et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7]; + et4000->acl.source_addr &= ~et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7]; + } + et4000->acl.source_back = et4000->acl.source_addr; + if (!(et4000->acl.internal.source_wrap & 0x40)) { + et4000->acl.source_y = (et4000->acl.source_addr / (et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] + 1)) & + (et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7] - 1); + et4000->acl.source_back &= ~(((et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] + 1) * + et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7]) - + 1); + } + et4000->acl.source_x_back = et4000->acl.source_x; - et4000w32_max_x[2] = ((et4000->acl.internal.pixel_depth & 0x30) == 0x20) ? 3 : 4; + et4000w32_max_x[2] = ((et4000->acl.internal.pixel_depth & 0x30) == 0x20) ? 3 : 4; - et4000->acl.internal.count_x += (et4000->acl.internal.pixel_depth >> 4) & 3; - et4000->acl.cpu_dat_pos = 0; - et4000->acl.cpu_dat = 0; + et4000->acl.internal.count_x += (et4000->acl.internal.pixel_depth >> 4) & 3; + et4000->acl.cpu_dat_pos = 0; + et4000->acl.cpu_dat = 0; - et4000->acl.pix_pos = 0; + et4000->acl.pix_pos = 0; } void et4000w32_incx(int c, et4000w32p_t *et4000) { - et4000->acl.dest_addr += c; - et4000->acl.pattern_x += c; - et4000->acl.source_x += c; - et4000->acl.mix_addr += c; - if (et4000->acl.pattern_x >= et4000w32_max_x[et4000->acl.internal.pattern_wrap & 7]) - et4000->acl.pattern_x -= et4000w32_max_x[et4000->acl.internal.pattern_wrap & 7]; - if (et4000->acl.source_x >= et4000w32_max_x[et4000->acl.internal.source_wrap & 7]) - et4000->acl.source_x -= et4000w32_max_x[et4000->acl.internal.source_wrap & 7]; + et4000->acl.dest_addr += c; + et4000->acl.pattern_x += c; + et4000->acl.source_x += c; + et4000->acl.mix_addr += c; + if (et4000->acl.pattern_x >= et4000w32_max_x[et4000->acl.internal.pattern_wrap & 7]) + et4000->acl.pattern_x -= et4000w32_max_x[et4000->acl.internal.pattern_wrap & 7]; + if (et4000->acl.source_x >= et4000w32_max_x[et4000->acl.internal.source_wrap & 7]) + et4000->acl.source_x -= et4000w32_max_x[et4000->acl.internal.source_wrap & 7]; } void et4000w32_decx(int c, et4000w32p_t *et4000) { - et4000->acl.dest_addr -= c; - et4000->acl.pattern_x -= c; - et4000->acl.source_x -= c; - et4000->acl.mix_addr -= c; - if (et4000->acl.pattern_x < 0) - et4000->acl.pattern_x += et4000w32_max_x[et4000->acl.internal.pattern_wrap & 7]; - if (et4000->acl.source_x < 0) - et4000->acl.source_x += et4000w32_max_x[et4000->acl.internal.source_wrap & 7]; + et4000->acl.dest_addr -= c; + et4000->acl.pattern_x -= c; + et4000->acl.source_x -= c; + et4000->acl.mix_addr -= c; + if (et4000->acl.pattern_x < 0) + et4000->acl.pattern_x += et4000w32_max_x[et4000->acl.internal.pattern_wrap & 7]; + if (et4000->acl.source_x < 0) + et4000->acl.source_x += et4000w32_max_x[et4000->acl.internal.source_wrap & 7]; } void et4000w32_incy(et4000w32p_t *et4000) { - et4000->acl.pattern_addr += et4000->acl.internal.pattern_off + 1; - et4000->acl.source_addr += et4000->acl.internal.source_off + 1; - et4000->acl.mix_addr += et4000->acl.internal.mix_off + 1; - et4000->acl.dest_addr += et4000->acl.internal.dest_off + 1; - et4000->acl.pattern_y++; - if (et4000->acl.pattern_y == et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7]) { - et4000->acl.pattern_y = 0; - et4000->acl.pattern_addr = et4000->acl.pattern_back; - } - et4000->acl.source_y++; - if (et4000->acl.source_y == et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7]) { - et4000->acl.source_y = 0; - et4000->acl.source_addr = et4000->acl.source_back; - } + et4000->acl.pattern_addr += et4000->acl.internal.pattern_off + 1; + et4000->acl.source_addr += et4000->acl.internal.source_off + 1; + et4000->acl.mix_addr += et4000->acl.internal.mix_off + 1; + et4000->acl.dest_addr += et4000->acl.internal.dest_off + 1; + et4000->acl.pattern_y++; + if (et4000->acl.pattern_y == et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7]) { + et4000->acl.pattern_y = 0; + et4000->acl.pattern_addr = et4000->acl.pattern_back; + } + et4000->acl.source_y++; + if (et4000->acl.source_y == et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7]) { + et4000->acl.source_y = 0; + et4000->acl.source_addr = et4000->acl.source_back; + } } void et4000w32_decy(et4000w32p_t *et4000) { - et4000->acl.pattern_addr -= et4000->acl.internal.pattern_off + 1; - et4000->acl.source_addr -= et4000->acl.internal.source_off + 1; - et4000->acl.mix_addr -= et4000->acl.internal.mix_off + 1; - et4000->acl.dest_addr -= et4000->acl.internal.dest_off + 1; - et4000->acl.pattern_y--; - if (et4000->acl.pattern_y < 0 && !(et4000->acl.internal.pattern_wrap & 0x40)) { - et4000->acl.pattern_y = et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7] - 1; - et4000->acl.pattern_addr = et4000->acl.pattern_back + (et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] * (et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7] - 1)); - } - et4000->acl.source_y--; - if (et4000->acl.source_y < 0 && !(et4000->acl.internal.source_wrap & 0x40)) { - et4000->acl.source_y = et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7] - 1; - et4000->acl.source_addr = et4000->acl.source_back + (et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] * (et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7] - 1));; - } + et4000->acl.pattern_addr -= et4000->acl.internal.pattern_off + 1; + et4000->acl.source_addr -= et4000->acl.internal.source_off + 1; + et4000->acl.mix_addr -= et4000->acl.internal.mix_off + 1; + et4000->acl.dest_addr -= et4000->acl.internal.dest_off + 1; + et4000->acl.pattern_y--; + if (et4000->acl.pattern_y < 0 && !(et4000->acl.internal.pattern_wrap & 0x40)) { + et4000->acl.pattern_y = et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7] - 1; + et4000->acl.pattern_addr = + et4000->acl.pattern_back + (et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] * + (et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7] - 1)); + } + et4000->acl.source_y--; + if (et4000->acl.source_y < 0 && !(et4000->acl.internal.source_wrap & 0x40)) { + et4000->acl.source_y = et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7] - 1; + et4000->acl.source_addr = + et4000->acl.source_back + (et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] * + (et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7] - 1)); + ; + } } void et4000w32_blit(int count, uint32_t mix, uint32_t sdat, int cpu_input, et4000w32p_t *et4000) { - svga_t *svga = &et4000->svga; - int c, d; - uint8_t pattern, source, dest, out; - uint8_t rop; - int mixdat; + svga_t *svga = &et4000->svga; + int c, d; + uint8_t pattern, source, dest, out; + uint8_t rop; + int mixdat; - if (!(et4000->acl.status & ACL_XYST)) - return; -// if (count>400) pclog("New blit - %i,%i %06X (%i,%i) %06X %06X\n",et4000->acl.internal.count_x,et4000->acl.internal.count_y,et4000->acl.dest_addr,et4000->acl.dest_addr%640,et4000->acl.dest_addr/640,et4000->acl.source_addr,et4000->acl.pattern_addr); - //pclog("Blit exec - %i %i %i\n",count,et4000->acl.internal.pos_x,et4000->acl.internal.pos_y); - if (et4000->acl.internal.xy_dir & 0x80) /*Line draw*/ - { - while (count--) { - if (bltout) - pclog("%i,%i : ", et4000->acl.internal.pos_x, et4000->acl.internal.pos_y); - pattern = svga->vram[(et4000->acl.pattern_addr + et4000->acl.pattern_x) & 0x1fffff]; - source = svga->vram[(et4000->acl.source_addr + et4000->acl.source_x) & 0x1fffff]; - if (bltout) - pclog("%06X %06X ", (et4000->acl.pattern_addr + et4000->acl.pattern_x) & 0x1fffff, (et4000->acl.source_addr + et4000->acl.source_x) & 0x1fffff); - if (cpu_input == 2) { - source = sdat & 0xff; - sdat >>= 8; - } - dest = svga->vram[et4000->acl.dest_addr & 0x1fffff]; - out = 0; - if (bltout) - pclog("%06X ", et4000->acl.dest_addr); - if ((et4000->acl.internal.ctrl_routing & 0xa) == 8) { - mixdat = svga->vram[(et4000->acl.mix_addr >> 3) & 0x1fffff] & (1 << (et4000->acl.mix_addr & 7)); - if (bltout) - pclog("%06X %02X ", et4000->acl.mix_addr, svga->vram[(et4000->acl.mix_addr >> 3) & 0x1fffff]); - } else { - mixdat = mix & 1; - mix >>= 1; - mix |= 0x80000000; - } - et4000->acl.mix_addr++; - rop = mixdat ? et4000->acl.internal.rop_fg : et4000->acl.internal.rop_bg; - for (c = 0; c < 8; c++) { - d = (dest & (1 << c)) ? 1 : 0; - if (source & (1 << c)) - d |= 2; - if (pattern & (1 << c)) - d |= 4; - if (rop & (1 << d)) - out |= (1 << c); - } - if (bltout) - pclog("%06X = %02X\n", et4000->acl.dest_addr & 0x1fffff, out); - if (!(et4000->acl.internal.ctrl_routing & 0x40)) { - svga->vram[et4000->acl.dest_addr & 0x1fffff] = out; - svga->changedvram[(et4000->acl.dest_addr & 0x1fffff) >> 12] = changeframecount; - } else { - et4000->acl.cpu_dat |= ((uint64_t)out << (et4000->acl.cpu_dat_pos * 8)); - et4000->acl.cpu_dat_pos++; - } + if (!(et4000->acl.status & ACL_XYST)) + return; + // if (count>400) pclog("New blit - %i,%i %06X (%i,%i) %06X + // %06X\n",et4000->acl.internal.count_x,et4000->acl.internal.count_y,et4000->acl.dest_addr,et4000->acl.dest_addr%640,et4000->acl.dest_addr/640,et4000->acl.source_addr,et4000->acl.pattern_addr); + // pclog("Blit exec - %i %i %i\n",count,et4000->acl.internal.pos_x,et4000->acl.internal.pos_y); + if (et4000->acl.internal.xy_dir & 0x80) /*Line draw*/ + { + while (count--) { + if (bltout) + pclog("%i,%i : ", et4000->acl.internal.pos_x, et4000->acl.internal.pos_y); + pattern = svga->vram[(et4000->acl.pattern_addr + et4000->acl.pattern_x) & 0x1fffff]; + source = svga->vram[(et4000->acl.source_addr + et4000->acl.source_x) & 0x1fffff]; + if (bltout) + pclog("%06X %06X ", (et4000->acl.pattern_addr + et4000->acl.pattern_x) & 0x1fffff, + (et4000->acl.source_addr + et4000->acl.source_x) & 0x1fffff); + if (cpu_input == 2) { + source = sdat & 0xff; + sdat >>= 8; + } + dest = svga->vram[et4000->acl.dest_addr & 0x1fffff]; + out = 0; + if (bltout) + pclog("%06X ", et4000->acl.dest_addr); + if ((et4000->acl.internal.ctrl_routing & 0xa) == 8) { + mixdat = svga->vram[(et4000->acl.mix_addr >> 3) & 0x1fffff] & (1 << (et4000->acl.mix_addr & 7)); + if (bltout) + pclog("%06X %02X ", et4000->acl.mix_addr, + svga->vram[(et4000->acl.mix_addr >> 3) & 0x1fffff]); + } else { + mixdat = mix & 1; + mix >>= 1; + mix |= 0x80000000; + } + et4000->acl.mix_addr++; + rop = mixdat ? et4000->acl.internal.rop_fg : et4000->acl.internal.rop_bg; + for (c = 0; c < 8; c++) { + d = (dest & (1 << c)) ? 1 : 0; + if (source & (1 << c)) + d |= 2; + if (pattern & (1 << c)) + d |= 4; + if (rop & (1 << d)) + out |= (1 << c); + } + if (bltout) + pclog("%06X = %02X\n", et4000->acl.dest_addr & 0x1fffff, out); + if (!(et4000->acl.internal.ctrl_routing & 0x40)) { + svga->vram[et4000->acl.dest_addr & 0x1fffff] = out; + svga->changedvram[(et4000->acl.dest_addr & 0x1fffff) >> 12] = changeframecount; + } else { + et4000->acl.cpu_dat |= ((uint64_t)out << (et4000->acl.cpu_dat_pos * 8)); + et4000->acl.cpu_dat_pos++; + } -// pclog("%i %i\n",et4000->acl.pix_pos,(et4000->acl.internal.pixel_depth>>4)&3); - et4000->acl.pix_pos++; - et4000->acl.internal.pos_x++; - if (et4000->acl.pix_pos <= ((et4000->acl.internal.pixel_depth >> 4) & 3)) { - if (et4000->acl.internal.xy_dir & 1) - et4000w32_decx(1, et4000); - else - et4000w32_incx(1, et4000); - } else { - if (et4000->acl.internal.xy_dir & 1) - et4000w32_incx((et4000->acl.internal.pixel_depth >> 4) & 3, et4000); - else - et4000w32_decx((et4000->acl.internal.pixel_depth >> 4) & 3, et4000); - et4000->acl.pix_pos = 0; - /*Next pixel*/ - switch (et4000->acl.internal.xy_dir & 7) { - case 0: - case 1: /*Y+*/ - et4000w32_incy(et4000); - et4000->acl.internal.pos_y++; - et4000->acl.internal.pos_x -= ((et4000->acl.internal.pixel_depth >> 4) & 3) + 1; - break; - case 2: - case 3: /*Y-*/ - et4000w32_decy(et4000); - et4000->acl.internal.pos_y++; - et4000->acl.internal.pos_x -= ((et4000->acl.internal.pixel_depth >> 4) & 3) + 1; - break; - case 4: - case 6: /*X+*/ - et4000w32_incx(((et4000->acl.internal.pixel_depth >> 4) & 3) + 1, et4000); - //et4000->acl.internal.pos_x++; - break; - case 5: - case 7: /*X-*/ - et4000w32_decx(((et4000->acl.internal.pixel_depth >> 4) & 3) + 1, et4000); - //et4000->acl.internal.pos_x++; - break; - } - et4000->acl.internal.error += et4000->acl.internal.dmin; - if (et4000->acl.internal.error > et4000->acl.internal.dmaj) { - et4000->acl.internal.error -= et4000->acl.internal.dmaj; - switch (et4000->acl.internal.xy_dir & 7) { - case 0: - case 2: /*X+*/ - et4000w32_incx(((et4000->acl.internal.pixel_depth >> 4) & 3) + 1, et4000); - et4000->acl.internal.pos_x++; - break; - case 1: - case 3: /*X-*/ - et4000w32_decx(((et4000->acl.internal.pixel_depth >> 4) & 3) + 1, et4000); - et4000->acl.internal.pos_x++; - break; - case 4: - case 5: /*Y+*/ - et4000w32_incy(et4000); - et4000->acl.internal.pos_y++; - break; - case 6: - case 7: /*Y-*/ - et4000w32_decy(et4000); - et4000->acl.internal.pos_y++; - break; - } - } - if (et4000->acl.internal.pos_x > et4000->acl.internal.count_x || - et4000->acl.internal.pos_y > et4000->acl.internal.count_y) { - et4000->acl.status &= ~(ACL_XYST | ACL_SSO); -// pclog("Blit line over\n"); - return; - } - } - } - } else { - while (count--) { - if (bltout) - pclog("%i,%i : ", et4000->acl.internal.pos_x, et4000->acl.internal.pos_y); + // pclog("%i %i\n",et4000->acl.pix_pos,(et4000->acl.internal.pixel_depth>>4)&3); + et4000->acl.pix_pos++; + et4000->acl.internal.pos_x++; + if (et4000->acl.pix_pos <= ((et4000->acl.internal.pixel_depth >> 4) & 3)) { + if (et4000->acl.internal.xy_dir & 1) + et4000w32_decx(1, et4000); + else + et4000w32_incx(1, et4000); + } else { + if (et4000->acl.internal.xy_dir & 1) + et4000w32_incx((et4000->acl.internal.pixel_depth >> 4) & 3, et4000); + else + et4000w32_decx((et4000->acl.internal.pixel_depth >> 4) & 3, et4000); + et4000->acl.pix_pos = 0; + /*Next pixel*/ + switch (et4000->acl.internal.xy_dir & 7) { + case 0: + case 1: /*Y+*/ + et4000w32_incy(et4000); + et4000->acl.internal.pos_y++; + et4000->acl.internal.pos_x -= ((et4000->acl.internal.pixel_depth >> 4) & 3) + 1; + break; + case 2: + case 3: /*Y-*/ + et4000w32_decy(et4000); + et4000->acl.internal.pos_y++; + et4000->acl.internal.pos_x -= ((et4000->acl.internal.pixel_depth >> 4) & 3) + 1; + break; + case 4: + case 6: /*X+*/ + et4000w32_incx(((et4000->acl.internal.pixel_depth >> 4) & 3) + 1, et4000); + // et4000->acl.internal.pos_x++; + break; + case 5: + case 7: /*X-*/ + et4000w32_decx(((et4000->acl.internal.pixel_depth >> 4) & 3) + 1, et4000); + // et4000->acl.internal.pos_x++; + break; + } + et4000->acl.internal.error += et4000->acl.internal.dmin; + if (et4000->acl.internal.error > et4000->acl.internal.dmaj) { + et4000->acl.internal.error -= et4000->acl.internal.dmaj; + switch (et4000->acl.internal.xy_dir & 7) { + case 0: + case 2: /*X+*/ + et4000w32_incx(((et4000->acl.internal.pixel_depth >> 4) & 3) + 1, et4000); + et4000->acl.internal.pos_x++; + break; + case 1: + case 3: /*X-*/ + et4000w32_decx(((et4000->acl.internal.pixel_depth >> 4) & 3) + 1, et4000); + et4000->acl.internal.pos_x++; + break; + case 4: + case 5: /*Y+*/ + et4000w32_incy(et4000); + et4000->acl.internal.pos_y++; + break; + case 6: + case 7: /*Y-*/ + et4000w32_decy(et4000); + et4000->acl.internal.pos_y++; + break; + } + } + if (et4000->acl.internal.pos_x > et4000->acl.internal.count_x || + et4000->acl.internal.pos_y > et4000->acl.internal.count_y) { + et4000->acl.status &= ~(ACL_XYST | ACL_SSO); + // pclog("Blit line over\n"); + return; + } + } + } + } else { + while (count--) { + if (bltout) + pclog("%i,%i : ", et4000->acl.internal.pos_x, et4000->acl.internal.pos_y); - pattern = svga->vram[(et4000->acl.pattern_addr + et4000->acl.pattern_x) & 0x1fffff]; - source = svga->vram[(et4000->acl.source_addr + et4000->acl.source_x) & 0x1fffff]; - if (bltout) - pclog("%i %06X %06X %02X %02X ", et4000->acl.pattern_y, - (et4000->acl.pattern_addr + et4000->acl.pattern_x) & 0x1fffff, (et4000->acl.source_addr + et4000->acl.source_x) & 0x1fffff, pattern, source); + pattern = svga->vram[(et4000->acl.pattern_addr + et4000->acl.pattern_x) & 0x1fffff]; + source = svga->vram[(et4000->acl.source_addr + et4000->acl.source_x) & 0x1fffff]; + if (bltout) + pclog("%i %06X %06X %02X %02X ", et4000->acl.pattern_y, + (et4000->acl.pattern_addr + et4000->acl.pattern_x) & 0x1fffff, + (et4000->acl.source_addr + et4000->acl.source_x) & 0x1fffff, pattern, source); - if (cpu_input == 2) { - source = sdat & 0xff; - sdat >>= 8; - } - dest = svga->vram[et4000->acl.dest_addr & 0x1fffff]; - out = 0; - if (bltout) - pclog("%06X %02X %i %08X %08X ", dest, et4000->acl.dest_addr, mix & 1, mix, et4000->acl.mix_addr); - if ((et4000->acl.internal.ctrl_routing & 0xa) == 8) { - mixdat = svga->vram[(et4000->acl.mix_addr >> 3) & 0x1fffff] & (1 << (et4000->acl.mix_addr & 7)); - if (bltout) - pclog("%06X %02X ", et4000->acl.mix_addr, svga->vram[(et4000->acl.mix_addr >> 3) & 0x1fffff]); - } else { - mixdat = mix & 1; - mix >>= 1; - mix |= 0x80000000; - } + if (cpu_input == 2) { + source = sdat & 0xff; + sdat >>= 8; + } + dest = svga->vram[et4000->acl.dest_addr & 0x1fffff]; + out = 0; + if (bltout) + pclog("%06X %02X %i %08X %08X ", dest, et4000->acl.dest_addr, mix & 1, mix, + et4000->acl.mix_addr); + if ((et4000->acl.internal.ctrl_routing & 0xa) == 8) { + mixdat = svga->vram[(et4000->acl.mix_addr >> 3) & 0x1fffff] & (1 << (et4000->acl.mix_addr & 7)); + if (bltout) + pclog("%06X %02X ", et4000->acl.mix_addr, + svga->vram[(et4000->acl.mix_addr >> 3) & 0x1fffff]); + } else { + mixdat = mix & 1; + mix >>= 1; + mix |= 0x80000000; + } - rop = mixdat ? et4000->acl.internal.rop_fg : et4000->acl.internal.rop_bg; - for (c = 0; c < 8; c++) { - d = (dest & (1 << c)) ? 1 : 0; - if (source & (1 << c)) - d |= 2; - if (pattern & (1 << c)) - d |= 4; - if (rop & (1 << d)) - out |= (1 << c); - } - if (bltout) - pclog("%06X = %02X\n", et4000->acl.dest_addr & 0x1fffff, out); - if (!(et4000->acl.internal.ctrl_routing & 0x40)) { - svga->vram[et4000->acl.dest_addr & 0x1fffff] = out; - svga->changedvram[(et4000->acl.dest_addr & 0x1fffff) >> 12] = changeframecount; - } else { - et4000->acl.cpu_dat |= ((uint64_t)out << (et4000->acl.cpu_dat_pos * 8)); - et4000->acl.cpu_dat_pos++; - } + rop = mixdat ? et4000->acl.internal.rop_fg : et4000->acl.internal.rop_bg; + for (c = 0; c < 8; c++) { + d = (dest & (1 << c)) ? 1 : 0; + if (source & (1 << c)) + d |= 2; + if (pattern & (1 << c)) + d |= 4; + if (rop & (1 << d)) + out |= (1 << c); + } + if (bltout) + pclog("%06X = %02X\n", et4000->acl.dest_addr & 0x1fffff, out); + if (!(et4000->acl.internal.ctrl_routing & 0x40)) { + svga->vram[et4000->acl.dest_addr & 0x1fffff] = out; + svga->changedvram[(et4000->acl.dest_addr & 0x1fffff) >> 12] = changeframecount; + } else { + et4000->acl.cpu_dat |= ((uint64_t)out << (et4000->acl.cpu_dat_pos * 8)); + et4000->acl.cpu_dat_pos++; + } - if (et4000->acl.internal.xy_dir & 1) - et4000w32_decx(1, et4000); - else - et4000w32_incx(1, et4000); + if (et4000->acl.internal.xy_dir & 1) + et4000w32_decx(1, et4000); + else + et4000w32_incx(1, et4000); - et4000->acl.internal.pos_x++; - if (et4000->acl.internal.pos_x > et4000->acl.internal.count_x) { - if (et4000->acl.internal.xy_dir & 2) { - et4000w32_decy(et4000); - et4000->acl.mix_back = et4000->acl.mix_addr = et4000->acl.mix_back - (et4000->acl.internal.mix_off + 1); - et4000->acl.dest_back = et4000->acl.dest_addr = et4000->acl.dest_back - (et4000->acl.internal.dest_off + 1); - } else { - et4000w32_incy(et4000); - et4000->acl.mix_back = et4000->acl.mix_addr = et4000->acl.mix_back + et4000->acl.internal.mix_off + 1; - et4000->acl.dest_back = et4000->acl.dest_addr = et4000->acl.dest_back + et4000->acl.internal.dest_off + 1; - } + et4000->acl.internal.pos_x++; + if (et4000->acl.internal.pos_x > et4000->acl.internal.count_x) { + if (et4000->acl.internal.xy_dir & 2) { + et4000w32_decy(et4000); + et4000->acl.mix_back = et4000->acl.mix_addr = + et4000->acl.mix_back - (et4000->acl.internal.mix_off + 1); + et4000->acl.dest_back = et4000->acl.dest_addr = + et4000->acl.dest_back - (et4000->acl.internal.dest_off + 1); + } else { + et4000w32_incy(et4000); + et4000->acl.mix_back = et4000->acl.mix_addr = + et4000->acl.mix_back + et4000->acl.internal.mix_off + 1; + et4000->acl.dest_back = et4000->acl.dest_addr = + et4000->acl.dest_back + et4000->acl.internal.dest_off + 1; + } - et4000->acl.pattern_x = et4000->acl.pattern_x_back; - et4000->acl.source_x = et4000->acl.source_x_back; + et4000->acl.pattern_x = et4000->acl.pattern_x_back; + et4000->acl.source_x = et4000->acl.source_x_back; - et4000->acl.internal.pos_y++; - et4000->acl.internal.pos_x = 0; - if (et4000->acl.internal.pos_y > et4000->acl.internal.count_y) { - et4000->acl.status &= ~(ACL_XYST | ACL_SSO); -// pclog("Blit over\n"); - return; - } - if (cpu_input) - return; - if (et4000->acl.internal.ctrl_routing & 0x40) { - if (et4000->acl.cpu_dat_pos & 3) - et4000->acl.cpu_dat_pos += 4 - (et4000->acl.cpu_dat_pos & 3); - return; - } - } - } - } + et4000->acl.internal.pos_y++; + et4000->acl.internal.pos_x = 0; + if (et4000->acl.internal.pos_y > et4000->acl.internal.count_y) { + et4000->acl.status &= ~(ACL_XYST | ACL_SSO); + // pclog("Blit over\n"); + return; + } + if (cpu_input) + return; + if (et4000->acl.internal.ctrl_routing & 0x40) { + if (et4000->acl.cpu_dat_pos & 3) + et4000->acl.cpu_dat_pos += 4 - (et4000->acl.cpu_dat_pos & 3); + return; + } + } + } + } } void et4000w32p_hwcursor_draw(svga_t *svga, int displine) { - int x, offset; - uint8_t dat; - offset = svga->hwcursor_latch.xoff; - for (x = 0; x < 64 - svga->hwcursor_latch.xoff; x += 4) { - dat = svga->vram[svga->hwcursor_latch.addr + (offset >> 2)]; - if (!(dat & 2)) - ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 32] = (dat & 1) ? 0xFFFFFF : 0; - else if ((dat & 3) == 3) - ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 32] ^= 0xFFFFFF; - dat >>= 2; - if (!(dat & 2)) - ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 33] = (dat & 1) ? 0xFFFFFF : 0; - else if ((dat & 3) == 3) - ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 33] ^= 0xFFFFFF; - dat >>= 2; - if (!(dat & 2)) - ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 34] = (dat & 1) ? 0xFFFFFF : 0; - else if ((dat & 3) == 3) - ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 34] ^= 0xFFFFFF; - dat >>= 2; - if (!(dat & 2)) - ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 35] = (dat & 1) ? 0xFFFFFF : 0; - else if ((dat & 3) == 3) - ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 35] ^= 0xFFFFFF; - dat >>= 2; - offset += 4; - } - svga->hwcursor_latch.addr += 16; + int x, offset; + uint8_t dat; + offset = svga->hwcursor_latch.xoff; + for (x = 0; x < 64 - svga->hwcursor_latch.xoff; x += 4) { + dat = svga->vram[svga->hwcursor_latch.addr + (offset >> 2)]; + if (!(dat & 2)) + ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 32] = (dat & 1) ? 0xFFFFFF : 0; + else if ((dat & 3) == 3) + ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 32] ^= 0xFFFFFF; + dat >>= 2; + if (!(dat & 2)) + ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 33] = (dat & 1) ? 0xFFFFFF : 0; + else if ((dat & 3) == 3) + ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 33] ^= 0xFFFFFF; + dat >>= 2; + if (!(dat & 2)) + ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 34] = (dat & 1) ? 0xFFFFFF : 0; + else if ((dat & 3) == 3) + ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 34] ^= 0xFFFFFF; + dat >>= 2; + if (!(dat & 2)) + ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 35] = (dat & 1) ? 0xFFFFFF : 0; + else if ((dat & 3) == 3) + ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 35] ^= 0xFFFFFF; + dat >>= 2; + offset += 4; + } + svga->hwcursor_latch.addr += 16; } static void et4000w32p_io_remove(et4000w32p_t *et4000) { - io_removehandler(0x03c0, 0x0020, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); + io_removehandler(0x03c0, 0x0020, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); - io_removehandler(0x210A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); - io_removehandler(0x211A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); - io_removehandler(0x212A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); - io_removehandler(0x213A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); - io_removehandler(0x214A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); - io_removehandler(0x215A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); - io_removehandler(0x216A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); - io_removehandler(0x217A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); + io_removehandler(0x210A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); + io_removehandler(0x211A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); + io_removehandler(0x212A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); + io_removehandler(0x213A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); + io_removehandler(0x214A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); + io_removehandler(0x215A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); + io_removehandler(0x216A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); + io_removehandler(0x217A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); } static void et4000w32p_io_set(et4000w32p_t *et4000) { - et4000w32p_io_remove(et4000); + et4000w32p_io_remove(et4000); - io_sethandler(0x03c0, 0x0020, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); + io_sethandler(0x03c0, 0x0020, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); - io_sethandler(0x210A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); - io_sethandler(0x211A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); - io_sethandler(0x212A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); - io_sethandler(0x213A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); - io_sethandler(0x214A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); - io_sethandler(0x215A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); - io_sethandler(0x216A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); - io_sethandler(0x217A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); + io_sethandler(0x210A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); + io_sethandler(0x211A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); + io_sethandler(0x212A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); + io_sethandler(0x213A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); + io_sethandler(0x214A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); + io_sethandler(0x215A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); + io_sethandler(0x216A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); + io_sethandler(0x217A, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); } uint8_t et4000w32p_pci_read(int func, int addr, void *p) { - et4000w32p_t *et4000 = (et4000w32p_t *)p; + et4000w32p_t *et4000 = (et4000w32p_t *)p; -// pclog("ET4000 PCI read %08X\n", addr); + // pclog("ET4000 PCI read %08X\n", addr); - switch (addr) { - case 0x00:return 0x0c; /*Tseng Labs*/ - case 0x01:return 0x10; + switch (addr) { + case 0x00: + return 0x0c; /*Tseng Labs*/ + case 0x01: + return 0x10; - case 0x02:return 0x06; /*ET4000W32p Rev D*/ - case 0x03:return 0x32; + case 0x02: + return 0x06; /*ET4000W32p Rev D*/ + case 0x03: + return 0x32; - case PCI_REG_COMMAND:return et4000->pci_regs[PCI_REG_COMMAND]; /*Respond to IO and memory accesses*/ + case PCI_REG_COMMAND: + return et4000->pci_regs[PCI_REG_COMMAND]; /*Respond to IO and memory accesses*/ - case 0x07:return 1 << 1; /*Medium DEVSEL timing*/ + case 0x07: + return 1 << 1; /*Medium DEVSEL timing*/ - case 0x08:return 0; /*Revision ID*/ - case 0x09:return 0; /*Programming interface*/ + case 0x08: + return 0; /*Revision ID*/ + case 0x09: + return 0; /*Programming interface*/ - case 0x0a:return 0x01; /*Supports VGA interface, XGA compatible*/ - case 0x0b:return 0x03; + case 0x0a: + return 0x01; /*Supports VGA interface, XGA compatible*/ + case 0x0b: + return 0x03; - case 0x10:return 0x00; /*Linear frame buffer address*/ - case 0x11:return 0x00; - case 0x12:return 0x00; - case 0x13:return et4000->pci_regs[0x13]; + case 0x10: + return 0x00; /*Linear frame buffer address*/ + case 0x11: + return 0x00; + case 0x12: + return 0x00; + case 0x13: + return et4000->pci_regs[0x13]; - case 0x30:return et4000->pci_regs[0x30] & 0x01; /*BIOS ROM address*/ - case 0x31:return 0x00; - case 0x32:return et4000->pci_regs[0x32]; - case 0x33:return et4000->pci_regs[0x33]; - } - return 0; + case 0x30: + return et4000->pci_regs[0x30] & 0x01; /*BIOS ROM address*/ + case 0x31: + return 0x00; + case 0x32: + return et4000->pci_regs[0x32]; + case 0x33: + return et4000->pci_regs[0x33]; + } + return 0; } void et4000w32p_pci_write(int func, int addr, uint8_t val, void *p) { - et4000w32p_t *et4000 = (et4000w32p_t *)p; + et4000w32p_t *et4000 = (et4000w32p_t *)p; - switch (addr) { - case PCI_REG_COMMAND:et4000->pci_regs[PCI_REG_COMMAND] = val & 0x27; - if (val & PCI_COMMAND_IO) - et4000w32p_io_set(et4000); - else - et4000w32p_io_remove(et4000); - et4000w32p_recalcmapping(et4000); - break; + switch (addr) { + case PCI_REG_COMMAND: + et4000->pci_regs[PCI_REG_COMMAND] = val & 0x27; + if (val & PCI_COMMAND_IO) + et4000w32p_io_set(et4000); + else + et4000w32p_io_remove(et4000); + et4000w32p_recalcmapping(et4000); + break; - case 0x13:et4000->linearbase = val << 24; - et4000->pci_regs[0x13] = val; - et4000w32p_recalcmapping(et4000); - break; + case 0x13: + et4000->linearbase = val << 24; + et4000->pci_regs[0x13] = val; + et4000w32p_recalcmapping(et4000); + break; - case 0x30: - case 0x32: - case 0x33:et4000->pci_regs[addr] = val; - if (et4000->pci_regs[0x30] & 0x01) { - uint32_t addr = (et4000->pci_regs[0x32] << 16) | (et4000->pci_regs[0x33] << 24); - pclog("ET4000 bios_rom enabled at %08x\n", addr); - mem_mapping_set_addr(&et4000->bios_rom.mapping, addr, 0x8000); - } else { - pclog("ET4000 bios_rom disabled\n"); - mem_mapping_disable(&et4000->bios_rom.mapping); - } - return; - } + case 0x30: + case 0x32: + case 0x33: + et4000->pci_regs[addr] = val; + if (et4000->pci_regs[0x30] & 0x01) { + uint32_t addr = (et4000->pci_regs[0x32] << 16) | (et4000->pci_regs[0x33] << 24); + pclog("ET4000 bios_rom enabled at %08x\n", addr); + mem_mapping_set_addr(&et4000->bios_rom.mapping, addr, 0x8000); + } else { + pclog("ET4000 bios_rom disabled\n"); + mem_mapping_disable(&et4000->bios_rom.mapping); + } + return; + } } void *et4000w32p_init() { - int vram_size; - int offset; - et4000w32p_t *et4000 = malloc(sizeof(et4000w32p_t)); - memset(et4000, 0, sizeof(et4000w32p_t)); + int vram_size; + int offset; + et4000w32p_t *et4000 = malloc(sizeof(et4000w32p_t)); + memset(et4000, 0, sizeof(et4000w32p_t)); - vram_size = device_get_config_int("memory"); + vram_size = device_get_config_int("memory"); - et4000->interleaved = (vram_size == 2) ? 1 : 0; - et4000->is_pci = 1; + et4000->interleaved = (vram_size == 2) ? 1 : 0; + et4000->is_pci = 1; - svga_init(&et4000->svga, et4000, vram_size << 20, - et4000w32p_recalctimings, - et4000w32p_in, et4000w32p_out, - et4000w32p_hwcursor_draw, - NULL); + svga_init(&et4000->svga, et4000, vram_size << 20, et4000w32p_recalctimings, et4000w32p_in, et4000w32p_out, + et4000w32p_hwcursor_draw, NULL); - rom_init(&et4000->bios_rom, "et4000w32.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&et4000->bios_rom, "et4000w32.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - /*Some BIOSes (eg Diamond Stealth 32 VLB) have a PCI data structure, but - with the wrong PCI device ID. The BIOSes on the Intel boards detect this - and refuse to use the card. To work around this we check the ID and if - it's wrong then disable PCI functionality. */ - offset = et4000->bios_rom.rom[0x18] | (et4000->bios_rom.rom[0x19] << 8); - if (et4000->bios_rom.rom[offset + 7] != 0x32) - et4000->is_pci = 0; + /*Some BIOSes (eg Diamond Stealth 32 VLB) have a PCI data structure, but + with the wrong PCI device ID. The BIOSes on the Intel boards detect this + and refuse to use the card. To work around this we check the ID and if + it's wrong then disable PCI functionality. */ + offset = et4000->bios_rom.rom[0x18] | (et4000->bios_rom.rom[0x19] << 8); + if (et4000->bios_rom.rom[offset + 7] != 0x32) + et4000->is_pci = 0; - if (PCI && et4000->is_pci) - mem_mapping_disable(&et4000->bios_rom.mapping); + if (PCI && et4000->is_pci) + mem_mapping_disable(&et4000->bios_rom.mapping); - mem_mapping_add(&et4000->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL, 0, &et4000->svga); - mem_mapping_add(&et4000->mmu_mapping, 0, 0, et4000w32p_mmu_read, NULL, NULL, et4000w32p_mmu_write, NULL, NULL, NULL, 0, et4000); + mem_mapping_add(&et4000->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, + svga_writew_linear, svga_writel_linear, NULL, 0, &et4000->svga); + mem_mapping_add(&et4000->mmu_mapping, 0, 0, et4000w32p_mmu_read, NULL, NULL, et4000w32p_mmu_write, NULL, NULL, NULL, 0, + et4000); - et4000w32p_io_set(et4000); + et4000w32p_io_set(et4000); - if (PCI && et4000->is_pci) - pci_add(et4000w32p_pci_read, et4000w32p_pci_write, et4000); + if (PCI && et4000->is_pci) + pci_add(et4000w32p_pci_read, et4000w32p_pci_write, et4000); - et4000->pci_regs[0x04] = 7; + et4000->pci_regs[0x04] = 7; - et4000->pci_regs[0x30] = 0x00; - et4000->pci_regs[0x32] = 0x0c; - et4000->pci_regs[0x33] = 0x00; + et4000->pci_regs[0x30] = 0x00; + et4000->pci_regs[0x32] = 0x0c; + et4000->pci_regs[0x33] = 0x00; - et4000->wake_fifo_thread = thread_create_event(); - et4000->fifo_not_full_event = thread_create_event(); - et4000->fifo_thread = thread_create(fifo_thread, et4000); + et4000->wake_fifo_thread = thread_create_event(); + et4000->fifo_not_full_event = thread_create_event(); + et4000->fifo_thread = thread_create(fifo_thread, et4000); - et4000->svga.packed_chain4 = 1; + et4000->svga.packed_chain4 = 1; - return et4000; + return et4000; } -int et4000w32p_available() { - return rom_present("et4000w32.bin"); -} +int et4000w32p_available() { return rom_present("et4000w32.bin"); } void et4000w32p_close(void *p) { - et4000w32p_t *et4000 = (et4000w32p_t *)p; + et4000w32p_t *et4000 = (et4000w32p_t *)p; - svga_close(&et4000->svga); + svga_close(&et4000->svga); - thread_kill(et4000->fifo_thread); - thread_destroy_event(et4000->wake_fifo_thread); - thread_destroy_event(et4000->fifo_not_full_event); + thread_kill(et4000->fifo_thread); + thread_destroy_event(et4000->wake_fifo_thread); + thread_destroy_event(et4000->fifo_not_full_event); - free(et4000); + free(et4000); } void et4000w32p_speed_changed(void *p) { - et4000w32p_t *et4000 = (et4000w32p_t *)p; + et4000w32p_t *et4000 = (et4000w32p_t *)p; - svga_recalctimings(&et4000->svga); + svga_recalctimings(&et4000->svga); } void et4000w32p_force_redraw(void *p) { - et4000w32p_t *et4000w32p = (et4000w32p_t *)p; + et4000w32p_t *et4000w32p = (et4000w32p_t *)p; - et4000w32p->svga.fullchange = changeframecount; + et4000w32p->svga.fullchange = changeframecount; } void et4000w32p_add_status_info(char *s, int max_len, void *p) { - et4000w32p_t *et4000 = (et4000w32p_t *)p; - char temps[256]; - uint64_t new_time = timer_read(); - uint64_t status_diff = new_time - et4000->status_time; - et4000->status_time = new_time; + et4000w32p_t *et4000 = (et4000w32p_t *)p; + char temps[256]; + uint64_t new_time = timer_read(); + uint64_t status_diff = new_time - et4000->status_time; + et4000->status_time = new_time; - svga_add_status_info(s, max_len, &et4000->svga); + svga_add_status_info(s, max_len, &et4000->svga); - sprintf(temps, "%f%% CPU\n%f%% CPU (real)\n\n", ((double)et4000->blitter_time * 100.0) / timer_freq, ((double)et4000->blitter_time * 100.0) / status_diff); - strncat(s, temps, max_len); + sprintf(temps, "%f%% CPU\n%f%% CPU (real)\n\n", ((double)et4000->blitter_time * 100.0) / timer_freq, + ((double)et4000->blitter_time * 100.0) / status_diff); + strncat(s, temps, max_len); - et4000->blitter_time = 0; + et4000->blitter_time = 0; } -static device_config_t et4000w32p_config[] = - { - { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "1 MB", - .value = 1 - }, - { - .description = "2 MB", - .value = 2 - }, - { - .description = "" - } - }, - .default_int = 2 - }, - { - .type = -1 - } - }; +static device_config_t et4000w32p_config[] = { + {.name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .selection = {{.description = "1 MB", .value = 1}, {.description = "2 MB", .value = 2}, {.description = ""}}, + .default_int = 2}, + {.type = -1}}; -device_t et4000w32p_device = - { - "Tseng Labs ET4000/w32p", - 0, - et4000w32p_init, - et4000w32p_close, - et4000w32p_available, - et4000w32p_speed_changed, - et4000w32p_force_redraw, - et4000w32p_add_status_info, - et4000w32p_config - }; +device_t et4000w32p_device = {"Tseng Labs ET4000/w32p", 0, + et4000w32p_init, et4000w32p_close, + et4000w32p_available, et4000w32p_speed_changed, + et4000w32p_force_redraw, et4000w32p_add_status_info, + et4000w32p_config}; diff --git a/src/video/vid_et4000w32i.c b/src/video/vid_et4000w32i.c index b9d33eea..350b7000 100644 --- a/src/video/vid_et4000w32i.c +++ b/src/video/vid_et4000w32i.c @@ -36,7 +36,7 @@ struct #define ACL_WRST 1 #define ACL_RDST 2 #define ACL_XYST 4 -#define ACL_SSO 8 +#define ACL_SSO 8 struct { diff --git a/src/video/vid_genius.c b/src/video/vid_genius.c index c5ae3ce0..d8a69738 100644 --- a/src/video/vid_genius.c +++ b/src/video/vid_genius.c @@ -17,9 +17,9 @@ void updatewindowsize(int x, int y); extern uint8_t fontdat8x12[256][16]; /* I'm at something of a disadvantage writing this emulation: I don't have an - * MDSI Genius card, nor do I have the BIOS extension (VHRBIOS.SYS) that came + * MDSI Genius card, nor do I have the BIOS extension (VHRBIOS.SYS) that came * with it. What I do have are the GEM and Windows 1.04 drivers, plus a driver - * for a later MCA version of the card. The latter can be found at + * for a later MCA version of the card. The latter can be found at * and is necessary if you * want the Windows driver to work. * @@ -28,9 +28,9 @@ extern uint8_t fontdat8x12[256][16]; * The GEM driver SDGEN9.VGA * The Windows 1.04 driver GENIUS.DRV * - * As far as I can see, the card uses a fixed resolution of 728x1008 pixels. + * As far as I can see, the card uses a fixed resolution of 728x1008 pixels. * It has the following modes of operation: - * + * * > MDA-compatible: 80x25 text, each character 9x15 pixels. * > CGA-compatible: 640x200 mono graphics * > Dual: MDA text in the top half, CGA graphics in the bottom @@ -38,16 +38,16 @@ extern uint8_t fontdat8x12[256][16]; * > Native graphics: 728x1008 mono graphics. * * Under the covers, this seems to translate to: - * > Text framebuffer. At B000:0000, 16k. Displayed if enable bit is set + * > Text framebuffer. At B000:0000, 16k. Displayed if enable bit is set * in the MDA control register. * > Graphics framebuffer. In native modes goes from A000:0000 to A000:FFFF - * and B800:0000 to B800:FFFF. In CGA-compatible + * and B800:0000 to B800:FFFF. In CGA-compatible * mode only the section at B800:0000 to B800:7FFF * is visible. Displayed if enable bit is set in the * CGA control register. - * + * * Two card-specific registers control text and graphics display: - * + * * 03B0: Control register. * Bit 0: Map all graphics framebuffer into memory. * Bit 2: Unknown. Set by GMC /M; cleared by mode set or GMC /T. @@ -59,52 +59,50 @@ extern uint8_t fontdat8x12[256][16]; * Bit 4: Set to double character cell height (scanlines are doubled) * Bit 7: Unknown, seems to be set for all modes except 80x66 * - * Not having the card also means I don't have its font. According to the - * card brochure the font is an 8x12 bitmap in a 9x15 character cell. I - * therefore generated it by taking the MDA font, increasing graphics to + * Not having the card also means I don't have its font. According to the + * card brochure the font is an 8x12 bitmap in a 9x15 character cell. I + * therefore generated it by taking the MDA font, increasing graphics to * 16 pixels in height and reducing the height of characters so they fit * in an 8x12 cell if necessary. */ - - typedef struct genius_t { - mem_mapping_t mapping; + mem_mapping_t mapping; - uint8_t mda_crtc[32]; /* The 'CRTC' as the host PC sees it */ - int mda_crtcreg; /* Current CRTC register */ - uint8_t genius_control; /* Native control register - * I think bit 0 enables the full - * framebuffer. - */ - uint8_t genius_charh; /* Native character height register: - * 00h => chars are 15 pixels high - * 81h => chars are 14 pixels high - * 83h => chars are 12 pixels high - * 90h => chars are 30 pixels high [15 x 2] - * 93h => chars are 24 pixels high [12 x 2] - */ - uint8_t genius_mode; /* Current mode (see list at top of file) */ - uint8_t cga_ctrl; /* Emulated CGA control register */ - uint8_t mda_ctrl; /* Emulated MDA control register */ - uint8_t cga_colour; /* Emulated CGA colour register (ignored) */ + uint8_t mda_crtc[32]; /* The 'CRTC' as the host PC sees it */ + int mda_crtcreg; /* Current CRTC register */ + uint8_t genius_control; /* Native control register + * I think bit 0 enables the full + * framebuffer. + */ + uint8_t genius_charh; /* Native character height register: + * 00h => chars are 15 pixels high + * 81h => chars are 14 pixels high + * 83h => chars are 12 pixels high + * 90h => chars are 30 pixels high [15 x 2] + * 93h => chars are 24 pixels high [12 x 2] + */ + uint8_t genius_mode; /* Current mode (see list at top of file) */ + uint8_t cga_ctrl; /* Emulated CGA control register */ + uint8_t mda_ctrl; /* Emulated MDA control register */ + uint8_t cga_colour; /* Emulated CGA colour register (ignored) */ - uint8_t mda_stat; /* MDA status (IN 0x3BA) */ - uint8_t cga_stat; /* CGA status (IN 0x3DA) */ + uint8_t mda_stat; /* MDA status (IN 0x3BA) */ + uint8_t cga_stat; /* CGA status (IN 0x3DA) */ - int font; /* Current font, 0 or 1 */ - int enabled; /* Display enabled, 0 or 1 */ - int detach; /* Detach cursor, 0 or 1 */ + int font; /* Current font, 0 or 1 */ + int enabled; /* Display enabled, 0 or 1 */ + int detach; /* Detach cursor, 0 or 1 */ - uint64_t dispontime, dispofftime; - pc_timer_t timer; + uint64_t dispontime, dispofftime; + pc_timer_t timer; - int linepos, displine; - int vc; - int dispon, blink; - int vsynctime; + int linepos, displine; + int vc; + int dispon, blink; + int vsynctime; - uint8_t *vram; + uint8_t *vram; } genius_t; static uint32_t genius_pal[4]; @@ -117,450 +115,449 @@ void genius_write(uint32_t addr, uint8_t val, void *p); uint8_t genius_read(uint32_t addr, void *p); void genius_out(uint16_t addr, uint8_t val, void *p) { - genius_t *genius = (genius_t *)p; + genius_t *genius = (genius_t *)p; - switch (addr) { - case 0x3b0: /* Command / control register */ - genius->genius_control = val; - if (val & 1) { - mem_mapping_set_addr(&genius->mapping, 0xa0000, 0x28000); - } else { - mem_mapping_set_addr(&genius->mapping, 0xb0000, 0x10000); - } + switch (addr) { + case 0x3b0: /* Command / control register */ + genius->genius_control = val; + if (val & 1) { + mem_mapping_set_addr(&genius->mapping, 0xa0000, 0x28000); + } else { + mem_mapping_set_addr(&genius->mapping, 0xb0000, 0x10000); + } - break; + break; - case 0x3b1:genius->genius_charh = val; - break; + case 0x3b1: + genius->genius_charh = val; + break; - /* Emulated CRTC, register select */ - case 0x3b2: - case 0x3b4: - case 0x3b6: - case 0x3d0: - case 0x3d2: - case 0x3d4: - case 0x3d6:genius->mda_crtcreg = val & 31; - break; + /* Emulated CRTC, register select */ + case 0x3b2: + case 0x3b4: + case 0x3b6: + case 0x3d0: + case 0x3d2: + case 0x3d4: + case 0x3d6: + genius->mda_crtcreg = val & 31; + break; - /* Emulated CRTC, value */ - case 0x3b3: - case 0x3b5: - case 0x3b7: - case 0x3d1: - case 0x3d3: - case 0x3d5: - case 0x3d7:genius->mda_crtc[genius->mda_crtcreg] = val; - genius_recalctimings(genius); - return; + /* Emulated CRTC, value */ + case 0x3b3: + case 0x3b5: + case 0x3b7: + case 0x3d1: + case 0x3d3: + case 0x3d5: + case 0x3d7: + genius->mda_crtc[genius->mda_crtcreg] = val; + genius_recalctimings(genius); + return; - /* Emulated MDA control register */ - case 0x3b8:genius->mda_ctrl = val; - return; - /* Emulated CGA control register */ - case 0x3D8:genius->cga_ctrl = val; - return; - /* Emulated CGA colour register */ - case 0x3D9:genius->cga_colour = val; - return; - } + /* Emulated MDA control register */ + case 0x3b8: + genius->mda_ctrl = val; + return; + /* Emulated CGA control register */ + case 0x3D8: + genius->cga_ctrl = val; + return; + /* Emulated CGA colour register */ + case 0x3D9: + genius->cga_colour = val; + return; + } } uint8_t genius_in(uint16_t addr, void *p) { - genius_t *genius = (genius_t *)p; + genius_t *genius = (genius_t *)p; - switch (addr) { - case 0x3b0: - case 0x3b2: - case 0x3b4: - case 0x3b6: - case 0x3d0: - case 0x3d2: - case 0x3d4: - case 0x3d6:return genius->mda_crtcreg; - case 0x3b1: - case 0x3b3: - case 0x3b5: - case 0x3b7: - case 0x3d1: - case 0x3d3: - case 0x3d5: - case 0x3d7:return genius->mda_crtc[genius->mda_crtcreg]; - case 0x3b8:return genius->mda_ctrl; - case 0x3d9:return genius->cga_colour; - case 0x3ba:return genius->mda_stat; - case 0x3d8:return genius->cga_ctrl; - case 0x3da:return genius->cga_stat; - } - return 0xff; + switch (addr) { + case 0x3b0: + case 0x3b2: + case 0x3b4: + case 0x3b6: + case 0x3d0: + case 0x3d2: + case 0x3d4: + case 0x3d6: + return genius->mda_crtcreg; + case 0x3b1: + case 0x3b3: + case 0x3b5: + case 0x3b7: + case 0x3d1: + case 0x3d3: + case 0x3d5: + case 0x3d7: + return genius->mda_crtc[genius->mda_crtcreg]; + case 0x3b8: + return genius->mda_ctrl; + case 0x3d9: + return genius->cga_colour; + case 0x3ba: + return genius->mda_stat; + case 0x3d8: + return genius->cga_ctrl; + case 0x3da: + return genius->cga_stat; + } + return 0xff; } void genius_write(uint32_t addr, uint8_t val, void *p) { - genius_t *genius = (genius_t *)p; - egawrites++; + genius_t *genius = (genius_t *)p; + egawrites++; - if (genius->genius_control & 1) { - addr = addr % 0x28000; - } else - /* If hi-res memory is disabled, only visible in the B000 segment */ - { - addr = (addr & 0xFFFF) + 0x10000; - } - genius->vram[addr] = val; + if (genius->genius_control & 1) { + addr = addr % 0x28000; + } else + /* If hi-res memory is disabled, only visible in the B000 segment */ + { + addr = (addr & 0xFFFF) + 0x10000; + } + genius->vram[addr] = val; } uint8_t genius_read(uint32_t addr, void *p) { - genius_t *genius = (genius_t *)p; - egareads++; + genius_t *genius = (genius_t *)p; + egareads++; - if (genius->genius_control & 1) { - addr = addr % 0x28000; - } else - /* If hi-res memory is disabled, only visible in the B000 segment */ - { - addr = (addr & 0xFFFF) + 0x10000; - } - return genius->vram[addr]; + if (genius->genius_control & 1) { + addr = addr % 0x28000; + } else + /* If hi-res memory is disabled, only visible in the B000 segment */ + { + addr = (addr & 0xFFFF) + 0x10000; + } + return genius->vram[addr]; } void genius_recalctimings(genius_t *genius) { - double disptime; - double _dispontime, _dispofftime; + double disptime; + double _dispontime, _dispofftime; - disptime = 0x31; - _dispontime = 0x28; - _dispofftime = disptime - _dispontime; - _dispontime *= MDACONST; - _dispofftime *= MDACONST; - genius->dispontime = (uint64_t)_dispontime; - genius->dispofftime = (uint64_t)_dispofftime; + disptime = 0x31; + _dispontime = 0x28; + _dispofftime = disptime - _dispontime; + _dispontime *= MDACONST; + _dispofftime *= MDACONST; + genius->dispontime = (uint64_t)_dispontime; + genius->dispofftime = (uint64_t)_dispofftime; } /* Draw a single line of the screen in either text mode */ void genius_textline(genius_t *genius, uint8_t background) { - int x; - int w = 80; /* 80 characters across */ - int cw = 9; /* Each character is 9 pixels wide */ - uint8_t chr, attr; - uint8_t bitmap[2]; - int blink, c, row; - int drawcursor, cursorline; - uint16_t addr; - uint8_t sc; - int charh; - uint16_t ma = (genius->mda_crtc[13] | (genius->mda_crtc[12] << 8)) & 0x3fff; - uint16_t ca = (genius->mda_crtc[15] | (genius->mda_crtc[14] << 8)) & 0x3fff; - unsigned char *framebuf = genius->vram + 0x10000; - uint32_t col; + int x; + int w = 80; /* 80 characters across */ + int cw = 9; /* Each character is 9 pixels wide */ + uint8_t chr, attr; + uint8_t bitmap[2]; + int blink, c, row; + int drawcursor, cursorline; + uint16_t addr; + uint8_t sc; + int charh; + uint16_t ma = (genius->mda_crtc[13] | (genius->mda_crtc[12] << 8)) & 0x3fff; + uint16_t ca = (genius->mda_crtc[15] | (genius->mda_crtc[14] << 8)) & 0x3fff; + unsigned char *framebuf = genius->vram + 0x10000; + uint32_t col; - /* Character height is 12-15 */ - charh = 15 - (genius->genius_charh & 3); - if (genius->genius_charh & 0x10) { - row = ((genius->displine >> 1) / charh); - sc = ((genius->displine >> 1) % charh); - } else { - row = (genius->displine / charh); - sc = (genius->displine % charh); - } - addr = ((ma & ~1) + row * w) * 2; + /* Character height is 12-15 */ + charh = 15 - (genius->genius_charh & 3); + if (genius->genius_charh & 0x10) { + row = ((genius->displine >> 1) / charh); + sc = ((genius->displine >> 1) % charh); + } else { + row = (genius->displine / charh); + sc = (genius->displine % charh); + } + addr = ((ma & ~1) + row * w) * 2; - ma += (row * w); + ma += (row * w); - if ((genius->mda_crtc[10] & 0x60) == 0x20) { - cursorline = 0; - } else { - cursorline = ((genius->mda_crtc[10] & 0x1F) <= sc) && - ((genius->mda_crtc[11] & 0x1F) >= sc); - } + if ((genius->mda_crtc[10] & 0x60) == 0x20) { + cursorline = 0; + } else { + cursorline = ((genius->mda_crtc[10] & 0x1F) <= sc) && ((genius->mda_crtc[11] & 0x1F) >= sc); + } - for (x = 0; x < w; x++) { - chr = framebuf[(addr + 2 * x) & 0x3FFF]; - attr = framebuf[(addr + 2 * x + 1) & 0x3FFF]; - drawcursor = ((ma == ca) && cursorline && genius->enabled && - (genius->mda_ctrl & 8)); + for (x = 0; x < w; x++) { + chr = framebuf[(addr + 2 * x) & 0x3FFF]; + attr = framebuf[(addr + 2 * x + 1) & 0x3FFF]; + drawcursor = ((ma == ca) && cursorline && genius->enabled && (genius->mda_ctrl & 8)); - switch (genius->mda_crtc[10] & 0x60) { - case 0x00:drawcursor = drawcursor && (genius->blink & 16); - break; - case 0x60:drawcursor = drawcursor && (genius->blink & 32); - break; - } - blink = ((genius->blink & 16) && - (genius->mda_ctrl & 0x20) && - (attr & 0x80) && !drawcursor); + switch (genius->mda_crtc[10] & 0x60) { + case 0x00: + drawcursor = drawcursor && (genius->blink & 16); + break; + case 0x60: + drawcursor = drawcursor && (genius->blink & 32); + break; + } + blink = ((genius->blink & 16) && (genius->mda_ctrl & 0x20) && (attr & 0x80) && !drawcursor); - if (genius->mda_ctrl & 0x20) - attr &= 0x7F; - /* MDA underline */ - if (sc == charh && ((attr & 7) == 1)) { - col = mdacols[attr][blink][1]; + if (genius->mda_ctrl & 0x20) + attr &= 0x7F; + /* MDA underline */ + if (sc == charh && ((attr & 7) == 1)) { + col = mdacols[attr][blink][1]; - if (genius->genius_control & 0x20) { - col ^= 0xffffff; - } + if (genius->genius_control & 0x20) { + col ^= 0xffffff; + } - for (c = 0; c < cw; c++) { - if (col != background) - ((uint32_t *)buffer32->line[genius->displine])[(x * cw) + c] = col; - } - } else /* Draw 8 pixels of character */ - { - bitmap[0] = fontdat8x12[chr][sc]; - for (c = 0; c < 8; c++) { - col = mdacols[attr][blink][(bitmap[0] & (1 << (c ^ 7))) ? 1 : 0]; - if (!(genius->enabled) || !(genius->mda_ctrl & 8)) - col = mdacols[0][0][0]; + for (c = 0; c < cw; c++) { + if (col != background) + ((uint32_t *)buffer32->line[genius->displine])[(x * cw) + c] = col; + } + } else /* Draw 8 pixels of character */ + { + bitmap[0] = fontdat8x12[chr][sc]; + for (c = 0; c < 8; c++) { + col = mdacols[attr][blink][(bitmap[0] & (1 << (c ^ 7))) ? 1 : 0]; + if (!(genius->enabled) || !(genius->mda_ctrl & 8)) + col = mdacols[0][0][0]; - if (genius->genius_control & 0x20) { - col ^= 0xffffff; - } - if (col != background) { - ((uint32_t *)buffer32->line[genius->displine])[(x * cw) + c] = col; - } - } - /* The ninth pixel column... */ - if ((chr & ~0x1f) == 0xc0) { - /* Echo column 8 for the graphics chars */ - col = ((uint32_t *)buffer32->line[genius->displine])[(x * cw) + 7]; - if (col != background) - ((uint32_t *)buffer32->line[genius->displine])[(x * cw) + 8] = col; - } else /* Otherwise fill with background */ - { - col = mdacols[attr][blink][0]; - if (genius->genius_control & 0x20) { - col ^= 0xffffff; - } - if (col != background) - ((uint32_t *)buffer32->line[genius->displine])[(x * cw) + 8] = col; - } - if (drawcursor) { - for (c = 0; c < cw; c++) - ((uint32_t *)buffer32->line[genius->displine])[(x * cw) + c] ^= mdacols[attr][0][1]; - } - ++ma; - } - } + if (genius->genius_control & 0x20) { + col ^= 0xffffff; + } + if (col != background) { + ((uint32_t *)buffer32->line[genius->displine])[(x * cw) + c] = col; + } + } + /* The ninth pixel column... */ + if ((chr & ~0x1f) == 0xc0) { + /* Echo column 8 for the graphics chars */ + col = ((uint32_t *)buffer32->line[genius->displine])[(x * cw) + 7]; + if (col != background) + ((uint32_t *)buffer32->line[genius->displine])[(x * cw) + 8] = col; + } else /* Otherwise fill with background */ + { + col = mdacols[attr][blink][0]; + if (genius->genius_control & 0x20) { + col ^= 0xffffff; + } + if (col != background) + ((uint32_t *)buffer32->line[genius->displine])[(x * cw) + 8] = col; + } + if (drawcursor) { + for (c = 0; c < cw; c++) + ((uint32_t *)buffer32->line[genius->displine])[(x * cw) + c] ^= mdacols[attr][0][1]; + } + ++ma; + } + } } /* Draw a line in the CGA 640x200 mode */ void genius_cgaline(genius_t *genius) { - int x, c; - uint32_t dat; - uint32_t ink; - uint32_t addr; + int x, c; + uint32_t dat; + uint32_t ink; + uint32_t addr; - ink = (genius->genius_control & 0x20) ? genius_pal[0] : genius_pal[3]; - /* We draw the CGA at row 600 */ - if (genius->displine < 600) { - return; - } - addr = 0x18000 + 80 * ((genius->displine - 600) >> 2); - if ((genius->displine - 600) & 2) { - addr += 0x2000; - } + ink = (genius->genius_control & 0x20) ? genius_pal[0] : genius_pal[3]; + /* We draw the CGA at row 600 */ + if (genius->displine < 600) { + return; + } + addr = 0x18000 + 80 * ((genius->displine - 600) >> 2); + if ((genius->displine - 600) & 2) { + addr += 0x2000; + } - for (x = 0; x < 80; x++) { - dat = genius->vram[addr]; - addr++; + for (x = 0; x < 80; x++) { + dat = genius->vram[addr]; + addr++; - for (c = 0; c < 8; c++) { - if (dat & 0x80) { - ((uint32_t *)buffer32->line[genius->displine])[x * 8 + c] = ink; - } - dat = dat << 1; - } - } + for (c = 0; c < 8; c++) { + if (dat & 0x80) { + ((uint32_t *)buffer32->line[genius->displine])[x * 8 + c] = ink; + } + dat = dat << 1; + } + } } /* Draw a line in the native high-resolution mode */ void genius_hiresline(genius_t *genius) { - int x, c; - uint32_t dat; - uint32_t ink; - uint32_t addr; + int x, c; + uint32_t dat; + uint32_t ink; + uint32_t addr; - ink = (genius->genius_control & 0x20) ? genius_pal[0] : genius_pal[3]; - /* The first 512 lines live at A0000 */ - if (genius->displine < 512) { - addr = 128 * genius->displine; - } else /* The second 496 live at B8000 */ - { - addr = 0x18000 + 128 * (genius->displine - 512); - } + ink = (genius->genius_control & 0x20) ? genius_pal[0] : genius_pal[3]; + /* The first 512 lines live at A0000 */ + if (genius->displine < 512) { + addr = 128 * genius->displine; + } else /* The second 496 live at B8000 */ + { + addr = 0x18000 + 128 * (genius->displine - 512); + } - for (x = 0; x < 91; x++) { - dat = genius->vram[addr]; - addr++; + for (x = 0; x < 91; x++) { + dat = genius->vram[addr]; + addr++; - for (c = 0; c < 8; c++) { - if (dat & 0x80) { - ((uint32_t *)buffer32->line[genius->displine])[x * 8 + c] = ink; - } - dat = dat << 1; - } - } + for (c = 0; c < 8; c++) { + if (dat & 0x80) { + ((uint32_t *)buffer32->line[genius->displine])[x * 8 + c] = ink; + } + dat = dat << 1; + } + } } void genius_poll(void *p) { - genius_t *genius = (genius_t *)p; - int x; - uint32_t background; + genius_t *genius = (genius_t *)p; + int x; + uint32_t background; - if (!genius->linepos) { - timer_advance_u64(&genius->timer, genius->dispofftime); - genius->cga_stat |= 1; - genius->mda_stat |= 1; - genius->linepos = 1; - if (genius->dispon) { - if (genius->genius_control & 0x20) { - background = genius_pal[3]; - } else { - background = genius_pal[0]; - } - if (genius->displine == 0) { - video_wait_for_buffer(); - } - /* Start off with a blank line */ - for (x = 0; x < GENIUS_XSIZE; x++) { - ((uint32_t *)buffer32->line[genius->displine])[x] = background; - } - /* If graphics display enabled, draw graphics on top - * of the blanked line */ - if (genius->cga_ctrl & 8) { - if (genius->genius_control & 8) { - genius_cgaline(genius); - } else { - genius_hiresline(genius); - } - } - /* If MDA display is enabled, draw MDA text on top - * of the lot */ - if (genius->mda_ctrl & 8) { - genius_textline(genius, background); - } - } - genius->displine++; - /* Hardcode a fixed refresh rate and VSYNC timing */ - if (genius->displine == 1008) /* Start of VSYNC */ - { - genius->cga_stat |= 8; - genius->dispon = 0; - } - if (genius->displine == 1040) /* End of VSYNC */ - { - genius->displine = 0; - genius->cga_stat &= ~8; - genius->dispon = 1; - } - } else { - if (genius->dispon) { - genius->cga_stat &= ~1; - genius->mda_stat &= ~1; - } - timer_advance_u64(&genius->timer, genius->dispontime); - genius->linepos = 0; + if (!genius->linepos) { + timer_advance_u64(&genius->timer, genius->dispofftime); + genius->cga_stat |= 1; + genius->mda_stat |= 1; + genius->linepos = 1; + if (genius->dispon) { + if (genius->genius_control & 0x20) { + background = genius_pal[3]; + } else { + background = genius_pal[0]; + } + if (genius->displine == 0) { + video_wait_for_buffer(); + } + /* Start off with a blank line */ + for (x = 0; x < GENIUS_XSIZE; x++) { + ((uint32_t *)buffer32->line[genius->displine])[x] = background; + } + /* If graphics display enabled, draw graphics on top + * of the blanked line */ + if (genius->cga_ctrl & 8) { + if (genius->genius_control & 8) { + genius_cgaline(genius); + } else { + genius_hiresline(genius); + } + } + /* If MDA display is enabled, draw MDA text on top + * of the lot */ + if (genius->mda_ctrl & 8) { + genius_textline(genius, background); + } + } + genius->displine++; + /* Hardcode a fixed refresh rate and VSYNC timing */ + if (genius->displine == 1008) /* Start of VSYNC */ + { + genius->cga_stat |= 8; + genius->dispon = 0; + } + if (genius->displine == 1040) /* End of VSYNC */ + { + genius->displine = 0; + genius->cga_stat &= ~8; + genius->dispon = 1; + } + } else { + if (genius->dispon) { + genius->cga_stat &= ~1; + genius->mda_stat &= ~1; + } + timer_advance_u64(&genius->timer, genius->dispontime); + genius->linepos = 0; - if (genius->displine == 1008) { -/* Hardcode GENIUS_XSIZE * GENIUS_YSIZE window size */ - if (GENIUS_XSIZE != xsize || GENIUS_YSIZE != ysize) { - xsize = GENIUS_XSIZE; - ysize = GENIUS_YSIZE; - if (xsize < 64) - xsize = 656; - if (ysize < 32) - ysize = 200; - updatewindowsize(xsize, ysize); - } - video_blit_memtoscreen(0, 0, 0, ysize, xsize, ysize); + if (genius->displine == 1008) { + /* Hardcode GENIUS_XSIZE * GENIUS_YSIZE window size */ + if (GENIUS_XSIZE != xsize || GENIUS_YSIZE != ysize) { + xsize = GENIUS_XSIZE; + ysize = GENIUS_YSIZE; + if (xsize < 64) + xsize = 656; + if (ysize < 32) + ysize = 200; + updatewindowsize(xsize, ysize); + } + video_blit_memtoscreen(0, 0, 0, ysize, xsize, ysize); - frames++; - /* Fixed 728x1008 resolution */ - video_res_x = GENIUS_XSIZE; - video_res_y = GENIUS_YSIZE; - video_bpp = 1; - genius->blink++; - } - } + frames++; + /* Fixed 728x1008 resolution */ + video_res_x = GENIUS_XSIZE; + video_res_y = GENIUS_YSIZE; + video_bpp = 1; + genius->blink++; + } + } } void *genius_init() { - int c; - genius_t *genius = malloc(sizeof(genius_t)); - memset(genius, 0, sizeof(genius_t)); + int c; + genius_t *genius = malloc(sizeof(genius_t)); + memset(genius, 0, sizeof(genius_t)); - /* 160k video RAM */ - genius->vram = malloc(0x28000); + /* 160k video RAM */ + genius->vram = malloc(0x28000); - timer_add(&genius->timer, genius_poll, genius, 1); + timer_add(&genius->timer, genius_poll, genius, 1); - /* Occupy memory between 0xB0000 and 0xBFFFF (moves to 0xA0000 in - * high-resolution modes) */ - mem_mapping_add(&genius->mapping, 0xb0000, 0x10000, genius_read, NULL, NULL, genius_write, NULL, NULL, NULL, 0, genius); - /* Respond to both MDA and CGA I/O ports */ - io_sethandler(0x03b0, 0x000C, genius_in, NULL, NULL, genius_out, NULL, NULL, genius); - io_sethandler(0x03d0, 0x0010, genius_in, NULL, NULL, genius_out, NULL, NULL, genius); + /* Occupy memory between 0xB0000 and 0xBFFFF (moves to 0xA0000 in + * high-resolution modes) */ + mem_mapping_add(&genius->mapping, 0xb0000, 0x10000, genius_read, NULL, NULL, genius_write, NULL, NULL, NULL, 0, genius); + /* Respond to both MDA and CGA I/O ports */ + io_sethandler(0x03b0, 0x000C, genius_in, NULL, NULL, genius_out, NULL, NULL, genius); + io_sethandler(0x03d0, 0x0010, genius_in, NULL, NULL, genius_out, NULL, NULL, genius); - genius_pal[0] = makecol(0x00, 0x00, 0x00); - genius_pal[1] = makecol(0x55, 0x55, 0x55); - genius_pal[2] = makecol(0xaa, 0xaa, 0xaa); - genius_pal[3] = makecol(0xff, 0xff, 0xff); + genius_pal[0] = makecol(0x00, 0x00, 0x00); + genius_pal[1] = makecol(0x55, 0x55, 0x55); + genius_pal[2] = makecol(0xaa, 0xaa, 0xaa); + genius_pal[3] = makecol(0xff, 0xff, 0xff); - /* MDA attributes */ - /* I don't know if the Genius's MDA emulation actually does - * emulate bright / non-bright. For the time being pretend it does. */ - for (c = 0; c < 256; c++) { - mdacols[c][0][0] = mdacols[c][1][0] = mdacols[c][1][1] = genius_pal[0]; - if (c & 8) - mdacols[c][0][1] = genius_pal[3]; - else - mdacols[c][0][1] = genius_pal[2]; - } - mdacols[0x70][0][1] = genius_pal[0]; - mdacols[0x70][0][0] = mdacols[0x70][1][0] = mdacols[0x70][1][1] = genius_pal[3]; - mdacols[0xF0][0][1] = genius_pal[0]; - mdacols[0xF0][0][0] = mdacols[0xF0][1][0] = mdacols[0xF0][1][1] = genius_pal[3]; - mdacols[0x78][0][1] = genius_pal[2]; - mdacols[0x78][0][0] = mdacols[0x78][1][0] = mdacols[0x78][1][1] = genius_pal[3]; - mdacols[0xF8][0][1] = genius_pal[2]; - mdacols[0xF8][0][0] = mdacols[0xF8][1][0] = mdacols[0xF8][1][1] = genius_pal[3]; - mdacols[0x00][0][1] = mdacols[0x00][1][1] = genius_pal[0]; - mdacols[0x08][0][1] = mdacols[0x08][1][1] = genius_pal[0]; - mdacols[0x80][0][1] = mdacols[0x80][1][1] = genius_pal[0]; - mdacols[0x88][0][1] = mdacols[0x88][1][1] = genius_pal[0]; + /* MDA attributes */ + /* I don't know if the Genius's MDA emulation actually does + * emulate bright / non-bright. For the time being pretend it does. */ + for (c = 0; c < 256; c++) { + mdacols[c][0][0] = mdacols[c][1][0] = mdacols[c][1][1] = genius_pal[0]; + if (c & 8) + mdacols[c][0][1] = genius_pal[3]; + else + mdacols[c][0][1] = genius_pal[2]; + } + mdacols[0x70][0][1] = genius_pal[0]; + mdacols[0x70][0][0] = mdacols[0x70][1][0] = mdacols[0x70][1][1] = genius_pal[3]; + mdacols[0xF0][0][1] = genius_pal[0]; + mdacols[0xF0][0][0] = mdacols[0xF0][1][0] = mdacols[0xF0][1][1] = genius_pal[3]; + mdacols[0x78][0][1] = genius_pal[2]; + mdacols[0x78][0][0] = mdacols[0x78][1][0] = mdacols[0x78][1][1] = genius_pal[3]; + mdacols[0xF8][0][1] = genius_pal[2]; + mdacols[0xF8][0][0] = mdacols[0xF8][1][0] = mdacols[0xF8][1][1] = genius_pal[3]; + mdacols[0x00][0][1] = mdacols[0x00][1][1] = genius_pal[0]; + mdacols[0x08][0][1] = mdacols[0x08][1][1] = genius_pal[0]; + mdacols[0x80][0][1] = mdacols[0x80][1][1] = genius_pal[0]; + mdacols[0x88][0][1] = mdacols[0x88][1][1] = genius_pal[0]; -/* Start off in 80x25 text mode */ - genius->cga_stat = 0xF4; - genius->genius_mode = 2; - genius->enabled = 1; - genius->genius_charh = 0x90; /* Native character height register */ - return genius; + /* Start off in 80x25 text mode */ + genius->cga_stat = 0xF4; + genius->genius_mode = 2; + genius->enabled = 1; + genius->genius_charh = 0x90; /* Native character height register */ + return genius; } void genius_close(void *p) { - genius_t *genius = (genius_t *)p; + genius_t *genius = (genius_t *)p; - free(genius->vram); - free(genius); + free(genius->vram); + free(genius); } -static int genius_available() { - return rom_present("8x12.bin"); -} +static int genius_available() { return rom_present("8x12.bin"); } void genius_speed_changed(void *p) { - genius_t *genius = (genius_t *)p; + genius_t *genius = (genius_t *)p; - genius_recalctimings(genius); + genius_recalctimings(genius); } -device_t genius_device = - { - "Genius VHR", - 0, - genius_init, - genius_close, - genius_available, - genius_speed_changed, - NULL, - NULL - }; +device_t genius_device = {"Genius VHR", 0, genius_init, genius_close, genius_available, genius_speed_changed, NULL, NULL}; diff --git a/src/video/vid_hercules.c b/src/video/vid_hercules.c index e1071f2d..6aad1bfd 100644 --- a/src/video/vid_hercules.c +++ b/src/video/vid_hercules.c @@ -9,26 +9,26 @@ #include "vid_hercules.h" typedef struct hercules_t { - mem_mapping_t mapping; + mem_mapping_t mapping; - uint8_t crtc[32]; - int crtcreg; + uint8_t crtc[32]; + int crtcreg; - uint8_t ctrl, ctrl2, stat; + uint8_t ctrl, ctrl2, stat; - uint64_t dispontime, dispofftime; - pc_timer_t timer; + uint64_t dispontime, dispofftime; + pc_timer_t timer; - int firstline, lastline; + int firstline, lastline; - int linepos, displine; - int vc, sc; - uint16_t ma, maback; - int con, coff, cursoron; - int dispon, blink; - int vsynctime, vadj; + int linepos, displine; + int vc, sc; + uint16_t ma, maback; + int con, coff, cursoron; + int dispon, blink; + int vsynctime, vadj; - uint8_t *vram; + uint8_t *vram; } hercules_t; static uint32_t mdacols[256][2][2]; @@ -38,335 +38,328 @@ void hercules_write(uint32_t addr, uint8_t val, void *p); uint8_t hercules_read(uint32_t addr, void *p); void hercules_out(uint16_t addr, uint8_t val, void *p) { - hercules_t *hercules = (hercules_t *)p; -// pclog("Herc out %04X %02X\n",addr,val); - switch (addr) { - case 0x3b0: - case 0x3b2: - case 0x3b4: - case 0x3b6:hercules->crtcreg = val & 31; - return; - case 0x3b1: - case 0x3b3: - case 0x3b5: - case 0x3b7:hercules->crtc[hercules->crtcreg] = val; - if (hercules->crtc[10] == 6 && hercules->crtc[11] == 7) /*Fix for Generic Turbo XT BIOS, which sets up cursor registers wrong*/ - { - hercules->crtc[10] = 0xb; - hercules->crtc[11] = 0xc; - } - hercules_recalctimings(hercules); - return; - case 0x3b8:hercules->ctrl = val; - return; - case 0x3bf:hercules->ctrl2 = val; - if (val & 2) - mem_mapping_set_addr(&hercules->mapping, 0xb0000, 0x10000); - else - mem_mapping_set_addr(&hercules->mapping, 0xb0000, 0x08000); - return; - } + hercules_t *hercules = (hercules_t *)p; + // pclog("Herc out %04X %02X\n",addr,val); + switch (addr) { + case 0x3b0: + case 0x3b2: + case 0x3b4: + case 0x3b6: + hercules->crtcreg = val & 31; + return; + case 0x3b1: + case 0x3b3: + case 0x3b5: + case 0x3b7: + hercules->crtc[hercules->crtcreg] = val; + if (hercules->crtc[10] == 6 && + hercules->crtc[11] == 7) /*Fix for Generic Turbo XT BIOS, which sets up cursor registers wrong*/ + { + hercules->crtc[10] = 0xb; + hercules->crtc[11] = 0xc; + } + hercules_recalctimings(hercules); + return; + case 0x3b8: + hercules->ctrl = val; + return; + case 0x3bf: + hercules->ctrl2 = val; + if (val & 2) + mem_mapping_set_addr(&hercules->mapping, 0xb0000, 0x10000); + else + mem_mapping_set_addr(&hercules->mapping, 0xb0000, 0x08000); + return; + } } uint8_t hercules_in(uint16_t addr, void *p) { - hercules_t *hercules = (hercules_t *)p; - // pclog("Herc in %04X %02X %04X:%04X %04X\n",addr,(hercules_stat & 0xF) | ((hercules_stat & 8) << 4),CS,pc,CX); - switch (addr) { - case 0x3b0: - case 0x3b2: - case 0x3b4: - case 0x3b6:return hercules->crtcreg; - case 0x3b1: - case 0x3b3: - case 0x3b5: - case 0x3b7:return hercules->crtc[hercules->crtcreg]; - case 0x3ba:return (hercules->stat & 0xf) | ((hercules->stat & 8) << 4); - } - return 0xff; + hercules_t *hercules = (hercules_t *)p; + // pclog("Herc in %04X %02X %04X:%04X %04X\n",addr,(hercules_stat & 0xF) | ((hercules_stat & 8) << 4),CS,pc,CX); + switch (addr) { + case 0x3b0: + case 0x3b2: + case 0x3b4: + case 0x3b6: + return hercules->crtcreg; + case 0x3b1: + case 0x3b3: + case 0x3b5: + case 0x3b7: + return hercules->crtc[hercules->crtcreg]; + case 0x3ba: + return (hercules->stat & 0xf) | ((hercules->stat & 8) << 4); + } + return 0xff; } void hercules_write(uint32_t addr, uint8_t val, void *p) { - hercules_t *hercules = (hercules_t *)p; - egawrites++; -// pclog("Herc write %08X %02X\n",addr,val); - hercules->vram[addr & 0xffff] = val; + hercules_t *hercules = (hercules_t *)p; + egawrites++; + // pclog("Herc write %08X %02X\n",addr,val); + hercules->vram[addr & 0xffff] = val; } uint8_t hercules_read(uint32_t addr, void *p) { - hercules_t *hercules = (hercules_t *)p; - egareads++; - return hercules->vram[addr & 0xffff]; + hercules_t *hercules = (hercules_t *)p; + egareads++; + return hercules->vram[addr & 0xffff]; } void hercules_recalctimings(hercules_t *hercules) { - double disptime; - double _dispontime, _dispofftime; - disptime = hercules->crtc[0] + 1; - _dispontime = hercules->crtc[1]; - _dispofftime = disptime - _dispontime; - _dispontime *= MDACONST; - _dispofftime *= MDACONST; - hercules->dispontime = (uint64_t)_dispontime; - hercules->dispofftime = (uint64_t)_dispofftime; + double disptime; + double _dispontime, _dispofftime; + disptime = hercules->crtc[0] + 1; + _dispontime = hercules->crtc[1]; + _dispofftime = disptime - _dispontime; + _dispontime *= MDACONST; + _dispofftime *= MDACONST; + hercules->dispontime = (uint64_t)_dispontime; + hercules->dispofftime = (uint64_t)_dispofftime; } void hercules_poll(void *p) { - hercules_t *hercules = (hercules_t *)p; - uint16_t ca = (hercules->crtc[15] | (hercules->crtc[14] << 8)) & 0x3fff; - int drawcursor; - int x, c; - int oldvc; - uint8_t chr, attr; - uint16_t dat; - int oldsc; - int blink; - if (!hercules->linepos) { - //pclog("Poll %i %i\n",vc,sc); - timer_advance_u64(&hercules->timer, hercules->dispofftime); - hercules->stat |= 1; - hercules->linepos = 1; - oldsc = hercules->sc; - if ((hercules->crtc[8] & 3) == 3) - hercules->sc = (hercules->sc << 1) & 7; - if (hercules->dispon) { - if (hercules->displine < hercules->firstline) { - hercules->firstline = hercules->displine; - video_wait_for_buffer(); - } - hercules->lastline = hercules->displine; - if ((hercules->ctrl & 2) && (hercules->ctrl2 & 1)) { - ca = (hercules->sc & 3) * 0x2000; - if ((hercules->ctrl & 0x80) && (hercules->ctrl2 & 2)) - ca += 0x8000; -// printf("Draw herc %04X\n",ca); - for (x = 0; x < hercules->crtc[1]; x++) { - dat = (hercules->vram[((hercules->ma << 1) & 0x1fff) + ca] << 8) | hercules->vram[((hercules->ma << 1) & 0x1fff) + ca + 1]; - hercules->ma++; - for (c = 0; c < 16; c++) - ((uint32_t *)buffer32->line[hercules->displine])[(x << 4) + c] = (dat & (32768 >> c)) ? cgapal[0x7] : 0; - } - } else { - for (x = 0; x < hercules->crtc[1]; x++) { - chr = hercules->vram[(hercules->ma << 1) & 0xfff]; - attr = hercules->vram[((hercules->ma << 1) + 1) & 0xfff]; - drawcursor = ((hercules->ma == ca) && hercules->con && hercules->cursoron); - blink = ((hercules->blink & 16) && (hercules->ctrl & 0x20) && (attr & 0x80) && !drawcursor); - if (hercules->sc == 12 && ((attr & 7) == 1)) { - for (c = 0; c < 9; c++) - ((uint32_t *)buffer32->line[hercules->displine])[(x * 9) + c] = mdacols[attr][blink][1]; - } else { - for (c = 0; c < 8; c++) - ((uint32_t *)buffer32->line[hercules->displine])[(x * 9) + c] = mdacols[attr][blink][(fontdatm[chr][hercules->sc] & (1 << (c ^ 7))) ? 1 : 0]; - if ((chr & ~0x1f) == 0xc0) - ((uint32_t *)buffer32->line[hercules->displine])[(x * 9) + 8] = mdacols[attr][blink][fontdatm[chr][hercules->sc] & 1]; - else - ((uint32_t *)buffer32->line[hercules->displine])[(x * 9) + 8] = mdacols[attr][blink][0]; - } - hercules->ma++; - if (drawcursor) { - for (c = 0; c < 9; c++) - ((uint32_t *)buffer32->line[hercules->displine])[(x * 9) + c] ^= mdacols[attr][0][1]; - } - } - } - } - hercules->sc = oldsc; - if (hercules->vc == hercules->crtc[7] && !hercules->sc) { - hercules->stat |= 8; -// printf("VSYNC on %i %i\n",vc,sc); - } - hercules->displine++; - if (hercules->displine >= 500) - hercules->displine = 0; - } else { - timer_advance_u64(&hercules->timer, hercules->dispontime); - if (hercules->dispon) - hercules->stat &= ~1; - hercules->linepos = 0; - if (hercules->vsynctime) { - hercules->vsynctime--; - if (!hercules->vsynctime) { - hercules->stat &= ~8; -// printf("VSYNC off %i %i\n",vc,sc); - } - } - if (hercules->sc == (hercules->crtc[11] & 31) || ((hercules->crtc[8] & 3) == 3 && hercules->sc == ((hercules->crtc[11] & 31) >> 1))) { - hercules->con = 0; - hercules->coff = 1; - } - if (hercules->vadj) { - hercules->sc++; - hercules->sc &= 31; - hercules->ma = hercules->maback; - hercules->vadj--; - if (!hercules->vadj) { - hercules->dispon = 1; - hercules->ma = hercules->maback = (hercules->crtc[13] | (hercules->crtc[12] << 8)) & 0x3fff; - hercules->sc = 0; - } - } else if (hercules->sc == hercules->crtc[9] || ((hercules->crtc[8] & 3) == 3 && hercules->sc == (hercules->crtc[9] >> 1))) { - hercules->maback = hercules->ma; - hercules->sc = 0; - oldvc = hercules->vc; - hercules->vc++; - hercules->vc &= 127; - if (hercules->vc == hercules->crtc[6]) - hercules->dispon = 0; - if (oldvc == hercules->crtc[4]) { -// printf("Display over at %i\n",displine); - hercules->vc = 0; - hercules->vadj = hercules->crtc[5]; - if (!hercules->vadj) - hercules->dispon = 1; - if (!hercules->vadj) - hercules->ma = hercules->maback = (hercules->crtc[13] | (hercules->crtc[12] << 8)) & 0x3fff; - if ((hercules->crtc[10] & 0x60) == 0x20) - hercules->cursoron = 0; - else - hercules->cursoron = hercules->blink & 16; - } - if (hercules->vc == hercules->crtc[7]) { - hercules->dispon = 0; - hercules->displine = 0; - hercules->vsynctime = 16;//(crtcm[3]>>4)+1; - if (hercules->crtc[7]) { -// printf("Lastline %i Firstline %i %i\n",lastline,firstline,lastline-firstline); - if ((hercules->ctrl & 2) && (hercules->ctrl2 & 1)) - x = hercules->crtc[1] << 4; - else - x = hercules->crtc[1] * 9; - hercules->lastline++; - if (x != xsize || (hercules->lastline - hercules->firstline) != ysize) { - xsize = x; - ysize = hercules->lastline - hercules->firstline; -// printf("Resize to %i,%i - R1 %i\n",xsize,ysize,crtcm[1]); - if (xsize < 64) - xsize = 656; - if (ysize < 32) - ysize = 200; - updatewindowsize(xsize, ysize); - } + hercules_t *hercules = (hercules_t *)p; + uint16_t ca = (hercules->crtc[15] | (hercules->crtc[14] << 8)) & 0x3fff; + int drawcursor; + int x, c; + int oldvc; + uint8_t chr, attr; + uint16_t dat; + int oldsc; + int blink; + if (!hercules->linepos) { + // pclog("Poll %i %i\n",vc,sc); + timer_advance_u64(&hercules->timer, hercules->dispofftime); + hercules->stat |= 1; + hercules->linepos = 1; + oldsc = hercules->sc; + if ((hercules->crtc[8] & 3) == 3) + hercules->sc = (hercules->sc << 1) & 7; + if (hercules->dispon) { + if (hercules->displine < hercules->firstline) { + hercules->firstline = hercules->displine; + video_wait_for_buffer(); + } + hercules->lastline = hercules->displine; + if ((hercules->ctrl & 2) && (hercules->ctrl2 & 1)) { + ca = (hercules->sc & 3) * 0x2000; + if ((hercules->ctrl & 0x80) && (hercules->ctrl2 & 2)) + ca += 0x8000; + // printf("Draw herc %04X\n",ca); + for (x = 0; x < hercules->crtc[1]; x++) { + dat = (hercules->vram[((hercules->ma << 1) & 0x1fff) + ca] << 8) | + hercules->vram[((hercules->ma << 1) & 0x1fff) + ca + 1]; + hercules->ma++; + for (c = 0; c < 16; c++) + ((uint32_t *)buffer32->line[hercules->displine])[(x << 4) + c] = + (dat & (32768 >> c)) ? cgapal[0x7] : 0; + } + } else { + for (x = 0; x < hercules->crtc[1]; x++) { + chr = hercules->vram[(hercules->ma << 1) & 0xfff]; + attr = hercules->vram[((hercules->ma << 1) + 1) & 0xfff]; + drawcursor = ((hercules->ma == ca) && hercules->con && hercules->cursoron); + blink = ((hercules->blink & 16) && (hercules->ctrl & 0x20) && (attr & 0x80) && + !drawcursor); + if (hercules->sc == 12 && ((attr & 7) == 1)) { + for (c = 0; c < 9; c++) + ((uint32_t *)buffer32->line[hercules->displine])[(x * 9) + c] = + mdacols[attr][blink][1]; + } else { + for (c = 0; c < 8; c++) + ((uint32_t *)buffer32->line[hercules->displine])[(x * 9) + c] = + mdacols[attr][blink] + [(fontdatm[chr][hercules->sc] & (1 << (c ^ 7))) ? 1 : 0]; + if ((chr & ~0x1f) == 0xc0) + ((uint32_t *)buffer32->line[hercules->displine])[(x * 9) + 8] = + mdacols[attr][blink][fontdatm[chr][hercules->sc] & 1]; + else + ((uint32_t *)buffer32->line[hercules->displine])[(x * 9) + 8] = + mdacols[attr][blink][0]; + } + hercules->ma++; + if (drawcursor) { + for (c = 0; c < 9; c++) + ((uint32_t *)buffer32->line[hercules->displine])[(x * 9) + c] ^= + mdacols[attr][0][1]; + } + } + } + } + hercules->sc = oldsc; + if (hercules->vc == hercules->crtc[7] && !hercules->sc) { + hercules->stat |= 8; + // printf("VSYNC on %i %i\n",vc,sc); + } + hercules->displine++; + if (hercules->displine >= 500) + hercules->displine = 0; + } else { + timer_advance_u64(&hercules->timer, hercules->dispontime); + if (hercules->dispon) + hercules->stat &= ~1; + hercules->linepos = 0; + if (hercules->vsynctime) { + hercules->vsynctime--; + if (!hercules->vsynctime) { + hercules->stat &= ~8; + // printf("VSYNC off %i %i\n",vc,sc); + } + } + if (hercules->sc == (hercules->crtc[11] & 31) || + ((hercules->crtc[8] & 3) == 3 && hercules->sc == ((hercules->crtc[11] & 31) >> 1))) { + hercules->con = 0; + hercules->coff = 1; + } + if (hercules->vadj) { + hercules->sc++; + hercules->sc &= 31; + hercules->ma = hercules->maback; + hercules->vadj--; + if (!hercules->vadj) { + hercules->dispon = 1; + hercules->ma = hercules->maback = (hercules->crtc[13] | (hercules->crtc[12] << 8)) & 0x3fff; + hercules->sc = 0; + } + } else if (hercules->sc == hercules->crtc[9] || + ((hercules->crtc[8] & 3) == 3 && hercules->sc == (hercules->crtc[9] >> 1))) { + hercules->maback = hercules->ma; + hercules->sc = 0; + oldvc = hercules->vc; + hercules->vc++; + hercules->vc &= 127; + if (hercules->vc == hercules->crtc[6]) + hercules->dispon = 0; + if (oldvc == hercules->crtc[4]) { + // printf("Display over at %i\n",displine); + hercules->vc = 0; + hercules->vadj = hercules->crtc[5]; + if (!hercules->vadj) + hercules->dispon = 1; + if (!hercules->vadj) + hercules->ma = hercules->maback = + (hercules->crtc[13] | (hercules->crtc[12] << 8)) & 0x3fff; + if ((hercules->crtc[10] & 0x60) == 0x20) + hercules->cursoron = 0; + else + hercules->cursoron = hercules->blink & 16; + } + if (hercules->vc == hercules->crtc[7]) { + hercules->dispon = 0; + hercules->displine = 0; + hercules->vsynctime = 16; //(crtcm[3]>>4)+1; + if (hercules->crtc[7]) { + // printf("Lastline %i Firstline %i + // %i\n",lastline,firstline,lastline-firstline); + if ((hercules->ctrl & 2) && (hercules->ctrl2 & 1)) + x = hercules->crtc[1] << 4; + else + x = hercules->crtc[1] * 9; + hercules->lastline++; + if (x != xsize || (hercules->lastline - hercules->firstline) != ysize) { + xsize = x; + ysize = hercules->lastline - hercules->firstline; + // printf("Resize to %i,%i - R1 + // %i\n",xsize,ysize,crtcm[1]); + if (xsize < 64) + xsize = 656; + if (ysize < 32) + ysize = 200; + updatewindowsize(xsize, ysize); + } - video_blit_memtoscreen(0, hercules->firstline, 0, ysize, xsize, ysize); + video_blit_memtoscreen(0, hercules->firstline, 0, ysize, xsize, ysize); - frames++; - if ((hercules->ctrl & 2) && (hercules->ctrl2 & 1)) { - video_res_x = hercules->crtc[1] * 16; - video_res_y = hercules->crtc[6] * 4; - video_bpp = 1; - } else { - video_res_x = hercules->crtc[1]; - video_res_y = hercules->crtc[6]; - video_bpp = 0; - } - } - hercules->firstline = 1000; - hercules->lastline = 0; - hercules->blink++; - } - } else { - hercules->sc++; - hercules->sc &= 31; - hercules->ma = hercules->maback; - } - if ((hercules->sc == (hercules->crtc[10] & 31) || ((hercules->crtc[8] & 3) == 3 && hercules->sc == ((hercules->crtc[10] & 31) >> 1)))) { - hercules->con = 1; -// printf("Cursor on - %02X %02X %02X\n",crtcm[8],crtcm[10],crtcm[11]); - } - } + frames++; + if ((hercules->ctrl & 2) && (hercules->ctrl2 & 1)) { + video_res_x = hercules->crtc[1] * 16; + video_res_y = hercules->crtc[6] * 4; + video_bpp = 1; + } else { + video_res_x = hercules->crtc[1]; + video_res_y = hercules->crtc[6]; + video_bpp = 0; + } + } + hercules->firstline = 1000; + hercules->lastline = 0; + hercules->blink++; + } + } else { + hercules->sc++; + hercules->sc &= 31; + hercules->ma = hercules->maback; + } + if ((hercules->sc == (hercules->crtc[10] & 31) || + ((hercules->crtc[8] & 3) == 3 && hercules->sc == ((hercules->crtc[10] & 31) >> 1)))) { + hercules->con = 1; + // printf("Cursor on - %02X %02X %02X\n",crtcm[8],crtcm[10],crtcm[11]); + } + } } void *hercules_init() { - int display_type; - int c; - hercules_t *hercules = malloc(sizeof(hercules_t)); - memset(hercules, 0, sizeof(hercules_t)); + int display_type; + int c; + hercules_t *hercules = malloc(sizeof(hercules_t)); + memset(hercules, 0, sizeof(hercules_t)); - hercules->vram = malloc(0x10000); + hercules->vram = malloc(0x10000); - timer_add(&hercules->timer, hercules_poll, hercules, 1); - mem_mapping_add(&hercules->mapping, 0xb0000, 0x08000, hercules_read, NULL, NULL, hercules_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, hercules); - io_sethandler(0x03b0, 0x0010, hercules_in, NULL, NULL, hercules_out, NULL, NULL, hercules); + timer_add(&hercules->timer, hercules_poll, hercules, 1); + mem_mapping_add(&hercules->mapping, 0xb0000, 0x08000, hercules_read, NULL, NULL, hercules_write, NULL, NULL, NULL, + MEM_MAPPING_EXTERNAL, hercules); + io_sethandler(0x03b0, 0x0010, hercules_in, NULL, NULL, hercules_out, NULL, NULL, hercules); - display_type = device_get_config_int("display_type"); - cgapal_rebuild(display_type, 0); + display_type = device_get_config_int("display_type"); + cgapal_rebuild(display_type, 0); - for (c = 0; c < 256; c++) { - mdacols[c][0][0] = mdacols[c][1][0] = mdacols[c][1][1] = cgapal[0]; - if (c & 8) - mdacols[c][0][1] = cgapal[0xf]; - else - mdacols[c][0][1] = cgapal[0x7]; - } - mdacols[0x70][0][1] = cgapal[0]; - mdacols[0x70][0][0] = mdacols[0x70][1][0] = mdacols[0x70][1][1] = cgapal[0xf]; - mdacols[0xF0][0][1] = cgapal[0]; - mdacols[0xF0][0][0] = mdacols[0xF0][1][0] = mdacols[0xF0][1][1] = cgapal[0xf]; - mdacols[0x78][0][1] = cgapal[0x7]; - mdacols[0x78][0][0] = mdacols[0x78][1][0] = mdacols[0x78][1][1] = cgapal[0xf]; - mdacols[0xF8][0][1] = cgapal[0x7]; - mdacols[0xF8][0][0] = mdacols[0xF8][1][0] = mdacols[0xF8][1][1] = cgapal[0xf]; - mdacols[0x00][0][1] = mdacols[0x00][1][1] = cgapal[0]; - mdacols[0x08][0][1] = mdacols[0x08][1][1] = cgapal[0]; - mdacols[0x80][0][1] = mdacols[0x80][1][1] = cgapal[0]; - mdacols[0x88][0][1] = mdacols[0x88][1][1] = cgapal[0]; + for (c = 0; c < 256; c++) { + mdacols[c][0][0] = mdacols[c][1][0] = mdacols[c][1][1] = cgapal[0]; + if (c & 8) + mdacols[c][0][1] = cgapal[0xf]; + else + mdacols[c][0][1] = cgapal[0x7]; + } + mdacols[0x70][0][1] = cgapal[0]; + mdacols[0x70][0][0] = mdacols[0x70][1][0] = mdacols[0x70][1][1] = cgapal[0xf]; + mdacols[0xF0][0][1] = cgapal[0]; + mdacols[0xF0][0][0] = mdacols[0xF0][1][0] = mdacols[0xF0][1][1] = cgapal[0xf]; + mdacols[0x78][0][1] = cgapal[0x7]; + mdacols[0x78][0][0] = mdacols[0x78][1][0] = mdacols[0x78][1][1] = cgapal[0xf]; + mdacols[0xF8][0][1] = cgapal[0x7]; + mdacols[0xF8][0][0] = mdacols[0xF8][1][0] = mdacols[0xF8][1][1] = cgapal[0xf]; + mdacols[0x00][0][1] = mdacols[0x00][1][1] = cgapal[0]; + mdacols[0x08][0][1] = mdacols[0x08][1][1] = cgapal[0]; + mdacols[0x80][0][1] = mdacols[0x80][1][1] = cgapal[0]; + mdacols[0x88][0][1] = mdacols[0x88][1][1] = cgapal[0]; - return hercules; + return hercules; } void hercules_close(void *p) { - hercules_t *hercules = (hercules_t *)p; + hercules_t *hercules = (hercules_t *)p; - free(hercules->vram); - free(hercules); + free(hercules->vram); + free(hercules); } void hercules_speed_changed(void *p) { - hercules_t *hercules = (hercules_t *)p; + hercules_t *hercules = (hercules_t *)p; - hercules_recalctimings(hercules); + hercules_recalctimings(hercules); } -static device_config_t hercules_config[] = - { - { - .name = "display_type", - .description = "Display type", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "Green", - .value = DISPLAY_GREEN - }, - { - .description = "Amber", - .value = DISPLAY_AMBER - }, - { - .description = "White", - .value = DISPLAY_WHITE - }, - { - .description = "" - } - }, - .default_int = DISPLAY_WHITE - }, - { - .type = -1 - } - }; +static device_config_t hercules_config[] = {{.name = "display_type", + .description = "Display type", + .type = CONFIG_SELECTION, + .selection = {{.description = "Green", .value = DISPLAY_GREEN}, + {.description = "Amber", .value = DISPLAY_AMBER}, + {.description = "White", .value = DISPLAY_WHITE}, + {.description = ""}}, + .default_int = DISPLAY_WHITE}, + {.type = -1}}; -device_t hercules_device = - { - "Hercules", - 0, - hercules_init, - hercules_close, - NULL, - hercules_speed_changed, - NULL, - NULL, - hercules_config - }; +device_t hercules_device = {"Hercules", 0, hercules_init, hercules_close, NULL, hercules_speed_changed, + NULL, NULL, hercules_config}; diff --git a/src/video/vid_ht216.c b/src/video/vid_ht216.c index 55f71998..81068d70 100644 --- a/src/video/vid_ht216.c +++ b/src/video/vid_ht216.c @@ -11,49 +11,49 @@ #include "vid_unk_ramdac.h" typedef struct ht216_t { - svga_t svga; + svga_t svga; - mem_mapping_t linear_mapping; + mem_mapping_t linear_mapping; - rom_t bios_rom; + rom_t bios_rom; - uint32_t vram_mask; + uint32_t vram_mask; - int ext_reg_enable; - int clk_sel; + int ext_reg_enable; + int clk_sel; - uint8_t read_bank_reg[2], write_bank_reg[2]; - uint32_t read_bank[2], write_bank[2]; - uint8_t misc; + uint8_t read_bank_reg[2], write_bank_reg[2]; + uint32_t read_bank[2], write_bank[2]; + uint8_t misc; - uint8_t bg_latch[8]; + uint8_t bg_latch[8]; - uint8_t ht_regs[256]; + uint8_t ht_regs[256]; } ht216_t; #define HT_MISC_PAGE_SEL (1 << 5) /*Shifts CPU VRAM read address by 3 bits, for use with fat pixel colour expansion*/ #define HT_REG_C8_MOVSB (1 << 0) -#define HT_REG_C8_E256 (1 << 4) -#define HT_REG_C8_XLAM (1 << 6) +#define HT_REG_C8_E256 (1 << 4) +#define HT_REG_C8_XLAM (1 << 6) #define HT_REG_CD_FP8PCEXP (1 << 1) -#define HT_REG_CD_BMSKSL (3 << 2) -#define HT_REG_CD_RMWMDE (1 << 5) +#define HT_REG_CD_BMSKSL (3 << 2) +#define HT_REG_CD_RMWMDE (1 << 5) /*Use GDC data rotate as offset when reading VRAM data into latches*/ -#define HT_REG_CD_ASTODE (1 << 6) -#define HT_REG_CD_EXALU (1 << 7) +#define HT_REG_CD_ASTODE (1 << 6) +#define HT_REG_CD_EXALU (1 << 7) -#define HT_REG_E0_SBAE (1 << 7) +#define HT_REG_E0_SBAE (1 << 7) #define HT_REG_F9_XPSEL (1 << 0) /*Enables A[14:15] of VRAM address in chain-4 modes*/ #define HT_REG_FC_ECOLRE (1 << 2) -#define HT_REG_FE_FBRC (1 << 1) -#define HT_REG_FE_FBMC (3 << 2) +#define HT_REG_FE_FBRC (1 << 1) +#define HT_REG_FE_FBMC (3 << 2) #define HT_REG_FE_FBRSL (3 << 4) void ht216_remap(ht216_t *ht216); @@ -62,1036 +62,1125 @@ void ht216_out(uint16_t addr, uint8_t val, void *p); uint8_t ht216_in(uint16_t addr, void *p); void ht216_out(uint16_t addr, uint8_t val, void *p) { - ht216_t *ht216 = (ht216_t *)p; - svga_t *svga = &ht216->svga; - uint8_t old; + ht216_t *ht216 = (ht216_t *)p; + svga_t *svga = &ht216->svga; + uint8_t old; -// pclog("ht216 %i out %04X %02X %04X:%04X\n", svga->miscout & 1, addr, val, CS, cpu_state.pc); + // pclog("ht216 %i out %04X %02X %04X:%04X\n", svga->miscout & 1, addr, val, CS, cpu_state.pc); - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; - switch (addr) { - case 0x3c2:ht216->clk_sel = (ht216->clk_sel & ~3) | ((val & 0x0c) >> 2); - ht216->misc = val; - ht216->read_bank_reg[0] = (ht216->read_bank_reg[0] & ~0x20) | ((val & HT_MISC_PAGE_SEL) ? 0x20 : 0); - ht216->write_bank_reg[0] = (ht216->write_bank_reg[0] & ~0x20) | ((val & HT_MISC_PAGE_SEL) ? 0x20 : 0); - ht216_remap(ht216); - svga_recalctimings(&ht216->svga); - break; + switch (addr) { + case 0x3c2: + ht216->clk_sel = (ht216->clk_sel & ~3) | ((val & 0x0c) >> 2); + ht216->misc = val; + ht216->read_bank_reg[0] = (ht216->read_bank_reg[0] & ~0x20) | ((val & HT_MISC_PAGE_SEL) ? 0x20 : 0); + ht216->write_bank_reg[0] = (ht216->write_bank_reg[0] & ~0x20) | ((val & HT_MISC_PAGE_SEL) ? 0x20 : 0); + ht216_remap(ht216); + svga_recalctimings(&ht216->svga); + break; - case 0x3c5: - if (svga->seqaddr == 4) { - svga->chain4 = val & 8; - ht216_remap(ht216); - } else if (svga->seqaddr == 6) { - if (val == 0xea) - ht216->ext_reg_enable = 1; - else if (val == 0xae) - ht216->ext_reg_enable = 0; - } else if (svga->seqaddr >= 0x80 && ht216->ext_reg_enable) { - ht216->ht_regs[svga->seqaddr & 0xff] = val; -// pclog("HT[%02x]=%02x %04x(%08x):%08x\n", svga->seqaddr, val, CS,cs,cpu_state.pc); - switch (svga->seqaddr & 0xff) { - case 0x83:svga->attraddr = val & 0x1f; - svga->attrff = (val & 0x80) ? 1 : 0; - break; + case 0x3c5: + if (svga->seqaddr == 4) { + svga->chain4 = val & 8; + ht216_remap(ht216); + } else if (svga->seqaddr == 6) { + if (val == 0xea) + ht216->ext_reg_enable = 1; + else if (val == 0xae) + ht216->ext_reg_enable = 0; + } else if (svga->seqaddr >= 0x80 && ht216->ext_reg_enable) { + ht216->ht_regs[svga->seqaddr & 0xff] = val; + // pclog("HT[%02x]=%02x %04x(%08x):%08x\n", svga->seqaddr, val, + // CS,cs,cpu_state.pc); + switch (svga->seqaddr & 0xff) { + case 0x83: + svga->attraddr = val & 0x1f; + svga->attrff = (val & 0x80) ? 1 : 0; + break; - case 0x94:svga->hwcursor.addr = ((val << 6) | (3 << 14) | ((ht216->ht_regs[0xff] & 0x60) << 11)) << 2; - //pclog("cursor_addr = %05x\n", svga->hwcursor.addr); - break; - case 0x9c: - case 0x9d:svga->hwcursor.x = ht216->ht_regs[0x9d] | ((ht216->ht_regs[0x9c] & 7) << 8); - break; - case 0x9e: - case 0x9f:svga->hwcursor.y = ht216->ht_regs[0x9f] | ((ht216->ht_regs[0x9e] & 3) << 8); - break; - case 0xa0:svga->la = val; - break; - case 0xa1:svga->lb = val; - break; - case 0xa2:svga->lc = val; - break; - case 0xa3:svga->ld = val; - break; - case 0xa4:ht216->clk_sel = (val >> 2) & 0xf; - svga->miscout = (svga->miscout & ~0xc) | ((ht216->clk_sel & 3) << 2); - break; - case 0xa5:svga->hwcursor.ena = val & 0x80; - break; - case 0xe8:ht216->read_bank_reg[0] = val; - ht216->write_bank_reg[0] = val; - break; - case 0xe9:ht216->read_bank_reg[1] = val; - ht216->write_bank_reg[1] = val; - break; - case 0xf6:svga->vram_display_mask = (val & 0x40) ? ht216->vram_mask : 0x3ffff; - ht216->read_bank_reg[0] = (ht216->read_bank_reg[0] & ~0xc0) | ((val & 0xc) << 4); - ht216->write_bank_reg[0] = (ht216->write_bank_reg[0] & ~0xc0) | ((val & 0x3) << 6); - break; - case 0xf9:ht216->read_bank_reg[0] = (ht216->read_bank_reg[0] & ~0x10) | ((val & 1) ? 0x10 : 0); - ht216->write_bank_reg[0] = (ht216->write_bank_reg[0] & ~0x10) | ((val & 1) ? 0x10 : 0); - break; - case 0xfc:svga->packed_chain4 = val & 0x20; - break; - case 0xff:svga->hwcursor.addr = ((ht216->ht_regs[0x94] << 6) | (3 << 14) | ((val & 0x60) << 11)) << 2; - //pclog("cursor_addr = %05x\n", svga->hwcursor.addr); - break; - } - switch (svga->seqaddr & 0xff) { - case 0xa4: - case 0xf6: - case 0xfc:svga->fullchange = changeframecount; - svga_recalctimings(&ht216->svga); - break; - } - switch (svga->seqaddr & 0xff) { - case 0xc8: - case 0xc9: - case 0xcf: - case 0xe0: - case 0xe8: - case 0xe9: - case 0xf6: - case 0xf9:ht216_remap(ht216); - break; - } - return; - } - break; + case 0x94: + svga->hwcursor.addr = ((val << 6) | (3 << 14) | ((ht216->ht_regs[0xff] & 0x60) << 11)) << 2; + // pclog("cursor_addr = %05x\n", svga->hwcursor.addr); + break; + case 0x9c: + case 0x9d: + svga->hwcursor.x = ht216->ht_regs[0x9d] | ((ht216->ht_regs[0x9c] & 7) << 8); + break; + case 0x9e: + case 0x9f: + svga->hwcursor.y = ht216->ht_regs[0x9f] | ((ht216->ht_regs[0x9e] & 3) << 8); + break; + case 0xa0: + svga->la = val; + break; + case 0xa1: + svga->lb = val; + break; + case 0xa2: + svga->lc = val; + break; + case 0xa3: + svga->ld = val; + break; + case 0xa4: + ht216->clk_sel = (val >> 2) & 0xf; + svga->miscout = (svga->miscout & ~0xc) | ((ht216->clk_sel & 3) << 2); + break; + case 0xa5: + svga->hwcursor.ena = val & 0x80; + break; + case 0xe8: + ht216->read_bank_reg[0] = val; + ht216->write_bank_reg[0] = val; + break; + case 0xe9: + ht216->read_bank_reg[1] = val; + ht216->write_bank_reg[1] = val; + break; + case 0xf6: + svga->vram_display_mask = (val & 0x40) ? ht216->vram_mask : 0x3ffff; + ht216->read_bank_reg[0] = (ht216->read_bank_reg[0] & ~0xc0) | ((val & 0xc) << 4); + ht216->write_bank_reg[0] = (ht216->write_bank_reg[0] & ~0xc0) | ((val & 0x3) << 6); + break; + case 0xf9: + ht216->read_bank_reg[0] = (ht216->read_bank_reg[0] & ~0x10) | ((val & 1) ? 0x10 : 0); + ht216->write_bank_reg[0] = (ht216->write_bank_reg[0] & ~0x10) | ((val & 1) ? 0x10 : 0); + break; + case 0xfc: + svga->packed_chain4 = val & 0x20; + break; + case 0xff: + svga->hwcursor.addr = ((ht216->ht_regs[0x94] << 6) | (3 << 14) | ((val & 0x60) << 11)) << 2; + // pclog("cursor_addr = %05x\n", svga->hwcursor.addr); + break; + } + switch (svga->seqaddr & 0xff) { + case 0xa4: + case 0xf6: + case 0xfc: + svga->fullchange = changeframecount; + svga_recalctimings(&ht216->svga); + break; + } + switch (svga->seqaddr & 0xff) { + case 0xc8: + case 0xc9: + case 0xcf: + case 0xe0: + case 0xe8: + case 0xe9: + case 0xf6: + case 0xf9: + ht216_remap(ht216); + break; + } + return; + } + break; - case 0x3cf: - if (svga->gdcaddr == 6) { - if (val & 8) - svga->banked_mask = 0x7fff; - else - svga->banked_mask = 0xffff; - } - break; + case 0x3cf: + if (svga->gdcaddr == 6) { + if (val & 8) + svga->banked_mask = 0x7fff; + else + svga->banked_mask = 0xffff; + } + break; - case 0x3D4:svga->crtcreg = val & 0x3f; - return; - case 0x3D5: - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) - return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); + case 0x3D4: + svga->crtcreg = val & 0x3f; + return; + case 0x3D5: + if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) + return; + if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) + val = (svga->crtc[7] & ~0x10) | (val & 0x10); -// if (svga->crtcreg == 0xc) -// pclog("CRTC[C]=%02x %08x\n", val, svga->vram_display_mask); - old = svga->crtc[svga->crtcreg]; - svga->crtc[svga->crtcreg] = val; + // if (svga->crtcreg == 0xc) + // pclog("CRTC[C]=%02x %08x\n", val, svga->vram_display_mask); + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; - if (old != val) { - if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { - svga->fullchange = changeframecount; - svga_recalctimings(&ht216->svga); - } - } - break; + if (old != val) { + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { + svga->fullchange = changeframecount; + svga_recalctimings(&ht216->svga); + } + } + break; - case 0x46e8:io_removehandler(0x03c0, 0x0020, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216); - mem_mapping_disable(&ht216->svga.mapping); - mem_mapping_disable(&ht216->linear_mapping); - if (val & 8) { - io_sethandler(0x03c0, 0x0020, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216); - mem_mapping_enable(&ht216->svga.mapping); - ht216_remap(ht216); - } - break; - } - svga_out(addr, val, svga); + case 0x46e8: + io_removehandler(0x03c0, 0x0020, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216); + mem_mapping_disable(&ht216->svga.mapping); + mem_mapping_disable(&ht216->linear_mapping); + if (val & 8) { + io_sethandler(0x03c0, 0x0020, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216); + mem_mapping_enable(&ht216->svga.mapping); + ht216_remap(ht216); + } + break; + } + svga_out(addr, val, svga); } uint8_t ht216_in(uint16_t addr, void *p) { - ht216_t *ht216 = (ht216_t *)p; - svga_t *svga = &ht216->svga; + ht216_t *ht216 = (ht216_t *)p; + svga_t *svga = &ht216->svga; -// if (addr != 0x3ba && addr != 0x3da) pclog("ht216 %i in %04X\n", svga->miscout & 1, addr); + // if (addr != 0x3ba && addr != 0x3da) pclog("ht216 %i in %04X\n", svga->miscout & 1, addr); - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; - switch (addr) { - case 0x3c2: -// pclog("3C2 read\n"); - break; -// return 0x10; + switch (addr) { + case 0x3c2: + // pclog("3C2 read\n"); + break; + // return 0x10; - case 0x3c5: - if (svga->seqaddr == 6) - return ht216->ext_reg_enable; - if (svga->seqaddr >= 0x80) { - if (ht216->ext_reg_enable) { -// pclog("Read HT[%02x]=%02x\n", svga->seqaddr & 0xff, ht216->ht_regs[svga->seqaddr & 0xff]); - switch (svga->seqaddr & 0xff) { - case 0x83: - if (svga->attrff) - return svga->attraddr | 0x80; - return svga->attraddr; + case 0x3c5: + if (svga->seqaddr == 6) + return ht216->ext_reg_enable; + if (svga->seqaddr >= 0x80) { + if (ht216->ext_reg_enable) { + // pclog("Read HT[%02x]=%02x\n", svga->seqaddr & 0xff, + // ht216->ht_regs[svga->seqaddr & 0xff]); + switch (svga->seqaddr & 0xff) { + case 0x83: + if (svga->attrff) + return svga->attraddr | 0x80; + return svga->attraddr; - case 0x8e:return 0x61; /*HT216-32*/ - case 0x8f:return 0x78; + case 0x8e: + return 0x61; /*HT216-32*/ + case 0x8f: + return 0x78; - case 0xa0:return svga->la; - case 0xa1:return svga->lb; - case 0xa2:return svga->lc; - case 0xa3:return svga->ld; - } - return ht216->ht_regs[svga->seqaddr & 0xff]; - } else - return 0xff; - } - break; + case 0xa0: + return svga->la; + case 0xa1: + return svga->lb; + case 0xa2: + return svga->lc; + case 0xa3: + return svga->ld; + } + return ht216->ht_regs[svga->seqaddr & 0xff]; + } else + return 0xff; + } + break; - case 0x3D4:return svga->crtcreg; - case 0x3D5: - if (svga->crtcreg == 0x1f) - return svga->crtc[0xc] ^ 0xea; - return svga->crtc[svga->crtcreg]; - } - return svga_in(addr, svga); + case 0x3D4: + return svga->crtcreg; + case 0x3D5: + if (svga->crtcreg == 0x1f) + return svga->crtc[0xc] ^ 0xea; + return svga->crtc[svga->crtcreg]; + } + return svga_in(addr, svga); } void ht216_remap(ht216_t *ht216) { - svga_t *svga = &ht216->svga; + svga_t *svga = &ht216->svga; - mem_mapping_disable(&ht216->linear_mapping); - if (ht216->ht_regs[0xc8] & HT_REG_C8_XLAM) { - uint32_t linear_base = ((ht216->ht_regs[0xc9] & 0xf) << 20) | (ht216->ht_regs[0xcf] << 24); + mem_mapping_disable(&ht216->linear_mapping); + if (ht216->ht_regs[0xc8] & HT_REG_C8_XLAM) { + uint32_t linear_base = ((ht216->ht_regs[0xc9] & 0xf) << 20) | (ht216->ht_regs[0xcf] << 24); - pclog("Linear base %08x\n", linear_base); - mem_mapping_set_addr(&ht216->linear_mapping, linear_base, 0x100000); + pclog("Linear base %08x\n", linear_base); + mem_mapping_set_addr(&ht216->linear_mapping, linear_base, 0x100000); - /*Linear mapping enabled*/ - } else { - uint8_t read_bank_reg[2] = {ht216->read_bank_reg[0], ht216->read_bank_reg[1]}; - uint8_t write_bank_reg[2] = {ht216->write_bank_reg[0], ht216->write_bank_reg[1]}; + /*Linear mapping enabled*/ + } else { + uint8_t read_bank_reg[2] = {ht216->read_bank_reg[0], ht216->read_bank_reg[1]}; + uint8_t write_bank_reg[2] = {ht216->write_bank_reg[0], ht216->write_bank_reg[1]}; - if (!svga->chain4 || !(ht216->ht_regs[0xfc] & HT_REG_FC_ECOLRE)) { - read_bank_reg[0] &= ~0x30; - read_bank_reg[1] &= ~0x30; - write_bank_reg[0] &= ~0x30; - write_bank_reg[1] &= ~0x30; - } + if (!svga->chain4 || !(ht216->ht_regs[0xfc] & HT_REG_FC_ECOLRE)) { + read_bank_reg[0] &= ~0x30; + read_bank_reg[1] &= ~0x30; + write_bank_reg[0] &= ~0x30; + write_bank_reg[1] &= ~0x30; + } - ht216->read_bank[0] = read_bank_reg[0] << 12; - ht216->write_bank[0] = write_bank_reg[0] << 12; - if (ht216->ht_regs[0xe0] & HT_REG_E0_SBAE) { - /*Split bank*/ - ht216->read_bank[1] = read_bank_reg[1] << 12; - ht216->write_bank[1] = write_bank_reg[1] << 12; - } else { - ht216->read_bank[1] = ht216->read_bank[0] + (svga->chain4 ? 0x8000 : 0x20000); - ht216->write_bank[1] = ht216->write_bank[0] + (svga->chain4 ? 0x8000 : 0x20000); - } + ht216->read_bank[0] = read_bank_reg[0] << 12; + ht216->write_bank[0] = write_bank_reg[0] << 12; + if (ht216->ht_regs[0xe0] & HT_REG_E0_SBAE) { + /*Split bank*/ + ht216->read_bank[1] = read_bank_reg[1] << 12; + ht216->write_bank[1] = write_bank_reg[1] << 12; + } else { + ht216->read_bank[1] = ht216->read_bank[0] + (svga->chain4 ? 0x8000 : 0x20000); + ht216->write_bank[1] = ht216->write_bank[0] + (svga->chain4 ? 0x8000 : 0x20000); + } - if (!svga->chain4) { - ht216->read_bank[0] >>= 2; - ht216->read_bank[1] >>= 2; - ht216->write_bank[0] >>= 2; - ht216->write_bank[1] >>= 2; - } - } -// pclog("Remap - chain4=%i [e0]=%02x [e8]=%02x [e9]=%02x [f6]=%02x [fc]=%02x [f9]=%02x misc=%02x gdc[6]=%02x read[0]=%05X write[0]=%05X read[1]=%05X write[1]=%05X\n", svga->chain4, ht216->ht_regs[0xe0], ht216->ht_regs[0xe8], ht216->ht_regs[0xe9], ht216->ht_regs[0xf6], ht216->ht_regs[0xfc], ht216->ht_regs[0xf9], ht216->misc, svga->gdcreg[6], ht216->read_bank[0], ht216->write_bank[0], ht216->read_bank[1], ht216->write_bank[1]); + if (!svga->chain4) { + ht216->read_bank[0] >>= 2; + ht216->read_bank[1] >>= 2; + ht216->write_bank[0] >>= 2; + ht216->write_bank[1] >>= 2; + } + } + // pclog("Remap - chain4=%i [e0]=%02x [e8]=%02x [e9]=%02x [f6]=%02x [fc]=%02x [f9]=%02x misc=%02x gdc[6]=%02x + // read[0]=%05X write[0]=%05X read[1]=%05X write[1]=%05X\n", svga->chain4, ht216->ht_regs[0xe0], + // ht216->ht_regs[0xe8], ht216->ht_regs[0xe9], ht216->ht_regs[0xf6], ht216->ht_regs[0xfc], ht216->ht_regs[0xf9], + // ht216->misc, svga->gdcreg[6], ht216->read_bank[0], ht216->write_bank[0], ht216->read_bank[1], + // ht216->write_bank[1]); } void ht216_recalctimings(svga_t *svga) { - ht216_t *ht216 = (ht216_t *)svga->p; + ht216_t *ht216 = (ht216_t *)svga->p; -// pclog("clk_sel = %i\n", ht216->clk_sel); - switch (ht216->clk_sel) { - case 5:svga->clock = (cpuclock * (double)(1ull << 32)) / 65000000.0; - break; - case 6:svga->clock = (cpuclock * (double)(1ull << 32)) / 40000000.0; - break; - case 10:svga->clock = (cpuclock * (double)(1ull << 32)) / 80000000.0; - break; - } - svga->lowres = !(ht216->ht_regs[0xc8] & HT_REG_C8_E256); - svga->ma_latch |= ((ht216->ht_regs[0xf6] & 0x30) << 12); - svga->interlace = ht216->ht_regs[0xe0] & 1; + // pclog("clk_sel = %i\n", ht216->clk_sel); + switch (ht216->clk_sel) { + case 5: + svga->clock = (cpuclock * (double)(1ull << 32)) / 65000000.0; + break; + case 6: + svga->clock = (cpuclock * (double)(1ull << 32)) / 40000000.0; + break; + case 10: + svga->clock = (cpuclock * (double)(1ull << 32)) / 80000000.0; + break; + } + svga->lowres = !(ht216->ht_regs[0xc8] & HT_REG_C8_E256); + svga->ma_latch |= ((ht216->ht_regs[0xf6] & 0x30) << 12); + svga->interlace = ht216->ht_regs[0xe0] & 1; - if (svga->bpp == 8 && !svga->lowres) - svga->render = svga_render_8bpp_highres; + if (svga->bpp == 8 && !svga->lowres) + svga->render = svga_render_8bpp_highres; } static void ht216_hwcursor_draw(svga_t *svga, int displine) { -// ht216_t *ht216 = (ht216_t *)svga->p; - int x; - uint32_t dat[2]; - int offset = svga->hwcursor_latch.x + 32; + // ht216_t *ht216 = (ht216_t *)svga->p; + int x; + uint32_t dat[2]; + int offset = svga->hwcursor_latch.x + 32; - if (svga->interlace && svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += 4; + if (svga->interlace && svga->hwcursor_oddeven) + svga->hwcursor_latch.addr += 4; - dat[0] = (svga->vram[svga->hwcursor_latch.addr] << 24) | - (svga->vram[svga->hwcursor_latch.addr + 1] << 16) | - (svga->vram[svga->hwcursor_latch.addr + 2] << 8) | - svga->vram[svga->hwcursor_latch.addr + 3]; - dat[1] = (svga->vram[svga->hwcursor_latch.addr + 128] << 24) | - (svga->vram[svga->hwcursor_latch.addr + 128 + 1] << 16) | - (svga->vram[svga->hwcursor_latch.addr + 128 + 2] << 8) | - svga->vram[svga->hwcursor_latch.addr + 128 + 3]; + dat[0] = (svga->vram[svga->hwcursor_latch.addr] << 24) | (svga->vram[svga->hwcursor_latch.addr + 1] << 16) | + (svga->vram[svga->hwcursor_latch.addr + 2] << 8) | svga->vram[svga->hwcursor_latch.addr + 3]; + dat[1] = (svga->vram[svga->hwcursor_latch.addr + 128] << 24) | (svga->vram[svga->hwcursor_latch.addr + 128 + 1] << 16) | + (svga->vram[svga->hwcursor_latch.addr + 128 + 2] << 8) | svga->vram[svga->hwcursor_latch.addr + 128 + 3]; - for (x = 0; x < 32; x++) { - if (!(dat[0] & 0x80000000)) - ((uint32_t *)buffer32->line[displine])[offset + x] = 0; - if (dat[1] & 0x80000000) - ((uint32_t *)buffer32->line[displine])[offset + x] ^= 0xffffff; + for (x = 0; x < 32; x++) { + if (!(dat[0] & 0x80000000)) + ((uint32_t *)buffer32->line[displine])[offset + x] = 0; + if (dat[1] & 0x80000000) + ((uint32_t *)buffer32->line[displine])[offset + x] ^= 0xffffff; - dat[0] <<= 1; - dat[1] <<= 1; - } + dat[0] <<= 1; + dat[1] <<= 1; + } - svga->hwcursor_latch.addr += 4; - if (svga->interlace && !svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += 4; + svga->hwcursor_latch.addr += 4; + if (svga->interlace && !svga->hwcursor_oddeven) + svga->hwcursor_latch.addr += 4; } static inline uint8_t extalu(int op, uint8_t input_a, uint8_t input_b) { - uint8_t val; + uint8_t val; - switch (op) { - case 0x0:val = 0; - break; - case 0x1:val = ~(input_a | input_b); - break; - case 0x2:val = input_a & ~input_b; - break; - case 0x3:val = ~input_b; - break; - case 0x4:val = ~input_a & input_b; - break; - case 0x5:val = ~input_a; - break; - case 0x6:val = input_a ^ input_b; - break; - case 0x7:val = ~(input_a & input_b); - break; - case 0x8:val = input_a & input_b; - break; - case 0x9:val = ~(input_a ^ input_b); - break; - case 0xa:val = input_a; - break; - case 0xb:val = input_a | ~input_b; - break; - case 0xc:val = input_b; - break; - case 0xd:val = ~input_a | input_b; - break; - case 0xe:val = input_a | input_b; - break; - case 0xf: - default:val = 0xff; - break; - } + switch (op) { + case 0x0: + val = 0; + break; + case 0x1: + val = ~(input_a | input_b); + break; + case 0x2: + val = input_a & ~input_b; + break; + case 0x3: + val = ~input_b; + break; + case 0x4: + val = ~input_a & input_b; + break; + case 0x5: + val = ~input_a; + break; + case 0x6: + val = input_a ^ input_b; + break; + case 0x7: + val = ~(input_a & input_b); + break; + case 0x8: + val = input_a & input_b; + break; + case 0x9: + val = ~(input_a ^ input_b); + break; + case 0xa: + val = input_a; + break; + case 0xb: + val = input_a | ~input_b; + break; + case 0xc: + val = input_b; + break; + case 0xd: + val = ~input_a | input_b; + break; + case 0xe: + val = input_a | input_b; + break; + case 0xf: + default: + val = 0xff; + break; + } - return val; + return val; } /*Remap address for chain-4/doubleword style layout*/ static inline uint32_t dword_remap(svga_t *svga, uint32_t in_addr) { - if (svga->packed_chain4) - return in_addr; - return ((in_addr & 0xfffc) << 2) | ((in_addr & 0x30000) >> 14) | (in_addr & ~0x3ffff); + if (svga->packed_chain4) + return in_addr; + return ((in_addr & 0xfffc) << 2) | ((in_addr & 0x30000) >> 14) | (in_addr & ~0x3ffff); } static void ht216_dm_write(ht216_t *ht216, uint32_t addr, uint8_t cpu_dat, uint8_t cpu_dat_unexpanded) { - svga_t *svga = &ht216->svga; - uint8_t vala, valb, valc, vald, wm = svga->writemask; - int writemask2 = svga->writemask; - uint8_t fg_data[4] = {0, 0, 0, 0}; + svga_t *svga = &ht216->svga; + uint8_t vala, valb, valc, vald, wm = svga->writemask; + int writemask2 = svga->writemask; + uint8_t fg_data[4] = {0, 0, 0, 0}; - if (!(svga->gdcreg[6] & 1)) - svga->fullchange = 2; - if (svga->chain4) { - writemask2 = 1 << (addr & 3); - addr = dword_remap(svga, addr) & ~3; - } else if (svga->chain2_write) { - writemask2 &= ~0xa; - if (addr & 1) - writemask2 <<= 1; - addr &= ~1; - addr <<= 2; - } else { - addr <<= 2; - } - if (addr >= svga->vram_max) - return; + if (!(svga->gdcreg[6] & 1)) + svga->fullchange = 2; + if (svga->chain4) { + writemask2 = 1 << (addr & 3); + addr = dword_remap(svga, addr) & ~3; + } else if (svga->chain2_write) { + writemask2 &= ~0xa; + if (addr & 1) + writemask2 <<= 1; + addr &= ~1; + addr <<= 2; + } else { + addr <<= 2; + } + if (addr >= svga->vram_max) + return; - svga->changedvram[addr >> 12] = changeframecount; + svga->changedvram[addr >> 12] = changeframecount; - switch (ht216->ht_regs[0xfe] & HT_REG_FE_FBMC) { - case 0x00:fg_data[0] = fg_data[1] = fg_data[2] = fg_data[3] = cpu_dat; - break; - case 0x04: - if (ht216->ht_regs[0xfe] & HT_REG_FE_FBRC) { - if (addr & 4) { - fg_data[0] = (cpu_dat_unexpanded & (1 << (((addr + 4) & 7) ^ 7))) ? ht216->ht_regs[0xfa] : ht216->ht_regs[0xfb]; - fg_data[1] = (cpu_dat_unexpanded & (1 << (((addr + 5) & 7) ^ 7))) ? ht216->ht_regs[0xfa] : ht216->ht_regs[0xfb]; - fg_data[2] = (cpu_dat_unexpanded & (1 << (((addr + 6) & 7) ^ 7))) ? ht216->ht_regs[0xfa] : ht216->ht_regs[0xfb]; - fg_data[3] = (cpu_dat_unexpanded & (1 << (((addr + 7) & 7) ^ 7))) ? ht216->ht_regs[0xfa] : ht216->ht_regs[0xfb]; - } else { - fg_data[0] = (cpu_dat_unexpanded & (1 << (((addr + 0) & 7) ^ 7))) ? ht216->ht_regs[0xfa] : ht216->ht_regs[0xfb]; - fg_data[1] = (cpu_dat_unexpanded & (1 << (((addr + 1) & 7) ^ 7))) ? ht216->ht_regs[0xfa] : ht216->ht_regs[0xfb]; - fg_data[2] = (cpu_dat_unexpanded & (1 << (((addr + 2) & 7) ^ 7))) ? ht216->ht_regs[0xfa] : ht216->ht_regs[0xfb]; - fg_data[3] = (cpu_dat_unexpanded & (1 << (((addr + 3) & 7) ^ 7))) ? ht216->ht_regs[0xfa] : ht216->ht_regs[0xfb]; - } - } else { - if (addr & 4) { - fg_data[0] = (ht216->ht_regs[0xf5] & (1 << (((addr + 4) & 7) ^ 7))) ? ht216->ht_regs[0xfa] : ht216->ht_regs[0xfb]; - fg_data[1] = (ht216->ht_regs[0xf5] & (1 << (((addr + 5) & 7) ^ 7))) ? ht216->ht_regs[0xfa] : ht216->ht_regs[0xfb]; - fg_data[2] = (ht216->ht_regs[0xf5] & (1 << (((addr + 6) & 7) ^ 7))) ? ht216->ht_regs[0xfa] : ht216->ht_regs[0xfb]; - fg_data[3] = (ht216->ht_regs[0xf5] & (1 << (((addr + 7) & 7) ^ 7))) ? ht216->ht_regs[0xfa] : ht216->ht_regs[0xfb]; - } else { - fg_data[0] = (ht216->ht_regs[0xf5] & (1 << (((addr + 0) & 7) ^ 7))) ? ht216->ht_regs[0xfa] : ht216->ht_regs[0xfb]; - fg_data[1] = (ht216->ht_regs[0xf5] & (1 << (((addr + 1) & 7) ^ 7))) ? ht216->ht_regs[0xfa] : ht216->ht_regs[0xfb]; - fg_data[2] = (ht216->ht_regs[0xf5] & (1 << (((addr + 2) & 7) ^ 7))) ? ht216->ht_regs[0xfa] : ht216->ht_regs[0xfb]; - fg_data[3] = (ht216->ht_regs[0xf5] & (1 << (((addr + 3) & 7) ^ 7))) ? ht216->ht_regs[0xfa] : ht216->ht_regs[0xfb]; - } - } - break; - case 0x08:fg_data[0] = ht216->ht_regs[0xec]; - fg_data[1] = ht216->ht_regs[0xed]; - fg_data[2] = ht216->ht_regs[0xee]; - fg_data[3] = ht216->ht_regs[0xef]; - break; - case 0x0c:fg_data[0] = ht216->ht_regs[0xec]; - fg_data[1] = ht216->ht_regs[0xed]; - fg_data[2] = ht216->ht_regs[0xee]; - fg_data[3] = ht216->ht_regs[0xef]; - break; - } + switch (ht216->ht_regs[0xfe] & HT_REG_FE_FBMC) { + case 0x00: + fg_data[0] = fg_data[1] = fg_data[2] = fg_data[3] = cpu_dat; + break; + case 0x04: + if (ht216->ht_regs[0xfe] & HT_REG_FE_FBRC) { + if (addr & 4) { + fg_data[0] = (cpu_dat_unexpanded & (1 << (((addr + 4) & 7) ^ 7))) ? ht216->ht_regs[0xfa] + : ht216->ht_regs[0xfb]; + fg_data[1] = (cpu_dat_unexpanded & (1 << (((addr + 5) & 7) ^ 7))) ? ht216->ht_regs[0xfa] + : ht216->ht_regs[0xfb]; + fg_data[2] = (cpu_dat_unexpanded & (1 << (((addr + 6) & 7) ^ 7))) ? ht216->ht_regs[0xfa] + : ht216->ht_regs[0xfb]; + fg_data[3] = (cpu_dat_unexpanded & (1 << (((addr + 7) & 7) ^ 7))) ? ht216->ht_regs[0xfa] + : ht216->ht_regs[0xfb]; + } else { + fg_data[0] = (cpu_dat_unexpanded & (1 << (((addr + 0) & 7) ^ 7))) ? ht216->ht_regs[0xfa] + : ht216->ht_regs[0xfb]; + fg_data[1] = (cpu_dat_unexpanded & (1 << (((addr + 1) & 7) ^ 7))) ? ht216->ht_regs[0xfa] + : ht216->ht_regs[0xfb]; + fg_data[2] = (cpu_dat_unexpanded & (1 << (((addr + 2) & 7) ^ 7))) ? ht216->ht_regs[0xfa] + : ht216->ht_regs[0xfb]; + fg_data[3] = (cpu_dat_unexpanded & (1 << (((addr + 3) & 7) ^ 7))) ? ht216->ht_regs[0xfa] + : ht216->ht_regs[0xfb]; + } + } else { + if (addr & 4) { + fg_data[0] = (ht216->ht_regs[0xf5] & (1 << (((addr + 4) & 7) ^ 7))) ? ht216->ht_regs[0xfa] + : ht216->ht_regs[0xfb]; + fg_data[1] = (ht216->ht_regs[0xf5] & (1 << (((addr + 5) & 7) ^ 7))) ? ht216->ht_regs[0xfa] + : ht216->ht_regs[0xfb]; + fg_data[2] = (ht216->ht_regs[0xf5] & (1 << (((addr + 6) & 7) ^ 7))) ? ht216->ht_regs[0xfa] + : ht216->ht_regs[0xfb]; + fg_data[3] = (ht216->ht_regs[0xf5] & (1 << (((addr + 7) & 7) ^ 7))) ? ht216->ht_regs[0xfa] + : ht216->ht_regs[0xfb]; + } else { + fg_data[0] = (ht216->ht_regs[0xf5] & (1 << (((addr + 0) & 7) ^ 7))) ? ht216->ht_regs[0xfa] + : ht216->ht_regs[0xfb]; + fg_data[1] = (ht216->ht_regs[0xf5] & (1 << (((addr + 1) & 7) ^ 7))) ? ht216->ht_regs[0xfa] + : ht216->ht_regs[0xfb]; + fg_data[2] = (ht216->ht_regs[0xf5] & (1 << (((addr + 2) & 7) ^ 7))) ? ht216->ht_regs[0xfa] + : ht216->ht_regs[0xfb]; + fg_data[3] = (ht216->ht_regs[0xf5] & (1 << (((addr + 3) & 7) ^ 7))) ? ht216->ht_regs[0xfa] + : ht216->ht_regs[0xfb]; + } + } + break; + case 0x08: + fg_data[0] = ht216->ht_regs[0xec]; + fg_data[1] = ht216->ht_regs[0xed]; + fg_data[2] = ht216->ht_regs[0xee]; + fg_data[3] = ht216->ht_regs[0xef]; + break; + case 0x0c: + fg_data[0] = ht216->ht_regs[0xec]; + fg_data[1] = ht216->ht_regs[0xed]; + fg_data[2] = ht216->ht_regs[0xee]; + fg_data[3] = ht216->ht_regs[0xef]; + break; + } - switch (svga->writemode) { - case 1: - if (writemask2 & 1) - svga->vram[addr] = svga->la; - if (writemask2 & 2) - svga->vram[addr | 0x1] = svga->lb; - if (writemask2 & 4) - svga->vram[addr | 0x2] = svga->lc; - if (writemask2 & 8) - svga->vram[addr | 0x3] = svga->ld; - break; - case 0: - if (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && (!svga->gdcreg[1] || svga->set_reset_disabled)) { - if (writemask2 & 1) - svga->vram[addr] = fg_data[0]; - if (writemask2 & 2) - svga->vram[addr | 0x1] = fg_data[1]; - if (writemask2 & 4) - svga->vram[addr | 0x2] = fg_data[2]; - if (writemask2 & 8) - svga->vram[addr | 0x3] = fg_data[3]; - } else { - if (svga->gdcreg[1] & 1) - vala = (svga->gdcreg[0] & 1) ? 0xff : 0; - else - vala = fg_data[0]; - if (svga->gdcreg[1] & 2) - valb = (svga->gdcreg[0] & 2) ? 0xff : 0; - else - valb = fg_data[1]; - if (svga->gdcreg[1] & 4) - valc = (svga->gdcreg[0] & 4) ? 0xff : 0; - else - valc = fg_data[2]; - if (svga->gdcreg[1] & 8) - vald = (svga->gdcreg[0] & 8) ? 0xff : 0; - else - vald = fg_data[3]; + switch (svga->writemode) { + case 1: + if (writemask2 & 1) + svga->vram[addr] = svga->la; + if (writemask2 & 2) + svga->vram[addr | 0x1] = svga->lb; + if (writemask2 & 4) + svga->vram[addr | 0x2] = svga->lc; + if (writemask2 & 8) + svga->vram[addr | 0x3] = svga->ld; + break; + case 0: + if (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && (!svga->gdcreg[1] || svga->set_reset_disabled)) { + if (writemask2 & 1) + svga->vram[addr] = fg_data[0]; + if (writemask2 & 2) + svga->vram[addr | 0x1] = fg_data[1]; + if (writemask2 & 4) + svga->vram[addr | 0x2] = fg_data[2]; + if (writemask2 & 8) + svga->vram[addr | 0x3] = fg_data[3]; + } else { + if (svga->gdcreg[1] & 1) + vala = (svga->gdcreg[0] & 1) ? 0xff : 0; + else + vala = fg_data[0]; + if (svga->gdcreg[1] & 2) + valb = (svga->gdcreg[0] & 2) ? 0xff : 0; + else + valb = fg_data[1]; + if (svga->gdcreg[1] & 4) + valc = (svga->gdcreg[0] & 4) ? 0xff : 0; + else + valc = fg_data[2]; + if (svga->gdcreg[1] & 8) + vald = (svga->gdcreg[0] & 8) ? 0xff : 0; + else + vald = fg_data[3]; - switch (svga->gdcreg[3] & 0x18) { - case 0: /*Set*/ - if (writemask2 & 1) - svga->vram[addr] = (vala & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]); - if (writemask2 & 2) - svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]); - if (writemask2 & 4) - svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]); - if (writemask2 & 8) - svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]); - break; - case 8: /*AND*/ - if (writemask2 & 1) - svga->vram[addr] = (vala | ~svga->gdcreg[8]) & svga->la; - if (writemask2 & 2) - svga->vram[addr | 0x1] = (valb | ~svga->gdcreg[8]) & svga->lb; - if (writemask2 & 4) - svga->vram[addr | 0x2] = (valc | ~svga->gdcreg[8]) & svga->lc; - if (writemask2 & 8) - svga->vram[addr | 0x3] = (vald | ~svga->gdcreg[8]) & svga->ld; - break; - case 0x10: /*OR*/ - if (writemask2 & 1) - svga->vram[addr] = (vala & svga->gdcreg[8]) | svga->la; - if (writemask2 & 2) - svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | svga->lb; - if (writemask2 & 4) - svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | svga->lc; - if (writemask2 & 8) - svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | svga->ld; - break; - case 0x18: /*XOR*/ - if (writemask2 & 1) - svga->vram[addr] = (vala & svga->gdcreg[8]) ^ svga->la; - if (writemask2 & 2) - svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) ^ svga->lb; - if (writemask2 & 4) - svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) ^ svga->lc; - if (writemask2 & 8) - svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) ^ svga->ld; - break; - } -// pclog("- %02X %02X %02X %02X %08X\n",vram[addr],vram[addr|0x1],vram[addr|0x2],vram[addr|0x3],addr); - } - break; - case 2: - if (!(svga->gdcreg[3] & 0x18) && (!svga->gdcreg[1] || svga->set_reset_disabled)) { - if (writemask2 & 1) - svga->vram[addr] = (((cpu_dat & 1) ? 0xff : 0) & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]); - if (writemask2 & 2) - svga->vram[addr | 0x1] = (((cpu_dat & 2) ? 0xff : 0) & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]); - if (writemask2 & 4) - svga->vram[addr | 0x2] = (((cpu_dat & 4) ? 0xff : 0) & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]); - if (writemask2 & 8) - svga->vram[addr | 0x3] = (((cpu_dat & 8) ? 0xff : 0) & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]); - } else { - vala = ((cpu_dat & 1) ? 0xff : 0); - valb = ((cpu_dat & 2) ? 0xff : 0); - valc = ((cpu_dat & 4) ? 0xff : 0); - vald = ((cpu_dat & 8) ? 0xff : 0); - switch (svga->gdcreg[3] & 0x18) { - case 0: /*Set*/ - if (writemask2 & 1) - svga->vram[addr] = (vala & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]); - if (writemask2 & 2) - svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]); - if (writemask2 & 4) - svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]); - if (writemask2 & 8) - svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]); - break; - case 8: /*AND*/ - if (writemask2 & 1) - svga->vram[addr] = (vala | ~svga->gdcreg[8]) & svga->la; - if (writemask2 & 2) - svga->vram[addr | 0x1] = (valb | ~svga->gdcreg[8]) & svga->lb; - if (writemask2 & 4) - svga->vram[addr | 0x2] = (valc | ~svga->gdcreg[8]) & svga->lc; - if (writemask2 & 8) - svga->vram[addr | 0x3] = (vald | ~svga->gdcreg[8]) & svga->ld; - break; - case 0x10: /*OR*/ - if (writemask2 & 1) - svga->vram[addr] = (vala & svga->gdcreg[8]) | svga->la; - if (writemask2 & 2) - svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | svga->lb; - if (writemask2 & 4) - svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | svga->lc; - if (writemask2 & 8) - svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | svga->ld; - break; - case 0x18: /*XOR*/ - if (writemask2 & 1) - svga->vram[addr] = (vala & svga->gdcreg[8]) ^ svga->la; - if (writemask2 & 2) - svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) ^ svga->lb; - if (writemask2 & 4) - svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) ^ svga->lc; - if (writemask2 & 8) - svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) ^ svga->ld; - break; - } - } - break; - case 3:wm = svga->gdcreg[8]; - svga->gdcreg[8] &= cpu_dat; + switch (svga->gdcreg[3] & 0x18) { + case 0: /*Set*/ + if (writemask2 & 1) + svga->vram[addr] = (vala & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]); + if (writemask2 & 2) + svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]); + if (writemask2 & 4) + svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]); + if (writemask2 & 8) + svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]); + break; + case 8: /*AND*/ + if (writemask2 & 1) + svga->vram[addr] = (vala | ~svga->gdcreg[8]) & svga->la; + if (writemask2 & 2) + svga->vram[addr | 0x1] = (valb | ~svga->gdcreg[8]) & svga->lb; + if (writemask2 & 4) + svga->vram[addr | 0x2] = (valc | ~svga->gdcreg[8]) & svga->lc; + if (writemask2 & 8) + svga->vram[addr | 0x3] = (vald | ~svga->gdcreg[8]) & svga->ld; + break; + case 0x10: /*OR*/ + if (writemask2 & 1) + svga->vram[addr] = (vala & svga->gdcreg[8]) | svga->la; + if (writemask2 & 2) + svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | svga->lb; + if (writemask2 & 4) + svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | svga->lc; + if (writemask2 & 8) + svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | svga->ld; + break; + case 0x18: /*XOR*/ + if (writemask2 & 1) + svga->vram[addr] = (vala & svga->gdcreg[8]) ^ svga->la; + if (writemask2 & 2) + svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) ^ svga->lb; + if (writemask2 & 4) + svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) ^ svga->lc; + if (writemask2 & 8) + svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) ^ svga->ld; + break; + } + // pclog("- %02X %02X %02X %02X + // %08X\n",vram[addr],vram[addr|0x1],vram[addr|0x2],vram[addr|0x3],addr); + } + break; + case 2: + if (!(svga->gdcreg[3] & 0x18) && (!svga->gdcreg[1] || svga->set_reset_disabled)) { + if (writemask2 & 1) + svga->vram[addr] = (((cpu_dat & 1) ? 0xff : 0) & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]); + if (writemask2 & 2) + svga->vram[addr | 0x1] = + (((cpu_dat & 2) ? 0xff : 0) & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]); + if (writemask2 & 4) + svga->vram[addr | 0x2] = + (((cpu_dat & 4) ? 0xff : 0) & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]); + if (writemask2 & 8) + svga->vram[addr | 0x3] = + (((cpu_dat & 8) ? 0xff : 0) & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]); + } else { + vala = ((cpu_dat & 1) ? 0xff : 0); + valb = ((cpu_dat & 2) ? 0xff : 0); + valc = ((cpu_dat & 4) ? 0xff : 0); + vald = ((cpu_dat & 8) ? 0xff : 0); + switch (svga->gdcreg[3] & 0x18) { + case 0: /*Set*/ + if (writemask2 & 1) + svga->vram[addr] = (vala & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]); + if (writemask2 & 2) + svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]); + if (writemask2 & 4) + svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]); + if (writemask2 & 8) + svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]); + break; + case 8: /*AND*/ + if (writemask2 & 1) + svga->vram[addr] = (vala | ~svga->gdcreg[8]) & svga->la; + if (writemask2 & 2) + svga->vram[addr | 0x1] = (valb | ~svga->gdcreg[8]) & svga->lb; + if (writemask2 & 4) + svga->vram[addr | 0x2] = (valc | ~svga->gdcreg[8]) & svga->lc; + if (writemask2 & 8) + svga->vram[addr | 0x3] = (vald | ~svga->gdcreg[8]) & svga->ld; + break; + case 0x10: /*OR*/ + if (writemask2 & 1) + svga->vram[addr] = (vala & svga->gdcreg[8]) | svga->la; + if (writemask2 & 2) + svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | svga->lb; + if (writemask2 & 4) + svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | svga->lc; + if (writemask2 & 8) + svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | svga->ld; + break; + case 0x18: /*XOR*/ + if (writemask2 & 1) + svga->vram[addr] = (vala & svga->gdcreg[8]) ^ svga->la; + if (writemask2 & 2) + svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) ^ svga->lb; + if (writemask2 & 4) + svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) ^ svga->lc; + if (writemask2 & 8) + svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) ^ svga->ld; + break; + } + } + break; + case 3: + wm = svga->gdcreg[8]; + svga->gdcreg[8] &= cpu_dat; - vala = (svga->gdcreg[0] & 1) ? 0xff : 0; - valb = (svga->gdcreg[0] & 2) ? 0xff : 0; - valc = (svga->gdcreg[0] & 4) ? 0xff : 0; - vald = (svga->gdcreg[0] & 8) ? 0xff : 0; - switch (svga->gdcreg[3] & 0x18) { - case 0: /*Set*/ - if (writemask2 & 1) - svga->vram[addr] = (vala & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]); - if (writemask2 & 2) - svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]); - if (writemask2 & 4) - svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]); - if (writemask2 & 8) - svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]); - break; - case 8: /*AND*/ - if (writemask2 & 1) - svga->vram[addr] = (vala | ~svga->gdcreg[8]) & svga->la; - if (writemask2 & 2) - svga->vram[addr | 0x1] = (valb | ~svga->gdcreg[8]) & svga->lb; - if (writemask2 & 4) - svga->vram[addr | 0x2] = (valc | ~svga->gdcreg[8]) & svga->lc; - if (writemask2 & 8) - svga->vram[addr | 0x3] = (vald | ~svga->gdcreg[8]) & svga->ld; - break; - case 0x10: /*OR*/ - if (writemask2 & 1) - svga->vram[addr] = (vala & svga->gdcreg[8]) | svga->la; - if (writemask2 & 2) - svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | svga->lb; - if (writemask2 & 4) - svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | svga->lc; - if (writemask2 & 8) - svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | svga->ld; - break; - case 0x18: /*XOR*/ - if (writemask2 & 1) - svga->vram[addr] = (vala & svga->gdcreg[8]) ^ svga->la; - if (writemask2 & 2) - svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) ^ svga->lb; - if (writemask2 & 4) - svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) ^ svga->lc; - if (writemask2 & 8) - svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) ^ svga->ld; - break; - } - svga->gdcreg[8] = wm; - break; - } + vala = (svga->gdcreg[0] & 1) ? 0xff : 0; + valb = (svga->gdcreg[0] & 2) ? 0xff : 0; + valc = (svga->gdcreg[0] & 4) ? 0xff : 0; + vald = (svga->gdcreg[0] & 8) ? 0xff : 0; + switch (svga->gdcreg[3] & 0x18) { + case 0: /*Set*/ + if (writemask2 & 1) + svga->vram[addr] = (vala & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]); + if (writemask2 & 2) + svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]); + if (writemask2 & 4) + svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]); + if (writemask2 & 8) + svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]); + break; + case 8: /*AND*/ + if (writemask2 & 1) + svga->vram[addr] = (vala | ~svga->gdcreg[8]) & svga->la; + if (writemask2 & 2) + svga->vram[addr | 0x1] = (valb | ~svga->gdcreg[8]) & svga->lb; + if (writemask2 & 4) + svga->vram[addr | 0x2] = (valc | ~svga->gdcreg[8]) & svga->lc; + if (writemask2 & 8) + svga->vram[addr | 0x3] = (vald | ~svga->gdcreg[8]) & svga->ld; + break; + case 0x10: /*OR*/ + if (writemask2 & 1) + svga->vram[addr] = (vala & svga->gdcreg[8]) | svga->la; + if (writemask2 & 2) + svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | svga->lb; + if (writemask2 & 4) + svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | svga->lc; + if (writemask2 & 8) + svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | svga->ld; + break; + case 0x18: /*XOR*/ + if (writemask2 & 1) + svga->vram[addr] = (vala & svga->gdcreg[8]) ^ svga->la; + if (writemask2 & 2) + svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) ^ svga->lb; + if (writemask2 & 4) + svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) ^ svga->lc; + if (writemask2 & 8) + svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) ^ svga->ld; + break; + } + svga->gdcreg[8] = wm; + break; + } } -static void ht216_dm_extalu_write(ht216_t *ht216, uint32_t addr, uint8_t cpu_dat, uint8_t bit_mask, uint8_t cpu_dat_unexpanded, uint8_t rop_select) { - /*Input B = CD.5 - Input A = FE[3:2] - 00 = Set/Reset output mode - output = CPU-side ALU input - 01 = Solid fg/bg mode (3C4:FA/FB) - Bit mask = 3CF.F5 or CPU byte - 10 = Dithered fg (3CF:EC-EF) - 11 = RMW (dest data) (set if CD.5 = 1) - F/B ROP select = FE[5:4] - 00 = CPU byte - 01 = Bit mask (3CF:8) - 1x = (3C4:F5)*/ - svga_t *svga = &ht216->svga; - uint8_t input_a = 0, input_b = 0; - uint8_t fg, bg; - uint8_t output; - uint32_t remapped_addr = dword_remap(svga, addr); +static void ht216_dm_extalu_write(ht216_t *ht216, uint32_t addr, uint8_t cpu_dat, uint8_t bit_mask, uint8_t cpu_dat_unexpanded, + uint8_t rop_select) { + /*Input B = CD.5 + Input A = FE[3:2] + 00 = Set/Reset output mode + output = CPU-side ALU input + 01 = Solid fg/bg mode (3C4:FA/FB) + Bit mask = 3CF.F5 or CPU byte + 10 = Dithered fg (3CF:EC-EF) + 11 = RMW (dest data) (set if CD.5 = 1) + F/B ROP select = FE[5:4] + 00 = CPU byte + 01 = Bit mask (3CF:8) + 1x = (3C4:F5)*/ + svga_t *svga = &ht216->svga; + uint8_t input_a = 0, input_b = 0; + uint8_t fg, bg; + uint8_t output; + uint32_t remapped_addr = dword_remap(svga, addr); - if (ht216->ht_regs[0xcd] & HT_REG_CD_RMWMDE) /*RMW*/ - input_b = svga->vram[remapped_addr]; - else - input_b = ht216->bg_latch[addr & 7]; + if (ht216->ht_regs[0xcd] & HT_REG_CD_RMWMDE) /*RMW*/ + input_b = svga->vram[remapped_addr]; + else + input_b = ht216->bg_latch[addr & 7]; - switch (ht216->ht_regs[0xfe] & HT_REG_FE_FBMC) { - case 0x00:input_a = cpu_dat; - break; - case 0x04: - if (ht216->ht_regs[0xfe] & HT_REG_FE_FBRC) - input_a = (cpu_dat_unexpanded & (1 << ((addr & 7) ^ 7))) ? ht216->ht_regs[0xfa] : ht216->ht_regs[0xfb]; - else - input_a = (ht216->ht_regs[0xf5] & (1 << ((addr & 7) ^ 7))) ? ht216->ht_regs[0xfa] : ht216->ht_regs[0xfb]; - break; - case 0x08:input_a = ht216->ht_regs[0xec + (addr & 3)]; - break; - case 0x0c:input_a = ht216->bg_latch[addr & 7]; - break; - } + switch (ht216->ht_regs[0xfe] & HT_REG_FE_FBMC) { + case 0x00: + input_a = cpu_dat; + break; + case 0x04: + if (ht216->ht_regs[0xfe] & HT_REG_FE_FBRC) + input_a = (cpu_dat_unexpanded & (1 << ((addr & 7) ^ 7))) ? ht216->ht_regs[0xfa] : ht216->ht_regs[0xfb]; + else + input_a = (ht216->ht_regs[0xf5] & (1 << ((addr & 7) ^ 7))) ? ht216->ht_regs[0xfa] : ht216->ht_regs[0xfb]; + break; + case 0x08: + input_a = ht216->ht_regs[0xec + (addr & 3)]; + break; + case 0x0c: + input_a = ht216->bg_latch[addr & 7]; + break; + } - fg = extalu(ht216->ht_regs[0xce] >> 4, input_a, input_b); - bg = extalu(ht216->ht_regs[0xce] & 0xf, input_a, input_b); -// svga->vram[addr] - output = (fg & rop_select) | (bg & ~rop_select); - svga->vram[addr] = (svga->vram[remapped_addr] & ~bit_mask) | (output & bit_mask); -// pclog(" A=%02x B=%02x R=%02x FG=%02x BG=%02x ops=%02x val=%02x addr=%05x\n", input_a, input_b, rop_select, fg, bg, ht216->ht_regs[0xce], svga->vram[addr], addr); - svga->changedvram[remapped_addr >> 12] = changeframecount; + fg = extalu(ht216->ht_regs[0xce] >> 4, input_a, input_b); + bg = extalu(ht216->ht_regs[0xce] & 0xf, input_a, input_b); + // svga->vram[addr] + output = (fg & rop_select) | (bg & ~rop_select); + svga->vram[addr] = (svga->vram[remapped_addr] & ~bit_mask) | (output & bit_mask); + // pclog(" A=%02x B=%02x R=%02x FG=%02x BG=%02x ops=%02x val=%02x addr=%05x\n", input_a, input_b, rop_select, fg, + // bg, ht216->ht_regs[0xce], svga->vram[addr], addr); + svga->changedvram[remapped_addr >> 12] = changeframecount; } static void ht216_write_common(ht216_t *ht216, uint32_t addr, uint8_t val) { - /*Input B = CD.5 - Input A = FE[3:2] - 00 = Set/Reset output mode - output = CPU-side ALU input - 01 = Solid fg/bg mode (3C4:FA/FB) - Bit mask = 3CF.F5 or CPU byte - 10 = Dithered fg (3CF:EC-EF) - 11 = RMW (dest data) (set if CD.5 = 1) - F/B ROP select = FE[5:4] - 00 = CPU byte - 01 = Bit mask (3CF:8) - 1x = (3C4:F5) - */ - svga_t *svga = &ht216->svga; + /*Input B = CD.5 + Input A = FE[3:2] + 00 = Set/Reset output mode + output = CPU-side ALU input + 01 = Solid fg/bg mode (3C4:FA/FB) + Bit mask = 3CF.F5 or CPU byte + 10 = Dithered fg (3CF:EC-EF) + 11 = RMW (dest data) (set if CD.5 = 1) + F/B ROP select = FE[5:4] + 00 = CPU byte + 01 = Bit mask (3CF:8) + 1x = (3C4:F5) + */ + svga_t *svga = &ht216->svga; - cycles -= video_timing_write_b; - cycles_lost += video_timing_write_b; + cycles -= video_timing_write_b; + cycles_lost += video_timing_write_b; - egawrites++; + egawrites++; - addr &= 0xfffff; + addr &= 0xfffff; -// pclog("%08X %02x %08x\n", addr, svga->gdcreg[6], svga->banked_mask); + // pclog("%08X %02x %08x\n", addr, svga->gdcreg[6], svga->banked_mask); - val = svga_rotate[svga->gdcreg[3] & 7][val]; + val = svga_rotate[svga->gdcreg[3] & 7][val]; - if (ht216->ht_regs[0xcd] & HT_REG_CD_EXALU) /*Extended ALU*/ - { - uint8_t bit_mask = 0, rop_select = 0; + if (ht216->ht_regs[0xcd] & HT_REG_CD_EXALU) /*Extended ALU*/ + { + uint8_t bit_mask = 0, rop_select = 0; - switch (ht216->ht_regs[0xfe] & HT_REG_FE_FBRSL) { - case 0x00:rop_select = val; - break; - case 0x10:rop_select = svga->gdcreg[8]; - break; - case 0x20: - case 0x30:rop_select = ht216->ht_regs[0xf5]; - break; - } + switch (ht216->ht_regs[0xfe] & HT_REG_FE_FBRSL) { + case 0x00: + rop_select = val; + break; + case 0x10: + rop_select = svga->gdcreg[8]; + break; + case 0x20: + case 0x30: + rop_select = ht216->ht_regs[0xf5]; + break; + } - switch (ht216->ht_regs[0xcd] & HT_REG_CD_BMSKSL) { - case 0x00:bit_mask = svga->gdcreg[8]; - break; - case 0x04:bit_mask = val; - break; - case 0x08: - case 0x0c:bit_mask = ht216->ht_regs[0xf5]; - break; - } + switch (ht216->ht_regs[0xcd] & HT_REG_CD_BMSKSL) { + case 0x00: + bit_mask = svga->gdcreg[8]; + break; + case 0x04: + bit_mask = val; + break; + case 0x08: + case 0x0c: + bit_mask = ht216->ht_regs[0xf5]; + break; + } - if (ht216->ht_regs[0xcd] & HT_REG_CD_FP8PCEXP) /*1->8 bit expansion*/ - { - addr = (addr << 3) & 0xfffff; - ht216_dm_extalu_write(ht216, addr, (val & 0x80) ? 0xff : 0, (bit_mask & 0x80) ? 0xff : 0, val, (rop_select & 0x80) ? 0xff : 0); - ht216_dm_extalu_write(ht216, addr + 1, (val & 0x40) ? 0xff : 0, (bit_mask & 0x40) ? 0xff : 0, val, (rop_select & 0x40) ? 0xff : 0); - ht216_dm_extalu_write(ht216, addr + 2, (val & 0x20) ? 0xff : 0, (bit_mask & 0x20) ? 0xff : 0, val, (rop_select & 0x20) ? 0xff : 0); - ht216_dm_extalu_write(ht216, addr + 3, (val & 0x10) ? 0xff : 0, (bit_mask & 0x10) ? 0xff : 0, val, (rop_select & 0x10) ? 0xff : 0); - ht216_dm_extalu_write(ht216, addr + 4, (val & 0x08) ? 0xff : 0, (bit_mask & 0x08) ? 0xff : 0, val, (rop_select & 0x08) ? 0xff : 0); - ht216_dm_extalu_write(ht216, addr + 5, (val & 0x04) ? 0xff : 0, (bit_mask & 0x04) ? 0xff : 0, val, (rop_select & 0x04) ? 0xff : 0); - ht216_dm_extalu_write(ht216, addr + 6, (val & 0x02) ? 0xff : 0, (bit_mask & 0x02) ? 0xff : 0, val, (rop_select & 0x02) ? 0xff : 0); - ht216_dm_extalu_write(ht216, addr + 7, (val & 0x01) ? 0xff : 0, (bit_mask & 0x01) ? 0xff : 0, val, (rop_select & 0x01) ? 0xff : 0); - } else - ht216_dm_extalu_write(ht216, addr, val, bit_mask, val, rop_select); - } else { - if (ht216->ht_regs[0xcd] & HT_REG_CD_FP8PCEXP) /*1->8 bit expansion*/ - { - addr = (addr << 3) & 0xfffff; - ht216_dm_write(ht216, addr, (val & 0x80) ? 0xff : 0, val); - ht216_dm_write(ht216, addr + 1, (val & 0x40) ? 0xff : 0, val); - ht216_dm_write(ht216, addr + 2, (val & 0x20) ? 0xff : 0, val); - ht216_dm_write(ht216, addr + 3, (val & 0x10) ? 0xff : 0, val); - ht216_dm_write(ht216, addr + 4, (val & 0x08) ? 0xff : 0, val); - ht216_dm_write(ht216, addr + 5, (val & 0x04) ? 0xff : 0, val); - ht216_dm_write(ht216, addr + 6, (val & 0x02) ? 0xff : 0, val); - ht216_dm_write(ht216, addr + 7, (val & 0x01) ? 0xff : 0, val); - } else - ht216_dm_write(ht216, addr, val, val); - } + if (ht216->ht_regs[0xcd] & HT_REG_CD_FP8PCEXP) /*1->8 bit expansion*/ + { + addr = (addr << 3) & 0xfffff; + ht216_dm_extalu_write(ht216, addr, (val & 0x80) ? 0xff : 0, (bit_mask & 0x80) ? 0xff : 0, val, + (rop_select & 0x80) ? 0xff : 0); + ht216_dm_extalu_write(ht216, addr + 1, (val & 0x40) ? 0xff : 0, (bit_mask & 0x40) ? 0xff : 0, val, + (rop_select & 0x40) ? 0xff : 0); + ht216_dm_extalu_write(ht216, addr + 2, (val & 0x20) ? 0xff : 0, (bit_mask & 0x20) ? 0xff : 0, val, + (rop_select & 0x20) ? 0xff : 0); + ht216_dm_extalu_write(ht216, addr + 3, (val & 0x10) ? 0xff : 0, (bit_mask & 0x10) ? 0xff : 0, val, + (rop_select & 0x10) ? 0xff : 0); + ht216_dm_extalu_write(ht216, addr + 4, (val & 0x08) ? 0xff : 0, (bit_mask & 0x08) ? 0xff : 0, val, + (rop_select & 0x08) ? 0xff : 0); + ht216_dm_extalu_write(ht216, addr + 5, (val & 0x04) ? 0xff : 0, (bit_mask & 0x04) ? 0xff : 0, val, + (rop_select & 0x04) ? 0xff : 0); + ht216_dm_extalu_write(ht216, addr + 6, (val & 0x02) ? 0xff : 0, (bit_mask & 0x02) ? 0xff : 0, val, + (rop_select & 0x02) ? 0xff : 0); + ht216_dm_extalu_write(ht216, addr + 7, (val & 0x01) ? 0xff : 0, (bit_mask & 0x01) ? 0xff : 0, val, + (rop_select & 0x01) ? 0xff : 0); + } else + ht216_dm_extalu_write(ht216, addr, val, bit_mask, val, rop_select); + } else { + if (ht216->ht_regs[0xcd] & HT_REG_CD_FP8PCEXP) /*1->8 bit expansion*/ + { + addr = (addr << 3) & 0xfffff; + ht216_dm_write(ht216, addr, (val & 0x80) ? 0xff : 0, val); + ht216_dm_write(ht216, addr + 1, (val & 0x40) ? 0xff : 0, val); + ht216_dm_write(ht216, addr + 2, (val & 0x20) ? 0xff : 0, val); + ht216_dm_write(ht216, addr + 3, (val & 0x10) ? 0xff : 0, val); + ht216_dm_write(ht216, addr + 4, (val & 0x08) ? 0xff : 0, val); + ht216_dm_write(ht216, addr + 5, (val & 0x04) ? 0xff : 0, val); + ht216_dm_write(ht216, addr + 6, (val & 0x02) ? 0xff : 0, val); + ht216_dm_write(ht216, addr + 7, (val & 0x01) ? 0xff : 0, val); + } else + ht216_dm_write(ht216, addr, val, val); + } } static void ht216_write(uint32_t addr, uint8_t val, void *p) { - ht216_t *ht216 = (ht216_t *)p; - svga_t *svga = &ht216->svga; + ht216_t *ht216 = (ht216_t *)p; + svga_t *svga = &ht216->svga; -/* if (ht216->ht_regs[0xcd]) - pclog("ht216_write: [CD]=%02x [FE]=%02x %08x %02x ", ht216->ht_regs[0xcd], ht216->ht_regs[0xfe], addr, val); - pclog("ht216_write : %05X %02X ", addr, val);*/ - addr &= svga->banked_mask; - addr = (addr & 0x7fff) + ht216->write_bank[(addr >> 15) & 1]; -// pclog("phys_addr=%05x\n", addr); - if (!ht216->ht_regs[0xcd] && !ht216->ht_regs[0xfe]) - svga_write_linear(addr, val, &ht216->svga); - else { - ht216_write_common(ht216, addr, val); - } + /* if (ht216->ht_regs[0xcd]) + pclog("ht216_write: [CD]=%02x [FE]=%02x %08x %02x ", ht216->ht_regs[0xcd], ht216->ht_regs[0xfe], addr, + val); pclog("ht216_write : %05X %02X ", addr, val);*/ + addr &= svga->banked_mask; + addr = (addr & 0x7fff) + ht216->write_bank[(addr >> 15) & 1]; + // pclog("phys_addr=%05x\n", addr); + if (!ht216->ht_regs[0xcd] && !ht216->ht_regs[0xfe]) + svga_write_linear(addr, val, &ht216->svga); + else { + ht216_write_common(ht216, addr, val); + } } static void ht216_writew(uint32_t addr, uint16_t val, void *p) { - ht216_t *ht216 = (ht216_t *)p; - svga_t *svga = &ht216->svga; + ht216_t *ht216 = (ht216_t *)p; + svga_t *svga = &ht216->svga; - addr &= svga->banked_mask; - addr = (addr & 0x7fff) + ht216->write_bank[(addr >> 15) & 1]; - if (!ht216->ht_regs[0xcd] && !ht216->ht_regs[0xfe]) - svga_writew_linear(addr, val, &ht216->svga); - else { - ht216_write_common(ht216, addr, val); - ht216_write_common(ht216, addr + 1, val >> 8); - } + addr &= svga->banked_mask; + addr = (addr & 0x7fff) + ht216->write_bank[(addr >> 15) & 1]; + if (!ht216->ht_regs[0xcd] && !ht216->ht_regs[0xfe]) + svga_writew_linear(addr, val, &ht216->svga); + else { + ht216_write_common(ht216, addr, val); + ht216_write_common(ht216, addr + 1, val >> 8); + } } static void ht216_writel(uint32_t addr, uint32_t val, void *p) { - ht216_t *ht216 = (ht216_t *)p; - svga_t *svga = &ht216->svga; + ht216_t *ht216 = (ht216_t *)p; + svga_t *svga = &ht216->svga; - addr &= svga->banked_mask; - addr = (addr & 0x7fff) + ht216->write_bank[(addr >> 15) & 1]; - if (!ht216->ht_regs[0xcd] && !ht216->ht_regs[0xfe]) - svga_writel_linear(addr, val, &ht216->svga); - else { - ht216_write_common(ht216, addr, val); - ht216_write_common(ht216, addr + 1, val >> 8); - ht216_write_common(ht216, addr + 2, val >> 16); - ht216_write_common(ht216, addr + 3, val >> 24); - } + addr &= svga->banked_mask; + addr = (addr & 0x7fff) + ht216->write_bank[(addr >> 15) & 1]; + if (!ht216->ht_regs[0xcd] && !ht216->ht_regs[0xfe]) + svga_writel_linear(addr, val, &ht216->svga); + else { + ht216_write_common(ht216, addr, val); + ht216_write_common(ht216, addr + 1, val >> 8); + ht216_write_common(ht216, addr + 2, val >> 16); + ht216_write_common(ht216, addr + 3, val >> 24); + } } static void ht216_write_linear(uint32_t addr, uint8_t val, void *p) { - ht216_t *ht216 = (ht216_t *)p; - svga_t *svga = &ht216->svga; + ht216_t *ht216 = (ht216_t *)p; + svga_t *svga = &ht216->svga; - if (!svga->chain4) /*Bits 16 and 17 of linear address seem to be unused in planar modes*/ - addr = (addr & 0xffff) | ((addr & 0xc0000) >> 2); + if (!svga->chain4) /*Bits 16 and 17 of linear address seem to be unused in planar modes*/ + addr = (addr & 0xffff) | ((addr & 0xc0000) >> 2); - if (!ht216->ht_regs[0xcd] && !ht216->ht_regs[0xfe]) - svga_write_linear(addr, val, &ht216->svga); - else - ht216_write_common(ht216, addr, val); + if (!ht216->ht_regs[0xcd] && !ht216->ht_regs[0xfe]) + svga_write_linear(addr, val, &ht216->svga); + else + ht216_write_common(ht216, addr, val); } static void ht216_writew_linear(uint32_t addr, uint16_t val, void *p) { - ht216_t *ht216 = (ht216_t *)p; - svga_t *svga = &ht216->svga; + ht216_t *ht216 = (ht216_t *)p; + svga_t *svga = &ht216->svga; - if (!svga->chain4) - addr = (addr & 0xffff) | ((addr & 0xc0000) >> 2); + if (!svga->chain4) + addr = (addr & 0xffff) | ((addr & 0xc0000) >> 2); - if (!ht216->ht_regs[0xcd] && !ht216->ht_regs[0xfe]) - svga_writew_linear(addr, val, &ht216->svga); - else { - ht216_write_common(ht216, addr, val); - ht216_write_common(ht216, addr + 1, val >> 8); - } + if (!ht216->ht_regs[0xcd] && !ht216->ht_regs[0xfe]) + svga_writew_linear(addr, val, &ht216->svga); + else { + ht216_write_common(ht216, addr, val); + ht216_write_common(ht216, addr + 1, val >> 8); + } } static void ht216_writel_linear(uint32_t addr, uint32_t val, void *p) { - ht216_t *ht216 = (ht216_t *)p; - svga_t *svga = &ht216->svga; + ht216_t *ht216 = (ht216_t *)p; + svga_t *svga = &ht216->svga; - if (!svga->chain4) - addr = (addr & 0xffff) | ((addr & 0xc0000) >> 2); + if (!svga->chain4) + addr = (addr & 0xffff) | ((addr & 0xc0000) >> 2); - if (!ht216->ht_regs[0xcd] && !ht216->ht_regs[0xfe]) - svga_writel_linear(addr, val, &ht216->svga); - else { - ht216_write_common(ht216, addr, val); - ht216_write_common(ht216, addr + 1, val >> 8); - ht216_write_common(ht216, addr + 2, val >> 16); - ht216_write_common(ht216, addr + 3, val >> 24); - } + if (!ht216->ht_regs[0xcd] && !ht216->ht_regs[0xfe]) + svga_writel_linear(addr, val, &ht216->svga); + else { + ht216_write_common(ht216, addr, val); + ht216_write_common(ht216, addr + 1, val >> 8); + ht216_write_common(ht216, addr + 2, val >> 16); + ht216_write_common(ht216, addr + 3, val >> 24); + } } static uint8_t ht216_read_common(ht216_t *ht216, uint32_t addr) { - svga_t *svga = &ht216->svga; - uint8_t temp, temp2, temp3, temp4; - int readplane = svga->readplane; - uint32_t latch_addr; + svga_t *svga = &ht216->svga; + uint8_t temp, temp2, temp3, temp4; + int readplane = svga->readplane; + uint32_t latch_addr; - if (ht216->ht_regs[0xc8] & HT_REG_C8_MOVSB) - addr <<= 3; -// pclog("%08X\n", addr); + if (ht216->ht_regs[0xc8] & HT_REG_C8_MOVSB) + addr <<= 3; + // pclog("%08X\n", addr); - addr &= 0xfffff; + addr &= 0xfffff; - cycles -= video_timing_read_b; - cycles_lost += video_timing_read_b; + cycles -= video_timing_read_b; + cycles_lost += video_timing_read_b; - egareads++; + egareads++; - if (svga->chain4) { -// if (ht216->ht_regs[0xcd]) -// pclog(" addr=%08x decode_mask=%08x vram_max=%08x\n", addr, svga->decode_mask, svga->vram_max); - addr &= svga->decode_mask; - if (addr >= svga->vram_max) - return 0xff; + if (svga->chain4) { + // if (ht216->ht_regs[0xcd]) + // pclog(" addr=%08x decode_mask=%08x vram_max=%08x\n", addr, svga->decode_mask, + // svga->vram_max); + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return 0xff; - latch_addr = (addr & svga->vram_mask) & ~7; - if (ht216->ht_regs[0xcd] & HT_REG_CD_ASTODE) - latch_addr += (svga->gdcreg[3] & 7); - ht216->bg_latch[0] = svga->vram[dword_remap(svga, latch_addr)]; - ht216->bg_latch[1] = svga->vram[dword_remap(svga, latch_addr + 1)]; - ht216->bg_latch[2] = svga->vram[dword_remap(svga, latch_addr + 2)]; - ht216->bg_latch[3] = svga->vram[dword_remap(svga, latch_addr + 3)]; - ht216->bg_latch[4] = svga->vram[dword_remap(svga, latch_addr + 4)]; - ht216->bg_latch[5] = svga->vram[dword_remap(svga, latch_addr + 5)]; - ht216->bg_latch[6] = svga->vram[dword_remap(svga, latch_addr + 6)]; - ht216->bg_latch[7] = svga->vram[dword_remap(svga, latch_addr + 7)]; + latch_addr = (addr & svga->vram_mask) & ~7; + if (ht216->ht_regs[0xcd] & HT_REG_CD_ASTODE) + latch_addr += (svga->gdcreg[3] & 7); + ht216->bg_latch[0] = svga->vram[dword_remap(svga, latch_addr)]; + ht216->bg_latch[1] = svga->vram[dword_remap(svga, latch_addr + 1)]; + ht216->bg_latch[2] = svga->vram[dword_remap(svga, latch_addr + 2)]; + ht216->bg_latch[3] = svga->vram[dword_remap(svga, latch_addr + 3)]; + ht216->bg_latch[4] = svga->vram[dword_remap(svga, latch_addr + 4)]; + ht216->bg_latch[5] = svga->vram[dword_remap(svga, latch_addr + 5)]; + ht216->bg_latch[6] = svga->vram[dword_remap(svga, latch_addr + 6)]; + ht216->bg_latch[7] = svga->vram[dword_remap(svga, latch_addr + 7)]; -/*pclog(" Read %08x %02x %02x %02x %02x %02x %02x %02x %02x\n", addr, - ht216->bg_latch[0],ht216->bg_latch[1],ht216->bg_latch[2],ht216->bg_latch[3], - ht216->bg_latch[4],ht216->bg_latch[5],ht216->bg_latch[6],ht216->bg_latch[7]);*/ + /*pclog(" Read %08x %02x %02x %02x %02x %02x %02x %02x %02x\n", addr, + ht216->bg_latch[0],ht216->bg_latch[1],ht216->bg_latch[2],ht216->bg_latch[3], + ht216->bg_latch[4],ht216->bg_latch[5],ht216->bg_latch[6],ht216->bg_latch[7]);*/ - return svga->vram[dword_remap(svga, addr) & svga->vram_mask]; - } else if (svga->chain2_read) { - readplane = (readplane & 2) | (addr & 1); - addr &= ~1; - addr <<= 2; - } else - addr <<= 2; + return svga->vram[dword_remap(svga, addr) & svga->vram_mask]; + } else if (svga->chain2_read) { + readplane = (readplane & 2) | (addr & 1); + addr &= ~1; + addr <<= 2; + } else + addr <<= 2; - addr &= svga->decode_mask; + addr &= svga->decode_mask; - if (addr >= svga->vram_max) - return 0xff; + if (addr >= svga->vram_max) + return 0xff; - addr &= svga->vram_mask; + addr &= svga->vram_mask; - latch_addr = addr & ~7; - if (ht216->ht_regs[0xcd] & HT_REG_CD_ASTODE) { - int offset = addr & 7; + latch_addr = addr & ~7; + if (ht216->ht_regs[0xcd] & HT_REG_CD_ASTODE) { + int offset = addr & 7; - ht216->bg_latch[0] = svga->vram[latch_addr | offset]; - ht216->bg_latch[1] = svga->vram[latch_addr | ((offset + 1) & 7)]; - ht216->bg_latch[2] = svga->vram[latch_addr | ((offset + 2) & 7)]; - ht216->bg_latch[3] = svga->vram[latch_addr | ((offset + 3) & 7)]; - ht216->bg_latch[4] = svga->vram[latch_addr | ((offset + 4) & 7)]; - ht216->bg_latch[5] = svga->vram[latch_addr | ((offset + 5) & 7)]; - ht216->bg_latch[6] = svga->vram[latch_addr | ((offset + 6) & 7)]; - ht216->bg_latch[7] = svga->vram[latch_addr | ((offset + 7) & 7)]; - } else { - ht216->bg_latch[0] = svga->vram[latch_addr]; - ht216->bg_latch[1] = svga->vram[latch_addr | 1]; - ht216->bg_latch[2] = svga->vram[latch_addr | 2]; - ht216->bg_latch[3] = svga->vram[latch_addr | 3]; - ht216->bg_latch[4] = svga->vram[latch_addr | 4]; - ht216->bg_latch[5] = svga->vram[latch_addr | 5]; - ht216->bg_latch[6] = svga->vram[latch_addr | 6]; - ht216->bg_latch[7] = svga->vram[latch_addr | 7]; - } -/*pclog(" Read %02x %02x %02x %02x %02x %02x %02x %02x\n", - ht216->bg_latch[0],ht216->bg_latch[1],ht216->bg_latch[2],ht216->bg_latch[3], - ht216->bg_latch[4],ht216->bg_latch[5],ht216->bg_latch[6],ht216->bg_latch[7]);*/ - if (addr & 4) { - svga->la = ht216->bg_latch[4]; - svga->lb = ht216->bg_latch[5]; - svga->lc = ht216->bg_latch[6]; - svga->ld = ht216->bg_latch[7]; - } else { - svga->la = ht216->bg_latch[0]; - svga->lb = ht216->bg_latch[1]; - svga->lc = ht216->bg_latch[2]; - svga->ld = ht216->bg_latch[3]; - } - if (svga->readmode) { - temp = svga->la; - temp ^= (svga->colourcompare & 1) ? 0xff : 0; - temp &= (svga->colournocare & 1) ? 0xff : 0; - temp2 = svga->lb; - temp2 ^= (svga->colourcompare & 2) ? 0xff : 0; - temp2 &= (svga->colournocare & 2) ? 0xff : 0; - temp3 = svga->lc; - temp3 ^= (svga->colourcompare & 4) ? 0xff : 0; - temp3 &= (svga->colournocare & 4) ? 0xff : 0; - temp4 = svga->ld; - temp4 ^= (svga->colourcompare & 8) ? 0xff : 0; - temp4 &= (svga->colournocare & 8) ? 0xff : 0; - return ~(temp | temp2 | temp3 | temp4); - } -//printf("Read %02X %04X %04X\n",vram[addr|svga->readplane],addr,svga->readplane); - return svga->vram[addr | readplane]; + ht216->bg_latch[0] = svga->vram[latch_addr | offset]; + ht216->bg_latch[1] = svga->vram[latch_addr | ((offset + 1) & 7)]; + ht216->bg_latch[2] = svga->vram[latch_addr | ((offset + 2) & 7)]; + ht216->bg_latch[3] = svga->vram[latch_addr | ((offset + 3) & 7)]; + ht216->bg_latch[4] = svga->vram[latch_addr | ((offset + 4) & 7)]; + ht216->bg_latch[5] = svga->vram[latch_addr | ((offset + 5) & 7)]; + ht216->bg_latch[6] = svga->vram[latch_addr | ((offset + 6) & 7)]; + ht216->bg_latch[7] = svga->vram[latch_addr | ((offset + 7) & 7)]; + } else { + ht216->bg_latch[0] = svga->vram[latch_addr]; + ht216->bg_latch[1] = svga->vram[latch_addr | 1]; + ht216->bg_latch[2] = svga->vram[latch_addr | 2]; + ht216->bg_latch[3] = svga->vram[latch_addr | 3]; + ht216->bg_latch[4] = svga->vram[latch_addr | 4]; + ht216->bg_latch[5] = svga->vram[latch_addr | 5]; + ht216->bg_latch[6] = svga->vram[latch_addr | 6]; + ht216->bg_latch[7] = svga->vram[latch_addr | 7]; + } + /*pclog(" Read %02x %02x %02x %02x %02x %02x %02x %02x\n", + ht216->bg_latch[0],ht216->bg_latch[1],ht216->bg_latch[2],ht216->bg_latch[3], + ht216->bg_latch[4],ht216->bg_latch[5],ht216->bg_latch[6],ht216->bg_latch[7]);*/ + if (addr & 4) { + svga->la = ht216->bg_latch[4]; + svga->lb = ht216->bg_latch[5]; + svga->lc = ht216->bg_latch[6]; + svga->ld = ht216->bg_latch[7]; + } else { + svga->la = ht216->bg_latch[0]; + svga->lb = ht216->bg_latch[1]; + svga->lc = ht216->bg_latch[2]; + svga->ld = ht216->bg_latch[3]; + } + if (svga->readmode) { + temp = svga->la; + temp ^= (svga->colourcompare & 1) ? 0xff : 0; + temp &= (svga->colournocare & 1) ? 0xff : 0; + temp2 = svga->lb; + temp2 ^= (svga->colourcompare & 2) ? 0xff : 0; + temp2 &= (svga->colournocare & 2) ? 0xff : 0; + temp3 = svga->lc; + temp3 ^= (svga->colourcompare & 4) ? 0xff : 0; + temp3 &= (svga->colournocare & 4) ? 0xff : 0; + temp4 = svga->ld; + temp4 ^= (svga->colourcompare & 8) ? 0xff : 0; + temp4 &= (svga->colournocare & 8) ? 0xff : 0; + return ~(temp | temp2 | temp3 | temp4); + } + // printf("Read %02X %04X %04X\n",vram[addr|svga->readplane],addr,svga->readplane); + return svga->vram[addr | readplane]; -// return svga_read_linear(addr, &ht216->svga); + // return svga_read_linear(addr, &ht216->svga); } static uint8_t ht216_read(uint32_t addr, void *p) { - ht216_t *ht216 = (ht216_t *)p; - svga_t *svga = &ht216->svga; + ht216_t *ht216 = (ht216_t *)p; + svga_t *svga = &ht216->svga; -// if (ht216->ht_regs[0xcd]) -// pclog("ht216_read: [CD]=%02x [FC]=%02x %08x\n", ht216->ht_regs[0xcd], ht216->ht_regs[0xfc], addr); -// pclog("ht216_read : %05X ", addr); - addr &= svga->banked_mask; - addr = (addr & 0x7fff) + ht216->read_bank[(addr >> 15) & 1]; + // if (ht216->ht_regs[0xcd]) + // pclog("ht216_read: [CD]=%02x [FC]=%02x %08x\n", ht216->ht_regs[0xcd], ht216->ht_regs[0xfc], addr); + // pclog("ht216_read : %05X ", addr); + addr &= svga->banked_mask; + addr = (addr & 0x7fff) + ht216->read_bank[(addr >> 15) & 1]; - return ht216_read_common(ht216, addr); + return ht216_read_common(ht216, addr); } /*static uint16_t ht216_readw(uint32_t addr, void *p) { ht216_t *ht216 = (ht216_t *)p; svga_t *svga = &ht216->svga; - + addr &= svga->banked_mask; addr = (addr & 0x7fff) + ht216->write_bank[(addr >> 15) & 1]; return svga_readw_linear(addr, &ht216->svga); }*/ static uint8_t ht216_read_linear(uint32_t addr, void *p) { - ht216_t *ht216 = (ht216_t *)p; - svga_t *svga = &ht216->svga; + ht216_t *ht216 = (ht216_t *)p; + svga_t *svga = &ht216->svga; - if (svga->chain4) - return ht216_read_common(ht216, addr); - else - return ht216_read_common(ht216, (addr & 0xffff) | ((addr & 0xc0000) >> 2)); + if (svga->chain4) + return ht216_read_common(ht216, addr); + else + return ht216_read_common(ht216, (addr & 0xffff) | ((addr & 0xc0000) >> 2)); } void *ht216_init() { - ht216_t *ht216 = malloc(sizeof(ht216_t)); - svga_t *svga = &ht216->svga; - memset(ht216, 0, sizeof(ht216_t)); + ht216_t *ht216 = malloc(sizeof(ht216_t)); + svga_t *svga = &ht216->svga; + memset(ht216, 0, sizeof(ht216_t)); - io_sethandler(0x03c0, 0x0020, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216); - io_sethandler(0x46e8, 0x0001, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216); + io_sethandler(0x03c0, 0x0020, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216); + io_sethandler(0x46e8, 0x0001, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216); - svga_init(&ht216->svga, ht216, 1 << 20, /*1MB*/ - ht216_recalctimings, - ht216_in, ht216_out, - ht216_hwcursor_draw, - NULL); - svga->hwcursor.ysize = 32; - ht216->vram_mask = 0xfffff; - svga->decode_mask = 0xfffff; + svga_init(&ht216->svga, ht216, 1 << 20, /*1MB*/ + ht216_recalctimings, ht216_in, ht216_out, ht216_hwcursor_draw, NULL); + svga->hwcursor.ysize = 32; + ht216->vram_mask = 0xfffff; + svga->decode_mask = 0xfffff; - mem_mapping_set_handler(&ht216->svga.mapping, ht216_read, NULL/*ht216_readw*/, NULL, ht216_write, ht216_writew, ht216_writel); - mem_mapping_set_p(&ht216->svga.mapping, ht216); - mem_mapping_add(&ht216->linear_mapping, 0, 0, ht216_read_linear, NULL, NULL, ht216_write_linear, ht216_writew_linear, ht216_writel_linear, NULL, 0, &ht216->svga); + mem_mapping_set_handler(&ht216->svga.mapping, ht216_read, NULL /*ht216_readw*/, NULL, ht216_write, ht216_writew, + ht216_writel); + mem_mapping_set_p(&ht216->svga.mapping, ht216); + mem_mapping_add(&ht216->linear_mapping, 0, 0, ht216_read_linear, NULL, NULL, ht216_write_linear, ht216_writew_linear, + ht216_writel_linear, NULL, 0, &ht216->svga); - svga->bpp = 8; - svga->miscout = 1; + svga->bpp = 8; + svga->miscout = 1; - ht216->ht_regs[0xb4] = 0x08; /*32-bit DRAM bus*/ + ht216->ht_regs[0xb4] = 0x08; /*32-bit DRAM bus*/ - return ht216; + return ht216; } static void *ht216_pb410a_init() { - ht216_t *ht216 = ht216_init(); + ht216_t *ht216 = ht216_init(); - return ht216; + return ht216; } void ht216_close(void *p) { - ht216_t *ht216 = (ht216_t *)p; + ht216_t *ht216 = (ht216_t *)p; - svga_close(&ht216->svga); + svga_close(&ht216->svga); - free(ht216); + free(ht216); } void ht216_speed_changed(void *p) { - ht216_t *ht216 = (ht216_t *)p; + ht216_t *ht216 = (ht216_t *)p; - svga_recalctimings(&ht216->svga); + svga_recalctimings(&ht216->svga); } void ht216_force_redraw(void *p) { - ht216_t *ht216 = (ht216_t *)p; + ht216_t *ht216 = (ht216_t *)p; - ht216->svga.fullchange = changeframecount; + ht216->svga.fullchange = changeframecount; } void ht216_add_status_info(char *s, int max_len, void *p) { - ht216_t *ht216 = (ht216_t *)p; + ht216_t *ht216 = (ht216_t *)p; - svga_add_status_info(s, max_len, &ht216->svga); + svga_add_status_info(s, max_len, &ht216->svga); } -device_t ht216_32_pb410a_device = - { - "Headland HT216-32 (Packard Bell PB410A)", - 0, - ht216_pb410a_init, - ht216_close, - NULL, - ht216_speed_changed, - ht216_force_redraw, - ht216_add_status_info - }; +device_t ht216_32_pb410a_device = {"Headland HT216-32 (Packard Bell PB410A)", + 0, + ht216_pb410a_init, + ht216_close, + NULL, + ht216_speed_changed, + ht216_force_redraw, + ht216_add_status_info}; diff --git a/src/video/vid_icd2061.c b/src/video/vid_icd2061.c index 3cf26ff2..0bab2b9b 100644 --- a/src/video/vid_icd2061.c +++ b/src/video/vid_icd2061.c @@ -6,47 +6,47 @@ #include "vid_icd2061.h" void icd2061_write(icd2061_t *icd2061, int val) { - int q, p, m, a; - if ((val & 1) && !(icd2061->state & 1)) { - pclog("ICD2061 write %02X %i %08X %i\n", val, icd2061->unlock, icd2061->data, icd2061->pos); - if (!icd2061->status) { - if (val & 2) - icd2061->unlock++; - else { - if (icd2061->unlock >= 5) { - icd2061->status = 1; - icd2061->pos = 0; - } else - icd2061->unlock = 0; - } - } else if (val & 1) { - icd2061->data = (icd2061->data >> 1) | (((val & 2) ? 1 : 0) << 24); - icd2061->pos++; - if (icd2061->pos == 26) { - pclog("ICD2061 data - %08X\n", icd2061->data); - a = (icd2061->data >> 21) & 0x7; - if (!(a & 4)) { - q = (icd2061->data & 0x7f) - 2; - m = 1 << ((icd2061->data >> 7) & 0x7); - p = ((icd2061->data >> 10) & 0x7f) - 3; - pclog("p %i q %i m %i\n", p, q, m); - if (icd2061->ctrl & (1 << a)) - p <<= 1; - icd2061->freq[a] = ((double)p / (double)q) * 2.0 * 14318184.0 / (double)m; - pclog("ICD2061 freq %i = %f\n", a, icd2061->freq[a]); - } else if (a == 6) { - icd2061->ctrl = val; - pclog("ICD2061 ctrl = %08X\n", val); - } - icd2061->unlock = icd2061->data = 0; - icd2061->status = 0; - } - } - } - icd2061->state = val; + int q, p, m, a; + if ((val & 1) && !(icd2061->state & 1)) { + pclog("ICD2061 write %02X %i %08X %i\n", val, icd2061->unlock, icd2061->data, icd2061->pos); + if (!icd2061->status) { + if (val & 2) + icd2061->unlock++; + else { + if (icd2061->unlock >= 5) { + icd2061->status = 1; + icd2061->pos = 0; + } else + icd2061->unlock = 0; + } + } else if (val & 1) { + icd2061->data = (icd2061->data >> 1) | (((val & 2) ? 1 : 0) << 24); + icd2061->pos++; + if (icd2061->pos == 26) { + pclog("ICD2061 data - %08X\n", icd2061->data); + a = (icd2061->data >> 21) & 0x7; + if (!(a & 4)) { + q = (icd2061->data & 0x7f) - 2; + m = 1 << ((icd2061->data >> 7) & 0x7); + p = ((icd2061->data >> 10) & 0x7f) - 3; + pclog("p %i q %i m %i\n", p, q, m); + if (icd2061->ctrl & (1 << a)) + p <<= 1; + icd2061->freq[a] = ((double)p / (double)q) * 2.0 * 14318184.0 / (double)m; + pclog("ICD2061 freq %i = %f\n", a, icd2061->freq[a]); + } else if (a == 6) { + icd2061->ctrl = val; + pclog("ICD2061 ctrl = %08X\n", val); + } + icd2061->unlock = icd2061->data = 0; + icd2061->status = 0; + } + } + } + icd2061->state = val; } double icd2061_getfreq(icd2061_t *icd2061, int i) { - pclog("Return freq %f\n", icd2061->freq[i]); - return icd2061->freq[i]; + pclog("Return freq %f\n", icd2061->freq[i]); + return icd2061->freq[i]; } diff --git a/src/video/vid_ics2595.c b/src/video/vid_ics2595.c index 7ed1d046..4d193209 100644 --- a/src/video/vid_ics2595.c +++ b/src/video/vid_ics2595.c @@ -4,45 +4,46 @@ #include "ibm.h" #include "vid_ics2595.h" -enum { - ICS2595_IDLE = 0, - ICS2595_WRITE, - ICS2595_READ -}; +enum { ICS2595_IDLE = 0, ICS2595_WRITE, ICS2595_READ }; static int ics2595_div[4] = {8, 4, 2, 1}; void ics2595_write(ics2595_t *ics2595, int strobe, int dat) { -// pclog("ics2595_write : %i %i\n", strobe, dat); - if (strobe) { - if ((dat & 8) && !ics2595->oldfs3) /*Data clock*/ - { -// pclog(" - new dat %i\n", dat & 4); - switch (ics2595->state) { - case ICS2595_IDLE:ics2595->state = (dat & 4) ? ICS2595_WRITE : ICS2595_IDLE; - ics2595->pos = 0; - break; - case ICS2595_WRITE:ics2595->dat = (ics2595->dat >> 1); - if (dat & 4) - ics2595->dat |= (1 << 19); - ics2595->pos++; - if (ics2595->pos == 20) { - int d, n, l; -// pclog("ICS2595_WRITE : dat %08X\n", ics2595->dat); - l = (ics2595->dat >> 2) & 0xf; - n = ((ics2595->dat >> 7) & 255) + 257; - d = ics2595_div[(ics2595->dat >> 16) & 3]; + // pclog("ics2595_write : %i %i\n", strobe, dat); + if (strobe) { + if ((dat & 8) && !ics2595->oldfs3) /*Data clock*/ + { + // pclog(" - new dat %i\n", dat & 4); + switch (ics2595->state) { + case ICS2595_IDLE: + ics2595->state = (dat & 4) ? ICS2595_WRITE : ICS2595_IDLE; + ics2595->pos = 0; + break; + case ICS2595_WRITE: + ics2595->dat = (ics2595->dat >> 1); + if (dat & 4) + ics2595->dat |= (1 << 19); + ics2595->pos++; + if (ics2595->pos == 20) { + int d, n, l; + // pclog("ICS2595_WRITE : dat %08X\n", + // ics2595->dat); + l = (ics2595->dat >> 2) & 0xf; + n = ((ics2595->dat >> 7) & 255) + 257; + d = ics2595_div[(ics2595->dat >> 16) & 3]; - ics2595->clocks[l] = (14318181.8 * ((double)n / 46.0)) / (double)d; -// pclog("ICS2595 clock set - L %i N %i D %i freq = %f\n", l, n, d, (14318181.8 * ((double)n / 46.0)) / (double)d); - ics2595->state = ICS2595_IDLE; - } - break; - } - } + ics2595->clocks[l] = (14318181.8 * ((double)n / 46.0)) / (double)d; + // pclog("ICS2595 clock set - L %i N %i D %i freq = + // %f\n", l, n, d, (14318181.8 * ((double)n + // / 46.0)) / (double)d); + ics2595->state = ICS2595_IDLE; + } + break; + } + } - ics2595->oldfs2 = dat & 4; - ics2595->oldfs3 = dat & 8; - } - ics2595->output_clock = ics2595->clocks[dat]; + ics2595->oldfs2 = dat & 4; + ics2595->oldfs3 = dat & 8; + } + ics2595->output_clock = ics2595->clocks[dat]; } diff --git a/src/video/vid_im1024.c b/src/video/vid_im1024.c index cd11ed95..acb1f1c6 100644 --- a/src/video/vid_im1024.c +++ b/src/video/vid_im1024.c @@ -10,7 +10,7 @@ #include "vid_pgc.h" #include "vid_im1024.h" -/* This implements just enough of the Vermont Microsystems IM-1024 to +/* This implements just enough of the Vermont Microsystems IM-1024 to * support the Windows 1.03 driver. Functions are partially implemented * or hardwired to the behaviour expected by the Windows driver. * @@ -22,763 +22,753 @@ extern uint8_t fontdat12x18[256][36]; typedef struct im1024_t { - pgc_core_t pgc; - unsigned char fontx[256]; - unsigned char fonty[256]; - unsigned char font[256][128]; + pgc_core_t pgc; + unsigned char fontx[256]; + unsigned char fonty[256]; + unsigned char font[256][128]; - unsigned char *fifo; - unsigned fifo_len, fifo_wrptr, fifo_rdptr; + unsigned char *fifo; + unsigned fifo_len, fifo_wrptr, fifo_rdptr; } im1024_t; -/* As well as the usual PGC ring buffer at 0xC6000, the IM1024 appears to - * have an alternate method of passing commands. This is enabled by setting +/* As well as the usual PGC ring buffer at 0xC6000, the IM1024 appears to + * have an alternate method of passing commands. This is enabled by setting * 0xC6330 to 1, and then: - * + * * CX = count to write * SI -> bytes to write - * + * * Set pending bytes to 0 - * Read [C6331]. This gives number of bytes that can be written: + * Read [C6331]. This gives number of bytes that can be written: * 0xFF => 0, 0xFE => 1, 0xFD => 2 etc. * Write that number of bytes to C6000. * If there are more to come, go back to reading [C6331]. - * As far as I can see, at least one byte is always written; there's no + * As far as I can see, at least one byte is always written; there's no * provision to pause if the queue is full. * - * I am implementing this by holding a FIFO of unlimited depth in the + * I am implementing this by holding a FIFO of unlimited depth in the * IM1024 to receive the data. * */ static void fifo_write(im1024_t *im1024, unsigned char val) { -/* PGCLOG(("fifo_write: %02x [rd=%04x wr=%04x]\n", val, - im1024->fifo_rdptr, im1024->fifo_wrptr)); */ - if (((im1024->fifo_wrptr + 1) % im1024->fifo_len) == im1024->fifo_rdptr) { -/* FIFO is full. Double its size. */ - unsigned char *buf; + /* PGCLOG(("fifo_write: %02x [rd=%04x wr=%04x]\n", val, + im1024->fifo_rdptr, im1024->fifo_wrptr)); */ + if (((im1024->fifo_wrptr + 1) % im1024->fifo_len) == im1024->fifo_rdptr) { + /* FIFO is full. Double its size. */ + unsigned char *buf; - PGCLOG(("fifo_resize: %d to %d\n", - im1024->fifo_len, 2 * im1024->fifo_len)); + PGCLOG(("fifo_resize: %d to %d\n", im1024->fifo_len, 2 * im1024->fifo_len)); - buf = realloc(im1024->fifo, 2 * im1024->fifo_len); - if (!buf) - return; -/* Move the [0..wrptr] range to the newly-allocated area [len..len+wrptr] */ - memmove(buf + im1024->fifo_len, buf, im1024->fifo_wrptr); - im1024->fifo = buf; - im1024->fifo_wrptr += im1024->fifo_len; - im1024->fifo_len *= 2; - } -/* Append to the queue */ - im1024->fifo[im1024->fifo_wrptr] = val; - ++im1024->fifo_wrptr; + buf = realloc(im1024->fifo, 2 * im1024->fifo_len); + if (!buf) + return; + /* Move the [0..wrptr] range to the newly-allocated area [len..len+wrptr] */ + memmove(buf + im1024->fifo_len, buf, im1024->fifo_wrptr); + im1024->fifo = buf; + im1024->fifo_wrptr += im1024->fifo_len; + im1024->fifo_len *= 2; + } + /* Append to the queue */ + im1024->fifo[im1024->fifo_wrptr] = val; + ++im1024->fifo_wrptr; -/* Wrap if end of buffer reached */ - if (im1024->fifo_wrptr >= im1024->fifo_len) { - im1024->fifo_wrptr = 0; - } + /* Wrap if end of buffer reached */ + if (im1024->fifo_wrptr >= im1024->fifo_len) { + im1024->fifo_wrptr = 0; + } } static int fifo_read(im1024_t *im1024) { - uint8_t result; - - if (im1024->fifo_wrptr == im1024->fifo_rdptr) { - return -1; /* FIFO empty */ - } - result = im1024->fifo[im1024->fifo_rdptr]; - ++im1024->fifo_rdptr; - if (im1024->fifo_rdptr >= im1024->fifo_len) { - im1024->fifo_rdptr = 0; - } -/* - PGCLOG(("fifo_read: %02x\n", result)); -*/ - return result; + uint8_t result; + if (im1024->fifo_wrptr == im1024->fifo_rdptr) { + return -1; /* FIFO empty */ + } + result = im1024->fifo[im1024->fifo_rdptr]; + ++im1024->fifo_rdptr; + if (im1024->fifo_rdptr >= im1024->fifo_len) { + im1024->fifo_rdptr = 0; + } + /* + PGCLOG(("fifo_read: %02x\n", result)); + */ + return result; } /* Where a normal PGC would just read from the ring buffer at 0xC6300, the * IM-1024 can read either from this or from its internal FIFO. The internal * FIFO has priority. */ int im1024_input_byte(pgc_core_t *pgc, uint8_t *result) { - im1024_t *im1024 = (im1024_t *)pgc; + im1024_t *im1024 = (im1024_t *)pgc; - /* If input buffer empty, wait for it to fill */ - while ((im1024->fifo_wrptr == im1024->fifo_rdptr) && - (pgc->mapram[0x300] == pgc->mapram[0x301])) { - pgc->waiting_input_fifo = 1; - pgc_sleep(pgc); - } - if (pgc->mapram[0x3FF]) /* Reset triggered */ - { - pgc_reset(pgc); - return 0; - } - if (im1024->fifo_wrptr == im1024->fifo_rdptr) { - *result = pgc->mapram[pgc->mapram[0x301]]; - ++pgc->mapram[0x301]; - } else { - *result = fifo_read(im1024); - } - return 1; + /* If input buffer empty, wait for it to fill */ + while ((im1024->fifo_wrptr == im1024->fifo_rdptr) && (pgc->mapram[0x300] == pgc->mapram[0x301])) { + pgc->waiting_input_fifo = 1; + pgc_sleep(pgc); + } + if (pgc->mapram[0x3FF]) /* Reset triggered */ + { + pgc_reset(pgc); + return 0; + } + if (im1024->fifo_wrptr == im1024->fifo_rdptr) { + *result = pgc->mapram[pgc->mapram[0x301]]; + ++pgc->mapram[0x301]; + } else { + *result = fifo_read(im1024); + } + return 1; } /* Macros to disable clipping and save clip state */ -#define PUSHCLIP { \ - uint16_t vp_x1, vp_x2, vp_y1, vp_y2; \ - vp_x1 = pgc->vp_x1; \ - vp_y1 = pgc->vp_y1; \ - vp_x2 = pgc->vp_x2; \ - vp_y2 = pgc->vp_y2; \ - pgc->vp_x1 = 0; \ - pgc->vp_y1 = 0; \ - pgc->vp_x2 = pgc->maxw - 1; \ - pgc->vp_y2 = pgc->maxh - 1; \ +#define PUSHCLIP \ + { \ + uint16_t vp_x1, vp_x2, vp_y1, vp_y2; \ + vp_x1 = pgc->vp_x1; \ + vp_y1 = pgc->vp_y1; \ + vp_x2 = pgc->vp_x2; \ + vp_y2 = pgc->vp_y2; \ + pgc->vp_x1 = 0; \ + pgc->vp_y1 = 0; \ + pgc->vp_x2 = pgc->maxw - 1; \ + pgc->vp_y2 = pgc->maxh - 1; /* And to restore clip state */ -#define POPCLIP \ - pgc->vp_x1 = vp_x1; \ - pgc->vp_y1 = vp_y1; \ - pgc->vp_x2 = vp_x2; \ - pgc->vp_y2 = vp_y2; \ +#define POPCLIP \ + pgc->vp_x1 = vp_x1; \ + pgc->vp_y1 = vp_y1; \ + pgc->vp_x2 = vp_x2; \ + pgc->vp_y2 = vp_y2; \ } /* Override memory read to return FIFO space */ uint8_t im1024_read(uint32_t addr, void *p) { - im1024_t *im1024 = (im1024_t *)p; + im1024_t *im1024 = (im1024_t *)p; - if (addr == 0xC6331 && im1024->pgc.mapram[0x330] == 1) { - return 0x80; /* Hardcode that there are 128 bytes - * free */ - } - return pgc_read(addr, &im1024->pgc); + if (addr == 0xC6331 && im1024->pgc.mapram[0x330] == 1) { + return 0x80; /* Hardcode that there are 128 bytes + * free */ + } + return pgc_read(addr, &im1024->pgc); } /* Override memory write to handle writes to the FIFO */ void im1024_write(uint32_t addr, uint8_t val, void *p) { - im1024_t *im1024 = (im1024_t *)p; + im1024_t *im1024 = (im1024_t *)p; - /* If we are in 'fast' input mode, send all writes to the internal - * FIFO */ - if (addr >= 0xC6000 && addr < 0xC6100 && im1024->pgc.mapram[0x330] == 1) { - fifo_write(im1024, val); -/* - PGCLOG(("im1024_write(%02x)\n", val)); -*/ - if (im1024->pgc.waiting_input_fifo) { - im1024->pgc.waiting_input_fifo = 0; - pgc_wake(&im1024->pgc); - } - return; - } - pgc_write(addr, val, &im1024->pgc); + /* If we are in 'fast' input mode, send all writes to the internal + * FIFO */ + if (addr >= 0xC6000 && addr < 0xC6100 && im1024->pgc.mapram[0x330] == 1) { + fifo_write(im1024, val); + /* + PGCLOG(("im1024_write(%02x)\n", val)); + */ + if (im1024->pgc.waiting_input_fifo) { + im1024->pgc.waiting_input_fifo = 0; + pgc_wake(&im1024->pgc); + } + return; + } + pgc_write(addr, val, &im1024->pgc); } /* I don't know what the IMGSIZ command does, only that the Windows driver * issues it. So just parse and ignore it */ void hndl_imgsiz(pgc_core_t *pgc) { - int16_t w, h; - uint8_t a, b; -// im1024_t *im1024 = (im1024_t *)pgc; + int16_t w, h; + uint8_t a, b; + // im1024_t *im1024 = (im1024_t *)pgc; - if (!pgc_param_word(pgc, &w)) - return; - if (!pgc_param_word(pgc, &h)) - return; - if (!pgc_param_byte(pgc, &a)) - return; - if (!pgc_param_byte(pgc, &b)) - return; + if (!pgc_param_word(pgc, &w)) + return; + if (!pgc_param_word(pgc, &h)) + return; + if (!pgc_param_byte(pgc, &a)) + return; + if (!pgc_param_byte(pgc, &b)) + return; - PGCLOG(("IMGSIZ %d,%d,%d,%d\n", w, h, a, b)); + PGCLOG(("IMGSIZ %d,%d,%d,%d\n", w, h, a, b)); } /* I don't know what the IPREC command does, only that the Windows driver * issues it. So just parse and ignore it */ void hndl_iprec(pgc_core_t *pgc) { - uint8_t param; -// im1024_t *im1024 = (im1024_t *)pgc; + uint8_t param; + // im1024_t *im1024 = (im1024_t *)pgc; - if (!pgc_param_byte(pgc, ¶m)) - return; + if (!pgc_param_byte(pgc, ¶m)) + return; - PGCLOG(("IPREC %d\n", param)); + PGCLOG(("IPREC %d\n", param)); } /* I think PAN controls which part of the 1024x1024 framebuffer is displayed * in the 1024x800 visible screen. */ void hndl_pan(pgc_core_t *pgc) { - int16_t x, y; + int16_t x, y; - if (!pgc_param_word(pgc, &x)) - return; - if (!pgc_param_word(pgc, &y)) - return; + if (!pgc_param_word(pgc, &x)) + return; + if (!pgc_param_word(pgc, &y)) + return; - PGCLOG(("PAN %d,%d\n", x, y)); + PGCLOG(("PAN %d,%d\n", x, y)); - pgc->pan_x = x; - pgc->pan_y = y; + pgc->pan_x = x; + pgc->pan_y = y; } /* PLINE draws a non-filled polyline at a fixed position */ void hndl_pline(pgc_core_t *pgc) { - int16_t x[257]; - int16_t y[257]; - uint8_t count; - unsigned n; - uint16_t linemask = pgc->line_pattern; + int16_t x[257]; + int16_t y[257]; + uint8_t count; + unsigned n; + uint16_t linemask = pgc->line_pattern; - if (!pgc_param_byte(pgc, &count)) - return; + if (!pgc_param_byte(pgc, &count)) + return; - PGCLOG(("PLINE (%d) ", count)); - for (n = 0; n < count; n++) { - if (!pgc_param_word(pgc, &x[n])) - return; - if (!pgc_param_word(pgc, &y[n])) - return; - PGCLOG((" (%d,%d)\n", x[n], y[n])); - } - for (n = 1; n < count; n++) { - linemask = pgc_draw_line(pgc, x[n - 1] << 16, y[n - 1] << 16, - x[n] << 16, y[n] << 16, linemask); - } + PGCLOG(("PLINE (%d) ", count)); + for (n = 0; n < count; n++) { + if (!pgc_param_word(pgc, &x[n])) + return; + if (!pgc_param_word(pgc, &y[n])) + return; + PGCLOG((" (%d,%d)\n", x[n], y[n])); + } + for (n = 1; n < count; n++) { + linemask = pgc_draw_line(pgc, x[n - 1] << 16, y[n - 1] << 16, x[n] << 16, y[n] << 16, linemask); + } } /* Blit a single row of pixels from one location to another. To avoid * difficulties if the two overlap, read both rows into memory, process them * there, and write the result back. */ -void blkmov_row(pgc_core_t *pgc, int16_t x0, int16_t x1, int16_t x2, - int16_t sy, int16_t ty) { - int16_t x; - uint8_t src[1024]; - uint8_t dst[1024]; - - for (x = x0; x <= x1; x++) { - src[x - x0] = pgc_read_pixel(pgc, x, sy); - dst[x - x0] = pgc_read_pixel(pgc, x - x0 + x2, ty); - } - for (x = x0; x <= x1; x++) { - switch (pgc->draw_mode) { - default: - case 0:pgc_write_pixel(pgc, (x - x0 + x2), ty, src[x - x0]); - break; - case 1:pgc_write_pixel(pgc, (x - x0 + x2), ty, dst[x - x0] ^ 0xFF); - break; - case 2:pgc_write_pixel(pgc, (x - x0 + x2), ty, src[x - x0] ^ dst[x - x0]); - break; - case 3:pgc_write_pixel(pgc, (x - x0 + x2), ty, src[x - x0] & dst[x - x0]); - break; - } - } +void blkmov_row(pgc_core_t *pgc, int16_t x0, int16_t x1, int16_t x2, int16_t sy, int16_t ty) { + int16_t x; + uint8_t src[1024]; + uint8_t dst[1024]; + for (x = x0; x <= x1; x++) { + src[x - x0] = pgc_read_pixel(pgc, x, sy); + dst[x - x0] = pgc_read_pixel(pgc, x - x0 + x2, ty); + } + for (x = x0; x <= x1; x++) { + switch (pgc->draw_mode) { + default: + case 0: + pgc_write_pixel(pgc, (x - x0 + x2), ty, src[x - x0]); + break; + case 1: + pgc_write_pixel(pgc, (x - x0 + x2), ty, dst[x - x0] ^ 0xFF); + break; + case 2: + pgc_write_pixel(pgc, (x - x0 + x2), ty, src[x - x0] ^ dst[x - x0]); + break; + case 3: + pgc_write_pixel(pgc, (x - x0 + x2), ty, src[x - x0] & dst[x - x0]); + break; + } + } } /* BLKMOV blits a rectangular area from one location to another, with no * clipping. */ void hndl_blkmov(pgc_core_t *pgc) { - int16_t x0, y0; - int16_t x1, y1; - int16_t x2, y2; - int16_t y; -// im1024_t *im1024 = (im1024_t *)pgc; + int16_t x0, y0; + int16_t x1, y1; + int16_t x2, y2; + int16_t y; + // im1024_t *im1024 = (im1024_t *)pgc; - if (!pgc_param_word(pgc, &x0)) - return; - if (!pgc_param_word(pgc, &y0)) - return; - if (!pgc_param_word(pgc, &x1)) - return; - if (!pgc_param_word(pgc, &y1)) - return; - if (!pgc_param_word(pgc, &x2)) - return; - if (!pgc_param_word(pgc, &y2)) - return; + if (!pgc_param_word(pgc, &x0)) + return; + if (!pgc_param_word(pgc, &y0)) + return; + if (!pgc_param_word(pgc, &x1)) + return; + if (!pgc_param_word(pgc, &y1)) + return; + if (!pgc_param_word(pgc, &x2)) + return; + if (!pgc_param_word(pgc, &y2)) + return; - PGCLOG(("BLKMOV %d,%d,%d,%d,%d,%d\n", x0, y0, x1, y1, x2, y2)); + PGCLOG(("BLKMOV %d,%d,%d,%d,%d,%d\n", x0, y0, x1, y1, x2, y2)); - /* Disable clipping */ - PUSHCLIP + /* Disable clipping */ + PUSHCLIP - /* Either go down from the top, or up from the bottom, depending - * whether areas might overlap */ - if (y2 <= y0) { - for (y = y0; y <= y1; y++) { - blkmov_row(pgc, x0, x1, x2, y, y - y0 + y2); - } - } else { - for (y = y1; y >= y0; y--) { - blkmov_row(pgc, x0, x1, x2, y, y - y0 + y2); - } - } - /* Restore clipping */ - POPCLIP + /* Either go down from the top, or up from the bottom, depending + * whether areas might overlap */ + if (y2 <= y0) { + for (y = y0; y <= y1; y++) { + blkmov_row(pgc, x0, x1, x2, y, y - y0 + y2); + } + } else { + for (y = y1; y >= y0; y--) { + blkmov_row(pgc, x0, x1, x2, y, y - y0 + y2); + } + } + /* Restore clipping */ + POPCLIP } /* This overrides the PGC ELIPSE command to parse its parameters as words * rather than coordinates */ static void hndl_ellipse(pgc_core_t *pgc) { - int16_t x, y; + int16_t x, y; - if (!pgc_param_word(pgc, &x)) - return; - if (!pgc_param_word(pgc, &y)) - return; + if (!pgc_param_word(pgc, &x)) + return; + if (!pgc_param_word(pgc, &y)) + return; - PGCLOG(("ELLIPSE %d,%d @ %d,%d\n", x, y, - pgc->x >> 16, pgc->y >> 16)); - pgc_draw_ellipse(pgc, x << 16, y << 16); + PGCLOG(("ELLIPSE %d,%d @ %d,%d\n", x, y, pgc->x >> 16, pgc->y >> 16)); + pgc_draw_ellipse(pgc, x << 16, y << 16); } /* This overrides the PGC MOVE command to parse its parameters as words * rather than coordinates */ static void hndl_move(pgc_core_t *pgc) { - int16_t x, y; + int16_t x, y; - if (!pgc_param_word(pgc, &x)) - return; - if (!pgc_param_word(pgc, &y)) - return; + if (!pgc_param_word(pgc, &x)) + return; + if (!pgc_param_word(pgc, &y)) + return; - pgc->x = x << 16; - pgc->y = y << 16; - PGCLOG(("MOVE %d,%d\n", x, y)); + pgc->x = x << 16; + pgc->y = y << 16; + PGCLOG(("MOVE %d,%d\n", x, y)); } /* This overrides the PGC DRAW command to parse its parameters as words * rather than coordinates */ static void hndl_draw(pgc_core_t *pgc) { - int16_t x, y; + int16_t x, y; - if (!pgc_param_word(pgc, &x)) - return; - if (!pgc_param_word(pgc, &y)) - return; + if (!pgc_param_word(pgc, &x)) + return; + if (!pgc_param_word(pgc, &y)) + return; - PGCLOG(("DRAW %d,%d to %d,%d\n", - pgc->x >> 16, pgc->y >> 16, x, y)); - pgc_draw_line(pgc, pgc->x, pgc->y, x << 16, y << 16, pgc->line_pattern); - pgc->x = x << 16; - pgc->y = y << 16; + PGCLOG(("DRAW %d,%d to %d,%d\n", pgc->x >> 16, pgc->y >> 16, x, y)); + pgc_draw_line(pgc, pgc->x, pgc->y, x << 16, y << 16, pgc->line_pattern); + pgc->x = x << 16; + pgc->y = y << 16; } /* This overrides the PGC POLY command to parse its parameters as words * rather than coordinates */ static void hndl_poly(pgc_core_t *pgc) { - int32_t *x, *y; - int32_t n; - int16_t xw, yw, mask; - unsigned realcount = 0; - int parsing = 1; - int as = 256; + int32_t *x, *y; + int32_t n; + int16_t xw, yw, mask; + unsigned realcount = 0; + int parsing = 1; + int as = 256; - x = malloc(as * sizeof(int32_t)); - y = malloc(as * sizeof(int32_t)); + x = malloc(as * sizeof(int32_t)); + y = malloc(as * sizeof(int32_t)); - if (!x || !y) { - PGCLOG(("hndl_poly: malloc failed\n")); - return; - } - while (parsing) { - uint8_t count; - if (!pgc_param_byte(pgc, &count)) - return; + if (!x || !y) { + PGCLOG(("hndl_poly: malloc failed\n")); + return; + } + while (parsing) { + uint8_t count; + if (!pgc_param_byte(pgc, &count)) + return; - if (count + realcount >= as) { - int32_t *nx, *ny; + if (count + realcount >= as) { + int32_t *nx, *ny; - nx = realloc(x, 2 * as * sizeof(int32_t)); - ny = realloc(y, 2 * as * sizeof(int32_t)); - if (!x || !y) { - PGCLOG(("hndl_poly: realloc failed\n")); - break; - } - x = nx; - y = ny; - as *= 2; - } + nx = realloc(x, 2 * as * sizeof(int32_t)); + ny = realloc(y, 2 * as * sizeof(int32_t)); + if (!x || !y) { + PGCLOG(("hndl_poly: realloc failed\n")); + break; + } + x = nx; + y = ny; + as *= 2; + } - for (n = 0; n < count; n++) { - if (!pgc_param_word(pgc, &xw)) - return; - if (!pgc_param_word(pgc, &yw)) - return; + for (n = 0; n < count; n++) { + if (!pgc_param_word(pgc, &xw)) + return; + if (!pgc_param_word(pgc, &yw)) + return; - /* Skip degenerate line segments */ - if (realcount > 0 && - (xw << 16) == x[realcount - 1] && - (yw << 16) == y[realcount - 1]) { - continue; - } - x[realcount] = xw << 16; - y[realcount] = yw << 16; - ++realcount; - } -/* If we're in a command list, peek ahead to see if the next command is - * also POLY. If so, that's a continuation of this polygon! */ - parsing = 0; - if (pgc->clcur && (pgc->clcur->rdptr + 1) < pgc->clcur->wrptr && - pgc->clcur->list[pgc->clcur->rdptr] == 0x30) { - PGCLOG(("hndl_poly: POLY continues!\n")); - parsing = 1; - /* Swallow the POLY */ - ++pgc->clcur->rdptr; - } + /* Skip degenerate line segments */ + if (realcount > 0 && (xw << 16) == x[realcount - 1] && (yw << 16) == y[realcount - 1]) { + continue; + } + x[realcount] = xw << 16; + y[realcount] = yw << 16; + ++realcount; + } + /* If we're in a command list, peek ahead to see if the next command is + * also POLY. If so, that's a continuation of this polygon! */ + parsing = 0; + if (pgc->clcur && (pgc->clcur->rdptr + 1) < pgc->clcur->wrptr && pgc->clcur->list[pgc->clcur->rdptr] == 0x30) { + PGCLOG(("hndl_poly: POLY continues!\n")); + parsing = 1; + /* Swallow the POLY */ + ++pgc->clcur->rdptr; + } + } - } - - PGCLOG(("POLY (%d) fill_mode=%d\n", realcount, pgc->fill_mode)); - for (n = 0; n < realcount; n++) { - PGCLOG((" (%d,%d)\n", x[n] >> 16, y[n] >> 16)); - } - if (pgc->fill_mode) { - pgc_fill_polygon(pgc, realcount, x, y); - } - /* Now draw borders */ - mask = pgc->line_pattern; - for (n = 1; n < realcount; n++) { - mask = pgc_draw_line(pgc, x[n - 1], y[n - 1], x[n], y[n], mask); - } - pgc_draw_line(pgc, x[realcount - 1], y[realcount - 1], x[0], y[0], mask); - free(y); - free(x); + PGCLOG(("POLY (%d) fill_mode=%d\n", realcount, pgc->fill_mode)); + for (n = 0; n < realcount; n++) { + PGCLOG((" (%d,%d)\n", x[n] >> 16, y[n] >> 16)); + } + if (pgc->fill_mode) { + pgc_fill_polygon(pgc, realcount, x, y); + } + /* Now draw borders */ + mask = pgc->line_pattern; + for (n = 1; n < realcount; n++) { + mask = pgc_draw_line(pgc, x[n - 1], y[n - 1], x[n], y[n], mask); + } + pgc_draw_line(pgc, x[realcount - 1], y[realcount - 1], x[0], y[0], mask); + free(y); + free(x); } static int parse_poly(pgc_core_t *pgc, pgc_commandlist_t *cl, int c) { - uint8_t count; + uint8_t count; - PGCLOG(("parse_poly\n")); - if (!pgc_param_byte(pgc, &count)) - return 0; + PGCLOG(("parse_poly\n")); + if (!pgc_param_byte(pgc, &count)) + return 0; - PGCLOG(("parse_poly: count=%02x\n", count)); - if (!pgc_commandlist_append(cl, count)) { - pgc_error(pgc, PGC_ERROR_OVERFLOW); - return 0; - } - PGCLOG(("parse_poly: parse %d words\n", 2 * count)); - return pgc_parse_words(pgc, cl, count * 2); + PGCLOG(("parse_poly: count=%02x\n", count)); + if (!pgc_commandlist_append(cl, count)) { + pgc_error(pgc, PGC_ERROR_OVERFLOW); + return 0; + } + PGCLOG(("parse_poly: parse %d words\n", 2 * count)); + return pgc_parse_words(pgc, cl, count * 2); } /* This overrides the PGC RECT command to parse its parameters as words * rather than coordinates */ static void hndl_rect(pgc_core_t *pgc) { - int16_t x0, y0, x1, y1, p, q; + int16_t x0, y0, x1, y1, p, q; - x0 = pgc->x >> 16; - y0 = pgc->y >> 16; + x0 = pgc->x >> 16; + y0 = pgc->y >> 16; - if (!pgc_param_word(pgc, &x1)) - return; - if (!pgc_param_word(pgc, &y1)) - return; + if (!pgc_param_word(pgc, &x1)) + return; + if (!pgc_param_word(pgc, &y1)) + return; - /* Convert to raster coords */ - pgc_sto_raster(pgc, &x0, &y0); - pgc_sto_raster(pgc, &x1, &y1); + /* Convert to raster coords */ + pgc_sto_raster(pgc, &x0, &y0); + pgc_sto_raster(pgc, &x1, &y1); - if (x0 > x1) { - p = x0; - x0 = x1; - x1 = p; - } - if (y0 > y1) { - q = y0; - y0 = y1; - y1 = q; - } + if (x0 > x1) { + p = x0; + x0 = x1; + x1 = p; + } + if (y0 > y1) { + q = y0; + y0 = y1; + y1 = q; + } - PGCLOG(("RECT (%d,%d) -> (%d,%d)\n", x0, y0, x1, y1)); + PGCLOG(("RECT (%d,%d) -> (%d,%d)\n", x0, y0, x1, y1)); - if (pgc->fill_mode) { - for (p = y0; p <= y1; p++) { - pgc_fill_line_r(pgc, x0, x1, p); - } - } else /* Outline: 4 lines */ - { - p = pgc->line_pattern; - p = pgc_draw_line_r(pgc, x0, y0, x1, y0, p); - p = pgc_draw_line_r(pgc, x1, y0, x1, y1, p); - p = pgc_draw_line_r(pgc, x1, y1, x0, y1, p); - p = pgc_draw_line_r(pgc, x0, y1, x0, y0, p); - } + if (pgc->fill_mode) { + for (p = y0; p <= y1; p++) { + pgc_fill_line_r(pgc, x0, x1, p); + } + } else /* Outline: 4 lines */ + { + p = pgc->line_pattern; + p = pgc_draw_line_r(pgc, x0, y0, x1, y0, p); + p = pgc_draw_line_r(pgc, x1, y0, x1, y1, p); + p = pgc_draw_line_r(pgc, x1, y1, x0, y1, p); + p = pgc_draw_line_r(pgc, x0, y1, x0, y0, p); + } } /* TODO: Text drawing should probably be implemented in vid_pgc.c rather * than vid_im1024.c */ static void hndl_tdefin(pgc_core_t *pgc) { - unsigned char ch, bt; - unsigned char rows, cols; - unsigned len, n; -// unsigned x = 0; - im1024_t *im1024 = (im1024_t *)pgc; + unsigned char ch, bt; + unsigned char rows, cols; + unsigned len, n; + // unsigned x = 0; + im1024_t *im1024 = (im1024_t *)pgc; - if (!pgc_param_byte(pgc, &ch)) - return; - if (!pgc_param_byte(pgc, &cols)) - return; - if (!pgc_param_byte(pgc, &rows)) - return; + if (!pgc_param_byte(pgc, &ch)) + return; + if (!pgc_param_byte(pgc, &cols)) + return; + if (!pgc_param_byte(pgc, &rows)) + return; - PGCLOG(("TDEFIN (%d,%d,%d) 0x%02x 0x%02x\n", ch, rows, cols, - pgc->mapram[0x300], pgc->mapram[0x301])); + PGCLOG(("TDEFIN (%d,%d,%d) 0x%02x 0x%02x\n", ch, rows, cols, pgc->mapram[0x300], pgc->mapram[0x301])); - len = ((cols + 7) / 8) * rows; - for (n = 0; n < len; n++) { -// char buf[10]; -// unsigned char mask; + len = ((cols + 7) / 8) * rows; + for (n = 0; n < len; n++) { + // char buf[10]; + // unsigned char mask; - if (!pgc_param_byte(pgc, &bt)) - return; + if (!pgc_param_byte(pgc, &bt)) + return; -// buf[0] = 0; -// for (mask = 0x80; mask != 0; mask >>= 1) -// { -// if (bt & mask) strcat(buf, "#"); -// else strcat(buf, "-"); -// ++x; -// if (x == cols) { strcat(buf, "\n"); x = 0; } -// } -// PGCLOG((buf)); + // buf[0] = 0; + // for (mask = 0x80; mask != 0; mask >>= 1) + // { + // if (bt & mask) strcat(buf, "#"); + // else strcat(buf, "-"); + // ++x; + // if (x == cols) { strcat(buf, "\n"); x = 0; } + // } + // PGCLOG((buf)); - if (n < sizeof(im1024->font[ch])) - im1024->font[ch][n] = bt; - } - im1024->fontx[ch] = cols; - im1024->fonty[ch] = rows; + if (n < sizeof(im1024->font[ch])) + im1024->font[ch][n] = bt; + } + im1024->fontx[ch] = cols; + im1024->fonty[ch] = rows; } static void hndl_tsize(pgc_core_t *pgc) { - int16_t size; + int16_t size; - if (!pgc_param_word(pgc, &size)) - return; - PGCLOG(("TSIZE(%d)\n", size)); + if (!pgc_param_word(pgc, &size)) + return; + PGCLOG(("TSIZE(%d)\n", size)); - pgc->tsize = size << 16; + pgc->tsize = size << 16; } static void hndl_twrite(pgc_core_t *pgc) { - unsigned char count; - unsigned char mask; - unsigned char *row; - int x, y, wb, n; - im1024_t *im1024 = (im1024_t *)pgc; - int16_t x0 = pgc->x >> 16; - int16_t y0 = pgc->y >> 16; - unsigned char buf[256]; -/* unsigned char rbuf[256];*/ + unsigned char count; + unsigned char mask; + unsigned char *row; + int x, y, wb, n; + im1024_t *im1024 = (im1024_t *)pgc; + int16_t x0 = pgc->x >> 16; + int16_t y0 = pgc->y >> 16; + unsigned char buf[256]; + /* unsigned char rbuf[256];*/ - if (!pgc_param_byte(pgc, &count)) - return; + if (!pgc_param_byte(pgc, &count)) + return; - for (n = 0; n < count; n++) { - if (!pgc_param_byte(pgc, &buf[n])) - return; - } - buf[count] = 0; -/* for (n = 0; n <= count; n++) - { - if (isprint(buf[n]) || 0 == buf[n]) - { - rbuf[n] = buf[n]; - } - else rbuf[n] = '?'; - }*/ - pgc_sto_raster(pgc, &x0, &y0); - PGCLOG(("TWRITE (%d,%-*.*s) x0=%d y0=%d\n", count, count, count, rbuf, x0, y0)); + for (n = 0; n < count; n++) { + if (!pgc_param_byte(pgc, &buf[n])) + return; + } + buf[count] = 0; + /* for (n = 0; n <= count; n++) + { + if (isprint(buf[n]) || 0 == buf[n]) + { + rbuf[n] = buf[n]; + } + else rbuf[n] = '?'; + }*/ + pgc_sto_raster(pgc, &x0, &y0); + PGCLOG(("TWRITE (%d,%-*.*s) x0=%d y0=%d\n", count, count, count, rbuf, x0, y0)); - for (n = 0; n < count; n++) { - wb = (im1024->fontx[buf[n]] + 7) / 8; - PGCLOG(("ch=0x%02x w=%d h=%d wb=%d\n", - buf[n], im1024->fontx[buf[n]], - im1024->fonty[buf[n]], wb)); - for (y = 0; y < im1024->fonty[buf[n]]; y++) { - mask = 0x80; - row = &im1024->font[buf[n]][y * wb]; - for (x = 0; x < im1024->fontx[buf[n]]; x++) { -/* rbuf[x] = (row[0] & mask) ? '#' : '-';*/ - if (row[0] & mask) - pgc_plot(pgc, x + x0, y0 - y); - mask = mask >> 1; - if (mask == 0) { - mask = 0x80; - ++row; - } - } -/* rbuf[x++] = '\n'; - rbuf[x++] = 0;*/ -// PGCLOG((rbuf); - } - x0 += im1024->fontx[buf[n]]; - } + for (n = 0; n < count; n++) { + wb = (im1024->fontx[buf[n]] + 7) / 8; + PGCLOG(("ch=0x%02x w=%d h=%d wb=%d\n", buf[n], im1024->fontx[buf[n]], im1024->fonty[buf[n]], wb)); + for (y = 0; y < im1024->fonty[buf[n]]; y++) { + mask = 0x80; + row = &im1024->font[buf[n]][y * wb]; + for (x = 0; x < im1024->fontx[buf[n]]; x++) { + /* rbuf[x] = (row[0] & mask) ? '#' : '-';*/ + if (row[0] & mask) + pgc_plot(pgc, x + x0, y0 - y); + mask = mask >> 1; + if (mask == 0) { + mask = 0x80; + ++row; + } + } + /* rbuf[x++] = '\n'; + rbuf[x++] = 0;*/ + // PGCLOG((rbuf); + } + x0 += im1024->fontx[buf[n]]; + } } static void hndl_txt88(pgc_core_t *pgc) { - unsigned char count; - unsigned char mask; - unsigned char *row; - int x, y, /*wb, */n; - int16_t x0 = pgc->x >> 16; - int16_t y0 = pgc->y >> 16; - unsigned char buf[256]; -/* unsigned char rbuf[256];*/ + unsigned char count; + unsigned char mask; + unsigned char *row; + int x, y, /*wb, */ n; + int16_t x0 = pgc->x >> 16; + int16_t y0 = pgc->y >> 16; + unsigned char buf[256]; + /* unsigned char rbuf[256];*/ - if (!pgc_param_byte(pgc, &count)) - return; + if (!pgc_param_byte(pgc, &count)) + return; - for (n = 0; n < count; n++) { - if (!pgc_param_byte(pgc, &buf[n])) - return; - } - buf[count] = 0; -/* for (n = 0; n <= count; n++) - { - if (isprint(buf[n]) || 0 == buf[n]) - { - rbuf[n] = buf[n]; - } - else rbuf[n] = '?'; - }*/ - pgc_sto_raster(pgc, &x0, &y0); - PGCLOG(("TXT88 (%d,%-*.*s) x0=%d y0=%d\n", count, count, count, rbuf, x0, y0)); + for (n = 0; n < count; n++) { + if (!pgc_param_byte(pgc, &buf[n])) + return; + } + buf[count] = 0; + /* for (n = 0; n <= count; n++) + { + if (isprint(buf[n]) || 0 == buf[n]) + { + rbuf[n] = buf[n]; + } + else rbuf[n] = '?'; + }*/ + pgc_sto_raster(pgc, &x0, &y0); + PGCLOG(("TXT88 (%d,%-*.*s) x0=%d y0=%d\n", count, count, count, rbuf, x0, y0)); - for (n = 0; n < count; n++) { -/* wb = 2;*/ - PGCLOG(("ch=0x%02x w=%d h=%d wb=%d\n", buf[n], 12, 18, wb)); - for (y = 0; y < 18; y++) { - mask = 0x80; - row = &fontdat12x18[buf[n]][y * 2]; - for (x = 0; x < 12; x++) { -/* rbuf[x] = (row[0] & mask) ? '#' : '-';*/ - if (row[0] & mask) - pgc_plot(pgc, x + x0, y0 - y); - mask = mask >> 1; - if (mask == 0) { - mask = 0x80; - ++row; - } - } -/* rbuf[x++] = '\n'; - rbuf[x++] = 0;*/ -// PGCLOG((rbuf); - } - x0 += 12; - } + for (n = 0; n < count; n++) { + /* wb = 2;*/ + PGCLOG(("ch=0x%02x w=%d h=%d wb=%d\n", buf[n], 12, 18, wb)); + for (y = 0; y < 18; y++) { + mask = 0x80; + row = &fontdat12x18[buf[n]][y * 2]; + for (x = 0; x < 12; x++) { + /* rbuf[x] = (row[0] & mask) ? '#' : '-';*/ + if (row[0] & mask) + pgc_plot(pgc, x + x0, y0 - y); + mask = mask >> 1; + if (mask == 0) { + mask = 0x80; + ++row; + } + } + /* rbuf[x++] = '\n'; + rbuf[x++] = 0;*/ + // PGCLOG((rbuf); + } + x0 += 12; + } } static void hndl_imagew(pgc_core_t *pgc) { - int16_t row1, col1, col2; - uint8_t v1, v2; - int16_t vp_x1, vp_y1, vp_x2, vp_y2; + int16_t row1, col1, col2; + uint8_t v1, v2; + int16_t vp_x1, vp_y1, vp_x2, vp_y2; - if (!pgc_param_word(pgc, &row1)) - return; - if (!pgc_param_word(pgc, &col1)) - return; - if (!pgc_param_word(pgc, &col2)) - return; + if (!pgc_param_word(pgc, &row1)) + return; + if (!pgc_param_word(pgc, &col1)) + return; + if (!pgc_param_word(pgc, &col2)) + return; - /* IMAGEW already uses raster coordinates so there is no need to - * convert it */ - PGCLOG(("IMAGEW (row=%d,col1=%d,col2=%d)\n", row1, col1, col2)); + /* IMAGEW already uses raster coordinates so there is no need to + * convert it */ + PGCLOG(("IMAGEW (row=%d,col1=%d,col2=%d)\n", row1, col1, col2)); - vp_x1 = pgc->vp_x1; - vp_y1 = pgc->vp_y1; - vp_x2 = pgc->vp_x2; - vp_y2 = pgc->vp_y2; - /* Disable clipping */ - pgc->vp_x1 = 0; - pgc->vp_y1 = 0; - pgc->vp_x2 = pgc->maxw - 1; - pgc->vp_y2 = pgc->maxh - 1; + vp_x1 = pgc->vp_x1; + vp_y1 = pgc->vp_y1; + vp_x2 = pgc->vp_x2; + vp_y2 = pgc->vp_y2; + /* Disable clipping */ + pgc->vp_x1 = 0; + pgc->vp_y1 = 0; + pgc->vp_x2 = pgc->maxw - 1; + pgc->vp_y2 = pgc->maxh - 1; - /* In ASCII mode, what is written is a stream of bytes */ - if (pgc->ascii_mode) { - while (col1 <= col2) { - if (!pgc_param_byte(pgc, &v1)) - return; - pgc_write_pixel(pgc, col1, row1, v1); - ++col1; - } - return; - } else /* In hex mode, it's RLE compressed */ - { - while (col1 <= col2) { - if (!pgc_param_byte(pgc, &v1)) - return; + /* In ASCII mode, what is written is a stream of bytes */ + if (pgc->ascii_mode) { + while (col1 <= col2) { + if (!pgc_param_byte(pgc, &v1)) + return; + pgc_write_pixel(pgc, col1, row1, v1); + ++col1; + } + return; + } else /* In hex mode, it's RLE compressed */ + { + while (col1 <= col2) { + if (!pgc_param_byte(pgc, &v1)) + return; - if (v1 & 0x80) /* Literal run */ - { - v1 -= 0x7F; - while (col1 <= col2 && v1 != 0) { - if (!pgc_param_byte(pgc, &v2)) - return; - pgc_write_pixel(pgc, col1, row1, v2); - ++col1; - --v1; - } - } else /* Repeated run */ - { - if (!pgc_param_byte(pgc, &v2)) - return; + if (v1 & 0x80) /* Literal run */ + { + v1 -= 0x7F; + while (col1 <= col2 && v1 != 0) { + if (!pgc_param_byte(pgc, &v2)) + return; + pgc_write_pixel(pgc, col1, row1, v2); + ++col1; + --v1; + } + } else /* Repeated run */ + { + if (!pgc_param_byte(pgc, &v2)) + return; - ++v1; - while (col1 <= col2 && v1 != 0) { - pgc_write_pixel(pgc, col1, row1, v2); - ++col1; - --v1; - } - } - } - } - /* Restore clipping */ - pgc->vp_x1 = vp_x1; - pgc->vp_y1 = vp_y1; - pgc->vp_x2 = vp_x2; - pgc->vp_y2 = vp_y2; + ++v1; + while (col1 <= col2 && v1 != 0) { + pgc_write_pixel(pgc, col1, row1, v2); + ++col1; + --v1; + } + } + } + } + /* Restore clipping */ + pgc->vp_x1 = vp_x1; + pgc->vp_y1 = vp_y1; + pgc->vp_x2 = vp_x2; + pgc->vp_y2 = vp_y2; } -/* I have called this command DOT - I don't know its proper name. Draws a +/* I have called this command DOT - I don't know its proper name. Draws a * single pixel at the current location */ static void hndl_dot(pgc_core_t *pgc) { - int16_t x = pgc->x >> 16, y = pgc->y >> 16; + int16_t x = pgc->x >> 16, y = pgc->y >> 16; - pgc_sto_raster(pgc, &x, &y); + pgc_sto_raster(pgc, &x, &y); - PGCLOG(("Dot @ %d,%d ink=%d mode=%d\n", x, y, pgc->colour, pgc->draw_mode)); - pgc_plot(pgc, x, y); + PGCLOG(("Dot @ %d,%d ink=%d mode=%d\n", x, y, pgc->colour, pgc->draw_mode)); + pgc_plot(pgc, x, y); } -/* This command (which I have called IMAGEX, since I don't know its real +/* This command (which I have called IMAGEX, since I don't know its real * name) is a screen-to-memory blit. It reads a rectangle of bytes, rather - * than the single row read by IMAGER, and does not attempt to compress + * than the single row read by IMAGER, and does not attempt to compress * the result */ static void hndl_imagex(pgc_core_t *pgc) { - int16_t x0, x1, y0, y1; - int16_t p, q; + int16_t x0, x1, y0, y1; + int16_t p, q; - if (!pgc_param_word(pgc, &x0)) - return; - if (!pgc_param_word(pgc, &y0)) - return; - if (!pgc_param_word(pgc, &x1)) - return; - if (!pgc_param_word(pgc, &y1)) - return; + if (!pgc_param_word(pgc, &x0)) + return; + if (!pgc_param_word(pgc, &y0)) + return; + if (!pgc_param_word(pgc, &x1)) + return; + if (!pgc_param_word(pgc, &y1)) + return; - /* IMAGEX already uses raster coordinates so don't convert */ - PGCLOG(("IMAGEX (%d,%d,%d,%d)\n", x0, y0, x1, y1)); + /* IMAGEX already uses raster coordinates so don't convert */ + PGCLOG(("IMAGEX (%d,%d,%d,%d)\n", x0, y0, x1, y1)); - for (p = y0; p <= y1; p++) { - for (q = x0; q <= x1; q++) { - if (!pgc_result_byte(pgc, pgc_read_pixel(pgc, q, p))) - return; - } - } + for (p = y0; p <= y1; p++) { + for (q = x0; q <= x1; q++) { + if (!pgc_result_byte(pgc, pgc_read_pixel(pgc, q, p))) + return; + } + } } /* Commands implemented by the IM-1024. @@ -788,83 +778,67 @@ static void hndl_imagex(pgc_core_t *pgc) { * (BLINK, BUTRD, COPROC, RBAND etc) because the Windows 1.03 driver * does not use them. */ -static const pgc_command_t im1024_commands[] = - { - {"BLKMOV", 0xDF, hndl_blkmov, pgc_parse_words, 6}, - {"DRAW", 0x28, hndl_draw, pgc_parse_words, 2}, - {"D", 0x28, hndl_draw, pgc_parse_words, 2}, - {"DOT", 0x08, hndl_dot}, - {"ELIPSE", 0x39, hndl_ellipse, pgc_parse_words, 2}, - {"EL", 0x39, hndl_ellipse, pgc_parse_words, 2}, - {"IMAGEW", 0xD9, hndl_imagew}, - {"IW", 0xD9, hndl_imagew}, - {"IMAGEX", 0xDA, hndl_imagex}, - {"TXT88", 0x88, hndl_txt88}, - {"TWRITE", 0x8B, hndl_twrite}, - {"TDEFIN", 0x84, hndl_tdefin}, - {"TD", 0x84, hndl_tdefin}, - {"TSIZE", 0x81, hndl_tsize}, - {"TS", 0x81, hndl_tsize}, - {"IPREC", 0xE4, hndl_iprec}, - {"IMGSIZ", 0x4E, hndl_imgsiz}, - {"LUT8", 0xE6, pgc_hndl_lut8}, - {"L8", 0xE6, pgc_hndl_lut8}, - {"LUT8RD", 0x53, pgc_hndl_lut8rd}, - {"L8RD", 0x53, pgc_hndl_lut8rd}, - {"PAN", 0xB7, hndl_pan}, - {"POLY", 0x30, hndl_poly, parse_poly}, - {"P", 0x30, hndl_poly, parse_poly}, - {"PLINE", 0x36, hndl_pline}, - {"PL", 0x37, hndl_pline}, - {"MOVE", 0x10, hndl_move, pgc_parse_words, 2}, - {"M", 0x10, hndl_move, pgc_parse_words, 2}, - {"RECT", 0x34, hndl_rect}, - {"R", 0x34, hndl_rect}, - {"******", 0x00, NULL} - }; +static const pgc_command_t im1024_commands[] = {{"BLKMOV", 0xDF, hndl_blkmov, pgc_parse_words, 6}, + {"DRAW", 0x28, hndl_draw, pgc_parse_words, 2}, + {"D", 0x28, hndl_draw, pgc_parse_words, 2}, + {"DOT", 0x08, hndl_dot}, + {"ELIPSE", 0x39, hndl_ellipse, pgc_parse_words, 2}, + {"EL", 0x39, hndl_ellipse, pgc_parse_words, 2}, + {"IMAGEW", 0xD9, hndl_imagew}, + {"IW", 0xD9, hndl_imagew}, + {"IMAGEX", 0xDA, hndl_imagex}, + {"TXT88", 0x88, hndl_txt88}, + {"TWRITE", 0x8B, hndl_twrite}, + {"TDEFIN", 0x84, hndl_tdefin}, + {"TD", 0x84, hndl_tdefin}, + {"TSIZE", 0x81, hndl_tsize}, + {"TS", 0x81, hndl_tsize}, + {"IPREC", 0xE4, hndl_iprec}, + {"IMGSIZ", 0x4E, hndl_imgsiz}, + {"LUT8", 0xE6, pgc_hndl_lut8}, + {"L8", 0xE6, pgc_hndl_lut8}, + {"LUT8RD", 0x53, pgc_hndl_lut8rd}, + {"L8RD", 0x53, pgc_hndl_lut8rd}, + {"PAN", 0xB7, hndl_pan}, + {"POLY", 0x30, hndl_poly, parse_poly}, + {"P", 0x30, hndl_poly, parse_poly}, + {"PLINE", 0x36, hndl_pline}, + {"PL", 0x37, hndl_pline}, + {"MOVE", 0x10, hndl_move, pgc_parse_words, 2}, + {"M", 0x10, hndl_move, pgc_parse_words, 2}, + {"RECT", 0x34, hndl_rect}, + {"R", 0x34, hndl_rect}, + {"******", 0x00, NULL}}; void *im1024_init() { - im1024_t *im1024 = malloc(sizeof(im1024_t)); - memset(im1024, 0, sizeof(im1024_t)); + im1024_t *im1024 = malloc(sizeof(im1024_t)); + memset(im1024, 0, sizeof(im1024_t)); - im1024->fifo = malloc(4096); - im1024->fifo_len = 4096; - im1024->fifo_wrptr = 0; - im1024->fifo_rdptr = 0; + im1024->fifo = malloc(4096); + im1024->fifo_len = 4096; + im1024->fifo_wrptr = 0; + im1024->fifo_rdptr = 0; - /* 1024x1024 framebuffer with 1024x800 visible - Pixel clock is a guess */ - pgc_core_init(&im1024->pgc, 1024, 1024, 1024, 800, im1024_input_byte, 65000000.0); + /* 1024x1024 framebuffer with 1024x800 visible + Pixel clock is a guess */ + pgc_core_init(&im1024->pgc, 1024, 1024, 1024, 800, im1024_input_byte, 65000000.0); - mem_mapping_set_handler(&im1024->pgc.mapping, - im1024_read, NULL, NULL, - im1024_write, NULL, NULL); + mem_mapping_set_handler(&im1024->pgc.mapping, im1024_read, NULL, NULL, im1024_write, NULL, NULL); - im1024->pgc.pgc_commands = im1024_commands; - return im1024; + im1024->pgc.pgc_commands = im1024_commands; + return im1024; } void im1024_close(void *p) { - im1024_t *im1024 = (im1024_t *)p; + im1024_t *im1024 = (im1024_t *)p; - pgc_close(&im1024->pgc); + pgc_close(&im1024->pgc); } void im1024_speed_changed(void *p) { - im1024_t *im1024 = (im1024_t *)p; + im1024_t *im1024 = (im1024_t *)p; - pgc_speed_changed(&im1024->pgc); + pgc_speed_changed(&im1024->pgc); } -device_t im1024_device = - { - "Image Manager 1024", - 0, - im1024_init, - im1024_close, - NULL, - im1024_speed_changed, - NULL, - NULL, - NULL - }; +device_t im1024_device = {"Image Manager 1024", 0, im1024_init, im1024_close, NULL, im1024_speed_changed, NULL, NULL, NULL}; diff --git a/src/video/vid_incolor.c b/src/video/vid_incolor.c index c3c7749a..6b572f16 100644 --- a/src/video/vid_incolor.c +++ b/src/video/vid_incolor.c @@ -9,34 +9,33 @@ #include "video.h" #include "vid_incolor.h" - /* extended CRTC registers */ -#define INCOLOR_CRTC_XMODE 20 /* xMode register */ -#define INCOLOR_CRTC_UNDER 21 /* Underline */ -#define INCOLOR_CRTC_OVER 22 /* Overstrike */ -#define INCOLOR_CRTC_EXCEPT 23 /* Exception */ -#define INCOLOR_CRTC_MASK 24 /* Plane display mask & write mask */ -#define INCOLOR_CRTC_RWCTRL 25 /* Read/write control */ -#define INCOLOR_CRTC_RWCOL 26 /* Read/write colour */ +#define INCOLOR_CRTC_XMODE 20 /* xMode register */ +#define INCOLOR_CRTC_UNDER 21 /* Underline */ +#define INCOLOR_CRTC_OVER 22 /* Overstrike */ +#define INCOLOR_CRTC_EXCEPT 23 /* Exception */ +#define INCOLOR_CRTC_MASK 24 /* Plane display mask & write mask */ +#define INCOLOR_CRTC_RWCTRL 25 /* Read/write control */ +#define INCOLOR_CRTC_RWCOL 26 /* Read/write colour */ #define INCOLOR_CRTC_PROTECT 27 /* Latch protect */ #define INCOLOR_CRTC_PALETTE 28 /* Palette */ /* character width */ -#define INCOLOR_CW ((incolor->crtc[INCOLOR_CRTC_XMODE] & INCOLOR_XMODE_90COL) ? 8 : 9) +#define INCOLOR_CW ((incolor->crtc[INCOLOR_CRTC_XMODE] & INCOLOR_XMODE_90COL) ? 8 : 9) /* mode control register */ -#define INCOLOR_CTRL_GRAPH 0x02 -#define INCOLOR_CTRL_ENABLE 0x08 -#define INCOLOR_CTRL_BLINK 0x20 -#define INCOLOR_CTRL_PAGE1 0x80 +#define INCOLOR_CTRL_GRAPH 0x02 +#define INCOLOR_CTRL_ENABLE 0x08 +#define INCOLOR_CTRL_BLINK 0x20 +#define INCOLOR_CTRL_PAGE1 0x80 /* CRTC status register */ -#define INCOLOR_STATUS_HSYNC 0x01 /* horizontal sync */ +#define INCOLOR_STATUS_HSYNC 0x01 /* horizontal sync */ #define INCOLOR_STATUS_LIGHT 0x02 #define INCOLOR_STATUS_VIDEO 0x08 -#define INCOLOR_STATUS_ID 0x50 /* Card identification */ -#define INCOLOR_STATUS_VSYNC 0x80 /* -vertical sync */ +#define INCOLOR_STATUS_ID 0x50 /* Card identification */ +#define INCOLOR_STATUS_VSYNC 0x80 /* -vertical sync */ /* configuration switch register */ #define INCOLOR_CTRL2_GRAPH 0x01 @@ -44,121 +43,116 @@ /* extended mode register */ #define INCOLOR_XMODE_RAMFONT 0x01 -#define INCOLOR_XMODE_90COL 0x02 - +#define INCOLOR_XMODE_90COL 0x02 /* Read/write control */ -#define INCOLOR_RWCTRL_WRMODE 0x30 +#define INCOLOR_RWCTRL_WRMODE 0x30 #define INCOLOR_RWCTRL_POLARITY 0x40 /* exception register */ -#define INCOLOR_EXCEPT_CURSOR 0x0F /* Cursor colour */ -#define INCOLOR_EXCEPT_PALETTE 0x10 /* Enable palette register */ -#define INCOLOR_EXCEPT_ALTATTR 0x20 /* Use alternate attributes */ +#define INCOLOR_EXCEPT_CURSOR 0x0F /* Cursor colour */ +#define INCOLOR_EXCEPT_PALETTE 0x10 /* Enable palette register */ +#define INCOLOR_EXCEPT_ALTATTR 0x20 /* Use alternate attributes */ /* Default palette */ -static unsigned char defpal[16] = - { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F - }; +static unsigned char defpal[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F}; static uint32_t incolor_rgb[64]; /* Mapping of inks to RGB */ -static unsigned char init_rgb[64][3] = - { - // rgbRGB - {0x00, 0x00, 0x00}, // 000000 - {0x00, 0x00, 0xaa}, // 000001 - {0x00, 0xaa, 0x00}, // 000010 - {0x00, 0xaa, 0xaa}, // 000011 - {0xaa, 0x00, 0x00}, // 000100 - {0xaa, 0x00, 0xaa}, // 000101 - {0xaa, 0xaa, 0x00}, // 000110 - {0xaa, 0xaa, 0xaa}, // 000111 - {0x00, 0x00, 0x55}, // 001000 - {0x00, 0x00, 0xff}, // 001001 - {0x00, 0xaa, 0x55}, // 001010 - {0x00, 0xaa, 0xff}, // 001011 - {0xaa, 0x00, 0x55}, // 001100 - {0xaa, 0x00, 0xff}, // 001101 - {0xaa, 0xaa, 0x55}, // 001110 - {0xaa, 0xaa, 0xff}, // 001111 - {0x00, 0x55, 0x00}, // 010000 - {0x00, 0x55, 0xaa}, // 010001 - {0x00, 0xff, 0x00}, // 010010 - {0x00, 0xff, 0xaa}, // 010011 - {0xaa, 0x55, 0x00}, // 010100 - {0xaa, 0x55, 0xaa}, // 010101 - {0xaa, 0xff, 0x00}, // 010110 - {0xaa, 0xff, 0xaa}, // 010111 - {0x00, 0x55, 0x55}, // 011000 - {0x00, 0x55, 0xff}, // 011001 - {0x00, 0xff, 0x55}, // 011010 - {0x00, 0xff, 0xff}, // 011011 - {0xaa, 0x55, 0x55}, // 011100 - {0xaa, 0x55, 0xff}, // 011101 - {0xaa, 0xff, 0x55}, // 011110 - {0xaa, 0xff, 0xff}, // 011111 - {0x55, 0x00, 0x00}, // 100000 - {0x55, 0x00, 0xaa}, // 100001 - {0x55, 0xaa, 0x00}, // 100010 - {0x55, 0xaa, 0xaa}, // 100011 - {0xff, 0x00, 0x00}, // 100100 - {0xff, 0x00, 0xaa}, // 100101 - {0xff, 0xaa, 0x00}, // 100110 - {0xff, 0xaa, 0xaa}, // 100111 - {0x55, 0x00, 0x55}, // 101000 - {0x55, 0x00, 0xff}, // 101001 - {0x55, 0xaa, 0x55}, // 101010 - {0x55, 0xaa, 0xff}, // 101011 - {0xff, 0x00, 0x55}, // 101100 - {0xff, 0x00, 0xff}, // 101101 - {0xff, 0xaa, 0x55}, // 101110 - {0xff, 0xaa, 0xff}, // 101111 - {0x55, 0x55, 0x00}, // 110000 - {0x55, 0x55, 0xaa}, // 110001 - {0x55, 0xff, 0x00}, // 110010 - {0x55, 0xff, 0xaa}, // 110011 - {0xff, 0x55, 0x00}, // 110100 - {0xff, 0x55, 0xaa}, // 110101 - {0xff, 0xff, 0x00}, // 110110 - {0xff, 0xff, 0xaa}, // 110111 - {0x55, 0x55, 0x55}, // 111000 - {0x55, 0x55, 0xff}, // 111001 - {0x55, 0xff, 0x55}, // 111010 - {0x55, 0xff, 0xff}, // 111011 - {0xff, 0x55, 0x55}, // 111100 - {0xff, 0x55, 0xff}, // 111101 - {0xff, 0xff, 0x55}, // 111110 - {0xff, 0xff, 0xff}, // 111111 - }; +static unsigned char init_rgb[64][3] = { + // rgbRGB + {0x00, 0x00, 0x00}, // 000000 + {0x00, 0x00, 0xaa}, // 000001 + {0x00, 0xaa, 0x00}, // 000010 + {0x00, 0xaa, 0xaa}, // 000011 + {0xaa, 0x00, 0x00}, // 000100 + {0xaa, 0x00, 0xaa}, // 000101 + {0xaa, 0xaa, 0x00}, // 000110 + {0xaa, 0xaa, 0xaa}, // 000111 + {0x00, 0x00, 0x55}, // 001000 + {0x00, 0x00, 0xff}, // 001001 + {0x00, 0xaa, 0x55}, // 001010 + {0x00, 0xaa, 0xff}, // 001011 + {0xaa, 0x00, 0x55}, // 001100 + {0xaa, 0x00, 0xff}, // 001101 + {0xaa, 0xaa, 0x55}, // 001110 + {0xaa, 0xaa, 0xff}, // 001111 + {0x00, 0x55, 0x00}, // 010000 + {0x00, 0x55, 0xaa}, // 010001 + {0x00, 0xff, 0x00}, // 010010 + {0x00, 0xff, 0xaa}, // 010011 + {0xaa, 0x55, 0x00}, // 010100 + {0xaa, 0x55, 0xaa}, // 010101 + {0xaa, 0xff, 0x00}, // 010110 + {0xaa, 0xff, 0xaa}, // 010111 + {0x00, 0x55, 0x55}, // 011000 + {0x00, 0x55, 0xff}, // 011001 + {0x00, 0xff, 0x55}, // 011010 + {0x00, 0xff, 0xff}, // 011011 + {0xaa, 0x55, 0x55}, // 011100 + {0xaa, 0x55, 0xff}, // 011101 + {0xaa, 0xff, 0x55}, // 011110 + {0xaa, 0xff, 0xff}, // 011111 + {0x55, 0x00, 0x00}, // 100000 + {0x55, 0x00, 0xaa}, // 100001 + {0x55, 0xaa, 0x00}, // 100010 + {0x55, 0xaa, 0xaa}, // 100011 + {0xff, 0x00, 0x00}, // 100100 + {0xff, 0x00, 0xaa}, // 100101 + {0xff, 0xaa, 0x00}, // 100110 + {0xff, 0xaa, 0xaa}, // 100111 + {0x55, 0x00, 0x55}, // 101000 + {0x55, 0x00, 0xff}, // 101001 + {0x55, 0xaa, 0x55}, // 101010 + {0x55, 0xaa, 0xff}, // 101011 + {0xff, 0x00, 0x55}, // 101100 + {0xff, 0x00, 0xff}, // 101101 + {0xff, 0xaa, 0x55}, // 101110 + {0xff, 0xaa, 0xff}, // 101111 + {0x55, 0x55, 0x00}, // 110000 + {0x55, 0x55, 0xaa}, // 110001 + {0x55, 0xff, 0x00}, // 110010 + {0x55, 0xff, 0xaa}, // 110011 + {0xff, 0x55, 0x00}, // 110100 + {0xff, 0x55, 0xaa}, // 110101 + {0xff, 0xff, 0x00}, // 110110 + {0xff, 0xff, 0xaa}, // 110111 + {0x55, 0x55, 0x55}, // 111000 + {0x55, 0x55, 0xff}, // 111001 + {0x55, 0xff, 0x55}, // 111010 + {0x55, 0xff, 0xff}, // 111011 + {0xff, 0x55, 0x55}, // 111100 + {0xff, 0x55, 0xff}, // 111101 + {0xff, 0xff, 0x55}, // 111110 + {0xff, 0xff, 0xff}, // 111111 +}; typedef struct incolor_t { - mem_mapping_t mapping; + mem_mapping_t mapping; - uint8_t crtc[32]; - int crtcreg; + uint8_t crtc[32]; + int crtcreg; - uint8_t ctrl, ctrl2, stat; + uint8_t ctrl, ctrl2, stat; - uint64_t dispontime, dispofftime; - pc_timer_t timer; + uint64_t dispontime, dispofftime; + pc_timer_t timer; - int firstline, lastline; + int firstline, lastline; - int linepos, displine; - int vc, sc; - uint16_t ma, maback; - int con, coff, cursoron; - int dispon, blink; - int vsynctime, vadj; + int linepos, displine; + int vc, sc; + uint16_t ma, maback; + int con, coff, cursoron; + int dispon, blink; + int vsynctime, vadj; - uint8_t palette[16]; /* EGA-style 16 -> 64 palette registers */ - uint8_t palette_idx; /* Palette write index */ - uint8_t latch[4]; /* Memory read/write latches */ - uint8_t *vram; + uint8_t palette[16]; /* EGA-style 16 -> 64 palette registers */ + uint8_t palette_idx; /* Palette write index */ + uint8_t latch[4]; /* Memory read/write latches */ + uint8_t *vram; } incolor_t; void incolor_recalctimings(incolor_t *incolor); @@ -166,769 +160,770 @@ void incolor_write(uint32_t addr, uint8_t val, void *p); uint8_t incolor_read(uint32_t addr, void *p); void incolor_out(uint16_t addr, uint8_t val, void *p) { - incolor_t *incolor = (incolor_t *)p; -/* pclog("InColor out %04X %02X\n",addr,val); */ - switch (addr) { - case 0x3b0: - case 0x3b2: - case 0x3b4: - case 0x3b6:incolor->crtcreg = val & 31; - return; - case 0x3b1: - case 0x3b3: - case 0x3b5: - case 0x3b7: - if (incolor->crtcreg > 28) - return; - /* Palette load register */ - if (incolor->crtcreg == INCOLOR_CRTC_PALETTE) { - incolor->palette[incolor->palette_idx % 16] = val; - ++incolor->palette_idx; - } - incolor->crtc[incolor->crtcreg] = val; - if (incolor->crtc[10] == 6 && incolor->crtc[11] == 7) /*Fix for Generic Turbo XT BIOS, which sets up cursor registers wrong*/ - { - incolor->crtc[10] = 0xb; - incolor->crtc[11] = 0xc; - } - incolor_recalctimings(incolor); - return; - case 0x3b8:incolor->ctrl = val; - return; - case 0x3bf:incolor->ctrl2 = val; - if (val & 2) - mem_mapping_set_addr(&incolor->mapping, 0xb0000, 0x10000); - else - mem_mapping_set_addr(&incolor->mapping, 0xb0000, 0x08000); - return; - } + incolor_t *incolor = (incolor_t *)p; + /* pclog("InColor out %04X %02X\n",addr,val); */ + switch (addr) { + case 0x3b0: + case 0x3b2: + case 0x3b4: + case 0x3b6: + incolor->crtcreg = val & 31; + return; + case 0x3b1: + case 0x3b3: + case 0x3b5: + case 0x3b7: + if (incolor->crtcreg > 28) + return; + /* Palette load register */ + if (incolor->crtcreg == INCOLOR_CRTC_PALETTE) { + incolor->palette[incolor->palette_idx % 16] = val; + ++incolor->palette_idx; + } + incolor->crtc[incolor->crtcreg] = val; + if (incolor->crtc[10] == 6 && + incolor->crtc[11] == 7) /*Fix for Generic Turbo XT BIOS, which sets up cursor registers wrong*/ + { + incolor->crtc[10] = 0xb; + incolor->crtc[11] = 0xc; + } + incolor_recalctimings(incolor); + return; + case 0x3b8: + incolor->ctrl = val; + return; + case 0x3bf: + incolor->ctrl2 = val; + if (val & 2) + mem_mapping_set_addr(&incolor->mapping, 0xb0000, 0x10000); + else + mem_mapping_set_addr(&incolor->mapping, 0xb0000, 0x08000); + return; + } } uint8_t incolor_in(uint16_t addr, void *p) { - incolor_t *incolor = (incolor_t *)p; -/* pclog("InColor in %04X %02X %04X:%04X %04X\n",addr,(incolor->stat & 0xF) | ((incolor->stat & 8) << 4),CS,pc,CX); */ - switch (addr) { - case 0x3b0: - case 0x3b2: - case 0x3b4: - case 0x3b6:return incolor->crtcreg; - case 0x3b1: - case 0x3b3: - case 0x3b5: - case 0x3b7: - if (incolor->crtcreg > 28) - return 0xff; - incolor->palette_idx = 0; /* Read resets the palette index */ - return incolor->crtc[incolor->crtcreg]; - case 0x3ba: - /* 0x50: InColor card identity */ - return (incolor->stat & 0xf) | ((incolor->stat & 8) << 4) | 0x50; - } - return 0xff; + incolor_t *incolor = (incolor_t *)p; + /* pclog("InColor in %04X %02X %04X:%04X %04X\n",addr,(incolor->stat & 0xF) | ((incolor->stat & 8) << 4),CS,pc,CX); + */ + switch (addr) { + case 0x3b0: + case 0x3b2: + case 0x3b4: + case 0x3b6: + return incolor->crtcreg; + case 0x3b1: + case 0x3b3: + case 0x3b5: + case 0x3b7: + if (incolor->crtcreg > 28) + return 0xff; + incolor->palette_idx = 0; /* Read resets the palette index */ + return incolor->crtc[incolor->crtcreg]; + case 0x3ba: + /* 0x50: InColor card identity */ + return (incolor->stat & 0xf) | ((incolor->stat & 8) << 4) | 0x50; + } + return 0xff; } void incolor_write(uint32_t addr, uint8_t val, void *p) { - incolor_t *incolor = (incolor_t *)p; - egawrites++; + incolor_t *incolor = (incolor_t *)p; + egawrites++; - int plane; - unsigned char wmask = incolor->crtc[INCOLOR_CRTC_MASK]; - unsigned char wmode = incolor->crtc[INCOLOR_CRTC_RWCTRL] & INCOLOR_RWCTRL_WRMODE; - unsigned char fg = incolor->crtc[INCOLOR_CRTC_RWCOL] & 0x0F; - unsigned char bg = (incolor->crtc[INCOLOR_CRTC_RWCOL] >> 4) & 0x0F; - unsigned char w = 0; - unsigned char vmask; /* Mask of bit within byte */ - unsigned char pmask; /* Mask of plane within colour value */ - unsigned char latch; + int plane; + unsigned char wmask = incolor->crtc[INCOLOR_CRTC_MASK]; + unsigned char wmode = incolor->crtc[INCOLOR_CRTC_RWCTRL] & INCOLOR_RWCTRL_WRMODE; + unsigned char fg = incolor->crtc[INCOLOR_CRTC_RWCOL] & 0x0F; + unsigned char bg = (incolor->crtc[INCOLOR_CRTC_RWCOL] >> 4) & 0x0F; + unsigned char w = 0; + unsigned char vmask; /* Mask of bit within byte */ + unsigned char pmask; /* Mask of plane within colour value */ + unsigned char latch; - addr &= 0xFFFF; + addr &= 0xFFFF; - /* In text mode, writes to the bottom 16k always touch all 4 planes */ - if (!(incolor->ctrl & INCOLOR_CTRL_GRAPH) && addr < 0x4000) { - incolor->vram[addr] = val; - return; - } + /* In text mode, writes to the bottom 16k always touch all 4 planes */ + if (!(incolor->ctrl & INCOLOR_CTRL_GRAPH) && addr < 0x4000) { + incolor->vram[addr] = val; + return; + } - /* There are four write modes: - * 0: 1 => foreground, 0 => background - * 1: 1 => foreground, 0 => source latch - * 2: 1 => source latch, 0 => background - * 3: 1 => source latch, 0 => ~source latch - */ - pmask = 1; - for (plane = 0; plane < 4; pmask <<= 1, wmask >>= 1, addr += 0x10000, - plane++) { - if (wmask & 0x10) /* Ignore writes to selected plane */ - { - continue; - } - latch = incolor->latch[plane]; - for (vmask = 0x80; vmask != 0; vmask >>= 1) { - switch (wmode) { - case 0x00: - if (val & vmask) - w = (fg & pmask); - else - w = (bg & pmask); - break; - case 0x10: - if (val & vmask) - w = (fg & pmask); - else - w = (latch & vmask); - break; - case 0x20: - if (val & vmask) - w = (latch & vmask); - else - w = (bg & pmask); - break; - case 0x30: - if (val & vmask) - w = (latch & vmask); - else - w = ((~latch) & vmask); - break; - } - /* w is nonzero to write a 1, zero to write a 0 */ - if (w) - incolor->vram[addr] |= vmask; - else - incolor->vram[addr] &= ~vmask; - } - } + /* There are four write modes: + * 0: 1 => foreground, 0 => background + * 1: 1 => foreground, 0 => source latch + * 2: 1 => source latch, 0 => background + * 3: 1 => source latch, 0 => ~source latch + */ + pmask = 1; + for (plane = 0; plane < 4; pmask <<= 1, wmask >>= 1, addr += 0x10000, plane++) { + if (wmask & 0x10) /* Ignore writes to selected plane */ + { + continue; + } + latch = incolor->latch[plane]; + for (vmask = 0x80; vmask != 0; vmask >>= 1) { + switch (wmode) { + case 0x00: + if (val & vmask) + w = (fg & pmask); + else + w = (bg & pmask); + break; + case 0x10: + if (val & vmask) + w = (fg & pmask); + else + w = (latch & vmask); + break; + case 0x20: + if (val & vmask) + w = (latch & vmask); + else + w = (bg & pmask); + break; + case 0x30: + if (val & vmask) + w = (latch & vmask); + else + w = ((~latch) & vmask); + break; + } + /* w is nonzero to write a 1, zero to write a 0 */ + if (w) + incolor->vram[addr] |= vmask; + else + incolor->vram[addr] &= ~vmask; + } + } } uint8_t incolor_read(uint32_t addr, void *p) { - incolor_t *incolor = (incolor_t *)p; - egareads++; - unsigned plane; - unsigned char lp = incolor->crtc[INCOLOR_CRTC_PROTECT]; - unsigned char value = 0; - unsigned char dc; /* "don't care" register */ - unsigned char bg; /* background colour */ - unsigned char fg; - unsigned char mask, pmask; + incolor_t *incolor = (incolor_t *)p; + egareads++; + unsigned plane; + unsigned char lp = incolor->crtc[INCOLOR_CRTC_PROTECT]; + unsigned char value = 0; + unsigned char dc; /* "don't care" register */ + unsigned char bg; /* background colour */ + unsigned char fg; + unsigned char mask, pmask; - addr &= 0xFFFF; - /* Read the four planes into latches */ - for (plane = 0; plane < 4; plane++, addr += 0x10000) { - incolor->latch[plane] &= lp; - incolor->latch[plane] |= (incolor->vram[addr] & ~lp); - } - addr &= 0xFFFF; - /* In text mode, reads from the bottom 16k assume all planes have - * the same contents */ - if (!(incolor->ctrl & INCOLOR_CTRL_GRAPH) && addr < 0x4000) { - return incolor->latch[0]; - } - /* For each pixel, work out if its colour matches the background */ - for (mask = 0x80; mask != 0; mask >>= 1) { - fg = 0; - dc = incolor->crtc[INCOLOR_CRTC_RWCTRL] & 0x0F; - bg = (incolor->crtc[INCOLOR_CRTC_RWCOL] >> 4) & 0x0F; - for (plane = 0, pmask = 1; plane < 4; plane++, pmask <<= 1) { - if (dc & pmask) { - fg |= (bg & pmask); - } else if (incolor->latch[plane] & mask) { - fg |= pmask; - } - } - if (bg == fg) - value |= mask; - } - if (incolor->crtc[INCOLOR_CRTC_RWCTRL] & INCOLOR_RWCTRL_POLARITY) { - value = ~value; - } - return value; + addr &= 0xFFFF; + /* Read the four planes into latches */ + for (plane = 0; plane < 4; plane++, addr += 0x10000) { + incolor->latch[plane] &= lp; + incolor->latch[plane] |= (incolor->vram[addr] & ~lp); + } + addr &= 0xFFFF; + /* In text mode, reads from the bottom 16k assume all planes have + * the same contents */ + if (!(incolor->ctrl & INCOLOR_CTRL_GRAPH) && addr < 0x4000) { + return incolor->latch[0]; + } + /* For each pixel, work out if its colour matches the background */ + for (mask = 0x80; mask != 0; mask >>= 1) { + fg = 0; + dc = incolor->crtc[INCOLOR_CRTC_RWCTRL] & 0x0F; + bg = (incolor->crtc[INCOLOR_CRTC_RWCOL] >> 4) & 0x0F; + for (plane = 0, pmask = 1; plane < 4; plane++, pmask <<= 1) { + if (dc & pmask) { + fg |= (bg & pmask); + } else if (incolor->latch[plane] & mask) { + fg |= pmask; + } + } + if (bg == fg) + value |= mask; + } + if (incolor->crtc[INCOLOR_CRTC_RWCTRL] & INCOLOR_RWCTRL_POLARITY) { + value = ~value; + } + return value; } void incolor_recalctimings(incolor_t *incolor) { - double disptime; - double _dispontime, _dispofftime; - disptime = incolor->crtc[0] + 1; - _dispontime = incolor->crtc[1]; - _dispofftime = disptime - _dispontime; - _dispontime *= MDACONST; - _dispofftime *= MDACONST; - incolor->dispontime = (uint64_t)_dispontime; - incolor->dispofftime = (uint64_t)_dispofftime; + double disptime; + double _dispontime, _dispofftime; + disptime = incolor->crtc[0] + 1; + _dispontime = incolor->crtc[1]; + _dispofftime = disptime - _dispontime; + _dispontime *= MDACONST; + _dispofftime *= MDACONST; + incolor->dispontime = (uint64_t)_dispontime; + incolor->dispofftime = (uint64_t)_dispofftime; } static void incolor_draw_char_rom(incolor_t *incolor, int x, uint8_t chr, uint8_t attr) { - unsigned i; - int elg, blk; - unsigned ull; - unsigned val; - unsigned ifg, ibg; - const unsigned char *fnt; - uint32_t fg, bg; - int cw = INCOLOR_CW; + unsigned i; + int elg, blk; + unsigned ull; + unsigned val; + unsigned ifg, ibg; + const unsigned char *fnt; + uint32_t fg, bg; + int cw = INCOLOR_CW; - blk = 0; - if (incolor->ctrl & INCOLOR_CTRL_BLINK) { - if (attr & 0x80) { - blk = (incolor->blink & 16); - } - attr &= 0x7f; - } + blk = 0; + if (incolor->ctrl & INCOLOR_CTRL_BLINK) { + if (attr & 0x80) { + blk = (incolor->blink & 16); + } + attr &= 0x7f; + } - if (incolor->crtc[INCOLOR_CRTC_EXCEPT] & INCOLOR_EXCEPT_ALTATTR) { - /* MDA-compatible attributes */ - ibg = 0; - ifg = 7; - if ((attr & 0x77) == 0x70) /* Invert */ - { - ifg = 0; - ibg = 7; - } - if (attr & 8) { - ifg |= 8; /* High intensity FG */ - } - if (attr & 0x80) { - ibg |= 8; /* High intensity BG */ - } - if ((attr & 0x77) == 0) /* Blank */ - { - ifg = ibg; - } - ull = ((attr & 0x07) == 1) ? 13 : 0xffff; - } else { - /* CGA-compatible attributes */ - ull = 0xffff; - ifg = attr & 0x0F; - ibg = (attr >> 4) & 0x0F; - } - if (incolor->crtc[INCOLOR_CRTC_EXCEPT] & INCOLOR_EXCEPT_PALETTE) { - fg = incolor_rgb[incolor->palette[ifg]]; - bg = incolor_rgb[incolor->palette[ibg]]; - } else { - fg = incolor_rgb[defpal[ifg]]; - bg = incolor_rgb[defpal[ibg]]; - } + if (incolor->crtc[INCOLOR_CRTC_EXCEPT] & INCOLOR_EXCEPT_ALTATTR) { + /* MDA-compatible attributes */ + ibg = 0; + ifg = 7; + if ((attr & 0x77) == 0x70) /* Invert */ + { + ifg = 0; + ibg = 7; + } + if (attr & 8) { + ifg |= 8; /* High intensity FG */ + } + if (attr & 0x80) { + ibg |= 8; /* High intensity BG */ + } + if ((attr & 0x77) == 0) /* Blank */ + { + ifg = ibg; + } + ull = ((attr & 0x07) == 1) ? 13 : 0xffff; + } else { + /* CGA-compatible attributes */ + ull = 0xffff; + ifg = attr & 0x0F; + ibg = (attr >> 4) & 0x0F; + } + if (incolor->crtc[INCOLOR_CRTC_EXCEPT] & INCOLOR_EXCEPT_PALETTE) { + fg = incolor_rgb[incolor->palette[ifg]]; + bg = incolor_rgb[incolor->palette[ibg]]; + } else { + fg = incolor_rgb[defpal[ifg]]; + bg = incolor_rgb[defpal[ibg]]; + } - /* ELG set to stretch 8px character to 9px */ - elg = ((chr >= 0xc0) && (chr <= 0xdf)); + /* ELG set to stretch 8px character to 9px */ + elg = ((chr >= 0xc0) && (chr <= 0xdf)); - fnt = &(fontdatm[chr][incolor->sc]); + fnt = &(fontdatm[chr][incolor->sc]); - if (blk) { - val = 0x000; /* Blinking, draw all background */ - } else if (incolor->sc == ull) { - val = 0x1ff; /* Underscore, draw all foreground */ - } else { - val = fnt[0] << 1; + if (blk) { + val = 0x000; /* Blinking, draw all background */ + } else if (incolor->sc == ull) { + val = 0x1ff; /* Underscore, draw all foreground */ + } else { + val = fnt[0] << 1; - if (elg) { - val |= (val >> 1) & 1; - } - } - for (i = 0; i < cw; i++) { - ((uint32_t *)buffer32->line[incolor->displine])[x * cw + i] = (val & 0x100) ? fg : bg; - val = val << 1; - } + if (elg) { + val |= (val >> 1) & 1; + } + } + for (i = 0; i < cw; i++) { + ((uint32_t *)buffer32->line[incolor->displine])[x * cw + i] = (val & 0x100) ? fg : bg; + val = val << 1; + } } static void incolor_draw_char_ram4(incolor_t *incolor, int x, uint8_t chr, uint8_t attr) { - unsigned i; - int elg, blk; - unsigned ull; - unsigned val[4]; - unsigned ifg, ibg, cfg, pmask, plane; - const unsigned char *fnt; - uint32_t fg; - int cw = INCOLOR_CW; - int blink = incolor->ctrl & INCOLOR_CTRL_BLINK; - int altattr = incolor->crtc[INCOLOR_CRTC_EXCEPT] & INCOLOR_EXCEPT_ALTATTR; - int palette = incolor->crtc[INCOLOR_CRTC_EXCEPT] & INCOLOR_EXCEPT_PALETTE; + unsigned i; + int elg, blk; + unsigned ull; + unsigned val[4]; + unsigned ifg, ibg, cfg, pmask, plane; + const unsigned char *fnt; + uint32_t fg; + int cw = INCOLOR_CW; + int blink = incolor->ctrl & INCOLOR_CTRL_BLINK; + int altattr = incolor->crtc[INCOLOR_CRTC_EXCEPT] & INCOLOR_EXCEPT_ALTATTR; + int palette = incolor->crtc[INCOLOR_CRTC_EXCEPT] & INCOLOR_EXCEPT_PALETTE; - blk = 0; - if (blink) { - if (attr & 0x80) { - blk = (incolor->blink & 16); - } - attr &= 0x7f; - } + blk = 0; + if (blink) { + if (attr & 0x80) { + blk = (incolor->blink & 16); + } + attr &= 0x7f; + } - if (altattr) { - /* MDA-compatible attributes */ - ibg = 0; - ifg = 7; - if ((attr & 0x77) == 0x70) /* Invert */ - { - ifg = 0; - ibg = 7; - } - if (attr & 8) { - ifg |= 8; /* High intensity FG */ - } - if (attr & 0x80) { - ibg |= 8; /* High intensity BG */ - } - if ((attr & 0x77) == 0) /* Blank */ - { - ifg = ibg; - } - ull = ((attr & 0x07) == 1) ? 13 : 0xffff; - } else { - /* CGA-compatible attributes */ - ull = 0xffff; - ifg = attr & 0x0F; - ibg = (attr >> 4) & 0x0F; - } - if (incolor->crtc[INCOLOR_CRTC_XMODE] & INCOLOR_XMODE_90COL) { - elg = 0; - } else { - elg = ((chr >= 0xc0) && (chr <= 0xdf)); - } - fnt = incolor->vram + 0x4000 + 16 * chr + incolor->sc; + if (altattr) { + /* MDA-compatible attributes */ + ibg = 0; + ifg = 7; + if ((attr & 0x77) == 0x70) /* Invert */ + { + ifg = 0; + ibg = 7; + } + if (attr & 8) { + ifg |= 8; /* High intensity FG */ + } + if (attr & 0x80) { + ibg |= 8; /* High intensity BG */ + } + if ((attr & 0x77) == 0) /* Blank */ + { + ifg = ibg; + } + ull = ((attr & 0x07) == 1) ? 13 : 0xffff; + } else { + /* CGA-compatible attributes */ + ull = 0xffff; + ifg = attr & 0x0F; + ibg = (attr >> 4) & 0x0F; + } + if (incolor->crtc[INCOLOR_CRTC_XMODE] & INCOLOR_XMODE_90COL) { + elg = 0; + } else { + elg = ((chr >= 0xc0) && (chr <= 0xdf)); + } + fnt = incolor->vram + 0x4000 + 16 * chr + incolor->sc; - if (blk) { - /* Blinking, draw all background */ - val[0] = val[1] = val[2] = val[3] = 0x000; - } else if (incolor->sc == ull) { - /* Underscore, draw all foreground */ - val[0] = val[1] = val[2] = val[3] = 0x1ff; - } else { - val[0] = fnt[0x00000] << 1; - val[1] = fnt[0x10000] << 1; - val[2] = fnt[0x20000] << 1; - val[3] = fnt[0x30000] << 1; + if (blk) { + /* Blinking, draw all background */ + val[0] = val[1] = val[2] = val[3] = 0x000; + } else if (incolor->sc == ull) { + /* Underscore, draw all foreground */ + val[0] = val[1] = val[2] = val[3] = 0x1ff; + } else { + val[0] = fnt[0x00000] << 1; + val[1] = fnt[0x10000] << 1; + val[2] = fnt[0x20000] << 1; + val[3] = fnt[0x30000] << 1; - if (elg) { - val[0] |= (val[0] >> 1) & 1; - val[1] |= (val[1] >> 1) & 1; - val[2] |= (val[2] >> 1) & 1; - val[3] |= (val[3] >> 1) & 1; - } - } - for (i = 0; i < cw; i++) { - /* Generate pixel colour */ - cfg = 0; - pmask = 1; - for (plane = 0; plane < 4; plane++, pmask = pmask << 1) { - if (val[plane] & 0x100) - cfg |= (ifg & pmask); - else - cfg |= (ibg & pmask); - } - /* cfg = colour of foreground pixels */ - if (altattr && (attr & 0x77) == 0) - cfg = ibg; /* 'blank' attribute */ - if (palette) { - fg = incolor_rgb[incolor->palette[cfg]]; - } else { - fg = incolor_rgb[defpal[cfg]]; - } + if (elg) { + val[0] |= (val[0] >> 1) & 1; + val[1] |= (val[1] >> 1) & 1; + val[2] |= (val[2] >> 1) & 1; + val[3] |= (val[3] >> 1) & 1; + } + } + for (i = 0; i < cw; i++) { + /* Generate pixel colour */ + cfg = 0; + pmask = 1; + for (plane = 0; plane < 4; plane++, pmask = pmask << 1) { + if (val[plane] & 0x100) + cfg |= (ifg & pmask); + else + cfg |= (ibg & pmask); + } + /* cfg = colour of foreground pixels */ + if (altattr && (attr & 0x77) == 0) + cfg = ibg; /* 'blank' attribute */ + if (palette) { + fg = incolor_rgb[incolor->palette[cfg]]; + } else { + fg = incolor_rgb[defpal[cfg]]; + } - ((uint32_t *)buffer32->line[incolor->displine])[x * cw + i] = fg; - val[0] = val[0] << 1; - val[1] = val[1] << 1; - val[2] = val[2] << 1; - val[3] = val[3] << 1; - } + ((uint32_t *)buffer32->line[incolor->displine])[x * cw + i] = fg; + val[0] = val[0] << 1; + val[1] = val[1] << 1; + val[2] = val[2] << 1; + val[3] = val[3] << 1; + } } static void incolor_draw_char_ram48(incolor_t *incolor, int x, uint8_t chr, uint8_t attr) { - unsigned i; - int elg, blk, ul, ol, bld; - unsigned ull, oll, ulc = 0, olc = 0; - unsigned val[4]; - unsigned ifg = 0, ibg, cfg, pmask, plane; - const unsigned char *fnt; - uint32_t fg; - int cw = INCOLOR_CW; - int blink = incolor->ctrl & INCOLOR_CTRL_BLINK; - int altattr = incolor->crtc[INCOLOR_CRTC_EXCEPT] & INCOLOR_EXCEPT_ALTATTR; - int palette = incolor->crtc[INCOLOR_CRTC_EXCEPT] & INCOLOR_EXCEPT_PALETTE; - int font = (attr & 0x0F); + unsigned i; + int elg, blk, ul, ol, bld; + unsigned ull, oll, ulc = 0, olc = 0; + unsigned val[4]; + unsigned ifg = 0, ibg, cfg, pmask, plane; + const unsigned char *fnt; + uint32_t fg; + int cw = INCOLOR_CW; + int blink = incolor->ctrl & INCOLOR_CTRL_BLINK; + int altattr = incolor->crtc[INCOLOR_CRTC_EXCEPT] & INCOLOR_EXCEPT_ALTATTR; + int palette = incolor->crtc[INCOLOR_CRTC_EXCEPT] & INCOLOR_EXCEPT_PALETTE; + int font = (attr & 0x0F); - if (font >= 12) - font &= 7; + if (font >= 12) + font &= 7; - blk = 0; - if (blink && altattr) { - if (attr & 0x40) { - blk = (incolor->blink & 16); - } - attr &= 0x7f; - } - if (altattr) { - /* MDA-compatible attributes */ - if (blink) { - ibg = (attr & 0x80) ? 8 : 0; - bld = 0; - ol = (attr & 0x20) ? 1 : 0; - ul = (attr & 0x10) ? 1 : 0; - } else { - bld = (attr & 0x80) ? 1 : 0; - ibg = (attr & 0x40) ? 0x0F : 0; - ol = (attr & 0x20) ? 1 : 0; - ul = (attr & 0x10) ? 1 : 0; - } - } else { - /* CGA-compatible attributes */ - ibg = 0; - ifg = (attr >> 4) & 0x0F; - ol = 0; - ul = 0; - bld = 0; - } - if (ul) { - ull = incolor->crtc[INCOLOR_CRTC_UNDER] & 0x0F; - ulc = (incolor->crtc[INCOLOR_CRTC_UNDER] >> 4) & 0x0F; - if (ulc == 0) - ulc = 7; - } else { - ull = 0xFFFF; - } - if (ol) { - oll = incolor->crtc[INCOLOR_CRTC_OVER] & 0x0F; - olc = (incolor->crtc[INCOLOR_CRTC_OVER] >> 4) & 0x0F; - if (olc == 0) - olc = 7; - } else { - oll = 0xFFFF; - } + blk = 0; + if (blink && altattr) { + if (attr & 0x40) { + blk = (incolor->blink & 16); + } + attr &= 0x7f; + } + if (altattr) { + /* MDA-compatible attributes */ + if (blink) { + ibg = (attr & 0x80) ? 8 : 0; + bld = 0; + ol = (attr & 0x20) ? 1 : 0; + ul = (attr & 0x10) ? 1 : 0; + } else { + bld = (attr & 0x80) ? 1 : 0; + ibg = (attr & 0x40) ? 0x0F : 0; + ol = (attr & 0x20) ? 1 : 0; + ul = (attr & 0x10) ? 1 : 0; + } + } else { + /* CGA-compatible attributes */ + ibg = 0; + ifg = (attr >> 4) & 0x0F; + ol = 0; + ul = 0; + bld = 0; + } + if (ul) { + ull = incolor->crtc[INCOLOR_CRTC_UNDER] & 0x0F; + ulc = (incolor->crtc[INCOLOR_CRTC_UNDER] >> 4) & 0x0F; + if (ulc == 0) + ulc = 7; + } else { + ull = 0xFFFF; + } + if (ol) { + oll = incolor->crtc[INCOLOR_CRTC_OVER] & 0x0F; + olc = (incolor->crtc[INCOLOR_CRTC_OVER] >> 4) & 0x0F; + if (olc == 0) + olc = 7; + } else { + oll = 0xFFFF; + } - if (incolor->crtc[INCOLOR_CRTC_XMODE] & INCOLOR_XMODE_90COL) { - elg = 0; - } else { - elg = ((chr >= 0xc0) && (chr <= 0xdf)); - } - fnt = incolor->vram + 0x4000 + 16 * chr + 4096 * font + incolor->sc; + if (incolor->crtc[INCOLOR_CRTC_XMODE] & INCOLOR_XMODE_90COL) { + elg = 0; + } else { + elg = ((chr >= 0xc0) && (chr <= 0xdf)); + } + fnt = incolor->vram + 0x4000 + 16 * chr + 4096 * font + incolor->sc; - if (blk) { - /* Blinking, draw all background */ - val[0] = val[1] = val[2] = val[3] = 0x000; - } else if (incolor->sc == ull) { - /* Underscore, draw all foreground */ - val[0] = val[1] = val[2] = val[3] = 0x1ff; - } else { - val[0] = fnt[0x00000] << 1; - val[1] = fnt[0x10000] << 1; - val[2] = fnt[0x20000] << 1; - val[3] = fnt[0x30000] << 1; + if (blk) { + /* Blinking, draw all background */ + val[0] = val[1] = val[2] = val[3] = 0x000; + } else if (incolor->sc == ull) { + /* Underscore, draw all foreground */ + val[0] = val[1] = val[2] = val[3] = 0x1ff; + } else { + val[0] = fnt[0x00000] << 1; + val[1] = fnt[0x10000] << 1; + val[2] = fnt[0x20000] << 1; + val[3] = fnt[0x30000] << 1; - if (elg) { - val[0] |= (val[0] >> 1) & 1; - val[1] |= (val[1] >> 1) & 1; - val[2] |= (val[2] >> 1) & 1; - val[3] |= (val[3] >> 1) & 1; - } - if (bld) { - val[0] |= (val[0] >> 1); - val[1] |= (val[1] >> 1); - val[2] |= (val[2] >> 1); - val[3] |= (val[3] >> 1); - } - } - for (i = 0; i < cw; i++) { - /* Generate pixel colour */ - cfg = 0; - pmask = 1; - if (incolor->sc == oll) { - cfg = olc ^ ibg; /* Strikethrough */ - } else if (incolor->sc == ull) { - cfg = ulc ^ ibg; /* Underline */ - } else { - for (plane = 0; plane < 4; plane++, pmask = pmask << 1) { - if (val[plane] & 0x100) { - if (altattr) - cfg |= ((~ibg) & pmask); - else - cfg |= ((~ifg) & pmask); - } else if (altattr) - cfg |= (ibg & pmask); - } - } - if (palette) { - fg = incolor_rgb[incolor->palette[cfg]]; - } else { - fg = incolor_rgb[defpal[cfg]]; - } + if (elg) { + val[0] |= (val[0] >> 1) & 1; + val[1] |= (val[1] >> 1) & 1; + val[2] |= (val[2] >> 1) & 1; + val[3] |= (val[3] >> 1) & 1; + } + if (bld) { + val[0] |= (val[0] >> 1); + val[1] |= (val[1] >> 1); + val[2] |= (val[2] >> 1); + val[3] |= (val[3] >> 1); + } + } + for (i = 0; i < cw; i++) { + /* Generate pixel colour */ + cfg = 0; + pmask = 1; + if (incolor->sc == oll) { + cfg = olc ^ ibg; /* Strikethrough */ + } else if (incolor->sc == ull) { + cfg = ulc ^ ibg; /* Underline */ + } else { + for (plane = 0; plane < 4; plane++, pmask = pmask << 1) { + if (val[plane] & 0x100) { + if (altattr) + cfg |= ((~ibg) & pmask); + else + cfg |= ((~ifg) & pmask); + } else if (altattr) + cfg |= (ibg & pmask); + } + } + if (palette) { + fg = incolor_rgb[incolor->palette[cfg]]; + } else { + fg = incolor_rgb[defpal[cfg]]; + } - ((uint32_t *)buffer32->line[incolor->displine])[x * cw + i] = fg; - val[0] = val[0] << 1; - val[1] = val[1] << 1; - val[2] = val[2] << 1; - val[3] = val[3] << 1; - } + ((uint32_t *)buffer32->line[incolor->displine])[x * cw + i] = fg; + val[0] = val[0] << 1; + val[1] = val[1] << 1; + val[2] = val[2] << 1; + val[3] = val[3] << 1; + } } static void incolor_text_line(incolor_t *incolor, uint16_t ca) { - int drawcursor; - int x, c; - uint8_t chr, attr; - uint32_t col; + int drawcursor; + int x, c; + uint8_t chr, attr; + uint32_t col; - for (x = 0; x < incolor->crtc[1]; x++) { - chr = incolor->vram[(incolor->ma << 1) & 0x3fff]; - attr = incolor->vram[((incolor->ma << 1) + 1) & 0x3fff]; + for (x = 0; x < incolor->crtc[1]; x++) { + chr = incolor->vram[(incolor->ma << 1) & 0x3fff]; + attr = incolor->vram[((incolor->ma << 1) + 1) & 0x3fff]; - drawcursor = ((incolor->ma == ca) && incolor->con && incolor->cursoron); + drawcursor = ((incolor->ma == ca) && incolor->con && incolor->cursoron); - switch (incolor->crtc[INCOLOR_CRTC_XMODE] & 5) { - case 0: - case 4: /* ROM font */ - incolor_draw_char_rom(incolor, x, chr, attr); - break; - case 1: /* 4k RAMfont */ - incolor_draw_char_ram4(incolor, x, chr, attr); - break; - case 5: /* 48k RAMfont */ - incolor_draw_char_ram48(incolor, x, chr, attr); - break; + switch (incolor->crtc[INCOLOR_CRTC_XMODE] & 5) { + case 0: + case 4: /* ROM font */ + incolor_draw_char_rom(incolor, x, chr, attr); + break; + case 1: /* 4k RAMfont */ + incolor_draw_char_ram4(incolor, x, chr, attr); + break; + case 5: /* 48k RAMfont */ + incolor_draw_char_ram48(incolor, x, chr, attr); + break; + } + ++incolor->ma; + if (drawcursor) { + int cw = INCOLOR_CW; + uint8_t ink = incolor->crtc[INCOLOR_CRTC_EXCEPT] & INCOLOR_EXCEPT_CURSOR; + if (ink == 0) + ink = (attr & 0x08) | 7; - } - ++incolor->ma; - if (drawcursor) { - int cw = INCOLOR_CW; - uint8_t ink = incolor->crtc[INCOLOR_CRTC_EXCEPT] & INCOLOR_EXCEPT_CURSOR; - if (ink == 0) - ink = (attr & 0x08) | 7; - - /* In MDA-compatible mode, cursor brightness comes from - * background */ - if (incolor->crtc[INCOLOR_CRTC_EXCEPT] & INCOLOR_EXCEPT_ALTATTR) { - ink = (attr & 0x08) | (ink & 7); - } - if (incolor->crtc[INCOLOR_CRTC_EXCEPT] & INCOLOR_EXCEPT_PALETTE) { - col = incolor_rgb[incolor->palette[ink]]; - } else { - col = incolor_rgb[defpal[ink]]; - } - for (c = 0; c < cw; c++) { - ((uint32_t *)buffer32->line[incolor->displine])[x * cw + c] = col; - } - } - } + /* In MDA-compatible mode, cursor brightness comes from + * background */ + if (incolor->crtc[INCOLOR_CRTC_EXCEPT] & INCOLOR_EXCEPT_ALTATTR) { + ink = (attr & 0x08) | (ink & 7); + } + if (incolor->crtc[INCOLOR_CRTC_EXCEPT] & INCOLOR_EXCEPT_PALETTE) { + col = incolor_rgb[incolor->palette[ink]]; + } else { + col = incolor_rgb[defpal[ink]]; + } + for (c = 0; c < cw; c++) { + ((uint32_t *)buffer32->line[incolor->displine])[x * cw + c] = col; + } + } + } } static void incolor_graphics_line(incolor_t *incolor) { - uint8_t mask; - uint16_t ca; - int x, c, plane, col; - uint8_t ink; - uint16_t val[4]; + uint8_t mask; + uint16_t ca; + int x, c, plane, col; + uint8_t ink; + uint16_t val[4]; - /* Graphics mode. */ - ca = (incolor->sc & 3) * 0x2000; - if ((incolor->ctrl & INCOLOR_CTRL_PAGE1) && (incolor->ctrl2 & INCOLOR_CTRL2_PAGE1)) - ca += 0x8000; + /* Graphics mode. */ + ca = (incolor->sc & 3) * 0x2000; + if ((incolor->ctrl & INCOLOR_CTRL_PAGE1) && (incolor->ctrl2 & INCOLOR_CTRL2_PAGE1)) + ca += 0x8000; - for (x = 0; x < incolor->crtc[1]; x++) { - mask = incolor->crtc[INCOLOR_CRTC_MASK]; /* Planes to display */ - for (plane = 0; plane < 4; plane++, mask = mask >> 1) { - if (mask & 1) - val[plane] = (incolor->vram[((incolor->ma << 1) & 0x1fff) + ca + 0x10000 * plane] << 8) | - incolor->vram[((incolor->ma << 1) & 0x1fff) + ca + 0x10000 * plane + 1]; - else - val[plane] = 0; - } - incolor->ma++; - for (c = 0; c < 16; c++) { - ink = 0; - for (plane = 0; plane < 4; plane++) { - ink = ink >> 1; - if (val[plane] & 0x8000) - ink |= 8; - val[plane] = val[plane] << 1; - } - /* Is palette in use? */ - if (incolor->crtc[INCOLOR_CRTC_EXCEPT] & INCOLOR_EXCEPT_PALETTE) - col = incolor->palette[ink]; - else - col = defpal[ink]; + for (x = 0; x < incolor->crtc[1]; x++) { + mask = incolor->crtc[INCOLOR_CRTC_MASK]; /* Planes to display */ + for (plane = 0; plane < 4; plane++, mask = mask >> 1) { + if (mask & 1) + val[plane] = (incolor->vram[((incolor->ma << 1) & 0x1fff) + ca + 0x10000 * plane] << 8) | + incolor->vram[((incolor->ma << 1) & 0x1fff) + ca + 0x10000 * plane + 1]; + else + val[plane] = 0; + } + incolor->ma++; + for (c = 0; c < 16; c++) { + ink = 0; + for (plane = 0; plane < 4; plane++) { + ink = ink >> 1; + if (val[plane] & 0x8000) + ink |= 8; + val[plane] = val[plane] << 1; + } + /* Is palette in use? */ + if (incolor->crtc[INCOLOR_CRTC_EXCEPT] & INCOLOR_EXCEPT_PALETTE) + col = incolor->palette[ink]; + else + col = defpal[ink]; - ((uint32_t *)buffer32->line[incolor->displine])[(x << 4) + c] = incolor_rgb[col]; - } - } + ((uint32_t *)buffer32->line[incolor->displine])[(x << 4) + c] = incolor_rgb[col]; + } + } } void incolor_poll(void *p) { - incolor_t *incolor = (incolor_t *)p; - uint16_t ca = (incolor->crtc[15] | (incolor->crtc[14] << 8)) & 0x3fff; - int x; - int oldvc; - int oldsc; + incolor_t *incolor = (incolor_t *)p; + uint16_t ca = (incolor->crtc[15] | (incolor->crtc[14] << 8)) & 0x3fff; + int x; + int oldvc; + int oldsc; - if (!incolor->linepos) { -// pclog("InColor poll %i %i\n", incolor->vc, incolor->sc); - timer_advance_u64(&incolor->timer, incolor->dispofftime); - incolor->stat |= 1; - incolor->linepos = 1; - oldsc = incolor->sc; - if ((incolor->crtc[8] & 3) == 3) - incolor->sc = (incolor->sc << 1) & 7; - if (incolor->dispon) { - if (incolor->displine < incolor->firstline) { - incolor->firstline = incolor->displine; - video_wait_for_buffer(); - } - incolor->lastline = incolor->displine; - if ((incolor->ctrl & INCOLOR_CTRL_GRAPH) && (incolor->ctrl2 & INCOLOR_CTRL2_GRAPH)) { - incolor_graphics_line(incolor); - } else { - incolor_text_line(incolor, ca); - } - } - incolor->sc = oldsc; - if (incolor->vc == incolor->crtc[7] && !incolor->sc) { - incolor->stat |= 8; -// printf("VSYNC on %i %i\n",vc,sc); - } - incolor->displine++; - if (incolor->displine >= 500) - incolor->displine = 0; - } else { - timer_advance_u64(&incolor->timer, incolor->dispontime); - if (incolor->dispon) - incolor->stat &= ~1; - incolor->linepos = 0; - if (incolor->vsynctime) { - incolor->vsynctime--; - if (!incolor->vsynctime) { - incolor->stat &= ~8; -// printf("VSYNC off %i %i\n",vc,sc); - } - } - if (incolor->sc == (incolor->crtc[11] & 31) || ((incolor->crtc[8] & 3) == 3 && incolor->sc == ((incolor->crtc[11] & 31) >> 1))) { - incolor->con = 0; - incolor->coff = 1; - } - if (incolor->vadj) { - incolor->sc++; - incolor->sc &= 31; - incolor->ma = incolor->maback; - incolor->vadj--; - if (!incolor->vadj) { - incolor->dispon = 1; - incolor->ma = incolor->maback = (incolor->crtc[13] | (incolor->crtc[12] << 8)) & 0x3fff; - incolor->sc = 0; - } - } else if (incolor->sc == incolor->crtc[9] || ((incolor->crtc[8] & 3) == 3 && incolor->sc == (incolor->crtc[9] >> 1))) { - incolor->maback = incolor->ma; - incolor->sc = 0; - oldvc = incolor->vc; - incolor->vc++; - incolor->vc &= 127; - if (incolor->vc == incolor->crtc[6]) - incolor->dispon = 0; - if (oldvc == incolor->crtc[4]) { -// printf("Display over at %i\n",displine); - incolor->vc = 0; - incolor->vadj = incolor->crtc[5]; - if (!incolor->vadj) - incolor->dispon = 1; - if (!incolor->vadj) - incolor->ma = incolor->maback = (incolor->crtc[13] | (incolor->crtc[12] << 8)) & 0x3fff; - if ((incolor->crtc[10] & 0x60) == 0x20) - incolor->cursoron = 0; - else - incolor->cursoron = incolor->blink & 16; - } - if (incolor->vc == incolor->crtc[7]) { - incolor->dispon = 0; - incolor->displine = 0; - incolor->vsynctime = 16;//(crtcm[3]>>4)+1; - if (incolor->crtc[7]) { -// printf("Lastline %i Firstline %i %i\n",lastline,firstline,lastline-firstline); - if ((incolor->ctrl & INCOLOR_CTRL_GRAPH) && (incolor->ctrl2 & INCOLOR_CTRL2_GRAPH)) { - x = incolor->crtc[1] << 4; - } else { - x = incolor->crtc[1] * 9; - } - incolor->lastline++; - if (x != xsize || (incolor->lastline - incolor->firstline) != ysize) { - xsize = x; - ysize = incolor->lastline - incolor->firstline; -// printf("Resize to %i,%i - R1 %i\n",xsize,ysize,crtcm[1]); - if (xsize < 64) - xsize = 656; - if (ysize < 32) - ysize = 200; - updatewindowsize(xsize, ysize); - } + if (!incolor->linepos) { + // pclog("InColor poll %i %i\n", incolor->vc, incolor->sc); + timer_advance_u64(&incolor->timer, incolor->dispofftime); + incolor->stat |= 1; + incolor->linepos = 1; + oldsc = incolor->sc; + if ((incolor->crtc[8] & 3) == 3) + incolor->sc = (incolor->sc << 1) & 7; + if (incolor->dispon) { + if (incolor->displine < incolor->firstline) { + incolor->firstline = incolor->displine; + video_wait_for_buffer(); + } + incolor->lastline = incolor->displine; + if ((incolor->ctrl & INCOLOR_CTRL_GRAPH) && (incolor->ctrl2 & INCOLOR_CTRL2_GRAPH)) { + incolor_graphics_line(incolor); + } else { + incolor_text_line(incolor, ca); + } + } + incolor->sc = oldsc; + if (incolor->vc == incolor->crtc[7] && !incolor->sc) { + incolor->stat |= 8; + // printf("VSYNC on %i %i\n",vc,sc); + } + incolor->displine++; + if (incolor->displine >= 500) + incolor->displine = 0; + } else { + timer_advance_u64(&incolor->timer, incolor->dispontime); + if (incolor->dispon) + incolor->stat &= ~1; + incolor->linepos = 0; + if (incolor->vsynctime) { + incolor->vsynctime--; + if (!incolor->vsynctime) { + incolor->stat &= ~8; + // printf("VSYNC off %i %i\n",vc,sc); + } + } + if (incolor->sc == (incolor->crtc[11] & 31) || + ((incolor->crtc[8] & 3) == 3 && incolor->sc == ((incolor->crtc[11] & 31) >> 1))) { + incolor->con = 0; + incolor->coff = 1; + } + if (incolor->vadj) { + incolor->sc++; + incolor->sc &= 31; + incolor->ma = incolor->maback; + incolor->vadj--; + if (!incolor->vadj) { + incolor->dispon = 1; + incolor->ma = incolor->maback = (incolor->crtc[13] | (incolor->crtc[12] << 8)) & 0x3fff; + incolor->sc = 0; + } + } else if (incolor->sc == incolor->crtc[9] || + ((incolor->crtc[8] & 3) == 3 && incolor->sc == (incolor->crtc[9] >> 1))) { + incolor->maback = incolor->ma; + incolor->sc = 0; + oldvc = incolor->vc; + incolor->vc++; + incolor->vc &= 127; + if (incolor->vc == incolor->crtc[6]) + incolor->dispon = 0; + if (oldvc == incolor->crtc[4]) { + // printf("Display over at %i\n",displine); + incolor->vc = 0; + incolor->vadj = incolor->crtc[5]; + if (!incolor->vadj) + incolor->dispon = 1; + if (!incolor->vadj) + incolor->ma = incolor->maback = (incolor->crtc[13] | (incolor->crtc[12] << 8)) & 0x3fff; + if ((incolor->crtc[10] & 0x60) == 0x20) + incolor->cursoron = 0; + else + incolor->cursoron = incolor->blink & 16; + } + if (incolor->vc == incolor->crtc[7]) { + incolor->dispon = 0; + incolor->displine = 0; + incolor->vsynctime = 16; //(crtcm[3]>>4)+1; + if (incolor->crtc[7]) { + // printf("Lastline %i Firstline %i + // %i\n",lastline,firstline,lastline-firstline); + if ((incolor->ctrl & INCOLOR_CTRL_GRAPH) && (incolor->ctrl2 & INCOLOR_CTRL2_GRAPH)) { + x = incolor->crtc[1] << 4; + } else { + x = incolor->crtc[1] * 9; + } + incolor->lastline++; + if (x != xsize || (incolor->lastline - incolor->firstline) != ysize) { + xsize = x; + ysize = incolor->lastline - incolor->firstline; + // printf("Resize to %i,%i - R1 + // %i\n",xsize,ysize,crtcm[1]); + if (xsize < 64) + xsize = 656; + if (ysize < 32) + ysize = 200; + updatewindowsize(xsize, ysize); + } - video_blit_memtoscreen(0, incolor->firstline, 0, incolor->lastline - incolor->firstline, xsize, incolor->lastline - incolor->firstline); + video_blit_memtoscreen(0, incolor->firstline, 0, incolor->lastline - incolor->firstline, + xsize, incolor->lastline - incolor->firstline); - frames++; - if ((incolor->ctrl & INCOLOR_CTRL_GRAPH) && (incolor->ctrl2 & INCOLOR_CTRL2_GRAPH)) { - video_res_x = incolor->crtc[1] * 16; - video_res_y = incolor->crtc[6] * 4; - video_bpp = 1; - } else { - video_res_x = incolor->crtc[1]; - video_res_y = incolor->crtc[6]; - video_bpp = 0; - } - } - incolor->firstline = 1000; - incolor->lastline = 0; - incolor->blink++; - } - } else { - incolor->sc++; - incolor->sc &= 31; - incolor->ma = incolor->maback; - } - if ((incolor->sc == (incolor->crtc[10] & 31) || ((incolor->crtc[8] & 3) == 3 && incolor->sc == ((incolor->crtc[10] & 31) >> 1)))) { - incolor->con = 1; -// printf("Cursor on - %02X %02X %02X\n",crtcm[8],crtcm[10],crtcm[11]); - } - } + frames++; + if ((incolor->ctrl & INCOLOR_CTRL_GRAPH) && (incolor->ctrl2 & INCOLOR_CTRL2_GRAPH)) { + video_res_x = incolor->crtc[1] * 16; + video_res_y = incolor->crtc[6] * 4; + video_bpp = 1; + } else { + video_res_x = incolor->crtc[1]; + video_res_y = incolor->crtc[6]; + video_bpp = 0; + } + } + incolor->firstline = 1000; + incolor->lastline = 0; + incolor->blink++; + } + } else { + incolor->sc++; + incolor->sc &= 31; + incolor->ma = incolor->maback; + } + if ((incolor->sc == (incolor->crtc[10] & 31) || + ((incolor->crtc[8] & 3) == 3 && incolor->sc == ((incolor->crtc[10] & 31) >> 1)))) { + incolor->con = 1; + // printf("Cursor on - %02X %02X %02X\n",crtcm[8],crtcm[10],crtcm[11]); + } + } } void *incolor_init() { - int c; - incolor_t *incolor = malloc(sizeof(incolor_t)); - memset(incolor, 0, sizeof(incolor_t)); + int c; + incolor_t *incolor = malloc(sizeof(incolor_t)); + memset(incolor, 0, sizeof(incolor_t)); - incolor->vram = malloc(0x40000); /* 4 planes of 64k */ + incolor->vram = malloc(0x40000); /* 4 planes of 64k */ - timer_add(&incolor->timer, incolor_poll, incolor, 1); - mem_mapping_add(&incolor->mapping, 0xb0000, 0x08000, incolor_read, NULL, NULL, incolor_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, incolor); - io_sethandler(0x03b0, 0x0010, incolor_in, NULL, NULL, incolor_out, NULL, NULL, incolor); + timer_add(&incolor->timer, incolor_poll, incolor, 1); + mem_mapping_add(&incolor->mapping, 0xb0000, 0x08000, incolor_read, NULL, NULL, incolor_write, NULL, NULL, NULL, + MEM_MAPPING_EXTERNAL, incolor); + io_sethandler(0x03b0, 0x0010, incolor_in, NULL, NULL, incolor_out, NULL, NULL, incolor); - for (c = 0; c < 64; c++) { - incolor_rgb[c] = makecol32(init_rgb[c][0], init_rgb[c][1], init_rgb[c][2]); - } + for (c = 0; c < 64; c++) { + incolor_rgb[c] = makecol32(init_rgb[c][0], init_rgb[c][1], init_rgb[c][2]); + } -/* Initialise CRTC regs to safe values */ - incolor->crtc[INCOLOR_CRTC_MASK] = 0x0F; /* All planes displayed */ - incolor->crtc[INCOLOR_CRTC_RWCTRL] = INCOLOR_RWCTRL_POLARITY; - incolor->crtc[INCOLOR_CRTC_RWCOL] = 0x0F; /* White on black */ - incolor->crtc[INCOLOR_CRTC_EXCEPT] = INCOLOR_EXCEPT_ALTATTR; - for (c = 0; c < 16; c++) { - incolor->palette[c] = defpal[c]; - } - incolor->palette_idx = 0; + /* Initialise CRTC regs to safe values */ + incolor->crtc[INCOLOR_CRTC_MASK] = 0x0F; /* All planes displayed */ + incolor->crtc[INCOLOR_CRTC_RWCTRL] = INCOLOR_RWCTRL_POLARITY; + incolor->crtc[INCOLOR_CRTC_RWCOL] = 0x0F; /* White on black */ + incolor->crtc[INCOLOR_CRTC_EXCEPT] = INCOLOR_EXCEPT_ALTATTR; + for (c = 0; c < 16; c++) { + incolor->palette[c] = defpal[c]; + } + incolor->palette_idx = 0; - return incolor; + return incolor; } void incolor_close(void *p) { - incolor_t *incolor = (incolor_t *)p; + incolor_t *incolor = (incolor_t *)p; - free(incolor->vram); - free(incolor); + free(incolor->vram); + free(incolor); } void incolor_speed_changed(void *p) { - incolor_t *incolor = (incolor_t *)p; + incolor_t *incolor = (incolor_t *)p; - incolor_recalctimings(incolor); + incolor_recalctimings(incolor); } -device_t incolor_device = - { - "Hercules InColor", - 0, - incolor_init, - incolor_close, - NULL, - incolor_speed_changed, - NULL, - NULL - }; +device_t incolor_device = {"Hercules InColor", 0, incolor_init, incolor_close, NULL, incolor_speed_changed, NULL, NULL}; diff --git a/src/video/vid_mda.c b/src/video/vid_mda.c index 4e8a936c..6aba549b 100644 --- a/src/video/vid_mda.c +++ b/src/video/vid_mda.c @@ -13,310 +13,290 @@ static uint32_t mdacols[256][2][2]; void mda_recalctimings(mda_t *mda); void mda_out(uint16_t addr, uint8_t val, void *p) { - mda_t *mda = (mda_t *)p; - switch (addr) { - case 0x3b0: - case 0x3b2: - case 0x3b4: - case 0x3b6:mda->crtcreg = val & 31; - return; - case 0x3b1: - case 0x3b3: - case 0x3b5: - case 0x3b7:mda->crtc[mda->crtcreg] = val; - if (mda->crtc[10] == 6 && mda->crtc[11] == 7) /*Fix for Generic Turbo XT BIOS, which sets up cursor registers wrong*/ - { - mda->crtc[10] = 0xb; - mda->crtc[11] = 0xc; - } - mda_recalctimings(mda); - return; - case 0x3b8:mda->ctrl = val; - return; - } + mda_t *mda = (mda_t *)p; + switch (addr) { + case 0x3b0: + case 0x3b2: + case 0x3b4: + case 0x3b6: + mda->crtcreg = val & 31; + return; + case 0x3b1: + case 0x3b3: + case 0x3b5: + case 0x3b7: + mda->crtc[mda->crtcreg] = val; + if (mda->crtc[10] == 6 && + mda->crtc[11] == 7) /*Fix for Generic Turbo XT BIOS, which sets up cursor registers wrong*/ + { + mda->crtc[10] = 0xb; + mda->crtc[11] = 0xc; + } + mda_recalctimings(mda); + return; + case 0x3b8: + mda->ctrl = val; + return; + } } uint8_t mda_in(uint16_t addr, void *p) { - mda_t *mda = (mda_t *)p; - switch (addr) { - case 0x3b0: - case 0x3b2: - case 0x3b4: - case 0x3b6:return mda->crtcreg; - case 0x3b1: - case 0x3b3: - case 0x3b5: - case 0x3b7:return mda->crtc[mda->crtcreg]; - case 0x3ba:return mda->stat | 0xF0; - } - return 0xff; + mda_t *mda = (mda_t *)p; + switch (addr) { + case 0x3b0: + case 0x3b2: + case 0x3b4: + case 0x3b6: + return mda->crtcreg; + case 0x3b1: + case 0x3b3: + case 0x3b5: + case 0x3b7: + return mda->crtc[mda->crtcreg]; + case 0x3ba: + return mda->stat | 0xF0; + } + return 0xff; } void mda_write(uint32_t addr, uint8_t val, void *p) { - mda_t *mda = (mda_t *)p; - egawrites++; - mda->vram[addr & 0xfff] = val; + mda_t *mda = (mda_t *)p; + egawrites++; + mda->vram[addr & 0xfff] = val; } uint8_t mda_read(uint32_t addr, void *p) { - mda_t *mda = (mda_t *)p; - egareads++; - return mda->vram[addr & 0xfff]; + mda_t *mda = (mda_t *)p; + egareads++; + return mda->vram[addr & 0xfff]; } void mda_recalctimings(mda_t *mda) { - double _dispontime, _dispofftime, disptime; - disptime = mda->crtc[0] + 1; - _dispontime = mda->crtc[1]; - _dispofftime = disptime - _dispontime; - _dispontime *= MDACONST; - _dispofftime *= MDACONST; - mda->dispontime = (uint64_t)_dispontime; - mda->dispofftime = (uint64_t)_dispofftime; + double _dispontime, _dispofftime, disptime; + disptime = mda->crtc[0] + 1; + _dispontime = mda->crtc[1]; + _dispofftime = disptime - _dispontime; + _dispontime *= MDACONST; + _dispofftime *= MDACONST; + mda->dispontime = (uint64_t)_dispontime; + mda->dispofftime = (uint64_t)_dispofftime; } void mda_poll(void *p) { - mda_t *mda = (mda_t *)p; - uint16_t ca = (mda->crtc[15] | (mda->crtc[14] << 8)) & 0x3fff; - int drawcursor; - int x, c; - int oldvc; - uint8_t chr, attr; - int oldsc; - int blink; - if (!mda->linepos) { - timer_advance_u64(&mda->timer, mda->dispofftime); - mda->stat |= 1; - mda->linepos = 1; - oldsc = mda->sc; - if ((mda->crtc[8] & 3) == 3) - mda->sc = (mda->sc << 1) & 7; - if (mda->dispon) { - if (mda->displine < mda->firstline) { - mda->firstline = mda->displine; - video_wait_for_buffer(); - } - mda->lastline = mda->displine; - for (x = 0; x < mda->crtc[1]; x++) { - chr = mda->vram[(mda->ma << 1) & 0xfff]; - attr = mda->vram[((mda->ma << 1) + 1) & 0xfff]; - drawcursor = ((mda->ma == ca) && mda->con && mda->cursoron); - blink = ((mda->blink & 16) && (mda->ctrl & 0x20) && (attr & 0x80) && !drawcursor); - if (mda->sc == 12 && ((attr & 7) == 1)) { - for (c = 0; c < 9; c++) - ((uint32_t *)buffer32->line[mda->displine])[(x * 9) + c] = mdacols[attr][blink][1]; - } else { - for (c = 0; c < 8; c++) - ((uint32_t *)buffer32->line[mda->displine])[(x * 9) + c] = mdacols[attr][blink][(fontdatm[chr][mda->sc] & (1 << (c ^ 7))) ? 1 : 0]; - if ((chr & ~0x1f) == 0xc0) - ((uint32_t *)buffer32->line[mda->displine])[(x * 9) + 8] = mdacols[attr][blink][fontdatm[chr][mda->sc] & 1]; - else - ((uint32_t *)buffer32->line[mda->displine])[(x * 9) + 8] = mdacols[attr][blink][0]; - } - mda->ma++; - if (drawcursor) { - for (c = 0; c < 9; c++) - ((uint32_t *)buffer32->line[mda->displine])[(x * 9) + c] ^= mdacols[attr][0][1]; - } - } - } - mda->sc = oldsc; - if (mda->vc == mda->crtc[7] && !mda->sc) { - mda->stat |= 8; -// printf("VSYNC on %i %i\n",vc,sc); - } - mda->displine++; - if (mda->displine >= 500) - mda->displine = 0; - } else { - timer_advance_u64(&mda->timer, mda->dispontime); - if (mda->dispon) - mda->stat &= ~1; - mda->linepos = 0; - if (mda->vsynctime) { - mda->vsynctime--; - if (!mda->vsynctime) { - mda->stat &= ~8; -// printf("VSYNC off %i %i\n",vc,sc); - } - } - if (mda->sc == (mda->crtc[11] & 31) || ((mda->crtc[8] & 3) == 3 && mda->sc == ((mda->crtc[11] & 31) >> 1))) { - mda->con = 0; - mda->coff = 1; - } - if (mda->vadj) { - mda->sc++; - mda->sc &= 31; - mda->ma = mda->maback; - mda->vadj--; - if (!mda->vadj) { - mda->dispon = 1; - mda->ma = mda->maback = (mda->crtc[13] | (mda->crtc[12] << 8)) & 0x3fff; - mda->sc = 0; - } - } else if (mda->sc == mda->crtc[9] || ((mda->crtc[8] & 3) == 3 && mda->sc == (mda->crtc[9] >> 1))) { - mda->maback = mda->ma; - mda->sc = 0; - oldvc = mda->vc; - mda->vc++; - mda->vc &= 127; - if (mda->vc == mda->crtc[6]) - mda->dispon = 0; - if (oldvc == mda->crtc[4]) { -// printf("Display over at %i\n",displine); - mda->vc = 0; - mda->vadj = mda->crtc[5]; - if (!mda->vadj) - mda->dispon = 1; - if (!mda->vadj) - mda->ma = mda->maback = (mda->crtc[13] | (mda->crtc[12] << 8)) & 0x3fff; - if ((mda->crtc[10] & 0x60) == 0x20) - mda->cursoron = 0; - else - mda->cursoron = mda->blink & 16; - } - if (mda->vc == mda->crtc[7]) { - mda->dispon = 0; - mda->displine = 0; - mda->vsynctime = 16; - if (mda->crtc[7]) { -// printf("Lastline %i Firstline %i %i\n",lastline,firstline,lastline-firstline); - x = mda->crtc[1] * 9; - mda->lastline++; - if (x != xsize || (mda->lastline - mda->firstline) != ysize) { - xsize = x; - ysize = mda->lastline - mda->firstline; -// printf("Resize to %i,%i - R1 %i\n",xsize,ysize,crtcm[1]); - if (xsize < 64) - xsize = 656; - if (ysize < 32) - ysize = 200; - updatewindowsize(xsize, ysize); - } + mda_t *mda = (mda_t *)p; + uint16_t ca = (mda->crtc[15] | (mda->crtc[14] << 8)) & 0x3fff; + int drawcursor; + int x, c; + int oldvc; + uint8_t chr, attr; + int oldsc; + int blink; + if (!mda->linepos) { + timer_advance_u64(&mda->timer, mda->dispofftime); + mda->stat |= 1; + mda->linepos = 1; + oldsc = mda->sc; + if ((mda->crtc[8] & 3) == 3) + mda->sc = (mda->sc << 1) & 7; + if (mda->dispon) { + if (mda->displine < mda->firstline) { + mda->firstline = mda->displine; + video_wait_for_buffer(); + } + mda->lastline = mda->displine; + for (x = 0; x < mda->crtc[1]; x++) { + chr = mda->vram[(mda->ma << 1) & 0xfff]; + attr = mda->vram[((mda->ma << 1) + 1) & 0xfff]; + drawcursor = ((mda->ma == ca) && mda->con && mda->cursoron); + blink = ((mda->blink & 16) && (mda->ctrl & 0x20) && (attr & 0x80) && !drawcursor); + if (mda->sc == 12 && ((attr & 7) == 1)) { + for (c = 0; c < 9; c++) + ((uint32_t *)buffer32->line[mda->displine])[(x * 9) + c] = + mdacols[attr][blink][1]; + } else { + for (c = 0; c < 8; c++) + ((uint32_t *)buffer32->line[mda->displine])[(x * 9) + c] = + mdacols[attr][blink][(fontdatm[chr][mda->sc] & (1 << (c ^ 7))) ? 1 : 0]; + if ((chr & ~0x1f) == 0xc0) + ((uint32_t *)buffer32->line[mda->displine])[(x * 9) + 8] = + mdacols[attr][blink][fontdatm[chr][mda->sc] & 1]; + else + ((uint32_t *)buffer32->line[mda->displine])[(x * 9) + 8] = + mdacols[attr][blink][0]; + } + mda->ma++; + if (drawcursor) { + for (c = 0; c < 9; c++) + ((uint32_t *)buffer32->line[mda->displine])[(x * 9) + c] ^= mdacols[attr][0][1]; + } + } + } + mda->sc = oldsc; + if (mda->vc == mda->crtc[7] && !mda->sc) { + mda->stat |= 8; + // printf("VSYNC on %i %i\n",vc,sc); + } + mda->displine++; + if (mda->displine >= 500) + mda->displine = 0; + } else { + timer_advance_u64(&mda->timer, mda->dispontime); + if (mda->dispon) + mda->stat &= ~1; + mda->linepos = 0; + if (mda->vsynctime) { + mda->vsynctime--; + if (!mda->vsynctime) { + mda->stat &= ~8; + // printf("VSYNC off %i %i\n",vc,sc); + } + } + if (mda->sc == (mda->crtc[11] & 31) || ((mda->crtc[8] & 3) == 3 && mda->sc == ((mda->crtc[11] & 31) >> 1))) { + mda->con = 0; + mda->coff = 1; + } + if (mda->vadj) { + mda->sc++; + mda->sc &= 31; + mda->ma = mda->maback; + mda->vadj--; + if (!mda->vadj) { + mda->dispon = 1; + mda->ma = mda->maback = (mda->crtc[13] | (mda->crtc[12] << 8)) & 0x3fff; + mda->sc = 0; + } + } else if (mda->sc == mda->crtc[9] || ((mda->crtc[8] & 3) == 3 && mda->sc == (mda->crtc[9] >> 1))) { + mda->maback = mda->ma; + mda->sc = 0; + oldvc = mda->vc; + mda->vc++; + mda->vc &= 127; + if (mda->vc == mda->crtc[6]) + mda->dispon = 0; + if (oldvc == mda->crtc[4]) { + // printf("Display over at %i\n",displine); + mda->vc = 0; + mda->vadj = mda->crtc[5]; + if (!mda->vadj) + mda->dispon = 1; + if (!mda->vadj) + mda->ma = mda->maback = (mda->crtc[13] | (mda->crtc[12] << 8)) & 0x3fff; + if ((mda->crtc[10] & 0x60) == 0x20) + mda->cursoron = 0; + else + mda->cursoron = mda->blink & 16; + } + if (mda->vc == mda->crtc[7]) { + mda->dispon = 0; + mda->displine = 0; + mda->vsynctime = 16; + if (mda->crtc[7]) { + // printf("Lastline %i Firstline %i + // %i\n",lastline,firstline,lastline-firstline); + x = mda->crtc[1] * 9; + mda->lastline++; + if (x != xsize || (mda->lastline - mda->firstline) != ysize) { + xsize = x; + ysize = mda->lastline - mda->firstline; + // printf("Resize to %i,%i - R1 + // %i\n",xsize,ysize,crtcm[1]); + if (xsize < 64) + xsize = 656; + if (ysize < 32) + ysize = 200; + updatewindowsize(xsize, ysize); + } - video_blit_memtoscreen(0, mda->firstline, 0, ysize, xsize, ysize); + video_blit_memtoscreen(0, mda->firstline, 0, ysize, xsize, ysize); - frames++; - video_res_x = mda->crtc[1]; - video_res_y = mda->crtc[6]; - video_bpp = 0; - } - mda->firstline = 1000; - mda->lastline = 0; - mda->blink++; - } - } else { - mda->sc++; - mda->sc &= 31; - mda->ma = mda->maback; - } - if ((mda->sc == (mda->crtc[10] & 31) || ((mda->crtc[8] & 3) == 3 && mda->sc == ((mda->crtc[10] & 31) >> 1)))) { - mda->con = 1; -// printf("Cursor on - %02X %02X %02X\n",crtcm[8],crtcm[10],crtcm[11]); - } - } + frames++; + video_res_x = mda->crtc[1]; + video_res_y = mda->crtc[6]; + video_bpp = 0; + } + mda->firstline = 1000; + mda->lastline = 0; + mda->blink++; + } + } else { + mda->sc++; + mda->sc &= 31; + mda->ma = mda->maback; + } + if ((mda->sc == (mda->crtc[10] & 31) || ((mda->crtc[8] & 3) == 3 && mda->sc == ((mda->crtc[10] & 31) >> 1)))) { + mda->con = 1; + // printf("Cursor on - %02X %02X %02X\n",crtcm[8],crtcm[10],crtcm[11]); + } + } } void *mda_standalone_init() { - mda_t *mda = malloc(sizeof(mda_t)); + mda_t *mda = malloc(sizeof(mda_t)); - memset(mda, 0, sizeof(mda_t)); - mda_init(mda); + memset(mda, 0, sizeof(mda_t)); + mda_init(mda); - mda->vram = malloc(0x1000); - mem_mapping_add(&mda->mapping, 0xb0000, 0x08000, mda_read, NULL, NULL, mda_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, mda); - io_sethandler(0x03b0, 0x0010, mda_in, NULL, NULL, mda_out, NULL, NULL, mda); + mda->vram = malloc(0x1000); + mem_mapping_add(&mda->mapping, 0xb0000, 0x08000, mda_read, NULL, NULL, mda_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, + mda); + io_sethandler(0x03b0, 0x0010, mda_in, NULL, NULL, mda_out, NULL, NULL, mda); - return mda; + return mda; } void mda_init(mda_t *mda) { - int display_type; - int c; + int display_type; + int c; - display_type = device_get_config_int("display_type"); - cgapal_rebuild(display_type, 0); + display_type = device_get_config_int("display_type"); + cgapal_rebuild(display_type, 0); - for (c = 0; c < 256; c++) { - mdacols[c][0][0] = mdacols[c][1][0] = mdacols[c][1][1] = cgapal[0]; - if (c & 8) - mdacols[c][0][1] = cgapal[0xf]; - else - mdacols[c][0][1] = cgapal[0x7]; - } - mdacols[0x70][0][1] = cgapal[0]; - mdacols[0x70][0][0] = mdacols[0x70][1][0] = mdacols[0x70][1][1] = cgapal[0xf]; - mdacols[0xF0][0][1] = cgapal[0]; - mdacols[0xF0][0][0] = mdacols[0xF0][1][0] = mdacols[0xF0][1][1] = cgapal[0xf]; - mdacols[0x78][0][1] = cgapal[0x7]; - mdacols[0x78][0][0] = mdacols[0x78][1][0] = mdacols[0x78][1][1] = cgapal[0xf]; - mdacols[0xF8][0][1] = cgapal[0x7]; - mdacols[0xF8][0][0] = mdacols[0xF8][1][0] = mdacols[0xF8][1][1] = cgapal[0xf]; - mdacols[0x00][0][1] = mdacols[0x00][1][1] = cgapal[0]; - mdacols[0x08][0][1] = mdacols[0x08][1][1] = cgapal[0]; - mdacols[0x80][0][1] = mdacols[0x80][1][1] = cgapal[0]; - mdacols[0x88][0][1] = mdacols[0x88][1][1] = cgapal[0]; + for (c = 0; c < 256; c++) { + mdacols[c][0][0] = mdacols[c][1][0] = mdacols[c][1][1] = cgapal[0]; + if (c & 8) + mdacols[c][0][1] = cgapal[0xf]; + else + mdacols[c][0][1] = cgapal[0x7]; + } + mdacols[0x70][0][1] = cgapal[0]; + mdacols[0x70][0][0] = mdacols[0x70][1][0] = mdacols[0x70][1][1] = cgapal[0xf]; + mdacols[0xF0][0][1] = cgapal[0]; + mdacols[0xF0][0][0] = mdacols[0xF0][1][0] = mdacols[0xF0][1][1] = cgapal[0xf]; + mdacols[0x78][0][1] = cgapal[0x7]; + mdacols[0x78][0][0] = mdacols[0x78][1][0] = mdacols[0x78][1][1] = cgapal[0xf]; + mdacols[0xF8][0][1] = cgapal[0x7]; + mdacols[0xF8][0][0] = mdacols[0xF8][1][0] = mdacols[0xF8][1][1] = cgapal[0xf]; + mdacols[0x00][0][1] = mdacols[0x00][1][1] = cgapal[0]; + mdacols[0x08][0][1] = mdacols[0x08][1][1] = cgapal[0]; + mdacols[0x80][0][1] = mdacols[0x80][1][1] = cgapal[0]; + mdacols[0x88][0][1] = mdacols[0x88][1][1] = cgapal[0]; - timer_add(&mda->timer, mda_poll, mda, 1); + timer_add(&mda->timer, mda_poll, mda, 1); } -void mda_setcol(int chr, int blink, int fg, uint8_t cga_ink) { - mdacols[chr][blink][fg] = cgapal[cga_ink]; -} +void mda_setcol(int chr, int blink, int fg, uint8_t cga_ink) { mdacols[chr][blink][fg] = cgapal[cga_ink]; } void mda_close(void *p) { - mda_t *mda = (mda_t *)p; + mda_t *mda = (mda_t *)p; - free(mda->vram); - free(mda); + free(mda->vram); + free(mda); } void mda_speed_changed(void *p) { - mda_t *mda = (mda_t *)p; + mda_t *mda = (mda_t *)p; - mda_recalctimings(mda); + mda_recalctimings(mda); } -static device_config_t mda_config[] = - { - { - .name = "display_type", - .description = "Display type", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "Green", - .value = DISPLAY_GREEN - }, - { - .description = "Amber", - .value = DISPLAY_AMBER - }, - { - .description = "White", - .value = DISPLAY_WHITE - }, - { - .description = "" - } - }, - .default_int = DISPLAY_WHITE - }, - { - .type = -1 - } - }; +static device_config_t mda_config[] = {{.name = "display_type", + .description = "Display type", + .type = CONFIG_SELECTION, + .selection = {{.description = "Green", .value = DISPLAY_GREEN}, + {.description = "Amber", .value = DISPLAY_AMBER}, + {.description = "White", .value = DISPLAY_WHITE}, + {.description = ""}}, + .default_int = DISPLAY_WHITE}, + {.type = -1}}; -device_t mda_device = - { - "MDA", - 0, - mda_standalone_init, - mda_close, - NULL, - mda_speed_changed, - NULL, - NULL, - mda_config - }; +device_t mda_device = {"MDA", 0, mda_standalone_init, mda_close, NULL, mda_speed_changed, NULL, NULL, mda_config}; diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index ea26b3d2..e1f08fc4 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -21,202 +21,202 @@ #define WAKE_DELAY (100 * TIMER_USEC) /*100us*/ #define FIFO_ENTRIES (mystique->fifo_write_idx - mystique->fifo_read_idx) -#define FIFO_FULL ((mystique->fifo_write_idx - mystique->fifo_read_idx) >= (FIFO_SIZE-1)) -#define FIFO_EMPTY (mystique->fifo_read_idx == mystique->fifo_write_idx) +#define FIFO_FULL ((mystique->fifo_write_idx - mystique->fifo_read_idx) >= (FIFO_SIZE - 1)) +#define FIFO_EMPTY (mystique->fifo_read_idx == mystique->fifo_write_idx) #define FIFO_TYPE 0xff000000 #define FIFO_ADDR 0x00ffffff enum { - FIFO_INVALID = (0x00 << 24), - FIFO_WRITE_CTRL_BYTE = (0x01 << 24), - FIFO_WRITE_CTRL_LONG = (0x02 << 24), - FIFO_WRITE_ILOAD_LONG = (0x03 << 24) + FIFO_INVALID = (0x00 << 24), + FIFO_WRITE_CTRL_BYTE = (0x01 << 24), + FIFO_WRITE_CTRL_LONG = (0x02 << 24), + FIFO_WRITE_ILOAD_LONG = (0x03 << 24) }; typedef struct { - uint32_t addr_type; - uint32_t val; + uint32_t addr_type; + uint32_t val; } fifo_entry_t; enum { - MGA_2064W, /*Millennium*/ - MGA_1064SG /*Mystique*/ + MGA_2064W, /*Millennium*/ + MGA_1064SG /*Mystique*/ }; typedef struct mystique_t { - svga_t svga; + svga_t svga; - rom_t bios_rom; + rom_t bios_rom; - int type; + int type; - tvp3026_ramdac_t tvp3026; /*Millennium*/ + tvp3026_ramdac_t tvp3026; /*Millennium*/ - mem_mapping_t lfb_mapping; - mem_mapping_t ctrl_mapping; - mem_mapping_t iload_mapping; + mem_mapping_t lfb_mapping; + mem_mapping_t ctrl_mapping; + mem_mapping_t iload_mapping; - uint8_t pci_regs[256]; - uint8_t int_line; - int card; + uint8_t pci_regs[256]; + uint8_t int_line; + int card; - int vram_size; - uint32_t vram_mask, vram_mask_w, vram_mask_l; + int vram_size; + uint32_t vram_mask, vram_mask_w, vram_mask_l; - uint32_t lfb_base, ctrl_base, iload_base; + uint32_t lfb_base, ctrl_base, iload_base; - uint8_t crtcext_regs[6]; - int crtcext_idx; + uint8_t crtcext_regs[6]; + int crtcext_idx; - uint8_t xreg_regs[256]; - int xreg_idx; + uint8_t xreg_regs[256]; + int xreg_idx; - uint32_t ma_latch_old; + uint32_t ma_latch_old; - uint32_t maccess, mctlwtst; - uint32_t maccess_running; + uint32_t maccess, mctlwtst; + uint32_t maccess_running; - uint32_t status; + uint32_t status; - uint8_t xcurctrl; + uint8_t xcurctrl; - uint8_t xsyspllm, xsysplln, xsyspllp; - struct { - int m, n, p, s; - } xpixpll[3]; + uint8_t xsyspllm, xsysplln, xsyspllp; + struct { + int m, n, p, s; + } xpixpll[3]; - uint8_t xgenioctrl; - uint8_t xgeniodata; - uint8_t xmulctrl; - uint8_t xgenctrl; - uint8_t xmiscctrl; - uint8_t xpixclkctrl; - uint8_t xvrefctrl; - uint8_t xcolkeymskl, xcolkeymskh; - uint8_t xcolkeyl, xcolkeyh; - int xzoomctrl; - uint8_t xcrcbitsel; + uint8_t xgenioctrl; + uint8_t xgeniodata; + uint8_t xmulctrl; + uint8_t xgenctrl; + uint8_t xmiscctrl; + uint8_t xpixclkctrl; + uint8_t xvrefctrl; + uint8_t xcolkeymskl, xcolkeymskh; + uint8_t xcolkeyl, xcolkeyh; + int xzoomctrl; + uint8_t xcrcbitsel; - uint8_t ien; + uint8_t ien; - struct { - uint8_t funcnt, stylelen; - int xoff, yoff; + struct { + uint8_t funcnt, stylelen; + int xoff, yoff; - uint16_t cxleft, cxright; - int16_t fxleft, fxright; - uint16_t length; + uint16_t cxleft, cxright; + int16_t fxleft, fxright; + uint16_t length; - uint32_t dwgctrl; - uint32_t dwgctrl_running; - uint32_t bcol, fcol; - uint32_t pitch; - uint32_t plnwt; - uint32_t ybot; - uint32_t ydstorg; - uint32_t ytop; - int selline; + uint32_t dwgctrl; + uint32_t dwgctrl_running; + uint32_t bcol, fcol; + uint32_t pitch; + uint32_t plnwt; + uint32_t ybot; + uint32_t ydstorg; + uint32_t ytop; + int selline; - uint32_t src[4]; - uint32_t ar[7]; - uint32_t dr[16]; + uint32_t src[4]; + uint32_t ar[7]; + uint32_t dr[16]; - int pattern[8][8]; + int pattern[8][8]; - struct { - int sdydxl; - int scanleft; - int sdxl; - int sdy; - int sdxr; - } sgn; + struct { + int sdydxl; + int scanleft; + int sdxl; + int sdy; + int sdxr; + } sgn; - uint32_t tmr[9]; - uint32_t texorg, texwidth, texheight; - uint32_t texctl, textrans; - uint32_t zorg; + uint32_t tmr[9]; + uint32_t texorg, texwidth, texheight; + uint32_t texctl, textrans; + uint32_t zorg; - int ydst; - uint32_t ydst_lin; + int ydst; + uint32_t ydst_lin; - int length_cur; - int16_t xdst; - uint32_t src_addr; - uint32_t z_base; + int length_cur; + int16_t xdst; + uint32_t src_addr; + uint32_t z_base; - int iload_rem_count; - uint32_t iload_rem_data; - int idump_end_of_line; + int iload_rem_count; + uint32_t iload_rem_data; + int idump_end_of_line; - int words; + int words; - int ta_key, ta_mask; + int ta_key, ta_mask; - int lastpix_r, lastpix_g, lastpix_b; + int lastpix_r, lastpix_g, lastpix_b; - int highv_line; - uint32_t highv_data; + int highv_line; + uint32_t highv_data; - int beta; + int beta; - int dither; + int dither; - uint8_t dmamod; - } dwgreg; + uint8_t dmamod; + } dwgreg; - struct { - uint8_t r, g, b; - } lut[256]; + struct { + uint8_t r, g, b; + } lut[256]; - struct { - uint16_t pos_x, pos_y; - uint16_t addr; - uint32_t col[3]; - } cursor; + struct { + uint16_t pos_x, pos_y; + uint16_t addr; + uint32_t col[3]; + } cursor; - uint8_t dmamod, dmadatasiz, dirdatasiz; - struct { - uint32_t primaddress, primend; - uint32_t secaddress, secend; + uint8_t dmamod, dmadatasiz, dirdatasiz; + struct { + uint32_t primaddress, primend; + uint32_t secaddress, secend; - int pri_pos, sec_pos, iload_pos; - uint32_t pri_header, sec_header, iload_header; + int pri_pos, sec_pos, iload_pos; + uint32_t pri_header, sec_header, iload_header; - int pri_state, sec_state, iload_state; + int pri_state, sec_state, iload_state; - int state; + int state; - mutex_t *lock; -// pc_timer_t timer; - } dma; + mutex_t *lock; + // pc_timer_t timer; + } dma; - uint8_t dmamap[16]; + uint8_t dmamap[16]; - volatile int busy; - volatile int blitter_submit_refcount; - volatile int blitter_submit_dma_refcount; - volatile int blitter_complete_refcount; + volatile int busy; + volatile int blitter_submit_refcount; + volatile int blitter_submit_dma_refcount; + volatile int blitter_complete_refcount; - volatile int endprdmasts_pending; - volatile int softrap_pending; - uint32_t softrap_pending_val; + volatile int endprdmasts_pending; + volatile int softrap_pending; + uint32_t softrap_pending_val; - pc_timer_t softrap_pending_timer; + pc_timer_t softrap_pending_timer; - uint64_t blitter_time; - uint64_t status_time; + uint64_t blitter_time; + uint64_t status_time; - int pixel_count, trap_count; + int pixel_count, trap_count; - fifo_entry_t fifo[FIFO_SIZE]; - volatile int fifo_read_idx, fifo_write_idx; + fifo_entry_t fifo[FIFO_SIZE]; + volatile int fifo_read_idx, fifo_write_idx; - thread_t *fifo_thread; - event_t *wake_fifo_thread; - event_t *fifo_not_full_event; + thread_t *fifo_thread; + event_t *wake_fifo_thread; + event_t *fifo_not_full_event; - pc_timer_t wake_timer; + pc_timer_t wake_timer; } mystique_t; static void mystique_start_blit(mystique_t *mystique); @@ -233,305 +233,211 @@ static void mystique_writeb_linear(uint32_t addr, uint8_t val, void *p); static void mystique_writew_linear(uint32_t addr, uint16_t val, void *p); static void mystique_writel_linear(uint32_t addr, uint32_t val, void *p); -static const uint8_t trans_masks[16][16] = - { - { - 1, 1, 1, 1, - 1, 1, 1, 1, - 1, 1, 1, 1, - 1, 1, 1, 1 - }, - { - 1, 0, 1, 0, - 0, 1, 0, 1, - 1, 0, 1, 0, - 0, 1, 0, 1 - }, - { - 0, 1, 0, 1, - 1, 0, 1, 0, - 0, 1, 0, 1, - 1, 0, 1, 0 - }, - { - 1, 0, 1, 0, - 0, 0, 0, 0, - 1, 0, 1, 0, - 0, 0, 0, 0 - }, - { - 0, 1, 0, 1, - 0, 0, 0, 0, - 0, 1, 0, 1, - 0, 0, 0, 0 - }, - { - 0, 0, 0, 0, - 1, 0, 1, 0, - 0, 0, 0, 0, - 1, 0, 1, 0 - }, - { - 0, 0, 0, 0, - 0, 1, 0, 1, - 0, 0, 0, 0, - 0, 1, 0, 1 - }, - { - 1, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 0 - }, - { - 0, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 1 - }, - { - 0, 0, 0, 1, - 0, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 0, 0 - }, - { - 0, 0, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 0, - 1, 0, 0, 0 - }, - { - 0, 0, 0, 0, - 1, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 1, 0 - }, - { - 0, 1, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 1, - 0, 0, 0, 0 - }, - { - 0, 0, 0, 0, - 0, 0, 0, 1, - 0, 0, 0, 0, - 0, 1, 0, 0 - }, - { - 0, 0, 1, 0, - 0, 0, 0, 0, - 1, 0, 0, 0, - 0, 0, 0, 0 - }, - { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0 - } - }; +static const uint8_t trans_masks[16][16] = { + {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, {1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1}, + {0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0}, {1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0}, + {0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0}, {0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0}, + {0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1}, {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, {0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}, + {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0}, + {0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}; static int8_t dither5[256][2][2]; static int8_t dither6[256][2][2]; -enum { - DMA_STATE_IDLE = 0, - DMA_STATE_PRI, - DMA_STATE_SEC -}; +enum { DMA_STATE_IDLE = 0, DMA_STATE_PRI, DMA_STATE_SEC }; #define DMA_POLL_TIME_US 100 /*100us*/ -#define DMA_MAX_WORDS 256 /*256 quad words per 100us poll*/ +#define DMA_MAX_WORDS 256 /*256 quad words per 100us poll*/ /*These registers are also mirrored into 0x1dxx, with the mirrored versions starting the blitter*/ -#define REG_DWGCTL 0x1c00 -#define REG_MACCESS 0x1c04 -#define REG_MCTLWTST 0x1c08 -#define REG_ZORG 0x1c0c -#define REG_PAT0 0x1c10 -#define REG_PAT1 0x1c14 -#define REG_PLNWT 0x1c1c -#define REG_BCOL 0x1c20 -#define REG_FCOL 0x1c24 -#define REG_SRC0 0x1c30 -#define REG_SRC1 0x1c34 -#define REG_SRC2 0x1c38 -#define REG_SRC3 0x1c3c -#define REG_XYSTRT 0x1c40 -#define REG_XYEND 0x1c44 -#define REG_SHIFT 0x1c50 -#define REG_DMAPAD 0x1c54 -#define REG_SGN 0x1c58 -#define REG_LEN 0x1c5c -#define REG_AR0 0x1c60 -#define REG_AR1 0x1c64 -#define REG_AR2 0x1c68 -#define REG_AR3 0x1c6c -#define REG_AR4 0x1c70 -#define REG_AR5 0x1c74 -#define REG_AR6 0x1c78 -#define REG_CXBNDRY 0x1c80 -#define REG_FXBNDRY 0x1c84 -#define REG_YDSTLEN 0x1c88 -#define REG_PITCH 0x1c8c -#define REG_YDST 0x1c90 -#define REG_YDSTORG 0x1c94 -#define REG_YTOP 0x1c98 -#define REG_YBOT 0x1c9c -#define REG_CXLEFT 0x1ca0 -#define REG_CXRIGHT 0x1ca4 -#define REG_FXLEFT 0x1ca8 -#define REG_FXRIGHT 0x1cac -#define REG_XDST 0x1cb0 -#define REG_DR0 0x1cc0 -#define REG_DR2 0x1cc8 -#define REG_DR3 0x1ccc -#define REG_DR4 0x1cd0 -#define REG_DR6 0x1cd8 -#define REG_DR7 0x1cdc -#define REG_DR8 0x1ce0 -#define REG_DR10 0x1ce8 -#define REG_DR11 0x1cec -#define REG_DR12 0x1cf0 -#define REG_DR14 0x1cf8 -#define REG_DR15 0x1cfc +#define REG_DWGCTL 0x1c00 +#define REG_MACCESS 0x1c04 +#define REG_MCTLWTST 0x1c08 +#define REG_ZORG 0x1c0c +#define REG_PAT0 0x1c10 +#define REG_PAT1 0x1c14 +#define REG_PLNWT 0x1c1c +#define REG_BCOL 0x1c20 +#define REG_FCOL 0x1c24 +#define REG_SRC0 0x1c30 +#define REG_SRC1 0x1c34 +#define REG_SRC2 0x1c38 +#define REG_SRC3 0x1c3c +#define REG_XYSTRT 0x1c40 +#define REG_XYEND 0x1c44 +#define REG_SHIFT 0x1c50 +#define REG_DMAPAD 0x1c54 +#define REG_SGN 0x1c58 +#define REG_LEN 0x1c5c +#define REG_AR0 0x1c60 +#define REG_AR1 0x1c64 +#define REG_AR2 0x1c68 +#define REG_AR3 0x1c6c +#define REG_AR4 0x1c70 +#define REG_AR5 0x1c74 +#define REG_AR6 0x1c78 +#define REG_CXBNDRY 0x1c80 +#define REG_FXBNDRY 0x1c84 +#define REG_YDSTLEN 0x1c88 +#define REG_PITCH 0x1c8c +#define REG_YDST 0x1c90 +#define REG_YDSTORG 0x1c94 +#define REG_YTOP 0x1c98 +#define REG_YBOT 0x1c9c +#define REG_CXLEFT 0x1ca0 +#define REG_CXRIGHT 0x1ca4 +#define REG_FXLEFT 0x1ca8 +#define REG_FXRIGHT 0x1cac +#define REG_XDST 0x1cb0 +#define REG_DR0 0x1cc0 +#define REG_DR2 0x1cc8 +#define REG_DR3 0x1ccc +#define REG_DR4 0x1cd0 +#define REG_DR6 0x1cd8 +#define REG_DR7 0x1cdc +#define REG_DR8 0x1ce0 +#define REG_DR10 0x1ce8 +#define REG_DR11 0x1cec +#define REG_DR12 0x1cf0 +#define REG_DR14 0x1cf8 +#define REG_DR15 0x1cfc -#define REG_FIFOSTATUS 0x1e10 -#define REG_STATUS 0x1e14 -#define REG_ICLEAR 0x1e18 -#define REG_IEN 0x1e1c -#define REG_VCOUNT 0x1e20 -#define REG_DMAMAP 0x1e30 -#define REG_RST 0x1e40 -#define REG_OPMODE 0x1e54 -#define REG_PRIMADDRESS 0x1e58 -#define REG_PRIMEND 0x1e5c +#define REG_FIFOSTATUS 0x1e10 +#define REG_STATUS 0x1e14 +#define REG_ICLEAR 0x1e18 +#define REG_IEN 0x1e1c +#define REG_VCOUNT 0x1e20 +#define REG_DMAMAP 0x1e30 +#define REG_RST 0x1e40 +#define REG_OPMODE 0x1e54 +#define REG_PRIMADDRESS 0x1e58 +#define REG_PRIMEND 0x1e5c #define REG_DWG_INDIR_WT 0x1e80 -#define REG_ATTR_IDX 0x1fc0 -#define REG_ATTR_DATA 0x1fc1 -#define REG_INSTS0 0x1fc2 -#define REG_MISC 0x1fc2 -#define REG_SEQ_IDX 0x1fc4 -#define REG_SEQ_DATA 0x1fc5 -#define REG_MISCREAD 0x1fcc -#define REG_GCTL_IDX 0x1fce -#define REG_GCTL_DATA 0x1fcf -#define REG_CRTC_IDX 0x1fd4 -#define REG_CRTC_DATA 0x1fd5 -#define REG_INSTS1 0x1fda -#define REG_CRTCEXT_IDX 0x1fde +#define REG_ATTR_IDX 0x1fc0 +#define REG_ATTR_DATA 0x1fc1 +#define REG_INSTS0 0x1fc2 +#define REG_MISC 0x1fc2 +#define REG_SEQ_IDX 0x1fc4 +#define REG_SEQ_DATA 0x1fc5 +#define REG_MISCREAD 0x1fcc +#define REG_GCTL_IDX 0x1fce +#define REG_GCTL_DATA 0x1fcf +#define REG_CRTC_IDX 0x1fd4 +#define REG_CRTC_DATA 0x1fd5 +#define REG_INSTS1 0x1fda +#define REG_CRTCEXT_IDX 0x1fde #define REG_CRTCEXT_DATA 0x1fdf -#define REG_CACHEFLUSH 0x1fff +#define REG_CACHEFLUSH 0x1fff /*Mystique only*/ -#define REG_TMR0 0x2c00 -#define REG_TMR1 0x2c04 -#define REG_TMR2 0x2c08 -#define REG_TMR3 0x2c0c -#define REG_TMR4 0x2c10 -#define REG_TMR5 0x2c14 -#define REG_TMR6 0x2c18 -#define REG_TMR7 0x2c1c -#define REG_TMR8 0x2c20 -#define REG_TEXORG 0x2c24 -#define REG_TEXWIDTH 0x2c28 -#define REG_TEXHEIGHT 0x2c2c -#define REG_TEXCTL 0x2c30 -#define REG_TEXTRANS 0x2c34 -#define REG_SECADDRESS 0x2c40 -#define REG_SECEND 0x2c44 -#define REG_SOFTRAP 0x2c48 +#define REG_TMR0 0x2c00 +#define REG_TMR1 0x2c04 +#define REG_TMR2 0x2c08 +#define REG_TMR3 0x2c0c +#define REG_TMR4 0x2c10 +#define REG_TMR5 0x2c14 +#define REG_TMR6 0x2c18 +#define REG_TMR7 0x2c1c +#define REG_TMR8 0x2c20 +#define REG_TEXORG 0x2c24 +#define REG_TEXWIDTH 0x2c28 +#define REG_TEXHEIGHT 0x2c2c +#define REG_TEXCTL 0x2c30 +#define REG_TEXTRANS 0x2c34 +#define REG_SECADDRESS 0x2c40 +#define REG_SECEND 0x2c44 +#define REG_SOFTRAP 0x2c48 /*Mystique only*/ -#define REG_PALWTADD 0x3c00 -#define REG_PALDATA 0x3c01 -#define REG_PIXRDMSK 0x3c02 -#define REG_PALRDADD 0x3c03 -#define REG_X_DATAREG 0x3c0a -#define REG_CURPOSX 0x3c0c -#define REG_CURPOSY 0x3c0e +#define REG_PALWTADD 0x3c00 +#define REG_PALDATA 0x3c01 +#define REG_PIXRDMSK 0x3c02 +#define REG_PALRDADD 0x3c03 +#define REG_X_DATAREG 0x3c0a +#define REG_CURPOSX 0x3c0c +#define REG_CURPOSY 0x3c0e #define REG_STATUS_VSYNCSTS (1 << 3) #define CRTCX_R0_STARTADD_MASK (0xf << 0) -#define CRTCX_R0_OFFSET_MASK (3 << 4) +#define CRTCX_R0_OFFSET_MASK (3 << 4) -#define CRTCX_R1_HTOTAL8 (1 << 0) +#define CRTCX_R1_HTOTAL8 (1 << 0) -#define CRTCX_R2_VTOTAL10 (1 << 0) -#define CRTCX_R2_VTOTAL11 (1 << 1) -#define CRTCX_R2_VDISPEND10 (1 << 2) -#define CRTCX_R2_VBLKSTR10 (1 << 3) -#define CRTCX_R2_VBLKSTR11 (1 << 4) -#define CRTCX_R2_VSYNCSTR10 (1 << 5) -#define CRTCX_R2_VSYNCSTR11 (1 << 6) -#define CRTCX_R2_LINECOMP10 (1 << 7) +#define CRTCX_R2_VTOTAL10 (1 << 0) +#define CRTCX_R2_VTOTAL11 (1 << 1) +#define CRTCX_R2_VDISPEND10 (1 << 2) +#define CRTCX_R2_VBLKSTR10 (1 << 3) +#define CRTCX_R2_VBLKSTR11 (1 << 4) +#define CRTCX_R2_VSYNCSTR10 (1 << 5) +#define CRTCX_R2_VSYNCSTR11 (1 << 6) +#define CRTCX_R2_LINECOMP10 (1 << 7) #define CRTCX_R3_MGAMODE (1 << 7) -#define XREG_XCURADDL 0x04 -#define XREG_XCURADDH 0x05 -#define XREG_XCURCTRL 0x06 +#define XREG_XCURADDL 0x04 +#define XREG_XCURADDH 0x05 +#define XREG_XCURCTRL 0x06 -#define XREG_XCURCOL0R 0x08 -#define XREG_XCURCOL0G 0x09 -#define XREG_XCURCOL0B 0x0a +#define XREG_XCURCOL0R 0x08 +#define XREG_XCURCOL0G 0x09 +#define XREG_XCURCOL0B 0x0a -#define XREG_XCURCOL1R 0x0c -#define XREG_XCURCOL1G 0x0d -#define XREG_XCURCOL1B 0x0e +#define XREG_XCURCOL1R 0x0c +#define XREG_XCURCOL1G 0x0d +#define XREG_XCURCOL1B 0x0e -#define XREG_XCURCOL2R 0x10 -#define XREG_XCURCOL2G 0x11 -#define XREG_XCURCOL2B 0x12 +#define XREG_XCURCOL2R 0x10 +#define XREG_XCURCOL2G 0x11 +#define XREG_XCURCOL2B 0x12 -#define XREG_XVREFCTRL 0x18 -#define XREG_XMULCTRL 0x19 +#define XREG_XVREFCTRL 0x18 +#define XREG_XMULCTRL 0x19 #define XREG_XPIXCLKCTRL 0x1a -#define XREG_XGENCTRL 0x1d -#define XREG_XMISCCTRL 0x1e +#define XREG_XGENCTRL 0x1d +#define XREG_XMISCCTRL 0x1e -#define XREG_XGENIOCTRL 0x2a -#define XREG_XGENIODATA 0x2b +#define XREG_XGENIOCTRL 0x2a +#define XREG_XGENIODATA 0x2b -#define XREG_XSYSPLLM 0x2c -#define XREG_XSYSPLLN 0x2d -#define XREG_XSYSPLLP 0x2e +#define XREG_XSYSPLLM 0x2c +#define XREG_XSYSPLLN 0x2d +#define XREG_XSYSPLLP 0x2e #define XREG_XSYSPLLSTAT 0x2f -#define XREG_XZOOMCTRL 0x38 +#define XREG_XZOOMCTRL 0x38 -#define XREG_XSENSETEST 0x3a +#define XREG_XSENSETEST 0x3a -#define XREG_XCRCREML 0x3c -#define XREG_XCRCREMH 0x3d -#define XREG_XCRCBITSEL 0x3e +#define XREG_XCRCREML 0x3c +#define XREG_XCRCREMH 0x3d +#define XREG_XCRCBITSEL 0x3e #define XREG_XCOLKEYMSKL 0x40 #define XREG_XCOLKEYMSKH 0x41 -#define XREG_XCOLKEYL 0x42 -#define XREG_XCOLKEYH 0x43 +#define XREG_XCOLKEYL 0x42 +#define XREG_XCOLKEYH 0x43 -#define XREG_XPIXPLLCM 0x4c -#define XREG_XPIXPLLCN 0x4d -#define XREG_XPIXPLLCP 0x4e +#define XREG_XPIXPLLCM 0x4c +#define XREG_XPIXPLLCN 0x4d +#define XREG_XPIXPLLCP 0x4e #define XREG_XPIXPLLSTAT 0x4f #define XMISCCTRL_VGA8DAC (1 << 3) -#define XMULCTRL_DEPTH_MASK (7 << 0) -#define XMULCTRL_DEPTH_8 (0 << 0) -#define XMULCTRL_DEPTH_15 (1 << 0) -#define XMULCTRL_DEPTH_16 (2 << 0) -#define XMULCTRL_DEPTH_24 (3 << 0) +#define XMULCTRL_DEPTH_MASK (7 << 0) +#define XMULCTRL_DEPTH_8 (0 << 0) +#define XMULCTRL_DEPTH_15 (1 << 0) +#define XMULCTRL_DEPTH_16 (2 << 0) +#define XMULCTRL_DEPTH_24 (3 << 0) #define XMULCTRL_DEPTH_32_OVERLAYED (4 << 0) -#define XMULCTRL_DEPTH_2G8V16 (5 << 0) -#define XMULCTRL_DEPTH_G16V16 (6 << 0) -#define XMULCTRL_DEPTH_32 (7 << 0) +#define XMULCTRL_DEPTH_2G8V16 (5 << 0) +#define XMULCTRL_DEPTH_G16V16 (6 << 0) +#define XMULCTRL_DEPTH_32 (7 << 0) #define XSYSPLLSTAT_SYSLOCK (1 << 6) @@ -539,126 +445,126 @@ enum { #define XCURCTRL_CURMODE_MASK (3 << 0) #define XCURCTRL_CURMODE_3COL (1 << 0) -#define XCURCTRL_CURMODE_XGA (2 << 0) +#define XCURCTRL_CURMODE_XGA (2 << 0) #define XCURCTRL_CURMODE_XWIN (3 << 0) -#define DWGCTRL_OPCODE_MASK (0xf << 0) -#define DWGCTRL_OPCODE_LINE_OPEN (0x0 << 0) -#define DWGCTRL_OPCODE_AUTOLINE_OPEN (0x1 << 0) -#define DWGCTRL_OPCODE_LINE_CLOSE (0x2 << 0) +#define DWGCTRL_OPCODE_MASK (0xf << 0) +#define DWGCTRL_OPCODE_LINE_OPEN (0x0 << 0) +#define DWGCTRL_OPCODE_AUTOLINE_OPEN (0x1 << 0) +#define DWGCTRL_OPCODE_LINE_CLOSE (0x2 << 0) #define DWGCTRL_OPCODE_AUTOLINE_CLOSE (0x3 << 0) -#define DWGCTRL_OPCODE_TRAP (0x4 << 0) -#define DWGCTRL_OPCODE_TEXTURE_TRAP (0x6 << 0) -#define DWGCTRL_OPCODE_ILOAD_HIGH (0x7 << 0) -#define DWGCTRL_OPCODE_BITBLT (0x8 << 0) -#define DWGCTRL_OPCODE_ILOAD (0x9 << 0) -#define DWGCTRL_OPCODE_IDUMP (0xa << 0) -#define DWGCTRL_OPCODE_FBITBLT (0xc << 0) -#define DWGCTRL_OPCODE_ILOAD_SCALE (0xd << 0) -#define DWGCTRL_OPCODE_ILOAD_HIGHV (0xe << 0) -#define DWGCTRL_ATYPE_MASK (7 << 4) -#define DWGCTRL_ATYPE_RPL (0 << 4) -#define DWGCTRL_ATYPE_RSTR (1 << 4) -#define DWGCTRL_ATYPE_ZI (3 << 4) -#define DWGCTRL_ATYPE_BLK (4 << 4) -#define DWGCTRL_ATYPE_I (7 << 4) -#define DWGCTRL_LINEAR (1 << 7) -#define DWGCTRL_ZMODE_MASK (7 << 8) -#define DWGCTRL_ZMODE_NOZCMP (0 << 8) -#define DWGCTRL_ZMODE_ZE (2 << 8) -#define DWGCTRL_ZMODE_ZNE (3 << 8) -#define DWGCTRL_ZMODE_ZLT (4 << 8) -#define DWGCTRL_ZMODE_ZLTE (5 << 8) -#define DWGCTRL_ZMODE_ZGT (6 << 8) -#define DWGCTRL_ZMODE_ZGTE (7 << 8) -#define DWGCTRL_SOLID (1 << 11) -#define DWGCTRL_ARZERO (1 << 12) -#define DWGCTRL_SGNZERO (1 << 13) -#define DWGCTRL_SHTZERO (1 << 14) -#define DWGCTRL_BOP_MASK (0xf << 16) -#define DWGCTRL_TRANS_SHIFT (20) -#define DWGCTRL_TRANS_MASK (0xf << DWGCTRL_TRANS_SHIFT) -#define DWGCTRL_BLTMOD_MASK (0xf << 25) +#define DWGCTRL_OPCODE_TRAP (0x4 << 0) +#define DWGCTRL_OPCODE_TEXTURE_TRAP (0x6 << 0) +#define DWGCTRL_OPCODE_ILOAD_HIGH (0x7 << 0) +#define DWGCTRL_OPCODE_BITBLT (0x8 << 0) +#define DWGCTRL_OPCODE_ILOAD (0x9 << 0) +#define DWGCTRL_OPCODE_IDUMP (0xa << 0) +#define DWGCTRL_OPCODE_FBITBLT (0xc << 0) +#define DWGCTRL_OPCODE_ILOAD_SCALE (0xd << 0) +#define DWGCTRL_OPCODE_ILOAD_HIGHV (0xe << 0) +#define DWGCTRL_ATYPE_MASK (7 << 4) +#define DWGCTRL_ATYPE_RPL (0 << 4) +#define DWGCTRL_ATYPE_RSTR (1 << 4) +#define DWGCTRL_ATYPE_ZI (3 << 4) +#define DWGCTRL_ATYPE_BLK (4 << 4) +#define DWGCTRL_ATYPE_I (7 << 4) +#define DWGCTRL_LINEAR (1 << 7) +#define DWGCTRL_ZMODE_MASK (7 << 8) +#define DWGCTRL_ZMODE_NOZCMP (0 << 8) +#define DWGCTRL_ZMODE_ZE (2 << 8) +#define DWGCTRL_ZMODE_ZNE (3 << 8) +#define DWGCTRL_ZMODE_ZLT (4 << 8) +#define DWGCTRL_ZMODE_ZLTE (5 << 8) +#define DWGCTRL_ZMODE_ZGT (6 << 8) +#define DWGCTRL_ZMODE_ZGTE (7 << 8) +#define DWGCTRL_SOLID (1 << 11) +#define DWGCTRL_ARZERO (1 << 12) +#define DWGCTRL_SGNZERO (1 << 13) +#define DWGCTRL_SHTZERO (1 << 14) +#define DWGCTRL_BOP_MASK (0xf << 16) +#define DWGCTRL_TRANS_SHIFT (20) +#define DWGCTRL_TRANS_MASK (0xf << DWGCTRL_TRANS_SHIFT) +#define DWGCTRL_BLTMOD_MASK (0xf << 25) #define DWGCTRL_BLTMOD_BMONOLEF (0x0 << 25) -#define DWGCTRL_BLTMOD_BFCOL (0x2 << 25) -#define DWGCTRL_BLTMOD_BMONOWF (0x4 << 25) -#define DWGCTRL_BLTMOD_BU32RGB (0x7 << 25) -#define DWGCTRL_BLTMOD_BUYUV (0xe << 25) -#define DWGCTRL_BLTMOD_BU24RGB (0xf << 25) -#define DWGCTRL_PATTERN (1 << 29) -#define DWGCTRL_TRANSC (1 << 30) +#define DWGCTRL_BLTMOD_BFCOL (0x2 << 25) +#define DWGCTRL_BLTMOD_BMONOWF (0x4 << 25) +#define DWGCTRL_BLTMOD_BU32RGB (0x7 << 25) +#define DWGCTRL_BLTMOD_BUYUV (0xe << 25) +#define DWGCTRL_BLTMOD_BU24RGB (0xf << 25) +#define DWGCTRL_PATTERN (1 << 29) +#define DWGCTRL_TRANSC (1 << 30) #define BOP(x) ((x) << 16) -#define MACCESS_PWIDTH_MASK (3 << 0) -#define MACCESS_PWIDTH_8 (0 << 0) -#define MACCESS_PWIDTH_16 (1 << 0) -#define MACCESS_PWIDTH_32 (2 << 0) -#define MACCESS_PWIDTH_24 (3 << 0) -#define MACCESS_TLUTLOAD (1 << 29) -#define MACCESS_NODITHER (1 << 30) -#define MACCESS_DIT555 (1 << 31) +#define MACCESS_PWIDTH_MASK (3 << 0) +#define MACCESS_PWIDTH_8 (0 << 0) +#define MACCESS_PWIDTH_16 (1 << 0) +#define MACCESS_PWIDTH_32 (2 << 0) +#define MACCESS_PWIDTH_24 (3 << 0) +#define MACCESS_TLUTLOAD (1 << 29) +#define MACCESS_NODITHER (1 << 30) +#define MACCESS_DIT555 (1 << 31) -#define PITCH_MASK 0x7e0 -#define PITCH_YLIN (1 << 15) +#define PITCH_MASK 0x7e0 +#define PITCH_YLIN (1 << 15) -#define SGN_SDYDXL (1 << 0) +#define SGN_SDYDXL (1 << 0) #define SGN_SCANLEFT (1 << 0) -#define SGN_SDXL (1 << 1) -#define SGN_SDY (1 << 2) -#define SGN_SDXR (1 << 5) +#define SGN_SDXL (1 << 1) +#define SGN_SDY (1 << 2) +#define SGN_SDXR (1 << 5) -#define DMA_ADDR_MASK 0xfffffffc -#define DMA_MODE_MASK 3 +#define DMA_ADDR_MASK 0xfffffffc +#define DMA_MODE_MASK 3 -#define DMA_MODE_REG 0 -#define DMA_MODE_BLIT 1 +#define DMA_MODE_REG 0 +#define DMA_MODE_BLIT 1 #define DMA_MODE_VECTOR 2 -#define STATUS_SOFTRAPEN (1 << 0) -#define STATUS_VSYNCPEN (1 << 4) -#define STATUS_VLINEPEN (1 << 5) -#define STATUS_DWGENGSTS (1 << 16) +#define STATUS_SOFTRAPEN (1 << 0) +#define STATUS_VSYNCPEN (1 << 4) +#define STATUS_VLINEPEN (1 << 5) +#define STATUS_DWGENGSTS (1 << 16) #define STATUS_ENDPRDMASTS (1 << 17) #define ICLEAR_SOFTRAPICLR (1 << 0) -#define ICLEAR_VLINEICLR (1 << 5) +#define ICLEAR_VLINEICLR (1 << 5) -#define IEN_SOFTRAPEN (1 << 0) +#define IEN_SOFTRAPEN (1 << 0) #define TEXCTL_TEXFORMAT_MASK (7 << 0) -#define TEXCTL_TEXFORMAT_TW4 (0 << 0) -#define TEXCTL_TEXFORMAT_TW8 (1 << 0) +#define TEXCTL_TEXFORMAT_TW4 (0 << 0) +#define TEXCTL_TEXFORMAT_TW8 (1 << 0) #define TEXCTL_TEXFORMAT_TW15 (2 << 0) #define TEXCTL_TEXFORMAT_TW16 (3 << 0) #define TEXCTL_TEXFORMAT_TW12 (4 << 0) -#define TEXCTL_PALSEL_MASK (0xf << 4) -#define TEXCTL_TPITCH_SHIFT (16) -#define TEXCTL_TPITCH_MASK (7 << TEXCTL_TPITCH_SHIFT) -#define TEXCTL_NPCEN (1 << 21) -#define TEXCTL_DECALCKEY (1 << 24) -#define TEXCTL_TAKEY (1 << 25) -#define TEXCTL_TAMASK (1 << 26) -#define TEXCTL_CLAMPV (1 << 27) -#define TEXCTL_CLAMPU (1 << 28) -#define TEXCTL_TMODULATE (1 << 29) -#define TEXCTL_STRANS (1 << 30) -#define TEXCTL_ITRANS (1 << 31) +#define TEXCTL_PALSEL_MASK (0xf << 4) +#define TEXCTL_TPITCH_SHIFT (16) +#define TEXCTL_TPITCH_MASK (7 << TEXCTL_TPITCH_SHIFT) +#define TEXCTL_NPCEN (1 << 21) +#define TEXCTL_DECALCKEY (1 << 24) +#define TEXCTL_TAKEY (1 << 25) +#define TEXCTL_TAMASK (1 << 26) +#define TEXCTL_CLAMPV (1 << 27) +#define TEXCTL_CLAMPU (1 << 28) +#define TEXCTL_TMODULATE (1 << 29) +#define TEXCTL_STRANS (1 << 30) +#define TEXCTL_ITRANS (1 << 31) -#define TEXHEIGHT_TH_MASK (0x3f << 0) +#define TEXHEIGHT_TH_MASK (0x3f << 0) #define TEXHEIGHT_THMASK_SHIFT (18) -#define TEXHEIGHT_THMASK_MASK (0x7ff << TEXHEIGHT_THMASK_SHIFT) +#define TEXHEIGHT_THMASK_MASK (0x7ff << TEXHEIGHT_THMASK_SHIFT) -#define TEXWIDTH_TW_MASK (0x3f << 0) -#define TEXWIDTH_TWMASK_SHIFT (18) -#define TEXWIDTH_TWMASK_MASK (0x7ff << TEXWIDTH_TWMASK_SHIFT) +#define TEXWIDTH_TW_MASK (0x3f << 0) +#define TEXWIDTH_TWMASK_SHIFT (18) +#define TEXWIDTH_TWMASK_MASK (0x7ff << TEXWIDTH_TWMASK_SHIFT) #define TEXTRANS_TCKEY_MASK (0xffff) #define TEXTRANS_TKMASK_SHIFT (16) #define TEXTRANS_TKMASK_MASK (0xffff << TEXTRANS_TKMASK_SHIFT) -#define DITHER_565 0 +#define DITHER_565 0 #define DITHER_NONE_565 1 -#define DITHER_555 2 +#define DITHER_555 2 #define DITHER_NONE_555 3 /*PCI configuration registers*/ @@ -676,1903 +582,2182 @@ static uint32_t blit_idump_read(mystique_t *mystique); static void blit_iload_write(mystique_t *mystique, uint32_t data, int size); void mystique_out(uint16_t addr, uint8_t val, void *p) { - mystique_t *mystique = (mystique_t *)p; - svga_t *svga = &mystique->svga; - uint8_t old; + mystique_t *mystique = (mystique_t *)p; + svga_t *svga = &mystique->svga; + uint8_t old; - if ((((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && addr < 0x3de) && !(svga->miscout & 1)) - addr ^= 0x60; // mono / color addr selection + if ((((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && addr < 0x3de) && !(svga->miscout & 1)) + addr ^= 0x60; // mono / color addr selection -// pclog("mystique_out : %04X %02X\n", addr, val); -// pclog(" %04X:%04X\n", CS,cpu_state.pc); - switch (addr) { - case 0x3c8:mystique->xreg_idx = val; - case 0x3c6: - case 0x3c7: - case 0x3c9: - if (mystique->type == MGA_2064W) { - tvp3026_ramdac_out(addr & 3, val, &mystique->tvp3026, svga); - return; - } - break; + // pclog("mystique_out : %04X %02X\n", addr, val); + // pclog(" %04X:%04X\n", CS,cpu_state.pc); + switch (addr) { + case 0x3c8: + mystique->xreg_idx = val; + case 0x3c6: + case 0x3c7: + case 0x3c9: + if (mystique->type == MGA_2064W) { + tvp3026_ramdac_out(addr & 3, val, &mystique->tvp3026, svga); + return; + } + break; - case 0x3cf: - if ((svga->gdcaddr & 15) == 6 && svga->gdcreg[6] != val) { - svga->gdcreg[svga->gdcaddr & 15] = val; - mystique_recalc_mapping(mystique); - return; - } - break; + case 0x3cf: + if ((svga->gdcaddr & 15) == 6 && svga->gdcreg[6] != val) { + svga->gdcreg[svga->gdcaddr & 15] = val; + mystique_recalc_mapping(mystique); + return; + } + break; - case 0x3D4:svga->crtcreg = val & 0x3f; - return; - case 0x3D5: -// if (svga->crtcreg == 0xc) -// pclog("Buffer swap\n"); - if (((svga->crtcreg & 0x3f) < 7) && (svga->crtc[0x11] & 0x80)) - return; - if (((svga->crtcreg & 0x3f) == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); - old = svga->crtc[svga->crtcreg & 0x3f]; - svga->crtc[svga->crtcreg & 0x3f] = val; - if (old != val) { - if ((svga->crtcreg & 0x3f) < 0xE || (svga->crtcreg & 0x3f) > 0x10) { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - if (svga->crtcreg == 0x11) { - if (!(val & 0x10)) - mystique->status &= ~STATUS_VSYNCPEN; - mystique_update_irqs(mystique); - } - } - break; + case 0x3D4: + svga->crtcreg = val & 0x3f; + return; + case 0x3D5: + // if (svga->crtcreg == 0xc) + // pclog("Buffer swap\n"); + if (((svga->crtcreg & 0x3f) < 7) && (svga->crtc[0x11] & 0x80)) + return; + if (((svga->crtcreg & 0x3f) == 7) && (svga->crtc[0x11] & 0x80)) + val = (svga->crtc[7] & ~0x10) | (val & 0x10); + old = svga->crtc[svga->crtcreg & 0x3f]; + svga->crtc[svga->crtcreg & 0x3f] = val; + if (old != val) { + if ((svga->crtcreg & 0x3f) < 0xE || (svga->crtcreg & 0x3f) > 0x10) { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } + if (svga->crtcreg == 0x11) { + if (!(val & 0x10)) + mystique->status &= ~STATUS_VSYNCPEN; + mystique_update_irqs(mystique); + } + } + break; - case 0x3de:mystique->crtcext_idx = val; - break; - case 0x3df: - if (mystique->crtcext_idx < 6) - mystique->crtcext_regs[mystique->crtcext_idx] = val; - if (mystique->crtcext_idx < 4) { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - if (mystique->crtcext_idx == 3) { - if (val & CRTCX_R3_MGAMODE) - svga->fb_only = 1; - else - svga->fb_only = 0; - svga_recalctimings(svga); + case 0x3de: + mystique->crtcext_idx = val; + break; + case 0x3df: + if (mystique->crtcext_idx < 6) + mystique->crtcext_regs[mystique->crtcext_idx] = val; + if (mystique->crtcext_idx < 4) { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } + if (mystique->crtcext_idx == 3) { + if (val & CRTCX_R3_MGAMODE) + svga->fb_only = 1; + else + svga->fb_only = 0; + svga_recalctimings(svga); -// pclog("Write CRTCX[3]=%02x\n", val); - } - if (mystique->crtcext_idx == 4) { - if (svga->gdcreg[6] & 0xc) { - /*64k banks*/ - svga->read_bank = (val & 0x7f) << 16; - svga->write_bank = (val & 0x7f) << 16; - } else { - /*128k banks*/ - svga->read_bank = (val & 0x7e) << 16; - svga->write_bank = (val & 0x7e) << 16; - } -// pclog("Write CRTCX[4]=%02x %08x\n", val, svga->read_bank); - } - break; - - } - svga_out(addr, val, svga); + // pclog("Write CRTCX[3]=%02x\n", val); + } + if (mystique->crtcext_idx == 4) { + if (svga->gdcreg[6] & 0xc) { + /*64k banks*/ + svga->read_bank = (val & 0x7f) << 16; + svga->write_bank = (val & 0x7f) << 16; + } else { + /*128k banks*/ + svga->read_bank = (val & 0x7e) << 16; + svga->write_bank = (val & 0x7e) << 16; + } + // pclog("Write CRTCX[4]=%02x %08x\n", val, svga->read_bank); + } + break; + } + svga_out(addr, val, svga); } uint8_t mystique_in(uint16_t addr, void *p) { - mystique_t *mystique = (mystique_t *)p; - svga_t *svga = &mystique->svga; - uint8_t temp = 0xff; + mystique_t *mystique = (mystique_t *)p; + svga_t *svga = &mystique->svga; + uint8_t temp = 0xff; - if ((((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && addr < 0x3de) && !(svga->miscout & 1)) - addr ^= 0x60; // mono / color addr selection + if ((((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && addr < 0x3de) && !(svga->miscout & 1)) + addr ^= 0x60; // mono / color addr selection -// if (addr != 0x3da && addr != 0x3ba) pclog("mystique_in : %04X ", addr); + // if (addr != 0x3da && addr != 0x3ba) pclog("mystique_in : %04X ", addr); - switch (addr) { - case 0x3c1: - if (svga->attraddr >= 0x15) - temp = 0; - else - temp = svga->attrregs[svga->attraddr]; - break; + switch (addr) { + case 0x3c1: + if (svga->attraddr >= 0x15) + temp = 0; + else + temp = svga->attrregs[svga->attraddr]; + break; - case 0x3c6: - case 0x3c7: - case 0x3c8: - case 0x3c9: - if (mystique->type == MGA_2064W) - temp = tvp3026_ramdac_in(addr & 3, &mystique->tvp3026, svga); - else - temp = svga_in(addr, svga); - break; + case 0x3c6: + case 0x3c7: + case 0x3c8: + case 0x3c9: + if (mystique->type == MGA_2064W) + temp = tvp3026_ramdac_in(addr & 3, &mystique->tvp3026, svga); + else + temp = svga_in(addr, svga); + break; - case 0x3D4:temp = svga->crtcreg; - break; - case 0x3D5: - if ((svga->crtcreg >= 0x19 && svga->crtcreg <= 0x21) || - svga->crtcreg == 0x23 || svga->crtcreg == 0x25 || svga->crtcreg >= 0x27) - temp = 0; - else - temp = svga->crtc[svga->crtcreg & 0x3f]; - break; + case 0x3D4: + temp = svga->crtcreg; + break; + case 0x3D5: + if ((svga->crtcreg >= 0x19 && svga->crtcreg <= 0x21) || svga->crtcreg == 0x23 || svga->crtcreg == 0x25 || + svga->crtcreg >= 0x27) + temp = 0; + else + temp = svga->crtc[svga->crtcreg & 0x3f]; + break; - case 0x3de:temp = mystique->crtcext_idx; - break; - case 0x3df: - if (mystique->crtcext_idx < 6) - temp = mystique->crtcext_regs[mystique->crtcext_idx]; - break; + case 0x3de: + temp = mystique->crtcext_idx; + break; + case 0x3df: + if (mystique->crtcext_idx < 6) + temp = mystique->crtcext_regs[mystique->crtcext_idx]; + break; - default:temp = svga_in(addr, svga); - break; - } + default: + temp = svga_in(addr, svga); + break; + } -// if (addr != 0x3da && addr != 0x3ba) pclog("%02X\n", temp); - return temp; + // if (addr != 0x3da && addr != 0x3ba) pclog("%02X\n", temp); + return temp; } static int mystique_line_compare(svga_t *svga) { - mystique_t *mystique = (mystique_t *)svga->p; + mystique_t *mystique = (mystique_t *)svga->p; - mystique->status |= STATUS_VLINEPEN; - mystique_update_irqs(mystique); + mystique->status |= STATUS_VLINEPEN; + mystique_update_irqs(mystique); - return 0; + return 0; } static void mystique_vsync_callback(svga_t *svga) { - mystique_t *mystique = (mystique_t *)svga->p; - - if (svga->crtc[0x11] & 0x10) { - mystique->status |= STATUS_VSYNCPEN; - mystique_update_irqs(mystique); - } + mystique_t *mystique = (mystique_t *)svga->p; + if (svga->crtc[0x11] & 0x10) { + mystique->status |= STATUS_VSYNCPEN; + mystique_update_irqs(mystique); + } } void mystique_recalctimings(svga_t *svga) { - mystique_t *mystique = (mystique_t *)svga->p; - int clk_sel = (svga->miscout >> 2) & 3; + mystique_t *mystique = (mystique_t *)svga->p; + int clk_sel = (svga->miscout >> 2) & 3; - if (clk_sel & 2) { - if (mystique->type == MGA_1064SG) { - int m = mystique->xpixpll[2].m; - int n = mystique->xpixpll[2].n; - int p = mystique->xpixpll[2].p; + if (clk_sel & 2) { + if (mystique->type == MGA_1064SG) { + int m = mystique->xpixpll[2].m; + int n = mystique->xpixpll[2].n; + int p = mystique->xpixpll[2].p; - double fvco = 14318181.0 * (n + 1) / (m + 1); - double fo = fvco / (p + 1); + double fvco = 14318181.0 * (n + 1) / (m + 1); + double fo = fvco / (p + 1); - svga->clock = (cpuclock * (float)(1ull << 32)) / fo; - } else { - svga->clock = (cpuclock * (float)(1ull << 32)) / tvp3026_getclock(&mystique->tvp3026); - } - } + svga->clock = (cpuclock * (float)(1ull << 32)) / fo; + } else { + svga->clock = (cpuclock * (float)(1ull << 32)) / tvp3026_getclock(&mystique->tvp3026); + } + } - if (mystique->crtcext_regs[1] & CRTCX_R1_HTOTAL8) - svga->htotal += 0x100; - if (mystique->crtcext_regs[2] & CRTCX_R2_VTOTAL10) - svga->vtotal += 0x400; - if (mystique->crtcext_regs[2] & CRTCX_R2_VTOTAL11) - svga->vtotal += 0x800; - if (mystique->crtcext_regs[2] & CRTCX_R2_VDISPEND10) - svga->dispend += 0x400; - if (mystique->crtcext_regs[2] & CRTCX_R2_VBLKSTR10) - svga->vblankstart += 0x400; - if (mystique->crtcext_regs[2] & CRTCX_R2_VBLKSTR11) - svga->vblankstart += 0x800; - if (mystique->crtcext_regs[2] & CRTCX_R2_VSYNCSTR10) - svga->vsyncstart += 0x400; - if (mystique->crtcext_regs[2] & CRTCX_R2_VSYNCSTR11) - svga->vsyncstart += 0x800; - if (mystique->crtcext_regs[2] & CRTCX_R2_LINECOMP10) - svga->split += 0x400; -// pclog("svga->split=%i\n", svga->split); + if (mystique->crtcext_regs[1] & CRTCX_R1_HTOTAL8) + svga->htotal += 0x100; + if (mystique->crtcext_regs[2] & CRTCX_R2_VTOTAL10) + svga->vtotal += 0x400; + if (mystique->crtcext_regs[2] & CRTCX_R2_VTOTAL11) + svga->vtotal += 0x800; + if (mystique->crtcext_regs[2] & CRTCX_R2_VDISPEND10) + svga->dispend += 0x400; + if (mystique->crtcext_regs[2] & CRTCX_R2_VBLKSTR10) + svga->vblankstart += 0x400; + if (mystique->crtcext_regs[2] & CRTCX_R2_VBLKSTR11) + svga->vblankstart += 0x800; + if (mystique->crtcext_regs[2] & CRTCX_R2_VSYNCSTR10) + svga->vsyncstart += 0x400; + if (mystique->crtcext_regs[2] & CRTCX_R2_VSYNCSTR11) + svga->vsyncstart += 0x800; + if (mystique->crtcext_regs[2] & CRTCX_R2_LINECOMP10) + svga->split += 0x400; + // pclog("svga->split=%i\n", svga->split); - if (mystique->crtcext_regs[3] & CRTCX_R3_MGAMODE) { - svga->packed_chain4 = 1; + if (mystique->crtcext_regs[3] & CRTCX_R3_MGAMODE) { + svga->packed_chain4 = 1; -// svga->split = 99999; - svga->lowres = 0; - svga->char_width = 8; - svga->hdisp = (svga->crtc[1] + 1) * 8; - svga->hdisp_time = svga->hdisp; - svga->rowoffset = svga->crtc[0x13] | ((mystique->crtcext_regs[0] & CRTCX_R0_OFFSET_MASK) << 4); - svga->ma_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) | - (svga->crtc[0xc] << 8) | svga->crtc[0xd]; - if (mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8)) { - svga->rowoffset *= 2; - svga->ma_latch *= 2; - } + // svga->split = 99999; + svga->lowres = 0; + svga->char_width = 8; + svga->hdisp = (svga->crtc[1] + 1) * 8; + svga->hdisp_time = svga->hdisp; + svga->rowoffset = svga->crtc[0x13] | ((mystique->crtcext_regs[0] & CRTCX_R0_OFFSET_MASK) << 4); + svga->ma_latch = + ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) | (svga->crtc[0xc] << 8) | svga->crtc[0xd]; + if (mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8)) { + svga->rowoffset *= 2; + svga->ma_latch *= 2; + } - if (mystique->type == MGA_1064SG) { - /*Mystique, unlike most SVGA cards, allows display start to take + if (mystique->type == MGA_1064SG) { + /*Mystique, unlike most SVGA cards, allows display start to take effect mid-screen*/ - if (svga->ma_latch != mystique->ma_latch_old) { -// pclog("ma_latch change: old=%08x new=%08x ma=%08x ", mystique->ma_latch_old, svga->ma_latch, svga->maback); - svga->ma = svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2); -// pclog("ma_new=%08x\n", svga->maback); - mystique->ma_latch_old = svga->ma_latch; - } - switch (mystique->xmulctrl & XMULCTRL_DEPTH_MASK) { - case XMULCTRL_DEPTH_8: - case XMULCTRL_DEPTH_2G8V16:svga->render = svga_render_8bpp_highres; - svga->bpp = 8; - break; - case XMULCTRL_DEPTH_15: - case XMULCTRL_DEPTH_G16V16:svga->render = svga_render_15bpp_highres; - svga->bpp = 15; - break; - case XMULCTRL_DEPTH_16:svga->render = svga_render_16bpp_highres; - svga->bpp = 15; - break; - case XMULCTRL_DEPTH_24:svga->render = svga_render_24bpp_highres; - svga->bpp = 24; - break; - case XMULCTRL_DEPTH_32: - case XMULCTRL_DEPTH_32_OVERLAYED:svga->render = svga_render_32bpp_highres; - svga->bpp = 32; - break; - } - } else { - switch (svga->bpp) { - case 8:svga->render = svga_render_8bpp_highres; - break; - case 15:svga->render = svga_render_15bpp_highres; - break; - case 16:svga->render = svga_render_16bpp_highres; - break; - case 24:svga->render = svga_render_24bpp_highres; - break; - case 32:svga->render = svga_render_32bpp_highres; - break; - } - } - svga->video_bpp = svga->bpp; + if (svga->ma_latch != mystique->ma_latch_old) { + // pclog("ma_latch change: old=%08x new=%08x ma=%08x ", + // mystique->ma_latch_old, svga->ma_latch, svga->maback); + svga->ma = svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2); + // pclog("ma_new=%08x\n", svga->maback); + mystique->ma_latch_old = svga->ma_latch; + } + switch (mystique->xmulctrl & XMULCTRL_DEPTH_MASK) { + case XMULCTRL_DEPTH_8: + case XMULCTRL_DEPTH_2G8V16: + svga->render = svga_render_8bpp_highres; + svga->bpp = 8; + break; + case XMULCTRL_DEPTH_15: + case XMULCTRL_DEPTH_G16V16: + svga->render = svga_render_15bpp_highres; + svga->bpp = 15; + break; + case XMULCTRL_DEPTH_16: + svga->render = svga_render_16bpp_highres; + svga->bpp = 15; + break; + case XMULCTRL_DEPTH_24: + svga->render = svga_render_24bpp_highres; + svga->bpp = 24; + break; + case XMULCTRL_DEPTH_32: + case XMULCTRL_DEPTH_32_OVERLAYED: + svga->render = svga_render_32bpp_highres; + svga->bpp = 32; + break; + } + } else { + switch (svga->bpp) { + case 8: + svga->render = svga_render_8bpp_highres; + break; + case 15: + svga->render = svga_render_15bpp_highres; + break; + case 16: + svga->render = svga_render_16bpp_highres; + break; + case 24: + svga->render = svga_render_24bpp_highres; + break; + case 32: + svga->render = svga_render_32bpp_highres; + break; + } + } + svga->video_bpp = svga->bpp; - svga->line_compare = mystique_line_compare; -// pclog("recalc: htotal=%i vtotal=%i dispend=%i\n", svga->htotal, svga->vtotal, svga->dispend); - } else { - svga->packed_chain4 = 0; + svga->line_compare = mystique_line_compare; + // pclog("recalc: htotal=%i vtotal=%i dispend=%i\n", svga->htotal, svga->vtotal, svga->dispend); + } else { + svga->packed_chain4 = 0; - svga->line_compare = NULL; - if (mystique->type == MGA_1064SG) - svga->bpp = 8; - } + svga->line_compare = NULL; + if (mystique->type == MGA_1064SG) + svga->bpp = 8; + } } static void mystique_recalc_mapping(mystique_t *mystique) { - svga_t *svga = &mystique->svga; + svga_t *svga = &mystique->svga; - io_removehandler(0x03c0, 0x0020, mystique_in, NULL, NULL, mystique_out, NULL, NULL, mystique); - if ((mystique->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) && (mystique->pci_regs[0x41] & 1)) - io_sethandler(0x03c0, 0x0020, mystique_in, NULL, NULL, mystique_out, NULL, NULL, mystique); + io_removehandler(0x03c0, 0x0020, mystique_in, NULL, NULL, mystique_out, NULL, NULL, mystique); + if ((mystique->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) && (mystique->pci_regs[0x41] & 1)) + io_sethandler(0x03c0, 0x0020, mystique_in, NULL, NULL, mystique_out, NULL, NULL, mystique); - if (!(mystique->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) { - mem_mapping_disable(&svga->mapping); - mem_mapping_disable(&mystique->ctrl_mapping); - mem_mapping_disable(&mystique->lfb_mapping); - mem_mapping_disable(&mystique->iload_mapping); - return; - } + if (!(mystique->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) { + mem_mapping_disable(&svga->mapping); + mem_mapping_disable(&mystique->ctrl_mapping); + mem_mapping_disable(&mystique->lfb_mapping); + mem_mapping_disable(&mystique->iload_mapping); + return; + } - if (mystique->ctrl_base) - mem_mapping_set_addr(&mystique->ctrl_mapping, mystique->ctrl_base, 0x4000); - else - mem_mapping_disable(&mystique->ctrl_mapping); - if (mystique->lfb_base) - mem_mapping_set_addr(&mystique->lfb_mapping, mystique->lfb_base, 0x800000); - else - mem_mapping_disable(&mystique->lfb_mapping); - if (mystique->iload_base) - mem_mapping_set_addr(&mystique->iload_mapping, mystique->iload_base, 0x800000); - else - mem_mapping_disable(&mystique->iload_mapping); + if (mystique->ctrl_base) + mem_mapping_set_addr(&mystique->ctrl_mapping, mystique->ctrl_base, 0x4000); + else + mem_mapping_disable(&mystique->ctrl_mapping); + if (mystique->lfb_base) + mem_mapping_set_addr(&mystique->lfb_mapping, mystique->lfb_base, 0x800000); + else + mem_mapping_disable(&mystique->lfb_mapping); + if (mystique->iload_base) + mem_mapping_set_addr(&mystique->iload_mapping, mystique->iload_base, 0x800000); + else + mem_mapping_disable(&mystique->iload_mapping); - if (mystique->pci_regs[0x41] & 1) { - switch (svga->gdcreg[6] & 0x0C) { - case 0x0: /*128k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - svga->banked_mask = 0x1ffff; - break; - case 0x4: /*64k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - svga->banked_mask = 0xffff; - break; - case 0x8: /*32k at B0000*/ - mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); - svga->banked_mask = 0x7fff; - break; - case 0xC: /*32k at B8000*/ - mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); - svga->banked_mask = 0x7fff; - break; - } - if (svga->gdcreg[6] & 0xc) { - /*64k banks*/ - svga->read_bank = (mystique->crtcext_regs[4] & 0x7f) << 16; - svga->write_bank = (mystique->crtcext_regs[4] & 0x7f) << 16; - } else { - /*128k banks*/ - svga->read_bank = (mystique->crtcext_regs[4] & 0x7e) << 16; - svga->write_bank = (mystique->crtcext_regs[4] & 0x7e) << 16; - } - } else - mem_mapping_disable(&svga->mapping); + if (mystique->pci_regs[0x41] & 1) { + switch (svga->gdcreg[6] & 0x0C) { + case 0x0: /*128k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + svga->banked_mask = 0x1ffff; + break; + case 0x4: /*64k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + svga->banked_mask = 0xffff; + break; + case 0x8: /*32k at B0000*/ + mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); + svga->banked_mask = 0x7fff; + break; + case 0xC: /*32k at B8000*/ + mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); + svga->banked_mask = 0x7fff; + break; + } + if (svga->gdcreg[6] & 0xc) { + /*64k banks*/ + svga->read_bank = (mystique->crtcext_regs[4] & 0x7f) << 16; + svga->write_bank = (mystique->crtcext_regs[4] & 0x7f) << 16; + } else { + /*128k banks*/ + svga->read_bank = (mystique->crtcext_regs[4] & 0x7e) << 16; + svga->write_bank = (mystique->crtcext_regs[4] & 0x7e) << 16; + } + } else + mem_mapping_disable(&svga->mapping); } static void mystique_update_irqs(mystique_t *mystique) { - svga_t *svga = &mystique->svga; - int irq = 0; + svga_t *svga = &mystique->svga; + int irq = 0; - if ((mystique->status & mystique->ien) & STATUS_SOFTRAPEN) - irq = 1; - if ((mystique->status & STATUS_VSYNCPEN) && (svga->crtc[0x11] & 0x30) == 0x10) - irq = 1; + if ((mystique->status & mystique->ien) & STATUS_SOFTRAPEN) + irq = 1; + if ((mystique->status & STATUS_VSYNCPEN) && (svga->crtc[0x11] & 0x30) == 0x10) + irq = 1; - if (irq) - pci_set_irq(mystique->card, PCI_INTA); - else - pci_clear_irq(mystique->card, PCI_INTA); + if (irq) + pci_set_irq(mystique->card, PCI_INTA); + else + pci_clear_irq(mystique->card, PCI_INTA); } -#define READ8(addr, var) switch ((addr) & 3) \ - { \ - case 0: ret = (var) & 0xff; break; \ - case 1: ret = ((var) >> 8) & 0xff; break; \ - case 2: ret = ((var) >> 16) & 0xff; break; \ - case 3: ret = ((var) >> 24) & 0xff; break; \ - } +#define READ8(addr, var) \ + switch ((addr)&3) { \ + case 0: \ + ret = (var)&0xff; \ + break; \ + case 1: \ + ret = ((var) >> 8) & 0xff; \ + break; \ + case 2: \ + ret = ((var) >> 16) & 0xff; \ + break; \ + case 3: \ + ret = ((var) >> 24) & 0xff; \ + break; \ + } -#define WRITE8(addr, var, val) switch ((addr) & 3) \ - { \ - case 0: var = (var & 0xffffff00) | (val); break; \ - case 1: var = (var & 0xffff00ff) | ((val) << 8); break; \ - case 2: var = (var & 0xff00ffff) | ((val) << 16); break; \ - case 3: var = (var & 0x00ffffff) | ((val) << 24); break; \ - } +#define WRITE8(addr, var, val) \ + switch ((addr)&3) { \ + case 0: \ + var = (var & 0xffffff00) | (val); \ + break; \ + case 1: \ + var = (var & 0xffff00ff) | ((val) << 8); \ + break; \ + case 2: \ + var = (var & 0xff00ffff) | ((val) << 16); \ + break; \ + case 3: \ + var = (var & 0x00ffffff) | ((val) << 24); \ + break; \ + } static uint8_t mystique_read_xreg(mystique_t *mystique, int reg) { - uint8_t ret = 0xff; + uint8_t ret = 0xff; - switch (reg) { - case XREG_XCURADDL:ret = mystique->cursor.addr & 0xff; - break; - case XREG_XCURADDH:ret = mystique->cursor.addr >> 8; - break; - case XREG_XCURCTRL:ret = mystique->xcurctrl; - break; + switch (reg) { + case XREG_XCURADDL: + ret = mystique->cursor.addr & 0xff; + break; + case XREG_XCURADDH: + ret = mystique->cursor.addr >> 8; + break; + case XREG_XCURCTRL: + ret = mystique->xcurctrl; + break; - case XREG_XCURCOL0R: - case XREG_XCURCOL0G: - case XREG_XCURCOL0B:READ8(reg, mystique->cursor.col[0]); - break; - case XREG_XCURCOL1R: - case XREG_XCURCOL1G: - case XREG_XCURCOL1B:READ8(reg, mystique->cursor.col[1]); - break; - case XREG_XCURCOL2R: - case XREG_XCURCOL2G: - case XREG_XCURCOL2B:READ8(reg, mystique->cursor.col[2]); - break; + case XREG_XCURCOL0R: + case XREG_XCURCOL0G: + case XREG_XCURCOL0B: + READ8(reg, mystique->cursor.col[0]); + break; + case XREG_XCURCOL1R: + case XREG_XCURCOL1G: + case XREG_XCURCOL1B: + READ8(reg, mystique->cursor.col[1]); + break; + case XREG_XCURCOL2R: + case XREG_XCURCOL2G: + case XREG_XCURCOL2B: + READ8(reg, mystique->cursor.col[2]); + break; - case XREG_XMULCTRL:ret = mystique->xmulctrl; - break; + case XREG_XMULCTRL: + ret = mystique->xmulctrl; + break; - case XREG_XMISCCTRL:ret = mystique->xmiscctrl; - break; + case XREG_XMISCCTRL: + ret = mystique->xmiscctrl; + break; - case XREG_XGENCTRL:ret = mystique->xgenctrl; - break; + case XREG_XGENCTRL: + ret = mystique->xgenctrl; + break; - case XREG_XVREFCTRL:ret = mystique->xvrefctrl; - break; + case XREG_XVREFCTRL: + ret = mystique->xvrefctrl; + break; - case XREG_XGENIOCTRL:ret = mystique->xgenioctrl; - break; - case XREG_XGENIODATA:ret = mystique->xgeniodata; - break; + case XREG_XGENIOCTRL: + ret = mystique->xgenioctrl; + break; + case XREG_XGENIODATA: + ret = mystique->xgeniodata; + break; - case XREG_XSYSPLLM:ret = mystique->xsyspllm; - break; - case XREG_XSYSPLLN:ret = mystique->xsysplln; - break; - case XREG_XSYSPLLP:ret = mystique->xsyspllp; - break; + case XREG_XSYSPLLM: + ret = mystique->xsyspllm; + break; + case XREG_XSYSPLLN: + ret = mystique->xsysplln; + break; + case XREG_XSYSPLLP: + ret = mystique->xsyspllp; + break; - case XREG_XZOOMCTRL:ret = mystique->xzoomctrl; - break; + case XREG_XZOOMCTRL: + ret = mystique->xzoomctrl; + break; - case XREG_XSENSETEST:ret = 0; - if (mystique->svga.vgapal[0].b < 0x80) - ret |= 1; - if (mystique->svga.vgapal[0].g < 0x80) - ret |= 2; - if (mystique->svga.vgapal[0].r < 0x80) - ret |= 4; - break; + case XREG_XSENSETEST: + ret = 0; + if (mystique->svga.vgapal[0].b < 0x80) + ret |= 1; + if (mystique->svga.vgapal[0].g < 0x80) + ret |= 2; + if (mystique->svga.vgapal[0].r < 0x80) + ret |= 4; + break; - case XREG_XCRCREML: /*CRC not implemented*/ - ret = 0; - break; - case XREG_XCRCREMH:ret = 0; - break; - case XREG_XCRCBITSEL:ret = mystique->xcrcbitsel; - break; + case XREG_XCRCREML: /*CRC not implemented*/ + ret = 0; + break; + case XREG_XCRCREMH: + ret = 0; + break; + case XREG_XCRCBITSEL: + ret = mystique->xcrcbitsel; + break; - case XREG_XCOLKEYMSKL:ret = mystique->xcolkeymskl; - break; - case XREG_XCOLKEYMSKH:ret = mystique->xcolkeymskh; - break; - case XREG_XCOLKEYL:ret = mystique->xcolkeyl; - break; - case XREG_XCOLKEYH:ret = mystique->xcolkeyh; - break; + case XREG_XCOLKEYMSKL: + ret = mystique->xcolkeymskl; + break; + case XREG_XCOLKEYMSKH: + ret = mystique->xcolkeymskh; + break; + case XREG_XCOLKEYL: + ret = mystique->xcolkeyl; + break; + case XREG_XCOLKEYH: + ret = mystique->xcolkeyh; + break; - case XREG_XPIXCLKCTRL:ret = mystique->xpixclkctrl; - break; + case XREG_XPIXCLKCTRL: + ret = mystique->xpixclkctrl; + break; - case XREG_XSYSPLLSTAT:ret = XSYSPLLSTAT_SYSLOCK; - break; + case XREG_XSYSPLLSTAT: + ret = XSYSPLLSTAT_SYSLOCK; + break; - case XREG_XPIXPLLSTAT:ret = XPIXPLLSTAT_SYSLOCK; - break; + case XREG_XPIXPLLSTAT: + ret = XPIXPLLSTAT_SYSLOCK; + break; - case XREG_XPIXPLLCM:ret = mystique->xpixpll[2].m; - break; - case XREG_XPIXPLLCN:ret = mystique->xpixpll[2].n; - break; - case XREG_XPIXPLLCP:ret = mystique->xpixpll[2].p | (mystique->xpixpll[2].s << 3); - break; + case XREG_XPIXPLLCM: + ret = mystique->xpixpll[2].m; + break; + case XREG_XPIXPLLCN: + ret = mystique->xpixpll[2].n; + break; + case XREG_XPIXPLLCP: + ret = mystique->xpixpll[2].p | (mystique->xpixpll[2].s << 3); + break; - case 0x00: - case 0x20: - case 0x3f:ret = 0xff; - break; + case 0x00: + case 0x20: + case 0x3f: + ret = 0xff; + break; - default: - if (reg >= 0x50) - ret = 0xff; + default: + if (reg >= 0x50) + ret = 0xff; #ifndef RELEASE_BUILD - else - fatal("Read XREG %02x\n", reg); + else + fatal("Read XREG %02x\n", reg); #endif - break; - } - return ret; + break; + } + return ret; } static void mystique_write_xreg(mystique_t *mystique, int reg, uint8_t val) { - svga_t *svga = &mystique->svga; + svga_t *svga = &mystique->svga; - switch (reg) { - case XREG_XCURADDL:mystique->cursor.addr = (mystique->cursor.addr & 0x1f00) | val; - svga->hwcursor.addr = mystique->cursor.addr << 10; - break; - case XREG_XCURADDH:mystique->cursor.addr = (mystique->cursor.addr & 0x00ff) | ((val & 0x1f) << 8); - svga->hwcursor.addr = mystique->cursor.addr << 10; - break; + switch (reg) { + case XREG_XCURADDL: + mystique->cursor.addr = (mystique->cursor.addr & 0x1f00) | val; + svga->hwcursor.addr = mystique->cursor.addr << 10; + break; + case XREG_XCURADDH: + mystique->cursor.addr = (mystique->cursor.addr & 0x00ff) | ((val & 0x1f) << 8); + svga->hwcursor.addr = mystique->cursor.addr << 10; + break; - case XREG_XCURCTRL:mystique->xcurctrl = val; - svga->hwcursor.ena = (val & 3) ? 1 : 0; - break; + case XREG_XCURCTRL: + mystique->xcurctrl = val; + svga->hwcursor.ena = (val & 3) ? 1 : 0; + break; - case XREG_XCURCOL0R: - case XREG_XCURCOL0G: - case XREG_XCURCOL0B:WRITE8(reg, mystique->cursor.col[0], val); - break; - case XREG_XCURCOL1R: - case XREG_XCURCOL1G: - case XREG_XCURCOL1B:WRITE8(reg, mystique->cursor.col[1], val); - break; - case XREG_XCURCOL2R: - case XREG_XCURCOL2G: - case XREG_XCURCOL2B:WRITE8(reg, mystique->cursor.col[2], val); - break; + case XREG_XCURCOL0R: + case XREG_XCURCOL0G: + case XREG_XCURCOL0B: + WRITE8(reg, mystique->cursor.col[0], val); + break; + case XREG_XCURCOL1R: + case XREG_XCURCOL1G: + case XREG_XCURCOL1B: + WRITE8(reg, mystique->cursor.col[1], val); + break; + case XREG_XCURCOL2R: + case XREG_XCURCOL2G: + case XREG_XCURCOL2B: + WRITE8(reg, mystique->cursor.col[2], val); + break; - case XREG_XMULCTRL:mystique->xmulctrl = val; - break; + case XREG_XMULCTRL: + mystique->xmulctrl = val; + break; - case XREG_XMISCCTRL:mystique->xmiscctrl = val; - svga_set_ramdac_type(svga, (val & XMISCCTRL_VGA8DAC) ? RAMDAC_8BIT : RAMDAC_6BIT); - break; + case XREG_XMISCCTRL: + mystique->xmiscctrl = val; + svga_set_ramdac_type(svga, (val & XMISCCTRL_VGA8DAC) ? RAMDAC_8BIT : RAMDAC_6BIT); + break; - case XREG_XGENCTRL:mystique->xgenctrl = val; - break; + case XREG_XGENCTRL: + mystique->xgenctrl = val; + break; - case XREG_XVREFCTRL:mystique->xvrefctrl = val; - break; + case XREG_XVREFCTRL: + mystique->xvrefctrl = val; + break; - case XREG_XGENIOCTRL:mystique->xgenioctrl = val; - break; - case XREG_XGENIODATA:mystique->xgeniodata = val; - break; + case XREG_XGENIOCTRL: + mystique->xgenioctrl = val; + break; + case XREG_XGENIODATA: + mystique->xgeniodata = val; + break; - case XREG_XSYSPLLM:mystique->xsyspllm = val; - break; - case XREG_XSYSPLLN:mystique->xsysplln = val; - break; - case XREG_XSYSPLLP:mystique->xsyspllp = val; - break; + case XREG_XSYSPLLM: + mystique->xsyspllm = val; + break; + case XREG_XSYSPLLN: + mystique->xsysplln = val; + break; + case XREG_XSYSPLLP: + mystique->xsyspllp = val; + break; - case XREG_XZOOMCTRL:mystique->xzoomctrl = val & 3; - break; + case XREG_XZOOMCTRL: + mystique->xzoomctrl = val & 3; + break; - case XREG_XSENSETEST:break; + case XREG_XSENSETEST: + break; - case XREG_XCRCREML: /*CRC not implemented*/ - break; - case XREG_XCRCREMH:break; - case XREG_XCRCBITSEL:mystique->xcrcbitsel = val & 0x1f; - break; + case XREG_XCRCREML: /*CRC not implemented*/ + break; + case XREG_XCRCREMH: + break; + case XREG_XCRCBITSEL: + mystique->xcrcbitsel = val & 0x1f; + break; - case XREG_XCOLKEYMSKL:mystique->xcolkeymskl = val; - break; - case XREG_XCOLKEYMSKH:mystique->xcolkeymskh = val; - break; - case XREG_XCOLKEYL:mystique->xcolkeyl = val; - break; - case XREG_XCOLKEYH:mystique->xcolkeyh = val; - break; + case XREG_XCOLKEYMSKL: + mystique->xcolkeymskl = val; + break; + case XREG_XCOLKEYMSKH: + mystique->xcolkeymskh = val; + break; + case XREG_XCOLKEYL: + mystique->xcolkeyl = val; + break; + case XREG_XCOLKEYH: + mystique->xcolkeyh = val; + break; - case XREG_XSYSPLLSTAT:break; + case XREG_XSYSPLLSTAT: + break; - case XREG_XPIXPLLSTAT:break; + case XREG_XPIXPLLSTAT: + break; - case XREG_XPIXCLKCTRL:mystique->xpixclkctrl = val; - break; + case XREG_XPIXCLKCTRL: + mystique->xpixclkctrl = val; + break; - case XREG_XPIXPLLCM:mystique->xpixpll[2].m = val; - break; - case XREG_XPIXPLLCN:mystique->xpixpll[2].n = val; - break; - case XREG_XPIXPLLCP:mystique->xpixpll[2].p = val & 7; - mystique->xpixpll[2].s = (val >> 3) & 3; - break; + case XREG_XPIXPLLCM: + mystique->xpixpll[2].m = val; + break; + case XREG_XPIXPLLCN: + mystique->xpixpll[2].n = val; + break; + case XREG_XPIXPLLCP: + mystique->xpixpll[2].p = val & 7; + mystique->xpixpll[2].s = (val >> 3) & 3; + break; - case 0x00: - case 0x01: - case 0x02: - case 0x03: - case 0x07: - case 0x0b: - case 0x0f: - case 0x13: - case 0x14: - case 0x15: - case 0x16: - case 0x17: - case 0x1b: - case 0x1c: - case 0x20: - case 0x39: - case 0x3b: - case 0x3f: - case 0x47: - case 0x4b:break; + case 0x00: + case 0x01: + case 0x02: + case 0x03: + case 0x07: + case 0x0b: + case 0x0f: + case 0x13: + case 0x14: + case 0x15: + case 0x16: + case 0x17: + case 0x1b: + case 0x1c: + case 0x20: + case 0x39: + case 0x3b: + case 0x3f: + case 0x47: + case 0x4b: + break; #ifndef RELEASE_BUILD - default: - if (reg < 0x50) - fatal("Write XREG %02x %02x\n", reg, val); - break; + default: + if (reg < 0x50) + fatal("Write XREG %02x %02x\n", reg, val); + break; #endif - } + } } static uint8_t mystique_ctrl_read_b(uint32_t addr, void *p) { - mystique_t *mystique = (mystique_t *)p; - svga_t *svga = &mystique->svga; - uint8_t ret = 0xff; - int fifocount; + mystique_t *mystique = (mystique_t *)p; + svga_t *svga = &mystique->svga; + uint8_t ret = 0xff; + int fifocount; -// pclog("mystique read %04x %08x\n", addr & 0x3fff, cpu_state.pc); + // pclog("mystique read %04x %08x\n", addr & 0x3fff, cpu_state.pc); - if (mystique->type == MGA_2064W && (addr & 0x3e00) == 0x3c00) { - /*RAMDAC*/ - ret = tvp3026_ramdac_in(addr & 0xf, &mystique->tvp3026, svga); - } else - switch (addr & 0x3fff) { - case REG_FIFOSTATUS:fifocount = FIFO_SIZE - FIFO_ENTRIES; - if (fifocount > 64) - fifocount = 64; - ret = fifocount; - break; - case REG_FIFOSTATUS + 1: - if (FIFO_EMPTY) - ret |= 2; - else if (FIFO_ENTRIES >= 64) - ret |= 1; -// ret = 2; /*Empty*/ - break; - case REG_FIFOSTATUS + 2: - case REG_FIFOSTATUS + 3:ret = 0; - break; + if (mystique->type == MGA_2064W && (addr & 0x3e00) == 0x3c00) { + /*RAMDAC*/ + ret = tvp3026_ramdac_in(addr & 0xf, &mystique->tvp3026, svga); + } else + switch (addr & 0x3fff) { + case REG_FIFOSTATUS: + fifocount = FIFO_SIZE - FIFO_ENTRIES; + if (fifocount > 64) + fifocount = 64; + ret = fifocount; + break; + case REG_FIFOSTATUS + 1: + if (FIFO_EMPTY) + ret |= 2; + else if (FIFO_ENTRIES >= 64) + ret |= 1; + // ret = 2; /*Empty*/ + break; + case REG_FIFOSTATUS + 2: + case REG_FIFOSTATUS + 3: + ret = 0; + break; - case REG_STATUS:ret = mystique->status & 0xff; - if (svga->cgastat & 8) - ret |= REG_STATUS_VSYNCSTS; -// pclog("REG_STATUS %02x\n", ret); - break; - case REG_STATUS + 1:ret = (mystique->status >> 8) & 0xff; - break; - case REG_STATUS + 2:ret = (mystique->status >> 16) & 0xff; - if (mystique->busy || - ((mystique->blitter_submit_refcount + mystique->blitter_submit_dma_refcount) != mystique->blitter_complete_refcount) || - !FIFO_EMPTY) - ret |= (STATUS_DWGENGSTS >> 16); -/* thread_lock_mutex(mystique->dma.lock); - if (mystique->dma.state == DMA_STATE_IDLE) - ret |= (STATUS_ENDPRDMASTS >> 16); - thread_unlock_mutex(mystique->dma.lock);*/ -/* pclog("Read status %02x %i %i %i fifo=%i\n", ret, mystique->busy, - ((mystique->blitter_submit_refcount + mystique->blitter_submit_dma_refcount) != mystique->blitter_complete_refcount), - !FIFO_EMPTY, FIFO_ENTRIES);*/ -// ret |= 2; - break; - case REG_STATUS + 3:ret = (mystique->status >> 24) & 0xff; - break; + case REG_STATUS: + ret = mystique->status & 0xff; + if (svga->cgastat & 8) + ret |= REG_STATUS_VSYNCSTS; + // pclog("REG_STATUS %02x\n", ret); + break; + case REG_STATUS + 1: + ret = (mystique->status >> 8) & 0xff; + break; + case REG_STATUS + 2: + ret = (mystique->status >> 16) & 0xff; + if (mystique->busy || + ((mystique->blitter_submit_refcount + mystique->blitter_submit_dma_refcount) != + mystique->blitter_complete_refcount) || + !FIFO_EMPTY) + ret |= (STATUS_DWGENGSTS >> 16); + /* thread_lock_mutex(mystique->dma.lock); + if (mystique->dma.state == DMA_STATE_IDLE) + ret |= (STATUS_ENDPRDMASTS >> 16); + thread_unlock_mutex(mystique->dma.lock);*/ + /* pclog("Read status %02x %i %i %i fifo=%i\n", ret, mystique->busy, + ((mystique->blitter_submit_refcount + + mystique->blitter_submit_dma_refcount) != mystique->blitter_complete_refcount), !FIFO_EMPTY, + FIFO_ENTRIES);*/ + // ret |= 2; + break; + case REG_STATUS + 3: + ret = (mystique->status >> 24) & 0xff; + break; - case REG_IEN:ret = mystique->ien & 0x64; - break; - case REG_IEN + 1: - case REG_IEN + 2: - case REG_IEN + 3:ret = 0; - break; + case REG_IEN: + ret = mystique->ien & 0x64; + break; + case REG_IEN + 1: + case REG_IEN + 2: + case REG_IEN + 3: + ret = 0; + break; - case REG_OPMODE:ret = mystique->dmamod << 2; - break; - case REG_OPMODE + 1:ret = mystique->dmadatasiz; - break; - case REG_OPMODE + 2:ret = mystique->dirdatasiz; - break; - case REG_OPMODE + 3:ret = 0; - break; + case REG_OPMODE: + ret = mystique->dmamod << 2; + break; + case REG_OPMODE + 1: + ret = mystique->dmadatasiz; + break; + case REG_OPMODE + 2: + ret = mystique->dirdatasiz; + break; + case REG_OPMODE + 3: + ret = 0; + break; - case REG_PRIMADDRESS: - case REG_PRIMADDRESS + 1: - case REG_PRIMADDRESS + 2: - case REG_PRIMADDRESS + 3:READ8(addr, mystique->dma.primaddress); - break; - case REG_PRIMEND: - case REG_PRIMEND + 1: - case REG_PRIMEND + 2: - case REG_PRIMEND + 3:READ8(addr, mystique->dma.primend); - break; + case REG_PRIMADDRESS: + case REG_PRIMADDRESS + 1: + case REG_PRIMADDRESS + 2: + case REG_PRIMADDRESS + 3: + READ8(addr, mystique->dma.primaddress); + break; + case REG_PRIMEND: + case REG_PRIMEND + 1: + case REG_PRIMEND + 2: + case REG_PRIMEND + 3: + READ8(addr, mystique->dma.primend); + break; - case REG_SECADDRESS: - case REG_SECADDRESS + 1: - case REG_SECADDRESS + 2: - case REG_SECADDRESS + 3:READ8(addr, mystique->dma.secaddress); - break; + case REG_SECADDRESS: + case REG_SECADDRESS + 1: + case REG_SECADDRESS + 2: + case REG_SECADDRESS + 3: + READ8(addr, mystique->dma.secaddress); + break; - case REG_VCOUNT: - case REG_VCOUNT + 1: - case REG_VCOUNT + 2: - case REG_VCOUNT + 3:READ8(addr, svga->vc); - break; + case REG_VCOUNT: + case REG_VCOUNT + 1: + case REG_VCOUNT + 2: + case REG_VCOUNT + 3: + READ8(addr, svga->vc); + break; - case REG_ATTR_IDX:ret = svga_in(0x3c0, svga); - break; - case REG_ATTR_DATA:ret = svga_in(0x3c1, svga); - break; + case REG_ATTR_IDX: + ret = svga_in(0x3c0, svga); + break; + case REG_ATTR_DATA: + ret = svga_in(0x3c1, svga); + break; - case REG_INSTS0:ret = svga_in(0x3c2, svga); - break; + case REG_INSTS0: + ret = svga_in(0x3c2, svga); + break; - case REG_SEQ_IDX:ret = svga_in(0x3c4, svga); - break; - case REG_SEQ_DATA:ret = svga_in(0x3c5, svga); - break; + case REG_SEQ_IDX: + ret = svga_in(0x3c4, svga); + break; + case REG_SEQ_DATA: + ret = svga_in(0x3c5, svga); + break; - case REG_MISCREAD:ret = svga_in(0x3cc, svga); - break; + case REG_MISCREAD: + ret = svga_in(0x3cc, svga); + break; - case REG_GCTL_IDX:ret = mystique_in(0x3ce, mystique); - break; - case REG_GCTL_DATA:ret = mystique_in(0x3cf, mystique); - break; + case REG_GCTL_IDX: + ret = mystique_in(0x3ce, mystique); + break; + case REG_GCTL_DATA: + ret = mystique_in(0x3cf, mystique); + break; - case REG_CRTC_IDX:ret = mystique_in(0x3d4, mystique); - break; - case REG_CRTC_DATA:ret = mystique_in(0x3d5, mystique); - break; + case REG_CRTC_IDX: + ret = mystique_in(0x3d4, mystique); + break; + case REG_CRTC_DATA: + ret = mystique_in(0x3d5, mystique); + break; - case REG_INSTS1:ret = mystique_in(0x3da, mystique); - break; + case REG_INSTS1: + ret = mystique_in(0x3da, mystique); + break; - case REG_CRTCEXT_IDX:ret = mystique_in(0x3de, mystique); - break; - case REG_CRTCEXT_DATA:ret = mystique_in(0x3df, mystique); - break; + case REG_CRTCEXT_IDX: + ret = mystique_in(0x3de, mystique); + break; + case REG_CRTCEXT_DATA: + ret = mystique_in(0x3df, mystique); + break; - case REG_PALWTADD:ret = svga_in(0x3c8, svga); - break; - case REG_PALDATA:ret = svga_in(0x3c9, svga); - break; - case REG_PIXRDMSK:ret = svga_in(0x3c6, svga); - break; - case REG_PALRDADD:ret = svga_in(0x3c7, svga); - break; + case REG_PALWTADD: + ret = svga_in(0x3c8, svga); + break; + case REG_PALDATA: + ret = svga_in(0x3c9, svga); + break; + case REG_PIXRDMSK: + ret = svga_in(0x3c6, svga); + break; + case REG_PALRDADD: + ret = svga_in(0x3c7, svga); + break; - case REG_X_DATAREG:ret = mystique_read_xreg(mystique, mystique->xreg_idx); - break; + case REG_X_DATAREG: + ret = mystique_read_xreg(mystique, mystique->xreg_idx); + break; - case 0x1c40: - case 0x1c41: - case 0x1c42: - case 0x1c43: - case 0x1d44: - case 0x1d45: - case 0x1d46: - case 0x1d47: - case 0x1e50: - case 0x1e51: - case 0x1e52: - case 0x1e53: - case REG_ICLEAR: - case REG_ICLEAR + 1: - case REG_ICLEAR + 2: - case REG_ICLEAR + 3: - case 0x2c30: - case 0x2c31: - case 0x2c32: - case 0x2c33: - case 0x3e08:break; + case 0x1c40: + case 0x1c41: + case 0x1c42: + case 0x1c43: + case 0x1d44: + case 0x1d45: + case 0x1d46: + case 0x1d47: + case 0x1e50: + case 0x1e51: + case 0x1e52: + case 0x1e53: + case REG_ICLEAR: + case REG_ICLEAR + 1: + case REG_ICLEAR + 2: + case REG_ICLEAR + 3: + case 0x2c30: + case 0x2c31: + case 0x2c32: + case 0x2c33: + case 0x3e08: + break; - case 0x3c08: - case 0x3c09: - case 0x3c0b:break; + case 0x3c08: + case 0x3c09: + case 0x3c0b: + break; - default: - if ((addr & 0x3fff) >= 0x2c00 && (addr & 0x3fff) < 0x2c40) - break; - if ((addr & 0x3fff) >= 0x3e00) - break; + default: + if ((addr & 0x3fff) >= 0x2c00 && (addr & 0x3fff) < 0x2c40) + break; + if ((addr & 0x3fff) >= 0x3e00) + break; #ifndef RELEASE_BUILD - fatal("Read MGA control %08x\n", addr & 0x3fff); + fatal("Read MGA control %08x\n", addr & 0x3fff); #endif - } + } -// pclog("mcrb: addr=%08x ret=%02x\n", addr, ret); - return ret; + // pclog("mcrb: addr=%08x ret=%02x\n", addr, ret); + return ret; } static void mystique_accel_ctrl_write_b(uint32_t addr, uint8_t val, void *p) { - mystique_t *mystique = (mystique_t *)p; - int start_blit = 0; - int x; + mystique_t *mystique = (mystique_t *)p; + int start_blit = 0; + int x; -// pclog("mystique accel addr=%04x val=%02x\n", addr & 0x3fff, val); + // pclog("mystique accel addr=%04x val=%02x\n", addr & 0x3fff, val); - if ((addr & 0x300) == 0x100) { - addr &= ~0x100; - start_blit = 1; - } + if ((addr & 0x300) == 0x100) { + addr &= ~0x100; + start_blit = 1; + } - switch (addr & 0x3fff) { - case REG_MACCESS: - case REG_MACCESS + 1: - case REG_MACCESS + 2: - case REG_MACCESS + 3:WRITE8(addr, mystique->maccess, val); - mystique->dwgreg.dither = mystique->maccess >> 30; - break; + switch (addr & 0x3fff) { + case REG_MACCESS: + case REG_MACCESS + 1: + case REG_MACCESS + 2: + case REG_MACCESS + 3: + WRITE8(addr, mystique->maccess, val); + mystique->dwgreg.dither = mystique->maccess >> 30; + break; - case REG_MCTLWTST: - case REG_MCTLWTST + 1: - case REG_MCTLWTST + 2: - case REG_MCTLWTST + 3:WRITE8(addr, mystique->mctlwtst, val); - break; + case REG_MCTLWTST: + case REG_MCTLWTST + 1: + case REG_MCTLWTST + 2: + case REG_MCTLWTST + 3: + WRITE8(addr, mystique->mctlwtst, val); + break; - case REG_PAT0: - case REG_PAT0 + 1: - case REG_PAT0 + 2: - case REG_PAT0 + 3: - case REG_PAT1: - case REG_PAT1 + 1: - case REG_PAT1 + 2: - case REG_PAT1 + 3: - for (x = 0; x < 8; x++) - mystique->dwgreg.pattern[addr & 7][x] = val & (1 << (7 - x)); - break; + case REG_PAT0: + case REG_PAT0 + 1: + case REG_PAT0 + 2: + case REG_PAT0 + 3: + case REG_PAT1: + case REG_PAT1 + 1: + case REG_PAT1 + 2: + case REG_PAT1 + 3: + for (x = 0; x < 8; x++) + mystique->dwgreg.pattern[addr & 7][x] = val & (1 << (7 - x)); + break; - case REG_XYSTRT: - case REG_XYSTRT + 1:WRITE8(addr & 1, mystique->dwgreg.ar[5], val); - if (mystique->dwgreg.ar[5] & 0x8000) - mystique->dwgreg.ar[5] |= 0xffff8000; - else - mystique->dwgreg.ar[5] &= ~0xffff8000; - WRITE8(addr & 1, mystique->dwgreg.xdst, val); - break; - case REG_XYSTRT + 2: - case REG_XYSTRT + 3:WRITE8(addr & 1, mystique->dwgreg.ar[6], val); - if (mystique->dwgreg.ar[6] & 0x8000) - mystique->dwgreg.ar[6] |= 0xffff8000; - else - mystique->dwgreg.ar[6] &= ~0xffff8000; - WRITE8(addr & 1, mystique->dwgreg.ydst, val); - mystique->dwgreg.ydst_lin = ((int32_t)(int16_t)mystique->dwgreg.ydst * (mystique->dwgreg.pitch & PITCH_MASK)) + mystique->dwgreg.ydstorg; - break; + case REG_XYSTRT: + case REG_XYSTRT + 1: + WRITE8(addr & 1, mystique->dwgreg.ar[5], val); + if (mystique->dwgreg.ar[5] & 0x8000) + mystique->dwgreg.ar[5] |= 0xffff8000; + else + mystique->dwgreg.ar[5] &= ~0xffff8000; + WRITE8(addr & 1, mystique->dwgreg.xdst, val); + break; + case REG_XYSTRT + 2: + case REG_XYSTRT + 3: + WRITE8(addr & 1, mystique->dwgreg.ar[6], val); + if (mystique->dwgreg.ar[6] & 0x8000) + mystique->dwgreg.ar[6] |= 0xffff8000; + else + mystique->dwgreg.ar[6] &= ~0xffff8000; + WRITE8(addr & 1, mystique->dwgreg.ydst, val); + mystique->dwgreg.ydst_lin = ((int32_t)(int16_t)mystique->dwgreg.ydst * (mystique->dwgreg.pitch & PITCH_MASK)) + + mystique->dwgreg.ydstorg; + break; - case REG_XYEND: - case REG_XYEND + 1:WRITE8(addr & 1, mystique->dwgreg.ar[0], val); - if (mystique->dwgreg.ar[0] & 0x8000) - mystique->dwgreg.ar[0] |= 0xffff8000; - else - mystique->dwgreg.ar[0] &= ~0xffff8000; -// pclog("XYEND AR[0]=%08x\n", mystique->dwgreg.ar[0]); - break; - case REG_XYEND + 2: - case REG_XYEND + 3:WRITE8(addr & 1, mystique->dwgreg.ar[2], val); - if (mystique->dwgreg.ar[2] & 0x8000) - mystique->dwgreg.ar[2] |= 0xffff8000; - else - mystique->dwgreg.ar[2] &= ~0xffff8000; - break; + case REG_XYEND: + case REG_XYEND + 1: + WRITE8(addr & 1, mystique->dwgreg.ar[0], val); + if (mystique->dwgreg.ar[0] & 0x8000) + mystique->dwgreg.ar[0] |= 0xffff8000; + else + mystique->dwgreg.ar[0] &= ~0xffff8000; + // pclog("XYEND AR[0]=%08x\n", mystique->dwgreg.ar[0]); + break; + case REG_XYEND + 2: + case REG_XYEND + 3: + WRITE8(addr & 1, mystique->dwgreg.ar[2], val); + if (mystique->dwgreg.ar[2] & 0x8000) + mystique->dwgreg.ar[2] |= 0xffff8000; + else + mystique->dwgreg.ar[2] &= ~0xffff8000; + break; - case REG_SGN:mystique->dwgreg.sgn.sdydxl = val & SGN_SDYDXL; - mystique->dwgreg.sgn.scanleft = val & SGN_SCANLEFT; - mystique->dwgreg.sgn.sdxl = val & SGN_SDXL; - mystique->dwgreg.sgn.sdy = val & SGN_SDY; - mystique->dwgreg.sgn.sdxr = val & SGN_SDXR; - break; - case REG_SGN + 1: - case REG_SGN + 2: - case REG_SGN + 3:break; + case REG_SGN: + mystique->dwgreg.sgn.sdydxl = val & SGN_SDYDXL; + mystique->dwgreg.sgn.scanleft = val & SGN_SCANLEFT; + mystique->dwgreg.sgn.sdxl = val & SGN_SDXL; + mystique->dwgreg.sgn.sdy = val & SGN_SDY; + mystique->dwgreg.sgn.sdxr = val & SGN_SDXR; + break; + case REG_SGN + 1: + case REG_SGN + 2: + case REG_SGN + 3: + break; - case REG_LEN: - case REG_LEN + 1:WRITE8(addr, mystique->dwgreg.length, val); - break; - case REG_LEN + 2:break; - case REG_LEN + 3:mystique->dwgreg.beta = val >> 4; - if (!mystique->dwgreg.beta) - mystique->dwgreg.beta = 16; - break; + case REG_LEN: + case REG_LEN + 1: + WRITE8(addr, mystique->dwgreg.length, val); + break; + case REG_LEN + 2: + break; + case REG_LEN + 3: + mystique->dwgreg.beta = val >> 4; + if (!mystique->dwgreg.beta) + mystique->dwgreg.beta = 16; + break; - case REG_CXBNDRY: - case REG_CXBNDRY + 1:WRITE8(addr, mystique->dwgreg.cxleft, val); - break; - case REG_CXBNDRY + 2: - case REG_CXBNDRY + 3:WRITE8(addr & 1, mystique->dwgreg.cxright, val); - break; - case REG_FXBNDRY: - case REG_FXBNDRY + 1:WRITE8(addr, mystique->dwgreg.fxleft, val); - break; - case REG_FXBNDRY + 2: - case REG_FXBNDRY + 3:WRITE8(addr & 1, mystique->dwgreg.fxright, val); - break; + case REG_CXBNDRY: + case REG_CXBNDRY + 1: + WRITE8(addr, mystique->dwgreg.cxleft, val); + break; + case REG_CXBNDRY + 2: + case REG_CXBNDRY + 3: + WRITE8(addr & 1, mystique->dwgreg.cxright, val); + break; + case REG_FXBNDRY: + case REG_FXBNDRY + 1: + WRITE8(addr, mystique->dwgreg.fxleft, val); + break; + case REG_FXBNDRY + 2: + case REG_FXBNDRY + 3: + WRITE8(addr & 1, mystique->dwgreg.fxright, val); + break; - case REG_YDSTLEN: - case REG_YDSTLEN + 1:WRITE8(addr, mystique->dwgreg.length, val); -// pclog("Write YDSTLEN+%i %i\n", addr&1, mystique->dwgreg.length); - break; - case REG_YDSTLEN + 2:mystique->dwgreg.ydst = (mystique->dwgreg.ydst & ~0xff) | val; - if (mystique->dwgreg.pitch & PITCH_YLIN) - mystique->dwgreg.ydst_lin = (mystique->dwgreg.ydst << 5) + mystique->dwgreg.ydstorg; - else { - mystique->dwgreg.ydst_lin = ((int32_t)(int16_t)mystique->dwgreg.ydst * (mystique->dwgreg.pitch & PITCH_MASK)) + mystique->dwgreg.ydstorg; - mystique->dwgreg.selline = val & 7; - } -// pclog("Write YDSTLEN+2 %i %08x\n", mystique->dwgreg.ydst, mystique->dwgreg.ydst_lin); - break; - case REG_YDSTLEN + 3:mystique->dwgreg.ydst = (mystique->dwgreg.ydst & 0xff) | (((int32_t)(int8_t)val) << 8); - if (mystique->dwgreg.pitch & PITCH_YLIN) - mystique->dwgreg.ydst_lin = (mystique->dwgreg.ydst << 5) + mystique->dwgreg.ydstorg; - else - mystique->dwgreg.ydst_lin = ((int32_t)(int16_t)mystique->dwgreg.ydst * (mystique->dwgreg.pitch & PITCH_MASK)) + mystique->dwgreg.ydstorg; -// pclog("Write YDSTLEN+3 %i %08x\n", mystique->dwgreg.ydst, mystique->dwgreg.ydst_lin); - break; + case REG_YDSTLEN: + case REG_YDSTLEN + 1: + WRITE8(addr, mystique->dwgreg.length, val); + // pclog("Write YDSTLEN+%i %i\n", addr&1, mystique->dwgreg.length); + break; + case REG_YDSTLEN + 2: + mystique->dwgreg.ydst = (mystique->dwgreg.ydst & ~0xff) | val; + if (mystique->dwgreg.pitch & PITCH_YLIN) + mystique->dwgreg.ydst_lin = (mystique->dwgreg.ydst << 5) + mystique->dwgreg.ydstorg; + else { + mystique->dwgreg.ydst_lin = + ((int32_t)(int16_t)mystique->dwgreg.ydst * (mystique->dwgreg.pitch & PITCH_MASK)) + + mystique->dwgreg.ydstorg; + mystique->dwgreg.selline = val & 7; + } + // pclog("Write YDSTLEN+2 %i %08x\n", mystique->dwgreg.ydst, mystique->dwgreg.ydst_lin); + break; + case REG_YDSTLEN + 3: + mystique->dwgreg.ydst = (mystique->dwgreg.ydst & 0xff) | (((int32_t)(int8_t)val) << 8); + if (mystique->dwgreg.pitch & PITCH_YLIN) + mystique->dwgreg.ydst_lin = (mystique->dwgreg.ydst << 5) + mystique->dwgreg.ydstorg; + else + mystique->dwgreg.ydst_lin = + ((int32_t)(int16_t)mystique->dwgreg.ydst * (mystique->dwgreg.pitch & PITCH_MASK)) + + mystique->dwgreg.ydstorg; + // pclog("Write YDSTLEN+3 %i %08x\n", mystique->dwgreg.ydst, mystique->dwgreg.ydst_lin); + break; - case REG_XDST: - case REG_XDST + 1:WRITE8(addr & 1, mystique->dwgreg.xdst, val); - break; - case REG_XDST + 2: - case REG_XDST + 3:break; + case REG_XDST: + case REG_XDST + 1: + WRITE8(addr & 1, mystique->dwgreg.xdst, val); + break; + case REG_XDST + 2: + case REG_XDST + 3: + break; - case REG_YDSTORG: - case REG_YDSTORG + 1: - case REG_YDSTORG + 2: - case REG_YDSTORG + 3:WRITE8(addr, mystique->dwgreg.ydstorg, val); - mystique->dwgreg.z_base = mystique->dwgreg.ydstorg * 2 + mystique->dwgreg.zorg; -// pclog("ydstorg=%06x z_base=%06x\n", mystique->dwgreg.ydstorg, mystique->dwgreg.z_base); - break; - case REG_YTOP: - case REG_YTOP + 1: - case REG_YTOP + 2: - case REG_YTOP + 3:WRITE8(addr, mystique->dwgreg.ytop, val); - break; - case REG_YBOT: - case REG_YBOT + 1: - case REG_YBOT + 2: - case REG_YBOT + 3:WRITE8(addr, mystique->dwgreg.ybot, val); - break; + case REG_YDSTORG: + case REG_YDSTORG + 1: + case REG_YDSTORG + 2: + case REG_YDSTORG + 3: + WRITE8(addr, mystique->dwgreg.ydstorg, val); + mystique->dwgreg.z_base = mystique->dwgreg.ydstorg * 2 + mystique->dwgreg.zorg; + // pclog("ydstorg=%06x z_base=%06x\n", mystique->dwgreg.ydstorg, mystique->dwgreg.z_base); + break; + case REG_YTOP: + case REG_YTOP + 1: + case REG_YTOP + 2: + case REG_YTOP + 3: + WRITE8(addr, mystique->dwgreg.ytop, val); + break; + case REG_YBOT: + case REG_YBOT + 1: + case REG_YBOT + 2: + case REG_YBOT + 3: + WRITE8(addr, mystique->dwgreg.ybot, val); + break; - case REG_CXLEFT: - case REG_CXLEFT + 1:WRITE8(addr, mystique->dwgreg.cxleft, val); - break; - case REG_CXLEFT + 2: - case REG_CXLEFT + 3:break; - case REG_CXRIGHT: - case REG_CXRIGHT + 1:WRITE8(addr, mystique->dwgreg.cxright, val); - break; - case REG_CXRIGHT + 2: - case REG_CXRIGHT + 3:break; + case REG_CXLEFT: + case REG_CXLEFT + 1: + WRITE8(addr, mystique->dwgreg.cxleft, val); + break; + case REG_CXLEFT + 2: + case REG_CXLEFT + 3: + break; + case REG_CXRIGHT: + case REG_CXRIGHT + 1: + WRITE8(addr, mystique->dwgreg.cxright, val); + break; + case REG_CXRIGHT + 2: + case REG_CXRIGHT + 3: + break; - case REG_FXLEFT: - case REG_FXLEFT + 1:WRITE8(addr, mystique->dwgreg.fxleft, val); - break; - case REG_FXLEFT + 2: - case REG_FXLEFT + 3:break; - case REG_FXRIGHT: - case REG_FXRIGHT + 1:WRITE8(addr, mystique->dwgreg.fxright, val); - break; - case REG_FXRIGHT + 2: - case REG_FXRIGHT + 3:break; + case REG_FXLEFT: + case REG_FXLEFT + 1: + WRITE8(addr, mystique->dwgreg.fxleft, val); + break; + case REG_FXLEFT + 2: + case REG_FXLEFT + 3: + break; + case REG_FXRIGHT: + case REG_FXRIGHT + 1: + WRITE8(addr, mystique->dwgreg.fxright, val); + break; + case REG_FXRIGHT + 2: + case REG_FXRIGHT + 3: + break; - case REG_SECADDRESS: - case REG_SECADDRESS + 1: - case REG_SECADDRESS + 2: - case REG_SECADDRESS + 3:WRITE8(addr, mystique->dma.secaddress, val); - mystique->dma.sec_state = 0; - break; + case REG_SECADDRESS: + case REG_SECADDRESS + 1: + case REG_SECADDRESS + 2: + case REG_SECADDRESS + 3: + WRITE8(addr, mystique->dma.secaddress, val); + mystique->dma.sec_state = 0; + break; - case REG_TMR0: - case REG_TMR0 + 1: - case REG_TMR0 + 2: - case REG_TMR0 + 3:WRITE8(addr, mystique->dwgreg.tmr[0], val); - break; - case REG_TMR1: - case REG_TMR1 + 1: - case REG_TMR1 + 2: - case REG_TMR1 + 3:WRITE8(addr, mystique->dwgreg.tmr[1], val); - break; - case REG_TMR2: - case REG_TMR2 + 1: - case REG_TMR2 + 2: - case REG_TMR2 + 3:WRITE8(addr, mystique->dwgreg.tmr[2], val); - break; - case REG_TMR3: - case REG_TMR3 + 1: - case REG_TMR3 + 2: - case REG_TMR3 + 3:WRITE8(addr, mystique->dwgreg.tmr[3], val); - break; - case REG_TMR4: - case REG_TMR4 + 1: - case REG_TMR4 + 2: - case REG_TMR4 + 3:WRITE8(addr, mystique->dwgreg.tmr[4], val); - break; - case REG_TMR5: - case REG_TMR5 + 1: - case REG_TMR5 + 2: - case REG_TMR5 + 3:WRITE8(addr, mystique->dwgreg.tmr[5], val); - break; - case REG_TMR6: - case REG_TMR6 + 1: - case REG_TMR6 + 2: - case REG_TMR6 + 3:WRITE8(addr, mystique->dwgreg.tmr[6], val); - break; - case REG_TMR7: - case REG_TMR7 + 1: - case REG_TMR7 + 2: - case REG_TMR7 + 3:WRITE8(addr, mystique->dwgreg.tmr[7], val); - break; - case REG_TMR8: - case REG_TMR8 + 1: - case REG_TMR8 + 2: - case REG_TMR8 + 3:WRITE8(addr, mystique->dwgreg.tmr[8], val); - break; + case REG_TMR0: + case REG_TMR0 + 1: + case REG_TMR0 + 2: + case REG_TMR0 + 3: + WRITE8(addr, mystique->dwgreg.tmr[0], val); + break; + case REG_TMR1: + case REG_TMR1 + 1: + case REG_TMR1 + 2: + case REG_TMR1 + 3: + WRITE8(addr, mystique->dwgreg.tmr[1], val); + break; + case REG_TMR2: + case REG_TMR2 + 1: + case REG_TMR2 + 2: + case REG_TMR2 + 3: + WRITE8(addr, mystique->dwgreg.tmr[2], val); + break; + case REG_TMR3: + case REG_TMR3 + 1: + case REG_TMR3 + 2: + case REG_TMR3 + 3: + WRITE8(addr, mystique->dwgreg.tmr[3], val); + break; + case REG_TMR4: + case REG_TMR4 + 1: + case REG_TMR4 + 2: + case REG_TMR4 + 3: + WRITE8(addr, mystique->dwgreg.tmr[4], val); + break; + case REG_TMR5: + case REG_TMR5 + 1: + case REG_TMR5 + 2: + case REG_TMR5 + 3: + WRITE8(addr, mystique->dwgreg.tmr[5], val); + break; + case REG_TMR6: + case REG_TMR6 + 1: + case REG_TMR6 + 2: + case REG_TMR6 + 3: + WRITE8(addr, mystique->dwgreg.tmr[6], val); + break; + case REG_TMR7: + case REG_TMR7 + 1: + case REG_TMR7 + 2: + case REG_TMR7 + 3: + WRITE8(addr, mystique->dwgreg.tmr[7], val); + break; + case REG_TMR8: + case REG_TMR8 + 1: + case REG_TMR8 + 2: + case REG_TMR8 + 3: + WRITE8(addr, mystique->dwgreg.tmr[8], val); + break; - case REG_TEXORG: - case REG_TEXORG + 1: - case REG_TEXORG + 2: - case REG_TEXORG + 3:WRITE8(addr, mystique->dwgreg.texorg, val); -// if ((addr & 3) == 3) pclog("texorg=%08x\n", mystique->dwgreg.texorg); - break; - case REG_TEXWIDTH: - case REG_TEXWIDTH + 1: - case REG_TEXWIDTH + 2: - case REG_TEXWIDTH + 3:WRITE8(addr, mystique->dwgreg.texwidth, val); -// if ((addr & 3) == 3) pclog("texwith=%08x\n", mystique->dwgreg.texwidth); - break; - case REG_TEXHEIGHT: - case REG_TEXHEIGHT + 1: - case REG_TEXHEIGHT + 2: - case REG_TEXHEIGHT + 3:WRITE8(addr, mystique->dwgreg.texheight, val); -// if ((addr & 3) == 3) pclog("texheight=%08x %i %i\n", mystique->dwgreg.texheight, mystique->dwgreg.texheight&0x3f, (int)(((mystique->dwgreg.texheight >> 9) & 0x3f) | ((mystique->dwgreg.texheight & (1 << 14)) ? 0xffffffc0 : 0))); - break; - case REG_TEXCTL: - case REG_TEXCTL + 1: - case REG_TEXCTL + 2: - case REG_TEXCTL + 3:WRITE8(addr, mystique->dwgreg.texctl, val); -// if ((addr & 3) == 3) pclog("texctl=%08x\n", mystique->dwgreg.texctl); - mystique->dwgreg.ta_key = (mystique->dwgreg.texctl & TEXCTL_TAKEY) ? 1 : 0; - mystique->dwgreg.ta_mask = (mystique->dwgreg.texctl & TEXCTL_TAMASK) ? 1 : 0; - break; - case REG_TEXTRANS: - case REG_TEXTRANS + 1: - case REG_TEXTRANS + 2: - case REG_TEXTRANS + 3:WRITE8(addr, mystique->dwgreg.textrans, val); -// /*if ((addr & 3) == 3) */pclog("textrans=%08x\n", mystique->dwgreg.textrans); - break; + case REG_TEXORG: + case REG_TEXORG + 1: + case REG_TEXORG + 2: + case REG_TEXORG + 3: + WRITE8(addr, mystique->dwgreg.texorg, val); + // if ((addr & 3) == 3) pclog("texorg=%08x\n", mystique->dwgreg.texorg); + break; + case REG_TEXWIDTH: + case REG_TEXWIDTH + 1: + case REG_TEXWIDTH + 2: + case REG_TEXWIDTH + 3: + WRITE8(addr, mystique->dwgreg.texwidth, val); + // if ((addr & 3) == 3) pclog("texwith=%08x\n", mystique->dwgreg.texwidth); + break; + case REG_TEXHEIGHT: + case REG_TEXHEIGHT + 1: + case REG_TEXHEIGHT + 2: + case REG_TEXHEIGHT + 3: + WRITE8(addr, mystique->dwgreg.texheight, val); + // if ((addr & 3) == 3) pclog("texheight=%08x %i %i\n", mystique->dwgreg.texheight, + // mystique->dwgreg.texheight&0x3f, (int)(((mystique->dwgreg.texheight >> 9) & 0x3f) | + // ((mystique->dwgreg.texheight & (1 << 14)) ? 0xffffffc0 : 0))); + break; + case REG_TEXCTL: + case REG_TEXCTL + 1: + case REG_TEXCTL + 2: + case REG_TEXCTL + 3: + WRITE8(addr, mystique->dwgreg.texctl, val); + // if ((addr & 3) == 3) pclog("texctl=%08x\n", mystique->dwgreg.texctl); + mystique->dwgreg.ta_key = (mystique->dwgreg.texctl & TEXCTL_TAKEY) ? 1 : 0; + mystique->dwgreg.ta_mask = (mystique->dwgreg.texctl & TEXCTL_TAMASK) ? 1 : 0; + break; + case REG_TEXTRANS: + case REG_TEXTRANS + 1: + case REG_TEXTRANS + 2: + case REG_TEXTRANS + 3: + WRITE8(addr, mystique->dwgreg.textrans, val); + // /*if ((addr & 3) == 3) */pclog("textrans=%08x\n", mystique->dwgreg.textrans); + break; - case 0x1c18: - case 0x1c19: - case 0x1c1a: - case 0x1c1b: - case 0x1c28: - case 0x1c29: - case 0x1c2a: - case 0x1c2b: - case 0x1c2c: - case 0x1c2d: - case 0x1c2e: - case 0x1c2f: - case 0x1cc4: - case 0x1cc5: - case 0x1cc6: - case 0x1cc7: - case 0x1cd4: - case 0x1cd5: - case 0x1cd6: - case 0x1cd7: - case 0x1ce4: - case 0x1ce5: - case 0x1ce6: - case 0x1ce7: - case 0x1cf4: - case 0x1cf5: - case 0x1cf6: - case 0x1cf7:break; + case 0x1c18: + case 0x1c19: + case 0x1c1a: + case 0x1c1b: + case 0x1c28: + case 0x1c29: + case 0x1c2a: + case 0x1c2b: + case 0x1c2c: + case 0x1c2d: + case 0x1c2e: + case 0x1c2f: + case 0x1cc4: + case 0x1cc5: + case 0x1cc6: + case 0x1cc7: + case 0x1cd4: + case 0x1cd5: + case 0x1cd6: + case 0x1cd7: + case 0x1ce4: + case 0x1ce5: + case 0x1ce6: + case 0x1ce7: + case 0x1cf4: + case 0x1cf5: + case 0x1cf6: + case 0x1cf7: + break; - case REG_OPMODE:mystique->dwgreg.dmamod = (val >> 2) & 3; - mystique->dma.iload_state = 0; - break; + case REG_OPMODE: + mystique->dwgreg.dmamod = (val >> 2) & 3; + mystique->dma.iload_state = 0; + break; - default: - if ((addr & 0x3fff) >= 0x2c4c && (addr & 0x3fff) <= 0x2cff) - break; + default: + if ((addr & 0x3fff) >= 0x2c4c && (addr & 0x3fff) <= 0x2cff) + break; #ifndef RELEASE_BUILD - fatal("Write MGA accel control %08x %02x\n", addr & 0x3fff, val); + fatal("Write MGA accel control %08x %02x\n", addr & 0x3fff, val); #endif - break; - } + break; + } - if (start_blit) { - mystique_start_blit(mystique); -// fatal("Start blit\n"); - } + if (start_blit) { + mystique_start_blit(mystique); + // fatal("Start blit\n"); + } } static void mystique_ctrl_write_b(uint32_t addr, uint8_t val, void *p) { - mystique_t *mystique = (mystique_t *)p; - svga_t *svga = &mystique->svga; + mystique_t *mystique = (mystique_t *)p; + svga_t *svga = &mystique->svga; -// pclog("mystique addr=%04x val=%02x\n", addr & 0x3fff, val); + // pclog("mystique addr=%04x val=%02x\n", addr & 0x3fff, val); - if (mystique->type == MGA_2064W && (addr & 0x3e00) == 0x3c00) { - /*RAMDAC*/ - tvp3026_ramdac_out(addr & 0xf, val, &mystique->tvp3026, svga); - return; - } - if ((addr & 0x3fff) < 0x1c00) { - mystique_iload_write_b(addr, val, p); - return; - } - if ((addr & 0x3e00) == 0x1c00 || (addr & 0x3e00) == 0x2c00) { - if ((addr & 0x300) == 0x100) - mystique->blitter_submit_refcount++; -// pclog("mystique queue addr=%04x val=%02x\n", addr & 0x3fff, val); - mystique_queue(mystique, addr & 0x3fff, val, FIFO_WRITE_CTRL_BYTE); - return; - } + if (mystique->type == MGA_2064W && (addr & 0x3e00) == 0x3c00) { + /*RAMDAC*/ + tvp3026_ramdac_out(addr & 0xf, val, &mystique->tvp3026, svga); + return; + } + if ((addr & 0x3fff) < 0x1c00) { + mystique_iload_write_b(addr, val, p); + return; + } + if ((addr & 0x3e00) == 0x1c00 || (addr & 0x3e00) == 0x2c00) { + if ((addr & 0x300) == 0x100) + mystique->blitter_submit_refcount++; + // pclog("mystique queue addr=%04x val=%02x\n", addr & 0x3fff, val); + mystique_queue(mystique, addr & 0x3fff, val, FIFO_WRITE_CTRL_BYTE); + return; + } - switch (addr & 0x3fff) { - case REG_ICLEAR: -// pclog("ICLEAR %02x\n", val); - if (val & ICLEAR_SOFTRAPICLR) { - mystique->status &= ~STATUS_SOFTRAPEN; - mystique_update_irqs(mystique); - } - if (val & ICLEAR_VLINEICLR) { - mystique->status &= ~STATUS_VLINEPEN; - mystique_update_irqs(mystique); - } - break; - case REG_ICLEAR + 1: - case REG_ICLEAR + 2: - case REG_ICLEAR + 3:break; + switch (addr & 0x3fff) { + case REG_ICLEAR: + // pclog("ICLEAR %02x\n", val); + if (val & ICLEAR_SOFTRAPICLR) { + mystique->status &= ~STATUS_SOFTRAPEN; + mystique_update_irqs(mystique); + } + if (val & ICLEAR_VLINEICLR) { + mystique->status &= ~STATUS_VLINEPEN; + mystique_update_irqs(mystique); + } + break; + case REG_ICLEAR + 1: + case REG_ICLEAR + 2: + case REG_ICLEAR + 3: + break; - case REG_IEN:mystique->ien = val & 0x65; -// pclog("Write IEN %02x\n", val); - break; - case REG_IEN + 1: - case REG_IEN + 2: - case REG_IEN + 3:break; + case REG_IEN: + mystique->ien = val & 0x65; + // pclog("Write IEN %02x\n", val); + break; + case REG_IEN + 1: + case REG_IEN + 2: + case REG_IEN + 3: + break; - case REG_OPMODE:mystique->dmamod = (val >> 2) & 3; -// pclog("OPMODE\n"); - mystique_queue(mystique, addr & 0x3fff, val, FIFO_WRITE_CTRL_BYTE); - break; - case REG_OPMODE + 1:mystique->dmadatasiz = val & 3; - break; - case REG_OPMODE + 2:mystique->dirdatasiz = val & 3; - break; - case REG_OPMODE + 3:break; + case REG_OPMODE: + mystique->dmamod = (val >> 2) & 3; + // pclog("OPMODE\n"); + mystique_queue(mystique, addr & 0x3fff, val, FIFO_WRITE_CTRL_BYTE); + break; + case REG_OPMODE + 1: + mystique->dmadatasiz = val & 3; + break; + case REG_OPMODE + 2: + mystique->dirdatasiz = val & 3; + break; + case REG_OPMODE + 3: + break; - case REG_PRIMADDRESS: - case REG_PRIMADDRESS + 1: - case REG_PRIMADDRESS + 2: - case REG_PRIMADDRESS + 3:thread_lock_mutex(mystique->dma.lock); - WRITE8(addr, mystique->dma.primaddress, val); - mystique->dma.pri_state = 0; -// pclog("PRIMADDRESS write %04x %08x\n", addr, mystique->dma.primaddress); - thread_unlock_mutex(mystique->dma.lock); - break; + case REG_PRIMADDRESS: + case REG_PRIMADDRESS + 1: + case REG_PRIMADDRESS + 2: + case REG_PRIMADDRESS + 3: + thread_lock_mutex(mystique->dma.lock); + WRITE8(addr, mystique->dma.primaddress, val); + mystique->dma.pri_state = 0; + // pclog("PRIMADDRESS write %04x %08x\n", addr, mystique->dma.primaddress); + thread_unlock_mutex(mystique->dma.lock); + break; - case REG_DMAMAP: - case REG_DMAMAP + 0x1: - case REG_DMAMAP + 0x2: - case REG_DMAMAP + 0x3: - case REG_DMAMAP + 0x4: - case REG_DMAMAP + 0x5: - case REG_DMAMAP + 0x6: - case REG_DMAMAP + 0x7: - case REG_DMAMAP + 0x8: - case REG_DMAMAP + 0x9: - case REG_DMAMAP + 0xa: - case REG_DMAMAP + 0xb: - case REG_DMAMAP + 0xc: - case REG_DMAMAP + 0xd: - case REG_DMAMAP + 0xe: - case REG_DMAMAP + 0xf:mystique->dmamap[addr & 0xf] = val; - break; + case REG_DMAMAP: + case REG_DMAMAP + 0x1: + case REG_DMAMAP + 0x2: + case REG_DMAMAP + 0x3: + case REG_DMAMAP + 0x4: + case REG_DMAMAP + 0x5: + case REG_DMAMAP + 0x6: + case REG_DMAMAP + 0x7: + case REG_DMAMAP + 0x8: + case REG_DMAMAP + 0x9: + case REG_DMAMAP + 0xa: + case REG_DMAMAP + 0xb: + case REG_DMAMAP + 0xc: + case REG_DMAMAP + 0xd: + case REG_DMAMAP + 0xe: + case REG_DMAMAP + 0xf: + mystique->dmamap[addr & 0xf] = val; + break; - case REG_RST: - case REG_RST + 1: - case REG_RST + 2: - case REG_RST + 3: -// pclog("Write REG_RST\n"); - wait_fifo_idle(mystique); - mystique->busy = 0; - mystique->blitter_submit_refcount = 0; - mystique->blitter_submit_dma_refcount = 0; - mystique->blitter_complete_refcount = 0; - mystique->dwgreg.iload_rem_count = 0; - mystique->status = STATUS_ENDPRDMASTS; - break; + case REG_RST: + case REG_RST + 1: + case REG_RST + 2: + case REG_RST + 3: + // pclog("Write REG_RST\n"); + wait_fifo_idle(mystique); + mystique->busy = 0; + mystique->blitter_submit_refcount = 0; + mystique->blitter_submit_dma_refcount = 0; + mystique->blitter_complete_refcount = 0; + mystique->dwgreg.iload_rem_count = 0; + mystique->status = STATUS_ENDPRDMASTS; + break; - case REG_ATTR_IDX:svga_out(0x3c0, val, svga); - break; - case REG_ATTR_DATA:svga_out(0x3c1, val, svga); - break; + case REG_ATTR_IDX: + svga_out(0x3c0, val, svga); + break; + case REG_ATTR_DATA: + svga_out(0x3c1, val, svga); + break; - case REG_MISC:svga_out(0x3c2, val, svga); - break; + case REG_MISC: + svga_out(0x3c2, val, svga); + break; - case REG_SEQ_IDX:svga_out(0x3c4, val, svga); - break; - case REG_SEQ_DATA:svga_out(0x3c5, val, svga); - break; + case REG_SEQ_IDX: + svga_out(0x3c4, val, svga); + break; + case REG_SEQ_DATA: + svga_out(0x3c5, val, svga); + break; - case REG_GCTL_IDX:mystique_out(0x3ce, val, mystique); - break; - case REG_GCTL_DATA:mystique_out(0x3cf, val, mystique); - break; + case REG_GCTL_IDX: + mystique_out(0x3ce, val, mystique); + break; + case REG_GCTL_DATA: + mystique_out(0x3cf, val, mystique); + break; - case REG_CRTC_IDX:mystique_out(0x3d4, val, mystique); - break; - case REG_CRTC_DATA:mystique_out(0x3d5, val, mystique); - break; + case REG_CRTC_IDX: + mystique_out(0x3d4, val, mystique); + break; + case REG_CRTC_DATA: + mystique_out(0x3d5, val, mystique); + break; - case REG_CRTCEXT_IDX:mystique_out(0x3de, val, mystique); - break; - case REG_CRTCEXT_DATA:mystique_out(0x3df, val, mystique); - break; + case REG_CRTCEXT_IDX: + mystique_out(0x3de, val, mystique); + break; + case REG_CRTCEXT_DATA: + mystique_out(0x3df, val, mystique); + break; - case REG_CACHEFLUSH:break; + case REG_CACHEFLUSH: + break; - case REG_PALWTADD:svga_out(0x3c8, val, svga); - mystique->xreg_idx = val; - break; - case REG_PALDATA:svga_out(0x3c9, val, svga); - break; - case REG_PIXRDMSK:svga_out(0x3c6, val, svga); - break; - case REG_PALRDADD:svga_out(0x3c7, val, svga); - break; + case REG_PALWTADD: + svga_out(0x3c8, val, svga); + mystique->xreg_idx = val; + break; + case REG_PALDATA: + svga_out(0x3c9, val, svga); + break; + case REG_PIXRDMSK: + svga_out(0x3c6, val, svga); + break; + case REG_PALRDADD: + svga_out(0x3c7, val, svga); + break; - case REG_X_DATAREG:mystique_write_xreg(mystique, mystique->xreg_idx, val); - break; + case REG_X_DATAREG: + mystique_write_xreg(mystique, mystique->xreg_idx, val); + break; - case REG_CURPOSX: - case REG_CURPOSX + 1:WRITE8(addr, mystique->cursor.pos_x, val); - svga->hwcursor.x = mystique->cursor.pos_x - 64; - break; - case REG_CURPOSY: - case REG_CURPOSY + 1:WRITE8(addr & 1, mystique->cursor.pos_y, val); - svga->hwcursor.y = mystique->cursor.pos_y - 64; - break; + case REG_CURPOSX: + case REG_CURPOSX + 1: + WRITE8(addr, mystique->cursor.pos_x, val); + svga->hwcursor.x = mystique->cursor.pos_x - 64; + break; + case REG_CURPOSY: + case REG_CURPOSY + 1: + WRITE8(addr & 1, mystique->cursor.pos_y, val); + svga->hwcursor.y = mystique->cursor.pos_y - 64; + break; - case 0x1e50: - case 0x1e51: - case 0x1e52: - case 0x1e53: - case 0x3c0b: - case 0x3e02: - case 0x3e08:break; + case 0x1e50: + case 0x1e51: + case 0x1e52: + case 0x1e53: + case 0x3c0b: + case 0x3e02: + case 0x3e08: + break; - default: - if ((addr & 0x3fff) >= 0x2c4c && (addr & 0x3fff) <= 0x2cff) - break; - if ((addr & 0x3fff) >= 0x3e00) - break; + default: + if ((addr & 0x3fff) >= 0x2c4c && (addr & 0x3fff) <= 0x2cff) + break; + if ((addr & 0x3fff) >= 0x3e00) + break; #ifndef RELEASE_BUILD - fatal("Write MGA control %08x %02x\n", addr & 0x3fff, val); + fatal("Write MGA control %08x %02x\n", addr & 0x3fff, val); #endif - break; - } + break; + } } static uint32_t mystique_ctrl_read_l(uint32_t addr, void *p) { - uint32_t ret; + uint32_t ret; -// pclog("mystique_ctrl_read_l: addr=%08x %08x\n", addr, cpu_state.pc); - if ((addr & 0x3fff) < 0x1c00) - return mystique_iload_read_l(addr, p); + // pclog("mystique_ctrl_read_l: addr=%08x %08x\n", addr, cpu_state.pc); + if ((addr & 0x3fff) < 0x1c00) + return mystique_iload_read_l(addr, p); - ret = mystique_ctrl_read_b(addr, p); - ret |= mystique_ctrl_read_b(addr + 1, p) << 8; - ret |= mystique_ctrl_read_b(addr + 2, p) << 16; - ret |= mystique_ctrl_read_b(addr + 3, p) << 24; -// pclog("mcrl: addr=%08x ret=%08x %08x\n", addr, ret, mystique->status); + ret = mystique_ctrl_read_b(addr, p); + ret |= mystique_ctrl_read_b(addr + 1, p) << 8; + ret |= mystique_ctrl_read_b(addr + 2, p) << 16; + ret |= mystique_ctrl_read_b(addr + 3, p) << 24; + // pclog("mcrl: addr=%08x ret=%08x %08x\n", addr, ret, mystique->status); - return ret; + return ret; } static void mystique_accel_ctrl_write_l(uint32_t addr, uint32_t val, void *p) { - mystique_t *mystique = (mystique_t *)p; - int start_blit = 0; + mystique_t *mystique = (mystique_t *)p; + int start_blit = 0; -// pclog("mystique accel addr=%04x val=%08x\n", addr & 0x3fff, val); - if ((addr & 0x300) == 0x100) { - addr &= ~0x100; - start_blit = 1; - } + // pclog("mystique accel addr=%04x val=%08x\n", addr & 0x3fff, val); + if ((addr & 0x300) == 0x100) { + addr &= ~0x100; + start_blit = 1; + } - switch (addr & 0x3ffc) { - case REG_DWGCTL: -// pclog(" dwgctrl write %08x %08x\n", addr2, val); - mystique->dwgreg.dwgctrl = val; + switch (addr & 0x3ffc) { + case REG_DWGCTL: + // pclog(" dwgctrl write %08x %08x\n", addr2, val); + mystique->dwgreg.dwgctrl = val; - if (val & DWGCTRL_SOLID) { - int x, y; + if (val & DWGCTRL_SOLID) { + int x, y; - for (y = 0; y < 8; y++) { - for (x = 0; x < 8; x++) - mystique->dwgreg.pattern[y][x] = 1; - } - mystique->dwgreg.src[0] = 0xffffffff; - mystique->dwgreg.src[1] = 0xffffffff; - mystique->dwgreg.src[2] = 0xffffffff; - mystique->dwgreg.src[3] = 0xffffffff; - } - if (val & DWGCTRL_ARZERO) { - mystique->dwgreg.ar[0] = 0; - mystique->dwgreg.ar[1] = 0; - mystique->dwgreg.ar[2] = 0; - mystique->dwgreg.ar[4] = 0; - mystique->dwgreg.ar[5] = 0; - mystique->dwgreg.ar[6] = 0; - } - if (val & DWGCTRL_SGNZERO) { - mystique->dwgreg.sgn.sdydxl = 0; - mystique->dwgreg.sgn.scanleft = 0; - mystique->dwgreg.sgn.sdxl = 0; - mystique->dwgreg.sgn.sdy = 0; - mystique->dwgreg.sgn.sdxr = 0; - } - if (val & DWGCTRL_SHTZERO) { - mystique->dwgreg.funcnt = 0; - mystique->dwgreg.stylelen = 0; - mystique->dwgreg.xoff = 0; - mystique->dwgreg.yoff = 0; - } - break; + for (y = 0; y < 8; y++) { + for (x = 0; x < 8; x++) + mystique->dwgreg.pattern[y][x] = 1; + } + mystique->dwgreg.src[0] = 0xffffffff; + mystique->dwgreg.src[1] = 0xffffffff; + mystique->dwgreg.src[2] = 0xffffffff; + mystique->dwgreg.src[3] = 0xffffffff; + } + if (val & DWGCTRL_ARZERO) { + mystique->dwgreg.ar[0] = 0; + mystique->dwgreg.ar[1] = 0; + mystique->dwgreg.ar[2] = 0; + mystique->dwgreg.ar[4] = 0; + mystique->dwgreg.ar[5] = 0; + mystique->dwgreg.ar[6] = 0; + } + if (val & DWGCTRL_SGNZERO) { + mystique->dwgreg.sgn.sdydxl = 0; + mystique->dwgreg.sgn.scanleft = 0; + mystique->dwgreg.sgn.sdxl = 0; + mystique->dwgreg.sgn.sdy = 0; + mystique->dwgreg.sgn.sdxr = 0; + } + if (val & DWGCTRL_SHTZERO) { + mystique->dwgreg.funcnt = 0; + mystique->dwgreg.stylelen = 0; + mystique->dwgreg.xoff = 0; + mystique->dwgreg.yoff = 0; + } + break; - case REG_ZORG:mystique->dwgreg.zorg = val; - mystique->dwgreg.z_base = mystique->dwgreg.ydstorg * 2 + mystique->dwgreg.zorg; -// pclog("zorg=%08x z_base=%08x\n", mystique->dwgreg.zorg, mystique->dwgreg.z_base); - break; + case REG_ZORG: + mystique->dwgreg.zorg = val; + mystique->dwgreg.z_base = mystique->dwgreg.ydstorg * 2 + mystique->dwgreg.zorg; + // pclog("zorg=%08x z_base=%08x\n", mystique->dwgreg.zorg, mystique->dwgreg.z_base); + break; - case REG_PLNWT:mystique->dwgreg.plnwt = val; - break; + case REG_PLNWT: + mystique->dwgreg.plnwt = val; + break; - case REG_SHIFT:mystique->dwgreg.funcnt = val & 0xff; - mystique->dwgreg.xoff = val & 7; - mystique->dwgreg.yoff = (val >> 4) & 7; - mystique->dwgreg.stylelen = (val >> 16) & 0xff; - break; + case REG_SHIFT: + mystique->dwgreg.funcnt = val & 0xff; + mystique->dwgreg.xoff = val & 7; + mystique->dwgreg.yoff = (val >> 4) & 7; + mystique->dwgreg.stylelen = (val >> 16) & 0xff; + break; - case REG_PITCH:mystique->dwgreg.pitch = val & 0xffff; - if (mystique->dwgreg.pitch & PITCH_YLIN) - mystique->dwgreg.ydst_lin = (mystique->dwgreg.ydst << 5) + mystique->dwgreg.ydstorg; - else - mystique->dwgreg.ydst_lin = ((int32_t)(int16_t)mystique->dwgreg.ydst * (mystique->dwgreg.pitch & PITCH_MASK)) + mystique->dwgreg.ydstorg; -// pclog("pitch=%04x %i\n", mystique->dwgreg.pitch, addr&1); - break; + case REG_PITCH: + mystique->dwgreg.pitch = val & 0xffff; + if (mystique->dwgreg.pitch & PITCH_YLIN) + mystique->dwgreg.ydst_lin = (mystique->dwgreg.ydst << 5) + mystique->dwgreg.ydstorg; + else + mystique->dwgreg.ydst_lin = + ((int32_t)(int16_t)mystique->dwgreg.ydst * (mystique->dwgreg.pitch & PITCH_MASK)) + + mystique->dwgreg.ydstorg; + // pclog("pitch=%04x %i\n", mystique->dwgreg.pitch, addr&1); + break; - case REG_YDST:mystique->dwgreg.ydst = val & 0x3fffff; - if (mystique->dwgreg.pitch & PITCH_YLIN) { - mystique->dwgreg.ydst_lin = (mystique->dwgreg.ydst << 5) + mystique->dwgreg.ydstorg; - mystique->dwgreg.selline = val >> 29; - } else { - mystique->dwgreg.ydst_lin = ((int32_t)(int16_t)mystique->dwgreg.ydst * (mystique->dwgreg.pitch & PITCH_MASK)) + mystique->dwgreg.ydstorg; - mystique->dwgreg.selline = val & 7; - } -// pclog("ydst=%i ydsth=%08x %08x pitch=%08x\n", mystique->dwgreg.ydst, mystique->dwgreg.ydst, mystique->dwgreg.ydst_lin, mystique->dwgreg.pitch); - break; + case REG_YDST: + mystique->dwgreg.ydst = val & 0x3fffff; + if (mystique->dwgreg.pitch & PITCH_YLIN) { + mystique->dwgreg.ydst_lin = (mystique->dwgreg.ydst << 5) + mystique->dwgreg.ydstorg; + mystique->dwgreg.selline = val >> 29; + } else { + mystique->dwgreg.ydst_lin = + ((int32_t)(int16_t)mystique->dwgreg.ydst * (mystique->dwgreg.pitch & PITCH_MASK)) + + mystique->dwgreg.ydstorg; + mystique->dwgreg.selline = val & 7; + } + // pclog("ydst=%i ydsth=%08x %08x pitch=%08x\n", mystique->dwgreg.ydst, mystique->dwgreg.ydst, + // mystique->dwgreg.ydst_lin, mystique->dwgreg.pitch); + break; - case REG_BCOL:mystique->dwgreg.bcol = val; -// pclog("BCOL %i %02x\n", addr & 3, val); - break; - case REG_FCOL:mystique->dwgreg.fcol = val; -// pclog("FCOL %i %02x\n", addr & 3, val); - break; + case REG_BCOL: + mystique->dwgreg.bcol = val; + // pclog("BCOL %i %02x\n", addr & 3, val); + break; + case REG_FCOL: + mystique->dwgreg.fcol = val; + // pclog("FCOL %i %02x\n", addr & 3, val); + break; - case REG_SRC0:mystique->dwgreg.src[0] = val; - if (mystique->busy && (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) == DWGCTRL_OPCODE_ILOAD) - blit_iload_write(mystique, mystique->dwgreg.src[0], 32); - break; - case REG_SRC1:mystique->dwgreg.src[1] = val; - if (mystique->busy && (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) == DWGCTRL_OPCODE_ILOAD) - blit_iload_write(mystique, mystique->dwgreg.src[1], 32); - break; - case REG_SRC2:mystique->dwgreg.src[2] = val; - if (mystique->busy && (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) == DWGCTRL_OPCODE_ILOAD) - blit_iload_write(mystique, mystique->dwgreg.src[2], 32); - break; - case REG_SRC3:mystique->dwgreg.src[3] = val; - if (mystique->busy && (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) == DWGCTRL_OPCODE_ILOAD) - blit_iload_write(mystique, mystique->dwgreg.src[3], 32); - break; + case REG_SRC0: + mystique->dwgreg.src[0] = val; + if (mystique->busy && (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) == DWGCTRL_OPCODE_ILOAD) + blit_iload_write(mystique, mystique->dwgreg.src[0], 32); + break; + case REG_SRC1: + mystique->dwgreg.src[1] = val; + if (mystique->busy && (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) == DWGCTRL_OPCODE_ILOAD) + blit_iload_write(mystique, mystique->dwgreg.src[1], 32); + break; + case REG_SRC2: + mystique->dwgreg.src[2] = val; + if (mystique->busy && (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) == DWGCTRL_OPCODE_ILOAD) + blit_iload_write(mystique, mystique->dwgreg.src[2], 32); + break; + case REG_SRC3: + mystique->dwgreg.src[3] = val; + if (mystique->busy && (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) == DWGCTRL_OPCODE_ILOAD) + blit_iload_write(mystique, mystique->dwgreg.src[3], 32); + break; - case REG_DMAPAD: - if (mystique->busy && (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) == DWGCTRL_OPCODE_ILOAD) - blit_iload_write(mystique, val, 32); - break; + case REG_DMAPAD: + if (mystique->busy && (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) == DWGCTRL_OPCODE_ILOAD) + blit_iload_write(mystique, val, 32); + break; - case REG_AR0:mystique->dwgreg.ar[0] = val; -// pclog("AR[0]=%08x\n", mystique->dwgreg.ar[0]); - break; - case REG_AR1:mystique->dwgreg.ar[1] = val; - break; - case REG_AR2:mystique->dwgreg.ar[2] = val; - break; - case REG_AR3:mystique->dwgreg.ar[3] = val; -// pclog("AR[3]=%08x\n", mystique->dwgreg.ar[3]); - break; - case REG_AR4:mystique->dwgreg.ar[4] = val; - break; - case REG_AR5:mystique->dwgreg.ar[5] = val; - break; - case REG_AR6:mystique->dwgreg.ar[6] = val; - break; + case REG_AR0: + mystique->dwgreg.ar[0] = val; + // pclog("AR[0]=%08x\n", mystique->dwgreg.ar[0]); + break; + case REG_AR1: + mystique->dwgreg.ar[1] = val; + break; + case REG_AR2: + mystique->dwgreg.ar[2] = val; + break; + case REG_AR3: + mystique->dwgreg.ar[3] = val; + // pclog("AR[3]=%08x\n", mystique->dwgreg.ar[3]); + break; + case REG_AR4: + mystique->dwgreg.ar[4] = val; + break; + case REG_AR5: + mystique->dwgreg.ar[5] = val; + break; + case REG_AR6: + mystique->dwgreg.ar[6] = val; + break; - case REG_DR0:mystique->dwgreg.dr[0] = val; - break; - case REG_DR2:mystique->dwgreg.dr[2] = val; - break; - case REG_DR3:mystique->dwgreg.dr[3] = val; - break; - case REG_DR4:mystique->dwgreg.dr[4] = val; -// if ((addr & 3) == 3) pclog("DR[4]=%08x\n", mystique->dwgreg.dr[4]); - break; - case REG_DR6:mystique->dwgreg.dr[6] = val; -// if ((addr & 3) == 3) pclog("DR[6]=%08x\n", mystique->dwgreg.dr[6]); - break; - case REG_DR7:mystique->dwgreg.dr[7] = val; -// if ((addr & 3) == 3) pclog("DR[7]=%08x\n", mystique->dwgreg.dr[7]); - break; - case REG_DR8:mystique->dwgreg.dr[8] = val; - break; - case REG_DR10:mystique->dwgreg.dr[10] = val; - break; - case REG_DR11:mystique->dwgreg.dr[11] = val; - break; - case REG_DR12:mystique->dwgreg.dr[12] = val; - break; - case REG_DR14:mystique->dwgreg.dr[14] = val; - break; - case REG_DR15:mystique->dwgreg.dr[15] = val; - break; + case REG_DR0: + mystique->dwgreg.dr[0] = val; + break; + case REG_DR2: + mystique->dwgreg.dr[2] = val; + break; + case REG_DR3: + mystique->dwgreg.dr[3] = val; + break; + case REG_DR4: + mystique->dwgreg.dr[4] = val; + // if ((addr & 3) == 3) pclog("DR[4]=%08x\n", mystique->dwgreg.dr[4]); + break; + case REG_DR6: + mystique->dwgreg.dr[6] = val; + // if ((addr & 3) == 3) pclog("DR[6]=%08x\n", mystique->dwgreg.dr[6]); + break; + case REG_DR7: + mystique->dwgreg.dr[7] = val; + // if ((addr & 3) == 3) pclog("DR[7]=%08x\n", mystique->dwgreg.dr[7]); + break; + case REG_DR8: + mystique->dwgreg.dr[8] = val; + break; + case REG_DR10: + mystique->dwgreg.dr[10] = val; + break; + case REG_DR11: + mystique->dwgreg.dr[11] = val; + break; + case REG_DR12: + mystique->dwgreg.dr[12] = val; + break; + case REG_DR14: + mystique->dwgreg.dr[14] = val; + break; + case REG_DR15: + mystique->dwgreg.dr[15] = val; + break; - case REG_SECEND: -// pclog("SECEND write %08x\n", val); - mystique->dma.secend = val; - if (mystique->dma.state != DMA_STATE_SEC && (mystique->dma.secaddress & DMA_ADDR_MASK) != (mystique->dma.secend & DMA_ADDR_MASK)) { -// pclog(" DMA state STATE_SEC\n"); - mystique->dma.state = DMA_STATE_SEC; - } - break; + case REG_SECEND: + // pclog("SECEND write %08x\n", val); + mystique->dma.secend = val; + if (mystique->dma.state != DMA_STATE_SEC && + (mystique->dma.secaddress & DMA_ADDR_MASK) != (mystique->dma.secend & DMA_ADDR_MASK)) { + // pclog(" DMA state STATE_SEC\n"); + mystique->dma.state = DMA_STATE_SEC; + } + break; - case REG_SOFTRAP: -// pclog("SOFTRAP\n"); -/* mystique->dma.secaddress = val;*/ - mystique->dma.state = DMA_STATE_IDLE; - mystique->endprdmasts_pending = 1; - mystique->softrap_pending_val = val; - mystique->softrap_pending = 1; -// pclog("SOFTRAP DMA state STATE_IDLE\n"); -/* mystique->status |= STATUS_SOFTRAPEN; - mystique_update_irqs(mystique);*/ - break; + case REG_SOFTRAP: + // pclog("SOFTRAP\n"); + /* mystique->dma.secaddress = val;*/ + mystique->dma.state = DMA_STATE_IDLE; + mystique->endprdmasts_pending = 1; + mystique->softrap_pending_val = val; + mystique->softrap_pending = 1; + // pclog("SOFTRAP DMA state STATE_IDLE\n"); + /* mystique->status |= STATUS_SOFTRAPEN; + mystique_update_irqs(mystique);*/ + break; - default:mystique_accel_ctrl_write_b(addr, val & 0xff, p); - mystique_accel_ctrl_write_b(addr + 1, (val >> 8) & 0xff, p); - mystique_accel_ctrl_write_b(addr + 2, (val >> 16) & 0xff, p); - mystique_accel_ctrl_write_b(addr + 3, (val >> 24) & 0xff, p); - break; - } + default: + mystique_accel_ctrl_write_b(addr, val & 0xff, p); + mystique_accel_ctrl_write_b(addr + 1, (val >> 8) & 0xff, p); + mystique_accel_ctrl_write_b(addr + 2, (val >> 16) & 0xff, p); + mystique_accel_ctrl_write_b(addr + 3, (val >> 24) & 0xff, p); + break; + } - if (start_blit) { - mystique_start_blit(mystique); -// fatal("Start blit\n"); - } + if (start_blit) { + mystique_start_blit(mystique); + // fatal("Start blit\n"); + } } static void mystique_ctrl_write_l(uint32_t addr, uint32_t val, void *p) { - mystique_t *mystique = (mystique_t *)p; - uint32_t reg_addr; + mystique_t *mystique = (mystique_t *)p; + uint32_t reg_addr; -// pclog("mystique addr=%04x val=%08x\n", addr & 0x3fff, val); - if ((addr & 0x3fff) < 0x1c00) { - mystique_iload_write_l(addr, val, p); - return; - } + // pclog("mystique addr=%04x val=%08x\n", addr & 0x3fff, val); + if ((addr & 0x3fff) < 0x1c00) { + mystique_iload_write_l(addr, val, p); + return; + } - if ((addr & 0x3e00) == 0x1c00 || (addr & 0x3e00) == 0x2c00) { - if ((addr & 0x300) == 0x100) - mystique->blitter_submit_refcount++; -// pclog("mystique queue addr=%04x val=%08x\n", addr & 0x3fff, val); - mystique_queue(mystique, addr & 0x3fff, val, FIFO_WRITE_CTRL_LONG); - return; - } + if ((addr & 0x3e00) == 0x1c00 || (addr & 0x3e00) == 0x2c00) { + if ((addr & 0x300) == 0x100) + mystique->blitter_submit_refcount++; + // pclog("mystique queue addr=%04x val=%08x\n", addr & 0x3fff, val); + mystique_queue(mystique, addr & 0x3fff, val, FIFO_WRITE_CTRL_LONG); + return; + } - switch (addr & 0x3ffc) { - case REG_PRIMEND:thread_lock_mutex(mystique->dma.lock); -// pclog("PRIMEND write %08x\n", val); - mystique->dma.primend = val; - if (mystique->dma.state == DMA_STATE_IDLE && (mystique->dma.primaddress & DMA_ADDR_MASK) != (mystique->dma.primend & DMA_ADDR_MASK)) { -// pclog("Clear DMA end flag\n"); - mystique->endprdmasts_pending = 0; - mystique->status &= ~STATUS_ENDPRDMASTS; + switch (addr & 0x3ffc) { + case REG_PRIMEND: + thread_lock_mutex(mystique->dma.lock); + // pclog("PRIMEND write %08x\n", val); + mystique->dma.primend = val; + if (mystique->dma.state == DMA_STATE_IDLE && + (mystique->dma.primaddress & DMA_ADDR_MASK) != (mystique->dma.primend & DMA_ADDR_MASK)) { + // pclog("Clear DMA end flag\n"); + mystique->endprdmasts_pending = 0; + mystique->status &= ~STATUS_ENDPRDMASTS; - mystique->dma.state = DMA_STATE_PRI; -// pclog(" DMA state STATE_PRI\n"); - mystique->dma.pri_state = 0; - wake_fifo_thread(mystique); - } - thread_unlock_mutex(mystique->dma.lock); - break; + mystique->dma.state = DMA_STATE_PRI; + // pclog(" DMA state STATE_PRI\n"); + mystique->dma.pri_state = 0; + wake_fifo_thread(mystique); + } + thread_unlock_mutex(mystique->dma.lock); + break; - case REG_DWG_INDIR_WT: - case REG_DWG_INDIR_WT + 0x04: - case REG_DWG_INDIR_WT + 0x08: - case REG_DWG_INDIR_WT + 0x0c: - case REG_DWG_INDIR_WT + 0x10: - case REG_DWG_INDIR_WT + 0x14: - case REG_DWG_INDIR_WT + 0x18: - case REG_DWG_INDIR_WT + 0x1c: - case REG_DWG_INDIR_WT + 0x20: - case REG_DWG_INDIR_WT + 0x24: - case REG_DWG_INDIR_WT + 0x28: - case REG_DWG_INDIR_WT + 0x2c: - case REG_DWG_INDIR_WT + 0x30: - case REG_DWG_INDIR_WT + 0x34: - case REG_DWG_INDIR_WT + 0x38: - case REG_DWG_INDIR_WT + 0x3c:reg_addr = (mystique->dmamap[(addr >> 2) & 0xf] & 0x7f) << 2; - if (mystique->dmamap[(addr >> 2) & 0xf] & 0x80) - reg_addr += 0x2c00; - else - reg_addr += 0x1c00; + case REG_DWG_INDIR_WT: + case REG_DWG_INDIR_WT + 0x04: + case REG_DWG_INDIR_WT + 0x08: + case REG_DWG_INDIR_WT + 0x0c: + case REG_DWG_INDIR_WT + 0x10: + case REG_DWG_INDIR_WT + 0x14: + case REG_DWG_INDIR_WT + 0x18: + case REG_DWG_INDIR_WT + 0x1c: + case REG_DWG_INDIR_WT + 0x20: + case REG_DWG_INDIR_WT + 0x24: + case REG_DWG_INDIR_WT + 0x28: + case REG_DWG_INDIR_WT + 0x2c: + case REG_DWG_INDIR_WT + 0x30: + case REG_DWG_INDIR_WT + 0x34: + case REG_DWG_INDIR_WT + 0x38: + case REG_DWG_INDIR_WT + 0x3c: + reg_addr = (mystique->dmamap[(addr >> 2) & 0xf] & 0x7f) << 2; + if (mystique->dmamap[(addr >> 2) & 0xf] & 0x80) + reg_addr += 0x2c00; + else + reg_addr += 0x1c00; - if ((reg_addr & 0x300) == 0x100) - mystique->blitter_submit_refcount++; + if ((reg_addr & 0x300) == 0x100) + mystique->blitter_submit_refcount++; -// pclog("mystique queue dwg addr=%04x val=%08x\n", reg_addr, val); - mystique_queue(mystique, reg_addr, val, FIFO_WRITE_CTRL_LONG); - break; + // pclog("mystique queue dwg addr=%04x val=%08x\n", reg_addr, val); + mystique_queue(mystique, reg_addr, val, FIFO_WRITE_CTRL_LONG); + break; - default:mystique_ctrl_write_b(addr, val & 0xff, p); - mystique_ctrl_write_b(addr + 1, (val >> 8) & 0xff, p); - mystique_ctrl_write_b(addr + 2, (val >> 16) & 0xff, p); - mystique_ctrl_write_b(addr + 3, (val >> 24) & 0xff, p); - break; - } + default: + mystique_ctrl_write_b(addr, val & 0xff, p); + mystique_ctrl_write_b(addr + 1, (val >> 8) & 0xff, p); + mystique_ctrl_write_b(addr + 2, (val >> 16) & 0xff, p); + mystique_ctrl_write_b(addr + 3, (val >> 24) & 0xff, p); + break; + } } static uint8_t mystique_iload_read_b(uint32_t addr, void *p) { - mystique_t *mystique = (mystique_t *)p; + mystique_t *mystique = (mystique_t *)p; - wait_fifo_idle(mystique); - if (!mystique->busy) { -// fatal("mystique_iload_read_b: %08x !busy\n", addr); - return 0xff; - } + wait_fifo_idle(mystique); + if (!mystique->busy) { + // fatal("mystique_iload_read_b: %08x !busy\n", addr); + return 0xff; + } -// pclog("Readb MGA ILOAD %08x\n", addr); - return blit_idump_read(mystique); + // pclog("Readb MGA ILOAD %08x\n", addr); + return blit_idump_read(mystique); } static uint32_t mystique_iload_read_l(uint32_t addr, void *p) { - mystique_t *mystique = (mystique_t *)p; + mystique_t *mystique = (mystique_t *)p; - wait_fifo_idle(mystique); - if (!mystique->busy) { -// fatal("mystique_iload_read_l: !busy\n"); - return 0xffffffff; - } + wait_fifo_idle(mystique); + if (!mystique->busy) { + // fatal("mystique_iload_read_l: !busy\n"); + return 0xffffffff; + } -// pclog("Readl MGA ILOAD %08x %i\n", addr, mystique->dwgreg.words); - mystique->dwgreg.words++; - return blit_idump_read(mystique); + // pclog("Readl MGA ILOAD %08x %i\n", addr, mystique->dwgreg.words); + mystique->dwgreg.words++; + return blit_idump_read(mystique); } static void mystique_iload_write_b(uint32_t addr, uint8_t val, void *p) { #ifndef RELEASE_BUILD - fatal("Write MGA ILOAD %08x %02x\n", addr, val); + fatal("Write MGA ILOAD %08x %02x\n", addr, val); #endif } static void mystique_iload_write_l(uint32_t addr, uint32_t val, void *p) { - mystique_t *mystique = (mystique_t *)p; + mystique_t *mystique = (mystique_t *)p; -// pclog("mystique queue iload addr=%04x val=%08x\n", addr, val); - mystique_queue(mystique, 0, val, FIFO_WRITE_ILOAD_LONG); + // pclog("mystique queue iload addr=%04x val=%08x\n", addr, val); + mystique_queue(mystique, 0, val, FIFO_WRITE_ILOAD_LONG); } static void mystique_accel_iload_write_l(uint32_t addr, uint32_t val, void *p) { - mystique_t *mystique = (mystique_t *)p; + mystique_t *mystique = (mystique_t *)p; -// pclog(" Write ILOAD %08x %i %i %08x\n", val, mystique->dwgreg.dmamod, mystique->dma.iload_state, mystique->dwgreg.dwgctrl); - switch (mystique->dwgreg.dmamod) { - case DMA_MODE_REG: - if (mystique->dma.iload_state == 0) { -// pclog(" ILOAD header\n"); - mystique->dma.iload_header = val; - mystique->dma.iload_state = 1; - } else { - uint32_t reg_addr = (mystique->dma.iload_header & 0x7f) << 2; - if (mystique->dma.iload_header & 0x80) - reg_addr += 0x2c00; - else - reg_addr += 0x1c00; + // pclog(" Write ILOAD %08x %i %i %08x\n", val, mystique->dwgreg.dmamod, mystique->dma.iload_state, + // mystique->dwgreg.dwgctrl); + switch (mystique->dwgreg.dmamod) { + case DMA_MODE_REG: + if (mystique->dma.iload_state == 0) { + // pclog(" ILOAD header\n"); + mystique->dma.iload_header = val; + mystique->dma.iload_state = 1; + } else { + uint32_t reg_addr = (mystique->dma.iload_header & 0x7f) << 2; + if (mystique->dma.iload_header & 0x80) + reg_addr += 0x2c00; + else + reg_addr += 0x1c00; -// pclog(" ILOAD write %08x to %02x %04x\n", val, mystique->dma.iload_header & 0xff, reg_addr); - if ((reg_addr & 0x300) == 0x100) - mystique->blitter_submit_dma_refcount++; - mystique_accel_ctrl_write_l(reg_addr, val, mystique); + // pclog(" ILOAD write %08x to %02x %04x\n", val, mystique->dma.iload_header & + // 0xff, reg_addr); + if ((reg_addr & 0x300) == 0x100) + mystique->blitter_submit_dma_refcount++; + mystique_accel_ctrl_write_l(reg_addr, val, mystique); - mystique->dma.iload_header >>= 8; - mystique->dma.iload_state = (mystique->dma.iload_state == 4) ? 0 : (mystique->dma.iload_state + 1); - } - break; + mystique->dma.iload_header >>= 8; + mystique->dma.iload_state = (mystique->dma.iload_state == 4) ? 0 : (mystique->dma.iload_state + 1); + } + break; - case DMA_MODE_BLIT: - if (mystique->busy) - blit_iload_write(mystique, val, 32); - break; + case DMA_MODE_BLIT: + if (mystique->busy) + blit_iload_write(mystique, val, 32); + break; #ifndef RELEASE_BUILD - default:fatal("ILOAD write DMAMOD %i\n", mystique->dwgreg.dmamod); + default: + fatal("ILOAD write DMAMOD %i\n", mystique->dwgreg.dmamod); #endif - } + } } static uint8_t mystique_readb_linear(uint32_t addr, void *p) { - svga_t *svga = (svga_t *)p; + svga_t *svga = (svga_t *)p; - egareads++; + egareads++; - cycles -= video_timing_read_b; - cycles_lost += video_timing_read_b; + cycles -= video_timing_read_b; + cycles_lost += video_timing_read_b; - addr &= svga->decode_mask; - if (addr >= svga->vram_max) - return 0xff; + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return 0xff; - return svga->vram[addr & svga->vram_mask]; + return svga->vram[addr & svga->vram_mask]; } static uint16_t mystique_readw_linear(uint32_t addr, void *p) { - svga_t *svga = (svga_t *)p; + svga_t *svga = (svga_t *)p; - egareads += 2; + egareads += 2; - cycles -= video_timing_read_w; - cycles_lost += video_timing_read_w; + cycles -= video_timing_read_w; + cycles_lost += video_timing_read_w; - addr &= svga->decode_mask; - if (addr >= svga->vram_max) - return 0xffff; + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return 0xffff; - return *(uint16_t *)&svga->vram[addr & svga->vram_mask]; + return *(uint16_t *)&svga->vram[addr & svga->vram_mask]; } static uint32_t mystique_readl_linear(uint32_t addr, void *p) { - svga_t *svga = (svga_t *)p; + svga_t *svga = (svga_t *)p; - egareads += 4; + egareads += 4; - cycles -= video_timing_read_l; - cycles_lost += video_timing_read_l; + cycles -= video_timing_read_l; + cycles_lost += video_timing_read_l; - addr &= svga->decode_mask; - if (addr >= svga->vram_max) - return 0xffffffff; + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return 0xffffffff; - return *(uint32_t *)&svga->vram[addr & svga->vram_mask]; + return *(uint32_t *)&svga->vram[addr & svga->vram_mask]; } static void mystique_writeb_linear(uint32_t addr, uint8_t val, void *p) { - svga_t *svga = (svga_t *)p; + svga_t *svga = (svga_t *)p; - egawrites++; + egawrites++; - cycles -= video_timing_write_b; - cycles_lost += video_timing_write_b; + cycles -= video_timing_write_b; + cycles_lost += video_timing_write_b; - addr &= svga->decode_mask; - if (addr >= svga->vram_max) - return; - addr &= svga->vram_mask; - svga->changedvram[addr >> 12] = changeframecount; - svga->vram[addr] = val; + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return; + addr &= svga->vram_mask; + svga->changedvram[addr >> 12] = changeframecount; + svga->vram[addr] = val; } static void mystique_writew_linear(uint32_t addr, uint16_t val, void *p) { - svga_t *svga = (svga_t *)p; + svga_t *svga = (svga_t *)p; - egawrites += 2; + egawrites += 2; - cycles -= video_timing_write_w; - cycles_lost += video_timing_write_w; + cycles -= video_timing_write_w; + cycles_lost += video_timing_write_w; - addr &= svga->decode_mask; - if (addr >= svga->vram_max) - return; - addr &= svga->vram_mask; - svga->changedvram[addr >> 12] = changeframecount; - *(uint16_t *)&svga->vram[addr] = val; + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return; + addr &= svga->vram_mask; + svga->changedvram[addr >> 12] = changeframecount; + *(uint16_t *)&svga->vram[addr] = val; } static void mystique_writel_linear(uint32_t addr, uint32_t val, void *p) { - svga_t *svga = (svga_t *)p; + svga_t *svga = (svga_t *)p; - egawrites += 4; + egawrites += 4; - cycles -= video_timing_write_l; - cycles_lost += video_timing_write_l; + cycles -= video_timing_write_l; + cycles_lost += video_timing_write_l; - addr &= svga->decode_mask; - if (addr >= svga->vram_max) - return; - addr &= svga->vram_mask; - svga->changedvram[addr >> 12] = changeframecount; - *(uint32_t *)&svga->vram[addr] = val; + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return; + addr &= svga->vram_mask; + svga->changedvram[addr >> 12] = changeframecount; + *(uint32_t *)&svga->vram[addr] = val; } static uint32_t mystique_dma_read(uint32_t addr) { - if ((addr & DMA_ADDR_MASK) > (mem_size * 1024)) { -// pclog("PCI DMA out of range\n"); - return -1; - } - return *(uint32_t *)&ram[addr & DMA_ADDR_MASK]; + if ((addr & DMA_ADDR_MASK) > (mem_size * 1024)) { + // pclog("PCI DMA out of range\n"); + return -1; + } + return *(uint32_t *)&ram[addr & DMA_ADDR_MASK]; } static void run_dma(mystique_t *mystique) { - int words_transferred = 0; + int words_transferred = 0; - thread_lock_mutex(mystique->dma.lock); + thread_lock_mutex(mystique->dma.lock); - if (mystique->dma.state == DMA_STATE_IDLE) { - thread_unlock_mutex(mystique->dma.lock); - return; - } + if (mystique->dma.state == DMA_STATE_IDLE) { + thread_unlock_mutex(mystique->dma.lock); + return; + } - while (words_transferred < DMA_MAX_WORDS && mystique->dma.state != DMA_STATE_IDLE) { - switch (mystique->dma.state)// != DMA_STATE_IDLE) - { - case DMA_STATE_PRI: - switch (mystique->dma.primaddress & DMA_MODE_MASK) { - case DMA_MODE_REG: - if (mystique->dma.pri_state == 0) { - mystique->dma.pri_header = mystique_dma_read(mystique->dma.primaddress); -// pclog("DMA pri read header %08x from %08x %08x\n", mystique->dma.pri_header, mystique->dma.primaddress, mystique->dma.primend); - mystique->dma.primaddress += 4; - } + while (words_transferred < DMA_MAX_WORDS && mystique->dma.state != DMA_STATE_IDLE) { + switch (mystique->dma.state) // != DMA_STATE_IDLE) + { + case DMA_STATE_PRI: + switch (mystique->dma.primaddress & DMA_MODE_MASK) { + case DMA_MODE_REG: + if (mystique->dma.pri_state == 0) { + mystique->dma.pri_header = mystique_dma_read(mystique->dma.primaddress); + // pclog("DMA pri read header %08x from %08x + // %08x\n", mystique->dma.pri_header, + // mystique->dma.primaddress, + // mystique->dma.primend); + mystique->dma.primaddress += 4; + } -// if ((mystique->dma.pri_header & 0xff) != 0x15) - { - uint32_t val = mystique_dma_read(mystique->dma.primaddress); - uint32_t reg_addr; + // if ((mystique->dma.pri_header & 0xff) != 0x15) + { + uint32_t val = mystique_dma_read(mystique->dma.primaddress); + uint32_t reg_addr; - mystique->dma.primaddress += 4; + mystique->dma.primaddress += 4; - reg_addr = (mystique->dma.pri_header & 0x7f) << 2; - if (mystique->dma.pri_header & 0x80) - reg_addr += 0x2c00; - else - reg_addr += 0x1c00; + reg_addr = (mystique->dma.pri_header & 0x7f) << 2; + if (mystique->dma.pri_header & 0x80) + reg_addr += 0x2c00; + else + reg_addr += 0x1c00; -// pclog(" DMA pri write %08x to %02x %04x %08x %08x\n", val, mystique->dma.pri_header & 0xff, reg_addr, (mystique->dma.primaddress & DMA_ADDR_MASK), (mystique->dma.primend & DMA_ADDR_MASK)); - if ((reg_addr & 0x300) == 0x100) - mystique->blitter_submit_dma_refcount++; + // pclog(" DMA pri write %08x to %02x %04x %08x + // %08x\n", val, mystique->dma.pri_header & 0xff, + // reg_addr, (mystique->dma.primaddress & + // DMA_ADDR_MASK), (mystique->dma.primend & + // DMA_ADDR_MASK)); + if ((reg_addr & 0x300) == 0x100) + mystique->blitter_submit_dma_refcount++; - mystique_accel_ctrl_write_l(reg_addr, val, mystique); - } + mystique_accel_ctrl_write_l(reg_addr, val, mystique); + } - mystique->dma.pri_header >>= 8; - mystique->dma.pri_state = (mystique->dma.pri_state + 1) & 3; + mystique->dma.pri_header >>= 8; + mystique->dma.pri_state = (mystique->dma.pri_state + 1) & 3; - words_transferred++; - if (mystique->dma.state == DMA_STATE_SEC) - mystique->dma.pri_state = 0; - else if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { -// pclog("DMA pri end\n"); - mystique->endprdmasts_pending = 1; - mystique->dma.state = DMA_STATE_IDLE; - } - break; + words_transferred++; + if (mystique->dma.state == DMA_STATE_SEC) + mystique->dma.pri_state = 0; + else if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { + // pclog("DMA pri end\n"); + mystique->endprdmasts_pending = 1; + mystique->dma.state = DMA_STATE_IDLE; + } + break; #ifndef RELEASE_BUILD - default:fatal("DMA_STATE_PRI: mode %i\n", mystique->dma.primaddress & DMA_MODE_MASK); + default: + fatal("DMA_STATE_PRI: mode %i\n", mystique->dma.primaddress & DMA_MODE_MASK); #endif - } - break; + } + break; - case DMA_STATE_SEC: - switch (mystique->dma.secaddress & DMA_MODE_MASK) { - case DMA_MODE_REG: - if (mystique->dma.sec_state == 0) { - mystique->dma.sec_header = mystique_dma_read(mystique->dma.secaddress); -// pclog("DMA sec read header %08x from %08x %08x\n", mystique->dma.sec_header, mystique->dma.secaddress, mystique->dma.secend); - mystique->dma.secaddress += 4; - } + case DMA_STATE_SEC: + switch (mystique->dma.secaddress & DMA_MODE_MASK) { + case DMA_MODE_REG: + if (mystique->dma.sec_state == 0) { + mystique->dma.sec_header = mystique_dma_read(mystique->dma.secaddress); + // pclog("DMA sec read header %08x from %08x + // %08x\n", mystique->dma.sec_header, + // mystique->dma.secaddress, mystique->dma.secend); + mystique->dma.secaddress += 4; + } -// if ((mystique->dma.sec_header & 0xff) != 0x15) - { - uint32_t val = mystique_dma_read(mystique->dma.secaddress); - uint32_t reg_addr; + // if ((mystique->dma.sec_header & 0xff) != 0x15) + { + uint32_t val = mystique_dma_read(mystique->dma.secaddress); + uint32_t reg_addr; - mystique->dma.secaddress += 4; + mystique->dma.secaddress += 4; - reg_addr = (mystique->dma.sec_header & 0x7f) << 2; - if (mystique->dma.sec_header & 0x80) - reg_addr += 0x2c00; - else - reg_addr += 0x1c00; + reg_addr = (mystique->dma.sec_header & 0x7f) << 2; + if (mystique->dma.sec_header & 0x80) + reg_addr += 0x2c00; + else + reg_addr += 0x1c00; -// pclog(" DMA sec write %08x to %02x %04x %08x %08x\n", val, mystique->dma.sec_header & 0xff, reg_addr, (mystique->dma.secaddress & DMA_ADDR_MASK), (mystique->dma.secend & DMA_ADDR_MASK)); - if ((reg_addr & 0x300) == 0x100) - mystique->blitter_submit_dma_refcount++; + // pclog(" DMA sec write %08x to %02x %04x %08x + // %08x\n", val, mystique->dma.sec_header & 0xff, + // reg_addr, (mystique->dma.secaddress & + // DMA_ADDR_MASK), (mystique->dma.secend & + // DMA_ADDR_MASK)); + if ((reg_addr & 0x300) == 0x100) + mystique->blitter_submit_dma_refcount++; - mystique_accel_ctrl_write_l(reg_addr, val, mystique); - } + mystique_accel_ctrl_write_l(reg_addr, val, mystique); + } - mystique->dma.sec_header >>= 8; - mystique->dma.sec_state = (mystique->dma.sec_state + 1) & 3; + mystique->dma.sec_header >>= 8; + mystique->dma.sec_state = (mystique->dma.sec_state + 1) & 3; - words_transferred++; - if ((mystique->dma.secaddress & DMA_ADDR_MASK) == (mystique->dma.secend & DMA_ADDR_MASK)) { -// pclog("DMA sec end\n"); - if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { -// pclog("DMA pri end\n"); - mystique->endprdmasts_pending = 1; - mystique->dma.state = DMA_STATE_IDLE; - } else { -// pclog("DMA pri resume\n"); - mystique->dma.state = DMA_STATE_PRI; - } - } - break; + words_transferred++; + if ((mystique->dma.secaddress & DMA_ADDR_MASK) == (mystique->dma.secend & DMA_ADDR_MASK)) { + // pclog("DMA sec end\n"); + if ((mystique->dma.primaddress & DMA_ADDR_MASK) == + (mystique->dma.primend & DMA_ADDR_MASK)) { + // pclog("DMA pri end\n"); + mystique->endprdmasts_pending = 1; + mystique->dma.state = DMA_STATE_IDLE; + } else { + // pclog("DMA pri resume\n"); + mystique->dma.state = DMA_STATE_PRI; + } + } + break; - case DMA_MODE_BLIT: { - uint32_t val = mystique_dma_read(mystique->dma.secaddress); -// pclog(" DMA_MODE_BLIT %08x %08x %08x %08x\n", mystique->dma.secaddress & DMA_ADDR_MASK, mystique->dma.secend & DMA_ADDR_MASK, mystique->dwgreg.dwgctrl_running, mystique->maccess_running); - mystique->dma.secaddress += 4; + case DMA_MODE_BLIT: { + uint32_t val = mystique_dma_read(mystique->dma.secaddress); + // pclog(" DMA_MODE_BLIT %08x %08x %08x %08x\n", + // mystique->dma.secaddress & DMA_ADDR_MASK, + // mystique->dma.secend & DMA_ADDR_MASK, + // mystique->dwgreg.dwgctrl_running, + // mystique->maccess_running); + mystique->dma.secaddress += 4; - if (mystique->busy) - blit_iload_write(mystique, val, 32); + if (mystique->busy) + blit_iload_write(mystique, val, 32); - words_transferred++; - if ((mystique->dma.secaddress & DMA_ADDR_MASK) == (mystique->dma.secend & DMA_ADDR_MASK)) { -// pclog("DMA sec end\n"); - if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { -// pclog("DMA pri end\n"); - mystique->endprdmasts_pending = 1; - mystique->dma.state = DMA_STATE_IDLE; - } else { -// pclog("DMA pri resume\n"); - mystique->dma.state = DMA_STATE_PRI; - } - } - } - break; + words_transferred++; + if ((mystique->dma.secaddress & DMA_ADDR_MASK) == (mystique->dma.secend & DMA_ADDR_MASK)) { + // pclog("DMA sec end\n"); + if ((mystique->dma.primaddress & DMA_ADDR_MASK) == + (mystique->dma.primend & DMA_ADDR_MASK)) { + // pclog("DMA pri end\n"); + mystique->endprdmasts_pending = 1; + mystique->dma.state = DMA_STATE_IDLE; + } else { + // pclog("DMA pri + // resume\n"); + mystique->dma.state = DMA_STATE_PRI; + } + } + } break; #ifndef RELEASE_BUILD - default:fatal("DMA_STATE_SEC: mode %i\n", mystique->dma.secaddress & DMA_MODE_MASK); + default: + fatal("DMA_STATE_SEC: mode %i\n", mystique->dma.secaddress & DMA_MODE_MASK); #endif - } - break; - } - } - thread_unlock_mutex(mystique->dma.lock); + } + break; + } + } + thread_unlock_mutex(mystique->dma.lock); } static void fifo_thread(void *p) { - mystique_t *mystique = (mystique_t *)p; + mystique_t *mystique = (mystique_t *)p; - while (1) { - thread_set_event(mystique->fifo_not_full_event); - thread_wait_event(mystique->wake_fifo_thread, -1); - thread_reset_event(mystique->wake_fifo_thread); + while (1) { + thread_set_event(mystique->fifo_not_full_event); + thread_wait_event(mystique->wake_fifo_thread, -1); + thread_reset_event(mystique->wake_fifo_thread); - while (!FIFO_EMPTY || mystique->dma.state != DMA_STATE_IDLE) { - int words_transferred = 0; + while (!FIFO_EMPTY || mystique->dma.state != DMA_STATE_IDLE) { + int words_transferred = 0; - while (!FIFO_EMPTY && words_transferred < 100) { - fifo_entry_t *fifo = &mystique->fifo[mystique->fifo_read_idx & FIFO_MASK]; + while (!FIFO_EMPTY && words_transferred < 100) { + fifo_entry_t *fifo = &mystique->fifo[mystique->fifo_read_idx & FIFO_MASK]; - switch (fifo->addr_type & FIFO_TYPE) { - case FIFO_WRITE_CTRL_BYTE:mystique_accel_ctrl_write_b(fifo->addr_type & FIFO_ADDR, fifo->val, mystique); - break; - case FIFO_WRITE_CTRL_LONG:mystique_accel_ctrl_write_l(fifo->addr_type & FIFO_ADDR, fifo->val, mystique); - break; - case FIFO_WRITE_ILOAD_LONG:mystique_accel_iload_write_l(fifo->addr_type & FIFO_ADDR, fifo->val, mystique); - break; - } + switch (fifo->addr_type & FIFO_TYPE) { + case FIFO_WRITE_CTRL_BYTE: + mystique_accel_ctrl_write_b(fifo->addr_type & FIFO_ADDR, fifo->val, mystique); + break; + case FIFO_WRITE_CTRL_LONG: + mystique_accel_ctrl_write_l(fifo->addr_type & FIFO_ADDR, fifo->val, mystique); + break; + case FIFO_WRITE_ILOAD_LONG: + mystique_accel_iload_write_l(fifo->addr_type & FIFO_ADDR, fifo->val, mystique); + break; + } - fifo->addr_type = FIFO_INVALID; - mystique->fifo_read_idx++; + fifo->addr_type = FIFO_INVALID; + mystique->fifo_read_idx++; - if (FIFO_ENTRIES > FIFO_THRESHOLD) - thread_set_event(mystique->fifo_not_full_event); + if (FIFO_ENTRIES > FIFO_THRESHOLD) + thread_set_event(mystique->fifo_not_full_event); - words_transferred++; - } - /*Only run DMA once the FIFO is empty. Required by + words_transferred++; + } + /*Only run DMA once the FIFO is empty. Required by Screamer 2 / Rally which will incorrectly clip an ILOAD if DMA runs ahead*/ - if (!words_transferred) - run_dma(mystique); - } - } + if (!words_transferred) + run_dma(mystique); + } + } } static void wake_fifo_thread(mystique_t *mystique) { - if (!timer_is_enabled(&mystique->wake_timer)) { - /*Don't wake FIFO thread immediately - if we do that it will probably + if (!timer_is_enabled(&mystique->wake_timer)) { + /*Don't wake FIFO thread immediately - if we do that it will probably process one word and go back to sleep, requiring it to be woken on almost every write. Instead, wait a short while so that the CPU emulation writes more data so we have more batched-up work.*/ - timer_set_delay_u64(&mystique->wake_timer, WAKE_DELAY); - } + timer_set_delay_u64(&mystique->wake_timer, WAKE_DELAY); + } } -static void wake_fifo_thread_now(mystique_t *mystique) { - thread_set_event(mystique->wake_fifo_thread); -} +static void wake_fifo_thread_now(mystique_t *mystique) { thread_set_event(mystique->wake_fifo_thread); } static void mystique_wake_timer(void *p) { - mystique_t *mystique = (mystique_t *)p; + mystique_t *mystique = (mystique_t *)p; - thread_set_event(mystique->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ + thread_set_event(mystique->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ } static void wait_fifo_idle(mystique_t *mystique) { - while (!FIFO_EMPTY) { - wake_fifo_thread_now(mystique); - thread_wait_event(mystique->fifo_not_full_event, 1); - } + while (!FIFO_EMPTY) { + wake_fifo_thread_now(mystique); + thread_wait_event(mystique->fifo_not_full_event, 1); + } } /*IRQ code (PCI & PIC) is not currently thread safe. SOFTRAP IRQ requests must @@ -2581,2732 +2766,3307 @@ static void wait_fifo_idle(mystique_t *mystique) { SOFTRAP IRQs and code reading the status register. Croc will get into an IRQ loop and triple fault if the ENDPRDMASTS flag is seen before the IRQ is taken*/ static void mystique_softrap_pending_timer(void *p) { - mystique_t *mystique = (mystique_t *)p; + mystique_t *mystique = (mystique_t *)p; - timer_advance_u64(&mystique->softrap_pending_timer, TIMER_USEC * 100); + timer_advance_u64(&mystique->softrap_pending_timer, TIMER_USEC * 100); - if (mystique->endprdmasts_pending) { - mystique->endprdmasts_pending = 0; - mystique->status |= STATUS_ENDPRDMASTS; - } - if (mystique->softrap_pending) { - mystique->softrap_pending = 0; + if (mystique->endprdmasts_pending) { + mystique->endprdmasts_pending = 0; + mystique->status |= STATUS_ENDPRDMASTS; + } + if (mystique->softrap_pending) { + mystique->softrap_pending = 0; -// pclog("Take SOFTRAP %08x\n", cpu_state.pc); - mystique->dma.secaddress = mystique->softrap_pending_val; - mystique->status |= STATUS_SOFTRAPEN; - mystique_update_irqs(mystique); - } + // pclog("Take SOFTRAP %08x\n", cpu_state.pc); + mystique->dma.secaddress = mystique->softrap_pending_val; + mystique->status |= STATUS_SOFTRAPEN; + mystique_update_irqs(mystique); + } } static void mystique_queue(mystique_t *mystique, uint32_t addr, uint32_t val, uint32_t type) { - fifo_entry_t *fifo = &mystique->fifo[mystique->fifo_write_idx & FIFO_MASK]; + fifo_entry_t *fifo = &mystique->fifo[mystique->fifo_write_idx & FIFO_MASK]; - if (FIFO_FULL) { - thread_reset_event(mystique->fifo_not_full_event); - if (FIFO_FULL) { - thread_wait_event(mystique->fifo_not_full_event, -1); /*Wait for room in ringbuffer*/ - } - } + if (FIFO_FULL) { + thread_reset_event(mystique->fifo_not_full_event); + if (FIFO_FULL) { + thread_wait_event(mystique->fifo_not_full_event, -1); /*Wait for room in ringbuffer*/ + } + } - fifo->val = val; - fifo->addr_type = (addr & FIFO_ADDR) | type; + fifo->val = val; + fifo->addr_type = (addr & FIFO_ADDR) | type; - mystique->fifo_write_idx++; + mystique->fifo_write_idx++; - if (FIFO_ENTRIES > FIFO_THRESHOLD || FIFO_ENTRIES < 8) - wake_fifo_thread(mystique); + if (FIFO_ENTRIES > FIFO_THRESHOLD || FIFO_ENTRIES < 8) + wake_fifo_thread(mystique); -// wait_fifo_idle(mystique); + // wait_fifo_idle(mystique); } static uint32_t bitop(uint32_t src, uint32_t dst, uint32_t dwgctrl) { - switch (dwgctrl & DWGCTRL_BOP_MASK) { - case BOP(0x0):return 0; - case BOP(0x1):return ~(dst | src); - case BOP(0x2):return dst & ~src; - case BOP(0x3):return ~src; - case BOP(0x4):return ~dst & src; - case BOP(0x5):return ~dst; - case BOP(0x6):return dst ^ src; - case BOP(0x7):return ~(dst & src); - case BOP(0x8):return dst & src; - case BOP(0x9):return ~(dst ^ src); - case BOP(0xa):return dst; - case BOP(0xb):return dst | ~src; - case BOP(0xc):return src; - case BOP(0xd):return ~dst | src; - case BOP(0xe):return dst | src; - case BOP(0xf):return ~0; - } - return 0; + switch (dwgctrl & DWGCTRL_BOP_MASK) { + case BOP(0x0): + return 0; + case BOP(0x1): + return ~(dst | src); + case BOP(0x2): + return dst & ~src; + case BOP(0x3): + return ~src; + case BOP(0x4): + return ~dst & src; + case BOP(0x5): + return ~dst; + case BOP(0x6): + return dst ^ src; + case BOP(0x7): + return ~(dst & src); + case BOP(0x8): + return dst & src; + case BOP(0x9): + return ~(dst ^ src); + case BOP(0xa): + return dst; + case BOP(0xb): + return dst | ~src; + case BOP(0xc): + return src; + case BOP(0xd): + return ~dst | src; + case BOP(0xe): + return dst | src; + case BOP(0xf): + return ~0; + } + return 0; } static uint16_t dither(mystique_t *mystique, int r, int g, int b, int x, int y) { - switch (mystique->dwgreg.dither) { - case DITHER_NONE_555:return (b >> 3) | ((g >> 3) << 5) | ((r >> 3) << 10); + switch (mystique->dwgreg.dither) { + case DITHER_NONE_555: + return (b >> 3) | ((g >> 3) << 5) | ((r >> 3) << 10); - case DITHER_NONE_565:return (b >> 3) | ((g >> 2) << 5) | ((r >> 3) << 11); + case DITHER_NONE_565: + return (b >> 3) | ((g >> 2) << 5) | ((r >> 3) << 11); - case DITHER_555:return dither5[b][y][x] | (dither5[g][y][x] << 5) | (dither5[r][y][x] << 10); + case DITHER_555: + return dither5[b][y][x] | (dither5[g][y][x] << 5) | (dither5[r][y][x] << 10); - case DITHER_565: - default:return dither5[b][y][x] | (dither6[g][y][x] << 5) | (dither5[r][y][x] << 11); - } + case DITHER_565: + default: + return dither5[b][y][x] | (dither6[g][y][x] << 5) | (dither5[r][y][x] << 11); + } } static uint32_t blit_idump_idump(mystique_t *mystique) { - svga_t *svga = &mystique->svga; - uint64_t val64 = 0; - uint32_t val = 0; - int count = 0; + svga_t *svga = &mystique->svga; + uint64_t val64 = 0; + uint32_t val = 0; + int count = 0; - switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { - case DWGCTRL_ATYPE_RPL: - switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { - case DWGCTRL_BLTMOD_BU32RGB: - case DWGCTRL_BLTMOD_BFCOL: - switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { - case MACCESS_PWIDTH_8: -// pclog(" IDUMP %08x\n", mystique->dwgreg.src_addr); - while (count < 32) { - val |= (svga->vram[mystique->dwgreg.src_addr & mystique->vram_mask] << count); + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { + case DWGCTRL_ATYPE_RPL: + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { + case DWGCTRL_BLTMOD_BU32RGB: + case DWGCTRL_BLTMOD_BFCOL: + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_8: + // pclog(" IDUMP %08x\n", mystique->dwgreg.src_addr); + while (count < 32) { + val |= (svga->vram[mystique->dwgreg.src_addr & mystique->vram_mask] << count); - if (mystique->dwgreg.src_addr == mystique->dwgreg.ar[0]) { - mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; - mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; - mystique->dwgreg.src_addr = mystique->dwgreg.ar[3]; - } else - mystique->dwgreg.src_addr++; + if (mystique->dwgreg.src_addr == mystique->dwgreg.ar[0]) { + mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; + mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; + mystique->dwgreg.src_addr = mystique->dwgreg.ar[3]; + } else + mystique->dwgreg.src_addr++; - if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { - mystique->dwgreg.xdst = mystique->dwgreg.fxleft; - mystique->dwgreg.length_cur--; - if (!mystique->dwgreg.length_cur) { - mystique->busy = 0; - mystique->blitter_complete_refcount++; - break; - } - break; - } else - mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; + if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.length_cur--; + if (!mystique->dwgreg.length_cur) { + mystique->busy = 0; + mystique->blitter_complete_refcount++; + break; + } + break; + } else + mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; - count += 8; - } - break; + count += 8; + } + break; - case MACCESS_PWIDTH_16: - // pclog(" IDUMP %08x\n", mystique->dwgreg.src_addr); - while (count < 32) { - val |= (((uint16_t *)svga->vram)[mystique->dwgreg.src_addr & mystique->vram_mask_w] << count); + case MACCESS_PWIDTH_16: + // pclog(" IDUMP %08x\n", mystique->dwgreg.src_addr); + while (count < 32) { + val |= (((uint16_t *)svga->vram)[mystique->dwgreg.src_addr & mystique->vram_mask_w] + << count); - if (mystique->dwgreg.src_addr == mystique->dwgreg.ar[0]) { - mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; - mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; - mystique->dwgreg.src_addr = mystique->dwgreg.ar[3]; - } else - mystique->dwgreg.src_addr++; + if (mystique->dwgreg.src_addr == mystique->dwgreg.ar[0]) { + mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; + mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; + mystique->dwgreg.src_addr = mystique->dwgreg.ar[3]; + } else + mystique->dwgreg.src_addr++; - if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { - mystique->dwgreg.xdst = mystique->dwgreg.fxleft; - mystique->dwgreg.length_cur--; - if (!mystique->dwgreg.length_cur) { - mystique->busy = 0; - mystique->blitter_complete_refcount++; - break; - } - break; - } else - mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; + if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.length_cur--; + if (!mystique->dwgreg.length_cur) { + mystique->busy = 0; + mystique->blitter_complete_refcount++; + break; + } + break; + } else + mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; - count += 16; - } - break; + count += 16; + } + break; - case MACCESS_PWIDTH_24: - if (mystique->dwgreg.idump_end_of_line) { - mystique->dwgreg.idump_end_of_line = 0; - val = mystique->dwgreg.iload_rem_data; - mystique->dwgreg.iload_rem_count = 0; - mystique->dwgreg.iload_rem_data = 0; - if (!mystique->dwgreg.length_cur) { - mystique->busy = 0; - mystique->blitter_complete_refcount++; - } - break; - } + case MACCESS_PWIDTH_24: + if (mystique->dwgreg.idump_end_of_line) { + mystique->dwgreg.idump_end_of_line = 0; + val = mystique->dwgreg.iload_rem_data; + mystique->dwgreg.iload_rem_count = 0; + mystique->dwgreg.iload_rem_data = 0; + if (!mystique->dwgreg.length_cur) { + mystique->busy = 0; + mystique->blitter_complete_refcount++; + } + break; + } - count += mystique->dwgreg.iload_rem_count; - val64 = mystique->dwgreg.iload_rem_data; + count += mystique->dwgreg.iload_rem_count; + val64 = mystique->dwgreg.iload_rem_data; -// pclog(" IDUMP %08x\n", mystique->dwgreg.src_addr); - while ((count < 32) && !mystique->dwgreg.idump_end_of_line) { - val64 |= (uint64_t)((*(uint32_t *)&svga->vram[(mystique->dwgreg.src_addr * 3) & mystique->vram_mask]) & 0xffffff) << count; -/* pclog(" %i %i %i %016llx\n", count, mystique->dwgreg.xdst, - mystique->dwgreg.length_cur, val64);*/ + // pclog(" IDUMP %08x\n", mystique->dwgreg.src_addr); + while ((count < 32) && !mystique->dwgreg.idump_end_of_line) { + val64 |= (uint64_t)((*(uint32_t *)&svga->vram[(mystique->dwgreg.src_addr * 3) & + mystique->vram_mask]) & + 0xffffff) + << count; + /* pclog(" %i %i %i %016llx\n", count, + mystique->dwgreg.xdst, mystique->dwgreg.length_cur, val64);*/ - if (mystique->dwgreg.src_addr == mystique->dwgreg.ar[0]) { - mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; - mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; - mystique->dwgreg.src_addr = mystique->dwgreg.ar[3]; - } else - mystique->dwgreg.src_addr++; + if (mystique->dwgreg.src_addr == mystique->dwgreg.ar[0]) { + mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; + mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; + mystique->dwgreg.src_addr = mystique->dwgreg.ar[3]; + } else + mystique->dwgreg.src_addr++; - if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { - mystique->dwgreg.xdst = mystique->dwgreg.fxleft; - mystique->dwgreg.length_cur--; - if (!mystique->dwgreg.length_cur) { - if (count > 8) - mystique->dwgreg.idump_end_of_line = 1; - else { - count = 32; - mystique->busy = 0; - mystique->blitter_complete_refcount++; - } - break; - } - if (!(mystique->dwgreg.dwgctrl_running & DWGCTRL_LINEAR)) { - if (count > 8) - mystique->dwgreg.idump_end_of_line = 1; - else { - count = 32; - break; - } - } - } else - mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; + if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.length_cur--; + if (!mystique->dwgreg.length_cur) { + if (count > 8) + mystique->dwgreg.idump_end_of_line = 1; + else { + count = 32; + mystique->busy = 0; + mystique->blitter_complete_refcount++; + } + break; + } + if (!(mystique->dwgreg.dwgctrl_running & DWGCTRL_LINEAR)) { + if (count > 8) + mystique->dwgreg.idump_end_of_line = 1; + else { + count = 32; + break; + } + } + } else + mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; - count += 24; - } - if (count > 32) - mystique->dwgreg.iload_rem_count = count - 32; - else - mystique->dwgreg.iload_rem_count = 0; - mystique->dwgreg.iload_rem_data = (uint32_t)(val64 >> 32); - val = val64 & 0xffffffff; - break; + count += 24; + } + if (count > 32) + mystique->dwgreg.iload_rem_count = count - 32; + else + mystique->dwgreg.iload_rem_count = 0; + mystique->dwgreg.iload_rem_data = (uint32_t)(val64 >> 32); + val = val64 & 0xffffffff; + break; - case MACCESS_PWIDTH_32: -// pclog(" IDUMP %08x\n", mystique->dwgreg.src_addr); + case MACCESS_PWIDTH_32: + // pclog(" IDUMP %08x\n", mystique->dwgreg.src_addr); - val = (((uint32_t *)svga->vram)[mystique->dwgreg.src_addr & mystique->vram_mask_l] << count); + val = (((uint32_t *)svga->vram)[mystique->dwgreg.src_addr & mystique->vram_mask_l] << count); - if (mystique->dwgreg.src_addr == mystique->dwgreg.ar[0]) { - mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; - mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; - mystique->dwgreg.src_addr = mystique->dwgreg.ar[3]; - } else - mystique->dwgreg.src_addr++; + if (mystique->dwgreg.src_addr == mystique->dwgreg.ar[0]) { + mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; + mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; + mystique->dwgreg.src_addr = mystique->dwgreg.ar[3]; + } else + mystique->dwgreg.src_addr++; - if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { - mystique->dwgreg.xdst = mystique->dwgreg.fxleft; - mystique->dwgreg.length_cur--; - if (!mystique->dwgreg.length_cur) { - mystique->busy = 0; - mystique->blitter_complete_refcount++; - break; - } - break; - } else - mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; - break; + if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.length_cur--; + if (!mystique->dwgreg.length_cur) { + mystique->busy = 0; + mystique->blitter_complete_refcount++; + break; + } + break; + } else + mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; + break; #ifndef RELEASE_BUILD - default:fatal("IDUMP DWGCTRL_BLTMOD_BU32RGB %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->maccess_running); + default: + fatal("IDUMP DWGCTRL_BLTMOD_BU32RGB %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, + mystique->maccess_running); #endif - } - break; + } + break; #ifndef RELEASE_BUILD - default:fatal("IDUMP DWGCTRL_ATYPE_RPL %08x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK, mystique->dwgreg.dwgctrl_running); - break; + default: + fatal("IDUMP DWGCTRL_ATYPE_RPL %08x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK, + mystique->dwgreg.dwgctrl_running); + break; #endif - } - break; + } + break; #ifndef RELEASE_BUILD - default:fatal("Unknown IDUMP atype %03x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); + default: + fatal("Unknown IDUMP atype %03x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, + mystique->dwgreg.dwgctrl_running); #endif - } + } - return val; + return val; } static uint32_t blit_idump_read(mystique_t *mystique) { - uint32_t ret = 0xffffffff; + uint32_t ret = 0xffffffff; - switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) { - case DWGCTRL_OPCODE_IDUMP:ret = blit_idump_idump(mystique); - break; + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) { + case DWGCTRL_OPCODE_IDUMP: + ret = blit_idump_idump(mystique); + break; #ifndef RELEASE_BUILD - default:fatal("blit_idump_read: bad opcode %08x\n", mystique->dwgreg.dwgctrl_running); + default: + fatal("blit_idump_read: bad opcode %08x\n", mystique->dwgreg.dwgctrl_running); #endif - } + } -// pclog(" idump returned %08x\n", ret); - return ret; + // pclog(" idump returned %08x\n", ret); + return ret; } static void blit_iload_iload(mystique_t *mystique, uint32_t data, int size) { - svga_t *svga = &mystique->svga; - uint32_t src, dst; - uint64_t data64; - int min_size; - uint32_t bltckey = mystique->dwgreg.fcol, bltcmsk = mystique->dwgreg.bcol; - const int transc = mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC; - const int trans_sel = (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANS_MASK) >> DWGCTRL_TRANS_SHIFT; - uint8_t const *const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; - uint32_t data_mask = 1; + svga_t *svga = &mystique->svga; + uint32_t src, dst; + uint64_t data64; + int min_size; + uint32_t bltckey = mystique->dwgreg.fcol, bltcmsk = mystique->dwgreg.bcol; + const int transc = mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC; + const int trans_sel = (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANS_MASK) >> DWGCTRL_TRANS_SHIFT; + uint8_t const *const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; + uint32_t data_mask = 1; - switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { - case MACCESS_PWIDTH_8:bltckey &= 0xff; - bltcmsk &= 0xff; - break; - case MACCESS_PWIDTH_16:bltckey &= 0xffff; - bltcmsk &= 0xffff; - break; - } + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_8: + bltckey &= 0xff; + bltcmsk &= 0xff; + break; + case MACCESS_PWIDTH_16: + bltckey &= 0xffff; + bltcmsk &= 0xffff; + break; + } - mystique->dwgreg.words++; -// pclog("blit_iload_iload: %08x %06x %02x %i %08x words=%i %08x %08x\n", data, mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst, data, (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) == DWGCTRL_BLTMOD_BMONOWF, mystique->dwgreg.dwgctrl_running, mystique->dwgreg.words,mystique->dwgreg.words, mystique->maccess_running); - switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { - case DWGCTRL_ATYPE_RPL: - if (mystique->maccess_running & MACCESS_TLUTLOAD) { - while ((mystique->dwgreg.length_cur > 0) && (size >= 16)) { - uint16_t src = data & 0xffff; -// pclog(" LUT[%02x]=%04x\n", mystique->dwgreg.ydst & 0xff, src); + mystique->dwgreg.words++; + // pclog("blit_iload_iload: %08x %06x %02x %i %08x words=%i %08x %08x\n", data, mystique->dwgreg.ydst_lin + + // mystique->dwgreg.xdst, data, (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) == DWGCTRL_BLTMOD_BMONOWF, + // mystique->dwgreg.dwgctrl_running, mystique->dwgreg.words,mystique->dwgreg.words, mystique->maccess_running); + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { + case DWGCTRL_ATYPE_RPL: + if (mystique->maccess_running & MACCESS_TLUTLOAD) { + while ((mystique->dwgreg.length_cur > 0) && (size >= 16)) { + uint16_t src = data & 0xffff; + // pclog(" LUT[%02x]=%04x\n", mystique->dwgreg.ydst & 0xff, src); - mystique->lut[mystique->dwgreg.ydst & 0xff].r = (src >> 11) << 3; - mystique->lut[mystique->dwgreg.ydst & 0xff].g = ((src >> 5) & 0x3f) << 2; - mystique->lut[mystique->dwgreg.ydst & 0xff].b = (src & 0x1f) << 3; - mystique->dwgreg.ydst++; - mystique->dwgreg.length_cur--; - data >>= 16; - size -= 16; - } + mystique->lut[mystique->dwgreg.ydst & 0xff].r = (src >> 11) << 3; + mystique->lut[mystique->dwgreg.ydst & 0xff].g = ((src >> 5) & 0x3f) << 2; + mystique->lut[mystique->dwgreg.ydst & 0xff].b = (src & 0x1f) << 3; + mystique->dwgreg.ydst++; + mystique->dwgreg.length_cur--; + data >>= 16; + size -= 16; + } - if (!mystique->dwgreg.length_cur) { - mystique->busy = 0; - mystique->blitter_complete_refcount++; - } - break; - } - case DWGCTRL_ATYPE_RSTR: - case DWGCTRL_ATYPE_BLK: - switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { - case DWGCTRL_BLTMOD_BFCOL:size += mystique->dwgreg.iload_rem_count; -// pclog(" size=%i xdst=%i cur=%i data= %08x %08x ", size, mystique->dwgreg.xdst, mystique->dwgreg.length_cur, mystique->dwgreg.iload_rem_data, data); - data64 = mystique->dwgreg.iload_rem_data | ((uint64_t)data << mystique->dwgreg.iload_rem_count); -// pclog("%016llx words=%i\n", data64, mystique->dwgreg.words); + if (!mystique->dwgreg.length_cur) { + mystique->busy = 0; + mystique->blitter_complete_refcount++; + } + break; + } + case DWGCTRL_ATYPE_RSTR: + case DWGCTRL_ATYPE_BLK: + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { + case DWGCTRL_BLTMOD_BFCOL: + size += mystique->dwgreg.iload_rem_count; + // pclog(" size=%i xdst=%i cur=%i data= %08x %08x ", size, + // mystique->dwgreg.xdst, mystique->dwgreg.length_cur, + // mystique->dwgreg.iload_rem_data, data); + data64 = mystique->dwgreg.iload_rem_data | ((uint64_t)data << mystique->dwgreg.iload_rem_count); + // pclog("%016llx words=%i\n", data64, mystique->dwgreg.words); - switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { - case MACCESS_PWIDTH_8:min_size = 8; - break; - case MACCESS_PWIDTH_16:min_size = 16; - break; - case MACCESS_PWIDTH_24:min_size = 24; - break; - case MACCESS_PWIDTH_32:min_size = 32; - break; - } + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_8: + min_size = 8; + break; + case MACCESS_PWIDTH_16: + min_size = 16; + break; + case MACCESS_PWIDTH_24: + min_size = 24; + break; + case MACCESS_PWIDTH_32: + min_size = 32; + break; + } - while (size >= min_size) { - int draw = (!transc || (data & bltcmsk) != bltckey) && trans[mystique->dwgreg.xdst & 3]; + while (size >= min_size) { + int draw = (!transc || (data & bltcmsk) != bltckey) && trans[mystique->dwgreg.xdst & 3]; - switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { - case MACCESS_PWIDTH_8: - if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && - mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && draw) { - dst = svga->vram[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask]; + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_8: + if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && + mystique->dwgreg.xdst <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && + mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && draw) { + dst = svga->vram[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & + mystique->vram_mask]; - dst = bitop(data & 0xff, dst, mystique->dwgreg.dwgctrl_running); -// pclog(" 8 %06x=%04x\n", mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst, dst); - svga->vram[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask) >> 12] = changeframecount; - } -/* else - pclog(" Clipped %i,%i %i %08x,%08x %08x\n", - mystique->dwgreg.cxleft, mystique->dwgreg.cxright, mystique->dwgreg.xdst, - mystique->dwgreg.ytop, mystique->dwgreg.ybot, mystique->dwgreg.ydst_lin);*/ + dst = bitop(data & 0xff, dst, mystique->dwgreg.dwgctrl_running); + // pclog(" 8 %06x=%04x\n", + // mystique->dwgreg.ydst_lin + + // mystique->dwgreg.xdst, dst); + svga->vram[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & + mystique->vram_mask] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & + mystique->vram_mask) >> + 12] = changeframecount; + } + /* else + pclog(" Clipped %i,%i %i %08x,%08x + %08x\n", mystique->dwgreg.cxleft, mystique->dwgreg.cxright, mystique->dwgreg.xdst, + mystique->dwgreg.ytop, + mystique->dwgreg.ybot, mystique->dwgreg.ydst_lin);*/ - data >>= 8; - size -= 8; - break; + data >>= 8; + size -= 8; + break; - case MACCESS_PWIDTH_16: - if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && - mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && draw) { - dst = ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w]; + case MACCESS_PWIDTH_16: + if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && + mystique->dwgreg.xdst <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && + mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && draw) { + dst = ((uint16_t *) + svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & + mystique->vram_mask_w]; - dst = bitop(data & 0xffff, dst, mystique->dwgreg.dwgctrl_running); -// pclog(" 16 %06x=%04x\n", mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst, dst); - ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w) >> 11] = changeframecount; - } + dst = bitop(data & 0xffff, dst, mystique->dwgreg.dwgctrl_running); + // pclog(" 16 %06x=%04x\n", + // mystique->dwgreg.ydst_lin + + // mystique->dwgreg.xdst, dst); + ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & + mystique->vram_mask_w] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & + mystique->vram_mask_w) >> + 11] = changeframecount; + } - data >>= 16; - size -= 16; - break; + data >>= 16; + size -= 16; + break; - case MACCESS_PWIDTH_24: - if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && - mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { - uint32_t old_dst = *((uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) * 3) & mystique->vram_mask]); + case MACCESS_PWIDTH_24: + if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && + mystique->dwgreg.xdst <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && + mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { + uint32_t old_dst = *( + (uint32_t *)&svga + ->vram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) * 3) & + mystique->vram_mask]); - dst = bitop(data64, old_dst, mystique->dwgreg.dwgctrl_running); - *((uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) * 3) & mystique->vram_mask]) = (dst & 0xffffff) | (old_dst & 0xff000000); - svga->changedvram[(((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) * 3) & mystique->vram_mask) >> 12] = changeframecount; - } + dst = bitop(data64, old_dst, mystique->dwgreg.dwgctrl_running); + *((uint32_t *)&svga + ->vram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) * 3) & + mystique->vram_mask]) = + (dst & 0xffffff) | (old_dst & 0xff000000); + svga->changedvram[(((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) * 3) & + mystique->vram_mask) >> + 12] = changeframecount; + } - data64 >>= 24; - size -= 24; - break; + data64 >>= 24; + size -= 24; + break; - case MACCESS_PWIDTH_32: - if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && - mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && draw) { - dst = ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l]; + case MACCESS_PWIDTH_32: + if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && + mystique->dwgreg.xdst <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && + mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && draw) { + dst = ((uint32_t *) + svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & + mystique->vram_mask_l]; - dst = bitop(data, dst, mystique->dwgreg.dwgctrl_running); -// pclog(" 32 %06x=%04x\n", mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst, dst); - ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l) >> 10] = changeframecount; - } + dst = bitop(data, dst, mystique->dwgreg.dwgctrl_running); + // pclog(" 32 %06x=%04x\n", + // mystique->dwgreg.ydst_lin + + // mystique->dwgreg.xdst, dst); + ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & + mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & + mystique->vram_mask_l) >> + 10] = changeframecount; + } - size = 0; - break; + size = 0; + break; #ifndef RELEASE_BUILD - default:fatal("ILOAD RSTR/RPL BFCOL pwidth %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK); + default: + fatal("ILOAD RSTR/RPL BFCOL pwidth %08x\n", + mystique->maccess_running & MACCESS_PWIDTH_MASK); #endif - } + } - if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { - mystique->dwgreg.xdst = mystique->dwgreg.fxleft; - mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); - mystique->dwgreg.selline = (mystique->dwgreg.selline + 1) & 7; - mystique->dwgreg.length_cur--; - if (!mystique->dwgreg.length_cur) { - mystique->busy = 0; - mystique->blitter_complete_refcount++; - break; - } - data64 = 0; - size = 0; - break; - } else - mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; - } - mystique->dwgreg.iload_rem_count = size; - mystique->dwgreg.iload_rem_data = data64; - break; + if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + mystique->dwgreg.selline = (mystique->dwgreg.selline + 1) & 7; + mystique->dwgreg.length_cur--; + if (!mystique->dwgreg.length_cur) { + mystique->busy = 0; + mystique->blitter_complete_refcount++; + break; + } + data64 = 0; + size = 0; + break; + } else + mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; + } + mystique->dwgreg.iload_rem_count = size; + mystique->dwgreg.iload_rem_data = data64; + break; - case DWGCTRL_BLTMOD_BMONOWF:data = (data >> 24) | ((data & 0x00ff0000) >> 8) | ((data & 0x0000ff00) << 8) | (data << 24); - data_mask = (1 << 31); - case DWGCTRL_BLTMOD_BMONOLEF: - while (size) { - if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && - mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && - ((data & data_mask) || !(mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC)) && - trans[mystique->dwgreg.xdst & 3]) { - uint32_t old_dst; + case DWGCTRL_BLTMOD_BMONOWF: + data = (data >> 24) | ((data & 0x00ff0000) >> 8) | ((data & 0x0000ff00) << 8) | (data << 24); + data_mask = (1 << 31); + case DWGCTRL_BLTMOD_BMONOLEF: + while (size) { + if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && + mystique->dwgreg.xdst <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && + mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && + ((data & data_mask) || !(mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC)) && + trans[mystique->dwgreg.xdst & 3]) { + uint32_t old_dst; - src = (data & data_mask) ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; - switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { - case MACCESS_PWIDTH_8:dst = svga->vram[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask]; + src = (data & data_mask) ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_8: + dst = svga->vram[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & + mystique->vram_mask]; -// pclog(" %02x %02x %06x ", src, dst, mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst); - dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); -// pclog("%02x\n", dst); + // pclog(" %02x %02x %06x ", src, + // dst, mystique->dwgreg.ydst_lin + + // mystique->dwgreg.xdst); + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); + // pclog("%02x\n", dst); - svga->vram[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask) >> 12] = changeframecount; - break; + svga->vram[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & + mystique->vram_mask] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & + mystique->vram_mask) >> + 12] = changeframecount; + break; - case MACCESS_PWIDTH_16:dst = ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w]; + case MACCESS_PWIDTH_16: + dst = ((uint16_t *) + svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & + mystique->vram_mask_w]; -// pclog(" %02x %02x %06x ", src, dst, mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst); - dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); -// pclog("%02x\n", dst); + // pclog(" %02x %02x %06x ", src, + // dst, mystique->dwgreg.ydst_lin + + // mystique->dwgreg.xdst); + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); + // pclog("%02x\n", dst); - ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w) >> 11] = changeframecount; - break; + ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & + mystique->vram_mask_w] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & + mystique->vram_mask_w) >> + 11] = changeframecount; + break; - case MACCESS_PWIDTH_24:old_dst = *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) * 3) & mystique->vram_mask]; + case MACCESS_PWIDTH_24: + old_dst = *(uint32_t *)&svga + ->vram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) * + 3) & + mystique->vram_mask]; -// pclog(" %02x %02x %06x ", src, old_dst, mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst); - dst = bitop(src, old_dst, mystique->dwgreg.dwgctrl_running); -// pclog("%02x %08x %08x %08x %i\n", dst, data, mystique->dwgreg.fcol, mystique->dwgreg.bcol, mystique->dwgreg.xdst); + // pclog(" %02x %02x %06x ", src, + // old_dst, + // mystique->dwgreg.ydst_lin + + // mystique->dwgreg.xdst); + dst = bitop(src, old_dst, mystique->dwgreg.dwgctrl_running); + // pclog("%02x %08x %08x %08x + // %i\n", dst, data, + // mystique->dwgreg.fcol, + // mystique->dwgreg.bcol, + // mystique->dwgreg.xdst); - *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) * 3) & mystique->vram_mask] = (dst & 0xffffff) | (old_dst & 0xff000000); - svga->changedvram[(((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) * 3) & mystique->vram_mask) >> 12] = changeframecount; - break; + *(uint32_t *)&svga + ->vram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) * 3) & + mystique->vram_mask] = (dst & 0xffffff) | (old_dst & 0xff000000); + svga->changedvram[(((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) * 3) & + mystique->vram_mask) >> + 12] = changeframecount; + break; - case MACCESS_PWIDTH_32:dst = ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l]; + case MACCESS_PWIDTH_32: + dst = ((uint32_t *) + svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & + mystique->vram_mask_l]; -// pclog(" %02x %02x %06x ", src, dst, mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst); - dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); -// pclog("%02x %08x %08x %08x %i\n", dst, data, mystique->dwgreg.fcol, mystique->dwgreg.bcol, mystique->dwgreg.xdst); + // pclog(" %02x %02x %06x ", src, + // dst, mystique->dwgreg.ydst_lin + + // mystique->dwgreg.xdst); + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); + // pclog("%02x %08x %08x %08x + // %i\n", dst, data, + // mystique->dwgreg.fcol, + // mystique->dwgreg.bcol, + // mystique->dwgreg.xdst); - ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l) >> 10] = changeframecount; - break; + ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & + mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & + mystique->vram_mask_l) >> + 10] = changeframecount; + break; #ifndef RELEASE_BUILD - default:fatal("ILOAD RSTR/RPL BMONOWF pwidth %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK); + default: + fatal("ILOAD RSTR/RPL BMONOWF pwidth %08x\n", + mystique->maccess_running & MACCESS_PWIDTH_MASK); #endif - } - } + } + } - if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { - mystique->dwgreg.xdst = mystique->dwgreg.fxleft; - mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); - mystique->dwgreg.length_cur--; - if (!mystique->dwgreg.length_cur) { - mystique->busy = 0; - mystique->blitter_complete_refcount++; - break; - } - if (!(mystique->dwgreg.dwgctrl_running & DWGCTRL_LINEAR)) - break; - } else - mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; - if (data_mask == 1) - data >>= 1; - else - data <<= 1; - size--; - } - break; + if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + mystique->dwgreg.length_cur--; + if (!mystique->dwgreg.length_cur) { + mystique->busy = 0; + mystique->blitter_complete_refcount++; + break; + } + if (!(mystique->dwgreg.dwgctrl_running & DWGCTRL_LINEAR)) + break; + } else + mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; + if (data_mask == 1) + data >>= 1; + else + data <<= 1; + size--; + } + break; - case DWGCTRL_BLTMOD_BU24RGB:size += mystique->dwgreg.iload_rem_count; -// pclog(" size=%i data= %08x %08x ", size, mystique->dwgreg.iload_rem_data, data); - data64 = mystique->dwgreg.iload_rem_data | ((uint64_t)data << mystique->dwgreg.iload_rem_count); -// pclog("%016llx\n", data64); + case DWGCTRL_BLTMOD_BU24RGB: + size += mystique->dwgreg.iload_rem_count; + // pclog(" size=%i data= %08x %08x ", size, mystique->dwgreg.iload_rem_data, + // data); + data64 = mystique->dwgreg.iload_rem_data | ((uint64_t)data << mystique->dwgreg.iload_rem_count); + // pclog("%016llx\n", data64); - while (size >= 24) { - if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && - mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { - switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { - case MACCESS_PWIDTH_32:dst = ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l]; + while (size >= 24) { + if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && + mystique->dwgreg.xdst <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && + mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_32: + dst = ((uint32_t *) + svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & + mystique->vram_mask_l]; -// pclog(" %06llx %02x %06x ", data64 & 0xffffff, dst, mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst); -// pclog("x=%i l=%i ", mystique->dwgreg.xdst, mystique->dwgreg.length_cur); - dst = bitop(data64 & 0xffffff, dst, mystique->dwgreg.dwgctrl_running); -// pclog("%02x\n", dst); + // pclog(" %06llx %02x %06x ", + // data64 & 0xffffff, dst, + // mystique->dwgreg.ydst_lin + + // mystique->dwgreg.xdst); + // pclog("x=%i l=%i ", + // mystique->dwgreg.xdst, + // mystique->dwgreg.length_cur); + dst = bitop(data64 & 0xffffff, dst, mystique->dwgreg.dwgctrl_running); + // pclog("%02x\n", dst); - ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l) >> 10] = changeframecount; - break; + ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & + mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & + mystique->vram_mask_l) >> + 10] = changeframecount; + break; #ifndef RELEASE_BUILD - default:fatal("ILOAD RSTR/RPL BU24RGB pwidth %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK); + default: + fatal("ILOAD RSTR/RPL BU24RGB pwidth %08x\n", + mystique->maccess_running & MACCESS_PWIDTH_MASK); #endif - } - } + } + } - data64 >>= 24; - size -= 24; - if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { - mystique->dwgreg.xdst = mystique->dwgreg.fxleft; - mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); - mystique->dwgreg.length_cur--; - if (!mystique->dwgreg.length_cur) { - mystique->busy = 0; - mystique->blitter_complete_refcount++; - break; - } - data64 = 0; - size = 0; - break; - } else - mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; - } + data64 >>= 24; + size -= 24; + if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + mystique->dwgreg.length_cur--; + if (!mystique->dwgreg.length_cur) { + mystique->busy = 0; + mystique->blitter_complete_refcount++; + break; + } + data64 = 0; + size = 0; + break; + } else + mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; + } - mystique->dwgreg.iload_rem_count = size; - mystique->dwgreg.iload_rem_data = data64; - break; + mystique->dwgreg.iload_rem_count = size; + mystique->dwgreg.iload_rem_data = data64; + break; - case DWGCTRL_BLTMOD_BU32RGB:size += mystique->dwgreg.iload_rem_count; -// pclog(" size=%i xdst=%i cur=%i data= %08x %08x ", size, mystique->dwgreg.xdst, mystique->dwgreg.length_cur, mystique->dwgreg.iload_rem_data, data); - data64 = mystique->dwgreg.iload_rem_data | ((uint64_t)data << mystique->dwgreg.iload_rem_count); -// pclog("%016llx words=%i\n", data64, mystique->dwgreg.words); + case DWGCTRL_BLTMOD_BU32RGB: + size += mystique->dwgreg.iload_rem_count; + // pclog(" size=%i xdst=%i cur=%i data= %08x %08x ", size, + // mystique->dwgreg.xdst, mystique->dwgreg.length_cur, + // mystique->dwgreg.iload_rem_data, data); + data64 = mystique->dwgreg.iload_rem_data | ((uint64_t)data << mystique->dwgreg.iload_rem_count); + // pclog("%016llx words=%i\n", data64, mystique->dwgreg.words); - while (size >= 32) { - int draw = (!transc || (data & bltcmsk) != bltckey) && trans[mystique->dwgreg.xdst & 3]; + while (size >= 32) { + int draw = (!transc || (data & bltcmsk) != bltckey) && trans[mystique->dwgreg.xdst & 3]; - if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && - mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && draw) { - dst = ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l]; + if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && + mystique->dwgreg.xdst <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && + mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && draw) { + dst = ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & + mystique->vram_mask_l]; - dst = bitop(data, dst, mystique->dwgreg.dwgctrl_running); - ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l) >> 10] = changeframecount; - } + dst = bitop(data, dst, mystique->dwgreg.dwgctrl_running); + ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & + mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & + mystique->vram_mask_l) >> + 10] = changeframecount; + } - size = 0; + size = 0; - if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { - mystique->dwgreg.xdst = mystique->dwgreg.fxleft; - mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); - mystique->dwgreg.selline = (mystique->dwgreg.selline + 1) & 7; - mystique->dwgreg.length_cur--; - if (!mystique->dwgreg.length_cur) { - mystique->busy = 0; - mystique->blitter_complete_refcount++; - break; - } - data64 = 0; - size = 0; - break; - } else - mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; - } - mystique->dwgreg.iload_rem_count = size; - mystique->dwgreg.iload_rem_data = data64; - break; + if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + mystique->dwgreg.selline = (mystique->dwgreg.selline + 1) & 7; + mystique->dwgreg.length_cur--; + if (!mystique->dwgreg.length_cur) { + mystique->busy = 0; + mystique->blitter_complete_refcount++; + break; + } + data64 = 0; + size = 0; + break; + } else + mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; + } + mystique->dwgreg.iload_rem_count = size; + mystique->dwgreg.iload_rem_data = data64; + break; #ifndef RELEASE_BUILD - default:fatal("ILOAD DWGCTRL_ATYPE_RPL\n"); - break; + default: + fatal("ILOAD DWGCTRL_ATYPE_RPL\n"); + break; #endif - } - break; + } + break; #ifndef RELEASE_BUILD - default:fatal("Unknown ILOAD iload atype %03x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); + default: + fatal("Unknown ILOAD iload atype %03x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, + mystique->dwgreg.dwgctrl_running); #endif - } + } } -#define CLAMP(x) do \ - { \ - if ((x) & ~0xff) \ - x = ((x) < 0) ? 0 : 0xff; \ - } \ - while (0) +#define CLAMP(x) \ + do { \ + if ((x) & ~0xff) \ + x = ((x) < 0) ? 0 : 0xff; \ + } while (0) static void blit_iload_iload_scale(mystique_t *mystique, uint32_t data, int size) { - svga_t *svga = &mystique->svga; - uint64_t data64 = 0; - int y0, y1; - int u, v; - int dR, dG, dB; - int r0, g0, b0; - int r1, g1, b1; + svga_t *svga = &mystique->svga; + uint64_t data64 = 0; + int y0, y1; + int u, v; + int dR, dG, dB; + int r0, g0, b0; + int r1, g1, b1; -// pclog(" iload_scale: data=%08x\n", data); + // pclog(" iload_scale: data=%08x\n", data); - switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { - case DWGCTRL_BLTMOD_BUYUV:y0 = (298 * ((int)(data & 0xff) - 16)) >> 8; - u = ((data >> 8) & 0xff) - 0x80; - y1 = (298 * ((int)((data >> 16) & 0xff) - 16)) >> 8; - v = ((data >> 24) & 0xff) - 0x80; + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { + case DWGCTRL_BLTMOD_BUYUV: + y0 = (298 * ((int)(data & 0xff) - 16)) >> 8; + u = ((data >> 8) & 0xff) - 0x80; + y1 = (298 * ((int)((data >> 16) & 0xff) - 16)) >> 8; + v = ((data >> 24) & 0xff) - 0x80; - dR = (309 * v) >> 8; - dG = (100 * u + 208 * v) >> 8; - dB = (516 * u) >> 8; + dR = (309 * v) >> 8; + dG = (100 * u + 208 * v) >> 8; + dB = (516 * u) >> 8; - r0 = y0 + dR; - CLAMP(r0); - g0 = y0 - dG; - CLAMP(g0); - b0 = y0 + dB; - CLAMP(b0); - r1 = y1 + dR; - CLAMP(r1); - g1 = y1 - dG; - CLAMP(g1); - b1 = y1 + dB; - CLAMP(b1); + r0 = y0 + dR; + CLAMP(r0); + g0 = y0 - dG; + CLAMP(g0); + b0 = y0 + dB; + CLAMP(b0); + r1 = y1 + dR; + CLAMP(r1); + g1 = y1 - dG; + CLAMP(g1); + b1 = y1 + dB; + CLAMP(b1); - switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { - case MACCESS_PWIDTH_16:data = (b0 >> 3) | ((g0 >> 2) << 5) | ((r0 >> 3) << 11); - data |= (((b1 >> 3) | ((g1 >> 2) << 5) | ((r1 >> 3) << 11)) << 16); - size = 32; - break; - case MACCESS_PWIDTH_32:data64 = b0 | (g0 << 8) | (r0 << 16); - data64 |= ((uint64_t)b0 << 32) | ((uint64_t)g0 << 40) | ((uint64_t)r0 << 48); - size = 64; - break; + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_16: + data = (b0 >> 3) | ((g0 >> 2) << 5) | ((r0 >> 3) << 11); + data |= (((b1 >> 3) | ((g1 >> 2) << 5) | ((r1 >> 3) << 11)) << 16); + size = 32; + break; + case MACCESS_PWIDTH_32: + data64 = b0 | (g0 << 8) | (r0 << 16); + data64 |= ((uint64_t)b0 << 32) | ((uint64_t)g0 << 40) | ((uint64_t)r0 << 48); + size = 64; + break; #ifndef RELEASE_BUILD - default:fatal("blit_iload_iload_scale BUYUV pwidth %i\n", mystique->maccess_running & MACCESS_PWIDTH_MASK); + default: + fatal("blit_iload_iload_scale BUYUV pwidth %i\n", mystique->maccess_running & MACCESS_PWIDTH_MASK); #endif - } - break; + } + break; #ifndef RELEASE_BUILD - default:fatal("blit_iload_iload_scale bltmod %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK); - break; + default: + fatal("blit_iload_iload_scale bltmod %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK); + break; #endif - } + } - switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { - case MACCESS_PWIDTH_16: - while (size >= 16) { -// pclog(" Write %i %i %08x\n", mystique->dwgreg.xdst, mystique->dwgreg.fxright, mystique->dwgreg.ar[6]); - if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && - mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { - uint16_t dst = ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w]; - dst = bitop(data & 0xffff, dst, mystique->dwgreg.dwgctrl_running); - ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w) >> 11] = changeframecount; - } + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_16: + while (size >= 16) { + // pclog(" Write %i %i %08x\n", mystique->dwgreg.xdst, mystique->dwgreg.fxright, + // mystique->dwgreg.ar[6]); + if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && + mystique->dwgreg.xdst <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && + mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { + uint16_t dst = ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & + mystique->vram_mask_w]; + dst = bitop(data & 0xffff, dst, mystique->dwgreg.dwgctrl_running); + ((uint16_t *)svga + ->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w] = + dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w) >> + 11] = changeframecount; + } - mystique->dwgreg.ar[6] += mystique->dwgreg.ar[2]; - if ((int32_t)mystique->dwgreg.ar[6] >= 0) { - mystique->dwgreg.ar[6] -= (mystique->dwgreg.fxright - mystique->dwgreg.fxleft); - data >>= 16; - size -= 16; - } + mystique->dwgreg.ar[6] += mystique->dwgreg.ar[2]; + if ((int32_t)mystique->dwgreg.ar[6] >= 0) { + mystique->dwgreg.ar[6] -= (mystique->dwgreg.fxright - mystique->dwgreg.fxleft); + data >>= 16; + size -= 16; + } - mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; - if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { - mystique->dwgreg.xdst = mystique->dwgreg.fxleft; - mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); - mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; - mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; - mystique->dwgreg.ar[6] = mystique->dwgreg.ar[2] - (mystique->dwgreg.fxright - mystique->dwgreg.fxleft); - mystique->dwgreg.length_cur--; - if (!mystique->dwgreg.length_cur) { - mystique->busy = 0; - mystique->blitter_complete_refcount++; - break; - } - break; - } - } - break; + mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; + if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; + mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; + mystique->dwgreg.ar[6] = + mystique->dwgreg.ar[2] - (mystique->dwgreg.fxright - mystique->dwgreg.fxleft); + mystique->dwgreg.length_cur--; + if (!mystique->dwgreg.length_cur) { + mystique->busy = 0; + mystique->blitter_complete_refcount++; + break; + } + break; + } + } + break; - case MACCESS_PWIDTH_32: - while (size >= 32) { -// pclog(" Write %i %i %08x\n", mystique->dwgreg.xdst, mystique->dwgreg.fxright, mystique->dwgreg.ar[6]); - if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && - mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { - uint32_t dst = ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l]; - dst = bitop(data64, dst, mystique->dwgreg.dwgctrl_running); - ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l) >> 10] = changeframecount; - } + case MACCESS_PWIDTH_32: + while (size >= 32) { + // pclog(" Write %i %i %08x\n", mystique->dwgreg.xdst, mystique->dwgreg.fxright, + // mystique->dwgreg.ar[6]); + if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && + mystique->dwgreg.xdst <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && + mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { + uint32_t dst = ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & + mystique->vram_mask_l]; + dst = bitop(data64, dst, mystique->dwgreg.dwgctrl_running); + ((uint32_t *)svga + ->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l] = + dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l) >> + 10] = changeframecount; + } - mystique->dwgreg.ar[6] += mystique->dwgreg.ar[2]; - if ((int32_t)mystique->dwgreg.ar[6] >= 0) { - mystique->dwgreg.ar[6] -= (mystique->dwgreg.fxright - mystique->dwgreg.fxleft); - data64 >>= 32; - size -= 32; - } + mystique->dwgreg.ar[6] += mystique->dwgreg.ar[2]; + if ((int32_t)mystique->dwgreg.ar[6] >= 0) { + mystique->dwgreg.ar[6] -= (mystique->dwgreg.fxright - mystique->dwgreg.fxleft); + data64 >>= 32; + size -= 32; + } - mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; - if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { - mystique->dwgreg.xdst = mystique->dwgreg.fxleft; - mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); - mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; - mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; - mystique->dwgreg.ar[6] = mystique->dwgreg.ar[2] - (mystique->dwgreg.fxright - mystique->dwgreg.fxleft); - mystique->dwgreg.length_cur--; - if (!mystique->dwgreg.length_cur) { - mystique->busy = 0; - mystique->blitter_complete_refcount++; - break; - } - break; - } - } - break; + mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; + if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; + mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; + mystique->dwgreg.ar[6] = + mystique->dwgreg.ar[2] - (mystique->dwgreg.fxright - mystique->dwgreg.fxleft); + mystique->dwgreg.length_cur--; + if (!mystique->dwgreg.length_cur) { + mystique->busy = 0; + mystique->blitter_complete_refcount++; + break; + } + break; + } + } + break; #ifndef RELEASE_BUILD - default:fatal("ILOAD_SCALE pwidth %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK); + default: + fatal("ILOAD_SCALE pwidth %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK); #endif - } + } } static void blit_iload_iload_high(mystique_t *mystique, uint32_t data, int size) { - svga_t *svga = &mystique->svga; - uint32_t out_data; - int y0, y1, u, v; - int dR, dG, dB; - int r = 0, g = 0, b = 0; - int next_r = 0, next_g = 0, next_b = 0; + svga_t *svga = &mystique->svga; + uint32_t out_data; + int y0, y1, u, v; + int dR, dG, dB; + int r = 0, g = 0, b = 0; + int next_r = 0, next_g = 0, next_b = 0; -// pclog(" iload_high: data=%08x\n", data); + // pclog(" iload_high: data=%08x\n", data); - switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { - case DWGCTRL_BLTMOD_BUYUV:y0 = (298 * ((int)(data & 0xff) - 16)) >> 8; - u = ((data >> 8) & 0xff) - 0x80; - y1 = (298 * ((int)((data >> 16) & 0xff) - 16)) >> 8; - v = ((data >> 24) & 0xff) - 0x80; + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { + case DWGCTRL_BLTMOD_BUYUV: + y0 = (298 * ((int)(data & 0xff) - 16)) >> 8; + u = ((data >> 8) & 0xff) - 0x80; + y1 = (298 * ((int)((data >> 16) & 0xff) - 16)) >> 8; + v = ((data >> 24) & 0xff) - 0x80; - dR = (309 * v) >> 8; - dG = (100 * u + 208 * v) >> 8; - dB = (516 * u) >> 8; + dR = (309 * v) >> 8; + dG = (100 * u + 208 * v) >> 8; + dB = (516 * u) >> 8; - r = y0 + dR; - CLAMP(r); - g = y0 - dG; - CLAMP(g); - b = y0 + dB; - CLAMP(b); + r = y0 + dR; + CLAMP(r); + g = y0 - dG; + CLAMP(g); + b = y0 + dB; + CLAMP(b); - next_r = y1 + dR; - CLAMP(next_r); - next_g = y1 - dG; - CLAMP(next_g); - next_b = y1 + dB; - CLAMP(next_b); + next_r = y1 + dR; + CLAMP(next_r); + next_g = y1 - dG; + CLAMP(next_g); + next_b = y1 + dB; + CLAMP(next_b); - size = 32; - break; + size = 32; + break; #ifndef RELEASE_BUILD - default:fatal("blit_iload_iload_high bltmod %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK); - break; + default: + fatal("blit_iload_iload_high bltmod %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK); + break; #endif - } + } - while (size >= 16) { - if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && - mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { - uint32_t dst; - int f1 = (mystique->dwgreg.ar[6] >> 12) & 0xf; - int f0 = 0x10 - f1; - int out_r = ((mystique->dwgreg.lastpix_r * f0) + (r * f1)) >> 4; - int out_g = ((mystique->dwgreg.lastpix_g * f0) + (g * f1)) >> 4; - int out_b = ((mystique->dwgreg.lastpix_b * f0) + (b * f1)) >> 4; + while (size >= 16) { + if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { + uint32_t dst; + int f1 = (mystique->dwgreg.ar[6] >> 12) & 0xf; + int f0 = 0x10 - f1; + int out_r = ((mystique->dwgreg.lastpix_r * f0) + (r * f1)) >> 4; + int out_g = ((mystique->dwgreg.lastpix_g * f0) + (g * f1)) >> 4; + int out_b = ((mystique->dwgreg.lastpix_b * f0) + (b * f1)) >> 4; -// pclog(" Write %i %i %08x %i %i %i %i %i\n", mystique->dwgreg.xdst, mystique->dwgreg.fxright, mystique->dwgreg.ar[6], mystique->dwgreg.lastpix_r, r, f0, f1, out_r); + // pclog(" Write %i %i %08x %i %i %i %i %i\n", mystique->dwgreg.xdst, + // mystique->dwgreg.fxright, mystique->dwgreg.ar[6], mystique->dwgreg.lastpix_r, r, + // f0, f1, out_r); - switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { - case MACCESS_PWIDTH_16:out_data = (out_b >> 3) | ((out_g >> 2) << 5) | ((out_r >> 3) << 11); - dst = ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w]; - dst = bitop(out_data, dst, mystique->dwgreg.dwgctrl_running); - ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w) >> 11] = changeframecount; - break; - case MACCESS_PWIDTH_32:out_data = out_b | (out_g << 8) | (out_r << 16); - dst = ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l]; - dst = bitop(out_data, dst, mystique->dwgreg.dwgctrl_running); - ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l) >> 10] = changeframecount; - break; + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_16: + out_data = (out_b >> 3) | ((out_g >> 2) << 5) | ((out_r >> 3) << 11); + dst = ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & + mystique->vram_mask_w]; + dst = bitop(out_data, dst, mystique->dwgreg.dwgctrl_running); + ((uint16_t *)svga + ->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w] = + dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w) >> + 11] = changeframecount; + break; + case MACCESS_PWIDTH_32: + out_data = out_b | (out_g << 8) | (out_r << 16); + dst = ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & + mystique->vram_mask_l]; + dst = bitop(out_data, dst, mystique->dwgreg.dwgctrl_running); + ((uint32_t *)svga + ->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l] = + dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l) >> + 10] = changeframecount; + break; #ifndef RELEASE_BUILD - default:fatal("ILOAD_SCALE_HIGH RSTR/RPL BUYUV pwidth %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK); + default: + fatal("ILOAD_SCALE_HIGH RSTR/RPL BUYUV pwidth %08x\n", + mystique->maccess_running & MACCESS_PWIDTH_MASK); #endif - } - } + } + } - mystique->dwgreg.ar[6] += mystique->dwgreg.ar[2]; - if ((int32_t)mystique->dwgreg.ar[6] >= 0) { - mystique->dwgreg.ar[6] -= 65536; - size -= 16; + mystique->dwgreg.ar[6] += mystique->dwgreg.ar[2]; + if ((int32_t)mystique->dwgreg.ar[6] >= 0) { + mystique->dwgreg.ar[6] -= 65536; + size -= 16; - mystique->dwgreg.lastpix_r = r; - mystique->dwgreg.lastpix_g = g; - mystique->dwgreg.lastpix_b = b; - r = next_r; - g = next_g; - b = next_b; - } + mystique->dwgreg.lastpix_r = r; + mystique->dwgreg.lastpix_g = g; + mystique->dwgreg.lastpix_b = b; + r = next_r; + g = next_g; + b = next_b; + } - if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { - mystique->dwgreg.xdst = mystique->dwgreg.fxleft; - mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); - mystique->dwgreg.ar[6] = mystique->dwgreg.ar[2] - (mystique->dwgreg.fxright - mystique->dwgreg.fxleft); - mystique->dwgreg.lastpix_r = 0; - mystique->dwgreg.lastpix_g = 0; - mystique->dwgreg.lastpix_b = 0; + if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + mystique->dwgreg.ar[6] = mystique->dwgreg.ar[2] - (mystique->dwgreg.fxright - mystique->dwgreg.fxleft); + mystique->dwgreg.lastpix_r = 0; + mystique->dwgreg.lastpix_g = 0; + mystique->dwgreg.lastpix_b = 0; - mystique->dwgreg.length_cur--; - if (!mystique->dwgreg.length_cur) { - mystique->busy = 0; - mystique->blitter_complete_refcount++; - break; - } - break; - } else - mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; - } + mystique->dwgreg.length_cur--; + if (!mystique->dwgreg.length_cur) { + mystique->busy = 0; + mystique->blitter_complete_refcount++; + break; + } + break; + } else + mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; + } } static void blit_iload_iload_highv(mystique_t *mystique, uint32_t data, int size) { - uint8_t *src0, *src1; + uint8_t *src0, *src1; -// pclog(" iload_highv: data=%08x\n", data); + // pclog(" iload_highv: data=%08x\n", data); - switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { - case DWGCTRL_BLTMOD_BUYUV: - if (!mystique->dwgreg.highv_line) { - mystique->dwgreg.highv_data = data; - mystique->dwgreg.highv_line = 1; - return; - } - mystique->dwgreg.highv_line = 0; + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { + case DWGCTRL_BLTMOD_BUYUV: + if (!mystique->dwgreg.highv_line) { + mystique->dwgreg.highv_data = data; + mystique->dwgreg.highv_line = 1; + return; + } + mystique->dwgreg.highv_line = 0; - src0 = (uint8_t *)&mystique->dwgreg.highv_data; - src1 = (uint8_t *)&data; + src0 = (uint8_t *)&mystique->dwgreg.highv_data; + src1 = (uint8_t *)&data; - src1[0] = ((src0[0] * mystique->dwgreg.beta) + (src1[0] * (16 - mystique->dwgreg.beta))) >> 4; - src1[1] = ((src0[1] * mystique->dwgreg.beta) + (src1[1] * (16 - mystique->dwgreg.beta))) >> 4; - src1[2] = ((src0[2] * mystique->dwgreg.beta) + (src1[2] * (16 - mystique->dwgreg.beta))) >> 4; - src1[3] = ((src0[3] * mystique->dwgreg.beta) + (src1[3] * (16 - mystique->dwgreg.beta))) >> 4; - blit_iload_iload_high(mystique, data, 32); - break; + src1[0] = ((src0[0] * mystique->dwgreg.beta) + (src1[0] * (16 - mystique->dwgreg.beta))) >> 4; + src1[1] = ((src0[1] * mystique->dwgreg.beta) + (src1[1] * (16 - mystique->dwgreg.beta))) >> 4; + src1[2] = ((src0[2] * mystique->dwgreg.beta) + (src1[2] * (16 - mystique->dwgreg.beta))) >> 4; + src1[3] = ((src0[3] * mystique->dwgreg.beta) + (src1[3] * (16 - mystique->dwgreg.beta))) >> 4; + blit_iload_iload_high(mystique, data, 32); + break; #ifndef RELEASE_BUILD - default:fatal("blit_iload_iload_highv bltmod %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK); - break; + default: + fatal("blit_iload_iload_highv bltmod %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK); + break; #endif - } + } } static void blit_iload_write(mystique_t *mystique, uint32_t data, int size) { -// pclog(" ILOAD %08x %08x\n", data, mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK); - switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) { - case DWGCTRL_OPCODE_ILOAD:blit_iload_iload(mystique, data, size); - break; + // pclog(" ILOAD %08x %08x\n", data, mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK); + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) { + case DWGCTRL_OPCODE_ILOAD: + blit_iload_iload(mystique, data, size); + break; - case DWGCTRL_OPCODE_ILOAD_SCALE:blit_iload_iload_scale(mystique, data, size); - break; + case DWGCTRL_OPCODE_ILOAD_SCALE: + blit_iload_iload_scale(mystique, data, size); + break; - case DWGCTRL_OPCODE_ILOAD_HIGH:blit_iload_iload_high(mystique, data, size); - break; + case DWGCTRL_OPCODE_ILOAD_HIGH: + blit_iload_iload_high(mystique, data, size); + break; - case DWGCTRL_OPCODE_ILOAD_HIGHV:blit_iload_iload_highv(mystique, data, size); - break; + case DWGCTRL_OPCODE_ILOAD_HIGHV: + blit_iload_iload_highv(mystique, data, size); + break; #ifndef RELEASE_BUILD - default:fatal("blit_iload_write: bad opcode %08x\n", mystique->dwgreg.dwgctrl_running); + default: + fatal("blit_iload_write: bad opcode %08x\n", mystique->dwgreg.dwgctrl_running); #endif - } + } } -static int z_check(uint16_t z, uint16_t old_z, uint32_t z_mode)//mystique->dwgreg.dwgctrl & DWGCTRL_ZMODE_MASK) +static int z_check(uint16_t z, uint16_t old_z, uint32_t z_mode) // mystique->dwgreg.dwgctrl & DWGCTRL_ZMODE_MASK) { - switch (z_mode) { - case DWGCTRL_ZMODE_ZE:return (z == old_z); - case DWGCTRL_ZMODE_ZNE:return (z != old_z); - case DWGCTRL_ZMODE_ZLT:return (z < old_z); - case DWGCTRL_ZMODE_ZLTE:return (z <= old_z); - case DWGCTRL_ZMODE_ZGT:return (z > old_z); - case DWGCTRL_ZMODE_ZGTE:return (z >= old_z); + switch (z_mode) { + case DWGCTRL_ZMODE_ZE: + return (z == old_z); + case DWGCTRL_ZMODE_ZNE: + return (z != old_z); + case DWGCTRL_ZMODE_ZLT: + return (z < old_z); + case DWGCTRL_ZMODE_ZLTE: + return (z <= old_z); + case DWGCTRL_ZMODE_ZGT: + return (z > old_z); + case DWGCTRL_ZMODE_ZGTE: + return (z >= old_z); - case DWGCTRL_ZMODE_NOZCMP: - default:return 1; - } + case DWGCTRL_ZMODE_NOZCMP: + default: + return 1; + } } static void blit_line(mystique_t *mystique, int closed) { - svga_t *svga = &mystique->svga; - uint32_t src, dst, old_dst; - int x; - int z_write; + svga_t *svga = &mystique->svga; + uint32_t src, dst, old_dst; + int x; + int z_write; - switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { - case DWGCTRL_ATYPE_RSTR: - case DWGCTRL_ATYPE_RPL:x = mystique->dwgreg.xdst; - while (mystique->dwgreg.length > 0) { - if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && - mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { - switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { - case MACCESS_PWIDTH_8:src = mystique->dwgreg.fcol; - dst = svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask]; + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { + case DWGCTRL_ATYPE_RSTR: + case DWGCTRL_ATYPE_RPL: + x = mystique->dwgreg.xdst; + while (mystique->dwgreg.length > 0) { + if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && + mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_8: + src = mystique->dwgreg.fcol; + dst = svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask]; -// pclog(" LINE %i %08x %08x\n", x, mystique->dwgreg.ydst_lin, mystique->dwgreg.ar[1]); - dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); - svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = changeframecount; - break; + // pclog(" LINE %i %08x %08x\n", x, + // mystique->dwgreg.ydst_lin, + // mystique->dwgreg.ar[1]); + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); + svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = + changeframecount; + break; - case MACCESS_PWIDTH_16:src = mystique->dwgreg.fcol; - dst = ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w]; + case MACCESS_PWIDTH_16: + src = mystique->dwgreg.fcol; + dst = ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w]; -// pclog(" LINE %i %08x %08x\n", x, mystique->dwgreg.ydst_lin, mystique->dwgreg.ar[1]); - dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); - ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount; - break; + // pclog(" LINE %i %08x %08x\n", x, + // mystique->dwgreg.ydst_lin, + // mystique->dwgreg.ar[1]); + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); + ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = + changeframecount; + break; - case MACCESS_PWIDTH_24:src = mystique->dwgreg.fcol; - old_dst = *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask]; + case MACCESS_PWIDTH_24: + src = mystique->dwgreg.fcol; + old_dst = *(uint32_t *)&svga + ->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask]; -// pclog(" LINE %i %08x %08x\n", x, mystique->dwgreg.ydst_lin, mystique->dwgreg.ar[1]); - dst = bitop(src, old_dst, mystique->dwgreg.dwgctrl_running); - *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = (dst & 0xffffff) | (old_dst & 0xff000000); - svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = changeframecount; - break; + // pclog(" LINE %i %08x %08x\n", x, + // mystique->dwgreg.ydst_lin, + // mystique->dwgreg.ar[1]); + dst = bitop(src, old_dst, mystique->dwgreg.dwgctrl_running); + *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = + (dst & 0xffffff) | (old_dst & 0xff000000); + svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = + changeframecount; + break; - case MACCESS_PWIDTH_32:src = mystique->dwgreg.fcol; - dst = ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l]; + case MACCESS_PWIDTH_32: + src = mystique->dwgreg.fcol; + dst = ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l]; -// pclog(" LINE %i %08x %08x\n", x, mystique->dwgreg.ydst_lin, mystique->dwgreg.ar[1]); - dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); - ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l) >> 10] = changeframecount; - break; + // pclog(" LINE %i %08x %08x\n", x, + // mystique->dwgreg.ydst_lin, + // mystique->dwgreg.ar[1]); + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); + ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l) >> 10] = + changeframecount; + break; #ifndef RELEASE_BUILD - default:fatal("LINE RSTR/RPL PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); + default: + fatal("LINE RSTR/RPL PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, + mystique->dwgreg.dwgctrl_running); #endif - } - } + } + } - if (mystique->dwgreg.sgn.sdydxl) - x += (mystique->dwgreg.sgn.sdxl ? -1 : 1); - else - mystique->dwgreg.ydst_lin += (mystique->dwgreg.sgn.sdy ? -(mystique->dwgreg.pitch & PITCH_MASK) : (mystique->dwgreg.pitch & PITCH_MASK)); + if (mystique->dwgreg.sgn.sdydxl) + x += (mystique->dwgreg.sgn.sdxl ? -1 : 1); + else + mystique->dwgreg.ydst_lin += (mystique->dwgreg.sgn.sdy ? -(mystique->dwgreg.pitch & PITCH_MASK) + : (mystique->dwgreg.pitch & PITCH_MASK)); - if ((int32_t)mystique->dwgreg.ar[1] >= 0) { - mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2]; + if ((int32_t)mystique->dwgreg.ar[1] >= 0) { + mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2]; - if (mystique->dwgreg.sgn.sdydxl) - mystique->dwgreg.ydst_lin += (mystique->dwgreg.sgn.sdy ? -(mystique->dwgreg.pitch & PITCH_MASK) : (mystique->dwgreg.pitch & PITCH_MASK)); - else - x += (mystique->dwgreg.sgn.sdxl ? -1 : 1); - } else - mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; + if (mystique->dwgreg.sgn.sdydxl) + mystique->dwgreg.ydst_lin += + (mystique->dwgreg.sgn.sdy ? -(mystique->dwgreg.pitch & PITCH_MASK) + : (mystique->dwgreg.pitch & PITCH_MASK)); + else + x += (mystique->dwgreg.sgn.sdxl ? -1 : 1); + } else + mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; - mystique->dwgreg.length--; - } - break; + mystique->dwgreg.length--; + } + break; - case DWGCTRL_ATYPE_I: - case DWGCTRL_ATYPE_ZI:z_write = ((mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) == DWGCTRL_ATYPE_ZI); - x = mystique->dwgreg.xdst; - while (mystique->dwgreg.length > 0) { - if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && - mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { - uint16_t z = ((int32_t)mystique->dwgreg.dr[0] < 0) ? 0 : (mystique->dwgreg.dr[0] >> 15); - uint16_t *z_p = (uint16_t *)&svga->vram[(mystique->dwgreg.ydst_lin * 2 + mystique->dwgreg.zorg) & mystique->vram_mask]; - uint16_t old_z = z_p[x]; + case DWGCTRL_ATYPE_I: + case DWGCTRL_ATYPE_ZI: + z_write = ((mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) == DWGCTRL_ATYPE_ZI); + x = mystique->dwgreg.xdst; + while (mystique->dwgreg.length > 0) { + if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && + mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { + uint16_t z = ((int32_t)mystique->dwgreg.dr[0] < 0) ? 0 : (mystique->dwgreg.dr[0] >> 15); + uint16_t *z_p = (uint16_t *)&svga->vram[(mystique->dwgreg.ydst_lin * 2 + mystique->dwgreg.zorg) & + mystique->vram_mask]; + uint16_t old_z = z_p[x]; - if (z_check(z, old_z, mystique->dwgreg.dwgctrl_running & DWGCTRL_ZMODE_MASK)) { - int r = 0, g = 0, b = 0; + if (z_check(z, old_z, mystique->dwgreg.dwgctrl_running & DWGCTRL_ZMODE_MASK)) { + int r = 0, g = 0, b = 0; - if (z_write) - z_p[x] = z; + if (z_write) + z_p[x] = z; - switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { - case MACCESS_PWIDTH_16: - if (!(mystique->dwgreg.dr[4] & (1 << 23))) - r = (mystique->dwgreg.dr[4] >> 18) & 0x1f; - if (!(mystique->dwgreg.dr[8] & (1 << 23))) - g = (mystique->dwgreg.dr[8] >> 17) & 0x3f; - if (!(mystique->dwgreg.dr[12] & (1 << 23))) - b = (mystique->dwgreg.dr[12] >> 18) & 0x1f; - dst = (r << 11) | (g << 5) | b; + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_16: + if (!(mystique->dwgreg.dr[4] & (1 << 23))) + r = (mystique->dwgreg.dr[4] >> 18) & 0x1f; + if (!(mystique->dwgreg.dr[8] & (1 << 23))) + g = (mystique->dwgreg.dr[8] >> 17) & 0x3f; + if (!(mystique->dwgreg.dr[12] & (1 << 23))) + b = (mystique->dwgreg.dr[12] >> 18) & 0x1f; + dst = (r << 11) | (g << 5) | b; - ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount; - break; + ((uint16_t *) + svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = + dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> + 11] = changeframecount; + break; #ifndef RELEASE_BUILD - default:fatal("LINE I/ZI PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); + default: + fatal("LINE I/ZI PWIDTH %x %08x\n", + mystique->maccess_running & MACCESS_PWIDTH_MASK, + mystique->dwgreg.dwgctrl_running); #endif - } - } - } + } + } + } - if (mystique->dwgreg.sgn.sdydxl) - x += (mystique->dwgreg.sgn.sdxl ? -1 : 1); - else - mystique->dwgreg.ydst_lin += (mystique->dwgreg.sgn.sdy ? -(mystique->dwgreg.pitch & PITCH_MASK) : (mystique->dwgreg.pitch & PITCH_MASK)); + if (mystique->dwgreg.sgn.sdydxl) + x += (mystique->dwgreg.sgn.sdxl ? -1 : 1); + else + mystique->dwgreg.ydst_lin += (mystique->dwgreg.sgn.sdy ? -(mystique->dwgreg.pitch & PITCH_MASK) + : (mystique->dwgreg.pitch & PITCH_MASK)); - mystique->dwgreg.dr[0] += mystique->dwgreg.dr[2]; - mystique->dwgreg.dr[4] += mystique->dwgreg.dr[6]; - mystique->dwgreg.dr[8] += mystique->dwgreg.dr[10]; - mystique->dwgreg.dr[12] += mystique->dwgreg.dr[14]; + mystique->dwgreg.dr[0] += mystique->dwgreg.dr[2]; + mystique->dwgreg.dr[4] += mystique->dwgreg.dr[6]; + mystique->dwgreg.dr[8] += mystique->dwgreg.dr[10]; + mystique->dwgreg.dr[12] += mystique->dwgreg.dr[14]; - if ((int32_t)mystique->dwgreg.ar[1] >= 0) { - mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2]; + if ((int32_t)mystique->dwgreg.ar[1] >= 0) { + mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2]; - if (mystique->dwgreg.sgn.sdydxl) - mystique->dwgreg.ydst_lin += (mystique->dwgreg.sgn.sdy ? -(mystique->dwgreg.pitch & PITCH_MASK) : (mystique->dwgreg.pitch & PITCH_MASK)); - else - x += (mystique->dwgreg.sgn.sdxl ? -1 : 1); + if (mystique->dwgreg.sgn.sdydxl) + mystique->dwgreg.ydst_lin += + (mystique->dwgreg.sgn.sdy ? -(mystique->dwgreg.pitch & PITCH_MASK) + : (mystique->dwgreg.pitch & PITCH_MASK)); + else + x += (mystique->dwgreg.sgn.sdxl ? -1 : 1); - mystique->dwgreg.dr[0] += mystique->dwgreg.dr[3]; - mystique->dwgreg.dr[4] += mystique->dwgreg.dr[7]; - mystique->dwgreg.dr[8] += mystique->dwgreg.dr[11]; - mystique->dwgreg.dr[12] += mystique->dwgreg.dr[15]; - } else - mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; + mystique->dwgreg.dr[0] += mystique->dwgreg.dr[3]; + mystique->dwgreg.dr[4] += mystique->dwgreg.dr[7]; + mystique->dwgreg.dr[8] += mystique->dwgreg.dr[11]; + mystique->dwgreg.dr[12] += mystique->dwgreg.dr[15]; + } else + mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; - mystique->dwgreg.length--; - } - break; + mystique->dwgreg.length--; + } + break; #ifndef RELEASE_BUILD - default:fatal("Unknown atype %03x %08x LINE\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); + default: + fatal("Unknown atype %03x %08x LINE\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, + mystique->dwgreg.dwgctrl_running); #endif - } - mystique->blitter_complete_refcount++; + } + mystique->blitter_complete_refcount++; } static void blit_autoline(mystique_t *mystique, int closed) { - int start_x = (int32_t)mystique->dwgreg.ar[5]; - int start_y = (int32_t)mystique->dwgreg.ar[6]; - int end_x = (int32_t)mystique->dwgreg.ar[0]; - int end_y = (int32_t)mystique->dwgreg.ar[2]; - int dx = end_x - start_x; - int dy = end_y - start_y; + int start_x = (int32_t)mystique->dwgreg.ar[5]; + int start_y = (int32_t)mystique->dwgreg.ar[6]; + int end_x = (int32_t)mystique->dwgreg.ar[0]; + int end_y = (int32_t)mystique->dwgreg.ar[2]; + int dx = end_x - start_x; + int dy = end_y - start_y; - if (ABS(dx) > ABS(dy)) { - mystique->dwgreg.sgn.sdydxl = 1; - mystique->dwgreg.ar[0] = 2 * ABS(dy); - mystique->dwgreg.ar[1] = 2 * ABS(dy) - ABS(dx) - ((start_y > end_y) ? 1 : 0); - mystique->dwgreg.ar[2] = 2 * ABS(dy) - 2 * ABS(dx); - mystique->dwgreg.length = ABS(end_x - start_x); - } else { - mystique->dwgreg.sgn.sdydxl = 0; - mystique->dwgreg.ar[0] = 2 * ABS(dx); - mystique->dwgreg.ar[1] = 2 * ABS(dx) - ABS(dy) - ((start_y > end_y) ? 1 : 0); - mystique->dwgreg.ar[2] = 2 * ABS(dx) - 2 * ABS(dy); - mystique->dwgreg.length = ABS(end_y - start_y); - } - mystique->dwgreg.sgn.sdxl = (start_x > end_x) ? 1 : 0; - mystique->dwgreg.sgn.sdy = (start_y > end_y) ? 1 : 0; + if (ABS(dx) > ABS(dy)) { + mystique->dwgreg.sgn.sdydxl = 1; + mystique->dwgreg.ar[0] = 2 * ABS(dy); + mystique->dwgreg.ar[1] = 2 * ABS(dy) - ABS(dx) - ((start_y > end_y) ? 1 : 0); + mystique->dwgreg.ar[2] = 2 * ABS(dy) - 2 * ABS(dx); + mystique->dwgreg.length = ABS(end_x - start_x); + } else { + mystique->dwgreg.sgn.sdydxl = 0; + mystique->dwgreg.ar[0] = 2 * ABS(dx); + mystique->dwgreg.ar[1] = 2 * ABS(dx) - ABS(dy) - ((start_y > end_y) ? 1 : 0); + mystique->dwgreg.ar[2] = 2 * ABS(dx) - 2 * ABS(dy); + mystique->dwgreg.length = ABS(end_y - start_y); + } + mystique->dwgreg.sgn.sdxl = (start_x > end_x) ? 1 : 0; + mystique->dwgreg.sgn.sdy = (start_y > end_y) ? 1 : 0; + /* pclog("Autoline %s\n", closed ? "closed" : "open"); + pclog("Start %i,%i\n", start_x, start_y); + pclog("End %i,%i\n", end_x, end_y); + pclog("SGN=%x\n", mystique->dwgreg.sgn); + pclog("AR0=%08x AR1=%08x AR2=%08x\n", mystique->dwgreg.ar[0], + mystique->dwgreg.ar[1], + mystique->dwgreg.ar[2]); + pclog("Length %i\n", mystique->dwgreg.length);*/ + blit_line(mystique, closed); -/* pclog("Autoline %s\n", closed ? "closed" : "open"); - pclog("Start %i,%i\n", start_x, start_y); - pclog("End %i,%i\n", end_x, end_y); - pclog("SGN=%x\n", mystique->dwgreg.sgn); - pclog("AR0=%08x AR1=%08x AR2=%08x\n", mystique->dwgreg.ar[0], - mystique->dwgreg.ar[1], - mystique->dwgreg.ar[2]); - pclog("Length %i\n", mystique->dwgreg.length);*/ - blit_line(mystique, closed); - - mystique->dwgreg.ar[5] = end_x; - mystique->dwgreg.xdst = end_x; - mystique->dwgreg.ar[6] = end_y; - mystique->dwgreg.ydst = end_y; - mystique->dwgreg.ydst_lin = ((int32_t)(int16_t)mystique->dwgreg.ydst * (mystique->dwgreg.pitch & PITCH_MASK)) + mystique->dwgreg.ydstorg; + mystique->dwgreg.ar[5] = end_x; + mystique->dwgreg.xdst = end_x; + mystique->dwgreg.ar[6] = end_y; + mystique->dwgreg.ydst = end_y; + mystique->dwgreg.ydst_lin = + ((int32_t)(int16_t)mystique->dwgreg.ydst * (mystique->dwgreg.pitch & PITCH_MASK)) + mystique->dwgreg.ydstorg; } static void blit_trap(mystique_t *mystique) { - svga_t *svga = &mystique->svga; - uint32_t z_back, r_back, g_back, b_back; - int z_write; - int y; - const int trans_sel = (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANS_MASK) >> DWGCTRL_TRANS_SHIFT; + svga_t *svga = &mystique->svga; + uint32_t z_back, r_back, g_back, b_back; + int z_write; + int y; + const int trans_sel = (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANS_MASK) >> DWGCTRL_TRANS_SHIFT; - mystique->trap_count++; + mystique->trap_count++; - switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { - case DWGCTRL_ATYPE_BLK: - case DWGCTRL_ATYPE_RPL: - //fxleft, fxright - //fcol -/* pclog("fxleft=%i fxright=%i\n", mystique->dwgreg.fxleft, mystique->dwgreg.fxright); - pclog("fcol=%08x\n", mystique->dwgreg.fcol); - pclog("ytop=%i length=%i\n", mystique->dwgreg.ytop, mystique->dwgreg.length); - pclog("pitch=%08x\n", mystique->dwgreg.pitch); - pclog("ydst_lin=%08x\n", mystique->dwgreg.ydst_lin);*/ -// if (!(mystique->dwgreg.dwgctrl_running & DWGCTRL_SGNZERO)) -// fatal("Not rectangle\n"); + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { + case DWGCTRL_ATYPE_BLK: + case DWGCTRL_ATYPE_RPL: + // fxleft, fxright + // fcol + /* pclog("fxleft=%i fxright=%i\n", mystique->dwgreg.fxleft, mystique->dwgreg.fxright); + pclog("fcol=%08x\n", mystique->dwgreg.fcol); + pclog("ytop=%i length=%i\n", mystique->dwgreg.ytop, mystique->dwgreg.length); + pclog("pitch=%08x\n", mystique->dwgreg.pitch); + pclog("ydst_lin=%08x\n", mystique->dwgreg.ydst_lin);*/ + // if (!(mystique->dwgreg.dwgctrl_running & DWGCTRL_SGNZERO)) + // fatal("Not rectangle\n"); - for (y = 0; y < mystique->dwgreg.length; y++) { - uint8_t const *const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; - int16_t x_l = mystique->dwgreg.fxleft & 0xffff; - int16_t x_r = mystique->dwgreg.fxright & 0xffff; - int yoff = (mystique->dwgreg.yoff + mystique->dwgreg.ydst) & 7; + for (y = 0; y < mystique->dwgreg.length; y++) { + uint8_t const *const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; + int16_t x_l = mystique->dwgreg.fxleft & 0xffff; + int16_t x_r = mystique->dwgreg.fxright & 0xffff; + int yoff = (mystique->dwgreg.yoff + mystique->dwgreg.ydst) & 7; -// pclog(" line %03i: %08x\n", y, mystique->dwgreg.ydst_lin); - while (x_l != x_r) { - if (x_l >= mystique->dwgreg.cxleft && x_l <= mystique->dwgreg.cxright && - mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && - trans[x_l & 3]) { - int xoff = (mystique->dwgreg.xoff + x_l) & 7; - int pattern = mystique->dwgreg.pattern[yoff][xoff]; - uint32_t dst; + // pclog(" line %03i: %08x\n", y, mystique->dwgreg.ydst_lin); + while (x_l != x_r) { + if (x_l >= mystique->dwgreg.cxleft && x_l <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && + mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && trans[x_l & 3]) { + int xoff = (mystique->dwgreg.xoff + x_l) & 7; + int pattern = mystique->dwgreg.pattern[yoff][xoff]; + uint32_t dst; -// pclog(" %06x %02x\n", mystique->dwgreg.ydst_lin + x, mystique->dwgreg.fcol & 0xff); - switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { - case MACCESS_PWIDTH_8: - svga->vram[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask] = - (pattern ? mystique->dwgreg.fcol : mystique->dwgreg.bcol) & 0xff; - svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask) >> 12] = changeframecount; - break; + // pclog(" %06x %02x\n", + // mystique->dwgreg.ydst_lin + x, + // mystique->dwgreg.fcol & 0xff); + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_8: + svga->vram[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask] = + (pattern ? mystique->dwgreg.fcol : mystique->dwgreg.bcol) & 0xff; + svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask) >> + 12] = changeframecount; + break; - case MACCESS_PWIDTH_16: - ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w] = - (pattern ? mystique->dwgreg.fcol : mystique->dwgreg.bcol) & 0xffff; - svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w) >> 11] = changeframecount; - break; + case MACCESS_PWIDTH_16: + ((uint16_t *) + svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w] = + (pattern ? mystique->dwgreg.fcol : mystique->dwgreg.bcol) & 0xffff; + svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w) >> + 11] = changeframecount; + break; - case MACCESS_PWIDTH_24:dst = *(uint32_t *)(&svga->vram[((mystique->dwgreg.ydst_lin + x_l) * 3) & mystique->vram_mask]) & 0xff000000; - *(uint32_t *)(&svga->vram[((mystique->dwgreg.ydst_lin + x_l) * 3) & mystique->vram_mask]) = - ((pattern ? mystique->dwgreg.fcol : mystique->dwgreg.bcol) & 0xffffff) | dst; - svga->changedvram[(((mystique->dwgreg.ydst_lin + x_l) * 3) & mystique->vram_mask) >> 12] = changeframecount; - break; + case MACCESS_PWIDTH_24: + dst = *(uint32_t *)(&svga->vram[((mystique->dwgreg.ydst_lin + x_l) * 3) & + mystique->vram_mask]) & + 0xff000000; + *(uint32_t *)(&svga->vram[((mystique->dwgreg.ydst_lin + x_l) * 3) & + mystique->vram_mask]) = + ((pattern ? mystique->dwgreg.fcol : mystique->dwgreg.bcol) & 0xffffff) | + dst; + svga->changedvram[(((mystique->dwgreg.ydst_lin + x_l) * 3) & + mystique->vram_mask) >> + 12] = changeframecount; + break; - case MACCESS_PWIDTH_32: - ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l] = - pattern ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; - svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l) >> 10] = changeframecount; - break; + case MACCESS_PWIDTH_32: + ((uint32_t *) + svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l] = + pattern ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; + svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l) >> + 10] = changeframecount; + break; #ifndef RELEASE_BUILD - default:fatal("TRAP BLK/RPL PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); + default: + fatal("TRAP BLK/RPL PWIDTH %x %08x\n", + mystique->maccess_running & MACCESS_PWIDTH_MASK, + mystique->dwgreg.dwgctrl_running); #endif - } - } - x_l++; - mystique->pixel_count++; - } + } + } + x_l++; + mystique->pixel_count++; + } - if ((int32_t)mystique->dwgreg.ar[1] < 0) { - while ((int32_t)mystique->dwgreg.ar[1] < 0 && mystique->dwgreg.ar[0]) { - mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; - mystique->dwgreg.fxleft += (mystique->dwgreg.sgn.sdxl ? -1 : 1); - } - } else - mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2]; + if ((int32_t)mystique->dwgreg.ar[1] < 0) { + while ((int32_t)mystique->dwgreg.ar[1] < 0 && mystique->dwgreg.ar[0]) { + mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; + mystique->dwgreg.fxleft += (mystique->dwgreg.sgn.sdxl ? -1 : 1); + } + } else + mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2]; - if ((int32_t)mystique->dwgreg.ar[4] < 0) { - while ((int32_t)mystique->dwgreg.ar[4] < 0 && mystique->dwgreg.ar[6]) { - mystique->dwgreg.ar[4] += mystique->dwgreg.ar[6]; - mystique->dwgreg.fxright += (mystique->dwgreg.sgn.sdxr ? -1 : 1); - } - } else - mystique->dwgreg.ar[4] += mystique->dwgreg.ar[5]; + if ((int32_t)mystique->dwgreg.ar[4] < 0) { + while ((int32_t)mystique->dwgreg.ar[4] < 0 && mystique->dwgreg.ar[6]) { + mystique->dwgreg.ar[4] += mystique->dwgreg.ar[6]; + mystique->dwgreg.fxright += (mystique->dwgreg.sgn.sdxr ? -1 : 1); + } + } else + mystique->dwgreg.ar[4] += mystique->dwgreg.ar[5]; - mystique->dwgreg.ydst++; - mystique->dwgreg.ydst &= 0x7fffff; - mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + mystique->dwgreg.ydst++; + mystique->dwgreg.ydst &= 0x7fffff; + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); - mystique->dwgreg.selline = (mystique->dwgreg.selline + 1) & 7; - } - break; + mystique->dwgreg.selline = (mystique->dwgreg.selline + 1) & 7; + } + break; - case DWGCTRL_ATYPE_RSTR: - for (y = 0; y < mystique->dwgreg.length; y++) { - uint8_t const *const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; - int16_t x_l = mystique->dwgreg.fxleft & 0xffff; - int16_t x_r = mystique->dwgreg.fxright & 0xffff; - int yoff = (mystique->dwgreg.yoff + mystique->dwgreg.ydst) & 7; + case DWGCTRL_ATYPE_RSTR: + for (y = 0; y < mystique->dwgreg.length; y++) { + uint8_t const *const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; + int16_t x_l = mystique->dwgreg.fxleft & 0xffff; + int16_t x_r = mystique->dwgreg.fxright & 0xffff; + int yoff = (mystique->dwgreg.yoff + mystique->dwgreg.ydst) & 7; -// pclog(" line %03i: %08x\n", y, mystique->dwgreg.ydst_lin); - while (x_l != x_r) { - if (x_l >= mystique->dwgreg.cxleft && x_l <= mystique->dwgreg.cxright && - mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && - trans[x_l & 3]) { - int xoff = (mystique->dwgreg.xoff + x_l) & 7; - int pattern = mystique->dwgreg.pattern[yoff][xoff]; - uint32_t src = pattern ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; - uint32_t dst, old_dst; + // pclog(" line %03i: %08x\n", y, mystique->dwgreg.ydst_lin); + while (x_l != x_r) { + if (x_l >= mystique->dwgreg.cxleft && x_l <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && + mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && trans[x_l & 3]) { + int xoff = (mystique->dwgreg.xoff + x_l) & 7; + int pattern = mystique->dwgreg.pattern[yoff][xoff]; + uint32_t src = pattern ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; + uint32_t dst, old_dst; - switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { - case MACCESS_PWIDTH_8:dst = svga->vram[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask]; + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_8: + dst = svga->vram[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask]; - dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); -// pclog(" %06x %02x\n", mystique->dwgreg.ydst_lin + x, mystique->dwgreg.fcol & 0xff); - svga->vram[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask) >> 12] = changeframecount; - break; + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); + // pclog(" %06x %02x\n", + // mystique->dwgreg.ydst_lin + x, + // mystique->dwgreg.fcol & 0xff); + svga->vram[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask) >> + 12] = changeframecount; + break; - case MACCESS_PWIDTH_16:dst = ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w]; + case MACCESS_PWIDTH_16: + dst = ((uint16_t *)svga + ->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w]; - dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); -// pclog(" %06x %02x\n", mystique->dwgreg.ydst_lin + x, mystique->dwgreg.fcol & 0xff); - ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w) >> 11] = changeframecount; - break; + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); + // pclog(" %06x %02x\n", + // mystique->dwgreg.ydst_lin + x, + // mystique->dwgreg.fcol & 0xff); + ((uint16_t *) + svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w] = + dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w) >> + 11] = changeframecount; + break; - case MACCESS_PWIDTH_24:old_dst = *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x_l) * 3) & mystique->vram_mask]; + case MACCESS_PWIDTH_24: + old_dst = *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x_l) * 3) & + mystique->vram_mask]; - dst = bitop(src, old_dst, mystique->dwgreg.dwgctrl_running); -// pclog(" %06x %02x\n", mystique->dwgreg.ydst_lin + x, mystique->dwgreg.fcol & 0xff); - *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x_l) * 3) & mystique->vram_mask] = (dst & 0xffffff) | (old_dst & 0xff000000); - svga->changedvram[(((mystique->dwgreg.ydst_lin + x_l) * 3) & mystique->vram_mask) >> 12] = changeframecount; - break; + dst = bitop(src, old_dst, mystique->dwgreg.dwgctrl_running); + // pclog(" %06x %02x\n", + // mystique->dwgreg.ydst_lin + x, + // mystique->dwgreg.fcol & 0xff); + *(uint32_t *)&svga + ->vram[((mystique->dwgreg.ydst_lin + x_l) * 3) & mystique->vram_mask] = + (dst & 0xffffff) | (old_dst & 0xff000000); + svga->changedvram[(((mystique->dwgreg.ydst_lin + x_l) * 3) & + mystique->vram_mask) >> + 12] = changeframecount; + break; - case MACCESS_PWIDTH_32:dst = ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l]; + case MACCESS_PWIDTH_32: + dst = ((uint32_t *)svga + ->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l]; - dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); -// pclog(" %06x %02x\n", mystique->dwgreg.ydst_lin + x, mystique->dwgreg.fcol & 0xff); - ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l) >> 10] = changeframecount; - break; + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); + // pclog(" %06x %02x\n", + // mystique->dwgreg.ydst_lin + x, + // mystique->dwgreg.fcol & 0xff); + ((uint32_t *) + svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l] = + dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l) >> + 10] = changeframecount; + break; #ifndef RELEASE_BUILD - default:fatal("TRAP RSTR PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); + default: + fatal("TRAP RSTR PWIDTH %x %08x\n", + mystique->maccess_running & MACCESS_PWIDTH_MASK, + mystique->dwgreg.dwgctrl_running); #endif - } - } - x_l++; - mystique->pixel_count++; - } + } + } + x_l++; + mystique->pixel_count++; + } - if ((int32_t)mystique->dwgreg.ar[1] < 0) { - while ((int32_t)mystique->dwgreg.ar[1] < 0 && mystique->dwgreg.ar[0]) { - mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; - mystique->dwgreg.fxleft += (mystique->dwgreg.sgn.sdxl ? -1 : 1); - } - } else - mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2]; + if ((int32_t)mystique->dwgreg.ar[1] < 0) { + while ((int32_t)mystique->dwgreg.ar[1] < 0 && mystique->dwgreg.ar[0]) { + mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; + mystique->dwgreg.fxleft += (mystique->dwgreg.sgn.sdxl ? -1 : 1); + } + } else + mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2]; - if ((int32_t)mystique->dwgreg.ar[4] < 0) { - while ((int32_t)mystique->dwgreg.ar[4] < 0 && mystique->dwgreg.ar[6]) { - mystique->dwgreg.ar[4] += mystique->dwgreg.ar[6]; - mystique->dwgreg.fxright += (mystique->dwgreg.sgn.sdxr ? -1 : 1); - } - } else - mystique->dwgreg.ar[4] += mystique->dwgreg.ar[5]; + if ((int32_t)mystique->dwgreg.ar[4] < 0) { + while ((int32_t)mystique->dwgreg.ar[4] < 0 && mystique->dwgreg.ar[6]) { + mystique->dwgreg.ar[4] += mystique->dwgreg.ar[6]; + mystique->dwgreg.fxright += (mystique->dwgreg.sgn.sdxr ? -1 : 1); + } + } else + mystique->dwgreg.ar[4] += mystique->dwgreg.ar[5]; - mystique->dwgreg.ydst++; - mystique->dwgreg.ydst &= 0x7fffff; - mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + mystique->dwgreg.ydst++; + mystique->dwgreg.ydst &= 0x7fffff; + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); - mystique->dwgreg.selline = (mystique->dwgreg.selline + 1) & 7; - } - break; + mystique->dwgreg.selline = (mystique->dwgreg.selline + 1) & 7; + } + break; - case DWGCTRL_ATYPE_I: - case DWGCTRL_ATYPE_ZI:z_write = ((mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) == DWGCTRL_ATYPE_ZI); -/* pclog("fxleft=%i fxright=%i\n", mystique->dwgreg.fxleft, mystique->dwgreg.fxright); - pclog("fcol=%08x\n", mystique->dwgreg.fcol); - pclog("ytop=%i length=%i\n", mystique->dwgreg.ytop, mystique->dwgreg.length); - pclog("pitch=%08x\n", mystique->dwgreg.pitch); - pclog("ydst_lin=%08x\n", mystique->dwgreg.ydst_lin); - pclog("trap! maccess=%08x %08x %08x %08x\n", mystique->maccess_running, mystique->dwgreg.dr[4], mystique->dwgreg.dr[8], mystique->dwgreg.dr[12]);*/ + case DWGCTRL_ATYPE_I: + case DWGCTRL_ATYPE_ZI: + z_write = ((mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) == DWGCTRL_ATYPE_ZI); + /* pclog("fxleft=%i fxright=%i\n", mystique->dwgreg.fxleft, mystique->dwgreg.fxright); + pclog("fcol=%08x\n", mystique->dwgreg.fcol); + pclog("ytop=%i length=%i\n", mystique->dwgreg.ytop, mystique->dwgreg.length); + pclog("pitch=%08x\n", mystique->dwgreg.pitch); + pclog("ydst_lin=%08x\n", mystique->dwgreg.ydst_lin); + pclog("trap! maccess=%08x %08x %08x %08x\n", mystique->maccess_running, mystique->dwgreg.dr[4], + mystique->dwgreg.dr[8], mystique->dwgreg.dr[12]);*/ - for (y = 0; y < mystique->dwgreg.length; y++) { - uint8_t const *const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; - uint16_t *z_p = (uint16_t *)&svga->vram[(mystique->dwgreg.ydst_lin * 2 + mystique->dwgreg.zorg) & mystique->vram_mask]; - int16_t x_l = mystique->dwgreg.fxleft & 0xffff; - int16_t x_r = mystique->dwgreg.fxright & 0xffff; - int16_t old_x_l = x_l; - int dx; + for (y = 0; y < mystique->dwgreg.length; y++) { + uint8_t const *const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; + uint16_t *z_p = + (uint16_t *)&svga + ->vram[(mystique->dwgreg.ydst_lin * 2 + mystique->dwgreg.zorg) & mystique->vram_mask]; + int16_t x_l = mystique->dwgreg.fxleft & 0xffff; + int16_t x_r = mystique->dwgreg.fxright & 0xffff; + int16_t old_x_l = x_l; + int dx; - z_back = mystique->dwgreg.dr[0]; - r_back = mystique->dwgreg.dr[4]; - g_back = mystique->dwgreg.dr[8]; - b_back = mystique->dwgreg.dr[12]; + z_back = mystique->dwgreg.dr[0]; + r_back = mystique->dwgreg.dr[4]; + g_back = mystique->dwgreg.dr[8]; + b_back = mystique->dwgreg.dr[12]; -// pclog(" line %03i: %08x\n", y, mystique->dwgreg.ydst_lin); - while (x_l != x_r) { - if (x_l >= mystique->dwgreg.cxleft && x_l <= mystique->dwgreg.cxright && - mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && - trans[x_l & 3]) { - uint16_t z = ((int32_t)mystique->dwgreg.dr[0] < 0) ? 0 : (mystique->dwgreg.dr[0] >> 15); - uint16_t old_z = z_p[x_l]; + // pclog(" line %03i: %08x\n", y, mystique->dwgreg.ydst_lin); + while (x_l != x_r) { + if (x_l >= mystique->dwgreg.cxleft && x_l <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && + mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && trans[x_l & 3]) { + uint16_t z = ((int32_t)mystique->dwgreg.dr[0] < 0) ? 0 : (mystique->dwgreg.dr[0] >> 15); + uint16_t old_z = z_p[x_l]; - if (z_check(z, old_z, mystique->dwgreg.dwgctrl_running & DWGCTRL_ZMODE_MASK)) { - uint32_t dst = 0, old_dst; - int r = 0, g = 0, b = 0; + if (z_check(z, old_z, mystique->dwgreg.dwgctrl_running & DWGCTRL_ZMODE_MASK)) { + uint32_t dst = 0, old_dst; + int r = 0, g = 0, b = 0; - if (!(mystique->dwgreg.dr[4] & (1 << 23))) - r = (mystique->dwgreg.dr[4] >> 15) & 0xff; - if (!(mystique->dwgreg.dr[8] & (1 << 23))) - g = (mystique->dwgreg.dr[8] >> 15) & 0xff; - if (!(mystique->dwgreg.dr[12] & (1 << 23))) - b = (mystique->dwgreg.dr[12] >> 15) & 0xff; + if (!(mystique->dwgreg.dr[4] & (1 << 23))) + r = (mystique->dwgreg.dr[4] >> 15) & 0xff; + if (!(mystique->dwgreg.dr[8] & (1 << 23))) + g = (mystique->dwgreg.dr[8] >> 15) & 0xff; + if (!(mystique->dwgreg.dr[12] & (1 << 23))) + b = (mystique->dwgreg.dr[12] >> 15) & 0xff; - if (z_write) - z_p[x_l] = z; + if (z_write) + z_p[x_l] = z; -// pclog(" %06x %02x\n", mystique->dwgreg.ydst_lin + x, mystique->dwgreg.fcol & 0xff); - switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { - case MACCESS_PWIDTH_8:svga->vram[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask) >> 12] = changeframecount; - break; + // pclog(" %06x %02x\n", + // mystique->dwgreg.ydst_lin + x, + // mystique->dwgreg.fcol & 0xff); + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_8: + svga->vram[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & + mystique->vram_mask) >> + 12] = changeframecount; + break; - case MACCESS_PWIDTH_16:dst = dither(mystique, r, g, b, x_l & 1, mystique->dwgreg.selline & 1); -// pclog(" %08x %08x %08x %04x\n", mystique->dwgreg.dr[4], mystique->dwgreg.dr[8], mystique->dwgreg.dr[12], dst); - ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w) >> 11] = changeframecount; - break; + case MACCESS_PWIDTH_16: + dst = dither(mystique, r, g, b, x_l & 1, mystique->dwgreg.selline & 1); + // pclog(" %08x + // %08x %08x + // %04x\n", + // mystique->dwgreg.dr[4], + // mystique->dwgreg.dr[8], + // mystique->dwgreg.dr[12], + // dst); + ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & + mystique->vram_mask_w] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & + mystique->vram_mask_w) >> + 11] = changeframecount; + break; - case MACCESS_PWIDTH_24:old_dst = *(uint32_t *)(&svga->vram[((mystique->dwgreg.ydst_lin + x_l) * 3) & mystique->vram_mask]) & 0xff000000; - *(uint32_t *)(&svga->vram[((mystique->dwgreg.ydst_lin + x_l) * 3) & mystique->vram_mask]) = old_dst | dst; - svga->changedvram[(((mystique->dwgreg.ydst_lin + x_l) * 3) & mystique->vram_mask) >> 12] = changeframecount; - break; + case MACCESS_PWIDTH_24: + old_dst = + *(uint32_t + *)(&svga->vram[((mystique->dwgreg.ydst_lin + x_l) * 3) & + mystique->vram_mask]) & + 0xff000000; + *(uint32_t *)(&svga->vram[((mystique->dwgreg.ydst_lin + x_l) * 3) & + mystique->vram_mask]) = old_dst | dst; + svga->changedvram[(((mystique->dwgreg.ydst_lin + x_l) * 3) & + mystique->vram_mask) >> + 12] = changeframecount; + break; - case MACCESS_PWIDTH_32:((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l] = b | (g << 8) | (r << 16); - svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l) >> 10] = changeframecount; - break; + case MACCESS_PWIDTH_32: + ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & + mystique->vram_mask_l] = + b | (g << 8) | (r << 16); + svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & + mystique->vram_mask_l) >> + 10] = changeframecount; + break; #ifndef RELEASE_BUILD - default:fatal("TRAP BLK/RPL PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); + default: + fatal("TRAP BLK/RPL PWIDTH %x %08x\n", + mystique->maccess_running & MACCESS_PWIDTH_MASK, + mystique->dwgreg.dwgctrl_running); #endif - } - } - } + } + } + } - mystique->dwgreg.dr[0] += mystique->dwgreg.dr[2]; - mystique->dwgreg.dr[4] += mystique->dwgreg.dr[6]; - mystique->dwgreg.dr[8] += mystique->dwgreg.dr[10]; - mystique->dwgreg.dr[12] += mystique->dwgreg.dr[14]; + mystique->dwgreg.dr[0] += mystique->dwgreg.dr[2]; + mystique->dwgreg.dr[4] += mystique->dwgreg.dr[6]; + mystique->dwgreg.dr[8] += mystique->dwgreg.dr[10]; + mystique->dwgreg.dr[12] += mystique->dwgreg.dr[14]; - x_l++; - mystique->pixel_count++; - } + x_l++; + mystique->pixel_count++; + } - mystique->dwgreg.dr[0] = z_back + mystique->dwgreg.dr[3]; - mystique->dwgreg.dr[4] = r_back + mystique->dwgreg.dr[7]; - mystique->dwgreg.dr[8] = g_back + mystique->dwgreg.dr[11]; - mystique->dwgreg.dr[12] = b_back + mystique->dwgreg.dr[15]; + mystique->dwgreg.dr[0] = z_back + mystique->dwgreg.dr[3]; + mystique->dwgreg.dr[4] = r_back + mystique->dwgreg.dr[7]; + mystique->dwgreg.dr[8] = g_back + mystique->dwgreg.dr[11]; + mystique->dwgreg.dr[12] = b_back + mystique->dwgreg.dr[15]; - while ((int32_t)mystique->dwgreg.ar[1] < 0 && mystique->dwgreg.ar[0]) { - mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; - mystique->dwgreg.fxleft += (mystique->dwgreg.sgn.sdxl ? -1 : 1); - } - mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2]; + while ((int32_t)mystique->dwgreg.ar[1] < 0 && mystique->dwgreg.ar[0]) { + mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; + mystique->dwgreg.fxleft += (mystique->dwgreg.sgn.sdxl ? -1 : 1); + } + mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2]; - while ((int32_t)mystique->dwgreg.ar[4] < 0 && mystique->dwgreg.ar[6]) { - mystique->dwgreg.ar[4] += mystique->dwgreg.ar[6]; - mystique->dwgreg.fxright += (mystique->dwgreg.sgn.sdxr ? -1 : 1); - } - mystique->dwgreg.ar[4] += mystique->dwgreg.ar[5]; + while ((int32_t)mystique->dwgreg.ar[4] < 0 && mystique->dwgreg.ar[6]) { + mystique->dwgreg.ar[4] += mystique->dwgreg.ar[6]; + mystique->dwgreg.fxright += (mystique->dwgreg.sgn.sdxr ? -1 : 1); + } + mystique->dwgreg.ar[4] += mystique->dwgreg.ar[5]; - dx = (int16_t)((mystique->dwgreg.fxleft - old_x_l) & 0xffff); - mystique->dwgreg.dr[0] += dx * mystique->dwgreg.dr[2]; - mystique->dwgreg.dr[4] += dx * mystique->dwgreg.dr[6]; - mystique->dwgreg.dr[8] += dx * mystique->dwgreg.dr[10]; - mystique->dwgreg.dr[12] += dx * mystique->dwgreg.dr[14]; + dx = (int16_t)((mystique->dwgreg.fxleft - old_x_l) & 0xffff); + mystique->dwgreg.dr[0] += dx * mystique->dwgreg.dr[2]; + mystique->dwgreg.dr[4] += dx * mystique->dwgreg.dr[6]; + mystique->dwgreg.dr[8] += dx * mystique->dwgreg.dr[10]; + mystique->dwgreg.dr[12] += dx * mystique->dwgreg.dr[14]; - mystique->dwgreg.ydst++; - mystique->dwgreg.ydst &= 0x7fffff; - mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + mystique->dwgreg.ydst++; + mystique->dwgreg.ydst &= 0x7fffff; + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); - mystique->dwgreg.selline = (mystique->dwgreg.selline + 1) & 7; - } - break; + mystique->dwgreg.selline = (mystique->dwgreg.selline + 1) & 7; + } + break; #ifndef RELEASE_BUILD - default:fatal("Unknown atype %03x %08x TRAP\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); + default: + fatal("Unknown atype %03x %08x TRAP\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, + mystique->dwgreg.dwgctrl_running); #endif - } + } - mystique->blitter_complete_refcount++; + mystique->blitter_complete_refcount++; } static int texture_read(mystique_t *mystique, int *tex_r, int *tex_g, int *tex_b, int *atransp) { - svga_t *svga = &mystique->svga; - const int tex_shift = 3 + ((mystique->dwgreg.texctl & TEXCTL_TPITCH_MASK) >> TEXCTL_TPITCH_SHIFT); - const unsigned int palsel = mystique->dwgreg.texctl & TEXCTL_PALSEL_MASK; - const uint16_t tckey = mystique->dwgreg.textrans & TEXTRANS_TCKEY_MASK; - const uint16_t tkmask = (mystique->dwgreg.textrans & TEXTRANS_TKMASK_MASK) >> TEXTRANS_TKMASK_SHIFT; - const unsigned int w_mask = (mystique->dwgreg.texwidth & TEXWIDTH_TWMASK_MASK) >> TEXWIDTH_TWMASK_SHIFT; - const unsigned int h_mask = (mystique->dwgreg.texheight & TEXHEIGHT_THMASK_MASK) >> TEXHEIGHT_THMASK_SHIFT; - uint16_t src = 0; - int s, t; + svga_t *svga = &mystique->svga; + const int tex_shift = 3 + ((mystique->dwgreg.texctl & TEXCTL_TPITCH_MASK) >> TEXCTL_TPITCH_SHIFT); + const unsigned int palsel = mystique->dwgreg.texctl & TEXCTL_PALSEL_MASK; + const uint16_t tckey = mystique->dwgreg.textrans & TEXTRANS_TCKEY_MASK; + const uint16_t tkmask = (mystique->dwgreg.textrans & TEXTRANS_TKMASK_MASK) >> TEXTRANS_TKMASK_SHIFT; + const unsigned int w_mask = (mystique->dwgreg.texwidth & TEXWIDTH_TWMASK_MASK) >> TEXWIDTH_TWMASK_SHIFT; + const unsigned int h_mask = (mystique->dwgreg.texheight & TEXHEIGHT_THMASK_MASK) >> TEXHEIGHT_THMASK_SHIFT; + uint16_t src = 0; + int s, t; - if (mystique->dwgreg.texctl & TEXCTL_NPCEN) { - const int s_shift = 20 - (mystique->dwgreg.texwidth & TEXWIDTH_TW_MASK); - const int t_shift = 20 - (mystique->dwgreg.texheight & TEXHEIGHT_TH_MASK); + if (mystique->dwgreg.texctl & TEXCTL_NPCEN) { + const int s_shift = 20 - (mystique->dwgreg.texwidth & TEXWIDTH_TW_MASK); + const int t_shift = 20 - (mystique->dwgreg.texheight & TEXHEIGHT_TH_MASK); - s = (int32_t)mystique->dwgreg.tmr[6] >> s_shift; - t = (int32_t)mystique->dwgreg.tmr[7] >> t_shift; - } else { - const int s_shift = (20 + 16) - (mystique->dwgreg.texwidth & TEXWIDTH_TW_MASK); - const int t_shift = (20 + 16) - (mystique->dwgreg.texheight & TEXHEIGHT_TH_MASK); - int64_t q = mystique->dwgreg.tmr[8] ? ((0x100000000ll / (int64_t)(int32_t)mystique->dwgreg.tmr[8]) /*>> 16*/) : 0; + s = (int32_t)mystique->dwgreg.tmr[6] >> s_shift; + t = (int32_t)mystique->dwgreg.tmr[7] >> t_shift; + } else { + const int s_shift = (20 + 16) - (mystique->dwgreg.texwidth & TEXWIDTH_TW_MASK); + const int t_shift = (20 + 16) - (mystique->dwgreg.texheight & TEXHEIGHT_TH_MASK); + int64_t q = mystique->dwgreg.tmr[8] ? ((0x100000000ll / (int64_t)(int32_t)mystique->dwgreg.tmr[8]) /*>> 16*/) : 0; - s = (((int64_t)(int32_t)mystique->dwgreg.tmr[6] * q) /*<< 8*/) >> s_shift;/*((16+20)-12);*/ - t = (((int64_t)(int32_t)mystique->dwgreg.tmr[7] * q) /*<< 8*/) >> t_shift;/*((16+20)-9);*/ - } + s = (((int64_t)(int32_t)mystique->dwgreg.tmr[6] * q) /*<< 8*/) >> s_shift; /*((16+20)-12);*/ + t = (((int64_t)(int32_t)mystique->dwgreg.tmr[7] * q) /*<< 8*/) >> t_shift; /*((16+20)-9);*/ + } - if (mystique->dwgreg.texctl & TEXCTL_CLAMPU) { - if (s < 0) - s = 0; - else if (s > w_mask) - s = w_mask; - } else - s &= w_mask; + if (mystique->dwgreg.texctl & TEXCTL_CLAMPU) { + if (s < 0) + s = 0; + else if (s > w_mask) + s = w_mask; + } else + s &= w_mask; - if (mystique->dwgreg.texctl & TEXCTL_CLAMPV) { - if (t < 0) - t = 0; - else if (t > h_mask) - t = h_mask; - } else - t &= h_mask; + if (mystique->dwgreg.texctl & TEXCTL_CLAMPV) { + if (t < 0) + t = 0; + else if (t > h_mask) + t = h_mask; + } else + t &= h_mask; - switch (mystique->dwgreg.texctl & TEXCTL_TEXFORMAT_MASK) { - case TEXCTL_TEXFORMAT_TW4:src = svga->vram[(mystique->dwgreg.texorg + (((t << tex_shift) + s) >> 1)) & mystique->vram_mask]; - if (s & 1) - src >>= 4; - else - src &= 0xf; - *tex_r = mystique->lut[src | palsel].r; - *tex_g = mystique->lut[src | palsel].g; - *tex_b = mystique->lut[src | palsel].b; - *atransp = 0; - break; - case TEXCTL_TEXFORMAT_TW8:src = svga->vram[(mystique->dwgreg.texorg + (t << tex_shift) + s) & mystique->vram_mask]; - *tex_r = mystique->lut[src].r; - *tex_g = mystique->lut[src].g; - *tex_b = mystique->lut[src].b; - *atransp = 0; - break; - case TEXCTL_TEXFORMAT_TW15:src = ((uint16_t *)svga->vram)[((mystique->dwgreg.texorg >> 1) + (t << tex_shift) + s) & mystique->vram_mask_w]; - *tex_r = ((src >> 10) & 0x1f) << 3; - *tex_g = ((src >> 5) & 0x1f) << 3; - *tex_b = (src & 0x1f) << 3; - if (((src >> 15) & mystique->dwgreg.ta_mask) == mystique->dwgreg.ta_key) - *atransp = 1; - else - *atransp = 0; - break; - case TEXCTL_TEXFORMAT_TW16:src = ((uint16_t *)svga->vram)[((mystique->dwgreg.texorg >> 1) + (t << tex_shift) + s) & mystique->vram_mask_w]; - *tex_r = (src >> 11) << 3; - *tex_g = ((src >> 5) & 0x3f) << 2; - *tex_b = (src & 0x1f) << 3; - *atransp = 0; - break; + switch (mystique->dwgreg.texctl & TEXCTL_TEXFORMAT_MASK) { + case TEXCTL_TEXFORMAT_TW4: + src = svga->vram[(mystique->dwgreg.texorg + (((t << tex_shift) + s) >> 1)) & mystique->vram_mask]; + if (s & 1) + src >>= 4; + else + src &= 0xf; + *tex_r = mystique->lut[src | palsel].r; + *tex_g = mystique->lut[src | palsel].g; + *tex_b = mystique->lut[src | palsel].b; + *atransp = 0; + break; + case TEXCTL_TEXFORMAT_TW8: + src = svga->vram[(mystique->dwgreg.texorg + (t << tex_shift) + s) & mystique->vram_mask]; + *tex_r = mystique->lut[src].r; + *tex_g = mystique->lut[src].g; + *tex_b = mystique->lut[src].b; + *atransp = 0; + break; + case TEXCTL_TEXFORMAT_TW15: + src = ((uint16_t *)svga->vram)[((mystique->dwgreg.texorg >> 1) + (t << tex_shift) + s) & mystique->vram_mask_w]; + *tex_r = ((src >> 10) & 0x1f) << 3; + *tex_g = ((src >> 5) & 0x1f) << 3; + *tex_b = (src & 0x1f) << 3; + if (((src >> 15) & mystique->dwgreg.ta_mask) == mystique->dwgreg.ta_key) + *atransp = 1; + else + *atransp = 0; + break; + case TEXCTL_TEXFORMAT_TW16: + src = ((uint16_t *)svga->vram)[((mystique->dwgreg.texorg >> 1) + (t << tex_shift) + s) & mystique->vram_mask_w]; + *tex_r = (src >> 11) << 3; + *tex_g = ((src >> 5) & 0x3f) << 2; + *tex_b = (src & 0x1f) << 3; + *atransp = 0; + break; #ifndef RELEASE_BUILD - default:fatal("Unknown texture format %i\n", mystique->dwgreg.texctl & TEXCTL_TEXFORMAT_MASK); - break; + default: + fatal("Unknown texture format %i\n", mystique->dwgreg.texctl & TEXCTL_TEXFORMAT_MASK); + break; #endif - } + } - return ((src & tkmask) == tckey); + return ((src & tkmask) == tckey); } static void blit_texture_trap(mystique_t *mystique) { - svga_t *svga = &mystique->svga; - int y; - int z_write; - const int trans_sel = (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANS_MASK) >> DWGCTRL_TRANS_SHIFT; - const int dest32 = ((mystique->maccess_running & MACCESS_PWIDTH_MASK) == MACCESS_PWIDTH_32); + svga_t *svga = &mystique->svga; + int y; + int z_write; + const int trans_sel = (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANS_MASK) >> DWGCTRL_TRANS_SHIFT; + const int dest32 = ((mystique->maccess_running & MACCESS_PWIDTH_MASK) == MACCESS_PWIDTH_32); - mystique->trap_count++; + mystique->trap_count++; - switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { - case DWGCTRL_ATYPE_I: - case DWGCTRL_ATYPE_ZI:z_write = ((mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) == DWGCTRL_ATYPE_ZI); -// pclog("fxleft=%i fxright=%i texctl=%08x texorg=%08x ydst=%i len=%i\n", mystique->dwgreg.fxleft, mystique->dwgreg.fxright, mystique->dwgreg.texctl, mystique->dwgreg.texorg, mystique->dwgreg.ydst, mystique->dwgreg.length); -/* pclog("fcol=%08x\n", mystique->dwgreg.fcol); - pclog("ytop=%i length=%i\n", mystique->dwgreg.ytop, mystique->dwgreg.length); - pclog("pitch=%08x\n", mystique->dwgreg.pitch); - pclog("ydst=%i ydst_lin=%08x\n", mystique->dwgreg.ydst, mystique->dwgreg.ydst_lin); - pclog("dYl =%08x errl =%08x -|dXl|=%08x\n", mystique->dwgreg.ar[0], mystique->dwgreg.ar[1], mystique->dwgreg.ar[2]); - pclog("errr=%08x -|dXr|=%08x dYr =%08x\n", mystique->dwgreg.ar[4], mystique->dwgreg.ar[5], mystique->dwgreg.ar[6]); - pclog(" q/wc=%08x q/wc/dX=%08x q/wc/dY=%08x\n", - mystique->dwgreg.tmr[8], mystique->dwgreg.tmr[4], mystique->dwgreg.tmr[5]); - pclog(" s/wc=%08x s/wc/dX=%08x s/wc/dY=%08x\n", - mystique->dwgreg.tmr[6], mystique->dwgreg.tmr[0], mystique->dwgreg.tmr[1]); - pclog(" t/wc=%08x t/wc/dX=%08x t/wc/dY=%08x\n", - mystique->dwgreg.tmr[7], mystique->dwgreg.tmr[2], mystique->dwgreg.tmr[3]);*/ + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { + case DWGCTRL_ATYPE_I: + case DWGCTRL_ATYPE_ZI: + z_write = ((mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) == DWGCTRL_ATYPE_ZI); + // pclog("fxleft=%i fxright=%i texctl=%08x texorg=%08x ydst=%i len=%i\n", mystique->dwgreg.fxleft, + // mystique->dwgreg.fxright, mystique->dwgreg.texctl, mystique->dwgreg.texorg, + // mystique->dwgreg.ydst, mystique->dwgreg.length); + /* pclog("fcol=%08x\n", mystique->dwgreg.fcol); + pclog("ytop=%i length=%i\n", mystique->dwgreg.ytop, mystique->dwgreg.length); + pclog("pitch=%08x\n", mystique->dwgreg.pitch); + pclog("ydst=%i ydst_lin=%08x\n", mystique->dwgreg.ydst, mystique->dwgreg.ydst_lin); + pclog("dYl =%08x errl =%08x -|dXl|=%08x\n", mystique->dwgreg.ar[0], mystique->dwgreg.ar[1], + mystique->dwgreg.ar[2]); pclog("errr=%08x -|dXr|=%08x dYr =%08x\n", mystique->dwgreg.ar[4], + mystique->dwgreg.ar[5], mystique->dwgreg.ar[6]); pclog(" q/wc=%08x q/wc/dX=%08x q/wc/dY=%08x\n", + mystique->dwgreg.tmr[8], mystique->dwgreg.tmr[4], mystique->dwgreg.tmr[5]); + pclog(" s/wc=%08x s/wc/dX=%08x s/wc/dY=%08x\n", + mystique->dwgreg.tmr[6], mystique->dwgreg.tmr[0], mystique->dwgreg.tmr[1]); + pclog(" t/wc=%08x t/wc/dX=%08x t/wc/dY=%08x\n", + mystique->dwgreg.tmr[7], mystique->dwgreg.tmr[2], mystique->dwgreg.tmr[3]);*/ - for (y = 0; y < mystique->dwgreg.length; y++) { - uint8_t const *const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; - uint16_t *z_p = (uint16_t *)&svga->vram[(mystique->dwgreg.ydst_lin * 2 + mystique->dwgreg.zorg) & mystique->vram_mask]; - int16_t x_l = mystique->dwgreg.fxleft & 0xffff; - int16_t x_r = mystique->dwgreg.fxright & 0xffff; - int16_t old_x_l = x_l; - int dx; + for (y = 0; y < mystique->dwgreg.length; y++) { + uint8_t const *const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; + uint16_t *z_p = + (uint16_t *)&svga + ->vram[(mystique->dwgreg.ydst_lin * 2 + mystique->dwgreg.zorg) & mystique->vram_mask]; + int16_t x_l = mystique->dwgreg.fxleft & 0xffff; + int16_t x_r = mystique->dwgreg.fxright & 0xffff; + int16_t old_x_l = x_l; + int dx; - uint32_t z_back = mystique->dwgreg.dr[0]; - uint32_t r_back = mystique->dwgreg.dr[4]; - uint32_t g_back = mystique->dwgreg.dr[8]; - uint32_t b_back = mystique->dwgreg.dr[12]; - uint32_t s_back = mystique->dwgreg.tmr[6]; - uint32_t t_back = mystique->dwgreg.tmr[7]; - uint32_t q_back = mystique->dwgreg.tmr[8]; + uint32_t z_back = mystique->dwgreg.dr[0]; + uint32_t r_back = mystique->dwgreg.dr[4]; + uint32_t g_back = mystique->dwgreg.dr[8]; + uint32_t b_back = mystique->dwgreg.dr[12]; + uint32_t s_back = mystique->dwgreg.tmr[6]; + uint32_t t_back = mystique->dwgreg.tmr[7]; + uint32_t q_back = mystique->dwgreg.tmr[8]; -// pclog(" line %i: %i %i %08x %08x %08x %08x %i\n", __y, x_l, x_r, mystique->dwgreg.dr[0],mystique->dwgreg.dr[2],mystique->dwgreg.dr[3], mystique->dwgreg.ydst_lin*2 + mystique->dwgreg.zorg, z_write); -// pclog(" %08x %08x %08x\n", mystique->dwgreg.tmr[4],mystique->dwgreg.tmr[5], mystique->dwgreg.tmr[8]); -// pclog(" %08x %08x %08x\n", mystique->dwgreg.ar[4], mystique->dwgreg.ar[5], mystique->dwgreg.ar[6]); + // pclog(" line %i: %i %i %08x %08x %08x %08x %i\n", __y, x_l, x_r, + // mystique->dwgreg.dr[0],mystique->dwgreg.dr[2],mystique->dwgreg.dr[3], + // mystique->dwgreg.ydst_lin*2 + mystique->dwgreg.zorg, z_write); pclog(" %08x + // %08x %08x\n", mystique->dwgreg.tmr[4],mystique->dwgreg.tmr[5], + // mystique->dwgreg.tmr[8]); pclog(" %08x %08x %08x\n", mystique->dwgreg.ar[4], + // mystique->dwgreg.ar[5], mystique->dwgreg.ar[6]); - while (x_l != x_r) { - if (x_l >= mystique->dwgreg.cxleft && x_l <= mystique->dwgreg.cxright && - mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && - trans[x_l & 3]) { - uint16_t z = ((int32_t)mystique->dwgreg.dr[0] < 0) ? 0 : (mystique->dwgreg.dr[0] >> 15); - uint16_t old_z = z_p[x_l]; + while (x_l != x_r) { + if (x_l >= mystique->dwgreg.cxleft && x_l <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && + mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && trans[x_l & 3]) { + uint16_t z = ((int32_t)mystique->dwgreg.dr[0] < 0) ? 0 : (mystique->dwgreg.dr[0] >> 15); + uint16_t old_z = z_p[x_l]; - if (z_check(z, old_z, mystique->dwgreg.dwgctrl_running & DWGCTRL_ZMODE_MASK)) { - int tex_r = 0, tex_g = 0, tex_b = 0; - int ctransp, atransp = 0; - int i_r = 0, i_g = 0, i_b = 0; + if (z_check(z, old_z, mystique->dwgreg.dwgctrl_running & DWGCTRL_ZMODE_MASK)) { + int tex_r = 0, tex_g = 0, tex_b = 0; + int ctransp, atransp = 0; + int i_r = 0, i_g = 0, i_b = 0; - if (!(mystique->dwgreg.dr[4] & (1 << 23))) - i_r = (mystique->dwgreg.dr[4] >> 15) & 0xff; - if (!(mystique->dwgreg.dr[8] & (1 << 23))) - i_g = (mystique->dwgreg.dr[8] >> 15) & 0xff; - if (!(mystique->dwgreg.dr[12] & (1 << 23))) - i_b = (mystique->dwgreg.dr[12] >> 15) & 0xff; + if (!(mystique->dwgreg.dr[4] & (1 << 23))) + i_r = (mystique->dwgreg.dr[4] >> 15) & 0xff; + if (!(mystique->dwgreg.dr[8] & (1 << 23))) + i_g = (mystique->dwgreg.dr[8] >> 15) & 0xff; + if (!(mystique->dwgreg.dr[12] & (1 << 23))) + i_b = (mystique->dwgreg.dr[12] >> 15) & 0xff; - ctransp = texture_read(mystique, &tex_r, &tex_g, &tex_b, &atransp); + ctransp = texture_read(mystique, &tex_r, &tex_g, &tex_b, &atransp); - switch (mystique->dwgreg.texctl & (TEXCTL_TMODULATE | TEXCTL_STRANS | TEXCTL_ITRANS | TEXCTL_DECALCKEY)) { - case 0: - if (ctransp) - goto skip_pixel; - if (atransp) { - tex_r = i_r; - tex_g = i_g; - tex_b = i_b; - } - break; + switch (mystique->dwgreg.texctl & + (TEXCTL_TMODULATE | TEXCTL_STRANS | TEXCTL_ITRANS | TEXCTL_DECALCKEY)) { + case 0: + if (ctransp) + goto skip_pixel; + if (atransp) { + tex_r = i_r; + tex_g = i_g; + tex_b = i_b; + } + break; - case TEXCTL_DECALCKEY: - if (ctransp) { - tex_r = i_r; - tex_g = i_g; - tex_b = i_b; - } - break; + case TEXCTL_DECALCKEY: + if (ctransp) { + tex_r = i_r; + tex_g = i_g; + tex_b = i_b; + } + break; - case (TEXCTL_STRANS | TEXCTL_DECALCKEY): - if (ctransp) - goto skip_pixel; - break; + case (TEXCTL_STRANS | TEXCTL_DECALCKEY): + if (ctransp) + goto skip_pixel; + break; - case TEXCTL_TMODULATE: - if (ctransp) - goto skip_pixel; - if (mystique->dwgreg.texctl & TEXCTL_TMODULATE) { - tex_r = (tex_r * i_r) >> 8; - tex_g = (tex_g * i_g) >> 8; - tex_b = (tex_b * i_b) >> 8; - } - break; + case TEXCTL_TMODULATE: + if (ctransp) + goto skip_pixel; + if (mystique->dwgreg.texctl & TEXCTL_TMODULATE) { + tex_r = (tex_r * i_r) >> 8; + tex_g = (tex_g * i_g) >> 8; + tex_b = (tex_b * i_b) >> 8; + } + break; - case (TEXCTL_TMODULATE | TEXCTL_STRANS): - if (ctransp || atransp) - goto skip_pixel; - if (mystique->dwgreg.texctl & TEXCTL_TMODULATE) { - tex_r = (tex_r * i_r) >> 8; - tex_g = (tex_g * i_g) >> 8; - tex_b = (tex_b * i_b) >> 8; - } - break; + case (TEXCTL_TMODULATE | TEXCTL_STRANS): + if (ctransp || atransp) + goto skip_pixel; + if (mystique->dwgreg.texctl & TEXCTL_TMODULATE) { + tex_r = (tex_r * i_r) >> 8; + tex_g = (tex_g * i_g) >> 8; + tex_b = (tex_b * i_b) >> 8; + } + break; #ifndef RELEASE_BUILD - default: - fatal("Bad TEXCTL %08x %08x\n", mystique->dwgreg.texctl, - mystique->dwgreg.texctl & (TEXCTL_TMODULATE | TEXCTL_STRANS | TEXCTL_ITRANS | TEXCTL_DECALCKEY)); + default: + fatal("Bad TEXCTL %08x %08x\n", mystique->dwgreg.texctl, + mystique->dwgreg.texctl & (TEXCTL_TMODULATE | TEXCTL_STRANS | + TEXCTL_ITRANS | TEXCTL_DECALCKEY)); #endif - } + } - if (dest32) { - ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l] = tex_b | (tex_g << 8) | (tex_r << 16); - svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l) >> 10] = changeframecount; - } else { - ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w] = dither(mystique, tex_r, tex_g, tex_b, - x_l & 1, mystique->dwgreg.selline & 1); - svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w) >> 11] = changeframecount; - } - if (z_write) - z_p[x_l] = z; - } - } - skip_pixel: - x_l++; - mystique->pixel_count++; + if (dest32) { + ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & + mystique->vram_mask_l] = + tex_b | (tex_g << 8) | (tex_r << 16); + svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & + mystique->vram_mask_l) >> + 10] = changeframecount; + } else { + ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & + mystique->vram_mask_w] = + dither(mystique, tex_r, tex_g, tex_b, x_l & 1, + mystique->dwgreg.selline & 1); + svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & + mystique->vram_mask_w) >> + 11] = changeframecount; + } + if (z_write) + z_p[x_l] = z; + } + } + skip_pixel: + x_l++; + mystique->pixel_count++; - mystique->dwgreg.dr[0] += mystique->dwgreg.dr[2]; - mystique->dwgreg.dr[4] += mystique->dwgreg.dr[6]; - mystique->dwgreg.dr[8] += mystique->dwgreg.dr[10]; - mystique->dwgreg.dr[12] += mystique->dwgreg.dr[14]; - mystique->dwgreg.tmr[6] += mystique->dwgreg.tmr[0]; - mystique->dwgreg.tmr[7] += mystique->dwgreg.tmr[2]; - mystique->dwgreg.tmr[8] += mystique->dwgreg.tmr[4]; - } + mystique->dwgreg.dr[0] += mystique->dwgreg.dr[2]; + mystique->dwgreg.dr[4] += mystique->dwgreg.dr[6]; + mystique->dwgreg.dr[8] += mystique->dwgreg.dr[10]; + mystique->dwgreg.dr[12] += mystique->dwgreg.dr[14]; + mystique->dwgreg.tmr[6] += mystique->dwgreg.tmr[0]; + mystique->dwgreg.tmr[7] += mystique->dwgreg.tmr[2]; + mystique->dwgreg.tmr[8] += mystique->dwgreg.tmr[4]; + } - mystique->dwgreg.dr[0] = z_back + mystique->dwgreg.dr[3]; - mystique->dwgreg.dr[4] = r_back + mystique->dwgreg.dr[7]; - mystique->dwgreg.dr[8] = g_back + mystique->dwgreg.dr[11]; - mystique->dwgreg.dr[12] = b_back + mystique->dwgreg.dr[15]; - mystique->dwgreg.tmr[6] = s_back + mystique->dwgreg.tmr[1]; - mystique->dwgreg.tmr[7] = t_back + mystique->dwgreg.tmr[3]; - mystique->dwgreg.tmr[8] = q_back + mystique->dwgreg.tmr[5]; + mystique->dwgreg.dr[0] = z_back + mystique->dwgreg.dr[3]; + mystique->dwgreg.dr[4] = r_back + mystique->dwgreg.dr[7]; + mystique->dwgreg.dr[8] = g_back + mystique->dwgreg.dr[11]; + mystique->dwgreg.dr[12] = b_back + mystique->dwgreg.dr[15]; + mystique->dwgreg.tmr[6] = s_back + mystique->dwgreg.tmr[1]; + mystique->dwgreg.tmr[7] = t_back + mystique->dwgreg.tmr[3]; + mystique->dwgreg.tmr[8] = q_back + mystique->dwgreg.tmr[5]; - while ((int32_t)mystique->dwgreg.ar[1] < 0 && mystique->dwgreg.ar[0]) { - mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; - mystique->dwgreg.fxleft += (mystique->dwgreg.sgn.sdxl ? -1 : 1); - } - mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2]; + while ((int32_t)mystique->dwgreg.ar[1] < 0 && mystique->dwgreg.ar[0]) { + mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; + mystique->dwgreg.fxleft += (mystique->dwgreg.sgn.sdxl ? -1 : 1); + } + mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2]; - while ((int32_t)mystique->dwgreg.ar[4] < 0 && mystique->dwgreg.ar[6]) { - mystique->dwgreg.ar[4] += mystique->dwgreg.ar[6]; - mystique->dwgreg.fxright += (mystique->dwgreg.sgn.sdxr ? -1 : 1); - } - mystique->dwgreg.ar[4] += mystique->dwgreg.ar[5]; + while ((int32_t)mystique->dwgreg.ar[4] < 0 && mystique->dwgreg.ar[6]) { + mystique->dwgreg.ar[4] += mystique->dwgreg.ar[6]; + mystique->dwgreg.fxright += (mystique->dwgreg.sgn.sdxr ? -1 : 1); + } + mystique->dwgreg.ar[4] += mystique->dwgreg.ar[5]; - dx = (int16_t)((mystique->dwgreg.fxleft - old_x_l) & 0xffff); - mystique->dwgreg.dr[0] += dx * mystique->dwgreg.dr[2]; - mystique->dwgreg.dr[4] += dx * mystique->dwgreg.dr[6]; - mystique->dwgreg.dr[8] += dx * mystique->dwgreg.dr[10]; - mystique->dwgreg.dr[12] += dx * mystique->dwgreg.dr[14]; - mystique->dwgreg.tmr[6] += dx * mystique->dwgreg.tmr[0]; - mystique->dwgreg.tmr[7] += dx * mystique->dwgreg.tmr[2]; - mystique->dwgreg.tmr[8] += dx * mystique->dwgreg.tmr[4]; + dx = (int16_t)((mystique->dwgreg.fxleft - old_x_l) & 0xffff); + mystique->dwgreg.dr[0] += dx * mystique->dwgreg.dr[2]; + mystique->dwgreg.dr[4] += dx * mystique->dwgreg.dr[6]; + mystique->dwgreg.dr[8] += dx * mystique->dwgreg.dr[10]; + mystique->dwgreg.dr[12] += dx * mystique->dwgreg.dr[14]; + mystique->dwgreg.tmr[6] += dx * mystique->dwgreg.tmr[0]; + mystique->dwgreg.tmr[7] += dx * mystique->dwgreg.tmr[2]; + mystique->dwgreg.tmr[8] += dx * mystique->dwgreg.tmr[4]; - mystique->dwgreg.ydst++; - mystique->dwgreg.ydst &= 0x7fffff; - mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + mystique->dwgreg.ydst++; + mystique->dwgreg.ydst &= 0x7fffff; + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); - mystique->dwgreg.selline = (mystique->dwgreg.selline + 1) & 7; - } - break; + mystique->dwgreg.selline = (mystique->dwgreg.selline + 1) & 7; + } + break; #ifndef RELEASE_BUILD - default:fatal("Unknown atype %03x %08x TEXTURE_TRAP\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); + default: + fatal("Unknown atype %03x %08x TEXTURE_TRAP\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, + mystique->dwgreg.dwgctrl_running); #endif - } + } - mystique->blitter_complete_refcount++; + mystique->blitter_complete_refcount++; } static void blit_bitblt(mystique_t *mystique) { - svga_t *svga = &mystique->svga; - uint32_t src_addr; - int y; - int x_dir = mystique->dwgreg.sgn.scanleft ? -1 : 1; - int16_t x_start = mystique->dwgreg.sgn.scanleft ? mystique->dwgreg.fxright : mystique->dwgreg.fxleft; - int16_t x_end = mystique->dwgreg.sgn.scanleft ? mystique->dwgreg.fxleft : mystique->dwgreg.fxright; - const int trans_sel = (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANS_MASK) >> DWGCTRL_TRANS_SHIFT; + svga_t *svga = &mystique->svga; + uint32_t src_addr; + int y; + int x_dir = mystique->dwgreg.sgn.scanleft ? -1 : 1; + int16_t x_start = mystique->dwgreg.sgn.scanleft ? mystique->dwgreg.fxright : mystique->dwgreg.fxleft; + int16_t x_end = mystique->dwgreg.sgn.scanleft ? mystique->dwgreg.fxleft : mystique->dwgreg.fxright; + const int trans_sel = (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANS_MASK) >> DWGCTRL_TRANS_SHIFT; - switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { - case DWGCTRL_ATYPE_BLK: -// if (mystique->maccess_running & MACCESS_TLUTLOAD) -// fatal("Bitblt TLUTLOAD BLK\n"); -// if (mystique->dwgreg.dwgctrl_running & DWGCTRL_PATTERN) -// fatal("BITBLT BLK with pattern\n"); - switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { - case DWGCTRL_BLTMOD_BMONOLEF: -// pclog("ar0=%08x ar3=%08x ar5=%08x dwgctrl=%08x\n", mystique->dwgreg.ar[0], mystique->dwgreg.ar[3], mystique->dwgreg.ar[5], mystique->dwgreg.dwgctrl_running); -// pclog("fxleft=%i fxright=%i ydst=%i fcol=%08x bcol=%08x\n", mystique->dwgreg.fxleft, mystique->dwgreg.fxright, mystique->dwgreg.ydst, mystique->dwgreg.fcol, mystique->dwgreg.bcol); + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { + case DWGCTRL_ATYPE_BLK: + // if (mystique->maccess_running & MACCESS_TLUTLOAD) + // fatal("Bitblt TLUTLOAD BLK\n"); + // if (mystique->dwgreg.dwgctrl_running & DWGCTRL_PATTERN) + // fatal("BITBLT BLK with pattern\n"); + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { + case DWGCTRL_BLTMOD_BMONOLEF: + // pclog("ar0=%08x ar3=%08x ar5=%08x dwgctrl=%08x\n", mystique->dwgreg.ar[0], + // mystique->dwgreg.ar[3], mystique->dwgreg.ar[5], + // mystique->dwgreg.dwgctrl_running); pclog("fxleft=%i fxright=%i ydst=%i fcol=%08x + // bcol=%08x\n", mystique->dwgreg.fxleft, mystique->dwgreg.fxright, + // mystique->dwgreg.ydst, mystique->dwgreg.fcol, mystique->dwgreg.bcol); - src_addr = mystique->dwgreg.ar[3]; -// mystique->dwgreg.bit_offset = 0; + src_addr = mystique->dwgreg.ar[3]; + // mystique->dwgreg.bit_offset = 0; - for (y = 0; y < mystique->dwgreg.length; y++) { - int16_t x = x_start; + for (y = 0; y < mystique->dwgreg.length; y++) { + int16_t x = x_start; -// pclog(" line %03i: %08x %08x %02x\n", y, mystique->dwgreg.ydst_lin, src_addr, svga->vram[0x2eba3]); - while (1) { - if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && - mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { - uint32_t byte_addr = (src_addr >> 3) & mystique->vram_mask; - int bit_offset = src_addr & 7; - uint32_t old_dst; + // pclog(" line %03i: %08x %08x %02x\n", y, + // mystique->dwgreg.ydst_lin, src_addr, svga->vram[0x2eba3]); + while (1) { + if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && + mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { + uint32_t byte_addr = (src_addr >> 3) & mystique->vram_mask; + int bit_offset = src_addr & 7; + uint32_t old_dst; - switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { - case MACCESS_PWIDTH_8: -// pclog(" pix %i %02x %i %i %06x\n", x, svga->vram[byte_addr], svga->vram[byte_addr] & (1 << bit_offset), mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC, byte_addr); - if (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC) { - if (svga->vram[byte_addr] & (1 << bit_offset)) - svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = mystique->dwgreg.fcol; - } else - svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = - (svga->vram[byte_addr] & (1 << bit_offset)) ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; - svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = changeframecount; - break; + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_8: + // pclog(" pix %i + // %02x %i %i + // %06x\n", x, + // svga->vram[byte_addr], + // svga->vram[byte_addr] + // & (1 << + // bit_offset), + // mystique->dwgreg.dwgctrl_running + // & + // DWGCTRL_TRANSC, + // byte_addr); + if (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC) { + if (svga->vram[byte_addr] & (1 << bit_offset)) + svga->vram[(mystique->dwgreg.ydst_lin + x) & + mystique->vram_mask] = mystique->dwgreg.fcol; + } else + svga->vram[(mystique->dwgreg.ydst_lin + x) & + mystique->vram_mask] = + (svga->vram[byte_addr] & (1 << bit_offset)) + ? mystique->dwgreg.fcol + : mystique->dwgreg.bcol; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & + mystique->vram_mask) >> + 12] = changeframecount; + break; - case MACCESS_PWIDTH_16: -// pclog(" pix %i %02x %i %i %06x\n", x, svga->vram[byte_addr], svga->vram[byte_addr] & (1 << bit_offset), mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC, byte_addr); - if (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC) { - if (svga->vram[byte_addr] & (1 << bit_offset)) - ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = mystique->dwgreg.fcol; - } else - ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = - (svga->vram[byte_addr] & (1 << bit_offset)) ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; - svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount; - break; + case MACCESS_PWIDTH_16: + // pclog(" pix %i + // %02x %i %i + // %06x\n", x, + // svga->vram[byte_addr], + // svga->vram[byte_addr] + // & (1 << + // bit_offset), + // mystique->dwgreg.dwgctrl_running + // & + // DWGCTRL_TRANSC, + // byte_addr); + if (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC) { + if (svga->vram[byte_addr] & (1 << bit_offset)) + ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & + mystique->vram_mask_w] = + mystique->dwgreg.fcol; + } else + ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & + mystique->vram_mask_w] = + (svga->vram[byte_addr] & (1 << bit_offset)) + ? mystique->dwgreg.fcol + : mystique->dwgreg.bcol; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & + mystique->vram_mask_w) >> + 11] = changeframecount; + break; - case MACCESS_PWIDTH_24:old_dst = *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask]; -// pclog(" pix %i %02x %i %i %06x\n", x, svga->vram[byte_addr], svga->vram[byte_addr] & (1 << bit_offset), mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC, byte_addr); - if (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC) { - if (svga->vram[byte_addr] & (1 << bit_offset)) - *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = - (old_dst & 0xff000000) | (mystique->dwgreg.fcol & 0xffffff); - } else - *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = - (old_dst & 0xff000000) - | (((svga->vram[byte_addr] & (1 << bit_offset)) ? mystique->dwgreg.fcol : mystique->dwgreg.bcol) & 0xffffff); - svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = changeframecount; - break; + case MACCESS_PWIDTH_24: + old_dst = *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & + mystique->vram_mask]; + // pclog(" pix %i + // %02x %i %i + // %06x\n", x, + // svga->vram[byte_addr], + // svga->vram[byte_addr] + // & (1 << + // bit_offset), + // mystique->dwgreg.dwgctrl_running + // & + // DWGCTRL_TRANSC, + // byte_addr); + if (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC) { + if (svga->vram[byte_addr] & (1 << bit_offset)) + *(uint32_t *)&svga + ->vram[((mystique->dwgreg.ydst_lin + x) * 3) & + mystique->vram_mask] = + (old_dst & 0xff000000) | + (mystique->dwgreg.fcol & 0xffffff); + } else + *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & + mystique->vram_mask] = + (old_dst & 0xff000000) | + (((svga->vram[byte_addr] & (1 << bit_offset)) + ? mystique->dwgreg.fcol + : mystique->dwgreg.bcol) & + 0xffffff); + svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & + mystique->vram_mask) >> + 12] = changeframecount; + break; - case MACCESS_PWIDTH_32: -// pclog(" pix %i %02x %i %i %06x\n", x, svga->vram[byte_addr], svga->vram[byte_addr] & (1 << bit_offset), mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC, byte_addr); - if (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC) { - if (svga->vram[byte_addr] & (1 << bit_offset)) - ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & 0xfffff] = mystique->dwgreg.fcol; - } else - ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & 0xfffff] = - (svga->vram[byte_addr] & (1 << bit_offset)) ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; - svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l) >> 10] = changeframecount; - break; + case MACCESS_PWIDTH_32: + // pclog(" pix %i + // %02x %i %i + // %06x\n", x, + // svga->vram[byte_addr], + // svga->vram[byte_addr] + // & (1 << + // bit_offset), + // mystique->dwgreg.dwgctrl_running + // & + // DWGCTRL_TRANSC, + // byte_addr); + if (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC) { + if (svga->vram[byte_addr] & (1 << bit_offset)) + ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & + 0xfffff] = mystique->dwgreg.fcol; + } else + ((uint32_t *) + svga->vram)[(mystique->dwgreg.ydst_lin + x) & 0xfffff] = + (svga->vram[byte_addr] & (1 << bit_offset)) + ? mystique->dwgreg.fcol + : mystique->dwgreg.bcol; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & + mystique->vram_mask_l) >> + 10] = changeframecount; + break; #ifndef RELEASE_BUILD - default:fatal("BITBLT DWGCTRL_ATYPE_BLK unknown MACCESS %i\n", mystique->maccess_running & MACCESS_PWIDTH_MASK); + default: + fatal("BITBLT DWGCTRL_ATYPE_BLK unknown MACCESS %i\n", + mystique->maccess_running & MACCESS_PWIDTH_MASK); #endif - } - } + } + } - if (src_addr == mystique->dwgreg.ar[0]) { - mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; - mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; - src_addr = mystique->dwgreg.ar[3]; - } else - src_addr += x_dir; + if (src_addr == mystique->dwgreg.ar[0]) { + mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; + mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; + src_addr = mystique->dwgreg.ar[3]; + } else + src_addr += x_dir; - if (x != x_end) - x += x_dir; - else - break; - } + if (x != x_end) + x += x_dir; + else + break; + } - if (mystique->dwgreg.sgn.sdy) - mystique->dwgreg.ydst_lin -= (mystique->dwgreg.pitch & PITCH_MASK); - else - mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); - } - break; + if (mystique->dwgreg.sgn.sdy) + mystique->dwgreg.ydst_lin -= (mystique->dwgreg.pitch & PITCH_MASK); + else + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + } + break; #ifndef RELEASE_BUILD - default:fatal("BITBLT BLK %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK); - break; + default: + fatal("BITBLT BLK %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK); + break; #endif - } - break; + } + break; - case DWGCTRL_ATYPE_RPL: -// pclog(" bitblt RPL\n"); - if (mystique->maccess_running & MACCESS_TLUTLOAD) { -// pclog("TLUTLOAD!\n"); - src_addr = mystique->dwgreg.ar[3]; + case DWGCTRL_ATYPE_RPL: + // pclog(" bitblt RPL\n"); + if (mystique->maccess_running & MACCESS_TLUTLOAD) { + // pclog("TLUTLOAD!\n"); + src_addr = mystique->dwgreg.ar[3]; - y = mystique->dwgreg.ydst; + y = mystique->dwgreg.ydst; - while (mystique->dwgreg.length) { - uint16_t src = ((uint16_t *)svga->vram)[src_addr & mystique->vram_mask_w]; -// pclog(" LUT[%02x]=VRAM[%05X]=%04x\n", y & 0xff, src_addr, src); + while (mystique->dwgreg.length) { + uint16_t src = ((uint16_t *)svga->vram)[src_addr & mystique->vram_mask_w]; + // pclog(" LUT[%02x]=VRAM[%05X]=%04x\n", y & 0xff, src_addr, src); - mystique->lut[y & 0xff].r = (src >> 11) << 3; - mystique->lut[y & 0xff].g = ((src >> 5) & 0x3f) << 2; - mystique->lut[y & 0xff].b = (src & 0x1f) << 3; - src_addr++; - y++; - mystique->dwgreg.length--; - } - break; - } - case DWGCTRL_ATYPE_RSTR: -// pclog(" bitblt RPL or RSTR\n"); -// if (mystique->maccess_running & MACCESS_TLUTLOAD) -// fatal("Bitblt TLUTLOAD RSTR\n"); - switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { - case DWGCTRL_BLTMOD_BMONOLEF: -// pclog("ar0=%08x ar3=%08x ar5=%08x\n", mystique->dwgreg.ar[0], mystique->dwgreg.ar[3], mystique->dwgreg.ar[5]); -// pclog("fxleft=%i fxright=%i\n", mystique->dwgreg.fxleft, mystique->dwgreg.fxright); + mystique->lut[y & 0xff].r = (src >> 11) << 3; + mystique->lut[y & 0xff].g = ((src >> 5) & 0x3f) << 2; + mystique->lut[y & 0xff].b = (src & 0x1f) << 3; + src_addr++; + y++; + mystique->dwgreg.length--; + } + break; + } + case DWGCTRL_ATYPE_RSTR: + // pclog(" bitblt RPL or RSTR\n"); + // if (mystique->maccess_running & MACCESS_TLUTLOAD) + // fatal("Bitblt TLUTLOAD RSTR\n"); + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { + case DWGCTRL_BLTMOD_BMONOLEF: + // pclog("ar0=%08x ar3=%08x ar5=%08x\n", mystique->dwgreg.ar[0], + // mystique->dwgreg.ar[3], mystique->dwgreg.ar[5]); pclog("fxleft=%i fxright=%i\n", + // mystique->dwgreg.fxleft, mystique->dwgreg.fxright); #ifndef RELEASE_BUILD - if (mystique->dwgreg.dwgctrl_running & DWGCTRL_PATTERN) - fatal("BITBLT RPL/RSTR BMONOLEF with pattern\n"); + if (mystique->dwgreg.dwgctrl_running & DWGCTRL_PATTERN) + fatal("BITBLT RPL/RSTR BMONOLEF with pattern\n"); #endif - src_addr = mystique->dwgreg.ar[3]; + src_addr = mystique->dwgreg.ar[3]; - for (y = 0; y < mystique->dwgreg.length; y++) { - uint8_t const *const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; - int16_t x = x_start; + for (y = 0; y < mystique->dwgreg.length; y++) { + uint8_t const *const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; + int16_t x = x_start; -// pclog(" line %03i: %08x %08x\n", y, mystique->dwgreg.ydst_lin, src_addr); - while (1) { - uint32_t byte_addr = (src_addr >> 3) & mystique->vram_mask; - int bit_offset = src_addr & 7; + // pclog(" line %03i: %08x %08x\n", y, mystique->dwgreg.ydst_lin, + // src_addr); + while (1) { + uint32_t byte_addr = (src_addr >> 3) & mystique->vram_mask; + int bit_offset = src_addr & 7; - if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && - mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && - ((svga->vram[byte_addr] & (1 << bit_offset)) || !(mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC)) && - trans[x & 3]) { - uint32_t src = (svga->vram[byte_addr] & (1 << bit_offset)) ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; - uint32_t dst, old_dst; + if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && + mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && + ((svga->vram[byte_addr] & (1 << bit_offset)) || + !(mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC)) && + trans[x & 3]) { + uint32_t src = (svga->vram[byte_addr] & (1 << bit_offset)) + ? mystique->dwgreg.fcol + : mystique->dwgreg.bcol; + uint32_t dst, old_dst; - switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { - case MACCESS_PWIDTH_8:dst = svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask]; + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_8: + dst = svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask]; -// pclog(" %02x %02x ", src, dst); - dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running);// & DWGCTRL_BOP_MASK -// pclog("%08x %08x %i dst=%02x\n", src_addr, mystique->dwgreg.ydst_lin + x, mystique->dwgreg.sgn.scanleft, dst); + // pclog(" %02x + // %02x ", src, + // dst); + dst = bitop(src, dst, + mystique->dwgreg.dwgctrl_running); // & DWGCTRL_BOP_MASK + // pclog("%08x %08x + // %i dst=%02x\n", + // src_addr, + // mystique->dwgreg.ydst_lin + // + x, + // mystique->dwgreg.sgn.scanleft, + // dst); - svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = changeframecount; - break; + svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & + mystique->vram_mask) >> + 12] = changeframecount; + break; - case MACCESS_PWIDTH_16:dst = ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w]; + case MACCESS_PWIDTH_16: + dst = ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & + mystique->vram_mask_w]; -// pclog(" %02x %02x ", src, dst); - dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running);// & DWGCTRL_BOP_MASK -// pclog("%08x %08x %i dst=%02x\n", src_addr, mystique->dwgreg.ydst_lin + x, mystique->dwgreg.sgn.scanleft, dst); + // pclog(" %02x + // %02x ", src, + // dst); + dst = bitop(src, dst, + mystique->dwgreg.dwgctrl_running); // & DWGCTRL_BOP_MASK + // pclog("%08x %08x + // %i dst=%02x\n", + // src_addr, + // mystique->dwgreg.ydst_lin + // + x, + // mystique->dwgreg.sgn.scanleft, + // dst); - ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount; - break; + ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & + mystique->vram_mask_w] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & + mystique->vram_mask_w) >> + 11] = changeframecount; + break; - case MACCESS_PWIDTH_24:old_dst = *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask]; + case MACCESS_PWIDTH_24: + old_dst = *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & + mystique->vram_mask]; -// pclog(" %02x %02x ", src, old_dst); - dst = bitop(src, old_dst, mystique->dwgreg.dwgctrl_running);// & DWGCTRL_BOP_MASK -// pclog("%08x %08x %i dst=%02x\n", src_addr, mystique->dwgreg.ydst_lin + x, mystique->dwgreg.sgn.scanleft, dst); + // pclog(" %02x + // %02x ", src, + // old_dst); + dst = bitop(src, old_dst, + mystique->dwgreg.dwgctrl_running); // & DWGCTRL_BOP_MASK + // pclog("%08x %08x + // %i dst=%02x\n", + // src_addr, + // mystique->dwgreg.ydst_lin + // + x, + // mystique->dwgreg.sgn.scanleft, + // dst); - *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = (dst & 0xffffff) | (old_dst & 0xff000000); - svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = changeframecount; - break; + *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & + mystique->vram_mask] = + (dst & 0xffffff) | (old_dst & 0xff000000); + svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & + mystique->vram_mask) >> + 12] = changeframecount; + break; - case MACCESS_PWIDTH_32:dst = ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l]; + case MACCESS_PWIDTH_32: + dst = ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & + mystique->vram_mask_l]; -// pclog(" %02x %02x ", src, dst); - dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running);// & DWGCTRL_BOP_MASK -// pclog("%08x %08x %i dst=%02x\n", src_addr, mystique->dwgreg.ydst_lin + x, mystique->dwgreg.sgn.scanleft, dst); + // pclog(" %02x + // %02x ", src, + // dst); + dst = bitop(src, dst, + mystique->dwgreg.dwgctrl_running); // & DWGCTRL_BOP_MASK + // pclog("%08x %08x + // %i dst=%02x\n", + // src_addr, + // mystique->dwgreg.ydst_lin + // + x, + // mystique->dwgreg.sgn.scanleft, + // dst); - ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 10] = changeframecount; - break; + ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & + mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & + mystique->vram_mask_w) >> + 10] = changeframecount; + break; #ifndef RELEASE_BUILD - default:fatal("BITBLT RPL BMONOLEF PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); + default: + fatal("BITBLT RPL BMONOLEF PWIDTH %x %08x\n", + mystique->maccess_running & MACCESS_PWIDTH_MASK, + mystique->dwgreg.dwgctrl_running); #endif - } - } + } + } - if (src_addr == mystique->dwgreg.ar[0]) { - mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; - mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; - src_addr = mystique->dwgreg.ar[3]; - } else - src_addr += x_dir; + if (src_addr == mystique->dwgreg.ar[0]) { + mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; + mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; + src_addr = mystique->dwgreg.ar[3]; + } else + src_addr += x_dir; - if (x != x_end) - x += x_dir; - else - break; - } + if (x != x_end) + x += x_dir; + else + break; + } - if (mystique->dwgreg.sgn.sdy) - mystique->dwgreg.ydst_lin -= (mystique->dwgreg.pitch & PITCH_MASK); - else - mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); - } - break; + if (mystique->dwgreg.sgn.sdy) + mystique->dwgreg.ydst_lin -= (mystique->dwgreg.pitch & PITCH_MASK); + else + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + } + break; - case DWGCTRL_BLTMOD_BFCOL: - case DWGCTRL_BLTMOD_BU32RGB: -// pclog("ar0=%08x ar3=%08x ar5=%08x\n", mystique->dwgreg.ar[0], mystique->dwgreg.ar[3], mystique->dwgreg.ar[5]); -// pclog("fxleft=%i fxright=%i\n", mystique->dwgreg.fxleft, mystique->dwgreg.fxright); + case DWGCTRL_BLTMOD_BFCOL: + case DWGCTRL_BLTMOD_BU32RGB: + // pclog("ar0=%08x ar3=%08x ar5=%08x\n", mystique->dwgreg.ar[0], + // mystique->dwgreg.ar[3], mystique->dwgreg.ar[5]); pclog("fxleft=%i fxright=%i\n", + // mystique->dwgreg.fxleft, mystique->dwgreg.fxright); - src_addr = mystique->dwgreg.ar[3]; + src_addr = mystique->dwgreg.ar[3]; - for (y = 0; y < mystique->dwgreg.length; y++) { - uint8_t const *const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; - uint32_t old_src_addr = src_addr; - int16_t x = x_start; + for (y = 0; y < mystique->dwgreg.length; y++) { + uint8_t const *const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; + uint32_t old_src_addr = src_addr; + int16_t x = x_start; -// pclog(" line %03i: %08x %08x\n", y, mystique->dwgreg.ydst_lin, src_addr); - while (1) { - if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && - mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && - trans[x & 3]) { - uint32_t src, dst, old_dst; + // pclog(" line %03i: %08x %08x\n", y, mystique->dwgreg.ydst_lin, + // src_addr); + while (1) { + if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && + mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && trans[x & 3]) { + uint32_t src, dst, old_dst; - switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { - case MACCESS_PWIDTH_8:src = svga->vram[src_addr & mystique->vram_mask]; - dst = svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask]; + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_8: + src = svga->vram[src_addr & mystique->vram_mask]; + dst = svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask]; -// pclog(" %02x %02x ", src, dst); - dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running);// & DWGCTRL_BOP_MASK -// pclog("%08x %08x %i dst=%02x\n", src_addr, mystique->dwgreg.ydst_lin + x, mystique->dwgreg.sgn.scanleft, dst); + // pclog(" %02x + // %02x ", src, + // dst); + dst = bitop(src, dst, + mystique->dwgreg.dwgctrl_running); // & DWGCTRL_BOP_MASK + // pclog("%08x %08x + // %i dst=%02x\n", + // src_addr, + // mystique->dwgreg.ydst_lin + // + x, + // mystique->dwgreg.sgn.scanleft, + // dst); - svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = changeframecount; - break; + svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & + mystique->vram_mask) >> + 12] = changeframecount; + break; - case MACCESS_PWIDTH_16:src = ((uint16_t *)svga->vram)[src_addr & mystique->vram_mask_w]; - dst = ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w]; + case MACCESS_PWIDTH_16: + src = ((uint16_t *)svga->vram)[src_addr & mystique->vram_mask_w]; + dst = ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & + mystique->vram_mask_w]; -// pclog(" %02x %02x ", src, dst); - dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running);// & DWGCTRL_BOP_MASK -// pclog("%08x %08x %i dst=%02x\n", src_addr, mystique->dwgreg.ydst_lin + x, mystique->dwgreg.sgn.scanleft, dst); + // pclog(" %02x + // %02x ", src, + // dst); + dst = bitop(src, dst, + mystique->dwgreg.dwgctrl_running); // & DWGCTRL_BOP_MASK + // pclog("%08x %08x + // %i dst=%02x\n", + // src_addr, + // mystique->dwgreg.ydst_lin + // + x, + // mystique->dwgreg.sgn.scanleft, + // dst); - ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount; - break; + ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & + mystique->vram_mask_w] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & + mystique->vram_mask_w) >> + 11] = changeframecount; + break; - case MACCESS_PWIDTH_24:src = *(uint32_t *)&svga->vram[(src_addr * 3) & mystique->vram_mask]; - old_dst = *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask]; + case MACCESS_PWIDTH_24: + src = *(uint32_t *)&svga->vram[(src_addr * 3) & mystique->vram_mask]; + old_dst = *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & + mystique->vram_mask]; -// pclog(" %02x %02x ", src, old_dst); - dst = bitop(src, old_dst, mystique->dwgreg.dwgctrl_running);// & DWGCTRL_BOP_MASK -// pclog("%08x %08x %i dst=%02x\n", src_addr, mystique->dwgreg.ydst_lin + x, mystique->dwgreg.sgn.scanleft, dst); + // pclog(" %02x + // %02x ", src, + // old_dst); + dst = bitop(src, old_dst, + mystique->dwgreg.dwgctrl_running); // & DWGCTRL_BOP_MASK + // pclog("%08x %08x + // %i dst=%02x\n", + // src_addr, + // mystique->dwgreg.ydst_lin + // + x, + // mystique->dwgreg.sgn.scanleft, + // dst); - *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = (dst & 0xffffff) | (old_dst & 0xff000000); - svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = changeframecount; - break; + *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & + mystique->vram_mask] = + (dst & 0xffffff) | (old_dst & 0xff000000); + svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & + mystique->vram_mask) >> + 12] = changeframecount; + break; - case MACCESS_PWIDTH_32:src = ((uint32_t *)svga->vram)[src_addr & mystique->vram_mask_l]; - dst = ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l]; + case MACCESS_PWIDTH_32: + src = ((uint32_t *)svga->vram)[src_addr & mystique->vram_mask_l]; + dst = ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & + mystique->vram_mask_l]; -// pclog(" %02x %02x ", src, dst); - dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running);// & DWGCTRL_BOP_MASK -// pclog("%08x %08x %i dst=%02x\n", src_addr, mystique->dwgreg.ydst_lin + x, mystique->dwgreg.sgn.scanleft, dst); + // pclog(" %02x + // %02x ", src, + // dst); + dst = bitop(src, dst, + mystique->dwgreg.dwgctrl_running); // & DWGCTRL_BOP_MASK + // pclog("%08x %08x + // %i dst=%02x\n", + // src_addr, + // mystique->dwgreg.ydst_lin + // + x, + // mystique->dwgreg.sgn.scanleft, + // dst); - ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l) >> 10] = changeframecount; - break; + ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & + mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & + mystique->vram_mask_l) >> + 10] = changeframecount; + break; #ifndef RELEASE_BUILD - default:fatal("BITBLT RPL BFCOL PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); + default: + fatal("BITBLT RPL BFCOL PWIDTH %x %08x\n", + mystique->maccess_running & MACCESS_PWIDTH_MASK, + mystique->dwgreg.dwgctrl_running); #endif - } - } + } + } - if (mystique->dwgreg.dwgctrl_running & DWGCTRL_PATTERN) - src_addr = ((src_addr + x_dir) & 7) | (src_addr & ~7); - else if (src_addr == mystique->dwgreg.ar[0]) { - mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; - mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; - src_addr = mystique->dwgreg.ar[3]; - } else - src_addr += x_dir; + if (mystique->dwgreg.dwgctrl_running & DWGCTRL_PATTERN) + src_addr = ((src_addr + x_dir) & 7) | (src_addr & ~7); + else if (src_addr == mystique->dwgreg.ar[0]) { + mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; + mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; + src_addr = mystique->dwgreg.ar[3]; + } else + src_addr += x_dir; - if (x != x_end) - x += x_dir; - else - break; - } + if (x != x_end) + x += x_dir; + else + break; + } - if (mystique->dwgreg.dwgctrl_running & DWGCTRL_PATTERN) { - src_addr = old_src_addr; - if (mystique->dwgreg.sgn.sdy) - src_addr = ((src_addr - 32) & 0xe0) | (src_addr & ~0xe0); - else - src_addr = ((src_addr + 32) & 0xe0) | (src_addr & ~0xe0); - } + if (mystique->dwgreg.dwgctrl_running & DWGCTRL_PATTERN) { + src_addr = old_src_addr; + if (mystique->dwgreg.sgn.sdy) + src_addr = ((src_addr - 32) & 0xe0) | (src_addr & ~0xe0); + else + src_addr = ((src_addr + 32) & 0xe0) | (src_addr & ~0xe0); + } - if (mystique->dwgreg.sgn.sdy) - mystique->dwgreg.ydst_lin -= (mystique->dwgreg.pitch & PITCH_MASK); - else - mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); - } - break; + if (mystique->dwgreg.sgn.sdy) + mystique->dwgreg.ydst_lin -= (mystique->dwgreg.pitch & PITCH_MASK); + else + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + } + break; #ifndef RELEASE_BUILD - default:fatal("BITBLT DWGCTRL_ATYPE_RPL unknown BLTMOD %08x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK, mystique->dwgreg.dwgctrl_running); + default: + fatal("BITBLT DWGCTRL_ATYPE_RPL unknown BLTMOD %08x %08x\n", + mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK, mystique->dwgreg.dwgctrl_running); #endif - } - break; + } + break; #ifndef RELEASE_BUILD - default:fatal("Unknown BITBLT atype %03x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); + default: + fatal("Unknown BITBLT atype %03x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, + mystique->dwgreg.dwgctrl_running); #endif - } - mystique->blitter_complete_refcount++; + } + mystique->blitter_complete_refcount++; } static void blit_fbitblt(mystique_t *mystique) { - svga_t *svga = &mystique->svga; - uint32_t src_addr; - int y; - int x_dir = mystique->dwgreg.sgn.scanleft ? -1 : 1; - int16_t x_start = mystique->dwgreg.sgn.scanleft ? mystique->dwgreg.fxright : mystique->dwgreg.fxleft; - int16_t x_end = mystique->dwgreg.sgn.scanleft ? mystique->dwgreg.fxleft : mystique->dwgreg.fxright; + svga_t *svga = &mystique->svga; + uint32_t src_addr; + int y; + int x_dir = mystique->dwgreg.sgn.scanleft ? -1 : 1; + int16_t x_start = mystique->dwgreg.sgn.scanleft ? mystique->dwgreg.fxright : mystique->dwgreg.fxleft; + int16_t x_end = mystique->dwgreg.sgn.scanleft ? mystique->dwgreg.fxleft : mystique->dwgreg.fxright; -/* pclog("FBITBLT %08x:\n", mystique->dwgreg.dwgctrl_running); - pclog("ar0=%08x ar3=%08x ar5=%08x %i %i\n", mystique->dwgreg.ar[0], mystique->dwgreg.ar[3], mystique->dwgreg.ar[5], - mystique->dwgreg.ar[0]-mystique->dwgreg.ar[3], - mystique->dwgreg.fxright-mystique->dwgreg.fxleft); - pclog("fxleft=%i(%x) fxright=%i(%x) pitch=%08x\n", - mystique->dwgreg.fxleft, mystique->dwgreg.fxleft, - mystique->dwgreg.fxright, mystique->dwgreg.fxright, mystique->dwgreg.pitch);*/ + /* pclog("FBITBLT %08x:\n", mystique->dwgreg.dwgctrl_running); + pclog("ar0=%08x ar3=%08x ar5=%08x %i %i\n", mystique->dwgreg.ar[0], mystique->dwgreg.ar[3], + mystique->dwgreg.ar[5], mystique->dwgreg.ar[0]-mystique->dwgreg.ar[3], + mystique->dwgreg.fxright-mystique->dwgreg.fxleft); + pclog("fxleft=%i(%x) fxright=%i(%x) pitch=%08x\n", + mystique->dwgreg.fxleft, mystique->dwgreg.fxleft, + mystique->dwgreg.fxright, mystique->dwgreg.fxright, mystique->dwgreg.pitch);*/ - src_addr = mystique->dwgreg.ar[3]; + src_addr = mystique->dwgreg.ar[3]; - for (y = 0; y < mystique->dwgreg.length; y++) { - int16_t x = x_start; + for (y = 0; y < mystique->dwgreg.length; y++) { + int16_t x = x_start; -// pclog(" line %03i: %08x %08x %08x %x\n", y, mystique->dwgreg.ydst_lin, src_addr, src_addr-x, x); - while (1) { - if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && - mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { - uint32_t src, old_dst; + // pclog(" line %03i: %08x %08x %08x %x\n", y, mystique->dwgreg.ydst_lin, src_addr, src_addr-x, + // x); + while (1) { + if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && + mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && + mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { + uint32_t src, old_dst; - switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { - case MACCESS_PWIDTH_8:src = svga->vram[src_addr & mystique->vram_mask]; + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_8: + src = svga->vram[src_addr & mystique->vram_mask]; - svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = src; - svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = changeframecount; - break; + svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = src; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = + changeframecount; + break; - case MACCESS_PWIDTH_16:src = ((uint16_t *)svga->vram)[src_addr & mystique->vram_mask_w]; + case MACCESS_PWIDTH_16: + src = ((uint16_t *)svga->vram)[src_addr & mystique->vram_mask_w]; - ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = src; - svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount; - break; + ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = src; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = + changeframecount; + break; - case MACCESS_PWIDTH_24:src = *(uint32_t *)&svga->vram[(src_addr * 3) & mystique->vram_mask]; - old_dst = *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask]; + case MACCESS_PWIDTH_24: + src = *(uint32_t *)&svga->vram[(src_addr * 3) & mystique->vram_mask]; + old_dst = *(uint32_t *)&svga + ->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask]; - *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = (src & 0xffffff) | (old_dst & 0xff000000); - svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = changeframecount; - break; + *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = + (src & 0xffffff) | (old_dst & 0xff000000); + svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = + changeframecount; + break; - case MACCESS_PWIDTH_32:src = ((uint32_t *)svga->vram)[src_addr & mystique->vram_mask_l]; + case MACCESS_PWIDTH_32: + src = ((uint32_t *)svga->vram)[src_addr & mystique->vram_mask_l]; - ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = src; - svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l) >> 10] = changeframecount; - break; + ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = src; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l) >> 10] = + changeframecount; + break; #ifndef RELEASE_BUILD - default:fatal("BITBLT RPL BFCOL PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); + default: + fatal("BITBLT RPL BFCOL PWIDTH %x %08x\n", + mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); #endif - } - } + } + } - if (src_addr == mystique->dwgreg.ar[0]) { - mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; - mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; - src_addr = mystique->dwgreg.ar[3]; - break; - } else - src_addr += x_dir; + if (src_addr == mystique->dwgreg.ar[0]) { + mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; + mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; + src_addr = mystique->dwgreg.ar[3]; + break; + } else + src_addr += x_dir; - if (x != x_end) - x += x_dir; - else - break; - } + if (x != x_end) + x += x_dir; + else + break; + } - if (mystique->dwgreg.sgn.sdy) - mystique->dwgreg.ydst_lin -= (mystique->dwgreg.pitch & PITCH_MASK); - else - mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); - } + if (mystique->dwgreg.sgn.sdy) + mystique->dwgreg.ydst_lin -= (mystique->dwgreg.pitch & PITCH_MASK); + else + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + } - mystique->blitter_complete_refcount++; + mystique->blitter_complete_refcount++; } static void blit_iload(mystique_t *mystique) { -// if (mystique->maccess_running & MACCESS_TLUTLOAD) -// fatal("ILOAD TLUTLOAD\n"); - switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { - case DWGCTRL_ATYPE_RPL: - case DWGCTRL_ATYPE_RSTR: - case DWGCTRL_ATYPE_BLK: - switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { - case DWGCTRL_BLTMOD_BFCOL: - case DWGCTRL_BLTMOD_BMONOLEF: - case DWGCTRL_BLTMOD_BMONOWF: - case DWGCTRL_BLTMOD_BU24RGB: - case DWGCTRL_BLTMOD_BU32RGB: -// pclog("fxleft=%i fxright=%i\n", mystique->dwgreg.fxleft, mystique->dwgreg.fxright); -// pclog("ytop=%i length=%i\n", mystique->dwgreg.ytop, mystique->dwgreg.length); - mystique->dwgreg.length_cur = mystique->dwgreg.length; - mystique->dwgreg.xdst = mystique->dwgreg.fxleft; - mystique->dwgreg.iload_rem_data = 0; - mystique->dwgreg.iload_rem_count = 0; - mystique->busy = 1; - mystique->dwgreg.words = 0; - break; + // if (mystique->maccess_running & MACCESS_TLUTLOAD) + // fatal("ILOAD TLUTLOAD\n"); + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { + case DWGCTRL_ATYPE_RPL: + case DWGCTRL_ATYPE_RSTR: + case DWGCTRL_ATYPE_BLK: + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { + case DWGCTRL_BLTMOD_BFCOL: + case DWGCTRL_BLTMOD_BMONOLEF: + case DWGCTRL_BLTMOD_BMONOWF: + case DWGCTRL_BLTMOD_BU24RGB: + case DWGCTRL_BLTMOD_BU32RGB: + // pclog("fxleft=%i fxright=%i\n", mystique->dwgreg.fxleft, + // mystique->dwgreg.fxright); pclog("ytop=%i length=%i\n", mystique->dwgreg.ytop, + // mystique->dwgreg.length); + mystique->dwgreg.length_cur = mystique->dwgreg.length; + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.iload_rem_data = 0; + mystique->dwgreg.iload_rem_count = 0; + mystique->busy = 1; + mystique->dwgreg.words = 0; + break; #ifndef RELEASE_BUILD - default:fatal("ILOAD DWGCTRL_ATYPE_RPL %08x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK, mystique->dwgreg.dwgctrl_running); - break; + default: + fatal("ILOAD DWGCTRL_ATYPE_RPL %08x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK, + mystique->dwgreg.dwgctrl_running); + break; #endif - } - break; + } + break; #ifndef RELEASE_BUILD - default:fatal("Unknown ILOAD atype %03x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); + default: + fatal("Unknown ILOAD atype %03x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, + mystique->dwgreg.dwgctrl_running); #endif - } + } } static void blit_idump(mystique_t *mystique) { - switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { - case DWGCTRL_ATYPE_RPL: -// pclog("ar0=%08x ar3=%08x ar5=%08x\n", mystique->dwgreg.ar[0], mystique->dwgreg.ar[3], mystique->dwgreg.ar[5]); -// pclog("fxleft=%i fxright=%i\n", mystique->dwgreg.fxleft, mystique->dwgreg.fxright); - mystique->dwgreg.length_cur = mystique->dwgreg.length; - mystique->dwgreg.xdst = mystique->dwgreg.fxleft; - mystique->dwgreg.src_addr = mystique->dwgreg.ar[3]; - mystique->dwgreg.words = 0; - mystique->dwgreg.iload_rem_count = 0; - mystique->dwgreg.iload_rem_data = 0; - mystique->dwgreg.idump_end_of_line = 0; - mystique->busy = 1; - break; + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { + case DWGCTRL_ATYPE_RPL: + // pclog("ar0=%08x ar3=%08x ar5=%08x\n", mystique->dwgreg.ar[0], mystique->dwgreg.ar[3], + // mystique->dwgreg.ar[5]); pclog("fxleft=%i fxright=%i\n", mystique->dwgreg.fxleft, + // mystique->dwgreg.fxright); + mystique->dwgreg.length_cur = mystique->dwgreg.length; + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.src_addr = mystique->dwgreg.ar[3]; + mystique->dwgreg.words = 0; + mystique->dwgreg.iload_rem_count = 0; + mystique->dwgreg.iload_rem_data = 0; + mystique->dwgreg.idump_end_of_line = 0; + mystique->busy = 1; + break; #ifndef RELEASE_BUILD - default:fatal("Unknown IDUMP atype %03x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); + default: + fatal("Unknown IDUMP atype %03x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, + mystique->dwgreg.dwgctrl_running); #endif - } + } } static void blit_iload_scale(mystique_t *mystique) { - switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { - case DWGCTRL_ATYPE_RPL: - switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { - case DWGCTRL_BLTMOD_BUYUV: -/* pclog("fxleft=%i fxright=%i\n", mystique->dwgreg.fxleft, mystique->dwgreg.fxright); - pclog("ytop=%i length=%i\n", mystique->dwgreg.ytop, mystique->dwgreg.length); - pclog("ar0=%08x\n", mystique->dwgreg.ar[0]); - pclog("ar2=%08x\n", mystique->dwgreg.ar[2]); - pclog("ar3=%08x\n", mystique->dwgreg.ar[3]); - pclog("ar5=%08x\n", mystique->dwgreg.ar[5]); - pclog("ar6=%08x\n", mystique->dwgreg.ar[6]);*/ - mystique->dwgreg.length_cur = mystique->dwgreg.length; - mystique->dwgreg.xdst = mystique->dwgreg.fxleft; - mystique->dwgreg.iload_rem_data = 0; - mystique->dwgreg.iload_rem_count = 0; - mystique->busy = 1; - mystique->dwgreg.words = 0; - break; + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { + case DWGCTRL_ATYPE_RPL: + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { + case DWGCTRL_BLTMOD_BUYUV: + /* pclog("fxleft=%i fxright=%i\n", mystique->dwgreg.fxleft, + mystique->dwgreg.fxright); pclog("ytop=%i length=%i\n", mystique->dwgreg.ytop, + mystique->dwgreg.length); pclog("ar0=%08x\n", mystique->dwgreg.ar[0]); pclog("ar2=%08x\n", + mystique->dwgreg.ar[2]); pclog("ar3=%08x\n", mystique->dwgreg.ar[3]); pclog("ar5=%08x\n", + mystique->dwgreg.ar[5]); pclog("ar6=%08x\n", mystique->dwgreg.ar[6]);*/ + mystique->dwgreg.length_cur = mystique->dwgreg.length; + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.iload_rem_data = 0; + mystique->dwgreg.iload_rem_count = 0; + mystique->busy = 1; + mystique->dwgreg.words = 0; + break; #ifndef RELEASE_BUILD - default:fatal("ILOAD_SCALE DWGCTRL_ATYPE_RPL %08x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK, mystique->dwgreg.dwgctrl_running); - break; + default: + fatal("ILOAD_SCALE DWGCTRL_ATYPE_RPL %08x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK, + mystique->dwgreg.dwgctrl_running); + break; #endif - } - break; + } + break; #ifndef RELEASE_BUILD - default:fatal("Unknown ILOAD_SCALE atype %03x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); + default: + fatal("Unknown ILOAD_SCALE atype %03x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, + mystique->dwgreg.dwgctrl_running); #endif - } + } } static void blit_iload_high(mystique_t *mystique) { - switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { - case DWGCTRL_ATYPE_RPL: - switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { - case DWGCTRL_BLTMOD_BUYUV: -/* pclog("fxleft=%i fxright=%i\n", mystique->dwgreg.fxleft, mystique->dwgreg.fxright); - pclog("ytop=%i length=%i\n", mystique->dwgreg.ytop, mystique->dwgreg.length); - pclog("ar0=%08x\n", mystique->dwgreg.ar[0]); - pclog("ar2=%08x\n", mystique->dwgreg.ar[2]); - pclog("ar3=%08x\n", mystique->dwgreg.ar[3]); - pclog("ar5=%08x\n", mystique->dwgreg.ar[5]); - pclog("ar6=%08x\n", mystique->dwgreg.ar[6]);*/ - mystique->dwgreg.length_cur = mystique->dwgreg.length; - mystique->dwgreg.xdst = mystique->dwgreg.fxleft; - mystique->dwgreg.iload_rem_data = 0; - mystique->dwgreg.iload_rem_count = 0; - mystique->busy = 1; - mystique->dwgreg.words = 0; - break; + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { + case DWGCTRL_ATYPE_RPL: + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { + case DWGCTRL_BLTMOD_BUYUV: + /* pclog("fxleft=%i fxright=%i\n", mystique->dwgreg.fxleft, + mystique->dwgreg.fxright); pclog("ytop=%i length=%i\n", mystique->dwgreg.ytop, + mystique->dwgreg.length); pclog("ar0=%08x\n", mystique->dwgreg.ar[0]); pclog("ar2=%08x\n", + mystique->dwgreg.ar[2]); pclog("ar3=%08x\n", mystique->dwgreg.ar[3]); pclog("ar5=%08x\n", + mystique->dwgreg.ar[5]); pclog("ar6=%08x\n", mystique->dwgreg.ar[6]);*/ + mystique->dwgreg.length_cur = mystique->dwgreg.length; + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.iload_rem_data = 0; + mystique->dwgreg.iload_rem_count = 0; + mystique->busy = 1; + mystique->dwgreg.words = 0; + break; #ifndef RELEASE_BUILD - default:fatal("ILOAD_HIGH DWGCTRL_ATYPE_RPL %08x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK, mystique->dwgreg.dwgctrl_running); - break; + default: + fatal("ILOAD_HIGH DWGCTRL_ATYPE_RPL %08x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK, + mystique->dwgreg.dwgctrl_running); + break; #endif - } - break; + } + break; #ifndef RELEASE_BUILD - default:fatal("Unknown ILOAD_HIGH atype %03x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); + default: + fatal("Unknown ILOAD_HIGH atype %03x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, + mystique->dwgreg.dwgctrl_running); #endif - } + } } static void blit_iload_highv(mystique_t *mystique) { - switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { - case DWGCTRL_ATYPE_RPL: - switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { - case DWGCTRL_BLTMOD_BUYUV: -/* pclog("fxleft=%i fxright=%i\n", mystique->dwgreg.fxleft, mystique->dwgreg.fxright); - pclog("ytop=%i length=%i\n", mystique->dwgreg.ytop, mystique->dwgreg.length); - pclog("ar0=%08x\n", mystique->dwgreg.ar[0]); - pclog("ar2=%08x\n", mystique->dwgreg.ar[2]); - pclog("ar3=%08x\n", mystique->dwgreg.ar[3]); - pclog("ar5=%08x\n", mystique->dwgreg.ar[5]); - pclog("ar6=%08x\n", mystique->dwgreg.ar[6]);*/ - mystique->dwgreg.length_cur = mystique->dwgreg.length; - mystique->dwgreg.xdst = mystique->dwgreg.fxleft; - mystique->dwgreg.iload_rem_data = 0; - mystique->dwgreg.iload_rem_count = 0; - mystique->busy = 1; - mystique->dwgreg.words = 0; - mystique->dwgreg.highv_line = 0; - mystique->dwgreg.lastpix_r = 0; - mystique->dwgreg.lastpix_g = 0; - mystique->dwgreg.lastpix_b = 0; - break; + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { + case DWGCTRL_ATYPE_RPL: + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { + case DWGCTRL_BLTMOD_BUYUV: + /* pclog("fxleft=%i fxright=%i\n", mystique->dwgreg.fxleft, + mystique->dwgreg.fxright); pclog("ytop=%i length=%i\n", mystique->dwgreg.ytop, + mystique->dwgreg.length); pclog("ar0=%08x\n", mystique->dwgreg.ar[0]); pclog("ar2=%08x\n", + mystique->dwgreg.ar[2]); pclog("ar3=%08x\n", mystique->dwgreg.ar[3]); pclog("ar5=%08x\n", + mystique->dwgreg.ar[5]); pclog("ar6=%08x\n", mystique->dwgreg.ar[6]);*/ + mystique->dwgreg.length_cur = mystique->dwgreg.length; + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.iload_rem_data = 0; + mystique->dwgreg.iload_rem_count = 0; + mystique->busy = 1; + mystique->dwgreg.words = 0; + mystique->dwgreg.highv_line = 0; + mystique->dwgreg.lastpix_r = 0; + mystique->dwgreg.lastpix_g = 0; + mystique->dwgreg.lastpix_b = 0; + break; #ifndef RELEASE_BUILD - default:fatal("ILOAD_HIGHV DWGCTRL_ATYPE_RPL %08x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK, mystique->dwgreg.dwgctrl_running); - break; + default: + fatal("ILOAD_HIGHV DWGCTRL_ATYPE_RPL %08x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK, + mystique->dwgreg.dwgctrl_running); + break; #endif - } - break; + } + break; #ifndef RELEASE_BUILD - default:fatal("Unknown ILOAD_HIGHV atype %03x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); + default: + fatal("Unknown ILOAD_HIGHV atype %03x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, + mystique->dwgreg.dwgctrl_running); #endif - } + } } static void mystique_start_blit(mystique_t *mystique) { - uint64_t start_time = timer_read(); - uint64_t end_time; + uint64_t start_time = timer_read(); + uint64_t end_time; - mystique->dwgreg.dwgctrl_running = mystique->dwgreg.dwgctrl; - mystique->maccess_running = mystique->maccess; -// pclog("start_blit %08x length=%i fxleft=%i fxright=%i %02x %i %i %i ylin=%08x ytop=%08x ybot=%08x\n", mystique->dwgreg.dwgctrl_running, mystique->dwgreg.length, mystique->dwgreg.fxleft, mystique->dwgreg.fxright, mystique->svga.vram[0x5c056], mystique->blitter_submit_refcount, mystique->blitter_submit_dma_refcount, mystique->blitter_complete_refcount, mystique->dwgreg.ydst_lin, mystique->dwgreg.ytop, mystique->dwgreg.ybot); + mystique->dwgreg.dwgctrl_running = mystique->dwgreg.dwgctrl; + mystique->maccess_running = mystique->maccess; +// pclog("start_blit %08x length=%i fxleft=%i fxright=%i %02x %i %i %i ylin=%08x ytop=%08x ybot=%08x\n", +// mystique->dwgreg.dwgctrl_running, mystique->dwgreg.length, mystique->dwgreg.fxleft, mystique->dwgreg.fxright, +// mystique->svga.vram[0x5c056], mystique->blitter_submit_refcount, mystique->blitter_submit_dma_refcount, +// mystique->blitter_complete_refcount, mystique->dwgreg.ydst_lin, mystique->dwgreg.ytop, mystique->dwgreg.ybot); #ifndef RELEASE_BUILD - if (mystique->busy) - fatal("mystique_start_blit: mystique->busy!\n"); + if (mystique->busy) + fatal("mystique_start_blit: mystique->busy!\n"); #endif - switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) { - case DWGCTRL_OPCODE_LINE_OPEN:blit_line(mystique, 0); - break; + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) { + case DWGCTRL_OPCODE_LINE_OPEN: + blit_line(mystique, 0); + break; - case DWGCTRL_OPCODE_LINE_CLOSE:blit_line(mystique, 0); - break; + case DWGCTRL_OPCODE_LINE_CLOSE: + blit_line(mystique, 0); + break; - case DWGCTRL_OPCODE_AUTOLINE_OPEN:blit_autoline(mystique, 0); - break; + case DWGCTRL_OPCODE_AUTOLINE_OPEN: + blit_autoline(mystique, 0); + break; - case DWGCTRL_OPCODE_AUTOLINE_CLOSE:blit_autoline(mystique, 1); - break; + case DWGCTRL_OPCODE_AUTOLINE_CLOSE: + blit_autoline(mystique, 1); + break; - case DWGCTRL_OPCODE_TRAP:blit_trap(mystique); - break; + case DWGCTRL_OPCODE_TRAP: + blit_trap(mystique); + break; - case DWGCTRL_OPCODE_TEXTURE_TRAP:blit_texture_trap(mystique); - break; + case DWGCTRL_OPCODE_TEXTURE_TRAP: + blit_texture_trap(mystique); + break; - case DWGCTRL_OPCODE_ILOAD_HIGH:blit_iload_high(mystique); - break; + case DWGCTRL_OPCODE_ILOAD_HIGH: + blit_iload_high(mystique); + break; - case DWGCTRL_OPCODE_BITBLT:blit_bitblt(mystique); - break; + case DWGCTRL_OPCODE_BITBLT: + blit_bitblt(mystique); + break; - case DWGCTRL_OPCODE_FBITBLT:blit_fbitblt(mystique); - break; + case DWGCTRL_OPCODE_FBITBLT: + blit_fbitblt(mystique); + break; - case DWGCTRL_OPCODE_ILOAD:blit_iload(mystique); - break; + case DWGCTRL_OPCODE_ILOAD: + blit_iload(mystique); + break; - case DWGCTRL_OPCODE_IDUMP:blit_idump(mystique); - break; + case DWGCTRL_OPCODE_IDUMP: + blit_idump(mystique); + break; - case DWGCTRL_OPCODE_ILOAD_SCALE:blit_iload_scale(mystique); - break; + case DWGCTRL_OPCODE_ILOAD_SCALE: + blit_iload_scale(mystique); + break; - case DWGCTRL_OPCODE_ILOAD_HIGHV:blit_iload_highv(mystique); - break; + case DWGCTRL_OPCODE_ILOAD_HIGHV: + blit_iload_highv(mystique); + break; #ifndef RELEASE_BUILD - default:fatal("mystique_start_blit: unknown blit %08x\n", mystique->dwgreg.dwgctrl_running); + default: + fatal("mystique_start_blit: unknown blit %08x\n", mystique->dwgreg.dwgctrl_running); #endif - } -// pclog("blit done\n"); + } + // pclog("blit done\n"); - end_time = timer_read(); - mystique->blitter_time += end_time - start_time; + end_time = timer_read(); + mystique->blitter_time += end_time - start_time; } static void mystique_hwcursor_draw(svga_t *svga, int displine) { - mystique_t *mystique = (mystique_t *)svga->p; + mystique_t *mystique = (mystique_t *)svga->p; - if (mystique->type == MGA_2064W) { - tvp3026_hwcursor_draw(&mystique->tvp3026, svga, displine); - } else { - int x; - uint64_t dat[2]; - int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; + if (mystique->type == MGA_2064W) { + tvp3026_hwcursor_draw(&mystique->tvp3026, svga, displine); + } else { + int x; + uint64_t dat[2]; + int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; - dat[0] = *(uint64_t *)(&svga->vram[svga->hwcursor_latch.addr]); - dat[1] = *(uint64_t *)(&svga->vram[svga->hwcursor_latch.addr + 8]); - svga->hwcursor_latch.addr += 16; - switch (mystique->xcurctrl & XCURCTRL_CURMODE_MASK) { - case XCURCTRL_CURMODE_XGA: - for (x = 0; x < 64; x++) { - if (!(dat[1] & (1ull << 63))) - ((uint32_t *)buffer32->line[displine])[offset + 32] = (dat[0] & (1ull << 63)) ? mystique->cursor.col[1] : mystique->cursor.col[0]; - else if (dat[0] & (1ull << 63)) - ((uint32_t *)buffer32->line[displine])[offset + 32] ^= 0xffffff; + dat[0] = *(uint64_t *)(&svga->vram[svga->hwcursor_latch.addr]); + dat[1] = *(uint64_t *)(&svga->vram[svga->hwcursor_latch.addr + 8]); + svga->hwcursor_latch.addr += 16; + switch (mystique->xcurctrl & XCURCTRL_CURMODE_MASK) { + case XCURCTRL_CURMODE_XGA: + for (x = 0; x < 64; x++) { + if (!(dat[1] & (1ull << 63))) + ((uint32_t *)buffer32->line[displine])[offset + 32] = + (dat[0] & (1ull << 63)) ? mystique->cursor.col[1] : mystique->cursor.col[0]; + else if (dat[0] & (1ull << 63)) + ((uint32_t *)buffer32->line[displine])[offset + 32] ^= 0xffffff; - offset++; - dat[0] <<= 1; - dat[1] <<= 1; - } - break; - } - } + offset++; + dat[0] <<= 1; + dat[1] <<= 1; + } + break; + } + } } static uint8_t mystique_pci_read(int func, int addr, void *p) { - mystique_t *mystique = (mystique_t *)p; + mystique_t *mystique = (mystique_t *)p; -// pclog("mystique PCI read %08X\n", addr); - switch (addr) { - case 0x00:return 0x2b; /*Matrox*/ - case 0x01:return 0x10; + // pclog("mystique PCI read %08X\n", addr); + switch (addr) { + case 0x00: + return 0x2b; /*Matrox*/ + case 0x01: + return 0x10; - case 0x02:return (mystique->type == MGA_2064W) ? 0x19 : 0x1a; /*MGA-1064SG*/ - case 0x03:return 0x05; + case 0x02: + return (mystique->type == MGA_2064W) ? 0x19 : 0x1a; /*MGA-1064SG*/ + case 0x03: + return 0x05; - case PCI_REG_COMMAND:return mystique->pci_regs[PCI_REG_COMMAND]; /*Respond to IO and memory accesses*/ + case PCI_REG_COMMAND: + return mystique->pci_regs[PCI_REG_COMMAND]; /*Respond to IO and memory accesses*/ - case 0x07:return 0 << 1; /*Fast DEVSEL timing*/ + case 0x07: + return 0 << 1; /*Fast DEVSEL timing*/ - case 0x08:return 0; /*Revision ID*/ - case 0x09:return 0; /*Programming interface*/ + case 0x08: + return 0; /*Revision ID*/ + case 0x09: + return 0; /*Programming interface*/ - case 0x0a:return 0x00; /*Supports VGA interface*/ - case 0x0b:return 0x03; + case 0x0a: + return 0x00; /*Supports VGA interface*/ + case 0x0b: + return 0x03; - case 0x10:return 0x00; /*Control aperture*/ - case 0x11:return (mystique->ctrl_base >> 8) & 0xc0; - case 0x12:return mystique->ctrl_base >> 16; - case 0x13:return mystique->ctrl_base >> 24; + case 0x10: + return 0x00; /*Control aperture*/ + case 0x11: + return (mystique->ctrl_base >> 8) & 0xc0; + case 0x12: + return mystique->ctrl_base >> 16; + case 0x13: + return mystique->ctrl_base >> 24; - case 0x14:return 0x00; /*Linear frame buffer*/ - case 0x16:return (mystique->lfb_base >> 16) & 0x80; - case 0x17:return mystique->lfb_base >> 24; + case 0x14: + return 0x00; /*Linear frame buffer*/ + case 0x16: + return (mystique->lfb_base >> 16) & 0x80; + case 0x17: + return mystique->lfb_base >> 24; - case 0x18:return 0x00; /*Pseudo-DMA (ILOAD)*/ - case 0x1a:return (mystique->iload_base >> 16) & 0x80; - case 0x1b:return mystique->iload_base >> 24; + case 0x18: + return 0x00; /*Pseudo-DMA (ILOAD)*/ + case 0x1a: + return (mystique->iload_base >> 16) & 0x80; + case 0x1b: + return mystique->iload_base >> 24; - case 0x30:return mystique->pci_regs[0x30] & 0x01; /*BIOS ROM address*/ - case 0x31:return 0x00; - case 0x32:return mystique->pci_regs[0x32]; - case 0x33:return mystique->pci_regs[0x33]; + case 0x30: + return mystique->pci_regs[0x30] & 0x01; /*BIOS ROM address*/ + case 0x31: + return 0x00; + case 0x32: + return mystique->pci_regs[0x32]; + case 0x33: + return mystique->pci_regs[0x33]; - case 0x3c:return mystique->int_line; - case 0x3d:return PCI_INTA; + case 0x3c: + return mystique->int_line; + case 0x3d: + return PCI_INTA; - case 0x40:return mystique->pci_regs[0x40]; - case 0x41:return mystique->pci_regs[0x41]; - case 0x42:return mystique->pci_regs[0x42]; - case 0x43:return mystique->pci_regs[0x43]; + case 0x40: + return mystique->pci_regs[0x40]; + case 0x41: + return mystique->pci_regs[0x41]; + case 0x42: + return mystique->pci_regs[0x42]; + case 0x43: + return mystique->pci_regs[0x43]; - case 0x44:return mystique->pci_regs[0x44]; - case 0x45:return mystique->pci_regs[0x45]; + case 0x44: + return mystique->pci_regs[0x44]; + case 0x45: + return mystique->pci_regs[0x45]; - case 0x48: - case 0x49: - case 0x4a: - case 0x4b: - addr = (mystique->pci_regs[0x44] & 0xfc) | - ((mystique->pci_regs[0x45] & 0x3f) << 8) | - (addr & 3); - return mystique_ctrl_read_b(addr, mystique); - } - return 0; + case 0x48: + case 0x49: + case 0x4a: + case 0x4b: + addr = (mystique->pci_regs[0x44] & 0xfc) | ((mystique->pci_regs[0x45] & 0x3f) << 8) | (addr & 3); + return mystique_ctrl_read_b(addr, mystique); + } + return 0; } static void mystique_pci_write(int func, int addr, uint8_t val, void *p) { - mystique_t *mystique = (mystique_t *)p; + mystique_t *mystique = (mystique_t *)p; -// pclog("mystique_pci_write: func=%i addr=%02x val=%02x\n", func, addr, val); - switch (addr) { - case PCI_REG_COMMAND:mystique->pci_regs[PCI_REG_COMMAND] = val & 0x23; - mystique_recalc_mapping(mystique); - break; + // pclog("mystique_pci_write: func=%i addr=%02x val=%02x\n", func, addr, val); + switch (addr) { + case PCI_REG_COMMAND: + mystique->pci_regs[PCI_REG_COMMAND] = val & 0x23; + mystique_recalc_mapping(mystique); + break; - case 0x11:mystique->ctrl_base = (mystique->ctrl_base & 0xffff0000) | ((val & 0xc0) << 8); - mystique_recalc_mapping(mystique); - break; - case 0x12:mystique->ctrl_base = (mystique->ctrl_base & 0xff00c000) | (val << 16); - mystique_recalc_mapping(mystique); - break; - case 0x13:mystique->ctrl_base = (mystique->ctrl_base & 0x00ffc000) | (val << 24); - mystique_recalc_mapping(mystique); - break; + case 0x11: + mystique->ctrl_base = (mystique->ctrl_base & 0xffff0000) | ((val & 0xc0) << 8); + mystique_recalc_mapping(mystique); + break; + case 0x12: + mystique->ctrl_base = (mystique->ctrl_base & 0xff00c000) | (val << 16); + mystique_recalc_mapping(mystique); + break; + case 0x13: + mystique->ctrl_base = (mystique->ctrl_base & 0x00ffc000) | (val << 24); + mystique_recalc_mapping(mystique); + break; - case 0x16:mystique->lfb_base = (mystique->lfb_base & 0xff000000) | ((val & 0x80) << 16); - mystique_recalc_mapping(mystique); - break; - case 0x17:mystique->lfb_base = (mystique->lfb_base & 0x00800000) | (val << 24); - mystique_recalc_mapping(mystique); - break; + case 0x16: + mystique->lfb_base = (mystique->lfb_base & 0xff000000) | ((val & 0x80) << 16); + mystique_recalc_mapping(mystique); + break; + case 0x17: + mystique->lfb_base = (mystique->lfb_base & 0x00800000) | (val << 24); + mystique_recalc_mapping(mystique); + break; - case 0x1a:mystique->iload_base = (mystique->iload_base & 0xff000000) | ((val & 0x80) << 16); - mystique_recalc_mapping(mystique); - break; - case 0x1b:mystique->iload_base = (mystique->iload_base & 0x00800000) | (val << 24); - mystique_recalc_mapping(mystique); - break; + case 0x1a: + mystique->iload_base = (mystique->iload_base & 0xff000000) | ((val & 0x80) << 16); + mystique_recalc_mapping(mystique); + break; + case 0x1b: + mystique->iload_base = (mystique->iload_base & 0x00800000) | (val << 24); + mystique_recalc_mapping(mystique); + break; - case 0x30: - case 0x32: - case 0x33:mystique->pci_regs[addr] = val; - if (mystique->pci_regs[0x30] & 0x01) { - uint32_t addr = (mystique->pci_regs[0x32] << 16) | (mystique->pci_regs[0x33] << 24); - mem_mapping_set_addr(&mystique->bios_rom.mapping, addr, 0x8000); - } else - mem_mapping_disable(&mystique->bios_rom.mapping); - return; + case 0x30: + case 0x32: + case 0x33: + mystique->pci_regs[addr] = val; + if (mystique->pci_regs[0x30] & 0x01) { + uint32_t addr = (mystique->pci_regs[0x32] << 16) | (mystique->pci_regs[0x33] << 24); + mem_mapping_set_addr(&mystique->bios_rom.mapping, addr, 0x8000); + } else + mem_mapping_disable(&mystique->bios_rom.mapping); + return; - case 0x3c:mystique->int_line = val; - return; + case 0x3c: + mystique->int_line = val; + return; - case 0x40: - case 0x41: - case 0x42: - case 0x43:mystique->pci_regs[addr] = val; - break; + case 0x40: + case 0x41: + case 0x42: + case 0x43: + mystique->pci_regs[addr] = val; + break; - case 0x4c: - case 0x4d: - case 0x4e: - case 0x4f:mystique->pci_regs[addr - 0x20] = val; - break; + case 0x4c: + case 0x4d: + case 0x4e: + case 0x4f: + mystique->pci_regs[addr - 0x20] = val; + break; - case 0x44: - case 0x45:mystique->pci_regs[addr] = val; - break; + case 0x44: + case 0x45: + mystique->pci_regs[addr] = val; + break; - case 0x48: - case 0x49: - case 0x4a: - case 0x4b: - addr = (mystique->pci_regs[0x44] & 0xfc) | - ((mystique->pci_regs[0x45] & 0x3f) << 8) | - (addr & 3); - mystique_ctrl_write_b(addr, val, mystique); - break; - } + case 0x48: + case 0x49: + case 0x4a: + case 0x4b: + addr = (mystique->pci_regs[0x44] & 0xfc) | ((mystique->pci_regs[0x45] & 0x3f) << 8) | (addr & 3); + mystique_ctrl_write_b(addr, val, mystique); + break; + } } void *mga_init_common(char *bios_fn, int type) { - int c; - mystique_t *mystique = malloc(sizeof(mystique_t)); - memset(mystique, 0, sizeof(mystique_t)); + int c; + mystique_t *mystique = malloc(sizeof(mystique_t)); + memset(mystique, 0, sizeof(mystique_t)); - rom_init(&mystique->bios_rom, bios_fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&mystique->bios_rom, bios_fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - mystique->type = type; - mystique->vram_size = device_get_config_int("memory"); - mystique->vram_mask = (mystique->vram_size << 20) - 1; - mystique->vram_mask_w = mystique->vram_mask >> 1; - mystique->vram_mask_l = mystique->vram_mask >> 2; + mystique->type = type; + mystique->vram_size = device_get_config_int("memory"); + mystique->vram_mask = (mystique->vram_size << 20) - 1; + mystique->vram_mask_w = mystique->vram_mask >> 1; + mystique->vram_mask_l = mystique->vram_mask >> 2; - svga_init(&mystique->svga, mystique, mystique->vram_size << 20, - mystique_recalctimings, - mystique_in, mystique_out, - mystique_hwcursor_draw, - NULL); + svga_init(&mystique->svga, mystique, mystique->vram_size << 20, mystique_recalctimings, mystique_in, mystique_out, + mystique_hwcursor_draw, NULL); - io_sethandler(0x03c0, 0x0020, mystique_in, NULL, NULL, mystique_out, NULL, NULL, mystique); - mem_mapping_add(&mystique->ctrl_mapping, 0, 0, - mystique_ctrl_read_b, NULL, mystique_ctrl_read_l, - mystique_ctrl_write_b, NULL, mystique_ctrl_write_l, - NULL, 0, mystique); - mem_mapping_add(&mystique->lfb_mapping, 0, 0, - mystique_readb_linear, mystique_readw_linear, mystique_readl_linear, - mystique_writeb_linear, mystique_writew_linear, mystique_writel_linear, - NULL, 0, mystique); - mem_mapping_add(&mystique->iload_mapping, 0, 0, - mystique_iload_read_b, NULL, mystique_iload_read_l, - mystique_iload_write_b, NULL, mystique_iload_write_l, - NULL, 0, mystique); + io_sethandler(0x03c0, 0x0020, mystique_in, NULL, NULL, mystique_out, NULL, NULL, mystique); + mem_mapping_add(&mystique->ctrl_mapping, 0, 0, mystique_ctrl_read_b, NULL, mystique_ctrl_read_l, mystique_ctrl_write_b, + NULL, mystique_ctrl_write_l, NULL, 0, mystique); + mem_mapping_add(&mystique->lfb_mapping, 0, 0, mystique_readb_linear, mystique_readw_linear, mystique_readl_linear, + mystique_writeb_linear, mystique_writew_linear, mystique_writel_linear, NULL, 0, mystique); + mem_mapping_add(&mystique->iload_mapping, 0, 0, mystique_iload_read_b, NULL, mystique_iload_read_l, + mystique_iload_write_b, NULL, mystique_iload_write_l, NULL, 0, mystique); - mystique->card = pci_add(mystique_pci_read, mystique_pci_write, mystique); - mystique->pci_regs[0x2c] = mystique->bios_rom.rom[0x7ff8]; - mystique->pci_regs[0x2d] = mystique->bios_rom.rom[0x7ff8]; - mystique->pci_regs[0x2e] = mystique->bios_rom.rom[0x7ff8]; - mystique->pci_regs[0x2f] = mystique->bios_rom.rom[0x7ff8]; + mystique->card = pci_add(mystique_pci_read, mystique_pci_write, mystique); + mystique->pci_regs[0x2c] = mystique->bios_rom.rom[0x7ff8]; + mystique->pci_regs[0x2d] = mystique->bios_rom.rom[0x7ff8]; + mystique->pci_regs[0x2e] = mystique->bios_rom.rom[0x7ff8]; + mystique->pci_regs[0x2f] = mystique->bios_rom.rom[0x7ff8]; - mystique->svga.miscout = 1; - mystique->pci_regs[0x41] = 0x01; /*vgaboot=1*/ + mystique->svga.miscout = 1; + mystique->pci_regs[0x41] = 0x01; /*vgaboot=1*/ -// timer_add(&mystique->dma.timer, dma_callback, mystique, 1); + // timer_add(&mystique->dma.timer, dma_callback, mystique, 1); - for (c = 0; c < 256; c++) { - dither5[c][0][0] = c >> 3; - dither5[c][1][1] = (c + 2) >> 3; - dither5[c][1][0] = (c + 4) >> 3; - dither5[c][0][1] = (c + 6) >> 3; + for (c = 0; c < 256; c++) { + dither5[c][0][0] = c >> 3; + dither5[c][1][1] = (c + 2) >> 3; + dither5[c][1][0] = (c + 4) >> 3; + dither5[c][0][1] = (c + 6) >> 3; - if (dither5[c][1][1] > 31) - dither5[c][1][1] = 31; - if (dither5[c][1][0] > 31) - dither5[c][1][0] = 31; - if (dither5[c][0][1] > 31) - dither5[c][0][1] = 31; + if (dither5[c][1][1] > 31) + dither5[c][1][1] = 31; + if (dither5[c][1][0] > 31) + dither5[c][1][0] = 31; + if (dither5[c][0][1] > 31) + dither5[c][0][1] = 31; - dither6[c][0][0] = c >> 2; - dither6[c][1][1] = (c + 1) >> 2; - dither6[c][1][0] = (c + 2) >> 2; - dither6[c][0][1] = (c + 3) >> 2; + dither6[c][0][0] = c >> 2; + dither6[c][1][1] = (c + 1) >> 2; + dither6[c][1][0] = (c + 2) >> 2; + dither6[c][0][1] = (c + 3) >> 2; - if (dither6[c][1][1] > 63) - dither6[c][1][1] = 63; - if (dither6[c][1][0] > 63) - dither6[c][1][0] = 63; - if (dither6[c][0][1] > 63) - dither6[c][0][1] = 63; - } + if (dither6[c][1][1] > 63) + dither6[c][1][1] = 63; + if (dither6[c][1][0] > 63) + dither6[c][1][0] = 63; + if (dither6[c][0][1] > 63) + dither6[c][0][1] = 63; + } - mystique->wake_fifo_thread = thread_create_event(); - mystique->fifo_not_full_event = thread_create_event(); - mystique->fifo_thread = thread_create(fifo_thread, mystique); - mystique->dma.lock = thread_create_mutex(); + mystique->wake_fifo_thread = thread_create_event(); + mystique->fifo_not_full_event = thread_create_event(); + mystique->fifo_thread = thread_create(fifo_thread, mystique); + mystique->dma.lock = thread_create_mutex(); - timer_add(&mystique->wake_timer, mystique_wake_timer, (void *)mystique, 0); - timer_add(&mystique->softrap_pending_timer, mystique_softrap_pending_timer, (void *)mystique, 1); + timer_add(&mystique->wake_timer, mystique_wake_timer, (void *)mystique, 0); + timer_add(&mystique->softrap_pending_timer, mystique_softrap_pending_timer, (void *)mystique, 1); - mystique->status = STATUS_ENDPRDMASTS; + mystique->status = STATUS_ENDPRDMASTS; - mystique->svga.vsync_callback = mystique_vsync_callback; + mystique->svga.vsync_callback = mystique_vsync_callback; - return mystique; + return mystique; } void *millennium_init() { - mystique_t *mystique = mga_init_common("matroxisstormr2.BIN", MGA_2064W); + mystique_t *mystique = mga_init_common("matroxisstormr2.BIN", MGA_2064W); - tvp3026_init(&mystique->tvp3026); - tvp3026_set_cursor_enable(&mystique->tvp3026, &mystique->svga, 1); + tvp3026_init(&mystique->tvp3026); + tvp3026_set_cursor_enable(&mystique->tvp3026, &mystique->svga, 1); - return mystique; + return mystique; } -void *mystique_init() { - return mga_init_common("MYSTIQUE.VBI", MGA_1064SG); -} +void *mystique_init() { return mga_init_common("MYSTIQUE.VBI", MGA_1064SG); } -static int millennium_available() { - return rom_present("matroxisstormr2.BIN"); -} +static int millennium_available() { return rom_present("matroxisstormr2.BIN"); } -static int mystique_available() { - return rom_present("MYSTIQUE.VBI"); -} +static int mystique_available() { return rom_present("MYSTIQUE.VBI"); } static void mystique_close(void *p) { - mystique_t *mystique = (mystique_t *)p; + mystique_t *mystique = (mystique_t *)p; - thread_kill(mystique->fifo_thread); - thread_destroy_event(mystique->wake_fifo_thread); - thread_destroy_event(mystique->fifo_not_full_event); - thread_destroy_mutex(mystique->dma.lock); + thread_kill(mystique->fifo_thread); + thread_destroy_event(mystique->wake_fifo_thread); + thread_destroy_event(mystique->fifo_not_full_event); + thread_destroy_mutex(mystique->dma.lock); - svga_close(&mystique->svga); + svga_close(&mystique->svga); - free(mystique); + free(mystique); } static void mystique_speed_changed(void *p) { - mystique_t *mystique = (mystique_t *)p; + mystique_t *mystique = (mystique_t *)p; - svga_recalctimings(&mystique->svga); + svga_recalctimings(&mystique->svga); } static void mystique_force_redraw(void *p) { - mystique_t *mystique = (mystique_t *)p; + mystique_t *mystique = (mystique_t *)p; - mystique->svga.fullchange = changeframecount; + mystique->svga.fullchange = changeframecount; } static void mystique_add_status_info(char *s, int max_len, void *p) { - mystique_t *mystique = (mystique_t *)p; - char temps[256]; - uint64_t new_time = timer_read(); - uint64_t status_diff = new_time - mystique->status_time; - mystique->status_time = new_time; + mystique_t *mystique = (mystique_t *)p; + char temps[256]; + uint64_t new_time = timer_read(); + uint64_t status_diff = new_time - mystique->status_time; + mystique->status_time = new_time; - if (!status_diff) - status_diff = 1; + if (!status_diff) + status_diff = 1; - svga_add_status_info(s, max_len, &mystique->svga); - sprintf(temps, "In %s mode\n%f Mpixels/sec\n%f ktraps/sec\n%f%% CPU\n%f%% CPU (real)\n\n", - (mystique->crtcext_regs[3] & CRTCX_R3_MGAMODE) ? "MGA" : "SVGA", - (double)mystique->pixel_count / 1000000.0, - (double)mystique->trap_count / 1000.0, - ((double)mystique->blitter_time * 100.0) / timer_freq, - ((double)mystique->blitter_time * 100.0) / status_diff); - strncat(s, temps, max_len); + svga_add_status_info(s, max_len, &mystique->svga); + sprintf(temps, "In %s mode\n%f Mpixels/sec\n%f ktraps/sec\n%f%% CPU\n%f%% CPU (real)\n\n", + (mystique->crtcext_regs[3] & CRTCX_R3_MGAMODE) ? "MGA" : "SVGA", (double)mystique->pixel_count / 1000000.0, + (double)mystique->trap_count / 1000.0, ((double)mystique->blitter_time * 100.0) / timer_freq, + ((double)mystique->blitter_time * 100.0) / status_diff); + strncat(s, temps, max_len); - mystique->pixel_count = mystique->trap_count = 0; - mystique->blitter_time = 0; + mystique->pixel_count = mystique->trap_count = 0; + mystique->blitter_time = 0; } -static device_config_t millennium_config[] = - { - { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "2 MB", - .value = 2 - }, - { - .description = "4 MB", - .value = 4 - }, - { - .description = "8 MB", - .value = 8 - }, - { - .description = "" - } - }, - .default_int = 4 - }, - { - .type = -1 - } - }; +static device_config_t millennium_config[] = {{.name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .selection = {{.description = "2 MB", .value = 2}, + {.description = "4 MB", .value = 4}, + {.description = "8 MB", .value = 8}, + {.description = ""}}, + .default_int = 4}, + {.type = -1}}; -static device_config_t mystique_config[] = - { - { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "2 MB", - .value = 2 - }, - { - .description = "4 MB", - .value = 4 - }, - { - .description = "" - } - }, - .default_int = 4 - }, - { - .type = -1 - } - }; +static device_config_t mystique_config[] = { + {.name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .selection = {{.description = "2 MB", .value = 2}, {.description = "4 MB", .value = 4}, {.description = ""}}, + .default_int = 4}, + {.type = -1}}; -device_t millennium_device = - { - "Matrox Millennium", - 0, - millennium_init, - mystique_close, - millennium_available, - mystique_speed_changed, - mystique_force_redraw, - mystique_add_status_info, - millennium_config - }; +device_t millennium_device = {"Matrox Millennium", 0, + millennium_init, mystique_close, + millennium_available, mystique_speed_changed, + mystique_force_redraw, mystique_add_status_info, + millennium_config}; -device_t mystique_device = - { - "Matrox Mystique", - DEVICE_NOT_WORKING, - mystique_init, - mystique_close, - mystique_available, - mystique_speed_changed, - mystique_force_redraw, - mystique_add_status_info, - mystique_config - }; +device_t mystique_device = {"Matrox Mystique", DEVICE_NOT_WORKING, mystique_init, + mystique_close, mystique_available, mystique_speed_changed, + mystique_force_redraw, mystique_add_status_info, mystique_config}; diff --git a/src/video/vid_olivetti_m24.c b/src/video/vid_olivetti_m24.c index eea94b84..35a9bfd7 100644 --- a/src/video/vid_olivetti_m24.c +++ b/src/video/vid_olivetti_m24.c @@ -10,413 +10,436 @@ #include "vid_olivetti_m24.h" typedef struct m24_t { - mem_mapping_t mapping; + mem_mapping_t mapping; - uint8_t crtc[32]; - int crtcreg; + uint8_t crtc[32]; + int crtcreg; - uint8_t *vram; - uint8_t charbuffer[256]; + uint8_t *vram; + uint8_t charbuffer[256]; - uint8_t ctrl; - uint32_t base; + uint8_t ctrl; + uint32_t base; - uint8_t cgamode, cgacol; - uint8_t stat; + uint8_t cgamode, cgacol; + uint8_t stat; - int linepos, displine; - int sc, vc; - int con, coff, cursoron, blink; - int vsynctime, vadj; - int lineff; - uint16_t ma, maback; - int dispon; + int linepos, displine; + int sc, vc; + int con, coff, cursoron, blink; + int vsynctime, vadj; + int lineff; + uint16_t ma, maback; + int dispon; - uint64_t dispontime, dispofftime; - pc_timer_t timer; + uint64_t dispontime, dispofftime; + pc_timer_t timer; - int firstline, lastline; + int firstline, lastline; } m24_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 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}; void m24_recalctimings(m24_t *m24); void m24_out(uint16_t addr, uint8_t val, void *p) { - m24_t *m24 = (m24_t *)p; - uint8_t old; -// pclog("m24_out %04X %02X\n", addr, val); - switch (addr) { - case 0x3d4:m24->crtcreg = val & 31; - return; - 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; - m24_recalctimings(m24); - } - } - return; - case 0x3d8:m24->cgamode = val; - return; - case 0x3d9:m24->cgacol = val; - return; - case 0x3de:m24->ctrl = val; - m24->base = (val & 0x08) ? 0x4000 : 0; - return; - } + m24_t *m24 = (m24_t *)p; + uint8_t old; + // pclog("m24_out %04X %02X\n", addr, val); + switch (addr) { + case 0x3d4: + m24->crtcreg = val & 31; + return; + 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; + m24_recalctimings(m24); + } + } + return; + case 0x3d8: + m24->cgamode = val; + return; + case 0x3d9: + m24->cgacol = val; + return; + case 0x3de: + m24->ctrl = val; + m24->base = (val & 0x08) ? 0x4000 : 0; + return; + } } uint8_t m24_in(uint16_t addr, void *p) { - m24_t *m24 = (m24_t *)p; - switch (addr) { - case 0x3d4:return m24->crtcreg; - case 0x3d5:return m24->crtc[m24->crtcreg]; - case 0x3da:return m24->stat; - } - return 0xff; + m24_t *m24 = (m24_t *)p; + switch (addr) { + case 0x3d4: + return m24->crtcreg; + case 0x3d5: + return m24->crtc[m24->crtcreg]; + case 0x3da: + return m24->stat; + } + return 0xff; } void m24_write(uint32_t addr, uint8_t val, void *p) { - m24_t *m24 = (m24_t *)p; - int offset = ((timer_get_remaining_u64(&m24->timer) / CGACONST) * 4) & 0xfc; + m24_t *m24 = (m24_t *)p; + int offset = ((timer_get_remaining_u64(&m24->timer) / CGACONST) * 4) & 0xfc; - m24->vram[addr & 0x7FFF] = val; - m24->charbuffer[offset] = val; - m24->charbuffer[offset | 1] = val; + m24->vram[addr & 0x7FFF] = val; + m24->charbuffer[offset] = val; + m24->charbuffer[offset | 1] = val; } uint8_t m24_read(uint32_t addr, void *p) { - m24_t *m24 = (m24_t *)p; - return m24->vram[addr & 0x7FFF]; + m24_t *m24 = (m24_t *)p; + return m24->vram[addr & 0x7FFF]; } void m24_recalctimings(m24_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; -// printf("%i %f %f %f %i %i\n",cgamode&1,disptime,dispontime,dispofftime,crtc[0],crtc[1]); - _dispontime *= CGACONST / 2; - _dispofftime *= CGACONST / 2; -// printf("Timings - on %f off %f frame %f second %f\n",dispontime,dispofftime,(dispontime+dispofftime)*262.0,(dispontime+dispofftime)*262.0*59.92); - m24->dispontime = (uint64_t)_dispontime; - m24->dispofftime = (uint64_t)_dispofftime; + 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; + // printf("%i %f %f %f %i %i\n",cgamode&1,disptime,dispontime,dispofftime,crtc[0],crtc[1]); + _dispontime *= CGACONST / 2; + _dispofftime *= CGACONST / 2; + // printf("Timings - on %f off %f frame %f second + // %f\n",dispontime,dispofftime,(dispontime+dispofftime)*262.0,(dispontime+dispofftime)*262.0*59.92); + m24->dispontime = (uint64_t)_dispontime; + m24->dispofftime = (uint64_t)_dispofftime; } void m24_poll(void *p) { - m24_t *m24 = (m24_t *)p; - 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; - uint32_t cols[4]; - int col; - int oldsc; - if (!m24->linepos) { -// pclog("Line poll %i %i %i %i - %04X %i %i %i\n", m24_lineff, vc, sc, vadj, ma, firstline, lastline, displine); - timer_advance_u64(&m24->timer, 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) { - pclog("dispon %i\n", m24->linepos); - if (m24->displine < m24->firstline) { - m24->firstline = m24->displine; -// printf("Firstline %i\n",firstline); - } - m24->lastline = m24->displine; - for (c = 0; c < 8; c++) { - if ((m24->cgamode & 0x12) == 0x12) { - ((uint32_t *)buffer32->line[m24->displine])[c] = cgapal[0]; - if (m24->cgamode & 1) - ((uint32_t *)buffer32->line[m24->displine])[c + (m24->crtc[1] << 3) + 8] = cgapal[0]; - else - ((uint32_t *)buffer32->line[m24->displine])[c + (m24->crtc[1] << 4) + 8] = cgapal[0]; - } else { - ((uint32_t *)buffer32->line[m24->displine])[c] = cgapal[m24->cgacol & 15]; - if (m24->cgamode & 1) - ((uint32_t *)buffer32->line[m24->displine])[c + (m24->crtc[1] << 3) + 8] = cgapal[m24->cgacol & 15]; - else - ((uint32_t *)buffer32->line[m24->displine])[c + (m24->crtc[1] << 4) + 8] = cgapal[m24->cgacol & 15]; - } - } - 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] = cgapal[attr & 15]; - cols[0] = cgapal[(attr >> 4) & 7]; - if ((m24->blink & 16) && (attr & 0x80) && !drawcursor) - cols[1] = cols[0]; - } else { - cols[1] = cgapal[attr & 15]; - cols[0] = cgapal[attr >> 4]; - } - if (drawcursor) { - for (c = 0; c < 8; c++) - ((uint32_t *)buffer32->line[m24->displine])[(x << 3) + c + 8] = - cols[(fontdatm[chr][((m24->sc & 7) << 1) | m24->lineff] & (1 << (c ^ 7))) ? 1 : 0] ^ 0xffffff; - } else { - for (c = 0; c < 8; c++) - ((uint32_t *)buffer32->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] = cgapal[attr & 15]; - cols[0] = cgapal[(attr >> 4) & 7]; - if ((m24->blink & 16) && (attr & 0x80)) - cols[1] = cols[0]; - } else { - cols[1] = cgapal[attr & 15]; - cols[0] = cgapal[attr >> 4]; - } - m24->ma++; - if (drawcursor) { - for (c = 0; c < 8; c++) - ((uint32_t *)buffer32->line[m24->displine])[(x << 4) + (c << 1) + 8] = - ((uint32_t *)buffer32->line[m24->displine])[(x << 4) + (c << 1) + 1 + 8] = - cols[(fontdatm[chr][((m24->sc & 7) << 1) | m24->lineff] & (1 << (c ^ 7))) ? 1 : 0] ^ 0xffffff; - } else { - for (c = 0; c < 8; c++) - ((uint32_t *)buffer32->line[m24->displine])[(x << 4) + (c << 1) + 8] = - ((uint32_t *)buffer32->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] = cgapal[m24->cgacol & 15]; - col = (m24->cgacol & 16) ? 8 : 0; - if (m24->cgamode & 4) { - cols[1] = cgapal[col | 3]; - cols[2] = cgapal[col | 4]; - cols[3] = cgapal[col | 7]; - } else if (m24->cgacol & 32) { - cols[1] = cgapal[col | 3]; - cols[2] = cgapal[col | 5]; - cols[3] = cgapal[col | 7]; - } else { - cols[1] = cgapal[col | 2]; - cols[2] = cgapal[col | 4]; - cols[3] = cgapal[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++) { - ((uint32_t *)buffer32->line[m24->displine])[(x << 4) + (c << 1) + 8] = - ((uint32_t *)buffer32->line[m24->displine])[(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14]; - dat <<= 2; - } - } - } else { - if (m24->ctrl & 1) { - dat2 = ((m24->sc & 1) * 0x4000) | (m24->lineff * 0x2000); - cols[0] = cgapal[0]; - cols[1] = cgapal[15]; - } else { - dat2 = (m24->sc & 1) * 0x2000; - cols[0] = cgapal[0]; - cols[1] = cgapal[m24->cgacol & 15]; - } - 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++) { - ((uint32_t *)buffer32->line[m24->displine])[(x << 4) + c + 8] = cols[dat >> 15]; - dat <<= 1; - } - } - } - } else { - cols[0] = cgapal[((m24->cgamode & 0x12) == 0x12) ? 0 : (m24->cgacol & 15)]; - if (m24->cgamode & 1) - hline(buffer32, 0, m24->displine, (m24->crtc[1] << 3) + 16, cols[0]); - else - hline(buffer32, 0, m24->displine, (m24->crtc[1] << 4) + 16, cols[0]); - } + m24_t *m24 = (m24_t *)p; + 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; + uint32_t cols[4]; + int col; + int oldsc; + if (!m24->linepos) { + // pclog("Line poll %i %i %i %i - %04X %i %i %i\n", m24_lineff, vc, sc, vadj, ma, firstline, + // lastline, displine); + timer_advance_u64(&m24->timer, 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) { + pclog("dispon %i\n", m24->linepos); + if (m24->displine < m24->firstline) { + m24->firstline = m24->displine; + // printf("Firstline %i\n",firstline); + } + m24->lastline = m24->displine; + for (c = 0; c < 8; c++) { + if ((m24->cgamode & 0x12) == 0x12) { + ((uint32_t *)buffer32->line[m24->displine])[c] = cgapal[0]; + if (m24->cgamode & 1) + ((uint32_t *)buffer32->line[m24->displine])[c + (m24->crtc[1] << 3) + 8] = + cgapal[0]; + else + ((uint32_t *)buffer32->line[m24->displine])[c + (m24->crtc[1] << 4) + 8] = + cgapal[0]; + } else { + ((uint32_t *)buffer32->line[m24->displine])[c] = cgapal[m24->cgacol & 15]; + if (m24->cgamode & 1) + ((uint32_t *)buffer32->line[m24->displine])[c + (m24->crtc[1] << 3) + 8] = + cgapal[m24->cgacol & 15]; + else + ((uint32_t *)buffer32->line[m24->displine])[c + (m24->crtc[1] << 4) + 8] = + cgapal[m24->cgacol & 15]; + } + } + 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] = cgapal[attr & 15]; + cols[0] = cgapal[(attr >> 4) & 7]; + if ((m24->blink & 16) && (attr & 0x80) && !drawcursor) + cols[1] = cols[0]; + } else { + cols[1] = cgapal[attr & 15]; + cols[0] = cgapal[attr >> 4]; + } + if (drawcursor) { + for (c = 0; c < 8; c++) + ((uint32_t *)buffer32->line[m24->displine])[(x << 3) + c + 8] = + cols[(fontdatm[chr][((m24->sc & 7) << 1) | m24->lineff] & + (1 << (c ^ 7))) + ? 1 + : 0] ^ + 0xffffff; + } else { + for (c = 0; c < 8; c++) + ((uint32_t *)buffer32->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] = cgapal[attr & 15]; + cols[0] = cgapal[(attr >> 4) & 7]; + if ((m24->blink & 16) && (attr & 0x80)) + cols[1] = cols[0]; + } else { + cols[1] = cgapal[attr & 15]; + cols[0] = cgapal[attr >> 4]; + } + m24->ma++; + if (drawcursor) { + for (c = 0; c < 8; c++) + ((uint32_t *)buffer32->line[m24->displine])[(x << 4) + (c << 1) + 8] = + ((uint32_t *)buffer32 + ->line[m24->displine])[(x << 4) + (c << 1) + 1 + 8] = + cols[(fontdatm[chr][((m24->sc & 7) << 1) | m24->lineff] & + (1 << (c ^ 7))) + ? 1 + : 0] ^ + 0xffffff; + } else { + for (c = 0; c < 8; c++) + ((uint32_t *)buffer32->line[m24->displine])[(x << 4) + (c << 1) + 8] = + ((uint32_t *)buffer32 + ->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] = cgapal[m24->cgacol & 15]; + col = (m24->cgacol & 16) ? 8 : 0; + if (m24->cgamode & 4) { + cols[1] = cgapal[col | 3]; + cols[2] = cgapal[col | 4]; + cols[3] = cgapal[col | 7]; + } else if (m24->cgacol & 32) { + cols[1] = cgapal[col | 3]; + cols[2] = cgapal[col | 5]; + cols[3] = cgapal[col | 7]; + } else { + cols[1] = cgapal[col | 2]; + cols[2] = cgapal[col | 4]; + cols[3] = cgapal[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++) { + ((uint32_t *)buffer32->line[m24->displine])[(x << 4) + (c << 1) + 8] = + ((uint32_t *)buffer32->line[m24->displine])[(x << 4) + (c << 1) + 1 + 8] = + cols[dat >> 14]; + dat <<= 2; + } + } + } else { + if (m24->ctrl & 1) { + dat2 = ((m24->sc & 1) * 0x4000) | (m24->lineff * 0x2000); + cols[0] = cgapal[0]; + cols[1] = cgapal[15]; + } else { + dat2 = (m24->sc & 1) * 0x2000; + cols[0] = cgapal[0]; + cols[1] = cgapal[m24->cgacol & 15]; + } + 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++) { + ((uint32_t *)buffer32->line[m24->displine])[(x << 4) + c + 8] = cols[dat >> 15]; + dat <<= 1; + } + } + } + } else { + cols[0] = cgapal[((m24->cgamode & 0x12) == 0x12) ? 0 : (m24->cgacol & 15)]; + if (m24->cgamode & 1) + hline(buffer32, 0, m24->displine, (m24->crtc[1] << 3) + 16, cols[0]); + else + hline(buffer32, 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; + 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 { -// pclog("Line poll %i %i %i %i\n", m24_lineff, vc, sc, vadj); - timer_advance_u64(&m24->timer, 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; + m24->sc = oldsc; + if (m24->vc == m24->crtc[7] && !m24->sc) + m24->stat |= 8; + m24->displine++; + if (m24->displine >= 720) + m24->displine = 0; + } else { + // pclog("Line poll %i %i %i %i\n", m24_lineff, vc, sc, vadj); + timer_advance_u64(&m24->timer, 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 (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 (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) { - xsize = x; - ysize = m24->lastline - m24->firstline; - if (xsize < 64) - xsize = 656; - if (ysize < 32) - ysize = 200; - updatewindowsize(xsize, ysize + 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) { + xsize = x; + ysize = m24->lastline - m24->firstline; + if (xsize < 64) + xsize = 656; + if (ysize < 32) + ysize = 200; + updatewindowsize(xsize, ysize + 16); + } - video_blit_memtoscreen(0, m24->firstline - 8, 0, (m24->lastline - m24->firstline) + 16, xsize, (m24->lastline - m24->firstline) + 16); - frames++; + video_blit_memtoscreen(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]; - } - } + 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]; + } + } } void *m24_init() { - m24_t *m24 = malloc(sizeof(m24_t)); - memset(m24, 0, sizeof(m24_t)); + m24_t *m24 = malloc(sizeof(m24_t)); + memset(m24, 0, sizeof(m24_t)); - m24->vram = malloc(0x8000); + m24->vram = malloc(0x8000); - timer_add(&m24->timer, m24_poll, m24, 1); - mem_mapping_add(&m24->mapping, 0xb8000, 0x08000, m24_read, NULL, NULL, m24_write, NULL, NULL, NULL, 0, m24); - io_sethandler(0x03d0, 0x0010, m24_in, NULL, NULL, m24_out, NULL, NULL, m24); - return m24; + timer_add(&m24->timer, m24_poll, m24, 1); + mem_mapping_add(&m24->mapping, 0xb8000, 0x08000, m24_read, NULL, NULL, m24_write, NULL, NULL, NULL, 0, m24); + io_sethandler(0x03d0, 0x0010, m24_in, NULL, NULL, m24_out, NULL, NULL, m24); + return m24; } void m24_close(void *p) { - m24_t *m24 = (m24_t *)p; + m24_t *m24 = (m24_t *)p; - free(m24->vram); - free(m24); + free(m24->vram); + free(m24); } void m24_speed_changed(void *p) { - m24_t *m24 = (m24_t *)p; + m24_t *m24 = (m24_t *)p; - m24_recalctimings(m24); + m24_recalctimings(m24); } -device_t m24_device = - { - "Olivetti M24 (video)", - 0, - m24_init, - m24_close, - NULL, - m24_speed_changed, - NULL, - NULL - }; +device_t m24_device = {"Olivetti M24 (video)", 0, m24_init, m24_close, NULL, m24_speed_changed, NULL, NULL}; diff --git a/src/video/vid_oti037.c b/src/video/vid_oti037.c index 2395667a..f845c058 100644 --- a/src/video/vid_oti037.c +++ b/src/video/vid_oti037.c @@ -10,214 +10,209 @@ #include "vid_svga.h" typedef struct oti037_t { - svga_t svga; + svga_t svga; - rom_t bios_rom; + rom_t bios_rom; - int index; - uint8_t regs[32]; + int index; + uint8_t regs[32]; - uint8_t enable_register; + uint8_t enable_register; } oti037_t; void oti037_out(uint16_t addr, uint8_t val, void *p) { - oti037_t *oti037 = (oti037_t *)p; - svga_t *svga = &oti037->svga; - uint8_t old; - uint8_t idx; + oti037_t *oti037 = (oti037_t *)p; + svga_t *svga = &oti037->svga; + uint8_t old; + uint8_t idx; - if (!(oti037->enable_register & 1) && addr != 0x3C3) - return; + if (!(oti037->enable_register & 1) && addr != 0x3C3) + return; - if ((((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && addr < 0x3de) && !(svga->miscout & 1)) - addr ^= 0x60; // mono / color addr selection + if ((((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && addr < 0x3de) && !(svga->miscout & 1)) + addr ^= 0x60; // mono / color addr selection -// pclog("oti037_out : %04X %02X %02X %i ", addr, val, ram[0x489], ins); -// pclog(" %04X:%04X\n", CS,cpu_state.pc); - switch (addr) { - case 0x3C3:oti037->enable_register = val & 1; - return; - case 0x3D4:svga->crtcreg = val /*& 31*/; // fixme: bios wants to set the test bit? - return; - case 0x3D5: - if (((svga->crtcreg & 31) < 7) && (svga->crtc[0x11] & 0x80)) - return; - if (((svga->crtcreg & 31) == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); - old = svga->crtc[svga->crtcreg & 31]; - svga->crtc[svga->crtcreg & 31] = val; - if (old != val) { - if ((svga->crtcreg & 31) < 0xE || (svga->crtcreg & 31) > 0x10) { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - } - break; + // pclog("oti037_out : %04X %02X %02X %i ", addr, val, ram[0x489], ins); + // pclog(" %04X:%04X\n", CS,cpu_state.pc); + switch (addr) { + case 0x3C3: + oti037->enable_register = val & 1; + return; + case 0x3D4: + svga->crtcreg = val /*& 31*/; // fixme: bios wants to set the test bit? + return; + case 0x3D5: + if (((svga->crtcreg & 31) < 7) && (svga->crtc[0x11] & 0x80)) + return; + if (((svga->crtcreg & 31) == 7) && (svga->crtc[0x11] & 0x80)) + val = (svga->crtc[7] & ~0x10) | (val & 0x10); + old = svga->crtc[svga->crtcreg & 31]; + svga->crtc[svga->crtcreg & 31] = val; + if (old != val) { + if ((svga->crtcreg & 31) < 0xE || (svga->crtcreg & 31) > 0x10) { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } + } + break; - case 0x3DE:oti037->index = val /*& 0x1f*/; - return; - case 0x3DF:idx = oti037->index & 0x1f; - oti037->regs[idx] = val; - switch (idx) { - case 0xD: - if (val & 0x80) - mem_mapping_disable(&svga->mapping); - else - mem_mapping_enable(&svga->mapping); - break; - case 0x11:svga->read_bank = (val & 0xf) * 65536; - svga->write_bank = (val >> 4) * 65536; - break; - } - return; - } - svga_out(addr, val, svga); + case 0x3DE: + oti037->index = val /*& 0x1f*/; + return; + case 0x3DF: + idx = oti037->index & 0x1f; + oti037->regs[idx] = val; + switch (idx) { + case 0xD: + if (val & 0x80) + mem_mapping_disable(&svga->mapping); + else + mem_mapping_enable(&svga->mapping); + break; + case 0x11: + svga->read_bank = (val & 0xf) * 65536; + svga->write_bank = (val >> 4) * 65536; + break; + } + return; + } + svga_out(addr, val, svga); } uint8_t oti037_in(uint16_t addr, void *p) { - oti037_t *oti037 = (oti037_t *)p; - svga_t *svga = &oti037->svga; - uint8_t temp; + oti037_t *oti037 = (oti037_t *)p; + svga_t *svga = &oti037->svga; + uint8_t temp; - if (!(oti037->enable_register & 1) && addr != 0x3C3) - return 0xff; + if (!(oti037->enable_register & 1) && addr != 0x3C3) + return 0xff; - if ((((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && addr < 0x3de) && !(svga->miscout & 1)) - addr ^= 0x60; // mono / color addr selection + if ((((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && addr < 0x3de) && !(svga->miscout & 1)) + addr ^= 0x60; // mono / color addr selection -// if (addr != 0x3da && addr != 0x3ba) pclog("oti037_in : %04X ", addr); + // if (addr != 0x3da && addr != 0x3ba) pclog("oti037_in : %04X ", addr); - switch (addr) { - case 0x3C3:temp = oti037->enable_register; - break; - case 0x3D4:temp = svga->crtcreg; - break; - case 0x3D5:temp = svga->crtc[svga->crtcreg & 31]; - break; + switch (addr) { + case 0x3C3: + temp = oti037->enable_register; + break; + case 0x3D4: + temp = svga->crtcreg; + break; + case 0x3D5: + temp = svga->crtc[svga->crtcreg & 31]; + break; - case 0x3DA:svga->attrff = 0; + case 0x3DA: + svga->attrff = 0; - /*The OTI-037C BIOS waits for bits 0 and 3 in 0x3da to go low, then reads 0x3da again - and expects the diagnostic bits to equal the current border colour. As I understand - it, the 0x3da active enable status does not include the border time, so this may be - an area where OTI-037C is not entirely VGA compatible.*/ - svga->cgastat &= ~0x30; - /* copy color diagnostic info from the overscan color register */ - switch (svga->attrregs[0x12] & 0x30) { - case 0x00: /* P0 and P2 */ - if (svga->attrregs[0x11] & 0x01) - svga->cgastat |= 0x10; - if (svga->attrregs[0x11] & 0x04) - svga->cgastat |= 0x20; - break; - case 0x10: /* P4 and P5 */ - if (svga->attrregs[0x11] & 0x10) - svga->cgastat |= 0x10; - if (svga->attrregs[0x11] & 0x20) - svga->cgastat |= 0x20; - break; - case 0x20: /* P1 and P3 */ - if (svga->attrregs[0x11] & 0x02) - svga->cgastat |= 0x10; - if (svga->attrregs[0x11] & 0x08) - svga->cgastat |= 0x20; - break; - case 0x30: /* P6 and P7 */ - if (svga->attrregs[0x11] & 0x40) - svga->cgastat |= 0x10; - if (svga->attrregs[0x11] & 0x80) - svga->cgastat |= 0x20; - break; - } - return svga->cgastat; + /*The OTI-037C BIOS waits for bits 0 and 3 in 0x3da to go low, then reads 0x3da again + and expects the diagnostic bits to equal the current border colour. As I understand + it, the 0x3da active enable status does not include the border time, so this may be + an area where OTI-037C is not entirely VGA compatible.*/ + svga->cgastat &= ~0x30; + /* copy color diagnostic info from the overscan color register */ + switch (svga->attrregs[0x12] & 0x30) { + case 0x00: /* P0 and P2 */ + if (svga->attrregs[0x11] & 0x01) + svga->cgastat |= 0x10; + if (svga->attrregs[0x11] & 0x04) + svga->cgastat |= 0x20; + break; + case 0x10: /* P4 and P5 */ + if (svga->attrregs[0x11] & 0x10) + svga->cgastat |= 0x10; + if (svga->attrregs[0x11] & 0x20) + svga->cgastat |= 0x20; + break; + case 0x20: /* P1 and P3 */ + if (svga->attrregs[0x11] & 0x02) + svga->cgastat |= 0x10; + if (svga->attrregs[0x11] & 0x08) + svga->cgastat |= 0x20; + break; + case 0x30: /* P6 and P7 */ + if (svga->attrregs[0x11] & 0x40) + svga->cgastat |= 0x10; + if (svga->attrregs[0x11] & 0x80) + svga->cgastat |= 0x20; + break; + } + return svga->cgastat; - case 0x3DE:temp = oti037->index; - break; - case 0x3DF: - if ((oti037->index & 0x1f) == 0x10) - temp = 0x18; - else - temp = oti037->regs[oti037->index & 0x1f]; - break; + case 0x3DE: + temp = oti037->index; + break; + case 0x3DF: + if ((oti037->index & 0x1f) == 0x10) + temp = 0x18; + else + temp = oti037->regs[oti037->index & 0x1f]; + break; - default:temp = svga_in(addr, svga); - break; - } -// if (addr != 0x3da && addr != 0x3ba) pclog("%02X %04X:%04X\n", temp, CS,cpu_state.pc); - return temp; + default: + temp = svga_in(addr, svga); + break; + } + // if (addr != 0x3da && addr != 0x3ba) pclog("%02X %04X:%04X\n", temp, CS,cpu_state.pc); + return temp; } void oti037_recalctimings(svga_t *svga) { - oti037_t *oti037 = (oti037_t *)svga->p; + oti037_t *oti037 = (oti037_t *)svga->p; - if (oti037->regs[0x14] & 0x08) - svga->ma_latch |= 0x10000; - if (oti037->regs[0x0d] & 0x0c) - svga->rowoffset <<= 1; - svga->interlace = oti037->regs[0x14] & 0x80; + if (oti037->regs[0x14] & 0x08) + svga->ma_latch |= 0x10000; + if (oti037->regs[0x0d] & 0x0c) + svga->rowoffset <<= 1; + svga->interlace = oti037->regs[0x14] & 0x80; } void *oti037_common_init(char *bios_fn, int vram_size) { - oti037_t *oti037 = malloc(sizeof(oti037_t)); - memset(oti037, 0, sizeof(oti037_t)); + oti037_t *oti037 = malloc(sizeof(oti037_t)); + memset(oti037, 0, sizeof(oti037_t)); - rom_init(&oti037->bios_rom, bios_fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&oti037->bios_rom, bios_fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - svga_init(&oti037->svga, oti037, vram_size << 10, - oti037_recalctimings, - oti037_in, oti037_out, - NULL, - NULL); + svga_init(&oti037->svga, oti037, vram_size << 10, oti037_recalctimings, oti037_in, oti037_out, NULL, NULL); - io_sethandler(0x03c0, 0x0020, oti037_in, NULL, NULL, oti037_out, NULL, NULL, oti037); + io_sethandler(0x03c0, 0x0020, oti037_in, NULL, NULL, oti037_out, NULL, NULL, oti037); - oti037->svga.miscout = 1; - oti037->regs[0] = 0x08; // fixme: bios wants to read this at index 0? this index is undocumented - return oti037; + oti037->svga.miscout = 1; + oti037->regs[0] = 0x08; // fixme: bios wants to read this at index 0? this index is undocumented + return oti037; } -void *oti037_init() { - return oti037_common_init("oti037/bios.bin", 256); -} +void *oti037_init() { return oti037_common_init("oti037/bios.bin", 256); } -static int oti037_available() { - return rom_present("oti037/bios.bin"); -} +static int oti037_available() { return rom_present("oti037/bios.bin"); } void oti037_close(void *p) { - oti037_t *oti037 = (oti037_t *)p; + oti037_t *oti037 = (oti037_t *)p; - svga_close(&oti037->svga); + svga_close(&oti037->svga); - free(oti037); + free(oti037); } void oti037_speed_changed(void *p) { - oti037_t *oti037 = (oti037_t *)p; + oti037_t *oti037 = (oti037_t *)p; - svga_recalctimings(&oti037->svga); + svga_recalctimings(&oti037->svga); } void oti037_force_redraw(void *p) { - oti037_t *oti037 = (oti037_t *)p; + oti037_t *oti037 = (oti037_t *)p; - oti037->svga.fullchange = changeframecount; + oti037->svga.fullchange = changeframecount; } void oti037_add_status_info(char *s, int max_len, void *p) { - oti037_t *oti037 = (oti037_t *)p; + oti037_t *oti037 = (oti037_t *)p; - svga_add_status_info(s, max_len, &oti037->svga); + svga_add_status_info(s, max_len, &oti037->svga); } -device_t oti037_device = - { - "Oak OTI-037", - 0, - oti037_init, - oti037_close, - oti037_available, - oti037_speed_changed, - oti037_force_redraw, - oti037_add_status_info - }; +device_t oti037_device = { + "Oak OTI-037", 0, oti037_init, oti037_close, oti037_available, oti037_speed_changed, oti037_force_redraw, + oti037_add_status_info}; diff --git a/src/video/vid_oti067.c b/src/video/vid_oti067.c index 0d912835..e2443078 100644 --- a/src/video/vid_oti067.c +++ b/src/video/vid_oti067.c @@ -11,283 +11,249 @@ #include "acer386sx.h" typedef struct oti067_t { - svga_t svga; + svga_t svga; - rom_t bios_rom; + rom_t bios_rom; - int index; - uint8_t regs[32]; + int index; + uint8_t regs[32]; - uint8_t pos; - uint8_t dipswitch_val; + uint8_t pos; + uint8_t dipswitch_val; - uint32_t vram_size; - uint32_t vram_mask; + uint32_t vram_size; + uint32_t vram_mask; } oti067_t; void oti067_out(uint16_t addr, uint8_t val, void *p) { - oti067_t *oti067 = (oti067_t *)p; - svga_t *svga = &oti067->svga; - uint8_t old; + oti067_t *oti067 = (oti067_t *)p; + svga_t *svga = &oti067->svga; + uint8_t old; -// pclog("oti067_out : %04X %02X %02X %i\n", addr, val, ram[0x489], ins); + // pclog("oti067_out : %04X %02X %02X %i\n", addr, val, ram[0x489], ins); - if ((((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && addr < 0x3de) && !(svga->miscout & 1)) - addr ^= 0x60; + if ((((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && addr < 0x3de) && !(svga->miscout & 1)) + addr ^= 0x60; - switch (addr) { - case 0x3D4:svga->crtcreg = val & 0x3f; - return; - case 0x3D5: - if (svga->crtcreg & 0x20) - return; - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) - return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); - old = svga->crtc[svga->crtcreg]; - svga->crtc[svga->crtcreg] = val; - if (old != val) { - if (svga->crtcreg < 0xE || svga->crtcreg > 0x10) { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - } - break; + switch (addr) { + case 0x3D4: + svga->crtcreg = val & 0x3f; + return; + case 0x3D5: + if (svga->crtcreg & 0x20) + return; + if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) + return; + if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) + val = (svga->crtc[7] & ~0x10) | (val & 0x10); + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; + if (old != val) { + if (svga->crtcreg < 0xE || svga->crtcreg > 0x10) { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } + } + break; - case 0x3DE:oti067->index = val & 0x1f; - return; - case 0x3DF:oti067->regs[oti067->index] = val; - switch (oti067->index) { - case 0xD:svga->vram_display_mask = (val & 0xc) ? oti067->vram_mask : 0x3ffff; - if ((val & 0x80) && oti067->vram_size == 256) - mem_mapping_disable(&svga->mapping); - else - mem_mapping_enable(&svga->mapping); - if (!(val & 0x80)) - svga->vram_display_mask = 0x3ffff; - break; - case 0x11:svga->read_bank = (val & 0xf) * 65536; - svga->write_bank = (val >> 4) * 65536; - break; - } - return; - } - svga_out(addr, val, svga); + case 0x3DE: + oti067->index = val & 0x1f; + return; + case 0x3DF: + oti067->regs[oti067->index] = val; + switch (oti067->index) { + case 0xD: + svga->vram_display_mask = (val & 0xc) ? oti067->vram_mask : 0x3ffff; + if ((val & 0x80) && oti067->vram_size == 256) + mem_mapping_disable(&svga->mapping); + else + mem_mapping_enable(&svga->mapping); + if (!(val & 0x80)) + svga->vram_display_mask = 0x3ffff; + break; + case 0x11: + svga->read_bank = (val & 0xf) * 65536; + svga->write_bank = (val >> 4) * 65536; + break; + } + return; + } + svga_out(addr, val, svga); } uint8_t oti067_in(uint16_t addr, void *p) { - oti067_t *oti067 = (oti067_t *)p; - svga_t *svga = &oti067->svga; - uint8_t temp; + oti067_t *oti067 = (oti067_t *)p; + svga_t *svga = &oti067->svga; + uint8_t temp; -// if (addr != 0x3da && addr != 0x3ba) pclog("oti067_in : %04X ", addr); + // if (addr != 0x3da && addr != 0x3ba) pclog("oti067_in : %04X ", addr); - if ((((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && addr < 0x3de) && !(svga->miscout & 1)) - addr ^= 0x60; + if ((((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && addr < 0x3de) && !(svga->miscout & 1)) + addr ^= 0x60; - switch (addr) { - case 0x3D4:temp = svga->crtcreg; - break; - case 0x3D5: - if (svga->crtcreg & 0x20) - temp = 0xff; - else - temp = svga->crtc[svga->crtcreg]; - break; + switch (addr) { + case 0x3D4: + temp = svga->crtcreg; + break; + case 0x3D5: + if (svga->crtcreg & 0x20) + temp = 0xff; + else + temp = svga->crtc[svga->crtcreg]; + break; - case 0x3DE:temp = oti067->index | (2 << 5); - break; - case 0x3DF: - if (oti067->index == 0x10) - temp = oti067->dipswitch_val; - else - temp = oti067->regs[oti067->index]; - break; + case 0x3DE: + temp = oti067->index | (2 << 5); + break; + case 0x3DF: + if (oti067->index == 0x10) + temp = oti067->dipswitch_val; + else + temp = oti067->regs[oti067->index]; + break; - default:temp = svga_in(addr, svga); - break; - } -// if (addr != 0x3da && addr != 0x3ba) pclog("%02X %04X:%04X\n", temp, CS,pc); - return temp; + default: + temp = svga_in(addr, svga); + break; + } + // if (addr != 0x3da && addr != 0x3ba) pclog("%02X %04X:%04X\n", temp, CS,pc); + return temp; } void oti067_pos_out(uint16_t addr, uint8_t val, void *p) { - oti067_t *oti067 = (oti067_t *)p; + oti067_t *oti067 = (oti067_t *)p; - if ((val & 8) != (oti067->pos & 8)) { - if (val & 8) - io_sethandler(0x03c0, 0x0020, oti067_in, NULL, NULL, oti067_out, NULL, NULL, oti067); - else - io_removehandler(0x03c0, 0x0020, oti067_in, NULL, NULL, oti067_out, NULL, NULL, oti067); - } + if ((val & 8) != (oti067->pos & 8)) { + if (val & 8) + io_sethandler(0x03c0, 0x0020, oti067_in, NULL, NULL, oti067_out, NULL, NULL, oti067); + else + io_removehandler(0x03c0, 0x0020, oti067_in, NULL, NULL, oti067_out, NULL, NULL, oti067); + } - oti067->pos = val; + oti067->pos = val; } uint8_t oti067_pos_in(uint16_t addr, void *p) { - oti067_t *oti067 = (oti067_t *)p; + oti067_t *oti067 = (oti067_t *)p; - return oti067->pos; + return oti067->pos; } void oti067_recalctimings(svga_t *svga) { - oti067_t *oti067 = (oti067_t *)svga->p; + oti067_t *oti067 = (oti067_t *)svga->p; - if (oti067->regs[0x14] & 0x08) - svga->ma_latch |= 0x10000; - if (oti067->regs[0x0d] & 0x0c) - svga->rowoffset <<= 1; - svga->interlace = oti067->regs[0x14] & 0x80; + if (oti067->regs[0x14] & 0x08) + svga->ma_latch |= 0x10000; + if (oti067->regs[0x0d] & 0x0c) + svga->rowoffset <<= 1; + svga->interlace = oti067->regs[0x14] & 0x80; } void *oti067_common_init(char *bios_fn, int vram_size) { - oti067_t *oti067 = malloc(sizeof(oti067_t)); - memset(oti067, 0, sizeof(oti067_t)); + oti067_t *oti067 = malloc(sizeof(oti067_t)); + memset(oti067, 0, sizeof(oti067_t)); - rom_init(&oti067->bios_rom, bios_fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&oti067->bios_rom, bios_fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - oti067->vram_size = vram_size; - oti067->vram_mask = (vram_size << 10) - 1; + oti067->vram_size = vram_size; + oti067->vram_mask = (vram_size << 10) - 1; - svga_init(&oti067->svga, oti067, vram_size << 10, - oti067_recalctimings, - oti067_in, oti067_out, - NULL, - NULL); + svga_init(&oti067->svga, oti067, vram_size << 10, oti067_recalctimings, oti067_in, oti067_out, NULL, NULL); - io_sethandler(0x03c0, 0x0020, oti067_in, NULL, NULL, oti067_out, NULL, NULL, oti067); - io_sethandler(0x46e8, 0x0001, oti067_pos_in, NULL, NULL, oti067_pos_out, NULL, NULL, oti067); + io_sethandler(0x03c0, 0x0020, oti067_in, NULL, NULL, oti067_out, NULL, NULL, oti067); + io_sethandler(0x46e8, 0x0001, oti067_pos_in, NULL, NULL, oti067_pos_out, NULL, NULL, oti067); - oti067->svga.miscout = 1; + oti067->svga.miscout = 1; - oti067->dipswitch_val = 0x18; - return oti067; + oti067->dipswitch_val = 0x18; + return oti067; } void oti067_enable_disable(void *p, int enable) { - oti067_t *oti067 = (oti067_t *)p; + oti067_t *oti067 = (oti067_t *)p; - mem_mapping_disable(&oti067->bios_rom.mapping); - io_removehandler(0x03c0, 0x0020, oti067_in, NULL, NULL, oti067_out, NULL, NULL, oti067); - io_removehandler(0x46e8, 0x0001, oti067_pos_in, NULL, NULL, oti067_pos_out, NULL, NULL, oti067); - mem_mapping_disable(&oti067->svga.mapping); - if (enable) { - mem_mapping_enable(&oti067->bios_rom.mapping); - io_sethandler(0x03c0, 0x0020, oti067_in, NULL, NULL, oti067_out, NULL, NULL, oti067); - io_sethandler(0x46e8, 0x0001, oti067_pos_in, NULL, NULL, oti067_pos_out, NULL, NULL, oti067); - mem_mapping_enable(&oti067->svga.mapping); - } + mem_mapping_disable(&oti067->bios_rom.mapping); + io_removehandler(0x03c0, 0x0020, oti067_in, NULL, NULL, oti067_out, NULL, NULL, oti067); + io_removehandler(0x46e8, 0x0001, oti067_pos_in, NULL, NULL, oti067_pos_out, NULL, NULL, oti067); + mem_mapping_disable(&oti067->svga.mapping); + if (enable) { + mem_mapping_enable(&oti067->bios_rom.mapping); + io_sethandler(0x03c0, 0x0020, oti067_in, NULL, NULL, oti067_out, NULL, NULL, oti067); + io_sethandler(0x46e8, 0x0001, oti067_pos_in, NULL, NULL, oti067_pos_out, NULL, NULL, oti067); + mem_mapping_enable(&oti067->svga.mapping); + } } void *oti067_init() { - int vram_size = device_get_config_int("memory"); - return oti067_common_init("oti067/bios.bin", vram_size); + int vram_size = device_get_config_int("memory"); + return oti067_common_init("oti067/bios.bin", vram_size); } void *oti067_acer386_init() { - oti067_t *oti067 = oti067_common_init("acer386/oti067.bin", 512); + oti067_t *oti067 = oti067_common_init("acer386/oti067.bin", 512); - acer386sx_set_oti067(oti067); + acer386sx_set_oti067(oti067); - return oti067; + return oti067; } void *oti067_ama932j_init() { - oti067_t *oti067 = oti067_common_init("ama932j/oti067.bin", 512); + oti067_t *oti067 = oti067_common_init("ama932j/oti067.bin", 512); - oti067->dipswitch_val |= 0x20; - return oti067; + oti067->dipswitch_val |= 0x20; + return oti067; } -static int oti067_available() { - return rom_present("oti067/bios.bin"); -} +static int oti067_available() { return rom_present("oti067/bios.bin"); } void oti067_close(void *p) { - oti067_t *oti067 = (oti067_t *)p; + oti067_t *oti067 = (oti067_t *)p; - svga_close(&oti067->svga); + svga_close(&oti067->svga); - free(oti067); + free(oti067); } void oti067_speed_changed(void *p) { - oti067_t *oti067 = (oti067_t *)p; + oti067_t *oti067 = (oti067_t *)p; - svga_recalctimings(&oti067->svga); + svga_recalctimings(&oti067->svga); } void oti067_force_redraw(void *p) { - oti067_t *oti067 = (oti067_t *)p; + oti067_t *oti067 = (oti067_t *)p; - oti067->svga.fullchange = changeframecount; + oti067->svga.fullchange = changeframecount; } void oti067_add_status_info(char *s, int max_len, void *p) { - oti067_t *oti067 = (oti067_t *)p; + oti067_t *oti067 = (oti067_t *)p; - svga_add_status_info(s, max_len, &oti067->svga); + svga_add_status_info(s, max_len, &oti067->svga); } -static device_config_t oti067_config[] = - { - { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "256 kB", - .value = 256 - }, - { - .description = "512 kB", - .value = 512 - }, - { - .description = "" - } - }, - .default_int = 512 - }, - { - .type = -1 - } - }; +static device_config_t oti067_config[] = { + {.name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .selection = {{.description = "256 kB", .value = 256}, {.description = "512 kB", .value = 512}, {.description = ""}}, + .default_int = 512}, + {.type = -1}}; -device_t oti067_device = - { - "Oak OTI-067", - 0, - oti067_init, - oti067_close, - oti067_available, - oti067_speed_changed, - oti067_force_redraw, - oti067_add_status_info, - oti067_config - }; -device_t oti067_acer386_device = - { - "Oak OTI-067 (Acermate 386SX/25N)", - 0, - oti067_acer386_init, - oti067_close, - oti067_available, - oti067_speed_changed, - oti067_force_redraw, - oti067_add_status_info - }; -device_t oti067_ama932j_device = - { - "Oak OTI-067 (AMA-932J)", - 0, - oti067_ama932j_init, - oti067_close, - oti067_available, - oti067_speed_changed, - oti067_force_redraw, - oti067_add_status_info - }; +device_t oti067_device = {"Oak OTI-067", 0, + oti067_init, oti067_close, + oti067_available, oti067_speed_changed, + oti067_force_redraw, oti067_add_status_info, + oti067_config}; +device_t oti067_acer386_device = {"Oak OTI-067 (Acermate 386SX/25N)", + 0, + oti067_acer386_init, + oti067_close, + oti067_available, + oti067_speed_changed, + oti067_force_redraw, + oti067_add_status_info}; +device_t oti067_ama932j_device = {"Oak OTI-067 (AMA-932J)", 0, + oti067_ama932j_init, oti067_close, + oti067_available, oti067_speed_changed, + oti067_force_redraw, oti067_add_status_info}; diff --git a/src/video/vid_paradise.c b/src/video/vid_paradise.c index 6bd09e47..b1e4f649 100644 --- a/src/video/vid_paradise.c +++ b/src/video/vid_paradise.c @@ -17,16 +17,13 @@ #include "wd76c10.h" typedef struct paradise_t { - svga_t svga; + svga_t svga; - rom_t bios_rom; + rom_t bios_rom; - enum { - PVGA1A = 0, - WD90C11 - } type; + enum { PVGA1A = 0, WD90C11 } type; - uint32_t read_bank[4], write_bank[4]; + uint32_t read_bank[4], write_bank[4]; } paradise_t; void paradise_remap(paradise_t *paradise); @@ -35,390 +32,382 @@ void paradise_out(uint16_t addr, uint8_t val, void *p); uint8_t paradise_in(uint16_t addr, void *p); void paradise_out(uint16_t addr, uint8_t val, void *p) { - paradise_t *paradise = (paradise_t *)p; - svga_t *svga = ¶dise->svga; - uint8_t old; + paradise_t *paradise = (paradise_t *)p; + svga_t *svga = ¶dise->svga; + uint8_t old; - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; -// output = 3; -// pclog("Paradise out %04X %02X %04X:%04X\n", addr, val, CS, pc); - switch (addr) { - case 0x3c5: - if (svga->seqaddr > 7) { - if (paradise->type < WD90C11 || svga->seqregs[6] != 0x48) - return; - svga->seqregs[svga->seqaddr & 0x1f] = val; - if (svga->seqaddr == 0x11) - paradise_remap(paradise); - return; - } - break; + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; + // output = 3; + // pclog("Paradise out %04X %02X %04X:%04X\n", addr, val, CS, pc); + switch (addr) { + case 0x3c5: + if (svga->seqaddr > 7) { + if (paradise->type < WD90C11 || svga->seqregs[6] != 0x48) + return; + svga->seqregs[svga->seqaddr & 0x1f] = val; + if (svga->seqaddr == 0x11) + paradise_remap(paradise); + return; + } + break; - case 0x3cf: - if (svga->gdcaddr >= 0x9 && svga->gdcaddr < 0xf) { - if ((svga->gdcreg[0xf] & 7) != 5) - return; - } - if (svga->gdcaddr == 6) { - if ((svga->gdcreg[6] & 0xc) != (val & 0xc)) { -// pclog("Write mapping %02X\n", val); - switch (val & 0xC) { - case 0x0: /*128k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); - svga->banked_mask = 0xffff; - break; - case 0x4: /*64k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - svga->banked_mask = 0xffff; - break; - case 0x8: /*32k at B0000*/ - mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); - svga->banked_mask = 0x7fff; - break; - case 0xC: /*32k at B8000*/ - mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); - svga->banked_mask = 0x7fff; - break; - } - } - svga->gdcreg[6] = val; - paradise_remap(paradise); - return; - } - if (svga->gdcaddr == 0x9 || svga->gdcaddr == 0xa) { - svga->gdcreg[svga->gdcaddr] = val; - paradise_remap(paradise); - return; - } - if (svga->gdcaddr == 0xb) { - svga->gdcreg[0xb] = val; - paradise_remap(paradise); - return; - } - break; + case 0x3cf: + if (svga->gdcaddr >= 0x9 && svga->gdcaddr < 0xf) { + if ((svga->gdcreg[0xf] & 7) != 5) + return; + } + if (svga->gdcaddr == 6) { + if ((svga->gdcreg[6] & 0xc) != (val & 0xc)) { + // pclog("Write mapping %02X\n", val); + switch (val & 0xC) { + case 0x0: /*128k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); + svga->banked_mask = 0xffff; + break; + case 0x4: /*64k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + svga->banked_mask = 0xffff; + break; + case 0x8: /*32k at B0000*/ + mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); + svga->banked_mask = 0x7fff; + break; + case 0xC: /*32k at B8000*/ + mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); + svga->banked_mask = 0x7fff; + break; + } + } + svga->gdcreg[6] = val; + paradise_remap(paradise); + return; + } + if (svga->gdcaddr == 0x9 || svga->gdcaddr == 0xa) { + svga->gdcreg[svga->gdcaddr] = val; + paradise_remap(paradise); + return; + } + if (svga->gdcaddr == 0xb) { + svga->gdcreg[0xb] = val; + paradise_remap(paradise); + return; + } + break; - case 0x3D4:svga->crtcreg = val & 0x3f; - return; - case 0x3D5: - if ((paradise->type == PVGA1A) && (svga->crtcreg & 0x20)) - return; - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) - return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); - if (svga->crtcreg > 0x29 && (svga->crtc[0x29] & 7) != 5) - return; - if (svga->crtcreg >= 0x31 && svga->crtcreg <= 0x37) - return; - old = svga->crtc[svga->crtcreg]; - svga->crtc[svga->crtcreg] = val; + case 0x3D4: + svga->crtcreg = val & 0x3f; + return; + case 0x3D5: + if ((paradise->type == PVGA1A) && (svga->crtcreg & 0x20)) + return; + if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) + return; + if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) + val = (svga->crtc[7] & ~0x10) | (val & 0x10); + if (svga->crtcreg > 0x29 && (svga->crtc[0x29] & 7) != 5) + return; + if (svga->crtcreg >= 0x31 && svga->crtcreg <= 0x37) + return; + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; - if (old != val) { - if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { - svga->fullchange = changeframecount; - svga_recalctimings(¶dise->svga); - } - } - break; + if (old != val) { + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { + svga->fullchange = changeframecount; + svga_recalctimings(¶dise->svga); + } + } + break; - case 0x46e8:io_removehandler(0x03c0, 0x0020, paradise_in, NULL, NULL, paradise_out, NULL, NULL, paradise); - mem_mapping_disable(¶dise->svga.mapping); - if (val & 8) { - io_sethandler(0x03c0, 0x0020, paradise_in, NULL, NULL, paradise_out, NULL, NULL, paradise); - mem_mapping_enable(¶dise->svga.mapping); - } - break; - } - svga_out(addr, val, svga); + case 0x46e8: + io_removehandler(0x03c0, 0x0020, paradise_in, NULL, NULL, paradise_out, NULL, NULL, paradise); + mem_mapping_disable(¶dise->svga.mapping); + if (val & 8) { + io_sethandler(0x03c0, 0x0020, paradise_in, NULL, NULL, paradise_out, NULL, NULL, paradise); + mem_mapping_enable(¶dise->svga.mapping); + } + break; + } + svga_out(addr, val, svga); } uint8_t paradise_in(uint16_t addr, void *p) { - paradise_t *paradise = (paradise_t *)p; - svga_t *svga = ¶dise->svga; + paradise_t *paradise = (paradise_t *)p; + svga_t *svga = ¶dise->svga; - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; -// if (addr != 0x3da) pclog("Paradise in %04X\n", addr); - switch (addr) { - case 0x3c2:return 0x10; + // if (addr != 0x3da) pclog("Paradise in %04X\n", addr); + switch (addr) { + case 0x3c2: + return 0x10; - case 0x3c5: - if (svga->seqaddr > 7) { - if (paradise->type < WD90C11 || svga->seqregs[6] != 0x48) - return 0xff; - if (svga->seqaddr > 0x12) - return 0xff; - return svga->seqregs[svga->seqaddr & 0x1f]; - } - break; + case 0x3c5: + if (svga->seqaddr > 7) { + if (paradise->type < WD90C11 || svga->seqregs[6] != 0x48) + return 0xff; + if (svga->seqaddr > 0x12) + return 0xff; + return svga->seqregs[svga->seqaddr & 0x1f]; + } + break; - case 0x3cf: - if (svga->gdcaddr >= 0x9 && svga->gdcaddr < 0xf) { - if (svga->gdcreg[0xf] & 0x10) - return 0xff; - switch (svga->gdcaddr) { - case 0xf:return (svga->gdcreg[0xf] & 0x17) | 0x80; - } - } - break; + case 0x3cf: + if (svga->gdcaddr >= 0x9 && svga->gdcaddr < 0xf) { + if (svga->gdcreg[0xf] & 0x10) + return 0xff; + switch (svga->gdcaddr) { + case 0xf: + return (svga->gdcreg[0xf] & 0x17) | 0x80; + } + } + break; - case 0x3D4:return svga->crtcreg; - case 0x3D5: - if ((paradise->type == PVGA1A) && (svga->crtcreg & 0x20)) - return 0xff; - if (svga->crtcreg > 0x29 && svga->crtcreg < 0x30 && (svga->crtc[0x29] & 0x88) != 0x80) - return 0xff; - return svga->crtc[svga->crtcreg]; - } - return svga_in(addr, svga); + case 0x3D4: + return svga->crtcreg; + case 0x3D5: + if ((paradise->type == PVGA1A) && (svga->crtcreg & 0x20)) + return 0xff; + if (svga->crtcreg > 0x29 && svga->crtcreg < 0x30 && (svga->crtc[0x29] & 0x88) != 0x80) + return 0xff; + return svga->crtc[svga->crtcreg]; + } + return svga_in(addr, svga); } void paradise_remap(paradise_t *paradise) { - svga_t *svga = ¶dise->svga; + svga_t *svga = ¶dise->svga; - if (svga->seqregs[0x11] & 0x80) { -// pclog("Remap 1\n"); - paradise->read_bank[0] = paradise->read_bank[2] = (svga->gdcreg[0x9] & 0x7f) << 12; - paradise->read_bank[1] = paradise->read_bank[3] = ((svga->gdcreg[0x9] & 0x7f) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); - paradise->write_bank[0] = paradise->write_bank[2] = (svga->gdcreg[0xa] & 0x7f) << 12; - paradise->write_bank[1] = paradise->write_bank[3] = ((svga->gdcreg[0xa] & 0x7f) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); - } else if (svga->gdcreg[0xb] & 0x08) { - if (svga->gdcreg[0x6] & 0xc) { -// pclog("Remap 2\n"); - paradise->read_bank[0] = paradise->read_bank[2] = (svga->gdcreg[0xa] & 0x7f) << 12; - paradise->write_bank[0] = paradise->write_bank[2] = (svga->gdcreg[0xa] & 0x7f) << 12; - paradise->read_bank[1] = paradise->read_bank[3] = ((svga->gdcreg[0x9] & 0x7f) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); - paradise->write_bank[1] = paradise->write_bank[3] = ((svga->gdcreg[0x9] & 0x7f) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); - } else { -// pclog("Remap 3\n"); - paradise->read_bank[0] = paradise->write_bank[0] = (svga->gdcreg[0xa] & 0x7f) << 12; - paradise->read_bank[1] = paradise->write_bank[1] = ((svga->gdcreg[0xa] & 0x7f) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); - paradise->read_bank[2] = paradise->write_bank[2] = (svga->gdcreg[0x9] & 0x7f) << 12; - paradise->read_bank[3] = paradise->write_bank[3] = ((svga->gdcreg[0x9] & 0x7f) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); - } - } else { - // pclog("Remap 4\n"); - paradise->read_bank[0] = paradise->read_bank[2] = (svga->gdcreg[0x9] & 0x7f) << 12; - paradise->read_bank[1] = paradise->read_bank[3] = ((svga->gdcreg[0x9] & 0x7f) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); - paradise->write_bank[0] = paradise->write_bank[2] = (svga->gdcreg[0x9] & 0x7f) << 12; - paradise->write_bank[1] = paradise->write_bank[3] = ((svga->gdcreg[0x9] & 0x7f) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); - } - paradise->read_bank[1] &= 0x7ffff; - paradise->write_bank[1] &= 0x7ffff; + if (svga->seqregs[0x11] & 0x80) { + // pclog("Remap 1\n"); + paradise->read_bank[0] = paradise->read_bank[2] = (svga->gdcreg[0x9] & 0x7f) << 12; + paradise->read_bank[1] = paradise->read_bank[3] = + ((svga->gdcreg[0x9] & 0x7f) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); + paradise->write_bank[0] = paradise->write_bank[2] = (svga->gdcreg[0xa] & 0x7f) << 12; + paradise->write_bank[1] = paradise->write_bank[3] = + ((svga->gdcreg[0xa] & 0x7f) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); + } else if (svga->gdcreg[0xb] & 0x08) { + if (svga->gdcreg[0x6] & 0xc) { + // pclog("Remap 2\n"); + paradise->read_bank[0] = paradise->read_bank[2] = (svga->gdcreg[0xa] & 0x7f) << 12; + paradise->write_bank[0] = paradise->write_bank[2] = (svga->gdcreg[0xa] & 0x7f) << 12; + paradise->read_bank[1] = paradise->read_bank[3] = + ((svga->gdcreg[0x9] & 0x7f) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); + paradise->write_bank[1] = paradise->write_bank[3] = + ((svga->gdcreg[0x9] & 0x7f) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); + } else { + // pclog("Remap 3\n"); + paradise->read_bank[0] = paradise->write_bank[0] = (svga->gdcreg[0xa] & 0x7f) << 12; + paradise->read_bank[1] = paradise->write_bank[1] = + ((svga->gdcreg[0xa] & 0x7f) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); + paradise->read_bank[2] = paradise->write_bank[2] = (svga->gdcreg[0x9] & 0x7f) << 12; + paradise->read_bank[3] = paradise->write_bank[3] = + ((svga->gdcreg[0x9] & 0x7f) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); + } + } else { + // pclog("Remap 4\n"); + paradise->read_bank[0] = paradise->read_bank[2] = (svga->gdcreg[0x9] & 0x7f) << 12; + paradise->read_bank[1] = paradise->read_bank[3] = + ((svga->gdcreg[0x9] & 0x7f) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); + paradise->write_bank[0] = paradise->write_bank[2] = (svga->gdcreg[0x9] & 0x7f) << 12; + paradise->write_bank[1] = paradise->write_bank[3] = + ((svga->gdcreg[0x9] & 0x7f) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); + } + paradise->read_bank[1] &= 0x7ffff; + paradise->write_bank[1] &= 0x7ffff; -// pclog("Remap - %04X %04X %04x %04x\n", paradise->read_bank[0], paradise->write_bank[0], paradise->read_bank[1], paradise->write_bank[1]); + // pclog("Remap - %04X %04X %04x %04x\n", paradise->read_bank[0], paradise->write_bank[0], paradise->read_bank[1], + // paradise->write_bank[1]); } void paradise_recalctimings(svga_t *svga) { - svga->lowres = !(svga->gdcreg[0xe] & 0x01); - if (svga->bpp == 8 && !svga->lowres) - svga->render = svga_render_8bpp_highres; + svga->lowres = !(svga->gdcreg[0xe] & 0x01); + if (svga->bpp == 8 && !svga->lowres) + svga->render = svga_render_8bpp_highres; } static void paradise_write(uint32_t addr, uint8_t val, void *p) { - paradise_t *paradise = (paradise_t *)p; -// pclog("paradise_write : %05X %02X ", addr, val); - addr = (addr & 0x7fff) + paradise->write_bank[(addr >> 15) & 3]; -// pclog("%08X\n", addr); - svga_write_linear(addr, val, ¶dise->svga); + paradise_t *paradise = (paradise_t *)p; + // pclog("paradise_write : %05X %02X ", addr, val); + addr = (addr & 0x7fff) + paradise->write_bank[(addr >> 15) & 3]; + // pclog("%08X\n", addr); + svga_write_linear(addr, val, ¶dise->svga); } static void paradise_writew(uint32_t addr, uint16_t val, void *p) { - paradise_t *paradise = (paradise_t *)p; - addr = (addr & 0x7fff) + paradise->write_bank[(addr >> 15) & 3]; - svga_writew_linear(addr, val, ¶dise->svga); + paradise_t *paradise = (paradise_t *)p; + addr = (addr & 0x7fff) + paradise->write_bank[(addr >> 15) & 3]; + svga_writew_linear(addr, val, ¶dise->svga); } static uint8_t paradise_read(uint32_t addr, void *p) { - paradise_t *paradise = (paradise_t *)p; -// pclog("paradise_read : %05X ", addr); - addr = (addr & 0x7fff) + paradise->read_bank[(addr >> 15) & 3]; -// pclog("%08X\n", addr); - return svga_read_linear(addr, ¶dise->svga); + paradise_t *paradise = (paradise_t *)p; + // pclog("paradise_read : %05X ", addr); + addr = (addr & 0x7fff) + paradise->read_bank[(addr >> 15) & 3]; + // pclog("%08X\n", addr); + return svga_read_linear(addr, ¶dise->svga); } static uint16_t paradise_readw(uint32_t addr, void *p) { - paradise_t *paradise = (paradise_t *)p; - addr = (addr & 0x7fff) + paradise->read_bank[(addr >> 15) & 3]; - return svga_readw_linear(addr, ¶dise->svga); + paradise_t *paradise = (paradise_t *)p; + addr = (addr & 0x7fff) + paradise->read_bank[(addr >> 15) & 3]; + return svga_readw_linear(addr, ¶dise->svga); } void *paradise_pvga1a_init() { - paradise_t *paradise = malloc(sizeof(paradise_t)); - svga_t *svga = ¶dise->svga; - memset(paradise, 0, sizeof(paradise_t)); + paradise_t *paradise = malloc(sizeof(paradise_t)); + svga_t *svga = ¶dise->svga; + memset(paradise, 0, sizeof(paradise_t)); - io_sethandler(0x03c0, 0x0020, paradise_in, NULL, NULL, paradise_out, NULL, NULL, paradise); + io_sethandler(0x03c0, 0x0020, paradise_in, NULL, NULL, paradise_out, NULL, NULL, paradise); - svga_init(¶dise->svga, paradise, 1 << 18, /*256kb*/ - NULL, - paradise_in, paradise_out, - NULL, - NULL); + svga_init(¶dise->svga, paradise, 1 << 18, /*256kb*/ + NULL, paradise_in, paradise_out, NULL, NULL); - mem_mapping_set_handler(¶dise->svga.mapping, paradise_read, paradise_readw, NULL, paradise_write, paradise_writew, NULL); - mem_mapping_set_p(¶dise->svga.mapping, paradise); + mem_mapping_set_handler(¶dise->svga.mapping, paradise_read, paradise_readw, NULL, paradise_write, paradise_writew, + NULL); + mem_mapping_set_p(¶dise->svga.mapping, paradise); - svga->crtc[0x31] = 'W'; - svga->crtc[0x32] = 'D'; - svga->crtc[0x33] = '9'; - svga->crtc[0x34] = '0'; - svga->crtc[0x35] = 'C'; + svga->crtc[0x31] = 'W'; + svga->crtc[0x32] = 'D'; + svga->crtc[0x33] = '9'; + svga->crtc[0x34] = '0'; + svga->crtc[0x35] = 'C'; - svga->bpp = 8; - svga->miscout = 1; + svga->bpp = 8; + svga->miscout = 1; - paradise->type = PVGA1A; + paradise->type = PVGA1A; - return paradise; + return paradise; } void *paradise_wd90c11_init() { - paradise_t *paradise = malloc(sizeof(paradise_t)); - svga_t *svga = ¶dise->svga; - memset(paradise, 0, sizeof(paradise_t)); + paradise_t *paradise = malloc(sizeof(paradise_t)); + svga_t *svga = ¶dise->svga; + memset(paradise, 0, sizeof(paradise_t)); - io_sethandler(0x03c0, 0x0020, paradise_in, NULL, NULL, paradise_out, NULL, NULL, paradise); + io_sethandler(0x03c0, 0x0020, paradise_in, NULL, NULL, paradise_out, NULL, NULL, paradise); - svga_init(¶dise->svga, paradise, 1 << 19, /*512kb*/ - paradise_recalctimings, - paradise_in, paradise_out, - NULL, - NULL); + svga_init(¶dise->svga, paradise, 1 << 19, /*512kb*/ + paradise_recalctimings, paradise_in, paradise_out, NULL, NULL); - mem_mapping_set_handler(¶dise->svga.mapping, paradise_read, paradise_readw, NULL, paradise_write, paradise_writew, NULL); - mem_mapping_set_p(¶dise->svga.mapping, paradise); + mem_mapping_set_handler(¶dise->svga.mapping, paradise_read, paradise_readw, NULL, paradise_write, paradise_writew, + NULL); + mem_mapping_set_p(¶dise->svga.mapping, paradise); - svga->crtc[0x31] = 'W'; - svga->crtc[0x32] = 'D'; - svga->crtc[0x33] = '9'; - svga->crtc[0x34] = '0'; - svga->crtc[0x35] = 'C'; - svga->crtc[0x36] = '1'; - svga->crtc[0x37] = '1'; + svga->crtc[0x31] = 'W'; + svga->crtc[0x32] = 'D'; + svga->crtc[0x33] = '9'; + svga->crtc[0x34] = '0'; + svga->crtc[0x35] = 'C'; + svga->crtc[0x36] = '1'; + svga->crtc[0x37] = '1'; - svga->bpp = 8; - svga->miscout = 1; + svga->bpp = 8; + svga->miscout = 1; - paradise->type = WD90C11; + paradise->type = WD90C11; - return paradise; + return paradise; } static void *paradise_pvga1a_pc2086_init() { - paradise_t *paradise = paradise_pvga1a_init(); + paradise_t *paradise = paradise_pvga1a_init(); - if (paradise) - rom_init(¶dise->bios_rom, "pc2086/40186.ic171", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + if (paradise) + rom_init(¶dise->bios_rom, "pc2086/40186.ic171", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - return paradise; + return paradise; } static void *paradise_pvga1a_pc3086_init() { - paradise_t *paradise = paradise_pvga1a_init(); + paradise_t *paradise = paradise_pvga1a_init(); - if (paradise) - rom_init(¶dise->bios_rom, "pc3086/c000.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + if (paradise) + rom_init(¶dise->bios_rom, "pc3086/c000.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - return paradise; + return paradise; } static void *paradise_wd90c11_megapc_init() { - paradise_t *paradise = paradise_wd90c11_init(); + paradise_t *paradise = paradise_wd90c11_init(); - if (paradise) - rom_init_interleaved(¶dise->bios_rom, - "megapc/41651-bios lo.u18", - "megapc/211253-bios hi.u19", - 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + if (paradise) + rom_init_interleaved(¶dise->bios_rom, "megapc/41651-bios lo.u18", "megapc/211253-bios hi.u19", 0xc0000, + 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - return paradise; + return paradise; } static void *paradise_pvga1a_oli_go481_init() { - paradise_t *paradise = paradise_pvga1a_init(); + paradise_t *paradise = paradise_pvga1a_init(); - if (paradise) - rom_init_interleaved(¶dise->bios_rom, - "oli_go481_lo.bin", - "oli_go481_hi.bin", - 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + if (paradise) + rom_init_interleaved(¶dise->bios_rom, "oli_go481_lo.bin", "oli_go481_hi.bin", 0xc0000, 0x8000, 0x7fff, 0, + MEM_MAPPING_EXTERNAL); - io_sethandler(0x46e8, 0x0001, paradise_in, NULL, NULL, paradise_out, NULL, NULL, paradise); + io_sethandler(0x46e8, 0x0001, paradise_in, NULL, NULL, paradise_out, NULL, NULL, paradise); - return paradise; + return paradise; } void paradise_close(void *p) { - paradise_t *paradise = (paradise_t *)p; + paradise_t *paradise = (paradise_t *)p; - svga_close(¶dise->svga); + svga_close(¶dise->svga); - free(paradise); + free(paradise); } void paradise_speed_changed(void *p) { - paradise_t *paradise = (paradise_t *)p; + paradise_t *paradise = (paradise_t *)p; - svga_recalctimings(¶dise->svga); + svga_recalctimings(¶dise->svga); } void paradise_force_redraw(void *p) { - paradise_t *paradise = (paradise_t *)p; + paradise_t *paradise = (paradise_t *)p; - paradise->svga.fullchange = changeframecount; + paradise->svga.fullchange = changeframecount; } void paradise_add_status_info(char *s, int max_len, void *p) { - paradise_t *paradise = (paradise_t *)p; + paradise_t *paradise = (paradise_t *)p; - svga_add_status_info(s, max_len, ¶dise->svga); + svga_add_status_info(s, max_len, ¶dise->svga); } -static int oli_go481_available() { - return (rom_present("oli_go481_lo.bin") && rom_present("oli_go481_hi.bin")); -} +static int oli_go481_available() { return (rom_present("oli_go481_lo.bin") && rom_present("oli_go481_hi.bin")); } -device_t paradise_pvga1a_pc2086_device = - { - "Paradise PVGA1A (Amstrad PC2086)", - 0, - paradise_pvga1a_pc2086_init, - paradise_close, - NULL, - paradise_speed_changed, - paradise_force_redraw, - paradise_add_status_info - }; -device_t paradise_pvga1a_pc3086_device = - { - "Paradise PVGA1A (Amstrad PC3086)", - 0, - paradise_pvga1a_pc3086_init, - paradise_close, - NULL, - paradise_speed_changed, - paradise_force_redraw, - paradise_add_status_info - }; -device_t paradise_wd90c11_megapc_device = - { - "Paradise WD90C11 (Amstrad MegaPC)", - 0, - paradise_wd90c11_megapc_init, - paradise_close, - NULL, - paradise_speed_changed, - paradise_force_redraw, - paradise_add_status_info - }; -device_t paradise_pvga1a_oli_go481_device = - { - "Paradise PVGA1A (Olivetti GO481)", - 0, - paradise_pvga1a_oli_go481_init, - paradise_close, - oli_go481_available, - paradise_speed_changed, - paradise_force_redraw, - paradise_add_status_info - }; +device_t paradise_pvga1a_pc2086_device = {"Paradise PVGA1A (Amstrad PC2086)", + 0, + paradise_pvga1a_pc2086_init, + paradise_close, + NULL, + paradise_speed_changed, + paradise_force_redraw, + paradise_add_status_info}; +device_t paradise_pvga1a_pc3086_device = {"Paradise PVGA1A (Amstrad PC3086)", + 0, + paradise_pvga1a_pc3086_init, + paradise_close, + NULL, + paradise_speed_changed, + paradise_force_redraw, + paradise_add_status_info}; +device_t paradise_wd90c11_megapc_device = {"Paradise WD90C11 (Amstrad MegaPC)", + 0, + paradise_wd90c11_megapc_init, + paradise_close, + NULL, + paradise_speed_changed, + paradise_force_redraw, + paradise_add_status_info}; +device_t paradise_pvga1a_oli_go481_device = {"Paradise PVGA1A (Olivetti GO481)", + 0, + paradise_pvga1a_oli_go481_init, + paradise_close, + oli_go481_available, + paradise_speed_changed, + paradise_force_redraw, + paradise_add_status_info}; diff --git a/src/video/vid_pc1512.c b/src/video/vid_pc1512.c index 20210aa8..22c261ea 100644 --- a/src/video/vid_pc1512.c +++ b/src/video/vid_pc1512.c @@ -1,10 +1,10 @@ /*PC1512 CGA emulation 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 + + The Technical Reference Manual lists the video waitstate time as between 12 and 46 cycles. PCem currently always uses the lower number.*/ #include #include "ibm.h" @@ -16,478 +16,468 @@ #include "vid_pc1512.h" typedef struct pc1512_t { - mem_mapping_t mapping; + mem_mapping_t mapping; - uint8_t crtc[32]; - int crtcreg; + uint8_t crtc[32]; + int crtcreg; - uint8_t cgacol, cgamode, stat; + uint8_t cgacol, cgamode, stat; - uint8_t plane_write, plane_read, border; + uint8_t plane_write, plane_read, border; - int fontbase; - int linepos, displine; - int sc, vc; - int cgadispon; - int con, coff, cursoron, cgablink; - int vsynctime, vadj; - uint16_t ma, maback; - int dispon; - int blink; + int fontbase; + int linepos, displine; + int sc, vc; + int cgadispon; + int con, coff, cursoron, cgablink; + int vsynctime, vadj; + uint16_t ma, maback; + int dispon; + int blink; - uint64_t dispontime, dispofftime; - pc_timer_t timer; - int firstline, lastline; + uint64_t dispontime, dispofftime; + pc_timer_t timer; + int firstline, lastline; - uint8_t *vram; + uint8_t *vram; } pc1512_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 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 void pc1512_recalctimings(pc1512_t *pc1512); static void pc1512_out(uint16_t addr, uint8_t val, void *p) { - pc1512_t *pc1512 = (pc1512_t *)p; - uint8_t old; -// pclog("PC1512 out %04X %02X %04X:%04X\n",addr,val,CS,pc); - switch (addr) { - case 0x3d0: - case 0x3d2: - case 0x3d4: - case 0x3d6:pc1512->crtcreg = val & 31; - return; - case 0x3d1: - case 0x3d3: - case 0x3d5: - case 0x3d7:old = pc1512->crtc[pc1512->crtcreg]; - pc1512->crtc[pc1512->crtcreg] = val & crtcmask[pc1512->crtcreg]; - if (old != val) { - if (pc1512->crtcreg < 0xe || pc1512->crtcreg > 0x10) { - fullchange = changeframecount; - pc1512_recalctimings(pc1512); - } - } - return; - case 0x3d8: - if ((val & 0x12) == 0x12 && (pc1512->cgamode & 0x12) != 0x12) { - pc1512->plane_write = 0xf; - pc1512->plane_read = 0; - } - pc1512->cgamode = val; - return; - case 0x3d9:pc1512->cgacol = val; - return; - case 0x3dd:pc1512->plane_write = val; - return; - case 0x3de:pc1512->plane_read = val & 3; - return; - case 0x3df:pc1512->border = val; - return; - } + pc1512_t *pc1512 = (pc1512_t *)p; + uint8_t old; + // pclog("PC1512 out %04X %02X %04X:%04X\n",addr,val,CS,pc); + switch (addr) { + case 0x3d0: + case 0x3d2: + case 0x3d4: + case 0x3d6: + pc1512->crtcreg = val & 31; + return; + case 0x3d1: + case 0x3d3: + case 0x3d5: + case 0x3d7: + old = pc1512->crtc[pc1512->crtcreg]; + pc1512->crtc[pc1512->crtcreg] = val & crtcmask[pc1512->crtcreg]; + if (old != val) { + if (pc1512->crtcreg < 0xe || pc1512->crtcreg > 0x10) { + fullchange = changeframecount; + pc1512_recalctimings(pc1512); + } + } + return; + case 0x3d8: + if ((val & 0x12) == 0x12 && (pc1512->cgamode & 0x12) != 0x12) { + pc1512->plane_write = 0xf; + pc1512->plane_read = 0; + } + pc1512->cgamode = val; + return; + case 0x3d9: + pc1512->cgacol = val; + return; + case 0x3dd: + pc1512->plane_write = val; + return; + case 0x3de: + pc1512->plane_read = val & 3; + return; + case 0x3df: + pc1512->border = val; + return; + } } static uint8_t pc1512_in(uint16_t addr, void *p) { - pc1512_t *pc1512 = (pc1512_t *)p; -// pclog("PC1512 in %04X %02X %04X:%04X\n",addr,CS,pc); - switch (addr) { - case 0x3d4:return pc1512->crtcreg; - case 0x3d5:return pc1512->crtc[pc1512->crtcreg]; - case 0x3da:pc1512->stat ^= 0x01; /*Bit 0 is toggle bit on PC1512*/ - return pc1512->stat ^ 0x01; - } - return 0xff; + pc1512_t *pc1512 = (pc1512_t *)p; + // pclog("PC1512 in %04X %02X %04X:%04X\n",addr,CS,pc); + switch (addr) { + case 0x3d4: + return pc1512->crtcreg; + case 0x3d5: + return pc1512->crtc[pc1512->crtcreg]; + case 0x3da: + pc1512->stat ^= 0x01; /*Bit 0 is toggle bit on PC1512*/ + return pc1512->stat ^ 0x01; + } + return 0xff; } static void pc1512_write(uint32_t addr, uint8_t val, void *p) { - pc1512_t *pc1512 = (pc1512_t *)p; + pc1512_t *pc1512 = (pc1512_t *)p; - egawrites++; - cycles -= 12; - addr &= 0x3fff; + egawrites++; + cycles -= 12; + addr &= 0x3fff; - if ((pc1512->cgamode & 0x12) == 0x12) { - if (pc1512->plane_write & 1) - pc1512->vram[addr] = val; - if (pc1512->plane_write & 2) - pc1512->vram[addr | 0x4000] = val; - if (pc1512->plane_write & 4) - pc1512->vram[addr | 0x8000] = val; - if (pc1512->plane_write & 8) - pc1512->vram[addr | 0xc000] = val; - } else - pc1512->vram[addr] = val; + if ((pc1512->cgamode & 0x12) == 0x12) { + if (pc1512->plane_write & 1) + pc1512->vram[addr] = val; + if (pc1512->plane_write & 2) + pc1512->vram[addr | 0x4000] = val; + if (pc1512->plane_write & 4) + pc1512->vram[addr | 0x8000] = val; + if (pc1512->plane_write & 8) + pc1512->vram[addr | 0xc000] = val; + } else + pc1512->vram[addr] = val; } static uint8_t pc1512_read(uint32_t addr, void *p) { - pc1512_t *pc1512 = (pc1512_t *)p; + pc1512_t *pc1512 = (pc1512_t *)p; - egareads++; - cycles -= 12; - addr &= 0x3fff; + egareads++; + cycles -= 12; + addr &= 0x3fff; - if ((pc1512->cgamode & 0x12) == 0x12) - return pc1512->vram[addr | (pc1512->plane_read << 14)]; - return pc1512->vram[addr]; + if ((pc1512->cgamode & 0x12) == 0x12) + return pc1512->vram[addr | (pc1512->plane_read << 14)]; + return pc1512->vram[addr]; } static void pc1512_recalctimings(pc1512_t *pc1512) { - double _dispontime, _dispofftime, disptime; - disptime = 114; /*Fixed on PC1512*/ - _dispontime = 80; - _dispofftime = disptime - _dispontime; -// printf("%i %f %f %f %i %i\n",cgamode&1,disptime,dispontime,dispofftime,crtc[0],crtc[1]); - _dispontime *= CGACONST; - _dispofftime *= CGACONST; -// printf("Timings - on %f off %f frame %f second %f\n",dispontime,dispofftime,(dispontime+dispofftime)*262.0,(dispontime+dispofftime)*262.0*59.92); - pc1512->dispontime = (uint64_t)_dispontime; - pc1512->dispofftime = (uint64_t)_dispofftime; + double _dispontime, _dispofftime, disptime; + disptime = 114; /*Fixed on PC1512*/ + _dispontime = 80; + _dispofftime = disptime - _dispontime; + // printf("%i %f %f %f %i %i\n",cgamode&1,disptime,dispontime,dispofftime,crtc[0],crtc[1]); + _dispontime *= CGACONST; + _dispofftime *= CGACONST; + // printf("Timings - on %f off %f frame %f second + // %f\n",dispontime,dispofftime,(dispontime+dispofftime)*262.0,(dispontime+dispofftime)*262.0*59.92); + pc1512->dispontime = (uint64_t)_dispontime; + pc1512->dispofftime = (uint64_t)_dispofftime; } static void pc1512_poll(void *p) { - pc1512_t *pc1512 = (pc1512_t *)p; - uint16_t ca = (pc1512->crtc[15] | (pc1512->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; + pc1512_t *pc1512 = (pc1512_t *)p; + uint16_t ca = (pc1512->crtc[15] | (pc1512->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 (!pc1512->linepos) { - timer_advance_u64(&pc1512->timer, pc1512->dispofftime); - pc1512->linepos = 1; - oldsc = pc1512->sc; - if (pc1512->dispon) { - if (pc1512->displine < pc1512->firstline) { - pc1512->firstline = pc1512->displine; - video_wait_for_buffer(); - } - pc1512->lastline = pc1512->displine; - for (c = 0; c < 8; c++) { - if ((pc1512->cgamode & 0x12) == 0x12) { - ((uint32_t *)buffer32->line[pc1512->displine])[c] = cgapal[pc1512->border & 15]; - if (pc1512->cgamode & 1) - ((uint32_t *)buffer32->line[pc1512->displine])[c + (pc1512->crtc[1] << 3) + 8] = 0; - else - ((uint32_t *)buffer32->line[pc1512->displine])[c + (pc1512->crtc[1] << 4) + 8] = 0; - } else { - ((uint32_t *)buffer32->line[pc1512->displine])[c] = cgapal[pc1512->cgacol & 15]; - if (pc1512->cgamode & 1) - ((uint32_t *)buffer32->line[pc1512->displine])[c + (pc1512->crtc[1] << 3) + 8] = cgapal[pc1512->cgacol & 15]; - else - ((uint32_t *)buffer32->line[pc1512->displine])[c + (pc1512->crtc[1] << 4) + 8] = cgapal[pc1512->cgacol & 15]; - } - } - if (pc1512->cgamode & 1) { - for (x = 0; x < 80; x++) { - chr = pc1512->vram[((pc1512->ma << 1) & 0x3fff)]; - attr = pc1512->vram[(((pc1512->ma << 1) + 1) & 0x3fff)]; - drawcursor = ((pc1512->ma == ca) && pc1512->con && pc1512->cursoron); - if (pc1512->cgamode & 0x20) { - cols[1] = cgapal[attr & 15]; - cols[0] = cgapal[(attr >> 4) & 7]; - if ((pc1512->blink & 16) && (attr & 0x80) && !drawcursor) - cols[1] = cols[0]; - } else { - cols[1] = cgapal[attr & 15]; - cols[0] = cgapal[attr >> 4]; - } - if (drawcursor) { - for (c = 0; c < 8; c++) - ((uint32_t *)buffer32->line[pc1512->displine])[(x << 3) + c + 8] = - cols[(fontdat[chr + pc1512->fontbase][pc1512->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 0xffffff; - } else { - for (c = 0; c < 8; c++) - ((uint32_t *)buffer32->line[pc1512->displine])[(x << 3) + c + 8] = cols[(fontdat[chr + pc1512->fontbase][pc1512->sc & 7] - & (1 << (c ^ 7))) ? 1 : 0]; - } - pc1512->ma++; - } - } else if (!(pc1512->cgamode & 2)) { - for (x = 0; x < 40; x++) { - chr = pc1512->vram[((pc1512->ma << 1) & 0x3fff)]; - attr = pc1512->vram[(((pc1512->ma << 1) + 1) & 0x3fff)]; - drawcursor = ((pc1512->ma == ca) && pc1512->con && pc1512->cursoron); - if (pc1512->cgamode & 0x20) { - cols[1] = cgapal[attr & 15]; - cols[0] = cgapal[(attr >> 4) & 7]; - if ((pc1512->blink & 16) && (attr & 0x80)) - cols[1] = cols[0]; - } else { - cols[1] = cgapal[attr & 15]; - cols[0] = cgapal[attr >> 4]; - } - pc1512->ma++; - if (drawcursor) { - for (c = 0; c < 8; c++) - ((uint32_t *)buffer32->line[pc1512->displine])[(x << 4) + (c << 1) + 8] = - ((uint32_t *)buffer32->line[pc1512->displine])[(x << 4) + (c << 1) + 1 + 8] = - cols[(fontdat[chr + pc1512->fontbase][pc1512->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 0xffffff; - } else { - for (c = 0; c < 8; c++) - ((uint32_t *)buffer32->line[pc1512->displine])[(x << 4) + (c << 1) + 8] = - ((uint32_t *)buffer32->line[pc1512->displine])[(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr + pc1512->fontbase][pc1512->sc & 7] - & (1 << (c ^ 7))) ? 1 : 0]; - } - } - } else if (!(pc1512->cgamode & 16)) { - cols[0] = cgapal[pc1512->cgacol & 15]; - col = (pc1512->cgacol & 16) ? 8 : 0; - if (pc1512->cgamode & 4) { - cols[1] = cgapal[col | 3]; - cols[2] = cgapal[col | 4]; - cols[3] = cgapal[col | 7]; - } else if (pc1512->cgacol & 32) { - cols[1] = cgapal[col | 3]; - cols[2] = cgapal[col | 5]; - cols[3] = cgapal[col | 7]; - } else { - cols[1] = cgapal[col | 2]; - cols[2] = cgapal[col | 4]; - cols[3] = cgapal[col | 6]; - } - for (x = 0; x < 40; x++) { - dat = (pc1512->vram[((pc1512->ma << 1) & 0x1fff) + ((pc1512->sc & 1) * 0x2000)] << 8) - | pc1512->vram[((pc1512->ma << 1) & 0x1fff) + ((pc1512->sc & 1) * 0x2000) + 1]; - pc1512->ma++; - for (c = 0; c < 8; c++) { - ((uint32_t *)buffer32->line[pc1512->displine])[(x << 4) + (c << 1) + 8] = - ((uint32_t *)buffer32->line[pc1512->displine])[(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14]; - dat <<= 2; - } - } - } else { - for (x = 0; x < 40; x++) { - ca = ((pc1512->ma << 1) & 0x1fff) + ((pc1512->sc & 1) * 0x2000); - dat = (pc1512->vram[ca] << 8) | pc1512->vram[ca + 1]; - dat2 = (pc1512->vram[ca + 0x4000] << 8) | pc1512->vram[ca + 0x4001]; - dat3 = (pc1512->vram[ca + 0x8000] << 8) | pc1512->vram[ca + 0x8001]; - dat4 = (pc1512->vram[ca + 0xc000] << 8) | pc1512->vram[ca + 0xc001]; + if (!pc1512->linepos) { + timer_advance_u64(&pc1512->timer, pc1512->dispofftime); + pc1512->linepos = 1; + oldsc = pc1512->sc; + if (pc1512->dispon) { + if (pc1512->displine < pc1512->firstline) { + pc1512->firstline = pc1512->displine; + video_wait_for_buffer(); + } + pc1512->lastline = pc1512->displine; + for (c = 0; c < 8; c++) { + if ((pc1512->cgamode & 0x12) == 0x12) { + ((uint32_t *)buffer32->line[pc1512->displine])[c] = cgapal[pc1512->border & 15]; + if (pc1512->cgamode & 1) + ((uint32_t *)buffer32->line[pc1512->displine])[c + (pc1512->crtc[1] << 3) + 8] = + 0; + else + ((uint32_t *)buffer32->line[pc1512->displine])[c + (pc1512->crtc[1] << 4) + 8] = + 0; + } else { + ((uint32_t *)buffer32->line[pc1512->displine])[c] = cgapal[pc1512->cgacol & 15]; + if (pc1512->cgamode & 1) + ((uint32_t *)buffer32->line[pc1512->displine])[c + (pc1512->crtc[1] << 3) + 8] = + cgapal[pc1512->cgacol & 15]; + else + ((uint32_t *)buffer32->line[pc1512->displine])[c + (pc1512->crtc[1] << 4) + 8] = + cgapal[pc1512->cgacol & 15]; + } + } + if (pc1512->cgamode & 1) { + for (x = 0; x < 80; x++) { + chr = pc1512->vram[((pc1512->ma << 1) & 0x3fff)]; + attr = pc1512->vram[(((pc1512->ma << 1) + 1) & 0x3fff)]; + drawcursor = ((pc1512->ma == ca) && pc1512->con && pc1512->cursoron); + if (pc1512->cgamode & 0x20) { + cols[1] = cgapal[attr & 15]; + cols[0] = cgapal[(attr >> 4) & 7]; + if ((pc1512->blink & 16) && (attr & 0x80) && !drawcursor) + cols[1] = cols[0]; + } else { + cols[1] = cgapal[attr & 15]; + cols[0] = cgapal[attr >> 4]; + } + if (drawcursor) { + for (c = 0; c < 8; c++) + ((uint32_t *)buffer32->line[pc1512->displine])[(x << 3) + c + 8] = + cols[(fontdat[chr + pc1512->fontbase][pc1512->sc & 7] & + (1 << (c ^ 7))) + ? 1 + : 0] ^ + 0xffffff; + } else { + for (c = 0; c < 8; c++) + ((uint32_t *)buffer32->line[pc1512->displine])[(x << 3) + c + 8] = + cols[(fontdat[chr + pc1512->fontbase][pc1512->sc & 7] & + (1 << (c ^ 7))) + ? 1 + : 0]; + } + pc1512->ma++; + } + } else if (!(pc1512->cgamode & 2)) { + for (x = 0; x < 40; x++) { + chr = pc1512->vram[((pc1512->ma << 1) & 0x3fff)]; + attr = pc1512->vram[(((pc1512->ma << 1) + 1) & 0x3fff)]; + drawcursor = ((pc1512->ma == ca) && pc1512->con && pc1512->cursoron); + if (pc1512->cgamode & 0x20) { + cols[1] = cgapal[attr & 15]; + cols[0] = cgapal[(attr >> 4) & 7]; + if ((pc1512->blink & 16) && (attr & 0x80)) + cols[1] = cols[0]; + } else { + cols[1] = cgapal[attr & 15]; + cols[0] = cgapal[attr >> 4]; + } + pc1512->ma++; + if (drawcursor) { + for (c = 0; c < 8; c++) + ((uint32_t *)buffer32->line[pc1512->displine])[(x << 4) + (c << 1) + 8] = + ((uint32_t *)buffer32 + ->line[pc1512->displine])[(x << 4) + (c << 1) + 1 + 8] = + cols[(fontdat[chr + pc1512->fontbase][pc1512->sc & 7] & + (1 << (c ^ 7))) + ? 1 + : 0] ^ + 0xffffff; + } else { + for (c = 0; c < 8; c++) + ((uint32_t *)buffer32->line[pc1512->displine])[(x << 4) + (c << 1) + 8] = + ((uint32_t *)buffer32 + ->line[pc1512->displine])[(x << 4) + (c << 1) + 1 + 8] = + cols[(fontdat[chr + pc1512->fontbase][pc1512->sc & 7] & + (1 << (c ^ 7))) + ? 1 + : 0]; + } + } + } else if (!(pc1512->cgamode & 16)) { + cols[0] = cgapal[pc1512->cgacol & 15]; + col = (pc1512->cgacol & 16) ? 8 : 0; + if (pc1512->cgamode & 4) { + cols[1] = cgapal[col | 3]; + cols[2] = cgapal[col | 4]; + cols[3] = cgapal[col | 7]; + } else if (pc1512->cgacol & 32) { + cols[1] = cgapal[col | 3]; + cols[2] = cgapal[col | 5]; + cols[3] = cgapal[col | 7]; + } else { + cols[1] = cgapal[col | 2]; + cols[2] = cgapal[col | 4]; + cols[3] = cgapal[col | 6]; + } + for (x = 0; x < 40; x++) { + dat = (pc1512->vram[((pc1512->ma << 1) & 0x1fff) + ((pc1512->sc & 1) * 0x2000)] << 8) | + pc1512->vram[((pc1512->ma << 1) & 0x1fff) + ((pc1512->sc & 1) * 0x2000) + 1]; + pc1512->ma++; + for (c = 0; c < 8; c++) { + ((uint32_t *)buffer32->line[pc1512->displine])[(x << 4) + (c << 1) + 8] = + ((uint32_t *) + buffer32->line[pc1512->displine])[(x << 4) + (c << 1) + 1 + 8] = + cols[dat >> 14]; + dat <<= 2; + } + } + } else { + for (x = 0; x < 40; x++) { + ca = ((pc1512->ma << 1) & 0x1fff) + ((pc1512->sc & 1) * 0x2000); + dat = (pc1512->vram[ca] << 8) | pc1512->vram[ca + 1]; + dat2 = (pc1512->vram[ca + 0x4000] << 8) | pc1512->vram[ca + 0x4001]; + dat3 = (pc1512->vram[ca + 0x8000] << 8) | pc1512->vram[ca + 0x8001]; + dat4 = (pc1512->vram[ca + 0xc000] << 8) | pc1512->vram[ca + 0xc001]; - pc1512->ma++; - for (c = 0; c < 16; c++) { - ((uint32_t *)buffer32->line[pc1512->displine])[(x << 4) + c + 8] = - cgapal[((dat >> 15) | ((dat2 >> 15) << 1) | ((dat3 >> 15) << 2) | ((dat4 >> 15) << 3)) - & (pc1512->cgacol & 15)]; - dat <<= 1; - dat2 <<= 1; - dat3 <<= 1; - dat4 <<= 1; - } - } - } - } else { - cols[0] = cgapal[((pc1512->cgamode & 0x12) == 0x12) ? 0 : (pc1512->cgacol & 15)]; - if (pc1512->cgamode & 1) - hline(buffer32, 0, pc1512->displine, (pc1512->crtc[1] << 3) + 16, cols[0]); - else - hline(buffer32, 0, pc1512->displine, (pc1512->crtc[1] << 4) + 16, cols[0]); - } + pc1512->ma++; + for (c = 0; c < 16; c++) { + ((uint32_t *)buffer32->line[pc1512->displine])[(x << 4) + c + 8] = + cgapal[((dat >> 15) | ((dat2 >> 15) << 1) | ((dat3 >> 15) << 2) | + ((dat4 >> 15) << 3)) & + (pc1512->cgacol & 15)]; + dat <<= 1; + dat2 <<= 1; + dat3 <<= 1; + dat4 <<= 1; + } + } + } + } else { + cols[0] = cgapal[((pc1512->cgamode & 0x12) == 0x12) ? 0 : (pc1512->cgacol & 15)]; + if (pc1512->cgamode & 1) + hline(buffer32, 0, pc1512->displine, (pc1512->crtc[1] << 3) + 16, cols[0]); + else + hline(buffer32, 0, pc1512->displine, (pc1512->crtc[1] << 4) + 16, cols[0]); + } - pc1512->sc = oldsc; - if (pc1512->vsynctime) - pc1512->stat |= 8; - pc1512->displine++; - if (pc1512->displine >= 360) - pc1512->displine = 0; -// pclog("Line %i %i %i %i %i %i\n",displine,cgadispon,firstline,lastline,vc,sc); - } else { - timer_advance_u64(&pc1512->timer, pc1512->dispontime); - if ((pc1512->lastline - pc1512->firstline) == 199) - pc1512->dispon = 0; /*Amstrad PC1512 always displays 200 lines, regardless of CRTC settings*/ - pc1512->linepos = 0; - if (pc1512->vsynctime) { - pc1512->vsynctime--; - if (!pc1512->vsynctime) - pc1512->stat &= ~8; - } - if (pc1512->sc == (pc1512->crtc[11] & 31)) { - pc1512->con = 0; - pc1512->coff = 1; - } - if (pc1512->vadj) { - pc1512->sc++; - pc1512->sc &= 31; - pc1512->ma = pc1512->maback; - pc1512->vadj--; - if (!pc1512->vadj) { - pc1512->dispon = 1; - pc1512->ma = pc1512->maback = (pc1512->crtc[13] | (pc1512->crtc[12] << 8)) & 0x3fff; - pc1512->sc = 0; - } - } else if (pc1512->sc == pc1512->crtc[9]) { - pc1512->maback = pc1512->ma; - pc1512->sc = 0; - pc1512->vc++; - pc1512->vc &= 127; + pc1512->sc = oldsc; + if (pc1512->vsynctime) + pc1512->stat |= 8; + pc1512->displine++; + if (pc1512->displine >= 360) + pc1512->displine = 0; + // pclog("Line %i %i %i %i %i %i\n",displine,cgadispon,firstline,lastline,vc,sc); + } else { + timer_advance_u64(&pc1512->timer, pc1512->dispontime); + if ((pc1512->lastline - pc1512->firstline) == 199) + pc1512->dispon = 0; /*Amstrad PC1512 always displays 200 lines, regardless of CRTC settings*/ + pc1512->linepos = 0; + if (pc1512->vsynctime) { + pc1512->vsynctime--; + if (!pc1512->vsynctime) + pc1512->stat &= ~8; + } + if (pc1512->sc == (pc1512->crtc[11] & 31)) { + pc1512->con = 0; + pc1512->coff = 1; + } + if (pc1512->vadj) { + pc1512->sc++; + pc1512->sc &= 31; + pc1512->ma = pc1512->maback; + pc1512->vadj--; + if (!pc1512->vadj) { + pc1512->dispon = 1; + pc1512->ma = pc1512->maback = (pc1512->crtc[13] | (pc1512->crtc[12] << 8)) & 0x3fff; + pc1512->sc = 0; + } + } else if (pc1512->sc == pc1512->crtc[9]) { + pc1512->maback = pc1512->ma; + pc1512->sc = 0; + pc1512->vc++; + pc1512->vc &= 127; - if (pc1512->displine == 32)//oldvc == (cgamode & 2) ? 127 : 31) - { - pc1512->vc = 0; - pc1512->vadj = 6; - if ((pc1512->crtc[10] & 0x60) == 0x20) - pc1512->cursoron = 0; - else - pc1512->cursoron = pc1512->blink & 16; - } + if (pc1512->displine == 32) // oldvc == (cgamode & 2) ? 127 : 31) + { + pc1512->vc = 0; + pc1512->vadj = 6; + if ((pc1512->crtc[10] & 0x60) == 0x20) + pc1512->cursoron = 0; + else + pc1512->cursoron = pc1512->blink & 16; + } - if (pc1512->displine >= 262)//vc == (cgamode & 2) ? 111 : 27) - { - pc1512->dispon = 0; - pc1512->displine = 0; - pc1512->vsynctime = 46; + if (pc1512->displine >= 262) // vc == (cgamode & 2) ? 111 : 27) + { + pc1512->dispon = 0; + pc1512->displine = 0; + pc1512->vsynctime = 46; - if (pc1512->cgamode & 1) - x = (pc1512->crtc[1] << 3) + 16; - else - x = (pc1512->crtc[1] << 4) + 16; - x = 640 + 16; - pc1512->lastline++; + if (pc1512->cgamode & 1) + x = (pc1512->crtc[1] << 3) + 16; + else + x = (pc1512->crtc[1] << 4) + 16; + x = 640 + 16; + pc1512->lastline++; - if (x != xsize || (pc1512->lastline - pc1512->firstline) != ysize) { - xsize = x; - ysize = pc1512->lastline - pc1512->firstline; - if (xsize < 64) - xsize = 656; - if (ysize < 32) - ysize = 200; - updatewindowsize(xsize, (ysize << 1) + 16); - } + if (x != xsize || (pc1512->lastline - pc1512->firstline) != ysize) { + xsize = x; + ysize = pc1512->lastline - pc1512->firstline; + if (xsize < 64) + xsize = 656; + if (ysize < 32) + ysize = 200; + updatewindowsize(xsize, (ysize << 1) + 16); + } - video_blit_memtoscreen(0, pc1512->firstline - 4, 0, (pc1512->lastline - pc1512->firstline) + 8, xsize, (pc1512->lastline - pc1512->firstline) + 8); -// blit(buffer,vbuf,0,firstline-4,0,0,xsize,(lastline-firstline)+8+1); -// if (vid_resize) stretch_blit(vbuf,screen,0,0,xsize,(lastline-firstline)+8+1,0,0,winsizex,winsizey); -// else stretch_blit(vbuf,screen,0,0,xsize,(lastline-firstline)+8+1,0,0,xsize,((lastline-firstline)<<1)+16+2); -// if (readflash) rectfill(screen,winsizex-40,8,winsizex-8,14,0xFFFFFFFF); -// readflash=0; + video_blit_memtoscreen(0, pc1512->firstline - 4, 0, (pc1512->lastline - pc1512->firstline) + 8, + xsize, (pc1512->lastline - pc1512->firstline) + 8); + // blit(buffer,vbuf,0,firstline-4,0,0,xsize,(lastline-firstline)+8+1); + // if (vid_resize) + // stretch_blit(vbuf,screen,0,0,xsize,(lastline-firstline)+8+1,0,0,winsizex,winsizey); + // else + // stretch_blit(vbuf,screen,0,0,xsize,(lastline-firstline)+8+1,0,0,xsize,((lastline-firstline)<<1)+16+2); + // if (readflash) + // rectfill(screen,winsizex-40,8,winsizex-8,14,0xFFFFFFFF); + // readflash=0; - video_res_x = xsize - 16; - video_res_y = ysize; - if (pc1512->cgamode & 1) { - video_res_x /= 8; - video_res_y /= pc1512->crtc[9] + 1; - video_bpp = 0; - } else if (!(pc1512->cgamode & 2)) { - video_res_x /= 16; - video_res_y /= pc1512->crtc[9] + 1; - video_bpp = 0; - } else if (!(pc1512->cgamode & 16)) { - video_res_x /= 2; - video_bpp = 2; - } else { - video_bpp = 4; - } + video_res_x = xsize - 16; + video_res_y = ysize; + if (pc1512->cgamode & 1) { + video_res_x /= 8; + video_res_y /= pc1512->crtc[9] + 1; + video_bpp = 0; + } else if (!(pc1512->cgamode & 2)) { + video_res_x /= 16; + video_res_y /= pc1512->crtc[9] + 1; + video_bpp = 0; + } else if (!(pc1512->cgamode & 16)) { + video_res_x /= 2; + video_bpp = 2; + } else { + video_bpp = 4; + } - pc1512->firstline = 1000; - pc1512->lastline = 0; - pc1512->blink++; - } - } else { - pc1512->sc++; - pc1512->sc &= 31; - pc1512->ma = pc1512->maback; - } - if (pc1512->sc == (pc1512->crtc[10] & 31)) - pc1512->con = 1; - } + pc1512->firstline = 1000; + pc1512->lastline = 0; + pc1512->blink++; + } + } else { + pc1512->sc++; + pc1512->sc &= 31; + pc1512->ma = pc1512->maback; + } + if (pc1512->sc == (pc1512->crtc[10] & 31)) + pc1512->con = 1; + } } static void *pc1512_init() { - int display_type; - pc1512_t *pc1512 = malloc(sizeof(pc1512_t)); - memset(pc1512, 0, sizeof(pc1512_t)); + int display_type; + pc1512_t *pc1512 = malloc(sizeof(pc1512_t)); + memset(pc1512, 0, sizeof(pc1512_t)); - pc1512->vram = malloc(0x10000); + pc1512->vram = malloc(0x10000); - pc1512->cgacol = 7; - pc1512->cgamode = 0x12; - pc1512->fontbase = (device_get_config_int("codepage") & 3) * 256; - display_type = device_get_config_int("display_type"); + pc1512->cgacol = 7; + pc1512->cgamode = 0x12; + pc1512->fontbase = (device_get_config_int("codepage") & 3) * 256; + display_type = device_get_config_int("display_type"); - timer_add(&pc1512->timer, pc1512_poll, pc1512, 1); - mem_mapping_add(&pc1512->mapping, 0xb8000, 0x08000, pc1512_read, NULL, NULL, pc1512_write, NULL, NULL, NULL, 0, pc1512); - io_sethandler(0x03d0, 0x0010, pc1512_in, NULL, NULL, pc1512_out, NULL, NULL, pc1512); - cgapal_rebuild(display_type, 0); - return pc1512; + timer_add(&pc1512->timer, pc1512_poll, pc1512, 1); + mem_mapping_add(&pc1512->mapping, 0xb8000, 0x08000, pc1512_read, NULL, NULL, pc1512_write, NULL, NULL, NULL, 0, pc1512); + io_sethandler(0x03d0, 0x0010, pc1512_in, NULL, NULL, pc1512_out, NULL, NULL, pc1512); + cgapal_rebuild(display_type, 0); + return pc1512; } static void pc1512_close(void *p) { - pc1512_t *pc1512 = (pc1512_t *)p; + pc1512_t *pc1512 = (pc1512_t *)p; - free(pc1512->vram); - free(pc1512); + free(pc1512->vram); + free(pc1512); } static void pc1512_speed_changed(void *p) { - pc1512_t *pc1512 = (pc1512_t *)p; + pc1512_t *pc1512 = (pc1512_t *)p; - pc1512_recalctimings(pc1512); + pc1512_recalctimings(pc1512); } -device_config_t pc1512_config[] = - { - { - .name = "display_type", - .description = "Display type", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "PC-CM (Colour)", - .value = DISPLAY_RGB - }, - { - .description = "PC-MM (Monochrome)", - .value = DISPLAY_WHITE - }, - { - .description = "" - } - } - }, - { - .name = "codepage", - .description = "Hardware font", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "US English", - .value = 3 - }, - { - .description = "Danish", - .value = 1 - }, - { - .description = "Greek", - .value = 0 - }, - { - .description = "" - } - }, - .default_int = 3 - }, - { - .type = -1 - } - }; +device_config_t pc1512_config[] = {{.name = "display_type", + .description = "Display type", + .type = CONFIG_SELECTION, + .selection = {{.description = "PC-CM (Colour)", .value = DISPLAY_RGB}, + {.description = "PC-MM (Monochrome)", .value = DISPLAY_WHITE}, + {.description = ""}}}, + {.name = "codepage", + .description = "Hardware font", + .type = CONFIG_SELECTION, + .selection = {{.description = "US English", .value = 3}, + {.description = "Danish", .value = 1}, + {.description = "Greek", .value = 0}, + {.description = ""}}, + .default_int = 3}, + {.type = -1}}; -device_t pc1512_device = - { - "Amstrad PC1512 (video)", - 0, - pc1512_init, - pc1512_close, - NULL, - pc1512_speed_changed, - NULL, - NULL, - pc1512_config - }; +device_t pc1512_device = {"Amstrad PC1512 (video)", 0, pc1512_init, pc1512_close, NULL, + pc1512_speed_changed, NULL, NULL, pc1512_config}; diff --git a/src/video/vid_pc1640.c b/src/video/vid_pc1640.c index e046daf1..9a40def0 100644 --- a/src/video/vid_pc1640.c +++ b/src/video/vid_pc1640.c @@ -13,125 +13,114 @@ #include "vid_pc1640.h" typedef struct pc1640_t { - mem_mapping_t cga_mapping; - mem_mapping_t ega_mapping; + mem_mapping_t cga_mapping; + mem_mapping_t ega_mapping; - cga_t cga; - ega_t ega; + cga_t cga; + ega_t ega; - rom_t bios_rom; + rom_t bios_rom; - int cga_enabled; - uint64_t dispontime, dispofftime; - pc_timer_t timer; + int cga_enabled; + uint64_t dispontime, dispofftime; + pc_timer_t timer; } pc1640_t; void pc1640_out(uint16_t addr, uint8_t val, void *p) { - pc1640_t *pc1640 = (pc1640_t *)p; + pc1640_t *pc1640 = (pc1640_t *)p; - switch (addr) { - case 0x3db: - if (pc1640->cga_enabled != (val & 0x40)) { - pc1640->cga_enabled = val & 0x40; - if (pc1640->cga_enabled) { - timer_disable(&pc1640->ega.timer); - timer_set_delay_u64(&pc1640->cga.timer, 0); - mem_mapping_enable(&pc1640->cga_mapping); - mem_mapping_disable(&pc1640->ega_mapping); - } else { - timer_disable(&pc1640->cga.timer); - timer_set_delay_u64(&pc1640->ega.timer, 0); - mem_mapping_disable(&pc1640->cga_mapping); - switch (pc1640->ega.gdcreg[6] & 0xc) { - case 0x0: /*128k at A0000*/ - mem_mapping_set_addr(&pc1640->ega_mapping, 0xa0000, 0x20000); - break; - case 0x4: /*64k at A0000*/ - mem_mapping_set_addr(&pc1640->ega_mapping, 0xa0000, 0x10000); - break; - case 0x8: /*32k at B0000*/ - mem_mapping_set_addr(&pc1640->ega_mapping, 0xb0000, 0x08000); - break; - case 0xC: /*32k at B8000*/ - mem_mapping_set_addr(&pc1640->ega_mapping, 0xb8000, 0x08000); - break; - } - } - } - pclog("3DB write %02X\n", val); - return; - } - if (pc1640->cga_enabled) - cga_out(addr, val, &pc1640->cga); - else - ega_out(addr, val, &pc1640->ega); + switch (addr) { + case 0x3db: + if (pc1640->cga_enabled != (val & 0x40)) { + pc1640->cga_enabled = val & 0x40; + if (pc1640->cga_enabled) { + timer_disable(&pc1640->ega.timer); + timer_set_delay_u64(&pc1640->cga.timer, 0); + mem_mapping_enable(&pc1640->cga_mapping); + mem_mapping_disable(&pc1640->ega_mapping); + } else { + timer_disable(&pc1640->cga.timer); + timer_set_delay_u64(&pc1640->ega.timer, 0); + mem_mapping_disable(&pc1640->cga_mapping); + switch (pc1640->ega.gdcreg[6] & 0xc) { + case 0x0: /*128k at A0000*/ + mem_mapping_set_addr(&pc1640->ega_mapping, 0xa0000, 0x20000); + break; + case 0x4: /*64k at A0000*/ + mem_mapping_set_addr(&pc1640->ega_mapping, 0xa0000, 0x10000); + break; + case 0x8: /*32k at B0000*/ + mem_mapping_set_addr(&pc1640->ega_mapping, 0xb0000, 0x08000); + break; + case 0xC: /*32k at B8000*/ + mem_mapping_set_addr(&pc1640->ega_mapping, 0xb8000, 0x08000); + break; + } + } + } + pclog("3DB write %02X\n", val); + return; + } + if (pc1640->cga_enabled) + cga_out(addr, val, &pc1640->cga); + else + ega_out(addr, val, &pc1640->ega); } uint8_t pc1640_in(uint16_t addr, void *p) { - pc1640_t *pc1640 = (pc1640_t *)p; + pc1640_t *pc1640 = (pc1640_t *)p; - switch (addr) { - } + switch (addr) {} - if (pc1640->cga_enabled) - return cga_in(addr, &pc1640->cga); - else - return ega_in(addr, &pc1640->ega); + if (pc1640->cga_enabled) + return cga_in(addr, &pc1640->cga); + else + return ega_in(addr, &pc1640->ega); } void pc1640_recalctimings(pc1640_t *pc1640) { - cga_recalctimings(&pc1640->cga); - ega_recalctimings(&pc1640->ega); - if (pc1640->cga_enabled) { - pc1640->dispontime = pc1640->cga.dispontime; - pc1640->dispofftime = pc1640->cga.dispofftime; - } else { - pc1640->dispontime = pc1640->ega.dispontime; - pc1640->dispofftime = pc1640->ega.dispofftime; - } + cga_recalctimings(&pc1640->cga); + ega_recalctimings(&pc1640->ega); + if (pc1640->cga_enabled) { + pc1640->dispontime = pc1640->cga.dispontime; + pc1640->dispofftime = pc1640->cga.dispofftime; + } else { + pc1640->dispontime = pc1640->ega.dispontime; + pc1640->dispofftime = pc1640->ega.dispofftime; + } } void *pc1640_init() { - pc1640_t *pc1640 = malloc(sizeof(pc1640_t)); - cga_t *cga = &pc1640->cga; - ega_t *ega = &pc1640->ega; - memset(pc1640, 0, sizeof(pc1640_t)); + pc1640_t *pc1640 = malloc(sizeof(pc1640_t)); + cga_t *cga = &pc1640->cga; + ega_t *ega = &pc1640->ega; + memset(pc1640, 0, sizeof(pc1640_t)); - rom_init(&pc1640->bios_rom, "pc1640/40100", 0xc0000, 0x8000, 0x7fff, 0, 0); + rom_init(&pc1640->bios_rom, "pc1640/40100", 0xc0000, 0x8000, 0x7fff, 0, 0); - ega_init(&pc1640->ega, 9, 0); - pc1640->cga.vram = pc1640->ega.vram; - pc1640->cga_enabled = 1; - cga_init(&pc1640->cga); - timer_disable(&pc1640->ega.timer); + ega_init(&pc1640->ega, 9, 0); + pc1640->cga.vram = pc1640->ega.vram; + pc1640->cga_enabled = 1; + cga_init(&pc1640->cga); + timer_disable(&pc1640->ega.timer); - mem_mapping_add(&pc1640->cga_mapping, 0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL, 0, cga); - mem_mapping_add(&pc1640->ega_mapping, 0, 0, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL, 0, ega); - io_sethandler(0x03a0, 0x0040, pc1640_in, NULL, NULL, pc1640_out, NULL, NULL, pc1640); - return pc1640; + mem_mapping_add(&pc1640->cga_mapping, 0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL, 0, cga); + mem_mapping_add(&pc1640->ega_mapping, 0, 0, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL, 0, ega); + io_sethandler(0x03a0, 0x0040, pc1640_in, NULL, NULL, pc1640_out, NULL, NULL, pc1640); + return pc1640; } void pc1640_close(void *p) { - pc1640_t *pc1640 = (pc1640_t *)p; + pc1640_t *pc1640 = (pc1640_t *)p; - free(pc1640->ega.vram); - free(pc1640); + free(pc1640->ega.vram); + free(pc1640); } void pc1640_speed_changed(void *p) { - pc1640_t *pc1640 = (pc1640_t *)p; + pc1640_t *pc1640 = (pc1640_t *)p; - pc1640_recalctimings(pc1640); + pc1640_recalctimings(pc1640); } -device_t pc1640_device = - { - "Amstrad PC1640 (video)", - 0, - pc1640_init, - pc1640_close, - NULL, - pc1640_speed_changed, - NULL, - NULL - }; +device_t pc1640_device = {"Amstrad PC1640 (video)", 0, pc1640_init, pc1640_close, NULL, pc1640_speed_changed, NULL, NULL}; diff --git a/src/video/vid_pc200.c b/src/video/vid_pc200.c index 8f434337..7b545f32 100644 --- a/src/video/vid_pc200.c +++ b/src/video/vid_pc200.c @@ -15,11 +15,11 @@ #define PC200LOG(x) /* Display type */ -#define PC200_CGA 0 /* CGA monitor */ -#define PC200_MDA 1 /* MDA monitor */ -#define PC200_TV 2 /* Television */ -#define PC200_LCDC 3 /* PPC512 LCD as CGA*/ -#define PC200_LCDM 4 /* PPC512 LCD as MDA*/ +#define PC200_CGA 0 /* CGA monitor */ +#define PC200_MDA 1 /* MDA monitor */ +#define PC200_TV 2 /* Television */ +#define PC200_LCDC 3 /* PPC512 LCD as CGA*/ +#define PC200_LCDM 4 /* PPC512 LCD as MDA*/ int pc200_is_mda; @@ -28,998 +28,887 @@ static uint32_t blue, green; static uint32_t lcdcols[256][2][2]; typedef struct pc200_t { - mem_mapping_t cga_mapping; - mem_mapping_t mda_mapping; + mem_mapping_t cga_mapping; + mem_mapping_t mda_mapping; - cga_t cga; - mda_t mda; + cga_t cga; + mda_t mda; - pc_timer_t timer; + pc_timer_t timer; - uint8_t emulation; /* Which display are we emulating? */ - uint8_t dipswitches; /* DIP switches 1-3 */ - uint8_t crtc_index; /* CRTC index readback - * Bit 7: CGA control port written - * Bit 6: Operation control port written - * Bit 5: CRTC register written - * Bits 0-4: Last CRTC register selected */ - uint8_t operation_ctrl; - uint8_t reg_3df; + uint8_t emulation; /* Which display are we emulating? */ + uint8_t dipswitches; /* DIP switches 1-3 */ + uint8_t crtc_index; /* CRTC index readback + * Bit 7: CGA control port written + * Bit 6: Operation control port written + * Bit 5: CRTC register written + * Bits 0-4: Last CRTC register selected */ + uint8_t operation_ctrl; + uint8_t reg_3df; } pc200_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 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}; /* LCD colour mappings - * + * * 0 => solid green * 1 => blue on green * 2 => green on blue * 3 => solid blue */ -static unsigned char mapping1[256] = - { -/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ -/*00*/ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -/*10*/ 2, 0, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, -/*20*/ 2, 2, 0, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, -/*30*/ 2, 2, 2, 0, 2, 2, 1, 1, 2, 2, 2, 1, 2, 2, 1, 1, -/*40*/ 2, 2, 1, 1, 0, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, -/*50*/ 2, 2, 1, 1, 2, 0, 1, 1, 2, 2, 1, 1, 2, 1, 1, 1, -/*60*/ 2, 2, 2, 2, 2, 2, 0, 1, 2, 2, 2, 2, 2, 2, 1, 1, -/*70*/ 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, -/*80*/ 2, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, -/*90*/ 2, 2, 1, 1, 1, 1, 1, 1, 2, 0, 1, 1, 1, 1, 1, 1, -/*A0*/ 2, 2, 2, 1, 2, 2, 1, 1, 2, 2, 0, 1, 2, 2, 1, 1, -/*B0*/ 2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 0, 2, 2, 1, 1, -/*C0*/ 2, 2, 1, 1, 2, 1, 1, 1, 2, 2, 1, 1, 0, 1, 1, 1, -/*D0*/ 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 0, 1, 1, -/*E0*/ 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 0, 1, -/*F0*/ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, - }; +static unsigned char mapping1[256] = { + /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ + /*00*/ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + /*10*/ 2, 0, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, + /*20*/ 2, 2, 0, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, + /*30*/ 2, 2, 2, 0, 2, 2, 1, 1, 2, 2, 2, 1, 2, 2, 1, 1, + /*40*/ 2, 2, 1, 1, 0, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, + /*50*/ 2, 2, 1, 1, 2, 0, 1, 1, 2, 2, 1, 1, 2, 1, 1, 1, + /*60*/ 2, 2, 2, 2, 2, 2, 0, 1, 2, 2, 2, 2, 2, 2, 1, 1, + /*70*/ 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, + /*80*/ 2, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, + /*90*/ 2, 2, 1, 1, 1, 1, 1, 1, 2, 0, 1, 1, 1, 1, 1, 1, + /*A0*/ 2, 2, 2, 1, 2, 2, 1, 1, 2, 2, 0, 1, 2, 2, 1, 1, + /*B0*/ 2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 0, 2, 2, 1, 1, + /*C0*/ 2, 2, 1, 1, 2, 1, 1, 1, 2, 2, 1, 1, 0, 1, 1, 1, + /*D0*/ 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 0, 1, 1, + /*E0*/ 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 0, 1, + /*F0*/ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, +}; -static unsigned char mapping2[256] = - { -/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ -/*00*/ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -/*10*/ 1, 3, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, -/*20*/ 1, 1, 3, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, -/*30*/ 1, 1, 1, 3, 1, 1, 2, 2, 1, 1, 1, 2, 1, 1, 2, 2, -/*40*/ 1, 1, 2, 2, 3, 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, -/*50*/ 1, 1, 2, 2, 1, 3, 2, 2, 1, 1, 2, 2, 1, 2, 2, 2, -/*60*/ 1, 1, 1, 1, 1, 1, 3, 2, 1, 1, 1, 1, 1, 1, 2, 2, -/*70*/ 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 2, -/*80*/ 2, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, -/*90*/ 1, 1, 2, 2, 2, 2, 2, 2, 1, 3, 2, 2, 2, 2, 2, 2, -/*A0*/ 1, 1, 1, 2, 1, 1, 2, 2, 1, 1, 3, 2, 1, 1, 2, 2, -/*B0*/ 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 3, 1, 1, 2, 2, -/*C0*/ 1, 1, 2, 2, 1, 2, 2, 2, 1, 1, 2, 2, 3, 2, 2, 2, -/*D0*/ 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 3, 2, 2, -/*E0*/ 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 3, 2, -/*F0*/ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, - }; +static unsigned char mapping2[256] = { + /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ + /*00*/ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + /*10*/ 1, 3, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, + /*20*/ 1, 1, 3, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, + /*30*/ 1, 1, 1, 3, 1, 1, 2, 2, 1, 1, 1, 2, 1, 1, 2, 2, + /*40*/ 1, 1, 2, 2, 3, 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, + /*50*/ 1, 1, 2, 2, 1, 3, 2, 2, 1, 1, 2, 2, 1, 2, 2, 2, + /*60*/ 1, 1, 1, 1, 1, 1, 3, 2, 1, 1, 1, 1, 1, 1, 2, 2, + /*70*/ 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 2, + /*80*/ 2, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, + /*90*/ 1, 1, 2, 2, 2, 2, 2, 2, 1, 3, 2, 2, 2, 2, 2, 2, + /*A0*/ 1, 1, 1, 2, 1, 1, 2, 2, 1, 1, 3, 2, 1, 1, 2, 2, + /*B0*/ 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 3, 1, 1, 2, 2, + /*C0*/ 1, 1, 2, 2, 1, 2, 2, 2, 1, 1, 2, 2, 3, 2, 2, 2, + /*D0*/ 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 3, 2, 2, + /*E0*/ 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 3, 2, + /*F0*/ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, +}; static void set_lcd_cols(uint8_t mode_reg) { - unsigned char *mapping = (mode_reg & 0x80) ? mapping2 : mapping1; - int c; + unsigned char *mapping = (mode_reg & 0x80) ? mapping2 : mapping1; + int c; - for (c = 0; c < 256; c++) { - switch (mapping[c]) { - case 0:lcdcols[c][0][0] = lcdcols[c][1][0] = green; - lcdcols[c][0][1] = lcdcols[c][1][1] = green; - break; + for (c = 0; c < 256; c++) { + switch (mapping[c]) { + case 0: + lcdcols[c][0][0] = lcdcols[c][1][0] = green; + lcdcols[c][0][1] = lcdcols[c][1][1] = green; + break; - case 1: - lcdcols[c][0][0] = lcdcols[c][1][0] = - lcdcols[c][1][1] = green; - lcdcols[c][0][1] = blue; - break; + case 1: + lcdcols[c][0][0] = lcdcols[c][1][0] = lcdcols[c][1][1] = green; + lcdcols[c][0][1] = blue; + break; - case 2: - lcdcols[c][0][0] = lcdcols[c][1][0] = - lcdcols[c][1][1] = blue; - lcdcols[c][0][1] = green; - break; + case 2: + lcdcols[c][0][0] = lcdcols[c][1][0] = lcdcols[c][1][1] = blue; + lcdcols[c][0][1] = green; + break; - case 3:lcdcols[c][0][0] = lcdcols[c][1][0] = blue; - lcdcols[c][0][1] = lcdcols[c][1][1] = blue; - break; - } - } + case 3: + lcdcols[c][0][0] = lcdcols[c][1][0] = blue; + lcdcols[c][0][1] = lcdcols[c][1][1] = blue; + break; + } + } } void pc200_out(uint16_t addr, uint8_t val, void *p) { - pc200_t *pc200 = (pc200_t *)p; - cga_t *cga = &pc200->cga; - mda_t *mda = &pc200->mda; - uint8_t old; + pc200_t *pc200 = (pc200_t *)p; + cga_t *cga = &pc200->cga; + mda_t *mda = &pc200->mda; + uint8_t old; - PC200LOG(("pc200_out(0x%04x), %02x\n", addr, val)); + PC200LOG(("pc200_out(0x%04x), %02x\n", addr, val)); -/* MDA writes ============================================================== */ - switch (addr) { - case 0x3b1: - case 0x3b3: - case 0x3b5: - case 0x3b7: + /* MDA writes ============================================================== */ + switch (addr) { + case 0x3b1: + case 0x3b3: + case 0x3b5: + case 0x3b7: - /* Writes banned to CRTC registers 0-11? */ - if (!(pc200->operation_ctrl & 0x40) && mda->crtcreg <= 11) { - pc200->crtc_index = 0x20 | (mda->crtcreg & 0x1f); - if (pc200->operation_ctrl & 0x80) { - PC200LOG(("NMI raised from CRTC register access: reg=0x%02x val=0x%02x nmi_mask=%d\n", mda->crtcreg & 0x1F, val, nmi_mask)); - nmi = 1; - } - pc200->reg_3df = val; - return; - } - PC200LOG(("CRTM[%02x]:=%02x\n", mda->crtcreg, val)); - old = mda->crtc[mda->crtcreg]; - mda->crtc[mda->crtcreg] = val & crtcmask[mda->crtcreg]; - if (old != val) { - if (mda->crtcreg < 0xe || mda->crtcreg > 0x10) { - fullchange = changeframecount; - mda_recalctimings(mda); - } - } - return; + /* Writes banned to CRTC registers 0-11? */ + if (!(pc200->operation_ctrl & 0x40) && mda->crtcreg <= 11) { + pc200->crtc_index = 0x20 | (mda->crtcreg & 0x1f); + if (pc200->operation_ctrl & 0x80) { + PC200LOG(("NMI raised from CRTC register access: reg=0x%02x val=0x%02x nmi_mask=%d\n", + mda->crtcreg & 0x1F, val, nmi_mask)); + nmi = 1; + } + pc200->reg_3df = val; + return; + } + PC200LOG(("CRTM[%02x]:=%02x\n", mda->crtcreg, val)); + old = mda->crtc[mda->crtcreg]; + mda->crtc[mda->crtcreg] = val & crtcmask[mda->crtcreg]; + if (old != val) { + if (mda->crtcreg < 0xe || mda->crtcreg > 0x10) { + fullchange = changeframecount; + mda_recalctimings(mda); + } + } + return; - case 0x3b8:old = mda->ctrl; - mda->ctrl = val; - if ((mda->ctrl ^ old) & 3) { - mda_recalctimings(mda); - } - pc200->crtc_index &= 0x1F; - pc200->crtc_index |= 0x80; - if (pc200->operation_ctrl & 0x80) { - PC200LOG(("NMI raised from mode control access: val=0x%02x nmi_mask=%d\n", val, nmi_mask)); - nmi = 1; - } - return; + case 0x3b8: + old = mda->ctrl; + mda->ctrl = val; + if ((mda->ctrl ^ old) & 3) { + mda_recalctimings(mda); + } + pc200->crtc_index &= 0x1F; + pc200->crtc_index |= 0x80; + if (pc200->operation_ctrl & 0x80) { + PC200LOG(("NMI raised from mode control access: val=0x%02x nmi_mask=%d\n", val, nmi_mask)); + nmi = 1; + } + return; + /* CGA writes ============================================================== */ + case 0x3d1: + case 0x3d3: + case 0x3d5: + case 0x3d7: -/* CGA writes ============================================================== */ - case 0x3d1: - case 0x3d3: - case 0x3d5: - case 0x3d7: + /* Writes banned to CRTC registers 0-11? */ + if (!(pc200->operation_ctrl & 0x40) && cga->crtcreg <= 11) { + pc200->crtc_index = 0x20 | (cga->crtcreg & 0x1f); + if (pc200->operation_ctrl & 0x80) { + PC200LOG(("NMI raised from CRTC register access: reg=0x%02x val=0x%02x nmi_mask=%d\n", + cga->crtcreg & 0x1F, val, nmi_mask)); + nmi = 1; + } + pc200->reg_3df = val; + return; + } + PC200LOG(("CRTC[%02x]:=%02x\n", cga->crtcreg, val)); + old = cga->crtc[cga->crtcreg]; + cga->crtc[cga->crtcreg] = val & crtcmask[cga->crtcreg]; + if (old != val) { + if (cga->crtcreg < 0xe || cga->crtcreg > 0x10) { + fullchange = changeframecount; + cga_recalctimings(cga); + } + } + return; - /* Writes banned to CRTC registers 0-11? */ - if (!(pc200->operation_ctrl & 0x40) && cga->crtcreg <= 11) { - pc200->crtc_index = 0x20 | (cga->crtcreg & 0x1f); - if (pc200->operation_ctrl & 0x80) { - PC200LOG(("NMI raised from CRTC register access: reg=0x%02x val=0x%02x nmi_mask=%d\n", cga->crtcreg & 0x1F, val, nmi_mask)); - nmi = 1; - } - pc200->reg_3df = val; - return; - } - PC200LOG(("CRTC[%02x]:=%02x\n", cga->crtcreg, val)); - old = cga->crtc[cga->crtcreg]; - cga->crtc[cga->crtcreg] = val & crtcmask[cga->crtcreg]; - if (old != val) { - if (cga->crtcreg < 0xe || cga->crtcreg > 0x10) { - fullchange = changeframecount; - cga_recalctimings(cga); - } - } - return; + case 0x3d8: + old = cga->cgamode; + cga->cgamode = val; + if ((cga->cgamode ^ old) & 3) { + cga_recalctimings(cga); + } + pc200->crtc_index &= 0x1F; + pc200->crtc_index |= 0x80; + if (pc200->operation_ctrl & 0x80) { + PC200LOG(("NMI raised from mode control access: val=0x%02x nmi_mask=%d\n", val, nmi_mask)); + nmi = 1; + } else + set_lcd_cols(val); + return; - case 0x3d8:old = cga->cgamode; - cga->cgamode = val; - if ((cga->cgamode ^ old) & 3) { - cga_recalctimings(cga); - } - pc200->crtc_index &= 0x1F; - pc200->crtc_index |= 0x80; - if (pc200->operation_ctrl & 0x80) { - PC200LOG(("NMI raised from mode control access: val=0x%02x nmi_mask=%d\n", val, nmi_mask)); - nmi = 1; - } else - set_lcd_cols(val); - return; + /* PC200 control port writes ============================================== */ + case 0x3de: + pc200->crtc_index = 0x1f; + /* NMI only seems to be triggered if the value being written has the high + * bit set (enable NMI). So it only protects writes to this port if you + * let it? */ + if (val & 0x80) { + PC200LOG(("NMI raised from operation control access: val=0x%02x nmi_mask=%d\n", val, nmi_mask)); + pc200->operation_ctrl = val; + pc200->crtc_index |= 0x40; + nmi = 1; + return; + } + timer_disable(&pc200->cga.timer); + timer_disable(&pc200->mda.timer); + timer_disable(&pc200->timer); + pc200->operation_ctrl = val; + /* Bits 0 and 1 control emulation and output mode */ + if (val & 1) /* Monitor */ + { + pc200->emulation = (val & 2) ? PC200_MDA : PC200_CGA; + } else if (romset == ROM_PPC512) { + pc200->emulation = (val & 2) ? PC200_LCDM : PC200_LCDC; + } else { + pc200->emulation = PC200_TV; + } + PC200LOG(("Video emulation set to %d\n", pc200->emulation)); + if (pc200->emulation == PC200_CGA || pc200->emulation == PC200_TV) + timer_advance_u64(&pc200->cga.timer, 1); + else if (pc200->emulation == PC200_MDA) + timer_advance_u64(&pc200->mda.timer, 1); + else + timer_advance_u64(&pc200->timer, 1); -/* PC200 control port writes ============================================== */ - case 0x3de:pc200->crtc_index = 0x1f; -/* NMI only seems to be triggered if the value being written has the high - * bit set (enable NMI). So it only protects writes to this port if you - * let it? */ - if (val & 0x80) { - PC200LOG(("NMI raised from operation control access: val=0x%02x nmi_mask=%d\n", val, nmi_mask)); - pc200->operation_ctrl = val; - pc200->crtc_index |= 0x40; - nmi = 1; - return; - } - timer_disable(&pc200->cga.timer); - timer_disable(&pc200->mda.timer); - timer_disable(&pc200->timer); - pc200->operation_ctrl = val; - /* Bits 0 and 1 control emulation and output mode */ - if (val & 1) /* Monitor */ - { - pc200->emulation = (val & 2) ? PC200_MDA : PC200_CGA; - } else if (romset == ROM_PPC512) { - pc200->emulation = (val & 2) ? PC200_LCDM : PC200_LCDC; - } else { - pc200->emulation = PC200_TV; + /* Bit 2 disables the IDA. We don't support dynamic enabling + * and disabling of the IDA (instead, PCEM disconnects the + * IDA from the bus altogether) so don't implement this */ - } - PC200LOG(("Video emulation set to %d\n", pc200->emulation)); - if (pc200->emulation == PC200_CGA || pc200->emulation == PC200_TV) - timer_advance_u64(&pc200->cga.timer, 1); - else if (pc200->emulation == PC200_MDA) - timer_advance_u64(&pc200->mda.timer, 1); - else - timer_advance_u64(&pc200->timer, 1); - - /* Bit 2 disables the IDA. We don't support dynamic enabling - * and disabling of the IDA (instead, PCEM disconnects the - * IDA from the bus altogether) so don't implement this */ - - /* Enable the appropriate memory ranges depending whether - * the IDA is configured as MDA or CGA */ - if (pc200->emulation == PC200_MDA || - pc200->emulation == PC200_LCDM) { - mem_mapping_disable(&pc200->cga_mapping); - mem_mapping_enable(&pc200->mda_mapping); - } else { - mem_mapping_disable(&pc200->mda_mapping); - mem_mapping_enable(&pc200->cga_mapping); - } - return; - } - if (addr >= 0x3D0 && addr <= 0x3DF) { - cga_out(addr, val, cga); - } - if (addr >= 0x3B0 && addr <= 0x3BB) { - mda_out(addr, val, mda); - } + /* Enable the appropriate memory ranges depending whether + * the IDA is configured as MDA or CGA */ + if (pc200->emulation == PC200_MDA || pc200->emulation == PC200_LCDM) { + mem_mapping_disable(&pc200->cga_mapping); + mem_mapping_enable(&pc200->mda_mapping); + } else { + mem_mapping_disable(&pc200->mda_mapping); + mem_mapping_enable(&pc200->cga_mapping); + } + return; + } + if (addr >= 0x3D0 && addr <= 0x3DF) { + cga_out(addr, val, cga); + } + if (addr >= 0x3B0 && addr <= 0x3BB) { + mda_out(addr, val, mda); + } } uint8_t pc200_in(uint16_t addr, void *p) { - pc200_t *pc200 = (pc200_t *)p; - cga_t *cga = &pc200->cga; - mda_t *mda = &pc200->mda; - uint8_t temp; + pc200_t *pc200 = (pc200_t *)p; + cga_t *cga = &pc200->cga; + mda_t *mda = &pc200->mda; + uint8_t temp; - PC200LOG(("pc200_in(0x%04x)\n", addr)); - switch (addr) { - case 0x3B8:PC200LOG((" = %02x\n", mda->ctrl)); - return mda->ctrl; + PC200LOG(("pc200_in(0x%04x)\n", addr)); + switch (addr) { + case 0x3B8: + PC200LOG((" = %02x\n", mda->ctrl)); + return mda->ctrl; - case 0x3D8:PC200LOG((" = %02x\n", cga->cgamode)); - return cga->cgamode; + case 0x3D8: + PC200LOG((" = %02x\n", cga->cgamode)); + return cga->cgamode; - case 0x3DD:temp = pc200->crtc_index; /* Read NMI reason */ - pc200->crtc_index &= 0x1f; /* Reset NMI reason */ - nmi = 0; /* And reset NMI flag */ - PC200LOG((" = %02x\n", temp)); - return temp; + case 0x3DD: + temp = pc200->crtc_index; /* Read NMI reason */ + pc200->crtc_index &= 0x1f; /* Reset NMI reason */ + nmi = 0; /* And reset NMI flag */ + PC200LOG((" = %02x\n", temp)); + return temp; - case 0x3DE:PC200LOG((" = %02x\n", ((pc200->operation_ctrl & 0xc7) | pc200->dipswitches))); - return ((pc200->operation_ctrl & 0xc7) | pc200->dipswitches); + case 0x3DE: + PC200LOG((" = %02x\n", ((pc200->operation_ctrl & 0xc7) | pc200->dipswitches))); + return ((pc200->operation_ctrl & 0xc7) | pc200->dipswitches); - case 0x3DF:return pc200->reg_3df; - } - if (addr >= 0x3D0 && addr <= 0x3DF) { - return cga_in(addr, cga); - } - if (addr >= 0x3B0 && addr <= 0x3BB) { - return mda_in(addr, mda); - } - return 0xFF; + case 0x3DF: + return pc200->reg_3df; + } + if (addr >= 0x3D0 && addr <= 0x3DF) { + return cga_in(addr, cga); + } + if (addr >= 0x3B0 && addr <= 0x3BB) { + return mda_in(addr, mda); + } + return 0xFF; } -void lcd_draw_char_80(pc200_t *pc200, uint32_t *buffer, uint8_t chr, - uint8_t attr, int drawcursor, int blink, int sc, - int mode160, uint8_t control) { - int c; - uint8_t bits = fontdat[chr + pc200->cga.fontbase][sc]; - uint8_t bright = 0; - uint16_t mask; +void lcd_draw_char_80(pc200_t *pc200, uint32_t *buffer, uint8_t chr, uint8_t attr, int drawcursor, int blink, int sc, int mode160, + uint8_t control) { + int c; + uint8_t bits = fontdat[chr + pc200->cga.fontbase][sc]; + uint8_t bright = 0; + uint16_t mask; - if (attr & 8) /* bright */ - { -/* The brightness algorithm appears to be: replace any bit sequence 011 - * with 001 (assuming an extra 0 to the left of the byte). - */ - bright = bits; - for (c = 0, mask = 0x100; c < 7; c++, mask >>= 1) { - if (((bits & mask) == 0) && - ((bits & (mask >> 1)) != 0) && - ((bits & (mask >> 2)) != 0)) { - bright &= ~(mask >> 1); - } - } - bits = bright; - } + if (attr & 8) /* bright */ + { + /* The brightness algorithm appears to be: replace any bit sequence 011 + * with 001 (assuming an extra 0 to the left of the byte). + */ + bright = bits; + for (c = 0, mask = 0x100; c < 7; c++, mask >>= 1) { + if (((bits & mask) == 0) && ((bits & (mask >> 1)) != 0) && ((bits & (mask >> 2)) != 0)) { + bright &= ~(mask >> 1); + } + } + bits = bright; + } - if (drawcursor) - bits ^= 0xFF; + if (drawcursor) + bits ^= 0xFF; - for (c = 0, mask = 0x80; c < 8; c++, mask >>= 1) { - if (mode160) - buffer[c] = (attr & mask) ? blue : green; - else if (control & 0x20) /* blinking */ - buffer[c] = lcdcols[attr & 0x7F][blink][(bits & mask) ? 1 : 0]; - else - buffer[c] = lcdcols[attr][blink][(bits & mask) ? 1 : 0]; - } + for (c = 0, mask = 0x80; c < 8; c++, mask >>= 1) { + if (mode160) + buffer[c] = (attr & mask) ? blue : green; + else if (control & 0x20) /* blinking */ + buffer[c] = lcdcols[attr & 0x7F][blink][(bits & mask) ? 1 : 0]; + else + buffer[c] = lcdcols[attr][blink][(bits & mask) ? 1 : 0]; + } } -void lcd_draw_char_40(pc200_t *pc200, uint32_t *buffer, uint8_t chr, - uint8_t attr, int drawcursor, int blink, int sc, - uint8_t control) { - int c; - uint8_t bits = fontdat[chr + pc200->cga.fontbase][sc]; - uint8_t mask = 0x80; +void lcd_draw_char_40(pc200_t *pc200, uint32_t *buffer, uint8_t chr, uint8_t attr, int drawcursor, int blink, int sc, + uint8_t control) { + int c; + uint8_t bits = fontdat[chr + pc200->cga.fontbase][sc]; + uint8_t mask = 0x80; - if (attr & 8) /* bright */ - { - bits = bits & (bits >> 1); - } - if (drawcursor) - bits ^= 0xFF; + if (attr & 8) /* bright */ + { + bits = bits & (bits >> 1); + } + if (drawcursor) + bits ^= 0xFF; - for (c = 0; c < 8; c++, mask >>= 1) { - if (control & 0x20) { - buffer[c * 2] = buffer[c * 2 + 1] = - lcdcols[attr & 0x7F][blink][(bits & mask) ? 1 : 0]; - } else { - buffer[c * 2] = buffer[c * 2 + 1] = - lcdcols[attr][blink][(bits & mask) ? 1 : 0]; - } - } + for (c = 0; c < 8; c++, mask >>= 1) { + if (control & 0x20) { + buffer[c * 2] = buffer[c * 2 + 1] = lcdcols[attr & 0x7F][blink][(bits & mask) ? 1 : 0]; + } else { + buffer[c * 2] = buffer[c * 2 + 1] = lcdcols[attr][blink][(bits & mask) ? 1 : 0]; + } + } } void lcdm_poll(pc200_t *pc200) { - mda_t *mda = &pc200->mda; - uint16_t ca = (mda->crtc[15] | (mda->crtc[14] << 8)) & 0x3fff; - int drawcursor; - int x; - int oldvc; - uint8_t chr, attr; - int oldsc; - int blink; - if (!mda->linepos) { - timer_advance_u64(&pc200->timer, mda->dispofftime); - mda->stat |= 1; - mda->linepos = 1; - oldsc = mda->sc; - if ((mda->crtc[8] & 3) == 3) - mda->sc = (mda->sc << 1) & 7; - if (mda->dispon) { - if (mda->displine < mda->firstline) { - mda->firstline = mda->displine; - video_wait_for_buffer(); - } - mda->lastline = mda->displine; - for (x = 0; x < mda->crtc[1]; x++) { - chr = mda->vram[(mda->ma << 1) & 0xfff]; - attr = mda->vram[((mda->ma << 1) + 1) & 0xfff]; - drawcursor = ((mda->ma == ca) && mda->con && mda->cursoron); - blink = ((mda->blink & 16) && (mda->ctrl & 0x20) && (attr & 0x80) && !drawcursor); + mda_t *mda = &pc200->mda; + uint16_t ca = (mda->crtc[15] | (mda->crtc[14] << 8)) & 0x3fff; + int drawcursor; + int x; + int oldvc; + uint8_t chr, attr; + int oldsc; + int blink; + if (!mda->linepos) { + timer_advance_u64(&pc200->timer, mda->dispofftime); + mda->stat |= 1; + mda->linepos = 1; + oldsc = mda->sc; + if ((mda->crtc[8] & 3) == 3) + mda->sc = (mda->sc << 1) & 7; + if (mda->dispon) { + if (mda->displine < mda->firstline) { + mda->firstline = mda->displine; + video_wait_for_buffer(); + } + mda->lastline = mda->displine; + for (x = 0; x < mda->crtc[1]; x++) { + chr = mda->vram[(mda->ma << 1) & 0xfff]; + attr = mda->vram[((mda->ma << 1) + 1) & 0xfff]; + drawcursor = ((mda->ma == ca) && mda->con && mda->cursoron); + blink = ((mda->blink & 16) && (mda->ctrl & 0x20) && (attr & 0x80) && !drawcursor); - lcd_draw_char_80(pc200, &((uint32_t *)(buffer32->line[mda->displine]))[x * 8], chr, attr, drawcursor, blink, mda->sc, 0, mda->ctrl); - mda->ma++; - } - } - mda->sc = oldsc; - if (mda->vc == mda->crtc[7] && !mda->sc) { - mda->stat |= 8; -// printf("VSYNC on %i %i\n",vc,sc); - } - mda->displine++; - if (mda->displine >= 500) - mda->displine = 0; - } else { - timer_advance_u64(&pc200->timer, mda->dispontime); - if (mda->dispon) - mda->stat &= ~1; - mda->linepos = 0; - if (mda->vsynctime) { - mda->vsynctime--; - if (!mda->vsynctime) { - mda->stat &= ~8; -// printf("VSYNC off %i %i\n",vc,sc); - } - } - if (mda->sc == (mda->crtc[11] & 31) || ((mda->crtc[8] & 3) == 3 && mda->sc == ((mda->crtc[11] & 31) >> 1))) { - mda->con = 0; - mda->coff = 1; - } - if (mda->vadj) { - mda->sc++; - mda->sc &= 31; - mda->ma = mda->maback; - mda->vadj--; - if (!mda->vadj) { - mda->dispon = 1; - mda->ma = mda->maback = (mda->crtc[13] | (mda->crtc[12] << 8)) & 0x3fff; - mda->sc = 0; - } - } else if (mda->sc == mda->crtc[9] || ((mda->crtc[8] & 3) == 3 && mda->sc == (mda->crtc[9] >> 1))) { - mda->maback = mda->ma; - mda->sc = 0; - oldvc = mda->vc; - mda->vc++; - mda->vc &= 127; - if (mda->vc == mda->crtc[6]) - mda->dispon = 0; - if (oldvc == mda->crtc[4]) { -// printf("Display over at %i\n",displine); - mda->vc = 0; - mda->vadj = mda->crtc[5]; - if (!mda->vadj) - mda->dispon = 1; - if (!mda->vadj) - mda->ma = mda->maback = (mda->crtc[13] | (mda->crtc[12] << 8)) & 0x3fff; - if ((mda->crtc[10] & 0x60) == 0x20) - mda->cursoron = 0; - else - mda->cursoron = mda->blink & 16; - } - if (mda->vc == mda->crtc[7]) { - mda->dispon = 0; - mda->displine = 0; - mda->vsynctime = 16; - if (mda->crtc[7]) { -// printf("Lastline %i Firstline %i %i\n",lastline,firstline,lastline-firstline); - x = mda->crtc[1] * 8; - mda->lastline++; - if (x != xsize || (mda->lastline - mda->firstline) != ysize) { - xsize = x; - ysize = mda->lastline - mda->firstline; -// printf("Resize to %i,%i - R1 %i\n",xsize,ysize,crtcm[1]); - if (xsize < 64) - xsize = 656; - if (ysize < 32) - ysize = 200; - updatewindowsize(xsize, ysize << 1); - } + lcd_draw_char_80(pc200, &((uint32_t *)(buffer32->line[mda->displine]))[x * 8], chr, attr, + drawcursor, blink, mda->sc, 0, mda->ctrl); + mda->ma++; + } + } + mda->sc = oldsc; + if (mda->vc == mda->crtc[7] && !mda->sc) { + mda->stat |= 8; + // printf("VSYNC on %i %i\n",vc,sc); + } + mda->displine++; + if (mda->displine >= 500) + mda->displine = 0; + } else { + timer_advance_u64(&pc200->timer, mda->dispontime); + if (mda->dispon) + mda->stat &= ~1; + mda->linepos = 0; + if (mda->vsynctime) { + mda->vsynctime--; + if (!mda->vsynctime) { + mda->stat &= ~8; + // printf("VSYNC off %i %i\n",vc,sc); + } + } + if (mda->sc == (mda->crtc[11] & 31) || ((mda->crtc[8] & 3) == 3 && mda->sc == ((mda->crtc[11] & 31) >> 1))) { + mda->con = 0; + mda->coff = 1; + } + if (mda->vadj) { + mda->sc++; + mda->sc &= 31; + mda->ma = mda->maback; + mda->vadj--; + if (!mda->vadj) { + mda->dispon = 1; + mda->ma = mda->maback = (mda->crtc[13] | (mda->crtc[12] << 8)) & 0x3fff; + mda->sc = 0; + } + } else if (mda->sc == mda->crtc[9] || ((mda->crtc[8] & 3) == 3 && mda->sc == (mda->crtc[9] >> 1))) { + mda->maback = mda->ma; + mda->sc = 0; + oldvc = mda->vc; + mda->vc++; + mda->vc &= 127; + if (mda->vc == mda->crtc[6]) + mda->dispon = 0; + if (oldvc == mda->crtc[4]) { + // printf("Display over at %i\n",displine); + mda->vc = 0; + mda->vadj = mda->crtc[5]; + if (!mda->vadj) + mda->dispon = 1; + if (!mda->vadj) + mda->ma = mda->maback = (mda->crtc[13] | (mda->crtc[12] << 8)) & 0x3fff; + if ((mda->crtc[10] & 0x60) == 0x20) + mda->cursoron = 0; + else + mda->cursoron = mda->blink & 16; + } + if (mda->vc == mda->crtc[7]) { + mda->dispon = 0; + mda->displine = 0; + mda->vsynctime = 16; + if (mda->crtc[7]) { + // printf("Lastline %i Firstline %i + // %i\n",lastline,firstline,lastline-firstline); + x = mda->crtc[1] * 8; + mda->lastline++; + if (x != xsize || (mda->lastline - mda->firstline) != ysize) { + xsize = x; + ysize = mda->lastline - mda->firstline; + // printf("Resize to %i,%i - R1 + // %i\n",xsize,ysize,crtcm[1]); + if (xsize < 64) + xsize = 656; + if (ysize < 32) + ysize = 200; + updatewindowsize(xsize, ysize << 1); + } - video_blit_memtoscreen(0, mda->firstline, 0, ysize, xsize, ysize); + video_blit_memtoscreen(0, mda->firstline, 0, ysize, xsize, ysize); - frames++; - video_res_x = mda->crtc[1]; - video_res_y = mda->crtc[6]; - video_bpp = 0; - } - mda->firstline = 1000; - mda->lastline = 0; - mda->blink++; - } - } else { - mda->sc++; - mda->sc &= 31; - mda->ma = mda->maback; - } - if ((mda->sc == (mda->crtc[10] & 31) || ((mda->crtc[8] & 3) == 3 && mda->sc == ((mda->crtc[10] & 31) >> 1)))) { - mda->con = 1; -// printf("Cursor on - %02X %02X %02X\n",crtcm[8],crtcm[10],crtcm[11]); - } - } + frames++; + video_res_x = mda->crtc[1]; + video_res_y = mda->crtc[6]; + video_bpp = 0; + } + mda->firstline = 1000; + mda->lastline = 0; + mda->blink++; + } + } else { + mda->sc++; + mda->sc &= 31; + mda->ma = mda->maback; + } + if ((mda->sc == (mda->crtc[10] & 31) || ((mda->crtc[8] & 3) == 3 && mda->sc == ((mda->crtc[10] & 31) >> 1)))) { + mda->con = 1; + // printf("Cursor on - %02X %02X %02X\n",crtcm[8],crtcm[10],crtcm[11]); + } + } } void lcdc_poll(pc200_t *pc200) { - cga_t *cga = &pc200->cga; - int drawcursor; - int x, c; - int oldvc; - uint8_t chr, attr; - uint16_t dat; - int oldsc; - uint16_t ca; - int blink; + cga_t *cga = &pc200->cga; + int drawcursor; + int x, c; + int oldvc; + uint8_t chr, attr; + uint16_t dat; + int oldsc; + uint16_t ca; + int blink; - ca = (cga->crtc[15] | (cga->crtc[14] << 8)) & 0x3fff; + ca = (cga->crtc[15] | (cga->crtc[14] << 8)) & 0x3fff; - if (!cga->linepos) { - timer_advance_u64(&pc200->timer, cga->dispofftime); - cga->cgastat |= 1; - cga->linepos = 1; - oldsc = cga->sc; - if ((cga->crtc[8] & 3) == 3) - cga->sc = ((cga->sc << 1) + cga->oddeven) & 7; - if (cga->cgadispon) { - if (cga->displine < cga->firstline) { - cga->firstline = cga->displine; - video_wait_for_buffer(); -// printf("Firstline %i\n",firstline); - } - cga->lastline = cga->displine; + if (!cga->linepos) { + timer_advance_u64(&pc200->timer, cga->dispofftime); + cga->cgastat |= 1; + cga->linepos = 1; + oldsc = cga->sc; + if ((cga->crtc[8] & 3) == 3) + cga->sc = ((cga->sc << 1) + cga->oddeven) & 7; + if (cga->cgadispon) { + if (cga->displine < cga->firstline) { + cga->firstline = cga->displine; + video_wait_for_buffer(); + // printf("Firstline %i\n",firstline); + } + cga->lastline = cga->displine; - if (cga->cgamode & 1) { - for (x = 0; x < cga->crtc[1]; x++) { - chr = cga->charbuffer[x << 1]; - attr = cga->charbuffer[(x << 1) + 1]; - drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron); - blink = ((cga->cgablink & 16) && (cga->cgamode & 0x20) && (attr & 0x80) && !drawcursor); - lcd_draw_char_80(pc200, &((uint32_t *)(buffer32->line[cga->displine]))[x * 8], chr, attr, drawcursor, blink, cga->sc, cga->cgamode & 0x40, cga->cgamode); - cga->ma++; - } - } else if (!(cga->cgamode & 2)) { - for (x = 0; x < cga->crtc[1]; x++) { - chr = cga->vram[((cga->ma << 1) & 0x3fff)]; - attr = cga->vram[(((cga->ma << 1) + 1) & 0x3fff)]; - drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron); - blink = ((cga->cgablink & 16) && (cga->cgamode & 0x20) && (attr & 0x80) && !drawcursor); - lcd_draw_char_40(pc200, &((uint32_t *)(buffer32->line[cga->displine]))[x * 16], chr, attr, drawcursor, blink, cga->sc, cga->cgamode); - cga->ma++; - } - } else /* Graphics mode */ - { - for (x = 0; x < cga->crtc[1]; x++) { - dat = (cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000)] << 8) | cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000) + 1]; - cga->ma++; - for (c = 0; c < 16; c++) { - ((uint32_t *)buffer32->line[cga->displine])[(x << 4) + c] = (dat & 0x8000) ? blue : green; - dat <<= 1; - } - } - } - } else { - if (cga->cgamode & 1) - hline(buffer32, 0, cga->displine, (cga->crtc[1] << 3), green); - else - hline(buffer32, 0, cga->displine, (cga->crtc[1] << 4), green); - } + if (cga->cgamode & 1) { + for (x = 0; x < cga->crtc[1]; x++) { + chr = cga->charbuffer[x << 1]; + attr = cga->charbuffer[(x << 1) + 1]; + drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron); + blink = ((cga->cgablink & 16) && (cga->cgamode & 0x20) && (attr & 0x80) && !drawcursor); + lcd_draw_char_80(pc200, &((uint32_t *)(buffer32->line[cga->displine]))[x * 8], chr, attr, + drawcursor, blink, cga->sc, cga->cgamode & 0x40, cga->cgamode); + cga->ma++; + } + } else if (!(cga->cgamode & 2)) { + for (x = 0; x < cga->crtc[1]; x++) { + chr = cga->vram[((cga->ma << 1) & 0x3fff)]; + attr = cga->vram[(((cga->ma << 1) + 1) & 0x3fff)]; + drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron); + blink = ((cga->cgablink & 16) && (cga->cgamode & 0x20) && (attr & 0x80) && !drawcursor); + lcd_draw_char_40(pc200, &((uint32_t *)(buffer32->line[cga->displine]))[x * 16], chr, attr, + drawcursor, blink, cga->sc, cga->cgamode); + cga->ma++; + } + } else /* Graphics mode */ + { + for (x = 0; x < cga->crtc[1]; x++) { + dat = (cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000)] << 8) | + cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000) + 1]; + cga->ma++; + for (c = 0; c < 16; c++) { + ((uint32_t *)buffer32->line[cga->displine])[(x << 4) + c] = + (dat & 0x8000) ? blue : green; + dat <<= 1; + } + } + } + } else { + if (cga->cgamode & 1) + hline(buffer32, 0, cga->displine, (cga->crtc[1] << 3), green); + else + hline(buffer32, 0, cga->displine, (cga->crtc[1] << 4), green); + } - if (cga->cgamode & 1) - x = (cga->crtc[1] << 3); - else - x = (cga->crtc[1] << 4); + if (cga->cgamode & 1) + x = (cga->crtc[1] << 3); + else + x = (cga->crtc[1] << 4); - cga->sc = oldsc; - if (cga->vc == cga->crtc[7] && !cga->sc) - cga->cgastat |= 8; - cga->displine++; - if (cga->displine >= 360) - cga->displine = 0; - } else { - timer_advance_u64(&pc200->timer, cga->dispontime); - cga->linepos = 0; - if (cga->vsynctime) { - cga->vsynctime--; - if (!cga->vsynctime) - cga->cgastat &= ~8; - } - if (cga->sc == (cga->crtc[11] & 31) || ((cga->crtc[8] & 3) == 3 && cga->sc == ((cga->crtc[11] & 31) >> 1))) { - cga->con = 0; - cga->coff = 1; - } - if ((cga->crtc[8] & 3) == 3 && cga->sc == (cga->crtc[9] >> 1)) - cga->maback = cga->ma; - if (cga->vadj) { - cga->sc++; - cga->sc &= 31; - cga->ma = cga->maback; - cga->vadj--; - if (!cga->vadj) { - cga->cgadispon = 1; - cga->ma = cga->maback = (cga->crtc[13] | (cga->crtc[12] << 8)) & 0x3fff; - cga->sc = 0; - } - } else if (cga->sc == cga->crtc[9]) { - cga->maback = cga->ma; - cga->sc = 0; - oldvc = cga->vc; - cga->vc++; - cga->vc &= 127; + cga->sc = oldsc; + if (cga->vc == cga->crtc[7] && !cga->sc) + cga->cgastat |= 8; + cga->displine++; + if (cga->displine >= 360) + cga->displine = 0; + } else { + timer_advance_u64(&pc200->timer, cga->dispontime); + cga->linepos = 0; + if (cga->vsynctime) { + cga->vsynctime--; + if (!cga->vsynctime) + cga->cgastat &= ~8; + } + if (cga->sc == (cga->crtc[11] & 31) || ((cga->crtc[8] & 3) == 3 && cga->sc == ((cga->crtc[11] & 31) >> 1))) { + cga->con = 0; + cga->coff = 1; + } + if ((cga->crtc[8] & 3) == 3 && cga->sc == (cga->crtc[9] >> 1)) + cga->maback = cga->ma; + if (cga->vadj) { + cga->sc++; + cga->sc &= 31; + cga->ma = cga->maback; + cga->vadj--; + if (!cga->vadj) { + cga->cgadispon = 1; + cga->ma = cga->maback = (cga->crtc[13] | (cga->crtc[12] << 8)) & 0x3fff; + cga->sc = 0; + } + } else if (cga->sc == cga->crtc[9]) { + cga->maback = cga->ma; + cga->sc = 0; + oldvc = cga->vc; + cga->vc++; + cga->vc &= 127; - if (cga->vc == cga->crtc[6]) - cga->cgadispon = 0; + if (cga->vc == cga->crtc[6]) + cga->cgadispon = 0; - if (oldvc == cga->crtc[4]) { - cga->vc = 0; - cga->vadj = cga->crtc[5]; - if (!cga->vadj) - cga->cgadispon = 1; - if (!cga->vadj) - cga->ma = cga->maback = (cga->crtc[13] | (cga->crtc[12] << 8)) & 0x3fff; - if ((cga->crtc[10] & 0x60) == 0x20) - cga->cursoron = 0; - else - cga->cursoron = cga->cgablink & 8; - } + if (oldvc == cga->crtc[4]) { + cga->vc = 0; + cga->vadj = cga->crtc[5]; + if (!cga->vadj) + cga->cgadispon = 1; + if (!cga->vadj) + cga->ma = cga->maback = (cga->crtc[13] | (cga->crtc[12] << 8)) & 0x3fff; + if ((cga->crtc[10] & 0x60) == 0x20) + cga->cursoron = 0; + else + cga->cursoron = cga->cgablink & 8; + } - if (cga->vc == cga->crtc[7]) { - cga->cgadispon = 0; - cga->displine = 0; - cga->vsynctime = 16; - if (cga->crtc[7]) { - if (cga->cgamode & 1) - x = (cga->crtc[1] << 3); - else - x = (cga->crtc[1] << 4); - cga->lastline++; - if (x != xsize || (cga->lastline - cga->firstline) != ysize) { - xsize = x; - ysize = cga->lastline - cga->firstline; - if (xsize < 64) - xsize = 656; - if (ysize < 32) - ysize = 200; - updatewindowsize(xsize, (ysize << 1)); - } + if (cga->vc == cga->crtc[7]) { + cga->cgadispon = 0; + cga->displine = 0; + cga->vsynctime = 16; + if (cga->crtc[7]) { + if (cga->cgamode & 1) + x = (cga->crtc[1] << 3); + else + x = (cga->crtc[1] << 4); + cga->lastline++; + if (x != xsize || (cga->lastline - cga->firstline) != ysize) { + xsize = x; + ysize = cga->lastline - cga->firstline; + if (xsize < 64) + xsize = 656; + if (ysize < 32) + ysize = 200; + updatewindowsize(xsize, (ysize << 1)); + } - video_blit_memtoscreen(0, cga->firstline, 0, (cga->lastline - cga->firstline), xsize, (cga->lastline - cga->firstline)); - frames++; - - video_res_x = xsize - 16; - video_res_y = ysize; - if (cga->cgamode & 1) { - video_res_x /= 8; - video_res_y /= cga->crtc[9] + 1; - video_bpp = 0; - } else if (!(cga->cgamode & 2)) { - video_res_x /= 16; - video_res_y /= cga->crtc[9] + 1; - video_bpp = 0; - } else if (!(cga->cgamode & 16)) { - video_res_x /= 2; - video_bpp = 2; - } else { - video_bpp = 1; - } - } - cga->firstline = 1000; - cga->lastline = 0; - cga->cgablink++; - cga->oddeven ^= 1; - } - } else { - cga->sc++; - cga->sc &= 31; - cga->ma = cga->maback; - } - if (cga->cgadispon) - cga->cgastat &= ~1; - if ((cga->sc == (cga->crtc[10] & 31) || ((cga->crtc[8] & 3) == 3 && cga->sc == ((cga->crtc[10] & 31) >> 1)))) - cga->con = 1; - if (cga->cgadispon && (cga->cgamode & 1)) { - for (x = 0; x < (cga->crtc[1] << 1); x++) - cga->charbuffer[x] = cga->vram[(((cga->ma << 1) + x) & 0x3fff)]; - } - } + video_blit_memtoscreen(0, cga->firstline, 0, (cga->lastline - cga->firstline), xsize, + (cga->lastline - cga->firstline)); + frames++; + video_res_x = xsize - 16; + video_res_y = ysize; + if (cga->cgamode & 1) { + video_res_x /= 8; + video_res_y /= cga->crtc[9] + 1; + video_bpp = 0; + } else if (!(cga->cgamode & 2)) { + video_res_x /= 16; + video_res_y /= cga->crtc[9] + 1; + video_bpp = 0; + } else if (!(cga->cgamode & 16)) { + video_res_x /= 2; + video_bpp = 2; + } else { + video_bpp = 1; + } + } + cga->firstline = 1000; + cga->lastline = 0; + cga->cgablink++; + cga->oddeven ^= 1; + } + } else { + cga->sc++; + cga->sc &= 31; + cga->ma = cga->maback; + } + if (cga->cgadispon) + cga->cgastat &= ~1; + if ((cga->sc == (cga->crtc[10] & 31) || ((cga->crtc[8] & 3) == 3 && cga->sc == ((cga->crtc[10] & 31) >> 1)))) + cga->con = 1; + if (cga->cgadispon && (cga->cgamode & 1)) { + for (x = 0; x < (cga->crtc[1] << 1); x++) + cga->charbuffer[x] = cga->vram[(((cga->ma << 1) + x) & 0x3fff)]; + } + } } void pc200_poll(void *p) { - pc200_t *pc200 = (pc200_t *)p; + pc200_t *pc200 = (pc200_t *)p; - switch (pc200->emulation) { -// case PC200_CGA: -// case PC200_TV: -// pc200->cga.vidtime = pc200->vidtime; -// cga_poll(&pc200->cga); -// pc200->vidtime = pc200->cga.vidtime; -// return; + switch (pc200->emulation) { + // case PC200_CGA: + // case PC200_TV: + // pc200->cga.vidtime = pc200->vidtime; + // cga_poll(&pc200->cga); + // pc200->vidtime = pc200->cga.vidtime; + // return; -// case PC200_MDA: -// pc200->mda.vidtime = pc200->vidtime; -// mda_poll(&pc200->mda); -// pc200->vidtime = pc200->mda.vidtime; -// return; + // case PC200_MDA: + // pc200->mda.vidtime = pc200->vidtime; + // mda_poll(&pc200->mda); + // pc200->vidtime = pc200->mda.vidtime; + // return; - case PC200_LCDM:lcdm_poll(pc200); - return; - case PC200_LCDC:lcdc_poll(pc200); - return; - } + case PC200_LCDM: + lcdm_poll(pc200); + return; + case PC200_LCDC: + lcdc_poll(pc200); + return; + } } void *pc200_init() { - int display_type, contrast; + int display_type, contrast; - pc200_t *pc200 = malloc(sizeof(pc200_t)); + pc200_t *pc200 = malloc(sizeof(pc200_t)); - memset(pc200, 0, sizeof(pc200_t)); + memset(pc200, 0, sizeof(pc200_t)); - pc200->emulation = device_get_config_int("video_emulation"); - display_type = device_get_config_int("display_type"); - contrast = device_get_config_int("contrast"); + pc200->emulation = device_get_config_int("video_emulation"); + display_type = device_get_config_int("display_type"); + contrast = device_get_config_int("contrast"); - /* Default to CGA */ - pc200->dipswitches = 0x10; + /* Default to CGA */ + pc200->dipswitches = 0x10; - /* DIP switches for PC200. Switches 2,3 give video emulation. - * Switch 1 is 'swap floppy drives' (not implemented) */ - if (romset == ROM_PC200) - switch (pc200->emulation) { - case PC200_CGA:pc200->dipswitches = 0x10; - break; - case PC200_MDA:pc200->dipswitches = 0x30; - break; - case PC200_TV:pc200->dipswitches = 0x00; - break; - /* The other combination is 'IDA disabled' (0x20) - see - * amstrad.c */ - } - /* DIP switches for PPC512. Switch 1 is CRT/LCD. Switch 2 - * is MDA / CGA. Switch 3 disables IDA, not implemented. */ - else - switch (pc200->emulation) { - case PC200_CGA:pc200->dipswitches = 0x08; - break; - case PC200_MDA:pc200->dipswitches = 0x18; - break; - case PC200_LCDC:pc200->dipswitches = 0x00; - break; - case PC200_LCDM:pc200->dipswitches = 0x10; - break; - } - /* Flag whether the card is behaving like a CGA or an MDA, so that - * DIP switches are reported correctly */ - pc200_is_mda = (pc200->emulation == PC200_MDA || - pc200->emulation == PC200_LCDM); - PC200LOG(("pc200: DIP switches = %02x\n", pc200->dipswitches)); + /* DIP switches for PC200. Switches 2,3 give video emulation. + * Switch 1 is 'swap floppy drives' (not implemented) */ + if (romset == ROM_PC200) + switch (pc200->emulation) { + case PC200_CGA: + pc200->dipswitches = 0x10; + break; + case PC200_MDA: + pc200->dipswitches = 0x30; + break; + case PC200_TV: + pc200->dipswitches = 0x00; + break; + /* The other combination is 'IDA disabled' (0x20) - see + * amstrad.c */ + } + /* DIP switches for PPC512. Switch 1 is CRT/LCD. Switch 2 + * is MDA / CGA. Switch 3 disables IDA, not implemented. */ + else + switch (pc200->emulation) { + case PC200_CGA: + pc200->dipswitches = 0x08; + break; + case PC200_MDA: + pc200->dipswitches = 0x18; + break; + case PC200_LCDC: + pc200->dipswitches = 0x00; + break; + case PC200_LCDM: + pc200->dipswitches = 0x10; + break; + } + /* Flag whether the card is behaving like a CGA or an MDA, so that + * DIP switches are reported correctly */ + pc200_is_mda = (pc200->emulation == PC200_MDA || pc200->emulation == PC200_LCDM); + PC200LOG(("pc200: DIP switches = %02x\n", pc200->dipswitches)); - pc200->cga.vram = pc200->mda.vram = malloc(0x4000); - cga_init(&pc200->cga); - mda_init(&pc200->mda); + pc200->cga.vram = pc200->mda.vram = malloc(0x4000); + cga_init(&pc200->cga); + mda_init(&pc200->mda); - /* Attribute 8 is white on black (on a real MDA it's black on black) */ - mda_setcol(0x08, 0, 1, 15); - mda_setcol(0x88, 0, 1, 15); - /* Attribute 64 is black on black (on a real MDA it's white on black) */ - mda_setcol(0x40, 0, 1, 0); - mda_setcol(0xC0, 0, 1, 0); + /* Attribute 8 is white on black (on a real MDA it's black on black) */ + mda_setcol(0x08, 0, 1, 15); + mda_setcol(0x88, 0, 1, 15); + /* Attribute 64 is black on black (on a real MDA it's white on black) */ + mda_setcol(0x40, 0, 1, 0); + mda_setcol(0xC0, 0, 1, 0); - pc200->cga.fontbase = (device_get_config_int("codepage") & 3) * 256; + pc200->cga.fontbase = (device_get_config_int("codepage") & 3) * 256; -// pclog("pc200=%p pc200->timer=%p pc200->cga=%p pc200->mda=%p pc200->mda->timer=%p\n", pc200, &pc200->timer, &pc200->cga, &pc200->mda, &pc200->mda->timer); - timer_add(&pc200->timer, pc200_poll, pc200, 1); - mem_mapping_add(&pc200->mda_mapping, 0xb0000, 0x08000, mda_read, NULL, NULL, mda_write, NULL, NULL, NULL, 0, &pc200->mda); - mem_mapping_add(&pc200->cga_mapping, 0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL, 0, &pc200->cga); - io_sethandler(0x03d0, 0x0010, pc200_in, NULL, NULL, pc200_out, NULL, NULL, pc200); - io_sethandler(0x03b0, 0x000c, pc200_in, NULL, NULL, pc200_out, NULL, NULL, pc200); + // pclog("pc200=%p pc200->timer=%p pc200->cga=%p pc200->mda=%p pc200->mda->timer=%p\n", pc200, &pc200->timer, + // &pc200->cga, &pc200->mda, &pc200->mda->timer); + timer_add(&pc200->timer, pc200_poll, pc200, 1); + mem_mapping_add(&pc200->mda_mapping, 0xb0000, 0x08000, mda_read, NULL, NULL, mda_write, NULL, NULL, NULL, 0, &pc200->mda); + mem_mapping_add(&pc200->cga_mapping, 0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL, 0, &pc200->cga); + io_sethandler(0x03d0, 0x0010, pc200_in, NULL, NULL, pc200_out, NULL, NULL, pc200); + io_sethandler(0x03b0, 0x000c, pc200_in, NULL, NULL, pc200_out, NULL, NULL, pc200); - green = makecol(0x1C, 0x71, 0x31); - blue = makecol(0x0f, 0x21, 0x3f); - cgapal_rebuild(display_type, contrast); - set_lcd_cols(0); + green = makecol(0x1C, 0x71, 0x31); + blue = makecol(0x0f, 0x21, 0x3f); + cgapal_rebuild(display_type, contrast); + set_lcd_cols(0); - timer_disable(&pc200->cga.timer); - timer_disable(&pc200->mda.timer); - timer_disable(&pc200->timer); - if (pc200->emulation == PC200_CGA || pc200->emulation == PC200_TV) - timer_enable(&pc200->cga.timer); - else if (pc200->emulation == PC200_MDA) - timer_enable(&pc200->mda.timer); - else - timer_enable(&pc200->timer); + timer_disable(&pc200->cga.timer); + timer_disable(&pc200->mda.timer); + timer_disable(&pc200->timer); + if (pc200->emulation == PC200_CGA || pc200->emulation == PC200_TV) + timer_enable(&pc200->cga.timer); + else if (pc200->emulation == PC200_MDA) + timer_enable(&pc200->mda.timer); + else + timer_enable(&pc200->timer); - return pc200; + return pc200; } void pc200_close(void *p) { - pc200_t *pc200 = (pc200_t *)p; + pc200_t *pc200 = (pc200_t *)p; - free(pc200->cga.vram); - free(pc200); + free(pc200->cga.vram); + free(pc200); } void pc200_speed_changed(void *p) { - pc200_t *pc200 = (pc200_t *)p; + pc200_t *pc200 = (pc200_t *)p; - cga_recalctimings(&pc200->cga); - mda_recalctimings(&pc200->mda); + cga_recalctimings(&pc200->cga); + mda_recalctimings(&pc200->mda); } -device_config_t pc200_config[] = - { - { - .name = "video_emulation", - .description = "Display type", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "CGA monitor", - .value = PC200_CGA, - }, - { - .description = "MDA monitor", - .value = PC200_MDA, - }, - { - .description = "Television", - .value = PC200_TV, - }, - { - .description = "" - } - }, - .default_int = PC200_CGA, - }, - { - .name = "display_type", - .description = "Monitor type", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "RGB", - .value = DISPLAY_RGB - }, - { - .description = "RGB (no brown)", - .value = DISPLAY_RGB_NO_BROWN - }, - { - .description = "Green Monochrome", - .value = DISPLAY_GREEN - }, - { - .description = "Amber Monochrome", - .value = DISPLAY_AMBER - }, - { - .description = "White Monochrome", - .value = DISPLAY_WHITE - }, - { - .description = "" - } - }, - .default_int = DISPLAY_RGB - }, - { - .name = "codepage", - .description = "Hardware font", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "US English", - .value = 3 - }, - { - .description = "Portugese", - .value = 2 - }, - { - .description = "Norwegian", - .value = 1 - }, - { - .description = "Greek", - .value = 0 - }, - { - .description = "" - } - }, - .default_int = 3 - }, - { - .type = -1 - } - }; +device_config_t pc200_config[] = {{ + .name = "video_emulation", + .description = "Display type", + .type = CONFIG_SELECTION, + .selection = {{ + .description = "CGA monitor", + .value = PC200_CGA, + }, + { + .description = "MDA monitor", + .value = PC200_MDA, + }, + { + .description = "Television", + .value = PC200_TV, + }, + {.description = ""}}, + .default_int = PC200_CGA, + }, + {.name = "display_type", + .description = "Monitor type", + .type = CONFIG_SELECTION, + .selection = {{.description = "RGB", .value = DISPLAY_RGB}, + {.description = "RGB (no brown)", .value = DISPLAY_RGB_NO_BROWN}, + {.description = "Green Monochrome", .value = DISPLAY_GREEN}, + {.description = "Amber Monochrome", .value = DISPLAY_AMBER}, + {.description = "White Monochrome", .value = DISPLAY_WHITE}, + {.description = ""}}, + .default_int = DISPLAY_RGB}, + {.name = "codepage", + .description = "Hardware font", + .type = CONFIG_SELECTION, + .selection = {{.description = "US English", .value = 3}, + {.description = "Portugese", .value = 2}, + {.description = "Norwegian", .value = 1}, + {.description = "Greek", .value = 0}, + {.description = ""}}, + .default_int = 3}, + {.type = -1}}; -device_config_t ppc512_config[] = - { - { - .name = "video_emulation", - .description = "Display type", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "CGA monitor", - .value = PC200_CGA, - }, - { - .description = "MDA monitor", - .value = PC200_MDA, - }, - { - .description = "LCD (CGA mode)", - .value = PC200_LCDC, - }, - { - .description = "LCD (MDA mode)", - .value = PC200_LCDM, - }, - { - .description = "" - } - }, - .default_int = PC200_LCDC, - }, - { - .name = "display_type", - .description = "External monitor", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "RGB", - .value = DISPLAY_RGB - }, - { - .description = "RGB (no brown)", - .value = DISPLAY_RGB_NO_BROWN - }, - { - .description = "Green Monochrome", - .value = DISPLAY_GREEN - }, - { - .description = "Amber Monochrome", - .value = DISPLAY_AMBER - }, - { - .description = "White Monochrome", - .value = DISPLAY_WHITE - }, - { - .description = "" - } - }, - .default_int = DISPLAY_RGB - }, - { - .name = "codepage", - .description = "Hardware font", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "US English", - .value = 3 - }, - { - .description = "Portugese", - .value = 2 - }, - { - .description = "Norwegian", - .value = 1 - }, - { - .description = "Greek", - .value = 0 - }, - { - .description = "" - } - }, - .default_int = 3 - }, - { - .type = -1 - } - }; +device_config_t ppc512_config[] = {{ + .name = "video_emulation", + .description = "Display type", + .type = CONFIG_SELECTION, + .selection = {{ + .description = "CGA monitor", + .value = PC200_CGA, + }, + { + .description = "MDA monitor", + .value = PC200_MDA, + }, + { + .description = "LCD (CGA mode)", + .value = PC200_LCDC, + }, + { + .description = "LCD (MDA mode)", + .value = PC200_LCDM, + }, + {.description = ""}}, + .default_int = PC200_LCDC, + }, + {.name = "display_type", + .description = "External monitor", + .type = CONFIG_SELECTION, + .selection = {{.description = "RGB", .value = DISPLAY_RGB}, + {.description = "RGB (no brown)", .value = DISPLAY_RGB_NO_BROWN}, + {.description = "Green Monochrome", .value = DISPLAY_GREEN}, + {.description = "Amber Monochrome", .value = DISPLAY_AMBER}, + {.description = "White Monochrome", .value = DISPLAY_WHITE}, + {.description = ""}}, + .default_int = DISPLAY_RGB}, + {.name = "codepage", + .description = "Hardware font", + .type = CONFIG_SELECTION, + .selection = {{.description = "US English", .value = 3}, + {.description = "Portugese", .value = 2}, + {.description = "Norwegian", .value = 1}, + {.description = "Greek", .value = 0}, + {.description = ""}}, + .default_int = 3}, + {.type = -1}}; -device_t pc200_device = - { - "Amstrad PC200 (video)", - 0, - pc200_init, - pc200_close, - NULL, - pc200_speed_changed, - NULL, - NULL, - pc200_config - }; - -device_t ppc512_device = - { - "Amstrad PPC512 (video)", - 0, - pc200_init, - pc200_close, - NULL, - pc200_speed_changed, - NULL, - NULL, - ppc512_config - }; +device_t pc200_device = {"Amstrad PC200 (video)", 0, pc200_init, pc200_close, NULL, + pc200_speed_changed, NULL, NULL, pc200_config}; +device_t ppc512_device = {"Amstrad PPC512 (video)", 0, pc200_init, pc200_close, NULL, + pc200_speed_changed, NULL, NULL, ppc512_config}; diff --git a/src/video/vid_pcjr.c b/src/video/vid_pcjr.c index 1dcde77f..a2a1970a 100644 --- a/src/video/vid_pcjr.c +++ b/src/video/vid_pcjr.c @@ -14,548 +14,536 @@ #define PCJR_COMPOSITE 1 typedef struct pcjr_t { - mem_mapping_t mapping; + mem_mapping_t mapping; - uint8_t crtc[32]; - int crtcreg; + uint8_t crtc[32]; + int crtcreg; - int array_index; - uint8_t array[32]; - int array_ff; - int memctrl;//=-1; - uint8_t stat; - int addr_mode; + int array_index; + uint8_t array[32]; + int array_ff; + int memctrl; //=-1; + uint8_t stat; + int addr_mode; - uint8_t *vram, *b8000; + uint8_t *vram, *b8000; - int linepos, displine; - int sc, vc; - int dispon; - int con, coff, cursoron, blink; - int vsynctime, vadj; - uint16_t ma, maback; + int linepos, displine; + int sc, vc; + int dispon; + int con, coff, cursoron, blink; + int vsynctime, vadj; + uint16_t ma, maback; - uint64_t dispontime, dispofftime; - pc_timer_t timer; - int firstline, lastline; + uint64_t dispontime, dispofftime; + pc_timer_t timer; + int firstline, lastline; - int composite; + int composite; } 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 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}; void pcjr_recalcaddress(pcjr_t *pcjr); void pcjr_recalctimings(pcjr_t *pcjr); void pcjr_out(uint16_t addr, uint8_t val, void *p) { - pcjr_t *pcjr = (pcjr_t *)p; - uint8_t old; -// pclog("pcjr OUT %04X %02X\n",addr,val); - switch (addr) { - case 0x3d4:pcjr->crtcreg = val & 0x1f; - return; - case 0x3d5: -// pclog("CRTC write %02X %02x\n", pcjr->crtcreg, val); - 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; - pcjr_recalctimings(pcjr); - } - } - return; - case 0x3da: -// pclog("Array write %02X %02X\n", pcjr->array_index, val); - 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; - pcjr_recalcaddress(pcjr); - break; - } + pcjr_t *pcjr = (pcjr_t *)p; + uint8_t old; + // pclog("pcjr OUT %04X %02X\n",addr,val); + switch (addr) { + case 0x3d4: + pcjr->crtcreg = val & 0x1f; + return; + case 0x3d5: + // pclog("CRTC write %02X %02x\n", pcjr->crtcreg, val); + 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; + pcjr_recalctimings(pcjr); + } + } + return; + case 0x3da: + // pclog("Array write %02X %02X\n", pcjr->array_index, val); + 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; + pcjr_recalcaddress(pcjr); + break; + } } uint8_t pcjr_in(uint16_t addr, void *p) { - pcjr_t *pcjr = (pcjr_t *)p; -// if (addr!=0x3DA) pclog("pcjr IN %04X\n",addr); - switch (addr) { - case 0x3d4:return pcjr->crtcreg; - case 0x3d5:return pcjr->crtc[pcjr->crtcreg]; - case 0x3da:pcjr->array_ff = 0; - pcjr->stat ^= 0x10; - return pcjr->stat; - } - return 0xFF; + pcjr_t *pcjr = (pcjr_t *)p; + // if (addr!=0x3DA) pclog("pcjr IN %04X\n",addr); + switch (addr) { + case 0x3d4: + return pcjr->crtcreg; + case 0x3d5: + return pcjr->crtc[pcjr->crtcreg]; + case 0x3da: + pcjr->array_ff = 0; + pcjr->stat ^= 0x10; + return pcjr->stat; + } + return 0xFF; } void pcjr_recalcaddress(pcjr_t *pcjr) { - if ((pcjr->memctrl & 0xc0) == 0xc0) { - pcjr->vram = &ram[(pcjr->memctrl & 0x06) << 14]; - pcjr->b8000 = &ram[(pcjr->memctrl & 0x30) << 11]; -// printf("VRAM at %05X B8000 at %05X\n",((pcjr->memctrl&0x6)<<14)+pcjr->base,((pcjr->memctrl&0x30)<<11)+pcjr->base); - } else { - pcjr->vram = &ram[(pcjr->memctrl & 0x07) << 14]; - pcjr->b8000 = &ram[(pcjr->memctrl & 0x38) << 11]; -// printf("VRAM at %05X B8000 at %05X\n",((pcjr->memctrl&0x7)<<14)+pcjr->base,((pcjr->memctrl&0x38)<<11)+pcjr->base); - } + if ((pcjr->memctrl & 0xc0) == 0xc0) { + pcjr->vram = &ram[(pcjr->memctrl & 0x06) << 14]; + pcjr->b8000 = &ram[(pcjr->memctrl & 0x30) << 11]; + // printf("VRAM at %05X B8000 at + // %05X\n",((pcjr->memctrl&0x6)<<14)+pcjr->base,((pcjr->memctrl&0x30)<<11)+pcjr->base); + } else { + pcjr->vram = &ram[(pcjr->memctrl & 0x07) << 14]; + pcjr->b8000 = &ram[(pcjr->memctrl & 0x38) << 11]; + // printf("VRAM at %05X B8000 at + // %05X\n",((pcjr->memctrl&0x7)<<14)+pcjr->base,((pcjr->memctrl&0x38)<<11)+pcjr->base); + } } void pcjr_write(uint32_t addr, uint8_t val, void *p) { - pcjr_t *pcjr = (pcjr_t *)p; - if (pcjr->memctrl == -1) - return; + pcjr_t *pcjr = (pcjr_t *)p; + if (pcjr->memctrl == -1) + return; - egawrites++; -// pclog("pcjr VRAM write %05X %02X %04X:%04X %04X:%04X\n",addr,val,CS,pc,DS,SI); - pcjr->b8000[addr & 0x3fff] = val; + egawrites++; + // pclog("pcjr VRAM write %05X %02X %04X:%04X %04X:%04X\n",addr,val,CS,pc,DS,SI); + pcjr->b8000[addr & 0x3fff] = val; } uint8_t pcjr_read(uint32_t addr, void *p) { - pcjr_t *pcjr = (pcjr_t *)p; - if (pcjr->memctrl == -1) - return 0xff; + pcjr_t *pcjr = (pcjr_t *)p; + if (pcjr->memctrl == -1) + return 0xff; - egareads++; -// pclog("pcjr VRAM read %05X %02X %04X:%04X\n",addr,pcjr->b8000[addr&0x7FFF],CS,pc); - return pcjr->b8000[addr & 0x3fff]; + egareads++; + // pclog("pcjr VRAM read %05X %02X %04X:%04X\n",addr,pcjr->b8000[addr&0x7FFF],CS,pc); + return pcjr->b8000[addr & 0x3fff]; } void pcjr_recalctimings(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 = (uint64_t)_dispontime; - pcjr->dispofftime = (uint64_t)_dispofftime; + 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 = (uint64_t)_dispontime; + pcjr->dispofftime = (uint64_t)_dispofftime; } void pcjr_poll(void *p) { -// int *cgapal=cga4pal[((pcjr->col&0x10)>>2)|((cgamode&4)>>1)|((cgacol&0x20)>>5)]; - 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; + // int *cgapal=cga4pal[((pcjr->col&0x10)>>2)|((cgamode&4)>>1)|((cgacol&0x20)>>5)]; + 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) { -// cgapal[0]=pcjr->col&15; -// printf("Firstline %i Lastline %i pcjr->displine %i\n",firstline,lastline,pcjr->displine); - timer_advance_u64(&pcjr->timer, 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->linepos) { + // cgapal[0]=pcjr->col&15; + // printf("Firstline %i Lastline %i pcjr->displine %i\n",firstline,lastline,pcjr->displine); + timer_advance_u64(&pcjr->timer, 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; - for (c = 0; c < 8; c++) { - ((uint32_t *)buffer32->line[pcjr->displine])[c] = cols[0]; - if (pcjr->array[0] & 1) - ((uint32_t *)buffer32->line[pcjr->displine])[c + (pcjr->crtc[1] << 3) + 8] = cols[0]; - else - ((uint32_t *)buffer32->line[pcjr->displine])[c + (pcjr->crtc[1] << 4) + 8] = cols[0]; - } + if (pcjr->displine < pcjr->firstline) { + pcjr->firstline = pcjr->displine; + video_wait_for_buffer(); + } + pcjr->lastline = pcjr->displine; + cols[0] = pcjr->array[2] & 0xf; + for (c = 0; c < 8; c++) { + ((uint32_t *)buffer32->line[pcjr->displine])[c] = cols[0]; + if (pcjr->array[0] & 1) + ((uint32_t *)buffer32->line[pcjr->displine])[c + (pcjr->crtc[1] << 3) + 8] = cols[0]; + else + ((uint32_t *)buffer32->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++; - ((uint32_t *)buffer32->line[pcjr->displine])[(x << 3) + 8] = - ((uint32_t *)buffer32->line[pcjr->displine])[(x << 3) + 9] = pcjr->array[((dat >> 12) & pcjr->array[1]) + 16]; - ((uint32_t *)buffer32->line[pcjr->displine])[(x << 3) + 10] = - ((uint32_t *)buffer32->line[pcjr->displine])[(x << 3) + 11] = pcjr->array[((dat >> 8) & pcjr->array[1]) + 16]; - ((uint32_t *)buffer32->line[pcjr->displine])[(x << 3) + 12] = - ((uint32_t *)buffer32->line[pcjr->displine])[(x << 3) + 13] = pcjr->array[((dat >> 4) & pcjr->array[1]) + 16]; - ((uint32_t *)buffer32->line[pcjr->displine])[(x << 3) + 14] = - ((uint32_t *)buffer32->line[pcjr->displine])[(x << 3) + 15] = pcjr->array[(dat & pcjr->array[1]) + 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++; - ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + 8] = - ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + 9] = - ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + 10] = - ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + 11] = pcjr->array[((dat >> 12) & pcjr->array[1]) + 16]; - ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + 12] = - ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + 13] = - ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + 14] = - ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + 15] = pcjr->array[((dat >> 8) & pcjr->array[1]) + 16]; - ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + 16] = - ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + 17] = - ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + 18] = - ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + 19] = pcjr->array[((dat >> 4) & pcjr->array[1]) + 16]; - ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + 20] = - ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + 21] = - ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + 22] = - ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + 23] = pcjr->array[(dat & pcjr->array[1]) + 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); - ((uint32_t *)buffer32->line[pcjr->displine])[(x << 3) + 8 + c] = pcjr->array[(chr & pcjr->array[1]) + 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]; - cols[0] = pcjr->array[(((attr >> 4) & 7) & pcjr->array[1]) + 16]; - if ((pcjr->blink & 16) && (attr & 0x80) && !drawcursor) - cols[1] = cols[0]; - } else { - cols[1] = pcjr->array[((attr & 15) & pcjr->array[1]) + 16]; - cols[0] = pcjr->array[((attr >> 4) & pcjr->array[1]) + 16]; - } - if (pcjr->sc & 8) { - for (c = 0; c < 8; c++) - ((uint32_t *)buffer32->line[pcjr->displine])[(x << 3) + c + 8] = cols[0]; - } else { - for (c = 0; c < 8; c++) - ((uint32_t *)buffer32->line[pcjr->displine])[(x << 3) + c + 8] = cols[(fontdat[chr][pcjr->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; - } -// if (!((ma^(crtc[15]|(crtc[14]<<8)))&0x3FFF)) printf("Cursor match! %04X\n",ma); - if (drawcursor) { - for (c = 0; c < 8; c++) - ((uint32_t *)buffer32->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]; - cols[0] = pcjr->array[(((attr >> 4) & 7) & pcjr->array[1]) + 16]; - if ((pcjr->blink & 16) && (attr & 0x80) && !drawcursor) - cols[1] = cols[0]; - } else { - cols[1] = pcjr->array[((attr & 15) & pcjr->array[1]) + 16]; - cols[0] = pcjr->array[((attr >> 4) & pcjr->array[1]) + 16]; - } - pcjr->ma++; - if (pcjr->sc & 8) { - for (c = 0; c < 8; c++) - ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + (c << 1) + 8] = - ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + (c << 1) + 1 + 8] = cols[0]; - } else { - for (c = 0; c < 8; c++) - ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + (c << 1) + 8] = - ((uint32_t *)buffer32->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++) - ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + c + 8] ^= 15; - } - } - break; - case 0x02: /*320x200x4*/ - cols[0] = pcjr->array[0 + 16]; - cols[1] = pcjr->array[1 + 16]; - cols[2] = pcjr->array[2 + 16]; - cols[3] = pcjr->array[3 + 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++) { - ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + (c << 1) + 8] = - ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14]; - dat <<= 2; - } - } - break; - case 0x102: /*640x200x2*/ - cols[0] = pcjr->array[0 + 16]; - cols[1] = pcjr->array[1 + 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++) { - ((uint32_t *)buffer32->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(buffer32, 0, pcjr->displine, (pcjr->crtc[1] << 3) + 16, pcjr->array[2] & 0xf); - else - hline(buffer32, 0, pcjr->displine, (pcjr->crtc[1] << 4) + 16, pcjr->array[2] & 0xf); - } else { -// cols[0] = ((pcjr->mode & 0x12) == 0x12) ? 0 : (pcjr->col & 0xf) + 16; - cols[0] = pcjr->array[0 + 16]; - if (pcjr->array[0] & 1) - hline(buffer32, 0, pcjr->displine, (pcjr->crtc[1] << 3) + 16, cols[0]); - else - hline(buffer32, 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] = ((uint32_t *)buffer32->line[pcjr->displine])[c] & 0xf; + 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++; + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 3) + 8] = + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 3) + 9] = + pcjr->array[((dat >> 12) & pcjr->array[1]) + 16]; + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 3) + 10] = + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 3) + 11] = + pcjr->array[((dat >> 8) & pcjr->array[1]) + 16]; + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 3) + 12] = + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 3) + 13] = + pcjr->array[((dat >> 4) & pcjr->array[1]) + 16]; + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 3) + 14] = + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 3) + 15] = + pcjr->array[(dat & pcjr->array[1]) + 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++; + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + 8] = + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + 9] = + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + 10] = + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + 11] = + pcjr->array[((dat >> 12) & pcjr->array[1]) + 16]; + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + 12] = + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + 13] = + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + 14] = + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + 15] = + pcjr->array[((dat >> 8) & pcjr->array[1]) + 16]; + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + 16] = + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + 17] = + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + 18] = + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + 19] = + pcjr->array[((dat >> 4) & pcjr->array[1]) + 16]; + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + 20] = + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + 21] = + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + 22] = + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + 23] = + pcjr->array[(dat & pcjr->array[1]) + 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); + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 3) + 8 + c] = + pcjr->array[(chr & pcjr->array[1]) + 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]; + cols[0] = pcjr->array[(((attr >> 4) & 7) & pcjr->array[1]) + 16]; + if ((pcjr->blink & 16) && (attr & 0x80) && !drawcursor) + cols[1] = cols[0]; + } else { + cols[1] = pcjr->array[((attr & 15) & pcjr->array[1]) + 16]; + cols[0] = pcjr->array[((attr >> 4) & pcjr->array[1]) + 16]; + } + if (pcjr->sc & 8) { + for (c = 0; c < 8; c++) + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 3) + c + 8] = cols[0]; + } else { + for (c = 0; c < 8; c++) + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 3) + c + 8] = + cols[(fontdat[chr][pcjr->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; + } + // if (!((ma^(crtc[15]|(crtc[14]<<8)))&0x3FFF)) + // printf("Cursor match! %04X\n",ma); + if (drawcursor) { + for (c = 0; c < 8; c++) + ((uint32_t *)buffer32->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]; + cols[0] = pcjr->array[(((attr >> 4) & 7) & pcjr->array[1]) + 16]; + if ((pcjr->blink & 16) && (attr & 0x80) && !drawcursor) + cols[1] = cols[0]; + } else { + cols[1] = pcjr->array[((attr & 15) & pcjr->array[1]) + 16]; + cols[0] = pcjr->array[((attr >> 4) & pcjr->array[1]) + 16]; + } + pcjr->ma++; + if (pcjr->sc & 8) { + for (c = 0; c < 8; c++) + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + (c << 1) + 8] = + ((uint32_t *)buffer32 + ->line[pcjr->displine])[(x << 4) + (c << 1) + 1 + 8] = + cols[0]; + } else { + for (c = 0; c < 8; c++) + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + (c << 1) + 8] = + ((uint32_t *)buffer32 + ->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++) + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + c + 8] ^= 15; + } + } + break; + case 0x02: /*320x200x4*/ + cols[0] = pcjr->array[0 + 16]; + cols[1] = pcjr->array[1 + 16]; + cols[2] = pcjr->array[2 + 16]; + cols[3] = pcjr->array[3 + 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++) { + ((uint32_t *)buffer32->line[pcjr->displine])[(x << 4) + (c << 1) + 8] = + ((uint32_t *) + buffer32->line[pcjr->displine])[(x << 4) + (c << 1) + 1 + 8] = + cols[dat >> 14]; + dat <<= 2; + } + } + break; + case 0x102: /*640x200x2*/ + cols[0] = pcjr->array[0 + 16]; + cols[1] = pcjr->array[1 + 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++) { + ((uint32_t *)buffer32->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(buffer32, 0, pcjr->displine, (pcjr->crtc[1] << 3) + 16, pcjr->array[2] & 0xf); + else + hline(buffer32, 0, pcjr->displine, (pcjr->crtc[1] << 4) + 16, pcjr->array[2] & 0xf); + } else { + // cols[0] = ((pcjr->mode & 0x12) == 0x12) ? 0 : (pcjr->col & 0xf) + // + 16; + cols[0] = pcjr->array[0 + 16]; + if (pcjr->array[0] & 1) + hline(buffer32, 0, pcjr->displine, (pcjr->crtc[1] << 3) + 16, cols[0]); + else + hline(buffer32, 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] = ((uint32_t *)buffer32->line[pcjr->displine])[c] & 0xf; - Composite_Process(pcjr->array[0], 0, x >> 2, buffer32->line[pcjr->displine]); - } else { - for (c = 0; c < x; c++) - ((uint32_t *)buffer32->line[pcjr->displine])[c] = cgapal[((uint32_t *)buffer32->line[pcjr->displine])[c] & 0xf]; - } - pcjr->sc = oldsc; - if (pcjr->vc == pcjr->crtc[7] && !pcjr->sc) { - pcjr->stat |= 8; -// printf("VSYNC on %i %i\n",vc,sc); - } - pcjr->displine++; - if (pcjr->displine >= 360) - pcjr->displine = 0; - } else { - timer_advance_u64(&pcjr->timer, pcjr->dispontime); - if (pcjr->dispon) - pcjr->stat |= 1; - pcjr->linepos = 0; - if (pcjr->vsynctime) { - pcjr->vsynctime--; - if (!pcjr->vsynctime) { - pcjr->stat &= ~8; -// printf("VSYNC off %i %i\n",vc,sc); - } - } - 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; -// printf("Display on!\n"); - } - } else if (pcjr->sc == pcjr->crtc[9] || ((pcjr->crtc[8] & 3) == 3 && pcjr->sc == (pcjr->crtc[9] >> 1))) { - pcjr->maback = pcjr->ma; -// con=0; -// coff=0; - pcjr->sc = 0; - oldvc = pcjr->vc; - pcjr->vc++; - pcjr->vc &= 127; -// pclog("VC %i %i\n", pcjr->vc, pcjr->crtc[7]); -// printf("VC %i %i %i %i %i\n",vc,crtc[4],crtc[6],crtc[7],pcjr->dispon); - if (pcjr->vc == pcjr->crtc[6]) - pcjr->dispon = 0; - if (oldvc == pcjr->crtc[4]) { -// printf("Display over at %i\n",pcjr->displine); - 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; -// printf("CRTC10 %02X %i\n",crtc[10],cursoron); - } - if (pcjr->vc == pcjr->crtc[7]) { - pcjr->dispon = 0; - pcjr->displine = 0; - pcjr->vsynctime = 16;//(crtc[3]>>4)+1; - picint(1 << 5); -// printf("pcjr->vsynctime %i %02X\n",pcjr->vsynctime,crtc[3]); -// pcjr->stat|=8; - if (pcjr->crtc[7]) { -// printf("Lastline %i Firstline %i %i %i %i\n",lastline,firstline,lastline-firstline,crtc[1],xsize); - 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) { - xsize = x; - ysize = pcjr->lastline - pcjr->firstline; -// printf("Resize to %i,%i - R1 %i\n",xsize,ysize,crtc[1]); - if (xsize < 64) - xsize = 656; - if (ysize < 32) - ysize = 200; - updatewindowsize(xsize, (ysize << 1) + 16); - } -// printf("Blit %i %i\n",firstline,lastline); -//printf("Xsize is %i\n",xsize); + Composite_Process(pcjr->array[0], 0, x >> 2, buffer32->line[pcjr->displine]); + } else { + for (c = 0; c < x; c++) + ((uint32_t *)buffer32->line[pcjr->displine])[c] = + cgapal[((uint32_t *)buffer32->line[pcjr->displine])[c] & 0xf]; + } + pcjr->sc = oldsc; + if (pcjr->vc == pcjr->crtc[7] && !pcjr->sc) { + pcjr->stat |= 8; + // printf("VSYNC on %i %i\n",vc,sc); + } + pcjr->displine++; + if (pcjr->displine >= 360) + pcjr->displine = 0; + } else { + timer_advance_u64(&pcjr->timer, pcjr->dispontime); + if (pcjr->dispon) + pcjr->stat |= 1; + pcjr->linepos = 0; + if (pcjr->vsynctime) { + pcjr->vsynctime--; + if (!pcjr->vsynctime) { + pcjr->stat &= ~8; + // printf("VSYNC off %i %i\n",vc,sc); + } + } + 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; + // printf("Display on!\n"); + } + } else if (pcjr->sc == pcjr->crtc[9] || ((pcjr->crtc[8] & 3) == 3 && pcjr->sc == (pcjr->crtc[9] >> 1))) { + pcjr->maback = pcjr->ma; + // con=0; + // coff=0; + pcjr->sc = 0; + oldvc = pcjr->vc; + pcjr->vc++; + pcjr->vc &= 127; + // pclog("VC %i %i\n", pcjr->vc, pcjr->crtc[7]); + // printf("VC %i %i %i %i %i\n",vc,crtc[4],crtc[6],crtc[7],pcjr->dispon); + if (pcjr->vc == pcjr->crtc[6]) + pcjr->dispon = 0; + if (oldvc == pcjr->crtc[4]) { + // printf("Display over at %i\n",pcjr->displine); + 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; + // printf("CRTC10 %02X %i\n",crtc[10],cursoron); + } + if (pcjr->vc == pcjr->crtc[7]) { + pcjr->dispon = 0; + pcjr->displine = 0; + pcjr->vsynctime = 16; //(crtc[3]>>4)+1; + picint(1 << 5); + // printf("pcjr->vsynctime %i %02X\n",pcjr->vsynctime,crtc[3]); + // pcjr->stat|=8; + if (pcjr->crtc[7]) { + // printf("Lastline %i Firstline %i %i %i + // %i\n",lastline,firstline,lastline-firstline,crtc[1],xsize); + 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) { + xsize = x; + ysize = pcjr->lastline - pcjr->firstline; + // printf("Resize to %i,%i - R1 + // %i\n",xsize,ysize,crtc[1]); + if (xsize < 64) + xsize = 656; + if (ysize < 32) + ysize = 200; + updatewindowsize(xsize, (ysize << 1) + 16); + } + // printf("Blit %i %i\n",firstline,lastline); + // printf("Xsize is %i\n",xsize); - video_blit_memtoscreen(0, pcjr->firstline - 4, 0, (pcjr->lastline - pcjr->firstline) + 8, xsize, (pcjr->lastline - pcjr->firstline) + 8); + video_blit_memtoscreen(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; - } + 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 *pcjr_video_init() { - int display_type; - pcjr_t *pcjr = malloc(sizeof(pcjr_t)); - memset(pcjr, 0, sizeof(pcjr_t)); + int display_type; + pcjr_t *pcjr = malloc(sizeof(pcjr_t)); + memset(pcjr, 0, sizeof(pcjr_t)); - display_type = model_get_config_int("display_type"); - pcjr->composite = (display_type != PCJR_RGB); + display_type = model_get_config_int("display_type"); + pcjr->composite = (display_type != PCJR_RGB); - pcjr->memctrl = -1; + pcjr->memctrl = -1; - timer_add(&pcjr->timer, pcjr_poll, pcjr, 1); - mem_mapping_add(&pcjr->mapping, 0xb8000, 0x08000, pcjr_read, NULL, NULL, pcjr_write, NULL, NULL, NULL, 0, pcjr); - io_sethandler(0x03d0, 0x0010, pcjr_in, NULL, NULL, pcjr_out, NULL, NULL, pcjr); - return pcjr; + timer_add(&pcjr->timer, pcjr_poll, pcjr, 1); + mem_mapping_add(&pcjr->mapping, 0xb8000, 0x08000, pcjr_read, NULL, NULL, pcjr_write, NULL, NULL, NULL, 0, pcjr); + io_sethandler(0x03d0, 0x0010, pcjr_in, NULL, NULL, pcjr_out, NULL, NULL, pcjr); + return pcjr; } static void pcjr_video_close(void *p) { - pcjr_t *pcjr = (pcjr_t *)p; + pcjr_t *pcjr = (pcjr_t *)p; - free(pcjr); + free(pcjr); } static void pcjr_speed_changed(void *p) { - pcjr_t *pcjr = (pcjr_t *)p; + pcjr_t *pcjr = (pcjr_t *)p; - pcjr_recalctimings(pcjr); + pcjr_recalctimings(pcjr); } -device_t pcjr_video_device = - { - "IBM PCjr (video)", - 0, - pcjr_video_init, - pcjr_video_close, - NULL, - pcjr_speed_changed, - NULL, - NULL - }; +device_t pcjr_video_device = {"IBM PCjr (video)", 0, pcjr_video_init, pcjr_video_close, NULL, pcjr_speed_changed, NULL, NULL}; -static device_config_t pcjr_config[] = - { - { - .name = "display_type", - .description = "Display type", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "RGB", - .value = PCJR_RGB - }, - { - .description = "Composite", - .value = PCJR_COMPOSITE - }, - { - .description = "" - } - }, - .default_int = PCJR_RGB - }, - { - .type = -1 - } - }; +static device_config_t pcjr_config[] = {{.name = "display_type", + .description = "Display type", + .type = CONFIG_SELECTION, + .selection = {{.description = "RGB", .value = PCJR_RGB}, + {.description = "Composite", .value = PCJR_COMPOSITE}, + {.description = ""}}, + .default_int = PCJR_RGB}, + {.type = -1}}; /*This isn't really a device as such - more of a convenient way to hook in the config information*/ -device_t pcjr_device = - { - "IBM PCjr", - 0, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - pcjr_config - }; +device_t pcjr_device = {"IBM PCjr", 0, NULL, NULL, NULL, NULL, NULL, NULL, pcjr_config}; diff --git a/src/video/vid_pgc.c b/src/video/vid_pgc.c index b8720e7f..b397b751 100644 --- a/src/video/vid_pgc.c +++ b/src/video/vid_pgc.c @@ -13,20 +13,20 @@ #include /* This implements just enough of the Professional Graphics Controller to - * act as a basis for the Vermont Microsystems IM-1024. + * act as a basis for the Vermont Microsystems IM-1024. * * PGC features implemented include: * > The CGA-compatible display modes * > Switching to and from native mode * > Communicating with the host PC - * + * * Numerous features are implemented partially or not at all, such as: * > 2D drawing * > 3D drawing * > Command lists * Some of these are marked TODO. * - * The PGC has two display modes: CGA (in which it appears in the normal CGA + * The PGC has two display modes: CGA (in which it appears in the normal CGA * memory and I/O ranges) and native (in which all functions are accessed * through reads and writes to 1k of memory at 0xC6000). The PGC's 8088 * processor monitors this buffer and executes instructions left there @@ -39,49 +39,34 @@ static int pgc_parse_command(pgc_core_t *pgc, const pgc_command_t **pcmd); int pgc_clist_byte(pgc_core_t *pgc, uint8_t *val); -static const char *pgc_err_msgs[] = - { - "Range \r", - "Integer \r", - "Memory \r", - "Overflow\r", - "Digit \r", - "Opcode \r", - "Running \r", - "Stack \r", - "Too long\r", - "Area \r", - "Missing \r" - }; +static const char *pgc_err_msgs[] = {"Range \r", "Integer \r", "Memory \r", "Overflow\r", "Digit \r", "Opcode \r", + "Running \r", "Stack \r", "Too long\r", "Area \r", "Missing \r"}; #define HWORD(u) ((u) >> 16) -#define LWORD(u) ((u) & 0xFFFF) +#define LWORD(u) ((u)&0xFFFF) /* Initial palettes */ -uint32_t init_palette[6][256] = - { +uint32_t init_palette[6][256] = { #include "pgc_palettes.h" - }; - - +}; /* When idle, the PGC drawing thread sleeps. pgc_wake() awakens it - but - * not immediately. Like the Voodoo, it has a short delay so that writes + * not immediately. Like the Voodoo, it has a short delay so that writes * can be batched */ #define WAKE_DELAY (TIMER_USEC * 500) void pgc_wake(pgc_core_t *pgc) { - if (!timer_is_enabled(&pgc->wake_timer)) { - timer_set_delay_u64(&pgc->wake_timer, WAKE_DELAY); - } + if (!timer_is_enabled(&pgc->wake_timer)) { + timer_set_delay_u64(&pgc->wake_timer, WAKE_DELAY); + } } /* When the wake timer expires, that's when the drawing thread is actually * woken */ static void pgc_wake_timer(void *p) { - pgc_core_t *pgc = (pgc_core_t *)p; + pgc_core_t *pgc = (pgc_core_t *)p; - PGCLOG(("pgc: Waking up\n")); - thread_set_event(pgc->pgc_wake_thread); + PGCLOG(("pgc: Waking up\n")); + thread_set_event(pgc->pgc_wake_thread); } /* This is called by the drawing thread when it's waiting for the host @@ -89,221 +74,214 @@ static void pgc_wake_timer(void *p) { * FIFO. */ void pgc_sleep(pgc_core_t *pgc) { - PGCLOG(("pgc: Sleeping on %d %d %d 0x%02x 0x%02x\n", - pgc->waiting_input_fifo, - pgc->waiting_output_fifo, - pgc->waiting_error_fifo, - pgc->mapram[0x300], pgc->mapram[0x301])); - /* Race condition: If host wrote to the PGC during the pclog() that - * won't be noticed */ - if (pgc->waiting_input_fifo && pgc->mapram[0x300] != pgc->mapram[0x301]) { - pgc->waiting_input_fifo = 0; - return; - } - /* Same if they read */ - if (pgc->waiting_output_fifo && pgc->mapram[0x302] != (uint8_t)(pgc->mapram[0x303] - 1)) { - pgc->waiting_output_fifo = 0; - return; - } - thread_wait_event(pgc->pgc_wake_thread, -1); - thread_reset_event(pgc->pgc_wake_thread); - + PGCLOG(("pgc: Sleeping on %d %d %d 0x%02x 0x%02x\n", pgc->waiting_input_fifo, pgc->waiting_output_fifo, + pgc->waiting_error_fifo, pgc->mapram[0x300], pgc->mapram[0x301])); + /* Race condition: If host wrote to the PGC during the pclog() that + * won't be noticed */ + if (pgc->waiting_input_fifo && pgc->mapram[0x300] != pgc->mapram[0x301]) { + pgc->waiting_input_fifo = 0; + return; + } + /* Same if they read */ + if (pgc->waiting_output_fifo && pgc->mapram[0x302] != (uint8_t)(pgc->mapram[0x303] - 1)) { + pgc->waiting_output_fifo = 0; + return; + } + thread_wait_event(pgc->pgc_wake_thread, -1); + thread_reset_event(pgc->pgc_wake_thread); } /* Switch between CGA mode (DISPLAY 1) and native mode (DISPLAY 0) */ void pgc_setdisplay(pgc_core_t *pgc, int cga) { - PGCLOG(("pgc_setdisplay(%d): cga_selected=%d cga_enabled=%d\n", - cga, pgc->cga_selected, pgc->cga_enabled)); - if (pgc->cga_selected != (pgc->cga_enabled && cga)) { - pgc->cga_selected = (pgc->cga_enabled && cga); + PGCLOG(("pgc_setdisplay(%d): cga_selected=%d cga_enabled=%d\n", cga, pgc->cga_selected, pgc->cga_enabled)); + if (pgc->cga_selected != (pgc->cga_enabled && cga)) { + pgc->cga_selected = (pgc->cga_enabled && cga); - if (pgc->cga_selected) { - mem_mapping_enable(&pgc->cga_mapping); - pgc->screenw = PGC_CGA_WIDTH; - pgc->screenh = PGC_CGA_HEIGHT; - } else { - mem_mapping_disable(&pgc->cga_mapping); - pgc->screenw = pgc->visw; - pgc->screenh = pgc->vish; - } - pgc_recalctimings(pgc); - } + if (pgc->cga_selected) { + mem_mapping_enable(&pgc->cga_mapping); + pgc->screenw = PGC_CGA_WIDTH; + pgc->screenh = PGC_CGA_HEIGHT; + } else { + mem_mapping_disable(&pgc->cga_mapping); + pgc->screenw = pgc->visw; + pgc->screenh = pgc->vish; + } + pgc_recalctimings(pgc); + } } /* Convert coordinates based on the current window / viewport to raster * coordinates. */ void pgc_dto_raster(pgc_core_t *pgc, double *x, double *y) { -/* double x0 = *x, y0 = *y; */ + /* double x0 = *x, y0 = *y; */ - *x += (pgc->vp_x1 - pgc->win_x1); - *y += (pgc->vp_y1 - pgc->win_y1); + *x += (pgc->vp_x1 - pgc->win_x1); + *y += (pgc->vp_y1 - pgc->win_y1); -/* PGCLOG(("Coords to raster: (%f, %f) -> (%f, %f)\n", x0, y0, *x, *y)); */ + /* PGCLOG(("Coords to raster: (%f, %f) -> (%f, %f)\n", x0, y0, *x, *y)); */ } /* Overloads that take ints */ void pgc_sto_raster(pgc_core_t *pgc, int16_t *x, int16_t *y) { - double xd = *x, yd = *y; + double xd = *x, yd = *y; - pgc_dto_raster(pgc, &xd, &yd); - *x = (int16_t)xd; - *y = (int16_t)yd; + pgc_dto_raster(pgc, &xd, &yd); + *x = (int16_t)xd; + *y = (int16_t)yd; } void pgc_ito_raster(pgc_core_t *pgc, int32_t *x, int32_t *y) { - double xd = *x, yd = *y; + double xd = *x, yd = *y; - pgc_dto_raster(pgc, &xd, &yd); - *x = (int32_t)xd; - *y = (int32_t)yd; + pgc_dto_raster(pgc, &xd, &yd); + *x = (int32_t)xd; + *y = (int32_t)yd; } /* Add a byte to a command list. We allow command lists to be * arbitrarily large */ int pgc_commandlist_append(pgc_commandlist_t *list, uint8_t v) { - if (list->listmax == 0 || list->list == NULL) { - list->list = malloc(4096); - if (!list->list) { - PGCLOG(("Out of memory initialising command list\n")); - return 0; - } - list->listmax = 4096; - } - while (list->wrptr >= list->listmax) { - uint8_t *buf = realloc(list->list, 2 * list->listmax); - if (!buf) { - PGCLOG(("Out of memory growing command list\n")); - return 0; - } - list->list = buf; - list->listmax *= 2; - } - list->list[list->wrptr++] = v; - return 1; + if (list->listmax == 0 || list->list == NULL) { + list->list = malloc(4096); + if (!list->list) { + PGCLOG(("Out of memory initialising command list\n")); + return 0; + } + list->listmax = 4096; + } + while (list->wrptr >= list->listmax) { + uint8_t *buf = realloc(list->list, 2 * list->listmax); + if (!buf) { + PGCLOG(("Out of memory growing command list\n")); + return 0; + } + list->list = buf; + list->listmax *= 2; + } + list->list[list->wrptr++] = v; + return 1; } /* Beginning of a command list. Parse commands up to the next CLEND, * storing them (in hex form) in the named command list. */ static void hndl_clbeg(pgc_core_t *pgc) { - uint8_t param; - pgc_commandlist_t cl; - const pgc_command_t *cmd; + uint8_t param; + pgc_commandlist_t cl; + const pgc_command_t *cmd; - memset(&cl, 0, sizeof(cl)); - if (!pgc_param_byte(pgc, ¶m)) - return; + memset(&cl, 0, sizeof(cl)); + if (!pgc_param_byte(pgc, ¶m)) + return; - PGCLOG(("CLBEG(%d)\n", param)); - while (1) { - if (!pgc_parse_command(pgc, &cmd)) { - /* PGC has been reset */ - return; - } - if (!cmd) { - pgc_error(pgc, PGC_ERROR_OPCODE); - return; - } else if (pgc->hex_command == 0x71) /* CLEND */ - { - pgc->clist[param] = cl; - return; - } else { - if (!pgc_commandlist_append(&cl, pgc->hex_command)) { - pgc_error(pgc, PGC_ERROR_OVERFLOW); - return; - } - if (cmd->parser) { - if (!(*cmd->parser)(pgc, &cl, cmd->p)) { - return; - } - } - } - } + PGCLOG(("CLBEG(%d)\n", param)); + while (1) { + if (!pgc_parse_command(pgc, &cmd)) { + /* PGC has been reset */ + return; + } + if (!cmd) { + pgc_error(pgc, PGC_ERROR_OPCODE); + return; + } else if (pgc->hex_command == 0x71) /* CLEND */ + { + pgc->clist[param] = cl; + return; + } else { + if (!pgc_commandlist_append(&cl, pgc->hex_command)) { + pgc_error(pgc, PGC_ERROR_OVERFLOW); + return; + } + if (cmd->parser) { + if (!(*cmd->parser)(pgc, &cl, cmd->p)) { + return; + } + } + } + } } -static void hndl_clend(pgc_core_t *pgc) { - /* Shouldn't happen outside a CLBEG */ -} +static void hndl_clend(pgc_core_t *pgc) { /* Shouldn't happen outside a CLBEG */ } -/* Execute a command list. If one was already executing, remember it so +/* Execute a command list. If one was already executing, remember it so * we can return to it afterwards. */ static void hndl_clrun(pgc_core_t *pgc) { - uint8_t param; - pgc_commandlist_t *clprev = pgc->clcur; + uint8_t param; + pgc_commandlist_t *clprev = pgc->clcur; - if (!pgc_param_byte(pgc, ¶m)) - return; + if (!pgc_param_byte(pgc, ¶m)) + return; - pgc->clcur = &pgc->clist[param]; - pgc->clcur->rdptr = 0; - pgc->clcur->repeat = 1; - pgc->clcur->chain = clprev; + pgc->clcur = &pgc->clist[param]; + pgc->clcur->rdptr = 0; + pgc->clcur->repeat = 1; + pgc->clcur->chain = clprev; } /* Execute a command list multiple times. */ static void hndl_cloop(pgc_core_t *pgc) { - uint8_t param; - int16_t repeat; - pgc_commandlist_t *clprev = pgc->clcur; + uint8_t param; + int16_t repeat; + pgc_commandlist_t *clprev = pgc->clcur; - if (!pgc_param_byte(pgc, ¶m)) - return; - if (!pgc_param_word(pgc, &repeat)) - return; + if (!pgc_param_byte(pgc, ¶m)) + return; + if (!pgc_param_word(pgc, &repeat)) + return; - pgc->clcur = &pgc->clist[param]; - pgc->clcur->rdptr = 0; - pgc->clcur->repeat = repeat; - pgc->clcur->chain = clprev; + pgc->clcur = &pgc->clist[param]; + pgc->clcur->rdptr = 0; + pgc->clcur->repeat = repeat; + pgc->clcur->chain = clprev; } /* Read back a command list */ static void hndl_clread(pgc_core_t *pgc) { - uint8_t param; - int n; + uint8_t param; + int n; - if (!pgc_param_byte(pgc, ¶m)) - return; + if (!pgc_param_byte(pgc, ¶m)) + return; - for (n = 0; n < pgc->clist[param].wrptr; n++) { - if (!pgc_result_byte(pgc, pgc->clist[param].list[n])) - return; - } + for (n = 0; n < pgc->clist[param].wrptr; n++) { + if (!pgc_result_byte(pgc, pgc->clist[param].list[n])) + return; + } } /* Delete a command list */ static void hndl_cldel(pgc_core_t *pgc) { - uint8_t param; + uint8_t param; - if (!pgc_param_byte(pgc, ¶m)) - return; - memset(&pgc->clist[param], 0, sizeof(pgc_commandlist_t)); + if (!pgc_param_byte(pgc, ¶m)) + return; + memset(&pgc->clist[param], 0, sizeof(pgc_commandlist_t)); } /* Clear the screen to a specified colour */ static void hndl_clears(pgc_core_t *pgc) { - uint8_t param; - int y; + uint8_t param; + int y; - if (!pgc_param_byte(pgc, ¶m)) - return; + if (!pgc_param_byte(pgc, ¶m)) + return; - for (y = 0; y < pgc->screenh; y++) - memset(pgc->vram + y * pgc->maxw, param, pgc->screenw); + for (y = 0; y < pgc->screenh; y++) + memset(pgc->vram + y * pgc->maxw, param, pgc->screenw); } /* Select drawing colour */ static void hndl_color(pgc_core_t *pgc) { - uint8_t param; + uint8_t param; - if (!pgc_param_byte(pgc, ¶m)) - return; + if (!pgc_param_byte(pgc, ¶m)) + return; - pgc->colour = param; - PGCLOG(("COLOR(%d)\n", param)); + pgc->colour = param; + PGCLOG(("COLOR(%d)\n", param)); } /* Set drawing mode. - * + * * 0 => Draw * 1 => Invert * 2 => XOR (IM-1024) @@ -311,725 +289,705 @@ static void hndl_color(pgc_core_t *pgc) { * */ static void hndl_linfun(pgc_core_t *pgc) { - uint8_t param; + uint8_t param; - if (!pgc_param_byte(pgc, ¶m)) - return; + if (!pgc_param_byte(pgc, ¶m)) + return; - /* TODO: Not range-checked. Strictly speaking we should limit to 0-1 - * for the PGC and 0-3 for the IM-1024. */ - pgc->draw_mode = param; - PGCLOG(("LINFUN(%d)\n", param)); + /* TODO: Not range-checked. Strictly speaking we should limit to 0-1 + * for the PGC and 0-3 for the IM-1024. */ + pgc->draw_mode = param; + PGCLOG(("LINFUN(%d)\n", param)); } /* Set the line drawing pattern */ static void hndl_linpat(pgc_core_t *pgc) { - uint16_t param; + uint16_t param; - if (!pgc_param_word(pgc, (int16_t *)¶m)) - return; + if (!pgc_param_word(pgc, (int16_t *)¶m)) + return; - pgc->line_pattern = param; - PGCLOG(("LINPAT(0x%04x)\n", param)); + pgc->line_pattern = param; + PGCLOG(("LINPAT(0x%04x)\n", param)); } /* Set the polygon fill mode (0=hollow, 1=filled, 2=fast fill) */ static void hndl_prmfil(pgc_core_t *pgc) { - uint8_t param; + uint8_t param; - if (!pgc_param_byte(pgc, ¶m)) - return; + if (!pgc_param_byte(pgc, ¶m)) + return; - PGCLOG(("PRMFIL(%d)\n", param)); - if (param < 3) { - pgc->fill_mode = param; - } else { - pgc_error(pgc, PGC_ERROR_RANGE); - } + PGCLOG(("PRMFIL(%d)\n", param)); + if (param < 3) { + pgc->fill_mode = param; + } else { + pgc_error(pgc, PGC_ERROR_RANGE); + } } /* Set the 2D drawing position */ static void hndl_move(pgc_core_t *pgc) { - int32_t x = 0, y = 0; + int32_t x = 0, y = 0; - if (!pgc_param_coord(pgc, &x)) - return; - if (!pgc_param_coord(pgc, &y)) - return; + if (!pgc_param_coord(pgc, &x)) + return; + if (!pgc_param_coord(pgc, &y)) + return; - pgc->x = x; - pgc->y = y; - PGCLOG(("MOVE %x.%04x,%x.%04x\n", HWORD(x), LWORD(x), HWORD(y), LWORD(y))); + pgc->x = x; + pgc->y = y; + PGCLOG(("MOVE %x.%04x,%x.%04x\n", HWORD(x), LWORD(x), HWORD(y), LWORD(y))); } /* Set the 3D drawing position */ static void hndl_move3(pgc_core_t *pgc) { - int32_t x = 0, y = 0, z = 0; + int32_t x = 0, y = 0, z = 0; - if (!pgc_param_coord(pgc, &x)) - return; - if (!pgc_param_coord(pgc, &y)) - return; - if (!pgc_param_coord(pgc, &z)) - return; + if (!pgc_param_coord(pgc, &x)) + return; + if (!pgc_param_coord(pgc, &y)) + return; + if (!pgc_param_coord(pgc, &z)) + return; - pgc->x = x; - pgc->y = y; - pgc->z = z; + pgc->x = x; + pgc->y = y; + pgc->z = z; } /* Relative move (2D) */ static void hndl_mover(pgc_core_t *pgc) { - int32_t x = 0, y = 0; + int32_t x = 0, y = 0; - if (!pgc_param_coord(pgc, &x)) - return; - if (!pgc_param_coord(pgc, &y)) - return; + if (!pgc_param_coord(pgc, &x)) + return; + if (!pgc_param_coord(pgc, &y)) + return; - pgc->x += x; - pgc->y += y; + pgc->x += x; + pgc->y += y; } /* Relative move (3D) */ static void hndl_mover3(pgc_core_t *pgc) { - int32_t x = 0, y = 0, z = 0; + int32_t x = 0, y = 0, z = 0; - if (!pgc_param_coord(pgc, &x)) - return; - if (!pgc_param_coord(pgc, &y)) - return; - if (!pgc_param_coord(pgc, &z)) - return; + if (!pgc_param_coord(pgc, &x)) + return; + if (!pgc_param_coord(pgc, &y)) + return; + if (!pgc_param_coord(pgc, &z)) + return; - pgc->x += x; - pgc->y += y; - pgc->z += z; + pgc->x += x; + pgc->y += y; + pgc->z += z; } /* Draw a line (using PGC fixed-point coordinates) */ uint16_t pgc_draw_line(pgc_core_t *pgc, int32_t x0, int32_t y0, int32_t x1, int32_t y1, uint16_t linemask) { - PGCLOG(("pgc_draw_line: (%d,%d) to (%d,%d)\n", x0 >> 16, y0 >> 16, - x1 >> 16, y1 >> 16)); - /* Convert from PGC fixed-point to device coordinates */ - x0 >>= 16; - x1 >>= 16; - y0 >>= 16; - y1 >>= 16; + PGCLOG(("pgc_draw_line: (%d,%d) to (%d,%d)\n", x0 >> 16, y0 >> 16, x1 >> 16, y1 >> 16)); + /* Convert from PGC fixed-point to device coordinates */ + x0 >>= 16; + x1 >>= 16; + y0 >>= 16; + y1 >>= 16; - pgc_ito_raster(pgc, &x0, &y0); - pgc_ito_raster(pgc, &x1, &y1); + pgc_ito_raster(pgc, &x0, &y0); + pgc_ito_raster(pgc, &x1, &y1); - return pgc_draw_line_r(pgc, x0, y0, x1, y1, linemask); + return pgc_draw_line_r(pgc, x0, y0, x1, y1, linemask); } /* Draw a line (using raster coordinates) - Bresenham's Algorithm from + Bresenham's Algorithm from * * The line pattern mask to use is passed in. The return value is the line * pattern mask rotated by the number of points drawn. */ uint16_t pgc_draw_line_r(pgc_core_t *pgc, int32_t x0, int32_t y0, int32_t x1, int32_t y1, uint16_t linemask) { - int32_t dx, dy, sx, sy, err, e2; + int32_t dx, dy, sx, sy, err, e2; - dx = abs(x1 - x0); - dy = abs(y1 - y0); - sx = (x0 < x1) ? 1 : -1; - sy = (y0 < y1) ? 1 : -1; - err = (dx > dy ? dx : -dy) / 2; + dx = abs(x1 - x0); + dy = abs(y1 - y0); + sx = (x0 < x1) ? 1 : -1; + sy = (y0 < y1) ? 1 : -1; + err = (dx > dy ? dx : -dy) / 2; - for (;;) { - if (linemask & 0x8000) { - pgc_plot(pgc, x0, y0); - linemask = (linemask << 1) | 1; - } else { - linemask = (linemask << 1); - } - if (x0 == x1 && y0 == y1) - break; - e2 = err; - if (e2 > -dx) { - err -= dy; - x0 += sx; - } - if (e2 < dy) { - err += dx; - y0 += sy; - } - } - return linemask; + for (;;) { + if (linemask & 0x8000) { + pgc_plot(pgc, x0, y0); + linemask = (linemask << 1) | 1; + } else { + linemask = (linemask << 1); + } + if (x0 == x1 && y0 == y1) + break; + e2 = err; + if (e2 > -dx) { + err -= dy; + x0 += sx; + } + if (e2 < dy) { + err += dx; + y0 += sy; + } + } + return linemask; } -/* Draw a horizontal line in the current fill pattern +/* Draw a horizontal line in the current fill pattern * (using raster coordinates) */ void pgc_fill_line_r(pgc_core_t *pgc, int32_t x0, int32_t x1, int32_t y0) { - int32_t x; - int32_t mask = 0x8000 >> (x0 & 0x0F); + int32_t x; + int32_t mask = 0x8000 >> (x0 & 0x0F); - if (x0 > x1) { - x = x1; - x1 = x0; - x0 = x; - } + if (x0 > x1) { + x = x1; + x1 = x0; + x0 = x; + } - for (x = x0; x <= x1; x++) { - if (pgc->fill_pattern[y0 & 0x0F] & mask) - pgc_plot(pgc, x, y0); - mask = mask >> 1; - if (mask == 0) - mask = 0x8000; - } + for (x = x0; x <= x1; x++) { + if (pgc->fill_pattern[y0 & 0x0F] & mask) + pgc_plot(pgc, x, y0); + mask = mask >> 1; + if (mask == 0) + mask = 0x8000; + } } /* For sorting polygon nodes */ static int compare_double(const void *a, const void *b) { - const double *da = (const double *)a; - const double *db = (const double *)b; + const double *da = (const double *)a; + const double *db = (const double *)b; - if (*da > *db) - return 1; - if (*da < *db) - return -1; - return 0; + if (*da > *db) + return 1; + if (*da < *db) + return -1; + return 0; } /* Draw a filled polygon (using PGC fixed-point coordinates) */ -void pgc_fill_polygon(pgc_core_t *pgc, - unsigned corners, int32_t *x, int32_t *y) { - double *nodex; - double *dx; - double *dy; - unsigned n, nodes, i, j; - double ymin, ymax, ypos; +void pgc_fill_polygon(pgc_core_t *pgc, unsigned corners, int32_t *x, int32_t *y) { + double *nodex; + double *dx; + double *dy; + unsigned n, nodes, i, j; + double ymin, ymax, ypos; - PGCLOG(("pgc_fill_polygon(%d corners)\n", corners)); + PGCLOG(("pgc_fill_polygon(%d corners)\n", corners)); - if (corners < 2) - return; /* Degenerate polygon */ - nodex = malloc(corners * sizeof(double)); - dx = malloc(corners * sizeof(double)); - dy = malloc(corners * sizeof(double)); - if (!nodex || !dx || !dy) - return; + if (corners < 2) + return; /* Degenerate polygon */ + nodex = malloc(corners * sizeof(double)); + dx = malloc(corners * sizeof(double)); + dy = malloc(corners * sizeof(double)); + if (!nodex || !dx || !dy) + return; - ymin = ymax = y[0] / 65536.0; - for (n = 0; n < corners; n++) { - /* Convert from PGC fixed-point to native floating-point */ - dx[n] = x[n] / 65536.0; - dy[n] = y[n] / 65536.0; + ymin = ymax = y[0] / 65536.0; + for (n = 0; n < corners; n++) { + /* Convert from PGC fixed-point to native floating-point */ + dx[n] = x[n] / 65536.0; + dy[n] = y[n] / 65536.0; - if (dy[n] < ymin) - ymin = dy[n]; - if (dy[n] > ymax) - ymax = dy[n]; - } - /* Polygon fill. Based on */ - /* For each row, work out where the polygon lines intersect with - * that row. */ - for (ypos = ymin; ypos <= ymax; ypos++) { - nodes = 0; - j = corners - 1; - for (i = 0; i < corners; i++) { - if ((dy[i] < ypos && dy[j] >= ypos) - || (dy[j] < ypos && dy[i] >= ypos)) /* Line crosses */ - { - nodex[nodes++] = dx[i] + (ypos - dy[i]) / (dy[j] - dy[i]) * (dx[j] - dx[i]); - } - j = i; - } + if (dy[n] < ymin) + ymin = dy[n]; + if (dy[n] > ymax) + ymax = dy[n]; + } + /* Polygon fill. Based on */ + /* For each row, work out where the polygon lines intersect with + * that row. */ + for (ypos = ymin; ypos <= ymax; ypos++) { + nodes = 0; + j = corners - 1; + for (i = 0; i < corners; i++) { + if ((dy[i] < ypos && dy[j] >= ypos) || (dy[j] < ypos && dy[i] >= ypos)) /* Line crosses */ + { + nodex[nodes++] = dx[i] + (ypos - dy[i]) / (dy[j] - dy[i]) * (dx[j] - dx[i]); + } + j = i; + } - /* Sort the intersections */ - if (nodes) - qsort(nodex, nodes, sizeof(double), compare_double); -/* - PGCLOG(("pgc_fill_polygon ypos=%f nodes=%d ", ypos, nodes)); - for (i = 0; i < nodes; i++) - { - PGCLOG(("%f;", nodex[i])); - } - PGCLOG(("\n")); -*/ - /* And fill between them */ - for (i = 0; i < nodes; i += 2) { - int16_t x1 = nodex[i], x2 = nodex[i + 1], - y1 = ypos, y2 = ypos; - pgc_sto_raster(pgc, &x1, &y1); - pgc_sto_raster(pgc, &x2, &y2); -/* PGCLOG(("pgc_fill_polygon raster %d,%d to %d,%d\n", - x1, y1, x2, y2)); */ - pgc_fill_line_r(pgc, x1, x2, y1); - } - } - free(nodex); - free(dx); - free(dy); + /* Sort the intersections */ + if (nodes) + qsort(nodex, nodes, sizeof(double), compare_double); + /* + PGCLOG(("pgc_fill_polygon ypos=%f nodes=%d ", ypos, nodes)); + for (i = 0; i < nodes; i++) + { + PGCLOG(("%f;", nodex[i])); + } + PGCLOG(("\n")); + */ + /* And fill between them */ + for (i = 0; i < nodes; i += 2) { + int16_t x1 = nodex[i], x2 = nodex[i + 1], y1 = ypos, y2 = ypos; + pgc_sto_raster(pgc, &x1, &y1); + pgc_sto_raster(pgc, &x2, &y2); + /* PGCLOG(("pgc_fill_polygon raster %d,%d to %d,%d\n", + x1, y1, x2, y2)); */ + pgc_fill_line_r(pgc, x1, x2, y1); + } + } + free(nodex); + free(dx); + free(dy); } /* Draw a filled ellipse (using PGC fixed-point coordinates) */ void pgc_draw_ellipse(pgc_core_t *pgc, int32_t x, int32_t y) { - /* Convert from PGC fixed-point to native floating-point */ - double h = y / 65536.0; - double w = x / 65536.0; - double y0 = pgc->y / 65536.0; - double x0 = pgc->x / 65536.0; - double ypos = 0.0, xpos = 0.0; - double x1; - double xlast = 0.0; - int16_t linemask = pgc->line_pattern; + /* Convert from PGC fixed-point to native floating-point */ + double h = y / 65536.0; + double w = x / 65536.0; + double y0 = pgc->y / 65536.0; + double x0 = pgc->x / 65536.0; + double ypos = 0.0, xpos = 0.0; + double x1; + double xlast = 0.0; + int16_t linemask = pgc->line_pattern; - pgc_dto_raster(pgc, &x0, &y0); - PGCLOG(("Ellipse: Colour=%d Drawmode=%d fill=%d\n", pgc->colour, - pgc->draw_mode, pgc->fill_mode)); - for (ypos = 0; ypos <= h; ypos++) { - if (ypos == 0) { - if (pgc->fill_mode) { - pgc_fill_line_r(pgc, x0 - w, x0 + w, y0); - } - if (linemask & 0x8000) { - pgc_plot(pgc, x0 + w, y0); - pgc_plot(pgc, x0 - w, y0); - linemask = (linemask << 1) | 1; - } else { - linemask = linemask << 1; - } - xlast = w; - } else { - x1 = sqrt((h * h) - (ypos * ypos)) * w / h; + pgc_dto_raster(pgc, &x0, &y0); + PGCLOG(("Ellipse: Colour=%d Drawmode=%d fill=%d\n", pgc->colour, pgc->draw_mode, pgc->fill_mode)); + for (ypos = 0; ypos <= h; ypos++) { + if (ypos == 0) { + if (pgc->fill_mode) { + pgc_fill_line_r(pgc, x0 - w, x0 + w, y0); + } + if (linemask & 0x8000) { + pgc_plot(pgc, x0 + w, y0); + pgc_plot(pgc, x0 - w, y0); + linemask = (linemask << 1) | 1; + } else { + linemask = linemask << 1; + } + xlast = w; + } else { + x1 = sqrt((h * h) - (ypos * ypos)) * w / h; - if (pgc->fill_mode) { - pgc_fill_line_r(pgc, x0 - x1, x0 + x1, y0 + ypos); - pgc_fill_line_r(pgc, x0 - x1, x0 + x1, y0 - ypos); - } + if (pgc->fill_mode) { + pgc_fill_line_r(pgc, x0 - x1, x0 + x1, y0 + ypos); + pgc_fill_line_r(pgc, x0 - x1, x0 + x1, y0 - ypos); + } - /* Draw border */ - for (xpos = xlast; xpos >= x1; xpos--) { - if (linemask & 0x8000) { - pgc_plot(pgc, x0 + xpos, y0 + ypos); - pgc_plot(pgc, x0 - xpos, y0 + ypos); - pgc_plot(pgc, x0 + xpos, y0 - ypos); - pgc_plot(pgc, x0 - xpos, y0 - ypos); - linemask = (linemask << 1) | 1; - } else { - linemask = linemask << 1; - } - - } - xlast = x1; - } - } + /* Draw border */ + for (xpos = xlast; xpos >= x1; xpos--) { + if (linemask & 0x8000) { + pgc_plot(pgc, x0 + xpos, y0 + ypos); + pgc_plot(pgc, x0 - xpos, y0 + ypos); + pgc_plot(pgc, x0 + xpos, y0 - ypos); + pgc_plot(pgc, x0 - xpos, y0 - ypos); + linemask = (linemask << 1) | 1; + } else { + linemask = linemask << 1; + } + } + xlast = x1; + } + } } /* Handle the ELIPSE (sic) command */ static void hndl_ellipse(pgc_core_t *pgc) { - int32_t x = 0, y = 0; + int32_t x = 0, y = 0; - if (!pgc_param_coord(pgc, &x)) - return; - if (!pgc_param_coord(pgc, &y)) - return; + if (!pgc_param_coord(pgc, &x)) + return; + if (!pgc_param_coord(pgc, &y)) + return; - pgc_draw_ellipse(pgc, x, y); + pgc_draw_ellipse(pgc, x, y); } /* Handle the POLY command */ static void hndl_poly(pgc_core_t *pgc) { - uint8_t count; - int32_t x[256]; - int32_t y[256]; - int32_t n; + uint8_t count; + int32_t x[256]; + int32_t y[256]; + int32_t n; - if (!pgc_param_byte(pgc, &count)) - return; + if (!pgc_param_byte(pgc, &count)) + return; - for (n = 0; n < count; n++) { - if (!pgc_param_coord(pgc, &x[n])) - return; - if (!pgc_param_coord(pgc, &y[n])) - return; - } - PGCLOG(("POLY (%d)\n", count)); + for (n = 0; n < count; n++) { + if (!pgc_param_coord(pgc, &x[n])) + return; + if (!pgc_param_coord(pgc, &y[n])) + return; + } + PGCLOG(("POLY (%d)\n", count)); } /* Parse but don't execute a POLY command (for adding to a command list) */ static int parse_poly(pgc_core_t *pgc, pgc_commandlist_t *cl, int c) { - uint8_t count; + uint8_t count; - PGCLOG(("parse_poly\n")); - if (!pgc_param_byte(pgc, &count)) - return 0; - PGCLOG(("parse_poly: count=%02x\n", count)); + PGCLOG(("parse_poly\n")); + if (!pgc_param_byte(pgc, &count)) + return 0; + PGCLOG(("parse_poly: count=%02x\n", count)); - if (!pgc_commandlist_append(cl, count)) { - pgc_error(pgc, PGC_ERROR_OVERFLOW); - return 0; - } - PGCLOG(("parse_poly: parse %d coords\n", 2 * count)); - return pgc_parse_coords(pgc, cl, 2 * count); + if (!pgc_commandlist_append(cl, count)) { + pgc_error(pgc, PGC_ERROR_OVERFLOW); + return 0; + } + PGCLOG(("parse_poly: parse %d coords\n", 2 * count)); + return pgc_parse_coords(pgc, cl, 2 * count); } /* Parse but don't execute a command with a fixed number of byte parameters */ int pgc_parse_bytes(pgc_core_t *pgc, pgc_commandlist_t *cl, int count) { - uint8_t *param = malloc(count); - int n; + uint8_t *param = malloc(count); + int n; - if (!param) { - pgc_error(pgc, PGC_ERROR_OVERFLOW); - return 0; - } - for (n = 0; n < count; n++) { - if (!pgc_param_byte(pgc, ¶m[n])) { - free(param); - return 0; - } - } - for (n = 0; n < count; n++) { - if (!pgc_commandlist_append(cl, param[n])) { - pgc_error(pgc, PGC_ERROR_OVERFLOW); - free(param); - return 0; - } - } - free(param); - return 1; + if (!param) { + pgc_error(pgc, PGC_ERROR_OVERFLOW); + return 0; + } + for (n = 0; n < count; n++) { + if (!pgc_param_byte(pgc, ¶m[n])) { + free(param); + return 0; + } + } + for (n = 0; n < count; n++) { + if (!pgc_commandlist_append(cl, param[n])) { + pgc_error(pgc, PGC_ERROR_OVERFLOW); + free(param); + return 0; + } + } + free(param); + return 1; } /* Parse but don't execute a command with a fixed number of word parameters */ int pgc_parse_words(pgc_core_t *pgc, pgc_commandlist_t *cl, int count) { - int16_t *param = malloc(count * sizeof(int16_t)); - int n; + int16_t *param = malloc(count * sizeof(int16_t)); + int n; - if (!param) { - pgc_error(pgc, PGC_ERROR_OVERFLOW); - return 0; - } - for (n = 0; n < count; n++) { - if (!pgc_param_word(pgc, ¶m[n])) - return 0; - } - for (n = 0; n < count; n++) { - if (!pgc_commandlist_append(cl, param[n] & 0xFF) || - !pgc_commandlist_append(cl, param[n] >> 8)) { - pgc_error(pgc, PGC_ERROR_OVERFLOW); - free(param); - return 0; - } - } - return 1; + if (!param) { + pgc_error(pgc, PGC_ERROR_OVERFLOW); + return 0; + } + for (n = 0; n < count; n++) { + if (!pgc_param_word(pgc, ¶m[n])) + return 0; + } + for (n = 0; n < count; n++) { + if (!pgc_commandlist_append(cl, param[n] & 0xFF) || !pgc_commandlist_append(cl, param[n] >> 8)) { + pgc_error(pgc, PGC_ERROR_OVERFLOW); + free(param); + return 0; + } + } + return 1; } /* Parse but don't execute a command with a fixed number of coord parameters */ int pgc_parse_coords(pgc_core_t *pgc, pgc_commandlist_t *cl, int count) { - int32_t *param = malloc(count * sizeof(int32_t)); - int n; + int32_t *param = malloc(count * sizeof(int32_t)); + int n; - if (!param) { - pgc_error(pgc, PGC_ERROR_OVERFLOW); - return 0; - } - for (n = 0; n < count; n++) { - if (!pgc_param_coord(pgc, ¶m[n])) - return 0; - } -/* Here's how the real PGC serialises coords: - * - * 100.5 -> 64 00 00 80 ie 0064.8000 - * 100.3 -> 64 00 CD 4C ie 0064.4CCD - * - */ - for (n = 0; n < count; n++) { - /* Serialise integer part */ - if (!pgc_commandlist_append(cl, (param[n] >> 16) & 0xFF) || - !pgc_commandlist_append(cl, (param[n] >> 24) & 0xFF) || - /* Serialise fraction part */ - !pgc_commandlist_append(cl, (param[n]) & 0xFF) || - !pgc_commandlist_append(cl, (param[n] >> 8) & 0xFF)) { - pgc_error(pgc, PGC_ERROR_OVERFLOW); - free(param); - return 0; - } - } - return 1; + if (!param) { + pgc_error(pgc, PGC_ERROR_OVERFLOW); + return 0; + } + for (n = 0; n < count; n++) { + if (!pgc_param_coord(pgc, ¶m[n])) + return 0; + } + /* Here's how the real PGC serialises coords: + * + * 100.5 -> 64 00 00 80 ie 0064.8000 + * 100.3 -> 64 00 CD 4C ie 0064.4CCD + * + */ + for (n = 0; n < count; n++) { + /* Serialise integer part */ + if (!pgc_commandlist_append(cl, (param[n] >> 16) & 0xFF) || + !pgc_commandlist_append(cl, (param[n] >> 24) & 0xFF) || + /* Serialise fraction part */ + !pgc_commandlist_append(cl, (param[n]) & 0xFF) || !pgc_commandlist_append(cl, (param[n] >> 8) & 0xFF)) { + pgc_error(pgc, PGC_ERROR_OVERFLOW); + free(param); + return 0; + } + } + return 1; } /* Handle the DISPLAY command */ static void hndl_display(pgc_core_t *pgc) { - uint8_t param; + uint8_t param; - if (!pgc_param_byte(pgc, ¶m)) - return; + if (!pgc_param_byte(pgc, ¶m)) + return; - PGCLOG(("DISPLAY(%d)\n", param)); - if (param > 1) { - pgc_error(pgc, PGC_ERROR_RANGE); - } else { - pgc_setdisplay(pgc, param); - } + PGCLOG(("DISPLAY(%d)\n", param)); + if (param > 1) { + pgc_error(pgc, PGC_ERROR_RANGE); + } else { + pgc_setdisplay(pgc, param); + } } /* Handle the IMAGEW command (memory to screen blit) */ static void hndl_imagew(pgc_core_t *pgc) { - int16_t row, col1, col2; - uint8_t v1, v2; + int16_t row, col1, col2; + uint8_t v1, v2; - if (!pgc_param_word(pgc, &row)) - return; - if (!pgc_param_word(pgc, &col1)) - return; - if (!pgc_param_word(pgc, &col2)) - return; + if (!pgc_param_word(pgc, &row)) + return; + if (!pgc_param_word(pgc, &col1)) + return; + if (!pgc_param_word(pgc, &col2)) + return; - if (row >= pgc->screenh || col1 >= pgc->maxw || col2 >= pgc->maxw) { - pgc_error(pgc, PGC_ERROR_RANGE); - return; - } + if (row >= pgc->screenh || col1 >= pgc->maxw || col2 >= pgc->maxw) { + pgc_error(pgc, PGC_ERROR_RANGE); + return; + } - /* In ASCII mode, what is written is a stream of bytes */ - if (pgc->ascii_mode) { - while (col1 <= col2) { - if (!pgc_param_byte(pgc, &v1)) - return; - pgc_write_pixel(pgc, col1, row, v1); - ++col1; - } - return; - } else /* In hex mode, it's RLE compressed */ - { - while (col1 <= col2) { - if (!pgc_param_byte(pgc, &v1)) - return; + /* In ASCII mode, what is written is a stream of bytes */ + if (pgc->ascii_mode) { + while (col1 <= col2) { + if (!pgc_param_byte(pgc, &v1)) + return; + pgc_write_pixel(pgc, col1, row, v1); + ++col1; + } + return; + } else /* In hex mode, it's RLE compressed */ + { + while (col1 <= col2) { + if (!pgc_param_byte(pgc, &v1)) + return; - if (v1 & 0x80) /* Literal run */ - { - v1 -= 0x7F; - while (col1 <= col2 && v1 != 0) { - if (!pgc_param_byte(pgc, &v2)) - return; - pgc_write_pixel(pgc, col1, row, v2); - ++col1; - --v1; - } - } else /* Repeated run */ - { - if (!pgc_param_byte(pgc, &v2)) - return; + if (v1 & 0x80) /* Literal run */ + { + v1 -= 0x7F; + while (col1 <= col2 && v1 != 0) { + if (!pgc_param_byte(pgc, &v2)) + return; + pgc_write_pixel(pgc, col1, row, v2); + ++col1; + --v1; + } + } else /* Repeated run */ + { + if (!pgc_param_byte(pgc, &v2)) + return; - ++v1; - while (col1 <= col2 && v1 != 0) { - pgc_write_pixel(pgc, col1, row, v2); - ++col1; - --v1; - } - } - } - } + ++v1; + while (col1 <= col2 && v1 != 0) { + pgc_write_pixel(pgc, col1, row, v2); + ++col1; + --v1; + } + } + } + } } /* Select one of the built-in palettes */ static void pgc_init_lut(pgc_core_t *pgc, int param) { - if (param >= 0 && param < 6) { - memcpy(pgc->palette, init_palette[param], sizeof(pgc->palette)); - } else if (param == 0xFF) { - memcpy(pgc->palette, pgc->userpal, sizeof(pgc->palette)); - } else { - pgc_error(pgc, PGC_ERROR_RANGE); - } + if (param >= 0 && param < 6) { + memcpy(pgc->palette, init_palette[param], sizeof(pgc->palette)); + } else if (param == 0xFF) { + memcpy(pgc->palette, pgc->userpal, sizeof(pgc->palette)); + } else { + pgc_error(pgc, PGC_ERROR_RANGE); + } } /* Save the current palette */ -static void hndl_lutsav(pgc_core_t *pgc) { - memcpy(pgc->userpal, pgc->palette, sizeof(pgc->palette)); -} +static void hndl_lutsav(pgc_core_t *pgc) { memcpy(pgc->userpal, pgc->palette, sizeof(pgc->palette)); } /* Handle LUTINT (select palette) */ static void hndl_lutint(pgc_core_t *pgc) { - uint8_t param; + uint8_t param; - if (!pgc_param_byte(pgc, ¶m)) - return; + if (!pgc_param_byte(pgc, ¶m)) + return; - pgc_init_lut(pgc, param); + pgc_init_lut(pgc, param); } /* Handle LUTRD (read palette register) */ static void hndl_lutrd(pgc_core_t *pgc) { - uint8_t param; - uint32_t col; + uint8_t param; + uint32_t col; - if (!pgc_param_byte(pgc, ¶m)) - return; + if (!pgc_param_byte(pgc, ¶m)) + return; - col = pgc->palette[param]; + col = pgc->palette[param]; - pgc_result_byte(pgc, (col >> 20) & 0x0F); - pgc_result_byte(pgc, (col >> 12) & 0x0F); - pgc_result_byte(pgc, (col >> 4) & 0x0F); + pgc_result_byte(pgc, (col >> 20) & 0x0F); + pgc_result_byte(pgc, (col >> 12) & 0x0F); + pgc_result_byte(pgc, (col >> 4) & 0x0F); } /* Handle LUT (write palette register) */ static void hndl_lut(pgc_core_t *pgc) { - uint8_t param[4]; - int n; + uint8_t param[4]; + int n; - for (n = 0; n < 4; n++) { - if (!pgc_param_byte(pgc, ¶m[n])) - return; - if (n > 0 && param[n] > 15) { - pgc_error(pgc, PGC_ERROR_RANGE); - param[n] &= 0x0F; - } - } - pgc->palette[param[0]] = makecol((param[1] * 0x11), - (param[2] * 0x11), - (param[3] * 0x11)); + for (n = 0; n < 4; n++) { + if (!pgc_param_byte(pgc, ¶m[n])) + return; + if (n > 0 && param[n] > 15) { + pgc_error(pgc, PGC_ERROR_RANGE); + param[n] &= 0x0F; + } + } + pgc->palette[param[0]] = makecol((param[1] * 0x11), (param[2] * 0x11), (param[3] * 0x11)); } /* LUT8RD and LUT8 are extensions implemented by several PGC clones, so - * here are functions that implement them even though they aren't + * here are functions that implement them even though they aren't * used by the PGC */ void pgc_hndl_lut8rd(pgc_core_t *pgc) { - uint8_t param; - uint32_t col; + uint8_t param; + uint32_t col; - if (!pgc_param_byte(pgc, ¶m)) - return; + if (!pgc_param_byte(pgc, ¶m)) + return; - col = pgc->palette[param]; + col = pgc->palette[param]; - pgc_result_byte(pgc, (col >> 16) & 0xFF); - pgc_result_byte(pgc, (col >> 8) & 0xFF); - pgc_result_byte(pgc, col & 0xFF); + pgc_result_byte(pgc, (col >> 16) & 0xFF); + pgc_result_byte(pgc, (col >> 8) & 0xFF); + pgc_result_byte(pgc, col & 0xFF); } void pgc_hndl_lut8(pgc_core_t *pgc) { - uint8_t param[4]; - int n; + uint8_t param[4]; + int n; - for (n = 0; n < 4; n++) { - if (!pgc_param_byte(pgc, ¶m[n])) - return; - } - pgc->palette[param[0]] = makecol((param[1]), (param[2]), (param[3])); + for (n = 0; n < 4; n++) { + if (!pgc_param_byte(pgc, ¶m[n])) + return; + } + pgc->palette[param[0]] = makecol((param[1]), (param[2]), (param[3])); } /* Handle AREAPT (set 16x16 fill pattern) */ static void hndl_areapt(pgc_core_t *pgc) { - int16_t pattern[16]; - int n; + int16_t pattern[16]; + int n; - for (n = 0; n < 16; n++) { - if (!pgc_param_word(pgc, &pattern[n])) - return; - } - memcpy(pgc->fill_pattern, pattern, sizeof(pgc->fill_pattern)); - PGCLOG(("AREAPT(%04x %04x %04x %04x...)\n", - pattern[0] & 0xFFFF, pattern[1] & 0xFFFF, - pattern[2] & 0xFFFF, pattern[3] & 0xFFFF)); + for (n = 0; n < 16; n++) { + if (!pgc_param_word(pgc, &pattern[n])) + return; + } + memcpy(pgc->fill_pattern, pattern, sizeof(pgc->fill_pattern)); + PGCLOG(("AREAPT(%04x %04x %04x %04x...)\n", pattern[0] & 0xFFFF, pattern[1] & 0xFFFF, pattern[2] & 0xFFFF, + pattern[3] & 0xFFFF)); } /* Handle CA (select ASCII mode) */ -static void hndl_ca(pgc_core_t *pgc) { - pgc->ascii_mode = 1; -} +static void hndl_ca(pgc_core_t *pgc) { pgc->ascii_mode = 1; } /* Handle CX (select hex mode) */ -static void hndl_cx(pgc_core_t *pgc) { - pgc->ascii_mode = 0; -} +static void hndl_cx(pgc_core_t *pgc) { pgc->ascii_mode = 0; } -/* CA and CX remain valid in hex mode; they are handled as command 0x43 ('C') +/* CA and CX remain valid in hex mode; they are handled as command 0x43 ('C') * with a one-byte parameter */ static void hndl_c(pgc_core_t *pgc) { - uint8_t param; + uint8_t param; - if (!pgc->inputbyte(pgc, ¶m)) - return; + if (!pgc->inputbyte(pgc, ¶m)) + return; - if (param == 'A') - pgc->ascii_mode = 1; - if (param == 'X') - pgc->ascii_mode = 0; + if (param == 'A') + pgc->ascii_mode = 1; + if (param == 'X') + pgc->ascii_mode = 0; } /* RESETF resets the PGC */ -static void hndl_resetf(pgc_core_t *pgc) { - pgc_reset(pgc); -} +static void hndl_resetf(pgc_core_t *pgc) { pgc_reset(pgc); } /* TJUST sets text justify settings */ static void hndl_tjust(pgc_core_t *pgc) { - uint8_t param[2]; + uint8_t param[2]; - if (!pgc->inputbyte(pgc, ¶m[0])) - return; - if (!pgc->inputbyte(pgc, ¶m[1])) - return; + if (!pgc->inputbyte(pgc, ¶m[0])) + return; + if (!pgc->inputbyte(pgc, ¶m[1])) + return; - if (param[0] >= 1 && param[0] <= 3 && - param[1] >= 1 && param[1] <= 3) { - pgc->tjust_h = param[0]; - pgc->tjust_v = param[1]; - } else { - pgc_error(pgc, PGC_ERROR_RANGE); - } + if (param[0] >= 1 && param[0] <= 3 && param[1] >= 1 && param[1] <= 3) { + pgc->tjust_h = param[0]; + pgc->tjust_v = param[1]; + } else { + pgc_error(pgc, PGC_ERROR_RANGE); + } } /* TSIZE controls text horizontal spacing */ static void hndl_tsize(pgc_core_t *pgc) { - int32_t param = 0; + int32_t param = 0; - if (!pgc_param_coord(pgc, ¶m)) - return; + if (!pgc_param_coord(pgc, ¶m)) + return; - pgc->tsize = param; - PGCLOG(("TSIZE %d\n", param)); + pgc->tsize = param; + PGCLOG(("TSIZE %d\n", param)); } /* VWPORT sets up the viewport (roughly, the clip rectangle) in raster * coordinates, measured from the bottom left of the screen */ static void hndl_vwport(pgc_core_t *pgc) { - int16_t x1, x2, y1, y2; + int16_t x1, x2, y1, y2; - if (!pgc_param_word(pgc, &x1)) - return; - if (!pgc_param_word(pgc, &x2)) - return; - if (!pgc_param_word(pgc, &y1)) - return; - if (!pgc_param_word(pgc, &y2)) - return; + if (!pgc_param_word(pgc, &x1)) + return; + if (!pgc_param_word(pgc, &x2)) + return; + if (!pgc_param_word(pgc, &y1)) + return; + if (!pgc_param_word(pgc, &y2)) + return; - PGCLOG(("VWPORT %d,%d,%d,%d\n", x1, x2, y1, y2)); - pgc->vp_x1 = x1; - pgc->vp_x2 = x2; - pgc->vp_y1 = y1; - pgc->vp_y2 = y2; + PGCLOG(("VWPORT %d,%d,%d,%d\n", x1, x2, y1, y2)); + pgc->vp_x1 = x1; + pgc->vp_x2 = x2; + pgc->vp_y1 = y1; + pgc->vp_y2 = y2; } /* WINDOW defines the coordinate system in use */ static void hndl_window(pgc_core_t *pgc) { - int16_t x1, x2, y1, y2; + int16_t x1, x2, y1, y2; - if (!pgc_param_word(pgc, &x1)) - return; - if (!pgc_param_word(pgc, &x2)) - return; - if (!pgc_param_word(pgc, &y1)) - return; - if (!pgc_param_word(pgc, &y2)) - return; + if (!pgc_param_word(pgc, &x1)) + return; + if (!pgc_param_word(pgc, &x2)) + return; + if (!pgc_param_word(pgc, &y1)) + return; + if (!pgc_param_word(pgc, &y2)) + return; - PGCLOG(("WINDOW %d,%d,%d,%d\n", x1, x2, y1, y2)); - pgc->win_x1 = x1; - pgc->win_x2 = x2; - pgc->win_y1 = y1; - pgc->win_y2 = y2; + PGCLOG(("WINDOW %d,%d,%d,%d\n", x1, x2, y1, y2)); + pgc->win_x1 = x1; + pgc->win_x2 = x2; + pgc->win_y1 = y1; + pgc->win_y2 = y2; } /* The list of commands implemented by this mini-PGC. In order to support * the original PGC and clones, we support two lists; core commands (listed * below) and subclass commands (listed in the clone). - * + * * Each row has five parameters: * ASCII-mode command * Hex-mode command @@ -1039,7 +997,7 @@ static void hndl_window(pgc_core_t *pgc) { * * TODO: This list omits numerous commands present in a genuine PGC * (ARC, AREA, AREABC, BUFFER, CIRCLE etc etc). - * TODO: Some commands don't have a parse function (for example, IMAGEW) + * TODO: Some commands don't have a parse function (for example, IMAGEW) * * The following ASCII entries have special meaning: * ~~~~~~ command is valid only in hex mode @@ -1047,1175 +1005,1155 @@ static void hndl_window(pgc_core_t *pgc) { * @@@@@@ end of core command list * */ -static const pgc_command_t pgc_core_commands[] = - { - {"AREAPT", 0xE7, hndl_areapt, pgc_parse_words, 16}, - {"AP", 0xE7, hndl_areapt, pgc_parse_words, 16}, - {"~~~~~~", 0x43, hndl_c}, /* Handle CA / CX in hex mode */ - {"CA", 0xD2, hndl_ca}, - {"CLBEG", 0x70, hndl_clbeg}, - {"CB", 0x70, hndl_clbeg}, - {"CLDEL", 0x74, hndl_cldel, pgc_parse_bytes, 1}, - {"CD", 0x74, hndl_cldel, pgc_parse_bytes, 1}, - {"CLEND", 0x71, hndl_clend}, - {"CLRUN", 0x72, hndl_clrun, pgc_parse_bytes, 1}, - {"CR", 0x72, hndl_clrun, pgc_parse_bytes, 1}, - {"CLRD", 0x75, hndl_clread, pgc_parse_bytes, 1}, - {"CRD", 0x75, hndl_clread, pgc_parse_bytes, 1}, - {"CLOOP", 0x73, hndl_cloop}, - {"CL", 0x73, hndl_cloop}, - {"CLEARS", 0x0F, hndl_clears, pgc_parse_bytes, 1}, - {"CLS", 0x0F, hndl_clears, pgc_parse_bytes, 1}, - {"COLOR", 0x06, hndl_color, pgc_parse_bytes, 1}, - {"C", 0x06, hndl_color, pgc_parse_bytes, 1}, - {"CX", 0xD1, hndl_cx}, - {"DISPLA", 0xD0, hndl_display, pgc_parse_bytes, 1}, - {"DI", 0xD0, hndl_display, pgc_parse_bytes, 1}, - {"ELIPSE", 0x39, hndl_ellipse, pgc_parse_coords, 2}, - {"EL", 0x39, hndl_ellipse, pgc_parse_coords, 2}, - {"IMAGEW", 0xD9, hndl_imagew}, - {"IW", 0xD9, hndl_imagew}, - {"LINFUN", 0xEB, hndl_linfun, pgc_parse_bytes, 1}, - {"LF", 0xEB, hndl_linfun, pgc_parse_bytes, 1}, - {"LINPAT", 0xEA, hndl_linpat, pgc_parse_words, 1}, - {"LP", 0xEA, hndl_linpat, pgc_parse_words, 1}, - {"LUTINT", 0xEC, hndl_lutint, pgc_parse_bytes, 1}, - {"LI", 0xEC, hndl_lutint, pgc_parse_bytes, 1}, - {"LUTRD", 0x50, hndl_lutrd, pgc_parse_bytes, 1}, - {"LUTSAV", 0xED, hndl_lutsav, NULL, 0}, - {"LUT", 0xEE, hndl_lut, pgc_parse_bytes, 4}, - {"MOVE", 0x10, hndl_move, pgc_parse_coords, 2}, - {"M", 0x10, hndl_move, pgc_parse_coords, 2}, - {"MOVE3", 0x12, hndl_move3, pgc_parse_coords, 3}, - {"M3", 0x12, hndl_move3, pgc_parse_coords, 3}, - {"MOVER", 0x11, hndl_mover, pgc_parse_coords, 2}, - {"MR", 0x11, hndl_mover, pgc_parse_coords, 2}, - {"MOVER3", 0x13, hndl_mover3, pgc_parse_coords, 3}, - {"MR3", 0x13, hndl_mover3, pgc_parse_coords, 3}, - {"PRMFIL", 0xE9, hndl_prmfil, pgc_parse_bytes, 1}, - {"PF", 0xE9, hndl_prmfil, pgc_parse_bytes, 1}, - {"POLY", 0x30, hndl_poly, parse_poly}, - {"P", 0x30, hndl_poly, parse_poly}, - {"RESETF", 0x04, hndl_resetf, NULL, 0}, - {"RF", 0x04, hndl_resetf, NULL, 0}, - {"TJUST", 0x85, hndl_tjust, pgc_parse_bytes, 2}, - {"TJ", 0x85, hndl_tjust, pgc_parse_bytes, 2}, - {"TSIZE", 0x81, hndl_tsize, pgc_parse_coords, 1}, - {"TS", 0x81, hndl_tsize, pgc_parse_coords, 1}, - {"VWPORT", 0xB2, hndl_vwport, pgc_parse_words, 4}, - {"VWP", 0xB2, hndl_vwport, pgc_parse_words, 4}, - {"WINDOW", 0xB3, hndl_window, pgc_parse_words, 4}, - {"WI", 0xB3, hndl_window, pgc_parse_words, 4}, +static const pgc_command_t pgc_core_commands[] = {{"AREAPT", 0xE7, hndl_areapt, pgc_parse_words, 16}, + {"AP", 0xE7, hndl_areapt, pgc_parse_words, 16}, + {"~~~~~~", 0x43, hndl_c}, /* Handle CA / CX in hex mode */ + {"CA", 0xD2, hndl_ca}, + {"CLBEG", 0x70, hndl_clbeg}, + {"CB", 0x70, hndl_clbeg}, + {"CLDEL", 0x74, hndl_cldel, pgc_parse_bytes, 1}, + {"CD", 0x74, hndl_cldel, pgc_parse_bytes, 1}, + {"CLEND", 0x71, hndl_clend}, + {"CLRUN", 0x72, hndl_clrun, pgc_parse_bytes, 1}, + {"CR", 0x72, hndl_clrun, pgc_parse_bytes, 1}, + {"CLRD", 0x75, hndl_clread, pgc_parse_bytes, 1}, + {"CRD", 0x75, hndl_clread, pgc_parse_bytes, 1}, + {"CLOOP", 0x73, hndl_cloop}, + {"CL", 0x73, hndl_cloop}, + {"CLEARS", 0x0F, hndl_clears, pgc_parse_bytes, 1}, + {"CLS", 0x0F, hndl_clears, pgc_parse_bytes, 1}, + {"COLOR", 0x06, hndl_color, pgc_parse_bytes, 1}, + {"C", 0x06, hndl_color, pgc_parse_bytes, 1}, + {"CX", 0xD1, hndl_cx}, + {"DISPLA", 0xD0, hndl_display, pgc_parse_bytes, 1}, + {"DI", 0xD0, hndl_display, pgc_parse_bytes, 1}, + {"ELIPSE", 0x39, hndl_ellipse, pgc_parse_coords, 2}, + {"EL", 0x39, hndl_ellipse, pgc_parse_coords, 2}, + {"IMAGEW", 0xD9, hndl_imagew}, + {"IW", 0xD9, hndl_imagew}, + {"LINFUN", 0xEB, hndl_linfun, pgc_parse_bytes, 1}, + {"LF", 0xEB, hndl_linfun, pgc_parse_bytes, 1}, + {"LINPAT", 0xEA, hndl_linpat, pgc_parse_words, 1}, + {"LP", 0xEA, hndl_linpat, pgc_parse_words, 1}, + {"LUTINT", 0xEC, hndl_lutint, pgc_parse_bytes, 1}, + {"LI", 0xEC, hndl_lutint, pgc_parse_bytes, 1}, + {"LUTRD", 0x50, hndl_lutrd, pgc_parse_bytes, 1}, + {"LUTSAV", 0xED, hndl_lutsav, NULL, 0}, + {"LUT", 0xEE, hndl_lut, pgc_parse_bytes, 4}, + {"MOVE", 0x10, hndl_move, pgc_parse_coords, 2}, + {"M", 0x10, hndl_move, pgc_parse_coords, 2}, + {"MOVE3", 0x12, hndl_move3, pgc_parse_coords, 3}, + {"M3", 0x12, hndl_move3, pgc_parse_coords, 3}, + {"MOVER", 0x11, hndl_mover, pgc_parse_coords, 2}, + {"MR", 0x11, hndl_mover, pgc_parse_coords, 2}, + {"MOVER3", 0x13, hndl_mover3, pgc_parse_coords, 3}, + {"MR3", 0x13, hndl_mover3, pgc_parse_coords, 3}, + {"PRMFIL", 0xE9, hndl_prmfil, pgc_parse_bytes, 1}, + {"PF", 0xE9, hndl_prmfil, pgc_parse_bytes, 1}, + {"POLY", 0x30, hndl_poly, parse_poly}, + {"P", 0x30, hndl_poly, parse_poly}, + {"RESETF", 0x04, hndl_resetf, NULL, 0}, + {"RF", 0x04, hndl_resetf, NULL, 0}, + {"TJUST", 0x85, hndl_tjust, pgc_parse_bytes, 2}, + {"TJ", 0x85, hndl_tjust, pgc_parse_bytes, 2}, + {"TSIZE", 0x81, hndl_tsize, pgc_parse_coords, 1}, + {"TS", 0x81, hndl_tsize, pgc_parse_coords, 1}, + {"VWPORT", 0xB2, hndl_vwport, pgc_parse_words, 4}, + {"VWP", 0xB2, hndl_vwport, pgc_parse_words, 4}, + {"WINDOW", 0xB3, hndl_window, pgc_parse_words, 4}, + {"WI", 0xB3, hndl_window, pgc_parse_words, 4}, - {"@@@@@@", 0x00, NULL} - }; + {"@@@@@@", 0x00, NULL}}; /* Writes to CGA registers are copied into the transfer memory buffer */ void pgc_out(uint16_t addr, uint8_t val, void *p) { - pgc_core_t *pgc = (pgc_core_t *)p; - - switch (addr) { - case 0x3D0: - case 0x3D2: - case 0x3D4: - case 0x3D6:pgc->mapram[0x3D0] = val; - break; - case 0x3D1: - case 0x3D3: - case 0x3D5: - case 0x3D7: - if (pgc->mapram[0x3D0] < 18) { - pgc->mapram[0x3E0 + pgc->mapram[0x3D0]] = val; - } - break; - case 0x3D8:pgc->mapram[0x3D8] = val; - break; - case 0x3D9:pgc->mapram[0x3D9] = val; - break; - } + pgc_core_t *pgc = (pgc_core_t *)p; + switch (addr) { + case 0x3D0: + case 0x3D2: + case 0x3D4: + case 0x3D6: + pgc->mapram[0x3D0] = val; + break; + case 0x3D1: + case 0x3D3: + case 0x3D5: + case 0x3D7: + if (pgc->mapram[0x3D0] < 18) { + pgc->mapram[0x3E0 + pgc->mapram[0x3D0]] = val; + } + break; + case 0x3D8: + pgc->mapram[0x3D8] = val; + break; + case 0x3D9: + pgc->mapram[0x3D9] = val; + break; + } } /* Read back the CGA registers */ uint8_t pgc_in(uint16_t addr, void *p) { - pgc_core_t *pgc = (pgc_core_t *)p; + pgc_core_t *pgc = (pgc_core_t *)p; - switch (addr) { - case 0x3D0: - case 0x3D2: - case 0x3D4: - case 0x3D6:return pgc->mapram[0x3D0]; - case 0x3D1: - case 0x3D3: - case 0x3D5: - case 0x3D7: - if (pgc->mapram[0x3D0] < 18) { - return pgc->mapram[0x3E0 + pgc->mapram[0x3D0]]; - } - return 0xFF; + switch (addr) { + case 0x3D0: + case 0x3D2: + case 0x3D4: + case 0x3D6: + return pgc->mapram[0x3D0]; + case 0x3D1: + case 0x3D3: + case 0x3D5: + case 0x3D7: + if (pgc->mapram[0x3D0] < 18) { + return pgc->mapram[0x3E0 + pgc->mapram[0x3D0]]; + } + return 0xFF; - case 0x3D8:return pgc->mapram[0x3D8]; - case 0x3D9:return pgc->mapram[0x3D9]; - case 0x3DA:return pgc->mapram[0x3DA]; - } - return 0xFF; + case 0x3D8: + return pgc->mapram[0x3D8]; + case 0x3D9: + return pgc->mapram[0x3D9]; + case 0x3DA: + return pgc->mapram[0x3DA]; + } + return 0xFF; } /* Memory write to the transfer buffer */ void pgc_write(uint32_t addr, uint8_t val, void *p) { - pgc_core_t *pgc = (pgc_core_t *)p; + pgc_core_t *pgc = (pgc_core_t *)p; - /* It seems variable whether the PGC maps 1k or 2k at 0xC6000. - * Map 2k here in case a clone requires it */ - if (addr >= 0xC6000 && addr < 0xC6800) { - addr &= 0x7FF; + /* It seems variable whether the PGC maps 1k or 2k at 0xC6000. + * Map 2k here in case a clone requires it */ + if (addr >= 0xC6000 && addr < 0xC6800) { + addr &= 0x7FF; - /* If one of the FIFOs has been updated, this may cause - * the drawing thread to be woken */ + /* If one of the FIFOs has been updated, this may cause + * the drawing thread to be woken */ - if (pgc->mapram[addr] != val) { - pgc->mapram[addr] = val; - switch (addr) { - case 0x300: /* Input write pointer */ - if (pgc->waiting_input_fifo && - pgc->mapram[0x300] != pgc->mapram[0x301]) { - pgc->waiting_input_fifo = 0; - pgc_wake(pgc); - } - break; + if (pgc->mapram[addr] != val) { + pgc->mapram[addr] = val; + switch (addr) { + case 0x300: /* Input write pointer */ + if (pgc->waiting_input_fifo && pgc->mapram[0x300] != pgc->mapram[0x301]) { + pgc->waiting_input_fifo = 0; + pgc_wake(pgc); + } + break; - case 0x303: /* Output read pointer */ - if (pgc->waiting_output_fifo && - pgc->mapram[0x302] != (uint8_t)(pgc->mapram[0x303] - 1)) { - pgc->waiting_output_fifo = 0; - pgc_wake(pgc); - } - break; + case 0x303: /* Output read pointer */ + if (pgc->waiting_output_fifo && pgc->mapram[0x302] != (uint8_t)(pgc->mapram[0x303] - 1)) { + pgc->waiting_output_fifo = 0; + pgc_wake(pgc); + } + break; - case 0x305: /* Error read pointer */ - if (pgc->waiting_error_fifo && - pgc->mapram[0x304] != (uint8_t)(pgc->mapram[0x305] - 1)) { - pgc->waiting_error_fifo = 0; - pgc_wake(pgc); - } - break; + case 0x305: /* Error read pointer */ + if (pgc->waiting_error_fifo && pgc->mapram[0x304] != (uint8_t)(pgc->mapram[0x305] - 1)) { + pgc->waiting_error_fifo = 0; + pgc_wake(pgc); + } + break; - case 0x306: /* Cold start flag */ - /* XXX This should be in IM-1024 specific code */ - pgc->mapram[0x306] = 0; - break; + case 0x306: /* Cold start flag */ + /* XXX This should be in IM-1024 specific code */ + pgc->mapram[0x306] = 0; + break; - case 0x030C: /* Display type */ - pgc_setdisplay(p, pgc->mapram[0x30C]); - pgc->mapram[0x30D] = pgc->mapram[0x30C]; - break; + case 0x030C: /* Display type */ + pgc_setdisplay(p, pgc->mapram[0x30C]); + pgc->mapram[0x30D] = pgc->mapram[0x30C]; + break; - case 0x3FF: /* Reboot the PGC - (handled on core thread) */ - pgc_wake(pgc); - break; - } // end switch (addr) - } - } - if (addr >= 0xB8000 && addr < 0xBC000 && pgc->cga_selected) { - addr &= 0x3FFF; - pgc->cga_vram[addr] = val; - } + case 0x3FF: /* Reboot the PGC + (handled on core thread) */ + pgc_wake(pgc); + break; + } // end switch (addr) + } + } + if (addr >= 0xB8000 && addr < 0xBC000 && pgc->cga_selected) { + addr &= 0x3FFF; + pgc->cga_vram[addr] = val; + } } uint8_t pgc_read(uint32_t addr, void *p) { - pgc_core_t *pgc = (pgc_core_t *)p; + pgc_core_t *pgc = (pgc_core_t *)p; - if (addr >= 0xC6000 && addr < 0xC6800) { - addr &= 0x7FF; + if (addr >= 0xC6000 && addr < 0xC6800) { + addr &= 0x7FF; - return pgc->mapram[addr]; - } - if (addr >= 0xB8000 && addr < 0xBC000 && pgc->cga_selected) { - addr &= 0x3FFF; - return pgc->cga_vram[addr]; - } - return 0xFF; + return pgc->mapram[addr]; + } + if (addr >= 0xB8000 && addr < 0xBC000 && pgc->cga_selected) { + addr &= 0x3FFF; + return pgc->cga_vram[addr]; + } + return 0xFF; } -/* Called by the drawing thread to read the next byte from the input - * buffer. If no byte available will sleep until one is. Returns 0 if +/* Called by the drawing thread to read the next byte from the input + * buffer. If no byte available will sleep until one is. Returns 0 if * a PGC reset has been triggered by a write to 0xC63FF */ int pgc_input_byte(pgc_core_t *pgc, uint8_t *result) { - /* If input buffer empty, wait for it to fill */ - while (pgc->mapram[0x300] == pgc->mapram[0x301]) { - pgc->waiting_input_fifo = 1; - pgc_sleep(pgc); - } - if (pgc->mapram[0x3FF]) /* Reset triggered */ - { - pgc_reset(pgc); - return 0; - } + /* If input buffer empty, wait for it to fill */ + while (pgc->mapram[0x300] == pgc->mapram[0x301]) { + pgc->waiting_input_fifo = 1; + pgc_sleep(pgc); + } + if (pgc->mapram[0x3FF]) /* Reset triggered */ + { + pgc_reset(pgc); + return 0; + } - *result = pgc->mapram[pgc->mapram[0x301]]; - ++pgc->mapram[0x301]; - return 1; + *result = pgc->mapram[pgc->mapram[0x301]]; + ++pgc->mapram[0x301]; + return 1; } /* Called by the drawing thread to write a byte to the output buffer. * If buffer is full will sleep until it is not. Returns 0 if * a PGC reset has been triggered by a write to 0xC63FF */ int pgc_output_byte(pgc_core_t *pgc, uint8_t val) { - /* If output buffer full, wait for it to empty */ - while (pgc->mapram[0x302] == (uint8_t)(pgc->mapram[0x303] - 1)) { - PGCLOG(("Output buffer state: %02x %02x Sleeping\n", - pgc->mapram[0x302], pgc->mapram[0x303])); - pgc->waiting_output_fifo = 1; - pgc_sleep(pgc); - } - if (pgc->mapram[0x3FF]) /* Reset triggered */ - { - pgc_reset(pgc); - return 0; - } - pgc->mapram[0x100 + pgc->mapram[0x302]] = val; - ++pgc->mapram[0x302]; -/* - PGCLOG(("Output %02x: new state: %02x %02x\n", val, - pgc->mapram[0x302], pgc->mapram[0x303])); */ - return 1; + /* If output buffer full, wait for it to empty */ + while (pgc->mapram[0x302] == (uint8_t)(pgc->mapram[0x303] - 1)) { + PGCLOG(("Output buffer state: %02x %02x Sleeping\n", pgc->mapram[0x302], pgc->mapram[0x303])); + pgc->waiting_output_fifo = 1; + pgc_sleep(pgc); + } + if (pgc->mapram[0x3FF]) /* Reset triggered */ + { + pgc_reset(pgc); + return 0; + } + pgc->mapram[0x100 + pgc->mapram[0x302]] = val; + ++pgc->mapram[0x302]; + /* + PGCLOG(("Output %02x: new state: %02x %02x\n", val, + pgc->mapram[0x302], pgc->mapram[0x303])); */ + return 1; } /* Helper to write an entire string to the output buffer */ int pgc_output_string(pgc_core_t *pgc, const char *s) { - while (*s) { - if (!pgc_output_byte(pgc, *s)) - return 0; - ++s; - } - return 1; + while (*s) { + if (!pgc_output_byte(pgc, *s)) + return 0; + ++s; + } + return 1; } /* As pgc_output_byte, for the error buffer */ int pgc_error_byte(pgc_core_t *pgc, uint8_t val) { - /* If error buffer full, wait for it to empty */ - while (pgc->mapram[0x304] == pgc->mapram[0x305] - 1) { - pgc->waiting_error_fifo = 1; - pgc_sleep(pgc); - } - if (pgc->mapram[0x3FF]) /* Reset triggered */ - { - pgc_reset(pgc); - return 0; - } - pgc->mapram[0x200 + pgc->mapram[0x304]] = val; - ++pgc->mapram[0x304]; - return 1; + /* If error buffer full, wait for it to empty */ + while (pgc->mapram[0x304] == pgc->mapram[0x305] - 1) { + pgc->waiting_error_fifo = 1; + pgc_sleep(pgc); + } + if (pgc->mapram[0x3FF]) /* Reset triggered */ + { + pgc_reset(pgc); + return 0; + } + pgc->mapram[0x200 + pgc->mapram[0x304]] = val; + ++pgc->mapram[0x304]; + return 1; } /* As pgc_output_string, for the error buffer */ int pgc_error_string(pgc_core_t *pgc, const char *s) { - while (*s) { - if (!pgc_error_byte(pgc, *s)) - return 0; - ++s; - } - return 1; + while (*s) { + if (!pgc_error_byte(pgc, *s)) + return 0; + ++s; + } + return 1; } /* Report an error, either in ASCII or in hex */ int pgc_error(pgc_core_t *pgc, int err) { - if (pgc->mapram[0x307]) /* Errors enabled? */ - { - if (pgc->ascii_mode) { - if (err >= PGC_ERROR_RANGE && err <= PGC_ERROR_MISSING) - return pgc_error_string(pgc, pgc_err_msgs[err]); - return pgc_error_string(pgc, "Unknown error\r"); - } else { - return pgc_error_byte(pgc, err); - } - } - return 1; + if (pgc->mapram[0x307]) /* Errors enabled? */ + { + if (pgc->ascii_mode) { + if (err >= PGC_ERROR_RANGE && err <= PGC_ERROR_MISSING) + return pgc_error_string(pgc, pgc_err_msgs[err]); + return pgc_error_string(pgc, "Unknown error\r"); + } else { + return pgc_error_byte(pgc, err); + } + } + return 1; } -static inline int is_whitespace(char ch) { - return (ch != 0 && strchr(" \r\n\t,;()+-", ch) != NULL); -} +static inline int is_whitespace(char ch) { return (ch != 0 && strchr(" \r\n\t,;()+-", ch) != NULL); } /* Read a byte and interpret as ASCII: ignore control characters other than * CR, LF or tab. */ int pgc_input_char(pgc_core_t *pgc, char *result) { - uint8_t ch; + uint8_t ch; - while (1) { - if (!pgc->inputbyte(pgc, &ch)) - return 0; + while (1) { + if (!pgc->inputbyte(pgc, &ch)) + return 0; - ch &= 0x7F; - if (ch == '\r' || ch == '\n' || ch == '\t' || ch >= ' ') { - *result = toupper(ch); - return 1; - } - } + ch &= 0x7F; + if (ch == '\r' || ch == '\n' || ch == '\t' || ch >= ' ') { + *result = toupper(ch); + return 1; + } + } } /* Parameter passed is not a number: abort */ static int err_digit(pgc_core_t *pgc) { - uint8_t asc; + uint8_t asc; - do /* Swallow everything until the next separator */ - { - if (!pgc->inputbyte(pgc, &asc)) - return 0; - } while (!is_whitespace(asc)); - pgc_error(pgc, PGC_ERROR_DIGIT); - return 0; + do /* Swallow everything until the next separator */ + { + if (!pgc->inputbyte(pgc, &asc)) + return 0; + } while (!is_whitespace(asc)); + pgc_error(pgc, PGC_ERROR_DIGIT); + return 0; } -typedef enum parse_state_t { - PS_MAIN, - PS_FRACTION, - PS_EXPONENT -} parse_state_t; +typedef enum parse_state_t { PS_MAIN, PS_FRACTION, PS_EXPONENT } parse_state_t; /* Read in a PGC coordinate, either as hex (4 bytes) or ASCII (xxxx.yyyyEeee) * Returns 0 if PGC reset detected while the value is being read */ int pgc_param_coord(pgc_core_t *pgc, int32_t *value) { - uint8_t asc; - int sign = 1; - int esign = 1; - int n; - uint16_t dp = 1; - uint16_t integer = 0; - uint16_t frac = 0; - uint16_t exponent = 0; - uint32_t res; - parse_state_t state = PS_MAIN; - uint8_t encoded[4]; + uint8_t asc; + int sign = 1; + int esign = 1; + int n; + uint16_t dp = 1; + uint16_t integer = 0; + uint16_t frac = 0; + uint16_t exponent = 0; + uint32_t res; + parse_state_t state = PS_MAIN; + uint8_t encoded[4]; - /* If there is a command list running, pull the bytes out of that - * command list */ - if (pgc->clcur) { - for (n = 0; n < 4; n++) { - if (!pgc_clist_byte(pgc, &encoded[n])) - return 0; - } - integer = (((int16_t)encoded[1]) << 8) | encoded[0]; - frac = (((int16_t)encoded[3]) << 8) | encoded[2]; + /* If there is a command list running, pull the bytes out of that + * command list */ + if (pgc->clcur) { + for (n = 0; n < 4; n++) { + if (!pgc_clist_byte(pgc, &encoded[n])) + return 0; + } + integer = (((int16_t)encoded[1]) << 8) | encoded[0]; + frac = (((int16_t)encoded[3]) << 8) | encoded[2]; - *value = (((int32_t)integer) << 16) | frac; - return 1; - } - /* If in hex mode, read in the encoded integer and fraction parts - * from the hex stream */ - if (!pgc->ascii_mode) { - for (n = 0; n < 4; n++) { - if (!pgc->inputbyte(pgc, &encoded[n])) - return 0; - } - integer = (((int16_t)encoded[1]) << 8) | encoded[0]; - frac = (((int16_t)encoded[3]) << 8) | encoded[2]; + *value = (((int32_t)integer) << 16) | frac; + return 1; + } + /* If in hex mode, read in the encoded integer and fraction parts + * from the hex stream */ + if (!pgc->ascii_mode) { + for (n = 0; n < 4; n++) { + if (!pgc->inputbyte(pgc, &encoded[n])) + return 0; + } + integer = (((int16_t)encoded[1]) << 8) | encoded[0]; + frac = (((int16_t)encoded[3]) << 8) | encoded[2]; - *value = (((int32_t)integer) << 16) | frac; - return 1; - } - /* Parsing an ASCII value */ + *value = (((int32_t)integer) << 16) | frac; + return 1; + } + /* Parsing an ASCII value */ - /* Skip separators */ - do { - if (!pgc->inputbyte(pgc, &asc)) - return 0; - if (asc == '-') - sign = -1; - } while (is_whitespace(asc)); + /* Skip separators */ + do { + if (!pgc->inputbyte(pgc, &asc)) + return 0; + if (asc == '-') + sign = -1; + } while (is_whitespace(asc)); - /* There had better be a digit next */ - if (!isdigit(asc)) { - pgc_error(pgc, PGC_ERROR_MISSING); - return 0; - } - do { - switch (asc) { -/* Decimal point is acceptable in 'main' state (start of fraction) - * not otherwise */ - case '.': - if (state == PS_MAIN) { - if (!pgc->inputbyte(pgc, &asc)) - return 0; - state = PS_FRACTION; - continue; - } else { - pgc_error(pgc, PGC_ERROR_MISSING); - return err_digit(pgc); - } - break; - /* Scientific notation */ - case 'd': - case 'D': - case 'e': - case 'E':esign = 1; - if (!pgc->inputbyte(pgc, &asc)) - return 0; - if (asc == '-') { - sign = -1; - if (!pgc->inputbyte(pgc, &asc)) - return 0; - } - state = PS_EXPONENT; - continue; - /* Should be a number or a separator */ - default: - if (is_whitespace(asc)) - break; - if (!isdigit(asc)) { - pgc_error(pgc, PGC_ERROR_MISSING); - return err_digit(pgc); - } - asc -= '0'; /* asc is digit */ - switch (state) { - case PS_MAIN:integer = (integer * 10) + asc; - if (integer & 0x8000) /* Overflow */ - { - pgc_error(pgc, PGC_ERROR_RANGE); - integer = 0x7FFF; - } - break; - case PS_FRACTION:frac = (frac * 10) + asc; - dp *= 10; - break; - case PS_EXPONENT:exponent = (exponent * 10) + asc; - break; - } + /* There had better be a digit next */ + if (!isdigit(asc)) { + pgc_error(pgc, PGC_ERROR_MISSING); + return 0; + } + do { + switch (asc) { + /* Decimal point is acceptable in 'main' state (start of fraction) + * not otherwise */ + case '.': + if (state == PS_MAIN) { + if (!pgc->inputbyte(pgc, &asc)) + return 0; + state = PS_FRACTION; + continue; + } else { + pgc_error(pgc, PGC_ERROR_MISSING); + return err_digit(pgc); + } + break; + /* Scientific notation */ + case 'd': + case 'D': + case 'e': + case 'E': + esign = 1; + if (!pgc->inputbyte(pgc, &asc)) + return 0; + if (asc == '-') { + sign = -1; + if (!pgc->inputbyte(pgc, &asc)) + return 0; + } + state = PS_EXPONENT; + continue; + /* Should be a number or a separator */ + default: + if (is_whitespace(asc)) + break; + if (!isdigit(asc)) { + pgc_error(pgc, PGC_ERROR_MISSING); + return err_digit(pgc); + } + asc -= '0'; /* asc is digit */ + switch (state) { + case PS_MAIN: + integer = (integer * 10) + asc; + if (integer & 0x8000) /* Overflow */ + { + pgc_error(pgc, PGC_ERROR_RANGE); + integer = 0x7FFF; + } + break; + case PS_FRACTION: + frac = (frac * 10) + asc; + dp *= 10; + break; + case PS_EXPONENT: + exponent = (exponent * 10) + asc; + break; + } + } + if (!pgc->inputbyte(pgc, &asc)) + return 0; + } while (!is_whitespace(asc)); - } - if (!pgc->inputbyte(pgc, &asc)) - return 0; - } while (!is_whitespace(asc)); + res = (frac << 16) / dp; + PGCLOG(("integer=%u frac=%u exponent=%u dp=%d res=0x%08x\n", integer, frac, exponent, dp, res)); - res = (frac << 16) / dp; - PGCLOG(("integer=%u frac=%u exponent=%u dp=%d res=0x%08x\n", - integer, frac, exponent, dp, res)); + res = (res & 0xFFFF) | (integer << 16); + if (exponent) { + for (n = 0; n < exponent; n++) { + if (esign > 0) + res *= 10; + else + res /= 10; + } + } + *value = sign * res; - res = (res & 0xFFFF) | (integer << 16); - if (exponent) { - for (n = 0; n < exponent; n++) { - if (esign > 0) - res *= 10; - else - res /= 10; - } - } - *value = sign * res; - - return 1; + return 1; } /* Pull the next byte from the current command list */ int pgc_clist_byte(pgc_core_t *pgc, uint8_t *val) { - if (pgc->clcur == NULL) - return 0; + if (pgc->clcur == NULL) + return 0; - if (pgc->clcur->rdptr < pgc->clcur->wrptr) { - *val = pgc->clcur->list[pgc->clcur->rdptr++]; - } else { - *val = 0; - } - /* If we've reached the end, reset to the beginning and - * (if repeating) run the repeat */ - if (pgc->clcur->rdptr >= pgc->clcur->wrptr) { - pgc->clcur->rdptr = 0; - --pgc->clcur->repeat; - if (pgc->clcur->repeat == 0) { - pgc->clcur = pgc->clcur->chain; - } - } - return 1; + if (pgc->clcur->rdptr < pgc->clcur->wrptr) { + *val = pgc->clcur->list[pgc->clcur->rdptr++]; + } else { + *val = 0; + } + /* If we've reached the end, reset to the beginning and + * (if repeating) run the repeat */ + if (pgc->clcur->rdptr >= pgc->clcur->wrptr) { + pgc->clcur->rdptr = 0; + --pgc->clcur->repeat; + if (pgc->clcur->repeat == 0) { + pgc->clcur = pgc->clcur->chain; + } + } + return 1; } /* Read in a byte, either as hex (1 byte) or ASCII (decimal). * Returns 0 if PGC reset detected while the value is being read */ int pgc_param_byte(pgc_core_t *pgc, uint8_t *val) { - int32_t c; + int32_t c; - if (pgc->clcur) - return pgc_clist_byte(pgc, val); + if (pgc->clcur) + return pgc_clist_byte(pgc, val); - if (!pgc->ascii_mode) - return pgc->inputbyte(pgc, val); + if (!pgc->ascii_mode) + return pgc->inputbyte(pgc, val); - if (!pgc_param_coord(pgc, &c)) - return 0; - c = (c >> 16); /* Drop fractional part */ + if (!pgc_param_coord(pgc, &c)) + return 0; + c = (c >> 16); /* Drop fractional part */ - if (c > 255) { - pgc_error(pgc, PGC_ERROR_RANGE); - return 0; - } - *val = (uint8_t)c; - return 1; + if (c > 255) { + pgc_error(pgc, PGC_ERROR_RANGE); + return 0; + } + *val = (uint8_t)c; + return 1; } /* Read in a word, either as hex (2 bytes) or ASCII (decimal). * Returns 0 if PGC reset detected while the value is being read */ int pgc_param_word(pgc_core_t *pgc, int16_t *val) { - int32_t c; + int32_t c; - if (pgc->clcur) { - uint8_t lo, hi; + if (pgc->clcur) { + uint8_t lo, hi; - if (!pgc_clist_byte(pgc, &lo)) - return 0; - if (!pgc_clist_byte(pgc, &hi)) - return 0; - *val = (((int16_t)hi) << 8) | lo; - return 1; - } + if (!pgc_clist_byte(pgc, &lo)) + return 0; + if (!pgc_clist_byte(pgc, &hi)) + return 0; + *val = (((int16_t)hi) << 8) | lo; + return 1; + } - if (!pgc->ascii_mode) { - uint8_t lo, hi; + if (!pgc->ascii_mode) { + uint8_t lo, hi; - if (!pgc->inputbyte(pgc, &lo)) - return 0; - if (!pgc->inputbyte(pgc, &hi)) - return 0; - *val = (((int16_t)hi) << 8) | lo; - return 1; - } + if (!pgc->inputbyte(pgc, &lo)) + return 0; + if (!pgc->inputbyte(pgc, &hi)) + return 0; + *val = (((int16_t)hi) << 8) | lo; + return 1; + } - if (!pgc_param_coord(pgc, &c)) - return 0; + if (!pgc_param_coord(pgc, &c)) + return 0; - c = (c >> 16); - if (c > 0x7FFF || c < -0x7FFF) { - pgc_error(pgc, PGC_ERROR_RANGE); - return 0; - } - *val = (int16_t)c; - return 1; + c = (c >> 16); + if (c > 0x7FFF || c < -0x7FFF) { + pgc_error(pgc, PGC_ERROR_RANGE); + return 0; + } + *val = (int16_t)c; + return 1; } /* Output a byte, either as hex or ASCII depending on the mode */ int pgc_result_byte(pgc_core_t *pgc, uint8_t val) { - char buf[20]; + char buf[20]; - if (!pgc->ascii_mode) - return pgc_output_byte(pgc, val); + if (!pgc->ascii_mode) + return pgc_output_byte(pgc, val); - if (pgc->result_count) { - if (!pgc_output_byte(pgc, ',')) - return 0; - } - sprintf(buf, "%d", val); - ++pgc->result_count; - return pgc_output_string(pgc, buf); + if (pgc->result_count) { + if (!pgc_output_byte(pgc, ',')) + return 0; + } + sprintf(buf, "%d", val); + ++pgc->result_count; + return pgc_output_string(pgc, buf); } /* Output a word, either as hex or ASCII depending on the mode */ int pgc_result_word(pgc_core_t *pgc, int16_t val) { - char buf[20]; + char buf[20]; - if (!pgc->ascii_mode) { - if (!pgc_output_byte(pgc, val & 0xFF)) - return 0; - return pgc_output_byte(pgc, val >> 8); - } + if (!pgc->ascii_mode) { + if (!pgc_output_byte(pgc, val & 0xFF)) + return 0; + return pgc_output_byte(pgc, val >> 8); + } - if (pgc->result_count) { - if (!pgc_output_byte(pgc, ',')) - return 0; - } - sprintf(buf, "%d", val); - ++pgc->result_count; - return pgc_output_string(pgc, buf); + if (pgc->result_count) { + if (!pgc_output_byte(pgc, ',')) + return 0; + } + sprintf(buf, "%d", val); + ++pgc->result_count; + return pgc_output_string(pgc, buf); } /* Write a screen pixel (x and y are raster coordinates, ink is the * value to write) */ void pgc_write_pixel(pgc_core_t *pgc, uint16_t x, uint16_t y, uint8_t ink) { - uint8_t *vram; + uint8_t *vram; - /* Suppress out-of-range writes; clip to viewport */ - if (x < pgc->vp_x1 || x > pgc->vp_x2 || x >= pgc->maxw || - y < pgc->vp_y1 || y > pgc->vp_y2 || y >= pgc->maxh) { - PGCLOG(("pgc_write_pixel clipped: (%d,%d) " - "vp_x1=%d vp_y1=%d vp_x2=%d vp_y2=%d " - "ink=0x%02x\n", x, y, - pgc->vp_x1, pgc->vp_y1, - pgc->vp_x2, pgc->vp_y2, ink)); - return; - } - vram = pgc_vram_addr(pgc, x, y); - if (vram) - *vram = ink; + /* Suppress out-of-range writes; clip to viewport */ + if (x < pgc->vp_x1 || x > pgc->vp_x2 || x >= pgc->maxw || y < pgc->vp_y1 || y > pgc->vp_y2 || y >= pgc->maxh) { + PGCLOG(("pgc_write_pixel clipped: (%d,%d) " + "vp_x1=%d vp_y1=%d vp_x2=%d vp_y2=%d " + "ink=0x%02x\n", + x, y, pgc->vp_x1, pgc->vp_y1, pgc->vp_x2, pgc->vp_y2, ink)); + return; + } + vram = pgc_vram_addr(pgc, x, y); + if (vram) + *vram = ink; } /* Read a screen pixel (x and y are raster coordinates) */ uint8_t pgc_read_pixel(pgc_core_t *pgc, uint16_t x, uint16_t y) { - uint8_t *vram; + uint8_t *vram; - /* Suppress out-of-range reads */ - if (x >= pgc->maxw || y >= pgc->maxh) { - return 0; - } - vram = pgc_vram_addr(pgc, x, y); - if (vram) - return *vram; - return 0; + /* Suppress out-of-range reads */ + if (x >= pgc->maxw || y >= pgc->maxh) { + return 0; + } + vram = pgc_vram_addr(pgc, x, y); + if (vram) + return *vram; + return 0; } /* Plot a point in the current colour and draw mode. Raster coordinates. */ void pgc_plot(pgc_core_t *pgc, uint16_t x, uint16_t y) { - uint8_t *vram; + uint8_t *vram; - /* Only allow plotting within the current viewport. */ - if (x < pgc->vp_x1 || x > pgc->vp_x2 || x >= pgc->maxw || - y < pgc->vp_y1 || y > pgc->vp_y2 || y >= pgc->maxh) { - PGCLOG(("pgc_plot clipped: (%d,%d) %d <= x <= %d; %d <= y <= %d; " - "mode=%d ink=0x%02x\n", x, y, - pgc->vp_x1, pgc->vp_x2, pgc->vp_y1, pgc->vp_y2, - pgc->draw_mode, pgc->colour)); - return; - } - vram = pgc_vram_addr(pgc, x, y); - if (!vram) - return; + /* Only allow plotting within the current viewport. */ + if (x < pgc->vp_x1 || x > pgc->vp_x2 || x >= pgc->maxw || y < pgc->vp_y1 || y > pgc->vp_y2 || y >= pgc->maxh) { + PGCLOG(("pgc_plot clipped: (%d,%d) %d <= x <= %d; %d <= y <= %d; " + "mode=%d ink=0x%02x\n", + x, y, pgc->vp_x1, pgc->vp_x2, pgc->vp_y1, pgc->vp_y2, pgc->draw_mode, pgc->colour)); + return; + } + vram = pgc_vram_addr(pgc, x, y); + if (!vram) + return; - /* TODO: Does not implement the PGC plane mask (set by MASK) */ - switch (pgc->draw_mode) { - default: - case 0:*vram = pgc->colour; - break; /* Write */ - case 1:*vram ^= 0xFF; - break; /* Invert */ - case 2:*vram ^= pgc->colour; - break; /* XOR colour */ - case 3:*vram &= pgc->colour; - break; /* AND */ - } + /* TODO: Does not implement the PGC plane mask (set by MASK) */ + switch (pgc->draw_mode) { + default: + case 0: + *vram = pgc->colour; + break; /* Write */ + case 1: + *vram ^= 0xFF; + break; /* Invert */ + case 2: + *vram ^= pgc->colour; + break; /* XOR colour */ + case 3: + *vram &= pgc->colour; + break; /* AND */ + } } /* Given raster coordinates, find the matching address in PGC video RAM */ uint8_t *pgc_vram_addr(pgc_core_t *pgc, int16_t x, int16_t y) { - int offset; + int offset; -/* We work from the bottom left-hand corner */ - if (y < 0 || y >= pgc->maxh || x < 0 || x >= pgc->maxw) - return NULL; + /* We work from the bottom left-hand corner */ + if (y < 0 || y >= pgc->maxh || x < 0 || x >= pgc->maxw) + return NULL; - offset = (pgc->maxh - 1 - y) * (pgc->maxw) + x; -// PGCLOG(("pgc_vram_addr x=%d y=%d offset=%d\n", x, y, offset); + offset = (pgc->maxh - 1 - y) * (pgc->maxw) + x; + // PGCLOG(("pgc_vram_addr x=%d y=%d offset=%d\n", x, y, offset); - if (offset < 0 || offset >= (pgc->maxw * pgc->maxh)) { - return NULL; - } - return &pgc->vram[offset]; + if (offset < 0 || offset >= (pgc->maxw * pgc->maxh)) { + return NULL; + } + return &pgc->vram[offset]; } /* Read in the next command, either as hex (1 byte) or ASCII (up to 6 * characters) */ int pgc_read_command(pgc_core_t *pgc) { - if (pgc->clcur) { - return pgc_clist_byte(pgc, &pgc->hex_command); - } else if (pgc->ascii_mode) { - char ch; - int count = 0; + if (pgc->clcur) { + return pgc_clist_byte(pgc, &pgc->hex_command); + } else if (pgc->ascii_mode) { + char ch; + int count = 0; - while (count < 7) { - if (!pgc_input_char(pgc, &ch)) - return 0; - if (is_whitespace(ch)) { - /* Pad to 6 characters */ - while (count < 6) - pgc->asc_command[count++] = ' '; - pgc->asc_command[6] = 0; - return 1; - } - pgc->asc_command[count++] = toupper(ch); - } - return 1; - } else { - return pgc->inputbyte(pgc, &pgc->hex_command); - } + while (count < 7) { + if (!pgc_input_char(pgc, &ch)) + return 0; + if (is_whitespace(ch)) { + /* Pad to 6 characters */ + while (count < 6) + pgc->asc_command[count++] = ' '; + pgc->asc_command[6] = 0; + return 1; + } + pgc->asc_command[count++] = toupper(ch); + } + return 1; + } else { + return pgc->inputbyte(pgc, &pgc->hex_command); + } } /* Read in the next command and parse it */ static int pgc_parse_command(pgc_core_t *pgc, const pgc_command_t **pcmd) { - const pgc_command_t *cmd; - char match[7]; + const pgc_command_t *cmd; + char match[7]; - *pcmd = NULL; - pgc->hex_command = 0; - memset(pgc->asc_command, ' ', 6); - pgc->asc_command[6] = 0; - if (!pgc_read_command(pgc)) { - /* PGC has been reset */ - return 0; - } -/* Scan the list of valid commands. pgc->pgc_commands may be a subclass - * list (terminated with '*') or the core list (terminated with '@') */ - for (cmd = pgc->pgc_commands; cmd->ascii[0] != '@'; cmd++) { - /* End of subclass command list, chain to core */ - if (cmd->ascii[0] == '*') - cmd = pgc_core_commands; + *pcmd = NULL; + pgc->hex_command = 0; + memset(pgc->asc_command, ' ', 6); + pgc->asc_command[6] = 0; + if (!pgc_read_command(pgc)) { + /* PGC has been reset */ + return 0; + } + /* Scan the list of valid commands. pgc->pgc_commands may be a subclass + * list (terminated with '*') or the core list (terminated with '@') */ + for (cmd = pgc->pgc_commands; cmd->ascii[0] != '@'; cmd++) { + /* End of subclass command list, chain to core */ + if (cmd->ascii[0] == '*') + cmd = pgc_core_commands; - /* If in ASCII mode match on the ASCII command */ - if (pgc->ascii_mode && !pgc->clcur) { - sprintf(match, "%-6.6s", cmd->ascii); - if (!strncmp(match, pgc->asc_command, 6)) { - *pcmd = cmd; - pgc->hex_command = cmd->hex; - break; - } - } else /* Otherwise match on the hex command */ - { - if (cmd->hex == pgc->hex_command) { - sprintf(pgc->asc_command, "%-6.6s", - cmd->ascii); - *pcmd = cmd; - break; - } - } - } - return 1; + /* If in ASCII mode match on the ASCII command */ + if (pgc->ascii_mode && !pgc->clcur) { + sprintf(match, "%-6.6s", cmd->ascii); + if (!strncmp(match, pgc->asc_command, 6)) { + *pcmd = cmd; + pgc->hex_command = cmd->hex; + break; + } + } else /* Otherwise match on the hex command */ + { + if (cmd->hex == pgc->hex_command) { + sprintf(pgc->asc_command, "%-6.6s", cmd->ascii); + *pcmd = cmd; + break; + } + } + } + return 1; } /* The PGC drawing thread main loop. Read in commands and execute them ad * infinitum */ void pgc_core_thread(void *p) { - pgc_core_t *pgc = (pgc_core_t *)p; - const pgc_command_t *cmd; + pgc_core_t *pgc = (pgc_core_t *)p; + const pgc_command_t *cmd; - PGCLOG(("pgc_core_thread begins")); - while (1) { - if (!pgc_parse_command(pgc, &cmd)) { - /* PGC has been reset */ - continue; - } - PGCLOG(("PGC command: [%02x] '%s' found=%d\n", - pgc->hex_command, pgc->asc_command, (cmd != NULL))); + PGCLOG(("pgc_core_thread begins")); + while (1) { + if (!pgc_parse_command(pgc, &cmd)) { + /* PGC has been reset */ + continue; + } + PGCLOG(("PGC command: [%02x] '%s' found=%d\n", pgc->hex_command, pgc->asc_command, (cmd != NULL))); - if (cmd) { - pgc->result_count = 0; - (*cmd->handler)(pgc); - } else { - pgc_error(pgc, PGC_ERROR_OPCODE); - } - } + if (cmd) { + pgc->result_count = 0; + (*cmd->handler)(pgc); + } else { + pgc_error(pgc, PGC_ERROR_OPCODE); + } + } } void pgc_recalctimings(pgc_core_t *pgc) { - double disptime, _dispontime, _dispofftime; - double pixel_clock = (cpuclock * (double)(1ull << 32)) / (pgc->cga_selected ? 25175000.0 : pgc->native_pixel_clock); + double disptime, _dispontime, _dispofftime; + double pixel_clock = (cpuclock * (double)(1ull << 32)) / (pgc->cga_selected ? 25175000.0 : pgc->native_pixel_clock); - /* Use a fixed 640 columns, like the T3100e */ - disptime = pgc->screenw + 11; - _dispontime = pgc->screenw * pixel_clock; - _dispofftime = (disptime - pgc->screenw) * pixel_clock; - pgc->dispontime = (uint64_t)_dispontime; - pgc->dispofftime = (uint64_t)_dispofftime; + /* Use a fixed 640 columns, like the T3100e */ + disptime = pgc->screenw + 11; + _dispontime = pgc->screenw * pixel_clock; + _dispofftime = (disptime - pgc->screenw) * pixel_clock; + pgc->dispontime = (uint64_t)_dispontime; + pgc->dispofftime = (uint64_t)_dispofftime; } /* Draw the display in CGA (640x400) text mode */ void pgc_cga_text(pgc_core_t *pgc, int w) { - int x, c; - uint8_t chr, attr; - int drawcursor = 0; - uint32_t cols[2]; - int pitch = (pgc->mapram[0x3E9] + 1) * 2; - uint16_t sc = (pgc->displine & 0x0F) % pitch; - uint16_t ma = (pgc->mapram[0x3ED] | (pgc->mapram[0x3EC] << 8)) & 0x3fff; - uint16_t ca = (pgc->mapram[0x3EF] | (pgc->mapram[0x3EE] << 8)) & 0x3fff; - uint8_t *addr; - int cw = (w == 80) ? 8 : 16; + int x, c; + uint8_t chr, attr; + int drawcursor = 0; + uint32_t cols[2]; + int pitch = (pgc->mapram[0x3E9] + 1) * 2; + uint16_t sc = (pgc->displine & 0x0F) % pitch; + uint16_t ma = (pgc->mapram[0x3ED] | (pgc->mapram[0x3EC] << 8)) & 0x3fff; + uint16_t ca = (pgc->mapram[0x3EF] | (pgc->mapram[0x3EE] << 8)) & 0x3fff; + uint8_t *addr; + int cw = (w == 80) ? 8 : 16; - addr = &pgc->cga_vram[((ma << 1) + (((pgc->displine / pitch) * w)) * 2) & 0x3ffe]; - ma += (pgc->displine / pitch) * w; + addr = &pgc->cga_vram[((ma << 1) + (((pgc->displine / pitch) * w)) * 2) & 0x3ffe]; + ma += (pgc->displine / pitch) * w; - for (x = 0; x < w; x++) { - chr = addr[0]; - attr = addr[1]; - addr += 2; + for (x = 0; x < w; x++) { + chr = addr[0]; + attr = addr[1]; + addr += 2; - /* Cursor enabled? */ - if (ma == ca && (pgc->cgablink & 8) && - (pgc->mapram[0x3EA] & 0x60) != 0x20) { - drawcursor = ((pgc->mapram[0x3EA] & 0x1F) <= (sc >> 1)) - && ((pgc->mapram[0x3EB] & 0x1F) >= (sc >> 1)); - } else - drawcursor = 0; - if (pgc->mapram[0x3D8] & 0x20) { - cols[1] = attr & 15; - cols[0] = (attr >> 4) & 7; - if ((pgc->cgablink & 8) && (attr & 0x80) && !drawcursor) - cols[1] = cols[0]; - } else { - cols[1] = attr & 15; - cols[0] = attr >> 4; - } - if (drawcursor) { - for (c = 0; c < cw; c++) { - if (w == 80) - ((uint32_t *)buffer32->line[pgc->displine & 2047])[(x << 3) + c] = cols[(fontdatm[chr + pgc->fontbase][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ 0xffffff; - else - ((uint32_t *)buffer32->line[pgc->displine & 2047])[(x << 4) + c] = cols[(fontdatm[chr + pgc->fontbase][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ 0xffffff; - } - } else { - for (c = 0; c < cw; c++) { - if (w == 80) - ((uint32_t *)buffer32->line[pgc->displine & 2047])[(x << 3) + c] = cols[(fontdatm[chr + pgc->fontbase][sc] & (1 << (c ^ 7))) ? 1 : 0]; - else - ((uint32_t *)buffer32->line[pgc->displine & 2047])[(x << 4) + c] = cols[(fontdatm[chr + pgc->fontbase][sc] & (1 << ((c >> 1) ^ 7))) ? 1 : 0]; - } - } - ma++; - } + /* Cursor enabled? */ + if (ma == ca && (pgc->cgablink & 8) && (pgc->mapram[0x3EA] & 0x60) != 0x20) { + drawcursor = ((pgc->mapram[0x3EA] & 0x1F) <= (sc >> 1)) && ((pgc->mapram[0x3EB] & 0x1F) >= (sc >> 1)); + } else + drawcursor = 0; + if (pgc->mapram[0x3D8] & 0x20) { + cols[1] = attr & 15; + cols[0] = (attr >> 4) & 7; + if ((pgc->cgablink & 8) && (attr & 0x80) && !drawcursor) + cols[1] = cols[0]; + } else { + cols[1] = attr & 15; + cols[0] = attr >> 4; + } + if (drawcursor) { + for (c = 0; c < cw; c++) { + if (w == 80) + ((uint32_t *)buffer32->line[pgc->displine & 2047])[(x << 3) + c] = + cols[(fontdatm[chr + pgc->fontbase][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ 0xffffff; + else + ((uint32_t *)buffer32->line[pgc->displine & 2047])[(x << 4) + c] = + cols[(fontdatm[chr + pgc->fontbase][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ 0xffffff; + } + } else { + for (c = 0; c < cw; c++) { + if (w == 80) + ((uint32_t *)buffer32->line[pgc->displine & 2047])[(x << 3) + c] = + cols[(fontdatm[chr + pgc->fontbase][sc] & (1 << (c ^ 7))) ? 1 : 0]; + else + ((uint32_t *)buffer32->line[pgc->displine & 2047])[(x << 4) + c] = + cols[(fontdatm[chr + pgc->fontbase][sc] & (1 << ((c >> 1) ^ 7))) ? 1 : 0]; + } + } + ma++; + } } /* Draw the display in CGA (320x200) graphics mode */ void pgc_cga_gfx40(pgc_core_t *pgc) { - int x, c; - uint32_t cols[4]; - int col; - uint16_t ma = (pgc->mapram[0x3ED] | (pgc->mapram[0x3EC] << 8)) & 0x3fff; - uint8_t *addr; - uint16_t dat; + int x, c; + uint32_t cols[4]; + int col; + uint16_t ma = (pgc->mapram[0x3ED] | (pgc->mapram[0x3EC] << 8)) & 0x3fff; + uint8_t *addr; + uint16_t dat; - cols[0] = pgc->mapram[0x3D9] & 15; - col = (pgc->mapram[0x3D9] & 16) ? 8 : 0; + cols[0] = pgc->mapram[0x3D9] & 15; + col = (pgc->mapram[0x3D9] & 16) ? 8 : 0; - if (pgc->mapram[0x3D8] & 4) { - cols[1] = col | 3; - cols[2] = col | 4; - cols[3] = col | 7; - } else if (pgc->mapram[0x3D9] & 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++) { - addr = &pgc->cga_vram[(ma + 2 * x + 80 * (pgc->displine >> 2) + 0x2000 * ((pgc->displine >> 1) & 1)) & 0x3FFF]; - dat = (addr[0] << 8) | addr[1]; - pgc->ma++; - for (c = 0; c < 8; c++) { - ((uint32_t *)buffer32->line[pgc->displine & 2047])[(x << 4) + (c << 1)] = - ((uint32_t *)buffer32->line[pgc->displine & 2047])[(x << 4) + (c << 1) + 1] = cols[dat >> 14]; - dat <<= 2; - } - } + if (pgc->mapram[0x3D8] & 4) { + cols[1] = col | 3; + cols[2] = col | 4; + cols[3] = col | 7; + } else if (pgc->mapram[0x3D9] & 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++) { + addr = &pgc->cga_vram[(ma + 2 * x + 80 * (pgc->displine >> 2) + 0x2000 * ((pgc->displine >> 1) & 1)) & 0x3FFF]; + dat = (addr[0] << 8) | addr[1]; + pgc->ma++; + for (c = 0; c < 8; c++) { + ((uint32_t *)buffer32->line[pgc->displine & 2047])[(x << 4) + (c << 1)] = + ((uint32_t *)buffer32->line[pgc->displine & 2047])[(x << 4) + (c << 1) + 1] = cols[dat >> 14]; + dat <<= 2; + } + } } /* Draw the display in CGA (640x200) graphics mode */ void pgc_cga_gfx80(pgc_core_t *pgc) { - int x, c; - uint32_t cols[2]; - uint16_t ma = (pgc->mapram[0x3ED] | (pgc->mapram[0x3EC] << 8)) & 0x3fff; - uint8_t *addr; - uint16_t dat; + int x, c; + uint32_t cols[2]; + uint16_t ma = (pgc->mapram[0x3ED] | (pgc->mapram[0x3EC] << 8)) & 0x3fff; + uint8_t *addr; + uint16_t dat; - cols[0] = 0; - cols[1] = pgc->mapram[0x3D9] & 15; + cols[0] = 0; + cols[1] = pgc->mapram[0x3D9] & 15; - for (x = 0; x < 40; x++) { - addr = &pgc->cga_vram[(ma + 2 * x + 80 * (pgc->displine >> 2) + 0x2000 * ((pgc->displine >> 1) & 1)) & 0x3FFF]; - dat = (addr[0] << 8) | addr[1]; - pgc->ma++; - for (c = 0; c < 16; c++) { - ((uint32_t *)buffer32->line[pgc->displine & 2047])[(x << 4) + c] = cols[dat >> 15]; - dat <<= 1; - } - } + for (x = 0; x < 40; x++) { + addr = &pgc->cga_vram[(ma + 2 * x + 80 * (pgc->displine >> 2) + 0x2000 * ((pgc->displine >> 1) & 1)) & 0x3FFF]; + dat = (addr[0] << 8) | addr[1]; + pgc->ma++; + for (c = 0; c < 16; c++) { + ((uint32_t *)buffer32->line[pgc->displine & 2047])[(x << 4) + c] = cols[dat >> 15]; + dat <<= 1; + } + } } /* Draw the screen in CGA mode. Based on the simplified WY700 renderer * rather than the original CGA, since the PGC doesn't have a real 6845 */ void pgc_cga_poll(pgc_core_t *pgc) { - int c; - uint32_t cols[2]; + int c; + uint32_t cols[2]; - if (!pgc->linepos) { - timer_advance_u64(&pgc->timer, pgc->dispofftime); - pgc->mapram[0x3DA] |= 1; - pgc->linepos = 1; - if (pgc->cgadispon) { - if (pgc->displine == 0) { - video_wait_for_buffer(); - } + if (!pgc->linepos) { + timer_advance_u64(&pgc->timer, pgc->dispofftime); + pgc->mapram[0x3DA] |= 1; + pgc->linepos = 1; + if (pgc->cgadispon) { + if (pgc->displine == 0) { + video_wait_for_buffer(); + } - if ((pgc->mapram[0x3D8] & 0x12) == 0x12) { - pgc_cga_gfx80(pgc); - } else if (pgc->mapram[0x3D8] & 0x02) { - pgc_cga_gfx40(pgc); - } else if (pgc->mapram[0x3D8] & 0x01) { - pgc_cga_text(pgc, 80); - } else { - pgc_cga_text(pgc, 40); - } - } else { - cols[0] = ((pgc->mapram[0x3D8] & 0x12) == 0x12) ? 0 : (pgc->mapram[0x3D9] & 15); - hline(buffer32, 0, pgc->displine & 2047, PGC_CGA_WIDTH, cols[0]); - } + if ((pgc->mapram[0x3D8] & 0x12) == 0x12) { + pgc_cga_gfx80(pgc); + } else if (pgc->mapram[0x3D8] & 0x02) { + pgc_cga_gfx40(pgc); + } else if (pgc->mapram[0x3D8] & 0x01) { + pgc_cga_text(pgc, 80); + } else { + pgc_cga_text(pgc, 40); + } + } else { + cols[0] = ((pgc->mapram[0x3D8] & 0x12) == 0x12) ? 0 : (pgc->mapram[0x3D9] & 15); + hline(buffer32, 0, pgc->displine & 2047, PGC_CGA_WIDTH, cols[0]); + } - for (c = 0; c < PGC_CGA_WIDTH; c++) - ((uint32_t *)buffer32->line[pgc->displine & 2047])[c] = cgapal[((uint32_t *)buffer32->line[pgc->displine & 2047])[c] & 0xf]; + for (c = 0; c < PGC_CGA_WIDTH; c++) + ((uint32_t *)buffer32->line[pgc->displine & 2047])[c] = + cgapal[((uint32_t *)buffer32->line[pgc->displine & 2047])[c] & 0xf]; - pgc->displine++; - if (pgc->displine == PGC_CGA_HEIGHT) { - pgc->mapram[0x3DA] |= 8; - pgc->cgadispon = 0; - } - if (pgc->displine == PGC_CGA_HEIGHT + 32) { - pgc->mapram[0x3DA] &= ~8; - pgc->cgadispon = 1; - pgc->displine = 0; - } - } else { - if (pgc->cgadispon) { - pgc->mapram[0x3DA] &= ~1; - } - timer_advance_u64(&pgc->timer, pgc->dispontime); - pgc->linepos = 0; + pgc->displine++; + if (pgc->displine == PGC_CGA_HEIGHT) { + pgc->mapram[0x3DA] |= 8; + pgc->cgadispon = 0; + } + if (pgc->displine == PGC_CGA_HEIGHT + 32) { + pgc->mapram[0x3DA] &= ~8; + pgc->cgadispon = 1; + pgc->displine = 0; + } + } else { + if (pgc->cgadispon) { + pgc->mapram[0x3DA] &= ~1; + } + timer_advance_u64(&pgc->timer, pgc->dispontime); + pgc->linepos = 0; - if (pgc->displine == PGC_CGA_HEIGHT) { - if (PGC_CGA_WIDTH != xsize || PGC_CGA_HEIGHT != ysize) { - xsize = PGC_CGA_WIDTH; - ysize = PGC_CGA_HEIGHT; - updatewindowsize(xsize, ysize); - } - video_blit_memtoscreen(0, 0, 0, ysize, xsize, ysize); - frames++; + if (pgc->displine == PGC_CGA_HEIGHT) { + if (PGC_CGA_WIDTH != xsize || PGC_CGA_HEIGHT != ysize) { + xsize = PGC_CGA_WIDTH; + ysize = PGC_CGA_HEIGHT; + updatewindowsize(xsize, ysize); + } + video_blit_memtoscreen(0, 0, 0, ysize, xsize, ysize); + frames++; - /* We have a fixed 640x400 screen for - * CGA modes */ - video_res_x = PGC_CGA_WIDTH; - video_res_y = PGC_CGA_HEIGHT; - switch (pgc->mapram[0x3D8] & 0x12) { - case 0x12:video_bpp = 1; - break; - case 0x02:video_bpp = 2; - break; - default:video_bpp = 0; - break; - } - pgc->cgablink++; - } - } + /* We have a fixed 640x400 screen for + * CGA modes */ + video_res_x = PGC_CGA_WIDTH; + video_res_y = PGC_CGA_HEIGHT; + switch (pgc->mapram[0x3D8] & 0x12) { + case 0x12: + video_bpp = 1; + break; + case 0x02: + video_bpp = 2; + break; + default: + video_bpp = 0; + break; + } + pgc->cgablink++; + } + } } /* Draw the screen in CGA or native mode. */ void pgc_poll(void *p) { - pgc_core_t *pgc = (pgc_core_t *)p; - int x, y; + pgc_core_t *pgc = (pgc_core_t *)p; + int x, y; - if (pgc->cga_selected) { - pgc_cga_poll(pgc); - return; - } -/* Not CGA, so must be native mode */ - if (!pgc->linepos) { - timer_advance_u64(&pgc->timer, pgc->dispofftime); - pgc->mapram[0x3DA] |= 1; - pgc->linepos = 1; - if (pgc->cgadispon && pgc->displine < pgc->maxh) { - if (pgc->displine == 0) { - video_wait_for_buffer(); - } - /* Don't know why pan needs to be multiplied by -2, but - * the IM1024 driver uses PAN -112 for an offset of - * 224. */ - y = pgc->displine - 2 * pgc->pan_y; - for (x = 0; x < pgc->screenw; x++) { - if (x + pgc->pan_x < pgc->maxw) { - ((uint32_t *)buffer32->line[pgc->displine & 2047])[x] = pgc->palette[pgc->vram[y * pgc->maxw + x]]; - } else { - ((uint32_t *)buffer32->line[pgc->displine & 2047])[x] = pgc->palette[0]; - } - } - } else { - hline(buffer32, 0, pgc->displine & 2047, pgc->screenw, pgc->palette[0]); - } - pgc->displine++; - if (pgc->displine == pgc->screenh) { - pgc->mapram[0x3DA] |= 8; - pgc->cgadispon = 0; - } - if (pgc->displine == pgc->screenh + 32) { - pgc->mapram[0x3DA] &= ~8; - pgc->cgadispon = 1; - pgc->displine = 0; - } - } else { - if (pgc->cgadispon) { - pgc->mapram[0x3DA] &= ~1; - } - timer_advance_u64(&pgc->timer, pgc->dispontime); - pgc->linepos = 0; + if (pgc->cga_selected) { + pgc_cga_poll(pgc); + return; + } + /* Not CGA, so must be native mode */ + if (!pgc->linepos) { + timer_advance_u64(&pgc->timer, pgc->dispofftime); + pgc->mapram[0x3DA] |= 1; + pgc->linepos = 1; + if (pgc->cgadispon && pgc->displine < pgc->maxh) { + if (pgc->displine == 0) { + video_wait_for_buffer(); + } + /* Don't know why pan needs to be multiplied by -2, but + * the IM1024 driver uses PAN -112 for an offset of + * 224. */ + y = pgc->displine - 2 * pgc->pan_y; + for (x = 0; x < pgc->screenw; x++) { + if (x + pgc->pan_x < pgc->maxw) { + ((uint32_t *)buffer32->line[pgc->displine & 2047])[x] = + pgc->palette[pgc->vram[y * pgc->maxw + x]]; + } else { + ((uint32_t *)buffer32->line[pgc->displine & 2047])[x] = pgc->palette[0]; + } + } + } else { + hline(buffer32, 0, pgc->displine & 2047, pgc->screenw, pgc->palette[0]); + } + pgc->displine++; + if (pgc->displine == pgc->screenh) { + pgc->mapram[0x3DA] |= 8; + pgc->cgadispon = 0; + } + if (pgc->displine == pgc->screenh + 32) { + pgc->mapram[0x3DA] &= ~8; + pgc->cgadispon = 1; + pgc->displine = 0; + } + } else { + if (pgc->cgadispon) { + pgc->mapram[0x3DA] &= ~1; + } + timer_advance_u64(&pgc->timer, pgc->dispontime); + pgc->linepos = 0; - if (pgc->displine == pgc->screenh) { - if (pgc->screenw != xsize || pgc->screenh != ysize) { - xsize = pgc->screenw; - ysize = pgc->screenh; - updatewindowsize(xsize, ysize); - } - video_blit_memtoscreen(0, 0, 0, ysize, xsize, ysize); - frames++; + if (pgc->displine == pgc->screenh) { + if (pgc->screenw != xsize || pgc->screenh != ysize) { + xsize = pgc->screenw; + ysize = pgc->screenh; + updatewindowsize(xsize, ysize); + } + video_blit_memtoscreen(0, 0, 0, ysize, xsize, ysize); + frames++; - video_res_x = pgc->screenw; - video_res_y = pgc->screenh; - video_bpp = 8; - pgc->cgablink++; - } - } + video_res_x = pgc->screenw; + video_res_y = pgc->screenh; + video_bpp = 8; + pgc->cgablink++; + } + } } /* Initialise RAM and registers to default values */ void pgc_reset(pgc_core_t *pgc) { - int n; + int n; - memset(pgc->mapram, 0, sizeof(pgc->mapram)); -/* There is no point in emulating the 'CGA disable' jumper as this is only - * appropriate for a dual-head system, not emulated by PCEM */ - pgc->mapram[0x30B] = pgc->cga_enabled = 1; - pgc->mapram[0x3F8] = 0x03; /* Minor version */ - pgc->mapram[0x3F9] = 0x01; /* Minor version */ - pgc->mapram[0x3FB] = 0xA5; /* } */ - pgc->mapram[0x3FC] = 0x5A; /* PGC self-test passed */ - pgc->mapram[0x3FD] = 0x55; /* } */ - pgc->mapram[0x3FE] = 0x5A; /* } */ + memset(pgc->mapram, 0, sizeof(pgc->mapram)); + /* There is no point in emulating the 'CGA disable' jumper as this is only + * appropriate for a dual-head system, not emulated by PCEM */ + pgc->mapram[0x30B] = pgc->cga_enabled = 1; + pgc->mapram[0x3F8] = 0x03; /* Minor version */ + pgc->mapram[0x3F9] = 0x01; /* Minor version */ + pgc->mapram[0x3FB] = 0xA5; /* } */ + pgc->mapram[0x3FC] = 0x5A; /* PGC self-test passed */ + pgc->mapram[0x3FD] = 0x55; /* } */ + pgc->mapram[0x3FE] = 0x5A; /* } */ - pgc->ascii_mode = 1; /* Start off in ASCII mode */ - pgc->line_pattern = 0xFFFF; - memset(pgc->fill_pattern, 0xFF, sizeof(pgc->fill_pattern)); - pgc->colour = 0xFF; - pgc->tjust_h = 1; - pgc->tjust_v = 1; + pgc->ascii_mode = 1; /* Start off in ASCII mode */ + pgc->line_pattern = 0xFFFF; + memset(pgc->fill_pattern, 0xFF, sizeof(pgc->fill_pattern)); + pgc->colour = 0xFF; + pgc->tjust_h = 1; + pgc->tjust_v = 1; - /* Reset panning */ - pgc->pan_x = 0; - pgc->pan_y = 0; + /* Reset panning */ + pgc->pan_x = 0; + pgc->pan_y = 0; - /* Reset clipping */ - pgc->vp_x1 = 0; - pgc->vp_y1 = 0; - pgc->vp_x2 = pgc->visw - 1; - pgc->vp_y2 = pgc->vish - 1; + /* Reset clipping */ + pgc->vp_x1 = 0; + pgc->vp_y1 = 0; + pgc->vp_x2 = pgc->visw - 1; + pgc->vp_y2 = pgc->vish - 1; - /* Empty command lists */ - for (n = 0; n < 256; n++) { - pgc->clist[n].wrptr = 0; - pgc->clist[n].rdptr = 0; - pgc->clist[n].repeat = 0; - pgc->clist[n].chain = 0; - } - pgc->clcur = NULL; - /* Select CGA display */ - pgc->cga_selected = -1; - pgc_setdisplay(pgc, pgc->cga_enabled); - pgc->mapram[0x30C] = pgc->cga_enabled; - pgc->mapram[0x30D] = pgc->cga_enabled; - /* Default palette is 0 */ - pgc_init_lut(pgc, 0); - hndl_lutsav(pgc); + /* Empty command lists */ + for (n = 0; n < 256; n++) { + pgc->clist[n].wrptr = 0; + pgc->clist[n].rdptr = 0; + pgc->clist[n].repeat = 0; + pgc->clist[n].chain = 0; + } + pgc->clcur = NULL; + /* Select CGA display */ + pgc->cga_selected = -1; + pgc_setdisplay(pgc, pgc->cga_enabled); + pgc->mapram[0x30C] = pgc->cga_enabled; + pgc->mapram[0x30D] = pgc->cga_enabled; + /* Default palette is 0 */ + pgc_init_lut(pgc, 0); + hndl_lutsav(pgc); } /* Initialisation code common to the PGC and its subclasses. * - * Pass the 'input byte' function in since this is overridden in - * the IM-1024, and needs to be set before the drawing thread is + * Pass the 'input byte' function in since this is overridden in + * the IM-1024, and needs to be set before the drawing thread is * launched */ void pgc_core_init(pgc_core_t *pgc, int maxw, int maxh, int visw, int vish, - int (*inpbyte)(struct pgc_core_t *pgc, uint8_t *result), double native_pixel_clock) { - int n; + int (*inpbyte)(struct pgc_core_t *pgc, uint8_t *result), double native_pixel_clock) { + int n; - mem_mapping_add(&pgc->mapping, 0xC6000, 0x800, - pgc_read, NULL, NULL, - pgc_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, pgc); - mem_mapping_add(&pgc->cga_mapping, 0xB8000, 0x8000, - pgc_read, NULL, NULL, - pgc_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, pgc); - io_sethandler(0x3D0, 0x0010, pgc_in, NULL, NULL, pgc_out, NULL, NULL, - pgc); + mem_mapping_add(&pgc->mapping, 0xC6000, 0x800, pgc_read, NULL, NULL, pgc_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, + pgc); + mem_mapping_add(&pgc->cga_mapping, 0xB8000, 0x8000, pgc_read, NULL, NULL, pgc_write, NULL, NULL, NULL, + MEM_MAPPING_EXTERNAL, pgc); + io_sethandler(0x3D0, 0x0010, pgc_in, NULL, NULL, pgc_out, NULL, NULL, pgc); - pgc->maxw = maxw; - pgc->maxh = maxh; - pgc->visw = visw; - pgc->vish = vish; - pgc->vram = malloc(maxw * maxh); - pgc->cga_vram = malloc(0x4000); - pgc->clist = calloc(256, sizeof(pgc_commandlist_t)); - pgc->clcur = NULL; - pgc->native_pixel_clock = native_pixel_clock; + pgc->maxw = maxw; + pgc->maxh = maxh; + pgc->visw = visw; + pgc->vish = vish; + pgc->vram = malloc(maxw * maxh); + pgc->cga_vram = malloc(0x4000); + pgc->clist = calloc(256, sizeof(pgc_commandlist_t)); + pgc->clcur = NULL; + pgc->native_pixel_clock = native_pixel_clock; - memset(pgc->vram, 0, maxw * maxh); - memset(pgc->cga_vram, 0, 0x4000); - /* Empty command lists */ - for (n = 0; n < 256; n++) { - pgc->clist[n].list = NULL; - pgc->clist[n].listmax = 0; - pgc->clist[n].wrptr = 0; - pgc->clist[n].rdptr = 0; - pgc->clist[n].repeat = 0; - pgc->clist[n].chain = NULL; - } + memset(pgc->vram, 0, maxw * maxh); + memset(pgc->cga_vram, 0, 0x4000); + /* Empty command lists */ + for (n = 0; n < 256; n++) { + pgc->clist[n].list = NULL; + pgc->clist[n].listmax = 0; + pgc->clist[n].wrptr = 0; + pgc->clist[n].rdptr = 0; + pgc->clist[n].repeat = 0; + pgc->clist[n].chain = NULL; + } - pgc_reset(pgc); - pgc->inputbyte = inpbyte; - pgc->pgc_commands = pgc_core_commands; - pgc->pgc_wake_thread = thread_create_event(); - pgc->pgc_thread = thread_create(pgc_core_thread, pgc); + pgc_reset(pgc); + pgc->inputbyte = inpbyte; + pgc->pgc_commands = pgc_core_commands; + pgc->pgc_wake_thread = thread_create_event(); + pgc->pgc_thread = thread_create(pgc_core_thread, pgc); - timer_add(&pgc->timer, pgc_poll, (void *)pgc, 1); + timer_add(&pgc->timer, pgc_poll, (void *)pgc, 1); - timer_add(&pgc->wake_timer, pgc_wake_timer, (void *)pgc, 0); + timer_add(&pgc->wake_timer, pgc_wake_timer, (void *)pgc, 0); } /* Initialisation code specific to the PGC */ void *pgc_standalone_init() { - pgc_core_t *pgc = malloc(sizeof(pgc_core_t)); - memset(pgc, 0, sizeof(pgc_core_t)); + pgc_core_t *pgc = malloc(sizeof(pgc_core_t)); + memset(pgc, 0, sizeof(pgc_core_t)); - /* Framebuffer and screen are both 640x480 */ - pgc_core_init(pgc, 640, 480, 640, 480, pgc_input_byte, 25175000.0); - return pgc; + /* Framebuffer and screen are both 640x480 */ + pgc_core_init(pgc, 640, 480, 640, 480, pgc_input_byte, 25175000.0); + return pgc; } void pgc_close(void *p) { - pgc_core_t *pgc = (pgc_core_t *)p; + pgc_core_t *pgc = (pgc_core_t *)p; - thread_kill(pgc->pgc_thread); - thread_destroy_event(pgc->pgc_wake_thread); + thread_kill(pgc->pgc_thread); + thread_destroy_event(pgc->pgc_wake_thread); - if (pgc->cga_vram) { - free(pgc->cga_vram); - } - if (pgc->vram) { - free(pgc->vram); - } - free(pgc); + if (pgc->cga_vram) { + free(pgc->cga_vram); + } + if (pgc->vram) { + free(pgc->vram); + } + free(pgc); } void pgc_speed_changed(void *p) { - pgc_core_t *pgc = (pgc_core_t *)p; + pgc_core_t *pgc = (pgc_core_t *)p; - pgc_recalctimings(pgc); + pgc_recalctimings(pgc); } -device_config_t pgc_config[] = - { - { - .type = -1 - } - }; - -device_t pgc_device = - { - "PGC", - 0, - pgc_standalone_init, - pgc_close, - NULL, - pgc_speed_changed, - NULL, - NULL, - pgc_config - }; +device_config_t pgc_config[] = {{.type = -1}}; +device_t pgc_device = {"PGC", 0, pgc_standalone_init, pgc_close, NULL, pgc_speed_changed, NULL, NULL, pgc_config}; diff --git a/src/video/vid_ps1_svga.c b/src/video/vid_ps1_svga.c index d74cbe8b..781521b1 100644 --- a/src/video/vid_ps1_svga.c +++ b/src/video/vid_ps1_svga.c @@ -1,6 +1,6 @@ /*Emulation of the SVGA chip in the IBM PS/1 Model 2121, or at least the 20 MHz version. - + I am not entirely sure what this chip actually is, possibly a CF62011? I can not find any documentation on the chip so have implemented enough to pass self-test in the PS/1 BIOS. It has 512kb video memory but I have not found any @@ -18,154 +18,157 @@ #include "vid_vga.h" typedef struct ps1_m2121_svga_t { - svga_t svga; + svga_t svga; - rom_t bios_rom; + rom_t bios_rom; - uint8_t banking; - uint8_t reg_2100; - uint8_t reg_210a; + uint8_t banking; + uint8_t reg_2100; + uint8_t reg_210a; } ps1_m2121_svga_t; void ps1_m2121_svga_out(uint16_t addr, uint8_t val, void *p) { - ps1_m2121_svga_t *ps1 = (ps1_m2121_svga_t *)p; - svga_t *svga = &ps1->svga; - uint8_t old; + ps1_m2121_svga_t *ps1 = (ps1_m2121_svga_t *)p; + svga_t *svga = &ps1->svga; + uint8_t old; -// pclog("svga_out : %04X %02X %04X:%04X %02X %i\n", addr, val, CS,cpu_state.pc, ram[0x489], ins); + // pclog("svga_out : %04X %02X %04X:%04X %02X %i\n", addr, val, CS,cpu_state.pc, ram[0x489], ins); - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; - switch (addr) { - case 0x3D4:svga->crtcreg = val & 0x3f; - return; - case 0x3D5: - if (svga->crtcreg & 0x20) - return; - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) - return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); - old = svga->crtc[svga->crtcreg]; - svga->crtc[svga->crtcreg] = val; - if (old != val) { - if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - } - break; + switch (addr) { + case 0x3D4: + svga->crtcreg = val & 0x3f; + return; + case 0x3D5: + if (svga->crtcreg & 0x20) + return; + if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) + return; + if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) + val = (svga->crtc[7] & ~0x10) | (val & 0x10); + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; + if (old != val) { + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } + } + break; - case 0x2100:ps1->reg_2100 = val; - if ((val & 7) < 4) - svga->read_bank = svga->write_bank = 0; - else - svga->read_bank = svga->write_bank = (ps1->banking & 0x7) * 0x10000; - break; - case 0x2108: - if ((ps1->reg_2100 & 7) >= 4) - svga->read_bank = svga->write_bank = (val & 0x7) * 0x10000; - ps1->banking = val; - break; - case 0x210a:ps1->reg_210a = val; - break; - } - svga_out(addr, val, svga); + case 0x2100: + ps1->reg_2100 = val; + if ((val & 7) < 4) + svga->read_bank = svga->write_bank = 0; + else + svga->read_bank = svga->write_bank = (ps1->banking & 0x7) * 0x10000; + break; + case 0x2108: + if ((ps1->reg_2100 & 7) >= 4) + svga->read_bank = svga->write_bank = (val & 0x7) * 0x10000; + ps1->banking = val; + break; + case 0x210a: + ps1->reg_210a = val; + break; + } + svga_out(addr, val, svga); } uint8_t ps1_m2121_svga_in(uint16_t addr, void *p) { - ps1_m2121_svga_t *ps1 = (ps1_m2121_svga_t *)p; - svga_t *svga = &ps1->svga; - uint8_t temp; + ps1_m2121_svga_t *ps1 = (ps1_m2121_svga_t *)p; + svga_t *svga = &ps1->svga; + uint8_t temp; -// if (addr != 0x3da) pclog("svga_in : %04X ", addr); + // if (addr != 0x3da) pclog("svga_in : %04X ", addr); - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; - switch (addr) { - case 0x100:temp = 0xfe; - break; - case 0x101:temp = 0xe8; - break; + switch (addr) { + case 0x100: + temp = 0xfe; + break; + case 0x101: + temp = 0xe8; + break; - case 0x3D4:temp = svga->crtcreg; - break; - case 0x3D5: - if (svga->crtcreg & 0x20) - temp = 0xff; - else - temp = svga->crtc[svga->crtcreg]; - break; + case 0x3D4: + temp = svga->crtcreg; + break; + case 0x3D5: + if (svga->crtcreg & 0x20) + temp = 0xff; + else + temp = svga->crtc[svga->crtcreg]; + break; - case 0x2108:temp = ps1->banking; - break; - case 0x210a:temp = ps1->reg_210a; - break; + case 0x2108: + temp = ps1->banking; + break; + case 0x210a: + temp = ps1->reg_210a; + break; - default:temp = svga_in(addr, svga); - break; - } -// if (addr != 0x3da) pclog("%02X %04X:%04X\n", temp, CS,pc); - return temp; + default: + temp = svga_in(addr, svga); + break; + } + // if (addr != 0x3da) pclog("%02X %04X:%04X\n", temp, CS,pc); + return temp; } void *ps1_m2121_svga_init() { - ps1_m2121_svga_t *ps1 = malloc(sizeof(ps1_m2121_svga_t)); - memset(ps1, 0, sizeof(ps1_m2121_svga_t)); + ps1_m2121_svga_t *ps1 = malloc(sizeof(ps1_m2121_svga_t)); + memset(ps1, 0, sizeof(ps1_m2121_svga_t)); - svga_init(&ps1->svga, ps1, 1 << 19, /*512kb*/ - NULL, - ps1_m2121_svga_in, ps1_m2121_svga_out, - NULL, - NULL); + svga_init(&ps1->svga, ps1, 1 << 19, /*512kb*/ + NULL, ps1_m2121_svga_in, ps1_m2121_svga_out, NULL, NULL); - io_sethandler(0x0100, 0x0002, ps1_m2121_svga_in, NULL, NULL, ps1_m2121_svga_out, NULL, NULL, ps1); - io_sethandler(0x03c0, 0x0020, ps1_m2121_svga_in, NULL, NULL, ps1_m2121_svga_out, NULL, NULL, ps1); - io_sethandler(0x2100, 0x0010, ps1_m2121_svga_in, NULL, NULL, ps1_m2121_svga_out, NULL, NULL, ps1); -// io_sethandler(0x210a, 0x0001, ps1_m2121_svga_in, NULL, NULL, ps1_m2121_svga_out, NULL, NULL, ps1); + io_sethandler(0x0100, 0x0002, ps1_m2121_svga_in, NULL, NULL, ps1_m2121_svga_out, NULL, NULL, ps1); + io_sethandler(0x03c0, 0x0020, ps1_m2121_svga_in, NULL, NULL, ps1_m2121_svga_out, NULL, NULL, ps1); + io_sethandler(0x2100, 0x0010, ps1_m2121_svga_in, NULL, NULL, ps1_m2121_svga_out, NULL, NULL, ps1); + // io_sethandler(0x210a, 0x0001, ps1_m2121_svga_in, NULL, NULL, ps1_m2121_svga_out, NULL, NULL, ps1); - ps1->svga.bpp = 8; - ps1->svga.miscout = 1; + ps1->svga.bpp = 8; + ps1->svga.miscout = 1; - return ps1; + return ps1; } void ps1_m2121_svga_close(void *p) { - ps1_m2121_svga_t *ps1 = (ps1_m2121_svga_t *)p; + ps1_m2121_svga_t *ps1 = (ps1_m2121_svga_t *)p; - svga_close(&ps1->svga); + svga_close(&ps1->svga); - free(ps1); + free(ps1); } void ps1_m2121_svga_speed_changed(void *p) { - ps1_m2121_svga_t *ps1 = (ps1_m2121_svga_t *)p; + ps1_m2121_svga_t *ps1 = (ps1_m2121_svga_t *)p; - svga_recalctimings(&ps1->svga); + svga_recalctimings(&ps1->svga); } void ps1_m2121_svga_force_redraw(void *p) { - ps1_m2121_svga_t *ps1 = (ps1_m2121_svga_t *)p; + ps1_m2121_svga_t *ps1 = (ps1_m2121_svga_t *)p; - ps1->svga.fullchange = changeframecount; + ps1->svga.fullchange = changeframecount; } void ps1_m2121_svga_add_status_info(char *s, int max_len, void *p) { - ps1_m2121_svga_t *ps1 = (ps1_m2121_svga_t *)p; + ps1_m2121_svga_t *ps1 = (ps1_m2121_svga_t *)p; - svga_add_status_info(s, max_len, &ps1->svga); + svga_add_status_info(s, max_len, &ps1->svga); } -device_t ps1_m2121_svga_device = - { - "PS/1 Model 2121 SVGA", - 0, - ps1_m2121_svga_init, - ps1_m2121_svga_close, - NULL, - ps1_m2121_svga_speed_changed, - ps1_m2121_svga_force_redraw, - ps1_m2121_svga_add_status_info - }; +device_t ps1_m2121_svga_device = {"PS/1 Model 2121 SVGA", + 0, + ps1_m2121_svga_init, + ps1_m2121_svga_close, + NULL, + ps1_m2121_svga_speed_changed, + ps1_m2121_svga_force_redraw, + ps1_m2121_svga_add_status_info}; diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 1434a801..0719643b 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -13,142 +13,132 @@ #include "vid_svga_render.h" #include "vid_sdac_ramdac.h" -enum { - S3_VISION864, - S3_TRIO32, - S3_TRIO64 -}; +enum { S3_VISION864, S3_TRIO32, S3_TRIO64 }; -enum { - VRAM_4MB = 0, - VRAM_8MB = 3, - VRAM_2MB = 4, - VRAM_1MB = 6, - VRAM_512KB = 7 -}; +enum { VRAM_4MB = 0, VRAM_8MB = 3, VRAM_2MB = 4, VRAM_1MB = 6, VRAM_512KB = 7 }; #define FIFO_SIZE 65536 #define FIFO_MASK (FIFO_SIZE - 1) #define FIFO_ENTRY_SIZE (1 << 31) #define FIFO_ENTRIES (s3->fifo_write_idx - s3->fifo_read_idx) -#define FIFO_FULL ((s3->fifo_write_idx - s3->fifo_read_idx) >= FIFO_SIZE) -#define FIFO_EMPTY (s3->fifo_read_idx == s3->fifo_write_idx) +#define FIFO_FULL ((s3->fifo_write_idx - s3->fifo_read_idx) >= FIFO_SIZE) +#define FIFO_EMPTY (s3->fifo_read_idx == s3->fifo_write_idx) #define FIFO_TYPE 0xff000000 #define FIFO_ADDR 0x00ffffff enum { - FIFO_INVALID = (0x00 << 24), - FIFO_WRITE_BYTE = (0x01 << 24), - FIFO_WRITE_WORD = (0x02 << 24), - FIFO_WRITE_DWORD = (0x03 << 24), - FIFO_OUT_BYTE = (0x04 << 24), - FIFO_OUT_WORD = (0x05 << 24), - FIFO_OUT_DWORD = (0x06 << 24) + FIFO_INVALID = (0x00 << 24), + FIFO_WRITE_BYTE = (0x01 << 24), + FIFO_WRITE_WORD = (0x02 << 24), + FIFO_WRITE_DWORD = (0x03 << 24), + FIFO_OUT_BYTE = (0x04 << 24), + FIFO_OUT_WORD = (0x05 << 24), + FIFO_OUT_DWORD = (0x06 << 24) }; typedef struct { - uint32_t addr_type; - uint32_t val; + uint32_t addr_type; + uint32_t val; } fifo_entry_t; typedef struct s3_t { - mem_mapping_t linear_mapping; - mem_mapping_t mmio_mapping; + mem_mapping_t linear_mapping; + mem_mapping_t mmio_mapping; - rom_t bios_rom; + rom_t bios_rom; - svga_t svga; - sdac_ramdac_t ramdac; + svga_t svga; + sdac_ramdac_t ramdac; - uint8_t bank; - uint8_t ma_ext; - int width; - int bpp; + uint8_t bank; + uint8_t ma_ext; + int width; + int bpp; - int chip; + int chip; - uint8_t id, id_ext, id_ext_pci; + uint8_t id, id_ext, id_ext_pci; - uint8_t int_line; + uint8_t int_line; - int packed_mmio; + int packed_mmio; - uint32_t linear_base, linear_size; + uint32_t linear_base, linear_size; - uint8_t pci_regs[256]; - int card; + uint8_t pci_regs[256]; + int card; - uint32_t vram_mask; + uint32_t vram_mask; - float (*getclock)(int clock, void *p); - void *getclock_p; + float (*getclock)(int clock, void *p); + void *getclock_p; - struct { - uint8_t subsys_cntl; - uint8_t setup_md; - uint8_t advfunc_cntl; - uint16_t cur_y, cur_y2; - uint16_t cur_x, cur_x2; - uint16_t x2; - int16_t desty_axstp, desty_axstp2; - int16_t destx_distp; - int16_t err_term, err_term2; - int16_t maj_axis_pcnt, maj_axis_pcnt2; - uint16_t cmd; - uint16_t short_stroke; - uint32_t bkgd_color; - uint32_t frgd_color; - uint32_t wrt_mask; - uint32_t rd_mask; - uint32_t color_cmp; - uint8_t bkgd_mix; - uint8_t frgd_mix; - uint16_t multifunc_cntl; - uint16_t multifunc[16]; - uint8_t pix_trans[4]; + struct { + uint8_t subsys_cntl; + uint8_t setup_md; + uint8_t advfunc_cntl; + uint16_t cur_y, cur_y2; + uint16_t cur_x, cur_x2; + uint16_t x2; + int16_t desty_axstp, desty_axstp2; + int16_t destx_distp; + int16_t err_term, err_term2; + int16_t maj_axis_pcnt, maj_axis_pcnt2; + uint16_t cmd; + uint16_t short_stroke; + uint32_t bkgd_color; + uint32_t frgd_color; + uint32_t wrt_mask; + uint32_t rd_mask; + uint32_t color_cmp; + uint8_t bkgd_mix; + uint8_t frgd_mix; + uint16_t multifunc_cntl; + uint16_t multifunc[16]; + uint8_t pix_trans[4]; - int cx, cy; - int sx, sy; - int dx, dy; - uint32_t src, dest, pattern; - int pix_trans_count; + int cx, cy; + int sx, sy; + int dx, dy; + uint32_t src, dest, pattern; + int pix_trans_count; - int poly_cx, poly_cx2; - int poly_cy, poly_cy2; - int point_1_updated, point_2_updated; - int poly_dx1, poly_dx2; - int poly_x; + int poly_cx, poly_cx2; + int poly_cy, poly_cy2; + int point_1_updated, point_2_updated; + int poly_dx1, poly_dx2; + int poly_x; - uint32_t dat_buf; - int dat_count; - } accel; + uint32_t dat_buf; + int dat_count; + } accel; - fifo_entry_t fifo[FIFO_SIZE]; - volatile int fifo_read_idx, fifo_write_idx; + fifo_entry_t fifo[FIFO_SIZE]; + volatile int fifo_read_idx, fifo_write_idx; - thread_t *fifo_thread; - event_t *wake_fifo_thread; - event_t *fifo_not_full_event; + thread_t *fifo_thread; + event_t *wake_fifo_thread; + event_t *fifo_not_full_event; - int blitter_busy; - uint64_t blitter_time; - uint64_t status_time; + int blitter_busy; + uint64_t blitter_time; + uint64_t status_time; - uint8_t subsys_cntl, subsys_stat; + uint8_t subsys_cntl, subsys_stat; - uint32_t hwc_fg_col, hwc_bg_col; - int hwc_col_stack_pos; + uint32_t hwc_fg_col, hwc_bg_col; + int hwc_col_stack_pos; - volatile int force_busy; + volatile int force_busy; } s3_t; -#define INT_VSY (1 << 0) -#define INT_GE_BSY (1 << 1) +#define INT_VSY (1 << 0) +#define INT_GE_BSY (1 << 1) #define INT_FIFO_OVR (1 << 2) #define INT_FIFO_EMP (1 << 3) -#define INT_MASK 0xf +#define INT_MASK 0xf void s3_updatemapping(); @@ -158,2776 +148,2988 @@ void s3_accel_write_l(uint32_t addr, uint32_t val, void *p); uint8_t s3_accel_read(uint32_t addr, void *p); static inline void wake_fifo_thread(s3_t *s3) { - thread_set_event(s3->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ + thread_set_event(s3->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ } static void s3_wait_fifo_idle(s3_t *s3) { - while (!FIFO_EMPTY) { - wake_fifo_thread(s3); - thread_wait_event(s3->fifo_not_full_event, 1); - } + while (!FIFO_EMPTY) { + wake_fifo_thread(s3); + thread_wait_event(s3->fifo_not_full_event, 1); + } } static void s3_update_irqs(s3_t *s3) { - if (s3->subsys_cntl & s3->subsys_stat & INT_MASK) - pci_set_irq(s3->card, PCI_INTA); - else - pci_clear_irq(s3->card, PCI_INTA); + if (s3->subsys_cntl & s3->subsys_stat & INT_MASK) + pci_set_irq(s3->card, PCI_INTA); + else + pci_clear_irq(s3->card, PCI_INTA); } void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_t *s3); -#define WRITE8(addr, var, val) switch ((addr) & 3) \ - { \ - case 0: var = (var & 0xffffff00) | (val); break; \ - case 1: var = (var & 0xffff00ff) | ((val) << 8); break; \ - case 2: var = (var & 0xff00ffff) | ((val) << 16); break; \ - case 3: var = (var & 0x00ffffff) | ((val) << 24); break; \ - } +#define WRITE8(addr, var, val) \ + switch ((addr)&3) { \ + case 0: \ + var = (var & 0xffffff00) | (val); \ + break; \ + case 1: \ + var = (var & 0xffff00ff) | ((val) << 8); \ + break; \ + case 2: \ + var = (var & 0xff00ffff) | ((val) << 16); \ + break; \ + case 3: \ + var = (var & 0x00ffffff) | ((val) << 24); \ + break; \ + } static void s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) { - switch (port) { - case 0x82e8:s3->accel.cur_y = (s3->accel.cur_y & 0xf00) | val; - s3->accel.poly_cy = s3->accel.cur_y; - break; - case 0x82e9:s3->accel.cur_y = (s3->accel.cur_y & 0xff) | ((val & 0x1f) << 8); - s3->accel.poly_cy = s3->accel.cur_y; - break; - case 0x82ea:s3->accel.cur_y2 = (s3->accel.cur_y2 & 0xf00) | val; - s3->accel.poly_cy2 = s3->accel.cur_y2; - break; - case 0x82eb:s3->accel.cur_y2 = (s3->accel.cur_y2 & 0xff) | ((val & 0x1f) << 8); - s3->accel.poly_cy2 = s3->accel.cur_y2; - break; + switch (port) { + case 0x82e8: + s3->accel.cur_y = (s3->accel.cur_y & 0xf00) | val; + s3->accel.poly_cy = s3->accel.cur_y; + break; + case 0x82e9: + s3->accel.cur_y = (s3->accel.cur_y & 0xff) | ((val & 0x1f) << 8); + s3->accel.poly_cy = s3->accel.cur_y; + break; + case 0x82ea: + s3->accel.cur_y2 = (s3->accel.cur_y2 & 0xf00) | val; + s3->accel.poly_cy2 = s3->accel.cur_y2; + break; + case 0x82eb: + s3->accel.cur_y2 = (s3->accel.cur_y2 & 0xff) | ((val & 0x1f) << 8); + s3->accel.poly_cy2 = s3->accel.cur_y2; + break; - case 0x86e8:s3->accel.cur_x = (s3->accel.cur_x & 0xf00) | val; - s3->accel.poly_cx = s3->accel.cur_x << 20; - s3->accel.poly_x = s3->accel.poly_cx >> 20; - break; - case 0x86e9:s3->accel.cur_x = (s3->accel.cur_x & 0xff) | ((val & 0x1f) << 8); - s3->accel.poly_cx = s3->accel.poly_x = s3->accel.cur_x << 20; - s3->accel.poly_x = s3->accel.poly_cx >> 20; - break; - case 0x86ea:s3->accel.cur_x2 = (s3->accel.cur_x2 & 0xf00) | val; - s3->accel.poly_cx2 = s3->accel.cur_x2 << 20; - break; - case 0x86eb:s3->accel.cur_x2 = (s3->accel.cur_x2 & 0xff) | ((val & 0x1f) << 8); - s3->accel.poly_cx2 = s3->accel.cur_x2 << 20; - break; + case 0x86e8: + s3->accel.cur_x = (s3->accel.cur_x & 0xf00) | val; + s3->accel.poly_cx = s3->accel.cur_x << 20; + s3->accel.poly_x = s3->accel.poly_cx >> 20; + break; + case 0x86e9: + s3->accel.cur_x = (s3->accel.cur_x & 0xff) | ((val & 0x1f) << 8); + s3->accel.poly_cx = s3->accel.poly_x = s3->accel.cur_x << 20; + s3->accel.poly_x = s3->accel.poly_cx >> 20; + break; + case 0x86ea: + s3->accel.cur_x2 = (s3->accel.cur_x2 & 0xf00) | val; + s3->accel.poly_cx2 = s3->accel.cur_x2 << 20; + break; + case 0x86eb: + s3->accel.cur_x2 = (s3->accel.cur_x2 & 0xff) | ((val & 0x1f) << 8); + s3->accel.poly_cx2 = s3->accel.cur_x2 << 20; + break; - case 0x8ae8:s3->accel.desty_axstp = (s3->accel.desty_axstp & 0x3f00) | val; - s3->accel.point_1_updated = 1; - break; - case 0x8ae9:s3->accel.desty_axstp = (s3->accel.desty_axstp & 0xff) | ((val & 0x3f) << 8); - if (val & 0x20) - s3->accel.desty_axstp |= ~0x3fff; - s3->accel.point_1_updated = 1; - break; - case 0x8aea:s3->accel.desty_axstp2 = (s3->accel.desty_axstp2 & 0x3f00) | val; - s3->accel.point_2_updated = 1; - break; - case 0x8aeb:s3->accel.desty_axstp2 = (s3->accel.desty_axstp2 & 0xff) | ((val & 0x3f) << 8); - if (val & 0x20) - s3->accel.desty_axstp2 |= ~0x3fff; - s3->accel.point_2_updated = 1; - break; + case 0x8ae8: + s3->accel.desty_axstp = (s3->accel.desty_axstp & 0x3f00) | val; + s3->accel.point_1_updated = 1; + break; + case 0x8ae9: + s3->accel.desty_axstp = (s3->accel.desty_axstp & 0xff) | ((val & 0x3f) << 8); + if (val & 0x20) + s3->accel.desty_axstp |= ~0x3fff; + s3->accel.point_1_updated = 1; + break; + case 0x8aea: + s3->accel.desty_axstp2 = (s3->accel.desty_axstp2 & 0x3f00) | val; + s3->accel.point_2_updated = 1; + break; + case 0x8aeb: + s3->accel.desty_axstp2 = (s3->accel.desty_axstp2 & 0xff) | ((val & 0x3f) << 8); + if (val & 0x20) + s3->accel.desty_axstp2 |= ~0x3fff; + s3->accel.point_2_updated = 1; + break; - case 0x8ee8:s3->accel.destx_distp = (s3->accel.destx_distp & 0x3f00) | val; - s3->accel.point_1_updated = 1; - break; - case 0x8ee9:s3->accel.destx_distp = (s3->accel.destx_distp & 0xff) | ((val & 0x3f) << 8); - if (val & 0x20) - s3->accel.destx_distp |= ~0x3fff; - s3->accel.point_1_updated = 1; - break; - case 0x8eea:s3->accel.x2 = (s3->accel.x2 & 0xf00) | val; - s3->accel.point_2_updated = 1; - break; - case 0x8eeb:s3->accel.x2 = (s3->accel.x2 & 0xff) | ((val & 0xf) << 8); - s3->accel.point_2_updated = 1; - break; + case 0x8ee8: + s3->accel.destx_distp = (s3->accel.destx_distp & 0x3f00) | val; + s3->accel.point_1_updated = 1; + break; + case 0x8ee9: + s3->accel.destx_distp = (s3->accel.destx_distp & 0xff) | ((val & 0x3f) << 8); + if (val & 0x20) + s3->accel.destx_distp |= ~0x3fff; + s3->accel.point_1_updated = 1; + break; + case 0x8eea: + s3->accel.x2 = (s3->accel.x2 & 0xf00) | val; + s3->accel.point_2_updated = 1; + break; + case 0x8eeb: + s3->accel.x2 = (s3->accel.x2 & 0xff) | ((val & 0xf) << 8); + s3->accel.point_2_updated = 1; + break; - case 0x92e8:s3->accel.err_term = (s3->accel.err_term & 0x3f00) | val; - break; - case 0x92e9:s3->accel.err_term = (s3->accel.err_term & 0xff) | ((val & 0x3f) << 8); - if (val & 0x20) - s3->accel.err_term |= ~0x3fff; - break; - case 0x92ea:s3->accel.err_term2 = (s3->accel.err_term2 & 0x3f00) | val; - break; - case 0x92eb:s3->accel.err_term2 = (s3->accel.err_term2 & 0xff) | ((val & 0x3f) << 8); - if (val & 0x20) - s3->accel.err_term2 |= ~0x3fff; - break; + case 0x92e8: + s3->accel.err_term = (s3->accel.err_term & 0x3f00) | val; + break; + case 0x92e9: + s3->accel.err_term = (s3->accel.err_term & 0xff) | ((val & 0x3f) << 8); + if (val & 0x20) + s3->accel.err_term |= ~0x3fff; + break; + case 0x92ea: + s3->accel.err_term2 = (s3->accel.err_term2 & 0x3f00) | val; + break; + case 0x92eb: + s3->accel.err_term2 = (s3->accel.err_term2 & 0xff) | ((val & 0x3f) << 8); + if (val & 0x20) + s3->accel.err_term2 |= ~0x3fff; + break; - case 0x96e8:s3->accel.maj_axis_pcnt = (s3->accel.maj_axis_pcnt & 0x3f00) | val; - break; - case 0x96e9:s3->accel.maj_axis_pcnt = (s3->accel.maj_axis_pcnt & 0xff) | ((val & 0x0f) << 8); - if (val & 0x08) - s3->accel.maj_axis_pcnt |= ~0x0fff; - break; - case 0x96ea:s3->accel.maj_axis_pcnt2 = (s3->accel.maj_axis_pcnt2 & 0xf00) | val; - break; - case 0x96eb:s3->accel.maj_axis_pcnt2 = (s3->accel.maj_axis_pcnt2 & 0xff) | ((val & 0x0f) << 8); - if (val & 0x08) - s3->accel.maj_axis_pcnt2 |= ~0x0fff; - break; + case 0x96e8: + s3->accel.maj_axis_pcnt = (s3->accel.maj_axis_pcnt & 0x3f00) | val; + break; + case 0x96e9: + s3->accel.maj_axis_pcnt = (s3->accel.maj_axis_pcnt & 0xff) | ((val & 0x0f) << 8); + if (val & 0x08) + s3->accel.maj_axis_pcnt |= ~0x0fff; + break; + case 0x96ea: + s3->accel.maj_axis_pcnt2 = (s3->accel.maj_axis_pcnt2 & 0xf00) | val; + break; + case 0x96eb: + s3->accel.maj_axis_pcnt2 = (s3->accel.maj_axis_pcnt2 & 0xff) | ((val & 0x0f) << 8); + if (val & 0x08) + s3->accel.maj_axis_pcnt2 |= ~0x0fff; + break; - case 0x9ae8:s3->accel.cmd = (s3->accel.cmd & 0xff00) | val; - break; - case 0x9ae9:s3->accel.cmd = (s3->accel.cmd & 0xff) | (val << 8); - s3_accel_start(-1, 0, 0xffffffff, 0, s3); - s3->accel.pix_trans_count = 0; - s3->accel.multifunc[0xe] &= ~0x10; /*hack*/ - break; + case 0x9ae8: + s3->accel.cmd = (s3->accel.cmd & 0xff00) | val; + break; + case 0x9ae9: + s3->accel.cmd = (s3->accel.cmd & 0xff) | (val << 8); + s3_accel_start(-1, 0, 0xffffffff, 0, s3); + s3->accel.pix_trans_count = 0; + s3->accel.multifunc[0xe] &= ~0x10; /*hack*/ + break; - case 0x9ee8:s3->accel.short_stroke = (s3->accel.short_stroke & 0xff00) | val; - break; - case 0x9ee9:s3->accel.short_stroke = (s3->accel.short_stroke & 0xff) | (val << 8); - break; + case 0x9ee8: + s3->accel.short_stroke = (s3->accel.short_stroke & 0xff00) | val; + break; + case 0x9ee9: + s3->accel.short_stroke = (s3->accel.short_stroke & 0xff) | (val << 8); + break; - case 0xa2e8: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x00ff0000) | (val << 16); - else - s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x000000ff) | val; - break; - case 0xa2e9: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0xff000000) | (val << 24); - else - s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x0000ff00) | (val << 8); - if (!(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.multifunc[0xe] ^= 0x10; - break; - case 0xa2ea: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x00ff0000) | (val << 16); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) - s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x00ff0000) | (val << 16); - else - s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x000000ff) | val; - } - break; - case 0xa2eb: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0xff000000) | (val << 24); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) - s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0xff000000) | (val << 24); - else - s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x0000ff00) | (val << 8); - s3->accel.multifunc[0xe] ^= 0x10; - } - break; + case 0xa2e8: + if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x00ff0000) | (val << 16); + else + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x000000ff) | val; + break; + case 0xa2e9: + if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0xff000000) | (val << 24); + else + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x0000ff00) | (val << 8); + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + break; + case 0xa2ea: + if (s3->accel.multifunc[0xe] & 0x200) + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x00ff0000) | (val << 16); + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x00ff0000) | (val << 16); + else + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x000000ff) | val; + } + break; + case 0xa2eb: + if (s3->accel.multifunc[0xe] & 0x200) + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0xff000000) | (val << 24); + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0xff000000) | (val << 24); + else + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x0000ff00) | (val << 8); + s3->accel.multifunc[0xe] ^= 0x10; + } + break; - case 0xa6e8: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.frgd_color = (s3->accel.frgd_color & ~0x00ff0000) | (val << 16); - else - s3->accel.frgd_color = (s3->accel.frgd_color & ~0x000000ff) | val; - break; - case 0xa6e9: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.frgd_color = (s3->accel.frgd_color & ~0xff000000) | (val << 24); - else - s3->accel.frgd_color = (s3->accel.frgd_color & ~0x0000ff00) | (val << 8); - if (!(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.multifunc[0xe] ^= 0x10; - break; - case 0xa6ea: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.frgd_color = (s3->accel.frgd_color & ~0x00ff0000) | (val << 16); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) - s3->accel.frgd_color = (s3->accel.frgd_color & ~0x00ff0000) | (val << 16); - else - s3->accel.frgd_color = (s3->accel.frgd_color & ~0x000000ff) | val; - } - break; - case 0xa6eb: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.frgd_color = (s3->accel.frgd_color & ~0xff000000) | (val << 24); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) - s3->accel.frgd_color = (s3->accel.frgd_color & ~0xff000000) | (val << 24); - else - s3->accel.frgd_color = (s3->accel.frgd_color & ~0x0000ff00) | (val << 8); - s3->accel.multifunc[0xe] ^= 0x10; - } - break; + case 0xa6e8: + if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.frgd_color = (s3->accel.frgd_color & ~0x00ff0000) | (val << 16); + else + s3->accel.frgd_color = (s3->accel.frgd_color & ~0x000000ff) | val; + break; + case 0xa6e9: + if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.frgd_color = (s3->accel.frgd_color & ~0xff000000) | (val << 24); + else + s3->accel.frgd_color = (s3->accel.frgd_color & ~0x0000ff00) | (val << 8); + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + break; + case 0xa6ea: + if (s3->accel.multifunc[0xe] & 0x200) + s3->accel.frgd_color = (s3->accel.frgd_color & ~0x00ff0000) | (val << 16); + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.frgd_color = (s3->accel.frgd_color & ~0x00ff0000) | (val << 16); + else + s3->accel.frgd_color = (s3->accel.frgd_color & ~0x000000ff) | val; + } + break; + case 0xa6eb: + if (s3->accel.multifunc[0xe] & 0x200) + s3->accel.frgd_color = (s3->accel.frgd_color & ~0xff000000) | (val << 24); + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.frgd_color = (s3->accel.frgd_color & ~0xff000000) | (val << 24); + else + s3->accel.frgd_color = (s3->accel.frgd_color & ~0x0000ff00) | (val << 8); + s3->accel.multifunc[0xe] ^= 0x10; + } + break; - case 0xaae8: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x00ff0000) | (val << 16); - else - s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x000000ff) | val; - break; - case 0xaae9: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0xff000000) | (val << 24); - else - s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x0000ff00) | (val << 8); - if (!(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.multifunc[0xe] ^= 0x10; - break; - case 0xaaea: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x00ff0000) | (val << 16); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) - s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x00ff0000) | (val << 16); - else - s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x000000ff) | val; - } - break; - case 0xaaeb: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0xff000000) | (val << 24); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) - s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0xff000000) | (val << 24); - else - s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x0000ff00) | (val << 8); - s3->accel.multifunc[0xe] ^= 0x10; - } - break; + case 0xaae8: + if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x00ff0000) | (val << 16); + else + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x000000ff) | val; + break; + case 0xaae9: + if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0xff000000) | (val << 24); + else + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x0000ff00) | (val << 8); + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + break; + case 0xaaea: + if (s3->accel.multifunc[0xe] & 0x200) + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x00ff0000) | (val << 16); + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x00ff0000) | (val << 16); + else + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x000000ff) | val; + } + break; + case 0xaaeb: + if (s3->accel.multifunc[0xe] & 0x200) + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0xff000000) | (val << 24); + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0xff000000) | (val << 24); + else + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x0000ff00) | (val << 8); + s3->accel.multifunc[0xe] ^= 0x10; + } + break; - case 0xaee8: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.rd_mask = (s3->accel.rd_mask & ~0x00ff0000) | (val << 16); - else - s3->accel.rd_mask = (s3->accel.rd_mask & ~0x000000ff) | val; - break; - case 0xaee9: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.rd_mask = (s3->accel.rd_mask & ~0xff000000) | (val << 24); - else - s3->accel.rd_mask = (s3->accel.rd_mask & ~0x0000ff00) | (val << 8); - if (!(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.multifunc[0xe] ^= 0x10; - break; - case 0xaeea: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.rd_mask = (s3->accel.rd_mask & ~0x00ff0000) | (val << 16); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) - s3->accel.rd_mask = (s3->accel.rd_mask & ~0x00ff0000) | (val << 16); - else - s3->accel.rd_mask = (s3->accel.rd_mask & ~0x000000ff) | val; - } - break; - case 0xaeeb: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.rd_mask = (s3->accel.rd_mask & ~0xff000000) | (val << 24); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) - s3->accel.rd_mask = (s3->accel.rd_mask & ~0xff000000) | (val << 24); - else - s3->accel.rd_mask = (s3->accel.rd_mask & ~0x0000ff00) | (val << 8); - s3->accel.multifunc[0xe] ^= 0x10; - } - break; + case 0xaee8: + if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.rd_mask = (s3->accel.rd_mask & ~0x00ff0000) | (val << 16); + else + s3->accel.rd_mask = (s3->accel.rd_mask & ~0x000000ff) | val; + break; + case 0xaee9: + if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.rd_mask = (s3->accel.rd_mask & ~0xff000000) | (val << 24); + else + s3->accel.rd_mask = (s3->accel.rd_mask & ~0x0000ff00) | (val << 8); + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + break; + case 0xaeea: + if (s3->accel.multifunc[0xe] & 0x200) + s3->accel.rd_mask = (s3->accel.rd_mask & ~0x00ff0000) | (val << 16); + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.rd_mask = (s3->accel.rd_mask & ~0x00ff0000) | (val << 16); + else + s3->accel.rd_mask = (s3->accel.rd_mask & ~0x000000ff) | val; + } + break; + case 0xaeeb: + if (s3->accel.multifunc[0xe] & 0x200) + s3->accel.rd_mask = (s3->accel.rd_mask & ~0xff000000) | (val << 24); + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.rd_mask = (s3->accel.rd_mask & ~0xff000000) | (val << 24); + else + s3->accel.rd_mask = (s3->accel.rd_mask & ~0x0000ff00) | (val << 8); + s3->accel.multifunc[0xe] ^= 0x10; + } + break; - case 0xb2e8: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.color_cmp = (s3->accel.color_cmp & ~0x00ff0000) | (val << 16); - else - s3->accel.color_cmp = (s3->accel.color_cmp & ~0x000000ff) | val; - break; - case 0xb2e9: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.color_cmp = (s3->accel.color_cmp & ~0xff000000) | (val << 24); - else - s3->accel.color_cmp = (s3->accel.color_cmp & ~0x0000ff00) | (val << 8); - if (!(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.multifunc[0xe] ^= 0x10; - break; - case 0xb2ea: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.color_cmp = (s3->accel.color_cmp & ~0x00ff0000) | (val << 16); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) - s3->accel.color_cmp = (s3->accel.color_cmp & ~0x00ff0000) | (val << 16); - else - s3->accel.color_cmp = (s3->accel.color_cmp & ~0x000000ff) | val; - } - break; - case 0xb2eb: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.color_cmp = (s3->accel.color_cmp & ~0xff000000) | (val << 24); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) - s3->accel.color_cmp = (s3->accel.color_cmp & ~0xff000000) | (val << 24); - else - s3->accel.color_cmp = (s3->accel.color_cmp & ~0x0000ff00) | (val << 8); - s3->accel.multifunc[0xe] ^= 0x10; - } - break; + case 0xb2e8: + if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.color_cmp = (s3->accel.color_cmp & ~0x00ff0000) | (val << 16); + else + s3->accel.color_cmp = (s3->accel.color_cmp & ~0x000000ff) | val; + break; + case 0xb2e9: + if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.color_cmp = (s3->accel.color_cmp & ~0xff000000) | (val << 24); + else + s3->accel.color_cmp = (s3->accel.color_cmp & ~0x0000ff00) | (val << 8); + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + break; + case 0xb2ea: + if (s3->accel.multifunc[0xe] & 0x200) + s3->accel.color_cmp = (s3->accel.color_cmp & ~0x00ff0000) | (val << 16); + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.color_cmp = (s3->accel.color_cmp & ~0x00ff0000) | (val << 16); + else + s3->accel.color_cmp = (s3->accel.color_cmp & ~0x000000ff) | val; + } + break; + case 0xb2eb: + if (s3->accel.multifunc[0xe] & 0x200) + s3->accel.color_cmp = (s3->accel.color_cmp & ~0xff000000) | (val << 24); + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.color_cmp = (s3->accel.color_cmp & ~0xff000000) | (val << 24); + else + s3->accel.color_cmp = (s3->accel.color_cmp & ~0x0000ff00) | (val << 8); + s3->accel.multifunc[0xe] ^= 0x10; + } + break; - case 0xb6e8:s3->accel.bkgd_mix = val; - break; + case 0xb6e8: + s3->accel.bkgd_mix = val; + break; - case 0xbae8:s3->accel.frgd_mix = val; - break; + case 0xbae8: + s3->accel.frgd_mix = val; + break; - case 0xbee8:s3->accel.multifunc_cntl = (s3->accel.multifunc_cntl & 0xff00) | val; - break; - case 0xbee9:s3->accel.multifunc_cntl = (s3->accel.multifunc_cntl & 0xff) | (val << 8); - s3->accel.multifunc[s3->accel.multifunc_cntl >> 12] = s3->accel.multifunc_cntl & 0xfff; - break; + case 0xbee8: + s3->accel.multifunc_cntl = (s3->accel.multifunc_cntl & 0xff00) | val; + break; + case 0xbee9: + s3->accel.multifunc_cntl = (s3->accel.multifunc_cntl & 0xff) | (val << 8); + s3->accel.multifunc[s3->accel.multifunc_cntl >> 12] = s3->accel.multifunc_cntl & 0xfff; + break; - case 0xe2e8:s3->accel.pix_trans[0] = val; - if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && !(s3->accel.cmd & 0x600) && (s3->accel.cmd & 0x100)) - s3_accel_start(8, 1, s3->accel.pix_trans[0], 0, s3); - else if (!(s3->accel.cmd & 0x600) && (s3->accel.cmd & 0x100)) - s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0], s3); - break; - case 0xe2e9:s3->accel.pix_trans[1] = val; - if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && (s3->accel.cmd & 0x600) == 0x200 && (s3->accel.cmd & 0x100)) { - if (s3->accel.cmd & 0x1000) - s3_accel_start(16, 1, s3->accel.pix_trans[1] | (s3->accel.pix_trans[0] << 8), 0, s3); - else - s3_accel_start(16, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), 0, s3); - } else if ((s3->accel.cmd & 0x600) == 0x200 && (s3->accel.cmd & 0x100)) { - if (s3->accel.cmd & 0x1000) - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[1] | (s3->accel.pix_trans[0] << 8), s3); - else - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); - } - break; - case 0xe2ea:s3->accel.pix_trans[2] = val; - break; - case 0xe2eb:s3->accel.pix_trans[3] = val; - if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && (s3->accel.cmd & 0x600) == 0x600 && (s3->accel.cmd & 0x100) && s3->chip == S3_TRIO32) { - s3_accel_start(8, 1, s3->accel.pix_trans[3], 0, s3); - s3_accel_start(8, 1, s3->accel.pix_trans[2], 0, s3); - s3_accel_start(8, 1, s3->accel.pix_trans[1], 0, s3); - s3_accel_start(8, 1, s3->accel.pix_trans[0], 0, s3); - } else if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && (s3->accel.cmd & 0x400) == 0x400 && (s3->accel.cmd & 0x100)) - s3_accel_start(32, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), 0, s3); - else if ((s3->accel.cmd & 0x600) == 0x400 && (s3->accel.cmd & 0x100)) - s3_accel_start(4, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); - break; - } + case 0xe2e8: + s3->accel.pix_trans[0] = val; + if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && !(s3->accel.cmd & 0x600) && (s3->accel.cmd & 0x100)) + s3_accel_start(8, 1, s3->accel.pix_trans[0], 0, s3); + else if (!(s3->accel.cmd & 0x600) && (s3->accel.cmd & 0x100)) + s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0], s3); + break; + case 0xe2e9: + s3->accel.pix_trans[1] = val; + if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && (s3->accel.cmd & 0x600) == 0x200 && (s3->accel.cmd & 0x100)) { + if (s3->accel.cmd & 0x1000) + s3_accel_start(16, 1, s3->accel.pix_trans[1] | (s3->accel.pix_trans[0] << 8), 0, s3); + else + s3_accel_start(16, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), 0, s3); + } else if ((s3->accel.cmd & 0x600) == 0x200 && (s3->accel.cmd & 0x100)) { + if (s3->accel.cmd & 0x1000) + s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[1] | (s3->accel.pix_trans[0] << 8), s3); + else + s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); + } + break; + case 0xe2ea: + s3->accel.pix_trans[2] = val; + break; + case 0xe2eb: + s3->accel.pix_trans[3] = val; + if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && (s3->accel.cmd & 0x600) == 0x600 && (s3->accel.cmd & 0x100) && + s3->chip == S3_TRIO32) { + s3_accel_start(8, 1, s3->accel.pix_trans[3], 0, s3); + s3_accel_start(8, 1, s3->accel.pix_trans[2], 0, s3); + s3_accel_start(8, 1, s3->accel.pix_trans[1], 0, s3); + s3_accel_start(8, 1, s3->accel.pix_trans[0], 0, s3); + } else if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && (s3->accel.cmd & 0x400) == 0x400 && + (s3->accel.cmd & 0x100)) + s3_accel_start(32, 1, + s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | + (s3->accel.pix_trans[3] << 24), + 0, s3); + else if ((s3->accel.cmd & 0x600) == 0x400 && (s3->accel.cmd & 0x100)) + s3_accel_start(4, 1, 0xffffffff, + s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | + (s3->accel.pix_trans[3] << 24), + s3); + break; + } } static void s3_accel_out_fifo_w(s3_t *s3, uint16_t port, uint16_t val) { -// pclog("Accel out w %04X %04X\n", port, val); - if (s3->accel.cmd & 0x100) { - if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80) { - if (s3->accel.cmd & 0x1000) - val = (val >> 8) | (val << 8); - if ((s3->accel.cmd & 0x600) == 0x600 && s3->chip == S3_TRIO32) { - s3_accel_start(8, 1, (val >> 8) & 0xff, 0, s3); - s3_accel_start(8, 1, val & 0xff, 0, s3); - } - if ((s3->accel.cmd & 0x600) == 0x000) - s3_accel_start(8, 1, val | (val << 16), 0, s3); - else - s3_accel_start(16, 1, val | (val << 16), 0, s3); - } else { - if ((s3->accel.cmd & 0x600) == 0x000) - s3_accel_start(1, 1, 0xffffffff, val | (val << 16), s3); - else - s3_accel_start(2, 1, 0xffffffff, val | (val << 16), s3); - } - } + // pclog("Accel out w %04X %04X\n", port, val); + if (s3->accel.cmd & 0x100) { + if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80) { + if (s3->accel.cmd & 0x1000) + val = (val >> 8) | (val << 8); + if ((s3->accel.cmd & 0x600) == 0x600 && s3->chip == S3_TRIO32) { + s3_accel_start(8, 1, (val >> 8) & 0xff, 0, s3); + s3_accel_start(8, 1, val & 0xff, 0, s3); + } + if ((s3->accel.cmd & 0x600) == 0x000) + s3_accel_start(8, 1, val | (val << 16), 0, s3); + else + s3_accel_start(16, 1, val | (val << 16), 0, s3); + } else { + if ((s3->accel.cmd & 0x600) == 0x000) + s3_accel_start(1, 1, 0xffffffff, val | (val << 16), s3); + else + s3_accel_start(2, 1, 0xffffffff, val | (val << 16), s3); + } + } } static void s3_accel_out_fifo_l(s3_t *s3, uint16_t port, uint32_t val) { -// pclog("Accel out l %04X %08X\n", port, val); - if (s3->accel.cmd & 0x100) { - if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80) { - if ((s3->accel.cmd & 0x600) == 0x600 && s3->chip == S3_TRIO32) { - if (s3->accel.cmd & 0x1000) - val = ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24); - s3_accel_start(8, 1, (val >> 24) & 0xff, 0, s3); - s3_accel_start(8, 1, (val >> 16) & 0xff, 0, s3); - s3_accel_start(8, 1, (val >> 8) & 0xff, 0, s3); - s3_accel_start(8, 1, val & 0xff, 0, s3); - } else if (s3->accel.cmd & 0x400) { - if (s3->accel.cmd & 0x1000) - val = ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24); - s3_accel_start(32, 1, val, 0, s3); - } else if ((s3->accel.cmd & 0x600) == 0x200) { - if (s3->accel.cmd & 0x1000) - val = ((val & 0xff00ff00) >> 8) | ((val & 0x00ff00ff) << 8); - s3_accel_start(16, 1, val, 0, s3); - s3_accel_start(16, 1, val >> 16, 0, s3); - } else { - if (s3->accel.cmd & 0x1000) - val = ((val & 0xff00ff00) >> 8) | ((val & 0x00ff00ff) << 8); - s3_accel_start(8, 1, val, 0, s3); - s3_accel_start(8, 1, val >> 16, 0, s3); - } - } else { - if (s3->accel.cmd & 0x400) - s3_accel_start(4, 1, 0xffffffff, val, s3); - else if ((s3->accel.cmd & 0x600) == 0x200) { - s3_accel_start(2, 1, 0xffffffff, val, s3); - s3_accel_start(2, 1, 0xffffffff, val >> 16, s3); - } else { - s3_accel_start(1, 1, 0xffffffff, val, s3); - s3_accel_start(1, 1, 0xffffffff, val >> 16, s3); - } - } - } + // pclog("Accel out l %04X %08X\n", port, val); + if (s3->accel.cmd & 0x100) { + if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80) { + if ((s3->accel.cmd & 0x600) == 0x600 && s3->chip == S3_TRIO32) { + if (s3->accel.cmd & 0x1000) + val = ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | + ((val & 0x000000ff) << 24); + s3_accel_start(8, 1, (val >> 24) & 0xff, 0, s3); + s3_accel_start(8, 1, (val >> 16) & 0xff, 0, s3); + s3_accel_start(8, 1, (val >> 8) & 0xff, 0, s3); + s3_accel_start(8, 1, val & 0xff, 0, s3); + } else if (s3->accel.cmd & 0x400) { + if (s3->accel.cmd & 0x1000) + val = ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | + ((val & 0x000000ff) << 24); + s3_accel_start(32, 1, val, 0, s3); + } else if ((s3->accel.cmd & 0x600) == 0x200) { + if (s3->accel.cmd & 0x1000) + val = ((val & 0xff00ff00) >> 8) | ((val & 0x00ff00ff) << 8); + s3_accel_start(16, 1, val, 0, s3); + s3_accel_start(16, 1, val >> 16, 0, s3); + } else { + if (s3->accel.cmd & 0x1000) + val = ((val & 0xff00ff00) >> 8) | ((val & 0x00ff00ff) << 8); + s3_accel_start(8, 1, val, 0, s3); + s3_accel_start(8, 1, val >> 16, 0, s3); + } + } else { + if (s3->accel.cmd & 0x400) + s3_accel_start(4, 1, 0xffffffff, val, s3); + else if ((s3->accel.cmd & 0x600) == 0x200) { + s3_accel_start(2, 1, 0xffffffff, val, s3); + s3_accel_start(2, 1, 0xffffffff, val >> 16, s3); + } else { + s3_accel_start(1, 1, 0xffffffff, val, s3); + s3_accel_start(1, 1, 0xffffffff, val >> 16, s3); + } + } + } } static void s3_accel_write_fifo(s3_t *s3, uint32_t addr, uint8_t val) { -// pclog("Write S3 accel %08X %02X\n", addr, val); - if (s3->packed_mmio) { - int addr_lo = addr & 1; - switch (addr & 0xfffe) { - case 0x8100:addr = 0x82e8; - break; /*ALT_CURXY*/ - case 0x8102:addr = 0x86e8; - break; + // pclog("Write S3 accel %08X %02X\n", addr, val); + if (s3->packed_mmio) { + int addr_lo = addr & 1; + switch (addr & 0xfffe) { + case 0x8100: + addr = 0x82e8; + break; /*ALT_CURXY*/ + case 0x8102: + addr = 0x86e8; + break; - case 0x8104:addr = 0x82ea; - break; /*ALT_CURXY2*/ - case 0x8106:addr = 0x86ea; - break; + case 0x8104: + addr = 0x82ea; + break; /*ALT_CURXY2*/ + case 0x8106: + addr = 0x86ea; + break; - case 0x8108:addr = 0x8ae8; - break; /*ALT_STEP*/ - case 0x810a:addr = 0x8ee8; - break; + case 0x8108: + addr = 0x8ae8; + break; /*ALT_STEP*/ + case 0x810a: + addr = 0x8ee8; + break; - case 0x810c:addr = 0x8aea; - break; /*ALT_STEP2*/ - case 0x810e:addr = 0x8eea; - break; + case 0x810c: + addr = 0x8aea; + break; /*ALT_STEP2*/ + case 0x810e: + addr = 0x8eea; + break; - case 0x8110:addr = 0x92e8; - break; /*ALT_ERR*/ - case 0x8112:addr = 0x92ee; - break; + case 0x8110: + addr = 0x92e8; + break; /*ALT_ERR*/ + case 0x8112: + addr = 0x92ee; + break; - case 0x8118:addr = 0x9ae8; - break; /*ALT_CMD*/ - case 0x811a:addr = 0x9aea; - break; + case 0x8118: + addr = 0x9ae8; + break; /*ALT_CMD*/ + case 0x811a: + addr = 0x9aea; + break; - case 0x811c:addr = 0x9ee8; - break; /*SHORT_STROKE*/ + case 0x811c: + addr = 0x9ee8; + break; /*SHORT_STROKE*/ - case 0x8120: - case 0x8122: /*BKGD_COLOR*/ - WRITE8(addr, s3->accel.bkgd_color, val); - return; + case 0x8120: + case 0x8122: /*BKGD_COLOR*/ + WRITE8(addr, s3->accel.bkgd_color, val); + return; - case 0x8124: - case 0x8126: /*FRGD_COLOR*/ - WRITE8(addr, s3->accel.frgd_color, val); - return; + case 0x8124: + case 0x8126: /*FRGD_COLOR*/ + WRITE8(addr, s3->accel.frgd_color, val); + return; - case 0x8128: - case 0x812a: /*WRT_MASK*/ - WRITE8(addr, s3->accel.wrt_mask, val); - return; + case 0x8128: + case 0x812a: /*WRT_MASK*/ + WRITE8(addr, s3->accel.wrt_mask, val); + return; - case 0x812c: - case 0x812e: /*RD_MASK*/ - WRITE8(addr, s3->accel.rd_mask, val); - return; + case 0x812c: + case 0x812e: /*RD_MASK*/ + WRITE8(addr, s3->accel.rd_mask, val); + return; - case 0x8130: - case 0x8132: /*COLOR_CMP*/ - WRITE8(addr, s3->accel.color_cmp, val); - return; + case 0x8130: + case 0x8132: /*COLOR_CMP*/ + WRITE8(addr, s3->accel.color_cmp, val); + return; - case 0x8134:addr = 0xb6e8; - break; /*ALT_MIX*/ - case 0x8136:addr = 0xbae8; - break; + case 0x8134: + addr = 0xb6e8; + break; /*ALT_MIX*/ + case 0x8136: + addr = 0xbae8; + break; - case 0x8138: /*SCISSORS_T*/ - WRITE8(addr & 1, s3->accel.multifunc[1], val); - return; - case 0x813a: /*SCISSORS_L*/ - WRITE8(addr & 1, s3->accel.multifunc[2], val); - return; - case 0x813c: /*SCISSORS_B*/ - WRITE8(addr & 1, s3->accel.multifunc[3], val); - return; - case 0x813e: /*SCISSORS_R*/ - WRITE8(addr & 1, s3->accel.multifunc[4], val); - return; + case 0x8138: /*SCISSORS_T*/ + WRITE8(addr & 1, s3->accel.multifunc[1], val); + return; + case 0x813a: /*SCISSORS_L*/ + WRITE8(addr & 1, s3->accel.multifunc[2], val); + return; + case 0x813c: /*SCISSORS_B*/ + WRITE8(addr & 1, s3->accel.multifunc[3], val); + return; + case 0x813e: /*SCISSORS_R*/ + WRITE8(addr & 1, s3->accel.multifunc[4], val); + return; - case 0x8140: /*PIX_CNTL*/ - WRITE8(addr & 1, s3->accel.multifunc[0xa], val); - return; - case 0x8142: /*MULT_MISC2*/ - WRITE8(addr & 1, s3->accel.multifunc[0xd], val); - return; - case 0x8144: /*MULT_MISC*/ - WRITE8(addr & 1, s3->accel.multifunc[0xe], val); - return; - case 0x8146: /*READ_SEL*/ - WRITE8(addr & 1, s3->accel.multifunc[0xf], val); - return; + case 0x8140: /*PIX_CNTL*/ + WRITE8(addr & 1, s3->accel.multifunc[0xa], val); + return; + case 0x8142: /*MULT_MISC2*/ + WRITE8(addr & 1, s3->accel.multifunc[0xd], val); + return; + case 0x8144: /*MULT_MISC*/ + WRITE8(addr & 1, s3->accel.multifunc[0xe], val); + return; + case 0x8146: /*READ_SEL*/ + WRITE8(addr & 1, s3->accel.multifunc[0xf], val); + return; - case 0x8148: /*ALT_PCNT*/ - WRITE8(addr & 1, s3->accel.multifunc[0], val); - return; - case 0x814a:addr = 0x96e8; - break; - case 0x814c:addr = 0x96ea; - break; + case 0x8148: /*ALT_PCNT*/ + WRITE8(addr & 1, s3->accel.multifunc[0], val); + return; + case 0x814a: + addr = 0x96e8; + break; + case 0x814c: + addr = 0x96ea; + break; - case 0x8168:addr = 0xeae8; - break; - case 0x816a:addr = 0xeaea; - break; - } - addr |= addr_lo; - } + case 0x8168: + addr = 0xeae8; + break; + case 0x816a: + addr = 0xeaea; + break; + } + addr |= addr_lo; + } - if (addr & 0x8000) { - s3_accel_out_fifo(s3, addr & 0xffff, val); - } else { - if (s3->accel.cmd & 0x100) { - if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80) - s3_accel_start(8, 1, val | (val << 8) | (val << 16) | (val << 24), 0, s3); - else - s3_accel_start(1, 1, 0xffffffff, val | (val << 8) | (val << 16) | (val << 24), s3); - } - } + if (addr & 0x8000) { + s3_accel_out_fifo(s3, addr & 0xffff, val); + } else { + if (s3->accel.cmd & 0x100) { + if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80) + s3_accel_start(8, 1, val | (val << 8) | (val << 16) | (val << 24), 0, s3); + else + s3_accel_start(1, 1, 0xffffffff, val | (val << 8) | (val << 16) | (val << 24), s3); + } + } } static void s3_accel_write_fifo_w(s3_t *s3, uint32_t addr, uint16_t val) { -// pclog("Write S3 accel w %08X %04X\n", addr, val); - if (addr & 0x8000) { - s3_accel_write_fifo(s3, addr, val); - s3_accel_write_fifo(s3, addr + 1, val >> 8); - } else { - if (s3->accel.cmd & 0x100) { - if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80) { - if (s3->accel.cmd & 0x1000) - val = (val >> 8) | (val << 8); - if ((s3->accel.cmd & 0x600) == 0x600 && s3->chip == S3_TRIO32) { - s3_accel_start(8, 1, (val >> 8) & 0xff, 0, s3); - s3_accel_start(8, 1, val & 0xff, 0, s3); - } else if ((s3->accel.cmd & 0x600) == 0x000) - s3_accel_start(8, 1, val | (val << 16), 0, s3); - else - s3_accel_start(16, 1, val | (val << 16), 0, s3); - } else { - if ((s3->accel.cmd & 0x600) == 0x000) - s3_accel_start(1, 1, 0xffffffff, val | (val << 16), s3); - else - s3_accel_start(2, 1, 0xffffffff, val | (val << 16), s3); - } - } - } + // pclog("Write S3 accel w %08X %04X\n", addr, val); + if (addr & 0x8000) { + s3_accel_write_fifo(s3, addr, val); + s3_accel_write_fifo(s3, addr + 1, val >> 8); + } else { + if (s3->accel.cmd & 0x100) { + if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80) { + if (s3->accel.cmd & 0x1000) + val = (val >> 8) | (val << 8); + if ((s3->accel.cmd & 0x600) == 0x600 && s3->chip == S3_TRIO32) { + s3_accel_start(8, 1, (val >> 8) & 0xff, 0, s3); + s3_accel_start(8, 1, val & 0xff, 0, s3); + } else if ((s3->accel.cmd & 0x600) == 0x000) + s3_accel_start(8, 1, val | (val << 16), 0, s3); + else + s3_accel_start(16, 1, val | (val << 16), 0, s3); + } else { + if ((s3->accel.cmd & 0x600) == 0x000) + s3_accel_start(1, 1, 0xffffffff, val | (val << 16), s3); + else + s3_accel_start(2, 1, 0xffffffff, val | (val << 16), s3); + } + } + } } static void s3_accel_write_fifo_l(s3_t *s3, uint32_t addr, uint32_t val) { -// pclog("Write S3 accel l %08X %08X\n", addr, val); - if (addr & 0x8000) { - s3_accel_write_fifo(s3, addr, val); - s3_accel_write_fifo(s3, addr + 1, val >> 8); - s3_accel_write_fifo(s3, addr + 2, val >> 16); - s3_accel_write_fifo(s3, addr + 3, val >> 24); - } else { - if (s3->accel.cmd & 0x100) { - if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80) { - if ((s3->accel.cmd & 0x600) == 0x600 && s3->chip == S3_TRIO32) { - if (s3->accel.cmd & 0x1000) - val = ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24); - s3_accel_start(8, 1, (val >> 24) & 0xff, 0, s3); - s3_accel_start(8, 1, (val >> 16) & 0xff, 0, s3); - s3_accel_start(8, 1, (val >> 8) & 0xff, 0, s3); - s3_accel_start(8, 1, val & 0xff, 0, s3); - } else if (s3->accel.cmd & 0x400) { - if (s3->accel.cmd & 0x1000) - val = ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24); - s3_accel_start(32, 1, val, 0, s3); - } else if ((s3->accel.cmd & 0x600) == 0x200) { - if (s3->accel.cmd & 0x1000) - val = ((val & 0xff00ff00) >> 8) | ((val & 0x00ff00ff) << 8); - s3_accel_start(16, 1, val, 0, s3); - s3_accel_start(16, 1, val >> 16, 0, s3); - } else { - if (s3->accel.cmd & 0x1000) - val = ((val & 0xff00ff00) >> 8) | ((val & 0x00ff00ff) << 8); - s3_accel_start(8, 1, val, 0, s3); - s3_accel_start(8, 1, val >> 16, 0, s3); - } - } else { - if (s3->accel.cmd & 0x400) - s3_accel_start(4, 1, 0xffffffff, val, s3); - else if ((s3->accel.cmd & 0x600) == 0x200) { - s3_accel_start(2, 1, 0xffffffff, val, s3); - s3_accel_start(2, 1, 0xffffffff, val >> 16, s3); - } else { - s3_accel_start(1, 1, 0xffffffff, val, s3); - s3_accel_start(1, 1, 0xffffffff, val >> 16, s3); - } - } - } - } + // pclog("Write S3 accel l %08X %08X\n", addr, val); + if (addr & 0x8000) { + s3_accel_write_fifo(s3, addr, val); + s3_accel_write_fifo(s3, addr + 1, val >> 8); + s3_accel_write_fifo(s3, addr + 2, val >> 16); + s3_accel_write_fifo(s3, addr + 3, val >> 24); + } else { + if (s3->accel.cmd & 0x100) { + if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80) { + if ((s3->accel.cmd & 0x600) == 0x600 && s3->chip == S3_TRIO32) { + if (s3->accel.cmd & 0x1000) + val = ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | + ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24); + s3_accel_start(8, 1, (val >> 24) & 0xff, 0, s3); + s3_accel_start(8, 1, (val >> 16) & 0xff, 0, s3); + s3_accel_start(8, 1, (val >> 8) & 0xff, 0, s3); + s3_accel_start(8, 1, val & 0xff, 0, s3); + } else if (s3->accel.cmd & 0x400) { + if (s3->accel.cmd & 0x1000) + val = ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | + ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24); + s3_accel_start(32, 1, val, 0, s3); + } else if ((s3->accel.cmd & 0x600) == 0x200) { + if (s3->accel.cmd & 0x1000) + val = ((val & 0xff00ff00) >> 8) | ((val & 0x00ff00ff) << 8); + s3_accel_start(16, 1, val, 0, s3); + s3_accel_start(16, 1, val >> 16, 0, s3); + } else { + if (s3->accel.cmd & 0x1000) + val = ((val & 0xff00ff00) >> 8) | ((val & 0x00ff00ff) << 8); + s3_accel_start(8, 1, val, 0, s3); + s3_accel_start(8, 1, val >> 16, 0, s3); + } + } else { + if (s3->accel.cmd & 0x400) + s3_accel_start(4, 1, 0xffffffff, val, s3); + else if ((s3->accel.cmd & 0x600) == 0x200) { + s3_accel_start(2, 1, 0xffffffff, val, s3); + s3_accel_start(2, 1, 0xffffffff, val >> 16, s3); + } else { + s3_accel_start(1, 1, 0xffffffff, val, s3); + s3_accel_start(1, 1, 0xffffffff, val >> 16, s3); + } + } + } + } } static void fifo_thread(void *param) { - s3_t *s3 = (s3_t *)param; + s3_t *s3 = (s3_t *)param; - while (1) { - thread_set_event(s3->fifo_not_full_event); - thread_wait_event(s3->wake_fifo_thread, -1); - thread_reset_event(s3->wake_fifo_thread); - s3->blitter_busy = 1; - while (!FIFO_EMPTY) { - uint64_t start_time = timer_read(); - uint64_t end_time; - fifo_entry_t *fifo = &s3->fifo[s3->fifo_read_idx & FIFO_MASK]; + while (1) { + thread_set_event(s3->fifo_not_full_event); + thread_wait_event(s3->wake_fifo_thread, -1); + thread_reset_event(s3->wake_fifo_thread); + s3->blitter_busy = 1; + while (!FIFO_EMPTY) { + uint64_t start_time = timer_read(); + uint64_t end_time; + fifo_entry_t *fifo = &s3->fifo[s3->fifo_read_idx & FIFO_MASK]; - switch (fifo->addr_type & FIFO_TYPE) { - case FIFO_WRITE_BYTE:s3_accel_write_fifo(s3, fifo->addr_type & FIFO_ADDR, fifo->val); - break; - case FIFO_WRITE_WORD:s3_accel_write_fifo_w(s3, fifo->addr_type & FIFO_ADDR, fifo->val); - break; - case FIFO_WRITE_DWORD:s3_accel_write_fifo_l(s3, fifo->addr_type & FIFO_ADDR, fifo->val); - break; - case FIFO_OUT_BYTE:s3_accel_out_fifo(s3, fifo->addr_type & FIFO_ADDR, fifo->val); - break; - case FIFO_OUT_WORD:s3_accel_out_fifo_w(s3, fifo->addr_type & FIFO_ADDR, fifo->val); - break; - case FIFO_OUT_DWORD:s3_accel_out_fifo_l(s3, fifo->addr_type & FIFO_ADDR, fifo->val); - break; - } + switch (fifo->addr_type & FIFO_TYPE) { + case FIFO_WRITE_BYTE: + s3_accel_write_fifo(s3, fifo->addr_type & FIFO_ADDR, fifo->val); + break; + case FIFO_WRITE_WORD: + s3_accel_write_fifo_w(s3, fifo->addr_type & FIFO_ADDR, fifo->val); + break; + case FIFO_WRITE_DWORD: + s3_accel_write_fifo_l(s3, fifo->addr_type & FIFO_ADDR, fifo->val); + break; + case FIFO_OUT_BYTE: + s3_accel_out_fifo(s3, fifo->addr_type & FIFO_ADDR, fifo->val); + break; + case FIFO_OUT_WORD: + s3_accel_out_fifo_w(s3, fifo->addr_type & FIFO_ADDR, fifo->val); + break; + case FIFO_OUT_DWORD: + s3_accel_out_fifo_l(s3, fifo->addr_type & FIFO_ADDR, fifo->val); + break; + } - s3->fifo_read_idx++; - fifo->addr_type = FIFO_INVALID; + s3->fifo_read_idx++; + fifo->addr_type = FIFO_INVALID; - if (FIFO_ENTRIES > 0xe000) - thread_set_event(s3->fifo_not_full_event); + if (FIFO_ENTRIES > 0xe000) + thread_set_event(s3->fifo_not_full_event); - end_time = timer_read(); - s3->blitter_time += end_time - start_time; - } - s3->blitter_busy = 0; - s3->subsys_stat |= INT_FIFO_EMP; - s3_update_irqs(s3); - } + end_time = timer_read(); + s3->blitter_time += end_time - start_time; + } + s3->blitter_busy = 0; + s3->subsys_stat |= INT_FIFO_EMP; + s3_update_irqs(s3); + } } static void s3_vblank_start(svga_t *svga) { - s3_t *s3 = (s3_t *)svga->p; + s3_t *s3 = (s3_t *)svga->p; - s3->subsys_stat |= INT_VSY; - s3_update_irqs(s3); + s3->subsys_stat |= INT_VSY; + s3_update_irqs(s3); } static void s3_queue(s3_t *s3, uint32_t addr, uint32_t val, uint32_t type) { - fifo_entry_t *fifo = &s3->fifo[s3->fifo_write_idx & FIFO_MASK]; + fifo_entry_t *fifo = &s3->fifo[s3->fifo_write_idx & FIFO_MASK]; - if (FIFO_FULL) { - thread_reset_event(s3->fifo_not_full_event); - if (FIFO_FULL) { - thread_wait_event(s3->fifo_not_full_event, -1); /*Wait for room in ringbuffer*/ - } - } + if (FIFO_FULL) { + thread_reset_event(s3->fifo_not_full_event); + if (FIFO_FULL) { + thread_wait_event(s3->fifo_not_full_event, -1); /*Wait for room in ringbuffer*/ + } + } - fifo->val = val; - fifo->addr_type = (addr & FIFO_ADDR) | type; + fifo->val = val; + fifo->addr_type = (addr & FIFO_ADDR) | type; - s3->fifo_write_idx++; + s3->fifo_write_idx++; - if (FIFO_ENTRIES > 0xe000 || FIFO_ENTRIES < 8) - wake_fifo_thread(s3); + if (FIFO_ENTRIES > 0xe000 || FIFO_ENTRIES < 8) + wake_fifo_thread(s3); } void s3_out(uint16_t addr, uint8_t val, void *p) { - s3_t *s3 = (s3_t *)p; - svga_t *svga = &s3->svga; - uint8_t old; + s3_t *s3 = (s3_t *)p; + svga_t *svga = &s3->svga; + uint8_t old; - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; -// pclog("S3 out %04X %02X %04x:%08x\n", addr, val, CS, pc); + // pclog("S3 out %04X %02X %04x:%08x\n", addr, val, CS, pc); - switch (addr) { - case 0x3c5: - if (svga->seqaddr >= 0x10 && svga->seqaddr < 0x20) { - svga->seqregs[svga->seqaddr] = val; - switch (svga->seqaddr) { - case 0x12: - case 0x13:svga_recalctimings(svga); - return; - } - } - if (svga->seqaddr == 4) /*Chain-4 - update banking*/ - { - if (val & 8) - svga->write_bank = svga->read_bank = s3->bank << 16; - else - svga->write_bank = svga->read_bank = s3->bank << 14; - } - break; + switch (addr) { + case 0x3c5: + if (svga->seqaddr >= 0x10 && svga->seqaddr < 0x20) { + svga->seqregs[svga->seqaddr] = val; + switch (svga->seqaddr) { + case 0x12: + case 0x13: + svga_recalctimings(svga); + return; + } + } + if (svga->seqaddr == 4) /*Chain-4 - update banking*/ + { + if (val & 8) + svga->write_bank = svga->read_bank = s3->bank << 16; + else + svga->write_bank = svga->read_bank = s3->bank << 14; + } + break; - case 0x3C6: - case 0x3C7: - case 0x3C8: - case 0x3C9: -// pclog("Write RAMDAC %04X %02X %04X:%04X\n", addr, val, CS, pc); - if (s3->chip == S3_TRIO32 || s3->chip == S3_TRIO64) - svga_out(addr, val, svga); - else { - if ((svga->crtc[0x55] & 1) || (svga->crtc[0x43] & 2)) - sdac_ramdac_out((addr & 3) | 4, val, &s3->ramdac, svga); - else - sdac_ramdac_out(addr & 3, val, &s3->ramdac, svga); - } - return; + case 0x3C6: + case 0x3C7: + case 0x3C8: + case 0x3C9: + // pclog("Write RAMDAC %04X %02X %04X:%04X\n", addr, val, CS, pc); + if (s3->chip == S3_TRIO32 || s3->chip == S3_TRIO64) + svga_out(addr, val, svga); + else { + if ((svga->crtc[0x55] & 1) || (svga->crtc[0x43] & 2)) + sdac_ramdac_out((addr & 3) | 4, val, &s3->ramdac, svga); + else + sdac_ramdac_out(addr & 3, val, &s3->ramdac, svga); + } + return; - case 0x3D4:svga->crtcreg = val & 0x7f; - return; - case 0x3D5: - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) - return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); - if (svga->crtcreg >= 0x20 && svga->crtcreg != 0x38 && svga->crtcreg != 0x39 && (svga->crtc[0x38] & 0xcc) != 0x48) { - if (!((svga->crtc[0x39] & 0xe0) == 0xa0 && svga->crtcreg >= 0x40 && svga->crtcreg <= 0x6d)) - return; - } - old = svga->crtc[svga->crtcreg]; - svga->crtc[svga->crtcreg] = val; - switch (svga->crtcreg) { - case 0x31:s3->ma_ext = (s3->ma_ext & 0x1c) | ((val & 0x30) >> 4); - svga->force_dword_mode = val & 0x08; - break; - case 0x32:svga->vram_display_mask = (val & 0x40) ? 0x3ffff : s3->vram_mask; - break; + case 0x3D4: + svga->crtcreg = val & 0x7f; + return; + case 0x3D5: + if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) + return; + if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) + val = (svga->crtc[7] & ~0x10) | (val & 0x10); + if (svga->crtcreg >= 0x20 && svga->crtcreg != 0x38 && svga->crtcreg != 0x39 && + (svga->crtc[0x38] & 0xcc) != 0x48) { + if (!((svga->crtc[0x39] & 0xe0) == 0xa0 && svga->crtcreg >= 0x40 && svga->crtcreg <= 0x6d)) + return; + } + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; + switch (svga->crtcreg) { + case 0x31: + s3->ma_ext = (s3->ma_ext & 0x1c) | ((val & 0x30) >> 4); + svga->force_dword_mode = val & 0x08; + break; + case 0x32: + svga->vram_display_mask = (val & 0x40) ? 0x3ffff : s3->vram_mask; + break; - case 0x50: - switch (svga->crtc[0x50] & 0xc1) { - case 0x00:s3->width = (svga->crtc[0x31] & 2) ? 2048 : 1024; - break; - case 0x01:s3->width = 1152; - break; - case 0x40:s3->width = 640; - break; - case 0x80:s3->width = 800; - break; - case 0x81:s3->width = 1600; - break; - case 0xc0:s3->width = 1280; - break; - } - s3->bpp = (svga->crtc[0x50] >> 4) & 3; - break; - case 0x69:s3->ma_ext = val & 0x1f; - break; + case 0x50: + switch (svga->crtc[0x50] & 0xc1) { + case 0x00: + s3->width = (svga->crtc[0x31] & 2) ? 2048 : 1024; + break; + case 0x01: + s3->width = 1152; + break; + case 0x40: + s3->width = 640; + break; + case 0x80: + s3->width = 800; + break; + case 0x81: + s3->width = 1600; + break; + case 0xc0: + s3->width = 1280; + break; + } + s3->bpp = (svga->crtc[0x50] >> 4) & 3; + break; + case 0x69: + s3->ma_ext = val & 0x1f; + break; - case 0x35:s3->bank = (s3->bank & 0x70) | (val & 0xf); -// pclog("CRTC write R35 %02X\n", val); - if (svga->chain4) - svga->write_bank = svga->read_bank = s3->bank << 16; - else - svga->write_bank = svga->read_bank = s3->bank << 14; - break; - case 0x51:s3->bank = (s3->bank & 0x4f) | ((val & 0xc) << 2); -// pclog("CRTC write R51 %02X\n", val); - if (svga->chain4) - svga->write_bank = svga->read_bank = s3->bank << 16; - else - svga->write_bank = svga->read_bank = s3->bank << 14; - s3->ma_ext = (s3->ma_ext & ~0xc) | ((val & 3) << 2); - break; - case 0x6a:s3->bank = val; -// pclog("CRTC write R6a %02X\n", val); - if (svga->chain4) - svga->write_bank = svga->read_bank = s3->bank << 16; - else - svga->write_bank = svga->read_bank = s3->bank << 14; - break; + case 0x35: + s3->bank = (s3->bank & 0x70) | (val & 0xf); + // pclog("CRTC write R35 %02X\n", val); + if (svga->chain4) + svga->write_bank = svga->read_bank = s3->bank << 16; + else + svga->write_bank = svga->read_bank = s3->bank << 14; + break; + case 0x51: + s3->bank = (s3->bank & 0x4f) | ((val & 0xc) << 2); + // pclog("CRTC write R51 %02X\n", val); + if (svga->chain4) + svga->write_bank = svga->read_bank = s3->bank << 16; + else + svga->write_bank = svga->read_bank = s3->bank << 14; + s3->ma_ext = (s3->ma_ext & ~0xc) | ((val & 3) << 2); + break; + case 0x6a: + s3->bank = val; + // pclog("CRTC write R6a %02X\n", val); + if (svga->chain4) + svga->write_bank = svga->read_bank = s3->bank << 16; + else + svga->write_bank = svga->read_bank = s3->bank << 14; + break; - case 0x3a: - if (val & 0x10) - svga->gdcreg[5] |= 0x40; /*Horrible cheat*/ - break; + case 0x3a: + if (val & 0x10) + svga->gdcreg[5] |= 0x40; /*Horrible cheat*/ + break; - case 0x45:svga->hwcursor.ena = val & 1; - break; - case 0x48:svga->hwcursor.x = ((svga->crtc[0x46] << 8) | svga->crtc[0x47]) & 0x7ff; - if (svga->bpp == 32) - svga->hwcursor.x >>= 1; - svga->hwcursor.y = ((svga->crtc[0x48] << 8) | svga->crtc[0x49]) & 0x7ff; - svga->hwcursor.xoff = svga->crtc[0x4e] & 63; - svga->hwcursor.yoff = svga->crtc[0x4f] & 63; - svga->hwcursor.addr = ((((svga->crtc[0x4c] << 8) | svga->crtc[0x4d]) & 0xfff) * 1024) + (svga->hwcursor.yoff * 16); - if ((s3->chip == S3_TRIO32 || s3->chip == S3_TRIO64) && svga->bpp == 32) - svga->hwcursor.x <<= 1; - break; + case 0x45: + svga->hwcursor.ena = val & 1; + break; + case 0x48: + svga->hwcursor.x = ((svga->crtc[0x46] << 8) | svga->crtc[0x47]) & 0x7ff; + if (svga->bpp == 32) + svga->hwcursor.x >>= 1; + svga->hwcursor.y = ((svga->crtc[0x48] << 8) | svga->crtc[0x49]) & 0x7ff; + svga->hwcursor.xoff = svga->crtc[0x4e] & 63; + svga->hwcursor.yoff = svga->crtc[0x4f] & 63; + svga->hwcursor.addr = + ((((svga->crtc[0x4c] << 8) | svga->crtc[0x4d]) & 0xfff) * 1024) + (svga->hwcursor.yoff * 16); + if ((s3->chip == S3_TRIO32 || s3->chip == S3_TRIO64) && svga->bpp == 32) + svga->hwcursor.x <<= 1; + break; - case 0x4a: - switch (s3->hwc_col_stack_pos) { - case 0:s3->hwc_fg_col = (s3->hwc_fg_col & 0xffff00) | val; - break; - case 1:s3->hwc_fg_col = (s3->hwc_fg_col & 0xff00ff) | (val << 8); - break; - case 2:s3->hwc_fg_col = (s3->hwc_fg_col & 0x00ffff) | (val << 16); - break; - } - s3->hwc_col_stack_pos = (s3->hwc_col_stack_pos + 1) % 3; - break; - case 0x4b: - switch (s3->hwc_col_stack_pos) { - case 0:s3->hwc_bg_col = (s3->hwc_bg_col & 0xffff00) | val; - break; - case 1:s3->hwc_bg_col = (s3->hwc_bg_col & 0xff00ff) | (val << 8); - break; - case 2:s3->hwc_bg_col = (s3->hwc_bg_col & 0x00ffff) | (val << 16); - break; - } - s3->hwc_col_stack_pos = (s3->hwc_col_stack_pos + 1) % 3; - break; + case 0x4a: + switch (s3->hwc_col_stack_pos) { + case 0: + s3->hwc_fg_col = (s3->hwc_fg_col & 0xffff00) | val; + break; + case 1: + s3->hwc_fg_col = (s3->hwc_fg_col & 0xff00ff) | (val << 8); + break; + case 2: + s3->hwc_fg_col = (s3->hwc_fg_col & 0x00ffff) | (val << 16); + break; + } + s3->hwc_col_stack_pos = (s3->hwc_col_stack_pos + 1) % 3; + break; + case 0x4b: + switch (s3->hwc_col_stack_pos) { + case 0: + s3->hwc_bg_col = (s3->hwc_bg_col & 0xffff00) | val; + break; + case 1: + s3->hwc_bg_col = (s3->hwc_bg_col & 0xff00ff) | (val << 8); + break; + case 2: + s3->hwc_bg_col = (s3->hwc_bg_col & 0x00ffff) | (val << 16); + break; + } + s3->hwc_col_stack_pos = (s3->hwc_col_stack_pos + 1) % 3; + break; - case 0x53: - case 0x58: - case 0x59: - case 0x5a:s3_updatemapping(s3); - break; + case 0x53: + case 0x58: + case 0x59: + case 0x5a: + s3_updatemapping(s3); + break; - case 0x67: - if (s3->chip == S3_TRIO32 || s3->chip == S3_TRIO64) { - switch (val >> 4) { - case 3:svga->bpp = 15; - break; - case 5:svga->bpp = 16; - break; - case 7:svga->bpp = 24; - break; - case 13:svga->bpp = 32; - break; - default:svga->bpp = 8; - break; - } - } - break; - //case 0x55: case 0x43: -// pclog("Write CRTC R%02X %02X\n", crtcreg, val); - } - if (old != val) { - if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - } - break; - } - svga_out(addr, val, svga); + case 0x67: + if (s3->chip == S3_TRIO32 || s3->chip == S3_TRIO64) { + switch (val >> 4) { + case 3: + svga->bpp = 15; + break; + case 5: + svga->bpp = 16; + break; + case 7: + svga->bpp = 24; + break; + case 13: + svga->bpp = 32; + break; + default: + svga->bpp = 8; + break; + } + } + break; + // case 0x55: case 0x43: + // pclog("Write CRTC R%02X %02X\n", crtcreg, val); + } + if (old != val) { + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } + } + break; + } + svga_out(addr, val, svga); } uint8_t s3_in(uint16_t addr, void *p) { - s3_t *s3 = (s3_t *)p; - svga_t *svga = &s3->svga; + s3_t *s3 = (s3_t *)p; + svga_t *svga = &s3->svga; - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; -// if (addr != 0x3da) pclog("S3 in %04X %08x:%02x\n", addr, CS, pc); - switch (addr) { - case 0x3c1: - if (svga->attraddr > 0x14) - return 0xff; - break; + // if (addr != 0x3da) pclog("S3 in %04X %08x:%02x\n", addr, CS, pc); + switch (addr) { + case 0x3c1: + if (svga->attraddr > 0x14) + return 0xff; + break; - case 0x3c5: - if (svga->seqaddr >= 0x10 && svga->seqaddr < 0x20) - return svga->seqregs[svga->seqaddr]; - break; + case 0x3c5: + if (svga->seqaddr >= 0x10 && svga->seqaddr < 0x20) + return svga->seqregs[svga->seqaddr]; + break; - case 0x3c6: - case 0x3c7: - case 0x3c8: - case 0x3c9: -// pclog("Read RAMDAC %04X %04X:%04X\n", addr, CS, pc); - if (s3->chip == S3_TRIO32 || s3->chip == S3_TRIO64) - return svga_in(addr, svga); - if ((svga->crtc[0x55] & 1) || (svga->crtc[0x43] & 2)) - return sdac_ramdac_in((addr & 3) | 4, &s3->ramdac, svga); - return sdac_ramdac_in(addr & 3, &s3->ramdac, svga); + case 0x3c6: + case 0x3c7: + case 0x3c8: + case 0x3c9: + // pclog("Read RAMDAC %04X %04X:%04X\n", addr, CS, pc); + if (s3->chip == S3_TRIO32 || s3->chip == S3_TRIO64) + return svga_in(addr, svga); + if ((svga->crtc[0x55] & 1) || (svga->crtc[0x43] & 2)) + return sdac_ramdac_in((addr & 3) | 4, &s3->ramdac, svga); + return sdac_ramdac_in(addr & 3, &s3->ramdac, svga); - case 0x3d4:return svga->crtcreg; - case 0x3d5: -// pclog("Read CRTC R%02X %02x %04X:%04X\n", svga->crtcreg, svga->crtc[svga->crtcreg], CS, pc); - switch (svga->crtcreg) { - case 0x2d:return 0x88; /*Extended chip ID*/ - case 0x2e:return s3->id_ext; /*New chip ID*/ - case 0x2f:return 0; /*Revision level*/ - case 0x30:return s3->id; /*Chip ID*/ - case 0x31:return (svga->crtc[0x31] & 0xcf) | ((s3->ma_ext & 3) << 4); - case 0x35:return (svga->crtc[0x35] & 0xf0) | (s3->bank & 0xf); - case 0x45:s3->hwc_col_stack_pos = 0; - break; - case 0x51:return (svga->crtc[0x51] & 0xf0) | ((s3->bank >> 2) & 0xc) | ((s3->ma_ext >> 2) & 3); - case 0x69:return s3->ma_ext; - case 0x6a:return s3->bank; - } - return svga->crtc[svga->crtcreg]; - } - return svga_in(addr, svga); + case 0x3d4: + return svga->crtcreg; + case 0x3d5: + // pclog("Read CRTC R%02X %02x %04X:%04X\n", svga->crtcreg, svga->crtc[svga->crtcreg], CS, pc); + switch (svga->crtcreg) { + case 0x2d: + return 0x88; /*Extended chip ID*/ + case 0x2e: + return s3->id_ext; /*New chip ID*/ + case 0x2f: + return 0; /*Revision level*/ + case 0x30: + return s3->id; /*Chip ID*/ + case 0x31: + return (svga->crtc[0x31] & 0xcf) | ((s3->ma_ext & 3) << 4); + case 0x35: + return (svga->crtc[0x35] & 0xf0) | (s3->bank & 0xf); + case 0x45: + s3->hwc_col_stack_pos = 0; + break; + case 0x51: + return (svga->crtc[0x51] & 0xf0) | ((s3->bank >> 2) & 0xc) | ((s3->ma_ext >> 2) & 3); + case 0x69: + return s3->ma_ext; + case 0x6a: + return s3->bank; + } + return svga->crtc[svga->crtcreg]; + } + return svga_in(addr, svga); } void s3_recalctimings(svga_t *svga) { - s3_t *s3 = (s3_t *)svga->p; - svga->hdisp = svga->hdisp_old; - int clk_sel = (svga->miscout >> 2) & 3; + s3_t *s3 = (s3_t *)svga->p; + svga->hdisp = svga->hdisp_old; + int clk_sel = (svga->miscout >> 2) & 3; - if (clk_sel == 3 && s3->chip == S3_VISION864) - clk_sel = svga->crtc[0x42] & 0xf; + if (clk_sel == 3 && s3->chip == S3_VISION864) + clk_sel = svga->crtc[0x42] & 0xf; -// pclog("%i %i\n", svga->hdisp, svga->hdisp_time); -// pclog("recalctimings\n"); - svga->ma_latch |= (s3->ma_ext << 16); -// pclog("SVGA_MA %08X\n", svga_ma); - if (svga->crtc[0x5d] & 0x01) - svga->htotal += 0x100; - if (svga->crtc[0x5d] & 0x02) { - svga->hdisp_time += 0x100; - svga->hdisp += 0x100 * ((svga->seqregs[1] & 8) ? 16 : 8); - } - if (svga->crtc[0x5e] & 0x01) - svga->vtotal += 0x400; - if (svga->crtc[0x5e] & 0x02) - svga->dispend += 0x400; - if (svga->crtc[0x5e] & 0x04) - svga->vblankstart += 0x400; - if (svga->crtc[0x5e] & 0x10) - svga->vsyncstart += 0x400; - if (svga->crtc[0x5e] & 0x40) - svga->split += 0x400; - if (svga->crtc[0x51] & 0x30) - svga->rowoffset += (svga->crtc[0x51] & 0x30) << 4; - else if (svga->crtc[0x43] & 0x04) - svga->rowoffset += 0x100; - if (!svga->rowoffset) - svga->rowoffset = 256; - svga->interlace = svga->crtc[0x42] & 0x20; - svga->clock = (cpuclock * (float)(1ull << 32)) / s3->getclock(clk_sel, s3->getclock_p); + // pclog("%i %i\n", svga->hdisp, svga->hdisp_time); + // pclog("recalctimings\n"); + svga->ma_latch |= (s3->ma_ext << 16); + // pclog("SVGA_MA %08X\n", svga_ma); + if (svga->crtc[0x5d] & 0x01) + svga->htotal += 0x100; + if (svga->crtc[0x5d] & 0x02) { + svga->hdisp_time += 0x100; + svga->hdisp += 0x100 * ((svga->seqregs[1] & 8) ? 16 : 8); + } + if (svga->crtc[0x5e] & 0x01) + svga->vtotal += 0x400; + if (svga->crtc[0x5e] & 0x02) + svga->dispend += 0x400; + if (svga->crtc[0x5e] & 0x04) + svga->vblankstart += 0x400; + if (svga->crtc[0x5e] & 0x10) + svga->vsyncstart += 0x400; + if (svga->crtc[0x5e] & 0x40) + svga->split += 0x400; + if (svga->crtc[0x51] & 0x30) + svga->rowoffset += (svga->crtc[0x51] & 0x30) << 4; + else if (svga->crtc[0x43] & 0x04) + svga->rowoffset += 0x100; + if (!svga->rowoffset) + svga->rowoffset = 256; + svga->interlace = svga->crtc[0x42] & 0x20; + svga->clock = (cpuclock * (float)(1ull << 32)) / s3->getclock(clk_sel, s3->getclock_p); - switch (svga->crtc[0x67] >> 4) { - case 3: - case 5: - case 7:svga->clock /= 2; - break; - } + switch (svga->crtc[0x67] >> 4) { + case 3: + case 5: + case 7: + svga->clock /= 2; + break; + } - svga->lowres = !((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)); - if ((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)) { - switch (svga->bpp) { - case 8:svga->render = svga_render_8bpp_highres; - break; - case 15:svga->render = svga_render_15bpp_highres; - svga->hdisp /= 2; - break; - case 16:svga->render = svga_render_16bpp_highres; - svga->hdisp /= 2; - break; - case 24:svga->render = svga_render_24bpp_highres; - svga->hdisp /= 3; - break; - case 32:svga->render = svga_render_32bpp_highres; - if (s3->chip != S3_TRIO32 && s3->chip != S3_TRIO64) - svga->hdisp /= 4; - break; - } - } + svga->lowres = !((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)); + if ((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)) { + switch (svga->bpp) { + case 8: + svga->render = svga_render_8bpp_highres; + break; + case 15: + svga->render = svga_render_15bpp_highres; + svga->hdisp /= 2; + break; + case 16: + svga->render = svga_render_16bpp_highres; + svga->hdisp /= 2; + break; + case 24: + svga->render = svga_render_24bpp_highres; + svga->hdisp /= 3; + break; + case 32: + svga->render = svga_render_32bpp_highres; + if (s3->chip != S3_TRIO32 && s3->chip != S3_TRIO64) + svga->hdisp /= 4; + break; + } + } } void s3_updatemapping(s3_t *s3) { - svga_t *svga = &s3->svga; + svga_t *svga = &s3->svga; -// video_write_a000_w = video_write_a000_l = NULL; + // video_write_a000_w = video_write_a000_l = NULL; - if (!(s3->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) { -// pclog("Update mapping - PCI disabled\n"); - mem_mapping_disable(&svga->mapping); - mem_mapping_disable(&s3->linear_mapping); - mem_mapping_disable(&s3->mmio_mapping); - return; - } + if (!(s3->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) { + // pclog("Update mapping - PCI disabled\n"); + mem_mapping_disable(&svga->mapping); + mem_mapping_disable(&s3->linear_mapping); + mem_mapping_disable(&s3->mmio_mapping); + return; + } -// pclog("Update mapping - bank %02X ", svga->gdcreg[6] & 0xc); - /*Banked framebuffer*/ - if (svga->crtc[0x31] & 0x08) /*Enhanced mode mappings*/ - { - /*Enhanced mapping forces 64kb at 0xa0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - svga->banked_mask = 0xffff; - } else - switch (svga->gdcreg[6] & 0xc) /*VGA mapping*/ - { - case 0x0: /*128k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); - svga->banked_mask = 0xffff; - break; - case 0x4: /*64k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - svga->banked_mask = 0xffff; - break; - case 0x8: /*32k at B0000*/ - mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); - svga->banked_mask = 0x7fff; - break; - case 0xC: /*32k at B8000*/ - mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); - svga->banked_mask = 0x7fff; - break; - } + // pclog("Update mapping - bank %02X ", svga->gdcreg[6] & 0xc); + /*Banked framebuffer*/ + if (svga->crtc[0x31] & 0x08) /*Enhanced mode mappings*/ + { + /*Enhanced mapping forces 64kb at 0xa0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + svga->banked_mask = 0xffff; + } else + switch (svga->gdcreg[6] & 0xc) /*VGA mapping*/ + { + case 0x0: /*128k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); + svga->banked_mask = 0xffff; + break; + case 0x4: /*64k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + svga->banked_mask = 0xffff; + break; + case 0x8: /*32k at B0000*/ + mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); + svga->banked_mask = 0x7fff; + break; + case 0xC: /*32k at B8000*/ + mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); + svga->banked_mask = 0x7fff; + break; + } -// pclog("Linear framebuffer %02X ", svga->crtc[0x58] & 0x10); - if (svga->crtc[0x58] & 0x10) /*Linear framebuffer*/ - { - mem_mapping_disable(&svga->mapping); + // pclog("Linear framebuffer %02X ", svga->crtc[0x58] & 0x10); + if (svga->crtc[0x58] & 0x10) /*Linear framebuffer*/ + { + mem_mapping_disable(&svga->mapping); - s3->linear_base = (svga->crtc[0x5a] << 16) | (svga->crtc[0x59] << 24); - switch (svga->crtc[0x58] & 3) { - case 0: /*64k*/ - s3->linear_size = 0x10000; - break; - case 1: /*1mb*/ - s3->linear_size = 0x100000; - break; - case 2: /*2mb*/ - s3->linear_size = 0x200000; - break; - case 3: /*8mb*/ - s3->linear_size = 0x800000; - break; - } - s3->linear_base &= ~(s3->linear_size - 1); -// pclog("%08X %08X %02X %02X %02X\n", linear_base, linear_size, crtc[0x58], crtc[0x59], crtc[0x5a]); -// pclog("Linear framebuffer at %08X size %08X\n", s3->linear_base, s3->linear_size); - if (s3->linear_base == 0xa0000) { - mem_mapping_disable(&s3->linear_mapping); - if (!(svga->crtc[0x53] & 0x10)) { - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - svga->banked_mask = 0xffff; - } -// mem_mapping_set_addr(&s3->linear_mapping, 0xa0000, 0x10000); - } else - mem_mapping_set_addr(&s3->linear_mapping, s3->linear_base, s3->linear_size); - } else - mem_mapping_disable(&s3->linear_mapping); + s3->linear_base = (svga->crtc[0x5a] << 16) | (svga->crtc[0x59] << 24); + switch (svga->crtc[0x58] & 3) { + case 0: /*64k*/ + s3->linear_size = 0x10000; + break; + case 1: /*1mb*/ + s3->linear_size = 0x100000; + break; + case 2: /*2mb*/ + s3->linear_size = 0x200000; + break; + case 3: /*8mb*/ + s3->linear_size = 0x800000; + break; + } + s3->linear_base &= ~(s3->linear_size - 1); + // pclog("%08X %08X %02X %02X %02X\n", linear_base, linear_size, crtc[0x58], crtc[0x59], + // crtc[0x5a]); pclog("Linear framebuffer at %08X size %08X\n", s3->linear_base, s3->linear_size); + if (s3->linear_base == 0xa0000) { + mem_mapping_disable(&s3->linear_mapping); + if (!(svga->crtc[0x53] & 0x10)) { + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + svga->banked_mask = 0xffff; + } + // mem_mapping_set_addr(&s3->linear_mapping, 0xa0000, 0x10000); + } else + mem_mapping_set_addr(&s3->linear_mapping, s3->linear_base, s3->linear_size); + } else + mem_mapping_disable(&s3->linear_mapping); -// pclog("Memory mapped IO %02X\n", svga->crtc[0x53] & 0x10); - if (svga->crtc[0x53] & 0x10) /*Memory mapped IO*/ - { - mem_mapping_disable(&svga->mapping); - mem_mapping_enable(&s3->mmio_mapping); - } else - mem_mapping_disable(&s3->mmio_mapping); + // pclog("Memory mapped IO %02X\n", svga->crtc[0x53] & 0x10); + if (svga->crtc[0x53] & 0x10) /*Memory mapped IO*/ + { + mem_mapping_disable(&svga->mapping); + mem_mapping_enable(&s3->mmio_mapping); + } else + mem_mapping_disable(&s3->mmio_mapping); } static float s3_trio64_getclock(int clock, void *p) { - s3_t *s3 = (s3_t *)p; - svga_t *svga = &s3->svga; - float t; - int m, n1, n2; -// pclog("Trio64_getclock %i %02X %02X\n", clock, svga->seqregs[0x13], svga->seqregs[0x12]); - if (clock == 0) - return 25175000.0; - if (clock == 1) - return 28322000.0; - m = svga->seqregs[0x13] + 2; - n1 = (svga->seqregs[0x12] & 0x1f) + 2; - n2 = ((svga->seqregs[0x12] >> 5) & 0x07); - t = (14318184.0 * ((float)m / (float)n1)) / (float)(1 << n2); -// pclog("TRIO64 clock %i %i %i %f %f %i\n", m, n1, n2, t, 14318184.0 * ((float)m / (float)n1), 1 << n2); - return t; + s3_t *s3 = (s3_t *)p; + svga_t *svga = &s3->svga; + float t; + int m, n1, n2; + // pclog("Trio64_getclock %i %02X %02X\n", clock, svga->seqregs[0x13], svga->seqregs[0x12]); + if (clock == 0) + return 25175000.0; + if (clock == 1) + return 28322000.0; + m = svga->seqregs[0x13] + 2; + n1 = (svga->seqregs[0x12] & 0x1f) + 2; + n2 = ((svga->seqregs[0x12] >> 5) & 0x07); + t = (14318184.0 * ((float)m / (float)n1)) / (float)(1 << n2); + // pclog("TRIO64 clock %i %i %i %f %f %i\n", m, n1, n2, t, 14318184.0 * ((float)m / (float)n1), 1 << n2); + return t; } void s3_accel_out(uint16_t port, uint8_t val, void *p) { - s3_t *s3 = (s3_t *)p; -// pclog("Accel out %04X %02X\n", port, val); + s3_t *s3 = (s3_t *)p; + // pclog("Accel out %04X %02X\n", port, val); - if (port >= 0x8000) { - s3_queue(s3, port, val, FIFO_OUT_BYTE); - } else - switch (port) { - case 0x42e8:s3->subsys_stat &= ~val; - s3_update_irqs(s3); - break; - case 0x42e9:s3->subsys_cntl = val; - s3_update_irqs(s3); - break; - case 0x46e8:s3->accel.setup_md = val; - break; - case 0x4ae8:s3->accel.advfunc_cntl = val; - break; - } + if (port >= 0x8000) { + s3_queue(s3, port, val, FIFO_OUT_BYTE); + } else + switch (port) { + case 0x42e8: + s3->subsys_stat &= ~val; + s3_update_irqs(s3); + break; + case 0x42e9: + s3->subsys_cntl = val; + s3_update_irqs(s3); + break; + case 0x46e8: + s3->accel.setup_md = val; + break; + case 0x4ae8: + s3->accel.advfunc_cntl = val; + break; + } } void s3_accel_out_w(uint16_t port, uint16_t val, void *p) { - s3_t *s3 = (s3_t *)p; -// pclog("Accel out w %04X %04X\n", port, val); - s3_queue(s3, port, val, FIFO_OUT_WORD); + s3_t *s3 = (s3_t *)p; + // pclog("Accel out w %04X %04X\n", port, val); + s3_queue(s3, port, val, FIFO_OUT_WORD); } void s3_accel_out_l(uint16_t port, uint32_t val, void *p) { - s3_t *s3 = (s3_t *)p; -// pclog("Accel out l %04X %08X\n", port, val); - s3_queue(s3, port, val, FIFO_OUT_DWORD); + s3_t *s3 = (s3_t *)p; + // pclog("Accel out l %04X %08X\n", port, val); + s3_queue(s3, port, val, FIFO_OUT_DWORD); } uint8_t s3_accel_in(uint16_t port, void *p) { - s3_t *s3 = (s3_t *)p; - int temp; -// pclog("Accel in %04X\n", port); - switch (port) { - case 0x42e8:return s3->subsys_stat; - case 0x42e9:return s3->subsys_cntl; + s3_t *s3 = (s3_t *)p; + int temp; + // pclog("Accel in %04X\n", port); + switch (port) { + case 0x42e8: + return s3->subsys_stat; + case 0x42e9: + return s3->subsys_cntl; - case 0x82e8:s3_wait_fifo_idle(s3); - return s3->accel.cur_y & 0xff; - case 0x82e9:s3_wait_fifo_idle(s3); - return s3->accel.cur_y >> 8; + case 0x82e8: + s3_wait_fifo_idle(s3); + return s3->accel.cur_y & 0xff; + case 0x82e9: + s3_wait_fifo_idle(s3); + return s3->accel.cur_y >> 8; - case 0x86e8:s3_wait_fifo_idle(s3); - return s3->accel.cur_x & 0xff; - case 0x86e9:s3_wait_fifo_idle(s3); - return s3->accel.cur_x >> 8; + case 0x86e8: + s3_wait_fifo_idle(s3); + return s3->accel.cur_x & 0xff; + case 0x86e9: + s3_wait_fifo_idle(s3); + return s3->accel.cur_x >> 8; - case 0x8ae8:s3_wait_fifo_idle(s3); - return s3->accel.desty_axstp & 0xff; - case 0x8ae9:s3_wait_fifo_idle(s3); - return s3->accel.desty_axstp >> 8; + case 0x8ae8: + s3_wait_fifo_idle(s3); + return s3->accel.desty_axstp & 0xff; + case 0x8ae9: + s3_wait_fifo_idle(s3); + return s3->accel.desty_axstp >> 8; - case 0x8ee8:s3_wait_fifo_idle(s3); - return s3->accel.destx_distp & 0xff; - case 0x8ee9:s3_wait_fifo_idle(s3); - return s3->accel.destx_distp >> 8; + case 0x8ee8: + s3_wait_fifo_idle(s3); + return s3->accel.destx_distp & 0xff; + case 0x8ee9: + s3_wait_fifo_idle(s3); + return s3->accel.destx_distp >> 8; - case 0x92e8:s3_wait_fifo_idle(s3); - return s3->accel.err_term & 0xff; - case 0x92e9:s3_wait_fifo_idle(s3); - return s3->accel.err_term >> 8; + case 0x92e8: + s3_wait_fifo_idle(s3); + return s3->accel.err_term & 0xff; + case 0x92e9: + s3_wait_fifo_idle(s3); + return s3->accel.err_term >> 8; - case 0x96e8:s3_wait_fifo_idle(s3); - return s3->accel.maj_axis_pcnt & 0xff; - case 0x96e9:s3_wait_fifo_idle(s3); - return s3->accel.maj_axis_pcnt >> 8; + case 0x96e8: + s3_wait_fifo_idle(s3); + return s3->accel.maj_axis_pcnt & 0xff; + case 0x96e9: + s3_wait_fifo_idle(s3); + return s3->accel.maj_axis_pcnt >> 8; - case 0x9ae8: - if (!s3->blitter_busy) - wake_fifo_thread(s3); - if (FIFO_FULL) - return 0xff; /*FIFO full*/ - return 0; /*FIFO empty*/ - case 0x9ae9: - if (!s3->blitter_busy) - wake_fifo_thread(s3); - temp = 0; - if (!FIFO_EMPTY || s3->force_busy) - temp |= 0x02; /*Hardware busy*/ - else - temp |= 0x04; /*FIFO empty*/ - s3->force_busy = 0; - if (FIFO_FULL) - temp |= 0xf8; /*FIFO full*/ - return temp; + case 0x9ae8: + if (!s3->blitter_busy) + wake_fifo_thread(s3); + if (FIFO_FULL) + return 0xff; /*FIFO full*/ + return 0; /*FIFO empty*/ + case 0x9ae9: + if (!s3->blitter_busy) + wake_fifo_thread(s3); + temp = 0; + if (!FIFO_EMPTY || s3->force_busy) + temp |= 0x02; /*Hardware busy*/ + else + temp |= 0x04; /*FIFO empty*/ + s3->force_busy = 0; + if (FIFO_FULL) + temp |= 0xf8; /*FIFO full*/ + return temp; - case 0xa2e8:s3_wait_fifo_idle(s3); - return s3->accel.bkgd_color & 0xff; - case 0xa2e9:s3_wait_fifo_idle(s3); - return s3->accel.bkgd_color >> 8; - case 0xa2ea:s3_wait_fifo_idle(s3); - return s3->accel.bkgd_color >> 16; - case 0xa2eb:s3_wait_fifo_idle(s3); - return s3->accel.bkgd_color >> 24; + case 0xa2e8: + s3_wait_fifo_idle(s3); + return s3->accel.bkgd_color & 0xff; + case 0xa2e9: + s3_wait_fifo_idle(s3); + return s3->accel.bkgd_color >> 8; + case 0xa2ea: + s3_wait_fifo_idle(s3); + return s3->accel.bkgd_color >> 16; + case 0xa2eb: + s3_wait_fifo_idle(s3); + return s3->accel.bkgd_color >> 24; - case 0xa6e8:s3_wait_fifo_idle(s3); - return s3->accel.frgd_color & 0xff; - case 0xa6e9:s3_wait_fifo_idle(s3); - return s3->accel.frgd_color >> 8; - case 0xa6ea:s3_wait_fifo_idle(s3); - return s3->accel.frgd_color >> 16; - case 0xa6eb:s3_wait_fifo_idle(s3); - return s3->accel.frgd_color >> 24; + case 0xa6e8: + s3_wait_fifo_idle(s3); + return s3->accel.frgd_color & 0xff; + case 0xa6e9: + s3_wait_fifo_idle(s3); + return s3->accel.frgd_color >> 8; + case 0xa6ea: + s3_wait_fifo_idle(s3); + return s3->accel.frgd_color >> 16; + case 0xa6eb: + s3_wait_fifo_idle(s3); + return s3->accel.frgd_color >> 24; - case 0xaae8:s3_wait_fifo_idle(s3); - return s3->accel.wrt_mask & 0xff; - case 0xaae9:s3_wait_fifo_idle(s3); - return s3->accel.wrt_mask >> 8; - case 0xaaea:s3_wait_fifo_idle(s3); - return s3->accel.wrt_mask >> 16; - case 0xaaeb:s3_wait_fifo_idle(s3); - return s3->accel.wrt_mask >> 24; + case 0xaae8: + s3_wait_fifo_idle(s3); + return s3->accel.wrt_mask & 0xff; + case 0xaae9: + s3_wait_fifo_idle(s3); + return s3->accel.wrt_mask >> 8; + case 0xaaea: + s3_wait_fifo_idle(s3); + return s3->accel.wrt_mask >> 16; + case 0xaaeb: + s3_wait_fifo_idle(s3); + return s3->accel.wrt_mask >> 24; - case 0xaee8:s3_wait_fifo_idle(s3); - return s3->accel.rd_mask & 0xff; - case 0xaee9:s3_wait_fifo_idle(s3); - return s3->accel.rd_mask >> 8; - case 0xaeea:s3_wait_fifo_idle(s3); - return s3->accel.rd_mask >> 16; - case 0xaeeb:s3_wait_fifo_idle(s3); - return s3->accel.rd_mask >> 24; + case 0xaee8: + s3_wait_fifo_idle(s3); + return s3->accel.rd_mask & 0xff; + case 0xaee9: + s3_wait_fifo_idle(s3); + return s3->accel.rd_mask >> 8; + case 0xaeea: + s3_wait_fifo_idle(s3); + return s3->accel.rd_mask >> 16; + case 0xaeeb: + s3_wait_fifo_idle(s3); + return s3->accel.rd_mask >> 24; - case 0xb2e8:s3_wait_fifo_idle(s3); - return s3->accel.color_cmp & 0xff; - case 0xb2e9:s3_wait_fifo_idle(s3); - return s3->accel.color_cmp >> 8; - case 0xb2ea:s3_wait_fifo_idle(s3); - return s3->accel.color_cmp >> 16; - case 0xb2eb:s3_wait_fifo_idle(s3); - return s3->accel.color_cmp >> 24; + case 0xb2e8: + s3_wait_fifo_idle(s3); + return s3->accel.color_cmp & 0xff; + case 0xb2e9: + s3_wait_fifo_idle(s3); + return s3->accel.color_cmp >> 8; + case 0xb2ea: + s3_wait_fifo_idle(s3); + return s3->accel.color_cmp >> 16; + case 0xb2eb: + s3_wait_fifo_idle(s3); + return s3->accel.color_cmp >> 24; - case 0xb6e8:s3_wait_fifo_idle(s3); - return s3->accel.bkgd_mix; + case 0xb6e8: + s3_wait_fifo_idle(s3); + return s3->accel.bkgd_mix; - case 0xbae8:s3_wait_fifo_idle(s3); - return s3->accel.frgd_mix; + case 0xbae8: + s3_wait_fifo_idle(s3); + return s3->accel.frgd_mix; - case 0xbee8:s3_wait_fifo_idle(s3); - temp = s3->accel.multifunc[0xf] & 0xf; - switch (temp) { - case 0x0:return s3->accel.multifunc[0x0] & 0xff; - case 0x1:return s3->accel.multifunc[0x1] & 0xff; - case 0x2:return s3->accel.multifunc[0x2] & 0xff; - case 0x3:return s3->accel.multifunc[0x3] & 0xff; - case 0x4:return s3->accel.multifunc[0x4] & 0xff; - case 0x5:return s3->accel.multifunc[0xa] & 0xff; - case 0x6:return s3->accel.multifunc[0xe] & 0xff; - case 0x7:return s3->accel.cmd & 0xff; - case 0x8:return s3->accel.subsys_cntl & 0xff; - case 0x9:return s3->accel.setup_md & 0xff; - case 0xa:return s3->accel.multifunc[0xd] & 0xff; - } - return 0xff; - case 0xbee9:s3_wait_fifo_idle(s3); - temp = s3->accel.multifunc[0xf] & 0xf; - s3->accel.multifunc[0xf]++; - switch (temp) { - case 0x0:return s3->accel.multifunc[0x0] >> 8; - case 0x1:return s3->accel.multifunc[0x1] >> 8; - case 0x2:return s3->accel.multifunc[0x2] >> 8; - case 0x3:return s3->accel.multifunc[0x3] >> 8; - case 0x4:return s3->accel.multifunc[0x4] >> 8; - case 0x5:return s3->accel.multifunc[0xa] >> 8; - case 0x6:return s3->accel.multifunc[0xe] >> 8; - case 0x7:return s3->accel.cmd >> 8; - case 0x8:return (s3->accel.subsys_cntl >> 8) & ~0xe000; - case 0x9:return (s3->accel.setup_md >> 8) & ~0xf000; - case 0xa:return s3->accel.multifunc[0xd] >> 8; - } - return 0xff; + case 0xbee8: + s3_wait_fifo_idle(s3); + temp = s3->accel.multifunc[0xf] & 0xf; + switch (temp) { + case 0x0: + return s3->accel.multifunc[0x0] & 0xff; + case 0x1: + return s3->accel.multifunc[0x1] & 0xff; + case 0x2: + return s3->accel.multifunc[0x2] & 0xff; + case 0x3: + return s3->accel.multifunc[0x3] & 0xff; + case 0x4: + return s3->accel.multifunc[0x4] & 0xff; + case 0x5: + return s3->accel.multifunc[0xa] & 0xff; + case 0x6: + return s3->accel.multifunc[0xe] & 0xff; + case 0x7: + return s3->accel.cmd & 0xff; + case 0x8: + return s3->accel.subsys_cntl & 0xff; + case 0x9: + return s3->accel.setup_md & 0xff; + case 0xa: + return s3->accel.multifunc[0xd] & 0xff; + } + return 0xff; + case 0xbee9: + s3_wait_fifo_idle(s3); + temp = s3->accel.multifunc[0xf] & 0xf; + s3->accel.multifunc[0xf]++; + switch (temp) { + case 0x0: + return s3->accel.multifunc[0x0] >> 8; + case 0x1: + return s3->accel.multifunc[0x1] >> 8; + case 0x2: + return s3->accel.multifunc[0x2] >> 8; + case 0x3: + return s3->accel.multifunc[0x3] >> 8; + case 0x4: + return s3->accel.multifunc[0x4] >> 8; + case 0x5: + return s3->accel.multifunc[0xa] >> 8; + case 0x6: + return s3->accel.multifunc[0xe] >> 8; + case 0x7: + return s3->accel.cmd >> 8; + case 0x8: + return (s3->accel.subsys_cntl >> 8) & ~0xe000; + case 0x9: + return (s3->accel.setup_md >> 8) & ~0xf000; + case 0xa: + return s3->accel.multifunc[0xd] >> 8; + } + return 0xff; - case 0xe2e8: - case 0xe2e9: - case 0xe2ea: - case 0xe2eb: /*PIX_TRANS*/ - break; - } - return 0; + case 0xe2e8: + case 0xe2e9: + case 0xe2ea: + case 0xe2eb: /*PIX_TRANS*/ + break; + } + return 0; } void s3_accel_write(uint32_t addr, uint8_t val, void *p) { - s3_t *s3 = (s3_t *)p; -// pclog("s3_accel_write %08x %02x\n", addr, val); - s3_queue(s3, addr & 0xffff, val, FIFO_WRITE_BYTE); + s3_t *s3 = (s3_t *)p; + // pclog("s3_accel_write %08x %02x\n", addr, val); + s3_queue(s3, addr & 0xffff, val, FIFO_WRITE_BYTE); } void s3_accel_write_w(uint32_t addr, uint16_t val, void *p) { - s3_t *s3 = (s3_t *)p; -// pclog("s3_accel_write_w %08x %04x\n", addr, val); - s3_queue(s3, addr & 0xffff, val, FIFO_WRITE_WORD); + s3_t *s3 = (s3_t *)p; + // pclog("s3_accel_write_w %08x %04x\n", addr, val); + s3_queue(s3, addr & 0xffff, val, FIFO_WRITE_WORD); } void s3_accel_write_l(uint32_t addr, uint32_t val, void *p) { - s3_t *s3 = (s3_t *)p; -// pclog("s3_accel_write_l %08x %08x\n", addr, val); - s3_queue(s3, addr & 0xffff, val, FIFO_WRITE_DWORD); + s3_t *s3 = (s3_t *)p; + // pclog("s3_accel_write_l %08x %08x\n", addr, val); + s3_queue(s3, addr & 0xffff, val, FIFO_WRITE_DWORD); } uint8_t s3_accel_read(uint32_t addr, void *p) { - if (addr & 0x8000) - return s3_accel_in(addr & 0xffff, p); - return 0; + if (addr & 0x8000) + return s3_accel_in(addr & 0xffff, p); + return 0; } static void polygon_setup(s3_t *s3) { - if (s3->accel.point_1_updated) { - int start_x = s3->accel.poly_cx; - int start_y = s3->accel.poly_cy; - int end_x = s3->accel.destx_distp << 20; - int end_y = s3->accel.desty_axstp; + if (s3->accel.point_1_updated) { + int start_x = s3->accel.poly_cx; + int start_y = s3->accel.poly_cy; + int end_x = s3->accel.destx_distp << 20; + int end_y = s3->accel.desty_axstp; - if (end_y - start_y) - s3->accel.poly_dx1 = (end_x - start_x) / (end_y - start_y); - else - s3->accel.poly_dx1 = 0; + if (end_y - start_y) + s3->accel.poly_dx1 = (end_x - start_x) / (end_y - start_y); + else + s3->accel.poly_dx1 = 0; - s3->accel.point_1_updated = 0; + s3->accel.point_1_updated = 0; - if (end_y == s3->accel.poly_cy) { - s3->accel.poly_cx = end_x; - s3->accel.poly_x = end_x >> 20; - } - } - if (s3->accel.point_2_updated) { - int start_x = s3->accel.poly_cx2; - int start_y = s3->accel.poly_cy2; - int end_x = s3->accel.x2 << 20; - int end_y = s3->accel.desty_axstp2; + if (end_y == s3->accel.poly_cy) { + s3->accel.poly_cx = end_x; + s3->accel.poly_x = end_x >> 20; + } + } + if (s3->accel.point_2_updated) { + int start_x = s3->accel.poly_cx2; + int start_y = s3->accel.poly_cy2; + int end_x = s3->accel.x2 << 20; + int end_y = s3->accel.desty_axstp2; - if (end_y - start_y) - s3->accel.poly_dx2 = (end_x - start_x) / (end_y - start_y); - else - s3->accel.poly_dx2 = 0; + if (end_y - start_y) + s3->accel.poly_dx2 = (end_x - start_x) / (end_y - start_y); + else + s3->accel.poly_dx2 = 0; - s3->accel.point_2_updated = 0; + s3->accel.point_2_updated = 0; - if (end_y == s3->accel.poly_cy) - s3->accel.poly_cx2 = end_x; - } + if (end_y == s3->accel.poly_cy) + s3->accel.poly_cx2 = end_x; + } } /*Remap address for chain-4/doubleword style layout*/ static inline uint32_t dword_remap(uint32_t in_addr) { - return ((in_addr << 2) & 0x3fff0) | - ((in_addr >> 14) & 0xc) | - (in_addr & ~0x3fffc); + return ((in_addr << 2) & 0x3fff0) | ((in_addr >> 14) & 0xc) | (in_addr & ~0x3fffc); } static inline uint32_t dword_remap_w(uint32_t in_addr) { - return ((in_addr << 2) & 0x1fff8) | - ((in_addr >> 14) & 0x6) | - (in_addr & ~0x1fffe); + return ((in_addr << 2) & 0x1fff8) | ((in_addr >> 14) & 0x6) | (in_addr & ~0x1fffe); } static inline uint32_t dword_remap_l(uint32_t in_addr) { - return ((in_addr << 2) & 0xfffc) | - ((in_addr >> 14) & 0x3) | - (in_addr & ~0xffff); + return ((in_addr << 2) & 0xfffc) | ((in_addr >> 14) & 0x3) | (in_addr & ~0xffff); } -#define READ_SRC(addr, dat) if (s3->bpp == 0) dat = svga->vram[ dword_remap(addr) & s3->vram_mask]; \ - else if (s3->bpp == 1) dat = vram_w[dword_remap_w(addr) & (s3->vram_mask >> 1)]; \ - else dat = vram_l[dword_remap_l(addr) & (s3->vram_mask >> 2)]; \ - if (vram_mask) \ - dat = ((dat & rd_mask) == rd_mask); +#define READ_SRC(addr, dat) \ + if (s3->bpp == 0) \ + dat = svga->vram[dword_remap(addr) & s3->vram_mask]; \ + else if (s3->bpp == 1) \ + dat = vram_w[dword_remap_w(addr) & (s3->vram_mask >> 1)]; \ + else \ + dat = vram_l[dword_remap_l(addr) & (s3->vram_mask >> 2)]; \ + if (vram_mask) \ + dat = ((dat & rd_mask) == rd_mask); -#define READ_DST(addr, dat) if (s3->bpp == 0) dat = svga->vram[ dword_remap(addr) & s3->vram_mask]; \ - else if (s3->bpp == 1) dat = vram_w[dword_remap_w(addr) & (s3->vram_mask >> 1)]; \ - else dat = vram_l[dword_remap_l(addr) & (s3->vram_mask >> 2)]; +#define READ_DST(addr, dat) \ + if (s3->bpp == 0) \ + dat = svga->vram[dword_remap(addr) & s3->vram_mask]; \ + else if (s3->bpp == 1) \ + dat = vram_w[dword_remap_w(addr) & (s3->vram_mask >> 1)]; \ + else \ + dat = vram_l[dword_remap_l(addr) & (s3->vram_mask >> 2)]; -#define MIX { \ - uint32_t old_dest_dat = dest_dat; \ - switch ((mix_dat & mix_mask) ? (s3->accel.frgd_mix & 0xf) : (s3->accel.bkgd_mix & 0xf)) \ - { \ - case 0x0: dest_dat = ~dest_dat; break; \ - case 0x1: dest_dat = 0; break; \ - case 0x2: dest_dat = ~0; break; \ - case 0x3: dest_dat = dest_dat; break; \ - case 0x4: dest_dat = ~src_dat; break; \ - case 0x5: dest_dat = src_dat ^ dest_dat; break; \ - case 0x6: dest_dat = ~(src_dat ^ dest_dat); break; \ - case 0x7: dest_dat = src_dat; break; \ - case 0x8: dest_dat = ~(src_dat & dest_dat); break; \ - case 0x9: dest_dat = ~src_dat | dest_dat; break; \ - case 0xa: dest_dat = src_dat | ~dest_dat; break; \ - case 0xb: dest_dat = src_dat | dest_dat; break; \ - case 0xc: dest_dat = src_dat & dest_dat; break; \ - case 0xd: dest_dat = src_dat & ~dest_dat; break; \ - case 0xe: dest_dat = ~src_dat & dest_dat; break; \ - case 0xf: dest_dat = ~(src_dat | dest_dat); break; \ - } \ - dest_dat = (dest_dat & s3->accel.wrt_mask) | (old_dest_dat & ~s3->accel.wrt_mask); \ - } +#define MIX \ + { \ + uint32_t old_dest_dat = dest_dat; \ + switch ((mix_dat & mix_mask) ? (s3->accel.frgd_mix & 0xf) : (s3->accel.bkgd_mix & 0xf)) { \ + case 0x0: \ + dest_dat = ~dest_dat; \ + break; \ + case 0x1: \ + dest_dat = 0; \ + break; \ + case 0x2: \ + dest_dat = ~0; \ + break; \ + case 0x3: \ + dest_dat = dest_dat; \ + break; \ + case 0x4: \ + dest_dat = ~src_dat; \ + break; \ + case 0x5: \ + dest_dat = src_dat ^ dest_dat; \ + break; \ + case 0x6: \ + dest_dat = ~(src_dat ^ dest_dat); \ + break; \ + case 0x7: \ + dest_dat = src_dat; \ + break; \ + case 0x8: \ + dest_dat = ~(src_dat & dest_dat); \ + break; \ + case 0x9: \ + dest_dat = ~src_dat | dest_dat; \ + break; \ + case 0xa: \ + dest_dat = src_dat | ~dest_dat; \ + break; \ + case 0xb: \ + dest_dat = src_dat | dest_dat; \ + break; \ + case 0xc: \ + dest_dat = src_dat & dest_dat; \ + break; \ + case 0xd: \ + dest_dat = src_dat & ~dest_dat; \ + break; \ + case 0xe: \ + dest_dat = ~src_dat & dest_dat; \ + break; \ + case 0xf: \ + dest_dat = ~(src_dat | dest_dat); \ + break; \ + } \ + dest_dat = (dest_dat & s3->accel.wrt_mask) | (old_dest_dat & ~s3->accel.wrt_mask); \ + } -#define WRITE(addr) if (s3->bpp == 0) \ - { \ - svga->vram[dword_remap(addr) & s3->vram_mask] = dest_dat; \ - svga->changedvram[(dword_remap(addr) & s3->vram_mask) >> 12] = changeframecount; \ - } \ - else if (s3->bpp == 1) \ - { \ - vram_w[dword_remap_w(addr) & (s3->vram_mask >> 1)] = dest_dat; \ - svga->changedvram[(dword_remap_w(addr) & (s3->vram_mask >> 1)) >> 11] = changeframecount; \ - } \ - else \ - { \ - vram_l[dword_remap_l(addr) & (s3->vram_mask >> 2)] = dest_dat; \ - svga->changedvram[(dword_remap_l(addr) & (s3->vram_mask >> 2)) >> 10] = changeframecount; \ - } +#define WRITE(addr) \ + if (s3->bpp == 0) { \ + svga->vram[dword_remap(addr) & s3->vram_mask] = dest_dat; \ + svga->changedvram[(dword_remap(addr) & s3->vram_mask) >> 12] = changeframecount; \ + } else if (s3->bpp == 1) { \ + vram_w[dword_remap_w(addr) & (s3->vram_mask >> 1)] = dest_dat; \ + svga->changedvram[(dword_remap_w(addr) & (s3->vram_mask >> 1)) >> 11] = changeframecount; \ + } else { \ + vram_l[dword_remap_l(addr) & (s3->vram_mask >> 2)] = dest_dat; \ + svga->changedvram[(dword_remap_l(addr) & (s3->vram_mask >> 2)) >> 10] = changeframecount; \ + } void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_t *s3) { - svga_t *svga = &s3->svga; - uint32_t src_dat, dest_dat; - int frgd_mix, bkgd_mix; - int clip_t = s3->accel.multifunc[1] & 0xfff; - int clip_l = s3->accel.multifunc[2] & 0xfff; - int clip_b = s3->accel.multifunc[3] & 0xfff; - int clip_r = s3->accel.multifunc[4] & 0xfff; - int vram_mask = (s3->accel.multifunc[0xa] & 0xc0) == 0xc0; - uint32_t mix_mask = 0; - uint16_t *vram_w = (uint16_t *)svga->vram; - uint32_t *vram_l = (uint32_t *)svga->vram; - uint32_t compare = s3->accel.color_cmp; - int compare_mode = (s3->accel.multifunc[0xe] >> 7) & 3; - uint32_t rd_mask = s3->accel.rd_mask; - int cmd = s3->accel.cmd >> 13; - uint32_t srcbase, dstbase; - - if ((s3->chip == S3_TRIO64) && (s3->accel.cmd & (1 << 11))) - cmd |= 8; - - if ((s3->accel.multifunc[13] >> 4) & 7) - srcbase = 0x100000 * ((s3->accel.multifunc[13] >> 4) & 3); - else - srcbase = 0x100000 * ((s3->accel.multifunc[14] >> 2) & 3); - if ((s3->accel.multifunc[13] >> 0) & 7) - dstbase = 0x100000 * ((s3->accel.multifunc[13] >> 0) & 3); - else - dstbase = 0x100000 * ((s3->accel.multifunc[14] >> 0) & 3); - if (s3->bpp == 1) { - srcbase >>= 1; - dstbase >>= 1; - } else if (s3->bpp == 3) { - srcbase >>= 2; - dstbase >>= 2; - } - - s3->force_busy = 1; -//return; -// if (!cpu_input) pclog("Start S3 command %i %i, %i %i, %i (clip %i, %i to %i, %i %i)\n", s3->accel.cmd >> 13, s3->accel.cur_x, s3->accel.cur_y, s3->accel.maj_axis_pcnt & 0xfff, s3->accel.multifunc[0] & 0xfff, clip_l, clip_t, clip_r, clip_b, s3->accel.multifunc[0xe] & 0x20); -// else pclog(" S3 command %i, %i, %08x %08x\n", s3->accel.cmd >> 13, count, mix_dat, cpu_dat); - - if (!cpu_input) - s3->accel.dat_count = 0; - if (cpu_input && (s3->accel.multifunc[0xa] & 0xc0) != 0x80) { - if (s3->bpp == 3 && count == 2) { - if (s3->accel.dat_count) { - cpu_dat = ((cpu_dat & 0xffff) << 16) | s3->accel.dat_buf; - count = 4; - s3->accel.dat_count = 0; - } else { - s3->accel.dat_buf = cpu_dat & 0xffff; - s3->accel.dat_count = 1; - } - } - if (s3->bpp == 1) - count >>= 1; - if (s3->bpp == 3) - count >>= 2; - } - - if (s3->bpp == 0) - rd_mask &= 0xff; - else if (s3->bpp == 1) - rd_mask &= 0xffff; - - switch (s3->accel.cmd & 0x600) { - case 0x000:mix_mask = 0x80; - break; - case 0x200:mix_mask = 0x8000; - break; - case 0x400:mix_mask = 0x80000000; - break; - case 0x600:mix_mask = (s3->chip == S3_TRIO32) ? 0x80 : 0x80000000; - break; - } - - if (s3->bpp == 0) - compare &= 0xff; - if (s3->bpp == 1) - compare &= 0xffff; - switch (cmd) { - case 1: /*Draw line*/ - if (!cpu_input) /*!cpu_input is trigger to start operation*/ - { - s3->accel.cx = s3->accel.cur_x; - if (s3->accel.cur_x & 0x1000) - s3->accel.cx |= ~0xfff; - s3->accel.cy = s3->accel.cur_y; - if (s3->accel.cur_y & 0x1000) - s3->accel.cy |= ~0xfff; - - s3->accel.sy = s3->accel.maj_axis_pcnt; - } - if ((s3->accel.cmd & 0x100) && !cpu_input) - return; /*Wait for data from CPU*/ - - frgd_mix = (s3->accel.frgd_mix >> 5) & 3; - bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; - - if (s3->accel.cmd & 8) /*Radial*/ - { - while (count-- && s3->accel.sy >= 0) { - if ((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && - (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b) { - switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { - case 0:src_dat = s3->accel.bkgd_color; - break; - case 1:src_dat = s3->accel.frgd_color; - break; - case 2:src_dat = cpu_dat; - break; - case 3:src_dat = 0; - break; - } - - if ((compare_mode == 2 && src_dat != compare) || - (compare_mode == 3 && src_dat == compare) || - compare_mode < 2) { - READ_DST((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); - - MIX - - WRITE((s3->accel.cy * s3->width) + s3->accel.cx); - } - } - - mix_dat <<= 1; - mix_dat |= 1; - if (s3->bpp == 0) - cpu_dat >>= 8; - else - cpu_dat >>= 16; - if (!s3->accel.sy) - break; - - switch (s3->accel.cmd & 0xe0) { - case 0x00:s3->accel.cx++; - break; - case 0x20:s3->accel.cx++; - s3->accel.cy--; - break; - case 0x40:s3->accel.cy--; - break; - case 0x60:s3->accel.cx--; - s3->accel.cy--; - break; - case 0x80:s3->accel.cx--; - break; - case 0xa0:s3->accel.cx--; - s3->accel.cy++; - break; - case 0xc0:s3->accel.cy++; - break; - case 0xe0:s3->accel.cx++; - s3->accel.cy++; - break; - } - s3->accel.sy--; - } - s3->accel.cur_x = s3->accel.cx; - s3->accel.cur_y = s3->accel.cy; - } else /*Bresenham*/ - { - while (count-- && s3->accel.sy >= 0) { - if ((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && - (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b) { - switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { - case 0:src_dat = s3->accel.bkgd_color; - break; - case 1:src_dat = s3->accel.frgd_color; - break; - case 2:src_dat = cpu_dat; - break; - case 3:src_dat = 0; - break; - } - - if ((compare_mode == 2 && src_dat != compare) || - (compare_mode == 3 && src_dat == compare) || - compare_mode < 2) { - READ_DST((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); - -// pclog("Line : %04i, %04i (%06X) - %02X (%02X %04X %05X) %02X (%02X %02X) ", s3->accel.cx, s3->accel.cy, s3->accel.dest + s3->accel.cx, src_dat, vram[s3->accel.src + s3->accel.cx], mix_dat & mix_mask, s3->accel.src + s3->accel.cx, dest_dat, s3->accel.frgd_color, s3->accel.bkgd_color); - - MIX - -// pclog("%02X\n", dest_dat); - - WRITE((s3->accel.cy * s3->width) + s3->accel.cx); - } - } - - mix_dat <<= 1; - mix_dat |= 1; - if (s3->bpp == 0) - cpu_dat >>= 8; - else - cpu_dat >>= 16; - -// pclog("%i, %i - %i %i %i %i\n", s3->accel.cx, s3->accel.cy, s3->accel.err_term, s3->accel.maj_axis_pcnt, s3->accel.desty_axstp, s3->accel.destx_distp); - - if (!s3->accel.sy) - break; - - if (s3->accel.err_term >= s3->accel.maj_axis_pcnt) { - s3->accel.err_term += s3->accel.destx_distp; - /*Step minor axis*/ - switch (s3->accel.cmd & 0xe0) { - case 0x00:s3->accel.cy--; - break; - case 0x20:s3->accel.cy--; - break; - case 0x40:s3->accel.cx--; - break; - case 0x60:s3->accel.cx++; - break; - case 0x80:s3->accel.cy++; - break; - case 0xa0:s3->accel.cy++; - break; - case 0xc0:s3->accel.cx--; - break; - case 0xe0:s3->accel.cx++; - break; - } - } else - s3->accel.err_term += s3->accel.desty_axstp; - - /*Step major axis*/ - switch (s3->accel.cmd & 0xe0) { - case 0x00:s3->accel.cx--; - break; - case 0x20:s3->accel.cx++; - break; - case 0x40:s3->accel.cy--; - break; - case 0x60:s3->accel.cy--; - break; - case 0x80:s3->accel.cx--; - break; - case 0xa0:s3->accel.cx++; - break; - case 0xc0:s3->accel.cy++; - break; - case 0xe0:s3->accel.cy++; - break; - } - s3->accel.sy--; - } - s3->accel.cur_x = s3->accel.cx; - s3->accel.cur_y = s3->accel.cy; - } - break; - - case 2: /*Rectangle fill*/ - if (!cpu_input) /*!cpu_input is trigger to start operation*/ - { - s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; - s3->accel.sy = s3->accel.multifunc[0] & 0xfff; - s3->accel.cx = s3->accel.cur_x; - if (s3->accel.cur_x & 0x1000) - s3->accel.cx |= ~0xfff; - s3->accel.cy = s3->accel.cur_y; - if (s3->accel.cur_y & 0x1000) - s3->accel.cy |= ~0xfff; - - s3->accel.dest = dstbase + s3->accel.cy * s3->width; - -// pclog("Dest %08X (%i, %i) %04X %04X\n", s3->accel.dest, s3->accel.cx, s3->accel.cy, s3->accel.cur_x, s3->accel.cur_x & 0x1000); - } - if ((s3->accel.cmd & 0x100) && !cpu_input) - return; /*Wait for data from CPU*/ -// if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && !cpu_input) /*Mix data from CPU*/ -// return; - - frgd_mix = (s3->accel.frgd_mix >> 5) & 3; - bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; - - while (count-- && s3->accel.sy >= 0) { - if ((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && - (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b) { - switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { - case 0:src_dat = s3->accel.bkgd_color; - break; - case 1:src_dat = s3->accel.frgd_color; - break; - case 2:src_dat = cpu_dat; - break; - case 3:src_dat = 0; - break; - } - - if ((compare_mode == 2 && src_dat != compare) || - (compare_mode == 3 && src_dat == compare) || - compare_mode < 2) { - READ_DST(s3->accel.dest + s3->accel.cx, dest_dat); - - -// if (CS != 0xc000) pclog("Write %05X %02X %02X %04X (%02X %02X) ", s3->accel.dest + s3->accel.cx, src_dat, dest_dat, mix_dat, s3->accel.frgd_mix, s3->accel.bkgd_mix); - - MIX - -// if (CS != 0xc000) pclog("%02X\n", dest_dat); - - WRITE(s3->accel.dest + s3->accel.cx); - } - } - - mix_dat <<= 1; - mix_dat |= 1; - if (s3->bpp == 0) - cpu_dat >>= 8; - else - cpu_dat >>= 16; - - if (s3->accel.cmd & 0x20) - s3->accel.cx++; - else - s3->accel.cx--; - s3->accel.sx--; - if (s3->accel.sx < 0) { - if (s3->accel.cmd & 0x20) - s3->accel.cx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; - else - s3->accel.cx += (s3->accel.maj_axis_pcnt & 0xfff) + 1; -// s3->accel.dest -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; - s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; - -// s3->accel.dest += s3_width; - if (s3->accel.cmd & 0x80) - s3->accel.cy++; - else - s3->accel.cy--; - - s3->accel.dest = dstbase + s3->accel.cy * s3->width; - s3->accel.sy--; - - if (cpu_input/* && (s3->accel.multifunc[0xa] & 0xc0) == 0x80*/) - return; - if (s3->accel.sy < 0) { - s3->accel.cur_x = s3->accel.cx; - s3->accel.cur_y = s3->accel.cy; - return; - } - } - } - break; - - case 6: /*BitBlt*/ - if (!cpu_input) /*!cpu_input is trigger to start operation*/ - { - s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; - s3->accel.sy = s3->accel.multifunc[0] & 0xfff; - - s3->accel.dx = s3->accel.destx_distp & 0xfff; - if (s3->accel.destx_distp & 0x1000) - s3->accel.dx |= ~0xfff; - s3->accel.dy = s3->accel.desty_axstp & 0xfff; - if (s3->accel.desty_axstp & 0x1000) - s3->accel.dy |= ~0xfff; - - s3->accel.cx = s3->accel.cur_x & 0xfff; - if (s3->accel.cur_x & 0x1000) - s3->accel.cx |= ~0xfff; - s3->accel.cy = s3->accel.cur_y & 0xfff; - if (s3->accel.cur_y & 0x1000) - s3->accel.cy |= ~0xfff; - - s3->accel.src = srcbase + s3->accel.cy * s3->width; - s3->accel.dest = dstbase + s3->accel.dy * s3->width; - -// pclog("Source %08X Dest %08X (%i, %i) - (%i, %i)\n", s3->accel.src, s3->accel.dest, s3->accel.cx, s3->accel.cy, s3->accel.dx, s3->accel.dy); - } - if ((s3->accel.cmd & 0x100) && !cpu_input) - return; /*Wait for data from CPU*/ -// if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && !cpu_input) /*Mix data from CPU*/ -// return; - - if (s3->accel.sy < 0) - return; - - frgd_mix = (s3->accel.frgd_mix >> 5) & 3; - bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; - - if (!cpu_input && frgd_mix == 3 && !vram_mask && !compare_mode && - (s3->accel.cmd & 0xa0) == 0xa0 && (s3->accel.frgd_mix & 0xf) == 7) { - while (1) { - if ((s3->accel.dx & 0xfff) >= clip_l && (s3->accel.dx & 0xfff) <= clip_r && - (s3->accel.dy & 0xfff) >= clip_t && (s3->accel.dy & 0xfff) <= clip_b) { - READ_SRC(s3->accel.src + s3->accel.cx, src_dat); - READ_DST(s3->accel.dest + s3->accel.dx, dest_dat); - - dest_dat = (src_dat & s3->accel.wrt_mask) | (dest_dat & ~s3->accel.wrt_mask); - - WRITE(s3->accel.dest + s3->accel.dx); - } - - s3->accel.cx++; - s3->accel.dx++; - s3->accel.sx--; - if (s3->accel.sx < 0) { - s3->accel.cx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; - s3->accel.dx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; - s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; - - s3->accel.cy++; - s3->accel.dy++; - - s3->accel.src = srcbase + s3->accel.cy * s3->width; - s3->accel.dest = dstbase + s3->accel.dy * s3->width; - - s3->accel.sy--; - - if (s3->accel.sy < 0) - return; - } - } - } else { - while (count-- && s3->accel.sy >= 0) { - if ((s3->accel.dx & 0xfff) >= clip_l && (s3->accel.dx & 0xfff) <= clip_r && - (s3->accel.dy & 0xfff) >= clip_t && (s3->accel.dy & 0xfff) <= clip_b) { - if (vram_mask) { - READ_SRC(s3->accel.src + s3->accel.cx, mix_dat) - - mix_dat = mix_dat ? mix_mask : 0; - } - switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { - case 0:src_dat = s3->accel.bkgd_color; - break; - case 1:src_dat = s3->accel.frgd_color; - break; - case 2:src_dat = cpu_dat; - break; - case 3:READ_SRC(s3->accel.src + s3->accel.cx, src_dat); - break; - } - - if ((compare_mode == 2 && src_dat != compare) || - (compare_mode == 3 && src_dat == compare) || - compare_mode < 2) { - READ_DST(s3->accel.dest + s3->accel.dx, dest_dat); - -// pclog("BitBlt : %04i, %04i (%06X) - %02X (%02X %04X %05X) %02X ", s3->accel.dx, s3->accel.dy, s3->accel.dest + s3->accel.dx, src_dat, vram[s3->accel.src + s3->accel.cx], mix_dat, s3->accel.src + s3->accel.cx, dest_dat); - - MIX - -// pclog("%02X\n", dest_dat); - - WRITE(s3->accel.dest + s3->accel.dx); - } - } - - mix_dat <<= 1; - mix_dat |= 1; - if (s3->bpp == 0) - cpu_dat >>= 8; - else - cpu_dat >>= 16; - - if (s3->accel.cmd & 0x20) { - s3->accel.cx++; - s3->accel.dx++; - } else { - s3->accel.cx--; - s3->accel.dx--; - } - s3->accel.sx--; - if (s3->accel.sx < 0) { - if (s3->accel.cmd & 0x20) { - s3->accel.cx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; - s3->accel.dx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; - } else { - s3->accel.cx += (s3->accel.maj_axis_pcnt & 0xfff) + 1; - s3->accel.dx += (s3->accel.maj_axis_pcnt & 0xfff) + 1; - } - s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; - - if (s3->accel.cmd & 0x80) { - s3->accel.cy++; - s3->accel.dy++; - } else { - s3->accel.cy--; - s3->accel.dy--; - } - - s3->accel.src = srcbase + s3->accel.cy * s3->width; - s3->accel.dest = dstbase + s3->accel.dy * s3->width; - - s3->accel.sy--; - - if (cpu_input/* && (s3->accel.multifunc[0xa] & 0xc0) == 0x80*/) - return; - if (s3->accel.sy < 0) - return; - } - } - } - break; - - case 7: /*Pattern fill - BitBlt but with source limited to 8x8*/ - if (!cpu_input) /*!cpu_input is trigger to start operation*/ - { - s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; - s3->accel.sy = s3->accel.multifunc[0] & 0xfff; - - s3->accel.dx = s3->accel.destx_distp & 0xfff; - if (s3->accel.destx_distp & 0x1000) - s3->accel.dx |= ~0xfff; - s3->accel.dy = s3->accel.desty_axstp & 0xfff; - if (s3->accel.desty_axstp & 0x1000) - s3->accel.dy |= ~0xfff; - - s3->accel.cx = s3->accel.cur_x & 0xfff; - if (s3->accel.cur_x & 0x1000) - s3->accel.cx |= ~0xfff; - s3->accel.cy = s3->accel.cur_y & 0xfff; - if (s3->accel.cur_y & 0x1000) - s3->accel.cy |= ~0xfff; - - /*Align source with destination*/ -// s3->accel.cx = (s3->accel.cx & ~7) | (s3->accel.dx & 7); -// s3->accel.cy = (s3->accel.cy & ~7) | (s3->accel.dy & 7); - - s3->accel.pattern = (s3->accel.cy * s3->width) + s3->accel.cx; - s3->accel.dest = dstbase + s3->accel.dy * s3->width; - - s3->accel.cx = s3->accel.dx & 7; - s3->accel.cy = s3->accel.dy & 7; - - s3->accel.src = srcbase + s3->accel.pattern + (s3->accel.cy * s3->width); - -// pclog("Source %08X Dest %08X (%i, %i) - (%i, %i)\n", s3->accel.src, s3->accel.dest, s3->accel.cx, s3->accel.cy, s3->accel.dx, s3->accel.dy); -// dumpregs(); -// exit(-1); - } - if ((s3->accel.cmd & 0x100) && !cpu_input) - return; /*Wait for data from CPU*/ -// if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && !cpu_input) /*Mix data from CPU*/ -// return; - - frgd_mix = (s3->accel.frgd_mix >> 5) & 3; - bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; - - while (count-- && s3->accel.sy >= 0) { - if ((s3->accel.dx & 0xfff) >= clip_l && (s3->accel.dx & 0xfff) <= clip_r && - (s3->accel.dy & 0xfff) >= clip_t && (s3->accel.dy & 0xfff) <= clip_b) { - if (vram_mask) { - READ_SRC(s3->accel.src + s3->accel.cx, mix_dat) - mix_dat = mix_dat ? mix_mask : 0; - } - switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { - case 0:src_dat = s3->accel.bkgd_color; - break; - case 1:src_dat = s3->accel.frgd_color; - break; - case 2:src_dat = cpu_dat; - break; - case 3:READ_SRC(s3->accel.src + s3->accel.cx, src_dat); - break; - } - - if ((compare_mode == 2 && src_dat != compare) || - (compare_mode == 3 && src_dat == compare) || - compare_mode < 2) { - READ_DST(s3->accel.dest + s3->accel.dx, dest_dat); - -// pclog("Pattern fill : %04i, %04i (%06X) - %02X (%02X %04X %05X) %02X ", s3->accel.dx, s3->accel.dy, s3->accel.dest + s3->accel.dx, src_dat, vram[s3->accel.src + s3->accel.cx], mix_dat, s3->accel.src + s3->accel.cx, dest_dat); - - MIX - -// pclog("%02X\n", dest_dat); - - WRITE(s3->accel.dest + s3->accel.dx); - } - } - - mix_dat <<= 1; - mix_dat |= 1; - if (s3->bpp == 0) - cpu_dat >>= 8; - else - cpu_dat >>= 16; - - if (s3->accel.cmd & 0x20) { - s3->accel.cx = ((s3->accel.cx + 1) & 7) | (s3->accel.cx & ~7); - s3->accel.dx++; - } else { - s3->accel.cx = ((s3->accel.cx - 1) & 7) | (s3->accel.cx & ~7); - s3->accel.dx--; - } - s3->accel.sx--; - if (s3->accel.sx < 0) { - if (s3->accel.cmd & 0x20) { - s3->accel.cx = ((s3->accel.cx - ((s3->accel.maj_axis_pcnt & 0xfff) + 1)) & 7) | (s3->accel.cx & ~7); - s3->accel.dx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; - } else { - s3->accel.cx = ((s3->accel.cx + ((s3->accel.maj_axis_pcnt & 0xfff) + 1)) & 7) | (s3->accel.cx & ~7); - s3->accel.dx += (s3->accel.maj_axis_pcnt & 0xfff) + 1; - } - s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; - - if (s3->accel.cmd & 0x80) { - s3->accel.cy = ((s3->accel.cy + 1) & 7) | (s3->accel.cy & ~7); - s3->accel.dy++; - } else { - s3->accel.cy = ((s3->accel.cy - 1) & 7) | (s3->accel.cy & ~7); - s3->accel.dy--; - } - - s3->accel.src = srcbase + s3->accel.pattern + (s3->accel.cy * s3->width); - s3->accel.dest = dstbase + s3->accel.dy * s3->width; - - s3->accel.sy--; - - if (cpu_input/* && (s3->accel.multifunc[0xa] & 0xc0) == 0x80*/) - return; - if (s3->accel.sy < 0) - return; - } - } - break; - - case 3: /*Polygon Fill Solid (Trio64 only)*/ - { - int end_y1, end_y2; - - if (s3->chip != S3_TRIO64) - break; - - polygon_setup(s3); - - if ((s3->accel.cmd & 0x100) && !cpu_input) - return; /*Wait for data from CPU*/ - - end_y1 = s3->accel.desty_axstp; - end_y2 = s3->accel.desty_axstp2; - - frgd_mix = (s3->accel.frgd_mix >> 5) & 3; - - while ((s3->accel.poly_cy < end_y1) && (s3->accel.poly_cy2 < end_y2)) { - int y = s3->accel.poly_cy; - int x_count = ABS((s3->accel.poly_cx2 >> 20) - s3->accel.poly_x) + 1; - - s3->accel.dest = dstbase + y * s3->width; - - while (x_count-- && count--) { - if ((s3->accel.poly_x & 0xfff) >= clip_l && (s3->accel.poly_x & 0xfff) <= clip_r && - (s3->accel.poly_cy & 0xfff) >= clip_t && (s3->accel.poly_cy & 0xfff) <= clip_b) { - switch (frgd_mix) { - case 0:src_dat = s3->accel.bkgd_color; - break; - case 1:src_dat = s3->accel.frgd_color; - break; - case 2:src_dat = cpu_dat; - break; - case 3:src_dat = 0; /*Nor supported?*/ break; - } - - if ((compare_mode == 2 && src_dat != compare) || - (compare_mode == 3 && src_dat == compare) || - compare_mode < 2) { - READ_DST(s3->accel.dest + s3->accel.poly_x, dest_dat); - - MIX - - WRITE(s3->accel.dest + s3->accel.poly_x); - } - } - if (s3->bpp == 0) - cpu_dat >>= 8; - else - cpu_dat >>= 16; - - if (s3->accel.poly_x < (s3->accel.poly_cx2 >> 20)) - s3->accel.poly_x++; - else - s3->accel.poly_x--; - } - - s3->accel.poly_cx += s3->accel.poly_dx1; - s3->accel.poly_cx2 += s3->accel.poly_dx2; - s3->accel.poly_x = s3->accel.poly_cx >> 20; - - s3->accel.poly_cy++; - s3->accel.poly_cy2++; - - if (!count) - break; - } - - s3->accel.cur_x = s3->accel.poly_cx & 0xfff; - s3->accel.cur_y = s3->accel.poly_cy & 0xfff; - s3->accel.cur_x2 = s3->accel.poly_cx2 & 0xfff; - s3->accel.cur_y2 = s3->accel.poly_cy & 0xfff; - } - break; - - case 11: /*Polygon Fill Pattern (Trio64 only)*/ - { - int end_y1, end_y2; - - if (s3->chip != S3_TRIO64) - break; - - polygon_setup(s3); - - if ((s3->accel.cmd & 0x100) && !cpu_input) - return; /*Wait for data from CPU*/ - - end_y1 = s3->accel.desty_axstp; - end_y2 = s3->accel.desty_axstp2; - - frgd_mix = (s3->accel.frgd_mix >> 5) & 3; - bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; - - while ((s3->accel.poly_cy < end_y1) && (s3->accel.poly_cy2 < end_y2)) { - int y = s3->accel.poly_cy; - int x_count = ABS((s3->accel.poly_cx2 >> 20) - s3->accel.poly_x) + 1; - - s3->accel.src = srcbase + s3->accel.pattern + ((y & 7) * s3->width); - s3->accel.dest = dstbase + y * s3->width; - - while (x_count-- && count--) { - int pat_x = s3->accel.poly_x & 7; - - if ((s3->accel.poly_x & 0xfff) >= clip_l && (s3->accel.poly_x & 0xfff) <= clip_r && - (s3->accel.poly_cy & 0xfff) >= clip_t && (s3->accel.poly_cy & 0xfff) <= clip_b) { - if (vram_mask) { - READ_SRC(s3->accel.src + pat_x, mix_dat) - mix_dat = mix_dat ? mix_mask : 0; - } - switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { - case 0:src_dat = s3->accel.bkgd_color; - break; - case 1:src_dat = s3->accel.frgd_color; - break; - case 2:src_dat = cpu_dat; - break; - case 3:READ_SRC(s3->accel.src + pat_x, src_dat); - break; - } - - if ((compare_mode == 2 && src_dat != compare) || - (compare_mode == 3 && src_dat == compare) || - compare_mode < 2) { - READ_DST(s3->accel.dest + s3->accel.poly_x, dest_dat); - - MIX - - WRITE(s3->accel.dest + s3->accel.poly_x); - } - } - if (s3->bpp == 0) - cpu_dat >>= 8; - else - cpu_dat >>= 16; - - mix_dat <<= 1; - mix_dat |= 1; - - if (s3->accel.poly_x < (s3->accel.poly_cx2 >> 20)) - s3->accel.poly_x++; - else - s3->accel.poly_x--; - } - - s3->accel.poly_cx += s3->accel.poly_dx1; - s3->accel.poly_cx2 += s3->accel.poly_dx2; - s3->accel.poly_x = s3->accel.poly_cx >> 20; - - s3->accel.poly_cy++; - s3->accel.poly_cy2++; - - if (!count) - break; - } - - s3->accel.cur_x = s3->accel.poly_cx & 0xfff; - s3->accel.cur_y = s3->accel.poly_cy & 0xfff; - s3->accel.cur_x2 = s3->accel.poly_cx2 & 0xfff; - s3->accel.cur_y2 = s3->accel.poly_cy & 0xfff; - } - break; - } + svga_t *svga = &s3->svga; + uint32_t src_dat, dest_dat; + int frgd_mix, bkgd_mix; + int clip_t = s3->accel.multifunc[1] & 0xfff; + int clip_l = s3->accel.multifunc[2] & 0xfff; + int clip_b = s3->accel.multifunc[3] & 0xfff; + int clip_r = s3->accel.multifunc[4] & 0xfff; + int vram_mask = (s3->accel.multifunc[0xa] & 0xc0) == 0xc0; + uint32_t mix_mask = 0; + uint16_t *vram_w = (uint16_t *)svga->vram; + uint32_t *vram_l = (uint32_t *)svga->vram; + uint32_t compare = s3->accel.color_cmp; + int compare_mode = (s3->accel.multifunc[0xe] >> 7) & 3; + uint32_t rd_mask = s3->accel.rd_mask; + int cmd = s3->accel.cmd >> 13; + uint32_t srcbase, dstbase; + + if ((s3->chip == S3_TRIO64) && (s3->accel.cmd & (1 << 11))) + cmd |= 8; + + if ((s3->accel.multifunc[13] >> 4) & 7) + srcbase = 0x100000 * ((s3->accel.multifunc[13] >> 4) & 3); + else + srcbase = 0x100000 * ((s3->accel.multifunc[14] >> 2) & 3); + if ((s3->accel.multifunc[13] >> 0) & 7) + dstbase = 0x100000 * ((s3->accel.multifunc[13] >> 0) & 3); + else + dstbase = 0x100000 * ((s3->accel.multifunc[14] >> 0) & 3); + if (s3->bpp == 1) { + srcbase >>= 1; + dstbase >>= 1; + } else if (s3->bpp == 3) { + srcbase >>= 2; + dstbase >>= 2; + } + + s3->force_busy = 1; + // return; + // if (!cpu_input) pclog("Start S3 command %i %i, %i %i, %i (clip %i, %i to %i, %i %i)\n", s3->accel.cmd >> 13, + // s3->accel.cur_x, s3->accel.cur_y, s3->accel.maj_axis_pcnt & 0xfff, s3->accel.multifunc[0] & 0xfff, clip_l, + // clip_t, clip_r, clip_b, s3->accel.multifunc[0xe] & 0x20); else pclog(" S3 command %i, %i, %08x + // %08x\n", s3->accel.cmd >> 13, count, mix_dat, cpu_dat); + + if (!cpu_input) + s3->accel.dat_count = 0; + if (cpu_input && (s3->accel.multifunc[0xa] & 0xc0) != 0x80) { + if (s3->bpp == 3 && count == 2) { + if (s3->accel.dat_count) { + cpu_dat = ((cpu_dat & 0xffff) << 16) | s3->accel.dat_buf; + count = 4; + s3->accel.dat_count = 0; + } else { + s3->accel.dat_buf = cpu_dat & 0xffff; + s3->accel.dat_count = 1; + } + } + if (s3->bpp == 1) + count >>= 1; + if (s3->bpp == 3) + count >>= 2; + } + + if (s3->bpp == 0) + rd_mask &= 0xff; + else if (s3->bpp == 1) + rd_mask &= 0xffff; + + switch (s3->accel.cmd & 0x600) { + case 0x000: + mix_mask = 0x80; + break; + case 0x200: + mix_mask = 0x8000; + break; + case 0x400: + mix_mask = 0x80000000; + break; + case 0x600: + mix_mask = (s3->chip == S3_TRIO32) ? 0x80 : 0x80000000; + break; + } + + if (s3->bpp == 0) + compare &= 0xff; + if (s3->bpp == 1) + compare &= 0xffff; + switch (cmd) { + case 1: /*Draw line*/ + if (!cpu_input) /*!cpu_input is trigger to start operation*/ + { + s3->accel.cx = s3->accel.cur_x; + if (s3->accel.cur_x & 0x1000) + s3->accel.cx |= ~0xfff; + s3->accel.cy = s3->accel.cur_y; + if (s3->accel.cur_y & 0x1000) + s3->accel.cy |= ~0xfff; + + s3->accel.sy = s3->accel.maj_axis_pcnt; + } + if ((s3->accel.cmd & 0x100) && !cpu_input) + return; /*Wait for data from CPU*/ + + frgd_mix = (s3->accel.frgd_mix >> 5) & 3; + bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; + + if (s3->accel.cmd & 8) /*Radial*/ + { + while (count-- && s3->accel.sy >= 0) { + if ((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && + (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b) { + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = s3->accel.bkgd_color; + break; + case 1: + src_dat = s3->accel.frgd_color; + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + src_dat = 0; + break; + } + + if ((compare_mode == 2 && src_dat != compare) || + (compare_mode == 3 && src_dat == compare) || compare_mode < 2) { + READ_DST((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); + + MIX + + WRITE((s3->accel.cy * s3->width) + s3->accel.cx); + } + } + + mix_dat <<= 1; + mix_dat |= 1; + if (s3->bpp == 0) + cpu_dat >>= 8; + else + cpu_dat >>= 16; + if (!s3->accel.sy) + break; + + switch (s3->accel.cmd & 0xe0) { + case 0x00: + s3->accel.cx++; + break; + case 0x20: + s3->accel.cx++; + s3->accel.cy--; + break; + case 0x40: + s3->accel.cy--; + break; + case 0x60: + s3->accel.cx--; + s3->accel.cy--; + break; + case 0x80: + s3->accel.cx--; + break; + case 0xa0: + s3->accel.cx--; + s3->accel.cy++; + break; + case 0xc0: + s3->accel.cy++; + break; + case 0xe0: + s3->accel.cx++; + s3->accel.cy++; + break; + } + s3->accel.sy--; + } + s3->accel.cur_x = s3->accel.cx; + s3->accel.cur_y = s3->accel.cy; + } else /*Bresenham*/ + { + while (count-- && s3->accel.sy >= 0) { + if ((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && + (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b) { + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = s3->accel.bkgd_color; + break; + case 1: + src_dat = s3->accel.frgd_color; + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + src_dat = 0; + break; + } + + if ((compare_mode == 2 && src_dat != compare) || + (compare_mode == 3 && src_dat == compare) || compare_mode < 2) { + READ_DST((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); + + // pclog("Line : %04i, %04i (%06X) - %02X + // (%02X %04X %05X) %02X (%02X %02X) ", + // s3->accel.cx, s3->accel.cy, + // s3->accel.dest + s3->accel.cx, src_dat, + // vram[s3->accel.src + s3->accel.cx], + // mix_dat & mix_mask, s3->accel.src + + // s3->accel.cx, dest_dat, + // s3->accel.frgd_color, + // s3->accel.bkgd_color); + + MIX + + // pclog("%02X\n", dest_dat); + + WRITE((s3->accel.cy * s3->width) + s3->accel.cx); + } + } + + mix_dat <<= 1; + mix_dat |= 1; + if (s3->bpp == 0) + cpu_dat >>= 8; + else + cpu_dat >>= 16; + + // pclog("%i, %i - %i %i %i %i\n", s3->accel.cx, s3->accel.cy, + // s3->accel.err_term, s3->accel.maj_axis_pcnt, + // s3->accel.desty_axstp, s3->accel.destx_distp); + + if (!s3->accel.sy) + break; + + if (s3->accel.err_term >= s3->accel.maj_axis_pcnt) { + s3->accel.err_term += s3->accel.destx_distp; + /*Step minor axis*/ + switch (s3->accel.cmd & 0xe0) { + case 0x00: + s3->accel.cy--; + break; + case 0x20: + s3->accel.cy--; + break; + case 0x40: + s3->accel.cx--; + break; + case 0x60: + s3->accel.cx++; + break; + case 0x80: + s3->accel.cy++; + break; + case 0xa0: + s3->accel.cy++; + break; + case 0xc0: + s3->accel.cx--; + break; + case 0xe0: + s3->accel.cx++; + break; + } + } else + s3->accel.err_term += s3->accel.desty_axstp; + + /*Step major axis*/ + switch (s3->accel.cmd & 0xe0) { + case 0x00: + s3->accel.cx--; + break; + case 0x20: + s3->accel.cx++; + break; + case 0x40: + s3->accel.cy--; + break; + case 0x60: + s3->accel.cy--; + break; + case 0x80: + s3->accel.cx--; + break; + case 0xa0: + s3->accel.cx++; + break; + case 0xc0: + s3->accel.cy++; + break; + case 0xe0: + s3->accel.cy++; + break; + } + s3->accel.sy--; + } + s3->accel.cur_x = s3->accel.cx; + s3->accel.cur_y = s3->accel.cy; + } + break; + + case 2: /*Rectangle fill*/ + if (!cpu_input) /*!cpu_input is trigger to start operation*/ + { + s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; + s3->accel.sy = s3->accel.multifunc[0] & 0xfff; + s3->accel.cx = s3->accel.cur_x; + if (s3->accel.cur_x & 0x1000) + s3->accel.cx |= ~0xfff; + s3->accel.cy = s3->accel.cur_y; + if (s3->accel.cur_y & 0x1000) + s3->accel.cy |= ~0xfff; + + s3->accel.dest = dstbase + s3->accel.cy * s3->width; + + // pclog("Dest %08X (%i, %i) %04X %04X\n", s3->accel.dest, s3->accel.cx, + // s3->accel.cy, s3->accel.cur_x, s3->accel.cur_x & 0x1000); + } + if ((s3->accel.cmd & 0x100) && !cpu_input) + return; /*Wait for data from CPU*/ + // if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && !cpu_input) /*Mix data from CPU*/ + // return; + + frgd_mix = (s3->accel.frgd_mix >> 5) & 3; + bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; + + while (count-- && s3->accel.sy >= 0) { + if ((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && + (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b) { + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = s3->accel.bkgd_color; + break; + case 1: + src_dat = s3->accel.frgd_color; + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + src_dat = 0; + break; + } + + if ((compare_mode == 2 && src_dat != compare) || (compare_mode == 3 && src_dat == compare) || + compare_mode < 2) { + READ_DST(s3->accel.dest + s3->accel.cx, dest_dat); + + // if (CS != 0xc000) pclog("Write %05X %02X %02X %04X + // (%02X %02X) ", s3->accel.dest + s3->accel.cx, src_dat, + // dest_dat, mix_dat, s3->accel.frgd_mix, + // s3->accel.bkgd_mix); + + MIX + + // if (CS != 0xc000) pclog("%02X\n", dest_dat); + + WRITE(s3->accel.dest + s3->accel.cx); + } + } + + mix_dat <<= 1; + mix_dat |= 1; + if (s3->bpp == 0) + cpu_dat >>= 8; + else + cpu_dat >>= 16; + + if (s3->accel.cmd & 0x20) + s3->accel.cx++; + else + s3->accel.cx--; + s3->accel.sx--; + if (s3->accel.sx < 0) { + if (s3->accel.cmd & 0x20) + s3->accel.cx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; + else + s3->accel.cx += (s3->accel.maj_axis_pcnt & 0xfff) + 1; + // s3->accel.dest -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; + s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; + + // s3->accel.dest += s3_width; + if (s3->accel.cmd & 0x80) + s3->accel.cy++; + else + s3->accel.cy--; + + s3->accel.dest = dstbase + s3->accel.cy * s3->width; + s3->accel.sy--; + + if (cpu_input /* && (s3->accel.multifunc[0xa] & 0xc0) == 0x80*/) + return; + if (s3->accel.sy < 0) { + s3->accel.cur_x = s3->accel.cx; + s3->accel.cur_y = s3->accel.cy; + return; + } + } + } + break; + + case 6: /*BitBlt*/ + if (!cpu_input) /*!cpu_input is trigger to start operation*/ + { + s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; + s3->accel.sy = s3->accel.multifunc[0] & 0xfff; + + s3->accel.dx = s3->accel.destx_distp & 0xfff; + if (s3->accel.destx_distp & 0x1000) + s3->accel.dx |= ~0xfff; + s3->accel.dy = s3->accel.desty_axstp & 0xfff; + if (s3->accel.desty_axstp & 0x1000) + s3->accel.dy |= ~0xfff; + + s3->accel.cx = s3->accel.cur_x & 0xfff; + if (s3->accel.cur_x & 0x1000) + s3->accel.cx |= ~0xfff; + s3->accel.cy = s3->accel.cur_y & 0xfff; + if (s3->accel.cur_y & 0x1000) + s3->accel.cy |= ~0xfff; + + s3->accel.src = srcbase + s3->accel.cy * s3->width; + s3->accel.dest = dstbase + s3->accel.dy * s3->width; + + // pclog("Source %08X Dest %08X (%i, %i) - (%i, %i)\n", s3->accel.src, + // s3->accel.dest, s3->accel.cx, s3->accel.cy, s3->accel.dx, s3->accel.dy); + } + if ((s3->accel.cmd & 0x100) && !cpu_input) + return; /*Wait for data from CPU*/ + // if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && !cpu_input) /*Mix data from CPU*/ + // return; + + if (s3->accel.sy < 0) + return; + + frgd_mix = (s3->accel.frgd_mix >> 5) & 3; + bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; + + if (!cpu_input && frgd_mix == 3 && !vram_mask && !compare_mode && (s3->accel.cmd & 0xa0) == 0xa0 && + (s3->accel.frgd_mix & 0xf) == 7) { + while (1) { + if ((s3->accel.dx & 0xfff) >= clip_l && (s3->accel.dx & 0xfff) <= clip_r && + (s3->accel.dy & 0xfff) >= clip_t && (s3->accel.dy & 0xfff) <= clip_b) { + READ_SRC(s3->accel.src + s3->accel.cx, src_dat); + READ_DST(s3->accel.dest + s3->accel.dx, dest_dat); + + dest_dat = (src_dat & s3->accel.wrt_mask) | (dest_dat & ~s3->accel.wrt_mask); + + WRITE(s3->accel.dest + s3->accel.dx); + } + + s3->accel.cx++; + s3->accel.dx++; + s3->accel.sx--; + if (s3->accel.sx < 0) { + s3->accel.cx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; + s3->accel.dx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; + s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; + + s3->accel.cy++; + s3->accel.dy++; + + s3->accel.src = srcbase + s3->accel.cy * s3->width; + s3->accel.dest = dstbase + s3->accel.dy * s3->width; + + s3->accel.sy--; + + if (s3->accel.sy < 0) + return; + } + } + } else { + while (count-- && s3->accel.sy >= 0) { + if ((s3->accel.dx & 0xfff) >= clip_l && (s3->accel.dx & 0xfff) <= clip_r && + (s3->accel.dy & 0xfff) >= clip_t && (s3->accel.dy & 0xfff) <= clip_b) { + if (vram_mask) { + READ_SRC(s3->accel.src + s3->accel.cx, mix_dat) + + mix_dat = mix_dat ? mix_mask : 0; + } + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = s3->accel.bkgd_color; + break; + case 1: + src_dat = s3->accel.frgd_color; + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + READ_SRC(s3->accel.src + s3->accel.cx, src_dat); + break; + } + + if ((compare_mode == 2 && src_dat != compare) || + (compare_mode == 3 && src_dat == compare) || compare_mode < 2) { + READ_DST(s3->accel.dest + s3->accel.dx, dest_dat); + + // pclog("BitBlt : %04i, %04i (%06X) - %02X (%02X + // %04X %05X) %02X ", s3->accel.dx, s3->accel.dy, + // s3->accel.dest + s3->accel.dx, src_dat, + // vram[s3->accel.src + s3->accel.cx], mix_dat, + // s3->accel.src + s3->accel.cx, dest_dat); + + MIX + + // pclog("%02X\n", dest_dat); + + WRITE(s3->accel.dest + s3->accel.dx); + } + } + + mix_dat <<= 1; + mix_dat |= 1; + if (s3->bpp == 0) + cpu_dat >>= 8; + else + cpu_dat >>= 16; + + if (s3->accel.cmd & 0x20) { + s3->accel.cx++; + s3->accel.dx++; + } else { + s3->accel.cx--; + s3->accel.dx--; + } + s3->accel.sx--; + if (s3->accel.sx < 0) { + if (s3->accel.cmd & 0x20) { + s3->accel.cx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; + s3->accel.dx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; + } else { + s3->accel.cx += (s3->accel.maj_axis_pcnt & 0xfff) + 1; + s3->accel.dx += (s3->accel.maj_axis_pcnt & 0xfff) + 1; + } + s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; + + if (s3->accel.cmd & 0x80) { + s3->accel.cy++; + s3->accel.dy++; + } else { + s3->accel.cy--; + s3->accel.dy--; + } + + s3->accel.src = srcbase + s3->accel.cy * s3->width; + s3->accel.dest = dstbase + s3->accel.dy * s3->width; + + s3->accel.sy--; + + if (cpu_input /* && (s3->accel.multifunc[0xa] & 0xc0) == 0x80*/) + return; + if (s3->accel.sy < 0) + return; + } + } + } + break; + + case 7: /*Pattern fill - BitBlt but with source limited to 8x8*/ + if (!cpu_input) /*!cpu_input is trigger to start operation*/ + { + s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; + s3->accel.sy = s3->accel.multifunc[0] & 0xfff; + + s3->accel.dx = s3->accel.destx_distp & 0xfff; + if (s3->accel.destx_distp & 0x1000) + s3->accel.dx |= ~0xfff; + s3->accel.dy = s3->accel.desty_axstp & 0xfff; + if (s3->accel.desty_axstp & 0x1000) + s3->accel.dy |= ~0xfff; + + s3->accel.cx = s3->accel.cur_x & 0xfff; + if (s3->accel.cur_x & 0x1000) + s3->accel.cx |= ~0xfff; + s3->accel.cy = s3->accel.cur_y & 0xfff; + if (s3->accel.cur_y & 0x1000) + s3->accel.cy |= ~0xfff; + + /*Align source with destination*/ + // s3->accel.cx = (s3->accel.cx & ~7) | (s3->accel.dx & 7); + // s3->accel.cy = (s3->accel.cy & ~7) | (s3->accel.dy & 7); + + s3->accel.pattern = (s3->accel.cy * s3->width) + s3->accel.cx; + s3->accel.dest = dstbase + s3->accel.dy * s3->width; + + s3->accel.cx = s3->accel.dx & 7; + s3->accel.cy = s3->accel.dy & 7; + + s3->accel.src = srcbase + s3->accel.pattern + (s3->accel.cy * s3->width); + + // pclog("Source %08X Dest %08X (%i, %i) - (%i, %i)\n", s3->accel.src, + // s3->accel.dest, s3->accel.cx, s3->accel.cy, s3->accel.dx, s3->accel.dy); + // dumpregs(); + // exit(-1); + } + if ((s3->accel.cmd & 0x100) && !cpu_input) + return; /*Wait for data from CPU*/ + // if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && !cpu_input) /*Mix data from CPU*/ + // return; + + frgd_mix = (s3->accel.frgd_mix >> 5) & 3; + bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; + + while (count-- && s3->accel.sy >= 0) { + if ((s3->accel.dx & 0xfff) >= clip_l && (s3->accel.dx & 0xfff) <= clip_r && + (s3->accel.dy & 0xfff) >= clip_t && (s3->accel.dy & 0xfff) <= clip_b) { + if (vram_mask) { + READ_SRC(s3->accel.src + s3->accel.cx, mix_dat) + mix_dat = mix_dat ? mix_mask : 0; + } + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = s3->accel.bkgd_color; + break; + case 1: + src_dat = s3->accel.frgd_color; + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + READ_SRC(s3->accel.src + s3->accel.cx, src_dat); + break; + } + + if ((compare_mode == 2 && src_dat != compare) || (compare_mode == 3 && src_dat == compare) || + compare_mode < 2) { + READ_DST(s3->accel.dest + s3->accel.dx, dest_dat); + + // pclog("Pattern fill : %04i, %04i (%06X) - %02X (%02X + // %04X %05X) %02X ", s3->accel.dx, s3->accel.dy, + // s3->accel.dest + s3->accel.dx, src_dat, + // vram[s3->accel.src + s3->accel.cx], mix_dat, + // s3->accel.src + s3->accel.cx, dest_dat); + + MIX + + // pclog("%02X\n", dest_dat); + + WRITE(s3->accel.dest + s3->accel.dx); + } + } + + mix_dat <<= 1; + mix_dat |= 1; + if (s3->bpp == 0) + cpu_dat >>= 8; + else + cpu_dat >>= 16; + + if (s3->accel.cmd & 0x20) { + s3->accel.cx = ((s3->accel.cx + 1) & 7) | (s3->accel.cx & ~7); + s3->accel.dx++; + } else { + s3->accel.cx = ((s3->accel.cx - 1) & 7) | (s3->accel.cx & ~7); + s3->accel.dx--; + } + s3->accel.sx--; + if (s3->accel.sx < 0) { + if (s3->accel.cmd & 0x20) { + s3->accel.cx = ((s3->accel.cx - ((s3->accel.maj_axis_pcnt & 0xfff) + 1)) & 7) | + (s3->accel.cx & ~7); + s3->accel.dx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; + } else { + s3->accel.cx = ((s3->accel.cx + ((s3->accel.maj_axis_pcnt & 0xfff) + 1)) & 7) | + (s3->accel.cx & ~7); + s3->accel.dx += (s3->accel.maj_axis_pcnt & 0xfff) + 1; + } + s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; + + if (s3->accel.cmd & 0x80) { + s3->accel.cy = ((s3->accel.cy + 1) & 7) | (s3->accel.cy & ~7); + s3->accel.dy++; + } else { + s3->accel.cy = ((s3->accel.cy - 1) & 7) | (s3->accel.cy & ~7); + s3->accel.dy--; + } + + s3->accel.src = srcbase + s3->accel.pattern + (s3->accel.cy * s3->width); + s3->accel.dest = dstbase + s3->accel.dy * s3->width; + + s3->accel.sy--; + + if (cpu_input /* && (s3->accel.multifunc[0xa] & 0xc0) == 0x80*/) + return; + if (s3->accel.sy < 0) + return; + } + } + break; + + case 3: /*Polygon Fill Solid (Trio64 only)*/ + { + int end_y1, end_y2; + + if (s3->chip != S3_TRIO64) + break; + + polygon_setup(s3); + + if ((s3->accel.cmd & 0x100) && !cpu_input) + return; /*Wait for data from CPU*/ + + end_y1 = s3->accel.desty_axstp; + end_y2 = s3->accel.desty_axstp2; + + frgd_mix = (s3->accel.frgd_mix >> 5) & 3; + + while ((s3->accel.poly_cy < end_y1) && (s3->accel.poly_cy2 < end_y2)) { + int y = s3->accel.poly_cy; + int x_count = ABS((s3->accel.poly_cx2 >> 20) - s3->accel.poly_x) + 1; + + s3->accel.dest = dstbase + y * s3->width; + + while (x_count-- && count--) { + if ((s3->accel.poly_x & 0xfff) >= clip_l && (s3->accel.poly_x & 0xfff) <= clip_r && + (s3->accel.poly_cy & 0xfff) >= clip_t && (s3->accel.poly_cy & 0xfff) <= clip_b) { + switch (frgd_mix) { + case 0: + src_dat = s3->accel.bkgd_color; + break; + case 1: + src_dat = s3->accel.frgd_color; + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + src_dat = 0; /*Nor supported?*/ + break; + } + + if ((compare_mode == 2 && src_dat != compare) || + (compare_mode == 3 && src_dat == compare) || compare_mode < 2) { + READ_DST(s3->accel.dest + s3->accel.poly_x, dest_dat); + + MIX + + WRITE(s3->accel.dest + s3->accel.poly_x); + } + } + if (s3->bpp == 0) + cpu_dat >>= 8; + else + cpu_dat >>= 16; + + if (s3->accel.poly_x < (s3->accel.poly_cx2 >> 20)) + s3->accel.poly_x++; + else + s3->accel.poly_x--; + } + + s3->accel.poly_cx += s3->accel.poly_dx1; + s3->accel.poly_cx2 += s3->accel.poly_dx2; + s3->accel.poly_x = s3->accel.poly_cx >> 20; + + s3->accel.poly_cy++; + s3->accel.poly_cy2++; + + if (!count) + break; + } + + s3->accel.cur_x = s3->accel.poly_cx & 0xfff; + s3->accel.cur_y = s3->accel.poly_cy & 0xfff; + s3->accel.cur_x2 = s3->accel.poly_cx2 & 0xfff; + s3->accel.cur_y2 = s3->accel.poly_cy & 0xfff; + } break; + + case 11: /*Polygon Fill Pattern (Trio64 only)*/ + { + int end_y1, end_y2; + + if (s3->chip != S3_TRIO64) + break; + + polygon_setup(s3); + + if ((s3->accel.cmd & 0x100) && !cpu_input) + return; /*Wait for data from CPU*/ + + end_y1 = s3->accel.desty_axstp; + end_y2 = s3->accel.desty_axstp2; + + frgd_mix = (s3->accel.frgd_mix >> 5) & 3; + bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; + + while ((s3->accel.poly_cy < end_y1) && (s3->accel.poly_cy2 < end_y2)) { + int y = s3->accel.poly_cy; + int x_count = ABS((s3->accel.poly_cx2 >> 20) - s3->accel.poly_x) + 1; + + s3->accel.src = srcbase + s3->accel.pattern + ((y & 7) * s3->width); + s3->accel.dest = dstbase + y * s3->width; + + while (x_count-- && count--) { + int pat_x = s3->accel.poly_x & 7; + + if ((s3->accel.poly_x & 0xfff) >= clip_l && (s3->accel.poly_x & 0xfff) <= clip_r && + (s3->accel.poly_cy & 0xfff) >= clip_t && (s3->accel.poly_cy & 0xfff) <= clip_b) { + if (vram_mask) { + READ_SRC(s3->accel.src + pat_x, mix_dat) + mix_dat = mix_dat ? mix_mask : 0; + } + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = s3->accel.bkgd_color; + break; + case 1: + src_dat = s3->accel.frgd_color; + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + READ_SRC(s3->accel.src + pat_x, src_dat); + break; + } + + if ((compare_mode == 2 && src_dat != compare) || + (compare_mode == 3 && src_dat == compare) || compare_mode < 2) { + READ_DST(s3->accel.dest + s3->accel.poly_x, dest_dat); + + MIX + + WRITE(s3->accel.dest + s3->accel.poly_x); + } + } + if (s3->bpp == 0) + cpu_dat >>= 8; + else + cpu_dat >>= 16; + + mix_dat <<= 1; + mix_dat |= 1; + + if (s3->accel.poly_x < (s3->accel.poly_cx2 >> 20)) + s3->accel.poly_x++; + else + s3->accel.poly_x--; + } + + s3->accel.poly_cx += s3->accel.poly_dx1; + s3->accel.poly_cx2 += s3->accel.poly_dx2; + s3->accel.poly_x = s3->accel.poly_cx >> 20; + + s3->accel.poly_cy++; + s3->accel.poly_cy2++; + + if (!count) + break; + } + + s3->accel.cur_x = s3->accel.poly_cx & 0xfff; + s3->accel.cur_y = s3->accel.poly_cy & 0xfff; + s3->accel.cur_x2 = s3->accel.poly_cx2 & 0xfff; + s3->accel.cur_y2 = s3->accel.poly_cy & 0xfff; + } break; + } } void s3_hwcursor_draw(svga_t *svga, int displine) { - s3_t *s3 = (s3_t *)svga->p; - int x; - uint16_t dat[2]; - int xx; - int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; - uint32_t fg = 0, bg = 0; + s3_t *s3 = (s3_t *)svga->p; + int x; + uint16_t dat[2]; + int xx; + int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; + uint32_t fg = 0, bg = 0; - switch (svga->bpp) { - case 15:fg = video_15to32[s3->hwc_fg_col & 0xffff]; - bg = video_15to32[s3->hwc_bg_col & 0xffff]; - break; + switch (svga->bpp) { + case 15: + fg = video_15to32[s3->hwc_fg_col & 0xffff]; + bg = video_15to32[s3->hwc_bg_col & 0xffff]; + break; - case 16:fg = video_16to32[s3->hwc_fg_col & 0xffff]; - bg = video_16to32[s3->hwc_bg_col & 0xffff]; - break; + case 16: + fg = video_16to32[s3->hwc_fg_col & 0xffff]; + bg = video_16to32[s3->hwc_bg_col & 0xffff]; + break; - case 24: - case 32:fg = s3->hwc_fg_col; - bg = s3->hwc_bg_col; - break; + case 24: + case 32: + fg = s3->hwc_fg_col; + bg = s3->hwc_bg_col; + break; - default: - if (s3->chip == S3_TRIO32 || s3->chip == S3_TRIO64) { - fg = svga->pallook[s3->hwc_fg_col & 0xff]; - bg = svga->pallook[s3->hwc_bg_col & 0xff]; - } else { - fg = svga->pallook[svga->crtc[0xe]]; - bg = svga->pallook[svga->crtc[0xf]]; - } - break; - } + default: + if (s3->chip == S3_TRIO32 || s3->chip == S3_TRIO64) { + fg = svga->pallook[s3->hwc_fg_col & 0xff]; + bg = svga->pallook[s3->hwc_bg_col & 0xff]; + } else { + fg = svga->pallook[svga->crtc[0xe]]; + bg = svga->pallook[svga->crtc[0xf]]; + } + break; + } - if (svga->interlace && svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += 16; + if (svga->interlace && svga->hwcursor_oddeven) + svga->hwcursor_latch.addr += 16; -// pclog("HWcursor %i %i\n", svga->hwcursor_latch.x, svga->hwcursor_latch.y); - for (x = 0; x < 64; x += 16) { - uint32_t remapped_addr = dword_remap(svga->hwcursor_latch.addr); + // pclog("HWcursor %i %i\n", svga->hwcursor_latch.x, svga->hwcursor_latch.y); + for (x = 0; x < 64; x += 16) { + uint32_t remapped_addr = dword_remap(svga->hwcursor_latch.addr); - dat[0] = (svga->vram[remapped_addr] << 8) | svga->vram[remapped_addr + 1]; - dat[1] = (svga->vram[remapped_addr + 2] << 8) | svga->vram[remapped_addr + 3]; - for (xx = 0; xx < 16; xx++) { - if (offset >= svga->hwcursor_latch.x) { - if (!(dat[0] & 0x8000)) - ((uint32_t *)buffer32->line[displine])[offset + 32] = (dat[1] & 0x8000) ? fg : bg; - else if (dat[1] & 0x8000) - ((uint32_t *)buffer32->line[displine])[offset + 32] ^= 0xffffff; -// pclog("Plot %i, %i (%i %i) %04X %04X\n", offset, displine, x+xx, svga_hwcursor_on, dat[0], dat[1]); - } + dat[0] = (svga->vram[remapped_addr] << 8) | svga->vram[remapped_addr + 1]; + dat[1] = (svga->vram[remapped_addr + 2] << 8) | svga->vram[remapped_addr + 3]; + for (xx = 0; xx < 16; xx++) { + if (offset >= svga->hwcursor_latch.x) { + if (!(dat[0] & 0x8000)) + ((uint32_t *)buffer32->line[displine])[offset + 32] = (dat[1] & 0x8000) ? fg : bg; + else if (dat[1] & 0x8000) + ((uint32_t *)buffer32->line[displine])[offset + 32] ^= 0xffffff; + // pclog("Plot %i, %i (%i %i) %04X %04X\n", offset, displine, x+xx, + // svga_hwcursor_on, dat[0], dat[1]); + } - offset++; - dat[0] <<= 1; - dat[1] <<= 1; - } - svga->hwcursor_latch.addr += 4; - } - if (svga->interlace && !svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += 16; + offset++; + dat[0] <<= 1; + dat[1] <<= 1; + } + svga->hwcursor_latch.addr += 4; + } + if (svga->interlace && !svga->hwcursor_oddeven) + svga->hwcursor_latch.addr += 16; } static void s3_io_remove(s3_t *s3) { - io_removehandler(0x03c0, 0x0020, s3_in, NULL, NULL, s3_out, NULL, NULL, s3); + io_removehandler(0x03c0, 0x0020, s3_in, NULL, NULL, s3_out, NULL, NULL, s3); - io_removehandler(0x42e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0x46e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0x4ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0x82e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0x86e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0x8ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0x8ee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0x92e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0x96e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0x9ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0x9ee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0xa2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0xa6e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0xaae8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0xaee8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0xb2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0xb6e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0xbae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0xbee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0xe2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, s3_accel_out_w, s3_accel_out_l, s3); + io_removehandler(0x42e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0x46e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0x4ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0x82e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0x86e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0x8ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0x8ee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0x92e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0x96e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0x9ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0x9ee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0xa2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0xa6e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0xaae8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0xaee8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0xb2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0xb6e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0xbae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0xbee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0xe2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, s3_accel_out_w, s3_accel_out_l, s3); } static void s3_io_set(s3_t *s3) { - s3_io_remove(s3); + s3_io_remove(s3); - io_sethandler(0x03c0, 0x0020, s3_in, NULL, NULL, s3_out, NULL, NULL, s3); + io_sethandler(0x03c0, 0x0020, s3_in, NULL, NULL, s3_out, NULL, NULL, s3); - io_sethandler(0x42e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x46e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x4ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - if (s3->chip == S3_TRIO64) { - io_sethandler(0x82e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x86e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x8ae8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x8ee8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x92e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x96e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - } else { - io_sethandler(0x82e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x86e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x8ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x8ee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x92e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x96e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - } - io_sethandler(0x9ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x9ee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0xa2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0xa6e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0xaae8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0xaee8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0xb2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0xb6e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0xbae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0xbee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0xe2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, s3_accel_out_w, s3_accel_out_l, s3); + io_sethandler(0x42e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x46e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x4ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + if (s3->chip == S3_TRIO64) { + io_sethandler(0x82e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x86e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x8ae8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x8ee8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x92e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x96e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + } else { + io_sethandler(0x82e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x86e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x8ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x8ee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x92e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x96e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + } + io_sethandler(0x9ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x9ee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0xa2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0xa6e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0xaae8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0xaee8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0xb2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0xb6e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0xbae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0xbee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0xe2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, s3_accel_out_w, s3_accel_out_l, s3); } uint8_t s3_pci_read(int func, int addr, void *p) { - s3_t *s3 = (s3_t *)p; - svga_t *svga = &s3->svga; -// pclog("S3 PCI read %08X\n", addr); - switch (addr) { - case 0x00:return 0x33; /*'S3'*/ - case 0x01:return 0x53; + s3_t *s3 = (s3_t *)p; + svga_t *svga = &s3->svga; + // pclog("S3 PCI read %08X\n", addr); + switch (addr) { + case 0x00: + return 0x33; /*'S3'*/ + case 0x01: + return 0x53; - case 0x02:return s3->id_ext_pci; - case 0x03:return 0x88; + case 0x02: + return s3->id_ext_pci; + case 0x03: + return 0x88; - case PCI_REG_COMMAND:return s3->pci_regs[PCI_REG_COMMAND]; /*Respond to IO and memory accesses*/ + case PCI_REG_COMMAND: + return s3->pci_regs[PCI_REG_COMMAND]; /*Respond to IO and memory accesses*/ - case 0x07:return 1 << 1; /*Medium DEVSEL timing*/ + case 0x07: + return 1 << 1; /*Medium DEVSEL timing*/ - case 0x08:return 0; /*Revision ID*/ - case 0x09:return 0; /*Programming interface*/ + case 0x08: + return 0; /*Revision ID*/ + case 0x09: + return 0; /*Programming interface*/ - case 0x0a:return 0x00; /*Supports VGA interface*/ - case 0x0b:return 0x03; + case 0x0a: + return 0x00; /*Supports VGA interface*/ + case 0x0b: + return 0x03; - case 0x10:return 0x00; /*Linear frame buffer address*/ - case 0x11:return 0x00; - case 0x12:return svga->crtc[0x5a] & 0x80; - case 0x13:return svga->crtc[0x59]; + case 0x10: + return 0x00; /*Linear frame buffer address*/ + case 0x11: + return 0x00; + case 0x12: + return svga->crtc[0x5a] & 0x80; + case 0x13: + return svga->crtc[0x59]; - case 0x30:return s3->pci_regs[0x30] & 0x01; /*BIOS ROM address*/ - case 0x31:return 0x00; - case 0x32:return s3->pci_regs[0x32]; - case 0x33:return s3->pci_regs[0x33]; + case 0x30: + return s3->pci_regs[0x30] & 0x01; /*BIOS ROM address*/ + case 0x31: + return 0x00; + case 0x32: + return s3->pci_regs[0x32]; + case 0x33: + return s3->pci_regs[0x33]; - case 0x3c:return s3->int_line; - case 0x3d:return PCI_INTA; - } - return 0; + case 0x3c: + return s3->int_line; + case 0x3d: + return PCI_INTA; + } + return 0; } void s3_pci_write(int func, int addr, uint8_t val, void *p) { - s3_t *s3 = (s3_t *)p; - svga_t *svga = &s3->svga; -// pclog("s3_pci_write: addr=%02x val=%02x\n", addr, val); - switch (addr) { - case PCI_REG_COMMAND:s3->pci_regs[PCI_REG_COMMAND] = val & 0x23; - if (val & PCI_COMMAND_IO) - s3_io_set(s3); - else - s3_io_remove(s3); - s3_updatemapping(s3); - break; + s3_t *s3 = (s3_t *)p; + svga_t *svga = &s3->svga; + // pclog("s3_pci_write: addr=%02x val=%02x\n", addr, val); + switch (addr) { + case PCI_REG_COMMAND: + s3->pci_regs[PCI_REG_COMMAND] = val & 0x23; + if (val & PCI_COMMAND_IO) + s3_io_set(s3); + else + s3_io_remove(s3); + s3_updatemapping(s3); + break; - case 0x12:svga->crtc[0x5a] = val & 0x80; - s3_updatemapping(s3); - break; - case 0x13:svga->crtc[0x59] = val; - s3_updatemapping(s3); - break; + case 0x12: + svga->crtc[0x5a] = val & 0x80; + s3_updatemapping(s3); + break; + case 0x13: + svga->crtc[0x59] = val; + s3_updatemapping(s3); + break; - case 0x30: - case 0x32: - case 0x33:s3->pci_regs[addr] = val; - if (s3->pci_regs[0x30] & 0x01) { - uint32_t addr = (s3->pci_regs[0x32] << 16) | (s3->pci_regs[0x33] << 24); -// pclog("S3 bios_rom enabled at %08x\n", addr); - mem_mapping_set_addr(&s3->bios_rom.mapping, addr, 0x8000); - } else { -// pclog("S3 bios_rom disabled\n"); - mem_mapping_disable(&s3->bios_rom.mapping); - } - return; + case 0x30: + case 0x32: + case 0x33: + s3->pci_regs[addr] = val; + if (s3->pci_regs[0x30] & 0x01) { + uint32_t addr = (s3->pci_regs[0x32] << 16) | (s3->pci_regs[0x33] << 24); + // pclog("S3 bios_rom enabled at %08x\n", addr); + mem_mapping_set_addr(&s3->bios_rom.mapping, addr, 0x8000); + } else { + // pclog("S3 bios_rom disabled\n"); + mem_mapping_disable(&s3->bios_rom.mapping); + } + return; - case 0x3c:s3->int_line = val; - return; - } + case 0x3c: + s3->int_line = val; + return; + } } -static int vram_sizes[] = - { - 7, /*512 kB*/ - 6, /*1 MB*/ - 4, /*2 MB*/ - 0, - 0, /*4 MB*/ - 0, - 0, - 0, - 3 /*8 MB*/ - }; +static int vram_sizes[] = { + 7, /*512 kB*/ + 6, /*1 MB*/ + 4, /*2 MB*/ + 0, 0, /*4 MB*/ + 0, 0, 0, 3 /*8 MB*/ +}; static void *s3_init(char *bios_fn, int chip) { - s3_t *s3 = malloc(sizeof(s3_t)); - svga_t *svga = &s3->svga; - int vram; - uint32_t vram_size; + s3_t *s3 = malloc(sizeof(s3_t)); + svga_t *svga = &s3->svga; + int vram; + uint32_t vram_size; - memset(s3, 0, sizeof(s3_t)); + memset(s3, 0, sizeof(s3_t)); - vram = device_get_config_int("memory"); - if (vram) - vram_size = vram << 20; - else - vram_size = 512 << 10; - s3->vram_mask = vram_size - 1; + vram = device_get_config_int("memory"); + if (vram) + vram_size = vram << 20; + else + vram_size = 512 << 10; + s3->vram_mask = vram_size - 1; - rom_init(&s3->bios_rom, bios_fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - if (PCI) - mem_mapping_disable(&s3->bios_rom.mapping); + rom_init(&s3->bios_rom, bios_fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + if (PCI) + mem_mapping_disable(&s3->bios_rom.mapping); - mem_mapping_add(&s3->linear_mapping, - 0, - 0, - svga_read_linear, - svga_readw_linear, - svga_readl_linear, - svga_write_linear, - svga_writew_linear, - svga_writel_linear, - NULL, - MEM_MAPPING_EXTERNAL, - &s3->svga); - mem_mapping_add(&s3->mmio_mapping, 0xa0000, 0x10000, s3_accel_read, NULL, NULL, s3_accel_write, s3_accel_write_w, s3_accel_write_l, NULL, MEM_MAPPING_EXTERNAL, s3); - mem_mapping_disable(&s3->mmio_mapping); + mem_mapping_add(&s3->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, + svga_writew_linear, svga_writel_linear, NULL, MEM_MAPPING_EXTERNAL, &s3->svga); + mem_mapping_add(&s3->mmio_mapping, 0xa0000, 0x10000, s3_accel_read, NULL, NULL, s3_accel_write, s3_accel_write_w, + s3_accel_write_l, NULL, MEM_MAPPING_EXTERNAL, s3); + mem_mapping_disable(&s3->mmio_mapping); - svga_init(&s3->svga, s3, vram_size, /*4mb - 864 supports 8mb but buggy VESA driver reports 0mb*/ - s3_recalctimings, - s3_in, s3_out, - s3_hwcursor_draw, - NULL); + svga_init(&s3->svga, s3, vram_size, /*4mb - 864 supports 8mb but buggy VESA driver reports 0mb*/ + s3_recalctimings, s3_in, s3_out, s3_hwcursor_draw, NULL); - svga->decode_mask = (4 << 20) - 1; - switch (vram) { - case 0: /*512kb*/ - svga->vram_mask = (1 << 19) - 1; - svga->vram_max = 2 << 20; - break; - case 1: /*1MB*/ - /*VRAM in first MB, mirrored in 2nd MB, 3rd and 4th MBs are open bus*/ - /*This works with the #9 9FX BIOS, and matches how my real Trio64 behaves, + svga->decode_mask = (4 << 20) - 1; + switch (vram) { + case 0: /*512kb*/ + svga->vram_mask = (1 << 19) - 1; + svga->vram_max = 2 << 20; + break; + case 1: /*1MB*/ + /*VRAM in first MB, mirrored in 2nd MB, 3rd and 4th MBs are open bus*/ + /*This works with the #9 9FX BIOS, and matches how my real Trio64 behaves, but does not work with the Phoenix EDO BIOS. Possibly an FPM/EDO difference?*/ - svga->vram_mask = (1 << 20) - 1; - svga->vram_max = 2 << 20; - break; - case 2: - default: /*2MB*/ - /*VRAM in first 2 MB, 3rd and 4th MBs are open bus*/ - svga->vram_mask = (2 << 20) - 1; - svga->vram_max = 2 << 20; - break; - case 4: /*4MB*/ - svga->vram_mask = (4 << 20) - 1; - svga->vram_max = 4 << 20; - break; - } + svga->vram_mask = (1 << 20) - 1; + svga->vram_max = 2 << 20; + break; + case 2: + default: /*2MB*/ + /*VRAM in first 2 MB, 3rd and 4th MBs are open bus*/ + svga->vram_mask = (2 << 20) - 1; + svga->vram_max = 2 << 20; + break; + case 4: /*4MB*/ + svga->vram_mask = (4 << 20) - 1; + svga->vram_max = 4 << 20; + break; + } - if (PCI) - svga->crtc[0x36] = 2 | (3 << 2) | (1 << 4) | (vram_sizes[vram] << 5); - else - svga->crtc[0x36] = 1 | (3 << 2) | (1 << 4) | (vram_sizes[vram] << 5); - svga->crtc[0x37] = 1 | (7 << 5); + if (PCI) + svga->crtc[0x36] = 2 | (3 << 2) | (1 << 4) | (vram_sizes[vram] << 5); + else + svga->crtc[0x36] = 1 | (3 << 2) | (1 << 4) | (vram_sizes[vram] << 5); + svga->crtc[0x37] = 1 | (7 << 5); - svga->vblank_start = s3_vblank_start; + svga->vblank_start = s3_vblank_start; - s3_io_set(s3); + s3_io_set(s3); - s3->card = pci_add(s3_pci_read, s3_pci_write, s3); + s3->card = pci_add(s3_pci_read, s3_pci_write, s3); - s3->pci_regs[0x04] = 7; + s3->pci_regs[0x04] = 7; - s3->pci_regs[0x30] = 0x00; - s3->pci_regs[0x32] = 0x0c; - s3->pci_regs[0x33] = 0x00; + s3->pci_regs[0x30] = 0x00; + s3->pci_regs[0x32] = 0x0c; + s3->pci_regs[0x33] = 0x00; - s3->chip = chip; + s3->chip = chip; - s3->wake_fifo_thread = thread_create_event(); - s3->fifo_not_full_event = thread_create_event(); - s3->fifo_thread = thread_create(fifo_thread, s3); + s3->wake_fifo_thread = thread_create_event(); + s3->fifo_not_full_event = thread_create_event(); + s3->fifo_thread = thread_create(fifo_thread, s3); - s3->int_line = 0; + s3->int_line = 0; - return s3; + return s3; } void *s3_bahamas64_init() { - s3_t *s3 = s3_init("bahamas64.bin", S3_VISION864); + s3_t *s3 = s3_init("bahamas64.bin", S3_VISION864); - s3->id = 0xc0; /*Vision864P*/ - s3->id_ext = s3->id_ext_pci = 0xc0; - s3->packed_mmio = 0; + s3->id = 0xc0; /*Vision864P*/ + s3->id_ext = s3->id_ext_pci = 0xc0; + s3->packed_mmio = 0; - s3->getclock = sdac_getclock; - s3->getclock_p = &s3->ramdac; - sdac_init(&s3->ramdac); + s3->getclock = sdac_getclock; + s3->getclock_p = &s3->ramdac; + sdac_init(&s3->ramdac); - return s3; + return s3; } -int s3_bahamas64_available() { - return rom_present("bahamas64.bin"); -} +int s3_bahamas64_available() { return rom_present("bahamas64.bin"); } void *s3_9fx_init() { - s3_t *s3 = s3_init("s3_764.bin", S3_TRIO64); + s3_t *s3 = s3_init("s3_764.bin", S3_TRIO64); - s3->id = 0xe1; /*Trio64*/ - s3->id_ext = s3->id_ext_pci = 0x11; - s3->packed_mmio = 1; + s3->id = 0xe1; /*Trio64*/ + s3->id_ext = s3->id_ext_pci = 0x11; + s3->packed_mmio = 1; - s3->getclock = s3_trio64_getclock; - s3->getclock_p = s3; + s3->getclock = s3_trio64_getclock; + s3->getclock_p = s3; - return s3; + return s3; } -int s3_9fx_available() { - return rom_present("s3_764.bin"); -} +int s3_9fx_available() { return rom_present("s3_764.bin"); } void *s3_phoenix_trio32_init() { - s3_t *s3 = s3_init("86c732p.bin", S3_TRIO32); + s3_t *s3 = s3_init("86c732p.bin", S3_TRIO32); - s3->id = 0xe1; /*Trio32*/ - s3->id_ext = 0x10; - s3->id_ext_pci = 0x11; - s3->packed_mmio = 1; + s3->id = 0xe1; /*Trio32*/ + s3->id_ext = 0x10; + s3->id_ext_pci = 0x11; + s3->packed_mmio = 1; - s3->getclock = s3_trio64_getclock; - s3->getclock_p = s3; + s3->getclock = s3_trio64_getclock; + s3->getclock_p = s3; - return s3; + return s3; } -int s3_phoenix_trio32_available() { - return rom_present("86c732p.bin"); -} +int s3_phoenix_trio32_available() { return rom_present("86c732p.bin"); } void *s3_phoenix_trio64_init() { - s3_t *s3 = s3_init("86c764x1.bin", S3_TRIO64); + s3_t *s3 = s3_init("86c764x1.bin", S3_TRIO64); - s3->id = 0xe1; /*Trio64*/ - s3->id_ext = s3->id_ext_pci = 0x11; - s3->packed_mmio = 1; - if (device_get_config_int("memory") == 1) - s3->svga.vram_max = 1 << 20; /*Phoenix BIOS does not expect VRAM to be mirrored*/ + s3->id = 0xe1; /*Trio64*/ + s3->id_ext = s3->id_ext_pci = 0x11; + s3->packed_mmio = 1; + if (device_get_config_int("memory") == 1) + s3->svga.vram_max = 1 << 20; /*Phoenix BIOS does not expect VRAM to be mirrored*/ - s3->getclock = s3_trio64_getclock; - s3->getclock_p = s3; + s3->getclock = s3_trio64_getclock; + s3->getclock_p = s3; - return s3; + return s3; } -int s3_phoenix_trio64_available() { - return rom_present("86c764x1.bin"); -} +int s3_phoenix_trio64_available() { return rom_present("86c764x1.bin"); } void s3_close(void *p) { - s3_t *s3 = (s3_t *)p; + s3_t *s3 = (s3_t *)p; - svga_close(&s3->svga); + svga_close(&s3->svga); - thread_kill(s3->fifo_thread); - thread_destroy_event(s3->wake_fifo_thread); - thread_destroy_event(s3->fifo_not_full_event); + thread_kill(s3->fifo_thread); + thread_destroy_event(s3->wake_fifo_thread); + thread_destroy_event(s3->fifo_not_full_event); - free(s3); + free(s3); } void s3_speed_changed(void *p) { - s3_t *s3 = (s3_t *)p; + s3_t *s3 = (s3_t *)p; - svga_recalctimings(&s3->svga); + svga_recalctimings(&s3->svga); } void s3_force_redraw(void *p) { - s3_t *s3 = (s3_t *)p; + s3_t *s3 = (s3_t *)p; - s3->svga.fullchange = changeframecount; + s3->svga.fullchange = changeframecount; } void s3_add_status_info(char *s, int max_len, void *p) { - s3_t *s3 = (s3_t *)p; - char temps[256]; - uint64_t new_time = timer_read(); - uint64_t status_diff = new_time - s3->status_time; - s3->status_time = new_time; + s3_t *s3 = (s3_t *)p; + char temps[256]; + uint64_t new_time = timer_read(); + uint64_t status_diff = new_time - s3->status_time; + s3->status_time = new_time; - if (!status_diff) - status_diff = 1; + if (!status_diff) + status_diff = 1; - svga_add_status_info(s, max_len, &s3->svga); - sprintf(temps, "%f%% CPU\n%f%% CPU (real)\n\n", ((double)s3->blitter_time * 100.0) / timer_freq, ((double)s3->blitter_time * 100.0) / status_diff); - strncat(s, temps, max_len); + svga_add_status_info(s, max_len, &s3->svga); + sprintf(temps, "%f%% CPU\n%f%% CPU (real)\n\n", ((double)s3->blitter_time * 100.0) / timer_freq, + ((double)s3->blitter_time * 100.0) / status_diff); + strncat(s, temps, max_len); - s3->blitter_time = 0; + s3->blitter_time = 0; } -static device_config_t s3_bahamas64_config[] = - { - { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "1 MB", - .value = 1 - }, - { - .description = "2 MB", - .value = 2 - }, - /*Vision864 also supports 4 and 8 MB, however the Paradise - BIOS is buggy (VESA modes don't work correctly), and UNIVBE and - OS/2 Warp misdetect the VRAM size. Bahamas 64 only supports - up to 2 MB on the board anyway. */ - { - .description = "" - } - }, - .default_int = 4 - }, - { - .type = -1 - } - }; +static device_config_t s3_bahamas64_config[] = {{.name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .selection = {{.description = "1 MB", .value = 1}, + {.description = "2 MB", .value = 2}, + /*Vision864 also supports 4 and 8 MB, however the Paradise + BIOS is buggy (VESA modes don't work correctly), and UNIVBE and + OS/2 Warp misdetect the VRAM size. Bahamas 64 only supports + up to 2 MB on the board anyway. */ + {.description = ""}}, + .default_int = 4}, + {.type = -1}}; -static device_config_t s3_9fx_config[] = - { - { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "1 MB", - .value = 1 - }, - { - .description = "2 MB", - .value = 2 - }, - /*Trio64 also supports 4 MB, however the Number Nine BIOS does not*/ - { - .description = "" - } - }, - .default_int = 2 - }, - { - .type = -1 - } - }; +static device_config_t s3_9fx_config[] = {{.name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .selection = {{.description = "1 MB", .value = 1}, + {.description = "2 MB", .value = 2}, + /*Trio64 also supports 4 MB, however the Number Nine BIOS does not*/ + {.description = ""}}, + .default_int = 2}, + {.type = -1}}; -static device_config_t s3_phoenix_trio32_config[] = - { - { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "512 KB", - .value = 0 - }, - { - .description = "1 MB", - .value = 1 - }, - { - .description = "2 MB", - .value = 2 - }, - { - .description = "" - } - }, - .default_int = 2 - }, - { - .type = -1 - } - }; +static device_config_t s3_phoenix_trio32_config[] = {{.name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .selection = {{.description = "512 KB", .value = 0}, + {.description = "1 MB", .value = 1}, + {.description = "2 MB", .value = 2}, + {.description = ""}}, + .default_int = 2}, + {.type = -1}}; -static device_config_t s3_phoenix_trio64_config[] = - { - { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "1 MB", - .value = 1 - }, - { - .description = "2 MB", - .value = 2 - }, - { - .description = "4 MB", - .value = 4 - }, - { - .description = "" - } - }, - .default_int = 2 - }, - { - .type = -1 - } - }; +static device_config_t s3_phoenix_trio64_config[] = {{.name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .selection = {{.description = "1 MB", .value = 1}, + {.description = "2 MB", .value = 2}, + {.description = "4 MB", .value = 4}, + {.description = ""}}, + .default_int = 2}, + {.type = -1}}; -device_t s3_bahamas64_device = - { - "Paradise Bahamas 64 (S3 Vision864)", - 0, - s3_bahamas64_init, - s3_close, - s3_bahamas64_available, - s3_speed_changed, - s3_force_redraw, - s3_add_status_info, - s3_bahamas64_config - }; +device_t s3_bahamas64_device = {"Paradise Bahamas 64 (S3 Vision864)", + 0, + s3_bahamas64_init, + s3_close, + s3_bahamas64_available, + s3_speed_changed, + s3_force_redraw, + s3_add_status_info, + s3_bahamas64_config}; -device_t s3_9fx_device = - { - "Number 9 9FX (S3 Trio64)", - 0, - s3_9fx_init, - s3_close, - s3_9fx_available, - s3_speed_changed, - s3_force_redraw, - s3_add_status_info, - s3_9fx_config - }; +device_t s3_9fx_device = {"Number 9 9FX (S3 Trio64)", + 0, + s3_9fx_init, + s3_close, + s3_9fx_available, + s3_speed_changed, + s3_force_redraw, + s3_add_status_info, + s3_9fx_config}; -device_t s3_phoenix_trio32_device = - { - "Phoenix S3 Trio32", - 0, - s3_phoenix_trio32_init, - s3_close, - s3_phoenix_trio32_available, - s3_speed_changed, - s3_force_redraw, - s3_add_status_info, - s3_phoenix_trio32_config - }; +device_t s3_phoenix_trio32_device = {"Phoenix S3 Trio32", + 0, + s3_phoenix_trio32_init, + s3_close, + s3_phoenix_trio32_available, + s3_speed_changed, + s3_force_redraw, + s3_add_status_info, + s3_phoenix_trio32_config}; -device_t s3_phoenix_trio64_device = - { - "Phoenix S3 Trio64", - 0, - s3_phoenix_trio64_init, - s3_close, - s3_phoenix_trio64_available, - s3_speed_changed, - s3_force_redraw, - s3_add_status_info, - s3_phoenix_trio64_config - }; +device_t s3_phoenix_trio64_device = {"Phoenix S3 Trio64", + 0, + s3_phoenix_trio64_init, + s3_close, + s3_phoenix_trio64_available, + s3_speed_changed, + s3_force_redraw, + s3_add_status_info, + s3_phoenix_trio64_config}; diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index 07c5cdf8..20e9aac0 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -27,13 +27,12 @@ static uint64_t virge_time = 0; static uint64_t status_time = 0; static int reg_writes = 0, reg_reads = 0; -static int dither[4][4] = - { - {0, 4, 1, 5}, - {6, 2, 7, 3}, - {1, 5, 0, 4}, - {7, 3, 6, 2}, - }; +static int dither[4][4] = { + {0, 4, 1, 5}, + {6, 2, 7, 3}, + {1, 5, 0, 4}, + {7, 3, 6, 2}, +}; #define RB_SIZE 256 #define RB_MASK (RB_SIZE - 1) @@ -47,195 +46,195 @@ static int dither[4][4] = #define FIFO_ENTRY_SIZE (1 << 31) #define FIFO_ENTRIES (virge->fifo_write_idx - virge->fifo_read_idx) -#define FIFO_FULL ((virge->fifo_write_idx - virge->fifo_read_idx) >= FIFO_SIZE) -#define FIFO_EMPTY (virge->fifo_read_idx == virge->fifo_write_idx) +#define FIFO_FULL ((virge->fifo_write_idx - virge->fifo_read_idx) >= FIFO_SIZE) +#define FIFO_EMPTY (virge->fifo_read_idx == virge->fifo_write_idx) #define FIFO_TYPE 0xff000000 #define FIFO_ADDR 0x00ffffff enum { - FIFO_INVALID = (0x00 << 24), - FIFO_WRITE_BYTE = (0x01 << 24), - FIFO_WRITE_WORD = (0x02 << 24), - FIFO_WRITE_DWORD = (0x03 << 24), + FIFO_INVALID = (0x00 << 24), + FIFO_WRITE_BYTE = (0x01 << 24), + FIFO_WRITE_WORD = (0x02 << 24), + FIFO_WRITE_DWORD = (0x03 << 24), }; typedef struct { - uint32_t addr_type; - uint32_t val; + uint32_t addr_type; + uint32_t val; } fifo_entry_t; typedef struct s3d_t { - uint32_t cmd_set; - int clip_l, clip_r, clip_t, clip_b; + uint32_t cmd_set; + int clip_l, clip_r, clip_t, clip_b; - uint32_t dest_base; - uint32_t dest_str; + uint32_t dest_base; + uint32_t dest_str; - uint32_t z_base; - uint32_t z_str; + uint32_t z_base; + uint32_t z_str; - uint32_t tex_base; - uint32_t tex_bdr_clr; - uint32_t tbv, tbu; - int32_t TdVdX, TdUdX; - int32_t TdVdY, TdUdY; - uint32_t tus, tvs; + uint32_t tex_base; + uint32_t tex_bdr_clr; + uint32_t tbv, tbu; + int32_t TdVdX, TdUdX; + int32_t TdVdY, TdUdY; + uint32_t tus, tvs; - int32_t TdZdX, TdZdY; - uint32_t tzs; + int32_t TdZdX, TdZdY; + uint32_t tzs; - int32_t TdWdX, TdWdY; - uint32_t tws; + int32_t TdWdX, TdWdY; + uint32_t tws; - int32_t TdDdX, TdDdY; - uint32_t tds; + int32_t TdDdX, TdDdY; + uint32_t tds; - int16_t TdGdX, TdBdX, TdRdX, TdAdX; - int16_t TdGdY, TdBdY, TdRdY, TdAdY; - uint32_t tgs, tbs, trs, tas; + int16_t TdGdX, TdBdX, TdRdX, TdAdX; + int16_t TdGdY, TdBdY, TdRdY, TdAdY; + uint32_t tgs, tbs, trs, tas; - uint32_t TdXdY12; - uint32_t txend12; - uint32_t TdXdY01; - uint32_t txend01; - uint32_t TdXdY02; - uint32_t txs; - uint32_t tys; - int ty01, ty12, tlr; + uint32_t TdXdY12; + uint32_t txend12; + uint32_t TdXdY01; + uint32_t txend01; + uint32_t TdXdY02; + uint32_t txs; + uint32_t tys; + int ty01, ty12, tlr; } s3d_t; typedef struct virge_t { - mem_mapping_t linear_mapping; - mem_mapping_t mmio_mapping; - mem_mapping_t new_mmio_mapping; + mem_mapping_t linear_mapping; + mem_mapping_t mmio_mapping; + mem_mapping_t new_mmio_mapping; - rom_t bios_rom; + rom_t bios_rom; - svga_t svga; + svga_t svga; - uint8_t bank; - uint8_t ma_ext; + uint8_t bank; + uint8_t ma_ext; - uint8_t virge_id, virge_id_high, virge_id_low, virge_rev; + uint8_t virge_id, virge_id_high, virge_id_low, virge_rev; - uint32_t linear_base, linear_size; + uint32_t linear_base, linear_size; - uint8_t pci_regs[256]; - int card; + uint8_t pci_regs[256]; + int card; - int is_375; + int is_375; - int bilinear_enabled; - int dithering_enabled; - int memory_size; + int bilinear_enabled; + int dithering_enabled; + int memory_size; - int pixel_count, tri_count; + int pixel_count, tri_count; - thread_t *render_thread; - event_t *wake_render_thread; - event_t *wake_main_thread; - event_t *not_full_event; + thread_t *render_thread; + event_t *wake_render_thread; + event_t *wake_main_thread; + event_t *not_full_event; - uint32_t hwc_fg_col, hwc_bg_col; - int hwc_col_stack_pos; + uint32_t hwc_fg_col, hwc_bg_col; + int hwc_col_stack_pos; - struct { - uint32_t src_base; - uint32_t dest_base; - int clip_l, clip_r, clip_t, clip_b; - int dest_str, src_str; - uint32_t mono_pat_0; - uint32_t mono_pat_1; - uint32_t pat_bg_clr; - uint32_t pat_fg_clr; - uint32_t src_bg_clr; - uint32_t src_fg_clr; - uint32_t cmd_set; - int r_width, r_height; - int rsrc_x, rsrc_y; - int rdest_x, rdest_y; + struct { + uint32_t src_base; + uint32_t dest_base; + int clip_l, clip_r, clip_t, clip_b; + int dest_str, src_str; + uint32_t mono_pat_0; + uint32_t mono_pat_1; + uint32_t pat_bg_clr; + uint32_t pat_fg_clr; + uint32_t src_bg_clr; + uint32_t src_fg_clr; + uint32_t cmd_set; + int r_width, r_height; + int rsrc_x, rsrc_y; + int rdest_x, rdest_y; - int lxend0, lxend1; - int32_t ldx; - uint32_t lxstart, lystart; - int lycnt; - int line_dir; + int lxend0, lxend1; + int32_t ldx; + uint32_t lxstart, lystart; + int lycnt; + int line_dir; - int src_x, src_y; - int dest_x, dest_y; - int w, h; - uint8_t rop; + int src_x, src_y; + int dest_x, dest_y; + int w, h; + uint8_t rop; - int data_left_count; - uint32_t data_left; + int data_left_count; + uint32_t data_left; - uint32_t pattern_8[8 * 8]; - uint32_t pattern_16[8 * 8]; - uint32_t pattern_32[8 * 8]; + uint32_t pattern_8[8 * 8]; + uint32_t pattern_16[8 * 8]; + uint32_t pattern_32[8 * 8]; - uint32_t prdx; - uint32_t prxstart; - uint32_t pldx; - uint32_t plxstart; - uint32_t pystart; - uint32_t pycnt; - uint32_t dest_l, dest_r; - } s3d; + uint32_t prdx; + uint32_t prxstart; + uint32_t pldx; + uint32_t plxstart; + uint32_t pystart; + uint32_t pycnt; + uint32_t dest_l, dest_r; + } s3d; - s3d_t s3d_tri; + s3d_t s3d_tri; - s3d_t s3d_buffer[RB_SIZE]; - int s3d_read_idx, s3d_write_idx; - int s3d_busy; + s3d_t s3d_buffer[RB_SIZE]; + int s3d_read_idx, s3d_write_idx; + int s3d_busy; - struct { - uint32_t pri_ctrl; - uint32_t chroma_ctrl; - uint32_t sec_ctrl; - uint32_t chroma_upper_bound; - uint32_t sec_filter; - uint32_t blend_ctrl; - uint32_t pri_fb0, pri_fb1; - uint32_t pri_stride; - uint32_t buffer_ctrl; - uint32_t sec_fb0, sec_fb1; - uint32_t sec_stride; - uint32_t overlay_ctrl; - int32_t k1_vert_scale; - int32_t k2_vert_scale; - int32_t dda_vert_accumulator; - int32_t k1_horiz_scale; - int32_t k2_horiz_scale; - int32_t dda_horiz_accumulator; - uint32_t fifo_ctrl; - uint32_t pri_start; - uint32_t pri_size; - uint32_t sec_start; - uint32_t sec_size; + struct { + uint32_t pri_ctrl; + uint32_t chroma_ctrl; + uint32_t sec_ctrl; + uint32_t chroma_upper_bound; + uint32_t sec_filter; + uint32_t blend_ctrl; + uint32_t pri_fb0, pri_fb1; + uint32_t pri_stride; + uint32_t buffer_ctrl; + uint32_t sec_fb0, sec_fb1; + uint32_t sec_stride; + uint32_t overlay_ctrl; + int32_t k1_vert_scale; + int32_t k2_vert_scale; + int32_t dda_vert_accumulator; + int32_t k1_horiz_scale; + int32_t k2_horiz_scale; + int32_t dda_horiz_accumulator; + uint32_t fifo_ctrl; + uint32_t pri_start; + uint32_t pri_size; + uint32_t sec_start; + uint32_t sec_size; - int sdif; + int sdif; - int pri_x, pri_y, pri_w, pri_h; - int sec_x, sec_y, sec_w, sec_h; - } streams; + int pri_x, pri_y, pri_w, pri_h; + int sec_x, sec_y, sec_w, sec_h; + } streams; - fifo_entry_t fifo[FIFO_SIZE]; - volatile int fifo_read_idx, fifo_write_idx; + fifo_entry_t fifo[FIFO_SIZE]; + volatile int fifo_read_idx, fifo_write_idx; - thread_t *fifo_thread; - event_t *wake_fifo_thread; - event_t *fifo_not_full_event; + thread_t *fifo_thread; + event_t *wake_fifo_thread; + event_t *fifo_not_full_event; - int virge_busy; + int virge_busy; - uint8_t subsys_stat, subsys_cntl; + uint8_t subsys_stat, subsys_cntl; - uint8_t serialport; + uint8_t serialport; } virge_t; static inline void wake_fifo_thread(virge_t *virge) { - thread_set_event(virge->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ + thread_set_event(virge->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ } static void queue_triangle(virge_t *virge); @@ -253,51 +252,51 @@ static void s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *p); static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p); enum { - CMD_SET_AE = 1, - CMD_SET_HC = (1 << 1), + CMD_SET_AE = 1, + CMD_SET_HC = (1 << 1), - CMD_SET_FORMAT_MASK = (7 << 2), - CMD_SET_FORMAT_8 = (0 << 2), - CMD_SET_FORMAT_16 = (1 << 2), - CMD_SET_FORMAT_24 = (2 << 2), + CMD_SET_FORMAT_MASK = (7 << 2), + CMD_SET_FORMAT_8 = (0 << 2), + CMD_SET_FORMAT_16 = (1 << 2), + CMD_SET_FORMAT_24 = (2 << 2), - CMD_SET_MS = (1 << 6), - CMD_SET_IDS = (1 << 7), - CMD_SET_MP = (1 << 8), - CMD_SET_TP = (1 << 9), + CMD_SET_MS = (1 << 6), + CMD_SET_IDS = (1 << 7), + CMD_SET_MP = (1 << 8), + CMD_SET_TP = (1 << 9), - CMD_SET_ITA_MASK = (3 << 10), - CMD_SET_ITA_BYTE = (0 << 10), - CMD_SET_ITA_WORD = (1 << 10), - CMD_SET_ITA_DWORD = (2 << 10), + CMD_SET_ITA_MASK = (3 << 10), + CMD_SET_ITA_BYTE = (0 << 10), + CMD_SET_ITA_WORD = (1 << 10), + CMD_SET_ITA_DWORD = (2 << 10), - CMD_SET_ZUP = (1 << 23), + CMD_SET_ZUP = (1 << 23), - CMD_SET_ZB_MODE = (3 << 24), + CMD_SET_ZB_MODE = (3 << 24), - CMD_SET_XP = (1 << 25), - CMD_SET_YP = (1 << 26), + CMD_SET_XP = (1 << 25), + CMD_SET_YP = (1 << 26), - CMD_SET_COMMAND_MASK = (15 << 27) + CMD_SET_COMMAND_MASK = (15 << 27) }; -#define CMD_SET_ABC_SRC (1 << 18) +#define CMD_SET_ABC_SRC (1 << 18) #define CMD_SET_ABC_ENABLE (1 << 19) -#define CMD_SET_TWE (1 << 26) +#define CMD_SET_TWE (1 << 26) enum { - CMD_SET_COMMAND_BITBLT = (0 << 27), - CMD_SET_COMMAND_RECTFILL = (2 << 27), - CMD_SET_COMMAND_LINE = (3 << 27), - CMD_SET_COMMAND_POLY = (5 << 27), - CMD_SET_COMMAND_NOP = (15 << 27) + CMD_SET_COMMAND_BITBLT = (0 << 27), + CMD_SET_COMMAND_RECTFILL = (2 << 27), + CMD_SET_COMMAND_LINE = (3 << 27), + CMD_SET_COMMAND_POLY = (5 << 27), + CMD_SET_COMMAND_NOP = (15 << 27) }; -#define INT_VSY (1 << 0) +#define INT_VSY (1 << 0) #define INT_S3D_DONE (1 << 1) #define INT_FIFO_OVF (1 << 2) #define INT_FIFO_EMP (1 << 3) -#define INT_3DF_EMP (1 << 6) +#define INT_3DF_EMP (1 << 6) #define INT_MASK 0xff #define SERIAL_PORT_SCW (1 << 0) @@ -306,2084 +305,2365 @@ enum { #define SERIAL_PORT_SDR (1 << 3) static void s3_virge_update_irqs(virge_t *virge) { - if ((virge->svga.crtc[0x32] & 0x10) && (virge->subsys_stat & virge->subsys_cntl & INT_MASK)) - pci_set_irq(virge->card, PCI_INTA); - else - pci_clear_irq(virge->card, PCI_INTA); + if ((virge->svga.crtc[0x32] & 0x10) && (virge->subsys_stat & virge->subsys_cntl & INT_MASK)) + pci_set_irq(virge->card, PCI_INTA); + else + pci_clear_irq(virge->card, PCI_INTA); } static void s3_virge_out(uint16_t addr, uint8_t val, void *p) { - virge_t *virge = (virge_t *)p; - svga_t *svga = &virge->svga; - uint8_t old; + virge_t *virge = (virge_t *)p; + svga_t *svga = &virge->svga; + uint8_t old; - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; -// pclog("S3 out %04X %02X %04X:%08X %04X %04X %i\n", addr, val, CS, pc, ES, BX, ins); + // pclog("S3 out %04X %02X %04X:%08X %04X %04X %i\n", addr, val, CS, pc, ES, BX, ins); - switch (addr) { - case 0x3c5: - if (svga->seqaddr >= 0x10) { - svga->seqregs[svga->seqaddr & 0x1f] = val; - svga_recalctimings(svga); - return; - } - if (svga->seqaddr == 4) /*Chain-4 - update banking*/ - { - if (val & 8) - svga->write_bank = svga->read_bank = virge->bank << 16; - else - svga->write_bank = svga->read_bank = virge->bank << 14; - } - break; + switch (addr) { + case 0x3c5: + if (svga->seqaddr >= 0x10) { + svga->seqregs[svga->seqaddr & 0x1f] = val; + svga_recalctimings(svga); + return; + } + if (svga->seqaddr == 4) /*Chain-4 - update banking*/ + { + if (val & 8) + svga->write_bank = svga->read_bank = virge->bank << 16; + else + svga->write_bank = svga->read_bank = virge->bank << 14; + } + break; - //case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: -// pclog("Write RAMDAC %04X %02X %04X:%04X\n", addr, val, CS, pc); - //sdac_ramdac_out(addr,val); - //return; + // case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: + // pclog("Write RAMDAC %04X %02X %04X:%04X\n", addr, val, CS, pc); + // sdac_ramdac_out(addr,val); + // return; - case 0x3d4:svga->crtcreg = val;// & 0x7f; - return; - case 0x3d5: - //pclog("Write CRTC R%02X %02X %04x(%08x):%08x\n", svga->crtcreg, val, CS, cs, pc); - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) - return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); - if (svga->crtcreg >= 0x20 && svga->crtcreg != 0x38 && (svga->crtc[0x38] & 0xcc) != 0x48) - return; - if (svga->crtcreg >= 0x80) - return; - old = svga->crtc[svga->crtcreg]; - svga->crtc[svga->crtcreg] = val; - switch (svga->crtcreg) { - case 0x31:virge->ma_ext = (virge->ma_ext & 0x1c) | ((val & 0x30) >> 4); - break; - case 0x32:s3_virge_update_irqs(virge); - break; + case 0x3d4: + svga->crtcreg = val; // & 0x7f; + return; + case 0x3d5: + // pclog("Write CRTC R%02X %02X %04x(%08x):%08x\n", svga->crtcreg, val, CS, cs, pc); + if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) + return; + if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) + val = (svga->crtc[7] & ~0x10) | (val & 0x10); + if (svga->crtcreg >= 0x20 && svga->crtcreg != 0x38 && (svga->crtc[0x38] & 0xcc) != 0x48) + return; + if (svga->crtcreg >= 0x80) + return; + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; + switch (svga->crtcreg) { + case 0x31: + virge->ma_ext = (virge->ma_ext & 0x1c) | ((val & 0x30) >> 4); + break; + case 0x32: + s3_virge_update_irqs(virge); + break; - case 0x69:virge->ma_ext = val & 0x1f; - break; + case 0x69: + virge->ma_ext = val & 0x1f; + break; - case 0x35:virge->bank = (virge->bank & 0x70) | (val & 0xf); -// pclog("CRTC write R35 %02X\n", val); - if (svga->chain4) - svga->write_bank = svga->read_bank = virge->bank << 16; - else - svga->write_bank = svga->read_bank = virge->bank << 14; - break; - case 0x51:virge->bank = (virge->bank & 0x4f) | ((val & 0xc) << 2); - if (svga->chain4) - svga->write_bank = svga->read_bank = virge->bank << 16; - else - svga->write_bank = svga->read_bank = virge->bank << 14; - virge->ma_ext = (virge->ma_ext & ~0xc) | ((val & 3) << 2); - break; - case 0x6a:virge->bank = val; -// pclog("CRTC write R6a %02X\n", val); - if (svga->chain4) - svga->write_bank = svga->read_bank = virge->bank << 16; - else - svga->write_bank = svga->read_bank = virge->bank << 14; - break; + case 0x35: + virge->bank = (virge->bank & 0x70) | (val & 0xf); + // pclog("CRTC write R35 %02X\n", val); + if (svga->chain4) + svga->write_bank = svga->read_bank = virge->bank << 16; + else + svga->write_bank = svga->read_bank = virge->bank << 14; + break; + case 0x51: + virge->bank = (virge->bank & 0x4f) | ((val & 0xc) << 2); + if (svga->chain4) + svga->write_bank = svga->read_bank = virge->bank << 16; + else + svga->write_bank = svga->read_bank = virge->bank << 14; + virge->ma_ext = (virge->ma_ext & ~0xc) | ((val & 3) << 2); + break; + case 0x6a: + virge->bank = val; + // pclog("CRTC write R6a %02X\n", val); + if (svga->chain4) + svga->write_bank = svga->read_bank = virge->bank << 16; + else + svga->write_bank = svga->read_bank = virge->bank << 14; + break; - case 0x3a: - if (val & 0x10) - svga->gdcreg[5] |= 0x40; /*Horrible cheat*/ - break; + case 0x3a: + if (val & 0x10) + svga->gdcreg[5] |= 0x40; /*Horrible cheat*/ + break; - case 0x45:svga->hwcursor.ena = val & 1; - break; - case 0x46: - case 0x47: - case 0x48: - case 0x49: - case 0x4c: - case 0x4d: - case 0x4e: - case 0x4f:svga->hwcursor.x = ((svga->crtc[0x46] << 8) | svga->crtc[0x47]) & 0x7ff; - svga->hwcursor.y = ((svga->crtc[0x48] << 8) | svga->crtc[0x49]) & 0x7ff; - svga->hwcursor.xoff = svga->crtc[0x4e] & 63; - svga->hwcursor.yoff = svga->crtc[0x4f] & 63; - svga->hwcursor.addr = ((((svga->crtc[0x4c] << 8) | svga->crtc[0x4d]) & 0xfff) * 1024) + (svga->hwcursor.yoff * 16); - break; + case 0x45: + svga->hwcursor.ena = val & 1; + break; + case 0x46: + case 0x47: + case 0x48: + case 0x49: + case 0x4c: + case 0x4d: + case 0x4e: + case 0x4f: + svga->hwcursor.x = ((svga->crtc[0x46] << 8) | svga->crtc[0x47]) & 0x7ff; + svga->hwcursor.y = ((svga->crtc[0x48] << 8) | svga->crtc[0x49]) & 0x7ff; + svga->hwcursor.xoff = svga->crtc[0x4e] & 63; + svga->hwcursor.yoff = svga->crtc[0x4f] & 63; + svga->hwcursor.addr = + ((((svga->crtc[0x4c] << 8) | svga->crtc[0x4d]) & 0xfff) * 1024) + (svga->hwcursor.yoff * 16); + break; - case 0x4a: - switch (virge->hwc_col_stack_pos) { - case 0:virge->hwc_fg_col = (virge->hwc_fg_col & 0xffff00) | val; - break; - case 1:virge->hwc_fg_col = (virge->hwc_fg_col & 0xff00ff) | (val << 8); - break; - case 2:virge->hwc_fg_col = (virge->hwc_fg_col & 0x00ffff) | (val << 16); - break; - } - virge->hwc_col_stack_pos = (virge->hwc_col_stack_pos + 1) & 3; - break; - case 0x4b: - switch (virge->hwc_col_stack_pos) { - case 0:virge->hwc_bg_col = (virge->hwc_bg_col & 0xffff00) | val; - break; - case 1:virge->hwc_bg_col = (virge->hwc_bg_col & 0xff00ff) | (val << 8); - break; - case 2:virge->hwc_bg_col = (virge->hwc_bg_col & 0x00ffff) | (val << 16); - break; - } - virge->hwc_col_stack_pos = (virge->hwc_col_stack_pos + 1) & 3; - break; + case 0x4a: + switch (virge->hwc_col_stack_pos) { + case 0: + virge->hwc_fg_col = (virge->hwc_fg_col & 0xffff00) | val; + break; + case 1: + virge->hwc_fg_col = (virge->hwc_fg_col & 0xff00ff) | (val << 8); + break; + case 2: + virge->hwc_fg_col = (virge->hwc_fg_col & 0x00ffff) | (val << 16); + break; + } + virge->hwc_col_stack_pos = (virge->hwc_col_stack_pos + 1) & 3; + break; + case 0x4b: + switch (virge->hwc_col_stack_pos) { + case 0: + virge->hwc_bg_col = (virge->hwc_bg_col & 0xffff00) | val; + break; + case 1: + virge->hwc_bg_col = (virge->hwc_bg_col & 0xff00ff) | (val << 8); + break; + case 2: + virge->hwc_bg_col = (virge->hwc_bg_col & 0x00ffff) | (val << 16); + break; + } + virge->hwc_col_stack_pos = (virge->hwc_col_stack_pos + 1) & 3; + break; - case 0x53: - case 0x58: - case 0x59: - case 0x5a:s3_virge_updatemapping(virge); - break; + case 0x53: + case 0x58: + case 0x59: + case 0x5a: + s3_virge_updatemapping(virge); + break; - case 0x67: - switch (val >> 4) { - case 3:svga->bpp = 15; - break; - case 5:svga->bpp = 16; - break; - case 7:svga->bpp = 24; - break; - case 13:svga->bpp = 32; - break; - default:svga->bpp = 8; - break; - } - break; - //case 0x55: case 0x43: -// pclog("Write CRTC R%02X %02X\n", crtcreg, val); - } - if (old != val) { - if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - } - break; - } - svga_out(addr, val, svga); + case 0x67: + switch (val >> 4) { + case 3: + svga->bpp = 15; + break; + case 5: + svga->bpp = 16; + break; + case 7: + svga->bpp = 24; + break; + case 13: + svga->bpp = 32; + break; + default: + svga->bpp = 8; + break; + } + break; + // case 0x55: case 0x43: + // pclog("Write CRTC R%02X %02X\n", crtcreg, val); + } + if (old != val) { + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } + } + break; + } + svga_out(addr, val, svga); } static uint8_t s3_virge_in(uint16_t addr, void *p) { - virge_t *virge = (virge_t *)p; - svga_t *svga = &virge->svga; - uint8_t ret; + virge_t *virge = (virge_t *)p; + svga_t *svga = &virge->svga; + uint8_t ret; - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; -// if (addr != 0x3da) pclog("S3 in %04X %04X:%08X ", addr, CS, pc); - switch (addr) { - case 0x3c1: - if (svga->attraddr > 0x14) - ret = 0xff; - else - ret = svga_in(addr, svga); - break; - //case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: -// pclog("Read RAMDAC %04X %04X:%04X\n", addr, CS, pc); - //return sdac_ramdac_in(addr); + // if (addr != 0x3da) pclog("S3 in %04X %04X:%08X ", addr, CS, pc); + switch (addr) { + case 0x3c1: + if (svga->attraddr > 0x14) + ret = 0xff; + else + ret = svga_in(addr, svga); + break; + // case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: + // pclog("Read RAMDAC %04X %04X:%04X\n", addr, CS, pc); + // return sdac_ramdac_in(addr); - case 0x3c5: - if (svga->seqaddr >= 8) - ret = svga->seqregs[svga->seqaddr & 0x1f]; - else if (svga->seqaddr <= 4) - ret = svga_in(addr, svga); - else - ret = 0xff; - break; + case 0x3c5: + if (svga->seqaddr >= 8) + ret = svga->seqregs[svga->seqaddr & 0x1f]; + else if (svga->seqaddr <= 4) + ret = svga_in(addr, svga); + else + ret = 0xff; + break; - case 0x3D4:ret = svga->crtcreg; - break; - case 0x3D5: - //pclog("Read CRTC R%02X %04X:%04X (%02x)\n", svga->crtcreg, CS, pc, svga->crtc[svga->crtcreg]); - switch (svga->crtcreg) { - case 0x2d:ret = virge->virge_id_high; - break; /*Extended chip ID*/ - case 0x2e:ret = virge->virge_id_low; - break; /*New chip ID*/ - case 0x2f:ret = virge->virge_rev; - break; - case 0x30:ret = virge->virge_id; - break; /*Chip ID*/ - case 0x31:ret = (svga->crtc[0x31] & 0xcf) | ((virge->ma_ext & 3) << 4); - break; - case 0x35:ret = (svga->crtc[0x35] & 0xf0) | (virge->bank & 0xf); - break; - case 0x36:ret = (svga->crtc[0x36] & 0xfc) | 2; - break; /*PCI bus*/ - case 0x45:virge->hwc_col_stack_pos = 0; - ret = svga->crtc[0x45]; - break; - case 0x51:ret = (svga->crtc[0x51] & 0xf0) | ((virge->bank >> 2) & 0xc) | ((virge->ma_ext >> 2) & 3); - break; - case 0x69:ret = virge->ma_ext; - break; - case 0x6a:ret = virge->bank; - break; - default:ret = svga->crtc[svga->crtcreg]; - break; - } - break; + case 0x3D4: + ret = svga->crtcreg; + break; + case 0x3D5: + // pclog("Read CRTC R%02X %04X:%04X (%02x)\n", svga->crtcreg, CS, pc, svga->crtc[svga->crtcreg]); + switch (svga->crtcreg) { + case 0x2d: + ret = virge->virge_id_high; + break; /*Extended chip ID*/ + case 0x2e: + ret = virge->virge_id_low; + break; /*New chip ID*/ + case 0x2f: + ret = virge->virge_rev; + break; + case 0x30: + ret = virge->virge_id; + break; /*Chip ID*/ + case 0x31: + ret = (svga->crtc[0x31] & 0xcf) | ((virge->ma_ext & 3) << 4); + break; + case 0x35: + ret = (svga->crtc[0x35] & 0xf0) | (virge->bank & 0xf); + break; + case 0x36: + ret = (svga->crtc[0x36] & 0xfc) | 2; + break; /*PCI bus*/ + case 0x45: + virge->hwc_col_stack_pos = 0; + ret = svga->crtc[0x45]; + break; + case 0x51: + ret = (svga->crtc[0x51] & 0xf0) | ((virge->bank >> 2) & 0xc) | ((virge->ma_ext >> 2) & 3); + break; + case 0x69: + ret = virge->ma_ext; + break; + case 0x6a: + ret = virge->bank; + break; + default: + ret = svga->crtc[svga->crtcreg]; + break; + } + break; - default:ret = svga_in(addr, svga); - break; - } -// if (addr != 0x3da) pclog("%02X\n", ret); - return ret; + default: + ret = svga_in(addr, svga); + break; + } + // if (addr != 0x3da) pclog("%02X\n", ret); + return ret; } static void s3_virge_recalctimings(svga_t *svga) { - virge_t *virge = (virge_t *)svga->p; + virge_t *virge = (virge_t *)svga->p; - if (svga->crtc[0x5d] & 0x01) - svga->htotal += 0x100; - if (svga->crtc[0x5d] & 0x02) - svga->hdisp += 0x100; - if (svga->crtc[0x5e] & 0x01) - svga->vtotal += 0x400; - if (svga->crtc[0x5e] & 0x02) - svga->dispend += 0x400; - if (svga->crtc[0x5e] & 0x04) - svga->vblankstart += 0x400; - if (svga->crtc[0x5e] & 0x10) - svga->vsyncstart += 0x400; - if (svga->crtc[0x5e] & 0x40) - svga->split += 0x400; - svga->interlace = svga->crtc[0x42] & 0x20; + if (svga->crtc[0x5d] & 0x01) + svga->htotal += 0x100; + if (svga->crtc[0x5d] & 0x02) + svga->hdisp += 0x100; + if (svga->crtc[0x5e] & 0x01) + svga->vtotal += 0x400; + if (svga->crtc[0x5e] & 0x02) + svga->dispend += 0x400; + if (svga->crtc[0x5e] & 0x04) + svga->vblankstart += 0x400; + if (svga->crtc[0x5e] & 0x10) + svga->vsyncstart += 0x400; + if (svga->crtc[0x5e] & 0x40) + svga->split += 0x400; + svga->interlace = svga->crtc[0x42] & 0x20; - if ((svga->crtc[0x67] & 0xc) != 0xc) /*VGA mode*/ - { - svga->ma_latch |= (virge->ma_ext << 16); -//pclog("VGA mode\n"); - if (svga->crtc[0x51] & 0x30) - svga->rowoffset += (svga->crtc[0x51] & 0x30) << 4; - else if (svga->crtc[0x43] & 0x04) - svga->rowoffset += 0x100; - if (!svga->rowoffset) - svga->rowoffset = 256; + if ((svga->crtc[0x67] & 0xc) != 0xc) /*VGA mode*/ + { + svga->ma_latch |= (virge->ma_ext << 16); + // pclog("VGA mode\n"); + if (svga->crtc[0x51] & 0x30) + svga->rowoffset += (svga->crtc[0x51] & 0x30) << 4; + else if (svga->crtc[0x43] & 0x04) + svga->rowoffset += 0x100; + if (!svga->rowoffset) + svga->rowoffset = 256; - if ((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)) { - switch (svga->bpp) { - case 8:svga->render = svga_render_8bpp_highres; - break; - case 15:svga->render = svga_render_15bpp_highres; - break; - case 16:svga->render = svga_render_16bpp_highres; - break; - case 24:svga->render = svga_render_24bpp_highres; - break; - case 32:svga->render = svga_render_32bpp_highres; - break; - } - } + if ((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)) { + switch (svga->bpp) { + case 8: + svga->render = svga_render_8bpp_highres; + break; + case 15: + svga->render = svga_render_15bpp_highres; + break; + case 16: + svga->render = svga_render_16bpp_highres; + break; + case 24: + svga->render = svga_render_24bpp_highres; + break; + case 32: + svga->render = svga_render_32bpp_highres; + break; + } + } -// pclog("svga->rowoffset = %i bpp=%i\n", svga->rowoffset, svga->bpp); - if (svga->bpp == 15 || svga->bpp == 16) { - svga->htotal >>= 1; - svga->hdisp >>= 1; - } - if (svga->bpp == 24) { - svga->rowoffset = (svga->rowoffset * 3) / 4; /*Hack*/ - } - svga->vram_display_mask = (!(svga->crtc[0x31] & 0x08) && (svga->crtc[0x32] & 0x40)) ? 0x3ffff : ((virge->memory_size << 20) - 1); -//pclog("VGA mode x_disp=%i dispend=%i vtotal=%i\n", svga->hdisp, svga->dispend, svga->vtotal); - } else /*Streams mode*/ - { - if (virge->streams.buffer_ctrl & 1) - svga->ma_latch = virge->streams.pri_fb1 >> 2; - else - svga->ma_latch = virge->streams.pri_fb0 >> 2; + // pclog("svga->rowoffset = %i bpp=%i\n", svga->rowoffset, svga->bpp); + if (svga->bpp == 15 || svga->bpp == 16) { + svga->htotal >>= 1; + svga->hdisp >>= 1; + } + if (svga->bpp == 24) { + svga->rowoffset = (svga->rowoffset * 3) / 4; /*Hack*/ + } + svga->vram_display_mask = + (!(svga->crtc[0x31] & 0x08) && (svga->crtc[0x32] & 0x40)) ? 0x3ffff : ((virge->memory_size << 20) - 1); + // pclog("VGA mode x_disp=%i dispend=%i vtotal=%i\n", svga->hdisp, svga->dispend, svga->vtotal); + } else /*Streams mode*/ + { + if (virge->streams.buffer_ctrl & 1) + svga->ma_latch = virge->streams.pri_fb1 >> 2; + else + svga->ma_latch = virge->streams.pri_fb0 >> 2; - svga->hdisp = virge->streams.pri_w + 1; - if (virge->streams.pri_h < svga->dispend) - svga->dispend = virge->streams.pri_h; + svga->hdisp = virge->streams.pri_w + 1; + if (virge->streams.pri_h < svga->dispend) + svga->dispend = virge->streams.pri_h; - svga->overlay.x = virge->streams.sec_x - virge->streams.pri_x; - svga->overlay.y = virge->streams.sec_y - virge->streams.pri_y; - svga->overlay.ysize = virge->streams.sec_h; + svga->overlay.x = virge->streams.sec_x - virge->streams.pri_x; + svga->overlay.y = virge->streams.sec_y - virge->streams.pri_y; + svga->overlay.ysize = virge->streams.sec_h; - if (virge->streams.buffer_ctrl & 2) - svga->overlay.addr = virge->streams.sec_fb1; - else - svga->overlay.addr = virge->streams.sec_fb0; + if (virge->streams.buffer_ctrl & 2) + svga->overlay.addr = virge->streams.sec_fb1; + else + svga->overlay.addr = virge->streams.sec_fb0; - svga->overlay.ena = (svga->overlay.x >= 0); - svga->overlay.v_acc = virge->streams.dda_vert_accumulator; -//pclog("Streams mode x_disp=%i dispend=%i vtotal=%i x=%i y=%i ysize=%i\n", svga->hdisp, svga->dispend, svga->vtotal, svga->overlay.x, svga->overlay.y, svga->overlay.ysize); - svga->rowoffset = virge->streams.pri_stride >> 3; + svga->overlay.ena = (svga->overlay.x >= 0); + svga->overlay.v_acc = virge->streams.dda_vert_accumulator; + // pclog("Streams mode x_disp=%i dispend=%i vtotal=%i x=%i y=%i ysize=%i\n", svga->hdisp, svga->dispend, + // svga->vtotal, svga->overlay.x, svga->overlay.y, svga->overlay.ysize); + svga->rowoffset = virge->streams.pri_stride >> 3; - switch ((virge->streams.pri_ctrl >> 24) & 0x7) { - case 0: /*RGB-8 (CLUT)*/ - svga->render = svga_render_8bpp_highres; - break; - case 3: /*KRGB-16 (1.5.5.5)*/ - svga->htotal >>= 1; - svga->render = svga_render_15bpp_highres; - break; - case 5: /*RGB-16 (5.6.5)*/ - svga->htotal >>= 1; - svga->render = svga_render_16bpp_highres; - break; - case 6: /*RGB-24 (8.8.8)*/ - svga->render = svga_render_24bpp_highres; - break; - case 7: /*XRGB-32 (X.8.8.8)*/ - svga->render = svga_render_32bpp_highres; - break; - } - svga->vram_display_mask = (virge->memory_size << 20) - 1; - } + switch ((virge->streams.pri_ctrl >> 24) & 0x7) { + case 0: /*RGB-8 (CLUT)*/ + svga->render = svga_render_8bpp_highres; + break; + case 3: /*KRGB-16 (1.5.5.5)*/ + svga->htotal >>= 1; + svga->render = svga_render_15bpp_highres; + break; + case 5: /*RGB-16 (5.6.5)*/ + svga->htotal >>= 1; + svga->render = svga_render_16bpp_highres; + break; + case 6: /*RGB-24 (8.8.8)*/ + svga->render = svga_render_24bpp_highres; + break; + case 7: /*XRGB-32 (X.8.8.8)*/ + svga->render = svga_render_32bpp_highres; + break; + } + svga->vram_display_mask = (virge->memory_size << 20) - 1; + } - if (((svga->miscout >> 2) & 3) == 3) { - int n = svga->seqregs[0x12] & 0x1f; - int r = (svga->seqregs[0x12] >> 5) & (virge->is_375 ? 7 : 3); - int m = svga->seqregs[0x13] & 0x7f; - double freq = (((double)m + 2) / (((double)n + 2) * (double)(1 << r))) * 14318184.0; + if (((svga->miscout >> 2) & 3) == 3) { + int n = svga->seqregs[0x12] & 0x1f; + int r = (svga->seqregs[0x12] >> 5) & (virge->is_375 ? 7 : 3); + int m = svga->seqregs[0x13] & 0x7f; + double freq = (((double)m + 2) / (((double)n + 2) * (double)(1 << r))) * 14318184.0; - svga->clock = (cpuclock * (float)(1ull << 32)) / freq; - } + svga->clock = (cpuclock * (float)(1ull << 32)) / freq; + } } static void s3_virge_updatemapping(virge_t *virge) { - svga_t *svga = &virge->svga; + svga_t *svga = &virge->svga; - if (!(virge->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) { -// pclog("Update mapping - PCI disabled\n"); - mem_mapping_disable(&svga->mapping); - mem_mapping_disable(&virge->linear_mapping); - mem_mapping_disable(&virge->mmio_mapping); - mem_mapping_disable(&virge->new_mmio_mapping); - return; - } + if (!(virge->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) { + // pclog("Update mapping - PCI disabled\n"); + mem_mapping_disable(&svga->mapping); + mem_mapping_disable(&virge->linear_mapping); + mem_mapping_disable(&virge->mmio_mapping); + mem_mapping_disable(&virge->new_mmio_mapping); + return; + } - pclog("Update mapping - bank %02X ", svga->gdcreg[6] & 0xc); - switch (svga->gdcreg[6] & 0xc) /*Banked framebuffer*/ - { - case 0x0: /*128k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); - svga->banked_mask = 0xffff; - break; - case 0x4: /*64k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - svga->banked_mask = 0xffff; - break; - case 0x8: /*32k at B0000*/ - mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); - svga->banked_mask = 0x7fff; - break; - case 0xC: /*32k at B8000*/ - mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); - svga->banked_mask = 0x7fff; - break; - } + pclog("Update mapping - bank %02X ", svga->gdcreg[6] & 0xc); + switch (svga->gdcreg[6] & 0xc) /*Banked framebuffer*/ + { + case 0x0: /*128k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); + svga->banked_mask = 0xffff; + break; + case 0x4: /*64k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + svga->banked_mask = 0xffff; + break; + case 0x8: /*32k at B0000*/ + mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); + svga->banked_mask = 0x7fff; + break; + case 0xC: /*32k at B8000*/ + mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); + svga->banked_mask = 0x7fff; + break; + } - virge->linear_base = (svga->crtc[0x5a] << 16) | (svga->crtc[0x59] << 24); + virge->linear_base = (svga->crtc[0x5a] << 16) | (svga->crtc[0x59] << 24); - pclog("Linear framebuffer %02X ", svga->crtc[0x58] & 0x10); - if (svga->crtc[0x58] & 0x10) /*Linear framebuffer*/ - { - switch (svga->crtc[0x58] & 3) { - case 0: /*64k*/ - virge->linear_size = 0x10000; - break; - case 1: /*1mb*/ - virge->linear_size = 0x100000; - break; - case 2: /*2mb*/ - virge->linear_size = 0x200000; - break; - case 3: /*8mb*/ - virge->linear_size = 0x400000; - break; - } - virge->linear_base &= ~(virge->linear_size - 1); -// pclog("%08X %08X %02X %02X %02X\n", linear_base, linear_size, crtc[0x58], crtc[0x59], crtc[0x5a]); - pclog("Linear framebuffer at %08X size %08X\n", virge->linear_base, virge->linear_size); - if (virge->linear_base == 0xa0000) { - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - mem_mapping_disable(&virge->linear_mapping); - } else - mem_mapping_set_addr(&virge->linear_mapping, virge->linear_base, virge->linear_size); - svga->fb_only = 1; - } else { - mem_mapping_disable(&virge->linear_mapping); - svga->fb_only = 0; - } + pclog("Linear framebuffer %02X ", svga->crtc[0x58] & 0x10); + if (svga->crtc[0x58] & 0x10) /*Linear framebuffer*/ + { + switch (svga->crtc[0x58] & 3) { + case 0: /*64k*/ + virge->linear_size = 0x10000; + break; + case 1: /*1mb*/ + virge->linear_size = 0x100000; + break; + case 2: /*2mb*/ + virge->linear_size = 0x200000; + break; + case 3: /*8mb*/ + virge->linear_size = 0x400000; + break; + } + virge->linear_base &= ~(virge->linear_size - 1); + // pclog("%08X %08X %02X %02X %02X\n", linear_base, linear_size, crtc[0x58], crtc[0x59], + // crtc[0x5a]); + pclog("Linear framebuffer at %08X size %08X\n", virge->linear_base, virge->linear_size); + if (virge->linear_base == 0xa0000) { + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + mem_mapping_disable(&virge->linear_mapping); + } else + mem_mapping_set_addr(&virge->linear_mapping, virge->linear_base, virge->linear_size); + svga->fb_only = 1; + } else { + mem_mapping_disable(&virge->linear_mapping); + svga->fb_only = 0; + } - pclog("Memory mapped IO %02X\n", svga->crtc[0x53] & 0x18); - if (svga->crtc[0x53] & 0x10) /*Old MMIO*/ - { - if (svga->crtc[0x53] & 0x20) - mem_mapping_set_addr(&virge->mmio_mapping, 0xb8000, 0x8000); - else - mem_mapping_set_addr(&virge->mmio_mapping, 0xa0000, 0x10000); - } else - mem_mapping_disable(&virge->mmio_mapping); - - if (svga->crtc[0x53] & 0x08) /*New MMIO*/ - mem_mapping_set_addr(&virge->new_mmio_mapping, virge->linear_base + 0x1000000, 0x10000); - else - mem_mapping_disable(&virge->new_mmio_mapping); + pclog("Memory mapped IO %02X\n", svga->crtc[0x53] & 0x18); + if (svga->crtc[0x53] & 0x10) /*Old MMIO*/ + { + if (svga->crtc[0x53] & 0x20) + mem_mapping_set_addr(&virge->mmio_mapping, 0xb8000, 0x8000); + else + mem_mapping_set_addr(&virge->mmio_mapping, 0xa0000, 0x10000); + } else + mem_mapping_disable(&virge->mmio_mapping); + if (svga->crtc[0x53] & 0x08) /*New MMIO*/ + mem_mapping_set_addr(&virge->new_mmio_mapping, virge->linear_base + 0x1000000, 0x10000); + else + mem_mapping_disable(&virge->new_mmio_mapping); } static void s3_virge_vblank_start(svga_t *svga) { - virge_t *virge = (virge_t *)svga->p; + virge_t *virge = (virge_t *)svga->p; - virge->subsys_stat |= INT_VSY; - s3_virge_update_irqs(virge); + virge->subsys_stat |= INT_VSY; + s3_virge_update_irqs(virge); } static void s3_virge_wait_fifo_idle(virge_t *virge) { - while (!FIFO_EMPTY) { - wake_fifo_thread(virge); - thread_wait_event(virge->fifo_not_full_event, 1); - } + while (!FIFO_EMPTY) { + wake_fifo_thread(virge); + thread_wait_event(virge->fifo_not_full_event, 1); + } } static uint8_t s3_virge_mmio_read(uint32_t addr, void *p) { - virge_t *virge = (virge_t *)p; - uint8_t ret; + virge_t *virge = (virge_t *)p; + uint8_t ret; - reg_reads++; -// pclog("New MMIO readb %08X\n", addr); - switch (addr & 0xffff) { - case 0x8505: - if (virge->s3d_busy || virge->virge_busy || !FIFO_EMPTY) - ret = 0x10; - else - ret = 0x10 | (1 << 5); - if (!virge->virge_busy) - wake_fifo_thread(virge); - return ret; + reg_reads++; + // pclog("New MMIO readb %08X\n", addr); + switch (addr & 0xffff) { + case 0x8505: + if (virge->s3d_busy || virge->virge_busy || !FIFO_EMPTY) + ret = 0x10; + else + ret = 0x10 | (1 << 5); + if (!virge->virge_busy) + wake_fifo_thread(virge); + return ret; - case 0x83b0: - case 0x83b1: - case 0x83b2: - case 0x83b3: - case 0x83b4: - case 0x83b5: - case 0x83b6: - case 0x83b7: - case 0x83b8: - case 0x83b9: - case 0x83ba: - case 0x83bb: - case 0x83bc: - case 0x83bd: - case 0x83be: - case 0x83bf: - case 0x83c0: - case 0x83c1: - case 0x83c2: - case 0x83c3: - case 0x83c4: - case 0x83c5: - case 0x83c6: - case 0x83c7: - case 0x83c8: - case 0x83c9: - case 0x83ca: - case 0x83cb: - case 0x83cc: - case 0x83cd: - case 0x83ce: - case 0x83cf: - case 0x83d0: - case 0x83d1: - case 0x83d2: - case 0x83d3: - case 0x83d4: - case 0x83d5: - case 0x83d6: - case 0x83d7: - case 0x83d8: - case 0x83d9: - case 0x83da: - case 0x83db: - case 0x83dc: - case 0x83dd: - case 0x83de: - case 0x83df:return s3_virge_in(addr & 0x3ff, p); + case 0x83b0: + case 0x83b1: + case 0x83b2: + case 0x83b3: + case 0x83b4: + case 0x83b5: + case 0x83b6: + case 0x83b7: + case 0x83b8: + case 0x83b9: + case 0x83ba: + case 0x83bb: + case 0x83bc: + case 0x83bd: + case 0x83be: + case 0x83bf: + case 0x83c0: + case 0x83c1: + case 0x83c2: + case 0x83c3: + case 0x83c4: + case 0x83c5: + case 0x83c6: + case 0x83c7: + case 0x83c8: + case 0x83c9: + case 0x83ca: + case 0x83cb: + case 0x83cc: + case 0x83cd: + case 0x83ce: + case 0x83cf: + case 0x83d0: + case 0x83d1: + case 0x83d2: + case 0x83d3: + case 0x83d4: + case 0x83d5: + case 0x83d6: + case 0x83d7: + case 0x83d8: + case 0x83d9: + case 0x83da: + case 0x83db: + case 0x83dc: + case 0x83dd: + case 0x83de: + case 0x83df: + return s3_virge_in(addr & 0x3ff, p); - case 0xff20: - case 0xff21:ret = virge->serialport & ~(SERIAL_PORT_SCR | SERIAL_PORT_SDR); - if ((virge->serialport & SERIAL_PORT_SCW) && ddc_read_clock()) - ret |= SERIAL_PORT_SCR; - if ((virge->serialport & SERIAL_PORT_SDW) && ddc_read_data()) - ret |= SERIAL_PORT_SDR; - return ret; - } - return 0xff; + case 0xff20: + case 0xff21: + ret = virge->serialport & ~(SERIAL_PORT_SCR | SERIAL_PORT_SDR); + if ((virge->serialport & SERIAL_PORT_SCW) && ddc_read_clock()) + ret |= SERIAL_PORT_SCR; + if ((virge->serialport & SERIAL_PORT_SDW) && ddc_read_data()) + ret |= SERIAL_PORT_SDR; + return ret; + } + return 0xff; } static uint16_t s3_virge_mmio_read_w(uint32_t addr, void *p) { - reg_reads++; -// pclog("New MMIO readw %08X\n", addr); - switch (addr & 0xfffe) { - default:return s3_virge_mmio_read(addr, p) | (s3_virge_mmio_read(addr + 1, p) << 8); - } - return 0xffff; + reg_reads++; + // pclog("New MMIO readw %08X\n", addr); + switch (addr & 0xfffe) { + default: + return s3_virge_mmio_read(addr, p) | (s3_virge_mmio_read(addr + 1, p) << 8); + } + return 0xffff; } static uint32_t s3_virge_mmio_read_l(uint32_t addr, void *p) { - virge_t *virge = (virge_t *)p; - uint32_t ret = 0xffffffff; - reg_reads++; -// pclog("New MMIO readl %08X %04X(%08X):%08X ", addr, CS, cs, pc); - switch (addr & 0xfffc) { - case 0x8180:ret = virge->streams.pri_ctrl; - break; - case 0x8184:ret = virge->streams.chroma_ctrl; - break; - case 0x8190:ret = virge->streams.sec_ctrl; - break; - case 0x8194:ret = virge->streams.chroma_upper_bound; - break; - case 0x8198:ret = virge->streams.sec_filter; - break; - case 0x81a0:ret = virge->streams.blend_ctrl; - break; - case 0x81c0:ret = virge->streams.pri_fb0; - break; - case 0x81c4:ret = virge->streams.pri_fb1; - break; - case 0x81c8:ret = virge->streams.pri_stride; - break; - case 0x81cc:ret = virge->streams.buffer_ctrl; - break; - case 0x81d0:ret = virge->streams.sec_fb0; - break; - case 0x81d4:ret = virge->streams.sec_fb1; - break; - case 0x81d8:ret = virge->streams.sec_stride; - break; - case 0x81dc:ret = virge->streams.overlay_ctrl; - break; - case 0x81e0:ret = virge->streams.k1_vert_scale; - break; - case 0x81e4:ret = virge->streams.k2_vert_scale; - break; - case 0x81e8:ret = virge->streams.dda_vert_accumulator; - break; - case 0x81ec:ret = virge->streams.fifo_ctrl; - break; - case 0x81f0:ret = virge->streams.pri_start; - break; - case 0x81f4:ret = virge->streams.pri_size; - break; - case 0x81f8:ret = virge->streams.sec_start; - break; - case 0x81fc:ret = virge->streams.sec_size; - break; + virge_t *virge = (virge_t *)p; + uint32_t ret = 0xffffffff; + reg_reads++; + // pclog("New MMIO readl %08X %04X(%08X):%08X ", addr, CS, cs, pc); + switch (addr & 0xfffc) { + case 0x8180: + ret = virge->streams.pri_ctrl; + break; + case 0x8184: + ret = virge->streams.chroma_ctrl; + break; + case 0x8190: + ret = virge->streams.sec_ctrl; + break; + case 0x8194: + ret = virge->streams.chroma_upper_bound; + break; + case 0x8198: + ret = virge->streams.sec_filter; + break; + case 0x81a0: + ret = virge->streams.blend_ctrl; + break; + case 0x81c0: + ret = virge->streams.pri_fb0; + break; + case 0x81c4: + ret = virge->streams.pri_fb1; + break; + case 0x81c8: + ret = virge->streams.pri_stride; + break; + case 0x81cc: + ret = virge->streams.buffer_ctrl; + break; + case 0x81d0: + ret = virge->streams.sec_fb0; + break; + case 0x81d4: + ret = virge->streams.sec_fb1; + break; + case 0x81d8: + ret = virge->streams.sec_stride; + break; + case 0x81dc: + ret = virge->streams.overlay_ctrl; + break; + case 0x81e0: + ret = virge->streams.k1_vert_scale; + break; + case 0x81e4: + ret = virge->streams.k2_vert_scale; + break; + case 0x81e8: + ret = virge->streams.dda_vert_accumulator; + break; + case 0x81ec: + ret = virge->streams.fifo_ctrl; + break; + case 0x81f0: + ret = virge->streams.pri_start; + break; + case 0x81f4: + ret = virge->streams.pri_size; + break; + case 0x81f8: + ret = virge->streams.sec_start; + break; + case 0x81fc: + ret = virge->streams.sec_size; + break; - case 0x8504: - if (virge->s3d_busy || virge->virge_busy || !FIFO_EMPTY) - ret = (0x10 << 8); - else - ret = (0x10 << 8) | (1 << 13); - ret |= virge->subsys_stat; - if (!virge->virge_busy) - wake_fifo_thread(virge); -// pclog("Read status %04x %i\n", ret, virge->s3d_busy); - break; - case 0xa4d4:s3_virge_wait_fifo_idle(virge); - ret = virge->s3d.src_base; - break; - case 0xa4d8:s3_virge_wait_fifo_idle(virge); - ret = virge->s3d.dest_base; - break; - case 0xa4dc:s3_virge_wait_fifo_idle(virge); - ret = (virge->s3d.clip_l << 16) | virge->s3d.clip_r; - break; - case 0xa4e0:s3_virge_wait_fifo_idle(virge); - ret = (virge->s3d.clip_t << 16) | virge->s3d.clip_b; - break; - case 0xa4e4:s3_virge_wait_fifo_idle(virge); - ret = (virge->s3d.dest_str << 16) | virge->s3d.src_str; - break; - case 0xa4e8: - case 0xace8:s3_virge_wait_fifo_idle(virge); - ret = virge->s3d.mono_pat_0; - break; - case 0xa4ec: - case 0xacec:s3_virge_wait_fifo_idle(virge); - ret = virge->s3d.mono_pat_1; - break; - case 0xa4f0:s3_virge_wait_fifo_idle(virge); - ret = virge->s3d.pat_bg_clr; - break; - case 0xa4f4:s3_virge_wait_fifo_idle(virge); - ret = virge->s3d.pat_fg_clr; - break; - case 0xa4f8:s3_virge_wait_fifo_idle(virge); - ret = virge->s3d.src_bg_clr; - break; - case 0xa4fc:s3_virge_wait_fifo_idle(virge); - ret = virge->s3d.src_fg_clr; - break; - case 0xa500:s3_virge_wait_fifo_idle(virge); - ret = virge->s3d.cmd_set; - break; - case 0xa504:s3_virge_wait_fifo_idle(virge); - ret = (virge->s3d.r_width << 16) | virge->s3d.r_height; - break; - case 0xa508:s3_virge_wait_fifo_idle(virge); - ret = (virge->s3d.rsrc_x << 16) | virge->s3d.rsrc_y; - break; - case 0xa50c:s3_virge_wait_fifo_idle(virge); - ret = (virge->s3d.rdest_x << 16) | virge->s3d.rdest_y; - break; + case 0x8504: + if (virge->s3d_busy || virge->virge_busy || !FIFO_EMPTY) + ret = (0x10 << 8); + else + ret = (0x10 << 8) | (1 << 13); + ret |= virge->subsys_stat; + if (!virge->virge_busy) + wake_fifo_thread(virge); + // pclog("Read status %04x %i\n", ret, virge->s3d_busy); + break; + case 0xa4d4: + s3_virge_wait_fifo_idle(virge); + ret = virge->s3d.src_base; + break; + case 0xa4d8: + s3_virge_wait_fifo_idle(virge); + ret = virge->s3d.dest_base; + break; + case 0xa4dc: + s3_virge_wait_fifo_idle(virge); + ret = (virge->s3d.clip_l << 16) | virge->s3d.clip_r; + break; + case 0xa4e0: + s3_virge_wait_fifo_idle(virge); + ret = (virge->s3d.clip_t << 16) | virge->s3d.clip_b; + break; + case 0xa4e4: + s3_virge_wait_fifo_idle(virge); + ret = (virge->s3d.dest_str << 16) | virge->s3d.src_str; + break; + case 0xa4e8: + case 0xace8: + s3_virge_wait_fifo_idle(virge); + ret = virge->s3d.mono_pat_0; + break; + case 0xa4ec: + case 0xacec: + s3_virge_wait_fifo_idle(virge); + ret = virge->s3d.mono_pat_1; + break; + case 0xa4f0: + s3_virge_wait_fifo_idle(virge); + ret = virge->s3d.pat_bg_clr; + break; + case 0xa4f4: + s3_virge_wait_fifo_idle(virge); + ret = virge->s3d.pat_fg_clr; + break; + case 0xa4f8: + s3_virge_wait_fifo_idle(virge); + ret = virge->s3d.src_bg_clr; + break; + case 0xa4fc: + s3_virge_wait_fifo_idle(virge); + ret = virge->s3d.src_fg_clr; + break; + case 0xa500: + s3_virge_wait_fifo_idle(virge); + ret = virge->s3d.cmd_set; + break; + case 0xa504: + s3_virge_wait_fifo_idle(virge); + ret = (virge->s3d.r_width << 16) | virge->s3d.r_height; + break; + case 0xa508: + s3_virge_wait_fifo_idle(virge); + ret = (virge->s3d.rsrc_x << 16) | virge->s3d.rsrc_y; + break; + case 0xa50c: + s3_virge_wait_fifo_idle(virge); + ret = (virge->s3d.rdest_x << 16) | virge->s3d.rdest_y; + break; - default:ret = s3_virge_mmio_read_w(addr, p) | (s3_virge_mmio_read_w(addr + 2, p) << 16); - } -// /*if ((addr & 0xfffc) != 0x8504) */pclog("%02x\n", ret); - return ret; + default: + ret = s3_virge_mmio_read_w(addr, p) | (s3_virge_mmio_read_w(addr + 2, p) << 16); + } + // /*if ((addr & 0xfffc) != 0x8504) */pclog("%02x\n", ret); + return ret; } static void fifo_thread(void *param) { - virge_t *virge = (virge_t *)param; + virge_t *virge = (virge_t *)param; - while (1) { - thread_set_event(virge->fifo_not_full_event); - thread_wait_event(virge->wake_fifo_thread, -1); - thread_reset_event(virge->wake_fifo_thread); - virge->virge_busy = 1; - while (!FIFO_EMPTY) { - uint64_t start_time = timer_read(); - uint64_t end_time; - fifo_entry_t *fifo = &virge->fifo[virge->fifo_read_idx & FIFO_MASK]; - uint32_t val = fifo->val; + while (1) { + thread_set_event(virge->fifo_not_full_event); + thread_wait_event(virge->wake_fifo_thread, -1); + thread_reset_event(virge->wake_fifo_thread); + virge->virge_busy = 1; + while (!FIFO_EMPTY) { + uint64_t start_time = timer_read(); + uint64_t end_time; + fifo_entry_t *fifo = &virge->fifo[virge->fifo_read_idx & FIFO_MASK]; + uint32_t val = fifo->val; - switch (fifo->addr_type & FIFO_TYPE) { - case FIFO_WRITE_BYTE: - if (((fifo->addr_type & FIFO_ADDR) & 0xfffc) < 0x8000) - s3_virge_bitblt(virge, 8, val); - break; - case FIFO_WRITE_WORD: - if (((fifo->addr_type & FIFO_ADDR) & 0xfffc) < 0x8000) { - if (virge->s3d.cmd_set & CMD_SET_MS) - s3_virge_bitblt(virge, 16, ((val >> 8) | (val << 8)) << 16); - else - s3_virge_bitblt(virge, 16, val); - } - break; - case FIFO_WRITE_DWORD: - if (((fifo->addr_type & FIFO_ADDR) & 0xfffc) < 0x8000) { - if (virge->s3d.cmd_set & CMD_SET_MS) - s3_virge_bitblt(virge, 32, ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24)); - else - s3_virge_bitblt(virge, 32, val); - } else { - switch ((fifo->addr_type & FIFO_ADDR) & 0xfffc) { - case 0xa000: - case 0xa004: - case 0xa008: - case 0xa00c: - case 0xa010: - case 0xa014: - case 0xa018: - case 0xa01c: - case 0xa020: - case 0xa024: - case 0xa028: - case 0xa02c: - case 0xa030: - case 0xa034: - case 0xa038: - case 0xa03c: - case 0xa040: - case 0xa044: - case 0xa048: - case 0xa04c: - case 0xa050: - case 0xa054: - case 0xa058: - case 0xa05c: - case 0xa060: - case 0xa064: - case 0xa068: - case 0xa06c: - case 0xa070: - case 0xa074: - case 0xa078: - case 0xa07c: - case 0xa080: - case 0xa084: - case 0xa088: - case 0xa08c: - case 0xa090: - case 0xa094: - case 0xa098: - case 0xa09c: - case 0xa0a0: - case 0xa0a4: - case 0xa0a8: - case 0xa0ac: - case 0xa0b0: - case 0xa0b4: - case 0xa0b8: - case 0xa0bc: - case 0xa0c0: - case 0xa0c4: - case 0xa0c8: - case 0xa0cc: - case 0xa0d0: - case 0xa0d4: - case 0xa0d8: - case 0xa0dc: - case 0xa0e0: - case 0xa0e4: - case 0xa0e8: - case 0xa0ec: - case 0xa0f0: - case 0xa0f4: - case 0xa0f8: - case 0xa0fc: - case 0xa100: - case 0xa104: - case 0xa108: - case 0xa10c: - case 0xa110: - case 0xa114: - case 0xa118: - case 0xa11c: - case 0xa120: - case 0xa124: - case 0xa128: - case 0xa12c: - case 0xa130: - case 0xa134: - case 0xa138: - case 0xa13c: - case 0xa140: - case 0xa144: - case 0xa148: - case 0xa14c: - case 0xa150: - case 0xa154: - case 0xa158: - case 0xa15c: - case 0xa160: - case 0xa164: - case 0xa168: - case 0xa16c: - case 0xa170: - case 0xa174: - case 0xa178: - case 0xa17c: - case 0xa180: - case 0xa184: - case 0xa188: - case 0xa18c: - case 0xa190: - case 0xa194: - case 0xa198: - case 0xa19c: - case 0xa1a0: - case 0xa1a4: - case 0xa1a8: - case 0xa1ac: - case 0xa1b0: - case 0xa1b4: - case 0xa1b8: - case 0xa1bc: - case 0xa1c0: - case 0xa1c4: - case 0xa1c8: - case 0xa1cc: - case 0xa1d0: - case 0xa1d4: - case 0xa1d8: - case 0xa1dc: - case 0xa1e0: - case 0xa1e4: - case 0xa1e8: - case 0xa1ec: - case 0xa1f0: - case 0xa1f4: - case 0xa1f8: - case 0xa1fc: { - int x = (fifo->addr_type & FIFO_ADDR) & 4; - int y = ((fifo->addr_type & FIFO_ADDR) >> 3) & 7; - virge->s3d.pattern_8[y * 8 + x] = val & 0xff; - virge->s3d.pattern_8[y * 8 + x + 1] = val >> 8; - virge->s3d.pattern_8[y * 8 + x + 2] = val >> 16; - virge->s3d.pattern_8[y * 8 + x + 3] = val >> 24; + switch (fifo->addr_type & FIFO_TYPE) { + case FIFO_WRITE_BYTE: + if (((fifo->addr_type & FIFO_ADDR) & 0xfffc) < 0x8000) + s3_virge_bitblt(virge, 8, val); + break; + case FIFO_WRITE_WORD: + if (((fifo->addr_type & FIFO_ADDR) & 0xfffc) < 0x8000) { + if (virge->s3d.cmd_set & CMD_SET_MS) + s3_virge_bitblt(virge, 16, ((val >> 8) | (val << 8)) << 16); + else + s3_virge_bitblt(virge, 16, val); + } + break; + case FIFO_WRITE_DWORD: + if (((fifo->addr_type & FIFO_ADDR) & 0xfffc) < 0x8000) { + if (virge->s3d.cmd_set & CMD_SET_MS) + s3_virge_bitblt(virge, 32, + ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | + ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24)); + else + s3_virge_bitblt(virge, 32, val); + } else { + switch ((fifo->addr_type & FIFO_ADDR) & 0xfffc) { + case 0xa000: + case 0xa004: + case 0xa008: + case 0xa00c: + case 0xa010: + case 0xa014: + case 0xa018: + case 0xa01c: + case 0xa020: + case 0xa024: + case 0xa028: + case 0xa02c: + case 0xa030: + case 0xa034: + case 0xa038: + case 0xa03c: + case 0xa040: + case 0xa044: + case 0xa048: + case 0xa04c: + case 0xa050: + case 0xa054: + case 0xa058: + case 0xa05c: + case 0xa060: + case 0xa064: + case 0xa068: + case 0xa06c: + case 0xa070: + case 0xa074: + case 0xa078: + case 0xa07c: + case 0xa080: + case 0xa084: + case 0xa088: + case 0xa08c: + case 0xa090: + case 0xa094: + case 0xa098: + case 0xa09c: + case 0xa0a0: + case 0xa0a4: + case 0xa0a8: + case 0xa0ac: + case 0xa0b0: + case 0xa0b4: + case 0xa0b8: + case 0xa0bc: + case 0xa0c0: + case 0xa0c4: + case 0xa0c8: + case 0xa0cc: + case 0xa0d0: + case 0xa0d4: + case 0xa0d8: + case 0xa0dc: + case 0xa0e0: + case 0xa0e4: + case 0xa0e8: + case 0xa0ec: + case 0xa0f0: + case 0xa0f4: + case 0xa0f8: + case 0xa0fc: + case 0xa100: + case 0xa104: + case 0xa108: + case 0xa10c: + case 0xa110: + case 0xa114: + case 0xa118: + case 0xa11c: + case 0xa120: + case 0xa124: + case 0xa128: + case 0xa12c: + case 0xa130: + case 0xa134: + case 0xa138: + case 0xa13c: + case 0xa140: + case 0xa144: + case 0xa148: + case 0xa14c: + case 0xa150: + case 0xa154: + case 0xa158: + case 0xa15c: + case 0xa160: + case 0xa164: + case 0xa168: + case 0xa16c: + case 0xa170: + case 0xa174: + case 0xa178: + case 0xa17c: + case 0xa180: + case 0xa184: + case 0xa188: + case 0xa18c: + case 0xa190: + case 0xa194: + case 0xa198: + case 0xa19c: + case 0xa1a0: + case 0xa1a4: + case 0xa1a8: + case 0xa1ac: + case 0xa1b0: + case 0xa1b4: + case 0xa1b8: + case 0xa1bc: + case 0xa1c0: + case 0xa1c4: + case 0xa1c8: + case 0xa1cc: + case 0xa1d0: + case 0xa1d4: + case 0xa1d8: + case 0xa1dc: + case 0xa1e0: + case 0xa1e4: + case 0xa1e8: + case 0xa1ec: + case 0xa1f0: + case 0xa1f4: + case 0xa1f8: + case 0xa1fc: { + int x = (fifo->addr_type & FIFO_ADDR) & 4; + int y = ((fifo->addr_type & FIFO_ADDR) >> 3) & 7; + virge->s3d.pattern_8[y * 8 + x] = val & 0xff; + virge->s3d.pattern_8[y * 8 + x + 1] = val >> 8; + virge->s3d.pattern_8[y * 8 + x + 2] = val >> 16; + virge->s3d.pattern_8[y * 8 + x + 3] = val >> 24; - x = ((fifo->addr_type & FIFO_ADDR) >> 1) & 6; - y = ((fifo->addr_type & FIFO_ADDR) >> 4) & 7; - virge->s3d.pattern_16[y * 8 + x] = val & 0xffff; - virge->s3d.pattern_16[y * 8 + x + 1] = val >> 16; + x = ((fifo->addr_type & FIFO_ADDR) >> 1) & 6; + y = ((fifo->addr_type & FIFO_ADDR) >> 4) & 7; + virge->s3d.pattern_16[y * 8 + x] = val & 0xffff; + virge->s3d.pattern_16[y * 8 + x + 1] = val >> 16; - x = ((fifo->addr_type & FIFO_ADDR) >> 2) & 7; - y = ((fifo->addr_type & FIFO_ADDR) >> 5) & 7; - virge->s3d.pattern_32[y * 8 + x] = val & 0xffffff; - } - break; + x = ((fifo->addr_type & FIFO_ADDR) >> 2) & 7; + y = ((fifo->addr_type & FIFO_ADDR) >> 5) & 7; + virge->s3d.pattern_32[y * 8 + x] = val & 0xffffff; + } break; - case 0xa4d4: - case 0xa8d4:virge->s3d.src_base = val & 0x3ffff8; - break; - case 0xa4d8: - case 0xa8d8:virge->s3d.dest_base = val & 0x3ffff8; - break; - case 0xa4dc: - case 0xa8dc:virge->s3d.clip_l = (val >> 16) & 0x7ff; - virge->s3d.clip_r = val & 0x7ff; - break; - case 0xa4e0: - case 0xa8e0:virge->s3d.clip_t = (val >> 16) & 0x7ff; - virge->s3d.clip_b = val & 0x7ff; - break; - case 0xa4e4: - case 0xa8e4:virge->s3d.dest_str = (val >> 16) & 0xff8; - virge->s3d.src_str = val & 0xff8; - break; - case 0xa4e8: - case 0xace8:virge->s3d.mono_pat_0 = val; - break; - case 0xa4ec: - case 0xacec:virge->s3d.mono_pat_1 = val; - break; - case 0xa4f0: - case 0xacf0:virge->s3d.pat_bg_clr = val; - break; - case 0xa4f4: - case 0xa8f4: - case 0xacf4:virge->s3d.pat_fg_clr = val; - break; - case 0xa4f8:virge->s3d.src_bg_clr = val; - break; - case 0xa4fc:virge->s3d.src_fg_clr = val; - break; - case 0xa500: - case 0xa900:virge->s3d.cmd_set = val; - if (!(val & CMD_SET_AE)) - s3_virge_bitblt(virge, -1, 0); - break; - case 0xa504:virge->s3d.r_width = (val >> 16) & 0x7ff; - virge->s3d.r_height = val & 0x7ff; - break; - case 0xa508:virge->s3d.rsrc_x = (val >> 16) & 0x7ff; - virge->s3d.rsrc_y = val & 0x7ff; - break; - case 0xa50c:virge->s3d.rdest_x = (val >> 16) & 0x7ff; - virge->s3d.rdest_y = val & 0x7ff; - if (virge->s3d.cmd_set & CMD_SET_AE) - s3_virge_bitblt(virge, -1, 0); - break; - case 0xa96c:virge->s3d.lxend0 = (val >> 16) & 0x7ff; - virge->s3d.lxend1 = val & 0x7ff; - break; - case 0xa970:virge->s3d.ldx = (int32_t)val; - break; - case 0xa974:virge->s3d.lxstart = val; - break; - case 0xa978:virge->s3d.lystart = val & 0x7ff; - break; - case 0xa97c:virge->s3d.lycnt = val & 0x7ff; - virge->s3d.line_dir = val >> 31; - if (virge->s3d.cmd_set & CMD_SET_AE) - s3_virge_bitblt(virge, -1, 0); - break; + case 0xa4d4: + case 0xa8d4: + virge->s3d.src_base = val & 0x3ffff8; + break; + case 0xa4d8: + case 0xa8d8: + virge->s3d.dest_base = val & 0x3ffff8; + break; + case 0xa4dc: + case 0xa8dc: + virge->s3d.clip_l = (val >> 16) & 0x7ff; + virge->s3d.clip_r = val & 0x7ff; + break; + case 0xa4e0: + case 0xa8e0: + virge->s3d.clip_t = (val >> 16) & 0x7ff; + virge->s3d.clip_b = val & 0x7ff; + break; + case 0xa4e4: + case 0xa8e4: + virge->s3d.dest_str = (val >> 16) & 0xff8; + virge->s3d.src_str = val & 0xff8; + break; + case 0xa4e8: + case 0xace8: + virge->s3d.mono_pat_0 = val; + break; + case 0xa4ec: + case 0xacec: + virge->s3d.mono_pat_1 = val; + break; + case 0xa4f0: + case 0xacf0: + virge->s3d.pat_bg_clr = val; + break; + case 0xa4f4: + case 0xa8f4: + case 0xacf4: + virge->s3d.pat_fg_clr = val; + break; + case 0xa4f8: + virge->s3d.src_bg_clr = val; + break; + case 0xa4fc: + virge->s3d.src_fg_clr = val; + break; + case 0xa500: + case 0xa900: + virge->s3d.cmd_set = val; + if (!(val & CMD_SET_AE)) + s3_virge_bitblt(virge, -1, 0); + break; + case 0xa504: + virge->s3d.r_width = (val >> 16) & 0x7ff; + virge->s3d.r_height = val & 0x7ff; + break; + case 0xa508: + virge->s3d.rsrc_x = (val >> 16) & 0x7ff; + virge->s3d.rsrc_y = val & 0x7ff; + break; + case 0xa50c: + virge->s3d.rdest_x = (val >> 16) & 0x7ff; + virge->s3d.rdest_y = val & 0x7ff; + if (virge->s3d.cmd_set & CMD_SET_AE) + s3_virge_bitblt(virge, -1, 0); + break; + case 0xa96c: + virge->s3d.lxend0 = (val >> 16) & 0x7ff; + virge->s3d.lxend1 = val & 0x7ff; + break; + case 0xa970: + virge->s3d.ldx = (int32_t)val; + break; + case 0xa974: + virge->s3d.lxstart = val; + break; + case 0xa978: + virge->s3d.lystart = val & 0x7ff; + break; + case 0xa97c: + virge->s3d.lycnt = val & 0x7ff; + virge->s3d.line_dir = val >> 31; + if (virge->s3d.cmd_set & CMD_SET_AE) + s3_virge_bitblt(virge, -1, 0); + break; - case 0xad00:virge->s3d.cmd_set = val; - if (!(val & CMD_SET_AE)) - s3_virge_bitblt(virge, -1, 0); - break; - case 0xad68:virge->s3d.prdx = val; - break; - case 0xad6c:virge->s3d.prxstart = val; - break; - case 0xad70:virge->s3d.pldx = val; - break; - case 0xad74:virge->s3d.plxstart = val; - break; - case 0xad78:virge->s3d.pystart = val & 0x7ff; - break; - case 0xad7c:virge->s3d.pycnt = val & 0x300007ff; - if (virge->s3d.cmd_set & CMD_SET_AE) - s3_virge_bitblt(virge, -1, 0); - break; + case 0xad00: + virge->s3d.cmd_set = val; + if (!(val & CMD_SET_AE)) + s3_virge_bitblt(virge, -1, 0); + break; + case 0xad68: + virge->s3d.prdx = val; + break; + case 0xad6c: + virge->s3d.prxstart = val; + break; + case 0xad70: + virge->s3d.pldx = val; + break; + case 0xad74: + virge->s3d.plxstart = val; + break; + case 0xad78: + virge->s3d.pystart = val & 0x7ff; + break; + case 0xad7c: + virge->s3d.pycnt = val & 0x300007ff; + if (virge->s3d.cmd_set & CMD_SET_AE) + s3_virge_bitblt(virge, -1, 0); + break; - case 0xb4d4:virge->s3d_tri.z_base = val & 0x3ffff8; - break; - case 0xb4d8:virge->s3d_tri.dest_base = val & 0x3ffff8; - break; - case 0xb4dc:virge->s3d_tri.clip_l = (val >> 16) & 0x7ff; - virge->s3d_tri.clip_r = val & 0x7ff; - break; - case 0xb4e0:virge->s3d_tri.clip_t = (val >> 16) & 0x7ff; - virge->s3d_tri.clip_b = val & 0x7ff; - break; - case 0xb4e4:virge->s3d_tri.dest_str = (val >> 16) & 0xff8; - virge->s3d.src_str = val & 0xff8; - break; - case 0xb4e8:virge->s3d_tri.z_str = val & 0xff8; - break; - case 0xb4ec:virge->s3d_tri.tex_base = val & 0x3ffff8; - break; - case 0xb4f0:virge->s3d_tri.tex_bdr_clr = val & 0xffffff; - break; - case 0xb500:virge->s3d_tri.cmd_set = val; - if (!(val & CMD_SET_AE)) - queue_triangle(virge); - break; - case 0xb504:virge->s3d_tri.tbv = val & 0xfffff; - break; - case 0xb508:virge->s3d_tri.tbu = val & 0xfffff; - break; - case 0xb50c:virge->s3d_tri.TdWdX = val; - break; - case 0xb510:virge->s3d_tri.TdWdY = val; - break; - case 0xb514:virge->s3d_tri.tws = val; - break; - case 0xb518:virge->s3d_tri.TdDdX = val; - break; - case 0xb51c:virge->s3d_tri.TdVdX = val; - break; - case 0xb520:virge->s3d_tri.TdUdX = val; - break; - case 0xb524:virge->s3d_tri.TdDdY = val; - break; - case 0xb528:virge->s3d_tri.TdVdY = val; - break; - case 0xb52c:virge->s3d_tri.TdUdY = val; - break; - case 0xb530:virge->s3d_tri.tds = val; - break; - case 0xb534:virge->s3d_tri.tvs = val; - break; - case 0xb538:virge->s3d_tri.tus = val; - break; - case 0xb53c:virge->s3d_tri.TdGdX = val >> 16; - virge->s3d_tri.TdBdX = val & 0xffff; - break; - case 0xb540:virge->s3d_tri.TdAdX = val >> 16; - virge->s3d_tri.TdRdX = val & 0xffff; - break; - case 0xb544:virge->s3d_tri.TdGdY = val >> 16; - virge->s3d_tri.TdBdY = val & 0xffff; - break; - case 0xb548:virge->s3d_tri.TdAdY = val >> 16; - virge->s3d_tri.TdRdY = val & 0xffff; - break; - case 0xb54c:virge->s3d_tri.tgs = (val >> 16) & 0xffff; - virge->s3d_tri.tbs = val & 0xffff; - break; - case 0xb550:virge->s3d_tri.tas = (val >> 16) & 0xffff; - virge->s3d_tri.trs = val & 0xffff; - break; + case 0xb4d4: + virge->s3d_tri.z_base = val & 0x3ffff8; + break; + case 0xb4d8: + virge->s3d_tri.dest_base = val & 0x3ffff8; + break; + case 0xb4dc: + virge->s3d_tri.clip_l = (val >> 16) & 0x7ff; + virge->s3d_tri.clip_r = val & 0x7ff; + break; + case 0xb4e0: + virge->s3d_tri.clip_t = (val >> 16) & 0x7ff; + virge->s3d_tri.clip_b = val & 0x7ff; + break; + case 0xb4e4: + virge->s3d_tri.dest_str = (val >> 16) & 0xff8; + virge->s3d.src_str = val & 0xff8; + break; + case 0xb4e8: + virge->s3d_tri.z_str = val & 0xff8; + break; + case 0xb4ec: + virge->s3d_tri.tex_base = val & 0x3ffff8; + break; + case 0xb4f0: + virge->s3d_tri.tex_bdr_clr = val & 0xffffff; + break; + case 0xb500: + virge->s3d_tri.cmd_set = val; + if (!(val & CMD_SET_AE)) + queue_triangle(virge); + break; + case 0xb504: + virge->s3d_tri.tbv = val & 0xfffff; + break; + case 0xb508: + virge->s3d_tri.tbu = val & 0xfffff; + break; + case 0xb50c: + virge->s3d_tri.TdWdX = val; + break; + case 0xb510: + virge->s3d_tri.TdWdY = val; + break; + case 0xb514: + virge->s3d_tri.tws = val; + break; + case 0xb518: + virge->s3d_tri.TdDdX = val; + break; + case 0xb51c: + virge->s3d_tri.TdVdX = val; + break; + case 0xb520: + virge->s3d_tri.TdUdX = val; + break; + case 0xb524: + virge->s3d_tri.TdDdY = val; + break; + case 0xb528: + virge->s3d_tri.TdVdY = val; + break; + case 0xb52c: + virge->s3d_tri.TdUdY = val; + break; + case 0xb530: + virge->s3d_tri.tds = val; + break; + case 0xb534: + virge->s3d_tri.tvs = val; + break; + case 0xb538: + virge->s3d_tri.tus = val; + break; + case 0xb53c: + virge->s3d_tri.TdGdX = val >> 16; + virge->s3d_tri.TdBdX = val & 0xffff; + break; + case 0xb540: + virge->s3d_tri.TdAdX = val >> 16; + virge->s3d_tri.TdRdX = val & 0xffff; + break; + case 0xb544: + virge->s3d_tri.TdGdY = val >> 16; + virge->s3d_tri.TdBdY = val & 0xffff; + break; + case 0xb548: + virge->s3d_tri.TdAdY = val >> 16; + virge->s3d_tri.TdRdY = val & 0xffff; + break; + case 0xb54c: + virge->s3d_tri.tgs = (val >> 16) & 0xffff; + virge->s3d_tri.tbs = val & 0xffff; + break; + case 0xb550: + virge->s3d_tri.tas = (val >> 16) & 0xffff; + virge->s3d_tri.trs = val & 0xffff; + break; - case 0xb554:virge->s3d_tri.TdZdX = val; - break; - case 0xb558:virge->s3d_tri.TdZdY = val; - break; - case 0xb55c:virge->s3d_tri.tzs = val; - break; - case 0xb560:virge->s3d_tri.TdXdY12 = val; - break; - case 0xb564:virge->s3d_tri.txend12 = val; - break; - case 0xb568:virge->s3d_tri.TdXdY01 = val; - break; - case 0xb56c:virge->s3d_tri.txend01 = val; - break; - case 0xb570:virge->s3d_tri.TdXdY02 = val; - break; - case 0xb574:virge->s3d_tri.txs = val; - break; - case 0xb578:virge->s3d_tri.tys = val; - break; - case 0xb57c:virge->s3d_tri.ty01 = (val >> 16) & 0x7ff; - virge->s3d_tri.ty12 = val & 0x7ff; - virge->s3d_tri.tlr = val >> 31; - if (virge->s3d_tri.cmd_set & CMD_SET_AE) - queue_triangle(virge); - break; - } - } - break; - } + case 0xb554: + virge->s3d_tri.TdZdX = val; + break; + case 0xb558: + virge->s3d_tri.TdZdY = val; + break; + case 0xb55c: + virge->s3d_tri.tzs = val; + break; + case 0xb560: + virge->s3d_tri.TdXdY12 = val; + break; + case 0xb564: + virge->s3d_tri.txend12 = val; + break; + case 0xb568: + virge->s3d_tri.TdXdY01 = val; + break; + case 0xb56c: + virge->s3d_tri.txend01 = val; + break; + case 0xb570: + virge->s3d_tri.TdXdY02 = val; + break; + case 0xb574: + virge->s3d_tri.txs = val; + break; + case 0xb578: + virge->s3d_tri.tys = val; + break; + case 0xb57c: + virge->s3d_tri.ty01 = (val >> 16) & 0x7ff; + virge->s3d_tri.ty12 = val & 0x7ff; + virge->s3d_tri.tlr = val >> 31; + if (virge->s3d_tri.cmd_set & CMD_SET_AE) + queue_triangle(virge); + break; + } + } + break; + } - virge->fifo_read_idx++; - fifo->addr_type = FIFO_INVALID; + virge->fifo_read_idx++; + fifo->addr_type = FIFO_INVALID; - if (FIFO_ENTRIES > 0xe000) - thread_set_event(virge->fifo_not_full_event); + if (FIFO_ENTRIES > 0xe000) + thread_set_event(virge->fifo_not_full_event); - end_time = timer_read(); - virge_time += end_time - start_time; - } - virge->virge_busy = 0; - virge->subsys_stat |= INT_FIFO_EMP | INT_3DF_EMP; - s3_virge_update_irqs(virge); - } + end_time = timer_read(); + virge_time += end_time - start_time; + } + virge->virge_busy = 0; + virge->subsys_stat |= INT_FIFO_EMP | INT_3DF_EMP; + s3_virge_update_irqs(virge); + } } static void s3_virge_queue(virge_t *virge, uint32_t addr, uint32_t val, uint32_t type) { - fifo_entry_t *fifo = &virge->fifo[virge->fifo_write_idx & FIFO_MASK]; + fifo_entry_t *fifo = &virge->fifo[virge->fifo_write_idx & FIFO_MASK]; - if (FIFO_FULL) { - thread_reset_event(virge->fifo_not_full_event); - if (FIFO_FULL) { - thread_wait_event(virge->fifo_not_full_event, -1); /*Wait for room in ringbuffer*/ - } - } + if (FIFO_FULL) { + thread_reset_event(virge->fifo_not_full_event); + if (FIFO_FULL) { + thread_wait_event(virge->fifo_not_full_event, -1); /*Wait for room in ringbuffer*/ + } + } - fifo->val = val; - fifo->addr_type = (addr & FIFO_ADDR) | type; + fifo->val = val; + fifo->addr_type = (addr & FIFO_ADDR) | type; - virge->fifo_write_idx++; + virge->fifo_write_idx++; - if (FIFO_ENTRIES > 0xe000) - wake_fifo_thread(virge); - if (FIFO_ENTRIES > 0xe000 || FIFO_ENTRIES < 8) - wake_fifo_thread(virge); + if (FIFO_ENTRIES > 0xe000) + wake_fifo_thread(virge); + if (FIFO_ENTRIES > 0xe000 || FIFO_ENTRIES < 8) + wake_fifo_thread(virge); } static void s3_virge_mmio_write(uint32_t addr, uint8_t val, void *p) { - virge_t *virge = (virge_t *)p; + virge_t *virge = (virge_t *)p; -// pclog("New MMIO writeb %08X %02X %04x(%08x):%08x\n", addr, val, CS, cs, pc); - reg_writes++; - if ((addr & 0xfffc) < 0x8000) { - s3_virge_queue(virge, addr, val, FIFO_WRITE_BYTE); - } else - switch (addr & 0xffff) { - case 0x83b0: - case 0x83b1: - case 0x83b2: - case 0x83b3: - case 0x83b4: - case 0x83b5: - case 0x83b6: - case 0x83b7: - case 0x83b8: - case 0x83b9: - case 0x83ba: - case 0x83bb: - case 0x83bc: - case 0x83bd: - case 0x83be: - case 0x83bf: - case 0x83c0: - case 0x83c1: - case 0x83c2: - case 0x83c3: - case 0x83c4: - case 0x83c5: - case 0x83c6: - case 0x83c7: - case 0x83c8: - case 0x83c9: - case 0x83ca: - case 0x83cb: - case 0x83cc: - case 0x83cd: - case 0x83ce: - case 0x83cf: - case 0x83d0: - case 0x83d1: - case 0x83d2: - case 0x83d3: - case 0x83d4: - case 0x83d5: - case 0x83d6: - case 0x83d7: - case 0x83d8: - case 0x83d9: - case 0x83da: - case 0x83db: - case 0x83dc: - case 0x83dd: - case 0x83de: - case 0x83df:s3_virge_out(addr & 0x3ff, val, p); - break; + // pclog("New MMIO writeb %08X %02X %04x(%08x):%08x\n", addr, val, CS, cs, pc); + reg_writes++; + if ((addr & 0xfffc) < 0x8000) { + s3_virge_queue(virge, addr, val, FIFO_WRITE_BYTE); + } else + switch (addr & 0xffff) { + case 0x83b0: + case 0x83b1: + case 0x83b2: + case 0x83b3: + case 0x83b4: + case 0x83b5: + case 0x83b6: + case 0x83b7: + case 0x83b8: + case 0x83b9: + case 0x83ba: + case 0x83bb: + case 0x83bc: + case 0x83bd: + case 0x83be: + case 0x83bf: + case 0x83c0: + case 0x83c1: + case 0x83c2: + case 0x83c3: + case 0x83c4: + case 0x83c5: + case 0x83c6: + case 0x83c7: + case 0x83c8: + case 0x83c9: + case 0x83ca: + case 0x83cb: + case 0x83cc: + case 0x83cd: + case 0x83ce: + case 0x83cf: + case 0x83d0: + case 0x83d1: + case 0x83d2: + case 0x83d3: + case 0x83d4: + case 0x83d5: + case 0x83d6: + case 0x83d7: + case 0x83d8: + case 0x83d9: + case 0x83da: + case 0x83db: + case 0x83dc: + case 0x83dd: + case 0x83de: + case 0x83df: + s3_virge_out(addr & 0x3ff, val, p); + break; - case 0xff20:virge->serialport = val; - ddc_i2c_change((val & SERIAL_PORT_SCW) ? 1 : 0, (val & SERIAL_PORT_SDW) ? 1 : 0); - break; - } + case 0xff20: + virge->serialport = val; + ddc_i2c_change((val & SERIAL_PORT_SCW) ? 1 : 0, (val & SERIAL_PORT_SDW) ? 1 : 0); + break; + } } static void s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *p) { - virge_t *virge = (virge_t *)p; - reg_writes++; -// pclog("New MMIO writew %08X %04X %04x(%08x):%08x\n", addr, val, CS, cs, pc); - if ((addr & 0xfffc) < 0x8000) { - s3_virge_queue(virge, addr, val, FIFO_WRITE_WORD); - } else - switch (addr & 0xfffe) { - case 0x83d4:s3_virge_mmio_write(addr, val, p); - s3_virge_mmio_write(addr + 1, val >> 8, p); - break; + virge_t *virge = (virge_t *)p; + reg_writes++; + // pclog("New MMIO writew %08X %04X %04x(%08x):%08x\n", addr, val, CS, cs, pc); + if ((addr & 0xfffc) < 0x8000) { + s3_virge_queue(virge, addr, val, FIFO_WRITE_WORD); + } else + switch (addr & 0xfffe) { + case 0x83d4: + s3_virge_mmio_write(addr, val, p); + s3_virge_mmio_write(addr + 1, val >> 8, p); + break; - case 0xff20:s3_virge_mmio_write(addr, val, p); - break; - } + case 0xff20: + s3_virge_mmio_write(addr, val, p); + break; + } } static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p) { - virge_t *virge = (virge_t *)p; - svga_t *svga = &virge->svga; - reg_writes++; -// if ((addr & 0xfffc) >= 0xb400 && (addr & 0xfffc) < 0xb800) -// pclog("New MMIO writel %08X %08X %04x(%08x):%08x\n", addr, val, CS, cs, pc); + virge_t *virge = (virge_t *)p; + svga_t *svga = &virge->svga; + reg_writes++; + // if ((addr & 0xfffc) >= 0xb400 && (addr & 0xfffc) < 0xb800) + // pclog("New MMIO writel %08X %08X %04x(%08x):%08x\n", addr, val, CS, cs, pc); - if ((addr & 0xfffc) < 0x8000) { - s3_virge_queue(virge, addr, val, FIFO_WRITE_DWORD); - } else if ((addr & 0xe000) == 0xa000) { - s3_virge_queue(virge, addr, val, FIFO_WRITE_DWORD); - } else - switch (addr & 0xfffc) { - case 0x8180:virge->streams.pri_ctrl = val; - svga_recalctimings(svga); - svga->fullchange = changeframecount; - break; - case 0x8184:virge->streams.chroma_ctrl = val; - break; - case 0x8190:virge->streams.sec_ctrl = val; - virge->streams.dda_horiz_accumulator = val & 0xfff; - if (val & (1 << 11)) - virge->streams.dda_horiz_accumulator |= 0xfffff800; - virge->streams.sdif = (val >> 24) & 7; - break; - case 0x8194:virge->streams.chroma_upper_bound = val; - break; - case 0x8198:virge->streams.sec_filter = val; - virge->streams.k1_horiz_scale = val & 0x7ff; - if (val & (1 << 10)) - virge->streams.k1_horiz_scale |= 0xfffff800; - virge->streams.k2_horiz_scale = (val >> 16) & 0x7ff; - if ((val >> 16) & (1 << 10)) - virge->streams.k2_horiz_scale |= 0xfffff800; - break; - case 0x81a0:virge->streams.blend_ctrl = val; - break; - case 0x81c0: -// pclog("Write pri_fb0 %08x\n", val); - virge->streams.pri_fb0 = val & 0x3fffff; - svga_recalctimings(svga); - svga->fullchange = changeframecount; - break; - case 0x81c4: -// pclog("Write pri_fb1 %08x\n", val); - virge->streams.pri_fb1 = val & 0x3fffff; - svga_recalctimings(svga); - svga->fullchange = changeframecount; - break; - case 0x81c8:virge->streams.pri_stride = val & 0xfff; - svga_recalctimings(svga); - svga->fullchange = changeframecount; - break; - case 0x81cc: -// pclog("Write buffer_ctrl %08x\n", val); - virge->streams.buffer_ctrl = val; - svga_recalctimings(svga); - svga->fullchange = changeframecount; - break; - case 0x81d0:virge->streams.sec_fb0 = val; - svga_recalctimings(svga); - svga->fullchange = changeframecount; - break; - case 0x81d4:virge->streams.sec_fb1 = val; - svga_recalctimings(svga); - svga->fullchange = changeframecount; - break; - case 0x81d8:virge->streams.sec_stride = val; - svga_recalctimings(svga); - svga->fullchange = changeframecount; - break; - case 0x81dc:virge->streams.overlay_ctrl = val; - break; - case 0x81e0:virge->streams.k1_vert_scale = val & 0x7ff; - if (val & (1 << 10)) - virge->streams.k1_vert_scale |= 0xfffff800; - break; - case 0x81e4:virge->streams.k2_vert_scale = val & 0x7ff; - if (val & (1 << 10)) - virge->streams.k2_vert_scale |= 0xfffff800; - break; - case 0x81e8:virge->streams.dda_vert_accumulator = val & 0xfff; - if (val & (1 << 11)) - virge->streams.dda_vert_accumulator |= 0xfffff800; - break; - case 0x81ec:virge->streams.fifo_ctrl = val; - break; - case 0x81f0:virge->streams.pri_start = val; - virge->streams.pri_x = (val >> 16) & 0x7ff; - virge->streams.pri_y = val & 0x7ff; - svga_recalctimings(svga); - svga->fullchange = changeframecount; - break; - case 0x81f4:virge->streams.pri_size = val; - virge->streams.pri_w = (val >> 16) & 0x7ff; - virge->streams.pri_h = val & 0x7ff; - svga_recalctimings(svga); - svga->fullchange = changeframecount; - break; - case 0x81f8:virge->streams.sec_start = val; - virge->streams.sec_x = (val >> 16) & 0x7ff; - virge->streams.sec_y = val & 0x7ff; - svga_recalctimings(svga); - svga->fullchange = changeframecount; - break; - case 0x81fc:virge->streams.sec_size = val; - virge->streams.sec_w = (val >> 16) & 0x7ff; - virge->streams.sec_h = val & 0x7ff; - svga_recalctimings(svga); - svga->fullchange = changeframecount; - break; + if ((addr & 0xfffc) < 0x8000) { + s3_virge_queue(virge, addr, val, FIFO_WRITE_DWORD); + } else if ((addr & 0xe000) == 0xa000) { + s3_virge_queue(virge, addr, val, FIFO_WRITE_DWORD); + } else + switch (addr & 0xfffc) { + case 0x8180: + virge->streams.pri_ctrl = val; + svga_recalctimings(svga); + svga->fullchange = changeframecount; + break; + case 0x8184: + virge->streams.chroma_ctrl = val; + break; + case 0x8190: + virge->streams.sec_ctrl = val; + virge->streams.dda_horiz_accumulator = val & 0xfff; + if (val & (1 << 11)) + virge->streams.dda_horiz_accumulator |= 0xfffff800; + virge->streams.sdif = (val >> 24) & 7; + break; + case 0x8194: + virge->streams.chroma_upper_bound = val; + break; + case 0x8198: + virge->streams.sec_filter = val; + virge->streams.k1_horiz_scale = val & 0x7ff; + if (val & (1 << 10)) + virge->streams.k1_horiz_scale |= 0xfffff800; + virge->streams.k2_horiz_scale = (val >> 16) & 0x7ff; + if ((val >> 16) & (1 << 10)) + virge->streams.k2_horiz_scale |= 0xfffff800; + break; + case 0x81a0: + virge->streams.blend_ctrl = val; + break; + case 0x81c0: + // pclog("Write pri_fb0 %08x\n", val); + virge->streams.pri_fb0 = val & 0x3fffff; + svga_recalctimings(svga); + svga->fullchange = changeframecount; + break; + case 0x81c4: + // pclog("Write pri_fb1 %08x\n", val); + virge->streams.pri_fb1 = val & 0x3fffff; + svga_recalctimings(svga); + svga->fullchange = changeframecount; + break; + case 0x81c8: + virge->streams.pri_stride = val & 0xfff; + svga_recalctimings(svga); + svga->fullchange = changeframecount; + break; + case 0x81cc: + // pclog("Write buffer_ctrl %08x\n", val); + virge->streams.buffer_ctrl = val; + svga_recalctimings(svga); + svga->fullchange = changeframecount; + break; + case 0x81d0: + virge->streams.sec_fb0 = val; + svga_recalctimings(svga); + svga->fullchange = changeframecount; + break; + case 0x81d4: + virge->streams.sec_fb1 = val; + svga_recalctimings(svga); + svga->fullchange = changeframecount; + break; + case 0x81d8: + virge->streams.sec_stride = val; + svga_recalctimings(svga); + svga->fullchange = changeframecount; + break; + case 0x81dc: + virge->streams.overlay_ctrl = val; + break; + case 0x81e0: + virge->streams.k1_vert_scale = val & 0x7ff; + if (val & (1 << 10)) + virge->streams.k1_vert_scale |= 0xfffff800; + break; + case 0x81e4: + virge->streams.k2_vert_scale = val & 0x7ff; + if (val & (1 << 10)) + virge->streams.k2_vert_scale |= 0xfffff800; + break; + case 0x81e8: + virge->streams.dda_vert_accumulator = val & 0xfff; + if (val & (1 << 11)) + virge->streams.dda_vert_accumulator |= 0xfffff800; + break; + case 0x81ec: + virge->streams.fifo_ctrl = val; + break; + case 0x81f0: + virge->streams.pri_start = val; + virge->streams.pri_x = (val >> 16) & 0x7ff; + virge->streams.pri_y = val & 0x7ff; + svga_recalctimings(svga); + svga->fullchange = changeframecount; + break; + case 0x81f4: + virge->streams.pri_size = val; + virge->streams.pri_w = (val >> 16) & 0x7ff; + virge->streams.pri_h = val & 0x7ff; + svga_recalctimings(svga); + svga->fullchange = changeframecount; + break; + case 0x81f8: + virge->streams.sec_start = val; + virge->streams.sec_x = (val >> 16) & 0x7ff; + virge->streams.sec_y = val & 0x7ff; + svga_recalctimings(svga); + svga->fullchange = changeframecount; + break; + case 0x81fc: + virge->streams.sec_size = val; + virge->streams.sec_w = (val >> 16) & 0x7ff; + virge->streams.sec_h = val & 0x7ff; + svga_recalctimings(svga); + svga->fullchange = changeframecount; + break; - case 0x8504:virge->subsys_stat &= ~(val & 0xff); - virge->subsys_cntl = (val >> 8); - s3_virge_update_irqs(virge); - break; + case 0x8504: + virge->subsys_stat &= ~(val & 0xff); + virge->subsys_cntl = (val >> 8); + s3_virge_update_irqs(virge); + break; - case 0xa000: - case 0xa004: - case 0xa008: - case 0xa00c: - case 0xa010: - case 0xa014: - case 0xa018: - case 0xa01c: - case 0xa020: - case 0xa024: - case 0xa028: - case 0xa02c: - case 0xa030: - case 0xa034: - case 0xa038: - case 0xa03c: - case 0xa040: - case 0xa044: - case 0xa048: - case 0xa04c: - case 0xa050: - case 0xa054: - case 0xa058: - case 0xa05c: - case 0xa060: - case 0xa064: - case 0xa068: - case 0xa06c: - case 0xa070: - case 0xa074: - case 0xa078: - case 0xa07c: - case 0xa080: - case 0xa084: - case 0xa088: - case 0xa08c: - case 0xa090: - case 0xa094: - case 0xa098: - case 0xa09c: - case 0xa0a0: - case 0xa0a4: - case 0xa0a8: - case 0xa0ac: - case 0xa0b0: - case 0xa0b4: - case 0xa0b8: - case 0xa0bc: - case 0xa0c0: - case 0xa0c4: - case 0xa0c8: - case 0xa0cc: - case 0xa0d0: - case 0xa0d4: - case 0xa0d8: - case 0xa0dc: - case 0xa0e0: - case 0xa0e4: - case 0xa0e8: - case 0xa0ec: - case 0xa0f0: - case 0xa0f4: - case 0xa0f8: - case 0xa0fc: - case 0xa100: - case 0xa104: - case 0xa108: - case 0xa10c: - case 0xa110: - case 0xa114: - case 0xa118: - case 0xa11c: - case 0xa120: - case 0xa124: - case 0xa128: - case 0xa12c: - case 0xa130: - case 0xa134: - case 0xa138: - case 0xa13c: - case 0xa140: - case 0xa144: - case 0xa148: - case 0xa14c: - case 0xa150: - case 0xa154: - case 0xa158: - case 0xa15c: - case 0xa160: - case 0xa164: - case 0xa168: - case 0xa16c: - case 0xa170: - case 0xa174: - case 0xa178: - case 0xa17c: - case 0xa180: - case 0xa184: - case 0xa188: - case 0xa18c: - case 0xa190: - case 0xa194: - case 0xa198: - case 0xa19c: - case 0xa1a0: - case 0xa1a4: - case 0xa1a8: - case 0xa1ac: - case 0xa1b0: - case 0xa1b4: - case 0xa1b8: - case 0xa1bc: - case 0xa1c0: - case 0xa1c4: - case 0xa1c8: - case 0xa1cc: - case 0xa1d0: - case 0xa1d4: - case 0xa1d8: - case 0xa1dc: - case 0xa1e0: - case 0xa1e4: - case 0xa1e8: - case 0xa1ec: - case 0xa1f0: - case 0xa1f4: - case 0xa1f8: - case 0xa1fc: { - int x = addr & 4; - int y = (addr >> 3) & 7; - virge->s3d.pattern_8[y * 8 + x] = val & 0xff; - virge->s3d.pattern_8[y * 8 + x + 1] = val >> 8; - virge->s3d.pattern_8[y * 8 + x + 2] = val >> 16; - virge->s3d.pattern_8[y * 8 + x + 3] = val >> 24; + case 0xa000: + case 0xa004: + case 0xa008: + case 0xa00c: + case 0xa010: + case 0xa014: + case 0xa018: + case 0xa01c: + case 0xa020: + case 0xa024: + case 0xa028: + case 0xa02c: + case 0xa030: + case 0xa034: + case 0xa038: + case 0xa03c: + case 0xa040: + case 0xa044: + case 0xa048: + case 0xa04c: + case 0xa050: + case 0xa054: + case 0xa058: + case 0xa05c: + case 0xa060: + case 0xa064: + case 0xa068: + case 0xa06c: + case 0xa070: + case 0xa074: + case 0xa078: + case 0xa07c: + case 0xa080: + case 0xa084: + case 0xa088: + case 0xa08c: + case 0xa090: + case 0xa094: + case 0xa098: + case 0xa09c: + case 0xa0a0: + case 0xa0a4: + case 0xa0a8: + case 0xa0ac: + case 0xa0b0: + case 0xa0b4: + case 0xa0b8: + case 0xa0bc: + case 0xa0c0: + case 0xa0c4: + case 0xa0c8: + case 0xa0cc: + case 0xa0d0: + case 0xa0d4: + case 0xa0d8: + case 0xa0dc: + case 0xa0e0: + case 0xa0e4: + case 0xa0e8: + case 0xa0ec: + case 0xa0f0: + case 0xa0f4: + case 0xa0f8: + case 0xa0fc: + case 0xa100: + case 0xa104: + case 0xa108: + case 0xa10c: + case 0xa110: + case 0xa114: + case 0xa118: + case 0xa11c: + case 0xa120: + case 0xa124: + case 0xa128: + case 0xa12c: + case 0xa130: + case 0xa134: + case 0xa138: + case 0xa13c: + case 0xa140: + case 0xa144: + case 0xa148: + case 0xa14c: + case 0xa150: + case 0xa154: + case 0xa158: + case 0xa15c: + case 0xa160: + case 0xa164: + case 0xa168: + case 0xa16c: + case 0xa170: + case 0xa174: + case 0xa178: + case 0xa17c: + case 0xa180: + case 0xa184: + case 0xa188: + case 0xa18c: + case 0xa190: + case 0xa194: + case 0xa198: + case 0xa19c: + case 0xa1a0: + case 0xa1a4: + case 0xa1a8: + case 0xa1ac: + case 0xa1b0: + case 0xa1b4: + case 0xa1b8: + case 0xa1bc: + case 0xa1c0: + case 0xa1c4: + case 0xa1c8: + case 0xa1cc: + case 0xa1d0: + case 0xa1d4: + case 0xa1d8: + case 0xa1dc: + case 0xa1e0: + case 0xa1e4: + case 0xa1e8: + case 0xa1ec: + case 0xa1f0: + case 0xa1f4: + case 0xa1f8: + case 0xa1fc: { + int x = addr & 4; + int y = (addr >> 3) & 7; + virge->s3d.pattern_8[y * 8 + x] = val & 0xff; + virge->s3d.pattern_8[y * 8 + x + 1] = val >> 8; + virge->s3d.pattern_8[y * 8 + x + 2] = val >> 16; + virge->s3d.pattern_8[y * 8 + x + 3] = val >> 24; - x = (addr >> 1) & 6; - y = (addr >> 4) & 7; - virge->s3d.pattern_16[y * 8 + x] = val & 0xffff; - virge->s3d.pattern_16[y * 8 + x + 1] = val >> 16; + x = (addr >> 1) & 6; + y = (addr >> 4) & 7; + virge->s3d.pattern_16[y * 8 + x] = val & 0xffff; + virge->s3d.pattern_16[y * 8 + x + 1] = val >> 16; - x = (addr >> 2) & 7; - y = (addr >> 5) & 7; - virge->s3d.pattern_32[y * 8 + x] = val & 0xffffff; - } - break; + x = (addr >> 2) & 7; + y = (addr >> 5) & 7; + virge->s3d.pattern_32[y * 8 + x] = val & 0xffffff; + } break; - case 0xa4d4: - case 0xa8d4:virge->s3d.src_base = val & 0x3ffff8; - break; - case 0xa4d8: - case 0xa8d8:virge->s3d.dest_base = val & 0x3ffff8; - break; - case 0xa4dc: - case 0xa8dc:virge->s3d.clip_l = (val >> 16) & 0x7ff; - virge->s3d.clip_r = val & 0x7ff; - break; - case 0xa4e0: - case 0xa8e0:virge->s3d.clip_t = (val >> 16) & 0x7ff; - virge->s3d.clip_b = val & 0x7ff; - break; - case 0xa4e4: - case 0xa8e4:virge->s3d.dest_str = (val >> 16) & 0xff8; - virge->s3d.src_str = val & 0xff8; - break; - case 0xa4e8: - case 0xace8:virge->s3d.mono_pat_0 = val; - break; - case 0xa4ec: - case 0xacec:virge->s3d.mono_pat_1 = val; - break; - case 0xa4f0: - case 0xacf0:virge->s3d.pat_bg_clr = val; - break; - case 0xa4f4: - case 0xa8f4: - case 0xacf4:virge->s3d.pat_fg_clr = val; - break; - case 0xa4f8:virge->s3d.src_bg_clr = val; - break; - case 0xa4fc:virge->s3d.src_fg_clr = val; - break; - case 0xa500: - case 0xa900:virge->s3d.cmd_set = val; - if (!(val & CMD_SET_AE)) - s3_virge_bitblt(virge, -1, 0); - break; - case 0xa504:virge->s3d.r_width = (val >> 16) & 0x7ff; - virge->s3d.r_height = val & 0x7ff; - break; - case 0xa508:virge->s3d.rsrc_x = (val >> 16) & 0x7ff; - virge->s3d.rsrc_y = val & 0x7ff; - break; - case 0xa50c:virge->s3d.rdest_x = (val >> 16) & 0x7ff; - virge->s3d.rdest_y = val & 0x7ff; - if (virge->s3d.cmd_set & CMD_SET_AE) - s3_virge_bitblt(virge, -1, 0); - break; - case 0xa96c:virge->s3d.lxend0 = (val >> 16) & 0x7ff; - virge->s3d.lxend1 = val & 0x7ff; - break; - case 0xa970:virge->s3d.ldx = (int32_t)val; - break; - case 0xa974:virge->s3d.lxstart = val; - break; - case 0xa978:virge->s3d.lystart = val & 0x7ff; - break; - case 0xa97c:virge->s3d.lycnt = val & 0x7ff; - virge->s3d.line_dir = val >> 31; - if (virge->s3d.cmd_set & CMD_SET_AE) - s3_virge_bitblt(virge, -1, 0); - break; + case 0xa4d4: + case 0xa8d4: + virge->s3d.src_base = val & 0x3ffff8; + break; + case 0xa4d8: + case 0xa8d8: + virge->s3d.dest_base = val & 0x3ffff8; + break; + case 0xa4dc: + case 0xa8dc: + virge->s3d.clip_l = (val >> 16) & 0x7ff; + virge->s3d.clip_r = val & 0x7ff; + break; + case 0xa4e0: + case 0xa8e0: + virge->s3d.clip_t = (val >> 16) & 0x7ff; + virge->s3d.clip_b = val & 0x7ff; + break; + case 0xa4e4: + case 0xa8e4: + virge->s3d.dest_str = (val >> 16) & 0xff8; + virge->s3d.src_str = val & 0xff8; + break; + case 0xa4e8: + case 0xace8: + virge->s3d.mono_pat_0 = val; + break; + case 0xa4ec: + case 0xacec: + virge->s3d.mono_pat_1 = val; + break; + case 0xa4f0: + case 0xacf0: + virge->s3d.pat_bg_clr = val; + break; + case 0xa4f4: + case 0xa8f4: + case 0xacf4: + virge->s3d.pat_fg_clr = val; + break; + case 0xa4f8: + virge->s3d.src_bg_clr = val; + break; + case 0xa4fc: + virge->s3d.src_fg_clr = val; + break; + case 0xa500: + case 0xa900: + virge->s3d.cmd_set = val; + if (!(val & CMD_SET_AE)) + s3_virge_bitblt(virge, -1, 0); + break; + case 0xa504: + virge->s3d.r_width = (val >> 16) & 0x7ff; + virge->s3d.r_height = val & 0x7ff; + break; + case 0xa508: + virge->s3d.rsrc_x = (val >> 16) & 0x7ff; + virge->s3d.rsrc_y = val & 0x7ff; + break; + case 0xa50c: + virge->s3d.rdest_x = (val >> 16) & 0x7ff; + virge->s3d.rdest_y = val & 0x7ff; + if (virge->s3d.cmd_set & CMD_SET_AE) + s3_virge_bitblt(virge, -1, 0); + break; + case 0xa96c: + virge->s3d.lxend0 = (val >> 16) & 0x7ff; + virge->s3d.lxend1 = val & 0x7ff; + break; + case 0xa970: + virge->s3d.ldx = (int32_t)val; + break; + case 0xa974: + virge->s3d.lxstart = val; + break; + case 0xa978: + virge->s3d.lystart = val & 0x7ff; + break; + case 0xa97c: + virge->s3d.lycnt = val & 0x7ff; + virge->s3d.line_dir = val >> 31; + if (virge->s3d.cmd_set & CMD_SET_AE) + s3_virge_bitblt(virge, -1, 0); + break; - case 0xad00:virge->s3d.cmd_set = val; - if (!(val & CMD_SET_AE)) - s3_virge_bitblt(virge, -1, 0); - break; - case 0xad68:virge->s3d.prdx = val; - break; - case 0xad6c:virge->s3d.prxstart = val; - break; - case 0xad70:virge->s3d.pldx = val; - break; - case 0xad74:virge->s3d.plxstart = val; - break; - case 0xad78:virge->s3d.pystart = val & 0x7ff; - break; - case 0xad7c:virge->s3d.pycnt = val & 0x300007ff; - if (virge->s3d.cmd_set & CMD_SET_AE) - s3_virge_bitblt(virge, -1, 0); - break; + case 0xad00: + virge->s3d.cmd_set = val; + if (!(val & CMD_SET_AE)) + s3_virge_bitblt(virge, -1, 0); + break; + case 0xad68: + virge->s3d.prdx = val; + break; + case 0xad6c: + virge->s3d.prxstart = val; + break; + case 0xad70: + virge->s3d.pldx = val; + break; + case 0xad74: + virge->s3d.plxstart = val; + break; + case 0xad78: + virge->s3d.pystart = val & 0x7ff; + break; + case 0xad7c: + virge->s3d.pycnt = val & 0x300007ff; + if (virge->s3d.cmd_set & CMD_SET_AE) + s3_virge_bitblt(virge, -1, 0); + break; - case 0xb4d4:virge->s3d_tri.z_base = val & 0x3ffff8; - break; - case 0xb4d8:virge->s3d_tri.dest_base = val & 0x3ffff8; - break; - case 0xb4dc:virge->s3d_tri.clip_l = (val >> 16) & 0x7ff; - virge->s3d_tri.clip_r = val & 0x7ff; - break; - case 0xb4e0:virge->s3d_tri.clip_t = (val >> 16) & 0x7ff; - virge->s3d_tri.clip_b = val & 0x7ff; - break; - case 0xb4e4:virge->s3d_tri.dest_str = (val >> 16) & 0xff8; - virge->s3d.src_str = val & 0xff8; - break; - case 0xb4e8:virge->s3d_tri.z_str = val & 0xff8; - break; - case 0xb4ec:virge->s3d_tri.tex_base = val & 0x3ffff8; - break; - case 0xb4f0:virge->s3d_tri.tex_bdr_clr = val & 0xffffff; - break; - case 0xb500:virge->s3d_tri.cmd_set = val; - if (!(val & CMD_SET_AE)) - queue_triangle(virge); -/* { - thread_set_event(virge->wake_render_thread); - thread_wait_event(virge->wake_main_thread, -1); - } */ -// s3_virge_triangle(virge); - break; - case 0xb504:virge->s3d_tri.tbv = val & 0xfffff; - break; - case 0xb508:virge->s3d_tri.tbu = val & 0xfffff; - break; - case 0xb50c:virge->s3d_tri.TdWdX = val; - break; - case 0xb510:virge->s3d_tri.TdWdY = val; - break; - case 0xb514:virge->s3d_tri.tws = val; - break; - case 0xb518:virge->s3d_tri.TdDdX = val; - break; - case 0xb51c:virge->s3d_tri.TdVdX = val; - break; - case 0xb520:virge->s3d_tri.TdUdX = val; - break; - case 0xb524:virge->s3d_tri.TdDdY = val; - break; - case 0xb528:virge->s3d_tri.TdVdY = val; - break; - case 0xb52c:virge->s3d_tri.TdUdY = val; - break; - case 0xb530:virge->s3d_tri.tds = val; - break; - case 0xb534:virge->s3d_tri.tvs = val; - break; - case 0xb538:virge->s3d_tri.tus = val; - break; - case 0xb53c:virge->s3d_tri.TdGdX = val >> 16; - virge->s3d_tri.TdBdX = val & 0xffff; - break; - case 0xb540:virge->s3d_tri.TdAdX = val >> 16; - virge->s3d_tri.TdRdX = val & 0xffff; - break; - case 0xb544:virge->s3d_tri.TdGdY = val >> 16; - virge->s3d_tri.TdBdY = val & 0xffff; - break; - case 0xb548:virge->s3d_tri.TdAdY = val >> 16; - virge->s3d_tri.TdRdY = val & 0xffff; - break; - case 0xb54c:virge->s3d_tri.tgs = (val >> 16) & 0xffff; - virge->s3d_tri.tbs = val & 0xffff; - break; - case 0xb550:virge->s3d_tri.tas = (val >> 16) & 0xffff; - virge->s3d_tri.trs = val & 0xffff; - break; + case 0xb4d4: + virge->s3d_tri.z_base = val & 0x3ffff8; + break; + case 0xb4d8: + virge->s3d_tri.dest_base = val & 0x3ffff8; + break; + case 0xb4dc: + virge->s3d_tri.clip_l = (val >> 16) & 0x7ff; + virge->s3d_tri.clip_r = val & 0x7ff; + break; + case 0xb4e0: + virge->s3d_tri.clip_t = (val >> 16) & 0x7ff; + virge->s3d_tri.clip_b = val & 0x7ff; + break; + case 0xb4e4: + virge->s3d_tri.dest_str = (val >> 16) & 0xff8; + virge->s3d.src_str = val & 0xff8; + break; + case 0xb4e8: + virge->s3d_tri.z_str = val & 0xff8; + break; + case 0xb4ec: + virge->s3d_tri.tex_base = val & 0x3ffff8; + break; + case 0xb4f0: + virge->s3d_tri.tex_bdr_clr = val & 0xffffff; + break; + case 0xb500: + virge->s3d_tri.cmd_set = val; + if (!(val & CMD_SET_AE)) + queue_triangle(virge); + /* { + thread_set_event(virge->wake_render_thread); + thread_wait_event(virge->wake_main_thread, -1); + } */ + // s3_virge_triangle(virge); + break; + case 0xb504: + virge->s3d_tri.tbv = val & 0xfffff; + break; + case 0xb508: + virge->s3d_tri.tbu = val & 0xfffff; + break; + case 0xb50c: + virge->s3d_tri.TdWdX = val; + break; + case 0xb510: + virge->s3d_tri.TdWdY = val; + break; + case 0xb514: + virge->s3d_tri.tws = val; + break; + case 0xb518: + virge->s3d_tri.TdDdX = val; + break; + case 0xb51c: + virge->s3d_tri.TdVdX = val; + break; + case 0xb520: + virge->s3d_tri.TdUdX = val; + break; + case 0xb524: + virge->s3d_tri.TdDdY = val; + break; + case 0xb528: + virge->s3d_tri.TdVdY = val; + break; + case 0xb52c: + virge->s3d_tri.TdUdY = val; + break; + case 0xb530: + virge->s3d_tri.tds = val; + break; + case 0xb534: + virge->s3d_tri.tvs = val; + break; + case 0xb538: + virge->s3d_tri.tus = val; + break; + case 0xb53c: + virge->s3d_tri.TdGdX = val >> 16; + virge->s3d_tri.TdBdX = val & 0xffff; + break; + case 0xb540: + virge->s3d_tri.TdAdX = val >> 16; + virge->s3d_tri.TdRdX = val & 0xffff; + break; + case 0xb544: + virge->s3d_tri.TdGdY = val >> 16; + virge->s3d_tri.TdBdY = val & 0xffff; + break; + case 0xb548: + virge->s3d_tri.TdAdY = val >> 16; + virge->s3d_tri.TdRdY = val & 0xffff; + break; + case 0xb54c: + virge->s3d_tri.tgs = (val >> 16) & 0xffff; + virge->s3d_tri.tbs = val & 0xffff; + break; + case 0xb550: + virge->s3d_tri.tas = (val >> 16) & 0xffff; + virge->s3d_tri.trs = val & 0xffff; + break; - case 0xb554:virge->s3d_tri.TdZdX = val; - break; - case 0xb558:virge->s3d_tri.TdZdY = val; - break; - case 0xb55c:virge->s3d_tri.tzs = val; - break; - case 0xb560:virge->s3d_tri.TdXdY12 = val; - break; - case 0xb564:virge->s3d_tri.txend12 = val; - break; - case 0xb568:virge->s3d_tri.TdXdY01 = val; - break; - case 0xb56c:virge->s3d_tri.txend01 = val; - break; - case 0xb570:virge->s3d_tri.TdXdY02 = val; - break; - case 0xb574:virge->s3d_tri.txs = val; - break; - case 0xb578:virge->s3d_tri.tys = val; - break; - case 0xb57c:virge->s3d_tri.ty01 = (val >> 16) & 0x7ff; - virge->s3d_tri.ty12 = val & 0x7ff; - virge->s3d_tri.tlr = val >> 31; - if (virge->s3d_tri.cmd_set & CMD_SET_AE) - queue_triangle(virge); -/* { - thread_set_event(virge->wake_render_thread); - thread_wait_event(virge->wake_main_thread, -1); - }*/ + case 0xb554: + virge->s3d_tri.TdZdX = val; + break; + case 0xb558: + virge->s3d_tri.TdZdY = val; + break; + case 0xb55c: + virge->s3d_tri.tzs = val; + break; + case 0xb560: + virge->s3d_tri.TdXdY12 = val; + break; + case 0xb564: + virge->s3d_tri.txend12 = val; + break; + case 0xb568: + virge->s3d_tri.TdXdY01 = val; + break; + case 0xb56c: + virge->s3d_tri.txend01 = val; + break; + case 0xb570: + virge->s3d_tri.TdXdY02 = val; + break; + case 0xb574: + virge->s3d_tri.txs = val; + break; + case 0xb578: + virge->s3d_tri.tys = val; + break; + case 0xb57c: + virge->s3d_tri.ty01 = (val >> 16) & 0x7ff; + virge->s3d_tri.ty12 = val & 0x7ff; + virge->s3d_tri.tlr = val >> 31; + if (virge->s3d_tri.cmd_set & CMD_SET_AE) + queue_triangle(virge); + /* { + thread_set_event(virge->wake_render_thread); + thread_wait_event(virge->wake_main_thread, -1); + }*/ -// s3_virge_triangle(virge); - break; + // s3_virge_triangle(virge); + break; - case 0xff20:s3_virge_mmio_write(addr, val, p); - break; - } + case 0xff20: + s3_virge_mmio_write(addr, val, p); + break; + } } -#define READ(addr, val) \ - do \ - { \ - switch (bpp) \ - { \ - case 0: /*8 bpp*/ \ - val = vram[addr & svga->vram_mask]; \ - break; \ - case 1: /*16 bpp*/ \ - val = *(uint16_t *)&vram[addr & svga->vram_mask]; \ - break; \ - case 2: /*24 bpp*/ \ - val = (*(uint32_t *)&vram[addr & svga->vram_mask]) & 0xffffff; \ - break; \ - } \ +#define READ(addr, val) \ + do { \ + switch (bpp) { \ + case 0: /*8 bpp*/ \ + val = vram[addr & svga->vram_mask]; \ + break; \ + case 1: /*16 bpp*/ \ + val = *(uint16_t *)&vram[addr & svga->vram_mask]; \ + break; \ + case 2: /*24 bpp*/ \ + val = (*(uint32_t *)&vram[addr & svga->vram_mask]) & 0xffffff; \ + break; \ + } \ } while (0) #define Z_READ(addr) *(uint16_t *)&vram[addr & svga->vram_mask] -#define Z_WRITE(addr, val) if (!(s3d_tri->cmd_set & CMD_SET_ZB_MODE)) *(uint16_t *)&vram[addr & svga->vram_mask] = val +#define Z_WRITE(addr, val) \ + if (!(s3d_tri->cmd_set & CMD_SET_ZB_MODE)) \ + *(uint16_t *)&vram[addr & svga->vram_mask] = val -#define CLIP(x, y) \ - do \ - { \ - if ((virge->s3d.cmd_set & CMD_SET_HC) && \ - (x < virge->s3d.clip_l || \ - x > virge->s3d.clip_r || \ - y < virge->s3d.clip_t || \ - y > virge->s3d.clip_b)) \ - update = 0; \ +#define CLIP(x, y) \ + do { \ + if ((virge->s3d.cmd_set & CMD_SET_HC) && \ + (x < virge->s3d.clip_l || x > virge->s3d.clip_r || y < virge->s3d.clip_t || y > virge->s3d.clip_b)) \ + update = 0; \ } while (0) -#define CLIP_3D(x, y) \ - do \ - { \ - if ((s3d_tri->cmd_set & CMD_SET_HC) && \ - (x < s3d_tri->clip_l || \ - x > s3d_tri->clip_r || \ - y < s3d_tri->clip_t || \ - y > s3d_tri->clip_b)) \ - update = 0; \ +#define CLIP_3D(x, y) \ + do { \ + if ((s3d_tri->cmd_set & CMD_SET_HC) && \ + (x < s3d_tri->clip_l || x > s3d_tri->clip_r || y < s3d_tri->clip_t || y > s3d_tri->clip_b)) \ + update = 0; \ } while (0) -#define Z_CLIP(Zzb, Zs) \ - do \ - { \ - if (!(s3d_tri->cmd_set & CMD_SET_ZB_MODE)) \ - switch ((s3d_tri->cmd_set >> 20) & 7) \ - { \ - case 0: update = 0; break; \ - case 1: if (Zs <= Zzb) update = 0; else Zzb = Zs; break; \ - case 2: if (Zs != Zzb) update = 0; else Zzb = Zs; break; \ - case 3: if (Zs < Zzb) update = 0; else Zzb = Zs; break; \ - case 4: if (Zs >= Zzb) update = 0; else Zzb = Zs; break; \ - case 5: if (Zs == Zzb) update = 0; else Zzb = Zs; break; \ - case 6: if (Zs > Zzb) update = 0; else Zzb = Zs; break; \ - case 7: update = 1; Zzb = Zs; break; \ - } \ +#define Z_CLIP(Zzb, Zs) \ + do { \ + if (!(s3d_tri->cmd_set & CMD_SET_ZB_MODE)) \ + switch ((s3d_tri->cmd_set >> 20) & 7) { \ + case 0: \ + update = 0; \ + break; \ + case 1: \ + if (Zs <= Zzb) \ + update = 0; \ + else \ + Zzb = Zs; \ + break; \ + case 2: \ + if (Zs != Zzb) \ + update = 0; \ + else \ + Zzb = Zs; \ + break; \ + case 3: \ + if (Zs < Zzb) \ + update = 0; \ + else \ + Zzb = Zs; \ + break; \ + case 4: \ + if (Zs >= Zzb) \ + update = 0; \ + else \ + Zzb = Zs; \ + break; \ + case 5: \ + if (Zs == Zzb) \ + update = 0; \ + else \ + Zzb = Zs; \ + break; \ + case 6: \ + if (Zs > Zzb) \ + update = 0; \ + else \ + Zzb = Zs; \ + break; \ + case 7: \ + update = 1; \ + Zzb = Zs; \ + break; \ + } \ } while (0) -#define MIX() \ - do \ - { \ - int c; \ - for (c = 0; c < 24; c++) \ - { \ - int d = (dest & (1 << c)) ? 1 : 0; \ - if (source & (1 << c)) d |= 2; \ - if (pattern & (1 << c)) d |= 4; \ - if (virge->s3d.rop & (1 << d)) out |= (1 << c); \ - } \ +#define MIX() \ + do { \ + int c; \ + for (c = 0; c < 24; c++) { \ + int d = (dest & (1 << c)) ? 1 : 0; \ + if (source & (1 << c)) \ + d |= 2; \ + if (pattern & (1 << c)) \ + d |= 4; \ + if (virge->s3d.rop & (1 << d)) \ + out |= (1 << c); \ + } \ } while (0) -#define WRITE(addr, val) \ - do \ - { \ - switch (bpp) \ - { \ - case 0: /*8 bpp*/ \ - vram[addr & svga->vram_mask] = val; \ - virge->svga.changedvram[(addr & svga->vram_mask) >> 12] = changeframecount; \ - break; \ - case 1: /*16 bpp*/ \ - *(uint16_t *)&vram[addr & svga->vram_mask] = val; \ - virge->svga.changedvram[(addr & svga->vram_mask) >> 12] = changeframecount; \ - break; \ - case 2: /*24 bpp*/ \ - *(uint32_t *)&vram[addr & svga->vram_mask] = (val & 0xffffff) | \ - (vram[(addr + 3) & svga->vram_mask] << 24); \ - virge->svga.changedvram[(addr & svga->vram_mask) >> 12] = changeframecount; \ - break; \ - } \ +#define WRITE(addr, val) \ + do { \ + switch (bpp) { \ + case 0: /*8 bpp*/ \ + vram[addr & svga->vram_mask] = val; \ + virge->svga.changedvram[(addr & svga->vram_mask) >> 12] = changeframecount; \ + break; \ + case 1: /*16 bpp*/ \ + *(uint16_t *)&vram[addr & svga->vram_mask] = val; \ + virge->svga.changedvram[(addr & svga->vram_mask) >> 12] = changeframecount; \ + break; \ + case 2: /*24 bpp*/ \ + *(uint32_t *)&vram[addr & svga->vram_mask] = \ + (val & 0xffffff) | (vram[(addr + 3) & svga->vram_mask] << 24); \ + virge->svga.changedvram[(addr & svga->vram_mask) >> 12] = changeframecount; \ + break; \ + } \ } while (0) static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) { - svga_t *svga = &virge->svga; - uint8_t *vram = virge->svga.vram; - uint32_t mono_pattern[64]; - int count_mask; - int x_inc = (virge->s3d.cmd_set & CMD_SET_XP) ? 1 : -1; - int y_inc = (virge->s3d.cmd_set & CMD_SET_YP) ? 1 : -1; - int bpp; - int x_mul; - int cpu_dat_shift; - uint32_t *pattern_data; - uint32_t src_fg_clr, src_bg_clr; + svga_t *svga = &virge->svga; + uint8_t *vram = virge->svga.vram; + uint32_t mono_pattern[64]; + int count_mask; + int x_inc = (virge->s3d.cmd_set & CMD_SET_XP) ? 1 : -1; + int y_inc = (virge->s3d.cmd_set & CMD_SET_YP) ? 1 : -1; + int bpp; + int x_mul; + int cpu_dat_shift; + uint32_t *pattern_data; + uint32_t src_fg_clr, src_bg_clr; - switch (virge->s3d.cmd_set & CMD_SET_FORMAT_MASK) { - case CMD_SET_FORMAT_8:bpp = 0; - x_mul = 1; - cpu_dat_shift = 8; - pattern_data = virge->s3d.pattern_8; - src_fg_clr = virge->s3d.src_fg_clr & 0xff; - src_bg_clr = virge->s3d.src_bg_clr & 0xff; - break; - case CMD_SET_FORMAT_16:bpp = 1; - x_mul = 2; - cpu_dat_shift = 16; - pattern_data = virge->s3d.pattern_16; - src_fg_clr = virge->s3d.src_fg_clr & 0xffff; - src_bg_clr = virge->s3d.src_bg_clr & 0xffff; - break; - case CMD_SET_FORMAT_24: - default:bpp = 2; - x_mul = 3; - cpu_dat_shift = 24; - pattern_data = virge->s3d.pattern_32; - src_fg_clr = virge->s3d.src_fg_clr; - src_bg_clr = virge->s3d.src_bg_clr; - break; - } - if (virge->s3d.cmd_set & CMD_SET_MP) - pattern_data = mono_pattern; + switch (virge->s3d.cmd_set & CMD_SET_FORMAT_MASK) { + case CMD_SET_FORMAT_8: + bpp = 0; + x_mul = 1; + cpu_dat_shift = 8; + pattern_data = virge->s3d.pattern_8; + src_fg_clr = virge->s3d.src_fg_clr & 0xff; + src_bg_clr = virge->s3d.src_bg_clr & 0xff; + break; + case CMD_SET_FORMAT_16: + bpp = 1; + x_mul = 2; + cpu_dat_shift = 16; + pattern_data = virge->s3d.pattern_16; + src_fg_clr = virge->s3d.src_fg_clr & 0xffff; + src_bg_clr = virge->s3d.src_bg_clr & 0xffff; + break; + case CMD_SET_FORMAT_24: + default: + bpp = 2; + x_mul = 3; + cpu_dat_shift = 24; + pattern_data = virge->s3d.pattern_32; + src_fg_clr = virge->s3d.src_fg_clr; + src_bg_clr = virge->s3d.src_bg_clr; + break; + } + if (virge->s3d.cmd_set & CMD_SET_MP) + pattern_data = mono_pattern; - switch (virge->s3d.cmd_set & CMD_SET_ITA_MASK) { - case CMD_SET_ITA_BYTE:count_mask = ~0x7; - break; - case CMD_SET_ITA_WORD:count_mask = ~0xf; - break; - case CMD_SET_ITA_DWORD: - default:count_mask = ~0x1f; - break; - } - if (virge->s3d.cmd_set & CMD_SET_MP) { - int x, y; - for (y = 0; y < 4; y++) { - for (x = 0; x < 8; x++) { - if (virge->s3d.mono_pat_0 & (1 << (x + y * 8))) - mono_pattern[y * 8 + x] = virge->s3d.pat_fg_clr; - else - mono_pattern[y * 8 + x] = virge->s3d.pat_bg_clr; - if (virge->s3d.mono_pat_1 & (1 << (x + y * 8))) - mono_pattern[(y + 4) * 8 + x] = virge->s3d.pat_fg_clr; - else - mono_pattern[(y + 4) * 8 + x] = virge->s3d.pat_bg_clr; - } - } - } - switch (virge->s3d.cmd_set & CMD_SET_COMMAND_MASK) { - case CMD_SET_COMMAND_NOP:break; + switch (virge->s3d.cmd_set & CMD_SET_ITA_MASK) { + case CMD_SET_ITA_BYTE: + count_mask = ~0x7; + break; + case CMD_SET_ITA_WORD: + count_mask = ~0xf; + break; + case CMD_SET_ITA_DWORD: + default: + count_mask = ~0x1f; + break; + } + if (virge->s3d.cmd_set & CMD_SET_MP) { + int x, y; + for (y = 0; y < 4; y++) { + for (x = 0; x < 8; x++) { + if (virge->s3d.mono_pat_0 & (1 << (x + y * 8))) + mono_pattern[y * 8 + x] = virge->s3d.pat_fg_clr; + else + mono_pattern[y * 8 + x] = virge->s3d.pat_bg_clr; + if (virge->s3d.mono_pat_1 & (1 << (x + y * 8))) + mono_pattern[(y + 4) * 8 + x] = virge->s3d.pat_fg_clr; + else + mono_pattern[(y + 4) * 8 + x] = virge->s3d.pat_bg_clr; + } + } + } + switch (virge->s3d.cmd_set & CMD_SET_COMMAND_MASK) { + case CMD_SET_COMMAND_NOP: + break; - case CMD_SET_COMMAND_BITBLT: - if (count == -1) { - virge->s3d.src_x = virge->s3d.rsrc_x; - virge->s3d.src_y = virge->s3d.rsrc_y; - virge->s3d.dest_x = virge->s3d.rdest_x; - virge->s3d.dest_y = virge->s3d.rdest_y; - virge->s3d.w = virge->s3d.r_width; - virge->s3d.h = virge->s3d.r_height; - virge->s3d.rop = (virge->s3d.cmd_set >> 17) & 0xff; - virge->s3d.data_left_count = 0; + case CMD_SET_COMMAND_BITBLT: + if (count == -1) { + virge->s3d.src_x = virge->s3d.rsrc_x; + virge->s3d.src_y = virge->s3d.rsrc_y; + virge->s3d.dest_x = virge->s3d.rdest_x; + virge->s3d.dest_y = virge->s3d.rdest_y; + virge->s3d.w = virge->s3d.r_width; + virge->s3d.h = virge->s3d.r_height; + virge->s3d.rop = (virge->s3d.cmd_set >> 17) & 0xff; + virge->s3d.data_left_count = 0; -/* pclog("BitBlt start %i,%i %i,%i %i,%i %02X %x %x\n", - virge->s3d.src_x, - virge->s3d.src_y, - virge->s3d.dest_x, - virge->s3d.dest_y, - virge->s3d.w, - virge->s3d.h, - virge->s3d.rop, - virge->s3d.src_base, - virge->s3d.dest_base);*/ + /* pclog("BitBlt start %i,%i %i,%i %i,%i %02X %x %x\n", + virge->s3d.src_x, + virge->s3d.src_y, + virge->s3d.dest_x, + virge->s3d.dest_y, + virge->s3d.w, + virge->s3d.h, + virge->s3d.rop, + virge->s3d.src_base, + virge->s3d.dest_base);*/ - if (virge->s3d.cmd_set & CMD_SET_IDS) - return; - } - if (!virge->s3d.h) - return; - while (count) { - uint32_t src_addr = virge->s3d.src_base + (virge->s3d.src_x * x_mul) + (virge->s3d.src_y * virge->s3d.src_str); - uint32_t dest_addr = virge->s3d.dest_base + (virge->s3d.dest_x * x_mul) + (virge->s3d.dest_y * virge->s3d.dest_str); - uint32_t source = 0, dest, pattern; - uint32_t out = 0; - int update = 1; + if (virge->s3d.cmd_set & CMD_SET_IDS) + return; + } + if (!virge->s3d.h) + return; + while (count) { + uint32_t src_addr = + virge->s3d.src_base + (virge->s3d.src_x * x_mul) + (virge->s3d.src_y * virge->s3d.src_str); + uint32_t dest_addr = + virge->s3d.dest_base + (virge->s3d.dest_x * x_mul) + (virge->s3d.dest_y * virge->s3d.dest_str); + uint32_t source = 0, dest, pattern; + uint32_t out = 0; + int update = 1; - switch (virge->s3d.cmd_set & (CMD_SET_MS | CMD_SET_IDS)) { - case 0: - case CMD_SET_MS:READ(src_addr, source); - if ((virge->s3d.cmd_set & CMD_SET_TP) && source == src_fg_clr) - update = 0; - break; - case CMD_SET_IDS: - if (virge->s3d.data_left_count) { - /*Handle shifting for 24-bit data*/ - source = virge->s3d.data_left; - source |= ((cpu_dat << virge->s3d.data_left_count) & ~0xff000000); - cpu_dat >>= (cpu_dat_shift - virge->s3d.data_left_count); - count -= (cpu_dat_shift - virge->s3d.data_left_count); - virge->s3d.data_left_count = 0; - if (count < cpu_dat_shift) { - virge->s3d.data_left = cpu_dat; - virge->s3d.data_left_count = count; - count = 0; - } - } else { - source = cpu_dat; - cpu_dat >>= cpu_dat_shift; - count -= cpu_dat_shift; - if (count < cpu_dat_shift) { - virge->s3d.data_left = cpu_dat; - virge->s3d.data_left_count = count; - count = 0; - } - } - if ((virge->s3d.cmd_set & CMD_SET_TP) && source == src_fg_clr) - update = 0; - break; - case CMD_SET_IDS | CMD_SET_MS:source = (cpu_dat & (1 << 31)) ? src_fg_clr : src_bg_clr; - if ((virge->s3d.cmd_set & CMD_SET_TP) && !(cpu_dat & (1 << 31))) - update = 0; - cpu_dat <<= 1; - count--; - break; - } + switch (virge->s3d.cmd_set & (CMD_SET_MS | CMD_SET_IDS)) { + case 0: + case CMD_SET_MS: + READ(src_addr, source); + if ((virge->s3d.cmd_set & CMD_SET_TP) && source == src_fg_clr) + update = 0; + break; + case CMD_SET_IDS: + if (virge->s3d.data_left_count) { + /*Handle shifting for 24-bit data*/ + source = virge->s3d.data_left; + source |= ((cpu_dat << virge->s3d.data_left_count) & ~0xff000000); + cpu_dat >>= (cpu_dat_shift - virge->s3d.data_left_count); + count -= (cpu_dat_shift - virge->s3d.data_left_count); + virge->s3d.data_left_count = 0; + if (count < cpu_dat_shift) { + virge->s3d.data_left = cpu_dat; + virge->s3d.data_left_count = count; + count = 0; + } + } else { + source = cpu_dat; + cpu_dat >>= cpu_dat_shift; + count -= cpu_dat_shift; + if (count < cpu_dat_shift) { + virge->s3d.data_left = cpu_dat; + virge->s3d.data_left_count = count; + count = 0; + } + } + if ((virge->s3d.cmd_set & CMD_SET_TP) && source == src_fg_clr) + update = 0; + break; + case CMD_SET_IDS | CMD_SET_MS: + source = (cpu_dat & (1 << 31)) ? src_fg_clr : src_bg_clr; + if ((virge->s3d.cmd_set & CMD_SET_TP) && !(cpu_dat & (1 << 31))) + update = 0; + cpu_dat <<= 1; + count--; + break; + } - CLIP(virge->s3d.dest_x, virge->s3d.dest_y); + CLIP(virge->s3d.dest_x, virge->s3d.dest_y); - if (update) { - READ(dest_addr, dest); - pattern = pattern_data[(virge->s3d.dest_y & 7) * 8 + (virge->s3d.dest_x & 7)]; - MIX(); + if (update) { + READ(dest_addr, dest); + pattern = pattern_data[(virge->s3d.dest_y & 7) * 8 + (virge->s3d.dest_x & 7)]; + MIX(); - WRITE(dest_addr, out); - } + WRITE(dest_addr, out); + } - virge->s3d.src_x += x_inc; - virge->s3d.src_x &= 0x7ff; - virge->s3d.dest_x += x_inc; - virge->s3d.dest_x &= 0x7ff; - if (!virge->s3d.w) { - virge->s3d.src_x = virge->s3d.rsrc_x; - virge->s3d.dest_x = virge->s3d.rdest_x; - virge->s3d.w = virge->s3d.r_width; + virge->s3d.src_x += x_inc; + virge->s3d.src_x &= 0x7ff; + virge->s3d.dest_x += x_inc; + virge->s3d.dest_x &= 0x7ff; + if (!virge->s3d.w) { + virge->s3d.src_x = virge->s3d.rsrc_x; + virge->s3d.dest_x = virge->s3d.rdest_x; + virge->s3d.w = virge->s3d.r_width; - virge->s3d.src_y += y_inc; - virge->s3d.dest_y += y_inc; - virge->s3d.h--; + virge->s3d.src_y += y_inc; + virge->s3d.dest_y += y_inc; + virge->s3d.h--; - switch (virge->s3d.cmd_set & (CMD_SET_MS | CMD_SET_IDS)) { - case CMD_SET_IDS:cpu_dat >>= (count - (count & count_mask)); - count &= count_mask; - virge->s3d.data_left_count = 0; - break; + switch (virge->s3d.cmd_set & (CMD_SET_MS | CMD_SET_IDS)) { + case CMD_SET_IDS: + cpu_dat >>= (count - (count & count_mask)); + count &= count_mask; + virge->s3d.data_left_count = 0; + break; - case CMD_SET_IDS | CMD_SET_MS:cpu_dat <<= (count - (count & count_mask)); - count &= count_mask; - break; - } - if (!virge->s3d.h) { - return; - } - } else - virge->s3d.w--; - } - break; + case CMD_SET_IDS | CMD_SET_MS: + cpu_dat <<= (count - (count & count_mask)); + count &= count_mask; + break; + } + if (!virge->s3d.h) { + return; + } + } else + virge->s3d.w--; + } + break; - case CMD_SET_COMMAND_RECTFILL: - /*No source, pattern = pat_fg_clr*/ - if (count == -1) { - virge->s3d.src_x = virge->s3d.rsrc_x; - virge->s3d.src_y = virge->s3d.rsrc_y; - virge->s3d.dest_x = virge->s3d.rdest_x; - virge->s3d.dest_y = virge->s3d.rdest_y; - virge->s3d.w = virge->s3d.r_width; - virge->s3d.h = virge->s3d.r_height; - virge->s3d.rop = (virge->s3d.cmd_set >> 17) & 0xff; + case CMD_SET_COMMAND_RECTFILL: + /*No source, pattern = pat_fg_clr*/ + if (count == -1) { + virge->s3d.src_x = virge->s3d.rsrc_x; + virge->s3d.src_y = virge->s3d.rsrc_y; + virge->s3d.dest_x = virge->s3d.rdest_x; + virge->s3d.dest_y = virge->s3d.rdest_y; + virge->s3d.w = virge->s3d.r_width; + virge->s3d.h = virge->s3d.r_height; + virge->s3d.rop = (virge->s3d.cmd_set >> 17) & 0xff; -/* pclog("RctFll start %i,%i %i,%i %02X %08x\n", virge->s3d.dest_x, - virge->s3d.dest_y, - virge->s3d.w, - virge->s3d.h, - virge->s3d.rop, virge->s3d.dest_base);*/ - } + /* pclog("RctFll start %i,%i %i,%i %02X %08x\n", virge->s3d.dest_x, + virge->s3d.dest_y, + virge->s3d.w, + virge->s3d.h, + virge->s3d.rop, virge->s3d.dest_base);*/ + } - while (count && virge->s3d.h) { - uint32_t dest_addr = virge->s3d.dest_base + (virge->s3d.dest_x * x_mul) + (virge->s3d.dest_y * virge->s3d.dest_str); - uint32_t source = 0, dest, pattern = virge->s3d.pat_fg_clr; - uint32_t out = 0; - int update = 1; + while (count && virge->s3d.h) { + uint32_t dest_addr = + virge->s3d.dest_base + (virge->s3d.dest_x * x_mul) + (virge->s3d.dest_y * virge->s3d.dest_str); + uint32_t source = 0, dest, pattern = virge->s3d.pat_fg_clr; + uint32_t out = 0; + int update = 1; - CLIP(virge->s3d.dest_x, virge->s3d.dest_y); + CLIP(virge->s3d.dest_x, virge->s3d.dest_y); - if (update) { - READ(dest_addr, dest); + if (update) { + READ(dest_addr, dest); - MIX(); + MIX(); - WRITE(dest_addr, out); - } + WRITE(dest_addr, out); + } - virge->s3d.src_x += x_inc; - virge->s3d.src_x &= 0x7ff; - virge->s3d.dest_x += x_inc; - virge->s3d.dest_x &= 0x7ff; - if (!virge->s3d.w) { - virge->s3d.src_x = virge->s3d.rsrc_x; - virge->s3d.dest_x = virge->s3d.rdest_x; - virge->s3d.w = virge->s3d.r_width; + virge->s3d.src_x += x_inc; + virge->s3d.src_x &= 0x7ff; + virge->s3d.dest_x += x_inc; + virge->s3d.dest_x &= 0x7ff; + if (!virge->s3d.w) { + virge->s3d.src_x = virge->s3d.rsrc_x; + virge->s3d.dest_x = virge->s3d.rdest_x; + virge->s3d.w = virge->s3d.r_width; - virge->s3d.src_y += y_inc; - virge->s3d.dest_y += y_inc; - virge->s3d.h--; - if (!virge->s3d.h) { - return; - } - } else - virge->s3d.w--; - count--; - } - break; + virge->s3d.src_y += y_inc; + virge->s3d.dest_y += y_inc; + virge->s3d.h--; + if (!virge->s3d.h) { + return; + } + } else + virge->s3d.w--; + count--; + } + break; - case CMD_SET_COMMAND_LINE: - if (count == -1) { - virge->s3d.dest_x = virge->s3d.lxstart; - virge->s3d.dest_y = virge->s3d.lystart; - virge->s3d.h = virge->s3d.lycnt; - virge->s3d.rop = (virge->s3d.cmd_set >> 17) & 0xff; - } - while (virge->s3d.h) { - int x; - int new_x; - int first_pixel = 1; + case CMD_SET_COMMAND_LINE: + if (count == -1) { + virge->s3d.dest_x = virge->s3d.lxstart; + virge->s3d.dest_y = virge->s3d.lystart; + virge->s3d.h = virge->s3d.lycnt; + virge->s3d.rop = (virge->s3d.cmd_set >> 17) & 0xff; + } + while (virge->s3d.h) { + int x; + int new_x; + int first_pixel = 1; - x = virge->s3d.dest_x >> 20; + x = virge->s3d.dest_x >> 20; - if (virge->s3d.h == virge->s3d.lycnt && - ((virge->s3d.line_dir && x > virge->s3d.lxend0) || - (!virge->s3d.line_dir && x < virge->s3d.lxend0))) - x = virge->s3d.lxend0; + if (virge->s3d.h == virge->s3d.lycnt && + ((virge->s3d.line_dir && x > virge->s3d.lxend0) || (!virge->s3d.line_dir && x < virge->s3d.lxend0))) + x = virge->s3d.lxend0; - if (virge->s3d.h == 1) - new_x = virge->s3d.lxend1 + (virge->s3d.line_dir ? 1 : -1); - else - new_x = (virge->s3d.dest_x + virge->s3d.ldx) >> 20; + if (virge->s3d.h == 1) + new_x = virge->s3d.lxend1 + (virge->s3d.line_dir ? 1 : -1); + else + new_x = (virge->s3d.dest_x + virge->s3d.ldx) >> 20; - if ((virge->s3d.line_dir && x > new_x) || - (!virge->s3d.line_dir && x < new_x)) - goto skip_line; + if ((virge->s3d.line_dir && x > new_x) || (!virge->s3d.line_dir && x < new_x)) + goto skip_line; - do { - uint32_t dest_addr = virge->s3d.dest_base + (x * x_mul) + (virge->s3d.dest_y * virge->s3d.dest_str); - uint32_t source = 0, dest, pattern; - uint32_t out = 0; - int update = 1; + do { + uint32_t dest_addr = + virge->s3d.dest_base + (x * x_mul) + (virge->s3d.dest_y * virge->s3d.dest_str); + uint32_t source = 0, dest, pattern; + uint32_t out = 0; + int update = 1; - if ((virge->s3d.h == virge->s3d.lycnt || !first_pixel) && - ((virge->s3d.line_dir && x < virge->s3d.lxend0) || - (!virge->s3d.line_dir && x > virge->s3d.lxend0))) - update = 0; + if ((virge->s3d.h == virge->s3d.lycnt || !first_pixel) && + ((virge->s3d.line_dir && x < virge->s3d.lxend0) || + (!virge->s3d.line_dir && x > virge->s3d.lxend0))) + update = 0; - if ((virge->s3d.h == 1 || !first_pixel) && - ((virge->s3d.line_dir && x > virge->s3d.lxend1) || - (!virge->s3d.line_dir && x < virge->s3d.lxend1))) - update = 0; + if ((virge->s3d.h == 1 || !first_pixel) && ((virge->s3d.line_dir && x > virge->s3d.lxend1) || + (!virge->s3d.line_dir && x < virge->s3d.lxend1))) + update = 0; - CLIP(x, virge->s3d.dest_y); + CLIP(x, virge->s3d.dest_y); - if (update) { - READ(dest_addr, dest); - pattern = virge->s3d.pat_fg_clr; + if (update) { + READ(dest_addr, dest); + pattern = virge->s3d.pat_fg_clr; - MIX(); + MIX(); - WRITE(dest_addr, out); - } + WRITE(dest_addr, out); + } - if (x < new_x) - x++; - else if (x > new_x) - x--; - first_pixel = 0; - } while (x != new_x); + if (x < new_x) + x++; + else if (x > new_x) + x--; + first_pixel = 0; + } while (x != new_x); - skip_line: - virge->s3d.dest_x += virge->s3d.ldx; - virge->s3d.dest_y--; - virge->s3d.h--; - } - break; + skip_line: + virge->s3d.dest_x += virge->s3d.ldx; + virge->s3d.dest_y--; + virge->s3d.h--; + } + break; - case CMD_SET_COMMAND_POLY: - /*No source*/ - if (virge->s3d.pycnt & (1 << 28)) - virge->s3d.dest_r = virge->s3d.prxstart; - if (virge->s3d.pycnt & (1 << 29)) - virge->s3d.dest_l = virge->s3d.plxstart; - virge->s3d.h = virge->s3d.pycnt & 0x7ff; - virge->s3d.rop = (virge->s3d.cmd_set >> 17) & 0xff; - //pclog("Start poly - l=%08x r=%08x h=%i rop=%02x\n", virge->s3d.dest_l, virge->s3d.dest_r, virge->s3d.h, virge->s3d.rop); - while (virge->s3d.h) { - int x = virge->s3d.dest_l >> 20; - int xend = virge->s3d.dest_r >> 20; - int y = virge->s3d.pystart & 0x7ff; - int xdir = (x < xend) ? 1 : -1; - //pclog(" %03i: %i - %i %08x-%08x\n", y, x, xend, virge->s3d.dest_l, virge->s3d.dest_r); - do { - uint32_t dest_addr = virge->s3d.dest_base + (x * x_mul) + (y * virge->s3d.dest_str); - uint32_t source = 0, dest, pattern; - uint32_t out = 0; - int update = 1; + case CMD_SET_COMMAND_POLY: + /*No source*/ + if (virge->s3d.pycnt & (1 << 28)) + virge->s3d.dest_r = virge->s3d.prxstart; + if (virge->s3d.pycnt & (1 << 29)) + virge->s3d.dest_l = virge->s3d.plxstart; + virge->s3d.h = virge->s3d.pycnt & 0x7ff; + virge->s3d.rop = (virge->s3d.cmd_set >> 17) & 0xff; + // pclog("Start poly - l=%08x r=%08x h=%i rop=%02x\n", virge->s3d.dest_l, virge->s3d.dest_r, virge->s3d.h, + // virge->s3d.rop); + while (virge->s3d.h) { + int x = virge->s3d.dest_l >> 20; + int xend = virge->s3d.dest_r >> 20; + int y = virge->s3d.pystart & 0x7ff; + int xdir = (x < xend) ? 1 : -1; + // pclog(" %03i: %i - %i %08x-%08x\n", y, x, xend, virge->s3d.dest_l, virge->s3d.dest_r); + do { + uint32_t dest_addr = virge->s3d.dest_base + (x * x_mul) + (y * virge->s3d.dest_str); + uint32_t source = 0, dest, pattern; + uint32_t out = 0; + int update = 1; - CLIP(x, y); + CLIP(x, y); - if (update) { - READ(dest_addr, dest); - pattern = pattern_data[(y & 7) * 8 + (x & 7)]; - MIX(); + if (update) { + READ(dest_addr, dest); + pattern = pattern_data[(y & 7) * 8 + (x & 7)]; + MIX(); - WRITE(dest_addr, out); - } + WRITE(dest_addr, out); + } - x = (x + xdir) & 0x7ff; - } while (x != (xend + xdir)); + x = (x + xdir) & 0x7ff; + } while (x != (xend + xdir)); - virge->s3d.dest_l += virge->s3d.pldx; - virge->s3d.dest_r += virge->s3d.prdx; - virge->s3d.h--; - virge->s3d.pystart = (virge->s3d.pystart - 1) & 0x7ff; - } - break; + virge->s3d.dest_l += virge->s3d.pldx; + virge->s3d.dest_r += virge->s3d.prdx; + virge->s3d.h--; + virge->s3d.pystart = (virge->s3d.pystart - 1) & 0x7ff; + } + break; - default:fatal("s3_virge_bitblt : blit command %i %08x\n", (virge->s3d.cmd_set >> 27) & 0xf, virge->s3d.cmd_set); - } + default: + fatal("s3_virge_bitblt : blit command %i %08x\n", (virge->s3d.cmd_set >> 27) & 0xf, virge->s3d.cmd_set); + } } -#define RGB15_TO_24(val, r, g, b) b = ((val & 0x001f) << 3) | ((val & 0x001f) >> 2); \ - g = ((val & 0x03e0) >> 2) | ((val & 0x03e0) >> 7); \ - r = ((val & 0x7c00) >> 7) | ((val & 0x7c00) >> 12); +#define RGB15_TO_24(val, r, g, b) \ + b = ((val & 0x001f) << 3) | ((val & 0x001f) >> 2); \ + g = ((val & 0x03e0) >> 2) | ((val & 0x03e0) >> 7); \ + r = ((val & 0x7c00) >> 7) | ((val & 0x7c00) >> 12); -#define RGB24_TO_24(val, r, g, b) b = val & 0xff; \ - g = (val & 0xff00) >> 8; \ - r = (val & 0xff0000) >> 16 +#define RGB24_TO_24(val, r, g, b) \ + b = val & 0xff; \ + g = (val & 0xff00) >> 8; \ + r = (val & 0xff0000) >> 16 -#define RGB15(r, g, b, dest) \ - if (virge->dithering_enabled) \ - { \ - int add = dither[_y & 3][_x & 3]; \ - int _r = (r > 248) ? 248 : r+add; \ - int _g = (g > 248) ? 248 : g+add; \ - int _b = (b > 248) ? 248 : b+add; \ - dest = ((_b >> 3) & 0x1f) | (((_g >> 3) & 0x1f) << 5) | (((_r >> 3) & 0x1f) << 10); \ - } \ - else \ +#define RGB15(r, g, b, dest) \ + if (virge->dithering_enabled) { \ + int add = dither[_y & 3][_x & 3]; \ + int _r = (r > 248) ? 248 : r + add; \ + int _g = (g > 248) ? 248 : g + add; \ + int _b = (b > 248) ? 248 : b + add; \ + dest = ((_b >> 3) & 0x1f) | (((_g >> 3) & 0x1f) << 5) | (((_r >> 3) & 0x1f) << 10); \ + } else \ dest = ((b >> 3) & 0x1f) | (((g >> 3) & 0x1f) << 5) | (((r >> 3) & 0x1f) << 10) #define RGB24(r, g, b) ((b) | ((g) << 8) | ((r) << 16)) typedef struct rgba_t { - int r, g, b, a; + int r, g, b, a; } rgba_t; typedef struct s3d_state_t { - int32_t r, g, b, a, u, v, d, w; + int32_t r, g, b, a, u, v, d, w; - int32_t base_r, base_g, base_b, base_a, base_u, base_v, base_d, base_w; + int32_t base_r, base_g, base_b, base_a, base_u, base_v, base_d, base_w; - uint32_t base_z; + uint32_t base_z; - uint32_t tbu, tbv; + uint32_t tbu, tbv; - uint32_t cmd_set; - int max_d; + uint32_t cmd_set; + int max_d; - uint16_t *texture[10]; + uint16_t *texture[10]; - uint32_t tex_bdr_clr; + uint32_t tex_bdr_clr; - int32_t x1, x2; - int y; + int32_t x1, x2; + int y; - rgba_t dest_rgba; + rgba_t dest_rgba; } s3d_state_t; typedef struct s3d_texture_state_t { - int level; - int texture_shift; + int level; + int texture_shift; - int32_t u, v; + int32_t u, v; } s3d_texture_state_t; static void (*tex_read)(s3d_state_t *state, s3d_texture_state_t *texture_state, rgba_t *out); @@ -2396,1709 +2676,1681 @@ static void (*dest_pixel)(s3d_state_t *state); static int _x, _y; static void tex_ARGB1555(s3d_state_t *state, s3d_texture_state_t *texture_state, rgba_t *out) { - int offset = ((texture_state->u & 0x7fc0000) >> texture_state->texture_shift) + - (((texture_state->v & 0x7fc0000) >> texture_state->texture_shift) << texture_state->level); - uint16_t val = state->texture[texture_state->level][offset]; + int offset = ((texture_state->u & 0x7fc0000) >> texture_state->texture_shift) + + (((texture_state->v & 0x7fc0000) >> texture_state->texture_shift) << texture_state->level); + uint16_t val = state->texture[texture_state->level][offset]; - out->r = ((val & 0x7c00) >> 7) | ((val & 0x7000) >> 12); - out->g = ((val & 0x03e0) >> 2) | ((val & 0x0380) >> 7); - out->b = ((val & 0x001f) << 3) | ((val & 0x001c) >> 2); - out->a = (val & 0x8000) ? 0xff : 0; + out->r = ((val & 0x7c00) >> 7) | ((val & 0x7000) >> 12); + out->g = ((val & 0x03e0) >> 2) | ((val & 0x0380) >> 7); + out->b = ((val & 0x001f) << 3) | ((val & 0x001c) >> 2); + out->a = (val & 0x8000) ? 0xff : 0; } static void tex_ARGB1555_nowrap(s3d_state_t *state, s3d_texture_state_t *texture_state, rgba_t *out) { - int offset = ((texture_state->u & 0x7fc0000) >> texture_state->texture_shift) + - (((texture_state->v & 0x7fc0000) >> texture_state->texture_shift) << texture_state->level); - uint16_t val = state->texture[texture_state->level][offset]; + int offset = ((texture_state->u & 0x7fc0000) >> texture_state->texture_shift) + + (((texture_state->v & 0x7fc0000) >> texture_state->texture_shift) << texture_state->level); + uint16_t val = state->texture[texture_state->level][offset]; - if (((texture_state->u | texture_state->v) & 0xf8000000) == 0xf8000000) - val = state->tex_bdr_clr; + if (((texture_state->u | texture_state->v) & 0xf8000000) == 0xf8000000) + val = state->tex_bdr_clr; - out->r = ((val & 0x7c00) >> 7) | ((val & 0x7000) >> 12); - out->g = ((val & 0x03e0) >> 2) | ((val & 0x0380) >> 7); - out->b = ((val & 0x001f) << 3) | ((val & 0x001c) >> 2); - out->a = (val & 0x8000) ? 0xff : 0; + out->r = ((val & 0x7c00) >> 7) | ((val & 0x7000) >> 12); + out->g = ((val & 0x03e0) >> 2) | ((val & 0x0380) >> 7); + out->b = ((val & 0x001f) << 3) | ((val & 0x001c) >> 2); + out->a = (val & 0x8000) ? 0xff : 0; } static void tex_ARGB4444(s3d_state_t *state, s3d_texture_state_t *texture_state, rgba_t *out) { - int offset = ((texture_state->u & 0x7fc0000) >> texture_state->texture_shift) + - (((texture_state->v & 0x7fc0000) >> texture_state->texture_shift) << texture_state->level); - uint16_t val = state->texture[texture_state->level][offset]; + int offset = ((texture_state->u & 0x7fc0000) >> texture_state->texture_shift) + + (((texture_state->v & 0x7fc0000) >> texture_state->texture_shift) << texture_state->level); + uint16_t val = state->texture[texture_state->level][offset]; - out->r = ((val & 0x0f00) >> 4) | ((val & 0x0f00) >> 8); - out->g = (val & 0x00f0) | ((val & 0x00f0) >> 4); - out->b = ((val & 0x000f) << 4) | (val & 0x000f); - out->a = ((val & 0xf000) >> 8) | ((val & 0xf000) >> 12); + out->r = ((val & 0x0f00) >> 4) | ((val & 0x0f00) >> 8); + out->g = (val & 0x00f0) | ((val & 0x00f0) >> 4); + out->b = ((val & 0x000f) << 4) | (val & 0x000f); + out->a = ((val & 0xf000) >> 8) | ((val & 0xf000) >> 12); } static void tex_ARGB4444_nowrap(s3d_state_t *state, s3d_texture_state_t *texture_state, rgba_t *out) { - int offset = ((texture_state->u & 0x7fc0000) >> texture_state->texture_shift) + - (((texture_state->v & 0x7fc0000) >> texture_state->texture_shift) << texture_state->level); - uint16_t val = state->texture[texture_state->level][offset]; + int offset = ((texture_state->u & 0x7fc0000) >> texture_state->texture_shift) + + (((texture_state->v & 0x7fc0000) >> texture_state->texture_shift) << texture_state->level); + uint16_t val = state->texture[texture_state->level][offset]; - if (((texture_state->u | texture_state->v) & 0xf8000000) == 0xf8000000) - val = state->tex_bdr_clr; + if (((texture_state->u | texture_state->v) & 0xf8000000) == 0xf8000000) + val = state->tex_bdr_clr; - out->r = ((val & 0x0f00) >> 4) | ((val & 0x0f00) >> 8); - out->g = (val & 0x00f0) | ((val & 0x00f0) >> 4); - out->b = ((val & 0x000f) << 4) | (val & 0x000f); - out->a = ((val & 0xf000) >> 8) | ((val & 0xf000) >> 12); + out->r = ((val & 0x0f00) >> 4) | ((val & 0x0f00) >> 8); + out->g = (val & 0x00f0) | ((val & 0x00f0) >> 4); + out->b = ((val & 0x000f) << 4) | (val & 0x000f); + out->a = ((val & 0xf000) >> 8) | ((val & 0xf000) >> 12); } static void tex_ARGB8888(s3d_state_t *state, s3d_texture_state_t *texture_state, rgba_t *out) { - int offset = ((texture_state->u & 0x7fc0000) >> texture_state->texture_shift) + - (((texture_state->v & 0x7fc0000) >> texture_state->texture_shift) << texture_state->level); - uint32_t val = ((uint32_t *)state->texture[texture_state->level])[offset]; + int offset = ((texture_state->u & 0x7fc0000) >> texture_state->texture_shift) + + (((texture_state->v & 0x7fc0000) >> texture_state->texture_shift) << texture_state->level); + uint32_t val = ((uint32_t *)state->texture[texture_state->level])[offset]; - out->r = (val >> 16) & 0xff; - out->g = (val >> 8) & 0xff; - out->b = val & 0xff; - out->a = (val >> 24) & 0xff; + out->r = (val >> 16) & 0xff; + out->g = (val >> 8) & 0xff; + out->b = val & 0xff; + out->a = (val >> 24) & 0xff; } static void tex_ARGB8888_nowrap(s3d_state_t *state, s3d_texture_state_t *texture_state, rgba_t *out) { - int offset = ((texture_state->u & 0x7fc0000) >> texture_state->texture_shift) + - (((texture_state->v & 0x7fc0000) >> texture_state->texture_shift) << texture_state->level); - uint32_t val = ((uint32_t *)state->texture[texture_state->level])[offset]; + int offset = ((texture_state->u & 0x7fc0000) >> texture_state->texture_shift) + + (((texture_state->v & 0x7fc0000) >> texture_state->texture_shift) << texture_state->level); + uint32_t val = ((uint32_t *)state->texture[texture_state->level])[offset]; - if (((texture_state->u | texture_state->v) & 0xf8000000) == 0xf8000000) - val = state->tex_bdr_clr; + if (((texture_state->u | texture_state->v) & 0xf8000000) == 0xf8000000) + val = state->tex_bdr_clr; - out->r = (val >> 16) & 0xff; - out->g = (val >> 8) & 0xff; - out->b = val & 0xff; - out->a = (val >> 24) & 0xff; + out->r = (val >> 16) & 0xff; + out->g = (val >> 8) & 0xff; + out->b = val & 0xff; + out->a = (val >> 24) & 0xff; } static void tex_sample_normal(s3d_state_t *state) { - s3d_texture_state_t texture_state; + s3d_texture_state_t texture_state; - texture_state.level = state->max_d; - texture_state.texture_shift = 18 + (9 - texture_state.level); - texture_state.u = state->u + state->tbu; - texture_state.v = state->v + state->tbv; + texture_state.level = state->max_d; + texture_state.texture_shift = 18 + (9 - texture_state.level); + texture_state.u = state->u + state->tbu; + texture_state.v = state->v + state->tbv; - tex_read(state, &texture_state, &state->dest_rgba); + tex_read(state, &texture_state, &state->dest_rgba); } static void tex_sample_normal_filter(s3d_state_t *state) { - s3d_texture_state_t texture_state; - int tex_offset; - rgba_t tex_samples[4]; - int du, dv; - int d[4]; + s3d_texture_state_t texture_state; + int tex_offset; + rgba_t tex_samples[4]; + int du, dv; + int d[4]; - texture_state.level = state->max_d; - texture_state.texture_shift = 18 + (9 - texture_state.level); - tex_offset = 1 << texture_state.texture_shift; + texture_state.level = state->max_d; + texture_state.texture_shift = 18 + (9 - texture_state.level); + tex_offset = 1 << texture_state.texture_shift; - texture_state.u = state->u + state->tbu; - texture_state.v = state->v + state->tbv; - tex_read(state, &texture_state, &tex_samples[0]); - du = (texture_state.u >> (texture_state.texture_shift - 8)) & 0xff; - dv = (texture_state.v >> (texture_state.texture_shift - 8)) & 0xff; + texture_state.u = state->u + state->tbu; + texture_state.v = state->v + state->tbv; + tex_read(state, &texture_state, &tex_samples[0]); + du = (texture_state.u >> (texture_state.texture_shift - 8)) & 0xff; + dv = (texture_state.v >> (texture_state.texture_shift - 8)) & 0xff; - texture_state.u = state->u + state->tbu + tex_offset; - texture_state.v = state->v + state->tbv; - tex_read(state, &texture_state, &tex_samples[1]); + texture_state.u = state->u + state->tbu + tex_offset; + texture_state.v = state->v + state->tbv; + tex_read(state, &texture_state, &tex_samples[1]); - texture_state.u = state->u + state->tbu; - texture_state.v = state->v + state->tbv + tex_offset; - tex_read(state, &texture_state, &tex_samples[2]); + texture_state.u = state->u + state->tbu; + texture_state.v = state->v + state->tbv + tex_offset; + tex_read(state, &texture_state, &tex_samples[2]); - texture_state.u = state->u + state->tbu + tex_offset; - texture_state.v = state->v + state->tbv + tex_offset; - tex_read(state, &texture_state, &tex_samples[3]); + texture_state.u = state->u + state->tbu + tex_offset; + texture_state.v = state->v + state->tbv + tex_offset; + tex_read(state, &texture_state, &tex_samples[3]); - d[0] = (256 - du) * (256 - dv); - d[1] = du * (256 - dv); - d[2] = (256 - du) * dv; - d[3] = du * dv; + d[0] = (256 - du) * (256 - dv); + d[1] = du * (256 - dv); + d[2] = (256 - du) * dv; + d[3] = du * dv; - state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; - state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; - state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; - state->dest_rgba.a = (tex_samples[0].a * d[0] + tex_samples[1].a * d[1] + tex_samples[2].a * d[2] + tex_samples[3].a * d[3]) >> 16; + state->dest_rgba.r = + (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; + state->dest_rgba.g = + (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; + state->dest_rgba.b = + (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; + state->dest_rgba.a = + (tex_samples[0].a * d[0] + tex_samples[1].a * d[1] + tex_samples[2].a * d[2] + tex_samples[3].a * d[3]) >> 16; } static void tex_sample_mipmap(s3d_state_t *state) { - s3d_texture_state_t texture_state; + s3d_texture_state_t texture_state; - texture_state.level = (state->d < 0) ? state->max_d : state->max_d - ((state->d >> 27) & 0xf); - if (texture_state.level < 0) - texture_state.level = 0; - texture_state.texture_shift = 18 + (9 - texture_state.level); - texture_state.u = state->u + state->tbu; - texture_state.v = state->v + state->tbv; + texture_state.level = (state->d < 0) ? state->max_d : state->max_d - ((state->d >> 27) & 0xf); + if (texture_state.level < 0) + texture_state.level = 0; + texture_state.texture_shift = 18 + (9 - texture_state.level); + texture_state.u = state->u + state->tbu; + texture_state.v = state->v + state->tbv; - tex_read(state, &texture_state, &state->dest_rgba); + tex_read(state, &texture_state, &state->dest_rgba); } static void tex_sample_mipmap_filter(s3d_state_t *state) { - s3d_texture_state_t texture_state; - int tex_offset; - rgba_t tex_samples[4]; - int du, dv; - int d[4]; + s3d_texture_state_t texture_state; + int tex_offset; + rgba_t tex_samples[4]; + int du, dv; + int d[4]; - texture_state.level = (state->d < 0) ? state->max_d : state->max_d - ((state->d >> 27) & 0xf); - if (texture_state.level < 0) - texture_state.level = 0; - texture_state.texture_shift = 18 + (9 - texture_state.level); - tex_offset = 1 << texture_state.texture_shift; + texture_state.level = (state->d < 0) ? state->max_d : state->max_d - ((state->d >> 27) & 0xf); + if (texture_state.level < 0) + texture_state.level = 0; + texture_state.texture_shift = 18 + (9 - texture_state.level); + tex_offset = 1 << texture_state.texture_shift; - texture_state.u = state->u + state->tbu; - texture_state.v = state->v + state->tbv; - tex_read(state, &texture_state, &tex_samples[0]); - du = (texture_state.u >> (texture_state.texture_shift - 8)) & 0xff; - dv = (texture_state.v >> (texture_state.texture_shift - 8)) & 0xff; + texture_state.u = state->u + state->tbu; + texture_state.v = state->v + state->tbv; + tex_read(state, &texture_state, &tex_samples[0]); + du = (texture_state.u >> (texture_state.texture_shift - 8)) & 0xff; + dv = (texture_state.v >> (texture_state.texture_shift - 8)) & 0xff; - texture_state.u = state->u + state->tbu + tex_offset; - texture_state.v = state->v + state->tbv; - tex_read(state, &texture_state, &tex_samples[1]); + texture_state.u = state->u + state->tbu + tex_offset; + texture_state.v = state->v + state->tbv; + tex_read(state, &texture_state, &tex_samples[1]); - texture_state.u = state->u + state->tbu; - texture_state.v = state->v + state->tbv + tex_offset; - tex_read(state, &texture_state, &tex_samples[2]); + texture_state.u = state->u + state->tbu; + texture_state.v = state->v + state->tbv + tex_offset; + tex_read(state, &texture_state, &tex_samples[2]); - texture_state.u = state->u + state->tbu + tex_offset; - texture_state.v = state->v + state->tbv + tex_offset; - tex_read(state, &texture_state, &tex_samples[3]); + texture_state.u = state->u + state->tbu + tex_offset; + texture_state.v = state->v + state->tbv + tex_offset; + tex_read(state, &texture_state, &tex_samples[3]); - d[0] = (256 - du) * (256 - dv); - d[1] = du * (256 - dv); - d[2] = (256 - du) * dv; - d[3] = du * dv; + d[0] = (256 - du) * (256 - dv); + d[1] = du * (256 - dv); + d[2] = (256 - du) * dv; + d[3] = du * dv; - state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; - state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; - state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; - state->dest_rgba.a = (tex_samples[0].a * d[0] + tex_samples[1].a * d[1] + tex_samples[2].a * d[2] + tex_samples[3].a * d[3]) >> 16; + state->dest_rgba.r = + (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; + state->dest_rgba.g = + (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; + state->dest_rgba.b = + (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; + state->dest_rgba.a = + (tex_samples[0].a * d[0] + tex_samples[1].a * d[1] + tex_samples[2].a * d[2] + tex_samples[3].a * d[3]) >> 16; } static void tex_sample_persp_normal(s3d_state_t *state) { - s3d_texture_state_t texture_state; - int32_t w = 0; + s3d_texture_state_t texture_state; + int32_t w = 0; - if (state->w) - w = (int32_t)(((1ULL << 27) << 19) / (int64_t)state->w); + if (state->w) + w = (int32_t)(((1ULL << 27) << 19) / (int64_t)state->w); - texture_state.level = state->max_d; - texture_state.texture_shift = 18 + (9 - texture_state.level); - texture_state.u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (12 + state->max_d)) + state->tbu; - texture_state.v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (12 + state->max_d)) + state->tbv; + texture_state.level = state->max_d; + texture_state.texture_shift = 18 + (9 - texture_state.level); + texture_state.u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (12 + state->max_d)) + state->tbu; + texture_state.v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (12 + state->max_d)) + state->tbv; - tex_read(state, &texture_state, &state->dest_rgba); + tex_read(state, &texture_state, &state->dest_rgba); } static void tex_sample_persp_normal_filter(s3d_state_t *state) { - s3d_texture_state_t texture_state; - int32_t w = 0, u, v; - int tex_offset; - rgba_t tex_samples[4]; - int du, dv; - int d[4]; + s3d_texture_state_t texture_state; + int32_t w = 0, u, v; + int tex_offset; + rgba_t tex_samples[4]; + int du, dv; + int d[4]; - if (state->w) - w = (int32_t)(((1ULL << 27) << 19) / (int64_t)state->w); + if (state->w) + w = (int32_t)(((1ULL << 27) << 19) / (int64_t)state->w); - u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (12 + state->max_d)) + state->tbu; - v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (12 + state->max_d)) + state->tbv; + u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (12 + state->max_d)) + state->tbu; + v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (12 + state->max_d)) + state->tbv; - texture_state.level = state->max_d; - texture_state.texture_shift = 18 + (9 - texture_state.level); - tex_offset = 1 << texture_state.texture_shift; + texture_state.level = state->max_d; + texture_state.texture_shift = 18 + (9 - texture_state.level); + tex_offset = 1 << texture_state.texture_shift; - texture_state.u = u; - texture_state.v = v; - tex_read(state, &texture_state, &tex_samples[0]); - du = (u >> (texture_state.texture_shift - 8)) & 0xff; - dv = (v >> (texture_state.texture_shift - 8)) & 0xff; + texture_state.u = u; + texture_state.v = v; + tex_read(state, &texture_state, &tex_samples[0]); + du = (u >> (texture_state.texture_shift - 8)) & 0xff; + dv = (v >> (texture_state.texture_shift - 8)) & 0xff; - texture_state.u = u + tex_offset; - texture_state.v = v; - tex_read(state, &texture_state, &tex_samples[1]); + texture_state.u = u + tex_offset; + texture_state.v = v; + tex_read(state, &texture_state, &tex_samples[1]); - texture_state.u = u; - texture_state.v = v + tex_offset; - tex_read(state, &texture_state, &tex_samples[2]); + texture_state.u = u; + texture_state.v = v + tex_offset; + tex_read(state, &texture_state, &tex_samples[2]); - texture_state.u = u + tex_offset; - texture_state.v = v + tex_offset; - tex_read(state, &texture_state, &tex_samples[3]); + texture_state.u = u + tex_offset; + texture_state.v = v + tex_offset; + tex_read(state, &texture_state, &tex_samples[3]); - d[0] = (256 - du) * (256 - dv); - d[1] = du * (256 - dv); - d[2] = (256 - du) * dv; - d[3] = du * dv; + d[0] = (256 - du) * (256 - dv); + d[1] = du * (256 - dv); + d[2] = (256 - du) * dv; + d[3] = du * dv; - state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; - state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; - state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; - state->dest_rgba.a = (tex_samples[0].a * d[0] + tex_samples[1].a * d[1] + tex_samples[2].a * d[2] + tex_samples[3].a * d[3]) >> 16; + state->dest_rgba.r = + (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; + state->dest_rgba.g = + (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; + state->dest_rgba.b = + (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; + state->dest_rgba.a = + (tex_samples[0].a * d[0] + tex_samples[1].a * d[1] + tex_samples[2].a * d[2] + tex_samples[3].a * d[3]) >> 16; } static void tex_sample_persp_normal_375(s3d_state_t *state) { - s3d_texture_state_t texture_state; - int32_t w = 0; + s3d_texture_state_t texture_state; + int32_t w = 0; - if (state->w) - w = (int32_t)(((1ULL << 27) << 19) / (int64_t)state->w); + if (state->w) + w = (int32_t)(((1ULL << 27) << 19) / (int64_t)state->w); - texture_state.level = state->max_d; - texture_state.texture_shift = 18 + (9 - texture_state.level); - texture_state.u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (8 + state->max_d)) + state->tbu; - texture_state.v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (8 + state->max_d)) + state->tbv; + texture_state.level = state->max_d; + texture_state.texture_shift = 18 + (9 - texture_state.level); + texture_state.u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (8 + state->max_d)) + state->tbu; + texture_state.v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (8 + state->max_d)) + state->tbv; - tex_read(state, &texture_state, &state->dest_rgba); + tex_read(state, &texture_state, &state->dest_rgba); } static void tex_sample_persp_normal_filter_375(s3d_state_t *state) { - s3d_texture_state_t texture_state; - int32_t w = 0, u, v; - int tex_offset; - rgba_t tex_samples[4]; - int du, dv; - int d[4]; + s3d_texture_state_t texture_state; + int32_t w = 0, u, v; + int tex_offset; + rgba_t tex_samples[4]; + int du, dv; + int d[4]; - if (state->w) - w = (int32_t)(((1ULL << 27) << 19) / (int64_t)state->w); + if (state->w) + w = (int32_t)(((1ULL << 27) << 19) / (int64_t)state->w); - u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (8 + state->max_d)) + state->tbu; - v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (8 + state->max_d)) + state->tbv; + u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (8 + state->max_d)) + state->tbu; + v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (8 + state->max_d)) + state->tbv; - texture_state.level = state->max_d; - texture_state.texture_shift = 18 + (9 - texture_state.level); - tex_offset = 1 << texture_state.texture_shift; + texture_state.level = state->max_d; + texture_state.texture_shift = 18 + (9 - texture_state.level); + tex_offset = 1 << texture_state.texture_shift; - texture_state.u = u; - texture_state.v = v; - tex_read(state, &texture_state, &tex_samples[0]); - du = (u >> (texture_state.texture_shift - 8)) & 0xff; - dv = (v >> (texture_state.texture_shift - 8)) & 0xff; + texture_state.u = u; + texture_state.v = v; + tex_read(state, &texture_state, &tex_samples[0]); + du = (u >> (texture_state.texture_shift - 8)) & 0xff; + dv = (v >> (texture_state.texture_shift - 8)) & 0xff; - texture_state.u = u + tex_offset; - texture_state.v = v; - tex_read(state, &texture_state, &tex_samples[1]); + texture_state.u = u + tex_offset; + texture_state.v = v; + tex_read(state, &texture_state, &tex_samples[1]); - texture_state.u = u; - texture_state.v = v + tex_offset; - tex_read(state, &texture_state, &tex_samples[2]); + texture_state.u = u; + texture_state.v = v + tex_offset; + tex_read(state, &texture_state, &tex_samples[2]); - texture_state.u = u + tex_offset; - texture_state.v = v + tex_offset; - tex_read(state, &texture_state, &tex_samples[3]); + texture_state.u = u + tex_offset; + texture_state.v = v + tex_offset; + tex_read(state, &texture_state, &tex_samples[3]); - d[0] = (256 - du) * (256 - dv); - d[1] = du * (256 - dv); - d[2] = (256 - du) * dv; - d[3] = du * dv; + d[0] = (256 - du) * (256 - dv); + d[1] = du * (256 - dv); + d[2] = (256 - du) * dv; + d[3] = du * dv; - state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; - state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; - state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; - state->dest_rgba.a = (tex_samples[0].a * d[0] + tex_samples[1].a * d[1] + tex_samples[2].a * d[2] + tex_samples[3].a * d[3]) >> 16; + state->dest_rgba.r = + (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; + state->dest_rgba.g = + (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; + state->dest_rgba.b = + (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; + state->dest_rgba.a = + (tex_samples[0].a * d[0] + tex_samples[1].a * d[1] + tex_samples[2].a * d[2] + tex_samples[3].a * d[3]) >> 16; } static void tex_sample_persp_mipmap(s3d_state_t *state) { - s3d_texture_state_t texture_state; - int32_t w = 0; + s3d_texture_state_t texture_state; + int32_t w = 0; - if (state->w) - w = (int32_t)(((1ULL << 27) << 19) / (int64_t)state->w); + if (state->w) + w = (int32_t)(((1ULL << 27) << 19) / (int64_t)state->w); - texture_state.level = (state->d < 0) ? state->max_d : state->max_d - ((state->d >> 27) & 0xf); - if (texture_state.level < 0) - texture_state.level = 0; - texture_state.texture_shift = 18 + (9 - texture_state.level); - texture_state.u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (12 + state->max_d)) + state->tbu; - texture_state.v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (12 + state->max_d)) + state->tbv; + texture_state.level = (state->d < 0) ? state->max_d : state->max_d - ((state->d >> 27) & 0xf); + if (texture_state.level < 0) + texture_state.level = 0; + texture_state.texture_shift = 18 + (9 - texture_state.level); + texture_state.u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (12 + state->max_d)) + state->tbu; + texture_state.v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (12 + state->max_d)) + state->tbv; - tex_read(state, &texture_state, &state->dest_rgba); + tex_read(state, &texture_state, &state->dest_rgba); } static void tex_sample_persp_mipmap_filter(s3d_state_t *state) { - s3d_texture_state_t texture_state; - int32_t w = 0, u, v; - int tex_offset; - rgba_t tex_samples[4]; - int du, dv; - int d[4]; + s3d_texture_state_t texture_state; + int32_t w = 0, u, v; + int tex_offset; + rgba_t tex_samples[4]; + int du, dv; + int d[4]; - if (state->w) - w = (int32_t)(((1ULL << 27) << 19) / (int64_t)state->w); + if (state->w) + w = (int32_t)(((1ULL << 27) << 19) / (int64_t)state->w); - u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (12 + state->max_d)) + state->tbu; - v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (12 + state->max_d)) + state->tbv; + u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (12 + state->max_d)) + state->tbu; + v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (12 + state->max_d)) + state->tbv; - texture_state.level = (state->d < 0) ? state->max_d : state->max_d - ((state->d >> 27) & 0xf); - if (texture_state.level < 0) - texture_state.level = 0; - texture_state.texture_shift = 18 + (9 - texture_state.level); - tex_offset = 1 << texture_state.texture_shift; + texture_state.level = (state->d < 0) ? state->max_d : state->max_d - ((state->d >> 27) & 0xf); + if (texture_state.level < 0) + texture_state.level = 0; + texture_state.texture_shift = 18 + (9 - texture_state.level); + tex_offset = 1 << texture_state.texture_shift; - texture_state.u = u; - texture_state.v = v; - tex_read(state, &texture_state, &tex_samples[0]); - du = (u >> (texture_state.texture_shift - 8)) & 0xff; - dv = (v >> (texture_state.texture_shift - 8)) & 0xff; + texture_state.u = u; + texture_state.v = v; + tex_read(state, &texture_state, &tex_samples[0]); + du = (u >> (texture_state.texture_shift - 8)) & 0xff; + dv = (v >> (texture_state.texture_shift - 8)) & 0xff; - texture_state.u = u + tex_offset; - texture_state.v = v; - tex_read(state, &texture_state, &tex_samples[1]); + texture_state.u = u + tex_offset; + texture_state.v = v; + tex_read(state, &texture_state, &tex_samples[1]); - texture_state.u = u; - texture_state.v = v + tex_offset; - tex_read(state, &texture_state, &tex_samples[2]); + texture_state.u = u; + texture_state.v = v + tex_offset; + tex_read(state, &texture_state, &tex_samples[2]); - texture_state.u = u + tex_offset; - texture_state.v = v + tex_offset; - tex_read(state, &texture_state, &tex_samples[3]); + texture_state.u = u + tex_offset; + texture_state.v = v + tex_offset; + tex_read(state, &texture_state, &tex_samples[3]); - d[0] = (256 - du) * (256 - dv); - d[1] = du * (256 - dv); - d[2] = (256 - du) * dv; - d[3] = du * dv; + d[0] = (256 - du) * (256 - dv); + d[1] = du * (256 - dv); + d[2] = (256 - du) * dv; + d[3] = du * dv; - state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; - state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; - state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; - state->dest_rgba.a = (tex_samples[0].a * d[0] + tex_samples[1].a * d[1] + tex_samples[2].a * d[2] + tex_samples[3].a * d[3]) >> 16; + state->dest_rgba.r = + (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; + state->dest_rgba.g = + (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; + state->dest_rgba.b = + (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; + state->dest_rgba.a = + (tex_samples[0].a * d[0] + tex_samples[1].a * d[1] + tex_samples[2].a * d[2] + tex_samples[3].a * d[3]) >> 16; } static void tex_sample_persp_mipmap_375(s3d_state_t *state) { - s3d_texture_state_t texture_state; - int32_t w = 0; + s3d_texture_state_t texture_state; + int32_t w = 0; - if (state->w) - w = (int32_t)(((1ULL << 27) << 19) / (int64_t)state->w); + if (state->w) + w = (int32_t)(((1ULL << 27) << 19) / (int64_t)state->w); - texture_state.level = (state->d < 0) ? state->max_d : state->max_d - ((state->d >> 27) & 0xf); - if (texture_state.level < 0) - texture_state.level = 0; - texture_state.texture_shift = 18 + (9 - texture_state.level); - texture_state.u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (8 + state->max_d)) + state->tbu; - texture_state.v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (8 + state->max_d)) + state->tbv; + texture_state.level = (state->d < 0) ? state->max_d : state->max_d - ((state->d >> 27) & 0xf); + if (texture_state.level < 0) + texture_state.level = 0; + texture_state.texture_shift = 18 + (9 - texture_state.level); + texture_state.u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (8 + state->max_d)) + state->tbu; + texture_state.v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (8 + state->max_d)) + state->tbv; - tex_read(state, &texture_state, &state->dest_rgba); + tex_read(state, &texture_state, &state->dest_rgba); } static void tex_sample_persp_mipmap_filter_375(s3d_state_t *state) { - s3d_texture_state_t texture_state; - int32_t w = 0, u, v; - int tex_offset; - rgba_t tex_samples[4]; - int du, dv; - int d[4]; + s3d_texture_state_t texture_state; + int32_t w = 0, u, v; + int tex_offset; + rgba_t tex_samples[4]; + int du, dv; + int d[4]; - if (state->w) - w = (int32_t)(((1ULL << 27) << 19) / (int64_t)state->w); + if (state->w) + w = (int32_t)(((1ULL << 27) << 19) / (int64_t)state->w); - u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (8 + state->max_d)) + state->tbu; - v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (8 + state->max_d)) + state->tbv; + u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (8 + state->max_d)) + state->tbu; + v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (8 + state->max_d)) + state->tbv; - texture_state.level = (state->d < 0) ? state->max_d : state->max_d - ((state->d >> 27) & 0xf); - if (texture_state.level < 0) - texture_state.level = 0; - texture_state.texture_shift = 18 + (9 - texture_state.level); - tex_offset = 1 << texture_state.texture_shift; + texture_state.level = (state->d < 0) ? state->max_d : state->max_d - ((state->d >> 27) & 0xf); + if (texture_state.level < 0) + texture_state.level = 0; + texture_state.texture_shift = 18 + (9 - texture_state.level); + tex_offset = 1 << texture_state.texture_shift; - texture_state.u = u; - texture_state.v = v; - tex_read(state, &texture_state, &tex_samples[0]); - du = (u >> (texture_state.texture_shift - 8)) & 0xff; - dv = (v >> (texture_state.texture_shift - 8)) & 0xff; + texture_state.u = u; + texture_state.v = v; + tex_read(state, &texture_state, &tex_samples[0]); + du = (u >> (texture_state.texture_shift - 8)) & 0xff; + dv = (v >> (texture_state.texture_shift - 8)) & 0xff; - texture_state.u = u + tex_offset; - texture_state.v = v; - tex_read(state, &texture_state, &tex_samples[1]); + texture_state.u = u + tex_offset; + texture_state.v = v; + tex_read(state, &texture_state, &tex_samples[1]); - texture_state.u = u; - texture_state.v = v + tex_offset; - tex_read(state, &texture_state, &tex_samples[2]); + texture_state.u = u; + texture_state.v = v + tex_offset; + tex_read(state, &texture_state, &tex_samples[2]); - texture_state.u = u + tex_offset; - texture_state.v = v + tex_offset; - tex_read(state, &texture_state, &tex_samples[3]); + texture_state.u = u + tex_offset; + texture_state.v = v + tex_offset; + tex_read(state, &texture_state, &tex_samples[3]); - d[0] = (256 - du) * (256 - dv); - d[1] = du * (256 - dv); - d[2] = (256 - du) * dv; - d[3] = du * dv; + d[0] = (256 - du) * (256 - dv); + d[1] = du * (256 - dv); + d[2] = (256 - du) * dv; + d[3] = du * dv; - state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; - state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; - state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; - state->dest_rgba.a = (tex_samples[0].a * d[0] + tex_samples[1].a * d[1] + tex_samples[2].a * d[2] + tex_samples[3].a * d[3]) >> 16; + state->dest_rgba.r = + (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; + state->dest_rgba.g = + (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; + state->dest_rgba.b = + (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; + state->dest_rgba.a = + (tex_samples[0].a * d[0] + tex_samples[1].a * d[1] + tex_samples[2].a * d[2] + tex_samples[3].a * d[3]) >> 16; } -#define CLAMP(x) do \ - { \ - if ((x) & ~0xff) \ - x = ((x) < 0) ? 0 : 0xff; \ - } \ - while (0) +#define CLAMP(x) \ + do { \ + if ((x) & ~0xff) \ + x = ((x) < 0) ? 0 : 0xff; \ + } while (0) -#define CLAMP_RGBA(r, g, b, a) \ - if ((r) & ~0xff) \ - r = ((r) < 0) ? 0 : 0xff; \ - if ((g) & ~0xff) \ - g = ((g) < 0) ? 0 : 0xff; \ - if ((b) & ~0xff) \ - b = ((b) < 0) ? 0 : 0xff; \ - if ((a) & ~0xff) \ - a = ((a) < 0) ? 0 : 0xff; +#define CLAMP_RGBA(r, g, b, a) \ + if ((r) & ~0xff) \ + r = ((r) < 0) ? 0 : 0xff; \ + if ((g) & ~0xff) \ + g = ((g) < 0) ? 0 : 0xff; \ + if ((b) & ~0xff) \ + b = ((b) < 0) ? 0 : 0xff; \ + if ((a) & ~0xff) \ + a = ((a) < 0) ? 0 : 0xff; -#define CLAMP_RGB(r, g, b) do \ - { \ - if ((r) < 0) \ - r = 0; \ - if ((r) > 0xff) \ - r = 0xff; \ - if ((g) < 0) \ - g = 0; \ - if ((g) > 0xff) \ - g = 0xff; \ - if ((b) < 0) \ - b = 0; \ - if ((b) > 0xff) \ - b = 0xff; \ - } \ - while (0) +#define CLAMP_RGB(r, g, b) \ + do { \ + if ((r) < 0) \ + r = 0; \ + if ((r) > 0xff) \ + r = 0xff; \ + if ((g) < 0) \ + g = 0; \ + if ((g) > 0xff) \ + g = 0xff; \ + if ((b) < 0) \ + b = 0; \ + if ((b) > 0xff) \ + b = 0xff; \ + } while (0) static void dest_pixel_gouraud_shaded_triangle(s3d_state_t *state) { - state->dest_rgba.r = state->r >> 7; - CLAMP(state->dest_rgba.r); + state->dest_rgba.r = state->r >> 7; + CLAMP(state->dest_rgba.r); - state->dest_rgba.g = state->g >> 7; - CLAMP(state->dest_rgba.g); + state->dest_rgba.g = state->g >> 7; + CLAMP(state->dest_rgba.g); - state->dest_rgba.b = state->b >> 7; - CLAMP(state->dest_rgba.b); + state->dest_rgba.b = state->b >> 7; + CLAMP(state->dest_rgba.b); - state->dest_rgba.a = state->a >> 7; - CLAMP(state->dest_rgba.a); + state->dest_rgba.a = state->a >> 7; + CLAMP(state->dest_rgba.a); } static void dest_pixel_unlit_texture_triangle(s3d_state_t *state) { - tex_sample(state); + tex_sample(state); - if (state->cmd_set & CMD_SET_ABC_SRC) - state->dest_rgba.a = state->a >> 7; + if (state->cmd_set & CMD_SET_ABC_SRC) + state->dest_rgba.a = state->a >> 7; } static void dest_pixel_lit_texture_decal(s3d_state_t *state) { - tex_sample(state); + tex_sample(state); - if (state->cmd_set & CMD_SET_ABC_SRC) - state->dest_rgba.a = state->a >> 7; + if (state->cmd_set & CMD_SET_ABC_SRC) + state->dest_rgba.a = state->a >> 7; } static void dest_pixel_lit_texture_reflection(s3d_state_t *state) { - tex_sample(state); + tex_sample(state); - state->dest_rgba.r += (state->r >> 7); - state->dest_rgba.g += (state->g >> 7); - state->dest_rgba.b += (state->b >> 7); - if (state->cmd_set & CMD_SET_ABC_SRC) - state->dest_rgba.a += (state->a >> 7); + state->dest_rgba.r += (state->r >> 7); + state->dest_rgba.g += (state->g >> 7); + state->dest_rgba.b += (state->b >> 7); + if (state->cmd_set & CMD_SET_ABC_SRC) + state->dest_rgba.a += (state->a >> 7); - CLAMP_RGBA(state->dest_rgba.r, state->dest_rgba.g, state->dest_rgba.b, state->dest_rgba.a); + CLAMP_RGBA(state->dest_rgba.r, state->dest_rgba.g, state->dest_rgba.b, state->dest_rgba.a); } static void dest_pixel_lit_texture_modulate(s3d_state_t *state) { - int r = state->r >> 7, g = state->g >> 7, b = state->b >> 7, a = state->a >> 7; + int r = state->r >> 7, g = state->g >> 7, b = state->b >> 7, a = state->a >> 7; - tex_sample(state); + tex_sample(state); - CLAMP_RGBA(r, g, b, a); + CLAMP_RGBA(r, g, b, a); - state->dest_rgba.r = ((state->dest_rgba.r) * r) >> 8; - state->dest_rgba.g = ((state->dest_rgba.g) * g) >> 8; - state->dest_rgba.b = ((state->dest_rgba.b) * b) >> 8; + state->dest_rgba.r = ((state->dest_rgba.r) * r) >> 8; + state->dest_rgba.g = ((state->dest_rgba.g) * g) >> 8; + state->dest_rgba.b = ((state->dest_rgba.b) * b) >> 8; - if (state->cmd_set & CMD_SET_ABC_SRC) - state->dest_rgba.a = a; + if (state->cmd_set & CMD_SET_ABC_SRC) + state->dest_rgba.a = a; } static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int32_t dx1, int32_t dx2) { - svga_t *svga = &virge->svga; - uint8_t *vram = virge->svga.vram; + svga_t *svga = &virge->svga; + uint8_t *vram = virge->svga.vram; - int x_dir = s3d_tri->tlr ? 1 : -1; + int x_dir = s3d_tri->tlr ? 1 : -1; - int use_z = !(s3d_tri->cmd_set & CMD_SET_ZB_MODE); + int use_z = !(s3d_tri->cmd_set & CMD_SET_ZB_MODE); - int y_count = yc; + int y_count = yc; - int bpp = (s3d_tri->cmd_set >> 2) & 7; + int bpp = (s3d_tri->cmd_set >> 2) & 7; - uint32_t dest_offset, z_offset; + uint32_t dest_offset, z_offset; - dest_offset = s3d_tri->dest_base + (state->y * s3d_tri->dest_str); - z_offset = s3d_tri->z_base + (state->y * s3d_tri->z_str); + dest_offset = s3d_tri->dest_base + (state->y * s3d_tri->dest_str); + z_offset = s3d_tri->z_base + (state->y * s3d_tri->z_str); - if (s3d_tri->cmd_set & CMD_SET_HC) { - if (state->y < s3d_tri->clip_t) - return; - if (state->y > s3d_tri->clip_b) { - int diff_y = state->y - s3d_tri->clip_b; + if (s3d_tri->cmd_set & CMD_SET_HC) { + if (state->y < s3d_tri->clip_t) + return; + if (state->y > s3d_tri->clip_b) { + int diff_y = state->y - s3d_tri->clip_b; - if (diff_y > y_count) - diff_y = y_count; + if (diff_y > y_count) + diff_y = y_count; - state->base_u += (s3d_tri->TdUdY * diff_y); - state->base_v += (s3d_tri->TdVdY * diff_y); - state->base_z += (s3d_tri->TdZdY * diff_y); - state->base_r += (s3d_tri->TdRdY * diff_y); - state->base_g += (s3d_tri->TdGdY * diff_y); - state->base_b += (s3d_tri->TdBdY * diff_y); - state->base_a += (s3d_tri->TdAdY * diff_y); - state->base_d += (s3d_tri->TdDdY * diff_y); - state->base_w += (s3d_tri->TdWdY * diff_y); - state->x1 += (dx1 * diff_y); - state->x2 += (dx2 * diff_y); - state->y -= diff_y; - dest_offset -= s3d_tri->dest_str; - z_offset -= s3d_tri->z_str; - y_count -= diff_y; - } - if ((state->y - y_count) < s3d_tri->clip_t) - y_count = (state->y - s3d_tri->clip_t) + 1; - } + state->base_u += (s3d_tri->TdUdY * diff_y); + state->base_v += (s3d_tri->TdVdY * diff_y); + state->base_z += (s3d_tri->TdZdY * diff_y); + state->base_r += (s3d_tri->TdRdY * diff_y); + state->base_g += (s3d_tri->TdGdY * diff_y); + state->base_b += (s3d_tri->TdBdY * diff_y); + state->base_a += (s3d_tri->TdAdY * diff_y); + state->base_d += (s3d_tri->TdDdY * diff_y); + state->base_w += (s3d_tri->TdWdY * diff_y); + state->x1 += (dx1 * diff_y); + state->x2 += (dx2 * diff_y); + state->y -= diff_y; + dest_offset -= s3d_tri->dest_str; + z_offset -= s3d_tri->z_str; + y_count -= diff_y; + } + if ((state->y - y_count) < s3d_tri->clip_t) + y_count = (state->y - s3d_tri->clip_t) + 1; + } - for (; y_count > 0; y_count--) { - int x = (state->x1 + ((1 << 20) - 1)) >> 20; - int xe = (state->x2 + ((1 << 20) - 1)) >> 20; - uint32_t z = (state->base_z > 0) ? (state->base_z << 1) : 0; - if (x_dir < 0) { - x--; - xe--; - } + for (; y_count > 0; y_count--) { + int x = (state->x1 + ((1 << 20) - 1)) >> 20; + int xe = (state->x2 + ((1 << 20) - 1)) >> 20; + uint32_t z = (state->base_z > 0) ? (state->base_z << 1) : 0; + if (x_dir < 0) { + x--; + xe--; + } - if (x != xe && ((x_dir > 0 && x < xe) || (x_dir < 0 && x > xe))) { - uint32_t dest_addr, z_addr; - int dx = (x_dir > 0) ? ((31 - ((state->x1 - 1) >> 15)) & 0x1f) : (((state->x1 - 1) >> 15) & 0x1f); - int x_offset = x_dir * (bpp + 1); - int xz_offset = x_dir << 1; - if (x_dir > 0) - dx += 1; - state->r = state->base_r + ((s3d_tri->TdRdX * dx) >> 5); - state->g = state->base_g + ((s3d_tri->TdGdX * dx) >> 5); - state->b = state->base_b + ((s3d_tri->TdBdX * dx) >> 5); - state->a = state->base_a + ((s3d_tri->TdAdX * dx) >> 5); - state->u = state->base_u + ((s3d_tri->TdUdX * dx) >> 5); - state->v = state->base_v + ((s3d_tri->TdVdX * dx) >> 5); - state->w = state->base_w + ((s3d_tri->TdWdX * dx) >> 5); - state->d = state->base_d + ((s3d_tri->TdDdX * dx) >> 5); - z += ((s3d_tri->TdZdX * dx) >> 5); + if (x != xe && ((x_dir > 0 && x < xe) || (x_dir < 0 && x > xe))) { + uint32_t dest_addr, z_addr; + int dx = (x_dir > 0) ? ((31 - ((state->x1 - 1) >> 15)) & 0x1f) : (((state->x1 - 1) >> 15) & 0x1f); + int x_offset = x_dir * (bpp + 1); + int xz_offset = x_dir << 1; + if (x_dir > 0) + dx += 1; + state->r = state->base_r + ((s3d_tri->TdRdX * dx) >> 5); + state->g = state->base_g + ((s3d_tri->TdGdX * dx) >> 5); + state->b = state->base_b + ((s3d_tri->TdBdX * dx) >> 5); + state->a = state->base_a + ((s3d_tri->TdAdX * dx) >> 5); + state->u = state->base_u + ((s3d_tri->TdUdX * dx) >> 5); + state->v = state->base_v + ((s3d_tri->TdVdX * dx) >> 5); + state->w = state->base_w + ((s3d_tri->TdWdX * dx) >> 5); + state->d = state->base_d + ((s3d_tri->TdDdX * dx) >> 5); + z += ((s3d_tri->TdZdX * dx) >> 5); -// pclog("Draw Y=%i X=%i to XE=%i %i %08x %08x %08x %08x %08x %08x %08x %08x %i %08x\n", state->y, x, xe, dx, state->x1, state->x2, dx1, virge->s3d.TdWdX, state->u, state->v, virge->s3d.TdUdX, virge->s3d.TdUdY, dx, (virge->s3d.TdUdX * dx) >> 4); + // pclog("Draw Y=%i X=%i to XE=%i %i %08x %08x %08x %08x %08x %08x %08x %08x %i + // %08x\n", state->y, x, xe, dx, state->x1, state->x2, dx1, virge->s3d.TdWdX, + // state->u, state->v, virge->s3d.TdUdX, virge->s3d.TdUdY, dx, (virge->s3d.TdUdX * + // dx) >> 4); - if (s3d_tri->cmd_set & CMD_SET_HC) { - if (x_dir > 0) { - if (x > s3d_tri->clip_r) - goto tri_skip_line; - if (xe < s3d_tri->clip_l) - goto tri_skip_line; - if (xe > s3d_tri->clip_r) - xe = s3d_tri->clip_r + 1; - if (x < s3d_tri->clip_l) { - int diff_x = s3d_tri->clip_l - x; + if (s3d_tri->cmd_set & CMD_SET_HC) { + if (x_dir > 0) { + if (x > s3d_tri->clip_r) + goto tri_skip_line; + if (xe < s3d_tri->clip_l) + goto tri_skip_line; + if (xe > s3d_tri->clip_r) + xe = s3d_tri->clip_r + 1; + if (x < s3d_tri->clip_l) { + int diff_x = s3d_tri->clip_l - x; - z += (s3d_tri->TdZdX * diff_x); - state->u += (s3d_tri->TdUdX * diff_x); - state->v += (s3d_tri->TdVdX * diff_x); - state->r += (s3d_tri->TdRdX * diff_x); - state->g += (s3d_tri->TdGdX * diff_x); - state->b += (s3d_tri->TdBdX * diff_x); - state->a += (s3d_tri->TdAdX * diff_x); - state->d += (s3d_tri->TdDdX * diff_x); - state->w += (s3d_tri->TdWdX * diff_x); + z += (s3d_tri->TdZdX * diff_x); + state->u += (s3d_tri->TdUdX * diff_x); + state->v += (s3d_tri->TdVdX * diff_x); + state->r += (s3d_tri->TdRdX * diff_x); + state->g += (s3d_tri->TdGdX * diff_x); + state->b += (s3d_tri->TdBdX * diff_x); + state->a += (s3d_tri->TdAdX * diff_x); + state->d += (s3d_tri->TdDdX * diff_x); + state->w += (s3d_tri->TdWdX * diff_x); - x = s3d_tri->clip_l; - } - } else { - if (x < s3d_tri->clip_l) - goto tri_skip_line; - if (xe > s3d_tri->clip_r) - goto tri_skip_line; - if (xe < s3d_tri->clip_l) - xe = s3d_tri->clip_l - 1; - if (x > s3d_tri->clip_r) { - int diff_x = x - s3d_tri->clip_r; + x = s3d_tri->clip_l; + } + } else { + if (x < s3d_tri->clip_l) + goto tri_skip_line; + if (xe > s3d_tri->clip_r) + goto tri_skip_line; + if (xe < s3d_tri->clip_l) + xe = s3d_tri->clip_l - 1; + if (x > s3d_tri->clip_r) { + int diff_x = x - s3d_tri->clip_r; - z += (s3d_tri->TdZdX * diff_x); - state->u += (s3d_tri->TdUdX * diff_x); - state->v += (s3d_tri->TdVdX * diff_x); - state->r += (s3d_tri->TdRdX * diff_x); - state->g += (s3d_tri->TdGdX * diff_x); - state->b += (s3d_tri->TdBdX * diff_x); - state->a += (s3d_tri->TdAdX * diff_x); - state->d += (s3d_tri->TdDdX * diff_x); - state->w += (s3d_tri->TdWdX * diff_x); + z += (s3d_tri->TdZdX * diff_x); + state->u += (s3d_tri->TdUdX * diff_x); + state->v += (s3d_tri->TdVdX * diff_x); + state->r += (s3d_tri->TdRdX * diff_x); + state->g += (s3d_tri->TdGdX * diff_x); + state->b += (s3d_tri->TdBdX * diff_x); + state->a += (s3d_tri->TdAdX * diff_x); + state->d += (s3d_tri->TdDdX * diff_x); + state->w += (s3d_tri->TdWdX * diff_x); - x = s3d_tri->clip_r; - } - } - } + x = s3d_tri->clip_r; + } + } + } - virge->svga.changedvram[(dest_offset & svga->vram_mask) >> 12] = changeframecount; + virge->svga.changedvram[(dest_offset & svga->vram_mask) >> 12] = changeframecount; - dest_addr = dest_offset + (x * (bpp + 1)); - z_addr = z_offset + (x << 1); + dest_addr = dest_offset + (x * (bpp + 1)); + z_addr = z_offset + (x << 1); - x &= 0xfff; - xe &= 0xfff; + x &= 0xfff; + xe &= 0xfff; - for (; x != xe; x = (x + x_dir) & 0xfff) { - int update = 1; - uint16_t src_z = 0; - _x = x; - _y = state->y; + for (; x != xe; x = (x + x_dir) & 0xfff) { + int update = 1; + uint16_t src_z = 0; + _x = x; + _y = state->y; - if (use_z) { - src_z = Z_READ(z_addr); - Z_CLIP(src_z, z >> 16); - } + if (use_z) { + src_z = Z_READ(z_addr); + Z_CLIP(src_z, z >> 16); + } - if (update) { - uint32_t dest_col; + if (update) { + uint32_t dest_col; - dest_pixel(state); + dest_pixel(state); - if (s3d_tri->cmd_set & CMD_SET_ABC_ENABLE) { - uint32_t src_col; - int src_r = 0, src_g = 0, src_b = 0; + if (s3d_tri->cmd_set & CMD_SET_ABC_ENABLE) { + uint32_t src_col; + int src_r = 0, src_g = 0, src_b = 0; - switch (bpp) { - case 0: /*8 bpp*/ - /*Not implemented yet*/ - break; - case 1: /*16 bpp*/ - src_col = *(uint16_t *)&vram[dest_addr & svga->vram_mask]; - RGB15_TO_24(src_col, src_r, src_g, src_b); - break; - case 2: /*24 bpp*/ - src_col = (*(uint32_t *)&vram[dest_addr & svga->vram_mask]) & 0xffffff; - RGB24_TO_24(src_col, src_r, src_g, src_b); - break; - } + switch (bpp) { + case 0: /*8 bpp*/ + /*Not implemented yet*/ + break; + case 1: /*16 bpp*/ + src_col = *(uint16_t *)&vram[dest_addr & svga->vram_mask]; + RGB15_TO_24(src_col, src_r, src_g, src_b); + break; + case 2: /*24 bpp*/ + src_col = (*(uint32_t *)&vram[dest_addr & svga->vram_mask]) & 0xffffff; + RGB24_TO_24(src_col, src_r, src_g, src_b); + break; + } - state->dest_rgba.r = ((state->dest_rgba.r * state->dest_rgba.a) + (src_r * (255 - state->dest_rgba.a))) / 255; - state->dest_rgba.g = ((state->dest_rgba.g * state->dest_rgba.a) + (src_g * (255 - state->dest_rgba.a))) / 255; - state->dest_rgba.b = ((state->dest_rgba.b * state->dest_rgba.a) + (src_b * (255 - state->dest_rgba.a))) / 255; - } + state->dest_rgba.r = ((state->dest_rgba.r * state->dest_rgba.a) + + (src_r * (255 - state->dest_rgba.a))) / + 255; + state->dest_rgba.g = ((state->dest_rgba.g * state->dest_rgba.a) + + (src_g * (255 - state->dest_rgba.a))) / + 255; + state->dest_rgba.b = ((state->dest_rgba.b * state->dest_rgba.a) + + (src_b * (255 - state->dest_rgba.a))) / + 255; + } - switch (bpp) { - case 0: /*8 bpp*/ - /*Not implemented yet*/ - break; - case 1: /*16 bpp*/ - RGB15(state->dest_rgba.r, state->dest_rgba.g, state->dest_rgba.b, dest_col); - *(uint16_t *)&vram[dest_addr] = dest_col; - break; - case 2: /*24 bpp*/ - dest_col = RGB24(state->dest_rgba.r, state->dest_rgba.g, state->dest_rgba.b); - *(uint8_t *)&vram[dest_addr] = dest_col & 0xff; - *(uint8_t *)&vram[dest_addr + 1] = (dest_col >> 8) & 0xff; - *(uint8_t *)&vram[dest_addr + 2] = (dest_col >> 16) & 0xff; - break; - } + switch (bpp) { + case 0: /*8 bpp*/ + /*Not implemented yet*/ + break; + case 1: /*16 bpp*/ + RGB15(state->dest_rgba.r, state->dest_rgba.g, state->dest_rgba.b, dest_col); + *(uint16_t *)&vram[dest_addr] = dest_col; + break; + case 2: /*24 bpp*/ + dest_col = RGB24(state->dest_rgba.r, state->dest_rgba.g, state->dest_rgba.b); + *(uint8_t *)&vram[dest_addr] = dest_col & 0xff; + *(uint8_t *)&vram[dest_addr + 1] = (dest_col >> 8) & 0xff; + *(uint8_t *)&vram[dest_addr + 2] = (dest_col >> 16) & 0xff; + break; + } - if (use_z && (s3d_tri->cmd_set & CMD_SET_ZUP)) - Z_WRITE(z_addr, src_z); - } + if (use_z && (s3d_tri->cmd_set & CMD_SET_ZUP)) + Z_WRITE(z_addr, src_z); + } - z += s3d_tri->TdZdX; - state->u += s3d_tri->TdUdX; - state->v += s3d_tri->TdVdX; - state->r += s3d_tri->TdRdX; - state->g += s3d_tri->TdGdX; - state->b += s3d_tri->TdBdX; - state->a += s3d_tri->TdAdX; - state->d += s3d_tri->TdDdX; - state->w += s3d_tri->TdWdX; - dest_addr += x_offset; - z_addr += xz_offset; - virge->pixel_count++; - } - } - tri_skip_line: - state->x1 += dx1; - state->x2 += dx2; - state->base_u += s3d_tri->TdUdY; - state->base_v += s3d_tri->TdVdY; - state->base_z += s3d_tri->TdZdY; - state->base_r += s3d_tri->TdRdY; - state->base_g += s3d_tri->TdGdY; - state->base_b += s3d_tri->TdBdY; - state->base_a += s3d_tri->TdAdY; - state->base_d += s3d_tri->TdDdY; - state->base_w += s3d_tri->TdWdY; - state->y--; - dest_offset -= s3d_tri->dest_str; - z_offset -= s3d_tri->z_str; - } + z += s3d_tri->TdZdX; + state->u += s3d_tri->TdUdX; + state->v += s3d_tri->TdVdX; + state->r += s3d_tri->TdRdX; + state->g += s3d_tri->TdGdX; + state->b += s3d_tri->TdBdX; + state->a += s3d_tri->TdAdX; + state->d += s3d_tri->TdDdX; + state->w += s3d_tri->TdWdX; + dest_addr += x_offset; + z_addr += xz_offset; + virge->pixel_count++; + } + } + tri_skip_line: + state->x1 += dx1; + state->x2 += dx2; + state->base_u += s3d_tri->TdUdY; + state->base_v += s3d_tri->TdVdY; + state->base_z += s3d_tri->TdZdY; + state->base_r += s3d_tri->TdRdY; + state->base_g += s3d_tri->TdGdY; + state->base_b += s3d_tri->TdBdY; + state->base_a += s3d_tri->TdAdY; + state->base_d += s3d_tri->TdDdY; + state->base_w += s3d_tri->TdWdY; + state->y--; + dest_offset -= s3d_tri->dest_str; + z_offset -= s3d_tri->z_str; + } } -static int tex_size[8] = - { - 4 * 2, - 2 * 2, - 2 * 2, - 1 * 2, - 2 / 1, - 2 / 1, - 1 * 2, - 1 * 2 - }; +static int tex_size[8] = {4 * 2, 2 * 2, 2 * 2, 1 * 2, 2 / 1, 2 / 1, 1 * 2, 1 * 2}; static void s3_virge_triangle(virge_t *virge, s3d_t *s3d_tri) { - s3d_state_t state; + s3d_state_t state; - uint32_t tex_base; - int c; + uint32_t tex_base; + int c; - uint64_t start_time = timer_read(); - uint64_t end_time; + uint64_t start_time = timer_read(); + uint64_t end_time; - state.tbu = s3d_tri->tbu << 11; - state.tbv = s3d_tri->tbv << 11; + state.tbu = s3d_tri->tbu << 11; + state.tbv = s3d_tri->tbv << 11; - state.max_d = (s3d_tri->cmd_set >> 8) & 15; + state.max_d = (s3d_tri->cmd_set >> 8) & 15; - state.tex_bdr_clr = s3d_tri->tex_bdr_clr; + state.tex_bdr_clr = s3d_tri->tex_bdr_clr; - state.cmd_set = s3d_tri->cmd_set; + state.cmd_set = s3d_tri->cmd_set; - state.base_u = s3d_tri->tus; - state.base_v = s3d_tri->tvs; - state.base_z = s3d_tri->tzs; - state.base_r = (int32_t)s3d_tri->trs; - state.base_g = (int32_t)s3d_tri->tgs; - state.base_b = (int32_t)s3d_tri->tbs; - state.base_a = (int32_t)s3d_tri->tas; - state.base_d = s3d_tri->tds; - state.base_w = s3d_tri->tws; + state.base_u = s3d_tri->tus; + state.base_v = s3d_tri->tvs; + state.base_z = s3d_tri->tzs; + state.base_r = (int32_t)s3d_tri->trs; + state.base_g = (int32_t)s3d_tri->tgs; + state.base_b = (int32_t)s3d_tri->tbs; + state.base_a = (int32_t)s3d_tri->tas; + state.base_d = s3d_tri->tds; + state.base_w = s3d_tri->tws; - tex_base = s3d_tri->tex_base; - for (c = 9; c >= 0; c--) { - state.texture[c] = (uint16_t *)&virge->svga.vram[tex_base]; - if (c <= state.max_d) - tex_base += ((1 << (c * 2)) * tex_size[(s3d_tri->cmd_set >> 5) & 7]) / 2; - } + tex_base = s3d_tri->tex_base; + for (c = 9; c >= 0; c--) { + state.texture[c] = (uint16_t *)&virge->svga.vram[tex_base]; + if (c <= state.max_d) + tex_base += ((1 << (c * 2)) * tex_size[(s3d_tri->cmd_set >> 5) & 7]) / 2; + } - switch ((s3d_tri->cmd_set >> 27) & 0xf) { - case 0:dest_pixel = dest_pixel_gouraud_shaded_triangle; -// pclog("dest_pixel_gouraud_shaded_triangle\n"); - break; - case 1: - case 5: - switch ((s3d_tri->cmd_set >> 15) & 0x3) { - case 0:dest_pixel = dest_pixel_lit_texture_reflection; -// pclog("dest_pixel_lit_texture_reflection\n"); - break; - case 1:dest_pixel = dest_pixel_lit_texture_modulate; -// pclog("dest_pixel_lit_texture_modulate\n"); - break; - case 2:dest_pixel = dest_pixel_lit_texture_decal; -// pclog("dest_pixel_lit_texture_decal\n"); - break; - default:pclog("bad triangle type %x\n", (s3d_tri->cmd_set >> 27) & 0xf); - return; - } - break; - case 2: - case 6:dest_pixel = dest_pixel_unlit_texture_triangle; -// pclog("dest_pixel_unlit_texture_triangle\n"); - break; - default:pclog("bad triangle type %x\n", (s3d_tri->cmd_set >> 27) & 0xf); - return; - } + switch ((s3d_tri->cmd_set >> 27) & 0xf) { + case 0: + dest_pixel = dest_pixel_gouraud_shaded_triangle; + // pclog("dest_pixel_gouraud_shaded_triangle\n"); + break; + case 1: + case 5: + switch ((s3d_tri->cmd_set >> 15) & 0x3) { + case 0: + dest_pixel = dest_pixel_lit_texture_reflection; + // pclog("dest_pixel_lit_texture_reflection\n"); + break; + case 1: + dest_pixel = dest_pixel_lit_texture_modulate; + // pclog("dest_pixel_lit_texture_modulate\n"); + break; + case 2: + dest_pixel = dest_pixel_lit_texture_decal; + // pclog("dest_pixel_lit_texture_decal\n"); + break; + default: + pclog("bad triangle type %x\n", (s3d_tri->cmd_set >> 27) & 0xf); + return; + } + break; + case 2: + case 6: + dest_pixel = dest_pixel_unlit_texture_triangle; + // pclog("dest_pixel_unlit_texture_triangle\n"); + break; + default: + pclog("bad triangle type %x\n", (s3d_tri->cmd_set >> 27) & 0xf); + return; + } - switch (((s3d_tri->cmd_set >> 12) & 7) | ((s3d_tri->cmd_set & (1 << 29)) ? 8 : 0)) { - case 0: - case 1:tex_sample = tex_sample_mipmap; -// pclog("use tex_sample_mipmap\n"); - break; - case 2: - case 3:tex_sample = virge->bilinear_enabled ? tex_sample_mipmap_filter : tex_sample_mipmap; -// pclog("use tex_sample_mipmap_filter\n"); - break; - case 4: - case 5:tex_sample = tex_sample_normal; -// pclog("use tex_sample_normal\n"); - break; - case 6: - case 7:tex_sample = virge->bilinear_enabled ? tex_sample_normal_filter : tex_sample_normal; -// pclog("use tex_sample_normal_filter\n"); - break; - case (0 | 8): - case (1 | 8): - if (virge->is_375) - tex_sample = tex_sample_persp_mipmap_375; - else - tex_sample = tex_sample_persp_mipmap; -// pclog("use tex_sample_persp_mipmap\n"); - break; - case (2 | 8): - case (3 | 8): - if (virge->is_375) - tex_sample = virge->bilinear_enabled ? tex_sample_persp_mipmap_filter_375 : tex_sample_persp_mipmap_375; - else - tex_sample = virge->bilinear_enabled ? tex_sample_persp_mipmap_filter : tex_sample_persp_mipmap; -// pclog("use tex_sample_persp_mipmap_filter\n"); - break; - case (4 | 8): - case (5 | 8): - if (virge->is_375) - tex_sample = tex_sample_persp_normal_375; - else - tex_sample = tex_sample_persp_normal; -// pclog("use tex_sample_persp_normal\n"); - break; - case (6 | 8): - case (7 | 8): - if (virge->is_375) - tex_sample = virge->bilinear_enabled ? tex_sample_persp_normal_filter_375 : tex_sample_persp_normal_375; - else - tex_sample = virge->bilinear_enabled ? tex_sample_persp_normal_filter : tex_sample_persp_normal; -// pclog("use tex_sample_persp_normal_filter\n"); - break; - } + switch (((s3d_tri->cmd_set >> 12) & 7) | ((s3d_tri->cmd_set & (1 << 29)) ? 8 : 0)) { + case 0: + case 1: + tex_sample = tex_sample_mipmap; + // pclog("use tex_sample_mipmap\n"); + break; + case 2: + case 3: + tex_sample = virge->bilinear_enabled ? tex_sample_mipmap_filter : tex_sample_mipmap; + // pclog("use tex_sample_mipmap_filter\n"); + break; + case 4: + case 5: + tex_sample = tex_sample_normal; + // pclog("use tex_sample_normal\n"); + break; + case 6: + case 7: + tex_sample = virge->bilinear_enabled ? tex_sample_normal_filter : tex_sample_normal; + // pclog("use tex_sample_normal_filter\n"); + break; + case (0 | 8): + case (1 | 8): + if (virge->is_375) + tex_sample = tex_sample_persp_mipmap_375; + else + tex_sample = tex_sample_persp_mipmap; + // pclog("use tex_sample_persp_mipmap\n"); + break; + case (2 | 8): + case (3 | 8): + if (virge->is_375) + tex_sample = virge->bilinear_enabled ? tex_sample_persp_mipmap_filter_375 : tex_sample_persp_mipmap_375; + else + tex_sample = virge->bilinear_enabled ? tex_sample_persp_mipmap_filter : tex_sample_persp_mipmap; + // pclog("use tex_sample_persp_mipmap_filter\n"); + break; + case (4 | 8): + case (5 | 8): + if (virge->is_375) + tex_sample = tex_sample_persp_normal_375; + else + tex_sample = tex_sample_persp_normal; + // pclog("use tex_sample_persp_normal\n"); + break; + case (6 | 8): + case (7 | 8): + if (virge->is_375) + tex_sample = virge->bilinear_enabled ? tex_sample_persp_normal_filter_375 : tex_sample_persp_normal_375; + else + tex_sample = virge->bilinear_enabled ? tex_sample_persp_normal_filter : tex_sample_persp_normal; + // pclog("use tex_sample_persp_normal_filter\n"); + break; + } - switch ((s3d_tri->cmd_set >> 5) & 7) { - case 0:tex_read = (s3d_tri->cmd_set & CMD_SET_TWE) ? tex_ARGB8888 : tex_ARGB8888_nowrap; - break; - case 1:tex_read = (s3d_tri->cmd_set & CMD_SET_TWE) ? tex_ARGB4444 : tex_ARGB4444_nowrap; -// pclog("tex_ARGB4444\n"); - break; - case 2:tex_read = (s3d_tri->cmd_set & CMD_SET_TWE) ? tex_ARGB1555 : tex_ARGB1555_nowrap; -// pclog("tex_ARGB1555 %i\n", (s3d_tri->cmd_set >> 5) & 7); - break; - default:pclog("bad texture type %i\n", (s3d_tri->cmd_set >> 5) & 7); - tex_read = (s3d_tri->cmd_set & CMD_SET_TWE) ? tex_ARGB1555 : tex_ARGB1555_nowrap; - break; - } + switch ((s3d_tri->cmd_set >> 5) & 7) { + case 0: + tex_read = (s3d_tri->cmd_set & CMD_SET_TWE) ? tex_ARGB8888 : tex_ARGB8888_nowrap; + break; + case 1: + tex_read = (s3d_tri->cmd_set & CMD_SET_TWE) ? tex_ARGB4444 : tex_ARGB4444_nowrap; + // pclog("tex_ARGB4444\n"); + break; + case 2: + tex_read = (s3d_tri->cmd_set & CMD_SET_TWE) ? tex_ARGB1555 : tex_ARGB1555_nowrap; + // pclog("tex_ARGB1555 %i\n", (s3d_tri->cmd_set >> 5) & 7); + break; + default: + pclog("bad texture type %i\n", (s3d_tri->cmd_set >> 5) & 7); + tex_read = (s3d_tri->cmd_set & CMD_SET_TWE) ? tex_ARGB1555 : tex_ARGB1555_nowrap; + break; + } -// pclog("Triangle %i %i,%i to %i,%i %08x\n", y, x1 >> 20, y, s3d_tri->txend01 >> 20, y - (s3d_tri->ty01 + s3d_tri->ty12), state.cmd_set); + // pclog("Triangle %i %i,%i to %i,%i %08x\n", y, x1 >> 20, y, s3d_tri->txend01 >> 20, y - (s3d_tri->ty01 + + // s3d_tri->ty12), state.cmd_set); - state.y = s3d_tri->tys; - state.x1 = s3d_tri->txs; - state.x2 = s3d_tri->txend01; - tri(virge, s3d_tri, &state, s3d_tri->ty01, s3d_tri->TdXdY02, s3d_tri->TdXdY01); - state.x2 = s3d_tri->txend12; - tri(virge, s3d_tri, &state, s3d_tri->ty12, s3d_tri->TdXdY02, s3d_tri->TdXdY12); + state.y = s3d_tri->tys; + state.x1 = s3d_tri->txs; + state.x2 = s3d_tri->txend01; + tri(virge, s3d_tri, &state, s3d_tri->ty01, s3d_tri->TdXdY02, s3d_tri->TdXdY01); + state.x2 = s3d_tri->txend12; + tri(virge, s3d_tri, &state, s3d_tri->ty12, s3d_tri->TdXdY02, s3d_tri->TdXdY12); - virge->tri_count++; + virge->tri_count++; - end_time = timer_read(); + end_time = timer_read(); - virge_time += end_time - start_time; + virge_time += end_time - start_time; } static void render_thread(void *param) { - virge_t *virge = (virge_t *)param; + virge_t *virge = (virge_t *)param; - while (1) { - thread_wait_event(virge->wake_render_thread, -1); - thread_reset_event(virge->wake_render_thread); - virge->s3d_busy = 1; - while (!RB_EMPTY) { - s3_virge_triangle(virge, &virge->s3d_buffer[virge->s3d_read_idx & RB_MASK]); - virge->s3d_read_idx++; + while (1) { + thread_wait_event(virge->wake_render_thread, -1); + thread_reset_event(virge->wake_render_thread); + virge->s3d_busy = 1; + while (!RB_EMPTY) { + s3_virge_triangle(virge, &virge->s3d_buffer[virge->s3d_read_idx & RB_MASK]); + virge->s3d_read_idx++; - if (RB_ENTRIES == RB_SIZE - 1) - thread_set_event(virge->not_full_event); - } - virge->s3d_busy = 0; - virge->subsys_stat |= INT_S3D_DONE; - s3_virge_update_irqs(virge); - } + if (RB_ENTRIES == RB_SIZE - 1) + thread_set_event(virge->not_full_event); + } + virge->s3d_busy = 0; + virge->subsys_stat |= INT_S3D_DONE; + s3_virge_update_irqs(virge); + } } static void queue_triangle(virge_t *virge) { -// pclog("queue_triangle: read=%i write=%i RB_ENTRIES=%i RB_FULL=%i\n", virge->s3d_read_idx, virge->s3d_write_idx, RB_ENTRIES, RB_FULL); - if (RB_FULL) { - thread_reset_event(virge->not_full_event); - if (RB_FULL) - thread_wait_event(virge->not_full_event, -1); /*Wait for room in ringbuffer*/ - } -// pclog(" add at read=%i write=%i %i\n", virge->s3d_read_idx, virge->s3d_write_idx, virge->s3d_write_idx & RB_MASK); - virge->s3d_buffer[virge->s3d_write_idx & RB_MASK] = virge->s3d_tri; - virge->s3d_write_idx++; - if (!virge->s3d_busy) - thread_set_event(virge->wake_render_thread); /*Wake up render thread if moving from idle*/ + // pclog("queue_triangle: read=%i write=%i RB_ENTRIES=%i RB_FULL=%i\n", virge->s3d_read_idx, virge->s3d_write_idx, + // RB_ENTRIES, RB_FULL); + if (RB_FULL) { + thread_reset_event(virge->not_full_event); + if (RB_FULL) + thread_wait_event(virge->not_full_event, -1); /*Wait for room in ringbuffer*/ + } + // pclog(" add at read=%i write=%i %i\n", virge->s3d_read_idx, virge->s3d_write_idx, + // virge->s3d_write_idx & RB_MASK); + virge->s3d_buffer[virge->s3d_write_idx & RB_MASK] = virge->s3d_tri; + virge->s3d_write_idx++; + if (!virge->s3d_busy) + thread_set_event(virge->wake_render_thread); /*Wake up render thread if moving from idle*/ } static void s3_virge_hwcursor_draw(svga_t *svga, int displine) { - virge_t *virge = (virge_t *)svga->p; - int x; - uint16_t dat[2]; - int xx; - int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; - uint32_t fg, bg; + virge_t *virge = (virge_t *)svga->p; + int x; + uint16_t dat[2]; + int xx; + int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; + uint32_t fg, bg; -// pclog("HWcursor %i %i %08x %08x\n", svga->hwcursor_latch.x, svga->hwcursor_latch.y, virge->hwcursor_col[0],virge->hwcursor_col[1]); - switch (svga->bpp) { - case 15:fg = video_15to32[virge->hwc_fg_col & 0xffff]; - bg = video_15to32[virge->hwc_bg_col & 0xffff]; - break; + // pclog("HWcursor %i %i %08x %08x\n", svga->hwcursor_latch.x, svga->hwcursor_latch.y, + // virge->hwcursor_col[0],virge->hwcursor_col[1]); + switch (svga->bpp) { + case 15: + fg = video_15to32[virge->hwc_fg_col & 0xffff]; + bg = video_15to32[virge->hwc_bg_col & 0xffff]; + break; - case 16:fg = video_16to32[virge->hwc_fg_col & 0xffff]; - bg = video_16to32[virge->hwc_bg_col & 0xffff]; - break; + case 16: + fg = video_16to32[virge->hwc_fg_col & 0xffff]; + bg = video_16to32[virge->hwc_bg_col & 0xffff]; + break; - case 24: - case 32:fg = virge->hwc_fg_col; - bg = virge->hwc_bg_col; - break; + case 24: + case 32: + fg = virge->hwc_fg_col; + bg = virge->hwc_bg_col; + break; - default:fg = svga->pallook[virge->hwc_fg_col & 0xff]; - bg = svga->pallook[virge->hwc_bg_col & 0xff]; - break; - } + default: + fg = svga->pallook[virge->hwc_fg_col & 0xff]; + bg = svga->pallook[virge->hwc_bg_col & 0xff]; + break; + } - for (x = 0; x < 64; x += 16) { - dat[0] = (svga->vram[svga->hwcursor_latch.addr] << 8) | svga->vram[svga->hwcursor_latch.addr + 1]; - dat[1] = (svga->vram[svga->hwcursor_latch.addr + 2] << 8) | svga->vram[svga->hwcursor_latch.addr + 3]; - if (svga->crtc[0x55] & 0x10) { - /*X11*/ - for (xx = 0; xx < 16; xx++) { - if (offset >= svga->hwcursor_latch.x) { - if (dat[0] & 0x8000) - ((uint32_t *)buffer32->line[displine])[offset + 32] = (dat[1] & 0x8000) ? fg : bg; - } + for (x = 0; x < 64; x += 16) { + dat[0] = (svga->vram[svga->hwcursor_latch.addr] << 8) | svga->vram[svga->hwcursor_latch.addr + 1]; + dat[1] = (svga->vram[svga->hwcursor_latch.addr + 2] << 8) | svga->vram[svga->hwcursor_latch.addr + 3]; + if (svga->crtc[0x55] & 0x10) { + /*X11*/ + for (xx = 0; xx < 16; xx++) { + if (offset >= svga->hwcursor_latch.x) { + if (dat[0] & 0x8000) + ((uint32_t *)buffer32->line[displine])[offset + 32] = (dat[1] & 0x8000) ? fg : bg; + } - offset++; - dat[0] <<= 1; - dat[1] <<= 1; - } - } else { - /*Windows*/ - for (xx = 0; xx < 16; xx++) { - if (offset >= svga->hwcursor_latch.x) { - if (!(dat[0] & 0x8000)) - ((uint32_t *)buffer32->line[displine])[offset + 32] = (dat[1] & 0x8000) ? fg : bg; - else if (dat[1] & 0x8000) - ((uint32_t *)buffer32->line[displine])[offset + 32] ^= 0xffffff; -// pclog("Plot %i, %i (%i %i) %04X %04X\n", offset, displine, x+xx, svga->hwcursor_on, dat[0], dat[1]); - } + offset++; + dat[0] <<= 1; + dat[1] <<= 1; + } + } else { + /*Windows*/ + for (xx = 0; xx < 16; xx++) { + if (offset >= svga->hwcursor_latch.x) { + if (!(dat[0] & 0x8000)) + ((uint32_t *)buffer32->line[displine])[offset + 32] = (dat[1] & 0x8000) ? fg : bg; + else if (dat[1] & 0x8000) + ((uint32_t *)buffer32->line[displine])[offset + 32] ^= 0xffffff; + // pclog("Plot %i, %i (%i %i) %04X %04X\n", offset, + // displine, x+xx, svga->hwcursor_on, dat[0], dat[1]); + } - offset++; - dat[0] <<= 1; - dat[1] <<= 1; - } - } - svga->hwcursor_latch.addr += 4; - } + offset++; + dat[0] <<= 1; + dat[1] <<= 1; + } + } + svga->hwcursor_latch.addr += 4; + } } -#define DECODE_YCbCr() \ - do \ - { \ - int c; \ - \ - for (c = 0; c < 2; c++) \ - { \ - uint8_t y1, y2; \ - int8_t Cr, Cb; \ - int dR, dG, dB; \ - \ - y1 = src[0]; \ - Cr = src[1] - 0x80; \ - y2 = src[2]; \ - Cb = src[3] - 0x80; \ - src += 4; \ - \ - dR = (359*Cr) >> 8; \ - dG = (88*Cb + 183*Cr) >> 8; \ - dB = (453*Cb) >> 8; \ - \ - r[x_write] = y1 + dR; \ - CLAMP(r[x_write]); \ - g[x_write] = y1 - dG; \ - CLAMP(g[x_write]); \ - b[x_write] = y1 + dB; \ - CLAMP(b[x_write]); \ - \ - r[x_write+1] = y2 + dR; \ - CLAMP(r[x_write+1]); \ - g[x_write+1] = y2 - dG; \ - CLAMP(g[x_write+1]); \ - b[x_write+1] = y2 + dB; \ - CLAMP(b[x_write+1]); \ - \ - x_write = (x_write + 2) & 7; \ - } \ +#define DECODE_YCbCr() \ + do { \ + int c; \ + \ + for (c = 0; c < 2; c++) { \ + uint8_t y1, y2; \ + int8_t Cr, Cb; \ + int dR, dG, dB; \ + \ + y1 = src[0]; \ + Cr = src[1] - 0x80; \ + y2 = src[2]; \ + Cb = src[3] - 0x80; \ + src += 4; \ + \ + dR = (359 * Cr) >> 8; \ + dG = (88 * Cb + 183 * Cr) >> 8; \ + dB = (453 * Cb) >> 8; \ + \ + r[x_write] = y1 + dR; \ + CLAMP(r[x_write]); \ + g[x_write] = y1 - dG; \ + CLAMP(g[x_write]); \ + b[x_write] = y1 + dB; \ + CLAMP(b[x_write]); \ + \ + r[x_write + 1] = y2 + dR; \ + CLAMP(r[x_write + 1]); \ + g[x_write + 1] = y2 - dG; \ + CLAMP(g[x_write + 1]); \ + b[x_write + 1] = y2 + dB; \ + CLAMP(b[x_write + 1]); \ + \ + x_write = (x_write + 2) & 7; \ + } \ } while (0) /*Both YUV formats are untested*/ -#define DECODE_YUV211() \ - do \ - { \ - uint8_t y1, y2, y3, y4; \ - int8_t U, V; \ - int dR, dG, dB; \ - \ - U = src[0] - 0x80; \ - y1 = (298 * (src[1] - 16)) >> 8; \ - y2 = (298 * (src[2] - 16)) >> 8; \ - V = src[3] - 0x80; \ - y3 = (298 * (src[4] - 16)) >> 8; \ - y4 = (298 * (src[5] - 16)) >> 8; \ - src += 6; \ - \ - dR = (309*V) >> 8; \ - dG = (100*U + 208*V) >> 8; \ - dB = (516*U) >> 8; \ - \ - r[x_write] = y1 + dR; \ - CLAMP(r[x_write]); \ - g[x_write] = y1 - dG; \ - CLAMP(g[x_write]); \ - b[x_write] = y1 + dB; \ - CLAMP(b[x_write]); \ - \ - r[x_write+1] = y2 + dR; \ - CLAMP(r[x_write+1]); \ - g[x_write+1] = y2 - dG; \ - CLAMP(g[x_write+1]); \ - b[x_write+1] = y2 + dB; \ - CLAMP(b[x_write+1]); \ - \ - r[x_write+2] = y3 + dR; \ - CLAMP(r[x_write+2]); \ - g[x_write+2] = y3 - dG; \ - CLAMP(g[x_write+2]); \ - b[x_write+2] = y3 + dB; \ - CLAMP(b[x_write+2]); \ - \ - r[x_write+3] = y4 + dR; \ - CLAMP(r[x_write+3]); \ - g[x_write+3] = y4 - dG; \ - CLAMP(g[x_write+3]); \ - b[x_write+3] = y4 + dB; \ - CLAMP(b[x_write+3]); \ - \ - x_write = (x_write + 4) & 7; \ +#define DECODE_YUV211() \ + do { \ + uint8_t y1, y2, y3, y4; \ + int8_t U, V; \ + int dR, dG, dB; \ + \ + U = src[0] - 0x80; \ + y1 = (298 * (src[1] - 16)) >> 8; \ + y2 = (298 * (src[2] - 16)) >> 8; \ + V = src[3] - 0x80; \ + y3 = (298 * (src[4] - 16)) >> 8; \ + y4 = (298 * (src[5] - 16)) >> 8; \ + src += 6; \ + \ + dR = (309 * V) >> 8; \ + dG = (100 * U + 208 * V) >> 8; \ + dB = (516 * U) >> 8; \ + \ + r[x_write] = y1 + dR; \ + CLAMP(r[x_write]); \ + g[x_write] = y1 - dG; \ + CLAMP(g[x_write]); \ + b[x_write] = y1 + dB; \ + CLAMP(b[x_write]); \ + \ + r[x_write + 1] = y2 + dR; \ + CLAMP(r[x_write + 1]); \ + g[x_write + 1] = y2 - dG; \ + CLAMP(g[x_write + 1]); \ + b[x_write + 1] = y2 + dB; \ + CLAMP(b[x_write + 1]); \ + \ + r[x_write + 2] = y3 + dR; \ + CLAMP(r[x_write + 2]); \ + g[x_write + 2] = y3 - dG; \ + CLAMP(g[x_write + 2]); \ + b[x_write + 2] = y3 + dB; \ + CLAMP(b[x_write + 2]); \ + \ + r[x_write + 3] = y4 + dR; \ + CLAMP(r[x_write + 3]); \ + g[x_write + 3] = y4 - dG; \ + CLAMP(g[x_write + 3]); \ + b[x_write + 3] = y4 + dB; \ + CLAMP(b[x_write + 3]); \ + \ + x_write = (x_write + 4) & 7; \ } while (0) -#define DECODE_YUV422() \ - do \ - { \ - int c; \ - \ - for (c = 0; c < 2; c++) \ - { \ - uint8_t y1, y2; \ - int8_t U, V; \ - int dR, dG, dB; \ - \ - U = src[0] - 0x80; \ - y1 = (298 * (src[1] - 16)) >> 8; \ - V = src[2] - 0x80; \ - y2 = (298 * (src[3] - 16)) >> 8; \ - src += 4; \ - \ - dR = (309*V) >> 8; \ - dG = (100*U + 208*V) >> 8; \ - dB = (516*U) >> 8; \ - \ - r[x_write] = y1 + dR; \ - CLAMP(r[x_write]); \ - g[x_write] = y1 - dG; \ - CLAMP(g[x_write]); \ - b[x_write] = y1 + dB; \ - CLAMP(b[x_write]); \ - \ - r[x_write+1] = y2 + dR; \ - CLAMP(r[x_write+1]); \ - g[x_write+1] = y2 - dG; \ - CLAMP(g[x_write+1]); \ - b[x_write+1] = y2 + dB; \ - CLAMP(b[x_write+1]); \ - \ - x_write = (x_write + 2) & 7; \ - } \ +#define DECODE_YUV422() \ + do { \ + int c; \ + \ + for (c = 0; c < 2; c++) { \ + uint8_t y1, y2; \ + int8_t U, V; \ + int dR, dG, dB; \ + \ + U = src[0] - 0x80; \ + y1 = (298 * (src[1] - 16)) >> 8; \ + V = src[2] - 0x80; \ + y2 = (298 * (src[3] - 16)) >> 8; \ + src += 4; \ + \ + dR = (309 * V) >> 8; \ + dG = (100 * U + 208 * V) >> 8; \ + dB = (516 * U) >> 8; \ + \ + r[x_write] = y1 + dR; \ + CLAMP(r[x_write]); \ + g[x_write] = y1 - dG; \ + CLAMP(g[x_write]); \ + b[x_write] = y1 + dB; \ + CLAMP(b[x_write]); \ + \ + r[x_write + 1] = y2 + dR; \ + CLAMP(r[x_write + 1]); \ + g[x_write + 1] = y2 - dG; \ + CLAMP(g[x_write + 1]); \ + b[x_write + 1] = y2 + dB; \ + CLAMP(b[x_write + 1]); \ + \ + x_write = (x_write + 2) & 7; \ + } \ } while (0) -#define DECODE_RGB555() \ - do \ - { \ - int c; \ - \ - for (c = 0; c < 4; c++) \ - { \ - uint16_t dat; \ - \ - dat = *(uint16_t *)src; \ - src += 2; \ - \ - r[x_write + c] = ((dat & 0x001f) << 3) | ((dat & 0x001f) >> 2); \ - g[x_write + c] = ((dat & 0x03e0) >> 2) | ((dat & 0x03e0) >> 7); \ - b[x_write + c] = ((dat & 0x7c00) >> 7) | ((dat & 0x7c00) >> 12); \ - } \ - x_write = (x_write + 4) & 7; \ +#define DECODE_RGB555() \ + do { \ + int c; \ + \ + for (c = 0; c < 4; c++) { \ + uint16_t dat; \ + \ + dat = *(uint16_t *)src; \ + src += 2; \ + \ + r[x_write + c] = ((dat & 0x001f) << 3) | ((dat & 0x001f) >> 2); \ + g[x_write + c] = ((dat & 0x03e0) >> 2) | ((dat & 0x03e0) >> 7); \ + b[x_write + c] = ((dat & 0x7c00) >> 7) | ((dat & 0x7c00) >> 12); \ + } \ + x_write = (x_write + 4) & 7; \ } while (0) -#define DECODE_RGB565() \ - do \ - { \ - int c; \ - \ - for (c = 0; c < 4; c++) \ - { \ - uint16_t dat; \ - \ - dat = *(uint16_t *)src; \ - src += 2; \ - \ - r[x_write + c] = ((dat & 0x001f) << 3) | ((dat & 0x001f) >> 2); \ - g[x_write + c] = ((dat & 0x07e0) >> 3) | ((dat & 0x07e0) >> 9); \ - b[x_write + c] = ((dat & 0xf800) >> 8) | ((dat & 0xf800) >> 13); \ - } \ - x_write = (x_write + 4) & 7; \ +#define DECODE_RGB565() \ + do { \ + int c; \ + \ + for (c = 0; c < 4; c++) { \ + uint16_t dat; \ + \ + dat = *(uint16_t *)src; \ + src += 2; \ + \ + r[x_write + c] = ((dat & 0x001f) << 3) | ((dat & 0x001f) >> 2); \ + g[x_write + c] = ((dat & 0x07e0) >> 3) | ((dat & 0x07e0) >> 9); \ + b[x_write + c] = ((dat & 0xf800) >> 8) | ((dat & 0xf800) >> 13); \ + } \ + x_write = (x_write + 4) & 7; \ } while (0) -#define DECODE_RGB888() \ - do \ - { \ - int c; \ - \ - for (c = 0; c < 4; c++) \ - { \ - r[x_write + c] = src[0]; \ - g[x_write + c] = src[1]; \ - b[x_write + c] = src[2]; \ - src += 3; \ - } \ - x_write = (x_write + 4) & 7; \ +#define DECODE_RGB888() \ + do { \ + int c; \ + \ + for (c = 0; c < 4; c++) { \ + r[x_write + c] = src[0]; \ + g[x_write + c] = src[1]; \ + b[x_write + c] = src[2]; \ + src += 3; \ + } \ + x_write = (x_write + 4) & 7; \ } while (0) -#define DECODE_XRGB8888() \ - do \ - { \ - int c; \ - \ - for (c = 0; c < 4; c++) \ - { \ - r[x_write + c] = src[0]; \ - g[x_write + c] = src[1]; \ - b[x_write + c] = src[2]; \ - src += 4; \ - } \ - x_write = (x_write + 4) & 7; \ +#define DECODE_XRGB8888() \ + do { \ + int c; \ + \ + for (c = 0; c < 4; c++) { \ + r[x_write + c] = src[0]; \ + g[x_write + c] = src[1]; \ + b[x_write + c] = src[2]; \ + src += 4; \ + } \ + x_write = (x_write + 4) & 7; \ } while (0) -#define OVERLAY_SAMPLE() \ - do \ - { \ - switch (virge->streams.sdif) \ - { \ - case 1: \ - DECODE_YCbCr(); \ - break; \ - case 2: \ - DECODE_YUV422(); \ - break; \ - case 3: \ - DECODE_RGB555(); \ - break; \ - case 4: \ - DECODE_YUV211(); \ - break; \ - case 5: \ - DECODE_RGB565(); \ - break; \ - case 6: \ - DECODE_RGB888(); \ - break; \ - case 7: \ - default: \ - DECODE_XRGB8888(); \ - break; \ - } \ +#define OVERLAY_SAMPLE() \ + do { \ + switch (virge->streams.sdif) { \ + case 1: \ + DECODE_YCbCr(); \ + break; \ + case 2: \ + DECODE_YUV422(); \ + break; \ + case 3: \ + DECODE_RGB555(); \ + break; \ + case 4: \ + DECODE_YUV211(); \ + break; \ + case 5: \ + DECODE_RGB565(); \ + break; \ + case 6: \ + DECODE_RGB888(); \ + break; \ + case 7: \ + default: \ + DECODE_XRGB8888(); \ + break; \ + } \ } while (0) static void s3_virge_overlay_draw(svga_t *svga, int displine) { - virge_t *virge = (virge_t *)svga->p; - int offset = (virge->streams.sec_x - virge->streams.pri_x) + 1; - int h_acc = virge->streams.dda_horiz_accumulator; - int r[8], g[8], b[8]; - int x_size, x_read = 4, x_write = 4; - int x; - uint32_t *p; - uint8_t *src = &svga->vram[svga->overlay_latch.addr]; + virge_t *virge = (virge_t *)svga->p; + int offset = (virge->streams.sec_x - virge->streams.pri_x) + 1; + int h_acc = virge->streams.dda_horiz_accumulator; + int r[8], g[8], b[8]; + int x_size, x_read = 4, x_write = 4; + int x; + uint32_t *p; + uint8_t *src = &svga->vram[svga->overlay_latch.addr]; - p = &((uint32_t *)buffer32->line[displine])[offset + 32]; + p = &((uint32_t *)buffer32->line[displine])[offset + 32]; - if ((offset + virge->streams.sec_w) > virge->streams.pri_w) - x_size = (virge->streams.pri_w - virge->streams.sec_x) + 1; - else - x_size = virge->streams.sec_w + 1; + if ((offset + virge->streams.sec_w) > virge->streams.pri_w) + x_size = (virge->streams.pri_w - virge->streams.sec_x) + 1; + else + x_size = virge->streams.sec_w + 1; - OVERLAY_SAMPLE(); + OVERLAY_SAMPLE(); - for (x = 0; x < x_size; x++) { - *p++ = r[x_read] | (g[x_read] << 8) | (b[x_read] << 16); + for (x = 0; x < x_size; x++) { + *p++ = r[x_read] | (g[x_read] << 8) | (b[x_read] << 16); - h_acc += virge->streams.k1_horiz_scale; - if (h_acc >= 0) { - if ((x_read ^ (x_read + 1)) & ~3) - OVERLAY_SAMPLE(); - x_read = (x_read + 1) & 7; + h_acc += virge->streams.k1_horiz_scale; + if (h_acc >= 0) { + if ((x_read ^ (x_read + 1)) & ~3) + OVERLAY_SAMPLE(); + x_read = (x_read + 1) & 7; - h_acc += (virge->streams.k2_horiz_scale - virge->streams.k1_horiz_scale); - } - } + h_acc += (virge->streams.k2_horiz_scale - virge->streams.k1_horiz_scale); + } + } - svga->overlay_latch.v_acc += virge->streams.k1_vert_scale; - if (svga->overlay_latch.v_acc >= 0) { - svga->overlay_latch.v_acc += (virge->streams.k2_vert_scale - virge->streams.k1_vert_scale); - svga->overlay_latch.addr += virge->streams.sec_stride; - } + svga->overlay_latch.v_acc += virge->streams.k1_vert_scale; + if (svga->overlay_latch.v_acc >= 0) { + svga->overlay_latch.v_acc += (virge->streams.k2_vert_scale - virge->streams.k1_vert_scale); + svga->overlay_latch.addr += virge->streams.sec_stride; + } } static uint8_t s3_virge_pci_read(int func, int addr, void *p) { - virge_t *virge = (virge_t *)p; - svga_t *svga = &virge->svga; - uint8_t ret = 0; -// pclog("S3 PCI read %08X ", addr); - switch (addr) { - case 0x00:ret = 0x33; - break; /*'S3'*/ - case 0x01:ret = 0x53; - break; + virge_t *virge = (virge_t *)p; + svga_t *svga = &virge->svga; + uint8_t ret = 0; + // pclog("S3 PCI read %08X ", addr); + switch (addr) { + case 0x00: + ret = 0x33; + break; /*'S3'*/ + case 0x01: + ret = 0x53; + break; - case 0x02:ret = virge->virge_id_low; - break; - case 0x03:ret = virge->virge_id_high; - break; + case 0x02: + ret = virge->virge_id_low; + break; + case 0x03: + ret = virge->virge_id_high; + break; - case 0x04:ret = virge->pci_regs[0x04] & 0x27; - break; + case 0x04: + ret = virge->pci_regs[0x04] & 0x27; + break; - case 0x07:ret = virge->pci_regs[0x07] & 0x36; - break; + case 0x07: + ret = virge->pci_regs[0x07] & 0x36; + break; - case 0x08:ret = 0; - break; /*Revision ID*/ - case 0x09:ret = 0; - break; /*Programming interface*/ + case 0x08: + ret = 0; + break; /*Revision ID*/ + case 0x09: + ret = 0; + break; /*Programming interface*/ - case 0x0a:ret = 0x00; - break; /*Supports VGA interface*/ - case 0x0b:ret = 0x03; /*output = 3; */break; + case 0x0a: + ret = 0x00; + break; /*Supports VGA interface*/ + case 0x0b: + ret = 0x03; /*output = 3; */ + break; - case 0x0d:ret = virge->pci_regs[0x0d] & 0xf8; - break; + case 0x0d: + ret = virge->pci_regs[0x0d] & 0xf8; + break; - case 0x10:ret = 0x00; - break;/*Linear frame buffer address*/ - case 0x11:ret = 0x00; - break; - case 0x12:ret = 0x00; - break; - case 0x13:ret = svga->crtc[0x59] & 0xfc; - break; + case 0x10: + ret = 0x00; + break; /*Linear frame buffer address*/ + case 0x11: + ret = 0x00; + break; + case 0x12: + ret = 0x00; + break; + case 0x13: + ret = svga->crtc[0x59] & 0xfc; + break; - case 0x30:ret = virge->pci_regs[0x30] & 0x01; - break; /*BIOS ROM address*/ - case 0x31:ret = 0x00; - break; - case 0x32:ret = virge->pci_regs[0x32]; - break; - case 0x33:ret = virge->pci_regs[0x33]; - break; + case 0x30: + ret = virge->pci_regs[0x30] & 0x01; + break; /*BIOS ROM address*/ + case 0x31: + ret = 0x00; + break; + case 0x32: + ret = virge->pci_regs[0x32]; + break; + case 0x33: + ret = virge->pci_regs[0x33]; + break; - case 0x3c:ret = virge->pci_regs[0x3c]; - break; + case 0x3c: + ret = virge->pci_regs[0x3c]; + break; - case 0x3d:ret = 0x01; - break; /*INTA*/ + case 0x3d: + ret = 0x01; + break; /*INTA*/ - case 0x3e:ret = 0x04; - break; - case 0x3f:ret = 0xff; - break; - - } -// pclog("%02X\n", ret); - return ret; + case 0x3e: + ret = 0x04; + break; + case 0x3f: + ret = 0xff; + break; + } + // pclog("%02X\n", ret); + return ret; } static void s3_virge_pci_write(int func, int addr, uint8_t val, void *p) { - virge_t *virge = (virge_t *)p; - svga_t *svga = &virge->svga; -// pclog("S3 PCI write %08X %02X %04X:%08X\n", addr, val, CS, pc); - switch (addr) { - case 0x00: - case 0x01: - case 0x02: - case 0x03: - case 0x08: - case 0x09: - case 0x0a: - case 0x0b: - case 0x3d: - case 0x3e: - case 0x3f:return; + virge_t *virge = (virge_t *)p; + svga_t *svga = &virge->svga; + // pclog("S3 PCI write %08X %02X %04X:%08X\n", addr, val, CS, pc); + switch (addr) { + case 0x00: + case 0x01: + case 0x02: + case 0x03: + case 0x08: + case 0x09: + case 0x0a: + case 0x0b: + case 0x3d: + case 0x3e: + case 0x3f: + return; - case PCI_REG_COMMAND: - if (val & PCI_COMMAND_IO) { - io_removehandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge); - io_sethandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge); - } else - io_removehandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge); - virge->pci_regs[PCI_REG_COMMAND] = val & 0x27; - s3_virge_updatemapping(virge); - return; - case 0x07:virge->pci_regs[0x07] = val & 0x3e; - return; - case 0x0d:virge->pci_regs[0x0d] = val & 0xf8; - return; + case PCI_REG_COMMAND: + if (val & PCI_COMMAND_IO) { + io_removehandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge); + io_sethandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge); + } else + io_removehandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge); + virge->pci_regs[PCI_REG_COMMAND] = val & 0x27; + s3_virge_updatemapping(virge); + return; + case 0x07: + virge->pci_regs[0x07] = val & 0x3e; + return; + case 0x0d: + virge->pci_regs[0x0d] = val & 0xf8; + return; - case 0x13:svga->crtc[0x59] = val & 0xfc; - s3_virge_updatemapping(virge); - return; + case 0x13: + svga->crtc[0x59] = val & 0xfc; + s3_virge_updatemapping(virge); + return; - case 0x30: - case 0x32: - case 0x33:virge->pci_regs[addr] = val; - if (virge->pci_regs[0x30] & 0x01) { - uint32_t addr = (virge->pci_regs[0x32] << 16) | (virge->pci_regs[0x33] << 24); -// pclog("Virge bios_rom enabled at %08x\n", addr); - mem_mapping_set_addr(&virge->bios_rom.mapping, addr, 0x8000); - mem_mapping_enable(&virge->bios_rom.mapping); - } else { -// pclog("Virge bios_rom disabled\n"); - mem_mapping_disable(&virge->bios_rom.mapping); - } - return; - case 0x3c:virge->pci_regs[0x3c] = val; - return; - } + case 0x30: + case 0x32: + case 0x33: + virge->pci_regs[addr] = val; + if (virge->pci_regs[0x30] & 0x01) { + uint32_t addr = (virge->pci_regs[0x32] << 16) | (virge->pci_regs[0x33] << 24); + // pclog("Virge bios_rom enabled at %08x\n", addr); + mem_mapping_set_addr(&virge->bios_rom.mapping, addr, 0x8000); + mem_mapping_enable(&virge->bios_rom.mapping); + } else { + // pclog("Virge bios_rom disabled\n"); + mem_mapping_disable(&virge->bios_rom.mapping); + } + return; + case 0x3c: + virge->pci_regs[0x3c] = val; + return; + } } static void *s3_virge_init() { - virge_t *virge = malloc(sizeof(virge_t)); - memset(virge, 0, sizeof(virge_t)); + virge_t *virge = malloc(sizeof(virge_t)); + memset(virge, 0, sizeof(virge_t)); - virge->bilinear_enabled = device_get_config_int("bilinear"); - virge->dithering_enabled = device_get_config_int("dithering"); - virge->memory_size = device_get_config_int("memory"); + virge->bilinear_enabled = device_get_config_int("bilinear"); + virge->dithering_enabled = device_get_config_int("dithering"); + virge->memory_size = device_get_config_int("memory"); - svga_init(&virge->svga, virge, virge->memory_size << 20, - s3_virge_recalctimings, - s3_virge_in, s3_virge_out, - s3_virge_hwcursor_draw, - s3_virge_overlay_draw); + svga_init(&virge->svga, virge, virge->memory_size << 20, s3_virge_recalctimings, s3_virge_in, s3_virge_out, + s3_virge_hwcursor_draw, s3_virge_overlay_draw); - rom_init(&virge->bios_rom, "s3virge.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - if (PCI) - mem_mapping_disable(&virge->bios_rom.mapping); + rom_init(&virge->bios_rom, "s3virge.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + if (PCI) + mem_mapping_disable(&virge->bios_rom.mapping); - mem_mapping_add(&virge->mmio_mapping, 0, 0, s3_virge_mmio_read, - s3_virge_mmio_read_w, - s3_virge_mmio_read_l, - s3_virge_mmio_write, - s3_virge_mmio_write_w, - s3_virge_mmio_write_l, - NULL, - 0, - virge); - mem_mapping_add(&virge->new_mmio_mapping, 0, 0, s3_virge_mmio_read, - s3_virge_mmio_read_w, - s3_virge_mmio_read_l, - s3_virge_mmio_write, - s3_virge_mmio_write_w, - s3_virge_mmio_write_l, - NULL, - 0, - virge); - mem_mapping_add(&virge->linear_mapping, 0, 0, svga_read_linear, - svga_readw_linear, - svga_readl_linear, - svga_write_linear, - svga_writew_linear, - svga_writel_linear, - NULL, - 0, - &virge->svga); + mem_mapping_add(&virge->mmio_mapping, 0, 0, s3_virge_mmio_read, s3_virge_mmio_read_w, s3_virge_mmio_read_l, + s3_virge_mmio_write, s3_virge_mmio_write_w, s3_virge_mmio_write_l, NULL, 0, virge); + mem_mapping_add(&virge->new_mmio_mapping, 0, 0, s3_virge_mmio_read, s3_virge_mmio_read_w, s3_virge_mmio_read_l, + s3_virge_mmio_write, s3_virge_mmio_write_w, s3_virge_mmio_write_l, NULL, 0, virge); + mem_mapping_add(&virge->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, + svga_writew_linear, svga_writel_linear, NULL, 0, &virge->svga); - io_sethandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge); + io_sethandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge); - virge->pci_regs[4] = 3; - virge->pci_regs[5] = 0; - virge->pci_regs[6] = 0; - virge->pci_regs[7] = 2; - virge->pci_regs[0x32] = 0x0c; - virge->pci_regs[0x3d] = 1; - virge->pci_regs[0x3e] = 4; - virge->pci_regs[0x3f] = 0xff; + virge->pci_regs[4] = 3; + virge->pci_regs[5] = 0; + virge->pci_regs[6] = 0; + virge->pci_regs[7] = 2; + virge->pci_regs[0x32] = 0x0c; + virge->pci_regs[0x3d] = 1; + virge->pci_regs[0x3e] = 4; + virge->pci_regs[0x3f] = 0xff; - virge->virge_id_high = 0x56; - virge->virge_id_low = 0x31; - virge->virge_rev = 0; - virge->virge_id = 0xe1; + virge->virge_id_high = 0x56; + virge->virge_id_low = 0x31; + virge->virge_rev = 0; + virge->virge_id = 0xe1; - switch (virge->memory_size) { - case 2:virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (4 << 5); - break; - case 4: - default:virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (0 << 5); - break; - } + switch (virge->memory_size) { + case 2: + virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (4 << 5); + break; + case 4: + default: + virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (0 << 5); + break; + } - virge->svga.crtc[0x37] = 1;// | (7 << 5); - virge->svga.crtc[0x53] = 1 << 3; - virge->svga.crtc[0x59] = 0x70; + virge->svga.crtc[0x37] = 1; // | (7 << 5); + virge->svga.crtc[0x53] = 1 << 3; + virge->svga.crtc[0x59] = 0x70; - virge->is_375 = 0; + virge->is_375 = 0; - pci_add(s3_virge_pci_read, s3_virge_pci_write, virge); + pci_add(s3_virge_pci_read, s3_virge_pci_write, virge); - virge->wake_render_thread = thread_create_event(); - virge->wake_main_thread = thread_create_event(); - virge->not_full_event = thread_create_event(); - virge->render_thread = thread_create(render_thread, virge); + virge->wake_render_thread = thread_create_event(); + virge->wake_main_thread = thread_create_event(); + virge->not_full_event = thread_create_event(); + virge->render_thread = thread_create(render_thread, virge); - virge->wake_fifo_thread = thread_create_event(); - virge->fifo_not_full_event = thread_create_event(); - virge->fifo_thread = thread_create(fifo_thread, virge); + virge->wake_fifo_thread = thread_create_event(); + virge->fifo_not_full_event = thread_create_event(); + virge->fifo_thread = thread_create(fifo_thread, virge); - ddc_init(); + ddc_init(); - //TODO ViRGE does not use packed chain4 - virge->svga.packed_chain4 = 1; + // TODO ViRGE does not use packed chain4 + virge->svga.packed_chain4 = 1; - return virge; + return virge; } static void *s3_virge_375_init() { - virge_t *virge = malloc(sizeof(virge_t)); - memset(virge, 0, sizeof(virge_t)); + virge_t *virge = malloc(sizeof(virge_t)); + memset(virge, 0, sizeof(virge_t)); - virge->bilinear_enabled = device_get_config_int("bilinear"); - virge->dithering_enabled = device_get_config_int("dithering"); - virge->memory_size = device_get_config_int("memory"); + virge->bilinear_enabled = device_get_config_int("bilinear"); + virge->dithering_enabled = device_get_config_int("dithering"); + virge->memory_size = device_get_config_int("memory"); - svga_init(&virge->svga, virge, virge->memory_size << 20, - s3_virge_recalctimings, - s3_virge_in, s3_virge_out, - s3_virge_hwcursor_draw, - s3_virge_overlay_draw); - virge->svga.vblank_start = s3_virge_vblank_start; + svga_init(&virge->svga, virge, virge->memory_size << 20, s3_virge_recalctimings, s3_virge_in, s3_virge_out, + s3_virge_hwcursor_draw, s3_virge_overlay_draw); + virge->svga.vblank_start = s3_virge_vblank_start; - rom_init(&virge->bios_rom, "86c375_1.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - if (PCI) - mem_mapping_disable(&virge->bios_rom.mapping); + rom_init(&virge->bios_rom, "86c375_1.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + if (PCI) + mem_mapping_disable(&virge->bios_rom.mapping); - mem_mapping_add(&virge->mmio_mapping, 0, 0, s3_virge_mmio_read, - s3_virge_mmio_read_w, - s3_virge_mmio_read_l, - s3_virge_mmio_write, - s3_virge_mmio_write_w, - s3_virge_mmio_write_l, - NULL, - 0, - virge); - mem_mapping_add(&virge->new_mmio_mapping, 0, 0, s3_virge_mmio_read, - s3_virge_mmio_read_w, - s3_virge_mmio_read_l, - s3_virge_mmio_write, - s3_virge_mmio_write_w, - s3_virge_mmio_write_l, - NULL, - 0, - virge); - mem_mapping_add(&virge->linear_mapping, 0, 0, svga_read_linear, - svga_readw_linear, - svga_readl_linear, - svga_write_linear, - svga_writew_linear, - svga_writel_linear, - NULL, - 0, - &virge->svga); + mem_mapping_add(&virge->mmio_mapping, 0, 0, s3_virge_mmio_read, s3_virge_mmio_read_w, s3_virge_mmio_read_l, + s3_virge_mmio_write, s3_virge_mmio_write_w, s3_virge_mmio_write_l, NULL, 0, virge); + mem_mapping_add(&virge->new_mmio_mapping, 0, 0, s3_virge_mmio_read, s3_virge_mmio_read_w, s3_virge_mmio_read_l, + s3_virge_mmio_write, s3_virge_mmio_write_w, s3_virge_mmio_write_l, NULL, 0, virge); + mem_mapping_add(&virge->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, + svga_writew_linear, svga_writel_linear, NULL, 0, &virge->svga); - io_sethandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge); + io_sethandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge); - virge->pci_regs[4] = 3; - virge->pci_regs[5] = 0; - virge->pci_regs[6] = 0; - virge->pci_regs[7] = 2; - virge->pci_regs[0x32] = 0x0c; - virge->pci_regs[0x3d] = 1; - virge->pci_regs[0x3e] = 4; - virge->pci_regs[0x3f] = 0xff; + virge->pci_regs[4] = 3; + virge->pci_regs[5] = 0; + virge->pci_regs[6] = 0; + virge->pci_regs[7] = 2; + virge->pci_regs[0x32] = 0x0c; + virge->pci_regs[0x3d] = 1; + virge->pci_regs[0x3e] = 4; + virge->pci_regs[0x3f] = 0xff; - virge->virge_id_high = 0x8a; - virge->virge_id_low = 0x01; - virge->virge_rev = 0; - virge->virge_id = 0xe1; + virge->virge_id_high = 0x8a; + virge->virge_id_low = 0x01; + virge->virge_rev = 0; + virge->virge_id = 0xe1; - switch (virge->memory_size) { - case 2:virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (4 << 5); - break; - case 4: - default:virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (0 << 5); - break; - } -// virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4); - virge->svga.crtc[0x37] = 1;// | (7 << 5); - virge->svga.crtc[0x53] = 1 << 3; - virge->svga.crtc[0x59] = 0x70; + switch (virge->memory_size) { + case 2: + virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (4 << 5); + break; + case 4: + default: + virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (0 << 5); + break; + } + // virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4); + virge->svga.crtc[0x37] = 1; // | (7 << 5); + virge->svga.crtc[0x53] = 1 << 3; + virge->svga.crtc[0x59] = 0x70; - virge->svga.crtc[0x6c] = 0x01; + virge->svga.crtc[0x6c] = 0x01; - virge->is_375 = 1; + virge->is_375 = 1; - virge->card = pci_add(s3_virge_pci_read, s3_virge_pci_write, virge); + virge->card = pci_add(s3_virge_pci_read, s3_virge_pci_write, virge); - virge->wake_render_thread = thread_create_event(); - virge->wake_main_thread = thread_create_event(); - virge->not_full_event = thread_create_event(); - virge->render_thread = thread_create(render_thread, virge); + virge->wake_render_thread = thread_create_event(); + virge->wake_main_thread = thread_create_event(); + virge->not_full_event = thread_create_event(); + virge->render_thread = thread_create(render_thread, virge); - virge->wake_fifo_thread = thread_create_event(); - virge->fifo_not_full_event = thread_create_event(); - virge->fifo_thread = thread_create(fifo_thread, virge); + virge->wake_fifo_thread = thread_create_event(); + virge->fifo_not_full_event = thread_create_event(); + virge->fifo_thread = thread_create(fifo_thread, virge); - ddc_init(); + ddc_init(); - //TODO ViRGE does not use packed chain4 - virge->svga.packed_chain4 = 1; + // TODO ViRGE does not use packed chain4 + virge->svga.packed_chain4 = 1; - return virge; + return virge; } static void s3_virge_close(void *p) { - virge_t *virge = (virge_t *)p; + virge_t *virge = (virge_t *)p; #ifndef RELEASE_BUILD - FILE *f = fopen("vram.dmp", "wb"); - fwrite(virge->svga.vram, 4 << 20, 1, f); - fclose(f); + FILE *f = fopen("vram.dmp", "wb"); + fwrite(virge->svga.vram, 4 << 20, 1, f); + fclose(f); #endif - thread_kill(virge->render_thread); - thread_destroy_event(virge->not_full_event); - thread_destroy_event(virge->wake_main_thread); - thread_destroy_event(virge->wake_render_thread); + thread_kill(virge->render_thread); + thread_destroy_event(virge->not_full_event); + thread_destroy_event(virge->wake_main_thread); + thread_destroy_event(virge->wake_render_thread); - thread_kill(virge->fifo_thread); - thread_destroy_event(virge->wake_fifo_thread); - thread_destroy_event(virge->fifo_not_full_event); + thread_kill(virge->fifo_thread); + thread_destroy_event(virge->wake_fifo_thread); + thread_destroy_event(virge->fifo_not_full_event); - svga_close(&virge->svga); + svga_close(&virge->svga); - free(virge); + free(virge); } -static int s3_virge_available() { - return rom_present("s3virge.bin"); -} +static int s3_virge_available() { return rom_present("s3virge.bin"); } -static int s3_virge_375_available() { - return rom_present("86c375_1.bin"); -} +static int s3_virge_375_available() { return rom_present("86c375_1.bin"); } static void s3_virge_speed_changed(void *p) { - virge_t *virge = (virge_t *)p; + virge_t *virge = (virge_t *)p; - svga_recalctimings(&virge->svga); + svga_recalctimings(&virge->svga); } static void s3_virge_force_redraw(void *p) { - virge_t *virge = (virge_t *)p; + virge_t *virge = (virge_t *)p; - virge->svga.fullchange = changeframecount; + virge->svga.fullchange = changeframecount; } static void s3_virge_add_status_info(char *s, int max_len, void *p) { - virge_t *virge = (virge_t *)p; - char temps[256]; - uint64_t new_time = timer_read(); - uint64_t status_diff = new_time - status_time; - status_time = new_time; + virge_t *virge = (virge_t *)p; + char temps[256]; + uint64_t new_time = timer_read(); + uint64_t status_diff = new_time - status_time; + status_time = new_time; - if (!status_diff) - status_diff = 1; + if (!status_diff) + status_diff = 1; - svga_add_status_info(s, max_len, &virge->svga); - sprintf(temps, "%f Mpixels/sec\n%f ktris/sec\n%f%% CPU\n%f%% CPU (real)\n%d writes %i reads\n\n", - (double)virge->pixel_count / 1000000.0, - (double)virge->tri_count / 1000.0, ((double)virge_time * 100.0) / timer_freq, ((double)virge_time * 100.0) / status_diff, reg_writes, reg_reads); - strncat(s, temps, max_len); + svga_add_status_info(s, max_len, &virge->svga); + sprintf(temps, "%f Mpixels/sec\n%f ktris/sec\n%f%% CPU\n%f%% CPU (real)\n%d writes %i reads\n\n", + (double)virge->pixel_count / 1000000.0, (double)virge->tri_count / 1000.0, + ((double)virge_time * 100.0) / timer_freq, ((double)virge_time * 100.0) / status_diff, reg_writes, reg_reads); + strncat(s, temps, max_len); - virge->pixel_count = virge->tri_count = 0; - virge_time = 0; - reg_reads = 0; - reg_writes = 0; + virge->pixel_count = virge->tri_count = 0; + virge_time = 0; + reg_reads = 0; + reg_writes = 0; } -static device_config_t s3_virge_config[] = - { - { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "2 MB", - .value = 2 - }, - { - .description = "4 MB", - .value = 4 - }, - { - .description = "" - } - }, - .default_int = 4 - }, - { - .name = "bilinear", - .description = "Bilinear filtering", - .type = CONFIG_BINARY, - .default_int = 1 - }, - { - .name = "dithering", - .description = "Dithering", - .type = CONFIG_BINARY, - .default_int = 1 - }, - { - .type = -1 - } - }; +static device_config_t s3_virge_config[] = { + {.name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .selection = {{.description = "2 MB", .value = 2}, {.description = "4 MB", .value = 4}, {.description = ""}}, + .default_int = 4}, + {.name = "bilinear", .description = "Bilinear filtering", .type = CONFIG_BINARY, .default_int = 1}, + {.name = "dithering", .description = "Dithering", .type = CONFIG_BINARY, .default_int = 1}, + {.type = -1}}; -device_t s3_virge_device = - { - "Diamond Stealth 3D 2000 (S3 ViRGE)", - 0, - s3_virge_init, - s3_virge_close, - s3_virge_available, - s3_virge_speed_changed, - s3_virge_force_redraw, - s3_virge_add_status_info, - s3_virge_config - }; +device_t s3_virge_device = {"Diamond Stealth 3D 2000 (S3 ViRGE)", + 0, + s3_virge_init, + s3_virge_close, + s3_virge_available, + s3_virge_speed_changed, + s3_virge_force_redraw, + s3_virge_add_status_info, + s3_virge_config}; -device_t s3_virge_375_device = - { - "S3 ViRGE/DX", - 0, - s3_virge_375_init, - s3_virge_close, - s3_virge_375_available, - s3_virge_speed_changed, - s3_virge_force_redraw, - s3_virge_add_status_info, - s3_virge_config - }; +device_t s3_virge_375_device = {"S3 ViRGE/DX", 0, + s3_virge_375_init, s3_virge_close, + s3_virge_375_available, s3_virge_speed_changed, + s3_virge_force_redraw, s3_virge_add_status_info, + s3_virge_config}; diff --git a/src/video/vid_sdac_ramdac.c b/src/video/vid_sdac_ramdac.c index 278a914c..dcdd0a10 100644 --- a/src/video/vid_sdac_ramdac.c +++ b/src/video/vid_sdac_ramdac.c @@ -6,157 +6,180 @@ #include "vid_sdac_ramdac.h" static void sdac_control_write(sdac_ramdac_t *ramdac, svga_t *svga, uint8_t val) { - ramdac->command = val; -// pclog("RAMDAC command reg now %02X\n", val); - switch (val & 0xf0) { - case 0x00: - case 0x10:svga->bpp = 8; - break; + ramdac->command = val; + // pclog("RAMDAC command reg now %02X\n", val); + switch (val & 0xf0) { + case 0x00: + case 0x10: + svga->bpp = 8; + break; - case 0x20: - case 0x30: - case 0x80: - case 0xa0:svga->bpp = 15; - break; + case 0x20: + case 0x30: + case 0x80: + case 0xa0: + svga->bpp = 15; + break; - case 0x50: - case 0x60: - case 0xc0:svga->bpp = 16; - break; + case 0x50: + case 0x60: + case 0xc0: + svga->bpp = 16; + break; - case 0x40: - case 0x90: - case 0xe0:svga->bpp = 24; - break; + case 0x40: + case 0x90: + case 0xe0: + svga->bpp = 24; + break; - case 0x70:svga->bpp = 32; - break; + case 0x70: + svga->bpp = 32; + break; - default:svga->bpp = 8; - break; - } + default: + svga->bpp = 8; + break; + } } static void sdac_reg_write(sdac_ramdac_t *ramdac, int reg, uint8_t val) { - if ((reg >= 2 && reg <= 7) || (reg == 0xa) || (reg == 0xe)) { - if (!ramdac->reg_ff) - ramdac->regs[reg] = (ramdac->regs[reg] & 0xff00) | val; - else - ramdac->regs[reg] = (ramdac->regs[reg] & 0x00ff) | (val << 8); - } - ramdac->reg_ff = !ramdac->reg_ff; - if (!ramdac->reg_ff) - ramdac->windex++; + if ((reg >= 2 && reg <= 7) || (reg == 0xa) || (reg == 0xe)) { + if (!ramdac->reg_ff) + ramdac->regs[reg] = (ramdac->regs[reg] & 0xff00) | val; + else + ramdac->regs[reg] = (ramdac->regs[reg] & 0x00ff) | (val << 8); + } + ramdac->reg_ff = !ramdac->reg_ff; + if (!ramdac->reg_ff) + ramdac->windex++; } static uint8_t sdac_reg_read(sdac_ramdac_t *ramdac, int reg) { - uint8_t temp; + uint8_t temp; - if (!ramdac->reg_ff) - temp = ramdac->regs[reg] & 0xff; - else - temp = ramdac->regs[reg] >> 8; - ramdac->reg_ff = !ramdac->reg_ff; - if (!ramdac->reg_ff) - ramdac->rindex++; + if (!ramdac->reg_ff) + temp = ramdac->regs[reg] & 0xff; + else + temp = ramdac->regs[reg] >> 8; + ramdac->reg_ff = !ramdac->reg_ff; + if (!ramdac->reg_ff) + ramdac->rindex++; - return temp; + return temp; } void sdac_ramdac_out(uint16_t addr, uint8_t val, sdac_ramdac_t *ramdac, svga_t *svga) { -// /*if (CS!=0xC000) */pclog("OUT RAMDAC %04X %02X %i %04X:%04X %i %i %i\n",addr,val,ramdac->magic_count,CS,cpu_state.pc, ramdac->rs2, ramdac->rindex, ramdac->windex); - switch (addr) { - case 2: - if (ramdac->magic_count == 4) - sdac_control_write(ramdac, svga, val); - ramdac->magic_count = 0; - break; + // /*if (CS!=0xC000) */pclog("OUT RAMDAC %04X %02X %i %04X:%04X %i %i + // %i\n",addr,val,ramdac->magic_count,CS,cpu_state.pc, ramdac->rs2, ramdac->rindex, ramdac->windex); + switch (addr) { + case 2: + if (ramdac->magic_count == 4) + sdac_control_write(ramdac, svga, val); + ramdac->magic_count = 0; + break; - case 3:ramdac->magic_count = 0; - break; - case 0:ramdac->magic_count = 0; - break; - case 1:ramdac->magic_count = 0; - break; + case 3: + ramdac->magic_count = 0; + break; + case 0: + ramdac->magic_count = 0; + break; + case 1: + ramdac->magic_count = 0; + break; - case 4:ramdac->windex = val; - ramdac->reg_ff = 0; - break; - case 5:sdac_reg_write(ramdac, ramdac->windex & 0xff, val); - break; - case 6:sdac_control_write(ramdac, svga, val); - break; - case 7:ramdac->rindex = val; - ramdac->reg_ff = 0; - break; - } - if (!(addr & 4)) { - if (addr < 2) - svga_out(addr + 0x3c8, val, svga); - else - svga_out(addr + 0x3c4, val, svga); - } + case 4: + ramdac->windex = val; + ramdac->reg_ff = 0; + break; + case 5: + sdac_reg_write(ramdac, ramdac->windex & 0xff, val); + break; + case 6: + sdac_control_write(ramdac, svga, val); + break; + case 7: + ramdac->rindex = val; + ramdac->reg_ff = 0; + break; + } + if (!(addr & 4)) { + if (addr < 2) + svga_out(addr + 0x3c8, val, svga); + else + svga_out(addr + 0x3c4, val, svga); + } } uint8_t sdac_ramdac_in(uint16_t addr, sdac_ramdac_t *ramdac, svga_t *svga) { -// /*if (CS!=0xC000) */pclog("IN RAMDAC %04X %04X:%04X %i %i %i\n",addr,CS,cpu_state.pc, ramdac->rs2, ramdac->rindex, ramdac->windex); - switch (addr) { - case 2: - if (ramdac->magic_count < 5) - ramdac->magic_count++; - if (ramdac->magic_count == 4) { - ramdac->rs2 = 1; - return 0x70; /*SDAC ID*/ - } - if (ramdac->magic_count == 5) { - ramdac->magic_count = 0; - return ramdac->command; - } - break; - case 3:ramdac->magic_count = 0; - break; - case 0:ramdac->magic_count = 0; - break; - case 1:ramdac->magic_count = 0; - break; + // /*if (CS!=0xC000) */pclog("IN RAMDAC %04X %04X:%04X %i %i %i\n",addr,CS,cpu_state.pc, ramdac->rs2, + // ramdac->rindex, ramdac->windex); + switch (addr) { + case 2: + if (ramdac->magic_count < 5) + ramdac->magic_count++; + if (ramdac->magic_count == 4) { + ramdac->rs2 = 1; + return 0x70; /*SDAC ID*/ + } + if (ramdac->magic_count == 5) { + ramdac->magic_count = 0; + return ramdac->command; + } + break; + case 3: + ramdac->magic_count = 0; + break; + case 0: + ramdac->magic_count = 0; + break; + case 1: + ramdac->magic_count = 0; + break; - case 4:return ramdac->windex; - case 5:return sdac_reg_read(ramdac, ramdac->rindex & 0xff); - case 6:return ramdac->command; - case 7:return ramdac->rindex; - } - if (!(addr & 4)) { - if (addr < 2) - return svga_in(addr + 0x3c8, svga); - else - return svga_in(addr + 0x3c4, svga); - } - return 0xff; + case 4: + return ramdac->windex; + case 5: + return sdac_reg_read(ramdac, ramdac->rindex & 0xff); + case 6: + return ramdac->command; + case 7: + return ramdac->rindex; + } + if (!(addr & 4)) { + if (addr < 2) + return svga_in(addr + 0x3c8, svga); + else + return svga_in(addr + 0x3c4, svga); + } + return 0xff; } float sdac_getclock(int clock, void *p) { - sdac_ramdac_t *ramdac = (sdac_ramdac_t *)p; - float t; - int m, n1, n2; + sdac_ramdac_t *ramdac = (sdac_ramdac_t *)p; + float t; + int m, n1, n2; - if (ramdac->regs[0xe] & (1 << 5)) - clock = ramdac->regs[0xe] & 7; + if (ramdac->regs[0xe] & (1 << 5)) + clock = ramdac->regs[0xe] & 7; -// pclog("SDAC_Getclock %i %04X\n", clock, ramdac->regs[clock]); - clock &= 7; - if (clock == 0) - return 25175000.0; - if (clock == 1) - return 28322000.0; - m = (ramdac->regs[clock] & 0x7f) + 2; - n1 = ((ramdac->regs[clock] >> 8) & 0x1f) + 2; - n2 = ((ramdac->regs[clock] >> 13) & 0x07); - t = (14318184.0 * ((float)m / (float)n1)) / (float)(1 << n2); -// pclog("SDAC clock %i %i %i %f %04X %f %i\n", m, n1, n2, t, ramdac->regs[2], 14318184.0 * ((float)m / (float)n1), 1 << n2); - return t; + // pclog("SDAC_Getclock %i %04X\n", clock, ramdac->regs[clock]); + clock &= 7; + if (clock == 0) + return 25175000.0; + if (clock == 1) + return 28322000.0; + m = (ramdac->regs[clock] & 0x7f) + 2; + n1 = ((ramdac->regs[clock] >> 8) & 0x1f) + 2; + n2 = ((ramdac->regs[clock] >> 13) & 0x07); + t = (14318184.0 * ((float)m / (float)n1)) / (float)(1 << n2); + // pclog("SDAC clock %i %i %i %f %04X %f %i\n", m, n1, n2, t, ramdac->regs[2], 14318184.0 * ((float)m / + // (float)n1), 1 << n2); + return t; } void sdac_init(sdac_ramdac_t *ramdac) { - ramdac->regs[0] = 0x6128; - ramdac->regs[1] = 0x623d; + ramdac->regs[0] = 0x6128; + ramdac->regs[1] = 0x623d; } diff --git a/src/video/vid_sigma.c b/src/video/vid_sigma.c index 54dbe415..f1f6d810 100644 --- a/src/video/vid_sigma.c +++ b/src/video/vid_sigma.c @@ -9,33 +9,32 @@ #include "video.h" #include "vid_sigma.h" - /* The Sigma Designs Color 400 is a video card from 1985, presumably intended * as an EGA competitor. - * - * The hardware seems to have gone through various iterations; I've seen + * + * The hardware seems to have gone through various iterations; I've seen * pictures of full-length and half-length versions. - * TH99 describes the jumpers / switches: + * TH99 describes the jumpers / switches: * * - * The card is CGA-compatible at BIOS level, but to improve compatibility - * attempts to write to the CGA I/O ports at 0x3D0-0x3DF trigger an NMI. The + * The card is CGA-compatible at BIOS level, but to improve compatibility + * attempts to write to the CGA I/O ports at 0x3D0-0x3DF trigger an NMI. The * card's BIOS handles the NMI and translates the CGA writes into commands * to its own hardware at 0x2D0-0x2DF. (DIP switches on the card allow the * base address to be changed, but since the BIOS dump I have doesn't support * this I haven't emulated it. Likewise the BIOS ROM address can be changed, * but I'm going with the default of 0xC0000). * - * The BIOS still functions if the NMI system isn't operational. There + * The BIOS still functions if the NMI system isn't operational. There * doesn't seem to be a jumper or DIP switch to lock it out, but at startup * the BIOS tests for its presence and configures itself to work or not * as required. I've therefore added a configuration option to handle this. * - * The card's real CRTC at 0x2D0/0x2D1 appears to be a 6845. One oddity is - * that all its horizontal counts are halved compared to what a real CGA - * uses; 40-column modes have a width of 20, and 80-column modes have a + * The card's real CRTC at 0x2D0/0x2D1 appears to be a 6845. One oddity is + * that all its horizontal counts are halved compared to what a real CGA + * uses; 40-column modes have a width of 20, and 80-column modes have a * width of 40. This means that the CRTC cursor position (registers 14/15) can - * only address even-numbered columns, so the top bit of the control + * only address even-numbered columns, so the top bit of the control * register at 0x2D9 is used to adjust the position. * * Apart from the CRTC, registers are: @@ -48,40 +47,40 @@ * Graphics 320x200: 0x0F * Graphics 640x200: 0x1F * Graphics 640x400: 0x7F - * + * * I have assumed this is a bitmap with the following meaning: */ -#define MODE_80COLS 0x01 /* For text modes, 80 columns across */ -#define MODE_GRAPHICS 0x02 /* Graphics mode */ -#define MODE_NOBLINK 0x04 /* Disable blink? */ -#define MODE_ENABLE 0x08 /* Enable display */ -#define MODE_HRGFX 0x10 /* For graphics modes, 640 pixels across */ -#define MODE_640x400 0x40 /* 400-line graphics mode */ -#define MODE_FONT16 0x80 /* Use 16-pixel high font */ +#define MODE_80COLS 0x01 /* For text modes, 80 columns across */ +#define MODE_GRAPHICS 0x02 /* Graphics mode */ +#define MODE_NOBLINK 0x04 /* Disable blink? */ +#define MODE_ENABLE 0x08 /* Enable display */ +#define MODE_HRGFX 0x10 /* For graphics modes, 640 pixels across */ +#define MODE_640x400 0x40 /* 400-line graphics mode */ +#define MODE_FONT16 0x80 /* Use 16-pixel high font */ /* * 0x2D9: Control register, with the following bits: */ -#define CTL_CURSOR 0x80 /* Low bit of cursor position */ -#define CTL_NMI 0x20 /* Writes to 0x3D0-0x3DF trigger NMI */ -#define CTL_CLEAR_LPEN 0x08 /* Strobe 0 to clear lightpen latch */ -#define CTL_SET_LPEN 0x04 /* Strobe 0 to set lightpen latch */ -#define CTL_PALETTE 0x01 /* 0x2DE writes to palette (1) or plane (0) */ +#define CTL_CURSOR 0x80 /* Low bit of cursor position */ +#define CTL_NMI 0x20 /* Writes to 0x3D0-0x3DF trigger NMI */ +#define CTL_CLEAR_LPEN 0x08 /* Strobe 0 to clear lightpen latch */ +#define CTL_SET_LPEN 0x04 /* Strobe 0 to set lightpen latch */ +#define CTL_PALETTE 0x01 /* 0x2DE writes to palette (1) or plane (0) */ /* - * The card BIOS seems to support two variants of the hardware: One where + * The card BIOS seems to support two variants of the hardware: One where * bits 2 and 3 are normally 1 and are set to 0 to set/clear the latch, and * one where they are normally 0 and are set to 1. Behaviour is selected by * whether the byte at C000:17FFh is greater than 2Fh. * * 0x2DA: Status register. */ -#define STATUS_CURSOR 0x80 /* Last value written to bit 7 of 0x2D9 */ -#define STATUS_NMI 0x20 /* Last value written to bit 5 of 0x2D9 */ -#define STATUS_RETR_V 0x10 /* Vertical retrace */ -#define STATUS_LPEN_T 0x04 /* Lightpen switch is off */ -#define STATUS_LPEN_A 0x02 /* Edge from lightpen has set trigger */ -#define STATUS_RETR_H 0x01 /* Horizontal retrace */ +#define STATUS_CURSOR 0x80 /* Last value written to bit 7 of 0x2D9 */ +#define STATUS_NMI 0x20 /* Last value written to bit 5 of 0x2D9 */ +#define STATUS_RETR_V 0x10 /* Vertical retrace */ +#define STATUS_LPEN_T 0x04 /* Lightpen switch is off */ +#define STATUS_LPEN_A 0x02 /* Edge from lightpen has set trigger */ +#define STATUS_RETR_H 0x01 /* Horizontal retrace */ /* - * 0x2DB: On read: Byte written to the card that triggered NMI + * 0x2DB: On read: Byte written to the card that triggered NMI * 0x2DB: On write: Resets the 'card raised NMI' flag. - * 0x2DC: On read: Bit 7 set if the card raised NMI. If so, bits 0-3 + * 0x2DC: On read: Bit 7 set if the card raised NMI. If so, bits 0-3 * give the low 4 bits of the I/O port address. * 0x2DC: On write: Resets the NMI. * 0x2DD: Memory paging. The memory from 0xC1800 to 0xC1FFF can be either: @@ -96,410 +95,418 @@ * Writing port 2DD switches to RAM. * * 0x2DE: Meaning depends on bottom bit of value written to port 0x2D9. - * Bit 0 set: Write to palette. High 4 bits of value = register, + * Bit 0 set: Write to palette. High 4 bits of value = register, * low 4 bits = RGBI values (active low) * Bit 0 clear: Write to plane select. Low 2 bits of value select - * plane 0-3 + * plane 0-3 */ - typedef struct sigma_t { - mem_mapping_t mapping; - mem_mapping_t bios_ram; - rom_t bios_rom; + mem_mapping_t mapping; + mem_mapping_t bios_ram; + rom_t bios_rom; - uint8_t lastport; /* Last I/O port written */ - uint8_t lastwrite; /* Value written to that port */ - uint8_t sigma_ctl; /* Controls register: - * Bit 7 is low bit of cursor position - * Bit 5 set if writes to CGA ports trigger NMI - * Bit 3 clears lightpen latch - * Bit 2 sets lightpen latch - * Bit 1 controls meaning of port 2DE - */ - uint8_t enable_nmi; /* Enable the NMI mechanism for CGA emulation?*/ - uint8_t rom_paged; /* Is ROM paged in at 0xC1800? */ + uint8_t lastport; /* Last I/O port written */ + uint8_t lastwrite; /* Value written to that port */ + uint8_t sigma_ctl; /* Controls register: + * Bit 7 is low bit of cursor position + * Bit 5 set if writes to CGA ports trigger NMI + * Bit 3 clears lightpen latch + * Bit 2 sets lightpen latch + * Bit 1 controls meaning of port 2DE + */ + uint8_t enable_nmi; /* Enable the NMI mechanism for CGA emulation?*/ + uint8_t rom_paged; /* Is ROM paged in at 0xC1800? */ - uint8_t crtc_value; /* Value to return from a CRTC register read */ + uint8_t crtc_value; /* Value to return from a CRTC register read */ - int crtcreg; /* CRTC: Real selected register */ - uint8_t crtc[32]; /* CRTC: Real values */ + int crtcreg; /* CRTC: Real selected register */ + uint8_t crtc[32]; /* CRTC: Real values */ - uint8_t sigmastat; /* Status register [0x2DA] */ + uint8_t sigmastat; /* Status register [0x2DA] */ - uint8_t sigmamode; /* Mode control register [0x2D8] */ + uint8_t sigmamode; /* Mode control register [0x2D8] */ - int linepos, displine; - int sc, vc; - int cgadispon; - int con, coff, cursoron, cgablink; - int vsynctime, vadj; - uint16_t ma, maback; - int oddeven; + int linepos, displine; + int sc, vc; + int cgadispon; + int con, coff, cursoron, cgablink; + int vsynctime, vadj; + uint16_t ma, maback; + int oddeven; - uint64_t dispontime, dispofftime; - pc_timer_t timer; + uint64_t dispontime, dispofftime; + pc_timer_t timer; - int firstline, lastline; + int firstline, lastline; - int drawcursor; + int drawcursor; - uint8_t *vram; - uint8_t bram[2048]; + uint8_t *vram; + uint8_t bram[2048]; - uint8_t palette[16]; + uint8_t palette[16]; - int plane; - int revision; + int plane; + int revision; } sigma_t; #define COMPOSITE_OLD 0 #define COMPOSITE_NEW 1 -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[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}; void sigma_recalctimings(sigma_t *cga); void sigma_out(uint16_t addr, uint8_t val, void *p) { - sigma_t *sigma = (sigma_t *)p; - uint8_t old; + sigma_t *sigma = (sigma_t *)p; + uint8_t old; -// pclog("SIGMA_OUT %04X %02X\n", addr, val); + // pclog("SIGMA_OUT %04X %02X\n", addr, val); -// if (addr == 0x3D8 && (val & 0x80)) output = 3; + // if (addr == 0x3D8 && (val & 0x80)) output = 3; - if (addr >= 0x3D0 && addr < 0x3E0) { - sigma->lastport = addr & 0x0F; - sigma->lastwrite = val; - /* If set to NMI on video I/O... */ - if (sigma->enable_nmi && (sigma->sigma_ctl & CTL_NMI)) { - sigma->lastport |= 0x80; /* Card raised NMI */ - nmi = 1; -// pclog("Sigma: Raise NMI\n"); - } - /* For CRTC emulation, the card BIOS sets the value to be - * read from port 0x3D1 like this */ - if (addr == 0x3D1) - sigma->crtc_value = val; - } else - switch (addr) { - case 0x2D0: - case 0x2D2: - case 0x2D4: - case 0x2D6:sigma->crtcreg = val & 31; - return; + if (addr >= 0x3D0 && addr < 0x3E0) { + sigma->lastport = addr & 0x0F; + sigma->lastwrite = val; + /* If set to NMI on video I/O... */ + if (sigma->enable_nmi && (sigma->sigma_ctl & CTL_NMI)) { + sigma->lastport |= 0x80; /* Card raised NMI */ + nmi = 1; + // pclog("Sigma: Raise NMI\n"); + } + /* For CRTC emulation, the card BIOS sets the value to be + * read from port 0x3D1 like this */ + if (addr == 0x3D1) + sigma->crtc_value = val; + } else + switch (addr) { + case 0x2D0: + case 0x2D2: + case 0x2D4: + case 0x2D6: + sigma->crtcreg = val & 31; + return; - case 0x2D1: - case 0x2D3: - case 0x2D5: - case 0x2D7:old = sigma->crtc[sigma->crtcreg]; - sigma->crtc[sigma->crtcreg] = val & crtcmask[sigma->crtcreg]; -// pclog("Sigma: CRTC[0x%02x] := 0x%02x\n", -// sigma->crtcreg, val); - if (old != val) { - if (sigma->crtcreg < 0xe || sigma->crtcreg > 0x10) { - fullchange = changeframecount; - sigma_recalctimings(sigma); - } - } - return; + case 0x2D1: + case 0x2D3: + case 0x2D5: + case 0x2D7: + old = sigma->crtc[sigma->crtcreg]; + sigma->crtc[sigma->crtcreg] = val & crtcmask[sigma->crtcreg]; + // pclog("Sigma: CRTC[0x%02x] := 0x%02x\n", + // sigma->crtcreg, val); + if (old != val) { + if (sigma->crtcreg < 0xe || sigma->crtcreg > 0x10) { + fullchange = changeframecount; + sigma_recalctimings(sigma); + } + } + return; - case 0x2D8: -// pclog("Sigma mode := %02x\n", val); - sigma->sigmamode = val; - return; - case 0x2D9: -// pclog("Sigma control := %02x\n", val); - sigma->sigma_ctl = val; - return; - case 0x2DB:sigma->lastport &= 0x7F; - return; - case 0x2DC: /* Reset NMI */ - nmi = 0; - sigma->lastport &= 0x7F; -// pclog("Sigma: Reset NMI\n"); - return; - case 0x2DD: /* Page in RAM at 0xC1800 */ - if (sigma->rom_paged != 0) - mmu_invalidate(0xC0000); - sigma->rom_paged = 0; -// pclog("Sigma: page RAM at C1800\n"); - return; + case 0x2D8: + // pclog("Sigma mode := %02x\n", val); + sigma->sigmamode = val; + return; + case 0x2D9: + // pclog("Sigma control := %02x\n", val); + sigma->sigma_ctl = val; + return; + case 0x2DB: + sigma->lastport &= 0x7F; + return; + case 0x2DC: /* Reset NMI */ + nmi = 0; + sigma->lastport &= 0x7F; + // pclog("Sigma: Reset NMI\n"); + return; + case 0x2DD: /* Page in RAM at 0xC1800 */ + if (sigma->rom_paged != 0) + mmu_invalidate(0xC0000); + sigma->rom_paged = 0; + // pclog("Sigma: page RAM at C1800\n"); + return; - case 0x2DE: - if (sigma->sigma_ctl & CTL_PALETTE) { -// pclog("Sigma: Write palette %x := %x\n", -// val >> 4, val & 0x0F); - sigma->palette[val >> 4] = (val & 0x0F) ^ 0x0F; - } else { -// pclog("Sigma: Set plane to %d\n", val & 3); - sigma->plane = val & 3; - } - return; - } + case 0x2DE: + if (sigma->sigma_ctl & CTL_PALETTE) { + // pclog("Sigma: Write palette %x := %x\n", + // val >> 4, val & 0x0F); + sigma->palette[val >> 4] = (val & 0x0F) ^ 0x0F; + } else { + // pclog("Sigma: Set plane to %d\n", val & 3); + sigma->plane = val & 3; + } + return; + } } uint8_t sigma_in(uint16_t addr, void *p) { - uint8_t result = 0xFF; - sigma_t *sigma = (sigma_t *)p; + uint8_t result = 0xFF; + sigma_t *sigma = (sigma_t *)p; - switch (addr) { - case 0x2D0: - case 0x2D2: - case 0x2D4: - case 0x2D6:result = sigma->crtcreg; - break; + switch (addr) { + case 0x2D0: + case 0x2D2: + case 0x2D4: + case 0x2D6: + result = sigma->crtcreg; + break; - case 0x2D1: - case 0x2D3: - case 0x2D5: - case 0x2D7:result = sigma->crtc[sigma->crtcreg & 0x1F]; - break; + case 0x2D1: + case 0x2D3: + case 0x2D5: + case 0x2D7: + result = sigma->crtc[sigma->crtcreg & 0x1F]; + break; - case 0x2DA: - result = (sigma->sigma_ctl & 0xE0) | - (sigma->sigmastat & 0x1F); - break; + case 0x2DA: + result = (sigma->sigma_ctl & 0xE0) | (sigma->sigmastat & 0x1F); + break; - case 0x2DB:result = sigma->lastwrite; /* Value that triggered NMI */ - break; - case 0x2DC:result = sigma->lastport; /* Port that triggered NMI */ - break; - case 0x2DD: /* Page in ROM at 0xC1800 */ -// pclog("Sigma: page ROM at C1800\n"); - result = (sigma->rom_paged ? 0x80 : 0); - if (sigma->rom_paged != 0x80) - mmu_invalidate(0xC0000); - sigma->rom_paged = 0x80; - break; + case 0x2DB: + result = sigma->lastwrite; /* Value that triggered NMI */ + break; + case 0x2DC: + result = sigma->lastport; /* Port that triggered NMI */ + break; + case 0x2DD: /* Page in ROM at 0xC1800 */ + // pclog("Sigma: page ROM at C1800\n"); + result = (sigma->rom_paged ? 0x80 : 0); + if (sigma->rom_paged != 0x80) + mmu_invalidate(0xC0000); + sigma->rom_paged = 0x80; + break; - case 0x3D1: - case 0x3D3: - case 0x3D5: - case 0x3D7:result = sigma->crtc_value; - break; + case 0x3D1: + case 0x3D3: + case 0x3D5: + case 0x3D7: + result = sigma->crtc_value; + break; -/* For CGA compatibility we have to return something palatable on this port. - * On a real card this functionality can be turned on or off with SW1/6 */ - case 0x3DA:result = sigma->sigmastat & 7; - if (sigma->sigmastat & STATUS_RETR_V) - result |= 8; - break; - } -// pclog("SIGMA_IN %04X = %02x\n", addr, result); - return result; + /* For CGA compatibility we have to return something palatable on this port. + * On a real card this functionality can be turned on or off with SW1/6 */ + case 0x3DA: + result = sigma->sigmastat & 7; + if (sigma->sigmastat & STATUS_RETR_V) + result |= 8; + break; + } + // pclog("SIGMA_IN %04X = %02x\n", addr, result); + return result; } void sigma_write(uint32_t addr, uint8_t val, void *p) { - sigma_t *sigma = (sigma_t *)p; + sigma_t *sigma = (sigma_t *)p; -// pclog("CGA_WRITE %04X %02X\n", addr, val); - sigma->vram[sigma->plane * 0x8000 + (addr & 0x7fff)] = val; - egawrites++; - cycles -= 4; + // pclog("CGA_WRITE %04X %02X\n", addr, val); + sigma->vram[sigma->plane * 0x8000 + (addr & 0x7fff)] = val; + egawrites++; + cycles -= 4; } uint8_t sigma_read(uint32_t addr, void *p) { - sigma_t *sigma = (sigma_t *)p; + sigma_t *sigma = (sigma_t *)p; - cycles -= 4; - egareads++; -// pclog("CGA_READ %04X\n", addr); - return sigma->vram[sigma->plane * 0x8000 + (addr & 0x7fff)]; + cycles -= 4; + egareads++; + // pclog("CGA_READ %04X\n", addr); + return sigma->vram[sigma->plane * 0x8000 + (addr & 0x7fff)]; } void sigma_bwrite(uint32_t addr, uint8_t val, void *p) { - sigma_t *sigma = (sigma_t *)p; + sigma_t *sigma = (sigma_t *)p; - addr &= 0x3FFF; - if (addr < 0x1800 || sigma->rom_paged || addr >= 0x2000) { -// pclog("sigma_bwrite(0x%05x) := [ROM] %02x\n", addr, val); - } else { -// pclog("sigma_bwrite(0x%05x) := [RAM] %02x\n", addr, val); - sigma->bram[addr & 0x7FF] = val; - } + addr &= 0x3FFF; + if (addr < 0x1800 || sigma->rom_paged || addr >= 0x2000) { + // pclog("sigma_bwrite(0x%05x) := [ROM] %02x\n", addr, val); + } else { + // pclog("sigma_bwrite(0x%05x) := [RAM] %02x\n", addr, val); + sigma->bram[addr & 0x7FF] = val; + } } uint8_t sigma_bread(uint32_t addr, void *p) { - sigma_t *sigma = (sigma_t *)p; - uint8_t result; + sigma_t *sigma = (sigma_t *)p; + uint8_t result; - addr &= 0x3FFF; - if (addr >= 0x2000) { -// if (output == 3) pclog("sigma_bread(0x%05x) = [NIL] %02x\n", -// addr, 0xFF); - return 0xFF; - } - if (addr < 0x1800 || sigma->rom_paged) { - result = sigma->bios_rom.rom[addr & 0x1FFF]; -// if (output == 3) pclog("sigma_bread(0x%05x) = [ROM] %02x\n", addr, result); - } else { - result = sigma->bram[addr & 0x7FF]; -// if (output == 3) pclog("sigma_bread(0x%05x) = [RAM] %02x\n", addr, result); - } - return result; + addr &= 0x3FFF; + if (addr >= 0x2000) { + // if (output == 3) pclog("sigma_bread(0x%05x) = [NIL] %02x\n", + // addr, 0xFF); + return 0xFF; + } + if (addr < 0x1800 || sigma->rom_paged) { + result = sigma->bios_rom.rom[addr & 0x1FFF]; + // if (output == 3) pclog("sigma_bread(0x%05x) = [ROM] %02x\n", addr, result); + } else { + result = sigma->bram[addr & 0x7FF]; + // if (output == 3) pclog("sigma_bread(0x%05x) = [RAM] %02x\n", addr, result); + } + return result; } void sigma_recalctimings(sigma_t *sigma) { - double disptime; - double _dispontime, _dispofftime; -// pclog("Sigma_recalctimings - total=%i displayed=%i hi-res=%i\n", -// sigma->crtc[0], sigma->crtc[1], sigma->sigmamode & MODE_80COLS); - if (sigma->sigmamode & MODE_80COLS) { - disptime = (sigma->crtc[0] + 1) << 1; - _dispontime = (sigma->crtc[1]) << 1; - } else { - disptime = (sigma->crtc[0] + 1) << 2; - _dispontime = sigma->crtc[1] << 2; - } - _dispofftime = disptime - _dispontime; -// printf("%i %f %f %f %i %i\n",cgamode&1,disptime,dispontime,dispofftime,crtc[0],crtc[1]); - _dispontime *= CGACONST; - _dispofftime *= CGACONST; -// printf("Timings - on %f off %f frame %f second %f\n",dispontime,dispofftime,(dispontime+dispofftime)*262.0,(dispontime+dispofftime)*262.0*59.92); - sigma->dispontime = (uint64_t)_dispontime; - sigma->dispofftime = (uint64_t)_dispofftime; + double disptime; + double _dispontime, _dispofftime; + // pclog("Sigma_recalctimings - total=%i displayed=%i hi-res=%i\n", + // sigma->crtc[0], sigma->crtc[1], sigma->sigmamode & MODE_80COLS); + if (sigma->sigmamode & MODE_80COLS) { + disptime = (sigma->crtc[0] + 1) << 1; + _dispontime = (sigma->crtc[1]) << 1; + } else { + disptime = (sigma->crtc[0] + 1) << 2; + _dispontime = sigma->crtc[1] << 2; + } + _dispofftime = disptime - _dispontime; + // printf("%i %f %f %f %i %i\n",cgamode&1,disptime,dispontime,dispofftime,crtc[0],crtc[1]); + _dispontime *= CGACONST; + _dispofftime *= CGACONST; + // printf("Timings - on %f off %f frame %f second + // %f\n",dispontime,dispofftime,(dispontime+dispofftime)*262.0,(dispontime+dispofftime)*262.0*59.92); + sigma->dispontime = (uint64_t)_dispontime; + sigma->dispofftime = (uint64_t)_dispofftime; } /* Render a line in 80-column text mode */ void sigma_text80(sigma_t *sigma) { - int x, c; - uint8_t chr, attr; - uint16_t ca = (sigma->crtc[15] | (sigma->crtc[14] << 8)); - uint16_t ma = ((sigma->ma & 0x3FFF) << 1); - int drawcursor; - uint32_t cols[4]; - uint8_t *vram = sigma->vram + (ma << 1); + int x, c; + uint8_t chr, attr; + uint16_t ca = (sigma->crtc[15] | (sigma->crtc[14] << 8)); + uint16_t ma = ((sigma->ma & 0x3FFF) << 1); + int drawcursor; + uint32_t cols[4]; + uint8_t *vram = sigma->vram + (ma << 1); - ca = ca << 1; - if (sigma->sigma_ctl & CTL_CURSOR) - ++ca; - ca &= 0x3fff; -// pclog("sigma_text80: displine=%d sc=%d Width=%d\n", -// sigma->displine, sigma->sc, sigma->crtc[1]); + ca = ca << 1; + if (sigma->sigma_ctl & CTL_CURSOR) + ++ca; + ca &= 0x3fff; + // pclog("sigma_text80: displine=%d sc=%d Width=%d\n", + // sigma->displine, sigma->sc, sigma->crtc[1]); - /* The Sigma 400 seems to use screen widths stated in words - * (40 for 80-column, 20 for 40-column) */ - for (x = 0; x < (sigma->crtc[1] << 1); x++) { - chr = vram[x << 1]; - attr = vram[(x << 1) + 1]; - drawcursor = ((ma == ca) && sigma->con && sigma->cursoron); + /* The Sigma 400 seems to use screen widths stated in words + * (40 for 80-column, 20 for 40-column) */ + for (x = 0; x < (sigma->crtc[1] << 1); x++) { + chr = vram[x << 1]; + attr = vram[(x << 1) + 1]; + drawcursor = ((ma == ca) && sigma->con && sigma->cursoron); - if (!(sigma->sigmamode & MODE_NOBLINK)) { - cols[1] = attr & 15; - cols[0] = (attr >> 4) & 7; - if ((sigma->cgablink & 8) && (attr & 0x80) && !sigma->drawcursor) - cols[1] = cols[0]; - } else /* No blink */ - { - cols[1] = attr & 15; - cols[0] = attr >> 4; - } -// if (chr != ' ') -// { -// pclog("[%x:%x]%c", cols[1], cols[0], chr); -// } - if (drawcursor) { - for (c = 0; c < 8; c++) { - if (sigma->sigmamode & MODE_FONT16) - ((uint32_t *)buffer32->line[sigma->displine])[(x << 3) + c + 8] = cols[(fontdatm[chr][sigma->sc & 15] & (1 << (c ^ 7))) ? 1 : 0] ^ 0xffffff; - else - ((uint32_t *)buffer32->line[sigma->displine])[(x << 3) + c + 8] = cols[(fontdat[chr][sigma->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 0xffffff; - } - } else { - for (c = 0; c < 8; c++) { - if (sigma->sigmamode & MODE_FONT16) - ((uint32_t *)buffer32->line[sigma->displine])[(x << 3) + c + 8] = cols[(fontdatm[chr][sigma->sc & 15] & (1 << (c ^ 7))) ? 1 : 0]; - else - ((uint32_t *)buffer32->line[sigma->displine])[(x << 3) + c + 8] = cols[(fontdat[chr][sigma->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; - } - } - ++ma; - } - sigma->ma += sigma->crtc[1]; - //pclog("\n"); + if (!(sigma->sigmamode & MODE_NOBLINK)) { + cols[1] = attr & 15; + cols[0] = (attr >> 4) & 7; + if ((sigma->cgablink & 8) && (attr & 0x80) && !sigma->drawcursor) + cols[1] = cols[0]; + } else /* No blink */ + { + cols[1] = attr & 15; + cols[0] = attr >> 4; + } + // if (chr != ' ') + // { + // pclog("[%x:%x]%c", cols[1], cols[0], chr); + // } + if (drawcursor) { + for (c = 0; c < 8; c++) { + if (sigma->sigmamode & MODE_FONT16) + ((uint32_t *)buffer32->line[sigma->displine])[(x << 3) + c + 8] = + cols[(fontdatm[chr][sigma->sc & 15] & (1 << (c ^ 7))) ? 1 : 0] ^ 0xffffff; + else + ((uint32_t *)buffer32->line[sigma->displine])[(x << 3) + c + 8] = + cols[(fontdat[chr][sigma->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 0xffffff; + } + } else { + for (c = 0; c < 8; c++) { + if (sigma->sigmamode & MODE_FONT16) + ((uint32_t *)buffer32->line[sigma->displine])[(x << 3) + c + 8] = + cols[(fontdatm[chr][sigma->sc & 15] & (1 << (c ^ 7))) ? 1 : 0]; + else + ((uint32_t *)buffer32->line[sigma->displine])[(x << 3) + c + 8] = + cols[(fontdat[chr][sigma->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; + } + } + ++ma; + } + sigma->ma += sigma->crtc[1]; + // pclog("\n"); } /* Render a line in 40-column text mode */ void sigma_text40(sigma_t *sigma) { - int x, c; - uint8_t chr, attr; - uint16_t ca = (sigma->crtc[15] | (sigma->crtc[14] << 8)); - uint16_t ma = ((sigma->ma & 0x3FFF) << 1); - int drawcursor; - uint32_t cols[4]; - uint8_t *vram = sigma->vram + ((ma << 1) & 0x3FFF); + int x, c; + uint8_t chr, attr; + uint16_t ca = (sigma->crtc[15] | (sigma->crtc[14] << 8)); + uint16_t ma = ((sigma->ma & 0x3FFF) << 1); + int drawcursor; + uint32_t cols[4]; + uint8_t *vram = sigma->vram + ((ma << 1) & 0x3FFF); - ca = ca << 1; - if (sigma->sigma_ctl & CTL_CURSOR) - ++ca; - ca &= 0x3fff; - /* The Sigma 400 seems to use screen widths stated in words - * (40 for 80-column, 20 for 40-column) */ - for (x = 0; x < (sigma->crtc[1] << 1); x++) { - chr = vram[x << 1]; - attr = vram[(x << 1) + 1]; - drawcursor = ((ma == ca) && sigma->con && sigma->cursoron); + ca = ca << 1; + if (sigma->sigma_ctl & CTL_CURSOR) + ++ca; + ca &= 0x3fff; + /* The Sigma 400 seems to use screen widths stated in words + * (40 for 80-column, 20 for 40-column) */ + for (x = 0; x < (sigma->crtc[1] << 1); x++) { + chr = vram[x << 1]; + attr = vram[(x << 1) + 1]; + drawcursor = ((ma == ca) && sigma->con && sigma->cursoron); - if (!(sigma->sigmamode & MODE_NOBLINK)) { - cols[1] = attr & 15; - cols[0] = (attr >> 4) & 7; - if ((sigma->cgablink & 8) && (attr & 0x80) && !sigma->drawcursor) - cols[1] = cols[0]; - } else /* No blink */ - { - cols[1] = attr & 15; - cols[0] = attr >> 4; - } -// if (chr != ' ') -// { -// pclog("[%x:%x]%c", cols[1], cols[0], chr); -// } - if (drawcursor) { - for (c = 0; c < 8; c++) { - ((uint32_t *)buffer32->line[sigma->displine])[(x << 4) + 2 * c + 8] = - ((uint32_t *)buffer32->line[sigma->displine])[(x << 4) + 2 * c + 9] = cols[(fontdatm[chr][sigma->sc & 15] & (1 << (c ^ 7))) ? 1 : 0] ^ 0xffffff; - } - } else { - for (c = 0; c < 8; c++) { - ((uint32_t *)buffer32->line[sigma->displine])[(x << 4) + 2 * c + 8] = - ((uint32_t *)buffer32->line[sigma->displine])[(x << 4) + 2 * c + 9] = cols[(fontdatm[chr][sigma->sc & 15] & (1 << (c ^ 7))) ? 1 : 0]; - } - } - ma++; - } - sigma->ma += sigma->crtc[1]; - //pclog("\n"); + if (!(sigma->sigmamode & MODE_NOBLINK)) { + cols[1] = attr & 15; + cols[0] = (attr >> 4) & 7; + if ((sigma->cgablink & 8) && (attr & 0x80) && !sigma->drawcursor) + cols[1] = cols[0]; + } else /* No blink */ + { + cols[1] = attr & 15; + cols[0] = attr >> 4; + } + // if (chr != ' ') + // { + // pclog("[%x:%x]%c", cols[1], cols[0], chr); + // } + if (drawcursor) { + for (c = 0; c < 8; c++) { + ((uint32_t *)buffer32->line[sigma->displine])[(x << 4) + 2 * c + 8] = + ((uint32_t *)buffer32->line[sigma->displine])[(x << 4) + 2 * c + 9] = + cols[(fontdatm[chr][sigma->sc & 15] & (1 << (c ^ 7))) ? 1 : 0] ^ 0xffffff; + } + } else { + for (c = 0; c < 8; c++) { + ((uint32_t *)buffer32->line[sigma->displine])[(x << 4) + 2 * c + 8] = + ((uint32_t *)buffer32->line[sigma->displine])[(x << 4) + 2 * c + 9] = + cols[(fontdatm[chr][sigma->sc & 15] & (1 << (c ^ 7))) ? 1 : 0]; + } + } + ma++; + } + sigma->ma += sigma->crtc[1]; + // pclog("\n"); } /* Draw a line in the 640x400 graphics mode */ void sigma_gfx400(sigma_t *sigma) { - int x; - unsigned char *vram = &sigma->vram[((sigma->ma << 1) & 0x1FFF) - + (sigma->sc & 3) * 0x2000]; - uint8_t plane[4]; - uint8_t mask, col, c; + int x; + unsigned char *vram = &sigma->vram[((sigma->ma << 1) & 0x1FFF) + (sigma->sc & 3) * 0x2000]; + uint8_t plane[4]; + uint8_t mask, col, c; - for (x = 0; x < (sigma->crtc[1] << 1); x++) { - plane[0] = vram[x]; - plane[1] = vram[0x8000 + x]; - plane[2] = vram[0x10000 + x]; - plane[3] = vram[0x18000 + x]; + for (x = 0; x < (sigma->crtc[1] << 1); x++) { + plane[0] = vram[x]; + plane[1] = vram[0x8000 + x]; + plane[2] = vram[0x10000 + x]; + plane[3] = vram[0x18000 + x]; - for (c = 0, mask = 0x80; c < 8; c++, mask >>= 1) { - col = ((plane[3] & mask) ? 8 : 0) | - ((plane[2] & mask) ? 4 : 0) | - ((plane[1] & mask) ? 2 : 0) | - ((plane[0] & mask) ? 1 : 0); - ((uint32_t *)buffer32->line[sigma->displine])[(x << 3) + c + 8] = col; - } - if (x & 1) - ++sigma->ma; - } + for (c = 0, mask = 0x80; c < 8; c++, mask >>= 1) { + col = ((plane[3] & mask) ? 8 : 0) | ((plane[2] & mask) ? 4 : 0) | ((plane[1] & mask) ? 2 : 0) | + ((plane[0] & mask) ? 1 : 0); + ((uint32_t *)buffer32->line[sigma->displine])[(x << 3) + c + 8] = col; + } + if (x & 1) + ++sigma->ma; + } } /* Draw a line in the 640x200 graphics mode. @@ -508,359 +515,303 @@ void sigma_gfx400(sigma_t *sigma) { * in plane 2 come out in white, others black; but by programming the palette * and plane registers manually you can get the full resolution. */ void sigma_gfx200(sigma_t *sigma) { - int x; - unsigned char *vram = &sigma->vram[((sigma->ma << 1) & 0x1FFF) - + (sigma->sc & 2) * 0x1000]; - uint8_t plane[4]; - uint8_t mask, col, c; + int x; + unsigned char *vram = &sigma->vram[((sigma->ma << 1) & 0x1FFF) + (sigma->sc & 2) * 0x1000]; + uint8_t plane[4]; + uint8_t mask, col, c; - for (x = 0; x < (sigma->crtc[1] << 1); x++) { - plane[0] = vram[x]; - plane[1] = vram[0x8000 + x]; - plane[2] = vram[0x10000 + x]; - plane[3] = vram[0x18000 + x]; + for (x = 0; x < (sigma->crtc[1] << 1); x++) { + plane[0] = vram[x]; + plane[1] = vram[0x8000 + x]; + plane[2] = vram[0x10000 + x]; + plane[3] = vram[0x18000 + x]; - for (c = 0, mask = 0x80; c < 8; c++, mask >>= 1) { - col = ((plane[3] & mask) ? 8 : 0) | - ((plane[2] & mask) ? 4 : 0) | - ((plane[1] & mask) ? 2 : 0) | - ((plane[0] & mask) ? 1 : 0); - ((uint32_t *)buffer32->line[sigma->displine])[(x << 3) + c + 8] = col; - } - if (x & 1) - ++sigma->ma; - } + for (c = 0, mask = 0x80; c < 8; c++, mask >>= 1) { + col = ((plane[3] & mask) ? 8 : 0) | ((plane[2] & mask) ? 4 : 0) | ((plane[1] & mask) ? 2 : 0) | + ((plane[0] & mask) ? 1 : 0); + ((uint32_t *)buffer32->line[sigma->displine])[(x << 3) + c + 8] = col; + } + if (x & 1) + ++sigma->ma; + } } /* Draw a line in the 320x200 graphics mode */ void sigma_gfx4col(sigma_t *sigma) { - int x; - unsigned char *vram = &sigma->vram[((sigma->ma << 1) & 0x1FFF) - + (sigma->sc & 2) * 0x1000]; - uint8_t plane[4]; - uint8_t mask, col, c; + int x; + unsigned char *vram = &sigma->vram[((sigma->ma << 1) & 0x1FFF) + (sigma->sc & 2) * 0x1000]; + uint8_t plane[4]; + uint8_t mask, col, c; - for (x = 0; x < (sigma->crtc[1] << 1); x++) { - plane[0] = vram[x]; - plane[1] = vram[0x8000 + x]; - plane[2] = vram[0x10000 + x]; - plane[3] = vram[0x18000 + x]; + for (x = 0; x < (sigma->crtc[1] << 1); x++) { + plane[0] = vram[x]; + plane[1] = vram[0x8000 + x]; + plane[2] = vram[0x10000 + x]; + plane[3] = vram[0x18000 + x]; - mask = 0x80; - for (c = 0; c < 4; c++) { - col = ((plane[3] & mask) ? 2 : 0) | - ((plane[2] & mask) ? 1 : 0); - mask = mask >> 1; - col |= ((plane[3] & mask) ? 8 : 0) | - ((plane[2] & mask) ? 4 : 0); - mask = mask >> 1; + mask = 0x80; + for (c = 0; c < 4; c++) { + col = ((plane[3] & mask) ? 2 : 0) | ((plane[2] & mask) ? 1 : 0); + mask = mask >> 1; + col |= ((plane[3] & mask) ? 8 : 0) | ((plane[2] & mask) ? 4 : 0); + mask = mask >> 1; - ((uint32_t *)buffer32->line[sigma->displine])[(x << 3) + (c << 1) + 8] = - ((uint32_t *)buffer32->line[sigma->displine])[(x << 3) + (c << 1) + 9] = col; - } - if (x & 1) - ++sigma->ma; - } + ((uint32_t *)buffer32->line[sigma->displine])[(x << 3) + (c << 1) + 8] = + ((uint32_t *)buffer32->line[sigma->displine])[(x << 3) + (c << 1) + 9] = col; + } + if (x & 1) + ++sigma->ma; + } } void sigma_poll(void *p) { - sigma_t *sigma = (sigma_t *)p; - int x, c; - int oldvc; - uint32_t cols[4]; - int oldsc; + sigma_t *sigma = (sigma_t *)p; + int x, c; + int oldvc; + uint32_t cols[4]; + int oldsc; - if (!sigma->linepos) { - timer_advance_u64(&sigma->timer, sigma->dispofftime); - sigma->sigmastat |= STATUS_RETR_H; - sigma->linepos = 1; - oldsc = sigma->sc; - if ((sigma->crtc[8] & 3) == 3) - sigma->sc = ((sigma->sc << 1) + sigma->oddeven) & 7; - if (sigma->cgadispon) { - if (sigma->displine < sigma->firstline) { - sigma->firstline = sigma->displine; - video_wait_for_buffer(); -// printf("Firstline %i\n",firstline); - } - sigma->lastline = sigma->displine; + if (!sigma->linepos) { + timer_advance_u64(&sigma->timer, sigma->dispofftime); + sigma->sigmastat |= STATUS_RETR_H; + sigma->linepos = 1; + oldsc = sigma->sc; + if ((sigma->crtc[8] & 3) == 3) + sigma->sc = ((sigma->sc << 1) + sigma->oddeven) & 7; + if (sigma->cgadispon) { + if (sigma->displine < sigma->firstline) { + sigma->firstline = sigma->displine; + video_wait_for_buffer(); + // printf("Firstline %i\n",firstline); + } + sigma->lastline = sigma->displine; - cols[0] = 0; - // Left overscan - for (c = 0; c < 8; c++) { - ((uint32_t *)buffer32->line[sigma->displine])[c] = cols[0]; - if (sigma->sigmamode & MODE_80COLS) - ((uint32_t *)buffer32->line[sigma->displine])[c + (sigma->crtc[1] << 4) + 8] = cols[0]; - else - ((uint32_t *)buffer32->line[sigma->displine])[c + (sigma->crtc[1] << 5) + 8] = cols[0]; - } - if (sigma->sigmamode & MODE_GRAPHICS) { - if (sigma->sigmamode & MODE_640x400) { - sigma_gfx400(sigma); - } else if (sigma->sigmamode & MODE_HRGFX) { - sigma_gfx200(sigma); - } else - sigma_gfx4col(sigma); + cols[0] = 0; + // Left overscan + for (c = 0; c < 8; c++) { + ((uint32_t *)buffer32->line[sigma->displine])[c] = cols[0]; + if (sigma->sigmamode & MODE_80COLS) + ((uint32_t *)buffer32->line[sigma->displine])[c + (sigma->crtc[1] << 4) + 8] = cols[0]; + else + ((uint32_t *)buffer32->line[sigma->displine])[c + (sigma->crtc[1] << 5) + 8] = cols[0]; + } + if (sigma->sigmamode & MODE_GRAPHICS) { + if (sigma->sigmamode & MODE_640x400) { + sigma_gfx400(sigma); + } else if (sigma->sigmamode & MODE_HRGFX) { + sigma_gfx200(sigma); + } else + sigma_gfx4col(sigma); - } else /* Text modes */ - { - if (sigma->sigmamode & MODE_80COLS) { - sigma_text80(sigma); - } else { - sigma_text40(sigma); - } - } - } else { - cols[0] = 0; - if (sigma->sigmamode & MODE_80COLS) - hline(buffer32, 0, sigma->displine, (sigma->crtc[1] << 4) + 16, cols[0]); - else - hline(buffer32, 0, sigma->displine, (sigma->crtc[1] << 5) + 16, cols[0]); - } + } else /* Text modes */ + { + if (sigma->sigmamode & MODE_80COLS) { + sigma_text80(sigma); + } else { + sigma_text40(sigma); + } + } + } else { + cols[0] = 0; + if (sigma->sigmamode & MODE_80COLS) + hline(buffer32, 0, sigma->displine, (sigma->crtc[1] << 4) + 16, cols[0]); + else + hline(buffer32, 0, sigma->displine, (sigma->crtc[1] << 5) + 16, cols[0]); + } - if (sigma->sigmamode & MODE_80COLS) { - x = (sigma->crtc[1] << 4) + 16; - } else { - x = (sigma->crtc[1] << 5) + 16; - } + if (sigma->sigmamode & MODE_80COLS) { + x = (sigma->crtc[1] << 4) + 16; + } else { + x = (sigma->crtc[1] << 5) + 16; + } - for (c = 0; c < x; c++) { - ((uint32_t *)buffer32->line[sigma->displine])[c] = cgapal[sigma->palette[((uint32_t *)buffer32->line[sigma->displine])[c] & 0xf]]; - } + for (c = 0; c < x; c++) { + ((uint32_t *)buffer32->line[sigma->displine])[c] = + cgapal[sigma->palette[((uint32_t *)buffer32->line[sigma->displine])[c] & 0xf]]; + } - sigma->sc = oldsc; - if (sigma->vc == sigma->crtc[7] && !sigma->sc) - sigma->sigmastat |= STATUS_RETR_V; - sigma->displine++; - if (sigma->displine >= 560) - sigma->displine = 0; - } else { - timer_advance_u64(&sigma->timer, sigma->dispontime); - sigma->linepos = 0; - if (sigma->vsynctime) { - sigma->vsynctime--; - if (!sigma->vsynctime) - sigma->sigmastat &= ~STATUS_RETR_V; - } - if (sigma->sc == (sigma->crtc[11] & 31) || ((sigma->crtc[8] & 3) == 3 && sigma->sc == ((sigma->crtc[11] & 31) >> 1))) { - sigma->con = 0; - sigma->coff = 1; - } - if ((sigma->crtc[8] & 3) == 3 && sigma->sc == (sigma->crtc[9] >> 1)) - sigma->maback = sigma->ma; - if (sigma->vadj) { - sigma->sc++; - sigma->sc &= 31; - sigma->ma = sigma->maback; - sigma->vadj--; - if (!sigma->vadj) { - sigma->cgadispon = 1; - sigma->ma = sigma->maback = (sigma->crtc[13] | (sigma->crtc[12] << 8)) & 0x3fff; - sigma->sc = 0; - } - } else if (sigma->sc == sigma->crtc[9]) { - sigma->maback = sigma->ma; - sigma->sc = 0; - oldvc = sigma->vc; - sigma->vc++; - sigma->vc &= 127; + sigma->sc = oldsc; + if (sigma->vc == sigma->crtc[7] && !sigma->sc) + sigma->sigmastat |= STATUS_RETR_V; + sigma->displine++; + if (sigma->displine >= 560) + sigma->displine = 0; + } else { + timer_advance_u64(&sigma->timer, sigma->dispontime); + sigma->linepos = 0; + if (sigma->vsynctime) { + sigma->vsynctime--; + if (!sigma->vsynctime) + sigma->sigmastat &= ~STATUS_RETR_V; + } + if (sigma->sc == (sigma->crtc[11] & 31) || + ((sigma->crtc[8] & 3) == 3 && sigma->sc == ((sigma->crtc[11] & 31) >> 1))) { + sigma->con = 0; + sigma->coff = 1; + } + if ((sigma->crtc[8] & 3) == 3 && sigma->sc == (sigma->crtc[9] >> 1)) + sigma->maback = sigma->ma; + if (sigma->vadj) { + sigma->sc++; + sigma->sc &= 31; + sigma->ma = sigma->maback; + sigma->vadj--; + if (!sigma->vadj) { + sigma->cgadispon = 1; + sigma->ma = sigma->maback = (sigma->crtc[13] | (sigma->crtc[12] << 8)) & 0x3fff; + sigma->sc = 0; + } + } else if (sigma->sc == sigma->crtc[9]) { + sigma->maback = sigma->ma; + sigma->sc = 0; + oldvc = sigma->vc; + sigma->vc++; + sigma->vc &= 127; - if (sigma->vc == sigma->crtc[6]) - sigma->cgadispon = 0; + if (sigma->vc == sigma->crtc[6]) + sigma->cgadispon = 0; - if (oldvc == sigma->crtc[4]) { - sigma->vc = 0; - sigma->vadj = sigma->crtc[5]; - if (!sigma->vadj) - sigma->cgadispon = 1; - if (!sigma->vadj) - sigma->ma = sigma->maback = (sigma->crtc[13] | (sigma->crtc[12] << 8)) & 0x3fff; - if ((sigma->crtc[10] & 0x60) == 0x20) - sigma->cursoron = 0; - else - sigma->cursoron = sigma->cgablink & 8; - } + if (oldvc == sigma->crtc[4]) { + sigma->vc = 0; + sigma->vadj = sigma->crtc[5]; + if (!sigma->vadj) + sigma->cgadispon = 1; + if (!sigma->vadj) + sigma->ma = sigma->maback = (sigma->crtc[13] | (sigma->crtc[12] << 8)) & 0x3fff; + if ((sigma->crtc[10] & 0x60) == 0x20) + sigma->cursoron = 0; + else + sigma->cursoron = sigma->cgablink & 8; + } - if (sigma->vc == sigma->crtc[7]) { - sigma->cgadispon = 0; - sigma->displine = 0; - sigma->vsynctime = 16; - if (sigma->crtc[7]) { - if (sigma->sigmamode & MODE_80COLS) - x = (sigma->crtc[1] << 4) + 16; - else - x = (sigma->crtc[1] << 5) + 16; - sigma->lastline++; - if (x != xsize || (sigma->lastline - sigma->firstline) != ysize) { - xsize = x; - ysize = sigma->lastline - sigma->firstline; -// pclog("sigma: xsize := %d ysize := %d\n", xsize, ysize); - if (xsize < 64) - xsize = 656; - if (ysize < 32) - ysize = 200; - updatewindowsize(xsize, ysize + 8); - } + if (sigma->vc == sigma->crtc[7]) { + sigma->cgadispon = 0; + sigma->displine = 0; + sigma->vsynctime = 16; + if (sigma->crtc[7]) { + if (sigma->sigmamode & MODE_80COLS) + x = (sigma->crtc[1] << 4) + 16; + else + x = (sigma->crtc[1] << 5) + 16; + sigma->lastline++; + if (x != xsize || (sigma->lastline - sigma->firstline) != ysize) { + xsize = x; + ysize = sigma->lastline - sigma->firstline; + // pclog("sigma: xsize := %d ysize := %d\n", + //xsize, ysize); + if (xsize < 64) + xsize = 656; + if (ysize < 32) + ysize = 200; + updatewindowsize(xsize, ysize + 8); + } - video_blit_memtoscreen(0, sigma->firstline - 4, 0, (sigma->lastline - sigma->firstline) + 8, xsize, (sigma->lastline - sigma->firstline) + 8); - frames++; + video_blit_memtoscreen(0, sigma->firstline - 4, 0, + (sigma->lastline - sigma->firstline) + 8, xsize, + (sigma->lastline - sigma->firstline) + 8); + frames++; - video_res_x = xsize - 16; - video_res_y = ysize; - if (sigma->sigmamode & MODE_GRAPHICS) { - if (sigma->sigmamode & (MODE_HRGFX | MODE_640x400)) { - video_bpp = 1; - } else { - video_res_x /= 2; - video_bpp = 2; - } - } else if (sigma->sigmamode & MODE_80COLS) { -/* 80-column text */ - video_res_x /= 8; - video_res_y /= sigma->crtc[9] + 1; - video_bpp = 0; - } else { -/* 40-column text */ - video_res_x /= 16; - video_res_y /= sigma->crtc[9] + 1; - video_bpp = 0; - } - } - sigma->firstline = 1000; - sigma->lastline = 0; - sigma->cgablink++; - sigma->oddeven ^= 1; - } - } else { - sigma->sc++; - sigma->sc &= 31; - sigma->ma = sigma->maback; - } - if (sigma->cgadispon) - sigma->sigmastat &= ~STATUS_RETR_H; - if ((sigma->sc == (sigma->crtc[10] & 31) || ((sigma->crtc[8] & 3) == 3 && sigma->sc == ((sigma->crtc[10] & 31) >> 1)))) - sigma->con = 1; - } + video_res_x = xsize - 16; + video_res_y = ysize; + if (sigma->sigmamode & MODE_GRAPHICS) { + if (sigma->sigmamode & (MODE_HRGFX | MODE_640x400)) { + video_bpp = 1; + } else { + video_res_x /= 2; + video_bpp = 2; + } + } else if (sigma->sigmamode & MODE_80COLS) { + /* 80-column text */ + video_res_x /= 8; + video_res_y /= sigma->crtc[9] + 1; + video_bpp = 0; + } else { + /* 40-column text */ + video_res_x /= 16; + video_res_y /= sigma->crtc[9] + 1; + video_bpp = 0; + } + } + sigma->firstline = 1000; + sigma->lastline = 0; + sigma->cgablink++; + sigma->oddeven ^= 1; + } + } else { + sigma->sc++; + sigma->sc &= 31; + sigma->ma = sigma->maback; + } + if (sigma->cgadispon) + sigma->sigmastat &= ~STATUS_RETR_H; + if ((sigma->sc == (sigma->crtc[10] & 31) || + ((sigma->crtc[8] & 3) == 3 && sigma->sc == ((sigma->crtc[10] & 31) >> 1)))) + sigma->con = 1; + } } void *sigma_init() { - int display_type, contrast; - sigma_t *sigma = malloc(sizeof(sigma_t)); - memset(sigma, 0, sizeof(sigma_t)); + int display_type, contrast; + sigma_t *sigma = malloc(sizeof(sigma_t)); + memset(sigma, 0, sizeof(sigma_t)); - display_type = device_get_config_int("display_type"); - contrast = device_get_config_int("contrast"); - sigma->enable_nmi = device_get_config_int("enable_nmi"); + display_type = device_get_config_int("display_type"); + contrast = device_get_config_int("contrast"); + sigma->enable_nmi = device_get_config_int("enable_nmi"); - loadfont("sigma400_font.rom", 7); - rom_init(&sigma->bios_rom, "sigma400_bios.rom", 0xC0000, 0x2000, - 0x1FFF, 0, MEM_MAPPING_EXTERNAL); - /* The BIOS ROM is overlaid by RAM, so remove its default mapping - * and access it through sigma_bread() / sigma_bwrite() below */ - mem_mapping_disable(&sigma->bios_rom.mapping); + loadfont("sigma400_font.rom", 7); + rom_init(&sigma->bios_rom, "sigma400_bios.rom", 0xC0000, 0x2000, 0x1FFF, 0, MEM_MAPPING_EXTERNAL); + /* The BIOS ROM is overlaid by RAM, so remove its default mapping + * and access it through sigma_bread() / sigma_bwrite() below */ + mem_mapping_disable(&sigma->bios_rom.mapping); - sigma->vram = malloc(0x8000 * 4); + sigma->vram = malloc(0x8000 * 4); - timer_add(&sigma->timer, sigma_poll, sigma, 1); - mem_mapping_add(&sigma->mapping, 0xb8000, 0x08000, - sigma_read, NULL, NULL, - sigma_write, NULL, NULL, - NULL, MEM_MAPPING_EXTERNAL, sigma); - mem_mapping_add(&sigma->bios_ram, 0xC1800, 0x0800, - sigma_bread, NULL, NULL, - sigma_bwrite, NULL, NULL, - sigma->bios_rom.rom, MEM_MAPPING_EXTERNAL, sigma); - io_sethandler(0x03d0, 0x0010, - sigma_in, NULL, NULL, - sigma_out, NULL, NULL, sigma); - io_sethandler(0x02d0, 0x0010, - sigma_in, NULL, NULL, - sigma_out, NULL, NULL, sigma); + timer_add(&sigma->timer, sigma_poll, sigma, 1); + mem_mapping_add(&sigma->mapping, 0xb8000, 0x08000, sigma_read, NULL, NULL, sigma_write, NULL, NULL, NULL, + MEM_MAPPING_EXTERNAL, sigma); + mem_mapping_add(&sigma->bios_ram, 0xC1800, 0x0800, sigma_bread, NULL, NULL, sigma_bwrite, NULL, NULL, sigma->bios_rom.rom, + MEM_MAPPING_EXTERNAL, sigma); + io_sethandler(0x03d0, 0x0010, sigma_in, NULL, NULL, sigma_out, NULL, NULL, sigma); + io_sethandler(0x02d0, 0x0010, sigma_in, NULL, NULL, sigma_out, NULL, NULL, sigma); - /* Start with ROM paged in, BIOS RAM paged out */ - sigma->rom_paged = 0x80; + /* Start with ROM paged in, BIOS RAM paged out */ + sigma->rom_paged = 0x80; - cgapal_rebuild(display_type, contrast); + cgapal_rebuild(display_type, contrast); - if (sigma->enable_nmi) { - sigma->sigmastat = STATUS_LPEN_T; - } - return sigma; + if (sigma->enable_nmi) { + sigma->sigmastat = STATUS_LPEN_T; + } + return sigma; } void sigma_close(void *p) { - sigma_t *sigma = (sigma_t *)p; + sigma_t *sigma = (sigma_t *)p; - free(sigma->vram); - free(sigma); + free(sigma->vram); + free(sigma); } void sigma_speed_changed(void *p) { - sigma_t *sigma = (sigma_t *)p; + sigma_t *sigma = (sigma_t *)p; - sigma_recalctimings(sigma); + sigma_recalctimings(sigma); } -device_config_t sigma_config[] = - { - { - .name = "display_type", - .description = "Display type", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "RGB", - .value = DISPLAY_RGB - }, - { - .description = "RGB (no brown)", - .value = DISPLAY_RGB_NO_BROWN - }, - { - .description = "Green Monochrome", - .value = DISPLAY_GREEN - }, - { - .description = "Amber Monochrome", - .value = DISPLAY_AMBER - }, - { - .description = "White Monochrome", - .value = DISPLAY_WHITE - }, - { - .description = "" - } - }, - .default_int = DISPLAY_RGB - }, - { - .name = "enable_nmi", - .description = "Enable NMI for CGA emulation", - .type = CONFIG_BINARY, - .default_int = 1 - }, - { - .name = "contrast", - .description = "Alternate monochrome contrast", - .type = CONFIG_BINARY, - .default_int = 0 - }, - { - .type = -1 - } - }; +device_config_t sigma_config[] = { + {.name = "display_type", + .description = "Display type", + .type = CONFIG_SELECTION, + .selection = {{.description = "RGB", .value = DISPLAY_RGB}, + {.description = "RGB (no brown)", .value = DISPLAY_RGB_NO_BROWN}, + {.description = "Green Monochrome", .value = DISPLAY_GREEN}, + {.description = "Amber Monochrome", .value = DISPLAY_AMBER}, + {.description = "White Monochrome", .value = DISPLAY_WHITE}, + {.description = ""}}, + .default_int = DISPLAY_RGB}, + {.name = "enable_nmi", .description = "Enable NMI for CGA emulation", .type = CONFIG_BINARY, .default_int = 1}, + {.name = "contrast", .description = "Alternate monochrome contrast", .type = CONFIG_BINARY, .default_int = 0}, + {.type = -1}}; -device_t sigma_device = - { - "Sigma Color 400", - 0, - sigma_init, - sigma_close, - NULL, - sigma_speed_changed, - NULL, - NULL, - sigma_config - }; +device_t sigma_device = {"Sigma Color 400", 0, sigma_init, sigma_close, NULL, sigma_speed_changed, NULL, NULL, sigma_config}; diff --git a/src/video/vid_stg_ramdac.c b/src/video/vid_stg_ramdac.c index eebdfa13..f22e8c80 100644 --- a/src/video/vid_stg_ramdac.c +++ b/src/video/vid_stg_ramdac.c @@ -9,114 +9,137 @@ static int stg_state_read[2][8] = {{1, 2, 3, 4, 0, 0, 0, 0}, {1, 2, 3, 4, 5, 6, static int stg_state_write[8] = {0, 0, 0, 0, 0, 6, 7, 7}; void stg_ramdac_out(uint16_t addr, uint8_t val, stg_ramdac_t *ramdac, svga_t *svga) { - int didwrite; - //if (CS!=0xC000) pclog("OUT RAMDAC %04X %02X %i %04X:%04X\n",addr,val,stg_ramdac.magic_count,CS,pc); - switch (addr) { - case 0x3c6: - switch (ramdac->magic_count) { - case 0: - case 1: - case 2: - case 3:break; - case 4:ramdac->command = val; - /*pclog("Write RAMDAC command %02X\n",val);*/ - break; - case 5:ramdac->index = (ramdac->index & 0xff00) | val; - break; - case 6:ramdac->index = (ramdac->index & 0xff) | (val << 8); - break; - case 7:pclog("Write RAMDAC reg %02X %02X\n", ramdac->index, val); - if (ramdac->index < 0x100) - ramdac->regs[ramdac->index] = val; - ramdac->index++; - break; - } - didwrite = (ramdac->magic_count >= 4); - ramdac->magic_count = stg_state_write[ramdac->magic_count & 7]; - if (ramdac->command & 8) { - switch (ramdac->regs[3]) { - case 0: - case 5: - case 7:svga->bpp = 8; - break; - case 1: - case 2: - case 8:svga->bpp = 15; - break; - case 3: - case 6:svga->bpp = 16; - break; - case 4: - case 9:svga->bpp = 24; - break; - default:svga->bpp = 8; - break; - } - } else { - switch (ramdac->command >> 5) { - case 0:svga->bpp = 8; - break; - case 5:svga->bpp = 15; - break; - case 6:svga->bpp = 16; - break; - case 7:svga->bpp = 24; - break; - default:svga->bpp = 8; - break; - } - } - svga_recalctimings(svga); - if (didwrite) - return; - break; - case 0x3c7: - case 0x3c8: - case 0x3c9:ramdac->magic_count = 0; - break; - } - svga_out(addr, val, svga); + int didwrite; + // if (CS!=0xC000) pclog("OUT RAMDAC %04X %02X %i %04X:%04X\n",addr,val,stg_ramdac.magic_count,CS,pc); + switch (addr) { + case 0x3c6: + switch (ramdac->magic_count) { + case 0: + case 1: + case 2: + case 3: + break; + case 4: + ramdac->command = val; + /*pclog("Write RAMDAC command %02X\n",val);*/ + break; + case 5: + ramdac->index = (ramdac->index & 0xff00) | val; + break; + case 6: + ramdac->index = (ramdac->index & 0xff) | (val << 8); + break; + case 7: + pclog("Write RAMDAC reg %02X %02X\n", ramdac->index, val); + if (ramdac->index < 0x100) + ramdac->regs[ramdac->index] = val; + ramdac->index++; + break; + } + didwrite = (ramdac->magic_count >= 4); + ramdac->magic_count = stg_state_write[ramdac->magic_count & 7]; + if (ramdac->command & 8) { + switch (ramdac->regs[3]) { + case 0: + case 5: + case 7: + svga->bpp = 8; + break; + case 1: + case 2: + case 8: + svga->bpp = 15; + break; + case 3: + case 6: + svga->bpp = 16; + break; + case 4: + case 9: + svga->bpp = 24; + break; + default: + svga->bpp = 8; + break; + } + } else { + switch (ramdac->command >> 5) { + case 0: + svga->bpp = 8; + break; + case 5: + svga->bpp = 15; + break; + case 6: + svga->bpp = 16; + break; + case 7: + svga->bpp = 24; + break; + default: + svga->bpp = 8; + break; + } + } + svga_recalctimings(svga); + if (didwrite) + return; + break; + case 0x3c7: + case 0x3c8: + case 0x3c9: + ramdac->magic_count = 0; + break; + } + svga_out(addr, val, svga); } uint8_t stg_ramdac_in(uint16_t addr, stg_ramdac_t *ramdac, svga_t *svga) { - uint8_t temp = 0xff; - //if (CS!=0xC000) pclog("IN RAMDAC %04X %04X:%04X\n",addr,CS,pc); - switch (addr) { - case 0x3c6: - switch (ramdac->magic_count) { - case 0: - case 1: - case 2: - case 3:temp = 0xff; - break; - case 4:temp = ramdac->command; - break; - case 5:temp = ramdac->index & 0xff; - break; - case 6:temp = ramdac->index >> 8; - break; - case 7: -// pclog("Read RAMDAC index %04X\n",stg_ramdac.index); - switch (ramdac->index) { - case 0:temp = 0x44; - break; - case 1:temp = 0x02; - break; - default: - if (ramdac->index < 0x100) - temp = ramdac->regs[ramdac->index]; - else - temp = 0xff; - break; - } - ramdac->index++; - break; - } - ramdac->magic_count = stg_state_read[(ramdac->command & 0x10) ? 1 : 0][ramdac->magic_count & 7]; - return temp; - case 0x3c8: - case 0x3c9:ramdac->magic_count = 0; - break; - } - return svga_in(addr, svga); + uint8_t temp = 0xff; + // if (CS!=0xC000) pclog("IN RAMDAC %04X %04X:%04X\n",addr,CS,pc); + switch (addr) { + case 0x3c6: + switch (ramdac->magic_count) { + case 0: + case 1: + case 2: + case 3: + temp = 0xff; + break; + case 4: + temp = ramdac->command; + break; + case 5: + temp = ramdac->index & 0xff; + break; + case 6: + temp = ramdac->index >> 8; + break; + case 7: + // pclog("Read RAMDAC index %04X\n",stg_ramdac.index); + switch (ramdac->index) { + case 0: + temp = 0x44; + break; + case 1: + temp = 0x02; + break; + default: + if (ramdac->index < 0x100) + temp = ramdac->regs[ramdac->index]; + else + temp = 0xff; + break; + } + ramdac->index++; + break; + } + ramdac->magic_count = stg_state_read[(ramdac->command & 0x10) ? 1 : 0][ramdac->magic_count & 7]; + return temp; + case 0x3c8: + case 0x3c9: + ramdac->magic_count = 0; + break; + } + return svga_in(addr, svga); } diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index c06a542d..a592c6f4 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -21,1588 +21,1644 @@ uint8_t svga_rotate[8][256]; only SVGA device.*/ static svga_t *svga_pri; -svga_t *svga_get_pri() { - return svga_pri; -} +svga_t *svga_get_pri() { return svga_pri; } void svga_set_override(svga_t *svga, int val) { - if (svga->override && !val) - svga->fullchange = changeframecount; - svga->override = val; + if (svga->override && !val) + svga->fullchange = changeframecount; + svga->override = val; } void svga_out(uint16_t addr, uint8_t val, void *p) { - svga_t *svga = (svga_t *)p; - int c; - uint8_t o; -// printf("OUT SVGA %03X %02X %04X:%04X\n",addr,val,CS,pc); - switch (addr) { - case 0x3C0: - if (!svga->attrff) { - svga->attraddr = val & 31; - if ((val & 0x20) != svga->attr_palette_enable) { - svga->fullchange = 3; - svga->attr_palette_enable = val & 0x20; - svga_recalctimings(svga); - } - } else { - if ((svga->attraddr == 0x13) && (svga->attrregs[0x13] != val)) - svga->fullchange = changeframecount; - svga->attrregs[svga->attraddr & 31] = val; - if (svga->attraddr < 16) - svga->fullchange = changeframecount; - if (svga->attraddr == 0x10 || svga->attraddr == 0x14 || svga->attraddr < 0x10) { - for (c = 0; c < 16; c++) { - if (svga->attrregs[0x10] & 0x80) - svga->egapal[c] = (svga->attrregs[c] & 0xf) | ((svga->attrregs[0x14] & 0xf) << 4); - else - svga->egapal[c] = (svga->attrregs[c] & 0x3f) | ((svga->attrregs[0x14] & 0xc) << 4); - } - } - if (svga->attraddr == 0x10) - svga_recalctimings(svga); - if (svga->attraddr == 0x12) { - if ((val & 0xf) != svga->plane_mask) - svga->fullchange = changeframecount; - svga->plane_mask = val & 0xf; - } - } - svga->attrff ^= 1; - break; - case 0x3C2:svga->miscout = val; - svga->vidclock = val & 4;// printf("3C2 write %02X\n",val); - io_removehandler(0x03a0, 0x0020, svga->video_in, NULL, NULL, svga->video_out, NULL, NULL, svga->p); - if (!(val & 1)) - io_sethandler(0x03a0, 0x0020, svga->video_in, NULL, NULL, svga->video_out, NULL, NULL, svga->p); - svga_recalctimings(svga); - break; - case 0x3C4:svga->seqaddr = val; - break; - case 0x3C5: - if (svga->seqaddr > 0xf) - return; - o = svga->seqregs[svga->seqaddr & 0xf]; - svga->seqregs[svga->seqaddr & 0xf] = val; - if (o != val && (svga->seqaddr & 0xf) == 1) - svga_recalctimings(svga); - switch (svga->seqaddr & 0xf) { - case 1: - if (svga->scrblank && !(val & 0x20)) - svga->fullchange = 3; - svga->scrblank = (svga->scrblank & ~0x20) | (val & 0x20); - svga_recalctimings(svga); - break; - case 2:svga->writemask = val & 0xf; - break; - case 3:svga->charsetb = (((val >> 2) & 3) * 0x10000) + 2; - svga->charseta = ((val & 3) * 0x10000) + 2; - if (val & 0x10) - svga->charseta += 0x8000; - if (val & 0x20) - svga->charsetb += 0x8000; - break; - case 4:svga->chain2_write = !(val & 4); - svga->chain4 = val & 8; - svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) && - ((svga->chain4 && svga->packed_chain4) || svga->fb_only); - break; - } - break; - case 0x3c6:svga->dac_mask = val; - break; - case 0x3C7:svga->dac_read = val; - svga->dac_pos = 0; - break; - case 0x3C8:svga->dac_write = val; - svga->dac_read = val - 1; - svga->dac_pos = 0; - break; - case 0x3C9:svga->dac_status = 0; - svga->fullchange = changeframecount; - switch (svga->dac_pos) { - case 0:svga->dac_r = val; - svga->dac_pos++; - break; - case 1:svga->dac_g = val; - svga->dac_pos++; - break; - case 2:svga->vgapal[svga->dac_write].r = svga->dac_r; - svga->vgapal[svga->dac_write].g = svga->dac_g; - svga->vgapal[svga->dac_write].b = val; - if (svga->ramdac_type == RAMDAC_8BIT) - svga->pallook[svga->dac_write] = makecol32(svga->vgapal[svga->dac_write].r, svga->vgapal[svga->dac_write].g, svga->vgapal[svga->dac_write].b); - else - svga->pallook[svga->dac_write] = makecol32( - (svga->vgapal[svga->dac_write].r & 0x3f) * 4, (svga->vgapal[svga->dac_write].g & 0x3f) * 4, (svga->vgapal[svga->dac_write].b & 0x3f) * 4); - svga->dac_pos = 0; - svga->dac_write = (svga->dac_write + 1) & 255; - break; - } - break; - case 0x3CE:svga->gdcaddr = val; - break; - case 0x3CF:o = svga->gdcreg[svga->gdcaddr & 15]; - switch (svga->gdcaddr & 15) { - case 2:svga->colourcompare = val; - break; - case 4:svga->readplane = val & 3; - break; - case 5:svga->writemode = val & 3; - svga->readmode = val & 8; - svga->chain2_read = val & 0x10; - break; - case 6: -// pclog("svga_out recalcmapping %p\n", svga); - if ((svga->gdcreg[6] & 0xc) != (val & 0xc)) { -// pclog("Write mapping %02X\n", val); - switch (val & 0xC) { - case 0x0: /*128k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); - svga->banked_mask = 0xffff; - break; - case 0x4: /*64k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - svga->banked_mask = 0xffff; - break; - case 0x8: /*32k at B0000*/ - mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); - svga->banked_mask = 0x7fff; - break; - case 0xC: /*32k at B8000*/ - mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); - svga->banked_mask = 0x7fff; - break; - } - } - break; - case 7:svga->colournocare = val; - break; - } - svga->gdcreg[svga->gdcaddr & 15] = val; - svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) && - ((svga->chain4 && svga->packed_chain4) || svga->fb_only); - if (((svga->gdcaddr & 15) == 5 && (val ^ o) & 0x70) || ((svga->gdcaddr & 15) == 6 && (val ^ o) & 1)) - svga_recalctimings(svga); - break; - } + svga_t *svga = (svga_t *)p; + int c; + uint8_t o; + // printf("OUT SVGA %03X %02X %04X:%04X\n",addr,val,CS,pc); + switch (addr) { + case 0x3C0: + if (!svga->attrff) { + svga->attraddr = val & 31; + if ((val & 0x20) != svga->attr_palette_enable) { + svga->fullchange = 3; + svga->attr_palette_enable = val & 0x20; + svga_recalctimings(svga); + } + } else { + if ((svga->attraddr == 0x13) && (svga->attrregs[0x13] != val)) + svga->fullchange = changeframecount; + svga->attrregs[svga->attraddr & 31] = val; + if (svga->attraddr < 16) + svga->fullchange = changeframecount; + if (svga->attraddr == 0x10 || svga->attraddr == 0x14 || svga->attraddr < 0x10) { + for (c = 0; c < 16; c++) { + if (svga->attrregs[0x10] & 0x80) + svga->egapal[c] = (svga->attrregs[c] & 0xf) | ((svga->attrregs[0x14] & 0xf) << 4); + else + svga->egapal[c] = + (svga->attrregs[c] & 0x3f) | ((svga->attrregs[0x14] & 0xc) << 4); + } + } + if (svga->attraddr == 0x10) + svga_recalctimings(svga); + if (svga->attraddr == 0x12) { + if ((val & 0xf) != svga->plane_mask) + svga->fullchange = changeframecount; + svga->plane_mask = val & 0xf; + } + } + svga->attrff ^= 1; + break; + case 0x3C2: + svga->miscout = val; + svga->vidclock = val & 4; // printf("3C2 write %02X\n",val); + io_removehandler(0x03a0, 0x0020, svga->video_in, NULL, NULL, svga->video_out, NULL, NULL, svga->p); + if (!(val & 1)) + io_sethandler(0x03a0, 0x0020, svga->video_in, NULL, NULL, svga->video_out, NULL, NULL, svga->p); + svga_recalctimings(svga); + break; + case 0x3C4: + svga->seqaddr = val; + break; + case 0x3C5: + if (svga->seqaddr > 0xf) + return; + o = svga->seqregs[svga->seqaddr & 0xf]; + svga->seqregs[svga->seqaddr & 0xf] = val; + if (o != val && (svga->seqaddr & 0xf) == 1) + svga_recalctimings(svga); + switch (svga->seqaddr & 0xf) { + case 1: + if (svga->scrblank && !(val & 0x20)) + svga->fullchange = 3; + svga->scrblank = (svga->scrblank & ~0x20) | (val & 0x20); + svga_recalctimings(svga); + break; + case 2: + svga->writemask = val & 0xf; + break; + case 3: + svga->charsetb = (((val >> 2) & 3) * 0x10000) + 2; + svga->charseta = ((val & 3) * 0x10000) + 2; + if (val & 0x10) + svga->charseta += 0x8000; + if (val & 0x20) + svga->charsetb += 0x8000; + break; + case 4: + svga->chain2_write = !(val & 4); + svga->chain4 = val & 8; + svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) && + ((svga->chain4 && svga->packed_chain4) || svga->fb_only); + break; + } + break; + case 0x3c6: + svga->dac_mask = val; + break; + case 0x3C7: + svga->dac_read = val; + svga->dac_pos = 0; + break; + case 0x3C8: + svga->dac_write = val; + svga->dac_read = val - 1; + svga->dac_pos = 0; + break; + case 0x3C9: + svga->dac_status = 0; + svga->fullchange = changeframecount; + switch (svga->dac_pos) { + case 0: + svga->dac_r = val; + svga->dac_pos++; + break; + case 1: + svga->dac_g = val; + svga->dac_pos++; + break; + case 2: + svga->vgapal[svga->dac_write].r = svga->dac_r; + svga->vgapal[svga->dac_write].g = svga->dac_g; + svga->vgapal[svga->dac_write].b = val; + if (svga->ramdac_type == RAMDAC_8BIT) + svga->pallook[svga->dac_write] = + makecol32(svga->vgapal[svga->dac_write].r, svga->vgapal[svga->dac_write].g, + svga->vgapal[svga->dac_write].b); + else + svga->pallook[svga->dac_write] = makecol32((svga->vgapal[svga->dac_write].r & 0x3f) * 4, + (svga->vgapal[svga->dac_write].g & 0x3f) * 4, + (svga->vgapal[svga->dac_write].b & 0x3f) * 4); + svga->dac_pos = 0; + svga->dac_write = (svga->dac_write + 1) & 255; + break; + } + break; + case 0x3CE: + svga->gdcaddr = val; + break; + case 0x3CF: + o = svga->gdcreg[svga->gdcaddr & 15]; + switch (svga->gdcaddr & 15) { + case 2: + svga->colourcompare = val; + break; + case 4: + svga->readplane = val & 3; + break; + case 5: + svga->writemode = val & 3; + svga->readmode = val & 8; + svga->chain2_read = val & 0x10; + break; + case 6: + // pclog("svga_out recalcmapping %p\n", svga); + if ((svga->gdcreg[6] & 0xc) != (val & 0xc)) { + // pclog("Write mapping %02X\n", val); + switch (val & 0xC) { + case 0x0: /*128k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); + svga->banked_mask = 0xffff; + break; + case 0x4: /*64k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + svga->banked_mask = 0xffff; + break; + case 0x8: /*32k at B0000*/ + mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); + svga->banked_mask = 0x7fff; + break; + case 0xC: /*32k at B8000*/ + mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); + svga->banked_mask = 0x7fff; + break; + } + } + break; + case 7: + svga->colournocare = val; + break; + } + svga->gdcreg[svga->gdcaddr & 15] = val; + svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) && + ((svga->chain4 && svga->packed_chain4) || svga->fb_only); + if (((svga->gdcaddr & 15) == 5 && (val ^ o) & 0x70) || ((svga->gdcaddr & 15) == 6 && (val ^ o) & 1)) + svga_recalctimings(svga); + break; + } } uint8_t svga_in(uint16_t addr, void *p) { - svga_t *svga = (svga_t *)p; - uint8_t temp; -// if (addr!=0x3da) pclog("Read port %04X\n",addr); - switch (addr) { - case 0x3C0:return svga->attraddr | svga->attr_palette_enable; - case 0x3C1:return svga->attrregs[svga->attraddr]; - case 0x3c2: - if ((svga->vgapal[0].r + svga->vgapal[0].g + svga->vgapal[0].b) >= 0x50) - temp = 0; - else - temp = 0x10; - return temp; - case 0x3C4:return svga->seqaddr; - case 0x3C5:return svga->seqregs[svga->seqaddr & 0xF]; - case 0x3c6:return svga->dac_mask; - case 0x3c7:return svga->dac_status; - case 0x3c8:return svga->dac_write; - case 0x3c9:svga->dac_status = 3; - switch (svga->dac_pos) { - case 0:svga->dac_pos++; - if (svga->ramdac_type == RAMDAC_8BIT) - return svga->vgapal[svga->dac_read].r; - return svga->vgapal[svga->dac_read].r & 0x3f; - case 1:svga->dac_pos++; - if (svga->ramdac_type == RAMDAC_8BIT) - return svga->vgapal[svga->dac_read].g; - return svga->vgapal[svga->dac_read].g & 0x3f; - case 2:svga->dac_pos = 0; - svga->dac_read = (svga->dac_read + 1) & 255; - if (svga->ramdac_type == RAMDAC_8BIT) - return svga->vgapal[(svga->dac_read - 1) & 255].b; - return svga->vgapal[(svga->dac_read - 1) & 255].b & 0x3f; - } - break; - case 0x3CC:return svga->miscout; - case 0x3CE:return svga->gdcaddr; - case 0x3CF:return svga->gdcreg[svga->gdcaddr & 0xf]; - case 0x3DA:svga->attrff = 0; + svga_t *svga = (svga_t *)p; + uint8_t temp; + // if (addr!=0x3da) pclog("Read port %04X\n",addr); + switch (addr) { + case 0x3C0: + return svga->attraddr | svga->attr_palette_enable; + case 0x3C1: + return svga->attrregs[svga->attraddr]; + case 0x3c2: + if ((svga->vgapal[0].r + svga->vgapal[0].g + svga->vgapal[0].b) >= 0x50) + temp = 0; + else + temp = 0x10; + return temp; + case 0x3C4: + return svga->seqaddr; + case 0x3C5: + return svga->seqregs[svga->seqaddr & 0xF]; + case 0x3c6: + return svga->dac_mask; + case 0x3c7: + return svga->dac_status; + case 0x3c8: + return svga->dac_write; + case 0x3c9: + svga->dac_status = 3; + switch (svga->dac_pos) { + case 0: + svga->dac_pos++; + if (svga->ramdac_type == RAMDAC_8BIT) + return svga->vgapal[svga->dac_read].r; + return svga->vgapal[svga->dac_read].r & 0x3f; + case 1: + svga->dac_pos++; + if (svga->ramdac_type == RAMDAC_8BIT) + return svga->vgapal[svga->dac_read].g; + return svga->vgapal[svga->dac_read].g & 0x3f; + case 2: + svga->dac_pos = 0; + svga->dac_read = (svga->dac_read + 1) & 255; + if (svga->ramdac_type == RAMDAC_8BIT) + return svga->vgapal[(svga->dac_read - 1) & 255].b; + return svga->vgapal[(svga->dac_read - 1) & 255].b & 0x3f; + } + break; + case 0x3CC: + return svga->miscout; + case 0x3CE: + return svga->gdcaddr; + case 0x3CF: + return svga->gdcreg[svga->gdcaddr & 0xf]; + case 0x3DA: + svga->attrff = 0; - if (svga->cgastat & 0x01) - svga->cgastat &= ~0x30; - else - svga->cgastat ^= 0x30; - return svga->cgastat; - } -// printf("Bad EGA read %04X %04X:%04X\n",addr,cs>>4,pc); - return 0xFF; + if (svga->cgastat & 0x01) + svga->cgastat &= ~0x30; + else + svga->cgastat ^= 0x30; + return svga->cgastat; + } + // printf("Bad EGA read %04X %04X:%04X\n",addr,cs>>4,pc); + return 0xFF; } void svga_set_ramdac_type(svga_t *svga, int type) { - int c; + int c; - if (svga->ramdac_type != type) { - svga->ramdac_type = type; + if (svga->ramdac_type != type) { + svga->ramdac_type = type; - for (c = 0; c < 256; c++) { - if (svga->ramdac_type == RAMDAC_8BIT) - svga->pallook[c] = makecol32(svga->vgapal[c].r, svga->vgapal[c].g, svga->vgapal[c].b); - else - svga->pallook[c] = makecol32((svga->vgapal[c].r & 0x3f) * 4, (svga->vgapal[c].g & 0x3f) * 4, (svga->vgapal[c].b & 0x3f) * 4); - } - } + for (c = 0; c < 256; c++) { + if (svga->ramdac_type == RAMDAC_8BIT) + svga->pallook[c] = makecol32(svga->vgapal[c].r, svga->vgapal[c].g, svga->vgapal[c].b); + else + svga->pallook[c] = makecol32((svga->vgapal[c].r & 0x3f) * 4, (svga->vgapal[c].g & 0x3f) * 4, + (svga->vgapal[c].b & 0x3f) * 4); + } + } } void svga_recalctimings(svga_t *svga) { - double crtcconst; - double _dispontime, _dispofftime, disptime; + double crtcconst; + double _dispontime, _dispofftime, disptime; - svga->vtotal = svga->crtc[6]; - svga->dispend = svga->crtc[0x12]; - svga->vsyncstart = svga->crtc[0x10]; - svga->split = svga->crtc[0x18]; - svga->vblankstart = svga->crtc[0x15]; + svga->vtotal = svga->crtc[6]; + svga->dispend = svga->crtc[0x12]; + svga->vsyncstart = svga->crtc[0x10]; + svga->split = svga->crtc[0x18]; + svga->vblankstart = svga->crtc[0x15]; - if (svga->crtc[7] & 1) - svga->vtotal |= 0x100; - if (svga->crtc[7] & 32) - svga->vtotal |= 0x200; - svga->vtotal += 2; + if (svga->crtc[7] & 1) + svga->vtotal |= 0x100; + if (svga->crtc[7] & 32) + svga->vtotal |= 0x200; + svga->vtotal += 2; - if (svga->crtc[7] & 2) - svga->dispend |= 0x100; - if (svga->crtc[7] & 64) - svga->dispend |= 0x200; - svga->dispend++; + if (svga->crtc[7] & 2) + svga->dispend |= 0x100; + if (svga->crtc[7] & 64) + svga->dispend |= 0x200; + svga->dispend++; - if (svga->crtc[7] & 4) - svga->vsyncstart |= 0x100; - if (svga->crtc[7] & 128) - svga->vsyncstart |= 0x200; - svga->vsyncstart++; + if (svga->crtc[7] & 4) + svga->vsyncstart |= 0x100; + if (svga->crtc[7] & 128) + svga->vsyncstart |= 0x200; + svga->vsyncstart++; - if (svga->crtc[7] & 0x10) - svga->split |= 0x100; - if (svga->crtc[9] & 0x40) - svga->split |= 0x200; - svga->split++; + if (svga->crtc[7] & 0x10) + svga->split |= 0x100; + if (svga->crtc[9] & 0x40) + svga->split |= 0x200; + svga->split++; - if (svga->crtc[7] & 0x08) - svga->vblankstart |= 0x100; - if (svga->crtc[9] & 0x20) - svga->vblankstart |= 0x200; - svga->vblankstart++; + if (svga->crtc[7] & 0x08) + svga->vblankstart |= 0x100; + if (svga->crtc[9] & 0x20) + svga->vblankstart |= 0x200; + svga->vblankstart++; - svga->hdisp = svga->crtc[1]; - svga->hdisp++; + svga->hdisp = svga->crtc[1]; + svga->hdisp++; - svga->htotal = svga->crtc[0]; - svga->htotal += 6; /*+6 is required for Tyrian*/ + svga->htotal = svga->crtc[0]; + svga->htotal += 6; /*+6 is required for Tyrian*/ - svga->rowoffset = svga->crtc[0x13]; + svga->rowoffset = svga->crtc[0x13]; - svga->clock = (svga->vidclock) ? VGACONST2 : VGACONST1; + svga->clock = (svga->vidclock) ? VGACONST2 : VGACONST1; - svga->lowres = svga->attrregs[0x10] & 0x40; + svga->lowres = svga->attrregs[0x10] & 0x40; - svga->interlace = 0; + svga->interlace = 0; - svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); - svga->ca_adj = 0; + svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); + svga->ca_adj = 0; - svga->rowcount = svga->crtc[9] & 31; - svga->linedbl = svga->crtc[9] & 0x80; + svga->rowcount = svga->crtc[9] & 31; + svga->linedbl = svga->crtc[9] & 0x80; - svga->hdisp_time = svga->hdisp; - svga->render = svga_render_blank; - if (!svga->scrblank && svga->attr_palette_enable) { - if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) /*Text mode*/ - { - if (svga->seqregs[1] & 8) /*40 column*/ - { - svga->render = svga_render_text_40; - svga->hdisp *= (svga->seqregs[1] & 1) ? 16 : 18; - } else { - svga->render = svga_render_text_80; - svga->hdisp *= (svga->seqregs[1] & 1) ? 8 : 9; - } - svga->hdisp_old = svga->hdisp; - } else { - svga->hdisp *= (svga->seqregs[1] & 8) ? 16 : 8; - svga->hdisp_old = svga->hdisp; + svga->hdisp_time = svga->hdisp; + svga->render = svga_render_blank; + if (!svga->scrblank && svga->attr_palette_enable) { + if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) /*Text mode*/ + { + if (svga->seqregs[1] & 8) /*40 column*/ + { + svga->render = svga_render_text_40; + svga->hdisp *= (svga->seqregs[1] & 1) ? 16 : 18; + } else { + svga->render = svga_render_text_80; + svga->hdisp *= (svga->seqregs[1] & 1) ? 8 : 9; + } + svga->hdisp_old = svga->hdisp; + } else { + svga->hdisp *= (svga->seqregs[1] & 8) ? 16 : 8; + svga->hdisp_old = svga->hdisp; - switch (svga->gdcreg[5] & 0x60) { - case 0x00: /*16 colours*/ - if (svga->seqregs[1] & 8) /*Low res (320)*/ - svga->render = svga_render_4bpp_lowres; - else - svga->render = svga_render_4bpp_highres; - break; - case 0x20: /*4 colours*/ - if (svga->seqregs[1] & 8) /*Low res (320)*/ - svga->render = svga_render_2bpp_lowres; - else - svga->render = svga_render_2bpp_highres; - break; - case 0x40: - case 0x60: /*256+ colours*/ - switch (svga->bpp) { - case 8: - if (svga->lowres) - svga->render = svga_render_8bpp_lowres; - else - svga->render = svga_render_8bpp_highres; - break; - case 15: - if (svga->lowres) - svga->render = svga_render_15bpp_lowres; - else - svga->render = svga_render_15bpp_highres; - break; - case 16: - if (svga->lowres) - svga->render = svga_render_16bpp_lowres; - else - svga->render = svga_render_16bpp_highres; - break; - case 24: - if (svga->lowres) - svga->render = svga_render_24bpp_lowres; - else - svga->render = svga_render_24bpp_highres; - break; - case 32: - if (svga->lowres) - svga->render = svga_render_32bpp_lowres; - else - svga->render = svga_render_32bpp_highres; - break; - } - break; - } - } - } + switch (svga->gdcreg[5] & 0x60) { + case 0x00: /*16 colours*/ + if (svga->seqregs[1] & 8) /*Low res (320)*/ + svga->render = svga_render_4bpp_lowres; + else + svga->render = svga_render_4bpp_highres; + break; + case 0x20: /*4 colours*/ + if (svga->seqregs[1] & 8) /*Low res (320)*/ + svga->render = svga_render_2bpp_lowres; + else + svga->render = svga_render_2bpp_highres; + break; + case 0x40: + case 0x60: /*256+ colours*/ + switch (svga->bpp) { + case 8: + if (svga->lowres) + svga->render = svga_render_8bpp_lowres; + else + svga->render = svga_render_8bpp_highres; + break; + case 15: + if (svga->lowres) + svga->render = svga_render_15bpp_lowres; + else + svga->render = svga_render_15bpp_highres; + break; + case 16: + if (svga->lowres) + svga->render = svga_render_16bpp_lowres; + else + svga->render = svga_render_16bpp_highres; + break; + case 24: + if (svga->lowres) + svga->render = svga_render_24bpp_lowres; + else + svga->render = svga_render_24bpp_highres; + break; + case 32: + if (svga->lowres) + svga->render = svga_render_32bpp_lowres; + else + svga->render = svga_render_32bpp_highres; + break; + } + break; + } + } + } -// pclog("svga_render %08X : %08X %08X %08X %08X %08X %i %i %02X %i %i\n", svga_render, svga_render_text_40, svga_render_text_80, svga_render_8bpp_lowres, svga_render_8bpp_highres, svga_render_blank, scrblank,gdcreg[6]&1,gdcreg[5]&0x60,bpp,seqregs[1]&8); + // pclog("svga_render %08X : %08X %08X %08X %08X %08X %i %i %02X %i %i\n", svga_render, svga_render_text_40, + // svga_render_text_80, svga_render_8bpp_lowres, svga_render_8bpp_highres, svga_render_blank, + // scrblank,gdcreg[6]&1,gdcreg[5]&0x60,bpp,seqregs[1]&8); - svga->char_width = (svga->seqregs[1] & 1) ? 8 : 9; - if (svga->recalctimings_ex) - svga->recalctimings_ex(svga); + svga->char_width = (svga->seqregs[1] & 1) ? 8 : 9; + if (svga->recalctimings_ex) + svga->recalctimings_ex(svga); - if (svga->vblankstart < svga->dispend) - svga->dispend = svga->vblankstart; + if (svga->vblankstart < svga->dispend) + svga->dispend = svga->vblankstart; - crtcconst = svga->clock * svga->char_width; + crtcconst = svga->clock * svga->char_width; - disptime = svga->htotal; - _dispontime = svga->hdisp_time; + disptime = svga->htotal; + _dispontime = svga->hdisp_time; -// printf("Disptime %f dispontime %f hdisp %i\n",disptime,dispontime,crtc[1]*8); - if (svga->seqregs[1] & 8) { - disptime *= 2; - _dispontime *= 2; - } - _dispofftime = disptime - _dispontime; - _dispontime *= crtcconst; - _dispofftime *= crtcconst; + // printf("Disptime %f dispontime %f hdisp %i\n",disptime,dispontime,crtc[1]*8); + if (svga->seqregs[1] & 8) { + disptime *= 2; + _dispontime *= 2; + } + _dispofftime = disptime - _dispontime; + _dispontime *= crtcconst; + _dispofftime *= crtcconst; - svga->dispontime = (uint64_t)_dispontime; - svga->dispofftime = (uint64_t)_dispofftime; - if (svga->dispontime < TIMER_USEC) - svga->dispontime = TIMER_USEC; - if (svga->dispofftime < TIMER_USEC) - svga->dispofftime = TIMER_USEC; + svga->dispontime = (uint64_t)_dispontime; + svga->dispofftime = (uint64_t)_dispofftime; + if (svga->dispontime < TIMER_USEC) + svga->dispontime = TIMER_USEC; + if (svga->dispofftime < TIMER_USEC) + svga->dispofftime = TIMER_USEC; - svga_recalc_remap_func(svga); -/* printf("SVGA horiz total %i display end %i vidclock %f\n",svga->crtc[0],svga->crtc[1],svga->clock); - printf("SVGA vert total %i display end %i max row %i vsync %i\n",svga->vtotal,svga->dispend,(svga->crtc[9]&31)+1,svga->vsyncstart); - printf("total %f on %i cycles off %i cycles frame %i sec %i %02X\n",disptime*crtcconst,svga->dispontime,svga->dispofftime,(svga->dispontime+svga->dispofftime)*svga->vtotal,(svga->dispontime+svga->dispofftime)*svga->vtotal*70,svga->seqregs[1]); + svga_recalc_remap_func(svga); + /* printf("SVGA horiz total %i display end %i vidclock %f\n",svga->crtc[0],svga->crtc[1],svga->clock); + printf("SVGA vert total %i display end %i max row %i vsync + %i\n",svga->vtotal,svga->dispend,(svga->crtc[9]&31)+1,svga->vsyncstart); printf("total %f on %i cycles off %i cycles + frame %i sec %i + %02X\n",disptime*crtcconst,svga->dispontime,svga->dispofftime,(svga->dispontime+svga->dispofftime)*svga->vtotal,(svga->dispontime+svga->dispofftime)*svga->vtotal*70,svga->seqregs[1]); - pclog("svga->render %08X\n", svga->render);*/ + pclog("svga->render %08X\n", svga->render);*/ } extern int cyc_total; void svga_poll(void *p) { - svga_t *svga = (svga_t *)p; - int x; + svga_t *svga = (svga_t *)p; + int x; - if (!svga->linepos) { -// if (!(vc & 15)) pclog("VC %i %i\n", vc, GetTickCount()); - if (svga->displine == svga->hwcursor_latch.y && svga->hwcursor_latch.ena) { - svga->hwcursor_on = svga->hwcursor.ysize - svga->hwcursor_latch.yoff; - if (svga->hwcursor_on < 0) - svga->hwcursor_on = 0; - svga->hwcursor_oddeven = 0; - } + if (!svga->linepos) { + // if (!(vc & 15)) pclog("VC %i %i\n", vc, GetTickCount()); + if (svga->displine == svga->hwcursor_latch.y && svga->hwcursor_latch.ena) { + svga->hwcursor_on = svga->hwcursor.ysize - svga->hwcursor_latch.yoff; + if (svga->hwcursor_on < 0) + svga->hwcursor_on = 0; + svga->hwcursor_oddeven = 0; + } - if (svga->displine == svga->hwcursor_latch.y + 1 && svga->hwcursor_latch.ena && svga->interlace) { - svga->hwcursor_on = svga->hwcursor.ysize - svga->hwcursor_latch.yoff; - if (svga->hwcursor_on < 0) - svga->hwcursor_on = 0; - svga->hwcursor_oddeven = 1; - } + if (svga->displine == svga->hwcursor_latch.y + 1 && svga->hwcursor_latch.ena && svga->interlace) { + svga->hwcursor_on = svga->hwcursor.ysize - svga->hwcursor_latch.yoff; + if (svga->hwcursor_on < 0) + svga->hwcursor_on = 0; + svga->hwcursor_oddeven = 1; + } - if (svga->displine == svga->overlay_latch.y && svga->overlay_latch.ena) { - svga->overlay_on = svga->overlay_latch.ysize - svga->overlay_latch.yoff; - svga->overlay_oddeven = 0; - } - if (svga->displine == svga->overlay_latch.y + 1 && svga->overlay_latch.ena && svga->interlace) { - svga->overlay_on = svga->overlay_latch.ysize - svga->overlay_latch.yoff; - svga->overlay_oddeven = 1; - } + if (svga->displine == svga->overlay_latch.y && svga->overlay_latch.ena) { + svga->overlay_on = svga->overlay_latch.ysize - svga->overlay_latch.yoff; + svga->overlay_oddeven = 0; + } + if (svga->displine == svga->overlay_latch.y + 1 && svga->overlay_latch.ena && svga->interlace) { + svga->overlay_on = svga->overlay_latch.ysize - svga->overlay_latch.yoff; + svga->overlay_oddeven = 1; + } - timer_advance_u64(&svga->timer, svga->dispofftime); -// if (output) printf("Display off %f\n",vidtime); - svga->cgastat |= 1; - svga->linepos = 1; + timer_advance_u64(&svga->timer, svga->dispofftime); + // if (output) printf("Display off %f\n",vidtime); + svga->cgastat |= 1; + svga->linepos = 1; - if (svga->dispon) { - svga->hdisp_on = 1; + if (svga->dispon) { + svga->hdisp_on = 1; - svga->ma &= svga->vram_display_mask; - if (svga->firstline == 2000) { - svga->firstline = svga->displine; - video_wait_for_buffer(); - } + svga->ma &= svga->vram_display_mask; + if (svga->firstline == 2000) { + svga->firstline = svga->displine; + video_wait_for_buffer(); + } - if (svga->hwcursor_on || svga->overlay_on) - svga->changedvram[svga->ma >> 12] = svga->changedvram[(svga->ma >> 12) + 1] = svga->interlace ? 3 : 2; + if (svga->hwcursor_on || svga->overlay_on) + svga->changedvram[svga->ma >> 12] = svga->changedvram[(svga->ma >> 12) + 1] = + svga->interlace ? 3 : 2; - if (!svga->override) - svga->render(svga); + if (!svga->override) + svga->render(svga); - if (svga->overlay_on) { - if (!svga->override) - svga->overlay_draw(svga, svga->displine); - svga->overlay_on--; - if (svga->overlay_on && svga->interlace) - svga->overlay_on--; - } + if (svga->overlay_on) { + if (!svga->override) + svga->overlay_draw(svga, svga->displine); + svga->overlay_on--; + if (svga->overlay_on && svga->interlace) + svga->overlay_on--; + } - if (svga->hwcursor_on) { - if (!svga->override) - svga->hwcursor_draw(svga, svga->displine); - svga->hwcursor_on--; - if (svga->hwcursor_on && svga->interlace) - svga->hwcursor_on--; - } + if (svga->hwcursor_on) { + if (!svga->override) + svga->hwcursor_draw(svga, svga->displine); + svga->hwcursor_on--; + if (svga->hwcursor_on && svga->interlace) + svga->hwcursor_on--; + } - if (svga->lastline < svga->displine) - svga->lastline = svga->displine; - } + if (svga->lastline < svga->displine) + svga->lastline = svga->displine; + } -// pclog("%03i %06X %06X\n",displine,ma,vrammask); - svga->displine++; - if (svga->interlace) - svga->displine++; - if ((svga->cgastat & 8) && ((svga->displine & 15) == (svga->crtc[0x11] & 15)) && svga->vslines) { -// printf("Vsync off at line %i\n",displine); - svga->cgastat &= ~8; - } - svga->vslines++; - if (svga->displine > 1500) - svga->displine = 0; -// pclog("Col is %08X %08X %08X %i %i %08X\n",((uint32_t *)buffer32->line[displine])[320],((uint32_t *)buffer32->line[displine])[321],((uint32_t *)buffer32->line[displine])[322], -// displine, vc, ma); - } else { -// pclog("VC %i ma %05X\n", svga->vc, svga->ma); - timer_advance_u64(&svga->timer, svga->dispontime); + // pclog("%03i %06X %06X\n",displine,ma,vrammask); + svga->displine++; + if (svga->interlace) + svga->displine++; + if ((svga->cgastat & 8) && ((svga->displine & 15) == (svga->crtc[0x11] & 15)) && svga->vslines) { + // printf("Vsync off at line %i\n",displine); + svga->cgastat &= ~8; + } + svga->vslines++; + if (svga->displine > 1500) + svga->displine = 0; + // pclog("Col is %08X %08X %08X %i %i %08X\n",((uint32_t + // *)buffer32->line[displine])[320],((uint32_t *)buffer32->line[displine])[321],((uint32_t + // *)buffer32->line[displine])[322], + // displine, vc, ma); + } else { + // pclog("VC %i ma %05X\n", svga->vc, svga->ma); + timer_advance_u64(&svga->timer, svga->dispontime); -// if (output) printf("Display on %f\n",vidtime); - if (svga->dispon) - svga->cgastat &= ~1; - svga->hdisp_on = 0; + // if (output) printf("Display on %f\n",vidtime); + if (svga->dispon) + svga->cgastat &= ~1; + svga->hdisp_on = 0; - svga->linepos = 0; - if (svga->sc == (svga->crtc[11] & 31)) - svga->con = 0; - if (svga->dispon) { - if (svga->linedbl && !svga->linecountff) { - svga->linecountff = 1; - svga->ma = svga->maback; - } else if (svga->sc == svga->rowcount) { - svga->linecountff = 0; - svga->sc = 0; + svga->linepos = 0; + if (svga->sc == (svga->crtc[11] & 31)) + svga->con = 0; + if (svga->dispon) { + if (svga->linedbl && !svga->linecountff) { + svga->linecountff = 1; + svga->ma = svga->maback; + } else if (svga->sc == svga->rowcount) { + svga->linecountff = 0; + svga->sc = 0; - svga->maback += (svga->rowoffset << 3); - if (svga->interlace) - svga->maback += (svga->rowoffset << 3); - svga->maback &= svga->vram_display_mask; - svga->ma = svga->maback; - } else { - svga->linecountff = 0; - svga->sc++; - svga->sc &= 31; - svga->ma = svga->maback; - } - } - svga->hsync_divisor = !svga->hsync_divisor; + svga->maback += (svga->rowoffset << 3); + if (svga->interlace) + svga->maback += (svga->rowoffset << 3); + svga->maback &= svga->vram_display_mask; + svga->ma = svga->maback; + } else { + svga->linecountff = 0; + svga->sc++; + svga->sc &= 31; + svga->ma = svga->maback; + } + } + svga->hsync_divisor = !svga->hsync_divisor; - if (svga->hsync_divisor && (svga->crtc[0x17] & 4)) - return; + if (svga->hsync_divisor && (svga->crtc[0x17] & 4)) + return; - svga->vc++; - svga->vc &= 2047; + svga->vc++; + svga->vc &= 2047; - if (svga->vc == svga->split) { - int ret = 1; + if (svga->vc == svga->split) { + int ret = 1; - if (svga->line_compare) - ret = svga->line_compare(svga); + if (svga->line_compare) + ret = svga->line_compare(svga); - if (ret) { -// pclog("VC split\n"); - svga->ma = svga->maback = 0; - svga->sc = 0; - if (svga->attrregs[0x10] & 0x20) - svga->scrollcache = 0; - } - } - if (svga->vc == svga->dispend) { - if (svga->vblank_start) - svga->vblank_start(svga); -// pclog("VC dispend\n"); - svga->dispon = 0; - if (svga->crtc[10] & 0x20) - svga->cursoron = 0; - else - svga->cursoron = svga->blink & 16; - if (!(svga->gdcreg[6] & 1) && !(svga->blink & 15)) - svga->fullchange = 2; - svga->blink++; + if (ret) { + // pclog("VC split\n"); + svga->ma = svga->maback = 0; + svga->sc = 0; + if (svga->attrregs[0x10] & 0x20) + svga->scrollcache = 0; + } + } + if (svga->vc == svga->dispend) { + if (svga->vblank_start) + svga->vblank_start(svga); + // pclog("VC dispend\n"); + svga->dispon = 0; + if (svga->crtc[10] & 0x20) + svga->cursoron = 0; + else + svga->cursoron = svga->blink & 16; + if (!(svga->gdcreg[6] & 1) && !(svga->blink & 15)) + svga->fullchange = 2; + svga->blink++; - for (x = 0; x < ((svga->vram_mask + 1) >> 12); x++) { - if (svga->changedvram[x]) - svga->changedvram[x]--; - } -// memset(changedvram,0,2048); - if (svga->fullchange) - svga->fullchange--; - } - if (svga->vc == svga->vsyncstart) { - int wx, wy; -// pclog("VC vsync %i %i\n", svga->firstline_draw, svga->lastline_draw); - svga->dispon = 0; - svga->cgastat |= 8; - x = svga->hdisp; + for (x = 0; x < ((svga->vram_mask + 1) >> 12); x++) { + if (svga->changedvram[x]) + svga->changedvram[x]--; + } + // memset(changedvram,0,2048); + if (svga->fullchange) + svga->fullchange--; + } + if (svga->vc == svga->vsyncstart) { + int wx, wy; + // pclog("VC vsync %i %i\n", svga->firstline_draw, svga->lastline_draw); + svga->dispon = 0; + svga->cgastat |= 8; + x = svga->hdisp; - if (svga->interlace && !svga->oddeven) - svga->lastline++; - if (svga->interlace && svga->oddeven) - svga->firstline--; + if (svga->interlace && !svga->oddeven) + svga->lastline++; + if (svga->interlace && svga->oddeven) + svga->firstline--; - wx = x; - wy = svga->lastline - svga->firstline; + wx = x; + wy = svga->lastline - svga->firstline; - if (!svga->override) - svga_doblit(svga->firstline_draw, svga->lastline_draw + 1, wx, wy, svga); + if (!svga->override) + svga_doblit(svga->firstline_draw, svga->lastline_draw + 1, wx, wy, svga); - readflash = 0; + readflash = 0; - svga->firstline = 2000; - svga->lastline = 0; + svga->firstline = 2000; + svga->lastline = 0; - svga->firstline_draw = 2000; - svga->lastline_draw = 0; + svga->firstline_draw = 2000; + svga->lastline_draw = 0; - svga->oddeven ^= 1; + svga->oddeven ^= 1; - changeframecount = svga->interlace ? 3 : 2; - svga->vslines = 0; + changeframecount = svga->interlace ? 3 : 2; + svga->vslines = 0; - if (svga->interlace && svga->oddeven) - svga->ma = svga->maback = svga->ma_latch + (svga->rowoffset << 1); - else - svga->ma = svga->maback = svga->ma_latch; - svga->ca = ((svga->crtc[0xe] << 8) | svga->crtc[0xf]) + svga->ca_adj; + if (svga->interlace && svga->oddeven) + svga->ma = svga->maback = svga->ma_latch + (svga->rowoffset << 1); + else + svga->ma = svga->maback = svga->ma_latch; + svga->ca = ((svga->crtc[0xe] << 8) | svga->crtc[0xf]) + svga->ca_adj; - svga->ma <<= 2; - svga->maback <<= 2; - svga->ca <<= 2; + svga->ma <<= 2; + svga->maback <<= 2; + svga->ca <<= 2; - if (!svga->video_res_override) { - svga->video_res_x = wx; - svga->video_res_y = wy + 1; + if (!svga->video_res_override) { + svga->video_res_x = wx; + svga->video_res_y = wy + 1; - if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) /*Text mode*/ - { - svga->video_res_x /= svga->char_width; - svga->video_res_y /= (svga->crtc[9] & 31) + 1; - svga->video_bpp = 0; - } else { - if (svga->crtc[9] & 0x80) - svga->video_res_y /= 2; - if (!(svga->crtc[0x17] & 2)) - svga->video_res_y *= 4; - else if (!(svga->crtc[0x17] & 1)) - svga->video_res_y *= 2; - svga->video_res_y /= (svga->crtc[9] & 31) + 1; - if (svga->render == svga_render_8bpp_lowres || - svga->render == svga_render_15bpp_lowres || - svga->render == svga_render_16bpp_lowres || - svga->render == svga_render_24bpp_lowres || - svga->render == svga_render_32bpp_lowres) - svga->video_res_x /= 2; + if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) /*Text mode*/ + { + svga->video_res_x /= svga->char_width; + svga->video_res_y /= (svga->crtc[9] & 31) + 1; + svga->video_bpp = 0; + } else { + if (svga->crtc[9] & 0x80) + svga->video_res_y /= 2; + if (!(svga->crtc[0x17] & 2)) + svga->video_res_y *= 4; + else if (!(svga->crtc[0x17] & 1)) + svga->video_res_y *= 2; + svga->video_res_y /= (svga->crtc[9] & 31) + 1; + if (svga->render == svga_render_8bpp_lowres || svga->render == svga_render_15bpp_lowres || + svga->render == svga_render_16bpp_lowres || + svga->render == svga_render_24bpp_lowres || svga->render == svga_render_32bpp_lowres) + svga->video_res_x /= 2; - switch (svga->gdcreg[5] & 0x60) { - case 0x00:svga->video_bpp = 4; - break; - case 0x20:svga->video_bpp = 2; - break; - case 0x40: - case 0x60:svga->video_bpp = svga->bpp; - break; - } - } - } -// if (svga_interlace && oddeven) ma=maback=ma+(svga_rowoffset<<2); + switch (svga->gdcreg[5] & 0x60) { + case 0x00: + svga->video_bpp = 4; + break; + case 0x20: + svga->video_bpp = 2; + break; + case 0x40: + case 0x60: + svga->video_bpp = svga->bpp; + break; + } + } + } + // if (svga_interlace && oddeven) ma=maback=ma+(svga_rowoffset<<2); -// pclog("Addr %08X vson %03X vsoff %01X %02X %02X %02X %i %i\n",ma,svga_vsyncstart,crtc[0x11]&0xF,crtc[0xD],crtc[0xC],crtc[0x33], svga_interlace, oddeven); + // pclog("Addr %08X vson %03X vsoff %01X %02X %02X %02X %i + // %i\n",ma,svga_vsyncstart,crtc[0x11]&0xF,crtc[0xD],crtc[0xC],crtc[0x33], + // svga_interlace, oddeven); - if (svga->vsync_callback) - svga->vsync_callback(svga); - } - if (svga->vc == svga->vtotal) { -// pclog("VC vtotal\n"); + if (svga->vsync_callback) + svga->vsync_callback(svga); + } + if (svga->vc == svga->vtotal) { + // pclog("VC vtotal\n"); + // printf("Frame over at line %i %i %i + // %i\n",displine,vc,svga_vsyncstart,svga_dispend); + svga->vc = 0; + svga->sc = svga->crtc[8] & 0x1f; + svga->dispon = 1; + svga->displine = (svga->interlace && svga->oddeven) ? 1 : 0; + svga->scrollcache = svga->attrregs[0x13] & 7; + svga->linecountff = 0; -// printf("Frame over at line %i %i %i %i\n",displine,vc,svga_vsyncstart,svga_dispend); - svga->vc = 0; - svga->sc = svga->crtc[8] & 0x1f; - svga->dispon = 1; - svga->displine = (svga->interlace && svga->oddeven) ? 1 : 0; - svga->scrollcache = svga->attrregs[0x13] & 7; - svga->linecountff = 0; + svga->hwcursor_on = 0; + svga->hwcursor_latch = svga->hwcursor; - svga->hwcursor_on = 0; - svga->hwcursor_latch = svga->hwcursor; + svga->overlay_on = 0; + svga->overlay_latch = svga->overlay; + // pclog("Latch HWcursor addr %08X\n", svga_hwcursor_latch.addr); - svga->overlay_on = 0; - svga->overlay_latch = svga->overlay; -// pclog("Latch HWcursor addr %08X\n", svga_hwcursor_latch.addr); - -// pclog("ADDR %08X\n",hwcursor_addr); - } - if (svga->sc == (svga->crtc[10] & 31)) - svga->con = 1; - } -// printf("2 %i\n",svga_vsyncstart); -//pclog("svga_poll %i %i %i %i %i %i %i\n", ins, svga->dispofftime, svga->dispontime, svga->vidtime, cyc_total, svga->linepos, svga->vc); + // pclog("ADDR %08X\n",hwcursor_addr); + } + if (svga->sc == (svga->crtc[10] & 31)) + svga->con = 1; + } + // printf("2 %i\n",svga_vsyncstart); + // pclog("svga_poll %i %i %i %i %i %i %i\n", ins, svga->dispofftime, svga->dispontime, svga->vidtime, cyc_total, + // svga->linepos, svga->vc); } -int svga_init(svga_t *svga, void *p, int memsize, - void (*recalctimings_ex)(struct svga_t *svga), - uint8_t (*video_in)(uint16_t addr, void *p), - void (*video_out)(uint16_t addr, uint8_t val, void *p), - void (*hwcursor_draw)(struct svga_t *svga, int displine), - void (*overlay_draw)(struct svga_t *svga, int displine)) { - int c, d, e; +int svga_init(svga_t *svga, void *p, int memsize, void (*recalctimings_ex)(struct svga_t *svga), + uint8_t (*video_in)(uint16_t addr, void *p), void (*video_out)(uint16_t addr, uint8_t val, void *p), + void (*hwcursor_draw)(struct svga_t *svga, int displine), void (*overlay_draw)(struct svga_t *svga, int displine)) { + int c, d, e; - svga->p = p; + svga->p = p; - for (c = 0; c < 256; c++) { - e = c; - for (d = 0; d < 8; d++) { - svga_rotate[d][c] = e; - e = (e >> 1) | ((e & 1) ? 0x80 : 0); - } - } - svga->readmode = 0; + for (c = 0; c < 256; c++) { + e = c; + for (d = 0; d < 8; d++) { + svga_rotate[d][c] = e; + e = (e >> 1) | ((e & 1) ? 0x80 : 0); + } + } + svga->readmode = 0; - svga->crtc[0] = 63; - svga->crtc[6] = 255; - svga->dispontime = 1000ull << 32; - svga->dispofftime = 1000ull << 32; - svga->bpp = 8; - svga->vram = malloc(memsize); - svga->vram_max = memsize; - svga->vram_display_mask = memsize - 1; - svga->vram_mask = memsize - 1; - svga->decode_mask = 0x7fffff; - svga->changedvram = malloc(/*(memsize >> 12) << 1*/0x1000000 >> 12); - svga->recalctimings_ex = recalctimings_ex; - svga->video_in = video_in; - svga->video_out = video_out; - svga->hwcursor_draw = hwcursor_draw; - svga->overlay_draw = overlay_draw; - svga->hwcursor.ysize = 64; - svga->ksc5601_english_font_type = 0; -// _svga_recalctimings(svga); + svga->crtc[0] = 63; + svga->crtc[6] = 255; + svga->dispontime = 1000ull << 32; + svga->dispofftime = 1000ull << 32; + svga->bpp = 8; + svga->vram = malloc(memsize); + svga->vram_max = memsize; + svga->vram_display_mask = memsize - 1; + svga->vram_mask = memsize - 1; + svga->decode_mask = 0x7fffff; + svga->changedvram = malloc(/*(memsize >> 12) << 1*/ 0x1000000 >> 12); + svga->recalctimings_ex = recalctimings_ex; + svga->video_in = video_in; + svga->video_out = video_out; + svga->hwcursor_draw = hwcursor_draw; + svga->overlay_draw = overlay_draw; + svga->hwcursor.ysize = 64; + svga->ksc5601_english_font_type = 0; + // _svga_recalctimings(svga); - mem_mapping_add(&svga->mapping, 0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL, MEM_MAPPING_EXTERNAL, svga); + mem_mapping_add(&svga->mapping, 0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, + NULL, MEM_MAPPING_EXTERNAL, svga); - timer_add(&svga->timer, svga_poll, svga, 1); + timer_add(&svga->timer, svga_poll, svga, 1); - svga_pri = svga; + svga_pri = svga; - svga->ramdac_type = RAMDAC_6BIT; + svga->ramdac_type = RAMDAC_6BIT; - return 0; + return 0; } void svga_close(svga_t *svga) { - free(svga->changedvram); - free(svga->vram); + free(svga->changedvram); + free(svga->vram); - svga_pri = NULL; + svga_pri = NULL; } void svga_write(uint32_t addr, uint8_t val, void *p) { - svga_t *svga = (svga_t *)p; - uint8_t vala, valb, valc, vald, wm = svga->writemask; - int writemask2 = svga->writemask; + svga_t *svga = (svga_t *)p; + uint8_t vala, valb, valc, vald, wm = svga->writemask; + int writemask2 = svga->writemask; - egawrites++; + egawrites++; - cycles -= video_timing_write_b; - cycles_lost += video_timing_write_b; + cycles -= video_timing_write_b; + cycles_lost += video_timing_write_b; - if (svga_output) - pclog("Writeega %06X ", addr); - addr &= svga->banked_mask; - addr += svga->write_bank; + if (svga_output) + pclog("Writeega %06X ", addr); + addr &= svga->banked_mask; + addr += svga->write_bank; - if (!(svga->gdcreg[6] & 1)) - svga->fullchange = 2; - if ((svga->chain4 && svga->packed_chain4) || svga->fb_only) { - writemask2 = 1 << (addr & 3); - addr &= ~3; - } else if (svga->chain4) { - writemask2 = 1 << (addr & 3); - addr &= ~3; - addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff); - } else if (svga->chain2_write) { - writemask2 &= ~0xa; - if (addr & 1) - writemask2 <<= 1; - addr &= ~1; - addr <<= 2; - } else { - addr <<= 2; - } - addr &= svga->decode_mask; + if (!(svga->gdcreg[6] & 1)) + svga->fullchange = 2; + if ((svga->chain4 && svga->packed_chain4) || svga->fb_only) { + writemask2 = 1 << (addr & 3); + addr &= ~3; + } else if (svga->chain4) { + writemask2 = 1 << (addr & 3); + addr &= ~3; + addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff); + } else if (svga->chain2_write) { + writemask2 &= ~0xa; + if (addr & 1) + writemask2 <<= 1; + addr &= ~1; + addr <<= 2; + } else { + addr <<= 2; + } + addr &= svga->decode_mask; - if (addr >= svga->vram_max) - return; + if (addr >= svga->vram_max) + return; - addr &= svga->vram_mask; + addr &= svga->vram_mask; - if (svga_output) - pclog("%08X (%i, %i) %02X %i %i %i %02X\n", addr, addr & 1023, addr >> 10, val, writemask2, svga->writemode, svga->chain4, svga->gdcreg[8]); - svga->changedvram[addr >> 12] = changeframecount; + if (svga_output) + pclog("%08X (%i, %i) %02X %i %i %i %02X\n", addr, addr & 1023, addr >> 10, val, writemask2, svga->writemode, + svga->chain4, svga->gdcreg[8]); + svga->changedvram[addr >> 12] = changeframecount; - switch (svga->writemode) { - case 1: - if (writemask2 & 1) - svga->vram[addr] = svga->la; - if (writemask2 & 2) - svga->vram[addr | 0x1] = svga->lb; - if (writemask2 & 4) - svga->vram[addr | 0x2] = svga->lc; - if (writemask2 & 8) - svga->vram[addr | 0x3] = svga->ld; - break; - case 0: - if (svga->gdcreg[3] & 7) - val = svga_rotate[svga->gdcreg[3] & 7][val]; - if (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && (!svga->gdcreg[1] || svga->set_reset_disabled)) { - if (writemask2 & 1) - svga->vram[addr] = val; - if (writemask2 & 2) - svga->vram[addr | 0x1] = val; - if (writemask2 & 4) - svga->vram[addr | 0x2] = val; - if (writemask2 & 8) - svga->vram[addr | 0x3] = val; - } else { - if (svga->gdcreg[1] & 1) - vala = (svga->gdcreg[0] & 1) ? 0xff : 0; - else - vala = val; - if (svga->gdcreg[1] & 2) - valb = (svga->gdcreg[0] & 2) ? 0xff : 0; - else - valb = val; - if (svga->gdcreg[1] & 4) - valc = (svga->gdcreg[0] & 4) ? 0xff : 0; - else - valc = val; - if (svga->gdcreg[1] & 8) - vald = (svga->gdcreg[0] & 8) ? 0xff : 0; - else - vald = val; + switch (svga->writemode) { + case 1: + if (writemask2 & 1) + svga->vram[addr] = svga->la; + if (writemask2 & 2) + svga->vram[addr | 0x1] = svga->lb; + if (writemask2 & 4) + svga->vram[addr | 0x2] = svga->lc; + if (writemask2 & 8) + svga->vram[addr | 0x3] = svga->ld; + break; + case 0: + if (svga->gdcreg[3] & 7) + val = svga_rotate[svga->gdcreg[3] & 7][val]; + if (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && (!svga->gdcreg[1] || svga->set_reset_disabled)) { + if (writemask2 & 1) + svga->vram[addr] = val; + if (writemask2 & 2) + svga->vram[addr | 0x1] = val; + if (writemask2 & 4) + svga->vram[addr | 0x2] = val; + if (writemask2 & 8) + svga->vram[addr | 0x3] = val; + } else { + if (svga->gdcreg[1] & 1) + vala = (svga->gdcreg[0] & 1) ? 0xff : 0; + else + vala = val; + if (svga->gdcreg[1] & 2) + valb = (svga->gdcreg[0] & 2) ? 0xff : 0; + else + valb = val; + if (svga->gdcreg[1] & 4) + valc = (svga->gdcreg[0] & 4) ? 0xff : 0; + else + valc = val; + if (svga->gdcreg[1] & 8) + vald = (svga->gdcreg[0] & 8) ? 0xff : 0; + else + vald = val; - switch (svga->gdcreg[3] & 0x18) { - case 0: /*Set*/ - if (writemask2 & 1) - svga->vram[addr] = (vala & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]); - if (writemask2 & 2) - svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]); - if (writemask2 & 4) - svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]); - if (writemask2 & 8) - svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]); - break; - case 8: /*AND*/ - if (writemask2 & 1) - svga->vram[addr] = (vala | ~svga->gdcreg[8]) & svga->la; - if (writemask2 & 2) - svga->vram[addr | 0x1] = (valb | ~svga->gdcreg[8]) & svga->lb; - if (writemask2 & 4) - svga->vram[addr | 0x2] = (valc | ~svga->gdcreg[8]) & svga->lc; - if (writemask2 & 8) - svga->vram[addr | 0x3] = (vald | ~svga->gdcreg[8]) & svga->ld; - break; - case 0x10: /*OR*/ - if (writemask2 & 1) - svga->vram[addr] = (vala & svga->gdcreg[8]) | svga->la; - if (writemask2 & 2) - svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | svga->lb; - if (writemask2 & 4) - svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | svga->lc; - if (writemask2 & 8) - svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | svga->ld; - break; - case 0x18: /*XOR*/ - if (writemask2 & 1) - svga->vram[addr] = (vala & svga->gdcreg[8]) ^ svga->la; - if (writemask2 & 2) - svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) ^ svga->lb; - if (writemask2 & 4) - svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) ^ svga->lc; - if (writemask2 & 8) - svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) ^ svga->ld; - break; - } -// pclog("- %02X %02X %02X %02X %08X\n",vram[addr],vram[addr|0x1],vram[addr|0x2],vram[addr|0x3],addr); - } - break; - case 2: - if (!(svga->gdcreg[3] & 0x18) && (!svga->gdcreg[1] || svga->set_reset_disabled)) { - if (writemask2 & 1) - svga->vram[addr] = (((val & 1) ? 0xff : 0) & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]); - if (writemask2 & 2) - svga->vram[addr | 0x1] = (((val & 2) ? 0xff : 0) & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]); - if (writemask2 & 4) - svga->vram[addr | 0x2] = (((val & 4) ? 0xff : 0) & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]); - if (writemask2 & 8) - svga->vram[addr | 0x3] = (((val & 8) ? 0xff : 0) & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]); - } else { - vala = ((val & 1) ? 0xff : 0); - valb = ((val & 2) ? 0xff : 0); - valc = ((val & 4) ? 0xff : 0); - vald = ((val & 8) ? 0xff : 0); - switch (svga->gdcreg[3] & 0x18) { - case 0: /*Set*/ - if (writemask2 & 1) - svga->vram[addr] = (vala & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]); - if (writemask2 & 2) - svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]); - if (writemask2 & 4) - svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]); - if (writemask2 & 8) - svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]); - break; - case 8: /*AND*/ - if (writemask2 & 1) - svga->vram[addr] = (vala | ~svga->gdcreg[8]) & svga->la; - if (writemask2 & 2) - svga->vram[addr | 0x1] = (valb | ~svga->gdcreg[8]) & svga->lb; - if (writemask2 & 4) - svga->vram[addr | 0x2] = (valc | ~svga->gdcreg[8]) & svga->lc; - if (writemask2 & 8) - svga->vram[addr | 0x3] = (vald | ~svga->gdcreg[8]) & svga->ld; - break; - case 0x10: /*OR*/ - if (writemask2 & 1) - svga->vram[addr] = (vala & svga->gdcreg[8]) | svga->la; - if (writemask2 & 2) - svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | svga->lb; - if (writemask2 & 4) - svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | svga->lc; - if (writemask2 & 8) - svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | svga->ld; - break; - case 0x18: /*XOR*/ - if (writemask2 & 1) - svga->vram[addr] = (vala & svga->gdcreg[8]) ^ svga->la; - if (writemask2 & 2) - svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) ^ svga->lb; - if (writemask2 & 4) - svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) ^ svga->lc; - if (writemask2 & 8) - svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) ^ svga->ld; - break; - } - } - break; - case 3: - if (svga->gdcreg[3] & 7) - val = svga_rotate[svga->gdcreg[3] & 7][val]; - wm = svga->gdcreg[8]; - svga->gdcreg[8] &= val; + switch (svga->gdcreg[3] & 0x18) { + case 0: /*Set*/ + if (writemask2 & 1) + svga->vram[addr] = (vala & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]); + if (writemask2 & 2) + svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]); + if (writemask2 & 4) + svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]); + if (writemask2 & 8) + svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]); + break; + case 8: /*AND*/ + if (writemask2 & 1) + svga->vram[addr] = (vala | ~svga->gdcreg[8]) & svga->la; + if (writemask2 & 2) + svga->vram[addr | 0x1] = (valb | ~svga->gdcreg[8]) & svga->lb; + if (writemask2 & 4) + svga->vram[addr | 0x2] = (valc | ~svga->gdcreg[8]) & svga->lc; + if (writemask2 & 8) + svga->vram[addr | 0x3] = (vald | ~svga->gdcreg[8]) & svga->ld; + break; + case 0x10: /*OR*/ + if (writemask2 & 1) + svga->vram[addr] = (vala & svga->gdcreg[8]) | svga->la; + if (writemask2 & 2) + svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | svga->lb; + if (writemask2 & 4) + svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | svga->lc; + if (writemask2 & 8) + svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | svga->ld; + break; + case 0x18: /*XOR*/ + if (writemask2 & 1) + svga->vram[addr] = (vala & svga->gdcreg[8]) ^ svga->la; + if (writemask2 & 2) + svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) ^ svga->lb; + if (writemask2 & 4) + svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) ^ svga->lc; + if (writemask2 & 8) + svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) ^ svga->ld; + break; + } + // pclog("- %02X %02X %02X %02X + // %08X\n",vram[addr],vram[addr|0x1],vram[addr|0x2],vram[addr|0x3],addr); + } + break; + case 2: + if (!(svga->gdcreg[3] & 0x18) && (!svga->gdcreg[1] || svga->set_reset_disabled)) { + if (writemask2 & 1) + svga->vram[addr] = (((val & 1) ? 0xff : 0) & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]); + if (writemask2 & 2) + svga->vram[addr | 0x1] = + (((val & 2) ? 0xff : 0) & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]); + if (writemask2 & 4) + svga->vram[addr | 0x2] = + (((val & 4) ? 0xff : 0) & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]); + if (writemask2 & 8) + svga->vram[addr | 0x3] = + (((val & 8) ? 0xff : 0) & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]); + } else { + vala = ((val & 1) ? 0xff : 0); + valb = ((val & 2) ? 0xff : 0); + valc = ((val & 4) ? 0xff : 0); + vald = ((val & 8) ? 0xff : 0); + switch (svga->gdcreg[3] & 0x18) { + case 0: /*Set*/ + if (writemask2 & 1) + svga->vram[addr] = (vala & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]); + if (writemask2 & 2) + svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]); + if (writemask2 & 4) + svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]); + if (writemask2 & 8) + svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]); + break; + case 8: /*AND*/ + if (writemask2 & 1) + svga->vram[addr] = (vala | ~svga->gdcreg[8]) & svga->la; + if (writemask2 & 2) + svga->vram[addr | 0x1] = (valb | ~svga->gdcreg[8]) & svga->lb; + if (writemask2 & 4) + svga->vram[addr | 0x2] = (valc | ~svga->gdcreg[8]) & svga->lc; + if (writemask2 & 8) + svga->vram[addr | 0x3] = (vald | ~svga->gdcreg[8]) & svga->ld; + break; + case 0x10: /*OR*/ + if (writemask2 & 1) + svga->vram[addr] = (vala & svga->gdcreg[8]) | svga->la; + if (writemask2 & 2) + svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | svga->lb; + if (writemask2 & 4) + svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | svga->lc; + if (writemask2 & 8) + svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | svga->ld; + break; + case 0x18: /*XOR*/ + if (writemask2 & 1) + svga->vram[addr] = (vala & svga->gdcreg[8]) ^ svga->la; + if (writemask2 & 2) + svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) ^ svga->lb; + if (writemask2 & 4) + svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) ^ svga->lc; + if (writemask2 & 8) + svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) ^ svga->ld; + break; + } + } + break; + case 3: + if (svga->gdcreg[3] & 7) + val = svga_rotate[svga->gdcreg[3] & 7][val]; + wm = svga->gdcreg[8]; + svga->gdcreg[8] &= val; - vala = (svga->gdcreg[0] & 1) ? 0xff : 0; - valb = (svga->gdcreg[0] & 2) ? 0xff : 0; - valc = (svga->gdcreg[0] & 4) ? 0xff : 0; - vald = (svga->gdcreg[0] & 8) ? 0xff : 0; - switch (svga->gdcreg[3] & 0x18) { - case 0: /*Set*/ - if (writemask2 & 1) - svga->vram[addr] = (vala & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]); - if (writemask2 & 2) - svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]); - if (writemask2 & 4) - svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]); - if (writemask2 & 8) - svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]); - break; - case 8: /*AND*/ - if (writemask2 & 1) - svga->vram[addr] = (vala | ~svga->gdcreg[8]) & svga->la; - if (writemask2 & 2) - svga->vram[addr | 0x1] = (valb | ~svga->gdcreg[8]) & svga->lb; - if (writemask2 & 4) - svga->vram[addr | 0x2] = (valc | ~svga->gdcreg[8]) & svga->lc; - if (writemask2 & 8) - svga->vram[addr | 0x3] = (vald | ~svga->gdcreg[8]) & svga->ld; - break; - case 0x10: /*OR*/ - if (writemask2 & 1) - svga->vram[addr] = (vala & svga->gdcreg[8]) | svga->la; - if (writemask2 & 2) - svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | svga->lb; - if (writemask2 & 4) - svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | svga->lc; - if (writemask2 & 8) - svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | svga->ld; - break; - case 0x18: /*XOR*/ - if (writemask2 & 1) - svga->vram[addr] = (vala & svga->gdcreg[8]) ^ svga->la; - if (writemask2 & 2) - svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) ^ svga->lb; - if (writemask2 & 4) - svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) ^ svga->lc; - if (writemask2 & 8) - svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) ^ svga->ld; - break; - } - svga->gdcreg[8] = wm; - break; - } + vala = (svga->gdcreg[0] & 1) ? 0xff : 0; + valb = (svga->gdcreg[0] & 2) ? 0xff : 0; + valc = (svga->gdcreg[0] & 4) ? 0xff : 0; + vald = (svga->gdcreg[0] & 8) ? 0xff : 0; + switch (svga->gdcreg[3] & 0x18) { + case 0: /*Set*/ + if (writemask2 & 1) + svga->vram[addr] = (vala & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]); + if (writemask2 & 2) + svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]); + if (writemask2 & 4) + svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]); + if (writemask2 & 8) + svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]); + break; + case 8: /*AND*/ + if (writemask2 & 1) + svga->vram[addr] = (vala | ~svga->gdcreg[8]) & svga->la; + if (writemask2 & 2) + svga->vram[addr | 0x1] = (valb | ~svga->gdcreg[8]) & svga->lb; + if (writemask2 & 4) + svga->vram[addr | 0x2] = (valc | ~svga->gdcreg[8]) & svga->lc; + if (writemask2 & 8) + svga->vram[addr | 0x3] = (vald | ~svga->gdcreg[8]) & svga->ld; + break; + case 0x10: /*OR*/ + if (writemask2 & 1) + svga->vram[addr] = (vala & svga->gdcreg[8]) | svga->la; + if (writemask2 & 2) + svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | svga->lb; + if (writemask2 & 4) + svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | svga->lc; + if (writemask2 & 8) + svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | svga->ld; + break; + case 0x18: /*XOR*/ + if (writemask2 & 1) + svga->vram[addr] = (vala & svga->gdcreg[8]) ^ svga->la; + if (writemask2 & 2) + svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) ^ svga->lb; + if (writemask2 & 4) + svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) ^ svga->lc; + if (writemask2 & 8) + svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) ^ svga->ld; + break; + } + svga->gdcreg[8] = wm; + break; + } } uint8_t svga_read(uint32_t addr, void *p) { - svga_t *svga = (svga_t *)p; - uint8_t temp, temp2, temp3, temp4; - uint32_t latch_addr; - int readplane = svga->readplane; + svga_t *svga = (svga_t *)p; + uint8_t temp, temp2, temp3, temp4; + uint32_t latch_addr; + int readplane = svga->readplane; - cycles -= video_timing_read_b; - cycles_lost += video_timing_read_b; + cycles -= video_timing_read_b; + cycles_lost += video_timing_read_b; - egareads++; -// pclog("Readega %06X ",addr); + egareads++; + // pclog("Readega %06X ",addr); - addr &= svga->banked_mask; - addr += svga->read_bank; + addr &= svga->banked_mask; + addr += svga->read_bank; - latch_addr = (addr << 2) & svga->decode_mask; + latch_addr = (addr << 2) & svga->decode_mask; -// pclog("%05X %i %04X:%04X %02X %02X %i\n",addr,svga->chain4,CS,pc, vram[addr & 0x7fffff], vram[(addr << 2) & 0x7fffff], svga->readmode); -// pclog("%i\n", svga->readmode); - if ((svga->chain4 && svga->packed_chain4) || svga->fb_only) { - addr &= svga->decode_mask; - if (addr >= svga->vram_max) - return 0xff; - latch_addr = addr & svga->vram_mask & ~3; - svga->la = svga->vram[latch_addr]; - svga->lb = svga->vram[latch_addr | 0x1]; - svga->lc = svga->vram[latch_addr | 0x2]; - svga->ld = svga->vram[latch_addr | 0x3]; - return svga->vram[addr & svga->vram_mask]; - } else if (svga->chain4) { - readplane = addr & 3; - addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff); - } else if (svga->chain2_read) { - readplane = (readplane & 2) | (addr & 1); - addr &= ~1; - addr <<= 2; - } else - addr <<= 2; + // pclog("%05X %i %04X:%04X %02X %02X %i\n",addr,svga->chain4,CS,pc, vram[addr & 0x7fffff], vram[(addr << 2) & + // 0x7fffff], svga->readmode); pclog("%i\n", svga->readmode); + if ((svga->chain4 && svga->packed_chain4) || svga->fb_only) { + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return 0xff; + latch_addr = addr & svga->vram_mask & ~3; + svga->la = svga->vram[latch_addr]; + svga->lb = svga->vram[latch_addr | 0x1]; + svga->lc = svga->vram[latch_addr | 0x2]; + svga->ld = svga->vram[latch_addr | 0x3]; + return svga->vram[addr & svga->vram_mask]; + } else if (svga->chain4) { + readplane = addr & 3; + addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff); + } else if (svga->chain2_read) { + readplane = (readplane & 2) | (addr & 1); + addr &= ~1; + addr <<= 2; + } else + addr <<= 2; - addr &= svga->decode_mask; + addr &= svga->decode_mask; - if (latch_addr >= svga->vram_max) { - svga->la = svga->lb = svga->lc = svga->ld = 0xff; - } else { - latch_addr &= svga->vram_mask; - svga->la = svga->vram[latch_addr]; - svga->lb = svga->vram[latch_addr | 0x1]; - svga->lc = svga->vram[latch_addr | 0x2]; - svga->ld = svga->vram[latch_addr | 0x3]; - } + if (latch_addr >= svga->vram_max) { + svga->la = svga->lb = svga->lc = svga->ld = 0xff; + } else { + latch_addr &= svga->vram_mask; + svga->la = svga->vram[latch_addr]; + svga->lb = svga->vram[latch_addr | 0x1]; + svga->lc = svga->vram[latch_addr | 0x2]; + svga->ld = svga->vram[latch_addr | 0x3]; + } - if (addr >= svga->vram_max) - return 0xff; + if (addr >= svga->vram_max) + return 0xff; - addr &= svga->vram_mask; + addr &= svga->vram_mask; - if (svga->readmode) { - temp = svga->la; - temp ^= (svga->colourcompare & 1) ? 0xff : 0; - temp &= (svga->colournocare & 1) ? 0xff : 0; - temp2 = svga->lb; - temp2 ^= (svga->colourcompare & 2) ? 0xff : 0; - temp2 &= (svga->colournocare & 2) ? 0xff : 0; - temp3 = svga->lc; - temp3 ^= (svga->colourcompare & 4) ? 0xff : 0; - temp3 &= (svga->colournocare & 4) ? 0xff : 0; - temp4 = svga->ld; - temp4 ^= (svga->colourcompare & 8) ? 0xff : 0; - temp4 &= (svga->colournocare & 8) ? 0xff : 0; - return ~(temp | temp2 | temp3 | temp4); - } -//pclog("Read %02X %04X %04X\n",vram[addr|svga->readplane],addr,svga->readplane); - return svga->vram[addr | readplane]; + if (svga->readmode) { + temp = svga->la; + temp ^= (svga->colourcompare & 1) ? 0xff : 0; + temp &= (svga->colournocare & 1) ? 0xff : 0; + temp2 = svga->lb; + temp2 ^= (svga->colourcompare & 2) ? 0xff : 0; + temp2 &= (svga->colournocare & 2) ? 0xff : 0; + temp3 = svga->lc; + temp3 ^= (svga->colourcompare & 4) ? 0xff : 0; + temp3 &= (svga->colournocare & 4) ? 0xff : 0; + temp4 = svga->ld; + temp4 ^= (svga->colourcompare & 8) ? 0xff : 0; + temp4 &= (svga->colournocare & 8) ? 0xff : 0; + return ~(temp | temp2 | temp3 | temp4); + } + // pclog("Read %02X %04X %04X\n",vram[addr|svga->readplane],addr,svga->readplane); + return svga->vram[addr | readplane]; } void svga_write_linear(uint32_t addr, uint8_t val, void *p) { - svga_t *svga = (svga_t *)p; - uint8_t vala, valb, valc, vald, wm = svga->writemask; - int writemask2 = svga->writemask; + svga_t *svga = (svga_t *)p; + uint8_t vala, valb, valc, vald, wm = svga->writemask; + int writemask2 = svga->writemask; - cycles -= video_timing_write_b; - cycles_lost += video_timing_write_b; + cycles -= video_timing_write_b; + cycles_lost += video_timing_write_b; - egawrites++; + egawrites++; - if (svga_output) - pclog("Write LFB %08X %02X ", addr, val); - if (!(svga->gdcreg[6] & 1)) - svga->fullchange = 2; - if ((svga->chain4 && svga->packed_chain4) || svga->fb_only) { - writemask2 = 1 << (addr & 3); - addr &= ~3; - } else if (svga->chain4) { - writemask2 = 1 << (addr & 3); - addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff); - } else if (svga->chain2_write) { - writemask2 &= ~0xa; - if (addr & 1) - writemask2 <<= 1; - addr &= ~1; - addr <<= 2; - } else { - addr <<= 2; - } - addr &= svga->decode_mask; - if (addr >= svga->vram_max) - return; - addr &= svga->vram_mask; - if (svga_output) - pclog("%08X\n", addr); - svga->changedvram[addr >> 12] = changeframecount; + if (svga_output) + pclog("Write LFB %08X %02X ", addr, val); + if (!(svga->gdcreg[6] & 1)) + svga->fullchange = 2; + if ((svga->chain4 && svga->packed_chain4) || svga->fb_only) { + writemask2 = 1 << (addr & 3); + addr &= ~3; + } else if (svga->chain4) { + writemask2 = 1 << (addr & 3); + addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff); + } else if (svga->chain2_write) { + writemask2 &= ~0xa; + if (addr & 1) + writemask2 <<= 1; + addr &= ~1; + addr <<= 2; + } else { + addr <<= 2; + } + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return; + addr &= svga->vram_mask; + if (svga_output) + pclog("%08X\n", addr); + svga->changedvram[addr >> 12] = changeframecount; - switch (svga->writemode) { - case 1: - if (writemask2 & 1) - svga->vram[addr] = svga->la; - if (writemask2 & 2) - svga->vram[addr | 0x1] = svga->lb; - if (writemask2 & 4) - svga->vram[addr | 0x2] = svga->lc; - if (writemask2 & 8) - svga->vram[addr | 0x3] = svga->ld; - break; - case 0: - if (svga->gdcreg[3] & 7) - val = svga_rotate[svga->gdcreg[3] & 7][val]; - if (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && (!svga->gdcreg[1] || svga->set_reset_disabled)) { - if (writemask2 & 1) - svga->vram[addr] = val; - if (writemask2 & 2) - svga->vram[addr | 0x1] = val; - if (writemask2 & 4) - svga->vram[addr | 0x2] = val; - if (writemask2 & 8) - svga->vram[addr | 0x3] = val; - } else { - if (svga->gdcreg[1] & 1) - vala = (svga->gdcreg[0] & 1) ? 0xff : 0; - else - vala = val; - if (svga->gdcreg[1] & 2) - valb = (svga->gdcreg[0] & 2) ? 0xff : 0; - else - valb = val; - if (svga->gdcreg[1] & 4) - valc = (svga->gdcreg[0] & 4) ? 0xff : 0; - else - valc = val; - if (svga->gdcreg[1] & 8) - vald = (svga->gdcreg[0] & 8) ? 0xff : 0; - else - vald = val; + switch (svga->writemode) { + case 1: + if (writemask2 & 1) + svga->vram[addr] = svga->la; + if (writemask2 & 2) + svga->vram[addr | 0x1] = svga->lb; + if (writemask2 & 4) + svga->vram[addr | 0x2] = svga->lc; + if (writemask2 & 8) + svga->vram[addr | 0x3] = svga->ld; + break; + case 0: + if (svga->gdcreg[3] & 7) + val = svga_rotate[svga->gdcreg[3] & 7][val]; + if (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && (!svga->gdcreg[1] || svga->set_reset_disabled)) { + if (writemask2 & 1) + svga->vram[addr] = val; + if (writemask2 & 2) + svga->vram[addr | 0x1] = val; + if (writemask2 & 4) + svga->vram[addr | 0x2] = val; + if (writemask2 & 8) + svga->vram[addr | 0x3] = val; + } else { + if (svga->gdcreg[1] & 1) + vala = (svga->gdcreg[0] & 1) ? 0xff : 0; + else + vala = val; + if (svga->gdcreg[1] & 2) + valb = (svga->gdcreg[0] & 2) ? 0xff : 0; + else + valb = val; + if (svga->gdcreg[1] & 4) + valc = (svga->gdcreg[0] & 4) ? 0xff : 0; + else + valc = val; + if (svga->gdcreg[1] & 8) + vald = (svga->gdcreg[0] & 8) ? 0xff : 0; + else + vald = val; - switch (svga->gdcreg[3] & 0x18) { - case 0: /*Set*/ - if (writemask2 & 1) - svga->vram[addr] = (vala & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]); - if (writemask2 & 2) - svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]); - if (writemask2 & 4) - svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]); - if (writemask2 & 8) - svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]); - break; - case 8: /*AND*/ - if (writemask2 & 1) - svga->vram[addr] = (vala | ~svga->gdcreg[8]) & svga->la; - if (writemask2 & 2) - svga->vram[addr | 0x1] = (valb | ~svga->gdcreg[8]) & svga->lb; - if (writemask2 & 4) - svga->vram[addr | 0x2] = (valc | ~svga->gdcreg[8]) & svga->lc; - if (writemask2 & 8) - svga->vram[addr | 0x3] = (vald | ~svga->gdcreg[8]) & svga->ld; - break; - case 0x10: /*OR*/ - if (writemask2 & 1) - svga->vram[addr] = (vala & svga->gdcreg[8]) | svga->la; - if (writemask2 & 2) - svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | svga->lb; - if (writemask2 & 4) - svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | svga->lc; - if (writemask2 & 8) - svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | svga->ld; - break; - case 0x18: /*XOR*/ - if (writemask2 & 1) - svga->vram[addr] = (vala & svga->gdcreg[8]) ^ svga->la; - if (writemask2 & 2) - svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) ^ svga->lb; - if (writemask2 & 4) - svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) ^ svga->lc; - if (writemask2 & 8) - svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) ^ svga->ld; - break; - } -// pclog("- %02X %02X %02X %02X %08X\n",vram[addr],vram[addr|0x1],vram[addr|0x2],vram[addr|0x3],addr); - } - break; - case 2: - if (!(svga->gdcreg[3] & 0x18) && (!svga->gdcreg[1] || svga->set_reset_disabled)) { - if (writemask2 & 1) - svga->vram[addr] = (((val & 1) ? 0xff : 0) & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]); - if (writemask2 & 2) - svga->vram[addr | 0x1] = (((val & 2) ? 0xff : 0) & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]); - if (writemask2 & 4) - svga->vram[addr | 0x2] = (((val & 4) ? 0xff : 0) & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]); - if (writemask2 & 8) - svga->vram[addr | 0x3] = (((val & 8) ? 0xff : 0) & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]); - } else { - vala = ((val & 1) ? 0xff : 0); - valb = ((val & 2) ? 0xff : 0); - valc = ((val & 4) ? 0xff : 0); - vald = ((val & 8) ? 0xff : 0); - switch (svga->gdcreg[3] & 0x18) { - case 0: /*Set*/ - if (writemask2 & 1) - svga->vram[addr] = (vala & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]); - if (writemask2 & 2) - svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]); - if (writemask2 & 4) - svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]); - if (writemask2 & 8) - svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]); - break; - case 8: /*AND*/ - if (writemask2 & 1) - svga->vram[addr] = (vala | ~svga->gdcreg[8]) & svga->la; - if (writemask2 & 2) - svga->vram[addr | 0x1] = (valb | ~svga->gdcreg[8]) & svga->lb; - if (writemask2 & 4) - svga->vram[addr | 0x2] = (valc | ~svga->gdcreg[8]) & svga->lc; - if (writemask2 & 8) - svga->vram[addr | 0x3] = (vald | ~svga->gdcreg[8]) & svga->ld; - break; - case 0x10: /*OR*/ - if (writemask2 & 1) - svga->vram[addr] = (vala & svga->gdcreg[8]) | svga->la; - if (writemask2 & 2) - svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | svga->lb; - if (writemask2 & 4) - svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | svga->lc; - if (writemask2 & 8) - svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | svga->ld; - break; - case 0x18: /*XOR*/ - if (writemask2 & 1) - svga->vram[addr] = (vala & svga->gdcreg[8]) ^ svga->la; - if (writemask2 & 2) - svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) ^ svga->lb; - if (writemask2 & 4) - svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) ^ svga->lc; - if (writemask2 & 8) - svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) ^ svga->ld; - break; - } - } - break; - case 3: - if (svga->gdcreg[3] & 7) - val = svga_rotate[svga->gdcreg[3] & 7][val]; - wm = svga->gdcreg[8]; - svga->gdcreg[8] &= val; + switch (svga->gdcreg[3] & 0x18) { + case 0: /*Set*/ + if (writemask2 & 1) + svga->vram[addr] = (vala & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]); + if (writemask2 & 2) + svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]); + if (writemask2 & 4) + svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]); + if (writemask2 & 8) + svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]); + break; + case 8: /*AND*/ + if (writemask2 & 1) + svga->vram[addr] = (vala | ~svga->gdcreg[8]) & svga->la; + if (writemask2 & 2) + svga->vram[addr | 0x1] = (valb | ~svga->gdcreg[8]) & svga->lb; + if (writemask2 & 4) + svga->vram[addr | 0x2] = (valc | ~svga->gdcreg[8]) & svga->lc; + if (writemask2 & 8) + svga->vram[addr | 0x3] = (vald | ~svga->gdcreg[8]) & svga->ld; + break; + case 0x10: /*OR*/ + if (writemask2 & 1) + svga->vram[addr] = (vala & svga->gdcreg[8]) | svga->la; + if (writemask2 & 2) + svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | svga->lb; + if (writemask2 & 4) + svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | svga->lc; + if (writemask2 & 8) + svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | svga->ld; + break; + case 0x18: /*XOR*/ + if (writemask2 & 1) + svga->vram[addr] = (vala & svga->gdcreg[8]) ^ svga->la; + if (writemask2 & 2) + svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) ^ svga->lb; + if (writemask2 & 4) + svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) ^ svga->lc; + if (writemask2 & 8) + svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) ^ svga->ld; + break; + } + // pclog("- %02X %02X %02X %02X + // %08X\n",vram[addr],vram[addr|0x1],vram[addr|0x2],vram[addr|0x3],addr); + } + break; + case 2: + if (!(svga->gdcreg[3] & 0x18) && (!svga->gdcreg[1] || svga->set_reset_disabled)) { + if (writemask2 & 1) + svga->vram[addr] = (((val & 1) ? 0xff : 0) & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]); + if (writemask2 & 2) + svga->vram[addr | 0x1] = + (((val & 2) ? 0xff : 0) & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]); + if (writemask2 & 4) + svga->vram[addr | 0x2] = + (((val & 4) ? 0xff : 0) & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]); + if (writemask2 & 8) + svga->vram[addr | 0x3] = + (((val & 8) ? 0xff : 0) & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]); + } else { + vala = ((val & 1) ? 0xff : 0); + valb = ((val & 2) ? 0xff : 0); + valc = ((val & 4) ? 0xff : 0); + vald = ((val & 8) ? 0xff : 0); + switch (svga->gdcreg[3] & 0x18) { + case 0: /*Set*/ + if (writemask2 & 1) + svga->vram[addr] = (vala & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]); + if (writemask2 & 2) + svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]); + if (writemask2 & 4) + svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]); + if (writemask2 & 8) + svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]); + break; + case 8: /*AND*/ + if (writemask2 & 1) + svga->vram[addr] = (vala | ~svga->gdcreg[8]) & svga->la; + if (writemask2 & 2) + svga->vram[addr | 0x1] = (valb | ~svga->gdcreg[8]) & svga->lb; + if (writemask2 & 4) + svga->vram[addr | 0x2] = (valc | ~svga->gdcreg[8]) & svga->lc; + if (writemask2 & 8) + svga->vram[addr | 0x3] = (vald | ~svga->gdcreg[8]) & svga->ld; + break; + case 0x10: /*OR*/ + if (writemask2 & 1) + svga->vram[addr] = (vala & svga->gdcreg[8]) | svga->la; + if (writemask2 & 2) + svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | svga->lb; + if (writemask2 & 4) + svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | svga->lc; + if (writemask2 & 8) + svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | svga->ld; + break; + case 0x18: /*XOR*/ + if (writemask2 & 1) + svga->vram[addr] = (vala & svga->gdcreg[8]) ^ svga->la; + if (writemask2 & 2) + svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) ^ svga->lb; + if (writemask2 & 4) + svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) ^ svga->lc; + if (writemask2 & 8) + svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) ^ svga->ld; + break; + } + } + break; + case 3: + if (svga->gdcreg[3] & 7) + val = svga_rotate[svga->gdcreg[3] & 7][val]; + wm = svga->gdcreg[8]; + svga->gdcreg[8] &= val; - vala = (svga->gdcreg[0] & 1) ? 0xff : 0; - valb = (svga->gdcreg[0] & 2) ? 0xff : 0; - valc = (svga->gdcreg[0] & 4) ? 0xff : 0; - vald = (svga->gdcreg[0] & 8) ? 0xff : 0; - switch (svga->gdcreg[3] & 0x18) { - case 0: /*Set*/ - if (writemask2 & 1) - svga->vram[addr] = (vala & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]); - if (writemask2 & 2) - svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]); - if (writemask2 & 4) - svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]); - if (writemask2 & 8) - svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]); - break; - case 8: /*AND*/ - if (writemask2 & 1) - svga->vram[addr] = (vala | ~svga->gdcreg[8]) & svga->la; - if (writemask2 & 2) - svga->vram[addr | 0x1] = (valb | ~svga->gdcreg[8]) & svga->lb; - if (writemask2 & 4) - svga->vram[addr | 0x2] = (valc | ~svga->gdcreg[8]) & svga->lc; - if (writemask2 & 8) - svga->vram[addr | 0x3] = (vald | ~svga->gdcreg[8]) & svga->ld; - break; - case 0x10: /*OR*/ - if (writemask2 & 1) - svga->vram[addr] = (vala & svga->gdcreg[8]) | svga->la; - if (writemask2 & 2) - svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | svga->lb; - if (writemask2 & 4) - svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | svga->lc; - if (writemask2 & 8) - svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | svga->ld; - break; - case 0x18: /*XOR*/ - if (writemask2 & 1) - svga->vram[addr] = (vala & svga->gdcreg[8]) ^ svga->la; - if (writemask2 & 2) - svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) ^ svga->lb; - if (writemask2 & 4) - svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) ^ svga->lc; - if (writemask2 & 8) - svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) ^ svga->ld; - break; - } - svga->gdcreg[8] = wm; - break; - } + vala = (svga->gdcreg[0] & 1) ? 0xff : 0; + valb = (svga->gdcreg[0] & 2) ? 0xff : 0; + valc = (svga->gdcreg[0] & 4) ? 0xff : 0; + vald = (svga->gdcreg[0] & 8) ? 0xff : 0; + switch (svga->gdcreg[3] & 0x18) { + case 0: /*Set*/ + if (writemask2 & 1) + svga->vram[addr] = (vala & svga->gdcreg[8]) | (svga->la & ~svga->gdcreg[8]); + if (writemask2 & 2) + svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | (svga->lb & ~svga->gdcreg[8]); + if (writemask2 & 4) + svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | (svga->lc & ~svga->gdcreg[8]); + if (writemask2 & 8) + svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | (svga->ld & ~svga->gdcreg[8]); + break; + case 8: /*AND*/ + if (writemask2 & 1) + svga->vram[addr] = (vala | ~svga->gdcreg[8]) & svga->la; + if (writemask2 & 2) + svga->vram[addr | 0x1] = (valb | ~svga->gdcreg[8]) & svga->lb; + if (writemask2 & 4) + svga->vram[addr | 0x2] = (valc | ~svga->gdcreg[8]) & svga->lc; + if (writemask2 & 8) + svga->vram[addr | 0x3] = (vald | ~svga->gdcreg[8]) & svga->ld; + break; + case 0x10: /*OR*/ + if (writemask2 & 1) + svga->vram[addr] = (vala & svga->gdcreg[8]) | svga->la; + if (writemask2 & 2) + svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) | svga->lb; + if (writemask2 & 4) + svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) | svga->lc; + if (writemask2 & 8) + svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) | svga->ld; + break; + case 0x18: /*XOR*/ + if (writemask2 & 1) + svga->vram[addr] = (vala & svga->gdcreg[8]) ^ svga->la; + if (writemask2 & 2) + svga->vram[addr | 0x1] = (valb & svga->gdcreg[8]) ^ svga->lb; + if (writemask2 & 4) + svga->vram[addr | 0x2] = (valc & svga->gdcreg[8]) ^ svga->lc; + if (writemask2 & 8) + svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) ^ svga->ld; + break; + } + svga->gdcreg[8] = wm; + break; + } } uint8_t svga_read_linear(uint32_t addr, void *p) { - svga_t *svga = (svga_t *)p; - uint8_t temp, temp2, temp3, temp4; - int readplane = svga->readplane; - uint32_t latch_addr = (addr << 2) & svga->decode_mask; + svga_t *svga = (svga_t *)p; + uint8_t temp, temp2, temp3, temp4; + int readplane = svga->readplane; + uint32_t latch_addr = (addr << 2) & svga->decode_mask; - cycles -= video_timing_read_b; - cycles_lost += video_timing_read_b; + cycles -= video_timing_read_b; + cycles_lost += video_timing_read_b; - egareads++; + egareads++; - if ((svga->chain4 && svga->packed_chain4) || svga->fb_only) { - addr &= svga->decode_mask; - if (addr >= svga->vram_max) - return 0xff; - return svga->vram[addr & svga->vram_mask]; - } else if (svga->chain4) { - readplane = addr & 3; - addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff); - } else if (svga->chain2_read) { - readplane = (readplane & 2) | (addr & 1); - addr &= ~1; - addr <<= 2; - } else { - addr <<= 2; - } + if ((svga->chain4 && svga->packed_chain4) || svga->fb_only) { + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return 0xff; + return svga->vram[addr & svga->vram_mask]; + } else if (svga->chain4) { + readplane = addr & 3; + addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff); + } else if (svga->chain2_read) { + readplane = (readplane & 2) | (addr & 1); + addr &= ~1; + addr <<= 2; + } else { + addr <<= 2; + } - addr &= svga->decode_mask; + addr &= svga->decode_mask; - if (latch_addr >= svga->vram_max) { - svga->la = svga->lb = svga->lc = svga->ld = 0xff; - } else { - latch_addr &= svga->vram_mask; - svga->la = svga->vram[latch_addr]; - svga->lb = svga->vram[latch_addr | 0x1]; - svga->lc = svga->vram[latch_addr | 0x2]; - svga->ld = svga->vram[latch_addr | 0x3]; - } + if (latch_addr >= svga->vram_max) { + svga->la = svga->lb = svga->lc = svga->ld = 0xff; + } else { + latch_addr &= svga->vram_mask; + svga->la = svga->vram[latch_addr]; + svga->lb = svga->vram[latch_addr | 0x1]; + svga->lc = svga->vram[latch_addr | 0x2]; + svga->ld = svga->vram[latch_addr | 0x3]; + } - if (addr >= svga->vram_max) - return 0xff; + if (addr >= svga->vram_max) + return 0xff; - addr &= svga->vram_mask; + addr &= svga->vram_mask; - if (svga->readmode) { - temp = svga->la; - temp ^= (svga->colourcompare & 1) ? 0xff : 0; - temp &= (svga->colournocare & 1) ? 0xff : 0; - temp2 = svga->lb; - temp2 ^= (svga->colourcompare & 2) ? 0xff : 0; - temp2 &= (svga->colournocare & 2) ? 0xff : 0; - temp3 = svga->lc; - temp3 ^= (svga->colourcompare & 4) ? 0xff : 0; - temp3 &= (svga->colournocare & 4) ? 0xff : 0; - temp4 = svga->ld; - temp4 ^= (svga->colourcompare & 8) ? 0xff : 0; - temp4 &= (svga->colournocare & 8) ? 0xff : 0; - return ~(temp | temp2 | temp3 | temp4); - } -//printf("Read %02X %04X %04X\n",vram[addr|svga->readplane],addr,svga->readplane); - return svga->vram[addr | readplane]; + if (svga->readmode) { + temp = svga->la; + temp ^= (svga->colourcompare & 1) ? 0xff : 0; + temp &= (svga->colournocare & 1) ? 0xff : 0; + temp2 = svga->lb; + temp2 ^= (svga->colourcompare & 2) ? 0xff : 0; + temp2 &= (svga->colournocare & 2) ? 0xff : 0; + temp3 = svga->lc; + temp3 ^= (svga->colourcompare & 4) ? 0xff : 0; + temp3 &= (svga->colournocare & 4) ? 0xff : 0; + temp4 = svga->ld; + temp4 ^= (svga->colourcompare & 8) ? 0xff : 0; + temp4 &= (svga->colournocare & 8) ? 0xff : 0; + return ~(temp | temp2 | temp3 | temp4); + } + // printf("Read %02X %04X %04X\n",vram[addr|svga->readplane],addr,svga->readplane); + return svga->vram[addr | readplane]; } void svga_doblit(int y1, int y2, int wx, int wy, svga_t *svga) { -// pclog("svga_doblit start\n"); - svga->frames++; -// pclog("doblit %i %i\n", y1, y2); -// pclog("svga_doblit %i %i\n", wx, svga->hdisp); - if (y1 > y2) { - video_blit_memtoscreen(32, 0, 0, 0, xsize, ysize); - return; - } + // pclog("svga_doblit start\n"); + svga->frames++; + // pclog("doblit %i %i\n", y1, y2); + // pclog("svga_doblit %i %i\n", wx, svga->hdisp); + if (y1 > y2) { + video_blit_memtoscreen(32, 0, 0, 0, xsize, ysize); + return; + } - if ((wx != xsize || wy != ysize) && !vid_resize) { - xsize = wx; - ysize = wy + 1; - if (xsize < 64) - xsize = 656; - if (ysize < 32) - ysize = 200; + if ((wx != xsize || wy != ysize) && !vid_resize) { + xsize = wx; + ysize = wy + 1; + if (xsize < 64) + xsize = 656; + if (ysize < 32) + ysize = 200; - if (svga->vertical_linedbl) - updatewindowsize(xsize, ysize * 2); - else - updatewindowsize(xsize, ysize); - } - if (vid_resize) { - xsize = wx; - ysize = wy + 1; - } - video_blit_memtoscreen(32, 0, y1, y2, xsize, ysize); -// pclog("svga_doblit end\n"); + if (svga->vertical_linedbl) + updatewindowsize(xsize, ysize * 2); + else + updatewindowsize(xsize, ysize); + } + if (vid_resize) { + xsize = wx; + ysize = wy + 1; + } + video_blit_memtoscreen(32, 0, y1, y2, xsize, ysize); + // pclog("svga_doblit end\n"); } void svga_writew(uint32_t addr, uint16_t val, void *p) { - svga_t *svga = (svga_t *)p; - if (!svga->fast) { - svga_write(addr, val, p); - svga_write(addr + 1, val >> 8, p); - return; - } + svga_t *svga = (svga_t *)p; + if (!svga->fast) { + svga_write(addr, val, p); + svga_write(addr + 1, val >> 8, p); + return; + } - egawrites += 2; + egawrites += 2; - cycles -= video_timing_write_w; - cycles_lost += video_timing_write_w; + cycles -= video_timing_write_w; + cycles_lost += video_timing_write_w; - if (svga_output) - pclog("svga_writew: %05X ", addr); - addr = (addr & svga->banked_mask) + svga->write_bank; - addr &= svga->decode_mask; - if (addr >= svga->vram_max) - return; - addr &= svga->vram_mask; - if (svga_output) - pclog("%08X (%i, %i) %04X\n", addr, addr & 1023, addr >> 10, val); - svga->changedvram[addr >> 12] = changeframecount; - *(uint16_t *)&svga->vram[addr] = val; + if (svga_output) + pclog("svga_writew: %05X ", addr); + addr = (addr & svga->banked_mask) + svga->write_bank; + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return; + addr &= svga->vram_mask; + if (svga_output) + pclog("%08X (%i, %i) %04X\n", addr, addr & 1023, addr >> 10, val); + svga->changedvram[addr >> 12] = changeframecount; + *(uint16_t *)&svga->vram[addr] = val; } void svga_writel(uint32_t addr, uint32_t val, void *p) { - svga_t *svga = (svga_t *)p; + svga_t *svga = (svga_t *)p; - if (!svga->fast) { - svga_write(addr, val, p); - svga_write(addr + 1, val >> 8, p); - svga_write(addr + 2, val >> 16, p); - svga_write(addr + 3, val >> 24, p); - return; - } + if (!svga->fast) { + svga_write(addr, val, p); + svga_write(addr + 1, val >> 8, p); + svga_write(addr + 2, val >> 16, p); + svga_write(addr + 3, val >> 24, p); + return; + } - egawrites += 4; + egawrites += 4; - cycles -= video_timing_write_l; - cycles_lost += video_timing_write_l; + cycles -= video_timing_write_l; + cycles_lost += video_timing_write_l; - if (svga_output) - pclog("svga_writel: %05X ", addr); - addr = (addr & svga->banked_mask) + svga->write_bank; - addr &= svga->decode_mask; - if (addr >= svga->vram_max) - return; - addr &= svga->vram_mask; - if (svga_output) - pclog("%08X (%i, %i) %08X\n", addr, addr & 1023, addr >> 10, val); + if (svga_output) + pclog("svga_writel: %05X ", addr); + addr = (addr & svga->banked_mask) + svga->write_bank; + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return; + addr &= svga->vram_mask; + if (svga_output) + pclog("%08X (%i, %i) %08X\n", addr, addr & 1023, addr >> 10, val); - svga->changedvram[addr >> 12] = changeframecount; - *(uint32_t *)&svga->vram[addr] = val; + svga->changedvram[addr >> 12] = changeframecount; + *(uint32_t *)&svga->vram[addr] = val; } uint16_t svga_readw(uint32_t addr, void *p) { - svga_t *svga = (svga_t *)p; + svga_t *svga = (svga_t *)p; - if (!svga->fast) - return svga_read(addr, p) | (svga_read(addr + 1, p) << 8); + if (!svga->fast) + return svga_read(addr, p) | (svga_read(addr + 1, p) << 8); - egareads += 2; + egareads += 2; - cycles -= video_timing_read_w; - cycles_lost += video_timing_read_w; + cycles -= video_timing_read_w; + cycles_lost += video_timing_read_w; -// pclog("Readw %05X ", addr); - addr = (addr & svga->banked_mask) + svga->read_bank; - addr &= svga->decode_mask; -// pclog("%08X %04X\n", addr, *(uint16_t *)&vram[addr]); - if (addr >= svga->vram_max) - return 0xffff; + // pclog("Readw %05X ", addr); + addr = (addr & svga->banked_mask) + svga->read_bank; + addr &= svga->decode_mask; + // pclog("%08X %04X\n", addr, *(uint16_t *)&vram[addr]); + if (addr >= svga->vram_max) + return 0xffff; - return *(uint16_t *)&svga->vram[addr & svga->vram_mask]; + return *(uint16_t *)&svga->vram[addr & svga->vram_mask]; } uint32_t svga_readl(uint32_t addr, void *p) { - svga_t *svga = (svga_t *)p; + svga_t *svga = (svga_t *)p; - if (!svga->fast) - return svga_read(addr, p) | (svga_read(addr + 1, p) << 8) | (svga_read(addr + 2, p) << 16) | (svga_read(addr + 3, p) << 24); + if (!svga->fast) + return svga_read(addr, p) | (svga_read(addr + 1, p) << 8) | (svga_read(addr + 2, p) << 16) | + (svga_read(addr + 3, p) << 24); - egareads += 4; + egareads += 4; - cycles -= video_timing_read_l; - cycles_lost += video_timing_read_l; + cycles -= video_timing_read_l; + cycles_lost += video_timing_read_l; -// pclog("Readl %05X ", addr); - addr = (addr & svga->banked_mask) + svga->read_bank; - addr &= svga->decode_mask; -// pclog("%08X %08X\n", addr, *(uint32_t *)&vram[addr]); - if (addr >= svga->vram_max) - return 0xffffffff; + // pclog("Readl %05X ", addr); + addr = (addr & svga->banked_mask) + svga->read_bank; + addr &= svga->decode_mask; + // pclog("%08X %08X\n", addr, *(uint32_t *)&vram[addr]); + if (addr >= svga->vram_max) + return 0xffffffff; - return *(uint32_t *)&svga->vram[addr & svga->vram_mask]; + return *(uint32_t *)&svga->vram[addr & svga->vram_mask]; } void svga_writew_linear(uint32_t addr, uint16_t val, void *p) { - svga_t *svga = (svga_t *)p; + svga_t *svga = (svga_t *)p; - if (!svga->fast) { - svga_write_linear(addr, val, p); - svga_write_linear(addr + 1, val >> 8, p); - return; - } + if (!svga->fast) { + svga_write_linear(addr, val, p); + svga_write_linear(addr + 1, val >> 8, p); + return; + } - egawrites += 2; + egawrites += 2; - cycles -= video_timing_write_w; - cycles_lost += video_timing_write_w; + cycles -= video_timing_write_w; + cycles_lost += video_timing_write_w; - if (svga_output) - pclog("Write LFBw %08X %04X\n", addr, val); - addr &= svga->decode_mask; - if (addr >= svga->vram_max) - return; - addr &= svga->vram_mask; - svga->changedvram[addr >> 12] = changeframecount; - *(uint16_t *)&svga->vram[addr] = val; + if (svga_output) + pclog("Write LFBw %08X %04X\n", addr, val); + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return; + addr &= svga->vram_mask; + svga->changedvram[addr >> 12] = changeframecount; + *(uint16_t *)&svga->vram[addr] = val; } void svga_writel_linear(uint32_t addr, uint32_t val, void *p) { - svga_t *svga = (svga_t *)p; + svga_t *svga = (svga_t *)p; - if (!svga->fast) { - svga_write_linear(addr, val, p); - svga_write_linear(addr + 1, val >> 8, p); - svga_write_linear(addr + 2, val >> 16, p); - svga_write_linear(addr + 3, val >> 24, p); - return; - } + if (!svga->fast) { + svga_write_linear(addr, val, p); + svga_write_linear(addr + 1, val >> 8, p); + svga_write_linear(addr + 2, val >> 16, p); + svga_write_linear(addr + 3, val >> 24, p); + return; + } - egawrites += 4; + egawrites += 4; - cycles -= video_timing_write_l; - cycles_lost += video_timing_write_l; + cycles -= video_timing_write_l; + cycles_lost += video_timing_write_l; - if (svga_output) - pclog("Write LFBl %08X %08X\n", addr, val); - addr &= svga->decode_mask; - if (addr >= svga->vram_max) - return; - addr &= svga->vram_mask; - svga->changedvram[addr >> 12] = changeframecount; - *(uint32_t *)&svga->vram[addr] = val; + if (svga_output) + pclog("Write LFBl %08X %08X\n", addr, val); + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return; + addr &= svga->vram_mask; + svga->changedvram[addr >> 12] = changeframecount; + *(uint32_t *)&svga->vram[addr] = val; } uint16_t svga_readw_linear(uint32_t addr, void *p) { - svga_t *svga = (svga_t *)p; + svga_t *svga = (svga_t *)p; - if (!svga->fast) - return svga_read_linear(addr, p) | (svga_read_linear(addr + 1, p) << 8); + if (!svga->fast) + return svga_read_linear(addr, p) | (svga_read_linear(addr + 1, p) << 8); - egareads += 2; + egareads += 2; - cycles -= video_timing_read_w; - cycles_lost += video_timing_read_w; + cycles -= video_timing_read_w; + cycles_lost += video_timing_read_w; - addr &= svga->decode_mask; - if (addr >= svga->vram_max) - return 0xffff; + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return 0xffff; - return *(uint16_t *)&svga->vram[addr & svga->vram_mask]; + return *(uint16_t *)&svga->vram[addr & svga->vram_mask]; } uint32_t svga_readl_linear(uint32_t addr, void *p) { - svga_t *svga = (svga_t *)p; + svga_t *svga = (svga_t *)p; - if (!svga->fast) - return svga_read_linear(addr, p) | (svga_read_linear(addr + 1, p) << 8) | (svga_read_linear(addr + 2, p) << 16) | (svga_read_linear(addr + 3, p) << 24); + if (!svga->fast) + return svga_read_linear(addr, p) | (svga_read_linear(addr + 1, p) << 8) | (svga_read_linear(addr + 2, p) << 16) | + (svga_read_linear(addr + 3, p) << 24); - egareads += 4; + egareads += 4; - cycles -= video_timing_read_l; - cycles_lost += video_timing_read_l; + cycles -= video_timing_read_l; + cycles_lost += video_timing_read_l; - addr &= svga->decode_mask; - if (addr >= svga->vram_max) - return 0xffffffff; + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return 0xffffffff; - return *(uint32_t *)&svga->vram[addr & svga->vram_mask]; + return *(uint32_t *)&svga->vram[addr & svga->vram_mask]; } void svga_add_status_info(char *s, int max_len, void *p) { - svga_t *svga = (svga_t *)p; - char temps[128]; + svga_t *svga = (svga_t *)p; + char temps[128]; - if (svga->chain4) - strcpy(temps, "SVGA chained (possibly mode 13h)\n"); - else - strcpy(temps, "SVGA unchained (possibly mode-X)\n"); - strncat(s, temps, max_len); + if (svga->chain4) + strcpy(temps, "SVGA chained (possibly mode 13h)\n"); + else + strcpy(temps, "SVGA unchained (possibly mode-X)\n"); + strncat(s, temps, max_len); - if (!svga->video_bpp) - strcpy(temps, "SVGA in text mode\n"); - else - sprintf(temps, "SVGA colour depth : %i bpp\n", svga->video_bpp); - strncat(s, temps, max_len); + if (!svga->video_bpp) + strcpy(temps, "SVGA in text mode\n"); + else + sprintf(temps, "SVGA colour depth : %i bpp\n", svga->video_bpp); + strncat(s, temps, max_len); - sprintf(temps, "SVGA resolution : %i x %i\n", svga->video_res_x, svga->video_res_y); - strncat(s, temps, max_len); + sprintf(temps, "SVGA resolution : %i x %i\n", svga->video_res_x, svga->video_res_y); + strncat(s, temps, max_len); - sprintf(temps, "SVGA refresh rate : %i Hz\n\n", svga->frames); - svga->frames = 0; - strncat(s, temps, max_len); + sprintf(temps, "SVGA refresh rate : %i Hz\n\n", svga->frames); + svga->frames = 0; + strncat(s, temps, max_len); } diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index 010016b0..b94c88ae 100644 --- a/src/video/vid_svga_render.c +++ b/src/video/vid_svga_render.c @@ -6,902 +6,911 @@ #include "vid_svga_render_remap.h" void svga_render_null(svga_t *svga) { - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; } void svga_render_blank(svga_t *svga) { - int x, xx; + int x, xx; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - for (x = 0; x < svga->hdisp; x++) { - switch (svga->seqregs[1] & 9) { - case 0: - for (xx = 0; xx < 9; xx++) - ((uint32_t *)buffer32->line[svga->displine])[(x * 9) + xx + 32] = 0; - break; - case 1: - for (xx = 0; xx < 8; xx++) - ((uint32_t *)buffer32->line[svga->displine])[(x * 8) + xx + 32] = 0; - break; - case 8: - for (xx = 0; xx < 18; xx++) - ((uint32_t *)buffer32->line[svga->displine])[(x * 18) + xx + 32] = 0; - break; - case 9: - for (xx = 0; xx < 16; xx++) - ((uint32_t *)buffer32->line[svga->displine])[(x * 16) + xx + 32] = 0; - break; - } - } + for (x = 0; x < svga->hdisp; x++) { + switch (svga->seqregs[1] & 9) { + case 0: + for (xx = 0; xx < 9; xx++) + ((uint32_t *)buffer32->line[svga->displine])[(x * 9) + xx + 32] = 0; + break; + case 1: + for (xx = 0; xx < 8; xx++) + ((uint32_t *)buffer32->line[svga->displine])[(x * 8) + xx + 32] = 0; + break; + case 8: + for (xx = 0; xx < 18; xx++) + ((uint32_t *)buffer32->line[svga->displine])[(x * 18) + xx + 32] = 0; + break; + case 9: + for (xx = 0; xx < 16; xx++) + ((uint32_t *)buffer32->line[svga->displine])[(x * 16) + xx + 32] = 0; + break; + } + } } void svga_render_text_40(svga_t *svga) { - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - if (svga->fullchange) { - int offset = ((8 - svga->scrollcache) << 1) + 16; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; - int x, xx; - int drawcursor; - uint8_t chr, attr, dat; - uint32_t charaddr; - int fg, bg; - int xinc = (svga->seqregs[1] & 1) ? 16 : 18; + if (svga->fullchange) { + int offset = ((8 - svga->scrollcache) << 1) + 16; + uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; + int x, xx; + int drawcursor; + uint8_t chr, attr, dat; + uint32_t charaddr; + int fg, bg; + int xinc = (svga->seqregs[1] & 1) ? 16 : 18; - for (x = 0; x < svga->hdisp; x += xinc) { - uint32_t addr = svga->remap_func(svga, svga->ma) & svga->vram_display_mask; + for (x = 0; x < svga->hdisp; x += xinc) { + uint32_t addr = svga->remap_func(svga, svga->ma) & svga->vram_display_mask; - drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron); - chr = svga->vram[addr]; - attr = svga->vram[addr + 1]; + drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron); + chr = svga->vram[addr]; + attr = svga->vram[addr + 1]; - if (attr & 8) - charaddr = svga->charsetb + (chr * 128); - else - charaddr = svga->charseta + (chr * 128); + if (attr & 8) + charaddr = svga->charsetb + (chr * 128); + else + charaddr = svga->charseta + (chr * 128); - if (drawcursor) { - bg = svga->pallook[svga->egapal[attr & 15]]; - fg = svga->pallook[svga->egapal[attr >> 4]]; - } else { - fg = svga->pallook[svga->egapal[attr & 15]]; - bg = svga->pallook[svga->egapal[attr >> 4]]; - if (attr & 0x80 && svga->attrregs[0x10] & 8) { - bg = svga->pallook[svga->egapal[(attr >> 4) & 7]]; - if (svga->blink & 16) - fg = bg; - } - } + if (drawcursor) { + bg = svga->pallook[svga->egapal[attr & 15]]; + fg = svga->pallook[svga->egapal[attr >> 4]]; + } else { + fg = svga->pallook[svga->egapal[attr & 15]]; + bg = svga->pallook[svga->egapal[attr >> 4]]; + if (attr & 0x80 && svga->attrregs[0x10] & 8) { + bg = svga->pallook[svga->egapal[(attr >> 4) & 7]]; + if (svga->blink & 16) + fg = bg; + } + } - dat = svga->vram[charaddr + (svga->sc << 2)]; - if (svga->seqregs[1] & 1) { - for (xx = 0; xx < 16; xx += 2) - p[xx] = p[xx + 1] = (dat & (0x80 >> (xx >> 1))) ? fg : bg; - } else { - for (xx = 0; xx < 16; xx += 2) - p[xx] = p[xx + 1] = (dat & (0x80 >> (xx >> 1))) ? fg : bg; - if ((chr & ~0x1F) != 0xC0 || !(svga->attrregs[0x10] & 4)) - p[16] = p[17] = bg; - else - p[16] = p[17] = (dat & 1) ? fg : bg; - } - svga->ma += 4; - p += xinc; - } - svga->ma &= svga->vram_display_mask; - } + dat = svga->vram[charaddr + (svga->sc << 2)]; + if (svga->seqregs[1] & 1) { + for (xx = 0; xx < 16; xx += 2) + p[xx] = p[xx + 1] = (dat & (0x80 >> (xx >> 1))) ? fg : bg; + } else { + for (xx = 0; xx < 16; xx += 2) + p[xx] = p[xx + 1] = (dat & (0x80 >> (xx >> 1))) ? fg : bg; + if ((chr & ~0x1F) != 0xC0 || !(svga->attrregs[0x10] & 4)) + p[16] = p[17] = bg; + else + p[16] = p[17] = (dat & 1) ? fg : bg; + } + svga->ma += 4; + p += xinc; + } + svga->ma &= svga->vram_display_mask; + } } void svga_render_text_80(svga_t *svga) { - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - if (svga->fullchange) { - int offset = (8 - svga->scrollcache) + 24; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; - int x, xx; - int drawcursor; - uint8_t chr, attr, dat; - uint32_t charaddr; - int fg, bg; - int xinc = (svga->seqregs[1] & 1) ? 8 : 9; + if (svga->fullchange) { + int offset = (8 - svga->scrollcache) + 24; + uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; + int x, xx; + int drawcursor; + uint8_t chr, attr, dat; + uint32_t charaddr; + int fg, bg; + int xinc = (svga->seqregs[1] & 1) ? 8 : 9; - for (x = 0; x < svga->hdisp; x += xinc) { - uint32_t addr = svga->remap_func(svga, svga->ma) & svga->vram_display_mask; + for (x = 0; x < svga->hdisp; x += xinc) { + uint32_t addr = svga->remap_func(svga, svga->ma) & svga->vram_display_mask; - drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron); - chr = svga->vram[addr]; - attr = svga->vram[addr + 1]; + drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron); + chr = svga->vram[addr]; + attr = svga->vram[addr + 1]; - if (attr & 8) - charaddr = svga->charsetb + (chr * 128); - else - charaddr = svga->charseta + (chr * 128); + if (attr & 8) + charaddr = svga->charsetb + (chr * 128); + else + charaddr = svga->charseta + (chr * 128); - if (drawcursor) { - bg = svga->pallook[svga->egapal[attr & 15]]; - fg = svga->pallook[svga->egapal[attr >> 4]]; - } else { - fg = svga->pallook[svga->egapal[attr & 15]]; - bg = svga->pallook[svga->egapal[attr >> 4]]; - if (attr & 0x80 && svga->attrregs[0x10] & 8) { - bg = svga->pallook[svga->egapal[(attr >> 4) & 7]]; - if (svga->blink & 16) - fg = bg; - } - } + if (drawcursor) { + bg = svga->pallook[svga->egapal[attr & 15]]; + fg = svga->pallook[svga->egapal[attr >> 4]]; + } else { + fg = svga->pallook[svga->egapal[attr & 15]]; + bg = svga->pallook[svga->egapal[attr >> 4]]; + if (attr & 0x80 && svga->attrregs[0x10] & 8) { + bg = svga->pallook[svga->egapal[(attr >> 4) & 7]]; + if (svga->blink & 16) + fg = bg; + } + } - dat = svga->vram[charaddr + (svga->sc << 2)]; - if (svga->seqregs[1] & 1) { - for (xx = 0; xx < 8; xx++) - p[xx] = (dat & (0x80 >> xx)) ? fg : bg; - } else { - for (xx = 0; xx < 8; xx++) - p[xx] = (dat & (0x80 >> xx)) ? fg : bg; - if ((chr & ~0x1F) != 0xC0 || !(svga->attrregs[0x10] & 4)) - p[8] = bg; - else - p[8] = (dat & 1) ? fg : bg; - } - svga->ma += 4; - p += xinc; - } - svga->ma &= svga->vram_display_mask; - } + dat = svga->vram[charaddr + (svga->sc << 2)]; + if (svga->seqregs[1] & 1) { + for (xx = 0; xx < 8; xx++) + p[xx] = (dat & (0x80 >> xx)) ? fg : bg; + } else { + for (xx = 0; xx < 8; xx++) + p[xx] = (dat & (0x80 >> xx)) ? fg : bg; + if ((chr & ~0x1F) != 0xC0 || !(svga->attrregs[0x10] & 4)) + p[8] = bg; + else + p[8] = (dat & 1) ? fg : bg; + } + svga->ma += 4; + p += xinc; + } + svga->ma &= svga->vram_display_mask; + } } void svga_render_text_80_ksc5601(svga_t *svga) { - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - if (svga->fullchange) { - int offset = (8 - svga->scrollcache) + 24; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; - int x, xx; - int drawcursor; - uint8_t chr, attr, dat, nextchr; - uint32_t charaddr; - int fg, bg; - int xinc = (svga->seqregs[1] & 1) ? 8 : 9; + if (svga->fullchange) { + int offset = (8 - svga->scrollcache) + 24; + uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; + int x, xx; + int drawcursor; + uint8_t chr, attr, dat, nextchr; + uint32_t charaddr; + int fg, bg; + int xinc = (svga->seqregs[1] & 1) ? 8 : 9; - for (x = 0; x < svga->hdisp; x += xinc) { - uint32_t addr = svga->remap_func(svga, svga->ma) & svga->vram_display_mask; + for (x = 0; x < svga->hdisp; x += xinc) { + uint32_t addr = svga->remap_func(svga, svga->ma) & svga->vram_display_mask; - drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron); - chr = svga->vram[addr]; - nextchr = svga->vram[addr + 8]; - attr = svga->vram[addr + 1]; + drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron); + chr = svga->vram[addr]; + nextchr = svga->vram[addr + 8]; + attr = svga->vram[addr + 1]; - if (drawcursor) { - bg = svga->pallook[svga->egapal[attr & 15]]; - fg = svga->pallook[svga->egapal[attr >> 4]]; - } else { - fg = svga->pallook[svga->egapal[attr & 15]]; - bg = svga->pallook[svga->egapal[attr >> 4]]; - if (attr & 0x80 && svga->attrregs[0x10] & 8) { - bg = svga->pallook[svga->egapal[(attr >> 4) & 7]]; - if (svga->blink & 16) - fg = bg; - } - } + if (drawcursor) { + bg = svga->pallook[svga->egapal[attr & 15]]; + fg = svga->pallook[svga->egapal[attr >> 4]]; + } else { + fg = svga->pallook[svga->egapal[attr & 15]]; + bg = svga->pallook[svga->egapal[attr >> 4]]; + if (attr & 0x80 && svga->attrregs[0x10] & 8) { + bg = svga->pallook[svga->egapal[(attr >> 4) & 7]]; + if (svga->blink & 16) + fg = bg; + } + } - if (x + xinc < svga->hdisp && (chr & (nextchr | svga->ksc5601_sbyte_mask) & 0x80)) { - if ((chr == svga->ksc5601_udc_area_msb[0] || chr == svga->ksc5601_udc_area_msb[1]) && (nextchr > 0xa0 && nextchr < 0xff)) - dat = fontdatksc5601_user[(chr == svga->ksc5601_udc_area_msb[1] ? 96 : 0) + (nextchr & 0x7F) - 0x20][svga->sc]; - else if (nextchr & 0x80) { - if (svga->ksc5601_swap_mode == 1 && (nextchr > 0xa0 && nextchr < 0xff)) { - if (chr >= 0x80 && chr < 0x99) - chr += 0x30; - else if (chr >= 0xB0 && chr < 0xC9) - chr -= 0x30; - } - dat = fontdatksc5601[((chr & 0x7F) << 7) | (nextchr & 0x7F)][svga->sc]; - } else - dat = 0xFF; - } else { - if (attr & 8) - charaddr = svga->charsetb + (chr * 128); - else - charaddr = svga->charseta + (chr * 128); + if (x + xinc < svga->hdisp && (chr & (nextchr | svga->ksc5601_sbyte_mask) & 0x80)) { + if ((chr == svga->ksc5601_udc_area_msb[0] || chr == svga->ksc5601_udc_area_msb[1]) && + (nextchr > 0xa0 && nextchr < 0xff)) + dat = fontdatksc5601_user[(chr == svga->ksc5601_udc_area_msb[1] ? 96 : 0) + + (nextchr & 0x7F) - 0x20][svga->sc]; + else if (nextchr & 0x80) { + if (svga->ksc5601_swap_mode == 1 && (nextchr > 0xa0 && nextchr < 0xff)) { + if (chr >= 0x80 && chr < 0x99) + chr += 0x30; + else if (chr >= 0xB0 && chr < 0xC9) + chr -= 0x30; + } + dat = fontdatksc5601[((chr & 0x7F) << 7) | (nextchr & 0x7F)][svga->sc]; + } else + dat = 0xFF; + } else { + if (attr & 8) + charaddr = svga->charsetb + (chr * 128); + else + charaddr = svga->charseta + (chr * 128); - if ((svga->ksc5601_english_font_type >> 8) == 1) - dat = fontdatksc5601[((svga->ksc5601_english_font_type & 0x7F) << 7) | (chr >> 1)][((chr & 1) << 4) | svga->sc]; - else - dat = svga->vram[charaddr + (svga->sc << 2)]; - } - if (svga->seqregs[1] & 1) { - for (xx = 0; xx < 8; xx++) - p[xx] = (dat & (0x80 >> xx)) ? fg : bg; - } else { - for (xx = 0; xx < 8; xx++) - p[xx] = (dat & (0x80 >> xx)) ? fg : bg; - if ((chr & ~0x1F) != 0xC0 || !(svga->attrregs[0x10] & 4)) - p[8] = bg; - else - p[8] = (dat & 1) ? fg : bg; - } - svga->ma += 4; - p += xinc; + if ((svga->ksc5601_english_font_type >> 8) == 1) + dat = fontdatksc5601[((svga->ksc5601_english_font_type & 0x7F) << 7) | (chr >> 1)] + [((chr & 1) << 4) | svga->sc]; + else + dat = svga->vram[charaddr + (svga->sc << 2)]; + } + if (svga->seqregs[1] & 1) { + for (xx = 0; xx < 8; xx++) + p[xx] = (dat & (0x80 >> xx)) ? fg : bg; + } else { + for (xx = 0; xx < 8; xx++) + p[xx] = (dat & (0x80 >> xx)) ? fg : bg; + if ((chr & ~0x1F) != 0xC0 || !(svga->attrregs[0x10] & 4)) + p[8] = bg; + else + p[8] = (dat & 1) ? fg : bg; + } + svga->ma += 4; + p += xinc; - if (x + xinc < svga->hdisp && (chr & (nextchr | svga->ksc5601_sbyte_mask) & 0x80)) { - attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask]; + if (x + xinc < svga->hdisp && (chr & (nextchr | svga->ksc5601_sbyte_mask) & 0x80)) { + attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask]; - if (drawcursor) { - bg = svga->pallook[svga->egapal[attr & 15]]; - fg = svga->pallook[svga->egapal[attr >> 4]]; - } else { - fg = svga->pallook[svga->egapal[attr & 15]]; - bg = svga->pallook[svga->egapal[attr >> 4]]; - if (attr & 0x80 && svga->attrregs[0x10] & 8) { - bg = svga->pallook[svga->egapal[(attr >> 4) & 7]]; - if (svga->blink & 16) - fg = bg; - } - } + if (drawcursor) { + bg = svga->pallook[svga->egapal[attr & 15]]; + fg = svga->pallook[svga->egapal[attr >> 4]]; + } else { + fg = svga->pallook[svga->egapal[attr & 15]]; + bg = svga->pallook[svga->egapal[attr >> 4]]; + if (attr & 0x80 && svga->attrregs[0x10] & 8) { + bg = svga->pallook[svga->egapal[(attr >> 4) & 7]]; + if (svga->blink & 16) + fg = bg; + } + } - if ((chr == svga->ksc5601_udc_area_msb[0] || chr == svga->ksc5601_udc_area_msb[1]) && (nextchr > 0xa0 && nextchr < 0xff)) - dat = fontdatksc5601_user[(chr == svga->ksc5601_udc_area_msb[1] ? 96 : 0) + (nextchr & 0x7F) - 0x20][svga->sc + 16]; - else if (nextchr & 0x80) { - dat = fontdatksc5601[((chr & 0x7F) << 7) | (nextchr & 0x7F)][svga->sc + 16]; - } else - dat = 0xFF; - if (svga->seqregs[1] & 1) { - for (xx = 0; xx < 8; xx++) - p[xx] = (dat & (0x80 >> xx)) ? fg : bg; - } else { - for (xx = 0; xx < 8; xx++) - p[xx] = (dat & (0x80 >> xx)) ? fg : bg; - if ((chr & ~0x1F) != 0xC0 || !(svga->attrregs[0x10] & 4)) - p[8] = bg; - else - p[8] = (dat & 1) ? fg : bg; - } + if ((chr == svga->ksc5601_udc_area_msb[0] || chr == svga->ksc5601_udc_area_msb[1]) && + (nextchr > 0xa0 && nextchr < 0xff)) + dat = fontdatksc5601_user[(chr == svga->ksc5601_udc_area_msb[1] ? 96 : 0) + + (nextchr & 0x7F) - 0x20][svga->sc + 16]; + else if (nextchr & 0x80) { + dat = fontdatksc5601[((chr & 0x7F) << 7) | (nextchr & 0x7F)][svga->sc + 16]; + } else + dat = 0xFF; + if (svga->seqregs[1] & 1) { + for (xx = 0; xx < 8; xx++) + p[xx] = (dat & (0x80 >> xx)) ? fg : bg; + } else { + for (xx = 0; xx < 8; xx++) + p[xx] = (dat & (0x80 >> xx)) ? fg : bg; + if ((chr & ~0x1F) != 0xC0 || !(svga->attrregs[0x10] & 4)) + p[8] = bg; + else + p[8] = (dat & 1) ? fg : bg; + } - svga->ma += 4; - p += xinc; - x += xinc; - } - } - svga->ma &= svga->vram_display_mask; - } + svga->ma += 4; + p += xinc; + x += xinc; + } + } + svga->ma &= svga->vram_display_mask; + } } void svga_render_2bpp_lowres(svga_t *svga) { - uint32_t changed_addr = svga->remap_func(svga, svga->ma); + uint32_t changed_addr = svga->remap_func(svga, svga->ma); - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - int x; - int offset = ((8 - svga->scrollcache) << 1) + 16; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + int x; + int offset = ((8 - svga->scrollcache) << 1) + 16; + uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x += 16) { - uint32_t addr = svga->remap_func(svga, svga->ma); - uint8_t dat[2]; + for (x = 0; x <= svga->hdisp; x += 16) { + uint32_t addr = svga->remap_func(svga, svga->ma); + uint8_t dat[2]; - dat[0] = svga->vram[addr]; - dat[1] = svga->vram[addr + 1]; - svga->ma += 4; - svga->ma &= svga->vram_display_mask; + dat[0] = svga->vram[addr]; + dat[1] = svga->vram[addr + 1]; + svga->ma += 4; + svga->ma &= svga->vram_display_mask; - p[0] = p[1] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]]; - p[2] = p[3] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]]; - p[4] = p[5] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]]; - p[6] = p[7] = svga->pallook[svga->egapal[dat[0] & 3]]; - p[8] = p[9] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]]; - p[10] = p[11] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]]; - p[12] = p[13] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]]; - p[14] = p[15] = svga->pallook[svga->egapal[dat[1] & 3]]; + p[0] = p[1] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]]; + p[2] = p[3] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]]; + p[4] = p[5] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]]; + p[6] = p[7] = svga->pallook[svga->egapal[dat[0] & 3]]; + p[8] = p[9] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]]; + p[10] = p[11] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]]; + p[12] = p[13] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]]; + p[14] = p[15] = svga->pallook[svga->egapal[dat[1] & 3]]; - p += 16; - } - } + p += 16; + } + } } void svga_render_2bpp_highres(svga_t *svga) { - uint32_t changed_addr = svga->remap_func(svga, svga->ma); + uint32_t changed_addr = svga->remap_func(svga, svga->ma); - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - int x; - int offset = (8 - svga->scrollcache) + 24; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + int x; + int offset = (8 - svga->scrollcache) + 24; + uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x += 8) { - uint32_t addr = svga->remap_func(svga, svga->ma); - uint8_t dat[2]; + for (x = 0; x <= svga->hdisp; x += 8) { + uint32_t addr = svga->remap_func(svga, svga->ma); + uint8_t dat[2]; - dat[0] = svga->vram[addr]; - dat[1] = svga->vram[addr + 1]; - svga->ma += 4; - svga->ma &= svga->vram_display_mask; + dat[0] = svga->vram[addr]; + dat[1] = svga->vram[addr + 1]; + svga->ma += 4; + svga->ma &= svga->vram_display_mask; - *p++ = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]]; - *p++ = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]]; - *p++ = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]]; - *p++ = svga->pallook[svga->egapal[dat[0] & 3]]; - *p++ = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]]; - *p++ = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]]; - *p++ = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]]; - *p++ = svga->pallook[svga->egapal[dat[1] & 3]]; - } - } + *p++ = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]]; + *p++ = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]]; + *p++ = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]]; + *p++ = svga->pallook[svga->egapal[dat[0] & 3]]; + *p++ = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]]; + *p++ = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]]; + *p++ = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]]; + *p++ = svga->pallook[svga->egapal[dat[1] & 3]]; + } + } } void svga_render_4bpp_lowres(svga_t *svga) { - uint32_t changed_addr = svga->remap_func(svga, svga->ma); + uint32_t changed_addr = svga->remap_func(svga, svga->ma); - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - int x; - int offset = ((8 - svga->scrollcache) << 1) + 16; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + int x; + int offset = ((8 - svga->scrollcache) << 1) + 16; + uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x += 16) { - uint8_t edat[4]; - uint8_t dat; - uint32_t addr = svga->remap_func(svga, svga->ma); + for (x = 0; x <= svga->hdisp; x += 16) { + uint8_t edat[4]; + uint8_t dat; + uint32_t addr = svga->remap_func(svga, svga->ma); - *(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[addr]); - svga->ma += 4; - svga->ma &= svga->vram_display_mask; + *(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[addr]); + svga->ma += 4; + svga->ma &= svga->vram_display_mask; - dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); - p[0] = p[1] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[2] = p[3] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); - p[4] = p[5] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[6] = p[7] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); - p[8] = p[9] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[10] = p[11] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); - p[12] = p[13] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[14] = p[15] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); + p[0] = p[1] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[2] = p[3] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | + (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); + p[4] = p[5] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[6] = p[7] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | + (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); + p[8] = p[9] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[10] = p[11] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); + p[12] = p[13] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[14] = p[15] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - p += 16; - } - } + p += 16; + } + } } void svga_render_4bpp_highres(svga_t *svga) { - uint32_t changed_addr = svga->remap_func(svga, svga->ma); + uint32_t changed_addr = svga->remap_func(svga, svga->ma); - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - int x; - int offset = (8 - svga->scrollcache) + 24; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + int x; + int offset = (8 - svga->scrollcache) + 24; + uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x += 8) { - uint8_t edat[4]; - uint8_t dat; - uint32_t addr = svga->remap_func(svga, svga->ma); + for (x = 0; x <= svga->hdisp; x += 8) { + uint8_t edat[4]; + uint8_t dat; + uint32_t addr = svga->remap_func(svga, svga->ma); - *(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[addr]); - svga->ma += 4; - svga->ma &= svga->vram_display_mask; + *(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[addr]); + svga->ma += 4; + svga->ma &= svga->vram_display_mask; - dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); - *p++ = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - *p++ = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); - *p++ = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - *p++ = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); - *p++ = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - *p++ = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); - *p++ = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - *p++ = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - } - } + dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); + *p++ = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + *p++ = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | + (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); + *p++ = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + *p++ = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | + (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); + *p++ = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + *p++ = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); + *p++ = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + *p++ = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + } + } } void svga_render_8bpp_lowres(svga_t *svga) { - uint32_t changed_addr = svga->remap_func(svga, svga->ma); + uint32_t changed_addr = svga->remap_func(svga, svga->ma); - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - int x; - int offset = (8 - (svga->scrollcache & 6)) + 24; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + int x; + int offset = (8 - (svga->scrollcache & 6)) + 24; + uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - if (!svga->remap_required) { - for (x = 0; x <= svga->hdisp; x += 8) { - uint32_t dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); + if (!svga->remap_required) { + for (x = 0; x <= svga->hdisp; x += 8) { + uint32_t dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); - p[0] = p[1] = svga->pallook[dat & 0xff]; - p[2] = p[3] = svga->pallook[(dat >> 8) & 0xff]; - p[4] = p[5] = svga->pallook[(dat >> 16) & 0xff]; - p[6] = p[7] = svga->pallook[(dat >> 24) & 0xff]; + p[0] = p[1] = svga->pallook[dat & 0xff]; + p[2] = p[3] = svga->pallook[(dat >> 8) & 0xff]; + p[4] = p[5] = svga->pallook[(dat >> 16) & 0xff]; + p[6] = p[7] = svga->pallook[(dat >> 24) & 0xff]; - svga->ma += 4; - p += 8; - } - } else { - for (x = 0; x <= svga->hdisp; x += 8) { - uint32_t addr = svga->remap_func(svga, svga->ma); - uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + svga->ma += 4; + p += 8; + } + } else { + for (x = 0; x <= svga->hdisp; x += 8) { + uint32_t addr = svga->remap_func(svga, svga->ma); + uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); - p[0] = p[1] = svga->pallook[dat & 0xff]; - p[2] = p[3] = svga->pallook[(dat >> 8) & 0xff]; - p[4] = p[5] = svga->pallook[(dat >> 16) & 0xff]; - p[6] = p[7] = svga->pallook[(dat >> 24) & 0xff]; + p[0] = p[1] = svga->pallook[dat & 0xff]; + p[2] = p[3] = svga->pallook[(dat >> 8) & 0xff]; + p[4] = p[5] = svga->pallook[(dat >> 16) & 0xff]; + p[6] = p[7] = svga->pallook[(dat >> 24) & 0xff]; - svga->ma += 4; - p += 8; - } - } - svga->ma &= svga->vram_display_mask; - } + svga->ma += 4; + p += 8; + } + } + svga->ma &= svga->vram_display_mask; + } } void svga_render_8bpp_highres(svga_t *svga) { - uint32_t changed_addr = svga->remap_func(svga, svga->ma); + uint32_t changed_addr = svga->remap_func(svga, svga->ma); - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - int x; - int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + int x; + int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; + uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - if (!svga->remap_required) { - for (x = 0; x <= svga->hdisp; x += 8) { - uint32_t dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); - *p++ = svga->pallook[dat & 0xff]; - *p++ = svga->pallook[(dat >> 8) & 0xff]; - *p++ = svga->pallook[(dat >> 16) & 0xff]; - *p++ = svga->pallook[(dat >> 24) & 0xff]; + if (!svga->remap_required) { + for (x = 0; x <= svga->hdisp; x += 8) { + uint32_t dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); + *p++ = svga->pallook[dat & 0xff]; + *p++ = svga->pallook[(dat >> 8) & 0xff]; + *p++ = svga->pallook[(dat >> 16) & 0xff]; + *p++ = svga->pallook[(dat >> 24) & 0xff]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); - *p++ = svga->pallook[dat & 0xff]; - *p++ = svga->pallook[(dat >> 8) & 0xff]; - *p++ = svga->pallook[(dat >> 16) & 0xff]; - *p++ = svga->pallook[(dat >> 24) & 0xff]; + dat = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); + *p++ = svga->pallook[dat & 0xff]; + *p++ = svga->pallook[(dat >> 8) & 0xff]; + *p++ = svga->pallook[(dat >> 16) & 0xff]; + *p++ = svga->pallook[(dat >> 24) & 0xff]; - svga->ma += 8; - } - } else { - for (x = 0; x <= svga->hdisp; x += 4) { - uint32_t addr = svga->remap_func(svga, svga->ma); - uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + svga->ma += 8; + } + } else { + for (x = 0; x <= svga->hdisp; x += 4) { + uint32_t addr = svga->remap_func(svga, svga->ma); + uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); - svga->ma += 4; + svga->ma += 4; - *p++ = svga->pallook[dat & 0xff]; - *p++ = svga->pallook[(dat >> 8) & 0xff]; - *p++ = svga->pallook[(dat >> 16) & 0xff]; - *p++ = svga->pallook[(dat >> 24) & 0xff]; - } - } + *p++ = svga->pallook[dat & 0xff]; + *p++ = svga->pallook[(dat >> 8) & 0xff]; + *p++ = svga->pallook[(dat >> 16) & 0xff]; + *p++ = svga->pallook[(dat >> 24) & 0xff]; + } + } - svga->ma &= svga->vram_display_mask; - } + svga->ma &= svga->vram_display_mask; + } } void svga_render_15bpp_lowres(svga_t *svga) { - uint32_t changed_addr = svga->remap_func(svga, svga->ma); + uint32_t changed_addr = svga->remap_func(svga, svga->ma); - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - int x; - int offset = (8 - (svga->scrollcache & 6)) + 24; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + int x; + int offset = (8 - (svga->scrollcache & 6)) + 24; + uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - if (!svga->remap_required) { - for (x = 0; x <= svga->hdisp; x += 4) { - uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); + if (!svga->remap_required) { + for (x = 0; x <= svga->hdisp; x += 4) { + uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - *p++ = video_15to32[dat & 0xffff]; - *p++ = video_15to32[dat >> 16]; + *p++ = video_15to32[dat & 0xffff]; + *p++ = video_15to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - *p++ = video_15to32[dat & 0xffff]; - *p++ = video_15to32[dat >> 16]; - } - svga->ma += x << 1; - } else { - for (x = 0; x <= svga->hdisp; x += 2) { - uint32_t addr = svga->remap_func(svga, svga->ma); - uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + *p++ = video_15to32[dat & 0xffff]; + *p++ = video_15to32[dat >> 16]; + } + svga->ma += x << 1; + } else { + for (x = 0; x <= svga->hdisp; x += 2) { + uint32_t addr = svga->remap_func(svga, svga->ma); + uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); - *p++ = video_15to32[dat & 0xffff]; - *p++ = video_15to32[dat >> 16]; + *p++ = video_15to32[dat & 0xffff]; + *p++ = video_15to32[dat >> 16]; - svga->ma += 4; - } - } - svga->ma &= svga->vram_display_mask; - } + svga->ma += 4; + } + } + svga->ma &= svga->vram_display_mask; + } } void svga_render_15bpp_highres(svga_t *svga) { - uint32_t changed_addr = svga->remap_func(svga, svga->ma); + uint32_t changed_addr = svga->remap_func(svga, svga->ma); - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - int x; - int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + int x; + int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; + uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - if (!svga->remap_required) { - for (x = 0; x <= svga->hdisp; x += 8) { - uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - *p++ = video_15to32[dat & 0xffff]; - *p++ = video_15to32[dat >> 16]; + if (!svga->remap_required) { + for (x = 0; x <= svga->hdisp; x += 8) { + uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); + *p++ = video_15to32[dat & 0xffff]; + *p++ = video_15to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - *p++ = video_15to32[dat & 0xffff]; - *p++ = video_15to32[dat >> 16]; + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); + *p++ = video_15to32[dat & 0xffff]; + *p++ = video_15to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); - *p++ = video_15to32[dat & 0xffff]; - *p++ = video_15to32[dat >> 16]; + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); + *p++ = video_15to32[dat & 0xffff]; + *p++ = video_15to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); - *p++ = video_15to32[dat & 0xffff]; - *p++ = video_15to32[dat >> 16]; - } + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); + *p++ = video_15to32[dat & 0xffff]; + *p++ = video_15to32[dat >> 16]; + } - svga->ma += x << 1; - } else { - for (x = 0; x <= svga->hdisp; x += 2) { - uint32_t addr = svga->remap_func(svga, svga->ma); - uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + svga->ma += x << 1; + } else { + for (x = 0; x <= svga->hdisp; x += 2) { + uint32_t addr = svga->remap_func(svga, svga->ma); + uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); - *p++ = video_15to32[dat & 0xffff]; - *p++ = video_15to32[dat >> 16]; + *p++ = video_15to32[dat & 0xffff]; + *p++ = video_15to32[dat >> 16]; - svga->ma += 4; - } - } - svga->ma &= svga->vram_display_mask; - } + svga->ma += 4; + } + } + svga->ma &= svga->vram_display_mask; + } } void svga_render_16bpp_lowres(svga_t *svga) { - uint32_t changed_addr = svga->remap_func(svga, svga->ma); + uint32_t changed_addr = svga->remap_func(svga, svga->ma); - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - int x; - int offset = (8 - (svga->scrollcache & 6)) + 24; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + int x; + int offset = (8 - (svga->scrollcache & 6)) + 24; + uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - if (!svga->remap_required) { - for (x = 0; x <= svga->hdisp; x += 4) { - uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); + if (!svga->remap_required) { + for (x = 0; x <= svga->hdisp; x += 4) { + uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - *p++ = video_16to32[dat & 0xffff]; - *p++ = video_16to32[dat >> 16]; + *p++ = video_16to32[dat & 0xffff]; + *p++ = video_16to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - *p++ = video_16to32[dat & 0xffff]; - *p++ = video_16to32[dat >> 16]; - } - svga->ma += x << 1; - } else { - for (x = 0; x <= svga->hdisp; x += 2) { - uint32_t addr = svga->remap_func(svga, svga->ma); - uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + *p++ = video_16to32[dat & 0xffff]; + *p++ = video_16to32[dat >> 16]; + } + svga->ma += x << 1; + } else { + for (x = 0; x <= svga->hdisp; x += 2) { + uint32_t addr = svga->remap_func(svga, svga->ma); + uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); - *p++ = video_16to32[dat & 0xffff]; - *p++ = video_16to32[dat >> 16]; + *p++ = video_16to32[dat & 0xffff]; + *p++ = video_16to32[dat >> 16]; - svga->ma += 4; - } - } - svga->ma += x << 1; - svga->ma &= svga->vram_display_mask; - } + svga->ma += 4; + } + } + svga->ma += x << 1; + svga->ma &= svga->vram_display_mask; + } } void svga_render_16bpp_highres(svga_t *svga) { - uint32_t changed_addr = svga->remap_func(svga, svga->ma); + uint32_t changed_addr = svga->remap_func(svga, svga->ma); - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - int x; - int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + int x; + int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; + uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - if (!svga->remap_required) { - for (x = 0; x <= svga->hdisp; x += 8) { - uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - *p++ = video_16to32[dat & 0xffff]; - *p++ = video_16to32[dat >> 16]; + if (!svga->remap_required) { + for (x = 0; x <= svga->hdisp; x += 8) { + uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); + *p++ = video_16to32[dat & 0xffff]; + *p++ = video_16to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - *p++ = video_16to32[dat & 0xffff]; - *p++ = video_16to32[dat >> 16]; + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); + *p++ = video_16to32[dat & 0xffff]; + *p++ = video_16to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); - *p++ = video_16to32[dat & 0xffff]; - *p++ = video_16to32[dat >> 16]; + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); + *p++ = video_16to32[dat & 0xffff]; + *p++ = video_16to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); - *p++ = video_16to32[dat & 0xffff]; - *p++ = video_16to32[dat >> 16]; - } + dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); + *p++ = video_16to32[dat & 0xffff]; + *p++ = video_16to32[dat >> 16]; + } - svga->ma += x << 1; - } else { - for (x = 0; x <= svga->hdisp; x += 2) { - uint32_t addr = svga->remap_func(svga, svga->ma); - uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + svga->ma += x << 1; + } else { + for (x = 0; x <= svga->hdisp; x += 2) { + uint32_t addr = svga->remap_func(svga, svga->ma); + uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); - *p++ = video_16to32[dat & 0xffff]; - *p++ = video_16to32[dat >> 16]; + *p++ = video_16to32[dat & 0xffff]; + *p++ = video_16to32[dat >> 16]; - svga->ma += 4; - } - } - svga->ma &= svga->vram_display_mask; - } + svga->ma += 4; + } + } + svga->ma &= svga->vram_display_mask; + } } void svga_render_24bpp_lowres(svga_t *svga) { - uint32_t changed_addr = svga->remap_func(svga, svga->ma); + uint32_t changed_addr = svga->remap_func(svga, svga->ma); - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - int x; - int offset = (8 - (svga->scrollcache & 6)) + 24; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + int x; + int offset = (8 - (svga->scrollcache & 6)) + 24; + uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - if (!svga->remap_required) { - for (x = 0; x <= svga->hdisp; x++) { - uint32_t dat0 = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); - uint32_t dat1 = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); - uint32_t dat2 = *(uint32_t *)(&svga->vram[(svga->ma + 8) & svga->vram_display_mask]); + if (!svga->remap_required) { + for (x = 0; x <= svga->hdisp; x++) { + uint32_t dat0 = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); + uint32_t dat1 = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); + uint32_t dat2 = *(uint32_t *)(&svga->vram[(svga->ma + 8) & svga->vram_display_mask]); - p[0] = p[1] = dat0 & 0xffffff; - p[2] = p[3] = (dat0 >> 24) | ((dat1 & 0xffff) << 8); - p[4] = p[5] = (dat1 >> 16) | ((dat2 & 0xff) << 16); - p[6] = p[7] = dat2 >> 8; + p[0] = p[1] = dat0 & 0xffffff; + p[2] = p[3] = (dat0 >> 24) | ((dat1 & 0xffff) << 8); + p[4] = p[5] = (dat1 >> 16) | ((dat2 & 0xff) << 16); + p[6] = p[7] = dat2 >> 8; - svga->ma += 12; - } - } else { - for (x = 0; x <= svga->hdisp; x += 4) { - uint32_t dat0, dat1, dat2; - uint32_t addr; + svga->ma += 12; + } + } else { + for (x = 0; x <= svga->hdisp; x += 4) { + uint32_t dat0, dat1, dat2; + uint32_t addr; - addr = svga->remap_func(svga, svga->ma); - dat0 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); - addr = svga->remap_func(svga, svga->ma + 4); - dat1 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); - addr = svga->remap_func(svga, svga->ma + 8); - dat2 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + addr = svga->remap_func(svga, svga->ma); + dat0 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + addr = svga->remap_func(svga, svga->ma + 4); + dat1 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + addr = svga->remap_func(svga, svga->ma + 8); + dat2 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); - p[0] = p[1] = dat0 & 0xffffff; - p[2] = p[3] = (dat0 >> 24) | ((dat1 & 0xffff) << 8); - p[4] = p[5] = (dat1 >> 16) | ((dat2 & 0xff) << 16); - p[6] = p[7] = dat2 >> 8; + p[0] = p[1] = dat0 & 0xffffff; + p[2] = p[3] = (dat0 >> 24) | ((dat1 & 0xffff) << 8); + p[4] = p[5] = (dat1 >> 16) | ((dat2 & 0xff) << 16); + p[6] = p[7] = dat2 >> 8; - svga->ma += 12; - } - } - } + svga->ma += 12; + } + } + } } void svga_render_24bpp_highres(svga_t *svga) { - uint32_t changed_addr = svga->remap_func(svga, svga->ma); + uint32_t changed_addr = svga->remap_func(svga, svga->ma); - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - int x; - int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + int x; + int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; + uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - if (!svga->remap_required) { - for (x = 0; x <= svga->hdisp; x += 4) { - uint32_t dat0 = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); - uint32_t dat1 = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); - uint32_t dat2 = *(uint32_t *)(&svga->vram[(svga->ma + 8) & svga->vram_display_mask]); + if (!svga->remap_required) { + for (x = 0; x <= svga->hdisp; x += 4) { + uint32_t dat0 = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); + uint32_t dat1 = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); + uint32_t dat2 = *(uint32_t *)(&svga->vram[(svga->ma + 8) & svga->vram_display_mask]); - *p++ = dat0 & 0xffffff; - *p++ = (dat0 >> 24) | ((dat1 & 0xffff) << 8); - *p++ = (dat1 >> 16) | ((dat2 & 0xff) << 16); - *p++ = dat2 >> 8; + *p++ = dat0 & 0xffffff; + *p++ = (dat0 >> 24) | ((dat1 & 0xffff) << 8); + *p++ = (dat1 >> 16) | ((dat2 & 0xff) << 16); + *p++ = dat2 >> 8; - svga->ma += 12; - } - } else { - for (x = 0; x <= svga->hdisp; x += 4) { - uint32_t dat0, dat1, dat2; - uint32_t addr; + svga->ma += 12; + } + } else { + for (x = 0; x <= svga->hdisp; x += 4) { + uint32_t dat0, dat1, dat2; + uint32_t addr; - addr = svga->remap_func(svga, svga->ma); - dat0 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); - addr = svga->remap_func(svga, svga->ma + 4); - dat1 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); - addr = svga->remap_func(svga, svga->ma + 8); - dat2 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + addr = svga->remap_func(svga, svga->ma); + dat0 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + addr = svga->remap_func(svga, svga->ma + 4); + dat1 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + addr = svga->remap_func(svga, svga->ma + 8); + dat2 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); - *p++ = dat0 & 0xffffff; - *p++ = (dat0 >> 24) | ((dat1 & 0xffff) << 8); - *p++ = (dat1 >> 16) | ((dat2 & 0xff) << 16); - *p++ = dat2 >> 8; + *p++ = dat0 & 0xffffff; + *p++ = (dat0 >> 24) | ((dat1 & 0xffff) << 8); + *p++ = (dat1 >> 16) | ((dat2 & 0xff) << 16); + *p++ = dat2 >> 8; - svga->ma += 12; - } - } - svga->ma &= svga->vram_display_mask; - } + svga->ma += 12; + } + } + svga->ma &= svga->vram_display_mask; + } } void svga_render_32bpp_lowres(svga_t *svga) { - uint32_t changed_addr = svga->remap_func(svga, svga->ma); + uint32_t changed_addr = svga->remap_func(svga, svga->ma); - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - int x; - int offset = (8 - (svga->scrollcache & 6)) + 24; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + int x; + int offset = (8 - (svga->scrollcache & 6)) + 24; + uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - if (!svga->remap_required) { - for (x = 0; x <= svga->hdisp; x++) { - uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); - *p++ = dat & 0xffffff; - *p++ = dat & 0xffffff; - } - svga->ma += x * 4; - } else { - for (x = 0; x <= svga->hdisp; x++) { - uint32_t addr = svga->remap_func(svga, svga->ma); - uint32_t dat = *(uint32_t *)(&svga->vram[addr]); - *p++ = dat & 0xffffff; - *p++ = dat & 0xffffff; - svga->ma += 4; - } - } - svga->ma &= svga->vram_display_mask; - } + if (!svga->remap_required) { + for (x = 0; x <= svga->hdisp; x++) { + uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); + *p++ = dat & 0xffffff; + *p++ = dat & 0xffffff; + } + svga->ma += x * 4; + } else { + for (x = 0; x <= svga->hdisp; x++) { + uint32_t addr = svga->remap_func(svga, svga->ma); + uint32_t dat = *(uint32_t *)(&svga->vram[addr]); + *p++ = dat & 0xffffff; + *p++ = dat & 0xffffff; + svga->ma += 4; + } + } + svga->ma &= svga->vram_display_mask; + } } /*72% 91%*/ void svga_render_32bpp_highres(svga_t *svga) { - uint32_t changed_addr = svga->remap_func(svga, svga->ma); + uint32_t changed_addr = svga->remap_func(svga, svga->ma); - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - int x; - int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + int x; + int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; + uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - if (!svga->remap_required) { - for (x = 0; x <= svga->hdisp; x++) { - uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); - *p++ = dat & 0xffffff; - } - svga->ma += x * 4; - } else { - for (x = 0; x <= svga->hdisp; x++) { - uint32_t addr = svga->remap_func(svga, svga->ma); - uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); - *p++ = dat & 0xffffff; - svga->ma += 4; - } - } + if (!svga->remap_required) { + for (x = 0; x <= svga->hdisp; x++) { + uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); + *p++ = dat & 0xffffff; + } + svga->ma += x * 4; + } else { + for (x = 0; x <= svga->hdisp; x++) { + uint32_t addr = svga->remap_func(svga, svga->ma); + uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + *p++ = dat & 0xffffff; + svga->ma += 4; + } + } - svga->ma &= svga->vram_display_mask; - } + svga->ma &= svga->vram_display_mask; + } } void svga_render_ABGR8888_highres(svga_t *svga) { - uint32_t changed_addr = svga->remap_func(svga, svga->ma); + uint32_t changed_addr = svga->remap_func(svga, svga->ma); - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - int x; - int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + int x; + int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; + uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - if (!svga->remap_required) { - for (x = 0; x <= svga->hdisp; x++) { - uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); - *p++ = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16); - } - svga->ma += x * 4; - } else { - for (x = 0; x <= svga->hdisp; x++) { - uint32_t addr = svga->remap_func(svga, svga->ma); - uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); - *p++ = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16); - svga->ma += 4; - } - } + if (!svga->remap_required) { + for (x = 0; x <= svga->hdisp; x++) { + uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); + *p++ = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16); + } + svga->ma += x * 4; + } else { + for (x = 0; x <= svga->hdisp; x++) { + uint32_t addr = svga->remap_func(svga, svga->ma); + uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + *p++ = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16); + svga->ma += 4; + } + } - svga->ma &= svga->vram_display_mask; - } + svga->ma &= svga->vram_display_mask; + } } void svga_render_RGBA8888_highres(svga_t *svga) { - uint32_t changed_addr = svga->remap_func(svga, svga->ma); + uint32_t changed_addr = svga->remap_func(svga, svga->ma); - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - int x; - int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + int x; + int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; + uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - if (!svga->remap_required) { - for (x = 0; x <= svga->hdisp; x++) { - uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); - *p++ = dat >> 8; - } - svga->ma += x * 4; - } else { - for (x = 0; x <= svga->hdisp; x++) { - uint32_t addr = svga->remap_func(svga, svga->ma); - uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); - *p++ = dat >> 8; - svga->ma += 4; - } - } + if (!svga->remap_required) { + for (x = 0; x <= svga->hdisp; x++) { + uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); + *p++ = dat >> 8; + } + svga->ma += x * 4; + } else { + for (x = 0; x <= svga->hdisp; x++) { + uint32_t addr = svga->remap_func(svga, svga->ma); + uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + *p++ = dat >> 8; + svga->ma += 4; + } + } - svga->ma &= svga->vram_display_mask; - } + svga->ma &= svga->vram_display_mask; + } } diff --git a/src/video/vid_t1000.c b/src/video/vid_t1000.c index b846ec75..34b38cb3 100644 --- a/src/video/vid_t1000.c +++ b/src/video/vid_t1000.c @@ -18,7 +18,7 @@ /* Mapping of attributes to colours */ static uint32_t blue, grey; -static uint8_t boldcols[256]; /* Which attributes use the bold font */ +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; @@ -34,43 +34,37 @@ static uint8_t st_enabled = 1; static uint8_t st_display_internal = -1; void t1000_video_options_set(uint8_t options) { - st_video_options = options & 1; - st_video_options |= language; + st_video_options = options & 1; + st_video_options |= language; } -void t1000_video_enable(uint8_t enabled) { - st_enabled = enabled; -} +void t1000_video_enable(uint8_t enabled) { st_enabled = enabled; } -void t1000_display_set(uint8_t internal) { - st_display_internal = internal; -} +void t1000_display_set(uint8_t internal) { st_display_internal = internal; } -uint8_t t1000_display_get() { - return st_display_internal; -} +uint8_t t1000_display_get() { return st_display_internal; } typedef struct t1000_t { - mem_mapping_t mapping; + 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. */ + 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 font; /* Current font, 0-3 */ + int enabled; /* Hardware enabled, 0 or 1 */ + int internal; /* Using internal display? */ + uint8_t attrmap; /* Attribute mapping register */ - uint64_t dispontime, dispofftime; + uint64_t dispontime, dispofftime; - int linepos, displine; - int vc; - int dispon; - int vsynctime; - uint8_t video_options; + int linepos, displine; + int vc; + int dispon; + int vsynctime; + uint8_t video_options; - uint8_t *vram; + uint8_t *vram; } t1000_t; static void t1000_recalctimings(t1000_t *t1000); @@ -79,568 +73,537 @@ 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; + 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); + /* 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; + 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; - } + /* 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; + 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; - } - } + 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); + 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_t *t1000 = (t1000_t *)p; + egawrites++; -// pclog("CGA_WRITE %04X %02X\n", addr, val); - t1000->vram[addr & 0x3fff] = val; - cycles -= 4; + // pclog("CGA_WRITE %04X %02X\n", addr, val); + 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; + t1000_t *t1000 = (t1000_t *)p; + egareads++; + cycles -= 4; -// pclog("CGA_READ %04X\n", addr); - return t1000->vram[addr & 0x3fff]; + // pclog("CGA_READ %04X\n", addr); + return t1000->vram[addr & 0x3fff]; } static void t1000_recalctimings(t1000_t *t1000) { - double disptime; - double _dispontime, _dispofftime; + double disptime; + double _dispontime, _dispofftime; - if (!t1000->internal) { - cga_recalctimings(&t1000->cga); - return; - } - disptime = 651; - _dispontime = 640; - _dispofftime = disptime - _dispontime; - t1000->dispontime = (uint64_t)(_dispontime * (cpuclock / VID_CLOCK) * (double)(1ull << 32)); - t1000->dispofftime = (uint64_t)(_dispofftime * (cpuclock / VID_CLOCK) * (double)(1ull << 32)); + if (!t1000->internal) { + cga_recalctimings(&t1000->cga); + return; + } + disptime = 651; + _dispontime = 640; + _dispofftime = disptime - _dispontime; + t1000->dispontime = (uint64_t)(_dispontime * (cpuclock / VID_CLOCK) * (double)(1ull << 32)); + t1000->dispofftime = (uint64_t)(_dispofftime * (cpuclock / VID_CLOCK) * (double)(1ull << 32)); } /* 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; + 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; + 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)); + 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); + 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->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; - } + 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; + 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; + 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)); + 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); + 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->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; - } + 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; + 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; + 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); + 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 (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; - } - } + 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; + 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); + 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 (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; + for (c = 0; c < 4; c++) { + pattern = (dat & 0xC0) >> 6; + if (!(t1000->cga.cgamode & 8)) + pattern = 0; - switch (pattern & 3) { - 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; - } - } + switch (pattern & 3) { + 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; + t1000_t *t1000 = (t1000_t *)p; - if (t1000->video_options != st_video_options || - t1000->enabled != st_enabled) { - t1000->video_options = st_video_options; - t1000->enabled = st_enabled; + if (t1000->video_options != st_video_options || t1000->enabled != st_enabled) { + t1000->video_options = st_video_options; + t1000->enabled = st_enabled; - /* Set the font used for the external display */ - t1000->cga.fontbase = ((t1000->video_options & 3) * 256); + /* Set the font used for the external display */ + t1000->cga.fontbase = ((t1000->video_options & 3) * 256); - if (t1000->enabled) /* Disable internal chipset */ - mem_mapping_enable(&t1000->mapping); - else - mem_mapping_disable(&t1000->mapping); - } - /* 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->enabled) /* Disable internal chipset */ + mem_mapping_enable(&t1000->mapping); + else + mem_mapping_disable(&t1000->mapping); + } + /* 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) { - timer_advance_u64(&t1000->cga.timer, t1000->dispofftime); - t1000->cga.cgastat |= 1; - t1000->linepos = 1; - if (t1000->dispon) { - if (t1000->displine == 0) { - video_wait_for_buffer(); - } + if (!t1000->linepos) { + timer_advance_u64(&t1000->cga.timer, 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; - } - timer_advance_u64(&t1000->cga.timer, t1000->dispontime); - t1000->linepos = 0; + /* 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; + } + timer_advance_u64(&t1000->cga.timer, 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; - updatewindowsize(xsize, ysize); - } - video_blit_memtoscreen(0, 0, 0, ysize, xsize, ysize); + 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; + updatewindowsize(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; + 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; + if (t1000->cga.cgamode & 0x02) { + if (t1000->cga.cgamode & 0x10) + video_bpp = 1; + else + video_bpp = 2; - } else - video_bpp = 0; - t1000->cga.cgablink++; - } - } + } else + video_bpp = 0; + t1000->cga.cgablink++; + } + } } static void t1000_recalcattrs(t1000_t *t1000) { - int n; + 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 */ + /* 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); + /* 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; - } + /* 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; - } + /* 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; - } + /* 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() { - t1000_t *t1000 = malloc(sizeof(t1000_t)); - memset(t1000, 0, sizeof(t1000_t)); - cga_init(&t1000->cga); + t1000_t *t1000 = malloc(sizeof(t1000_t)); + memset(t1000, 0, sizeof(t1000_t)); + cga_init(&t1000->cga); - t1000->internal = 1; + t1000->internal = 1; - /* 16k video RAM */ - t1000->vram = malloc(0x4000); + /* 16k video RAM */ + t1000->vram = malloc(0x4000); - timer_set_callback(&t1000->cga.timer, t1000_poll); - timer_set_p(&t1000->cga.timer, t1000); + timer_set_callback(&t1000->cga.timer, t1000_poll); + timer_set_p(&t1000->cga.timer, 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); + /* 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); + /* 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; + /* 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; + t1000_t *t1000 = (t1000_t *)p; - free(t1000->vram); - free(t1000); + free(t1000->vram); + free(t1000); } static void t1000_speed_changed(void *p) { - t1000_t *t1000 = (t1000_t *)p; + t1000_t *t1000 = (t1000_t *)p; - t1000_recalctimings(t1000); + t1000_recalctimings(t1000); } -static 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 - } - }; +static 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}}; -device_t t1000_device = - { - "Toshiba T1000", - 0, - t1000_init, - t1000_close, - NULL, - t1000_speed_changed, - NULL, - NULL, - t1000_config - }; +device_t t1000_device = {"Toshiba T1000", 0, t1000_init, t1000_close, NULL, t1000_speed_changed, NULL, NULL, t1000_config}; diff --git a/src/video/vid_t3100e.c b/src/video/vid_t3100e.c index 4b1cb902..b66cca46 100644 --- a/src/video/vid_t3100e.c +++ b/src/video/vid_t3100e.c @@ -20,8 +20,8 @@ * * 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 @@ -33,7 +33,7 @@ void updatewindowsize(int x, int y); /* Mapping of attributes to colours */ static uint32_t amber, black; -static uint8_t boldcols[256]; /* Which attributes use the bold font */ +static uint8_t boldcols[256]; /* Which attributes use the bold font */ static uint32_t blinkcols[256][2]; static uint32_t normcols[256][2]; @@ -42,44 +42,38 @@ static uint32_t normcols[256][2]; * * Bit 3: Disable built-in video (for add-on card) * Bit 2: Thin font - * Bits 0,1: Font set (not currently implemented) + * Bits 0,1: Font set (not currently implemented) */ static uint8_t st_video_options; static uint8_t st_display_internal = -1; -void t3100e_video_options_set(uint8_t options) { - st_video_options = options; -} +void t3100e_video_options_set(uint8_t options) { st_video_options = options; } -void t3100e_display_set(uint8_t internal) { - st_display_internal = internal; -} +void t3100e_display_set(uint8_t internal) { st_display_internal = internal; } -uint8_t t3100e_display_get() { - return st_display_internal; -} +uint8_t t3100e_display_get() { return st_display_internal; } typedef struct t3100e_t { - mem_mapping_t mapping; + 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. */ + 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 font; /* Current font, 0-3 */ + int enabled; /* Hardware enabled, 0 or 1 */ + int internal; /* Using internal display? */ + uint8_t attrmap; /* Attribute mapping register */ - uint64_t dispontime, dispofftime; + uint64_t dispontime, dispofftime; - int linepos, displine; - int vc; - int dispon; - int vsynctime; - uint8_t video_options; + int linepos, displine; + int vc; + int dispon; + int vsynctime; + uint8_t video_options; - uint8_t *vram; + uint8_t *vram; } t3100e_t; void t3100e_recalctimings(t3100e_t *t3100e); @@ -88,555 +82,536 @@ 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; + 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); + /* 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; + 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; - } + /* 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; + 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; - } - } + 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); + 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_t *t3100e = (t3100e_t *)p; + egawrites++; -// pclog("CGA_WRITE %04X %02X\n", addr, val); - t3100e->vram[addr & 0x7fff] = val; - cycles -= 4; + // pclog("CGA_WRITE %04X %02X\n", addr, val); + 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; + t3100e_t *t3100e = (t3100e_t *)p; + egareads++; + cycles -= 4; -// pclog("CGA_READ %04X\n", addr); - return t3100e->vram[addr & 0x7fff]; + // pclog("CGA_READ %04X\n", addr); + return t3100e->vram[addr & 0x7fff]; } void t3100e_recalctimings(t3100e_t *t3100e) { - double disptime; - double _dispontime, _dispofftime; + double disptime; + double _dispontime, _dispofftime; - if (!t3100e->internal) { - cga_recalctimings(&t3100e->cga); - return; - } - disptime = 651; - _dispontime = 640; - _dispofftime = disptime - _dispontime; - t3100e->dispontime = (uint64_t)(_dispontime * (cpuclock / VID_CLOCK) * (double)(1ull << 32)); - t3100e->dispofftime = (uint64_t)(_dispofftime * (cpuclock / VID_CLOCK) * (double)(1ull << 32)); + if (!t3100e->internal) { + cga_recalctimings(&t3100e->cga); + return; + } + disptime = 651; + _dispontime = 640; + _dispofftime = disptime - _dispontime; + t3100e->dispontime = (uint64_t)(_dispontime * (cpuclock / VID_CLOCK) * (double)(1ull << 32)); + t3100e->dispofftime = (uint64_t)(_dispofftime * (cpuclock / VID_CLOCK) * (double)(1ull << 32)); } /* 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; + 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; + 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)); + 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); + 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->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; - } + 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; + 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; + 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)); + 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); + 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->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; - } + 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; + 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; + 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++; + 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; - } - } + 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, ink1; - uint16_t addr; + int x, c; + uint8_t dat, pattern; + uint32_t ink0, ink1; + 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++; + 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; + 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; - } - } + 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; + t3100e_t *t3100e = (t3100e_t *)p; - if (t3100e->video_options != st_video_options) { - t3100e->video_options = st_video_options; + 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); + 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); + /* 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; + } - } - /* 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) { + timer_advance_u64(&t3100e->cga.timer, t3100e->dispofftime); + t3100e->cga.cgastat |= 1; + t3100e->linepos = 1; + if (t3100e->dispon) { + if (t3100e->displine == 0) { + video_wait_for_buffer(); + } - if (!t3100e->linepos) { - timer_advance_u64(&t3100e->cga.timer, 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; + } + timer_advance_u64(&t3100e->cga.timer, t3100e->dispontime); + t3100e->linepos = 0; - /* 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; - } - timer_advance_u64(&t3100e->cga.timer, 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; + updatewindowsize(xsize, ysize); + } + video_blit_memtoscreen(0, 0, 0, ysize, xsize, ysize); - 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; - updatewindowsize(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; - 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; - if (t3100e->cga.cgamode & 0x02) { - if (t3100e->cga.cgamode & 0x10) - video_bpp = 1; - else - video_bpp = 2; - - } else - video_bpp = 0; - t3100e->cga.cgablink++; - } - } + } else + video_bpp = 0; + t3100e->cga.cgablink++; + } + } } void t3100e_recalcattrs(t3100e_t *t3100e) { - int n; + 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 */ + /* 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); + /* 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; - } + /* 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; - } + /* 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; - } + /* 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() { - t3100e_t *t3100e = malloc(sizeof(t3100e_t)); - memset(t3100e, 0, sizeof(t3100e_t)); - cga_init(&t3100e->cga); + t3100e_t *t3100e = malloc(sizeof(t3100e_t)); + memset(t3100e, 0, sizeof(t3100e_t)); + cga_init(&t3100e->cga); - t3100e->internal = 1; + t3100e->internal = 1; - /* 32k video RAM */ - t3100e->vram = malloc(0x8000); + /* 32k video RAM */ + t3100e->vram = malloc(0x8000); - timer_set_callback(&t3100e->cga.timer, t3100e_poll); - timer_set_p(&t3100e->cga.timer, t3100e); + timer_set_callback(&t3100e->cga.timer, t3100e_poll); + timer_set_p(&t3100e->cga.timer, 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); + /* 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); + /* 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; + /* 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; + t3100e_t *t3100e = (t3100e_t *)p; - free(t3100e->vram); - free(t3100e); + free(t3100e->vram); + free(t3100e); } void t3100e_speed_changed(void *p) { - t3100e_t *t3100e = (t3100e_t *)p; + t3100e_t *t3100e = (t3100e_t *)p; - t3100e_recalctimings(t3100e); + t3100e_recalctimings(t3100e); } -device_t t3100e_device = - { - "Toshiba T3100e", - 0, - t3100e_init, - t3100e_close, - NULL, - t3100e_speed_changed, - NULL, - NULL - }; +device_t t3100e_device = {"Toshiba T3100e", 0, t3100e_init, t3100e_close, NULL, t3100e_speed_changed, NULL, NULL}; diff --git a/src/video/vid_tandy.c b/src/video/vid_tandy.c index 7a4e3342..72b207b8 100644 --- a/src/video/vid_tandy.c +++ b/src/video/vid_tandy.c @@ -13,617 +13,608 @@ #define TANDY_COMPOSITE 1 typedef struct tandy_t { - mem_mapping_t mapping; - mem_mapping_t ram_mapping; + mem_mapping_t mapping; + mem_mapping_t ram_mapping; - uint8_t crtc[32]; - int crtcreg; + uint8_t crtc[32]; + int crtcreg; - int array_index; - uint8_t array[32]; - int memctrl;//=-1; - uint32_t base; - uint8_t mode, col; - uint8_t stat; + int array_index; + uint8_t array[32]; + int memctrl; //=-1; + uint32_t base; + uint8_t mode, col; + uint8_t stat; - uint8_t *vram, *b8000; - uint32_t b8000_mask; + uint8_t *vram, *b8000; + uint32_t b8000_mask; - int linepos, displine; - int sc, vc; - int dispon; - int con, coff, cursoron, blink; - int vsynctime, vadj; - uint16_t ma, maback; + int linepos, displine; + int sc, vc; + int dispon; + int con, coff, cursoron, blink; + int vsynctime, vadj; + uint16_t ma, maback; - uint64_t dispontime, dispofftime; - pc_timer_t timer; - int firstline, lastline; + uint64_t dispontime, dispofftime; + pc_timer_t timer; + int firstline, lastline; - int composite; + int composite; } tandy_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 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}; void tandy_recalcaddress(tandy_t *tandy); void tandy_recalctimings(tandy_t *tandy); void tandy_out(uint16_t addr, uint8_t val, void *p) { - tandy_t *tandy = (tandy_t *)p; - uint8_t old; -// pclog("Tandy OUT %04X %02X\n",addr,val); - switch (addr) { - case 0x3d0: - case 0x3d2: - case 0x3d4: - case 0x3d6:tandy->crtcreg = val & 0x1f; - return; - case 0x3d1: - case 0x3d3: - case 0x3d5: - case 0x3d7:old = tandy->crtc[tandy->crtcreg]; - tandy->crtc[tandy->crtcreg] = val & crtcmask[tandy->crtcreg]; - if (old != val) { - if (tandy->crtcreg < 0xe || tandy->crtcreg > 0x10) { - fullchange = changeframecount; - tandy_recalctimings(tandy); - } - } - return; - case 0x3d8:tandy->mode = val; - update_cga16_color(tandy->mode); - return; - case 0x3d9:tandy->col = val; - return; - case 0x3da:tandy->array_index = val & 0x1f; - break; - case 0x3de: - if (tandy->array_index & 16) - val &= 0xf; - tandy->array[tandy->array_index & 0x1f] = val; - break; - case 0x3df:tandy->memctrl = val; - tandy_recalcaddress(tandy); - break; - case 0xa0:mem_mapping_set_addr(&tandy->ram_mapping, ((val >> 1) & 7) * 128 * 1024, 0x20000); - tandy_recalcaddress(tandy); - break; - } + tandy_t *tandy = (tandy_t *)p; + uint8_t old; + // pclog("Tandy OUT %04X %02X\n",addr,val); + switch (addr) { + case 0x3d0: + case 0x3d2: + case 0x3d4: + case 0x3d6: + tandy->crtcreg = val & 0x1f; + return; + case 0x3d1: + case 0x3d3: + case 0x3d5: + case 0x3d7: + old = tandy->crtc[tandy->crtcreg]; + tandy->crtc[tandy->crtcreg] = val & crtcmask[tandy->crtcreg]; + if (old != val) { + if (tandy->crtcreg < 0xe || tandy->crtcreg > 0x10) { + fullchange = changeframecount; + tandy_recalctimings(tandy); + } + } + return; + case 0x3d8: + tandy->mode = val; + update_cga16_color(tandy->mode); + return; + case 0x3d9: + tandy->col = val; + return; + case 0x3da: + tandy->array_index = val & 0x1f; + break; + case 0x3de: + if (tandy->array_index & 16) + val &= 0xf; + tandy->array[tandy->array_index & 0x1f] = val; + break; + case 0x3df: + tandy->memctrl = val; + tandy_recalcaddress(tandy); + break; + case 0xa0: + mem_mapping_set_addr(&tandy->ram_mapping, ((val >> 1) & 7) * 128 * 1024, 0x20000); + tandy_recalcaddress(tandy); + break; + } } uint8_t tandy_in(uint16_t addr, void *p) { - tandy_t *tandy = (tandy_t *)p; -// if (addr!=0x3DA) pclog("Tandy IN %04X\n",addr); - switch (addr) { - case 0x3d4:return tandy->crtcreg; - case 0x3d5:return tandy->crtc[tandy->crtcreg]; - case 0x3da:return tandy->stat; - } - return 0xFF; + tandy_t *tandy = (tandy_t *)p; + // if (addr!=0x3DA) pclog("Tandy IN %04X\n",addr); + switch (addr) { + case 0x3d4: + return tandy->crtcreg; + case 0x3d5: + return tandy->crtc[tandy->crtcreg]; + case 0x3da: + return tandy->stat; + } + return 0xFF; } void tandy_recalcaddress(tandy_t *tandy) { - if ((tandy->memctrl & 0xc0) == 0xc0) { - tandy->vram = &ram[((tandy->memctrl & 0x06) << 14) + tandy->base]; - tandy->b8000 = &ram[((tandy->memctrl & 0x30) << 11) + tandy->base]; - tandy->b8000_mask = 0x7fff; -// printf("VRAM at %05X B8000 at %05X\n",((tandy->memctrl&0x6)<<14)+tandy->base,((tandy->memctrl&0x30)<<11)+tandy->base); - } else { - tandy->vram = &ram[((tandy->memctrl & 0x07) << 14) + tandy->base]; - tandy->b8000 = &ram[((tandy->memctrl & 0x38) << 11) + tandy->base]; - tandy->b8000_mask = 0x3fff; -// printf("VRAM at %05X B8000 at %05X\n",((tandy->memctrl&0x7)<<14)+tandy->base,((tandy->memctrl&0x38)<<11)+tandy->base); - } + if ((tandy->memctrl & 0xc0) == 0xc0) { + tandy->vram = &ram[((tandy->memctrl & 0x06) << 14) + tandy->base]; + tandy->b8000 = &ram[((tandy->memctrl & 0x30) << 11) + tandy->base]; + tandy->b8000_mask = 0x7fff; + // printf("VRAM at %05X B8000 at + // %05X\n",((tandy->memctrl&0x6)<<14)+tandy->base,((tandy->memctrl&0x30)<<11)+tandy->base); + } else { + tandy->vram = &ram[((tandy->memctrl & 0x07) << 14) + tandy->base]; + tandy->b8000 = &ram[((tandy->memctrl & 0x38) << 11) + tandy->base]; + tandy->b8000_mask = 0x3fff; + // printf("VRAM at %05X B8000 at + // %05X\n",((tandy->memctrl&0x7)<<14)+tandy->base,((tandy->memctrl&0x38)<<11)+tandy->base); + } } void tandy_ram_write(uint32_t addr, uint8_t val, void *p) { - tandy_t *tandy = (tandy_t *)p; -// pclog("Tandy RAM write %05X %02X %04X:%04X\n",addr,val,CS,pc); - ram[tandy->base + (addr & 0x1ffff)] = val; + tandy_t *tandy = (tandy_t *)p; + // pclog("Tandy RAM write %05X %02X %04X:%04X\n",addr,val,CS,pc); + ram[tandy->base + (addr & 0x1ffff)] = val; } uint8_t tandy_ram_read(uint32_t addr, void *p) { - tandy_t *tandy = (tandy_t *)p; -// pclog("Tandy RAM read %05X %02X %04X:%04X\n",addr,ram[tandy->base + (addr & 0x1ffff)],CS,pc); - return ram[tandy->base + (addr & 0x1ffff)]; + tandy_t *tandy = (tandy_t *)p; + // pclog("Tandy RAM read %05X %02X %04X:%04X\n",addr,ram[tandy->base + (addr & 0x1ffff)],CS,pc); + return ram[tandy->base + (addr & 0x1ffff)]; } void tandy_write(uint32_t addr, uint8_t val, void *p) { - tandy_t *tandy = (tandy_t *)p; - if (tandy->memctrl == -1) - return; + tandy_t *tandy = (tandy_t *)p; + if (tandy->memctrl == -1) + return; - egawrites++; -// pclog("Tandy VRAM write %05X %02X %04X:%04X %04X:%04X\n",addr,val,CS,pc,DS,SI); - tandy->b8000[addr & tandy->b8000_mask] = val; + egawrites++; + // pclog("Tandy VRAM write %05X %02X %04X:%04X %04X:%04X\n",addr,val,CS,pc,DS,SI); + tandy->b8000[addr & tandy->b8000_mask] = val; } uint8_t tandy_read(uint32_t addr, void *p) { - tandy_t *tandy = (tandy_t *)p; - if (tandy->memctrl == -1) - return 0xff; + tandy_t *tandy = (tandy_t *)p; + if (tandy->memctrl == -1) + return 0xff; - egareads++; -// pclog("Tandy VRAM read %05X %02X %04X:%04X\n",addr,tandy->b8000[addr&0x7FFF],CS,pc); - return tandy->b8000[addr & tandy->b8000_mask]; + egareads++; + // pclog("Tandy VRAM read %05X %02X %04X:%04X\n",addr,tandy->b8000[addr&0x7FFF],CS,pc); + return tandy->b8000[addr & tandy->b8000_mask]; } void tandy_recalctimings(tandy_t *tandy) { - double _dispontime, _dispofftime, disptime; - if (tandy->mode & 1) { - disptime = tandy->crtc[0] + 1; - _dispontime = tandy->crtc[1]; - } else { - disptime = (tandy->crtc[0] + 1) << 1; - _dispontime = tandy->crtc[1] << 1; - } - _dispofftime = disptime - _dispontime; - _dispontime *= CGACONST; - _dispofftime *= CGACONST; - tandy->dispontime = (uint64_t)_dispontime; - tandy->dispofftime = (uint64_t)_dispofftime; + double _dispontime, _dispofftime, disptime; + if (tandy->mode & 1) { + disptime = tandy->crtc[0] + 1; + _dispontime = tandy->crtc[1]; + } else { + disptime = (tandy->crtc[0] + 1) << 1; + _dispontime = tandy->crtc[1] << 1; + } + _dispofftime = disptime - _dispontime; + _dispontime *= CGACONST; + _dispofftime *= CGACONST; + tandy->dispontime = (uint64_t)_dispontime; + tandy->dispofftime = (uint64_t)_dispofftime; } void tandy_poll(void *p) { -// int *cgapal=cga4pal[((tandy->col&0x10)>>2)|((cgamode&4)>>1)|((cgacol&0x20)>>5)]; - tandy_t *tandy = (tandy_t *)p; - uint16_t ca = (tandy->crtc[15] | (tandy->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 (!tandy->linepos) { -// cgapal[0]=tandy->col&15; -// printf("Firstline %i Lastline %i tandy->displine %i\n",firstline,lastline,tandy->displine); - timer_advance_u64(&tandy->timer, tandy->dispofftime); - tandy->stat |= 1; - tandy->linepos = 1; - oldsc = tandy->sc; - if ((tandy->crtc[8] & 3) == 3) - tandy->sc = (tandy->sc << 1) & 7; - if (tandy->dispon) { - if (tandy->displine < tandy->firstline) { - tandy->firstline = tandy->displine; - video_wait_for_buffer(); -// printf("Firstline %i\n",firstline); - } - tandy->lastline = tandy->displine; - cols[0] = tandy->array[2] & 0xf; - for (c = 0; c < 8; c++) { - if (tandy->array[3] & 4) { - ((uint32_t *)buffer32->line[tandy->displine])[c] = cols[0]; - if (tandy->mode & 1) - ((uint32_t *)buffer32->line[tandy->displine])[c + (tandy->crtc[1] << 3) + 8] = cols[0]; - else - ((uint32_t *)buffer32->line[tandy->displine])[c + (tandy->crtc[1] << 4) + 8] = cols[0]; - } else if ((tandy->mode & 0x12) == 0x12) { - ((uint32_t *)buffer32->line[tandy->displine])[c] = 0; - if (tandy->mode & 1) - ((uint32_t *)buffer32->line[tandy->displine])[c + (tandy->crtc[1] << 3) + 8] = 0; - else - ((uint32_t *)buffer32->line[tandy->displine])[c + (tandy->crtc[1] << 4) + 8] = 0; - } else { - ((uint32_t *)buffer32->line[tandy->displine])[c] = tandy->col & 15; - if (tandy->mode & 1) - ((uint32_t *)buffer32->line[tandy->displine])[c + (tandy->crtc[1] << 3) + 8] = tandy->col & 15; - else - ((uint32_t *)buffer32->line[tandy->displine])[c + (tandy->crtc[1] << 4) + 8] = tandy->col & 15; - } - } -// printf("X %i %i\n",c+(crtc[1]<<4)+8,c+(crtc[1]<<3)+8); -// printf("Drawing %i %i %i\n",tandy->displine,vc,sc); - if ((tandy->array[3] & 0x10) && (tandy->mode & 1)) /*320x200x16*/ - { - for (x = 0; x < tandy->crtc[1]; x++) { - dat = (tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 3) * 0x2000)] << 8) | - tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 3) * 0x2000) + 1]; - tandy->ma++; - ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + 8] = - ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + 9] = tandy->array[((dat >> 12) & tandy->array[1]) + 16]; - ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + 10] = - ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + 11] = tandy->array[((dat >> 8) & tandy->array[1]) + 16]; - ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + 12] = - ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + 13] = tandy->array[((dat >> 4) & tandy->array[1]) + 16]; - ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + 14] = - ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + 15] = tandy->array[(dat & tandy->array[1]) + 16]; - } - } else if (tandy->array[3] & 0x10) /*160x200x16*/ - { - for (x = 0; x < tandy->crtc[1]; x++) { - dat = (tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 3) * 0x2000)] << 8) | - tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 3) * 0x2000) + 1]; - tandy->ma++; - ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 8] = - ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 9] = - ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 10] = - ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 11] = tandy->array[((dat >> 12) & tandy->array[1]) + 16]; - ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 12] = - ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 13] = - ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 14] = - ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 15] = tandy->array[((dat >> 8) & tandy->array[1]) + 16]; - ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 16] = - ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 17] = - ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 18] = - ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 19] = tandy->array[((dat >> 4) & tandy->array[1]) + 16]; - ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 20] = - ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 21] = - ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 22] = - ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 23] = tandy->array[(dat & tandy->array[1]) + 16]; - } - } else if (tandy->array[3] & 0x08) /*640x200x4 - this implementation is a complete guess!*/ - { - for (x = 0; x < tandy->crtc[1]; x++) { - dat = (tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 3) * 0x2000)] << 8) | - tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 3) * 0x2000) + 1]; - tandy->ma++; - for (c = 0; c < 8; c++) { - chr = (dat >> 7) & 1; - chr |= ((dat >> 14) & 2); - ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + 8 + c] = tandy->array[(chr & tandy->array[1]) + 16]; - dat <<= 1; - } - } - } else if (tandy->mode & 1) { - for (x = 0; x < tandy->crtc[1]; x++) { - chr = tandy->vram[(tandy->ma << 1) & 0x3fff]; - attr = tandy->vram[((tandy->ma << 1) + 1) & 0x3fff]; - drawcursor = ((tandy->ma == ca) && tandy->con && tandy->cursoron); - if (tandy->mode & 0x20) { - cols[1] = tandy->array[((attr & 15) & tandy->array[1]) + 16]; - cols[0] = tandy->array[(((attr >> 4) & 7) & tandy->array[1]) + 16]; - if ((tandy->blink & 16) && (attr & 0x80) && !drawcursor) - cols[1] = cols[0]; - } else { - cols[1] = tandy->array[((attr & 15) & tandy->array[1]) + 16]; - cols[0] = tandy->array[((attr >> 4) & tandy->array[1]) + 16]; - } - if (tandy->sc & 8) { - for (c = 0; c < 8; c++) - ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + c + 8] = cols[0]; - } else { - for (c = 0; c < 8; c++) - ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + c + 8] = cols[(fontdat[chr][tandy->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; - } -// if (!((ma^(crtc[15]|(crtc[14]<<8)))&0x3FFF)) printf("Cursor match! %04X\n",ma); - if (drawcursor) { - for (c = 0; c < 8; c++) - ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + c + 8] ^= 0xffffff; - } - tandy->ma++; - } - } else if (!(tandy->mode & 2)) { - for (x = 0; x < tandy->crtc[1]; x++) { - chr = tandy->vram[(tandy->ma << 1) & 0x3fff]; - attr = tandy->vram[((tandy->ma << 1) + 1) & 0x3fff]; - drawcursor = ((tandy->ma == ca) && tandy->con && tandy->cursoron); - if (tandy->mode & 0x20) { - cols[1] = tandy->array[((attr & 15) & tandy->array[1]) + 16]; - cols[0] = tandy->array[(((attr >> 4) & 7) & tandy->array[1]) + 16]; - if ((tandy->blink & 16) && (attr & 0x80) && !drawcursor) - cols[1] = cols[0]; - } else { - cols[1] = tandy->array[((attr & 15) & tandy->array[1]) + 16]; - cols[0] = tandy->array[((attr >> 4) & tandy->array[1]) + 16]; - } - tandy->ma++; - if (tandy->sc & 8) { - for (c = 0; c < 8; c++) - ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + (c << 1) + 8] = - ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + (c << 1) + 1 + 8] = cols[0]; - } else { - for (c = 0; c < 8; c++) - ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + (c << 1) + 8] = - ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][tandy->sc & 7] - & (1 << (c ^ 7))) ? 1 : 0]; - } - if (drawcursor) { - for (c = 0; c < 16; c++) - ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + c + 8] ^= 0xffffff; - } - } - } else if (!(tandy->mode & 16)) { - cols[0] = tandy->col & 15; - col = (tandy->col & 16) ? 8 : 0; - if (tandy->mode & 4) { - cols[1] = col | 3; - cols[2] = col | 4; - cols[3] = col | 7; - } else if (tandy->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 < tandy->crtc[1]; x++) { - dat = (tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 1) * 0x2000)] << 8) | - tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 1) * 0x2000) + 1]; - tandy->ma++; - for (c = 0; c < 8; c++) { - ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + (c << 1) + 8] = - ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14]; - dat <<= 2; - } - } - } else { - cols[0] = 0; - cols[1] = tandy->array[(tandy->col & tandy->array[1]) + 16]; - for (x = 0; x < tandy->crtc[1]; x++) { - dat = (tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 1) * 0x2000)] << 8) | - tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 1) * 0x2000) + 1]; - tandy->ma++; - for (c = 0; c < 16; c++) { - ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + c + 8] = cols[dat >> 15]; - dat <<= 1; - } - } - } - } else { - if (tandy->array[3] & 4) { - if (tandy->mode & 1) - hline(buffer32, 0, tandy->displine, (tandy->crtc[1] << 3) + 16, tandy->array[2] & 0xf); - else - hline(buffer32, 0, tandy->displine, (tandy->crtc[1] << 4) + 16, tandy->array[2] & 0xf); - } else { - cols[0] = ((tandy->mode & 0x12) == 0x12) ? 0 : (tandy->col & 0xf); - if (tandy->mode & 1) - hline(buffer32, 0, tandy->displine, (tandy->crtc[1] << 3) + 16, cols[0]); - else - hline(buffer32, 0, tandy->displine, (tandy->crtc[1] << 4) + 16, cols[0]); - } - } - if (tandy->mode & 1) - x = (tandy->crtc[1] << 3) + 16; - else - x = (tandy->crtc[1] << 4) + 16; + // int *cgapal=cga4pal[((tandy->col&0x10)>>2)|((cgamode&4)>>1)|((cgacol&0x20)>>5)]; + tandy_t *tandy = (tandy_t *)p; + uint16_t ca = (tandy->crtc[15] | (tandy->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 (!tandy->linepos) { + // cgapal[0]=tandy->col&15; + // printf("Firstline %i Lastline %i tandy->displine %i\n",firstline,lastline,tandy->displine); + timer_advance_u64(&tandy->timer, tandy->dispofftime); + tandy->stat |= 1; + tandy->linepos = 1; + oldsc = tandy->sc; + if ((tandy->crtc[8] & 3) == 3) + tandy->sc = (tandy->sc << 1) & 7; + if (tandy->dispon) { + if (tandy->displine < tandy->firstline) { + tandy->firstline = tandy->displine; + video_wait_for_buffer(); + // printf("Firstline %i\n",firstline); + } + tandy->lastline = tandy->displine; + cols[0] = tandy->array[2] & 0xf; + for (c = 0; c < 8; c++) { + if (tandy->array[3] & 4) { + ((uint32_t *)buffer32->line[tandy->displine])[c] = cols[0]; + if (tandy->mode & 1) + ((uint32_t *)buffer32->line[tandy->displine])[c + (tandy->crtc[1] << 3) + 8] = + cols[0]; + else + ((uint32_t *)buffer32->line[tandy->displine])[c + (tandy->crtc[1] << 4) + 8] = + cols[0]; + } else if ((tandy->mode & 0x12) == 0x12) { + ((uint32_t *)buffer32->line[tandy->displine])[c] = 0; + if (tandy->mode & 1) + ((uint32_t *)buffer32->line[tandy->displine])[c + (tandy->crtc[1] << 3) + 8] = 0; + else + ((uint32_t *)buffer32->line[tandy->displine])[c + (tandy->crtc[1] << 4) + 8] = 0; + } else { + ((uint32_t *)buffer32->line[tandy->displine])[c] = tandy->col & 15; + if (tandy->mode & 1) + ((uint32_t *)buffer32->line[tandy->displine])[c + (tandy->crtc[1] << 3) + 8] = + tandy->col & 15; + else + ((uint32_t *)buffer32->line[tandy->displine])[c + (tandy->crtc[1] << 4) + 8] = + tandy->col & 15; + } + } + // printf("X %i %i\n",c+(crtc[1]<<4)+8,c+(crtc[1]<<3)+8); + // printf("Drawing %i %i %i\n",tandy->displine,vc,sc); + if ((tandy->array[3] & 0x10) && (tandy->mode & 1)) /*320x200x16*/ + { + for (x = 0; x < tandy->crtc[1]; x++) { + dat = (tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 3) * 0x2000)] << 8) | + tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 3) * 0x2000) + 1]; + tandy->ma++; + ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + 8] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + 9] = + tandy->array[((dat >> 12) & tandy->array[1]) + 16]; + ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + 10] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + 11] = + tandy->array[((dat >> 8) & tandy->array[1]) + 16]; + ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + 12] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + 13] = + tandy->array[((dat >> 4) & tandy->array[1]) + 16]; + ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + 14] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + 15] = + tandy->array[(dat & tandy->array[1]) + 16]; + } + } else if (tandy->array[3] & 0x10) /*160x200x16*/ + { + for (x = 0; x < tandy->crtc[1]; x++) { + dat = (tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 3) * 0x2000)] << 8) | + tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 3) * 0x2000) + 1]; + tandy->ma++; + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 8] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 9] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 10] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 11] = + tandy->array[((dat >> 12) & tandy->array[1]) + 16]; + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 12] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 13] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 14] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 15] = + tandy->array[((dat >> 8) & tandy->array[1]) + 16]; + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 16] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 17] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 18] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 19] = + tandy->array[((dat >> 4) & tandy->array[1]) + 16]; + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 20] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 21] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 22] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 23] = + tandy->array[(dat & tandy->array[1]) + 16]; + } + } else if (tandy->array[3] & 0x08) /*640x200x4 - this implementation is a complete guess!*/ + { + for (x = 0; x < tandy->crtc[1]; x++) { + dat = (tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 3) * 0x2000)] << 8) | + tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 3) * 0x2000) + 1]; + tandy->ma++; + for (c = 0; c < 8; c++) { + chr = (dat >> 7) & 1; + chr |= ((dat >> 14) & 2); + ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + 8 + c] = + tandy->array[(chr & tandy->array[1]) + 16]; + dat <<= 1; + } + } + } else if (tandy->mode & 1) { + for (x = 0; x < tandy->crtc[1]; x++) { + chr = tandy->vram[(tandy->ma << 1) & 0x3fff]; + attr = tandy->vram[((tandy->ma << 1) + 1) & 0x3fff]; + drawcursor = ((tandy->ma == ca) && tandy->con && tandy->cursoron); + if (tandy->mode & 0x20) { + cols[1] = tandy->array[((attr & 15) & tandy->array[1]) + 16]; + cols[0] = tandy->array[(((attr >> 4) & 7) & tandy->array[1]) + 16]; + if ((tandy->blink & 16) && (attr & 0x80) && !drawcursor) + cols[1] = cols[0]; + } else { + cols[1] = tandy->array[((attr & 15) & tandy->array[1]) + 16]; + cols[0] = tandy->array[((attr >> 4) & tandy->array[1]) + 16]; + } + if (tandy->sc & 8) { + for (c = 0; c < 8; c++) + ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + c + 8] = cols[0]; + } else { + for (c = 0; c < 8; c++) + ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + c + 8] = + cols[(fontdat[chr][tandy->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; + } + // if (!((ma^(crtc[15]|(crtc[14]<<8)))&0x3FFF)) + // printf("Cursor match! %04X\n",ma); + if (drawcursor) { + for (c = 0; c < 8; c++) + ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + c + 8] ^= + 0xffffff; + } + tandy->ma++; + } + } else if (!(tandy->mode & 2)) { + for (x = 0; x < tandy->crtc[1]; x++) { + chr = tandy->vram[(tandy->ma << 1) & 0x3fff]; + attr = tandy->vram[((tandy->ma << 1) + 1) & 0x3fff]; + drawcursor = ((tandy->ma == ca) && tandy->con && tandy->cursoron); + if (tandy->mode & 0x20) { + cols[1] = tandy->array[((attr & 15) & tandy->array[1]) + 16]; + cols[0] = tandy->array[(((attr >> 4) & 7) & tandy->array[1]) + 16]; + if ((tandy->blink & 16) && (attr & 0x80) && !drawcursor) + cols[1] = cols[0]; + } else { + cols[1] = tandy->array[((attr & 15) & tandy->array[1]) + 16]; + cols[0] = tandy->array[((attr >> 4) & tandy->array[1]) + 16]; + } + tandy->ma++; + if (tandy->sc & 8) { + for (c = 0; c < 8; c++) + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + (c << 1) + 8] = + ((uint32_t *)buffer32 + ->line[tandy->displine])[(x << 4) + (c << 1) + 1 + 8] = + cols[0]; + } else { + for (c = 0; c < 8; c++) + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + (c << 1) + 8] = + ((uint32_t *)buffer32 + ->line[tandy->displine])[(x << 4) + (c << 1) + 1 + 8] = + cols[(fontdat[chr][tandy->sc & 7] & (1 << (c ^ 7))) ? 1 + : 0]; + } + if (drawcursor) { + for (c = 0; c < 16; c++) + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + c + 8] ^= + 0xffffff; + } + } + } else if (!(tandy->mode & 16)) { + cols[0] = tandy->col & 15; + col = (tandy->col & 16) ? 8 : 0; + if (tandy->mode & 4) { + cols[1] = col | 3; + cols[2] = col | 4; + cols[3] = col | 7; + } else if (tandy->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 < tandy->crtc[1]; x++) { + dat = (tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 1) * 0x2000)] << 8) | + tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 1) * 0x2000) + 1]; + tandy->ma++; + for (c = 0; c < 8; c++) { + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + (c << 1) + 8] = + ((uint32_t *) + buffer32->line[tandy->displine])[(x << 4) + (c << 1) + 1 + 8] = + cols[dat >> 14]; + dat <<= 2; + } + } + } else { + cols[0] = 0; + cols[1] = tandy->array[(tandy->col & tandy->array[1]) + 16]; + for (x = 0; x < tandy->crtc[1]; x++) { + dat = (tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 1) * 0x2000)] << 8) | + tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 1) * 0x2000) + 1]; + tandy->ma++; + for (c = 0; c < 16; c++) { + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + c + 8] = cols[dat >> 15]; + dat <<= 1; + } + } + } + } else { + if (tandy->array[3] & 4) { + if (tandy->mode & 1) + hline(buffer32, 0, tandy->displine, (tandy->crtc[1] << 3) + 16, tandy->array[2] & 0xf); + else + hline(buffer32, 0, tandy->displine, (tandy->crtc[1] << 4) + 16, tandy->array[2] & 0xf); + } else { + cols[0] = ((tandy->mode & 0x12) == 0x12) ? 0 : (tandy->col & 0xf); + if (tandy->mode & 1) + hline(buffer32, 0, tandy->displine, (tandy->crtc[1] << 3) + 16, cols[0]); + else + hline(buffer32, 0, tandy->displine, (tandy->crtc[1] << 4) + 16, cols[0]); + } + } + if (tandy->mode & 1) + x = (tandy->crtc[1] << 3) + 16; + else + x = (tandy->crtc[1] << 4) + 16; - if (tandy->composite) { - for (c = 0; c < x; c++) - buffer32->line[tandy->displine][c] = ((uint32_t *)buffer32->line[tandy->displine])[c] & 0xf; + if (tandy->composite) { + for (c = 0; c < x; c++) + buffer32->line[tandy->displine][c] = ((uint32_t *)buffer32->line[tandy->displine])[c] & 0xf; - Composite_Process(tandy->mode, 0, x >> 2, buffer32->line[tandy->displine]); - } else { - for (c = 0; c < x; c++) - ((uint32_t *)buffer32->line[tandy->displine])[c] = cgapal[((uint32_t *)buffer32->line[tandy->displine])[c] & 0xf]; - } + Composite_Process(tandy->mode, 0, x >> 2, buffer32->line[tandy->displine]); + } else { + for (c = 0; c < x; c++) + ((uint32_t *)buffer32->line[tandy->displine])[c] = + cgapal[((uint32_t *)buffer32->line[tandy->displine])[c] & 0xf]; + } - tandy->sc = oldsc; - if (tandy->vc == tandy->crtc[7] && !tandy->sc) { - tandy->stat |= 8; -// printf("VSYNC on %i %i\n",vc,sc); - } - tandy->displine++; - if (tandy->displine >= 360) - tandy->displine = 0; - } else { - timer_advance_u64(&tandy->timer, tandy->dispontime); - if (tandy->dispon) - tandy->stat &= ~1; - tandy->linepos = 0; - if (tandy->vsynctime) { - tandy->vsynctime--; - if (!tandy->vsynctime) { - tandy->stat &= ~8; -// printf("VSYNC off %i %i\n",vc,sc); - } - } - if (tandy->sc == (tandy->crtc[11] & 31) || ((tandy->crtc[8] & 3) == 3 && tandy->sc == ((tandy->crtc[11] & 31) >> 1))) { - tandy->con = 0; - tandy->coff = 1; - } - if (tandy->vadj) { - tandy->sc++; - tandy->sc &= 31; - tandy->ma = tandy->maback; - tandy->vadj--; - if (!tandy->vadj) { - tandy->dispon = 1; - tandy->ma = tandy->maback = (tandy->crtc[13] | (tandy->crtc[12] << 8)) & 0x3fff; - tandy->sc = 0; -// printf("Display on!\n"); - } - } else if (tandy->sc == tandy->crtc[9] || ((tandy->crtc[8] & 3) == 3 && tandy->sc == (tandy->crtc[9] >> 1))) { - tandy->maback = tandy->ma; -// con=0; -// coff=0; - tandy->sc = 0; - oldvc = tandy->vc; - tandy->vc++; - tandy->vc &= 127; -// printf("VC %i %i %i %i %i\n",vc,crtc[4],crtc[6],crtc[7],tandy->dispon); - if (tandy->vc == tandy->crtc[6]) - tandy->dispon = 0; - if (oldvc == tandy->crtc[4]) { -// printf("Display over at %i\n",tandy->displine); - tandy->vc = 0; - tandy->vadj = tandy->crtc[5]; - if (!tandy->vadj) - tandy->dispon = 1; - if (!tandy->vadj) - tandy->ma = tandy->maback = (tandy->crtc[13] | (tandy->crtc[12] << 8)) & 0x3fff; - if ((tandy->crtc[10] & 0x60) == 0x20) - tandy->cursoron = 0; - else - tandy->cursoron = tandy->blink & 16; -// printf("CRTC10 %02X %i\n",crtc[10],cursoron); - } - if (tandy->vc == tandy->crtc[7]) { - tandy->dispon = 0; - tandy->displine = 0; - tandy->vsynctime = 16;//(crtc[3]>>4)+1; -// printf("tandy->vsynctime %i %02X\n",tandy->vsynctime,crtc[3]); -// tandy->stat|=8; - if (tandy->crtc[7]) { -// printf("Lastline %i Firstline %i %i %i %i\n",lastline,firstline,lastline-firstline,crtc[1],xsize); - if (tandy->mode & 1) - x = (tandy->crtc[1] << 3) + 16; - else - x = (tandy->crtc[1] << 4) + 16; - tandy->lastline++; - if (x != xsize || (tandy->lastline - tandy->firstline) != ysize) { - xsize = x; - ysize = tandy->lastline - tandy->firstline; -// printf("Resize to %i,%i - R1 %i\n",xsize,ysize,crtc[1]); - if (xsize < 64) - xsize = 656; - if (ysize < 32) - ysize = 200; - updatewindowsize(xsize, (ysize << 1) + 16); - } -// printf("Blit %i %i\n",firstline,lastline); -//printf("Xsize is %i\n",xsize); + tandy->sc = oldsc; + if (tandy->vc == tandy->crtc[7] && !tandy->sc) { + tandy->stat |= 8; + // printf("VSYNC on %i %i\n",vc,sc); + } + tandy->displine++; + if (tandy->displine >= 360) + tandy->displine = 0; + } else { + timer_advance_u64(&tandy->timer, tandy->dispontime); + if (tandy->dispon) + tandy->stat &= ~1; + tandy->linepos = 0; + if (tandy->vsynctime) { + tandy->vsynctime--; + if (!tandy->vsynctime) { + tandy->stat &= ~8; + // printf("VSYNC off %i %i\n",vc,sc); + } + } + if (tandy->sc == (tandy->crtc[11] & 31) || + ((tandy->crtc[8] & 3) == 3 && tandy->sc == ((tandy->crtc[11] & 31) >> 1))) { + tandy->con = 0; + tandy->coff = 1; + } + if (tandy->vadj) { + tandy->sc++; + tandy->sc &= 31; + tandy->ma = tandy->maback; + tandy->vadj--; + if (!tandy->vadj) { + tandy->dispon = 1; + tandy->ma = tandy->maback = (tandy->crtc[13] | (tandy->crtc[12] << 8)) & 0x3fff; + tandy->sc = 0; + // printf("Display on!\n"); + } + } else if (tandy->sc == tandy->crtc[9] || ((tandy->crtc[8] & 3) == 3 && tandy->sc == (tandy->crtc[9] >> 1))) { + tandy->maback = tandy->ma; + // con=0; + // coff=0; + tandy->sc = 0; + oldvc = tandy->vc; + tandy->vc++; + tandy->vc &= 127; + // printf("VC %i %i %i %i %i\n",vc,crtc[4],crtc[6],crtc[7],tandy->dispon); + if (tandy->vc == tandy->crtc[6]) + tandy->dispon = 0; + if (oldvc == tandy->crtc[4]) { + // printf("Display over at %i\n",tandy->displine); + tandy->vc = 0; + tandy->vadj = tandy->crtc[5]; + if (!tandy->vadj) + tandy->dispon = 1; + if (!tandy->vadj) + tandy->ma = tandy->maback = (tandy->crtc[13] | (tandy->crtc[12] << 8)) & 0x3fff; + if ((tandy->crtc[10] & 0x60) == 0x20) + tandy->cursoron = 0; + else + tandy->cursoron = tandy->blink & 16; + // printf("CRTC10 %02X %i\n",crtc[10],cursoron); + } + if (tandy->vc == tandy->crtc[7]) { + tandy->dispon = 0; + tandy->displine = 0; + tandy->vsynctime = 16; //(crtc[3]>>4)+1; + // printf("tandy->vsynctime %i %02X\n",tandy->vsynctime,crtc[3]); + // tandy->stat|=8; + if (tandy->crtc[7]) { + // printf("Lastline %i Firstline %i %i %i + // %i\n",lastline,firstline,lastline-firstline,crtc[1],xsize); + if (tandy->mode & 1) + x = (tandy->crtc[1] << 3) + 16; + else + x = (tandy->crtc[1] << 4) + 16; + tandy->lastline++; + if (x != xsize || (tandy->lastline - tandy->firstline) != ysize) { + xsize = x; + ysize = tandy->lastline - tandy->firstline; + // printf("Resize to %i,%i - R1 + // %i\n",xsize,ysize,crtc[1]); + if (xsize < 64) + xsize = 656; + if (ysize < 32) + ysize = 200; + updatewindowsize(xsize, (ysize << 1) + 16); + } + // printf("Blit %i %i\n",firstline,lastline); + // printf("Xsize is %i\n",xsize); - video_blit_memtoscreen(0, tandy->firstline - 4, 0, (tandy->lastline - tandy->firstline) + 8, xsize, (tandy->lastline - tandy->firstline) + 8); + video_blit_memtoscreen(0, tandy->firstline - 4, 0, + (tandy->lastline - tandy->firstline) + 8, xsize, + (tandy->lastline - tandy->firstline) + 8); - frames++; - video_res_x = xsize - 16; - video_res_y = ysize; - if ((tandy->array[3] & 0x10) && (tandy->mode & 1)) /*320x200x16*/ - { - video_res_x /= 2; - video_bpp = 4; - } else if (tandy->array[3] & 0x10) /*160x200x16*/ - { - video_res_x /= 4; - video_bpp = 4; - } else if (tandy->array[3] & 0x08) /*640x200x4 - this implementation is a complete guess!*/ - video_bpp = 2; - else if (tandy->mode & 1) { - video_res_x /= 8; - video_res_y /= tandy->crtc[9] + 1; - video_bpp = 0; - } else if (!(tandy->mode & 2)) { - video_res_x /= 16; - video_res_y /= tandy->crtc[9] + 1; - video_bpp = 0; - } else if (!(tandy->mode & 16)) { - video_res_x /= 2; - video_bpp = 2; - } else - video_bpp = 1; - } - tandy->firstline = 1000; - tandy->lastline = 0; - tandy->blink++; - } - } else { - tandy->sc++; - tandy->sc &= 31; - tandy->ma = tandy->maback; - } - if ((tandy->sc == (tandy->crtc[10] & 31) || ((tandy->crtc[8] & 3) == 3 && tandy->sc == ((tandy->crtc[10] & 31) >> 1)))) - tandy->con = 1; - } + frames++; + video_res_x = xsize - 16; + video_res_y = ysize; + if ((tandy->array[3] & 0x10) && (tandy->mode & 1)) /*320x200x16*/ + { + video_res_x /= 2; + video_bpp = 4; + } else if (tandy->array[3] & 0x10) /*160x200x16*/ + { + video_res_x /= 4; + video_bpp = 4; + } else if (tandy->array[3] & + 0x08) /*640x200x4 - this implementation is a complete guess!*/ + video_bpp = 2; + else if (tandy->mode & 1) { + video_res_x /= 8; + video_res_y /= tandy->crtc[9] + 1; + video_bpp = 0; + } else if (!(tandy->mode & 2)) { + video_res_x /= 16; + video_res_y /= tandy->crtc[9] + 1; + video_bpp = 0; + } else if (!(tandy->mode & 16)) { + video_res_x /= 2; + video_bpp = 2; + } else + video_bpp = 1; + } + tandy->firstline = 1000; + tandy->lastline = 0; + tandy->blink++; + } + } else { + tandy->sc++; + tandy->sc &= 31; + tandy->ma = tandy->maback; + } + if ((tandy->sc == (tandy->crtc[10] & 31) || + ((tandy->crtc[8] & 3) == 3 && tandy->sc == ((tandy->crtc[10] & 31) >> 1)))) + tandy->con = 1; + } } void *tandy_init() { - int display_type; - tandy_t *tandy = malloc(sizeof(tandy_t)); - memset(tandy, 0, sizeof(tandy_t)); + int display_type; + tandy_t *tandy = malloc(sizeof(tandy_t)); + memset(tandy, 0, sizeof(tandy_t)); - display_type = model_get_config_int("display_type"); - tandy->composite = (display_type != TANDY_RGB); + display_type = model_get_config_int("display_type"); + tandy->composite = (display_type != TANDY_RGB); - cga_comp_init(1); - tandy->memctrl = -1; - tandy->base = (mem_size - 128) * 1024; + cga_comp_init(1); + tandy->memctrl = -1; + tandy->base = (mem_size - 128) * 1024; - timer_add(&tandy->timer, tandy_poll, tandy, 1); - mem_mapping_add(&tandy->mapping, 0xb8000, 0x08000, tandy_read, NULL, NULL, tandy_write, NULL, NULL, NULL, 0, tandy); - mem_mapping_add(&tandy->ram_mapping, 0x80000, 0x20000, tandy_ram_read, NULL, NULL, tandy_ram_write, NULL, NULL, NULL, 0, tandy); - /*Base 128k mapping is controlled via port 0xA0, so we remove it from the main mapping*/ - mem_mapping_set_addr(&ram_low_mapping, 0, (mem_size - 128) * 1024); - io_sethandler(0x03d0, 0x0010, tandy_in, NULL, NULL, tandy_out, NULL, NULL, tandy); - io_sethandler(0x00a0, 0x0001, tandy_in, NULL, NULL, tandy_out, NULL, NULL, tandy); - tandy->b8000_mask = 0x3fff; + timer_add(&tandy->timer, tandy_poll, tandy, 1); + mem_mapping_add(&tandy->mapping, 0xb8000, 0x08000, tandy_read, NULL, NULL, tandy_write, NULL, NULL, NULL, 0, tandy); + mem_mapping_add(&tandy->ram_mapping, 0x80000, 0x20000, tandy_ram_read, NULL, NULL, tandy_ram_write, NULL, NULL, NULL, 0, + tandy); + /*Base 128k mapping is controlled via port 0xA0, so we remove it from the main mapping*/ + mem_mapping_set_addr(&ram_low_mapping, 0, (mem_size - 128) * 1024); + io_sethandler(0x03d0, 0x0010, tandy_in, NULL, NULL, tandy_out, NULL, NULL, tandy); + io_sethandler(0x00a0, 0x0001, tandy_in, NULL, NULL, tandy_out, NULL, NULL, tandy); + tandy->b8000_mask = 0x3fff; - return tandy; + return tandy; } void tandy_close(void *p) { - tandy_t *tandy = (tandy_t *)p; + tandy_t *tandy = (tandy_t *)p; - free(tandy); + free(tandy); } void tandy_speed_changed(void *p) { - tandy_t *tandy = (tandy_t *)p; + tandy_t *tandy = (tandy_t *)p; - tandy_recalctimings(tandy); + tandy_recalctimings(tandy); } -device_t tandy_device = - { - "Tandy 1000 (video)", - 0, - tandy_init, - tandy_close, - NULL, - tandy_speed_changed, - NULL, - NULL - }; +device_t tandy_device = {"Tandy 1000 (video)", 0, tandy_init, tandy_close, NULL, tandy_speed_changed, NULL, NULL}; -static device_config_t tandy_config[] = - { - { - .name = "display_type", - .description = "Display type", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "RGB", - .value = TANDY_RGB - }, - { - .description = "Composite", - .value = TANDY_COMPOSITE - }, - { - .description = "" - } - }, - .default_int = TANDY_RGB - }, - { - .type = -1 - } - }; +static device_config_t tandy_config[] = {{.name = "display_type", + .description = "Display type", + .type = CONFIG_SELECTION, + .selection = {{.description = "RGB", .value = TANDY_RGB}, + {.description = "Composite", .value = TANDY_COMPOSITE}, + {.description = ""}}, + .default_int = TANDY_RGB}, + {.type = -1}}; /*These aren't really devices as such - more of a convenient way to hook in the config information*/ -device_t tandy1000_device = - { - "Tandy 1000", - 0, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - tandy_config - }; -device_t tandy1000hx_device = - { - "Tandy 1000HX", - 0, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - tandy_config - }; +device_t tandy1000_device = {"Tandy 1000", 0, NULL, NULL, NULL, NULL, NULL, NULL, tandy_config}; +device_t tandy1000hx_device = {"Tandy 1000HX", 0, NULL, NULL, NULL, NULL, NULL, NULL, tandy_config}; diff --git a/src/video/vid_tandysl.c b/src/video/vid_tandysl.c index b913d8cb..f64f4a09 100644 --- a/src/video/vid_tandysl.c +++ b/src/video/vid_tandysl.c @@ -9,41 +9,38 @@ #include "vid_tandysl.h" typedef struct tandysl_t { - mem_mapping_t mapping; - mem_mapping_t ram_mapping; - mem_mapping_t vram_mapping; + mem_mapping_t mapping; + mem_mapping_t ram_mapping; + mem_mapping_t vram_mapping; - uint8_t crtc[32]; - int crtcreg; + uint8_t crtc[32]; + int crtcreg; - int array_index; - uint8_t array[32]; - int memctrl;//=-1; - uint32_t base; - uint8_t mode, col; - uint8_t stat; + int array_index; + uint8_t array[32]; + int memctrl; //=-1; + uint32_t base; + uint8_t mode, col; + uint8_t stat; - uint8_t *vram, *b8000; - uint32_t b8000_limit; - uint8_t planar_ctrl; + uint8_t *vram, *b8000; + uint32_t b8000_limit; + uint8_t planar_ctrl; - int linepos, displine; - int sc, vc; - int dispon; - int con, coff, cursoron, blink; - int vsynctime, vadj; - uint16_t ma, maback; + int linepos, displine; + int sc, vc; + int dispon; + int con, coff, cursoron, blink; + int vsynctime, vadj; + uint16_t ma, maback; - uint64_t dispontime, dispofftime; - pc_timer_t timer; - int firstline, lastline; + uint64_t dispontime, dispofftime; + pc_timer_t timer; + int firstline, lastline; } tandysl_t; -static uint8_t crtcmask[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 uint8_t crtcmask[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 void tandysl_recalcaddress(tandysl_t *tandy); static void tandysl_recalctimings(tandysl_t *tandy); @@ -53,582 +50,623 @@ static void tandysl_ram_write(uint32_t addr, uint8_t val, void *p); static void tandysl_write(uint32_t addr, uint8_t val, void *p); static void tandysl_out(uint16_t addr, uint8_t val, void *p) { - tandysl_t *tandy = (tandysl_t *)p; - uint8_t old; -// pclog("TandySL OUT %04X %02X\n",addr,val); - switch (addr) { - case 0x3d0: - case 0x3d2: - case 0x3d4: - case 0x3d6:tandy->crtcreg = val & 0x1f; - return; - case 0x3d1: - case 0x3d3: - case 0x3d5: - case 0x3d7: -// pclog("Write CRTC R%02x %02x ",tandy->crtcreg, val); - old = tandy->crtc[tandy->crtcreg]; - tandy->crtc[tandy->crtcreg] = val & crtcmask[tandy->crtcreg]; -// pclog("now %02x\n", tandy->crtc[tandy->crtcreg]); - if (old != val) { - if (tandy->crtcreg < 0xe || tandy->crtcreg > 0x10) { - fullchange = changeframecount; - tandysl_recalctimings(tandy); - } - } - return; - case 0x3d8:tandy->mode = val; - return; - case 0x3d9:tandy->col = val; - return; - case 0x3da:tandy->array_index = val & 0x1f; - break; - case 0x3de: - if (tandy->array_index & 16) - val &= 0xf; - tandy->array[tandy->array_index & 0x1f] = val; - if ((tandy->array_index & 0x1f) == 5) { - tandysl_recalcmapping(tandy); - tandysl_recalcaddress(tandy); - } - break; - case 0x3df:tandy->memctrl = val; -// pclog("tandy 3df write %02x\n", val); - tandysl_recalcaddress(tandy); - break; - case 0x65: - if (val == 8) /*Hack*/ - return; - tandy->planar_ctrl = val; - tandysl_recalcmapping(tandy); - break; - case 0xffe8: - if ((val & 0xe) == 0xe) - mem_mapping_disable(&tandy->ram_mapping); - else - mem_mapping_set_addr(&tandy->ram_mapping, ((val >> 1) & 7) * 128 * 1024, 0x20000); - tandysl_recalcaddress(tandy); - break; - } + tandysl_t *tandy = (tandysl_t *)p; + uint8_t old; + // pclog("TandySL OUT %04X %02X\n",addr,val); + switch (addr) { + case 0x3d0: + case 0x3d2: + case 0x3d4: + case 0x3d6: + tandy->crtcreg = val & 0x1f; + return; + case 0x3d1: + case 0x3d3: + case 0x3d5: + case 0x3d7: + // pclog("Write CRTC R%02x %02x ",tandy->crtcreg, val); + old = tandy->crtc[tandy->crtcreg]; + tandy->crtc[tandy->crtcreg] = val & crtcmask[tandy->crtcreg]; + // pclog("now %02x\n", tandy->crtc[tandy->crtcreg]); + if (old != val) { + if (tandy->crtcreg < 0xe || tandy->crtcreg > 0x10) { + fullchange = changeframecount; + tandysl_recalctimings(tandy); + } + } + return; + case 0x3d8: + tandy->mode = val; + return; + case 0x3d9: + tandy->col = val; + return; + case 0x3da: + tandy->array_index = val & 0x1f; + break; + case 0x3de: + if (tandy->array_index & 16) + val &= 0xf; + tandy->array[tandy->array_index & 0x1f] = val; + if ((tandy->array_index & 0x1f) == 5) { + tandysl_recalcmapping(tandy); + tandysl_recalcaddress(tandy); + } + break; + case 0x3df: + tandy->memctrl = val; + // pclog("tandy 3df write %02x\n", val); + tandysl_recalcaddress(tandy); + break; + case 0x65: + if (val == 8) /*Hack*/ + return; + tandy->planar_ctrl = val; + tandysl_recalcmapping(tandy); + break; + case 0xffe8: + if ((val & 0xe) == 0xe) + mem_mapping_disable(&tandy->ram_mapping); + else + mem_mapping_set_addr(&tandy->ram_mapping, ((val >> 1) & 7) * 128 * 1024, 0x20000); + tandysl_recalcaddress(tandy); + break; + } } static uint8_t tandysl_in(uint16_t addr, void *p) { - tandysl_t *tandy = (tandysl_t *)p; -// if (addr!=0x3DA) pclog("Tandy IN %04X\n",addr); - switch (addr) { - case 0x3d4:return tandy->crtcreg; - case 0x3d5:return tandy->crtc[tandy->crtcreg]; - case 0x3da:return tandy->stat; - } -// pclog("Bad Tandy IN %04x\n", addr); - return 0xFF; + tandysl_t *tandy = (tandysl_t *)p; + // if (addr!=0x3DA) pclog("Tandy IN %04X\n",addr); + switch (addr) { + case 0x3d4: + return tandy->crtcreg; + case 0x3d5: + return tandy->crtc[tandy->crtcreg]; + case 0x3da: + return tandy->stat; + } + // pclog("Bad Tandy IN %04x\n", addr); + return 0xFF; } static void tandysl_recalcaddress(tandysl_t *tandy) { - tandy->b8000_limit = 0x8000; - if (tandy->array[5] & 1) { - tandy->vram = &ram[((tandy->memctrl & 0x04) << 14) + tandy->base]; - tandy->b8000 = &ram[((tandy->memctrl & 0x20) << 11) + tandy->base]; - } else if ((tandy->memctrl & 0xc0) == 0xc0) { - tandy->vram = &ram[((tandy->memctrl & 0x06) << 14) + tandy->base]; - tandy->b8000 = &ram[((tandy->memctrl & 0x30) << 11) + tandy->base]; -// printf("VRAM at %05X B8000 at %05X\n",((tandy->memctrl&0x6)<<14)+tandy->base,((tandy->memctrl&0x30)<<11)+tandy->base); - } else { - tandy->vram = &ram[((tandy->memctrl & 0x07) << 14) + tandy->base]; - tandy->b8000 = &ram[((tandy->memctrl & 0x38) << 11) + tandy->base]; -// printf("VRAM at %05X B8000 at %05X\n",((tandy->memctrl&0x7)<<14)+tandy->base,((tandy->memctrl&0x38)<<11)+tandy->base); - if ((tandy->memctrl & 0x38) == 0x38) - tandy->b8000_limit = 0x4000; - } + tandy->b8000_limit = 0x8000; + if (tandy->array[5] & 1) { + tandy->vram = &ram[((tandy->memctrl & 0x04) << 14) + tandy->base]; + tandy->b8000 = &ram[((tandy->memctrl & 0x20) << 11) + tandy->base]; + } else if ((tandy->memctrl & 0xc0) == 0xc0) { + tandy->vram = &ram[((tandy->memctrl & 0x06) << 14) + tandy->base]; + tandy->b8000 = &ram[((tandy->memctrl & 0x30) << 11) + tandy->base]; + // printf("VRAM at %05X B8000 at + // %05X\n",((tandy->memctrl&0x6)<<14)+tandy->base,((tandy->memctrl&0x30)<<11)+tandy->base); + } else { + tandy->vram = &ram[((tandy->memctrl & 0x07) << 14) + tandy->base]; + tandy->b8000 = &ram[((tandy->memctrl & 0x38) << 11) + tandy->base]; + // printf("VRAM at %05X B8000 at + // %05X\n",((tandy->memctrl&0x7)<<14)+tandy->base,((tandy->memctrl&0x38)<<11)+tandy->base); + if ((tandy->memctrl & 0x38) == 0x38) + tandy->b8000_limit = 0x4000; + } } static void tandysl_recalcmapping(tandysl_t *tandy) { - mem_mapping_disable(&tandy->mapping); - io_removehandler(0x03d0, 0x0010, tandysl_in, NULL, NULL, tandysl_out, NULL, NULL, tandy); - if (tandy->planar_ctrl & 4) { -// pclog("Enable VRAM mapping\n"); - mem_mapping_enable(&tandy->mapping); - if (tandy->array[5] & 1) { -// pclog("Tandy mapping at A0000 %p %p\n", tandy_ram_write, tandy_write); - mem_mapping_set_addr(&tandy->mapping, 0xa0000, 0x10000); - } else { -// pclog("Tandy mapping at B8000\n"); - mem_mapping_set_addr(&tandy->mapping, 0xb8000, 0x8000); - } -// mem_mapping_enable(&tandy->vram_mapping); - io_sethandler(0x03d0, 0x0010, tandysl_in, NULL, NULL, tandysl_out, NULL, NULL, tandy); - } else { -// pclog("Disable VRAM mapping\n"); - mem_mapping_disable(&tandy->mapping); -// mem_mapping_disable(&tandy->vram_mapping); - io_removehandler(0x03d0, 0x0010, tandysl_in, NULL, NULL, tandysl_out, NULL, NULL, tandy); - } + mem_mapping_disable(&tandy->mapping); + io_removehandler(0x03d0, 0x0010, tandysl_in, NULL, NULL, tandysl_out, NULL, NULL, tandy); + if (tandy->planar_ctrl & 4) { + // pclog("Enable VRAM mapping\n"); + mem_mapping_enable(&tandy->mapping); + if (tandy->array[5] & 1) { + // pclog("Tandy mapping at A0000 %p %p\n", tandy_ram_write, tandy_write); + mem_mapping_set_addr(&tandy->mapping, 0xa0000, 0x10000); + } else { + // pclog("Tandy mapping at B8000\n"); + mem_mapping_set_addr(&tandy->mapping, 0xb8000, 0x8000); + } + // mem_mapping_enable(&tandy->vram_mapping); + io_sethandler(0x03d0, 0x0010, tandysl_in, NULL, NULL, tandysl_out, NULL, NULL, tandy); + } else { + // pclog("Disable VRAM mapping\n"); + mem_mapping_disable(&tandy->mapping); + // mem_mapping_disable(&tandy->vram_mapping); + io_removehandler(0x03d0, 0x0010, tandysl_in, NULL, NULL, tandysl_out, NULL, NULL, tandy); + } } static void tandysl_ram_write(uint32_t addr, uint8_t val, void *p) { - tandysl_t *tandy = (tandysl_t *)p; -// pclog("Tandy RAM write %05X %02X %04X:%04X %08x\n",addr,val,CS,pc, tandy->base); - ram[tandy->base + (addr & 0x1ffff)] = val; + tandysl_t *tandy = (tandysl_t *)p; + // pclog("Tandy RAM write %05X %02X %04X:%04X %08x\n",addr,val,CS,pc, tandy->base); + ram[tandy->base + (addr & 0x1ffff)] = val; } static uint8_t tandysl_ram_read(uint32_t addr, void *p) { - tandysl_t *tandy = (tandysl_t *)p; -// if (!nopageerrors) pclog("Tandy RAM read %05X %02X %04X:%04X\n",addr,ram[tandy->base + (addr & 0x1ffff)],CS,pc); - return ram[tandy->base + (addr & 0x1ffff)]; + tandysl_t *tandy = (tandysl_t *)p; + // if (!nopageerrors) pclog("Tandy RAM read %05X %02X %04X:%04X\n",addr,ram[tandy->base + (addr & 0x1ffff)],CS,pc); + return ram[tandy->base + (addr & 0x1ffff)]; } static void tandysl_write(uint32_t addr, uint8_t val, void *p) { - tandysl_t *tandy = (tandysl_t *)p; - if (tandy->memctrl == -1) - return; + tandysl_t *tandy = (tandysl_t *)p; + if (tandy->memctrl == -1) + return; - egawrites++; -// pclog("Tandy VRAM write %05X %02X %04X:%04X %02x %x\n",addr,val,CS,pc,tandy->array[5], (uintptr_t)&tandy->b8000[addr & 0xffff] - (uintptr_t)ram); - if (tandy->array[5] & 1) - tandy->b8000[addr & 0xffff] = val; - else { - if ((addr & 0x7fff) >= tandy->b8000_limit) - return; - tandy->b8000[addr & 0x7fff] = val; - } + egawrites++; + // pclog("Tandy VRAM write %05X %02X %04X:%04X %02x %x\n",addr,val,CS,pc,tandy->array[5], + // (uintptr_t)&tandy->b8000[addr & 0xffff] - (uintptr_t)ram); + if (tandy->array[5] & 1) + tandy->b8000[addr & 0xffff] = val; + else { + if ((addr & 0x7fff) >= tandy->b8000_limit) + return; + tandy->b8000[addr & 0x7fff] = val; + } } static uint8_t tandysl_read(uint32_t addr, void *p) { - tandysl_t *tandy = (tandysl_t *)p; - if (tandy->memctrl == -1) - return 0xff; + tandysl_t *tandy = (tandysl_t *)p; + if (tandy->memctrl == -1) + return 0xff; - egareads++; -// if (!nopageerrors) pclog("Tandy VRAM read %05X %02X %04X:%04X\n",addr,tandy->b8000[addr&0x7FFF],CS,pc); - if (tandy->array[5] & 1) - return tandy->b8000[addr & 0xffff]; - if ((addr & 0x7fff) >= tandy->b8000_limit) - return 0xff; - return tandy->b8000[addr & 0x7fff]; + egareads++; + // if (!nopageerrors) pclog("Tandy VRAM read %05X %02X %04X:%04X\n",addr,tandy->b8000[addr&0x7FFF],CS,pc); + if (tandy->array[5] & 1) + return tandy->b8000[addr & 0xffff]; + if ((addr & 0x7fff) >= tandy->b8000_limit) + return 0xff; + return tandy->b8000[addr & 0x7fff]; } static void tandysl_recalctimings(tandysl_t *tandy) { - double _dispontime, _dispofftime, disptime; - if (tandy->mode & 1) { - disptime = tandy->crtc[0] + 1; - _dispontime = tandy->crtc[1]; - } else { - disptime = (tandy->crtc[0] + 1) << 1; - _dispontime = tandy->crtc[1] << 1; - } - _dispofftime = disptime - _dispontime; - _dispontime *= CGACONST; - _dispofftime *= CGACONST; - tandy->dispontime = (uint64_t)_dispontime; - tandy->dispofftime = (uint64_t)_dispofftime; + double _dispontime, _dispofftime, disptime; + if (tandy->mode & 1) { + disptime = tandy->crtc[0] + 1; + _dispontime = tandy->crtc[1]; + } else { + disptime = (tandy->crtc[0] + 1) << 1; + _dispontime = tandy->crtc[1] << 1; + } + _dispofftime = disptime - _dispontime; + _dispontime *= CGACONST; + _dispofftime *= CGACONST; + tandy->dispontime = (uint64_t)_dispontime; + tandy->dispofftime = (uint64_t)_dispofftime; } static void tandysl_poll(void *p) { - tandysl_t *tandy = (tandysl_t *)p; - uint16_t ca = (tandy->crtc[15] | (tandy->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; + tandysl_t *tandy = (tandysl_t *)p; + uint16_t ca = (tandy->crtc[15] | (tandy->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 (!tandy->linepos) { -// pclog("tandy_poll vc=%i sc=%i dispon=%i\n", tandy->vc, tandy->sc, tandy->dispon); -// cgapal[0]=tandy->col&15; -// printf("Firstline %i Lastline %i tandy->displine %i\n",firstline,lastline,tandy->displine); - timer_advance_u64(&tandy->timer, tandy->dispofftime); - tandy->stat |= 1; - tandy->linepos = 1; - oldsc = tandy->sc; - if ((tandy->crtc[8] & 3) == 3) - tandy->sc = (tandy->sc << 1) & 7; - if (tandy->dispon) { - if (tandy->displine < tandy->firstline) { - tandy->firstline = tandy->displine; - video_wait_for_buffer(); -// printf("Firstline %i\n",firstline); - } - tandy->lastline = tandy->displine; - cols[0] = cgapal[tandy->array[2] & 0xf]; - for (c = 0; c < 8; c++) { - if (tandy->array[3] & 4) { - ((uint32_t *)buffer32->line[tandy->displine])[c] = cols[0]; - if (tandy->mode & 1) - ((uint32_t *)buffer32->line[tandy->displine])[c + (tandy->crtc[1] << 3) + 8] = cols[0]; - else - ((uint32_t *)buffer32->line[tandy->displine])[c + (tandy->crtc[1] << 4) + 8] = cols[0]; - } else if ((tandy->mode & 0x12) == 0x12) { - ((uint32_t *)buffer32->line[tandy->displine])[c] = cgapal[0]; - if (tandy->mode & 1) - ((uint32_t *)buffer32->line[tandy->displine])[c + (tandy->crtc[1] << 3) + 8] = cgapal[0]; - else - ((uint32_t *)buffer32->line[tandy->displine])[c + (tandy->crtc[1] << 4) + 8] = cgapal[0]; - } else { - ((uint32_t *)buffer32->line[tandy->displine])[c] = cgapal[tandy->col & 15]; - if (tandy->mode & 1) - ((uint32_t *)buffer32->line[tandy->displine])[c + (tandy->crtc[1] << 3) + 8] = cgapal[tandy->col & 15]; - else - ((uint32_t *)buffer32->line[tandy->displine])[c + (tandy->crtc[1] << 4) + 8] = cgapal[tandy->col & 15]; - } - } - if (tandy->array[5] & 1) /*640x200x16*/ - { - for (x = 0; x < tandy->crtc[1] * 2; x++) { - dat = (tandy->vram[(tandy->ma << 1) & 0xffff] << 8) | - tandy->vram[((tandy->ma << 1) + 1) & 0xffff]; - tandy->ma++; - ((uint32_t *)buffer32->line[tandy->displine])[(x << 2) + 8] = cgapal[tandy->array[((dat >> 12) & 0xf)/*tandy->array[1])*/ + 16]]; - ((uint32_t *)buffer32->line[tandy->displine])[(x << 2) + 9] = cgapal[tandy->array[((dat >> 8) & 0xf)/*tandy->array[1])*/ + 16]]; - ((uint32_t *)buffer32->line[tandy->displine])[(x << 2) + 10] = cgapal[tandy->array[((dat >> 4) & 0xf)/*tandy->array[1])*/ + 16]]; - ((uint32_t *)buffer32->line[tandy->displine])[(x << 2) + 11] = cgapal[tandy->array[(dat & 0xf)/*tandy->array[1])*/ + 16]]; - } - } else if ((tandy->array[3] & 0x10) && (tandy->mode & 1)) /*320x200x16*/ - { - for (x = 0; x < tandy->crtc[1]; x++) { - dat = (tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 3) * 0x2000)] << 8) | - tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 3) * 0x2000) + 1]; - tandy->ma++; - ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + 8] = - ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + 9] = cgapal[tandy->array[((dat >> 12) & tandy->array[1]) + 16]]; - ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + 10] = - ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + 11] = cgapal[tandy->array[((dat >> 8) & tandy->array[1]) + 16]]; - ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + 12] = - ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + 13] = cgapal[tandy->array[((dat >> 4) & tandy->array[1]) + 16]]; - ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + 14] = - ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + 15] = cgapal[tandy->array[(dat & tandy->array[1]) + 16]]; - } - } else if (tandy->array[3] & 0x10) /*160x200x16*/ - { - for (x = 0; x < tandy->crtc[1]; x++) { - dat = (tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 1) * 0x2000)] << 8) | - tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 1) * 0x2000) + 1]; - tandy->ma++; - ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 8] = - ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 9] = - ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 10] = - ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 11] = cgapal[tandy->array[((dat >> 12) & tandy->array[1]) + 16]]; - ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 12] = - ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 13] = - ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 14] = - ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 15] = cgapal[tandy->array[((dat >> 8) & tandy->array[1]) + 16]]; - ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 16] = - ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 17] = - ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 18] = - ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 19] = cgapal[tandy->array[((dat >> 4) & tandy->array[1]) + 16]]; - ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 20] = - ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 21] = - ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 22] = - ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 23] = cgapal[tandy->array[(dat & tandy->array[1]) + 16]]; - } - } else if (tandy->array[3] & 0x08) /*640x200x4 - this implementation is a complete guess!*/ - { - for (x = 0; x < tandy->crtc[1]; x++) { - dat = (tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 3) * 0x2000)] << 8) | - tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 3) * 0x2000) + 1]; - tandy->ma++; - for (c = 0; c < 8; c++) { - chr = (dat >> 7) & 1; - chr |= ((dat >> 14) & 2); - ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + 8 + c] = cgapal[tandy->array[(chr & tandy->array[1]) + 16]]; - dat <<= 1; - } - } - } else if (tandy->mode & 1) { - for (x = 0; x < tandy->crtc[1]; x++) { - chr = tandy->vram[(tandy->ma << 1) & 0x3fff]; - attr = tandy->vram[((tandy->ma << 1) + 1) & 0x3fff]; - drawcursor = ((tandy->ma == ca) && tandy->con && tandy->cursoron); - if (tandy->mode & 0x20) { - cols[1] = cgapal[tandy->array[((attr & 15) & tandy->array[1]) + 16]]; - cols[0] = cgapal[tandy->array[(((attr >> 4) & 7) & tandy->array[1]) + 16]]; - if ((tandy->blink & 16) && (attr & 0x80) && !drawcursor) - cols[1] = cols[0]; - } else { - cols[1] = cgapal[tandy->array[((attr & 15) & tandy->array[1]) + 16]]; - cols[0] = cgapal[tandy->array[((attr >> 4) & tandy->array[1]) + 16]]; - } - if (tandy->sc & 8) { - for (c = 0; c < 8; c++) - ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + c + 8] = cols[0]; - } else { - for (c = 0; c < 8; c++) - ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + c + 8] = cols[(fontdat[chr][tandy->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; - } -// if (!((ma^(crtc[15]|(crtc[14]<<8)))&0x3FFF)) printf("Cursor match! %04X\n",ma); - if (drawcursor) { - for (c = 0; c < 8; c++) - ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + c + 8] ^= 0xffffff; - } - tandy->ma++; - } - } else if (!(tandy->mode & 2)) { - for (x = 0; x < tandy->crtc[1]; x++) { - chr = tandy->vram[(tandy->ma << 1) & 0x3fff]; - attr = tandy->vram[((tandy->ma << 1) + 1) & 0x3fff]; - drawcursor = ((tandy->ma == ca) && tandy->con && tandy->cursoron); - if (tandy->mode & 0x20) { - cols[1] = cgapal[tandy->array[((attr & 15) & tandy->array[1]) + 16]]; - cols[0] = cgapal[tandy->array[(((attr >> 4) & 7) & tandy->array[1]) + 16]]; - if ((tandy->blink & 16) && (attr & 0x80) && !drawcursor) - cols[1] = cols[0]; - } else { - cols[1] = cgapal[tandy->array[((attr & 15) & tandy->array[1]) + 16]]; - cols[0] = cgapal[tandy->array[((attr >> 4) & tandy->array[1]) + 16]]; - } - tandy->ma++; - if (tandy->sc & 8) { - for (c = 0; c < 8; c++) - ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + (c << 1) + 8] = - ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + (c << 1) + 1 + 8] = cols[0]; - } else { - for (c = 0; c < 8; c++) - ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + (c << 1) + 8] = - ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][tandy->sc & 7] - & (1 << (c ^ 7))) ? 1 : 0]; - } - if (drawcursor) { - for (c = 0; c < 16; c++) - ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + c + 8] ^= 0xffffff; - } - } - } else if (!(tandy->mode & 16)) { - cols[0] = cgapal[tandy->col & 15]; - col = (tandy->col & 16) ? 8 : 0; - if (tandy->mode & 4) { - cols[1] = cgapal[col | 3]; - cols[2] = cgapal[col | 4]; - cols[3] = cgapal[col | 7]; - } else if (tandy->col & 32) { - cols[1] = cgapal[col | 3]; - cols[2] = cgapal[col | 5]; - cols[3] = cgapal[col | 7]; - } else { - cols[1] = cgapal[col | 2]; - cols[2] = cgapal[col | 4]; - cols[3] = cgapal[col | 6]; - } - for (x = 0; x < tandy->crtc[1]; x++) { - dat = (tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 1) * 0x2000)] << 8) | - tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 1) * 0x2000) + 1]; - tandy->ma++; - for (c = 0; c < 8; c++) { - ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + (c << 1) + 8] = - ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14]; - dat <<= 2; - } - } - } else { - cols[0] = cgapal[0]; - cols[1] = cgapal[tandy->array[(tandy->col & tandy->array[1]) + 16]]; - for (x = 0; x < tandy->crtc[1]; x++) { - dat = (tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 1) * 0x2000)] << 8) | - tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 1) * 0x2000) + 1]; - tandy->ma++; - for (c = 0; c < 16; c++) { - ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + c + 8] = cols[dat >> 15]; - dat <<= 1; - } - } - } - } else { - if (tandy->array[3] & 4) { - if (tandy->mode & 1) - hline(buffer32, 0, tandy->displine, (tandy->crtc[1] << 3) + 16, cgapal[tandy->array[2] & 0xf]); - else - hline(buffer32, 0, tandy->displine, (tandy->crtc[1] << 4) + 16, cgapal[tandy->array[2] & 0xf]); - } else { - cols[0] = cgapal[((tandy->mode & 0x12) == 0x12) ? 0 : (tandy->col & 0xf)]; - if (tandy->mode & 1) - hline(buffer32, 0, tandy->displine, (tandy->crtc[1] << 3) + 16, cols[0]); - else - hline(buffer32, 0, tandy->displine, (tandy->crtc[1] << 4) + 16, cols[0]); - } - } - if (tandy->mode & 1) - x = (tandy->crtc[1] << 3) + 16; - else - x = (tandy->crtc[1] << 4) + 16; - tandy->sc = oldsc; - if (tandy->vc == tandy->crtc[7] && !tandy->sc) { - tandy->stat |= 8; -// printf("VSYNC on %i %i\n",vc,sc); - } - tandy->displine++; - if (tandy->displine >= 360) - tandy->displine = 0; - } else { - timer_advance_u64(&tandy->timer, tandy->dispontime); - if (tandy->dispon) - tandy->stat &= ~1; - tandy->linepos = 0; - if (tandy->vsynctime) { - tandy->vsynctime--; - if (!tandy->vsynctime) { - tandy->stat &= ~8; -// printf("VSYNC off %i %i\n",vc,sc); - } - } - if (tandy->sc == (tandy->crtc[11] & 31) || ((tandy->crtc[8] & 3) == 3 && tandy->sc == ((tandy->crtc[11] & 31) >> 1))) { - tandy->con = 0; - tandy->coff = 1; - } - if (tandy->vadj) { - tandy->sc++; - tandy->sc &= 31; - tandy->ma = tandy->maback; - tandy->vadj--; - if (!tandy->vadj) { - tandy->dispon = 1; - if (tandy->array[5] & 1) - tandy->ma = tandy->maback = tandy->crtc[13] | (tandy->crtc[12] << 8); - else - tandy->ma = tandy->maback = (tandy->crtc[13] | (tandy->crtc[12] << 8)) & 0x3fff; - tandy->sc = 0; -// printf("Display on!\n"); - } - } else if (tandy->sc == tandy->crtc[9] || ((tandy->crtc[8] & 3) == 3 && tandy->sc == (tandy->crtc[9] >> 1))) { - tandy->maback = tandy->ma; -// con=0; -// coff=0; - tandy->sc = 0; - oldvc = tandy->vc; - tandy->vc++; - tandy->vc &= 255; -// printf("VC %i %i %i %i %i\n",vc,crtc[4],crtc[6],crtc[7],tandy->dispon); - if (tandy->vc == tandy->crtc[6]) { -// pclog("Display off\n"); - tandy->dispon = 0; - } - if (oldvc == tandy->crtc[4]) { -// pclog("Display over\n"); -// printf("Display over at %i\n",tandy->displine); - tandy->vc = 0; - tandy->vadj = tandy->crtc[5]; - if (!tandy->vadj) - tandy->dispon = 1; - if (!tandy->vadj) { - if (tandy->array[5] & 1) - tandy->ma = tandy->maback = tandy->crtc[13] | (tandy->crtc[12] << 8); - else - tandy->ma = tandy->maback = (tandy->crtc[13] | (tandy->crtc[12] << 8)) & 0x3fff; - } - if ((tandy->crtc[10] & 0x60) == 0x20) - tandy->cursoron = 0; - else - tandy->cursoron = tandy->blink & 16; -// printf("CRTC10 %02X %i\n",crtc[10],cursoron); - } - if (tandy->vc == tandy->crtc[7]) { - tandy->dispon = 0; - tandy->displine = 0; - tandy->vsynctime = 16;//(crtc[3]>>4)+1; -// printf("tandy->vsynctime %i %02X\n",tandy->vsynctime,crtc[3]); -// tandy->stat|=8; - if (tandy->crtc[7]) { -// printf("Lastline %i Firstline %i %i %i %i\n",lastline,firstline,lastline-firstline,crtc[1],xsize); - if (tandy->mode & 1) - x = (tandy->crtc[1] << 3) + 16; - else - x = (tandy->crtc[1] << 4) + 16; - tandy->lastline++; - if (x != xsize || (tandy->lastline - tandy->firstline) != ysize) { - xsize = x; - ysize = tandy->lastline - tandy->firstline; -// printf("Resize to %i,%i - R1 %i\n",xsize,ysize,crtc[1]); - if (xsize < 64) - xsize = 656; - if (ysize < 32) - ysize = 200; - updatewindowsize(xsize, (ysize << 1) + 16); - } -// printf("Blit %i %i\n",firstline,lastline); -//printf("Xsize is %i\n",xsize); + if (!tandy->linepos) { + // pclog("tandy_poll vc=%i sc=%i dispon=%i\n", tandy->vc, tandy->sc, tandy->dispon); + // cgapal[0]=tandy->col&15; + // printf("Firstline %i Lastline %i tandy->displine %i\n",firstline,lastline,tandy->displine); + timer_advance_u64(&tandy->timer, tandy->dispofftime); + tandy->stat |= 1; + tandy->linepos = 1; + oldsc = tandy->sc; + if ((tandy->crtc[8] & 3) == 3) + tandy->sc = (tandy->sc << 1) & 7; + if (tandy->dispon) { + if (tandy->displine < tandy->firstline) { + tandy->firstline = tandy->displine; + video_wait_for_buffer(); + // printf("Firstline %i\n",firstline); + } + tandy->lastline = tandy->displine; + cols[0] = cgapal[tandy->array[2] & 0xf]; + for (c = 0; c < 8; c++) { + if (tandy->array[3] & 4) { + ((uint32_t *)buffer32->line[tandy->displine])[c] = cols[0]; + if (tandy->mode & 1) + ((uint32_t *)buffer32->line[tandy->displine])[c + (tandy->crtc[1] << 3) + 8] = + cols[0]; + else + ((uint32_t *)buffer32->line[tandy->displine])[c + (tandy->crtc[1] << 4) + 8] = + cols[0]; + } else if ((tandy->mode & 0x12) == 0x12) { + ((uint32_t *)buffer32->line[tandy->displine])[c] = cgapal[0]; + if (tandy->mode & 1) + ((uint32_t *)buffer32->line[tandy->displine])[c + (tandy->crtc[1] << 3) + 8] = + cgapal[0]; + else + ((uint32_t *)buffer32->line[tandy->displine])[c + (tandy->crtc[1] << 4) + 8] = + cgapal[0]; + } else { + ((uint32_t *)buffer32->line[tandy->displine])[c] = cgapal[tandy->col & 15]; + if (tandy->mode & 1) + ((uint32_t *)buffer32->line[tandy->displine])[c + (tandy->crtc[1] << 3) + 8] = + cgapal[tandy->col & 15]; + else + ((uint32_t *)buffer32->line[tandy->displine])[c + (tandy->crtc[1] << 4) + 8] = + cgapal[tandy->col & 15]; + } + } + if (tandy->array[5] & 1) /*640x200x16*/ + { + for (x = 0; x < tandy->crtc[1] * 2; x++) { + dat = (tandy->vram[(tandy->ma << 1) & 0xffff] << 8) | + tandy->vram[((tandy->ma << 1) + 1) & 0xffff]; + tandy->ma++; + ((uint32_t *)buffer32->line[tandy->displine])[(x << 2) + 8] = + cgapal[tandy->array[((dat >> 12) & 0xf) /*tandy->array[1])*/ + 16]]; + ((uint32_t *)buffer32->line[tandy->displine])[(x << 2) + 9] = + cgapal[tandy->array[((dat >> 8) & 0xf) /*tandy->array[1])*/ + 16]]; + ((uint32_t *)buffer32->line[tandy->displine])[(x << 2) + 10] = + cgapal[tandy->array[((dat >> 4) & 0xf) /*tandy->array[1])*/ + 16]]; + ((uint32_t *)buffer32->line[tandy->displine])[(x << 2) + 11] = + cgapal[tandy->array[(dat & 0xf) /*tandy->array[1])*/ + 16]]; + } + } else if ((tandy->array[3] & 0x10) && (tandy->mode & 1)) /*320x200x16*/ + { + for (x = 0; x < tandy->crtc[1]; x++) { + dat = (tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 3) * 0x2000)] << 8) | + tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 3) * 0x2000) + 1]; + tandy->ma++; + ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + 8] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + 9] = + cgapal[tandy->array[((dat >> 12) & tandy->array[1]) + 16]]; + ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + 10] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + 11] = + cgapal[tandy->array[((dat >> 8) & tandy->array[1]) + 16]]; + ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + 12] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + 13] = + cgapal[tandy->array[((dat >> 4) & tandy->array[1]) + 16]]; + ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + 14] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + 15] = + cgapal[tandy->array[(dat & tandy->array[1]) + 16]]; + } + } else if (tandy->array[3] & 0x10) /*160x200x16*/ + { + for (x = 0; x < tandy->crtc[1]; x++) { + dat = (tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 1) * 0x2000)] << 8) | + tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 1) * 0x2000) + 1]; + tandy->ma++; + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 8] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 9] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 10] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 11] = + cgapal[tandy->array[((dat >> 12) & tandy->array[1]) + + 16]]; + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 12] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 13] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 14] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 15] = + cgapal[tandy->array[((dat >> 8) & tandy->array[1]) + 16]]; + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 16] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 17] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 18] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 19] = + cgapal[tandy->array[((dat >> 4) & tandy->array[1]) + 16]]; + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 20] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 21] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 22] = + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + 23] = + cgapal[tandy->array[(dat & tandy->array[1]) + 16]]; + } + } else if (tandy->array[3] & 0x08) /*640x200x4 - this implementation is a complete guess!*/ + { + for (x = 0; x < tandy->crtc[1]; x++) { + dat = (tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 3) * 0x2000)] << 8) | + tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 3) * 0x2000) + 1]; + tandy->ma++; + for (c = 0; c < 8; c++) { + chr = (dat >> 7) & 1; + chr |= ((dat >> 14) & 2); + ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + 8 + c] = + cgapal[tandy->array[(chr & tandy->array[1]) + 16]]; + dat <<= 1; + } + } + } else if (tandy->mode & 1) { + for (x = 0; x < tandy->crtc[1]; x++) { + chr = tandy->vram[(tandy->ma << 1) & 0x3fff]; + attr = tandy->vram[((tandy->ma << 1) + 1) & 0x3fff]; + drawcursor = ((tandy->ma == ca) && tandy->con && tandy->cursoron); + if (tandy->mode & 0x20) { + cols[1] = cgapal[tandy->array[((attr & 15) & tandy->array[1]) + 16]]; + cols[0] = cgapal[tandy->array[(((attr >> 4) & 7) & tandy->array[1]) + 16]]; + if ((tandy->blink & 16) && (attr & 0x80) && !drawcursor) + cols[1] = cols[0]; + } else { + cols[1] = cgapal[tandy->array[((attr & 15) & tandy->array[1]) + 16]]; + cols[0] = cgapal[tandy->array[((attr >> 4) & tandy->array[1]) + 16]]; + } + if (tandy->sc & 8) { + for (c = 0; c < 8; c++) + ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + c + 8] = cols[0]; + } else { + for (c = 0; c < 8; c++) + ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + c + 8] = + cols[(fontdat[chr][tandy->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; + } + // if (!((ma^(crtc[15]|(crtc[14]<<8)))&0x3FFF)) + // printf("Cursor match! %04X\n",ma); + if (drawcursor) { + for (c = 0; c < 8; c++) + ((uint32_t *)buffer32->line[tandy->displine])[(x << 3) + c + 8] ^= + 0xffffff; + } + tandy->ma++; + } + } else if (!(tandy->mode & 2)) { + for (x = 0; x < tandy->crtc[1]; x++) { + chr = tandy->vram[(tandy->ma << 1) & 0x3fff]; + attr = tandy->vram[((tandy->ma << 1) + 1) & 0x3fff]; + drawcursor = ((tandy->ma == ca) && tandy->con && tandy->cursoron); + if (tandy->mode & 0x20) { + cols[1] = cgapal[tandy->array[((attr & 15) & tandy->array[1]) + 16]]; + cols[0] = cgapal[tandy->array[(((attr >> 4) & 7) & tandy->array[1]) + 16]]; + if ((tandy->blink & 16) && (attr & 0x80) && !drawcursor) + cols[1] = cols[0]; + } else { + cols[1] = cgapal[tandy->array[((attr & 15) & tandy->array[1]) + 16]]; + cols[0] = cgapal[tandy->array[((attr >> 4) & tandy->array[1]) + 16]]; + } + tandy->ma++; + if (tandy->sc & 8) { + for (c = 0; c < 8; c++) + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + (c << 1) + 8] = + ((uint32_t *)buffer32 + ->line[tandy->displine])[(x << 4) + (c << 1) + 1 + 8] = + cols[0]; + } else { + for (c = 0; c < 8; c++) + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + (c << 1) + 8] = + ((uint32_t *)buffer32 + ->line[tandy->displine])[(x << 4) + (c << 1) + 1 + 8] = + cols[(fontdat[chr][tandy->sc & 7] & (1 << (c ^ 7))) ? 1 + : 0]; + } + if (drawcursor) { + for (c = 0; c < 16; c++) + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + c + 8] ^= + 0xffffff; + } + } + } else if (!(tandy->mode & 16)) { + cols[0] = cgapal[tandy->col & 15]; + col = (tandy->col & 16) ? 8 : 0; + if (tandy->mode & 4) { + cols[1] = cgapal[col | 3]; + cols[2] = cgapal[col | 4]; + cols[3] = cgapal[col | 7]; + } else if (tandy->col & 32) { + cols[1] = cgapal[col | 3]; + cols[2] = cgapal[col | 5]; + cols[3] = cgapal[col | 7]; + } else { + cols[1] = cgapal[col | 2]; + cols[2] = cgapal[col | 4]; + cols[3] = cgapal[col | 6]; + } + for (x = 0; x < tandy->crtc[1]; x++) { + dat = (tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 1) * 0x2000)] << 8) | + tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 1) * 0x2000) + 1]; + tandy->ma++; + for (c = 0; c < 8; c++) { + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + (c << 1) + 8] = + ((uint32_t *) + buffer32->line[tandy->displine])[(x << 4) + (c << 1) + 1 + 8] = + cols[dat >> 14]; + dat <<= 2; + } + } + } else { + cols[0] = cgapal[0]; + cols[1] = cgapal[tandy->array[(tandy->col & tandy->array[1]) + 16]]; + for (x = 0; x < tandy->crtc[1]; x++) { + dat = (tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 1) * 0x2000)] << 8) | + tandy->vram[((tandy->ma << 1) & 0x1fff) + ((tandy->sc & 1) * 0x2000) + 1]; + tandy->ma++; + for (c = 0; c < 16; c++) { + ((uint32_t *)buffer32->line[tandy->displine])[(x << 4) + c + 8] = cols[dat >> 15]; + dat <<= 1; + } + } + } + } else { + if (tandy->array[3] & 4) { + if (tandy->mode & 1) + hline(buffer32, 0, tandy->displine, (tandy->crtc[1] << 3) + 16, + cgapal[tandy->array[2] & 0xf]); + else + hline(buffer32, 0, tandy->displine, (tandy->crtc[1] << 4) + 16, + cgapal[tandy->array[2] & 0xf]); + } else { + cols[0] = cgapal[((tandy->mode & 0x12) == 0x12) ? 0 : (tandy->col & 0xf)]; + if (tandy->mode & 1) + hline(buffer32, 0, tandy->displine, (tandy->crtc[1] << 3) + 16, cols[0]); + else + hline(buffer32, 0, tandy->displine, (tandy->crtc[1] << 4) + 16, cols[0]); + } + } + if (tandy->mode & 1) + x = (tandy->crtc[1] << 3) + 16; + else + x = (tandy->crtc[1] << 4) + 16; + tandy->sc = oldsc; + if (tandy->vc == tandy->crtc[7] && !tandy->sc) { + tandy->stat |= 8; + // printf("VSYNC on %i %i\n",vc,sc); + } + tandy->displine++; + if (tandy->displine >= 360) + tandy->displine = 0; + } else { + timer_advance_u64(&tandy->timer, tandy->dispontime); + if (tandy->dispon) + tandy->stat &= ~1; + tandy->linepos = 0; + if (tandy->vsynctime) { + tandy->vsynctime--; + if (!tandy->vsynctime) { + tandy->stat &= ~8; + // printf("VSYNC off %i %i\n",vc,sc); + } + } + if (tandy->sc == (tandy->crtc[11] & 31) || + ((tandy->crtc[8] & 3) == 3 && tandy->sc == ((tandy->crtc[11] & 31) >> 1))) { + tandy->con = 0; + tandy->coff = 1; + } + if (tandy->vadj) { + tandy->sc++; + tandy->sc &= 31; + tandy->ma = tandy->maback; + tandy->vadj--; + if (!tandy->vadj) { + tandy->dispon = 1; + if (tandy->array[5] & 1) + tandy->ma = tandy->maback = tandy->crtc[13] | (tandy->crtc[12] << 8); + else + tandy->ma = tandy->maback = (tandy->crtc[13] | (tandy->crtc[12] << 8)) & 0x3fff; + tandy->sc = 0; + // printf("Display on!\n"); + } + } else if (tandy->sc == tandy->crtc[9] || ((tandy->crtc[8] & 3) == 3 && tandy->sc == (tandy->crtc[9] >> 1))) { + tandy->maback = tandy->ma; + // con=0; + // coff=0; + tandy->sc = 0; + oldvc = tandy->vc; + tandy->vc++; + tandy->vc &= 255; + // printf("VC %i %i %i %i %i\n",vc,crtc[4],crtc[6],crtc[7],tandy->dispon); + if (tandy->vc == tandy->crtc[6]) { + // pclog("Display off\n"); + tandy->dispon = 0; + } + if (oldvc == tandy->crtc[4]) { + // pclog("Display over\n"); + // printf("Display over at %i\n",tandy->displine); + tandy->vc = 0; + tandy->vadj = tandy->crtc[5]; + if (!tandy->vadj) + tandy->dispon = 1; + if (!tandy->vadj) { + if (tandy->array[5] & 1) + tandy->ma = tandy->maback = tandy->crtc[13] | (tandy->crtc[12] << 8); + else + tandy->ma = tandy->maback = (tandy->crtc[13] | (tandy->crtc[12] << 8)) & 0x3fff; + } + if ((tandy->crtc[10] & 0x60) == 0x20) + tandy->cursoron = 0; + else + tandy->cursoron = tandy->blink & 16; + // printf("CRTC10 %02X %i\n",crtc[10],cursoron); + } + if (tandy->vc == tandy->crtc[7]) { + tandy->dispon = 0; + tandy->displine = 0; + tandy->vsynctime = 16; //(crtc[3]>>4)+1; + // printf("tandy->vsynctime %i %02X\n",tandy->vsynctime,crtc[3]); + // tandy->stat|=8; + if (tandy->crtc[7]) { + // printf("Lastline %i Firstline %i %i %i + // %i\n",lastline,firstline,lastline-firstline,crtc[1],xsize); + if (tandy->mode & 1) + x = (tandy->crtc[1] << 3) + 16; + else + x = (tandy->crtc[1] << 4) + 16; + tandy->lastline++; + if (x != xsize || (tandy->lastline - tandy->firstline) != ysize) { + xsize = x; + ysize = tandy->lastline - tandy->firstline; + // printf("Resize to %i,%i - R1 + // %i\n",xsize,ysize,crtc[1]); + if (xsize < 64) + xsize = 656; + if (ysize < 32) + ysize = 200; + updatewindowsize(xsize, (ysize << 1) + 16); + } + // printf("Blit %i %i\n",firstline,lastline); + // printf("Xsize is %i\n",xsize); - video_blit_memtoscreen(0, tandy->firstline - 4, 0, (tandy->lastline - tandy->firstline) + 8, xsize, (tandy->lastline - tandy->firstline) + 8); + video_blit_memtoscreen(0, tandy->firstline - 4, 0, + (tandy->lastline - tandy->firstline) + 8, xsize, + (tandy->lastline - tandy->firstline) + 8); - frames++; - video_res_x = xsize - 16; - video_res_y = ysize; - if ((tandy->array[3] & 0x10) && (tandy->mode & 1)) /*320x200x16*/ - { - video_res_x /= 2; - video_bpp = 4; - } else if (tandy->array[3] & 0x10) /*160x200x16*/ - { - video_res_x /= 4; - video_bpp = 4; - } else if (tandy->array[3] & 0x08) /*640x200x4 - this implementation is a complete guess!*/ - video_bpp = 2; - else if (tandy->mode & 1) { - video_res_x /= 8; - video_res_y /= tandy->crtc[9] + 1; - video_bpp = 0; - } else if (!(tandy->mode & 2)) { - video_res_x /= 16; - video_res_y /= tandy->crtc[9] + 1; - video_bpp = 0; - } else if (!(tandy->mode & 16)) { - video_res_x /= 2; - video_bpp = 2; - } else - video_bpp = 1; - } - tandy->firstline = 1000; - tandy->lastline = 0; - tandy->blink++; - } - } else { - tandy->sc++; - tandy->sc &= 31; - tandy->ma = tandy->maback; - } - if ((tandy->sc == (tandy->crtc[10] & 31) || ((tandy->crtc[8] & 3) == 3 && tandy->sc == ((tandy->crtc[10] & 31) >> 1)))) - tandy->con = 1; - } + frames++; + video_res_x = xsize - 16; + video_res_y = ysize; + if ((tandy->array[3] & 0x10) && (tandy->mode & 1)) /*320x200x16*/ + { + video_res_x /= 2; + video_bpp = 4; + } else if (tandy->array[3] & 0x10) /*160x200x16*/ + { + video_res_x /= 4; + video_bpp = 4; + } else if (tandy->array[3] & + 0x08) /*640x200x4 - this implementation is a complete guess!*/ + video_bpp = 2; + else if (tandy->mode & 1) { + video_res_x /= 8; + video_res_y /= tandy->crtc[9] + 1; + video_bpp = 0; + } else if (!(tandy->mode & 2)) { + video_res_x /= 16; + video_res_y /= tandy->crtc[9] + 1; + video_bpp = 0; + } else if (!(tandy->mode & 16)) { + video_res_x /= 2; + video_bpp = 2; + } else + video_bpp = 1; + } + tandy->firstline = 1000; + tandy->lastline = 0; + tandy->blink++; + } + } else { + tandy->sc++; + tandy->sc &= 31; + tandy->ma = tandy->maback; + } + if ((tandy->sc == (tandy->crtc[10] & 31) || + ((tandy->crtc[8] & 3) == 3 && tandy->sc == ((tandy->crtc[10] & 31) >> 1)))) + tandy->con = 1; + } } static void *tandysl_init() { - tandysl_t *tandy = malloc(sizeof(tandysl_t)); - memset(tandy, 0, sizeof(tandysl_t)); + tandysl_t *tandy = malloc(sizeof(tandysl_t)); + memset(tandy, 0, sizeof(tandysl_t)); - tandy->memctrl = -1; - tandy->base = (mem_size - 128) * 1024; - tandy->b8000_limit = 0x8000; - tandy->planar_ctrl = 4; + tandy->memctrl = -1; + tandy->base = (mem_size - 128) * 1024; + tandy->b8000_limit = 0x8000; + tandy->planar_ctrl = 4; - timer_add(&tandy->timer, tandysl_poll, tandy, 1); - mem_mapping_add(&tandy->mapping, 0xb8000, 0x08000, tandysl_read, NULL, NULL, tandysl_write, NULL, NULL, NULL, 0, tandy); - mem_mapping_add(&tandy->ram_mapping, 0x80000, 0x20000, tandysl_ram_read, NULL, NULL, tandysl_ram_write, NULL, NULL, NULL, 0, tandy); - /*Base 128k mapping is controlled via port 0xffe8, so we remove it from the main mapping*/ - mem_mapping_set_addr(&ram_low_mapping, 0, (mem_size - 128) * 1024); - io_sethandler(0x03d0, 0x0010, tandysl_in, NULL, NULL, tandysl_out, NULL, NULL, tandy); - io_sethandler(0xffe8, 0x0001, tandysl_in, NULL, NULL, tandysl_out, NULL, NULL, tandy); - io_sethandler(0x0065, 0x0001, tandysl_in, NULL, NULL, tandysl_out, NULL, NULL, tandy); - return tandy; + timer_add(&tandy->timer, tandysl_poll, tandy, 1); + mem_mapping_add(&tandy->mapping, 0xb8000, 0x08000, tandysl_read, NULL, NULL, tandysl_write, NULL, NULL, NULL, 0, tandy); + mem_mapping_add(&tandy->ram_mapping, 0x80000, 0x20000, tandysl_ram_read, NULL, NULL, tandysl_ram_write, NULL, NULL, NULL, + 0, tandy); + /*Base 128k mapping is controlled via port 0xffe8, so we remove it from the main mapping*/ + mem_mapping_set_addr(&ram_low_mapping, 0, (mem_size - 128) * 1024); + io_sethandler(0x03d0, 0x0010, tandysl_in, NULL, NULL, tandysl_out, NULL, NULL, tandy); + io_sethandler(0xffe8, 0x0001, tandysl_in, NULL, NULL, tandysl_out, NULL, NULL, tandy); + io_sethandler(0x0065, 0x0001, tandysl_in, NULL, NULL, tandysl_out, NULL, NULL, tandy); + return tandy; } static void tandysl_close(void *p) { - tandysl_t *tandy = (tandysl_t *)p; + tandysl_t *tandy = (tandysl_t *)p; - free(tandy); + free(tandy); } static void tandysl_speed_changed(void *p) { - tandysl_t *tandy = (tandysl_t *)p; + tandysl_t *tandy = (tandysl_t *)p; - tandysl_recalctimings(tandy); + tandysl_recalctimings(tandy); } -device_t tandysl_device = - { - "Tandy 1000SL (video)", - 0, - tandysl_init, - tandysl_close, - NULL, - tandysl_speed_changed, - NULL, - NULL - }; +device_t tandysl_device = {"Tandy 1000SL (video)", 0, tandysl_init, tandysl_close, NULL, tandysl_speed_changed, NULL, NULL}; diff --git a/src/video/vid_tgui9440.c b/src/video/vid_tgui9440.c index a9ebe176..3bd2e104 100644 --- a/src/video/vid_tgui9440.c +++ b/src/video/vid_tgui9440.c @@ -14,7 +14,7 @@ #include "vid_tgui9440.h" /*TGUI9400CXi has extended write modes, controlled by extended GDC registers : - + GDC[0x10] - Control bit 0 - pixel width (1 = 16 bit, 0 = 8 bit) bit 1 - mono->colour expansion (1 = enabled, 0 = disabled) @@ -26,7 +26,7 @@ GDC[0x15] - Foreground colour (high byte) GDC[0x17] - Write mask (low byte) GDC[0x18] - Write mask (high byte) - + Mono->colour expansion will expand written data 8:1 to 8/16 consecutive bytes. MSB is processed first. On word writes, low byte is processed first. 1 bits write foreground colour, 0 bits write background colour unless transparency is enabled. @@ -34,113 +34,110 @@ With 16-bit pixel width, each bit still expands to one byte, so the TGUI driver doubles up monochrome data. - + While there is room in the register map for three byte colours, I don't believe 24-bit colour is supported. The TGUI9440 blitter has the same limitation. - + I don't think double word writes are supported. - + Extended latch copy uses an internal 16 byte latch. Reads load the latch, writing writes out 16 bytes. I don't think the access size or host data has any affect, but the Windows 3.1 driver always reads bytes and write words of 0xffff.*/ -#define EXT_CTRL_16BIT 0x01 -#define EXT_CTRL_MONO_EXPANSION 0x02 +#define EXT_CTRL_16BIT 0x01 +#define EXT_CTRL_MONO_EXPANSION 0x02 #define EXT_CTRL_MONO_TRANSPARENT 0x04 -#define EXT_CTRL_LATCH_COPY 0x08 +#define EXT_CTRL_LATCH_COPY 0x08 #define FIFO_SIZE 65536 #define FIFO_MASK (FIFO_SIZE - 1) #define FIFO_ENTRY_SIZE (1 << 31) #define FIFO_ENTRIES (tgui->fifo_write_idx - tgui->fifo_read_idx) -#define FIFO_FULL ((tgui->fifo_write_idx - tgui->fifo_read_idx) >= FIFO_SIZE) -#define FIFO_EMPTY (tgui->fifo_read_idx == tgui->fifo_write_idx) +#define FIFO_FULL ((tgui->fifo_write_idx - tgui->fifo_read_idx) >= FIFO_SIZE) +#define FIFO_EMPTY (tgui->fifo_read_idx == tgui->fifo_write_idx) #define FIFO_TYPE 0xff000000 #define FIFO_ADDR 0x00ffffff -enum { - TGUI_9400CXI = 0, - TGUI_9440 -}; +enum { TGUI_9400CXI = 0, TGUI_9440 }; enum { - FIFO_INVALID = (0x00 << 24), - FIFO_WRITE_BYTE = (0x01 << 24), - FIFO_WRITE_FB_BYTE = (0x04 << 24), - FIFO_WRITE_FB_WORD = (0x05 << 24), - FIFO_WRITE_FB_LONG = (0x06 << 24) + FIFO_INVALID = (0x00 << 24), + FIFO_WRITE_BYTE = (0x01 << 24), + FIFO_WRITE_FB_BYTE = (0x04 << 24), + FIFO_WRITE_FB_WORD = (0x05 << 24), + FIFO_WRITE_FB_LONG = (0x06 << 24) }; typedef struct { - uint32_t addr_type; - uint32_t val; + uint32_t addr_type; + uint32_t val; } fifo_entry_t; typedef struct tgui_t { - mem_mapping_t linear_mapping; - mem_mapping_t accel_mapping; + mem_mapping_t linear_mapping; + mem_mapping_t accel_mapping; - rom_t bios_rom; + rom_t bios_rom; - svga_t svga; + svga_t svga; - tkd8001_ramdac_t ramdac; /*TGUI9400CXi*/ + tkd8001_ramdac_t ramdac; /*TGUI9400CXi*/ - int type; + int type; - struct { - uint16_t src_x, src_y; - uint16_t dst_x, dst_y; - uint16_t size_x, size_y; - uint16_t fg_col, bg_col; - uint8_t rop; - uint16_t flags; - uint8_t pattern[0x80]; - int command; - int offset; - uint8_t ger22; + struct { + uint16_t src_x, src_y; + uint16_t dst_x, dst_y; + uint16_t size_x, size_y; + uint16_t fg_col, bg_col; + uint8_t rop; + uint16_t flags; + uint8_t pattern[0x80]; + int command; + int offset; + uint8_t ger22; - int x, y; - uint32_t src, dst, src_old, dst_old; - int pat_x, pat_y; - int use_src; + int x, y; + uint32_t src, dst, src_old, dst_old; + int pat_x, pat_y; + int use_src; - int pitch, bpp; + int pitch, bpp; - uint16_t tgui_pattern[8][8]; - } accel; + uint16_t tgui_pattern[8][8]; + } accel; - uint8_t ext_gdc_regs[16]; /*TGUI9400CXi only*/ - uint8_t copy_latch[16]; + uint8_t ext_gdc_regs[16]; /*TGUI9400CXi only*/ + uint8_t copy_latch[16]; - uint8_t tgui_3d8, tgui_3d9; - int oldmode; - uint8_t oldctrl1; - uint8_t oldctrl2, newctrl2; + uint8_t tgui_3d8, tgui_3d9; + int oldmode; + uint8_t oldctrl1; + uint8_t oldctrl2, newctrl2; - uint32_t linear_base, linear_size; + uint32_t linear_base, linear_size; - int ramdac_state; - uint8_t ramdac_ctrl; + int ramdac_state; + uint8_t ramdac_ctrl; - int clock_m, clock_n, clock_k; + int clock_m, clock_n, clock_k; - uint32_t vram_size, vram_mask; + uint32_t vram_size, vram_mask; - fifo_entry_t fifo[FIFO_SIZE]; - volatile int fifo_read_idx, fifo_write_idx; + fifo_entry_t fifo[FIFO_SIZE]; + volatile int fifo_read_idx, fifo_write_idx; - thread_t *fifo_thread; - event_t *wake_fifo_thread; - event_t *fifo_not_full_event; + thread_t *fifo_thread; + event_t *wake_fifo_thread; + event_t *fifo_not_full_event; - int blitter_busy; - uint64_t blitter_time; - uint64_t status_time; + int blitter_busy; + uint64_t blitter_time; + uint64_t status_time; - volatile int write_blitter; + volatile int write_blitter; } tgui_t; void tgui_recalcmapping(tgui_t *tgui); @@ -170,1704 +167,1730 @@ static void tgui_ext_writew(uint32_t addr, uint16_t val, void *p); static void tgui_ext_writel(uint32_t addr, uint32_t val, void *p); void tgui_out(uint16_t addr, uint8_t val, void *p) { - tgui_t *tgui = (tgui_t *)p; - svga_t *svga = &tgui->svga; + tgui_t *tgui = (tgui_t *)p; + svga_t *svga = &tgui->svga; - uint8_t old; + uint8_t old; -// pclog("tgui_out : %04X %02X %04X:%04X %i\n", addr, val, CS,pc, svga->bpp); - if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1)) - addr ^= 0x60; + // pclog("tgui_out : %04X %02X %04X:%04X %i\n", addr, val, CS,pc, svga->bpp); + if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1)) + addr ^= 0x60; - switch (addr) { - case 0x3C5: - switch (svga->seqaddr & 0xf) { - case 0xB:tgui->oldmode = 1; - break; - case 0xC: - if (svga->seqregs[0xe] & 0x80) - svga->seqregs[0xc] = val; - break; - case 0xd: - if (tgui->oldmode) - tgui->oldctrl2 = val; - else - tgui->newctrl2 = val; - break; - case 0xE: - if (tgui->oldmode) - tgui->oldctrl1 = val; - else { - svga->seqregs[0xe] = val ^ 2; - svga->write_bank = (svga->seqregs[0xe] & 0xf) * 65536; - if (!(svga->gdcreg[0xf] & 1)) - svga->read_bank = svga->write_bank; - } - return; - } - break; + switch (addr) { + case 0x3C5: + switch (svga->seqaddr & 0xf) { + case 0xB: + tgui->oldmode = 1; + break; + case 0xC: + if (svga->seqregs[0xe] & 0x80) + svga->seqregs[0xc] = val; + break; + case 0xd: + if (tgui->oldmode) + tgui->oldctrl2 = val; + else + tgui->newctrl2 = val; + break; + case 0xE: + if (tgui->oldmode) + tgui->oldctrl1 = val; + else { + svga->seqregs[0xe] = val ^ 2; + svga->write_bank = (svga->seqregs[0xe] & 0xf) * 65536; + if (!(svga->gdcreg[0xf] & 1)) + svga->read_bank = svga->write_bank; + } + return; + } + break; - case 0x3C6: - if (tgui->type == TGUI_9400CXI) { - tkd8001_ramdac_out(addr, val, &tgui->ramdac, svga); - return; - } - if (tgui->ramdac_state == 4) { - tgui->ramdac_state = 0; - tgui->ramdac_ctrl = val; - switch (tgui->ramdac_ctrl & 0xf0) { - case 0x10:svga->bpp = 15; - break; - case 0x30:svga->bpp = 16; - break; - case 0xd0:svga->bpp = 24; - break; - default:svga->bpp = 8; - break; - } - return; - } - case 0x3C7: - case 0x3C8: - case 0x3C9: - if (tgui->type == TGUI_9400CXI) { - tkd8001_ramdac_out(addr, val, &tgui->ramdac, svga); - return; - } - tgui->ramdac_state = 0; - break; + case 0x3C6: + if (tgui->type == TGUI_9400CXI) { + tkd8001_ramdac_out(addr, val, &tgui->ramdac, svga); + return; + } + if (tgui->ramdac_state == 4) { + tgui->ramdac_state = 0; + tgui->ramdac_ctrl = val; + switch (tgui->ramdac_ctrl & 0xf0) { + case 0x10: + svga->bpp = 15; + break; + case 0x30: + svga->bpp = 16; + break; + case 0xd0: + svga->bpp = 24; + break; + default: + svga->bpp = 8; + break; + } + return; + } + case 0x3C7: + case 0x3C8: + case 0x3C9: + if (tgui->type == TGUI_9400CXI) { + tkd8001_ramdac_out(addr, val, &tgui->ramdac, svga); + return; + } + tgui->ramdac_state = 0; + break; - case 0x3CF: - if (tgui->type == TGUI_9400CXI && svga->gdcaddr >= 16 && svga->gdcaddr < 32) { - old = tgui->ext_gdc_regs[svga->gdcaddr & 15]; - tgui->ext_gdc_regs[svga->gdcaddr & 15] = val; - if (svga->gdcaddr == 16) - tgui_recalcmapping(tgui); - return; - } - switch (svga->gdcaddr & 15) { - case 0x6: - if (svga->gdcreg[6] != val) { - svga->gdcreg[6] = val; - tgui_recalcmapping(tgui); - } - return; + case 0x3CF: + if (tgui->type == TGUI_9400CXI && svga->gdcaddr >= 16 && svga->gdcaddr < 32) { + old = tgui->ext_gdc_regs[svga->gdcaddr & 15]; + tgui->ext_gdc_regs[svga->gdcaddr & 15] = val; + if (svga->gdcaddr == 16) + tgui_recalcmapping(tgui); + return; + } + switch (svga->gdcaddr & 15) { + case 0x6: + if (svga->gdcreg[6] != val) { + svga->gdcreg[6] = val; + tgui_recalcmapping(tgui); + } + return; - case 0xE:svga->gdcreg[0xe] = val ^ 2; - if ((svga->gdcreg[0xf] & 1) == 1) - svga->read_bank = (svga->gdcreg[0xe] & 0xf) * 65536; - break; - case 0xF: - if (val & 1) - svga->read_bank = (svga->gdcreg[0xe] & 0xf) * 65536; - else - svga->read_bank = (svga->seqregs[0xe] & 0xf) * 65536; - svga->write_bank = (svga->seqregs[0xe] & 0xf) * 65536; - break; - } - break; - case 0x3D4:svga->crtcreg = val & 0x7f; - return; - case 0x3D5: - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) - return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); - old = svga->crtc[svga->crtcreg]; - svga->crtc[svga->crtcreg] = val; -// if (svga->crtcreg != 0xE && svga->crtcreg != 0xF) pclog("CRTC R%02X = %02X\n", svga->crtcreg, val); - if (old != val) { - if (svga->crtcreg < 0xE || svga->crtcreg > 0x10) { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - } - switch (svga->crtcreg) { - case 0x21: - if (old != val) { - if (!PCI) { - tgui->linear_base = ((val & 0xf) | ((val >> 2) & 0x30)) << 20; - tgui->linear_size = (val & 0x10) ? 0x200000 : 0x100000; - tgui->svga.decode_mask = (val & 0x10) ? 0x1fffff : 0xfffff; - } - tgui_recalcmapping(tgui); - } - break; + case 0xE: + svga->gdcreg[0xe] = val ^ 2; + if ((svga->gdcreg[0xf] & 1) == 1) + svga->read_bank = (svga->gdcreg[0xe] & 0xf) * 65536; + break; + case 0xF: + if (val & 1) + svga->read_bank = (svga->gdcreg[0xe] & 0xf) * 65536; + else + svga->read_bank = (svga->seqregs[0xe] & 0xf) * 65536; + svga->write_bank = (svga->seqregs[0xe] & 0xf) * 65536; + break; + } + break; + case 0x3D4: + svga->crtcreg = val & 0x7f; + return; + case 0x3D5: + if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) + return; + if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) + val = (svga->crtc[7] & ~0x10) | (val & 0x10); + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; + // if (svga->crtcreg != 0xE && svga->crtcreg != 0xF) pclog("CRTC R%02X = %02X\n", svga->crtcreg, + // val); + if (old != val) { + if (svga->crtcreg < 0xE || svga->crtcreg > 0x10) { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } + } + switch (svga->crtcreg) { + case 0x21: + if (old != val) { + if (!PCI) { + tgui->linear_base = ((val & 0xf) | ((val >> 2) & 0x30)) << 20; + tgui->linear_size = (val & 0x10) ? 0x200000 : 0x100000; + tgui->svga.decode_mask = (val & 0x10) ? 0x1fffff : 0xfffff; + } + tgui_recalcmapping(tgui); + } + break; - case 0x40: - case 0x41: - case 0x42: - case 0x43: - case 0x44: - case 0x45: - case 0x46: - case 0x47: - if (tgui->type >= TGUI_9440) { - svga->hwcursor.x = (svga->crtc[0x40] | (svga->crtc[0x41] << 8)) & 0x7ff; - svga->hwcursor.y = (svga->crtc[0x42] | (svga->crtc[0x43] << 8)) & 0x7ff; - svga->hwcursor.xoff = svga->crtc[0x46] & 0x3f; - svga->hwcursor.yoff = svga->crtc[0x47] & 0x3f; - svga->hwcursor.addr = (svga->crtc[0x44] << 10) | ((svga->crtc[0x45] & 0x7) << 18) | (svga->hwcursor.yoff * 8); - } - break; + case 0x40: + case 0x41: + case 0x42: + case 0x43: + case 0x44: + case 0x45: + case 0x46: + case 0x47: + if (tgui->type >= TGUI_9440) { + svga->hwcursor.x = (svga->crtc[0x40] | (svga->crtc[0x41] << 8)) & 0x7ff; + svga->hwcursor.y = (svga->crtc[0x42] | (svga->crtc[0x43] << 8)) & 0x7ff; + svga->hwcursor.xoff = svga->crtc[0x46] & 0x3f; + svga->hwcursor.yoff = svga->crtc[0x47] & 0x3f; + svga->hwcursor.addr = + (svga->crtc[0x44] << 10) | ((svga->crtc[0x45] & 0x7) << 18) | (svga->hwcursor.yoff * 8); + } + break; - case 0x50: - if (tgui->type >= TGUI_9440) { - svga->hwcursor.ena = val & 0x80; - svga->hwcursor.xsize = (val & 1) ? 64 : 32; - svga->hwcursor.ysize = (val & 1) ? 64 : 32; - } - break; - } - return; - case 0x3D8:tgui->tgui_3d8 = val; - if (svga->gdcreg[0xf] & 4) { - svga->write_bank = (val & 0x1f) * 65536; -// pclog("SVGAWBANK 3D8 %08X %04X:%04X\n",svgawbank,CS,pc); - if (!(svga->gdcreg[0xf] & 1)) { - svga->read_bank = (val & 0x1f) * 65536; -// pclog("SVGARBANK 3D8 %08X %04X:%04X\n",svgarbank,CS,pc); - } - } - return; - case 0x3D9:tgui->tgui_3d9 = val; - if ((svga->gdcreg[0xf] & 5) == 5) { - svga->read_bank = (val & 0x1F) * 65536; -// pclog("SVGARBANK 3D9 %08X %04X:%04X\n",svgarbank,CS,pc); - } - return; + case 0x50: + if (tgui->type >= TGUI_9440) { + svga->hwcursor.ena = val & 0x80; + svga->hwcursor.xsize = (val & 1) ? 64 : 32; + svga->hwcursor.ysize = (val & 1) ? 64 : 32; + } + break; + } + return; + case 0x3D8: + tgui->tgui_3d8 = val; + if (svga->gdcreg[0xf] & 4) { + svga->write_bank = (val & 0x1f) * 65536; + // pclog("SVGAWBANK 3D8 %08X %04X:%04X\n",svgawbank,CS,pc); + if (!(svga->gdcreg[0xf] & 1)) { + svga->read_bank = (val & 0x1f) * 65536; + // pclog("SVGARBANK 3D8 %08X %04X:%04X\n",svgarbank,CS,pc); + } + } + return; + case 0x3D9: + tgui->tgui_3d9 = val; + if ((svga->gdcreg[0xf] & 5) == 5) { + svga->read_bank = (val & 0x1F) * 65536; + // pclog("SVGARBANK 3D9 %08X %04X:%04X\n",svgarbank,CS,pc); + } + return; - case 0x43c8:tgui->clock_n = val & 0x7f; - tgui->clock_m = (tgui->clock_m & ~1) | (val >> 7); - break; - case 0x43c9:tgui->clock_m = (tgui->clock_m & ~0x1e) | ((val << 1) & 0x1e); - tgui->clock_k = (val & 0x10) >> 4; - break; - } - svga_out(addr, val, svga); + case 0x43c8: + tgui->clock_n = val & 0x7f; + tgui->clock_m = (tgui->clock_m & ~1) | (val >> 7); + break; + case 0x43c9: + tgui->clock_m = (tgui->clock_m & ~0x1e) | ((val << 1) & 0x1e); + tgui->clock_k = (val & 0x10) >> 4; + break; + } + svga_out(addr, val, svga); } uint8_t tgui_in(uint16_t addr, void *p) { - tgui_t *tgui = (tgui_t *)p; - svga_t *svga = &tgui->svga; + tgui_t *tgui = (tgui_t *)p; + svga_t *svga = &tgui->svga; -// if (addr != 0x3da) pclog("tgui_in : %04X %04X:%04X\n", addr, CS,pc); + // if (addr != 0x3da) pclog("tgui_in : %04X %04X:%04X\n", addr, CS,pc); - if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1)) - addr ^= 0x60; + if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1)) + addr ^= 0x60; - switch (addr) { - case 0x3C5: - if ((svga->seqaddr & 0xf) == 0xb) { -// printf("Read Trident ID %04X:%04X %04X\n",CS,pc,readmemw(ss,SP)); - tgui->oldmode = 0; - switch (tgui->type) { - case TGUI_9400CXI:return 0x93; /*TGUI9400CXi*/ - case TGUI_9440:return 0xe3; /*TGUI9440AGi*/ - } - } - if ((svga->seqaddr & 0xf) == 0xc) { -// printf("Read Trident Power Up 1 %04X:%04X %04X\n",CS,pc,readmemw(ss,SP)); -// return 0x20; /*2 DRAM banks*/ - } - if ((svga->seqaddr & 0xf) == 0xd) { - if (tgui->oldmode) - return tgui->oldctrl2; - return tgui->newctrl2; - } - if ((svga->seqaddr & 0xf) == 0xe) { - if (tgui->oldmode) - return tgui->oldctrl1; - } - break; - case 0x3C6: - if (tgui->type == TGUI_9400CXI) - return tkd8001_ramdac_in(addr, &tgui->ramdac, svga); - if (tgui->ramdac_state == 4) - return tgui->ramdac_ctrl; - tgui->ramdac_state++; - break; - case 0x3C7: - case 0x3C8: - case 0x3C9: - if (tgui->type == TGUI_9400CXI) - return tkd8001_ramdac_in(addr, &tgui->ramdac, svga); - tgui->ramdac_state = 0; - break; - case 0x3CF: - if (tgui->type == TGUI_9400CXI && svga->gdcaddr >= 16 && svga->gdcaddr < 32) - return tgui->ext_gdc_regs[svga->gdcaddr & 15]; - break; - case 0x3D4:return svga->crtcreg; - case 0x3D5:return svga->crtc[svga->crtcreg]; - case 0x3d8:return tgui->tgui_3d8; - case 0x3d9:return tgui->tgui_3d9; - } - return svga_in(addr, svga); + switch (addr) { + case 0x3C5: + if ((svga->seqaddr & 0xf) == 0xb) { + // printf("Read Trident ID %04X:%04X %04X\n",CS,pc,readmemw(ss,SP)); + tgui->oldmode = 0; + switch (tgui->type) { + case TGUI_9400CXI: + return 0x93; /*TGUI9400CXi*/ + case TGUI_9440: + return 0xe3; /*TGUI9440AGi*/ + } + } + if ((svga->seqaddr & 0xf) == 0xc) { + // printf("Read Trident Power Up 1 %04X:%04X %04X\n",CS,pc,readmemw(ss,SP)); + // return 0x20; /*2 DRAM banks*/ + } + if ((svga->seqaddr & 0xf) == 0xd) { + if (tgui->oldmode) + return tgui->oldctrl2; + return tgui->newctrl2; + } + if ((svga->seqaddr & 0xf) == 0xe) { + if (tgui->oldmode) + return tgui->oldctrl1; + } + break; + case 0x3C6: + if (tgui->type == TGUI_9400CXI) + return tkd8001_ramdac_in(addr, &tgui->ramdac, svga); + if (tgui->ramdac_state == 4) + return tgui->ramdac_ctrl; + tgui->ramdac_state++; + break; + case 0x3C7: + case 0x3C8: + case 0x3C9: + if (tgui->type == TGUI_9400CXI) + return tkd8001_ramdac_in(addr, &tgui->ramdac, svga); + tgui->ramdac_state = 0; + break; + case 0x3CF: + if (tgui->type == TGUI_9400CXI && svga->gdcaddr >= 16 && svga->gdcaddr < 32) + return tgui->ext_gdc_regs[svga->gdcaddr & 15]; + break; + case 0x3D4: + return svga->crtcreg; + case 0x3D5: + return svga->crtc[svga->crtcreg]; + case 0x3d8: + return tgui->tgui_3d8; + case 0x3d9: + return tgui->tgui_3d9; + } + return svga_in(addr, svga); } void tgui_recalctimings(svga_t *svga) { - tgui_t *tgui = (tgui_t *)svga->p; + tgui_t *tgui = (tgui_t *)svga->p; - if (svga->crtc[0x29] & 0x10) - svga->rowoffset += 0x100; + if (svga->crtc[0x29] & 0x10) + svga->rowoffset += 0x100; - if (tgui->type >= TGUI_9440 && svga->bpp == 24) - svga->hdisp = (svga->crtc[1] + 1) * 8; + if (tgui->type >= TGUI_9440 && svga->bpp == 24) + svga->hdisp = (svga->crtc[1] + 1) * 8; - if ((svga->crtc[0x1e] & 0xA0) == 0xA0) - svga->ma_latch |= 0x10000; - if ((svga->crtc[0x27] & 0x01) == 0x01) - svga->ma_latch |= 0x20000; - if ((svga->crtc[0x27] & 0x02) == 0x02) - svga->ma_latch |= 0x40000; + if ((svga->crtc[0x1e] & 0xA0) == 0xA0) + svga->ma_latch |= 0x10000; + if ((svga->crtc[0x27] & 0x01) == 0x01) + svga->ma_latch |= 0x20000; + if ((svga->crtc[0x27] & 0x02) == 0x02) + svga->ma_latch |= 0x40000; - if (tgui->oldctrl2 & 0x10) - svga->rowoffset <<= 1; - if ((tgui->oldctrl2 & 0x10) || (svga->crtc[0x2a] & 0x40)) - svga->ma_latch <<= 1; + if (tgui->oldctrl2 & 0x10) + svga->rowoffset <<= 1; + if ((tgui->oldctrl2 & 0x10) || (svga->crtc[0x2a] & 0x40)) + svga->ma_latch <<= 1; - if (tgui->oldctrl2 & 0x10) /*I'm not convinced this is the right register for this function*/ - svga->lowres = 0; + if (tgui->oldctrl2 & 0x10) /*I'm not convinced this is the right register for this function*/ + svga->lowres = 0; - svga->lowres = !(svga->crtc[0x2a] & 0x40); + svga->lowres = !(svga->crtc[0x2a] & 0x40); - svga->interlace = svga->crtc[0x1e] & 4; - if (svga->interlace && tgui->type < TGUI_9440) - svga->rowoffset >>= 1; + svga->interlace = svga->crtc[0x1e] & 4; + if (svga->interlace && tgui->type < TGUI_9440) + svga->rowoffset >>= 1; - if (tgui->type >= TGUI_9440) { - if (svga->miscout & 8) - svga->clock = (cpuclock * (double)(1ull << 32)) / (((tgui->clock_n + 8) * 14318180.0) / ((tgui->clock_m + 2) * (1 << tgui->clock_k))); + if (tgui->type >= TGUI_9440) { + if (svga->miscout & 8) + svga->clock = (cpuclock * (double)(1ull << 32)) / + (((tgui->clock_n + 8) * 14318180.0) / ((tgui->clock_m + 2) * (1 << tgui->clock_k))); - if (svga->gdcreg[0xf] & 0x08) - svga->clock *= 2; - else if (svga->gdcreg[0xf] & 0x40) - svga->clock *= 3; - } else { - switch (((svga->miscout >> 2) & 3) | ((tgui->newctrl2 << 2) & 4) | ((tgui->newctrl2 >> 3) & 8)) { - case 0x02:svga->clock = (cpuclock * (double)(1ull << 32)) / 44900000.0; - break; - case 0x03:svga->clock = (cpuclock * (double)(1ull << 32)) / 36000000.0; - break; - case 0x04:svga->clock = (cpuclock * (double)(1ull << 32)) / 57272000.0; - break; - case 0x05:svga->clock = (cpuclock * (double)(1ull << 32)) / 65000000.0; - break; - case 0x06:svga->clock = (cpuclock * (double)(1ull << 32)) / 50350000.0; - break; - case 0x07:svga->clock = (cpuclock * (double)(1ull << 32)) / 40000000.0; - break; - case 0x08:svga->clock = (cpuclock * (double)(1ull << 32)) / 88000000.0; - break; - case 0x09:svga->clock = (cpuclock * (double)(1ull << 32)) / 98000000.0; - break; - case 0x0a:svga->clock = (cpuclock * (double)(1ull << 32)) / 118800000.0; - break; - case 0x0b:svga->clock = (cpuclock * (double)(1ull << 32)) / 108000000.0; - break; - case 0x0c:svga->clock = (cpuclock * (double)(1ull << 32)) / 72000000.0; - break; - case 0x0d:svga->clock = (cpuclock * (double)(1ull << 32)) / 77000000.0; - break; - case 0x0e:svga->clock = (cpuclock * (double)(1ull << 32)) / 80000000.0; - break; - case 0x0f:svga->clock = (cpuclock * (double)(1ull << 32)) / 75000000.0; - break; - } - if (svga->gdcreg[0xf] & 0x08) { - svga->htotal *= 2; - svga->hdisp *= 2; - svga->hdisp_time *= 2; - } - } + if (svga->gdcreg[0xf] & 0x08) + svga->clock *= 2; + else if (svga->gdcreg[0xf] & 0x40) + svga->clock *= 3; + } else { + switch (((svga->miscout >> 2) & 3) | ((tgui->newctrl2 << 2) & 4) | ((tgui->newctrl2 >> 3) & 8)) { + case 0x02: + svga->clock = (cpuclock * (double)(1ull << 32)) / 44900000.0; + break; + case 0x03: + svga->clock = (cpuclock * (double)(1ull << 32)) / 36000000.0; + break; + case 0x04: + svga->clock = (cpuclock * (double)(1ull << 32)) / 57272000.0; + break; + case 0x05: + svga->clock = (cpuclock * (double)(1ull << 32)) / 65000000.0; + break; + case 0x06: + svga->clock = (cpuclock * (double)(1ull << 32)) / 50350000.0; + break; + case 0x07: + svga->clock = (cpuclock * (double)(1ull << 32)) / 40000000.0; + break; + case 0x08: + svga->clock = (cpuclock * (double)(1ull << 32)) / 88000000.0; + break; + case 0x09: + svga->clock = (cpuclock * (double)(1ull << 32)) / 98000000.0; + break; + case 0x0a: + svga->clock = (cpuclock * (double)(1ull << 32)) / 118800000.0; + break; + case 0x0b: + svga->clock = (cpuclock * (double)(1ull << 32)) / 108000000.0; + break; + case 0x0c: + svga->clock = (cpuclock * (double)(1ull << 32)) / 72000000.0; + break; + case 0x0d: + svga->clock = (cpuclock * (double)(1ull << 32)) / 77000000.0; + break; + case 0x0e: + svga->clock = (cpuclock * (double)(1ull << 32)) / 80000000.0; + break; + case 0x0f: + svga->clock = (cpuclock * (double)(1ull << 32)) / 75000000.0; + break; + } + if (svga->gdcreg[0xf] & 0x08) { + svga->htotal *= 2; + svga->hdisp *= 2; + svga->hdisp_time *= 2; + } + } - if ((tgui->oldctrl2 & 0x10) || (svga->crtc[0x2a] & 0x40)) { - switch (svga->bpp) { - case 8:svga->render = svga_render_8bpp_highres; - break; - case 15:svga->render = svga_render_15bpp_highres; - if (tgui->type < TGUI_9440) - svga->hdisp /= 2; - break; - case 16:svga->render = svga_render_16bpp_highres; - if (tgui->type < TGUI_9440) - svga->hdisp /= 2; - break; - case 24:svga->render = svga_render_24bpp_highres; - if (tgui->type < TGUI_9440) - svga->hdisp = (svga->hdisp * 2) / 3; - break; - } - } + if ((tgui->oldctrl2 & 0x10) || (svga->crtc[0x2a] & 0x40)) { + switch (svga->bpp) { + case 8: + svga->render = svga_render_8bpp_highres; + break; + case 15: + svga->render = svga_render_15bpp_highres; + if (tgui->type < TGUI_9440) + svga->hdisp /= 2; + break; + case 16: + svga->render = svga_render_16bpp_highres; + if (tgui->type < TGUI_9440) + svga->hdisp /= 2; + break; + case 24: + svga->render = svga_render_24bpp_highres; + if (tgui->type < TGUI_9440) + svga->hdisp = (svga->hdisp * 2) / 3; + break; + } + } } void tgui_recalcmapping(tgui_t *tgui) { - svga_t *svga = &tgui->svga; + svga_t *svga = &tgui->svga; -// pclog("tgui_recalcmapping : %02X %02X\n", svga->crtc[0x21], svga->gdcreg[6]); + // pclog("tgui_recalcmapping : %02X %02X\n", svga->crtc[0x21], svga->gdcreg[6]); - if (tgui->type == TGUI_9400CXI) { - if (tgui->ext_gdc_regs[0] & EXT_CTRL_LATCH_COPY) { - mem_mapping_set_handler(&tgui->linear_mapping, - tgui_ext_linear_read, NULL, NULL, - tgui_ext_linear_write, tgui_ext_linear_writew, tgui_ext_linear_writel); - mem_mapping_set_handler(&svga->mapping, - tgui_ext_read, NULL, NULL, - tgui_ext_write, tgui_ext_writew, tgui_ext_writel); - } else if (tgui->ext_gdc_regs[0] & EXT_CTRL_MONO_EXPANSION) { - mem_mapping_set_handler(&tgui->linear_mapping, - svga_read_linear, svga_readw_linear, svga_readl_linear, - tgui_ext_linear_write, tgui_ext_linear_writew, tgui_ext_linear_writel); - mem_mapping_set_handler(&svga->mapping, - svga_read, svga_readw, svga_readl, - tgui_ext_write, tgui_ext_writew, tgui_ext_writel); - } else { - mem_mapping_set_handler(&tgui->linear_mapping, - svga_read_linear, svga_readw_linear, svga_readl_linear, - svga_write_linear, svga_writew_linear, svga_writel_linear); - mem_mapping_set_handler(&svga->mapping, - svga_read, svga_readw, svga_readl, - svga_write, svga_writew, svga_writel); - } - } + if (tgui->type == TGUI_9400CXI) { + if (tgui->ext_gdc_regs[0] & EXT_CTRL_LATCH_COPY) { + mem_mapping_set_handler(&tgui->linear_mapping, tgui_ext_linear_read, NULL, NULL, tgui_ext_linear_write, + tgui_ext_linear_writew, tgui_ext_linear_writel); + mem_mapping_set_handler(&svga->mapping, tgui_ext_read, NULL, NULL, tgui_ext_write, tgui_ext_writew, + tgui_ext_writel); + } else if (tgui->ext_gdc_regs[0] & EXT_CTRL_MONO_EXPANSION) { + mem_mapping_set_handler(&tgui->linear_mapping, svga_read_linear, svga_readw_linear, svga_readl_linear, + tgui_ext_linear_write, tgui_ext_linear_writew, tgui_ext_linear_writel); + mem_mapping_set_handler(&svga->mapping, svga_read, svga_readw, svga_readl, tgui_ext_write, + tgui_ext_writew, tgui_ext_writel); + } else { + mem_mapping_set_handler(&tgui->linear_mapping, svga_read_linear, svga_readw_linear, svga_readl_linear, + svga_write_linear, svga_writew_linear, svga_writel_linear); + mem_mapping_set_handler(&svga->mapping, svga_read, svga_readw, svga_readl, svga_write, svga_writew, + svga_writel); + } + } - if (svga->crtc[0x21] & 0x20) { - mem_mapping_disable(&svga->mapping); - mem_mapping_set_addr(&tgui->linear_mapping, tgui->linear_base, tgui->linear_size); -// pclog("Trident linear framebuffer at %08X - size %06X\n", tgui->linear_base, tgui->linear_size); - if (tgui->type >= TGUI_9440) { - mem_mapping_enable(&tgui->accel_mapping); - mem_mapping_disable(&svga->mapping); - } else { - switch (svga->gdcreg[6] & 0xC) { - case 0x0: /*128k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); - svga->banked_mask = 0xffff; - break; - case 0x4: /*64k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - svga->banked_mask = 0xffff; - break; - case 0x8: /*32k at B0000*/ - mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); - svga->banked_mask = 0x7fff; - break; - case 0xC: /*32k at B8000*/ - mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); - svga->banked_mask = 0x7fff; - break; - } - } - } else { -// pclog("Write mapping %02X\n", val); - mem_mapping_disable(&tgui->linear_mapping); - mem_mapping_disable(&tgui->accel_mapping); - switch (svga->gdcreg[6] & 0xC) { - case 0x0: /*128k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); - svga->banked_mask = 0xffff; - break; - case 0x4: /*64k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - mem_mapping_enable(&tgui->accel_mapping); - svga->banked_mask = 0xffff; - break; - case 0x8: /*32k at B0000*/ - mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); - svga->banked_mask = 0x7fff; - break; - case 0xC: /*32k at B8000*/ - mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); - svga->banked_mask = 0x7fff; - break; - } - } + if (svga->crtc[0x21] & 0x20) { + mem_mapping_disable(&svga->mapping); + mem_mapping_set_addr(&tgui->linear_mapping, tgui->linear_base, tgui->linear_size); + // pclog("Trident linear framebuffer at %08X - size %06X\n", tgui->linear_base, tgui->linear_size); + if (tgui->type >= TGUI_9440) { + mem_mapping_enable(&tgui->accel_mapping); + mem_mapping_disable(&svga->mapping); + } else { + switch (svga->gdcreg[6] & 0xC) { + case 0x0: /*128k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); + svga->banked_mask = 0xffff; + break; + case 0x4: /*64k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + svga->banked_mask = 0xffff; + break; + case 0x8: /*32k at B0000*/ + mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); + svga->banked_mask = 0x7fff; + break; + case 0xC: /*32k at B8000*/ + mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); + svga->banked_mask = 0x7fff; + break; + } + } + } else { + // pclog("Write mapping %02X\n", val); + mem_mapping_disable(&tgui->linear_mapping); + mem_mapping_disable(&tgui->accel_mapping); + switch (svga->gdcreg[6] & 0xC) { + case 0x0: /*128k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); + svga->banked_mask = 0xffff; + break; + case 0x4: /*64k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + mem_mapping_enable(&tgui->accel_mapping); + svga->banked_mask = 0xffff; + break; + case 0x8: /*32k at B0000*/ + mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); + svga->banked_mask = 0x7fff; + break; + case 0xC: /*32k at B8000*/ + mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); + svga->banked_mask = 0x7fff; + break; + } + } } /*Remap address for chain-4/doubleword style layout*/ static inline uint32_t dword_remap(uint32_t in_addr) { - return ((in_addr << 2) & 0x3fff0) | - ((in_addr >> 14) & 0xc) | - (in_addr & ~0x3fffc); + return ((in_addr << 2) & 0x3fff0) | ((in_addr >> 14) & 0xc) | (in_addr & ~0x3fffc); } static inline uint32_t dword_remap_w(uint32_t in_addr) { - return ((in_addr << 2) & 0x1fff8) | - ((in_addr >> 14) & 0x6) | - (in_addr & ~0x1fffe); + return ((in_addr << 2) & 0x1fff8) | ((in_addr >> 14) & 0x6) | (in_addr & ~0x1fffe); } void tgui_hwcursor_draw(svga_t *svga, int displine) { - uint32_t dat[2]; - int xx; - int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; - uint32_t remapped_addr; + uint32_t dat[2]; + int xx; + int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; + uint32_t remapped_addr; - if (svga->interlace && svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += 8; + if (svga->interlace && svga->hwcursor_oddeven) + svga->hwcursor_latch.addr += 8; - remapped_addr = dword_remap(svga->hwcursor_latch.addr); - dat[0] = (svga->vram[remapped_addr] << 24) | (svga->vram[remapped_addr + 1] << 16) | (svga->vram[remapped_addr + 2] << 8) | svga->vram[remapped_addr + 3]; - remapped_addr = dword_remap(svga->hwcursor_latch.addr + 4); - dat[1] = (svga->vram[remapped_addr] << 24) | (svga->vram[remapped_addr + 1] << 16) | (svga->vram[remapped_addr + 2] << 8) | svga->vram[remapped_addr + 3]; - for (xx = 0; xx < 32; xx++) { - if (offset >= svga->hwcursor_latch.x) { - if (!(dat[0] & 0x80000000)) - ((uint32_t *)buffer32->line[displine])[offset + 32] = (dat[1] & 0x80000000) ? 0xffffff : 0; - else if (dat[1] & 0x80000000) - ((uint32_t *)buffer32->line[displine])[offset + 32] ^= 0xffffff; -// pclog("Plot %i, %i (%i %i) %04X %04X\n", offset, displine, x+xx, svga_hwcursor_on, dat[0], dat[1]); - } + remapped_addr = dword_remap(svga->hwcursor_latch.addr); + dat[0] = (svga->vram[remapped_addr] << 24) | (svga->vram[remapped_addr + 1] << 16) | + (svga->vram[remapped_addr + 2] << 8) | svga->vram[remapped_addr + 3]; + remapped_addr = dword_remap(svga->hwcursor_latch.addr + 4); + dat[1] = (svga->vram[remapped_addr] << 24) | (svga->vram[remapped_addr + 1] << 16) | + (svga->vram[remapped_addr + 2] << 8) | svga->vram[remapped_addr + 3]; + for (xx = 0; xx < 32; xx++) { + if (offset >= svga->hwcursor_latch.x) { + if (!(dat[0] & 0x80000000)) + ((uint32_t *)buffer32->line[displine])[offset + 32] = (dat[1] & 0x80000000) ? 0xffffff : 0; + else if (dat[1] & 0x80000000) + ((uint32_t *)buffer32->line[displine])[offset + 32] ^= 0xffffff; + // pclog("Plot %i, %i (%i %i) %04X %04X\n", offset, displine, x+xx, + // svga_hwcursor_on, dat[0], dat[1]); + } - offset++; - dat[0] <<= 1; - dat[1] <<= 1; - } - svga->hwcursor_latch.addr += 8; + offset++; + dat[0] <<= 1; + dat[1] <<= 1; + } + svga->hwcursor_latch.addr += 8; - if (svga->interlace && !svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += 8; + if (svga->interlace && !svga->hwcursor_oddeven) + svga->hwcursor_latch.addr += 8; } uint8_t tgui_pci_read(int func, int addr, void *p) { - tgui_t *tgui = (tgui_t *)p; + tgui_t *tgui = (tgui_t *)p; -// pclog("Trident PCI read %08X\n", addr); + // pclog("Trident PCI read %08X\n", addr); - switch (addr) { - case 0x00:return 0x23; /*Trident*/ - case 0x01:return 0x10; + switch (addr) { + case 0x00: + return 0x23; /*Trident*/ + case 0x01: + return 0x10; - case 0x02:return 0x40; /*TGUI9440 (9682)*/ - case 0x03:return 0x94; + case 0x02: + return 0x40; /*TGUI9440 (9682)*/ + case 0x03: + return 0x94; - case 0x04:return 0x03; /*Respond to IO and memory accesses*/ + case 0x04: + return 0x03; /*Respond to IO and memory accesses*/ - case 0x07:return 1 << 1; /*Medium DEVSEL timing*/ + case 0x07: + return 1 << 1; /*Medium DEVSEL timing*/ - case 0x08:return 0; /*Revision ID*/ - case 0x09:return 0; /*Programming interface*/ + case 0x08: + return 0; /*Revision ID*/ + case 0x09: + return 0; /*Programming interface*/ - case 0x0a:return 0x01; /*Supports VGA interface, XGA compatible*/ - case 0x0b:return 0x03; + case 0x0a: + return 0x01; /*Supports VGA interface, XGA compatible*/ + case 0x0b: + return 0x03; - case 0x10:return 0x00; /*Linear frame buffer address*/ - case 0x11:return 0x00; - case 0x12:return tgui->linear_base >> 16; - case 0x13:return tgui->linear_base >> 24; + case 0x10: + return 0x00; /*Linear frame buffer address*/ + case 0x11: + return 0x00; + case 0x12: + return tgui->linear_base >> 16; + case 0x13: + return tgui->linear_base >> 24; - case 0x30:return 0x01; /*BIOS ROM address*/ - case 0x31:return 0x00; - case 0x32:return 0x0C; - case 0x33:return 0x00; - } - return 0; + case 0x30: + return 0x01; /*BIOS ROM address*/ + case 0x31: + return 0x00; + case 0x32: + return 0x0C; + case 0x33: + return 0x00; + } + return 0; } void tgui_pci_write(int func, int addr, uint8_t val, void *p) { - tgui_t *tgui = (tgui_t *)p; - svga_t *svga = &tgui->svga; + tgui_t *tgui = (tgui_t *)p; + svga_t *svga = &tgui->svga; -// pclog("Trident PCI write %08X %02X\n", addr, val); + // pclog("Trident PCI write %08X %02X\n", addr, val); - switch (addr) { - case 0x12:tgui->linear_base = (tgui->linear_base & 0xff000000) | ((val & 0xe0) << 16); - tgui->linear_size = 2 << 20; - tgui->svga.decode_mask = 0x1fffff; - svga->crtc[0x21] = (svga->crtc[0x21] & ~0xf) | (val >> 4); - tgui_recalcmapping(tgui); - break; - case 0x13:tgui->linear_base = (tgui->linear_base & 0xe00000) | (val << 24); - tgui->linear_size = 2 << 20; - tgui->svga.decode_mask = 0x1fffff; - svga->crtc[0x21] = (svga->crtc[0x21] & ~0xc0) | (val >> 6); - tgui_recalcmapping(tgui); - break; - } + switch (addr) { + case 0x12: + tgui->linear_base = (tgui->linear_base & 0xff000000) | ((val & 0xe0) << 16); + tgui->linear_size = 2 << 20; + tgui->svga.decode_mask = 0x1fffff; + svga->crtc[0x21] = (svga->crtc[0x21] & ~0xf) | (val >> 4); + tgui_recalcmapping(tgui); + break; + case 0x13: + tgui->linear_base = (tgui->linear_base & 0xe00000) | (val << 24); + tgui->linear_size = 2 << 20; + tgui->svga.decode_mask = 0x1fffff; + svga->crtc[0x21] = (svga->crtc[0x21] & ~0xc0) | (val >> 6); + tgui_recalcmapping(tgui); + break; + } } static void *tgui_init(char *bios_fn, int type, int mem_size) { - tgui_t *tgui = malloc(sizeof(tgui_t)); - memset(tgui, 0, sizeof(tgui_t)); + tgui_t *tgui = malloc(sizeof(tgui_t)); + memset(tgui, 0, sizeof(tgui_t)); - if (mem_size) - tgui->vram_size = mem_size; - else - tgui->vram_size = device_get_config_int("memory") << 20; - tgui->vram_mask = tgui->vram_size - 1; + if (mem_size) + tgui->vram_size = mem_size; + else + tgui->vram_size = device_get_config_int("memory") << 20; + tgui->vram_mask = tgui->vram_size - 1; - tgui->type = type; + tgui->type = type; - rom_init(&tgui->bios_rom, bios_fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&tgui->bios_rom, bios_fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - svga_init(&tgui->svga, tgui, tgui->vram_size, - tgui_recalctimings, - tgui_in, tgui_out, - tgui_hwcursor_draw, - NULL); + svga_init(&tgui->svga, tgui, tgui->vram_size, tgui_recalctimings, tgui_in, tgui_out, tgui_hwcursor_draw, NULL); - mem_mapping_add(&tgui->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, tgui_accel_write_fb_b, tgui_accel_write_fb_w, tgui_accel_write_fb_l, NULL, 0, &tgui->svga); - mem_mapping_add(&tgui->accel_mapping, 0xbc000, 0x4000, tgui_accel_read, tgui_accel_read_w, tgui_accel_read_l, tgui_accel_write, tgui_accel_write_w, tgui_accel_write_l, NULL, 0, tgui); - mem_mapping_disable(&tgui->accel_mapping); + mem_mapping_add(&tgui->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, + tgui_accel_write_fb_b, tgui_accel_write_fb_w, tgui_accel_write_fb_l, NULL, 0, &tgui->svga); + mem_mapping_add(&tgui->accel_mapping, 0xbc000, 0x4000, tgui_accel_read, tgui_accel_read_w, tgui_accel_read_l, + tgui_accel_write, tgui_accel_write_w, tgui_accel_write_l, NULL, 0, tgui); + mem_mapping_disable(&tgui->accel_mapping); - io_sethandler(0x03c0, 0x0020, tgui_in, NULL, NULL, tgui_out, NULL, NULL, tgui); - if (tgui->type >= TGUI_9440) - io_sethandler(0x43c8, 0x0002, tgui_in, NULL, NULL, tgui_out, NULL, NULL, tgui); + io_sethandler(0x03c0, 0x0020, tgui_in, NULL, NULL, tgui_out, NULL, NULL, tgui); + if (tgui->type >= TGUI_9440) + io_sethandler(0x43c8, 0x0002, tgui_in, NULL, NULL, tgui_out, NULL, NULL, tgui); - if (tgui->type >= TGUI_9440) - pci_add(tgui_pci_read, tgui_pci_write, tgui); + if (tgui->type >= TGUI_9440) + pci_add(tgui_pci_read, tgui_pci_write, tgui); - tgui->wake_fifo_thread = thread_create_event(); - tgui->fifo_not_full_event = thread_create_event(); - tgui->fifo_thread = thread_create(fifo_thread, tgui); + tgui->wake_fifo_thread = thread_create_event(); + tgui->fifo_not_full_event = thread_create_event(); + tgui->fifo_thread = thread_create(fifo_thread, tgui); - return tgui; + return tgui; } -static void *tgui9400cxi_init() { - return tgui_init("9400CXI.vbi", TGUI_9400CXI, 0); -} +static void *tgui9400cxi_init() { return tgui_init("9400CXI.vbi", TGUI_9400CXI, 0); } static void *tgui9400cxi_elx_init() { - /*Try combined ROM dump first. If not present, use seperated dump*/ - FILE *f = romfopen("elx_pc425x/elx_pc425x.bin", "rb"); - if (f) { - fclose(f); - return tgui_init("elx_pc425x/elx_pc425x.bin", TGUI_9400CXI, 512 << 10); - } + /*Try combined ROM dump first. If not present, use seperated dump*/ + FILE *f = romfopen("elx_pc425x/elx_pc425x.bin", "rb"); + if (f) { + fclose(f); + return tgui_init("elx_pc425x/elx_pc425x.bin", TGUI_9400CXI, 512 << 10); + } - return tgui_init("elx_pc425x/elx_pc425x_vbios.bin", TGUI_9400CXI, 512 << 10); + return tgui_init("elx_pc425x/elx_pc425x_vbios.bin", TGUI_9400CXI, 512 << 10); } -static void *tgui9440_init() { - return tgui_init("9440.vbi", TGUI_9440, 0); -} +static void *tgui9440_init() { return tgui_init("9440.vbi", TGUI_9440, 0); } -static int tgui9400cxi_available() { - return rom_present("9400CXI.vbi"); -} +static int tgui9400cxi_available() { return rom_present("9400CXI.vbi"); } -static int tgui9440_available() { - return rom_present("9440.vbi"); -} +static int tgui9440_available() { return rom_present("9440.vbi"); } void tgui_close(void *p) { - tgui_t *tgui = (tgui_t *)p; + tgui_t *tgui = (tgui_t *)p; - svga_close(&tgui->svga); + svga_close(&tgui->svga); - thread_kill(tgui->fifo_thread); - thread_destroy_event(tgui->wake_fifo_thread); - thread_destroy_event(tgui->fifo_not_full_event); + thread_kill(tgui->fifo_thread); + thread_destroy_event(tgui->wake_fifo_thread); + thread_destroy_event(tgui->fifo_not_full_event); - free(tgui); + free(tgui); } void tgui_speed_changed(void *p) { - tgui_t *tgui = (tgui_t *)p; + tgui_t *tgui = (tgui_t *)p; - svga_recalctimings(&tgui->svga); + svga_recalctimings(&tgui->svga); } void tgui_force_redraw(void *p) { - tgui_t *tgui = (tgui_t *)p; + tgui_t *tgui = (tgui_t *)p; - tgui->svga.fullchange = changeframecount; + tgui->svga.fullchange = changeframecount; } static uint8_t tgui_ext_linear_read(uint32_t addr, void *p) { - svga_t *svga = (svga_t *)p; - tgui_t *tgui = (tgui_t *)svga->p; - int c; + svga_t *svga = (svga_t *)p; + tgui_t *tgui = (tgui_t *)svga->p; + int c; - cycles -= video_timing_read_b; - cycles_lost += video_timing_read_b; + cycles -= video_timing_read_b; + cycles_lost += video_timing_read_b; - addr &= svga->decode_mask; - if (addr >= svga->vram_max) - return 0xff; + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return 0xff; - addr &= ~0xf; - addr = dword_remap(addr); + addr &= ~0xf; + addr = dword_remap(addr); - for (c = 0; c < 16; c++) { - tgui->copy_latch[c] = svga->vram[addr]; - addr += ((c & 3) == 3) ? 13 : 1; - } + for (c = 0; c < 16; c++) { + tgui->copy_latch[c] = svga->vram[addr]; + addr += ((c & 3) == 3) ? 13 : 1; + } - return svga->vram[addr & svga->vram_mask]; + return svga->vram[addr & svga->vram_mask]; } static uint8_t tgui_ext_read(uint32_t addr, void *p) { - svga_t *svga = (svga_t *)p; + svga_t *svga = (svga_t *)p; - addr = (addr & svga->banked_mask) + svga->read_bank; + addr = (addr & svga->banked_mask) + svga->read_bank; - return tgui_ext_linear_read(addr, svga); + return tgui_ext_linear_read(addr, svga); } static void tgui_ext_linear_write(uint32_t addr, uint8_t val, void *p) { - svga_t *svga = (svga_t *)p; - tgui_t *tgui = (tgui_t *)svga->p; - int c; - uint8_t fg[2] = {tgui->ext_gdc_regs[4], tgui->ext_gdc_regs[5]}; - uint8_t bg[2] = {tgui->ext_gdc_regs[1], tgui->ext_gdc_regs[2]}; - uint8_t mask = tgui->ext_gdc_regs[7]; + svga_t *svga = (svga_t *)p; + tgui_t *tgui = (tgui_t *)svga->p; + int c; + uint8_t fg[2] = {tgui->ext_gdc_regs[4], tgui->ext_gdc_regs[5]}; + uint8_t bg[2] = {tgui->ext_gdc_regs[1], tgui->ext_gdc_regs[2]}; + uint8_t mask = tgui->ext_gdc_regs[7]; - cycles -= video_timing_write_b; - cycles_lost += video_timing_write_b; + cycles -= video_timing_write_b; + cycles_lost += video_timing_write_b; - addr &= svga->decode_mask; - if (addr >= svga->vram_max) - return; - addr &= svga->vram_mask; - addr &= (tgui->ext_gdc_regs[0] & 8) ? ~0xf : ~0x7; + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return; + addr &= svga->vram_mask; + addr &= (tgui->ext_gdc_regs[0] & 8) ? ~0xf : ~0x7; - addr = dword_remap(addr); - svga->changedvram[addr >> 12] = changeframecount; + addr = dword_remap(addr); + svga->changedvram[addr >> 12] = changeframecount; - switch (tgui->ext_gdc_regs[0] & 0xf) { - /*8-bit mono->colour expansion, unmasked*/ - case 2: - for (c = 7; c >= 0; c--) { - if (mask & (1 << c)) - *(uint8_t *)&svga->vram[addr] = (val & (1 << c)) ? fg[0] : bg[0]; - addr += (c == 4) ? 13 : 1; - } - break; + switch (tgui->ext_gdc_regs[0] & 0xf) { + /*8-bit mono->colour expansion, unmasked*/ + case 2: + for (c = 7; c >= 0; c--) { + if (mask & (1 << c)) + *(uint8_t *)&svga->vram[addr] = (val & (1 << c)) ? fg[0] : bg[0]; + addr += (c == 4) ? 13 : 1; + } + break; - /*16-bit mono->colour expansion, unmasked*/ - case 3: - for (c = 7; c >= 0; c--) { - if (mask & (1 << c)) - *(uint8_t *)&svga->vram[addr] = (val & (1 << c)) ? fg[(c & 1) ^ 1] : bg[(c & 1) ^ 1]; - addr += (c == 4) ? 13 : 1; - } - break; + /*16-bit mono->colour expansion, unmasked*/ + case 3: + for (c = 7; c >= 0; c--) { + if (mask & (1 << c)) + *(uint8_t *)&svga->vram[addr] = (val & (1 << c)) ? fg[(c & 1) ^ 1] : bg[(c & 1) ^ 1]; + addr += (c == 4) ? 13 : 1; + } + break; - /*8-bit mono->colour expansion, masked*/ - case 6: - for (c = 7; c >= 0; c--) { - if ((val & mask) & (1 << c)) - *(uint8_t *)&svga->vram[addr] = fg[0]; - addr += (c == 4) ? 13 : 1; - } - break; + /*8-bit mono->colour expansion, masked*/ + case 6: + for (c = 7; c >= 0; c--) { + if ((val & mask) & (1 << c)) + *(uint8_t *)&svga->vram[addr] = fg[0]; + addr += (c == 4) ? 13 : 1; + } + break; - /*16-bit mono->colour expansion, masked*/ - case 7: - for (c = 7; c >= 0; c--) { - if ((val & mask) & (1 << c)) - *(uint8_t *)&svga->vram[addr] = fg[(c & 1) ^ 1]; - addr += (c == 4) ? 13 : 1; - } - break; + /*16-bit mono->colour expansion, masked*/ + case 7: + for (c = 7; c >= 0; c--) { + if ((val & mask) & (1 << c)) + *(uint8_t *)&svga->vram[addr] = fg[(c & 1) ^ 1]; + addr += (c == 4) ? 13 : 1; + } + break; - case 0x8: - case 0x9: - case 0xa: - case 0xb: - case 0xc: - case 0xd: - case 0xe: - case 0xf: - for (c = 0; c < 16; c++) { - *(uint8_t *)&svga->vram[addr] = tgui->copy_latch[c]; - addr += ((c & 3) == 3) ? 13 : 1; - } - break; - } + case 0x8: + case 0x9: + case 0xa: + case 0xb: + case 0xc: + case 0xd: + case 0xe: + case 0xf: + for (c = 0; c < 16; c++) { + *(uint8_t *)&svga->vram[addr] = tgui->copy_latch[c]; + addr += ((c & 3) == 3) ? 13 : 1; + } + break; + } } static void tgui_ext_linear_writew(uint32_t addr, uint16_t val, void *p) { - svga_t *svga = (svga_t *)p; - tgui_t *tgui = (tgui_t *)svga->p; - int c; - uint8_t fg[2] = {tgui->ext_gdc_regs[4], tgui->ext_gdc_regs[5]}; - uint8_t bg[2] = {tgui->ext_gdc_regs[1], tgui->ext_gdc_regs[2]}; - uint16_t mask = (tgui->ext_gdc_regs[7] << 8) | tgui->ext_gdc_regs[8]; + svga_t *svga = (svga_t *)p; + tgui_t *tgui = (tgui_t *)svga->p; + int c; + uint8_t fg[2] = {tgui->ext_gdc_regs[4], tgui->ext_gdc_regs[5]}; + uint8_t bg[2] = {tgui->ext_gdc_regs[1], tgui->ext_gdc_regs[2]}; + uint16_t mask = (tgui->ext_gdc_regs[7] << 8) | tgui->ext_gdc_regs[8]; - cycles -= video_timing_write_w; - cycles_lost += video_timing_write_w; + cycles -= video_timing_write_w; + cycles_lost += video_timing_write_w; - addr &= svga->decode_mask; - if (addr >= svga->vram_max) - return; - addr &= svga->vram_mask; - addr &= ~0xf; + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return; + addr &= svga->vram_mask; + addr &= ~0xf; - addr = dword_remap(addr); - svga->changedvram[addr >> 12] = changeframecount; + addr = dword_remap(addr); + svga->changedvram[addr >> 12] = changeframecount; - val = (val >> 8) | (val << 8); + val = (val >> 8) | (val << 8); - switch (tgui->ext_gdc_regs[0] & 0xf) { - /*8-bit mono->colour expansion, unmasked*/ - case 2: - for (c = 15; c >= 0; c--) { - if (mask & (1 << c)) - *(uint8_t *)&svga->vram[addr] = (val & (1 << c)) ? fg[0] : bg[0]; - addr += (c & 3) ? 1 : 13; - } - break; + switch (tgui->ext_gdc_regs[0] & 0xf) { + /*8-bit mono->colour expansion, unmasked*/ + case 2: + for (c = 15; c >= 0; c--) { + if (mask & (1 << c)) + *(uint8_t *)&svga->vram[addr] = (val & (1 << c)) ? fg[0] : bg[0]; + addr += (c & 3) ? 1 : 13; + } + break; - /*16-bit mono->colour expansion, unmasked*/ - case 3: - for (c = 15; c >= 0; c--) { - if (mask & (1 << c)) - *(uint8_t *)&svga->vram[addr] = (val & (1 << c)) ? fg[(c & 1) ^ 1] : bg[(c & 1) ^ 1]; - addr += (c & 3) ? 1 : 13; - } - break; + /*16-bit mono->colour expansion, unmasked*/ + case 3: + for (c = 15; c >= 0; c--) { + if (mask & (1 << c)) + *(uint8_t *)&svga->vram[addr] = (val & (1 << c)) ? fg[(c & 1) ^ 1] : bg[(c & 1) ^ 1]; + addr += (c & 3) ? 1 : 13; + } + break; - /*8-bit mono->colour expansion, masked*/ - case 6: - for (c = 15; c >= 0; c--) { - if ((val & mask) & (1 << c)) - *(uint8_t *)&svga->vram[addr] = fg[0]; - addr += (c & 3) ? 1 : 13; - } - break; + /*8-bit mono->colour expansion, masked*/ + case 6: + for (c = 15; c >= 0; c--) { + if ((val & mask) & (1 << c)) + *(uint8_t *)&svga->vram[addr] = fg[0]; + addr += (c & 3) ? 1 : 13; + } + break; - /*16-bit mono->colour expansion, masked*/ - case 7: - for (c = 15; c >= 0; c--) { - if ((val & mask) & (1 << c)) - *(uint8_t *)&svga->vram[addr] = fg[(c & 1) ^ 1]; - addr += (c & 3) ? 1 : 13; - } - break; + /*16-bit mono->colour expansion, masked*/ + case 7: + for (c = 15; c >= 0; c--) { + if ((val & mask) & (1 << c)) + *(uint8_t *)&svga->vram[addr] = fg[(c & 1) ^ 1]; + addr += (c & 3) ? 1 : 13; + } + break; - case 0x8: - case 0x9: - case 0xa: - case 0xb: - case 0xc: - case 0xd: - case 0xe: - case 0xf: - for (c = 0; c < 16; c++) { - *(uint8_t *)&svga->vram[addr] = tgui->copy_latch[c]; - addr += ((c & 3) == 3) ? 13 : 1; - } - break; - } + case 0x8: + case 0x9: + case 0xa: + case 0xb: + case 0xc: + case 0xd: + case 0xe: + case 0xf: + for (c = 0; c < 16; c++) { + *(uint8_t *)&svga->vram[addr] = tgui->copy_latch[c]; + addr += ((c & 3) == 3) ? 13 : 1; + } + break; + } } -static void tgui_ext_linear_writel(uint32_t addr, uint32_t val, void *p) { - tgui_ext_linear_writew(addr, val, p); -} +static void tgui_ext_linear_writel(uint32_t addr, uint32_t val, void *p) { tgui_ext_linear_writew(addr, val, p); } static void tgui_ext_write(uint32_t addr, uint8_t val, void *p) { - svga_t *svga = (svga_t *)p; + svga_t *svga = (svga_t *)p; - addr = (addr & svga->banked_mask) + svga->read_bank; + addr = (addr & svga->banked_mask) + svga->read_bank; - tgui_ext_linear_write(addr, val, svga); + tgui_ext_linear_write(addr, val, svga); } static void tgui_ext_writew(uint32_t addr, uint16_t val, void *p) { - svga_t *svga = (svga_t *)p; + svga_t *svga = (svga_t *)p; - addr = (addr & svga->banked_mask) + svga->read_bank; + addr = (addr & svga->banked_mask) + svga->read_bank; - tgui_ext_linear_writew(addr, val, svga); + tgui_ext_linear_writew(addr, val, svga); } static void tgui_ext_writel(uint32_t addr, uint32_t val, void *p) { - svga_t *svga = (svga_t *)p; + svga_t *svga = (svga_t *)p; - addr = (addr & svga->banked_mask) + svga->read_bank; + addr = (addr & svga->banked_mask) + svga->read_bank; - tgui_ext_linear_writel(addr, val, svga); + tgui_ext_linear_writel(addr, val, svga); } -enum { - TGUI_BITBLT = 1 -}; +enum { TGUI_BITBLT = 1 }; enum { - TGUI_SRCCPU = 0, + TGUI_SRCCPU = 0, - TGUI_SRCDISP = 0x04, /*Source is from display*/ - TGUI_PATMONO = 0x20, /*Pattern is monochrome and needs expansion*/ - TGUI_SRCMONO = 0x40, /*Source is monochrome from CPU and needs expansion*/ - TGUI_TRANSENA = 0x1000, /*Transparent (no draw when source == bg col)*/ - TGUI_TRANSREV = 0x2000, /*Reverse fg/bg for transparent*/ - TGUI_SOLIDFILL = 0x4000 /*Pattern all zero?*/ + TGUI_SRCDISP = 0x04, /*Source is from display*/ + TGUI_PATMONO = 0x20, /*Pattern is monochrome and needs expansion*/ + TGUI_SRCMONO = 0x40, /*Source is monochrome from CPU and needs expansion*/ + TGUI_TRANSENA = 0x1000, /*Transparent (no draw when source == bg col)*/ + TGUI_TRANSREV = 0x2000, /*Reverse fg/bg for transparent*/ + TGUI_SOLIDFILL = 0x4000 /*Pattern all zero?*/ }; -#define READ(addr, dat) if (tgui->accel.bpp == 0) dat = svga->vram[dword_remap(addr) & 0x1fffff]; \ - else dat = vram_w[dword_remap_w(addr) & 0xfffff]; +#define READ(addr, dat) \ + if (tgui->accel.bpp == 0) \ + dat = svga->vram[dword_remap(addr) & 0x1fffff]; \ + else \ + dat = vram_w[dword_remap_w(addr) & 0xfffff]; -#define MIX() do \ - { \ - out = 0; \ - for (c=0;c<16;c++) \ - { \ - d=(dst_dat & (1<accel.rop & (1<accel.rop & (1 << d)) \ + out |= (1 << c); \ + } \ } while (0) -#define WRITE(addr, dat) if (tgui->accel.bpp == 0) \ - { \ - svga->vram[dword_remap(addr) & 0x1fffff] = dat; \ - svga->changedvram[(dword_remap(addr) & 0x1fffff) >> 12] = changeframecount; \ - } \ - else \ - { \ - vram_w[dword_remap_w(addr) & 0xfffff] = dat; \ - svga->changedvram[(dword_remap_w(addr) & 0xfffff) >> 11] = changeframecount; \ - } +#define WRITE(addr, dat) \ + if (tgui->accel.bpp == 0) { \ + svga->vram[dword_remap(addr) & 0x1fffff] = dat; \ + svga->changedvram[(dword_remap(addr) & 0x1fffff) >> 12] = changeframecount; \ + } else { \ + vram_w[dword_remap_w(addr) & 0xfffff] = dat; \ + svga->changedvram[(dword_remap_w(addr) & 0xfffff) >> 11] = changeframecount; \ + } void tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) { - svga_t *svga = &tgui->svga; - int x, y; - int c, d; - uint16_t src_dat, dst_dat, pat_dat; - uint16_t out; - int xdir = (tgui->accel.flags & 0x200) ? -1 : 1; - int ydir = (tgui->accel.flags & 0x100) ? -1 : 1; - uint16_t trans_col = (tgui->accel.flags & TGUI_TRANSREV) ? tgui->accel.fg_col : tgui->accel.bg_col; - uint16_t *vram_w = (uint16_t *)svga->vram; + svga_t *svga = &tgui->svga; + int x, y; + int c, d; + uint16_t src_dat, dst_dat, pat_dat; + uint16_t out; + int xdir = (tgui->accel.flags & 0x200) ? -1 : 1; + int ydir = (tgui->accel.flags & 0x100) ? -1 : 1; + uint16_t trans_col = (tgui->accel.flags & TGUI_TRANSREV) ? tgui->accel.fg_col : tgui->accel.bg_col; + uint16_t *vram_w = (uint16_t *)svga->vram; - if (tgui->accel.bpp == 0) - trans_col &= 0xff; + if (tgui->accel.bpp == 0) + trans_col &= 0xff; - if (count != -1 && !tgui->accel.x && (tgui->accel.flags & TGUI_SRCMONO)) { - count -= tgui->accel.offset; - cpu_dat <<= tgui->accel.offset; - } - if (count == -1) { - tgui->accel.x = tgui->accel.y = 0; - } - if (tgui->accel.flags & TGUI_SOLIDFILL) { -// pclog("SOLIDFILL\n"); - for (y = 0; y < 8; y++) { - for (x = 0; x < 8; x++) { - tgui->accel.tgui_pattern[y][x] = tgui->accel.fg_col; - } - } - } else if (tgui->accel.flags & TGUI_PATMONO) { -// pclog("PATMONO\n"); - for (y = 0; y < 8; y++) { - for (x = 0; x < 8; x++) { - tgui->accel.tgui_pattern[y][x] = (tgui->accel.pattern[y] & (1 << x)) ? tgui->accel.fg_col : tgui->accel.bg_col; - } - } - } else { - if (tgui->accel.bpp == 0) { -// pclog("OTHER 8-bit\n"); - for (y = 0; y < 8; y++) { - for (x = 0; x < 8; x++) { - tgui->accel.tgui_pattern[y][x] = tgui->accel.pattern[x + y * 8]; - } - } - } else { -// pclog("OTHER 16-bit\n"); - for (y = 0; y < 8; y++) { - for (x = 0; x < 8; x++) { - tgui->accel.tgui_pattern[y][x] = tgui->accel.pattern[x * 2 + y * 16] | (tgui->accel.pattern[x * 2 + y * 16 + 1] << 8); - } - } - } - } -/* for (y = 0; y < 8; y++) - { - if (count == -1) pclog("Pattern %i : %02X %02X %02X %02X %02X %02X %02X %02X\n", y, tgui->accel.tgui_pattern[y][0], tgui->accel.tgui_pattern[y][1], tgui->accel.tgui_pattern[y][2], tgui->accel.tgui_pattern[y][3], tgui->accel.tgui_pattern[y][4], tgui->accel.tgui_pattern[y][5], tgui->accel.tgui_pattern[y][6], tgui->accel.tgui_pattern[y][7]); - }*/ -// if (count == -1) pclog("Command %i %i %p\n", tgui->accel.command, TGUI_BITBLT, tgui); - switch (tgui->accel.command) { - case TGUI_BITBLT: -// if (count == -1) pclog("BITBLT src %i,%i dst %i,%i size %i,%i flags %04X\n", tgui->accel.src_x, tgui->accel.src_y, tgui->accel.dst_x, tgui->accel.dst_y, tgui->accel.size_x, tgui->accel.size_y, tgui->accel.flags); - if (count == -1) { - tgui->accel.src = tgui->accel.src_old = tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.pitch); - tgui->accel.dst = tgui->accel.dst_old = tgui->accel.dst_x + (tgui->accel.dst_y * tgui->accel.pitch); - tgui->accel.pat_x = tgui->accel.dst_x; - tgui->accel.pat_y = tgui->accel.dst_y; - } + if (count != -1 && !tgui->accel.x && (tgui->accel.flags & TGUI_SRCMONO)) { + count -= tgui->accel.offset; + cpu_dat <<= tgui->accel.offset; + } + if (count == -1) { + tgui->accel.x = tgui->accel.y = 0; + } + if (tgui->accel.flags & TGUI_SOLIDFILL) { + // pclog("SOLIDFILL\n"); + for (y = 0; y < 8; y++) { + for (x = 0; x < 8; x++) { + tgui->accel.tgui_pattern[y][x] = tgui->accel.fg_col; + } + } + } else if (tgui->accel.flags & TGUI_PATMONO) { + // pclog("PATMONO\n"); + for (y = 0; y < 8; y++) { + for (x = 0; x < 8; x++) { + tgui->accel.tgui_pattern[y][x] = + (tgui->accel.pattern[y] & (1 << x)) ? tgui->accel.fg_col : tgui->accel.bg_col; + } + } + } else { + if (tgui->accel.bpp == 0) { + // pclog("OTHER 8-bit\n"); + for (y = 0; y < 8; y++) { + for (x = 0; x < 8; x++) { + tgui->accel.tgui_pattern[y][x] = tgui->accel.pattern[x + y * 8]; + } + } + } else { + // pclog("OTHER 16-bit\n"); + for (y = 0; y < 8; y++) { + for (x = 0; x < 8; x++) { + tgui->accel.tgui_pattern[y][x] = tgui->accel.pattern[x * 2 + y * 16] | + (tgui->accel.pattern[x * 2 + y * 16 + 1] << 8); + } + } + } + } + /* for (y = 0; y < 8; y++) + { + if (count == -1) pclog("Pattern %i : %02X %02X %02X %02X %02X %02X %02X %02X\n", y, + tgui->accel.tgui_pattern[y][0], tgui->accel.tgui_pattern[y][1], tgui->accel.tgui_pattern[y][2], + tgui->accel.tgui_pattern[y][3], tgui->accel.tgui_pattern[y][4], tgui->accel.tgui_pattern[y][5], + tgui->accel.tgui_pattern[y][6], tgui->accel.tgui_pattern[y][7]); + }*/ + // if (count == -1) pclog("Command %i %i %p\n", tgui->accel.command, TGUI_BITBLT, tgui); + switch (tgui->accel.command) { + case TGUI_BITBLT: + // if (count == -1) pclog("BITBLT src %i,%i dst %i,%i size %i,%i flags %04X\n", tgui->accel.src_x, + //tgui->accel.src_y, tgui->accel.dst_x, tgui->accel.dst_y, tgui->accel.size_x, tgui->accel.size_y, + //tgui->accel.flags); + if (count == -1) { + tgui->accel.src = tgui->accel.src_old = tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.pitch); + tgui->accel.dst = tgui->accel.dst_old = tgui->accel.dst_x + (tgui->accel.dst_y * tgui->accel.pitch); + tgui->accel.pat_x = tgui->accel.dst_x; + tgui->accel.pat_y = tgui->accel.dst_y; + } - switch (tgui->accel.flags & (TGUI_SRCMONO | TGUI_SRCDISP)) { - case TGUI_SRCCPU: - if (count == -1) { -// pclog("Blit start TGUI_SRCCPU\n"); - if (svga->crtc[0x21] & 0x20) { - tgui->write_blitter = 1; - } - if (tgui->accel.use_src) - return; - } else - count >>= 3; -// pclog("TGUI_SRCCPU\n"); - while (count) { - if (tgui->accel.bpp == 0) { - src_dat = cpu_dat >> 24; - cpu_dat <<= 8; - } else { - src_dat = (cpu_dat >> 24) | ((cpu_dat >> 8) & 0xff00); - cpu_dat <<= 16; - count--; - } - READ(tgui->accel.dst, dst_dat); - pat_dat = tgui->accel.tgui_pattern[tgui->accel.pat_y & 7][tgui->accel.pat_x & 7]; + switch (tgui->accel.flags & (TGUI_SRCMONO | TGUI_SRCDISP)) { + case TGUI_SRCCPU: + if (count == -1) { + // pclog("Blit start TGUI_SRCCPU\n"); + if (svga->crtc[0x21] & 0x20) { + tgui->write_blitter = 1; + } + if (tgui->accel.use_src) + return; + } else + count >>= 3; + // pclog("TGUI_SRCCPU\n"); + while (count) { + if (tgui->accel.bpp == 0) { + src_dat = cpu_dat >> 24; + cpu_dat <<= 8; + } else { + src_dat = (cpu_dat >> 24) | ((cpu_dat >> 8) & 0xff00); + cpu_dat <<= 16; + count--; + } + READ(tgui->accel.dst, dst_dat); + pat_dat = tgui->accel.tgui_pattern[tgui->accel.pat_y & 7][tgui->accel.pat_x & 7]; - if (!(tgui->accel.flags & TGUI_TRANSENA) || src_dat != trans_col) { - MIX(); + if (!(tgui->accel.flags & TGUI_TRANSENA) || src_dat != trans_col) { + MIX(); - WRITE(tgui->accel.dst, out); - } + WRITE(tgui->accel.dst, out); + } -// pclog(" %i,%i %02X %02X %02X %02X\n", tgui->accel.x, tgui->accel.y, src_dat,dst_dat,pat_dat, out); + // pclog(" %i,%i %02X %02X %02X %02X\n", tgui->accel.x, tgui->accel.y, + //src_dat,dst_dat,pat_dat, out); - tgui->accel.src += xdir; - tgui->accel.dst += xdir; - tgui->accel.pat_x += xdir; + tgui->accel.src += xdir; + tgui->accel.dst += xdir; + tgui->accel.pat_x += xdir; - tgui->accel.x++; - if (tgui->accel.x > tgui->accel.size_x) { - tgui->accel.x = 0; - tgui->accel.y++; + tgui->accel.x++; + if (tgui->accel.x > tgui->accel.size_x) { + tgui->accel.x = 0; + tgui->accel.y++; - tgui->accel.pat_x = tgui->accel.dst_x; + tgui->accel.pat_x = tgui->accel.dst_x; - tgui->accel.src = tgui->accel.src_old = tgui->accel.src_old + (ydir * tgui->accel.pitch); - tgui->accel.dst = tgui->accel.dst_old = tgui->accel.dst_old + (ydir * tgui->accel.pitch); - tgui->accel.pat_y += ydir; + tgui->accel.src = tgui->accel.src_old = tgui->accel.src_old + (ydir * tgui->accel.pitch); + tgui->accel.dst = tgui->accel.dst_old = tgui->accel.dst_old + (ydir * tgui->accel.pitch); + tgui->accel.pat_y += ydir; - if (tgui->accel.y > tgui->accel.size_y) { - if (svga->crtc[0x21] & 0x20) { - tgui->write_blitter = 0; - } - return; - } - if (tgui->accel.use_src) - return; - } - count--; - } - break; + if (tgui->accel.y > tgui->accel.size_y) { + if (svga->crtc[0x21] & 0x20) { + tgui->write_blitter = 0; + } + return; + } + if (tgui->accel.use_src) + return; + } + count--; + } + break; - case TGUI_SRCMONO | TGUI_SRCCPU: - if (count == -1) { -// pclog("Blit start TGUI_SRCMONO | TGUI_SRCCPU\n"); - if (svga->crtc[0x21] & 0x20) { - tgui->write_blitter = 1; - } + case TGUI_SRCMONO | TGUI_SRCCPU: + if (count == -1) { + // pclog("Blit start TGUI_SRCMONO | TGUI_SRCCPU\n"); + if (svga->crtc[0x21] & 0x20) { + tgui->write_blitter = 1; + } -// pclog(" %i\n", tgui->accel.command); - if (tgui->accel.use_src) - return; - } -// pclog("TGUI_SRCMONO | TGUI_SRCCPU\n"); - while (count) { - src_dat = ((cpu_dat >> 31) ? tgui->accel.fg_col : tgui->accel.bg_col); - if (tgui->accel.bpp == 0) - src_dat &= 0xff; + // pclog(" %i\n", tgui->accel.command); + if (tgui->accel.use_src) + return; + } + // pclog("TGUI_SRCMONO | TGUI_SRCCPU\n"); + while (count) { + src_dat = ((cpu_dat >> 31) ? tgui->accel.fg_col : tgui->accel.bg_col); + if (tgui->accel.bpp == 0) + src_dat &= 0xff; - READ(tgui->accel.dst, dst_dat); - pat_dat = tgui->accel.tgui_pattern[tgui->accel.pat_y & 7][tgui->accel.pat_x & 7]; + READ(tgui->accel.dst, dst_dat); + pat_dat = tgui->accel.tgui_pattern[tgui->accel.pat_y & 7][tgui->accel.pat_x & 7]; - if (!(tgui->accel.flags & TGUI_TRANSENA) || src_dat != trans_col) { - MIX(); + if (!(tgui->accel.flags & TGUI_TRANSENA) || src_dat != trans_col) { + MIX(); - WRITE(tgui->accel.dst, out); - } -// pclog(" %i,%i %02X %02X %02X %02X %i\n", tgui->accel.x, tgui->accel.y, src_dat,dst_dat,pat_dat, out, (!(tgui->accel.flags & TGUI_TRANSENA) || src_dat != trans_col)); - cpu_dat <<= 1; - tgui->accel.src += xdir; - tgui->accel.dst += xdir; - tgui->accel.pat_x += xdir; + WRITE(tgui->accel.dst, out); + } + // pclog(" %i,%i %02X %02X %02X %02X %i\n", tgui->accel.x, + //tgui->accel.y, src_dat,dst_dat,pat_dat, out, (!(tgui->accel.flags & TGUI_TRANSENA) || src_dat != + //trans_col)); + cpu_dat <<= 1; + tgui->accel.src += xdir; + tgui->accel.dst += xdir; + tgui->accel.pat_x += xdir; - tgui->accel.x++; - if (tgui->accel.x > tgui->accel.size_x) { - tgui->accel.x = 0; - tgui->accel.y++; + tgui->accel.x++; + if (tgui->accel.x > tgui->accel.size_x) { + tgui->accel.x = 0; + tgui->accel.y++; - tgui->accel.pat_x = tgui->accel.dst_x; + tgui->accel.pat_x = tgui->accel.dst_x; - tgui->accel.src = tgui->accel.src_old = tgui->accel.src_old + (ydir * tgui->accel.pitch); - tgui->accel.dst = tgui->accel.dst_old = tgui->accel.dst_old + (ydir * tgui->accel.pitch); - tgui->accel.pat_y += ydir; + tgui->accel.src = tgui->accel.src_old = tgui->accel.src_old + (ydir * tgui->accel.pitch); + tgui->accel.dst = tgui->accel.dst_old = tgui->accel.dst_old + (ydir * tgui->accel.pitch); + tgui->accel.pat_y += ydir; - if (tgui->accel.y > tgui->accel.size_y) { - if (svga->crtc[0x21] & 0x20) { - tgui->write_blitter = 0; - } - return; - } - if (tgui->accel.use_src) - return; - } - count--; - } - break; + if (tgui->accel.y > tgui->accel.size_y) { + if (svga->crtc[0x21] & 0x20) { + tgui->write_blitter = 0; + } + return; + } + if (tgui->accel.use_src) + return; + } + count--; + } + break; - default: - while (count) { - READ(tgui->accel.src, src_dat); - READ(tgui->accel.dst, dst_dat); - pat_dat = tgui->accel.tgui_pattern[tgui->accel.pat_y & 7][tgui->accel.pat_x & 7]; + default: + while (count) { + READ(tgui->accel.src, src_dat); + READ(tgui->accel.dst, dst_dat); + pat_dat = tgui->accel.tgui_pattern[tgui->accel.pat_y & 7][tgui->accel.pat_x & 7]; - if (!(tgui->accel.flags & TGUI_TRANSENA) || src_dat != trans_col) { - MIX(); + if (!(tgui->accel.flags & TGUI_TRANSENA) || src_dat != trans_col) { + MIX(); - WRITE(tgui->accel.dst, out); - } -// pclog(" %i,%i %02X %02X %02X %02X\n", tgui->accel.x, tgui->accel.y, src_dat,dst_dat,pat_dat, out); + WRITE(tgui->accel.dst, out); + } + // pclog(" %i,%i %02X %02X %02X %02X\n", tgui->accel.x, + // tgui->accel.y, src_dat,dst_dat,pat_dat, out); - tgui->accel.src += xdir; - tgui->accel.dst += xdir; - tgui->accel.pat_x += xdir; + tgui->accel.src += xdir; + tgui->accel.dst += xdir; + tgui->accel.pat_x += xdir; - tgui->accel.x++; - if (tgui->accel.x > tgui->accel.size_x) { - tgui->accel.x = 0; - tgui->accel.y++; + tgui->accel.x++; + if (tgui->accel.x > tgui->accel.size_x) { + tgui->accel.x = 0; + tgui->accel.y++; - tgui->accel.pat_x = tgui->accel.dst_x; + tgui->accel.pat_x = tgui->accel.dst_x; - tgui->accel.src = tgui->accel.src_old = tgui->accel.src_old + (ydir * tgui->accel.pitch); - tgui->accel.dst = tgui->accel.dst_old = tgui->accel.dst_old + (ydir * tgui->accel.pitch); - tgui->accel.pat_y += ydir; + tgui->accel.src = tgui->accel.src_old = tgui->accel.src_old + (ydir * tgui->accel.pitch); + tgui->accel.dst = tgui->accel.dst_old = tgui->accel.dst_old + (ydir * tgui->accel.pitch); + tgui->accel.pat_y += ydir; - if (tgui->accel.y > tgui->accel.size_y) - return; - } - count--; - } - break; - } - break; - } + if (tgui->accel.y > tgui->accel.size_y) + return; + } + count--; + } + break; + } + break; + } } static void tgui_accel_write_fifo(tgui_t *tgui, uint32_t addr, uint8_t val) { - switch (addr & 0xff) { - case 0x22:tgui->accel.ger22 = val; - tgui->accel.pitch = 512 << ((val >> 2) & 3); - tgui->accel.bpp = (val & 3) ? 1 : 0; - tgui->accel.pitch >>= tgui->accel.bpp; - break; + switch (addr & 0xff) { + case 0x22: + tgui->accel.ger22 = val; + tgui->accel.pitch = 512 << ((val >> 2) & 3); + tgui->accel.bpp = (val & 3) ? 1 : 0; + tgui->accel.pitch >>= tgui->accel.bpp; + break; - case 0x24: /*Command*/ - tgui->accel.command = val; - tgui_accel_command(-1, 0, tgui); - break; + case 0x24: /*Command*/ + tgui->accel.command = val; + tgui_accel_command(-1, 0, tgui); + break; - case 0x27: /*ROP*/ - tgui->accel.rop = val; - tgui->accel.use_src = (val & 0x33) ^ ((val >> 2) & 0x33); -// pclog("Write ROP %02X %i\n", val, tgui->accel.use_src); - break; + case 0x27: /*ROP*/ + tgui->accel.rop = val; + tgui->accel.use_src = (val & 0x33) ^ ((val >> 2) & 0x33); + // pclog("Write ROP %02X %i\n", val, tgui->accel.use_src); + break; - case 0x28: /*Flags*/ - tgui->accel.flags = (tgui->accel.flags & 0xff00) | val; - break; - case 0x29: /*Flags*/ - tgui->accel.flags = (tgui->accel.flags & 0xff) | (val << 8); - break; + case 0x28: /*Flags*/ + tgui->accel.flags = (tgui->accel.flags & 0xff00) | val; + break; + case 0x29: /*Flags*/ + tgui->accel.flags = (tgui->accel.flags & 0xff) | (val << 8); + break; - case 0x2b:tgui->accel.offset = val & 7; - break; + case 0x2b: + tgui->accel.offset = val & 7; + break; - case 0x2c: /*Foreground colour*/ - tgui->accel.fg_col = (tgui->accel.fg_col & 0xff00) | val; - break; - case 0x2d: /*Foreground colour*/ - tgui->accel.fg_col = (tgui->accel.fg_col & 0xff) | (val << 8); - break; + case 0x2c: /*Foreground colour*/ + tgui->accel.fg_col = (tgui->accel.fg_col & 0xff00) | val; + break; + case 0x2d: /*Foreground colour*/ + tgui->accel.fg_col = (tgui->accel.fg_col & 0xff) | (val << 8); + break; - case 0x30: /*Background colour*/ - tgui->accel.bg_col = (tgui->accel.bg_col & 0xff00) | val; - break; - case 0x31: /*Background colour*/ - tgui->accel.bg_col = (tgui->accel.bg_col & 0xff) | (val << 8); - break; + case 0x30: /*Background colour*/ + tgui->accel.bg_col = (tgui->accel.bg_col & 0xff00) | val; + break; + case 0x31: /*Background colour*/ + tgui->accel.bg_col = (tgui->accel.bg_col & 0xff) | (val << 8); + break; - case 0x38: /*Dest X*/ - tgui->accel.dst_x = (tgui->accel.dst_x & 0xff00) | val; - break; - case 0x39: /*Dest X*/ - tgui->accel.dst_x = (tgui->accel.dst_x & 0xff) | (val << 8); - break; - case 0x3a: /*Dest Y*/ - tgui->accel.dst_y = (tgui->accel.dst_y & 0xff00) | val; - break; - case 0x3b: /*Dest Y*/ - tgui->accel.dst_y = (tgui->accel.dst_y & 0xff) | (val << 8); - break; + case 0x38: /*Dest X*/ + tgui->accel.dst_x = (tgui->accel.dst_x & 0xff00) | val; + break; + case 0x39: /*Dest X*/ + tgui->accel.dst_x = (tgui->accel.dst_x & 0xff) | (val << 8); + break; + case 0x3a: /*Dest Y*/ + tgui->accel.dst_y = (tgui->accel.dst_y & 0xff00) | val; + break; + case 0x3b: /*Dest Y*/ + tgui->accel.dst_y = (tgui->accel.dst_y & 0xff) | (val << 8); + break; - case 0x3c: /*Src X*/ - tgui->accel.src_x = (tgui->accel.src_x & 0xff00) | val; - break; - case 0x3d: /*Src X*/ - tgui->accel.src_x = (tgui->accel.src_x & 0xff) | (val << 8); - break; - case 0x3e: /*Src Y*/ - tgui->accel.src_y = (tgui->accel.src_y & 0xff00) | val; - break; - case 0x3f: /*Src Y*/ - tgui->accel.src_y = (tgui->accel.src_y & 0xff) | (val << 8); - break; + case 0x3c: /*Src X*/ + tgui->accel.src_x = (tgui->accel.src_x & 0xff00) | val; + break; + case 0x3d: /*Src X*/ + tgui->accel.src_x = (tgui->accel.src_x & 0xff) | (val << 8); + break; + case 0x3e: /*Src Y*/ + tgui->accel.src_y = (tgui->accel.src_y & 0xff00) | val; + break; + case 0x3f: /*Src Y*/ + tgui->accel.src_y = (tgui->accel.src_y & 0xff) | (val << 8); + break; - case 0x40: /*Size X*/ - tgui->accel.size_x = (tgui->accel.size_x & 0xff00) | val; - break; - case 0x41: /*Size X*/ - tgui->accel.size_x = (tgui->accel.size_x & 0xff) | (val << 8); - break; - case 0x42: /*Size Y*/ - tgui->accel.size_y = (tgui->accel.size_y & 0xff00) | val; - break; - case 0x43: /*Size Y*/ - tgui->accel.size_y = (tgui->accel.size_y & 0xff) | (val << 8); - break; + case 0x40: /*Size X*/ + tgui->accel.size_x = (tgui->accel.size_x & 0xff00) | val; + break; + case 0x41: /*Size X*/ + tgui->accel.size_x = (tgui->accel.size_x & 0xff) | (val << 8); + break; + case 0x42: /*Size Y*/ + tgui->accel.size_y = (tgui->accel.size_y & 0xff00) | val; + break; + case 0x43: /*Size Y*/ + tgui->accel.size_y = (tgui->accel.size_y & 0xff) | (val << 8); + break; - case 0x80: - case 0x81: - case 0x82: - case 0x83: - case 0x84: - case 0x85: - case 0x86: - case 0x87: - case 0x88: - case 0x89: - case 0x8a: - case 0x8b: - case 0x8c: - case 0x8d: - case 0x8e: - case 0x8f: - case 0x90: - case 0x91: - case 0x92: - case 0x93: - case 0x94: - case 0x95: - case 0x96: - case 0x97: - case 0x98: - case 0x99: - case 0x9a: - case 0x9b: - case 0x9c: - case 0x9d: - case 0x9e: - case 0x9f: - case 0xa0: - case 0xa1: - case 0xa2: - case 0xa3: - case 0xa4: - case 0xa5: - case 0xa6: - case 0xa7: - case 0xa8: - case 0xa9: - case 0xaa: - case 0xab: - case 0xac: - case 0xad: - case 0xae: - case 0xaf: - case 0xb0: - case 0xb1: - case 0xb2: - case 0xb3: - case 0xb4: - case 0xb5: - case 0xb6: - case 0xb7: - case 0xb8: - case 0xb9: - case 0xba: - case 0xbb: - case 0xbc: - case 0xbd: - case 0xbe: - case 0xbf: - case 0xc0: - case 0xc1: - case 0xc2: - case 0xc3: - case 0xc4: - case 0xc5: - case 0xc6: - case 0xc7: - case 0xc8: - case 0xc9: - case 0xca: - case 0xcb: - case 0xcc: - case 0xcd: - case 0xce: - case 0xcf: - case 0xd0: - case 0xd1: - case 0xd2: - case 0xd3: - case 0xd4: - case 0xd5: - case 0xd6: - case 0xd7: - case 0xd8: - case 0xd9: - case 0xda: - case 0xdb: - case 0xdc: - case 0xdd: - case 0xde: - case 0xdf: - case 0xe0: - case 0xe1: - case 0xe2: - case 0xe3: - case 0xe4: - case 0xe5: - case 0xe6: - case 0xe7: - case 0xe8: - case 0xe9: - case 0xea: - case 0xeb: - case 0xec: - case 0xed: - case 0xee: - case 0xef: - 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:tgui->accel.pattern[addr & 0x7f] = val; - break; - } + case 0x80: + case 0x81: + case 0x82: + case 0x83: + case 0x84: + case 0x85: + case 0x86: + case 0x87: + case 0x88: + case 0x89: + case 0x8a: + case 0x8b: + case 0x8c: + case 0x8d: + case 0x8e: + case 0x8f: + case 0x90: + case 0x91: + case 0x92: + case 0x93: + case 0x94: + case 0x95: + case 0x96: + case 0x97: + case 0x98: + case 0x99: + case 0x9a: + case 0x9b: + case 0x9c: + case 0x9d: + case 0x9e: + case 0x9f: + case 0xa0: + case 0xa1: + case 0xa2: + case 0xa3: + case 0xa4: + case 0xa5: + case 0xa6: + case 0xa7: + case 0xa8: + case 0xa9: + case 0xaa: + case 0xab: + case 0xac: + case 0xad: + case 0xae: + case 0xaf: + case 0xb0: + case 0xb1: + case 0xb2: + case 0xb3: + case 0xb4: + case 0xb5: + case 0xb6: + case 0xb7: + case 0xb8: + case 0xb9: + case 0xba: + case 0xbb: + case 0xbc: + case 0xbd: + case 0xbe: + case 0xbf: + case 0xc0: + case 0xc1: + case 0xc2: + case 0xc3: + case 0xc4: + case 0xc5: + case 0xc6: + case 0xc7: + case 0xc8: + case 0xc9: + case 0xca: + case 0xcb: + case 0xcc: + case 0xcd: + case 0xce: + case 0xcf: + case 0xd0: + case 0xd1: + case 0xd2: + case 0xd3: + case 0xd4: + case 0xd5: + case 0xd6: + case 0xd7: + case 0xd8: + case 0xd9: + case 0xda: + case 0xdb: + case 0xdc: + case 0xdd: + case 0xde: + case 0xdf: + case 0xe0: + case 0xe1: + case 0xe2: + case 0xe3: + case 0xe4: + case 0xe5: + case 0xe6: + case 0xe7: + case 0xe8: + case 0xe9: + case 0xea: + case 0xeb: + case 0xec: + case 0xed: + case 0xee: + case 0xef: + 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: + tgui->accel.pattern[addr & 0x7f] = val; + break; + } } -static void tgui_accel_write_fifo_fb_b(tgui_t *tgui, uint32_t addr, uint8_t val) { - tgui_accel_command(8, val << 24, tgui); -} +static void tgui_accel_write_fifo_fb_b(tgui_t *tgui, uint32_t addr, uint8_t val) { tgui_accel_command(8, val << 24, tgui); } static void tgui_accel_write_fifo_fb_w(tgui_t *tgui, uint32_t addr, uint16_t val) { - tgui_accel_command(16, (((val & 0xff00) >> 8) | ((val & 0x00ff) << 8)) << 16, tgui); + tgui_accel_command(16, (((val & 0xff00) >> 8) | ((val & 0x00ff) << 8)) << 16, tgui); } static void tgui_accel_write_fifo_fb_l(tgui_t *tgui, uint32_t addr, uint32_t val) { - tgui_accel_command(32, ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24), tgui); + tgui_accel_command(32, + ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | + ((val & 0x000000ff) << 24), + tgui); } static void fifo_thread(void *param) { - tgui_t *tgui = (tgui_t *)param; + tgui_t *tgui = (tgui_t *)param; - while (1) { - thread_set_event(tgui->fifo_not_full_event); - thread_wait_event(tgui->wake_fifo_thread, -1); - thread_reset_event(tgui->wake_fifo_thread); - tgui->blitter_busy = 1; - while (!FIFO_EMPTY) { - uint64_t start_time = timer_read(); - uint64_t end_time; - fifo_entry_t *fifo = &tgui->fifo[tgui->fifo_read_idx & FIFO_MASK]; + while (1) { + thread_set_event(tgui->fifo_not_full_event); + thread_wait_event(tgui->wake_fifo_thread, -1); + thread_reset_event(tgui->wake_fifo_thread); + tgui->blitter_busy = 1; + while (!FIFO_EMPTY) { + uint64_t start_time = timer_read(); + uint64_t end_time; + fifo_entry_t *fifo = &tgui->fifo[tgui->fifo_read_idx & FIFO_MASK]; - switch (fifo->addr_type & FIFO_TYPE) { - case FIFO_WRITE_BYTE:tgui_accel_write_fifo(tgui, fifo->addr_type & FIFO_ADDR, fifo->val); - break; - case FIFO_WRITE_FB_BYTE:tgui_accel_write_fifo_fb_b(tgui, fifo->addr_type & FIFO_ADDR, fifo->val); - break; - case FIFO_WRITE_FB_WORD:tgui_accel_write_fifo_fb_w(tgui, fifo->addr_type & FIFO_ADDR, fifo->val); - break; - case FIFO_WRITE_FB_LONG:tgui_accel_write_fifo_fb_l(tgui, fifo->addr_type & FIFO_ADDR, fifo->val); - break; - } + switch (fifo->addr_type & FIFO_TYPE) { + case FIFO_WRITE_BYTE: + tgui_accel_write_fifo(tgui, fifo->addr_type & FIFO_ADDR, fifo->val); + break; + case FIFO_WRITE_FB_BYTE: + tgui_accel_write_fifo_fb_b(tgui, fifo->addr_type & FIFO_ADDR, fifo->val); + break; + case FIFO_WRITE_FB_WORD: + tgui_accel_write_fifo_fb_w(tgui, fifo->addr_type & FIFO_ADDR, fifo->val); + break; + case FIFO_WRITE_FB_LONG: + tgui_accel_write_fifo_fb_l(tgui, fifo->addr_type & FIFO_ADDR, fifo->val); + break; + } - tgui->fifo_read_idx++; - fifo->addr_type = FIFO_INVALID; + tgui->fifo_read_idx++; + fifo->addr_type = FIFO_INVALID; - if (FIFO_ENTRIES > 0xe000) - thread_set_event(tgui->fifo_not_full_event); + if (FIFO_ENTRIES > 0xe000) + thread_set_event(tgui->fifo_not_full_event); - end_time = timer_read(); - tgui->blitter_time += end_time - start_time; - } - tgui->blitter_busy = 0; - } + end_time = timer_read(); + tgui->blitter_time += end_time - start_time; + } + tgui->blitter_busy = 0; + } } static inline void wake_fifo_thread(tgui_t *tgui) { - thread_set_event(tgui->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ + thread_set_event(tgui->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ } static void tgui_wait_fifo_idle(tgui_t *tgui) { - while (!FIFO_EMPTY) { - wake_fifo_thread(tgui); - thread_wait_event(tgui->fifo_not_full_event, 1); - } + while (!FIFO_EMPTY) { + wake_fifo_thread(tgui); + thread_wait_event(tgui->fifo_not_full_event, 1); + } } static void tgui_queue(tgui_t *tgui, uint32_t addr, uint32_t val, uint32_t type) { - fifo_entry_t *fifo = &tgui->fifo[tgui->fifo_write_idx & FIFO_MASK]; + fifo_entry_t *fifo = &tgui->fifo[tgui->fifo_write_idx & FIFO_MASK]; - if (FIFO_FULL) { - thread_reset_event(tgui->fifo_not_full_event); - if (FIFO_FULL) { - thread_wait_event(tgui->fifo_not_full_event, -1); /*Wait for room in ringbuffer*/ - } - } + if (FIFO_FULL) { + thread_reset_event(tgui->fifo_not_full_event); + if (FIFO_FULL) { + thread_wait_event(tgui->fifo_not_full_event, -1); /*Wait for room in ringbuffer*/ + } + } - fifo->val = val; - fifo->addr_type = (addr & FIFO_ADDR) | type; + fifo->val = val; + fifo->addr_type = (addr & FIFO_ADDR) | type; - tgui->fifo_write_idx++; + tgui->fifo_write_idx++; - if (FIFO_ENTRIES > 0xe000 || FIFO_ENTRIES < 8) - wake_fifo_thread(tgui); + if (FIFO_ENTRIES > 0xe000 || FIFO_ENTRIES < 8) + wake_fifo_thread(tgui); } void tgui_accel_write(uint32_t addr, uint8_t val, void *p) { - tgui_t *tgui = (tgui_t *)p; -// pclog("tgui_accel_write : %08X %02X %04X(%08X):%08X %02X\n", addr, val, CS,cs,pc, opcode); - if ((addr & ~0xff) != 0xbff00) - return; - tgui_queue(tgui, addr, val, FIFO_WRITE_BYTE); + tgui_t *tgui = (tgui_t *)p; + // pclog("tgui_accel_write : %08X %02X %04X(%08X):%08X %02X\n", addr, val, CS,cs,pc, opcode); + if ((addr & ~0xff) != 0xbff00) + return; + tgui_queue(tgui, addr, val, FIFO_WRITE_BYTE); } void tgui_accel_write_w(uint32_t addr, uint16_t val, void *p) { - tgui_t *tgui = (tgui_t *)p; -// pclog("tgui_accel_write_w %08X %04X\n", addr, val); - tgui_accel_write(addr, val, tgui); - tgui_accel_write(addr + 1, val >> 8, tgui); + tgui_t *tgui = (tgui_t *)p; + // pclog("tgui_accel_write_w %08X %04X\n", addr, val); + tgui_accel_write(addr, val, tgui); + tgui_accel_write(addr + 1, val >> 8, tgui); } void tgui_accel_write_l(uint32_t addr, uint32_t val, void *p) { - tgui_t *tgui = (tgui_t *)p; -// pclog("tgui_accel_write_l %08X %08X\n", addr, val); - tgui_accel_write(addr, val, tgui); - tgui_accel_write(addr + 1, val >> 8, tgui); - tgui_accel_write(addr + 2, val >> 16, tgui); - tgui_accel_write(addr + 3, val >> 24, tgui); + tgui_t *tgui = (tgui_t *)p; + // pclog("tgui_accel_write_l %08X %08X\n", addr, val); + tgui_accel_write(addr, val, tgui); + tgui_accel_write(addr + 1, val >> 8, tgui); + tgui_accel_write(addr + 2, val >> 16, tgui); + tgui_accel_write(addr + 3, val >> 24, tgui); } uint8_t tgui_accel_read(uint32_t addr, void *p) { - tgui_t *tgui = (tgui_t *)p; -// pclog("tgui_accel_read : %08X\n", addr); - if ((addr & ~0xff) != 0xbff00) - return 0xff; - if ((addr & 0xff) != 0x20) - tgui_wait_fifo_idle(tgui); - switch (addr & 0xff) { - case 0x20: /*Status*/ - if (!FIFO_EMPTY) - return 1 << 5; - return 0; + tgui_t *tgui = (tgui_t *)p; + // pclog("tgui_accel_read : %08X\n", addr); + if ((addr & ~0xff) != 0xbff00) + return 0xff; + if ((addr & 0xff) != 0x20) + tgui_wait_fifo_idle(tgui); + switch (addr & 0xff) { + case 0x20: /*Status*/ + if (!FIFO_EMPTY) + return 1 << 5; + return 0; - case 0x27: /*ROP*/ - return tgui->accel.rop; + case 0x27: /*ROP*/ + return tgui->accel.rop; - case 0x28: /*Flags*/ - return tgui->accel.flags & 0xff; - case 0x29: /*Flags*/ - return tgui->accel.flags >> 8; + case 0x28: /*Flags*/ + return tgui->accel.flags & 0xff; + case 0x29: /*Flags*/ + return tgui->accel.flags >> 8; - case 0x2b:return tgui->accel.offset; + case 0x2b: + return tgui->accel.offset; - case 0x2c: /*Background colour*/ - return tgui->accel.bg_col & 0xff; - case 0x2d: /*Background colour*/ - return tgui->accel.bg_col >> 8; + case 0x2c: /*Background colour*/ + return tgui->accel.bg_col & 0xff; + case 0x2d: /*Background colour*/ + return tgui->accel.bg_col >> 8; - case 0x30: /*Foreground colour*/ - return tgui->accel.fg_col & 0xff; - case 0x31: /*Foreground colour*/ - return tgui->accel.fg_col >> 8; + case 0x30: /*Foreground colour*/ + return tgui->accel.fg_col & 0xff; + case 0x31: /*Foreground colour*/ + return tgui->accel.fg_col >> 8; - case 0x38: /*Dest X*/ - return tgui->accel.dst_x & 0xff; - case 0x39: /*Dest X*/ - return tgui->accel.dst_x >> 8; - case 0x3a: /*Dest Y*/ - return tgui->accel.dst_y & 0xff; - case 0x3b: /*Dest Y*/ - return tgui->accel.dst_y >> 8; + case 0x38: /*Dest X*/ + return tgui->accel.dst_x & 0xff; + case 0x39: /*Dest X*/ + return tgui->accel.dst_x >> 8; + case 0x3a: /*Dest Y*/ + return tgui->accel.dst_y & 0xff; + case 0x3b: /*Dest Y*/ + return tgui->accel.dst_y >> 8; - case 0x3c: /*Src X*/ - return tgui->accel.src_x & 0xff; - case 0x3d: /*Src X*/ - return tgui->accel.src_x >> 8; - case 0x3e: /*Src Y*/ - return tgui->accel.src_y & 0xff; - case 0x3f: /*Src Y*/ - return tgui->accel.src_y >> 8; + case 0x3c: /*Src X*/ + return tgui->accel.src_x & 0xff; + case 0x3d: /*Src X*/ + return tgui->accel.src_x >> 8; + case 0x3e: /*Src Y*/ + return tgui->accel.src_y & 0xff; + case 0x3f: /*Src Y*/ + return tgui->accel.src_y >> 8; - case 0x40: /*Size X*/ - return tgui->accel.size_x & 0xff; - case 0x41: /*Size X*/ - return tgui->accel.size_x >> 8; - case 0x42: /*Size Y*/ - return tgui->accel.size_y & 0xff; - case 0x43: /*Size Y*/ - return tgui->accel.size_y >> 8; + case 0x40: /*Size X*/ + return tgui->accel.size_x & 0xff; + case 0x41: /*Size X*/ + return tgui->accel.size_x >> 8; + case 0x42: /*Size Y*/ + return tgui->accel.size_y & 0xff; + case 0x43: /*Size Y*/ + return tgui->accel.size_y >> 8; - case 0x80: - case 0x81: - case 0x82: - case 0x83: - case 0x84: - case 0x85: - case 0x86: - case 0x87: - case 0x88: - case 0x89: - case 0x8a: - case 0x8b: - case 0x8c: - case 0x8d: - case 0x8e: - case 0x8f: - case 0x90: - case 0x91: - case 0x92: - case 0x93: - case 0x94: - case 0x95: - case 0x96: - case 0x97: - case 0x98: - case 0x99: - case 0x9a: - case 0x9b: - case 0x9c: - case 0x9d: - case 0x9e: - case 0x9f: - case 0xa0: - case 0xa1: - case 0xa2: - case 0xa3: - case 0xa4: - case 0xa5: - case 0xa6: - case 0xa7: - case 0xa8: - case 0xa9: - case 0xaa: - case 0xab: - case 0xac: - case 0xad: - case 0xae: - case 0xaf: - case 0xb0: - case 0xb1: - case 0xb2: - case 0xb3: - case 0xb4: - case 0xb5: - case 0xb6: - case 0xb7: - case 0xb8: - case 0xb9: - case 0xba: - case 0xbb: - case 0xbc: - case 0xbd: - case 0xbe: - case 0xbf: - case 0xc0: - case 0xc1: - case 0xc2: - case 0xc3: - case 0xc4: - case 0xc5: - case 0xc6: - case 0xc7: - case 0xc8: - case 0xc9: - case 0xca: - case 0xcb: - case 0xcc: - case 0xcd: - case 0xce: - case 0xcf: - case 0xd0: - case 0xd1: - case 0xd2: - case 0xd3: - case 0xd4: - case 0xd5: - case 0xd6: - case 0xd7: - case 0xd8: - case 0xd9: - case 0xda: - case 0xdb: - case 0xdc: - case 0xdd: - case 0xde: - case 0xdf: - case 0xe0: - case 0xe1: - case 0xe2: - case 0xe3: - case 0xe4: - case 0xe5: - case 0xe6: - case 0xe7: - case 0xe8: - case 0xe9: - case 0xea: - case 0xeb: - case 0xec: - case 0xed: - case 0xee: - case 0xef: - 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:return tgui->accel.pattern[addr & 0x7f]; - } - return 0xff; + case 0x80: + case 0x81: + case 0x82: + case 0x83: + case 0x84: + case 0x85: + case 0x86: + case 0x87: + case 0x88: + case 0x89: + case 0x8a: + case 0x8b: + case 0x8c: + case 0x8d: + case 0x8e: + case 0x8f: + case 0x90: + case 0x91: + case 0x92: + case 0x93: + case 0x94: + case 0x95: + case 0x96: + case 0x97: + case 0x98: + case 0x99: + case 0x9a: + case 0x9b: + case 0x9c: + case 0x9d: + case 0x9e: + case 0x9f: + case 0xa0: + case 0xa1: + case 0xa2: + case 0xa3: + case 0xa4: + case 0xa5: + case 0xa6: + case 0xa7: + case 0xa8: + case 0xa9: + case 0xaa: + case 0xab: + case 0xac: + case 0xad: + case 0xae: + case 0xaf: + case 0xb0: + case 0xb1: + case 0xb2: + case 0xb3: + case 0xb4: + case 0xb5: + case 0xb6: + case 0xb7: + case 0xb8: + case 0xb9: + case 0xba: + case 0xbb: + case 0xbc: + case 0xbd: + case 0xbe: + case 0xbf: + case 0xc0: + case 0xc1: + case 0xc2: + case 0xc3: + case 0xc4: + case 0xc5: + case 0xc6: + case 0xc7: + case 0xc8: + case 0xc9: + case 0xca: + case 0xcb: + case 0xcc: + case 0xcd: + case 0xce: + case 0xcf: + case 0xd0: + case 0xd1: + case 0xd2: + case 0xd3: + case 0xd4: + case 0xd5: + case 0xd6: + case 0xd7: + case 0xd8: + case 0xd9: + case 0xda: + case 0xdb: + case 0xdc: + case 0xdd: + case 0xde: + case 0xdf: + case 0xe0: + case 0xe1: + case 0xe2: + case 0xe3: + case 0xe4: + case 0xe5: + case 0xe6: + case 0xe7: + case 0xe8: + case 0xe9: + case 0xea: + case 0xeb: + case 0xec: + case 0xed: + case 0xee: + case 0xef: + 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: + return tgui->accel.pattern[addr & 0x7f]; + } + return 0xff; } uint16_t tgui_accel_read_w(uint32_t addr, void *p) { - tgui_t *tgui = (tgui_t *)p; -// pclog("tgui_accel_read_w %08X\n", addr); - return tgui_accel_read(addr, tgui) | (tgui_accel_read(addr + 1, tgui) << 8); + tgui_t *tgui = (tgui_t *)p; + // pclog("tgui_accel_read_w %08X\n", addr); + return tgui_accel_read(addr, tgui) | (tgui_accel_read(addr + 1, tgui) << 8); } uint32_t tgui_accel_read_l(uint32_t addr, void *p) { - tgui_t *tgui = (tgui_t *)p; -// pclog("tgui_accel_read_l %08X\n", addr); - return tgui_accel_read_w(addr, tgui) | (tgui_accel_read_w(addr + 2, tgui) << 16); + tgui_t *tgui = (tgui_t *)p; + // pclog("tgui_accel_read_l %08X\n", addr); + return tgui_accel_read_w(addr, tgui) | (tgui_accel_read_w(addr + 2, tgui) << 16); } void tgui_accel_write_fb_b(uint32_t addr, uint8_t val, void *p) { - svga_t *svga = (svga_t *)p; - tgui_t *tgui = (tgui_t *)svga->p; + svga_t *svga = (svga_t *)p; + tgui_t *tgui = (tgui_t *)svga->p; - if (tgui->write_blitter) - tgui_queue(tgui, addr, val, FIFO_WRITE_FB_BYTE); - else - svga_write_linear(addr, val, svga); + if (tgui->write_blitter) + tgui_queue(tgui, addr, val, FIFO_WRITE_FB_BYTE); + else + svga_write_linear(addr, val, svga); } void tgui_accel_write_fb_w(uint32_t addr, uint16_t val, void *p) { - svga_t *svga = (svga_t *)p; - tgui_t *tgui = (tgui_t *)svga->p; + svga_t *svga = (svga_t *)p; + tgui_t *tgui = (tgui_t *)svga->p; - if (tgui->write_blitter) - tgui_queue(tgui, addr, val, FIFO_WRITE_FB_WORD); - else - svga_writew_linear(addr, val, svga); + if (tgui->write_blitter) + tgui_queue(tgui, addr, val, FIFO_WRITE_FB_WORD); + else + svga_writew_linear(addr, val, svga); } void tgui_accel_write_fb_l(uint32_t addr, uint32_t val, void *p) { - svga_t *svga = (svga_t *)p; - tgui_t *tgui = (tgui_t *)svga->p; + svga_t *svga = (svga_t *)p; + tgui_t *tgui = (tgui_t *)svga->p; - if (tgui->write_blitter) - tgui_queue(tgui, addr, val, FIFO_WRITE_FB_LONG); - else - svga_writel_linear(addr, val, svga); + if (tgui->write_blitter) + tgui_queue(tgui, addr, val, FIFO_WRITE_FB_LONG); + else + svga_writel_linear(addr, val, svga); } void tgui_add_status_info(char *s, int max_len, void *p) { - tgui_t *tgui = (tgui_t *)p; - char temps[256]; - uint64_t new_time = timer_read(); - uint64_t status_diff = new_time - tgui->status_time; - tgui->status_time = new_time; + tgui_t *tgui = (tgui_t *)p; + char temps[256]; + uint64_t new_time = timer_read(); + uint64_t status_diff = new_time - tgui->status_time; + tgui->status_time = new_time; - svga_add_status_info(s, max_len, &tgui->svga); + svga_add_status_info(s, max_len, &tgui->svga); - sprintf(temps, "%f%% CPU\n%f%% CPU (real)\n\n", ((double)tgui->blitter_time * 100.0) / timer_freq, ((double)tgui->blitter_time * 100.0) / status_diff); - strncat(s, temps, max_len); + sprintf(temps, "%f%% CPU\n%f%% CPU (real)\n\n", ((double)tgui->blitter_time * 100.0) / timer_freq, + ((double)tgui->blitter_time * 100.0) / status_diff); + strncat(s, temps, max_len); - tgui->blitter_time = 0; + tgui->blitter_time = 0; } -static device_config_t tgui9440_config[] = - { - { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "1 MB", - .value = 1 - }, - { - .description = "2 MB", - .value = 2 - }, - { - .description = "" - } - }, - .default_int = 2 - }, - { - .type = -1 - } - }; +static device_config_t tgui9440_config[] = { + {.name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .selection = {{.description = "1 MB", .value = 1}, {.description = "2 MB", .value = 2}, {.description = ""}}, + .default_int = 2}, + {.type = -1}}; -device_t tgui9400cxi_device = - { - "Trident TGUI 9400CXi", - 0, - tgui9400cxi_init, - tgui_close, - tgui9400cxi_available, - tgui_speed_changed, - tgui_force_redraw, - tgui_add_status_info, - tgui9440_config - }; +device_t tgui9400cxi_device = {"Trident TGUI 9400CXi", 0, + tgui9400cxi_init, tgui_close, + tgui9400cxi_available, tgui_speed_changed, + tgui_force_redraw, tgui_add_status_info, + tgui9440_config}; -device_t tgui9400cxi_elx_device = - { - "Trident TGUI 9400CXi (Elonex PC-425X)", - 0, - tgui9400cxi_elx_init, - tgui_close, - tgui9400cxi_available, - tgui_speed_changed, - tgui_force_redraw, - tgui_add_status_info, - tgui9440_config - }; +device_t tgui9400cxi_elx_device = {"Trident TGUI 9400CXi (Elonex PC-425X)", + 0, + tgui9400cxi_elx_init, + tgui_close, + tgui9400cxi_available, + tgui_speed_changed, + tgui_force_redraw, + tgui_add_status_info, + tgui9440_config}; -device_t tgui9440_device = - { - "Trident TGUI 9440", - 0, - tgui9440_init, - tgui_close, - tgui9440_available, - tgui_speed_changed, - tgui_force_redraw, - tgui_add_status_info, - tgui9440_config - }; +device_t tgui9440_device = {"Trident TGUI 9440", 0, + tgui9440_init, tgui_close, + tgui9440_available, tgui_speed_changed, + tgui_force_redraw, tgui_add_status_info, + tgui9440_config}; diff --git a/src/video/vid_tkd8001_ramdac.c b/src/video/vid_tkd8001_ramdac.c index cfa25e45..edfe9d94 100644 --- a/src/video/vid_tkd8001_ramdac.c +++ b/src/video/vid_tkd8001_ramdac.c @@ -6,51 +6,57 @@ #include "vid_tkd8001_ramdac.h" void tkd8001_ramdac_out(uint16_t addr, uint8_t val, tkd8001_ramdac_t *ramdac, svga_t *svga) { -// pclog("OUT RAMDAC %04X %02X %04X:%04X\n",addr,val,CS,pc); - switch (addr) { - case 0x3C6: - if (ramdac->state == 4) { - ramdac->state = 0; - ramdac->ctrl = val; - switch (val >> 5) { - case 0: - case 1: - case 2: - case 3:svga->bpp = 8; - break; - case 5:svga->bpp = 15; - break; - case 6:svga->bpp = 24; - break; - case 7:svga->bpp = 16; - break; - } - return; - } - // tkd8001_state = 0; - break; - case 0x3C7: - case 0x3C8: - case 0x3C9:ramdac->state = 0; - break; - } - svga_out(addr, val, svga); + // pclog("OUT RAMDAC %04X %02X %04X:%04X\n",addr,val,CS,pc); + switch (addr) { + case 0x3C6: + if (ramdac->state == 4) { + ramdac->state = 0; + ramdac->ctrl = val; + switch (val >> 5) { + case 0: + case 1: + case 2: + case 3: + svga->bpp = 8; + break; + case 5: + svga->bpp = 15; + break; + case 6: + svga->bpp = 24; + break; + case 7: + svga->bpp = 16; + break; + } + return; + } + // tkd8001_state = 0; + break; + case 0x3C7: + case 0x3C8: + case 0x3C9: + ramdac->state = 0; + break; + } + svga_out(addr, val, svga); } uint8_t tkd8001_ramdac_in(uint16_t addr, tkd8001_ramdac_t *ramdac, svga_t *svga) { -// pclog("IN RAMDAC %04X %04X:%04X\n",addr,CS,pc); - switch (addr) { - case 0x3C6: - if (ramdac->state == 4) { - //tkd8001_state = 0; - return ramdac->ctrl; - } - ramdac->state++; - break; - case 0x3C7: - case 0x3C8: - case 0x3C9:ramdac->state = 0; - break; - } - return svga_in(addr, svga); + // pclog("IN RAMDAC %04X %04X:%04X\n",addr,CS,pc); + switch (addr) { + case 0x3C6: + if (ramdac->state == 4) { + // tkd8001_state = 0; + return ramdac->ctrl; + } + ramdac->state++; + break; + case 0x3C7: + case 0x3C8: + case 0x3C9: + ramdac->state = 0; + break; + } + return svga_in(addr, svga); } diff --git a/src/video/vid_tvga.c b/src/video/vid_tvga.c index b43bc0df..71167345 100644 --- a/src/video/vid_tvga.c +++ b/src/video/vid_tvga.c @@ -11,436 +11,407 @@ #include "vid_tkd8001_ramdac.h" #include "vid_tvga.h" -enum { - TVGA_8900D = 0x33, - TVGA_9000 = 0x23 -}; +enum { TVGA_8900D = 0x33, TVGA_9000 = 0x23 }; typedef struct tvga_t { - mem_mapping_t linear_mapping; - mem_mapping_t accel_mapping; + mem_mapping_t linear_mapping; + mem_mapping_t accel_mapping; - svga_t svga; - tkd8001_ramdac_t ramdac; + svga_t svga; + tkd8001_ramdac_t ramdac; - rom_t bios_rom; + rom_t bios_rom; - uint8_t tvga_3d8, tvga_3d9; - int oldmode; - uint8_t oldctrl1; - uint8_t oldctrl2, newctrl2; + uint8_t tvga_3d8, tvga_3d9; + int oldmode; + uint8_t oldctrl1; + uint8_t oldctrl2, newctrl2; - int vram_size; - uint32_t vram_mask; + int vram_size; + uint32_t vram_mask; - uint8_t id; + uint8_t id; } tvga_t; -static uint8_t crtc_mask[0x40] = - { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x7f, 0xff, 0x3f, 0x7f, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xef, - 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, - 0x7f, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x03, - 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; +static uint8_t crtc_mask[0x40] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0x3f, 0x7f, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xef, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, + 0x7f, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x03, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; static void tvga_recalcbanking(tvga_t *tvga); void tvga_out(uint16_t addr, uint8_t val, void *p) { - tvga_t *tvga = (tvga_t *)p; - svga_t *svga = &tvga->svga; + tvga_t *tvga = (tvga_t *)p; + svga_t *svga = &tvga->svga; - uint8_t old; + uint8_t old; -// pclog("tvga_out : %04X %02X %04X:%04X %i\n", addr, val, CS,pc, svga->bpp); - if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1)) - addr ^= 0x60; + // pclog("tvga_out : %04X %02X %04X:%04X %i\n", addr, val, CS,pc, svga->bpp); + if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1)) + addr ^= 0x60; - switch (addr) { - case 0x3C5: - switch (svga->seqaddr & 0xf) { - case 0xB:tvga->oldmode = 1; - break; - case 0xC: - if (svga->seqregs[0xe] & 0x80) - svga->seqregs[0xc] = val; - break; - case 0xd: - if (tvga->oldmode) - tvga->oldctrl2 = val; - else { - tvga->newctrl2 = val; - svga_recalctimings(svga); - } - break; - case 0xE: - if (tvga->oldmode) { - tvga->oldctrl1 = val; - svga_recalctimings(svga); - } else { - svga->seqregs[0xe] = val ^ 2; - tvga->tvga_3d8 = svga->seqregs[0xe] & 0xf; - tvga_recalcbanking(tvga); - } - return; - } - break; + switch (addr) { + case 0x3C5: + switch (svga->seqaddr & 0xf) { + case 0xB: + tvga->oldmode = 1; + break; + case 0xC: + if (svga->seqregs[0xe] & 0x80) + svga->seqregs[0xc] = val; + break; + case 0xd: + if (tvga->oldmode) + tvga->oldctrl2 = val; + else { + tvga->newctrl2 = val; + svga_recalctimings(svga); + } + break; + case 0xE: + if (tvga->oldmode) { + tvga->oldctrl1 = val; + svga_recalctimings(svga); + } else { + svga->seqregs[0xe] = val ^ 2; + tvga->tvga_3d8 = svga->seqregs[0xe] & 0xf; + tvga_recalcbanking(tvga); + } + return; + } + break; - case 0x3C6: - case 0x3C7: - case 0x3C8: - case 0x3C9: - if (tvga->id != TVGA_9000) { - tkd8001_ramdac_out(addr, val, &tvga->ramdac, svga); - return; - } - break; + case 0x3C6: + case 0x3C7: + case 0x3C8: + case 0x3C9: + if (tvga->id != TVGA_9000) { + tkd8001_ramdac_out(addr, val, &tvga->ramdac, svga); + return; + } + break; - case 0x3CF: - switch (svga->gdcaddr & 15) { - case 0x6:old = svga->gdcreg[6]; - svga_out(addr, val, svga); - if ((old & 0xc) != 0 && (val & 0xc) == 0) { - /*override mask - TVGA supports linear 128k at A0000*/ - svga->banked_mask = 0x1ffff; - } - return; - case 0xE:svga->gdcreg[0xe] = val ^ 2; - tvga->tvga_3d9 = svga->gdcreg[0xe] & 0xf; - tvga_recalcbanking(tvga); - break; - case 0xF:svga->gdcreg[0xf] = val; - tvga_recalcbanking(tvga); - break; - } - break; - case 0x3D4:svga->crtcreg = val & 0x3f; - return; - case 0x3D5: - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) - return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); - old = svga->crtc[svga->crtcreg]; - val &= crtc_mask[svga->crtcreg]; - svga->crtc[svga->crtcreg] = val; -// if (svga->crtcreg != 0xC && svga->crtcreg != 0xE && svga->crtcreg != 0xF) pclog("CRTC R%02X = %02X %04X:%04X\n", svga->crtcreg, val, CS, pc); - if (old != val) { - if (svga->crtcreg < 0xE || svga->crtcreg > 0x10) { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - } - switch (svga->crtcreg) { - case 0x1e:svga->vram_display_mask = (val & 0x80) ? tvga->vram_mask : 0x3ffff; - break; - } - return; - case 0x3D8: - if (svga->gdcreg[0xf] & 4) { - tvga->tvga_3d8 = val; - tvga_recalcbanking(tvga); - } - return; - case 0x3D9: - if (svga->gdcreg[0xf] & 4) { - tvga->tvga_3d9 = val; - tvga_recalcbanking(tvga); - } - return; - case 0x3DB: - if (tvga->id == TVGA_8900D) { - /*3db appears to be a 4 bit clock select register on 8900D*/ - svga->miscout = (svga->miscout & ~0x0c) | ((val & 3) << 2); - tvga->newctrl2 = (tvga->newctrl2 & ~0x01) | ((val & 4) >> 2); - tvga->oldctrl1 = (tvga->oldctrl1 & ~0x10) | ((val & 8) << 1); - svga_recalctimings(svga); - } - break; - } - svga_out(addr, val, svga); + case 0x3CF: + switch (svga->gdcaddr & 15) { + case 0x6: + old = svga->gdcreg[6]; + svga_out(addr, val, svga); + if ((old & 0xc) != 0 && (val & 0xc) == 0) { + /*override mask - TVGA supports linear 128k at A0000*/ + svga->banked_mask = 0x1ffff; + } + return; + case 0xE: + svga->gdcreg[0xe] = val ^ 2; + tvga->tvga_3d9 = svga->gdcreg[0xe] & 0xf; + tvga_recalcbanking(tvga); + break; + case 0xF: + svga->gdcreg[0xf] = val; + tvga_recalcbanking(tvga); + break; + } + break; + case 0x3D4: + svga->crtcreg = val & 0x3f; + return; + case 0x3D5: + if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) + return; + if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) + val = (svga->crtc[7] & ~0x10) | (val & 0x10); + old = svga->crtc[svga->crtcreg]; + val &= crtc_mask[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; + // if (svga->crtcreg != 0xC && svga->crtcreg != 0xE && svga->crtcreg != 0xF) pclog("CRTC R%02X = + // %02X %04X:%04X\n", svga->crtcreg, val, CS, pc); + if (old != val) { + if (svga->crtcreg < 0xE || svga->crtcreg > 0x10) { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } + } + switch (svga->crtcreg) { + case 0x1e: + svga->vram_display_mask = (val & 0x80) ? tvga->vram_mask : 0x3ffff; + break; + } + return; + case 0x3D8: + if (svga->gdcreg[0xf] & 4) { + tvga->tvga_3d8 = val; + tvga_recalcbanking(tvga); + } + return; + case 0x3D9: + if (svga->gdcreg[0xf] & 4) { + tvga->tvga_3d9 = val; + tvga_recalcbanking(tvga); + } + return; + case 0x3DB: + if (tvga->id == TVGA_8900D) { + /*3db appears to be a 4 bit clock select register on 8900D*/ + svga->miscout = (svga->miscout & ~0x0c) | ((val & 3) << 2); + tvga->newctrl2 = (tvga->newctrl2 & ~0x01) | ((val & 4) >> 2); + tvga->oldctrl1 = (tvga->oldctrl1 & ~0x10) | ((val & 8) << 1); + svga_recalctimings(svga); + } + break; + } + svga_out(addr, val, svga); } uint8_t tvga_in(uint16_t addr, void *p) { - tvga_t *tvga = (tvga_t *)p; - svga_t *svga = &tvga->svga; + tvga_t *tvga = (tvga_t *)p; + svga_t *svga = &tvga->svga; -// if (addr != 0x3da) pclog("tvga_in : %04X %04X:%04X\n", addr, CS,pc); + // if (addr != 0x3da) pclog("tvga_in : %04X %04X:%04X\n", addr, CS,pc); - if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1)) - addr ^= 0x60; + if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1)) + addr ^= 0x60; - switch (addr) { - case 0x3C5: - if ((svga->seqaddr & 0xf) == 0xb) { -// printf("Read Trident ID %04X:%04X %04X\n",CS,pc,readmemw(ss,SP)); - tvga->oldmode = 0; - return tvga->id; - } - if ((svga->seqaddr & 0xf) == 0xc) { -// printf("Read Trident Power Up 1 %04X:%04X %04X\n",CS,pc,readmemw(ss,SP)); -// return 0x20; /*2 DRAM banks*/ - } - if ((svga->seqaddr & 0xf) == 0xd) { - if (tvga->oldmode) - return tvga->oldctrl2; - return tvga->newctrl2; - } - if ((svga->seqaddr & 0xf) == 0xe) { - if (tvga->oldmode) - return tvga->oldctrl1; - } - break; - case 0x3C6: - case 0x3C7: - case 0x3C8: - case 0x3C9: - if (tvga->id != TVGA_9000) - return tkd8001_ramdac_in(addr, &tvga->ramdac, svga); - break; - case 0x3D4:return svga->crtcreg; - case 0x3D5: - if (svga->crtcreg > 0x18 && svga->crtcreg < 0x1e) - return 0xff; - return svga->crtc[svga->crtcreg]; - case 0x3d8:return tvga->tvga_3d8; - case 0x3d9:return tvga->tvga_3d9; - } - return svga_in(addr, svga); + switch (addr) { + case 0x3C5: + if ((svga->seqaddr & 0xf) == 0xb) { + // printf("Read Trident ID %04X:%04X %04X\n",CS,pc,readmemw(ss,SP)); + tvga->oldmode = 0; + return tvga->id; + } + if ((svga->seqaddr & 0xf) == 0xc) { + // printf("Read Trident Power Up 1 %04X:%04X %04X\n",CS,pc,readmemw(ss,SP)); + // return 0x20; /*2 DRAM banks*/ + } + if ((svga->seqaddr & 0xf) == 0xd) { + if (tvga->oldmode) + return tvga->oldctrl2; + return tvga->newctrl2; + } + if ((svga->seqaddr & 0xf) == 0xe) { + if (tvga->oldmode) + return tvga->oldctrl1; + } + break; + case 0x3C6: + case 0x3C7: + case 0x3C8: + case 0x3C9: + if (tvga->id != TVGA_9000) + return tkd8001_ramdac_in(addr, &tvga->ramdac, svga); + break; + case 0x3D4: + return svga->crtcreg; + case 0x3D5: + if (svga->crtcreg > 0x18 && svga->crtcreg < 0x1e) + return 0xff; + return svga->crtc[svga->crtcreg]; + case 0x3d8: + return tvga->tvga_3d8; + case 0x3d9: + return tvga->tvga_3d9; + } + return svga_in(addr, svga); } static void tvga_recalcbanking(tvga_t *tvga) { - svga_t *svga = &tvga->svga; + svga_t *svga = &tvga->svga; - svga->write_bank = (tvga->tvga_3d8 & 0x1f) * 65536; + svga->write_bank = (tvga->tvga_3d8 & 0x1f) * 65536; - if (svga->gdcreg[0xf] & 1) - svga->read_bank = (tvga->tvga_3d9 & 0x1f) * 65536; - else - svga->read_bank = svga->write_bank; + if (svga->gdcreg[0xf] & 1) + svga->read_bank = (tvga->tvga_3d9 & 0x1f) * 65536; + else + svga->read_bank = svga->write_bank; -// pclog("recalcbanking: write_bank=%08x read_bank=%08x GDC[E]=%02x GDC[F]=%02x SEQ[E]=%02x 3d8=%02x 3d9=%02x\n", svga->read_bank, svga->write_bank, svga->gdcreg[0xe], svga->gdcreg[0xf], svga->seqregs[0xe], tvga->tvga_3d8, tvga->tvga_3d9); + // pclog("recalcbanking: write_bank=%08x read_bank=%08x GDC[E]=%02x GDC[F]=%02x SEQ[E]=%02x 3d8=%02x 3d9=%02x\n", + // svga->read_bank, svga->write_bank, svga->gdcreg[0xe], svga->gdcreg[0xf], svga->seqregs[0xe], tvga->tvga_3d8, + // tvga->tvga_3d9); } void tvga_recalctimings(svga_t *svga) { - tvga_t *tvga = (tvga_t *)svga->p; - int clksel; - int high_res_256 = 0; + tvga_t *tvga = (tvga_t *)svga->p; + int clksel; + int high_res_256 = 0; - if (!svga->rowoffset) - svga->rowoffset = 0x100; /*This is the only sensible way I can see this being handled, + if (!svga->rowoffset) + svga->rowoffset = 0x100; /*This is the only sensible way I can see this being handled, given that TVGA8900D has no overflow bits. Some sort of overflow is required for 320x200x24 and 1024x768x16*/ - if (svga->crtc[0x29] & 0x10) - svga->rowoffset += 0x100; + if (svga->crtc[0x29] & 0x10) + svga->rowoffset += 0x100; - if (svga->bpp == 24) - svga->hdisp = (svga->crtc[1] + 1) * 8; + if (svga->bpp == 24) + svga->hdisp = (svga->crtc[1] + 1) * 8; - if ((svga->crtc[0x1e] & 0xA0) == 0xA0) - svga->ma_latch |= 0x10000; - if ((svga->crtc[0x27] & 0x01) == 0x01) - svga->ma_latch |= 0x20000; - if ((svga->crtc[0x27] & 0x02) == 0x02) - svga->ma_latch |= 0x40000; + if ((svga->crtc[0x1e] & 0xA0) == 0xA0) + svga->ma_latch |= 0x10000; + if ((svga->crtc[0x27] & 0x01) == 0x01) + svga->ma_latch |= 0x20000; + if ((svga->crtc[0x27] & 0x02) == 0x02) + svga->ma_latch |= 0x40000; - if (tvga->oldctrl2 & 0x10) { - svga->rowoffset <<= 1; - svga->ma_latch <<= 1; - } - if (svga->gdcreg[0xf] & 0x08) { - svga->htotal *= 2; - svga->hdisp *= 2; - svga->hdisp_time *= 2; - } + if (tvga->oldctrl2 & 0x10) { + svga->rowoffset <<= 1; + svga->ma_latch <<= 1; + } + if (svga->gdcreg[0xf] & 0x08) { + svga->htotal *= 2; + svga->hdisp *= 2; + svga->hdisp_time *= 2; + } - svga->interlace = svga->crtc[0x1e] & 4; - if (svga->interlace) - svga->rowoffset >>= 1; + svga->interlace = svga->crtc[0x1e] & 4; + if (svga->interlace) + svga->rowoffset >>= 1; - if (tvga->id == TVGA_8900D) - clksel = ((svga->miscout >> 2) & 3) | ((tvga->newctrl2 & 0x01) << 2) | ((tvga->oldctrl1 & 0x10) >> 1); - else - clksel = ((svga->miscout >> 2) & 3) | ((tvga->newctrl2 & 0x01) << 2) | ((tvga->newctrl2 & 0x40) >> 3); - switch (clksel) { - case 0x2:svga->clock = (cpuclock * (double)(1ull << 32)) / 44900000.0; - break; - case 0x3:svga->clock = (cpuclock * (double)(1ull << 32)) / 36000000.0; - break; - case 0x4:svga->clock = (cpuclock * (double)(1ull << 32)) / 57272000.0; - break; - case 0x5:svga->clock = (cpuclock * (double)(1ull << 32)) / 65000000.0; - break; - case 0x6:svga->clock = (cpuclock * (double)(1ull << 32)) / 50350000.0; - break; - case 0x7:svga->clock = (cpuclock * (double)(1ull << 32)) / 40000000.0; - break; - case 0x8:svga->clock = (cpuclock * (double)(1ull << 32)) / 88000000.0; - break; - case 0x9:svga->clock = (cpuclock * (double)(1ull << 32)) / 98000000.0; - break; - case 0xa:svga->clock = (cpuclock * (double)(1ull << 32)) / 118800000.0; - break; - case 0xb:svga->clock = (cpuclock * (double)(1ull << 32)) / 108000000.0; - break; - case 0xc:svga->clock = (cpuclock * (double)(1ull << 32)) / 72000000.0; - break; - case 0xd:svga->clock = (cpuclock * (double)(1ull << 32)) / 77000000.0; - break; - case 0xe:svga->clock = (cpuclock * (double)(1ull << 32)) / 80000000.0; - break; - case 0xf:svga->clock = (cpuclock * (double)(1ull << 32)) / 75000000.0; - break; - } + if (tvga->id == TVGA_8900D) + clksel = ((svga->miscout >> 2) & 3) | ((tvga->newctrl2 & 0x01) << 2) | ((tvga->oldctrl1 & 0x10) >> 1); + else + clksel = ((svga->miscout >> 2) & 3) | ((tvga->newctrl2 & 0x01) << 2) | ((tvga->newctrl2 & 0x40) >> 3); + switch (clksel) { + case 0x2: + svga->clock = (cpuclock * (double)(1ull << 32)) / 44900000.0; + break; + case 0x3: + svga->clock = (cpuclock * (double)(1ull << 32)) / 36000000.0; + break; + case 0x4: + svga->clock = (cpuclock * (double)(1ull << 32)) / 57272000.0; + break; + case 0x5: + svga->clock = (cpuclock * (double)(1ull << 32)) / 65000000.0; + break; + case 0x6: + svga->clock = (cpuclock * (double)(1ull << 32)) / 50350000.0; + break; + case 0x7: + svga->clock = (cpuclock * (double)(1ull << 32)) / 40000000.0; + break; + case 0x8: + svga->clock = (cpuclock * (double)(1ull << 32)) / 88000000.0; + break; + case 0x9: + svga->clock = (cpuclock * (double)(1ull << 32)) / 98000000.0; + break; + case 0xa: + svga->clock = (cpuclock * (double)(1ull << 32)) / 118800000.0; + break; + case 0xb: + svga->clock = (cpuclock * (double)(1ull << 32)) / 108000000.0; + break; + case 0xc: + svga->clock = (cpuclock * (double)(1ull << 32)) / 72000000.0; + break; + case 0xd: + svga->clock = (cpuclock * (double)(1ull << 32)) / 77000000.0; + break; + case 0xe: + svga->clock = (cpuclock * (double)(1ull << 32)) / 80000000.0; + break; + case 0xf: + svga->clock = (cpuclock * (double)(1ull << 32)) / 75000000.0; + break; + } - if (tvga->id == TVGA_9000) { - /*TVGA9000 doesn't seem to have support for a 'high res' 256 colour mode - (without the VGA pixel doubling). Instead it implements these modes by - doubling the horizontal pixel count and pixel clock. Hence we use a - basic heuristic to detect this*/ - if (svga->interlace) - high_res_256 = (svga->htotal * 8) > (svga->vtotal * 4); - else - high_res_256 = (svga->htotal * 8) > (svga->vtotal * 2); - } - if ((tvga->oldctrl2 & 0x10) || high_res_256) { - if (high_res_256) - svga->hdisp /= 2; - switch (svga->bpp) { - case 8:svga->render = svga_render_8bpp_highres; - break; - case 15:svga->render = svga_render_15bpp_highres; - svga->hdisp /= 2; - break; - case 16:svga->render = svga_render_16bpp_highres; - svga->hdisp /= 2; - break; - case 24:svga->render = svga_render_24bpp_highres; - svga->hdisp /= 3; - break; - } - svga->lowres = 0; - } + if (tvga->id == TVGA_9000) { + /*TVGA9000 doesn't seem to have support for a 'high res' 256 colour mode + (without the VGA pixel doubling). Instead it implements these modes by + doubling the horizontal pixel count and pixel clock. Hence we use a + basic heuristic to detect this*/ + if (svga->interlace) + high_res_256 = (svga->htotal * 8) > (svga->vtotal * 4); + else + high_res_256 = (svga->htotal * 8) > (svga->vtotal * 2); + } + if ((tvga->oldctrl2 & 0x10) || high_res_256) { + if (high_res_256) + svga->hdisp /= 2; + switch (svga->bpp) { + case 8: + svga->render = svga_render_8bpp_highres; + break; + case 15: + svga->render = svga_render_15bpp_highres; + svga->hdisp /= 2; + break; + case 16: + svga->render = svga_render_16bpp_highres; + svga->hdisp /= 2; + break; + case 24: + svga->render = svga_render_24bpp_highres; + svga->hdisp /= 3; + break; + } + svga->lowres = 0; + } } static void *tvga_common_init(char *fn, uint32_t id, int vram_size) { - tvga_t *tvga = malloc(sizeof(tvga_t)); - memset(tvga, 0, sizeof(tvga_t)); + tvga_t *tvga = malloc(sizeof(tvga_t)); + memset(tvga, 0, sizeof(tvga_t)); - tvga->vram_size = vram_size << 10; - tvga->vram_mask = tvga->vram_size - 1; - tvga->id = id; + tvga->vram_size = vram_size << 10; + tvga->vram_mask = tvga->vram_size - 1; + tvga->id = id; - rom_init(&tvga->bios_rom, fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&tvga->bios_rom, fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - svga_init(&tvga->svga, tvga, tvga->vram_size, - tvga_recalctimings, - tvga_in, tvga_out, - NULL, - NULL); + svga_init(&tvga->svga, tvga, tvga->vram_size, tvga_recalctimings, tvga_in, tvga_out, NULL, NULL); - io_sethandler(0x03c0, 0x0020, tvga_in, NULL, NULL, tvga_out, NULL, NULL, tvga); + io_sethandler(0x03c0, 0x0020, tvga_in, NULL, NULL, tvga_out, NULL, NULL, tvga); - return tvga; + return tvga; } static void *tvga8900d_init() { - int vram_size = device_get_config_int("memory"); + int vram_size = device_get_config_int("memory"); - return tvga_common_init("trident.bin", TVGA_8900D, vram_size); -} -static void *tvga9000b_init() { - return tvga_common_init("tvga9000b/BIOS.BIN", TVGA_9000, 512); + return tvga_common_init("trident.bin", TVGA_8900D, vram_size); } +static void *tvga9000b_init() { return tvga_common_init("tvga9000b/BIOS.BIN", TVGA_9000, 512); } -static int tvga8900d_available() { - return rom_present("trident.bin"); -} -static int tvga9000b_available() { - return rom_present("tvga9000b/BIOS.BIN"); -} +static int tvga8900d_available() { return rom_present("trident.bin"); } +static int tvga9000b_available() { return rom_present("tvga9000b/BIOS.BIN"); } void tvga_close(void *p) { - tvga_t *tvga = (tvga_t *)p; + tvga_t *tvga = (tvga_t *)p; - svga_close(&tvga->svga); + svga_close(&tvga->svga); - free(tvga); + free(tvga); } void tvga_speed_changed(void *p) { - tvga_t *tvga = (tvga_t *)p; + tvga_t *tvga = (tvga_t *)p; - svga_recalctimings(&tvga->svga); + svga_recalctimings(&tvga->svga); } void tvga_force_redraw(void *p) { - tvga_t *tvga = (tvga_t *)p; + tvga_t *tvga = (tvga_t *)p; - tvga->svga.fullchange = changeframecount; + tvga->svga.fullchange = changeframecount; } void tvga_add_status_info(char *s, int max_len, void *p) { - tvga_t *tvga = (tvga_t *)p; + tvga_t *tvga = (tvga_t *)p; - svga_add_status_info(s, max_len, &tvga->svga); + svga_add_status_info(s, max_len, &tvga->svga); } -static device_config_t tvga_config[] = - { - { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "256 kB", - .value = 256 - }, - { - .description = "512 kB", - .value = 512 - }, - { - .description = "1 MB", - .value = 1024 - }, - /*Chip supports 2mb, but drivers are buggy*/ - { - .description = "" - } - }, - .default_int = 1024 - }, - { - .type = -1 - } - }; +static device_config_t tvga_config[] = {{.name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .selection = {{.description = "256 kB", .value = 256}, + {.description = "512 kB", .value = 512}, + {.description = "1 MB", .value = 1024}, + /*Chip supports 2mb, but drivers are buggy*/ + {.description = ""}}, + .default_int = 1024}, + {.type = -1}}; -device_t tvga8900d_device = - { - "Trident TVGA 8900D", - 0, - tvga8900d_init, - tvga_close, - tvga8900d_available, - tvga_speed_changed, - tvga_force_redraw, - tvga_add_status_info, - tvga_config - }; -device_t tvga9000b_device = - { - "Trident TVGA 9000B", - 0, - tvga9000b_init, - tvga_close, - tvga9000b_available, - tvga_speed_changed, - tvga_force_redraw, - tvga_add_status_info, - NULL - }; +device_t tvga8900d_device = { + "Trident TVGA 8900D", 0, tvga8900d_init, tvga_close, tvga8900d_available, tvga_speed_changed, tvga_force_redraw, + tvga_add_status_info, tvga_config}; +device_t tvga9000b_device = { + "Trident TVGA 9000B", 0, tvga9000b_init, tvga_close, tvga9000b_available, tvga_speed_changed, tvga_force_redraw, + tvga_add_status_info, NULL}; diff --git a/src/video/vid_tvp3026_ramdac.c b/src/video/vid_tvp3026_ramdac.c index e97f1569..d5aa8ddb 100644 --- a/src/video/vid_tvp3026_ramdac.c +++ b/src/video/vid_tvp3026_ramdac.c @@ -4,19 +4,19 @@ #include "vid_svga.h" #include "vid_tvp3026_ramdac.h" -#define REG_DCC 0x09 +#define REG_DCC 0x09 #define REG_CURSOR_DATA 0x0b -#define REG_CURSOR_XL 0x0c -#define REG_CURSOR_XH 0x0d -#define REG_CURSOR_YL 0x0e -#define REG_CURSOR_YH 0x0f +#define REG_CURSOR_XL 0x0c +#define REG_CURSOR_XH 0x0d +#define REG_CURSOR_YL 0x0e +#define REG_CURSOR_YH 0x0f -#define IREG_ICC 0x06 -#define REG_MSC 0x1e +#define IREG_ICC 0x06 +#define REG_MSC 0x1e #define DCC_MODE_SEL_MASK (0x03) #define DCC_MODE_SEL_3_COLOUR (0x01) -#define DCC_MODE_SEL_XGA (0x02) +#define DCC_MODE_SEL_XGA (0x02) #define DCC_MODE_SEL_XWINDOWS (0x03) #define CCR_ADDR_SHIFT (2) #define CCR_ADDR_MASK (3 << CCR_ADDR_SHIFT) @@ -26,342 +26,392 @@ /*Update SVGA hwcursor variables with RAMDAC cursor. Should only be called when ramdac->cursor_enabled is set, otherwise the host SVGA board controls the cursor*/ static void update_cursor(tvp3026_ramdac_t *ramdac, svga_t *svga) { -// pclog("update_cursor: %02x\n", ramdac->regs[REG_DCC]); - if (ramdac->cursor_control & DCC_MODE_SEL_MASK) { - svga->hwcursor.ena = 1; - if (ramdac->cursor_x >= 64) { - svga->hwcursor.xoff = 0; - svga->hwcursor.x = ramdac->cursor_x - 64; - } else { - svga->hwcursor.xoff = 64 - ramdac->cursor_x; - svga->hwcursor.x = 0; - } - if (ramdac->cursor_y >= 64) { - svga->hwcursor.yoff = 0; - svga->hwcursor.addr = 0; - svga->hwcursor.y = ramdac->cursor_y - 64; - } else { - svga->hwcursor.yoff = 64 - ramdac->cursor_y; - svga->hwcursor.addr = svga->hwcursor.yoff * 8; - svga->hwcursor.y = 0; - } - ramdac->cursor_mode = ramdac->cursor_control & DCC_MODE_SEL_MASK; -// pclog(" x=%i y=%i\n", svga->hwcursor.x, svga->hwcursor.y); - } else - svga->hwcursor.ena = 0; + // pclog("update_cursor: %02x\n", ramdac->regs[REG_DCC]); + if (ramdac->cursor_control & DCC_MODE_SEL_MASK) { + svga->hwcursor.ena = 1; + if (ramdac->cursor_x >= 64) { + svga->hwcursor.xoff = 0; + svga->hwcursor.x = ramdac->cursor_x - 64; + } else { + svga->hwcursor.xoff = 64 - ramdac->cursor_x; + svga->hwcursor.x = 0; + } + if (ramdac->cursor_y >= 64) { + svga->hwcursor.yoff = 0; + svga->hwcursor.addr = 0; + svga->hwcursor.y = ramdac->cursor_y - 64; + } else { + svga->hwcursor.yoff = 64 - ramdac->cursor_y; + svga->hwcursor.addr = svga->hwcursor.yoff * 8; + svga->hwcursor.y = 0; + } + ramdac->cursor_mode = ramdac->cursor_control & DCC_MODE_SEL_MASK; + // pclog(" x=%i y=%i\n", svga->hwcursor.x, svga->hwcursor.y); + } else + svga->hwcursor.ena = 0; } void tvp3026_ramdac_out(uint16_t addr, uint8_t val, tvp3026_ramdac_t *ramdac, svga_t *svga) { -// pclog("tvp3026_ramdac_out: addr=%04x val=%02x\n", addr, val); - switch (addr) { - case 0x0:ramdac->reg_idx = val; - case 0x1:svga_out(addr + 0x3c8, val, svga); - break; - case 0x2: - case 0x3:svga_out(addr + 0x3c4, val, svga); - break; + // pclog("tvp3026_ramdac_out: addr=%04x val=%02x\n", addr, val); + switch (addr) { + case 0x0: + ramdac->reg_idx = val; + case 0x1: + svga_out(addr + 0x3c8, val, svga); + break; + case 0x2: + case 0x3: + svga_out(addr + 0x3c4, val, svga); + break; - case 0x4:ramdac->cursor_pal_write = val; - ramdac->cursor_pal_pos = 0; - break; - case 0x5:svga->fullchange = changeframecount; - switch (ramdac->cursor_pal_pos) { - case 0:ramdac->cursor_pal_r = val; - ramdac->cursor_pal_pos++; - break; - case 1:ramdac->cursor_pal_g = val; - ramdac->cursor_pal_pos++; - break; - case 2:ramdac->cursor_pal[ramdac->cursor_pal_write].r = ramdac->cursor_pal_r; - ramdac->cursor_pal[ramdac->cursor_pal_write].g = ramdac->cursor_pal_g; - ramdac->cursor_pal[ramdac->cursor_pal_write].b = val; - ramdac->cursor_pal_look[ramdac->cursor_pal_write] = - makecol32(ramdac->cursor_pal[ramdac->cursor_pal_write].r, ramdac->cursor_pal[ramdac->cursor_pal_write].g, ramdac->cursor_pal[ramdac->cursor_pal_write].b); - ramdac->cursor_pal_pos = 0; - ramdac->cursor_pal_write = (ramdac->cursor_pal_write + 1) & 3; - break; - } - break; - case 0x7:ramdac->cursor_pal_read = val; - ramdac->cursor_pal_pos = 0; - break; + case 0x4: + ramdac->cursor_pal_write = val; + ramdac->cursor_pal_pos = 0; + break; + case 0x5: + svga->fullchange = changeframecount; + switch (ramdac->cursor_pal_pos) { + case 0: + ramdac->cursor_pal_r = val; + ramdac->cursor_pal_pos++; + break; + case 1: + ramdac->cursor_pal_g = val; + ramdac->cursor_pal_pos++; + break; + case 2: + ramdac->cursor_pal[ramdac->cursor_pal_write].r = ramdac->cursor_pal_r; + ramdac->cursor_pal[ramdac->cursor_pal_write].g = ramdac->cursor_pal_g; + ramdac->cursor_pal[ramdac->cursor_pal_write].b = val; + ramdac->cursor_pal_look[ramdac->cursor_pal_write] = makecol32( + ramdac->cursor_pal[ramdac->cursor_pal_write].r, ramdac->cursor_pal[ramdac->cursor_pal_write].g, + ramdac->cursor_pal[ramdac->cursor_pal_write].b); + ramdac->cursor_pal_pos = 0; + ramdac->cursor_pal_write = (ramdac->cursor_pal_write + 1) & 3; + break; + } + break; + case 0x7: + ramdac->cursor_pal_read = val; + ramdac->cursor_pal_pos = 0; + break; - case REG_DCC:ramdac->cursor_control = (ramdac->cursor_control & ~DCC_MODE_SEL_MASK) | (val & DCC_MODE_SEL_MASK); - update_cursor(ramdac, svga); - break; + case REG_DCC: + ramdac->cursor_control = (ramdac->cursor_control & ~DCC_MODE_SEL_MASK) | (val & DCC_MODE_SEL_MASK); + update_cursor(ramdac, svga); + break; - case REG_CURSOR_DATA:ramdac->cursor_data[svga->dac_write + (((ramdac->cursor_control & CCR_ADDR_MASK) >> CCR_ADDR_SHIFT) << 8)] = val; - svga->dac_write = (svga->dac_write + 1) & 0xff; - if (!svga->dac_write) - ramdac->cursor_control = (ramdac->cursor_control & ~CCR_ADDR_MASK) | ((ramdac->cursor_control + (1 << CCR_ADDR_SHIFT)) & CCR_ADDR_MASK); - break; + case REG_CURSOR_DATA: + ramdac->cursor_data[svga->dac_write + (((ramdac->cursor_control & CCR_ADDR_MASK) >> CCR_ADDR_SHIFT) << 8)] = val; + svga->dac_write = (svga->dac_write + 1) & 0xff; + if (!svga->dac_write) + ramdac->cursor_control = (ramdac->cursor_control & ~CCR_ADDR_MASK) | + ((ramdac->cursor_control + (1 << CCR_ADDR_SHIFT)) & CCR_ADDR_MASK); + break; - case REG_CURSOR_XL:ramdac->cursor_x = val | (ramdac->cursor_x & 0xf00); - update_cursor(ramdac, svga); - break; - case REG_CURSOR_XH:ramdac->cursor_x = ((val & 0xf) << 8) | (ramdac->cursor_x & 0xff); - update_cursor(ramdac, svga); - break; - case REG_CURSOR_YL:ramdac->cursor_y = val | (ramdac->cursor_y & 0xf00); - update_cursor(ramdac, svga); - break; - case REG_CURSOR_YH:ramdac->cursor_y = ((val & 0xf) << 8) | (ramdac->cursor_y & 0xff); - update_cursor(ramdac, svga); - break; + case REG_CURSOR_XL: + ramdac->cursor_x = val | (ramdac->cursor_x & 0xf00); + update_cursor(ramdac, svga); + break; + case REG_CURSOR_XH: + ramdac->cursor_x = ((val & 0xf) << 8) | (ramdac->cursor_x & 0xff); + update_cursor(ramdac, svga); + break; + case REG_CURSOR_YL: + ramdac->cursor_y = val | (ramdac->cursor_y & 0xf00); + update_cursor(ramdac, svga); + break; + case REG_CURSOR_YH: + ramdac->cursor_y = ((val & 0xf) << 8) | (ramdac->cursor_y & 0xff); + update_cursor(ramdac, svga); + break; - case 0xa: - switch (ramdac->reg_idx) { - case IREG_ICC:ramdac->cursor_control = val; - update_cursor(ramdac, svga); - break; + case 0xa: + switch (ramdac->reg_idx) { + case IREG_ICC: + ramdac->cursor_control = val; + update_cursor(ramdac, svga); + break; - case 0x18: /*True color control*/ - /*bit 7 = pseudo-color mode - bit 6 = true-color mode - bit 4 = 24-bit colour mode - bit 3 = alternate packing on 24-bit formats*/ - if (val & 0x80) - svga->bpp = 8; - else - switch (val & 0x1f) { - case 0x04: /*ORGB 1555*/ - svga->bpp = 15; - break; - case 0x05: /*RGB 565*/ - svga->bpp = 16; - break; - case 0x06: /*ORGB 8888*/ - svga->bpp = 32; - break; - case 0x16: - case 0x1e: /*RGB 888*/ - svga->bpp = 24; - break; + case 0x18: /*True color control*/ + /*bit 7 = pseudo-color mode + bit 6 = true-color mode + bit 4 = 24-bit colour mode + bit 3 = alternate packing on 24-bit formats*/ + if (val & 0x80) + svga->bpp = 8; + else + switch (val & 0x1f) { + case 0x04: /*ORGB 1555*/ + svga->bpp = 15; + break; + case 0x05: /*RGB 565*/ + svga->bpp = 16; + break; + case 0x06: /*ORGB 8888*/ + svga->bpp = 32; + break; + case 0x16: + case 0x1e: /*RGB 888*/ + svga->bpp = 24; + break; - case 0x01: /*RGBO 4444 - not implemented*/ - case 0x03: /*RGB 664 - not implemented*/ - case 0x07: /*BGRO 8888 - not implemented*/ - case 0x17: /*BGR 888 - not implemented*/ - case 0x1f: /*BGR 888 - not implemented*/ - break; - } - svga_recalctimings(svga); -// pclog("bpp=%i\n", svga->bpp); - break; + case 0x01: /*RGBO 4444 - not implemented*/ + case 0x03: /*RGB 664 - not implemented*/ + case 0x07: /*BGRO 8888 - not implemented*/ + case 0x17: /*BGR 888 - not implemented*/ + case 0x1f: /*BGR 888 - not implemented*/ + break; + } + svga_recalctimings(svga); + // pclog("bpp=%i\n", svga->bpp); + break; - case REG_MSC:svga_set_ramdac_type(svga, (val & MSC_PAL_DEPTH) ? RAMDAC_8BIT : RAMDAC_6BIT); - break; + case REG_MSC: + svga_set_ramdac_type(svga, (val & MSC_PAL_DEPTH) ? RAMDAC_8BIT : RAMDAC_6BIT); + break; - case 0x2d: /*Pixel clock PLL data*/ - switch (ramdac->regs[0x2c] & 3) { - case 0:ramdac->pix.n = val; - break; - case 1:ramdac->pix.m = val; - break; - case 2:ramdac->pix.p = val; - break; - } - ramdac->regs[0x2c] = ((ramdac->regs[0x2c] + 1) & 3) | (ramdac->regs[0x2c] & 0xfc); - break; + case 0x2d: /*Pixel clock PLL data*/ + switch (ramdac->regs[0x2c] & 3) { + case 0: + ramdac->pix.n = val; + break; + case 1: + ramdac->pix.m = val; + break; + case 2: + ramdac->pix.p = val; + break; + } + ramdac->regs[0x2c] = ((ramdac->regs[0x2c] + 1) & 3) | (ramdac->regs[0x2c] & 0xfc); + break; - case 0x2e: /*Memory clock PLL data*/ - switch ((ramdac->regs[0x2c] >> 2) & 3) { - case 0:ramdac->mem.n = val; - break; - case 1:ramdac->mem.m = val; - break; - case 2:ramdac->mem.p = val; - break; - } - ramdac->regs[0x2c] = ((ramdac->regs[0x2c] + 4) & 0x0c) | (ramdac->regs[0x2c] & 0xf3); - break; + case 0x2e: /*Memory clock PLL data*/ + switch ((ramdac->regs[0x2c] >> 2) & 3) { + case 0: + ramdac->mem.n = val; + break; + case 1: + ramdac->mem.m = val; + break; + case 2: + ramdac->mem.p = val; + break; + } + ramdac->regs[0x2c] = ((ramdac->regs[0x2c] + 4) & 0x0c) | (ramdac->regs[0x2c] & 0xf3); + break; - case 0x2f: /*Loop clock PLL data*/ - switch ((ramdac->regs[0x2c] >> 4) & 3) { - case 0:ramdac->loop.n = val; - break; - case 1:ramdac->loop.m = val; - break; - case 2:ramdac->loop.p = val; - break; - } - ramdac->regs[0x2c] = ((ramdac->regs[0x2c] + 0x10) & 0x30) | (ramdac->regs[0x2c] & 0xcf); - break; - } + case 0x2f: /*Loop clock PLL data*/ + switch ((ramdac->regs[0x2c] >> 4) & 3) { + case 0: + ramdac->loop.n = val; + break; + case 1: + ramdac->loop.m = val; + break; + case 2: + ramdac->loop.p = val; + break; + } + ramdac->regs[0x2c] = ((ramdac->regs[0x2c] + 0x10) & 0x30) | (ramdac->regs[0x2c] & 0xcf); + break; + } - switch (ramdac->reg_idx) { - case 0x06: - case 0x0f: - case 0x18: - case 0x19: - case 0x1a: - case 0x1c: - case 0x1d: - case 0x1e: - 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 0x3e: - case 0xff:ramdac->regs[ramdac->reg_idx] = val; - break; - } -// pclog("RAMDAC[%02x]=%02x\n", ramdac->reg_idx, val); - break; - } + switch (ramdac->reg_idx) { + case 0x06: + case 0x0f: + case 0x18: + case 0x19: + case 0x1a: + case 0x1c: + case 0x1d: + case 0x1e: + 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 0x3e: + case 0xff: + ramdac->regs[ramdac->reg_idx] = val; + break; + } + // pclog("RAMDAC[%02x]=%02x\n", ramdac->reg_idx, val); + break; + } } uint8_t tvp3026_ramdac_in(uint16_t addr, tvp3026_ramdac_t *ramdac, svga_t *svga) { - uint8_t ret = 0xff; + uint8_t ret = 0xff; - switch (addr) { - case 0x0: - case 0x1:ret = svga_in(addr + 0x3c8, svga); - break; - case 0x2:ret = 0xff; - break; - case 0x3:ret = svga_in(addr + 0x3c4, svga); - break; + switch (addr) { + case 0x0: + case 0x1: + ret = svga_in(addr + 0x3c8, svga); + break; + case 0x2: + ret = 0xff; + break; + case 0x3: + ret = svga_in(addr + 0x3c4, svga); + break; - case 0x4:ret = ramdac->cursor_pal_write; - break; - case 0x5: - switch (ramdac->cursor_pal_pos) { - case 0:ramdac->cursor_pal_pos++; - return ramdac->cursor_pal[ramdac->cursor_pal_read].r; - case 1:ramdac->cursor_pal_pos++; - return ramdac->cursor_pal[ramdac->cursor_pal_read].g; - case 2:ramdac->cursor_pal_pos = 0; - ramdac->cursor_pal_read = (ramdac->cursor_pal_read + 1) & 3; - return ramdac->cursor_pal[(ramdac->cursor_pal_read - 1) & 3].b; - } - break; - case 0x7:ret = ramdac->cursor_pal_read; - break; + case 0x4: + ret = ramdac->cursor_pal_write; + break; + case 0x5: + switch (ramdac->cursor_pal_pos) { + case 0: + ramdac->cursor_pal_pos++; + return ramdac->cursor_pal[ramdac->cursor_pal_read].r; + case 1: + ramdac->cursor_pal_pos++; + return ramdac->cursor_pal[ramdac->cursor_pal_read].g; + case 2: + ramdac->cursor_pal_pos = 0; + ramdac->cursor_pal_read = (ramdac->cursor_pal_read + 1) & 3; + return ramdac->cursor_pal[(ramdac->cursor_pal_read - 1) & 3].b; + } + break; + case 0x7: + ret = ramdac->cursor_pal_read; + break; - case 0xa: - switch (ramdac->reg_idx) { - case 0x2d: /*Pixel clock PLL data*/ - switch (ramdac->regs[0x2c] & 3) { - case 0:ret = ramdac->pix.n; - break; - case 1:ret = ramdac->pix.m; - break; - case 2:ret = ramdac->pix.p; - break; - case 3:ret = 0x40; /*PLL locked to frequency*/ - break; - } - break; + case 0xa: + switch (ramdac->reg_idx) { + case 0x2d: /*Pixel clock PLL data*/ + switch (ramdac->regs[0x2c] & 3) { + case 0: + ret = ramdac->pix.n; + break; + case 1: + ret = ramdac->pix.m; + break; + case 2: + ret = ramdac->pix.p; + break; + case 3: + ret = 0x40; /*PLL locked to frequency*/ + break; + } + break; - case 0x2e: /*Memory clock PLL data*/ - switch ((ramdac->regs[0x2c] >> 2) & 3) { - case 0:ret = ramdac->mem.n; - break; - case 1:ret = ramdac->mem.m; - break; - case 2:ret = ramdac->mem.p; - break; - case 3:ret = 0x40; /*PLL locked to frequency*/ - break; - } - break; + case 0x2e: /*Memory clock PLL data*/ + switch ((ramdac->regs[0x2c] >> 2) & 3) { + case 0: + ret = ramdac->mem.n; + break; + case 1: + ret = ramdac->mem.m; + break; + case 2: + ret = ramdac->mem.p; + break; + case 3: + ret = 0x40; /*PLL locked to frequency*/ + break; + } + break; - case 0x2f: /*Loop clock PLL data*/ - switch ((ramdac->regs[0x2c] >> 4) & 3) { - case 0:ret = ramdac->loop.n; - break; - case 1:ret = ramdac->loop.m; - break; - case 2:ret = ramdac->loop.p; - break; - case 3:ret = 0x40; /*PLL locked to frequency*/ - break; - } - break; + case 0x2f: /*Loop clock PLL data*/ + switch ((ramdac->regs[0x2c] >> 4) & 3) { + case 0: + ret = ramdac->loop.n; + break; + case 1: + ret = ramdac->loop.m; + break; + case 2: + ret = ramdac->loop.p; + break; + case 3: + ret = 0x40; /*PLL locked to frequency*/ + break; + } + break; - default:ret = ramdac->regs[ramdac->reg_idx]; - break; - } -// pclog("Read RAMDAC[%02x]=%02x\n", ramdac->reg_idx, ret); - break; - } -// pclog("tvp3026_ramdac_in: addr=%04x ret=%02x\n", addr, ret); - return ret; + default: + ret = ramdac->regs[ramdac->reg_idx]; + break; + } + // pclog("Read RAMDAC[%02x]=%02x\n", ramdac->reg_idx, ret); + break; + } + // pclog("tvp3026_ramdac_in: addr=%04x ret=%02x\n", addr, ret); + return ret; } float tvp3026_getclock(tvp3026_ramdac_t *ramdac) { -/*Fvco = 8 x Fref x (65 - M) / (65 - N)*/ -/*Fpll = Fvco / 2^P*/ - int n = ramdac->pix.n & 0x3f; - int m = ramdac->pix.m & 0x3f; - int p = ramdac->pix.p & 0x03; - double f_vco = 8.0 * 14318184 * (double)(65 - m) / (double)(65 - n); - double f_pll = f_vco / (double)(1 << p); + /*Fvco = 8 x Fref x (65 - M) / (65 - N)*/ + /*Fpll = Fvco / 2^P*/ + int n = ramdac->pix.n & 0x3f; + int m = ramdac->pix.m & 0x3f; + int p = ramdac->pix.p & 0x03; + double f_vco = 8.0 * 14318184 * (double)(65 - m) / (double)(65 - n); + double f_pll = f_vco / (double)(1 << p); -// pclog("f_pll=%g %i\n", f_pll, (int)f_pll); - return f_pll; + // pclog("f_pll=%g %i\n", f_pll, (int)f_pll); + return f_pll; } void tvp3026_set_cursor_enable(tvp3026_ramdac_t *ramdac, svga_t *svga, int ena) { - ramdac->cursor_ena = ena; - if (ena) - update_cursor(ramdac, svga); + ramdac->cursor_ena = ena; + if (ena) + update_cursor(ramdac, svga); } void tvp3026_hwcursor_draw(tvp3026_ramdac_t *ramdac, svga_t *svga, int displine) { - int offset = (svga->hwcursor_latch.x + 32) - svga->hwcursor.xoff; - int x; - uint8_t *cursor_data = &ramdac->cursor_data[svga->hwcursor_latch.addr]; + int offset = (svga->hwcursor_latch.x + 32) - svga->hwcursor.xoff; + int x; + uint8_t *cursor_data = &ramdac->cursor_data[svga->hwcursor_latch.addr]; - for (x = 0; x < 64; x++) { - if ((offset + x) >= 32) { - int p0 = cursor_data[x >> 3] & (0x80 >> (x & 7)); - int p1 = cursor_data[(x >> 3) + 512] & (0x80 >> (x & 7)); + for (x = 0; x < 64; x++) { + if ((offset + x) >= 32) { + int p0 = cursor_data[x >> 3] & (0x80 >> (x & 7)); + int p1 = cursor_data[(x >> 3) + 512] & (0x80 >> (x & 7)); - switch (ramdac->cursor_mode) { - case DCC_MODE_SEL_3_COLOUR: - if (p0 || p1) { - int col = (p0 ? 1 : 0) | (p1 ? 2 : 0); - ((uint32_t *)buffer32->line[displine])[x + offset] = ramdac->cursor_pal_look[col]; - } - break; + switch (ramdac->cursor_mode) { + case DCC_MODE_SEL_3_COLOUR: + if (p0 || p1) { + int col = (p0 ? 1 : 0) | (p1 ? 2 : 0); + ((uint32_t *)buffer32->line[displine])[x + offset] = ramdac->cursor_pal_look[col]; + } + break; - case DCC_MODE_SEL_XGA: - if (!p1) - ((uint32_t *)buffer32->line[displine])[x + offset] = ramdac->cursor_pal_look[p0 ? 2 : 1]; - else if (p0) - ((uint32_t *)buffer32->line[displine])[x + offset] ^= 0xffffff; - break; + case DCC_MODE_SEL_XGA: + if (!p1) + ((uint32_t *)buffer32->line[displine])[x + offset] = ramdac->cursor_pal_look[p0 ? 2 : 1]; + else if (p0) + ((uint32_t *)buffer32->line[displine])[x + offset] ^= 0xffffff; + break; - case DCC_MODE_SEL_XWINDOWS: - if (p1) - ((uint32_t *)buffer32->line[displine])[x + offset] = ramdac->cursor_pal_look[p0 ? 2 : 1]; - break; - } - } - } - svga->hwcursor_latch.addr += 8; + case DCC_MODE_SEL_XWINDOWS: + if (p1) + ((uint32_t *)buffer32->line[displine])[x + offset] = ramdac->cursor_pal_look[p0 ? 2 : 1]; + break; + } + } + } + svga->hwcursor_latch.addr += 8; } void tvp3026_init(tvp3026_ramdac_t *ramdac) { - ramdac->regs[0x0f] = 0x06; /*Latch control*/ - ramdac->regs[0x18] = 0x80; /*True color control*/ - ramdac->regs[0x19] = 0x80; /*Multiplex control*/ - ramdac->regs[0x1a] = 0x80; /*Clock selection*/ - ramdac->regs[0x39] = 0x18; /*MCLK / Loop clock control*/ - ramdac->regs[0x3f] = 0x26; /*ID*/ + ramdac->regs[0x0f] = 0x06; /*Latch control*/ + ramdac->regs[0x18] = 0x80; /*True color control*/ + ramdac->regs[0x19] = 0x80; /*Multiplex control*/ + ramdac->regs[0x1a] = 0x80; /*Clock selection*/ + ramdac->regs[0x39] = 0x18; /*MCLK / Loop clock control*/ + ramdac->regs[0x3f] = 0x26; /*ID*/ } diff --git a/src/video/vid_unk_ramdac.c b/src/video/vid_unk_ramdac.c index 8b04fca8..6c135757 100644 --- a/src/video/vid_unk_ramdac.c +++ b/src/video/vid_unk_ramdac.c @@ -8,59 +8,65 @@ #include "vid_unk_ramdac.h" void unk_ramdac_out(uint16_t addr, uint8_t val, unk_ramdac_t *ramdac, svga_t *svga) { - //pclog("OUT RAMDAC %04X %02X\n",addr,val); - switch (addr) { - case 0x3C6: - if (ramdac->state == 4) { - ramdac->state = 0; - ramdac->ctrl = val; - switch ((val & 1) | ((val & 0xE0) >> 4)) { - case 0: - case 1: - case 2: - case 3:svga->bpp = 8; - break; - case 6: - case 7:svga->bpp = 24; - break; - case 8: - case 9: - case 0xA: - case 0xB:svga->bpp = 15; - break; - case 0xC: - case 0xD: - case 0xE: - case 0xF:svga->bpp = 16; - break; - } - svga_recalctimings(svga); - return; - } - ramdac->state = 0; - break; - case 0x3C7: - case 0x3C8: - case 0x3C9:ramdac->state = 0; - break; - } - svga_out(addr, val, svga); + // pclog("OUT RAMDAC %04X %02X\n",addr,val); + switch (addr) { + case 0x3C6: + if (ramdac->state == 4) { + ramdac->state = 0; + ramdac->ctrl = val; + switch ((val & 1) | ((val & 0xE0) >> 4)) { + case 0: + case 1: + case 2: + case 3: + svga->bpp = 8; + break; + case 6: + case 7: + svga->bpp = 24; + break; + case 8: + case 9: + case 0xA: + case 0xB: + svga->bpp = 15; + break; + case 0xC: + case 0xD: + case 0xE: + case 0xF: + svga->bpp = 16; + break; + } + svga_recalctimings(svga); + return; + } + ramdac->state = 0; + break; + case 0x3C7: + case 0x3C8: + case 0x3C9: + ramdac->state = 0; + break; + } + svga_out(addr, val, svga); } uint8_t unk_ramdac_in(uint16_t addr, unk_ramdac_t *ramdac, svga_t *svga) { - //pclog("IN RAMDAC %04X\n",addr); - switch (addr) { - case 0x3C6: - if (ramdac->state == 4) { - ramdac->state = 0; - return ramdac->ctrl; - } - ramdac->state++; - break; - case 0x3C7: - case 0x3C8: - case 0x3C9:ramdac->state = 0; - break; - } - return svga_in(addr, svga); + // pclog("IN RAMDAC %04X\n",addr); + switch (addr) { + case 0x3C6: + if (ramdac->state == 4) { + ramdac->state = 0; + return ramdac->ctrl; + } + ramdac->state++; + break; + case 0x3C7: + case 0x3C8: + case 0x3C9: + ramdac->state = 0; + break; + } + return svga_in(addr, svga); } diff --git a/src/video/vid_vga.c b/src/video/vid_vga.c index 29f51ed4..aef96375 100644 --- a/src/video/vid_vga.c +++ b/src/video/vid_vga.c @@ -12,183 +12,159 @@ svga_t *mb_vga = NULL; typedef struct vga_t { - svga_t svga; + svga_t svga; - rom_t bios_rom; + rom_t bios_rom; } vga_t; void vga_out(uint16_t addr, uint8_t val, void *p) { - vga_t *vga = (vga_t *)p; - svga_t *svga = &vga->svga; - uint8_t old; + vga_t *vga = (vga_t *)p; + svga_t *svga = &vga->svga; + uint8_t old; -// pclog("vga_out : %04X %02X %04X:%04X %02X %i\n", addr, val, CS,pc, ram[0x489], ins); + // pclog("vga_out : %04X %02X %04X:%04X %02X %i\n", addr, val, CS,pc, ram[0x489], ins); - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; - switch (addr) { - case 0x3D4:svga->crtcreg = val & 0x3f; - return; - case 0x3D5: - if (svga->crtcreg & 0x20) - return; - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) - return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); - old = svga->crtc[svga->crtcreg]; - svga->crtc[svga->crtcreg] = val; - if (old != val) { - if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - } - break; - } - svga_out(addr, val, svga); + switch (addr) { + case 0x3D4: + svga->crtcreg = val & 0x3f; + return; + case 0x3D5: + if (svga->crtcreg & 0x20) + return; + if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) + return; + if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) + val = (svga->crtc[7] & ~0x10) | (val & 0x10); + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; + if (old != val) { + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } + } + break; + } + svga_out(addr, val, svga); } uint8_t vga_in(uint16_t addr, void *p) { - vga_t *vga = (vga_t *)p; - svga_t *svga = &vga->svga; - uint8_t temp; + vga_t *vga = (vga_t *)p; + svga_t *svga = &vga->svga; + uint8_t temp; -// if (addr != 0x3da) pclog("vga_in : %04X ", addr); + // if (addr != 0x3da) pclog("vga_in : %04X ", addr); - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; - switch (addr) { - case 0x3D4:temp = svga->crtcreg; - break; - case 0x3D5: - if (svga->crtcreg & 0x20) - temp = 0xff; - else - temp = svga->crtc[svga->crtcreg]; - break; - default:temp = svga_in(addr, svga); - break; - } -// if (addr != 0x3da) pclog("%02X %04X:%04X\n", temp, CS,pc); - return temp; + switch (addr) { + case 0x3D4: + temp = svga->crtcreg; + break; + case 0x3D5: + if (svga->crtcreg & 0x20) + temp = 0xff; + else + temp = svga->crtc[svga->crtcreg]; + break; + default: + temp = svga_in(addr, svga); + break; + } + // if (addr != 0x3da) pclog("%02X %04X:%04X\n", temp, CS,pc); + return temp; } void vga_disable(void *p) { - vga_t *vga = (vga_t *)p; - svga_t *svga = &vga->svga; + vga_t *vga = (vga_t *)p; + svga_t *svga = &vga->svga; -// pclog("vga_disable\n"); - io_removehandler(0x03a0, 0x0040, vga_in, NULL, NULL, vga_out, NULL, NULL, vga); - mem_mapping_disable(&svga->mapping); + // pclog("vga_disable\n"); + io_removehandler(0x03a0, 0x0040, vga_in, NULL, NULL, vga_out, NULL, NULL, vga); + mem_mapping_disable(&svga->mapping); } void vga_enable(void *p) { - vga_t *vga = (vga_t *)p; - svga_t *svga = &vga->svga; + vga_t *vga = (vga_t *)p; + svga_t *svga = &vga->svga; -// pclog("vga_enable\n"); - io_sethandler(0x03c0, 0x0020, vga_in, NULL, NULL, vga_out, NULL, NULL, vga); - if (!(svga->miscout & 1)) - io_sethandler(0x03a0, 0x0020, vga_in, NULL, NULL, vga_out, NULL, NULL, vga); + // pclog("vga_enable\n"); + io_sethandler(0x03c0, 0x0020, vga_in, NULL, NULL, vga_out, NULL, NULL, vga); + if (!(svga->miscout & 1)) + io_sethandler(0x03a0, 0x0020, vga_in, NULL, NULL, vga_out, NULL, NULL, vga); - mem_mapping_enable(&svga->mapping); + mem_mapping_enable(&svga->mapping); } void *vga_init() { - vga_t *vga = malloc(sizeof(vga_t)); - memset(vga, 0, sizeof(vga_t)); + vga_t *vga = malloc(sizeof(vga_t)); + memset(vga, 0, sizeof(vga_t)); - rom_init(&vga->bios_rom, "ibm_vga.bin", 0xc0000, 0x8000, 0x7fff, 0x2000, MEM_MAPPING_EXTERNAL); + rom_init(&vga->bios_rom, "ibm_vga.bin", 0xc0000, 0x8000, 0x7fff, 0x2000, MEM_MAPPING_EXTERNAL); - svga_init(&vga->svga, vga, 1 << 18, /*256kb*/ - NULL, - vga_in, vga_out, - NULL, - NULL); + svga_init(&vga->svga, vga, 1 << 18, /*256kb*/ + NULL, vga_in, vga_out, NULL, NULL); - io_sethandler(0x03c0, 0x0020, vga_in, NULL, NULL, vga_out, NULL, NULL, vga); + io_sethandler(0x03c0, 0x0020, vga_in, NULL, NULL, vga_out, NULL, NULL, vga); - vga->svga.bpp = 8; - vga->svga.miscout = 1; + vga->svga.bpp = 8; + vga->svga.miscout = 1; - return vga; + return vga; } /*PS/1 uses a standard VGA controller, but with no option ROM*/ void *ps1vga_init() { - vga_t *vga = malloc(sizeof(vga_t)); - memset(vga, 0, sizeof(vga_t)); + vga_t *vga = malloc(sizeof(vga_t)); + memset(vga, 0, sizeof(vga_t)); - svga_init(&vga->svga, vga, 1 << 18, /*256kb*/ - NULL, - vga_in, vga_out, - NULL, - NULL); + svga_init(&vga->svga, vga, 1 << 18, /*256kb*/ + NULL, vga_in, vga_out, NULL, NULL); - io_sethandler(0x03c0, 0x0020, vga_in, NULL, NULL, vga_out, NULL, NULL, vga); + io_sethandler(0x03c0, 0x0020, vga_in, NULL, NULL, vga_out, NULL, NULL, vga); - vga->svga.bpp = 8; - vga->svga.miscout = 1; + vga->svga.bpp = 8; + vga->svga.miscout = 1; - mb_vga = &vga->svga; + mb_vga = &vga->svga; - return vga; + return vga; } -static int vga_available() { - return rom_present("ibm_vga.bin"); -} +static int vga_available() { return rom_present("ibm_vga.bin"); } void vga_close(void *p) { - vga_t *vga = (vga_t *)p; + vga_t *vga = (vga_t *)p; - mb_vga = NULL; + mb_vga = NULL; - svga_close(&vga->svga); + svga_close(&vga->svga); - free(vga); + free(vga); } void vga_speed_changed(void *p) { - vga_t *vga = (vga_t *)p; + vga_t *vga = (vga_t *)p; - svga_recalctimings(&vga->svga); + svga_recalctimings(&vga->svga); } void vga_force_redraw(void *p) { - vga_t *vga = (vga_t *)p; + vga_t *vga = (vga_t *)p; - vga->svga.fullchange = changeframecount; + vga->svga.fullchange = changeframecount; } void vga_add_status_info(char *s, int max_len, void *p) { - vga_t *vga = (vga_t *)p; + vga_t *vga = (vga_t *)p; - svga_add_status_info(s, max_len, &vga->svga); + svga_add_status_info(s, max_len, &vga->svga); } -device_t vga_device = - { - "VGA", - 0, - vga_init, - vga_close, - vga_available, - vga_speed_changed, - vga_force_redraw, - vga_add_status_info - }; -device_t ps1vga_device = - { - "PS/1 VGA", - 0, - ps1vga_init, - vga_close, - vga_available, - vga_speed_changed, - vga_force_redraw, - vga_add_status_info - }; +device_t vga_device = {"VGA", 0, vga_init, vga_close, vga_available, vga_speed_changed, vga_force_redraw, vga_add_status_info}; +device_t ps1vga_device = {"PS/1 VGA", 0, ps1vga_init, vga_close, vga_available, vga_speed_changed, vga_force_redraw, + vga_add_status_info}; diff --git a/src/video/vid_voodoo.c b/src/video/vid_voodoo.c index bcf9ef1f..43e67e25 100644 --- a/src/video/vid_voodoo.c +++ b/src/video/vid_voodoo.c @@ -28,1276 +28,1287 @@ int tris = 0; static uint64_t status_time = 0; void voodoo_recalc(voodoo_t *voodoo) { - uint32_t buffer_offset = ((voodoo->fbiInit2 >> 11) & 511) * 4096; + uint32_t buffer_offset = ((voodoo->fbiInit2 >> 11) & 511) * 4096; - if (voodoo->type >= VOODOO_BANSHEE) - return; + if (voodoo->type >= VOODOO_BANSHEE) + return; - voodoo->params.front_offset = voodoo->disp_buffer * buffer_offset; - voodoo->back_offset = voodoo->draw_buffer * buffer_offset; + voodoo->params.front_offset = voodoo->disp_buffer * buffer_offset; + voodoo->back_offset = voodoo->draw_buffer * buffer_offset; - voodoo->buffer_cutoff = TRIPLE_BUFFER ? (buffer_offset * 4) : (buffer_offset * 3); - if (TRIPLE_BUFFER) - voodoo->params.aux_offset = buffer_offset * 3; - else - voodoo->params.aux_offset = buffer_offset * 2; + voodoo->buffer_cutoff = TRIPLE_BUFFER ? (buffer_offset * 4) : (buffer_offset * 3); + if (TRIPLE_BUFFER) + voodoo->params.aux_offset = buffer_offset * 3; + else + voodoo->params.aux_offset = buffer_offset * 2; - switch (voodoo->lfbMode & LFB_WRITE_MASK) { - case LFB_WRITE_FRONT:voodoo->fb_write_offset = voodoo->params.front_offset; - voodoo->fb_write_buffer = voodoo->disp_buffer; - break; - case LFB_WRITE_BACK:voodoo->fb_write_offset = voodoo->back_offset; - voodoo->fb_write_buffer = voodoo->draw_buffer; - break; + switch (voodoo->lfbMode & LFB_WRITE_MASK) { + case LFB_WRITE_FRONT: + voodoo->fb_write_offset = voodoo->params.front_offset; + voodoo->fb_write_buffer = voodoo->disp_buffer; + break; + case LFB_WRITE_BACK: + voodoo->fb_write_offset = voodoo->back_offset; + voodoo->fb_write_buffer = voodoo->draw_buffer; + break; - default: - /*BreakNeck sets invalid LFB write buffer select*/ - voodoo->fb_write_offset = voodoo->params.front_offset; - break; - } + default: + /*BreakNeck sets invalid LFB write buffer select*/ + voodoo->fb_write_offset = voodoo->params.front_offset; + break; + } - switch (voodoo->lfbMode & LFB_READ_MASK) { - case LFB_READ_FRONT:voodoo->fb_read_offset = voodoo->params.front_offset; - break; - case LFB_READ_BACK:voodoo->fb_read_offset = voodoo->back_offset; - break; - case LFB_READ_AUX:voodoo->fb_read_offset = voodoo->params.aux_offset; - break; + switch (voodoo->lfbMode & LFB_READ_MASK) { + case LFB_READ_FRONT: + voodoo->fb_read_offset = voodoo->params.front_offset; + break; + case LFB_READ_BACK: + voodoo->fb_read_offset = voodoo->back_offset; + break; + case LFB_READ_AUX: + voodoo->fb_read_offset = voodoo->params.aux_offset; + break; - default:fatal("voodoo_recalc : unknown lfb source\n"); - } + default: + fatal("voodoo_recalc : unknown lfb source\n"); + } - switch (voodoo->params.fbzMode & FBZ_DRAW_MASK) { - case FBZ_DRAW_FRONT:voodoo->params.draw_offset = voodoo->params.front_offset; - voodoo->fb_draw_buffer = voodoo->disp_buffer; - break; - case FBZ_DRAW_BACK:voodoo->params.draw_offset = voodoo->back_offset; - voodoo->fb_draw_buffer = voodoo->draw_buffer; - break; + switch (voodoo->params.fbzMode & FBZ_DRAW_MASK) { + case FBZ_DRAW_FRONT: + voodoo->params.draw_offset = voodoo->params.front_offset; + voodoo->fb_draw_buffer = voodoo->disp_buffer; + break; + case FBZ_DRAW_BACK: + voodoo->params.draw_offset = voodoo->back_offset; + voodoo->fb_draw_buffer = voodoo->draw_buffer; + break; - default:fatal("voodoo_recalc : unknown draw buffer\n"); - } + default: + fatal("voodoo_recalc : unknown draw buffer\n"); + } - voodoo->block_width = ((voodoo->fbiInit1 >> 4) & 15) * 2; - if (voodoo->fbiInit6 & (1 << 30)) - voodoo->block_width += 1; - if (voodoo->fbiInit1 & (1 << 24)) - voodoo->block_width += 32; - voodoo->row_width = voodoo->block_width * 32 * 2; - voodoo->params.row_width = voodoo->row_width; - voodoo->aux_row_width = voodoo->row_width; - voodoo->params.aux_row_width = voodoo->aux_row_width; + voodoo->block_width = ((voodoo->fbiInit1 >> 4) & 15) * 2; + if (voodoo->fbiInit6 & (1 << 30)) + voodoo->block_width += 1; + if (voodoo->fbiInit1 & (1 << 24)) + voodoo->block_width += 32; + voodoo->row_width = voodoo->block_width * 32 * 2; + voodoo->params.row_width = voodoo->row_width; + voodoo->aux_row_width = voodoo->row_width; + voodoo->params.aux_row_width = voodoo->aux_row_width; -/* pclog("voodoo_recalc : front_offset %08X back_offset %08X aux_offset %08X draw_offset %08x\n", voodoo->params.front_offset, voodoo->back_offset, voodoo->params.aux_offset, voodoo->params.draw_offset); - pclog(" fb_read_offset %08X fb_write_offset %08X row_width %i %08x %08x\n", voodoo->fb_read_offset, voodoo->fb_write_offset, voodoo->row_width, voodoo->lfbMode, voodoo->params.fbzMode);*/ + /* pclog("voodoo_recalc : front_offset %08X back_offset %08X aux_offset %08X draw_offset %08x\n", + voodoo->params.front_offset, voodoo->back_offset, voodoo->params.aux_offset, voodoo->params.draw_offset); pclog(" + fb_read_offset %08X fb_write_offset %08X row_width %i %08x %08x\n", voodoo->fb_read_offset, voodoo->fb_write_offset, + voodoo->row_width, voodoo->lfbMode, voodoo->params.fbzMode);*/ } static uint16_t voodoo_readw(uint32_t addr, void *p) { - voodoo_t *voodoo = (voodoo_t *)p; + voodoo_t *voodoo = (voodoo_t *)p; - addr &= 0xffffff; + addr &= 0xffffff; - cycles -= voodoo->read_time; + cycles -= voodoo->read_time; - if ((addr & 0xc00000) == 0x400000) /*Framebuffer*/ - { - if (SLI_ENABLED) { - voodoo_set_t *set = voodoo->set; - int y = (addr >> 11) & 0x3ff; + if ((addr & 0xc00000) == 0x400000) /*Framebuffer*/ + { + if (SLI_ENABLED) { + voodoo_set_t *set = voodoo->set; + int y = (addr >> 11) & 0x3ff; - if (y & 1) - voodoo = set->voodoos[1]; - else - voodoo = set->voodoos[0]; - } + if (y & 1) + voodoo = set->voodoos[1]; + else + voodoo = set->voodoos[0]; + } - voodoo->flush = 1; - while (!FIFO_EMPTY) { - voodoo_wake_fifo_thread_now(voodoo); - thread_wait_event(voodoo->fifo_not_full_event, 1); - } - voodoo_wait_for_render_thread_idle(voodoo); - voodoo->flush = 0; + voodoo->flush = 1; + while (!FIFO_EMPTY) { + voodoo_wake_fifo_thread_now(voodoo); + thread_wait_event(voodoo->fifo_not_full_event, 1); + } + voodoo_wait_for_render_thread_idle(voodoo); + voodoo->flush = 0; - return voodoo_fb_readw(addr, voodoo); - } + return voodoo_fb_readw(addr, voodoo); + } - return 0xffff; + return 0xffff; } static uint32_t voodoo_readl(uint32_t addr, void *p) { - voodoo_t *voodoo = (voodoo_t *)p; - uint32_t temp; - int fifo_size; - voodoo->rd_count++; - addr &= 0xffffff; + voodoo_t *voodoo = (voodoo_t *)p; + uint32_t temp; + int fifo_size; + voodoo->rd_count++; + addr &= 0xffffff; - cycles -= voodoo->read_time; + cycles -= voodoo->read_time; - if (addr & 0x800000) /*Texture*/ - { - } else if (addr & 0x400000) /*Framebuffer*/ - { - if (SLI_ENABLED) { - voodoo_set_t *set = voodoo->set; - int y = (addr >> 11) & 0x3ff; + if (addr & 0x800000) /*Texture*/ + { + } else if (addr & 0x400000) /*Framebuffer*/ + { + if (SLI_ENABLED) { + voodoo_set_t *set = voodoo->set; + int y = (addr >> 11) & 0x3ff; - if (y & 1) - voodoo = set->voodoos[1]; - else - voodoo = set->voodoos[0]; - } + if (y & 1) + voodoo = set->voodoos[1]; + else + voodoo = set->voodoos[0]; + } - voodoo->flush = 1; - while (!FIFO_EMPTY) { - voodoo_wake_fifo_thread_now(voodoo); - thread_wait_event(voodoo->fifo_not_full_event, 1); - } - voodoo_wait_for_render_thread_idle(voodoo); - voodoo->flush = 0; + voodoo->flush = 1; + while (!FIFO_EMPTY) { + voodoo_wake_fifo_thread_now(voodoo); + thread_wait_event(voodoo->fifo_not_full_event, 1); + } + voodoo_wait_for_render_thread_idle(voodoo); + voodoo->flush = 0; - temp = voodoo_fb_readl(addr, voodoo); - } else - switch (addr & 0x3fc) { - case SST_status: { - int fifo_entries = FIFO_ENTRIES; - int swap_count = voodoo->swap_count; - int written = voodoo->cmd_written + voodoo->cmd_written_fifo; - int busy = (written - voodoo->cmd_read) || (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr); + temp = voodoo_fb_readl(addr, voodoo); + } else + switch (addr & 0x3fc) { + case SST_status: { + int fifo_entries = FIFO_ENTRIES; + int swap_count = voodoo->swap_count; + int written = voodoo->cmd_written + voodoo->cmd_written_fifo; + int busy = (written - voodoo->cmd_read) || (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr); - if (SLI_ENABLED && voodoo->type != VOODOO_2) { - voodoo_t *voodoo_other = (voodoo == voodoo->set->voodoos[0]) ? voodoo->set->voodoos[1] : voodoo->set->voodoos[0]; - int other_written = voodoo_other->cmd_written + voodoo_other->cmd_written_fifo; + if (SLI_ENABLED && voodoo->type != VOODOO_2) { + voodoo_t *voodoo_other = + (voodoo == voodoo->set->voodoos[0]) ? voodoo->set->voodoos[1] : voodoo->set->voodoos[0]; + int other_written = voodoo_other->cmd_written + voodoo_other->cmd_written_fifo; - if (voodoo_other->swap_count > swap_count) - swap_count = voodoo_other->swap_count; - if ((voodoo_other->fifo_write_idx - voodoo_other->fifo_read_idx) > fifo_entries) - fifo_entries = voodoo_other->fifo_write_idx - voodoo_other->fifo_read_idx; - if ((other_written - voodoo_other->cmd_read) || - (voodoo_other->cmdfifo_depth_rd != voodoo_other->cmdfifo_depth_wr)) - busy = 1; - if (!voodoo_other->voodoo_busy) - voodoo_wake_fifo_thread(voodoo_other); - } + if (voodoo_other->swap_count > swap_count) + swap_count = voodoo_other->swap_count; + if ((voodoo_other->fifo_write_idx - voodoo_other->fifo_read_idx) > fifo_entries) + fifo_entries = voodoo_other->fifo_write_idx - voodoo_other->fifo_read_idx; + if ((other_written - voodoo_other->cmd_read) || + (voodoo_other->cmdfifo_depth_rd != voodoo_other->cmdfifo_depth_wr)) + busy = 1; + if (!voodoo_other->voodoo_busy) + voodoo_wake_fifo_thread(voodoo_other); + } - fifo_size = 0xffff - fifo_entries; - temp = fifo_size << 12; - if (fifo_size < 0x40) - temp |= fifo_size; - else - temp |= 0x3f; - if (swap_count < 7) - temp |= (swap_count << 28); - else - temp |= (7 << 28); - if (!voodoo->v_retrace) - temp |= 0x40; + fifo_size = 0xffff - fifo_entries; + temp = fifo_size << 12; + if (fifo_size < 0x40) + temp |= fifo_size; + else + temp |= 0x3f; + if (swap_count < 7) + temp |= (swap_count << 28); + else + temp |= (7 << 28); + if (!voodoo->v_retrace) + temp |= 0x40; - if (busy) - temp |= 0x380; /*Busy*/ + if (busy) + temp |= 0x380; /*Busy*/ - if (!voodoo->voodoo_busy) - voodoo_wake_fifo_thread(voodoo); - } - break; + if (!voodoo->voodoo_busy) + voodoo_wake_fifo_thread(voodoo); + } break; - case SST_fbzColorPath:voodoo_flush(voodoo); - temp = voodoo->params.fbzColorPath; - break; - case SST_fogMode:voodoo_flush(voodoo); - temp = voodoo->params.fogMode; - break; - case SST_alphaMode:voodoo_flush(voodoo); - temp = voodoo->params.alphaMode; - break; - case SST_fbzMode:voodoo_flush(voodoo); - temp = voodoo->params.fbzMode; - break; - case SST_lfbMode:voodoo_flush(voodoo); - temp = voodoo->lfbMode; - break; - case SST_clipLeftRight:voodoo_flush(voodoo); - temp = voodoo->params.clipRight | (voodoo->params.clipLeft << 16); - break; - case SST_clipLowYHighY:voodoo_flush(voodoo); - temp = voodoo->params.clipHighY | (voodoo->params.clipLowY << 16); - break; + case SST_fbzColorPath: + voodoo_flush(voodoo); + temp = voodoo->params.fbzColorPath; + break; + case SST_fogMode: + voodoo_flush(voodoo); + temp = voodoo->params.fogMode; + break; + case SST_alphaMode: + voodoo_flush(voodoo); + temp = voodoo->params.alphaMode; + break; + case SST_fbzMode: + voodoo_flush(voodoo); + temp = voodoo->params.fbzMode; + break; + case SST_lfbMode: + voodoo_flush(voodoo); + temp = voodoo->lfbMode; + break; + case SST_clipLeftRight: + voodoo_flush(voodoo); + temp = voodoo->params.clipRight | (voodoo->params.clipLeft << 16); + break; + case SST_clipLowYHighY: + voodoo_flush(voodoo); + temp = voodoo->params.clipHighY | (voodoo->params.clipLowY << 16); + break; - case SST_stipple:voodoo_flush(voodoo); - temp = voodoo->params.stipple; - break; - case SST_color0:voodoo_flush(voodoo); - temp = voodoo->params.color0; - break; - case SST_color1:voodoo_flush(voodoo); - temp = voodoo->params.color1; - break; + case SST_stipple: + voodoo_flush(voodoo); + temp = voodoo->params.stipple; + break; + case SST_color0: + voodoo_flush(voodoo); + temp = voodoo->params.color0; + break; + case SST_color1: + voodoo_flush(voodoo); + temp = voodoo->params.color1; + break; - case SST_fbiPixelsIn:temp = voodoo->fbiPixelsIn & 0xffffff; - break; - case SST_fbiChromaFail:temp = voodoo->fbiChromaFail & 0xffffff; - break; - case SST_fbiZFuncFail:temp = voodoo->fbiZFuncFail & 0xffffff; - break; - case SST_fbiAFuncFail:temp = voodoo->fbiAFuncFail & 0xffffff; - break; - case SST_fbiPixelsOut:temp = voodoo->fbiPixelsOut & 0xffffff; - break; + case SST_fbiPixelsIn: + temp = voodoo->fbiPixelsIn & 0xffffff; + break; + case SST_fbiChromaFail: + temp = voodoo->fbiChromaFail & 0xffffff; + break; + case SST_fbiZFuncFail: + temp = voodoo->fbiZFuncFail & 0xffffff; + break; + case SST_fbiAFuncFail: + temp = voodoo->fbiAFuncFail & 0xffffff; + break; + case SST_fbiPixelsOut: + temp = voodoo->fbiPixelsOut & 0xffffff; + break; - case SST_fbiInit4:temp = voodoo->fbiInit4; - break; - case SST_fbiInit0:temp = voodoo->fbiInit0; - break; - case SST_fbiInit1:temp = voodoo->fbiInit1; - break; - case SST_fbiInit2: - if (voodoo->initEnable & 0x04) - temp = voodoo->dac_readdata; - else - temp = voodoo->fbiInit2; - break; - case SST_fbiInit3:temp = voodoo->fbiInit3 | (1 << 10) | (2 << 8); - break; + case SST_fbiInit4: + temp = voodoo->fbiInit4; + break; + case SST_fbiInit0: + temp = voodoo->fbiInit0; + break; + case SST_fbiInit1: + temp = voodoo->fbiInit1; + break; + case SST_fbiInit2: + if (voodoo->initEnable & 0x04) + temp = voodoo->dac_readdata; + else + temp = voodoo->fbiInit2; + break; + case SST_fbiInit3: + temp = voodoo->fbiInit3 | (1 << 10) | (2 << 8); + break; - case SST_vRetrace:temp = voodoo->line & 0x1fff; - break; - case SST_hvRetrace: { - uint32_t line_time = (uint32_t)(voodoo->line_time >> 32); - uint32_t diff = (timer_get_ts_int(&voodoo->timer) > (tsc & 0xffffffff)) ? (timer_get_ts_int(&voodoo->timer) - (tsc & 0xffffffff)) : 0; - uint32_t pre_div = diff * voodoo->h_total; - uint32_t post_div = pre_div / line_time; - uint32_t h_pos = (voodoo->h_total - 1) - post_div; + case SST_vRetrace: + temp = voodoo->line & 0x1fff; + break; + case SST_hvRetrace: { + uint32_t line_time = (uint32_t)(voodoo->line_time >> 32); + uint32_t diff = (timer_get_ts_int(&voodoo->timer) > (tsc & 0xffffffff)) + ? (timer_get_ts_int(&voodoo->timer) - (tsc & 0xffffffff)) + : 0; + uint32_t pre_div = diff * voodoo->h_total; + uint32_t post_div = pre_div / line_time; + uint32_t h_pos = (voodoo->h_total - 1) - post_div; - if (h_pos >= voodoo->h_total) - h_pos = 0; + if (h_pos >= voodoo->h_total) + h_pos = 0; - temp = voodoo->line & 0x1fff; - temp |= (h_pos << 16); - } - break; + temp = voodoo->line & 0x1fff; + temp |= (h_pos << 16); + } break; - case SST_fbiInit5:temp = voodoo->fbiInit5 & ~0x1ff; - break; - case SST_fbiInit6:temp = voodoo->fbiInit6; - break; - case SST_fbiInit7:temp = voodoo->fbiInit7 & ~0xff; - break; + case SST_fbiInit5: + temp = voodoo->fbiInit5 & ~0x1ff; + break; + case SST_fbiInit6: + temp = voodoo->fbiInit6; + break; + case SST_fbiInit7: + temp = voodoo->fbiInit7 & ~0xff; + break; - case SST_cmdFifoBaseAddr:temp = voodoo->cmdfifo_base >> 12; - temp |= (voodoo->cmdfifo_end >> 12) << 16; - break; + case SST_cmdFifoBaseAddr: + temp = voodoo->cmdfifo_base >> 12; + temp |= (voodoo->cmdfifo_end >> 12) << 16; + break; - case SST_cmdFifoRdPtr:temp = voodoo->cmdfifo_rp; - break; - case SST_cmdFifoAMin:temp = voodoo->cmdfifo_amin; - break; - case SST_cmdFifoAMax:temp = voodoo->cmdfifo_amax; - break; - case SST_cmdFifoDepth:temp = voodoo->cmdfifo_depth_wr - voodoo->cmdfifo_depth_rd; - break; + case SST_cmdFifoRdPtr: + temp = voodoo->cmdfifo_rp; + break; + case SST_cmdFifoAMin: + temp = voodoo->cmdfifo_amin; + break; + case SST_cmdFifoAMax: + temp = voodoo->cmdfifo_amax; + break; + case SST_cmdFifoDepth: + temp = voodoo->cmdfifo_depth_wr - voodoo->cmdfifo_depth_rd; + break; - default:pclog("voodoo_readl : bad addr %08X\n", addr); - temp = 0xffffffff; - } + default: + pclog("voodoo_readl : bad addr %08X\n", addr); + temp = 0xffffffff; + } - return temp; + return temp; } static void voodoo_writew(uint32_t addr, uint16_t val, void *p) { - voodoo_t *voodoo = (voodoo_t *)p; - voodoo->wr_count++; - addr &= 0xffffff; + voodoo_t *voodoo = (voodoo_t *)p; + voodoo->wr_count++; + addr &= 0xffffff; - cycles -= voodoo->write_time; + cycles -= voodoo->write_time; - if ((addr & 0xc00000) == 0x400000) /*Framebuffer*/ - voodoo_queue_command(voodoo, addr | FIFO_WRITEW_FB, val); + if ((addr & 0xc00000) == 0x400000) /*Framebuffer*/ + voodoo_queue_command(voodoo, addr | FIFO_WRITEW_FB, val); } static void voodoo_writel(uint32_t addr, uint32_t val, void *p) { - voodoo_t *voodoo = (voodoo_t *)p; + voodoo_t *voodoo = (voodoo_t *)p; - voodoo->wr_count++; + voodoo->wr_count++; - addr &= 0xffffff; + addr &= 0xffffff; - if (addr == voodoo->last_write_addr + 4) - cycles -= voodoo->burst_time; - else - cycles -= voodoo->write_time; - voodoo->last_write_addr = addr; + if (addr == voodoo->last_write_addr + 4) + cycles -= voodoo->burst_time; + else + cycles -= voodoo->write_time; + voodoo->last_write_addr = addr; - if (addr & 0x800000) /*Texture*/ - { - voodoo->tex_count++; - voodoo_queue_command(voodoo, addr | FIFO_WRITEL_TEX, val); - } else if (addr & 0x400000) /*Framebuffer*/ - { - voodoo_queue_command(voodoo, addr | FIFO_WRITEL_FB, val); - } else if ((addr & 0x200000) && (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE)) { -// pclog("Write CMDFIFO %08x(%08x) %08x %08x\n", addr, voodoo->cmdfifo_base + (addr & 0x3fffc), val, (voodoo->cmdfifo_base + (addr & 0x3fffc)) & voodoo->fb_mask); - *(uint32_t *)&voodoo->fb_mem[(voodoo->cmdfifo_base + (addr & 0x3fffc)) & voodoo->fb_mask] = val; - voodoo->cmdfifo_depth_wr++; - if ((voodoo->cmdfifo_depth_wr - voodoo->cmdfifo_depth_rd) < 20) - voodoo_wake_fifo_thread(voodoo); - } else - switch (addr & 0x3fc) { - case SST_intrCtrl:fatal("intrCtrl write %08x\n", val); - break; + if (addr & 0x800000) /*Texture*/ + { + voodoo->tex_count++; + voodoo_queue_command(voodoo, addr | FIFO_WRITEL_TEX, val); + } else if (addr & 0x400000) /*Framebuffer*/ + { + voodoo_queue_command(voodoo, addr | FIFO_WRITEL_FB, val); + } else if ((addr & 0x200000) && (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE)) { + // pclog("Write CMDFIFO %08x(%08x) %08x %08x\n", addr, voodoo->cmdfifo_base + (addr & 0x3fffc), + // val, (voodoo->cmdfifo_base + (addr & 0x3fffc)) & voodoo->fb_mask); + *(uint32_t *)&voodoo->fb_mem[(voodoo->cmdfifo_base + (addr & 0x3fffc)) & voodoo->fb_mask] = val; + voodoo->cmdfifo_depth_wr++; + if ((voodoo->cmdfifo_depth_wr - voodoo->cmdfifo_depth_rd) < 20) + voodoo_wake_fifo_thread(voodoo); + } else + switch (addr & 0x3fc) { + case SST_intrCtrl: + fatal("intrCtrl write %08x\n", val); + break; - case SST_userIntrCMD:fatal("userIntrCMD write %08x\n", val); - break; + case SST_userIntrCMD: + fatal("userIntrCMD write %08x\n", val); + break; - case SST_swapbufferCMD:voodoo->cmd_written++; - thread_lock_mutex(voodoo->swap_mutex); - voodoo->swap_count++; - thread_unlock_mutex(voodoo->swap_mutex); - if (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE) - return; - voodoo_queue_command(voodoo, addr | FIFO_WRITEL_REG, val); - if (!voodoo->voodoo_busy) - voodoo_wake_fifo_threads(voodoo->set, voodoo); - break; - case SST_triangleCMD: - if (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE) - return; - voodoo->cmd_written++; - voodoo_queue_command(voodoo, addr | FIFO_WRITEL_REG, val); - if (!voodoo->voodoo_busy) - voodoo_wake_fifo_threads(voodoo->set, voodoo); - break; - case SST_ftriangleCMD: - if (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE) - return; - voodoo->cmd_written++; - voodoo_queue_command(voodoo, addr | FIFO_WRITEL_REG, val); - if (!voodoo->voodoo_busy) - voodoo_wake_fifo_threads(voodoo->set, voodoo); - break; - case SST_fastfillCMD: - if (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE) - return; - voodoo->cmd_written++; - voodoo_queue_command(voodoo, addr | FIFO_WRITEL_REG, val); - if (!voodoo->voodoo_busy) - voodoo_wake_fifo_threads(voodoo->set, voodoo); - break; - case SST_nopCMD: - if (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE) - return; - voodoo->cmd_written++; - voodoo_queue_command(voodoo, addr | FIFO_WRITEL_REG, val); - if (!voodoo->voodoo_busy) - voodoo_wake_fifo_threads(voodoo->set, voodoo); - break; + case SST_swapbufferCMD: + voodoo->cmd_written++; + thread_lock_mutex(voodoo->swap_mutex); + voodoo->swap_count++; + thread_unlock_mutex(voodoo->swap_mutex); + if (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE) + return; + voodoo_queue_command(voodoo, addr | FIFO_WRITEL_REG, val); + if (!voodoo->voodoo_busy) + voodoo_wake_fifo_threads(voodoo->set, voodoo); + break; + case SST_triangleCMD: + if (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE) + return; + voodoo->cmd_written++; + voodoo_queue_command(voodoo, addr | FIFO_WRITEL_REG, val); + if (!voodoo->voodoo_busy) + voodoo_wake_fifo_threads(voodoo->set, voodoo); + break; + case SST_ftriangleCMD: + if (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE) + return; + voodoo->cmd_written++; + voodoo_queue_command(voodoo, addr | FIFO_WRITEL_REG, val); + if (!voodoo->voodoo_busy) + voodoo_wake_fifo_threads(voodoo->set, voodoo); + break; + case SST_fastfillCMD: + if (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE) + return; + voodoo->cmd_written++; + voodoo_queue_command(voodoo, addr | FIFO_WRITEL_REG, val); + if (!voodoo->voodoo_busy) + voodoo_wake_fifo_threads(voodoo->set, voodoo); + break; + case SST_nopCMD: + if (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE) + return; + voodoo->cmd_written++; + voodoo_queue_command(voodoo, addr | FIFO_WRITEL_REG, val); + if (!voodoo->voodoo_busy) + voodoo_wake_fifo_threads(voodoo->set, voodoo); + break; - case SST_fbiInit4: - if (voodoo->initEnable & 0x01) { - voodoo->fbiInit4 = val; - voodoo->read_time = pci_nonburst_time + pci_burst_time * ((voodoo->fbiInit4 & 1) ? 2 : 1); -// pclog("fbiInit4 write %08x - read_time=%i\n", val, voodoo->read_time); - } - break; - case SST_backPorch:voodoo->backPorch = val; - break; - case SST_videoDimensions:voodoo->videoDimensions = val; - voodoo->h_disp = (val & 0xfff) + 1; - voodoo->v_disp = (val >> 16) & 0xfff; - break; - case SST_fbiInit0: - if (voodoo->initEnable & 0x01) { - voodoo->fbiInit0 = val; - if (voodoo->set->nr_cards == 2) - svga_set_override(voodoo->svga, (voodoo->set->voodoos[0]->fbiInit0 | voodoo->set->voodoos[1]->fbiInit0) & 1); - else - svga_set_override(voodoo->svga, val & 1); - if (val & FBIINIT0_GRAPHICS_RESET) { - /*Reset display/draw buffer selection. This may not actually - happen here on a real Voodoo*/ - voodoo->disp_buffer = 0; - voodoo->draw_buffer = 1; - voodoo_recalc(voodoo); - voodoo->front_offset = voodoo->params.front_offset; - } - } - break; - case SST_fbiInit1: - if (voodoo->initEnable & 0x01) { - if ((voodoo->fbiInit1 & FBIINIT1_VIDEO_RESET) && !(val & FBIINIT1_VIDEO_RESET)) { - voodoo->line = 0; - thread_lock_mutex(voodoo->swap_mutex); - voodoo->swap_count = 0; - thread_unlock_mutex(voodoo->swap_mutex); - voodoo->retrace_count = 0; - } - voodoo->fbiInit1 = (val & ~5) | (voodoo->fbiInit1 & 5); - voodoo->write_time = pci_nonburst_time + pci_burst_time * ((voodoo->fbiInit1 & 2) ? 1 : 0); - voodoo->burst_time = pci_burst_time * ((voodoo->fbiInit1 & 2) ? 2 : 1); -// pclog("fbiInit1 write %08x - write_time=%i burst_time=%i\n", val, voodoo->write_time, voodoo->burst_time); - } - break; - case SST_fbiInit2: - if (voodoo->initEnable & 0x01) { - voodoo->fbiInit2 = val; - voodoo_recalc(voodoo); - } - break; - case SST_fbiInit3: - if (voodoo->initEnable & 0x01) - voodoo->fbiInit3 = val; - break; + case SST_fbiInit4: + if (voodoo->initEnable & 0x01) { + voodoo->fbiInit4 = val; + voodoo->read_time = pci_nonburst_time + pci_burst_time * ((voodoo->fbiInit4 & 1) ? 2 : 1); + // pclog("fbiInit4 write %08x - read_time=%i\n", val, voodoo->read_time); + } + break; + case SST_backPorch: + voodoo->backPorch = val; + break; + case SST_videoDimensions: + voodoo->videoDimensions = val; + voodoo->h_disp = (val & 0xfff) + 1; + voodoo->v_disp = (val >> 16) & 0xfff; + break; + case SST_fbiInit0: + if (voodoo->initEnable & 0x01) { + voodoo->fbiInit0 = val; + if (voodoo->set->nr_cards == 2) + svga_set_override( + voodoo->svga, + (voodoo->set->voodoos[0]->fbiInit0 | voodoo->set->voodoos[1]->fbiInit0) & 1); + else + svga_set_override(voodoo->svga, val & 1); + if (val & FBIINIT0_GRAPHICS_RESET) { + /*Reset display/draw buffer selection. This may not actually + happen here on a real Voodoo*/ + voodoo->disp_buffer = 0; + voodoo->draw_buffer = 1; + voodoo_recalc(voodoo); + voodoo->front_offset = voodoo->params.front_offset; + } + } + break; + case SST_fbiInit1: + if (voodoo->initEnable & 0x01) { + if ((voodoo->fbiInit1 & FBIINIT1_VIDEO_RESET) && !(val & FBIINIT1_VIDEO_RESET)) { + voodoo->line = 0; + thread_lock_mutex(voodoo->swap_mutex); + voodoo->swap_count = 0; + thread_unlock_mutex(voodoo->swap_mutex); + voodoo->retrace_count = 0; + } + voodoo->fbiInit1 = (val & ~5) | (voodoo->fbiInit1 & 5); + voodoo->write_time = pci_nonburst_time + pci_burst_time * ((voodoo->fbiInit1 & 2) ? 1 : 0); + voodoo->burst_time = pci_burst_time * ((voodoo->fbiInit1 & 2) ? 2 : 1); + // pclog("fbiInit1 write %08x - write_time=%i burst_time=%i\n", val, + // voodoo->write_time, voodoo->burst_time); + } + break; + case SST_fbiInit2: + if (voodoo->initEnable & 0x01) { + voodoo->fbiInit2 = val; + voodoo_recalc(voodoo); + } + break; + case SST_fbiInit3: + if (voodoo->initEnable & 0x01) + voodoo->fbiInit3 = val; + break; - case SST_hSync:voodoo->hSync = val; - voodoo->h_total = (val & 0xffff) + (val >> 16); - voodoo_pixelclock_update(voodoo); - break; - case SST_vSync:voodoo->vSync = val; - voodoo->v_total = (val & 0xffff) + (val >> 16); - break; + case SST_hSync: + voodoo->hSync = val; + voodoo->h_total = (val & 0xffff) + (val >> 16); + voodoo_pixelclock_update(voodoo); + break; + case SST_vSync: + voodoo->vSync = val; + voodoo->v_total = (val & 0xffff) + (val >> 16); + break; - case SST_clutData:voodoo->clutData[(val >> 24) & 0x3f].b = val & 0xff; - voodoo->clutData[(val >> 24) & 0x3f].g = (val >> 8) & 0xff; - voodoo->clutData[(val >> 24) & 0x3f].r = (val >> 16) & 0xff; - if (val & 0x20000000) { - voodoo->clutData[(val >> 24) & 0x3f].b = 255; - voodoo->clutData[(val >> 24) & 0x3f].g = 255; - voodoo->clutData[(val >> 24) & 0x3f].r = 255; - } - voodoo->clutData_dirty = 1; - break; + case SST_clutData: + voodoo->clutData[(val >> 24) & 0x3f].b = val & 0xff; + voodoo->clutData[(val >> 24) & 0x3f].g = (val >> 8) & 0xff; + voodoo->clutData[(val >> 24) & 0x3f].r = (val >> 16) & 0xff; + if (val & 0x20000000) { + voodoo->clutData[(val >> 24) & 0x3f].b = 255; + voodoo->clutData[(val >> 24) & 0x3f].g = 255; + voodoo->clutData[(val >> 24) & 0x3f].r = 255; + } + voodoo->clutData_dirty = 1; + break; - case SST_dacData:voodoo->dac_reg = (val >> 8) & 7; - voodoo->dac_readdata = 0xff; - if (val & 0x800) { -// pclog(" dacData read %i %02X\n", voodoo->dac_reg, voodoo->dac_data[7]); - if (voodoo->dac_reg == 5) { - switch (voodoo->dac_data[7]) { - case 0x01:voodoo->dac_readdata = 0x55; - break; - case 0x07:voodoo->dac_readdata = 0x71; - break; - case 0x0b:voodoo->dac_readdata = 0x79; - break; - } - } else - voodoo->dac_readdata = voodoo->dac_data[voodoo->dac_readdata & 7]; - } else { - if (voodoo->dac_reg == 5) { - if (!voodoo->dac_reg_ff) - voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf] = (voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf] & 0xff00) | val; - else - voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf] = (voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf] & 0xff) | (val << 8); -// pclog("Write PLL reg %x %04x\n", voodoo->dac_data[4] & 0xf, voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf]); - voodoo->dac_reg_ff = !voodoo->dac_reg_ff; - if (!voodoo->dac_reg_ff) - voodoo->dac_data[4]++; + case SST_dacData: + voodoo->dac_reg = (val >> 8) & 7; + voodoo->dac_readdata = 0xff; + if (val & 0x800) { + // pclog(" dacData read %i %02X\n", voodoo->dac_reg, voodoo->dac_data[7]); + if (voodoo->dac_reg == 5) { + switch (voodoo->dac_data[7]) { + case 0x01: + voodoo->dac_readdata = 0x55; + break; + case 0x07: + voodoo->dac_readdata = 0x71; + break; + case 0x0b: + voodoo->dac_readdata = 0x79; + break; + } + } else + voodoo->dac_readdata = voodoo->dac_data[voodoo->dac_readdata & 7]; + } else { + if (voodoo->dac_reg == 5) { + if (!voodoo->dac_reg_ff) + voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf] = + (voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf] & 0xff00) | val; + else + voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf] = + (voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf] & 0xff) | (val << 8); + // pclog("Write PLL reg %x %04x\n", voodoo->dac_data[4] & + // 0xf, voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf]); + voodoo->dac_reg_ff = !voodoo->dac_reg_ff; + if (!voodoo->dac_reg_ff) + voodoo->dac_data[4]++; - } else { - voodoo->dac_data[voodoo->dac_reg] = val & 0xff; - voodoo->dac_reg_ff = 0; - } - voodoo_pixelclock_update(voodoo); - } - break; + } else { + voodoo->dac_data[voodoo->dac_reg] = val & 0xff; + voodoo->dac_reg_ff = 0; + } + voodoo_pixelclock_update(voodoo); + } + break; - case SST_scrFilter: - if (voodoo->initEnable & 0x01) { - voodoo->scrfilterEnabled = 1; - voodoo->scrfilterThreshold = val; /* update the threshold values and generate a new lookup table if necessary */ + case SST_scrFilter: + if (voodoo->initEnable & 0x01) { + voodoo->scrfilterEnabled = 1; + voodoo->scrfilterThreshold = + val; /* update the threshold values and generate a new lookup table if necessary */ - if (val < 1) - voodoo->scrfilterEnabled = 0; - voodoo_threshold_check(voodoo); - pclog("Voodoo Filter: %06x\n", val); - } - break; + if (val < 1) + voodoo->scrfilterEnabled = 0; + voodoo_threshold_check(voodoo); + pclog("Voodoo Filter: %06x\n", val); + } + break; - case SST_fbiInit5: - if (voodoo->initEnable & 0x01) - voodoo->fbiInit5 = (val & ~0x41e6) | (voodoo->fbiInit5 & 0x41e6); - break; - case SST_fbiInit6: - if (voodoo->initEnable & 0x01) - voodoo->fbiInit6 = val; - break; - case SST_fbiInit7: - if (voodoo->initEnable & 0x01) { - voodoo->fbiInit7 = val; - voodoo->cmdfifo_enabled = val & 0x100; - } - break; + case SST_fbiInit5: + if (voodoo->initEnable & 0x01) + voodoo->fbiInit5 = (val & ~0x41e6) | (voodoo->fbiInit5 & 0x41e6); + break; + case SST_fbiInit6: + if (voodoo->initEnable & 0x01) + voodoo->fbiInit6 = val; + break; + case SST_fbiInit7: + if (voodoo->initEnable & 0x01) { + voodoo->fbiInit7 = val; + voodoo->cmdfifo_enabled = val & 0x100; + } + break; - case SST_cmdFifoBaseAddr:voodoo->cmdfifo_base = (val & 0x3ff) << 12; - voodoo->cmdfifo_end = ((val >> 16) & 0x3ff) << 12; -// pclog("CMDFIFO base=%08x end=%08x\n", voodoo->cmdfifo_base, voodoo->cmdfifo_end); - break; + case SST_cmdFifoBaseAddr: + voodoo->cmdfifo_base = (val & 0x3ff) << 12; + voodoo->cmdfifo_end = ((val >> 16) & 0x3ff) << 12; + // pclog("CMDFIFO base=%08x end=%08x\n", voodoo->cmdfifo_base, voodoo->cmdfifo_end); + break; - case SST_cmdFifoRdPtr:voodoo->cmdfifo_rp = val; - break; - case SST_cmdFifoAMin:voodoo->cmdfifo_amin = val; - break; - case SST_cmdFifoAMax:voodoo->cmdfifo_amax = val; - break; - case SST_cmdFifoDepth:voodoo->cmdfifo_depth_rd = 0; - voodoo->cmdfifo_depth_wr = val & 0xffff; - break; + case SST_cmdFifoRdPtr: + voodoo->cmdfifo_rp = val; + break; + case SST_cmdFifoAMin: + voodoo->cmdfifo_amin = val; + break; + case SST_cmdFifoAMax: + voodoo->cmdfifo_amax = val; + break; + case SST_cmdFifoDepth: + voodoo->cmdfifo_depth_rd = 0; + voodoo->cmdfifo_depth_wr = val & 0xffff; + break; - default: - if (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE) { - pclog("Unknown register write in CMDFIFO mode %08x %08x\n", addr, val); - } else { - voodoo_queue_command(voodoo, addr | FIFO_WRITEL_REG, val); - } - break; - } + default: + if (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE) { + pclog("Unknown register write in CMDFIFO mode %08x %08x\n", addr, val); + } else { + voodoo_queue_command(voodoo, addr | FIFO_WRITEL_REG, val); + } + break; + } } static uint16_t voodoo_snoop_readw(uint32_t addr, void *p) { - voodoo_set_t *set = (voodoo_set_t *)p; + voodoo_set_t *set = (voodoo_set_t *)p; - return voodoo_readw(addr, set->voodoos[0]); + return voodoo_readw(addr, set->voodoos[0]); } static uint32_t voodoo_snoop_readl(uint32_t addr, void *p) { - voodoo_set_t *set = (voodoo_set_t *)p; + voodoo_set_t *set = (voodoo_set_t *)p; - return voodoo_readl(addr, set->voodoos[0]); + return voodoo_readl(addr, set->voodoos[0]); } static void voodoo_snoop_writew(uint32_t addr, uint16_t val, void *p) { - voodoo_set_t *set = (voodoo_set_t *)p; + voodoo_set_t *set = (voodoo_set_t *)p; - voodoo_writew(addr, val, set->voodoos[0]); - voodoo_writew(addr, val, set->voodoos[1]); + voodoo_writew(addr, val, set->voodoos[0]); + voodoo_writew(addr, val, set->voodoos[1]); } static void voodoo_snoop_writel(uint32_t addr, uint32_t val, void *p) { - voodoo_set_t *set = (voodoo_set_t *)p; + voodoo_set_t *set = (voodoo_set_t *)p; - voodoo_writel(addr, val, set->voodoos[0]); - voodoo_writel(addr, val, set->voodoos[1]); + voodoo_writel(addr, val, set->voodoos[0]); + voodoo_writel(addr, val, set->voodoos[1]); } static void voodoo_recalcmapping(voodoo_set_t *set) { - if (set->nr_cards == 2) { - if (set->voodoos[0]->pci_enable && set->voodoos[0]->memBaseAddr) { - if (set->voodoos[0]->type == VOODOO_2 && set->voodoos[1]->initEnable & (1 << 23)) { - pclog("voodoo_recalcmapping (pri) with snoop : memBaseAddr %08X\n", set->voodoos[0]->memBaseAddr); - mem_mapping_disable(&set->voodoos[0]->mapping); - mem_mapping_set_addr(&set->snoop_mapping, set->voodoos[0]->memBaseAddr, 0x01000000); - } else if (set->voodoos[1]->pci_enable && (set->voodoos[0]->memBaseAddr == set->voodoos[1]->memBaseAddr)) { - pclog("voodoo_recalcmapping (pri) (sec) same addr : memBaseAddr %08X\n", set->voodoos[0]->memBaseAddr); - mem_mapping_disable(&set->voodoos[0]->mapping); - mem_mapping_disable(&set->voodoos[1]->mapping); - mem_mapping_set_addr(&set->snoop_mapping, set->voodoos[0]->memBaseAddr, 0x01000000); - return; - } else { - pclog("voodoo_recalcmapping (pri) : memBaseAddr %08X\n", set->voodoos[0]->memBaseAddr); - mem_mapping_disable(&set->snoop_mapping); - mem_mapping_set_addr(&set->voodoos[0]->mapping, set->voodoos[0]->memBaseAddr, 0x01000000); - } - } else { - pclog("voodoo_recalcmapping (pri) : disabled\n"); - mem_mapping_disable(&set->voodoos[0]->mapping); - } + if (set->nr_cards == 2) { + if (set->voodoos[0]->pci_enable && set->voodoos[0]->memBaseAddr) { + if (set->voodoos[0]->type == VOODOO_2 && set->voodoos[1]->initEnable & (1 << 23)) { + pclog("voodoo_recalcmapping (pri) with snoop : memBaseAddr %08X\n", set->voodoos[0]->memBaseAddr); + mem_mapping_disable(&set->voodoos[0]->mapping); + mem_mapping_set_addr(&set->snoop_mapping, set->voodoos[0]->memBaseAddr, 0x01000000); + } else if (set->voodoos[1]->pci_enable && + (set->voodoos[0]->memBaseAddr == set->voodoos[1]->memBaseAddr)) { + pclog("voodoo_recalcmapping (pri) (sec) same addr : memBaseAddr %08X\n", + set->voodoos[0]->memBaseAddr); + mem_mapping_disable(&set->voodoos[0]->mapping); + mem_mapping_disable(&set->voodoos[1]->mapping); + mem_mapping_set_addr(&set->snoop_mapping, set->voodoos[0]->memBaseAddr, 0x01000000); + return; + } else { + pclog("voodoo_recalcmapping (pri) : memBaseAddr %08X\n", set->voodoos[0]->memBaseAddr); + mem_mapping_disable(&set->snoop_mapping); + mem_mapping_set_addr(&set->voodoos[0]->mapping, set->voodoos[0]->memBaseAddr, 0x01000000); + } + } else { + pclog("voodoo_recalcmapping (pri) : disabled\n"); + mem_mapping_disable(&set->voodoos[0]->mapping); + } - if (set->voodoos[1]->pci_enable && set->voodoos[1]->memBaseAddr) { - pclog("voodoo_recalcmapping (sec) : memBaseAddr %08X\n", set->voodoos[1]->memBaseAddr); - mem_mapping_set_addr(&set->voodoos[1]->mapping, set->voodoos[1]->memBaseAddr, 0x01000000); - } else { - pclog("voodoo_recalcmapping (sec) : disabled\n"); - mem_mapping_disable(&set->voodoos[1]->mapping); - } - } else { - voodoo_t *voodoo = set->voodoos[0]; + if (set->voodoos[1]->pci_enable && set->voodoos[1]->memBaseAddr) { + pclog("voodoo_recalcmapping (sec) : memBaseAddr %08X\n", set->voodoos[1]->memBaseAddr); + mem_mapping_set_addr(&set->voodoos[1]->mapping, set->voodoos[1]->memBaseAddr, 0x01000000); + } else { + pclog("voodoo_recalcmapping (sec) : disabled\n"); + mem_mapping_disable(&set->voodoos[1]->mapping); + } + } else { + voodoo_t *voodoo = set->voodoos[0]; - if (voodoo->pci_enable && voodoo->memBaseAddr) { - pclog("voodoo_recalcmapping : memBaseAddr %08X\n", voodoo->memBaseAddr); - mem_mapping_set_addr(&voodoo->mapping, voodoo->memBaseAddr, 0x01000000); - } else { - pclog("voodoo_recalcmapping : disabled\n"); - mem_mapping_disable(&voodoo->mapping); - } - } + if (voodoo->pci_enable && voodoo->memBaseAddr) { + pclog("voodoo_recalcmapping : memBaseAddr %08X\n", voodoo->memBaseAddr); + mem_mapping_set_addr(&voodoo->mapping, voodoo->memBaseAddr, 0x01000000); + } else { + pclog("voodoo_recalcmapping : disabled\n"); + mem_mapping_disable(&voodoo->mapping); + } + } } uint8_t voodoo_pci_read(int func, int addr, void *p) { - voodoo_t *voodoo = (voodoo_t *)p; + voodoo_t *voodoo = (voodoo_t *)p; - if (func) - return 0; + if (func) + return 0; -// pclog("Voodoo PCI read %08X PC=%08x\n", addr, cpu_state.pc); + // pclog("Voodoo PCI read %08X PC=%08x\n", addr, cpu_state.pc); - switch (addr) { - case 0x00:return 0x1a; /*3dfx*/ - case 0x01:return 0x12; + switch (addr) { + case 0x00: + return 0x1a; /*3dfx*/ + case 0x01: + return 0x12; - case 0x02: - if (voodoo->type == VOODOO_2) - return 0x02; /*Voodoo 2*/ - else - return 0x01; /*SST-1 (Voodoo Graphics)*/ - case 0x03:return 0x00; + case 0x02: + if (voodoo->type == VOODOO_2) + return 0x02; /*Voodoo 2*/ + else + return 0x01; /*SST-1 (Voodoo Graphics)*/ + case 0x03: + return 0x00; - case 0x04:return voodoo->pci_enable ? 0x02 : 0x00; /*Respond to memory accesses*/ + case 0x04: + return voodoo->pci_enable ? 0x02 : 0x00; /*Respond to memory accesses*/ - case 0x08:return 2; /*Revision ID*/ - case 0x09:return 0; /*Programming interface*/ - case 0x0a:return 0; - case 0x0b:return 0x04; + case 0x08: + return 2; /*Revision ID*/ + case 0x09: + return 0; /*Programming interface*/ + case 0x0a: + return 0; + case 0x0b: + return 0x04; - case 0x10:return 0x00; /*memBaseAddr*/ - case 0x11:return 0x00; - case 0x12:return 0x00; - case 0x13:return voodoo->memBaseAddr >> 24; + case 0x10: + return 0x00; /*memBaseAddr*/ + case 0x11: + return 0x00; + case 0x12: + return 0x00; + case 0x13: + return voodoo->memBaseAddr >> 24; - case 0x40:return voodoo->initEnable & 0xff; - case 0x41: - if (voodoo->type == VOODOO_2) - return 0x50 | ((voodoo->initEnable >> 8) & 0x0f); - return (voodoo->initEnable >> 8) & 0x0f; - case 0x42:return (voodoo->initEnable >> 16) & 0xff; - case 0x43:return (voodoo->initEnable >> 24) & 0xff; - } - return 0; + case 0x40: + return voodoo->initEnable & 0xff; + case 0x41: + if (voodoo->type == VOODOO_2) + return 0x50 | ((voodoo->initEnable >> 8) & 0x0f); + return (voodoo->initEnable >> 8) & 0x0f; + case 0x42: + return (voodoo->initEnable >> 16) & 0xff; + case 0x43: + return (voodoo->initEnable >> 24) & 0xff; + } + return 0; } void voodoo_pci_write(int func, int addr, uint8_t val, void *p) { - voodoo_t *voodoo = (voodoo_t *)p; + voodoo_t *voodoo = (voodoo_t *)p; - if (func) - return; + if (func) + return; -// pclog("Voodoo PCI write %04X %02X PC=%08x\n", addr, val, cpu_state.pc); + // pclog("Voodoo PCI write %04X %02X PC=%08x\n", addr, val, cpu_state.pc); - switch (addr) { - case 0x04:voodoo->pci_enable = val & 2; - voodoo_recalcmapping(voodoo->set); - break; + switch (addr) { + case 0x04: + voodoo->pci_enable = val & 2; + voodoo_recalcmapping(voodoo->set); + break; - case 0x13:voodoo->memBaseAddr = val << 24; - voodoo_recalcmapping(voodoo->set); - break; + case 0x13: + voodoo->memBaseAddr = val << 24; + voodoo_recalcmapping(voodoo->set); + break; - case 0x40:voodoo->initEnable = (voodoo->initEnable & ~0x000000ff) | val; - break; - case 0x41:voodoo->initEnable = (voodoo->initEnable & ~0x0000ff00) | (val << 8); - break; - case 0x42:voodoo->initEnable = (voodoo->initEnable & ~0x00ff0000) | (val << 16); - voodoo_recalcmapping(voodoo->set); - break; - case 0x43:voodoo->initEnable = (voodoo->initEnable & ~0xff000000) | (val << 24); - voodoo_recalcmapping(voodoo->set); - break; - } + case 0x40: + voodoo->initEnable = (voodoo->initEnable & ~0x000000ff) | val; + break; + case 0x41: + voodoo->initEnable = (voodoo->initEnable & ~0x0000ff00) | (val << 8); + break; + case 0x42: + voodoo->initEnable = (voodoo->initEnable & ~0x00ff0000) | (val << 16); + voodoo_recalcmapping(voodoo->set); + break; + case 0x43: + voodoo->initEnable = (voodoo->initEnable & ~0xff000000) | (val << 24); + voodoo_recalcmapping(voodoo->set); + break; + } } static void voodoo_add_status_info(char *s, int max_len, void *p) { - voodoo_set_t *voodoo_set = (voodoo_set_t *)p; - voodoo_t *voodoo = voodoo_set->voodoos[0]; - voodoo_t *voodoo_slave = voodoo_set->voodoos[1]; - char temps[512], temps2[256]; - int pixel_count_current[4]; - int pixel_count_total; - int texel_count_current[4]; - int texel_count_total; - int render_time[4]; - uint64_t new_time = timer_read(); - uint64_t status_diff = new_time - status_time; - status_time = new_time; - int c; + voodoo_set_t *voodoo_set = (voodoo_set_t *)p; + voodoo_t *voodoo = voodoo_set->voodoos[0]; + voodoo_t *voodoo_slave = voodoo_set->voodoos[1]; + char temps[512], temps2[256]; + int pixel_count_current[4]; + int pixel_count_total; + int texel_count_current[4]; + int texel_count_total; + int render_time[4]; + uint64_t new_time = timer_read(); + uint64_t status_diff = new_time - status_time; + status_time = new_time; + int c; - if (!status_diff) - status_diff = 1; + if (!status_diff) + status_diff = 1; - for (c = 0; c < 4; c++) { - pixel_count_current[c] = voodoo->pixel_count[c]; - texel_count_current[c] = voodoo->texel_count[c]; - render_time[c] = voodoo->render_time[c]; - } - if (voodoo_set->nr_cards == 2) { - for (c = 0; c < 4; c++) { - pixel_count_current[c] += voodoo_slave->pixel_count[c]; - texel_count_current[c] += voodoo_slave->texel_count[c]; - render_time[c] = (render_time[c] + voodoo_slave->render_time[c]) / 2; - } - } - pixel_count_total = (pixel_count_current[0] + pixel_count_current[1] + pixel_count_current[2] + pixel_count_current[3]) - - (voodoo->pixel_count_old[0] + voodoo->pixel_count_old[1] + voodoo->pixel_count_old[2] + voodoo->pixel_count_old[3]); - texel_count_total = (texel_count_current[0] + texel_count_current[1] + texel_count_current[2] + texel_count_current[3]) - - (voodoo->texel_count_old[0] + voodoo->texel_count_old[1] + voodoo->texel_count_old[2] + voodoo->texel_count_old[3]); - sprintf(temps, "%f Mpixels/sec (%f)\n%f Mtexels/sec (%f)\n%f ktris/sec\n%f%% CPU (%f%% real)\n%d frames/sec (%i)\n%f%% CPU (%f%% real)\n"/*%d reads/sec\n%d write/sec\n%d tex/sec\n*/, - (double)pixel_count_total / 1000000.0, - ((double)pixel_count_total / 1000000.0) / ((double)render_time[0] / status_diff), - (double)texel_count_total / 1000000.0, - ((double)texel_count_total / 1000000.0) / ((double)render_time[0] / status_diff), - (double)voodoo->tri_count / 1000.0, ((double)voodoo->time * 100.0) / timer_freq, ((double)voodoo->time * 100.0) / status_diff, voodoo->frame_count, voodoo_recomp, - ((double)voodoo->render_time[0] * 100.0) / timer_freq, ((double)voodoo->render_time[0] * 100.0) / status_diff); - if (voodoo->render_threads >= 2) { - sprintf(temps2, "%f%% CPU (%f%% real)\n", - ((double)voodoo->render_time[1] * 100.0) / timer_freq, ((double)voodoo->render_time[1] * 100.0) / status_diff); - strncat(temps, temps2, sizeof(temps) - 1); - } - if (voodoo->render_threads == 4) { - sprintf(temps2, "%f%% CPU (%f%% real)\n%f%% CPU (%f%% real)\n", - ((double)voodoo->render_time[2] * 100.0) / timer_freq, ((double)voodoo->render_time[2] * 100.0) / status_diff, - ((double)voodoo->render_time[3] * 100.0) / timer_freq, ((double)voodoo->render_time[3] * 100.0) / status_diff); - strncat(temps, temps2, sizeof(temps) - 1); - } - if (voodoo_set->nr_cards == 2) { - sprintf(temps2, "%f%% CPU (%f%% real)\n", - ((double)voodoo_slave->render_time[0] * 100.0) / timer_freq, ((double)voodoo_slave->render_time[0] * 100.0) / status_diff); - strncat(temps, temps2, sizeof(temps) - 1); + for (c = 0; c < 4; c++) { + pixel_count_current[c] = voodoo->pixel_count[c]; + texel_count_current[c] = voodoo->texel_count[c]; + render_time[c] = voodoo->render_time[c]; + } + if (voodoo_set->nr_cards == 2) { + for (c = 0; c < 4; c++) { + pixel_count_current[c] += voodoo_slave->pixel_count[c]; + texel_count_current[c] += voodoo_slave->texel_count[c]; + render_time[c] = (render_time[c] + voodoo_slave->render_time[c]) / 2; + } + } + pixel_count_total = (pixel_count_current[0] + pixel_count_current[1] + pixel_count_current[2] + pixel_count_current[3]) - + (voodoo->pixel_count_old[0] + voodoo->pixel_count_old[1] + voodoo->pixel_count_old[2] + + voodoo->pixel_count_old[3]); + texel_count_total = (texel_count_current[0] + texel_count_current[1] + texel_count_current[2] + texel_count_current[3]) - + (voodoo->texel_count_old[0] + voodoo->texel_count_old[1] + voodoo->texel_count_old[2] + + voodoo->texel_count_old[3]); + sprintf(temps, + "%f Mpixels/sec (%f)\n%f Mtexels/sec (%f)\n%f ktris/sec\n%f%% CPU (%f%% real)\n%d frames/sec (%i)\n%f%% CPU " + "(%f%% real)\n" /*%d reads/sec\n%d write/sec\n%d tex/sec\n*/, + (double)pixel_count_total / 1000000.0, + ((double)pixel_count_total / 1000000.0) / ((double)render_time[0] / status_diff), + (double)texel_count_total / 1000000.0, + ((double)texel_count_total / 1000000.0) / ((double)render_time[0] / status_diff), + (double)voodoo->tri_count / 1000.0, ((double)voodoo->time * 100.0) / timer_freq, + ((double)voodoo->time * 100.0) / status_diff, voodoo->frame_count, voodoo_recomp, + ((double)voodoo->render_time[0] * 100.0) / timer_freq, ((double)voodoo->render_time[0] * 100.0) / status_diff); + if (voodoo->render_threads >= 2) { + sprintf(temps2, "%f%% CPU (%f%% real)\n", ((double)voodoo->render_time[1] * 100.0) / timer_freq, + ((double)voodoo->render_time[1] * 100.0) / status_diff); + strncat(temps, temps2, sizeof(temps) - 1); + } + if (voodoo->render_threads == 4) { + sprintf(temps2, "%f%% CPU (%f%% real)\n%f%% CPU (%f%% real)\n", + ((double)voodoo->render_time[2] * 100.0) / timer_freq, + ((double)voodoo->render_time[2] * 100.0) / status_diff, + ((double)voodoo->render_time[3] * 100.0) / timer_freq, + ((double)voodoo->render_time[3] * 100.0) / status_diff); + strncat(temps, temps2, sizeof(temps) - 1); + } + if (voodoo_set->nr_cards == 2) { + sprintf(temps2, "%f%% CPU (%f%% real)\n", ((double)voodoo_slave->render_time[0] * 100.0) / timer_freq, + ((double)voodoo_slave->render_time[0] * 100.0) / status_diff); + strncat(temps, temps2, sizeof(temps) - 1); - if (voodoo_slave->render_threads >= 2) { - sprintf(temps2, "%f%% CPU (%f%% real)\n", - ((double)voodoo_slave->render_time[1] * 100.0) / timer_freq, ((double)voodoo_slave->render_time[1] * 100.0) / status_diff); - strncat(temps, temps2, sizeof(temps) - 1); - } - if (voodoo_slave->render_threads == 4) { - sprintf(temps2, "%f%% CPU (%f%% real)\n%f%% CPU (%f%% real)\n", - ((double)voodoo_slave->render_time[2] * 100.0) / timer_freq, ((double)voodoo_slave->render_time[2] * 100.0) / status_diff, - ((double)voodoo_slave->render_time[3] * 100.0) / timer_freq, ((double)voodoo_slave->render_time[3] * 100.0) / status_diff); - strncat(temps, temps2, sizeof(temps) - 1); - } - } - strncat(s, temps, max_len); + if (voodoo_slave->render_threads >= 2) { + sprintf(temps2, "%f%% CPU (%f%% real)\n", ((double)voodoo_slave->render_time[1] * 100.0) / timer_freq, + ((double)voodoo_slave->render_time[1] * 100.0) / status_diff); + strncat(temps, temps2, sizeof(temps) - 1); + } + if (voodoo_slave->render_threads == 4) { + sprintf(temps2, "%f%% CPU (%f%% real)\n%f%% CPU (%f%% real)\n", + ((double)voodoo_slave->render_time[2] * 100.0) / timer_freq, + ((double)voodoo_slave->render_time[2] * 100.0) / status_diff, + ((double)voodoo_slave->render_time[3] * 100.0) / timer_freq, + ((double)voodoo_slave->render_time[3] * 100.0) / status_diff); + strncat(temps, temps2, sizeof(temps) - 1); + } + } + strncat(s, temps, max_len); - for (c = 0; c < 4; c++) { - voodoo->pixel_count_old[c] = pixel_count_current[c]; - voodoo->texel_count_old[c] = texel_count_current[c]; - voodoo->render_time[c] = 0; - } - voodoo->tri_count = voodoo->frame_count = 0; - voodoo->rd_count = voodoo->wr_count = voodoo->tex_count = 0; - voodoo->time = 0; - if (voodoo_set->nr_cards == 2) { - for (c = 0; c < 4; c++) { - voodoo_slave->pixel_count_old[c] = pixel_count_current[c]; - voodoo_slave->texel_count_old[c] = texel_count_current[c]; - voodoo_slave->render_time[c] = 0; - } - voodoo_slave->tri_count = voodoo_slave->frame_count = 0; - voodoo_slave->rd_count = voodoo_slave->wr_count = voodoo_slave->tex_count = 0; - voodoo_slave->time = 0; - } - voodoo_recomp = 0; + for (c = 0; c < 4; c++) { + voodoo->pixel_count_old[c] = pixel_count_current[c]; + voodoo->texel_count_old[c] = texel_count_current[c]; + voodoo->render_time[c] = 0; + } + voodoo->tri_count = voodoo->frame_count = 0; + voodoo->rd_count = voodoo->wr_count = voodoo->tex_count = 0; + voodoo->time = 0; + if (voodoo_set->nr_cards == 2) { + for (c = 0; c < 4; c++) { + voodoo_slave->pixel_count_old[c] = pixel_count_current[c]; + voodoo_slave->texel_count_old[c] = texel_count_current[c]; + voodoo_slave->render_time[c] = 0; + } + voodoo_slave->tri_count = voodoo_slave->frame_count = 0; + voodoo_slave->rd_count = voodoo_slave->wr_count = voodoo_slave->tex_count = 0; + voodoo_slave->time = 0; + } + voodoo_recomp = 0; } static void voodoo_speed_changed(void *p) { - voodoo_set_t *voodoo_set = (voodoo_set_t *)p; + voodoo_set_t *voodoo_set = (voodoo_set_t *)p; - voodoo_pixelclock_update(voodoo_set->voodoos[0]); - voodoo_set->voodoos[0]->read_time = pci_nonburst_time + pci_burst_time * ((voodoo_set->voodoos[0]->fbiInit4 & 1) ? 2 : 1); - voodoo_set->voodoos[0]->write_time = pci_nonburst_time + pci_burst_time * ((voodoo_set->voodoos[0]->fbiInit1 & 2) ? 1 : 0); - voodoo_set->voodoos[0]->burst_time = pci_burst_time * ((voodoo_set->voodoos[0]->fbiInit1 & 2) ? 2 : 1); - if (voodoo_set->nr_cards == 2) { - voodoo_pixelclock_update(voodoo_set->voodoos[1]); - voodoo_set->voodoos[1]->read_time = pci_nonburst_time + pci_burst_time * ((voodoo_set->voodoos[1]->fbiInit4 & 1) ? 2 : 1); - voodoo_set->voodoos[1]->write_time = pci_nonburst_time + pci_burst_time * ((voodoo_set->voodoos[1]->fbiInit1 & 2) ? 1 : 0); - voodoo_set->voodoos[1]->burst_time = pci_burst_time * ((voodoo_set->voodoos[1]->fbiInit1 & 2) ? 2 : 1); - } -// pclog("Voodoo read_time=%i write_time=%i burst_time=%i %08x %08x\n", voodoo->read_time, voodoo->write_time, voodoo->burst_time, voodoo->fbiInit1, voodoo->fbiInit4); + voodoo_pixelclock_update(voodoo_set->voodoos[0]); + voodoo_set->voodoos[0]->read_time = pci_nonburst_time + pci_burst_time * ((voodoo_set->voodoos[0]->fbiInit4 & 1) ? 2 : 1); + voodoo_set->voodoos[0]->write_time = + pci_nonburst_time + pci_burst_time * ((voodoo_set->voodoos[0]->fbiInit1 & 2) ? 1 : 0); + voodoo_set->voodoos[0]->burst_time = pci_burst_time * ((voodoo_set->voodoos[0]->fbiInit1 & 2) ? 2 : 1); + if (voodoo_set->nr_cards == 2) { + voodoo_pixelclock_update(voodoo_set->voodoos[1]); + voodoo_set->voodoos[1]->read_time = + pci_nonburst_time + pci_burst_time * ((voodoo_set->voodoos[1]->fbiInit4 & 1) ? 2 : 1); + voodoo_set->voodoos[1]->write_time = + pci_nonburst_time + pci_burst_time * ((voodoo_set->voodoos[1]->fbiInit1 & 2) ? 1 : 0); + voodoo_set->voodoos[1]->burst_time = pci_burst_time * ((voodoo_set->voodoos[1]->fbiInit1 & 2) ? 2 : 1); + } + // pclog("Voodoo read_time=%i write_time=%i burst_time=%i %08x %08x\n", voodoo->read_time, voodoo->write_time, + // voodoo->burst_time, voodoo->fbiInit1, voodoo->fbiInit4); } void *voodoo_card_init() { - int c; - voodoo_t *voodoo = malloc(sizeof(voodoo_t)); - memset(voodoo, 0, sizeof(voodoo_t)); + int c; + voodoo_t *voodoo = malloc(sizeof(voodoo_t)); + memset(voodoo, 0, sizeof(voodoo_t)); - voodoo->bilinear_enabled = device_get_config_int("bilinear"); - voodoo->dithersub_enabled = device_get_config_int("dithersub"); - voodoo->scrfilter = device_get_config_int("dacfilter"); - voodoo->texture_size = device_get_config_int("texture_memory"); - voodoo->texture_mask = (voodoo->texture_size << 20) - 1; - voodoo->fb_size = device_get_config_int("framebuffer_memory"); - voodoo->fb_mask = (voodoo->fb_size << 20) - 1; - voodoo->render_threads = device_get_config_int("render_threads"); - voodoo->odd_even_mask = voodoo->render_threads - 1; + voodoo->bilinear_enabled = device_get_config_int("bilinear"); + voodoo->dithersub_enabled = device_get_config_int("dithersub"); + voodoo->scrfilter = device_get_config_int("dacfilter"); + voodoo->texture_size = device_get_config_int("texture_memory"); + voodoo->texture_mask = (voodoo->texture_size << 20) - 1; + voodoo->fb_size = device_get_config_int("framebuffer_memory"); + voodoo->fb_mask = (voodoo->fb_size << 20) - 1; + voodoo->render_threads = device_get_config_int("render_threads"); + voodoo->odd_even_mask = voodoo->render_threads - 1; #ifndef NO_CODEGEN - voodoo->use_recompiler = device_get_config_int("recompiler"); + voodoo->use_recompiler = device_get_config_int("recompiler"); #endif - voodoo->type = device_get_config_int("type"); - switch (voodoo->type) { - case VOODOO_1:voodoo->dual_tmus = 0; - break; - case VOODOO_SB50:voodoo->dual_tmus = 1; - break; - case VOODOO_2:voodoo->dual_tmus = 1; - break; - } + voodoo->type = device_get_config_int("type"); + switch (voodoo->type) { + case VOODOO_1: + voodoo->dual_tmus = 0; + break; + case VOODOO_SB50: + voodoo->dual_tmus = 1; + break; + case VOODOO_2: + voodoo->dual_tmus = 1; + break; + } - if (voodoo->type == VOODOO_2) /*generate filter lookup tables*/ - voodoo_generate_filter_v2(voodoo); - else - voodoo_generate_filter_v1(voodoo); + if (voodoo->type == VOODOO_2) /*generate filter lookup tables*/ + voodoo_generate_filter_v2(voodoo); + else + voodoo_generate_filter_v1(voodoo); - pci_add(voodoo_pci_read, voodoo_pci_write, voodoo); + pci_add(voodoo_pci_read, voodoo_pci_write, voodoo); - mem_mapping_add(&voodoo->mapping, 0, 0, NULL, voodoo_readw, voodoo_readl, NULL, voodoo_writew, voodoo_writel, NULL, MEM_MAPPING_EXTERNAL, voodoo); + mem_mapping_add(&voodoo->mapping, 0, 0, NULL, voodoo_readw, voodoo_readl, NULL, voodoo_writew, voodoo_writel, NULL, + MEM_MAPPING_EXTERNAL, voodoo); - voodoo->fb_mem = malloc(4 * 1024 * 1024); - voodoo->tex_mem[0] = malloc(voodoo->texture_size * 1024 * 1024); - if (voodoo->dual_tmus) - voodoo->tex_mem[1] = malloc(voodoo->texture_size * 1024 * 1024); - voodoo->tex_mem_w[0] = (uint16_t *)voodoo->tex_mem[0]; - voodoo->tex_mem_w[1] = (uint16_t *)voodoo->tex_mem[1]; + voodoo->fb_mem = malloc(4 * 1024 * 1024); + voodoo->tex_mem[0] = malloc(voodoo->texture_size * 1024 * 1024); + if (voodoo->dual_tmus) + voodoo->tex_mem[1] = malloc(voodoo->texture_size * 1024 * 1024); + voodoo->tex_mem_w[0] = (uint16_t *)voodoo->tex_mem[0]; + voodoo->tex_mem_w[1] = (uint16_t *)voodoo->tex_mem[1]; - for (c = 0; c < TEX_CACHE_MAX; c++) { - voodoo->texture_cache[0][c].data = malloc((256 * 256 + 256 * 256 + 128 * 128 + 64 * 64 + 32 * 32 + 16 * 16 + 8 * 8 + 4 * 4 + 2 * 2) * 4); - voodoo->texture_cache[0][c].base = -1; /*invalid*/ - voodoo->texture_cache[0][c].refcount = 0; - if (voodoo->dual_tmus) { - voodoo->texture_cache[1][c].data = malloc((256 * 256 + 256 * 256 + 128 * 128 + 64 * 64 + 32 * 32 + 16 * 16 + 8 * 8 + 4 * 4 + 2 * 2) * 4); - voodoo->texture_cache[1][c].base = -1; /*invalid*/ - voodoo->texture_cache[1][c].refcount = 0; - } - } + for (c = 0; c < TEX_CACHE_MAX; c++) { + voodoo->texture_cache[0][c].data = + malloc((256 * 256 + 256 * 256 + 128 * 128 + 64 * 64 + 32 * 32 + 16 * 16 + 8 * 8 + 4 * 4 + 2 * 2) * 4); + voodoo->texture_cache[0][c].base = -1; /*invalid*/ + voodoo->texture_cache[0][c].refcount = 0; + if (voodoo->dual_tmus) { + voodoo->texture_cache[1][c].data = malloc( + (256 * 256 + 256 * 256 + 128 * 128 + 64 * 64 + 32 * 32 + 16 * 16 + 8 * 8 + 4 * 4 + 2 * 2) * 4); + voodoo->texture_cache[1][c].base = -1; /*invalid*/ + voodoo->texture_cache[1][c].refcount = 0; + } + } - timer_add(&voodoo->timer, voodoo_callback, voodoo, 1); + timer_add(&voodoo->timer, voodoo_callback, voodoo, 1); - voodoo->svga = svga_get_pri(); - voodoo->fbiInit0 = 0; + voodoo->svga = svga_get_pri(); + voodoo->fbiInit0 = 0; - voodoo->wake_fifo_thread = thread_create_event(); - voodoo->wake_render_thread[0] = thread_create_event(); - voodoo->wake_render_thread[1] = thread_create_event(); - voodoo->wake_render_thread[2] = thread_create_event(); - voodoo->wake_render_thread[3] = thread_create_event(); - voodoo->wake_main_thread = thread_create_event(); - voodoo->fifo_not_full_event = thread_create_event(); - voodoo->render_not_full_event[0] = thread_create_event(); - voodoo->render_not_full_event[1] = thread_create_event(); - voodoo->render_not_full_event[2] = thread_create_event(); - voodoo->render_not_full_event[3] = thread_create_event(); - voodoo->fifo_thread = thread_create(voodoo_fifo_thread, voodoo); - voodoo->render_thread[0] = thread_create(voodoo_render_thread_1, voodoo); - if (voodoo->render_threads >= 2) - voodoo->render_thread[1] = thread_create(voodoo_render_thread_2, voodoo); - if (voodoo->render_threads == 4) { - voodoo->render_thread[2] = thread_create(voodoo_render_thread_3, voodoo); - voodoo->render_thread[3] = thread_create(voodoo_render_thread_4, voodoo); - } - voodoo->swap_mutex = thread_create_mutex(); - timer_add(&voodoo->wake_timer, voodoo_wake_timer, (void *)voodoo, 0); + voodoo->wake_fifo_thread = thread_create_event(); + voodoo->wake_render_thread[0] = thread_create_event(); + voodoo->wake_render_thread[1] = thread_create_event(); + voodoo->wake_render_thread[2] = thread_create_event(); + voodoo->wake_render_thread[3] = thread_create_event(); + voodoo->wake_main_thread = thread_create_event(); + voodoo->fifo_not_full_event = thread_create_event(); + voodoo->render_not_full_event[0] = thread_create_event(); + voodoo->render_not_full_event[1] = thread_create_event(); + voodoo->render_not_full_event[2] = thread_create_event(); + voodoo->render_not_full_event[3] = thread_create_event(); + voodoo->fifo_thread = thread_create(voodoo_fifo_thread, voodoo); + voodoo->render_thread[0] = thread_create(voodoo_render_thread_1, voodoo); + if (voodoo->render_threads >= 2) + voodoo->render_thread[1] = thread_create(voodoo_render_thread_2, voodoo); + if (voodoo->render_threads == 4) { + voodoo->render_thread[2] = thread_create(voodoo_render_thread_3, voodoo); + voodoo->render_thread[3] = thread_create(voodoo_render_thread_4, voodoo); + } + voodoo->swap_mutex = thread_create_mutex(); + timer_add(&voodoo->wake_timer, voodoo_wake_timer, (void *)voodoo, 0); - for (c = 0; c < 0x100; c++) { - rgb332[c].r = c & 0xe0; - rgb332[c].g = (c << 3) & 0xe0; - rgb332[c].b = (c << 6) & 0xc0; - rgb332[c].r = rgb332[c].r | (rgb332[c].r >> 3) | (rgb332[c].r >> 6); - rgb332[c].g = rgb332[c].g | (rgb332[c].g >> 3) | (rgb332[c].g >> 6); - rgb332[c].b = rgb332[c].b | (rgb332[c].b >> 2); - rgb332[c].b = rgb332[c].b | (rgb332[c].b >> 4); - rgb332[c].a = 0xff; + for (c = 0; c < 0x100; c++) { + rgb332[c].r = c & 0xe0; + rgb332[c].g = (c << 3) & 0xe0; + rgb332[c].b = (c << 6) & 0xc0; + rgb332[c].r = rgb332[c].r | (rgb332[c].r >> 3) | (rgb332[c].r >> 6); + rgb332[c].g = rgb332[c].g | (rgb332[c].g >> 3) | (rgb332[c].g >> 6); + rgb332[c].b = rgb332[c].b | (rgb332[c].b >> 2); + rgb332[c].b = rgb332[c].b | (rgb332[c].b >> 4); + rgb332[c].a = 0xff; - ai44[c].a = (c & 0xf0) | ((c & 0xf0) >> 4); - ai44[c].r = (c & 0x0f) | ((c & 0x0f) << 4); - ai44[c].g = ai44[c].b = ai44[c].r; - } + ai44[c].a = (c & 0xf0) | ((c & 0xf0) >> 4); + ai44[c].r = (c & 0x0f) | ((c & 0x0f) << 4); + ai44[c].g = ai44[c].b = ai44[c].r; + } - for (c = 0; c < 0x10000; c++) { - rgb565[c].r = (c >> 8) & 0xf8; - rgb565[c].g = (c >> 3) & 0xfc; - rgb565[c].b = (c << 3) & 0xf8; - rgb565[c].r |= (rgb565[c].r >> 5); - rgb565[c].g |= (rgb565[c].g >> 6); - rgb565[c].b |= (rgb565[c].b >> 5); - rgb565[c].a = 0xff; + for (c = 0; c < 0x10000; c++) { + rgb565[c].r = (c >> 8) & 0xf8; + rgb565[c].g = (c >> 3) & 0xfc; + rgb565[c].b = (c << 3) & 0xf8; + rgb565[c].r |= (rgb565[c].r >> 5); + rgb565[c].g |= (rgb565[c].g >> 6); + rgb565[c].b |= (rgb565[c].b >> 5); + rgb565[c].a = 0xff; - argb1555[c].r = (c >> 7) & 0xf8; - argb1555[c].g = (c >> 2) & 0xf8; - argb1555[c].b = (c << 3) & 0xf8; - argb1555[c].r |= (argb1555[c].r >> 5); - argb1555[c].g |= (argb1555[c].g >> 5); - argb1555[c].b |= (argb1555[c].b >> 5); - argb1555[c].a = (c & 0x8000) ? 0xff : 0; + argb1555[c].r = (c >> 7) & 0xf8; + argb1555[c].g = (c >> 2) & 0xf8; + argb1555[c].b = (c << 3) & 0xf8; + argb1555[c].r |= (argb1555[c].r >> 5); + argb1555[c].g |= (argb1555[c].g >> 5); + argb1555[c].b |= (argb1555[c].b >> 5); + argb1555[c].a = (c & 0x8000) ? 0xff : 0; - argb4444[c].a = (c >> 8) & 0xf0; - argb4444[c].r = (c >> 4) & 0xf0; - argb4444[c].g = c & 0xf0; - argb4444[c].b = (c << 4) & 0xf0; - argb4444[c].a |= (argb4444[c].a >> 4); - argb4444[c].r |= (argb4444[c].r >> 4); - argb4444[c].g |= (argb4444[c].g >> 4); - argb4444[c].b |= (argb4444[c].b >> 4); + argb4444[c].a = (c >> 8) & 0xf0; + argb4444[c].r = (c >> 4) & 0xf0; + argb4444[c].g = c & 0xf0; + argb4444[c].b = (c << 4) & 0xf0; + argb4444[c].a |= (argb4444[c].a >> 4); + argb4444[c].r |= (argb4444[c].r >> 4); + argb4444[c].g |= (argb4444[c].g >> 4); + argb4444[c].b |= (argb4444[c].b >> 4); - ai88[c].a = (c >> 8); - ai88[c].r = c & 0xff; - ai88[c].g = c & 0xff; - ai88[c].b = c & 0xff; - } + ai88[c].a = (c >> 8); + ai88[c].r = c & 0xff; + ai88[c].g = c & 0xff; + ai88[c].b = c & 0xff; + } #ifndef NO_CODEGEN - voodoo_codegen_init(voodoo); + voodoo_codegen_init(voodoo); #endif - voodoo->disp_buffer = 0; - voodoo->draw_buffer = 1; + voodoo->disp_buffer = 0; + voodoo->draw_buffer = 1; - return voodoo; + return voodoo; } void *voodoo_2d3d_card_init(int type) { - int c; - voodoo_t *voodoo = malloc(sizeof(voodoo_t)); - memset(voodoo, 0, sizeof(voodoo_t)); + int c; + voodoo_t *voodoo = malloc(sizeof(voodoo_t)); + memset(voodoo, 0, sizeof(voodoo_t)); - voodoo->bilinear_enabled = device_get_config_int("bilinear"); - voodoo->dithersub_enabled = device_get_config_int("dithersub"); - voodoo->scrfilter = device_get_config_int("dacfilter"); - voodoo->render_threads = device_get_config_int("render_threads"); + voodoo->bilinear_enabled = device_get_config_int("bilinear"); + voodoo->dithersub_enabled = device_get_config_int("dithersub"); + voodoo->scrfilter = device_get_config_int("dacfilter"); + voodoo->render_threads = device_get_config_int("render_threads"); - voodoo->odd_even_mask = voodoo->render_threads - 1; + voodoo->odd_even_mask = voodoo->render_threads - 1; #ifndef NO_CODEGEN - voodoo->use_recompiler = device_get_config_int("recompiler"); + voodoo->use_recompiler = device_get_config_int("recompiler"); #endif - voodoo->type = type; - voodoo->dual_tmus = (type == VOODOO_3) ? 1 : 0; + voodoo->type = type; + voodoo->dual_tmus = (type == VOODOO_3) ? 1 : 0; - /*generate filter lookup tables*/ - voodoo_generate_filter_v2(voodoo); + /*generate filter lookup tables*/ + voodoo_generate_filter_v2(voodoo); - for (c = 0; c < TEX_CACHE_MAX; c++) { - voodoo->texture_cache[0][c].data = malloc((256 * 256 + 256 * 256 + 128 * 128 + 64 * 64 + 32 * 32 + 16 * 16 + 8 * 8 + 4 * 4 + 2 * 2) * 4); - voodoo->texture_cache[0][c].base = -1; /*invalid*/ - voodoo->texture_cache[0][c].refcount = 0; - if (voodoo->dual_tmus) { - voodoo->texture_cache[1][c].data = malloc((256 * 256 + 256 * 256 + 128 * 128 + 64 * 64 + 32 * 32 + 16 * 16 + 8 * 8 + 4 * 4 + 2 * 2) * 4); - voodoo->texture_cache[1][c].base = -1; /*invalid*/ - voodoo->texture_cache[1][c].refcount = 0; - } - } + for (c = 0; c < TEX_CACHE_MAX; c++) { + voodoo->texture_cache[0][c].data = + malloc((256 * 256 + 256 * 256 + 128 * 128 + 64 * 64 + 32 * 32 + 16 * 16 + 8 * 8 + 4 * 4 + 2 * 2) * 4); + voodoo->texture_cache[0][c].base = -1; /*invalid*/ + voodoo->texture_cache[0][c].refcount = 0; + if (voodoo->dual_tmus) { + voodoo->texture_cache[1][c].data = malloc( + (256 * 256 + 256 * 256 + 128 * 128 + 64 * 64 + 32 * 32 + 16 * 16 + 8 * 8 + 4 * 4 + 2 * 2) * 4); + voodoo->texture_cache[1][c].base = -1; /*invalid*/ + voodoo->texture_cache[1][c].refcount = 0; + } + } - timer_add(&voodoo->timer, voodoo_callback, voodoo, 1); + timer_add(&voodoo->timer, voodoo_callback, voodoo, 1); - voodoo->fbiInit0 = 0; + voodoo->fbiInit0 = 0; - voodoo->wake_fifo_thread = thread_create_event(); - voodoo->wake_render_thread[0] = thread_create_event(); - voodoo->wake_render_thread[1] = thread_create_event(); - voodoo->wake_render_thread[2] = thread_create_event(); - voodoo->wake_render_thread[3] = thread_create_event(); - voodoo->wake_main_thread = thread_create_event(); - voodoo->fifo_not_full_event = thread_create_event(); - voodoo->render_not_full_event[0] = thread_create_event(); - voodoo->render_not_full_event[1] = thread_create_event(); - voodoo->render_not_full_event[2] = thread_create_event(); - voodoo->render_not_full_event[3] = thread_create_event(); - voodoo->fifo_thread = thread_create(voodoo_fifo_thread, voodoo); - voodoo->render_thread[0] = thread_create(voodoo_render_thread_1, voodoo); - if (voodoo->render_threads >= 2) - voodoo->render_thread[1] = thread_create(voodoo_render_thread_2, voodoo); - if (voodoo->render_threads == 4) { - voodoo->render_thread[2] = thread_create(voodoo_render_thread_3, voodoo); - voodoo->render_thread[3] = thread_create(voodoo_render_thread_4, voodoo); - } - voodoo->swap_mutex = thread_create_mutex(); - timer_add(&voodoo->wake_timer, voodoo_wake_timer, (void *)voodoo, 0); + voodoo->wake_fifo_thread = thread_create_event(); + voodoo->wake_render_thread[0] = thread_create_event(); + voodoo->wake_render_thread[1] = thread_create_event(); + voodoo->wake_render_thread[2] = thread_create_event(); + voodoo->wake_render_thread[3] = thread_create_event(); + voodoo->wake_main_thread = thread_create_event(); + voodoo->fifo_not_full_event = thread_create_event(); + voodoo->render_not_full_event[0] = thread_create_event(); + voodoo->render_not_full_event[1] = thread_create_event(); + voodoo->render_not_full_event[2] = thread_create_event(); + voodoo->render_not_full_event[3] = thread_create_event(); + voodoo->fifo_thread = thread_create(voodoo_fifo_thread, voodoo); + voodoo->render_thread[0] = thread_create(voodoo_render_thread_1, voodoo); + if (voodoo->render_threads >= 2) + voodoo->render_thread[1] = thread_create(voodoo_render_thread_2, voodoo); + if (voodoo->render_threads == 4) { + voodoo->render_thread[2] = thread_create(voodoo_render_thread_3, voodoo); + voodoo->render_thread[3] = thread_create(voodoo_render_thread_4, voodoo); + } + voodoo->swap_mutex = thread_create_mutex(); + timer_add(&voodoo->wake_timer, voodoo_wake_timer, (void *)voodoo, 0); - for (c = 0; c < 0x100; c++) { - rgb332[c].r = c & 0xe0; - rgb332[c].g = (c << 3) & 0xe0; - rgb332[c].b = (c << 6) & 0xc0; - rgb332[c].r = rgb332[c].r | (rgb332[c].r >> 3) | (rgb332[c].r >> 6); - rgb332[c].g = rgb332[c].g | (rgb332[c].g >> 3) | (rgb332[c].g >> 6); - rgb332[c].b = rgb332[c].b | (rgb332[c].b >> 2); - rgb332[c].b = rgb332[c].b | (rgb332[c].b >> 4); - rgb332[c].a = 0xff; + for (c = 0; c < 0x100; c++) { + rgb332[c].r = c & 0xe0; + rgb332[c].g = (c << 3) & 0xe0; + rgb332[c].b = (c << 6) & 0xc0; + rgb332[c].r = rgb332[c].r | (rgb332[c].r >> 3) | (rgb332[c].r >> 6); + rgb332[c].g = rgb332[c].g | (rgb332[c].g >> 3) | (rgb332[c].g >> 6); + rgb332[c].b = rgb332[c].b | (rgb332[c].b >> 2); + rgb332[c].b = rgb332[c].b | (rgb332[c].b >> 4); + rgb332[c].a = 0xff; - ai44[c].a = (c & 0xf0) | ((c & 0xf0) >> 4); - ai44[c].r = (c & 0x0f) | ((c & 0x0f) << 4); - ai44[c].g = ai44[c].b = ai44[c].r; - } + ai44[c].a = (c & 0xf0) | ((c & 0xf0) >> 4); + ai44[c].r = (c & 0x0f) | ((c & 0x0f) << 4); + ai44[c].g = ai44[c].b = ai44[c].r; + } - for (c = 0; c < 0x10000; c++) { - rgb565[c].r = (c >> 8) & 0xf8; - rgb565[c].g = (c >> 3) & 0xfc; - rgb565[c].b = (c << 3) & 0xf8; - rgb565[c].r |= (rgb565[c].r >> 5); - rgb565[c].g |= (rgb565[c].g >> 6); - rgb565[c].b |= (rgb565[c].b >> 5); - rgb565[c].a = 0xff; + for (c = 0; c < 0x10000; c++) { + rgb565[c].r = (c >> 8) & 0xf8; + rgb565[c].g = (c >> 3) & 0xfc; + rgb565[c].b = (c << 3) & 0xf8; + rgb565[c].r |= (rgb565[c].r >> 5); + rgb565[c].g |= (rgb565[c].g >> 6); + rgb565[c].b |= (rgb565[c].b >> 5); + rgb565[c].a = 0xff; - argb1555[c].r = (c >> 7) & 0xf8; - argb1555[c].g = (c >> 2) & 0xf8; - argb1555[c].b = (c << 3) & 0xf8; - argb1555[c].r |= (argb1555[c].r >> 5); - argb1555[c].g |= (argb1555[c].g >> 5); - argb1555[c].b |= (argb1555[c].b >> 5); - argb1555[c].a = (c & 0x8000) ? 0xff : 0; + argb1555[c].r = (c >> 7) & 0xf8; + argb1555[c].g = (c >> 2) & 0xf8; + argb1555[c].b = (c << 3) & 0xf8; + argb1555[c].r |= (argb1555[c].r >> 5); + argb1555[c].g |= (argb1555[c].g >> 5); + argb1555[c].b |= (argb1555[c].b >> 5); + argb1555[c].a = (c & 0x8000) ? 0xff : 0; - argb4444[c].a = (c >> 8) & 0xf0; - argb4444[c].r = (c >> 4) & 0xf0; - argb4444[c].g = c & 0xf0; - argb4444[c].b = (c << 4) & 0xf0; - argb4444[c].a |= (argb4444[c].a >> 4); - argb4444[c].r |= (argb4444[c].r >> 4); - argb4444[c].g |= (argb4444[c].g >> 4); - argb4444[c].b |= (argb4444[c].b >> 4); + argb4444[c].a = (c >> 8) & 0xf0; + argb4444[c].r = (c >> 4) & 0xf0; + argb4444[c].g = c & 0xf0; + argb4444[c].b = (c << 4) & 0xf0; + argb4444[c].a |= (argb4444[c].a >> 4); + argb4444[c].r |= (argb4444[c].r >> 4); + argb4444[c].g |= (argb4444[c].g >> 4); + argb4444[c].b |= (argb4444[c].b >> 4); - ai88[c].a = (c >> 8); - ai88[c].r = c & 0xff; - ai88[c].g = c & 0xff; - ai88[c].b = c & 0xff; - } + ai88[c].a = (c >> 8); + ai88[c].r = c & 0xff; + ai88[c].g = c & 0xff; + ai88[c].b = c & 0xff; + } #ifndef NO_CODEGEN - voodoo_codegen_init(voodoo); + voodoo_codegen_init(voodoo); #endif - voodoo->disp_buffer = 0; - voodoo->draw_buffer = 1; + voodoo->disp_buffer = 0; + voodoo->draw_buffer = 1; - return voodoo; + return voodoo; } void *voodoo_init() { - voodoo_set_t *voodoo_set = malloc(sizeof(voodoo_set_t)); - uint32_t tmuConfig = 1; - int type; - memset(voodoo_set, 0, sizeof(voodoo_set_t)); + voodoo_set_t *voodoo_set = malloc(sizeof(voodoo_set_t)); + uint32_t tmuConfig = 1; + int type; + memset(voodoo_set, 0, sizeof(voodoo_set_t)); - type = device_get_config_int("type"); + type = device_get_config_int("type"); - voodoo_set->nr_cards = device_get_config_int("sli") ? 2 : 1; - voodoo_set->voodoos[0] = voodoo_card_init(); - voodoo_set->voodoos[0]->set = voodoo_set; - if (voodoo_set->nr_cards == 2) { - voodoo_set->voodoos[1] = voodoo_card_init(); + voodoo_set->nr_cards = device_get_config_int("sli") ? 2 : 1; + voodoo_set->voodoos[0] = voodoo_card_init(); + voodoo_set->voodoos[0]->set = voodoo_set; + if (voodoo_set->nr_cards == 2) { + voodoo_set->voodoos[1] = voodoo_card_init(); - voodoo_set->voodoos[1]->set = voodoo_set; + voodoo_set->voodoos[1]->set = voodoo_set; - if (type == VOODOO_2) { - voodoo_set->voodoos[0]->fbiInit5 |= FBIINIT5_MULTI_CVG; - voodoo_set->voodoos[1]->fbiInit5 |= FBIINIT5_MULTI_CVG; - } else { - voodoo_set->voodoos[0]->fbiInit1 |= FBIINIT1_MULTI_SST; - voodoo_set->voodoos[1]->fbiInit1 |= FBIINIT1_MULTI_SST; - } - } + if (type == VOODOO_2) { + voodoo_set->voodoos[0]->fbiInit5 |= FBIINIT5_MULTI_CVG; + voodoo_set->voodoos[1]->fbiInit5 |= FBIINIT5_MULTI_CVG; + } else { + voodoo_set->voodoos[0]->fbiInit1 |= FBIINIT1_MULTI_SST; + voodoo_set->voodoos[1]->fbiInit1 |= FBIINIT1_MULTI_SST; + } + } - switch (type) { - case VOODOO_1: - if (voodoo_set->nr_cards == 2) - tmuConfig = 1 | (3 << 3); - else - tmuConfig = 1; - break; - case VOODOO_SB50: - if (voodoo_set->nr_cards == 2) - tmuConfig = 1 | (3 << 3) | (3 << 6) | (2 << 9); - else - tmuConfig = 1 | (3 << 6); - break; - case VOODOO_2:tmuConfig = 1 | (3 << 6); - break; - } + switch (type) { + case VOODOO_1: + if (voodoo_set->nr_cards == 2) + tmuConfig = 1 | (3 << 3); + else + tmuConfig = 1; + break; + case VOODOO_SB50: + if (voodoo_set->nr_cards == 2) + tmuConfig = 1 | (3 << 3) | (3 << 6) | (2 << 9); + else + tmuConfig = 1 | (3 << 6); + break; + case VOODOO_2: + tmuConfig = 1 | (3 << 6); + break; + } - voodoo_set->voodoos[0]->tmuConfig = tmuConfig; - if (voodoo_set->nr_cards == 2) - voodoo_set->voodoos[1]->tmuConfig = tmuConfig; + voodoo_set->voodoos[0]->tmuConfig = tmuConfig; + if (voodoo_set->nr_cards == 2) + voodoo_set->voodoos[1]->tmuConfig = tmuConfig; - mem_mapping_add(&voodoo_set->snoop_mapping, 0, 0, NULL, voodoo_snoop_readw, voodoo_snoop_readl, NULL, voodoo_snoop_writew, voodoo_snoop_writel, NULL, MEM_MAPPING_EXTERNAL, voodoo_set); + mem_mapping_add(&voodoo_set->snoop_mapping, 0, 0, NULL, voodoo_snoop_readw, voodoo_snoop_readl, NULL, voodoo_snoop_writew, + voodoo_snoop_writel, NULL, MEM_MAPPING_EXTERNAL, voodoo_set); - return voodoo_set; + return voodoo_set; } void voodoo_card_close(voodoo_t *voodoo) { #ifndef RELEASE_BUILD - FILE *f; + FILE *f; #endif - int c; + int c; #ifndef RELEASE_BUILD - if (voodoo->tex_mem[0]) { - f = romfopen("texram.dmp", "wb"); - fwrite(voodoo->tex_mem[0], voodoo->texture_size * 1024 * 1024, 1, f); - fclose(f); - if (voodoo->dual_tmus) { - f = romfopen("texram2.dmp", "wb"); - fwrite(voodoo->tex_mem[1], voodoo->texture_size * 1024 * 1024, 1, f); - fclose(f); - } - } + if (voodoo->tex_mem[0]) { + f = romfopen("texram.dmp", "wb"); + fwrite(voodoo->tex_mem[0], voodoo->texture_size * 1024 * 1024, 1, f); + fclose(f); + if (voodoo->dual_tmus) { + f = romfopen("texram2.dmp", "wb"); + fwrite(voodoo->tex_mem[1], voodoo->texture_size * 1024 * 1024, 1, f); + fclose(f); + } + } #endif - thread_kill(voodoo->fifo_thread); - thread_kill(voodoo->render_thread[0]); - if (voodoo->render_threads >= 2) - thread_kill(voodoo->render_thread[1]); - if (voodoo->render_threads == 4) { - thread_kill(voodoo->render_thread[2]); - thread_kill(voodoo->render_thread[3]); - } - thread_destroy_event(voodoo->fifo_not_full_event); - thread_destroy_event(voodoo->wake_main_thread); - thread_destroy_event(voodoo->wake_fifo_thread); - thread_destroy_event(voodoo->wake_render_thread[0]); - thread_destroy_event(voodoo->wake_render_thread[1]); - thread_destroy_event(voodoo->render_not_full_event[0]); - thread_destroy_event(voodoo->render_not_full_event[1]); + thread_kill(voodoo->fifo_thread); + thread_kill(voodoo->render_thread[0]); + if (voodoo->render_threads >= 2) + thread_kill(voodoo->render_thread[1]); + if (voodoo->render_threads == 4) { + thread_kill(voodoo->render_thread[2]); + thread_kill(voodoo->render_thread[3]); + } + thread_destroy_event(voodoo->fifo_not_full_event); + thread_destroy_event(voodoo->wake_main_thread); + thread_destroy_event(voodoo->wake_fifo_thread); + thread_destroy_event(voodoo->wake_render_thread[0]); + thread_destroy_event(voodoo->wake_render_thread[1]); + thread_destroy_event(voodoo->render_not_full_event[0]); + thread_destroy_event(voodoo->render_not_full_event[1]); - for (c = 0; c < TEX_CACHE_MAX; c++) { - if (voodoo->dual_tmus) - free(voodoo->texture_cache[1][c].data); - free(voodoo->texture_cache[0][c].data); - } + for (c = 0; c < TEX_CACHE_MAX; c++) { + if (voodoo->dual_tmus) + free(voodoo->texture_cache[1][c].data); + free(voodoo->texture_cache[0][c].data); + } #ifndef NO_CODEGEN - voodoo_codegen_close(voodoo); + voodoo_codegen_close(voodoo); #endif - if (voodoo->type < VOODOO_BANSHEE && voodoo->fb_mem) { - free(voodoo->fb_mem); - if (voodoo->dual_tmus) - free(voodoo->tex_mem[1]); - free(voodoo->tex_mem[0]); - } - free(voodoo); + if (voodoo->type < VOODOO_BANSHEE && voodoo->fb_mem) { + free(voodoo->fb_mem); + if (voodoo->dual_tmus) + free(voodoo->tex_mem[1]); + free(voodoo->tex_mem[0]); + } + free(voodoo); } void voodoo_close(void *p) { - voodoo_set_t *voodoo_set = (voodoo_set_t *)p; + voodoo_set_t *voodoo_set = (voodoo_set_t *)p; - if (voodoo_set->nr_cards == 2) - voodoo_card_close(voodoo_set->voodoos[1]); - voodoo_card_close(voodoo_set->voodoos[0]); + if (voodoo_set->nr_cards == 2) + voodoo_card_close(voodoo_set->voodoos[1]); + voodoo_card_close(voodoo_set->voodoos[0]); - free(voodoo_set); + free(voodoo_set); } -static device_config_t voodoo_config[] = - { - { - .name = "type", - .description = "Voodoo type", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "Voodoo Graphics", - .value = VOODOO_1 - }, - { - .description = "Obsidian SB50 + Amethyst (2 TMUs)", - .value = VOODOO_SB50 - }, - { - .description = "Voodoo 2", - .value = VOODOO_2 - }, - { - .description = "" - } - }, - .default_int = 0 - }, - { - .name = "framebuffer_memory", - .description = "Framebuffer memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "2 MB", - .value = 2 - }, - { - .description = "4 MB", - .value = 4 - }, - { - .description = "" - } - }, - .default_int = 2 - }, - { - .name = "texture_memory", - .description = "Texture memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "2 MB", - .value = 2 - }, - { - .description = "4 MB", - .value = 4 - }, - { - .description = "" - } - }, - .default_int = 2 - }, - { - .name = "bilinear", - .description = "Bilinear filtering", - .type = CONFIG_BINARY, - .default_int = 1 - }, - { - .name = "dithersub", - .description = "Dither subtraction", - .type = CONFIG_BINARY, - .default_int = 1 - }, - { - .name = "dacfilter", - .description = "Screen Filter", - .type = CONFIG_BINARY, - .default_int = 0 - }, - { - .name = "render_threads", - .description = "Render threads", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "1", - .value = 1 - }, - { - .description = "2", - .value = 2 - }, - { - .description = "4", - .value = 4 - }, - { - .description = "" - } - }, - .default_int = 2 - }, - { - .name = "sli", - .description = "SLI", - .type = CONFIG_BINARY, - .default_int = 0 - }, +static device_config_t voodoo_config[] = { + {.name = "type", + .description = "Voodoo type", + .type = CONFIG_SELECTION, + .selection = {{.description = "Voodoo Graphics", .value = VOODOO_1}, + {.description = "Obsidian SB50 + Amethyst (2 TMUs)", .value = VOODOO_SB50}, + {.description = "Voodoo 2", .value = VOODOO_2}, + {.description = ""}}, + .default_int = 0}, + {.name = "framebuffer_memory", + .description = "Framebuffer memory size", + .type = CONFIG_SELECTION, + .selection = {{.description = "2 MB", .value = 2}, {.description = "4 MB", .value = 4}, {.description = ""}}, + .default_int = 2}, + {.name = "texture_memory", + .description = "Texture memory size", + .type = CONFIG_SELECTION, + .selection = {{.description = "2 MB", .value = 2}, {.description = "4 MB", .value = 4}, {.description = ""}}, + .default_int = 2}, + {.name = "bilinear", .description = "Bilinear filtering", .type = CONFIG_BINARY, .default_int = 1}, + {.name = "dithersub", .description = "Dither subtraction", .type = CONFIG_BINARY, .default_int = 1}, + {.name = "dacfilter", .description = "Screen Filter", .type = CONFIG_BINARY, .default_int = 0}, + {.name = "render_threads", + .description = "Render threads", + .type = CONFIG_SELECTION, + .selection = {{.description = "1", .value = 1}, + {.description = "2", .value = 2}, + {.description = "4", .value = 4}, + {.description = ""}}, + .default_int = 2}, + {.name = "sli", .description = "SLI", .type = CONFIG_BINARY, .default_int = 0}, #ifndef NO_CODEGEN - { - .name = "recompiler", - .description = "Recompiler", - .type = CONFIG_BINARY, - .default_int = 1 - }, + {.name = "recompiler", .description = "Recompiler", .type = CONFIG_BINARY, .default_int = 1}, #endif - { - .type = -1 - } - }; + {.type = -1}}; -device_t voodoo_device = - { - "3DFX Voodoo Graphics", - DEVICE_PCI, - voodoo_init, - voodoo_close, - NULL, - voodoo_speed_changed, - NULL, - voodoo_add_status_info, - voodoo_config - }; +device_t voodoo_device = {"3DFX Voodoo Graphics", DEVICE_PCI, voodoo_init, voodoo_close, NULL, voodoo_speed_changed, NULL, + voodoo_add_status_info, voodoo_config}; diff --git a/src/video/vid_voodoo_banshee.c b/src/video/vid_voodoo_banshee.c index 4fc2cc2e..2cff6b1d 100644 --- a/src/video/vid_voodoo_banshee.c +++ b/src/video/vid_voodoo_banshee.c @@ -28,117 +28,113 @@ static uint8_t vb_filter_v1_g[256][256]; static uint8_t vb_filter_bx_rb[256][256]; static uint8_t vb_filter_bx_g[256][256]; -enum { - TYPE_BANSHEE = 0, - TYPE_V3_2000, - TYPE_V3_3000 -}; +enum { TYPE_BANSHEE = 0, TYPE_V3_2000, TYPE_V3_3000 }; typedef struct banshee_t { - svga_t svga; + svga_t svga; - rom_t bios_rom; + rom_t bios_rom; - uint8_t pci_regs[256]; + uint8_t pci_regs[256]; - uint32_t memBaseAddr0; - uint32_t memBaseAddr1; - uint32_t ioBaseAddr; + uint32_t memBaseAddr0; + uint32_t memBaseAddr1; + uint32_t ioBaseAddr; - uint32_t agpInit0; - uint32_t dramInit0, dramInit1; - uint32_t lfbMemoryConfig; - uint32_t miscInit0, miscInit1; - uint32_t pciInit0; - uint32_t vgaInit0, vgaInit1; + uint32_t agpInit0; + uint32_t dramInit0, dramInit1; + uint32_t lfbMemoryConfig; + uint32_t miscInit0, miscInit1; + uint32_t pciInit0; + uint32_t vgaInit0, vgaInit1; - uint32_t command_2d; - uint32_t srcBaseAddr_2d; + uint32_t command_2d; + uint32_t srcBaseAddr_2d; - uint32_t pllCtrl0, pllCtrl1, pllCtrl2; + uint32_t pllCtrl0, pllCtrl1, pllCtrl2; - uint32_t dacMode; - int dacAddr; + uint32_t dacMode; + int dacAddr; - uint32_t vidDesktopOverlayStride; - uint32_t vidDesktopStartAddr; - uint32_t vidProcCfg; - uint32_t vidScreenSize; - uint32_t vidSerialParallelPort; + uint32_t vidDesktopOverlayStride; + uint32_t vidDesktopStartAddr; + uint32_t vidProcCfg; + uint32_t vidScreenSize; + uint32_t vidSerialParallelPort; - int overlay_pix_fmt; + int overlay_pix_fmt; - uint32_t hwCurPatAddr, hwCurLoc, hwCurC0, hwCurC1; + uint32_t hwCurPatAddr, hwCurLoc, hwCurC0, hwCurC1; - uint32_t intrCtrl; + uint32_t intrCtrl; - uint32_t overlay_buffer[2][4096]; + uint32_t overlay_buffer[2][4096]; - mem_mapping_t linear_mapping; + mem_mapping_t linear_mapping; - mem_mapping_t reg_mapping_low; /*0000000-07fffff*/ - mem_mapping_t reg_mapping_high; /*0c00000-1ffffff - Windows 2000 puts the BIOS ROM in between these two areas*/ + mem_mapping_t reg_mapping_low; /*0000000-07fffff*/ + mem_mapping_t reg_mapping_high; /*0c00000-1ffffff - Windows 2000 puts the BIOS ROM in between these two areas*/ - voodoo_t *voodoo; + voodoo_t *voodoo; - uint32_t desktop_addr; - int desktop_y; - uint32_t desktop_stride_tiled; + uint32_t desktop_addr; + int desktop_y; + uint32_t desktop_stride_tiled; - int type; + int type; } banshee_t; enum { - Init_status = 0x00, - Init_pciInit0 = 0x04, - Init_lfbMemoryConfig = 0x0c, - Init_miscInit0 = 0x10, - Init_miscInit1 = 0x14, - Init_dramInit0 = 0x18, - Init_dramInit1 = 0x1c, - Init_agpInit0 = 0x20, - Init_vgaInit0 = 0x28, - Init_vgaInit1 = 0x2c, - Init_2dCommand = 0x30, - Init_2dSrcBaseAddr = 0x34, - Init_strapInfo = 0x38, + Init_status = 0x00, + Init_pciInit0 = 0x04, + Init_lfbMemoryConfig = 0x0c, + Init_miscInit0 = 0x10, + Init_miscInit1 = 0x14, + Init_dramInit0 = 0x18, + Init_dramInit1 = 0x1c, + Init_agpInit0 = 0x20, + Init_vgaInit0 = 0x28, + Init_vgaInit1 = 0x2c, + Init_2dCommand = 0x30, + Init_2dSrcBaseAddr = 0x34, + Init_strapInfo = 0x38, - PLL_pllCtrl0 = 0x40, - PLL_pllCtrl1 = 0x44, - PLL_pllCtrl2 = 0x48, + PLL_pllCtrl0 = 0x40, + PLL_pllCtrl1 = 0x44, + PLL_pllCtrl2 = 0x48, - DAC_dacMode = 0x4c, - DAC_dacAddr = 0x50, - DAC_dacData = 0x54, + DAC_dacMode = 0x4c, + DAC_dacAddr = 0x50, + DAC_dacData = 0x54, - Video_vidProcCfg = 0x5c, - Video_maxRgbDelta = 0x58, - Video_hwCurPatAddr = 0x60, - Video_hwCurLoc = 0x64, - Video_hwCurC0 = 0x68, - Video_hwCurC1 = 0x6c, - Video_vidSerialParallelPort = 0x78, - Video_vidScreenSize = 0x98, - Video_vidOverlayStartCoords = 0x9c, - Video_vidOverlayEndScreenCoords = 0xa0, - Video_vidOverlayDudx = 0xa4, - Video_vidOverlayDudxOffsetSrcWidth = 0xa8, - Video_vidOverlayDvdy = 0xac, - Video_vidOverlayDvdyOffset = 0xe0, - Video_vidDesktopStartAddr = 0xe4, - Video_vidDesktopOverlayStride = 0xe8 + Video_vidProcCfg = 0x5c, + Video_maxRgbDelta = 0x58, + Video_hwCurPatAddr = 0x60, + Video_hwCurLoc = 0x64, + Video_hwCurC0 = 0x68, + Video_hwCurC1 = 0x6c, + Video_vidSerialParallelPort = 0x78, + Video_vidScreenSize = 0x98, + Video_vidOverlayStartCoords = 0x9c, + Video_vidOverlayEndScreenCoords = 0xa0, + Video_vidOverlayDudx = 0xa4, + Video_vidOverlayDudxOffsetSrcWidth = 0xa8, + Video_vidOverlayDvdy = 0xac, + Video_vidOverlayDvdyOffset = 0xe0, + Video_vidDesktopStartAddr = 0xe4, + Video_vidDesktopOverlayStride = 0xe8 }; enum { - cmdBaseAddr0 = 0x20, - cmdBaseSize0 = 0x24, - cmdBump0 = 0x28, - cmdRdPtrL0 = 0x2c, - cmdRdPtrH0 = 0x30, - cmdAMin0 = 0x34, - cmdAMax0 = 0x3c, - cmdFifoDepth0 = 0x44, - cmdHoleCnt0 = 0x48 + cmdBaseAddr0 = 0x20, + cmdBaseSize0 = 0x24, + cmdBump0 = 0x28, + cmdRdPtrL0 = 0x2c, + cmdRdPtrH0 = 0x30, + cmdAMin0 = 0x34, + cmdAMax0 = 0x3c, + cmdFifoDepth0 = 0x44, + cmdHoleCnt0 = 0x48 }; #define VGAINIT0_EXTENDED_SHIFT_OUT (1 << 12) @@ -152,22 +148,22 @@ enum { #define VIDPROCCFG_H_SCALE_ENABLE (1 << 14) #define VIDPROCCFG_V_SCALE_ENABLE (1 << 15) #define VIDPROCCFG_FILTER_MODE_MASK (3 << 16) -#define VIDPROCCFG_FILTER_MODE_POINT (0 << 16) +#define VIDPROCCFG_FILTER_MODE_POINT (0 << 16) #define VIDPROCCFG_FILTER_MODE_DITHER_2X2 (1 << 16) #define VIDPROCCFG_FILTER_MODE_DITHER_4X4 (2 << 16) -#define VIDPROCCFG_FILTER_MODE_BILINEAR (3 << 16) +#define VIDPROCCFG_FILTER_MODE_BILINEAR (3 << 16) #define VIDPROCCFG_DESKTOP_PIX_FORMAT ((banshee->vidProcCfg >> 18) & 7) #define VIDPROCCFG_OVERLAY_PIX_FORMAT ((banshee->vidProcCfg >> 21) & 7) #define VIDPROCCFG_OVERLAY_PIX_FORMAT_SHIFT (21) #define VIDPROCCFG_OVERLAY_PIX_FORMAT_MASK (7 << VIDPROCCFG_OVERLAY_PIX_FORMAT_SHIFT) #define VIDPROCCFG_DESKTOP_TILE (1 << 24) #define VIDPROCCFG_OVERLAY_TILE (1 << 25) -#define VIDPROCCFG_2X_MODE (1 << 26) +#define VIDPROCCFG_2X_MODE (1 << 26) #define VIDPROCCFG_HWCURSOR_ENA (1 << 27) -#define OVERLAY_FMT_565 (1) -#define OVERLAY_FMT_YUYV422 (5) -#define OVERLAY_FMT_UYVY422 (6) +#define OVERLAY_FMT_565 (1) +#define OVERLAY_FMT_YUYV422 (5) +#define OVERLAY_FMT_UYVY422 (6) #define OVERLAY_FMT_565_DITHER (7) #define OVERLAY_START_X_MASK (0xfff) @@ -179,7 +175,7 @@ enum { #define OVERLAY_END_Y_MASK (0xfff << OVERLAY_END_Y_SHIFT) #define OVERLAY_SRC_WIDTH_SHIFT (19) -#define OVERLAY_SRC_WIDTH_MASK (0x1fff << OVERLAY_SRC_WIDTH_SHIFT) +#define OVERLAY_SRC_WIDTH_MASK (0x1fff << OVERLAY_SRC_WIDTH_SHIFT) #define VID_STRIDE_OVERLAY_SHIFT (16) #define VID_STRIDE_OVERLAY_MASK (0x7fff << VID_STRIDE_OVERLAY_SHIFT) @@ -187,10 +183,10 @@ enum { #define VID_DUDX_MASK (0xffffff) #define VID_DVDY_MASK (0xffffff) -#define PIX_FORMAT_8 0 +#define PIX_FORMAT_8 0 #define PIX_FORMAT_RGB565 1 -#define PIX_FORMAT_RGB24 2 -#define PIX_FORMAT_RGB32 3 +#define PIX_FORMAT_RGB24 2 +#define PIX_FORMAT_RGB32 3 #define VIDSERIAL_DDC_DCK_W (1 << 19) #define VIDSERIAL_DDC_DDA_W (1 << 20) @@ -207,2541 +203,2577 @@ enum { static uint32_t banshee_status(banshee_t *banshee); static void banshee_out(uint16_t addr, uint8_t val, void *p) { - banshee_t *banshee = (banshee_t *)p; - svga_t *svga = &banshee->svga; - uint8_t old; + banshee_t *banshee = (banshee_t *)p; + svga_t *svga = &banshee->svga; + uint8_t old; -// /*if (addr != 0x3c9) */pclog("banshee_out : %04X %02X %04X:%04X\n", addr, val, CS,cpu_state.pc); + // /*if (addr != 0x3c9) */pclog("banshee_out : %04X %02X %04X:%04X\n", addr, val, CS,cpu_state.pc); - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; - switch (addr) { - case 0x3D4:svga->crtcreg = val & 0x3f; - return; - case 0x3D5: - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) - return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); - old = svga->crtc[svga->crtcreg]; - svga->crtc[svga->crtcreg] = val; - if (old != val) { - if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - } - break; - } - svga_out(addr, val, svga); + switch (addr) { + case 0x3D4: + svga->crtcreg = val & 0x3f; + return; + case 0x3D5: + if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) + return; + if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) + val = (svga->crtc[7] & ~0x10) | (val & 0x10); + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; + if (old != val) { + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } + } + break; + } + svga_out(addr, val, svga); } static uint8_t banshee_in(uint16_t addr, void *p) { - banshee_t *banshee = (banshee_t *)p; - svga_t *svga = &banshee->svga; - uint8_t temp; + banshee_t *banshee = (banshee_t *)p; + svga_t *svga = &banshee->svga; + uint8_t temp; -// if (addr != 0x3da) pclog("banshee_in : %04X ", addr); + // if (addr != 0x3da) pclog("banshee_in : %04X ", addr); - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; - switch (addr) { - case 0x3c2: - if ((svga->vgapal[0].r + svga->vgapal[0].g + svga->vgapal[0].b) >= 0x40) - temp = 0; - else - temp = 0x10; - break; - case 0x3D4:temp = svga->crtcreg; - break; - case 0x3D5:temp = svga->crtc[svga->crtcreg]; - break; - default:temp = svga_in(addr, svga); - break; - } -// if (addr != 0x3da) pclog("%02X %04X:%04X %i\n", temp, CS,cpu_state.pc, ins); - return temp; + switch (addr) { + case 0x3c2: + if ((svga->vgapal[0].r + svga->vgapal[0].g + svga->vgapal[0].b) >= 0x40) + temp = 0; + else + temp = 0x10; + break; + case 0x3D4: + temp = svga->crtcreg; + break; + case 0x3D5: + temp = svga->crtc[svga->crtcreg]; + break; + default: + temp = svga_in(addr, svga); + break; + } + // if (addr != 0x3da) pclog("%02X %04X:%04X %i\n", temp, CS,cpu_state.pc, ins); + return temp; } static void banshee_updatemapping(banshee_t *banshee) { - svga_t *svga = &banshee->svga; + svga_t *svga = &banshee->svga; - if (!(banshee->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) { -// pclog("Update mapping - PCI disabled\n"); - mem_mapping_disable(&svga->mapping); - mem_mapping_disable(&banshee->linear_mapping); - mem_mapping_disable(&banshee->reg_mapping_low); - mem_mapping_disable(&banshee->reg_mapping_high); - return; - } + if (!(banshee->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) { + // pclog("Update mapping - PCI disabled\n"); + mem_mapping_disable(&svga->mapping); + mem_mapping_disable(&banshee->linear_mapping); + mem_mapping_disable(&banshee->reg_mapping_low); + mem_mapping_disable(&banshee->reg_mapping_high); + return; + } - pclog("Update mapping - bank %02X ", svga->gdcreg[6] & 0xc); - switch (svga->gdcreg[6] & 0xc) /*Banked framebuffer*/ - { - case 0x0: /*128k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); - svga->banked_mask = 0xffff; - break; - case 0x4: /*64k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - svga->banked_mask = 0xffff; - break; - case 0x8: /*32k at B0000*/ - mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); - svga->banked_mask = 0x7fff; - break; - case 0xC: /*32k at B8000*/ - mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); - svga->banked_mask = 0x7fff; - break; - } + pclog("Update mapping - bank %02X ", svga->gdcreg[6] & 0xc); + switch (svga->gdcreg[6] & 0xc) /*Banked framebuffer*/ + { + case 0x0: /*128k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); + svga->banked_mask = 0xffff; + break; + case 0x4: /*64k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + svga->banked_mask = 0xffff; + break; + case 0x8: /*32k at B0000*/ + mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); + svga->banked_mask = 0x7fff; + break; + case 0xC: /*32k at B8000*/ + mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); + svga->banked_mask = 0x7fff; + break; + } - pclog("Linear framebuffer %08X ", banshee->memBaseAddr1); - mem_mapping_set_addr(&banshee->linear_mapping, banshee->memBaseAddr1, 32 << 20); - pclog("registers %08X\n", banshee->memBaseAddr0); - mem_mapping_set_addr(&banshee->reg_mapping_low, banshee->memBaseAddr0, 8 << 20); - mem_mapping_set_addr(&banshee->reg_mapping_high, banshee->memBaseAddr0 + 0xc00000, 20 << 20); + pclog("Linear framebuffer %08X ", banshee->memBaseAddr1); + mem_mapping_set_addr(&banshee->linear_mapping, banshee->memBaseAddr1, 32 << 20); + pclog("registers %08X\n", banshee->memBaseAddr0); + mem_mapping_set_addr(&banshee->reg_mapping_low, banshee->memBaseAddr0, 8 << 20); + mem_mapping_set_addr(&banshee->reg_mapping_high, banshee->memBaseAddr0 + 0xc00000, 20 << 20); } static void banshee_render_16bpp_tiled(svga_t *svga) { - banshee_t *banshee = (banshee_t *)svga->p; - int x; - int offset = 32; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; - uint32_t addr; - int drawn = 0; + banshee_t *banshee = (banshee_t *)svga->p; + int x; + int offset = 32; + uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset]; + uint32_t addr; + int drawn = 0; - if (banshee->vidProcCfg & VIDPROCCFG_HALF_MODE) - addr = banshee->desktop_addr + ((banshee->desktop_y >> 1) & 31) * 128 + ((banshee->desktop_y >> 6) * banshee->desktop_stride_tiled); - else - addr = banshee->desktop_addr + (banshee->desktop_y & 31) * 128 + ((banshee->desktop_y >> 5) * banshee->desktop_stride_tiled); + if (banshee->vidProcCfg & VIDPROCCFG_HALF_MODE) + addr = banshee->desktop_addr + ((banshee->desktop_y >> 1) & 31) * 128 + + ((banshee->desktop_y >> 6) * banshee->desktop_stride_tiled); + else + addr = banshee->desktop_addr + (banshee->desktop_y & 31) * 128 + + ((banshee->desktop_y >> 5) * banshee->desktop_stride_tiled); - for (x = 0; x <= svga->hdisp; x += 64) { - if (svga->hwcursor_on || svga->overlay_on) - svga->changedvram[addr >> 12] = 2; - if (svga->changedvram[addr >> 12] || svga->fullchange) { - uint16_t *vram_p = (uint16_t *)&svga->vram[addr & svga->vram_display_mask]; - int xx; + for (x = 0; x <= svga->hdisp; x += 64) { + if (svga->hwcursor_on || svga->overlay_on) + svga->changedvram[addr >> 12] = 2; + if (svga->changedvram[addr >> 12] || svga->fullchange) { + uint16_t *vram_p = (uint16_t *)&svga->vram[addr & svga->vram_display_mask]; + int xx; - for (xx = 0; xx < 64; xx++) - *p++ = video_16to32[*vram_p++]; + for (xx = 0; xx < 64; xx++) + *p++ = video_16to32[*vram_p++]; - drawn = 1; - } else - p += 64; - addr += 128 * 32; - } + drawn = 1; + } else + p += 64; + addr += 128 * 32; + } - if (drawn) { - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - } + if (drawn) { + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + } - banshee->desktop_y++; + banshee->desktop_y++; } static void banshee_recalctimings(svga_t *svga) { - banshee_t *banshee = (banshee_t *)svga->p; - voodoo_t *voodoo = banshee->voodoo; + banshee_t *banshee = (banshee_t *)svga->p; + voodoo_t *voodoo = banshee->voodoo; -/*7 R/W Horizontal Retrace End bit 5. - - 6 R/W Horizontal Retrace Start bit 8 0x4 - 5 R/W Horizontal Blank End bit 6. - - 4 R/W Horizontal Blank Start bit 8. 0x3 - 3 R/W Reserved. - - 2 R/W Horizontal Display Enable End bit 8. 0x1 - 1 R/W Reserved. - - 0 R/W Horizontal Total bit 8. 0x0*/ - if (svga->crtc[0x1a] & 0x01) - svga->htotal += 0x100; - if (svga->crtc[0x1a] & 0x04) - svga->hdisp += 0x100; -/*6 R/W Vertical Retrace Start bit 10 0x10 - 5 R/W Reserved. - - 4 R/W Vertical Blank Start bit 10. 0x15 - 3 R/W Reserved. - - 2 R/W Vertical Display Enable End bit 10 0x12 - 1 R/W Reserved. - - 0 R/W Vertical Total bit 10. 0x6*/ - if (svga->crtc[0x1b] & 0x01) - svga->vtotal += 0x400; - if (svga->crtc[0x1b] & 0x04) - svga->dispend += 0x400; - if (svga->crtc[0x1b] & 0x10) - svga->vblankstart += 0x400; - if (svga->crtc[0x1b] & 0x40) - svga->vsyncstart += 0x400; -// pclog("svga->hdisp=%i\n", svga->hdisp); + /*7 R/W Horizontal Retrace End bit 5. - + 6 R/W Horizontal Retrace Start bit 8 0x4 + 5 R/W Horizontal Blank End bit 6. - + 4 R/W Horizontal Blank Start bit 8. 0x3 + 3 R/W Reserved. - + 2 R/W Horizontal Display Enable End bit 8. 0x1 + 1 R/W Reserved. - + 0 R/W Horizontal Total bit 8. 0x0*/ + if (svga->crtc[0x1a] & 0x01) + svga->htotal += 0x100; + if (svga->crtc[0x1a] & 0x04) + svga->hdisp += 0x100; + /*6 R/W Vertical Retrace Start bit 10 0x10 + 5 R/W Reserved. - + 4 R/W Vertical Blank Start bit 10. 0x15 + 3 R/W Reserved. - + 2 R/W Vertical Display Enable End bit 10 0x12 + 1 R/W Reserved. - + 0 R/W Vertical Total bit 10. 0x6*/ + if (svga->crtc[0x1b] & 0x01) + svga->vtotal += 0x400; + if (svga->crtc[0x1b] & 0x04) + svga->dispend += 0x400; + if (svga->crtc[0x1b] & 0x10) + svga->vblankstart += 0x400; + if (svga->crtc[0x1b] & 0x40) + svga->vsyncstart += 0x400; + // pclog("svga->hdisp=%i\n", svga->hdisp); - if (banshee->vgaInit0 & VGAINIT0_EXTENDED_SHIFT_OUT) { - switch (VIDPROCCFG_DESKTOP_PIX_FORMAT) { - case PIX_FORMAT_8:svga->render = svga_render_8bpp_highres; - svga->bpp = 8; - break; - case PIX_FORMAT_RGB565:svga->render = (banshee->vidProcCfg & VIDPROCCFG_DESKTOP_TILE) ? banshee_render_16bpp_tiled : svga_render_16bpp_highres; - svga->bpp = 16; - break; - case PIX_FORMAT_RGB24:svga->render = svga_render_24bpp_highres; - svga->bpp = 24; - break; - case PIX_FORMAT_RGB32:svga->render = svga_render_32bpp_highres; - svga->bpp = 32; - break; + if (banshee->vgaInit0 & VGAINIT0_EXTENDED_SHIFT_OUT) { + switch (VIDPROCCFG_DESKTOP_PIX_FORMAT) { + case PIX_FORMAT_8: + svga->render = svga_render_8bpp_highres; + svga->bpp = 8; + break; + case PIX_FORMAT_RGB565: + svga->render = (banshee->vidProcCfg & VIDPROCCFG_DESKTOP_TILE) ? banshee_render_16bpp_tiled + : svga_render_16bpp_highres; + svga->bpp = 16; + break; + case PIX_FORMAT_RGB24: + svga->render = svga_render_24bpp_highres; + svga->bpp = 24; + break; + case PIX_FORMAT_RGB32: + svga->render = svga_render_32bpp_highres; + svga->bpp = 32; + break; #ifndef RELEASE_BUILD - default:fatal("Unknown pixel format %08x\n", banshee->vgaInit0); + default: + fatal("Unknown pixel format %08x\n", banshee->vgaInit0); #endif - } - svga->rowcount = 0; - if (!(banshee->vidProcCfg & VIDPROCCFG_DESKTOP_TILE) && (banshee->vidProcCfg & VIDPROCCFG_HALF_MODE)) - svga->linedbl = 1; - else - svga->linedbl = 0; - if (banshee->vidProcCfg & VIDPROCCFG_DESKTOP_TILE) - svga->rowoffset = ((banshee->vidDesktopOverlayStride & 0x3fff) * 128) >> 3; - else - svga->rowoffset = (banshee->vidDesktopOverlayStride & 0x3fff) >> 3; - svga->ma_latch = banshee->vidDesktopStartAddr >> 2; - banshee->desktop_stride_tiled = (banshee->vidDesktopOverlayStride & 0x3fff) * 128 * 32; -// pclog("Extended shift out %i rowoffset=%i %02x\n", VIDPROCCFG_DESKTOP_PIX_FORMAT, svga->rowoffset, svga->crtc[1]); + } + svga->rowcount = 0; + if (!(banshee->vidProcCfg & VIDPROCCFG_DESKTOP_TILE) && (banshee->vidProcCfg & VIDPROCCFG_HALF_MODE)) + svga->linedbl = 1; + else + svga->linedbl = 0; + if (banshee->vidProcCfg & VIDPROCCFG_DESKTOP_TILE) + svga->rowoffset = ((banshee->vidDesktopOverlayStride & 0x3fff) * 128) >> 3; + else + svga->rowoffset = (banshee->vidDesktopOverlayStride & 0x3fff) >> 3; + svga->ma_latch = banshee->vidDesktopStartAddr >> 2; + banshee->desktop_stride_tiled = (banshee->vidDesktopOverlayStride & 0x3fff) * 128 * 32; + // pclog("Extended shift out %i rowoffset=%i %02x\n", VIDPROCCFG_DESKTOP_PIX_FORMAT, + // svga->rowoffset, svga->crtc[1]); - svga->char_width = 8; - svga->split = 99999; + svga->char_width = 8; + svga->split = 99999; - if (banshee->vidProcCfg & VIDPROCCFG_2X_MODE) { - svga->hdisp *= 2; - svga->htotal *= 2; - } + if (banshee->vidProcCfg & VIDPROCCFG_2X_MODE) { + svga->hdisp *= 2; + svga->htotal *= 2; + } - svga->overlay.ena = banshee->vidProcCfg & VIDPROCCFG_OVERLAY_ENABLE; + svga->overlay.ena = banshee->vidProcCfg & VIDPROCCFG_OVERLAY_ENABLE; - svga->overlay.x = voodoo->overlay.start_x; - svga->overlay.y = voodoo->overlay.start_y; - svga->overlay.xsize = voodoo->overlay.size_x; - svga->overlay.ysize = voodoo->overlay.size_y; - svga->overlay.pitch = (banshee->vidDesktopOverlayStride & VID_STRIDE_OVERLAY_MASK) >> VID_STRIDE_OVERLAY_SHIFT; - if (banshee->vidProcCfg & VIDPROCCFG_OVERLAY_TILE) - svga->overlay.pitch *= 128 * 32; - if (svga->overlay.xsize <= 0 || svga->overlay.ysize <= 0) - svga->overlay.ena = 0; - if (svga->overlay.ena) { -/* pclog("Overlay enabled : start=%i,%i end=%i,%i size=%i,%i pitch=%x\n", - voodoo->overlay.start_x, voodoo->overlay.start_y, - voodoo->overlay.end_x, voodoo->overlay.end_y, - voodoo->overlay.size_x, voodoo->overlay.size_y, - svga->overlay.pitch);*/ - if (!voodoo->overlay.start_x && !voodoo->overlay.start_y && - svga->hdisp == voodoo->overlay.size_x && svga->dispend == voodoo->overlay.size_y) { - /*Overlay is full screen, so don't bother rendering the desktop - behind it*/ - svga->render = svga_render_null; - svga->bpp = 0; - } - } + svga->overlay.x = voodoo->overlay.start_x; + svga->overlay.y = voodoo->overlay.start_y; + svga->overlay.xsize = voodoo->overlay.size_x; + svga->overlay.ysize = voodoo->overlay.size_y; + svga->overlay.pitch = (banshee->vidDesktopOverlayStride & VID_STRIDE_OVERLAY_MASK) >> VID_STRIDE_OVERLAY_SHIFT; + if (banshee->vidProcCfg & VIDPROCCFG_OVERLAY_TILE) + svga->overlay.pitch *= 128 * 32; + if (svga->overlay.xsize <= 0 || svga->overlay.ysize <= 0) + svga->overlay.ena = 0; + if (svga->overlay.ena) { + /* pclog("Overlay enabled : start=%i,%i end=%i,%i size=%i,%i pitch=%x\n", + voodoo->overlay.start_x, voodoo->overlay.start_y, + voodoo->overlay.end_x, voodoo->overlay.end_y, + voodoo->overlay.size_x, voodoo->overlay.size_y, + svga->overlay.pitch);*/ + if (!voodoo->overlay.start_x && !voodoo->overlay.start_y && svga->hdisp == voodoo->overlay.size_x && + svga->dispend == voodoo->overlay.size_y) { + /*Overlay is full screen, so don't bother rendering the desktop + behind it*/ + svga->render = svga_render_null; + svga->bpp = 0; + } + } - svga->video_res_override = 1; - svga->video_res_x = svga->hdisp; - svga->video_res_y = svga->dispend; - svga->video_bpp = svga->bpp; - } else { -// pclog("Normal shift out\n"); - svga->bpp = 8; - svga->video_res_override = 0; - } + svga->video_res_override = 1; + svga->video_res_x = svga->hdisp; + svga->video_res_y = svga->dispend; + svga->video_bpp = svga->bpp; + } else { + // pclog("Normal shift out\n"); + svga->bpp = 8; + svga->video_res_override = 0; + } - svga->fb_only = (banshee->vidProcCfg & VIDPROCCFG_VIDPROC_ENABLE); + svga->fb_only = (banshee->vidProcCfg & VIDPROCCFG_VIDPROC_ENABLE); - if (((svga->miscout >> 2) & 3) == 3) { - int k = banshee->pllCtrl0 & 3; - int m = (banshee->pllCtrl0 >> 2) & 0x3f; - int n = (banshee->pllCtrl0 >> 8) & 0xff; - double freq = (((double)n + 2) / (((double)m + 2) * (double)(1 << k))) * 14318184.0; + if (((svga->miscout >> 2) & 3) == 3) { + int k = banshee->pllCtrl0 & 3; + int m = (banshee->pllCtrl0 >> 2) & 0x3f; + int n = (banshee->pllCtrl0 >> 8) & 0xff; + double freq = (((double)n + 2) / (((double)m + 2) * (double)(1 << k))) * 14318184.0; - svga->clock = (cpuclock * (float)(1ull << 32)) / freq; -// svga->clock = cpuclock / freq; + svga->clock = (cpuclock * (float)(1ull << 32)) / freq; + // svga->clock = cpuclock / freq; -// pclog("svga->clock = %g %g m=%i k=%i n=%i\n", freq, freq / 1000000.0, m, k, n); - } + // pclog("svga->clock = %g %g m=%i k=%i n=%i\n", freq, freq / 1000000.0, m, k, n); + } } static void banshee_ext_out(uint16_t addr, uint8_t val, void *p) { -// banshee_t *banshee = (banshee_t *)p; -// svga_t *svga = &banshee->svga; + // banshee_t *banshee = (banshee_t *)p; + // svga_t *svga = &banshee->svga; -// pclog("banshee_ext_out: addr=%04x val=%02x\n", addr, val); + // pclog("banshee_ext_out: addr=%04x val=%02x\n", addr, val); - switch (addr & 0xff) { - case 0xb0: - case 0xb1: - case 0xb2: - case 0xb3: - case 0xb4: - case 0xb5: - case 0xb6: - case 0xb7: - case 0xb8: - case 0xb9: - case 0xba: - case 0xbb: - case 0xbc: - case 0xbd: - case 0xbe: - case 0xbf: - case 0xc0: - case 0xc1: - case 0xc2: - case 0xc3: - case 0xc4: - case 0xc5: - case 0xc6: - case 0xc7: - case 0xc8: - case 0xc9: - case 0xca: - case 0xcb: - case 0xcc: - case 0xcd: - case 0xce: - case 0xcf: - case 0xd0: - case 0xd1: - case 0xd2: - case 0xd3: - case 0xd4: - case 0xd5: - case 0xd6: - case 0xd7: - case 0xd8: - case 0xd9: - case 0xda: - case 0xdb: - case 0xdc: - case 0xdd: - case 0xde: - case 0xdf:banshee_out((addr & 0xff) + 0x300, val, p); - break; + switch (addr & 0xff) { + case 0xb0: + case 0xb1: + case 0xb2: + case 0xb3: + case 0xb4: + case 0xb5: + case 0xb6: + case 0xb7: + case 0xb8: + case 0xb9: + case 0xba: + case 0xbb: + case 0xbc: + case 0xbd: + case 0xbe: + case 0xbf: + case 0xc0: + case 0xc1: + case 0xc2: + case 0xc3: + case 0xc4: + case 0xc5: + case 0xc6: + case 0xc7: + case 0xc8: + case 0xc9: + case 0xca: + case 0xcb: + case 0xcc: + case 0xcd: + case 0xce: + case 0xcf: + case 0xd0: + case 0xd1: + case 0xd2: + case 0xd3: + case 0xd4: + case 0xd5: + case 0xd6: + case 0xd7: + case 0xd8: + case 0xd9: + case 0xda: + case 0xdb: + case 0xdc: + case 0xdd: + case 0xde: + case 0xdf: + banshee_out((addr & 0xff) + 0x300, val, p); + break; - default:pclog("bad banshee_ext_out: addr=%04x val=%02x\n", addr, val); - } + default: + pclog("bad banshee_ext_out: addr=%04x val=%02x\n", addr, val); + } } static void banshee_ext_outl(uint16_t addr, uint32_t val, void *p) { - banshee_t *banshee = (banshee_t *)p; - voodoo_t *voodoo = banshee->voodoo; - svga_t *svga = &banshee->svga; + banshee_t *banshee = (banshee_t *)p; + voodoo_t *voodoo = banshee->voodoo; + svga_t *svga = &banshee->svga; -// pclog("banshee_ext_outl: addr=%04x val=%08x %04x(%08x):%08x\n", addr, val, CS,cs,cpu_state.pc); + // pclog("banshee_ext_outl: addr=%04x val=%08x %04x(%08x):%08x\n", addr, val, CS,cs,cpu_state.pc); - switch (addr & 0xff) { - case Init_pciInit0:banshee->pciInit0 = val; - voodoo->read_time = pci_nonburst_time + pci_burst_time * ((val & 0x100) ? 2 : 1); - voodoo->burst_time = pci_burst_time * ((val & 0x200) ? 1 : 0); - voodoo->write_time = pci_nonburst_time + voodoo->burst_time; - break; + switch (addr & 0xff) { + case Init_pciInit0: + banshee->pciInit0 = val; + voodoo->read_time = pci_nonburst_time + pci_burst_time * ((val & 0x100) ? 2 : 1); + voodoo->burst_time = pci_burst_time * ((val & 0x200) ? 1 : 0); + voodoo->write_time = pci_nonburst_time + voodoo->burst_time; + break; - case Init_lfbMemoryConfig:banshee->lfbMemoryConfig = val; -// pclog("lfbMemoryConfig=%08x\n", val); - voodoo->tile_base = (val & 0x1fff) << 12; - voodoo->tile_stride = 1024 << ((val >> 13) & 7); - voodoo->tile_stride_shift = 10 + ((val >> 13) & 7); - voodoo->tile_x = ((val >> 16) & 0x7f) * 128; - voodoo->tile_x_real = ((val >> 16) & 0x7f) * 128 * 32; - break; + case Init_lfbMemoryConfig: + banshee->lfbMemoryConfig = val; + // pclog("lfbMemoryConfig=%08x\n", val); + voodoo->tile_base = (val & 0x1fff) << 12; + voodoo->tile_stride = 1024 << ((val >> 13) & 7); + voodoo->tile_stride_shift = 10 + ((val >> 13) & 7); + voodoo->tile_x = ((val >> 16) & 0x7f) * 128; + voodoo->tile_x_real = ((val >> 16) & 0x7f) * 128 * 32; + break; - case Init_miscInit0:banshee->miscInit0 = val; - voodoo->y_origin_swap = (val & MISCINIT0_Y_ORIGIN_SWAP_MASK) >> MISCINIT0_Y_ORIGIN_SWAP_SHIFT; - break; - case Init_miscInit1:banshee->miscInit1 = val; - break; - case Init_dramInit0:banshee->dramInit0 = val; - break; - case Init_dramInit1:banshee->dramInit1 = val; - break; - case Init_agpInit0:banshee->agpInit0 = val; - break; + case Init_miscInit0: + banshee->miscInit0 = val; + voodoo->y_origin_swap = (val & MISCINIT0_Y_ORIGIN_SWAP_MASK) >> MISCINIT0_Y_ORIGIN_SWAP_SHIFT; + break; + case Init_miscInit1: + banshee->miscInit1 = val; + break; + case Init_dramInit0: + banshee->dramInit0 = val; + break; + case Init_dramInit1: + banshee->dramInit1 = val; + break; + case Init_agpInit0: + banshee->agpInit0 = val; + break; - case Init_2dCommand:banshee->command_2d = val; - break; - case Init_2dSrcBaseAddr:banshee->srcBaseAddr_2d = val; - break; - case Init_vgaInit0:banshee->vgaInit0 = val; - break; - case Init_vgaInit1:banshee->vgaInit1 = val; - svga->write_bank = (val & 0x3ff) << 15; - svga->read_bank = ((val >> 10) & 0x3ff) << 15; - break; + case Init_2dCommand: + banshee->command_2d = val; + break; + case Init_2dSrcBaseAddr: + banshee->srcBaseAddr_2d = val; + break; + case Init_vgaInit0: + banshee->vgaInit0 = val; + break; + case Init_vgaInit1: + banshee->vgaInit1 = val; + svga->write_bank = (val & 0x3ff) << 15; + svga->read_bank = ((val >> 10) & 0x3ff) << 15; + break; - case PLL_pllCtrl0:banshee->pllCtrl0 = val; - break; - case PLL_pllCtrl1:banshee->pllCtrl1 = val; - break; - case PLL_pllCtrl2:banshee->pllCtrl2 = val; - break; + case PLL_pllCtrl0: + banshee->pllCtrl0 = val; + break; + case PLL_pllCtrl1: + banshee->pllCtrl1 = val; + break; + case PLL_pllCtrl2: + banshee->pllCtrl2 = val; + break; - case DAC_dacMode:banshee->dacMode = val; - break; - case DAC_dacAddr:banshee->dacAddr = val & 0x1ff; - break; - case DAC_dacData:svga->pallook[banshee->dacAddr] = val & 0xffffff; - svga->fullchange = changeframecount; - break; + case DAC_dacMode: + banshee->dacMode = val; + break; + case DAC_dacAddr: + banshee->dacAddr = val & 0x1ff; + break; + case DAC_dacData: + svga->pallook[banshee->dacAddr] = val & 0xffffff; + svga->fullchange = changeframecount; + break; - case Video_vidProcCfg:banshee->vidProcCfg = val; -// pclog("vidProcCfg=%08x\n", val); - banshee->overlay_pix_fmt = (val & VIDPROCCFG_OVERLAY_PIX_FORMAT_MASK) >> VIDPROCCFG_OVERLAY_PIX_FORMAT_SHIFT; - svga->hwcursor.ena = val & VIDPROCCFG_HWCURSOR_ENA; - svga->fullchange = changeframecount; - svga_recalctimings(svga); - break; + case Video_vidProcCfg: + banshee->vidProcCfg = val; + // pclog("vidProcCfg=%08x\n", val); + banshee->overlay_pix_fmt = (val & VIDPROCCFG_OVERLAY_PIX_FORMAT_MASK) >> VIDPROCCFG_OVERLAY_PIX_FORMAT_SHIFT; + svga->hwcursor.ena = val & VIDPROCCFG_HWCURSOR_ENA; + svga->fullchange = changeframecount; + svga_recalctimings(svga); + break; - case Video_maxRgbDelta:banshee->voodoo->scrfilterThreshold = val; - if (val > 0x00) - banshee->voodoo->scrfilterEnabled = 1; - else - banshee->voodoo->scrfilterEnabled = 0; - voodoo_threshold_check(banshee->voodoo); - pclog("Banshee Filter: %06x\n", val); + case Video_maxRgbDelta: + banshee->voodoo->scrfilterThreshold = val; + if (val > 0x00) + banshee->voodoo->scrfilterEnabled = 1; + else + banshee->voodoo->scrfilterEnabled = 0; + voodoo_threshold_check(banshee->voodoo); + pclog("Banshee Filter: %06x\n", val); - break; + break; - case Video_hwCurPatAddr:banshee->hwCurPatAddr = val; - svga->hwcursor.addr = (val & 0xfffff0) + (svga->hwcursor.yoff * 16); - break; - case Video_hwCurLoc:banshee->hwCurLoc = val; - svga->hwcursor.x = (val & 0x7ff) - 32; - svga->hwcursor.y = ((val >> 16) & 0x7ff) - 64; - if (svga->hwcursor.y < 0) { - svga->hwcursor.yoff = -svga->hwcursor.y; - svga->hwcursor.y = 0; - } else - svga->hwcursor.yoff = 0; - svga->hwcursor.addr = (banshee->hwCurPatAddr & 0xfffff0) + (svga->hwcursor.yoff * 16); - svga->hwcursor.xsize = 64; - svga->hwcursor.ysize = 64; -// pclog("hwCurLoc %08x %i\n", val, svga->hwcursor.y); - break; - case Video_hwCurC0:banshee->hwCurC0 = val; - break; - case Video_hwCurC1:banshee->hwCurC1 = val; - break; + case Video_hwCurPatAddr: + banshee->hwCurPatAddr = val; + svga->hwcursor.addr = (val & 0xfffff0) + (svga->hwcursor.yoff * 16); + break; + case Video_hwCurLoc: + banshee->hwCurLoc = val; + svga->hwcursor.x = (val & 0x7ff) - 32; + svga->hwcursor.y = ((val >> 16) & 0x7ff) - 64; + if (svga->hwcursor.y < 0) { + svga->hwcursor.yoff = -svga->hwcursor.y; + svga->hwcursor.y = 0; + } else + svga->hwcursor.yoff = 0; + svga->hwcursor.addr = (banshee->hwCurPatAddr & 0xfffff0) + (svga->hwcursor.yoff * 16); + svga->hwcursor.xsize = 64; + svga->hwcursor.ysize = 64; + // pclog("hwCurLoc %08x %i\n", val, svga->hwcursor.y); + break; + case Video_hwCurC0: + banshee->hwCurC0 = val; + break; + case Video_hwCurC1: + banshee->hwCurC1 = val; + break; - case Video_vidSerialParallelPort:banshee->vidSerialParallelPort = val; -// pclog("vidSerialParallelPort: write %08x %08x %04x(%08x):%08x\n", val, val & (VIDSERIAL_DDC_DCK_W | VIDSERIAL_DDC_DDA_W), CS,cs,cpu_state.pc); - ddc_i2c_change((val & VIDSERIAL_DDC_DCK_W) ? 1 : 0, (val & VIDSERIAL_DDC_DDA_W) ? 1 : 0); - break; + case Video_vidSerialParallelPort: + banshee->vidSerialParallelPort = val; + // pclog("vidSerialParallelPort: write %08x %08x %04x(%08x):%08x\n", val, val & + // (VIDSERIAL_DDC_DCK_W | VIDSERIAL_DDC_DDA_W), CS,cs,cpu_state.pc); + ddc_i2c_change((val & VIDSERIAL_DDC_DCK_W) ? 1 : 0, (val & VIDSERIAL_DDC_DDA_W) ? 1 : 0); + break; - case Video_vidScreenSize:banshee->vidScreenSize = val; - voodoo->h_disp = (val & 0xfff) + 1; - voodoo->v_disp = (val >> 12) & 0xfff; - break; - case Video_vidOverlayStartCoords:voodoo->overlay.vidOverlayStartCoords = val; - voodoo->overlay.start_x = val & OVERLAY_START_X_MASK; - voodoo->overlay.start_y = (val & OVERLAY_START_Y_MASK) >> OVERLAY_START_Y_SHIFT; - voodoo->overlay.size_x = voodoo->overlay.end_x - voodoo->overlay.start_x; - voodoo->overlay.size_y = voodoo->overlay.end_y - voodoo->overlay.start_y; - svga_recalctimings(svga); - break; - case Video_vidOverlayEndScreenCoords:voodoo->overlay.vidOverlayEndScreenCoords = val; - voodoo->overlay.end_x = val & OVERLAY_END_X_MASK; - voodoo->overlay.end_y = (val & OVERLAY_END_Y_MASK) >> OVERLAY_END_Y_SHIFT; - voodoo->overlay.size_x = (voodoo->overlay.end_x - voodoo->overlay.start_x) + 1; - voodoo->overlay.size_y = (voodoo->overlay.end_y - voodoo->overlay.start_y) + 1; - svga_recalctimings(svga); - break; - case Video_vidOverlayDudx:voodoo->overlay.vidOverlayDudx = val & VID_DUDX_MASK; -// pclog("vidOverlayDudx=%08x\n", val); - break; - case Video_vidOverlayDudxOffsetSrcWidth:voodoo->overlay.vidOverlayDudxOffsetSrcWidth = val; - voodoo->overlay.overlay_bytes = (val & OVERLAY_SRC_WIDTH_MASK) >> OVERLAY_SRC_WIDTH_SHIFT; -// pclog("vidOverlayDudxOffsetSrcWidth=%08x\n", val); - break; - case Video_vidOverlayDvdy:voodoo->overlay.vidOverlayDvdy = val & VID_DVDY_MASK; -// pclog("vidOverlayDvdy=%08x\n", val); - break; - case Video_vidOverlayDvdyOffset:voodoo->overlay.vidOverlayDvdyOffset = val; - break; + case Video_vidScreenSize: + banshee->vidScreenSize = val; + voodoo->h_disp = (val & 0xfff) + 1; + voodoo->v_disp = (val >> 12) & 0xfff; + break; + case Video_vidOverlayStartCoords: + voodoo->overlay.vidOverlayStartCoords = val; + voodoo->overlay.start_x = val & OVERLAY_START_X_MASK; + voodoo->overlay.start_y = (val & OVERLAY_START_Y_MASK) >> OVERLAY_START_Y_SHIFT; + voodoo->overlay.size_x = voodoo->overlay.end_x - voodoo->overlay.start_x; + voodoo->overlay.size_y = voodoo->overlay.end_y - voodoo->overlay.start_y; + svga_recalctimings(svga); + break; + case Video_vidOverlayEndScreenCoords: + voodoo->overlay.vidOverlayEndScreenCoords = val; + voodoo->overlay.end_x = val & OVERLAY_END_X_MASK; + voodoo->overlay.end_y = (val & OVERLAY_END_Y_MASK) >> OVERLAY_END_Y_SHIFT; + voodoo->overlay.size_x = (voodoo->overlay.end_x - voodoo->overlay.start_x) + 1; + voodoo->overlay.size_y = (voodoo->overlay.end_y - voodoo->overlay.start_y) + 1; + svga_recalctimings(svga); + break; + case Video_vidOverlayDudx: + voodoo->overlay.vidOverlayDudx = val & VID_DUDX_MASK; + // pclog("vidOverlayDudx=%08x\n", val); + break; + case Video_vidOverlayDudxOffsetSrcWidth: + voodoo->overlay.vidOverlayDudxOffsetSrcWidth = val; + voodoo->overlay.overlay_bytes = (val & OVERLAY_SRC_WIDTH_MASK) >> OVERLAY_SRC_WIDTH_SHIFT; + // pclog("vidOverlayDudxOffsetSrcWidth=%08x\n", val); + break; + case Video_vidOverlayDvdy: + voodoo->overlay.vidOverlayDvdy = val & VID_DVDY_MASK; + // pclog("vidOverlayDvdy=%08x\n", val); + break; + case Video_vidOverlayDvdyOffset: + voodoo->overlay.vidOverlayDvdyOffset = val; + break; - case Video_vidDesktopStartAddr:banshee->vidDesktopStartAddr = val & 0xffffff; -// pclog("vidDesktopStartAddr=%08x\n", val); - svga->fullchange = changeframecount; - svga_recalctimings(svga); - break; - case Video_vidDesktopOverlayStride:banshee->vidDesktopOverlayStride = val; -// pclog("vidDesktopOverlayStride=%08x\n", val); - svga->fullchange = changeframecount; - svga_recalctimings(svga); - break; -// default: -// fatal("bad banshee_ext_outl: addr=%04x val=%08x\n", addr, val); - } + case Video_vidDesktopStartAddr: + banshee->vidDesktopStartAddr = val & 0xffffff; + // pclog("vidDesktopStartAddr=%08x\n", val); + svga->fullchange = changeframecount; + svga_recalctimings(svga); + break; + case Video_vidDesktopOverlayStride: + banshee->vidDesktopOverlayStride = val; + // pclog("vidDesktopOverlayStride=%08x\n", val); + svga->fullchange = changeframecount; + svga_recalctimings(svga); + break; + // default: + // fatal("bad banshee_ext_outl: addr=%04x val=%08x\n", addr, val); + } } static uint8_t banshee_ext_in(uint16_t addr, void *p) { - banshee_t *banshee = (banshee_t *)p; -// svga_t *svga = &banshee->svga; - uint8_t ret = 0xff; + banshee_t *banshee = (banshee_t *)p; + // svga_t *svga = &banshee->svga; + uint8_t ret = 0xff; - switch (addr & 0xff) { - case Init_status: - case Init_status + 1: - case Init_status + 2: - case Init_status + 3:ret = (banshee_status(banshee) >> ((addr & 3) * 8)) & 0xff; -// pclog("Read status reg! %04x(%08x):%08x\n", CS, cs, cpu_state.pc); - break; + switch (addr & 0xff) { + case Init_status: + case Init_status + 1: + case Init_status + 2: + case Init_status + 3: + ret = (banshee_status(banshee) >> ((addr & 3) * 8)) & 0xff; + // pclog("Read status reg! %04x(%08x):%08x\n", CS, cs, cpu_state.pc); + break; - case 0xb0: - case 0xb1: - case 0xb2: - case 0xb3: - case 0xb4: - case 0xb5: - case 0xb6: - case 0xb7: - case 0xb8: - case 0xb9: - case 0xba: - case 0xbb: - case 0xbc: - case 0xbd: - case 0xbe: - case 0xbf: - case 0xc0: - case 0xc1: - case 0xc2: - case 0xc3: - case 0xc4: - case 0xc5: - case 0xc6: - case 0xc7: - case 0xc8: - case 0xc9: - case 0xca: - case 0xcb: - case 0xcc: - case 0xcd: - case 0xce: - case 0xcf: - case 0xd0: - case 0xd1: - case 0xd2: - case 0xd3: - case 0xd4: - case 0xd5: - case 0xd6: - case 0xd7: - case 0xd8: - case 0xd9: - case 0xda: - case 0xdb: - case 0xdc: - case 0xdd: - case 0xde: - case 0xdf:ret = banshee_in((addr & 0xff) + 0x300, p); - break; + case 0xb0: + case 0xb1: + case 0xb2: + case 0xb3: + case 0xb4: + case 0xb5: + case 0xb6: + case 0xb7: + case 0xb8: + case 0xb9: + case 0xba: + case 0xbb: + case 0xbc: + case 0xbd: + case 0xbe: + case 0xbf: + case 0xc0: + case 0xc1: + case 0xc2: + case 0xc3: + case 0xc4: + case 0xc5: + case 0xc6: + case 0xc7: + case 0xc8: + case 0xc9: + case 0xca: + case 0xcb: + case 0xcc: + case 0xcd: + case 0xce: + case 0xcf: + case 0xd0: + case 0xd1: + case 0xd2: + case 0xd3: + case 0xd4: + case 0xd5: + case 0xd6: + case 0xd7: + case 0xd8: + case 0xd9: + case 0xda: + case 0xdb: + case 0xdc: + case 0xdd: + case 0xde: + case 0xdf: + ret = banshee_in((addr & 0xff) + 0x300, p); + break; - default:pclog("bad banshee_ext_in: addr=%04x\n", addr); - break; - } + default: + pclog("bad banshee_ext_in: addr=%04x\n", addr); + break; + } -// pclog("banshee_ext_in: addr=%04x val=%02x\n", addr, ret); + // pclog("banshee_ext_in: addr=%04x val=%02x\n", addr, ret); - return ret; + return ret; } static uint32_t banshee_status(banshee_t *banshee) { - voodoo_t *voodoo = banshee->voodoo; - svga_t *svga = &banshee->svga; - int fifo_entries = FIFO_ENTRIES; - int fifo_size = 0xffff - fifo_entries; - int swap_count = voodoo->swap_count; - int written = voodoo->cmd_written + voodoo->cmd_written_fifo; - int busy = (written - voodoo->cmd_read) || (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr) || - voodoo->render_voodoo_busy[0] || voodoo->render_voodoo_busy[1] || - voodoo->render_voodoo_busy[2] || voodoo->render_voodoo_busy[3] || - voodoo->voodoo_busy; - uint32_t ret; + voodoo_t *voodoo = banshee->voodoo; + svga_t *svga = &banshee->svga; + int fifo_entries = FIFO_ENTRIES; + int fifo_size = 0xffff - fifo_entries; + int swap_count = voodoo->swap_count; + int written = voodoo->cmd_written + voodoo->cmd_written_fifo; + int busy = (written - voodoo->cmd_read) || (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr) || + voodoo->render_voodoo_busy[0] || voodoo->render_voodoo_busy[1] || voodoo->render_voodoo_busy[2] || + voodoo->render_voodoo_busy[3] || voodoo->voodoo_busy; + uint32_t ret; - ret = 0; - if (fifo_size < 0x20) - ret |= fifo_size; - else - ret |= 0x1f; - if (fifo_size) - ret |= 0x20; - if (swap_count < 7) - ret |= (swap_count << 28); - else - ret |= (7 << 28); - if (!(svga->cgastat & 8)) - ret |= 0x40; + ret = 0; + if (fifo_size < 0x20) + ret |= fifo_size; + else + ret |= 0x1f; + if (fifo_size) + ret |= 0x20; + if (swap_count < 7) + ret |= (swap_count << 28); + else + ret |= (7 << 28); + if (!(svga->cgastat & 8)) + ret |= 0x40; - if (busy) - ret |= 0x780; /*Busy*/ + if (busy) + ret |= 0x780; /*Busy*/ - if (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr) - ret |= (1 << 11); + if (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr) + ret |= (1 << 11); - if (!voodoo->voodoo_busy) - voodoo_wake_fifo_thread(voodoo); + if (!voodoo->voodoo_busy) + voodoo_wake_fifo_thread(voodoo); -// pclog("banshee_status: busy %i %i (%i %i) %i %i %i %04x(%08x):%08x %08x\n", busy, written, voodoo->cmd_written, voodoo->cmd_written_fifo, voodoo->cmd_read, voodoo->cmdfifo_depth_rd, voodoo->cmdfifo_depth_wr, CS,cs,cpu_state.pc, ret); + // pclog("banshee_status: busy %i %i (%i %i) %i %i %i %04x(%08x):%08x %08x\n", busy, written, + // voodoo->cmd_written, voodoo->cmd_written_fifo, voodoo->cmd_read, voodoo->cmdfifo_depth_rd, + // voodoo->cmdfifo_depth_wr, CS,cs,cpu_state.pc, ret); - return ret; + return ret; } static uint32_t banshee_ext_inl(uint16_t addr, void *p) { - banshee_t *banshee = (banshee_t *)p; - voodoo_t *voodoo = banshee->voodoo; - svga_t *svga = &banshee->svga; - uint32_t ret = 0xffffffff; + banshee_t *banshee = (banshee_t *)p; + voodoo_t *voodoo = banshee->voodoo; + svga_t *svga = &banshee->svga; + uint32_t ret = 0xffffffff; - cycles -= voodoo->read_time; + cycles -= voodoo->read_time; - switch (addr & 0xff) { - case Init_status:ret = banshee_status(banshee); -// pclog("Read status reg! %04x(%08x):%08x\n", CS, cs, cpu_state.pc); - break; - case Init_pciInit0:ret = banshee->pciInit0; - break; - case Init_lfbMemoryConfig:ret = banshee->lfbMemoryConfig; - break; + switch (addr & 0xff) { + case Init_status: + ret = banshee_status(banshee); + // pclog("Read status reg! %04x(%08x):%08x\n", CS, cs, cpu_state.pc); + break; + case Init_pciInit0: + ret = banshee->pciInit0; + break; + case Init_lfbMemoryConfig: + ret = banshee->lfbMemoryConfig; + break; - case Init_miscInit0:ret = banshee->miscInit0; - break; - case Init_miscInit1:ret = banshee->miscInit1; - break; - case Init_dramInit0:ret = banshee->dramInit0; - break; - case Init_dramInit1:ret = banshee->dramInit1; - break; - case Init_agpInit0:ret = banshee->agpInit0; - break; + case Init_miscInit0: + ret = banshee->miscInit0; + break; + case Init_miscInit1: + ret = banshee->miscInit1; + break; + case Init_dramInit0: + ret = banshee->dramInit0; + break; + case Init_dramInit1: + ret = banshee->dramInit1; + break; + case Init_agpInit0: + ret = banshee->agpInit0; + break; - case Init_vgaInit0:ret = banshee->vgaInit0; - break; - case Init_vgaInit1:ret = banshee->vgaInit1; - break; + case Init_vgaInit0: + ret = banshee->vgaInit0; + break; + case Init_vgaInit1: + ret = banshee->vgaInit1; + break; - case Init_2dCommand:ret = banshee->command_2d; - break; - case Init_2dSrcBaseAddr:ret = banshee->srcBaseAddr_2d; - break; - case Init_strapInfo:ret = 0x00000040; /*8 MB SGRAM, PCI, IRQ enabled, 32kB BIOS*/ - break; + case Init_2dCommand: + ret = banshee->command_2d; + break; + case Init_2dSrcBaseAddr: + ret = banshee->srcBaseAddr_2d; + break; + case Init_strapInfo: + ret = 0x00000040; /*8 MB SGRAM, PCI, IRQ enabled, 32kB BIOS*/ + break; - case PLL_pllCtrl0:ret = banshee->pllCtrl0; - break; - case PLL_pllCtrl1:ret = banshee->pllCtrl1; - break; - case PLL_pllCtrl2:ret = banshee->pllCtrl2; - break; + case PLL_pllCtrl0: + ret = banshee->pllCtrl0; + break; + case PLL_pllCtrl1: + ret = banshee->pllCtrl1; + break; + case PLL_pllCtrl2: + ret = banshee->pllCtrl2; + break; - case DAC_dacMode:ret = banshee->dacMode; - break; - case DAC_dacAddr:ret = banshee->dacAddr; - break; - case DAC_dacData:ret = svga->pallook[banshee->dacAddr]; - break; + case DAC_dacMode: + ret = banshee->dacMode; + break; + case DAC_dacAddr: + ret = banshee->dacAddr; + break; + case DAC_dacData: + ret = svga->pallook[banshee->dacAddr]; + break; - case Video_vidProcCfg:ret = banshee->vidProcCfg; - break; + case Video_vidProcCfg: + ret = banshee->vidProcCfg; + break; - case Video_hwCurPatAddr:ret = banshee->hwCurPatAddr; - break; - case Video_hwCurLoc:ret = banshee->hwCurLoc; - break; - case Video_hwCurC0:ret = banshee->hwCurC0; - break; - case Video_hwCurC1:ret = banshee->hwCurC1; - break; + case Video_hwCurPatAddr: + ret = banshee->hwCurPatAddr; + break; + case Video_hwCurLoc: + ret = banshee->hwCurLoc; + break; + case Video_hwCurC0: + ret = banshee->hwCurC0; + break; + case Video_hwCurC1: + ret = banshee->hwCurC1; + break; - case Video_vidSerialParallelPort:ret = banshee->vidSerialParallelPort & ~(VIDSERIAL_DDC_DCK_R | VIDSERIAL_DDC_DDA_R); - if ((banshee->vidSerialParallelPort & VIDSERIAL_DDC_DCK_W) && ddc_read_clock()) - ret |= VIDSERIAL_DDC_DCK_R; - if ((banshee->vidSerialParallelPort & VIDSERIAL_DDC_DDA_W) && ddc_read_data()) - ret |= VIDSERIAL_DDC_DDA_R; - ret = ret & ~(VIDSERIAL_I2C_SCK_R | VIDSERIAL_I2C_SDA_R); - if (banshee->vidSerialParallelPort & VIDSERIAL_I2C_SCK_W) - ret |= VIDSERIAL_I2C_SCK_R; - if (banshee->vidSerialParallelPort & VIDSERIAL_I2C_SDA_W) - ret |= VIDSERIAL_I2C_SDA_R; -// pclog("vidSerialParallelPort: read %08x %08x %04x(%08x):%08x\n", ret, ret & (VIDSERIAL_DDC_DCK_R | VIDSERIAL_DDC_DDA_R), CS,cs,cpu_state.pc); - break; + case Video_vidSerialParallelPort: + ret = banshee->vidSerialParallelPort & ~(VIDSERIAL_DDC_DCK_R | VIDSERIAL_DDC_DDA_R); + if ((banshee->vidSerialParallelPort & VIDSERIAL_DDC_DCK_W) && ddc_read_clock()) + ret |= VIDSERIAL_DDC_DCK_R; + if ((banshee->vidSerialParallelPort & VIDSERIAL_DDC_DDA_W) && ddc_read_data()) + ret |= VIDSERIAL_DDC_DDA_R; + ret = ret & ~(VIDSERIAL_I2C_SCK_R | VIDSERIAL_I2C_SDA_R); + if (banshee->vidSerialParallelPort & VIDSERIAL_I2C_SCK_W) + ret |= VIDSERIAL_I2C_SCK_R; + if (banshee->vidSerialParallelPort & VIDSERIAL_I2C_SDA_W) + ret |= VIDSERIAL_I2C_SDA_R; + // pclog("vidSerialParallelPort: read %08x %08x %04x(%08x):%08x\n", ret, ret & + // (VIDSERIAL_DDC_DCK_R | VIDSERIAL_DDC_DDA_R), CS,cs,cpu_state.pc); + break; - case Video_vidScreenSize:ret = banshee->vidScreenSize; - break; - case Video_vidOverlayStartCoords:ret = voodoo->overlay.vidOverlayStartCoords; - break; - case Video_vidOverlayEndScreenCoords:ret = voodoo->overlay.vidOverlayEndScreenCoords; - break; - case Video_vidOverlayDudx:ret = voodoo->overlay.vidOverlayDudx; - break; - case Video_vidOverlayDudxOffsetSrcWidth:ret = voodoo->overlay.vidOverlayDudxOffsetSrcWidth; - break; - case Video_vidOverlayDvdy:ret = voodoo->overlay.vidOverlayDvdy; - break; - case Video_vidOverlayDvdyOffset:ret = voodoo->overlay.vidOverlayDvdyOffset; - break; + case Video_vidScreenSize: + ret = banshee->vidScreenSize; + break; + case Video_vidOverlayStartCoords: + ret = voodoo->overlay.vidOverlayStartCoords; + break; + case Video_vidOverlayEndScreenCoords: + ret = voodoo->overlay.vidOverlayEndScreenCoords; + break; + case Video_vidOverlayDudx: + ret = voodoo->overlay.vidOverlayDudx; + break; + case Video_vidOverlayDudxOffsetSrcWidth: + ret = voodoo->overlay.vidOverlayDudxOffsetSrcWidth; + break; + case Video_vidOverlayDvdy: + ret = voodoo->overlay.vidOverlayDvdy; + break; + case Video_vidOverlayDvdyOffset: + ret = voodoo->overlay.vidOverlayDvdyOffset; + break; - case Video_vidDesktopStartAddr:ret = banshee->vidDesktopStartAddr; - break; - case Video_vidDesktopOverlayStride:ret = banshee->vidDesktopOverlayStride; - break; + case Video_vidDesktopStartAddr: + ret = banshee->vidDesktopStartAddr; + break; + case Video_vidDesktopOverlayStride: + ret = banshee->vidDesktopOverlayStride; + break; - default: -// fatal("bad banshee_ext_inl: addr=%04x\n", addr); - break; - } + default: + // fatal("bad banshee_ext_inl: addr=%04x\n", addr); + break; + } -// /*if (addr) */pclog("banshee_ext_inl: addr=%04x val=%08x\n", addr, ret); + // /*if (addr) */pclog("banshee_ext_inl: addr=%04x val=%08x\n", addr, ret); - return ret; + return ret; } static uint32_t banshee_reg_readl(uint32_t addr, void *p); static uint8_t banshee_reg_read(uint32_t addr, void *p) { -// pclog("banshee_reg_read: addr=%08x\n", addr); - return banshee_reg_readl(addr & ~3, p) >> (8 * (addr & 3)); + // pclog("banshee_reg_read: addr=%08x\n", addr); + return banshee_reg_readl(addr & ~3, p) >> (8 * (addr & 3)); } static uint16_t banshee_reg_readw(uint32_t addr, void *p) { -// pclog("banshee_reg_readw: addr=%08x\n", addr); - return banshee_reg_readl(addr & ~3, p) >> (8 * (addr & 2)); + // pclog("banshee_reg_readw: addr=%08x\n", addr); + return banshee_reg_readl(addr & ~3, p) >> (8 * (addr & 2)); } static uint32_t banshee_cmd_read(banshee_t *banshee, uint32_t addr) { - voodoo_t *voodoo = banshee->voodoo; - uint32_t ret = 0xffffffff; + voodoo_t *voodoo = banshee->voodoo; + uint32_t ret = 0xffffffff; - switch (addr & 0x1fc) { - case cmdBaseAddr0:ret = voodoo->cmdfifo_base >> 12; -// pclog("Read cmdfifo_base %08x\n", ret); - break; + switch (addr & 0x1fc) { + case cmdBaseAddr0: + ret = voodoo->cmdfifo_base >> 12; + // pclog("Read cmdfifo_base %08x\n", ret); + break; - case cmdRdPtrL0:ret = voodoo->cmdfifo_rp; -// pclog("Read cmdfifo_rp %08x\n", ret); - break; + case cmdRdPtrL0: + ret = voodoo->cmdfifo_rp; + // pclog("Read cmdfifo_rp %08x\n", ret); + break; - case cmdFifoDepth0:ret = voodoo->cmdfifo_depth_wr - voodoo->cmdfifo_depth_rd; -// pclog("Read cmdfifo_depth %08x\n", ret); - break; + case cmdFifoDepth0: + ret = voodoo->cmdfifo_depth_wr - voodoo->cmdfifo_depth_rd; + // pclog("Read cmdfifo_depth %08x\n", ret); + break; - case 0x108:break; + case 0x108: + break; #ifndef RELEASE_BUILD - default:fatal("Unknown banshee_cmd_read %08x\n", addr); + default: + fatal("Unknown banshee_cmd_read %08x\n", addr); #endif - } + } - return ret; + return ret; } static uint32_t banshee_reg_readl(uint32_t addr, void *p) { - banshee_t *banshee = (banshee_t *)p; - voodoo_t *voodoo = banshee->voodoo; - uint32_t ret = 0xffffffff; + banshee_t *banshee = (banshee_t *)p; + voodoo_t *voodoo = banshee->voodoo; + uint32_t ret = 0xffffffff; - cycles -= voodoo->read_time; + cycles -= voodoo->read_time; - switch (addr & 0x1f00000) { - case 0x0000000: /*IO remap*/ - if (!(addr & 0x80000)) - ret = banshee_ext_inl(addr & 0xff, banshee); - else - ret = banshee_cmd_read(banshee, addr); - break; + switch (addr & 0x1f00000) { + case 0x0000000: /*IO remap*/ + if (!(addr & 0x80000)) + ret = banshee_ext_inl(addr & 0xff, banshee); + else + ret = banshee_cmd_read(banshee, addr); + break; - case 0x0100000: /*2D registers*/ - voodoo_flush(voodoo); - switch (addr & 0x1fc) { - case 0x08:ret = voodoo->banshee_blt.clip0Min; - break; - case 0x0c:ret = voodoo->banshee_blt.clip0Max; - break; - case 0x10:ret = voodoo->banshee_blt.dstBaseAddr; - break; - case 0x14:ret = voodoo->banshee_blt.dstFormat; - break; - case 0x34:ret = voodoo->banshee_blt.srcBaseAddr; - break; - case 0x38:ret = voodoo->banshee_blt.commandExtra; - break; - case 0x5c:ret = voodoo->banshee_blt.srcXY; - break; - case 0x60:ret = voodoo->banshee_blt.colorBack; - break; - case 0x64:ret = voodoo->banshee_blt.colorFore; - break; - case 0x68:ret = voodoo->banshee_blt.dstSize; - break; - case 0x6c:ret = voodoo->banshee_blt.dstXY; - break; - case 0x70:ret = voodoo->banshee_blt.command; - break; - default:pclog("banshee_reg_readl: addr=%08x\n", addr); - } - break; + case 0x0100000: /*2D registers*/ + voodoo_flush(voodoo); + switch (addr & 0x1fc) { + case 0x08: + ret = voodoo->banshee_blt.clip0Min; + break; + case 0x0c: + ret = voodoo->banshee_blt.clip0Max; + break; + case 0x10: + ret = voodoo->banshee_blt.dstBaseAddr; + break; + case 0x14: + ret = voodoo->banshee_blt.dstFormat; + break; + case 0x34: + ret = voodoo->banshee_blt.srcBaseAddr; + break; + case 0x38: + ret = voodoo->banshee_blt.commandExtra; + break; + case 0x5c: + ret = voodoo->banshee_blt.srcXY; + break; + case 0x60: + ret = voodoo->banshee_blt.colorBack; + break; + case 0x64: + ret = voodoo->banshee_blt.colorFore; + break; + case 0x68: + ret = voodoo->banshee_blt.dstSize; + break; + case 0x6c: + ret = voodoo->banshee_blt.dstXY; + break; + case 0x70: + ret = voodoo->banshee_blt.command; + break; + default: + pclog("banshee_reg_readl: addr=%08x\n", addr); + } + break; - case 0x0200000: - case 0x0300000: - case 0x0400000: - case 0x0500000: /*3D registers*/ - switch (addr & 0x3fc) { - case SST_status:ret = banshee_status(banshee); - break; + case 0x0200000: + case 0x0300000: + case 0x0400000: + case 0x0500000: /*3D registers*/ + switch (addr & 0x3fc) { + case SST_status: + ret = banshee_status(banshee); + break; - case SST_intrCtrl:ret = banshee->intrCtrl & 0x0030003f; - break; + case SST_intrCtrl: + ret = banshee->intrCtrl & 0x0030003f; + break; - case SST_fbzColorPath:voodoo_flush(voodoo); - ret = voodoo->params.fbzColorPath; - break; - case SST_fogMode:voodoo_flush(voodoo); - ret = voodoo->params.fogMode; - break; - case SST_alphaMode:voodoo_flush(voodoo); - ret = voodoo->params.alphaMode; - break; - case SST_fbzMode:voodoo_flush(voodoo); - ret = voodoo->params.fbzMode; - break; - case SST_lfbMode:voodoo_flush(voodoo); - ret = voodoo->lfbMode; - break; - case SST_clipLeftRight:ret = voodoo->params.clipRight | (voodoo->params.clipLeft << 16); - break; - case SST_clipLowYHighY:ret = voodoo->params.clipHighY | (voodoo->params.clipLowY << 16); - break; + case SST_fbzColorPath: + voodoo_flush(voodoo); + ret = voodoo->params.fbzColorPath; + break; + case SST_fogMode: + voodoo_flush(voodoo); + ret = voodoo->params.fogMode; + break; + case SST_alphaMode: + voodoo_flush(voodoo); + ret = voodoo->params.alphaMode; + break; + case SST_fbzMode: + voodoo_flush(voodoo); + ret = voodoo->params.fbzMode; + break; + case SST_lfbMode: + voodoo_flush(voodoo); + ret = voodoo->lfbMode; + break; + case SST_clipLeftRight: + ret = voodoo->params.clipRight | (voodoo->params.clipLeft << 16); + break; + case SST_clipLowYHighY: + ret = voodoo->params.clipHighY | (voodoo->params.clipLowY << 16); + break; - case SST_clipLeftRight1:ret = voodoo->params.clipRight1 | (voodoo->params.clipLeft1 << 16); - break; - case SST_clipTopBottom1:ret = voodoo->params.clipHighY1 | (voodoo->params.clipLowY1 << 16); - break; + case SST_clipLeftRight1: + ret = voodoo->params.clipRight1 | (voodoo->params.clipLeft1 << 16); + break; + case SST_clipTopBottom1: + ret = voodoo->params.clipHighY1 | (voodoo->params.clipLowY1 << 16); + break; - case SST_stipple:voodoo_flush(voodoo); - ret = voodoo->params.stipple; - break; - case SST_color0:voodoo_flush(voodoo); - ret = voodoo->params.color0; - break; - case SST_color1:voodoo_flush(voodoo); - ret = voodoo->params.color1; - break; + case SST_stipple: + voodoo_flush(voodoo); + ret = voodoo->params.stipple; + break; + case SST_color0: + voodoo_flush(voodoo); + ret = voodoo->params.color0; + break; + case SST_color1: + voodoo_flush(voodoo); + ret = voodoo->params.color1; + break; - case SST_fbiPixelsIn:ret = voodoo->fbiPixelsIn & 0xffffff; - break; - case SST_fbiChromaFail:ret = voodoo->fbiChromaFail & 0xffffff; - break; - case SST_fbiZFuncFail:ret = voodoo->fbiZFuncFail & 0xffffff; - break; - case SST_fbiAFuncFail:ret = voodoo->fbiAFuncFail & 0xffffff; - break; - case SST_fbiPixelsOut:ret = voodoo->fbiPixelsOut & 0xffffff; - break; + case SST_fbiPixelsIn: + ret = voodoo->fbiPixelsIn & 0xffffff; + break; + case SST_fbiChromaFail: + ret = voodoo->fbiChromaFail & 0xffffff; + break; + case SST_fbiZFuncFail: + ret = voodoo->fbiZFuncFail & 0xffffff; + break; + case SST_fbiAFuncFail: + ret = voodoo->fbiAFuncFail & 0xffffff; + break; + case SST_fbiPixelsOut: + ret = voodoo->fbiPixelsOut & 0xffffff; + break; - default:pclog("banshee_reg_readl: 3D addr=%08x\n", addr); - break; - } - break; - } + default: + pclog("banshee_reg_readl: 3D addr=%08x\n", addr); + break; + } + break; + } -// /*if (addr != 0xe0000000) */pclog("banshee_reg_readl: addr=%08x ret=%08x %04x(%08x):%08x\n", addr, ret, CS,cs,cpu_state.pc); -// if (cpu_state.pc == 0x1000e437) -// output = 3; - return ret; + // /*if (addr != 0xe0000000) */pclog("banshee_reg_readl: addr=%08x ret=%08x %04x(%08x):%08x\n", addr, ret, + // CS,cs,cpu_state.pc); if (cpu_state.pc == 0x1000e437) + // output = 3; + return ret; } static void banshee_reg_write(uint32_t addr, uint8_t val, void *p) { -// pclog("banshee_reg_writeb: addr=%08x val=%02x\n", addr, val); + // pclog("banshee_reg_writeb: addr=%08x val=%02x\n", addr, val); } static void banshee_reg_writew(uint32_t addr, uint16_t val, void *p) { - banshee_t *banshee = (banshee_t *)p; - voodoo_t *voodoo = banshee->voodoo; + banshee_t *banshee = (banshee_t *)p; + voodoo_t *voodoo = banshee->voodoo; - cycles -= voodoo->write_time; + cycles -= voodoo->write_time; -// pclog("banshee_reg_writew: addr=%08x val=%04x\n", addr, val); - switch (addr & 0x1f00000) { - case 0x1000000: - case 0x1100000: - case 0x1200000: - case 0x1300000: /*3D LFB*/ - case 0x1400000: - case 0x1500000: - case 0x1600000: - case 0x1700000: - case 0x1800000: - case 0x1900000: - case 0x1a00000: - case 0x1b00000: - case 0x1c00000: - case 0x1d00000: - case 0x1e00000: - case 0x1f00000:voodoo_queue_command(voodoo, (addr & 0xffffff) | FIFO_WRITEW_FB, val); - break; - } + // pclog("banshee_reg_writew: addr=%08x val=%04x\n", addr, val); + switch (addr & 0x1f00000) { + case 0x1000000: + case 0x1100000: + case 0x1200000: + case 0x1300000: /*3D LFB*/ + case 0x1400000: + case 0x1500000: + case 0x1600000: + case 0x1700000: + case 0x1800000: + case 0x1900000: + case 0x1a00000: + case 0x1b00000: + case 0x1c00000: + case 0x1d00000: + case 0x1e00000: + case 0x1f00000: + voodoo_queue_command(voodoo, (addr & 0xffffff) | FIFO_WRITEW_FB, val); + break; + } } static void banshee_cmd_write(banshee_t *banshee, uint32_t addr, uint32_t val) { - voodoo_t *voodoo = banshee->voodoo; -// pclog("banshee_cmd_write: addr=%03x val=%08x\n", addr & 0x1fc, val); - switch (addr & 0x1fc) { - case cmdBaseAddr0:voodoo->cmdfifo_base = (val & 0xfff) << 12; - voodoo->cmdfifo_end = voodoo->cmdfifo_base + (((voodoo->cmdfifo_size & 0xff) + 1) << 12); -// pclog("cmdfifo_base=%08x cmdfifo_end=%08x %08x\n", voodoo->cmdfifo_base, voodoo->cmdfifo_end, val); - break; + voodoo_t *voodoo = banshee->voodoo; + // pclog("banshee_cmd_write: addr=%03x val=%08x\n", addr & 0x1fc, val); + switch (addr & 0x1fc) { + case cmdBaseAddr0: + voodoo->cmdfifo_base = (val & 0xfff) << 12; + voodoo->cmdfifo_end = voodoo->cmdfifo_base + (((voodoo->cmdfifo_size & 0xff) + 1) << 12); + // pclog("cmdfifo_base=%08x cmdfifo_end=%08x %08x\n", voodoo->cmdfifo_base, voodoo->cmdfifo_end, + // val); + break; - case cmdBaseSize0:voodoo->cmdfifo_size = val; - voodoo->cmdfifo_end = voodoo->cmdfifo_base + (((voodoo->cmdfifo_size & 0xff) + 1) << 12); - voodoo->cmdfifo_enabled = val & 0x100; - if (!voodoo->cmdfifo_enabled) - voodoo->cmdfifo_in_sub = 0; /*Not sure exactly when this should be reset*/ -// pclog("cmdfifo_base=%08x cmdfifo_end=%08x\n", voodoo->cmdfifo_base, voodoo->cmdfifo_end); - break; + case cmdBaseSize0: + voodoo->cmdfifo_size = val; + voodoo->cmdfifo_end = voodoo->cmdfifo_base + (((voodoo->cmdfifo_size & 0xff) + 1) << 12); + voodoo->cmdfifo_enabled = val & 0x100; + if (!voodoo->cmdfifo_enabled) + voodoo->cmdfifo_in_sub = 0; /*Not sure exactly when this should be reset*/ + // pclog("cmdfifo_base=%08x cmdfifo_end=%08x\n", voodoo->cmdfifo_base, voodoo->cmdfifo_end); + break; -// voodoo->cmdfifo_end = ((val >> 16) & 0x3ff) << 12; -// pclog("CMDFIFO base=%08x end=%08x\n", voodoo->cmdfifo_base, voodoo->cmdfifo_end); -// break; + // voodoo->cmdfifo_end = ((val >> 16) & 0x3ff) << 12; + // pclog("CMDFIFO base=%08x end=%08x\n", voodoo->cmdfifo_base, voodoo->cmdfifo_end); + // break; - case cmdRdPtrL0:voodoo->cmdfifo_rp = val; - break; - case cmdAMin0:voodoo->cmdfifo_amin = val; - break; - case cmdAMax0:voodoo->cmdfifo_amax = val; - break; - case cmdFifoDepth0:voodoo->cmdfifo_depth_rd = 0; - voodoo->cmdfifo_depth_wr = val & 0xffff; - break; + case cmdRdPtrL0: + voodoo->cmdfifo_rp = val; + break; + case cmdAMin0: + voodoo->cmdfifo_amin = val; + break; + case cmdAMax0: + voodoo->cmdfifo_amax = val; + break; + case cmdFifoDepth0: + voodoo->cmdfifo_depth_rd = 0; + voodoo->cmdfifo_depth_wr = val & 0xffff; + break; - default:pclog("Unknown banshee_cmd_write: addr=%08x val=%08x\n", addr, val); - break; - } + default: + pclog("Unknown banshee_cmd_write: addr=%08x val=%08x\n", addr, val); + break; + } -/* cmdBaseSize0 = 0x24, - cmdBump0 = 0x28, - cmdRdPtrL0 = 0x2c, - cmdRdPtrH0 = 0x30, - cmdAMin0 = 0x34, - cmdAMax0 = 0x3c, - cmdFifoDepth0 = 0x44, - cmdHoleCnt0 = 0x48 - }*/ + /* cmdBaseSize0 = 0x24, + cmdBump0 = 0x28, + cmdRdPtrL0 = 0x2c, + cmdRdPtrH0 = 0x30, + cmdAMin0 = 0x34, + cmdAMax0 = 0x3c, + cmdFifoDepth0 = 0x44, + cmdHoleCnt0 = 0x48 + }*/ } static void banshee_reg_writel(uint32_t addr, uint32_t val, void *p) { - banshee_t *banshee = (banshee_t *)p; - voodoo_t *voodoo = banshee->voodoo; + banshee_t *banshee = (banshee_t *)p; + voodoo_t *voodoo = banshee->voodoo; - if (addr == voodoo->last_write_addr + 4) - cycles -= voodoo->burst_time; - else - cycles -= voodoo->write_time; - voodoo->last_write_addr = addr; + if (addr == voodoo->last_write_addr + 4) + cycles -= voodoo->burst_time; + else + cycles -= voodoo->write_time; + voodoo->last_write_addr = addr; -// pclog("banshee_reg_writel: addr=%08x val=%08x\n", addr, val); + // pclog("banshee_reg_writel: addr=%08x val=%08x\n", addr, val); - switch (addr & 0x1f00000) { - case 0x0000000: /*IO remap*/ - if (!(addr & 0x80000)) - banshee_ext_outl(addr & 0xff, val, banshee); - else - banshee_cmd_write(banshee, addr, val); -// pclog("CMD!!! write %08x %08x\n", addr, val); - break; + switch (addr & 0x1f00000) { + case 0x0000000: /*IO remap*/ + if (!(addr & 0x80000)) + banshee_ext_outl(addr & 0xff, val, banshee); + else + banshee_cmd_write(banshee, addr, val); + // pclog("CMD!!! write %08x %08x\n", addr, val); + break; - case 0x0100000: /*2D registers*/ - voodoo_queue_command(voodoo, (addr & 0x1fc) | FIFO_WRITEL_2DREG, val); - break; + case 0x0100000: /*2D registers*/ + voodoo_queue_command(voodoo, (addr & 0x1fc) | FIFO_WRITEL_2DREG, val); + break; - case 0x0200000: - case 0x0300000: - case 0x0400000: - case 0x0500000: /*3D registers*/ - switch (addr & 0x3fc) { - case SST_intrCtrl:banshee->intrCtrl = val & 0x0030003f; -// pclog("intrCtrl=%08x\n", val); - break; + case 0x0200000: + case 0x0300000: + case 0x0400000: + case 0x0500000: /*3D registers*/ + switch (addr & 0x3fc) { + case SST_intrCtrl: + banshee->intrCtrl = val & 0x0030003f; + // pclog("intrCtrl=%08x\n", val); + break; - case SST_userIntrCMD: + case SST_userIntrCMD: #ifndef RELEASE_BUILD - fatal("userIntrCMD write %08x\n", val); + fatal("userIntrCMD write %08x\n", val); #endif - break; + break; - case SST_swapbufferCMD:voodoo->cmd_written++; - voodoo_queue_command(voodoo, (addr & 0x3fc) | FIFO_WRITEL_REG, val); - if (!voodoo->voodoo_busy) - voodoo_wake_fifo_threads(voodoo->set, voodoo); -// pclog("SST_swapbufferCMD write: %i %i\n", voodoo->cmd_written, voodoo->cmd_written_fifo); - break; - case SST_triangleCMD:voodoo->cmd_written++; - voodoo_queue_command(voodoo, (addr & 0x3fc) | FIFO_WRITEL_REG, val); - if (!voodoo->voodoo_busy) - voodoo_wake_fifo_threads(voodoo->set, voodoo); - break; - case SST_ftriangleCMD:voodoo->cmd_written++; - voodoo_queue_command(voodoo, (addr & 0x3fc) | FIFO_WRITEL_REG, val); - if (!voodoo->voodoo_busy) - voodoo_wake_fifo_threads(voodoo->set, voodoo); - break; - case SST_fastfillCMD:voodoo->cmd_written++; - voodoo_queue_command(voodoo, (addr & 0x3fc) | FIFO_WRITEL_REG, val); - if (!voodoo->voodoo_busy) - voodoo_wake_fifo_threads(voodoo->set, voodoo); - break; - case SST_nopCMD:voodoo->cmd_written++; - voodoo_queue_command(voodoo, (addr & 0x3fc) | FIFO_WRITEL_REG, val); - if (!voodoo->voodoo_busy) - voodoo_wake_fifo_threads(voodoo->set, voodoo); - break; + case SST_swapbufferCMD: + voodoo->cmd_written++; + voodoo_queue_command(voodoo, (addr & 0x3fc) | FIFO_WRITEL_REG, val); + if (!voodoo->voodoo_busy) + voodoo_wake_fifo_threads(voodoo->set, voodoo); + // pclog("SST_swapbufferCMD write: %i %i\n", voodoo->cmd_written, + // voodoo->cmd_written_fifo); + break; + case SST_triangleCMD: + voodoo->cmd_written++; + voodoo_queue_command(voodoo, (addr & 0x3fc) | FIFO_WRITEL_REG, val); + if (!voodoo->voodoo_busy) + voodoo_wake_fifo_threads(voodoo->set, voodoo); + break; + case SST_ftriangleCMD: + voodoo->cmd_written++; + voodoo_queue_command(voodoo, (addr & 0x3fc) | FIFO_WRITEL_REG, val); + if (!voodoo->voodoo_busy) + voodoo_wake_fifo_threads(voodoo->set, voodoo); + break; + case SST_fastfillCMD: + voodoo->cmd_written++; + voodoo_queue_command(voodoo, (addr & 0x3fc) | FIFO_WRITEL_REG, val); + if (!voodoo->voodoo_busy) + voodoo_wake_fifo_threads(voodoo->set, voodoo); + break; + case SST_nopCMD: + voodoo->cmd_written++; + voodoo_queue_command(voodoo, (addr & 0x3fc) | FIFO_WRITEL_REG, val); + if (!voodoo->voodoo_busy) + voodoo_wake_fifo_threads(voodoo->set, voodoo); + break; - case SST_swapPending:thread_lock_mutex(voodoo->swap_mutex); - voodoo->swap_count++; - thread_unlock_mutex(voodoo->swap_mutex); -// voodoo->cmd_written++; - break; + case SST_swapPending: + thread_lock_mutex(voodoo->swap_mutex); + voodoo->swap_count++; + thread_unlock_mutex(voodoo->swap_mutex); + // voodoo->cmd_written++; + break; - default:voodoo_queue_command(voodoo, (addr & 0x3ffffc) | FIFO_WRITEL_REG, val); - break; - } - break; + default: + voodoo_queue_command(voodoo, (addr & 0x3ffffc) | FIFO_WRITEL_REG, val); + break; + } + break; - case 0x0600000: - case 0x0700000: /*Texture download*/ - voodoo->tex_count++; - voodoo_queue_command(voodoo, (addr & 0x1ffffc) | FIFO_WRITEL_TEX, val); - break; + case 0x0600000: + case 0x0700000: /*Texture download*/ + voodoo->tex_count++; + voodoo_queue_command(voodoo, (addr & 0x1ffffc) | FIFO_WRITEL_TEX, val); + break; - case 0x1000000: - case 0x1100000: - case 0x1200000: - case 0x1300000: /*3D LFB*/ - case 0x1400000: - case 0x1500000: - case 0x1600000: - case 0x1700000: - case 0x1800000: - case 0x1900000: - case 0x1a00000: - case 0x1b00000: - case 0x1c00000: - case 0x1d00000: - case 0x1e00000: - case 0x1f00000:voodoo_queue_command(voodoo, (addr & 0xfffffc) | FIFO_WRITEL_FB, val); - break; - } + case 0x1000000: + case 0x1100000: + case 0x1200000: + case 0x1300000: /*3D LFB*/ + case 0x1400000: + case 0x1500000: + case 0x1600000: + case 0x1700000: + case 0x1800000: + case 0x1900000: + case 0x1a00000: + case 0x1b00000: + case 0x1c00000: + case 0x1d00000: + case 0x1e00000: + case 0x1f00000: + voodoo_queue_command(voodoo, (addr & 0xfffffc) | FIFO_WRITEL_FB, val); + break; + } } static uint8_t banshee_read_linear(uint32_t addr, void *p) { - banshee_t *banshee = (banshee_t *)p; - voodoo_t *voodoo = banshee->voodoo; - svga_t *svga = &banshee->svga; + banshee_t *banshee = (banshee_t *)p; + voodoo_t *voodoo = banshee->voodoo; + svga_t *svga = &banshee->svga; - cycles -= voodoo->read_time; - cycles_lost += voodoo->read_time; + cycles -= voodoo->read_time; + cycles_lost += voodoo->read_time; - addr &= svga->decode_mask; - if (addr >= voodoo->tile_base) { - int x, y; + addr &= svga->decode_mask; + if (addr >= voodoo->tile_base) { + int x, y; - addr -= voodoo->tile_base; - x = addr & (voodoo->tile_stride - 1); - y = addr >> voodoo->tile_stride_shift; + addr -= voodoo->tile_base; + x = addr & (voodoo->tile_stride - 1); + y = addr >> voodoo->tile_stride_shift; - addr = voodoo->tile_base + (x & 127) + ((x >> 7) * 128 * 32) + ((y & 31) * 128) + (y >> 5) * voodoo->tile_x_real; -// pclog(" Tile rb %08x->%08x %i %i\n", old_addr, addr, x, y); - } - if (addr >= svga->vram_max) - return 0xff; + addr = voodoo->tile_base + (x & 127) + ((x >> 7) * 128 * 32) + ((y & 31) * 128) + (y >> 5) * voodoo->tile_x_real; + // pclog(" Tile rb %08x->%08x %i %i\n", old_addr, addr, x, y); + } + if (addr >= svga->vram_max) + return 0xff; - egareads++; - cycles -= video_timing_read_b; - cycles_lost += video_timing_read_b; + egareads++; + cycles -= video_timing_read_b; + cycles_lost += video_timing_read_b; -// pclog("read_linear: addr=%08x val=%02x\n", addr, svga->vram[addr & svga->vram_mask]); + // pclog("read_linear: addr=%08x val=%02x\n", addr, svga->vram[addr & svga->vram_mask]); - return svga->vram[addr & svga->vram_mask]; + return svga->vram[addr & svga->vram_mask]; } static uint16_t banshee_read_linear_w(uint32_t addr, void *p) { - banshee_t *banshee = (banshee_t *)p; - voodoo_t *voodoo = banshee->voodoo; - svga_t *svga = &banshee->svga; + banshee_t *banshee = (banshee_t *)p; + voodoo_t *voodoo = banshee->voodoo; + svga_t *svga = &banshee->svga; - if (addr & 1) - return banshee_read_linear(addr, p) | (banshee_read_linear(addr + 1, p) << 8); + if (addr & 1) + return banshee_read_linear(addr, p) | (banshee_read_linear(addr + 1, p) << 8); - cycles -= voodoo->read_time; - cycles_lost += voodoo->read_time; + cycles -= voodoo->read_time; + cycles_lost += voodoo->read_time; - addr &= svga->decode_mask; - if (addr >= voodoo->tile_base) { - int x, y; + addr &= svga->decode_mask; + if (addr >= voodoo->tile_base) { + int x, y; - addr -= voodoo->tile_base; - x = addr & (voodoo->tile_stride - 1); - y = addr >> voodoo->tile_stride_shift; + addr -= voodoo->tile_base; + x = addr & (voodoo->tile_stride - 1); + y = addr >> voodoo->tile_stride_shift; - addr = voodoo->tile_base + (x & 127) + ((x >> 7) * 128 * 32) + ((y & 31) * 128) + (y >> 5) * voodoo->tile_x_real; -// pclog(" Tile rb %08x->%08x %i %i\n", old_addr, addr, x, y); - } - if (addr >= svga->vram_max) - return 0xff; + addr = voodoo->tile_base + (x & 127) + ((x >> 7) * 128 * 32) + ((y & 31) * 128) + (y >> 5) * voodoo->tile_x_real; + // pclog(" Tile rb %08x->%08x %i %i\n", old_addr, addr, x, y); + } + if (addr >= svga->vram_max) + return 0xff; - egareads++; - cycles -= video_timing_read_w; - cycles_lost += video_timing_read_w; + egareads++; + cycles -= video_timing_read_w; + cycles_lost += video_timing_read_w; -// pclog("read_linear: addr=%08x val=%02x\n", addr, svga->vram[addr & svga->vram_mask]); + // pclog("read_linear: addr=%08x val=%02x\n", addr, svga->vram[addr & svga->vram_mask]); - return *(uint16_t *)&svga->vram[addr & svga->vram_mask]; + return *(uint16_t *)&svga->vram[addr & svga->vram_mask]; } static uint32_t banshee_read_linear_l(uint32_t addr, void *p) { - banshee_t *banshee = (banshee_t *)p; - voodoo_t *voodoo = banshee->voodoo; - svga_t *svga = &banshee->svga; + banshee_t *banshee = (banshee_t *)p; + voodoo_t *voodoo = banshee->voodoo; + svga_t *svga = &banshee->svga; - if (addr & 3) - return banshee_read_linear_w(addr, p) | (banshee_read_linear_w(addr + 2, p) << 16); + if (addr & 3) + return banshee_read_linear_w(addr, p) | (banshee_read_linear_w(addr + 2, p) << 16); - cycles -= voodoo->read_time; - cycles_lost += voodoo->read_time; + cycles -= voodoo->read_time; + cycles_lost += voodoo->read_time; - addr &= svga->decode_mask; - if (addr >= voodoo->tile_base) { - int x, y; + addr &= svga->decode_mask; + if (addr >= voodoo->tile_base) { + int x, y; - addr -= voodoo->tile_base; - x = addr & (voodoo->tile_stride - 1); - y = addr >> voodoo->tile_stride_shift; + addr -= voodoo->tile_base; + x = addr & (voodoo->tile_stride - 1); + y = addr >> voodoo->tile_stride_shift; - addr = voodoo->tile_base + (x & 127) + ((x >> 7) * 128 * 32) + ((y & 31) * 128) + (y >> 5) * voodoo->tile_x_real; -// pclog(" Tile rb %08x->%08x %i %i\n", old_addr, addr, x, y); - } - if (addr >= svga->vram_max) - return 0xff; + addr = voodoo->tile_base + (x & 127) + ((x >> 7) * 128 * 32) + ((y & 31) * 128) + (y >> 5) * voodoo->tile_x_real; + // pclog(" Tile rb %08x->%08x %i %i\n", old_addr, addr, x, y); + } + if (addr >= svga->vram_max) + return 0xff; - egareads++; - cycles -= video_timing_read_l; - cycles_lost += video_timing_read_l; + egareads++; + cycles -= video_timing_read_l; + cycles_lost += video_timing_read_l; -// pclog("read_linear: addr=%08x val=%02x\n", addr, svga->vram[addr & svga->vram_mask]); + // pclog("read_linear: addr=%08x val=%02x\n", addr, svga->vram[addr & svga->vram_mask]); - return *(uint32_t *)&svga->vram[addr & svga->vram_mask]; + return *(uint32_t *)&svga->vram[addr & svga->vram_mask]; } static void banshee_write_linear(uint32_t addr, uint8_t val, void *p) { - banshee_t *banshee = (banshee_t *)p; - voodoo_t *voodoo = banshee->voodoo; - svga_t *svga = &banshee->svga; + banshee_t *banshee = (banshee_t *)p; + voodoo_t *voodoo = banshee->voodoo; + svga_t *svga = &banshee->svga; - cycles -= voodoo->write_time; - cycles_lost += voodoo->write_time; + cycles -= voodoo->write_time; + cycles_lost += voodoo->write_time; -// pclog("write_linear: addr=%08x val=%02x\n", addr, val); - addr &= svga->decode_mask; - if (addr >= voodoo->tile_base) { - int x, y; + // pclog("write_linear: addr=%08x val=%02x\n", addr, val); + addr &= svga->decode_mask; + if (addr >= voodoo->tile_base) { + int x, y; - addr -= voodoo->tile_base; - x = addr & (voodoo->tile_stride - 1); - y = addr >> voodoo->tile_stride_shift; + addr -= voodoo->tile_base; + x = addr & (voodoo->tile_stride - 1); + y = addr >> voodoo->tile_stride_shift; - addr = voodoo->tile_base + (x & 127) + ((x >> 7) * 128 * 32) + ((y & 31) * 128) + (y >> 5) * voodoo->tile_x_real; -// pclog(" Tile b %08x->%08x %i %i\n", old_addr, addr, x, y); - } - if (addr >= svga->vram_max) - return; + addr = voodoo->tile_base + (x & 127) + ((x >> 7) * 128 * 32) + ((y & 31) * 128) + (y >> 5) * voodoo->tile_x_real; + // pclog(" Tile b %08x->%08x %i %i\n", old_addr, addr, x, y); + } + if (addr >= svga->vram_max) + return; - egawrites++; + egawrites++; - cycles -= video_timing_write_b; - cycles_lost += video_timing_write_b; + cycles -= video_timing_write_b; + cycles_lost += video_timing_write_b; - svga->changedvram[addr >> 12] = changeframecount; - svga->vram[addr & svga->vram_mask] = val; + svga->changedvram[addr >> 12] = changeframecount; + svga->vram[addr & svga->vram_mask] = val; } static void banshee_write_linear_w(uint32_t addr, uint16_t val, void *p) { - banshee_t *banshee = (banshee_t *)p; - voodoo_t *voodoo = banshee->voodoo; - svga_t *svga = &banshee->svga; + banshee_t *banshee = (banshee_t *)p; + voodoo_t *voodoo = banshee->voodoo; + svga_t *svga = &banshee->svga; - if (addr & 1) { - banshee_write_linear(addr, val, p); - banshee_write_linear(addr + 1, val >> 8, p); - return; - } + if (addr & 1) { + banshee_write_linear(addr, val, p); + banshee_write_linear(addr + 1, val >> 8, p); + return; + } - cycles -= voodoo->write_time; - cycles_lost += voodoo->write_time; + cycles -= voodoo->write_time; + cycles_lost += voodoo->write_time; -// pclog("write_linear: addr=%08x val=%02x\n", addr, val); - addr &= svga->decode_mask; - if (addr >= voodoo->tile_base) { - int x, y; + // pclog("write_linear: addr=%08x val=%02x\n", addr, val); + addr &= svga->decode_mask; + if (addr >= voodoo->tile_base) { + int x, y; - addr -= voodoo->tile_base; - x = addr & (voodoo->tile_stride - 1); - y = addr >> voodoo->tile_stride_shift; + addr -= voodoo->tile_base; + x = addr & (voodoo->tile_stride - 1); + y = addr >> voodoo->tile_stride_shift; - addr = voodoo->tile_base + (x & 127) + ((x >> 7) * 128 * 32) + ((y & 31) * 128) + (y >> 5) * voodoo->tile_x_real; -// pclog(" Tile b %08x->%08x %i %i\n", old_addr, addr, x, y); - } - if (addr >= svga->vram_max) - return; + addr = voodoo->tile_base + (x & 127) + ((x >> 7) * 128 * 32) + ((y & 31) * 128) + (y >> 5) * voodoo->tile_x_real; + // pclog(" Tile b %08x->%08x %i %i\n", old_addr, addr, x, y); + } + if (addr >= svga->vram_max) + return; - egawrites++; + egawrites++; - cycles -= video_timing_write_w; - cycles_lost += video_timing_write_w; + cycles -= video_timing_write_w; + cycles_lost += video_timing_write_w; - svga->changedvram[addr >> 12] = changeframecount; - *(uint16_t *)&svga->vram[addr & svga->vram_mask] = val; + svga->changedvram[addr >> 12] = changeframecount; + *(uint16_t *)&svga->vram[addr & svga->vram_mask] = val; } static void banshee_write_linear_l(uint32_t addr, uint32_t val, void *p) { - banshee_t *banshee = (banshee_t *)p; - voodoo_t *voodoo = banshee->voodoo; - svga_t *svga = &banshee->svga; - int timing; + banshee_t *banshee = (banshee_t *)p; + voodoo_t *voodoo = banshee->voodoo; + svga_t *svga = &banshee->svga; + int timing; - if (addr & 3) { - banshee_write_linear_w(addr, val, p); - banshee_write_linear_w(addr + 2, val >> 16, p); - return; - } + if (addr & 3) { + banshee_write_linear_w(addr, val, p); + banshee_write_linear_w(addr + 2, val >> 16, p); + return; + } - if (addr == voodoo->last_write_addr + 4) - timing = voodoo->burst_time; - else - timing = voodoo->write_time; - cycles -= timing; - cycles_lost += timing; - voodoo->last_write_addr = addr; + if (addr == voodoo->last_write_addr + 4) + timing = voodoo->burst_time; + else + timing = voodoo->write_time; + cycles -= timing; + cycles_lost += timing; + voodoo->last_write_addr = addr; -// /*if (val) */pclog("write_linear_l: addr=%08x val=%08x %08x\n", addr, val, voodoo->tile_base); - addr &= svga->decode_mask; - if (addr >= voodoo->tile_base) { - int x, y; + // /*if (val) */pclog("write_linear_l: addr=%08x val=%08x %08x\n", addr, val, voodoo->tile_base); + addr &= svga->decode_mask; + if (addr >= voodoo->tile_base) { + int x, y; - addr -= voodoo->tile_base; - x = addr & (voodoo->tile_stride - 1); - y = addr >> voodoo->tile_stride_shift; + addr -= voodoo->tile_base; + x = addr & (voodoo->tile_stride - 1); + y = addr >> voodoo->tile_stride_shift; - addr = voodoo->tile_base + (x & 127) + ((x >> 7) * 128 * 32) + ((y & 31) * 128) + (y >> 5) * voodoo->tile_x_real; -// pclog(" Tile %08x->%08x->%08x->%08x %i %i tile_x=%i\n", old_addr, addr_off, addr2, addr, x, y, voodoo->tile_x_real); - } + addr = voodoo->tile_base + (x & 127) + ((x >> 7) * 128 * 32) + ((y & 31) * 128) + (y >> 5) * voodoo->tile_x_real; + // pclog(" Tile %08x->%08x->%08x->%08x %i %i tile_x=%i\n", old_addr, addr_off, addr2, addr, x, y, + // voodoo->tile_x_real); + } - if (addr >= svga->vram_max) - return; + if (addr >= svga->vram_max) + return; - egawrites += 4; + egawrites += 4; - cycles -= video_timing_write_l; - cycles_lost += video_timing_write_l; + cycles -= video_timing_write_l; + cycles_lost += video_timing_write_l; - svga->changedvram[addr >> 12] = changeframecount; - *(uint32_t *)&svga->vram[addr & svga->vram_mask] = val; - if (voodoo->cmdfifo_enabled && addr >= voodoo->cmdfifo_base && addr < voodoo->cmdfifo_end) { -// pclog("CMDFIFO write %08x %08x old amin=%08x amax=%08x hlcnt=%i depth_wr=%i rp=%08x\n", addr, val, voodoo->cmdfifo_amin, voodoo->cmdfifo_amax, voodoo->cmdfifo_holecount, voodoo->cmdfifo_depth_wr, voodoo->cmdfifo_rp); - if (addr == voodoo->cmdfifo_base && !voodoo->cmdfifo_holecount) { -// if (voodoo->cmdfifo_holecount) -// fatal("CMDFIFO reset pointers while outstanding holes\n"); - /*Reset pointers*/ - voodoo->cmdfifo_amin = voodoo->cmdfifo_base; - voodoo->cmdfifo_amax = voodoo->cmdfifo_base; - voodoo->cmdfifo_depth_wr++; - voodoo_wake_fifo_thread(voodoo); - } else if (voodoo->cmdfifo_holecount) { -// if ((addr <= voodoo->cmdfifo_amin && voodoo->cmdfifo_amin != -4) || addr >= voodoo->cmdfifo_amax) -// fatal("CMDFIFO holecount write outside of amin/amax - amin=%08x amax=%08x holecount=%i\n", voodoo->cmdfifo_amin, voodoo->cmdfifo_amax, voodoo->cmdfifo_holecount); -// pclog("holecount %i\n", voodoo->cmdfifo_holecount); - voodoo->cmdfifo_holecount--; - if (!voodoo->cmdfifo_holecount) { - /*Filled in holes, resume normal operation*/ - voodoo->cmdfifo_depth_wr += ((voodoo->cmdfifo_amax - voodoo->cmdfifo_amin) >> 2); - voodoo->cmdfifo_amin = voodoo->cmdfifo_amax; - voodoo_wake_fifo_thread(voodoo); -// pclog("hole filled! amin=%08x amax=%08x added %i words\n", voodoo->cmdfifo_amin, voodoo->cmdfifo_amax, words_to_add); - } - } else if (addr == voodoo->cmdfifo_amax + 4) { - /*In-order write*/ - voodoo->cmdfifo_amin = addr; - voodoo->cmdfifo_amax = addr; - voodoo->cmdfifo_depth_wr++; - voodoo_wake_fifo_thread(voodoo); - } else { - /*Out-of-order write*/ - if (addr < voodoo->cmdfifo_amin) { - /*Reset back to start. Note that write is still out of order!*/ - voodoo->cmdfifo_amin = voodoo->cmdfifo_base - 4; - - } -// else if (addr < voodoo->cmdfifo_amax) -// fatal("Out-of-order write really out of order\n"); - voodoo->cmdfifo_amax = addr; - voodoo->cmdfifo_holecount = ((voodoo->cmdfifo_amax - voodoo->cmdfifo_amin) >> 2) - 1; -// pclog("CMDFIFO out of order: amin=%08x amax=%08x holecount=%i\n", voodoo->cmdfifo_amin, voodoo->cmdfifo_amax, voodoo->cmdfifo_holecount); - } - } + svga->changedvram[addr >> 12] = changeframecount; + *(uint32_t *)&svga->vram[addr & svga->vram_mask] = val; + if (voodoo->cmdfifo_enabled && addr >= voodoo->cmdfifo_base && addr < voodoo->cmdfifo_end) { + // pclog("CMDFIFO write %08x %08x old amin=%08x amax=%08x hlcnt=%i depth_wr=%i rp=%08x\n", addr, + // val, voodoo->cmdfifo_amin, voodoo->cmdfifo_amax, voodoo->cmdfifo_holecount, + // voodoo->cmdfifo_depth_wr, voodoo->cmdfifo_rp); + if (addr == voodoo->cmdfifo_base && !voodoo->cmdfifo_holecount) { + // if (voodoo->cmdfifo_holecount) + // fatal("CMDFIFO reset pointers while outstanding holes\n"); + /*Reset pointers*/ + voodoo->cmdfifo_amin = voodoo->cmdfifo_base; + voodoo->cmdfifo_amax = voodoo->cmdfifo_base; + voodoo->cmdfifo_depth_wr++; + voodoo_wake_fifo_thread(voodoo); + } else if (voodoo->cmdfifo_holecount) { + // if ((addr <= voodoo->cmdfifo_amin && voodoo->cmdfifo_amin != -4) || addr >= + // voodoo->cmdfifo_amax) + // fatal("CMDFIFO holecount write outside of amin/amax - amin=%08x + // amax=%08x holecount=%i\n", voodoo->cmdfifo_amin, voodoo->cmdfifo_amax, + // voodoo->cmdfifo_holecount); + // pclog("holecount %i\n", voodoo->cmdfifo_holecount); + voodoo->cmdfifo_holecount--; + if (!voodoo->cmdfifo_holecount) { + /*Filled in holes, resume normal operation*/ + voodoo->cmdfifo_depth_wr += ((voodoo->cmdfifo_amax - voodoo->cmdfifo_amin) >> 2); + voodoo->cmdfifo_amin = voodoo->cmdfifo_amax; + voodoo_wake_fifo_thread(voodoo); + // pclog("hole filled! amin=%08x amax=%08x added %i words\n", + // voodoo->cmdfifo_amin, voodoo->cmdfifo_amax, words_to_add); + } + } else if (addr == voodoo->cmdfifo_amax + 4) { + /*In-order write*/ + voodoo->cmdfifo_amin = addr; + voodoo->cmdfifo_amax = addr; + voodoo->cmdfifo_depth_wr++; + voodoo_wake_fifo_thread(voodoo); + } else { + /*Out-of-order write*/ + if (addr < voodoo->cmdfifo_amin) { + /*Reset back to start. Note that write is still out of order!*/ + voodoo->cmdfifo_amin = voodoo->cmdfifo_base - 4; + } + // else if (addr < voodoo->cmdfifo_amax) + // fatal("Out-of-order write really out of order\n"); + voodoo->cmdfifo_amax = addr; + voodoo->cmdfifo_holecount = ((voodoo->cmdfifo_amax - voodoo->cmdfifo_amin) >> 2) - 1; + // pclog("CMDFIFO out of order: amin=%08x amax=%08x holecount=%i\n", + // voodoo->cmdfifo_amin, voodoo->cmdfifo_amax, voodoo->cmdfifo_holecount); + } + } } void banshee_hwcursor_draw(svga_t *svga, int displine) { - banshee_t *banshee = (banshee_t *)svga->p; - int x, c; - int x_off; - uint32_t col0 = banshee->hwCurC0; - uint32_t col1 = banshee->hwCurC1; - uint8_t plane0[8], plane1[8]; + banshee_t *banshee = (banshee_t *)svga->p; + int x, c; + int x_off; + uint32_t col0 = banshee->hwCurC0; + uint32_t col1 = banshee->hwCurC1; + uint8_t plane0[8], plane1[8]; - for (c = 0; c < 8; c++) - plane0[c] = svga->vram[svga->hwcursor_latch.addr + c]; - for (c = 0; c < 8; c++) - plane1[c] = svga->vram[svga->hwcursor_latch.addr + c + 8]; - svga->hwcursor_latch.addr += 16; + for (c = 0; c < 8; c++) + plane0[c] = svga->vram[svga->hwcursor_latch.addr + c]; + for (c = 0; c < 8; c++) + plane1[c] = svga->vram[svga->hwcursor_latch.addr + c + 8]; + svga->hwcursor_latch.addr += 16; - x_off = svga->hwcursor_latch.x; + x_off = svga->hwcursor_latch.x; - if (banshee->vidProcCfg & VIDPROCCFG_CURSOR_MODE) { - /*X11 mode*/ - for (x = 0; x < 64; x += 8) { - if (x_off > (32 - 8)) { - int xx; + if (banshee->vidProcCfg & VIDPROCCFG_CURSOR_MODE) { + /*X11 mode*/ + for (x = 0; x < 64; x += 8) { + if (x_off > (32 - 8)) { + int xx; - for (xx = 0; xx < 8; xx++) { - if (plane0[x >> 3] & (1 << 7)) - ((uint32_t *)buffer32->line[displine])[x_off + xx] = (plane1[x >> 3] & (1 << 7)) ? col1 : col0; + for (xx = 0; xx < 8; xx++) { + if (plane0[x >> 3] & (1 << 7)) + ((uint32_t *)buffer32->line[displine])[x_off + xx] = + (plane1[x >> 3] & (1 << 7)) ? col1 : col0; - plane0[x >> 3] <<= 1; - plane1[x >> 3] <<= 1; - } - } + plane0[x >> 3] <<= 1; + plane1[x >> 3] <<= 1; + } + } - x_off += 8; - } - } else { - /*Windows mode*/ - for (x = 0; x < 64; x += 8) { - if (x_off > (32 - 8)) { - int xx; + x_off += 8; + } + } else { + /*Windows mode*/ + for (x = 0; x < 64; x += 8) { + if (x_off > (32 - 8)) { + int xx; - for (xx = 0; xx < 8; xx++) { - if (!(plane0[x >> 3] & (1 << 7))) - ((uint32_t *)buffer32->line[displine])[x_off + xx] = (plane1[x >> 3] & (1 << 7)) ? col1 : col0; - else if (plane1[x >> 3] & (1 << 7)) - ((uint32_t *)buffer32->line[displine])[x_off + xx] ^= 0xffffff; + for (xx = 0; xx < 8; xx++) { + if (!(plane0[x >> 3] & (1 << 7))) + ((uint32_t *)buffer32->line[displine])[x_off + xx] = + (plane1[x >> 3] & (1 << 7)) ? col1 : col0; + else if (plane1[x >> 3] & (1 << 7)) + ((uint32_t *)buffer32->line[displine])[x_off + xx] ^= 0xffffff; - plane0[x >> 3] <<= 1; - plane1[x >> 3] <<= 1; - } - } + plane0[x >> 3] <<= 1; + plane1[x >> 3] <<= 1; + } + } - x_off += 8; - } - } + x_off += 8; + } + } } -#define CLAMP(x) do \ - { \ - if ((x) & ~0xff) \ - x = ((x) < 0) ? 0 : 0xff; \ - } \ - while (0) - -#define DECODE_RGB565(buf) \ - do \ - { \ - int c; \ - int wp = 0; \ - \ - for (c = 0; c < voodoo->overlay.overlay_bytes; c += 2) \ - { \ - uint16_t data = *(uint16_t *)src; \ - int r = data & 0x1f; \ - int g = (data >> 5) & 0x3f; \ - int b = data >> 11; \ - \ - if (banshee->vidProcCfg & VIDPROCCFG_OVERLAY_CLUT_BYPASS) \ - buf[wp++] = (r << 3) | (g << 10) | (b << 19); \ - else \ - buf[wp++] = (clut[r << 3] & 0x0000ff) | \ - (clut[g << 2] & 0x00ff00) | \ - (clut[b << 3] & 0xff0000); \ - src += 2; \ - } \ +#define CLAMP(x) \ + do { \ + if ((x) & ~0xff) \ + x = ((x) < 0) ? 0 : 0xff; \ } while (0) -#define DECODE_RGB565_TILED(buf) \ - do \ - { \ - int c; \ - int wp = 0; \ - uint32_t base_addr = (buf == banshee->overlay_buffer[1]) ? src_addr2 : src_addr; \ - \ - for (c = 0; c < voodoo->overlay.overlay_bytes; c += 2) \ - { \ - uint16_t data = *(uint16_t *)&svga->vram[(base_addr + (c & 127) + (c >> 7)*128*32) & svga->vram_mask]; \ - int r = data & 0x1f; \ - int g = (data >> 5) & 0x3f; \ - int b = data >> 11; \ - \ - if (banshee->vidProcCfg & VIDPROCCFG_OVERLAY_CLUT_BYPASS) \ - buf[wp++] = (r << 3) | (g << 10) | (b << 19); \ - else \ - buf[wp++] = (clut[r << 3] & 0x0000ff) | \ - (clut[g << 2] & 0x00ff00) | \ - (clut[b << 3] & 0xff0000); \ - } \ +#define DECODE_RGB565(buf) \ + do { \ + int c; \ + int wp = 0; \ + \ + for (c = 0; c < voodoo->overlay.overlay_bytes; c += 2) { \ + uint16_t data = *(uint16_t *)src; \ + int r = data & 0x1f; \ + int g = (data >> 5) & 0x3f; \ + int b = data >> 11; \ + \ + if (banshee->vidProcCfg & VIDPROCCFG_OVERLAY_CLUT_BYPASS) \ + buf[wp++] = (r << 3) | (g << 10) | (b << 19); \ + else \ + buf[wp++] = (clut[r << 3] & 0x0000ff) | (clut[g << 2] & 0x00ff00) | (clut[b << 3] & 0xff0000); \ + src += 2; \ + } \ } while (0) -#define DECODE_YUYV422(buf) \ - do \ - { \ - int c; \ - int wp = 0; \ - \ - for (c = 0; c < voodoo->overlay.overlay_bytes; c += 4) \ - { \ - uint8_t y1, y2; \ - int8_t Cr, Cb; \ - int dR, dG, dB; \ - int r, g, b; \ - \ - y1 = src[0]; \ - Cr = src[1] - 0x80; \ - y2 = src[2]; \ - Cb = src[3] - 0x80; \ - src += 4; \ - \ - dR = (359*Cr) >> 8; \ - dG = (88*Cb + 183*Cr) >> 8; \ - dB = (453*Cb) >> 8; \ - \ - r = y1 + dR; \ - CLAMP(r); \ - g = y1 - dG; \ - CLAMP(g); \ - b = y1 + dB; \ - CLAMP(b); \ - buf[wp++] = r | (g << 8) | (b << 16); \ - \ - r = y2 + dR; \ - CLAMP(r); \ - g = y2 - dG; \ - CLAMP(g); \ - b = y2 + dB; \ - CLAMP(b); \ - buf[wp++] = r | (g << 8) | (b << 16); \ - } \ +#define DECODE_RGB565_TILED(buf) \ + do { \ + int c; \ + int wp = 0; \ + uint32_t base_addr = (buf == banshee->overlay_buffer[1]) ? src_addr2 : src_addr; \ + \ + for (c = 0; c < voodoo->overlay.overlay_bytes; c += 2) { \ + uint16_t data = \ + *(uint16_t *)&svga->vram[(base_addr + (c & 127) + (c >> 7) * 128 * 32) & svga->vram_mask]; \ + int r = data & 0x1f; \ + int g = (data >> 5) & 0x3f; \ + int b = data >> 11; \ + \ + if (banshee->vidProcCfg & VIDPROCCFG_OVERLAY_CLUT_BYPASS) \ + buf[wp++] = (r << 3) | (g << 10) | (b << 19); \ + else \ + buf[wp++] = (clut[r << 3] & 0x0000ff) | (clut[g << 2] & 0x00ff00) | (clut[b << 3] & 0xff0000); \ + } \ } while (0) -#define DECODE_UYUV422(buf) \ - do \ - { \ - int c; \ - int wp = 0; \ - \ - for (c = 0; c < voodoo->overlay.overlay_bytes; c += 4) \ - { \ - uint8_t y1, y2; \ - int8_t Cr, Cb; \ - int dR, dG, dB; \ - int r, g, b; \ - \ - Cr = src[0] - 0x80; \ - y1 = src[1]; \ - Cb = src[2] - 0x80; \ - y2 = src[3]; \ - src += 4; \ - \ - dR = (359*Cr) >> 8; \ - dG = (88*Cb + 183*Cr) >> 8; \ - dB = (453*Cb) >> 8; \ - \ - r = y1 + dR; \ - CLAMP(r); \ - g = y1 - dG; \ - CLAMP(g); \ - b = y1 + dB; \ - CLAMP(b); \ - buf[wp++] = r | (g << 8) | (b << 16); \ - \ - r = y2 + dR; \ - CLAMP(r); \ - g = y2 - dG; \ - CLAMP(g); \ - b = y2 + dB; \ - CLAMP(b); \ - buf[wp++] = r | (g << 8) | (b << 16); \ - } \ +#define DECODE_YUYV422(buf) \ + do { \ + int c; \ + int wp = 0; \ + \ + for (c = 0; c < voodoo->overlay.overlay_bytes; c += 4) { \ + uint8_t y1, y2; \ + int8_t Cr, Cb; \ + int dR, dG, dB; \ + int r, g, b; \ + \ + y1 = src[0]; \ + Cr = src[1] - 0x80; \ + y2 = src[2]; \ + Cb = src[3] - 0x80; \ + src += 4; \ + \ + dR = (359 * Cr) >> 8; \ + dG = (88 * Cb + 183 * Cr) >> 8; \ + dB = (453 * Cb) >> 8; \ + \ + r = y1 + dR; \ + CLAMP(r); \ + g = y1 - dG; \ + CLAMP(g); \ + b = y1 + dB; \ + CLAMP(b); \ + buf[wp++] = r | (g << 8) | (b << 16); \ + \ + r = y2 + dR; \ + CLAMP(r); \ + g = y2 - dG; \ + CLAMP(g); \ + b = y2 + dB; \ + CLAMP(b); \ + buf[wp++] = r | (g << 8) | (b << 16); \ + } \ } while (0) -#define OVERLAY_SAMPLE(buf) \ - do \ - { \ - switch (banshee->overlay_pix_fmt) \ - { \ - case 0: \ - break; \ - \ - case OVERLAY_FMT_YUYV422: \ - DECODE_YUYV422(buf); \ - break; \ - \ - case OVERLAY_FMT_UYVY422: \ - DECODE_UYUV422(buf); \ - break; \ - \ - case OVERLAY_FMT_565: \ - case OVERLAY_FMT_565_DITHER: \ - if (banshee->vidProcCfg & VIDPROCCFG_OVERLAY_TILE) \ - DECODE_RGB565_TILED(buf); \ - else \ - DECODE_RGB565(buf); \ - break; \ - } \ +#define DECODE_UYUV422(buf) \ + do { \ + int c; \ + int wp = 0; \ + \ + for (c = 0; c < voodoo->overlay.overlay_bytes; c += 4) { \ + uint8_t y1, y2; \ + int8_t Cr, Cb; \ + int dR, dG, dB; \ + int r, g, b; \ + \ + Cr = src[0] - 0x80; \ + y1 = src[1]; \ + Cb = src[2] - 0x80; \ + y2 = src[3]; \ + src += 4; \ + \ + dR = (359 * Cr) >> 8; \ + dG = (88 * Cb + 183 * Cr) >> 8; \ + dB = (453 * Cb) >> 8; \ + \ + r = y1 + dR; \ + CLAMP(r); \ + g = y1 - dG; \ + CLAMP(g); \ + b = y1 + dB; \ + CLAMP(b); \ + buf[wp++] = r | (g << 8) | (b << 16); \ + \ + r = y2 + dR; \ + CLAMP(r); \ + g = y2 - dG; \ + CLAMP(g); \ + b = y2 + dB; \ + CLAMP(b); \ + buf[wp++] = r | (g << 8) | (b << 16); \ + } \ + } while (0) + +#define OVERLAY_SAMPLE(buf) \ + do { \ + switch (banshee->overlay_pix_fmt) { \ + case 0: \ + break; \ + \ + case OVERLAY_FMT_YUYV422: \ + DECODE_YUYV422(buf); \ + break; \ + \ + case OVERLAY_FMT_UYVY422: \ + DECODE_UYUV422(buf); \ + break; \ + \ + case OVERLAY_FMT_565: \ + case OVERLAY_FMT_565_DITHER: \ + if (banshee->vidProcCfg & VIDPROCCFG_OVERLAY_TILE) \ + DECODE_RGB565_TILED(buf); \ + else \ + DECODE_RGB565(buf); \ + break; \ + } \ } while (0) /* generate both filters for the static table here */ void voodoo_generate_vb_filters(voodoo_t *voodoo, int fcr, int fcg) { - int g, h; - float difference, diffg; - float thiscol, thiscolg; - float clr, clg = 0; - float hack = 1.0f; - // pre-clamping + int g, h; + float difference, diffg; + float thiscol, thiscolg; + float clr, clg = 0; + float hack = 1.0f; + // pre-clamping - fcr *= hack; - fcg *= hack; + fcr *= hack; + fcg *= hack; + /* box prefilter */ + for (g = 0; g < 256; g++) // pixel 1 - our target pixel we want to bleed into + { + for (h = 0; h < 256; h++) // pixel 2 - our main pixel + { + float avg; + float avgdiff; - /* box prefilter */ - for (g = 0; g < 256; g++) // pixel 1 - our target pixel we want to bleed into - { - for (h = 0; h < 256; h++) // pixel 2 - our main pixel - { - float avg; - float avgdiff; + difference = (float)(g - h); + avg = g; + avgdiff = avg - h; - difference = (float)(g - h); - avg = g; - avgdiff = avg - h; + avgdiff = avgdiff * 0.75f; + if (avgdiff < 0) + avgdiff *= -1; + if (difference < 0) + difference *= -1; - avgdiff = avgdiff * 0.75f; - if (avgdiff < 0) - avgdiff *= -1; - if (difference < 0) - difference *= -1; + thiscol = thiscolg = g; - thiscol = thiscolg = g; + if (h > g) { + clr = clg = avgdiff; - if (h > g) { - clr = clg = avgdiff; + if (clr > fcr) + clr = fcr; + if (clg > fcg) + clg = fcg; - if (clr > fcr) - clr = fcr; - if (clg > fcg) - clg = fcg; + thiscol = g; + thiscolg = g; - thiscol = g; - thiscolg = g; + if (thiscol > g + fcr) + thiscol = g + fcr; + if (thiscolg > g + fcg) + thiscolg = g + fcg; - if (thiscol > g + fcr) - thiscol = g + fcr; - if (thiscolg > g + fcg) - thiscolg = g + fcg; + if (thiscol > g + difference) + thiscol = g + difference; + if (thiscolg > g + difference) + thiscolg = g + difference; - if (thiscol > g + difference) - thiscol = g + difference; - if (thiscolg > g + difference) - thiscolg = g + difference; + // hmm this might not be working out.. + int ugh = g - h; + if (ugh < fcr) + thiscol = h; + if (ugh < fcg) + thiscolg = h; + } - // hmm this might not be working out.. - int ugh = g - h; - if (ugh < fcr) - thiscol = h; - if (ugh < fcg) - thiscolg = h; - } + if (difference > fcr) + thiscol = g; + if (difference > fcg) + thiscolg = g; - if (difference > fcr) - thiscol = g; - if (difference > fcg) - thiscolg = g; + // clamp + if (thiscol < 0) + thiscol = 0; + if (thiscolg < 0) + thiscolg = 0; - // clamp - if (thiscol < 0) - thiscol = 0; - if (thiscolg < 0) - thiscolg = 0; + if (thiscol > 255) + thiscol = 255; + if (thiscolg > 255) + thiscolg = 255; - if (thiscol > 255) - thiscol = 255; - if (thiscolg > 255) - thiscolg = 255; + vb_filter_bx_rb[g][h] = (thiscol); + vb_filter_bx_g[g][h] = (thiscolg); + } + float lined = g + 4; + if (lined > 255) + lined = 255; + voodoo->purpleline[g][0] = lined; + voodoo->purpleline[g][2] = lined; - vb_filter_bx_rb[g][h] = (thiscol); - vb_filter_bx_g[g][h] = (thiscolg); + lined = g + 0; + if (lined > 255) + lined = 255; + voodoo->purpleline[g][1] = lined; + } - } - float lined = g + 4; - if (lined > 255) - lined = 255; - voodoo->purpleline[g][0] = lined; - voodoo->purpleline[g][2] = lined; + /* 4x1 and 2x2 filter */ + // fcr *= 5; + // fcg *= 6; - lined = g + 0; - if (lined > 255) - lined = 255; - voodoo->purpleline[g][1] = lined; - } + for (g = 0; g < 256; g++) // pixel 1 + { + for (h = 0; h < 256; h++) // pixel 2 + { + difference = (float)(h - g); + diffg = difference; - /* 4x1 and 2x2 filter */ - //fcr *= 5; - //fcg *= 6; + thiscol = thiscolg = g; - for (g = 0; g < 256; g++) // pixel 1 - { - for (h = 0; h < 256; h++) // pixel 2 - { - difference = (float)(h - g); - diffg = difference; + if (difference > fcr) + difference = fcr; + if (difference < -fcr) + difference = -fcr; - thiscol = thiscolg = g; + if (diffg > fcg) + diffg = fcg; + if (diffg < -fcg) + diffg = -fcg; - if (difference > fcr) - difference = fcr; - if (difference < -fcr) - difference = -fcr; + if ((difference < fcr) || (-difference > -fcr)) + thiscol = g + (difference / 2); + if ((diffg < fcg) || (-diffg > -fcg)) + thiscolg = g + (diffg / 2); - if (diffg > fcg) - diffg = fcg; - if (diffg < -fcg) - diffg = -fcg; + if (thiscol < 0) + thiscol = 0; + if (thiscol > 255) + thiscol = 255; - if ((difference < fcr) || (-difference > -fcr)) - thiscol = g + (difference / 2); - if ((diffg < fcg) || (-diffg > -fcg)) - thiscolg = g + (diffg / 2); - - if (thiscol < 0) - thiscol = 0; - if (thiscol > 255) - thiscol = 255; - - if (thiscolg < 0) - thiscolg = 0; - if (thiscolg > 255) - thiscolg = 255; - - vb_filter_v1_rb[g][h] = thiscol; - vb_filter_v1_g[g][h] = thiscolg; - - } - } + if (thiscolg < 0) + thiscolg = 0; + if (thiscolg > 255) + thiscolg = 255; + vb_filter_v1_rb[g][h] = thiscol; + vb_filter_v1_g[g][h] = thiscolg; + } + } } static void banshee_overlay_draw(svga_t *svga, int displine) { - banshee_t *banshee = (banshee_t *)svga->p; - voodoo_t *voodoo = banshee->voodoo; - uint32_t *p; - int x; - int y = voodoo->overlay.src_y >> 20; - uint32_t src_addr = svga->overlay_latch.addr + ((banshee->vidProcCfg & VIDPROCCFG_OVERLAY_TILE) ? - ((y & 31) * 128 + (y >> 5) * svga->overlay_latch.pitch) : - y * svga->overlay_latch.pitch); - uint32_t src_addr2 = svga->overlay_latch.addr + ((banshee->vidProcCfg & VIDPROCCFG_OVERLAY_TILE) ? - (((y + 1) & 31) * 128 + ((y + 1) >> 5) * svga->overlay_latch.pitch) : - (y + 1) * svga->overlay_latch.pitch); - uint8_t *src = &svga->vram[src_addr & svga->vram_mask]; - uint32_t src_x = 0; - unsigned int y_coeff = (voodoo->overlay.src_y & 0xfffff) >> 4; - int skip_filtering; - uint32_t *clut = &svga->pallook[(banshee->vidProcCfg & VIDPROCCFG_OVERLAY_CLUT_SEL) ? 256 : 0]; + banshee_t *banshee = (banshee_t *)svga->p; + voodoo_t *voodoo = banshee->voodoo; + uint32_t *p; + int x; + int y = voodoo->overlay.src_y >> 20; + uint32_t src_addr = svga->overlay_latch.addr + ((banshee->vidProcCfg & VIDPROCCFG_OVERLAY_TILE) + ? ((y & 31) * 128 + (y >> 5) * svga->overlay_latch.pitch) + : y * svga->overlay_latch.pitch); + uint32_t src_addr2 = + svga->overlay_latch.addr + ((banshee->vidProcCfg & VIDPROCCFG_OVERLAY_TILE) + ? (((y + 1) & 31) * 128 + ((y + 1) >> 5) * svga->overlay_latch.pitch) + : (y + 1) * svga->overlay_latch.pitch); + uint8_t *src = &svga->vram[src_addr & svga->vram_mask]; + uint32_t src_x = 0; + unsigned int y_coeff = (voodoo->overlay.src_y & 0xfffff) >> 4; + int skip_filtering; + uint32_t *clut = &svga->pallook[(banshee->vidProcCfg & VIDPROCCFG_OVERLAY_CLUT_SEL) ? 256 : 0]; - if (svga->render == svga_render_null && - !svga->changedvram[src_addr >> 12] && !svga->changedvram[src_addr2 >> 12] && - !svga->fullchange && - ((voodoo->overlay.src_y >> 20) < 2048 && !voodoo->dirty_line[voodoo->overlay.src_y >> 20]) && - !(banshee->vidProcCfg & VIDPROCCFG_V_SCALE_ENABLE)) { - voodoo->overlay.src_y += (1 << 20); - return; - } + if (svga->render == svga_render_null && !svga->changedvram[src_addr >> 12] && !svga->changedvram[src_addr2 >> 12] && + !svga->fullchange && ((voodoo->overlay.src_y >> 20) < 2048 && !voodoo->dirty_line[voodoo->overlay.src_y >> 20]) && + !(banshee->vidProcCfg & VIDPROCCFG_V_SCALE_ENABLE)) { + voodoo->overlay.src_y += (1 << 20); + return; + } - if ((voodoo->overlay.src_y >> 20) < 2048) - voodoo->dirty_line[voodoo->overlay.src_y >> 20] = 0; -// pclog("displine=%i addr=%08x %08x %08x %08x\n", displine, svga->overlay_latch.addr, src_addr, voodoo->overlay.vidOverlayDvdy, *(uint32_t *)src); -// if (src_addr >= 0x800000) -// fatal("overlay out of range!\n"); - p = &((uint32_t *)buffer32->line[displine])[svga->overlay_latch.x + 32]; + if ((voodoo->overlay.src_y >> 20) < 2048) + voodoo->dirty_line[voodoo->overlay.src_y >> 20] = 0; + // pclog("displine=%i addr=%08x %08x %08x %08x\n", displine, svga->overlay_latch.addr, src_addr, + // voodoo->overlay.vidOverlayDvdy, *(uint32_t *)src); if (src_addr >= 0x800000) + // fatal("overlay out of range!\n"); + p = &((uint32_t *)buffer32->line[displine])[svga->overlay_latch.x + 32]; - if (banshee->voodoo->scrfilter && banshee->voodoo->scrfilterEnabled) - skip_filtering = ((banshee->vidProcCfg & VIDPROCCFG_FILTER_MODE_MASK) != VIDPROCCFG_FILTER_MODE_BILINEAR && - !(banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) && !(banshee->vidProcCfg & VIDPROCCFG_FILTER_MODE_DITHER_4X4) && - !(banshee->vidProcCfg & VIDPROCCFG_FILTER_MODE_DITHER_2X2)); - else - skip_filtering = ((banshee->vidProcCfg & VIDPROCCFG_FILTER_MODE_MASK) != VIDPROCCFG_FILTER_MODE_BILINEAR && - !(banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE)); + if (banshee->voodoo->scrfilter && banshee->voodoo->scrfilterEnabled) + skip_filtering = ((banshee->vidProcCfg & VIDPROCCFG_FILTER_MODE_MASK) != VIDPROCCFG_FILTER_MODE_BILINEAR && + !(banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) && + !(banshee->vidProcCfg & VIDPROCCFG_FILTER_MODE_DITHER_4X4) && + !(banshee->vidProcCfg & VIDPROCCFG_FILTER_MODE_DITHER_2X2)); + else + skip_filtering = ((banshee->vidProcCfg & VIDPROCCFG_FILTER_MODE_MASK) != VIDPROCCFG_FILTER_MODE_BILINEAR && + !(banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE)); - if (skip_filtering) { - /*No scaling or filtering required, just write straight to output buffer*/ - OVERLAY_SAMPLE(p); - } else { - OVERLAY_SAMPLE(banshee->overlay_buffer[0]); + if (skip_filtering) { + /*No scaling or filtering required, just write straight to output buffer*/ + OVERLAY_SAMPLE(p); + } else { + OVERLAY_SAMPLE(banshee->overlay_buffer[0]); - switch (banshee->vidProcCfg & VIDPROCCFG_FILTER_MODE_MASK) { - case VIDPROCCFG_FILTER_MODE_BILINEAR:src = &svga->vram[src_addr2 & svga->vram_mask]; - OVERLAY_SAMPLE(banshee->overlay_buffer[1]); - if (banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) { - for (x = 0; x < svga->overlay_latch.xsize; x++) { - unsigned int x_coeff = (src_x & 0xfffff) >> 4; - unsigned int coeffs[4] = { - ((0x10000 - x_coeff) * (0x10000 - y_coeff)) >> 16, - (x_coeff * (0x10000 - y_coeff)) >> 16, - ((0x10000 - x_coeff) * y_coeff) >> 16, - (x_coeff * y_coeff) >> 16 - }; - uint32_t samp0 = banshee->overlay_buffer[0][src_x >> 20]; - uint32_t samp1 = banshee->overlay_buffer[0][(src_x >> 20) + 1]; - uint32_t samp2 = banshee->overlay_buffer[1][src_x >> 20]; - uint32_t samp3 = banshee->overlay_buffer[1][(src_x >> 20) + 1]; - int r = (((samp0 >> 16) & 0xff) * coeffs[0] + - ((samp1 >> 16) & 0xff) * coeffs[1] + - ((samp2 >> 16) & 0xff) * coeffs[2] + - ((samp3 >> 16) & 0xff) * coeffs[3]) >> 16; - int g = (((samp0 >> 8) & 0xff) * coeffs[0] + - ((samp1 >> 8) & 0xff) * coeffs[1] + - ((samp2 >> 8) & 0xff) * coeffs[2] + - ((samp3 >> 8) & 0xff) * coeffs[3]) >> 16; - int b = ((samp0 & 0xff) * coeffs[0] + - (samp1 & 0xff) * coeffs[1] + - (samp2 & 0xff) * coeffs[2] + - (samp3 & 0xff) * coeffs[3]) >> 16; - p[x] = (r << 16) | (g << 8) | b; + switch (banshee->vidProcCfg & VIDPROCCFG_FILTER_MODE_MASK) { + case VIDPROCCFG_FILTER_MODE_BILINEAR: + src = &svga->vram[src_addr2 & svga->vram_mask]; + OVERLAY_SAMPLE(banshee->overlay_buffer[1]); + if (banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) { + for (x = 0; x < svga->overlay_latch.xsize; x++) { + unsigned int x_coeff = (src_x & 0xfffff) >> 4; + unsigned int coeffs[4] = {((0x10000 - x_coeff) * (0x10000 - y_coeff)) >> 16, + (x_coeff * (0x10000 - y_coeff)) >> 16, + ((0x10000 - x_coeff) * y_coeff) >> 16, + (x_coeff * y_coeff) >> 16}; + uint32_t samp0 = banshee->overlay_buffer[0][src_x >> 20]; + uint32_t samp1 = banshee->overlay_buffer[0][(src_x >> 20) + 1]; + uint32_t samp2 = banshee->overlay_buffer[1][src_x >> 20]; + uint32_t samp3 = banshee->overlay_buffer[1][(src_x >> 20) + 1]; + int r = (((samp0 >> 16) & 0xff) * coeffs[0] + ((samp1 >> 16) & 0xff) * coeffs[1] + + ((samp2 >> 16) & 0xff) * coeffs[2] + ((samp3 >> 16) & 0xff) * coeffs[3]) >> + 16; + int g = (((samp0 >> 8) & 0xff) * coeffs[0] + ((samp1 >> 8) & 0xff) * coeffs[1] + + ((samp2 >> 8) & 0xff) * coeffs[2] + ((samp3 >> 8) & 0xff) * coeffs[3]) >> + 16; + int b = ((samp0 & 0xff) * coeffs[0] + (samp1 & 0xff) * coeffs[1] + + (samp2 & 0xff) * coeffs[2] + (samp3 & 0xff) * coeffs[3]) >> + 16; + p[x] = (r << 16) | (g << 8) | b; - src_x += voodoo->overlay.vidOverlayDudx; - } - } else { - for (x = 0; x < svga->overlay_latch.xsize; x++) { - uint32_t samp0 = banshee->overlay_buffer[0][src_x >> 20]; - uint32_t samp1 = banshee->overlay_buffer[1][src_x >> 20]; - int r = (((samp0 >> 16) & 0xff) * (0x10000 - y_coeff) + - ((samp1 >> 16) & 0xff) * y_coeff) >> 16; - int g = (((samp0 >> 8) & 0xff) * (0x10000 - y_coeff) + - ((samp1 >> 8) & 0xff) * y_coeff) >> 16; - int b = ((samp0 & 0xff) * (0x10000 - y_coeff) + - (samp1 & 0xff) * y_coeff) >> 16; - p[x] = (r << 16) | (g << 8) | b; - } - } - break; + src_x += voodoo->overlay.vidOverlayDudx; + } + } else { + for (x = 0; x < svga->overlay_latch.xsize; x++) { + uint32_t samp0 = banshee->overlay_buffer[0][src_x >> 20]; + uint32_t samp1 = banshee->overlay_buffer[1][src_x >> 20]; + int r = (((samp0 >> 16) & 0xff) * (0x10000 - y_coeff) + + ((samp1 >> 16) & 0xff) * y_coeff) >> + 16; + int g = (((samp0 >> 8) & 0xff) * (0x10000 - y_coeff) + ((samp1 >> 8) & 0xff) * y_coeff) >> + 16; + int b = ((samp0 & 0xff) * (0x10000 - y_coeff) + (samp1 & 0xff) * y_coeff) >> 16; + p[x] = (r << 16) | (g << 8) | b; + } + } + break; - case VIDPROCCFG_FILTER_MODE_DITHER_4X4: - if (banshee->voodoo->scrfilter && banshee->voodoo->scrfilterEnabled) { - uint8_t fil[(svga->overlay_latch.xsize) * 3]; - uint8_t fil3[(svga->overlay_latch.xsize) * 3]; + case VIDPROCCFG_FILTER_MODE_DITHER_4X4: + if (banshee->voodoo->scrfilter && banshee->voodoo->scrfilterEnabled) { + uint8_t fil[(svga->overlay_latch.xsize) * 3]; + uint8_t fil3[(svga->overlay_latch.xsize) * 3]; - if (banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) /* leilei HACK - don't know of real 4x1 hscaled behavior yet, double for now */ - { - for (x = 0; x < svga->overlay_latch.xsize; x++) { - fil[x * 3] = ((banshee->overlay_buffer[0][src_x >> 20])); - fil[x * 3 + 1] = ((banshee->overlay_buffer[0][src_x >> 20] >> 8)); - fil[x * 3 + 2] = ((banshee->overlay_buffer[0][src_x >> 20] >> 16)); - fil3[x * 3 + 0] = fil[x * 3 + 0]; - fil3[x * 3 + 1] = fil[x * 3 + 1]; - fil3[x * 3 + 2] = fil[x * 3 + 2]; - src_x += voodoo->overlay.vidOverlayDudx; - } - } else { - for (x = 0; x < svga->overlay_latch.xsize; x++) { - fil[x * 3] = ((banshee->overlay_buffer[0][x])); - fil[x * 3 + 1] = ((banshee->overlay_buffer[0][x] >> 8)); - fil[x * 3 + 2] = ((banshee->overlay_buffer[0][x] >> 16)); - fil3[x * 3 + 0] = fil[x * 3 + 0]; - fil3[x * 3 + 1] = fil[x * 3 + 1]; - fil3[x * 3 + 2] = fil[x * 3 + 2]; - } - } - if (y % 2 == 0) { - for (x = 0; x < svga->overlay_latch.xsize; x++) { - fil[x * 3] = banshee->voodoo->purpleline[fil[x * 3 + 0]][0]; - fil[x * 3 + 1] = banshee->voodoo->purpleline[fil[x * 3 + 1]][1]; - fil[x * 3 + 2] = banshee->voodoo->purpleline[fil[x * 3 + 2]][2]; - } - } + if (banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) /* leilei HACK - don't know of real 4x1 + hscaled behavior yet, double for now */ + { + for (x = 0; x < svga->overlay_latch.xsize; x++) { + fil[x * 3] = ((banshee->overlay_buffer[0][src_x >> 20])); + fil[x * 3 + 1] = ((banshee->overlay_buffer[0][src_x >> 20] >> 8)); + fil[x * 3 + 2] = ((banshee->overlay_buffer[0][src_x >> 20] >> 16)); + fil3[x * 3 + 0] = fil[x * 3 + 0]; + fil3[x * 3 + 1] = fil[x * 3 + 1]; + fil3[x * 3 + 2] = fil[x * 3 + 2]; + src_x += voodoo->overlay.vidOverlayDudx; + } + } else { + for (x = 0; x < svga->overlay_latch.xsize; x++) { + fil[x * 3] = ((banshee->overlay_buffer[0][x])); + fil[x * 3 + 1] = ((banshee->overlay_buffer[0][x] >> 8)); + fil[x * 3 + 2] = ((banshee->overlay_buffer[0][x] >> 16)); + fil3[x * 3 + 0] = fil[x * 3 + 0]; + fil3[x * 3 + 1] = fil[x * 3 + 1]; + fil3[x * 3 + 2] = fil[x * 3 + 2]; + } + } + if (y % 2 == 0) { + for (x = 0; x < svga->overlay_latch.xsize; x++) { + fil[x * 3] = banshee->voodoo->purpleline[fil[x * 3 + 0]][0]; + fil[x * 3 + 1] = banshee->voodoo->purpleline[fil[x * 3 + 1]][1]; + fil[x * 3 + 2] = banshee->voodoo->purpleline[fil[x * 3 + 2]][2]; + } + } - for (x = 1; x < svga->overlay_latch.xsize; x++) { - fil3[(x) * 3] = vb_filter_v1_rb[fil[x * 3]][fil[(x - 1) * 3]]; - fil3[(x) * 3 + 1] = vb_filter_v1_g[fil[x * 3 + 1]][fil[(x - 1) * 3 + 1]]; - fil3[(x) * 3 + 2] = vb_filter_v1_rb[fil[x * 3 + 2]][fil[(x - 1) * 3 + 2]]; - } - for (x = 1; x < svga->overlay_latch.xsize; x++) { - fil[(x) * 3] = vb_filter_v1_rb[fil[x * 3]][fil3[(x - 1) * 3]]; - fil[(x) * 3 + 1] = vb_filter_v1_g[fil[x * 3 + 1]][fil3[(x - 1) * 3 + 1]]; - fil[(x) * 3 + 2] = vb_filter_v1_rb[fil[x * 3 + 2]][fil3[(x - 1) * 3 + 2]]; - } - for (x = 1; x < svga->overlay_latch.xsize; x++) { - fil3[(x) * 3] = vb_filter_v1_rb[fil[x * 3]][fil[(x - 1) * 3]]; - fil3[(x) * 3 + 1] = vb_filter_v1_g[fil[x * 3 + 1]][fil[(x - 1) * 3 + 1]]; - fil3[(x) * 3 + 2] = vb_filter_v1_rb[fil[x * 3 + 2]][fil[(x - 1) * 3 + 2]]; - } - for (x = 0; x < svga->overlay_latch.xsize; x++) { - fil[(x) * 3] = vb_filter_v1_rb[fil[x * 3]][fil3[(x + 1) * 3]]; - fil[(x) * 3 + 1] = vb_filter_v1_g[fil[x * 3 + 1]][fil3[(x + 1) * 3 + 1]]; - fil[(x) * 3 + 2] = vb_filter_v1_rb[fil[x * 3 + 2]][fil3[(x + 1) * 3 + 2]]; - p[x] = (fil[x * 3 + 2] << 16) | (fil[x * 3 + 1] << 8) | fil[x * 3]; - } - } else /* filter disabled by emulator option */ - { - if (banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) { - for (x = 0; x < svga->overlay_latch.xsize; x++) { - p[x] = banshee->overlay_buffer[0][src_x >> 20]; - src_x += voodoo->overlay.vidOverlayDudx; - } - } else { - for (x = 0; x < svga->overlay_latch.xsize; x++) - p[x] = banshee->overlay_buffer[0][x]; - } - } - break; + for (x = 1; x < svga->overlay_latch.xsize; x++) { + fil3[(x)*3] = vb_filter_v1_rb[fil[x * 3]][fil[(x - 1) * 3]]; + fil3[(x)*3 + 1] = vb_filter_v1_g[fil[x * 3 + 1]][fil[(x - 1) * 3 + 1]]; + fil3[(x)*3 + 2] = vb_filter_v1_rb[fil[x * 3 + 2]][fil[(x - 1) * 3 + 2]]; + } + for (x = 1; x < svga->overlay_latch.xsize; x++) { + fil[(x)*3] = vb_filter_v1_rb[fil[x * 3]][fil3[(x - 1) * 3]]; + fil[(x)*3 + 1] = vb_filter_v1_g[fil[x * 3 + 1]][fil3[(x - 1) * 3 + 1]]; + fil[(x)*3 + 2] = vb_filter_v1_rb[fil[x * 3 + 2]][fil3[(x - 1) * 3 + 2]]; + } + for (x = 1; x < svga->overlay_latch.xsize; x++) { + fil3[(x)*3] = vb_filter_v1_rb[fil[x * 3]][fil[(x - 1) * 3]]; + fil3[(x)*3 + 1] = vb_filter_v1_g[fil[x * 3 + 1]][fil[(x - 1) * 3 + 1]]; + fil3[(x)*3 + 2] = vb_filter_v1_rb[fil[x * 3 + 2]][fil[(x - 1) * 3 + 2]]; + } + for (x = 0; x < svga->overlay_latch.xsize; x++) { + fil[(x)*3] = vb_filter_v1_rb[fil[x * 3]][fil3[(x + 1) * 3]]; + fil[(x)*3 + 1] = vb_filter_v1_g[fil[x * 3 + 1]][fil3[(x + 1) * 3 + 1]]; + fil[(x)*3 + 2] = vb_filter_v1_rb[fil[x * 3 + 2]][fil3[(x + 1) * 3 + 2]]; + p[x] = (fil[x * 3 + 2] << 16) | (fil[x * 3 + 1] << 8) | fil[x * 3]; + } + } else /* filter disabled by emulator option */ + { + if (banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) { + for (x = 0; x < svga->overlay_latch.xsize; x++) { + p[x] = banshee->overlay_buffer[0][src_x >> 20]; + src_x += voodoo->overlay.vidOverlayDudx; + } + } else { + for (x = 0; x < svga->overlay_latch.xsize; x++) + p[x] = banshee->overlay_buffer[0][x]; + } + } + break; - case VIDPROCCFG_FILTER_MODE_DITHER_2X2: - if (banshee->voodoo->scrfilter && banshee->voodoo->scrfilterEnabled) { - uint8_t fil[(svga->overlay_latch.xsize) * 3]; - uint8_t soak[(svga->overlay_latch.xsize) * 3]; - uint8_t soak2[(svga->overlay_latch.xsize) * 3]; + case VIDPROCCFG_FILTER_MODE_DITHER_2X2: + if (banshee->voodoo->scrfilter && banshee->voodoo->scrfilterEnabled) { + uint8_t fil[(svga->overlay_latch.xsize) * 3]; + uint8_t soak[(svga->overlay_latch.xsize) * 3]; + uint8_t soak2[(svga->overlay_latch.xsize) * 3]; - uint8_t samp1[(svga->overlay_latch.xsize) * 3]; - uint8_t samp2[(svga->overlay_latch.xsize) * 3]; - uint8_t samp3[(svga->overlay_latch.xsize) * 3]; - uint8_t samp4[(svga->overlay_latch.xsize) * 3]; + uint8_t samp1[(svga->overlay_latch.xsize) * 3]; + uint8_t samp2[(svga->overlay_latch.xsize) * 3]; + uint8_t samp3[(svga->overlay_latch.xsize) * 3]; + uint8_t samp4[(svga->overlay_latch.xsize) * 3]; - src = &svga->vram[src_addr2 & svga->vram_mask]; - OVERLAY_SAMPLE(banshee->overlay_buffer[1]); - for (x = 0; x < svga->overlay_latch.xsize; x++) { - samp1[x * 3] = ((banshee->overlay_buffer[0][x])); - samp1[x * 3 + 1] = ((banshee->overlay_buffer[0][x] >> 8)); - samp1[x * 3 + 2] = ((banshee->overlay_buffer[0][x] >> 16)); + src = &svga->vram[src_addr2 & svga->vram_mask]; + OVERLAY_SAMPLE(banshee->overlay_buffer[1]); + for (x = 0; x < svga->overlay_latch.xsize; x++) { + samp1[x * 3] = ((banshee->overlay_buffer[0][x])); + samp1[x * 3 + 1] = ((banshee->overlay_buffer[0][x] >> 8)); + samp1[x * 3 + 2] = ((banshee->overlay_buffer[0][x] >> 16)); - samp2[x * 3 + 0] = ((banshee->overlay_buffer[0][x + 1])); - samp2[x * 3 + 1] = ((banshee->overlay_buffer[0][x + 1] >> 8)); - samp2[x * 3 + 2] = ((banshee->overlay_buffer[0][x + 1] >> 16)); + samp2[x * 3 + 0] = ((banshee->overlay_buffer[0][x + 1])); + samp2[x * 3 + 1] = ((banshee->overlay_buffer[0][x + 1] >> 8)); + samp2[x * 3 + 2] = ((banshee->overlay_buffer[0][x + 1] >> 16)); - samp3[x * 3 + 0] = ((banshee->overlay_buffer[1][x])); - samp3[x * 3 + 1] = ((banshee->overlay_buffer[1][x] >> 8)); - samp3[x * 3 + 2] = ((banshee->overlay_buffer[1][x] >> 16)); + samp3[x * 3 + 0] = ((banshee->overlay_buffer[1][x])); + samp3[x * 3 + 1] = ((banshee->overlay_buffer[1][x] >> 8)); + samp3[x * 3 + 2] = ((banshee->overlay_buffer[1][x] >> 16)); - samp4[x * 3 + 0] = ((banshee->overlay_buffer[1][x + 1])); - samp4[x * 3 + 1] = ((banshee->overlay_buffer[1][x + 1] >> 8)); - samp4[x * 3 + 2] = ((banshee->overlay_buffer[1][x + 1] >> 16)); + samp4[x * 3 + 0] = ((banshee->overlay_buffer[1][x + 1])); + samp4[x * 3 + 1] = ((banshee->overlay_buffer[1][x + 1] >> 8)); + samp4[x * 3 + 2] = ((banshee->overlay_buffer[1][x + 1] >> 16)); - /* sample two lines */ + /* sample two lines */ - soak[x * 3 + 0] = vb_filter_bx_rb[samp1[x * 3 + 0]][samp2[x * 3 + 0]]; - soak[x * 3 + 1] = vb_filter_bx_g[samp1[x * 3 + 1]][samp2[x * 3 + 1]]; - soak[x * 3 + 2] = vb_filter_bx_rb[samp1[x * 3 + 2]][samp2[x * 3 + 2]]; + soak[x * 3 + 0] = vb_filter_bx_rb[samp1[x * 3 + 0]][samp2[x * 3 + 0]]; + soak[x * 3 + 1] = vb_filter_bx_g[samp1[x * 3 + 1]][samp2[x * 3 + 1]]; + soak[x * 3 + 2] = vb_filter_bx_rb[samp1[x * 3 + 2]][samp2[x * 3 + 2]]; - soak2[x * 3 + 0] = vb_filter_bx_rb[samp3[x * 3 + 0]][samp4[x * 3 + 0]]; - soak2[x * 3 + 1] = vb_filter_bx_g[samp3[x * 3 + 1]][samp4[x * 3 + 1]]; - soak2[x * 3 + 2] = vb_filter_bx_rb[samp3[x * 3 + 2]][samp4[x * 3 + 2]]; + soak2[x * 3 + 0] = vb_filter_bx_rb[samp3[x * 3 + 0]][samp4[x * 3 + 0]]; + soak2[x * 3 + 1] = vb_filter_bx_g[samp3[x * 3 + 1]][samp4[x * 3 + 1]]; + soak2[x * 3 + 2] = vb_filter_bx_rb[samp3[x * 3 + 2]][samp4[x * 3 + 2]]; - /* then pour it on the rest */ + /* then pour it on the rest */ - fil[x * 3 + 0] = vb_filter_v1_rb[soak[x * 3 + 0]][soak2[x * 3 + 0]]; - fil[x * 3 + 1] = vb_filter_v1_g[soak[x * 3 + 1]][soak2[x * 3 + 1]]; - fil[x * 3 + 2] = vb_filter_v1_rb[soak[x * 3 + 2]][soak2[x * 3 + 2]]; - } + fil[x * 3 + 0] = vb_filter_v1_rb[soak[x * 3 + 0]][soak2[x * 3 + 0]]; + fil[x * 3 + 1] = vb_filter_v1_g[soak[x * 3 + 1]][soak2[x * 3 + 1]]; + fil[x * 3 + 2] = vb_filter_v1_rb[soak[x * 3 + 2]][soak2[x * 3 + 2]]; + } - if (banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) /* 2x2 on a scaled low res */ - { - for (x = 0; x < svga->overlay_latch.xsize; x++) { - p[x] = (fil[(src_x >> 20) * 3 + 2] << 16) | (fil[(src_x >> 20) * 3 + 1] << 8) | fil[(src_x >> 20) * 3]; - src_x += voodoo->overlay.vidOverlayDudx; - } - } else { - for (x = 0; x < svga->overlay_latch.xsize; x++) { - p[x] = (fil[x * 3 + 2] << 16) | (fil[x * 3 + 1] << 8) | fil[x * 3]; - } - } - } else /* filter disabled by emulator option */ - { - if (banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) { - for (x = 0; x < svga->overlay_latch.xsize; x++) { - p[x] = banshee->overlay_buffer[0][src_x >> 20]; + if (banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) /* 2x2 on a scaled low res */ + { + for (x = 0; x < svga->overlay_latch.xsize; x++) { + p[x] = (fil[(src_x >> 20) * 3 + 2] << 16) | (fil[(src_x >> 20) * 3 + 1] << 8) | + fil[(src_x >> 20) * 3]; + src_x += voodoo->overlay.vidOverlayDudx; + } + } else { + for (x = 0; x < svga->overlay_latch.xsize; x++) { + p[x] = (fil[x * 3 + 2] << 16) | (fil[x * 3 + 1] << 8) | fil[x * 3]; + } + } + } else /* filter disabled by emulator option */ + { + if (banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) { + for (x = 0; x < svga->overlay_latch.xsize; x++) { + p[x] = banshee->overlay_buffer[0][src_x >> 20]; - src_x += voodoo->overlay.vidOverlayDudx; - } - } else { - for (x = 0; x < svga->overlay_latch.xsize; x++) - p[x] = banshee->overlay_buffer[0][x]; - } - } - break; + src_x += voodoo->overlay.vidOverlayDudx; + } + } else { + for (x = 0; x < svga->overlay_latch.xsize; x++) + p[x] = banshee->overlay_buffer[0][x]; + } + } + break; - case VIDPROCCFG_FILTER_MODE_POINT: - default: - if (banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) { - for (x = 0; x < svga->overlay_latch.xsize; x++) { - p[x] = banshee->overlay_buffer[0][src_x >> 20]; + case VIDPROCCFG_FILTER_MODE_POINT: + default: + if (banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) { + for (x = 0; x < svga->overlay_latch.xsize; x++) { + p[x] = banshee->overlay_buffer[0][src_x >> 20]; - src_x += voodoo->overlay.vidOverlayDudx; - } - } else { - for (x = 0; x < svga->overlay_latch.xsize; x++) - p[x] = banshee->overlay_buffer[0][x]; - } - break; - } - } + src_x += voodoo->overlay.vidOverlayDudx; + } + } else { + for (x = 0; x < svga->overlay_latch.xsize; x++) + p[x] = banshee->overlay_buffer[0][x]; + } + break; + } + } - if (banshee->vidProcCfg & VIDPROCCFG_V_SCALE_ENABLE) - voodoo->overlay.src_y += voodoo->overlay.vidOverlayDvdy; - else - voodoo->overlay.src_y += (1 << 20); + if (banshee->vidProcCfg & VIDPROCCFG_V_SCALE_ENABLE) + voodoo->overlay.src_y += voodoo->overlay.vidOverlayDvdy; + else + voodoo->overlay.src_y += (1 << 20); } void banshee_set_overlay_addr(void *p, uint32_t addr) { - banshee_t *banshee = (banshee_t *)p; - voodoo_t *voodoo = banshee->voodoo; + banshee_t *banshee = (banshee_t *)p; + voodoo_t *voodoo = banshee->voodoo; - banshee->svga.overlay.addr = banshee->voodoo->leftOverlayBuf & 0xfffffff; - banshee->svga.overlay_latch.addr = banshee->voodoo->leftOverlayBuf & 0xfffffff; - memset(voodoo->dirty_line, 1, sizeof(voodoo->dirty_line)); + banshee->svga.overlay.addr = banshee->voodoo->leftOverlayBuf & 0xfffffff; + banshee->svga.overlay_latch.addr = banshee->voodoo->leftOverlayBuf & 0xfffffff; + memset(voodoo->dirty_line, 1, sizeof(voodoo->dirty_line)); } static void banshee_vsync_callback(svga_t *svga) { - banshee_t *banshee = (banshee_t *)svga->p; - voodoo_t *voodoo = banshee->voodoo; + banshee_t *banshee = (banshee_t *)svga->p; + voodoo_t *voodoo = banshee->voodoo; - voodoo->retrace_count++; - thread_lock_mutex(voodoo->swap_mutex); - if (voodoo->swap_pending && (voodoo->retrace_count > voodoo->swap_interval)) { - if (voodoo->swap_count > 0) - voodoo->swap_count--; - voodoo->swap_pending = 0; - thread_unlock_mutex(voodoo->swap_mutex); + voodoo->retrace_count++; + thread_lock_mutex(voodoo->swap_mutex); + if (voodoo->swap_pending && (voodoo->retrace_count > voodoo->swap_interval)) { + if (voodoo->swap_count > 0) + voodoo->swap_count--; + voodoo->swap_pending = 0; + thread_unlock_mutex(voodoo->swap_mutex); - memset(voodoo->dirty_line, 1, sizeof(voodoo->dirty_line)); - voodoo->retrace_count = 0; - banshee_set_overlay_addr(banshee, voodoo->swap_offset); - thread_set_event(voodoo->wake_fifo_thread); - voodoo->frame_count++; - } else - thread_unlock_mutex(voodoo->swap_mutex); + memset(voodoo->dirty_line, 1, sizeof(voodoo->dirty_line)); + voodoo->retrace_count = 0; + banshee_set_overlay_addr(banshee, voodoo->swap_offset); + thread_set_event(voodoo->wake_fifo_thread); + voodoo->frame_count++; + } else + thread_unlock_mutex(voodoo->swap_mutex); - voodoo->overlay.src_y = 0; - banshee->desktop_addr = banshee->vidDesktopStartAddr; - banshee->desktop_y = 0; + voodoo->overlay.src_y = 0; + banshee->desktop_addr = banshee->vidDesktopStartAddr; + banshee->desktop_y = 0; } static uint8_t banshee_pci_read(int func, int addr, void *p) { - banshee_t *banshee = (banshee_t *)p; -// svga_t *svga = &banshee->svga; - uint8_t ret = 0; + banshee_t *banshee = (banshee_t *)p; + // svga_t *svga = &banshee->svga; + uint8_t ret = 0; - if (func) - return 0xff; -// pclog("Banshee PCI read %08X ", addr); - switch (addr) { - case 0x00:ret = 0x1a; - break; /*3DFX*/ - case 0x01:ret = 0x12; - break; + if (func) + return 0xff; + // pclog("Banshee PCI read %08X ", addr); + switch (addr) { + case 0x00: + ret = 0x1a; + break; /*3DFX*/ + case 0x01: + ret = 0x12; + break; - case 0x02:ret = (banshee->type == TYPE_BANSHEE) ? 0x03 : 0x05; - break; - case 0x03:ret = 0x00; - break; + case 0x02: + ret = (banshee->type == TYPE_BANSHEE) ? 0x03 : 0x05; + break; + case 0x03: + ret = 0x00; + break; - case 0x04:ret = banshee->pci_regs[0x04] & 0x27; - break; + case 0x04: + ret = banshee->pci_regs[0x04] & 0x27; + break; - case 0x07:ret = banshee->pci_regs[0x07] & 0x36; - break; + case 0x07: + ret = banshee->pci_regs[0x07] & 0x36; + break; - case 0x08:ret = (banshee->type == TYPE_BANSHEE) ? 3 : 1; - break; /*Revision ID*/ - case 0x09:ret = 0; - break; /*Programming interface*/ + case 0x08: + ret = (banshee->type == TYPE_BANSHEE) ? 3 : 1; + break; /*Revision ID*/ + case 0x09: + ret = 0; + break; /*Programming interface*/ - case 0x0a:ret = 0x00; - break; /*Supports VGA interface*/ - case 0x0b:ret = 0x03; /*output = 3; */break; + case 0x0a: + ret = 0x00; + break; /*Supports VGA interface*/ + case 0x0b: + ret = 0x03; /*output = 3; */ + break; - case 0x0d:ret = banshee->pci_regs[0x0d] & 0xf8; - break; + case 0x0d: + ret = banshee->pci_regs[0x0d] & 0xf8; + break; - case 0x10:ret = 0x00; - break; /*memBaseAddr0*/ - case 0x11:ret = 0x00; - break; - case 0x12:ret = 0x00; - break; - case 0x13:ret = banshee->memBaseAddr0 >> 24; - break; + case 0x10: + ret = 0x00; + break; /*memBaseAddr0*/ + case 0x11: + ret = 0x00; + break; + case 0x12: + ret = 0x00; + break; + case 0x13: + ret = banshee->memBaseAddr0 >> 24; + break; - case 0x14:ret = 0x00; - break; /*memBaseAddr1*/ - case 0x15:ret = 0x00; - break; - case 0x16:ret = 0x00; - break; - case 0x17:ret = banshee->memBaseAddr1 >> 24; - break; + case 0x14: + ret = 0x00; + break; /*memBaseAddr1*/ + case 0x15: + ret = 0x00; + break; + case 0x16: + ret = 0x00; + break; + case 0x17: + ret = banshee->memBaseAddr1 >> 24; + break; - case 0x18:ret = 0x01; - break; /*ioBaseAddr*/ - case 0x19:ret = banshee->ioBaseAddr >> 8; - break; - case 0x1a:ret = 0x00; - break; - case 0x1b:ret = 0x00; - break; + case 0x18: + ret = 0x01; + break; /*ioBaseAddr*/ + case 0x19: + ret = banshee->ioBaseAddr >> 8; + break; + case 0x1a: + ret = 0x00; + break; + case 0x1b: + ret = 0x00; + break; - /*Subsystem vendor ID*/ - case 0x2c:ret = banshee->pci_regs[0x2c]; - break; - case 0x2d:ret = banshee->pci_regs[0x2d]; - break; - case 0x2e:ret = banshee->pci_regs[0x2e]; - break; - case 0x2f:ret = banshee->pci_regs[0x2f]; - break; + /*Subsystem vendor ID*/ + case 0x2c: + ret = banshee->pci_regs[0x2c]; + break; + case 0x2d: + ret = banshee->pci_regs[0x2d]; + break; + case 0x2e: + ret = banshee->pci_regs[0x2e]; + break; + case 0x2f: + ret = banshee->pci_regs[0x2f]; + break; - case 0x30:ret = banshee->pci_regs[0x30] & 0x01; - break; /*BIOS ROM address*/ - case 0x31:ret = 0x00; - break; - case 0x32:ret = banshee->pci_regs[0x32]; - break; - case 0x33:ret = banshee->pci_regs[0x33]; - break; + case 0x30: + ret = banshee->pci_regs[0x30] & 0x01; + break; /*BIOS ROM address*/ + case 0x31: + ret = 0x00; + break; + case 0x32: + ret = banshee->pci_regs[0x32]; + break; + case 0x33: + ret = banshee->pci_regs[0x33]; + break; - case 0x3c:ret = banshee->pci_regs[0x3c]; - break; + case 0x3c: + ret = banshee->pci_regs[0x3c]; + break; - case 0x3d:ret = 0x01; - break; /*INTA*/ + case 0x3d: + ret = 0x01; + break; /*INTA*/ - case 0x3e:ret = 0x04; - break; - case 0x3f:ret = 0xff; - break; - - } -// pclog("%02X\n", ret); - return ret; + case 0x3e: + ret = 0x04; + break; + case 0x3f: + ret = 0xff; + break; + } + // pclog("%02X\n", ret); + return ret; } static void banshee_pci_write(int func, int addr, uint8_t val, void *p) { - banshee_t *banshee = (banshee_t *)p; -// svga_t *svga = &banshee->svga; + banshee_t *banshee = (banshee_t *)p; + // svga_t *svga = &banshee->svga; - if (func) - return; -// pclog("Banshee write %08X %02X %04X:%08X\n", addr, val, CS, cpu_state.pc); - switch (addr) { - case 0x00: - case 0x01: - case 0x02: - case 0x03: - case 0x08: - case 0x09: - case 0x0a: - case 0x0b: - case 0x3d: - case 0x3e: - case 0x3f:return; + if (func) + return; + // pclog("Banshee write %08X %02X %04X:%08X\n", addr, val, CS, cpu_state.pc); + switch (addr) { + case 0x00: + case 0x01: + case 0x02: + case 0x03: + case 0x08: + case 0x09: + case 0x0a: + case 0x0b: + case 0x3d: + case 0x3e: + case 0x3f: + return; - case PCI_REG_COMMAND: - if (val & PCI_COMMAND_IO) { - io_removehandler(0x03c0, 0x0020, banshee_in, NULL, NULL, banshee_out, NULL, NULL, banshee); - if (banshee->ioBaseAddr) - io_removehandler(banshee->ioBaseAddr, 0x0100, banshee_ext_in, NULL, banshee_ext_inl, banshee_ext_out, NULL, banshee_ext_outl, banshee); + case PCI_REG_COMMAND: + if (val & PCI_COMMAND_IO) { + io_removehandler(0x03c0, 0x0020, banshee_in, NULL, NULL, banshee_out, NULL, NULL, banshee); + if (banshee->ioBaseAddr) + io_removehandler(banshee->ioBaseAddr, 0x0100, banshee_ext_in, NULL, banshee_ext_inl, + banshee_ext_out, NULL, banshee_ext_outl, banshee); - io_sethandler(0x03c0, 0x0020, banshee_in, NULL, NULL, banshee_out, NULL, NULL, banshee); - if (banshee->ioBaseAddr) - io_sethandler(banshee->ioBaseAddr, 0x0100, banshee_ext_in, NULL, banshee_ext_inl, banshee_ext_out, NULL, banshee_ext_outl, banshee); - } else { - io_removehandler(0x03c0, 0x0020, banshee_in, NULL, NULL, banshee_out, NULL, NULL, banshee); - io_removehandler(banshee->ioBaseAddr, 0x0100, banshee_ext_in, NULL, banshee_ext_inl, banshee_ext_out, NULL, banshee_ext_outl, banshee); - } - banshee->pci_regs[PCI_REG_COMMAND] = val & 0x27; - banshee_updatemapping(banshee); - return; - case 0x07:banshee->pci_regs[0x07] = val & 0x3e; - return; - case 0x0d:banshee->pci_regs[0x0d] = val & 0xf8; - return; + io_sethandler(0x03c0, 0x0020, banshee_in, NULL, NULL, banshee_out, NULL, NULL, banshee); + if (banshee->ioBaseAddr) + io_sethandler(banshee->ioBaseAddr, 0x0100, banshee_ext_in, NULL, banshee_ext_inl, banshee_ext_out, + NULL, banshee_ext_outl, banshee); + } else { + io_removehandler(0x03c0, 0x0020, banshee_in, NULL, NULL, banshee_out, NULL, NULL, banshee); + io_removehandler(banshee->ioBaseAddr, 0x0100, banshee_ext_in, NULL, banshee_ext_inl, banshee_ext_out, + NULL, banshee_ext_outl, banshee); + } + banshee->pci_regs[PCI_REG_COMMAND] = val & 0x27; + banshee_updatemapping(banshee); + return; + case 0x07: + banshee->pci_regs[0x07] = val & 0x3e; + return; + case 0x0d: + banshee->pci_regs[0x0d] = val & 0xf8; + return; - case 0x13:banshee->memBaseAddr0 = (val & 0xfe) << 24; - banshee_updatemapping(banshee); - return; + case 0x13: + banshee->memBaseAddr0 = (val & 0xfe) << 24; + banshee_updatemapping(banshee); + return; - case 0x17:banshee->memBaseAddr1 = (val & 0xfe) << 24; - banshee_updatemapping(banshee); - return; + case 0x17: + banshee->memBaseAddr1 = (val & 0xfe) << 24; + banshee_updatemapping(banshee); + return; - case 0x19: - if (banshee->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) - io_removehandler(banshee->ioBaseAddr, 0x0100, banshee_ext_in, NULL, banshee_ext_inl, banshee_ext_out, NULL, banshee_ext_outl, banshee); - banshee->ioBaseAddr = val << 8; - if ((banshee->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) && banshee->ioBaseAddr) - io_sethandler(banshee->ioBaseAddr, 0x0100, banshee_ext_in, NULL, banshee_ext_inl, banshee_ext_out, NULL, banshee_ext_outl, banshee); - pclog("Banshee ioBaseAddr=%08x\n", banshee->ioBaseAddr); -// s3_virge_updatemapping(virge); - return; + case 0x19: + if (banshee->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) + io_removehandler(banshee->ioBaseAddr, 0x0100, banshee_ext_in, NULL, banshee_ext_inl, banshee_ext_out, + NULL, banshee_ext_outl, banshee); + banshee->ioBaseAddr = val << 8; + if ((banshee->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) && banshee->ioBaseAddr) + io_sethandler(banshee->ioBaseAddr, 0x0100, banshee_ext_in, NULL, banshee_ext_inl, banshee_ext_out, NULL, + banshee_ext_outl, banshee); + pclog("Banshee ioBaseAddr=%08x\n", banshee->ioBaseAddr); + // s3_virge_updatemapping(virge); + return; - case 0x30: - case 0x32: - case 0x33:banshee->pci_regs[addr] = val; - if (banshee->pci_regs[0x30] & 0x01) { - uint32_t addr = (banshee->pci_regs[0x32] << 16) | (banshee->pci_regs[0x33] << 24); - pclog("Banshee bios_rom enabled at %08x\n", addr); - mem_mapping_set_addr(&banshee->bios_rom.mapping, addr, 0x10000); - mem_mapping_enable(&banshee->bios_rom.mapping); - } else { - pclog("Banshee bios_rom disabled\n"); - mem_mapping_disable(&banshee->bios_rom.mapping); - } - return; - case 0x3c:banshee->pci_regs[0x3c] = val; - return; - } + case 0x30: + case 0x32: + case 0x33: + banshee->pci_regs[addr] = val; + if (banshee->pci_regs[0x30] & 0x01) { + uint32_t addr = (banshee->pci_regs[0x32] << 16) | (banshee->pci_regs[0x33] << 24); + pclog("Banshee bios_rom enabled at %08x\n", addr); + mem_mapping_set_addr(&banshee->bios_rom.mapping, addr, 0x10000); + mem_mapping_enable(&banshee->bios_rom.mapping); + } else { + pclog("Banshee bios_rom disabled\n"); + mem_mapping_disable(&banshee->bios_rom.mapping); + } + return; + case 0x3c: + banshee->pci_regs[0x3c] = val; + return; + } } -static device_config_t banshee_sgram_config[] = - { - { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "8 MB", - .value = 8 - }, - { - .description = "16 MB", - .value = 16 - }, - { - .description = "" - } - }, - .default_int = 16 - }, - { - .name = "bilinear", - .description = "Bilinear filtering", - .type = CONFIG_BINARY, - .default_int = 1 - }, - { - .name = "dithersub", - .description = "Dither subtraction", - .type = CONFIG_BINARY, - .default_int = 1 - }, - { - .name = "dacfilter", - .description = "Screen Filter", - .type = CONFIG_BINARY, - .default_int = 0 - }, - { - .name = "render_threads", - .description = "Render threads", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "1", - .value = 1 - }, - { - .description = "2", - .value = 2 - }, - { - .description = "4", - .value = 4 - }, - { - .description = "" - } - }, - .default_int = 2 - }, +static device_config_t banshee_sgram_config[] = { + {.name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .selection = {{.description = "8 MB", .value = 8}, {.description = "16 MB", .value = 16}, {.description = ""}}, + .default_int = 16}, + {.name = "bilinear", .description = "Bilinear filtering", .type = CONFIG_BINARY, .default_int = 1}, + {.name = "dithersub", .description = "Dither subtraction", .type = CONFIG_BINARY, .default_int = 1}, + {.name = "dacfilter", .description = "Screen Filter", .type = CONFIG_BINARY, .default_int = 0}, + {.name = "render_threads", + .description = "Render threads", + .type = CONFIG_SELECTION, + .selection = {{.description = "1", .value = 1}, + {.description = "2", .value = 2}, + {.description = "4", .value = 4}, + {.description = ""}}, + .default_int = 2}, #ifndef NO_CODEGEN - { - .name = "recompiler", - .description = "Recompiler", - .type = CONFIG_BINARY, - .default_int = 1 - }, + {.name = "recompiler", .description = "Recompiler", .type = CONFIG_BINARY, .default_int = 1}, #endif - { - .type = -1 - } - }; + {.type = -1}}; -static device_config_t banshee_sdram_config[] = - { - { - .name = "bilinear", - .description = "Bilinear filtering", - .type = CONFIG_BINARY, - .default_int = 1 - }, - { - .name = "dithersub", - .description = "Dither subtraction", - .type = CONFIG_BINARY, - .default_int = 1 - }, - { - .name = "dacfilter", - .description = "Screen Filter", - .type = CONFIG_BINARY, - .default_int = 0 - }, - { - .name = "render_threads", - .description = "Render threads", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "1", - .value = 1 - }, - { - .description = "2", - .value = 2 - }, - { - .description = "4", - .value = 4 - }, - { - .description = "" - } - }, - .default_int = 2 - }, +static device_config_t banshee_sdram_config[] = { + {.name = "bilinear", .description = "Bilinear filtering", .type = CONFIG_BINARY, .default_int = 1}, + {.name = "dithersub", .description = "Dither subtraction", .type = CONFIG_BINARY, .default_int = 1}, + {.name = "dacfilter", .description = "Screen Filter", .type = CONFIG_BINARY, .default_int = 0}, + {.name = "render_threads", + .description = "Render threads", + .type = CONFIG_SELECTION, + .selection = {{.description = "1", .value = 1}, + {.description = "2", .value = 2}, + {.description = "4", .value = 4}, + {.description = ""}}, + .default_int = 2}, #ifndef NO_CODEGEN - { - .name = "recompiler", - .description = "Recompiler", - .type = CONFIG_BINARY, - .default_int = 1 - }, + {.name = "recompiler", .description = "Recompiler", .type = CONFIG_BINARY, .default_int = 1}, #endif - { - .type = -1 - } - }; + {.type = -1}}; static void *banshee_init_common(char *fn, int has_sgram, int type, int voodoo_type) { - int mem_size; - banshee_t *banshee = malloc(sizeof(banshee_t)); - memset(banshee, 0, sizeof(banshee_t)); + int mem_size; + banshee_t *banshee = malloc(sizeof(banshee_t)); + memset(banshee, 0, sizeof(banshee_t)); - banshee->type = type; + banshee->type = type; - rom_init(&banshee->bios_rom, fn, 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); - mem_mapping_disable(&banshee->bios_rom.mapping); + rom_init(&banshee->bios_rom, fn, 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); + mem_mapping_disable(&banshee->bios_rom.mapping); - if (has_sgram) - mem_size = device_get_config_int("memory"); - else - mem_size = 16; /*SDRAM Banshee only supports 16 MB*/ + if (has_sgram) + mem_size = device_get_config_int("memory"); + else + mem_size = 16; /*SDRAM Banshee only supports 16 MB*/ - svga_init(&banshee->svga, banshee, mem_size << 20, - banshee_recalctimings, - banshee_in, banshee_out, - banshee_hwcursor_draw, - banshee_overlay_draw); - banshee->svga.vsync_callback = banshee_vsync_callback; + svga_init(&banshee->svga, banshee, mem_size << 20, banshee_recalctimings, banshee_in, banshee_out, banshee_hwcursor_draw, + banshee_overlay_draw); + banshee->svga.vsync_callback = banshee_vsync_callback; - mem_mapping_add(&banshee->linear_mapping, 0, 0, banshee_read_linear, - banshee_read_linear_w, - banshee_read_linear_l, - banshee_write_linear, - banshee_write_linear_w, - banshee_write_linear_l, - NULL, - MEM_MAPPING_EXTERNAL, - &banshee->svga); - mem_mapping_add(&banshee->reg_mapping_low, 0, 0, banshee_reg_read, - banshee_reg_readw, - banshee_reg_readl, - banshee_reg_write, - banshee_reg_writew, - banshee_reg_writel, - NULL, - MEM_MAPPING_EXTERNAL, - banshee); - mem_mapping_add(&banshee->reg_mapping_high, 0, 0, banshee_reg_read, - banshee_reg_readw, - banshee_reg_readl, - banshee_reg_write, - banshee_reg_writew, - banshee_reg_writel, - NULL, - MEM_MAPPING_EXTERNAL, - banshee); + mem_mapping_add(&banshee->linear_mapping, 0, 0, banshee_read_linear, banshee_read_linear_w, banshee_read_linear_l, + banshee_write_linear, banshee_write_linear_w, banshee_write_linear_l, NULL, MEM_MAPPING_EXTERNAL, + &banshee->svga); + mem_mapping_add(&banshee->reg_mapping_low, 0, 0, banshee_reg_read, banshee_reg_readw, banshee_reg_readl, + banshee_reg_write, banshee_reg_writew, banshee_reg_writel, NULL, MEM_MAPPING_EXTERNAL, banshee); + mem_mapping_add(&banshee->reg_mapping_high, 0, 0, banshee_reg_read, banshee_reg_readw, banshee_reg_readl, + banshee_reg_write, banshee_reg_writew, banshee_reg_writel, NULL, MEM_MAPPING_EXTERNAL, banshee); -// io_sethandler(0x03c0, 0x0020, banshee_in, NULL, NULL, banshee_out, NULL, NULL, banshee); + // io_sethandler(0x03c0, 0x0020, banshee_in, NULL, NULL, banshee_out, NULL, NULL, banshee); - banshee->svga.bpp = 8; - banshee->svga.miscout = 1; + banshee->svga.bpp = 8; + banshee->svga.miscout = 1; - banshee->dramInit0 = 1 << 27; - if (has_sgram && mem_size == 16) - banshee->dramInit0 |= (1 << 26); /*2xSGRAM = 16 MB*/ - if (!has_sgram) - banshee->dramInit1 = 1 << 30; /*SDRAM*/ - banshee->svga.decode_mask = 0x1ffffff; + banshee->dramInit0 = 1 << 27; + if (has_sgram && mem_size == 16) + banshee->dramInit0 |= (1 << 26); /*2xSGRAM = 16 MB*/ + if (!has_sgram) + banshee->dramInit1 = 1 << 30; /*SDRAM*/ + banshee->svga.decode_mask = 0x1ffffff; - pci_add(banshee_pci_read, banshee_pci_write, banshee); + pci_add(banshee_pci_read, banshee_pci_write, banshee); - banshee->voodoo = voodoo_2d3d_card_init(voodoo_type); - banshee->voodoo->p = banshee; - banshee->voodoo->vram = banshee->svga.vram; - banshee->voodoo->changedvram = banshee->svga.changedvram; - banshee->voodoo->fb_mem = banshee->svga.vram; - banshee->voodoo->fb_mask = banshee->svga.vram_mask; - banshee->voodoo->tex_mem[0] = banshee->svga.vram; - banshee->voodoo->tex_mem_w[0] = (uint16_t *)banshee->svga.vram; - banshee->voodoo->tex_mem[1] = banshee->svga.vram; - banshee->voodoo->tex_mem_w[1] = (uint16_t *)banshee->svga.vram; - banshee->voodoo->texture_mask = banshee->svga.vram_mask; - voodoo_generate_filter_v1(banshee->voodoo); + banshee->voodoo = voodoo_2d3d_card_init(voodoo_type); + banshee->voodoo->p = banshee; + banshee->voodoo->vram = banshee->svga.vram; + banshee->voodoo->changedvram = banshee->svga.changedvram; + banshee->voodoo->fb_mem = banshee->svga.vram; + banshee->voodoo->fb_mask = banshee->svga.vram_mask; + banshee->voodoo->tex_mem[0] = banshee->svga.vram; + banshee->voodoo->tex_mem_w[0] = (uint16_t *)banshee->svga.vram; + banshee->voodoo->tex_mem[1] = banshee->svga.vram; + banshee->voodoo->tex_mem_w[1] = (uint16_t *)banshee->svga.vram; + banshee->voodoo->texture_mask = banshee->svga.vram_mask; + voodoo_generate_filter_v1(banshee->voodoo); - banshee->vidSerialParallelPort = VIDSERIAL_DDC_DCK_W | VIDSERIAL_DDC_DDA_W; + banshee->vidSerialParallelPort = VIDSERIAL_DDC_DCK_W | VIDSERIAL_DDC_DDA_W; - ddc_init(); + ddc_init(); - switch (type) { - case TYPE_BANSHEE: - if (has_sgram) { - banshee->pci_regs[0x2c] = 0x1a; - banshee->pci_regs[0x2d] = 0x12; - banshee->pci_regs[0x2e] = 0x04; - banshee->pci_regs[0x2f] = 0x00; - } else { - banshee->pci_regs[0x2c] = 0x02; - banshee->pci_regs[0x2d] = 0x11; - banshee->pci_regs[0x2e] = 0x17; - banshee->pci_regs[0x2f] = 0x10; - } - break; + switch (type) { + case TYPE_BANSHEE: + if (has_sgram) { + banshee->pci_regs[0x2c] = 0x1a; + banshee->pci_regs[0x2d] = 0x12; + banshee->pci_regs[0x2e] = 0x04; + banshee->pci_regs[0x2f] = 0x00; + } else { + banshee->pci_regs[0x2c] = 0x02; + banshee->pci_regs[0x2d] = 0x11; + banshee->pci_regs[0x2e] = 0x17; + banshee->pci_regs[0x2f] = 0x10; + } + break; - case TYPE_V3_2000:banshee->pci_regs[0x2c] = 0x1a; - banshee->pci_regs[0x2d] = 0x12; - banshee->pci_regs[0x2e] = 0x30; - banshee->pci_regs[0x2f] = 0x00; - break; + case TYPE_V3_2000: + banshee->pci_regs[0x2c] = 0x1a; + banshee->pci_regs[0x2d] = 0x12; + banshee->pci_regs[0x2e] = 0x30; + banshee->pci_regs[0x2f] = 0x00; + break; - case TYPE_V3_3000:banshee->pci_regs[0x2c] = 0x1a; - banshee->pci_regs[0x2d] = 0x12; - banshee->pci_regs[0x2e] = 0x3a; - banshee->pci_regs[0x2f] = 0x00; - break; - } + case TYPE_V3_3000: + banshee->pci_regs[0x2c] = 0x1a; + banshee->pci_regs[0x2d] = 0x12; + banshee->pci_regs[0x2e] = 0x3a; + banshee->pci_regs[0x2f] = 0x00; + break; + } - return banshee; + return banshee; } -static void *banshee_init() { - return banshee_init_common("pci_sg.rom", 1, TYPE_BANSHEE, VOODOO_BANSHEE); -} -static void *creative_banshee_init() { - return banshee_init_common("blasterpci.rom", 0, TYPE_BANSHEE, VOODOO_BANSHEE); -} -static void *v3_2000_init() { - return banshee_init_common("voodoo3_2000/2k11sd.rom", 0, TYPE_V3_2000, VOODOO_3); -} -static void *v3_3000_init() { - return banshee_init_common("voodoo3_3000/3k12sd.rom", 0, TYPE_V3_3000, VOODOO_3); -} +static void *banshee_init() { return banshee_init_common("pci_sg.rom", 1, TYPE_BANSHEE, VOODOO_BANSHEE); } +static void *creative_banshee_init() { return banshee_init_common("blasterpci.rom", 0, TYPE_BANSHEE, VOODOO_BANSHEE); } +static void *v3_2000_init() { return banshee_init_common("voodoo3_2000/2k11sd.rom", 0, TYPE_V3_2000, VOODOO_3); } +static void *v3_3000_init() { return banshee_init_common("voodoo3_3000/3k12sd.rom", 0, TYPE_V3_3000, VOODOO_3); } -static int banshee_available() { - return rom_present("pci_sg.rom"); -} -static int creative_banshee_available() { - return rom_present("blasterpci.rom"); -} -static int v3_2000_available() { - return rom_present("voodoo3_2000/2k11sd.rom"); -} -static int v3_3000_available() { - return rom_present("voodoo3_3000/3k12sd.rom"); -} +static int banshee_available() { return rom_present("pci_sg.rom"); } +static int creative_banshee_available() { return rom_present("blasterpci.rom"); } +static int v3_2000_available() { return rom_present("voodoo3_2000/2k11sd.rom"); } +static int v3_3000_available() { return rom_present("voodoo3_3000/3k12sd.rom"); } static void banshee_close(void *p) { - banshee_t *banshee = (banshee_t *)p; + banshee_t *banshee = (banshee_t *)p; - voodoo_card_close(banshee->voodoo); - svga_close(&banshee->svga); + voodoo_card_close(banshee->voodoo); + svga_close(&banshee->svga); - free(banshee); + free(banshee); } static void banshee_speed_changed(void *p) { - banshee_t *banshee = (banshee_t *)p; + banshee_t *banshee = (banshee_t *)p; - svga_recalctimings(&banshee->svga); + svga_recalctimings(&banshee->svga); } static void banshee_force_redraw(void *p) { - banshee_t *banshee = (banshee_t *)p; + banshee_t *banshee = (banshee_t *)p; - banshee->svga.fullchange = changeframecount; + banshee->svga.fullchange = changeframecount; } static uint64_t status_time = 0; static void banshee_add_status_info(char *s, int max_len, void *p) { - banshee_t *banshee = (banshee_t *)p; - voodoo_t *voodoo = banshee->voodoo; - char temps[512]; - int pixel_count_current[4]; - int pixel_count_total; - int texel_count_current[4]; - int texel_count_total; - int render_time[4]; - uint64_t new_time = timer_read(); - uint64_t status_diff = new_time - status_time; - int c; - status_time = new_time; + banshee_t *banshee = (banshee_t *)p; + voodoo_t *voodoo = banshee->voodoo; + char temps[512]; + int pixel_count_current[4]; + int pixel_count_total; + int texel_count_current[4]; + int texel_count_total; + int render_time[4]; + uint64_t new_time = timer_read(); + uint64_t status_diff = new_time - status_time; + int c; + status_time = new_time; - svga_add_status_info(s, max_len, &banshee->svga); + svga_add_status_info(s, max_len, &banshee->svga); - for (c = 0; c < 4; c++) { - pixel_count_current[c] = voodoo->pixel_count[c]; - texel_count_current[c] = voodoo->texel_count[c]; - render_time[c] = voodoo->render_time[c]; - } + for (c = 0; c < 4; c++) { + pixel_count_current[c] = voodoo->pixel_count[c]; + texel_count_current[c] = voodoo->texel_count[c]; + render_time[c] = voodoo->render_time[c]; + } - pixel_count_total = (pixel_count_current[0] + pixel_count_current[1] + pixel_count_current[2] + pixel_count_current[3]) - - (voodoo->pixel_count_old[0] + voodoo->pixel_count_old[1] + voodoo->pixel_count_old[2] + voodoo->pixel_count_old[3]); - texel_count_total = (texel_count_current[0] + texel_count_current[1] + texel_count_current[2] + texel_count_current[3]) - - (voodoo->texel_count_old[0] + voodoo->texel_count_old[1] + voodoo->texel_count_old[2] + voodoo->texel_count_old[3]); - sprintf(temps, "%f Mpixels/sec (%f)\n%f Mtexels/sec (%f)\n%f ktris/sec\n%f%% CPU (%f%% real)\n%d frames/sec (%i)\n%f%% CPU (%f%% real)\n"/*%d reads/sec\n%d write/sec\n%d tex/sec\n*/, - (double)pixel_count_total / 1000000.0, - ((double)pixel_count_total / 1000000.0) / ((double)render_time[0] / status_diff), - (double)texel_count_total / 1000000.0, - ((double)texel_count_total / 1000000.0) / ((double)render_time[0] / status_diff), - (double)voodoo->tri_count / 1000.0, ((double)voodoo->time * 100.0) / timer_freq, ((double)voodoo->time * 100.0) / status_diff, voodoo->frame_count, voodoo_recomp, - ((double)voodoo->render_time[0] * 100.0) / timer_freq, ((double)voodoo->render_time[0] * 100.0) / status_diff); - if (voodoo->render_threads >= 2) { - char temps2[512]; - sprintf(temps2, "%f%% CPU (%f%% real)\n", - ((double)voodoo->render_time[1] * 100.0) / timer_freq, ((double)voodoo->render_time[1] * 100.0) / status_diff); - strncat(temps, temps2, sizeof(temps) - 1); - } - if (voodoo->render_threads == 4) { - char temps2[512]; - sprintf(temps2, "%f%% CPU (%f%% real)\n%f%% CPU (%f%% real)\n", - ((double)voodoo->render_time[2] * 100.0) / timer_freq, ((double)voodoo->render_time[2] * 100.0) / status_diff, - ((double)voodoo->render_time[3] * 100.0) / timer_freq, ((double)voodoo->render_time[3] * 100.0) / status_diff); - strncat(temps, temps2, sizeof(temps) - 1); - } + pixel_count_total = (pixel_count_current[0] + pixel_count_current[1] + pixel_count_current[2] + pixel_count_current[3]) - + (voodoo->pixel_count_old[0] + voodoo->pixel_count_old[1] + voodoo->pixel_count_old[2] + + voodoo->pixel_count_old[3]); + texel_count_total = (texel_count_current[0] + texel_count_current[1] + texel_count_current[2] + texel_count_current[3]) - + (voodoo->texel_count_old[0] + voodoo->texel_count_old[1] + voodoo->texel_count_old[2] + + voodoo->texel_count_old[3]); + sprintf(temps, + "%f Mpixels/sec (%f)\n%f Mtexels/sec (%f)\n%f ktris/sec\n%f%% CPU (%f%% real)\n%d frames/sec (%i)\n%f%% CPU " + "(%f%% real)\n" /*%d reads/sec\n%d write/sec\n%d tex/sec\n*/, + (double)pixel_count_total / 1000000.0, + ((double)pixel_count_total / 1000000.0) / ((double)render_time[0] / status_diff), + (double)texel_count_total / 1000000.0, + ((double)texel_count_total / 1000000.0) / ((double)render_time[0] / status_diff), + (double)voodoo->tri_count / 1000.0, ((double)voodoo->time * 100.0) / timer_freq, + ((double)voodoo->time * 100.0) / status_diff, voodoo->frame_count, voodoo_recomp, + ((double)voodoo->render_time[0] * 100.0) / timer_freq, ((double)voodoo->render_time[0] * 100.0) / status_diff); + if (voodoo->render_threads >= 2) { + char temps2[512]; + sprintf(temps2, "%f%% CPU (%f%% real)\n", ((double)voodoo->render_time[1] * 100.0) / timer_freq, + ((double)voodoo->render_time[1] * 100.0) / status_diff); + strncat(temps, temps2, sizeof(temps) - 1); + } + if (voodoo->render_threads == 4) { + char temps2[512]; + sprintf(temps2, "%f%% CPU (%f%% real)\n%f%% CPU (%f%% real)\n", + ((double)voodoo->render_time[2] * 100.0) / timer_freq, + ((double)voodoo->render_time[2] * 100.0) / status_diff, + ((double)voodoo->render_time[3] * 100.0) / timer_freq, + ((double)voodoo->render_time[3] * 100.0) / status_diff); + strncat(temps, temps2, sizeof(temps) - 1); + } - strncat(s, temps, max_len); + strncat(s, temps, max_len); - strncat(s, "Overlay mode: ", max_len); /* leilei debug additions */ - if ((banshee->vidProcCfg & VIDPROCCFG_FILTER_MODE_MASK) == VIDPROCCFG_FILTER_MODE_DITHER_2X2) - strncat(s, "2x2 box filter\n", max_len); - if ((banshee->vidProcCfg & VIDPROCCFG_FILTER_MODE_MASK) == VIDPROCCFG_FILTER_MODE_DITHER_4X4) - strncat(s, "4x1 tap filter\n", max_len); - if ((banshee->vidProcCfg & VIDPROCCFG_FILTER_MODE_MASK) == VIDPROCCFG_FILTER_MODE_POINT) - strncat(s, "Nearest neighbor\n", max_len); - if ((banshee->vidProcCfg & VIDPROCCFG_FILTER_MODE_MASK) == VIDPROCCFG_FILTER_MODE_BILINEAR) - strncat(s, "Bilinear filtered\n", max_len); - if ((banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE)) - strncat(s, "H scaled \n", max_len); - if ((banshee->vidProcCfg & VIDPROCCFG_V_SCALE_ENABLE)) - strncat(s, "V scaled \n", max_len); - if ((banshee->vidProcCfg & VIDPROCCFG_2X_MODE)) - strncat(s, "2X mode\n", max_len); + strncat(s, "Overlay mode: ", max_len); /* leilei debug additions */ + if ((banshee->vidProcCfg & VIDPROCCFG_FILTER_MODE_MASK) == VIDPROCCFG_FILTER_MODE_DITHER_2X2) + strncat(s, "2x2 box filter\n", max_len); + if ((banshee->vidProcCfg & VIDPROCCFG_FILTER_MODE_MASK) == VIDPROCCFG_FILTER_MODE_DITHER_4X4) + strncat(s, "4x1 tap filter\n", max_len); + if ((banshee->vidProcCfg & VIDPROCCFG_FILTER_MODE_MASK) == VIDPROCCFG_FILTER_MODE_POINT) + strncat(s, "Nearest neighbor\n", max_len); + if ((banshee->vidProcCfg & VIDPROCCFG_FILTER_MODE_MASK) == VIDPROCCFG_FILTER_MODE_BILINEAR) + strncat(s, "Bilinear filtered\n", max_len); + if ((banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE)) + strncat(s, "H scaled \n", max_len); + if ((banshee->vidProcCfg & VIDPROCCFG_V_SCALE_ENABLE)) + strncat(s, "V scaled \n", max_len); + if ((banshee->vidProcCfg & VIDPROCCFG_2X_MODE)) + strncat(s, "2X mode\n", max_len); - strncat(s, "\n", max_len); + strncat(s, "\n", max_len); - for (c = 0; c < 4; c++) { - voodoo->pixel_count_old[c] = pixel_count_current[c]; - voodoo->texel_count_old[c] = texel_count_current[c]; - voodoo->render_time[c] = 0; - } + for (c = 0; c < 4; c++) { + voodoo->pixel_count_old[c] = pixel_count_current[c]; + voodoo->texel_count_old[c] = texel_count_current[c]; + voodoo->render_time[c] = 0; + } - voodoo->tri_count = voodoo->frame_count = 0; - voodoo->rd_count = voodoo->wr_count = voodoo->tex_count = 0; - voodoo->time = 0; + voodoo->tri_count = voodoo->frame_count = 0; + voodoo->rd_count = voodoo->wr_count = voodoo->tex_count = 0; + voodoo->time = 0; - voodoo->read_time = pci_nonburst_time + pci_burst_time; + voodoo->read_time = pci_nonburst_time + pci_burst_time; - voodoo_recomp = 0; + voodoo_recomp = 0; } -device_t voodoo_banshee_device = - { - "Voodoo Banshee PCI (reference)", - DEVICE_PCI, - banshee_init, - banshee_close, - banshee_available, - banshee_speed_changed, - banshee_force_redraw, - banshee_add_status_info, - banshee_sgram_config - }; +device_t voodoo_banshee_device = {"Voodoo Banshee PCI (reference)", + DEVICE_PCI, + banshee_init, + banshee_close, + banshee_available, + banshee_speed_changed, + banshee_force_redraw, + banshee_add_status_info, + banshee_sgram_config}; -device_t creative_voodoo_banshee_device = - { - "Creative Labs 3D Blaster Banshee PCI", - DEVICE_PCI, - creative_banshee_init, - banshee_close, - creative_banshee_available, - banshee_speed_changed, - banshee_force_redraw, - banshee_add_status_info, - banshee_sdram_config - }; +device_t creative_voodoo_banshee_device = {"Creative Labs 3D Blaster Banshee PCI", + DEVICE_PCI, + creative_banshee_init, + banshee_close, + creative_banshee_available, + banshee_speed_changed, + banshee_force_redraw, + banshee_add_status_info, + banshee_sdram_config}; -device_t voodoo_3_2000_device = - { - "Voodoo 3 2000 PCI", - DEVICE_PCI, - v3_2000_init, - banshee_close, - v3_2000_available, - banshee_speed_changed, - banshee_force_redraw, - banshee_add_status_info, - banshee_sdram_config - }; +device_t voodoo_3_2000_device = {"Voodoo 3 2000 PCI", DEVICE_PCI, + v3_2000_init, banshee_close, + v3_2000_available, banshee_speed_changed, + banshee_force_redraw, banshee_add_status_info, + banshee_sdram_config}; -device_t voodoo_3_3000_device = - { - "Voodoo 3 3000 PCI", - DEVICE_PCI, - v3_3000_init, - banshee_close, - v3_3000_available, - banshee_speed_changed, - banshee_force_redraw, - banshee_add_status_info, - banshee_sdram_config - }; +device_t voodoo_3_3000_device = {"Voodoo 3 3000 PCI", DEVICE_PCI, + v3_3000_init, banshee_close, + v3_3000_available, banshee_speed_changed, + banshee_force_redraw, banshee_add_status_info, + banshee_sdram_config}; diff --git a/src/video/vid_voodoo_banshee_blitter.c b/src/video/vid_voodoo_banshee_blitter.c index bd00192e..2f123cf7 100644 --- a/src/video/vid_voodoo_banshee_blitter.c +++ b/src/video/vid_voodoo_banshee_blitter.c @@ -22,1328 +22,1525 @@ #include "vid_voodoo_banshee_blitter.h" #include "vid_voodoo_render.h" -#define COMMAND_CMD_MASK (0xf) -#define COMMAND_CMD_NOP (0 << 0) -#define COMMAND_CMD_SCREEN_TO_SCREEN_BLT (1 << 0) +#define COMMAND_CMD_MASK (0xf) +#define COMMAND_CMD_NOP (0 << 0) +#define COMMAND_CMD_SCREEN_TO_SCREEN_BLT (1 << 0) #define COMMAND_CMD_SCREEN_TO_SCREEN_STRETCH_BLT (2 << 0) -#define COMMAND_CMD_HOST_TO_SCREEN_BLT (3 << 0) -#define COMMAND_CMD_HOST_TO_SCREEN_STRETCH_BLT (4 << 0) -#define COMMAND_CMD_RECTFILL (5 << 0) -#define COMMAND_CMD_LINE (6 << 0) -#define COMMAND_CMD_POLYLINE (7 << 0) -#define COMMAND_CMD_POLYFILL (8 << 0) -#define COMMAND_INITIATE (1 << 8) -#define COMMAND_INC_X_START (1 << 10) -#define COMMAND_INC_Y_START (1 << 11) -#define COMMAND_STIPPLE_LINE (1 << 12) -#define COMMAND_PATTERN_MONO (1 << 13) -#define COMMAND_DX (1 << 14) -#define COMMAND_DY (1 << 15) -#define COMMAND_TRANS_MONO (1 << 16) -#define COMMAND_PATOFF_X_MASK (7 << 17) -#define COMMAND_PATOFF_X_SHIFT (17) -#define COMMAND_PATOFF_Y_MASK (7 << 20) -#define COMMAND_PATOFF_Y_SHIFT (20) -#define COMMAND_CLIP_SEL (1 << 23) +#define COMMAND_CMD_HOST_TO_SCREEN_BLT (3 << 0) +#define COMMAND_CMD_HOST_TO_SCREEN_STRETCH_BLT (4 << 0) +#define COMMAND_CMD_RECTFILL (5 << 0) +#define COMMAND_CMD_LINE (6 << 0) +#define COMMAND_CMD_POLYLINE (7 << 0) +#define COMMAND_CMD_POLYFILL (8 << 0) +#define COMMAND_INITIATE (1 << 8) +#define COMMAND_INC_X_START (1 << 10) +#define COMMAND_INC_Y_START (1 << 11) +#define COMMAND_STIPPLE_LINE (1 << 12) +#define COMMAND_PATTERN_MONO (1 << 13) +#define COMMAND_DX (1 << 14) +#define COMMAND_DY (1 << 15) +#define COMMAND_TRANS_MONO (1 << 16) +#define COMMAND_PATOFF_X_MASK (7 << 17) +#define COMMAND_PATOFF_X_SHIFT (17) +#define COMMAND_PATOFF_Y_MASK (7 << 20) +#define COMMAND_PATOFF_Y_SHIFT (20) +#define COMMAND_CLIP_SEL (1 << 23) -#define CMDEXTRA_SRC_COLORKEY (1 << 0) -#define CMDEXTRA_DST_COLORKEY (1 << 1) +#define CMDEXTRA_SRC_COLORKEY (1 << 0) +#define CMDEXTRA_DST_COLORKEY (1 << 1) #define CMDEXTRA_FORCE_PAT_ROW0 (1 << 3) #define SRC_FORMAT_STRIDE_MASK (0x1fff) -#define SRC_FORMAT_COL_MASK (0xf << 16) -#define SRC_FORMAT_COL_1_BPP (0 << 16) -#define SRC_FORMAT_COL_8_BPP (1 << 16) -#define SRC_FORMAT_COL_16_BPP (3 << 16) -#define SRC_FORMAT_COL_24_BPP (4 << 16) -#define SRC_FORMAT_COL_32_BPP (5 << 16) -#define SRC_FORMAT_COL_YUYV (8 << 16) -#define SRC_FORMAT_COL_UYVY (9 << 16) -#define SRC_FORMAT_BYTE_SWIZZLE (1 << 20) -#define SRC_FORMAT_WORD_SWIZZLE (1 << 21) -#define SRC_FORMAT_PACKING_MASK (3 << 22) +#define SRC_FORMAT_COL_MASK (0xf << 16) +#define SRC_FORMAT_COL_1_BPP (0 << 16) +#define SRC_FORMAT_COL_8_BPP (1 << 16) +#define SRC_FORMAT_COL_16_BPP (3 << 16) +#define SRC_FORMAT_COL_24_BPP (4 << 16) +#define SRC_FORMAT_COL_32_BPP (5 << 16) +#define SRC_FORMAT_COL_YUYV (8 << 16) +#define SRC_FORMAT_COL_UYVY (9 << 16) +#define SRC_FORMAT_BYTE_SWIZZLE (1 << 20) +#define SRC_FORMAT_WORD_SWIZZLE (1 << 21) +#define SRC_FORMAT_PACKING_MASK (3 << 22) #define SRC_FORMAT_PACKING_STRIDE (0 << 22) -#define SRC_FORMAT_PACKING_BYTE (1 << 22) -#define SRC_FORMAT_PACKING_WORD (2 << 22) -#define SRC_FORMAT_PACKING_DWORD (3 << 22) +#define SRC_FORMAT_PACKING_BYTE (1 << 22) +#define SRC_FORMAT_PACKING_WORD (2 << 22) +#define SRC_FORMAT_PACKING_DWORD (3 << 22) #define DST_FORMAT_STRIDE_MASK (0x1fff) -#define DST_FORMAT_COL_MASK (0xf << 16) -#define DST_FORMAT_COL_8_BPP (1 << 16) -#define DST_FORMAT_COL_16_BPP (3 << 16) -#define DST_FORMAT_COL_24_BPP (4 << 16) -#define DST_FORMAT_COL_32_BPP (5 << 16) +#define DST_FORMAT_COL_MASK (0xf << 16) +#define DST_FORMAT_COL_8_BPP (1 << 16) +#define DST_FORMAT_COL_16_BPP (3 << 16) +#define DST_FORMAT_COL_24_BPP (4 << 16) +#define DST_FORMAT_COL_32_BPP (5 << 16) -#define BRES_ERROR_MASK (0xffff) -#define BRES_ERROR_USE (1 << 31) +#define BRES_ERROR_MASK (0xffff) +#define BRES_ERROR_USE (1 << 31) -enum { - COLORKEY_8, - COLORKEY_16, - COLORKEY_32 -}; +enum { COLORKEY_8, COLORKEY_16, COLORKEY_32 }; static int colorkey(voodoo_t *voodoo, uint32_t src, int src_notdst, int color_format) { - uint32_t min = src_notdst ? voodoo->banshee_blt.srcColorkeyMin : voodoo->banshee_blt.dstColorkeyMin; - uint32_t max = src_notdst ? voodoo->banshee_blt.srcColorkeyMax : voodoo->banshee_blt.dstColorkeyMax; + uint32_t min = src_notdst ? voodoo->banshee_blt.srcColorkeyMin : voodoo->banshee_blt.dstColorkeyMin; + uint32_t max = src_notdst ? voodoo->banshee_blt.srcColorkeyMax : voodoo->banshee_blt.dstColorkeyMax; - if (!(voodoo->banshee_blt.commandExtra & (src_notdst ? CMDEXTRA_SRC_COLORKEY : CMDEXTRA_DST_COLORKEY))) - return 0; + if (!(voodoo->banshee_blt.commandExtra & (src_notdst ? CMDEXTRA_SRC_COLORKEY : CMDEXTRA_DST_COLORKEY))) + return 0; - switch (color_format) { - case COLORKEY_8:return ((src & 0xff) >= (min & 0xff)) && ((src & 0xff) <= (max & 0xff)); + switch (color_format) { + case COLORKEY_8: + return ((src & 0xff) >= (min & 0xff)) && ((src & 0xff) <= (max & 0xff)); - case COLORKEY_16: { - int r = (src >> 11) & 0x1f, r_min = (min >> 11) & 0x1f, r_max = (max >> 11) & 0x1f; - int g = (src >> 5) & 0x3f, g_min = (min >> 5) & 0x3f, g_max = (max >> 5) & 0x3f; - int b = src & 0x1f, b_min = min & 0x1f, b_max = max & 0x1f; + case COLORKEY_16: { + int r = (src >> 11) & 0x1f, r_min = (min >> 11) & 0x1f, r_max = (max >> 11) & 0x1f; + int g = (src >> 5) & 0x3f, g_min = (min >> 5) & 0x3f, g_max = (max >> 5) & 0x3f; + int b = src & 0x1f, b_min = min & 0x1f, b_max = max & 0x1f; - return (r >= r_min) && (r <= r_max) && (g >= g_min) && (g <= g_max) && - (b >= b_min) && (b <= b_max); - } + return (r >= r_min) && (r <= r_max) && (g >= g_min) && (g <= g_max) && (b >= b_min) && (b <= b_max); + } - case COLORKEY_32: { - int r = (src >> 16) & 0xff, r_min = (min >> 16) & 0xff, r_max = (max >> 16) & 0xff; - int g = (src >> 8) & 0xff, g_min = (min >> 8) & 0xff, g_max = (max >> 8) & 0xff; - int b = src & 0xff, b_min = min & 0xff, b_max = max & 0xff; + case COLORKEY_32: { + int r = (src >> 16) & 0xff, r_min = (min >> 16) & 0xff, r_max = (max >> 16) & 0xff; + int g = (src >> 8) & 0xff, g_min = (min >> 8) & 0xff, g_max = (max >> 8) & 0xff; + int b = src & 0xff, b_min = min & 0xff, b_max = max & 0xff; - return (r >= r_min) && (r <= r_max) && (g >= g_min) && (g <= g_max) && - (b >= b_min) && (b <= b_max); - } + return (r >= r_min) && (r <= r_max) && (g >= g_min) && (g <= g_max) && (b >= b_min) && (b <= b_max); + } - default:return 0; - } + default: + return 0; + } } -static uint32_t MIX(voodoo_t *voodoo, uint32_t dest, uint32_t src, uint32_t pattern, int colour_format_src, int colour_format_dest) { - int rop_nr = 0; - uint32_t result = 0; - uint32_t rop; +static uint32_t MIX(voodoo_t *voodoo, uint32_t dest, uint32_t src, uint32_t pattern, int colour_format_src, + int colour_format_dest) { + int rop_nr = 0; + uint32_t result = 0; + uint32_t rop; - if (colorkey(voodoo, src, 1, colour_format_src)) - rop_nr |= 2; - if (colorkey(voodoo, dest, 0, colour_format_dest)) - rop_nr |= 1; + if (colorkey(voodoo, src, 1, colour_format_src)) + rop_nr |= 2; + if (colorkey(voodoo, dest, 0, colour_format_dest)) + rop_nr |= 1; - rop = voodoo->banshee_blt.rops[rop_nr]; + rop = voodoo->banshee_blt.rops[rop_nr]; - if (rop & 0x01) - result |= (~pattern & ~src & ~dest); - if (rop & 0x02) - result |= (~pattern & ~src & dest); - if (rop & 0x04) - result |= (~pattern & src & ~dest); - if (rop & 0x08) - result |= (~pattern & src & dest); - if (rop & 0x10) - result |= (pattern & ~src & ~dest); - if (rop & 0x20) - result |= (pattern & ~src & dest); - if (rop & 0x40) - result |= (pattern & src & ~dest); - if (rop & 0x80) - result |= (pattern & src & dest); + if (rop & 0x01) + result |= (~pattern & ~src & ~dest); + if (rop & 0x02) + result |= (~pattern & ~src & dest); + if (rop & 0x04) + result |= (~pattern & src & ~dest); + if (rop & 0x08) + result |= (~pattern & src & dest); + if (rop & 0x10) + result |= (pattern & ~src & ~dest); + if (rop & 0x20) + result |= (pattern & ~src & dest); + if (rop & 0x40) + result |= (pattern & src & ~dest); + if (rop & 0x80) + result |= (pattern & src & dest); - return result; + return result; } static uint32_t get_addr(voodoo_t *voodoo, int x, int y, int src_notdst, uint32_t src_stride) { - uint32_t stride = src_notdst ? src_stride : voodoo->banshee_blt.dst_stride; - uint32_t base_addr = src_notdst ? voodoo->banshee_blt.srcBaseAddr : voodoo->banshee_blt.dstBaseAddr; + uint32_t stride = src_notdst ? src_stride : voodoo->banshee_blt.dst_stride; + uint32_t base_addr = src_notdst ? voodoo->banshee_blt.srcBaseAddr : voodoo->banshee_blt.dstBaseAddr; - if (src_notdst ? voodoo->banshee_blt.srcBaseAddr_tiled : voodoo->banshee_blt.dstBaseAddr_tiled) - return (base_addr + (x & 127) + ((x >> 7) * 128 * 32) + ((y & 31) * 128) + (y >> 5) * stride) & voodoo->fb_mask; - else - return (base_addr + x + y * stride) & voodoo->fb_mask; + if (src_notdst ? voodoo->banshee_blt.srcBaseAddr_tiled : voodoo->banshee_blt.dstBaseAddr_tiled) + return (base_addr + (x & 127) + ((x >> 7) * 128 * 32) + ((y & 31) * 128) + (y >> 5) * stride) & voodoo->fb_mask; + else + return (base_addr + x + y * stride) & voodoo->fb_mask; } -static void PLOT(voodoo_t *voodoo, int x, int y, int pat_x, int pat_y, uint8_t pattern_mask, uint8_t rop, uint32_t src, int src_colorkey) { - switch (voodoo->banshee_blt.dstFormat & DST_FORMAT_COL_MASK) { - case DST_FORMAT_COL_8_BPP: { - uint32_t addr = get_addr(voodoo, x, y, 0, 0);//(voodoo->banshee_blt.dstBaseAddr + x + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; - uint32_t dest = voodoo->vram[addr]; - uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? - ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : - voodoo->banshee_blt.colorPattern8[(pat_x & 7) + (pat_y & 7) * 8]; +static void PLOT(voodoo_t *voodoo, int x, int y, int pat_x, int pat_y, uint8_t pattern_mask, uint8_t rop, uint32_t src, + int src_colorkey) { + switch (voodoo->banshee_blt.dstFormat & DST_FORMAT_COL_MASK) { + case DST_FORMAT_COL_8_BPP: { + uint32_t addr = + get_addr(voodoo, x, y, 0, + 0); //(voodoo->banshee_blt.dstBaseAddr + x + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t dest = voodoo->vram[addr]; + uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) + ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore + : voodoo->banshee_blt.colorBack) + : voodoo->banshee_blt.colorPattern8[(pat_x & 7) + (pat_y & 7) * 8]; - voodoo->vram[addr] = MIX(voodoo, dest, src, pattern, src_colorkey, COLORKEY_8); - voodoo->changedvram[addr >> 12] = changeframecount; - break; - } - case DST_FORMAT_COL_16_BPP: { - uint32_t addr = get_addr(voodoo, x * 2, y, 0, 0);//(voodoo->banshee_blt.dstBaseAddr + x*2 + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; - uint32_t dest = *(uint16_t *)&voodoo->vram[addr]; - uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? - ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : - voodoo->banshee_blt.colorPattern16[(pat_x & 7) + (pat_y & 7) * 8]; + voodoo->vram[addr] = MIX(voodoo, dest, src, pattern, src_colorkey, COLORKEY_8); + voodoo->changedvram[addr >> 12] = changeframecount; + break; + } + case DST_FORMAT_COL_16_BPP: { + uint32_t addr = get_addr( + voodoo, x * 2, y, 0, + 0); //(voodoo->banshee_blt.dstBaseAddr + x*2 + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t dest = *(uint16_t *)&voodoo->vram[addr]; + uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) + ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore + : voodoo->banshee_blt.colorBack) + : voodoo->banshee_blt.colorPattern16[(pat_x & 7) + (pat_y & 7) * 8]; - *(uint16_t *)&voodoo->vram[addr] = MIX(voodoo, dest, src, pattern, src_colorkey, COLORKEY_16); - voodoo->changedvram[addr >> 12] = changeframecount; - break; - } - case DST_FORMAT_COL_24_BPP: { - uint32_t addr = get_addr(voodoo, x * 3, y, 0, 0);//(voodoo->banshee_blt.dstBaseAddr + x*3 + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; - uint32_t dest = *(uint32_t *)&voodoo->vram[addr]; - uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? - ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : - voodoo->banshee_blt.colorPattern24[(pat_x & 7) + (pat_y & 7) * 8]; + *(uint16_t *)&voodoo->vram[addr] = MIX(voodoo, dest, src, pattern, src_colorkey, COLORKEY_16); + voodoo->changedvram[addr >> 12] = changeframecount; + break; + } + case DST_FORMAT_COL_24_BPP: { + uint32_t addr = get_addr( + voodoo, x * 3, y, 0, + 0); //(voodoo->banshee_blt.dstBaseAddr + x*3 + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t dest = *(uint32_t *)&voodoo->vram[addr]; + uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) + ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore + : voodoo->banshee_blt.colorBack) + : voodoo->banshee_blt.colorPattern24[(pat_x & 7) + (pat_y & 7) * 8]; - *(uint32_t *)&voodoo->vram[addr] = (MIX(voodoo, dest, src, pattern, src_colorkey, COLORKEY_32) & 0xffffff) | (dest & 0xff000000); - voodoo->changedvram[addr >> 12] = changeframecount; - break; - } - case DST_FORMAT_COL_32_BPP: { - uint32_t addr = get_addr(voodoo, x * 4, y, 0, 0);//(voodoo->banshee_blt.dstBaseAddr + x*4 + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; - uint32_t dest = *(uint32_t *)&voodoo->vram[addr]; - uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? - ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : - voodoo->banshee_blt.colorPattern[(pat_x & 7) + (pat_y & 7) * 8]; + *(uint32_t *)&voodoo->vram[addr] = + (MIX(voodoo, dest, src, pattern, src_colorkey, COLORKEY_32) & 0xffffff) | (dest & 0xff000000); + voodoo->changedvram[addr >> 12] = changeframecount; + break; + } + case DST_FORMAT_COL_32_BPP: { + uint32_t addr = get_addr( + voodoo, x * 4, y, 0, + 0); //(voodoo->banshee_blt.dstBaseAddr + x*4 + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t dest = *(uint32_t *)&voodoo->vram[addr]; + uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) + ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore + : voodoo->banshee_blt.colorBack) + : voodoo->banshee_blt.colorPattern[(pat_x & 7) + (pat_y & 7) * 8]; - *(uint32_t *)&voodoo->vram[addr] = MIX(voodoo, dest, src, pattern, src_colorkey, COLORKEY_32); - voodoo->changedvram[addr >> 12] = changeframecount; - break; - } - } + *(uint32_t *)&voodoo->vram[addr] = MIX(voodoo, dest, src, pattern, src_colorkey, COLORKEY_32); + voodoo->changedvram[addr >> 12] = changeframecount; + break; + } + } } static void PLOT_LINE(voodoo_t *voodoo, int x, int y, uint8_t rop, uint32_t pattern, int src_colorkey) { - switch (voodoo->banshee_blt.dstFormat & DST_FORMAT_COL_MASK) { - case DST_FORMAT_COL_8_BPP: { - uint32_t addr = get_addr(voodoo, x, y, 0, 0);//(voodoo->banshee_blt.dstBaseAddr + x + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; - uint32_t dest = voodoo->vram[addr]; + switch (voodoo->banshee_blt.dstFormat & DST_FORMAT_COL_MASK) { + case DST_FORMAT_COL_8_BPP: { + uint32_t addr = + get_addr(voodoo, x, y, 0, + 0); //(voodoo->banshee_blt.dstBaseAddr + x + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t dest = voodoo->vram[addr]; - voodoo->vram[addr] = MIX(voodoo, dest, voodoo->banshee_blt.colorFore, pattern, src_colorkey, COLORKEY_8); - voodoo->changedvram[addr >> 12] = changeframecount; - break; - } - case DST_FORMAT_COL_16_BPP: { - uint32_t addr = get_addr(voodoo, x * 2, y, 0, 0);//(voodoo->banshee_blt.dstBaseAddr + x*2 + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; - uint32_t dest = *(uint16_t *)&voodoo->vram[addr]; + voodoo->vram[addr] = MIX(voodoo, dest, voodoo->banshee_blt.colorFore, pattern, src_colorkey, COLORKEY_8); + voodoo->changedvram[addr >> 12] = changeframecount; + break; + } + case DST_FORMAT_COL_16_BPP: { + uint32_t addr = get_addr( + voodoo, x * 2, y, 0, + 0); //(voodoo->banshee_blt.dstBaseAddr + x*2 + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t dest = *(uint16_t *)&voodoo->vram[addr]; - *(uint16_t *)&voodoo->vram[addr] = MIX(voodoo, dest, voodoo->banshee_blt.colorFore, pattern, src_colorkey, COLORKEY_16); - voodoo->changedvram[addr >> 12] = changeframecount; - break; - } - case DST_FORMAT_COL_24_BPP: { - uint32_t addr = get_addr(voodoo, x * 3, y, 0, 0);//(voodoo->banshee_blt.dstBaseAddr + x*3 + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; - uint32_t dest = *(uint32_t *)&voodoo->vram[addr]; + *(uint16_t *)&voodoo->vram[addr] = + MIX(voodoo, dest, voodoo->banshee_blt.colorFore, pattern, src_colorkey, COLORKEY_16); + voodoo->changedvram[addr >> 12] = changeframecount; + break; + } + case DST_FORMAT_COL_24_BPP: { + uint32_t addr = get_addr( + voodoo, x * 3, y, 0, + 0); //(voodoo->banshee_blt.dstBaseAddr + x*3 + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t dest = *(uint32_t *)&voodoo->vram[addr]; - *(uint32_t *)&voodoo->vram[addr] = (MIX(voodoo, dest, voodoo->banshee_blt.colorFore, pattern, src_colorkey, COLORKEY_32) & 0xffffff) | (dest & 0xff000000); - voodoo->changedvram[addr >> 12] = changeframecount; - break; - } - case DST_FORMAT_COL_32_BPP: { - uint32_t addr = get_addr(voodoo, x * 4, y, 0, 0);//(voodoo->banshee_blt.dstBaseAddr + x*4 + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; - uint32_t dest = *(uint32_t *)&voodoo->vram[addr]; + *(uint32_t *)&voodoo->vram[addr] = + (MIX(voodoo, dest, voodoo->banshee_blt.colorFore, pattern, src_colorkey, COLORKEY_32) & 0xffffff) | + (dest & 0xff000000); + voodoo->changedvram[addr >> 12] = changeframecount; + break; + } + case DST_FORMAT_COL_32_BPP: { + uint32_t addr = get_addr( + voodoo, x * 4, y, 0, + 0); //(voodoo->banshee_blt.dstBaseAddr + x*4 + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t dest = *(uint32_t *)&voodoo->vram[addr]; - *(uint32_t *)&voodoo->vram[addr] = MIX(voodoo, dest, voodoo->banshee_blt.colorFore, pattern, src_colorkey, COLORKEY_32); - voodoo->changedvram[addr >> 12] = changeframecount; - break; - } - } + *(uint32_t *)&voodoo->vram[addr] = + MIX(voodoo, dest, voodoo->banshee_blt.colorFore, pattern, src_colorkey, COLORKEY_32); + voodoo->changedvram[addr >> 12] = changeframecount; + break; + } + } } static void update_src_stride(voodoo_t *voodoo) { - int bpp; + int bpp; - switch (voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) { - case SRC_FORMAT_COL_1_BPP:bpp = 1; - break; - case SRC_FORMAT_COL_8_BPP:bpp = 8; - break; - case SRC_FORMAT_COL_16_BPP:bpp = 16; - break; - case SRC_FORMAT_COL_24_BPP:bpp = 24; - break; - case SRC_FORMAT_COL_32_BPP:bpp = 32; - break; + switch (voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) { + case SRC_FORMAT_COL_1_BPP: + bpp = 1; + break; + case SRC_FORMAT_COL_8_BPP: + bpp = 8; + break; + case SRC_FORMAT_COL_16_BPP: + bpp = 16; + break; + case SRC_FORMAT_COL_24_BPP: + bpp = 24; + break; + case SRC_FORMAT_COL_32_BPP: + bpp = 32; + break; - default:bpp = 16; - break; - } + default: + bpp = 16; + break; + } - switch (voodoo->banshee_blt.srcFormat & SRC_FORMAT_PACKING_MASK) { - case SRC_FORMAT_PACKING_STRIDE:voodoo->banshee_blt.src_stride_src = voodoo->banshee_blt.src_stride; //voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK; - voodoo->banshee_blt.src_stride_dest = voodoo->banshee_blt.src_stride; //voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK; - voodoo->banshee_blt.host_data_size_src = (voodoo->banshee_blt.srcSizeX * bpp + 7) >> 3; - voodoo->banshee_blt.host_data_size_dest = (voodoo->banshee_blt.dstSizeX * bpp + 7) >> 3; -// pclog("Stride packing %08x %08x bpp=%i dstSizeX=%i\n", voodoo->banshee_blt.src_stride_dest, voodoo->banshee_blt.host_data_size_dest, bpp, voodoo->banshee_blt.dstSizeX); - break; + switch (voodoo->banshee_blt.srcFormat & SRC_FORMAT_PACKING_MASK) { + case SRC_FORMAT_PACKING_STRIDE: + voodoo->banshee_blt.src_stride_src = + voodoo->banshee_blt.src_stride; // voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK; + voodoo->banshee_blt.src_stride_dest = + voodoo->banshee_blt.src_stride; // voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK; + voodoo->banshee_blt.host_data_size_src = (voodoo->banshee_blt.srcSizeX * bpp + 7) >> 3; + voodoo->banshee_blt.host_data_size_dest = (voodoo->banshee_blt.dstSizeX * bpp + 7) >> 3; + // pclog("Stride packing %08x %08x bpp=%i dstSizeX=%i\n", voodoo->banshee_blt.src_stride_dest, + // voodoo->banshee_blt.host_data_size_dest, bpp, voodoo->banshee_blt.dstSizeX); + break; - case SRC_FORMAT_PACKING_BYTE:voodoo->banshee_blt.src_stride_src = (voodoo->banshee_blt.srcSizeX * bpp + 7) >> 3; - voodoo->banshee_blt.src_stride_dest = (voodoo->banshee_blt.dstSizeX * bpp + 7) >> 3; - voodoo->banshee_blt.host_data_size_src = voodoo->banshee_blt.src_stride_src; - voodoo->banshee_blt.host_data_size_dest = voodoo->banshee_blt.src_stride_dest; -// pclog("Byte packing %08x %08x\n", voodoo->banshee_blt.src_stride_dest, voodoo->banshee_blt.host_data_size_dest); - break; + case SRC_FORMAT_PACKING_BYTE: + voodoo->banshee_blt.src_stride_src = (voodoo->banshee_blt.srcSizeX * bpp + 7) >> 3; + voodoo->banshee_blt.src_stride_dest = (voodoo->banshee_blt.dstSizeX * bpp + 7) >> 3; + voodoo->banshee_blt.host_data_size_src = voodoo->banshee_blt.src_stride_src; + voodoo->banshee_blt.host_data_size_dest = voodoo->banshee_blt.src_stride_dest; + // pclog("Byte packing %08x %08x\n", voodoo->banshee_blt.src_stride_dest, + // voodoo->banshee_blt.host_data_size_dest); + break; - case SRC_FORMAT_PACKING_WORD:voodoo->banshee_blt.src_stride_src = ((voodoo->banshee_blt.srcSizeX * bpp + 15) >> 4) * 2; - voodoo->banshee_blt.src_stride_dest = ((voodoo->banshee_blt.dstSizeX * bpp + 15) >> 4) * 2; - voodoo->banshee_blt.host_data_size_src = voodoo->banshee_blt.src_stride_src; - voodoo->banshee_blt.host_data_size_dest = voodoo->banshee_blt.src_stride_dest; -// pclog("Word packing %08x %08x\n", voodoo->banshee_blt.src_stride_dest, voodoo->banshee_blt.host_data_size_dest); - break; + case SRC_FORMAT_PACKING_WORD: + voodoo->banshee_blt.src_stride_src = ((voodoo->banshee_blt.srcSizeX * bpp + 15) >> 4) * 2; + voodoo->banshee_blt.src_stride_dest = ((voodoo->banshee_blt.dstSizeX * bpp + 15) >> 4) * 2; + voodoo->banshee_blt.host_data_size_src = voodoo->banshee_blt.src_stride_src; + voodoo->banshee_blt.host_data_size_dest = voodoo->banshee_blt.src_stride_dest; + // pclog("Word packing %08x %08x\n", voodoo->banshee_blt.src_stride_dest, + // voodoo->banshee_blt.host_data_size_dest); + break; - case SRC_FORMAT_PACKING_DWORD:voodoo->banshee_blt.src_stride_src = ((voodoo->banshee_blt.srcSizeX * bpp + 31) >> 5) * 4; - voodoo->banshee_blt.src_stride_dest = ((voodoo->banshee_blt.dstSizeX * bpp + 31) >> 5) * 4; - voodoo->banshee_blt.host_data_size_src = voodoo->banshee_blt.src_stride_src; - voodoo->banshee_blt.host_data_size_dest = voodoo->banshee_blt.src_stride_dest; -// pclog("Dword packing %08x %08x\n", voodoo->banshee_blt.src_stride_dest, voodoo->banshee_blt.host_data_size_dest); - break; - } + case SRC_FORMAT_PACKING_DWORD: + voodoo->banshee_blt.src_stride_src = ((voodoo->banshee_blt.srcSizeX * bpp + 31) >> 5) * 4; + voodoo->banshee_blt.src_stride_dest = ((voodoo->banshee_blt.dstSizeX * bpp + 31) >> 5) * 4; + voodoo->banshee_blt.host_data_size_src = voodoo->banshee_blt.src_stride_src; + voodoo->banshee_blt.host_data_size_dest = voodoo->banshee_blt.src_stride_dest; + // pclog("Dword packing %08x %08x\n", voodoo->banshee_blt.src_stride_dest, + // voodoo->banshee_blt.host_data_size_dest); + break; + } } static void end_command(voodoo_t *voodoo) { - /*Update dest coordinates if required*/ - if (voodoo->banshee_blt.command & COMMAND_INC_X_START) { - voodoo->banshee_blt.dstXY &= ~0x0000ffff; - voodoo->banshee_blt.dstXY |= (voodoo->banshee_blt.dstX & 0xffff); - } + /*Update dest coordinates if required*/ + if (voodoo->banshee_blt.command & COMMAND_INC_X_START) { + voodoo->banshee_blt.dstXY &= ~0x0000ffff; + voodoo->banshee_blt.dstXY |= (voodoo->banshee_blt.dstX & 0xffff); + } - if (voodoo->banshee_blt.command & COMMAND_INC_Y_START) { - voodoo->banshee_blt.dstXY &= ~0xffff0000; - voodoo->banshee_blt.dstXY |= (voodoo->banshee_blt.dstY << 16); - } + if (voodoo->banshee_blt.command & COMMAND_INC_Y_START) { + voodoo->banshee_blt.dstXY &= ~0xffff0000; + voodoo->banshee_blt.dstXY |= (voodoo->banshee_blt.dstY << 16); + } } static void banshee_do_rectfill(voodoo_t *voodoo) { - clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0]; - int dst_y = voodoo->banshee_blt.dstY; - uint8_t *pattern_mono = (uint8_t *)voodoo->banshee_blt.colorPattern; - int pat_y = (voodoo->banshee_blt.commandExtra & CMDEXTRA_FORCE_PAT_ROW0) ? 0 : (voodoo->banshee_blt.patoff_y + voodoo->banshee_blt.dstY); - int use_pattern_trans = (voodoo->banshee_blt.command & (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO)) == - (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO); - uint8_t rop = voodoo->banshee_blt.command >> 24; + clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0]; + int dst_y = voodoo->banshee_blt.dstY; + uint8_t *pattern_mono = (uint8_t *)voodoo->banshee_blt.colorPattern; + int pat_y = (voodoo->banshee_blt.commandExtra & CMDEXTRA_FORCE_PAT_ROW0) + ? 0 + : (voodoo->banshee_blt.patoff_y + voodoo->banshee_blt.dstY); + int use_pattern_trans = (voodoo->banshee_blt.command & (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO)) == + (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO); + uint8_t rop = voodoo->banshee_blt.command >> 24; -// pclog("banshee_do_rectfill: size=%i,%i dst=%i,%i\n", voodoo->banshee_blt.dstSizeX, voodoo->banshee_blt.dstSizeY, voodoo->banshee_blt.dstX, voodoo->banshee_blt.dstY); -// pclog("clipping: %i,%i -> %i,%i\n", clip->x_min, clip->y_min, clip->x_max, clip->y_max); -// pclog("colorFore=%08x\n", voodoo->banshee_blt.colorFore); - for (voodoo->banshee_blt.cur_y = 0; voodoo->banshee_blt.cur_y < voodoo->banshee_blt.dstSizeY; voodoo->banshee_blt.cur_y++) { - int dst_x = voodoo->banshee_blt.dstX; + // pclog("banshee_do_rectfill: size=%i,%i dst=%i,%i\n", voodoo->banshee_blt.dstSizeX, + // voodoo->banshee_blt.dstSizeY, voodoo->banshee_blt.dstX, voodoo->banshee_blt.dstY); pclog("clipping: %i,%i -> + // %i,%i\n", clip->x_min, clip->y_min, clip->x_max, clip->y_max); pclog("colorFore=%08x\n", + // voodoo->banshee_blt.colorFore); + for (voodoo->banshee_blt.cur_y = 0; voodoo->banshee_blt.cur_y < voodoo->banshee_blt.dstSizeY; + voodoo->banshee_blt.cur_y++) { + int dst_x = voodoo->banshee_blt.dstX; - if (dst_y >= clip->y_min && dst_y < clip->y_max) { - int pat_x = voodoo->banshee_blt.patoff_x + voodoo->banshee_blt.dstX; - uint8_t pattern_mask = pattern_mono[pat_y & 7]; + if (dst_y >= clip->y_min && dst_y < clip->y_max) { + int pat_x = voodoo->banshee_blt.patoff_x + voodoo->banshee_blt.dstX; + uint8_t pattern_mask = pattern_mono[pat_y & 7]; - for (voodoo->banshee_blt.cur_x = 0; voodoo->banshee_blt.cur_x < voodoo->banshee_blt.dstSizeX; voodoo->banshee_blt.cur_x++) { - int pattern_trans = use_pattern_trans ? (pattern_mask & (1 << (7 - (pat_x & 7)))) : 1; + for (voodoo->banshee_blt.cur_x = 0; voodoo->banshee_blt.cur_x < voodoo->banshee_blt.dstSizeX; + voodoo->banshee_blt.cur_x++) { + int pattern_trans = use_pattern_trans ? (pattern_mask & (1 << (7 - (pat_x & 7)))) : 1; - if (dst_x >= clip->x_min && dst_x < clip->x_max && pattern_trans) - PLOT(voodoo, dst_x, dst_y, pat_x, pat_y, pattern_mask, rop, voodoo->banshee_blt.colorFore, COLORKEY_32); + if (dst_x >= clip->x_min && dst_x < clip->x_max && pattern_trans) + PLOT(voodoo, dst_x, dst_y, pat_x, pat_y, pattern_mask, rop, voodoo->banshee_blt.colorFore, + COLORKEY_32); - dst_x += (voodoo->banshee_blt.command & COMMAND_DX) ? -1 : 1; - pat_x += (voodoo->banshee_blt.command & COMMAND_DX) ? -1 : 1; - } - } - dst_y += (voodoo->banshee_blt.command & COMMAND_DY) ? -1 : 1; - if (!(voodoo->banshee_blt.commandExtra & CMDEXTRA_FORCE_PAT_ROW0)) - pat_y += (voodoo->banshee_blt.command & COMMAND_DY) ? -1 : 1; - } + dst_x += (voodoo->banshee_blt.command & COMMAND_DX) ? -1 : 1; + pat_x += (voodoo->banshee_blt.command & COMMAND_DX) ? -1 : 1; + } + } + dst_y += (voodoo->banshee_blt.command & COMMAND_DY) ? -1 : 1; + if (!(voodoo->banshee_blt.commandExtra & CMDEXTRA_FORCE_PAT_ROW0)) + pat_y += (voodoo->banshee_blt.command & COMMAND_DY) ? -1 : 1; + } - end_command(voodoo); + end_command(voodoo); } static void do_screen_to_screen_line(voodoo_t *voodoo, uint8_t *src_p, int use_x_dir, int src_x, int src_tiled) { - clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0]; - int dst_y = voodoo->banshee_blt.dstY; - int pat_y = (voodoo->banshee_blt.commandExtra & CMDEXTRA_FORCE_PAT_ROW0) ? 0 : (voodoo->banshee_blt.patoff_y + voodoo->banshee_blt.dstY); - uint8_t *pattern_mono = (uint8_t *)voodoo->banshee_blt.colorPattern; - int use_pattern_trans = (voodoo->banshee_blt.command & (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO)) == - (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO); - uint8_t rop = voodoo->banshee_blt.command >> 24; - int src_colorkey; + clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0]; + int dst_y = voodoo->banshee_blt.dstY; + int pat_y = (voodoo->banshee_blt.commandExtra & CMDEXTRA_FORCE_PAT_ROW0) + ? 0 + : (voodoo->banshee_blt.patoff_y + voodoo->banshee_blt.dstY); + uint8_t *pattern_mono = (uint8_t *)voodoo->banshee_blt.colorPattern; + int use_pattern_trans = (voodoo->banshee_blt.command & (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO)) == + (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO); + uint8_t rop = voodoo->banshee_blt.command >> 24; + int src_colorkey; - switch (voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) { - case SRC_FORMAT_COL_8_BPP:src_colorkey = COLORKEY_8; - break; - case SRC_FORMAT_COL_16_BPP:src_colorkey = COLORKEY_16; - break; - default:src_colorkey = COLORKEY_32; - break; - } -// pclog("do_screen_to_screen_line: srcFormat=%08x dst=%08x\n", voodoo->banshee_blt.srcFormat, voodoo->banshee_blt.dstFormat); - if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) == - (voodoo->banshee_blt.dstFormat & DST_FORMAT_COL_MASK)) { - /*No conversion required*/ - if (dst_y >= clip->y_min && dst_y < clip->y_max) { - int dst_x = voodoo->banshee_blt.dstX; - int pat_x = voodoo->banshee_blt.patoff_x + voodoo->banshee_blt.dstX; - uint8_t pattern_mask = pattern_mono[pat_y & 7]; + switch (voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) { + case SRC_FORMAT_COL_8_BPP: + src_colorkey = COLORKEY_8; + break; + case SRC_FORMAT_COL_16_BPP: + src_colorkey = COLORKEY_16; + break; + default: + src_colorkey = COLORKEY_32; + break; + } + // pclog("do_screen_to_screen_line: srcFormat=%08x dst=%08x\n", voodoo->banshee_blt.srcFormat, + // voodoo->banshee_blt.dstFormat); + if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) == (voodoo->banshee_blt.dstFormat & DST_FORMAT_COL_MASK)) { + /*No conversion required*/ + if (dst_y >= clip->y_min && dst_y < clip->y_max) { + int dst_x = voodoo->banshee_blt.dstX; + int pat_x = voodoo->banshee_blt.patoff_x + voodoo->banshee_blt.dstX; + uint8_t pattern_mask = pattern_mono[pat_y & 7]; - for (voodoo->banshee_blt.cur_x = 0; voodoo->banshee_blt.cur_x < voodoo->banshee_blt.dstSizeX; voodoo->banshee_blt.cur_x++) { - int pattern_trans = use_pattern_trans ? (pattern_mask & (1 << (7 - (pat_x & 7)))) : 1; - int src_x_real = (src_x * voodoo->banshee_blt.src_bpp) >> 3; + for (voodoo->banshee_blt.cur_x = 0; voodoo->banshee_blt.cur_x < voodoo->banshee_blt.dstSizeX; + voodoo->banshee_blt.cur_x++) { + int pattern_trans = use_pattern_trans ? (pattern_mask & (1 << (7 - (pat_x & 7)))) : 1; + int src_x_real = (src_x * voodoo->banshee_blt.src_bpp) >> 3; - if (src_tiled) - src_x_real = (src_x_real & 127) + ((src_x_real >> 7) * 128 * 32); + if (src_tiled) + src_x_real = (src_x_real & 127) + ((src_x_real >> 7) * 128 * 32); - if (dst_x >= clip->x_min && dst_x < clip->x_max && pattern_trans) { - switch (voodoo->banshee_blt.dstFormat & DST_FORMAT_COL_MASK) { - case DST_FORMAT_COL_8_BPP: { - uint32_t dst_addr = - get_addr(voodoo, dst_x, dst_y, 0, 0);//(voodoo->banshee_blt.dstBaseAddr + dst_x + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; - uint32_t src = src_p[src_x_real]; - uint32_t dest = voodoo->vram[dst_addr]; - uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? - ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : - voodoo->banshee_blt.colorPattern8[(pat_x & 7) + (pat_y & 7) * 8]; + if (dst_x >= clip->x_min && dst_x < clip->x_max && pattern_trans) { + switch (voodoo->banshee_blt.dstFormat & DST_FORMAT_COL_MASK) { + case DST_FORMAT_COL_8_BPP: { + uint32_t dst_addr = + get_addr(voodoo, dst_x, dst_y, 0, + 0); //(voodoo->banshee_blt.dstBaseAddr + dst_x + + //dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t src = src_p[src_x_real]; + uint32_t dest = voodoo->vram[dst_addr]; + uint32_t pattern = + (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) + ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) + ? voodoo->banshee_blt.colorFore + : voodoo->banshee_blt.colorBack) + : voodoo->banshee_blt + .colorPattern8[(pat_x & 7) + (pat_y & 7) * 8]; - voodoo->vram[dst_addr] = MIX(voodoo, dest, src, pattern, COLORKEY_8, COLORKEY_8); - voodoo->changedvram[dst_addr >> 12] = changeframecount; - break; - } - case DST_FORMAT_COL_16_BPP: { - uint32_t dst_addr = get_addr(voodoo, - dst_x * 2, - dst_y, - 0, - 0);//dst_addr = (voodoo->banshee_blt.dstBaseAddr + dst_x*2 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; - uint32_t src = *(uint16_t *)&src_p[src_x_real]; - uint32_t dest = *(uint16_t *)&voodoo->vram[dst_addr]; - uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? - ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : - voodoo->banshee_blt.colorPattern16[(pat_x & 7) + (pat_y & 7) * 8]; + voodoo->vram[dst_addr] = MIX(voodoo, dest, src, pattern, COLORKEY_8, COLORKEY_8); + voodoo->changedvram[dst_addr >> 12] = changeframecount; + break; + } + case DST_FORMAT_COL_16_BPP: { + uint32_t dst_addr = + get_addr(voodoo, dst_x * 2, dst_y, 0, + 0); // dst_addr = (voodoo->banshee_blt.dstBaseAddr + dst_x*2 + + // dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t src = *(uint16_t *)&src_p[src_x_real]; + uint32_t dest = *(uint16_t *)&voodoo->vram[dst_addr]; + uint32_t pattern = + (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) + ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) + ? voodoo->banshee_blt.colorFore + : voodoo->banshee_blt.colorBack) + : voodoo->banshee_blt + .colorPattern16[(pat_x & 7) + (pat_y & 7) * 8]; - *(uint16_t *)&voodoo->vram[dst_addr] = MIX(voodoo, dest, src, pattern, COLORKEY_16, COLORKEY_16); - voodoo->changedvram[dst_addr >> 12] = changeframecount; - break; - } - case DST_FORMAT_COL_24_BPP: { - uint32_t dst_addr = get_addr(voodoo, - dst_x * 3, - dst_y, - 0, - 0);//dst_addr = (voodoo->banshee_blt.dstBaseAddr + dst_x*3 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; - uint32_t src = *(uint32_t *)&src_p[src_x_real]; - uint32_t dest = *(uint32_t *)&voodoo->vram[dst_addr]; - uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? - ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : - voodoo->banshee_blt.colorPattern24[(pat_x & 7) + (pat_y & 7) * 8]; + *(uint16_t *)&voodoo->vram[dst_addr] = + MIX(voodoo, dest, src, pattern, COLORKEY_16, COLORKEY_16); + voodoo->changedvram[dst_addr >> 12] = changeframecount; + break; + } + case DST_FORMAT_COL_24_BPP: { + uint32_t dst_addr = + get_addr(voodoo, dst_x * 3, dst_y, 0, + 0); // dst_addr = (voodoo->banshee_blt.dstBaseAddr + dst_x*3 + + // dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t src = *(uint32_t *)&src_p[src_x_real]; + uint32_t dest = *(uint32_t *)&voodoo->vram[dst_addr]; + uint32_t pattern = + (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) + ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) + ? voodoo->banshee_blt.colorFore + : voodoo->banshee_blt.colorBack) + : voodoo->banshee_blt + .colorPattern24[(pat_x & 7) + (pat_y & 7) * 8]; - *(uint32_t *)&voodoo->vram[dst_addr] = (MIX(voodoo, dest, src, pattern, COLORKEY_32, COLORKEY_32) & 0xffffff) | (dest & 0xff000000); - voodoo->changedvram[dst_addr >> 12] = changeframecount; - break; - } - case DST_FORMAT_COL_32_BPP: { - uint32_t dst_addr = get_addr(voodoo, - dst_x * 4, - dst_y, - 0, - 0);//dst_addr = (voodoo->banshee_blt.dstBaseAddr + dst_x*4 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; - uint32_t src = *(uint32_t *)&src_p[src_x_real]; - uint32_t dest = *(uint32_t *)&voodoo->vram[dst_addr]; - uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? - ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : - voodoo->banshee_blt.colorPattern[(pat_x & 7) + (pat_y & 7) * 8]; + *(uint32_t *)&voodoo->vram[dst_addr] = + (MIX(voodoo, dest, src, pattern, COLORKEY_32, COLORKEY_32) & 0xffffff) | + (dest & 0xff000000); + voodoo->changedvram[dst_addr >> 12] = changeframecount; + break; + } + case DST_FORMAT_COL_32_BPP: { + uint32_t dst_addr = + get_addr(voodoo, dst_x * 4, dst_y, 0, + 0); // dst_addr = (voodoo->banshee_blt.dstBaseAddr + dst_x*4 + + // dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t src = *(uint32_t *)&src_p[src_x_real]; + uint32_t dest = *(uint32_t *)&voodoo->vram[dst_addr]; + uint32_t pattern = + (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) + ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) + ? voodoo->banshee_blt.colorFore + : voodoo->banshee_blt.colorBack) + : voodoo->banshee_blt.colorPattern[(pat_x & 7) + (pat_y & 7) * 8]; - *(uint32_t *)&voodoo->vram[dst_addr] = MIX(voodoo, dest, src, pattern, COLORKEY_32, COLORKEY_32); - voodoo->changedvram[dst_addr >> 12] = changeframecount; - break; - } - } - } - if (use_x_dir) { - src_x += (voodoo->banshee_blt.command & COMMAND_DX) ? -1 : 1; - dst_x += (voodoo->banshee_blt.command & COMMAND_DX) ? -1 : 1; - pat_x += (voodoo->banshee_blt.command & COMMAND_DX) ? -1 : 1; - } else { - src_x++; - dst_x++; - pat_x++; - } - } - } - voodoo->banshee_blt.srcY += (voodoo->banshee_blt.command & COMMAND_DY) ? -1 : 1; - voodoo->banshee_blt.dstY += (voodoo->banshee_blt.command & COMMAND_DY) ? -1 : 1; - } else { - /*Conversion required*/ - if (dst_y >= clip->y_min && dst_y < clip->y_max) { -// int src_x = voodoo->banshee_blt.srcX; - int dst_x = voodoo->banshee_blt.dstX; - int pat_x = voodoo->banshee_blt.patoff_x + voodoo->banshee_blt.dstX; - uint8_t pattern_mask = pattern_mono[pat_y & 7]; + *(uint32_t *)&voodoo->vram[dst_addr] = + MIX(voodoo, dest, src, pattern, COLORKEY_32, COLORKEY_32); + voodoo->changedvram[dst_addr >> 12] = changeframecount; + break; + } + } + } + if (use_x_dir) { + src_x += (voodoo->banshee_blt.command & COMMAND_DX) ? -1 : 1; + dst_x += (voodoo->banshee_blt.command & COMMAND_DX) ? -1 : 1; + pat_x += (voodoo->banshee_blt.command & COMMAND_DX) ? -1 : 1; + } else { + src_x++; + dst_x++; + pat_x++; + } + } + } + voodoo->banshee_blt.srcY += (voodoo->banshee_blt.command & COMMAND_DY) ? -1 : 1; + voodoo->banshee_blt.dstY += (voodoo->banshee_blt.command & COMMAND_DY) ? -1 : 1; + } else { + /*Conversion required*/ + if (dst_y >= clip->y_min && dst_y < clip->y_max) { + // int src_x = voodoo->banshee_blt.srcX; + int dst_x = voodoo->banshee_blt.dstX; + int pat_x = voodoo->banshee_blt.patoff_x + voodoo->banshee_blt.dstX; + uint8_t pattern_mask = pattern_mono[pat_y & 7]; - for (voodoo->banshee_blt.cur_x = 0; voodoo->banshee_blt.cur_x < voodoo->banshee_blt.dstSizeX; voodoo->banshee_blt.cur_x++) { - int pattern_trans = use_pattern_trans ? (pattern_mask & (1 << (7 - (pat_x & 7)))) : 1; - int src_x_real = (src_x * voodoo->banshee_blt.src_bpp) >> 3; + for (voodoo->banshee_blt.cur_x = 0; voodoo->banshee_blt.cur_x < voodoo->banshee_blt.dstSizeX; + voodoo->banshee_blt.cur_x++) { + int pattern_trans = use_pattern_trans ? (pattern_mask & (1 << (7 - (pat_x & 7)))) : 1; + int src_x_real = (src_x * voodoo->banshee_blt.src_bpp) >> 3; - if (src_tiled) - src_x_real = (src_x_real & 127) + ((src_x_real >> 7) * 128 * 32); + if (src_tiled) + src_x_real = (src_x_real & 127) + ((src_x_real >> 7) * 128 * 32); - if (dst_x >= clip->x_min && dst_x < clip->x_max && pattern_trans) { - uint32_t src_data = 0; - int transparent = 0; + if (dst_x >= clip->x_min && dst_x < clip->x_max && pattern_trans) { + uint32_t src_data = 0; + int transparent = 0; - switch (voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) { - case SRC_FORMAT_COL_1_BPP: { - uint8_t src_byte = src_p[src_x_real]; - src_data = (src_byte & (0x80 >> (src_x & 7))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack; - if (voodoo->banshee_blt.command & COMMAND_TRANS_MONO) - transparent = !(src_byte & (0x80 >> (src_x & 7))); -// pclog(" 1bpp src_byte=%02x src_x=%i src_data=%x transparent=%i\n", src_byte, src_x, src_data, transparent); - break; - } - case SRC_FORMAT_COL_8_BPP: { - src_data = src_p[src_x_real]; - break; - } - case SRC_FORMAT_COL_16_BPP: { - uint16_t src_16 = *(uint16_t *)&src_p[src_x_real]; - int r = (src_16 >> 11); - int g = (src_16 >> 5) & 0x3f; - int b = src_16 & 0x1f; + switch (voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) { + case SRC_FORMAT_COL_1_BPP: { + uint8_t src_byte = src_p[src_x_real]; + src_data = (src_byte & (0x80 >> (src_x & 7))) ? voodoo->banshee_blt.colorFore + : voodoo->banshee_blt.colorBack; + if (voodoo->banshee_blt.command & COMMAND_TRANS_MONO) + transparent = !(src_byte & (0x80 >> (src_x & 7))); + // pclog(" 1bpp + // src_byte=%02x src_x=%i + // src_data=%x + // transparent=%i\n", + // src_byte, src_x, + // src_data, transparent); + break; + } + case SRC_FORMAT_COL_8_BPP: { + src_data = src_p[src_x_real]; + break; + } + case SRC_FORMAT_COL_16_BPP: { + uint16_t src_16 = *(uint16_t *)&src_p[src_x_real]; + int r = (src_16 >> 11); + int g = (src_16 >> 5) & 0x3f; + int b = src_16 & 0x1f; - r = (r << 3) | (r >> 2); - g = (g << 2) | (g >> 4); - b = (b << 3) | (b >> 2); - src_data = (r << 16) | (g << 8) | b; - break; - } - case SRC_FORMAT_COL_24_BPP: { - src_data = *(uint32_t *)&src_p[src_x_real]; - break; - } - case SRC_FORMAT_COL_32_BPP: { - src_data = *(uint32_t *)&src_p[src_x_real]; - break; - } + r = (r << 3) | (r >> 2); + g = (g << 2) | (g >> 4); + b = (b << 3) | (b >> 2); + src_data = (r << 16) | (g << 8) | b; + break; + } + case SRC_FORMAT_COL_24_BPP: { + src_data = *(uint32_t *)&src_p[src_x_real]; + break; + } + case SRC_FORMAT_COL_32_BPP: { + src_data = *(uint32_t *)&src_p[src_x_real]; + break; + } #ifndef RELEASE_BUILD - default:fatal("banshee_do_screen_to_screen_blt: unknown srcFormat %08x\n", voodoo->banshee_blt.srcFormat); + default: + fatal("banshee_do_screen_to_screen_blt: unknown srcFormat %08x\n", + voodoo->banshee_blt.srcFormat); #endif - } + } - if ((voodoo->banshee_blt.dstFormat & DST_FORMAT_COL_MASK) == DST_FORMAT_COL_16_BPP && - (voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) != SRC_FORMAT_COL_1_BPP) { - int r = src_data >> 16; - int g = (src_data >> 8) & 0xff; - int b = src_data & 0xff; + if ((voodoo->banshee_blt.dstFormat & DST_FORMAT_COL_MASK) == DST_FORMAT_COL_16_BPP && + (voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) != SRC_FORMAT_COL_1_BPP) { + int r = src_data >> 16; + int g = (src_data >> 8) & 0xff; + int b = src_data & 0xff; - src_data = (b >> 3) | ((g >> 2) << 5) | ((r >> 3) << 11); - } + src_data = (b >> 3) | ((g >> 2) << 5) | ((r >> 3) << 11); + } - if (!transparent) - PLOT(voodoo, dst_x, dst_y, pat_x, pat_y, pattern_mask, rop, src_data, src_colorkey); - } - if (use_x_dir) { - src_x += (voodoo->banshee_blt.command & COMMAND_DX) ? -1 : 1; - dst_x += (voodoo->banshee_blt.command & COMMAND_DX) ? -1 : 1; - pat_x += (voodoo->banshee_blt.command & COMMAND_DX) ? -1 : 1; - } else { - src_x++; - dst_x++; - pat_x++; - } - } - } - voodoo->banshee_blt.srcY += (voodoo->banshee_blt.command & COMMAND_DY) ? -1 : 1; - voodoo->banshee_blt.dstY += (voodoo->banshee_blt.command & COMMAND_DY) ? -1 : 1; - } + if (!transparent) + PLOT(voodoo, dst_x, dst_y, pat_x, pat_y, pattern_mask, rop, src_data, + src_colorkey); + } + if (use_x_dir) { + src_x += (voodoo->banshee_blt.command & COMMAND_DX) ? -1 : 1; + dst_x += (voodoo->banshee_blt.command & COMMAND_DX) ? -1 : 1; + pat_x += (voodoo->banshee_blt.command & COMMAND_DX) ? -1 : 1; + } else { + src_x++; + dst_x++; + pat_x++; + } + } + } + voodoo->banshee_blt.srcY += (voodoo->banshee_blt.command & COMMAND_DY) ? -1 : 1; + voodoo->banshee_blt.dstY += (voodoo->banshee_blt.command & COMMAND_DY) ? -1 : 1; + } } static void banshee_do_screen_to_screen_blt(voodoo_t *voodoo) { -// pclog("screen_to_screen: %08x %08x %08x\n", voodoo->banshee_blt.srcFormat, voodoo->banshee_blt.src_stride, voodoo->banshee_blt.src_stride_dest); -// return; - for (voodoo->banshee_blt.cur_y = 0; voodoo->banshee_blt.cur_y < voodoo->banshee_blt.dstSizeY; voodoo->banshee_blt.cur_y++) { - uint32_t src_addr = get_addr(voodoo, 0, voodoo->banshee_blt.srcY, 1, voodoo->banshee_blt.src_stride_dest); -// if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) == SRC_FORMAT_COL_1_BPP) -// pclog(" srcY=%i src_addr=%08x\n", voodoo->banshee_blt.srcY, src_addr); - do_screen_to_screen_line(voodoo, &voodoo->vram[src_addr], 1, voodoo->banshee_blt.srcX, voodoo->banshee_blt.srcBaseAddr_tiled); - } - end_command(voodoo); + // pclog("screen_to_screen: %08x %08x %08x\n", voodoo->banshee_blt.srcFormat, voodoo->banshee_blt.src_stride, + // voodoo->banshee_blt.src_stride_dest); + // return; + for (voodoo->banshee_blt.cur_y = 0; voodoo->banshee_blt.cur_y < voodoo->banshee_blt.dstSizeY; + voodoo->banshee_blt.cur_y++) { + uint32_t src_addr = get_addr(voodoo, 0, voodoo->banshee_blt.srcY, 1, voodoo->banshee_blt.src_stride_dest); + // if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) == SRC_FORMAT_COL_1_BPP) + // pclog(" srcY=%i src_addr=%08x\n", voodoo->banshee_blt.srcY, src_addr); + do_screen_to_screen_line(voodoo, &voodoo->vram[src_addr], 1, voodoo->banshee_blt.srcX, + voodoo->banshee_blt.srcBaseAddr_tiled); + } + end_command(voodoo); } static void banshee_do_host_to_screen_blt(voodoo_t *voodoo, int count, uint32_t data) { -// if (voodoo->banshee_blt.dstBaseAddr == 0xee5194) -// pclog("banshee_do_host_to_screen_blt: data=%08x host_data_count=%i src_stride_dest=%i host_data_size_dest=%i\n", data, voodoo->banshee_blt.host_data_count, voodoo->banshee_blt.src_stride_dest, voodoo->banshee_blt.host_data_size_dest); + // if (voodoo->banshee_blt.dstBaseAddr == 0xee5194) + // pclog("banshee_do_host_to_screen_blt: data=%08x host_data_count=%i src_stride_dest=%i + // host_data_size_dest=%i\n", data, voodoo->banshee_blt.host_data_count, + // voodoo->banshee_blt.src_stride_dest, voodoo->banshee_blt.host_data_size_dest); - if (voodoo->banshee_blt.srcFormat & SRC_FORMAT_BYTE_SWIZZLE) - data = (data >> 24) | ((data >> 8) & 0xff00) | ((data << 8) & 0xff0000) | (data << 24); - if (voodoo->banshee_blt.srcFormat & SRC_FORMAT_WORD_SWIZZLE) - data = (data >> 16) | (data << 16); + if (voodoo->banshee_blt.srcFormat & SRC_FORMAT_BYTE_SWIZZLE) + data = (data >> 24) | ((data >> 8) & 0xff00) | ((data << 8) & 0xff0000) | (data << 24); + if (voodoo->banshee_blt.srcFormat & SRC_FORMAT_WORD_SWIZZLE) + data = (data >> 16) | (data << 16); - if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_PACKING_MASK) == SRC_FORMAT_PACKING_STRIDE) { - int last_byte; + if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_PACKING_MASK) == SRC_FORMAT_PACKING_STRIDE) { + int last_byte; - if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) == SRC_FORMAT_COL_1_BPP) - last_byte = ((voodoo->banshee_blt.srcX & 31) + voodoo->banshee_blt.dstSizeX + 7) >> 3; - else - last_byte = (voodoo->banshee_blt.srcX & 3) + voodoo->banshee_blt.host_data_size_dest; + if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) == SRC_FORMAT_COL_1_BPP) + last_byte = ((voodoo->banshee_blt.srcX & 31) + voodoo->banshee_blt.dstSizeX + 7) >> 3; + else + last_byte = (voodoo->banshee_blt.srcX & 3) + voodoo->banshee_blt.host_data_size_dest; - *(uint32_t *)&voodoo->banshee_blt.host_data[voodoo->banshee_blt.host_data_count] = data; - voodoo->banshee_blt.host_data_count += 4; - if (voodoo->banshee_blt.host_data_count >= last_byte) { -// pclog(" %i %i srcX=%i srcFormat=%08x\n", voodoo->banshee_blt.cur_y, voodoo->banshee_blt.dstSizeY, voodoo->banshee_blt.srcX); - if (voodoo->banshee_blt.cur_y < voodoo->banshee_blt.dstSizeY) { - if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) == SRC_FORMAT_COL_1_BPP) - do_screen_to_screen_line(voodoo, &voodoo->banshee_blt.host_data[(voodoo->banshee_blt.srcX >> 3) & 3], 0, voodoo->banshee_blt.srcX & 7, 0); - else - do_screen_to_screen_line(voodoo, &voodoo->banshee_blt.host_data[voodoo->banshee_blt.srcX & 3], 0, 0, 0); - voodoo->banshee_blt.cur_y++; - if (voodoo->banshee_blt.cur_y == voodoo->banshee_blt.dstSizeY) - end_command(voodoo); - } + *(uint32_t *)&voodoo->banshee_blt.host_data[voodoo->banshee_blt.host_data_count] = data; + voodoo->banshee_blt.host_data_count += 4; + if (voodoo->banshee_blt.host_data_count >= last_byte) { + // pclog(" %i %i srcX=%i srcFormat=%08x\n", voodoo->banshee_blt.cur_y, + // voodoo->banshee_blt.dstSizeY, voodoo->banshee_blt.srcX); + if (voodoo->banshee_blt.cur_y < voodoo->banshee_blt.dstSizeY) { + if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) == SRC_FORMAT_COL_1_BPP) + do_screen_to_screen_line( + voodoo, &voodoo->banshee_blt.host_data[(voodoo->banshee_blt.srcX >> 3) & 3], 0, + voodoo->banshee_blt.srcX & 7, 0); + else + do_screen_to_screen_line( + voodoo, &voodoo->banshee_blt.host_data[voodoo->banshee_blt.srcX & 3], 0, 0, 0); + voodoo->banshee_blt.cur_y++; + if (voodoo->banshee_blt.cur_y == voodoo->banshee_blt.dstSizeY) + end_command(voodoo); + } - if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) == SRC_FORMAT_COL_1_BPP) - voodoo->banshee_blt.srcX += (voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK) << 3; - else - voodoo->banshee_blt.srcX += (voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK); + if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) == SRC_FORMAT_COL_1_BPP) + voodoo->banshee_blt.srcX += (voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK) << 3; + else + voodoo->banshee_blt.srcX += (voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK); - voodoo->banshee_blt.host_data_count = 0; - } - } else { - *(uint32_t *)&voodoo->banshee_blt.host_data[voodoo->banshee_blt.host_data_count] = data; - voodoo->banshee_blt.host_data_count += 4; - while (voodoo->banshee_blt.host_data_count >= voodoo->banshee_blt.src_stride_dest) { - voodoo->banshee_blt.host_data_count -= voodoo->banshee_blt.src_stride_dest; + voodoo->banshee_blt.host_data_count = 0; + } + } else { + *(uint32_t *)&voodoo->banshee_blt.host_data[voodoo->banshee_blt.host_data_count] = data; + voodoo->banshee_blt.host_data_count += 4; + while (voodoo->banshee_blt.host_data_count >= voodoo->banshee_blt.src_stride_dest) { + voodoo->banshee_blt.host_data_count -= voodoo->banshee_blt.src_stride_dest; -// pclog(" %i %i\n", voodoo->banshee_blt.cur_y, voodoo->banshee_blt.dstSizeY); - if (voodoo->banshee_blt.cur_y < voodoo->banshee_blt.dstSizeY) { - do_screen_to_screen_line(voodoo, voodoo->banshee_blt.host_data, 0, 0, 0); - voodoo->banshee_blt.cur_y++; - if (voodoo->banshee_blt.cur_y == voodoo->banshee_blt.dstSizeY) - end_command(voodoo); - } + // pclog(" %i %i\n", voodoo->banshee_blt.cur_y, voodoo->banshee_blt.dstSizeY); + if (voodoo->banshee_blt.cur_y < voodoo->banshee_blt.dstSizeY) { + do_screen_to_screen_line(voodoo, voodoo->banshee_blt.host_data, 0, 0, 0); + voodoo->banshee_blt.cur_y++; + if (voodoo->banshee_blt.cur_y == voodoo->banshee_blt.dstSizeY) + end_command(voodoo); + } - if (voodoo->banshee_blt.host_data_count) { -// pclog(" remaining=%i\n", voodoo->banshee_blt.host_data_count); - *(uint32_t *)&voodoo->banshee_blt.host_data[0] = data >> (4 - voodoo->banshee_blt.host_data_count) * 8; - } - } - } + if (voodoo->banshee_blt.host_data_count) { + // pclog(" remaining=%i\n", voodoo->banshee_blt.host_data_count); + *(uint32_t *)&voodoo->banshee_blt.host_data[0] = + data >> (4 - voodoo->banshee_blt.host_data_count) * 8; + } + } + } } static void do_screen_to_screen_stretch_line(voodoo_t *voodoo, uint8_t *src_p, int src_x, int *src_y) { - clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0]; -// int src_y = voodoo->banshee_blt.srcY; - int dst_y = voodoo->banshee_blt.dstY; - int pat_y = (voodoo->banshee_blt.commandExtra & CMDEXTRA_FORCE_PAT_ROW0) ? 0 : (voodoo->banshee_blt.patoff_y + voodoo->banshee_blt.dstY); - uint8_t *pattern_mono = (uint8_t *)voodoo->banshee_blt.colorPattern; - int use_pattern_trans = (voodoo->banshee_blt.command & (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO)) == - (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO); - uint32_t *colorPattern = voodoo->banshee_blt.colorPattern; + clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0]; + // int src_y = voodoo->banshee_blt.srcY; + int dst_y = voodoo->banshee_blt.dstY; + int pat_y = (voodoo->banshee_blt.commandExtra & CMDEXTRA_FORCE_PAT_ROW0) + ? 0 + : (voodoo->banshee_blt.patoff_y + voodoo->banshee_blt.dstY); + uint8_t *pattern_mono = (uint8_t *)voodoo->banshee_blt.colorPattern; + int use_pattern_trans = (voodoo->banshee_blt.command & (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO)) == + (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO); + uint32_t *colorPattern = voodoo->banshee_blt.colorPattern; - //int error_y = voodoo->banshee_blt.dstSizeY / 2; + // int error_y = voodoo->banshee_blt.dstSizeY / 2; -/* pclog("banshee_do_screen_to_screen_stretch_blt:\n"); - pclog(" srcXY=%i,%i srcsizeXY=%i,%i\n", voodoo->banshee_blt.srcX, voodoo->banshee_blt.srcY, voodoo->banshee_blt.srcSizeX, voodoo->banshee_blt.srcSizeY); - pclog(" dstXY=%i,%i dstsizeXY=%i,%i\n", voodoo->banshee_blt.dstX, voodoo->banshee_blt.dstY, voodoo->banshee_blt.dstSizeX, voodoo->banshee_blt.dstSizeY);*/ - if (dst_y >= clip->y_min && dst_y < clip->y_max) { -// int src_x = voodoo->banshee_blt.srcX; - int dst_x = voodoo->banshee_blt.dstX; - int pat_x = voodoo->banshee_blt.patoff_x + voodoo->banshee_blt.dstX; - uint8_t pattern_mask = pattern_mono[pat_y & 7]; - int error_x = voodoo->banshee_blt.dstSizeX / 2; + /* pclog("banshee_do_screen_to_screen_stretch_blt:\n"); + pclog(" srcXY=%i,%i srcsizeXY=%i,%i\n", voodoo->banshee_blt.srcX, voodoo->banshee_blt.srcY, + voodoo->banshee_blt.srcSizeX, voodoo->banshee_blt.srcSizeY); pclog(" dstXY=%i,%i dstsizeXY=%i,%i\n", + voodoo->banshee_blt.dstX, voodoo->banshee_blt.dstY, voodoo->banshee_blt.dstSizeX, voodoo->banshee_blt.dstSizeY);*/ + if (dst_y >= clip->y_min && dst_y < clip->y_max) { + // int src_x = voodoo->banshee_blt.srcX; + int dst_x = voodoo->banshee_blt.dstX; + int pat_x = voodoo->banshee_blt.patoff_x + voodoo->banshee_blt.dstX; + uint8_t pattern_mask = pattern_mono[pat_y & 7]; + int error_x = voodoo->banshee_blt.dstSizeX / 2; -// pclog(" Plot dest line %03i : src line %03i\n", dst_y, src_y); - for (voodoo->banshee_blt.cur_x = 0; voodoo->banshee_blt.cur_x < voodoo->banshee_blt.dstSizeX; voodoo->banshee_blt.cur_x++) { - int pattern_trans = use_pattern_trans ? (pattern_mask & (1 << (7 - (pat_x & 7)))) : 1; + // pclog(" Plot dest line %03i : src line %03i\n", dst_y, src_y); + for (voodoo->banshee_blt.cur_x = 0; voodoo->banshee_blt.cur_x < voodoo->banshee_blt.dstSizeX; + voodoo->banshee_blt.cur_x++) { + int pattern_trans = use_pattern_trans ? (pattern_mask & (1 << (7 - (pat_x & 7)))) : 1; - if (dst_x >= clip->x_min && dst_x < clip->x_max && pattern_trans) { - switch (voodoo->banshee_blt.dstFormat & DST_FORMAT_COL_MASK) { - case DST_FORMAT_COL_8_BPP: { - uint32_t dst_addr = get_addr(voodoo, dst_x, dst_y, 0, 0);//(voodoo->banshee_blt.dstBaseAddr + dst_x + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; - uint32_t src = src_p[src_x]; - uint32_t dest = voodoo->vram[dst_addr]; - uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? - ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : - colorPattern[(pat_x & 7) + (pat_y & 7) * 8]; + if (dst_x >= clip->x_min && dst_x < clip->x_max && pattern_trans) { + switch (voodoo->banshee_blt.dstFormat & DST_FORMAT_COL_MASK) { + case DST_FORMAT_COL_8_BPP: { + uint32_t dst_addr = + get_addr(voodoo, dst_x, dst_y, 0, + 0); //(voodoo->banshee_blt.dstBaseAddr + dst_x + + //dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t src = src_p[src_x]; + uint32_t dest = voodoo->vram[dst_addr]; + uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) + ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) + ? voodoo->banshee_blt.colorFore + : voodoo->banshee_blt.colorBack) + : colorPattern[(pat_x & 7) + (pat_y & 7) * 8]; - voodoo->vram[dst_addr] = MIX(voodoo, dest, src, pattern, COLORKEY_8, COLORKEY_8); -// pclog("%i,%i : sdp=%02x,%02x,%02x res=%02x\n", voodoo->banshee_blt.cur_x, voodoo->banshee_blt.cur_y, src, dest, pattern, voodoo->vram[dst_addr]); - voodoo->changedvram[dst_addr >> 12] = changeframecount; - break; - } - case DST_FORMAT_COL_16_BPP: { - uint32_t dst_addr = get_addr(voodoo, - dst_x * 2, dst_y, 0, 0);//(voodoo->banshee_blt.dstBaseAddr + dst_x*2 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; - uint32_t src = *(uint16_t *)&src_p[src_x * 2]; - uint32_t dest = *(uint16_t *)&voodoo->vram[dst_addr]; - uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? - ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : - colorPattern[(pat_x & 7) + (pat_y & 7) * 8]; + voodoo->vram[dst_addr] = MIX(voodoo, dest, src, pattern, COLORKEY_8, COLORKEY_8); + // pclog("%i,%i : sdp=%02x,%02x,%02x + // res=%02x\n", voodoo->banshee_blt.cur_x, + // voodoo->banshee_blt.cur_y, src, dest, + // pattern, voodoo->vram[dst_addr]); + voodoo->changedvram[dst_addr >> 12] = changeframecount; + break; + } + case DST_FORMAT_COL_16_BPP: { + uint32_t dst_addr = + get_addr(voodoo, dst_x * 2, dst_y, 0, + 0); //(voodoo->banshee_blt.dstBaseAddr + dst_x*2 + + //dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t src = *(uint16_t *)&src_p[src_x * 2]; + uint32_t dest = *(uint16_t *)&voodoo->vram[dst_addr]; + uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) + ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) + ? voodoo->banshee_blt.colorFore + : voodoo->banshee_blt.colorBack) + : colorPattern[(pat_x & 7) + (pat_y & 7) * 8]; - *(uint16_t *)&voodoo->vram[dst_addr] = MIX(voodoo, dest, src, pattern, COLORKEY_16, COLORKEY_16); -// pclog("%i,%i : sdp=%02x,%02x,%02x res=%02x\n", voodoo->banshee_blt.cur_x, voodoo->banshee_blt.cur_y, src, dest, pattern, *(uint16_t *)&voodoo->vram[dst_addr]); - voodoo->changedvram[dst_addr >> 12] = changeframecount; - break; - } - case DST_FORMAT_COL_24_BPP: { - uint32_t dst_addr = get_addr(voodoo, - dst_x * 3, dst_y, 0, 0);//(voodoo->banshee_blt.dstBaseAddr + dst_x*3 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; - uint32_t src = *(uint32_t *)&src_p[src_x * 3]; - uint32_t dest = *(uint32_t *)&voodoo->vram[dst_addr]; - uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? - ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : - colorPattern[(pat_x & 7) + (pat_y & 7) * 8]; + *(uint16_t *)&voodoo->vram[dst_addr] = + MIX(voodoo, dest, src, pattern, COLORKEY_16, COLORKEY_16); + // pclog("%i,%i : sdp=%02x,%02x,%02x + // res=%02x\n", voodoo->banshee_blt.cur_x, + // voodoo->banshee_blt.cur_y, src, dest, + // pattern, *(uint16_t + // *)&voodoo->vram[dst_addr]); + voodoo->changedvram[dst_addr >> 12] = changeframecount; + break; + } + case DST_FORMAT_COL_24_BPP: { + uint32_t dst_addr = + get_addr(voodoo, dst_x * 3, dst_y, 0, + 0); //(voodoo->banshee_blt.dstBaseAddr + dst_x*3 + + //dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t src = *(uint32_t *)&src_p[src_x * 3]; + uint32_t dest = *(uint32_t *)&voodoo->vram[dst_addr]; + uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) + ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) + ? voodoo->banshee_blt.colorFore + : voodoo->banshee_blt.colorBack) + : colorPattern[(pat_x & 7) + (pat_y & 7) * 8]; - *(uint32_t *)&voodoo->vram[dst_addr] = - (MIX(voodoo, dest, src, pattern, COLORKEY_32, COLORKEY_32) & 0xffffff) | (*(uint32_t *)&voodoo->vram[dst_addr] & 0xff000000); -// pclog("%i,%i : sdp=%02x,%02x,%02x res=%02x\n", voodoo->banshee_blt.cur_x, voodoo->banshee_blt.cur_y, src, dest, pattern, voodoo->vram[dst_addr]); - voodoo->changedvram[dst_addr >> 12] = changeframecount; - break; - } - case DST_FORMAT_COL_32_BPP: { - uint32_t dst_addr = get_addr(voodoo, - dst_x * 4, dst_y, 0, 0);//(voodoo->banshee_blt.dstBaseAddr + dst_x*4 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; - uint32_t src = *(uint32_t *)&src_p[src_x * 4]; - uint32_t dest = *(uint32_t *)&voodoo->vram[dst_addr]; - uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? - ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : - colorPattern[(pat_x & 7) + (pat_y & 7) * 8]; + *(uint32_t *)&voodoo->vram[dst_addr] = + (MIX(voodoo, dest, src, pattern, COLORKEY_32, COLORKEY_32) & 0xffffff) | + (*(uint32_t *)&voodoo->vram[dst_addr] & 0xff000000); + // pclog("%i,%i : sdp=%02x,%02x,%02x + // res=%02x\n", voodoo->banshee_blt.cur_x, + // voodoo->banshee_blt.cur_y, src, dest, + // pattern, voodoo->vram[dst_addr]); + voodoo->changedvram[dst_addr >> 12] = changeframecount; + break; + } + case DST_FORMAT_COL_32_BPP: { + uint32_t dst_addr = + get_addr(voodoo, dst_x * 4, dst_y, 0, + 0); //(voodoo->banshee_blt.dstBaseAddr + dst_x*4 + + //dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t src = *(uint32_t *)&src_p[src_x * 4]; + uint32_t dest = *(uint32_t *)&voodoo->vram[dst_addr]; + uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) + ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) + ? voodoo->banshee_blt.colorFore + : voodoo->banshee_blt.colorBack) + : colorPattern[(pat_x & 7) + (pat_y & 7) * 8]; - *(uint32_t *)&voodoo->vram[dst_addr] = MIX(voodoo, dest, src, pattern, COLORKEY_32, COLORKEY_32); -// pclog("%i,%i : sdp=%02x,%02x,%02x res=%02x\n", voodoo->banshee_blt.cur_x, voodoo->banshee_blt.cur_y, src, dest, pattern, voodoo->vram[dst_addr]); - voodoo->changedvram[dst_addr >> 12] = changeframecount; - break; - } - } - } + *(uint32_t *)&voodoo->vram[dst_addr] = + MIX(voodoo, dest, src, pattern, COLORKEY_32, COLORKEY_32); + // pclog("%i,%i : sdp=%02x,%02x,%02x + // res=%02x\n", voodoo->banshee_blt.cur_x, + // voodoo->banshee_blt.cur_y, src, dest, + // pattern, voodoo->vram[dst_addr]); + voodoo->changedvram[dst_addr >> 12] = changeframecount; + break; + } + } + } - error_x -= voodoo->banshee_blt.srcSizeX; - while (error_x < 0) { - error_x += voodoo->banshee_blt.dstSizeX; - src_x++; - } - dst_x++; - pat_x++; - } - } + error_x -= voodoo->banshee_blt.srcSizeX; + while (error_x < 0) { + error_x += voodoo->banshee_blt.dstSizeX; + src_x++; + } + dst_x++; + pat_x++; + } + } - voodoo->banshee_blt.bres_error_0 -= voodoo->banshee_blt.srcSizeY; - while (voodoo->banshee_blt.bres_error_0 < 0) { - voodoo->banshee_blt.bres_error_0 += voodoo->banshee_blt.dstSizeY; - if (src_y) - (*src_y) += (voodoo->banshee_blt.command & COMMAND_DY) ? -1 : 1; - } - voodoo->banshee_blt.dstY += (voodoo->banshee_blt.command & COMMAND_DY) ? -1 : 1; -// pat_y += (voodoo->banshee_blt.command & COMMAND_DY) ? -1 : 1; + voodoo->banshee_blt.bres_error_0 -= voodoo->banshee_blt.srcSizeY; + while (voodoo->banshee_blt.bres_error_0 < 0) { + voodoo->banshee_blt.bres_error_0 += voodoo->banshee_blt.dstSizeY; + if (src_y) + (*src_y) += (voodoo->banshee_blt.command & COMMAND_DY) ? -1 : 1; + } + voodoo->banshee_blt.dstY += (voodoo->banshee_blt.command & COMMAND_DY) ? -1 : 1; + // pat_y += (voodoo->banshee_blt.command & COMMAND_DY) ? -1 : 1; } static void banshee_do_screen_to_screen_stretch_blt(voodoo_t *voodoo) { -// pclog("screen_to_screen: %08x %08x %08x\n", voodoo->banshee_blt.srcFormat, voodoo->banshee_blt.src_stride, voodoo->banshee_blt.src_stride_dest); -// return; - for (voodoo->banshee_blt.cur_y = 0; voodoo->banshee_blt.cur_y < voodoo->banshee_blt.dstSizeY; voodoo->banshee_blt.cur_y++) { - uint32_t src_addr = get_addr(voodoo, - 0, - voodoo->banshee_blt.srcY, - 1, - voodoo->banshee_blt.src_stride_src);//(voodoo->banshee_blt.srcBaseAddr + voodoo->banshee_blt.srcY*voodoo->banshee_blt.src_stride_src) & voodoo->fb_mask; -// pclog("scale_blit %i %08x %08x\n", voodoo->banshee_blt.cur_y, src_addr, voodoo->banshee_blt.command); -// if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) == SRC_FORMAT_COL_1_BPP) -// pclog(" srcY=%i src_addr=%08x\n", voodoo->banshee_blt.srcY, src_addr); - do_screen_to_screen_stretch_line(voodoo, &voodoo->vram[src_addr], voodoo->banshee_blt.srcX, &voodoo->banshee_blt.srcY); - } - end_command(voodoo); + // pclog("screen_to_screen: %08x %08x %08x\n", voodoo->banshee_blt.srcFormat, voodoo->banshee_blt.src_stride, + // voodoo->banshee_blt.src_stride_dest); + // return; + for (voodoo->banshee_blt.cur_y = 0; voodoo->banshee_blt.cur_y < voodoo->banshee_blt.dstSizeY; + voodoo->banshee_blt.cur_y++) { + uint32_t src_addr = get_addr(voodoo, 0, voodoo->banshee_blt.srcY, 1, + voodoo->banshee_blt.src_stride_src); //(voodoo->banshee_blt.srcBaseAddr + + //voodoo->banshee_blt.srcY*voodoo->banshee_blt.src_stride_src) + //& voodoo->fb_mask; + // pclog("scale_blit %i %08x %08x\n", voodoo->banshee_blt.cur_y, src_addr, + // voodoo->banshee_blt.command); if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) == + // SRC_FORMAT_COL_1_BPP) + // pclog(" srcY=%i src_addr=%08x\n", voodoo->banshee_blt.srcY, src_addr); + do_screen_to_screen_stretch_line(voodoo, &voodoo->vram[src_addr], voodoo->banshee_blt.srcX, + &voodoo->banshee_blt.srcY); + } + end_command(voodoo); } static void banshee_do_host_to_screen_stretch_blt(voodoo_t *voodoo, int count, uint32_t data) { -// if (voodoo->banshee_blt.dstBaseAddr == 0xee5194) -// pclog("banshee_do_host_to_screen_blt: data=%08x host_data_count=%i src_stride_dest=%i host_data_size_dest=%i\n", data, voodoo->banshee_blt.host_data_count, voodoo->banshee_blt.src_stride_dest, voodoo->banshee_blt.host_data_size_dest); + // if (voodoo->banshee_blt.dstBaseAddr == 0xee5194) + // pclog("banshee_do_host_to_screen_blt: data=%08x host_data_count=%i src_stride_dest=%i + // host_data_size_dest=%i\n", data, voodoo->banshee_blt.host_data_count, + // voodoo->banshee_blt.src_stride_dest, voodoo->banshee_blt.host_data_size_dest); - if (voodoo->banshee_blt.srcFormat & SRC_FORMAT_BYTE_SWIZZLE) - data = (data >> 24) | ((data >> 8) & 0xff00) | ((data << 8) & 0xff0000) | (data << 24); - if (voodoo->banshee_blt.srcFormat & SRC_FORMAT_WORD_SWIZZLE) - data = (data >> 16) | (data << 16); + if (voodoo->banshee_blt.srcFormat & SRC_FORMAT_BYTE_SWIZZLE) + data = (data >> 24) | ((data >> 8) & 0xff00) | ((data << 8) & 0xff0000) | (data << 24); + if (voodoo->banshee_blt.srcFormat & SRC_FORMAT_WORD_SWIZZLE) + data = (data >> 16) | (data << 16); - if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_PACKING_MASK) == SRC_FORMAT_PACKING_STRIDE) { - int last_byte = (voodoo->banshee_blt.srcX & 3) + voodoo->banshee_blt.host_data_size_src; + if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_PACKING_MASK) == SRC_FORMAT_PACKING_STRIDE) { + int last_byte = (voodoo->banshee_blt.srcX & 3) + voodoo->banshee_blt.host_data_size_src; - *(uint32_t *)&voodoo->banshee_blt.host_data[voodoo->banshee_blt.host_data_count] = data; - voodoo->banshee_blt.host_data_count += 4; - if (voodoo->banshee_blt.host_data_count >= last_byte) { -// pclog(" %i %i srcX=%i srcFormat=%08x\n", voodoo->banshee_blt.cur_y, voodoo->banshee_blt.dstSizeY, voodoo->banshee_blt.srcX); - if (voodoo->banshee_blt.cur_y < voodoo->banshee_blt.dstSizeY) { - if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) == SRC_FORMAT_COL_1_BPP) - do_screen_to_screen_stretch_line(voodoo, &voodoo->banshee_blt.host_data[(voodoo->banshee_blt.srcX >> 3) & 3], voodoo->banshee_blt.srcX & 7, NULL); - else - do_screen_to_screen_stretch_line(voodoo, &voodoo->banshee_blt.host_data[voodoo->banshee_blt.srcX & 3], 0, NULL); - voodoo->banshee_blt.cur_y++; - if (voodoo->banshee_blt.cur_y == voodoo->banshee_blt.dstSizeY) - end_command(voodoo); - } + *(uint32_t *)&voodoo->banshee_blt.host_data[voodoo->banshee_blt.host_data_count] = data; + voodoo->banshee_blt.host_data_count += 4; + if (voodoo->banshee_blt.host_data_count >= last_byte) { + // pclog(" %i %i srcX=%i srcFormat=%08x\n", voodoo->banshee_blt.cur_y, + // voodoo->banshee_blt.dstSizeY, voodoo->banshee_blt.srcX); + if (voodoo->banshee_blt.cur_y < voodoo->banshee_blt.dstSizeY) { + if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) == SRC_FORMAT_COL_1_BPP) + do_screen_to_screen_stretch_line( + voodoo, &voodoo->banshee_blt.host_data[(voodoo->banshee_blt.srcX >> 3) & 3], + voodoo->banshee_blt.srcX & 7, NULL); + else + do_screen_to_screen_stretch_line( + voodoo, &voodoo->banshee_blt.host_data[voodoo->banshee_blt.srcX & 3], 0, NULL); + voodoo->banshee_blt.cur_y++; + if (voodoo->banshee_blt.cur_y == voodoo->banshee_blt.dstSizeY) + end_command(voodoo); + } - if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) == SRC_FORMAT_COL_1_BPP) - voodoo->banshee_blt.srcX += (voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK) << 3; - else - voodoo->banshee_blt.srcX += (voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK); + if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) == SRC_FORMAT_COL_1_BPP) + voodoo->banshee_blt.srcX += (voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK) << 3; + else + voodoo->banshee_blt.srcX += (voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK); - voodoo->banshee_blt.host_data_count = 0; - } - } else { - *(uint32_t *)&voodoo->banshee_blt.host_data[voodoo->banshee_blt.host_data_count] = data; - voodoo->banshee_blt.host_data_count += 4; - while (voodoo->banshee_blt.host_data_count >= voodoo->banshee_blt.src_stride_src) { - voodoo->banshee_blt.host_data_count -= voodoo->banshee_blt.src_stride_src; + voodoo->banshee_blt.host_data_count = 0; + } + } else { + *(uint32_t *)&voodoo->banshee_blt.host_data[voodoo->banshee_blt.host_data_count] = data; + voodoo->banshee_blt.host_data_count += 4; + while (voodoo->banshee_blt.host_data_count >= voodoo->banshee_blt.src_stride_src) { + voodoo->banshee_blt.host_data_count -= voodoo->banshee_blt.src_stride_src; -// pclog(" %i %i\n", voodoo->banshee_blt.cur_y, voodoo->banshee_blt.dstSizeY); - if (voodoo->banshee_blt.cur_y < voodoo->banshee_blt.dstSizeY) { - do_screen_to_screen_stretch_line(voodoo, voodoo->banshee_blt.host_data, 0, NULL); - voodoo->banshee_blt.cur_y++; - if (voodoo->banshee_blt.cur_y == voodoo->banshee_blt.dstSizeY) - end_command(voodoo); - } + // pclog(" %i %i\n", voodoo->banshee_blt.cur_y, voodoo->banshee_blt.dstSizeY); + if (voodoo->banshee_blt.cur_y < voodoo->banshee_blt.dstSizeY) { + do_screen_to_screen_stretch_line(voodoo, voodoo->banshee_blt.host_data, 0, NULL); + voodoo->banshee_blt.cur_y++; + if (voodoo->banshee_blt.cur_y == voodoo->banshee_blt.dstSizeY) + end_command(voodoo); + } - if (voodoo->banshee_blt.host_data_count) { -// pclog(" remaining=%i\n", voodoo->banshee_blt.host_data_count); - *(uint32_t *)&voodoo->banshee_blt.host_data[0] = data >> (4 - voodoo->banshee_blt.host_data_count) * 8; - } - } - } + if (voodoo->banshee_blt.host_data_count) { + // pclog(" remaining=%i\n", voodoo->banshee_blt.host_data_count); + *(uint32_t *)&voodoo->banshee_blt.host_data[0] = + data >> (4 - voodoo->banshee_blt.host_data_count) * 8; + } + } + } } static void step_line(voodoo_t *voodoo) { - if (voodoo->banshee_blt.line_pix_pos == voodoo->banshee_blt.line_rep_cnt) { - voodoo->banshee_blt.line_pix_pos = 0; - if (voodoo->banshee_blt.line_bit_pos == voodoo->banshee_blt.line_bit_mask_size) - voodoo->banshee_blt.line_bit_pos = 0; - else - voodoo->banshee_blt.line_bit_pos++; - } else - voodoo->banshee_blt.line_pix_pos++; + if (voodoo->banshee_blt.line_pix_pos == voodoo->banshee_blt.line_rep_cnt) { + voodoo->banshee_blt.line_pix_pos = 0; + if (voodoo->banshee_blt.line_bit_pos == voodoo->banshee_blt.line_bit_mask_size) + voodoo->banshee_blt.line_bit_pos = 0; + else + voodoo->banshee_blt.line_bit_pos++; + } else + voodoo->banshee_blt.line_pix_pos++; } static void banshee_do_line(voodoo_t *voodoo, int draw_last_pixel) { - clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0]; - uint8_t rop = voodoo->banshee_blt.command >> 24; - int dx = ABS(voodoo->banshee_blt.dstX - voodoo->banshee_blt.srcX); - int dy = ABS(voodoo->banshee_blt.dstY - voodoo->banshee_blt.srcY); - int x_inc = (voodoo->banshee_blt.dstX > voodoo->banshee_blt.srcX) ? 1 : -1; - int y_inc = (voodoo->banshee_blt.dstY > voodoo->banshee_blt.srcY) ? 1 : -1; - int x = voodoo->banshee_blt.srcX; - int y = voodoo->banshee_blt.srcY; - int error; - uint32_t stipple = (voodoo->banshee_blt.command & COMMAND_STIPPLE_LINE) ? - voodoo->banshee_blt.lineStipple : ~0; + clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0]; + uint8_t rop = voodoo->banshee_blt.command >> 24; + int dx = ABS(voodoo->banshee_blt.dstX - voodoo->banshee_blt.srcX); + int dy = ABS(voodoo->banshee_blt.dstY - voodoo->banshee_blt.srcY); + int x_inc = (voodoo->banshee_blt.dstX > voodoo->banshee_blt.srcX) ? 1 : -1; + int y_inc = (voodoo->banshee_blt.dstY > voodoo->banshee_blt.srcY) ? 1 : -1; + int x = voodoo->banshee_blt.srcX; + int y = voodoo->banshee_blt.srcY; + int error; + uint32_t stipple = (voodoo->banshee_blt.command & COMMAND_STIPPLE_LINE) ? voodoo->banshee_blt.lineStipple : ~0; - if (dx > dy) /*X major*/ - { - error = dx / 2; - while (x != voodoo->banshee_blt.dstX) { - int mask = stipple & (1 << voodoo->banshee_blt.line_bit_pos); - int pattern_trans = (voodoo->banshee_blt.command & COMMAND_TRANS_MONO) ? mask : 1; + if (dx > dy) /*X major*/ + { + error = dx / 2; + while (x != voodoo->banshee_blt.dstX) { + int mask = stipple & (1 << voodoo->banshee_blt.line_bit_pos); + int pattern_trans = (voodoo->banshee_blt.command & COMMAND_TRANS_MONO) ? mask : 1; - if (y >= clip->y_min && y < clip->y_max && x >= clip->x_min && x < clip->x_max && pattern_trans) - PLOT_LINE(voodoo, x, y, rop, mask ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack, COLORKEY_32); + if (y >= clip->y_min && y < clip->y_max && x >= clip->x_min && x < clip->x_max && pattern_trans) + PLOT_LINE(voodoo, x, y, rop, mask ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack, + COLORKEY_32); - error -= dy; - if (error < 0) { - error += dx; - y += y_inc; - } - x += x_inc; - step_line(voodoo); - } - } else /*Y major*/ - { - error = dy / 2; - while (y != voodoo->banshee_blt.dstY) { - int mask = stipple & (1 << voodoo->banshee_blt.line_bit_pos); - int pattern_trans = (voodoo->banshee_blt.command & COMMAND_TRANS_MONO) ? mask : 1; + error -= dy; + if (error < 0) { + error += dx; + y += y_inc; + } + x += x_inc; + step_line(voodoo); + } + } else /*Y major*/ + { + error = dy / 2; + while (y != voodoo->banshee_blt.dstY) { + int mask = stipple & (1 << voodoo->banshee_blt.line_bit_pos); + int pattern_trans = (voodoo->banshee_blt.command & COMMAND_TRANS_MONO) ? mask : 1; - if (y >= clip->y_min && y < clip->y_max && x >= clip->x_min && x < clip->x_max && pattern_trans) - PLOT_LINE(voodoo, x, y, rop, mask ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack, COLORKEY_32); + if (y >= clip->y_min && y < clip->y_max && x >= clip->x_min && x < clip->x_max && pattern_trans) + PLOT_LINE(voodoo, x, y, rop, mask ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack, + COLORKEY_32); - error -= dx; - if (error < 0) { - error += dy; - x += x_inc; - } - y += y_inc; - step_line(voodoo); - } - } + error -= dx; + if (error < 0) { + error += dy; + x += x_inc; + } + y += y_inc; + step_line(voodoo); + } + } - if (draw_last_pixel) { - int mask = stipple & (1 << voodoo->banshee_blt.line_bit_pos); - int pattern_trans = (voodoo->banshee_blt.command & COMMAND_TRANS_MONO) ? mask : 1; + if (draw_last_pixel) { + int mask = stipple & (1 << voodoo->banshee_blt.line_bit_pos); + int pattern_trans = (voodoo->banshee_blt.command & COMMAND_TRANS_MONO) ? mask : 1; - if (y >= clip->y_min && y < clip->y_max && x >= clip->x_min && x < clip->x_max && pattern_trans) - PLOT_LINE(voodoo, x, y, rop, mask ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack, COLORKEY_32); - } + if (y >= clip->y_min && y < clip->y_max && x >= clip->x_min && x < clip->x_max && pattern_trans) + PLOT_LINE(voodoo, x, y, rop, mask ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack, + COLORKEY_32); + } - voodoo->banshee_blt.srcXY = (x & 0xffff) | (y << 16); - voodoo->banshee_blt.srcX = x; - voodoo->banshee_blt.srcY = y; + voodoo->banshee_blt.srcXY = (x & 0xffff) | (y << 16); + voodoo->banshee_blt.srcX = x; + voodoo->banshee_blt.srcY = y; } static void banshee_polyfill_start(voodoo_t *voodoo) { - voodoo->banshee_blt.lx[0] = voodoo->banshee_blt.srcX; - voodoo->banshee_blt.ly[0] = voodoo->banshee_blt.srcY; - voodoo->banshee_blt.rx[0] = voodoo->banshee_blt.dstX; - voodoo->banshee_blt.ry[0] = voodoo->banshee_blt.dstY; - voodoo->banshee_blt.lx[1] = voodoo->banshee_blt.srcX; - voodoo->banshee_blt.ly[1] = voodoo->banshee_blt.srcY; - voodoo->banshee_blt.rx[1] = voodoo->banshee_blt.dstX; - voodoo->banshee_blt.ry[1] = voodoo->banshee_blt.dstY; - voodoo->banshee_blt.lx_cur = voodoo->banshee_blt.srcX; - voodoo->banshee_blt.rx_cur = voodoo->banshee_blt.dstX; + voodoo->banshee_blt.lx[0] = voodoo->banshee_blt.srcX; + voodoo->banshee_blt.ly[0] = voodoo->banshee_blt.srcY; + voodoo->banshee_blt.rx[0] = voodoo->banshee_blt.dstX; + voodoo->banshee_blt.ry[0] = voodoo->banshee_blt.dstY; + voodoo->banshee_blt.lx[1] = voodoo->banshee_blt.srcX; + voodoo->banshee_blt.ly[1] = voodoo->banshee_blt.srcY; + voodoo->banshee_blt.rx[1] = voodoo->banshee_blt.dstX; + voodoo->banshee_blt.ry[1] = voodoo->banshee_blt.dstY; + voodoo->banshee_blt.lx_cur = voodoo->banshee_blt.srcX; + voodoo->banshee_blt.rx_cur = voodoo->banshee_blt.dstX; } static void banshee_polyfill_continue(voodoo_t *voodoo, uint32_t data) { - clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0]; - uint8_t *pattern_mono = (uint8_t *)voodoo->banshee_blt.colorPattern; - int use_pattern_trans = (voodoo->banshee_blt.command & (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO)) == - (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO); - uint8_t rop = voodoo->banshee_blt.command >> 24; - int y = MAX(voodoo->banshee_blt.ly[0], voodoo->banshee_blt.ry[0]); - int y_end; + clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0]; + uint8_t *pattern_mono = (uint8_t *)voodoo->banshee_blt.colorPattern; + int use_pattern_trans = (voodoo->banshee_blt.command & (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO)) == + (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO); + uint8_t rop = voodoo->banshee_blt.command >> 24; + int y = MAX(voodoo->banshee_blt.ly[0], voodoo->banshee_blt.ry[0]); + int y_end; -// pclog("Polyfill : data %08x\n", data); + // pclog("Polyfill : data %08x\n", data); - /*if r1.y>=l1.y, next vertex is left*/ - if (voodoo->banshee_blt.ry[1] >= voodoo->banshee_blt.ly[1]) { - voodoo->banshee_blt.lx[1] = ((int32_t)(data << 19)) >> 19; - voodoo->banshee_blt.ly[1] = ((int32_t)(data << 3)) >> 19; - voodoo->banshee_blt.dx[0] = ABS(voodoo->banshee_blt.lx[1] - voodoo->banshee_blt.lx[0]); - voodoo->banshee_blt.dy[0] = ABS(voodoo->banshee_blt.ly[1] - voodoo->banshee_blt.ly[0]); - voodoo->banshee_blt.x_inc[0] = (voodoo->banshee_blt.lx[1] > voodoo->banshee_blt.lx[0]) ? 1 : -1; - voodoo->banshee_blt.error[0] = voodoo->banshee_blt.dy[0] / 2; - } else { - voodoo->banshee_blt.rx[1] = ((int32_t)(data << 19)) >> 19; - voodoo->banshee_blt.ry[1] = ((int32_t)(data << 3)) >> 19; - voodoo->banshee_blt.dx[1] = ABS(voodoo->banshee_blt.rx[1] - voodoo->banshee_blt.rx[0]); - voodoo->banshee_blt.dy[1] = ABS(voodoo->banshee_blt.ry[1] - voodoo->banshee_blt.ry[0]); - voodoo->banshee_blt.x_inc[1] = (voodoo->banshee_blt.rx[1] > voodoo->banshee_blt.rx[0]) ? 1 : -1; - voodoo->banshee_blt.error[1] = voodoo->banshee_blt.dy[1] / 2; - } + /*if r1.y>=l1.y, next vertex is left*/ + if (voodoo->banshee_blt.ry[1] >= voodoo->banshee_blt.ly[1]) { + voodoo->banshee_blt.lx[1] = ((int32_t)(data << 19)) >> 19; + voodoo->banshee_blt.ly[1] = ((int32_t)(data << 3)) >> 19; + voodoo->banshee_blt.dx[0] = ABS(voodoo->banshee_blt.lx[1] - voodoo->banshee_blt.lx[0]); + voodoo->banshee_blt.dy[0] = ABS(voodoo->banshee_blt.ly[1] - voodoo->banshee_blt.ly[0]); + voodoo->banshee_blt.x_inc[0] = (voodoo->banshee_blt.lx[1] > voodoo->banshee_blt.lx[0]) ? 1 : -1; + voodoo->banshee_blt.error[0] = voodoo->banshee_blt.dy[0] / 2; + } else { + voodoo->banshee_blt.rx[1] = ((int32_t)(data << 19)) >> 19; + voodoo->banshee_blt.ry[1] = ((int32_t)(data << 3)) >> 19; + voodoo->banshee_blt.dx[1] = ABS(voodoo->banshee_blt.rx[1] - voodoo->banshee_blt.rx[0]); + voodoo->banshee_blt.dy[1] = ABS(voodoo->banshee_blt.ry[1] - voodoo->banshee_blt.ry[0]); + voodoo->banshee_blt.x_inc[1] = (voodoo->banshee_blt.rx[1] > voodoo->banshee_blt.rx[0]) ? 1 : -1; + voodoo->banshee_blt.error[1] = voodoo->banshee_blt.dy[1] / 2; + } -/* pclog(" verts now : %03i,%03i %03i,%03i\n", voodoo->banshee_blt.lx[0], voodoo->banshee_blt.ly[0], voodoo->banshee_blt.rx[0], voodoo->banshee_blt.ry[0]); - pclog(" %03i,%03i %03i,%03i\n", voodoo->banshee_blt.lx[1], voodoo->banshee_blt.ly[1], voodoo->banshee_blt.rx[1], voodoo->banshee_blt.ry[1]); - pclog(" left dx=%i dy=%i x_inc=%i error=%i\n", voodoo->banshee_blt.dx[0],voodoo->banshee_blt.dy[0],voodoo->banshee_blt.x_inc[0],voodoo->banshee_blt.error[0]); - pclog(" right dx=%i dy=%i x_inc=%i error=%i\n", voodoo->banshee_blt.dx[1],voodoo->banshee_blt.dy[1],voodoo->banshee_blt.x_inc[1],voodoo->banshee_blt.error[1]);*/ - y_end = MIN(voodoo->banshee_blt.ly[1], voodoo->banshee_blt.ry[1]); -// pclog("Polyfill : draw spans from %i-%i\n", y, y_end); - for (; y < y_end; y++) { -// pclog(" %i: %i %i\n", y, voodoo->banshee_blt.lx_cur, voodoo->banshee_blt.rx_cur); - /*Draw span from lx_cur to rx_cur*/ - if (y >= clip->y_min && y < clip->y_max) { - int pat_y = (voodoo->banshee_blt.commandExtra & CMDEXTRA_FORCE_PAT_ROW0) ? 0 : (voodoo->banshee_blt.patoff_y + y); - uint8_t pattern_mask = pattern_mono[pat_y & 7]; - int x; + /* pclog(" verts now : %03i,%03i %03i,%03i\n", voodoo->banshee_blt.lx[0], voodoo->banshee_blt.ly[0], + voodoo->banshee_blt.rx[0], voodoo->banshee_blt.ry[0]); pclog(" %03i,%03i %03i,%03i\n", + voodoo->banshee_blt.lx[1], voodoo->banshee_blt.ly[1], voodoo->banshee_blt.rx[1], voodoo->banshee_blt.ry[1]); pclog(" + left dx=%i dy=%i x_inc=%i error=%i\n", + voodoo->banshee_blt.dx[0],voodoo->banshee_blt.dy[0],voodoo->banshee_blt.x_inc[0],voodoo->banshee_blt.error[0]); + pclog(" right dx=%i dy=%i x_inc=%i error=%i\n", + voodoo->banshee_blt.dx[1],voodoo->banshee_blt.dy[1],voodoo->banshee_blt.x_inc[1],voodoo->banshee_blt.error[1]);*/ + y_end = MIN(voodoo->banshee_blt.ly[1], voodoo->banshee_blt.ry[1]); + // pclog("Polyfill : draw spans from %i-%i\n", y, y_end); + for (; y < y_end; y++) { + // pclog(" %i: %i %i\n", y, voodoo->banshee_blt.lx_cur, voodoo->banshee_blt.rx_cur); + /*Draw span from lx_cur to rx_cur*/ + if (y >= clip->y_min && y < clip->y_max) { + int pat_y = (voodoo->banshee_blt.commandExtra & CMDEXTRA_FORCE_PAT_ROW0) + ? 0 + : (voodoo->banshee_blt.patoff_y + y); + uint8_t pattern_mask = pattern_mono[pat_y & 7]; + int x; - for (x = voodoo->banshee_blt.lx_cur; x < voodoo->banshee_blt.rx_cur; x++) { - int pat_x = voodoo->banshee_blt.patoff_x + x; - int pattern_trans = use_pattern_trans ? (pattern_mask & (1 << (7 - (pat_x & 7)))) : 1; + for (x = voodoo->banshee_blt.lx_cur; x < voodoo->banshee_blt.rx_cur; x++) { + int pat_x = voodoo->banshee_blt.patoff_x + x; + int pattern_trans = use_pattern_trans ? (pattern_mask & (1 << (7 - (pat_x & 7)))) : 1; - if (x >= clip->x_min && x < clip->x_max && pattern_trans) - PLOT(voodoo, x, y, pat_x, pat_y, pattern_mask, rop, voodoo->banshee_blt.colorFore, COLORKEY_32); - } - } + if (x >= clip->x_min && x < clip->x_max && pattern_trans) + PLOT(voodoo, x, y, pat_x, pat_y, pattern_mask, rop, voodoo->banshee_blt.colorFore, + COLORKEY_32); + } + } - voodoo->banshee_blt.error[0] -= voodoo->banshee_blt.dx[0]; - while (voodoo->banshee_blt.error[0] < 0) { - voodoo->banshee_blt.error[0] += voodoo->banshee_blt.dy[0]; - voodoo->banshee_blt.lx_cur += voodoo->banshee_blt.x_inc[0]; - } - voodoo->banshee_blt.error[1] -= voodoo->banshee_blt.dx[1]; - while (voodoo->banshee_blt.error[1] < 0) { - voodoo->banshee_blt.error[1] += voodoo->banshee_blt.dy[1]; - voodoo->banshee_blt.rx_cur += voodoo->banshee_blt.x_inc[1]; - } - } + voodoo->banshee_blt.error[0] -= voodoo->banshee_blt.dx[0]; + while (voodoo->banshee_blt.error[0] < 0) { + voodoo->banshee_blt.error[0] += voodoo->banshee_blt.dy[0]; + voodoo->banshee_blt.lx_cur += voodoo->banshee_blt.x_inc[0]; + } + voodoo->banshee_blt.error[1] -= voodoo->banshee_blt.dx[1]; + while (voodoo->banshee_blt.error[1] < 0) { + voodoo->banshee_blt.error[1] += voodoo->banshee_blt.dy[1]; + voodoo->banshee_blt.rx_cur += voodoo->banshee_blt.x_inc[1]; + } + } - if (voodoo->banshee_blt.ry[1] == voodoo->banshee_blt.ly[1]) { - voodoo->banshee_blt.lx[0] = voodoo->banshee_blt.lx[1]; - voodoo->banshee_blt.ly[0] = voodoo->banshee_blt.ly[1]; - voodoo->banshee_blt.rx[0] = voodoo->banshee_blt.rx[1]; - voodoo->banshee_blt.ry[0] = voodoo->banshee_blt.ry[1]; - } else if (voodoo->banshee_blt.ry[1] >= voodoo->banshee_blt.ly[1]) { - voodoo->banshee_blt.lx[0] = voodoo->banshee_blt.lx[1]; - voodoo->banshee_blt.ly[0] = voodoo->banshee_blt.ly[1]; - } else { - voodoo->banshee_blt.rx[0] = voodoo->banshee_blt.rx[1]; - voodoo->banshee_blt.ry[0] = voodoo->banshee_blt.ry[1]; - } + if (voodoo->banshee_blt.ry[1] == voodoo->banshee_blt.ly[1]) { + voodoo->banshee_blt.lx[0] = voodoo->banshee_blt.lx[1]; + voodoo->banshee_blt.ly[0] = voodoo->banshee_blt.ly[1]; + voodoo->banshee_blt.rx[0] = voodoo->banshee_blt.rx[1]; + voodoo->banshee_blt.ry[0] = voodoo->banshee_blt.ry[1]; + } else if (voodoo->banshee_blt.ry[1] >= voodoo->banshee_blt.ly[1]) { + voodoo->banshee_blt.lx[0] = voodoo->banshee_blt.lx[1]; + voodoo->banshee_blt.ly[0] = voodoo->banshee_blt.ly[1]; + } else { + voodoo->banshee_blt.rx[0] = voodoo->banshee_blt.rx[1]; + voodoo->banshee_blt.ry[0] = voodoo->banshee_blt.ry[1]; + } } static void banshee_do_2d_blit(voodoo_t *voodoo, int count, uint32_t data) { - switch (voodoo->banshee_blt.command & COMMAND_CMD_MASK) { - case COMMAND_CMD_NOP:break; + switch (voodoo->banshee_blt.command & COMMAND_CMD_MASK) { + case COMMAND_CMD_NOP: + break; - case COMMAND_CMD_SCREEN_TO_SCREEN_BLT:banshee_do_screen_to_screen_blt(voodoo); - break; + case COMMAND_CMD_SCREEN_TO_SCREEN_BLT: + banshee_do_screen_to_screen_blt(voodoo); + break; - case COMMAND_CMD_SCREEN_TO_SCREEN_STRETCH_BLT:banshee_do_screen_to_screen_stretch_blt(voodoo); - break; + case COMMAND_CMD_SCREEN_TO_SCREEN_STRETCH_BLT: + banshee_do_screen_to_screen_stretch_blt(voodoo); + break; - case COMMAND_CMD_HOST_TO_SCREEN_BLT:banshee_do_host_to_screen_blt(voodoo, count, data); - break; + case COMMAND_CMD_HOST_TO_SCREEN_BLT: + banshee_do_host_to_screen_blt(voodoo, count, data); + break; - case COMMAND_CMD_HOST_TO_SCREEN_STRETCH_BLT:banshee_do_host_to_screen_stretch_blt(voodoo, count, data); - break; + case COMMAND_CMD_HOST_TO_SCREEN_STRETCH_BLT: + banshee_do_host_to_screen_stretch_blt(voodoo, count, data); + break; - case COMMAND_CMD_RECTFILL:banshee_do_rectfill(voodoo); - break; + case COMMAND_CMD_RECTFILL: + banshee_do_rectfill(voodoo); + break; - case COMMAND_CMD_LINE:banshee_do_line(voodoo, 1); - break; + case COMMAND_CMD_LINE: + banshee_do_line(voodoo, 1); + break; - case COMMAND_CMD_POLYLINE:banshee_do_line(voodoo, 0); - break; + case COMMAND_CMD_POLYLINE: + banshee_do_line(voodoo, 0); + break; #ifndef RELEASE_BUILD - default:fatal("banshee_do_2d_blit: unknown command=%08x\n", voodoo->banshee_blt.command); + default: + fatal("banshee_do_2d_blit: unknown command=%08x\n", voodoo->banshee_blt.command); #endif - } + } } void voodoo_2d_reg_writel(voodoo_t *voodoo, uint32_t addr, uint32_t val) { -// /*if ((addr & 0x1fc) != 0x80) */pclog("2D reg write %03x %08x\n", addr & 0x1fc, val); - switch (addr & 0x1fc) { - case 0x08:voodoo->banshee_blt.clip0Min = val; - voodoo->banshee_blt.clip[0].x_min = val & 0xfff; - voodoo->banshee_blt.clip[0].y_min = (val >> 16) & 0xfff; - break; - case 0x0c:voodoo->banshee_blt.clip0Max = val; - voodoo->banshee_blt.clip[0].x_max = val & 0xfff; - voodoo->banshee_blt.clip[0].y_max = (val >> 16) & 0xfff; - break; - case 0x10:voodoo->banshee_blt.dstBaseAddr = val & 0xffffff; - voodoo->banshee_blt.dstBaseAddr_tiled = val & 0x80000000; - if (voodoo->banshee_blt.dstBaseAddr_tiled) - voodoo->banshee_blt.dst_stride = (voodoo->banshee_blt.dstFormat & DST_FORMAT_STRIDE_MASK) * 128 * 32; - else - voodoo->banshee_blt.dst_stride = voodoo->banshee_blt.dstFormat & DST_FORMAT_STRIDE_MASK; -// pclog("dstBaseAddr=%08x\n", val); - break; - case 0x14:voodoo->banshee_blt.dstFormat = val; - if (voodoo->banshee_blt.dstBaseAddr_tiled) - voodoo->banshee_blt.dst_stride = (voodoo->banshee_blt.dstFormat & DST_FORMAT_STRIDE_MASK) * 128 * 32; - else - voodoo->banshee_blt.dst_stride = voodoo->banshee_blt.dstFormat & DST_FORMAT_STRIDE_MASK; -// pclog("dstFormat=%08x\n", val); - break; + // /*if ((addr & 0x1fc) != 0x80) */pclog("2D reg write %03x %08x\n", addr & 0x1fc, val); + switch (addr & 0x1fc) { + case 0x08: + voodoo->banshee_blt.clip0Min = val; + voodoo->banshee_blt.clip[0].x_min = val & 0xfff; + voodoo->banshee_blt.clip[0].y_min = (val >> 16) & 0xfff; + break; + case 0x0c: + voodoo->banshee_blt.clip0Max = val; + voodoo->banshee_blt.clip[0].x_max = val & 0xfff; + voodoo->banshee_blt.clip[0].y_max = (val >> 16) & 0xfff; + break; + case 0x10: + voodoo->banshee_blt.dstBaseAddr = val & 0xffffff; + voodoo->banshee_blt.dstBaseAddr_tiled = val & 0x80000000; + if (voodoo->banshee_blt.dstBaseAddr_tiled) + voodoo->banshee_blt.dst_stride = (voodoo->banshee_blt.dstFormat & DST_FORMAT_STRIDE_MASK) * 128 * 32; + else + voodoo->banshee_blt.dst_stride = voodoo->banshee_blt.dstFormat & DST_FORMAT_STRIDE_MASK; + // pclog("dstBaseAddr=%08x\n", val); + break; + case 0x14: + voodoo->banshee_blt.dstFormat = val; + if (voodoo->banshee_blt.dstBaseAddr_tiled) + voodoo->banshee_blt.dst_stride = (voodoo->banshee_blt.dstFormat & DST_FORMAT_STRIDE_MASK) * 128 * 32; + else + voodoo->banshee_blt.dst_stride = voodoo->banshee_blt.dstFormat & DST_FORMAT_STRIDE_MASK; + // pclog("dstFormat=%08x\n", val); + break; - case 0x18:voodoo->banshee_blt.srcColorkeyMin = val & 0xffffff; - break; - case 0x1c:voodoo->banshee_blt.srcColorkeyMax = val & 0xffffff; - break; - case 0x20:voodoo->banshee_blt.dstColorkeyMin = val & 0xffffff; - break; - case 0x24:voodoo->banshee_blt.dstColorkeyMax = val & 0xffffff; - break; + case 0x18: + voodoo->banshee_blt.srcColorkeyMin = val & 0xffffff; + break; + case 0x1c: + voodoo->banshee_blt.srcColorkeyMax = val & 0xffffff; + break; + case 0x20: + voodoo->banshee_blt.dstColorkeyMin = val & 0xffffff; + break; + case 0x24: + voodoo->banshee_blt.dstColorkeyMax = val & 0xffffff; + break; - case 0x28:voodoo->banshee_blt.bresError0 = val; - voodoo->banshee_blt.bres_error_0 = val & 0xffff; - break; - case 0x2c:voodoo->banshee_blt.bresError1 = val; - voodoo->banshee_blt.bres_error_1 = val & 0xffff; - break; + case 0x28: + voodoo->banshee_blt.bresError0 = val; + voodoo->banshee_blt.bres_error_0 = val & 0xffff; + break; + case 0x2c: + voodoo->banshee_blt.bresError1 = val; + voodoo->banshee_blt.bres_error_1 = val & 0xffff; + break; - case 0x30:voodoo->banshee_blt.rop = val; - voodoo->banshee_blt.rops[1] = val & 0xff; - voodoo->banshee_blt.rops[2] = (val >> 8) & 0xff; - voodoo->banshee_blt.rops[3] = (val >> 16) & 0xff; -// pclog("rop=%08x\n", val); - break; - case 0x34:voodoo->banshee_blt.srcBaseAddr = val & 0xffffff; - voodoo->banshee_blt.srcBaseAddr_tiled = val & 0x80000000; - if (voodoo->banshee_blt.srcBaseAddr_tiled) - voodoo->banshee_blt.src_stride = (voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK) * 128 * 32; - else - voodoo->banshee_blt.src_stride = voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK; - update_src_stride(voodoo); -// pclog("srcBaseAddr=%08x\n", val); - break; - case 0x38:voodoo->banshee_blt.commandExtra = val; -// pclog("commandExtra=%08x\n", val); - break; - case 0x3c:voodoo->banshee_blt.lineStipple = val; - break; - case 0x40:voodoo->banshee_blt.lineStyle = val; - voodoo->banshee_blt.line_rep_cnt = val & 0xff; - voodoo->banshee_blt.line_bit_mask_size = (val >> 8) & 0x1f; - voodoo->banshee_blt.line_pix_pos = (val >> 16) & 0xff; - voodoo->banshee_blt.line_bit_pos = (val >> 24) & 0x1f; - break; - case 0x44:voodoo->banshee_blt.colorPattern[0] = val; -// pclog("colorPattern0=%08x\n", val); - voodoo->banshee_blt.colorPattern24[0] = val & 0xffffff; - voodoo->banshee_blt.colorPattern24[1] = (voodoo->banshee_blt.colorPattern24[1] & 0xffff00) | (val >> 24); - voodoo->banshee_blt.colorPattern16[0] = val & 0xffff; - voodoo->banshee_blt.colorPattern16[1] = (val >> 16) & 0xffff; - voodoo->banshee_blt.colorPattern8[0] = val & 0xff; - voodoo->banshee_blt.colorPattern8[1] = (val >> 8) & 0xff; - voodoo->banshee_blt.colorPattern8[2] = (val >> 16) & 0xff; - voodoo->banshee_blt.colorPattern8[3] = (val >> 24) & 0xff; - break; - case 0x48:voodoo->banshee_blt.colorPattern[1] = val; -// pclog("colorPattern1=%08x\n", val); - voodoo->banshee_blt.colorPattern24[1] = (voodoo->banshee_blt.colorPattern24[1] & 0xff) | ((val & 0xffff) << 8); - voodoo->banshee_blt.colorPattern24[2] = (voodoo->banshee_blt.colorPattern24[2] & 0xff0000) | (val >> 16); - voodoo->banshee_blt.colorPattern16[2] = val & 0xffff; - voodoo->banshee_blt.colorPattern16[3] = (val >> 16) & 0xffff; - voodoo->banshee_blt.colorPattern8[4] = val & 0xff; - voodoo->banshee_blt.colorPattern8[5] = (val >> 8) & 0xff; - voodoo->banshee_blt.colorPattern8[6] = (val >> 16) & 0xff; - voodoo->banshee_blt.colorPattern8[7] = (val >> 24) & 0xff; - break; - case 0x4c:voodoo->banshee_blt.clip1Min = val; - voodoo->banshee_blt.clip[1].x_min = val & 0xfff; - voodoo->banshee_blt.clip[1].y_min = (val >> 16) & 0xfff; - break; - case 0x50:voodoo->banshee_blt.clip1Max = val; - voodoo->banshee_blt.clip[1].x_max = val & 0xfff; - voodoo->banshee_blt.clip[1].y_max = (val >> 16) & 0xfff; - break; - case 0x54:voodoo->banshee_blt.srcFormat = val; - if (voodoo->banshee_blt.srcBaseAddr_tiled) - voodoo->banshee_blt.src_stride = (voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK) * 128 * 32; - else - voodoo->banshee_blt.src_stride = voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK; - update_src_stride(voodoo); - switch (voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) { - case SRC_FORMAT_COL_1_BPP:voodoo->banshee_blt.src_bpp = 1; - break; - case SRC_FORMAT_COL_8_BPP:voodoo->banshee_blt.src_bpp = 8; - break; - case SRC_FORMAT_COL_24_BPP:voodoo->banshee_blt.src_bpp = 24; - break; - case SRC_FORMAT_COL_32_BPP:voodoo->banshee_blt.src_bpp = 32; - break; - case SRC_FORMAT_COL_16_BPP: - default:voodoo->banshee_blt.src_bpp = 16; - break; - } -// pclog("srcFormat=%08x\n", val); - break; - case 0x58:voodoo->banshee_blt.srcSize = val; - voodoo->banshee_blt.srcSizeX = voodoo->banshee_blt.srcSize & 0x1fff; - voodoo->banshee_blt.srcSizeY = (voodoo->banshee_blt.srcSize >> 16) & 0x1fff; - update_src_stride(voodoo); -// pclog("srcSize=%08x\n", val); - break; - case 0x5c:voodoo->banshee_blt.srcXY = val; - voodoo->banshee_blt.srcX = ((int32_t)(val << 19)) >> 19; - voodoo->banshee_blt.srcY = ((int32_t)(val << 3)) >> 19; - update_src_stride(voodoo); -// pclog("srcXY=%08x\n", val); - break; - case 0x60:voodoo->banshee_blt.colorBack = val; - break; - case 0x64:voodoo->banshee_blt.colorFore = val; - break; - case 0x68:voodoo->banshee_blt.dstSize = val; - voodoo->banshee_blt.dstSizeX = voodoo->banshee_blt.dstSize & 0x1fff; - voodoo->banshee_blt.dstSizeY = (voodoo->banshee_blt.dstSize >> 16) & 0x1fff; - update_src_stride(voodoo); -// pclog("dstSize=%08x\n", val); - break; - case 0x6c:voodoo->banshee_blt.dstXY = val; - voodoo->banshee_blt.dstX = ((int32_t)(val << 19)) >> 19; - voodoo->banshee_blt.dstY = ((int32_t)(val << 3)) >> 19; -// pclog("dstXY=%08x\n", val); - break; - case 0x70:voodoo_wait_for_render_thread_idle(voodoo); - voodoo->banshee_blt.command = val; - voodoo->banshee_blt.rops[0] = val >> 24; -// pclog("command=%x %08x\n", voodoo->banshee_blt.command & COMMAND_CMD_MASK, val); - voodoo->banshee_blt.patoff_x = (val & COMMAND_PATOFF_X_MASK) >> COMMAND_PATOFF_X_SHIFT; - voodoo->banshee_blt.patoff_y = (val & COMMAND_PATOFF_Y_MASK) >> COMMAND_PATOFF_Y_SHIFT; - voodoo->banshee_blt.cur_x = 0; - voodoo->banshee_blt.cur_y = 0; - voodoo->banshee_blt.dstX = ((int32_t)(voodoo->banshee_blt.dstXY << 19)) >> 19; - voodoo->banshee_blt.dstY = ((int32_t)(voodoo->banshee_blt.dstXY << 3)) >> 19; - voodoo->banshee_blt.srcX = ((int32_t)(voodoo->banshee_blt.srcXY << 19)) >> 19; - voodoo->banshee_blt.srcY = ((int32_t)(voodoo->banshee_blt.srcXY << 3)) >> 19; - voodoo->banshee_blt.old_srcX = voodoo->banshee_blt.srcX; - voodoo->banshee_blt.host_data_remainder = 0; - voodoo->banshee_blt.host_data_count = 0; - switch (voodoo->banshee_blt.command & COMMAND_CMD_MASK) { -/* case COMMAND_CMD_SCREEN_TO_SCREEN_STRETCH_BLT: - if (voodoo->banshee_blt.bresError0 & BRES_ERROR_USE) - voodoo->banshee_blt.bres_error_0 = (int32_t)(int16_t)(voodoo->banshee_blt.bresError0 & BRES_ERROR_MASK); - else - voodoo->banshee_blt.bres_error_0 = voodoo->banshee_blt.dstSizeY / 2; - if (voodoo->banshee_blt.bresError1 & BRES_ERROR_USE) - voodoo->banshee_blt.bres_error_1 = (int32_t)(int16_t)(voodoo->banshee_blt.bresError1 & BRES_ERROR_MASK); - else - voodoo->banshee_blt.bres_error_1 = voodoo->banshee_blt.dstSizeX / 2; + case 0x30: + voodoo->banshee_blt.rop = val; + voodoo->banshee_blt.rops[1] = val & 0xff; + voodoo->banshee_blt.rops[2] = (val >> 8) & 0xff; + voodoo->banshee_blt.rops[3] = (val >> 16) & 0xff; + // pclog("rop=%08x\n", val); + break; + case 0x34: + voodoo->banshee_blt.srcBaseAddr = val & 0xffffff; + voodoo->banshee_blt.srcBaseAddr_tiled = val & 0x80000000; + if (voodoo->banshee_blt.srcBaseAddr_tiled) + voodoo->banshee_blt.src_stride = (voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK) * 128 * 32; + else + voodoo->banshee_blt.src_stride = voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK; + update_src_stride(voodoo); + // pclog("srcBaseAddr=%08x\n", val); + break; + case 0x38: + voodoo->banshee_blt.commandExtra = val; + // pclog("commandExtra=%08x\n", val); + break; + case 0x3c: + voodoo->banshee_blt.lineStipple = val; + break; + case 0x40: + voodoo->banshee_blt.lineStyle = val; + voodoo->banshee_blt.line_rep_cnt = val & 0xff; + voodoo->banshee_blt.line_bit_mask_size = (val >> 8) & 0x1f; + voodoo->banshee_blt.line_pix_pos = (val >> 16) & 0xff; + voodoo->banshee_blt.line_bit_pos = (val >> 24) & 0x1f; + break; + case 0x44: + voodoo->banshee_blt.colorPattern[0] = val; + // pclog("colorPattern0=%08x\n", val); + voodoo->banshee_blt.colorPattern24[0] = val & 0xffffff; + voodoo->banshee_blt.colorPattern24[1] = (voodoo->banshee_blt.colorPattern24[1] & 0xffff00) | (val >> 24); + voodoo->banshee_blt.colorPattern16[0] = val & 0xffff; + voodoo->banshee_blt.colorPattern16[1] = (val >> 16) & 0xffff; + voodoo->banshee_blt.colorPattern8[0] = val & 0xff; + voodoo->banshee_blt.colorPattern8[1] = (val >> 8) & 0xff; + voodoo->banshee_blt.colorPattern8[2] = (val >> 16) & 0xff; + voodoo->banshee_blt.colorPattern8[3] = (val >> 24) & 0xff; + break; + case 0x48: + voodoo->banshee_blt.colorPattern[1] = val; + // pclog("colorPattern1=%08x\n", val); + voodoo->banshee_blt.colorPattern24[1] = (voodoo->banshee_blt.colorPattern24[1] & 0xff) | ((val & 0xffff) << 8); + voodoo->banshee_blt.colorPattern24[2] = (voodoo->banshee_blt.colorPattern24[2] & 0xff0000) | (val >> 16); + voodoo->banshee_blt.colorPattern16[2] = val & 0xffff; + voodoo->banshee_blt.colorPattern16[3] = (val >> 16) & 0xffff; + voodoo->banshee_blt.colorPattern8[4] = val & 0xff; + voodoo->banshee_blt.colorPattern8[5] = (val >> 8) & 0xff; + voodoo->banshee_blt.colorPattern8[6] = (val >> 16) & 0xff; + voodoo->banshee_blt.colorPattern8[7] = (val >> 24) & 0xff; + break; + case 0x4c: + voodoo->banshee_blt.clip1Min = val; + voodoo->banshee_blt.clip[1].x_min = val & 0xfff; + voodoo->banshee_blt.clip[1].y_min = (val >> 16) & 0xfff; + break; + case 0x50: + voodoo->banshee_blt.clip1Max = val; + voodoo->banshee_blt.clip[1].x_max = val & 0xfff; + voodoo->banshee_blt.clip[1].y_max = (val >> 16) & 0xfff; + break; + case 0x54: + voodoo->banshee_blt.srcFormat = val; + if (voodoo->banshee_blt.srcBaseAddr_tiled) + voodoo->banshee_blt.src_stride = (voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK) * 128 * 32; + else + voodoo->banshee_blt.src_stride = voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK; + update_src_stride(voodoo); + switch (voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) { + case SRC_FORMAT_COL_1_BPP: + voodoo->banshee_blt.src_bpp = 1; + break; + case SRC_FORMAT_COL_8_BPP: + voodoo->banshee_blt.src_bpp = 8; + break; + case SRC_FORMAT_COL_24_BPP: + voodoo->banshee_blt.src_bpp = 24; + break; + case SRC_FORMAT_COL_32_BPP: + voodoo->banshee_blt.src_bpp = 32; + break; + case SRC_FORMAT_COL_16_BPP: + default: + voodoo->banshee_blt.src_bpp = 16; + break; + } + // pclog("srcFormat=%08x\n", val); + break; + case 0x58: + voodoo->banshee_blt.srcSize = val; + voodoo->banshee_blt.srcSizeX = voodoo->banshee_blt.srcSize & 0x1fff; + voodoo->banshee_blt.srcSizeY = (voodoo->banshee_blt.srcSize >> 16) & 0x1fff; + update_src_stride(voodoo); + // pclog("srcSize=%08x\n", val); + break; + case 0x5c: + voodoo->banshee_blt.srcXY = val; + voodoo->banshee_blt.srcX = ((int32_t)(val << 19)) >> 19; + voodoo->banshee_blt.srcY = ((int32_t)(val << 3)) >> 19; + update_src_stride(voodoo); + // pclog("srcXY=%08x\n", val); + break; + case 0x60: + voodoo->banshee_blt.colorBack = val; + break; + case 0x64: + voodoo->banshee_blt.colorFore = val; + break; + case 0x68: + voodoo->banshee_blt.dstSize = val; + voodoo->banshee_blt.dstSizeX = voodoo->banshee_blt.dstSize & 0x1fff; + voodoo->banshee_blt.dstSizeY = (voodoo->banshee_blt.dstSize >> 16) & 0x1fff; + update_src_stride(voodoo); + // pclog("dstSize=%08x\n", val); + break; + case 0x6c: + voodoo->banshee_blt.dstXY = val; + voodoo->banshee_blt.dstX = ((int32_t)(val << 19)) >> 19; + voodoo->banshee_blt.dstY = ((int32_t)(val << 3)) >> 19; + // pclog("dstXY=%08x\n", val); + break; + case 0x70: + voodoo_wait_for_render_thread_idle(voodoo); + voodoo->banshee_blt.command = val; + voodoo->banshee_blt.rops[0] = val >> 24; + // pclog("command=%x %08x\n", voodoo->banshee_blt.command & COMMAND_CMD_MASK, val); + voodoo->banshee_blt.patoff_x = (val & COMMAND_PATOFF_X_MASK) >> COMMAND_PATOFF_X_SHIFT; + voodoo->banshee_blt.patoff_y = (val & COMMAND_PATOFF_Y_MASK) >> COMMAND_PATOFF_Y_SHIFT; + voodoo->banshee_blt.cur_x = 0; + voodoo->banshee_blt.cur_y = 0; + voodoo->banshee_blt.dstX = ((int32_t)(voodoo->banshee_blt.dstXY << 19)) >> 19; + voodoo->banshee_blt.dstY = ((int32_t)(voodoo->banshee_blt.dstXY << 3)) >> 19; + voodoo->banshee_blt.srcX = ((int32_t)(voodoo->banshee_blt.srcXY << 19)) >> 19; + voodoo->banshee_blt.srcY = ((int32_t)(voodoo->banshee_blt.srcXY << 3)) >> 19; + voodoo->banshee_blt.old_srcX = voodoo->banshee_blt.srcX; + voodoo->banshee_blt.host_data_remainder = 0; + voodoo->banshee_blt.host_data_count = 0; + switch (voodoo->banshee_blt.command & COMMAND_CMD_MASK) { + /* case COMMAND_CMD_SCREEN_TO_SCREEN_STRETCH_BLT: + if (voodoo->banshee_blt.bresError0 & BRES_ERROR_USE) + voodoo->banshee_blt.bres_error_0 = + (int32_t)(int16_t)(voodoo->banshee_blt.bresError0 & BRES_ERROR_MASK); else + voodoo->banshee_blt.bres_error_0 = voodoo->banshee_blt.dstSizeY / 2; + if (voodoo->banshee_blt.bresError1 & BRES_ERROR_USE) + voodoo->banshee_blt.bres_error_1 = + (int32_t)(int16_t)(voodoo->banshee_blt.bresError1 & BRES_ERROR_MASK); else + voodoo->banshee_blt.bres_error_1 = voodoo->banshee_blt.dstSizeX / 2; - if (val & COMMAND_INITIATE) + if (val & COMMAND_INITIATE) + banshee_do_2d_blit(voodoo, -1, 0); + break;*/ + + case COMMAND_CMD_POLYFILL: + if (val & COMMAND_INITIATE) { + voodoo->banshee_blt.dstXY = voodoo->banshee_blt.srcXY; + voodoo->banshee_blt.dstX = voodoo->banshee_blt.srcX; + voodoo->banshee_blt.dstY = voodoo->banshee_blt.srcY; + } + banshee_polyfill_start(voodoo); + break; + + default: + if (val & COMMAND_INITIATE) { banshee_do_2d_blit(voodoo, -1, 0); - break;*/ + // fatal("Initiate command!\n"); + } + break; + } + break; - case COMMAND_CMD_POLYFILL: - if (val & COMMAND_INITIATE) { - voodoo->banshee_blt.dstXY = voodoo->banshee_blt.srcXY; - voodoo->banshee_blt.dstX = voodoo->banshee_blt.srcX; - voodoo->banshee_blt.dstY = voodoo->banshee_blt.srcY; - } - banshee_polyfill_start(voodoo); - break; + case 0x80: + case 0x84: + case 0x88: + case 0x8c: + case 0x90: + case 0x94: + case 0x98: + case 0x9c: + case 0xa0: + case 0xa4: + case 0xa8: + case 0xac: + case 0xb0: + case 0xb4: + case 0xb8: + case 0xbc: + case 0xc0: + case 0xc4: + case 0xc8: + case 0xcc: + case 0xd0: + case 0xd4: + case 0xd8: + case 0xdc: + case 0xe0: + case 0xe4: + case 0xe8: + case 0xec: + case 0xf0: + case 0xf4: + case 0xf8: + case 0xfc: + // pclog("launch %08x %08x %08x %08x\n", voodoo->banshee_blt.command, + // voodoo->banshee_blt.commandExtra, voodoo->banshee_blt.srcColorkeyMin, + // voodoo->banshee_blt.srcColorkeyMax); + switch (voodoo->banshee_blt.command & COMMAND_CMD_MASK) { + case COMMAND_CMD_SCREEN_TO_SCREEN_BLT: + voodoo->banshee_blt.srcXY = val; + voodoo->banshee_blt.srcX = ((int32_t)(val << 19)) >> 19; + voodoo->banshee_blt.srcY = ((int32_t)(val << 3)) >> 19; + banshee_do_screen_to_screen_blt(voodoo); + break; - default: - if (val & COMMAND_INITIATE) { - banshee_do_2d_blit(voodoo, -1, 0); - // fatal("Initiate command!\n"); - } - break; - } - break; + case COMMAND_CMD_HOST_TO_SCREEN_BLT: + banshee_do_2d_blit(voodoo, 32, val); + break; - case 0x80: - case 0x84: - case 0x88: - case 0x8c: - case 0x90: - case 0x94: - case 0x98: - case 0x9c: - case 0xa0: - case 0xa4: - case 0xa8: - case 0xac: - case 0xb0: - case 0xb4: - case 0xb8: - case 0xbc: - case 0xc0: - case 0xc4: - case 0xc8: - case 0xcc: - case 0xd0: - case 0xd4: - case 0xd8: - case 0xdc: - case 0xe0: - case 0xe4: - case 0xe8: - case 0xec: - case 0xf0: - case 0xf4: - case 0xf8: - case 0xfc: -// pclog("launch %08x %08x %08x %08x\n", voodoo->banshee_blt.command, voodoo->banshee_blt.commandExtra, voodoo->banshee_blt.srcColorkeyMin, voodoo->banshee_blt.srcColorkeyMax); - switch (voodoo->banshee_blt.command & COMMAND_CMD_MASK) { - case COMMAND_CMD_SCREEN_TO_SCREEN_BLT:voodoo->banshee_blt.srcXY = val; - voodoo->banshee_blt.srcX = ((int32_t)(val << 19)) >> 19; - voodoo->banshee_blt.srcY = ((int32_t)(val << 3)) >> 19; - banshee_do_screen_to_screen_blt(voodoo); - break; + case COMMAND_CMD_HOST_TO_SCREEN_STRETCH_BLT: + banshee_do_2d_blit(voodoo, 32, val); + break; - case COMMAND_CMD_HOST_TO_SCREEN_BLT:banshee_do_2d_blit(voodoo, 32, val); - break; + case COMMAND_CMD_RECTFILL: + voodoo->banshee_blt.dstXY = val; + voodoo->banshee_blt.dstX = ((int32_t)(val << 19)) >> 19; + voodoo->banshee_blt.dstY = ((int32_t)(val << 3)) >> 19; + banshee_do_rectfill(voodoo); + break; - case COMMAND_CMD_HOST_TO_SCREEN_STRETCH_BLT:banshee_do_2d_blit(voodoo, 32, val); - break; + case COMMAND_CMD_LINE: + voodoo->banshee_blt.dstXY = val; + voodoo->banshee_blt.dstX = ((int32_t)(val << 19)) >> 19; + voodoo->banshee_blt.dstY = ((int32_t)(val << 3)) >> 19; + banshee_do_line(voodoo, 1); + break; - case COMMAND_CMD_RECTFILL:voodoo->banshee_blt.dstXY = val; - voodoo->banshee_blt.dstX = ((int32_t)(val << 19)) >> 19; - voodoo->banshee_blt.dstY = ((int32_t)(val << 3)) >> 19; - banshee_do_rectfill(voodoo); - break; + case COMMAND_CMD_POLYLINE: + voodoo->banshee_blt.dstXY = val; + voodoo->banshee_blt.dstX = ((int32_t)(val << 19)) >> 19; + voodoo->banshee_blt.dstY = ((int32_t)(val << 3)) >> 19; + banshee_do_line(voodoo, 0); + break; - case COMMAND_CMD_LINE:voodoo->banshee_blt.dstXY = val; - voodoo->banshee_blt.dstX = ((int32_t)(val << 19)) >> 19; - voodoo->banshee_blt.dstY = ((int32_t)(val << 3)) >> 19; - banshee_do_line(voodoo, 1); - break; - - case COMMAND_CMD_POLYLINE:voodoo->banshee_blt.dstXY = val; - voodoo->banshee_blt.dstX = ((int32_t)(val << 19)) >> 19; - voodoo->banshee_blt.dstY = ((int32_t)(val << 3)) >> 19; - banshee_do_line(voodoo, 0); - break; - - case COMMAND_CMD_POLYFILL:banshee_polyfill_continue(voodoo, val); - break; + case COMMAND_CMD_POLYFILL: + banshee_polyfill_continue(voodoo, val); + break; #ifndef RELEASE_BUILD - default:fatal("launch area write, command=%08x\n", voodoo->banshee_blt.command); + default: + fatal("launch area write, command=%08x\n", voodoo->banshee_blt.command); #endif - } - break; + } + break; - case 0x100: - case 0x104: - case 0x108: - case 0x10c: - case 0x110: - case 0x114: - case 0x118: - case 0x11c: - case 0x120: - case 0x124: - case 0x128: - case 0x12c: - case 0x130: - case 0x134: - case 0x138: - case 0x13c: - case 0x140: - case 0x144: - case 0x148: - case 0x14c: - case 0x150: - case 0x154: - case 0x158: - case 0x15c: - case 0x160: - case 0x164: - case 0x168: - case 0x16c: - case 0x170: - case 0x174: - case 0x178: - case 0x17c: - case 0x180: - case 0x184: - case 0x188: - case 0x18c: - case 0x190: - case 0x194: - case 0x198: - case 0x19c: - case 0x1a0: - case 0x1a4: - case 0x1a8: - case 0x1ac: - case 0x1b0: - case 0x1b4: - case 0x1b8: - case 0x1bc: - case 0x1c0: - case 0x1c4: - case 0x1c8: - case 0x1cc: - case 0x1d0: - case 0x1d4: - case 0x1d8: - case 0x1dc: - case 0x1e0: - case 0x1e4: - case 0x1e8: - case 0x1ec: - case 0x1f0: - case 0x1f4: - case 0x1f8: - case 0x1fc:voodoo->banshee_blt.colorPattern[(addr >> 2) & 63] = val; - if ((addr & 0x1fc) < 0x1c0) { - int base_addr = (addr & 0xfc) / 0xc; - uintptr_t src_p = (uintptr_t)&voodoo->banshee_blt.colorPattern[base_addr * 3]; - int col24 = base_addr * 4; + case 0x100: + case 0x104: + case 0x108: + case 0x10c: + case 0x110: + case 0x114: + case 0x118: + case 0x11c: + case 0x120: + case 0x124: + case 0x128: + case 0x12c: + case 0x130: + case 0x134: + case 0x138: + case 0x13c: + case 0x140: + case 0x144: + case 0x148: + case 0x14c: + case 0x150: + case 0x154: + case 0x158: + case 0x15c: + case 0x160: + case 0x164: + case 0x168: + case 0x16c: + case 0x170: + case 0x174: + case 0x178: + case 0x17c: + case 0x180: + case 0x184: + case 0x188: + case 0x18c: + case 0x190: + case 0x194: + case 0x198: + case 0x19c: + case 0x1a0: + case 0x1a4: + case 0x1a8: + case 0x1ac: + case 0x1b0: + case 0x1b4: + case 0x1b8: + case 0x1bc: + case 0x1c0: + case 0x1c4: + case 0x1c8: + case 0x1cc: + case 0x1d0: + case 0x1d4: + case 0x1d8: + case 0x1dc: + case 0x1e0: + case 0x1e4: + case 0x1e8: + case 0x1ec: + case 0x1f0: + case 0x1f4: + case 0x1f8: + case 0x1fc: + voodoo->banshee_blt.colorPattern[(addr >> 2) & 63] = val; + if ((addr & 0x1fc) < 0x1c0) { + int base_addr = (addr & 0xfc) / 0xc; + uintptr_t src_p = (uintptr_t)&voodoo->banshee_blt.colorPattern[base_addr * 3]; + int col24 = base_addr * 4; - voodoo->banshee_blt.colorPattern24[col24] = *(uint32_t *)src_p & 0xffffff; - voodoo->banshee_blt.colorPattern24[col24 + 1] = *(uint32_t *)(src_p + 3) & 0xffffff; - voodoo->banshee_blt.colorPattern24[col24 + 2] = *(uint32_t *)(src_p + 6) & 0xffffff; - voodoo->banshee_blt.colorPattern24[col24 + 3] = *(uint32_t *)(src_p + 9) & 0xffffff; - } - if ((addr & 0x1fc) < 0x180) { - voodoo->banshee_blt.colorPattern16[(addr >> 1) & 62] = val & 0xffff; - voodoo->banshee_blt.colorPattern16[((addr >> 1) & 62) + 1] = (val >> 16) & 0xffff; - } - if ((addr & 0x1fc) < 0x140) { - voodoo->banshee_blt.colorPattern8[addr & 60] = val & 0xff; - voodoo->banshee_blt.colorPattern8[(addr & 60) + 1] = (val >> 8) & 0xff; - voodoo->banshee_blt.colorPattern8[(addr & 60) + 2] = (val >> 16) & 0xff; - voodoo->banshee_blt.colorPattern8[(addr & 60) + 3] = (val >> 24) & 0xff; - } -// pclog("colorPattern%02x=%08x\n", (addr >> 2) & 63, val); - break; + voodoo->banshee_blt.colorPattern24[col24] = *(uint32_t *)src_p & 0xffffff; + voodoo->banshee_blt.colorPattern24[col24 + 1] = *(uint32_t *)(src_p + 3) & 0xffffff; + voodoo->banshee_blt.colorPattern24[col24 + 2] = *(uint32_t *)(src_p + 6) & 0xffffff; + voodoo->banshee_blt.colorPattern24[col24 + 3] = *(uint32_t *)(src_p + 9) & 0xffffff; + } + if ((addr & 0x1fc) < 0x180) { + voodoo->banshee_blt.colorPattern16[(addr >> 1) & 62] = val & 0xffff; + voodoo->banshee_blt.colorPattern16[((addr >> 1) & 62) + 1] = (val >> 16) & 0xffff; + } + if ((addr & 0x1fc) < 0x140) { + voodoo->banshee_blt.colorPattern8[addr & 60] = val & 0xff; + voodoo->banshee_blt.colorPattern8[(addr & 60) + 1] = (val >> 8) & 0xff; + voodoo->banshee_blt.colorPattern8[(addr & 60) + 2] = (val >> 16) & 0xff; + voodoo->banshee_blt.colorPattern8[(addr & 60) + 3] = (val >> 24) & 0xff; + } + // pclog("colorPattern%02x=%08x\n", (addr >> 2) & 63, val); + break; #ifndef RELEASE_BUILD - default:fatal("Unknown 2D reg write %03x %08x\n", addr & 0x1fc, val); + default: + fatal("Unknown 2D reg write %03x %08x\n", addr & 0x1fc, val); #endif - } + } } diff --git a/src/video/vid_voodoo_blitter.c b/src/video/vid_voodoo_blitter.c index e92a9d16..68d070ff 100644 --- a/src/video/vid_voodoo_blitter.c +++ b/src/video/vid_voodoo_blitter.c @@ -14,425 +14,480 @@ #include "vid_voodoo_render.h" enum { - BLIT_COMMAND_SCREEN_TO_SCREEN = 0, - BLIT_COMMAND_CPU_TO_SCREEN = 1, - BLIT_COMMAND_RECT_FILL = 2, - BLIT_COMMAND_SGRAM_FILL = 3 + BLIT_COMMAND_SCREEN_TO_SCREEN = 0, + BLIT_COMMAND_CPU_TO_SCREEN = 1, + BLIT_COMMAND_RECT_FILL = 2, + BLIT_COMMAND_SGRAM_FILL = 3 }; enum { - BLIT_SRC_1BPP = (0 << 3), - BLIT_SRC_1BPP_BYTE_PACKED = (1 << 3), - BLIT_SRC_16BPP = (2 << 3), - BLIT_SRC_24BPP = (3 << 3), - BLIT_SRC_24BPP_DITHER_2X2 = (4 << 3), - BLIT_SRC_24BPP_DITHER_4X4 = (5 << 3) + BLIT_SRC_1BPP = (0 << 3), + BLIT_SRC_1BPP_BYTE_PACKED = (1 << 3), + BLIT_SRC_16BPP = (2 << 3), + BLIT_SRC_24BPP = (3 << 3), + BLIT_SRC_24BPP_DITHER_2X2 = (4 << 3), + BLIT_SRC_24BPP_DITHER_4X4 = (5 << 3) }; +enum { BLIT_SRC_RGB_ARGB = (0 << 6), BLIT_SRC_RGB_ABGR = (1 << 6), BLIT_SRC_RGB_RGBA = (2 << 6), BLIT_SRC_RGB_BGRA = (3 << 6) }; + enum { - BLIT_SRC_RGB_ARGB = (0 << 6), - BLIT_SRC_RGB_ABGR = (1 << 6), - BLIT_SRC_RGB_RGBA = (2 << 6), - BLIT_SRC_RGB_BGRA = (3 << 6) + BLIT_COMMAND_MASK = 7, + BLIT_SRC_FORMAT = (7 << 3), + BLIT_SRC_RGB_FORMAT = (3 << 6), + BLIT_SRC_CHROMA = (1 << 10), + BLIT_DST_CHROMA = (1 << 12), + BLIT_CLIPPING_ENABLED = (1 << 16) }; -enum { - BLIT_COMMAND_MASK = 7, - BLIT_SRC_FORMAT = (7 << 3), - BLIT_SRC_RGB_FORMAT = (3 << 6), - BLIT_SRC_CHROMA = (1 << 10), - BLIT_DST_CHROMA = (1 << 12), - BLIT_CLIPPING_ENABLED = (1 << 16) -}; +enum { BLIT_ROP_DST_PASS = (1 << 0), BLIT_ROP_SRC_PASS = (1 << 1) }; -enum { - BLIT_ROP_DST_PASS = (1 << 0), - BLIT_ROP_SRC_PASS = (1 << 1) -}; - -#define MIX(src_dat, dst_dat, rop) \ - switch (rop) \ - { \ - case 0x0: dst_dat = 0; break; \ - case 0x1: dst_dat = ~(src_dat | dst_dat); break; \ - case 0x2: dst_dat = ~src_dat & dst_dat; break; \ - case 0x3: dst_dat = ~src_dat; break; \ - case 0x4: dst_dat = src_dat & ~dst_dat; break; \ - case 0x5: dst_dat = ~dst_dat; break; \ - case 0x6: dst_dat = src_dat ^ dst_dat; break; \ - case 0x7: dst_dat = ~(src_dat & dst_dat); break; \ - case 0x8: dst_dat = src_dat & dst_dat; break; \ - case 0x9: dst_dat = ~(src_dat ^ dst_dat); break; \ - case 0xa: dst_dat = dst_dat; break; \ - case 0xb: dst_dat = ~src_dat | dst_dat; break; \ - case 0xc: dst_dat = src_dat; break; \ - case 0xd: dst_dat = src_dat | ~dst_dat; break; \ - case 0xe: dst_dat = src_dat | dst_dat; break; \ - case 0xf: dst_dat = 0xffff; break; \ +#define MIX(src_dat, dst_dat, rop) \ + switch (rop) { \ + case 0x0: \ + dst_dat = 0; \ + break; \ + case 0x1: \ + dst_dat = ~(src_dat | dst_dat); \ + break; \ + case 0x2: \ + dst_dat = ~src_dat & dst_dat; \ + break; \ + case 0x3: \ + dst_dat = ~src_dat; \ + break; \ + case 0x4: \ + dst_dat = src_dat & ~dst_dat; \ + break; \ + case 0x5: \ + dst_dat = ~dst_dat; \ + break; \ + case 0x6: \ + dst_dat = src_dat ^ dst_dat; \ + break; \ + case 0x7: \ + dst_dat = ~(src_dat & dst_dat); \ + break; \ + case 0x8: \ + dst_dat = src_dat & dst_dat; \ + break; \ + case 0x9: \ + dst_dat = ~(src_dat ^ dst_dat); \ + break; \ + case 0xa: \ + dst_dat = dst_dat; \ + break; \ + case 0xb: \ + dst_dat = ~src_dat | dst_dat; \ + break; \ + case 0xc: \ + dst_dat = src_dat; \ + break; \ + case 0xd: \ + dst_dat = src_dat | ~dst_dat; \ + break; \ + case 0xe: \ + dst_dat = src_dat | dst_dat; \ + break; \ + case 0xf: \ + dst_dat = 0xffff; \ + break; \ } void voodoo_v2_blit_start(voodoo_t *voodoo) { - uint64_t dat64; - int size_x = ABS(voodoo->bltSizeX), size_y = ABS(voodoo->bltSizeY); - int x_dir = (voodoo->bltSizeX > 0) ? 1 : -1; - int y_dir = (voodoo->bltSizeY > 0) ? 1 : -1; - int dst_x; - int src_y = voodoo->bltSrcY & 0x7ff, dst_y = voodoo->bltDstY & 0x7ff; - int src_stride = (voodoo->bltCommand & BLTCMD_SRC_TILED) ? ((voodoo->bltSrcXYStride & 0x3f) * 32 * 2) : (voodoo->bltSrcXYStride & 0xff8); - int dst_stride = (voodoo->bltCommand & BLTCMD_DST_TILED) ? ((voodoo->bltDstXYStride & 0x3f) * 32 * 2) : (voodoo->bltDstXYStride & 0xff8); - uint32_t src_base_addr = (voodoo->bltCommand & BLTCMD_SRC_TILED) ? ((voodoo->bltSrcBaseAddr & 0x3ff) << 12) : (voodoo->bltSrcBaseAddr & 0x3ffff8); - uint32_t dst_base_addr = (voodoo->bltCommand & BLTCMD_DST_TILED) ? ((voodoo->bltDstBaseAddr & 0x3ff) << 12) : (voodoo->bltDstBaseAddr & 0x3ffff8); - int x, y; + uint64_t dat64; + int size_x = ABS(voodoo->bltSizeX), size_y = ABS(voodoo->bltSizeY); + int x_dir = (voodoo->bltSizeX > 0) ? 1 : -1; + int y_dir = (voodoo->bltSizeY > 0) ? 1 : -1; + int dst_x; + int src_y = voodoo->bltSrcY & 0x7ff, dst_y = voodoo->bltDstY & 0x7ff; + int src_stride = (voodoo->bltCommand & BLTCMD_SRC_TILED) ? ((voodoo->bltSrcXYStride & 0x3f) * 32 * 2) + : (voodoo->bltSrcXYStride & 0xff8); + int dst_stride = (voodoo->bltCommand & BLTCMD_DST_TILED) ? ((voodoo->bltDstXYStride & 0x3f) * 32 * 2) + : (voodoo->bltDstXYStride & 0xff8); + uint32_t src_base_addr = (voodoo->bltCommand & BLTCMD_SRC_TILED) ? ((voodoo->bltSrcBaseAddr & 0x3ff) << 12) + : (voodoo->bltSrcBaseAddr & 0x3ffff8); + uint32_t dst_base_addr = (voodoo->bltCommand & BLTCMD_DST_TILED) ? ((voodoo->bltDstBaseAddr & 0x3ff) << 12) + : (voodoo->bltDstBaseAddr & 0x3ffff8); + int x, y; -/* pclog("blit_start: command=%08x srcX=%i srcY=%i dstX=%i dstY=%i sizeX=%i sizeY=%i color=%04x,%04x\n", - voodoo->bltCommand, voodoo->bltSrcX, voodoo->bltSrcY, voodoo->bltDstX, voodoo->bltDstY, voodoo->bltSizeX, voodoo->bltSizeY, voodoo->bltColorFg, voodoo->bltColorBg);*/ + /* pclog("blit_start: command=%08x srcX=%i srcY=%i dstX=%i dstY=%i sizeX=%i sizeY=%i color=%04x,%04x\n", + voodoo->bltCommand, voodoo->bltSrcX, voodoo->bltSrcY, voodoo->bltDstX, voodoo->bltDstY, voodoo->bltSizeX, + voodoo->bltSizeY, voodoo->bltColorFg, voodoo->bltColorBg);*/ - voodoo_wait_for_render_thread_idle(voodoo); + voodoo_wait_for_render_thread_idle(voodoo); - switch (voodoo->bltCommand & BLIT_COMMAND_MASK) { - case BLIT_COMMAND_SCREEN_TO_SCREEN: - for (y = 0; y <= size_y; y++) { - uint16_t *src = (uint16_t *)&voodoo->fb_mem[src_base_addr + src_y * src_stride]; - uint16_t *dst = (uint16_t *)&voodoo->fb_mem[dst_base_addr + dst_y * dst_stride]; - int src_x = voodoo->bltSrcX, dst_x = voodoo->bltDstX; + switch (voodoo->bltCommand & BLIT_COMMAND_MASK) { + case BLIT_COMMAND_SCREEN_TO_SCREEN: + for (y = 0; y <= size_y; y++) { + uint16_t *src = (uint16_t *)&voodoo->fb_mem[src_base_addr + src_y * src_stride]; + uint16_t *dst = (uint16_t *)&voodoo->fb_mem[dst_base_addr + dst_y * dst_stride]; + int src_x = voodoo->bltSrcX, dst_x = voodoo->bltDstX; - for (x = 0; x <= size_x; x++) { - uint16_t src_dat = src[src_x]; - uint16_t dst_dat = dst[dst_x]; - int rop = 0; + for (x = 0; x <= size_x; x++) { + uint16_t src_dat = src[src_x]; + uint16_t dst_dat = dst[dst_x]; + int rop = 0; - if (voodoo->bltCommand & BLIT_CLIPPING_ENABLED) { - if (dst_x < voodoo->bltClipLeft || dst_x >= voodoo->bltClipRight || - dst_y < voodoo->bltClipLowY || dst_y >= voodoo->bltClipHighY) - goto skip_pixel_blit; - } + if (voodoo->bltCommand & BLIT_CLIPPING_ENABLED) { + if (dst_x < voodoo->bltClipLeft || dst_x >= voodoo->bltClipRight || + dst_y < voodoo->bltClipLowY || dst_y >= voodoo->bltClipHighY) + goto skip_pixel_blit; + } - if (voodoo->bltCommand & BLIT_SRC_CHROMA) { - int r = (src_dat >> 11); - int g = (src_dat >> 5) & 0x3f; - int b = src_dat & 0x1f; + if (voodoo->bltCommand & BLIT_SRC_CHROMA) { + int r = (src_dat >> 11); + int g = (src_dat >> 5) & 0x3f; + int b = src_dat & 0x1f; - if (r >= voodoo->bltSrcChromaMinR && r <= voodoo->bltSrcChromaMaxR && - g >= voodoo->bltSrcChromaMinG && g <= voodoo->bltSrcChromaMaxG && - b >= voodoo->bltSrcChromaMinB && b <= voodoo->bltSrcChromaMaxB) - rop |= BLIT_ROP_SRC_PASS; - } - if (voodoo->bltCommand & BLIT_DST_CHROMA) { - int r = (dst_dat >> 11); - int g = (dst_dat >> 5) & 0x3f; - int b = dst_dat & 0x1f; + if (r >= voodoo->bltSrcChromaMinR && r <= voodoo->bltSrcChromaMaxR && + g >= voodoo->bltSrcChromaMinG && g <= voodoo->bltSrcChromaMaxG && + b >= voodoo->bltSrcChromaMinB && b <= voodoo->bltSrcChromaMaxB) + rop |= BLIT_ROP_SRC_PASS; + } + if (voodoo->bltCommand & BLIT_DST_CHROMA) { + int r = (dst_dat >> 11); + int g = (dst_dat >> 5) & 0x3f; + int b = dst_dat & 0x1f; - if (r >= voodoo->bltDstChromaMinR && r <= voodoo->bltDstChromaMaxR && - g >= voodoo->bltDstChromaMinG && g <= voodoo->bltDstChromaMaxG && - b >= voodoo->bltDstChromaMinB && b <= voodoo->bltDstChromaMaxB) - rop |= BLIT_ROP_DST_PASS; - } + if (r >= voodoo->bltDstChromaMinR && r <= voodoo->bltDstChromaMaxR && + g >= voodoo->bltDstChromaMinG && g <= voodoo->bltDstChromaMaxG && + b >= voodoo->bltDstChromaMinB && b <= voodoo->bltDstChromaMaxB) + rop |= BLIT_ROP_DST_PASS; + } - MIX(src_dat, dst_dat, voodoo->bltRop[rop]); + MIX(src_dat, dst_dat, voodoo->bltRop[rop]); - dst[dst_x] = dst_dat; - skip_pixel_blit: - src_x += x_dir; - dst_x += x_dir; - } + dst[dst_x] = dst_dat; + skip_pixel_blit: + src_x += x_dir; + dst_x += x_dir; + } - src_y += y_dir; - dst_y += y_dir; - } - break; + src_y += y_dir; + dst_y += y_dir; + } + break; - case BLIT_COMMAND_CPU_TO_SCREEN:voodoo->blt.dst_x = voodoo->bltDstX; - voodoo->blt.dst_y = voodoo->bltDstY; - voodoo->blt.cur_x = 0; - voodoo->blt.size_x = size_x; - voodoo->blt.size_y = size_y; - voodoo->blt.x_dir = x_dir; - voodoo->blt.y_dir = y_dir; - voodoo->blt.dst_stride = (voodoo->bltCommand & BLTCMD_DST_TILED) ? ((voodoo->bltDstXYStride & 0x3f) * 32 * 2) : (voodoo->bltDstXYStride & 0xff8); - break; + case BLIT_COMMAND_CPU_TO_SCREEN: + voodoo->blt.dst_x = voodoo->bltDstX; + voodoo->blt.dst_y = voodoo->bltDstY; + voodoo->blt.cur_x = 0; + voodoo->blt.size_x = size_x; + voodoo->blt.size_y = size_y; + voodoo->blt.x_dir = x_dir; + voodoo->blt.y_dir = y_dir; + voodoo->blt.dst_stride = (voodoo->bltCommand & BLTCMD_DST_TILED) ? ((voodoo->bltDstXYStride & 0x3f) * 32 * 2) + : (voodoo->bltDstXYStride & 0xff8); + break; - case BLIT_COMMAND_RECT_FILL: - for (y = 0; y <= size_y; y++) { - uint16_t *dst; - int dst_x = voodoo->bltDstX; + case BLIT_COMMAND_RECT_FILL: + for (y = 0; y <= size_y; y++) { + uint16_t *dst; + int dst_x = voodoo->bltDstX; - if (SLI_ENABLED) { - if ((!(voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && (voodoo->blt.dst_y & 1)) || - ((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && !(voodoo->blt.dst_y & 1))) - goto skip_line_fill; - dst = (uint16_t *)&voodoo->fb_mem[dst_base_addr + (dst_y >> 1) * dst_stride]; - } else - dst = (uint16_t *)&voodoo->fb_mem[dst_base_addr + dst_y * dst_stride]; + if (SLI_ENABLED) { + if ((!(voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && (voodoo->blt.dst_y & 1)) || + ((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && !(voodoo->blt.dst_y & 1))) + goto skip_line_fill; + dst = (uint16_t *)&voodoo->fb_mem[dst_base_addr + (dst_y >> 1) * dst_stride]; + } else + dst = (uint16_t *)&voodoo->fb_mem[dst_base_addr + dst_y * dst_stride]; - for (x = 0; x <= size_x; x++) { - if (voodoo->bltCommand & BLIT_CLIPPING_ENABLED) { - if (dst_x < voodoo->bltClipLeft || dst_x >= voodoo->bltClipRight || - dst_y < voodoo->bltClipLowY || dst_y >= voodoo->bltClipHighY) - goto skip_pixel_fill; - } + for (x = 0; x <= size_x; x++) { + if (voodoo->bltCommand & BLIT_CLIPPING_ENABLED) { + if (dst_x < voodoo->bltClipLeft || dst_x >= voodoo->bltClipRight || + dst_y < voodoo->bltClipLowY || dst_y >= voodoo->bltClipHighY) + goto skip_pixel_fill; + } - dst[dst_x] = voodoo->bltColorFg; - skip_pixel_fill: - dst_x += x_dir; - } - skip_line_fill: - dst_y += y_dir; - } - break; + dst[dst_x] = voodoo->bltColorFg; + skip_pixel_fill: + dst_x += x_dir; + } + skip_line_fill: + dst_y += y_dir; + } + break; - case BLIT_COMMAND_SGRAM_FILL: - /*32x32 tiles - 2kb*/ - dst_y = voodoo->bltDstY & 0x3ff; - size_x = voodoo->bltSizeX & 0x1ff; //512*8 = 4kb - size_y = voodoo->bltSizeY & 0x3ff; + case BLIT_COMMAND_SGRAM_FILL: + /*32x32 tiles - 2kb*/ + dst_y = voodoo->bltDstY & 0x3ff; + size_x = voodoo->bltSizeX & 0x1ff; // 512*8 = 4kb + size_y = voodoo->bltSizeY & 0x3ff; - dat64 = voodoo->bltColorFg | ((uint64_t)voodoo->bltColorFg << 16) | - ((uint64_t)voodoo->bltColorFg << 32) | ((uint64_t)voodoo->bltColorFg << 48); + dat64 = voodoo->bltColorFg | ((uint64_t)voodoo->bltColorFg << 16) | ((uint64_t)voodoo->bltColorFg << 32) | + ((uint64_t)voodoo->bltColorFg << 48); - for (y = 0; y <= size_y; y++) { - uint64_t *dst; + for (y = 0; y <= size_y; y++) { + uint64_t *dst; - /*This may be wrong*/ - if (!y) { - dst_x = voodoo->bltDstX & 0x1ff; - size_x = 511 - dst_x; - } else if (y < size_y) { - dst_x = 0; - size_x = 511; - } else { - dst_x = 0; - size_x = voodoo->bltSizeX & 0x1ff; - } + /*This may be wrong*/ + if (!y) { + dst_x = voodoo->bltDstX & 0x1ff; + size_x = 511 - dst_x; + } else if (y < size_y) { + dst_x = 0; + size_x = 511; + } else { + dst_x = 0; + size_x = voodoo->bltSizeX & 0x1ff; + } - dst = (uint64_t *)&voodoo->fb_mem[(dst_y * 512 * 8 + dst_x * 8) & voodoo->fb_mask]; + dst = (uint64_t *)&voodoo->fb_mem[(dst_y * 512 * 8 + dst_x * 8) & voodoo->fb_mask]; - for (x = 0; x <= size_x; x++) - dst[x] = dat64; + for (x = 0; x <= size_x; x++) + dst[x] = dat64; - dst_y++; - } - break; + dst_y++; + } + break; - default:fatal("bad blit command %08x\n", voodoo->bltCommand); - } + default: + fatal("bad blit command %08x\n", voodoo->bltCommand); + } } void voodoo_v2_blit_data(voodoo_t *voodoo, uint32_t data) { - int src_bits = 32; - uint32_t base_addr = (voodoo->bltCommand & BLTCMD_DST_TILED) ? ((voodoo->bltDstBaseAddr & 0x3ff) << 12) : (voodoo->bltDstBaseAddr & 0x3ffff8); - uint32_t addr; - uint16_t *dst; + int src_bits = 32; + uint32_t base_addr = (voodoo->bltCommand & BLTCMD_DST_TILED) ? ((voodoo->bltDstBaseAddr & 0x3ff) << 12) + : (voodoo->bltDstBaseAddr & 0x3ffff8); + uint32_t addr; + uint16_t *dst; - if ((voodoo->bltCommand & BLIT_COMMAND_MASK) != BLIT_COMMAND_CPU_TO_SCREEN) - return; + if ((voodoo->bltCommand & BLIT_COMMAND_MASK) != BLIT_COMMAND_CPU_TO_SCREEN) + return; - if (SLI_ENABLED) { - addr = base_addr + (voodoo->blt.dst_y >> 1) * voodoo->blt.dst_stride; - dst = (uint16_t *)&voodoo->fb_mem[addr]; - } else { - addr = base_addr + voodoo->blt.dst_y * voodoo->blt.dst_stride; - dst = (uint16_t *)&voodoo->fb_mem[addr]; - } + if (SLI_ENABLED) { + addr = base_addr + (voodoo->blt.dst_y >> 1) * voodoo->blt.dst_stride; + dst = (uint16_t *)&voodoo->fb_mem[addr]; + } else { + addr = base_addr + voodoo->blt.dst_y * voodoo->blt.dst_stride; + dst = (uint16_t *)&voodoo->fb_mem[addr]; + } - if (addr >= voodoo->front_offset && voodoo->row_width) { - int y = (addr - voodoo->front_offset) / voodoo->row_width; - if (y < voodoo->v_disp) - voodoo->dirty_line[y] = 2; - } + if (addr >= voodoo->front_offset && voodoo->row_width) { + int y = (addr - voodoo->front_offset) / voodoo->row_width; + if (y < voodoo->v_disp) + voodoo->dirty_line[y] = 2; + } - while (src_bits && voodoo->blt.cur_x <= voodoo->blt.size_x) { - int r = 0, g = 0, b = 0; - uint16_t src_dat = 0, dst_dat; - int x = (voodoo->blt.x_dir > 0) ? (voodoo->blt.dst_x + voodoo->blt.cur_x) : (voodoo->blt.dst_x - voodoo->blt.cur_x); - int rop = 0; + while (src_bits && voodoo->blt.cur_x <= voodoo->blt.size_x) { + int r = 0, g = 0, b = 0; + uint16_t src_dat = 0, dst_dat; + int x = (voodoo->blt.x_dir > 0) ? (voodoo->blt.dst_x + voodoo->blt.cur_x) + : (voodoo->blt.dst_x - voodoo->blt.cur_x); + int rop = 0; - switch (voodoo->bltCommand & BLIT_SRC_FORMAT) { - case BLIT_SRC_1BPP: - case BLIT_SRC_1BPP_BYTE_PACKED:src_dat = (data & 1) ? voodoo->bltColorFg : voodoo->bltColorBg; - data >>= 1; - src_bits--; - break; - case BLIT_SRC_16BPP: - switch (voodoo->bltCommand & BLIT_SRC_RGB_FORMAT) { - case BLIT_SRC_RGB_ARGB: - case BLIT_SRC_RGB_RGBA:src_dat = data & 0xffff; - break; - case BLIT_SRC_RGB_ABGR: - case BLIT_SRC_RGB_BGRA:src_dat = ((data & 0xf800) >> 11) | (data & 0x07c0) | ((data & 0x0038) << 11); - break; - } - data >>= 16; - src_bits -= 16; - break; - case BLIT_SRC_24BPP: - case BLIT_SRC_24BPP_DITHER_2X2: - case BLIT_SRC_24BPP_DITHER_4X4: - switch (voodoo->bltCommand & BLIT_SRC_RGB_FORMAT) { - case BLIT_SRC_RGB_ARGB:r = (data >> 16) & 0xff; - g = (data >> 8) & 0xff; - b = data & 0xff; - break; - case BLIT_SRC_RGB_ABGR:r = data & 0xff; - g = (data >> 8) & 0xff; - b = (data >> 16) & 0xff; - break; - case BLIT_SRC_RGB_RGBA:r = (data >> 24) & 0xff; - g = (data >> 16) & 0xff; - b = (data >> 8) & 0xff; - break; - case BLIT_SRC_RGB_BGRA:r = (data >> 8) & 0xff; - g = (data >> 16) & 0xff; - b = (data >> 24) & 0xff; - break; - } - switch (voodoo->bltCommand & BLIT_SRC_FORMAT) { - case BLIT_SRC_24BPP:src_dat = (b >> 3) | ((g & 0xfc) << 3) | ((r & 0xf8) << 8); - break; - case BLIT_SRC_24BPP_DITHER_2X2:r = dither_rb2x2[r][voodoo->blt.dst_y & 1][x & 1]; - g = dither_g2x2[g][voodoo->blt.dst_y & 1][x & 1]; - b = dither_rb2x2[b][voodoo->blt.dst_y & 1][x & 1]; - src_dat = (b >> 3) | ((g & 0xfc) << 3) | ((r & 0xf8) << 8); - break; - case BLIT_SRC_24BPP_DITHER_4X4:r = dither_rb[r][voodoo->blt.dst_y & 3][x & 3]; - g = dither_g[g][voodoo->blt.dst_y & 3][x & 3]; - b = dither_rb[b][voodoo->blt.dst_y & 3][x & 3]; - src_dat = (b >> 3) | ((g & 0xfc) << 3) | ((r & 0xf8) << 8); - break; - } - src_bits = 0; - break; - } + switch (voodoo->bltCommand & BLIT_SRC_FORMAT) { + case BLIT_SRC_1BPP: + case BLIT_SRC_1BPP_BYTE_PACKED: + src_dat = (data & 1) ? voodoo->bltColorFg : voodoo->bltColorBg; + data >>= 1; + src_bits--; + break; + case BLIT_SRC_16BPP: + switch (voodoo->bltCommand & BLIT_SRC_RGB_FORMAT) { + case BLIT_SRC_RGB_ARGB: + case BLIT_SRC_RGB_RGBA: + src_dat = data & 0xffff; + break; + case BLIT_SRC_RGB_ABGR: + case BLIT_SRC_RGB_BGRA: + src_dat = ((data & 0xf800) >> 11) | (data & 0x07c0) | ((data & 0x0038) << 11); + break; + } + data >>= 16; + src_bits -= 16; + break; + case BLIT_SRC_24BPP: + case BLIT_SRC_24BPP_DITHER_2X2: + case BLIT_SRC_24BPP_DITHER_4X4: + switch (voodoo->bltCommand & BLIT_SRC_RGB_FORMAT) { + case BLIT_SRC_RGB_ARGB: + r = (data >> 16) & 0xff; + g = (data >> 8) & 0xff; + b = data & 0xff; + break; + case BLIT_SRC_RGB_ABGR: + r = data & 0xff; + g = (data >> 8) & 0xff; + b = (data >> 16) & 0xff; + break; + case BLIT_SRC_RGB_RGBA: + r = (data >> 24) & 0xff; + g = (data >> 16) & 0xff; + b = (data >> 8) & 0xff; + break; + case BLIT_SRC_RGB_BGRA: + r = (data >> 8) & 0xff; + g = (data >> 16) & 0xff; + b = (data >> 24) & 0xff; + break; + } + switch (voodoo->bltCommand & BLIT_SRC_FORMAT) { + case BLIT_SRC_24BPP: + src_dat = (b >> 3) | ((g & 0xfc) << 3) | ((r & 0xf8) << 8); + break; + case BLIT_SRC_24BPP_DITHER_2X2: + r = dither_rb2x2[r][voodoo->blt.dst_y & 1][x & 1]; + g = dither_g2x2[g][voodoo->blt.dst_y & 1][x & 1]; + b = dither_rb2x2[b][voodoo->blt.dst_y & 1][x & 1]; + src_dat = (b >> 3) | ((g & 0xfc) << 3) | ((r & 0xf8) << 8); + break; + case BLIT_SRC_24BPP_DITHER_4X4: + r = dither_rb[r][voodoo->blt.dst_y & 3][x & 3]; + g = dither_g[g][voodoo->blt.dst_y & 3][x & 3]; + b = dither_rb[b][voodoo->blt.dst_y & 3][x & 3]; + src_dat = (b >> 3) | ((g & 0xfc) << 3) | ((r & 0xf8) << 8); + break; + } + src_bits = 0; + break; + } - if (SLI_ENABLED) { - if ((!(voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && (voodoo->blt.dst_y & 1)) || - ((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && !(voodoo->blt.dst_y & 1))) - goto skip_pixel; - } + if (SLI_ENABLED) { + if ((!(voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && (voodoo->blt.dst_y & 1)) || + ((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && !(voodoo->blt.dst_y & 1))) + goto skip_pixel; + } - if (voodoo->bltCommand & BLIT_CLIPPING_ENABLED) { - if (x < voodoo->bltClipLeft || x >= voodoo->bltClipRight || - voodoo->blt.dst_y < voodoo->bltClipLowY || voodoo->blt.dst_y >= voodoo->bltClipHighY) - goto skip_pixel; - } + if (voodoo->bltCommand & BLIT_CLIPPING_ENABLED) { + if (x < voodoo->bltClipLeft || x >= voodoo->bltClipRight || voodoo->blt.dst_y < voodoo->bltClipLowY || + voodoo->blt.dst_y >= voodoo->bltClipHighY) + goto skip_pixel; + } - dst_dat = dst[x]; + dst_dat = dst[x]; - if (voodoo->bltCommand & BLIT_SRC_CHROMA) { - r = (src_dat >> 11); - g = (src_dat >> 5) & 0x3f; - b = src_dat & 0x1f; + if (voodoo->bltCommand & BLIT_SRC_CHROMA) { + r = (src_dat >> 11); + g = (src_dat >> 5) & 0x3f; + b = src_dat & 0x1f; - if (r >= voodoo->bltSrcChromaMinR && r <= voodoo->bltSrcChromaMaxR && - g >= voodoo->bltSrcChromaMinG && g <= voodoo->bltSrcChromaMaxG && - b >= voodoo->bltSrcChromaMinB && b <= voodoo->bltSrcChromaMaxB) - rop |= BLIT_ROP_SRC_PASS; - } - if (voodoo->bltCommand & BLIT_DST_CHROMA) { - r = (dst_dat >> 11); - g = (dst_dat >> 5) & 0x3f; - b = dst_dat & 0x1f; + if (r >= voodoo->bltSrcChromaMinR && r <= voodoo->bltSrcChromaMaxR && g >= voodoo->bltSrcChromaMinG && + g <= voodoo->bltSrcChromaMaxG && b >= voodoo->bltSrcChromaMinB && b <= voodoo->bltSrcChromaMaxB) + rop |= BLIT_ROP_SRC_PASS; + } + if (voodoo->bltCommand & BLIT_DST_CHROMA) { + r = (dst_dat >> 11); + g = (dst_dat >> 5) & 0x3f; + b = dst_dat & 0x1f; - if (r >= voodoo->bltDstChromaMinR && r <= voodoo->bltDstChromaMaxR && - g >= voodoo->bltDstChromaMinG && g <= voodoo->bltDstChromaMaxG && - b >= voodoo->bltDstChromaMinB && b <= voodoo->bltDstChromaMaxB) - rop |= BLIT_ROP_DST_PASS; - } + if (r >= voodoo->bltDstChromaMinR && r <= voodoo->bltDstChromaMaxR && g >= voodoo->bltDstChromaMinG && + g <= voodoo->bltDstChromaMaxG && b >= voodoo->bltDstChromaMinB && b <= voodoo->bltDstChromaMaxB) + rop |= BLIT_ROP_DST_PASS; + } - MIX(src_dat, dst_dat, voodoo->bltRop[rop]); + MIX(src_dat, dst_dat, voodoo->bltRop[rop]); - dst[x] = dst_dat; + dst[x] = dst_dat; - skip_pixel: - voodoo->blt.cur_x++; - } + skip_pixel: + voodoo->blt.cur_x++; + } - if (voodoo->blt.cur_x > voodoo->blt.size_x) { - voodoo->blt.size_y--; - if (voodoo->blt.size_y >= 0) { - voodoo->blt.cur_x = 0; - voodoo->blt.dst_y += voodoo->blt.y_dir; - } - } + if (voodoo->blt.cur_x > voodoo->blt.size_x) { + voodoo->blt.size_y--; + if (voodoo->blt.size_y >= 0) { + voodoo->blt.cur_x = 0; + voodoo->blt.dst_y += voodoo->blt.y_dir; + } + } } void voodoo_fastfill(voodoo_t *voodoo, voodoo_params_t *params) { - int y; - int low_y, high_y; + int y; + int low_y, high_y; - if (params->fbzMode & (1 << 17)) { - int y_origin = (voodoo->type >= VOODOO_BANSHEE) ? (voodoo->y_origin_swap + 1) : voodoo->v_disp; + if (params->fbzMode & (1 << 17)) { + int y_origin = (voodoo->type >= VOODOO_BANSHEE) ? (voodoo->y_origin_swap + 1) : voodoo->v_disp; - high_y = y_origin - params->clipLowY; - low_y = y_origin - params->clipHighY; - } else { - low_y = params->clipLowY; - high_y = params->clipHighY; - } + high_y = y_origin - params->clipLowY; + low_y = y_origin - params->clipHighY; + } else { + low_y = params->clipLowY; + high_y = params->clipHighY; + } - if (params->fbzMode & FBZ_RGB_WMASK) { - int r, g, b; - uint16_t col; + if (params->fbzMode & FBZ_RGB_WMASK) { + int r, g, b; + uint16_t col; - r = ((params->color1 >> 16) >> 3) & 0x1f; - g = ((params->color1 >> 8) >> 2) & 0x3f; - b = (params->color1 >> 3) & 0x1f; - col = b | (g << 5) | (r << 11); + r = ((params->color1 >> 16) >> 3) & 0x1f; + g = ((params->color1 >> 8) >> 2) & 0x3f; + b = (params->color1 >> 3) & 0x1f; + col = b | (g << 5) | (r << 11); - if (SLI_ENABLED) { - for (y = low_y; y < high_y; y += 2) { - uint16_t *cbuf = (uint16_t *)&voodoo->fb_mem[(params->draw_offset + (y >> 1) * voodoo->row_width) & voodoo->fb_mask]; - int x; + if (SLI_ENABLED) { + for (y = low_y; y < high_y; y += 2) { + uint16_t *cbuf = + (uint16_t *)&voodoo + ->fb_mem[(params->draw_offset + (y >> 1) * voodoo->row_width) & voodoo->fb_mask]; + int x; - for (x = params->clipLeft; x < params->clipRight; x++) - cbuf[x] = col; - } - } else { - for (y = low_y; y < high_y; y++) { - if (voodoo->col_tiled) { - uint16_t *cbuf = (uint16_t *)&voodoo->fb_mem[(params->draw_offset + (y >> 5) * voodoo->row_width + (y & 31) * 128) & voodoo->fb_mask]; - int x; + for (x = params->clipLeft; x < params->clipRight; x++) + cbuf[x] = col; + } + } else { + for (y = low_y; y < high_y; y++) { + if (voodoo->col_tiled) { + uint16_t *cbuf = + (uint16_t *)&voodoo->fb_mem[(params->draw_offset + (y >> 5) * voodoo->row_width + + (y & 31) * 128) & + voodoo->fb_mask]; + int x; - for (x = params->clipLeft; x < params->clipRight; x++) { - int x2 = (x & 63) | ((x >> 6) * 128 * 32 / 2); - cbuf[x2] = col; - } - } else { - uint16_t *cbuf = (uint16_t *)&voodoo->fb_mem[(params->draw_offset + y * voodoo->row_width) & voodoo->fb_mask]; - int x; + for (x = params->clipLeft; x < params->clipRight; x++) { + int x2 = (x & 63) | ((x >> 6) * 128 * 32 / 2); + cbuf[x2] = col; + } + } else { + uint16_t *cbuf = + (uint16_t *)&voodoo + ->fb_mem[(params->draw_offset + y * voodoo->row_width) & voodoo->fb_mask]; + int x; - for (x = params->clipLeft; x < params->clipRight; x++) - cbuf[x] = col; - } - } - } - } - if (params->fbzMode & FBZ_DEPTH_WMASK) { - if (SLI_ENABLED) { - for (y = low_y; y < high_y; y += 2) { - uint16_t *abuf = (uint16_t *)&voodoo->fb_mem[(params->aux_offset + (y >> 1) * voodoo->row_width) & voodoo->fb_mask]; - int x; + for (x = params->clipLeft; x < params->clipRight; x++) + cbuf[x] = col; + } + } + } + } + if (params->fbzMode & FBZ_DEPTH_WMASK) { + if (SLI_ENABLED) { + for (y = low_y; y < high_y; y += 2) { + uint16_t *abuf = + (uint16_t *)&voodoo + ->fb_mem[(params->aux_offset + (y >> 1) * voodoo->row_width) & voodoo->fb_mask]; + int x; - for (x = params->clipLeft; x < params->clipRight; x++) - abuf[x] = params->zaColor & 0xffff; - } - } else { - for (y = low_y; y < high_y; y++) { - if (voodoo->aux_tiled) { - uint16_t *abuf = (uint16_t *)&voodoo->fb_mem[(params->aux_offset + (y >> 5) * voodoo->aux_row_width + (y & 31) * 128) & voodoo->fb_mask]; - int x; + for (x = params->clipLeft; x < params->clipRight; x++) + abuf[x] = params->zaColor & 0xffff; + } + } else { + for (y = low_y; y < high_y; y++) { + if (voodoo->aux_tiled) { + uint16_t *abuf = + (uint16_t *)&voodoo->fb_mem[(params->aux_offset + + (y >> 5) * voodoo->aux_row_width + (y & 31) * 128) & + voodoo->fb_mask]; + int x; - for (x = params->clipLeft; x < params->clipRight; x++) { - int x2 = (x & 63) | ((x >> 6) * 128 * 32 / 2); - abuf[x2] = params->zaColor & 0xffff; - } - } else { - uint16_t *abuf = (uint16_t *)&voodoo->fb_mem[(params->aux_offset + y * voodoo->aux_row_width) & voodoo->fb_mask]; - int x; + for (x = params->clipLeft; x < params->clipRight; x++) { + int x2 = (x & 63) | ((x >> 6) * 128 * 32 / 2); + abuf[x2] = params->zaColor & 0xffff; + } + } else { + uint16_t *abuf = + (uint16_t *)&voodoo->fb_mem[(params->aux_offset + y * voodoo->aux_row_width) & + voodoo->fb_mask]; + int x; - for (x = params->clipLeft; x < params->clipRight; x++) - abuf[x] = params->zaColor & 0xffff; - } - } - } - } + for (x = params->clipLeft; x < params->clipRight; x++) + abuf[x] = params->zaColor & 0xffff; + } + } + } + } } diff --git a/src/video/vid_voodoo_display.c b/src/video/vid_voodoo_display.c index cbf4c375..a90bddf4 100644 --- a/src/video/vid_voodoo_display.c +++ b/src/video/vid_voodoo_display.c @@ -11,559 +11,559 @@ #include "vid_voodoo_render.h" void voodoo_update_ncc(voodoo_t *voodoo, int tmu) { - int tbl; + int tbl; - for (tbl = 0; tbl < 2; tbl++) { - int col; + for (tbl = 0; tbl < 2; tbl++) { + int col; - for (col = 0; col < 256; col++) { - int y = (col >> 4), i = (col >> 2) & 3, q = col & 3; - int i_r, i_g, i_b; - int q_r, q_g, q_b; + for (col = 0; col < 256; col++) { + int y = (col >> 4), i = (col >> 2) & 3, q = col & 3; + int i_r, i_g, i_b; + int q_r, q_g, q_b; - y = (voodoo->nccTable[tmu][tbl].y[y >> 2] >> ((y & 3) * 8)) & 0xff; + y = (voodoo->nccTable[tmu][tbl].y[y >> 2] >> ((y & 3) * 8)) & 0xff; - i_r = (voodoo->nccTable[tmu][tbl].i[i] >> 18) & 0x1ff; - if (i_r & 0x100) - i_r |= 0xfffffe00; - i_g = (voodoo->nccTable[tmu][tbl].i[i] >> 9) & 0x1ff; - if (i_g & 0x100) - i_g |= 0xfffffe00; - i_b = voodoo->nccTable[tmu][tbl].i[i] & 0x1ff; - if (i_b & 0x100) - i_b |= 0xfffffe00; + i_r = (voodoo->nccTable[tmu][tbl].i[i] >> 18) & 0x1ff; + if (i_r & 0x100) + i_r |= 0xfffffe00; + i_g = (voodoo->nccTable[tmu][tbl].i[i] >> 9) & 0x1ff; + if (i_g & 0x100) + i_g |= 0xfffffe00; + i_b = voodoo->nccTable[tmu][tbl].i[i] & 0x1ff; + if (i_b & 0x100) + i_b |= 0xfffffe00; - q_r = (voodoo->nccTable[tmu][tbl].q[q] >> 18) & 0x1ff; - if (q_r & 0x100) - q_r |= 0xfffffe00; - q_g = (voodoo->nccTable[tmu][tbl].q[q] >> 9) & 0x1ff; - if (q_g & 0x100) - q_g |= 0xfffffe00; - q_b = voodoo->nccTable[tmu][tbl].q[q] & 0x1ff; - if (q_b & 0x100) - q_b |= 0xfffffe00; + q_r = (voodoo->nccTable[tmu][tbl].q[q] >> 18) & 0x1ff; + if (q_r & 0x100) + q_r |= 0xfffffe00; + q_g = (voodoo->nccTable[tmu][tbl].q[q] >> 9) & 0x1ff; + if (q_g & 0x100) + q_g |= 0xfffffe00; + q_b = voodoo->nccTable[tmu][tbl].q[q] & 0x1ff; + if (q_b & 0x100) + q_b |= 0xfffffe00; - voodoo->ncc_lookup[tmu][tbl][col].rgba.r = CLAMP(y + i_r + q_r); - voodoo->ncc_lookup[tmu][tbl][col].rgba.g = CLAMP(y + i_g + q_g); - voodoo->ncc_lookup[tmu][tbl][col].rgba.b = CLAMP(y + i_b + q_b); - voodoo->ncc_lookup[tmu][tbl][col].rgba.a = 0xff; - } - } + voodoo->ncc_lookup[tmu][tbl][col].rgba.r = CLAMP(y + i_r + q_r); + voodoo->ncc_lookup[tmu][tbl][col].rgba.g = CLAMP(y + i_g + q_g); + voodoo->ncc_lookup[tmu][tbl][col].rgba.b = CLAMP(y + i_b + q_b); + voodoo->ncc_lookup[tmu][tbl][col].rgba.a = 0xff; + } + } } void voodoo_pixelclock_update(voodoo_t *voodoo) { - int m = (voodoo->dac_pll_regs[0] & 0x7f) + 2; - int n1 = ((voodoo->dac_pll_regs[0] >> 8) & 0x1f) + 2; - int n2 = ((voodoo->dac_pll_regs[0] >> 13) & 0x07); - float t = (14318184.0 * ((float)m / (float)n1)) / (float)(1 << n2); - double clock_const; - int line_length; + int m = (voodoo->dac_pll_regs[0] & 0x7f) + 2; + int n1 = ((voodoo->dac_pll_regs[0] >> 8) & 0x1f) + 2; + int n2 = ((voodoo->dac_pll_regs[0] >> 13) & 0x07); + float t = (14318184.0 * ((float)m / (float)n1)) / (float)(1 << n2); + double clock_const; + int line_length; - if ((voodoo->dac_data[6] & 0xf0) == 0x20 || - (voodoo->dac_data[6] & 0xf0) == 0x60 || - (voodoo->dac_data[6] & 0xf0) == 0x70) - t /= 2.0f; + if ((voodoo->dac_data[6] & 0xf0) == 0x20 || (voodoo->dac_data[6] & 0xf0) == 0x60 || (voodoo->dac_data[6] & 0xf0) == 0x70) + t /= 2.0f; - line_length = (voodoo->hSync & 0xff) + ((voodoo->hSync >> 16) & 0x3ff); + line_length = (voodoo->hSync & 0xff) + ((voodoo->hSync >> 16) & 0x3ff); -// pclog("Pixel clock %f MHz hsync %08x line_length %d\n", t, voodoo->hSync, line_length); + // pclog("Pixel clock %f MHz hsync %08x line_length %d\n", t, voodoo->hSync, line_length); - voodoo->pixel_clock = t; + voodoo->pixel_clock = t; - clock_const = cpuclock / t; - voodoo->line_time = (uint64_t)((double)line_length * clock_const * (double)(1ull << 32)); + clock_const = cpuclock / t; + voodoo->line_time = (uint64_t)((double)line_length * clock_const * (double)(1ull << 32)); } static void voodoo_calc_clutData(voodoo_t *voodoo) { - int c; + int c; - for (c = 0; c < 256; c++) { - voodoo->clutData256[c].r = (voodoo->clutData[c >> 3].r * (8 - (c & 7)) + - voodoo->clutData[(c >> 3) + 1].r * (c & 7)) >> 3; - voodoo->clutData256[c].g = (voodoo->clutData[c >> 3].g * (8 - (c & 7)) + - voodoo->clutData[(c >> 3) + 1].g * (c & 7)) >> 3; - voodoo->clutData256[c].b = (voodoo->clutData[c >> 3].b * (8 - (c & 7)) + - voodoo->clutData[(c >> 3) + 1].b * (c & 7)) >> 3; - } + for (c = 0; c < 256; c++) { + voodoo->clutData256[c].r = + (voodoo->clutData[c >> 3].r * (8 - (c & 7)) + voodoo->clutData[(c >> 3) + 1].r * (c & 7)) >> 3; + voodoo->clutData256[c].g = + (voodoo->clutData[c >> 3].g * (8 - (c & 7)) + voodoo->clutData[(c >> 3) + 1].g * (c & 7)) >> 3; + voodoo->clutData256[c].b = + (voodoo->clutData[c >> 3].b * (8 - (c & 7)) + voodoo->clutData[(c >> 3) + 1].b * (c & 7)) >> 3; + } - for (c = 0; c < 65536; c++) { - int r = (c >> 8) & 0xf8; - int g = (c >> 3) & 0xfc; - int b = (c << 3) & 0xf8; -// r |= (r >> 5); -// g |= (g >> 6); -// b |= (b >> 5); + for (c = 0; c < 65536; c++) { + int r = (c >> 8) & 0xf8; + int g = (c >> 3) & 0xfc; + int b = (c << 3) & 0xf8; + // r |= (r >> 5); + // g |= (g >> 6); + // b |= (b >> 5); - voodoo->video_16to32[c] = (voodoo->clutData256[r].r << 16) | (voodoo->clutData256[g].g << 8) | voodoo->clutData256[b].b; - } + voodoo->video_16to32[c] = + (voodoo->clutData256[r].r << 16) | (voodoo->clutData256[g].g << 8) | voodoo->clutData256[b].b; + } } #define FILTDIV 256 -static int FILTCAP, FILTCAPG, FILTCAPB = 0; /* color filter threshold values */ +static int FILTCAP, FILTCAPG, FILTCAPB = 0; /* color filter threshold values */ void voodoo_generate_filter_v1(voodoo_t *voodoo) { - int g, h; - float difference, diffg, diffb; - float thiscol, thiscolg, thiscolb, lined; - float fcr, fcg, fcb; + int g, h; + float difference, diffg, diffb; + float thiscol, thiscolg, thiscolb, lined; + float fcr, fcg, fcb; - fcr = FILTCAP * 5; - fcg = FILTCAPG * 6; - fcb = FILTCAPB * 5; + fcr = FILTCAP * 5; + fcg = FILTCAPG * 6; + fcb = FILTCAPB * 5; - for (g = 0; g < FILTDIV; g++) // pixel 1 - { - for (h = 0; h < FILTDIV; h++) // pixel 2 - { - difference = (float)(h - g); - diffg = difference; - diffb = difference; + for (g = 0; g < FILTDIV; g++) // pixel 1 + { + for (h = 0; h < FILTDIV; h++) // pixel 2 + { + difference = (float)(h - g); + diffg = difference; + diffb = difference; - thiscol = thiscolg = thiscolb = g; + thiscol = thiscolg = thiscolb = g; - if (difference > FILTCAP) - difference = FILTCAP; - if (difference < -FILTCAP) - difference = -FILTCAP; + if (difference > FILTCAP) + difference = FILTCAP; + if (difference < -FILTCAP) + difference = -FILTCAP; - if (diffg > FILTCAPG) - diffg = FILTCAPG; - if (diffg < -FILTCAPG) - diffg = -FILTCAPG; + if (diffg > FILTCAPG) + diffg = FILTCAPG; + if (diffg < -FILTCAPG) + diffg = -FILTCAPG; - if (diffb > FILTCAPB) - diffb = FILTCAPB; - if (diffb < -FILTCAPB) - diffb = -FILTCAPB; + if (diffb > FILTCAPB) + diffb = FILTCAPB; + if (diffb < -FILTCAPB) + diffb = -FILTCAPB; - // hack - to make it not bleed onto black - //if (g == 0){ - //difference = diffg = diffb = 0; - //} + // hack - to make it not bleed onto black + // if (g == 0){ + // difference = diffg = diffb = 0; + //} - if ((difference < fcr) || (-difference > -fcr)) - thiscol = g + (difference / 2); - if ((diffg < fcg) || (-diffg > -fcg)) - thiscolg = g + (diffg / 2); /* need these divides so we can actually undither! */ - if ((diffb < fcb) || (-diffb > -fcb)) - thiscolb = g + (diffb / 2); + if ((difference < fcr) || (-difference > -fcr)) + thiscol = g + (difference / 2); + if ((diffg < fcg) || (-diffg > -fcg)) + thiscolg = g + (diffg / 2); /* need these divides so we can actually undither! */ + if ((diffb < fcb) || (-diffb > -fcb)) + thiscolb = g + (diffb / 2); - if (thiscol < 0) - thiscol = 0; - if (thiscol > FILTDIV - 1) - thiscol = FILTDIV - 1; + if (thiscol < 0) + thiscol = 0; + if (thiscol > FILTDIV - 1) + thiscol = FILTDIV - 1; - if (thiscolg < 0) - thiscolg = 0; - if (thiscolg > FILTDIV - 1) - thiscolg = FILTDIV - 1; + if (thiscolg < 0) + thiscolg = 0; + if (thiscolg > FILTDIV - 1) + thiscolg = FILTDIV - 1; - if (thiscolb < 0) - thiscolb = 0; - if (thiscolb > FILTDIV - 1) - thiscolb = FILTDIV - 1; + if (thiscolb < 0) + thiscolb = 0; + if (thiscolb > FILTDIV - 1) + thiscolb = FILTDIV - 1; - voodoo->thefilter[g][h] = thiscol; - voodoo->thefilterg[g][h] = thiscolg; - voodoo->thefilterb[g][h] = thiscolb; - } + voodoo->thefilter[g][h] = thiscol; + voodoo->thefilterg[g][h] = thiscolg; + voodoo->thefilterb[g][h] = thiscolb; + } - lined = g + 4; - if (lined > 255) - lined = 255; - voodoo->purpleline[g][0] = lined; - voodoo->purpleline[g][2] = lined; + lined = g + 4; + if (lined > 255) + lined = 255; + voodoo->purpleline[g][0] = lined; + voodoo->purpleline[g][2] = lined; - lined = g + 0; - if (lined > 255) - lined = 255; - voodoo->purpleline[g][1] = lined; - } + lined = g + 0; + if (lined > 255) + lined = 255; + voodoo->purpleline[g][1] = lined; + } } void voodoo_generate_filter_v2(voodoo_t *voodoo) { - int g, h; - float difference; - float thiscol, thiscolg, thiscolb; - float clr, clg, clb = 0; - float fcr, fcg, fcb = 0; + int g, h; + float difference; + float thiscol, thiscolg, thiscolb; + float clr, clg, clb = 0; + float fcr, fcg, fcb = 0; - // pre-clamping + // pre-clamping - fcr = FILTCAP; - fcg = FILTCAPG; - fcb = FILTCAPB; + fcr = FILTCAP; + fcg = FILTCAPG; + fcb = FILTCAPB; - if (fcr > 32) - fcr = 32; - if (fcg > 32) - fcg = 32; - if (fcb > 32) - fcb = 32; + if (fcr > 32) + fcr = 32; + if (fcg > 32) + fcg = 32; + if (fcb > 32) + fcb = 32; - for (g = 0; g < 256; g++) // pixel 1 - our target pixel we want to bleed into - { - for (h = 0; h < 256; h++) // pixel 2 - our main pixel - { - float avg; - float avgdiff; + for (g = 0; g < 256; g++) // pixel 1 - our target pixel we want to bleed into + { + for (h = 0; h < 256; h++) // pixel 2 - our main pixel + { + float avg; + float avgdiff; - difference = (float)(g - h); - avg = (float)((g + g + g + g + h) / 5); - avgdiff = avg - (float)((g + h + h + h + h) / 5); - if (avgdiff < 0) - avgdiff *= -1; - if (difference < 0) - difference *= -1; + difference = (float)(g - h); + avg = (float)((g + g + g + g + h) / 5); + avgdiff = avg - (float)((g + h + h + h + h) / 5); + if (avgdiff < 0) + avgdiff *= -1; + if (difference < 0) + difference *= -1; - thiscol = thiscolg = thiscolb = g; + thiscol = thiscolg = thiscolb = g; - // try lighten - if (h > g) { - clr = clg = clb = avgdiff; + // try lighten + if (h > g) { + clr = clg = clb = avgdiff; - if (clr > fcr) - clr = fcr; - if (clg > fcg) - clg = fcg; - if (clb > fcb) - clb = fcb; + if (clr > fcr) + clr = fcr; + if (clg > fcg) + clg = fcg; + if (clb > fcb) + clb = fcb; - thiscol = g + clr; - thiscolg = g + clg; - thiscolb = g + clb; + thiscol = g + clr; + thiscolg = g + clg; + thiscolb = g + clb; - if (thiscol > g + FILTCAP) - thiscol = g + FILTCAP; - if (thiscolg > g + FILTCAPG) - thiscolg = g + FILTCAPG; - if (thiscolb > g + FILTCAPB) - thiscolb = g + FILTCAPB; + if (thiscol > g + FILTCAP) + thiscol = g + FILTCAP; + if (thiscolg > g + FILTCAPG) + thiscolg = g + FILTCAPG; + if (thiscolb > g + FILTCAPB) + thiscolb = g + FILTCAPB; - if (thiscol > g + avgdiff) - thiscol = g + avgdiff; - if (thiscolg > g + avgdiff) - thiscolg = g + avgdiff; - if (thiscolb > g + avgdiff) - thiscolb = g + avgdiff; + if (thiscol > g + avgdiff) + thiscol = g + avgdiff; + if (thiscolg > g + avgdiff) + thiscolg = g + avgdiff; + if (thiscolb > g + avgdiff) + thiscolb = g + avgdiff; + } - } + if (difference > FILTCAP) + thiscol = g; + if (difference > FILTCAPG) + thiscolg = g; + if (difference > FILTCAPB) + thiscolb = g; - if (difference > FILTCAP) - thiscol = g; - if (difference > FILTCAPG) - thiscolg = g; - if (difference > FILTCAPB) - thiscolb = g; + // clamp + if (thiscol < 0) + thiscol = 0; + if (thiscolg < 0) + thiscolg = 0; + if (thiscolb < 0) + thiscolb = 0; - // clamp - if (thiscol < 0) - thiscol = 0; - if (thiscolg < 0) - thiscolg = 0; - if (thiscolb < 0) - thiscolb = 0; + if (thiscol > 255) + thiscol = 255; + if (thiscolg > 255) + thiscolg = 255; + if (thiscolb > 255) + thiscolb = 255; - if (thiscol > 255) - thiscol = 255; - if (thiscolg > 255) - thiscolg = 255; - if (thiscolb > 255) - thiscolb = 255; + // add to the table + voodoo->thefilter[g][h] = (thiscol); + voodoo->thefilterg[g][h] = (thiscolg); + voodoo->thefilterb[g][h] = (thiscolb); - // add to the table - voodoo->thefilter[g][h] = (thiscol); - voodoo->thefilterg[g][h] = (thiscolg); - voodoo->thefilterb[g][h] = (thiscolb); - - // debug the ones that don't give us much of a difference - //if (difference < FILTCAP) - //pclog("Voodoofilter: %ix%i - %f difference, %f average difference, R=%f, G=%f, B=%f\n", g, h, difference, avgdiff, thiscol, thiscolg, thiscolb); - } - - } + // debug the ones that don't give us much of a difference + // if (difference < FILTCAP) + // pclog("Voodoofilter: %ix%i - %f difference, %f average difference, R=%f, G=%f, B=%f\n", g, h, + // difference, avgdiff, thiscol, thiscolg, thiscolb); + } + } } void voodoo_threshold_check(voodoo_t *voodoo) { - int r, g, b; + int r, g, b; - if (!voodoo->scrfilterEnabled) - return; /* considered disabled; don't check and generate */ + if (!voodoo->scrfilterEnabled) + return; /* considered disabled; don't check and generate */ - /* Check for changes, to generate anew table */ - if (voodoo->scrfilterThreshold != voodoo->scrfilterThresholdOld) { - r = (voodoo->scrfilterThreshold >> 16) & 0xFF; - g = (voodoo->scrfilterThreshold >> 8) & 0xFF; - b = voodoo->scrfilterThreshold & 0xFF; + /* Check for changes, to generate anew table */ + if (voodoo->scrfilterThreshold != voodoo->scrfilterThresholdOld) { + r = (voodoo->scrfilterThreshold >> 16) & 0xFF; + g = (voodoo->scrfilterThreshold >> 8) & 0xFF; + b = voodoo->scrfilterThreshold & 0xFF; - FILTCAP = r; - FILTCAPG = g; - FILTCAPB = b; + FILTCAP = r; + FILTCAPG = g; + FILTCAPB = b; - pclog("Voodoo Filter Threshold Check: %06x - RED %i GREEN %i BLUE %i\n", voodoo->scrfilterThreshold, r, g, b); + pclog("Voodoo Filter Threshold Check: %06x - RED %i GREEN %i BLUE %i\n", voodoo->scrfilterThreshold, r, g, b); - voodoo->scrfilterThresholdOld = voodoo->scrfilterThreshold; + voodoo->scrfilterThresholdOld = voodoo->scrfilterThreshold; - if (voodoo->type == VOODOO_2) - voodoo_generate_filter_v2(voodoo); - else - voodoo_generate_filter_v1(voodoo); + if (voodoo->type == VOODOO_2) + voodoo_generate_filter_v2(voodoo); + else + voodoo_generate_filter_v1(voodoo); - if (voodoo->type >= VOODOO_BANSHEE) - voodoo_generate_vb_filters(voodoo, FILTCAP, FILTCAPG); - } + if (voodoo->type >= VOODOO_BANSHEE) + voodoo_generate_vb_filters(voodoo, FILTCAP, FILTCAPG); + } } static void voodoo_filterline_v1(voodoo_t *voodoo, uint8_t *fil, int column, uint16_t *src, int line) { - int x; + int x; - // Scratchpad for avoiding feedback streaks - uint8_t fil3[(voodoo->h_disp) * 3]; + // Scratchpad for avoiding feedback streaks + uint8_t fil3[(voodoo->h_disp) * 3]; - /* 16 to 32-bit */ - for (x = 0; x < column; x++) { - fil[x * 3] = ((src[x] & 31) << 3); - fil[x * 3 + 1] = (((src[x] >> 5) & 63) << 2); - fil[x * 3 + 2] = (((src[x] >> 11) & 31) << 3); + /* 16 to 32-bit */ + for (x = 0; x < column; x++) { + fil[x * 3] = ((src[x] & 31) << 3); + fil[x * 3 + 1] = (((src[x] >> 5) & 63) << 2); + fil[x * 3 + 2] = (((src[x] >> 11) & 31) << 3); - // Copy to our scratchpads - fil3[x * 3 + 0] = fil[x * 3 + 0]; - fil3[x * 3 + 1] = fil[x * 3 + 1]; - fil3[x * 3 + 2] = fil[x * 3 + 2]; - } + // Copy to our scratchpads + fil3[x * 3 + 0] = fil[x * 3 + 0]; + fil3[x * 3 + 1] = fil[x * 3 + 1]; + fil3[x * 3 + 2] = fil[x * 3 + 2]; + } + /* lines */ - /* lines */ + if (line & 1) { + for (x = 0; x < column; x++) { + fil[x * 3] = voodoo->purpleline[fil[x * 3]][0]; + fil[x * 3 + 1] = voodoo->purpleline[fil[x * 3 + 1]][1]; + fil[x * 3 + 2] = voodoo->purpleline[fil[x * 3 + 2]][2]; + } + } - if (line & 1) { - for (x = 0; x < column; x++) { - fil[x * 3] = voodoo->purpleline[fil[x * 3]][0]; - fil[x * 3 + 1] = voodoo->purpleline[fil[x * 3 + 1]][1]; - fil[x * 3 + 2] = voodoo->purpleline[fil[x * 3 + 2]][2]; - } - } + /* filtering time */ + for (x = 1; x < column; x++) { + fil3[(x)*3] = voodoo->thefilterb[fil[x * 3]][fil[(x - 1) * 3]]; + fil3[(x)*3 + 1] = voodoo->thefilterg[fil[x * 3 + 1]][fil[(x - 1) * 3 + 1]]; + fil3[(x)*3 + 2] = voodoo->thefilter[fil[x * 3 + 2]][fil[(x - 1) * 3 + 2]]; + } - /* filtering time */ + for (x = 1; x < column; x++) { + fil[(x)*3] = voodoo->thefilterb[fil3[x * 3]][fil3[(x - 1) * 3]]; + fil[(x)*3 + 1] = voodoo->thefilterg[fil3[x * 3 + 1]][fil3[(x - 1) * 3 + 1]]; + fil[(x)*3 + 2] = voodoo->thefilter[fil3[x * 3 + 2]][fil3[(x - 1) * 3 + 2]]; + } - for (x = 1; x < column; x++) { - fil3[(x) * 3] = voodoo->thefilterb[fil[x * 3]][fil[(x - 1) * 3]]; - fil3[(x) * 3 + 1] = voodoo->thefilterg[fil[x * 3 + 1]][fil[(x - 1) * 3 + 1]]; - fil3[(x) * 3 + 2] = voodoo->thefilter[fil[x * 3 + 2]][fil[(x - 1) * 3 + 2]]; - } + for (x = 1; x < column; x++) { + fil3[(x)*3] = voodoo->thefilterb[fil[x * 3]][fil[(x - 1) * 3]]; + fil3[(x)*3 + 1] = voodoo->thefilterg[fil[x * 3 + 1]][fil[(x - 1) * 3 + 1]]; + fil3[(x)*3 + 2] = voodoo->thefilter[fil[x * 3 + 2]][fil[(x - 1) * 3 + 2]]; + } - for (x = 1; x < column; x++) { - fil[(x) * 3] = voodoo->thefilterb[fil3[x * 3]][fil3[(x - 1) * 3]]; - fil[(x) * 3 + 1] = voodoo->thefilterg[fil3[x * 3 + 1]][fil3[(x - 1) * 3 + 1]]; - fil[(x) * 3 + 2] = voodoo->thefilter[fil3[x * 3 + 2]][fil3[(x - 1) * 3 + 2]]; - } - - for (x = 1; x < column; x++) { - fil3[(x) * 3] = voodoo->thefilterb[fil[x * 3]][fil[(x - 1) * 3]]; - fil3[(x) * 3 + 1] = voodoo->thefilterg[fil[x * 3 + 1]][fil[(x - 1) * 3 + 1]]; - fil3[(x) * 3 + 2] = voodoo->thefilter[fil[x * 3 + 2]][fil[(x - 1) * 3 + 2]]; - } - - for (x = 0; x < column - 1; x++) { - fil[(x) * 3] = voodoo->thefilterb[fil3[x * 3]][fil3[(x + 1) * 3]]; - fil[(x) * 3 + 1] = voodoo->thefilterg[fil3[x * 3 + 1]][fil3[(x + 1) * 3 + 1]]; - fil[(x) * 3 + 2] = voodoo->thefilter[fil3[x * 3 + 2]][fil3[(x + 1) * 3 + 2]]; - } + for (x = 0; x < column - 1; x++) { + fil[(x)*3] = voodoo->thefilterb[fil3[x * 3]][fil3[(x + 1) * 3]]; + fil[(x)*3 + 1] = voodoo->thefilterg[fil3[x * 3 + 1]][fil3[(x + 1) * 3 + 1]]; + fil[(x)*3 + 2] = voodoo->thefilter[fil3[x * 3 + 2]][fil3[(x + 1) * 3 + 2]]; + } } static void voodoo_filterline_v2(voodoo_t *voodoo, uint8_t *fil, int column, uint16_t *src, int line) { - int x; + int x; - // Scratchpad for blending filter - uint8_t fil3[(voodoo->h_disp) * 3]; + // Scratchpad for blending filter + uint8_t fil3[(voodoo->h_disp) * 3]; - /* 16 to 32-bit */ - for (x = 0; x < column; x++) { - // Blank scratchpads - fil3[x * 3 + 0] = fil[x * 3 + 0] = ((src[x] & 31) << 3); - fil3[x * 3 + 1] = fil[x * 3 + 1] = (((src[x] >> 5) & 63) << 2); - fil3[x * 3 + 2] = fil[x * 3 + 2] = (((src[x] >> 11) & 31) << 3); - } + /* 16 to 32-bit */ + for (x = 0; x < column; x++) { + // Blank scratchpads + fil3[x * 3 + 0] = fil[x * 3 + 0] = ((src[x] & 31) << 3); + fil3[x * 3 + 1] = fil[x * 3 + 1] = (((src[x] >> 5) & 63) << 2); + fil3[x * 3 + 2] = fil[x * 3 + 2] = (((src[x] >> 11) & 31) << 3); + } - /* filtering time */ + /* filtering time */ - for (x = 1; x < column - 3; x++) { - fil3[(x + 3) * 3] = voodoo->thefilterb[((src[x + 3] & 31) << 3)][((src[x] & 31) << 3)]; - fil3[(x + 3) * 3 + 1] = voodoo->thefilterg[(((src[x + 3] >> 5) & 63) << 2)][(((src[x] >> 5) & 63) << 2)]; - fil3[(x + 3) * 3 + 2] = voodoo->thefilter[(((src[x + 3] >> 11) & 31) << 3)][(((src[x] >> 11) & 31) << 3)]; + for (x = 1; x < column - 3; x++) { + fil3[(x + 3) * 3] = voodoo->thefilterb[((src[x + 3] & 31) << 3)][((src[x] & 31) << 3)]; + fil3[(x + 3) * 3 + 1] = voodoo->thefilterg[(((src[x + 3] >> 5) & 63) << 2)][(((src[x] >> 5) & 63) << 2)]; + fil3[(x + 3) * 3 + 2] = voodoo->thefilter[(((src[x + 3] >> 11) & 31) << 3)][(((src[x] >> 11) & 31) << 3)]; - fil[(x + 2) * 3] = voodoo->thefilterb[fil3[(x + 2) * 3]][((src[x] & 31) << 3)]; - fil[(x + 2) * 3 + 1] = voodoo->thefilterg[fil3[(x + 2) * 3 + 1]][(((src[x] >> 5) & 63) << 2)]; - fil[(x + 2) * 3 + 2] = voodoo->thefilter[fil3[(x + 2) * 3 + 2]][(((src[x] >> 11) & 31) << 3)]; + fil[(x + 2) * 3] = voodoo->thefilterb[fil3[(x + 2) * 3]][((src[x] & 31) << 3)]; + fil[(x + 2) * 3 + 1] = voodoo->thefilterg[fil3[(x + 2) * 3 + 1]][(((src[x] >> 5) & 63) << 2)]; + fil[(x + 2) * 3 + 2] = voodoo->thefilter[fil3[(x + 2) * 3 + 2]][(((src[x] >> 11) & 31) << 3)]; - fil3[(x + 1) * 3] = voodoo->thefilterb[fil[(x + 1) * 3]][((src[x] & 31) << 3)]; - fil3[(x + 1) * 3 + 1] = voodoo->thefilterg[fil[(x + 1) * 3 + 1]][(((src[x] >> 5) & 63) << 2)]; - fil3[(x + 1) * 3 + 2] = voodoo->thefilter[fil[(x + 1) * 3 + 2]][(((src[x] >> 11) & 31) << 3)]; + fil3[(x + 1) * 3] = voodoo->thefilterb[fil[(x + 1) * 3]][((src[x] & 31) << 3)]; + fil3[(x + 1) * 3 + 1] = voodoo->thefilterg[fil[(x + 1) * 3 + 1]][(((src[x] >> 5) & 63) << 2)]; + fil3[(x + 1) * 3 + 2] = voodoo->thefilter[fil[(x + 1) * 3 + 2]][(((src[x] >> 11) & 31) << 3)]; - fil[(x - 1) * 3] = voodoo->thefilterb[fil3[(x - 1) * 3]][((src[x] & 31) << 3)]; - fil[(x - 1) * 3 + 1] = voodoo->thefilterg[fil3[(x - 1) * 3 + 1]][(((src[x] >> 5) & 63) << 2)]; - fil[(x - 1) * 3 + 2] = voodoo->thefilter[fil3[(x - 1) * 3 + 2]][(((src[x] >> 11) & 31) << 3)]; - } + fil[(x - 1) * 3] = voodoo->thefilterb[fil3[(x - 1) * 3]][((src[x] & 31) << 3)]; + fil[(x - 1) * 3 + 1] = voodoo->thefilterg[fil3[(x - 1) * 3 + 1]][(((src[x] >> 5) & 63) << 2)]; + fil[(x - 1) * 3 + 2] = voodoo->thefilter[fil3[(x - 1) * 3 + 2]][(((src[x] >> 11) & 31) << 3)]; + } - // unroll for edge cases + // unroll for edge cases - fil3[(column - 3) * 3] = voodoo->thefilterb[((src[column - 3] & 31) << 3)][((src[column] & 31) << 3)]; - fil3[(column - 3) * 3 + 1] = voodoo->thefilterg[(((src[column - 3] >> 5) & 63) << 2)][(((src[column] >> 5) & 63) << 2)]; - fil3[(column - 3) * 3 + 2] = voodoo->thefilter[(((src[column - 3] >> 11) & 31) << 3)][(((src[column] >> 11) & 31) << 3)]; + fil3[(column - 3) * 3] = voodoo->thefilterb[((src[column - 3] & 31) << 3)][((src[column] & 31) << 3)]; + fil3[(column - 3) * 3 + 1] = voodoo->thefilterg[(((src[column - 3] >> 5) & 63) << 2)][(((src[column] >> 5) & 63) << 2)]; + fil3[(column - 3) * 3 + 2] = voodoo->thefilter[(((src[column - 3] >> 11) & 31) << 3)][(((src[column] >> 11) & 31) << 3)]; - fil3[(column - 2) * 3] = voodoo->thefilterb[((src[column - 2] & 31) << 3)][((src[column] & 31) << 3)]; - fil3[(column - 2) * 3 + 1] = voodoo->thefilterg[(((src[column - 2] >> 5) & 63) << 2)][(((src[column] >> 5) & 63) << 2)]; - fil3[(column - 2) * 3 + 2] = voodoo->thefilter[(((src[column - 2] >> 11) & 31) << 3)][(((src[column] >> 11) & 31) << 3)]; + fil3[(column - 2) * 3] = voodoo->thefilterb[((src[column - 2] & 31) << 3)][((src[column] & 31) << 3)]; + fil3[(column - 2) * 3 + 1] = voodoo->thefilterg[(((src[column - 2] >> 5) & 63) << 2)][(((src[column] >> 5) & 63) << 2)]; + fil3[(column - 2) * 3 + 2] = voodoo->thefilter[(((src[column - 2] >> 11) & 31) << 3)][(((src[column] >> 11) & 31) << 3)]; - fil3[(column - 1) * 3] = voodoo->thefilterb[((src[column - 1] & 31) << 3)][((src[column] & 31) << 3)]; - fil3[(column - 1) * 3 + 1] = voodoo->thefilterg[(((src[column - 1] >> 5) & 63) << 2)][(((src[column] >> 5) & 63) << 2)]; - fil3[(column - 1) * 3 + 2] = voodoo->thefilter[(((src[column - 1] >> 11) & 31) << 3)][(((src[column] >> 11) & 31) << 3)]; + fil3[(column - 1) * 3] = voodoo->thefilterb[((src[column - 1] & 31) << 3)][((src[column] & 31) << 3)]; + fil3[(column - 1) * 3 + 1] = voodoo->thefilterg[(((src[column - 1] >> 5) & 63) << 2)][(((src[column] >> 5) & 63) << 2)]; + fil3[(column - 1) * 3 + 2] = voodoo->thefilter[(((src[column - 1] >> 11) & 31) << 3)][(((src[column] >> 11) & 31) << 3)]; - fil[(column - 2) * 3] = voodoo->thefilterb[fil3[(column - 2) * 3]][((src[column] & 31) << 3)]; - fil[(column - 2) * 3 + 1] = voodoo->thefilterg[fil3[(column - 2) * 3 + 1]][(((src[column] >> 5) & 63) << 2)]; - fil[(column - 2) * 3 + 2] = voodoo->thefilter[fil3[(column - 2) * 3 + 2]][(((src[column] >> 11) & 31) << 3)]; + fil[(column - 2) * 3] = voodoo->thefilterb[fil3[(column - 2) * 3]][((src[column] & 31) << 3)]; + fil[(column - 2) * 3 + 1] = voodoo->thefilterg[fil3[(column - 2) * 3 + 1]][(((src[column] >> 5) & 63) << 2)]; + fil[(column - 2) * 3 + 2] = voodoo->thefilter[fil3[(column - 2) * 3 + 2]][(((src[column] >> 11) & 31) << 3)]; - fil[(column - 1) * 3] = voodoo->thefilterb[fil3[(column - 1) * 3]][((src[column] & 31) << 3)]; - fil[(column - 1) * 3 + 1] = voodoo->thefilterg[fil3[(column - 1) * 3 + 1]][(((src[column] >> 5) & 63) << 2)]; - fil[(column - 1) * 3 + 2] = voodoo->thefilter[fil3[(column - 1) * 3 + 2]][(((src[column] >> 11) & 31) << 3)]; + fil[(column - 1) * 3] = voodoo->thefilterb[fil3[(column - 1) * 3]][((src[column] & 31) << 3)]; + fil[(column - 1) * 3 + 1] = voodoo->thefilterg[fil3[(column - 1) * 3 + 1]][(((src[column] >> 5) & 63) << 2)]; + fil[(column - 1) * 3 + 2] = voodoo->thefilter[fil3[(column - 1) * 3 + 2]][(((src[column] >> 11) & 31) << 3)]; - fil3[(column - 1) * 3] = voodoo->thefilterb[fil[(column - 1) * 3]][((src[column] & 31) << 3)]; - fil3[(column - 1) * 3 + 1] = voodoo->thefilterg[fil[(column - 1) * 3 + 1]][(((src[column] >> 5) & 63) << 2)]; - fil3[(column - 1) * 3 + 2] = voodoo->thefilter[fil[(column - 1) * 3 + 2]][(((src[column] >> 11) & 31) << 3)]; + fil3[(column - 1) * 3] = voodoo->thefilterb[fil[(column - 1) * 3]][((src[column] & 31) << 3)]; + fil3[(column - 1) * 3 + 1] = voodoo->thefilterg[fil[(column - 1) * 3 + 1]][(((src[column] >> 5) & 63) << 2)]; + fil3[(column - 1) * 3 + 2] = voodoo->thefilter[fil[(column - 1) * 3 + 2]][(((src[column] >> 11) & 31) << 3)]; } void voodoo_callback(void *p) { - voodoo_t *voodoo = (voodoo_t *)p; + voodoo_t *voodoo = (voodoo_t *)p; - if (voodoo->fbiInit0 & FBIINIT0_VGA_PASS) { - if (voodoo->line < voodoo->v_disp) { - voodoo_t *draw_voodoo; - int draw_line; + if (voodoo->fbiInit0 & FBIINIT0_VGA_PASS) { + if (voodoo->line < voodoo->v_disp) { + voodoo_t *draw_voodoo; + int draw_line; - if (SLI_ENABLED) { - if (voodoo == voodoo->set->voodoos[1]) - goto skip_draw; + if (SLI_ENABLED) { + if (voodoo == voodoo->set->voodoos[1]) + goto skip_draw; - if (((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) ? 1 : 0) == (voodoo->line & 1)) - draw_voodoo = voodoo; - else - draw_voodoo = voodoo->set->voodoos[1]; - draw_line = voodoo->line >> 1; - } else { - if (!(voodoo->fbiInit0 & 1)) - goto skip_draw; - draw_voodoo = voodoo; - draw_line = voodoo->line; - } + if (((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) ? 1 : 0) == (voodoo->line & 1)) + draw_voodoo = voodoo; + else + draw_voodoo = voodoo->set->voodoos[1]; + draw_line = voodoo->line >> 1; + } else { + if (!(voodoo->fbiInit0 & 1)) + goto skip_draw; + draw_voodoo = voodoo; + draw_line = voodoo->line; + } - if (draw_voodoo->dirty_line[draw_line]) { - uint32_t *p = &((uint32_t *)buffer32->line[voodoo->line])[32]; - uint16_t *src = (uint16_t *)&draw_voodoo->fb_mem[draw_voodoo->front_offset + draw_line * draw_voodoo->row_width]; - int x; + if (draw_voodoo->dirty_line[draw_line]) { + uint32_t *p = &((uint32_t *)buffer32->line[voodoo->line])[32]; + uint16_t *src = (uint16_t *)&draw_voodoo + ->fb_mem[draw_voodoo->front_offset + draw_line * draw_voodoo->row_width]; + int x; - draw_voodoo->dirty_line[draw_line] = 0; + draw_voodoo->dirty_line[draw_line] = 0; - if (voodoo->line < voodoo->dirty_line_low) { - voodoo->dirty_line_low = voodoo->line; - video_wait_for_buffer(); - } - if (voodoo->line > voodoo->dirty_line_high) - voodoo->dirty_line_high = voodoo->line; + if (voodoo->line < voodoo->dirty_line_low) { + voodoo->dirty_line_low = voodoo->line; + video_wait_for_buffer(); + } + if (voodoo->line > voodoo->dirty_line_high) + voodoo->dirty_line_high = voodoo->line; - if (voodoo->scrfilter && voodoo->scrfilterEnabled) { - uint8_t fil[(voodoo->h_disp) * 3]; /* interleaved 24-bit RGB */ + if (voodoo->scrfilter && voodoo->scrfilterEnabled) { + uint8_t fil[(voodoo->h_disp) * 3]; /* interleaved 24-bit RGB */ - if (voodoo->type == VOODOO_2) - voodoo_filterline_v2(voodoo, fil, voodoo->h_disp, src, voodoo->line); - else - voodoo_filterline_v1(voodoo, fil, voodoo->h_disp, src, voodoo->line); + if (voodoo->type == VOODOO_2) + voodoo_filterline_v2(voodoo, fil, voodoo->h_disp, src, voodoo->line); + else + voodoo_filterline_v1(voodoo, fil, voodoo->h_disp, src, voodoo->line); - for (x = 0; x < voodoo->h_disp; x++) { - p[x] = (voodoo->clutData256[fil[x * 3]].b << 0 | voodoo->clutData256[fil[x * 3 + 1]].g << 8 | voodoo->clutData256[fil[x * 3 + 2]].r << 16); - } - } else { - for (x = 0; x < voodoo->h_disp; x++) { - p[x] = draw_voodoo->video_16to32[src[x]]; - } - } - } - } - } - skip_draw: - if (voodoo->line == voodoo->v_disp) { -// pclog("retrace %i %i %08x %i\n", voodoo->retrace_count, voodoo->swap_interval, voodoo->swap_offset, voodoo->swap_pending); - voodoo->retrace_count++; - if (SLI_ENABLED && (voodoo->fbiInit2 & FBIINIT2_SWAP_ALGORITHM_MASK) == FBIINIT2_SWAP_ALGORITHM_SLI_SYNC) { - if (voodoo == voodoo->set->voodoos[0]) { - voodoo_t *voodoo_1 = voodoo->set->voodoos[1]; + for (x = 0; x < voodoo->h_disp; x++) { + p[x] = (voodoo->clutData256[fil[x * 3]].b << 0 | + voodoo->clutData256[fil[x * 3 + 1]].g << 8 | + voodoo->clutData256[fil[x * 3 + 2]].r << 16); + } + } else { + for (x = 0; x < voodoo->h_disp; x++) { + p[x] = draw_voodoo->video_16to32[src[x]]; + } + } + } + } + } +skip_draw: + if (voodoo->line == voodoo->v_disp) { + // pclog("retrace %i %i %08x %i\n", voodoo->retrace_count, voodoo->swap_interval, + // voodoo->swap_offset, voodoo->swap_pending); + voodoo->retrace_count++; + if (SLI_ENABLED && (voodoo->fbiInit2 & FBIINIT2_SWAP_ALGORITHM_MASK) == FBIINIT2_SWAP_ALGORITHM_SLI_SYNC) { + if (voodoo == voodoo->set->voodoos[0]) { + voodoo_t *voodoo_1 = voodoo->set->voodoos[1]; - thread_lock_mutex(voodoo->swap_mutex); - /*Only swap if both Voodoos are waiting for buffer swap*/ - if (voodoo->swap_pending && (voodoo->retrace_count > voodoo->swap_interval) && - voodoo_1->swap_pending && (voodoo_1->retrace_count > voodoo_1->swap_interval)) { - memset(voodoo->dirty_line, 1, 1024); - voodoo->retrace_count = 0; - voodoo->front_offset = voodoo->swap_offset; - if (voodoo->swap_count > 0) - voodoo->swap_count--; - voodoo->swap_pending = 0; + thread_lock_mutex(voodoo->swap_mutex); + /*Only swap if both Voodoos are waiting for buffer swap*/ + if (voodoo->swap_pending && (voodoo->retrace_count > voodoo->swap_interval) && + voodoo_1->swap_pending && (voodoo_1->retrace_count > voodoo_1->swap_interval)) { + memset(voodoo->dirty_line, 1, 1024); + voodoo->retrace_count = 0; + voodoo->front_offset = voodoo->swap_offset; + if (voodoo->swap_count > 0) + voodoo->swap_count--; + voodoo->swap_pending = 0; - memset(voodoo_1->dirty_line, 1, 1024); - voodoo_1->retrace_count = 0; - voodoo_1->front_offset = voodoo_1->swap_offset; - if (voodoo_1->swap_count > 0) - voodoo_1->swap_count--; - voodoo_1->swap_pending = 0; - thread_unlock_mutex(voodoo->swap_mutex); + memset(voodoo_1->dirty_line, 1, 1024); + voodoo_1->retrace_count = 0; + voodoo_1->front_offset = voodoo_1->swap_offset; + if (voodoo_1->swap_count > 0) + voodoo_1->swap_count--; + voodoo_1->swap_pending = 0; + thread_unlock_mutex(voodoo->swap_mutex); - thread_set_event(voodoo->wake_fifo_thread); - thread_set_event(voodoo_1->wake_fifo_thread); + thread_set_event(voodoo->wake_fifo_thread); + thread_set_event(voodoo_1->wake_fifo_thread); - voodoo->frame_count++; - voodoo_1->frame_count++; - } else - thread_unlock_mutex(voodoo->swap_mutex); - } - } else { - thread_lock_mutex(voodoo->swap_mutex); - if (voodoo->swap_pending && (voodoo->retrace_count > voodoo->swap_interval)) { - voodoo->front_offset = voodoo->swap_offset; - if (voodoo->swap_count > 0) - voodoo->swap_count--; - voodoo->swap_pending = 0; - thread_unlock_mutex(voodoo->swap_mutex); + voodoo->frame_count++; + voodoo_1->frame_count++; + } else + thread_unlock_mutex(voodoo->swap_mutex); + } + } else { + thread_lock_mutex(voodoo->swap_mutex); + if (voodoo->swap_pending && (voodoo->retrace_count > voodoo->swap_interval)) { + voodoo->front_offset = voodoo->swap_offset; + if (voodoo->swap_count > 0) + voodoo->swap_count--; + voodoo->swap_pending = 0; + thread_unlock_mutex(voodoo->swap_mutex); - memset(voodoo->dirty_line, 1, 1024); - voodoo->retrace_count = 0; - thread_set_event(voodoo->wake_fifo_thread); - voodoo->frame_count++; - } else - thread_unlock_mutex(voodoo->swap_mutex); - } - voodoo->v_retrace = 1; - } - voodoo->line++; + memset(voodoo->dirty_line, 1, 1024); + voodoo->retrace_count = 0; + thread_set_event(voodoo->wake_fifo_thread); + voodoo->frame_count++; + } else + thread_unlock_mutex(voodoo->swap_mutex); + } + voodoo->v_retrace = 1; + } + voodoo->line++; - if (voodoo->fbiInit0 & FBIINIT0_VGA_PASS) { - if (voodoo->line == voodoo->v_disp) { - if (voodoo->dirty_line_high > voodoo->dirty_line_low) - svga_doblit(0, voodoo->v_disp, voodoo->h_disp, voodoo->v_disp - 1, voodoo->svga); - if (voodoo->clutData_dirty) { - voodoo->clutData_dirty = 0; - voodoo_calc_clutData(voodoo); - } - voodoo->dirty_line_high = -1; - voodoo->dirty_line_low = 2000; - } - } + if (voodoo->fbiInit0 & FBIINIT0_VGA_PASS) { + if (voodoo->line == voodoo->v_disp) { + if (voodoo->dirty_line_high > voodoo->dirty_line_low) + svga_doblit(0, voodoo->v_disp, voodoo->h_disp, voodoo->v_disp - 1, voodoo->svga); + if (voodoo->clutData_dirty) { + voodoo->clutData_dirty = 0; + voodoo_calc_clutData(voodoo); + } + voodoo->dirty_line_high = -1; + voodoo->dirty_line_low = 2000; + } + } - if (voodoo->line >= voodoo->v_total) { - voodoo->line = 0; - voodoo->v_retrace = 0; - } - if (voodoo->line_time) - timer_advance_u64(&voodoo->timer, voodoo->line_time); - else - timer_advance_u64(&voodoo->timer, TIMER_USEC * 32); + if (voodoo->line >= voodoo->v_total) { + voodoo->line = 0; + voodoo->v_retrace = 0; + } + if (voodoo->line_time) + timer_advance_u64(&voodoo->timer, voodoo->line_time); + else + timer_advance_u64(&voodoo->timer, TIMER_USEC * 32); } diff --git a/src/video/vid_voodoo_fb.c b/src/video/vid_voodoo_fb.c index 5544ed93..4728cca2 100644 --- a/src/video/vid_voodoo_fb.c +++ b/src/video/vid_voodoo_fb.c @@ -12,380 +12,400 @@ #include "vid_voodoo_fb.h" uint16_t voodoo_fb_readw(uint32_t addr, void *p) { - voodoo_t *voodoo = (voodoo_t *)p; - int x, y; - uint32_t read_addr; - uint16_t temp; + voodoo_t *voodoo = (voodoo_t *)p; + int x, y; + uint32_t read_addr; + uint16_t temp; - if (voodoo->type >= VOODOO_BANSHEE) { - x = addr & 0xffe; - y = (addr >> 12) & 0x3ff; - } else { - x = addr & 0x7fe; - y = (addr >> 11) & 0x3ff; - } + if (voodoo->type >= VOODOO_BANSHEE) { + x = addr & 0xffe; + y = (addr >> 12) & 0x3ff; + } else { + x = addr & 0x7fe; + y = (addr >> 11) & 0x3ff; + } - if (SLI_ENABLED) { - voodoo_set_t *set = voodoo->set; + if (SLI_ENABLED) { + voodoo_set_t *set = voodoo->set; - if (y & 1) - voodoo = set->voodoos[1]; - else - voodoo = set->voodoos[0]; + if (y & 1) + voodoo = set->voodoos[1]; + else + voodoo = set->voodoos[0]; - y >>= 1; - } + y >>= 1; + } - if (voodoo->col_tiled) - read_addr = voodoo->fb_read_offset + (x & 127) + (x >> 7) * 128 * 32 + (y & 31) * 128 + (y >> 5) * voodoo->row_width; - else - read_addr = voodoo->fb_read_offset + x + (y * voodoo->row_width); + if (voodoo->col_tiled) + read_addr = + voodoo->fb_read_offset + (x & 127) + (x >> 7) * 128 * 32 + (y & 31) * 128 + (y >> 5) * voodoo->row_width; + else + read_addr = voodoo->fb_read_offset + x + (y * voodoo->row_width); - if (read_addr > voodoo->fb_mask) - return 0xffff; + if (read_addr > voodoo->fb_mask) + return 0xffff; - temp = *(uint16_t *)(&voodoo->fb_mem[read_addr & voodoo->fb_mask]); + temp = *(uint16_t *)(&voodoo->fb_mem[read_addr & voodoo->fb_mask]); -// pclog("voodoo_fb_readw : %08X %08X %i %i %08X %08X %08x:%08x %i\n", addr, temp, x, y, read_addr, *(uint32_t *)(&voodoo->fb_mem[4]), cs, pc, fb_reads++); - return temp; + // pclog("voodoo_fb_readw : %08X %08X %i %i %08X %08X %08x:%08x %i\n", addr, temp, x, y, read_addr, *(uint32_t + // *)(&voodoo->fb_mem[4]), cs, pc, fb_reads++); + return temp; } uint32_t voodoo_fb_readl(uint32_t addr, void *p) { - voodoo_t *voodoo = (voodoo_t *)p; - int x, y; - uint32_t read_addr; - uint32_t temp; + voodoo_t *voodoo = (voodoo_t *)p; + int x, y; + uint32_t read_addr; + uint32_t temp; - if (voodoo->type >= VOODOO_BANSHEE) { - x = addr & 0xffe; - y = (addr >> 12) & 0x3ff; - } else { - x = addr & 0x7fe; - y = (addr >> 11) & 0x3ff; - } + if (voodoo->type >= VOODOO_BANSHEE) { + x = addr & 0xffe; + y = (addr >> 12) & 0x3ff; + } else { + x = addr & 0x7fe; + y = (addr >> 11) & 0x3ff; + } - if (SLI_ENABLED) { - voodoo_set_t *set = voodoo->set; + if (SLI_ENABLED) { + voodoo_set_t *set = voodoo->set; - if (y & 1) - voodoo = set->voodoos[1]; - else - voodoo = set->voodoos[0]; + if (y & 1) + voodoo = set->voodoos[1]; + else + voodoo = set->voodoos[0]; - y >>= 1; - } + y >>= 1; + } - if (voodoo->col_tiled) - read_addr = voodoo->fb_read_offset + (x & 127) + (x >> 7) * 128 * 32 + (y & 31) * 128 + (y >> 5) * voodoo->row_width; - else - read_addr = voodoo->fb_read_offset + x + (y * voodoo->row_width); + if (voodoo->col_tiled) + read_addr = + voodoo->fb_read_offset + (x & 127) + (x >> 7) * 128 * 32 + (y & 31) * 128 + (y >> 5) * voodoo->row_width; + else + read_addr = voodoo->fb_read_offset + x + (y * voodoo->row_width); - if (read_addr > voodoo->fb_mask) - return 0xffffffff; + if (read_addr > voodoo->fb_mask) + return 0xffffffff; - temp = *(uint32_t *)(&voodoo->fb_mem[read_addr & voodoo->fb_mask]); + temp = *(uint32_t *)(&voodoo->fb_mem[read_addr & voodoo->fb_mask]); -// pclog("voodoo_fb_readl : %08X %08x %08X x=%i y=%i %08X %08X %08x:%08x %i ro=%08x rw=%i\n", addr, read_addr, temp, x, y, read_addr, *(uint32_t *)(&voodoo->fb_mem[4]), cs, pc, fb_reads++, voodoo->fb_read_offset, voodoo->row_width); - return temp; + // pclog("voodoo_fb_readl : %08X %08x %08X x=%i y=%i %08X %08X %08x:%08x %i ro=%08x rw=%i\n", addr, read_addr, + // temp, x, y, read_addr, *(uint32_t *)(&voodoo->fb_mem[4]), cs, pc, fb_reads++, voodoo->fb_read_offset, + // voodoo->row_width); + return temp; } static inline uint16_t do_dither(voodoo_params_t *params, rgba8_t col, int x, int y) { - int r, g, b; + int r, g, b; - if (dither) { - if (dither2x2) { - r = dither_rb2x2[col.r][y & 1][x & 1]; - g = dither_g2x2[col.g][y & 1][x & 1]; - b = dither_rb2x2[col.b][y & 1][x & 1]; - } else { - r = dither_rb[col.r][y & 3][x & 3]; - g = dither_g[col.g][y & 3][x & 3]; - b = dither_rb[col.b][y & 3][x & 3]; - } - } else { - r = col.r >> 3; - g = col.g >> 2; - b = col.b >> 3; - } + if (dither) { + if (dither2x2) { + r = dither_rb2x2[col.r][y & 1][x & 1]; + g = dither_g2x2[col.g][y & 1][x & 1]; + b = dither_rb2x2[col.b][y & 1][x & 1]; + } else { + r = dither_rb[col.r][y & 3][x & 3]; + g = dither_g[col.g][y & 3][x & 3]; + b = dither_rb[col.b][y & 3][x & 3]; + } + } else { + r = col.r >> 3; + g = col.g >> 2; + b = col.b >> 3; + } - return b | (g << 5) | (r << 11); + return b | (g << 5) | (r << 11); } void voodoo_fb_writew(uint32_t addr, uint16_t val, void *p) { - voodoo_t *voodoo = (voodoo_t *)p; - voodoo_params_t *params = &voodoo->params; - int x, y; - uint32_t write_addr, write_addr_aux; - rgba8_t colour_data; - uint16_t depth_data; - uint8_t alpha_data; - int write_mask = 0; + voodoo_t *voodoo = (voodoo_t *)p; + voodoo_params_t *params = &voodoo->params; + int x, y; + uint32_t write_addr, write_addr_aux; + rgba8_t colour_data; + uint16_t depth_data; + uint8_t alpha_data; + int write_mask = 0; - colour_data.r = colour_data.g = colour_data.b = colour_data.a = 0; + colour_data.r = colour_data.g = colour_data.b = colour_data.a = 0; - depth_data = voodoo->params.zaColor & 0xffff; - alpha_data = voodoo->params.zaColor >> 24; + depth_data = voodoo->params.zaColor & 0xffff; + alpha_data = voodoo->params.zaColor >> 24; -// while (!RB_EMPTY) -// thread_reset_event(voodoo->not_full_event); + // while (!RB_EMPTY) + // thread_reset_event(voodoo->not_full_event); -// pclog("voodoo_fb_writew : %08X %04X\n", addr, val); + // pclog("voodoo_fb_writew : %08X %04X\n", addr, val); + switch (voodoo->lfbMode & LFB_FORMAT_MASK) { + case LFB_FORMAT_RGB565: + colour_data = rgb565[val]; + alpha_data = 0xff; + write_mask = LFB_WRITE_COLOUR; + break; + case LFB_FORMAT_RGB555: + colour_data = argb1555[val]; + alpha_data = 0xff; + write_mask = LFB_WRITE_COLOUR; + break; + case LFB_FORMAT_ARGB1555: + colour_data = argb1555[val]; + alpha_data = colour_data.a; + write_mask = LFB_WRITE_COLOUR; + break; + case LFB_FORMAT_DEPTH: + depth_data = val; + write_mask = LFB_WRITE_DEPTH; + break; - switch (voodoo->lfbMode & LFB_FORMAT_MASK) { - case LFB_FORMAT_RGB565:colour_data = rgb565[val]; - alpha_data = 0xff; - write_mask = LFB_WRITE_COLOUR; - break; - case LFB_FORMAT_RGB555:colour_data = argb1555[val]; - alpha_data = 0xff; - write_mask = LFB_WRITE_COLOUR; - break; - case LFB_FORMAT_ARGB1555:colour_data = argb1555[val]; - alpha_data = colour_data.a; - write_mask = LFB_WRITE_COLOUR; - break; - case LFB_FORMAT_DEPTH:depth_data = val; - write_mask = LFB_WRITE_DEPTH; - break; + default: + fatal("voodoo_fb_writew : bad LFB format %08X\n", voodoo->lfbMode); + } - default:fatal("voodoo_fb_writew : bad LFB format %08X\n", voodoo->lfbMode); - } + if (voodoo->type >= VOODOO_BANSHEE) { + x = addr & 0xffe; + y = (addr >> 12) & 0x3ff; + } else { + x = addr & 0x7fe; + y = (addr >> 11) & 0x3ff; + } - if (voodoo->type >= VOODOO_BANSHEE) { - x = addr & 0xffe; - y = (addr >> 12) & 0x3ff; - } else { - x = addr & 0x7fe; - y = (addr >> 11) & 0x3ff; - } + if (SLI_ENABLED) { + if ((!(voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && (y & 1)) || + ((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && !(y & 1))) + return; + y >>= 1; + } - if (SLI_ENABLED) { - if ((!(voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && (y & 1)) || - ((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && !(y & 1))) - return; - y >>= 1; - } + if (voodoo->fb_write_offset == voodoo->params.front_offset && y < 2048) + voodoo->dirty_line[y] = 1; - if (voodoo->fb_write_offset == voodoo->params.front_offset && y < 2048) - voodoo->dirty_line[y] = 1; + if (voodoo->col_tiled) + write_addr = + voodoo->fb_write_offset + (x & 127) + (x >> 7) * 128 * 32 + (y & 31) * 128 + (y >> 5) * voodoo->row_width; + else + write_addr = voodoo->fb_write_offset + x + (y * voodoo->row_width); + if (voodoo->aux_tiled) + write_addr_aux = voodoo->params.aux_offset + (x & 127) + (x >> 7) * 128 * 32 + (y & 31) * 128 + + (y >> 5) * voodoo->row_width; + else + write_addr_aux = voodoo->params.aux_offset + x + (y * voodoo->row_width); - if (voodoo->col_tiled) - write_addr = voodoo->fb_write_offset + (x & 127) + (x >> 7) * 128 * 32 + (y & 31) * 128 + (y >> 5) * voodoo->row_width; - else - write_addr = voodoo->fb_write_offset + x + (y * voodoo->row_width); - if (voodoo->aux_tiled) - write_addr_aux = voodoo->params.aux_offset + (x & 127) + (x >> 7) * 128 * 32 + (y & 31) * 128 + (y >> 5) * voodoo->row_width; - else - write_addr_aux = voodoo->params.aux_offset + x + (y * voodoo->row_width); + // pclog("fb_writew %08x %i %i %i %08x\n", addr, x, y, voodoo->row_width, write_addr); -// pclog("fb_writew %08x %i %i %i %08x\n", addr, x, y, voodoo->row_width, write_addr); + if (voodoo->lfbMode & 0x100) { + { + rgba8_t write_data = colour_data; + uint16_t new_depth = depth_data; - if (voodoo->lfbMode & 0x100) { - { - rgba8_t write_data = colour_data; - uint16_t new_depth = depth_data; + if (params->fbzMode & FBZ_DEPTH_ENABLE) { + uint16_t old_depth = *(uint16_t *)(&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]); - if (params->fbzMode & FBZ_DEPTH_ENABLE) { - uint16_t old_depth = *(uint16_t *)(&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]); + DEPTH_TEST(new_depth); + } - DEPTH_TEST(new_depth); - } + if ((params->fbzMode & FBZ_CHROMAKEY) && write_data.r == params->chromaKey_r && + write_data.g == params->chromaKey_g && write_data.b == params->chromaKey_b) + goto skip_pixel; - if ((params->fbzMode & FBZ_CHROMAKEY) && - write_data.r == params->chromaKey_r && - write_data.g == params->chromaKey_g && - write_data.b == params->chromaKey_b) - goto skip_pixel; + if (params->fogMode & FOG_ENABLE) { + int32_t z = new_depth << 12; + int64_t w_depth = (int64_t)(int32_t)new_depth; + int32_t ia = alpha_data << 12; - if (params->fogMode & FOG_ENABLE) { - int32_t z = new_depth << 12; - int64_t w_depth = (int64_t)(int32_t)new_depth; - int32_t ia = alpha_data << 12; + APPLY_FOG(write_data.r, write_data.g, write_data.b, z, ia, w_depth); + } - APPLY_FOG(write_data.r, write_data.g, write_data.b, z, ia, w_depth); - } + if (params->alphaMode & 1) + ALPHA_TEST(alpha_data); - if (params->alphaMode & 1) - ALPHA_TEST(alpha_data); + if (params->alphaMode & (1 << 4)) { + uint16_t dat = *(uint16_t *)(&voodoo->fb_mem[write_addr & voodoo->fb_mask]); + int dest_r, dest_g, dest_b, dest_a; - if (params->alphaMode & (1 << 4)) { - uint16_t dat = *(uint16_t *)(&voodoo->fb_mem[write_addr & voodoo->fb_mask]); - int dest_r, dest_g, dest_b, dest_a; + dest_r = (dat >> 8) & 0xf8; + dest_g = (dat >> 3) & 0xfc; + dest_b = (dat << 3) & 0xf8; + dest_r |= (dest_r >> 5); + dest_g |= (dest_g >> 6); + dest_b |= (dest_b >> 5); + dest_a = 0xff; - dest_r = (dat >> 8) & 0xf8; - dest_g = (dat >> 3) & 0xfc; - dest_b = (dat << 3) & 0xf8; - dest_r |= (dest_r >> 5); - dest_g |= (dest_g >> 6); - dest_b |= (dest_b >> 5); - dest_a = 0xff; + ALPHA_BLEND(write_data.r, write_data.g, write_data.b, alpha_data); + } - ALPHA_BLEND(write_data.r, write_data.g, write_data.b, alpha_data); - } + if (params->fbzMode & FBZ_RGB_WMASK) + *(uint16_t *)(&voodoo->fb_mem[write_addr & voodoo->fb_mask]) = + do_dither(&voodoo->params, write_data, x >> 1, y); + if (params->fbzMode & FBZ_DEPTH_WMASK) + *(uint16_t *)(&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]) = new_depth; - if (params->fbzMode & FBZ_RGB_WMASK) - *(uint16_t *)(&voodoo->fb_mem[write_addr & voodoo->fb_mask]) = do_dither(&voodoo->params, write_data, x >> 1, y); - if (params->fbzMode & FBZ_DEPTH_WMASK) - *(uint16_t *)(&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]) = new_depth; - - skip_pixel: - x = x; - } - } else { - if (write_mask & LFB_WRITE_COLOUR) - *(uint16_t *)(&voodoo->fb_mem[write_addr & voodoo->fb_mask]) = do_dither(&voodoo->params, colour_data, x >> 1, y); - if (write_mask & LFB_WRITE_DEPTH) - *(uint16_t *)(&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]) = depth_data; - } + skip_pixel: + x = x; + } + } else { + if (write_mask & LFB_WRITE_COLOUR) + *(uint16_t *)(&voodoo->fb_mem[write_addr & voodoo->fb_mask]) = + do_dither(&voodoo->params, colour_data, x >> 1, y); + if (write_mask & LFB_WRITE_DEPTH) + *(uint16_t *)(&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]) = depth_data; + } } void voodoo_fb_writel(uint32_t addr, uint32_t val, void *p) { - voodoo_t *voodoo = (voodoo_t *)p; - voodoo_params_t *params = &voodoo->params; - int x, y; - uint32_t write_addr, write_addr_aux; - rgba8_t colour_data[2]; - uint16_t depth_data[2]; - uint8_t alpha_data[2]; - int write_mask = 0, count = 1; + voodoo_t *voodoo = (voodoo_t *)p; + voodoo_params_t *params = &voodoo->params; + int x, y; + uint32_t write_addr, write_addr_aux; + rgba8_t colour_data[2]; + uint16_t depth_data[2]; + uint8_t alpha_data[2]; + int write_mask = 0, count = 1; - depth_data[0] = depth_data[1] = voodoo->params.zaColor & 0xffff; - alpha_data[0] = alpha_data[1] = voodoo->params.zaColor >> 24; -// while (!RB_EMPTY) -// thread_reset_event(voodoo->not_full_event); + depth_data[0] = depth_data[1] = voodoo->params.zaColor & 0xffff; + alpha_data[0] = alpha_data[1] = voodoo->params.zaColor >> 24; + // while (!RB_EMPTY) + // thread_reset_event(voodoo->not_full_event); -// pclog("voodoo_fb_writel : %08X %08X\n", addr, val); + // pclog("voodoo_fb_writel : %08X %08X\n", addr, val); - switch (voodoo->lfbMode & LFB_FORMAT_MASK) { - case LFB_FORMAT_RGB565:colour_data[0] = rgb565[val & 0xffff]; - colour_data[1] = rgb565[val >> 16]; - write_mask = LFB_WRITE_COLOUR; - count = 2; - break; - case LFB_FORMAT_RGB555:colour_data[0] = argb1555[val & 0xffff]; - colour_data[1] = argb1555[val >> 16]; - write_mask = LFB_WRITE_COLOUR; - count = 2; - break; - case LFB_FORMAT_ARGB1555:colour_data[0] = argb1555[val & 0xffff]; - alpha_data[0] = colour_data[0].a; - colour_data[1] = argb1555[val >> 16]; - alpha_data[1] = colour_data[1].a; - write_mask = LFB_WRITE_COLOUR; - count = 2; - break; + switch (voodoo->lfbMode & LFB_FORMAT_MASK) { + case LFB_FORMAT_RGB565: + colour_data[0] = rgb565[val & 0xffff]; + colour_data[1] = rgb565[val >> 16]; + write_mask = LFB_WRITE_COLOUR; + count = 2; + break; + case LFB_FORMAT_RGB555: + colour_data[0] = argb1555[val & 0xffff]; + colour_data[1] = argb1555[val >> 16]; + write_mask = LFB_WRITE_COLOUR; + count = 2; + break; + case LFB_FORMAT_ARGB1555: + colour_data[0] = argb1555[val & 0xffff]; + alpha_data[0] = colour_data[0].a; + colour_data[1] = argb1555[val >> 16]; + alpha_data[1] = colour_data[1].a; + write_mask = LFB_WRITE_COLOUR; + count = 2; + break; - case LFB_FORMAT_ARGB8888:colour_data[0].b = val & 0xff; - colour_data[0].g = (val >> 8) & 0xff; - colour_data[0].r = (val >> 16) & 0xff; - alpha_data[0] = (val >> 24) & 0xff; - write_mask = LFB_WRITE_COLOUR; - addr >>= 1; - break; + case LFB_FORMAT_ARGB8888: + colour_data[0].b = val & 0xff; + colour_data[0].g = (val >> 8) & 0xff; + colour_data[0].r = (val >> 16) & 0xff; + alpha_data[0] = (val >> 24) & 0xff; + write_mask = LFB_WRITE_COLOUR; + addr >>= 1; + break; - case LFB_FORMAT_DEPTH:depth_data[0] = val; - depth_data[1] = val >> 16; - write_mask = LFB_WRITE_DEPTH; - count = 2; - break; + case LFB_FORMAT_DEPTH: + depth_data[0] = val; + depth_data[1] = val >> 16; + write_mask = LFB_WRITE_DEPTH; + count = 2; + break; - default:fatal("voodoo_fb_writel : bad LFB format %08X\n", voodoo->lfbMode); - } + default: + fatal("voodoo_fb_writel : bad LFB format %08X\n", voodoo->lfbMode); + } - if (voodoo->type >= VOODOO_BANSHEE) { - x = addr & 0xffe; - y = (addr >> 12) & 0x3ff; - } else { - x = addr & 0x7fe; - y = (addr >> 11) & 0x3ff; - } + if (voodoo->type >= VOODOO_BANSHEE) { + x = addr & 0xffe; + y = (addr >> 12) & 0x3ff; + } else { + x = addr & 0x7fe; + y = (addr >> 11) & 0x3ff; + } - if (SLI_ENABLED) { - if ((!(voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && (y & 1)) || - ((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && !(y & 1))) - return; - y >>= 1; - } + if (SLI_ENABLED) { + if ((!(voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && (y & 1)) || + ((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && !(y & 1))) + return; + y >>= 1; + } - if (voodoo->fb_write_offset == voodoo->params.front_offset && y < 2048) - voodoo->dirty_line[y] = 1; + if (voodoo->fb_write_offset == voodoo->params.front_offset && y < 2048) + voodoo->dirty_line[y] = 1; - if (voodoo->col_tiled) - write_addr = voodoo->fb_write_offset + (x & 127) + (x >> 7) * 128 * 32 + (y & 31) * 128 + (y >> 5) * voodoo->row_width; - else - write_addr = voodoo->fb_write_offset + x + (y * voodoo->row_width); - if (voodoo->aux_tiled) - write_addr_aux = voodoo->params.aux_offset + (x & 127) + (x >> 7) * 128 * 32 + (y & 31) * 128 + (y >> 5) * voodoo->row_width; - else - write_addr_aux = voodoo->params.aux_offset + x + (y * voodoo->row_width); + if (voodoo->col_tiled) + write_addr = + voodoo->fb_write_offset + (x & 127) + (x >> 7) * 128 * 32 + (y & 31) * 128 + (y >> 5) * voodoo->row_width; + else + write_addr = voodoo->fb_write_offset + x + (y * voodoo->row_width); + if (voodoo->aux_tiled) + write_addr_aux = voodoo->params.aux_offset + (x & 127) + (x >> 7) * 128 * 32 + (y & 31) * 128 + + (y >> 5) * voodoo->row_width; + else + write_addr_aux = voodoo->params.aux_offset + x + (y * voodoo->row_width); -// pclog("fb_writel %08x x=%i y=%i rw=%i %08x wo=%08x\n", addr, x, y, voodoo->row_width, write_addr, voodoo->fb_write_offset); + // pclog("fb_writel %08x x=%i y=%i rw=%i %08x wo=%08x\n", addr, x, y, voodoo->row_width, write_addr, + // voodoo->fb_write_offset); - if (voodoo->lfbMode & 0x100) { - int c; + if (voodoo->lfbMode & 0x100) { + int c; - for (c = 0; c < count; c++) { - rgba8_t write_data = colour_data[c]; - uint16_t new_depth = depth_data[c]; + for (c = 0; c < count; c++) { + rgba8_t write_data = colour_data[c]; + uint16_t new_depth = depth_data[c]; - if (params->fbzMode & FBZ_DEPTH_ENABLE) { - uint16_t old_depth = *(uint16_t *)(&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]); + if (params->fbzMode & FBZ_DEPTH_ENABLE) { + uint16_t old_depth = *(uint16_t *)(&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]); - DEPTH_TEST(new_depth); - } + DEPTH_TEST(new_depth); + } - if ((params->fbzMode & FBZ_CHROMAKEY) && - write_data.r == params->chromaKey_r && - write_data.g == params->chromaKey_g && - write_data.b == params->chromaKey_b) - goto skip_pixel; + if ((params->fbzMode & FBZ_CHROMAKEY) && write_data.r == params->chromaKey_r && + write_data.g == params->chromaKey_g && write_data.b == params->chromaKey_b) + goto skip_pixel; - if (params->fogMode & FOG_ENABLE) { - int32_t z = new_depth << 12; - int64_t w_depth = new_depth; - int32_t ia = alpha_data[c] << 12; + if (params->fogMode & FOG_ENABLE) { + int32_t z = new_depth << 12; + int64_t w_depth = new_depth; + int32_t ia = alpha_data[c] << 12; - APPLY_FOG(write_data.r, write_data.g, write_data.b, z, ia, w_depth); - } + APPLY_FOG(write_data.r, write_data.g, write_data.b, z, ia, w_depth); + } - if (params->alphaMode & 1) - ALPHA_TEST(alpha_data[c]); + if (params->alphaMode & 1) + ALPHA_TEST(alpha_data[c]); - if (params->alphaMode & (1 << 4)) { - uint16_t dat = *(uint16_t *)(&voodoo->fb_mem[write_addr & voodoo->fb_mask]); - int dest_r, dest_g, dest_b, dest_a; + if (params->alphaMode & (1 << 4)) { + uint16_t dat = *(uint16_t *)(&voodoo->fb_mem[write_addr & voodoo->fb_mask]); + int dest_r, dest_g, dest_b, dest_a; - dest_r = (dat >> 8) & 0xf8; - dest_g = (dat >> 3) & 0xfc; - dest_b = (dat << 3) & 0xf8; - dest_r |= (dest_r >> 5); - dest_g |= (dest_g >> 6); - dest_b |= (dest_b >> 5); - dest_a = 0xff; + dest_r = (dat >> 8) & 0xf8; + dest_g = (dat >> 3) & 0xfc; + dest_b = (dat << 3) & 0xf8; + dest_r |= (dest_r >> 5); + dest_g |= (dest_g >> 6); + dest_b |= (dest_b >> 5); + dest_a = 0xff; - ALPHA_BLEND(write_data.r, write_data.g, write_data.b, alpha_data[c]); - } + ALPHA_BLEND(write_data.r, write_data.g, write_data.b, alpha_data[c]); + } - if (params->fbzMode & FBZ_RGB_WMASK) - *(uint16_t *)(&voodoo->fb_mem[write_addr & voodoo->fb_mask]) = do_dither(&voodoo->params, write_data, (x >> 1) + c, y); - if (params->fbzMode & FBZ_DEPTH_WMASK) - *(uint16_t *)(&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]) = new_depth; + if (params->fbzMode & FBZ_RGB_WMASK) + *(uint16_t *)(&voodoo->fb_mem[write_addr & voodoo->fb_mask]) = + do_dither(&voodoo->params, write_data, (x >> 1) + c, y); + if (params->fbzMode & FBZ_DEPTH_WMASK) + *(uint16_t *)(&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]) = new_depth; - skip_pixel: - write_addr += 2; - write_addr_aux += 2; - } - } else { - int c; + skip_pixel: + write_addr += 2; + write_addr_aux += 2; + } + } else { + int c; - for (c = 0; c < count; c++) { - if (write_mask & LFB_WRITE_COLOUR) - *(uint16_t *)(&voodoo->fb_mem[write_addr & voodoo->fb_mask]) = do_dither(&voodoo->params, colour_data[c], (x >> 1) + c, y); - if (write_mask & LFB_WRITE_DEPTH) - *(uint16_t *)(&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]) = depth_data[c]; + for (c = 0; c < count; c++) { + if (write_mask & LFB_WRITE_COLOUR) + *(uint16_t *)(&voodoo->fb_mem[write_addr & voodoo->fb_mask]) = + do_dither(&voodoo->params, colour_data[c], (x >> 1) + c, y); + if (write_mask & LFB_WRITE_DEPTH) + *(uint16_t *)(&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]) = depth_data[c]; - write_addr += 2; - write_addr_aux += 2; - } - } + write_addr += 2; + write_addr_aux += 2; + } + } } diff --git a/src/video/vid_voodoo_fifo.c b/src/video/vid_voodoo_fifo.c index f3b505b4..f6a1745a 100644 --- a/src/video/vid_voodoo_fifo.c +++ b/src/video/vid_voodoo_fifo.c @@ -18,420 +18,445 @@ #define WAKE_DELAY (TIMER_USEC * 100) void voodoo_wake_fifo_thread(voodoo_t *voodoo) { - if (!timer_is_enabled(&voodoo->wake_timer)) { - /*Don't wake FIFO thread immediately - if we do that it will probably - process one word and go back to sleep, requiring it to be woken on - almost every write. Instead, wait a short while so that the CPU - emulation writes more data so we have more batched-up work.*/ - timer_set_delay_u64(&voodoo->wake_timer, WAKE_DELAY); - } + if (!timer_is_enabled(&voodoo->wake_timer)) { + /*Don't wake FIFO thread immediately - if we do that it will probably + process one word and go back to sleep, requiring it to be woken on + almost every write. Instead, wait a short while so that the CPU + emulation writes more data so we have more batched-up work.*/ + timer_set_delay_u64(&voodoo->wake_timer, WAKE_DELAY); + } } void voodoo_wake_fifo_thread_now(voodoo_t *voodoo) { - thread_set_event(voodoo->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ + thread_set_event(voodoo->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ } void voodoo_wake_timer(void *p) { - voodoo_t *voodoo = (voodoo_t *)p; + voodoo_t *voodoo = (voodoo_t *)p; - thread_set_event(voodoo->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ + thread_set_event(voodoo->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ } void voodoo_queue_command(voodoo_t *voodoo, uint32_t addr_type, uint32_t val) { - fifo_entry_t *fifo = &voodoo->fifo[voodoo->fifo_write_idx & FIFO_MASK]; + fifo_entry_t *fifo = &voodoo->fifo[voodoo->fifo_write_idx & FIFO_MASK]; - while (FIFO_FULL) { - thread_reset_event(voodoo->fifo_not_full_event); - if (FIFO_FULL) { - thread_wait_event(voodoo->fifo_not_full_event, 1); /*Wait for room in ringbuffer*/ - if (FIFO_FULL) - voodoo_wake_fifo_thread_now(voodoo); - } - } + while (FIFO_FULL) { + thread_reset_event(voodoo->fifo_not_full_event); + if (FIFO_FULL) { + thread_wait_event(voodoo->fifo_not_full_event, 1); /*Wait for room in ringbuffer*/ + if (FIFO_FULL) + voodoo_wake_fifo_thread_now(voodoo); + } + } - fifo->val = val; - fifo->addr_type = addr_type; + fifo->val = val; + fifo->addr_type = addr_type; - voodoo->fifo_write_idx++; + voodoo->fifo_write_idx++; - if (FIFO_ENTRIES > 0xe000) - voodoo_wake_fifo_thread(voodoo); + if (FIFO_ENTRIES > 0xe000) + voodoo_wake_fifo_thread(voodoo); } void voodoo_flush(voodoo_t *voodoo) { - voodoo->flush = 1; - while (!FIFO_EMPTY) { - voodoo_wake_fifo_thread_now(voodoo); - thread_wait_event(voodoo->fifo_not_full_event, 1); - } - voodoo_wait_for_render_thread_idle(voodoo); - voodoo->flush = 0; + voodoo->flush = 1; + while (!FIFO_EMPTY) { + voodoo_wake_fifo_thread_now(voodoo); + thread_wait_event(voodoo->fifo_not_full_event, 1); + } + voodoo_wait_for_render_thread_idle(voodoo); + voodoo->flush = 0; } void voodoo_wake_fifo_threads(voodoo_set_t *set, voodoo_t *voodoo) { - voodoo_wake_fifo_thread(voodoo); - if (SLI_ENABLED && voodoo->type != VOODOO_2 && set->voodoos[0] == voodoo) - voodoo_wake_fifo_thread(set->voodoos[1]); + voodoo_wake_fifo_thread(voodoo); + if (SLI_ENABLED && voodoo->type != VOODOO_2 && set->voodoos[0] == voodoo) + voodoo_wake_fifo_thread(set->voodoos[1]); } void voodoo_wait_for_swap_complete(voodoo_t *voodoo) { - while (voodoo->swap_pending) { - thread_wait_event(voodoo->wake_fifo_thread, -1); - thread_reset_event(voodoo->wake_fifo_thread); + while (voodoo->swap_pending) { + thread_wait_event(voodoo->wake_fifo_thread, -1); + thread_reset_event(voodoo->wake_fifo_thread); - thread_lock_mutex(voodoo->swap_mutex); - if ((voodoo->swap_pending && voodoo->flush) || FIFO_FULL) { - /*Main thread is waiting for FIFO to empty, so skip vsync wait and just swap*/ - memset(voodoo->dirty_line, 1, sizeof(voodoo->dirty_line)); - voodoo->front_offset = voodoo->params.front_offset; - if (voodoo->swap_count > 0) - voodoo->swap_count--; - voodoo->swap_pending = 0; - thread_unlock_mutex(voodoo->swap_mutex); - break; - } else - thread_unlock_mutex(voodoo->swap_mutex); - } + thread_lock_mutex(voodoo->swap_mutex); + if ((voodoo->swap_pending && voodoo->flush) || FIFO_FULL) { + /*Main thread is waiting for FIFO to empty, so skip vsync wait and just swap*/ + memset(voodoo->dirty_line, 1, sizeof(voodoo->dirty_line)); + voodoo->front_offset = voodoo->params.front_offset; + if (voodoo->swap_count > 0) + voodoo->swap_count--; + voodoo->swap_pending = 0; + thread_unlock_mutex(voodoo->swap_mutex); + break; + } else + thread_unlock_mutex(voodoo->swap_mutex); + } } static uint32_t cmdfifo_get(voodoo_t *voodoo) { - uint32_t val; + uint32_t val; - if (!voodoo->cmdfifo_in_sub) { - while (voodoo->cmdfifo_depth_rd == voodoo->cmdfifo_depth_wr) { - thread_wait_event(voodoo->wake_fifo_thread, -1); - thread_reset_event(voodoo->wake_fifo_thread); - } - } + if (!voodoo->cmdfifo_in_sub) { + while (voodoo->cmdfifo_depth_rd == voodoo->cmdfifo_depth_wr) { + thread_wait_event(voodoo->wake_fifo_thread, -1); + thread_reset_event(voodoo->wake_fifo_thread); + } + } - val = *(uint32_t *)&voodoo->fb_mem[voodoo->cmdfifo_rp & voodoo->fb_mask]; + val = *(uint32_t *)&voodoo->fb_mem[voodoo->cmdfifo_rp & voodoo->fb_mask]; - if (!voodoo->cmdfifo_in_sub) - voodoo->cmdfifo_depth_rd++; - voodoo->cmdfifo_rp += 4; + if (!voodoo->cmdfifo_in_sub) + voodoo->cmdfifo_depth_rd++; + voodoo->cmdfifo_rp += 4; -// pclog(" CMDFIFO get %08x\n", val); - return val; + // pclog(" CMDFIFO get %08x\n", val); + return val; } static inline float cmdfifo_get_f(voodoo_t *voodoo) { - union { - uint32_t i; - float f; - } tempif; + union { + uint32_t i; + float f; + } tempif; - tempif.i = cmdfifo_get(voodoo); - return tempif.f; + tempif.i = cmdfifo_get(voodoo); + return tempif.f; } enum { - CMDFIFO3_PC_MASK_RGB = (1 << 10), - CMDFIFO3_PC_MASK_ALPHA = (1 << 11), - CMDFIFO3_PC_MASK_Z = (1 << 12), - CMDFIFO3_PC_MASK_Wb = (1 << 13), - CMDFIFO3_PC_MASK_W0 = (1 << 14), - CMDFIFO3_PC_MASK_S0_T0 = (1 << 15), - CMDFIFO3_PC_MASK_W1 = (1 << 16), - CMDFIFO3_PC_MASK_S1_T1 = (1 << 17), + CMDFIFO3_PC_MASK_RGB = (1 << 10), + CMDFIFO3_PC_MASK_ALPHA = (1 << 11), + CMDFIFO3_PC_MASK_Z = (1 << 12), + CMDFIFO3_PC_MASK_Wb = (1 << 13), + CMDFIFO3_PC_MASK_W0 = (1 << 14), + CMDFIFO3_PC_MASK_S0_T0 = (1 << 15), + CMDFIFO3_PC_MASK_W1 = (1 << 16), + CMDFIFO3_PC_MASK_S1_T1 = (1 << 17), - CMDFIFO3_PC = (1 << 28) + CMDFIFO3_PC = (1 << 28) }; void voodoo_fifo_thread(void *param) { - voodoo_t *voodoo = (voodoo_t *)param; + voodoo_t *voodoo = (voodoo_t *)param; - while (1) { - thread_set_event(voodoo->fifo_not_full_event); - thread_wait_event(voodoo->wake_fifo_thread, -1); - thread_reset_event(voodoo->wake_fifo_thread); - voodoo->voodoo_busy = 1; - while (!FIFO_EMPTY) { - uint64_t start_time = timer_read(); - uint64_t end_time; - fifo_entry_t *fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK]; + while (1) { + thread_set_event(voodoo->fifo_not_full_event); + thread_wait_event(voodoo->wake_fifo_thread, -1); + thread_reset_event(voodoo->wake_fifo_thread); + voodoo->voodoo_busy = 1; + while (!FIFO_EMPTY) { + uint64_t start_time = timer_read(); + uint64_t end_time; + fifo_entry_t *fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK]; - switch (fifo->addr_type & FIFO_TYPE) { - case FIFO_WRITEL_REG: - while ((fifo->addr_type & FIFO_TYPE) == FIFO_WRITEL_REG) { - voodoo_reg_writel(fifo->addr_type & FIFO_ADDR, fifo->val, voodoo); - fifo->addr_type = FIFO_INVALID; - voodoo->fifo_read_idx++; - if (FIFO_EMPTY) - break; - fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK]; - } - break; - case FIFO_WRITEW_FB:voodoo_wait_for_render_thread_idle(voodoo); - while ((fifo->addr_type & FIFO_TYPE) == FIFO_WRITEW_FB) { - voodoo_fb_writew(fifo->addr_type & FIFO_ADDR, fifo->val, voodoo); - fifo->addr_type = FIFO_INVALID; - voodoo->fifo_read_idx++; - if (FIFO_EMPTY) - break; - fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK]; - } - break; - case FIFO_WRITEL_FB:voodoo_wait_for_render_thread_idle(voodoo); - while ((fifo->addr_type & FIFO_TYPE) == FIFO_WRITEL_FB) { - voodoo_fb_writel(fifo->addr_type & FIFO_ADDR, fifo->val, voodoo); - fifo->addr_type = FIFO_INVALID; - voodoo->fifo_read_idx++; - if (FIFO_EMPTY) - break; - fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK]; - } - break; - case FIFO_WRITEL_TEX: - while ((fifo->addr_type & FIFO_TYPE) == FIFO_WRITEL_TEX) { - if (!(fifo->addr_type & 0x400000)) - voodoo_tex_writel(fifo->addr_type & FIFO_ADDR, fifo->val, voodoo); - fifo->addr_type = FIFO_INVALID; - voodoo->fifo_read_idx++; - if (FIFO_EMPTY) - break; - fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK]; - } - break; - case FIFO_WRITEL_2DREG: - while ((fifo->addr_type & FIFO_TYPE) == FIFO_WRITEL_2DREG) { - voodoo_2d_reg_writel(voodoo, fifo->addr_type & FIFO_ADDR, fifo->val); - fifo->addr_type = FIFO_INVALID; - voodoo->fifo_read_idx++; - if (FIFO_EMPTY) - break; - fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK]; - } - break; + switch (fifo->addr_type & FIFO_TYPE) { + case FIFO_WRITEL_REG: + while ((fifo->addr_type & FIFO_TYPE) == FIFO_WRITEL_REG) { + voodoo_reg_writel(fifo->addr_type & FIFO_ADDR, fifo->val, voodoo); + fifo->addr_type = FIFO_INVALID; + voodoo->fifo_read_idx++; + if (FIFO_EMPTY) + break; + fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK]; + } + break; + case FIFO_WRITEW_FB: + voodoo_wait_for_render_thread_idle(voodoo); + while ((fifo->addr_type & FIFO_TYPE) == FIFO_WRITEW_FB) { + voodoo_fb_writew(fifo->addr_type & FIFO_ADDR, fifo->val, voodoo); + fifo->addr_type = FIFO_INVALID; + voodoo->fifo_read_idx++; + if (FIFO_EMPTY) + break; + fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK]; + } + break; + case FIFO_WRITEL_FB: + voodoo_wait_for_render_thread_idle(voodoo); + while ((fifo->addr_type & FIFO_TYPE) == FIFO_WRITEL_FB) { + voodoo_fb_writel(fifo->addr_type & FIFO_ADDR, fifo->val, voodoo); + fifo->addr_type = FIFO_INVALID; + voodoo->fifo_read_idx++; + if (FIFO_EMPTY) + break; + fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK]; + } + break; + case FIFO_WRITEL_TEX: + while ((fifo->addr_type & FIFO_TYPE) == FIFO_WRITEL_TEX) { + if (!(fifo->addr_type & 0x400000)) + voodoo_tex_writel(fifo->addr_type & FIFO_ADDR, fifo->val, voodoo); + fifo->addr_type = FIFO_INVALID; + voodoo->fifo_read_idx++; + if (FIFO_EMPTY) + break; + fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK]; + } + break; + case FIFO_WRITEL_2DREG: + while ((fifo->addr_type & FIFO_TYPE) == FIFO_WRITEL_2DREG) { + voodoo_2d_reg_writel(voodoo, fifo->addr_type & FIFO_ADDR, fifo->val); + fifo->addr_type = FIFO_INVALID; + voodoo->fifo_read_idx++; + if (FIFO_EMPTY) + break; + fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK]; + } + break; - default:fatal("Unknown fifo entry %08x\n", fifo->addr_type); - } + default: + fatal("Unknown fifo entry %08x\n", fifo->addr_type); + } - if (FIFO_ENTRIES > 0xe000) - thread_set_event(voodoo->fifo_not_full_event); + if (FIFO_ENTRIES > 0xe000) + thread_set_event(voodoo->fifo_not_full_event); - end_time = timer_read(); - voodoo->time += end_time - start_time; - } + end_time = timer_read(); + voodoo->time += end_time - start_time; + } - while (voodoo->cmdfifo_enabled && (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr || voodoo->cmdfifo_in_sub)) { - uint64_t start_time = timer_read(); - uint64_t end_time; - uint32_t header = cmdfifo_get(voodoo); - uint32_t addr; - uint32_t mask; - int smode; - int num; - int num_verticies; - int v_num; + while (voodoo->cmdfifo_enabled && + (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr || voodoo->cmdfifo_in_sub)) { + uint64_t start_time = timer_read(); + uint64_t end_time; + uint32_t header = cmdfifo_get(voodoo); + uint32_t addr; + uint32_t mask; + int smode; + int num; + int num_verticies; + int v_num; -// pclog(" CMDFIFO header %08x at %08x\n", header, voodoo->cmdfifo_rp); + // pclog(" CMDFIFO header %08x at %08x\n", header, voodoo->cmdfifo_rp); - switch (header & 7) { - case 0: -// pclog("CMDFIFO0\n"); - switch ((header >> 3) & 7) { - case 0: /*NOP*/ - break; + switch (header & 7) { + case 0: + // pclog("CMDFIFO0\n"); + switch ((header >> 3) & 7) { + case 0: /*NOP*/ + break; - case 1: /*JSR*/ -// pclog("JSR %08x\n", (header >> 4) & 0xfffffc); - voodoo->cmdfifo_ret_addr = voodoo->cmdfifo_rp; - voodoo->cmdfifo_rp = (header >> 4) & 0xfffffc; - voodoo->cmdfifo_in_sub = 1; - break; + case 1: /*JSR*/ + // pclog("JSR %08x\n", (header >> 4) & 0xfffffc); + voodoo->cmdfifo_ret_addr = voodoo->cmdfifo_rp; + voodoo->cmdfifo_rp = (header >> 4) & 0xfffffc; + voodoo->cmdfifo_in_sub = 1; + break; - case 2: /*RET*/ - voodoo->cmdfifo_rp = voodoo->cmdfifo_ret_addr; - voodoo->cmdfifo_in_sub = 0; - break; + case 2: /*RET*/ + voodoo->cmdfifo_rp = voodoo->cmdfifo_ret_addr; + voodoo->cmdfifo_in_sub = 0; + break; - case 3: /*JMP local frame buffer*/ - voodoo->cmdfifo_rp = (header >> 4) & 0xfffffc; -// pclog("JMP to %08x %04x\n", voodoo->cmdfifo_rp, header); - break; + case 3: /*JMP local frame buffer*/ + voodoo->cmdfifo_rp = (header >> 4) & 0xfffffc; + // pclog("JMP to %08x %04x\n", voodoo->cmdfifo_rp, + // header); + break; - default:fatal("Bad CMDFIFO0 %08x\n", header); - } - break; + default: + fatal("Bad CMDFIFO0 %08x\n", header); + } + break; - case 1:num = header >> 16; - addr = (header & 0x7ff8) >> 1; -// pclog("CMDFIFO1 addr=%08x\n",addr); - while (num--) { - uint32_t val = cmdfifo_get(voodoo); - if ((addr & (1 << 13)) && voodoo->type >= VOODOO_BANSHEE) { -// if (voodoo->type != VOODOO_BANSHEE) -// fatal("CMDFIFO1: Not Banshee\n"); -// pclog("CMDFIFO1: write %08x %08x\n", addr, val); - voodoo_2d_reg_writel(voodoo, addr, val); - } else { - if ((addr & 0x3ff) == SST_triangleCMD || (addr & 0x3ff) == SST_ftriangleCMD || - (addr & 0x3ff) == SST_fastfillCMD || (addr & 0x3ff) == SST_nopCMD) - voodoo->cmd_written_fifo++; + case 1: + num = header >> 16; + addr = (header & 0x7ff8) >> 1; + // pclog("CMDFIFO1 addr=%08x\n",addr); + while (num--) { + uint32_t val = cmdfifo_get(voodoo); + if ((addr & (1 << 13)) && voodoo->type >= VOODOO_BANSHEE) { + // if (voodoo->type != + // VOODOO_BANSHEE) + // fatal("CMDFIFO1: Not + // Banshee\n"); + // pclog("CMDFIFO1: write %08x + // %08x\n", addr, val); + voodoo_2d_reg_writel(voodoo, addr, val); + } else { + if ((addr & 0x3ff) == SST_triangleCMD || (addr & 0x3ff) == SST_ftriangleCMD || + (addr & 0x3ff) == SST_fastfillCMD || (addr & 0x3ff) == SST_nopCMD) + voodoo->cmd_written_fifo++; - if (voodoo->type >= VOODOO_BANSHEE && (addr & 0x3ff) == SST_swapbufferCMD) - voodoo->cmd_written_fifo++; - voodoo_reg_writel(addr, val, voodoo); - } + if (voodoo->type >= VOODOO_BANSHEE && (addr & 0x3ff) == SST_swapbufferCMD) + voodoo->cmd_written_fifo++; + voodoo_reg_writel(addr, val, voodoo); + } - if (header & (1 << 15)) - addr += 4; - } - break; + if (header & (1 << 15)) + addr += 4; + } + break; - case 2: - if (voodoo->type < VOODOO_BANSHEE) - fatal("CMDFIFO2: Not Banshee\n"); - mask = (header >> 3); - addr = 8; - while (mask) { - if (mask & 1) { - uint32_t val = cmdfifo_get(voodoo); + case 2: + if (voodoo->type < VOODOO_BANSHEE) + fatal("CMDFIFO2: Not Banshee\n"); + mask = (header >> 3); + addr = 8; + while (mask) { + if (mask & 1) { + uint32_t val = cmdfifo_get(voodoo); - voodoo_2d_reg_writel(voodoo, addr, val); - } + voodoo_2d_reg_writel(voodoo, addr, val); + } - addr += 4; - mask >>= 1; - } - break; + addr += 4; + mask >>= 1; + } + break; - case 3:num = (header >> 29) & 7; - mask = header;//(header >> 10) & 0xff; - smode = (header >> 22) & 0xf; - voodoo_reg_writel(SST_sSetupMode, ((header >> 10) & 0xff) | (smode << 16), voodoo); - num_verticies = (header >> 6) & 0xf; - v_num = 0; - if (((header >> 3) & 7) == 2) - v_num = 1; -// pclog("CMDFIFO3: num=%i verts=%i mask=%02x\n", num, num_verticies, (header >> 10) & 0xff); -// pclog("CMDFIFO3 %02x %i\n", (header >> 10), (header >> 3) & 7); + case 3: + num = (header >> 29) & 7; + mask = header; //(header >> 10) & 0xff; + smode = (header >> 22) & 0xf; + voodoo_reg_writel(SST_sSetupMode, ((header >> 10) & 0xff) | (smode << 16), voodoo); + num_verticies = (header >> 6) & 0xf; + v_num = 0; + if (((header >> 3) & 7) == 2) + v_num = 1; + // pclog("CMDFIFO3: num=%i verts=%i mask=%02x\n", num, + // num_verticies, (header >> 10) & 0xff); pclog("CMDFIFO3 %02x + // %i\n", (header >> 10), (header >> 3) & 7); - while (num_verticies--) { - voodoo->verts[3].sVx = cmdfifo_get_f(voodoo); - voodoo->verts[3].sVy = cmdfifo_get_f(voodoo); - if (mask & CMDFIFO3_PC_MASK_RGB) { - if (header & CMDFIFO3_PC) { - uint32_t val = cmdfifo_get(voodoo); - voodoo->verts[3].sBlue = (float)(val & 0xff); - voodoo->verts[3].sGreen = (float)((val >> 8) & 0xff); - voodoo->verts[3].sRed = (float)((val >> 16) & 0xff); - voodoo->verts[3].sAlpha = (float)((val >> 24) & 0xff); - } else { - voodoo->verts[3].sRed = cmdfifo_get_f(voodoo); - voodoo->verts[3].sGreen = cmdfifo_get_f(voodoo); - voodoo->verts[3].sBlue = cmdfifo_get_f(voodoo); - } - } - if ((mask & CMDFIFO3_PC_MASK_ALPHA) && !(header & CMDFIFO3_PC)) - voodoo->verts[3].sAlpha = cmdfifo_get_f(voodoo); - if (mask & CMDFIFO3_PC_MASK_Z) - voodoo->verts[3].sVz = cmdfifo_get_f(voodoo); - if (mask & CMDFIFO3_PC_MASK_Wb) - voodoo->verts[3].sWb = cmdfifo_get_f(voodoo); - if (mask & CMDFIFO3_PC_MASK_W0) - voodoo->verts[3].sW0 = cmdfifo_get_f(voodoo); - if (mask & CMDFIFO3_PC_MASK_S0_T0) { - voodoo->verts[3].sS0 = cmdfifo_get_f(voodoo); - voodoo->verts[3].sT0 = cmdfifo_get_f(voodoo); - } - if (mask & CMDFIFO3_PC_MASK_W1) - voodoo->verts[3].sW1 = cmdfifo_get_f(voodoo); - if (mask & CMDFIFO3_PC_MASK_S1_T1) { - voodoo->verts[3].sS1 = cmdfifo_get_f(voodoo); - voodoo->verts[3].sT1 = cmdfifo_get_f(voodoo); - } - if (v_num) - voodoo_reg_writel(SST_sDrawTriCMD, 0, voodoo); - else - voodoo_reg_writel(SST_sBeginTriCMD, 0, voodoo); - v_num++; - if (v_num == 3 && ((header >> 3) & 7) == 0) - v_num = 0; - } - break; + while (num_verticies--) { + voodoo->verts[3].sVx = cmdfifo_get_f(voodoo); + voodoo->verts[3].sVy = cmdfifo_get_f(voodoo); + if (mask & CMDFIFO3_PC_MASK_RGB) { + if (header & CMDFIFO3_PC) { + uint32_t val = cmdfifo_get(voodoo); + voodoo->verts[3].sBlue = (float)(val & 0xff); + voodoo->verts[3].sGreen = (float)((val >> 8) & 0xff); + voodoo->verts[3].sRed = (float)((val >> 16) & 0xff); + voodoo->verts[3].sAlpha = (float)((val >> 24) & 0xff); + } else { + voodoo->verts[3].sRed = cmdfifo_get_f(voodoo); + voodoo->verts[3].sGreen = cmdfifo_get_f(voodoo); + voodoo->verts[3].sBlue = cmdfifo_get_f(voodoo); + } + } + if ((mask & CMDFIFO3_PC_MASK_ALPHA) && !(header & CMDFIFO3_PC)) + voodoo->verts[3].sAlpha = cmdfifo_get_f(voodoo); + if (mask & CMDFIFO3_PC_MASK_Z) + voodoo->verts[3].sVz = cmdfifo_get_f(voodoo); + if (mask & CMDFIFO3_PC_MASK_Wb) + voodoo->verts[3].sWb = cmdfifo_get_f(voodoo); + if (mask & CMDFIFO3_PC_MASK_W0) + voodoo->verts[3].sW0 = cmdfifo_get_f(voodoo); + if (mask & CMDFIFO3_PC_MASK_S0_T0) { + voodoo->verts[3].sS0 = cmdfifo_get_f(voodoo); + voodoo->verts[3].sT0 = cmdfifo_get_f(voodoo); + } + if (mask & CMDFIFO3_PC_MASK_W1) + voodoo->verts[3].sW1 = cmdfifo_get_f(voodoo); + if (mask & CMDFIFO3_PC_MASK_S1_T1) { + voodoo->verts[3].sS1 = cmdfifo_get_f(voodoo); + voodoo->verts[3].sT1 = cmdfifo_get_f(voodoo); + } + if (v_num) + voodoo_reg_writel(SST_sDrawTriCMD, 0, voodoo); + else + voodoo_reg_writel(SST_sBeginTriCMD, 0, voodoo); + v_num++; + if (v_num == 3 && ((header >> 3) & 7) == 0) + v_num = 0; + } + break; - case 4:num = (header >> 29) & 7; - mask = (header >> 15) & 0x3fff; - addr = (header & 0x7ff8) >> 1; -// pclog("CMDFIFO4 addr=%08x\n",addr); - while (mask) { - if (mask & 1) { - uint32_t val = cmdfifo_get(voodoo); + case 4: + num = (header >> 29) & 7; + mask = (header >> 15) & 0x3fff; + addr = (header & 0x7ff8) >> 1; + // pclog("CMDFIFO4 addr=%08x\n",addr); + while (mask) { + if (mask & 1) { + uint32_t val = cmdfifo_get(voodoo); - if ((addr & (1 << 13)) && voodoo->type >= VOODOO_BANSHEE) { - if (voodoo->type < VOODOO_BANSHEE) - fatal("CMDFIFO1: Not Banshee\n"); -// pclog("CMDFIFO1: write %08x %08x\n", addr, val); - voodoo_2d_reg_writel(voodoo, addr, val); - } else { - if ((addr & 0x3ff) == SST_triangleCMD || (addr & 0x3ff) == SST_ftriangleCMD || - (addr & 0x3ff) == SST_fastfillCMD || (addr & 0x3ff) == SST_nopCMD) - voodoo->cmd_written_fifo++; + if ((addr & (1 << 13)) && voodoo->type >= VOODOO_BANSHEE) { + if (voodoo->type < VOODOO_BANSHEE) + fatal("CMDFIFO1: Not Banshee\n"); + // pclog("CMDFIFO1: write + // %08x %08x\n", addr, + // val); + voodoo_2d_reg_writel(voodoo, addr, val); + } else { + if ((addr & 0x3ff) == SST_triangleCMD || + (addr & 0x3ff) == SST_ftriangleCMD || + (addr & 0x3ff) == SST_fastfillCMD || (addr & 0x3ff) == SST_nopCMD) + voodoo->cmd_written_fifo++; - if (voodoo->type >= VOODOO_BANSHEE && (addr & 0x3ff) == SST_swapbufferCMD) - voodoo->cmd_written_fifo++; - voodoo_reg_writel(addr, val, voodoo); - } - } + if (voodoo->type >= VOODOO_BANSHEE && (addr & 0x3ff) == SST_swapbufferCMD) + voodoo->cmd_written_fifo++; + voodoo_reg_writel(addr, val, voodoo); + } + } - addr += 4; - mask >>= 1; - } - while (num--) - cmdfifo_get(voodoo); - break; + addr += 4; + mask >>= 1; + } + while (num--) + cmdfifo_get(voodoo); + break; - case 5: -// if (header & 0x3fc00000) -// fatal("CMDFIFO packet 5 has byte disables set %08x\n", header); - num = (header >> 3) & 0x7ffff; - addr = cmdfifo_get(voodoo) & 0xffffff; - if (!num) - num = 1; -// pclog("CMDFIFO5 addr=%08x num=%i\n", addr, num); - switch (header >> 30) { - case 0: /*Linear framebuffer (Banshee)*/ - if (voodoo->texture_present[0][(addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT]) { -// pclog("texture_present at %08x %i\n", addr, (addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT); - flush_texture_cache(voodoo, addr & voodoo->texture_mask, 0); - } - if (voodoo->texture_present[1][(addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT]) { -// pclog("texture_present at %08x %i\n", addr, (addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT); - flush_texture_cache(voodoo, addr & voodoo->texture_mask, 1); - } - while (num--) { - uint32_t val = cmdfifo_get(voodoo); - if (addr <= voodoo->fb_mask) - *(uint32_t *)&voodoo->fb_mem[addr] = val; - addr += 4; - } - break; - case 2: /*Framebuffer*/ - while (num--) { - uint32_t val = cmdfifo_get(voodoo); - voodoo_fb_writel(addr, val, voodoo); - addr += 4; - } - break; - case 3: /*Texture*/ - while (num--) { - uint32_t val = cmdfifo_get(voodoo); - voodoo_tex_writel(addr, val, voodoo); - addr += 4; - } - break; + case 5: + // if (header & 0x3fc00000) + // fatal("CMDFIFO packet 5 has byte disables set %08x\n", + // header); + num = (header >> 3) & 0x7ffff; + addr = cmdfifo_get(voodoo) & 0xffffff; + if (!num) + num = 1; + // pclog("CMDFIFO5 addr=%08x num=%i\n", addr, num); + switch (header >> 30) { + case 0: /*Linear framebuffer (Banshee)*/ + if (voodoo->texture_present[0][(addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT]) { + // pclog("texture_present at %08x + // %i\n", addr, (addr & + // voodoo->texture_mask) >> + // TEX_DIRTY_SHIFT); + flush_texture_cache(voodoo, addr & voodoo->texture_mask, 0); + } + if (voodoo->texture_present[1][(addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT]) { + // pclog("texture_present at %08x + // %i\n", addr, (addr & + // voodoo->texture_mask) >> + // TEX_DIRTY_SHIFT); + flush_texture_cache(voodoo, addr & voodoo->texture_mask, 1); + } + while (num--) { + uint32_t val = cmdfifo_get(voodoo); + if (addr <= voodoo->fb_mask) + *(uint32_t *)&voodoo->fb_mem[addr] = val; + addr += 4; + } + break; + case 2: /*Framebuffer*/ + while (num--) { + uint32_t val = cmdfifo_get(voodoo); + voodoo_fb_writel(addr, val, voodoo); + addr += 4; + } + break; + case 3: /*Texture*/ + while (num--) { + uint32_t val = cmdfifo_get(voodoo); + voodoo_tex_writel(addr, val, voodoo); + addr += 4; + } + break; - default:fatal("CMDFIFO packet 5 bad space %08x %08x\n", header, voodoo->cmdfifo_rp); - } - break; + default: + fatal("CMDFIFO packet 5 bad space %08x %08x\n", header, voodoo->cmdfifo_rp); + } + break; - default:fatal("Bad CMDFIFO packet %08x %08x\n", header, voodoo->cmdfifo_rp); - } + default: + fatal("Bad CMDFIFO packet %08x %08x\n", header, voodoo->cmdfifo_rp); + } - end_time = timer_read(); - voodoo->time += end_time - start_time; - } - voodoo->voodoo_busy = 0; - } + end_time = timer_read(); + voodoo->time += end_time - start_time; + } + voodoo->voodoo_busy = 0; + } } diff --git a/src/video/vid_voodoo_reg.c b/src/video/vid_voodoo_reg.c index 8a1a7d9e..c6b540e0 100644 --- a/src/video/vid_voodoo_reg.c +++ b/src/video/vid_voodoo_reg.c @@ -18,1172 +18,1267 @@ #include "vid_voodoo_setup.h" #include "vid_voodoo_texture.h" -enum { - CHIP_FBI = 0x1, - CHIP_TREX0 = 0x2, - CHIP_TREX1 = 0x4, - CHIP_TREX2 = 0x8 -}; +enum { CHIP_FBI = 0x1, CHIP_TREX0 = 0x2, CHIP_TREX1 = 0x4, CHIP_TREX2 = 0x8 }; void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) { - voodoo_t *voodoo = (voodoo_t *)p; - union { - uint32_t i; - float f; - } tempif; - int ad21 = addr & (1 << 21); - int chip = (addr >> 10) & 0xf; - if (!chip) - chip = 0xf; + voodoo_t *voodoo = (voodoo_t *)p; + union { + uint32_t i; + float f; + } tempif; + int ad21 = addr & (1 << 21); + int chip = (addr >> 10) & 0xf; + if (!chip) + chip = 0xf; - tempif.i = val; -//pclog("voodoo_reg_write_l: addr=%08x val=%08x(%f) chip=%x\n", addr, val, tempif.f, chip); - addr &= 0x3fc; + tempif.i = val; + // pclog("voodoo_reg_write_l: addr=%08x val=%08x(%f) chip=%x\n", addr, val, tempif.f, chip); + addr &= 0x3fc; - if ((voodoo->fbiInit3 & FBIINIT3_REMAP) && addr < 0x100 && ad21) - addr |= 0x400; - switch (addr) { - case SST_swapbufferCMD: - if (voodoo->type >= VOODOO_BANSHEE) { -// pclog("swapbufferCMD %08x %08x\n", val, voodoo->leftOverlayBuf); + if ((voodoo->fbiInit3 & FBIINIT3_REMAP) && addr < 0x100 && ad21) + addr |= 0x400; + switch (addr) { + case SST_swapbufferCMD: + if (voodoo->type >= VOODOO_BANSHEE) { + // pclog("swapbufferCMD %08x %08x\n", val, voodoo->leftOverlayBuf); - voodoo_wait_for_render_thread_idle(voodoo); - if (!(val & 1)) { - banshee_set_overlay_addr(voodoo->p, voodoo->leftOverlayBuf); - thread_lock_mutex(voodoo->swap_mutex); - if (voodoo->swap_count > 0) - voodoo->swap_count--; - thread_unlock_mutex(voodoo->swap_mutex); - voodoo->frame_count++; - } else if (TRIPLE_BUFFER) { - if (voodoo->swap_pending) - voodoo_wait_for_swap_complete(voodoo); - voodoo->swap_interval = (val >> 1) & 0xff; - voodoo->swap_offset = voodoo->leftOverlayBuf; - voodoo->swap_pending = 1; - } else { - voodoo->swap_interval = (val >> 1) & 0xff; - voodoo->swap_offset = voodoo->leftOverlayBuf; - voodoo->swap_pending = 1; + voodoo_wait_for_render_thread_idle(voodoo); + if (!(val & 1)) { + banshee_set_overlay_addr(voodoo->p, voodoo->leftOverlayBuf); + thread_lock_mutex(voodoo->swap_mutex); + if (voodoo->swap_count > 0) + voodoo->swap_count--; + thread_unlock_mutex(voodoo->swap_mutex); + voodoo->frame_count++; + } else if (TRIPLE_BUFFER) { + if (voodoo->swap_pending) + voodoo_wait_for_swap_complete(voodoo); + voodoo->swap_interval = (val >> 1) & 0xff; + voodoo->swap_offset = voodoo->leftOverlayBuf; + voodoo->swap_pending = 1; + } else { + voodoo->swap_interval = (val >> 1) & 0xff; + voodoo->swap_offset = voodoo->leftOverlayBuf; + voodoo->swap_pending = 1; - voodoo_wait_for_swap_complete(voodoo); - } + voodoo_wait_for_swap_complete(voodoo); + } - voodoo->cmd_read++; - break; - } + voodoo->cmd_read++; + break; + } - if (TRIPLE_BUFFER) { - voodoo->disp_buffer = (voodoo->disp_buffer + 1) % 3; - voodoo->draw_buffer = (voodoo->draw_buffer + 1) % 3; - } else { - voodoo->disp_buffer = !voodoo->disp_buffer; - voodoo->draw_buffer = !voodoo->draw_buffer; - } - voodoo_recalc(voodoo); + if (TRIPLE_BUFFER) { + voodoo->disp_buffer = (voodoo->disp_buffer + 1) % 3; + voodoo->draw_buffer = (voodoo->draw_buffer + 1) % 3; + } else { + voodoo->disp_buffer = !voodoo->disp_buffer; + voodoo->draw_buffer = !voodoo->draw_buffer; + } + voodoo_recalc(voodoo); - voodoo->params.swapbufferCMD = val; + voodoo->params.swapbufferCMD = val; -// pclog("Swap buffer %08x %d %p %i\n", val, voodoo->swap_count, &voodoo->swap_count, (voodoo == voodoo->set->voodoos[1]) ? 1 : 0); -// voodoo->front_offset = params->front_offset; - voodoo_wait_for_render_thread_idle(voodoo); - if (!(val & 1)) { - memset(voodoo->dirty_line, 1, sizeof(voodoo->dirty_line)); - voodoo->front_offset = voodoo->params.front_offset; - thread_lock_mutex(voodoo->swap_mutex); - if (voodoo->swap_count > 0) - voodoo->swap_count--; - thread_unlock_mutex(voodoo->swap_mutex); - } else if (TRIPLE_BUFFER) { - if (voodoo->swap_pending) - voodoo_wait_for_swap_complete(voodoo); + // pclog("Swap buffer %08x %d %p %i\n", val, voodoo->swap_count, &voodoo->swap_count, (voodoo == + // voodoo->set->voodoos[1]) ? 1 : 0); voodoo->front_offset = params->front_offset; + voodoo_wait_for_render_thread_idle(voodoo); + if (!(val & 1)) { + memset(voodoo->dirty_line, 1, sizeof(voodoo->dirty_line)); + voodoo->front_offset = voodoo->params.front_offset; + thread_lock_mutex(voodoo->swap_mutex); + if (voodoo->swap_count > 0) + voodoo->swap_count--; + thread_unlock_mutex(voodoo->swap_mutex); + } else if (TRIPLE_BUFFER) { + if (voodoo->swap_pending) + voodoo_wait_for_swap_complete(voodoo); - voodoo->swap_interval = (val >> 1) & 0xff; - voodoo->swap_offset = voodoo->params.front_offset; - voodoo->swap_pending = 1; - } else { - voodoo->swap_interval = (val >> 1) & 0xff; - voodoo->swap_offset = voodoo->params.front_offset; - voodoo->swap_pending = 1; + voodoo->swap_interval = (val >> 1) & 0xff; + voodoo->swap_offset = voodoo->params.front_offset; + voodoo->swap_pending = 1; + } else { + voodoo->swap_interval = (val >> 1) & 0xff; + voodoo->swap_offset = voodoo->params.front_offset; + voodoo->swap_pending = 1; - voodoo_wait_for_swap_complete(voodoo); - } - voodoo->cmd_read++; - break; + voodoo_wait_for_swap_complete(voodoo); + } + voodoo->cmd_read++; + break; - case SST_vertexAx: - case SST_remap_vertexAx:voodoo->params.vertexAx = val & 0xffff; - break; - case SST_vertexAy: - case SST_remap_vertexAy:voodoo->params.vertexAy = val & 0xffff; - break; - case SST_vertexBx: - case SST_remap_vertexBx:voodoo->params.vertexBx = val & 0xffff; - break; - case SST_vertexBy: - case SST_remap_vertexBy:voodoo->params.vertexBy = val & 0xffff; - break; - case SST_vertexCx: - case SST_remap_vertexCx:voodoo->params.vertexCx = val & 0xffff; - break; - case SST_vertexCy: - case SST_remap_vertexCy:voodoo->params.vertexCy = val & 0xffff; - break; + case SST_vertexAx: + case SST_remap_vertexAx: + voodoo->params.vertexAx = val & 0xffff; + break; + case SST_vertexAy: + case SST_remap_vertexAy: + voodoo->params.vertexAy = val & 0xffff; + break; + case SST_vertexBx: + case SST_remap_vertexBx: + voodoo->params.vertexBx = val & 0xffff; + break; + case SST_vertexBy: + case SST_remap_vertexBy: + voodoo->params.vertexBy = val & 0xffff; + break; + case SST_vertexCx: + case SST_remap_vertexCx: + voodoo->params.vertexCx = val & 0xffff; + break; + case SST_vertexCy: + case SST_remap_vertexCy: + voodoo->params.vertexCy = val & 0xffff; + break; - case SST_startR: - case SST_remap_startR:voodoo->params.startR = val & 0xffffff; - break; - case SST_startG: - case SST_remap_startG:voodoo->params.startG = val & 0xffffff; - break; - case SST_startB: - case SST_remap_startB:voodoo->params.startB = val & 0xffffff; - break; - case SST_startZ: - case SST_remap_startZ:voodoo->params.startZ = val; - break; - case SST_startA: - case SST_remap_startA:voodoo->params.startA = val & 0xffffff; - break; - case SST_startS: - case SST_remap_startS: - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].startS = ((int64_t)(int32_t)val) << 14; - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].startS = ((int64_t)(int32_t)val) << 14; - break; - case SST_startT: - case SST_remap_startT: - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].startT = ((int64_t)(int32_t)val) << 14; - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].startT = ((int64_t)(int32_t)val) << 14; - break; - case SST_startW: - case SST_remap_startW: - if (chip & CHIP_FBI) - voodoo->params.startW = (int64_t)(int32_t)val << 2; - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].startW = (int64_t)(int32_t)val << 2; - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].startW = (int64_t)(int32_t)val << 2; - break; + case SST_startR: + case SST_remap_startR: + voodoo->params.startR = val & 0xffffff; + break; + case SST_startG: + case SST_remap_startG: + voodoo->params.startG = val & 0xffffff; + break; + case SST_startB: + case SST_remap_startB: + voodoo->params.startB = val & 0xffffff; + break; + case SST_startZ: + case SST_remap_startZ: + voodoo->params.startZ = val; + break; + case SST_startA: + case SST_remap_startA: + voodoo->params.startA = val & 0xffffff; + break; + case SST_startS: + case SST_remap_startS: + if (chip & CHIP_TREX0) + voodoo->params.tmu[0].startS = ((int64_t)(int32_t)val) << 14; + if (chip & CHIP_TREX1) + voodoo->params.tmu[1].startS = ((int64_t)(int32_t)val) << 14; + break; + case SST_startT: + case SST_remap_startT: + if (chip & CHIP_TREX0) + voodoo->params.tmu[0].startT = ((int64_t)(int32_t)val) << 14; + if (chip & CHIP_TREX1) + voodoo->params.tmu[1].startT = ((int64_t)(int32_t)val) << 14; + break; + case SST_startW: + case SST_remap_startW: + if (chip & CHIP_FBI) + voodoo->params.startW = (int64_t)(int32_t)val << 2; + if (chip & CHIP_TREX0) + voodoo->params.tmu[0].startW = (int64_t)(int32_t)val << 2; + if (chip & CHIP_TREX1) + voodoo->params.tmu[1].startW = (int64_t)(int32_t)val << 2; + break; - case SST_dRdX: - case SST_remap_dRdX:voodoo->params.dRdX = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); - break; - case SST_dGdX: - case SST_remap_dGdX:voodoo->params.dGdX = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); - break; - case SST_dBdX: - case SST_remap_dBdX:voodoo->params.dBdX = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); - break; - case SST_dZdX: - case SST_remap_dZdX:voodoo->params.dZdX = val; - break; - case SST_dAdX: - case SST_remap_dAdX:voodoo->params.dAdX = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); - break; - case SST_dSdX: - case SST_remap_dSdX: - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].dSdX = ((int64_t)(int32_t)val) << 14; - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].dSdX = ((int64_t)(int32_t)val) << 14; - break; - case SST_dTdX: - case SST_remap_dTdX: - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].dTdX = ((int64_t)(int32_t)val) << 14; - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].dTdX = ((int64_t)(int32_t)val) << 14; - break; - case SST_dWdX: - case SST_remap_dWdX: - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].dWdX = (int64_t)(int32_t)val << 2; - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].dWdX = (int64_t)(int32_t)val << 2; - if (chip & CHIP_FBI) - voodoo->params.dWdX = (int64_t)(int32_t)val << 2; - break; + case SST_dRdX: + case SST_remap_dRdX: + voodoo->params.dRdX = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); + break; + case SST_dGdX: + case SST_remap_dGdX: + voodoo->params.dGdX = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); + break; + case SST_dBdX: + case SST_remap_dBdX: + voodoo->params.dBdX = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); + break; + case SST_dZdX: + case SST_remap_dZdX: + voodoo->params.dZdX = val; + break; + case SST_dAdX: + case SST_remap_dAdX: + voodoo->params.dAdX = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); + break; + case SST_dSdX: + case SST_remap_dSdX: + if (chip & CHIP_TREX0) + voodoo->params.tmu[0].dSdX = ((int64_t)(int32_t)val) << 14; + if (chip & CHIP_TREX1) + voodoo->params.tmu[1].dSdX = ((int64_t)(int32_t)val) << 14; + break; + case SST_dTdX: + case SST_remap_dTdX: + if (chip & CHIP_TREX0) + voodoo->params.tmu[0].dTdX = ((int64_t)(int32_t)val) << 14; + if (chip & CHIP_TREX1) + voodoo->params.tmu[1].dTdX = ((int64_t)(int32_t)val) << 14; + break; + case SST_dWdX: + case SST_remap_dWdX: + if (chip & CHIP_TREX0) + voodoo->params.tmu[0].dWdX = (int64_t)(int32_t)val << 2; + if (chip & CHIP_TREX1) + voodoo->params.tmu[1].dWdX = (int64_t)(int32_t)val << 2; + if (chip & CHIP_FBI) + voodoo->params.dWdX = (int64_t)(int32_t)val << 2; + break; - case SST_dRdY: - case SST_remap_dRdY:voodoo->params.dRdY = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); - break; - case SST_dGdY: - case SST_remap_dGdY:voodoo->params.dGdY = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); - break; - case SST_dBdY: - case SST_remap_dBdY:voodoo->params.dBdY = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); - break; - case SST_dZdY: - case SST_remap_dZdY:voodoo->params.dZdY = val; - break; - case SST_dAdY: - case SST_remap_dAdY:voodoo->params.dAdY = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); - break; - case SST_dSdY: - case SST_remap_dSdY: - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].dSdY = ((int64_t)(int32_t)val) << 14; - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].dSdY = ((int64_t)(int32_t)val) << 14; - break; - case SST_dTdY: - case SST_remap_dTdY: - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].dTdY = ((int64_t)(int32_t)val) << 14; - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].dTdY = ((int64_t)(int32_t)val) << 14; - break; - case SST_dWdY: - case SST_remap_dWdY: - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].dWdY = (int64_t)(int32_t)val << 2; - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].dWdY = (int64_t)(int32_t)val << 2; - if (chip & CHIP_FBI) - voodoo->params.dWdY = (int64_t)(int32_t)val << 2; - break; + case SST_dRdY: + case SST_remap_dRdY: + voodoo->params.dRdY = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); + break; + case SST_dGdY: + case SST_remap_dGdY: + voodoo->params.dGdY = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); + break; + case SST_dBdY: + case SST_remap_dBdY: + voodoo->params.dBdY = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); + break; + case SST_dZdY: + case SST_remap_dZdY: + voodoo->params.dZdY = val; + break; + case SST_dAdY: + case SST_remap_dAdY: + voodoo->params.dAdY = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); + break; + case SST_dSdY: + case SST_remap_dSdY: + if (chip & CHIP_TREX0) + voodoo->params.tmu[0].dSdY = ((int64_t)(int32_t)val) << 14; + if (chip & CHIP_TREX1) + voodoo->params.tmu[1].dSdY = ((int64_t)(int32_t)val) << 14; + break; + case SST_dTdY: + case SST_remap_dTdY: + if (chip & CHIP_TREX0) + voodoo->params.tmu[0].dTdY = ((int64_t)(int32_t)val) << 14; + if (chip & CHIP_TREX1) + voodoo->params.tmu[1].dTdY = ((int64_t)(int32_t)val) << 14; + break; + case SST_dWdY: + case SST_remap_dWdY: + if (chip & CHIP_TREX0) + voodoo->params.tmu[0].dWdY = (int64_t)(int32_t)val << 2; + if (chip & CHIP_TREX1) + voodoo->params.tmu[1].dWdY = (int64_t)(int32_t)val << 2; + if (chip & CHIP_FBI) + voodoo->params.dWdY = (int64_t)(int32_t)val << 2; + break; - case SST_triangleCMD: - case SST_remap_triangleCMD:voodoo->params.sign = val & (1 << 31); + case SST_triangleCMD: + case SST_remap_triangleCMD: + voodoo->params.sign = val & (1 << 31); - if (voodoo->ncc_dirty[0]) - voodoo_update_ncc(voodoo, 0); - if (voodoo->ncc_dirty[1]) - voodoo_update_ncc(voodoo, 1); - voodoo->ncc_dirty[0] = voodoo->ncc_dirty[1] = 0; + if (voodoo->ncc_dirty[0]) + voodoo_update_ncc(voodoo, 0); + if (voodoo->ncc_dirty[1]) + voodoo_update_ncc(voodoo, 1); + voodoo->ncc_dirty[0] = voodoo->ncc_dirty[1] = 0; - voodoo_queue_triangle(voodoo, &voodoo->params); + voodoo_queue_triangle(voodoo, &voodoo->params); - voodoo->cmd_read++; - break; + voodoo->cmd_read++; + break; - case SST_fvertexAx: - case SST_remap_fvertexAx:voodoo->fvertexAx.i = val; - voodoo->params.vertexAx = (int32_t)(int16_t)(int32_t)(voodoo->fvertexAx.f * 16.0f) & 0xffff; - break; - case SST_fvertexAy: - case SST_remap_fvertexAy:voodoo->fvertexAy.i = val; - voodoo->params.vertexAy = (int32_t)(int16_t)(int32_t)(voodoo->fvertexAy.f * 16.0f) & 0xffff; - break; - case SST_fvertexBx: - case SST_remap_fvertexBx:voodoo->fvertexBx.i = val; - voodoo->params.vertexBx = (int32_t)(int16_t)(int32_t)(voodoo->fvertexBx.f * 16.0f) & 0xffff; - break; - case SST_fvertexBy: - case SST_remap_fvertexBy:voodoo->fvertexBy.i = val; - voodoo->params.vertexBy = (int32_t)(int16_t)(int32_t)(voodoo->fvertexBy.f * 16.0f) & 0xffff; - break; - case SST_fvertexCx: - case SST_remap_fvertexCx:voodoo->fvertexCx.i = val; - voodoo->params.vertexCx = (int32_t)(int16_t)(int32_t)(voodoo->fvertexCx.f * 16.0f) & 0xffff; - break; - case SST_fvertexCy: - case SST_remap_fvertexCy:voodoo->fvertexCy.i = val; - voodoo->params.vertexCy = (int32_t)(int16_t)(int32_t)(voodoo->fvertexCy.f * 16.0f) & 0xffff; - break; + case SST_fvertexAx: + case SST_remap_fvertexAx: + voodoo->fvertexAx.i = val; + voodoo->params.vertexAx = (int32_t)(int16_t)(int32_t)(voodoo->fvertexAx.f * 16.0f) & 0xffff; + break; + case SST_fvertexAy: + case SST_remap_fvertexAy: + voodoo->fvertexAy.i = val; + voodoo->params.vertexAy = (int32_t)(int16_t)(int32_t)(voodoo->fvertexAy.f * 16.0f) & 0xffff; + break; + case SST_fvertexBx: + case SST_remap_fvertexBx: + voodoo->fvertexBx.i = val; + voodoo->params.vertexBx = (int32_t)(int16_t)(int32_t)(voodoo->fvertexBx.f * 16.0f) & 0xffff; + break; + case SST_fvertexBy: + case SST_remap_fvertexBy: + voodoo->fvertexBy.i = val; + voodoo->params.vertexBy = (int32_t)(int16_t)(int32_t)(voodoo->fvertexBy.f * 16.0f) & 0xffff; + break; + case SST_fvertexCx: + case SST_remap_fvertexCx: + voodoo->fvertexCx.i = val; + voodoo->params.vertexCx = (int32_t)(int16_t)(int32_t)(voodoo->fvertexCx.f * 16.0f) & 0xffff; + break; + case SST_fvertexCy: + case SST_remap_fvertexCy: + voodoo->fvertexCy.i = val; + voodoo->params.vertexCy = (int32_t)(int16_t)(int32_t)(voodoo->fvertexCy.f * 16.0f) & 0xffff; + break; - case SST_fstartR: - case SST_remap_fstartR:tempif.i = val; - voodoo->params.startR = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fstartG: - case SST_remap_fstartG:tempif.i = val; - voodoo->params.startG = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fstartB: - case SST_remap_fstartB:tempif.i = val; - voodoo->params.startB = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fstartZ: - case SST_remap_fstartZ:tempif.i = val; - voodoo->params.startZ = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fstartA: - case SST_remap_fstartA:tempif.i = val; - voodoo->params.startA = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fstartS: - case SST_remap_fstartS:tempif.i = val; - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].startS = (int64_t)(tempif.f * 4294967296.0f); - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].startS = (int64_t)(tempif.f * 4294967296.0f); - break; - case SST_fstartT: - case SST_remap_fstartT:tempif.i = val; - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].startT = (int64_t)(tempif.f * 4294967296.0f); - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].startT = (int64_t)(tempif.f * 4294967296.0f); - break; - case SST_fstartW: - case SST_remap_fstartW:tempif.i = val; - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].startW = (int64_t)(tempif.f * 4294967296.0f); - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].startW = (int64_t)(tempif.f * 4294967296.0f); - if (chip & CHIP_FBI) - voodoo->params.startW = (int64_t)(tempif.f * 4294967296.0f); - break; + case SST_fstartR: + case SST_remap_fstartR: + tempif.i = val; + voodoo->params.startR = (int32_t)(tempif.f * 4096.0f); + break; + case SST_fstartG: + case SST_remap_fstartG: + tempif.i = val; + voodoo->params.startG = (int32_t)(tempif.f * 4096.0f); + break; + case SST_fstartB: + case SST_remap_fstartB: + tempif.i = val; + voodoo->params.startB = (int32_t)(tempif.f * 4096.0f); + break; + case SST_fstartZ: + case SST_remap_fstartZ: + tempif.i = val; + voodoo->params.startZ = (int32_t)(tempif.f * 4096.0f); + break; + case SST_fstartA: + case SST_remap_fstartA: + tempif.i = val; + voodoo->params.startA = (int32_t)(tempif.f * 4096.0f); + break; + case SST_fstartS: + case SST_remap_fstartS: + tempif.i = val; + if (chip & CHIP_TREX0) + voodoo->params.tmu[0].startS = (int64_t)(tempif.f * 4294967296.0f); + if (chip & CHIP_TREX1) + voodoo->params.tmu[1].startS = (int64_t)(tempif.f * 4294967296.0f); + break; + case SST_fstartT: + case SST_remap_fstartT: + tempif.i = val; + if (chip & CHIP_TREX0) + voodoo->params.tmu[0].startT = (int64_t)(tempif.f * 4294967296.0f); + if (chip & CHIP_TREX1) + voodoo->params.tmu[1].startT = (int64_t)(tempif.f * 4294967296.0f); + break; + case SST_fstartW: + case SST_remap_fstartW: + tempif.i = val; + if (chip & CHIP_TREX0) + voodoo->params.tmu[0].startW = (int64_t)(tempif.f * 4294967296.0f); + if (chip & CHIP_TREX1) + voodoo->params.tmu[1].startW = (int64_t)(tempif.f * 4294967296.0f); + if (chip & CHIP_FBI) + voodoo->params.startW = (int64_t)(tempif.f * 4294967296.0f); + break; - case SST_fdRdX: - case SST_remap_fdRdX:tempif.i = val; - voodoo->params.dRdX = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fdGdX: - case SST_remap_fdGdX:tempif.i = val; - voodoo->params.dGdX = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fdBdX: - case SST_remap_fdBdX:tempif.i = val; - voodoo->params.dBdX = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fdZdX: - case SST_remap_fdZdX:tempif.i = val; - voodoo->params.dZdX = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fdAdX: - case SST_remap_fdAdX:tempif.i = val; - voodoo->params.dAdX = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fdSdX: - case SST_remap_fdSdX:tempif.i = val; - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].dSdX = (int64_t)(tempif.f * 4294967296.0f); - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].dSdX = (int64_t)(tempif.f * 4294967296.0f); - break; - case SST_fdTdX: - case SST_remap_fdTdX:tempif.i = val; - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].dTdX = (int64_t)(tempif.f * 4294967296.0f); - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].dTdX = (int64_t)(tempif.f * 4294967296.0f); - break; - case SST_fdWdX: - case SST_remap_fdWdX:tempif.i = val; - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].dWdX = (int64_t)(tempif.f * 4294967296.0f); - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].dWdX = (int64_t)(tempif.f * 4294967296.0f); - if (chip & CHIP_FBI) - voodoo->params.dWdX = (int64_t)(tempif.f * 4294967296.0f); - break; + case SST_fdRdX: + case SST_remap_fdRdX: + tempif.i = val; + voodoo->params.dRdX = (int32_t)(tempif.f * 4096.0f); + break; + case SST_fdGdX: + case SST_remap_fdGdX: + tempif.i = val; + voodoo->params.dGdX = (int32_t)(tempif.f * 4096.0f); + break; + case SST_fdBdX: + case SST_remap_fdBdX: + tempif.i = val; + voodoo->params.dBdX = (int32_t)(tempif.f * 4096.0f); + break; + case SST_fdZdX: + case SST_remap_fdZdX: + tempif.i = val; + voodoo->params.dZdX = (int32_t)(tempif.f * 4096.0f); + break; + case SST_fdAdX: + case SST_remap_fdAdX: + tempif.i = val; + voodoo->params.dAdX = (int32_t)(tempif.f * 4096.0f); + break; + case SST_fdSdX: + case SST_remap_fdSdX: + tempif.i = val; + if (chip & CHIP_TREX0) + voodoo->params.tmu[0].dSdX = (int64_t)(tempif.f * 4294967296.0f); + if (chip & CHIP_TREX1) + voodoo->params.tmu[1].dSdX = (int64_t)(tempif.f * 4294967296.0f); + break; + case SST_fdTdX: + case SST_remap_fdTdX: + tempif.i = val; + if (chip & CHIP_TREX0) + voodoo->params.tmu[0].dTdX = (int64_t)(tempif.f * 4294967296.0f); + if (chip & CHIP_TREX1) + voodoo->params.tmu[1].dTdX = (int64_t)(tempif.f * 4294967296.0f); + break; + case SST_fdWdX: + case SST_remap_fdWdX: + tempif.i = val; + if (chip & CHIP_TREX0) + voodoo->params.tmu[0].dWdX = (int64_t)(tempif.f * 4294967296.0f); + if (chip & CHIP_TREX1) + voodoo->params.tmu[1].dWdX = (int64_t)(tempif.f * 4294967296.0f); + if (chip & CHIP_FBI) + voodoo->params.dWdX = (int64_t)(tempif.f * 4294967296.0f); + break; - case SST_fdRdY: - case SST_remap_fdRdY:tempif.i = val; - voodoo->params.dRdY = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fdGdY: - case SST_remap_fdGdY:tempif.i = val; - voodoo->params.dGdY = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fdBdY: - case SST_remap_fdBdY:tempif.i = val; - voodoo->params.dBdY = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fdZdY: - case SST_remap_fdZdY:tempif.i = val; - voodoo->params.dZdY = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fdAdY: - case SST_remap_fdAdY:tempif.i = val; - voodoo->params.dAdY = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fdSdY: - case SST_remap_fdSdY:tempif.i = val; - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].dSdY = (int64_t)(tempif.f * 4294967296.0f); - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].dSdY = (int64_t)(tempif.f * 4294967296.0f); - break; - case SST_fdTdY: - case SST_remap_fdTdY:tempif.i = val; - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].dTdY = (int64_t)(tempif.f * 4294967296.0f); - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].dTdY = (int64_t)(tempif.f * 4294967296.0f); - break; - case SST_fdWdY: - case SST_remap_fdWdY:tempif.i = val; - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].dWdY = (int64_t)(tempif.f * 4294967296.0f); - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].dWdY = (int64_t)(tempif.f * 4294967296.0f); - if (chip & CHIP_FBI) - voodoo->params.dWdY = (int64_t)(tempif.f * 4294967296.0f); - break; + case SST_fdRdY: + case SST_remap_fdRdY: + tempif.i = val; + voodoo->params.dRdY = (int32_t)(tempif.f * 4096.0f); + break; + case SST_fdGdY: + case SST_remap_fdGdY: + tempif.i = val; + voodoo->params.dGdY = (int32_t)(tempif.f * 4096.0f); + break; + case SST_fdBdY: + case SST_remap_fdBdY: + tempif.i = val; + voodoo->params.dBdY = (int32_t)(tempif.f * 4096.0f); + break; + case SST_fdZdY: + case SST_remap_fdZdY: + tempif.i = val; + voodoo->params.dZdY = (int32_t)(tempif.f * 4096.0f); + break; + case SST_fdAdY: + case SST_remap_fdAdY: + tempif.i = val; + voodoo->params.dAdY = (int32_t)(tempif.f * 4096.0f); + break; + case SST_fdSdY: + case SST_remap_fdSdY: + tempif.i = val; + if (chip & CHIP_TREX0) + voodoo->params.tmu[0].dSdY = (int64_t)(tempif.f * 4294967296.0f); + if (chip & CHIP_TREX1) + voodoo->params.tmu[1].dSdY = (int64_t)(tempif.f * 4294967296.0f); + break; + case SST_fdTdY: + case SST_remap_fdTdY: + tempif.i = val; + if (chip & CHIP_TREX0) + voodoo->params.tmu[0].dTdY = (int64_t)(tempif.f * 4294967296.0f); + if (chip & CHIP_TREX1) + voodoo->params.tmu[1].dTdY = (int64_t)(tempif.f * 4294967296.0f); + break; + case SST_fdWdY: + case SST_remap_fdWdY: + tempif.i = val; + if (chip & CHIP_TREX0) + voodoo->params.tmu[0].dWdY = (int64_t)(tempif.f * 4294967296.0f); + if (chip & CHIP_TREX1) + voodoo->params.tmu[1].dWdY = (int64_t)(tempif.f * 4294967296.0f); + if (chip & CHIP_FBI) + voodoo->params.dWdY = (int64_t)(tempif.f * 4294967296.0f); + break; - case SST_ftriangleCMD:voodoo->params.sign = val & (1 << 31); + case SST_ftriangleCMD: + voodoo->params.sign = val & (1 << 31); - if (voodoo->ncc_dirty[0]) - voodoo_update_ncc(voodoo, 0); - if (voodoo->ncc_dirty[1]) - voodoo_update_ncc(voodoo, 1); - voodoo->ncc_dirty[0] = voodoo->ncc_dirty[1] = 0; + if (voodoo->ncc_dirty[0]) + voodoo_update_ncc(voodoo, 0); + if (voodoo->ncc_dirty[1]) + voodoo_update_ncc(voodoo, 1); + voodoo->ncc_dirty[0] = voodoo->ncc_dirty[1] = 0; - voodoo_queue_triangle(voodoo, &voodoo->params); + voodoo_queue_triangle(voodoo, &voodoo->params); - voodoo->cmd_read++; - break; + voodoo->cmd_read++; + break; - case SST_fbzColorPath:voodoo->params.fbzColorPath = val; - voodoo->rgb_sel = val & 3; - break; + case SST_fbzColorPath: + voodoo->params.fbzColorPath = val; + voodoo->rgb_sel = val & 3; + break; - case SST_fogMode:voodoo->params.fogMode = val; - break; - case SST_alphaMode:voodoo->params.alphaMode = val; - break; - case SST_fbzMode:voodoo->params.fbzMode = val; - voodoo_recalc(voodoo); - break; - case SST_lfbMode:voodoo->lfbMode = val; - voodoo_recalc(voodoo); - break; + case SST_fogMode: + voodoo->params.fogMode = val; + break; + case SST_alphaMode: + voodoo->params.alphaMode = val; + break; + case SST_fbzMode: + voodoo->params.fbzMode = val; + voodoo_recalc(voodoo); + break; + case SST_lfbMode: + voodoo->lfbMode = val; + voodoo_recalc(voodoo); + break; - case SST_clipLeftRight: - if (voodoo->type >= VOODOO_2) { - voodoo->params.clipRight = val & 0xfff; - voodoo->params.clipLeft = (val >> 16) & 0xfff; - } else { - voodoo->params.clipRight = val & 0x3ff; - voodoo->params.clipLeft = (val >> 16) & 0x3ff; - } - break; - case SST_clipLowYHighY: - if (voodoo->type >= VOODOO_2) { - voodoo->params.clipHighY = val & 0xfff; - voodoo->params.clipLowY = (val >> 16) & 0xfff; - } else { - voodoo->params.clipHighY = val & 0x3ff; - voodoo->params.clipLowY = (val >> 16) & 0x3ff; - } - break; + case SST_clipLeftRight: + if (voodoo->type >= VOODOO_2) { + voodoo->params.clipRight = val & 0xfff; + voodoo->params.clipLeft = (val >> 16) & 0xfff; + } else { + voodoo->params.clipRight = val & 0x3ff; + voodoo->params.clipLeft = (val >> 16) & 0x3ff; + } + break; + case SST_clipLowYHighY: + if (voodoo->type >= VOODOO_2) { + voodoo->params.clipHighY = val & 0xfff; + voodoo->params.clipLowY = (val >> 16) & 0xfff; + } else { + voodoo->params.clipHighY = val & 0x3ff; + voodoo->params.clipLowY = (val >> 16) & 0x3ff; + } + break; - case SST_nopCMD:voodoo->cmd_read++; - voodoo->fbiPixelsIn = 0; - voodoo->fbiChromaFail = 0; - voodoo->fbiZFuncFail = 0; - voodoo->fbiAFuncFail = 0; - voodoo->fbiPixelsOut = 0; - break; - case SST_fastfillCMD:voodoo_wait_for_render_thread_idle(voodoo); - voodoo_fastfill(voodoo, &voodoo->params); - voodoo->cmd_read++; - break; + case SST_nopCMD: + voodoo->cmd_read++; + voodoo->fbiPixelsIn = 0; + voodoo->fbiChromaFail = 0; + voodoo->fbiZFuncFail = 0; + voodoo->fbiAFuncFail = 0; + voodoo->fbiPixelsOut = 0; + break; + case SST_fastfillCMD: + voodoo_wait_for_render_thread_idle(voodoo); + voodoo_fastfill(voodoo, &voodoo->params); + voodoo->cmd_read++; + break; - case SST_fogColor:voodoo->params.fogColor.r = (val >> 16) & 0xff; - voodoo->params.fogColor.g = (val >> 8) & 0xff; - voodoo->params.fogColor.b = val & 0xff; - break; + case SST_fogColor: + voodoo->params.fogColor.r = (val >> 16) & 0xff; + voodoo->params.fogColor.g = (val >> 8) & 0xff; + voodoo->params.fogColor.b = val & 0xff; + break; - case SST_zaColor:voodoo->params.zaColor = val; - break; - case SST_chromaKey:voodoo->params.chromaKey_r = (val >> 16) & 0xff; - voodoo->params.chromaKey_g = (val >> 8) & 0xff; - voodoo->params.chromaKey_b = val & 0xff; - voodoo->params.chromaKey = val & 0xffffff; - break; - case SST_stipple:voodoo->params.stipple = val; - break; - case SST_color0:voodoo->params.color0 = val; - break; - case SST_color1:voodoo->params.color1 = val; - break; + case SST_zaColor: + voodoo->params.zaColor = val; + break; + case SST_chromaKey: + voodoo->params.chromaKey_r = (val >> 16) & 0xff; + voodoo->params.chromaKey_g = (val >> 8) & 0xff; + voodoo->params.chromaKey_b = val & 0xff; + voodoo->params.chromaKey = val & 0xffffff; + break; + case SST_stipple: + voodoo->params.stipple = val; + break; + case SST_color0: + voodoo->params.color0 = val; + break; + case SST_color1: + voodoo->params.color1 = val; + break; - case SST_fogTable00: - case SST_fogTable01: - case SST_fogTable02: - case SST_fogTable03: - case SST_fogTable04: - case SST_fogTable05: - case SST_fogTable06: - case SST_fogTable07: - case SST_fogTable08: - case SST_fogTable09: - case SST_fogTable0a: - case SST_fogTable0b: - case SST_fogTable0c: - case SST_fogTable0d: - case SST_fogTable0e: - case SST_fogTable0f: - case SST_fogTable10: - case SST_fogTable11: - case SST_fogTable12: - case SST_fogTable13: - case SST_fogTable14: - case SST_fogTable15: - case SST_fogTable16: - case SST_fogTable17: - case SST_fogTable18: - case SST_fogTable19: - case SST_fogTable1a: - case SST_fogTable1b: - case SST_fogTable1c: - case SST_fogTable1d: - case SST_fogTable1e: - case SST_fogTable1f:addr = (addr - SST_fogTable00) >> 1; - voodoo->params.fogTable[addr].dfog = val & 0xff; - voodoo->params.fogTable[addr].fog = (val >> 8) & 0xff; - voodoo->params.fogTable[addr + 1].dfog = (val >> 16) & 0xff; - voodoo->params.fogTable[addr + 1].fog = (val >> 24) & 0xff; - break; + case SST_fogTable00: + case SST_fogTable01: + case SST_fogTable02: + case SST_fogTable03: + case SST_fogTable04: + case SST_fogTable05: + case SST_fogTable06: + case SST_fogTable07: + case SST_fogTable08: + case SST_fogTable09: + case SST_fogTable0a: + case SST_fogTable0b: + case SST_fogTable0c: + case SST_fogTable0d: + case SST_fogTable0e: + case SST_fogTable0f: + case SST_fogTable10: + case SST_fogTable11: + case SST_fogTable12: + case SST_fogTable13: + case SST_fogTable14: + case SST_fogTable15: + case SST_fogTable16: + case SST_fogTable17: + case SST_fogTable18: + case SST_fogTable19: + case SST_fogTable1a: + case SST_fogTable1b: + case SST_fogTable1c: + case SST_fogTable1d: + case SST_fogTable1e: + case SST_fogTable1f: + addr = (addr - SST_fogTable00) >> 1; + voodoo->params.fogTable[addr].dfog = val & 0xff; + voodoo->params.fogTable[addr].fog = (val >> 8) & 0xff; + voodoo->params.fogTable[addr + 1].dfog = (val >> 16) & 0xff; + voodoo->params.fogTable[addr + 1].fog = (val >> 24) & 0xff; + break; - case SST_clipLeftRight1: - if (voodoo->type >= VOODOO_BANSHEE) { - voodoo->params.clipRight1 = val & 0xfff; - voodoo->params.clipLeft1 = (val >> 16) & 0xfff; - } - break; - case SST_clipTopBottom1: - if (voodoo->type >= VOODOO_BANSHEE) { - voodoo->params.clipHighY1 = val & 0xfff; - voodoo->params.clipLowY1 = (val >> 16) & 0xfff; - } - break; + case SST_clipLeftRight1: + if (voodoo->type >= VOODOO_BANSHEE) { + voodoo->params.clipRight1 = val & 0xfff; + voodoo->params.clipLeft1 = (val >> 16) & 0xfff; + } + break; + case SST_clipTopBottom1: + if (voodoo->type >= VOODOO_BANSHEE) { + voodoo->params.clipHighY1 = val & 0xfff; + voodoo->params.clipLowY1 = (val >> 16) & 0xfff; + } + break; - case SST_colBufferAddr: - if (voodoo->type >= VOODOO_BANSHEE) { - voodoo->params.draw_offset = val & 0xfffff0; - voodoo->fb_write_offset = voodoo->params.draw_offset; -// pclog("colorBufferAddr=%06x\n", voodoo->params.draw_offset); - } - break; - case SST_colBufferStride: - if (voodoo->type >= VOODOO_BANSHEE) { - voodoo->col_tiled = val & (1 << 15); - voodoo->params.col_tiled = voodoo->col_tiled; - if (voodoo->col_tiled) { - voodoo->row_width = (val & 0x7f) * 128 * 32; -// pclog("colBufferStride tiled = %i bytes, tiled %08x\n", voodoo->row_width, val); - } else { - voodoo->row_width = val & 0x3fff; -// pclog("colBufferStride linear = %i bytes, linear\n", voodoo->row_width); - } - voodoo->params.row_width = voodoo->row_width; - } - break; - case SST_auxBufferAddr: - if (voodoo->type >= VOODOO_BANSHEE) { - voodoo->params.aux_offset = val & 0xfffff0; -// pclog("auxBufferAddr=%06x\n", voodoo->params.aux_offset); - } - break; - case SST_auxBufferStride: - if (voodoo->type >= VOODOO_BANSHEE) { - voodoo->aux_tiled = val & (1 << 15); - voodoo->params.aux_tiled = voodoo->aux_tiled; - if (voodoo->aux_tiled) { - voodoo->aux_row_width = (val & 0x7f) * 128 * 32; -// pclog("auxBufferStride tiled = %i bytes, tiled\n", voodoo->aux_row_width); - } else { - voodoo->aux_row_width = val & 0x3fff; -// pclog("auxBufferStride linear = %i bytes, linear\n", voodoo->aux_row_width); - } - voodoo->params.aux_row_width = voodoo->aux_row_width; - } - break; + case SST_colBufferAddr: + if (voodoo->type >= VOODOO_BANSHEE) { + voodoo->params.draw_offset = val & 0xfffff0; + voodoo->fb_write_offset = voodoo->params.draw_offset; + // pclog("colorBufferAddr=%06x\n", voodoo->params.draw_offset); + } + break; + case SST_colBufferStride: + if (voodoo->type >= VOODOO_BANSHEE) { + voodoo->col_tiled = val & (1 << 15); + voodoo->params.col_tiled = voodoo->col_tiled; + if (voodoo->col_tiled) { + voodoo->row_width = (val & 0x7f) * 128 * 32; + // pclog("colBufferStride tiled = %i bytes, tiled %08x\n", + // voodoo->row_width, val); + } else { + voodoo->row_width = val & 0x3fff; + // pclog("colBufferStride linear = %i bytes, linear\n", + // voodoo->row_width); + } + voodoo->params.row_width = voodoo->row_width; + } + break; + case SST_auxBufferAddr: + if (voodoo->type >= VOODOO_BANSHEE) { + voodoo->params.aux_offset = val & 0xfffff0; + // pclog("auxBufferAddr=%06x\n", voodoo->params.aux_offset); + } + break; + case SST_auxBufferStride: + if (voodoo->type >= VOODOO_BANSHEE) { + voodoo->aux_tiled = val & (1 << 15); + voodoo->params.aux_tiled = voodoo->aux_tiled; + if (voodoo->aux_tiled) { + voodoo->aux_row_width = (val & 0x7f) * 128 * 32; + // pclog("auxBufferStride tiled = %i bytes, tiled\n", + // voodoo->aux_row_width); + } else { + voodoo->aux_row_width = val & 0x3fff; + // pclog("auxBufferStride linear = %i bytes, linear\n", + // voodoo->aux_row_width); + } + voodoo->params.aux_row_width = voodoo->aux_row_width; + } + break; - case SST_clutData:voodoo->clutData[(val >> 24) & 0x3f].b = val & 0xff; - voodoo->clutData[(val >> 24) & 0x3f].g = (val >> 8) & 0xff; - voodoo->clutData[(val >> 24) & 0x3f].r = (val >> 16) & 0xff; - if (val & 0x20000000) { - voodoo->clutData[(val >> 24) & 0x3f].b = 255; - voodoo->clutData[(val >> 24) & 0x3f].g = 255; - voodoo->clutData[(val >> 24) & 0x3f].r = 255; - } - voodoo->clutData_dirty = 1; - break; + case SST_clutData: + voodoo->clutData[(val >> 24) & 0x3f].b = val & 0xff; + voodoo->clutData[(val >> 24) & 0x3f].g = (val >> 8) & 0xff; + voodoo->clutData[(val >> 24) & 0x3f].r = (val >> 16) & 0xff; + if (val & 0x20000000) { + voodoo->clutData[(val >> 24) & 0x3f].b = 255; + voodoo->clutData[(val >> 24) & 0x3f].g = 255; + voodoo->clutData[(val >> 24) & 0x3f].r = 255; + } + voodoo->clutData_dirty = 1; + break; - case SST_sSetupMode:voodoo->sSetupMode = val; - break; - case SST_sVx:tempif.i = val; - voodoo->verts[3].sVx = tempif.f; -// pclog("sVx[%i]=%f\n", voodoo->vertex_num, tempif.f); - break; - case SST_sVy:tempif.i = val; - voodoo->verts[3].sVy = tempif.f; -// pclog("sVy[%i]=%f\n", voodoo->vertex_num, tempif.f); - break; - case SST_sARGB:voodoo->verts[3].sBlue = (float)(val & 0xff); - voodoo->verts[3].sGreen = (float)((val >> 8) & 0xff); - voodoo->verts[3].sRed = (float)((val >> 16) & 0xff); - voodoo->verts[3].sAlpha = (float)((val >> 24) & 0xff); - break; - case SST_sRed:tempif.i = val; - voodoo->verts[3].sRed = tempif.f; - break; - case SST_sGreen:tempif.i = val; - voodoo->verts[3].sGreen = tempif.f; - break; - case SST_sBlue:tempif.i = val; - voodoo->verts[3].sBlue = tempif.f; - break; - case SST_sAlpha:tempif.i = val; - voodoo->verts[3].sAlpha = tempif.f; - break; - case SST_sVz:tempif.i = val; - voodoo->verts[3].sVz = tempif.f; - break; - case SST_sWb:tempif.i = val; - voodoo->verts[3].sWb = tempif.f; - break; - case SST_sW0:tempif.i = val; - voodoo->verts[3].sW0 = tempif.f; - break; - case SST_sS0:tempif.i = val; - voodoo->verts[3].sS0 = tempif.f; - break; - case SST_sT0:tempif.i = val; - voodoo->verts[3].sT0 = tempif.f; - break; - case SST_sW1:tempif.i = val; - voodoo->verts[3].sW1 = tempif.f; - break; - case SST_sS1:tempif.i = val; - voodoo->verts[3].sS1 = tempif.f; - break; - case SST_sT1:tempif.i = val; - voodoo->verts[3].sT1 = tempif.f; - break; + case SST_sSetupMode: + voodoo->sSetupMode = val; + break; + case SST_sVx: + tempif.i = val; + voodoo->verts[3].sVx = tempif.f; + // pclog("sVx[%i]=%f\n", voodoo->vertex_num, tempif.f); + break; + case SST_sVy: + tempif.i = val; + voodoo->verts[3].sVy = tempif.f; + // pclog("sVy[%i]=%f\n", voodoo->vertex_num, tempif.f); + break; + case SST_sARGB: + voodoo->verts[3].sBlue = (float)(val & 0xff); + voodoo->verts[3].sGreen = (float)((val >> 8) & 0xff); + voodoo->verts[3].sRed = (float)((val >> 16) & 0xff); + voodoo->verts[3].sAlpha = (float)((val >> 24) & 0xff); + break; + case SST_sRed: + tempif.i = val; + voodoo->verts[3].sRed = tempif.f; + break; + case SST_sGreen: + tempif.i = val; + voodoo->verts[3].sGreen = tempif.f; + break; + case SST_sBlue: + tempif.i = val; + voodoo->verts[3].sBlue = tempif.f; + break; + case SST_sAlpha: + tempif.i = val; + voodoo->verts[3].sAlpha = tempif.f; + break; + case SST_sVz: + tempif.i = val; + voodoo->verts[3].sVz = tempif.f; + break; + case SST_sWb: + tempif.i = val; + voodoo->verts[3].sWb = tempif.f; + break; + case SST_sW0: + tempif.i = val; + voodoo->verts[3].sW0 = tempif.f; + break; + case SST_sS0: + tempif.i = val; + voodoo->verts[3].sS0 = tempif.f; + break; + case SST_sT0: + tempif.i = val; + voodoo->verts[3].sT0 = tempif.f; + break; + case SST_sW1: + tempif.i = val; + voodoo->verts[3].sW1 = tempif.f; + break; + case SST_sS1: + tempif.i = val; + voodoo->verts[3].sS1 = tempif.f; + break; + case SST_sT1: + tempif.i = val; + voodoo->verts[3].sT1 = tempif.f; + break; - case SST_sBeginTriCMD: -// pclog("sBeginTriCMD %i %f\n", voodoo->vertex_num, voodoo->verts[4].sVx); - voodoo->verts[0] = voodoo->verts[3]; - voodoo->verts[1] = voodoo->verts[3]; - voodoo->verts[2] = voodoo->verts[3]; - voodoo->vertex_next_age = 0; - voodoo->vertex_ages[0] = voodoo->vertex_next_age++; + case SST_sBeginTriCMD: + // pclog("sBeginTriCMD %i %f\n", voodoo->vertex_num, voodoo->verts[4].sVx); + voodoo->verts[0] = voodoo->verts[3]; + voodoo->verts[1] = voodoo->verts[3]; + voodoo->verts[2] = voodoo->verts[3]; + voodoo->vertex_next_age = 0; + voodoo->vertex_ages[0] = voodoo->vertex_next_age++; - voodoo->num_verticies = 1; - voodoo->cull_pingpong = 0; - break; - case SST_sDrawTriCMD: -// pclog("sDrawTriCMD %i %i\n", voodoo->num_verticies, voodoo->sSetupMode & SETUPMODE_STRIP_MODE); - /*I'm not sure this is the vertex selection algorithm actually used in the 3dfx - chips, but this works with a number of games that switch between strip and fan - mode in the middle of a run (eg Black & White, Viper Racing)*/ - if (voodoo->vertex_next_age < 3) { - /*Fewer than three vertices already written, store in next slot*/ - int vertex_nr = voodoo->vertex_next_age; + voodoo->num_verticies = 1; + voodoo->cull_pingpong = 0; + break; + case SST_sDrawTriCMD: + // pclog("sDrawTriCMD %i %i\n", voodoo->num_verticies, voodoo->sSetupMode & SETUPMODE_STRIP_MODE); + /*I'm not sure this is the vertex selection algorithm actually used in the 3dfx + chips, but this works with a number of games that switch between strip and fan + mode in the middle of a run (eg Black & White, Viper Racing)*/ + if (voodoo->vertex_next_age < 3) { + /*Fewer than three vertices already written, store in next slot*/ + int vertex_nr = voodoo->vertex_next_age; - voodoo->verts[vertex_nr] = voodoo->verts[3]; - voodoo->vertex_ages[vertex_nr] = voodoo->vertex_next_age++; - } else { - int vertex_nr = 0; + voodoo->verts[vertex_nr] = voodoo->verts[3]; + voodoo->vertex_ages[vertex_nr] = voodoo->vertex_next_age++; + } else { + int vertex_nr = 0; - if (!(voodoo->sSetupMode & SETUPMODE_STRIP_MODE)) { - /*Strip - find oldest vertex*/ - if ((voodoo->vertex_ages[0] < voodoo->vertex_ages[1]) && - (voodoo->vertex_ages[0] < voodoo->vertex_ages[2])) - vertex_nr = 0; - else if ((voodoo->vertex_ages[1] < voodoo->vertex_ages[0]) && - (voodoo->vertex_ages[1] < voodoo->vertex_ages[2])) - vertex_nr = 1; - else - vertex_nr = 2; - } else { - /*Fan - find second oldest vertex (ie pivot around oldest)*/ - if ((voodoo->vertex_ages[1] < voodoo->vertex_ages[0]) && - (voodoo->vertex_ages[0] < voodoo->vertex_ages[2])) - vertex_nr = 0; - else if ((voodoo->vertex_ages[2] < voodoo->vertex_ages[0]) && - (voodoo->vertex_ages[0] < voodoo->vertex_ages[1])) - vertex_nr = 0; - else if ((voodoo->vertex_ages[0] < voodoo->vertex_ages[1]) && - (voodoo->vertex_ages[1] < voodoo->vertex_ages[2])) - vertex_nr = 1; - else if ((voodoo->vertex_ages[2] < voodoo->vertex_ages[1]) && - (voodoo->vertex_ages[1] < voodoo->vertex_ages[0])) - vertex_nr = 1; - else - vertex_nr = 2; - } - voodoo->verts[vertex_nr] = voodoo->verts[3]; - voodoo->vertex_ages[vertex_nr] = voodoo->vertex_next_age++; - } + if (!(voodoo->sSetupMode & SETUPMODE_STRIP_MODE)) { + /*Strip - find oldest vertex*/ + if ((voodoo->vertex_ages[0] < voodoo->vertex_ages[1]) && + (voodoo->vertex_ages[0] < voodoo->vertex_ages[2])) + vertex_nr = 0; + else if ((voodoo->vertex_ages[1] < voodoo->vertex_ages[0]) && + (voodoo->vertex_ages[1] < voodoo->vertex_ages[2])) + vertex_nr = 1; + else + vertex_nr = 2; + } else { + /*Fan - find second oldest vertex (ie pivot around oldest)*/ + if ((voodoo->vertex_ages[1] < voodoo->vertex_ages[0]) && + (voodoo->vertex_ages[0] < voodoo->vertex_ages[2])) + vertex_nr = 0; + else if ((voodoo->vertex_ages[2] < voodoo->vertex_ages[0]) && + (voodoo->vertex_ages[0] < voodoo->vertex_ages[1])) + vertex_nr = 0; + else if ((voodoo->vertex_ages[0] < voodoo->vertex_ages[1]) && + (voodoo->vertex_ages[1] < voodoo->vertex_ages[2])) + vertex_nr = 1; + else if ((voodoo->vertex_ages[2] < voodoo->vertex_ages[1]) && + (voodoo->vertex_ages[1] < voodoo->vertex_ages[0])) + vertex_nr = 1; + else + vertex_nr = 2; + } + voodoo->verts[vertex_nr] = voodoo->verts[3]; + voodoo->vertex_ages[vertex_nr] = voodoo->vertex_next_age++; + } - voodoo->num_verticies++; - if (voodoo->num_verticies == 3) { -// pclog("triangle_setup\n"); - voodoo_triangle_setup(voodoo); - voodoo->cull_pingpong = !voodoo->cull_pingpong; + voodoo->num_verticies++; + if (voodoo->num_verticies == 3) { + // pclog("triangle_setup\n"); + voodoo_triangle_setup(voodoo); + voodoo->cull_pingpong = !voodoo->cull_pingpong; - voodoo->num_verticies = 2; - } - break; + voodoo->num_verticies = 2; + } + break; - case SST_bltSrcBaseAddr:voodoo->bltSrcBaseAddr = val & 0x3fffff; - break; - case SST_bltDstBaseAddr: -// pclog("Write bltDstBaseAddr %08x\n", val); - voodoo->bltDstBaseAddr = val & 0x3fffff; - break; - case SST_bltXYStrides:voodoo->bltSrcXYStride = val & 0xfff; - voodoo->bltDstXYStride = (val >> 16) & 0xfff; -// pclog("Write bltXYStrides %08x\n", val); - break; - case SST_bltSrcChromaRange:voodoo->bltSrcChromaRange = val; - voodoo->bltSrcChromaMinB = val & 0x1f; - voodoo->bltSrcChromaMinG = (val >> 5) & 0x3f; - voodoo->bltSrcChromaMinR = (val >> 11) & 0x1f; - voodoo->bltSrcChromaMaxB = (val >> 16) & 0x1f; - voodoo->bltSrcChromaMaxG = (val >> 21) & 0x3f; - voodoo->bltSrcChromaMaxR = (val >> 27) & 0x1f; - break; - case SST_bltDstChromaRange:voodoo->bltDstChromaRange = val; - voodoo->bltDstChromaMinB = val & 0x1f; - voodoo->bltDstChromaMinG = (val >> 5) & 0x3f; - voodoo->bltDstChromaMinR = (val >> 11) & 0x1f; - voodoo->bltDstChromaMaxB = (val >> 16) & 0x1f; - voodoo->bltDstChromaMaxG = (val >> 21) & 0x3f; - voodoo->bltDstChromaMaxR = (val >> 27) & 0x1f; - break; - case SST_bltClipX:voodoo->bltClipRight = val & 0xfff; - voodoo->bltClipLeft = (val >> 16) & 0xfff; - break; - case SST_bltClipY:voodoo->bltClipHighY = val & 0xfff; - voodoo->bltClipLowY = (val >> 16) & 0xfff; - break; + case SST_bltSrcBaseAddr: + voodoo->bltSrcBaseAddr = val & 0x3fffff; + break; + case SST_bltDstBaseAddr: + // pclog("Write bltDstBaseAddr %08x\n", val); + voodoo->bltDstBaseAddr = val & 0x3fffff; + break; + case SST_bltXYStrides: + voodoo->bltSrcXYStride = val & 0xfff; + voodoo->bltDstXYStride = (val >> 16) & 0xfff; + // pclog("Write bltXYStrides %08x\n", val); + break; + case SST_bltSrcChromaRange: + voodoo->bltSrcChromaRange = val; + voodoo->bltSrcChromaMinB = val & 0x1f; + voodoo->bltSrcChromaMinG = (val >> 5) & 0x3f; + voodoo->bltSrcChromaMinR = (val >> 11) & 0x1f; + voodoo->bltSrcChromaMaxB = (val >> 16) & 0x1f; + voodoo->bltSrcChromaMaxG = (val >> 21) & 0x3f; + voodoo->bltSrcChromaMaxR = (val >> 27) & 0x1f; + break; + case SST_bltDstChromaRange: + voodoo->bltDstChromaRange = val; + voodoo->bltDstChromaMinB = val & 0x1f; + voodoo->bltDstChromaMinG = (val >> 5) & 0x3f; + voodoo->bltDstChromaMinR = (val >> 11) & 0x1f; + voodoo->bltDstChromaMaxB = (val >> 16) & 0x1f; + voodoo->bltDstChromaMaxG = (val >> 21) & 0x3f; + voodoo->bltDstChromaMaxR = (val >> 27) & 0x1f; + break; + case SST_bltClipX: + voodoo->bltClipRight = val & 0xfff; + voodoo->bltClipLeft = (val >> 16) & 0xfff; + break; + case SST_bltClipY: + voodoo->bltClipHighY = val & 0xfff; + voodoo->bltClipLowY = (val >> 16) & 0xfff; + break; - case SST_bltSrcXY:voodoo->bltSrcX = val & 0x7ff; - voodoo->bltSrcY = (val >> 16) & 0x7ff; - break; - case SST_bltDstXY: -// pclog("Write bltDstXY %08x\n", val); - voodoo->bltDstX = val & 0x7ff; - voodoo->bltDstY = (val >> 16) & 0x7ff; - if (val & (1 << 31)) - voodoo_v2_blit_start(voodoo); - break; - case SST_bltSize: -// pclog("Write bltSize %08x\n", val); - voodoo->bltSizeX = val & 0xfff; - if (voodoo->bltSizeX & 0x800) - voodoo->bltSizeX |= 0xfffff000; - voodoo->bltSizeY = (val >> 16) & 0xfff; - if (voodoo->bltSizeY & 0x800) - voodoo->bltSizeY |= 0xfffff000; - if (val & (1 << 31)) - voodoo_v2_blit_start(voodoo); - break; - case SST_bltRop:voodoo->bltRop[0] = val & 0xf; - voodoo->bltRop[1] = (val >> 4) & 0xf; - voodoo->bltRop[2] = (val >> 8) & 0xf; - voodoo->bltRop[3] = (val >> 12) & 0xf; - break; - case SST_bltColor: -// pclog("Write bltColor %08x\n", val); - voodoo->bltColorFg = val & 0xffff; - voodoo->bltColorBg = (val >> 16) & 0xffff; - break; + case SST_bltSrcXY: + voodoo->bltSrcX = val & 0x7ff; + voodoo->bltSrcY = (val >> 16) & 0x7ff; + break; + case SST_bltDstXY: + // pclog("Write bltDstXY %08x\n", val); + voodoo->bltDstX = val & 0x7ff; + voodoo->bltDstY = (val >> 16) & 0x7ff; + if (val & (1 << 31)) + voodoo_v2_blit_start(voodoo); + break; + case SST_bltSize: + // pclog("Write bltSize %08x\n", val); + voodoo->bltSizeX = val & 0xfff; + if (voodoo->bltSizeX & 0x800) + voodoo->bltSizeX |= 0xfffff000; + voodoo->bltSizeY = (val >> 16) & 0xfff; + if (voodoo->bltSizeY & 0x800) + voodoo->bltSizeY |= 0xfffff000; + if (val & (1 << 31)) + voodoo_v2_blit_start(voodoo); + break; + case SST_bltRop: + voodoo->bltRop[0] = val & 0xf; + voodoo->bltRop[1] = (val >> 4) & 0xf; + voodoo->bltRop[2] = (val >> 8) & 0xf; + voodoo->bltRop[3] = (val >> 12) & 0xf; + break; + case SST_bltColor: + // pclog("Write bltColor %08x\n", val); + voodoo->bltColorFg = val & 0xffff; + voodoo->bltColorBg = (val >> 16) & 0xffff; + break; - case SST_bltCommand:voodoo->bltCommand = val; -// pclog("Write bltCommand %08x\n", val); - if (val & (1 << 31)) - voodoo_v2_blit_start(voodoo); - break; - case SST_bltData:voodoo_v2_blit_data(voodoo, val); - break; + case SST_bltCommand: + voodoo->bltCommand = val; + // pclog("Write bltCommand %08x\n", val); + if (val & (1 << 31)) + voodoo_v2_blit_start(voodoo); + break; + case SST_bltData: + voodoo_v2_blit_data(voodoo, val); + break; - case SST_textureMode: - if (chip & CHIP_TREX0) { - voodoo->params.textureMode[0] = val; - voodoo->params.tformat[0] = (val >> 8) & 0xf; - } - if (chip & CHIP_TREX1) { - voodoo->params.textureMode[1] = val; - voodoo->params.tformat[1] = (val >> 8) & 0xf; - } - break; - case SST_tLOD: - if (chip & CHIP_TREX0) { - voodoo->params.tLOD[0] = val; - voodoo_recalc_tex(voodoo, 0); - } - if (chip & CHIP_TREX1) { - voodoo->params.tLOD[1] = val; - voodoo_recalc_tex(voodoo, 1); - } - break; - case SST_tDetail: - if (chip & CHIP_TREX0) { - voodoo->params.detail_max[0] = val & 0xff; - voodoo->params.detail_bias[0] = (val >> 8) & 0x3f; - voodoo->params.detail_scale[0] = (val >> 14) & 7; - } - if (chip & CHIP_TREX1) { - voodoo->params.detail_max[1] = val & 0xff; - voodoo->params.detail_bias[1] = (val >> 8) & 0x3f; - voodoo->params.detail_scale[1] = (val >> 14) & 7; - } - break; - case SST_texBaseAddr: - if (chip & CHIP_TREX0) { - if (voodoo->type >= VOODOO_BANSHEE) - voodoo->params.texBaseAddr[0] = val & 0xfffff0; - else - voodoo->params.texBaseAddr[0] = (val & 0x7ffff) << 3; -// pclog("texBaseAddr = %08x %08x\n", voodoo->params.texBaseAddr[0], val); - voodoo_recalc_tex(voodoo, 0); - } - if (chip & CHIP_TREX1) { - if (voodoo->type >= VOODOO_BANSHEE) - voodoo->params.texBaseAddr[1] = val & 0xfffff0; - else - voodoo->params.texBaseAddr[1] = (val & 0x7ffff) << 3; - voodoo_recalc_tex(voodoo, 1); - } - break; - case SST_texBaseAddr1: - if (chip & CHIP_TREX0) { - if (voodoo->type >= VOODOO_BANSHEE) - voodoo->params.texBaseAddr1[0] = val & 0xfffff0; - else - voodoo->params.texBaseAddr1[0] = (val & 0x7ffff) << 3; - voodoo_recalc_tex(voodoo, 0); - } - if (chip & CHIP_TREX1) { - if (voodoo->type >= VOODOO_BANSHEE) - voodoo->params.texBaseAddr1[1] = val & 0xfffff0; - else - voodoo->params.texBaseAddr1[1] = (val & 0x7ffff) << 3; - voodoo_recalc_tex(voodoo, 1); - } - break; - case SST_texBaseAddr2: - if (chip & CHIP_TREX0) { - if (voodoo->type >= VOODOO_BANSHEE) - voodoo->params.texBaseAddr2[0] = val & 0xfffff0; - else - voodoo->params.texBaseAddr2[0] = (val & 0x7ffff) << 3; - voodoo_recalc_tex(voodoo, 0); - } - if (chip & CHIP_TREX1) { - if (voodoo->type >= VOODOO_BANSHEE) - voodoo->params.texBaseAddr2[1] = val & 0xfffff0; - else - voodoo->params.texBaseAddr2[1] = (val & 0x7ffff) << 3; - voodoo_recalc_tex(voodoo, 1); - } - break; - case SST_texBaseAddr38: - if (chip & CHIP_TREX0) { - if (voodoo->type >= VOODOO_BANSHEE) - voodoo->params.texBaseAddr38[0] = val & 0xfffff0; - else - voodoo->params.texBaseAddr38[0] = (val & 0x7ffff) << 3; - voodoo_recalc_tex(voodoo, 0); - } - if (chip & CHIP_TREX1) { - if (voodoo->type >= VOODOO_BANSHEE) - voodoo->params.texBaseAddr38[1] = val & 0xfffff0; - else - voodoo->params.texBaseAddr38[1] = (val & 0x7ffff) << 3; - voodoo_recalc_tex(voodoo, 1); - } - break; + case SST_textureMode: + if (chip & CHIP_TREX0) { + voodoo->params.textureMode[0] = val; + voodoo->params.tformat[0] = (val >> 8) & 0xf; + } + if (chip & CHIP_TREX1) { + voodoo->params.textureMode[1] = val; + voodoo->params.tformat[1] = (val >> 8) & 0xf; + } + break; + case SST_tLOD: + if (chip & CHIP_TREX0) { + voodoo->params.tLOD[0] = val; + voodoo_recalc_tex(voodoo, 0); + } + if (chip & CHIP_TREX1) { + voodoo->params.tLOD[1] = val; + voodoo_recalc_tex(voodoo, 1); + } + break; + case SST_tDetail: + if (chip & CHIP_TREX0) { + voodoo->params.detail_max[0] = val & 0xff; + voodoo->params.detail_bias[0] = (val >> 8) & 0x3f; + voodoo->params.detail_scale[0] = (val >> 14) & 7; + } + if (chip & CHIP_TREX1) { + voodoo->params.detail_max[1] = val & 0xff; + voodoo->params.detail_bias[1] = (val >> 8) & 0x3f; + voodoo->params.detail_scale[1] = (val >> 14) & 7; + } + break; + case SST_texBaseAddr: + if (chip & CHIP_TREX0) { + if (voodoo->type >= VOODOO_BANSHEE) + voodoo->params.texBaseAddr[0] = val & 0xfffff0; + else + voodoo->params.texBaseAddr[0] = (val & 0x7ffff) << 3; + // pclog("texBaseAddr = %08x %08x\n", voodoo->params.texBaseAddr[0], val); + voodoo_recalc_tex(voodoo, 0); + } + if (chip & CHIP_TREX1) { + if (voodoo->type >= VOODOO_BANSHEE) + voodoo->params.texBaseAddr[1] = val & 0xfffff0; + else + voodoo->params.texBaseAddr[1] = (val & 0x7ffff) << 3; + voodoo_recalc_tex(voodoo, 1); + } + break; + case SST_texBaseAddr1: + if (chip & CHIP_TREX0) { + if (voodoo->type >= VOODOO_BANSHEE) + voodoo->params.texBaseAddr1[0] = val & 0xfffff0; + else + voodoo->params.texBaseAddr1[0] = (val & 0x7ffff) << 3; + voodoo_recalc_tex(voodoo, 0); + } + if (chip & CHIP_TREX1) { + if (voodoo->type >= VOODOO_BANSHEE) + voodoo->params.texBaseAddr1[1] = val & 0xfffff0; + else + voodoo->params.texBaseAddr1[1] = (val & 0x7ffff) << 3; + voodoo_recalc_tex(voodoo, 1); + } + break; + case SST_texBaseAddr2: + if (chip & CHIP_TREX0) { + if (voodoo->type >= VOODOO_BANSHEE) + voodoo->params.texBaseAddr2[0] = val & 0xfffff0; + else + voodoo->params.texBaseAddr2[0] = (val & 0x7ffff) << 3; + voodoo_recalc_tex(voodoo, 0); + } + if (chip & CHIP_TREX1) { + if (voodoo->type >= VOODOO_BANSHEE) + voodoo->params.texBaseAddr2[1] = val & 0xfffff0; + else + voodoo->params.texBaseAddr2[1] = (val & 0x7ffff) << 3; + voodoo_recalc_tex(voodoo, 1); + } + break; + case SST_texBaseAddr38: + if (chip & CHIP_TREX0) { + if (voodoo->type >= VOODOO_BANSHEE) + voodoo->params.texBaseAddr38[0] = val & 0xfffff0; + else + voodoo->params.texBaseAddr38[0] = (val & 0x7ffff) << 3; + voodoo_recalc_tex(voodoo, 0); + } + if (chip & CHIP_TREX1) { + if (voodoo->type >= VOODOO_BANSHEE) + voodoo->params.texBaseAddr38[1] = val & 0xfffff0; + else + voodoo->params.texBaseAddr38[1] = (val & 0x7ffff) << 3; + voodoo_recalc_tex(voodoo, 1); + } + break; - case SST_trexInit1: - if (chip & CHIP_TREX0) - voodoo->trexInit1[0] = val; - if (chip & CHIP_TREX1) - voodoo->trexInit1[1] = val; - break; + case SST_trexInit1: + if (chip & CHIP_TREX0) + voodoo->trexInit1[0] = val; + if (chip & CHIP_TREX1) + voodoo->trexInit1[1] = val; + break; - case SST_nccTable0_Y0: - if (chip & CHIP_TREX0) { - voodoo->nccTable[0][0].y[0] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) { - voodoo->nccTable[1][0].y[0] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - case SST_nccTable0_Y1: - if (chip & CHIP_TREX0) { - voodoo->nccTable[0][0].y[1] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) { - voodoo->nccTable[1][0].y[1] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - case SST_nccTable0_Y2: - if (chip & CHIP_TREX0) { - voodoo->nccTable[0][0].y[2] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) { - voodoo->nccTable[1][0].y[2] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - case SST_nccTable0_Y3: - if (chip & CHIP_TREX0) { - voodoo->nccTable[0][0].y[3] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) { - voodoo->nccTable[1][0].y[3] = val; - voodoo->ncc_dirty[1] = 1; - } - break; + case SST_nccTable0_Y0: + if (chip & CHIP_TREX0) { + voodoo->nccTable[0][0].y[0] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) { + voodoo->nccTable[1][0].y[0] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + case SST_nccTable0_Y1: + if (chip & CHIP_TREX0) { + voodoo->nccTable[0][0].y[1] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) { + voodoo->nccTable[1][0].y[1] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + case SST_nccTable0_Y2: + if (chip & CHIP_TREX0) { + voodoo->nccTable[0][0].y[2] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) { + voodoo->nccTable[1][0].y[2] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + case SST_nccTable0_Y3: + if (chip & CHIP_TREX0) { + voodoo->nccTable[0][0].y[3] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) { + voodoo->nccTable[1][0].y[3] = val; + voodoo->ncc_dirty[1] = 1; + } + break; - case SST_nccTable0_I0: - if (!(val & (1 << 31))) { - if (chip & CHIP_TREX0) { - voodoo->nccTable[0][0].i[0] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) { - voodoo->nccTable[1][0].i[0] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - } - case SST_nccTable0_I2: - if (!(val & (1 << 31))) { - if (chip & CHIP_TREX0) { - voodoo->nccTable[0][0].i[2] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) { - voodoo->nccTable[1][0].i[2] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - } - case SST_nccTable0_Q0: - if (!(val & (1 << 31))) { - if (chip & CHIP_TREX0) { - voodoo->nccTable[0][0].q[0] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) { - voodoo->nccTable[1][0].q[0] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - } - case SST_nccTable0_Q2: - if (!(val & (1 << 31))) { - if (chip & CHIP_TREX0) { - voodoo->nccTable[0][0].i[2] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) { - voodoo->nccTable[1][0].i[2] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - } - if (val & (1 << 31)) { - int p = (val >> 23) & 0xfe; - if (chip & CHIP_TREX0) { - voodoo->palette[0][p].u = val | 0xff000000; - voodoo->palette_dirty[0] = 1; - } - if (chip & CHIP_TREX1) { - voodoo->palette[1][p].u = val | 0xff000000; - voodoo->palette_dirty[1] = 1; - } - } - break; + case SST_nccTable0_I0: + if (!(val & (1 << 31))) { + if (chip & CHIP_TREX0) { + voodoo->nccTable[0][0].i[0] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) { + voodoo->nccTable[1][0].i[0] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + } + case SST_nccTable0_I2: + if (!(val & (1 << 31))) { + if (chip & CHIP_TREX0) { + voodoo->nccTable[0][0].i[2] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) { + voodoo->nccTable[1][0].i[2] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + } + case SST_nccTable0_Q0: + if (!(val & (1 << 31))) { + if (chip & CHIP_TREX0) { + voodoo->nccTable[0][0].q[0] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) { + voodoo->nccTable[1][0].q[0] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + } + case SST_nccTable0_Q2: + if (!(val & (1 << 31))) { + if (chip & CHIP_TREX0) { + voodoo->nccTable[0][0].i[2] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) { + voodoo->nccTable[1][0].i[2] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + } + if (val & (1 << 31)) { + int p = (val >> 23) & 0xfe; + if (chip & CHIP_TREX0) { + voodoo->palette[0][p].u = val | 0xff000000; + voodoo->palette_dirty[0] = 1; + } + if (chip & CHIP_TREX1) { + voodoo->palette[1][p].u = val | 0xff000000; + voodoo->palette_dirty[1] = 1; + } + } + break; - case SST_nccTable0_I1: - if (!(val & (1 << 31))) { - if (chip & CHIP_TREX0) { - voodoo->nccTable[0][0].i[1] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) { - voodoo->nccTable[1][0].i[1] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - } - case SST_nccTable0_I3: - if (!(val & (1 << 31))) { - if (chip & CHIP_TREX0) { - voodoo->nccTable[0][0].i[3] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) { - voodoo->nccTable[1][0].i[3] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - } - case SST_nccTable0_Q1: - if (!(val & (1 << 31))) { - if (chip & CHIP_TREX0) { - voodoo->nccTable[0][0].q[1] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) { - voodoo->nccTable[1][0].q[1] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - } - case SST_nccTable0_Q3: - if (!(val & (1 << 31))) { - if (chip & CHIP_TREX0) { - voodoo->nccTable[0][0].q[3] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) { - voodoo->nccTable[1][0].q[3] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - } - if (val & (1 << 31)) { - int p = ((val >> 23) & 0xfe) | 0x01; - if (chip & CHIP_TREX0) { - voodoo->palette[0][p].u = val | 0xff000000; - voodoo->palette_dirty[0] = 1; - } - if (chip & CHIP_TREX1) { - voodoo->palette[1][p].u = val | 0xff000000; - voodoo->palette_dirty[1] = 1; - } - } - break; + case SST_nccTable0_I1: + if (!(val & (1 << 31))) { + if (chip & CHIP_TREX0) { + voodoo->nccTable[0][0].i[1] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) { + voodoo->nccTable[1][0].i[1] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + } + case SST_nccTable0_I3: + if (!(val & (1 << 31))) { + if (chip & CHIP_TREX0) { + voodoo->nccTable[0][0].i[3] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) { + voodoo->nccTable[1][0].i[3] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + } + case SST_nccTable0_Q1: + if (!(val & (1 << 31))) { + if (chip & CHIP_TREX0) { + voodoo->nccTable[0][0].q[1] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) { + voodoo->nccTable[1][0].q[1] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + } + case SST_nccTable0_Q3: + if (!(val & (1 << 31))) { + if (chip & CHIP_TREX0) { + voodoo->nccTable[0][0].q[3] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) { + voodoo->nccTable[1][0].q[3] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + } + if (val & (1 << 31)) { + int p = ((val >> 23) & 0xfe) | 0x01; + if (chip & CHIP_TREX0) { + voodoo->palette[0][p].u = val | 0xff000000; + voodoo->palette_dirty[0] = 1; + } + if (chip & CHIP_TREX1) { + voodoo->palette[1][p].u = val | 0xff000000; + voodoo->palette_dirty[1] = 1; + } + } + break; - case SST_nccTable1_Y0: - if (chip & CHIP_TREX0) { - voodoo->nccTable[0][1].y[0] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) { - voodoo->nccTable[1][1].y[0] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - case SST_nccTable1_Y1: - if (chip & CHIP_TREX0) { - voodoo->nccTable[0][1].y[1] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) { - voodoo->nccTable[1][1].y[1] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - case SST_nccTable1_Y2: - if (chip & CHIP_TREX0) { - voodoo->nccTable[0][1].y[2] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) { - voodoo->nccTable[1][1].y[2] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - case SST_nccTable1_Y3: - if (chip & CHIP_TREX0) { - voodoo->nccTable[0][1].y[3] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) { - voodoo->nccTable[1][1].y[3] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - case SST_nccTable1_I0: - if (chip & CHIP_TREX0) { - voodoo->nccTable[0][1].i[0] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) { - voodoo->nccTable[1][1].i[0] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - case SST_nccTable1_I1: - if (chip & CHIP_TREX0) { - voodoo->nccTable[0][1].i[1] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) { - voodoo->nccTable[1][1].i[1] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - case SST_nccTable1_I2: - if (chip & CHIP_TREX0) { - voodoo->nccTable[0][1].i[2] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) { - voodoo->nccTable[1][1].i[2] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - case SST_nccTable1_I3: - if (chip & CHIP_TREX0) { - voodoo->nccTable[0][1].i[3] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) { - voodoo->nccTable[1][1].i[3] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - case SST_nccTable1_Q0: - if (chip & CHIP_TREX0) { - voodoo->nccTable[0][1].q[0] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) { - voodoo->nccTable[1][1].q[0] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - case SST_nccTable1_Q1: - if (chip & CHIP_TREX0) { - voodoo->nccTable[0][1].q[1] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) { - voodoo->nccTable[1][1].q[1] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - case SST_nccTable1_Q2: - if (chip & CHIP_TREX0) { - voodoo->nccTable[0][1].q[2] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) { - voodoo->nccTable[1][1].q[2] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - case SST_nccTable1_Q3: - if (chip & CHIP_TREX0) { - voodoo->nccTable[0][1].q[3] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) { - voodoo->nccTable[1][1].q[3] = val; - voodoo->ncc_dirty[1] = 1; - } - break; + case SST_nccTable1_Y0: + if (chip & CHIP_TREX0) { + voodoo->nccTable[0][1].y[0] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) { + voodoo->nccTable[1][1].y[0] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + case SST_nccTable1_Y1: + if (chip & CHIP_TREX0) { + voodoo->nccTable[0][1].y[1] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) { + voodoo->nccTable[1][1].y[1] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + case SST_nccTable1_Y2: + if (chip & CHIP_TREX0) { + voodoo->nccTable[0][1].y[2] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) { + voodoo->nccTable[1][1].y[2] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + case SST_nccTable1_Y3: + if (chip & CHIP_TREX0) { + voodoo->nccTable[0][1].y[3] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) { + voodoo->nccTable[1][1].y[3] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + case SST_nccTable1_I0: + if (chip & CHIP_TREX0) { + voodoo->nccTable[0][1].i[0] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) { + voodoo->nccTable[1][1].i[0] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + case SST_nccTable1_I1: + if (chip & CHIP_TREX0) { + voodoo->nccTable[0][1].i[1] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) { + voodoo->nccTable[1][1].i[1] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + case SST_nccTable1_I2: + if (chip & CHIP_TREX0) { + voodoo->nccTable[0][1].i[2] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) { + voodoo->nccTable[1][1].i[2] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + case SST_nccTable1_I3: + if (chip & CHIP_TREX0) { + voodoo->nccTable[0][1].i[3] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) { + voodoo->nccTable[1][1].i[3] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + case SST_nccTable1_Q0: + if (chip & CHIP_TREX0) { + voodoo->nccTable[0][1].q[0] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) { + voodoo->nccTable[1][1].q[0] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + case SST_nccTable1_Q1: + if (chip & CHIP_TREX0) { + voodoo->nccTable[0][1].q[1] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) { + voodoo->nccTable[1][1].q[1] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + case SST_nccTable1_Q2: + if (chip & CHIP_TREX0) { + voodoo->nccTable[0][1].q[2] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) { + voodoo->nccTable[1][1].q[2] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + case SST_nccTable1_Q3: + if (chip & CHIP_TREX0) { + voodoo->nccTable[0][1].q[3] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) { + voodoo->nccTable[1][1].q[3] = val; + voodoo->ncc_dirty[1] = 1; + } + break; - case SST_userIntrCMD:fatal("userIntrCMD write %08x from FIFO\n", val); - break; + case SST_userIntrCMD: + fatal("userIntrCMD write %08x from FIFO\n", val); + break; - case SST_leftOverlayBuf:voodoo->leftOverlayBuf = val; - break; - } + case SST_leftOverlayBuf: + voodoo->leftOverlayBuf = val; + break; + } } diff --git a/src/video/vid_voodoo_render.c b/src/video/vid_voodoo_render.c index e9d4d4d0..8be4afa0 100644 --- a/src/video/vid_voodoo_render.c +++ b/src/video/vid_voodoo_render.c @@ -14,527 +14,549 @@ #include "vid_voodoo_texture.h" typedef struct voodoo_state_t { - int xstart, xend, xdir; - uint32_t base_r, base_g, base_b, base_a, base_z; - struct { - int64_t base_s, base_t, base_w; - int lod; - } tmu[2]; - int64_t base_w; - int lod; - int lod_min[2], lod_max[2]; - int dx1, dx2; - int y, yend, ydir; - int32_t dxAB, dxAC, dxBC; - int tex_b[2], tex_g[2], tex_r[2], tex_a[2]; - int tex_s, tex_t; - int clamp_s[2], clamp_t[2]; + int xstart, xend, xdir; + uint32_t base_r, base_g, base_b, base_a, base_z; + struct { + int64_t base_s, base_t, base_w; + int lod; + } tmu[2]; + int64_t base_w; + int lod; + int lod_min[2], lod_max[2]; + int dx1, dx2; + int y, yend, ydir; + int32_t dxAB, dxAC, dxBC; + int tex_b[2], tex_g[2], tex_r[2], tex_a[2]; + int tex_s, tex_t; + int clamp_s[2], clamp_t[2]; - int32_t vertexAx, vertexAy, vertexBx, vertexBy, vertexCx, vertexCy; + int32_t vertexAx, vertexAy, vertexBx, vertexBy, vertexCx, vertexCy; - uint32_t *tex[2][LOD_MAX + 1]; - int tformat; + uint32_t *tex[2][LOD_MAX + 1]; + int tformat; - int *tex_w_mask[2]; - int *tex_h_mask[2]; - int *tex_shift[2]; - int *tex_lod[2]; + int *tex_w_mask[2]; + int *tex_h_mask[2]; + int *tex_shift[2]; + int *tex_lod[2]; - uint16_t *fb_mem, *aux_mem; + uint16_t *fb_mem, *aux_mem; - int32_t ib, ig, ir, ia; - int32_t z; + int32_t ib, ig, ir, ia; + int32_t z; - int32_t new_depth; + int32_t new_depth; - int64_t tmu0_s, tmu0_t; - int64_t tmu0_w; - int64_t tmu1_s, tmu1_t; - int64_t tmu1_w; - int64_t w; + int64_t tmu0_s, tmu0_t; + int64_t tmu0_w; + int64_t tmu1_s, tmu1_t; + int64_t tmu1_w; + int64_t w; - int pixel_count, texel_count; - int x, x2, x_tiled; + int pixel_count, texel_count; + int x, x2, x_tiled; - uint32_t w_depth; + uint32_t w_depth; - float log_temp; - uint32_t ebp_store; - uint32_t texBaseAddr; + float log_temp; + uint32_t ebp_store; + uint32_t texBaseAddr; - int lod_frac[2]; + int lod_frac[2]; } voodoo_state_t; static int voodoo_output = 0; -static uint8_t logtable[256] = - { - 0x00, 0x01, 0x02, 0x04, 0x05, 0x07, 0x08, 0x09, 0x0b, 0x0c, 0x0e, 0x0f, 0x10, 0x12, 0x13, 0x15, - 0x16, 0x17, 0x19, 0x1a, 0x1b, 0x1d, 0x1e, 0x1f, 0x21, 0x22, 0x23, 0x25, 0x26, 0x27, 0x28, 0x2a, - 0x2b, 0x2c, 0x2e, 0x2f, 0x30, 0x31, 0x33, 0x34, 0x35, 0x36, 0x38, 0x39, 0x3a, 0x3b, 0x3d, 0x3e, - 0x3f, 0x40, 0x41, 0x43, 0x44, 0x45, 0x46, 0x47, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x50, 0x51, - 0x52, 0x53, 0x54, 0x55, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x60, 0x61, 0x62, 0x63, - 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, - 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x83, 0x84, 0x85, - 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, - 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa2, 0xa3, - 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, - 0xb3, 0xb4, 0xb5, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, - 0xc1, 0xc2, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xcd, - 0xce, 0xcf, 0xd0, 0xd1, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xda, - 0xdb, 0xdc, 0xdd, 0xde, 0xde, 0xdf, 0xe0, 0xe1, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe5, 0xe6, 0xe7, - 0xe8, 0xe8, 0xe9, 0xea, 0xeb, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xef, 0xf0, 0xf1, 0xf2, 0xf2, 0xf3, - 0xf4, 0xf5, 0xf5, 0xf6, 0xf7, 0xf7, 0xf8, 0xf9, 0xfa, 0xfa, 0xfb, 0xfc, 0xfd, 0xfd, 0xfe, 0xff - }; +static uint8_t logtable[256] = { + 0x00, 0x01, 0x02, 0x04, 0x05, 0x07, 0x08, 0x09, 0x0b, 0x0c, 0x0e, 0x0f, 0x10, 0x12, 0x13, 0x15, 0x16, 0x17, 0x19, 0x1a, + 0x1b, 0x1d, 0x1e, 0x1f, 0x21, 0x22, 0x23, 0x25, 0x26, 0x27, 0x28, 0x2a, 0x2b, 0x2c, 0x2e, 0x2f, 0x30, 0x31, 0x33, 0x34, + 0x35, 0x36, 0x38, 0x39, 0x3a, 0x3b, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x43, 0x44, 0x45, 0x46, 0x47, 0x49, 0x4a, 0x4b, 0x4c, + 0x4d, 0x4e, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x60, 0x61, 0x62, 0x63, + 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, + 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8c, + 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, + 0xa1, 0xa2, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, + 0xb3, 0xb4, 0xb5, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc2, 0xc3, + 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd1, 0xd2, 0xd3, 0xd4, + 0xd5, 0xd6, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xde, 0xdf, 0xe0, 0xe1, 0xe1, 0xe2, 0xe3, 0xe4, + 0xe5, 0xe5, 0xe6, 0xe7, 0xe8, 0xe8, 0xe9, 0xea, 0xeb, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xef, 0xf0, 0xf1, 0xf2, 0xf2, 0xf3, + 0xf4, 0xf5, 0xf5, 0xf6, 0xf7, 0xf7, 0xf8, 0xf9, 0xfa, 0xfa, 0xfb, 0xfc, 0xfd, 0xfd, 0xfe, 0xff}; static inline int fastlog(uint64_t val) { - uint64_t oldval = val; - int exp = 63; - int frac; + uint64_t oldval = val; + int exp = 63; + int frac; - if (!val || val & (1ULL << 63)) - return 0x80000000; + if (!val || val & (1ULL << 63)) + return 0x80000000; - if (!(val & 0xffffffff00000000)) { - exp -= 32; - val <<= 32; - } - if (!(val & 0xffff000000000000)) { - exp -= 16; - val <<= 16; - } - if (!(val & 0xff00000000000000)) { - exp -= 8; - val <<= 8; - } - if (!(val & 0xf000000000000000)) { - exp -= 4; - val <<= 4; - } - if (!(val & 0xc000000000000000)) { - exp -= 2; - val <<= 2; - } - if (!(val & 0x8000000000000000)) { - exp -= 1; - val <<= 1; - } + if (!(val & 0xffffffff00000000)) { + exp -= 32; + val <<= 32; + } + if (!(val & 0xffff000000000000)) { + exp -= 16; + val <<= 16; + } + if (!(val & 0xff00000000000000)) { + exp -= 8; + val <<= 8; + } + if (!(val & 0xf000000000000000)) { + exp -= 4; + val <<= 4; + } + if (!(val & 0xc000000000000000)) { + exp -= 2; + val <<= 2; + } + if (!(val & 0x8000000000000000)) { + exp -= 1; + val <<= 1; + } - if (exp >= 8) - frac = (oldval >> (exp - 8)) & 0xff; - else - frac = (oldval << (8 - exp)) & 0xff; + if (exp >= 8) + frac = (oldval >> (exp - 8)) & 0xff; + else + frac = (oldval << (8 - exp)) & 0xff; - return (exp << 8) | logtable[frac]; + return (exp << 8) | logtable[frac]; } static inline int voodoo_fls(uint16_t val) { - int num = 0; + int num = 0; -//pclog("fls(%04x) = ", val); - if (!(val & 0xff00)) { - num += 8; - val <<= 8; - } - if (!(val & 0xf000)) { - num += 4; - val <<= 4; - } - if (!(val & 0xc000)) { - num += 2; - val <<= 2; - } - if (!(val & 0x8000)) { - num += 1; - val <<= 1; - } -//pclog("%i %04x\n", num, val); - return num; + // pclog("fls(%04x) = ", val); + if (!(val & 0xff00)) { + num += 8; + val <<= 8; + } + if (!(val & 0xf000)) { + num += 4; + val <<= 4; + } + if (!(val & 0xc000)) { + num += 2; + val <<= 2; + } + if (!(val & 0x8000)) { + num += 1; + val <<= 1; + } + // pclog("%i %04x\n", num, val); + return num; } typedef struct voodoo_texture_state_t { - int s, t; - int w_mask, h_mask; - int tex_shift; + int s, t; + int w_mask, h_mask; + int tex_shift; } voodoo_texture_state_t; static inline void tex_read(voodoo_state_t *state, voodoo_texture_state_t *texture_state, int tmu) { - uint32_t dat; + uint32_t dat; - if (texture_state->s & ~texture_state->w_mask) { - if (state->clamp_s[tmu]) { - if (texture_state->s < 0) - texture_state->s = 0; - if (texture_state->s > texture_state->w_mask) - texture_state->s = texture_state->w_mask; - } else - texture_state->s &= texture_state->w_mask; - } - if (texture_state->t & ~texture_state->h_mask) { - if (state->clamp_t[tmu]) { - if (texture_state->t < 0) - texture_state->t = 0; - if (texture_state->t > texture_state->h_mask) - texture_state->t = texture_state->h_mask; - } else - texture_state->t &= texture_state->h_mask; - } + if (texture_state->s & ~texture_state->w_mask) { + if (state->clamp_s[tmu]) { + if (texture_state->s < 0) + texture_state->s = 0; + if (texture_state->s > texture_state->w_mask) + texture_state->s = texture_state->w_mask; + } else + texture_state->s &= texture_state->w_mask; + } + if (texture_state->t & ~texture_state->h_mask) { + if (state->clamp_t[tmu]) { + if (texture_state->t < 0) + texture_state->t = 0; + if (texture_state->t > texture_state->h_mask) + texture_state->t = texture_state->h_mask; + } else + texture_state->t &= texture_state->h_mask; + } - dat = state->tex[tmu][state->lod][texture_state->s + (texture_state->t << texture_state->tex_shift)]; + dat = state->tex[tmu][state->lod][texture_state->s + (texture_state->t << texture_state->tex_shift)]; - state->tex_b[tmu] = dat & 0xff; - state->tex_g[tmu] = (dat >> 8) & 0xff; - state->tex_r[tmu] = (dat >> 16) & 0xff; - state->tex_a[tmu] = (dat >> 24) & 0xff; + state->tex_b[tmu] = dat & 0xff; + state->tex_g[tmu] = (dat >> 8) & 0xff; + state->tex_r[tmu] = (dat >> 16) & 0xff; + state->tex_a[tmu] = (dat >> 24) & 0xff; } -#define LOW4(x) ((x & 0x0f) | ((x & 0x0f) << 4)) +#define LOW4(x) ((x & 0x0f) | ((x & 0x0f) << 4)) #define HIGH4(x) ((x & 0xf0) | ((x & 0xf0) >> 4)) -static inline void tex_read_4(voodoo_state_t *state, voodoo_texture_state_t *texture_state, int s, int t, int *d, int tmu, int x) { - rgba_u dat[4]; +static inline void tex_read_4(voodoo_state_t *state, voodoo_texture_state_t *texture_state, int s, int t, int *d, int tmu, + int x) { + rgba_u dat[4]; - if (((s | (s + 1)) & ~texture_state->w_mask) || ((t | (t + 1)) & ~texture_state->h_mask)) { - int c; - for (c = 0; c < 4; c++) { - int _s = s + (c & 1); - int _t = t + ((c & 2) >> 1); + if (((s | (s + 1)) & ~texture_state->w_mask) || ((t | (t + 1)) & ~texture_state->h_mask)) { + int c; + for (c = 0; c < 4; c++) { + int _s = s + (c & 1); + int _t = t + ((c & 2) >> 1); - if (_s & ~texture_state->w_mask) { - if (state->clamp_s[tmu]) { - if (_s < 0) - _s = 0; - if (_s > texture_state->w_mask) - _s = texture_state->w_mask; - } else - _s &= texture_state->w_mask; - } - if (_t & ~texture_state->h_mask) { - if (state->clamp_t[tmu]) { - if (_t < 0) - _t = 0; - if (_t > texture_state->h_mask) - _t = texture_state->h_mask; - } else - _t &= texture_state->h_mask; - } - dat[c].u = state->tex[tmu][state->lod][_s + (_t << texture_state->tex_shift)]; - } - } else { - dat[0].u = state->tex[tmu][state->lod][s + (t << texture_state->tex_shift)]; - dat[1].u = state->tex[tmu][state->lod][s + 1 + (t << texture_state->tex_shift)]; - dat[2].u = state->tex[tmu][state->lod][s + ((t + 1) << texture_state->tex_shift)]; - dat[3].u = state->tex[tmu][state->lod][s + 1 + ((t + 1) << texture_state->tex_shift)]; - } + if (_s & ~texture_state->w_mask) { + if (state->clamp_s[tmu]) { + if (_s < 0) + _s = 0; + if (_s > texture_state->w_mask) + _s = texture_state->w_mask; + } else + _s &= texture_state->w_mask; + } + if (_t & ~texture_state->h_mask) { + if (state->clamp_t[tmu]) { + if (_t < 0) + _t = 0; + if (_t > texture_state->h_mask) + _t = texture_state->h_mask; + } else + _t &= texture_state->h_mask; + } + dat[c].u = state->tex[tmu][state->lod][_s + (_t << texture_state->tex_shift)]; + } + } else { + dat[0].u = state->tex[tmu][state->lod][s + (t << texture_state->tex_shift)]; + dat[1].u = state->tex[tmu][state->lod][s + 1 + (t << texture_state->tex_shift)]; + dat[2].u = state->tex[tmu][state->lod][s + ((t + 1) << texture_state->tex_shift)]; + dat[3].u = state->tex[tmu][state->lod][s + 1 + ((t + 1) << texture_state->tex_shift)]; + } - state->tex_r[tmu] = (dat[0].rgba.r * d[0] + dat[1].rgba.r * d[1] + dat[2].rgba.r * d[2] + dat[3].rgba.r * d[3]) >> 8; - state->tex_g[tmu] = (dat[0].rgba.g * d[0] + dat[1].rgba.g * d[1] + dat[2].rgba.g * d[2] + dat[3].rgba.g * d[3]) >> 8; - state->tex_b[tmu] = (dat[0].rgba.b * d[0] + dat[1].rgba.b * d[1] + dat[2].rgba.b * d[2] + dat[3].rgba.b * d[3]) >> 8; - state->tex_a[tmu] = (dat[0].rgba.a * d[0] + dat[1].rgba.a * d[1] + dat[2].rgba.a * d[2] + dat[3].rgba.a * d[3]) >> 8; + state->tex_r[tmu] = (dat[0].rgba.r * d[0] + dat[1].rgba.r * d[1] + dat[2].rgba.r * d[2] + dat[3].rgba.r * d[3]) >> 8; + state->tex_g[tmu] = (dat[0].rgba.g * d[0] + dat[1].rgba.g * d[1] + dat[2].rgba.g * d[2] + dat[3].rgba.g * d[3]) >> 8; + state->tex_b[tmu] = (dat[0].rgba.b * d[0] + dat[1].rgba.b * d[1] + dat[2].rgba.b * d[2] + dat[3].rgba.b * d[3]) >> 8; + state->tex_a[tmu] = (dat[0].rgba.a * d[0] + dat[1].rgba.a * d[1] + dat[2].rgba.a * d[2] + dat[3].rgba.a * d[3]) >> 8; } static inline void voodoo_get_texture(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int tmu, int x) { - voodoo_texture_state_t texture_state; - int d[4]; - int s, t; - int tex_lod = state->tex_lod[tmu][state->lod]; + voodoo_texture_state_t texture_state; + int d[4]; + int s, t; + int tex_lod = state->tex_lod[tmu][state->lod]; - texture_state.w_mask = state->tex_w_mask[tmu][state->lod]; - texture_state.h_mask = state->tex_h_mask[tmu][state->lod]; - texture_state.tex_shift = 8 - tex_lod; + texture_state.w_mask = state->tex_w_mask[tmu][state->lod]; + texture_state.h_mask = state->tex_h_mask[tmu][state->lod]; + texture_state.tex_shift = 8 - tex_lod; - if (params->tLOD[tmu] & LOD_TMIRROR_S) { - if (state->tex_s & 0x1000) - state->tex_s = ~state->tex_s; - } - if (params->tLOD[tmu] & LOD_TMIRROR_T) { - if (state->tex_t & 0x1000) - state->tex_t = ~state->tex_t; - } + if (params->tLOD[tmu] & LOD_TMIRROR_S) { + if (state->tex_s & 0x1000) + state->tex_s = ~state->tex_s; + } + if (params->tLOD[tmu] & LOD_TMIRROR_T) { + if (state->tex_t & 0x1000) + state->tex_t = ~state->tex_t; + } - if (voodoo->bilinear_enabled && params->textureMode[tmu] & 6) { - int _ds, dt; + if (voodoo->bilinear_enabled && params->textureMode[tmu] & 6) { + int _ds, dt; - state->tex_s -= 1 << (3 + tex_lod); - state->tex_t -= 1 << (3 + tex_lod); + state->tex_s -= 1 << (3 + tex_lod); + state->tex_t -= 1 << (3 + tex_lod); - s = state->tex_s >> tex_lod; - t = state->tex_t >> tex_lod; + s = state->tex_s >> tex_lod; + t = state->tex_t >> tex_lod; - _ds = s & 0xf; - dt = t & 0xf; + _ds = s & 0xf; + dt = t & 0xf; - s >>= 4; - t >>= 4; -//if (x == 80) -//if (voodoo_output) -// pclog("s=%08x t=%08x _ds=%02x _dt=%02x\n", s, t, _ds, dt); - d[0] = (16 - _ds) * (16 - dt); - d[1] = _ds * (16 - dt); - d[2] = (16 - _ds) * dt; - d[3] = _ds * dt; + s >>= 4; + t >>= 4; + // if (x == 80) + // if (voodoo_output) + // pclog("s=%08x t=%08x _ds=%02x _dt=%02x\n", s, t, _ds, dt); + d[0] = (16 - _ds) * (16 - dt); + d[1] = _ds * (16 - dt); + d[2] = (16 - _ds) * dt; + d[3] = _ds * dt; -// texture_state.s = s; -// texture_state.t = t; - tex_read_4(state, &texture_state, s, t, d, tmu, x); + // texture_state.s = s; + // texture_state.t = t; + tex_read_4(state, &texture_state, s, t, d, tmu, x); + /* state->tex_r = (tex_samples[0].rgba.r * d[0] + tex_samples[1].rgba.r * d[1] + + tex_samples[2].rgba.r * d[2] + tex_samples[3].rgba.r * d[3]) >> 8; state->tex_g = (tex_samples[0].rgba.g * d[0] + + tex_samples[1].rgba.g * d[1] + tex_samples[2].rgba.g * d[2] + tex_samples[3].rgba.g * d[3]) >> 8; + state->tex_b = (tex_samples[0].rgba.b * d[0] + tex_samples[1].rgba.b * d[1] + + tex_samples[2].rgba.b * d[2] + tex_samples[3].rgba.b * d[3]) >> 8; + state->tex_a = (tex_samples[0].rgba.a * d[0] + tex_samples[1].rgba.a * d[1] + + tex_samples[2].rgba.a * d[2] + tex_samples[3].rgba.a * d[3]) >> 8;*/ + /* state->tex_r = tex_samples[0].r; + state->tex_g = tex_samples[0].g; + state->tex_b = tex_samples[0].b; + state->tex_a = tex_samples[0].a;*/ + } else { + // rgba_t tex_samples; + // voodoo_texture_state_t texture_state; + // int s = state->tex_s >> (18+state->lod); + // int t = state->tex_t >> (18+state->lod); + // int s, t; -/* state->tex_r = (tex_samples[0].rgba.r * d[0] + tex_samples[1].rgba.r * d[1] + tex_samples[2].rgba.r * d[2] + tex_samples[3].rgba.r * d[3]) >> 8; - state->tex_g = (tex_samples[0].rgba.g * d[0] + tex_samples[1].rgba.g * d[1] + tex_samples[2].rgba.g * d[2] + tex_samples[3].rgba.g * d[3]) >> 8; - state->tex_b = (tex_samples[0].rgba.b * d[0] + tex_samples[1].rgba.b * d[1] + tex_samples[2].rgba.b * d[2] + tex_samples[3].rgba.b * d[3]) >> 8; - state->tex_a = (tex_samples[0].rgba.a * d[0] + tex_samples[1].rgba.a * d[1] + tex_samples[2].rgba.a * d[2] + tex_samples[3].rgba.a * d[3]) >> 8;*/ -/* state->tex_r = tex_samples[0].r; - state->tex_g = tex_samples[0].g; - state->tex_b = tex_samples[0].b; - state->tex_a = tex_samples[0].a;*/ - } else { - // rgba_t tex_samples; - // voodoo_texture_state_t texture_state; -// int s = state->tex_s >> (18+state->lod); -// int t = state->tex_t >> (18+state->lod); - // int s, t; + // state->tex_s -= 1 << (17+state->lod); + // state->tex_t -= 1 << (17+state->lod); -// state->tex_s -= 1 << (17+state->lod); -// state->tex_t -= 1 << (17+state->lod); + s = state->tex_s >> (4 + tex_lod); + t = state->tex_t >> (4 + tex_lod); - s = state->tex_s >> (4 + tex_lod); - t = state->tex_t >> (4 + tex_lod); + texture_state.s = s; + texture_state.t = t; + tex_read(state, &texture_state, tmu); - texture_state.s = s; - texture_state.t = t; - tex_read(state, &texture_state, tmu); - -/* state->tex_r = tex_samples[0].rgba.r; - state->tex_g = tex_samples[0].rgba.g; - state->tex_b = tex_samples[0].rgba.b; - state->tex_a = tex_samples[0].rgba.a;*/ - } + /* state->tex_r = tex_samples[0].rgba.r; + state->tex_g = tex_samples[0].rgba.g; + state->tex_b = tex_samples[0].rgba.b; + state->tex_a = tex_samples[0].rgba.a;*/ + } } static inline void voodoo_tmu_fetch(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int tmu, int x) { - if (params->textureMode[tmu] & 1) { - int64_t _w = 0; + if (params->textureMode[tmu] & 1) { + int64_t _w = 0; - if (tmu) { - if (state->tmu1_w) - _w = (int64_t)((1ULL << 48) / state->tmu1_w); - state->tex_s = (int32_t)(((((state->tmu1_s + (1 << 13)) >> 14) * _w) + (1 << 29)) >> 30); - state->tex_t = (int32_t)(((((state->tmu1_t + (1 << 13)) >> 14) * _w) + (1 << 29)) >> 30); - } else { - if (state->tmu0_w) - _w = (int64_t)((1ULL << 48) / state->tmu0_w); - state->tex_s = (int32_t)(((((state->tmu0_s + (1 << 13)) >> 14) * _w) + (1 << 29)) >> 30); - state->tex_t = (int32_t)(((((state->tmu0_t + (1 << 13)) >> 14) * _w) + (1 << 29)) >> 30); - } + if (tmu) { + if (state->tmu1_w) + _w = (int64_t)((1ULL << 48) / state->tmu1_w); + state->tex_s = (int32_t)(((((state->tmu1_s + (1 << 13)) >> 14) * _w) + (1 << 29)) >> 30); + state->tex_t = (int32_t)(((((state->tmu1_t + (1 << 13)) >> 14) * _w) + (1 << 29)) >> 30); + } else { + if (state->tmu0_w) + _w = (int64_t)((1ULL << 48) / state->tmu0_w); + state->tex_s = (int32_t)(((((state->tmu0_s + (1 << 13)) >> 14) * _w) + (1 << 29)) >> 30); + state->tex_t = (int32_t)(((((state->tmu0_t + (1 << 13)) >> 14) * _w) + (1 << 29)) >> 30); + } - state->lod = state->tmu[tmu].lod + (fastlog(_w) - (19 << 8)); - } else { - if (tmu) { - state->tex_s = (int32_t)(state->tmu1_s >> (14 + 14)); - state->tex_t = (int32_t)(state->tmu1_t >> (14 + 14)); - } else { - state->tex_s = (int32_t)(state->tmu0_s >> (14 + 14)); - state->tex_t = (int32_t)(state->tmu0_t >> (14 + 14)); - } - state->lod = state->tmu[tmu].lod; - } + state->lod = state->tmu[tmu].lod + (fastlog(_w) - (19 << 8)); + } else { + if (tmu) { + state->tex_s = (int32_t)(state->tmu1_s >> (14 + 14)); + state->tex_t = (int32_t)(state->tmu1_t >> (14 + 14)); + } else { + state->tex_s = (int32_t)(state->tmu0_s >> (14 + 14)); + state->tex_t = (int32_t)(state->tmu0_t >> (14 + 14)); + } + state->lod = state->tmu[tmu].lod; + } - if (state->lod < state->lod_min[tmu]) - state->lod = state->lod_min[tmu]; - else if (state->lod > state->lod_max[tmu]) - state->lod = state->lod_max[tmu]; - state->lod_frac[tmu] = state->lod & 0xff; - state->lod >>= 8; + if (state->lod < state->lod_min[tmu]) + state->lod = state->lod_min[tmu]; + else if (state->lod > state->lod_max[tmu]) + state->lod = state->lod_max[tmu]; + state->lod_frac[tmu] = state->lod & 0xff; + state->lod >>= 8; - voodoo_get_texture(voodoo, params, state, tmu, x); + voodoo_get_texture(voodoo, params, state, tmu, x); } /*Perform texture fetch and blending for both TMUs*/ static inline void voodoo_tmu_fetch_and_blend(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int x) { - int r, g, b, a; - int c_reverse, a_reverse; -// int c_reverse1, a_reverse1; - int factor_r = 0, factor_g = 0, factor_b = 0, factor_a = 0; + int r, g, b, a; + int c_reverse, a_reverse; + // int c_reverse1, a_reverse1; + int factor_r = 0, factor_g = 0, factor_b = 0, factor_a = 0; - voodoo_tmu_fetch(voodoo, params, state, 1, x); + voodoo_tmu_fetch(voodoo, params, state, 1, x); - if ((params->textureMode[1] & TEXTUREMODE_TRILINEAR) && (state->lod & 1)) { - c_reverse = tc_reverse_blend; - a_reverse = tca_reverse_blend; - } else { - c_reverse = !tc_reverse_blend; - a_reverse = !tca_reverse_blend; - } -/* c_reverse1 = c_reverse; - a_reverse1 = a_reverse;*/ - if (tc_sub_clocal_1) { - switch (tc_mselect_1) { - case TC_MSELECT_ZERO:factor_r = factor_g = factor_b = 0; - break; - case TC_MSELECT_CLOCAL:factor_r = state->tex_r[1]; - factor_g = state->tex_g[1]; - factor_b = state->tex_b[1]; - break; - case TC_MSELECT_AOTHER:factor_r = factor_g = factor_b = 0; - break; - case TC_MSELECT_ALOCAL:factor_r = factor_g = factor_b = state->tex_a[1]; - break; - case TC_MSELECT_DETAIL:factor_r = (params->detail_bias[1] - state->lod) << params->detail_scale[1]; - if (factor_r > params->detail_max[1]) - factor_r = params->detail_max[1]; - factor_g = factor_b = factor_r; - break; - case TC_MSELECT_LOD_FRAC:factor_r = factor_g = factor_b = state->lod_frac[1]; - break; - } - if (!c_reverse) { - r = (-state->tex_r[1] * (factor_r + 1)) >> 8; - g = (-state->tex_g[1] * (factor_g + 1)) >> 8; - b = (-state->tex_b[1] * (factor_b + 1)) >> 8; - } else { - r = (-state->tex_r[1] * ((factor_r ^ 0xff) + 1)) >> 8; - g = (-state->tex_g[1] * ((factor_g ^ 0xff) + 1)) >> 8; - b = (-state->tex_b[1] * ((factor_b ^ 0xff) + 1)) >> 8; - } - if (tc_add_clocal_1) { - r += state->tex_r[1]; - g += state->tex_g[1]; - b += state->tex_b[1]; - } else if (tc_add_alocal_1) { - r += state->tex_a[1]; - g += state->tex_a[1]; - b += state->tex_a[1]; - } - state->tex_r[1] = CLAMP(r); - state->tex_g[1] = CLAMP(g); - state->tex_b[1] = CLAMP(b); - } - if (tca_sub_clocal_1) { - switch (tca_mselect_1) { - case TCA_MSELECT_ZERO:factor_a = 0; - break; - case TCA_MSELECT_CLOCAL:factor_a = state->tex_a[1]; - break; - case TCA_MSELECT_AOTHER:factor_a = 0; - break; - case TCA_MSELECT_ALOCAL:factor_a = state->tex_a[1]; - break; - case TCA_MSELECT_DETAIL:factor_a = (params->detail_bias[1] - state->lod) << params->detail_scale[1]; - if (factor_a > params->detail_max[1]) - factor_a = params->detail_max[1]; - break; - case TCA_MSELECT_LOD_FRAC:factor_a = state->lod_frac[1]; - break; - } - if (!a_reverse) - a = (-state->tex_a[1] * ((factor_a ^ 0xff) + 1)) >> 8; - else - a = (-state->tex_a[1] * (factor_a + 1)) >> 8; - if (tca_add_clocal_1 || tca_add_alocal_1) - a += state->tex_a[1]; - state->tex_a[1] = CLAMP(a); - } + if ((params->textureMode[1] & TEXTUREMODE_TRILINEAR) && (state->lod & 1)) { + c_reverse = tc_reverse_blend; + a_reverse = tca_reverse_blend; + } else { + c_reverse = !tc_reverse_blend; + a_reverse = !tca_reverse_blend; + } + /* c_reverse1 = c_reverse; + a_reverse1 = a_reverse;*/ + if (tc_sub_clocal_1) { + switch (tc_mselect_1) { + case TC_MSELECT_ZERO: + factor_r = factor_g = factor_b = 0; + break; + case TC_MSELECT_CLOCAL: + factor_r = state->tex_r[1]; + factor_g = state->tex_g[1]; + factor_b = state->tex_b[1]; + break; + case TC_MSELECT_AOTHER: + factor_r = factor_g = factor_b = 0; + break; + case TC_MSELECT_ALOCAL: + factor_r = factor_g = factor_b = state->tex_a[1]; + break; + case TC_MSELECT_DETAIL: + factor_r = (params->detail_bias[1] - state->lod) << params->detail_scale[1]; + if (factor_r > params->detail_max[1]) + factor_r = params->detail_max[1]; + factor_g = factor_b = factor_r; + break; + case TC_MSELECT_LOD_FRAC: + factor_r = factor_g = factor_b = state->lod_frac[1]; + break; + } + if (!c_reverse) { + r = (-state->tex_r[1] * (factor_r + 1)) >> 8; + g = (-state->tex_g[1] * (factor_g + 1)) >> 8; + b = (-state->tex_b[1] * (factor_b + 1)) >> 8; + } else { + r = (-state->tex_r[1] * ((factor_r ^ 0xff) + 1)) >> 8; + g = (-state->tex_g[1] * ((factor_g ^ 0xff) + 1)) >> 8; + b = (-state->tex_b[1] * ((factor_b ^ 0xff) + 1)) >> 8; + } + if (tc_add_clocal_1) { + r += state->tex_r[1]; + g += state->tex_g[1]; + b += state->tex_b[1]; + } else if (tc_add_alocal_1) { + r += state->tex_a[1]; + g += state->tex_a[1]; + b += state->tex_a[1]; + } + state->tex_r[1] = CLAMP(r); + state->tex_g[1] = CLAMP(g); + state->tex_b[1] = CLAMP(b); + } + if (tca_sub_clocal_1) { + switch (tca_mselect_1) { + case TCA_MSELECT_ZERO: + factor_a = 0; + break; + case TCA_MSELECT_CLOCAL: + factor_a = state->tex_a[1]; + break; + case TCA_MSELECT_AOTHER: + factor_a = 0; + break; + case TCA_MSELECT_ALOCAL: + factor_a = state->tex_a[1]; + break; + case TCA_MSELECT_DETAIL: + factor_a = (params->detail_bias[1] - state->lod) << params->detail_scale[1]; + if (factor_a > params->detail_max[1]) + factor_a = params->detail_max[1]; + break; + case TCA_MSELECT_LOD_FRAC: + factor_a = state->lod_frac[1]; + break; + } + if (!a_reverse) + a = (-state->tex_a[1] * ((factor_a ^ 0xff) + 1)) >> 8; + else + a = (-state->tex_a[1] * (factor_a + 1)) >> 8; + if (tca_add_clocal_1 || tca_add_alocal_1) + a += state->tex_a[1]; + state->tex_a[1] = CLAMP(a); + } - voodoo_tmu_fetch(voodoo, params, state, 0, x); + voodoo_tmu_fetch(voodoo, params, state, 0, x); - if ((params->textureMode[0] & TEXTUREMODE_TRILINEAR) && (state->lod & 1)) { - c_reverse = tc_reverse_blend; - a_reverse = tca_reverse_blend; - } else { - c_reverse = !tc_reverse_blend; - a_reverse = !tca_reverse_blend; - } + if ((params->textureMode[0] & TEXTUREMODE_TRILINEAR) && (state->lod & 1)) { + c_reverse = tc_reverse_blend; + a_reverse = tca_reverse_blend; + } else { + c_reverse = !tc_reverse_blend; + a_reverse = !tca_reverse_blend; + } - if (!tc_zero_other) { - r = state->tex_r[1]; - g = state->tex_g[1]; - b = state->tex_b[1]; - } else - r = g = b = 0; - if (tc_sub_clocal) { - r -= state->tex_r[0]; - g -= state->tex_g[0]; - b -= state->tex_b[0]; - } - switch (tc_mselect) { - case TC_MSELECT_ZERO:factor_r = factor_g = factor_b = 0; - break; - case TC_MSELECT_CLOCAL:factor_r = state->tex_r[0]; - factor_g = state->tex_g[0]; - factor_b = state->tex_b[0]; - break; - case TC_MSELECT_AOTHER:factor_r = factor_g = factor_b = state->tex_a[1]; - break; - case TC_MSELECT_ALOCAL:factor_r = factor_g = factor_b = state->tex_a[0]; - break; - case TC_MSELECT_DETAIL:factor_r = (params->detail_bias[0] - state->lod) << params->detail_scale[0]; - if (factor_r > params->detail_max[0]) - factor_r = params->detail_max[0]; - factor_g = factor_b = factor_r; - break; - case TC_MSELECT_LOD_FRAC:factor_r = factor_g = factor_b = state->lod_frac[0]; - break; - } - if (!c_reverse) { - r = (r * (factor_r + 1)) >> 8; - g = (g * (factor_g + 1)) >> 8; - b = (b * (factor_b + 1)) >> 8; - } else { - r = (r * ((factor_r ^ 0xff) + 1)) >> 8; - g = (g * ((factor_g ^ 0xff) + 1)) >> 8; - b = (b * ((factor_b ^ 0xff) + 1)) >> 8; - } - if (tc_add_clocal) { - r += state->tex_r[0]; - g += state->tex_g[0]; - b += state->tex_b[0]; - } else if (tc_add_alocal) { - r += state->tex_a[0]; - g += state->tex_a[0]; - b += state->tex_a[0]; - } + if (!tc_zero_other) { + r = state->tex_r[1]; + g = state->tex_g[1]; + b = state->tex_b[1]; + } else + r = g = b = 0; + if (tc_sub_clocal) { + r -= state->tex_r[0]; + g -= state->tex_g[0]; + b -= state->tex_b[0]; + } + switch (tc_mselect) { + case TC_MSELECT_ZERO: + factor_r = factor_g = factor_b = 0; + break; + case TC_MSELECT_CLOCAL: + factor_r = state->tex_r[0]; + factor_g = state->tex_g[0]; + factor_b = state->tex_b[0]; + break; + case TC_MSELECT_AOTHER: + factor_r = factor_g = factor_b = state->tex_a[1]; + break; + case TC_MSELECT_ALOCAL: + factor_r = factor_g = factor_b = state->tex_a[0]; + break; + case TC_MSELECT_DETAIL: + factor_r = (params->detail_bias[0] - state->lod) << params->detail_scale[0]; + if (factor_r > params->detail_max[0]) + factor_r = params->detail_max[0]; + factor_g = factor_b = factor_r; + break; + case TC_MSELECT_LOD_FRAC: + factor_r = factor_g = factor_b = state->lod_frac[0]; + break; + } + if (!c_reverse) { + r = (r * (factor_r + 1)) >> 8; + g = (g * (factor_g + 1)) >> 8; + b = (b * (factor_b + 1)) >> 8; + } else { + r = (r * ((factor_r ^ 0xff) + 1)) >> 8; + g = (g * ((factor_g ^ 0xff) + 1)) >> 8; + b = (b * ((factor_b ^ 0xff) + 1)) >> 8; + } + if (tc_add_clocal) { + r += state->tex_r[0]; + g += state->tex_g[0]; + b += state->tex_b[0]; + } else if (tc_add_alocal) { + r += state->tex_a[0]; + g += state->tex_a[0]; + b += state->tex_a[0]; + } - if (!tca_zero_other) - a = state->tex_a[1]; - else - a = 0; - if (tca_sub_clocal) - a -= state->tex_a[0]; - switch (tca_mselect) { - case TCA_MSELECT_ZERO:factor_a = 0; - break; - case TCA_MSELECT_CLOCAL:factor_a = state->tex_a[0]; - break; - case TCA_MSELECT_AOTHER:factor_a = state->tex_a[1]; - break; - case TCA_MSELECT_ALOCAL:factor_a = state->tex_a[0]; - break; - case TCA_MSELECT_DETAIL:factor_a = (params->detail_bias[0] - state->lod) << params->detail_scale[0]; - if (factor_a > params->detail_max[0]) - factor_a = params->detail_max[0]; - break; - case TCA_MSELECT_LOD_FRAC:factor_a = state->lod_frac[0]; - break; - } - if (a_reverse) - a = (a * ((factor_a ^ 0xff) + 1)) >> 8; - else - a = (a * (factor_a + 1)) >> 8; - if (tca_add_clocal || tca_add_alocal) - a += state->tex_a[0]; + if (!tca_zero_other) + a = state->tex_a[1]; + else + a = 0; + if (tca_sub_clocal) + a -= state->tex_a[0]; + switch (tca_mselect) { + case TCA_MSELECT_ZERO: + factor_a = 0; + break; + case TCA_MSELECT_CLOCAL: + factor_a = state->tex_a[0]; + break; + case TCA_MSELECT_AOTHER: + factor_a = state->tex_a[1]; + break; + case TCA_MSELECT_ALOCAL: + factor_a = state->tex_a[0]; + break; + case TCA_MSELECT_DETAIL: + factor_a = (params->detail_bias[0] - state->lod) << params->detail_scale[0]; + if (factor_a > params->detail_max[0]) + factor_a = params->detail_max[0]; + break; + case TCA_MSELECT_LOD_FRAC: + factor_a = state->lod_frac[0]; + break; + } + if (a_reverse) + a = (a * ((factor_a ^ 0xff) + 1)) >> 8; + else + a = (a * (factor_a + 1)) >> 8; + if (tca_add_clocal || tca_add_alocal) + a += state->tex_a[0]; - state->tex_r[0] = CLAMP(r); - state->tex_g[0] = CLAMP(g); - state->tex_b[0] = CLAMP(b); - state->tex_a[0] = CLAMP(a); + state->tex_r[0] = CLAMP(r); + state->tex_g[0] = CLAMP(g); + state->tex_b[0] = CLAMP(b); + state->tex_a[0] = CLAMP(a); - if (tc_invert_output) { - state->tex_r[0] ^= 0xff; - state->tex_g[0] ^= 0xff; - state->tex_b[0] ^= 0xff; - } - if (tca_invert_output) - state->tex_a[0] ^= 0xff; + if (tc_invert_output) { + state->tex_r[0] ^= 0xff; + state->tex_g[0] ^= 0xff; + state->tex_b[0] ^= 0xff; + } + if (tca_invert_output) + state->tex_a[0] ^= 0xff; } #if (defined i386 || defined __i386 || defined __i386__ || defined _X86_) && !(defined __amd64__) @@ -545,903 +567,948 @@ static inline void voodoo_tmu_fetch_and_blend(voodoo_t *voodoo, voodoo_params_t int voodoo_recomp = 0; #endif -static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int ystart, int yend, int odd_even) { -/* int rgb_sel = params->fbzColorPath & 3; - int a_sel = (params->fbzColorPath >> 2) & 3; - int cc_localselect = params->fbzColorPath & (1 << 4); - int cca_localselect = (params->fbzColorPath >> 5) & 3; - int cc_localselect_override = params->fbzColorPath & (1 << 7); - int cc_zero_other = params->fbzColorPath & (1 << 8); - int cc_sub_clocal = params->fbzColorPath & (1 << 9); - int cc_mselect = (params->fbzColorPath >> 10) & 7; - int cc_reverse_blend = params->fbzColorPath & (1 << 13); - int cc_add = (params->fbzColorPath >> 14) & 3; - int cc_add_alocal = params->fbzColorPath & (1 << 15); - int cc_invert_output = params->fbzColorPath & (1 << 16); - int cca_zero_other = params->fbzColorPath & (1 << 17); - int cca_sub_clocal = params->fbzColorPath & (1 << 18); - int cca_mselect = (params->fbzColorPath >> 19) & 7; - int cca_reverse_blend = params->fbzColorPath & (1 << 22); - int cca_add = (params->fbzColorPath >> 23) & 3; - int cca_invert_output = params->fbzColorPath & (1 << 25); - int src_afunc = (params->alphaMode >> 8) & 0xf; - int dest_afunc = (params->alphaMode >> 12) & 0xf; - int alpha_func = (params->alphaMode >> 1) & 7; - int a_ref = params->alphaMode >> 24; - int depth_op = (params->fbzMode >> 5) & 7; - int dither = params->fbzMode & FBZ_DITHER;*/ - int texels; - int c; +static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int ystart, int yend, + int odd_even) { + /* int rgb_sel = params->fbzColorPath & 3; + int a_sel = (params->fbzColorPath >> 2) & 3; + int cc_localselect = params->fbzColorPath & (1 << 4); + int cca_localselect = (params->fbzColorPath >> 5) & 3; + int cc_localselect_override = params->fbzColorPath & (1 << 7); + int cc_zero_other = params->fbzColorPath & (1 << 8); + int cc_sub_clocal = params->fbzColorPath & (1 << 9); + int cc_mselect = (params->fbzColorPath >> 10) & 7; + int cc_reverse_blend = params->fbzColorPath & (1 << 13); + int cc_add = (params->fbzColorPath >> 14) & 3; + int cc_add_alocal = params->fbzColorPath & (1 << 15); + int cc_invert_output = params->fbzColorPath & (1 << 16); + int cca_zero_other = params->fbzColorPath & (1 << 17); + int cca_sub_clocal = params->fbzColorPath & (1 << 18); + int cca_mselect = (params->fbzColorPath >> 19) & 7; + int cca_reverse_blend = params->fbzColorPath & (1 << 22); + int cca_add = (params->fbzColorPath >> 23) & 3; + int cca_invert_output = params->fbzColorPath & (1 << 25); + int src_afunc = (params->alphaMode >> 8) & 0xf; + int dest_afunc = (params->alphaMode >> 12) & 0xf; + int alpha_func = (params->alphaMode >> 1) & 7; + int a_ref = params->alphaMode >> 24; + int depth_op = (params->fbzMode >> 5) & 7; + int dither = params->fbzMode & FBZ_DITHER;*/ + int texels; + int c; #ifndef NO_CODEGEN - uint8_t (*voodoo_draw)(voodoo_state_t *state, voodoo_params_t *params, int x, int real_y); + uint8_t (*voodoo_draw)(voodoo_state_t * state, voodoo_params_t * params, int x, int real_y); #endif - int y_diff = SLI_ENABLED ? 2 : 1; - int y_origin = (voodoo->type >= VOODOO_BANSHEE) ? voodoo->y_origin_swap : (voodoo->v_disp - 1); + int y_diff = SLI_ENABLED ? 2 : 1; + int y_origin = (voodoo->type >= VOODOO_BANSHEE) ? voodoo->y_origin_swap : (voodoo->v_disp - 1); - if ((params->textureMode[0] & TEXTUREMODE_MASK) == TEXTUREMODE_PASSTHROUGH || - (params->textureMode[0] & TEXTUREMODE_LOCAL_MASK) == TEXTUREMODE_LOCAL) - texels = 1; - else - texels = 2; + if ((params->textureMode[0] & TEXTUREMODE_MASK) == TEXTUREMODE_PASSTHROUGH || + (params->textureMode[0] & TEXTUREMODE_LOCAL_MASK) == TEXTUREMODE_LOCAL) + texels = 1; + else + texels = 2; - state->clamp_s[0] = params->textureMode[0] & TEXTUREMODE_TCLAMPS; - state->clamp_t[0] = params->textureMode[0] & TEXTUREMODE_TCLAMPT; - state->clamp_s[1] = params->textureMode[1] & TEXTUREMODE_TCLAMPS; - state->clamp_t[1] = params->textureMode[1] & TEXTUREMODE_TCLAMPT; -// int last_x; -// pclog("voodoo_triangle : bottom-half %X %X %X %X %X %i %i %i %i\n", xstart, xend, dx1, dx2, dx2 * 36, xdir, y, yend, ydir); + state->clamp_s[0] = params->textureMode[0] & TEXTUREMODE_TCLAMPS; + state->clamp_t[0] = params->textureMode[0] & TEXTUREMODE_TCLAMPT; + state->clamp_s[1] = params->textureMode[1] & TEXTUREMODE_TCLAMPS; + state->clamp_t[1] = params->textureMode[1] & TEXTUREMODE_TCLAMPT; + // int last_x; + // pclog("voodoo_triangle : bottom-half %X %X %X %X %X %i %i %i %i\n", xstart, xend, dx1, dx2, dx2 * 36, xdir, y, + // yend, ydir); - for (c = 0; c <= LOD_MAX; c++) { - state->tex[0][c] = &voodoo->texture_cache[0][params->tex_entry[0]].data[texture_offset[c]]; - state->tex[1][c] = &voodoo->texture_cache[1][params->tex_entry[1]].data[texture_offset[c]]; - } + for (c = 0; c <= LOD_MAX; c++) { + state->tex[0][c] = &voodoo->texture_cache[0][params->tex_entry[0]].data[texture_offset[c]]; + state->tex[1][c] = &voodoo->texture_cache[1][params->tex_entry[1]].data[texture_offset[c]]; + } - state->tformat = params->tformat[0]; + state->tformat = params->tformat[0]; - state->tex_w_mask[0] = params->tex_w_mask[0]; - state->tex_h_mask[0] = params->tex_h_mask[0]; - state->tex_shift[0] = params->tex_shift[0]; - state->tex_lod[0] = params->tex_lod[0]; - state->tex_w_mask[1] = params->tex_w_mask[1]; - state->tex_h_mask[1] = params->tex_h_mask[1]; - state->tex_shift[1] = params->tex_shift[1]; - state->tex_lod[1] = params->tex_lod[1]; + state->tex_w_mask[0] = params->tex_w_mask[0]; + state->tex_h_mask[0] = params->tex_h_mask[0]; + state->tex_shift[0] = params->tex_shift[0]; + state->tex_lod[0] = params->tex_lod[0]; + state->tex_w_mask[1] = params->tex_w_mask[1]; + state->tex_h_mask[1] = params->tex_h_mask[1]; + state->tex_shift[1] = params->tex_shift[1]; + state->tex_lod[1] = params->tex_lod[1]; - if ((params->fbzMode & 1) && (ystart < params->clipLowY)) { - int dy = params->clipLowY - ystart; + if ((params->fbzMode & 1) && (ystart < params->clipLowY)) { + int dy = params->clipLowY - ystart; - state->base_r += params->dRdY * dy; - state->base_g += params->dGdY * dy; - state->base_b += params->dBdY * dy; - state->base_a += params->dAdY * dy; - state->base_z += params->dZdY * dy; - state->tmu[0].base_s += params->tmu[0].dSdY * dy; - state->tmu[0].base_t += params->tmu[0].dTdY * dy; - state->tmu[0].base_w += params->tmu[0].dWdY * dy; - state->tmu[1].base_s += params->tmu[1].dSdY * dy; - state->tmu[1].base_t += params->tmu[1].dTdY * dy; - state->tmu[1].base_w += params->tmu[1].dWdY * dy; - state->base_w += params->dWdY * dy; - state->xstart += state->dx1 * dy; - state->xend += state->dx2 * dy; + state->base_r += params->dRdY * dy; + state->base_g += params->dGdY * dy; + state->base_b += params->dBdY * dy; + state->base_a += params->dAdY * dy; + state->base_z += params->dZdY * dy; + state->tmu[0].base_s += params->tmu[0].dSdY * dy; + state->tmu[0].base_t += params->tmu[0].dTdY * dy; + state->tmu[0].base_w += params->tmu[0].dWdY * dy; + state->tmu[1].base_s += params->tmu[1].dSdY * dy; + state->tmu[1].base_t += params->tmu[1].dTdY * dy; + state->tmu[1].base_w += params->tmu[1].dWdY * dy; + state->base_w += params->dWdY * dy; + state->xstart += state->dx1 * dy; + state->xend += state->dx2 * dy; - ystart = params->clipLowY; - } + ystart = params->clipLowY; + } - if ((params->fbzMode & 1) && (yend >= params->clipHighY)) - yend = params->clipHighY; + if ((params->fbzMode & 1) && (yend >= params->clipHighY)) + yend = params->clipHighY; - state->y = ystart; -// yend--; + state->y = ystart; + // yend--; - if (SLI_ENABLED) { - int test_y; + if (SLI_ENABLED) { + int test_y; - if (params->fbzMode & (1 << 17)) - test_y = y_origin - state->y; - else - test_y = state->y; + if (params->fbzMode & (1 << 17)) + test_y = y_origin - state->y; + else + test_y = state->y; - if ((!(voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && (test_y & 1)) || - ((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && !(test_y & 1))) { - state->y++; + if ((!(voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && (test_y & 1)) || + ((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && !(test_y & 1))) { + state->y++; - state->base_r += params->dRdY; - state->base_g += params->dGdY; - state->base_b += params->dBdY; - state->base_a += params->dAdY; - state->base_z += params->dZdY; - state->tmu[0].base_s += params->tmu[0].dSdY; - state->tmu[0].base_t += params->tmu[0].dTdY; - state->tmu[0].base_w += params->tmu[0].dWdY; - state->tmu[1].base_s += params->tmu[1].dSdY; - state->tmu[1].base_t += params->tmu[1].dTdY; - state->tmu[1].base_w += params->tmu[1].dWdY; - state->base_w += params->dWdY; - state->xstart += state->dx1; - state->xend += state->dx2; - } - } + state->base_r += params->dRdY; + state->base_g += params->dGdY; + state->base_b += params->dBdY; + state->base_a += params->dAdY; + state->base_z += params->dZdY; + state->tmu[0].base_s += params->tmu[0].dSdY; + state->tmu[0].base_t += params->tmu[0].dTdY; + state->tmu[0].base_w += params->tmu[0].dWdY; + state->tmu[1].base_s += params->tmu[1].dSdY; + state->tmu[1].base_t += params->tmu[1].dTdY; + state->tmu[1].base_w += params->tmu[1].dWdY; + state->base_w += params->dWdY; + state->xstart += state->dx1; + state->xend += state->dx2; + } + } #ifndef NO_CODEGEN - if (voodoo->use_recompiler) - voodoo_draw = voodoo_get_block(voodoo, params, state, odd_even); - else - voodoo_draw = NULL; + if (voodoo->use_recompiler) + voodoo_draw = voodoo_get_block(voodoo, params, state, odd_even); + else + voodoo_draw = NULL; #endif - if (voodoo_output) - pclog("dxAB=%08x dxBC=%08x dxAC=%08x\n", state->dxAB, state->dxBC, state->dxAC); -// pclog("Start %i %i\n", ystart, voodoo->fbzMode & (1 << 17)); + if (voodoo_output) + pclog("dxAB=%08x dxBC=%08x dxAC=%08x\n", state->dxAB, state->dxBC, state->dxAC); + // pclog("Start %i %i\n", ystart, voodoo->fbzMode & (1 << 17)); - for (; state->y < yend; state->y += y_diff) { - int x, x2; - int real_y = (state->y << 4) + 8; - int start_x, start_x2; - int dx; - uint16_t *fb_mem, *aux_mem; + for (; state->y < yend; state->y += y_diff) { + int x, x2; + int real_y = (state->y << 4) + 8; + int start_x, start_x2; + int dx; + uint16_t *fb_mem, *aux_mem; - state->ir = state->base_r; - state->ig = state->base_g; - state->ib = state->base_b; - state->ia = state->base_a; - state->z = state->base_z; - state->tmu0_s = state->tmu[0].base_s; - state->tmu0_t = state->tmu[0].base_t; - state->tmu0_w = state->tmu[0].base_w; - state->tmu1_s = state->tmu[1].base_s; - state->tmu1_t = state->tmu[1].base_t; - state->tmu1_w = state->tmu[1].base_w; - state->w = state->base_w; + state->ir = state->base_r; + state->ig = state->base_g; + state->ib = state->base_b; + state->ia = state->base_a; + state->z = state->base_z; + state->tmu0_s = state->tmu[0].base_s; + state->tmu0_t = state->tmu[0].base_t; + state->tmu0_w = state->tmu[0].base_w; + state->tmu1_s = state->tmu[1].base_s; + state->tmu1_t = state->tmu[1].base_t; + state->tmu1_w = state->tmu[1].base_w; + state->w = state->base_w; - x = (state->vertexAx << 12) + ((state->dxAC * (real_y - state->vertexAy)) >> 4); + x = (state->vertexAx << 12) + ((state->dxAC * (real_y - state->vertexAy)) >> 4); - if (real_y < state->vertexBy) - x2 = (state->vertexAx << 12) + ((state->dxAB * (real_y - state->vertexAy)) >> 4); - else - x2 = (state->vertexBx << 12) + ((state->dxBC * (real_y - state->vertexBy)) >> 4); + if (real_y < state->vertexBy) + x2 = (state->vertexAx << 12) + ((state->dxAB * (real_y - state->vertexAy)) >> 4); + else + x2 = (state->vertexBx << 12) + ((state->dxBC * (real_y - state->vertexBy)) >> 4); - if (params->fbzMode & (1 << 17)) - real_y = y_origin - (real_y >> 4); - else - real_y >>= 4; + if (params->fbzMode & (1 << 17)) + real_y = y_origin - (real_y >> 4); + else + real_y >>= 4; - if (SLI_ENABLED) { - if (((real_y >> 1) & voodoo->odd_even_mask) != odd_even) - goto next_line; - } else { - if ((real_y & voodoo->odd_even_mask) != odd_even) - goto next_line; - } + if (SLI_ENABLED) { + if (((real_y >> 1) & voodoo->odd_even_mask) != odd_even) + goto next_line; + } else { + if ((real_y & voodoo->odd_even_mask) != odd_even) + goto next_line; + } - start_x = x; + start_x = x; - if (state->xdir > 0) - x2 -= (1 << 16); - else - x -= (1 << 16); - dx = ((x + 0x7000) >> 16) - (((state->vertexAx << 12) + 0x7000) >> 16); - start_x2 = x + 0x7000; - x = (x + 0x7000) >> 16; - x2 = (x2 + 0x7000) >> 16; + if (state->xdir > 0) + x2 -= (1 << 16); + else + x -= (1 << 16); + dx = ((x + 0x7000) >> 16) - (((state->vertexAx << 12) + 0x7000) >> 16); + start_x2 = x + 0x7000; + x = (x + 0x7000) >> 16; + x2 = (x2 + 0x7000) >> 16; - if (voodoo_output) - pclog("%03i:%03i : Ax=%08x start_x=%08x dSdX=%016llx dx=%08x s=%08x -> ", x, state->y, state->vertexAx << 8, start_x, params->tmu[0].dTdX, dx, state->tmu0_t); + if (voodoo_output) + pclog("%03i:%03i : Ax=%08x start_x=%08x dSdX=%016llx dx=%08x s=%08x -> ", x, state->y, + state->vertexAx << 8, start_x, params->tmu[0].dTdX, dx, state->tmu0_t); - state->ir += (params->dRdX * dx); - state->ig += (params->dGdX * dx); - state->ib += (params->dBdX * dx); - state->ia += (params->dAdX * dx); - state->z += (params->dZdX * dx); - state->tmu0_s += (params->tmu[0].dSdX * dx); - state->tmu0_t += (params->tmu[0].dTdX * dx); - state->tmu0_w += (params->tmu[0].dWdX * dx); - state->tmu1_s += (params->tmu[1].dSdX * dx); - state->tmu1_t += (params->tmu[1].dTdX * dx); - state->tmu1_w += (params->tmu[1].dWdX * dx); - state->w += (params->dWdX * dx); + state->ir += (params->dRdX * dx); + state->ig += (params->dGdX * dx); + state->ib += (params->dBdX * dx); + state->ia += (params->dAdX * dx); + state->z += (params->dZdX * dx); + state->tmu0_s += (params->tmu[0].dSdX * dx); + state->tmu0_t += (params->tmu[0].dTdX * dx); + state->tmu0_w += (params->tmu[0].dWdX * dx); + state->tmu1_s += (params->tmu[1].dSdX * dx); + state->tmu1_t += (params->tmu[1].dTdX * dx); + state->tmu1_w += (params->tmu[1].dWdX * dx); + state->w += (params->dWdX * dx); - if (voodoo_output) - pclog("%08llx %lli %lli\n", state->tmu0_t, state->tmu0_t >> (18 + state->lod), (state->tmu0_t + (1 << (17 + state->lod))) >> (18 + state->lod)); + if (voodoo_output) + pclog("%08llx %lli %lli\n", state->tmu0_t, state->tmu0_t >> (18 + state->lod), + (state->tmu0_t + (1 << (17 + state->lod))) >> (18 + state->lod)); - if (params->fbzMode & 1) { - if (state->xdir > 0) { - if (x < params->clipLeft) { - int dx = params->clipLeft - x; + if (params->fbzMode & 1) { + if (state->xdir > 0) { + if (x < params->clipLeft) { + int dx = params->clipLeft - x; - state->ir += params->dRdX * dx; - state->ig += params->dGdX * dx; - state->ib += params->dBdX * dx; - state->ia += params->dAdX * dx; - state->z += params->dZdX * dx; - state->tmu0_s += params->tmu[0].dSdX * dx; - state->tmu0_t += params->tmu[0].dTdX * dx; - state->tmu0_w += params->tmu[0].dWdX * dx; - state->tmu1_s += params->tmu[1].dSdX * dx; - state->tmu1_t += params->tmu[1].dTdX * dx; - state->tmu1_w += params->tmu[1].dWdX * dx; - state->w += params->dWdX * dx; + state->ir += params->dRdX * dx; + state->ig += params->dGdX * dx; + state->ib += params->dBdX * dx; + state->ia += params->dAdX * dx; + state->z += params->dZdX * dx; + state->tmu0_s += params->tmu[0].dSdX * dx; + state->tmu0_t += params->tmu[0].dTdX * dx; + state->tmu0_w += params->tmu[0].dWdX * dx; + state->tmu1_s += params->tmu[1].dSdX * dx; + state->tmu1_t += params->tmu[1].dTdX * dx; + state->tmu1_w += params->tmu[1].dWdX * dx; + state->w += params->dWdX * dx; - x = params->clipLeft; - } - if (x2 >= params->clipRight) - x2 = params->clipRight - 1; - } else { - if (x >= params->clipRight) { - int dx = (params->clipRight - 1) - x; + x = params->clipLeft; + } + if (x2 >= params->clipRight) + x2 = params->clipRight - 1; + } else { + if (x >= params->clipRight) { + int dx = (params->clipRight - 1) - x; - state->ir += params->dRdX * dx; - state->ig += params->dGdX * dx; - state->ib += params->dBdX * dx; - state->ia += params->dAdX * dx; - state->z += params->dZdX * dx; - state->tmu0_s += params->tmu[0].dSdX * dx; - state->tmu0_t += params->tmu[0].dTdX * dx; - state->tmu0_w += params->tmu[0].dWdX * dx; - state->tmu1_s += params->tmu[1].dSdX * dx; - state->tmu1_t += params->tmu[1].dTdX * dx; - state->tmu1_w += params->tmu[1].dWdX * dx; - state->w += params->dWdX * dx; + state->ir += params->dRdX * dx; + state->ig += params->dGdX * dx; + state->ib += params->dBdX * dx; + state->ia += params->dAdX * dx; + state->z += params->dZdX * dx; + state->tmu0_s += params->tmu[0].dSdX * dx; + state->tmu0_t += params->tmu[0].dTdX * dx; + state->tmu0_w += params->tmu[0].dWdX * dx; + state->tmu1_s += params->tmu[1].dSdX * dx; + state->tmu1_t += params->tmu[1].dTdX * dx; + state->tmu1_w += params->tmu[1].dWdX * dx; + state->w += params->dWdX * dx; - x = params->clipRight - 1; - } - if (x2 < params->clipLeft) - x2 = params->clipLeft; - } - } + x = params->clipRight - 1; + } + if (x2 < params->clipLeft) + x2 = params->clipLeft; + } + } - if (x2 < x && state->xdir > 0) - goto next_line; - if (x2 > x && state->xdir < 0) - goto next_line; + if (x2 < x && state->xdir > 0) + goto next_line; + if (x2 > x && state->xdir < 0) + goto next_line; - if (SLI_ENABLED) { - state->fb_mem = fb_mem = (uint16_t *)&voodoo->fb_mem[params->draw_offset + ((real_y >> 1) * params->row_width)]; - state->aux_mem = aux_mem = (uint16_t *)&voodoo->fb_mem[(params->aux_offset + ((real_y >> 1) * params->row_width)) & voodoo->fb_mask]; - } else { - if (params->col_tiled) - state->fb_mem = fb_mem = (uint16_t *)&voodoo->fb_mem[params->draw_offset + (real_y >> 5) * params->row_width + (real_y & 31) * 128]; - else - state->fb_mem = fb_mem = (uint16_t *)&voodoo->fb_mem[params->draw_offset + (real_y * params->row_width)]; - if (params->aux_tiled) - state->aux_mem = aux_mem = (uint16_t *)&voodoo->fb_mem[(params->aux_offset + (real_y >> 5) * params->aux_row_width + (real_y & 31) * 128) & voodoo->fb_mask]; - else - state->aux_mem = aux_mem = (uint16_t *)&voodoo->fb_mem[(params->aux_offset + (real_y * params->row_width)) & voodoo->fb_mask]; - } + if (SLI_ENABLED) { + state->fb_mem = fb_mem = + (uint16_t *)&voodoo->fb_mem[params->draw_offset + ((real_y >> 1) * params->row_width)]; + state->aux_mem = aux_mem = + (uint16_t *)&voodoo + ->fb_mem[(params->aux_offset + ((real_y >> 1) * params->row_width)) & voodoo->fb_mask]; + } else { + if (params->col_tiled) + state->fb_mem = fb_mem = + (uint16_t *)&voodoo->fb_mem[params->draw_offset + (real_y >> 5) * params->row_width + + (real_y & 31) * 128]; + else + state->fb_mem = fb_mem = + (uint16_t *)&voodoo->fb_mem[params->draw_offset + (real_y * params->row_width)]; + if (params->aux_tiled) + state->aux_mem = aux_mem = + (uint16_t *)&voodoo->fb_mem[(params->aux_offset + (real_y >> 5) * params->aux_row_width + + (real_y & 31) * 128) & + voodoo->fb_mask]; + else + state->aux_mem = aux_mem = + (uint16_t *)&voodoo + ->fb_mem[(params->aux_offset + (real_y * params->row_width)) & voodoo->fb_mask]; + } - if (voodoo_output) - pclog("%03i: x=%08x x2=%08x xstart=%08x xend=%08x dx=%08x start_x2=%08x\n", state->y, x, x2, state->xstart, state->xend, dx, start_x2); + if (voodoo_output) + pclog("%03i: x=%08x x2=%08x xstart=%08x xend=%08x dx=%08x start_x2=%08x\n", state->y, x, x2, + state->xstart, state->xend, dx, start_x2); - state->pixel_count = 0; - state->texel_count = 0; - state->x = x; - state->x2 = x2; + state->pixel_count = 0; + state->texel_count = 0; + state->x = x; + state->x2 = x2; #ifndef NO_CODEGEN - if (voodoo->use_recompiler) { - voodoo_draw(state, params, x, real_y); - } else + if (voodoo->use_recompiler) { + voodoo_draw(state, params, x, real_y); + } else #endif - do { - int x_tiled = (x & 63) | ((x >> 6) * 128 * 32 / 2); - start_x = x; - state->x = x; - voodoo->pixel_count[odd_even]++; - voodoo->texel_count[odd_even] += texels; - voodoo->fbiPixelsIn++; + do { + int x_tiled = (x & 63) | ((x >> 6) * 128 * 32 / 2); + start_x = x; + state->x = x; + voodoo->pixel_count[odd_even]++; + voodoo->texel_count[odd_even] += texels; + voodoo->fbiPixelsIn++; - if (voodoo_output) - pclog(" X=%03i T=%08x\n", x, state->tmu0_t); -// if (voodoo->fbzMode & FBZ_RGB_WMASK) - { - int update = 1; - uint8_t cother_r, cother_g, cother_b, aother; - uint8_t clocal_r, clocal_g, clocal_b, alocal; - int src_r = 0, src_g = 0, src_b = 0, src_a = 0; - int msel_r, msel_g, msel_b, msel_a; - uint8_t dest_r, dest_g, dest_b, dest_a; - uint16_t dat; - int sel; - int32_t new_depth, w_depth; + if (voodoo_output) + pclog(" X=%03i T=%08x\n", x, state->tmu0_t); + // if (voodoo->fbzMode & FBZ_RGB_WMASK) + { + int update = 1; + uint8_t cother_r, cother_g, cother_b, aother; + uint8_t clocal_r, clocal_g, clocal_b, alocal; + int src_r = 0, src_g = 0, src_b = 0, src_a = 0; + int msel_r, msel_g, msel_b, msel_a; + uint8_t dest_r, dest_g, dest_b, dest_a; + uint16_t dat; + int sel; + int32_t new_depth, w_depth; - if (state->w & 0xffff00000000) - w_depth = 0; - else if (!(state->w & 0xffff0000)) - w_depth = 0xf001; - else { - int exp = voodoo_fls((uint16_t)((uint32_t)state->w >> 16)); - int mant = ((~(uint32_t)state->w >> (19 - exp))) & 0xfff; - w_depth = (exp << 12) + mant + 1; - if (w_depth > 0xffff) - w_depth = 0xffff; - } + if (state->w & 0xffff00000000) + w_depth = 0; + else if (!(state->w & 0xffff0000)) + w_depth = 0xf001; + else { + int exp = voodoo_fls((uint16_t)((uint32_t)state->w >> 16)); + int mant = ((~(uint32_t)state->w >> (19 - exp))) & 0xfff; + w_depth = (exp << 12) + mant + 1; + if (w_depth > 0xffff) + w_depth = 0xffff; + } -// w_depth = CLAMP16(w_depth); + // w_depth = CLAMP16(w_depth); - if (params->fbzMode & FBZ_W_BUFFER) - new_depth = w_depth; - else - new_depth = CLAMP16(state->z >> 12); + if (params->fbzMode & FBZ_W_BUFFER) + new_depth = w_depth; + else + new_depth = CLAMP16(state->z >> 12); - if (params->fbzMode & FBZ_DEPTH_BIAS) - new_depth = CLAMP16(new_depth + (int16_t)params->zaColor); + if (params->fbzMode & FBZ_DEPTH_BIAS) + new_depth = CLAMP16(new_depth + (int16_t)params->zaColor); - if (params->fbzMode & FBZ_DEPTH_ENABLE) { - uint16_t old_depth = voodoo->params.aux_tiled ? aux_mem[x_tiled] : aux_mem[x]; + if (params->fbzMode & FBZ_DEPTH_ENABLE) { + uint16_t old_depth = voodoo->params.aux_tiled ? aux_mem[x_tiled] : aux_mem[x]; - DEPTH_TEST((params->fbzMode & FBZ_DEPTH_SOURCE) ? (params->zaColor & 0xffff) : new_depth); - } + DEPTH_TEST((params->fbzMode & FBZ_DEPTH_SOURCE) ? (params->zaColor & 0xffff) + : new_depth); + } - dat = voodoo->params.col_tiled ? fb_mem[x_tiled] : fb_mem[x]; - dest_r = (dat >> 8) & 0xf8; - dest_g = (dat >> 3) & 0xfc; - dest_b = (dat << 3) & 0xf8; - dest_r |= (dest_r >> 5); - dest_g |= (dest_g >> 6); - dest_b |= (dest_b >> 5); - dest_a = 0xff; + dat = voodoo->params.col_tiled ? fb_mem[x_tiled] : fb_mem[x]; + dest_r = (dat >> 8) & 0xf8; + dest_g = (dat >> 3) & 0xfc; + dest_b = (dat << 3) & 0xf8; + dest_r |= (dest_r >> 5); + dest_g |= (dest_g >> 6); + dest_b |= (dest_b >> 5); + dest_a = 0xff; - if (params->fbzColorPath & FBZCP_TEXTURE_ENABLED) { - if ((params->textureMode[0] & TEXTUREMODE_LOCAL_MASK) == TEXTUREMODE_LOCAL || !voodoo->dual_tmus) { - /*TMU0 only sampling local colour or only one TMU, only sample TMU0*/ - voodoo_tmu_fetch(voodoo, params, state, 0, x); - } else if ((params->textureMode[0] & TEXTUREMODE_MASK) == TEXTUREMODE_PASSTHROUGH) { - /*TMU0 in pass-through mode, only sample TMU1*/ - voodoo_tmu_fetch(voodoo, params, state, 1, x); + if (params->fbzColorPath & FBZCP_TEXTURE_ENABLED) { + if ((params->textureMode[0] & TEXTUREMODE_LOCAL_MASK) == TEXTUREMODE_LOCAL || + !voodoo->dual_tmus) { + /*TMU0 only sampling local colour or only one TMU, only sample TMU0*/ + voodoo_tmu_fetch(voodoo, params, state, 0, x); + } else if ((params->textureMode[0] & TEXTUREMODE_MASK) == + TEXTUREMODE_PASSTHROUGH) { + /*TMU0 in pass-through mode, only sample TMU1*/ + voodoo_tmu_fetch(voodoo, params, state, 1, x); - state->tex_r[0] = state->tex_r[1]; - state->tex_g[0] = state->tex_g[1]; - state->tex_b[0] = state->tex_b[1]; - state->tex_a[0] = state->tex_a[1]; - } else { - voodoo_tmu_fetch_and_blend(voodoo, params, state, x); - } + state->tex_r[0] = state->tex_r[1]; + state->tex_g[0] = state->tex_g[1]; + state->tex_b[0] = state->tex_b[1]; + state->tex_a[0] = state->tex_a[1]; + } else { + voodoo_tmu_fetch_and_blend(voodoo, params, state, x); + } - if ((params->fbzMode & FBZ_CHROMAKEY) && - state->tex_r[0] == params->chromaKey_r && - state->tex_g[0] == params->chromaKey_g && - state->tex_b[0] == params->chromaKey_b) { - voodoo->fbiChromaFail++; - goto skip_pixel; - } - } + if ((params->fbzMode & FBZ_CHROMAKEY) && state->tex_r[0] == params->chromaKey_r && + state->tex_g[0] == params->chromaKey_g && + state->tex_b[0] == params->chromaKey_b) { + voodoo->fbiChromaFail++; + goto skip_pixel; + } + } - if (voodoo->trexInit1[0] & (1 << 18)) { - state->tex_r[0] = state->tex_g[0] = 0; - state->tex_b[0] = voodoo->tmuConfig; - } + if (voodoo->trexInit1[0] & (1 << 18)) { + state->tex_r[0] = state->tex_g[0] = 0; + state->tex_b[0] = voodoo->tmuConfig; + } - if (cc_localselect_override) - sel = (state->tex_a[0] & 0x80) ? 1 : 0; - else - sel = cc_localselect; + if (cc_localselect_override) + sel = (state->tex_a[0] & 0x80) ? 1 : 0; + else + sel = cc_localselect; - if (sel) { - clocal_r = (params->color0 >> 16) & 0xff; - clocal_g = (params->color0 >> 8) & 0xff; - clocal_b = params->color0 & 0xff; - } else { - clocal_r = CLAMP(state->ir >> 12); - clocal_g = CLAMP(state->ig >> 12); - clocal_b = CLAMP(state->ib >> 12); - } + if (sel) { + clocal_r = (params->color0 >> 16) & 0xff; + clocal_g = (params->color0 >> 8) & 0xff; + clocal_b = params->color0 & 0xff; + } else { + clocal_r = CLAMP(state->ir >> 12); + clocal_g = CLAMP(state->ig >> 12); + clocal_b = CLAMP(state->ib >> 12); + } - switch (_rgb_sel) { - case CC_LOCALSELECT_ITER_RGB: /*Iterated RGB*/ - cother_r = CLAMP(state->ir >> 12); - cother_g = CLAMP(state->ig >> 12); - cother_b = CLAMP(state->ib >> 12); - break; + switch (_rgb_sel) { + case CC_LOCALSELECT_ITER_RGB: /*Iterated RGB*/ + cother_r = CLAMP(state->ir >> 12); + cother_g = CLAMP(state->ig >> 12); + cother_b = CLAMP(state->ib >> 12); + break; - case CC_LOCALSELECT_TEX: /*TREX Color Output*/ - cother_r = state->tex_r[0]; - cother_g = state->tex_g[0]; - cother_b = state->tex_b[0]; - break; + case CC_LOCALSELECT_TEX: /*TREX Color Output*/ + cother_r = state->tex_r[0]; + cother_g = state->tex_g[0]; + cother_b = state->tex_b[0]; + break; - case CC_LOCALSELECT_COLOR1: /*Color1 RGB*/ - cother_r = (params->color1 >> 16) & 0xff; - cother_g = (params->color1 >> 8) & 0xff; - cother_b = params->color1 & 0xff; - break; + case CC_LOCALSELECT_COLOR1: /*Color1 RGB*/ + cother_r = (params->color1 >> 16) & 0xff; + cother_g = (params->color1 >> 8) & 0xff; + cother_b = params->color1 & 0xff; + break; - case CC_LOCALSELECT_LFB: /*Linear Frame Buffer*/ - cother_r = src_r; - cother_g = src_g; - cother_b = src_b; - break; - } + case CC_LOCALSELECT_LFB: /*Linear Frame Buffer*/ + cother_r = src_r; + cother_g = src_g; + cother_b = src_b; + break; + } - switch (cca_localselect) { - case CCA_LOCALSELECT_ITER_A:alocal = CLAMP(state->ia >> 12); - break; + switch (cca_localselect) { + case CCA_LOCALSELECT_ITER_A: + alocal = CLAMP(state->ia >> 12); + break; - case CCA_LOCALSELECT_COLOR0:alocal = (params->color0 >> 24) & 0xff; - break; + case CCA_LOCALSELECT_COLOR0: + alocal = (params->color0 >> 24) & 0xff; + break; - case CCA_LOCALSELECT_ITER_Z:alocal = CLAMP(state->z >> 20); - break; + case CCA_LOCALSELECT_ITER_Z: + alocal = CLAMP(state->z >> 20); + break; - default:fatal("Bad cca_localselect %i\n", cca_localselect); - alocal = 0xff; - break; - } + default: + fatal("Bad cca_localselect %i\n", cca_localselect); + alocal = 0xff; + break; + } - switch (a_sel) { - case A_SEL_ITER_A:aother = CLAMP(state->ia >> 12); - break; - case A_SEL_TEX:aother = state->tex_a[0]; - break; - case A_SEL_COLOR1:aother = (params->color1 >> 24) & 0xff; - break; - default:fatal("Bad a_sel %i\n", a_sel); - aother = 0; - break; - } + switch (a_sel) { + case A_SEL_ITER_A: + aother = CLAMP(state->ia >> 12); + break; + case A_SEL_TEX: + aother = state->tex_a[0]; + break; + case A_SEL_COLOR1: + aother = (params->color1 >> 24) & 0xff; + break; + default: + fatal("Bad a_sel %i\n", a_sel); + aother = 0; + break; + } - if (cc_zero_other) { - src_r = 0; - src_g = 0; - src_b = 0; - } else { - src_r = cother_r; - src_g = cother_g; - src_b = cother_b; - } + if (cc_zero_other) { + src_r = 0; + src_g = 0; + src_b = 0; + } else { + src_r = cother_r; + src_g = cother_g; + src_b = cother_b; + } - if (cca_zero_other) - src_a = 0; - else - src_a = aother; + if (cca_zero_other) + src_a = 0; + else + src_a = aother; - if (cc_sub_clocal) { - src_r -= clocal_r; - src_g -= clocal_g; - src_b -= clocal_b; - } + if (cc_sub_clocal) { + src_r -= clocal_r; + src_g -= clocal_g; + src_b -= clocal_b; + } - if (cca_sub_clocal) - src_a -= alocal; + if (cca_sub_clocal) + src_a -= alocal; - switch (cc_mselect) { - case CC_MSELECT_ZERO:msel_r = 0; - msel_g = 0; - msel_b = 0; - break; - case CC_MSELECT_CLOCAL:msel_r = clocal_r; - msel_g = clocal_g; - msel_b = clocal_b; - break; - case CC_MSELECT_AOTHER:msel_r = aother; - msel_g = aother; - msel_b = aother; - break; - case CC_MSELECT_ALOCAL:msel_r = alocal; - msel_g = alocal; - msel_b = alocal; - break; - case CC_MSELECT_TEX:msel_r = state->tex_a[0]; - msel_g = state->tex_a[0]; - msel_b = state->tex_a[0]; - break; - case CC_MSELECT_TEXRGB:msel_r = state->tex_r[0]; - msel_g = state->tex_g[0]; - msel_b = state->tex_b[0]; - break; + switch (cc_mselect) { + case CC_MSELECT_ZERO: + msel_r = 0; + msel_g = 0; + msel_b = 0; + break; + case CC_MSELECT_CLOCAL: + msel_r = clocal_r; + msel_g = clocal_g; + msel_b = clocal_b; + break; + case CC_MSELECT_AOTHER: + msel_r = aother; + msel_g = aother; + msel_b = aother; + break; + case CC_MSELECT_ALOCAL: + msel_r = alocal; + msel_g = alocal; + msel_b = alocal; + break; + case CC_MSELECT_TEX: + msel_r = state->tex_a[0]; + msel_g = state->tex_a[0]; + msel_b = state->tex_a[0]; + break; + case CC_MSELECT_TEXRGB: + msel_r = state->tex_r[0]; + msel_g = state->tex_g[0]; + msel_b = state->tex_b[0]; + break; - default:fatal("Bad cc_mselect %i\n", cc_mselect); - msel_r = 0; - msel_g = 0; - msel_b = 0; - break; - } + default: + fatal("Bad cc_mselect %i\n", cc_mselect); + msel_r = 0; + msel_g = 0; + msel_b = 0; + break; + } - switch (cca_mselect) { - case CCA_MSELECT_ZERO:msel_a = 0; - break; - case CCA_MSELECT_ALOCAL:msel_a = alocal; - break; - case CCA_MSELECT_AOTHER:msel_a = aother; - break; - case CCA_MSELECT_ALOCAL2:msel_a = alocal; - break; - case CCA_MSELECT_TEX:msel_a = state->tex_a[0]; - break; + switch (cca_mselect) { + case CCA_MSELECT_ZERO: + msel_a = 0; + break; + case CCA_MSELECT_ALOCAL: + msel_a = alocal; + break; + case CCA_MSELECT_AOTHER: + msel_a = aother; + break; + case CCA_MSELECT_ALOCAL2: + msel_a = alocal; + break; + case CCA_MSELECT_TEX: + msel_a = state->tex_a[0]; + break; - default:fatal("Bad cca_mselect %i\n", cca_mselect); - msel_a = 0; - break; - } + default: + fatal("Bad cca_mselect %i\n", cca_mselect); + msel_a = 0; + break; + } - if (!cc_reverse_blend) { - msel_r ^= 0xff; - msel_g ^= 0xff; - msel_b ^= 0xff; - } - msel_r++; - msel_g++; - msel_b++; + if (!cc_reverse_blend) { + msel_r ^= 0xff; + msel_g ^= 0xff; + msel_b ^= 0xff; + } + msel_r++; + msel_g++; + msel_b++; - if (!cca_reverse_blend) - msel_a ^= 0xff; - msel_a++; + if (!cca_reverse_blend) + msel_a ^= 0xff; + msel_a++; - src_r = (src_r * msel_r) >> 8; - src_g = (src_g * msel_g) >> 8; - src_b = (src_b * msel_b) >> 8; - src_a = (src_a * msel_a) >> 8; + src_r = (src_r * msel_r) >> 8; + src_g = (src_g * msel_g) >> 8; + src_b = (src_b * msel_b) >> 8; + src_a = (src_a * msel_a) >> 8; - switch (cc_add) { - case CC_ADD_CLOCAL:src_r += clocal_r; - src_g += clocal_g; - src_b += clocal_b; - break; - case CC_ADD_ALOCAL:src_r += alocal; - src_g += alocal; - src_b += alocal; - break; - case 0:break; - default:fatal("Bad cc_add %i\n", cc_add); - } + switch (cc_add) { + case CC_ADD_CLOCAL: + src_r += clocal_r; + src_g += clocal_g; + src_b += clocal_b; + break; + case CC_ADD_ALOCAL: + src_r += alocal; + src_g += alocal; + src_b += alocal; + break; + case 0: + break; + default: + fatal("Bad cc_add %i\n", cc_add); + } - if (cca_add) - src_a += alocal; + if (cca_add) + src_a += alocal; - src_r = CLAMP(src_r); - src_g = CLAMP(src_g); - src_b = CLAMP(src_b); - src_a = CLAMP(src_a); + src_r = CLAMP(src_r); + src_g = CLAMP(src_g); + src_b = CLAMP(src_b); + src_a = CLAMP(src_a); - if (cc_invert_output) { - src_r ^= 0xff; - src_g ^= 0xff; - src_b ^= 0xff; - } - if (cca_invert_output) - src_a ^= 0xff; + if (cc_invert_output) { + src_r ^= 0xff; + src_g ^= 0xff; + src_b ^= 0xff; + } + if (cca_invert_output) + src_a ^= 0xff; - if (params->fogMode & FOG_ENABLE) - APPLY_FOG(src_r, src_g, src_b, state->z, state->ia, state->w); + if (params->fogMode & FOG_ENABLE) + APPLY_FOG(src_r, src_g, src_b, state->z, state->ia, state->w); - if (params->alphaMode & 1) - ALPHA_TEST(src_a); + if (params->alphaMode & 1) + ALPHA_TEST(src_a); - if (params->alphaMode & (1 << 4)) { - if (dithersub && !dither2x2 && voodoo->dithersub_enabled) { - dest_r = dithersub_rb[dest_r][real_y & 3][x & 3]; - dest_g = dithersub_g[dest_g][real_y & 3][x & 3]; - dest_b = dithersub_rb[dest_b][real_y & 3][x & 3]; - } - if (dithersub && dither2x2 && voodoo->dithersub_enabled) { - dest_r = dithersub_rb2x2[dest_r][real_y & 1][x & 1]; - dest_g = dithersub_g2x2[dest_g][real_y & 1][x & 1]; - dest_b = dithersub_rb2x2[dest_b][real_y & 1][x & 1]; - } - ALPHA_BLEND(src_r, src_g, src_b, src_a); - } + if (params->alphaMode & (1 << 4)) { + if (dithersub && !dither2x2 && voodoo->dithersub_enabled) { + dest_r = dithersub_rb[dest_r][real_y & 3][x & 3]; + dest_g = dithersub_g[dest_g][real_y & 3][x & 3]; + dest_b = dithersub_rb[dest_b][real_y & 3][x & 3]; + } + if (dithersub && dither2x2 && voodoo->dithersub_enabled) { + dest_r = dithersub_rb2x2[dest_r][real_y & 1][x & 1]; + dest_g = dithersub_g2x2[dest_g][real_y & 1][x & 1]; + dest_b = dithersub_rb2x2[dest_b][real_y & 1][x & 1]; + } + ALPHA_BLEND(src_r, src_g, src_b, src_a); + } - if (update) { - if (dither) { - if (dither2x2) { - src_r = dither_rb2x2[src_r][real_y & 1][x & 1]; - src_g = dither_g2x2[src_g][real_y & 1][x & 1]; - src_b = dither_rb2x2[src_b][real_y & 1][x & 1]; - } else { - src_r = dither_rb[src_r][real_y & 3][x & 3]; - src_g = dither_g[src_g][real_y & 3][x & 3]; - src_b = dither_rb[src_b][real_y & 3][x & 3]; - } - } else { - src_r >>= 3; - src_g >>= 2; - src_b >>= 3; - } + if (update) { + if (dither) { + if (dither2x2) { + src_r = dither_rb2x2[src_r][real_y & 1][x & 1]; + src_g = dither_g2x2[src_g][real_y & 1][x & 1]; + src_b = dither_rb2x2[src_b][real_y & 1][x & 1]; + } else { + src_r = dither_rb[src_r][real_y & 3][x & 3]; + src_g = dither_g[src_g][real_y & 3][x & 3]; + src_b = dither_rb[src_b][real_y & 3][x & 3]; + } + } else { + src_r >>= 3; + src_g >>= 2; + src_b >>= 3; + } - if (params->fbzMode & FBZ_RGB_WMASK) { - if (voodoo->params.col_tiled) - fb_mem[x_tiled] = src_b | (src_g << 5) | (src_r << 11); - else - fb_mem[x] = src_b | (src_g << 5) | (src_r << 11); - } - if ((params->fbzMode & (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) == (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) { - if (voodoo->params.aux_tiled) - aux_mem[x_tiled] = new_depth; - else - aux_mem[x] = new_depth; - } - } - } - voodoo_output &= ~2; - voodoo->fbiPixelsOut++; - skip_pixel: - if (state->xdir > 0) { - state->ir += params->dRdX; - state->ig += params->dGdX; - state->ib += params->dBdX; - state->ia += params->dAdX; - state->z += params->dZdX; - state->tmu0_s += params->tmu[0].dSdX; - state->tmu0_t += params->tmu[0].dTdX; - state->tmu0_w += params->tmu[0].dWdX; - state->tmu1_s += params->tmu[1].dSdX; - state->tmu1_t += params->tmu[1].dTdX; - state->tmu1_w += params->tmu[1].dWdX; - state->w += params->dWdX; - } else { - state->ir -= params->dRdX; - state->ig -= params->dGdX; - state->ib -= params->dBdX; - state->ia -= params->dAdX; - state->z -= params->dZdX; - state->tmu0_s -= params->tmu[0].dSdX; - state->tmu0_t -= params->tmu[0].dTdX; - state->tmu0_w -= params->tmu[0].dWdX; - state->tmu1_s -= params->tmu[1].dSdX; - state->tmu1_t -= params->tmu[1].dTdX; - state->tmu1_w -= params->tmu[1].dWdX; - state->w -= params->dWdX; - } + if (params->fbzMode & FBZ_RGB_WMASK) { + if (voodoo->params.col_tiled) + fb_mem[x_tiled] = src_b | (src_g << 5) | (src_r << 11); + else + fb_mem[x] = src_b | (src_g << 5) | (src_r << 11); + } + if ((params->fbzMode & (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) == + (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) { + if (voodoo->params.aux_tiled) + aux_mem[x_tiled] = new_depth; + else + aux_mem[x] = new_depth; + } + } + } + voodoo_output &= ~2; + voodoo->fbiPixelsOut++; + skip_pixel: + if (state->xdir > 0) { + state->ir += params->dRdX; + state->ig += params->dGdX; + state->ib += params->dBdX; + state->ia += params->dAdX; + state->z += params->dZdX; + state->tmu0_s += params->tmu[0].dSdX; + state->tmu0_t += params->tmu[0].dTdX; + state->tmu0_w += params->tmu[0].dWdX; + state->tmu1_s += params->tmu[1].dSdX; + state->tmu1_t += params->tmu[1].dTdX; + state->tmu1_w += params->tmu[1].dWdX; + state->w += params->dWdX; + } else { + state->ir -= params->dRdX; + state->ig -= params->dGdX; + state->ib -= params->dBdX; + state->ia -= params->dAdX; + state->z -= params->dZdX; + state->tmu0_s -= params->tmu[0].dSdX; + state->tmu0_t -= params->tmu[0].dTdX; + state->tmu0_w -= params->tmu[0].dWdX; + state->tmu1_s -= params->tmu[1].dSdX; + state->tmu1_t -= params->tmu[1].dTdX; + state->tmu1_w -= params->tmu[1].dWdX; + state->w -= params->dWdX; + } - x += state->xdir; - } while (start_x != x2); + x += state->xdir; + } while (start_x != x2); - voodoo->pixel_count[odd_even] += state->pixel_count; - voodoo->texel_count[odd_even] += state->texel_count; - voodoo->fbiPixelsIn += state->pixel_count; + voodoo->pixel_count[odd_even] += state->pixel_count; + voodoo->texel_count[odd_even] += state->texel_count; + voodoo->fbiPixelsIn += state->pixel_count; - if (voodoo->params.draw_offset == voodoo->params.front_offset && (real_y >> 1) < 2048) - voodoo->dirty_line[real_y >> 1] = 1; + if (voodoo->params.draw_offset == voodoo->params.front_offset && (real_y >> 1) < 2048) + voodoo->dirty_line[real_y >> 1] = 1; - next_line: - if (SLI_ENABLED) { - state->base_r += params->dRdY; - state->base_g += params->dGdY; - state->base_b += params->dBdY; - state->base_a += params->dAdY; - state->base_z += params->dZdY; - state->tmu[0].base_s += params->tmu[0].dSdY; - state->tmu[0].base_t += params->tmu[0].dTdY; - state->tmu[0].base_w += params->tmu[0].dWdY; - state->tmu[1].base_s += params->tmu[1].dSdY; - state->tmu[1].base_t += params->tmu[1].dTdY; - state->tmu[1].base_w += params->tmu[1].dWdY; - state->base_w += params->dWdY; - state->xstart += state->dx1; - state->xend += state->dx2; - } - state->base_r += params->dRdY; - state->base_g += params->dGdY; - state->base_b += params->dBdY; - state->base_a += params->dAdY; - state->base_z += params->dZdY; - state->tmu[0].base_s += params->tmu[0].dSdY; - state->tmu[0].base_t += params->tmu[0].dTdY; - state->tmu[0].base_w += params->tmu[0].dWdY; - state->tmu[1].base_s += params->tmu[1].dSdY; - state->tmu[1].base_t += params->tmu[1].dTdY; - state->tmu[1].base_w += params->tmu[1].dWdY; - state->base_w += params->dWdY; - state->xstart += state->dx1; - state->xend += state->dx2; - } + next_line: + if (SLI_ENABLED) { + state->base_r += params->dRdY; + state->base_g += params->dGdY; + state->base_b += params->dBdY; + state->base_a += params->dAdY; + state->base_z += params->dZdY; + state->tmu[0].base_s += params->tmu[0].dSdY; + state->tmu[0].base_t += params->tmu[0].dTdY; + state->tmu[0].base_w += params->tmu[0].dWdY; + state->tmu[1].base_s += params->tmu[1].dSdY; + state->tmu[1].base_t += params->tmu[1].dTdY; + state->tmu[1].base_w += params->tmu[1].dWdY; + state->base_w += params->dWdY; + state->xstart += state->dx1; + state->xend += state->dx2; + } + state->base_r += params->dRdY; + state->base_g += params->dGdY; + state->base_b += params->dBdY; + state->base_a += params->dAdY; + state->base_z += params->dZdY; + state->tmu[0].base_s += params->tmu[0].dSdY; + state->tmu[0].base_t += params->tmu[0].dTdY; + state->tmu[0].base_w += params->tmu[0].dWdY; + state->tmu[1].base_s += params->tmu[1].dSdY; + state->tmu[1].base_t += params->tmu[1].dTdY; + state->tmu[1].base_w += params->tmu[1].dWdY; + state->base_w += params->dWdY; + state->xstart += state->dx1; + state->xend += state->dx2; + } - voodoo->texture_cache[0][params->tex_entry[0]].refcount_r[odd_even]++; - voodoo->texture_cache[1][params->tex_entry[1]].refcount_r[odd_even]++; + voodoo->texture_cache[0][params->tex_entry[0]].refcount_r[odd_even]++; + voodoo->texture_cache[1][params->tex_entry[1]].refcount_r[odd_even]++; } void voodoo_triangle(voodoo_t *voodoo, voodoo_params_t *params, int odd_even) { - voodoo_state_t state; - int vertexAy_adjusted; - int vertexCy_adjusted; - int dx, dy; + voodoo_state_t state; + int vertexAy_adjusted; + int vertexCy_adjusted; + int dx, dy; - uint64_t tempdx, tempdy; - uint64_t tempLOD; - int LOD; - int lodbias; + uint64_t tempdx, tempdy; + uint64_t tempLOD; + int LOD; + int lodbias; - voodoo->tri_count++; + voodoo->tri_count++; - dx = 8 - (params->vertexAx & 0xf); - if ((params->vertexAx & 0xf) > 8) - dx += 16; - dy = 8 - (params->vertexAy & 0xf); - if ((params->vertexAy & 0xf) > 8) - dy += 16; + dx = 8 - (params->vertexAx & 0xf); + if ((params->vertexAx & 0xf) > 8) + dx += 16; + dy = 8 - (params->vertexAy & 0xf); + if ((params->vertexAy & 0xf) > 8) + dy += 16; -/* pclog("voodoo_triangle %i %i %i : vA %f, %f vB %f, %f vC %f, %f f %i,%i %08x %08x %08x,%08x tex=%i,%i fogMode=%08x\n", odd_even, voodoo->params_read_idx[odd_even], voodoo->params_read_idx[odd_even] & PARAM_MASK, (float)params->vertexAx / 16.0, (float)params->vertexAy / 16.0, - (float)params->vertexBx / 16.0, (float)params->vertexBy / 16.0, - (float)params->vertexCx / 16.0, (float)params->vertexCy / 16.0, - (params->fbzColorPath & FBZCP_TEXTURE_ENABLED) ? params->tformat[0] : 0, - (params->fbzColorPath & FBZCP_TEXTURE_ENABLED) ? params->tformat[1] : 0, params->fbzColorPath, params->alphaMode, params->textureMode[0],params->textureMode[1], params->tex_entry[0],params->tex_entry[1], params->fogMode);*/ + /* pclog("voodoo_triangle %i %i %i : vA %f, %f vB %f, %f vC %f, %f f %i,%i %08x %08x %08x,%08x tex=%i,%i + fogMode=%08x\n", odd_even, voodoo->params_read_idx[odd_even], voodoo->params_read_idx[odd_even] & PARAM_MASK, + (float)params->vertexAx / 16.0, (float)params->vertexAy / 16.0, (float)params->vertexBx / 16.0, (float)params->vertexBy + / 16.0, (float)params->vertexCx / 16.0, (float)params->vertexCy / 16.0, (params->fbzColorPath & FBZCP_TEXTURE_ENABLED) + ? params->tformat[0] : 0, (params->fbzColorPath & FBZCP_TEXTURE_ENABLED) ? params->tformat[1] : 0, + params->fbzColorPath, params->alphaMode, params->textureMode[0],params->textureMode[1], + params->tex_entry[0],params->tex_entry[1], params->fogMode);*/ - state.base_r = params->startR; - state.base_g = params->startG; - state.base_b = params->startB; - state.base_a = params->startA; - state.base_z = params->startZ; - state.tmu[0].base_s = params->tmu[0].startS; - state.tmu[0].base_t = params->tmu[0].startT; - state.tmu[0].base_w = params->tmu[0].startW; - state.tmu[1].base_s = params->tmu[1].startS; - state.tmu[1].base_t = params->tmu[1].startT; - state.tmu[1].base_w = params->tmu[1].startW; - state.base_w = params->startW; + state.base_r = params->startR; + state.base_g = params->startG; + state.base_b = params->startB; + state.base_a = params->startA; + state.base_z = params->startZ; + state.tmu[0].base_s = params->tmu[0].startS; + state.tmu[0].base_t = params->tmu[0].startT; + state.tmu[0].base_w = params->tmu[0].startW; + state.tmu[1].base_s = params->tmu[1].startS; + state.tmu[1].base_t = params->tmu[1].startT; + state.tmu[1].base_w = params->tmu[1].startW; + state.base_w = params->startW; - if (params->fbzColorPath & FBZ_PARAM_ADJUST) { - state.base_r += (dx * params->dRdX + dy * params->dRdY) >> 4; - state.base_g += (dx * params->dGdX + dy * params->dGdY) >> 4; - state.base_b += (dx * params->dBdX + dy * params->dBdY) >> 4; - state.base_a += (dx * params->dAdX + dy * params->dAdY) >> 4; - state.base_z += (dx * params->dZdX + dy * params->dZdY) >> 4; - state.tmu[0].base_s += (dx * params->tmu[0].dSdX + dy * params->tmu[0].dSdY) >> 4; - state.tmu[0].base_t += (dx * params->tmu[0].dTdX + dy * params->tmu[0].dTdY) >> 4; - state.tmu[0].base_w += (dx * params->tmu[0].dWdX + dy * params->tmu[0].dWdY) >> 4; - state.tmu[1].base_s += (dx * params->tmu[1].dSdX + dy * params->tmu[1].dSdY) >> 4; - state.tmu[1].base_t += (dx * params->tmu[1].dTdX + dy * params->tmu[1].dTdY) >> 4; - state.tmu[1].base_w += (dx * params->tmu[1].dWdX + dy * params->tmu[1].dWdY) >> 4; - state.base_w += (dx * params->dWdX + dy * params->dWdY) >> 4; - } + if (params->fbzColorPath & FBZ_PARAM_ADJUST) { + state.base_r += (dx * params->dRdX + dy * params->dRdY) >> 4; + state.base_g += (dx * params->dGdX + dy * params->dGdY) >> 4; + state.base_b += (dx * params->dBdX + dy * params->dBdY) >> 4; + state.base_a += (dx * params->dAdX + dy * params->dAdY) >> 4; + state.base_z += (dx * params->dZdX + dy * params->dZdY) >> 4; + state.tmu[0].base_s += (dx * params->tmu[0].dSdX + dy * params->tmu[0].dSdY) >> 4; + state.tmu[0].base_t += (dx * params->tmu[0].dTdX + dy * params->tmu[0].dTdY) >> 4; + state.tmu[0].base_w += (dx * params->tmu[0].dWdX + dy * params->tmu[0].dWdY) >> 4; + state.tmu[1].base_s += (dx * params->tmu[1].dSdX + dy * params->tmu[1].dSdY) >> 4; + state.tmu[1].base_t += (dx * params->tmu[1].dTdX + dy * params->tmu[1].dTdY) >> 4; + state.tmu[1].base_w += (dx * params->tmu[1].dWdX + dy * params->tmu[1].dWdY) >> 4; + state.base_w += (dx * params->dWdX + dy * params->dWdY) >> 4; + } - tris++; + tris++; - state.vertexAy = params->vertexAy & ~0xffff0000; - if (state.vertexAy & 0x8000) - state.vertexAy |= 0xffff0000; - state.vertexBy = params->vertexBy & ~0xffff0000; - if (state.vertexBy & 0x8000) - state.vertexBy |= 0xffff0000; - state.vertexCy = params->vertexCy & ~0xffff0000; - if (state.vertexCy & 0x8000) - state.vertexCy |= 0xffff0000; + state.vertexAy = params->vertexAy & ~0xffff0000; + if (state.vertexAy & 0x8000) + state.vertexAy |= 0xffff0000; + state.vertexBy = params->vertexBy & ~0xffff0000; + if (state.vertexBy & 0x8000) + state.vertexBy |= 0xffff0000; + state.vertexCy = params->vertexCy & ~0xffff0000; + if (state.vertexCy & 0x8000) + state.vertexCy |= 0xffff0000; - state.vertexAx = params->vertexAx & ~0xffff0000; - if (state.vertexAx & 0x8000) - state.vertexAx |= 0xffff0000; - state.vertexBx = params->vertexBx & ~0xffff0000; - if (state.vertexBx & 0x8000) - state.vertexBx |= 0xffff0000; - state.vertexCx = params->vertexCx & ~0xffff0000; - if (state.vertexCx & 0x8000) - state.vertexCx |= 0xffff0000; + state.vertexAx = params->vertexAx & ~0xffff0000; + if (state.vertexAx & 0x8000) + state.vertexAx |= 0xffff0000; + state.vertexBx = params->vertexBx & ~0xffff0000; + if (state.vertexBx & 0x8000) + state.vertexBx |= 0xffff0000; + state.vertexCx = params->vertexCx & ~0xffff0000; + if (state.vertexCx & 0x8000) + state.vertexCx |= 0xffff0000; - vertexAy_adjusted = (state.vertexAy + 7) >> 4; - vertexCy_adjusted = (state.vertexCy + 7) >> 4; + vertexAy_adjusted = (state.vertexAy + 7) >> 4; + vertexCy_adjusted = (state.vertexCy + 7) >> 4; - if (state.vertexBy - state.vertexAy) - state.dxAB = (int)((((int64_t)state.vertexBx << 12) - ((int64_t)state.vertexAx << 12)) << 4) / (int)(state.vertexBy - state.vertexAy); - else - state.dxAB = 0; - if (state.vertexCy - state.vertexAy) - state.dxAC = (int)((((int64_t)state.vertexCx << 12) - ((int64_t)state.vertexAx << 12)) << 4) / (int)(state.vertexCy - state.vertexAy); - else - state.dxAC = 0; - if (state.vertexCy - state.vertexBy) - state.dxBC = (int)((((int64_t)state.vertexCx << 12) - ((int64_t)state.vertexBx << 12)) << 4) / (int)(state.vertexCy - state.vertexBy); - else - state.dxBC = 0; + if (state.vertexBy - state.vertexAy) + state.dxAB = (int)((((int64_t)state.vertexBx << 12) - ((int64_t)state.vertexAx << 12)) << 4) / + (int)(state.vertexBy - state.vertexAy); + else + state.dxAB = 0; + if (state.vertexCy - state.vertexAy) + state.dxAC = (int)((((int64_t)state.vertexCx << 12) - ((int64_t)state.vertexAx << 12)) << 4) / + (int)(state.vertexCy - state.vertexAy); + else + state.dxAC = 0; + if (state.vertexCy - state.vertexBy) + state.dxBC = (int)((((int64_t)state.vertexCx << 12) - ((int64_t)state.vertexBx << 12)) << 4) / + (int)(state.vertexCy - state.vertexBy); + else + state.dxBC = 0; - state.lod_min[0] = (params->tLOD[0] & 0x3f) << 6; - state.lod_max[0] = ((params->tLOD[0] >> 6) & 0x3f) << 6; - if (state.lod_max[0] > 0x800) - state.lod_max[0] = 0x800; - state.lod_min[1] = (params->tLOD[1] & 0x3f) << 6; - state.lod_max[1] = ((params->tLOD[1] >> 6) & 0x3f) << 6; - if (state.lod_max[1] > 0x800) - state.lod_max[1] = 0x800; + state.lod_min[0] = (params->tLOD[0] & 0x3f) << 6; + state.lod_max[0] = ((params->tLOD[0] >> 6) & 0x3f) << 6; + if (state.lod_max[0] > 0x800) + state.lod_max[0] = 0x800; + state.lod_min[1] = (params->tLOD[1] & 0x3f) << 6; + state.lod_max[1] = ((params->tLOD[1] >> 6) & 0x3f) << 6; + if (state.lod_max[1] > 0x800) + state.lod_max[1] = 0x800; - state.xstart = state.xend = state.vertexAx << 8; - state.xdir = params->sign ? -1 : 1; + state.xstart = state.xend = state.vertexAx << 8; + state.xdir = params->sign ? -1 : 1; - state.y = (state.vertexAy + 8) >> 4; - state.ydir = 1; + state.y = (state.vertexAy + 8) >> 4; + state.ydir = 1; - tempdx = (params->tmu[0].dSdX >> 14) * (params->tmu[0].dSdX >> 14) + (params->tmu[0].dTdX >> 14) * (params->tmu[0].dTdX >> 14); - tempdy = (params->tmu[0].dSdY >> 14) * (params->tmu[0].dSdY >> 14) + (params->tmu[0].dTdY >> 14) * (params->tmu[0].dTdY >> 14); + tempdx = (params->tmu[0].dSdX >> 14) * (params->tmu[0].dSdX >> 14) + + (params->tmu[0].dTdX >> 14) * (params->tmu[0].dTdX >> 14); + tempdy = (params->tmu[0].dSdY >> 14) * (params->tmu[0].dSdY >> 14) + + (params->tmu[0].dTdY >> 14) * (params->tmu[0].dTdY >> 14); - if (tempdx > tempdy) - tempLOD = tempdx; - else - tempLOD = tempdy; + if (tempdx > tempdy) + tempLOD = tempdx; + else + tempLOD = tempdy; - LOD = (int)(log2((double)tempLOD / (double)(1ULL << 36)) * 256); - LOD >>= 2; + LOD = (int)(log2((double)tempLOD / (double)(1ULL << 36)) * 256); + LOD >>= 2; - lodbias = (params->tLOD[0] >> 12) & 0x3f; - if (lodbias & 0x20) - lodbias |= ~0x3f; - state.tmu[0].lod = LOD + (lodbias << 6); + lodbias = (params->tLOD[0] >> 12) & 0x3f; + if (lodbias & 0x20) + lodbias |= ~0x3f; + state.tmu[0].lod = LOD + (lodbias << 6); - tempdx = (params->tmu[1].dSdX >> 14) * (params->tmu[1].dSdX >> 14) + (params->tmu[1].dTdX >> 14) * (params->tmu[1].dTdX >> 14); - tempdy = (params->tmu[1].dSdY >> 14) * (params->tmu[1].dSdY >> 14) + (params->tmu[1].dTdY >> 14) * (params->tmu[1].dTdY >> 14); + tempdx = (params->tmu[1].dSdX >> 14) * (params->tmu[1].dSdX >> 14) + + (params->tmu[1].dTdX >> 14) * (params->tmu[1].dTdX >> 14); + tempdy = (params->tmu[1].dSdY >> 14) * (params->tmu[1].dSdY >> 14) + + (params->tmu[1].dTdY >> 14) * (params->tmu[1].dTdY >> 14); - if (tempdx > tempdy) - tempLOD = tempdx; - else - tempLOD = tempdy; + if (tempdx > tempdy) + tempLOD = tempdx; + else + tempLOD = tempdy; - LOD = (int)(log2((double)tempLOD / (double)(1ULL << 36)) * 256); - LOD >>= 2; + LOD = (int)(log2((double)tempLOD / (double)(1ULL << 36)) * 256); + LOD >>= 2; - lodbias = (params->tLOD[1] >> 12) & 0x3f; - if (lodbias & 0x20) - lodbias |= ~0x3f; - state.tmu[1].lod = LOD + (lodbias << 6); + lodbias = (params->tLOD[1] >> 12) & 0x3f; + if (lodbias & 0x20) + lodbias |= ~0x3f; + state.tmu[1].lod = LOD + (lodbias << 6); - voodoo_half_triangle(voodoo, params, &state, vertexAy_adjusted, vertexCy_adjusted, odd_even); + voodoo_half_triangle(voodoo, params, &state, vertexAy_adjusted, vertexCy_adjusted, odd_even); } static void render_thread(void *param, int odd_even) { - voodoo_t *voodoo = (voodoo_t *)param; + voodoo_t *voodoo = (voodoo_t *)param; - while (1) { - thread_set_event(voodoo->render_not_full_event[odd_even]); - thread_wait_event(voodoo->wake_render_thread[odd_even], -1); - thread_reset_event(voodoo->wake_render_thread[odd_even]); - voodoo->render_voodoo_busy[odd_even] = 1; + while (1) { + thread_set_event(voodoo->render_not_full_event[odd_even]); + thread_wait_event(voodoo->wake_render_thread[odd_even], -1); + thread_reset_event(voodoo->wake_render_thread[odd_even]); + voodoo->render_voodoo_busy[odd_even] = 1; - while (!PARAM_EMPTY(odd_even)) { - uint64_t start_time = timer_read(); - uint64_t end_time; - voodoo_params_t *params = &voodoo->params_buffer[voodoo->params_read_idx[odd_even] & PARAM_MASK]; + while (!PARAM_EMPTY(odd_even)) { + uint64_t start_time = timer_read(); + uint64_t end_time; + voodoo_params_t *params = &voodoo->params_buffer[voodoo->params_read_idx[odd_even] & PARAM_MASK]; - voodoo_triangle(voodoo, params, odd_even); + voodoo_triangle(voodoo, params, odd_even); - voodoo->params_read_idx[odd_even]++; + voodoo->params_read_idx[odd_even]++; - if (PARAM_ENTRIES(odd_even) > (PARAM_SIZE - 10)) - thread_set_event(voodoo->render_not_full_event[odd_even]); + if (PARAM_ENTRIES(odd_even) > (PARAM_SIZE - 10)) + thread_set_event(voodoo->render_not_full_event[odd_even]); - end_time = timer_read(); - voodoo->render_time[odd_even] += end_time - start_time; - } + end_time = timer_read(); + voodoo->render_time[odd_even] += end_time - start_time; + } - voodoo->render_voodoo_busy[odd_even] = 0; - } + voodoo->render_voodoo_busy[odd_even] = 0; + } } -void voodoo_render_thread_1(void *param) { - render_thread(param, 0); -} -void voodoo_render_thread_2(void *param) { - render_thread(param, 1); -} -void voodoo_render_thread_3(void *param) { - render_thread(param, 2); -} -void voodoo_render_thread_4(void *param) { - render_thread(param, 3); -} +void voodoo_render_thread_1(void *param) { render_thread(param, 0); } +void voodoo_render_thread_2(void *param) { render_thread(param, 1); } +void voodoo_render_thread_3(void *param) { render_thread(param, 2); } +void voodoo_render_thread_4(void *param) { render_thread(param, 3); } void voodoo_queue_triangle(voodoo_t *voodoo, voodoo_params_t *params) { - voodoo_params_t *params_new = &voodoo->params_buffer[voodoo->params_write_idx & PARAM_MASK]; + voodoo_params_t *params_new = &voodoo->params_buffer[voodoo->params_write_idx & PARAM_MASK]; - while (PARAM_FULL(0) || (voodoo->render_threads >= 2 && PARAM_FULL(1)) || - (voodoo->render_threads == 4 && (PARAM_FULL(2) || PARAM_FULL(3)))) { - thread_reset_event(voodoo->render_not_full_event[0]); - if (voodoo->render_threads >= 2) - thread_reset_event(voodoo->render_not_full_event[1]); - if (voodoo->render_threads == 4) { - thread_reset_event(voodoo->render_not_full_event[2]); - thread_reset_event(voodoo->render_not_full_event[3]); - } - if (PARAM_FULL(0)) - thread_wait_event(voodoo->render_not_full_event[0], -1); /*Wait for room in ringbuffer*/ - if (voodoo->render_threads >= 2 && PARAM_FULL(1)) - thread_wait_event(voodoo->render_not_full_event[1], -1); /*Wait for room in ringbuffer*/ - if (voodoo->render_threads == 4 && PARAM_FULL(2)) - thread_wait_event(voodoo->render_not_full_event[2], -1); /*Wait for room in ringbuffer*/ - if (voodoo->render_threads == 4 && PARAM_FULL(3)) - thread_wait_event(voodoo->render_not_full_event[3], -1); /*Wait for room in ringbuffer*/ - } + while (PARAM_FULL(0) || (voodoo->render_threads >= 2 && PARAM_FULL(1)) || + (voodoo->render_threads == 4 && (PARAM_FULL(2) || PARAM_FULL(3)))) { + thread_reset_event(voodoo->render_not_full_event[0]); + if (voodoo->render_threads >= 2) + thread_reset_event(voodoo->render_not_full_event[1]); + if (voodoo->render_threads == 4) { + thread_reset_event(voodoo->render_not_full_event[2]); + thread_reset_event(voodoo->render_not_full_event[3]); + } + if (PARAM_FULL(0)) + thread_wait_event(voodoo->render_not_full_event[0], -1); /*Wait for room in ringbuffer*/ + if (voodoo->render_threads >= 2 && PARAM_FULL(1)) + thread_wait_event(voodoo->render_not_full_event[1], -1); /*Wait for room in ringbuffer*/ + if (voodoo->render_threads == 4 && PARAM_FULL(2)) + thread_wait_event(voodoo->render_not_full_event[2], -1); /*Wait for room in ringbuffer*/ + if (voodoo->render_threads == 4 && PARAM_FULL(3)) + thread_wait_event(voodoo->render_not_full_event[3], -1); /*Wait for room in ringbuffer*/ + } - voodoo_use_texture(voodoo, params, 0); - if (voodoo->dual_tmus) - voodoo_use_texture(voodoo, params, 1); + voodoo_use_texture(voodoo, params, 0); + if (voodoo->dual_tmus) + voodoo_use_texture(voodoo, params, 1); - memcpy(params_new, params, sizeof(voodoo_params_t)); + memcpy(params_new, params, sizeof(voodoo_params_t)); - voodoo->params_write_idx++; + voodoo->params_write_idx++; - if (PARAM_ENTRIES(0) < 4 || (voodoo->render_threads >= 2 && PARAM_ENTRIES(1) < 4) || - (voodoo->render_threads == 4 && (PARAM_ENTRIES(2) < 4 || PARAM_ENTRIES(3) < 4))) - voodoo_wake_render_thread(voodoo); + if (PARAM_ENTRIES(0) < 4 || (voodoo->render_threads >= 2 && PARAM_ENTRIES(1) < 4) || + (voodoo->render_threads == 4 && (PARAM_ENTRIES(2) < 4 || PARAM_ENTRIES(3) < 4))) + voodoo_wake_render_thread(voodoo); } diff --git a/src/video/vid_voodoo_setup.c b/src/video/vid_voodoo_setup.c index 5b8d3dee..607e4425 100644 --- a/src/video/vid_voodoo_setup.c +++ b/src/video/vid_voodoo_setup.c @@ -11,177 +11,202 @@ #include "vid_voodoo_setup.h" void voodoo_triangle_setup(voodoo_t *voodoo) { - float dxAB, dxBC, dyAB, dyBC; - float area; - int va = 0, vb = 1, vc = 2; - vert_t verts[3]; + float dxAB, dxBC, dyAB, dyBC; + float area; + int va = 0, vb = 1, vc = 2; + vert_t verts[3]; - verts[0] = voodoo->verts[0]; - verts[1] = voodoo->verts[1]; - verts[2] = voodoo->verts[2]; + verts[0] = voodoo->verts[0]; + verts[1] = voodoo->verts[1]; + verts[2] = voodoo->verts[2]; - if (verts[0].sVy < verts[1].sVy) { - if (verts[1].sVy < verts[2].sVy) { - /* V1>V0, V2>V1, V2>V1>V0*/ - va = 0; /*OK*/ - vb = 1; - vc = 2; - } else { - /* V1>V0, V1>V2*/ - if (verts[0].sVy < verts[2].sVy) { - /* V1>V0, V1>V2, V2>V0, V1>V2>V0*/ - va = 0; - vb = 2; - vc = 1; - } else { - /* V1>V0, V1>V2, V0>V2, V1>V0>V2*/ - va = 2; - vb = 0; - vc = 1; - } - } - } else { - if (verts[1].sVy < verts[2].sVy) { - /* V0>V1, V2>V1*/ - if (verts[0].sVy < verts[2].sVy) { - /* V0>V1, V2>V1, V2>V0, V2>V0>V1*/ - va = 1; - vb = 0; - vc = 2; - } else { - /* V0>V1, V2>V1, V0>V2, V0>V2>V1*/ - va = 1; - vb = 2; - vc = 0; - } - } else { - /*V0>V1>V2*/ - va = 2; - vb = 1; - vc = 0; - } - } + if (verts[0].sVy < verts[1].sVy) { + if (verts[1].sVy < verts[2].sVy) { + /* V1>V0, V2>V1, V2>V1>V0*/ + va = 0; /*OK*/ + vb = 1; + vc = 2; + } else { + /* V1>V0, V1>V2*/ + if (verts[0].sVy < verts[2].sVy) { + /* V1>V0, V1>V2, V2>V0, V1>V2>V0*/ + va = 0; + vb = 2; + vc = 1; + } else { + /* V1>V0, V1>V2, V0>V2, V1>V0>V2*/ + va = 2; + vb = 0; + vc = 1; + } + } + } else { + if (verts[1].sVy < verts[2].sVy) { + /* V0>V1, V2>V1*/ + if (verts[0].sVy < verts[2].sVy) { + /* V0>V1, V2>V1, V2>V0, V2>V0>V1*/ + va = 1; + vb = 0; + vc = 2; + } else { + /* V0>V1, V2>V1, V0>V2, V0>V2>V1*/ + va = 1; + vb = 2; + vc = 0; + } + } else { + /*V0>V1>V2*/ + va = 2; + vb = 1; + vc = 0; + } + } - dxAB = verts[0].sVx - verts[1].sVx; - dxBC = verts[1].sVx - verts[2].sVx; - dyAB = verts[0].sVy - verts[1].sVy; - dyBC = verts[1].sVy - verts[2].sVy; + dxAB = verts[0].sVx - verts[1].sVx; + dxBC = verts[1].sVx - verts[2].sVx; + dyAB = verts[0].sVy - verts[1].sVy; + dyBC = verts[1].sVy - verts[2].sVy; - area = dxAB * dyBC - dxBC * dyAB; + area = dxAB * dyBC - dxBC * dyAB; - if (area == 0.0) - return; + if (area == 0.0) + return; - if (voodoo->sSetupMode & SETUPMODE_CULLING_ENABLE) { - int cull_sign = voodoo->sSetupMode & SETUPMODE_CULLING_SIGN; - int sign = (area < 0.0); + if (voodoo->sSetupMode & SETUPMODE_CULLING_ENABLE) { + int cull_sign = voodoo->sSetupMode & SETUPMODE_CULLING_SIGN; + int sign = (area < 0.0); - if ((voodoo->sSetupMode & (SETUPMODE_CULLING_ENABLE | SETUPMODE_DISABLE_PINGPONG)) - == SETUPMODE_CULLING_ENABLE && voodoo->cull_pingpong) - cull_sign = !cull_sign; + if ((voodoo->sSetupMode & (SETUPMODE_CULLING_ENABLE | SETUPMODE_DISABLE_PINGPONG)) == SETUPMODE_CULLING_ENABLE && + voodoo->cull_pingpong) + cull_sign = !cull_sign; - if (cull_sign && sign) - return; - if (!cull_sign && !sign) - return; - } + if (cull_sign && sign) + return; + if (!cull_sign && !sign) + return; + } - dxAB = verts[va].sVx - verts[vb].sVx; - dxBC = verts[vb].sVx - verts[vc].sVx; - dyAB = verts[va].sVy - verts[vb].sVy; - dyBC = verts[vb].sVy - verts[vc].sVy; + dxAB = verts[va].sVx - verts[vb].sVx; + dxBC = verts[vb].sVx - verts[vc].sVx; + dyAB = verts[va].sVy - verts[vb].sVy; + dyBC = verts[vb].sVy - verts[vc].sVy; - area = dxAB * dyBC - dxBC * dyAB; + area = dxAB * dyBC - dxBC * dyAB; - dxAB /= area; - dxBC /= area; - dyAB /= area; - dyBC /= area; + dxAB /= area; + dxBC /= area; + dyAB /= area; + dyBC /= area; - voodoo->params.vertexAx = (int32_t)(int16_t)((int32_t)(verts[va].sVx * 16.0f) & 0xffff); - voodoo->params.vertexAy = (int32_t)(int16_t)((int32_t)(verts[va].sVy * 16.0f) & 0xffff); - voodoo->params.vertexBx = (int32_t)(int16_t)((int32_t)(verts[vb].sVx * 16.0f) & 0xffff); - voodoo->params.vertexBy = (int32_t)(int16_t)((int32_t)(verts[vb].sVy * 16.0f) & 0xffff); - voodoo->params.vertexCx = (int32_t)(int16_t)((int32_t)(verts[vc].sVx * 16.0f) & 0xffff); - voodoo->params.vertexCy = (int32_t)(int16_t)((int32_t)(verts[vc].sVy * 16.0f) & 0xffff); + voodoo->params.vertexAx = (int32_t)(int16_t)((int32_t)(verts[va].sVx * 16.0f) & 0xffff); + voodoo->params.vertexAy = (int32_t)(int16_t)((int32_t)(verts[va].sVy * 16.0f) & 0xffff); + voodoo->params.vertexBx = (int32_t)(int16_t)((int32_t)(verts[vb].sVx * 16.0f) & 0xffff); + voodoo->params.vertexBy = (int32_t)(int16_t)((int32_t)(verts[vb].sVy * 16.0f) & 0xffff); + voodoo->params.vertexCx = (int32_t)(int16_t)((int32_t)(verts[vc].sVx * 16.0f) & 0xffff); + voodoo->params.vertexCy = (int32_t)(int16_t)((int32_t)(verts[vc].sVy * 16.0f) & 0xffff); - if (voodoo->params.vertexAy > voodoo->params.vertexBy || voodoo->params.vertexBy > voodoo->params.vertexCy) { - pclog("triangle_setup wrong order %d %d %d\n", voodoo->params.vertexAy, voodoo->params.vertexBy, voodoo->params.vertexCy); - return; - } + if (voodoo->params.vertexAy > voodoo->params.vertexBy || voodoo->params.vertexBy > voodoo->params.vertexCy) { + pclog("triangle_setup wrong order %d %d %d\n", voodoo->params.vertexAy, voodoo->params.vertexBy, + voodoo->params.vertexCy); + return; + } - if (voodoo->sSetupMode & SETUPMODE_RGB) { - voodoo->params.startR = (int32_t)(verts[va].sRed * 4096.0f); - voodoo->params.dRdX = (int32_t)(((verts[va].sRed - verts[vb].sRed) * dyBC - (verts[vb].sRed - verts[vc].sRed) * dyAB) * 4096.0f); - voodoo->params.dRdY = (int32_t)(((verts[vb].sRed - verts[vc].sRed) * dxAB - (verts[va].sRed - verts[vb].sRed) * dxBC) * 4096.0f); - voodoo->params.startG = (int32_t)(verts[va].sGreen * 4096.0f); - voodoo->params.dGdX = (int32_t)(((verts[va].sGreen - verts[vb].sGreen) * dyBC - (verts[vb].sGreen - verts[vc].sGreen) * dyAB) * 4096.0f); - voodoo->params.dGdY = (int32_t)(((verts[vb].sGreen - verts[vc].sGreen) * dxAB - (verts[va].sGreen - verts[vb].sGreen) * dxBC) * 4096.0f); - voodoo->params.startB = (int32_t)(verts[va].sBlue * 4096.0f); - voodoo->params.dBdX = (int32_t)(((verts[va].sBlue - verts[vb].sBlue) * dyBC - (verts[vb].sBlue - verts[vc].sBlue) * dyAB) * 4096.0f); - voodoo->params.dBdY = (int32_t)(((verts[vb].sBlue - verts[vc].sBlue) * dxAB - (verts[va].sBlue - verts[vb].sBlue) * dxBC) * 4096.0f); - } - if (voodoo->sSetupMode & SETUPMODE_ALPHA) { - voodoo->params.startA = (int32_t)(verts[va].sAlpha * 4096.0f); - voodoo->params.dAdX = (int32_t)(((verts[va].sAlpha - verts[vb].sAlpha) * dyBC - (verts[vb].sAlpha - verts[vc].sAlpha) * dyAB) * 4096.0f); - voodoo->params.dAdY = (int32_t)(((verts[vb].sAlpha - verts[vc].sAlpha) * dxAB - (verts[va].sAlpha - verts[vb].sAlpha) * dxBC) * 4096.0f); - } - if (voodoo->sSetupMode & SETUPMODE_Z) { - voodoo->params.startZ = (int32_t)(verts[va].sVz * 4096.0f); - voodoo->params.dZdX = (int32_t)(((verts[va].sVz - verts[vb].sVz) * dyBC - (verts[vb].sVz - verts[vc].sVz) * dyAB) * 4096.0f); - voodoo->params.dZdY = (int32_t)(((verts[vb].sVz - verts[vc].sVz) * dxAB - (verts[va].sVz - verts[vb].sVz) * dxBC) * 4096.0f); - } - if (voodoo->sSetupMode & SETUPMODE_Wb) { - voodoo->params.startW = (int64_t)(verts[va].sWb * 4294967296.0f); - voodoo->params.dWdX = (int64_t)(((verts[va].sWb - verts[vb].sWb) * dyBC - (verts[vb].sWb - verts[vc].sWb) * dyAB) * 4294967296.0f); - voodoo->params.dWdY = (int64_t)(((verts[vb].sWb - verts[vc].sWb) * dxAB - (verts[va].sWb - verts[vb].sWb) * dxBC) * 4294967296.0f); - voodoo->params.tmu[0].startW = voodoo->params.tmu[1].startW = voodoo->params.startW; - voodoo->params.tmu[0].dWdX = voodoo->params.tmu[1].dWdX = voodoo->params.dWdX; - voodoo->params.tmu[0].dWdY = voodoo->params.tmu[1].dWdY = voodoo->params.dWdY; - } - if (voodoo->sSetupMode & SETUPMODE_W0) { - voodoo->params.tmu[0].startW = (int64_t)(verts[va].sW0 * 4294967296.0f); - voodoo->params.tmu[0].dWdX = (int64_t)(((verts[va].sW0 - verts[vb].sW0) * dyBC - (verts[vb].sW0 - verts[vc].sW0) * dyAB) * 4294967296.0f); - voodoo->params.tmu[0].dWdY = (int64_t)(((verts[vb].sW0 - verts[vc].sW0) * dxAB - (verts[va].sW0 - verts[vb].sW0) * dxBC) * 4294967296.0f); - voodoo->params.tmu[1].startW = voodoo->params.tmu[0].startW; - voodoo->params.tmu[1].dWdX = voodoo->params.tmu[0].dWdX; - voodoo->params.tmu[1].dWdY = voodoo->params.tmu[0].dWdY; - } - if (voodoo->sSetupMode & SETUPMODE_S0_T0) { - voodoo->params.tmu[0].startS = (int64_t)(verts[va].sS0 * 4294967296.0f); - voodoo->params.tmu[0].dSdX = (int64_t)(((verts[va].sS0 - verts[vb].sS0) * dyBC - (verts[vb].sS0 - verts[vc].sS0) * dyAB) * 4294967296.0f); - voodoo->params.tmu[0].dSdY = (int64_t)(((verts[vb].sS0 - verts[vc].sS0) * dxAB - (verts[va].sS0 - verts[vb].sS0) * dxBC) * 4294967296.0f); - voodoo->params.tmu[0].startT = (int64_t)(verts[va].sT0 * 4294967296.0f); - voodoo->params.tmu[0].dTdX = (int64_t)(((verts[va].sT0 - verts[vb].sT0) * dyBC - (verts[vb].sT0 - verts[vc].sT0) * dyAB) * 4294967296.0f); - voodoo->params.tmu[0].dTdY = (int64_t)(((verts[vb].sT0 - verts[vc].sT0) * dxAB - (verts[va].sT0 - verts[vb].sT0) * dxBC) * 4294967296.0f); - voodoo->params.tmu[1].startS = voodoo->params.tmu[0].startS; - voodoo->params.tmu[1].dSdX = voodoo->params.tmu[0].dSdX; - voodoo->params.tmu[1].dSdY = voodoo->params.tmu[0].dSdY; - voodoo->params.tmu[1].startT = voodoo->params.tmu[0].startT; - voodoo->params.tmu[1].dTdX = voodoo->params.tmu[0].dTdX; - voodoo->params.tmu[1].dTdY = voodoo->params.tmu[0].dTdY; - } - if (voodoo->sSetupMode & SETUPMODE_W1) { - voodoo->params.tmu[1].startW = (int64_t)(verts[va].sW1 * 4294967296.0f); - voodoo->params.tmu[1].dWdX = (int64_t)(((verts[va].sW1 - verts[vb].sW1) * dyBC - (verts[vb].sW1 - verts[vc].sW1) * dyAB) * 4294967296.0f); - voodoo->params.tmu[1].dWdY = (int64_t)(((verts[vb].sW1 - verts[vc].sW1) * dxAB - (verts[va].sW1 - verts[vb].sW1) * dxBC) * 4294967296.0f); - } - if (voodoo->sSetupMode & SETUPMODE_S1_T1) { - voodoo->params.tmu[1].startS = (int64_t)(verts[va].sS1 * 4294967296.0f); - voodoo->params.tmu[1].dSdX = (int64_t)(((verts[va].sS1 - verts[vb].sS1) * dyBC - (verts[vb].sS1 - verts[vc].sS1) * dyAB) * 4294967296.0f); - voodoo->params.tmu[1].dSdY = (int64_t)(((verts[vb].sS1 - verts[vc].sS1) * dxAB - (verts[va].sS1 - verts[vb].sS1) * dxBC) * 4294967296.0f); - voodoo->params.tmu[1].startT = (int64_t)(verts[va].sT1 * 4294967296.0f); - voodoo->params.tmu[1].dTdX = (int64_t)(((verts[va].sT1 - verts[vb].sT1) * dyBC - (verts[vb].sT1 - verts[vc].sT1) * dyAB) * 4294967296.0f); - voodoo->params.tmu[1].dTdY = (int64_t)(((verts[vb].sT1 - verts[vc].sT1) * dxAB - (verts[va].sT1 - verts[vb].sT1) * dxBC) * 4294967296.0f); - } + if (voodoo->sSetupMode & SETUPMODE_RGB) { + voodoo->params.startR = (int32_t)(verts[va].sRed * 4096.0f); + voodoo->params.dRdX = (int32_t)( + ((verts[va].sRed - verts[vb].sRed) * dyBC - (verts[vb].sRed - verts[vc].sRed) * dyAB) * 4096.0f); + voodoo->params.dRdY = (int32_t)( + ((verts[vb].sRed - verts[vc].sRed) * dxAB - (verts[va].sRed - verts[vb].sRed) * dxBC) * 4096.0f); + voodoo->params.startG = (int32_t)(verts[va].sGreen * 4096.0f); + voodoo->params.dGdX = (int32_t)( + ((verts[va].sGreen - verts[vb].sGreen) * dyBC - (verts[vb].sGreen - verts[vc].sGreen) * dyAB) * 4096.0f); + voodoo->params.dGdY = (int32_t)( + ((verts[vb].sGreen - verts[vc].sGreen) * dxAB - (verts[va].sGreen - verts[vb].sGreen) * dxBC) * 4096.0f); + voodoo->params.startB = (int32_t)(verts[va].sBlue * 4096.0f); + voodoo->params.dBdX = (int32_t)( + ((verts[va].sBlue - verts[vb].sBlue) * dyBC - (verts[vb].sBlue - verts[vc].sBlue) * dyAB) * 4096.0f); + voodoo->params.dBdY = (int32_t)( + ((verts[vb].sBlue - verts[vc].sBlue) * dxAB - (verts[va].sBlue - verts[vb].sBlue) * dxBC) * 4096.0f); + } + if (voodoo->sSetupMode & SETUPMODE_ALPHA) { + voodoo->params.startA = (int32_t)(verts[va].sAlpha * 4096.0f); + voodoo->params.dAdX = (int32_t)( + ((verts[va].sAlpha - verts[vb].sAlpha) * dyBC - (verts[vb].sAlpha - verts[vc].sAlpha) * dyAB) * 4096.0f); + voodoo->params.dAdY = (int32_t)( + ((verts[vb].sAlpha - verts[vc].sAlpha) * dxAB - (verts[va].sAlpha - verts[vb].sAlpha) * dxBC) * 4096.0f); + } + if (voodoo->sSetupMode & SETUPMODE_Z) { + voodoo->params.startZ = (int32_t)(verts[va].sVz * 4096.0f); + voodoo->params.dZdX = + (int32_t)(((verts[va].sVz - verts[vb].sVz) * dyBC - (verts[vb].sVz - verts[vc].sVz) * dyAB) * 4096.0f); + voodoo->params.dZdY = + (int32_t)(((verts[vb].sVz - verts[vc].sVz) * dxAB - (verts[va].sVz - verts[vb].sVz) * dxBC) * 4096.0f); + } + if (voodoo->sSetupMode & SETUPMODE_Wb) { + voodoo->params.startW = (int64_t)(verts[va].sWb * 4294967296.0f); + voodoo->params.dWdX = (int64_t)( + ((verts[va].sWb - verts[vb].sWb) * dyBC - (verts[vb].sWb - verts[vc].sWb) * dyAB) * 4294967296.0f); + voodoo->params.dWdY = (int64_t)( + ((verts[vb].sWb - verts[vc].sWb) * dxAB - (verts[va].sWb - verts[vb].sWb) * dxBC) * 4294967296.0f); + voodoo->params.tmu[0].startW = voodoo->params.tmu[1].startW = voodoo->params.startW; + voodoo->params.tmu[0].dWdX = voodoo->params.tmu[1].dWdX = voodoo->params.dWdX; + voodoo->params.tmu[0].dWdY = voodoo->params.tmu[1].dWdY = voodoo->params.dWdY; + } + if (voodoo->sSetupMode & SETUPMODE_W0) { + voodoo->params.tmu[0].startW = (int64_t)(verts[va].sW0 * 4294967296.0f); + voodoo->params.tmu[0].dWdX = (int64_t)( + ((verts[va].sW0 - verts[vb].sW0) * dyBC - (verts[vb].sW0 - verts[vc].sW0) * dyAB) * 4294967296.0f); + voodoo->params.tmu[0].dWdY = (int64_t)( + ((verts[vb].sW0 - verts[vc].sW0) * dxAB - (verts[va].sW0 - verts[vb].sW0) * dxBC) * 4294967296.0f); + voodoo->params.tmu[1].startW = voodoo->params.tmu[0].startW; + voodoo->params.tmu[1].dWdX = voodoo->params.tmu[0].dWdX; + voodoo->params.tmu[1].dWdY = voodoo->params.tmu[0].dWdY; + } + if (voodoo->sSetupMode & SETUPMODE_S0_T0) { + voodoo->params.tmu[0].startS = (int64_t)(verts[va].sS0 * 4294967296.0f); + voodoo->params.tmu[0].dSdX = (int64_t)( + ((verts[va].sS0 - verts[vb].sS0) * dyBC - (verts[vb].sS0 - verts[vc].sS0) * dyAB) * 4294967296.0f); + voodoo->params.tmu[0].dSdY = (int64_t)( + ((verts[vb].sS0 - verts[vc].sS0) * dxAB - (verts[va].sS0 - verts[vb].sS0) * dxBC) * 4294967296.0f); + voodoo->params.tmu[0].startT = (int64_t)(verts[va].sT0 * 4294967296.0f); + voodoo->params.tmu[0].dTdX = (int64_t)( + ((verts[va].sT0 - verts[vb].sT0) * dyBC - (verts[vb].sT0 - verts[vc].sT0) * dyAB) * 4294967296.0f); + voodoo->params.tmu[0].dTdY = (int64_t)( + ((verts[vb].sT0 - verts[vc].sT0) * dxAB - (verts[va].sT0 - verts[vb].sT0) * dxBC) * 4294967296.0f); + voodoo->params.tmu[1].startS = voodoo->params.tmu[0].startS; + voodoo->params.tmu[1].dSdX = voodoo->params.tmu[0].dSdX; + voodoo->params.tmu[1].dSdY = voodoo->params.tmu[0].dSdY; + voodoo->params.tmu[1].startT = voodoo->params.tmu[0].startT; + voodoo->params.tmu[1].dTdX = voodoo->params.tmu[0].dTdX; + voodoo->params.tmu[1].dTdY = voodoo->params.tmu[0].dTdY; + } + if (voodoo->sSetupMode & SETUPMODE_W1) { + voodoo->params.tmu[1].startW = (int64_t)(verts[va].sW1 * 4294967296.0f); + voodoo->params.tmu[1].dWdX = (int64_t)( + ((verts[va].sW1 - verts[vb].sW1) * dyBC - (verts[vb].sW1 - verts[vc].sW1) * dyAB) * 4294967296.0f); + voodoo->params.tmu[1].dWdY = (int64_t)( + ((verts[vb].sW1 - verts[vc].sW1) * dxAB - (verts[va].sW1 - verts[vb].sW1) * dxBC) * 4294967296.0f); + } + if (voodoo->sSetupMode & SETUPMODE_S1_T1) { + voodoo->params.tmu[1].startS = (int64_t)(verts[va].sS1 * 4294967296.0f); + voodoo->params.tmu[1].dSdX = (int64_t)( + ((verts[va].sS1 - verts[vb].sS1) * dyBC - (verts[vb].sS1 - verts[vc].sS1) * dyAB) * 4294967296.0f); + voodoo->params.tmu[1].dSdY = (int64_t)( + ((verts[vb].sS1 - verts[vc].sS1) * dxAB - (verts[va].sS1 - verts[vb].sS1) * dxBC) * 4294967296.0f); + voodoo->params.tmu[1].startT = (int64_t)(verts[va].sT1 * 4294967296.0f); + voodoo->params.tmu[1].dTdX = (int64_t)( + ((verts[va].sT1 - verts[vb].sT1) * dyBC - (verts[vb].sT1 - verts[vc].sT1) * dyAB) * 4294967296.0f); + voodoo->params.tmu[1].dTdY = (int64_t)( + ((verts[vb].sT1 - verts[vc].sT1) * dxAB - (verts[va].sT1 - verts[vb].sT1) * dxBC) * 4294967296.0f); + } - voodoo->params.sign = (area < 0.0); + voodoo->params.sign = (area < 0.0); - if (voodoo->ncc_dirty[0]) - voodoo_update_ncc(voodoo, 0); - if (voodoo->ncc_dirty[1]) - voodoo_update_ncc(voodoo, 1); - voodoo->ncc_dirty[0] = voodoo->ncc_dirty[1] = 0; + if (voodoo->ncc_dirty[0]) + voodoo_update_ncc(voodoo, 0); + if (voodoo->ncc_dirty[1]) + voodoo_update_ncc(voodoo, 1); + voodoo->ncc_dirty[0] = voodoo->ncc_dirty[1] = 0; - voodoo_queue_triangle(voodoo, &voodoo->params); + voodoo_queue_triangle(voodoo, &voodoo->params); } diff --git a/src/video/vid_voodoo_texture.c b/src/video/vid_voodoo_texture.c index 60da5797..6bf6f590 100644 --- a/src/video/vid_voodoo_texture.c +++ b/src/video/vid_voodoo_texture.c @@ -14,484 +14,516 @@ #include "vid_voodoo_texture.h" void voodoo_recalc_tex(voodoo_t *voodoo, int tmu) { - int aspect = (voodoo->params.tLOD[tmu] >> 21) & 3; - int width = 256, height = 256; - int shift = 8; - int lod; - uint32_t base = voodoo->params.texBaseAddr[tmu]; - uint32_t offset = 0; - int tex_lod = 0; - uint32_t offsets[LOD_MAX + 3]; - int widths[LOD_MAX + 3], heights[LOD_MAX + 3], shifts[LOD_MAX + 3]; + int aspect = (voodoo->params.tLOD[tmu] >> 21) & 3; + int width = 256, height = 256; + int shift = 8; + int lod; + uint32_t base = voodoo->params.texBaseAddr[tmu]; + uint32_t offset = 0; + int tex_lod = 0; + uint32_t offsets[LOD_MAX + 3]; + int widths[LOD_MAX + 3], heights[LOD_MAX + 3], shifts[LOD_MAX + 3]; - if (voodoo->params.tLOD[tmu] & LOD_S_IS_WIDER) - height >>= aspect; - else { - width >>= aspect; - shift -= aspect; - } + if (voodoo->params.tLOD[tmu] & LOD_S_IS_WIDER) + height >>= aspect; + else { + width >>= aspect; + shift -= aspect; + } - for (lod = 0; lod <= LOD_MAX + 2; lod++) { - offsets[lod] = offset; - widths[lod] = width >> lod; - heights[lod] = height >> lod; - shifts[lod] = shift - lod; + for (lod = 0; lod <= LOD_MAX + 2; lod++) { + offsets[lod] = offset; + widths[lod] = width >> lod; + heights[lod] = height >> lod; + shifts[lod] = shift - lod; - if (!widths[lod]) - widths[lod] = 1; - if (!heights[lod]) - heights[lod] = 1; - if (shifts[lod] < 0) - shifts[lod] = 0; + if (!widths[lod]) + widths[lod] = 1; + if (!heights[lod]) + heights[lod] = 1; + if (shifts[lod] < 0) + shifts[lod] = 0; - if (!(voodoo->params.tLOD[tmu] & LOD_SPLIT) || - ((lod & 1) && (voodoo->params.tLOD[tmu] & LOD_ODD)) || - (!(lod & 1) && !(voodoo->params.tLOD[tmu] & LOD_ODD))) { - if (voodoo->params.tformat[tmu] & 8) - offset += (width >> lod) * (height >> lod) * 2; - else - offset += (width >> lod) * (height >> lod); - } - } + if (!(voodoo->params.tLOD[tmu] & LOD_SPLIT) || ((lod & 1) && (voodoo->params.tLOD[tmu] & LOD_ODD)) || + (!(lod & 1) && !(voodoo->params.tLOD[tmu] & LOD_ODD))) { + if (voodoo->params.tformat[tmu] & 8) + offset += (width >> lod) * (height >> lod) * 2; + else + offset += (width >> lod) * (height >> lod); + } + } - if ((voodoo->params.textureMode[tmu] & TEXTUREMODE_TRILINEAR) && (voodoo->params.tLOD[tmu] & LOD_ODD)) - tex_lod++; /*Skip LOD 0*/ + if ((voodoo->params.textureMode[tmu] & TEXTUREMODE_TRILINEAR) && (voodoo->params.tLOD[tmu] & LOD_ODD)) + tex_lod++; /*Skip LOD 0*/ -// pclog("TMU %i: %08x\n", tmu, voodoo->params.textureMode[tmu]); - for (lod = 0; lod <= LOD_MAX + 1; lod++) { - if (voodoo->params.tLOD[tmu] & LOD_TMULTIBASEADDR) { - switch (tex_lod) { - case 0:base = voodoo->params.texBaseAddr[tmu]; - break; - case 1:base = voodoo->params.texBaseAddr1[tmu]; - break; - case 2:base = voodoo->params.texBaseAddr2[tmu]; - break; - default:base = voodoo->params.texBaseAddr38[tmu]; - break; - } - } + // pclog("TMU %i: %08x\n", tmu, voodoo->params.textureMode[tmu]); + for (lod = 0; lod <= LOD_MAX + 1; lod++) { + if (voodoo->params.tLOD[tmu] & LOD_TMULTIBASEADDR) { + switch (tex_lod) { + case 0: + base = voodoo->params.texBaseAddr[tmu]; + break; + case 1: + base = voodoo->params.texBaseAddr1[tmu]; + break; + case 2: + base = voodoo->params.texBaseAddr2[tmu]; + break; + default: + base = voodoo->params.texBaseAddr38[tmu]; + break; + } + } - voodoo->params.tex_base[tmu][lod] = base + offsets[tex_lod]; - if (voodoo->params.tformat[tmu] & 8) - voodoo->params.tex_end[tmu][lod] = base + offsets[tex_lod] + (widths[tex_lod] * heights[tex_lod] * 2); - else - voodoo->params.tex_end[tmu][lod] = base + offsets[tex_lod] + (widths[tex_lod] * heights[tex_lod]); - voodoo->params.tex_w_mask[tmu][lod] = widths[tex_lod] - 1; - voodoo->params.tex_w_nmask[tmu][lod] = ~(widths[tex_lod] - 1); - voodoo->params.tex_h_mask[tmu][lod] = heights[tex_lod] - 1; - voodoo->params.tex_shift[tmu][lod] = shifts[tex_lod]; - voodoo->params.tex_lod[tmu][lod] = tex_lod; + voodoo->params.tex_base[tmu][lod] = base + offsets[tex_lod]; + if (voodoo->params.tformat[tmu] & 8) + voodoo->params.tex_end[tmu][lod] = base + offsets[tex_lod] + (widths[tex_lod] * heights[tex_lod] * 2); + else + voodoo->params.tex_end[tmu][lod] = base + offsets[tex_lod] + (widths[tex_lod] * heights[tex_lod]); + voodoo->params.tex_w_mask[tmu][lod] = widths[tex_lod] - 1; + voodoo->params.tex_w_nmask[tmu][lod] = ~(widths[tex_lod] - 1); + voodoo->params.tex_h_mask[tmu][lod] = heights[tex_lod] - 1; + voodoo->params.tex_shift[tmu][lod] = shifts[tex_lod]; + voodoo->params.tex_lod[tmu][lod] = tex_lod; - if (!(voodoo->params.textureMode[tmu] & TEXTUREMODE_TRILINEAR) || - ((lod & 1) && (voodoo->params.tLOD[tmu] & LOD_ODD)) || - (!(lod & 1) && !(voodoo->params.tLOD[tmu] & LOD_ODD))) { - if (!(voodoo->params.tLOD[tmu] & LOD_ODD) || lod != 0) { - if (voodoo->params.textureMode[tmu] & TEXTUREMODE_TRILINEAR) - tex_lod += 2; - else - tex_lod++; - } - } - } + if (!(voodoo->params.textureMode[tmu] & TEXTUREMODE_TRILINEAR) || + ((lod & 1) && (voodoo->params.tLOD[tmu] & LOD_ODD)) || + (!(lod & 1) && !(voodoo->params.tLOD[tmu] & LOD_ODD))) { + if (!(voodoo->params.tLOD[tmu] & LOD_ODD) || lod != 0) { + if (voodoo->params.textureMode[tmu] & TEXTUREMODE_TRILINEAR) + tex_lod += 2; + else + tex_lod++; + } + } + } - voodoo->params.tex_width[tmu] = width; + voodoo->params.tex_width[tmu] = width; } -#define makergba(r, g, b, a) ((b) | ((g) << 8) | ((r) << 16) | ((a) << 24)) +#define makergba(r, g, b, a) ((b) | ((g) << 8) | ((r) << 16) | ((a) << 24)) void voodoo_use_texture(voodoo_t *voodoo, voodoo_params_t *params, int tmu) { - int c, d; - int lod; - int lod_min, lod_max; - uint32_t addr = 0, addr_end; - uint32_t palette_checksum; + int c, d; + int lod; + int lod_min, lod_max; + uint32_t addr = 0, addr_end; + uint32_t palette_checksum; - lod_min = (params->tLOD[tmu] >> 2) & 15; - lod_max = (params->tLOD[tmu] >> 8) & 15; + lod_min = (params->tLOD[tmu] >> 2) & 15; + lod_max = (params->tLOD[tmu] >> 8) & 15; - if (params->tformat[tmu] == TEX_PAL8 || params->tformat[tmu] == TEX_APAL8 || params->tformat[tmu] == TEX_APAL88) { - if (voodoo->palette_dirty[tmu]) { - palette_checksum = 0; + if (params->tformat[tmu] == TEX_PAL8 || params->tformat[tmu] == TEX_APAL8 || params->tformat[tmu] == TEX_APAL88) { + if (voodoo->palette_dirty[tmu]) { + palette_checksum = 0; - for (c = 0; c < 256; c++) - palette_checksum ^= voodoo->palette[tmu][c].u; + for (c = 0; c < 256; c++) + palette_checksum ^= voodoo->palette[tmu][c].u; - voodoo->palette_checksum[tmu] = palette_checksum; - voodoo->palette_dirty[tmu] = 0; - } else - palette_checksum = voodoo->palette_checksum[tmu]; - } else - palette_checksum = 0; + voodoo->palette_checksum[tmu] = palette_checksum; + voodoo->palette_dirty[tmu] = 0; + } else + palette_checksum = voodoo->palette_checksum[tmu]; + } else + palette_checksum = 0; - if ((voodoo->params.tLOD[tmu] & LOD_SPLIT) && (voodoo->params.tLOD[tmu] & LOD_ODD) && (voodoo->params.tLOD[tmu] & LOD_TMULTIBASEADDR)) - addr = params->texBaseAddr1[tmu]; - else - addr = params->texBaseAddr[tmu]; + if ((voodoo->params.tLOD[tmu] & LOD_SPLIT) && (voodoo->params.tLOD[tmu] & LOD_ODD) && + (voodoo->params.tLOD[tmu] & LOD_TMULTIBASEADDR)) + addr = params->texBaseAddr1[tmu]; + else + addr = params->texBaseAddr[tmu]; - /*Try to find texture in cache*/ - for (c = 0; c < TEX_CACHE_MAX; c++) { - if (voodoo->texture_cache[tmu][c].base == addr && - voodoo->texture_cache[tmu][c].tLOD == (params->tLOD[tmu] & 0xf00fff) && - voodoo->texture_cache[tmu][c].palette_checksum == palette_checksum) { - params->tex_entry[tmu] = c; - voodoo->texture_cache[tmu][c].refcount++; - return; - } - } + /*Try to find texture in cache*/ + for (c = 0; c < TEX_CACHE_MAX; c++) { + if (voodoo->texture_cache[tmu][c].base == addr && + voodoo->texture_cache[tmu][c].tLOD == (params->tLOD[tmu] & 0xf00fff) && + voodoo->texture_cache[tmu][c].palette_checksum == palette_checksum) { + params->tex_entry[tmu] = c; + voodoo->texture_cache[tmu][c].refcount++; + return; + } + } - /*Texture not found, search for unused texture*/ - do { - for (c = 0; c < TEX_CACHE_MAX; c++) { - voodoo->texture_last_removed++; - voodoo->texture_last_removed &= (TEX_CACHE_MAX - 1); - if (voodoo->texture_cache[tmu][voodoo->texture_last_removed].refcount == voodoo->texture_cache[tmu][voodoo->texture_last_removed].refcount_r[0] && - (voodoo->render_threads == 1 - || voodoo->texture_cache[tmu][voodoo->texture_last_removed].refcount == voodoo->texture_cache[tmu][voodoo->texture_last_removed].refcount_r[1])) - break; - } - if (c == TEX_CACHE_MAX) - voodoo_wait_for_render_thread_idle(voodoo); - } while (c == TEX_CACHE_MAX); - if (c == TEX_CACHE_MAX) - fatal("Texture cache full!\n"); + /*Texture not found, search for unused texture*/ + do { + for (c = 0; c < TEX_CACHE_MAX; c++) { + voodoo->texture_last_removed++; + voodoo->texture_last_removed &= (TEX_CACHE_MAX - 1); + if (voodoo->texture_cache[tmu][voodoo->texture_last_removed].refcount == + voodoo->texture_cache[tmu][voodoo->texture_last_removed].refcount_r[0] && + (voodoo->render_threads == 1 || + voodoo->texture_cache[tmu][voodoo->texture_last_removed].refcount == + voodoo->texture_cache[tmu][voodoo->texture_last_removed].refcount_r[1])) + break; + } + if (c == TEX_CACHE_MAX) + voodoo_wait_for_render_thread_idle(voodoo); + } while (c == TEX_CACHE_MAX); + if (c == TEX_CACHE_MAX) + fatal("Texture cache full!\n"); - c = voodoo->texture_last_removed; + c = voodoo->texture_last_removed; - if ((voodoo->params.tLOD[tmu] & LOD_SPLIT) && (voodoo->params.tLOD[tmu] & LOD_ODD) && (voodoo->params.tLOD[tmu] & LOD_TMULTIBASEADDR)) - voodoo->texture_cache[tmu][c].base = params->texBaseAddr1[tmu]; - else - voodoo->texture_cache[tmu][c].base = params->texBaseAddr[tmu]; - voodoo->texture_cache[tmu][c].tLOD = params->tLOD[tmu] & 0xf00fff; + if ((voodoo->params.tLOD[tmu] & LOD_SPLIT) && (voodoo->params.tLOD[tmu] & LOD_ODD) && + (voodoo->params.tLOD[tmu] & LOD_TMULTIBASEADDR)) + voodoo->texture_cache[tmu][c].base = params->texBaseAddr1[tmu]; + else + voodoo->texture_cache[tmu][c].base = params->texBaseAddr[tmu]; + voodoo->texture_cache[tmu][c].tLOD = params->tLOD[tmu] & 0xf00fff; - lod_min = (params->tLOD[tmu] >> 2) & 15; - lod_max = (params->tLOD[tmu] >> 8) & 15; -// pclog(" add new texture to %i tformat=%i %08x LOD=%i-%i tmu=%i\n", c, voodoo->params.tformat[tmu], params->texBaseAddr[tmu], lod_min, lod_max, tmu); - lod_min = MIN(lod_min, 8); - lod_max = MIN(lod_max, 8); - for (lod = lod_min; lod <= lod_max; lod++) { - uint32_t *base = &voodoo->texture_cache[tmu][c].data[texture_offset[lod]]; - uint32_t tex_addr = params->tex_base[tmu][lod] & voodoo->texture_mask; - int x, y; - int shift = 8 - params->tex_lod[tmu][lod]; - rgba_u *pal; + lod_min = (params->tLOD[tmu] >> 2) & 15; + lod_max = (params->tLOD[tmu] >> 8) & 15; + // pclog(" add new texture to %i tformat=%i %08x LOD=%i-%i tmu=%i\n", c, voodoo->params.tformat[tmu], + // params->texBaseAddr[tmu], lod_min, lod_max, tmu); + lod_min = MIN(lod_min, 8); + lod_max = MIN(lod_max, 8); + for (lod = lod_min; lod <= lod_max; lod++) { + uint32_t *base = &voodoo->texture_cache[tmu][c].data[texture_offset[lod]]; + uint32_t tex_addr = params->tex_base[tmu][lod] & voodoo->texture_mask; + int x, y; + int shift = 8 - params->tex_lod[tmu][lod]; + rgba_u *pal; - //pclog(" LOD %i : %08x - %08x %i %i,%i\n", lod, params->tex_base[tmu][lod] & voodoo->texture_mask, addr, voodoo->params.tformat[tmu], voodoo->params.tex_w_mask[tmu][lod],voodoo->params.tex_h_mask[tmu][lod]); + // pclog(" LOD %i : %08x - %08x %i %i,%i\n", lod, params->tex_base[tmu][lod] & voodoo->texture_mask, addr, + // voodoo->params.tformat[tmu], voodoo->params.tex_w_mask[tmu][lod],voodoo->params.tex_h_mask[tmu][lod]); + switch (params->tformat[tmu]) { + case TEX_RGB332: + for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod] + 1; y++) { + for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod] + 1; x++) { + uint8_t dat = voodoo->tex_mem[tmu][(tex_addr + x) & voodoo->texture_mask]; - switch (params->tformat[tmu]) { - case TEX_RGB332: - for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod] + 1; y++) { - for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod] + 1; x++) { - uint8_t dat = voodoo->tex_mem[tmu][(tex_addr + x) & voodoo->texture_mask]; + base[x] = makergba(rgb332[dat].r, rgb332[dat].g, rgb332[dat].b, 0xff); + } + tex_addr += (1 << voodoo->params.tex_shift[tmu][lod]); + base += (1 << shift); + } + break; - base[x] = makergba(rgb332[dat].r, rgb332[dat].g, rgb332[dat].b, 0xff); - } - tex_addr += (1 << voodoo->params.tex_shift[tmu][lod]); - base += (1 << shift); - } - break; + case TEX_Y4I2Q2: + pal = voodoo->ncc_lookup[tmu][(voodoo->params.textureMode[tmu] & TEXTUREMODE_NCC_SEL) ? 1 : 0]; + for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod] + 1; y++) { + for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod] + 1; x++) { + uint8_t dat = voodoo->tex_mem[tmu][(tex_addr + x) & voodoo->texture_mask]; - case TEX_Y4I2Q2:pal = voodoo->ncc_lookup[tmu][(voodoo->params.textureMode[tmu] & TEXTUREMODE_NCC_SEL) ? 1 : 0]; - for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod] + 1; y++) { - for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod] + 1; x++) { - uint8_t dat = voodoo->tex_mem[tmu][(tex_addr + x) & voodoo->texture_mask]; + base[x] = makergba(pal[dat].rgba.r, pal[dat].rgba.g, pal[dat].rgba.b, 0xff); + } + tex_addr += (1 << voodoo->params.tex_shift[tmu][lod]); + base += (1 << shift); + } + break; - base[x] = makergba(pal[dat].rgba.r, pal[dat].rgba.g, pal[dat].rgba.b, 0xff); - } - tex_addr += (1 << voodoo->params.tex_shift[tmu][lod]); - base += (1 << shift); - } - break; + case TEX_A8: + for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod] + 1; y++) { + for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod] + 1; x++) { + uint8_t dat = voodoo->tex_mem[tmu][(tex_addr + x) & voodoo->texture_mask]; - case TEX_A8: - for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod] + 1; y++) { - for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod] + 1; x++) { - uint8_t dat = voodoo->tex_mem[tmu][(tex_addr + x) & voodoo->texture_mask]; + base[x] = makergba(dat, dat, dat, dat); + } + tex_addr += (1 << voodoo->params.tex_shift[tmu][lod]); + base += (1 << shift); + } + break; - base[x] = makergba(dat, dat, dat, dat); - } - tex_addr += (1 << voodoo->params.tex_shift[tmu][lod]); - base += (1 << shift); - } - break; + case TEX_I8: + for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod] + 1; y++) { + for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod] + 1; x++) { + uint8_t dat = voodoo->tex_mem[tmu][(tex_addr + x) & voodoo->texture_mask]; - case TEX_I8: - for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod] + 1; y++) { - for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod] + 1; x++) { - uint8_t dat = voodoo->tex_mem[tmu][(tex_addr + x) & voodoo->texture_mask]; + base[x] = makergba(dat, dat, dat, 0xff); + } + tex_addr += (1 << voodoo->params.tex_shift[tmu][lod]); + base += (1 << shift); + } + break; - base[x] = makergba(dat, dat, dat, 0xff); - } - tex_addr += (1 << voodoo->params.tex_shift[tmu][lod]); - base += (1 << shift); - } - break; + case TEX_AI8: + for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod] + 1; y++) { + for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod] + 1; x++) { + uint8_t dat = voodoo->tex_mem[tmu][(tex_addr + x) & voodoo->texture_mask]; - case TEX_AI8: - for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod] + 1; y++) { - for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod] + 1; x++) { - uint8_t dat = voodoo->tex_mem[tmu][(tex_addr + x) & voodoo->texture_mask]; + base[x] = + makergba((dat & 0x0f) | ((dat << 4) & 0xf0), (dat & 0x0f) | ((dat << 4) & 0xf0), + (dat & 0x0f) | ((dat << 4) & 0xf0), (dat & 0xf0) | ((dat >> 4) & 0x0f)); + } + tex_addr += (1 << voodoo->params.tex_shift[tmu][lod]); + base += (1 << shift); + } + break; - base[x] = makergba( - (dat & 0x0f) | ((dat << 4) & 0xf0), (dat & 0x0f) | ((dat << 4) & 0xf0), (dat & 0x0f) | ((dat << 4) & 0xf0), (dat & 0xf0) | ((dat >> 4) & 0x0f)); - } - tex_addr += (1 << voodoo->params.tex_shift[tmu][lod]); - base += (1 << shift); - } - break; + case TEX_PAL8: + pal = voodoo->palette[tmu]; + for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod] + 1; y++) { + for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod] + 1; x++) { + uint8_t dat = voodoo->tex_mem[tmu][(tex_addr + x) & voodoo->texture_mask]; - case TEX_PAL8:pal = voodoo->palette[tmu]; - for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod] + 1; y++) { - for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod] + 1; x++) { - uint8_t dat = voodoo->tex_mem[tmu][(tex_addr + x) & voodoo->texture_mask]; + base[x] = makergba(pal[dat].rgba.r, pal[dat].rgba.g, pal[dat].rgba.b, 0xff); + } + tex_addr += (1 << voodoo->params.tex_shift[tmu][lod]); + base += (1 << shift); + } + break; - base[x] = makergba(pal[dat].rgba.r, pal[dat].rgba.g, pal[dat].rgba.b, 0xff); - } - tex_addr += (1 << voodoo->params.tex_shift[tmu][lod]); - base += (1 << shift); - } - break; + case TEX_APAL8: + pal = voodoo->palette[tmu]; + for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod] + 1; y++) { + for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod] + 1; x++) { + uint8_t dat = voodoo->tex_mem[tmu][(tex_addr + x) & voodoo->texture_mask]; - case TEX_APAL8:pal = voodoo->palette[tmu]; - for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod] + 1; y++) { - for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod] + 1; x++) { - uint8_t dat = voodoo->tex_mem[tmu][(tex_addr + x) & voodoo->texture_mask]; + int r = ((pal[dat].rgba.r & 3) << 6) | ((pal[dat].rgba.g & 0xf0) >> 2) | + (pal[dat].rgba.r & 3); + int g = ((pal[dat].rgba.g & 0xf) << 4) | ((pal[dat].rgba.b & 0xc0) >> 4) | + ((pal[dat].rgba.g & 0xf) >> 2); + int b = ((pal[dat].rgba.b & 0x3f) << 2) | ((pal[dat].rgba.b & 0x30) >> 4); + int a = (pal[dat].rgba.r & 0xfc) | ((pal[dat].rgba.r & 0xc0) >> 6); - int r = ((pal[dat].rgba.r & 3) << 6) | ((pal[dat].rgba.g & 0xf0) >> 2) | (pal[dat].rgba.r & 3); - int g = ((pal[dat].rgba.g & 0xf) << 4) | ((pal[dat].rgba.b & 0xc0) >> 4) | ((pal[dat].rgba.g & 0xf) >> 2); - int b = ((pal[dat].rgba.b & 0x3f) << 2) | ((pal[dat].rgba.b & 0x30) >> 4); - int a = (pal[dat].rgba.r & 0xfc) | ((pal[dat].rgba.r & 0xc0) >> 6); + base[x] = makergba(r, g, b, a); + } + tex_addr += (1 << voodoo->params.tex_shift[tmu][lod]); + base += (1 << shift); + } + break; - base[x] = makergba(r, g, b, a); - } - tex_addr += (1 << voodoo->params.tex_shift[tmu][lod]); - base += (1 << shift); - } - break; + case TEX_ARGB8332: + for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod] + 1; y++) { + for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod] + 1; x++) { + uint16_t dat = + *(uint16_t *)&voodoo->tex_mem[tmu][(tex_addr + x * 2) & voodoo->texture_mask]; - case TEX_ARGB8332: - for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod] + 1; y++) { - for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod] + 1; x++) { - uint16_t dat = *(uint16_t *)&voodoo->tex_mem[tmu][(tex_addr + x * 2) & voodoo->texture_mask]; + base[x] = makergba(rgb332[dat & 0xff].r, rgb332[dat & 0xff].g, rgb332[dat & 0xff].b, + dat >> 8); + } + tex_addr += (1 << (voodoo->params.tex_shift[tmu][lod] + 1)); + base += (1 << shift); + } + break; - base[x] = makergba(rgb332[dat & 0xff].r, rgb332[dat & 0xff].g, rgb332[dat & 0xff].b, dat >> 8); - } - tex_addr += (1 << (voodoo->params.tex_shift[tmu][lod] + 1)); - base += (1 << shift); - } - break; + case TEX_A8Y4I2Q2: + pal = voodoo->ncc_lookup[tmu][(voodoo->params.textureMode[tmu] & TEXTUREMODE_NCC_SEL) ? 1 : 0]; + for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod] + 1; y++) { + for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod] + 1; x++) { + uint16_t dat = + *(uint16_t *)&voodoo->tex_mem[tmu][(tex_addr + x * 2) & voodoo->texture_mask]; - case TEX_A8Y4I2Q2:pal = voodoo->ncc_lookup[tmu][(voodoo->params.textureMode[tmu] & TEXTUREMODE_NCC_SEL) ? 1 : 0]; - for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod] + 1; y++) { - for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod] + 1; x++) { - uint16_t dat = *(uint16_t *)&voodoo->tex_mem[tmu][(tex_addr + x * 2) & voodoo->texture_mask]; + base[x] = makergba(pal[dat & 0xff].rgba.r, pal[dat & 0xff].rgba.g, pal[dat & 0xff].rgba.b, + dat >> 8); + } + tex_addr += (1 << (voodoo->params.tex_shift[tmu][lod] + 1)); + base += (1 << shift); + } + break; - base[x] = makergba(pal[dat & 0xff].rgba.r, pal[dat & 0xff].rgba.g, pal[dat & 0xff].rgba.b, dat >> 8); - } - tex_addr += (1 << (voodoo->params.tex_shift[tmu][lod] + 1)); - base += (1 << shift); - } - break; + case TEX_R5G6B5: + for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod] + 1; y++) { + for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod] + 1; x++) { + uint16_t dat = + *(uint16_t *)&voodoo->tex_mem[tmu][(tex_addr + x * 2) & voodoo->texture_mask]; - case TEX_R5G6B5: - for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod] + 1; y++) { - for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod] + 1; x++) { - uint16_t dat = *(uint16_t *)&voodoo->tex_mem[tmu][(tex_addr + x * 2) & voodoo->texture_mask]; + base[x] = makergba(rgb565[dat].r, rgb565[dat].g, rgb565[dat].b, 0xff); + } + tex_addr += (1 << (voodoo->params.tex_shift[tmu][lod] + 1)); + base += (1 << shift); + } + break; - base[x] = makergba(rgb565[dat].r, rgb565[dat].g, rgb565[dat].b, 0xff); - } - tex_addr += (1 << (voodoo->params.tex_shift[tmu][lod] + 1)); - base += (1 << shift); - } - break; + case TEX_ARGB1555: + for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod] + 1; y++) { + for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod] + 1; x++) { + uint16_t dat = + *(uint16_t *)&voodoo->tex_mem[tmu][(tex_addr + x * 2) & voodoo->texture_mask]; - case TEX_ARGB1555: - for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod] + 1; y++) { - for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod] + 1; x++) { - uint16_t dat = *(uint16_t *)&voodoo->tex_mem[tmu][(tex_addr + x * 2) & voodoo->texture_mask]; + base[x] = makergba(argb1555[dat].r, argb1555[dat].g, argb1555[dat].b, argb1555[dat].a); + } + tex_addr += (1 << (voodoo->params.tex_shift[tmu][lod] + 1)); + base += (1 << shift); + } + break; - base[x] = makergba(argb1555[dat].r, argb1555[dat].g, argb1555[dat].b, argb1555[dat].a); - } - tex_addr += (1 << (voodoo->params.tex_shift[tmu][lod] + 1)); - base += (1 << shift); - } - break; + case TEX_ARGB4444: + for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod] + 1; y++) { + for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod] + 1; x++) { + uint16_t dat = + *(uint16_t *)&voodoo->tex_mem[tmu][(tex_addr + x * 2) & voodoo->texture_mask]; - case TEX_ARGB4444: - for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod] + 1; y++) { - for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod] + 1; x++) { - uint16_t dat = *(uint16_t *)&voodoo->tex_mem[tmu][(tex_addr + x * 2) & voodoo->texture_mask]; + base[x] = makergba(argb4444[dat].r, argb4444[dat].g, argb4444[dat].b, argb4444[dat].a); + } + tex_addr += (1 << (voodoo->params.tex_shift[tmu][lod] + 1)); + base += (1 << shift); + } + break; - base[x] = makergba(argb4444[dat].r, argb4444[dat].g, argb4444[dat].b, argb4444[dat].a); - } - tex_addr += (1 << (voodoo->params.tex_shift[tmu][lod] + 1)); - base += (1 << shift); - } - break; + case TEX_A8I8: + for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod] + 1; y++) { + for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod] + 1; x++) { + uint16_t dat = + *(uint16_t *)&voodoo->tex_mem[tmu][(tex_addr + x * 2) & voodoo->texture_mask]; - case TEX_A8I8: - for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod] + 1; y++) { - for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod] + 1; x++) { - uint16_t dat = *(uint16_t *)&voodoo->tex_mem[tmu][(tex_addr + x * 2) & voodoo->texture_mask]; + base[x] = makergba(dat & 0xff, dat & 0xff, dat & 0xff, dat >> 8); + } + tex_addr += (1 << (voodoo->params.tex_shift[tmu][lod] + 1)); + base += (1 << shift); + } + break; - base[x] = makergba(dat & 0xff, dat & 0xff, dat & 0xff, dat >> 8); - } - tex_addr += (1 << (voodoo->params.tex_shift[tmu][lod] + 1)); - base += (1 << shift); - } - break; + case TEX_APAL88: + pal = voodoo->palette[tmu]; + for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod] + 1; y++) { + for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod] + 1; x++) { + uint16_t dat = + *(uint16_t *)&voodoo->tex_mem[tmu][(tex_addr + x * 2) & voodoo->texture_mask]; - case TEX_APAL88:pal = voodoo->palette[tmu]; - for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod] + 1; y++) { - for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod] + 1; x++) { - uint16_t dat = *(uint16_t *)&voodoo->tex_mem[tmu][(tex_addr + x * 2) & voodoo->texture_mask]; + base[x] = makergba(pal[dat & 0xff].rgba.r, pal[dat & 0xff].rgba.g, pal[dat & 0xff].rgba.b, + dat >> 8); + } + tex_addr += (1 << (voodoo->params.tex_shift[tmu][lod] + 1)); + base += (1 << shift); + } + break; - base[x] = makergba(pal[dat & 0xff].rgba.r, pal[dat & 0xff].rgba.g, pal[dat & 0xff].rgba.b, dat >> 8); - } - tex_addr += (1 << (voodoo->params.tex_shift[tmu][lod] + 1)); - base += (1 << shift); - } - break; + default: + fatal("Unknown texture format %i\n", params->tformat[tmu]); + } + } - default:fatal("Unknown texture format %i\n", params->tformat[tmu]); - } - } + voodoo->texture_cache[tmu][c].is16 = voodoo->params.tformat[tmu] & 8; - voodoo->texture_cache[tmu][c].is16 = voodoo->params.tformat[tmu] & 8; + if (params->tformat[tmu] == TEX_PAL8 || params->tformat[tmu] == TEX_APAL8 || params->tformat[tmu] == TEX_APAL88) + voodoo->texture_cache[tmu][c].palette_checksum = palette_checksum; + else + voodoo->texture_cache[tmu][c].palette_checksum = 0; - if (params->tformat[tmu] == TEX_PAL8 || params->tformat[tmu] == TEX_APAL8 || params->tformat[tmu] == TEX_APAL88) - voodoo->texture_cache[tmu][c].palette_checksum = palette_checksum; - else - voodoo->texture_cache[tmu][c].palette_checksum = 0; + if (lod_min == 0) { + voodoo->texture_cache[tmu][c].addr_start[0] = voodoo->params.tex_base[tmu][0]; + voodoo->texture_cache[tmu][c].addr_end[0] = voodoo->params.tex_end[tmu][0]; + } else + voodoo->texture_cache[tmu][c].addr_start[0] = voodoo->texture_cache[tmu][c].addr_end[0] = 0; - if (lod_min == 0) { - voodoo->texture_cache[tmu][c].addr_start[0] = voodoo->params.tex_base[tmu][0]; - voodoo->texture_cache[tmu][c].addr_end[0] = voodoo->params.tex_end[tmu][0]; - } else - voodoo->texture_cache[tmu][c].addr_start[0] = voodoo->texture_cache[tmu][c].addr_end[0] = 0; + if (lod_min <= 1 && lod_max >= 1) { + voodoo->texture_cache[tmu][c].addr_start[1] = voodoo->params.tex_base[tmu][1]; + voodoo->texture_cache[tmu][c].addr_end[1] = voodoo->params.tex_end[tmu][1]; + } else + voodoo->texture_cache[tmu][c].addr_start[1] = voodoo->texture_cache[tmu][c].addr_end[1] = 0; - if (lod_min <= 1 && lod_max >= 1) { - voodoo->texture_cache[tmu][c].addr_start[1] = voodoo->params.tex_base[tmu][1]; - voodoo->texture_cache[tmu][c].addr_end[1] = voodoo->params.tex_end[tmu][1]; - } else - voodoo->texture_cache[tmu][c].addr_start[1] = voodoo->texture_cache[tmu][c].addr_end[1] = 0; + if (lod_min <= 2 && lod_max >= 2) { + voodoo->texture_cache[tmu][c].addr_start[2] = voodoo->params.tex_base[tmu][2]; + voodoo->texture_cache[tmu][c].addr_end[2] = voodoo->params.tex_end[tmu][2]; + } else + voodoo->texture_cache[tmu][c].addr_start[2] = voodoo->texture_cache[tmu][c].addr_end[2] = 0; - if (lod_min <= 2 && lod_max >= 2) { - voodoo->texture_cache[tmu][c].addr_start[2] = voodoo->params.tex_base[tmu][2]; - voodoo->texture_cache[tmu][c].addr_end[2] = voodoo->params.tex_end[tmu][2]; - } else - voodoo->texture_cache[tmu][c].addr_start[2] = voodoo->texture_cache[tmu][c].addr_end[2] = 0; + if (lod_max >= 3) { + voodoo->texture_cache[tmu][c].addr_start[3] = voodoo->params.tex_base[tmu][(lod_min > 3) ? lod_min : 3]; + voodoo->texture_cache[tmu][c].addr_end[3] = voodoo->params.tex_end[tmu][(lod_max < 8) ? lod_max : 8]; + } else + voodoo->texture_cache[tmu][c].addr_start[3] = voodoo->texture_cache[tmu][c].addr_end[3] = 0; - if (lod_max >= 3) { - voodoo->texture_cache[tmu][c].addr_start[3] = voodoo->params.tex_base[tmu][(lod_min > 3) ? lod_min : 3]; - voodoo->texture_cache[tmu][c].addr_end[3] = voodoo->params.tex_end[tmu][(lod_max < 8) ? lod_max : 8]; - } else - voodoo->texture_cache[tmu][c].addr_start[3] = voodoo->texture_cache[tmu][c].addr_end[3] = 0; + for (d = 0; d < 4; d++) { + addr = voodoo->texture_cache[tmu][c].addr_start[d]; + addr_end = voodoo->texture_cache[tmu][c].addr_end[d]; - for (d = 0; d < 4; d++) { - addr = voodoo->texture_cache[tmu][c].addr_start[d]; - addr_end = voodoo->texture_cache[tmu][c].addr_end[d]; + if (addr_end != 0) { + for (; addr <= addr_end; addr += (1 << TEX_DIRTY_SHIFT)) + voodoo->texture_present[tmu][(addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT] = 1; + } + } - if (addr_end != 0) { - for (; addr <= addr_end; addr += (1 << TEX_DIRTY_SHIFT)) - voodoo->texture_present[tmu][(addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT] = 1; - } - } - - params->tex_entry[tmu] = c; - voodoo->texture_cache[tmu][c].refcount++; + params->tex_entry[tmu] = c; + voodoo->texture_cache[tmu][c].refcount++; } void flush_texture_cache(voodoo_t *voodoo, uint32_t dirty_addr, int tmu) { - int wait_for_idle = 0; - int c; + int wait_for_idle = 0; + int c; - memset(voodoo->texture_present[tmu], 0, sizeof(voodoo->texture_present[0])); -// pclog("Evict %08x %i\n", dirty_addr, sizeof(voodoo->texture_present)); - for (c = 0; c < TEX_CACHE_MAX; c++) { - if (voodoo->texture_cache[tmu][c].base != -1) { - int d; + memset(voodoo->texture_present[tmu], 0, sizeof(voodoo->texture_present[0])); + // pclog("Evict %08x %i\n", dirty_addr, sizeof(voodoo->texture_present)); + for (c = 0; c < TEX_CACHE_MAX; c++) { + if (voodoo->texture_cache[tmu][c].base != -1) { + int d; - for (d = 0; d < 4; d++) { - int addr_start = voodoo->texture_cache[tmu][c].addr_start[d]; - int addr_end = voodoo->texture_cache[tmu][c].addr_end[d]; + for (d = 0; d < 4; d++) { + int addr_start = voodoo->texture_cache[tmu][c].addr_start[d]; + int addr_end = voodoo->texture_cache[tmu][c].addr_end[d]; - if (addr_end != 0) { - int addr_start_masked = addr_start & voodoo->texture_mask & ~0x3ff; - int addr_end_masked = ((addr_end & voodoo->texture_mask) + 0x3ff) & ~0x3ff; + if (addr_end != 0) { + int addr_start_masked = addr_start & voodoo->texture_mask & ~0x3ff; + int addr_end_masked = ((addr_end & voodoo->texture_mask) + 0x3ff) & ~0x3ff; - if (addr_end_masked < addr_start_masked) - addr_end_masked = voodoo->texture_mask + 1; - if (dirty_addr >= addr_start_masked && dirty_addr < addr_end_masked) { -// pclog(" Evict texture %i %08x\n", c, voodoo->texture_cache[tmu][c].base); + if (addr_end_masked < addr_start_masked) + addr_end_masked = voodoo->texture_mask + 1; + if (dirty_addr >= addr_start_masked && dirty_addr < addr_end_masked) { + // pclog(" Evict texture %i %08x\n", c, + // voodoo->texture_cache[tmu][c].base); - if (voodoo->texture_cache[tmu][c].refcount != voodoo->texture_cache[tmu][c].refcount_r[0] || - (voodoo->render_threads == 2 && voodoo->texture_cache[tmu][c].refcount != voodoo->texture_cache[tmu][c].refcount_r[1])) - wait_for_idle = 1; + if (voodoo->texture_cache[tmu][c].refcount != + voodoo->texture_cache[tmu][c].refcount_r[0] || + (voodoo->render_threads == 2 && + voodoo->texture_cache[tmu][c].refcount != + voodoo->texture_cache[tmu][c].refcount_r[1])) + wait_for_idle = 1; - voodoo->texture_cache[tmu][c].base = -1; - } else { - for (; addr_start <= addr_end; addr_start += (1 << TEX_DIRTY_SHIFT)) - voodoo->texture_present[tmu][(addr_start & voodoo->texture_mask) >> TEX_DIRTY_SHIFT] = 1; - } - } - } - } - } - if (wait_for_idle) - voodoo_wait_for_render_thread_idle(voodoo); + voodoo->texture_cache[tmu][c].base = -1; + } else { + for (; addr_start <= addr_end; addr_start += (1 << TEX_DIRTY_SHIFT)) + voodoo->texture_present[tmu][(addr_start & voodoo->texture_mask) >> + TEX_DIRTY_SHIFT] = 1; + } + } + } + } + } + if (wait_for_idle) + voodoo_wait_for_render_thread_idle(voodoo); } void voodoo_tex_writel(uint32_t addr, uint32_t val, void *p) { - int lod, s, t; - voodoo_t *voodoo = (voodoo_t *)p; - int tmu; + int lod, s, t; + voodoo_t *voodoo = (voodoo_t *)p; + int tmu; - if (addr & 0x400000) - return; /*TREX != 0*/ + if (addr & 0x400000) + return; /*TREX != 0*/ - tmu = (addr & 0x200000) ? 1 : 0; + tmu = (addr & 0x200000) ? 1 : 0; - if (tmu && !voodoo->dual_tmus) - return; + if (tmu && !voodoo->dual_tmus) + return; - if (voodoo->type < VOODOO_BANSHEE) { - if (!(voodoo->params.tformat[tmu] & 8) && voodoo->type >= VOODOO_BANSHEE) { - lod = (addr >> 16) & 0xf; - t = (addr >> 8) & 0xff; - } else { - lod = (addr >> 17) & 0xf; - t = (addr >> 9) & 0xff; - } - if (voodoo->params.tformat[tmu] & 8) - s = (addr >> 1) & 0xfe; - else { - if ((voodoo->params.textureMode[tmu] & (1 << 31)) || voodoo->type >= VOODOO_BANSHEE) - s = addr & 0xfc; - else - s = (addr >> 1) & 0xfc; - } - if (lod > LOD_MAX) - return; + if (voodoo->type < VOODOO_BANSHEE) { + if (!(voodoo->params.tformat[tmu] & 8) && voodoo->type >= VOODOO_BANSHEE) { + lod = (addr >> 16) & 0xf; + t = (addr >> 8) & 0xff; + } else { + lod = (addr >> 17) & 0xf; + t = (addr >> 9) & 0xff; + } + if (voodoo->params.tformat[tmu] & 8) + s = (addr >> 1) & 0xfe; + else { + if ((voodoo->params.textureMode[tmu] & (1 << 31)) || voodoo->type >= VOODOO_BANSHEE) + s = addr & 0xfc; + else + s = (addr >> 1) & 0xfc; + } + if (lod > LOD_MAX) + return; -// if (addr >= 0x200000) -// return; + // if (addr >= 0x200000) + // return; - if (voodoo->params.tformat[tmu] & 8) - addr = voodoo->params.tex_base[tmu][lod] + s * 2 + (t << voodoo->params.tex_shift[tmu][lod]) * 2; - else - addr = voodoo->params.tex_base[tmu][lod] + s + (t << voodoo->params.tex_shift[tmu][lod]); - } else - addr = (addr & 0x1ffffc) + voodoo->params.tex_base[tmu][0]; + if (voodoo->params.tformat[tmu] & 8) + addr = voodoo->params.tex_base[tmu][lod] + s * 2 + (t << voodoo->params.tex_shift[tmu][lod]) * 2; + else + addr = voodoo->params.tex_base[tmu][lod] + s + (t << voodoo->params.tex_shift[tmu][lod]); + } else + addr = (addr & 0x1ffffc) + voodoo->params.tex_base[tmu][0]; - if (voodoo->texture_present[tmu][(addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT]) { -// pclog("texture_present at %08x %i\n", addr, (addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT); - flush_texture_cache(voodoo, addr & voodoo->texture_mask, tmu); - } - if (voodoo->type == VOODOO_3 && voodoo->texture_present[tmu ^ 1][(addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT]) { -// pclog("texture_present at %08x %i\n", addr, (addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT); - flush_texture_cache(voodoo, addr & voodoo->texture_mask, tmu ^ 1); - } - *(uint32_t *)(&voodoo->tex_mem[tmu][addr & voodoo->texture_mask]) = val; + if (voodoo->texture_present[tmu][(addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT]) { + // pclog("texture_present at %08x %i\n", addr, (addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT); + flush_texture_cache(voodoo, addr & voodoo->texture_mask, tmu); + } + if (voodoo->type == VOODOO_3 && voodoo->texture_present[tmu ^ 1][(addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT]) { + // pclog("texture_present at %08x %i\n", addr, (addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT); + flush_texture_cache(voodoo, addr & voodoo->texture_mask, tmu ^ 1); + } + *(uint32_t *)(&voodoo->tex_mem[tmu][addr & voodoo->texture_mask]) = val; } diff --git a/src/video/vid_wy700.c b/src/video/vid_wy700.c index d3821e58..55ebe85d 100644 --- a/src/video/vid_wy700.c +++ b/src/video/vid_wy700.c @@ -13,19 +13,18 @@ void updatewindowsize(int x, int y); - /* The Wyse 700 is an unusual video card. Though it has an MC6845 CRTC, this * is not exposed directly to the host PC. Instead, the CRTC is controlled by - * an MC68705P3 microcontroller. + * an MC68705P3 microcontroller. * - * Rather than emulate the real CRTC, I'm writing this as more or less a + * Rather than emulate the real CRTC, I'm writing this as more or less a * fixed-frequency card with a 1280x800 display, and scaling its selection * of modes to that window. * - * By default, the card responds to both the CGA and MDA I/O and memory + * By default, the card responds to both the CGA and MDA I/O and memory * ranges. Either range can be disabled by means of jumpers; this allows - * the Wy700 to coexist with a CGA or MDA. - * + * the Wy700 to coexist with a CGA or MDA. + * * wy700->wy700_mode indicates which of the supported video modes is in use: * * 0x00: 40x 25 text (CGA compatible) [32x32 character cell] @@ -44,9 +43,9 @@ void updatewindowsize(int x, int y); /* What works (or appears to) : * MDA/CGA 80x25 text mode - * CGA 40x25 text mode - * CGA 640x200 graphics mode - * CGA 320x200 graphics mode + * CGA 40x25 text mode + * CGA 640x200 graphics mode + * CGA 320x200 graphics mode * Hi-res graphics modes * Font selection * Display enable / disable @@ -58,95 +57,88 @@ void updatewindowsize(int x, int y); * - Cursor detach (commands 4 and 5) */ - /* The microcontroller sets up the real CRTC with one of five fixed mode - * definitions. As written, this is a fairly simplistic emulation that - * doesn't attempt to closely follow the actual working of the CRTC; but I've + * definitions. As written, this is a fairly simplistic emulation that + * doesn't attempt to closely follow the actual working of the CRTC; but I've * included the definitions here for information. */ -static uint8_t mode_1280x800[] = - { - 0x31, /* Horizontal total */ - 0x28, /* Horizontal displayed */ - 0x29, /* Horizontal sync position */ - 0x06, /* Horizontal sync width */ - 0x1b, /* Vertical total */ - 0x00, /* Vertical total adjust */ - 0x19, /* Vertical displayed */ - 0x1a, /* Vsync position */ - 0x03, /* Interlace and skew */ - 0x0f, /* Maximum raster address */ - }; +static uint8_t mode_1280x800[] = { + 0x31, /* Horizontal total */ + 0x28, /* Horizontal displayed */ + 0x29, /* Horizontal sync position */ + 0x06, /* Horizontal sync width */ + 0x1b, /* Vertical total */ + 0x00, /* Vertical total adjust */ + 0x19, /* Vertical displayed */ + 0x1a, /* Vsync position */ + 0x03, /* Interlace and skew */ + 0x0f, /* Maximum raster address */ +}; -static uint8_t mode_1280x400[] = - { - 0x31, /* Horizontal total */ - 0x28, /* Horizontal displayed */ - 0x29, /* Horizontal sync position */ - 0x06, /* Horizontal sync width */ - 0x1b, /* Vertical total */ - 0x00, /* Vertical total adjust */ - 0x19, /* Vertical displayed */ - 0x1a, /* Vsync position */ - 0x01, /* Interlace and skew */ - 0x0f, /* Maximum raster address */ - }; +static uint8_t mode_1280x400[] = { + 0x31, /* Horizontal total */ + 0x28, /* Horizontal displayed */ + 0x29, /* Horizontal sync position */ + 0x06, /* Horizontal sync width */ + 0x1b, /* Vertical total */ + 0x00, /* Vertical total adjust */ + 0x19, /* Vertical displayed */ + 0x1a, /* Vsync position */ + 0x01, /* Interlace and skew */ + 0x0f, /* Maximum raster address */ +}; -static uint8_t mode_640x400[] = - { - 0x18, /* Horizontal total */ - 0x14, /* Horizontal displayed */ - 0x14, /* Horizontal sync position */ - 0x03, /* Horizontal sync width */ - 0x1b, /* Vertical total */ - 0x00, /* Vertical total adjust */ - 0x19, /* Vertical displayed */ - 0x1a, /* Vsync position */ - 0x01, /* Interlace and skew */ - 0x0f, /* Maximum raster address */ - }; +static uint8_t mode_640x400[] = { + 0x18, /* Horizontal total */ + 0x14, /* Horizontal displayed */ + 0x14, /* Horizontal sync position */ + 0x03, /* Horizontal sync width */ + 0x1b, /* Vertical total */ + 0x00, /* Vertical total adjust */ + 0x19, /* Vertical displayed */ + 0x1a, /* Vsync position */ + 0x01, /* Interlace and skew */ + 0x0f, /* Maximum raster address */ +}; -static uint8_t mode_640x200[] = - { - 0x18, /* Horizontal total */ - 0x14, /* Horizontal displayed */ - 0x14, /* Horizontal sync position */ - 0xff, /* Horizontal sync width */ - 0x37, /* Vertical total */ - 0x00, /* Vertical total adjust */ - 0x32, /* Vertical displayed */ - 0x34, /* Vsync position */ - 0x03, /* Interlace and skew */ - 0x07, /* Maximum raster address */ - }; +static uint8_t mode_640x200[] = { + 0x18, /* Horizontal total */ + 0x14, /* Horizontal displayed */ + 0x14, /* Horizontal sync position */ + 0xff, /* Horizontal sync width */ + 0x37, /* Vertical total */ + 0x00, /* Vertical total adjust */ + 0x32, /* Vertical displayed */ + 0x34, /* Vsync position */ + 0x03, /* Interlace and skew */ + 0x07, /* Maximum raster address */ +}; -static uint8_t mode_80x24[] = - { - 0x31, /* Horizontal total */ - 0x28, /* Horizontal displayed */ - 0x2A, /* Horizontal sync position */ - 0xff, /* Horizontal sync width */ - 0x1b, /* Vertical total */ - 0x00, /* Vertical total adjust */ - 0x19, /* Vertical displayed */ - 0x1a, /* Vsync position */ - 0x01, /* Interlace and skew */ - 0x0f, /* Maximum raster address */ - }; +static uint8_t mode_80x24[] = { + 0x31, /* Horizontal total */ + 0x28, /* Horizontal displayed */ + 0x2A, /* Horizontal sync position */ + 0xff, /* Horizontal sync width */ + 0x1b, /* Vertical total */ + 0x00, /* Vertical total adjust */ + 0x19, /* Vertical displayed */ + 0x1a, /* Vsync position */ + 0x01, /* Interlace and skew */ + 0x0f, /* Maximum raster address */ +}; -static uint8_t mode_40x24[] = - { - 0x18, /* Horizontal total */ - 0x14, /* Horizontal displayed */ - 0x15, /* Horizontal sync position */ - 0xff, /* Horizontal sync width */ - 0x1b, /* Vertical total */ - 0x00, /* Vertical total adjust */ - 0x19, /* Vertical displayed */ - 0x1a, /* Vsync position */ - 0x01, /* Interlace and skew */ - 0x0f, /* Maximum raster address */ - }; +static uint8_t mode_40x24[] = { + 0x18, /* Horizontal total */ + 0x14, /* Horizontal displayed */ + 0x15, /* Horizontal sync position */ + 0xff, /* Horizontal sync width */ + 0x1b, /* Vertical total */ + 0x00, /* Vertical total adjust */ + 0x19, /* Vertical displayed */ + 0x1a, /* Vsync position */ + 0x01, /* Interlace and skew */ + 0x0f, /* Maximum raster address */ +}; static uint32_t wy700_pal[4]; @@ -154,49 +146,49 @@ static uint32_t wy700_pal[4]; extern uint8_t fontdatw[512][32]; typedef struct wy700_t { - mem_mapping_t mapping; + mem_mapping_t mapping; - /* The microcontroller works by watching four ports: - * 0x3D8 / 0x3B8 (mode control register) - * 0x3DD (top scanline address) - * 0x3DF (Wy700 control register) - * CRTC reg 14 (cursor location high) - * - * It will do nothing until one of these registers is touched. When - * one is, it then reconfigures the internal 6845 based on what it - * sees. - */ - uint8_t last_03D8; /* Copies of values written to the listed */ - uint8_t last_03DD; /* I/O ports */ - uint8_t last_03DF; - uint8_t last_crtc_0E; + /* The microcontroller works by watching four ports: + * 0x3D8 / 0x3B8 (mode control register) + * 0x3DD (top scanline address) + * 0x3DF (Wy700 control register) + * CRTC reg 14 (cursor location high) + * + * It will do nothing until one of these registers is touched. When + * one is, it then reconfigures the internal 6845 based on what it + * sees. + */ + uint8_t last_03D8; /* Copies of values written to the listed */ + uint8_t last_03DD; /* I/O ports */ + uint8_t last_03DF; + uint8_t last_crtc_0E; - uint8_t cga_crtc[32]; /* The 'CRTC' as the host PC sees it */ - uint8_t real_crtc[32]; /* The internal CRTC as the microcontroller */ - /* sees it */ - int cga_crtcreg; /* Current CRTC register */ - uint16_t wy700_base; /* Framebuffer base address (native modes) */ - uint8_t wy700_control; /* Native control / command register */ - uint8_t wy700_mode; /* Current mode (see list at top of file) */ - uint8_t cga_ctrl; /* Emulated MDA/CGA control register */ - uint8_t cga_colour; /* Emulated CGA colour register (ignored) */ + uint8_t cga_crtc[32]; /* The 'CRTC' as the host PC sees it */ + uint8_t real_crtc[32]; /* The internal CRTC as the microcontroller */ + /* sees it */ + int cga_crtcreg; /* Current CRTC register */ + uint16_t wy700_base; /* Framebuffer base address (native modes) */ + uint8_t wy700_control; /* Native control / command register */ + uint8_t wy700_mode; /* Current mode (see list at top of file) */ + uint8_t cga_ctrl; /* Emulated MDA/CGA control register */ + uint8_t cga_colour; /* Emulated CGA colour register (ignored) */ - uint8_t mda_stat; /* MDA status (IN 0x3BA) */ - uint8_t cga_stat; /* CGA status (IN 0x3DA) */ + uint8_t mda_stat; /* MDA status (IN 0x3BA) */ + uint8_t cga_stat; /* CGA status (IN 0x3DA) */ - int font; /* Current font, 0 or 1 */ - int enabled; /* Display enabled, 0 or 1 */ - int detach; /* Detach cursor, 0 or 1 */ + int font; /* Current font, 0 or 1 */ + int enabled; /* Display enabled, 0 or 1 */ + int detach; /* Detach cursor, 0 or 1 */ - uint64_t dispontime, dispofftime; - pc_timer_t timer; + uint64_t dispontime, dispofftime; + pc_timer_t timer; - int linepos, displine; - int vc; - int dispon, blink; - int vsynctime; + int linepos, displine; + int vc; + int dispon, blink; + int vsynctime; - uint8_t *vram; + uint8_t *vram; } wy700_t; /* Mapping of attributes to colours, in CGA emulation... */ @@ -210,712 +202,695 @@ uint8_t wy700_read(uint32_t addr, void *p); void wy700_checkchanges(wy700_t *wy700); void wy700_out(uint16_t addr, uint8_t val, void *p) { - wy700_t *wy700 = (wy700_t *)p; - switch (addr) { - /* These three registers are only mapped in the 3Dx range, - * not the 3Bx range. */ - case 0x3DD: /* Base address (low) */ - wy700->wy700_base &= 0xFF00; - wy700->wy700_base |= val; - wy700_checkchanges(wy700); - break; + wy700_t *wy700 = (wy700_t *)p; + switch (addr) { + /* These three registers are only mapped in the 3Dx range, + * not the 3Bx range. */ + case 0x3DD: /* Base address (low) */ + wy700->wy700_base &= 0xFF00; + wy700->wy700_base |= val; + wy700_checkchanges(wy700); + break; - case 0x3DE: /* Base address (high) */ - wy700->wy700_base &= 0xFF; - wy700->wy700_base |= ((uint16_t)val) << 8; - wy700_checkchanges(wy700); - break; + case 0x3DE: /* Base address (high) */ + wy700->wy700_base &= 0xFF; + wy700->wy700_base |= ((uint16_t)val) << 8; + wy700_checkchanges(wy700); + break; - case 0x3DF: /* Command / control register */ - wy700->wy700_control = val; - wy700_checkchanges(wy700); - break; + case 0x3DF: /* Command / control register */ + wy700->wy700_control = val; + wy700_checkchanges(wy700); + break; - /* Emulated CRTC, register select */ - case 0x3b0: - case 0x3b2: - case 0x3b4: - case 0x3b6: - case 0x3d0: - case 0x3d2: - case 0x3d4: - case 0x3d6:wy700->cga_crtcreg = val & 31; - break; + /* Emulated CRTC, register select */ + case 0x3b0: + case 0x3b2: + case 0x3b4: + case 0x3b6: + case 0x3d0: + case 0x3d2: + case 0x3d4: + case 0x3d6: + wy700->cga_crtcreg = val & 31; + break; - /* Emulated CRTC, value */ - case 0x3b1: - case 0x3b3: - case 0x3b5: - case 0x3b7: - case 0x3d1: - case 0x3d3: - case 0x3d5: - case 0x3d7:wy700->cga_crtc[wy700->cga_crtcreg] = val; + /* Emulated CRTC, value */ + case 0x3b1: + case 0x3b3: + case 0x3b5: + case 0x3b7: + case 0x3d1: + case 0x3d3: + case 0x3d5: + case 0x3d7: + wy700->cga_crtc[wy700->cga_crtcreg] = val; - wy700_checkchanges(wy700); - wy700_recalctimings(wy700); - return; + wy700_checkchanges(wy700); + wy700_recalctimings(wy700); + return; - /* Emulated MDA / CGA control register */ - case 0x3b8: - case 0x3D8:wy700->cga_ctrl = val; - wy700_checkchanges(wy700); - return; - /* Emulated CGA colour register */ - case 0x3D9:wy700->cga_colour = val; - return; - } + /* Emulated MDA / CGA control register */ + case 0x3b8: + case 0x3D8: + wy700->cga_ctrl = val; + wy700_checkchanges(wy700); + return; + /* Emulated CGA colour register */ + case 0x3D9: + wy700->cga_colour = val; + return; + } } uint8_t wy700_in(uint16_t addr, void *p) { - wy700_t *wy700 = (wy700_t *)p; - switch (addr) { - case 0x3b0: - case 0x3b2: - case 0x3b4: - case 0x3b6: - case 0x3d0: - case 0x3d2: - case 0x3d4: - case 0x3d6:return wy700->cga_crtcreg; - case 0x3b1: - case 0x3b3: - case 0x3b5: - case 0x3b7: - case 0x3d1: - case 0x3d3: - case 0x3d5: - case 0x3d7:return wy700->cga_crtc[wy700->cga_crtcreg]; - case 0x3b8: - case 0x3d8:return wy700->cga_ctrl; - case 0x3d9:return wy700->cga_colour; - case 0x3ba:return wy700->mda_stat; - case 0x3da:return wy700->cga_stat; - } - return 0xff; + wy700_t *wy700 = (wy700_t *)p; + switch (addr) { + case 0x3b0: + case 0x3b2: + case 0x3b4: + case 0x3b6: + case 0x3d0: + case 0x3d2: + case 0x3d4: + case 0x3d6: + return wy700->cga_crtcreg; + case 0x3b1: + case 0x3b3: + case 0x3b5: + case 0x3b7: + case 0x3d1: + case 0x3d3: + case 0x3d5: + case 0x3d7: + return wy700->cga_crtc[wy700->cga_crtcreg]; + case 0x3b8: + case 0x3d8: + return wy700->cga_ctrl; + case 0x3d9: + return wy700->cga_colour; + case 0x3ba: + return wy700->mda_stat; + case 0x3da: + return wy700->cga_stat; + } + return 0xff; } /* Check if any of the four key registers has changed. If so, check for a * mode change or cursor size change */ void wy700_checkchanges(wy700_t *wy700) { - uint8_t curstart, curend; + uint8_t curstart, curend; - if (wy700->last_03D8 == wy700->cga_ctrl && - wy700->last_03DD == (wy700->wy700_base & 0xFF) && - wy700->last_03DF == wy700->wy700_control && - wy700->last_crtc_0E == wy700->cga_crtc[0x0E]) { - return; /* Nothing changed */ - } - /* Check for control register changes */ - if (wy700->last_03DF != wy700->wy700_control) { - wy700->last_03DF = wy700->wy700_control; + if (wy700->last_03D8 == wy700->cga_ctrl && wy700->last_03DD == (wy700->wy700_base & 0xFF) && + wy700->last_03DF == wy700->wy700_control && wy700->last_crtc_0E == wy700->cga_crtc[0x0E]) { + return; /* Nothing changed */ + } + /* Check for control register changes */ + if (wy700->last_03DF != wy700->wy700_control) { + wy700->last_03DF = wy700->wy700_control; - /* Values 1-7 are commands. */ - switch (wy700->wy700_control) { - case 1: /* Reset */ - wy700->font = 0; - wy700->enabled = 1; - wy700->detach = 0; - break; + /* Values 1-7 are commands. */ + switch (wy700->wy700_control) { + case 1: /* Reset */ + wy700->font = 0; + wy700->enabled = 1; + wy700->detach = 0; + break; - case 2: /* Font 1 */ - wy700->font = 0; - break; + case 2: /* Font 1 */ + wy700->font = 0; + break; - case 3: /* Font 2 */ - wy700->font = 1; - break; + case 3: /* Font 2 */ + wy700->font = 1; + break; -/* Even with the microprogram from an original card, I can't really work out - * what commands 4 and 5 (which I've called 'cursor detach' / 'cursor attach') - * do. Command 4 sets a flag in microcontroller RAM, and command 5 clears - * it. When the flag is set, the real cursor doesn't track the cursor in the - * emulated CRTC, and its blink rate increases. Possibly it's a self-test - * function of some kind. - * - * The card documentation doesn't cover these commands. - */ + /* Even with the microprogram from an original card, I can't really work out + * what commands 4 and 5 (which I've called 'cursor detach' / 'cursor attach') + * do. Command 4 sets a flag in microcontroller RAM, and command 5 clears + * it. When the flag is set, the real cursor doesn't track the cursor in the + * emulated CRTC, and its blink rate increases. Possibly it's a self-test + * function of some kind. + * + * The card documentation doesn't cover these commands. + */ - case 4: /* Detach cursor */ - wy700->detach = 1; - break; + case 4: /* Detach cursor */ + wy700->detach = 1; + break; - case 5: /* Attach cursor */ - wy700->detach = 0; - break; + case 5: /* Attach cursor */ + wy700->detach = 0; + break; - case 6: /* Disable display */ - wy700->enabled = 0; - break; + case 6: /* Disable display */ + wy700->enabled = 0; + break; - case 7: /* Enable display */ - wy700->enabled = 1; - break; - } - /* A control write with the top bit set selects graphics mode */ - if (wy700->wy700_control & 0x80) { - /* Select hi-res graphics mode; map framebuffer at A0000 */ - mem_mapping_set_addr(&wy700->mapping, 0xa0000, 0x20000); - wy700->wy700_mode = wy700->wy700_control; + case 7: /* Enable display */ + wy700->enabled = 1; + break; + } + /* A control write with the top bit set selects graphics mode */ + if (wy700->wy700_control & 0x80) { + /* Select hi-res graphics mode; map framebuffer at A0000 */ + mem_mapping_set_addr(&wy700->mapping, 0xa0000, 0x20000); + wy700->wy700_mode = wy700->wy700_control; - /* Select appropriate preset timings */ - if (wy700->wy700_mode & 0x40) { - memcpy(wy700->real_crtc, mode_1280x800, - sizeof(mode_1280x800)); - } else if (wy700->wy700_mode & 0x20) { - memcpy(wy700->real_crtc, mode_1280x400, - sizeof(mode_1280x400)); - } else { - memcpy(wy700->real_crtc, mode_640x400, - sizeof(mode_640x400)); - } - } - } - /* An attempt to program the CGA / MDA selects low-res mode */ - else if (wy700->last_03D8 != wy700->cga_ctrl) { - wy700->last_03D8 = wy700->cga_ctrl; - /* Set lo-res text or graphics mode. - * (Strictly speaking, when not in hi-res mode the card - * should be mapped at B0000-B3FFF and B8000-BBFFF, leaving - * a 16k hole between the two ranges) */ - mem_mapping_set_addr(&wy700->mapping, 0xb0000, 0x0C000); - if (wy700->cga_ctrl & 2) /* Graphics mode */ - { - wy700->wy700_mode = (wy700->cga_ctrl & 0x10) ? 6 : 4; - memcpy(wy700->real_crtc, mode_640x200, - sizeof(mode_640x200)); - } else if (wy700->cga_ctrl & 1) /* Text mode 80x24 */ - { - wy700->wy700_mode = 2; - memcpy(wy700->real_crtc, mode_80x24, sizeof(mode_80x24)); - } else /* Text mode 40x24 */ - { - wy700->wy700_mode = 0; - memcpy(wy700->real_crtc, mode_40x24, sizeof(mode_40x24)); - } - } - /* Convert the cursor sizes from the ones used by the CGA or MDA - * to native */ + /* Select appropriate preset timings */ + if (wy700->wy700_mode & 0x40) { + memcpy(wy700->real_crtc, mode_1280x800, sizeof(mode_1280x800)); + } else if (wy700->wy700_mode & 0x20) { + memcpy(wy700->real_crtc, mode_1280x400, sizeof(mode_1280x400)); + } else { + memcpy(wy700->real_crtc, mode_640x400, sizeof(mode_640x400)); + } + } + } + /* An attempt to program the CGA / MDA selects low-res mode */ + else if (wy700->last_03D8 != wy700->cga_ctrl) { + wy700->last_03D8 = wy700->cga_ctrl; + /* Set lo-res text or graphics mode. + * (Strictly speaking, when not in hi-res mode the card + * should be mapped at B0000-B3FFF and B8000-BBFFF, leaving + * a 16k hole between the two ranges) */ + mem_mapping_set_addr(&wy700->mapping, 0xb0000, 0x0C000); + if (wy700->cga_ctrl & 2) /* Graphics mode */ + { + wy700->wy700_mode = (wy700->cga_ctrl & 0x10) ? 6 : 4; + memcpy(wy700->real_crtc, mode_640x200, sizeof(mode_640x200)); + } else if (wy700->cga_ctrl & 1) /* Text mode 80x24 */ + { + wy700->wy700_mode = 2; + memcpy(wy700->real_crtc, mode_80x24, sizeof(mode_80x24)); + } else /* Text mode 40x24 */ + { + wy700->wy700_mode = 0; + memcpy(wy700->real_crtc, mode_40x24, sizeof(mode_40x24)); + } + } + /* Convert the cursor sizes from the ones used by the CGA or MDA + * to native */ - if (wy700->cga_crtc[9] == 13) /* MDA scaling */ - { - curstart = wy700->cga_crtc[10] & 0x1F; - wy700->real_crtc[10] = ((curstart + 5) >> 3) + curstart; - if (wy700->real_crtc[10] > 31) - wy700->real_crtc[10] = 31; - /* And bring 'cursor disabled' flag across */ - if ((wy700->cga_crtc[10] & 0x60) == 0x20) { - wy700->real_crtc[10] |= 0x20; - } - curend = wy700->cga_crtc[11] & 0x1F; - wy700->real_crtc[11] = ((curend + 5) >> 3) + curend; - if (wy700->real_crtc[11] > 31) - wy700->real_crtc[11] = 31; - } else /* CGA scaling */ - { - curstart = wy700->cga_crtc[10] & 0x1F; - wy700->real_crtc[10] = curstart << 1; - if (wy700->real_crtc[10] > 31) - wy700->real_crtc[10] = 31; - /* And bring 'cursor disabled' flag across */ - if ((wy700->cga_crtc[10] & 0x60) == 0x20) { - wy700->real_crtc[10] |= 0x20; - } - curend = wy700->cga_crtc[11] & 0x1F; - wy700->real_crtc[11] = curend << 1; - if (wy700->real_crtc[11] > 31) - wy700->real_crtc[11] = 31; - } + if (wy700->cga_crtc[9] == 13) /* MDA scaling */ + { + curstart = wy700->cga_crtc[10] & 0x1F; + wy700->real_crtc[10] = ((curstart + 5) >> 3) + curstart; + if (wy700->real_crtc[10] > 31) + wy700->real_crtc[10] = 31; + /* And bring 'cursor disabled' flag across */ + if ((wy700->cga_crtc[10] & 0x60) == 0x20) { + wy700->real_crtc[10] |= 0x20; + } + curend = wy700->cga_crtc[11] & 0x1F; + wy700->real_crtc[11] = ((curend + 5) >> 3) + curend; + if (wy700->real_crtc[11] > 31) + wy700->real_crtc[11] = 31; + } else /* CGA scaling */ + { + curstart = wy700->cga_crtc[10] & 0x1F; + wy700->real_crtc[10] = curstart << 1; + if (wy700->real_crtc[10] > 31) + wy700->real_crtc[10] = 31; + /* And bring 'cursor disabled' flag across */ + if ((wy700->cga_crtc[10] & 0x60) == 0x20) { + wy700->real_crtc[10] |= 0x20; + } + curend = wy700->cga_crtc[11] & 0x1F; + wy700->real_crtc[11] = curend << 1; + if (wy700->real_crtc[11] > 31) + wy700->real_crtc[11] = 31; + } } void wy700_write(uint32_t addr, uint8_t val, void *p) { - wy700_t *wy700 = (wy700_t *)p; - egawrites++; + wy700_t *wy700 = (wy700_t *)p; + egawrites++; - if (wy700->wy700_mode & 0x80) /* High-res mode. */ - { - addr &= 0xFFFF; -/* In 800-line modes, bit 1 of the control register sets the high bit of the - * write address. */ - if ((wy700->wy700_mode & 0x42) == 0x42) { - addr |= 0x10000; - } - wy700->vram[addr] = val; - } else { - wy700->vram[addr & 0x3fff] = val; - } + if (wy700->wy700_mode & 0x80) /* High-res mode. */ + { + addr &= 0xFFFF; + /* In 800-line modes, bit 1 of the control register sets the high bit of the + * write address. */ + if ((wy700->wy700_mode & 0x42) == 0x42) { + addr |= 0x10000; + } + wy700->vram[addr] = val; + } else { + wy700->vram[addr & 0x3fff] = val; + } } uint8_t wy700_read(uint32_t addr, void *p) { - wy700_t *wy700 = (wy700_t *)p; - egareads++; - if (wy700->wy700_mode & 0x80) /* High-res mode. */ - { - addr &= 0xFFFF; -/* In 800-line modes, bit 0 of the control register sets the high bit of the - * read address. */ - if ((wy700->wy700_mode & 0x41) == 0x41) { - addr |= 0x10000; - } - return wy700->vram[addr]; - } else { - return wy700->vram[addr & 0x3fff]; - } + wy700_t *wy700 = (wy700_t *)p; + egareads++; + if (wy700->wy700_mode & 0x80) /* High-res mode. */ + { + addr &= 0xFFFF; + /* In 800-line modes, bit 0 of the control register sets the high bit of the + * read address. */ + if ((wy700->wy700_mode & 0x41) == 0x41) { + addr |= 0x10000; + } + return wy700->vram[addr]; + } else { + return wy700->vram[addr & 0x3fff]; + } } void wy700_recalctimings(wy700_t *wy700) { - double disptime; - double _dispontime, _dispofftime; + double disptime; + double _dispontime, _dispofftime; - disptime = wy700->real_crtc[0] + 1; - _dispontime = wy700->real_crtc[1]; - _dispofftime = disptime - _dispontime; - _dispontime *= MDACONST; - _dispofftime *= MDACONST; - wy700->dispontime = (uint64_t)_dispontime; - wy700->dispofftime = (uint64_t)_dispofftime; + disptime = wy700->real_crtc[0] + 1; + _dispontime = wy700->real_crtc[1]; + _dispofftime = disptime - _dispontime; + _dispontime *= MDACONST; + _dispofftime *= MDACONST; + wy700->dispontime = (uint64_t)_dispontime; + wy700->dispofftime = (uint64_t)_dispofftime; } /* Draw a single line of the screen in either text mode */ void wy700_textline(wy700_t *wy700) { - int x; - int w = (wy700->wy700_mode == 0) ? 40 : 80; - int cw = (wy700->wy700_mode == 0) ? 32 : 16; - uint8_t chr, attr; - uint8_t bitmap[2]; - uint8_t *fontbase = &fontdatw[0][0]; - int blink, c; - int drawcursor, cursorline; - int mda = 0; - uint16_t addr; - uint8_t sc; - uint16_t ma = (wy700->cga_crtc[13] | (wy700->cga_crtc[12] << 8)) & 0x3fff; - uint16_t ca = (wy700->cga_crtc[15] | (wy700->cga_crtc[14] << 8)) & 0x3fff; + int x; + int w = (wy700->wy700_mode == 0) ? 40 : 80; + int cw = (wy700->wy700_mode == 0) ? 32 : 16; + uint8_t chr, attr; + uint8_t bitmap[2]; + uint8_t *fontbase = &fontdatw[0][0]; + int blink, c; + int drawcursor, cursorline; + int mda = 0; + uint16_t addr; + uint8_t sc; + uint16_t ma = (wy700->cga_crtc[13] | (wy700->cga_crtc[12] << 8)) & 0x3fff; + uint16_t ca = (wy700->cga_crtc[15] | (wy700->cga_crtc[14] << 8)) & 0x3fff; + /* The fake CRTC character height register selects whether MDA or CGA + * attributes are used */ + if (wy700->cga_crtc[9] == 0 || wy700->cga_crtc[9] == 13) { + mda = 1; + } -/* The fake CRTC character height register selects whether MDA or CGA - * attributes are used */ - if (wy700->cga_crtc[9] == 0 || wy700->cga_crtc[9] == 13) { - mda = 1; - } + if (wy700->font) { + fontbase += 256 * 32; + } + addr = ((ma & ~1) + (wy700->displine >> 5) * w) * 2; + sc = (wy700->displine >> 1) & 15; - if (wy700->font) { - fontbase += 256 * 32; - } - addr = ((ma & ~1) + (wy700->displine >> 5) * w) * 2; - sc = (wy700->displine >> 1) & 15; + ma += ((wy700->displine >> 5) * w); - ma += ((wy700->displine >> 5) * w); + if ((wy700->real_crtc[10] & 0x60) == 0x20) { + cursorline = 0; + } else { + cursorline = ((wy700->real_crtc[10] & 0x1F) <= sc) && ((wy700->real_crtc[11] & 0x1F) >= sc); + } - if ((wy700->real_crtc[10] & 0x60) == 0x20) { - cursorline = 0; - } else { - cursorline = ((wy700->real_crtc[10] & 0x1F) <= sc) && - ((wy700->real_crtc[11] & 0x1F) >= sc); - } + for (x = 0; x < w; x++) { + chr = wy700->vram[(addr + 2 * x) & 0x3FFF]; + attr = wy700->vram[(addr + 2 * x + 1) & 0x3FFF]; + drawcursor = ((ma == ca) && cursorline && wy700->enabled && (wy700->cga_ctrl & 8) && (wy700->blink & 16)); + blink = ((wy700->blink & 16) && (wy700->cga_ctrl & 0x20) && (attr & 0x80) && !drawcursor); - for (x = 0; x < w; x++) { - chr = wy700->vram[(addr + 2 * x) & 0x3FFF]; - attr = wy700->vram[(addr + 2 * x + 1) & 0x3FFF]; - drawcursor = ((ma == ca) && cursorline && wy700->enabled && - (wy700->cga_ctrl & 8) && (wy700->blink & 16)); - blink = ((wy700->blink & 16) && - (wy700->cga_ctrl & 0x20) && - (attr & 0x80) && !drawcursor); + if (wy700->cga_ctrl & 0x20) + attr &= 0x7F; + /* MDA underline */ + if (sc == 14 && mda && ((attr & 7) == 1)) { + for (c = 0; c < cw; c++) + ((uint32_t *)buffer32->line[wy700->displine])[(x * cw) + c] = mdacols[attr][blink][1]; + } else /* Draw 16 pixels of character */ + { + bitmap[0] = fontbase[chr * 32 + 2 * sc]; + bitmap[1] = fontbase[chr * 32 + 2 * sc + 1]; + for (c = 0; c < 16; c++) { + int col; + if (c < 8) + col = (mda ? mdacols : cgacols)[attr][blink][(bitmap[0] & (1 << (c ^ 7))) ? 1 : 0]; + else + col = (mda ? mdacols : cgacols)[attr][blink][(bitmap[1] & (1 << ((c & 7) ^ 7))) ? 1 : 0]; + if (!(wy700->enabled) || !(wy700->cga_ctrl & 8)) + col = mdacols[0][0][0]; + if (w == 40) { + ((uint32_t *)buffer32->line[wy700->displine])[(x * cw) + 2 * c] = col; + ((uint32_t *)buffer32->line[wy700->displine])[(x * cw) + 2 * c + 1] = col; + } else + ((uint32_t *)buffer32->line[wy700->displine])[(x * cw) + c] = col; + } - if (wy700->cga_ctrl & 0x20) - attr &= 0x7F; - /* MDA underline */ - if (sc == 14 && mda && ((attr & 7) == 1)) { - for (c = 0; c < cw; c++) - ((uint32_t *)buffer32->line[wy700->displine])[(x * cw) + c] = - mdacols[attr][blink][1]; - } else /* Draw 16 pixels of character */ - { - bitmap[0] = fontbase[chr * 32 + 2 * sc]; - bitmap[1] = fontbase[chr * 32 + 2 * sc + 1]; - for (c = 0; c < 16; c++) { - int col; - if (c < 8) - col = (mda ? mdacols : cgacols)[attr][blink][(bitmap[0] & (1 << (c ^ 7))) ? 1 : 0]; - else - col = (mda ? mdacols : cgacols)[attr][blink][(bitmap[1] & (1 << ((c & 7) ^ 7))) ? 1 : 0]; - if (!(wy700->enabled) || !(wy700->cga_ctrl & 8)) - col = mdacols[0][0][0]; - if (w == 40) { - ((uint32_t *)buffer32->line[wy700->displine])[(x * cw) + 2 * c] = col; - ((uint32_t *)buffer32->line[wy700->displine])[(x * cw) + 2 * c + 1] = col; - } else - ((uint32_t *)buffer32->line[wy700->displine])[(x * cw) + c] = col; - } - - if (drawcursor) { - for (c = 0; c < cw; c++) - ((uint32_t *)buffer32->line[wy700->displine])[(x * cw) + c] ^= (mda ? mdacols : cgacols)[attr][0][1]; - } - ++ma; - } - } + if (drawcursor) { + for (c = 0; c < cw; c++) + ((uint32_t *)buffer32->line[wy700->displine])[(x * cw) + c] ^= + (mda ? mdacols : cgacols)[attr][0][1]; + } + ++ma; + } + } } /* Draw a line in either of the CGA graphics modes (320x200 or 640x200) */ void wy700_cgaline(wy700_t *wy700) { - int x, c; - uint32_t dat; - uint32_t ink = 0; - uint16_t addr; + int x, c; + uint32_t dat; + uint32_t ink = 0; + uint16_t addr; - uint16_t ma = (wy700->cga_crtc[13] | (wy700->cga_crtc[12] << 8)) & 0x3fff; - addr = ((wy700->displine >> 2) & 1) * 0x2000 + - (wy700->displine >> 3) * 80 + - ((ma & ~1) << 1); + uint16_t ma = (wy700->cga_crtc[13] | (wy700->cga_crtc[12] << 8)) & 0x3fff; + addr = ((wy700->displine >> 2) & 1) * 0x2000 + (wy700->displine >> 3) * 80 + ((ma & ~1) << 1); - /* The fixed mode setting here programs the real CRTC with a screen - * width to 20, so draw in 20 fixed chunks of 4 bytes each */ - for (x = 0; x < 20; x++) { - dat = ((wy700->vram[addr & 0x3FFF] << 24) | - (wy700->vram[(addr + 1) & 0x3FFF] << 16) | - (wy700->vram[(addr + 2) & 0x3FFF] << 8) | - (wy700->vram[(addr + 3) & 0x3FFF])); - addr += 4; + /* The fixed mode setting here programs the real CRTC with a screen + * width to 20, so draw in 20 fixed chunks of 4 bytes each */ + for (x = 0; x < 20; x++) { + dat = ((wy700->vram[addr & 0x3FFF] << 24) | (wy700->vram[(addr + 1) & 0x3FFF] << 16) | + (wy700->vram[(addr + 2) & 0x3FFF] << 8) | (wy700->vram[(addr + 3) & 0x3FFF])); + addr += 4; - if (wy700->wy700_mode == 6) { - for (c = 0; c < 32; c++) { - ink = (dat & 0x80000000) ? wy700_pal[3] : wy700_pal[0]; - if (!(wy700->enabled) || !(wy700->cga_ctrl & 8)) - ink = wy700_pal[0]; - ((uint32_t *)buffer32->line[wy700->displine])[x * 64 + 2 * c] = - ((uint32_t *)buffer32->line[wy700->displine])[x * 64 + 2 * c + 1] = - ink; - dat = dat << 1; - } - } else { - for (c = 0; c < 16; c++) { - ink = wy700_pal[(dat >> 30) & 3]; - if (!(wy700->enabled) || !(wy700->cga_ctrl & 8)) - ink = wy700_pal[0]; - ((uint32_t *)buffer32->line[wy700->displine])[x * 64 + 4 * c] = - ((uint32_t *)buffer32->line[wy700->displine])[x * 64 + 4 * c + 1] = - ((uint32_t *)buffer32->line[wy700->displine])[x * 64 + 4 * c + 2] = - ((uint32_t *)buffer32->line[wy700->displine])[x * 64 + 4 * c + 3] = - ink; - dat = dat << 2; - } - } - } + if (wy700->wy700_mode == 6) { + for (c = 0; c < 32; c++) { + ink = (dat & 0x80000000) ? wy700_pal[3] : wy700_pal[0]; + if (!(wy700->enabled) || !(wy700->cga_ctrl & 8)) + ink = wy700_pal[0]; + ((uint32_t *)buffer32->line[wy700->displine])[x * 64 + 2 * c] = + ((uint32_t *)buffer32->line[wy700->displine])[x * 64 + 2 * c + 1] = ink; + dat = dat << 1; + } + } else { + for (c = 0; c < 16; c++) { + ink = wy700_pal[(dat >> 30) & 3]; + if (!(wy700->enabled) || !(wy700->cga_ctrl & 8)) + ink = wy700_pal[0]; + ((uint32_t *)buffer32->line[wy700->displine])[x * 64 + 4 * c] = + ((uint32_t *)buffer32->line[wy700->displine])[x * 64 + 4 * c + 1] = + ((uint32_t *)buffer32->line[wy700->displine])[x * 64 + 4 * c + 2] = + ((uint32_t *)buffer32->line[wy700->displine])[x * 64 + 4 * c + 3] = ink; + dat = dat << 2; + } + } + } } /* Draw a line in the medium-resolution graphics modes (640x400 or 320x400) */ void wy700_medresline(wy700_t *wy700) { - int x, c; - uint32_t dat; - uint32_t ink = 0; - uint32_t addr; + int x, c; + uint32_t dat; + uint32_t ink = 0; + uint32_t addr; - addr = (wy700->displine >> 1) * 80 + 4 * wy700->wy700_base; + addr = (wy700->displine >> 1) * 80 + 4 * wy700->wy700_base; - for (x = 0; x < 20; x++) { - dat = ((wy700->vram[addr & 0x1FFFF] << 24) | - (wy700->vram[(addr + 1) & 0x1FFFF] << 16) | - (wy700->vram[(addr + 2) & 0x1FFFF] << 8) | - (wy700->vram[(addr + 3) & 0x1FFFF])); - addr += 4; + for (x = 0; x < 20; x++) { + dat = ((wy700->vram[addr & 0x1FFFF] << 24) | (wy700->vram[(addr + 1) & 0x1FFFF] << 16) | + (wy700->vram[(addr + 2) & 0x1FFFF] << 8) | (wy700->vram[(addr + 3) & 0x1FFFF])); + addr += 4; - if (wy700->wy700_mode & 0x10) { - for (c = 0; c < 16; c++) { - ink = wy700_pal[(dat >> 30) & 3]; - /* Display disabled? */ - if (!(wy700->wy700_mode & 8)) - ink = wy700_pal[0]; - ((uint32_t *)buffer32->line[wy700->displine])[x * 64 + 4 * c] = - ((uint32_t *)buffer32->line[wy700->displine])[x * 64 + 4 * c + 1] = - ((uint32_t *)buffer32->line[wy700->displine])[x * 64 + 4 * c + 2] = - ((uint32_t *)buffer32->line[wy700->displine])[x * 64 + 4 * c + 3] = - ink; - dat = dat << 2; - } - } else { - for (c = 0; c < 32; c++) { - ink = (dat & 0x80000000) ? wy700_pal[3] : wy700_pal[0]; - /* Display disabled? */ - if (!(wy700->wy700_mode & 8)) - ink = wy700_pal[0]; - ((uint32_t *)buffer32->line[wy700->displine])[x * 64 + 2 * c] = - ((uint32_t *)buffer32->line[wy700->displine])[x * 64 + 2 * c + 1] = - ink; - dat = dat << 1; - } - } - } + if (wy700->wy700_mode & 0x10) { + for (c = 0; c < 16; c++) { + ink = wy700_pal[(dat >> 30) & 3]; + /* Display disabled? */ + if (!(wy700->wy700_mode & 8)) + ink = wy700_pal[0]; + ((uint32_t *)buffer32->line[wy700->displine])[x * 64 + 4 * c] = + ((uint32_t *)buffer32->line[wy700->displine])[x * 64 + 4 * c + 1] = + ((uint32_t *)buffer32->line[wy700->displine])[x * 64 + 4 * c + 2] = + ((uint32_t *)buffer32->line[wy700->displine])[x * 64 + 4 * c + 3] = ink; + dat = dat << 2; + } + } else { + for (c = 0; c < 32; c++) { + ink = (dat & 0x80000000) ? wy700_pal[3] : wy700_pal[0]; + /* Display disabled? */ + if (!(wy700->wy700_mode & 8)) + ink = wy700_pal[0]; + ((uint32_t *)buffer32->line[wy700->displine])[x * 64 + 2 * c] = + ((uint32_t *)buffer32->line[wy700->displine])[x * 64 + 2 * c + 1] = ink; + dat = dat << 1; + } + } + } } /* Draw a line in one of the high-resolution modes */ void wy700_hiresline(wy700_t *wy700) { - int x, c; - uint32_t dat; - uint32_t ink = 0; - uint32_t addr; + int x, c; + uint32_t dat; + uint32_t ink = 0; + uint32_t addr; - addr = (wy700->displine >> 1) * 160 + 4 * wy700->wy700_base; + addr = (wy700->displine >> 1) * 160 + 4 * wy700->wy700_base; - if (wy700->wy700_mode & 0x40) /* 800-line interleaved modes */ - { - if (wy700->displine & 1) - addr += 0x10000; - } - for (x = 0; x < 40; x++) { - dat = ((wy700->vram[addr & 0x1FFFF] << 24) | - (wy700->vram[(addr + 1) & 0x1FFFF] << 16) | - (wy700->vram[(addr + 2) & 0x1FFFF] << 8) | - (wy700->vram[(addr + 3) & 0x1FFFF])); - addr += 4; + if (wy700->wy700_mode & 0x40) /* 800-line interleaved modes */ + { + if (wy700->displine & 1) + addr += 0x10000; + } + for (x = 0; x < 40; x++) { + dat = ((wy700->vram[addr & 0x1FFFF] << 24) | (wy700->vram[(addr + 1) & 0x1FFFF] << 16) | + (wy700->vram[(addr + 2) & 0x1FFFF] << 8) | (wy700->vram[(addr + 3) & 0x1FFFF])); + addr += 4; - if (wy700->wy700_mode & 0x10) { - for (c = 0; c < 16; c++) { - ink = wy700_pal[(dat >> 30) & 3]; - /* Display disabled? */ - if (!(wy700->wy700_mode & 8)) - ink = wy700_pal[0]; - ((uint32_t *)buffer32->line[wy700->displine])[x * 32 + 2 * c] = - ((uint32_t *)buffer32->line[wy700->displine])[x * 32 + 2 * c + 1] = - ink; - dat = dat << 2; - } - } else { - for (c = 0; c < 32; c++) { - ink = (dat & 0x80000000) ? wy700_pal[3] : wy700_pal[0]; - /* Display disabled? */ - if (!(wy700->wy700_mode & 8)) - ink = wy700_pal[0]; - ((uint32_t *)buffer32->line[wy700->displine])[x * 32 + c] = ink; - dat = dat << 1; - } - } - } + if (wy700->wy700_mode & 0x10) { + for (c = 0; c < 16; c++) { + ink = wy700_pal[(dat >> 30) & 3]; + /* Display disabled? */ + if (!(wy700->wy700_mode & 8)) + ink = wy700_pal[0]; + ((uint32_t *)buffer32->line[wy700->displine])[x * 32 + 2 * c] = + ((uint32_t *)buffer32->line[wy700->displine])[x * 32 + 2 * c + 1] = ink; + dat = dat << 2; + } + } else { + for (c = 0; c < 32; c++) { + ink = (dat & 0x80000000) ? wy700_pal[3] : wy700_pal[0]; + /* Display disabled? */ + if (!(wy700->wy700_mode & 8)) + ink = wy700_pal[0]; + ((uint32_t *)buffer32->line[wy700->displine])[x * 32 + c] = ink; + dat = dat << 1; + } + } + } } void wy700_poll(void *p) { - wy700_t *wy700 = (wy700_t *)p; - int mode; + wy700_t *wy700 = (wy700_t *)p; + int mode; - if (!wy700->linepos) { - timer_advance_u64(&wy700->timer, wy700->dispofftime); - wy700->cga_stat |= 1; - wy700->mda_stat |= 1; - wy700->linepos = 1; - if (wy700->dispon) { - if (wy700->displine == 0) { - video_wait_for_buffer(); - } + if (!wy700->linepos) { + timer_advance_u64(&wy700->timer, wy700->dispofftime); + wy700->cga_stat |= 1; + wy700->mda_stat |= 1; + wy700->linepos = 1; + if (wy700->dispon) { + if (wy700->displine == 0) { + video_wait_for_buffer(); + } - if (wy700->wy700_mode & 0x80) - mode = wy700->wy700_mode & 0xF0; - else - mode = wy700->wy700_mode & 0x0F; + if (wy700->wy700_mode & 0x80) + mode = wy700->wy700_mode & 0xF0; + else + mode = wy700->wy700_mode & 0x0F; - switch (mode) { - default: - case 0x00: - case 0x02:wy700_textline(wy700); - break; - case 0x04: - case 0x06:wy700_cgaline(wy700); - break; - case 0x80: - case 0x90:wy700_medresline(wy700); - break; - case 0xA0: - case 0xB0: - case 0xC0: - case 0xD0: - case 0xE0: - case 0xF0:wy700_hiresline(wy700); - break; - } - } - wy700->displine++; - /* Hardcode a fixed refresh rate and VSYNC timing */ - if (wy700->displine == 800) /* Start of VSYNC */ - { - wy700->cga_stat |= 8; - wy700->dispon = 0; - } - if (wy700->displine == 832) /* End of VSYNC */ - { - wy700->displine = 0; - wy700->cga_stat &= ~8; - wy700->dispon = 1; - } - } else { - if (wy700->dispon) { - wy700->cga_stat &= ~1; - wy700->mda_stat &= ~1; - } - timer_advance_u64(&wy700->timer, wy700->dispontime); - wy700->linepos = 0; + switch (mode) { + default: + case 0x00: + case 0x02: + wy700_textline(wy700); + break; + case 0x04: + case 0x06: + wy700_cgaline(wy700); + break; + case 0x80: + case 0x90: + wy700_medresline(wy700); + break; + case 0xA0: + case 0xB0: + case 0xC0: + case 0xD0: + case 0xE0: + case 0xF0: + wy700_hiresline(wy700); + break; + } + } + wy700->displine++; + /* Hardcode a fixed refresh rate and VSYNC timing */ + if (wy700->displine == 800) /* Start of VSYNC */ + { + wy700->cga_stat |= 8; + wy700->dispon = 0; + } + if (wy700->displine == 832) /* End of VSYNC */ + { + wy700->displine = 0; + wy700->cga_stat &= ~8; + wy700->dispon = 1; + } + } else { + if (wy700->dispon) { + wy700->cga_stat &= ~1; + wy700->mda_stat &= ~1; + } + timer_advance_u64(&wy700->timer, wy700->dispontime); + wy700->linepos = 0; - if (wy700->displine == 800) { -/* Hardcode 1280x800 window size */ - if (WY700_XSIZE != xsize || WY700_YSIZE != ysize) { - xsize = WY700_XSIZE; - ysize = WY700_YSIZE; - if (xsize < 64) - xsize = 656; - if (ysize < 32) - ysize = 200; - updatewindowsize(xsize, ysize); - } - video_blit_memtoscreen(0, 0, 0, ysize, xsize, ysize); + if (wy700->displine == 800) { + /* Hardcode 1280x800 window size */ + if (WY700_XSIZE != xsize || WY700_YSIZE != ysize) { + xsize = WY700_XSIZE; + ysize = WY700_YSIZE; + if (xsize < 64) + xsize = 656; + if (ysize < 32) + ysize = 200; + updatewindowsize(xsize, ysize); + } + video_blit_memtoscreen(0, 0, 0, ysize, xsize, ysize); - frames++; - /* Fixed 1280x800 resolution */ - video_res_x = WY700_XSIZE; - video_res_y = WY700_YSIZE; - if (wy700->wy700_mode & 0x80) - mode = wy700->wy700_mode & 0xF0; - else - mode = wy700->wy700_mode & 0x0F; - switch (mode) { - case 0x00: - case 0x02:video_bpp = 0; - break; - case 0x04: - case 0x90: - case 0xB0: - case 0xD0: - case 0xF0:video_bpp = 2; - break; - default:video_bpp = 1; - break; - } - wy700->blink++; - } - } + frames++; + /* Fixed 1280x800 resolution */ + video_res_x = WY700_XSIZE; + video_res_y = WY700_YSIZE; + if (wy700->wy700_mode & 0x80) + mode = wy700->wy700_mode & 0xF0; + else + mode = wy700->wy700_mode & 0x0F; + switch (mode) { + case 0x00: + case 0x02: + video_bpp = 0; + break; + case 0x04: + case 0x90: + case 0xB0: + case 0xD0: + case 0xF0: + video_bpp = 2; + break; + default: + video_bpp = 1; + break; + } + wy700->blink++; + } + } } void *wy700_init() { - int c; - wy700_t *wy700 = malloc(sizeof(wy700_t)); - memset(wy700, 0, sizeof(wy700_t)); + int c; + wy700_t *wy700 = malloc(sizeof(wy700_t)); + memset(wy700, 0, sizeof(wy700_t)); - /* 128k video RAM */ - wy700->vram = malloc(0x20000); + /* 128k video RAM */ + wy700->vram = malloc(0x20000); - timer_add(&wy700->timer, wy700_poll, wy700, 1); + timer_add(&wy700->timer, wy700_poll, wy700, 1); - /* Occupy memory between 0xB0000 and 0xBFFFF (moves to 0xA0000 in - * high-resolution modes) */ - mem_mapping_add(&wy700->mapping, 0xb0000, 0x10000, wy700_read, NULL, NULL, wy700_write, NULL, NULL, NULL, 0, wy700); - /* Respond to both MDA and CGA I/O ports */ - io_sethandler(0x03b0, 0x000C, wy700_in, NULL, NULL, wy700_out, NULL, NULL, wy700); - io_sethandler(0x03d0, 0x0010, wy700_in, NULL, NULL, wy700_out, NULL, NULL, wy700); + /* Occupy memory between 0xB0000 and 0xBFFFF (moves to 0xA0000 in + * high-resolution modes) */ + mem_mapping_add(&wy700->mapping, 0xb0000, 0x10000, wy700_read, NULL, NULL, wy700_write, NULL, NULL, NULL, 0, wy700); + /* Respond to both MDA and CGA I/O ports */ + io_sethandler(0x03b0, 0x000C, wy700_in, NULL, NULL, wy700_out, NULL, NULL, wy700); + io_sethandler(0x03d0, 0x0010, wy700_in, NULL, NULL, wy700_out, NULL, NULL, wy700); - wy700_pal[0] = makecol(0x00, 0x00, 0x00); - wy700_pal[1] = makecol(0x55, 0x55, 0x55); - wy700_pal[2] = makecol(0xaa, 0xaa, 0xaa); - wy700_pal[3] = makecol(0xff, 0xff, 0xff); + wy700_pal[0] = makecol(0x00, 0x00, 0x00); + wy700_pal[1] = makecol(0x55, 0x55, 0x55); + wy700_pal[2] = makecol(0xaa, 0xaa, 0xaa); + wy700_pal[3] = makecol(0xff, 0xff, 0xff); - /* Set up the emulated attributes. - * CGA is done in four groups: 00-0F, 10-7F, 80-8F, 90-FF */ - for (c = 0; c < 0x10; c++) { - cgacols[c][0][0] = cgacols[c][1][0] = cgacols[c][1][1] = wy700_pal[0]; - if (c & 8) - cgacols[c][0][1] = wy700_pal[3]; - else - cgacols[c][0][1] = wy700_pal[2]; - } - for (c = 0x10; c < 0x80; c++) { - cgacols[c][0][0] = cgacols[c][1][0] = cgacols[c][1][1] = wy700_pal[2]; - if (c & 8) - cgacols[c][0][1] = wy700_pal[3]; - else - cgacols[c][0][1] = wy700_pal[0]; + /* Set up the emulated attributes. + * CGA is done in four groups: 00-0F, 10-7F, 80-8F, 90-FF */ + for (c = 0; c < 0x10; c++) { + cgacols[c][0][0] = cgacols[c][1][0] = cgacols[c][1][1] = wy700_pal[0]; + if (c & 8) + cgacols[c][0][1] = wy700_pal[3]; + else + cgacols[c][0][1] = wy700_pal[2]; + } + for (c = 0x10; c < 0x80; c++) { + cgacols[c][0][0] = cgacols[c][1][0] = cgacols[c][1][1] = wy700_pal[2]; + if (c & 8) + cgacols[c][0][1] = wy700_pal[3]; + else + cgacols[c][0][1] = wy700_pal[0]; - if ((c & 0x0F) == 8) - cgacols[c][0][1] = wy700_pal[1]; - } - /* With special cases for 00, 11, 22, ... 77 */ - cgacols[0x00][0][1] = cgacols[0x00][1][1] = wy700_pal[0]; - for (c = 0x11; c <= 0x77; c += 0x11) { - cgacols[c][0][1] = cgacols[c][1][1] = wy700_pal[2]; - } - for (c = 0x80; c < 0x90; c++) { - cgacols[c][0][0] = wy700_pal[1]; - if (c & 8) - cgacols[c][0][1] = wy700_pal[3]; - else - cgacols[c][0][1] = wy700_pal[2]; - cgacols[c][1][0] = cgacols[c][1][1] = cgacols[c - 0x80][0][0]; - } - for (c = 0x90; c < 0x100; c++) { - cgacols[c][0][0] = wy700_pal[3]; - if (c & 8) - cgacols[c][0][1] = wy700_pal[1]; - else - cgacols[c][0][1] = wy700_pal[2]; - if ((c & 0x0F) == 0) - cgacols[c][0][1] = wy700_pal[0]; - cgacols[c][1][0] = cgacols[c][1][1] = cgacols[c - 0x80][0][0]; - } - /* Also special cases for 99, AA, ..., FF */ - for (c = 0x99; c <= 0xFF; c += 0x11) { - cgacols[c][0][1] = wy700_pal[3]; - } - /* Special cases for 08, 80 and 88 */ - cgacols[0x08][0][1] = wy700_pal[1]; - cgacols[0x80][0][1] = wy700_pal[0]; - cgacols[0x88][0][1] = wy700_pal[1]; + if ((c & 0x0F) == 8) + cgacols[c][0][1] = wy700_pal[1]; + } + /* With special cases for 00, 11, 22, ... 77 */ + cgacols[0x00][0][1] = cgacols[0x00][1][1] = wy700_pal[0]; + for (c = 0x11; c <= 0x77; c += 0x11) { + cgacols[c][0][1] = cgacols[c][1][1] = wy700_pal[2]; + } + for (c = 0x80; c < 0x90; c++) { + cgacols[c][0][0] = wy700_pal[1]; + if (c & 8) + cgacols[c][0][1] = wy700_pal[3]; + else + cgacols[c][0][1] = wy700_pal[2]; + cgacols[c][1][0] = cgacols[c][1][1] = cgacols[c - 0x80][0][0]; + } + for (c = 0x90; c < 0x100; c++) { + cgacols[c][0][0] = wy700_pal[3]; + if (c & 8) + cgacols[c][0][1] = wy700_pal[1]; + else + cgacols[c][0][1] = wy700_pal[2]; + if ((c & 0x0F) == 0) + cgacols[c][0][1] = wy700_pal[0]; + cgacols[c][1][0] = cgacols[c][1][1] = cgacols[c - 0x80][0][0]; + } + /* Also special cases for 99, AA, ..., FF */ + for (c = 0x99; c <= 0xFF; c += 0x11) { + cgacols[c][0][1] = wy700_pal[3]; + } + /* Special cases for 08, 80 and 88 */ + cgacols[0x08][0][1] = wy700_pal[1]; + cgacols[0x80][0][1] = wy700_pal[0]; + cgacols[0x88][0][1] = wy700_pal[1]; - /* MDA attributes */ - for (c = 0; c < 256; c++) { - mdacols[c][0][0] = mdacols[c][1][0] = mdacols[c][1][1] = wy700_pal[0]; - if (c & 8) - mdacols[c][0][1] = wy700_pal[3]; - else - mdacols[c][0][1] = wy700_pal[2]; - } - mdacols[0x70][0][1] = wy700_pal[0]; - mdacols[0x70][0][0] = mdacols[0x70][1][0] = mdacols[0x70][1][1] = wy700_pal[3]; - mdacols[0xF0][0][1] = wy700_pal[0]; - mdacols[0xF0][0][0] = mdacols[0xF0][1][0] = mdacols[0xF0][1][1] = wy700_pal[3]; - mdacols[0x78][0][1] = wy700_pal[2]; - mdacols[0x78][0][0] = mdacols[0x78][1][0] = mdacols[0x78][1][1] = wy700_pal[3]; - mdacols[0xF8][0][1] = wy700_pal[2]; - mdacols[0xF8][0][0] = mdacols[0xF8][1][0] = mdacols[0xF8][1][1] = wy700_pal[3]; - mdacols[0x00][0][1] = mdacols[0x00][1][1] = wy700_pal[0]; - mdacols[0x08][0][1] = mdacols[0x08][1][1] = wy700_pal[0]; - mdacols[0x80][0][1] = mdacols[0x80][1][1] = wy700_pal[0]; - mdacols[0x88][0][1] = mdacols[0x88][1][1] = wy700_pal[0]; + /* MDA attributes */ + for (c = 0; c < 256; c++) { + mdacols[c][0][0] = mdacols[c][1][0] = mdacols[c][1][1] = wy700_pal[0]; + if (c & 8) + mdacols[c][0][1] = wy700_pal[3]; + else + mdacols[c][0][1] = wy700_pal[2]; + } + mdacols[0x70][0][1] = wy700_pal[0]; + mdacols[0x70][0][0] = mdacols[0x70][1][0] = mdacols[0x70][1][1] = wy700_pal[3]; + mdacols[0xF0][0][1] = wy700_pal[0]; + mdacols[0xF0][0][0] = mdacols[0xF0][1][0] = mdacols[0xF0][1][1] = wy700_pal[3]; + mdacols[0x78][0][1] = wy700_pal[2]; + mdacols[0x78][0][0] = mdacols[0x78][1][0] = mdacols[0x78][1][1] = wy700_pal[3]; + mdacols[0xF8][0][1] = wy700_pal[2]; + mdacols[0xF8][0][0] = mdacols[0xF8][1][0] = mdacols[0xF8][1][1] = wy700_pal[3]; + mdacols[0x00][0][1] = mdacols[0x00][1][1] = wy700_pal[0]; + mdacols[0x08][0][1] = mdacols[0x08][1][1] = wy700_pal[0]; + mdacols[0x80][0][1] = mdacols[0x80][1][1] = wy700_pal[0]; + mdacols[0x88][0][1] = mdacols[0x88][1][1] = wy700_pal[0]; -/* Start off in 80x25 text mode */ - wy700->cga_stat = 0xF4; - wy700->wy700_mode = 2; - wy700->enabled = 1; - memcpy(wy700->real_crtc, mode_80x24, sizeof(mode_80x24)); - return wy700; + /* Start off in 80x25 text mode */ + wy700->cga_stat = 0xF4; + wy700->wy700_mode = 2; + wy700->enabled = 1; + memcpy(wy700->real_crtc, mode_80x24, sizeof(mode_80x24)); + return wy700; } void wy700_close(void *p) { - wy700_t *wy700 = (wy700_t *)p; + wy700_t *wy700 = (wy700_t *)p; - free(wy700->vram); - free(wy700); + free(wy700->vram); + free(wy700); } void wy700_speed_changed(void *p) { - wy700_t *wy700 = (wy700_t *)p; + wy700_t *wy700 = (wy700_t *)p; - wy700_recalctimings(wy700); + wy700_recalctimings(wy700); } -device_t wy700_device = - { - "Wyse 700", - 0, - wy700_init, - wy700_close, - NULL, - wy700_speed_changed, - NULL, - NULL - }; +device_t wy700_device = {"Wyse 700", 0, wy700_init, wy700_close, NULL, wy700_speed_changed, NULL, NULL}; diff --git a/src/video/video.c b/src/video/video.c index a187304c..240447d4 100644 --- a/src/video/video.c +++ b/src/video/video.c @@ -56,69 +56,136 @@ extern VIDEO_CARD *video_cards[GFX_MAX]; -enum { - VIDEO_ISA = 0, - VIDEO_BUS -}; +enum { VIDEO_ISA = 0, VIDEO_BUS }; -#define VIDEO_FLAG_TYPE_CGA 0 -#define VIDEO_FLAG_TYPE_MDA 1 +#define VIDEO_FLAG_TYPE_CGA 0 +#define VIDEO_FLAG_TYPE_MDA 1 #define VIDEO_FLAG_TYPE_SPECIAL 2 -#define VIDEO_FLAG_TYPE_MASK 3 +#define VIDEO_FLAG_TYPE_MASK 3 -VIDEO_CARD v_banshee = {"3DFX Voodoo Banshee (reference)", "banshee", &voodoo_banshee_device, GFX_BANSHEE, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}}; -VIDEO_CARD v_v3_2000 = {"3DFX Voodoo 3 2000", "v3_2000", &voodoo_3_2000_device, GFX_VOODOO_3_2000, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}}; -VIDEO_CARD v_v3_3000 = {"3DFX Voodoo 3 3000", "v3_3000", &voodoo_3_3000_device, GFX_VOODOO_3_3000, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}}; -VIDEO_CARD v_avga2 = {"Acumos AVGA2 / Cirrus Logic CL-GD5402", "avga2", &avga2_device, GFX_AVGA2, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}; -VIDEO_CARD v_mach64gx = {"ATI Graphics Pro Turbo (Mach64 GX)", "mach64gx", &mach64gx_device, GFX_MACH64GX, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}}; -VIDEO_CARD v_mach64vt2 = {"ATI Video Xpression (Mach64 VT2)", "mach64vt2", &mach64vt2_device, GFX_MACH64VT2, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}}; -VIDEO_CARD v_egawonder800 = {"ATI EGA Wonder 800+ (ATI-18800)", "egawonder800", &ati_ega_wonder_800_device, GFX_EGAWONDER800, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}; -VIDEO_CARD v_ati28800k = {"ATI Korean VGA (ATI-28800)", "ati28800k", &ati28800k_device, GFX_ATIKOREANVGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}; -VIDEO_CARD v_ati28800 = {"ATI VGA Charger (ATI-28800)", "ati28800", &ati28800_device, GFX_VGACHARGER, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}; -VIDEO_CARD v_ati18800 = {"ATI VGA Edge-16 (ATI-18800)", "ati18800", &ati18800_device, GFX_VGAEDGE16, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}; +VIDEO_CARD v_banshee = { + "3DFX Voodoo Banshee (reference)", "banshee", &voodoo_banshee_device, GFX_BANSHEE, VIDEO_FLAG_TYPE_SPECIAL, + {VIDEO_BUS, 2, 2, 1, 20, 20, 21}}; +VIDEO_CARD v_v3_2000 = {"3DFX Voodoo 3 2000", "v3_2000", + &voodoo_3_2000_device, GFX_VOODOO_3_2000, + VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}}; +VIDEO_CARD v_v3_3000 = {"3DFX Voodoo 3 3000", "v3_3000", + &voodoo_3_3000_device, GFX_VOODOO_3_3000, + VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}}; +VIDEO_CARD v_avga2 = {"Acumos AVGA2 / Cirrus Logic CL-GD5402", "avga2", &avga2_device, GFX_AVGA2, VIDEO_FLAG_TYPE_SPECIAL, + {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}; +VIDEO_CARD v_mach64gx = { + "ATI Graphics Pro Turbo (Mach64 GX)", "mach64gx", &mach64gx_device, GFX_MACH64GX, VIDEO_FLAG_TYPE_SPECIAL, + {VIDEO_BUS, 2, 2, 1, 20, 20, 21}}; +VIDEO_CARD v_mach64vt2 = { + "ATI Video Xpression (Mach64 VT2)", "mach64vt2", &mach64vt2_device, GFX_MACH64VT2, VIDEO_FLAG_TYPE_SPECIAL, + {VIDEO_BUS, 2, 2, 1, 20, 20, 21}}; +VIDEO_CARD v_egawonder800 = {"ATI EGA Wonder 800+ (ATI-18800)", "egawonder800", + &ati_ega_wonder_800_device, GFX_EGAWONDER800, + VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}; +VIDEO_CARD v_ati28800k = { + "ATI Korean VGA (ATI-28800)", "ati28800k", &ati28800k_device, GFX_ATIKOREANVGA, VIDEO_FLAG_TYPE_SPECIAL, + {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}; +VIDEO_CARD v_ati28800 = {"ATI VGA Charger (ATI-28800)", "ati28800", &ati28800_device, GFX_VGACHARGER, VIDEO_FLAG_TYPE_SPECIAL, + {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}; +VIDEO_CARD v_ati18800 = {"ATI VGA Edge-16 (ATI-18800)", "ati18800", &ati18800_device, GFX_VGAEDGE16, VIDEO_FLAG_TYPE_SPECIAL, + {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}; VIDEO_CARD v_cga = {"CGA", "cga", &cga_device, GFX_CGA, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}; -VIDEO_CARD v_cl_gd5428 = {"Cirrus Logic CL-GD5428", "cl_gd5428", &gd5428_device, GFX_CL_GD5428, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}; -VIDEO_CARD v_cl_gd5429 = {"Cirrus Logic CL-GD5429", "cl_gd5429", &gd5429_device, GFX_CL_GD5429, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}; -VIDEO_CARD v_cl_gd5430 = {"Cirrus Logic CL-GD5430", "cl_gd5430", &gd5430_device, GFX_CL_GD5430, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}; -VIDEO_CARD v_cl_gd5434 = {"Cirrus Logic CL-GD5434", "cl_gd5434", &gd5434_device, GFX_CL_GD5434, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}; -VIDEO_CARD v_compaq_cga_device = {"Compaq CGA", "compaq_cga", &compaq_cga_device, GFX_COMPAQ_CGA, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}; -VIDEO_CARD v_cl_banshee = {"Creative Labs 3D Blaster Banshee PCI", "cl_banshee", &creative_voodoo_banshee_device, GFX_CL_BANSHEE, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}}; -VIDEO_CARD v_stealth32 = {"Diamond Stealth 32 (Tseng ET4000/w32p)", "stealth32", &et4000w32p_device, GFX_ET4000W32, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 4, 10, 10, 10}}; -VIDEO_CARD v_stealth3d_2000 = {"Diamond Stealth 3D 2000 (S3 ViRGE)", "stealth3d_2000", &s3_virge_device, GFX_VIRGE, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 28, 28, 45}}; +VIDEO_CARD v_cl_gd5428 = {"Cirrus Logic CL-GD5428", "cl_gd5428", &gd5428_device, GFX_CL_GD5428, VIDEO_FLAG_TYPE_SPECIAL, + {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}; +VIDEO_CARD v_cl_gd5429 = {"Cirrus Logic CL-GD5429", "cl_gd5429", &gd5429_device, GFX_CL_GD5429, VIDEO_FLAG_TYPE_SPECIAL, + {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}; +VIDEO_CARD v_cl_gd5430 = {"Cirrus Logic CL-GD5430", "cl_gd5430", &gd5430_device, GFX_CL_GD5430, VIDEO_FLAG_TYPE_SPECIAL, + {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}; +VIDEO_CARD v_cl_gd5434 = {"Cirrus Logic CL-GD5434", "cl_gd5434", &gd5434_device, GFX_CL_GD5434, VIDEO_FLAG_TYPE_SPECIAL, + {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}; +VIDEO_CARD v_compaq_cga_device = {"Compaq CGA", "compaq_cga", &compaq_cga_device, + GFX_COMPAQ_CGA, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}; +VIDEO_CARD v_cl_banshee = {"Creative Labs 3D Blaster Banshee PCI", + "cl_banshee", + &creative_voodoo_banshee_device, + GFX_CL_BANSHEE, + VIDEO_FLAG_TYPE_SPECIAL, + {VIDEO_BUS, 2, 2, 1, 20, 20, 21}}; +VIDEO_CARD v_stealth32 = { + "Diamond Stealth 32 (Tseng ET4000/w32p)", "stealth32", &et4000w32p_device, GFX_ET4000W32, VIDEO_FLAG_TYPE_SPECIAL, + {VIDEO_BUS, 4, 4, 4, 10, 10, 10}}; +VIDEO_CARD v_stealth3d_2000 = { + "Diamond Stealth 3D 2000 (S3 ViRGE)", "stealth3d_2000", &s3_virge_device, GFX_VIRGE, VIDEO_FLAG_TYPE_SPECIAL, + {VIDEO_BUS, 2, 2, 3, 28, 28, 45}}; VIDEO_CARD v_ega = {"EGA", "ega", &ega_device, GFX_EGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}; -VIDEO_CARD v_hercules = {"Hercules", "hercules", &hercules_device, GFX_HERCULES, VIDEO_FLAG_TYPE_MDA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}; -VIDEO_CARD v_incolor = {"Hercules InColor", "incolor", &incolor_device, GFX_INCOLOR, VIDEO_FLAG_TYPE_MDA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}; -VIDEO_CARD v_ibm1mbsvga = {"IBM 1MB SVGA Adapter/A (CL GD5428)", "ibm1mbsvga", &ibm_gd5428_device, GFX_IBM_GD5428, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}; -VIDEO_CARD v_im1024 = {"Image Manager 1024", "im1024", &im1024_device, GFX_IM1024, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}; -VIDEO_CARD v_kasan16 = {"Kasan Hangulmadang-16 (Tseng ET4000AX)", "kasan16", &et4000_kasan_device, GFX_KASAN16VGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}; -VIDEO_CARD v_mystique = {"Matrox Mystique", "mystique", &mystique_device, GFX_MYSTIQUE, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 4, 10, 10, 10}}; -VIDEO_CARD v_millennium = {"Matrox Millennium", "millennium", &millennium_device, GFX_MILLENNIUM, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 1, 10, 10, 10}}; +VIDEO_CARD v_hercules = {"Hercules", "hercules", &hercules_device, + GFX_HERCULES, VIDEO_FLAG_TYPE_MDA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}; +VIDEO_CARD v_incolor = {"Hercules InColor", "incolor", &incolor_device, + GFX_INCOLOR, VIDEO_FLAG_TYPE_MDA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}; +VIDEO_CARD v_ibm1mbsvga = { + "IBM 1MB SVGA Adapter/A (CL GD5428)", "ibm1mbsvga", &ibm_gd5428_device, GFX_IBM_GD5428, VIDEO_FLAG_TYPE_SPECIAL, + {VIDEO_BUS, 4, 4, 8, 10, 10, 20}}; +VIDEO_CARD v_im1024 = { + "Image Manager 1024", "im1024", &im1024_device, GFX_IM1024, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}; +VIDEO_CARD v_kasan16 = {"Kasan Hangulmadang-16 (Tseng ET4000AX)", + "kasan16", + &et4000_kasan_device, + GFX_KASAN16VGA, + VIDEO_FLAG_TYPE_SPECIAL, + {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}; +VIDEO_CARD v_mystique = { + "Matrox Mystique", "mystique", &mystique_device, GFX_MYSTIQUE, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 4, 10, 10, 10}}; +VIDEO_CARD v_millennium = {"Matrox Millennium", "millennium", + &millennium_device, GFX_MILLENNIUM, + VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 1, 10, 10, 10}}; VIDEO_CARD v_mda = {"MDA", "mda", &mda_device, GFX_MDA, VIDEO_FLAG_TYPE_MDA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}; -VIDEO_CARD v_genius = {"MDSI Genius", "genius", &genius_device, GFX_GENIUS, VIDEO_FLAG_TYPE_MDA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}; -VIDEO_CARD v_n9_9fx = {"Number Nine 9FX (S3 Trio64)", "n9_9fx", &s3_9fx_device, GFX_N9_9FX, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 3, 2, 4, 25, 25, 40}}; -VIDEO_CARD v_oti037 = {"OAK OTI-037", "oti037", &oti037_device, GFX_OTI037, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 6, 8, 16, 6, 8, 16}}; -VIDEO_CARD v_oti067 = {"OAK OTI-067", "oti067", &oti067_device, GFX_OTI067, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 6, 8, 16, 6, 8, 16}}; -VIDEO_CARD v_olivetti_go481 = {"Olivetti GO481 (Paradise PVGA1A)", "olivetti_go481", ¶dise_pvga1a_oli_go481_device, GFX_OLIVETTI_GO481, VIDEO_FLAG_TYPE_SPECIAL, - {VIDEO_ISA, 6, 8, 16, 6, 8, 16}}; -VIDEO_CARD v_bahamas64 = {"Paradise Bahamas 64 (S3 Vision864)", "bahamas64", &s3_bahamas64_device, GFX_BAHAMAS64, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 5, 20, 20, 35}}; +VIDEO_CARD v_genius = { + "MDSI Genius", "genius", &genius_device, GFX_GENIUS, VIDEO_FLAG_TYPE_MDA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}; +VIDEO_CARD v_n9_9fx = {"Number Nine 9FX (S3 Trio64)", "n9_9fx", &s3_9fx_device, GFX_N9_9FX, VIDEO_FLAG_TYPE_SPECIAL, + {VIDEO_BUS, 3, 2, 4, 25, 25, 40}}; +VIDEO_CARD v_oti037 = { + "OAK OTI-037", "oti037", &oti037_device, GFX_OTI037, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 6, 8, 16, 6, 8, 16}}; +VIDEO_CARD v_oti067 = { + "OAK OTI-067", "oti067", &oti067_device, GFX_OTI067, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 6, 8, 16, 6, 8, 16}}; +VIDEO_CARD v_olivetti_go481 = {"Olivetti GO481 (Paradise PVGA1A)", + "olivetti_go481", + ¶dise_pvga1a_oli_go481_device, + GFX_OLIVETTI_GO481, + VIDEO_FLAG_TYPE_SPECIAL, + {VIDEO_ISA, 6, 8, 16, 6, 8, 16}}; +VIDEO_CARD v_bahamas64 = { + "Paradise Bahamas 64 (S3 Vision864)", "bahamas64", &s3_bahamas64_device, GFX_BAHAMAS64, VIDEO_FLAG_TYPE_SPECIAL, + {VIDEO_BUS, 4, 4, 5, 20, 20, 35}}; #ifdef USE_EXPERIMENTAL_PGC -VIDEO_CARD v_pgc = {"Professional Graphics Controller", "pgc", &pgc_device, GFX_PGC, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}; +VIDEO_CARD v_pgc = {"Professional Graphics Controller", "pgc", &pgc_device, GFX_PGC, VIDEO_FLAG_TYPE_CGA, + {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}; #endif -VIDEO_CARD v_px_trio32 = {"Phoenix S3 Trio32", "px_trio32", &s3_phoenix_trio32_device, GFX_PHOENIX_TRIO32, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 3, 2, 4, 25, 25, 40}}; -VIDEO_CARD v_px_trio64 = {"Phoenix S3 Trio64", "px_trio64", &s3_phoenix_trio64_device, GFX_PHOENIX_TRIO64, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 3, 2, 4, 25, 25, 40}}; -VIDEO_CARD v_plantronics = {"Plantronics ColorPlus", "plantronics", &colorplus_device, GFX_COLORPLUS, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}; -VIDEO_CARD v_virge375 = {"S3 ViRGE/DX", "virge375", &s3_virge_375_device, GFX_VIRGEDX, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 28, 28, 45}}; -VIDEO_CARD v_sigma400 = {"Sigma Color 400", "sigma400", &sigma_device, GFX_SIGMA400, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}; -VIDEO_CARD v_tvga8900d = {"Trident TVGA8900D", "tvga8900d", &tvga8900d_device, GFX_TVGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 8, 8, 12}}; -VIDEO_CARD v_tvga9000b = {"Trident TVGA9000B", "tvga9000b", &tvga9000b_device, GFX_TVGA9000B, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 7, 7, 12, 7, 7, 12}}; -VIDEO_CARD v_tgui9400cxi = {"Trident TGUI9400CXi", "tgui9400cxi", &tgui9400cxi_device, GFX_TGUI9400CXI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 8, 16, 4, 8, 16}}; -VIDEO_CARD v_tgui9440 = {"Trident TGUI9440", "tgui9440", &tgui9440_device, GFX_TGUI9440, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 8, 16, 4, 8, 16}}; -VIDEO_CARD v_tgkorvga = {"Trigem Korean VGA (Tseng ET4000AX)", "tgkorvga", &et4000k_device, GFX_TGKOREANVGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}; -VIDEO_CARD v_et4000ax = {"Tseng ET4000AX", "et4000ax", &et4000_device, GFX_ET4000, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}; +VIDEO_CARD v_px_trio32 = {"Phoenix S3 Trio32", "px_trio32", + &s3_phoenix_trio32_device, GFX_PHOENIX_TRIO32, + VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 3, 2, 4, 25, 25, 40}}; +VIDEO_CARD v_px_trio64 = {"Phoenix S3 Trio64", "px_trio64", + &s3_phoenix_trio64_device, GFX_PHOENIX_TRIO64, + VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 3, 2, 4, 25, 25, 40}}; +VIDEO_CARD v_plantronics = {"Plantronics ColorPlus", "plantronics", &colorplus_device, + GFX_COLORPLUS, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}; +VIDEO_CARD v_virge375 = { + "S3 ViRGE/DX", "virge375", &s3_virge_375_device, GFX_VIRGEDX, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 3, 28, 28, 45}}; +VIDEO_CARD v_sigma400 = {"Sigma Color 400", "sigma400", &sigma_device, + GFX_SIGMA400, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}; +VIDEO_CARD v_tvga8900d = {"Trident TVGA8900D", "tvga8900d", &tvga8900d_device, GFX_TVGA, VIDEO_FLAG_TYPE_SPECIAL, + {VIDEO_ISA, 3, 3, 6, 8, 8, 12}}; +VIDEO_CARD v_tvga9000b = {"Trident TVGA9000B", "tvga9000b", + &tvga9000b_device, GFX_TVGA9000B, + VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 7, 7, 12, 7, 7, 12}}; +VIDEO_CARD v_tgui9400cxi = {"Trident TGUI9400CXi", "tgui9400cxi", &tgui9400cxi_device, + GFX_TGUI9400CXI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 8, 16, 4, 8, 16}}; +VIDEO_CARD v_tgui9440 = { + "Trident TGUI9440", "tgui9440", &tgui9440_device, GFX_TGUI9440, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 8, 16, 4, 8, 16}}; +VIDEO_CARD v_tgkorvga = { + "Trigem Korean VGA (Tseng ET4000AX)", "tgkorvga", &et4000k_device, GFX_TGKOREANVGA, VIDEO_FLAG_TYPE_SPECIAL, + {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}; +VIDEO_CARD v_et4000ax = { + "Tseng ET4000AX", "et4000ax", &et4000_device, GFX_ET4000, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}; VIDEO_CARD v_vga = {"VGA", "vga", &vga_device, GFX_VGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}; VIDEO_CARD v_wy700 = {"Wyse 700", "wy700", &wy700_device, GFX_WY700, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}; -static video_timings_t timing_dram = {VIDEO_BUS, 0, 0, 0, 0, 0, 0}; /*No additional waitstates*/ +static video_timings_t timing_dram = {VIDEO_BUS, 0, 0, 0, 0, 0, 0}; /*No additional waitstates*/ static video_timings_t timing_pc1512 = {VIDEO_BUS, 0, 0, 0, 0, 0, 0}; /*PC1512 video code handles waitstates itself*/ static video_timings_t timing_pc1640 = {VIDEO_ISA, 8, 16, 32, 8, 16, 32}; static video_timings_t timing_pc200 = {VIDEO_ISA, 8, 16, 32, 8, 16, 32}; @@ -138,301 +205,324 @@ static video_timings_t timing_pb570 = {VIDEO_BUS, 4, 4, 8, 10, 10, 20}; static video_timings_t timing_pb520r = {VIDEO_BUS, 4, 4, 8, 10, 10, 20}; int video_card_available(int card) { - if (card == GFX_BUILTIN) - return 1; + if (card == GFX_BUILTIN) + return 1; - if (video_cards[card]->device) - return device_available(video_cards[card]->device); + if (video_cards[card]->device) + return device_available(video_cards[card]->device); - return 1; + return 1; } char *video_card_getname(int card) { - if (card == GFX_BUILTIN) - return "Built-in video"; - if (video_cards[card] == NULL) - return ""; + if (card == GFX_BUILTIN) + return "Built-in video"; + if (video_cards[card] == NULL) + return ""; - return video_cards[card]->name; + return video_cards[card]->name; } device_t *video_card_getdevice(int card, int romset) { - switch (romset) { - case ROM_IBMPCJR:return &pcjr_video_device; + switch (romset) { + case ROM_IBMPCJR: + return &pcjr_video_device; - case ROM_TANDY: - case ROM_TANDY1000HX:return &tandy_device; + case ROM_TANDY: + case ROM_TANDY1000HX: + return &tandy_device; - case ROM_TANDY1000SL2:return &tandysl_device; + case ROM_TANDY1000SL2: + return &tandysl_device; - case ROM_PC1512:return &pc1512_device; + case ROM_PC1512: + return &pc1512_device; - case ROM_PC1640: - if (card == GFX_BUILTIN) - return &pc1640_device; - break; + case ROM_PC1640: + if (card == GFX_BUILTIN) + return &pc1640_device; + break; - case ROM_PC200: - if (card == GFX_BUILTIN) - return &pc200_device; - break; + case ROM_PC200: + if (card == GFX_BUILTIN) + return &pc200_device; + break; - case ROM_PPC512: - if (card == GFX_BUILTIN) - return &ppc512_device; - break; + case ROM_PPC512: + if (card == GFX_BUILTIN) + return &ppc512_device; + break; - case ROM_OLIM24:return &m24_device; + case ROM_OLIM24: + return &m24_device; - case ROM_PC2086: - if (card == GFX_BUILTIN) - return ¶dise_pvga1a_pc2086_device; - break; + case ROM_PC2086: + if (card == GFX_BUILTIN) + return ¶dise_pvga1a_pc2086_device; + break; - case ROM_PC3086: - if (card == GFX_BUILTIN) - return ¶dise_pvga1a_pc3086_device; - break; + case ROM_PC3086: + if (card == GFX_BUILTIN) + return ¶dise_pvga1a_pc3086_device; + break; - case ROM_MEGAPC:return ¶dise_wd90c11_megapc_device; + case ROM_MEGAPC: + return ¶dise_wd90c11_megapc_device; - case ROM_SPC4620P: - if (card == GFX_BUILTIN) - return &ati28800k_spc4620p_device; - break; + case ROM_SPC4620P: + if (card == GFX_BUILTIN) + return &ati28800k_spc4620p_device; + break; - case ROM_SPC6033P: - if (card == GFX_BUILTIN) - return &ati28800k_spc6033p_device; - break; + case ROM_SPC6033P: + if (card == GFX_BUILTIN) + return &ati28800k_spc6033p_device; + break; - case ROM_ACER386:return &oti067_acer386_device; + case ROM_ACER386: + return &oti067_acer386_device; - case ROM_AMA932J:return &oti067_ama932j_device; + case ROM_AMA932J: + return &oti067_ama932j_device; - case ROM_IBMPS1_2011: - case ROM_IBMPS2_M30_286:return &ps1vga_device; + case ROM_IBMPS1_2011: + case ROM_IBMPS2_M30_286: + return &ps1vga_device; - case ROM_IBMPS2_M50: - case ROM_IBMPS2_M55SX: - case ROM_IBMPS2_M70_TYPE3: - case ROM_IBMPS2_M70_TYPE4: - case ROM_IBMPS2_M80: - if (card == GFX_BUILTIN) - return &ps1vga_device; - break; + case ROM_IBMPS2_M50: + case ROM_IBMPS2_M55SX: + case ROM_IBMPS2_M70_TYPE3: + case ROM_IBMPS2_M70_TYPE4: + case ROM_IBMPS2_M80: + if (card == GFX_BUILTIN) + return &ps1vga_device; + break; - case ROM_IBMPS1_2121:return &ps1_m2121_svga_device; + case ROM_IBMPS1_2121: + return &ps1_m2121_svga_device; - case ROM_IBMPS1_2133_451:return &gd5426_ps1_device; + case ROM_IBMPS1_2133_451: + return &gd5426_ps1_device; - case ROM_T3100E:return &t3100e_device; + case ROM_T3100E: + return &t3100e_device; - case ROM_T1000: - case ROM_T1200:return &t1000_device; + case ROM_T1000: + case ROM_T1200: + return &t1000_device; - case ROM_ELX_PC425X:return &tgui9400cxi_elx_device; + case ROM_ELX_PC425X: + return &tgui9400cxi_elx_device; - case ROM_PB410A:return &ht216_32_pb410a_device; + case ROM_PB410A: + return &ht216_32_pb410a_device; - case ROM_PB570:return &gd5430_pb570_device; + case ROM_PB570: + return &gd5430_pb570_device; - case ROM_PB520R:return &gd5434_pb520r_device; + case ROM_PB520R: + return &gd5434_pb520r_device; - case ROM_CBM_SL386SX25:return &avga2_cbm_sl386sx_device; - } - return video_cards[card]->device; + case ROM_CBM_SL386SX25: + return &avga2_cbm_sl386sx_device; + } + return video_cards[card]->device; } int video_card_has_config(int card, int romset) { - /* Allow builtin cards to have configuration */ - device_t *device = video_card_getdevice(card, romset); + /* Allow builtin cards to have configuration */ + device_t *device = video_card_getdevice(card, romset); - if (!device) { - return 0; - } - return device->config ? 1 : 0; + if (!device) { + return 0; + } + return device->config ? 1 : 0; } int video_card_getid(char *s) { - int c = 0; + int c = 0; - while (video_cards[c] != NULL && video_cards[c]->device) { - if (!strcmp(video_cards[c]->name, s)) - return c; - c++; - } + while (video_cards[c] != NULL && video_cards[c]->device) { + if (!strcmp(video_cards[c]->name, s)) + return c; + c++; + } - if (!strcmp(s, "Built-in video")) - return GFX_BUILTIN; + if (!strcmp(s, "Built-in video")) + return GFX_BUILTIN; - return 0; + return 0; } int video_old_to_new(int card) { - int c = 0; + int c = 0; - if (card == GFX_BUILTIN) - return GFX_BUILTIN; + if (card == GFX_BUILTIN) + return GFX_BUILTIN; - while (video_cards[c] != NULL && video_cards[c]->device) { - if (video_cards[c]->legacy_id == card) - return c; - c++; - } + while (video_cards[c] != NULL && video_cards[c]->device) { + if (video_cards[c]->legacy_id == card) + return c; + c++; + } - return 0; + return 0; } int video_new_to_old(int card) { - if (card == GFX_BUILTIN) - return GFX_BUILTIN; + if (card == GFX_BUILTIN) + return GFX_BUILTIN; - return video_cards[card]->legacy_id; + return video_cards[card]->legacy_id; } char *video_get_internal_name(int card) { - if (card == GFX_BUILTIN) - return "builtin"; + if (card == GFX_BUILTIN) + return "builtin"; - return video_cards[card]->internal_name; + return video_cards[card]->internal_name; } int video_get_video_from_internal_name(char *s) { - int c = 0; + int c = 0; - if (!strcmp(s, "builtin")) - return GFX_BUILTIN; + if (!strcmp(s, "builtin")) + return GFX_BUILTIN; - while (video_cards[c] != NULL) { - if (!strcmp(video_cards[c]->internal_name, s)) - return video_cards[c]->legacy_id; - c++; - } + while (video_cards[c] != NULL) { + if (!strcmp(video_cards[c]->internal_name, s)) + return video_cards[c]->legacy_id; + c++; + } - return 0; + return 0; } int video_is_mda() { - switch (romset) { - case ROM_PC200: - case ROM_PPC512: - if (gfxcard == GFX_BUILTIN) { -/* The chipset here can emulate either CGA or MDA. Find out which */ - return (pc200_is_mda); - } - break; + switch (romset) { + case ROM_PC200: + case ROM_PPC512: + if (gfxcard == GFX_BUILTIN) { + /* The chipset here can emulate either CGA or MDA. Find out which */ + return (pc200_is_mda); + } + break; - case ROM_PC1640: - case ROM_PC2086: - case ROM_PC3086: - case ROM_MEGAPC: - case ROM_ACER386: - if (gfxcard != GFX_BUILTIN) - break; - case ROM_IBMPCJR: - case ROM_TANDY: - case ROM_TANDY1000HX: - case ROM_TANDY1000SL2: - case ROM_PC1512: - case ROM_OLIM24: - case ROM_IBMPS1_2011: - case ROM_IBMPS2_M30_286: - case ROM_IBMPS2_M50: - case ROM_IBMPS2_M55SX: - case ROM_IBMPS2_M70_TYPE3: - case ROM_IBMPS2_M70_TYPE4: - case ROM_IBMPS2_M80: - case ROM_IBMPS1_2121: - case ROM_IBMPS1_2133_451: - case ROM_T3100E: - case ROM_T1000: - case ROM_ELX_PC425X: - case ROM_PB410A: - case ROM_PB570: - case ROM_PB520R: - case ROM_CBM_SL386SX25:return 0; - } - return (video_cards[video_old_to_new(gfxcard)]->flags & VIDEO_FLAG_TYPE_MASK) == VIDEO_FLAG_TYPE_MDA; + case ROM_PC1640: + case ROM_PC2086: + case ROM_PC3086: + case ROM_MEGAPC: + case ROM_ACER386: + if (gfxcard != GFX_BUILTIN) + break; + case ROM_IBMPCJR: + case ROM_TANDY: + case ROM_TANDY1000HX: + case ROM_TANDY1000SL2: + case ROM_PC1512: + case ROM_OLIM24: + case ROM_IBMPS1_2011: + case ROM_IBMPS2_M30_286: + case ROM_IBMPS2_M50: + case ROM_IBMPS2_M55SX: + case ROM_IBMPS2_M70_TYPE3: + case ROM_IBMPS2_M70_TYPE4: + case ROM_IBMPS2_M80: + case ROM_IBMPS1_2121: + case ROM_IBMPS1_2133_451: + case ROM_T3100E: + case ROM_T1000: + case ROM_ELX_PC425X: + case ROM_PB410A: + case ROM_PB570: + case ROM_PB520R: + case ROM_CBM_SL386SX25: + return 0; + } + return (video_cards[video_old_to_new(gfxcard)]->flags & VIDEO_FLAG_TYPE_MASK) == VIDEO_FLAG_TYPE_MDA; } int video_is_cga() { - switch (romset) { - case ROM_PC200: - case ROM_PPC512: - if (gfxcard == GFX_BUILTIN) { -/* The chipset here can emulate either CGA or MDA. Find out which */ - return (!pc200_is_mda); - } - break; + switch (romset) { + case ROM_PC200: + case ROM_PPC512: + if (gfxcard == GFX_BUILTIN) { + /* The chipset here can emulate either CGA or MDA. Find out which */ + return (!pc200_is_mda); + } + break; - case ROM_IBMPCJR: - case ROM_TANDY: - case ROM_TANDY1000HX: - case ROM_TANDY1000SL2: - case ROM_PC1512: - case ROM_OLIM24: - case ROM_T3100E: - case ROM_T1000:return 1; + case ROM_IBMPCJR: + case ROM_TANDY: + case ROM_TANDY1000HX: + case ROM_TANDY1000SL2: + case ROM_PC1512: + case ROM_OLIM24: + case ROM_T3100E: + case ROM_T1000: + return 1; - case ROM_PC1640: - case ROM_PC2086: - case ROM_PC3086: - case ROM_MEGAPC: - case ROM_ACER386: - if (gfxcard != GFX_BUILTIN) - break; - case ROM_IBMPS1_2011: - case ROM_IBMPS2_M30_286: - case ROM_IBMPS2_M50: - case ROM_IBMPS2_M55SX: - case ROM_IBMPS2_M70_TYPE3: - case ROM_IBMPS2_M70_TYPE4: - case ROM_IBMPS2_M80: - case ROM_IBMPS1_2121: - case ROM_IBMPS1_2133_451: - case ROM_ELX_PC425X: - case ROM_PB410A: - case ROM_PB570: - case ROM_PB520R: - case ROM_CBM_SL386SX25:return 0; - } - return (video_cards[video_old_to_new(gfxcard)]->flags & VIDEO_FLAG_TYPE_MASK) == VIDEO_FLAG_TYPE_CGA; + case ROM_PC1640: + case ROM_PC2086: + case ROM_PC3086: + case ROM_MEGAPC: + case ROM_ACER386: + if (gfxcard != GFX_BUILTIN) + break; + case ROM_IBMPS1_2011: + case ROM_IBMPS2_M30_286: + case ROM_IBMPS2_M50: + case ROM_IBMPS2_M55SX: + case ROM_IBMPS2_M70_TYPE3: + case ROM_IBMPS2_M70_TYPE4: + case ROM_IBMPS2_M80: + case ROM_IBMPS1_2121: + case ROM_IBMPS1_2133_451: + case ROM_ELX_PC425X: + case ROM_PB410A: + case ROM_PB570: + case ROM_PB520R: + case ROM_CBM_SL386SX25: + return 0; + } + return (video_cards[video_old_to_new(gfxcard)]->flags & VIDEO_FLAG_TYPE_MASK) == VIDEO_FLAG_TYPE_CGA; } int video_is_ega_vga() { - switch (romset) { - case ROM_IBMPCJR: - case ROM_TANDY: - case ROM_TANDY1000HX: - case ROM_TANDY1000SL2: - case ROM_PC1512: - case ROM_PC200: - case ROM_PPC512: - case ROM_OLIM24: - case ROM_T3100E: - case ROM_T1000:return 0; + switch (romset) { + case ROM_IBMPCJR: + case ROM_TANDY: + case ROM_TANDY1000HX: + case ROM_TANDY1000SL2: + case ROM_PC1512: + case ROM_PC200: + case ROM_PPC512: + case ROM_OLIM24: + case ROM_T3100E: + case ROM_T1000: + return 0; - case ROM_PC1640: - case ROM_PC2086: - case ROM_PC3086: - case ROM_MEGAPC: - case ROM_ACER386: - case ROM_AMA932J: - case ROM_IBMPS1_2011: - case ROM_IBMPS2_M30_286: - case ROM_IBMPS2_M50: - case ROM_IBMPS2_M55SX: - case ROM_IBMPS2_M70_TYPE3: - case ROM_IBMPS2_M70_TYPE4: - case ROM_IBMPS2_M80: - case ROM_IBMPS1_2121: - case ROM_IBMPS1_2133_451: - case ROM_ELX_PC425X: - case ROM_PB410A: - case ROM_PB570: - case ROM_PB520R: - case ROM_CBM_SL386SX25:return 1; - } - return (video_cards[video_old_to_new(gfxcard)]->flags & VIDEO_FLAG_TYPE_MASK) == VIDEO_FLAG_TYPE_SPECIAL; + case ROM_PC1640: + case ROM_PC2086: + case ROM_PC3086: + case ROM_MEGAPC: + case ROM_ACER386: + case ROM_AMA932J: + case ROM_IBMPS1_2011: + case ROM_IBMPS2_M30_286: + case ROM_IBMPS2_M50: + case ROM_IBMPS2_M55SX: + case ROM_IBMPS2_M70_TYPE3: + case ROM_IBMPS2_M70_TYPE4: + case ROM_IBMPS2_M80: + case ROM_IBMPS1_2121: + case ROM_IBMPS1_2133_451: + case ROM_ELX_PC425X: + case ROM_PB410A: + case ROM_PB570: + case ROM_PB520R: + case ROM_CBM_SL386SX25: + return 1; + } + return (video_cards[video_old_to_new(gfxcard)]->flags & VIDEO_FLAG_TYPE_MASK) == VIDEO_FLAG_TYPE_SPECIAL; } int video_fullscreen = 0, video_fullscreen_scale, video_fullscreen_first; @@ -460,7 +550,7 @@ uint8_t edatlookup[4][4]; B = 8 ISA clocks W = 16 ISA clocks L = 32 ISA clocks - + Slow 16-bit - 2mb/sec B = 6 ISA clocks W = 8 ISA clocks @@ -470,17 +560,17 @@ Fast 16-bit - 4mb/sec B = 3 ISA clocks W = 3 ISA clocks L = 6 ISA clocks - + Slow VLB/PCI - 8mb/sec (ish) B = 4 bus clocks W = 8 bus clocks L = 16 bus clocks - + Mid VLB/PCI - B = 4 bus clocks W = 5 bus clocks L = 10 bus clocks - + Fast VLB/PCI - B = 3 bus clocks W = 3 bus clocks @@ -488,155 +578,160 @@ Fast VLB/PCI - */ int video_speed = 0; -int video_timing[7][4] = - { - {VIDEO_ISA, 8, 16, 32}, - {VIDEO_ISA, 6, 8, 16}, - {VIDEO_ISA, 3, 3, 6}, - {VIDEO_BUS, 4, 8, 16}, - {VIDEO_BUS, 4, 5, 10}, - {VIDEO_BUS, 3, 3, 4} - }; +int video_timing[7][4] = {{VIDEO_ISA, 8, 16, 32}, {VIDEO_ISA, 6, 8, 16}, {VIDEO_ISA, 3, 3, 6}, + {VIDEO_BUS, 4, 8, 16}, {VIDEO_BUS, 4, 5, 10}, {VIDEO_BUS, 3, 3, 4}}; void video_updatetiming() { - if (video_speed == -1) { - video_timings_t *timing; - int new_gfxcard = 0; + if (video_speed == -1) { + video_timings_t *timing; + int new_gfxcard = 0; - new_gfxcard = video_old_to_new(gfxcard); - timing = &video_cards[new_gfxcard]->timing; + new_gfxcard = video_old_to_new(gfxcard); + timing = &video_cards[new_gfxcard]->timing; - switch (romset) { - case ROM_IBMPCJR: - case ROM_TANDY: - case ROM_TANDY1000HX: - case ROM_TANDY1000SL2:timing = &timing_dram; - break; + switch (romset) { + case ROM_IBMPCJR: + case ROM_TANDY: + case ROM_TANDY1000HX: + case ROM_TANDY1000SL2: + timing = &timing_dram; + break; - case ROM_PC1512:timing = &timing_pc1512; - break; + case ROM_PC1512: + timing = &timing_pc1512; + break; - case ROM_PC1640: - if (gfxcard == GFX_BUILTIN) - timing = &timing_pc1640; - break; + case ROM_PC1640: + if (gfxcard == GFX_BUILTIN) + timing = &timing_pc1640; + break; - case ROM_PC200: - case ROM_PPC512: - if (gfxcard == GFX_BUILTIN) - timing = &timing_pc200; - break; + case ROM_PC200: + case ROM_PPC512: + if (gfxcard == GFX_BUILTIN) + timing = &timing_pc200; + break; - case ROM_OLIM24:timing = &timing_m24; - break; + case ROM_OLIM24: + timing = &timing_m24; + break; - case ROM_PC2086: - case ROM_PC3086: - if (gfxcard == GFX_BUILTIN) - timing = &timing_pvga1a; - break; + case ROM_PC2086: + case ROM_PC3086: + if (gfxcard == GFX_BUILTIN) + timing = &timing_pvga1a; + break; - case ROM_MEGAPC: - if (gfxcard == GFX_BUILTIN) - timing = &timing_wd90c11; - break; + case ROM_MEGAPC: + if (gfxcard == GFX_BUILTIN) + timing = &timing_wd90c11; + break; - case ROM_SPC4620P: - case ROM_SPC6033P: - if (gfxcard == GFX_BUILTIN) - timing = &timing_spc4620p; - break; + case ROM_SPC4620P: + case ROM_SPC6033P: + if (gfxcard == GFX_BUILTIN) + timing = &timing_spc4620p; + break; - case ROM_ACER386: - if (gfxcard == GFX_BUILTIN) - timing = &timing_oti067; - break; + case ROM_ACER386: + if (gfxcard == GFX_BUILTIN) + timing = &timing_oti067; + break; - case ROM_AMA932J: - if (gfxcard == GFX_BUILTIN) - timing = &timing_oti067; - break; + case ROM_AMA932J: + if (gfxcard == GFX_BUILTIN) + timing = &timing_oti067; + break; - case ROM_IBMPS1_2011: - case ROM_IBMPS2_M30_286:timing = &timing_vga; - break; + case ROM_IBMPS1_2011: + case ROM_IBMPS2_M30_286: + timing = &timing_vga; + break; - case ROM_IBMPS2_M50: - case ROM_IBMPS2_M55SX: - case ROM_IBMPS2_M70_TYPE3: - case ROM_IBMPS2_M70_TYPE4: - case ROM_IBMPS2_M80: - if (gfxcard == GFX_BUILTIN) - timing = &timing_vga; - break; + case ROM_IBMPS2_M50: + case ROM_IBMPS2_M55SX: + case ROM_IBMPS2_M70_TYPE3: + case ROM_IBMPS2_M70_TYPE4: + case ROM_IBMPS2_M80: + if (gfxcard == GFX_BUILTIN) + timing = &timing_vga; + break; - case ROM_IBMPS1_2121:timing = &timing_ps1_svga; - break; + case ROM_IBMPS1_2121: + timing = &timing_ps1_svga; + break; - case ROM_IBMPS1_2133_451:timing = &timing_pb570; - break; + case ROM_IBMPS1_2133_451: + timing = &timing_pb570; + break; - case ROM_T3100E:timing = &timing_t3100e; - break; + case ROM_T3100E: + timing = &timing_t3100e; + break; - case ROM_T1000:timing = &timing_t1000; - break; + case ROM_T1000: + timing = &timing_t1000; + break; - case ROM_ELX_PC425X:timing = &timing_pc425x; - break; + case ROM_ELX_PC425X: + timing = &timing_pc425x; + break; - case ROM_PB410A: - if (gfxcard == GFX_BUILTIN) - timing = &timing_pb410a; - break; + case ROM_PB410A: + if (gfxcard == GFX_BUILTIN) + timing = &timing_pb410a; + break; - case ROM_PB570:timing = &timing_pb570; - break; + case ROM_PB570: + timing = &timing_pb570; + break; - case ROM_PB520R:timing = &timing_pb520r; - break; + case ROM_PB520R: + timing = &timing_pb520r; + break; - case ROM_CBM_SL386SX25:timing = &timing_avga2; - break; - } + case ROM_CBM_SL386SX25: + timing = &timing_avga2; + break; + } - if (timing->type == VIDEO_ISA) { - video_timing_read_b = ISA_CYCLES(timing->read_b); - video_timing_read_w = ISA_CYCLES(timing->read_w); - video_timing_read_l = ISA_CYCLES(timing->read_l); - video_timing_write_b = ISA_CYCLES(timing->write_b); - video_timing_write_w = ISA_CYCLES(timing->write_w); - video_timing_write_l = ISA_CYCLES(timing->write_l); - } else { - video_timing_read_b = (int)(bus_timing * timing->read_b); - video_timing_read_w = (int)(bus_timing * timing->read_w); - video_timing_read_l = (int)(bus_timing * timing->read_l); - video_timing_write_b = (int)(bus_timing * timing->write_b); - video_timing_write_w = (int)(bus_timing * timing->write_w); - video_timing_write_l = (int)(bus_timing * timing->write_l); - } - } else { - if (video_timing[video_speed][0] == VIDEO_ISA) { - video_timing_read_b = ISA_CYCLES(video_timing[video_speed][1]); - video_timing_read_w = ISA_CYCLES(video_timing[video_speed][2]); - video_timing_read_l = ISA_CYCLES(video_timing[video_speed][3]); - video_timing_write_b = ISA_CYCLES(video_timing[video_speed][1]); - video_timing_write_w = ISA_CYCLES(video_timing[video_speed][2]); - video_timing_write_l = ISA_CYCLES(video_timing[video_speed][3]); - } else { - video_timing_read_b = (int)(bus_timing * video_timing[video_speed][1]); - video_timing_read_w = (int)(bus_timing * video_timing[video_speed][2]); - video_timing_read_l = (int)(bus_timing * video_timing[video_speed][3]); - video_timing_write_b = (int)(bus_timing * video_timing[video_speed][1]); - video_timing_write_w = (int)(bus_timing * video_timing[video_speed][2]); - video_timing_write_l = (int)(bus_timing * video_timing[video_speed][3]); - } - } - pclog("Video timing %i %i %i\n", video_timing_write_b, video_timing_write_w, video_timing_write_l); - if (cpu_16bitbus) { - video_timing_read_l = video_timing_read_w * 2; - video_timing_write_l = video_timing_write_w * 2; - } + if (timing->type == VIDEO_ISA) { + video_timing_read_b = ISA_CYCLES(timing->read_b); + video_timing_read_w = ISA_CYCLES(timing->read_w); + video_timing_read_l = ISA_CYCLES(timing->read_l); + video_timing_write_b = ISA_CYCLES(timing->write_b); + video_timing_write_w = ISA_CYCLES(timing->write_w); + video_timing_write_l = ISA_CYCLES(timing->write_l); + } else { + video_timing_read_b = (int)(bus_timing * timing->read_b); + video_timing_read_w = (int)(bus_timing * timing->read_w); + video_timing_read_l = (int)(bus_timing * timing->read_l); + video_timing_write_b = (int)(bus_timing * timing->write_b); + video_timing_write_w = (int)(bus_timing * timing->write_w); + video_timing_write_l = (int)(bus_timing * timing->write_l); + } + } else { + if (video_timing[video_speed][0] == VIDEO_ISA) { + video_timing_read_b = ISA_CYCLES(video_timing[video_speed][1]); + video_timing_read_w = ISA_CYCLES(video_timing[video_speed][2]); + video_timing_read_l = ISA_CYCLES(video_timing[video_speed][3]); + video_timing_write_b = ISA_CYCLES(video_timing[video_speed][1]); + video_timing_write_w = ISA_CYCLES(video_timing[video_speed][2]); + video_timing_write_l = ISA_CYCLES(video_timing[video_speed][3]); + } else { + video_timing_read_b = (int)(bus_timing * video_timing[video_speed][1]); + video_timing_read_w = (int)(bus_timing * video_timing[video_speed][2]); + video_timing_read_l = (int)(bus_timing * video_timing[video_speed][3]); + video_timing_write_b = (int)(bus_timing * video_timing[video_speed][1]); + video_timing_write_w = (int)(bus_timing * video_timing[video_speed][2]); + video_timing_write_l = (int)(bus_timing * video_timing[video_speed][3]); + } + } + pclog("Video timing %i %i %i\n", video_timing_write_b, video_timing_write_w, video_timing_write_l); + if (cpu_16bitbus) { + video_timing_read_l = video_timing_read_w * 2; + video_timing_write_l = video_timing_write_w * 2; + } } int video_timing_read_b, video_timing_read_w, video_timing_read_l; @@ -647,284 +742,301 @@ int video_res_x, video_res_y, video_bpp; void (*video_blit_memtoscreen_func)(int x, int y, int y1, int y2, int w, int h); void video_init() { - pclog("Video_init %i %i\n", romset, gfxcard); + pclog("Video_init %i %i\n", romset, gfxcard); - switch (romset) { - case ROM_IBMPCJR:device_add(&pcjr_video_device); - return; + switch (romset) { + case ROM_IBMPCJR: + device_add(&pcjr_video_device); + return; - case ROM_TANDY: - case ROM_TANDY1000HX:device_add(&tandy_device); - return; + case ROM_TANDY: + case ROM_TANDY1000HX: + device_add(&tandy_device); + return; - case ROM_TANDY1000SL2:device_add(&tandysl_device); - return; + case ROM_TANDY1000SL2: + device_add(&tandysl_device); + return; - case ROM_PC1512:device_add(&pc1512_device); - return; + case ROM_PC1512: + device_add(&pc1512_device); + return; - case ROM_PC1640: - if (gfxcard == GFX_BUILTIN) { - device_add(&pc1640_device); - return; - } - break; + case ROM_PC1640: + if (gfxcard == GFX_BUILTIN) { + device_add(&pc1640_device); + return; + } + break; - case ROM_PC200: - if (gfxcard == GFX_BUILTIN) { - device_add(&pc200_device); - return; - } - break; + case ROM_PC200: + if (gfxcard == GFX_BUILTIN) { + device_add(&pc200_device); + return; + } + break; - case ROM_PPC512: - if (gfxcard == GFX_BUILTIN) { - device_add(&ppc512_device); - return; - } - break; + case ROM_PPC512: + if (gfxcard == GFX_BUILTIN) { + device_add(&ppc512_device); + return; + } + break; - case ROM_OLIM24:device_add(&m24_device); - return; + case ROM_OLIM24: + device_add(&m24_device); + return; - case ROM_PC2086: - if (gfxcard == GFX_BUILTIN) { - device_add(¶dise_pvga1a_pc2086_device); - return; - } - break; + case ROM_PC2086: + if (gfxcard == GFX_BUILTIN) { + device_add(¶dise_pvga1a_pc2086_device); + return; + } + break; - case ROM_PC3086: - if (gfxcard == GFX_BUILTIN) { - device_add(¶dise_pvga1a_pc3086_device); - return; - } - break; + case ROM_PC3086: + if (gfxcard == GFX_BUILTIN) { + device_add(¶dise_pvga1a_pc3086_device); + return; + } + break; - case ROM_MEGAPC: - if (gfxcard == GFX_BUILTIN) { - device_add(¶dise_wd90c11_megapc_device); - return; - } - break; + case ROM_MEGAPC: + if (gfxcard == GFX_BUILTIN) { + device_add(¶dise_wd90c11_megapc_device); + return; + } + break; - case ROM_SPC4620P: - if (gfxcard == GFX_BUILTIN) { - device_add(&ati28800k_spc4620p_device); - return; - } - break; + case ROM_SPC4620P: + if (gfxcard == GFX_BUILTIN) { + device_add(&ati28800k_spc4620p_device); + return; + } + break; - case ROM_SPC6033P: - if (gfxcard == GFX_BUILTIN) { - device_add(&ati28800k_spc6033p_device); - return; - } - break; + case ROM_SPC6033P: + if (gfxcard == GFX_BUILTIN) { + device_add(&ati28800k_spc6033p_device); + return; + } + break; - case ROM_ACER386:device_add(&oti067_acer386_device); - if (gfxcard != GFX_BUILTIN) { - svga_set_override(svga_get_pri(), 1); - break; - } - return; + case ROM_ACER386: + device_add(&oti067_acer386_device); + if (gfxcard != GFX_BUILTIN) { + svga_set_override(svga_get_pri(), 1); + break; + } + return; - case ROM_AMA932J:device_add(&oti067_ama932j_device); - return; + case ROM_AMA932J: + device_add(&oti067_ama932j_device); + return; - case ROM_IBMPS1_2011: - case ROM_IBMPS2_M30_286:device_add(&ps1vga_device); - return; + case ROM_IBMPS1_2011: + case ROM_IBMPS2_M30_286: + device_add(&ps1vga_device); + return; - case ROM_IBMPS2_M50: - case ROM_IBMPS2_M55SX: - case ROM_IBMPS2_M70_TYPE3: - case ROM_IBMPS2_M70_TYPE4: - case ROM_IBMPS2_M80:device_add(&ps1vga_device); - if (gfxcard == GFX_BUILTIN) - return; - break; + case ROM_IBMPS2_M50: + case ROM_IBMPS2_M55SX: + case ROM_IBMPS2_M70_TYPE3: + case ROM_IBMPS2_M70_TYPE4: + case ROM_IBMPS2_M80: + device_add(&ps1vga_device); + if (gfxcard == GFX_BUILTIN) + return; + break; - case ROM_IBMPS1_2121:device_add(&ps1_m2121_svga_device); - return; + case ROM_IBMPS1_2121: + device_add(&ps1_m2121_svga_device); + return; - case ROM_IBMPS1_2133_451:device_add(&gd5426_ps1_device); - return; + case ROM_IBMPS1_2133_451: + device_add(&gd5426_ps1_device); + return; - case ROM_T3100E:device_add(&t3100e_device); - return; + case ROM_T3100E: + device_add(&t3100e_device); + return; - case ROM_T1000: - case ROM_T1200:device_add(&t1000_device); - return; + case ROM_T1000: + case ROM_T1200: + device_add(&t1000_device); + return; - case ROM_ELX_PC425X:device_add(&tgui9400cxi_elx_device); - return; + case ROM_ELX_PC425X: + device_add(&tgui9400cxi_elx_device); + return; - case ROM_PB410A:device_add(&ht216_32_pb410a_device); - if (gfxcard != GFX_BUILTIN) { - svga_set_override(svga_get_pri(), 1); - break; - } - return; + case ROM_PB410A: + device_add(&ht216_32_pb410a_device); + if (gfxcard != GFX_BUILTIN) { + svga_set_override(svga_get_pri(), 1); + break; + } + return; - case ROM_PB570:device_add(&gd5430_pb570_device); - if (gfxcard != GFX_BUILTIN) { - svga_set_override(svga_get_pri(), 1); - break; - } - return; + case ROM_PB570: + device_add(&gd5430_pb570_device); + if (gfxcard != GFX_BUILTIN) { + svga_set_override(svga_get_pri(), 1); + break; + } + return; - case ROM_PB520R:device_add(&gd5434_pb520r_device); - if (gfxcard != GFX_BUILTIN) { - svga_set_override(svga_get_pri(), 1); - break; - } - return; + case ROM_PB520R: + device_add(&gd5434_pb520r_device); + if (gfxcard != GFX_BUILTIN) { + svga_set_override(svga_get_pri(), 1); + break; + } + return; - case ROM_CBM_SL386SX25:device_add(&avga2_cbm_sl386sx_device); - return; - } - device_add(video_cards[video_old_to_new(gfxcard)]->device); + case ROM_CBM_SL386SX25: + device_add(&avga2_cbm_sl386sx_device); + return; + } + device_add(video_cards[video_old_to_new(gfxcard)]->device); } BITMAP *buffer32; uint8_t fontdat[2048][8]; uint8_t fontdatm[2048][16]; -uint8_t fontdatw[512][32]; /* Wyse700 font */ -uint8_t fontdat8x12[256][16]; /* MDSI Genius font */ +uint8_t fontdatw[512][32]; /* Wyse700 font */ +uint8_t fontdat8x12[256][16]; /* MDSI Genius font */ uint8_t fontdat12x18[256][36]; /* IM1024 font */ -uint8_t fontdatksc5601[16384][32]; /* Korean KSC-5601 font */ +uint8_t fontdatksc5601[16384][32]; /* Korean KSC-5601 font */ uint8_t fontdatksc5601_user[192][32]; /* Korean KSC-5601 user defined font */ int xsize = 1, ysize = 1; void loadfont(char *s, fontformat_t format) { - FILE *f = romfopen(s, "rb"); - int c, d; + FILE *f = romfopen(s, "rb"); + int c, d; - pclog("loadfont %i %s %p\n", format, s, f); - if (!f) { - return; - } - switch (format) { - case FONT_MDA: /* MDA */ - for (c = 0; c < 256; c++) { - for (d = 0; d < 8; d++) { - fontdatm[c][d] = getc(f); - } - } - for (c = 0; c < 256; c++) { - for (d = 0; d < 8; d++) { - fontdatm[c][d + 8] = getc(f); - } - } - fseek(f, 4096 + 2048, SEEK_SET); - for (c = 0; c < 256; c++) { - for (d = 0; d < 8; d++) { - fontdat[c][d] = getc(f); - } - } - break; - case FONT_PC200: /* PC200 */ - for (d = 0; d < 4; d++) /* There are 4 fonts in the ROM */ - { - for (c = 0; c < 256; c++) /* 8x14 MDA in 8x16 cell */ - { - fread(&fontdatm[256 * d + c], 1, 16, f); - } - for (c = 0; c < 256; c++) /* 8x8 CGA in 8x16 cell */ - { - fread(fontdat[256 * d + c], 1, 8, f); - fseek(f, 8, SEEK_CUR); - } - } - break; - default: - case FONT_CGA: /* CGA */ - for (c = 0; c < 2048; c++) /* Allow up to 2048 chars */ - { - for (d = 0; d < 8; d++) { - fontdat[c][d] = getc(f); - } - } - break; - case FONT_WY700: /* Wyse 700 */ - for (c = 0; c < 512; c++) { - for (d = 0; d < 32; d++) { - fontdatw[c][d] = getc(f); - } - } - break; - case FONT_MDSI: /* MDSI Genius */ - for (c = 0; c < 256; c++) { - for (d = 0; d < 16; d++) { - fontdat8x12[c][d] = getc(f); - } - } - break; - case FONT_T3100E: /* Toshiba 3100e */ - for (d = 0; d < 2048; d += 512) /* Four languages... */ - { - for (c = d; c < d + 256; c++) { - fread(&fontdatm[c][8], 1, 8, f); - } - for (c = d + 256; c < d + 512; c++) { - fread(&fontdatm[c][8], 1, 8, f); - } - for (c = d; c < d + 256; c++) { - fread(&fontdatm[c][0], 1, 8, f); - } - for (c = d + 256; c < d + 512; c++) { - fread(&fontdatm[c][0], 1, 8, f); - } - fseek(f, 4096, SEEK_CUR); /* Skip blank section */ - for (c = d; c < d + 256; c++) { - fread(&fontdat[c][0], 1, 8, f); - } - for (c = d + 256; c < d + 512; c++) { - fread(&fontdat[c][0], 1, 8, f); - } - } - break; - case FONT_KSC5601: /* Korean KSC-5601 */ - for (c = 0; c < 16384; c++) { - for (d = 0; d < 32; d++) { - fontdatksc5601[c][d] = getc(f); - } - } - break; - case FONT_SIGMA400: /* Sigma Color 400 */ - /* The first 4k of the character ROM holds an 8x8 font */ - for (c = 0; c < 256; c++) { - fread(&fontdat[c][0], 1, 8, f); - fseek(f, 8, SEEK_CUR); - } - /* The second 4k holds an 8x16 font */ - for (c = 0; c < 256; c++) { - fread(&fontdatm[c][0], 1, 16, f); - } - break; - case FONT_IM1024: /* Image Manager 1024 native font */ - for (c = 0; c < 256; c++) { - fread(&fontdat12x18[c][0], 1, 36, f); - } - break; - - } - fclose(f); + pclog("loadfont %i %s %p\n", format, s, f); + if (!f) { + return; + } + switch (format) { + case FONT_MDA: /* MDA */ + for (c = 0; c < 256; c++) { + for (d = 0; d < 8; d++) { + fontdatm[c][d] = getc(f); + } + } + for (c = 0; c < 256; c++) { + for (d = 0; d < 8; d++) { + fontdatm[c][d + 8] = getc(f); + } + } + fseek(f, 4096 + 2048, SEEK_SET); + for (c = 0; c < 256; c++) { + for (d = 0; d < 8; d++) { + fontdat[c][d] = getc(f); + } + } + break; + case FONT_PC200: /* PC200 */ + for (d = 0; d < 4; d++) /* There are 4 fonts in the ROM */ + { + for (c = 0; c < 256; c++) /* 8x14 MDA in 8x16 cell */ + { + fread(&fontdatm[256 * d + c], 1, 16, f); + } + for (c = 0; c < 256; c++) /* 8x8 CGA in 8x16 cell */ + { + fread(fontdat[256 * d + c], 1, 8, f); + fseek(f, 8, SEEK_CUR); + } + } + break; + default: + case FONT_CGA: /* CGA */ + for (c = 0; c < 2048; c++) /* Allow up to 2048 chars */ + { + for (d = 0; d < 8; d++) { + fontdat[c][d] = getc(f); + } + } + break; + case FONT_WY700: /* Wyse 700 */ + for (c = 0; c < 512; c++) { + for (d = 0; d < 32; d++) { + fontdatw[c][d] = getc(f); + } + } + break; + case FONT_MDSI: /* MDSI Genius */ + for (c = 0; c < 256; c++) { + for (d = 0; d < 16; d++) { + fontdat8x12[c][d] = getc(f); + } + } + break; + case FONT_T3100E: /* Toshiba 3100e */ + for (d = 0; d < 2048; d += 512) /* Four languages... */ + { + for (c = d; c < d + 256; c++) { + fread(&fontdatm[c][8], 1, 8, f); + } + for (c = d + 256; c < d + 512; c++) { + fread(&fontdatm[c][8], 1, 8, f); + } + for (c = d; c < d + 256; c++) { + fread(&fontdatm[c][0], 1, 8, f); + } + for (c = d + 256; c < d + 512; c++) { + fread(&fontdatm[c][0], 1, 8, f); + } + fseek(f, 4096, SEEK_CUR); /* Skip blank section */ + for (c = d; c < d + 256; c++) { + fread(&fontdat[c][0], 1, 8, f); + } + for (c = d + 256; c < d + 512; c++) { + fread(&fontdat[c][0], 1, 8, f); + } + } + break; + case FONT_KSC5601: /* Korean KSC-5601 */ + for (c = 0; c < 16384; c++) { + for (d = 0; d < 32; d++) { + fontdatksc5601[c][d] = getc(f); + } + } + break; + case FONT_SIGMA400: /* Sigma Color 400 */ + /* The first 4k of the character ROM holds an 8x8 font */ + for (c = 0; c < 256; c++) { + fread(&fontdat[c][0], 1, 8, f); + fseek(f, 8, SEEK_CUR); + } + /* The second 4k holds an 8x16 font */ + for (c = 0; c < 256; c++) { + fread(&fontdatm[c][0], 1, 16, f); + } + break; + case FONT_IM1024: /* Image Manager 1024 native font */ + for (c = 0; c < 256; c++) { + fread(&fontdat12x18[c][0], 1, 36, f); + } + break; + } + fclose(f); } static struct { - int x, y, y1, y2, w, h; - int busy; - int buffer_in_use; + int x, y, y1, y2, w, h; + int busy; + int buffer_in_use; - thread_t *blit_thread; - event_t *wake_blit_thread; - event_t *blit_complete; - event_t *buffer_not_in_use; + thread_t *blit_thread; + event_t *wake_blit_thread; + event_t *blit_complete; + event_t *buffer_not_in_use; } blit_data; static void blit_thread(void *param); @@ -932,290 +1044,291 @@ static void blit_thread(void *param); uint32_t cgapal[16]; void initvideo() { - int c, d, e; + int c, d, e; - buffer32 = create_bitmap(2048, 2048); + buffer32 = create_bitmap(2048, 2048); - for (c = 0; c < 256; c++) { - e = c; - for (d = 0; d < 8; d++) { - rotatevga[d][c] = e; - e = (e >> 1) | ((e & 1) ? 0x80 : 0); - } - } - for (c = 0; c < 4; c++) { - for (d = 0; d < 4; d++) { - edatlookup[c][d] = 0; - if (c & 1) - edatlookup[c][d] |= 1; - if (d & 1) - edatlookup[c][d] |= 2; - if (c & 2) - edatlookup[c][d] |= 0x10; - if (d & 2) - edatlookup[c][d] |= 0x20; -// printf("Edat %i,%i now %02X\n",c,d,edatlookup[c][d]); - } - } + for (c = 0; c < 256; c++) { + e = c; + for (d = 0; d < 8; d++) { + rotatevga[d][c] = e; + e = (e >> 1) | ((e & 1) ? 0x80 : 0); + } + } + for (c = 0; c < 4; c++) { + for (d = 0; d < 4; d++) { + edatlookup[c][d] = 0; + if (c & 1) + edatlookup[c][d] |= 1; + if (d & 1) + edatlookup[c][d] |= 2; + if (c & 2) + edatlookup[c][d] |= 0x10; + if (d & 2) + edatlookup[c][d] |= 0x20; + // printf("Edat %i,%i now %02X\n",c,d,edatlookup[c][d]); + } + } - video_15to32 = malloc(4 * 65536); - for (c = 0; c < 65536; c++) - video_15to32[c] = ((c & 31) << 3) | (((c >> 5) & 31) << 11) | (((c >> 10) & 31) << 19); + video_15to32 = malloc(4 * 65536); + for (c = 0; c < 65536; c++) + video_15to32[c] = ((c & 31) << 3) | (((c >> 5) & 31) << 11) | (((c >> 10) & 31) << 19); - video_16to32 = malloc(4 * 65536); - for (c = 0; c < 65536; c++) - video_16to32[c] = ((c & 31) << 3) | (((c >> 5) & 63) << 10) | (((c >> 11) & 31) << 19); + video_16to32 = malloc(4 * 65536); + for (c = 0; c < 65536; c++) + video_16to32[c] = ((c & 31) << 3) | (((c >> 5) & 63) << 10) | (((c >> 11) & 31) << 19); - cgapal_rebuild(DISPLAY_RGB, 0); + cgapal_rebuild(DISPLAY_RGB, 0); - blit_data.wake_blit_thread = thread_create_event(); - blit_data.blit_complete = thread_create_event(); - blit_data.buffer_not_in_use = thread_create_event(); - blit_data.blit_thread = thread_create(blit_thread, NULL); + blit_data.wake_blit_thread = thread_create_event(); + blit_data.blit_complete = thread_create_event(); + blit_data.buffer_not_in_use = thread_create_event(); + blit_data.blit_thread = thread_create(blit_thread, NULL); } void closevideo() { - thread_kill(blit_data.blit_thread); - thread_destroy_event(blit_data.buffer_not_in_use); - thread_destroy_event(blit_data.blit_complete); - thread_destroy_event(blit_data.wake_blit_thread); + thread_kill(blit_data.blit_thread); + thread_destroy_event(blit_data.buffer_not_in_use); + thread_destroy_event(blit_data.blit_complete); + thread_destroy_event(blit_data.wake_blit_thread); - free(video_15to32); - free(video_16to32); - destroy_bitmap(buffer32); + free(video_15to32); + free(video_16to32); + destroy_bitmap(buffer32); } static void blit_thread(void *param) { - while (1) { - thread_wait_event(blit_data.wake_blit_thread, -1); - thread_reset_event(blit_data.wake_blit_thread); + while (1) { + thread_wait_event(blit_data.wake_blit_thread, -1); + thread_reset_event(blit_data.wake_blit_thread); - video_blit_memtoscreen_func(blit_data.x, blit_data.y, blit_data.y1, blit_data.y2, blit_data.w, blit_data.h); + video_blit_memtoscreen_func(blit_data.x, blit_data.y, blit_data.y1, blit_data.y2, blit_data.w, blit_data.h); - blit_data.busy = 0; - thread_set_event(blit_data.blit_complete); - } + blit_data.busy = 0; + thread_set_event(blit_data.blit_complete); + } } void video_blit_complete() { - blit_data.buffer_in_use = 0; - thread_set_event(blit_data.buffer_not_in_use); + blit_data.buffer_in_use = 0; + thread_set_event(blit_data.buffer_not_in_use); } void video_wait_for_blit() { - while (blit_data.busy) - thread_wait_event(blit_data.blit_complete, 1); - thread_reset_event(blit_data.blit_complete); + while (blit_data.busy) + thread_wait_event(blit_data.blit_complete, 1); + thread_reset_event(blit_data.blit_complete); } void video_wait_for_buffer() { - while (blit_data.buffer_in_use) - thread_wait_event(blit_data.buffer_not_in_use, 1); - thread_reset_event(blit_data.buffer_not_in_use); + while (blit_data.buffer_in_use) + thread_wait_event(blit_data.buffer_not_in_use, 1); + thread_reset_event(blit_data.buffer_not_in_use); } void video_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) { - video_frames++; - if (h <= 0) - return; - video_wait_for_blit(); - blit_data.busy = 1; - blit_data.buffer_in_use = 1; - blit_data.x = x; - blit_data.y = y; - blit_data.y1 = y1; - blit_data.y2 = y2; - blit_data.w = w; - blit_data.h = h; - thread_set_event(blit_data.wake_blit_thread); + video_frames++; + if (h <= 0) + return; + video_wait_for_blit(); + blit_data.busy = 1; + blit_data.buffer_in_use = 1; + blit_data.x = x; + blit_data.y = y; + blit_data.y1 = y1; + blit_data.y2 = y2; + blit_data.w = w; + blit_data.h = h; + thread_set_event(blit_data.wake_blit_thread); } void cgapal_rebuild(int display_type, int contrast) { - switch (display_type) { - case DISPLAY_GREEN: - if (contrast) { - cgapal[0x0] = makecol(0x00, 0x00, 0x00); - cgapal[0x1] = makecol(0x00, 0x34, 0x0c); - cgapal[0x2] = makecol(0x04, 0x5d, 0x14); - cgapal[0x3] = makecol(0x04, 0x69, 0x18); - cgapal[0x4] = makecol(0x08, 0xa2, 0x24); - cgapal[0x5] = makecol(0x08, 0xb2, 0x28); - cgapal[0x6] = makecol(0x0c, 0xe7, 0x34); - cgapal[0x7] = makecol(0x0c, 0xf3, 0x38); - cgapal[0x8] = makecol(0x00, 0x1c, 0x04); - cgapal[0x9] = makecol(0x04, 0x4d, 0x10); - cgapal[0xa] = makecol(0x04, 0x7d, 0x1c); - cgapal[0xb] = makecol(0x04, 0x8e, 0x20); - cgapal[0xc] = makecol(0x08, 0xc7, 0x2c); - cgapal[0xd] = makecol(0x08, 0xd7, 0x30); - cgapal[0xe] = makecol(0x14, 0xff, 0x45); - cgapal[0xf] = makecol(0x34, 0xff, 0x5d); - } else { - cgapal[0x0] = makecol(0x00, 0x00, 0x00); - cgapal[0x1] = makecol(0x00, 0x34, 0x0c); - cgapal[0x2] = makecol(0x04, 0x55, 0x14); - cgapal[0x3] = makecol(0x04, 0x5d, 0x14); - cgapal[0x4] = makecol(0x04, 0x86, 0x20); - cgapal[0x5] = makecol(0x04, 0x92, 0x20); - cgapal[0x6] = makecol(0x08, 0xba, 0x2c); - cgapal[0x7] = makecol(0x08, 0xc7, 0x2c); - cgapal[0x8] = makecol(0x04, 0x8a, 0x20); - cgapal[0x9] = makecol(0x08, 0xa2, 0x24); - cgapal[0xa] = makecol(0x08, 0xc3, 0x2c); - cgapal[0xb] = makecol(0x08, 0xcb, 0x30); - cgapal[0xc] = makecol(0x0c, 0xe7, 0x34); - cgapal[0xd] = makecol(0x0c, 0xef, 0x38); - cgapal[0xe] = makecol(0x24, 0xff, 0x51); - cgapal[0xf] = makecol(0x34, 0xff, 0x5d); - } - break; - case DISPLAY_AMBER: - if (contrast) { - cgapal[0x0] = makecol(0x00, 0x00, 0x00); - cgapal[0x1] = makecol(0x55, 0x14, 0x00); - cgapal[0x2] = makecol(0x82, 0x2c, 0x00); - cgapal[0x3] = makecol(0x92, 0x34, 0x00); - cgapal[0x4] = makecol(0xcf, 0x61, 0x00); - cgapal[0x5] = makecol(0xdf, 0x6d, 0x00); - cgapal[0x6] = makecol(0xff, 0x9a, 0x04); - cgapal[0x7] = makecol(0xff, 0xae, 0x18); - cgapal[0x8] = makecol(0x2c, 0x08, 0x00); - cgapal[0x9] = makecol(0x6d, 0x20, 0x00); - cgapal[0xa] = makecol(0xa6, 0x45, 0x00); - cgapal[0xb] = makecol(0xba, 0x51, 0x00); - cgapal[0xc] = makecol(0xef, 0x79, 0x00); - cgapal[0xd] = makecol(0xfb, 0x86, 0x00); - cgapal[0xe] = makecol(0xff, 0xcb, 0x28); - cgapal[0xf] = makecol(0xff, 0xe3, 0x34); - } else { - cgapal[0x0] = makecol(0x00, 0x00, 0x00); - cgapal[0x1] = makecol(0x55, 0x14, 0x00); - cgapal[0x2] = makecol(0x79, 0x24, 0x00); - cgapal[0x3] = makecol(0x86, 0x2c, 0x00); - cgapal[0x4] = makecol(0xae, 0x49, 0x00); - cgapal[0x5] = makecol(0xbe, 0x55, 0x00); - cgapal[0x6] = makecol(0xe3, 0x71, 0x00); - cgapal[0x7] = makecol(0xef, 0x79, 0x00); - cgapal[0x8] = makecol(0xb2, 0x4d, 0x00); - cgapal[0x9] = makecol(0xcb, 0x5d, 0x00); - cgapal[0xa] = makecol(0xeb, 0x79, 0x00); - cgapal[0xb] = makecol(0xf3, 0x7d, 0x00); - cgapal[0xc] = makecol(0xff, 0x9e, 0x04); - cgapal[0xd] = makecol(0xff, 0xaa, 0x10); - cgapal[0xe] = makecol(0xff, 0xdb, 0x30); - cgapal[0xf] = makecol(0xff, 0xe3, 0x34); - } - break; - case DISPLAY_WHITE: - if (contrast) { - cgapal[0x0] = makecol(0x00, 0x00, 0x00); - cgapal[0x1] = makecol(0x37, 0x3d, 0x40); - cgapal[0x2] = makecol(0x55, 0x5c, 0x5f); - cgapal[0x3] = makecol(0x61, 0x67, 0x6b); - cgapal[0x4] = makecol(0x8f, 0x95, 0x95); - cgapal[0x5] = makecol(0x9b, 0xa0, 0x9f); - cgapal[0x6] = makecol(0xcc, 0xcf, 0xc8); - cgapal[0x7] = makecol(0xdf, 0xde, 0xd4); - cgapal[0x8] = makecol(0x24, 0x27, 0x29); - cgapal[0x9] = makecol(0x42, 0x48, 0x4c); - cgapal[0xa] = makecol(0x70, 0x76, 0x78); - cgapal[0xb] = makecol(0x81, 0x87, 0x87); - cgapal[0xc] = makecol(0xaf, 0xb3, 0xb0); - cgapal[0xd] = makecol(0xbb, 0xbf, 0xba); - cgapal[0xe] = makecol(0xef, 0xed, 0xdf); - cgapal[0xf] = makecol(0xff, 0xfd, 0xed); - } else { - cgapal[0x0] = makecol(0x00, 0x00, 0x00); - cgapal[0x1] = makecol(0x37, 0x3d, 0x40); - cgapal[0x2] = makecol(0x4a, 0x50, 0x54); - cgapal[0x3] = makecol(0x55, 0x5c, 0x5f); - cgapal[0x4] = makecol(0x78, 0x7e, 0x80); - cgapal[0x5] = makecol(0x81, 0x87, 0x87); - cgapal[0x6] = makecol(0xa3, 0xa7, 0xa6); - cgapal[0x7] = makecol(0xaf, 0xb3, 0xb0); - cgapal[0x8] = makecol(0x7a, 0x81, 0x83); - cgapal[0x9] = makecol(0x8c, 0x92, 0x92); - cgapal[0xa] = makecol(0xac, 0xb0, 0xad); - cgapal[0xb] = makecol(0xb3, 0xb7, 0xb4); - cgapal[0xc] = makecol(0xd1, 0xd3, 0xcb); - cgapal[0xd] = makecol(0xd9, 0xdb, 0xd2); - cgapal[0xe] = makecol(0xf7, 0xf5, 0xe7); - cgapal[0xf] = makecol(0xff, 0xfd, 0xed); - } - break; + switch (display_type) { + case DISPLAY_GREEN: + if (contrast) { + cgapal[0x0] = makecol(0x00, 0x00, 0x00); + cgapal[0x1] = makecol(0x00, 0x34, 0x0c); + cgapal[0x2] = makecol(0x04, 0x5d, 0x14); + cgapal[0x3] = makecol(0x04, 0x69, 0x18); + cgapal[0x4] = makecol(0x08, 0xa2, 0x24); + cgapal[0x5] = makecol(0x08, 0xb2, 0x28); + cgapal[0x6] = makecol(0x0c, 0xe7, 0x34); + cgapal[0x7] = makecol(0x0c, 0xf3, 0x38); + cgapal[0x8] = makecol(0x00, 0x1c, 0x04); + cgapal[0x9] = makecol(0x04, 0x4d, 0x10); + cgapal[0xa] = makecol(0x04, 0x7d, 0x1c); + cgapal[0xb] = makecol(0x04, 0x8e, 0x20); + cgapal[0xc] = makecol(0x08, 0xc7, 0x2c); + cgapal[0xd] = makecol(0x08, 0xd7, 0x30); + cgapal[0xe] = makecol(0x14, 0xff, 0x45); + cgapal[0xf] = makecol(0x34, 0xff, 0x5d); + } else { + cgapal[0x0] = makecol(0x00, 0x00, 0x00); + cgapal[0x1] = makecol(0x00, 0x34, 0x0c); + cgapal[0x2] = makecol(0x04, 0x55, 0x14); + cgapal[0x3] = makecol(0x04, 0x5d, 0x14); + cgapal[0x4] = makecol(0x04, 0x86, 0x20); + cgapal[0x5] = makecol(0x04, 0x92, 0x20); + cgapal[0x6] = makecol(0x08, 0xba, 0x2c); + cgapal[0x7] = makecol(0x08, 0xc7, 0x2c); + cgapal[0x8] = makecol(0x04, 0x8a, 0x20); + cgapal[0x9] = makecol(0x08, 0xa2, 0x24); + cgapal[0xa] = makecol(0x08, 0xc3, 0x2c); + cgapal[0xb] = makecol(0x08, 0xcb, 0x30); + cgapal[0xc] = makecol(0x0c, 0xe7, 0x34); + cgapal[0xd] = makecol(0x0c, 0xef, 0x38); + cgapal[0xe] = makecol(0x24, 0xff, 0x51); + cgapal[0xf] = makecol(0x34, 0xff, 0x5d); + } + break; + case DISPLAY_AMBER: + if (contrast) { + cgapal[0x0] = makecol(0x00, 0x00, 0x00); + cgapal[0x1] = makecol(0x55, 0x14, 0x00); + cgapal[0x2] = makecol(0x82, 0x2c, 0x00); + cgapal[0x3] = makecol(0x92, 0x34, 0x00); + cgapal[0x4] = makecol(0xcf, 0x61, 0x00); + cgapal[0x5] = makecol(0xdf, 0x6d, 0x00); + cgapal[0x6] = makecol(0xff, 0x9a, 0x04); + cgapal[0x7] = makecol(0xff, 0xae, 0x18); + cgapal[0x8] = makecol(0x2c, 0x08, 0x00); + cgapal[0x9] = makecol(0x6d, 0x20, 0x00); + cgapal[0xa] = makecol(0xa6, 0x45, 0x00); + cgapal[0xb] = makecol(0xba, 0x51, 0x00); + cgapal[0xc] = makecol(0xef, 0x79, 0x00); + cgapal[0xd] = makecol(0xfb, 0x86, 0x00); + cgapal[0xe] = makecol(0xff, 0xcb, 0x28); + cgapal[0xf] = makecol(0xff, 0xe3, 0x34); + } else { + cgapal[0x0] = makecol(0x00, 0x00, 0x00); + cgapal[0x1] = makecol(0x55, 0x14, 0x00); + cgapal[0x2] = makecol(0x79, 0x24, 0x00); + cgapal[0x3] = makecol(0x86, 0x2c, 0x00); + cgapal[0x4] = makecol(0xae, 0x49, 0x00); + cgapal[0x5] = makecol(0xbe, 0x55, 0x00); + cgapal[0x6] = makecol(0xe3, 0x71, 0x00); + cgapal[0x7] = makecol(0xef, 0x79, 0x00); + cgapal[0x8] = makecol(0xb2, 0x4d, 0x00); + cgapal[0x9] = makecol(0xcb, 0x5d, 0x00); + cgapal[0xa] = makecol(0xeb, 0x79, 0x00); + cgapal[0xb] = makecol(0xf3, 0x7d, 0x00); + cgapal[0xc] = makecol(0xff, 0x9e, 0x04); + cgapal[0xd] = makecol(0xff, 0xaa, 0x10); + cgapal[0xe] = makecol(0xff, 0xdb, 0x30); + cgapal[0xf] = makecol(0xff, 0xe3, 0x34); + } + break; + case DISPLAY_WHITE: + if (contrast) { + cgapal[0x0] = makecol(0x00, 0x00, 0x00); + cgapal[0x1] = makecol(0x37, 0x3d, 0x40); + cgapal[0x2] = makecol(0x55, 0x5c, 0x5f); + cgapal[0x3] = makecol(0x61, 0x67, 0x6b); + cgapal[0x4] = makecol(0x8f, 0x95, 0x95); + cgapal[0x5] = makecol(0x9b, 0xa0, 0x9f); + cgapal[0x6] = makecol(0xcc, 0xcf, 0xc8); + cgapal[0x7] = makecol(0xdf, 0xde, 0xd4); + cgapal[0x8] = makecol(0x24, 0x27, 0x29); + cgapal[0x9] = makecol(0x42, 0x48, 0x4c); + cgapal[0xa] = makecol(0x70, 0x76, 0x78); + cgapal[0xb] = makecol(0x81, 0x87, 0x87); + cgapal[0xc] = makecol(0xaf, 0xb3, 0xb0); + cgapal[0xd] = makecol(0xbb, 0xbf, 0xba); + cgapal[0xe] = makecol(0xef, 0xed, 0xdf); + cgapal[0xf] = makecol(0xff, 0xfd, 0xed); + } else { + cgapal[0x0] = makecol(0x00, 0x00, 0x00); + cgapal[0x1] = makecol(0x37, 0x3d, 0x40); + cgapal[0x2] = makecol(0x4a, 0x50, 0x54); + cgapal[0x3] = makecol(0x55, 0x5c, 0x5f); + cgapal[0x4] = makecol(0x78, 0x7e, 0x80); + cgapal[0x5] = makecol(0x81, 0x87, 0x87); + cgapal[0x6] = makecol(0xa3, 0xa7, 0xa6); + cgapal[0x7] = makecol(0xaf, 0xb3, 0xb0); + cgapal[0x8] = makecol(0x7a, 0x81, 0x83); + cgapal[0x9] = makecol(0x8c, 0x92, 0x92); + cgapal[0xa] = makecol(0xac, 0xb0, 0xad); + cgapal[0xb] = makecol(0xb3, 0xb7, 0xb4); + cgapal[0xc] = makecol(0xd1, 0xd3, 0xcb); + cgapal[0xd] = makecol(0xd9, 0xdb, 0xd2); + cgapal[0xe] = makecol(0xf7, 0xf5, 0xe7); + cgapal[0xf] = makecol(0xff, 0xfd, 0xed); + } + break; - default:cgapal[0x0] = makecol(0x00, 0x00, 0x00); - cgapal[0x1] = makecol(0x00, 0x00, 0xaa); - cgapal[0x2] = makecol(0x00, 0xaa, 0x00); - cgapal[0x3] = makecol(0x00, 0xaa, 0xaa); - cgapal[0x4] = makecol(0xaa, 0x00, 0x00); - cgapal[0x5] = makecol(0xaa, 0x00, 0xaa); - if (display_type == DISPLAY_RGB_NO_BROWN) { - cgapal[0x6] = makecol(0xaa, 0xaa, 0x00); - } else { - cgapal[0x6] = makecol(0xaa, 0x55, 0x00); - } - cgapal[0x7] = makecol(0xaa, 0xaa, 0xaa); - cgapal[0x8] = makecol(0x55, 0x55, 0x55); - cgapal[0x9] = makecol(0x55, 0x55, 0xff); - cgapal[0xa] = makecol(0x55, 0xff, 0x55); - cgapal[0xb] = makecol(0x55, 0xff, 0xff); - cgapal[0xc] = makecol(0xff, 0x55, 0x55); - cgapal[0xd] = makecol(0xff, 0x55, 0xff); - cgapal[0xe] = makecol(0xff, 0xff, 0x55); - cgapal[0xf] = makecol(0xff, 0xff, 0xff); - break; - } + default: + cgapal[0x0] = makecol(0x00, 0x00, 0x00); + cgapal[0x1] = makecol(0x00, 0x00, 0xaa); + cgapal[0x2] = makecol(0x00, 0xaa, 0x00); + cgapal[0x3] = makecol(0x00, 0xaa, 0xaa); + cgapal[0x4] = makecol(0xaa, 0x00, 0x00); + cgapal[0x5] = makecol(0xaa, 0x00, 0xaa); + if (display_type == DISPLAY_RGB_NO_BROWN) { + cgapal[0x6] = makecol(0xaa, 0xaa, 0x00); + } else { + cgapal[0x6] = makecol(0xaa, 0x55, 0x00); + } + cgapal[0x7] = makecol(0xaa, 0xaa, 0xaa); + cgapal[0x8] = makecol(0x55, 0x55, 0x55); + cgapal[0x9] = makecol(0x55, 0x55, 0xff); + cgapal[0xa] = makecol(0x55, 0xff, 0x55); + cgapal[0xb] = makecol(0x55, 0xff, 0xff); + cgapal[0xc] = makecol(0xff, 0x55, 0x55); + cgapal[0xd] = makecol(0xff, 0x55, 0xff); + cgapal[0xe] = makecol(0xff, 0xff, 0x55); + cgapal[0xf] = makecol(0xff, 0xff, 0xff); + break; + } } void video_init_builtin() { - pcem_add_video(&v_banshee); - pcem_add_video(&v_v3_2000); - pcem_add_video(&v_v3_3000); - pcem_add_video(&v_avga2); - pcem_add_video(&v_mach64gx); - pcem_add_video(&v_mach64vt2); - pcem_add_video(&v_egawonder800); - pcem_add_video(&v_ati28800k); - pcem_add_video(&v_ati28800); - pcem_add_video(&v_ati18800); - pcem_add_video(&v_cga); - pcem_add_video(&v_cl_gd5428); - pcem_add_video(&v_cl_gd5429); - pcem_add_video(&v_cl_gd5430); - pcem_add_video(&v_cl_gd5434); - pcem_add_video(&v_compaq_cga_device); - pcem_add_video(&v_cl_banshee); - pcem_add_video(&v_stealth32); - pcem_add_video(&v_stealth3d_2000); - pcem_add_video(&v_ega); - pcem_add_video(&v_hercules); - pcem_add_video(&v_incolor); - pcem_add_video(&v_ibm1mbsvga); - pcem_add_video(&v_im1024); - pcem_add_video(&v_kasan16); - pcem_add_video(&v_mystique); - pcem_add_video(&v_millennium); - pcem_add_video(&v_mda); - pcem_add_video(&v_genius); - pcem_add_video(&v_n9_9fx); - pcem_add_video(&v_oti037); - pcem_add_video(&v_oti067); - pcem_add_video(&v_olivetti_go481); - pcem_add_video(&v_bahamas64); + pcem_add_video(&v_banshee); + pcem_add_video(&v_v3_2000); + pcem_add_video(&v_v3_3000); + pcem_add_video(&v_avga2); + pcem_add_video(&v_mach64gx); + pcem_add_video(&v_mach64vt2); + pcem_add_video(&v_egawonder800); + pcem_add_video(&v_ati28800k); + pcem_add_video(&v_ati28800); + pcem_add_video(&v_ati18800); + pcem_add_video(&v_cga); + pcem_add_video(&v_cl_gd5428); + pcem_add_video(&v_cl_gd5429); + pcem_add_video(&v_cl_gd5430); + pcem_add_video(&v_cl_gd5434); + pcem_add_video(&v_compaq_cga_device); + pcem_add_video(&v_cl_banshee); + pcem_add_video(&v_stealth32); + pcem_add_video(&v_stealth3d_2000); + pcem_add_video(&v_ega); + pcem_add_video(&v_hercules); + pcem_add_video(&v_incolor); + pcem_add_video(&v_ibm1mbsvga); + pcem_add_video(&v_im1024); + pcem_add_video(&v_kasan16); + pcem_add_video(&v_mystique); + pcem_add_video(&v_millennium); + pcem_add_video(&v_mda); + pcem_add_video(&v_genius); + pcem_add_video(&v_n9_9fx); + pcem_add_video(&v_oti037); + pcem_add_video(&v_oti067); + pcem_add_video(&v_olivetti_go481); + pcem_add_video(&v_bahamas64); #ifdef USE_EXPERIMENTAL_PGC - pcem_add_video(&v_pgc); + pcem_add_video(&v_pgc); #endif - pcem_add_video(&v_px_trio32); - pcem_add_video(&v_px_trio64); - pcem_add_video(&v_plantronics); - pcem_add_video(&v_virge375); - pcem_add_video(&v_sigma400); - pcem_add_video(&v_tvga8900d); - pcem_add_video(&v_tvga9000b); - pcem_add_video(&v_tgui9400cxi); - pcem_add_video(&v_tgui9440); - pcem_add_video(&v_tgkorvga); - pcem_add_video(&v_et4000ax); - pcem_add_video(&v_vga); - pcem_add_video(&v_wy700); + pcem_add_video(&v_px_trio32); + pcem_add_video(&v_px_trio64); + pcem_add_video(&v_plantronics); + pcem_add_video(&v_virge375); + pcem_add_video(&v_sigma400); + pcem_add_video(&v_tvga8900d); + pcem_add_video(&v_tvga9000b); + pcem_add_video(&v_tgui9400cxi); + pcem_add_video(&v_tgui9440); + pcem_add_video(&v_tgkorvga); + pcem_add_video(&v_et4000ax); + pcem_add_video(&v_vga); + pcem_add_video(&v_wy700); } diff --git a/src/wx-ui/wx-app.cc b/src/wx-ui/wx-app.cc index f7fa6c14..685f1d2e 100644 --- a/src/wx-ui/wx-app.cc +++ b/src/wx-ui/wx-app.cc @@ -13,8 +13,7 @@ #undef BITMAP #endif -extern "C" -{ +extern "C" { int wx_load_config(void *); int wx_start(void *); int wx_stop(void *); @@ -42,200 +41,186 @@ wxDEFINE_EVENT(WX_POPUP_MENU_EVENT, PopupMenuEvent); wxDEFINE_EVENT(WX_WIN_SEND_MESSAGE_EVENT, WinSendMessageEvent); #endif -wxBEGIN_EVENT_TABLE(Frame, wxFrame) -wxEND_EVENT_TABLE() +wxBEGIN_EVENT_TABLE(Frame, wxFrame) wxEND_EVENT_TABLE() -wxIMPLEMENT_APP_NO_MAIN(App); + wxIMPLEMENT_APP_NO_MAIN(App); -App::App() { - this->frame = NULL; -} +App::App() { this->frame = NULL; } bool App::OnInit() { - wxImage::AddHandler(new wxPNGHandler); - wxXmlResource::Get()->InitAllHandlers(); -// if (!wxXmlResource::Get()->Load("src/pc.xrc")) -// { -// std::cout << "Could not load resource file" << std::endl; -// return false; -// } - InitXmlResource(); + wxImage::AddHandler(new wxPNGHandler); + wxXmlResource::Get()->InitAllHandlers(); + // if (!wxXmlResource::Get()->Load("src/pc.xrc")) + // { + // std::cout << "Could not load resource file" << std::endl; + // return false; + // } + InitXmlResource(); - frame = new Frame(this, "null frame", wxPoint(500, 500), - wxSize(100, 100)); - frame->Start(); - return true; + frame = new Frame(this, "null frame", wxPoint(500, 500), wxSize(100, 100)); + frame->Start(); + return true; } -int App::OnRun() { - return wxApp::OnRun(); -} +int App::OnRun() { return wxApp::OnRun(); } #include -Frame::Frame(App *app, const wxString &title, const wxPoint &pos, - const wxSize &size) : - wxFrame(NULL, wxID_ANY, title, pos, size, 0)//wxDEFAULT_FRAME_STYLE & ~(wxRESIZE_BORDER)) +Frame::Frame(App *app, const wxString &title, const wxPoint &pos, const wxSize &size) + : wxFrame(NULL, wxID_ANY, title, pos, size, 0) // wxDEFAULT_FRAME_STYLE & ~(wxRESIZE_BORDER)) { - this->closing = false; - this->menu = wxXmlResource::Get()->LoadMenu(wxT("main_menu")); + this->closing = false; + this->menu = wxXmlResource::Get()->LoadMenu(wxT("main_menu")); - Bind(wxEVT_CLOSE_WINDOW, &Frame::OnClose, this); - Bind(wxEVT_MENU, &Frame::OnCommand, this); - Bind(wxEVT_TOOL, &Frame::OnCommand, this); - Bind(WX_SHOW_WINDOW_EVENT, &Frame::OnShowWindowEvent, this); - Bind(WX_POPUP_MENU_EVENT, &Frame::OnPopupMenuEvent, this); - Bind(WX_EXIT_EVENT, &Frame::OnExitEvent, this); - Bind(WX_EXIT_COMPLETE_EVENT, &Frame::OnExitCompleteEvent, this); - Bind(WX_STOP_EMULATION_EVENT, &Frame::OnStopEmulationEvent, this); - Bind(WX_STOP_EMULATION_NOW_EVENT, &Frame::OnStopEmulationNowEvent, this); - Bind(WX_CALLBACK_EVENT, &Frame::OnCallbackEvent, this); + Bind(wxEVT_CLOSE_WINDOW, &Frame::OnClose, this); + Bind(wxEVT_MENU, &Frame::OnCommand, this); + Bind(wxEVT_TOOL, &Frame::OnCommand, this); + Bind(WX_SHOW_WINDOW_EVENT, &Frame::OnShowWindowEvent, this); + Bind(WX_POPUP_MENU_EVENT, &Frame::OnPopupMenuEvent, this); + Bind(WX_EXIT_EVENT, &Frame::OnExitEvent, this); + Bind(WX_EXIT_COMPLETE_EVENT, &Frame::OnExitCompleteEvent, this); + Bind(WX_STOP_EMULATION_EVENT, &Frame::OnStopEmulationEvent, this); + Bind(WX_STOP_EMULATION_NOW_EVENT, &Frame::OnStopEmulationNowEvent, this); + Bind(WX_CALLBACK_EVENT, &Frame::OnCallbackEvent, this); #ifdef _WIN32 - Bind(WX_WIN_SEND_MESSAGE_EVENT, &Frame::OnWinSendMessageEvent, this); + Bind(WX_WIN_SEND_MESSAGE_EVENT, &Frame::OnWinSendMessageEvent, this); #endif - CenterOnScreen(); + CenterOnScreen(); } void Frame::Start() { - if (wx_start(this)) - ShowConfigSelection(); - else - Quit(0); + if (wx_start(this)) + ShowConfigSelection(); + else + Quit(0); } void Frame::ShowConfigSelection() { - if (wx_load_config(this)) - start_emulation(this); - else - Quit(1); + if (wx_load_config(this)) + start_emulation(this); + else + Quit(1); } void Frame::OnCallbackEvent(CallbackEvent &event) { - WX_CALLBACK callback = event.GetCallback(); - callback(event.GetData()); + WX_CALLBACK callback = event.GetCallback(); + callback(event.GetData()); } void Frame::OnStopEmulationEvent(wxCommandEvent &event) { - if (emulation_state != EMULATION_STOPPED) { - pause_emulation(); - int ret = wxID_OK; - pclog_flush(); - if (confirm_on_stop_emulation) { - wxDialog dlg; - wxXmlResource::Get()->LoadDialog(&dlg, this, "ConfirmRememberDlg"); - dlg.FindWindow("IDC_CONFIRM_LABEL")->SetLabel("Stop emulation?"); - dlg.FindWindow("IDC_CONFIRM_REMEMBER")->SetLabel("Do not ask again"); - dlg.Fit(); - ret = dlg.ShowModal(); - if (ret == wxID_OK) - confirm_on_stop_emulation = !((wxCheckBox *)dlg.FindWindow("IDC_CONFIRM_REMEMBER"))->IsChecked(); - } + if (emulation_state != EMULATION_STOPPED) { + pause_emulation(); + int ret = wxID_OK; + pclog_flush(); + if (confirm_on_stop_emulation) { + wxDialog dlg; + wxXmlResource::Get()->LoadDialog(&dlg, this, "ConfirmRememberDlg"); + dlg.FindWindow("IDC_CONFIRM_LABEL")->SetLabel("Stop emulation?"); + dlg.FindWindow("IDC_CONFIRM_REMEMBER")->SetLabel("Do not ask again"); + dlg.Fit(); + ret = dlg.ShowModal(); + if (ret == wxID_OK) + confirm_on_stop_emulation = !((wxCheckBox *)dlg.FindWindow("IDC_CONFIRM_REMEMBER"))->IsChecked(); + } - if (ret == wxID_OK) { - stop_emulation(); - if (!config_override) - ShowConfigSelection(); - else - Quit(1); - } else - resume_emulation(); - } + if (ret == wxID_OK) { + stop_emulation(); + if (!config_override) + ShowConfigSelection(); + else + Quit(1); + } else + resume_emulation(); + } } void Frame::OnStopEmulationNowEvent(wxCommandEvent &event) { - stop_emulation(); - pclog_flush(); - if (!config_override) - ShowConfigSelection(); - else - Quit(1); + stop_emulation(); + pclog_flush(); + if (!config_override) + ShowConfigSelection(); + else + Quit(1); } void Frame::OnShowWindowEvent(wxCommandEvent &event) { - wxWindow *window = (wxWindow *)event.GetEventObject(); - int shown = window->IsShown(); - int value = event.GetInt(); - if (value < 0) - window->Show(!shown); - else - window->Show(value > 0); - if (!shown) - window->Refresh(); + wxWindow *window = (wxWindow *)event.GetEventObject(); + int shown = window->IsShown(); + int value = event.GetInt(); + if (value < 0) + window->Show(!shown); + else + window->Show(value > 0); + if (!shown) + window->Refresh(); } void Frame::OnPopupMenuEvent(PopupMenuEvent &event) { - wxWindow *window = event.GetWindow(); - wxMenu *menu = event.GetMenu(); - int *x = event.GetX(); - int *y = event.GetY(); + wxWindow *window = event.GetWindow(); + wxMenu *menu = event.GetMenu(); + int *x = event.GetX(); + int *y = event.GetY(); - if (x && y) - window->PopupMenu(menu, *x, *y); - else - window->PopupMenu(menu); + if (x && y) + window->PopupMenu(menu, *x, *y); + else + window->PopupMenu(menu); } -void Frame::OnCommand(wxCommandEvent &event) { - wx_handle_command(this, event.GetId(), event.IsChecked()); -} +void Frame::OnCommand(wxCommandEvent &event) { wx_handle_command(this, event.GetId(), event.IsChecked()); } void Frame::OnClose(wxCloseEvent &event) { - pclog_end(); - wx_exit(this, 0); + pclog_end(); + wx_exit(this, 0); } -wxMenu *Frame::GetMenu() { - return menu; -} +wxMenu *Frame::GetMenu() { return menu; } /* Exit */ void Frame::Quit(bool stop_emulator) { - if (closing) - return; - closing = true; - if (stop_emulator) { - if (!wx_stop(this)) { - // cancel quit - closing = false; - return; - } - } - pclog_end(); - Destroy(); + if (closing) + return; + closing = true; + if (stop_emulator) { + if (!wx_stop(this)) { + // cancel quit + closing = false; + return; + } + } + pclog_end(); + Destroy(); } void Frame::OnExitEvent(wxCommandEvent &event) { - if (closing) - return; - closing = true; - CExitThread *exitThread = new CExitThread(this); - exitThread->Run(); + if (closing) + return; + closing = true; + CExitThread *exitThread = new CExitThread(this); + exitThread->Run(); } void Frame::OnExitCompleteEvent(wxCommandEvent &event) { - if (event.GetInt()) { - pclog_end(); - Destroy(); - } - else - closing = false; + if (event.GetInt()) { + pclog_end(); + Destroy(); + } else + closing = false; } -CExitThread::CExitThread(Frame *frame) { - this->frame = frame; -} +CExitThread::CExitThread(Frame *frame) { this->frame = frame; } wxThread::ExitCode CExitThread::Entry() { - wxCommandEvent *event = new wxCommandEvent(WX_EXIT_COMPLETE_EVENT, wxID_ANY); - event->SetInt(wx_stop(frame)); - wxQueueEvent(frame, event); - return 0; + wxCommandEvent *event = new wxCommandEvent(WX_EXIT_COMPLETE_EVENT, wxID_ANY); + event->SetInt(wx_stop(frame)); + wxQueueEvent(frame, event); + return 0; } #ifdef _WIN32 void Frame::OnWinSendMessageEvent(WinSendMessageEvent &event) { - SendMessage((HWND)event.GetHWND(), event.GetMessage(), event.GetWParam(), event.GetLParam()); + SendMessage((HWND)event.GetHWND(), event.GetMessage(), event.GetWParam(), event.GetLParam()); } #endif diff --git a/src/wx-ui/wx-common.c b/src/wx-ui/wx-common.c index 8a3af985..b1f4e933 100644 --- a/src/wx-ui/wx-common.c +++ b/src/wx-ui/wx-common.c @@ -2,31 +2,32 @@ #include "config.h" void wx_loadconfig() { - show_machine_info = config_get_int(CFG_GLOBAL, "wxWidgets", "show_machine_info", show_machine_info); - show_disc_activity = config_get_int(CFG_GLOBAL, "wxWidgets", "show_disc_activity", show_disc_activity); - show_speed_history = config_get_int(CFG_GLOBAL, "wxWidgets", "show_speed_history", show_speed_history); - show_mount_paths = config_get_int(CFG_GLOBAL, "wxWidgets", "show_mount_paths", show_mount_paths); - show_status = config_get_int(CFG_GLOBAL, "wxWidgets", "show_status", show_status); - show_machine_on_start = config_get_int(CFG_GLOBAL, "wxWidgets", "show_machine_on_start", show_machine_on_start); + show_machine_info = config_get_int(CFG_GLOBAL, "wxWidgets", "show_machine_info", show_machine_info); + show_disc_activity = config_get_int(CFG_GLOBAL, "wxWidgets", "show_disc_activity", show_disc_activity); + show_speed_history = config_get_int(CFG_GLOBAL, "wxWidgets", "show_speed_history", show_speed_history); + show_mount_paths = config_get_int(CFG_GLOBAL, "wxWidgets", "show_mount_paths", show_mount_paths); + show_status = config_get_int(CFG_GLOBAL, "wxWidgets", "show_status", show_status); + show_machine_on_start = config_get_int(CFG_GLOBAL, "wxWidgets", "show_machine_on_start", show_machine_on_start); - confirm_on_reset_machine = config_get_int(CFG_GLOBAL, "wxWidgets", "confirm_on_reset_machine", confirm_on_reset_machine); - confirm_on_stop_emulation = config_get_int(CFG_GLOBAL, "wxWidgets", "confirm_on_stop_emulation", confirm_on_stop_emulation); + confirm_on_reset_machine = config_get_int(CFG_GLOBAL, "wxWidgets", "confirm_on_reset_machine", confirm_on_reset_machine); + confirm_on_stop_emulation = + config_get_int(CFG_GLOBAL, "wxWidgets", "confirm_on_stop_emulation", confirm_on_stop_emulation); - wx_window_x = config_get_int(CFG_GLOBAL, "wxWidgets", "window_x", wx_window_x); - wx_window_y = config_get_int(CFG_GLOBAL, "wxWidgets", "window_y", wx_window_y); + wx_window_x = config_get_int(CFG_GLOBAL, "wxWidgets", "window_x", wx_window_x); + wx_window_y = config_get_int(CFG_GLOBAL, "wxWidgets", "window_y", wx_window_y); } void wx_saveconfig() { - config_set_int(CFG_GLOBAL, "wxWidgets", "show_machine_info", show_machine_info); - config_set_int(CFG_GLOBAL, "wxWidgets", "show_disc_activity", show_disc_activity); - config_set_int(CFG_GLOBAL, "wxWidgets", "show_speed_history", show_speed_history); - config_set_int(CFG_GLOBAL, "wxWidgets", "show_mount_paths", show_mount_paths); - config_set_int(CFG_GLOBAL, "wxWidgets", "show_status", show_status); - config_set_int(CFG_GLOBAL, "wxWidgets", "show_machine_on_start", show_machine_on_start); + config_set_int(CFG_GLOBAL, "wxWidgets", "show_machine_info", show_machine_info); + config_set_int(CFG_GLOBAL, "wxWidgets", "show_disc_activity", show_disc_activity); + config_set_int(CFG_GLOBAL, "wxWidgets", "show_speed_history", show_speed_history); + config_set_int(CFG_GLOBAL, "wxWidgets", "show_mount_paths", show_mount_paths); + config_set_int(CFG_GLOBAL, "wxWidgets", "show_status", show_status); + config_set_int(CFG_GLOBAL, "wxWidgets", "show_machine_on_start", show_machine_on_start); - config_set_int(CFG_GLOBAL, "wxWidgets", "confirm_on_reset_machine", confirm_on_reset_machine); - config_set_int(CFG_GLOBAL, "wxWidgets", "confirm_on_stop_emulation", confirm_on_stop_emulation); + config_set_int(CFG_GLOBAL, "wxWidgets", "confirm_on_reset_machine", confirm_on_reset_machine); + config_set_int(CFG_GLOBAL, "wxWidgets", "confirm_on_stop_emulation", confirm_on_stop_emulation); - config_set_int(CFG_GLOBAL, "wxWidgets", "window_x", wx_window_x); - config_set_int(CFG_GLOBAL, "wxWidgets", "window_y", wx_window_y); + config_set_int(CFG_GLOBAL, "wxWidgets", "window_x", wx_window_x); + config_set_int(CFG_GLOBAL, "wxWidgets", "window_y", wx_window_y); } diff --git a/src/wx-ui/wx-config-eventbinder.cc b/src/wx-ui/wx-config-eventbinder.cc index 98e2edec..1179d47a 100644 --- a/src/wx-ui/wx-config-eventbinder.cc +++ b/src/wx-ui/wx-config-eventbinder.cc @@ -6,46 +6,44 @@ class WXConfigEventBinder : public wxWindow { private: - void (*selectedPageCallback)(void *hdlg, int selectedPage); - wxWindow *hdlg; + void (*selectedPageCallback)(void *hdlg, int selectedPage); + wxWindow *hdlg; public: - void selectedPageCallbackExecute(wxListEvent &event) { - long item = -1; - wxListCtrl *control = (wxListCtrl *)this->hdlg->FindWindow(XRCID("IDC_PAGESELECTION")); + void selectedPageCallbackExecute(wxListEvent &event) { + long item = -1; + wxListCtrl *control = (wxListCtrl *)this->hdlg->FindWindow(XRCID("IDC_PAGESELECTION")); - for (;;) { - item = control->GetNextItem(item, - wxLIST_NEXT_ALL, - wxLIST_STATE_SELECTED); - if (item == -1) - break; - if (this->selectedPageCallback != NULL) - this->selectedPageCallback(this->hdlg, item); - } - } + for (;;) { + item = control->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + if (item == -1) + break; + if (this->selectedPageCallback != NULL) + this->selectedPageCallback(this->hdlg, item); + } + } - WXConfigEventBinder(wxWindow *hdlg, void (*selectedPageCallback)(void *hdlg, int selectedPage)) { - this->selectedPageCallback = selectedPageCallback; - this->hdlg = hdlg; + WXConfigEventBinder(wxWindow *hdlg, void (*selectedPageCallback)(void *hdlg, int selectedPage)) { + this->selectedPageCallback = selectedPageCallback; + this->hdlg = hdlg; - wxListCtrl *control = (wxListCtrl *)this->hdlg->FindWindow(XRCID("IDC_PAGESELECTION")); - control->SetMaxSize(wxSize(250, -1)); - control->SetMinSize(wxSize(250, -1)); - control->Connect(wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler(WXConfigEventBinder::selectedPageCallbackExecute), NULL, this); - } + wxListCtrl *control = (wxListCtrl *)this->hdlg->FindWindow(XRCID("IDC_PAGESELECTION")); + control->SetMaxSize(wxSize(250, -1)); + control->SetMinSize(wxSize(250, -1)); + control->Connect(wxEVT_COMMAND_LIST_ITEM_SELECTED, + wxListEventHandler(WXConfigEventBinder::selectedPageCallbackExecute), NULL, this); + } - ~WXConfigEventBinder() { - wxListCtrl *control = (wxListCtrl *)this->hdlg->FindWindow(XRCID("IDC_PAGESELECTION")); - control->Disconnect(wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler(WXConfigEventBinder::selectedPageCallbackExecute), NULL, this); - } + ~WXConfigEventBinder() { + wxListCtrl *control = (wxListCtrl *)this->hdlg->FindWindow(XRCID("IDC_PAGESELECTION")); + control->Disconnect(wxEVT_COMMAND_LIST_ITEM_SELECTED, + wxListEventHandler(WXConfigEventBinder::selectedPageCallbackExecute), NULL, this); + } }; void *wx_config_eventbinder(void *hdlg, void (*selectedPageCallback)(void *hdlg, int selectedPage)) { - WXConfigEventBinder *binder = new WXConfigEventBinder((wxWindow *)hdlg, selectedPageCallback); - return (void *)binder; + WXConfigEventBinder *binder = new WXConfigEventBinder((wxWindow *)hdlg, selectedPageCallback); + return (void *)binder; } -void wx_config_destroyeventbinder(void *eventBinder) { - delete (WXConfigEventBinder *)eventBinder; -} \ No newline at end of file +void wx_config_destroyeventbinder(void *eventBinder) { delete (WXConfigEventBinder *)eventBinder; } \ No newline at end of file diff --git a/src/wx-ui/wx-config.c b/src/wx-ui/wx-config.c index 99c43031..74e0e411 100644 --- a/src/wx-ui/wx-config.c +++ b/src/wx-ui/wx-config.c @@ -28,8 +28,7 @@ extern int pause; extern int is486; -static int romstolist[ROM_MAX], listtomodel[ROM_MAX], romstomodel[ROM_MAX], - modeltolist[ROM_MAX]; +static int romstolist[ROM_MAX], listtomodel[ROM_MAX], romstomodel[ROM_MAX], modeltolist[ROM_MAX]; static int settings_sound_to_list[20], settings_list_to_sound[20]; static int settings_mouse_to_list[20], settings_list_to_mouse[20]; #ifdef USE_NETWORKING @@ -62,16 +61,13 @@ static int hdd_controller_selected_has_config(void *hdlg); static device_t *hdd_controller_selected_get_device(void *hdlg); static int mouse_valid(int type, int model) { - if (((type & MOUSE_TYPE_IF_MASK) == MOUSE_TYPE_PS2) - && !(models[model]->flags & MODEL_PS2)) - return 0; - if (((type & MOUSE_TYPE_IF_MASK) == MOUSE_TYPE_AMSTRAD) - && !(models[model]->flags & MODEL_AMSTRAD)) - return 0; - if (((type & MOUSE_TYPE_IF_MASK) == MOUSE_TYPE_OLIM24) - && !(models[model]->flags & MODEL_OLIM24)) - return 0; - return 1; + if (((type & MOUSE_TYPE_IF_MASK) == MOUSE_TYPE_PS2) && !(models[model]->flags & MODEL_PS2)) + return 0; + if (((type & MOUSE_TYPE_IF_MASK) == MOUSE_TYPE_AMSTRAD) && !(models[model]->flags & MODEL_AMSTRAD)) + return 0; + if (((type & MOUSE_TYPE_IF_MASK) == MOUSE_TYPE_OLIM24) && !(models[model]->flags & MODEL_OLIM24)) + return 0; + return 1; } /*static int mpu401_available(int sound_card) @@ -84,1401 +80,1366 @@ static int mouse_valid(int type, int model) { }*/ static void recalc_fpu_list(void *hdlg, int model, int manu, int cpu, int fpu) { - void *h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOFPU")); - int c = 0; + void *h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOFPU")); + int c = 0; - wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); - wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); + wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); + wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); - while (1) { - const char *name = fpu_get_name_from_index(model, manu, cpu, c); - int type = fpu_get_type_from_index(model, manu, cpu, c); - if (!name) - break; + while (1) { + const char *name = fpu_get_name_from_index(model, manu, cpu, c); + int type = fpu_get_type_from_index(model, manu, cpu, c); + if (!name) + break; - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)name); - if (!c || type == fpu) - wx_sendmessage(h, WX_CB_SETCURSEL, c, 0); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)name); + if (!c || type == fpu) + wx_sendmessage(h, WX_CB_SETCURSEL, c, 0); - c++; - } - if (c > 1) - wx_enablewindow(h, TRUE); - else - wx_enablewindow(h, FALSE); + c++; + } + if (c > 1) + wx_enablewindow(h, TRUE); + else + wx_enablewindow(h, FALSE); } static void recalc_vid_list(void *hdlg, int model, int force_builtin_video) { - void *h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOVID")); - int c = 0, d = 0; - int found_card = 0; - int cur_gfxcard = gfxcard; - int romset = model_getromset_from_model(model); + void *h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOVID")); + int c = 0, d = 0; + int found_card = 0; + int cur_gfxcard = gfxcard; + int romset = model_getromset_from_model(model); - wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); - wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); + wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); + wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); - if (model_has_fixed_gfx(model)) { - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Built-in video"); - wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); - wx_enablewindow(h, FALSE); - h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGUREVID")); - wx_enablewindow(h, video_card_has_config(gfxcard, romset)); - return; - } + if (model_has_fixed_gfx(model)) { + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "Built-in video"); + wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); + wx_enablewindow(h, FALSE); + h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGUREVID")); + wx_enablewindow(h, video_card_has_config(gfxcard, romset)); + return; + } - if (model_has_optional_gfx(model)) { - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Built-in video"); - if (gfxcard == GFX_BUILTIN || force_builtin_video) { - wx_sendmessage(h, WX_CB_SETCURSEL, d, 0); - found_card = 1; - cur_gfxcard = GFX_BUILTIN; - } - d++; - } + if (model_has_optional_gfx(model)) { + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "Built-in video"); + if (gfxcard == GFX_BUILTIN || force_builtin_video) { + wx_sendmessage(h, WX_CB_SETCURSEL, d, 0); + found_card = 1; + cur_gfxcard = GFX_BUILTIN; + } + d++; + } - if (cur_gfxcard == GFX_BUILTIN && !model_has_fixed_gfx(model) && !model_has_optional_gfx(model)) - cur_gfxcard = 0; + if (cur_gfxcard == GFX_BUILTIN && !model_has_fixed_gfx(model) && !model_has_optional_gfx(model)) + cur_gfxcard = 0; - while (1) { - char *s = video_card_getname(c); + while (1) { + char *s = video_card_getname(c); - if (!s[0]) - break; + if (!s[0]) + break; - if (video_card_available(c) && gfx_present[video_new_to_old(c)] && - ((models[model]->flags & MODEL_PCI) || !(video_card_getdevice(c, romset)->flags & DEVICE_PCI)) && - ((models[model]->flags & MODEL_MCA) || !(video_card_getdevice(c, romset)->flags & DEVICE_MCA)) && - (!(models[model]->flags & MODEL_MCA) || (video_card_getdevice(c, romset)->flags & DEVICE_MCA)) - ) { - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); - if (video_new_to_old(c) == gfxcard && !found_card) { - wx_sendmessage(h, WX_CB_SETCURSEL, d, 0); - found_card = 1; - } + if (video_card_available(c) && gfx_present[video_new_to_old(c)] && + ((models[model]->flags & MODEL_PCI) || !(video_card_getdevice(c, romset)->flags & DEVICE_PCI)) && + ((models[model]->flags & MODEL_MCA) || !(video_card_getdevice(c, romset)->flags & DEVICE_MCA)) && + (!(models[model]->flags & MODEL_MCA) || (video_card_getdevice(c, romset)->flags & DEVICE_MCA))) { + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); + if (video_new_to_old(c) == gfxcard && !found_card) { + wx_sendmessage(h, WX_CB_SETCURSEL, d, 0); + found_card = 1; + } - d++; - } + d++; + } - c++; - } - if (!found_card) - wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); - wx_enablewindow(h, TRUE); + c++; + } + if (!found_card) + wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); + wx_enablewindow(h, TRUE); - h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGUREVID")); - if (video_card_has_config(video_old_to_new(cur_gfxcard), romset)) - wx_enablewindow(h, TRUE); - else - wx_enablewindow(h, FALSE); + h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGUREVID")); + if (video_card_has_config(video_old_to_new(cur_gfxcard), romset)) + wx_enablewindow(h, TRUE); + else + wx_enablewindow(h, FALSE); - h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKVOODOO")); - wx_enablewindow(h, (models[model]->flags & MODEL_PCI) ? TRUE : FALSE); - h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGUREVOODOO")); - wx_enablewindow(h, (models[model]->flags & MODEL_PCI) ? TRUE : FALSE); + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKVOODOO")); + wx_enablewindow(h, (models[model]->flags & MODEL_PCI) ? TRUE : FALSE); + h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGUREVOODOO")); + wx_enablewindow(h, (models[model]->flags & MODEL_PCI) ? TRUE : FALSE); } static void recalc_snd_list(void *hdlg, int model) { - void *h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOSND")); - int c = 0, d = 0; + void *h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOSND")); + int c = 0, d = 0; - wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); + wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); - while (1) { - char *s = sound_card_getname(c); + while (1) { + char *s = sound_card_getname(c); - if (!s[0]) - break; + if (!s[0]) + break; - settings_sound_to_list[c] = d; + settings_sound_to_list[c] = d; - if (sound_card_available(c)) { - device_t *sound_dev = sound_card_getdevice(c); + if (sound_card_available(c)) { + device_t *sound_dev = sound_card_getdevice(c); - if (!sound_dev || (sound_dev->flags & DEVICE_MCA) == (models[model]->flags & MODEL_MCA)) { - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); - settings_list_to_sound[d] = c; - d++; - } - } + if (!sound_dev || (sound_dev->flags & DEVICE_MCA) == (models[model]->flags & MODEL_MCA)) { + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); + settings_list_to_sound[d] = c; + d++; + } + } - c++; - } - wx_sendmessage(h, WX_CB_SETCURSEL, settings_sound_to_list[sound_card_current], 0); + c++; + } + wx_sendmessage(h, WX_CB_SETCURSEL, settings_sound_to_list[sound_card_current], 0); } static void recalc_hdd_list(void *hdlg, int model, int use_selected_hdd, int force_ide) { - void *h; - char *s; - int valid = 0; - char old_name[16]; - int c, d; - int hdd_type; + void *h; + char *s; + int valid = 0; + char old_name[16]; + int c, d; + int hdd_type; - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOHDD")); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOHDD")); - if (force_ide) - strcpy(old_name, "ide"); - else if (use_selected_hdd) { - c = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + if (force_ide) + strcpy(old_name, "ide"); + else if (use_selected_hdd) { + c = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - if (c != -1 && hdd_names[c]) - strncpy(old_name, hdd_names[c], sizeof(old_name) - 1); - else { - if (models[model]->flags & MODEL_HAS_IDE) - strcpy(old_name, "none"); - else - strcpy(old_name, "ide"); - } - } else - strncpy(old_name, hdd_controller_name, sizeof(old_name) - 1); + if (c != -1 && hdd_names[c]) + strncpy(old_name, hdd_names[c], sizeof(old_name) - 1); + else { + if (models[model]->flags & MODEL_HAS_IDE) + strcpy(old_name, "none"); + else + strcpy(old_name, "ide"); + } + } else + strncpy(old_name, hdd_controller_name, sizeof(old_name) - 1); - wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); - c = d = 0; - while (1) { - s = hdd_controller_get_name(c); - if (s[0] == 0) - break; - if ((((hdd_controller_get_flags(c) & DEVICE_AT) && !(models[model]->flags & MODEL_AT)) || - (hdd_controller_get_flags(c) & DEVICE_MCA) != (models[model]->flags & MODEL_MCA)) && c) { - c++; - continue; - } - if ((((hdd_controller_get_flags(c) & DEVICE_PS1) && models[model]->id != ROM_IBMPS1_2011) || - (!(hdd_controller_get_flags(c) & DEVICE_PS1) && models[model]->id == ROM_IBMPS1_2011)) && c) { - c++; - continue; - } - if (!hdd_controller_available(c)) { - c++; - continue; - } - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); - hdd_names[d] = hdd_controller_get_internal_name(c); + wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); + c = d = 0; + while (1) { + s = hdd_controller_get_name(c); + if (s[0] == 0) + break; + if ((((hdd_controller_get_flags(c) & DEVICE_AT) && !(models[model]->flags & MODEL_AT)) || + (hdd_controller_get_flags(c) & DEVICE_MCA) != (models[model]->flags & MODEL_MCA)) && + c) { + c++; + continue; + } + if ((((hdd_controller_get_flags(c) & DEVICE_PS1) && models[model]->id != ROM_IBMPS1_2011) || + (!(hdd_controller_get_flags(c) & DEVICE_PS1) && models[model]->id == ROM_IBMPS1_2011)) && + c) { + c++; + continue; + } + if (!hdd_controller_available(c)) { + c++; + continue; + } + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); + hdd_names[d] = hdd_controller_get_internal_name(c); - if (!strcmp(old_name, hdd_names[d])) { - wx_sendmessage(h, WX_CB_SETCURSEL, d, 0); - valid = 1; - } - c++; - d++; - } + if (!strcmp(old_name, hdd_names[d])) { + wx_sendmessage(h, WX_CB_SETCURSEL, d, 0); + valid = 1; + } + c++; + d++; + } - if (!valid) - wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); + if (!valid) + wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); - wx_enablewindow(h, TRUE); + wx_enablewindow(h, TRUE); - h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGUREHDD")); - if (hdd_controller_selected_has_config(hdlg)) - wx_enablewindow(h, TRUE); - else - wx_enablewindow(h, FALSE); + h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGUREHDD")); + if (hdd_controller_selected_has_config(hdlg)) + wx_enablewindow(h, TRUE); + else + wx_enablewindow(h, FALSE); - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOHDD")); - hdd_type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_HDCBOOK")); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOHDD")); + hdd_type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_HDCBOOK")); - while (wx_sendmessage(h, WX_CHB_GETPAGECOUNT, 0, 0)) - wx_sendmessage(h, WX_CHB_REMOVEPAGE, 0, 0); + while (wx_sendmessage(h, WX_CHB_GETPAGECOUNT, 0, 0)) + wx_sendmessage(h, WX_CHB_REMOVEPAGE, 0, 0); - for (c = 0; c < 7; c++) { - void *page; - char s[80]; + for (c = 0; c < 7; c++) { + void *page; + char s[80]; - sprintf(s, "IDC_HDPANEL[%i]", c); + sprintf(s, "IDC_HDPANEL[%i]", c); - page = wx_getdlgitem(hdlg, WX_ID(s)); - wx_sendmessage(page, WX_REPARENT, (LONG_PARAM)h, 0); - wx_sendmessage(h, WX_CHB_ADDPAGE, (LONG_PARAM)page, (LONG_PARAM)"dummy name"); - } - if (hdd_controller_is_scsi(hdd_names[hdd_type])) { - for (c = 0; c < 7; c++) { - void *page; - char s[80]; + page = wx_getdlgitem(hdlg, WX_ID(s)); + wx_sendmessage(page, WX_REPARENT, (LONG_PARAM)h, 0); + wx_sendmessage(h, WX_CHB_ADDPAGE, (LONG_PARAM)page, (LONG_PARAM) "dummy name"); + } + if (hdd_controller_is_scsi(hdd_names[hdd_type])) { + for (c = 0; c < 7; c++) { + void *page; + char s[80]; - sprintf(s, "IDC_HDPANEL[%i]", c); - page = wx_getdlgitem(hdlg, WX_ID(s)); - wx_sendmessage(page, WX_REPARENT, (LONG_PARAM)h, 0); - sprintf(s, "SCSI ID %i (%c:)", c, 'C' + c); - wx_sendmessage(h, WX_CHB_SETPAGETEXT, c, (LONG_PARAM)s); - } - } else if (hdd_controller_is_ide(hdd_names[hdd_type])) { - for (c = 0; c < 4; c++) { - void *page; - char s[80]; + sprintf(s, "IDC_HDPANEL[%i]", c); + page = wx_getdlgitem(hdlg, WX_ID(s)); + wx_sendmessage(page, WX_REPARENT, (LONG_PARAM)h, 0); + sprintf(s, "SCSI ID %i (%c:)", c, 'C' + c); + wx_sendmessage(h, WX_CHB_SETPAGETEXT, c, (LONG_PARAM)s); + } + } else if (hdd_controller_is_ide(hdd_names[hdd_type])) { + for (c = 0; c < 4; c++) { + void *page; + char s[80]; - sprintf(s, "IDC_HDPANEL[%i]", c); - page = wx_getdlgitem(hdlg, WX_ID(s)); - wx_sendmessage(page, WX_REPARENT, (LONG_PARAM)h, 0); - sprintf(s, "Drive %i %s %s (%c:)", c, (c & 2) ? "Secondary" : "Primary", (c & 1) ? "Slave" : "Master", 'C' + c); - wx_sendmessage(h, WX_CHB_SETPAGETEXT, c, (LONG_PARAM)s); - } - for (c = 6; c >= 4; c--) { - wx_sendmessage(h, WX_CHB_REMOVEPAGE, c, 0); - } - } else { - for (c = 0; c < 2; c++) { - void *page; - char s[80]; + sprintf(s, "IDC_HDPANEL[%i]", c); + page = wx_getdlgitem(hdlg, WX_ID(s)); + wx_sendmessage(page, WX_REPARENT, (LONG_PARAM)h, 0); + sprintf(s, "Drive %i %s %s (%c:)", c, (c & 2) ? "Secondary" : "Primary", (c & 1) ? "Slave" : "Master", + 'C' + c); + wx_sendmessage(h, WX_CHB_SETPAGETEXT, c, (LONG_PARAM)s); + } + for (c = 6; c >= 4; c--) { + wx_sendmessage(h, WX_CHB_REMOVEPAGE, c, 0); + } + } else { + for (c = 0; c < 2; c++) { + void *page; + char s[80]; - sprintf(s, "IDC_HDPANEL[%i]", c); - page = wx_getdlgitem(hdlg, WX_ID(s)); - wx_sendmessage(page, WX_REPARENT, (LONG_PARAM)h, 0); - sprintf(s, "Drive %i %s (%c:)", c, (c & 1) ? "Secondary" : "Primary", 'C' + c); - wx_sendmessage(h, WX_CHB_SETPAGETEXT, c, (LONG_PARAM)s); - } - for (c = 6; c >= 2; c--) { - wx_sendmessage(h, WX_CHB_REMOVEPAGE, c, 0); - } - } + sprintf(s, "IDC_HDPANEL[%i]", c); + page = wx_getdlgitem(hdlg, WX_ID(s)); + wx_sendmessage(page, WX_REPARENT, (LONG_PARAM)h, 0); + sprintf(s, "Drive %i %s (%c:)", c, (c & 1) ? "Secondary" : "Primary", 'C' + c); + wx_sendmessage(h, WX_CHB_SETPAGETEXT, c, (LONG_PARAM)s); + } + for (c = 6; c >= 2; c--) { + wx_sendmessage(h, WX_CHB_REMOVEPAGE, c, 0); + } + } } // TODO: split this into model/speed recalcs? static void recalc_cd_list(void *hdlg, int cur_speed, char *cur_model) { - int temp_model = -1; - void *h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_CDMODEL")); - int c = 0; - int found = 0; + int temp_model = -1; + void *h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_CDMODEL")); + int c = 0; + int found = 0; - wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); - if (hdd_controller_selected_is_ide(hdlg) || hdd_controller_selected_is_scsi(hdlg)) - wx_enablewindow(h, TRUE); - else - wx_enablewindow(h, FALSE); - while (c < MAX_CD_MODEL) { - char s[40]; - char *model; + wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); + if (hdd_controller_selected_is_ide(hdlg) || hdd_controller_selected_is_scsi(hdlg)) + wx_enablewindow(h, TRUE); + else + wx_enablewindow(h, FALSE); + while (c < MAX_CD_MODEL) { + char s[40]; + char *model; - if ((cd_get_model_interfaces(c) == CD_MODEL_INTERFACE_ALL) || - (cd_get_model_interfaces(c) == CD_MODEL_INTERFACE_IDE && hdd_controller_selected_is_ide(hdlg)) || - (cd_get_model_interfaces(c) == CD_MODEL_INTERFACE_SCSI && hdd_controller_selected_is_scsi(hdlg))) { + if ((cd_get_model_interfaces(c) == CD_MODEL_INTERFACE_ALL) || + (cd_get_model_interfaces(c) == CD_MODEL_INTERFACE_IDE && hdd_controller_selected_is_ide(hdlg)) || + (cd_get_model_interfaces(c) == CD_MODEL_INTERFACE_SCSI && hdd_controller_selected_is_scsi(hdlg))) { - model = cd_get_model(c); - sprintf(s, "%s", model); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); + model = cd_get_model(c); + sprintf(s, "%s", model); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); - if (!strncmp(s, cur_model, 40)) { - wx_sendmessage(h, WX_CB_SETCURSEL, c, 0); - temp_model = c; - found = 1; - } - } + if (!strncmp(s, cur_model, 40)) { + wx_sendmessage(h, WX_CB_SETCURSEL, c, 0); + temp_model = c; + found = 1; + } + } - c++; - } - if (!found) - wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); // assume that there is always at least one TODO: is this necessary? + c++; + } + if (!found) + wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); // assume that there is always at least one TODO: is this necessary? + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_CDSPEED")); + c = 0; + found = 0; - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_CDSPEED")); - c = 0; - found = 0; + wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); + if (temp_model >= 0 && cd_get_model_speed(temp_model) != -1) { + // this model has a specific speed + wx_enablewindow(h, FALSE); + cur_speed = cd_get_model_speed(temp_model); + } else if (hdd_controller_selected_is_ide(hdlg) || hdd_controller_selected_is_scsi(hdlg)) + wx_enablewindow(h, TRUE); + else + wx_enablewindow(h, FALSE); + while (1) { + char s[8]; + int speed; - wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); - if (temp_model >= 0 && cd_get_model_speed(temp_model) != -1) { - // this model has a specific speed - wx_enablewindow(h, FALSE); - cur_speed = cd_get_model_speed(temp_model); - } else if (hdd_controller_selected_is_ide(hdlg) || hdd_controller_selected_is_scsi(hdlg)) - wx_enablewindow(h, TRUE); - else - wx_enablewindow(h, FALSE); - while (1) { - char s[8]; - int speed; + speed = cd_get_speed(c); + sprintf(s, "%iX", speed); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); - speed = cd_get_speed(c); - sprintf(s, "%iX", speed); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); + if (speed == cur_speed) { + wx_sendmessage(h, WX_CB_SETCURSEL, c, 0); + found = 1; + } - if (speed == cur_speed) { - wx_sendmessage(h, WX_CB_SETCURSEL, c, 0); - found = 1; - } - - c++; - if (speed >= MAX_CD_SPEED) - break; - } - if (!found) - wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); // fall back TODO: is this necessary? + c++; + if (speed >= MAX_CD_SPEED) + break; + } + if (!found) + wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); // fall back TODO: is this necessary? } #ifdef USE_NETWORKING -static void recalc_net_list(void *hdlg, int model) -{ - void *h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_NETCARD")); - int c = 0, d = 0; - int found_card = 0; +static void recalc_net_list(void *hdlg, int model) { + void *h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_NETCARD")); + int c = 0, d = 0; + int found_card = 0; - wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); + wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); - while (1) - { - char *s = network_card_getname(c); - device_t *dev; + while (1) { + char *s = network_card_getname(c); + device_t *dev; - if (!s[0]) - break; + if (!s[0]) + break; - settings_network_to_list[c] = d; + settings_network_to_list[c] = d; - dev = network_card_getdevice(c); + dev = network_card_getdevice(c); - if (network_card_available(c) && - (!dev || (models[model]->flags & MODEL_PCI) || !(dev->flags & DEVICE_PCI))) - { - device_t *network_dev = network_card_getdevice(c); + if (network_card_available(c) && (!dev || (models[model]->flags & MODEL_PCI) || !(dev->flags & DEVICE_PCI))) { + device_t *network_dev = network_card_getdevice(c); - if (!network_dev || (network_dev->flags & DEVICE_MCA) == (models[model]->flags & MODEL_MCA)) - { - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); - settings_list_to_network[d] = c; - if (c == network_card_current) - { - wx_sendmessage(h, WX_CB_SETCURSEL, d, 0); - found_card = 1; - } - d++; - } - } + if (!network_dev || (network_dev->flags & DEVICE_MCA) == (models[model]->flags & MODEL_MCA)) { + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); + settings_list_to_network[d] = c; + if (c == network_card_current) { + wx_sendmessage(h, WX_CB_SETCURSEL, d, 0); + found_card = 1; + } + d++; + } + } - c++; - } - if (!found_card) - wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); + c++; + } + if (!found_card) + wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); } #endif int config_dlgsave(void *hdlg) { - char temp_str[256]; - void *h; - int c; - int gfx;//, fpu; - int temp_cpu, temp_cpu_m, temp_model, temp_fpu; - int temp_GAMEBLASTER, temp_GUS, temp_SSI2001, temp_voodoo, temp_sound_card_current; - int temp_dynarec; - int temp_fda_type, temp_fdb_type; - int temp_mouse_type; - int temp_lpt1_device; - int temp_joystick_type; + char temp_str[256]; + void *h; + int c; + int gfx; //, fpu; + int temp_cpu, temp_cpu_m, temp_model, temp_fpu; + int temp_GAMEBLASTER, temp_GUS, temp_SSI2001, temp_voodoo, temp_sound_card_current; + int temp_dynarec; + int temp_fda_type, temp_fdb_type; + int temp_mouse_type; + int temp_lpt1_device; + int temp_joystick_type; #ifdef USE_NETWORKING - int temp_network_card; + int temp_network_card; #endif - int hdd_changed = 0; - char s[260]; - PcemHDC hd[7]; + int hdd_changed = 0; + char s[260]; + PcemHDC hd[7]; - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO1")); - temp_model = listtomodel[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO1")); + temp_model = listtomodel[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; - h = wx_getdlgitem(hdlg, WX_ID("IDC_MEMSPIN")); - int mem = wx_sendmessage(h, WX_UDM_GETPOS, 0, 0); - mem &= ~(models[temp_model]->ram_granularity - 1); - if (mem < models[temp_model]->min_ram) - mem = models[temp_model]->min_ram; - else if (mem > models[temp_model]->max_ram) - mem = models[temp_model]->max_ram; - if ((models[temp_model]->flags & MODEL_AT) && models[temp_model]->ram_granularity < 128) - mem *= 1024; + h = wx_getdlgitem(hdlg, WX_ID("IDC_MEMSPIN")); + int mem = wx_sendmessage(h, WX_UDM_GETPOS, 0, 0); + mem &= ~(models[temp_model]->ram_granularity - 1); + if (mem < models[temp_model]->min_ram) + mem = models[temp_model]->min_ram; + else if (mem > models[temp_model]->max_ram) + mem = models[temp_model]->max_ram; + if ((models[temp_model]->flags & MODEL_AT) && models[temp_model]->ram_granularity < 128) + mem *= 1024; - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOVID")); - wx_sendmessage(h, WX_CB_GETLBTEXT, wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0), - (LONG_PARAM)temp_str); - gfx = video_new_to_old(video_card_getid(temp_str)); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOVID")); + wx_sendmessage(h, WX_CB_GETLBTEXT, wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0), (LONG_PARAM)temp_str); + gfx = video_new_to_old(video_card_getid(temp_str)); - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOCPUM")); - temp_cpu_m = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO3")); - temp_cpu = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); -// fpu = (models[temp_model]->cpu[temp_cpu_m].cpus[temp_cpu].cpu_type -// >= CPU_i486DX) ? 1 : 0; + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOCPUM")); + temp_cpu_m = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO3")); + temp_cpu = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + // fpu = (models[temp_model]->cpu[temp_cpu_m].cpus[temp_cpu].cpu_type + // >= CPU_i486DX) ? 1 : 0; - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOFPU")); - temp_fpu = fpu_get_type_from_index(temp_model, temp_cpu_m, temp_cpu, wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOFPU")); + temp_fpu = fpu_get_type_from_index(temp_model, temp_cpu_m, temp_cpu, wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)); - h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECK3")); - temp_GAMEBLASTER = wx_sendmessage(h, WX_BM_GETCHECK, 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECK3")); + temp_GAMEBLASTER = wx_sendmessage(h, WX_BM_GETCHECK, 0, 0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKGUS")); - temp_GUS = wx_sendmessage(h, WX_BM_GETCHECK, 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKGUS")); + temp_GUS = wx_sendmessage(h, WX_BM_GETCHECK, 0, 0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKSSI")); - temp_SSI2001 = wx_sendmessage(h, WX_BM_GETCHECK, 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKSSI")); + temp_SSI2001 = wx_sendmessage(h, WX_BM_GETCHECK, 0, 0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKSYNC")); - enable_sync = wx_sendmessage(h, WX_BM_GETCHECK, 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKSYNC")); + enable_sync = wx_sendmessage(h, WX_BM_GETCHECK, 0, 0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKVOODOO")); - temp_voodoo = wx_sendmessage(h, WX_BM_GETCHECK, 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKVOODOO")); + temp_voodoo = wx_sendmessage(h, WX_BM_GETCHECK, 0, 0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOSND")); - temp_sound_card_current = settings_list_to_sound[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOSND")); + temp_sound_card_current = settings_list_to_sound[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; - h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKDYNAREC")); - temp_dynarec = wx_sendmessage(h, WX_BM_GETCHECK, 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKDYNAREC")); + temp_dynarec = wx_sendmessage(h, WX_BM_GETCHECK, 0, 0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBODRA")); - temp_fda_type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBODRB")); - temp_fdb_type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBODRA")); + temp_fda_type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBODRB")); + temp_fdb_type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOJOY")); - temp_joystick_type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOJOY")); + temp_joystick_type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOMOUSE")); - temp_mouse_type = settings_list_to_mouse[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOMOUSE")); + temp_mouse_type = settings_list_to_mouse[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOHDD")); - c = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - if (hdd_names[c]) - hdd_changed = strncmp(hdd_names[c], hdd_controller_name, sizeof(hdd_controller_name) - 1); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOHDD")); + c = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + if (hdd_names[c]) + hdd_changed = strncmp(hdd_names[c], hdd_controller_name, sizeof(hdd_controller_name) - 1); - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOLPT1")); - temp_lpt1_device = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOLPT1")); + temp_lpt1_device = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); #ifdef USE_NETWORKING - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_NETCARD")); - temp_network_card = settings_list_to_network[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_NETCARD")); + temp_network_card = settings_list_to_network[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; #endif - if (temp_model != model || gfx != gfxcard || mem != mem_size || temp_fpu != fpu_type || - temp_GAMEBLASTER != GAMEBLASTER || temp_GUS != GUS || - temp_SSI2001 != SSI2001 || temp_sound_card_current != sound_card_current || - temp_voodoo != voodoo_enabled || temp_dynarec != cpu_use_dynarec || - temp_fda_type != fdd_get_type(0) || temp_fdb_type != fdd_get_type(1) || - temp_mouse_type != mouse_type || hdd_changed || hd_changed || cdrom_channel != new_cdrom_channel || - zip_channel != new_zip_channel || lpt1_current != temp_lpt1_device + if (temp_model != model || gfx != gfxcard || mem != mem_size || temp_fpu != fpu_type || temp_GAMEBLASTER != GAMEBLASTER || + temp_GUS != GUS || temp_SSI2001 != SSI2001 || temp_sound_card_current != sound_card_current || + temp_voodoo != voodoo_enabled || temp_dynarec != cpu_use_dynarec || temp_fda_type != fdd_get_type(0) || + temp_fdb_type != fdd_get_type(1) || temp_mouse_type != mouse_type || hdd_changed || hd_changed || + cdrom_channel != new_cdrom_channel || zip_channel != new_zip_channel || lpt1_current != temp_lpt1_device #ifdef USE_NETWORKING - || temp_network_card != network_card_current + || temp_network_card != network_card_current #endif - ) { - if (!has_been_inited || confirm()) { - savenvr(); - model = temp_model; - romset = model_getromset(); - gfxcard = gfx; - mem_size = mem; - cpu_manufacturer = temp_cpu_m; - cpu = temp_cpu; - fpu_type = temp_fpu; - GAMEBLASTER = temp_GAMEBLASTER; - GUS = temp_GUS; - SSI2001 = temp_SSI2001; - sound_card_current = temp_sound_card_current; - lpt1_current = temp_lpt1_device; - voodoo_enabled = temp_voodoo; - cpu_use_dynarec = temp_dynarec; - mouse_type = temp_mouse_type; - strcpy(lpt1_device_name, lpt_device_get_internal_name(temp_lpt1_device)); + ) { + if (!has_been_inited || confirm()) { + savenvr(); + model = temp_model; + romset = model_getromset(); + gfxcard = gfx; + mem_size = mem; + cpu_manufacturer = temp_cpu_m; + cpu = temp_cpu; + fpu_type = temp_fpu; + GAMEBLASTER = temp_GAMEBLASTER; + GUS = temp_GUS; + SSI2001 = temp_SSI2001; + sound_card_current = temp_sound_card_current; + lpt1_current = temp_lpt1_device; + voodoo_enabled = temp_voodoo; + cpu_use_dynarec = temp_dynarec; + mouse_type = temp_mouse_type; + strcpy(lpt1_device_name, lpt_device_get_internal_name(temp_lpt1_device)); #ifdef USE_NETWORKING - network_card_current = temp_network_card; + network_card_current = temp_network_card; #endif - fdd_set_type(0, temp_fda_type); - fdd_set_type(1, temp_fdb_type); + fdd_set_type(0, temp_fda_type); + fdd_set_type(1, temp_fdb_type); - if (hdd_names[c]) - strncpy(hdd_controller_name, hdd_names[c], sizeof(hdd_controller_name) - 1); - else - strcpy(hdd_controller_name, "none"); + if (hdd_names[c]) + strncpy(hdd_controller_name, hdd_names[c], sizeof(hdd_controller_name) - 1); + else + strcpy(hdd_controller_name, "none"); - for (c = 0; c < 7; c++) { - sprintf(s, "IDC_EDIT_SPT[%i]", c); - h = wx_getdlgitem(hdlg, WX_ID(s)); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[c].spt); - sprintf(s, "IDC_EDIT_HPC[%i]", c); - h = wx_getdlgitem(hdlg, WX_ID(s)); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[c].hpc); - sprintf(s, "IDC_EDIT_CYL[%i]", c); - h = wx_getdlgitem(hdlg, WX_ID(s)); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[c].tracks); - sprintf(s, "IDC_EDIT_FN[%i]", c); - h = wx_getdlgitem(hdlg, WX_ID(s)); - wx_sendmessage(h, WX_WM_GETTEXT, 511, (LONG_PARAM)ide_fn[c]); + for (c = 0; c < 7; c++) { + sprintf(s, "IDC_EDIT_SPT[%i]", c); + h = wx_getdlgitem(hdlg, WX_ID(s)); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[c].spt); + sprintf(s, "IDC_EDIT_HPC[%i]", c); + h = wx_getdlgitem(hdlg, WX_ID(s)); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[c].hpc); + sprintf(s, "IDC_EDIT_CYL[%i]", c); + h = wx_getdlgitem(hdlg, WX_ID(s)); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[c].tracks); + sprintf(s, "IDC_EDIT_FN[%i]", c); + h = wx_getdlgitem(hdlg, WX_ID(s)); + wx_sendmessage(h, WX_WM_GETTEXT, 511, (LONG_PARAM)ide_fn[c]); - hdc[c] = hd[c]; - } + hdc[c] = hd[c]; + } - cdrom_channel = new_cdrom_channel; - zip_channel = new_zip_channel; + cdrom_channel = new_cdrom_channel; + zip_channel = new_zip_channel; - if (has_been_inited) { - mem_alloc(); - loadbios(); - resetpchard(); - } - } else - return TRUE; - } + if (has_been_inited) { + mem_alloc(); + loadbios(); + resetpchard(); + } + } else + return TRUE; + } - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOSPD")); - video_speed = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0) - 1; + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOSPD")); + video_speed = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0) - 1; - cpu_manufacturer = temp_cpu_m; - cpu = temp_cpu; - cpu_set(); + cpu_manufacturer = temp_cpu_m; + cpu = temp_cpu; + cpu_set(); - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOWS")); - cpu_waitstates = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - cpu_update_waitstates(); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOWS")); + cpu_waitstates = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + cpu_update_waitstates(); - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_CDSPEED")); - cd_speed = cd_get_speed(wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)); - cd_set_speed(cd_speed); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_CDSPEED")); + cd_speed = cd_get_speed(wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)); + cd_set_speed(cd_speed); - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_CDMODEL")); - cd_model = cd_get_model(wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)); - cd_set_model(cd_model); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_CDMODEL")); + cd_model = cd_get_model(wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)); + cd_set_model(cd_model); - if (has_been_inited) - saveconfig(NULL); + if (has_been_inited) + saveconfig(NULL); - speedchanged(); + speedchanged(); - joystick_type = temp_joystick_type; - gameport_update_joystick_type(); + joystick_type = temp_joystick_type; + gameport_update_joystick_type(); - return TRUE; + return TRUE; } static int prev_model; int config_dlgproc(void *hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) { - char temp_str[256]; - void *h; - int c, d; - int gfx, mem; - int temp_cpu, temp_cpu_m, temp_model, temp_fpu; - int temp_sound_card_current; - int temp_dynarec; - int cpu_flags; - int cpu_type; - int temp_cd_model, temp_cd_speed; - int temp_mouse_type; - int temp_lpt1_current; + char temp_str[256]; + void *h; + int c, d; + int gfx, mem; + int temp_cpu, temp_cpu_m, temp_model, temp_fpu; + int temp_sound_card_current; + int temp_dynarec; + int cpu_flags; + int cpu_type; + int temp_cd_model, temp_cd_speed; + int temp_mouse_type; + int temp_lpt1_current; #ifdef USE_NETWORKING - int temp_network_card; + int temp_network_card; #endif - switch (message) { - case WX_INITDIALOG: { - pause = 1; - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO1")); - for (c = 0; c < ROM_MAX; c++) - romstolist[c] = 0; - c = d = 0; - while (models[c] != NULL) { - pclog("INITDIALOG : %i %i %i\n", c, models[c]->id, - romspresent[models[c]->id]); - if (romspresent[models[c]->id]) { - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)models[c]->name); - modeltolist[c] = d; - listtomodel[d] = c; - romstolist[models[c]->id] = d; - romstomodel[models[c]->id] = c; - d++; - } - c++; - } - wx_sendmessage(h, WX_CB_SETCURSEL, modeltolist[model], 0); - model = listtomodel[modeltolist[model]]; - romset = model_getromset(); - prev_model = model; + switch (message) { + case WX_INITDIALOG: { + pause = 1; + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO1")); + for (c = 0; c < ROM_MAX; c++) + romstolist[c] = 0; + c = d = 0; + while (models[c] != NULL) { + pclog("INITDIALOG : %i %i %i\n", c, models[c]->id, romspresent[models[c]->id]); + if (romspresent[models[c]->id]) { + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)models[c]->name); + modeltolist[c] = d; + listtomodel[d] = c; + romstolist[models[c]->id] = d; + romstomodel[models[c]->id] = c; + d++; + } + c++; + } + wx_sendmessage(h, WX_CB_SETCURSEL, modeltolist[model], 0); + model = listtomodel[modeltolist[model]]; + romset = model_getromset(); + prev_model = model; - recalc_vid_list(hdlg, romstomodel[romset], 0); + recalc_vid_list(hdlg, romstomodel[romset], 0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOCPUM")); - c = 0; - while (models[romstomodel[romset]]->cpu[c].cpus != NULL && c < 4) { - wx_sendmessage(h, WX_CB_ADDSTRING, 0, - (LONG_PARAM)models[romstomodel[romset]]->cpu[c].name); - c++; - } - wx_enablewindow(h, TRUE); - wx_sendmessage(h, WX_CB_SETCURSEL, cpu_manufacturer, 0); - if (c == 1) - wx_enablewindow(h, FALSE); - else - wx_enablewindow(h, TRUE); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOCPUM")); + c = 0; + while (models[romstomodel[romset]]->cpu[c].cpus != NULL && c < 4) { + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)models[romstomodel[romset]]->cpu[c].name); + c++; + } + wx_enablewindow(h, TRUE); + wx_sendmessage(h, WX_CB_SETCURSEL, cpu_manufacturer, 0); + if (c == 1) + wx_enablewindow(h, FALSE); + else + wx_enablewindow(h, TRUE); - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO3")); - c = 0; - while (models[romstomodel[romset]]->cpu[cpu_manufacturer].cpus[c].cpu_type != -1) { - wx_sendmessage(h, WX_CB_ADDSTRING, 0, - (LONG_PARAM)models[romstomodel[romset]]->cpu[cpu_manufacturer].cpus[c].name); - c++; - } - wx_enablewindow(h, TRUE); - wx_sendmessage(h, WX_CB_SETCURSEL, cpu, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO3")); + c = 0; + while (models[romstomodel[romset]]->cpu[cpu_manufacturer].cpus[c].cpu_type != -1) { + wx_sendmessage(h, WX_CB_ADDSTRING, 0, + (LONG_PARAM)models[romstomodel[romset]]->cpu[cpu_manufacturer].cpus[c].name); + c++; + } + wx_enablewindow(h, TRUE); + wx_sendmessage(h, WX_CB_SETCURSEL, cpu, 0); - recalc_fpu_list(hdlg, romstomodel[romset], cpu_manufacturer, cpu, fpu_type); + recalc_fpu_list(hdlg, romstomodel[romset], cpu_manufacturer, cpu, fpu_type); - recalc_snd_list(hdlg, romstomodel[romset]); + recalc_snd_list(hdlg, romstomodel[romset]); - h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECK3")); - wx_sendmessage(h, WX_BM_SETCHECK, GAMEBLASTER, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECK3")); + wx_sendmessage(h, WX_BM_SETCHECK, GAMEBLASTER, 0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKGUS")); - wx_sendmessage(h, WX_BM_SETCHECK, GUS, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKGUS")); + wx_sendmessage(h, WX_BM_SETCHECK, GUS, 0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKSSI")); - wx_sendmessage(h, WX_BM_SETCHECK, SSI2001, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKSSI")); + wx_sendmessage(h, WX_BM_SETCHECK, SSI2001, 0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKSYNC")); - wx_sendmessage(h, WX_BM_SETCHECK, enable_sync, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKSYNC")); + wx_sendmessage(h, WX_BM_SETCHECK, enable_sync, 0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKVOODOO")); - wx_sendmessage(h, WX_BM_SETCHECK, voodoo_enabled, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKVOODOO")); + wx_sendmessage(h, WX_BM_SETCHECK, voodoo_enabled, 0); - cpu_flags = - models[romstomodel[romset]]->cpu[cpu_manufacturer].cpus[cpu].cpu_flags; - h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKDYNAREC")); - if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) || (cpu_flags & CPU_REQUIRES_DYNAREC)) - wx_enablewindow(h, FALSE); - else - wx_enablewindow(h, TRUE); - wx_sendmessage(h, WX_BM_SETCHECK, - ((cpu_flags & CPU_SUPPORTS_DYNAREC) && cpu_use_dynarec) - || (cpu_flags & CPU_REQUIRES_DYNAREC), 0); + cpu_flags = models[romstomodel[romset]]->cpu[cpu_manufacturer].cpus[cpu].cpu_flags; + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKDYNAREC")); + if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) || (cpu_flags & CPU_REQUIRES_DYNAREC)) + wx_enablewindow(h, FALSE); + else + wx_enablewindow(h, TRUE); + wx_sendmessage(h, WX_BM_SETCHECK, + ((cpu_flags & CPU_SUPPORTS_DYNAREC) && cpu_use_dynarec) || (cpu_flags & CPU_REQUIRES_DYNAREC), 0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOSPD")); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Default"); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"8-bit"); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Slow 16-bit"); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Fast 16-bit"); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Slow VLB/PCI"); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Mid VLB/PCI"); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Fast VLB/PCI"); - wx_sendmessage(h, WX_CB_SETCURSEL, video_speed + 1, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOSPD")); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "Default"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "8-bit"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "Slow 16-bit"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "Fast 16-bit"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "Slow VLB/PCI"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "Mid VLB/PCI"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "Fast VLB/PCI"); + wx_sendmessage(h, WX_CB_SETCURSEL, video_speed + 1, 0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_MEMSPIN")); - printf("%d\n", models[model]->ram_granularity); - wx_sendmessage(h, WX_UDM_SETRANGE, 0, - (models[romstomodel[romset]]->min_ram << 16) - | models[romstomodel[romset]]->max_ram); - wx_sendmessage(h, WX_UDM_SETINCR, 0, models[model]->ram_granularity); - if (!((models[model]->flags & MODEL_AT) && models[model]->ram_granularity < 128)) { - wx_sendmessage(h, WX_UDM_SETPOS, 0, mem_size); - memspin_old = mem_size; - } else { - wx_sendmessage(h, WX_UDM_SETPOS, 0, mem_size / 1024); - memspin_old = mem_size / 1024; - } + h = wx_getdlgitem(hdlg, WX_ID("IDC_MEMSPIN")); + printf("%d\n", models[model]->ram_granularity); + wx_sendmessage(h, WX_UDM_SETRANGE, 0, + (models[romstomodel[romset]]->min_ram << 16) | models[romstomodel[romset]]->max_ram); + wx_sendmessage(h, WX_UDM_SETINCR, 0, models[model]->ram_granularity); + if (!((models[model]->flags & MODEL_AT) && models[model]->ram_granularity < 128)) { + wx_sendmessage(h, WX_UDM_SETPOS, 0, mem_size); + memspin_old = mem_size; + } else { + wx_sendmessage(h, WX_UDM_SETPOS, 0, mem_size / 1024); + memspin_old = mem_size / 1024; + } - h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGUREMOD")); - if (model_getdevice(model)) - wx_enablewindow(h, TRUE); - else - wx_enablewindow(h, FALSE); + h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGUREMOD")); + if (model_getdevice(model)) + wx_enablewindow(h, TRUE); + else + wx_enablewindow(h, FALSE); - h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGURESND")); - if (sound_card_has_config(sound_card_current)) - wx_enablewindow(h, TRUE); - else - wx_enablewindow(h, FALSE); + h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGURESND")); + if (sound_card_has_config(sound_card_current)) + wx_enablewindow(h, TRUE); + else + wx_enablewindow(h, FALSE); - h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGURELPT1")); - if (lpt_device_has_config(lpt1_current)) - wx_enablewindow(h, TRUE); - else - wx_enablewindow(h, FALSE); + h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGURELPT1")); + if (lpt_device_has_config(lpt1_current)) + wx_enablewindow(h, TRUE); + else + wx_enablewindow(h, FALSE); - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBODRA")); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"None"); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"5.25\" 360k"); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"5.25\" 1.2M"); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"5.25\" 1.2M Dual RPM"); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"3.5\" 720k"); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"3.5\" 1.44M"); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"3.5\" 1.44M 3-Mode"); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"3.5\" 2.88M"); - wx_sendmessage(h, WX_CB_SETCURSEL, fdd_get_type(0), 0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBODRB")); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"None"); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"5.25\" 360k"); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"5.25\" 1.2M"); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"5.25\" 1.2M Dual RPM"); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"3.5\" 720k"); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"3.5\" 1.44M"); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"3.5\" 1.44M 3-Mode"); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"3.5\" 2.88M"); - wx_sendmessage(h, WX_CB_SETCURSEL, fdd_get_type(1), 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBODRA")); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "None"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "5.25\" 360k"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "5.25\" 1.2M"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "5.25\" 1.2M Dual RPM"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "3.5\" 720k"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "3.5\" 1.44M"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "3.5\" 1.44M 3-Mode"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "3.5\" 2.88M"); + wx_sendmessage(h, WX_CB_SETCURSEL, fdd_get_type(0), 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBODRB")); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "None"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "5.25\" 360k"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "5.25\" 1.2M"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "5.25\" 1.2M Dual RPM"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "3.5\" 720k"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "3.5\" 1.44M"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "3.5\" 1.44M 3-Mode"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "3.5\" 2.88M"); + wx_sendmessage(h, WX_CB_SETCURSEL, fdd_get_type(1), 0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_MB")); - if ((models[model]->flags & MODEL_AT) && (models[model]->ram_granularity < 128)) - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)"MB"); - else - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)"KB"); + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_MB")); + if ((models[model]->flags & MODEL_AT) && (models[model]->ram_granularity < 128)) + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM) "MB"); + else + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM) "KB"); - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOJOY")); - c = 0; - while (joystick_get_name(c)) { - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)joystick_get_name(c)); - c++; - } - wx_enablewindow(h, TRUE); - wx_sendmessage(h, WX_CB_SETCURSEL, joystick_type, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOJOY")); + c = 0; + while (joystick_get_name(c)) { + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)joystick_get_name(c)); + c++; + } + wx_enablewindow(h, TRUE); + wx_sendmessage(h, WX_CB_SETCURSEL, joystick_type, 0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_JOY1")); - wx_enablewindow(h, (joystick_get_max_joysticks(joystick_type) >= 1) ? TRUE : FALSE); - h = wx_getdlgitem(hdlg, WX_ID("IDC_JOY2")); - wx_enablewindow(h, (joystick_get_max_joysticks(joystick_type) >= 2) ? TRUE : FALSE); - h = wx_getdlgitem(hdlg, WX_ID("IDC_JOY3")); - wx_enablewindow(h, (joystick_get_max_joysticks(joystick_type) >= 3) ? TRUE : FALSE); - h = wx_getdlgitem(hdlg, WX_ID("IDC_JOY4")); - wx_enablewindow(h, (joystick_get_max_joysticks(joystick_type) >= 4) ? TRUE : FALSE); + h = wx_getdlgitem(hdlg, WX_ID("IDC_JOY1")); + wx_enablewindow(h, (joystick_get_max_joysticks(joystick_type) >= 1) ? TRUE : FALSE); + h = wx_getdlgitem(hdlg, WX_ID("IDC_JOY2")); + wx_enablewindow(h, (joystick_get_max_joysticks(joystick_type) >= 2) ? TRUE : FALSE); + h = wx_getdlgitem(hdlg, WX_ID("IDC_JOY3")); + wx_enablewindow(h, (joystick_get_max_joysticks(joystick_type) >= 3) ? TRUE : FALSE); + h = wx_getdlgitem(hdlg, WX_ID("IDC_JOY4")); + wx_enablewindow(h, (joystick_get_max_joysticks(joystick_type) >= 4) ? TRUE : FALSE); - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOWS")); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"System default"); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"0 W/S"); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"1 W/S"); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"2 W/S"); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"3 W/S"); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"4 W/S"); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"5 W/S"); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"6 W/S"); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"7 W/S"); - wx_sendmessage(h, WX_CB_SETCURSEL, cpu_waitstates, 0); - cpu_type = - models[romstomodel[romset]]->cpu[cpu_manufacturer].cpus[cpu].cpu_type; - if ((cpu_type >= CPU_286) && (cpu_type <= CPU_386DX)) - wx_enablewindow(h, TRUE); - else - wx_enablewindow(h, FALSE); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOWS")); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "System default"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "0 W/S"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "1 W/S"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "2 W/S"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "3 W/S"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "4 W/S"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "5 W/S"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "6 W/S"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "7 W/S"); + wx_sendmessage(h, WX_CB_SETCURSEL, cpu_waitstates, 0); + cpu_type = models[romstomodel[romset]]->cpu[cpu_manufacturer].cpus[cpu].cpu_type; + if ((cpu_type >= CPU_286) && (cpu_type <= CPU_386DX)) + wx_enablewindow(h, TRUE); + else + wx_enablewindow(h, FALSE); - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOMOUSE")); - c = d = 0; - while (1) { - char *s = mouse_get_name(c); - int type; + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOMOUSE")); + c = d = 0; + while (1) { + char *s = mouse_get_name(c); + int type; - if (!s) - break; + if (!s) + break; - type = mouse_get_type(c); + type = mouse_get_type(c); - settings_mouse_to_list[c] = d; + settings_mouse_to_list[c] = d; - if (mouse_valid(type, model)) { - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); + if (mouse_valid(type, model)) { + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); - settings_list_to_mouse[d] = c; - d++; - } - c++; - } - wx_sendmessage(h, WX_CB_SETCURSEL, settings_mouse_to_list[mouse_type], 0); + settings_list_to_mouse[d] = c; + d++; + } + c++; + } + wx_sendmessage(h, WX_CB_SETCURSEL, settings_mouse_to_list[mouse_type], 0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOLPT1")); - c = d = 0; - while (1) { - char *s = lpt_device_get_name(c); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOLPT1")); + c = d = 0; + while (1) { + char *s = lpt_device_get_name(c); - if (!s) - break; + if (!s) + break; - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); - if (!strcmp(lpt1_device_name, lpt_device_get_internal_name(c))) - if (lpt1_current == c) - d = c; + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); + if (!strcmp(lpt1_device_name, lpt_device_get_internal_name(c))) + if (lpt1_current == c) + d = c; - c++; - } - wx_sendmessage(h, WX_CB_SETCURSEL, d, 0); + c++; + } + wx_sendmessage(h, WX_CB_SETCURSEL, d, 0); - recalc_hdd_list(hdlg, romstomodel[romset], 0, 0); + recalc_hdd_list(hdlg, romstomodel[romset], 0, 0); - hd_changed = 0; - new_cdrom_channel = cdrom_channel; - new_zip_channel = zip_channel; + hd_changed = 0; + new_cdrom_channel = cdrom_channel; + new_zip_channel = zip_channel; - hdconf_init(hdlg); + hdconf_init(hdlg); - for (c = 0; c < 7; c++) { - char s[80]; + for (c = 0; c < 7; c++) { + char s[80]; - sprintf(s, "IDC_COMBODRIVETYPE[%i]", c); - h = wx_getdlgitem(hdlg, WX_ID(s)); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Hard drive"); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"CD-ROM"); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Iomega Zip"); - if (cdrom_channel == c) - wx_sendmessage(h, WX_CB_SETCURSEL, 1, 0); - else if (zip_channel == c) - wx_sendmessage(h, WX_CB_SETCURSEL, 2, 0); - else - wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); - } + sprintf(s, "IDC_COMBODRIVETYPE[%i]", c); + h = wx_getdlgitem(hdlg, WX_ID(s)); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "Hard drive"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "CD-ROM"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "Iomega Zip"); + if (cdrom_channel == c) + wx_sendmessage(h, WX_CB_SETCURSEL, 1, 0); + else if (zip_channel == c) + wx_sendmessage(h, WX_CB_SETCURSEL, 2, 0); + else + wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); + } - recalc_cd_list(hdlg, cd_speed, cd_model); + recalc_cd_list(hdlg, cd_speed, cd_model); #ifdef USE_NETWORKING - recalc_net_list(hdlg, romstomodel[romset]); + recalc_net_list(hdlg, romstomodel[romset]); - h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGURE_NETCARD")); - if (network_card_has_config(network_card_current)) - wx_enablewindow(h, TRUE); - else - wx_enablewindow(h, FALSE); + h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGURE_NETCARD")); + if (network_card_has_config(network_card_current)) + wx_enablewindow(h, TRUE); + else + wx_enablewindow(h, FALSE); #endif - return TRUE; - } - break; - case WX_COMMAND: { - if (wParam == WX_ID("IDC_COMBO1")) { - int force_ide = 0; - int force_builtin_video = 0; + return TRUE; + } break; + case WX_COMMAND: { + if (wParam == WX_ID("IDC_COMBO1")) { + int force_ide = 0; + int force_builtin_video = 0; - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO1")); - temp_model = listtomodel[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO1")); + temp_model = listtomodel[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; - if (temp_model == prev_model) - break; + if (temp_model == prev_model) + break; - if ((models[temp_model]->flags & MODEL_HAS_IDE) && !(models[prev_model]->flags & MODEL_HAS_IDE)) - force_ide = 1; - if (model_has_optional_gfx(temp_model)) - force_builtin_video = 1; + if ((models[temp_model]->flags & MODEL_HAS_IDE) && !(models[prev_model]->flags & MODEL_HAS_IDE)) + force_ide = 1; + if (model_has_optional_gfx(temp_model)) + force_builtin_video = 1; - prev_model = temp_model; + prev_model = temp_model; - /*Rebuild manufacturer list*/ - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOCPUM")); - temp_cpu_m = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); - c = 0; - while (models[temp_model]->cpu[c].cpus != NULL && c < 4) { - wx_sendmessage(h, WX_CB_ADDSTRING, 0, - (LONG_PARAM)models[temp_model]->cpu[c].name); - c++; - } - if (temp_cpu_m >= c) - temp_cpu_m = c - 1; - wx_sendmessage(h, WX_CB_SETCURSEL, temp_cpu_m, 0); - if (c == 1) - wx_enablewindow(h, FALSE); - else - wx_enablewindow(h, TRUE); + /*Rebuild manufacturer list*/ + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOCPUM")); + temp_cpu_m = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); + c = 0; + while (models[temp_model]->cpu[c].cpus != NULL && c < 4) { + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)models[temp_model]->cpu[c].name); + c++; + } + if (temp_cpu_m >= c) + temp_cpu_m = c - 1; + wx_sendmessage(h, WX_CB_SETCURSEL, temp_cpu_m, 0); + if (c == 1) + wx_enablewindow(h, FALSE); + else + wx_enablewindow(h, TRUE); - /*Rebuild CPU list*/ - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO3")); - temp_cpu = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); - c = 0; - while (models[temp_model]->cpu[temp_cpu_m].cpus[c].cpu_type != -1) { - wx_sendmessage(h, WX_CB_ADDSTRING, 0, - (LONG_PARAM)models[temp_model]->cpu[temp_cpu_m].cpus[c].name); - c++; - } - if (temp_cpu >= c) - temp_cpu = c - 1; - wx_sendmessage(h, WX_CB_SETCURSEL, temp_cpu, 0); + /*Rebuild CPU list*/ + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO3")); + temp_cpu = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); + c = 0; + while (models[temp_model]->cpu[temp_cpu_m].cpus[c].cpu_type != -1) { + wx_sendmessage(h, WX_CB_ADDSTRING, 0, + (LONG_PARAM)models[temp_model]->cpu[temp_cpu_m].cpus[c].name); + c++; + } + if (temp_cpu >= c) + temp_cpu = c - 1; + wx_sendmessage(h, WX_CB_SETCURSEL, temp_cpu, 0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOFPU")); - temp_fpu = fpu_get_type_from_index(temp_model, temp_cpu_m, temp_cpu, wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)); - recalc_fpu_list(hdlg, temp_model, temp_cpu_m, temp_cpu, temp_fpu); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOFPU")); + temp_fpu = fpu_get_type_from_index(temp_model, temp_cpu_m, temp_cpu, + wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)); + recalc_fpu_list(hdlg, temp_model, temp_cpu_m, temp_cpu, temp_fpu); - h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKDYNAREC")); - temp_dynarec = wx_sendmessage(h, WX_BM_GETCHECK, 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKDYNAREC")); + temp_dynarec = wx_sendmessage(h, WX_BM_GETCHECK, 0, 0); - cpu_flags = - models[temp_model]->cpu[temp_cpu_m].cpus[temp_cpu].cpu_flags; - h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKDYNAREC")); - if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) || (cpu_flags & CPU_REQUIRES_DYNAREC)) - wx_enablewindow(h, FALSE); - else - wx_enablewindow(h, TRUE); - wx_sendmessage(h, WX_BM_SETCHECK, - ((cpu_flags & CPU_SUPPORTS_DYNAREC) && temp_dynarec) - || (cpu_flags & CPU_REQUIRES_DYNAREC), 0); + cpu_flags = models[temp_model]->cpu[temp_cpu_m].cpus[temp_cpu].cpu_flags; + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKDYNAREC")); + if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) || (cpu_flags & CPU_REQUIRES_DYNAREC)) + wx_enablewindow(h, FALSE); + else + wx_enablewindow(h, TRUE); + wx_sendmessage(h, WX_BM_SETCHECK, + ((cpu_flags & CPU_SUPPORTS_DYNAREC) && temp_dynarec) || (cpu_flags & CPU_REQUIRES_DYNAREC), + 0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_MB")); - if ((models[temp_model]->flags & MODEL_AT) && models[temp_model]->ram_granularity < 128) - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)"MB"); - else - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)"KB"); + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT_MB")); + if ((models[temp_model]->flags & MODEL_AT) && models[temp_model]->ram_granularity < 128) + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM) "MB"); + else + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM) "KB"); - h = wx_getdlgitem(hdlg, WX_ID("IDC_MEMSPIN")); - mem = wx_sendmessage(h, WX_UDM_GETPOS, 0, 0); - wx_sendmessage(h, WX_UDM_SETRANGE, 0, - (models[temp_model]->min_ram << 16) - | models[temp_model]->max_ram); - mem &= ~(models[temp_model]->ram_granularity - 1); - if (mem < models[temp_model]->min_ram) - mem = models[temp_model]->min_ram; - else if (mem > models[temp_model]->max_ram) - mem = models[temp_model]->max_ram; - wx_sendmessage(h, WX_UDM_SETPOS, 0, mem); - wx_sendmessage(h, WX_UDM_SETINCR, 0, models[temp_model]->ram_granularity); + h = wx_getdlgitem(hdlg, WX_ID("IDC_MEMSPIN")); + mem = wx_sendmessage(h, WX_UDM_GETPOS, 0, 0); + wx_sendmessage(h, WX_UDM_SETRANGE, 0, (models[temp_model]->min_ram << 16) | models[temp_model]->max_ram); + mem &= ~(models[temp_model]->ram_granularity - 1); + if (mem < models[temp_model]->min_ram) + mem = models[temp_model]->min_ram; + else if (mem > models[temp_model]->max_ram) + mem = models[temp_model]->max_ram; + wx_sendmessage(h, WX_UDM_SETPOS, 0, mem); + wx_sendmessage(h, WX_UDM_SETINCR, 0, models[temp_model]->ram_granularity); - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOWS")); - cpu_type = - models[temp_model]->cpu[temp_cpu_m].cpus[temp_cpu].cpu_type; - if (cpu_type >= CPU_286 && cpu_type <= CPU_386DX) - wx_enablewindow(h, TRUE); - else - wx_enablewindow(h, FALSE); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOWS")); + cpu_type = models[temp_model]->cpu[temp_cpu_m].cpus[temp_cpu].cpu_type; + if (cpu_type >= CPU_286 && cpu_type <= CPU_386DX) + wx_enablewindow(h, TRUE); + else + wx_enablewindow(h, FALSE); - h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGUREMOD")); - if (model_getdevice(temp_model)) - wx_enablewindow(h, TRUE); - else - wx_enablewindow(h, FALSE); + h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGUREMOD")); + if (model_getdevice(temp_model)) + wx_enablewindow(h, TRUE); + else + wx_enablewindow(h, FALSE); - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOMOUSE")); - temp_mouse_type = settings_list_to_mouse[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; - wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); - c = d = 0; - while (1) { - char *s = mouse_get_name(c); - int type; + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOMOUSE")); + temp_mouse_type = settings_list_to_mouse[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; + wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); + c = d = 0; + while (1) { + char *s = mouse_get_name(c); + int type; - if (!s) - break; + if (!s) + break; - type = mouse_get_type(c); - settings_mouse_to_list[c] = d; + type = mouse_get_type(c); + settings_mouse_to_list[c] = d; - if (mouse_valid(type, temp_model)) { - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); + if (mouse_valid(type, temp_model)) { + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); - settings_list_to_mouse[d] = c; - d++; - } + settings_list_to_mouse[d] = c; + d++; + } - c++; - } + c++; + } - if (mouse_valid(mouse_get_type(temp_mouse_type), temp_model)) - wx_sendmessage(h, WX_CB_SETCURSEL, settings_mouse_to_list[temp_mouse_type], 0); - else - wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); + if (mouse_valid(mouse_get_type(temp_mouse_type), temp_model)) + wx_sendmessage(h, WX_CB_SETCURSEL, settings_mouse_to_list[temp_mouse_type], 0); + else + wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); - recalc_vid_list(hdlg, temp_model, force_builtin_video); + recalc_vid_list(hdlg, temp_model, force_builtin_video); - recalc_hdd_list(hdlg, temp_model, 1, force_ide); + recalc_hdd_list(hdlg, temp_model, 1, force_ide); - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_CDMODEL")); - temp_cd_model = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_CDSPEED")); - temp_cd_speed = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - recalc_cd_list(hdlg, cd_get_speed(temp_cd_speed), cd_get_model(temp_cd_model)); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_CDMODEL")); + temp_cd_model = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_CDSPEED")); + temp_cd_speed = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + recalc_cd_list(hdlg, cd_get_speed(temp_cd_speed), cd_get_model(temp_cd_model)); - recalc_snd_list(hdlg, temp_model); + recalc_snd_list(hdlg, temp_model); #ifdef USE_NETWORKING - recalc_net_list(hdlg, temp_model); + recalc_net_list(hdlg, temp_model); #endif - } else if (wParam == WX_ID("IDC_COMBOCPUM")) { - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO1")); - temp_model = listtomodel[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOCPUM")); - temp_cpu_m = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + } else if (wParam == WX_ID("IDC_COMBOCPUM")) { + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO1")); + temp_model = listtomodel[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOCPUM")); + temp_cpu_m = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - /*Rebuild CPU list*/ - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO3")); - temp_cpu = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); - c = 0; - while (models[temp_model]->cpu[temp_cpu_m].cpus[c].cpu_type != -1) { - wx_sendmessage(h, WX_CB_ADDSTRING, 0, - (LONG_PARAM)models[temp_model]->cpu[temp_cpu_m].cpus[c].name); - c++; - } - if (temp_cpu >= c) - temp_cpu = c - 1; - wx_sendmessage(h, WX_CB_SETCURSEL, temp_cpu, 0); + /*Rebuild CPU list*/ + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO3")); + temp_cpu = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); + c = 0; + while (models[temp_model]->cpu[temp_cpu_m].cpus[c].cpu_type != -1) { + wx_sendmessage(h, WX_CB_ADDSTRING, 0, + (LONG_PARAM)models[temp_model]->cpu[temp_cpu_m].cpus[c].name); + c++; + } + if (temp_cpu >= c) + temp_cpu = c - 1; + wx_sendmessage(h, WX_CB_SETCURSEL, temp_cpu, 0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOFPU")); - temp_fpu = fpu_get_type_from_index(temp_model, temp_cpu_m, temp_cpu, wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)); - recalc_fpu_list(hdlg, temp_model, temp_cpu_m, temp_cpu, temp_fpu); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOFPU")); + temp_fpu = fpu_get_type_from_index(temp_model, temp_cpu_m, temp_cpu, + wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)); + recalc_fpu_list(hdlg, temp_model, temp_cpu_m, temp_cpu, temp_fpu); - h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKDYNAREC")); - temp_dynarec = wx_sendmessage(h, WX_BM_GETCHECK, 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKDYNAREC")); + temp_dynarec = wx_sendmessage(h, WX_BM_GETCHECK, 0, 0); - cpu_flags = - models[temp_model]->cpu[temp_cpu_m].cpus[temp_cpu].cpu_flags; - h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKDYNAREC")); - if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) || (cpu_flags & CPU_REQUIRES_DYNAREC)) - wx_enablewindow(h, FALSE); - else - wx_enablewindow(h, TRUE); - wx_sendmessage(h, WX_BM_SETCHECK, - ((cpu_flags & CPU_SUPPORTS_DYNAREC) && temp_dynarec) - || (cpu_flags & CPU_REQUIRES_DYNAREC), 0); + cpu_flags = models[temp_model]->cpu[temp_cpu_m].cpus[temp_cpu].cpu_flags; + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKDYNAREC")); + if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) || (cpu_flags & CPU_REQUIRES_DYNAREC)) + wx_enablewindow(h, FALSE); + else + wx_enablewindow(h, TRUE); + wx_sendmessage(h, WX_BM_SETCHECK, + ((cpu_flags & CPU_SUPPORTS_DYNAREC) && temp_dynarec) || (cpu_flags & CPU_REQUIRES_DYNAREC), + 0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOWS")); - cpu_type = - models[temp_model]->cpu[temp_cpu_m].cpus[temp_cpu].cpu_type; - if (cpu_type >= CPU_286 && cpu_type <= CPU_386DX) - wx_enablewindow(h, TRUE); - else - wx_enablewindow(h, FALSE); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOWS")); + cpu_type = models[temp_model]->cpu[temp_cpu_m].cpus[temp_cpu].cpu_type; + if (cpu_type >= CPU_286 && cpu_type <= CPU_386DX) + wx_enablewindow(h, TRUE); + else + wx_enablewindow(h, FALSE); - } else if (wParam == WX_ID("IDC_COMBO3")) { - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO1")); - temp_model = listtomodel[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOCPUM")); - temp_cpu_m = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO3")); - temp_cpu = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + } else if (wParam == WX_ID("IDC_COMBO3")) { + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO1")); + temp_model = listtomodel[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOCPUM")); + temp_cpu_m = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO3")); + temp_cpu = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOFPU")); - temp_fpu = fpu_get_type_from_index(temp_model, temp_cpu_m, temp_cpu, wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)); - recalc_fpu_list(hdlg, temp_model, temp_cpu_m, temp_cpu, temp_fpu); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOFPU")); + temp_fpu = fpu_get_type_from_index(temp_model, temp_cpu_m, temp_cpu, + wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)); + recalc_fpu_list(hdlg, temp_model, temp_cpu_m, temp_cpu, temp_fpu); - h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKDYNAREC")); - temp_dynarec = wx_sendmessage(h, WX_BM_GETCHECK, 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKDYNAREC")); + temp_dynarec = wx_sendmessage(h, WX_BM_GETCHECK, 0, 0); - cpu_flags = - models[temp_model]->cpu[temp_cpu_m].cpus[temp_cpu].cpu_flags; - h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKDYNAREC")); - if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) || (cpu_flags & CPU_REQUIRES_DYNAREC)) - wx_enablewindow(h, FALSE); - else - wx_enablewindow(h, TRUE); - wx_sendmessage(h, WX_BM_SETCHECK, - ((cpu_flags & CPU_SUPPORTS_DYNAREC) && temp_dynarec) - || (cpu_flags & CPU_REQUIRES_DYNAREC), 0); + cpu_flags = models[temp_model]->cpu[temp_cpu_m].cpus[temp_cpu].cpu_flags; + h = wx_getdlgitem(hdlg, WX_ID("IDC_CHECKDYNAREC")); + if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) || (cpu_flags & CPU_REQUIRES_DYNAREC)) + wx_enablewindow(h, FALSE); + else + wx_enablewindow(h, TRUE); + wx_sendmessage(h, WX_BM_SETCHECK, + ((cpu_flags & CPU_SUPPORTS_DYNAREC) && temp_dynarec) || (cpu_flags & CPU_REQUIRES_DYNAREC), + 0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOWS")); - cpu_type = - models[temp_model]->cpu[temp_cpu_m].cpus[temp_cpu].cpu_type; - if (cpu_type >= CPU_286 && cpu_type <= CPU_386DX) - wx_enablewindow(h, TRUE); - else - wx_enablewindow(h, FALSE); - } else if (wParam == WX_ID("IDC_CONFIGUREMOD")) { - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO1")); - temp_model = listtomodel[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOWS")); + cpu_type = models[temp_model]->cpu[temp_cpu_m].cpus[temp_cpu].cpu_type; + if (cpu_type >= CPU_286 && cpu_type <= CPU_386DX) + wx_enablewindow(h, TRUE); + else + wx_enablewindow(h, FALSE); + } else if (wParam == WX_ID("IDC_CONFIGUREMOD")) { + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO1")); + temp_model = listtomodel[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; - deviceconfig_open(hdlg, (void *)model_getdevice(temp_model)); - } else if (wParam == WX_ID("IDC_CONFIGUREVID")) { - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOVID")); - wx_sendmessage(h, WX_CB_GETLBTEXT, wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0), (LONG_PARAM)temp_str); - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO1")); - temp_model = listtomodel[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; + deviceconfig_open(hdlg, (void *)model_getdevice(temp_model)); + } else if (wParam == WX_ID("IDC_CONFIGUREVID")) { + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOVID")); + wx_sendmessage(h, WX_CB_GETLBTEXT, wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0), (LONG_PARAM)temp_str); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO1")); + temp_model = listtomodel[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; - deviceconfig_open(hdlg, (void *)video_card_getdevice(video_card_getid(temp_str), model_getromset_from_model(temp_model))); - } else if (wParam == WX_ID("IDC_COMBOVID")) { - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO1")); - temp_model = listtomodel[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; + deviceconfig_open(hdlg, (void *)video_card_getdevice(video_card_getid(temp_str), + model_getromset_from_model(temp_model))); + } else if (wParam == WX_ID("IDC_COMBOVID")) { + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO1")); + temp_model = listtomodel[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOVID")); - wx_sendmessage(h, WX_CB_GETLBTEXT, wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0), - (LONG_PARAM)temp_str); - gfx = video_card_getid(temp_str); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOVID")); + wx_sendmessage(h, WX_CB_GETLBTEXT, wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0), (LONG_PARAM)temp_str); + gfx = video_card_getid(temp_str); - h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGUREVID")); - if (video_card_has_config(gfx, model_getromset_from_model(temp_model))) - wx_enablewindow(h, TRUE); - else - wx_enablewindow(h, FALSE); - } else if (wParam == WX_ID("IDC_CONFIGURESND")) { - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOSND")); - temp_sound_card_current = settings_list_to_sound[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; + h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGUREVID")); + if (video_card_has_config(gfx, model_getromset_from_model(temp_model))) + wx_enablewindow(h, TRUE); + else + wx_enablewindow(h, FALSE); + } else if (wParam == WX_ID("IDC_CONFIGURESND")) { + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOSND")); + temp_sound_card_current = settings_list_to_sound[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; - deviceconfig_open(hdlg, (void *)sound_card_getdevice(temp_sound_card_current)); - } else if (wParam == WX_ID("IDC_COMBOSND")) { - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOSND")); - temp_sound_card_current = settings_list_to_sound[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; + deviceconfig_open(hdlg, (void *)sound_card_getdevice(temp_sound_card_current)); + } else if (wParam == WX_ID("IDC_COMBOSND")) { + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOSND")); + temp_sound_card_current = settings_list_to_sound[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; - h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGURESND")); - if (sound_card_has_config(temp_sound_card_current)) - wx_enablewindow(h, TRUE); - else - wx_enablewindow(h, FALSE); - } else if (wParam == WX_ID("IDC_CONFIGUREVOODOO")) { - deviceconfig_open(hdlg, (void *)&voodoo_device); - } else if (wParam == WX_ID("IDC_COMBOHDD")) { - hdconf_update(hdlg); + h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGURESND")); + if (sound_card_has_config(temp_sound_card_current)) + wx_enablewindow(h, TRUE); + else + wx_enablewindow(h, FALSE); + } else if (wParam == WX_ID("IDC_CONFIGUREVOODOO")) { + deviceconfig_open(hdlg, (void *)&voodoo_device); + } else if (wParam == WX_ID("IDC_COMBOHDD")) { + hdconf_update(hdlg); - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO1")); - temp_model = listtomodel[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; - recalc_hdd_list(hdlg, temp_model, 1, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO1")); + temp_model = listtomodel[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; + recalc_hdd_list(hdlg, temp_model, 1, 0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_CDMODEL")); - temp_cd_model = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_CDSPEED")); - temp_cd_speed = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - recalc_cd_list(hdlg, cd_get_speed(temp_cd_speed), cd_get_model(temp_cd_model)); - } else if (wParam == WX_ID("IDC_CONFIGUREHDD")) { - deviceconfig_open(hdlg, (void *)hdd_controller_selected_get_device(hdlg)); - } else if (wParam == WX_ID("IDC_COMBO_CDMODEL")) { - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_CDMODEL")); - temp_cd_model = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_CDSPEED")); - temp_cd_speed = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - recalc_cd_list(hdlg, cd_get_speed(temp_cd_speed), cd_get_model(temp_cd_model)); - } + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_CDMODEL")); + temp_cd_model = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_CDSPEED")); + temp_cd_speed = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + recalc_cd_list(hdlg, cd_get_speed(temp_cd_speed), cd_get_model(temp_cd_model)); + } else if (wParam == WX_ID("IDC_CONFIGUREHDD")) { + deviceconfig_open(hdlg, (void *)hdd_controller_selected_get_device(hdlg)); + } else if (wParam == WX_ID("IDC_COMBO_CDMODEL")) { + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_CDMODEL")); + temp_cd_model = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_CDSPEED")); + temp_cd_speed = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + recalc_cd_list(hdlg, cd_get_speed(temp_cd_speed), cd_get_model(temp_cd_model)); + } #ifdef USE_NETWORKING - else if (wParam == WX_ID("IDC_COMBO_NETCARD")) - { - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_NETCARD")); - temp_network_card = settings_list_to_network[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; + else if (wParam == WX_ID("IDC_COMBO_NETCARD")) { + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_NETCARD")); + temp_network_card = settings_list_to_network[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; - h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGURE_NETCARD")); - if (network_card_has_config(temp_network_card)) - wx_enablewindow(h, TRUE); - else - wx_enablewindow(h, FALSE); - } - else if (wParam == WX_ID("IDC_CONFIGURE_NETCARD")) - { - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_NETCARD")); - temp_network_card = settings_list_to_network[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; + h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGURE_NETCARD")); + if (network_card_has_config(temp_network_card)) + wx_enablewindow(h, TRUE); + else + wx_enablewindow(h, FALSE); + } else if (wParam == WX_ID("IDC_CONFIGURE_NETCARD")) { + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_NETCARD")); + temp_network_card = settings_list_to_network[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; - deviceconfig_open(hdlg, (void *)network_card_getdevice(temp_network_card)); - } + deviceconfig_open(hdlg, (void *)network_card_getdevice(temp_network_card)); + } #endif - else if (wParam == WX_ID("IDC_COMBOJOY")) { - int temp_joystick_type; + else if (wParam == WX_ID("IDC_COMBOJOY")) { + int temp_joystick_type; - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOJOY")); - temp_joystick_type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOJOY")); + temp_joystick_type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_JOY1")); - wx_enablewindow(h, (joystick_get_max_joysticks(temp_joystick_type) >= 1) ? TRUE : FALSE); - h = wx_getdlgitem(hdlg, WX_ID("IDC_JOY2")); - wx_enablewindow(h, (joystick_get_max_joysticks(temp_joystick_type) >= 2) ? TRUE : FALSE); - h = wx_getdlgitem(hdlg, WX_ID("IDC_JOY3")); - wx_enablewindow(h, (joystick_get_max_joysticks(temp_joystick_type) >= 3) ? TRUE : FALSE); - h = wx_getdlgitem(hdlg, WX_ID("IDC_JOY4")); - wx_enablewindow(h, (joystick_get_max_joysticks(temp_joystick_type) >= 4) ? TRUE : FALSE); - } else if (wParam == WX_ID("IDC_JOY1")) { - int temp_joystick_type; + h = wx_getdlgitem(hdlg, WX_ID("IDC_JOY1")); + wx_enablewindow(h, (joystick_get_max_joysticks(temp_joystick_type) >= 1) ? TRUE : FALSE); + h = wx_getdlgitem(hdlg, WX_ID("IDC_JOY2")); + wx_enablewindow(h, (joystick_get_max_joysticks(temp_joystick_type) >= 2) ? TRUE : FALSE); + h = wx_getdlgitem(hdlg, WX_ID("IDC_JOY3")); + wx_enablewindow(h, (joystick_get_max_joysticks(temp_joystick_type) >= 3) ? TRUE : FALSE); + h = wx_getdlgitem(hdlg, WX_ID("IDC_JOY4")); + wx_enablewindow(h, (joystick_get_max_joysticks(temp_joystick_type) >= 4) ? TRUE : FALSE); + } else if (wParam == WX_ID("IDC_JOY1")) { + int temp_joystick_type; - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOJOY")); - temp_joystick_type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - joystickconfig_open(hdlg, 0, temp_joystick_type); - } else if (wParam == WX_ID("IDC_JOY2")) { - int temp_joystick_type; + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOJOY")); + temp_joystick_type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + joystickconfig_open(hdlg, 0, temp_joystick_type); + } else if (wParam == WX_ID("IDC_JOY2")) { + int temp_joystick_type; - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOJOY")); - temp_joystick_type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - joystickconfig_open(hdlg, 1, temp_joystick_type); - } else if (wParam == WX_ID("IDC_JOY3")) { - int temp_joystick_type; + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOJOY")); + temp_joystick_type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + joystickconfig_open(hdlg, 1, temp_joystick_type); + } else if (wParam == WX_ID("IDC_JOY3")) { + int temp_joystick_type; - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOJOY")); - temp_joystick_type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - joystickconfig_open(hdlg, 2, temp_joystick_type); - } else if (wParam == WX_ID("IDC_JOY4")) { - int temp_joystick_type; + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOJOY")); + temp_joystick_type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + joystickconfig_open(hdlg, 2, temp_joystick_type); + } else if (wParam == WX_ID("IDC_JOY4")) { + int temp_joystick_type; - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOJOY")); - temp_joystick_type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - joystickconfig_open(hdlg, 3, temp_joystick_type); - } else if (wParam == WX_ID("IDC_CONFIGURELPT1")) { - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOLPT1")); - temp_lpt1_current = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOJOY")); + temp_joystick_type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + joystickconfig_open(hdlg, 3, temp_joystick_type); + } else if (wParam == WX_ID("IDC_CONFIGURELPT1")) { + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOLPT1")); + temp_lpt1_current = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - deviceconfig_open(hdlg, (void *)lpt_get_device(temp_lpt1_current)); - } else if (wParam == WX_ID("IDC_COMBOLPT1")) { - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOLPT1")); - temp_lpt1_current = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + deviceconfig_open(hdlg, (void *)lpt_get_device(temp_lpt1_current)); + } else if (wParam == WX_ID("IDC_COMBOLPT1")) { + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOLPT1")); + temp_lpt1_current = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGURELPT1")); - if (lpt_device_has_config(temp_lpt1_current)) - wx_enablewindow(h, TRUE); - else - wx_enablewindow(h, FALSE); - } + h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGURELPT1")); + if (lpt_device_has_config(temp_lpt1_current)) + wx_enablewindow(h, TRUE); + else + wx_enablewindow(h, FALSE); + } #ifndef __WXGTK__ - /*Emulate spinner granularity on systems that don't implement wxSpinCtrl->SetIncrement()*/ - else if (wParam == WX_ID("IDC_MEMSPIN")) { - int mem; - int granularity; - int granularity_mask; + /*Emulate spinner granularity on systems that don't implement wxSpinCtrl->SetIncrement()*/ + else if (wParam == WX_ID("IDC_MEMSPIN")) { + int mem; + int granularity; + int granularity_mask; - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO1")); - temp_model = listtomodel[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO1")); + temp_model = listtomodel[wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0)]; - granularity = models[temp_model]->ram_granularity; - granularity_mask = granularity - 1; + granularity = models[temp_model]->ram_granularity; + granularity_mask = granularity - 1; - h = wx_getdlgitem(hdlg, WX_ID("IDC_MEMSPIN")); - mem = wx_sendmessage(h, WX_UDM_GETPOS, 0, 0); - if (mem < memspin_old) { - /*Assume decrease*/ - mem &= ~granularity_mask; - } else { - /*Assume increase*/ - mem = (mem + granularity_mask) & ~granularity_mask; - } - wx_sendmessage(h, WX_UDM_SETPOS, 0, mem); - memspin_old = mem; - } + h = wx_getdlgitem(hdlg, WX_ID("IDC_MEMSPIN")); + mem = wx_sendmessage(h, WX_UDM_GETPOS, 0, 0); + if (mem < memspin_old) { + /*Assume decrease*/ + mem &= ~granularity_mask; + } else { + /*Assume increase*/ + mem = (mem + granularity_mask) & ~granularity_mask; + } + wx_sendmessage(h, WX_UDM_SETPOS, 0, mem); + memspin_old = mem; + } #endif - return 0; - } - } - return 0; + return 0; + } + } + return 0; } static struct { - int cylinders; - int heads; -} hd_types[] = - { - {306, 4}, {615, 4}, {615, 6}, {940, 8}, - {940, 6}, {615, 4}, {462, 8}, {733, 5}, - {900, 15}, {820, 3}, {855, 5}, {855, 7}, - {306, 8}, {733, 7}, {0, 0}, {612, 4}, - {977, 5}, {977, 7}, {1024, 7}, {733, 5}, - {733, 7}, {733, 5}, {306, 4}, {925, 7}, - {925, 9}, {754, 7}, {754, 11}, {699, 7}, - {823, 10}, {918, 7}, {1024, 11}, {1024, 15}, - {1024, 5}, {612, 2}, {1024, 9}, {1024, 8}, - {615, 8}, {987, 3}, {462, 7}, {820, 6}, - {977, 5}, {981, 5}, {830, 7}, {830, 10}, - {917, 15}, {1224, 15} - }; + int cylinders; + int heads; +} hd_types[] = {{306, 4}, {615, 4}, {615, 6}, {940, 8}, {940, 6}, {615, 4}, {462, 8}, {733, 5}, {900, 15}, {820, 3}, + {855, 5}, {855, 7}, {306, 8}, {733, 7}, {0, 0}, {612, 4}, {977, 5}, {977, 7}, {1024, 7}, {733, 5}, + {733, 7}, {733, 5}, {306, 4}, {925, 7}, {925, 9}, {754, 7}, {754, 11}, {699, 7}, {823, 10}, {918, 7}, + {1024, 11}, {1024, 15}, {1024, 5}, {612, 2}, {1024, 9}, {1024, 8}, {615, 8}, {987, 3}, {462, 7}, {820, 6}, + {977, 5}, {981, 5}, {830, 7}, {830, 10}, {917, 15}, {1224, 15}}; static int hdd_controller_selected_is_mfm(void *hdlg) { - void *h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOHDD")); - int c = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - if (hdd_names[c]) - return hdd_controller_is_mfm(hdd_names[c]); - return 0; + void *h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOHDD")); + int c = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + if (hdd_names[c]) + return hdd_controller_is_mfm(hdd_names[c]); + return 0; } static int hdd_controller_selected_is_ide(void *hdlg) { - void *h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOHDD")); - int c = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - if (hdd_names[c]) - return hdd_controller_is_ide(hdd_names[c]); - return 0; + void *h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOHDD")); + int c = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + if (hdd_names[c]) + return hdd_controller_is_ide(hdd_names[c]); + return 0; } static int hdd_controller_selected_is_scsi(void *hdlg) { - void *h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOHDD")); - int c = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - if (hdd_names[c]) - return hdd_controller_is_scsi(hdd_names[c]); - return 0; + void *h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOHDD")); + int c = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + if (hdd_names[c]) + return hdd_controller_is_scsi(hdd_names[c]); + return 0; } static int hdd_controller_selected_has_config(void *hdlg) { - void *h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOHDD")); - int c = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - if (hdd_names[c]) - return hdd_controller_has_config(hdd_names[c]); - return 0; + void *h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOHDD")); + int c = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + if (hdd_names[c]) + return hdd_controller_has_config(hdd_names[c]); + return 0; } static device_t *hdd_controller_selected_get_device(void *hdlg) { - void *h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOHDD")); - int c = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - if (hdd_names[c]) - return hdd_controller_get_device(hdd_names[c]); - return NULL; + void *h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBOHDD")); + int c = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + if (hdd_names[c]) + return hdd_controller_get_device(hdd_names[c]); + return NULL; } static void check_hd_type(void *hdlg, off64_t sz) { - int c; + int c; - hd_new_type = 0; + hd_new_type = 0; - if (hdd_controller_selected_is_mfm(hdlg)) { - for (c = 0; c < 46; c++) { - if ((hd_types[c].cylinders * hd_types[c].heads * 17 * 512) == sz) { - hd_new_spt = 17; - hd_new_hpc = hd_types[c].heads; - hd_new_cyl = hd_types[c].cylinders; - hd_new_type = c + 1; - return; - } - } - hd_new_spt = 63; - hd_new_hpc = 16; - hd_new_cyl = ((sz / 512) / 16) / 63; - } else { - if ((sz % 17) == 0 && sz <= 142606336) { - hd_new_spt = 17; + if (hdd_controller_selected_is_mfm(hdlg)) { + for (c = 0; c < 46; c++) { + if ((hd_types[c].cylinders * hd_types[c].heads * 17 * 512) == sz) { + hd_new_spt = 17; + hd_new_hpc = hd_types[c].heads; + hd_new_cyl = hd_types[c].cylinders; + hd_new_type = c + 1; + return; + } + } + hd_new_spt = 63; + hd_new_hpc = 16; + hd_new_cyl = ((sz / 512) / 16) / 63; + } else { + if ((sz % 17) == 0 && sz <= 142606336) { + hd_new_spt = 17; - if (sz <= 26738688) - hd_new_hpc = 4; - else if ((sz % 3072) == 0 && sz <= 53477376) - hd_new_hpc = 6; - else { - for (c = 5; c < 16; c++) { - if ((sz % (c * 512)) == 0 && sz <= 1024 * c * 17 * 512) - break; - if (c == 5) - c++; - } - hd_new_hpc = c; - } - hd_new_cyl = (int)((sz / 512) / hd_new_hpc) / 17; - } else { - hd_new_spt = 63; - hd_new_hpc = 16; - hd_new_cyl = ((sz / 512) / 16) / 63; - } - } + if (sz <= 26738688) + hd_new_hpc = 4; + else if ((sz % 3072) == 0 && sz <= 53477376) + hd_new_hpc = 6; + else { + for (c = 5; c < 16; c++) { + if ((sz % (c * 512)) == 0 && sz <= 1024 * c * 17 * 512) + break; + if (c == 5) + c++; + } + hd_new_hpc = c; + } + hd_new_cyl = (int)((sz / 512) / hd_new_hpc) / 17; + } else { + hd_new_spt = 63; + hd_new_hpc = 16; + hd_new_cyl = ((sz / 512) / 16) / 63; + } + } } static void update_hdd_cdrom(void *hdlg) { - void *h; - int i, j, b; - char s[25]; + void *h; + int i, j, b; + char s[25]; - int is_mfm = hdd_controller_selected_is_mfm(hdlg); + int is_mfm = hdd_controller_selected_is_mfm(hdlg); - for (i = 0; i < 7; ++i) { - b = !is_mfm && ((new_cdrom_channel == i) || (new_zip_channel == i)); - pclog("update_hdd_cdrom: i=%i b=%i new_cdrom_channel=%i new_zip_channel=%i\n", i, b, new_cdrom_channel, new_zip_channel); - sprintf(s, "IDC_COMBODRIVETYPE[%d]", i); - h = wx_getdlgitem(hdlg, WX_ID(s)); - if (i == new_cdrom_channel) - wx_sendmessage(h, WX_CB_SETCURSEL, 1, 0); - else if (i == new_zip_channel) - wx_sendmessage(h, WX_CB_SETCURSEL, 2, 0); - else - wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); - sprintf(s, "IDC_EDIT_FN[%d]", i); - wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !b); - sprintf(s, "IDC_FILE[%d]", i); - wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !b); - sprintf(s, "IDC_EJECT[%d]", i); - wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !b); - sprintf(s, "IDC_NEW[%d]", i); - wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !b); - sprintf(s, "IDC_EDIT_SPT[%d]", i); - wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !b); - sprintf(s, "IDC_EDIT_HPC[%d]", i); - wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !b); - sprintf(s, "IDC_EDIT_CYL[%d]", i); - wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !b); - sprintf(s, "IDC_TEXT_SIZE[%d]", i); - wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !b); - for (j = 1; j < 6; ++j) { - sprintf(s, "IDC_HDD_LABEL[%d]", i * 10 + j); - wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !b); - } - } + for (i = 0; i < 7; ++i) { + b = !is_mfm && ((new_cdrom_channel == i) || (new_zip_channel == i)); + pclog("update_hdd_cdrom: i=%i b=%i new_cdrom_channel=%i new_zip_channel=%i\n", i, b, new_cdrom_channel, + new_zip_channel); + sprintf(s, "IDC_COMBODRIVETYPE[%d]", i); + h = wx_getdlgitem(hdlg, WX_ID(s)); + if (i == new_cdrom_channel) + wx_sendmessage(h, WX_CB_SETCURSEL, 1, 0); + else if (i == new_zip_channel) + wx_sendmessage(h, WX_CB_SETCURSEL, 2, 0); + else + wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); + sprintf(s, "IDC_EDIT_FN[%d]", i); + wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !b); + sprintf(s, "IDC_FILE[%d]", i); + wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !b); + sprintf(s, "IDC_EJECT[%d]", i); + wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !b); + sprintf(s, "IDC_NEW[%d]", i); + wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !b); + sprintf(s, "IDC_EDIT_SPT[%d]", i); + wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !b); + sprintf(s, "IDC_EDIT_HPC[%d]", i); + wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !b); + sprintf(s, "IDC_EDIT_CYL[%d]", i); + wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !b); + sprintf(s, "IDC_TEXT_SIZE[%d]", i); + wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !b); + for (j = 1; j < 6; ++j) { + sprintf(s, "IDC_HDD_LABEL[%d]", i * 10 + j); + wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !b); + } + } } static volatile int create_drive_pos; static int create_drive_raw(void *data) { - int c; - uint8_t buf[512]; - FILE *f = (FILE *)data; - memset(buf, 0, 512); - for (c = 0; c < (hd_new_cyl * hd_new_hpc * hd_new_spt); c++) { - create_drive_pos = c; - fwrite(buf, 512, 1, f); - } + int c; + uint8_t buf[512]; + FILE *f = (FILE *)data; + memset(buf, 0, 512); + for (c = 0; c < (hd_new_cyl * hd_new_hpc * hd_new_spt); c++) { + create_drive_pos = c; + fwrite(buf, 512, 1, f); + } - fclose(f); + fclose(f); - return 1; + return 1; } -static void vhd_progress_callback(uint32_t current_sector, uint32_t total_sectors) { - create_drive_pos = (int)current_sector; -} +static void vhd_progress_callback(uint32_t current_sector, uint32_t total_sectors) { create_drive_pos = (int)current_sector; } /* If the disk geometry requested in the PCem GUI is not compatible with the internal VHD geometry, * we adjust it to the next-largest size that is compatible. On average, this will be a difference @@ -1486,840 +1447,853 @@ static void vhd_progress_callback(uint32_t current_sector, uint32_t total_sector * than a tenth of a percent change in size. */ static void adjust_pcem_geometry_for_vhd(MVHDGeom *vhd_geometry) { - if (hd_new_cyl <= 65535) - return; + if (hd_new_cyl <= 65535) + return; - int desired_sectors = hd_new_cyl * hd_new_hpc * hd_new_spt; - if (desired_sectors > 267321600) - desired_sectors = 267321600; + int desired_sectors = hd_new_cyl * hd_new_hpc * hd_new_spt; + if (desired_sectors > 267321600) + desired_sectors = 267321600; - int remainder = desired_sectors % 85680; /* 8560 is the LCM of 1008 (63*16) and 4080 (255*16) */ - if (remainder > 0) - desired_sectors += (85680 - remainder); + int remainder = desired_sectors % 85680; /* 8560 is the LCM of 1008 (63*16) and 4080 (255*16) */ + if (remainder > 0) + desired_sectors += (85680 - remainder); - hd_new_cyl = desired_sectors / (16 * 63); - hd_new_hpc = 16; - hd_new_spt = 63; + hd_new_cyl = desired_sectors / (16 * 63); + hd_new_hpc = 16; + hd_new_spt = 63; - vhd_geometry->cyl = desired_sectors / (16 * 255); - vhd_geometry->heads = 16; - vhd_geometry->spt = 255; + vhd_geometry->cyl = desired_sectors / (16 * 255); + vhd_geometry->heads = 16; + vhd_geometry->spt = 255; } static void adjust_vhd_geometry_for_pcem() { - if (hd_new_spt <= 63) - return; + if (hd_new_spt <= 63) + return; - int desired_sectors = hd_new_cyl * hd_new_hpc * hd_new_spt; - if (desired_sectors > 267321600) - desired_sectors = 267321600; + int desired_sectors = hd_new_cyl * hd_new_hpc * hd_new_spt; + if (desired_sectors > 267321600) + desired_sectors = 267321600; - int remainder = desired_sectors % 85680; /* 8560 is the LCM of 1008 (63*16) and 4080 (255*16) */ - if (remainder > 0) - desired_sectors -= remainder; + int remainder = desired_sectors % 85680; /* 8560 is the LCM of 1008 (63*16) and 4080 (255*16) */ + if (remainder > 0) + desired_sectors -= remainder; - hd_new_cyl = desired_sectors / (16 * 63); - hd_new_hpc = 16; - hd_new_spt = 63; + hd_new_cyl = desired_sectors / (16 * 63); + hd_new_hpc = 16; + hd_new_spt = 63; } static int create_drive_vhd_fixed(void *data) { - MVHDGeom geometry = {.cyl = hd_new_cyl, .heads = hd_new_hpc, .spt = hd_new_spt}; - adjust_pcem_geometry_for_vhd(&geometry); + MVHDGeom geometry = {.cyl = hd_new_cyl, .heads = hd_new_hpc, .spt = hd_new_spt}; + adjust_pcem_geometry_for_vhd(&geometry); - int vhd_error = 0; - MVHDMeta *vhd = mvhd_create_fixed(hd_new_name, geometry, &vhd_error, vhd_progress_callback); - if (vhd == NULL) { - return 0; - } else { - mvhd_close(vhd); - return 1; - } + int vhd_error = 0; + MVHDMeta *vhd = mvhd_create_fixed(hd_new_name, geometry, &vhd_error, vhd_progress_callback); + if (vhd == NULL) { + return 0; + } else { + mvhd_close(vhd); + return 1; + } } static int create_drive_vhd_dynamic(int blocksize) { - MVHDGeom geometry = {.cyl = hd_new_cyl, .heads = hd_new_hpc, .spt = hd_new_spt}; - adjust_pcem_geometry_for_vhd(&geometry); - int vhd_error = 0; - MVHDCreationOptions options; - options.block_size_in_sectors = blocksize; - options.path = hd_new_name; - options.size_in_bytes = 0; - options.geometry = geometry; - options.type = MVHD_TYPE_DYNAMIC; + MVHDGeom geometry = {.cyl = hd_new_cyl, .heads = hd_new_hpc, .spt = hd_new_spt}; + adjust_pcem_geometry_for_vhd(&geometry); + int vhd_error = 0; + MVHDCreationOptions options; + options.block_size_in_sectors = blocksize; + options.path = hd_new_name; + options.size_in_bytes = 0; + options.geometry = geometry; + options.type = MVHD_TYPE_DYNAMIC; - MVHDMeta *vhd = mvhd_create_ex(options, &vhd_error); - if (vhd == NULL) { - return 0; - } else { - mvhd_close(vhd); - return 1; - } + MVHDMeta *vhd = mvhd_create_ex(options, &vhd_error); + if (vhd == NULL) { + return 0; + } else { + mvhd_close(vhd); + return 1; + } } static int create_drive_vhd_diff(char *parent_filename, int blocksize) { - int vhd_error = 0; - MVHDCreationOptions options; - options.block_size_in_sectors = blocksize; - options.path = hd_new_name; - options.parent_path = parent_filename; - options.type = MVHD_TYPE_DIFF; + int vhd_error = 0; + MVHDCreationOptions options; + options.block_size_in_sectors = blocksize; + options.path = hd_new_name; + options.parent_path = parent_filename; + options.type = MVHD_TYPE_DIFF; - MVHDMeta *vhd = mvhd_create_ex(options, &vhd_error); - if (vhd == NULL) { - return 0; - } else { - MVHDGeom vhd_geom = mvhd_get_geometry(vhd); + MVHDMeta *vhd = mvhd_create_ex(options, &vhd_error); + if (vhd == NULL) { + return 0; + } else { + MVHDGeom vhd_geom = mvhd_get_geometry(vhd); - if (vhd_geom.spt > 63) { - hd_new_cyl = mvhd_calc_size_sectors(&vhd_geom) / (16 * 63); - hd_new_hpc = 16; - hd_new_spt = 63; - } else { - hd_new_cyl = vhd_geom.cyl; - hd_new_hpc = vhd_geom.heads; - hd_new_spt = vhd_geom.spt; - } + if (vhd_geom.spt > 63) { + hd_new_cyl = mvhd_calc_size_sectors(&vhd_geom) / (16 * 63); + hd_new_hpc = 16; + hd_new_spt = 63; + } else { + hd_new_cyl = vhd_geom.cyl; + hd_new_hpc = vhd_geom.heads; + hd_new_spt = vhd_geom.spt; + } - mvhd_close(vhd); - return 1; - } + mvhd_close(vhd); + return 1; + } } static int hdnew_dlgproc(void *hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) { - char s[260]; - void *h; - int c; - PcemHDC hd[7]; - FILE *f; - int hd_type, hd_format, hd_blocksize; - int size; + char s[260]; + void *h; + int c; + PcemHDC hd[7]; + FILE *f; + int hd_type, hd_format, hd_blocksize; + int size; - switch (message) { - case WX_INITDIALOG:h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT1")); - sprintf(s, "%i", 63); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT2")); - sprintf(s, "%i", 16); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT3")); - sprintf(s, "%i", 511); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + switch (message) { + case WX_INITDIALOG: + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT1")); + sprintf(s, "%i", 63); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT2")); + sprintf(s, "%i", 16); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT3")); + sprintf(s, "%i", 511); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDITC")); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)""); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDITC")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM) ""); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT4")); - sprintf(s, "%i", (((511 * 16 * 63) * 512) / 1024) / 1024); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT4")); + sprintf(s, "%i", (((511 * 16 * 63) * 512) / 1024) / 1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); -// hd_type = 0; - h = wx_getdlgitem(hdlg, WX_ID("IDC_HDTYPE")); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Custom type"); - for (c = 1; c <= 46; c++) { - sprintf(s, - "Type %02i : cylinders=%i, heads=%i, size=%iMB", - c, - hd_types[c - 1].cylinders, - hd_types[c - 1].heads, - (hd_types[c - 1].cylinders * hd_types[c - 1].heads * 17 * 512) / (1024 * 1024)); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); - } - wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); + // hd_type = 0; + h = wx_getdlgitem(hdlg, WX_ID("IDC_HDTYPE")); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "Custom type"); + for (c = 1; c <= 46; c++) { + sprintf(s, "Type %02i : cylinders=%i, heads=%i, size=%iMB", c, hd_types[c - 1].cylinders, + hd_types[c - 1].heads, + (hd_types[c - 1].cylinders * hd_types[c - 1].heads * 17 * 512) / (1024 * 1024)); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); + } + wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_HDFORMAT")); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Raw (.img)"); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Fixed-size VHD (.vhd)"); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Dynamic-size VHD (.vhd)"); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Differencing VHD (.vhd)"); - wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_HDFORMAT")); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "Raw (.img)"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "Fixed-size VHD (.vhd)"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "Dynamic-size VHD (.vhd)"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "Differencing VHD (.vhd)"); + wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_HDBLOCKSIZE")); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Large blocks (2 MB)"); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Small blocks (512 KB)"); - wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); - wx_sendmessage(h, WX_WM_SHOW, 0, (LONG_PARAM)0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_HDBLOCKSIZE")); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "Large blocks (2 MB)"); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "Small blocks (512 KB)"); + wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); + wx_sendmessage(h, WX_WM_SHOW, 0, (LONG_PARAM)0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_HDBLOCKSIZELABEL")); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)" "); + h = wx_getdlgitem(hdlg, WX_ID("IDC_HDBLOCKSIZELABEL")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM) " "); - return TRUE; - case WX_COMMAND: - if (wParam == wxID_OK) { - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDITC")); - wx_sendmessage(h, WX_WM_GETTEXT, 511, (LONG_PARAM)hd_new_name); - if (!hd_new_name[0]) { - wx_messagebox(hdlg, "Please enter a valid filename", "PCem error", WX_MB_OK); - return TRUE; - } - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT1")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd_new_spt); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT2")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd_new_hpc); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT3")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd_new_cyl); + return TRUE; + case WX_COMMAND: + if (wParam == wxID_OK) { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDITC")); + wx_sendmessage(h, WX_WM_GETTEXT, 511, (LONG_PARAM)hd_new_name); + if (!hd_new_name[0]) { + wx_messagebox(hdlg, "Please enter a valid filename", "PCem error", WX_MB_OK); + return TRUE; + } + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT1")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd_new_spt); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT2")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd_new_hpc); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT3")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd_new_cyl); - if (hd_new_spt > 63) { - wx_messagebox(hdlg, "Drive has too many sectors (maximum is 63)", "PCem error", WX_MB_OK); - return TRUE; - } - if (hd_new_hpc > 16) { - wx_messagebox(hdlg, "Drive has too many heads (maximum is 16)", "PCem error", WX_MB_OK); - return TRUE; - } - if (hd_new_cyl > MAX_CYLINDERS) { - char s[256]; - sprintf(s, "Drive has too many cylinders (maximum is %i)", MAX_CYLINDERS); - wx_messagebox(hdlg, s, "PCem error", WX_MB_OK); - return TRUE; - } + if (hd_new_spt > 63) { + wx_messagebox(hdlg, "Drive has too many sectors (maximum is 63)", "PCem error", WX_MB_OK); + return TRUE; + } + if (hd_new_hpc > 16) { + wx_messagebox(hdlg, "Drive has too many heads (maximum is 16)", "PCem error", WX_MB_OK); + return TRUE; + } + if (hd_new_cyl > MAX_CYLINDERS) { + char s[256]; + sprintf(s, "Drive has too many cylinders (maximum is %i)", MAX_CYLINDERS); + wx_messagebox(hdlg, s, "PCem error", WX_MB_OK); + return TRUE; + } - h = wx_getdlgitem(hdlg, WX_ID("IDC_HDFORMAT")); - hd_format = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_HDFORMAT")); + hd_format = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_HDBLOCKSIZE")); - hd_blocksize = (wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0) == 0) ? MVHD_BLOCK_LARGE : MVHD_BLOCK_SMALL; + h = wx_getdlgitem(hdlg, WX_ID("IDC_HDBLOCKSIZE")); + hd_blocksize = (wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0) == 0) ? MVHD_BLOCK_LARGE : MVHD_BLOCK_SMALL; - if (hd_format == 0) /* Raw .img */ - { - f = fopen64(hd_new_name, "wb"); - if (!f) { - wx_messagebox(hdlg, "Can't open file for write", "PCem error", WX_MB_OK); - return TRUE; - } - wx_progressdialog(hdlg, "PCem", "Creating drive, please wait...", create_drive_raw, f, hd_new_cyl * hd_new_hpc * hd_new_spt, &create_drive_pos); - } else if (hd_format == 1) /* Fixed VHD */ - { - if (!wx_progressdialog(hdlg, "PCem", "Creating drive, please wait...", create_drive_vhd_fixed, NULL, hd_new_cyl * hd_new_hpc * hd_new_spt, &create_drive_pos)) { - wx_messagebox(hdlg, "Can't create VHD", "PCem error", WX_MB_OK); - return TRUE; - } - } else if (hd_format == 2) /* Dynamic VHD */ - { - if (!create_drive_vhd_dynamic(hd_blocksize)) { - wx_messagebox(hdlg, "Can't create VHD", "PCem error", WX_MB_OK); - return TRUE; - } - } else if (hd_format == 3) /* Differencing VHD */ - { - if (!getfilewithcaption(hdlg, "VHD file (*.vhd)|*.vhd|All files (*.*)|*.*", "", "Select the parent VHD")) { - if (!create_drive_vhd_diff(openfilestring, hd_blocksize)) { - wx_messagebox(hdlg, "Can't create VHD", "PCem error", WX_MB_OK); - return TRUE; - } - } - wx_messagebox(hdlg, "Differencing VHD image created.\n\n" - "WARNING: Do not open or modify the parent image(s) while this file exists.", "PCem", WX_MB_OK); - } - if (hd_format != 3) { - wx_messagebox(hdlg, "Drive created, remember to partition and format the new drive.", "PCem", WX_MB_OK); - } + if (hd_format == 0) /* Raw .img */ + { + f = fopen64(hd_new_name, "wb"); + if (!f) { + wx_messagebox(hdlg, "Can't open file for write", "PCem error", WX_MB_OK); + return TRUE; + } + wx_progressdialog(hdlg, "PCem", "Creating drive, please wait...", create_drive_raw, f, + hd_new_cyl * hd_new_hpc * hd_new_spt, &create_drive_pos); + } else if (hd_format == 1) /* Fixed VHD */ + { + if (!wx_progressdialog(hdlg, "PCem", "Creating drive, please wait...", create_drive_vhd_fixed, + NULL, hd_new_cyl * hd_new_hpc * hd_new_spt, &create_drive_pos)) { + wx_messagebox(hdlg, "Can't create VHD", "PCem error", WX_MB_OK); + return TRUE; + } + } else if (hd_format == 2) /* Dynamic VHD */ + { + if (!create_drive_vhd_dynamic(hd_blocksize)) { + wx_messagebox(hdlg, "Can't create VHD", "PCem error", WX_MB_OK); + return TRUE; + } + } else if (hd_format == 3) /* Differencing VHD */ + { + if (!getfilewithcaption(hdlg, "VHD file (*.vhd)|*.vhd|All files (*.*)|*.*", "", + "Select the parent VHD")) { + if (!create_drive_vhd_diff(openfilestring, hd_blocksize)) { + wx_messagebox(hdlg, "Can't create VHD", "PCem error", WX_MB_OK); + return TRUE; + } + } + wx_messagebox(hdlg, + "Differencing VHD image created.\n\n" + "WARNING: Do not open or modify the parent image(s) while this file exists.", + "PCem", WX_MB_OK); + } + if (hd_format != 3) { + wx_messagebox(hdlg, "Drive created, remember to partition and format the new drive.", "PCem", + WX_MB_OK); + } - wx_enddialog(hdlg, 1); - return TRUE; - } else if (wParam == wxID_CANCEL) { - wx_enddialog(hdlg, 0); - return TRUE; - } else if (ID_IS("IDC_CFILE")) { - h = wx_getdlgitem(hdlg, WX_ID("IDC_HDFORMAT")); - hd_format = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - if (!getsfile(hdlg, - hd_format == 0 ? "Raw Hard disc image (*.img)|*.img|All files (*.*)|*.*" : "VHD file (*.vhd)|*.vhd|All files (*.*)|*.*", - "", - NULL, - hd_format == 0 ? "img" : "vhd")) { - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDITC")); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)openfilestring); - } - return TRUE; - } else if (ID_IS("IDC_EDIT1") || ID_IS("IDC_EDIT2") || ID_IS("IDC_EDIT3")) { - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT1")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - pclog("EDIT1: %s\n", s); - sscanf(s, "%i", &hd[0].spt); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT2")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - pclog("EDIT2: %s\n", s); - sscanf(s, "%i", &hd[0].hpc); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT3")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - pclog("EDIT3: %s\n", s); - sscanf(s, "%i", &hd[0].tracks); + wx_enddialog(hdlg, 1); + return TRUE; + } else if (wParam == wxID_CANCEL) { + wx_enddialog(hdlg, 0); + return TRUE; + } else if (ID_IS("IDC_CFILE")) { + h = wx_getdlgitem(hdlg, WX_ID("IDC_HDFORMAT")); + hd_format = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + if (!getsfile(hdlg, + hd_format == 0 ? "Raw Hard disc image (*.img)|*.img|All files (*.*)|*.*" + : "VHD file (*.vhd)|*.vhd|All files (*.*)|*.*", + "", NULL, hd_format == 0 ? "img" : "vhd")) { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDITC")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)openfilestring); + } + return TRUE; + } else if (ID_IS("IDC_EDIT1") || ID_IS("IDC_EDIT2") || ID_IS("IDC_EDIT3")) { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT1")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + pclog("EDIT1: %s\n", s); + sscanf(s, "%i", &hd[0].spt); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT2")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + pclog("EDIT2: %s\n", s); + sscanf(s, "%i", &hd[0].hpc); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT3")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + pclog("EDIT3: %s\n", s); + sscanf(s, "%i", &hd[0].tracks); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT4")); - sprintf(s, "%i", (int)(((((uint64_t)hd[0].tracks * (uint64_t)hd[0].hpc) * (uint64_t)hd[0].spt) * 512) / 1024) / 1024); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT4")); + sprintf(s, "%i", + (int)(((((uint64_t)hd[0].tracks * (uint64_t)hd[0].hpc) * (uint64_t)hd[0].spt) * 512) / 1024) / + 1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - hd_type = 0; - for (c = 1; c <= 46; c++) { - pclog("Compare %i,%i %i,%i %i,%i\n", hd[0].spt, 17, hd[0].hpc, hd_types[c - 1].heads, hd[0].tracks, hd_types[c - 1].cylinders); - if (hd[0].spt == 17 && hd[0].hpc == hd_types[c - 1].heads && hd[0].tracks == hd_types[c - 1].cylinders) { - hd_type = c; - break; - } - } - h = wx_getdlgitem(hdlg, WX_ID("IDC_HDTYPE")); - wx_sendmessage(h, WX_CB_SETCURSEL, hd_type, 0); + hd_type = 0; + for (c = 1; c <= 46; c++) { + pclog("Compare %i,%i %i,%i %i,%i\n", hd[0].spt, 17, hd[0].hpc, hd_types[c - 1].heads, + hd[0].tracks, hd_types[c - 1].cylinders); + if (hd[0].spt == 17 && hd[0].hpc == hd_types[c - 1].heads && + hd[0].tracks == hd_types[c - 1].cylinders) { + hd_type = c; + break; + } + } + h = wx_getdlgitem(hdlg, WX_ID("IDC_HDTYPE")); + wx_sendmessage(h, WX_CB_SETCURSEL, hd_type, 0); - return TRUE; - } else if (ID_IS("IDC_EDIT4")) { - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT4")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - pclog("EDIT4: %s\n", s); - sscanf(s, "%i", &size); + return TRUE; + } else if (ID_IS("IDC_EDIT4")) { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT4")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + pclog("EDIT4: %s\n", s); + sscanf(s, "%i", &size); - hd[0].spt = 63; - hd[0].hpc = 16; - hd[0].tracks = (int)(((int64_t)size * 1024 * 1024) / (16 * 63 * 512)); + hd[0].spt = 63; + hd[0].hpc = 16; + hd[0].tracks = (int)(((int64_t)size * 1024 * 1024) / (16 * 63 * 512)); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT1")); - sprintf(s, "%i", 63); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT2")); - sprintf(s, "%i", 16); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT3")); - sprintf(s, "%i", hd[0].tracks); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - } else if (ID_IS("IDC_HDTYPE")) { - h = wx_getdlgitem(hdlg, WX_ID("IDC_HDTYPE")); - hd_type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - if (hd_type) { - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT3")); - sprintf(s, "%i", hd_types[hd_type - 1].cylinders); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT2")); - sprintf(s, "%i", hd_types[hd_type - 1].heads); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT1")); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)"17"); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT1")); + sprintf(s, "%i", 63); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT2")); + sprintf(s, "%i", 16); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT3")); + sprintf(s, "%i", hd[0].tracks); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + } else if (ID_IS("IDC_HDTYPE")) { + h = wx_getdlgitem(hdlg, WX_ID("IDC_HDTYPE")); + hd_type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + if (hd_type) { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT3")); + sprintf(s, "%i", hd_types[hd_type - 1].cylinders); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT2")); + sprintf(s, "%i", hd_types[hd_type - 1].heads); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT1")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM) "17"); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT4")); - sprintf(s, "%i", (int)(((uint64_t)hd_types[hd_type - 1].cylinders * hd_types[hd_type - 1].heads * 17 * 512) / 1024) / 1024); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - } - return TRUE; - } else if (ID_IS("IDC_HDFORMAT")) { - h = wx_getdlgitem(hdlg, WX_ID("IDC_HDFORMAT")); - hd_format = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - if (hd_format == 3) /* They switched to a dynamic VHD; disable the geometry fields. */ - { - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT1")); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)"(use parent)"); - wx_sendmessage(h, WX_WM_ENABLE, 0, (LONG_PARAM)0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT2")); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)"(use parent)"); - wx_sendmessage(h, WX_WM_ENABLE, 0, (LONG_PARAM)0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT3")); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)"(use parent)"); - wx_sendmessage(h, WX_WM_ENABLE, 0, (LONG_PARAM)0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT4")); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)"(use parent)"); - wx_sendmessage(h, WX_WM_ENABLE, 0, (LONG_PARAM)0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT4")); + sprintf(s, "%i", + (int)(((uint64_t)hd_types[hd_type - 1].cylinders * hd_types[hd_type - 1].heads * 17 * + 512) / + 1024) / + 1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + } + return TRUE; + } else if (ID_IS("IDC_HDFORMAT")) { + h = wx_getdlgitem(hdlg, WX_ID("IDC_HDFORMAT")); + hd_format = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + if (hd_format == 3) /* They switched to a dynamic VHD; disable the geometry fields. */ + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT1")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM) "(use parent)"); + wx_sendmessage(h, WX_WM_ENABLE, 0, (LONG_PARAM)0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT2")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM) "(use parent)"); + wx_sendmessage(h, WX_WM_ENABLE, 0, (LONG_PARAM)0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT3")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM) "(use parent)"); + wx_sendmessage(h, WX_WM_ENABLE, 0, (LONG_PARAM)0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT4")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM) "(use parent)"); + wx_sendmessage(h, WX_WM_ENABLE, 0, (LONG_PARAM)0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_HDTYPE")); - wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); - wx_sendmessage(h, WX_WM_ENABLE, 0, (LONG_PARAM)0); - } else /* Restore geometry fields if necessary. */ - { - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT1")); - wx_sendmessage(h, WX_WM_GETTEXT, 0, (LONG_PARAM)s); - if (!strncmp(s, "(use parent)", 12)) { - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)"63"); - wx_sendmessage(h, WX_WM_ENABLE, 0, (LONG_PARAM)1); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT2")); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)"16"); - wx_sendmessage(h, WX_WM_ENABLE, 0, (LONG_PARAM)1); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT3")); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)"511"); - wx_sendmessage(h, WX_WM_ENABLE, 0, (LONG_PARAM)1); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT4")); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)"251"); - wx_sendmessage(h, WX_WM_ENABLE, 0, (LONG_PARAM)1); + h = wx_getdlgitem(hdlg, WX_ID("IDC_HDTYPE")); + wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); + wx_sendmessage(h, WX_WM_ENABLE, 0, (LONG_PARAM)0); + } else /* Restore geometry fields if necessary. */ + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT1")); + wx_sendmessage(h, WX_WM_GETTEXT, 0, (LONG_PARAM)s); + if (!strncmp(s, "(use parent)", 12)) { + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM) "63"); + wx_sendmessage(h, WX_WM_ENABLE, 0, (LONG_PARAM)1); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT2")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM) "16"); + wx_sendmessage(h, WX_WM_ENABLE, 0, (LONG_PARAM)1); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT3")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM) "511"); + wx_sendmessage(h, WX_WM_ENABLE, 0, (LONG_PARAM)1); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT4")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM) "251"); + wx_sendmessage(h, WX_WM_ENABLE, 0, (LONG_PARAM)1); - h = wx_getdlgitem(hdlg, WX_ID("IDC_HDTYPE")); - wx_sendmessage(h, WX_WM_ENABLE, 0, (LONG_PARAM)1); - } - } + h = wx_getdlgitem(hdlg, WX_ID("IDC_HDTYPE")); + wx_sendmessage(h, WX_WM_ENABLE, 0, (LONG_PARAM)1); + } + } - if (hd_format == 2 || hd_format == 3) /* For dynamic and diff VHDs, show the block size dropdown. */ - { - h = wx_getdlgitem(hdlg, WX_ID("IDC_HDBLOCKSIZELABEL")); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)"Block size:"); - h = wx_getdlgitem(hdlg, WX_ID("IDC_HDBLOCKSIZE")); - wx_sendmessage(h, WX_WM_SHOW, 0, (LONG_PARAM)1); - } else /* Hide it otherwise. */ - { - h = wx_getdlgitem(hdlg, WX_ID("IDC_HDBLOCKSIZELABEL")); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)" "); - h = wx_getdlgitem(hdlg, WX_ID("IDC_HDBLOCKSIZE")); - wx_sendmessage(h, WX_WM_SHOW, 0, (LONG_PARAM)0); - } + if (hd_format == 2 || hd_format == 3) /* For dynamic and diff VHDs, show the block size dropdown. */ + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_HDBLOCKSIZELABEL")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM) "Block size:"); + h = wx_getdlgitem(hdlg, WX_ID("IDC_HDBLOCKSIZE")); + wx_sendmessage(h, WX_WM_SHOW, 0, (LONG_PARAM)1); + } else /* Hide it otherwise. */ + { + h = wx_getdlgitem(hdlg, WX_ID("IDC_HDBLOCKSIZELABEL")); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM) " "); + h = wx_getdlgitem(hdlg, WX_ID("IDC_HDBLOCKSIZE")); + wx_sendmessage(h, WX_WM_SHOW, 0, (LONG_PARAM)0); + } - return TRUE; - } - break; - - } - return FALSE; + return TRUE; + } + break; + } + return FALSE; } static int hdsize_dlgproc(void *hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) { - char s[260]; - void *h; - PcemHDC hd[2]; - int c; + char s[260]; + void *h; + PcemHDC hd[2]; + int c; - switch (message) { - case WX_INITDIALOG:h = wx_getdlgitem(hdlg, WX_ID("IDC_HDTYPE")); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"Custom type"); - for (c = 1; c <= 46; c++) { - sprintf(s, - "Type %02i : cylinders=%i, heads=%i, size=%iMB", - c, - hd_types[c - 1].cylinders, - hd_types[c - 1].heads, - (hd_types[c - 1].cylinders * hd_types[c - 1].heads * 17 * 512) / (1024 * 1024)); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); - } - wx_sendmessage(h, WX_CB_SETCURSEL, hd_new_type, 0); + switch (message) { + case WX_INITDIALOG: + h = wx_getdlgitem(hdlg, WX_ID("IDC_HDTYPE")); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "Custom type"); + for (c = 1; c <= 46; c++) { + sprintf(s, "Type %02i : cylinders=%i, heads=%i, size=%iMB", c, hd_types[c - 1].cylinders, + hd_types[c - 1].heads, + (hd_types[c - 1].cylinders * hd_types[c - 1].heads * 17 * 512) / (1024 * 1024)); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); + } + wx_sendmessage(h, WX_CB_SETCURSEL, hd_new_type, 0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT1")); - sprintf(s, "%i", hd_new_spt); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT2")); - sprintf(s, "%i", hd_new_hpc); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT3")); - sprintf(s, "%i", hd_new_cyl); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT1")); + sprintf(s, "%i", hd_new_spt); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT2")); + sprintf(s, "%i", hd_new_hpc); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT3")); + sprintf(s, "%i", hd_new_cyl); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT1")); - sprintf(s, "%imb", (int)((((uint64_t)hd_new_spt * (uint64_t)hd_new_hpc * (uint64_t)hd_new_cyl) * 512) / 1024) / 1024); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT1")); + sprintf(s, "%imb", + (int)((((uint64_t)hd_new_spt * (uint64_t)hd_new_hpc * (uint64_t)hd_new_cyl) * 512) / 1024) / 1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - return TRUE; - case WX_COMMAND: - if (wParam == wxID_OK) { - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT1")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd_new_spt); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT2")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd_new_hpc); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT3")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd_new_cyl); + return TRUE; + case WX_COMMAND: + if (wParam == wxID_OK) { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT1")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd_new_spt); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT2")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd_new_hpc); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT3")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd_new_cyl); - if (hd_new_spt > 63) { - wx_messagebox(hdlg, "Drive has too many sectors (maximum is 63)", "PCem error", WX_MB_OK); - return TRUE; - } - if (hd_new_hpc > 16) { - wx_messagebox(hdlg, "Drive has too many heads (maximum is 16)", "PCem error", WX_MB_OK); - return TRUE; - } - if (hd_new_cyl > MAX_CYLINDERS) { - char s[256]; - sprintf(s, "Drive has too many cylinders (maximum is %i)", MAX_CYLINDERS); - wx_messagebox(hdlg, s, "PCem error", WX_MB_OK); - return TRUE; - } + if (hd_new_spt > 63) { + wx_messagebox(hdlg, "Drive has too many sectors (maximum is 63)", "PCem error", WX_MB_OK); + return TRUE; + } + if (hd_new_hpc > 16) { + wx_messagebox(hdlg, "Drive has too many heads (maximum is 16)", "PCem error", WX_MB_OK); + return TRUE; + } + if (hd_new_cyl > MAX_CYLINDERS) { + char s[256]; + sprintf(s, "Drive has too many cylinders (maximum is %i)", MAX_CYLINDERS); + wx_messagebox(hdlg, s, "PCem error", WX_MB_OK); + return TRUE; + } - wx_enddialog(hdlg, 1); - return TRUE; - } else if (wParam == wxID_CANCEL) { - wx_enddialog(hdlg, 0); - return TRUE; - } else if (ID_IS("IDC_EDIT1") || ID_IS("IDC_EDIT2") || ID_IS("IDC_EDIT3")) { - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT1")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[0].spt); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT2")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[0].hpc); - h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT3")); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hd[0].tracks); + wx_enddialog(hdlg, 1); + return TRUE; + } else if (wParam == wxID_CANCEL) { + wx_enddialog(hdlg, 0); + return TRUE; + } else if (ID_IS("IDC_EDIT1") || ID_IS("IDC_EDIT2") || ID_IS("IDC_EDIT3")) { + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT1")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[0].spt); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT2")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[0].hpc); + h = wx_getdlgitem(hdlg, WX_ID("IDC_EDIT3")); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hd[0].tracks); - h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT1")); - sprintf(s, "%imb", (int)(((((uint64_t)hd[0].tracks * (uint64_t)hd[0].hpc) * (uint64_t)hd[0].spt) * 512) / 1024) / 1024); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - return TRUE; - } - - } - return FALSE; + h = wx_getdlgitem(hdlg, WX_ID("IDC_TEXT1")); + sprintf(s, "%imb", + (int)(((((uint64_t)hd[0].tracks * (uint64_t)hd[0].hpc) * (uint64_t)hd[0].spt) * 512) / 1024) / + 1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + return TRUE; + } + } + return FALSE; } int hdconf_init(void *hdlg) { - int c; + int c; - for (c = 0; c < 7; c++) { - char s[260]; - void *h; + for (c = 0; c < 7; c++) { + char s[260]; + void *h; - sprintf(s, "IDC_EDIT_SPT[%i]", c); - h = wx_getdlgitem(hdlg, WX_ID(s)); - sprintf(s, "%i", hdc[c].spt); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - sprintf(s, "IDC_EDIT_HPC[%i]", c); - h = wx_getdlgitem(hdlg, WX_ID(s)); - sprintf(s, "%i", hdc[c].hpc); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - sprintf(s, "IDC_EDIT_CYL[%i]", c); - h = wx_getdlgitem(hdlg, WX_ID(s)); - sprintf(s, "%i", hdc[c].tracks); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - sprintf(s, "IDC_EDIT_FN[%i]", c); - h = wx_getdlgitem(hdlg, WX_ID(s)); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)ide_fn[c]); + sprintf(s, "IDC_EDIT_SPT[%i]", c); + h = wx_getdlgitem(hdlg, WX_ID(s)); + sprintf(s, "%i", hdc[c].spt); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + sprintf(s, "IDC_EDIT_HPC[%i]", c); + h = wx_getdlgitem(hdlg, WX_ID(s)); + sprintf(s, "%i", hdc[c].hpc); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + sprintf(s, "IDC_EDIT_CYL[%i]", c); + h = wx_getdlgitem(hdlg, WX_ID(s)); + sprintf(s, "%i", hdc[c].tracks); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + sprintf(s, "IDC_EDIT_FN[%i]", c); + h = wx_getdlgitem(hdlg, WX_ID(s)); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)ide_fn[c]); - sprintf(s, "IDC_TEXT_SIZE[%i]", c); - h = wx_getdlgitem(hdlg, WX_ID(s)); - sprintf(s, "%imb", (int)(((((uint64_t)hdc[c].tracks * (uint64_t)hdc[c].hpc) * (uint64_t)hdc[c].spt) * 512) / 1024) / 1024); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + sprintf(s, "IDC_TEXT_SIZE[%i]", c); + h = wx_getdlgitem(hdlg, WX_ID(s)); + sprintf(s, "%imb", + (int)(((((uint64_t)hdc[c].tracks * (uint64_t)hdc[c].hpc) * (uint64_t)hdc[c].spt) * 512) / 1024) / 1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + } - } - - return hdconf_update(hdlg); + return hdconf_update(hdlg); } int hdconf_update(void *hdlg) { - char s[260]; - void *h; + char s[260]; + void *h; - int is_mfm = hdd_controller_selected_is_mfm(hdlg); + int is_mfm = hdd_controller_selected_is_mfm(hdlg); - update_hdd_cdrom(hdlg); + update_hdd_cdrom(hdlg); - int i; - for (i = 0; i < 7; ++i) { - sprintf(s, "IDC_HDD_LABEL[%d]", i * 10); - wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !is_mfm); - sprintf(s, "IDC_COMBODRIVETYPE[%d]", i); - h = wx_getdlgitem(hdlg, WX_ID(s)); - wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !is_mfm); - } + int i; + for (i = 0; i < 7; ++i) { + sprintf(s, "IDC_HDD_LABEL[%d]", i * 10); + wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !is_mfm); + sprintf(s, "IDC_COMBODRIVETYPE[%d]", i); + h = wx_getdlgitem(hdlg, WX_ID(s)); + wx_enablewindow(wx_getdlgitem(hdlg, WX_ID(s)), !is_mfm); + } - h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGUREHDD")); - if (hdd_controller_selected_has_config(hdlg)) - wx_enablewindow(h, TRUE); - else - wx_enablewindow(h, FALSE); + h = wx_getdlgitem(hdlg, WX_ID("IDC_CONFIGUREHDD")); + if (hdd_controller_selected_has_config(hdlg)) + wx_enablewindow(h, TRUE); + else + wx_enablewindow(h, FALSE); - return TRUE; + return TRUE; } static int hd_eject(void *hdlg, int drive) { - char s[80]; + char s[80]; - ide_fn[drive][0] = 0; - sprintf(s, "IDC_EDIT_SPT[%i]", drive); - wx_setdlgitemtext(hdlg, WX_ID(s), "0"); - sprintf(s, "IDC_EDIT_HPC[%i]", drive); - wx_setdlgitemtext(hdlg, WX_ID(s), "0"); - sprintf(s, "IDC_EDIT_CYL[%i]", drive); - wx_setdlgitemtext(hdlg, WX_ID(s), "0"); - sprintf(s, "IDC_EDIT_FN[%i]", drive); - wx_setdlgitemtext(hdlg, WX_ID(s), ""); - hd_changed = 1; + ide_fn[drive][0] = 0; + sprintf(s, "IDC_EDIT_SPT[%i]", drive); + wx_setdlgitemtext(hdlg, WX_ID(s), "0"); + sprintf(s, "IDC_EDIT_HPC[%i]", drive); + wx_setdlgitemtext(hdlg, WX_ID(s), "0"); + sprintf(s, "IDC_EDIT_CYL[%i]", drive); + wx_setdlgitemtext(hdlg, WX_ID(s), "0"); + sprintf(s, "IDC_EDIT_FN[%i]", drive); + wx_setdlgitemtext(hdlg, WX_ID(s), ""); + hd_changed = 1; - return TRUE; + return TRUE; } static int hd_new(void *hdlg, int drive) { - if (wx_dialogbox(hdlg, "HdNewDlg", hdnew_dlgproc) == 1) { - char s[80]; - char id[80]; - void *h; + if (wx_dialogbox(hdlg, "HdNewDlg", hdnew_dlgproc) == 1) { + char s[80]; + char id[80]; + void *h; - sprintf(id, "IDC_EDIT_SPT[%i]", drive); - h = wx_getdlgitem(hdlg, WX_ID(id)); - sprintf(s, "%i", hd_new_spt); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - sprintf(id, "IDC_EDIT_HPC[%i]", drive); - h = wx_getdlgitem(hdlg, WX_ID(id)); - sprintf(s, "%i", hd_new_hpc); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - sprintf(id, "IDC_EDIT_CYL[%i]", drive); - h = wx_getdlgitem(hdlg, WX_ID(id)); - sprintf(s, "%i", hd_new_cyl); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - sprintf(id, "IDC_EDIT_FN[%i]", drive); - h = wx_getdlgitem(hdlg, WX_ID(id)); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)hd_new_name); + sprintf(id, "IDC_EDIT_SPT[%i]", drive); + h = wx_getdlgitem(hdlg, WX_ID(id)); + sprintf(s, "%i", hd_new_spt); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + sprintf(id, "IDC_EDIT_HPC[%i]", drive); + h = wx_getdlgitem(hdlg, WX_ID(id)); + sprintf(s, "%i", hd_new_hpc); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + sprintf(id, "IDC_EDIT_CYL[%i]", drive); + h = wx_getdlgitem(hdlg, WX_ID(id)); + sprintf(s, "%i", hd_new_cyl); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + sprintf(id, "IDC_EDIT_FN[%i]", drive); + h = wx_getdlgitem(hdlg, WX_ID(id)); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)hd_new_name); - sprintf(id, "IDC_TEXT_SIZE[%i]", drive); - h = wx_getdlgitem(hdlg, WX_ID(id)); - sprintf(s, "%imb", (int)(((((uint64_t)hd_new_cyl * (uint64_t)hd_new_hpc) * (uint64_t)hd_new_spt) * 512) / 1024) / 1024); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + sprintf(id, "IDC_TEXT_SIZE[%i]", drive); + h = wx_getdlgitem(hdlg, WX_ID(id)); + sprintf(s, "%imb", + (int)(((((uint64_t)hd_new_cyl * (uint64_t)hd_new_hpc) * (uint64_t)hd_new_spt) * 512) / 1024) / 1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - hd_changed = 1; - } - return TRUE; + hd_changed = 1; + } + return TRUE; } static int hd_file(void *hdlg, int drive) { - if (!getfile(hdlg, "Hard disc image (*.img;*.vhd)|*.img;*.vhd|All files (*.*)|*.*", "")) { - off64_t sz; - FILE *f = fopen64(openfilestring, "rb"); - if (!f) { - wx_messagebox(hdlg, "Can't open file for read", "PCem error", WX_MB_OK); - return TRUE; - } + if (!getfile(hdlg, "Hard disc image (*.img;*.vhd)|*.img;*.vhd|All files (*.*)|*.*", "")) { + off64_t sz; + FILE *f = fopen64(openfilestring, "rb"); + if (!f) { + wx_messagebox(hdlg, "Can't open file for read", "PCem error", WX_MB_OK); + return TRUE; + } - if (mvhd_file_is_vhd(f)) { - fclose(f); - int vhdError = 0; - MVHDMeta *vhd = mvhd_open(openfilestring, false, &vhdError); - if (vhd == NULL) { - wx_messagebox(hdlg, mvhd_strerr(vhdError), "PCem error", WX_MB_OK); - return TRUE; - } else if (vhdError == MVHD_ERR_TIMESTAMP) { - const char ts_warning[] = - "WARNING: VHD PARENT/CHILD TIMESTAMPS DO NOT MATCH!\n\n" - "This could indicate that the parent image was modified after this VHD was created.\n\n" - "This could also happen if the VHD files were moved/copied, or the differencing VHD was created with DiskPart.\n\n" - "Do you wish to fix this error after a file copy or DiskPart creation?"; - int wx_res = wx_messagebox(hdlg, ts_warning, "PCem error", WX_MB_NODEFAULT); - if (wx_res == WX_MB_YES) { - int ts_res = mvhd_diff_update_par_timestamp(vhd, &vhdError); - if (ts_res != 0) { - wx_messagebox(hdlg, "Can't fix VHD timestamps", "PCem error", WX_MB_OK); - mvhd_close(vhd); - return TRUE; - } - } else { - mvhd_close(vhd); - return TRUE; - } + if (mvhd_file_is_vhd(f)) { + fclose(f); + int vhdError = 0; + MVHDMeta *vhd = mvhd_open(openfilestring, false, &vhdError); + if (vhd == NULL) { + wx_messagebox(hdlg, mvhd_strerr(vhdError), "PCem error", WX_MB_OK); + return TRUE; + } else if (vhdError == MVHD_ERR_TIMESTAMP) { + const char ts_warning[] = + "WARNING: VHD PARENT/CHILD TIMESTAMPS DO NOT MATCH!\n\n" + "This could indicate that the parent image was modified after this VHD was created.\n\n" + "This could also happen if the VHD files were moved/copied, or the differencing VHD was " + "created with DiskPart.\n\n" + "Do you wish to fix this error after a file copy or DiskPart creation?"; + int wx_res = wx_messagebox(hdlg, ts_warning, "PCem error", WX_MB_NODEFAULT); + if (wx_res == WX_MB_YES) { + int ts_res = mvhd_diff_update_par_timestamp(vhd, &vhdError); + if (ts_res != 0) { + wx_messagebox(hdlg, "Can't fix VHD timestamps", "PCem error", WX_MB_OK); + mvhd_close(vhd); + return TRUE; + } + } else { + mvhd_close(vhd); + return TRUE; + } + } + MVHDGeom geom = mvhd_get_geometry(vhd); + hd_new_cyl = geom.cyl; + hd_new_hpc = geom.heads; + hd_new_spt = geom.spt; + hd_new_type = 0; + adjust_vhd_geometry_for_pcem(); + mvhd_close(vhd); + } else { + fseeko64(f, -1, SEEK_END); + sz = ftello64(f) + 1; + fclose(f); + check_hd_type(hdlg, sz); + } - } - MVHDGeom geom = mvhd_get_geometry(vhd); - hd_new_cyl = geom.cyl; - hd_new_hpc = geom.heads; - hd_new_spt = geom.spt; - hd_new_type = 0; - adjust_vhd_geometry_for_pcem(); - mvhd_close(vhd); - } else { - fseeko64(f, -1, SEEK_END); - sz = ftello64(f) + 1; - fclose(f); - check_hd_type(hdlg, sz); - } + if (wx_dialogbox(hdlg, "HdSizeDlg", hdsize_dlgproc) == 1) { + char s[80]; + char id[80]; + void *h; - if (wx_dialogbox(hdlg, "HdSizeDlg", hdsize_dlgproc) == 1) { - char s[80]; - char id[80]; - void *h; + sprintf(id, "IDC_EDIT_SPT[%i]", drive); + h = wx_getdlgitem(hdlg, WX_ID(id)); + sprintf(s, "%i", hd_new_spt); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + sprintf(id, "IDC_EDIT_HPC[%i]", drive); + h = wx_getdlgitem(hdlg, WX_ID(id)); + sprintf(s, "%i", hd_new_hpc); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + sprintf(id, "IDC_EDIT_CYL[%i]", drive); + h = wx_getdlgitem(hdlg, WX_ID(id)); + sprintf(s, "%i", hd_new_cyl); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + sprintf(id, "IDC_EDIT_FN[%i]", drive); + h = wx_getdlgitem(hdlg, WX_ID(id)); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)openfilestring); - sprintf(id, "IDC_EDIT_SPT[%i]", drive); - h = wx_getdlgitem(hdlg, WX_ID(id)); - sprintf(s, "%i", hd_new_spt); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - sprintf(id, "IDC_EDIT_HPC[%i]", drive); - h = wx_getdlgitem(hdlg, WX_ID(id)); - sprintf(s, "%i", hd_new_hpc); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - sprintf(id, "IDC_EDIT_CYL[%i]", drive); - h = wx_getdlgitem(hdlg, WX_ID(id)); - sprintf(s, "%i", hd_new_cyl); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - sprintf(id, "IDC_EDIT_FN[%i]", drive); - h = wx_getdlgitem(hdlg, WX_ID(id)); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)openfilestring); + sprintf(id, "IDC_TEXT_SIZE[%i]", drive); + h = wx_getdlgitem(hdlg, WX_ID(id)); + sprintf(s, "%imb", + (int)(((((uint64_t)hd_new_cyl * (uint64_t)hd_new_hpc) * (uint64_t)hd_new_spt) * 512) / 1024) / + 1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - sprintf(id, "IDC_TEXT_SIZE[%i]", drive); - h = wx_getdlgitem(hdlg, WX_ID(id)); - sprintf(s, "%imb", (int)(((((uint64_t)hd_new_cyl * (uint64_t)hd_new_hpc) * (uint64_t)hd_new_spt) * 512) / 1024) / 1024); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - - hd_changed = 1; - } - } - return TRUE; + hd_changed = 1; + } + } + return TRUE; } static int hd_edit(void *hdlg, int drive) { - char s[80]; - char id[80]; - void *h; - int spt, hpc, tracks; + char s[80]; + char id[80]; + void *h; + int spt, hpc, tracks; - sprintf(id, "IDC_EDIT_SPT[%i]", drive); - h = wx_getdlgitem(hdlg, WX_ID(id)); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &spt); - sprintf(id, "IDC_EDIT_HPC[%i]", drive); - h = wx_getdlgitem(hdlg, WX_ID(id)); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &hpc); - sprintf(id, "IDC_EDIT_CYL[%i]", drive); - h = wx_getdlgitem(hdlg, WX_ID(id)); - wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); - sscanf(s, "%i", &tracks); + sprintf(id, "IDC_EDIT_SPT[%i]", drive); + h = wx_getdlgitem(hdlg, WX_ID(id)); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &spt); + sprintf(id, "IDC_EDIT_HPC[%i]", drive); + h = wx_getdlgitem(hdlg, WX_ID(id)); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &hpc); + sprintf(id, "IDC_EDIT_CYL[%i]", drive); + h = wx_getdlgitem(hdlg, WX_ID(id)); + wx_sendmessage(h, WX_WM_GETTEXT, 255, (LONG_PARAM)s); + sscanf(s, "%i", &tracks); - sprintf(id, "IDC_TEXT_SIZE[%i]", drive); - h = wx_getdlgitem(hdlg, WX_ID(id)); - sprintf(s, "%imb", ((((tracks * hpc) * spt) * 512) / 1024) / 1024); - wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); + sprintf(id, "IDC_TEXT_SIZE[%i]", drive); + h = wx_getdlgitem(hdlg, WX_ID(id)); + sprintf(s, "%imb", ((((tracks * hpc) * spt) * 512) / 1024) / 1024); + wx_sendmessage(h, WX_WM_SETTEXT, 0, (LONG_PARAM)s); - return TRUE; + return TRUE; } static int hd_combodrivetype(void *hdlg, int drive) { - int type; - char id[80]; - void *h; + int type; + char id[80]; + void *h; - sprintf(id, "IDC_COMBODRIVETYPE[%i]", drive); - h = wx_getdlgitem(hdlg, WX_ID(id)); - type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + sprintf(id, "IDC_COMBODRIVETYPE[%i]", drive); + h = wx_getdlgitem(hdlg, WX_ID(id)); + type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - switch (type) { - case 0: /*Hard drive*/ - if (new_cdrom_channel == drive) - new_cdrom_channel = -1; - if (new_zip_channel == drive) - new_zip_channel = -1; - break; - case 1: /*CD-ROM*/ - new_cdrom_channel = drive; - if (new_zip_channel == drive) - new_zip_channel = -1; - break; - case 2: /*Zip*/ - new_zip_channel = drive; - if (new_cdrom_channel == drive) - new_cdrom_channel = -1; - break; - } - update_hdd_cdrom(hdlg); - return TRUE; + switch (type) { + case 0: /*Hard drive*/ + if (new_cdrom_channel == drive) + new_cdrom_channel = -1; + if (new_zip_channel == drive) + new_zip_channel = -1; + break; + case 1: /*CD-ROM*/ + new_cdrom_channel = drive; + if (new_zip_channel == drive) + new_zip_channel = -1; + break; + case 2: /*Zip*/ + new_zip_channel = drive; + if (new_cdrom_channel == drive) + new_cdrom_channel = -1; + break; + } + update_hdd_cdrom(hdlg); + return TRUE; } int hdconf_dlgproc(void *hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) { - switch (message) { - case WX_INITDIALOG:pause = 1; - return hdconf_init(hdlg); + switch (message) { + case WX_INITDIALOG: + pause = 1; + return hdconf_init(hdlg); - case WX_COMMAND: - if (ID_IS("IDC_EJECT[0]")) - return hd_eject(hdlg, 0); - else if (ID_IS("IDC_EJECT[1]")) - return hd_eject(hdlg, 1); - else if (ID_IS("IDC_EJECT[2]")) - return hd_eject(hdlg, 2); - else if (ID_IS("IDC_EJECT[3]")) - return hd_eject(hdlg, 3); - else if (ID_IS("IDC_EJECT[4]")) - return hd_eject(hdlg, 4); - else if (ID_IS("IDC_EJECT[5]")) - return hd_eject(hdlg, 5); - else if (ID_IS("IDC_EJECT[6]")) - return hd_eject(hdlg, 6); - else if (ID_IS("IDC_NEW[0]")) - return hd_new(hdlg, 0); - else if (ID_IS("IDC_NEW[1]")) - return hd_new(hdlg, 1); - else if (ID_IS("IDC_NEW[2]")) - return hd_new(hdlg, 2); - else if (ID_IS("IDC_NEW[3]")) - return hd_new(hdlg, 3); - else if (ID_IS("IDC_NEW[4]")) - return hd_new(hdlg, 4); - else if (ID_IS("IDC_NEW[5]")) - return hd_new(hdlg, 5); - else if (ID_IS("IDC_NEW[6]")) - return hd_new(hdlg, 6); - else if (ID_IS("IDC_FILE[0]")) - return hd_file(hdlg, 0); - else if (ID_IS("IDC_FILE[1]")) - return hd_file(hdlg, 1); - else if (ID_IS("IDC_FILE[2]")) - return hd_file(hdlg, 2); - else if (ID_IS("IDC_FILE[3]")) - return hd_file(hdlg, 3); - else if (ID_IS("IDC_FILE[4]")) - return hd_file(hdlg, 4); - else if (ID_IS("IDC_FILE[5]")) - return hd_file(hdlg, 5); - else if (ID_IS("IDC_FILE[6]")) - return hd_file(hdlg, 6); - else if (ID_IS("IDC_EDIT_SPT[0]") || ID_IS("IDC_EDIT_HPC[0]") || ID_IS("IDC_EDIT_CYL[0]")) - return hd_edit(hdlg, 0); - else if (ID_IS("IDC_EDIT_SPT[1]") || ID_IS("IDC_EDIT_HPC[1]") || ID_IS("IDC_EDIT_CYL[1]")) - return hd_edit(hdlg, 1); - else if (ID_IS("IDC_EDIT_SPT[2]") || ID_IS("IDC_EDIT_HPC[2]") || ID_IS("IDC_EDIT_CYL[2]")) - return hd_edit(hdlg, 2); - else if (ID_IS("IDC_EDIT_SPT[3]") || ID_IS("IDC_EDIT_HPC[3]") || ID_IS("IDC_EDIT_CYL[3]")) - return hd_edit(hdlg, 3); - else if (ID_IS("IDC_EDIT_SPT[4]") || ID_IS("IDC_EDIT_HPC[4]") || ID_IS("IDC_EDIT_CYL[4]")) - return hd_edit(hdlg, 4); - else if (ID_IS("IDC_EDIT_SPT[5]") || ID_IS("IDC_EDIT_HPC[5]") || ID_IS("IDC_EDIT_CYL[5]")) - return hd_edit(hdlg, 5); - else if (ID_IS("IDC_EDIT_SPT[6]") || ID_IS("IDC_EDIT_HPC[6]") || ID_IS("IDC_EDIT_CYL[6]")) - return hd_edit(hdlg, 6); - else if (ID_IS("IDC_COMBODRIVETYPE[0]")) - return hd_combodrivetype(hdlg, 0); - else if (ID_IS("IDC_COMBODRIVETYPE[1]")) - return hd_combodrivetype(hdlg, 1); - else if (ID_IS("IDC_COMBODRIVETYPE[2]")) - return hd_combodrivetype(hdlg, 2); - else if (ID_IS("IDC_COMBODRIVETYPE[3]")) - return hd_combodrivetype(hdlg, 3); - else if (ID_IS("IDC_COMBODRIVETYPE[4]")) - return hd_combodrivetype(hdlg, 4); - else if (ID_IS("IDC_COMBODRIVETYPE[5]")) - return hd_combodrivetype(hdlg, 5); - else if (ID_IS("IDC_COMBODRIVETYPE[6]")) - return hd_combodrivetype(hdlg, 6); - } - return FALSE; + case WX_COMMAND: + if (ID_IS("IDC_EJECT[0]")) + return hd_eject(hdlg, 0); + else if (ID_IS("IDC_EJECT[1]")) + return hd_eject(hdlg, 1); + else if (ID_IS("IDC_EJECT[2]")) + return hd_eject(hdlg, 2); + else if (ID_IS("IDC_EJECT[3]")) + return hd_eject(hdlg, 3); + else if (ID_IS("IDC_EJECT[4]")) + return hd_eject(hdlg, 4); + else if (ID_IS("IDC_EJECT[5]")) + return hd_eject(hdlg, 5); + else if (ID_IS("IDC_EJECT[6]")) + return hd_eject(hdlg, 6); + else if (ID_IS("IDC_NEW[0]")) + return hd_new(hdlg, 0); + else if (ID_IS("IDC_NEW[1]")) + return hd_new(hdlg, 1); + else if (ID_IS("IDC_NEW[2]")) + return hd_new(hdlg, 2); + else if (ID_IS("IDC_NEW[3]")) + return hd_new(hdlg, 3); + else if (ID_IS("IDC_NEW[4]")) + return hd_new(hdlg, 4); + else if (ID_IS("IDC_NEW[5]")) + return hd_new(hdlg, 5); + else if (ID_IS("IDC_NEW[6]")) + return hd_new(hdlg, 6); + else if (ID_IS("IDC_FILE[0]")) + return hd_file(hdlg, 0); + else if (ID_IS("IDC_FILE[1]")) + return hd_file(hdlg, 1); + else if (ID_IS("IDC_FILE[2]")) + return hd_file(hdlg, 2); + else if (ID_IS("IDC_FILE[3]")) + return hd_file(hdlg, 3); + else if (ID_IS("IDC_FILE[4]")) + return hd_file(hdlg, 4); + else if (ID_IS("IDC_FILE[5]")) + return hd_file(hdlg, 5); + else if (ID_IS("IDC_FILE[6]")) + return hd_file(hdlg, 6); + else if (ID_IS("IDC_EDIT_SPT[0]") || ID_IS("IDC_EDIT_HPC[0]") || ID_IS("IDC_EDIT_CYL[0]")) + return hd_edit(hdlg, 0); + else if (ID_IS("IDC_EDIT_SPT[1]") || ID_IS("IDC_EDIT_HPC[1]") || ID_IS("IDC_EDIT_CYL[1]")) + return hd_edit(hdlg, 1); + else if (ID_IS("IDC_EDIT_SPT[2]") || ID_IS("IDC_EDIT_HPC[2]") || ID_IS("IDC_EDIT_CYL[2]")) + return hd_edit(hdlg, 2); + else if (ID_IS("IDC_EDIT_SPT[3]") || ID_IS("IDC_EDIT_HPC[3]") || ID_IS("IDC_EDIT_CYL[3]")) + return hd_edit(hdlg, 3); + else if (ID_IS("IDC_EDIT_SPT[4]") || ID_IS("IDC_EDIT_HPC[4]") || ID_IS("IDC_EDIT_CYL[4]")) + return hd_edit(hdlg, 4); + else if (ID_IS("IDC_EDIT_SPT[5]") || ID_IS("IDC_EDIT_HPC[5]") || ID_IS("IDC_EDIT_CYL[5]")) + return hd_edit(hdlg, 5); + else if (ID_IS("IDC_EDIT_SPT[6]") || ID_IS("IDC_EDIT_HPC[6]") || ID_IS("IDC_EDIT_CYL[6]")) + return hd_edit(hdlg, 6); + else if (ID_IS("IDC_COMBODRIVETYPE[0]")) + return hd_combodrivetype(hdlg, 0); + else if (ID_IS("IDC_COMBODRIVETYPE[1]")) + return hd_combodrivetype(hdlg, 1); + else if (ID_IS("IDC_COMBODRIVETYPE[2]")) + return hd_combodrivetype(hdlg, 2); + else if (ID_IS("IDC_COMBODRIVETYPE[3]")) + return hd_combodrivetype(hdlg, 3); + else if (ID_IS("IDC_COMBODRIVETYPE[4]")) + return hd_combodrivetype(hdlg, 4); + else if (ID_IS("IDC_COMBODRIVETYPE[5]")) + return hd_combodrivetype(hdlg, 5); + else if (ID_IS("IDC_COMBODRIVETYPE[6]")) + return hd_combodrivetype(hdlg, 6); + } + return FALSE; } void config_change_page_index(void *hdlg, int index) { - void *h; - h = wx_getdlgitem(hdlg, WX_ID("IDC_NOTEBOOK")); - wx_sendmessage(h, WX_SB_SETCURSEL, index, 0); + void *h; + h = wx_getdlgitem(hdlg, WX_ID("IDC_NOTEBOOK")); + wx_sendmessage(h, WX_SB_SETCURSEL, index, 0); - if (index == 3) - update_hdd_cdrom(hdlg); + if (index == 3) + update_hdd_cdrom(hdlg); } int config_dialog_proc(void *hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) { - switch (message) { - case WX_INITDIALOG:pause = 1; - eventBinder = wx_config_eventbinder(hdlg, config_change_page_index); - return config_dlgproc(hdlg, message, wParam, lParam); - case WX_COMMAND: { - if (wParam == wxID_OK) { - wx_config_destroyeventbinder(eventBinder); - eventBinder = NULL; - config_dlgsave(hdlg); - pause = 0; - wx_enddialog(hdlg, 1); - return TRUE; - } else if (wParam == wxID_CANCEL) { - wx_config_destroyeventbinder(eventBinder); - eventBinder = NULL; - pause = 0; - wx_enddialog(hdlg, 0); - return TRUE; - } - break; - } - } - config_dlgproc(hdlg, message, wParam, lParam); - hdconf_dlgproc(hdlg, message, wParam, lParam); - return TRUE; + switch (message) { + case WX_INITDIALOG: + pause = 1; + eventBinder = wx_config_eventbinder(hdlg, config_change_page_index); + return config_dlgproc(hdlg, message, wParam, lParam); + case WX_COMMAND: { + if (wParam == wxID_OK) { + wx_config_destroyeventbinder(eventBinder); + eventBinder = NULL; + config_dlgsave(hdlg); + pause = 0; + wx_enddialog(hdlg, 1); + return TRUE; + } else if (wParam == wxID_CANCEL) { + wx_config_destroyeventbinder(eventBinder); + eventBinder = NULL; + pause = 0; + wx_enddialog(hdlg, 0); + return TRUE; + } + break; + } + } + config_dlgproc(hdlg, message, wParam, lParam); + hdconf_dlgproc(hdlg, message, wParam, lParam); + return TRUE; } -int config_open(void *hwnd) { - return wx_dialogbox(hwnd, "ConfigureDlg", config_dialog_proc); -} +int config_open(void *hwnd) { return wx_dialogbox(hwnd, "ConfigureDlg", config_dialog_proc); } diff --git a/src/wx-ui/wx-config_sel.c b/src/wx-ui/wx-config_sel.c index ecee7cae..00a35c72 100644 --- a/src/wx-ui/wx-config_sel.c +++ b/src/wx-ui/wx-config_sel.c @@ -9,303 +9,304 @@ static int active_config = -1; extern int config_open(void *hwnd); char *validate_config_name(const char *name) { - char notAllowed[] = {'/', '<', '>', ':', '"', '\\', '|', '?', '*'}; + char notAllowed[] = {'/', '<', '>', ':', '"', '\\', '|', '?', '*'}; - for (int i = 0; i < sizeof(notAllowed) / sizeof(char); i++) { - char *ret = strchr(name, notAllowed[i]); - if (ret != NULL) - return ret; - } + for (int i = 0; i < sizeof(notAllowed) / sizeof(char); i++) { + char *ret = strchr(name, notAllowed[i]); + if (ret != NULL) + return ret; + } - return NULL; + return NULL; } static void select_config(void *hdlg, char *name) { - char s[512]; - int num, c; - void *h; + char s[512]; + int num, c; + void *h; - h = wx_getdlgitem(hdlg, WX_ID("IDC_LIST")); - num = wx_sendmessage(h, WX_LB_GETCOUNT, 0, 0); - - for (c = 0; c < num; c++) { - wx_sendmessage(h, WX_LB_GETTEXT, c, (LONG_PARAM)s); - if (!strcmp(s, name)) { - wx_sendmessage(h, WX_LB_SETCURSEL, c, 0); - return; - } - } + h = wx_getdlgitem(hdlg, WX_ID("IDC_LIST")); + num = wx_sendmessage(h, WX_LB_GETCOUNT, 0, 0); + for (c = 0; c < num; c++) { + wx_sendmessage(h, WX_LB_GETTEXT, c, (LONG_PARAM)s); + if (!strcmp(s, name)) { + wx_sendmessage(h, WX_LB_SETCURSEL, c, 0); + return; + } + } } static void config_list_update(void *hdlg) { - char s[512]; - int num, p; - void *h; + char s[512]; + int num, p; + void *h; - strcpy(s, configs_path); - put_backslash(s); - strcat(s, "*.cfg"); - pclog("Dir %s\n", s); + strcpy(s, configs_path); + put_backslash(s); + strcat(s, "*.cfg"); + pclog("Dir %s\n", s); - h = wx_getdlgitem(hdlg, WX_ID("IDC_LIST")); - p = wx_sendmessage(h, WX_LB_GETCURSEL, 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_LIST")); + p = wx_sendmessage(h, WX_LB_GETCURSEL, 0, 0); - wx_dlgdirlist(hdlg, s, WX_ID("IDC_LIST"), 0, 0); + wx_dlgdirlist(hdlg, s, WX_ID("IDC_LIST"), 0, 0); - num = wx_sendmessage(h, WX_LB_GETCOUNT, 0, 0); + num = wx_sendmessage(h, WX_LB_GETCOUNT, 0, 0); - if (num > 0) { - if (p >= num) - p = num - 1; - else if (p < 0) - p = 0; - wx_sendmessage(h, WX_LB_SETCURSEL, p, 0); - } - wx_enablewindow(wx_getdlgitem(hdlg, WX_ID("IDC_RENAME")), num); - wx_enablewindow(wx_getdlgitem(hdlg, WX_ID("IDC_DELETE")), num); - wx_enablewindow(wx_getdlgitem(hdlg, WX_ID("IDC_CONFIG")), num); - wx_enablewindow(wx_getdlgitem(hdlg, wxID_OK), num); + if (num > 0) { + if (p >= num) + p = num - 1; + else if (p < 0) + p = 0; + wx_sendmessage(h, WX_LB_SETCURSEL, p, 0); + } + wx_enablewindow(wx_getdlgitem(hdlg, WX_ID("IDC_RENAME")), num); + wx_enablewindow(wx_getdlgitem(hdlg, WX_ID("IDC_DELETE")), num); + wx_enablewindow(wx_getdlgitem(hdlg, WX_ID("IDC_CONFIG")), num); + wx_enablewindow(wx_getdlgitem(hdlg, wxID_OK), num); } static int run(void *hdlg) { - char s[512]; + char s[512]; - int ret = wx_dlgdirselectex(hdlg, (LONG_PARAM)s, 512, WX_ID("IDC_LIST")); + int ret = wx_dlgdirselectex(hdlg, (LONG_PARAM)s, 512, WX_ID("IDC_LIST")); - pclog("wx_dlgdirselectex returned %i %s\n", ret, s); - if (s[0]) { - char cfg[512]; + pclog("wx_dlgdirselectex returned %i %s\n", ret, s); + if (s[0]) { + char cfg[512]; - active_config = wx_sendmessage(wx_getdlgitem(hdlg, WX_ID("IDC_LIST")), WX_LB_GETCURSEL, 0, 0); + active_config = wx_sendmessage(wx_getdlgitem(hdlg, WX_ID("IDC_LIST")), WX_LB_GETCURSEL, 0, 0); - strcpy(cfg, configs_path); - put_backslash(cfg); - strcat(cfg, s); - strcat(cfg, "cfg"); -// sprintf(cfg, "%s\\configs\\%scfg", config_path, s); - pclog("Config name %s\n", cfg); + strcpy(cfg, configs_path); + put_backslash(cfg); + strcat(cfg, s); + strcat(cfg, "cfg"); + // sprintf(cfg, "%s\\configs\\%scfg", config_path, s); + pclog("Config name %s\n", cfg); - strcpy(config_file_default, cfg); - strcpy(config_name, s); - if (config_name[strlen(config_name) - 1] == '.') - config_name[strlen(config_name) - 1] = 0; + strcpy(config_file_default, cfg); + strcpy(config_name, s); + if (config_name[strlen(config_name) - 1] == '.') + config_name[strlen(config_name) - 1] = 0; - wx_enddialog(hdlg, 1); -// pause = 0; - return TRUE; - } - return FALSE; + wx_enddialog(hdlg, 1); + // pause = 0; + return TRUE; + } + return FALSE; } static int config_selection_dlgproc(void *hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) { - //void* h; - int done = 0; + // void* h; + int done = 0; - switch (message) { - case WX_INITDIALOG: { - // pause = 1; - config_list_update(hdlg); + switch (message) { + case WX_INITDIALOG: { + // pause = 1; + config_list_update(hdlg); - if (active_config >= 0) - wx_sendmessage(wx_getdlgitem(hdlg, WX_ID("IDC_LIST")), WX_LB_SETCURSEL, active_config, 0); + if (active_config >= 0) + wx_sendmessage(wx_getdlgitem(hdlg, WX_ID("IDC_LIST")), WX_LB_SETCURSEL, active_config, 0); - // h = wx_getdlgitem(hdlg, IDC_LIST); - // wx_sendmessage(h, LB_ADDSTRING, 0, (LONG_PARAM)(LPCSTR)"AAA"); - // wx_sendmessage(h, LB_ADDSTRING, 0, (LONG_PARAM)(LPCSTR)"BBB"); - return TRUE; - } - case WX_COMMAND: { - if (wParam == wxID_OK) - return run(hdlg); - else if (wParam == wxID_CANCEL) { - wx_enddialog(hdlg, 0); - // pause = 0; - return TRUE; - } else if (wParam == WX_ID("IDC_NEW")) { - char name[64]; - name[0] = 0; + // h = wx_getdlgitem(hdlg, IDC_LIST); + // wx_sendmessage(h, LB_ADDSTRING, 0, (LONG_PARAM)(LPCSTR)"AAA"); + // wx_sendmessage(h, LB_ADDSTRING, 0, (LONG_PARAM)(LPCSTR)"BBB"); + return TRUE; + } + case WX_COMMAND: { + if (wParam == wxID_OK) + return run(hdlg); + else if (wParam == wxID_CANCEL) { + wx_enddialog(hdlg, 0); + // pause = 0; + return TRUE; + } else if (wParam == WX_ID("IDC_NEW")) { + char name[64]; + name[0] = 0; - while (!done) { - if (wx_textentrydialog(hdlg, "Enter name:", "New config", name, 1, 64, (LONG_PARAM)name)) { - if (validate_config_name(name) != NULL) { - wx_simple_messagebox("Invalid name", "The following characters cannot be in the name: /, <, >, :, \", \\, |, ?, *"); - } else { - char cfg[512]; + while (!done) { + if (wx_textentrydialog(hdlg, "Enter name:", "New config", name, 1, 64, (LONG_PARAM)name)) { + if (validate_config_name(name) != NULL) { + wx_simple_messagebox("Invalid name", "The following characters cannot be in the " + "name: /, <, >, :, \", \\, |, ?, *"); + } else { + char cfg[512]; - strcpy(cfg, configs_path); - put_backslash(cfg); - strcat(cfg, name); - strcat(cfg, ".cfg"); + strcpy(cfg, configs_path); + put_backslash(cfg); + strcat(cfg, name); + strcat(cfg, ".cfg"); - pclog("Config %s\n", cfg); + pclog("Config %s\n", cfg); - if (!wx_file_exists(cfg)) { - if (config_open(hdlg)) { - saveconfig(cfg); + if (!wx_file_exists(cfg)) { + if (config_open(hdlg)) { + saveconfig(cfg); - config_list_update(hdlg); - select_config(hdlg, name); - } - done = 1; - } else - wx_simple_messagebox("Already exists", "A configuration with that name already exists."); - } - } else - done = 1; - } + config_list_update(hdlg); + select_config(hdlg, name); + } + done = 1; + } else + wx_simple_messagebox("Already exists", + "A configuration with that name already exists."); + } + } else + done = 1; + } - return TRUE; - } else if (wParam == WX_ID("IDC_CONFIG")) { - char s[512]; + return TRUE; + } else if (wParam == WX_ID("IDC_CONFIG")) { + char s[512]; - int ret = wx_dlgdirselectex(hdlg, (LONG_PARAM)s, 512, WX_ID("IDC_LIST")); + int ret = wx_dlgdirselectex(hdlg, (LONG_PARAM)s, 512, WX_ID("IDC_LIST")); - pclog("wx_dlgdirselectex returned %i %s\n", ret, s); - if (s[0]) { - char cfg[512]; + pclog("wx_dlgdirselectex returned %i %s\n", ret, s); + if (s[0]) { + char cfg[512]; - strcpy(cfg, configs_path); - put_backslash(cfg); - strcat(cfg, s); - strcat(cfg, "cfg"); - pclog("Config name %s\n", cfg); + strcpy(cfg, configs_path); + put_backslash(cfg); + strcat(cfg, s); + strcat(cfg, "cfg"); + pclog("Config name %s\n", cfg); - loadconfig(cfg); - config_open(hdlg); - saveconfig(cfg); - } + loadconfig(cfg); + config_open(hdlg); + saveconfig(cfg); + } - return TRUE; - } else if (wParam == WX_ID("IDC_RENAME")) { - char name[64]; - char old_name[64]; - void *h; - int c; + return TRUE; + } else if (wParam == WX_ID("IDC_RENAME")) { + char name[64]; + char old_name[64]; + void *h; + int c; - h = wx_getdlgitem(hdlg, WX_ID("IDC_LIST")); - c = wx_sendmessage(h, WX_LB_GETCURSEL, 0, 0); - if (c >= 0) { - wx_sendmessage(h, WX_LB_GETTEXT, c, (LONG_PARAM)old_name); - strcpy(name, old_name); + h = wx_getdlgitem(hdlg, WX_ID("IDC_LIST")); + c = wx_sendmessage(h, WX_LB_GETCURSEL, 0, 0); + if (c >= 0) { + wx_sendmessage(h, WX_LB_GETTEXT, c, (LONG_PARAM)old_name); + strcpy(name, old_name); - while (!done) { - if (wx_textentrydialog(hdlg, "Enter name:", "New name", name, 1, 64, (LONG_PARAM)name)) { - char old_path[512]; - char new_path[512]; + while (!done) { + if (wx_textentrydialog(hdlg, "Enter name:", "New name", name, 1, 64, (LONG_PARAM)name)) { + char old_path[512]; + char new_path[512]; - strcpy(old_path, configs_path); - put_backslash(old_path); - strcat(old_path, old_name); - strcat(old_path, ".cfg"); + strcpy(old_path, configs_path); + put_backslash(old_path); + strcat(old_path, old_name); + strcat(old_path, ".cfg"); - strcpy(new_path, configs_path); - put_backslash(new_path); - strcat(new_path, name); - strcat(new_path, ".cfg"); + strcpy(new_path, configs_path); + put_backslash(new_path); + strcat(new_path, name); + strcat(new_path, ".cfg"); - pclog("Rename %s to %s\n", old_path, new_path); + pclog("Rename %s to %s\n", old_path, new_path); - if (!wx_file_exists(new_path)) { - rename(old_path, new_path); + if (!wx_file_exists(new_path)) { + rename(old_path, new_path); - config_list_update(hdlg); - done = 1; - } else - wx_simple_messagebox("Already exists", "A configuration with that name already exists."); - } else - done = 1; - } - } + config_list_update(hdlg); + done = 1; + } else + wx_simple_messagebox("Already exists", + "A configuration with that name already exists."); + } else + done = 1; + } + } - return TRUE; - } else if (wParam == WX_ID("IDC_COPY")) { - char name[64]; - char old_name[64]; - void *h; - int c; + return TRUE; + } else if (wParam == WX_ID("IDC_COPY")) { + char name[64]; + char old_name[64]; + void *h; + int c; - h = wx_getdlgitem(hdlg, WX_ID("IDC_LIST")); - c = wx_sendmessage(h, WX_LB_GETCURSEL, 0, 0); - if (c >= 0) { - wx_sendmessage(h, WX_LB_GETTEXT, c, (LONG_PARAM)old_name); - strcpy(name, old_name); + h = wx_getdlgitem(hdlg, WX_ID("IDC_LIST")); + c = wx_sendmessage(h, WX_LB_GETCURSEL, 0, 0); + if (c >= 0) { + wx_sendmessage(h, WX_LB_GETTEXT, c, (LONG_PARAM)old_name); + strcpy(name, old_name); - while (!done) { - if (wx_textentrydialog(hdlg, "Enter name:", "New name", name, 1, 64, (LONG_PARAM)name)) { - char old_path[512]; - char new_path[512]; + while (!done) { + if (wx_textentrydialog(hdlg, "Enter name:", "New name", name, 1, 64, (LONG_PARAM)name)) { + char old_path[512]; + char new_path[512]; - strcpy(old_path, configs_path); - put_backslash(old_path); - strcat(old_path, old_name); - strcat(old_path, ".cfg"); + strcpy(old_path, configs_path); + put_backslash(old_path); + strcat(old_path, old_name); + strcat(old_path, ".cfg"); - strcpy(new_path, configs_path); - put_backslash(new_path); - strcat(new_path, name); - strcat(new_path, ".cfg"); + strcpy(new_path, configs_path); + put_backslash(new_path); + strcat(new_path, name); + strcat(new_path, ".cfg"); - pclog("Copy %s to %s\n", old_path, new_path); + pclog("Copy %s to %s\n", old_path, new_path); - if (!wx_file_exists(new_path)) { - wx_copy_file(old_path, new_path, 1); + if (!wx_file_exists(new_path)) { + wx_copy_file(old_path, new_path, 1); - config_list_update(hdlg); - done = 1; - } else - wx_simple_messagebox("Already exists", "A configuration with that name already exists."); - } else - done = 1; - } - } + config_list_update(hdlg); + done = 1; + } else + wx_simple_messagebox("Already exists", + "A configuration with that name already exists."); + } else + done = 1; + } + } - return TRUE; - } else if (wParam == WX_ID("IDC_DELETE")) { - char name[64]; - void *h; - int c; - h = wx_getdlgitem(hdlg, WX_ID("IDC_LIST")); - c = wx_sendmessage(h, WX_LB_GETCURSEL, 0, 0); - if (c >= 0) { - char s[512]; - wx_sendmessage(h, WX_LB_GETTEXT, c, (LONG_PARAM)name); - sprintf(s, "Do you want to delete \"%s\"?", name); - if (wx_messagebox(NULL, s, "PCem", WX_MB_OKCANCEL) == WX_IDOK) { - strcpy(s, configs_path); - put_backslash(s); - strcat(s, name); - strcat(s, ".cfg"); + return TRUE; + } else if (wParam == WX_ID("IDC_DELETE")) { + char name[64]; + void *h; + int c; + h = wx_getdlgitem(hdlg, WX_ID("IDC_LIST")); + c = wx_sendmessage(h, WX_LB_GETCURSEL, 0, 0); + if (c >= 0) { + char s[512]; + wx_sendmessage(h, WX_LB_GETTEXT, c, (LONG_PARAM)name); + sprintf(s, "Do you want to delete \"%s\"?", name); + if (wx_messagebox(NULL, s, "PCem", WX_MB_OKCANCEL) == WX_IDOK) { + strcpy(s, configs_path); + put_backslash(s); + strcat(s, name); + strcat(s, ".cfg"); - remove(s); + remove(s); - config_list_update(hdlg); - } - } - } else if (wParam == WX_ID("IDC_LIST")) { - if (lParam == WX_LBN_DBLCLK) - run(hdlg); - } + config_list_update(hdlg); + } + } + } else if (wParam == WX_ID("IDC_LIST")) { + if (lParam == WX_LBN_DBLCLK) + run(hdlg); + } #ifdef USE_NETWORKING - else if (wParam == WX_ID("IDC_CONFIG_HOST")) - { - hostconfig_open(hdlg); - } + else if (wParam == WX_ID("IDC_CONFIG_HOST")) { + hostconfig_open(hdlg); + } #endif - } - break; - } - return FALSE; + } break; + } + return FALSE; } int config_selection_open(void *hwnd, int inited) { - int ret; + int ret; - has_been_inited = inited; + has_been_inited = inited; - ret = wx_dialogbox(hwnd, "ConfigureSelectionDlg", config_selection_dlgproc); + ret = wx_dialogbox(hwnd, "ConfigureSelectionDlg", config_selection_dlgproc); - has_been_inited = 1; + has_been_inited = 1; - return ret; + return ret; } diff --git a/src/wx-ui/wx-createdisc.cc b/src/wx-ui/wx-createdisc.cc index 5576f59f..4447bc98 100644 --- a/src/wx-ui/wx-createdisc.cc +++ b/src/wx-ui/wx-createdisc.cc @@ -19,116 +19,108 @@ extern "C" void pclog(const char *format, ...); #define IDC_CONFIG_BASE 1000 static struct { - char name[80]; - int nr_sectors; -} disc_formats[] = - { - {"160 kB", 1 * 40 * 8}, - {"180 kB", 1 * 40 * 9}, - {"320 kB", 2 * 40 * 8}, - {"360 kB", 2 * 40 * 9}, - {"720 kB", 2 * 80 * 9}, - {"1.2 MB", 2 * 80 * 15}, - {"1.44 MB", 2 * 80 * 18}, - {"2.88 MB", 2 * 80 * 36}, - {"100 MB (Zip)", 2048 * 96}, - {"", 0} - }; + char name[80]; + int nr_sectors; +} disc_formats[] = {{"160 kB", 1 * 40 * 8}, {"180 kB", 1 * 40 * 9}, + {"320 kB", 2 * 40 * 8}, {"360 kB", 2 * 40 * 9}, + {"720 kB", 2 * 80 * 9}, {"1.2 MB", 2 * 80 * 15}, + {"1.44 MB", 2 * 80 * 18}, {"2.88 MB", 2 * 80 * 36}, + {"100 MB (Zip)", 2048 * 96}, {"", 0}}; -static int creatediscimage_dlgproc(void *hdlg, int message, INT_PARAM wParam, - LONG_PARAM lParam) { - wxWindow *window = (wxWindow *)hdlg; - int c; +static int creatediscimage_dlgproc(void *hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) { + wxWindow *window = (wxWindow *)hdlg; + int c; - switch (message) { - case WX_INITDIALOG:return TRUE; + switch (message) { + case WX_INITDIALOG: + return TRUE; - case WX_COMMAND: - switch (wParam) { - case wxID_OK:c = 0; + case WX_COMMAND: + switch (wParam) { + case wxID_OK: + c = 0; - while (disc_formats[c].nr_sectors) { - wxWindow *rb_win = window->FindWindow(IDC_CONFIG_BASE + c); - wxRadioButton *rb = wxDynamicCast(rb_win, wxRadioButton); + while (disc_formats[c].nr_sectors) { + wxWindow *rb_win = window->FindWindow(IDC_CONFIG_BASE + c); + wxRadioButton *rb = wxDynamicCast(rb_win, wxRadioButton); - if (rb->GetValue()) - break; - c++; - } + if (rb->GetValue()) + break; + c++; + } - if (disc_formats[c].nr_sectors) { - char openfilestring[260]; - int ret; + if (disc_formats[c].nr_sectors) { + char openfilestring[260]; + int ret; - memset(openfilestring, 0, sizeof(openfilestring)); - ret = wx_filedialog(hdlg, "Save", "", - "Disc image (*.img;*.ima)|*.img;*.ima|All files (*.*)|*.*", - ".img", - 0, openfilestring); + memset(openfilestring, 0, sizeof(openfilestring)); + ret = wx_filedialog(hdlg, "Save", "", "Disc image (*.img;*.ima)|*.img;*.ima|All files (*.*)|*.*", + ".img", 0, openfilestring); - if (!ret) { - FILE *f = fopen(openfilestring, "wb"); - if (f) { - uint8_t sector[512]; - int d; + if (!ret) { + FILE *f = fopen(openfilestring, "wb"); + if (f) { + uint8_t sector[512]; + int d; - memset(sector, 0, 512); + memset(sector, 0, 512); - for (d = 0; d < disc_formats[c].nr_sectors; d++) - fwrite(sector, 512, 1, f); + for (d = 0; d < disc_formats[c].nr_sectors; d++) + fwrite(sector, 512, 1, f); - fclose(f); - } - } - } + fclose(f); + } + } + } - wx_enddialog(hdlg, 0); - return TRUE; + wx_enddialog(hdlg, 0); + return TRUE; - case wxID_CANCEL:wx_enddialog(hdlg, 0); - return TRUE; - } - break; - } - return FALSE; + case wxID_CANCEL: + wx_enddialog(hdlg, 0); + return TRUE; + } + break; + } + return FALSE; } void creatediscimage_open(void *hwnd) { - int id = IDC_CONFIG_BASE; - int c = 0; + int id = IDC_CONFIG_BASE; + int c = 0; - PCemDialogBox dialog((wxWindow *)hwnd, creatediscimage_dlgproc); + PCemDialogBox dialog((wxWindow *)hwnd, creatediscimage_dlgproc); - dialog.SetTitle("Create Disc Image"); + dialog.SetTitle("Create Disc Image"); - wxFlexGridSizer *root = new wxFlexGridSizer(0, 1, 0, 0); - root->SetFlexibleDirection(wxBOTH); - root->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED); - dialog.SetSizer(root); + wxFlexGridSizer *root = new wxFlexGridSizer(0, 1, 0, 0); + root->SetFlexibleDirection(wxBOTH); + root->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED); + dialog.SetSizer(root); - wxFlexGridSizer *sizer = new wxFlexGridSizer(0, 1, 0, 0); - sizer->SetFlexibleDirection(wxBOTH); - sizer->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED); - root->Add(sizer, 1, wxEXPAND, 5); + wxFlexGridSizer *sizer = new wxFlexGridSizer(0, 1, 0, 0); + sizer->SetFlexibleDirection(wxBOTH); + sizer->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED); + root->Add(sizer, 1, wxEXPAND, 5); - while (disc_formats[c].nr_sectors) { - wxBoxSizer *radioSizer = new wxBoxSizer(wxHORIZONTAL); - sizer->Add(radioSizer, 1, wxEXPAND, 5); - wxRadioButton *rb = new wxRadioButton(&dialog, id++, disc_formats[c].name); - radioSizer->Add(rb, 1, wxALL, 5); + while (disc_formats[c].nr_sectors) { + wxBoxSizer *radioSizer = new wxBoxSizer(wxHORIZONTAL); + sizer->Add(radioSizer, 1, wxEXPAND, 5); + wxRadioButton *rb = new wxRadioButton(&dialog, id++, disc_formats[c].name); + radioSizer->Add(rb, 1, wxALL, 5); - c++; - } + c++; + } - wxBoxSizer *okCancelSizer = new wxBoxSizer(wxHORIZONTAL); - root->Add(okCancelSizer, 1, wxEXPAND, 5); + wxBoxSizer *okCancelSizer = new wxBoxSizer(wxHORIZONTAL); + root->Add(okCancelSizer, 1, wxEXPAND, 5); - okCancelSizer->Add(0, 0, 1, wxEXPAND, 5); - okCancelSizer->Add(new wxButton(&dialog, wxID_OK), 0, wxALL, 5); - okCancelSizer->Add(new wxButton(&dialog, wxID_CANCEL), 0, wxALL, 5); + okCancelSizer->Add(0, 0, 1, wxEXPAND, 5); + okCancelSizer->Add(new wxButton(&dialog, wxID_OK), 0, wxALL, 5); + okCancelSizer->Add(new wxButton(&dialog, wxID_CANCEL), 0, wxALL, 5); - dialog.Fit(); - dialog.OnInit(); - dialog.ShowModal(); - dialog.Destroy(); + dialog.Fit(); + dialog.OnInit(); + dialog.ShowModal(); + dialog.Destroy(); } diff --git a/src/wx-ui/wx-deviceconfig.cc b/src/wx-ui/wx-deviceconfig.cc index 18c38bb9..60aee162 100644 --- a/src/wx-ui/wx-deviceconfig.cc +++ b/src/wx-ui/wx-deviceconfig.cc @@ -11,250 +11,259 @@ #include "wx/xrc/xmlres.h" -extern "C" -{ +extern "C" { #include "config.h" #include "plat-midi.h" void saveconfig(char *); void resetpchard(); -int deviceconfig_dlgproc(void *hdlg, int message, INT_PARAM wParam, - LONG_PARAM lParam); +int deviceconfig_dlgproc(void *hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam); device_t *config_device; int confirm(); } #define IDC_CONFIG_BASE 1000 -int deviceconfig_dlgproc(void *hdlg, int message, INT_PARAM wParam, - LONG_PARAM lParam) { - switch (message) { - case WX_INITDIALOG: { - int id = IDC_CONFIG_BASE; - device_config_t *config = config_device->config; - int c; +int deviceconfig_dlgproc(void *hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) { + switch (message) { + case WX_INITDIALOG: { + int id = IDC_CONFIG_BASE; + device_config_t *config = config_device->config; + int c; - while (config->type != -1) { - device_config_selection_t *selection = config->selection; - void *h = 0; - int val_int; - int num; - char s[100]; + while (config->type != -1) { + device_config_selection_t *selection = config->selection; + void *h = 0; + int val_int; + int num; + char s[100]; - switch (config->type) { - case CONFIG_BINARY:h = wx_getdlgitem(hdlg, id); - val_int = config_get_int(CFG_MACHINE, config_device->name, config->name, config->default_int); + switch (config->type) { + case CONFIG_BINARY: + h = wx_getdlgitem(hdlg, id); + val_int = config_get_int(CFG_MACHINE, config_device->name, config->name, config->default_int); - wx_sendmessage(h, WX_BM_SETCHECK, val_int, 0); + wx_sendmessage(h, WX_BM_SETCHECK, val_int, 0); - id++; - break; + id++; + break; - case CONFIG_SELECTION:h = wx_getdlgitem(hdlg, id + 1); - val_int = config_get_int(CFG_MACHINE, config_device->name, config->name, config->default_int); + case CONFIG_SELECTION: + h = wx_getdlgitem(hdlg, id + 1); + val_int = config_get_int(CFG_MACHINE, config_device->name, config->name, config->default_int); - c = 0; - while (selection->description[0]) { - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)selection->description); - if (val_int == selection->value) - wx_sendmessage(h, WX_CB_SETCURSEL, c, 0); - selection++; - c++; - } + c = 0; + while (selection->description[0]) { + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)selection->description); + if (val_int == selection->value) + wx_sendmessage(h, WX_CB_SETCURSEL, c, 0); + selection++; + c++; + } - id += 2; - break; + id += 2; + break; - case CONFIG_MIDI:num = midi_get_num_devs(); - if (num > 0) { - h = wx_getdlgitem(hdlg, id + 1); - val_int = config_get_int(CFG_MACHINE, NULL, config->name, config->default_int); + case CONFIG_MIDI: + num = midi_get_num_devs(); + if (num > 0) { + h = wx_getdlgitem(hdlg, id + 1); + val_int = config_get_int(CFG_MACHINE, NULL, config->name, config->default_int); - for (c = 0; c < num; c++) { - midi_get_dev_name(c, s); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); - if (val_int == c) - wx_sendmessage(h, WX_CB_SETCURSEL, c, 0); - } - id += 2; - } - break; - } - config++; - } - } - return TRUE; + for (c = 0; c < num; c++) { + midi_get_dev_name(c, s); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); + if (val_int == c) + wx_sendmessage(h, WX_CB_SETCURSEL, c, 0); + } + id += 2; + } + break; + } + config++; + } + } + return TRUE; - case WX_COMMAND: - switch (wParam) { - case wxID_OK: { - int id = IDC_CONFIG_BASE; - device_config_t *config = config_device->config; - int c; - int changed = 0; + case WX_COMMAND: + switch (wParam) { + case wxID_OK: { + int id = IDC_CONFIG_BASE; + device_config_t *config = config_device->config; + int c; + int changed = 0; - while (config->type != -1) { - device_config_selection_t *selection = config->selection; - void *h = 0; - int val_int; + while (config->type != -1) { + device_config_selection_t *selection = config->selection; + void *h = 0; + int val_int; - switch (config->type) { - case CONFIG_BINARY:h = wx_getdlgitem(hdlg, id); - val_int = config_get_int(CFG_MACHINE, config_device->name, config->name, config->default_int); + switch (config->type) { + case CONFIG_BINARY: + h = wx_getdlgitem(hdlg, id); + val_int = config_get_int(CFG_MACHINE, config_device->name, config->name, + config->default_int); - if (val_int != wx_sendmessage(h, WX_BM_GETCHECK, 0, 0)) - changed = 1; + if (val_int != wx_sendmessage(h, WX_BM_GETCHECK, 0, 0)) + changed = 1; - id++; - break; + id++; + break; - case CONFIG_SELECTION:h = wx_getdlgitem(hdlg, id + 1); - val_int = config_get_int(CFG_MACHINE, config_device->name, config->name, config->default_int); + case CONFIG_SELECTION: + h = wx_getdlgitem(hdlg, id + 1); + val_int = config_get_int(CFG_MACHINE, config_device->name, config->name, + config->default_int); - c = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + c = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - for (; c > 0; c--) - selection++; + for (; c > 0; c--) + selection++; - if (val_int != selection->value) - changed = 1; + if (val_int != selection->value) + changed = 1; - id += 2; - break; + id += 2; + break; - case CONFIG_MIDI: - if (midi_get_num_devs() > 0) { - h = wx_getdlgitem(hdlg, id + 1); - val_int = config_get_int(CFG_MACHINE, NULL, config->name, config->default_int); + case CONFIG_MIDI: + if (midi_get_num_devs() > 0) { + h = wx_getdlgitem(hdlg, id + 1); + val_int = config_get_int(CFG_MACHINE, NULL, config->name, config->default_int); - c = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + c = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - if (val_int != c) - changed = 1; - id += 2; - } - break; - } - config++; - } + if (val_int != c) + changed = 1; + id += 2; + } + break; + } + config++; + } - if (!changed) { - wx_enddialog(hdlg, 0); - return TRUE; - } + if (!changed) { + wx_enddialog(hdlg, 0); + return TRUE; + } - if (has_been_inited && !confirm()) { - wx_enddialog(hdlg, 0); - return TRUE; - } + if (has_been_inited && !confirm()) { + wx_enddialog(hdlg, 0); + return TRUE; + } - id = IDC_CONFIG_BASE; - config = config_device->config; + id = IDC_CONFIG_BASE; + config = config_device->config; - while (config->type != -1) { - device_config_selection_t *selection = config->selection; - void *h = 0; + while (config->type != -1) { + device_config_selection_t *selection = config->selection; + void *h = 0; - switch (config->type) { - case CONFIG_BINARY:h = wx_getdlgitem(hdlg, id); - config_set_int(CFG_MACHINE, config_device->name, config->name, wx_sendmessage(h, WX_BM_GETCHECK, 0, 0)); + switch (config->type) { + case CONFIG_BINARY: + h = wx_getdlgitem(hdlg, id); + config_set_int(CFG_MACHINE, config_device->name, config->name, + wx_sendmessage(h, WX_BM_GETCHECK, 0, 0)); - id++; - break; + id++; + break; - case CONFIG_SELECTION:h = wx_getdlgitem(hdlg, id + 1); - c = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - for (; c > 0; c--) - selection++; - config_set_int(CFG_MACHINE, config_device->name, config->name, selection->value); + case CONFIG_SELECTION: + h = wx_getdlgitem(hdlg, id + 1); + c = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + for (; c > 0; c--) + selection++; + config_set_int(CFG_MACHINE, config_device->name, config->name, selection->value); - id += 2; - break; + id += 2; + break; - case CONFIG_MIDI: - if (midi_get_num_devs() > 0) { - h = wx_getdlgitem(hdlg, id + 1); - c = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - config_set_int(CFG_MACHINE, NULL, config->name, c); + case CONFIG_MIDI: + if (midi_get_num_devs() > 0) { + h = wx_getdlgitem(hdlg, id + 1); + c = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + config_set_int(CFG_MACHINE, NULL, config->name, c); - id += 2; - } - break; - } - config++; - } + id += 2; + } + break; + } + config++; + } - if (has_been_inited) { - saveconfig(NULL); - resetpchard(); - } + if (has_been_inited) { + saveconfig(NULL); + resetpchard(); + } - wx_enddialog(hdlg, 0); - return TRUE; - } - case wxID_CANCEL:wx_enddialog(hdlg, 0); - return TRUE; - } - break; - } - return FALSE; + wx_enddialog(hdlg, 0); + return TRUE; + } + case wxID_CANCEL: + wx_enddialog(hdlg, 0); + return TRUE; + } + break; + } + return FALSE; } void deviceconfig_open(void *hwnd, device_t *device) { - char s[257]; - config_device = device; + char s[257]; + config_device = device; - PCemDialogBox dialog((wxWindow *)hwnd, deviceconfig_dlgproc); -// dialog.SetWindowStyle(wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER); + PCemDialogBox dialog((wxWindow *)hwnd, deviceconfig_dlgproc); + // dialog.SetWindowStyle(wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER); - device_config_t *config = device->config; + device_config_t *config = device->config; - dialog.SetTitle("Device Configuration"); + dialog.SetTitle("Device Configuration"); - wxFlexGridSizer *root = new wxFlexGridSizer(0, 1, 0, 0); - root->SetFlexibleDirection(wxBOTH); - root->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED); - dialog.SetSizer(root); + wxFlexGridSizer *root = new wxFlexGridSizer(0, 1, 0, 0); + root->SetFlexibleDirection(wxBOTH); + root->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED); + dialog.SetSizer(root); - wxFlexGridSizer *sizer = new wxFlexGridSizer(0, 2, 0, 0); - sizer->SetFlexibleDirection(wxBOTH); - sizer->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED); - sizer->AddGrowableCol(1); - root->Add(sizer, 1, wxEXPAND, 5); + wxFlexGridSizer *sizer = new wxFlexGridSizer(0, 2, 0, 0); + sizer->SetFlexibleDirection(wxBOTH); + sizer->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED); + sizer->AddGrowableCol(1); + root->Add(sizer, 1, wxEXPAND, 5); - int id = IDC_CONFIG_BASE; + int id = IDC_CONFIG_BASE; - while (config->type != -1) { - switch (config->type) { - case CONFIG_BINARY:sizer->Add(0, 0, 1, wxEXPAND, 5); - sizer->Add(new wxCheckBox(&dialog, id++, config->description), 0, wxALL, 5); - break; + while (config->type != -1) { + switch (config->type) { + case CONFIG_BINARY: + sizer->Add(0, 0, 1, wxEXPAND, 5); + sizer->Add(new wxCheckBox(&dialog, id++, config->description), 0, wxALL, 5); + break; - case CONFIG_SELECTION: - case CONFIG_MIDI: { - if (config->type == CONFIG_MIDI && midi_get_num_devs() == 0) - break; - sprintf(s, "%s:", config->description); - sizer->Add(new wxStaticText(&dialog, id++, s), 0, wxALL | wxALIGN_CENTER_VERTICAL, 5); - wxBoxSizer *comboSizer = new wxBoxSizer(wxHORIZONTAL); - sizer->Add(comboSizer, 1, wxEXPAND, 5); - wxComboBox *cb = new wxComboBox(&dialog, id++); - cb->SetEditable(false); - comboSizer->Add(cb, 1, wxALL, 5); - break; - } - } + case CONFIG_SELECTION: + case CONFIG_MIDI: { + if (config->type == CONFIG_MIDI && midi_get_num_devs() == 0) + break; + sprintf(s, "%s:", config->description); + sizer->Add(new wxStaticText(&dialog, id++, s), 0, wxALL | wxALIGN_CENTER_VERTICAL, 5); + wxBoxSizer *comboSizer = new wxBoxSizer(wxHORIZONTAL); + sizer->Add(comboSizer, 1, wxEXPAND, 5); + wxComboBox *cb = new wxComboBox(&dialog, id++); + cb->SetEditable(false); + comboSizer->Add(cb, 1, wxALL, 5); + break; + } + } - config++; - } + config++; + } - wxBoxSizer *okCancelSizer = new wxBoxSizer(wxHORIZONTAL); - root->Add(okCancelSizer, 1, wxEXPAND, 5); + wxBoxSizer *okCancelSizer = new wxBoxSizer(wxHORIZONTAL); + root->Add(okCancelSizer, 1, wxEXPAND, 5); - okCancelSizer->Add(0, 0, 1, wxEXPAND, 5); - okCancelSizer->Add(new wxButton(&dialog, wxID_OK), 0, wxALL, 5); - okCancelSizer->Add(new wxButton(&dialog, wxID_CANCEL), 0, wxALL, 5); + okCancelSizer->Add(0, 0, 1, wxEXPAND, 5); + okCancelSizer->Add(new wxButton(&dialog, wxID_OK), 0, wxALL, 5); + okCancelSizer->Add(new wxButton(&dialog, wxID_CANCEL), 0, wxALL, 5); - dialog.Fit(); - dialog.OnInit(); - dialog.ShowModal(); - dialog.Destroy(); + dialog.Fit(); + dialog.OnInit(); + dialog.ShowModal(); + dialog.Destroy(); } diff --git a/src/wx-ui/wx-dialogbox.cc b/src/wx-ui/wx-dialogbox.cc index b25b8264..fafe10fb 100644 --- a/src/wx-ui/wx-dialogbox.cc +++ b/src/wx-ui/wx-dialogbox.cc @@ -10,66 +10,68 @@ #include "wx-dialogbox.h" #include "wx-utils.h" -BEGIN_EVENT_TABLE(PCemDialogBox, wxDialog)END_EVENT_TABLE() +BEGIN_EVENT_TABLE(PCemDialogBox, wxDialog) +END_EVENT_TABLE() -class CommandValue : public wxObject { + class CommandValue : public wxObject { public: - CommandValue(int value) { this->value = value; } - int GetValue() { return this->value; } + CommandValue(int value) { this->value = value; } + int GetValue() { return this->value; } + private: - int value; + int value; }; -PCemDialogBox::PCemDialogBox(wxWindow *parent, int (*callback)(void *window, int message, INT_PARAM param1, LONG_PARAM param2)) : - wxDialog(parent, -1, "No title") { - this->callback = callback; - this->commandActive = false; +PCemDialogBox::PCemDialogBox(wxWindow *parent, int (*callback)(void *window, int message, INT_PARAM param1, LONG_PARAM param2)) + : wxDialog(parent, -1, "No title") { + this->callback = callback; + this->commandActive = false; } -PCemDialogBox::PCemDialogBox(wxWindow *parent, const char *name, int (*callback)(void *window, int message, INT_PARAM param1, LONG_PARAM param2)) { - wxXmlResource::Get()->LoadDialog(this, parent, name); - this->callback = callback; - this->commandActive = false; +PCemDialogBox::PCemDialogBox(wxWindow *parent, const char *name, + int (*callback)(void *window, int message, INT_PARAM param1, LONG_PARAM param2)) { + wxXmlResource::Get()->LoadDialog(this, parent, name); + this->callback = callback; + this->commandActive = false; } void PCemDialogBox::OnInit() { - if (callback) { - callback(this, WX_INITDIALOG, 0, 0); - Bind(wxEVT_BUTTON, &PCemDialogBox::OnCommand, this); - Bind(wxEVT_RADIOBUTTON, &PCemDialogBox::OnCommand, this); - Bind(wxEVT_TEXT, &PCemDialogBox::OnCommand, this); - Bind(wxEVT_COMBOBOX, &PCemDialogBox::OnCommand, this); - Bind(wxEVT_NOTEBOOK_PAGE_CHANGED, &PCemDialogBox::OnNotebookChanged, this); - Bind(wxEVT_LISTBOX_DCLICK, &PCemDialogBox::OnCommand, this, wxID_ANY, wxID_ANY, new CommandValue(WX_LBN_DBLCLK)); - } + if (callback) { + callback(this, WX_INITDIALOG, 0, 0); + Bind(wxEVT_BUTTON, &PCemDialogBox::OnCommand, this); + Bind(wxEVT_RADIOBUTTON, &PCemDialogBox::OnCommand, this); + Bind(wxEVT_TEXT, &PCemDialogBox::OnCommand, this); + Bind(wxEVT_COMBOBOX, &PCemDialogBox::OnCommand, this); + Bind(wxEVT_NOTEBOOK_PAGE_CHANGED, &PCemDialogBox::OnNotebookChanged, this); + Bind(wxEVT_LISTBOX_DCLICK, &PCemDialogBox::OnCommand, this, wxID_ANY, wxID_ANY, new CommandValue(WX_LBN_DBLCLK)); + } - wxWindow *root = FindWindow(XRCID("ROOT_PANEL")); - if (root) - root->Fit(); - Fit(); + wxWindow *root = FindWindow(XRCID("ROOT_PANEL")); + if (root) + root->Fit(); + Fit(); } int PCemDialogBox::processEvent(int message, INT_PARAM param1, LONG_PARAM param2) { - int result = 0; - /* lock the current command to prevent strange behavior */ - if (!commandActive) { - commandActive = true; - result = callback(this, message, param1, param2); - commandActive = false; - } - return result; + int result = 0; + /* lock the current command to prevent strange behavior */ + if (!commandActive) { + commandActive = true; + result = callback(this, message, param1, param2); + commandActive = false; + } + return result; } void PCemDialogBox::OnNotebookChanged(wxCommandEvent &event) { - wxBookCtrlEvent *ev = (wxBookCtrlEvent *)&event; - processEvent(WX_COMMAND, ev->GetId(), ev->GetSelection()); + wxBookCtrlEvent *ev = (wxBookCtrlEvent *)&event; + processEvent(WX_COMMAND, ev->GetId(), ev->GetSelection()); } void PCemDialogBox::OnCommand(wxCommandEvent &event) { - LONG_PARAM val = 0; - CommandValue *c = (CommandValue *)event.GetEventUserData(); - if (c) - val = c->GetValue(); - processEvent(WX_COMMAND, event.GetId(), val); + LONG_PARAM val = 0; + CommandValue *c = (CommandValue *)event.GetEventUserData(); + if (c) + val = c->GetValue(); + processEvent(WX_COMMAND, event.GetId(), val); } - diff --git a/src/wx-ui/wx-glslp-parser.c b/src/wx-ui/wx-glslp-parser.c index 97e01296..de10addc 100644 --- a/src/wx-ui/wx-glslp-parser.c +++ b/src/wx-ui/wx-glslp-parser.c @@ -6,293 +6,297 @@ #include #include "wx-utils.h" -#define safe_strncpy(a, b, n) do { strncpy((a),(b),(n)-1); (a)[(n)-1] = 0; } while (0) +#define safe_strncpy(a, b, n) \ + do { \ + strncpy((a), (b), (n)-1); \ + (a)[(n)-1] = 0; \ + } while (0) extern char *get_filename(char *); extern void pclog(const char *format, ...); static int endswith(const char *str, const char *ext) { - int i; - const char *p; - int elen = strlen(ext); - int slen = strlen(str); - if (slen >= elen) { - p = &str[slen - elen]; - for (i = 0; i < elen; ++i) { - if (tolower(p[i]) != tolower(ext[i])) - return 0; - } - return 1; - } - return 0; + int i; + const char *p; + int elen = strlen(ext); + int slen = strlen(str); + if (slen >= elen) { + p = &str[slen - elen]; + for (i = 0; i < elen; ++i) { + if (tolower(p[i]) != tolower(ext[i])) + return 0; + } + return 1; + } + return 0; } static char *load_file(const char *fn) { - FILE *f = fopen(fn, "rb"); - if (!f) - return 0; - fseek(f, 0, SEEK_END); - long fsize = ftell(f); - fseek(f, 0, SEEK_SET); + FILE *f = fopen(fn, "rb"); + if (!f) + return 0; + fseek(f, 0, SEEK_END); + long fsize = ftell(f); + fseek(f, 0, SEEK_SET); - char *data = malloc(fsize + 1); + char *data = malloc(fsize + 1); - fread(data, fsize, 1, f); - fclose(f); + fread(data, fsize, 1, f); + fclose(f); - data[fsize] = 0; + data[fsize] = 0; - return data; + return data; } static void strip_lines(const char *program, const char *starts_with) { - /* strip parameters */ - char *ptr = strstr(program, starts_with); - while (ptr) { - while (*ptr != '\n' && *ptr != '\0') - *ptr++ = ' '; - ptr = strstr(program, starts_with); - } + /* strip parameters */ + char *ptr = strstr(program, starts_with); + while (ptr) { + while (*ptr != '\n' && *ptr != '\0') + *ptr++ = ' '; + ptr = strstr(program, starts_with); + } } static void strip_parameters(const char *program) { - /* strip parameters */ - strip_lines(program, "#pragma parameter"); + /* strip parameters */ + strip_lines(program, "#pragma parameter"); } static void strip_defines(const char *program) { - /* strip texture define */ - strip_lines(program, "#define texture"); + /* strip texture define */ + strip_lines(program, "#define texture"); } static int has_parameter(glslp_t *glsl, char *id) { - int i; - for (i = 0; i < glsl->num_parameters; ++i) - if (!strcmp(glsl->parameters[i].id, id)) - return 1; - return 0; + int i; + for (i = 0; i < glsl->num_parameters; ++i) + if (!strcmp(glsl->parameters[i].id, id)) + return 1; + return 0; } static int get_parameters(glslp_t *glsl) { - int i; - struct parameter p; - for (i = 0; i < glsl->num_shaders; ++i) { - struct shader *shader = &glsl->shaders[i]; - FILE *f = fopen(shader->shader_fn, "rb"); - if (!f) - return 0; + int i; + struct parameter p; + for (i = 0; i < glsl->num_shaders; ++i) { + struct shader *shader = &glsl->shaders[i]; + FILE *f = fopen(shader->shader_fn, "rb"); + if (!f) + return 0; - char line[1024]; - while (fgets(line, sizeof(line) - 1, f) && glsl->num_parameters < MAX_PARAMETERS) { - int num = sscanf(line, "#pragma parameter %63s \"%63[^\"]\" %f %f %f %f", p.id, p.description, &p.default_value, &p.min, &p.max, &p.step); - if (num < 5) - continue; - p.id[63] = 0; - p.description[63] = 0; + char line[1024]; + while (fgets(line, sizeof(line) - 1, f) && glsl->num_parameters < MAX_PARAMETERS) { + int num = sscanf(line, "#pragma parameter %63s \"%63[^\"]\" %f %f %f %f", p.id, p.description, + &p.default_value, &p.min, &p.max, &p.step); + if (num < 5) + continue; + p.id[63] = 0; + p.description[63] = 0; - if (num == 5) - p.step = 0.1f * (p.max - p.min); + if (num == 5) + p.step = 0.1f * (p.max - p.min); - p.value = p.default_value; + p.value = p.default_value; - if (!has_parameter(glsl, p.id)) { - memcpy(&glsl->parameters[glsl->num_parameters++], &p, sizeof(struct parameter)); - pclog("Read parameter: %s (%s) %f, %f -> %f (%f)\n", p.id, p.description, p.default_value, p.min, p.max, p.step); - } - } + if (!has_parameter(glsl, p.id)) { + memcpy(&glsl->parameters[glsl->num_parameters++], &p, sizeof(struct parameter)); + pclog("Read parameter: %s (%s) %f, %f -> %f (%f)\n", p.id, p.description, p.default_value, p.min, + p.max, p.step); + } + } - fclose(f); - } + fclose(f); + } - return 1; + return 1; } static struct parameter *get_parameter(glslp_t *glslp, const char *id) { - int i; - for (i = 0; i < glslp->num_parameters; ++i) { - if (!strcmp(glslp->parameters[i].id, id)) { - return &glslp->parameters[i]; - } - } - return 0; + int i; + for (i = 0; i < glslp->num_parameters; ++i) { + if (!strcmp(glslp->parameters[i].id, id)) { + return &glslp->parameters[i]; + } + } + return 0; } static glslp_t *glsl_parse(const char *f) { - glslp_t *glslp = malloc(sizeof(glslp_t)); - memset(glslp, 0, sizeof(glslp_t)); - glslp->num_shaders = 1; - struct shader *shader = &glslp->shaders[0]; - strcpy(shader->shader_fn, f); - shader->shader_program = load_file(f); - if (!shader->shader_program) { - wx_simple_messagebox("GLSL error", "Could not load shader %s\n", shader->shader_fn); - glslp_free(glslp); - return 0; - } - strip_parameters(shader->shader_program); - strip_defines(shader->shader_program); - shader->scale_x = shader->scale_y = 1.0f; - strcpy(shader->scale_type_x, "source"); - strcpy(shader->scale_type_y, "source"); - get_parameters(glslp); - return glslp; + glslp_t *glslp = malloc(sizeof(glslp_t)); + memset(glslp, 0, sizeof(glslp_t)); + glslp->num_shaders = 1; + struct shader *shader = &glslp->shaders[0]; + strcpy(shader->shader_fn, f); + shader->shader_program = load_file(f); + if (!shader->shader_program) { + wx_simple_messagebox("GLSL error", "Could not load shader %s\n", shader->shader_fn); + glslp_free(glslp); + return 0; + } + strip_parameters(shader->shader_program); + strip_defines(shader->shader_program); + shader->scale_x = shader->scale_y = 1.0f; + strcpy(shader->scale_type_x, "source"); + strcpy(shader->scale_type_y, "source"); + get_parameters(glslp); + return glslp; } -void get_glslp_name(const char *f, char *s, int size) { - safe_strncpy(s, get_filename((char *)f), size); -} +void get_glslp_name(const char *f, char *s, int size) { safe_strncpy(s, get_filename((char *)f), size); } glslp_t *glslp_parse(const char *f) { - int i, j, len, sublen; - char s[512], t[512], z[540]; + int i, j, len, sublen; + char s[512], t[512], z[540]; - memset(s, 0, sizeof(s)); - if (endswith(f, ".glsl")) - return glsl_parse(f); + memset(s, 0, sizeof(s)); + if (endswith(f, ".glsl")) + return glsl_parse(f); - void *cfg = wx_config_load(f); + void *cfg = wx_config_load(f); - if (!cfg) { - wx_simple_messagebox("GLSLP error", "Could not load GLSLP-file %s\n", f); - return 0; - } + if (!cfg) { + wx_simple_messagebox("GLSLP error", "Could not load GLSLP-file %s\n", f); + return 0; + } - glslp_t *glslp = malloc(sizeof(glslp_t)); - memset(glslp, 0, sizeof(glslp_t)); + glslp_t *glslp = malloc(sizeof(glslp_t)); + memset(glslp, 0, sizeof(glslp_t)); - get_glslp_name(f, glslp->name, sizeof(glslp->name)); + get_glslp_name(f, glslp->name, sizeof(glslp->name)); - wx_config_get_int(cfg, "shaders", &glslp->num_shaders, 0); + wx_config_get_int(cfg, "shaders", &glslp->num_shaders, 0); - wx_config_get_bool(cfg, "filter_linear0", &glslp->input_filter_linear, -1); + wx_config_get_bool(cfg, "filter_linear0", &glslp->input_filter_linear, -1); - for (i = 0; i < glslp->num_shaders; ++i) { - struct shader *shader = &glslp->shaders[i]; + for (i = 0; i < glslp->num_shaders; ++i) { + struct shader *shader = &glslp->shaders[i]; - snprintf(s, sizeof(s) - 1, "shader%d", i); - if (!wx_config_get_string(cfg, s, t, sizeof(t), 0)) { - /* shader doesn't exist, lets break here */ - glslp->num_shaders = i; - break; - } - strcpy(s, f); - *get_filename(s) = 0; - snprintf(shader->shader_fn, sizeof(shader->shader_fn) - 1, "%s%s", s, t); - shader->shader_program = load_file(shader->shader_fn); - if (!shader->shader_program) { - wx_simple_messagebox("GLSL error", "Could not load shader %s\n", shader->shader_fn); - glslp_free(glslp); - return 0; - } - strip_parameters(shader->shader_program); - strip_defines(shader->shader_program); + snprintf(s, sizeof(s) - 1, "shader%d", i); + if (!wx_config_get_string(cfg, s, t, sizeof(t), 0)) { + /* shader doesn't exist, lets break here */ + glslp->num_shaders = i; + break; + } + strcpy(s, f); + *get_filename(s) = 0; + snprintf(shader->shader_fn, sizeof(shader->shader_fn) - 1, "%s%s", s, t); + shader->shader_program = load_file(shader->shader_fn); + if (!shader->shader_program) { + wx_simple_messagebox("GLSL error", "Could not load shader %s\n", shader->shader_fn); + glslp_free(glslp); + return 0; + } + strip_parameters(shader->shader_program); + strip_defines(shader->shader_program); - snprintf(s, sizeof(s) - 1, "alias%d", i); - wx_config_get_string(cfg, s, shader->alias, sizeof(shader->alias), 0); + snprintf(s, sizeof(s) - 1, "alias%d", i); + wx_config_get_string(cfg, s, shader->alias, sizeof(shader->alias), 0); - snprintf(s, sizeof(s) - 1, "filter_linear%d", i + 1); - wx_config_get_bool(cfg, s, &shader->filter_linear, 0); + snprintf(s, sizeof(s) - 1, "filter_linear%d", i + 1); + wx_config_get_bool(cfg, s, &shader->filter_linear, 0); - snprintf(s, sizeof(s) - 1, "wrap_mode%d", i); - wx_config_get_string(cfg, s, shader->wrap_mode, sizeof(shader->wrap_mode), 0); + snprintf(s, sizeof(s) - 1, "wrap_mode%d", i); + wx_config_get_string(cfg, s, shader->wrap_mode, sizeof(shader->wrap_mode), 0); - snprintf(s, sizeof(s) - 1, "float_framebuffer%d", i); - wx_config_get_bool(cfg, s, &shader->float_framebuffer, 0); - snprintf(s, sizeof(s) - 1, "srgb_framebuffer%d", i); - wx_config_get_bool(cfg, s, &shader->srgb_framebuffer, 0); + snprintf(s, sizeof(s) - 1, "float_framebuffer%d", i); + wx_config_get_bool(cfg, s, &shader->float_framebuffer, 0); + snprintf(s, sizeof(s) - 1, "srgb_framebuffer%d", i); + wx_config_get_bool(cfg, s, &shader->srgb_framebuffer, 0); - snprintf(s, sizeof(s) - 1, "mipmap_input%d", i); - wx_config_get_bool(cfg, s, &shader->mipmap_input, 0); + snprintf(s, sizeof(s) - 1, "mipmap_input%d", i); + wx_config_get_bool(cfg, s, &shader->mipmap_input, 0); - strcpy(shader->scale_type_x, "source"); - snprintf(s, sizeof(s) - 1, "scale_type_x%d", i); - wx_config_get_string(cfg, s, shader->scale_type_x, sizeof(shader->scale_type_x), 0); - strcpy(shader->scale_type_y, "source"); - snprintf(s, sizeof(s) - 1, "scale_type_y%d", i); - wx_config_get_string(cfg, s, shader->scale_type_y, sizeof(shader->scale_type_y), 0); - snprintf(s, sizeof(s) - 1, "scale_type%d", i); - if (wx_config_has_entry(cfg, s)) { - wx_config_get_string(cfg, s, shader->scale_type_x, sizeof(shader->scale_type_x), 0); - wx_config_get_string(cfg, s, shader->scale_type_y, sizeof(shader->scale_type_y), 0); - } + strcpy(shader->scale_type_x, "source"); + snprintf(s, sizeof(s) - 1, "scale_type_x%d", i); + wx_config_get_string(cfg, s, shader->scale_type_x, sizeof(shader->scale_type_x), 0); + strcpy(shader->scale_type_y, "source"); + snprintf(s, sizeof(s) - 1, "scale_type_y%d", i); + wx_config_get_string(cfg, s, shader->scale_type_y, sizeof(shader->scale_type_y), 0); + snprintf(s, sizeof(s) - 1, "scale_type%d", i); + if (wx_config_has_entry(cfg, s)) { + wx_config_get_string(cfg, s, shader->scale_type_x, sizeof(shader->scale_type_x), 0); + wx_config_get_string(cfg, s, shader->scale_type_y, sizeof(shader->scale_type_y), 0); + } - snprintf(s, sizeof(s) - 1, "scale_x%d", i); - wx_config_get_float(cfg, s, &shader->scale_x, 1.0f); - snprintf(s, sizeof(s) - 1, "scale_y%d", i); - wx_config_get_float(cfg, s, &shader->scale_y, 1.0f); - snprintf(s, sizeof(s) - 1, "scale%d", i); - if (wx_config_has_entry(cfg, s)) { - wx_config_get_float(cfg, s, &shader->scale_x, 1.0f); - wx_config_get_float(cfg, s, &shader->scale_y, 1.0f); - } + snprintf(s, sizeof(s) - 1, "scale_x%d", i); + wx_config_get_float(cfg, s, &shader->scale_x, 1.0f); + snprintf(s, sizeof(s) - 1, "scale_y%d", i); + wx_config_get_float(cfg, s, &shader->scale_y, 1.0f); + snprintf(s, sizeof(s) - 1, "scale%d", i); + if (wx_config_has_entry(cfg, s)) { + wx_config_get_float(cfg, s, &shader->scale_x, 1.0f); + wx_config_get_float(cfg, s, &shader->scale_y, 1.0f); + } - snprintf(s, sizeof(s) - 1, "frame_count_mod%d", i); - wx_config_get_int(cfg, s, &shader->frame_count_mod, 0); - } + snprintf(s, sizeof(s) - 1, "frame_count_mod%d", i); + wx_config_get_int(cfg, s, &shader->frame_count_mod, 0); + } - /* textures */ - glslp->num_textures = 0; - wx_config_get_string(cfg, "textures", t, sizeof(t), 0); + /* textures */ + glslp->num_textures = 0; + wx_config_get_string(cfg, "textures", t, sizeof(t), 0); - len = strlen(t); - j = 0; - sublen = 0; - for (i = 0; i < len; ++i) { - if (t[i] == ';' || i == len - 1) { - sublen = (i - j) + ((i == len - 1) ? 1 : 0) + 1; - safe_strncpy(s, t + j, sublen); - s[511 < sublen ? 511 : sublen] = 0; + len = strlen(t); + j = 0; + sublen = 0; + for (i = 0; i < len; ++i) { + if (t[i] == ';' || i == len - 1) { + sublen = (i - j) + ((i == len - 1) ? 1 : 0) + 1; + safe_strncpy(s, t + j, sublen); + s[511 < sublen ? 511 : sublen] = 0; - struct texture *tex = &glslp->textures[glslp->num_textures++]; + struct texture *tex = &glslp->textures[glslp->num_textures++]; - strcpy(tex->name, s); - wx_config_get_string(cfg, s, tex->path, sizeof(tex->path), 0); + strcpy(tex->name, s); + wx_config_get_string(cfg, s, tex->path, sizeof(tex->path), 0); - snprintf(z, sizeof(z) - 1, "%s_linear", s); - wx_config_get_bool(cfg, z, &tex->linear, 0); + snprintf(z, sizeof(z) - 1, "%s_linear", s); + wx_config_get_bool(cfg, z, &tex->linear, 0); - snprintf(z, sizeof(z) - 1, "%s_mipmap", s); - wx_config_get_bool(cfg, z, &tex->mipmap, 0); + snprintf(z, sizeof(z) - 1, "%s_mipmap", s); + wx_config_get_bool(cfg, z, &tex->mipmap, 0); - snprintf(z, sizeof(z) - 1, "%s_wrap_mode", s); - wx_config_get_string(cfg, z, tex->wrap_mode, sizeof(tex->wrap_mode), 0); + snprintf(z, sizeof(z) - 1, "%s_wrap_mode", s); + wx_config_get_string(cfg, z, tex->wrap_mode, sizeof(tex->wrap_mode), 0); - j = i + 1; - } - } + j = i + 1; + } + } - /* parameters */ - get_parameters(glslp); + /* parameters */ + get_parameters(glslp); - wx_config_get_string(cfg, "parameters", t, sizeof(t), 0); + wx_config_get_string(cfg, "parameters", t, sizeof(t), 0); - len = strlen(t); - j = 0; - sublen = 0; - for (i = 0; i < len; ++i) { - if (t[i] == ';' || i == len - 1) { - sublen = (i - j) + ((i == len - 1) ? 1 : 0) + 1; - safe_strncpy(s, t + j, sublen); - s[511 < sublen ? 511 : sublen] = 0; + len = strlen(t); + j = 0; + sublen = 0; + for (i = 0; i < len; ++i) { + if (t[i] == ';' || i == len - 1) { + sublen = (i - j) + ((i == len - 1) ? 1 : 0) + 1; + safe_strncpy(s, t + j, sublen); + s[511 < sublen ? 511 : sublen] = 0; - struct parameter *p = get_parameter(glslp, s); + struct parameter *p = get_parameter(glslp, s); - if (p) - wx_config_get_float(cfg, s, &p->default_value, 0); + if (p) + wx_config_get_float(cfg, s, &p->default_value, 0); - j = i + 1; - } - } + j = i + 1; + } + } - wx_config_free(cfg); + wx_config_free(cfg); - return glslp; + return glslp; } void glslp_free(glslp_t *p) { - int i; - for (i = 0; i < p->num_shaders; ++i) - if (p->shaders[i].shader_program) - free(p->shaders[i].shader_program); - free(p); + int i; + for (i = 0; i < p->num_shaders; ++i) + if (p->shaders[i].shader_program) + free(p->shaders[i].shader_program); + free(p); } diff --git a/src/wx-ui/wx-hostconfig.c b/src/wx-ui/wx-hostconfig.c index 5f518286..d234d788 100644 --- a/src/wx-ui/wx-hostconfig.c +++ b/src/wx-ui/wx-hostconfig.c @@ -22,179 +22,166 @@ static pcap_if_t *alldevs; static char *dev_name[20]; #endif -#define ETH_DEV_NAME_MAX 256 /* maximum device name size */ -#define ETH_DEV_DESC_MAX 256 /* maximum device description size */ -#define ETH_MAX_DEVICE 30 /* maximum ethernet devices */ -#define ETH_PROMISC 1 /* promiscuous mode = true */ -#define ETH_MAX_PACKET 1514 /* maximum ethernet packet size */ +#define ETH_DEV_NAME_MAX 256 /* maximum device name size */ +#define ETH_DEV_DESC_MAX 256 /* maximum device description size */ +#define ETH_MAX_DEVICE 30 /* maximum ethernet devices */ +#define ETH_PROMISC 1 /* promiscuous mode = true */ +#define ETH_MAX_PACKET 1514 /* maximum ethernet packet size */ #define PCAP_READ_TIMEOUT -1 #ifdef USE_PCAP_NETWORKING -static int get_network_name(char *dev_name, char *regval) -{ +static int get_network_name(char *dev_name, char *regval) { #if _WIN32 - if (dev_name[strlen( "\\Device\\NPF_" )] == '{') - { - char regkey[2048]; - HKEY reghnd; + if (dev_name[strlen("\\Device\\NPF_")] == '{') { + char regkey[2048]; + HKEY reghnd; - sprintf(regkey, "SYSTEM\\CurrentControlSet\\Control\\Network\\" - "{4D36E972-E325-11CE-BFC1-08002BE10318}\\%s\\Connection", dev_name+ - strlen("\\Device\\NPF_")); + sprintf(regkey, + "SYSTEM\\CurrentControlSet\\Control\\Network\\" + "{4D36E972-E325-11CE-BFC1-08002BE10318}\\%s\\Connection", + dev_name + strlen("\\Device\\NPF_")); - if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, regkey, 0, KEY_QUERY_VALUE, ®hnd) == ERROR_SUCCESS) - { - DWORD reglen = 2048; - DWORD regtype; + if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, regkey, 0, KEY_QUERY_VALUE, ®hnd) == ERROR_SUCCESS) { + DWORD reglen = 2048; + DWORD regtype; - if (RegQueryValueExA(reghnd, "Name", NULL, ®type, (LPBYTE)regval, ®len) == ERROR_SUCCESS) - { - RegCloseKey (reghnd); + if (RegQueryValueExA(reghnd, "Name", NULL, ®type, (LPBYTE)regval, ®len) == ERROR_SUCCESS) { + RegCloseKey(reghnd); - if ((regtype != REG_SZ) || (reglen > 2048)) - return -1; + if ((regtype != REG_SZ) || (reglen > 2048)) + return -1; - /*Name now in regval*/ - return 0; - } - RegCloseKey (reghnd); - } - } + /*Name now in regval*/ + return 0; + } + RegCloseKey(reghnd); + } + } #endif - return -1; + return -1; } #endif int hostconfig_dialog_proc(void *hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) { - void *h; + void *h; #ifdef USE_PCAP_NETWORKING - pcap_if_t *dev; - char errbuf[PCAP_ERRBUF_SIZE]; + pcap_if_t *dev; + char errbuf[PCAP_ERRBUF_SIZE]; #endif - switch (message) { - case WX_INITDIALOG:h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_NETWORK_TYPE")); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"SLiRP"); - wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_NETWORK_DEVICE")); - wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); - wx_enablewindow(h, FALSE); + switch (message) { + case WX_INITDIALOG: + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_NETWORK_TYPE")); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "SLiRP"); + wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_NETWORK_DEVICE")); + wx_sendmessage(h, WX_CB_SETCURSEL, 0, 0); + wx_enablewindow(h, FALSE); #ifdef USE_PCAP_NETWORKING - int c = 0; - int match = 0; + int c = 0; + int match = 0; - if (pcap_findalldevs(&alldevs, errbuf) != -1) - { - char *pcap_device = config_get_string(CFG_GLOBAL, NULL, "pcap_device", "nothing"); + if (pcap_findalldevs(&alldevs, errbuf) != -1) { + char *pcap_device = config_get_string(CFG_GLOBAL, NULL, "pcap_device", "nothing"); - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_NETWORK_DEVICE")); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_NETWORK_DEVICE")); - for (dev = alldevs; dev; dev = dev->next) - { - pcap_t *conn = pcap_open_live(dev->name, ETH_MAX_PACKET, ETH_PROMISC, PCAP_READ_TIMEOUT, errbuf); - int datalink = 0; + for (dev = alldevs; dev; dev = dev->next) { + pcap_t *conn = pcap_open_live(dev->name, ETH_MAX_PACKET, ETH_PROMISC, PCAP_READ_TIMEOUT, errbuf); + int datalink = 0; - if (conn) - { - datalink = pcap_datalink(conn); - pcap_close(conn); - } + if (conn) { + datalink = pcap_datalink(conn); + pcap_close(conn); + } - if (conn && datalink == DLT_EN10MB) - { - char desc[2048]; - char s[2048]; + if (conn && datalink == DLT_EN10MB) { + char desc[2048]; + char s[2048]; - if ((dev->flags & PCAP_IF_LOOPBACK) || (!strcmp("any", dev->name))) - continue; + if ((dev->flags & PCAP_IF_LOOPBACK) || (!strcmp("any", dev->name))) + continue; - if (pcap_device) - { - if (!strcmp(pcap_device, dev->name)) - match = c; - } + if (pcap_device) { + if (!strcmp(pcap_device, dev->name)) + match = c; + } - dev_name[c++] = dev->name; - if (get_network_name(dev->name, desc)) - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)dev->name); - else - { - sprintf(s, "%s - %s", dev->name, desc); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); - } - } - } - } - if (c) - { - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_NETWORK_TYPE")); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)"PCAP"); + dev_name[c++] = dev->name; + if (get_network_name(dev->name, desc)) + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)dev->name); + else { + sprintf(s, "%s - %s", dev->name, desc); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); + } + } + } + } + if (c) { + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_NETWORK_TYPE")); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM) "PCAP"); - if (config_get_int(CFG_GLOBAL, NULL, "net_type", NET_SLIRP) == NET_PCAP) - { - wx_sendmessage(h, WX_CB_SETCURSEL, 1, 0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_NETWORK_DEVICE")); - wx_sendmessage(h, WX_CB_SETCURSEL, match, 0); - wx_enablewindow(h, TRUE); - } - } + if (config_get_int(CFG_GLOBAL, NULL, "net_type", NET_SLIRP) == NET_PCAP) { + wx_sendmessage(h, WX_CB_SETCURSEL, 1, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_NETWORK_DEVICE")); + wx_sendmessage(h, WX_CB_SETCURSEL, match, 0); + wx_enablewindow(h, TRUE); + } + } #endif - return TRUE; + return TRUE; - case WX_COMMAND: - if (wParam == wxID_OK) { - int type; + case WX_COMMAND: + if (wParam == wxID_OK) { + int type; - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_NETWORK_TYPE")); - type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_NETWORK_TYPE")); + type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); #ifdef USE_PCAP_NETWORKING - if (type) /*PCAP*/ - { - int dev; + if (type) /*PCAP*/ + { + int dev; - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_NETWORK_DEVICE")); - dev = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_NETWORK_DEVICE")); + dev = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - config_set_int(CFG_GLOBAL, NULL, "net_type", NET_PCAP); - config_set_string(CFG_GLOBAL, NULL, "pcap_device", dev_name[dev]); - } - else /*SLiRP*/ - { + config_set_int(CFG_GLOBAL, NULL, "net_type", NET_PCAP); + config_set_string(CFG_GLOBAL, NULL, "pcap_device", dev_name[dev]); + } else /*SLiRP*/ + { #endif - config_set_int(CFG_GLOBAL, NULL, "net_type", NET_SLIRP); - config_set_string(CFG_GLOBAL, NULL, "pcap_device", "nothing"); + config_set_int(CFG_GLOBAL, NULL, "net_type", NET_SLIRP); + config_set_string(CFG_GLOBAL, NULL, "pcap_device", "nothing"); #ifdef USE_PCAP_NETWORKING - } + } #endif - saveconfig_global_only(); + saveconfig_global_only(); - wx_enddialog(hdlg, 1); + wx_enddialog(hdlg, 1); - return TRUE; - } else if (wParam == wxID_CANCEL) { - wx_enddialog(hdlg, 0); + return TRUE; + } else if (wParam == wxID_CANCEL) { + wx_enddialog(hdlg, 0); - return TRUE; - } else if (ID_IS("IDC_COMBO_NETWORK_TYPE")) { - int type; + return TRUE; + } else if (ID_IS("IDC_COMBO_NETWORK_TYPE")) { + int type; - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_NETWORK_TYPE")); - type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_NETWORK_DEVICE")); - if (!type) - wx_enablewindow(h, FALSE); - else - wx_enablewindow(h, TRUE); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_NETWORK_TYPE")); + type = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_COMBO_NETWORK_DEVICE")); + if (!type) + wx_enablewindow(h, FALSE); + else + wx_enablewindow(h, TRUE); - return TRUE; - } - break; - } + return TRUE; + } + break; + } - return TRUE; + return TRUE; } -int hostconfig_open(void *hwnd) { - return wx_dialogbox(hwnd, "HostConfig", hostconfig_dialog_proc); -} +int hostconfig_open(void *hwnd) { return wx_dialogbox(hwnd, "HostConfig", hostconfig_dialog_proc); } diff --git a/src/wx-ui/wx-joystickconfig.cc b/src/wx-ui/wx-joystickconfig.cc index 8956779e..b807ad79 100644 --- a/src/wx-ui/wx-joystickconfig.cc +++ b/src/wx-ui/wx-joystickconfig.cc @@ -27,295 +27,296 @@ static int joystick_config_type; static char axis_strings[AXIS_STRINGS_MAX][10] = {"X Axis", "Y Axis", "Z Axis"}; static void rebuild_axis_button_selections(void *hdlg) { - int id = IDC_CONFIG_BASE + 3; - void *h; - int joystick; - int c, d; + int id = IDC_CONFIG_BASE + 3; + void *h; + int joystick; + int c, d; - h = wx_getdlgitem(hdlg, IDC_CONFIG_BASE + 1); - joystick = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + h = wx_getdlgitem(hdlg, IDC_CONFIG_BASE + 1); + joystick = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - for (c = 0; c < joystick_get_axis_count(joystick_config_type); c++) { - int sel = c; + for (c = 0; c < joystick_get_axis_count(joystick_config_type); c++) { + int sel = c; - h = wx_getdlgitem(hdlg, id); - wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); + h = wx_getdlgitem(hdlg, id); + wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); - if (joystick) { - for (d = 0; d < plat_joystick_state[joystick - 1].nr_axes; d++) { - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)plat_joystick_state[joystick - 1].axis[d].name); - if (c < AXIS_STRINGS_MAX) { - if (!strcasecmp(axis_strings[c], plat_joystick_state[joystick - 1].axis[d].name)) - sel = d; - } - } - for (d = 0; d < plat_joystick_state[joystick - 1].nr_povs; d++) { - char s[80]; + if (joystick) { + for (d = 0; d < plat_joystick_state[joystick - 1].nr_axes; d++) { + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)plat_joystick_state[joystick - 1].axis[d].name); + if (c < AXIS_STRINGS_MAX) { + if (!strcasecmp(axis_strings[c], plat_joystick_state[joystick - 1].axis[d].name)) + sel = d; + } + } + for (d = 0; d < plat_joystick_state[joystick - 1].nr_povs; d++) { + char s[80]; - sprintf(s, "%s (X axis)", plat_joystick_state[joystick - 1].pov[d].name); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); - sprintf(s, "%s (Y axis)", plat_joystick_state[joystick - 1].pov[d].name); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); - } - wx_sendmessage(h, WX_CB_SETCURSEL, sel, 0); - wx_enablewindow(h, TRUE); - } else - wx_enablewindow(h, FALSE); + sprintf(s, "%s (X axis)", plat_joystick_state[joystick - 1].pov[d].name); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); + sprintf(s, "%s (Y axis)", plat_joystick_state[joystick - 1].pov[d].name); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); + } + wx_sendmessage(h, WX_CB_SETCURSEL, sel, 0); + wx_enablewindow(h, TRUE); + } else + wx_enablewindow(h, FALSE); - id += 2; - } + id += 2; + } - for (c = 0; c < joystick_get_button_count(joystick_config_type); c++) { - h = wx_getdlgitem(hdlg, id); - wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); + for (c = 0; c < joystick_get_button_count(joystick_config_type); c++) { + h = wx_getdlgitem(hdlg, id); + wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); - if (joystick) { - for (d = 0; d < plat_joystick_state[joystick - 1].nr_buttons; d++) - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)plat_joystick_state[joystick - 1].button[d].name); - wx_sendmessage(h, WX_CB_SETCURSEL, c, 0); - wx_enablewindow(h, TRUE); - } else - wx_enablewindow(h, FALSE); + if (joystick) { + for (d = 0; d < plat_joystick_state[joystick - 1].nr_buttons; d++) + wx_sendmessage(h, WX_CB_ADDSTRING, 0, + (LONG_PARAM)plat_joystick_state[joystick - 1].button[d].name); + wx_sendmessage(h, WX_CB_SETCURSEL, c, 0); + wx_enablewindow(h, TRUE); + } else + wx_enablewindow(h, FALSE); - id += 2; - } + id += 2; + } - for (c = 0; c < joystick_get_pov_count(joystick_config_type) * 2; c++) { - int sel = c; + for (c = 0; c < joystick_get_pov_count(joystick_config_type) * 2; c++) { + int sel = c; - h = wx_getdlgitem(hdlg, id); - wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); + h = wx_getdlgitem(hdlg, id); + wx_sendmessage(h, WX_CB_RESETCONTENT, 0, 0); - if (joystick) { - for (d = 0; d < plat_joystick_state[joystick - 1].nr_povs; d++) { - char s[80]; + if (joystick) { + for (d = 0; d < plat_joystick_state[joystick - 1].nr_povs; d++) { + char s[80]; - sprintf(s, "%s (X axis)", plat_joystick_state[joystick - 1].pov[d].name); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); - sprintf(s, "%s (Y axis)", plat_joystick_state[joystick - 1].pov[d].name); - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); - } - for (d = 0; d < plat_joystick_state[joystick - 1].nr_axes; d++) { - wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)plat_joystick_state[joystick - 1].axis[d].name); - } - wx_sendmessage(h, WX_CB_SETCURSEL, sel, 0); - wx_enablewindow(h, TRUE); - } else - wx_enablewindow(h, FALSE); - - id += 2; - } + sprintf(s, "%s (X axis)", plat_joystick_state[joystick - 1].pov[d].name); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); + sprintf(s, "%s (Y axis)", plat_joystick_state[joystick - 1].pov[d].name); + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)s); + } + for (d = 0; d < plat_joystick_state[joystick - 1].nr_axes; d++) { + wx_sendmessage(h, WX_CB_ADDSTRING, 0, (LONG_PARAM)plat_joystick_state[joystick - 1].axis[d].name); + } + wx_sendmessage(h, WX_CB_SETCURSEL, sel, 0); + wx_enablewindow(h, TRUE); + } else + wx_enablewindow(h, FALSE); + id += 2; + } } static int get_axis(void *hdlg, int id) { - void *h = wx_getdlgitem(hdlg, id); - int axis_sel = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - int nr_axes = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr - 1].nr_axes; + void *h = wx_getdlgitem(hdlg, id); + int axis_sel = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + int nr_axes = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr - 1].nr_axes; - if (axis_sel < nr_axes) - return axis_sel; + if (axis_sel < nr_axes) + return axis_sel; - axis_sel -= nr_axes; - if (axis_sel & 1) - return POV_Y | (axis_sel >> 1); - else - return POV_X | (axis_sel >> 1); + axis_sel -= nr_axes; + if (axis_sel & 1) + return POV_Y | (axis_sel >> 1); + else + return POV_X | (axis_sel >> 1); } static int get_pov(void *hdlg, int id) { - void *h = wx_getdlgitem(hdlg, id); - int axis_sel = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - int nr_povs = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr - 1].nr_povs * 2; + void *h = wx_getdlgitem(hdlg, id); + int axis_sel = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + int nr_povs = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr - 1].nr_povs * 2; - if (axis_sel < nr_povs) { - if (axis_sel & 1) - return POV_Y | (axis_sel >> 1); - else - return POV_X | (axis_sel >> 1); - } + if (axis_sel < nr_povs) { + if (axis_sel & 1) + return POV_Y | (axis_sel >> 1); + else + return POV_X | (axis_sel >> 1); + } - return axis_sel - nr_povs; + return axis_sel - nr_povs; } static int joystickconfig_dlgproc(void *hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) { - switch (message) { - case WX_INITDIALOG: { -// rebuild_axis_button_selections(hdlg); + switch (message) { + case WX_INITDIALOG: { + // rebuild_axis_button_selections(hdlg); - void *h = wx_getdlgitem(hdlg, IDC_CONFIG_BASE + 1); - int c; - int id = IDC_CONFIG_BASE + 3; - int joystick = joystick_state[joystick_nr].plat_joystick_nr; + void *h = wx_getdlgitem(hdlg, IDC_CONFIG_BASE + 1); + int c; + int id = IDC_CONFIG_BASE + 3; + int joystick = joystick_state[joystick_nr].plat_joystick_nr; - wx_sendmessage(h, WX_CB_SETCURSEL, joystick, 0); + wx_sendmessage(h, WX_CB_SETCURSEL, joystick, 0); - rebuild_axis_button_selections(hdlg); + rebuild_axis_button_selections(hdlg); - if (joystick_state[joystick_nr].plat_joystick_nr) { - int nr_axes = plat_joystick_state[joystick - 1].nr_axes; - int nr_povs = plat_joystick_state[joystick - 1].nr_povs; - for (c = 0; c < joystick_get_axis_count(joystick_config_type); c++) { - int mapping = joystick_state[joystick_nr].axis_mapping[c]; + if (joystick_state[joystick_nr].plat_joystick_nr) { + int nr_axes = plat_joystick_state[joystick - 1].nr_axes; + int nr_povs = plat_joystick_state[joystick - 1].nr_povs; + for (c = 0; c < joystick_get_axis_count(joystick_config_type); c++) { + int mapping = joystick_state[joystick_nr].axis_mapping[c]; - h = wx_getdlgitem(hdlg, id); - if (mapping & POV_X) - wx_sendmessage(h, WX_CB_SETCURSEL, nr_axes + (mapping & 3) * 2, 0); - else if (mapping & POV_Y) - wx_sendmessage(h, WX_CB_SETCURSEL, nr_axes + (mapping & 3) * 2 + 1, 0); - else - wx_sendmessage(h, WX_CB_SETCURSEL, mapping, 0); - id += 2; - } - for (c = 0; c < joystick_get_button_count(joystick_config_type); c++) { - h = wx_getdlgitem(hdlg, id); - wx_sendmessage(h, WX_CB_SETCURSEL, joystick_state[joystick_nr].button_mapping[c], 0); - id += 2; - } - for (c = 0; c < joystick_get_pov_count(joystick_config_type); c++) { - int mapping; + h = wx_getdlgitem(hdlg, id); + if (mapping & POV_X) + wx_sendmessage(h, WX_CB_SETCURSEL, nr_axes + (mapping & 3) * 2, 0); + else if (mapping & POV_Y) + wx_sendmessage(h, WX_CB_SETCURSEL, nr_axes + (mapping & 3) * 2 + 1, 0); + else + wx_sendmessage(h, WX_CB_SETCURSEL, mapping, 0); + id += 2; + } + for (c = 0; c < joystick_get_button_count(joystick_config_type); c++) { + h = wx_getdlgitem(hdlg, id); + wx_sendmessage(h, WX_CB_SETCURSEL, joystick_state[joystick_nr].button_mapping[c], 0); + id += 2; + } + for (c = 0; c < joystick_get_pov_count(joystick_config_type); c++) { + int mapping; - h = wx_getdlgitem(hdlg, id); - mapping = joystick_state[joystick_nr].pov_mapping[c][0]; - if (mapping & POV_X) - wx_sendmessage(h, WX_CB_SETCURSEL, (mapping & 3) * 2, 0); - else if (mapping & POV_Y) - wx_sendmessage(h, WX_CB_SETCURSEL, (mapping & 3) * 2 + 1, 0); - else - wx_sendmessage(h, WX_CB_SETCURSEL, mapping + nr_povs * 2, 0); - id += 2; - h = wx_getdlgitem(hdlg, id); - mapping = joystick_state[joystick_nr].pov_mapping[c][1]; - if (mapping & POV_X) - wx_sendmessage(h, WX_CB_SETCURSEL, (mapping & 3) * 2, 0); - else if (mapping & POV_Y) - wx_sendmessage(h, WX_CB_SETCURSEL, (mapping & 3) * 2 + 1, 0); - else - wx_sendmessage(h, WX_CB_SETCURSEL, mapping + nr_povs * 2, 0); - id += 2; - } - } - } - return TRUE; + h = wx_getdlgitem(hdlg, id); + mapping = joystick_state[joystick_nr].pov_mapping[c][0]; + if (mapping & POV_X) + wx_sendmessage(h, WX_CB_SETCURSEL, (mapping & 3) * 2, 0); + else if (mapping & POV_Y) + wx_sendmessage(h, WX_CB_SETCURSEL, (mapping & 3) * 2 + 1, 0); + else + wx_sendmessage(h, WX_CB_SETCURSEL, mapping + nr_povs * 2, 0); + id += 2; + h = wx_getdlgitem(hdlg, id); + mapping = joystick_state[joystick_nr].pov_mapping[c][1]; + if (mapping & POV_X) + wx_sendmessage(h, WX_CB_SETCURSEL, (mapping & 3) * 2, 0); + else if (mapping & POV_Y) + wx_sendmessage(h, WX_CB_SETCURSEL, (mapping & 3) * 2 + 1, 0); + else + wx_sendmessage(h, WX_CB_SETCURSEL, mapping + nr_povs * 2, 0); + id += 2; + } + } + } + return TRUE; - case WX_COMMAND: - switch (wParam) { - case IDC_CONFIG_BASE + 1: -// if (HIWORD(wParam) == CBN_SELCHANGE) - rebuild_axis_button_selections(hdlg); - break; + case WX_COMMAND: + switch (wParam) { + case IDC_CONFIG_BASE + 1: + // if (HIWORD(wParam) == CBN_SELCHANGE) + rebuild_axis_button_selections(hdlg); + break; - case wxID_OK: { - void *h; - int c; - int id = IDC_CONFIG_BASE + 3; + case wxID_OK: { + void *h; + int c; + int id = IDC_CONFIG_BASE + 3; - h = wx_getdlgitem(hdlg, IDC_CONFIG_BASE + 1); - joystick_state[joystick_nr].plat_joystick_nr = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + h = wx_getdlgitem(hdlg, IDC_CONFIG_BASE + 1); + joystick_state[joystick_nr].plat_joystick_nr = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - if (joystick_state[joystick_nr].plat_joystick_nr) { - for (c = 0; c < joystick_get_axis_count(joystick_config_type); c++) { - joystick_state[joystick_nr].axis_mapping[c] = get_axis(hdlg, id); - id += 2; - } - for (c = 0; c < joystick_get_button_count(joystick_config_type); c++) { - h = wx_getdlgitem(hdlg, id); - joystick_state[joystick_nr].button_mapping[c] = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); - id += 2; - } - for (c = 0; c < joystick_get_pov_count(joystick_config_type); c++) { - h = wx_getdlgitem(hdlg, id); - joystick_state[joystick_nr].pov_mapping[c][0] = get_pov(hdlg, id); - id += 2; - h = wx_getdlgitem(hdlg, id); - joystick_state[joystick_nr].pov_mapping[c][1] = get_pov(hdlg, id); - id += 2; - } - } - } - case wxID_CANCEL:wx_enddialog(hdlg, 0); - return TRUE; - } - break; - } - return FALSE; + if (joystick_state[joystick_nr].plat_joystick_nr) { + for (c = 0; c < joystick_get_axis_count(joystick_config_type); c++) { + joystick_state[joystick_nr].axis_mapping[c] = get_axis(hdlg, id); + id += 2; + } + for (c = 0; c < joystick_get_button_count(joystick_config_type); c++) { + h = wx_getdlgitem(hdlg, id); + joystick_state[joystick_nr].button_mapping[c] = wx_sendmessage(h, WX_CB_GETCURSEL, 0, 0); + id += 2; + } + for (c = 0; c < joystick_get_pov_count(joystick_config_type); c++) { + h = wx_getdlgitem(hdlg, id); + joystick_state[joystick_nr].pov_mapping[c][0] = get_pov(hdlg, id); + id += 2; + h = wx_getdlgitem(hdlg, id); + joystick_state[joystick_nr].pov_mapping[c][1] = get_pov(hdlg, id); + id += 2; + } + } + } + case wxID_CANCEL: + wx_enddialog(hdlg, 0); + return TRUE; + } + break; + } + return FALSE; } void joystickconfig_open(void *hwnd, int joy_nr, int type) { - char s[257]; - int c; + char s[257]; + int c; - PCemDialogBox dialog((wxWindow *)hwnd, joystickconfig_dlgproc); -// dialog.SetWindowStyle(wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER); + PCemDialogBox dialog((wxWindow *)hwnd, joystickconfig_dlgproc); + // dialog.SetWindowStyle(wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER); - joystick_nr = joy_nr; - joystick_config_type = type; + joystick_nr = joy_nr; + joystick_config_type = type; - dialog.SetTitle("Joystick Configuration"); + dialog.SetTitle("Joystick Configuration"); - wxFlexGridSizer *root = new wxFlexGridSizer(0, 1, 0, 0); - root->SetFlexibleDirection(wxBOTH); - root->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED); - dialog.SetSizer(root); + wxFlexGridSizer *root = new wxFlexGridSizer(0, 1, 0, 0); + root->SetFlexibleDirection(wxBOTH); + root->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED); + dialog.SetSizer(root); - wxFlexGridSizer *sizer = new wxFlexGridSizer(0, 2, 0, 0); - sizer->SetFlexibleDirection(wxBOTH); - sizer->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED); - sizer->AddGrowableCol(1); - root->Add(sizer, 1, wxEXPAND, 5); + wxFlexGridSizer *sizer = new wxFlexGridSizer(0, 2, 0, 0); + sizer->SetFlexibleDirection(wxBOTH); + sizer->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED); + sizer->AddGrowableCol(1); + root->Add(sizer, 1, wxEXPAND, 5); - int id = IDC_CONFIG_BASE; + int id = IDC_CONFIG_BASE; - sizer->Add(new wxStaticText(&dialog, id++, "Device:"), 0, wxALL | wxALIGN_CENTER_VERTICAL, 5); - wxBoxSizer *comboSizer = new wxBoxSizer(wxHORIZONTAL); - sizer->Add(comboSizer, 1, wxEXPAND, 5); - wxComboBox *cb = new wxComboBox(&dialog, id++); - cb->SetEditable(false); - comboSizer->Add(cb, 1, wxALL, 5); + sizer->Add(new wxStaticText(&dialog, id++, "Device:"), 0, wxALL | wxALIGN_CENTER_VERTICAL, 5); + wxBoxSizer *comboSizer = new wxBoxSizer(wxHORIZONTAL); + sizer->Add(comboSizer, 1, wxEXPAND, 5); + wxComboBox *cb = new wxComboBox(&dialog, id++); + cb->SetEditable(false); + comboSizer->Add(cb, 1, wxALL, 5); - cb->Append("None"); - for (c = 0; c < joysticks_present; c++) - cb->Append(plat_joystick_state[c].name); + cb->Append("None"); + for (c = 0; c < joysticks_present; c++) + cb->Append(plat_joystick_state[c].name); - for (c = 0; c < joystick_get_axis_count(type); c++) { - sprintf(s, "Axis %i:", c); - sizer->Add(new wxStaticText(&dialog, id++, s), 0, wxALL | wxALIGN_CENTER_VERTICAL, 5); - wxBoxSizer *comboSizer = new wxBoxSizer(wxHORIZONTAL); - sizer->Add(comboSizer, 1, wxEXPAND, 5); - wxComboBox *cb = new wxComboBox(&dialog, id++); - cb->SetEditable(false); - comboSizer->Add(cb, 1, wxALL, 5); - } + for (c = 0; c < joystick_get_axis_count(type); c++) { + sprintf(s, "Axis %i:", c); + sizer->Add(new wxStaticText(&dialog, id++, s), 0, wxALL | wxALIGN_CENTER_VERTICAL, 5); + wxBoxSizer *comboSizer = new wxBoxSizer(wxHORIZONTAL); + sizer->Add(comboSizer, 1, wxEXPAND, 5); + wxComboBox *cb = new wxComboBox(&dialog, id++); + cb->SetEditable(false); + comboSizer->Add(cb, 1, wxALL, 5); + } - for (c = 0; c < joystick_get_button_count(type); c++) { - sprintf(s, "Button %i:", c); - sizer->Add(new wxStaticText(&dialog, id++, s), 0, wxALL | wxALIGN_CENTER_VERTICAL, 5); - wxBoxSizer *comboSizer = new wxBoxSizer(wxHORIZONTAL); - sizer->Add(comboSizer, 1, wxEXPAND, 5); - wxComboBox *cb = new wxComboBox(&dialog, id++); - cb->SetEditable(false); - comboSizer->Add(cb, 1, wxALL, 5); - } + for (c = 0; c < joystick_get_button_count(type); c++) { + sprintf(s, "Button %i:", c); + sizer->Add(new wxStaticText(&dialog, id++, s), 0, wxALL | wxALIGN_CENTER_VERTICAL, 5); + wxBoxSizer *comboSizer = new wxBoxSizer(wxHORIZONTAL); + sizer->Add(comboSizer, 1, wxEXPAND, 5); + wxComboBox *cb = new wxComboBox(&dialog, id++); + cb->SetEditable(false); + comboSizer->Add(cb, 1, wxALL, 5); + } - for (c = 0; c < joystick_get_pov_count(type) * 2; c++) { - sprintf(s, "POV %i:", c); - sizer->Add(new wxStaticText(&dialog, id++, s), 0, wxALL | wxALIGN_CENTER_VERTICAL, 5); - wxBoxSizer *comboSizer = new wxBoxSizer(wxHORIZONTAL); - sizer->Add(comboSizer, 1, wxEXPAND, 5); - wxComboBox *cb = new wxComboBox(&dialog, id++); - cb->SetEditable(false); - comboSizer->Add(cb, 1, wxALL, 5); - } + for (c = 0; c < joystick_get_pov_count(type) * 2; c++) { + sprintf(s, "POV %i:", c); + sizer->Add(new wxStaticText(&dialog, id++, s), 0, wxALL | wxALIGN_CENTER_VERTICAL, 5); + wxBoxSizer *comboSizer = new wxBoxSizer(wxHORIZONTAL); + sizer->Add(comboSizer, 1, wxEXPAND, 5); + wxComboBox *cb = new wxComboBox(&dialog, id++); + cb->SetEditable(false); + comboSizer->Add(cb, 1, wxALL, 5); + } - wxBoxSizer *okCancelSizer = new wxBoxSizer(wxHORIZONTAL); - root->Add(okCancelSizer, 1, wxEXPAND, 5); + wxBoxSizer *okCancelSizer = new wxBoxSizer(wxHORIZONTAL); + root->Add(okCancelSizer, 1, wxEXPAND, 5); - okCancelSizer->Add(0, 0, 1, wxEXPAND, 5); - okCancelSizer->Add(new wxButton(&dialog, wxID_OK), 0, wxALL, 5); - okCancelSizer->Add(new wxButton(&dialog, wxID_CANCEL), 0, wxALL, 5); + okCancelSizer->Add(0, 0, 1, wxEXPAND, 5); + okCancelSizer->Add(new wxButton(&dialog, wxID_OK), 0, wxALL, 5); + okCancelSizer->Add(new wxButton(&dialog, wxID_CANCEL), 0, wxALL, 5); - dialog.Fit(); - dialog.OnInit(); - dialog.ShowModal(); - dialog.Destroy(); + dialog.Fit(); + dialog.OnInit(); + dialog.ShowModal(); + dialog.Destroy(); } diff --git a/src/wx-ui/wx-main.cc b/src/wx-ui/wx-main.cc index 4db7bdd0..b40873f3 100644 --- a/src/wx-ui/wx-main.cc +++ b/src/wx-ui/wx-main.cc @@ -6,8 +6,7 @@ #include #endif -extern "C" -{ +extern "C" { int pc_main(int, char **); int main(int argc, char **argv); } @@ -15,19 +14,18 @@ int main(int argc, char **argv); #if WIN32 int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, char *, int nShowCmd) #else -int main(int argc, char** argv) +int main(int argc, char **argv) #endif { #if WIN32 - int argc = __argc; - char **argv = __argv; + int argc = __argc; + char **argv = __argv; #endif - if (!pc_main(argc, argv)) - return -1; + if (!pc_main(argc, argv)) + return -1; - wxApp::SetInstance(new App()); - wxEntry(argc, argv); - return 0; + wxApp::SetInstance(new App()); + wxEntry(argc, argv); + return 0; } - diff --git a/src/wx-ui/wx-sdl2-display-win.c b/src/wx-ui/wx-sdl2-display-win.c index 2d458572..e26478a5 100644 --- a/src/wx-ui/wx-sdl2-display-win.c +++ b/src/wx-ui/wx-sdl2-display-win.c @@ -78,381 +78,397 @@ extern void toggle_fullscreen(); #define MIN_WIDTH 360 void display_resize(int width, int height) { - winsizex = width * (video_scale + 1) >> 1; - winsizey = height * (video_scale + 1) >> 1; + winsizex = width * (video_scale + 1) >> 1; + winsizey = height * (video_scale + 1) >> 1; - SDL_Rect rect; - rect.x = rect.y = 0; - rect.w = winsizex; - rect.h = winsizey; - sdl_scale(video_fullscreen_scale, rect, &rect, winsizex, winsizey); - winsizex = rect.w; - winsizey = rect.h; + SDL_Rect rect; + rect.x = rect.y = 0; + rect.w = winsizex; + rect.h = winsizey; + sdl_scale(video_fullscreen_scale, rect, &rect, winsizex, winsizey); + winsizex = rect.w; + winsizey = rect.h; - if (winsizex < MIN_WIDTH) - winsizex = MIN_WIDTH; - win_doresize = 1; - //pclog("Resizing to %d %d", width, height); + if (winsizex < MIN_WIDTH) + winsizex = MIN_WIDTH; + win_doresize = 1; + // pclog("Resizing to %d %d", width, height); } void releasemouse() { - if (mousecapture) { - SDL_SetWindowGrab(window, SDL_FALSE); - SDL_SetRelativeMouseMode(SDL_FALSE); - mousecapture = 0; - } + if (mousecapture) { + SDL_SetWindowGrab(window, SDL_FALSE); + SDL_SetRelativeMouseMode(SDL_FALSE); + mousecapture = 0; + } } int is_fullscreen() { - if (window) { - int flags = SDL_GetWindowFlags(window); - return (flags & SDL_WINDOW_FULLSCREEN) || (flags & SDL_WINDOW_FULLSCREEN_DESKTOP); - } - return 0; + if (window) { + int flags = SDL_GetWindowFlags(window); + return (flags & SDL_WINDOW_FULLSCREEN) || (flags & SDL_WINDOW_FULLSCREEN_DESKTOP); + } + return 0; } /* This is so we can disambiguate scan codes that would otherwise conflict and get passed on incorrectly. */ UINT16 convert_scan_code(UINT16 scan_code) { - switch (scan_code) { - case 0xE001:return 0xF001; - case 0xE002:return 0xF002; - case 0xE005:return 0xF005; - case 0xE006:return 0xF006; - case 0xE007:return 0xF007; - case 0xE071:return 0xF008; - case 0xE072:return 0xF009; - case 0xE07F:return 0xF00A; - case 0xE0E1:return 0xF00B; - case 0xE0EE:return 0xF00C; - case 0xE0F1:return 0xF00D; - case 0xE0FE:return 0xF00E; - case 0xE0EF:return 0xF00F; + switch (scan_code) { + case 0xE001: + return 0xF001; + case 0xE002: + return 0xF002; + case 0xE005: + return 0xF005; + case 0xE006: + return 0xF006; + case 0xE007: + return 0xF007; + case 0xE071: + return 0xF008; + case 0xE072: + return 0xF009; + case 0xE07F: + return 0xF00A; + case 0xE0E1: + return 0xF00B; + case 0xE0EE: + return 0xF00C; + case 0xE0F1: + return 0xF00D; + case 0xE0FE: + return 0xF00E; + case 0xE0EF: + return 0xF00F; - default:return scan_code; - } + default: + return scan_code; + } } void get_registry_key_map() { - char *keyName = "SYSTEM\\CurrentControlSet\\Control\\Keyboard Layout"; - char *valueName = "Scancode Map"; - char buf[32768]; - DWORD bufSize; - HKEY hKey; - int j; + char *keyName = "SYSTEM\\CurrentControlSet\\Control\\Keyboard Layout"; + char *valueName = "Scancode Map"; + char buf[32768]; + DWORD bufSize; + HKEY hKey; + int j; - /* First, prepare the default scan code map list which is 1:1. - Remappings will be inserted directly into it. - 65536 bytes so scan codes fit in easily and it's easy to find what each maps too, - since each array element is a scan code and provides for E0, etc. ones too. */ - for (j = 0; j < 65536; j++) - scancode_map[j] = convert_scan_code(j); + /* First, prepare the default scan code map list which is 1:1. + Remappings will be inserted directly into it. + 65536 bytes so scan codes fit in easily and it's easy to find what each maps too, + since each array element is a scan code and provides for E0, etc. ones too. */ + for (j = 0; j < 65536; j++) + scancode_map[j] = convert_scan_code(j); - bufSize = 32768; - pclog("Preparing scan code map list...\n"); - /* Get the scan code remappings from: - HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout */ - if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyName, 0, 1, &hKey) == ERROR_SUCCESS) { - if (RegQueryValueEx(hKey, valueName, NULL, NULL, (LPBYTE)buf, &bufSize) == ERROR_SUCCESS) { - UINT32 *bufEx2 = (UINT32 *)buf; - int scMapCount = bufEx2[2]; - pclog("%lu scan code mappings found!\n", scMapCount); - if ((bufSize != 0) && (scMapCount != 0)) { - UINT16 *bufEx = (UINT16 *)(buf + 12); - pclog("More than zero scan code mappings found, processing...\n"); - for (j = 0; j < scMapCount * 2; j += 2) { - /* Each scan code is 32-bit: 16 bits of remapped scan code, - and 16 bits of original scan code. */ - int scancode_unmapped = bufEx[j + 1]; - int scancode_mapped = bufEx[j]; + bufSize = 32768; + pclog("Preparing scan code map list...\n"); + /* Get the scan code remappings from: + HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout */ + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyName, 0, 1, &hKey) == ERROR_SUCCESS) { + if (RegQueryValueEx(hKey, valueName, NULL, NULL, (LPBYTE)buf, &bufSize) == ERROR_SUCCESS) { + UINT32 *bufEx2 = (UINT32 *)buf; + int scMapCount = bufEx2[2]; + pclog("%lu scan code mappings found!\n", scMapCount); + if ((bufSize != 0) && (scMapCount != 0)) { + UINT16 *bufEx = (UINT16 *)(buf + 12); + pclog("More than zero scan code mappings found, processing...\n"); + for (j = 0; j < scMapCount * 2; j += 2) { + /* Each scan code is 32-bit: 16 bits of remapped scan code, + and 16 bits of original scan code. */ + int scancode_unmapped = bufEx[j + 1]; + int scancode_mapped = bufEx[j]; - scancode_mapped = convert_scan_code(scancode_mapped); + scancode_mapped = convert_scan_code(scancode_mapped); - scancode_map[scancode_unmapped] = scancode_mapped; - pclog("Scan code mapping %u detected: %X -> %X\n", scancode_unmapped, scancode_mapped, scancode_map[scancode_unmapped]); - } - pclog("Done processing!\n"); - } - } - RegCloseKey(hKey); - } - pclog("Done preparing!\n"); + scancode_map[scancode_unmapped] = scancode_mapped; + pclog("Scan code mapping %u detected: %X -> %X\n", scancode_unmapped, scancode_mapped, + scancode_map[scancode_unmapped]); + } + pclog("Done processing!\n"); + } + } + RegCloseKey(hKey); + } + pclog("Done preparing!\n"); } LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) { - if (nCode < 0 || nCode != HC_ACTION || (!mousecapture && !video_fullscreen)) - return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam); + if (nCode < 0 || nCode != HC_ACTION || (!mousecapture && !video_fullscreen)) + return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam); - KBDLLHOOKSTRUCT *p = (KBDLLHOOKSTRUCT *)lParam; + KBDLLHOOKSTRUCT *p = (KBDLLHOOKSTRUCT *)lParam; - if (p->vkCode == VK_TAB && p->flags & LLKHF_ALTDOWN) - return 1; // disable alt-tab - if (p->vkCode == VK_SPACE && p->flags & LLKHF_ALTDOWN) - return 1; // disable alt-tab - if ((p->vkCode == VK_LWIN) || (p->vkCode == VK_RWIN)) - return 1; // disable windows keys - if (p->vkCode == VK_ESCAPE && p->flags & LLKHF_ALTDOWN) - return 1; // disable alt-escape - BOOL bControlKeyDown = GetAsyncKeyState(VK_CONTROL) >> ((sizeof(SHORT) * 8) - 1); // checks ctrl key pressed - if (p->vkCode == VK_ESCAPE && bControlKeyDown) - return 1; // disable ctrl-escape + if (p->vkCode == VK_TAB && p->flags & LLKHF_ALTDOWN) + return 1; // disable alt-tab + if (p->vkCode == VK_SPACE && p->flags & LLKHF_ALTDOWN) + return 1; // disable alt-tab + if ((p->vkCode == VK_LWIN) || (p->vkCode == VK_RWIN)) + return 1; // disable windows keys + if (p->vkCode == VK_ESCAPE && p->flags & LLKHF_ALTDOWN) + return 1; // disable alt-escape + BOOL bControlKeyDown = GetAsyncKeyState(VK_CONTROL) >> ((sizeof(SHORT) * 8) - 1); // checks ctrl key pressed + if (p->vkCode == VK_ESCAPE && bControlKeyDown) + return 1; // disable ctrl-escape - return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam); + return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam); } LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { - switch (message) { - case WM_COMMAND: - /* pass through commands to wx window */ - wx_winsendmessage(window_ptr, message, wParam, lParam); - return 0; - break; - case WM_INPUT: { - UINT size; - RAWINPUT *raw; + switch (message) { + case WM_COMMAND: + /* pass through commands to wx window */ + wx_winsendmessage(window_ptr, message, wParam, lParam); + return 0; + break; + case WM_INPUT: { + UINT size; + RAWINPUT *raw; - if (!infocus) - break; + if (!infocus) + break; - GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &size, sizeof(RAWINPUTHEADER)); + GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &size, sizeof(RAWINPUTHEADER)); - raw = malloc(size); + raw = malloc(size); - /* Here we read the raw input data for the keyboard */ - GetRawInputData((HRAWINPUT)(lParam), RID_INPUT, raw, &size, sizeof(RAWINPUTHEADER)); + /* Here we read the raw input data for the keyboard */ + GetRawInputData((HRAWINPUT)(lParam), RID_INPUT, raw, &size, sizeof(RAWINPUTHEADER)); - /* If the input is keyboard, we process it */ - if (raw->header.dwType == RIM_TYPEKEYBOARD) { - const RAWKEYBOARD rawKB = raw->data.keyboard; - USHORT scancode = rawKB.MakeCode; + /* If the input is keyboard, we process it */ + if (raw->header.dwType == RIM_TYPEKEYBOARD) { + const RAWKEYBOARD rawKB = raw->data.keyboard; + USHORT scancode = rawKB.MakeCode; - // pclog("Keyboard input received: S:%X VK:%X F:%X\n", c, d, e); + // pclog("Keyboard input received: S:%X VK:%X F:%X\n", c, d, e); - /* If it's not a scan code that starts with 0xE1 */ - if (!(rawKB.Flags & RI_KEY_E1)) { - if (rawKB.Flags & RI_KEY_E0) - scancode |= (0xE0 << 8); + /* If it's not a scan code that starts with 0xE1 */ + if (!(rawKB.Flags & RI_KEY_E1)) { + if (rawKB.Flags & RI_KEY_E0) + scancode |= (0xE0 << 8); - /* Remap it according to the list from the Registry */ - scancode = scancode_map[scancode]; + /* Remap it according to the list from the Registry */ + scancode = scancode_map[scancode]; - if ((scancode >> 8) == 0xF0) - scancode |= 0x100; /* Extended key code in disambiguated format */ - else if ((scancode >> 8) == 0xE0) - scancode |= 0x80; /* Normal extended key code */ + if ((scancode >> 8) == 0xF0) + scancode |= 0x100; /* Extended key code in disambiguated format */ + else if ((scancode >> 8) == 0xE0) + scancode |= 0x80; /* Normal extended key code */ - /* If it's not 0 (therefore not 0xE1, 0xE2, etc), - then pass it on to the rawinputkey array */ - if (!(scancode & 0xf00)) - rawinputkey[scancode & 0x1ff] = !(rawKB.Flags & RI_KEY_BREAK); - } - } - free(raw); - } - break; - case WM_SETFOCUS:infocus = 1; - break; - case WM_KILLFOCUS:infocus = 0; - if (is_fullscreen()) - window_dowindowed = 1; - window_doinputrelease = 1; - memset(rawinputkey, 0, sizeof(rawinputkey)); - break; - case WM_CLOSE: - case WM_DESTROY: - case WM_KEYDOWN: - case WM_SYSKEYDOWN: - case WM_KEYUP: - case WM_SYSKEYUP:return 0; + /* If it's not 0 (therefore not 0xE1, 0xE2, etc), + then pass it on to the rawinputkey array */ + if (!(scancode & 0xf00)) + rawinputkey[scancode & 0x1ff] = !(rawKB.Flags & RI_KEY_BREAK); + } + } + free(raw); + } break; + case WM_SETFOCUS: + infocus = 1; + break; + case WM_KILLFOCUS: + infocus = 0; + if (is_fullscreen()) + window_dowindowed = 1; + window_doinputrelease = 1; + memset(rawinputkey, 0, sizeof(rawinputkey)); + break; + case WM_CLOSE: + case WM_DESTROY: + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + case WM_KEYUP: + case WM_SYSKEYUP: + return 0; - case WM_SYSCOMMAND: - if (wParam == SC_KEYMENU && HIWORD(lParam) <= 0 && (video_fullscreen || mousecapture)) - return 0; /*disable ALT key for menu*/ - break; - default:break; - } - return DefWindowProc(hwnd, message, wParam, lParam); + case WM_SYSCOMMAND: + if (wParam == SC_KEYMENU && HIWORD(lParam) <= 0 && (video_fullscreen || mousecapture)) + return 0; /*disable ALT key for menu*/ + break; + default: + break; + } + return DefWindowProc(hwnd, message, wParam, lParam); } LRESULT CALLBACK subWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { - switch (message) { - default:return DefWindowProc(hwnd, message, wParam, lParam); - } - return 0; + switch (message) { + default: + return DefWindowProc(hwnd, message, wParam, lParam); + } + return 0; } int display_init() { - SDL_SetHint(SDL_HINT_WINDOWS_DISABLE_THREAD_NAMING, "1"); - if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0) { - printf("SDL could not initialize! Error: %s\n", SDL_GetError()); - return 0; - } + SDL_SetHint(SDL_HINT_WINDOWS_DISABLE_THREAD_NAMING, "1"); + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0) { + printf("SDL could not initialize! Error: %s\n", SDL_GetError()); + return 0; + } - SDL_version ver; - SDL_GetVersion(&ver); - printf("SDL %i.%i.%i initialized.\n", ver.major, ver.minor, ver.patch); + SDL_version ver; + SDL_GetVersion(&ver); + printf("SDL %i.%i.%i initialized.\n", ver.major, ver.minor, ver.patch); - return 1; + return 1; } -void display_close() { - SDL_Quit(); -} +void display_close() { SDL_Quit(); } void display_start(void *wnd_ptr) { - window_ptr = wnd_ptr; - menu_ptr = wx_getmenu(wnd_ptr); + window_ptr = wnd_ptr; + menu_ptr = wx_getmenu(wnd_ptr); - get_registry_key_map(); + get_registry_key_map(); - infocus = 1; + infocus = 1; - atexit(releasemouse); - rendererMutex = SDL_CreateMutex(); - rendererCond = SDL_CreateCond(); - renderer_start(); + atexit(releasemouse); + rendererMutex = SDL_CreateMutex(); + rendererCond = SDL_CreateCond(); + renderer_start(); } void display_stop() { - renderer_stop(10 * 1000); + renderer_stop(10 * 1000); - SDL_DestroyMutex(rendererMutex); - SDL_DestroyCond(rendererCond); - SDL_DetachThread(renderthread); - releasemouse(); + SDL_DestroyMutex(rendererMutex); + SDL_DestroyCond(rendererCond); + SDL_DetachThread(renderthread); + releasemouse(); } void sdl_set_window_title(const char *title) { - if (hwnd && !is_fullscreen()) - SetWindowText(hwnd, title); + if (hwnd && !is_fullscreen()) + SetWindowText(hwnd, title); } int get_border_size(int *top, int *left, int *bottom, int *right) { - int res = SDL_GetWindowBordersSize(window, top, left, bottom, right); - if (top) - *top -= GetSystemMetrics(SM_CYMENUSIZE); + int res = SDL_GetWindowBordersSize(window, top, left, bottom, right); + if (top) + *top -= GetSystemMetrics(SM_CYMENUSIZE); - return res; + return res; } static const struct { - SDL_Scancode sdl; - int system; -} SDLScancodeToSystemScancode[] = { - {SDL_SCANCODE_A, 0x1e}, - {SDL_SCANCODE_B, 0x30}, - {SDL_SCANCODE_C, 0x2e}, - {SDL_SCANCODE_D, 0x20}, - {SDL_SCANCODE_E, 0x12}, - {SDL_SCANCODE_F, 0x21}, - {SDL_SCANCODE_G, 0x22}, - {SDL_SCANCODE_H, 0x23}, - {SDL_SCANCODE_I, 0x17}, - {SDL_SCANCODE_J, 0x24}, - {SDL_SCANCODE_K, 0x25}, - {SDL_SCANCODE_L, 0x26}, - {SDL_SCANCODE_M, 0x32}, - {SDL_SCANCODE_N, 0x31}, - {SDL_SCANCODE_O, 0x18}, - {SDL_SCANCODE_P, 0x19}, - {SDL_SCANCODE_Q, 0x10}, - {SDL_SCANCODE_R, 0x13}, - {SDL_SCANCODE_S, 0x1f}, - {SDL_SCANCODE_T, 0x14}, - {SDL_SCANCODE_U, 0x16}, - {SDL_SCANCODE_V, 0x2f}, - {SDL_SCANCODE_W, 0x11}, - {SDL_SCANCODE_X, 0x2d}, - {SDL_SCANCODE_Y, 0x15}, - {SDL_SCANCODE_Z, 0x2c}, - {SDL_SCANCODE_0, 0x0B}, - {SDL_SCANCODE_1, 0x02}, - {SDL_SCANCODE_2, 0x03}, - {SDL_SCANCODE_3, 0x04}, - {SDL_SCANCODE_4, 0x05}, - {SDL_SCANCODE_5, 0x06}, - {SDL_SCANCODE_6, 0x07}, - {SDL_SCANCODE_7, 0x08}, - {SDL_SCANCODE_8, 0x09}, - {SDL_SCANCODE_9, 0x0A}, - {SDL_SCANCODE_GRAVE, 0x29}, - {SDL_SCANCODE_MINUS, 0x0c}, - {SDL_SCANCODE_EQUALS, 0x0d}, - {SDL_SCANCODE_NONUSBACKSLASH, 0x56}, - {SDL_SCANCODE_BACKSLASH, 0x2b}, - {SDL_SCANCODE_BACKSPACE, 0x0e}, - {SDL_SCANCODE_SPACE, 0x39}, - {SDL_SCANCODE_TAB, 0x0f}, - {SDL_SCANCODE_CAPSLOCK, 0x3a}, - {SDL_SCANCODE_LSHIFT, 0x2a}, - {SDL_SCANCODE_LCTRL, 0x1d}, - {SDL_SCANCODE_LGUI, 0xdb}, - {SDL_SCANCODE_LALT, 0x38}, - {SDL_SCANCODE_RSHIFT, 0x36}, - {SDL_SCANCODE_RCTRL, 0x9d}, - {SDL_SCANCODE_RGUI, 0xdc}, - {SDL_SCANCODE_RALT, 0xb8}, - {SDL_SCANCODE_SYSREQ, 0x54}, - {SDL_SCANCODE_APPLICATION, 0xdd}, - {SDL_SCANCODE_RETURN, 0x1c}, - {SDL_SCANCODE_ESCAPE, 0x01}, - {SDL_SCANCODE_F1, 0x3B}, - {SDL_SCANCODE_F2, 0x3C}, - {SDL_SCANCODE_F3, 0x3D}, - {SDL_SCANCODE_F4, 0x3e}, - {SDL_SCANCODE_F5, 0x3f}, - {SDL_SCANCODE_F6, 0x40}, - {SDL_SCANCODE_F7, 0x41}, - {SDL_SCANCODE_F8, 0x42}, - {SDL_SCANCODE_F9, 0x43}, - {SDL_SCANCODE_F10, 0x44}, - {SDL_SCANCODE_F11, 0x57}, - {SDL_SCANCODE_F12, 0x58}, - {SDL_SCANCODE_SCROLLLOCK, 0x46}, - {SDL_SCANCODE_LEFTBRACKET, 0x1a}, - {SDL_SCANCODE_RIGHTBRACKET, 0x1b}, - {SDL_SCANCODE_INSERT, 0xd2}, - {SDL_SCANCODE_HOME, 0xc7}, - {SDL_SCANCODE_PAGEUP, 0xc9}, - {SDL_SCANCODE_DELETE, 0xd3}, - {SDL_SCANCODE_END, 0xcf}, - {SDL_SCANCODE_PAGEDOWN, 0xd1}, - {SDL_SCANCODE_UP, 0xc8}, - {SDL_SCANCODE_LEFT, 0xcb}, - {SDL_SCANCODE_DOWN, 0xd0}, - {SDL_SCANCODE_RIGHT, 0xcd}, - {SDL_SCANCODE_NUMLOCKCLEAR, 0x45}, - {SDL_SCANCODE_KP_DIVIDE, 0xb5}, - {SDL_SCANCODE_KP_MULTIPLY, 0x37}, - {SDL_SCANCODE_KP_MINUS, 0x4a}, - {SDL_SCANCODE_KP_PLUS, 0x4e}, - {SDL_SCANCODE_KP_ENTER, 0x9c}, - {SDL_SCANCODE_KP_PERIOD, 0x53}, - {SDL_SCANCODE_KP_0, 0x52}, - {SDL_SCANCODE_KP_1, 0x4f}, - {SDL_SCANCODE_KP_2, 0x50}, - {SDL_SCANCODE_KP_3, 0x51}, - {SDL_SCANCODE_KP_4, 0x48}, - {SDL_SCANCODE_KP_5, 0x4c}, - {SDL_SCANCODE_KP_6, 0x4d}, - {SDL_SCANCODE_KP_7, 0x47}, - {SDL_SCANCODE_KP_8, 0x48}, - {SDL_SCANCODE_KP_9, 0x49}, - {SDL_SCANCODE_SEMICOLON, 0x27}, - {SDL_SCANCODE_APOSTROPHE, 0x28}, - {SDL_SCANCODE_COMMA, 0x33}, - {SDL_SCANCODE_PERIOD, 0x34}, - {SDL_SCANCODE_SLASH, 0x35}, - {SDL_SCANCODE_PRINTSCREEN, 0xb7}}; + SDL_Scancode sdl; + int system; +} SDLScancodeToSystemScancode[] = {{SDL_SCANCODE_A, 0x1e}, + {SDL_SCANCODE_B, 0x30}, + {SDL_SCANCODE_C, 0x2e}, + {SDL_SCANCODE_D, 0x20}, + {SDL_SCANCODE_E, 0x12}, + {SDL_SCANCODE_F, 0x21}, + {SDL_SCANCODE_G, 0x22}, + {SDL_SCANCODE_H, 0x23}, + {SDL_SCANCODE_I, 0x17}, + {SDL_SCANCODE_J, 0x24}, + {SDL_SCANCODE_K, 0x25}, + {SDL_SCANCODE_L, 0x26}, + {SDL_SCANCODE_M, 0x32}, + {SDL_SCANCODE_N, 0x31}, + {SDL_SCANCODE_O, 0x18}, + {SDL_SCANCODE_P, 0x19}, + {SDL_SCANCODE_Q, 0x10}, + {SDL_SCANCODE_R, 0x13}, + {SDL_SCANCODE_S, 0x1f}, + {SDL_SCANCODE_T, 0x14}, + {SDL_SCANCODE_U, 0x16}, + {SDL_SCANCODE_V, 0x2f}, + {SDL_SCANCODE_W, 0x11}, + {SDL_SCANCODE_X, 0x2d}, + {SDL_SCANCODE_Y, 0x15}, + {SDL_SCANCODE_Z, 0x2c}, + {SDL_SCANCODE_0, 0x0B}, + {SDL_SCANCODE_1, 0x02}, + {SDL_SCANCODE_2, 0x03}, + {SDL_SCANCODE_3, 0x04}, + {SDL_SCANCODE_4, 0x05}, + {SDL_SCANCODE_5, 0x06}, + {SDL_SCANCODE_6, 0x07}, + {SDL_SCANCODE_7, 0x08}, + {SDL_SCANCODE_8, 0x09}, + {SDL_SCANCODE_9, 0x0A}, + {SDL_SCANCODE_GRAVE, 0x29}, + {SDL_SCANCODE_MINUS, 0x0c}, + {SDL_SCANCODE_EQUALS, 0x0d}, + {SDL_SCANCODE_NONUSBACKSLASH, 0x56}, + {SDL_SCANCODE_BACKSLASH, 0x2b}, + {SDL_SCANCODE_BACKSPACE, 0x0e}, + {SDL_SCANCODE_SPACE, 0x39}, + {SDL_SCANCODE_TAB, 0x0f}, + {SDL_SCANCODE_CAPSLOCK, 0x3a}, + {SDL_SCANCODE_LSHIFT, 0x2a}, + {SDL_SCANCODE_LCTRL, 0x1d}, + {SDL_SCANCODE_LGUI, 0xdb}, + {SDL_SCANCODE_LALT, 0x38}, + {SDL_SCANCODE_RSHIFT, 0x36}, + {SDL_SCANCODE_RCTRL, 0x9d}, + {SDL_SCANCODE_RGUI, 0xdc}, + {SDL_SCANCODE_RALT, 0xb8}, + {SDL_SCANCODE_SYSREQ, 0x54}, + {SDL_SCANCODE_APPLICATION, 0xdd}, + {SDL_SCANCODE_RETURN, 0x1c}, + {SDL_SCANCODE_ESCAPE, 0x01}, + {SDL_SCANCODE_F1, 0x3B}, + {SDL_SCANCODE_F2, 0x3C}, + {SDL_SCANCODE_F3, 0x3D}, + {SDL_SCANCODE_F4, 0x3e}, + {SDL_SCANCODE_F5, 0x3f}, + {SDL_SCANCODE_F6, 0x40}, + {SDL_SCANCODE_F7, 0x41}, + {SDL_SCANCODE_F8, 0x42}, + {SDL_SCANCODE_F9, 0x43}, + {SDL_SCANCODE_F10, 0x44}, + {SDL_SCANCODE_F11, 0x57}, + {SDL_SCANCODE_F12, 0x58}, + {SDL_SCANCODE_SCROLLLOCK, 0x46}, + {SDL_SCANCODE_LEFTBRACKET, 0x1a}, + {SDL_SCANCODE_RIGHTBRACKET, 0x1b}, + {SDL_SCANCODE_INSERT, 0xd2}, + {SDL_SCANCODE_HOME, 0xc7}, + {SDL_SCANCODE_PAGEUP, 0xc9}, + {SDL_SCANCODE_DELETE, 0xd3}, + {SDL_SCANCODE_END, 0xcf}, + {SDL_SCANCODE_PAGEDOWN, 0xd1}, + {SDL_SCANCODE_UP, 0xc8}, + {SDL_SCANCODE_LEFT, 0xcb}, + {SDL_SCANCODE_DOWN, 0xd0}, + {SDL_SCANCODE_RIGHT, 0xcd}, + {SDL_SCANCODE_NUMLOCKCLEAR, 0x45}, + {SDL_SCANCODE_KP_DIVIDE, 0xb5}, + {SDL_SCANCODE_KP_MULTIPLY, 0x37}, + {SDL_SCANCODE_KP_MINUS, 0x4a}, + {SDL_SCANCODE_KP_PLUS, 0x4e}, + {SDL_SCANCODE_KP_ENTER, 0x9c}, + {SDL_SCANCODE_KP_PERIOD, 0x53}, + {SDL_SCANCODE_KP_0, 0x52}, + {SDL_SCANCODE_KP_1, 0x4f}, + {SDL_SCANCODE_KP_2, 0x50}, + {SDL_SCANCODE_KP_3, 0x51}, + {SDL_SCANCODE_KP_4, 0x48}, + {SDL_SCANCODE_KP_5, 0x4c}, + {SDL_SCANCODE_KP_6, 0x4d}, + {SDL_SCANCODE_KP_7, 0x47}, + {SDL_SCANCODE_KP_8, 0x48}, + {SDL_SCANCODE_KP_9, 0x49}, + {SDL_SCANCODE_SEMICOLON, 0x27}, + {SDL_SCANCODE_APOSTROPHE, 0x28}, + {SDL_SCANCODE_COMMA, 0x33}, + {SDL_SCANCODE_PERIOD, 0x34}, + {SDL_SCANCODE_SLASH, 0x35}, + {SDL_SCANCODE_PRINTSCREEN, 0xb7}}; int sdl_scancode(SDL_Scancode scancode) { - int i; - for (i = 0; i < SDL_arraysize(SDLScancodeToSystemScancode); ++i) { - if (SDLScancodeToSystemScancode[i].sdl == scancode) { - return SDLScancodeToSystemScancode[i].system; - } - } - return -1; + int i; + for (i = 0; i < SDL_arraysize(SDLScancodeToSystemScancode); ++i) { + if (SDLScancodeToSystemScancode[i].sdl == scancode) { + return SDLScancodeToSystemScancode[i].system; + } + } + return -1; } SDL_Event event; @@ -464,468 +480,473 @@ uint32_t render_frame_time = 0; uint32_t render_frames = 0; void window_setup() { - SDL_SetHint(SDL_HINT_GRAB_KEYBOARD, "0"); - SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1"); - SDL_SetHint(SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4, "1"); + SDL_SetHint(SDL_HINT_GRAB_KEYBOARD, "0"); + SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1"); + SDL_SetHint(SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4, "1"); - if (start_in_fullscreen) { - start_in_fullscreen = 0; - window_dofullscreen = 1; - window_doinputgrab = 1; - } + if (start_in_fullscreen) { + start_in_fullscreen = 0; + window_dofullscreen = 1; + window_doinputgrab = 1; + } - if (window_remember) { - rect.x = window_x; - rect.y = window_y; - //pclog("window_setup. setting window position to %dx%d\n", rect.x, rect.y); - rect.w = window_w; - rect.h = window_h; - } else { - rect.x = SDL_WINDOWPOS_CENTERED; - rect.y = SDL_WINDOWPOS_CENTERED; - //pclog("window_setup. setting window position with SDL_WINDOWPOS_CENTERED\n"); - rect.w = 640; - rect.h = 480; - } + if (window_remember) { + rect.x = window_x; + rect.y = window_y; + // pclog("window_setup. setting window position to %dx%d\n", rect.x, rect.y); + rect.w = window_w; + rect.h = window_h; + } else { + rect.x = SDL_WINDOWPOS_CENTERED; + rect.y = SDL_WINDOWPOS_CENTERED; + // pclog("window_setup. setting window position with SDL_WINDOWPOS_CENTERED\n"); + rect.w = 640; + rect.h = 480; + } - if (vid_resize == 2) { - rect.w = custom_resolution_width; - rect.h = custom_resolution_height; - } + if (vid_resize == 2) { + rect.w = custom_resolution_width; + rect.h = custom_resolution_height; + } } int window_create() { - int i; - WNDCLASSEX wincl; /* Data structure for the windowclass */ + int i; + WNDCLASSEX wincl; /* Data structure for the windowclass */ - hinstance = (HINSTANCE)GetModuleHandle(NULL); - /* The Window structure */ - wincl.hInstance = hinstance; - wincl.lpszClassName = szClassName; - wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */ - wincl.style = CS_DBLCLKS; /* Catch double-clicks */ - wincl.cbSize = sizeof(WNDCLASSEX); + hinstance = (HINSTANCE)GetModuleHandle(NULL); + /* The Window structure */ + wincl.hInstance = hinstance; + wincl.lpszClassName = szClassName; + wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */ + wincl.style = CS_DBLCLKS; /* Catch double-clicks */ + wincl.cbSize = sizeof(WNDCLASSEX); - /* Use default icon and mouse-pointer */ - wincl.hIcon = LoadIcon(NULL, IDI_APPLICATION); - wincl.hIconSm = LoadIcon(NULL, IDI_APPLICATION); - wincl.hCursor = NULL; // LoadCursor (NULL, IDC_ARROW); - wincl.lpszMenuName = NULL; /* No menu */ - wincl.cbClsExtra = 0; /* No extra bytes after the window class */ - wincl.cbWndExtra = 0; /* structure or the window instance */ - /* Use Windows's default color as the background of the window */ - wincl.hbrBackground = (HBRUSH)COLOR_BACKGROUND; + /* Use default icon and mouse-pointer */ + wincl.hIcon = LoadIcon(NULL, IDI_APPLICATION); + wincl.hIconSm = LoadIcon(NULL, IDI_APPLICATION); + wincl.hCursor = NULL; // LoadCursor (NULL, IDC_ARROW); + wincl.lpszMenuName = NULL; /* No menu */ + wincl.cbClsExtra = 0; /* No extra bytes after the window class */ + wincl.cbWndExtra = 0; /* structure or the window instance */ + /* Use Windows's default color as the background of the window */ + wincl.hbrBackground = (HBRUSH)COLOR_BACKGROUND; - /* Register the window class, and if it fails quit the program */ - if (!RegisterClassEx(&wincl)) - return 0; + /* Register the window class, and if it fails quit the program */ + if (!RegisterClassEx(&wincl)) + return 0; - wincl.lpszClassName = szSubClassName; - wincl.lpfnWndProc = subWindowProcedure; /* This function is called by windows */ + wincl.lpszClassName = szSubClassName; + wincl.lpfnWndProc = subWindowProcedure; /* This function is called by windows */ - if (!RegisterClassEx(&wincl)) - return 0; + if (!RegisterClassEx(&wincl)) + return 0; - menu = CreateMenu(); - HMENU native_menu = (HMENU)wx_getnativemenu(menu_ptr); - int count = GetMenuItemCount(native_menu); - MENUITEMINFO info; - for (i = 0; i < count; ++i) { - char label[256]; - memset(&info, 0, sizeof(MENUITEMINFO)); - info.cbSize = sizeof(MENUITEMINFO); - info.fMask = MIIM_TYPE | MIIM_ID; - info.fType = MFT_STRING; - info.cch = 256; - info.dwTypeData = label; - if (GetMenuItemInfo(native_menu, i, 1, &info)) - AppendMenu(menu, MF_STRING | MF_POPUP, (UINT)GetSubMenu(native_menu, i), info.dwTypeData); - } + menu = CreateMenu(); + HMENU native_menu = (HMENU)wx_getnativemenu(menu_ptr); + int count = GetMenuItemCount(native_menu); + MENUITEMINFO info; + for (i = 0; i < count; ++i) { + char label[256]; + memset(&info, 0, sizeof(MENUITEMINFO)); + info.cbSize = sizeof(MENUITEMINFO); + info.fMask = MIIM_TYPE | MIIM_ID; + info.fType = MFT_STRING; + info.cch = 256; + info.dwTypeData = label; + if (GetMenuItemInfo(native_menu, i, 1, &info)) + AppendMenu(menu, MF_STRING | MF_POPUP, (UINT)GetSubMenu(native_menu, i), info.dwTypeData); + } - /* The class is registered, let's create the program*/ - hwnd = CreateWindowEx( - 0, /* Extended possibilites for variation */ - szClassName, /* Classname */ - "PCem " PCEM_VERSION_STRING, /* Title Text */ - WS_OVERLAPPEDWINDOW & ~WS_SIZEBOX, /* default window */ - CW_USEDEFAULT, /* Windows decides the position */ - CW_USEDEFAULT, /* where the window ends up on the screen */ - 640 + (GetSystemMetrics(SM_CXFIXEDFRAME) * 2), /* The programs width */ - 480 + (GetSystemMetrics(SM_CYFIXEDFRAME) * 2) + GetSystemMetrics(SM_CYMENUSIZE) + GetSystemMetrics(SM_CYCAPTION) + 1, /* and height in pixels */ - HWND_DESKTOP, /* The window is a child-window to desktop */ - menu, /* Menu */ - hinstance, /* Program Instance handler */ - NULL /* No Window Creation data */ - ); + /* The class is registered, let's create the program*/ + hwnd = CreateWindowEx(0, /* Extended possibilites for variation */ + szClassName, /* Classname */ + "PCem " PCEM_VERSION_STRING, /* Title Text */ + WS_OVERLAPPEDWINDOW & ~WS_SIZEBOX, /* default window */ + CW_USEDEFAULT, /* Windows decides the position */ + CW_USEDEFAULT, /* where the window ends up on the screen */ + 640 + (GetSystemMetrics(SM_CXFIXEDFRAME) * 2), /* The programs width */ + 480 + (GetSystemMetrics(SM_CYFIXEDFRAME) * 2) + GetSystemMetrics(SM_CYMENUSIZE) + + GetSystemMetrics(SM_CYCAPTION) + 1, /* and height in pixels */ + HWND_DESKTOP, /* The window is a child-window to desktop */ + menu, /* Menu */ + hinstance, /* Program Instance handler */ + NULL /* No Window Creation data */ + ); - /* Make the window visible on the screen */ - ShowWindow(hwnd, 1); + /* Make the window visible on the screen */ + ShowWindow(hwnd, 1); - memset(rawinputkey, 0, sizeof(rawinputkey)); - device.usUsagePage = 0x01; - device.usUsage = 0x06; - device.dwFlags = RIDEV_NOHOTKEYS; - device.hwndTarget = hwnd; + memset(rawinputkey, 0, sizeof(rawinputkey)); + device.usUsagePage = 0x01; + device.usUsage = 0x06; + device.dwFlags = RIDEV_NOHOTKEYS; + device.hwndTarget = hwnd; - if (RegisterRawInputDevices(&device, 1, sizeof(device))) - pclog("Raw input registered!\n"); - else - pclog("Raw input registration failed!\n"); + if (RegisterRawInputDevices(&device, 1, sizeof(device))) + pclog("Raw input registered!\n"); + else + pclog("Raw input registration failed!\n"); - hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandle(NULL), 0); + hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandle(NULL), 0); - if (requested_render_driver.sdl_window_params & SDL_WINDOW_OPENGL) { - /* create dummy window for opengl */ - dummy_window = SDL_CreateWindow("GL3 test", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1, 1, SDL_WINDOW_HIDDEN | SDL_WINDOW_OPENGL); - if (dummy_window) { - char ptr[32]; - snprintf(ptr, 31, "%p", dummy_window); - ptr[31] = 0; - SDL_SetHint(SDL_HINT_VIDEO_WINDOW_SHARE_PIXEL_FORMAT, ptr); - } - } - window = SDL_CreateWindowFrom(hwnd); - if (!window) { - char message[200]; - sprintf(message, - "SDL window could not be created! Error: %s\n", - SDL_GetError()); - wx_messagebox(window_ptr, message, "SDL Error", WX_MB_OK); - return 0; - } + if (requested_render_driver.sdl_window_params & SDL_WINDOW_OPENGL) { + /* create dummy window for opengl */ + dummy_window = SDL_CreateWindow("GL3 test", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1, 1, + SDL_WINDOW_HIDDEN | SDL_WINDOW_OPENGL); + if (dummy_window) { + char ptr[32]; + snprintf(ptr, 31, "%p", dummy_window); + ptr[31] = 0; + SDL_SetHint(SDL_HINT_VIDEO_WINDOW_SHARE_PIXEL_FORMAT, ptr); + } + } + window = SDL_CreateWindowFrom(hwnd); + if (!window) { + char message[200]; + sprintf(message, "SDL window could not be created! Error: %s\n", SDL_GetError()); + wx_messagebox(window_ptr, message, "SDL Error", WX_MB_OK); + return 0; + } - // set size before position, so that SDL_WINDOWPOS_CENTERED can work. - SDL_SetWindowSize(window, rect.w, rect.h); - SDL_SetWindowPosition(window, rect.x, rect.y); - //pclog("window_create Setting window position to %dx%d\n", rect.x, rect.y); + // set size before position, so that SDL_WINDOWPOS_CENTERED can work. + SDL_SetWindowSize(window, rect.w, rect.h); + SDL_SetWindowPosition(window, rect.x, rect.y); + // pclog("window_create Setting window position to %dx%d\n", rect.x, rect.y); - if (vid_resize) - window_dosetresize = 1; + if (vid_resize) + window_dosetresize = 1; - render_time = 0; - render_fps = 0; - render_frame_time = SDL_GetTicks(); - render_frames = 0; - return 1; + render_time = 0; + render_fps = 0; + render_frame_time = SDL_GetTicks(); + render_frames = 0; + return 1; } void window_close() { - int i; - sdl_renderer_close(); + int i; + sdl_renderer_close(); - if (window) { - // Do this before removing the menu or else the sizes will be incorrect. - SDL_GetWindowPosition(window, &rect.x, &rect.y); - //pclog("window_close Getting window position. is %dx%d\n", rect.x, rect.y); - SDL_GetWindowSize(window, &rect.w, &rect.h); - if (window_remember) { - // These are incorrectly set sometimes from SDL_WINDOWEVENT_MOVED so we ensure they have the correct value. - window_x = rect.x; - window_y = rect.y; - } - } + if (window) { + // Do this before removing the menu or else the sizes will be incorrect. + SDL_GetWindowPosition(window, &rect.x, &rect.y); + // pclog("window_close Getting window position. is %dx%d\n", rect.x, rect.y); + SDL_GetWindowSize(window, &rect.w, &rect.h); + if (window_remember) { + // These are incorrectly set sometimes from SDL_WINDOWEVENT_MOVED so we ensure they have the correct + // value. + window_x = rect.x; + window_y = rect.y; + } + } - int count = GetMenuItemCount(menu); - for (i = 0; i < count; ++i) - RemoveMenu(menu, 0, MF_BYPOSITION); - DestroyMenu(menu); - menu = 0; - SetMenu(hwnd, 0); + int count = GetMenuItemCount(menu); + for (i = 0; i < count; ++i) + RemoveMenu(menu, 0, MF_BYPOSITION); + DestroyMenu(menu); + menu = 0; + SetMenu(hwnd, 0); - if (window) { - SDL_DestroyWindow(window); - } - window = NULL; + if (window) { + SDL_DestroyWindow(window); + } + window = NULL; - if (dummy_window) { - SDL_SetHint(SDL_HINT_VIDEO_WINDOW_SHARE_PIXEL_FORMAT, ""); - SDL_DestroyWindow(dummy_window); - } - dummy_window = NULL; + if (dummy_window) { + SDL_SetHint(SDL_HINT_VIDEO_WINDOW_SHARE_PIXEL_FORMAT, ""); + SDL_DestroyWindow(dummy_window); + } + dummy_window = NULL; - UnhookWindowsHookEx(hKeyboardHook); - DestroyWindow(hwnd); - hwnd = NULL; + UnhookWindowsHookEx(hKeyboardHook); + DestroyWindow(hwnd); + hwnd = NULL; - UnregisterClass(szSubClassName, hinstance); - UnregisterClass(szClassName, hinstance); + UnregisterClass(szSubClassName, hinstance); + UnregisterClass(szClassName, hinstance); } int render() { - uint64_t start_time = timer_read(); - uint64_t end_time; + uint64_t start_time = timer_read(); + uint64_t end_time; - if (window_doreset) { - pclog("window_doreset\n"); - window_doreset = 0; - renderer_doreset = 0; - return 0; - } - if (window_dosetresize) { - window_dosetresize = 0; - SDL_GetWindowSize(window, &rect.w, &rect.h); - SDL_SetWindowResizable(window, vid_resize == 1); - SDL_SetWindowSize(window, rect.w, rect.h); + if (window_doreset) { + pclog("window_doreset\n"); + window_doreset = 0; + renderer_doreset = 0; + return 0; + } + if (window_dosetresize) { + window_dosetresize = 0; + SDL_GetWindowSize(window, &rect.w, &rect.h); + SDL_SetWindowResizable(window, vid_resize == 1); + SDL_SetWindowSize(window, rect.w, rect.h); - if (vid_resize == 2) - SDL_SetWindowSize(window, custom_resolution_width, custom_resolution_height); + if (vid_resize == 2) + SDL_SetWindowSize(window, custom_resolution_width, custom_resolution_height); - device_force_redraw(); - } - if (renderer_doreset) { - pclog("renderer_doreset\n"); - renderer_doreset = 0; - sdl_renderer_close(); - sdl_renderer_init(window); + device_force_redraw(); + } + if (renderer_doreset) { + pclog("renderer_doreset\n"); + renderer_doreset = 0; + sdl_renderer_close(); + sdl_renderer_init(window); - device_force_redraw(); - video_wait_for_blit(); - } - while (SDL_PollEvent(&event)) { - switch (event.type) { - case SDL_MOUSEBUTTONUP: - if (!mousecapture) { - if (event.button.button == SDL_BUTTON_LEFT && !pause) { - window_doinputgrab = 1; - if (video_fullscreen) - window_dofullscreen = 1; - } - } else if (event.button.button == SDL_BUTTON_MIDDLE && !is_fullscreen() && !(mouse_get_type(mouse_type) & MOUSE_TYPE_3BUTTON)) - window_doinputrelease = 1; - break; - case SDL_MOUSEWHEEL: - if (mousecapture) - mouse_wheel_update(event.wheel.y); - break; - case SDL_WINDOWEVENT: - if (event.window.event == SDL_WINDOWEVENT_CLOSE) - wx_stop_emulation(window_ptr); - if (event.window.event == SDL_WINDOWEVENT_RESIZED) - device_force_redraw(); + device_force_redraw(); + video_wait_for_blit(); + } + while (SDL_PollEvent(&event)) { + switch (event.type) { + case SDL_MOUSEBUTTONUP: + if (!mousecapture) { + if (event.button.button == SDL_BUTTON_LEFT && !pause) { + window_doinputgrab = 1; + if (video_fullscreen) + window_dofullscreen = 1; + } + } else if (event.button.button == SDL_BUTTON_MIDDLE && !is_fullscreen() && + !(mouse_get_type(mouse_type) & MOUSE_TYPE_3BUTTON)) + window_doinputrelease = 1; + break; + case SDL_MOUSEWHEEL: + if (mousecapture) + mouse_wheel_update(event.wheel.y); + break; + case SDL_WINDOWEVENT: + if (event.window.event == SDL_WINDOWEVENT_CLOSE) + wx_stop_emulation(window_ptr); + if (event.window.event == SDL_WINDOWEVENT_RESIZED) + device_force_redraw(); - if (window_remember) { - int flags = SDL_GetWindowFlags(window); - if (!(flags & SDL_WINDOW_FULLSCREEN) && !(flags & SDL_WINDOW_FULLSCREEN_DESKTOP)) { - if (event.window.event == SDL_WINDOWEVENT_MOVED) { - window_x = event.window.data1; - window_y = event.window.data2; - //pclog("render window_remember SDL_WINDOWEVENT_MOVED. setting window_x/y to %dx%d\n", window_x, window_y); - } else if (event.window.event == SDL_WINDOWEVENT_RESIZED) { - window_w = event.window.data1; - window_h = event.window.data2; - } - // save_window_pos = 1; - } - } + if (window_remember) { + int flags = SDL_GetWindowFlags(window); + if (!(flags & SDL_WINDOW_FULLSCREEN) && !(flags & SDL_WINDOW_FULLSCREEN_DESKTOP)) { + if (event.window.event == SDL_WINDOWEVENT_MOVED) { + window_x = event.window.data1; + window_y = event.window.data2; + // pclog("render window_remember SDL_WINDOWEVENT_MOVED. setting window_x/y to + // %dx%d\n", window_x, window_y); + } else if (event.window.event == SDL_WINDOWEVENT_RESIZED) { + window_w = event.window.data1; + window_h = event.window.data2; + } + // save_window_pos = 1; + } + } - break; - } - } - if ((rawinputkey[sdl_scancode(SDL_SCANCODE_PAGEDOWN)] || rawinputkey[sdl_scancode(SDL_SCANCODE_KP_3)]) && - (rawinputkey[sdl_scancode(SDL_SCANCODE_LCTRL)] || rawinputkey[sdl_scancode(SDL_SCANCODE_RCTRL)]) && - (rawinputkey[sdl_scancode(SDL_SCANCODE_LALT)] || rawinputkey[sdl_scancode(SDL_SCANCODE_RALT)])) - trigger_fullscreen = 1; - else if (trigger_fullscreen) { - trigger_fullscreen = 0; - toggle_fullscreen(); - } else if ((rawinputkey[sdl_scancode(SDL_SCANCODE_PAGEUP)] || rawinputkey[sdl_scancode(SDL_SCANCODE_KP_9)]) && - (rawinputkey[sdl_scancode(SDL_SCANCODE_LCTRL)] || rawinputkey[sdl_scancode(SDL_SCANCODE_RCTRL)]) && - (rawinputkey[sdl_scancode(SDL_SCANCODE_LALT)] || rawinputkey[sdl_scancode(SDL_SCANCODE_RALT)])) - trigger_screenshot = 1; - else if (trigger_screenshot) { - trigger_screenshot = 0; - take_screenshot = 1; - } else if ((rawinputkey[sdl_scancode(SDL_SCANCODE_END)] || rawinputkey[sdl_scancode(SDL_SCANCODE_KP_1)]) && - (rawinputkey[sdl_scancode(SDL_SCANCODE_LCTRL)] || rawinputkey[sdl_scancode(SDL_SCANCODE_RCTRL)])) - trigger_inputrelease = 1; - else if (trigger_inputrelease) { - trigger_inputrelease = 0; - if (!is_fullscreen()) - window_doinputrelease = 1; - } - if (window_doremember) { - window_doremember = 0; - SDL_GetWindowPosition(window, &window_x, &window_y); - //pclog("render window_doremember. setting window_x/y to %dx%d\n", window_x, window_y); - SDL_GetWindowSize(window, &window_w, &window_h); - saveconfig(NULL); - } + break; + } + } + if ((rawinputkey[sdl_scancode(SDL_SCANCODE_PAGEDOWN)] || rawinputkey[sdl_scancode(SDL_SCANCODE_KP_3)]) && + (rawinputkey[sdl_scancode(SDL_SCANCODE_LCTRL)] || rawinputkey[sdl_scancode(SDL_SCANCODE_RCTRL)]) && + (rawinputkey[sdl_scancode(SDL_SCANCODE_LALT)] || rawinputkey[sdl_scancode(SDL_SCANCODE_RALT)])) + trigger_fullscreen = 1; + else if (trigger_fullscreen) { + trigger_fullscreen = 0; + toggle_fullscreen(); + } else if ((rawinputkey[sdl_scancode(SDL_SCANCODE_PAGEUP)] || rawinputkey[sdl_scancode(SDL_SCANCODE_KP_9)]) && + (rawinputkey[sdl_scancode(SDL_SCANCODE_LCTRL)] || rawinputkey[sdl_scancode(SDL_SCANCODE_RCTRL)]) && + (rawinputkey[sdl_scancode(SDL_SCANCODE_LALT)] || rawinputkey[sdl_scancode(SDL_SCANCODE_RALT)])) + trigger_screenshot = 1; + else if (trigger_screenshot) { + trigger_screenshot = 0; + take_screenshot = 1; + } else if ((rawinputkey[sdl_scancode(SDL_SCANCODE_END)] || rawinputkey[sdl_scancode(SDL_SCANCODE_KP_1)]) && + (rawinputkey[sdl_scancode(SDL_SCANCODE_LCTRL)] || rawinputkey[sdl_scancode(SDL_SCANCODE_RCTRL)])) + trigger_inputrelease = 1; + else if (trigger_inputrelease) { + trigger_inputrelease = 0; + if (!is_fullscreen()) + window_doinputrelease = 1; + } + if (window_doremember) { + window_doremember = 0; + SDL_GetWindowPosition(window, &window_x, &window_y); + // pclog("render window_doremember. setting window_x/y to %dx%d\n", window_x, window_y); + SDL_GetWindowSize(window, &window_w, &window_h); + saveconfig(NULL); + } - if (window_dotogglefullscreen) { - window_dotogglefullscreen = 0; - if (SDL_GetWindowGrab(window) || is_fullscreen()) { - window_doinputrelease = 1; - if (is_fullscreen()) - window_dowindowed = 1; - } else { - window_doinputgrab = 1; - window_dofullscreen = 1; - } - } + if (window_dotogglefullscreen) { + window_dotogglefullscreen = 0; + if (SDL_GetWindowGrab(window) || is_fullscreen()) { + window_doinputrelease = 1; + if (is_fullscreen()) + window_dowindowed = 1; + } else { + window_doinputgrab = 1; + window_dofullscreen = 1; + } + } - if (window_dofullscreen) { - window_dofullscreen = 0; - // Get window position before hiding the menu or else the sizes will be incorrect. - SDL_GetWindowPosition(window, &remembered_rect.x, &remembered_rect.y); - //pclog("render window_dofullscreen. getting window position remembered_rect to %dx%d\n", remembered_rect.x, remembered_rect.y); - SDL_GetWindowSize(window, &remembered_rect.w, &remembered_rect.h); - SetMenu(hwnd, 0); - video_wait_for_blit(); - SDL_RaiseWindow(window); - SDL_GetGlobalMouseState(&remembered_mouse_x, &remembered_mouse_y); - SDL_SetWindowFullscreen(window, video_fullscreen_mode == 0 ? SDL_WINDOW_FULLSCREEN_DESKTOP : SDL_WINDOW_FULLSCREEN); - device_force_redraw(); - } - if (window_doinputgrab) { - window_doinputgrab = 0; - mousecapture = 1; - SDL_Rect rect; - SDL_GetWindowSize(window, &rect.w, &rect.h); - SDL_WarpMouseInWindow(window, rect.w / 2, rect.h / 2); - SDL_SetWindowGrab(window, SDL_TRUE); - SDL_SetRelativeMouseMode(SDL_TRUE); - SDL_GetRelativeMouseState(0, 0); - } + if (window_dofullscreen) { + window_dofullscreen = 0; + // Get window position before hiding the menu or else the sizes will be incorrect. + SDL_GetWindowPosition(window, &remembered_rect.x, &remembered_rect.y); + // pclog("render window_dofullscreen. getting window position remembered_rect to %dx%d\n", remembered_rect.x, + // remembered_rect.y); + SDL_GetWindowSize(window, &remembered_rect.w, &remembered_rect.h); + SetMenu(hwnd, 0); + video_wait_for_blit(); + SDL_RaiseWindow(window); + SDL_GetGlobalMouseState(&remembered_mouse_x, &remembered_mouse_y); + SDL_SetWindowFullscreen(window, + video_fullscreen_mode == 0 ? SDL_WINDOW_FULLSCREEN_DESKTOP : SDL_WINDOW_FULLSCREEN); + device_force_redraw(); + } + if (window_doinputgrab) { + window_doinputgrab = 0; + mousecapture = 1; + SDL_Rect rect; + SDL_GetWindowSize(window, &rect.w, &rect.h); + SDL_WarpMouseInWindow(window, rect.w / 2, rect.h / 2); + SDL_SetWindowGrab(window, SDL_TRUE); + SDL_SetRelativeMouseMode(SDL_TRUE); + SDL_GetRelativeMouseState(0, 0); + } - if (window_doinputrelease) { - window_doinputrelease = 0; - releasemouse(); - } - if (window_dowindowed) { - window_dowindowed = 0; - SetMenu(hwnd, menu); - SDL_SetWindowFullscreen(window, 0); - //pclog("render window_dowindowed. setting window position remembered_rect to %dx%d\n", remembered_rect.x, remembered_rect.y); - SDL_SetWindowSize(window, remembered_rect.w, remembered_rect.h); - SDL_SetWindowPosition(window, remembered_rect.x, remembered_rect.y); - SDL_WarpMouseGlobal(remembered_mouse_x, remembered_mouse_y); - device_force_redraw(); - } + if (window_doinputrelease) { + window_doinputrelease = 0; + releasemouse(); + } + if (window_dowindowed) { + window_dowindowed = 0; + SetMenu(hwnd, menu); + SDL_SetWindowFullscreen(window, 0); + // pclog("render window_dowindowed. setting window position remembered_rect to %dx%d\n", remembered_rect.x, + // remembered_rect.y); + SDL_SetWindowSize(window, remembered_rect.w, remembered_rect.h); + SDL_SetWindowPosition(window, remembered_rect.x, remembered_rect.y); + SDL_WarpMouseGlobal(remembered_mouse_x, remembered_mouse_y); + device_force_redraw(); + } - if (win_doresize) { - int flags = SDL_GetWindowFlags(window); - win_doresize = 0; - if (!vid_resize || (flags & SDL_WINDOW_FULLSCREEN)) { - SDL_GetWindowSize(window, &rect.w, &rect.h); - if (rect.w != winsizex || rect.h != winsizey) { - SDL_GetWindowPosition(window, &rect.x, &rect.y); - SDL_SetWindowSize(window, winsizex, winsizey); - SDL_SetWindowPosition(window, rect.x, rect.y); - //pclog("render win_doresize. get/set window position rect to %dx%d\n", rect.x, rect.y); - device_force_redraw(); - } - } - } + if (win_doresize) { + int flags = SDL_GetWindowFlags(window); + win_doresize = 0; + if (!vid_resize || (flags & SDL_WINDOW_FULLSCREEN)) { + SDL_GetWindowSize(window, &rect.w, &rect.h); + if (rect.w != winsizex || rect.h != winsizey) { + SDL_GetWindowPosition(window, &rect.x, &rect.y); + SDL_SetWindowSize(window, winsizex, winsizey); + SDL_SetWindowPosition(window, rect.x, rect.y); + // pclog("render win_doresize. get/set window position rect to %dx%d\n", rect.x, rect.y); + device_force_redraw(); + } + } + } - if (sdl_renderer_update(window)) - sdl_renderer_present(window); + if (sdl_renderer_update(window)) + sdl_renderer_present(window); - end_time = timer_read(); - render_time += end_time - start_time; + end_time = timer_read(); + render_time += end_time - start_time; - ++render_frames; - uint32_t ticks = SDL_GetTicks(); - if (ticks - render_frame_time >= 1000) { - render_fps = render_frames / ((ticks - render_frame_time) / 1000.0); - render_frames = 0; - render_frame_time = ticks; - } + ++render_frames; + uint32_t ticks = SDL_GetTicks(); + if (ticks - render_frame_time >= 1000) { + render_fps = render_frames / ((ticks - render_frame_time) / 1000.0); + render_frames = 0; + render_frame_time = ticks; + } - return 1; + return 1; } int renderer_thread(void *params) { - int internal_rendering; + int internal_rendering; - SDL_LockMutex(rendererMutex); - SDL_CondSignal(rendererCond); - SDL_UnlockMutex(rendererMutex); + SDL_LockMutex(rendererMutex); + SDL_CondSignal(rendererCond); + SDL_UnlockMutex(rendererMutex); - window_setup(); + window_setup(); - rendering = 1; - while (rendering) { + rendering = 1; + while (rendering) { - if (!window_create()) - rendering = 0; + if (!window_create()) + rendering = 0; - renderer_doreset = 1; - internal_rendering = 1; - while (rendering && internal_rendering) { - if (!render()) - internal_rendering = 0; + renderer_doreset = 1; + internal_rendering = 1; + while (rendering && internal_rendering) { + if (!render()) + internal_rendering = 0; - SDL_Delay(1); - } - window_close(); - } + SDL_Delay(1); + } + window_close(); + } - SDL_LockMutex(rendererMutex); - SDL_CondSignal(rendererCond); - SDL_UnlockMutex(rendererMutex); + SDL_LockMutex(rendererMutex); + SDL_CondSignal(rendererCond); + SDL_UnlockMutex(rendererMutex); - return SDL_TRUE; + return SDL_TRUE; } void *timer = 0; void render_timer() { #ifdef PCEM_RENDER_TIMER_LOOP - /* For some reason this while-loop works on OSX, which also fixes missing events. No idea why though. */ - renderer_thread(0); + /* For some reason this while-loop works on OSX, which also fixes missing events. No idea why though. */ + renderer_thread(0); #else - if (rendering && !render()) { - window_close(); - window_create(); - renderer_doreset = 1; - } + if (rendering && !render()) { + window_close(); + window_create(); + renderer_doreset = 1; + } #endif } void render_start_timer() { #ifdef PCEM_RENDER_TIMER_LOOP - timer = wx_createtimer(render_timer); - wx_starttimer(timer, 500, 1); + timer = wx_createtimer(render_timer); + wx_starttimer(timer, 500, 1); #else - window_setup(); - if (window_create()) { - rendering = 1; - renderer_doreset = 1; - wx_starttimer(timer, 1, 0); - } + window_setup(); + if (window_create()) { + rendering = 1; + renderer_doreset = 1; + wx_starttimer(timer, 1, 0); + } #endif } void renderer_start() { - if (!rendering) { + if (!rendering) { #ifdef PCEM_RENDER_WITH_TIMER - render_start_timer(); + render_start_timer(); #else - SDL_LockMutex(rendererMutex); - renderthread = SDL_CreateThread(renderer_thread, "SDL2 Thread", NULL); - SDL_CondWait(rendererCond, rendererMutex); - SDL_UnlockMutex(rendererMutex); + SDL_LockMutex(rendererMutex); + renderthread = SDL_CreateThread(renderer_thread, "SDL2 Thread", NULL); + SDL_CondWait(rendererCond, rendererMutex); + SDL_UnlockMutex(rendererMutex); #endif - } + } } void renderer_stop(int timeout) { #if defined(PCEM_RENDER_WITH_TIMER) && !defined(PCEM_RENDER_TIMER_LOOP) - rendering = 0; - window_close(); - wx_destroytimer(timer); + rendering = 0; + window_close(); + wx_destroytimer(timer); #else - if (rendering) { - SDL_LockMutex(rendererMutex); - rendering = 0; - if (timeout) - SDL_CondWaitTimeout(rendererCond, rendererMutex, timeout); - else - SDL_CondWait(rendererCond, rendererMutex); - SDL_UnlockMutex(rendererMutex); - renderthread = NULL; - } - if (timer) - wx_destroytimer(timer); + if (rendering) { + SDL_LockMutex(rendererMutex); + rendering = 0; + if (timeout) + SDL_CondWaitTimeout(rendererCond, rendererMutex, timeout); + else + SDL_CondWait(rendererCond, rendererMutex); + SDL_UnlockMutex(rendererMutex); + renderthread = NULL; + } + if (timer) + wx_destroytimer(timer); #endif } diff --git a/src/wx-ui/wx-sdl2-display.c b/src/wx-ui/wx-sdl2-display.c index f8e83eb5..e550946e 100644 --- a/src/wx-ui/wx-sdl2-display.c +++ b/src/wx-ui/wx-sdl2-display.c @@ -58,205 +58,205 @@ extern void mouse_wheel_update(int); extern void toggle_fullscreen(); void display_resize(int width, int height) { - winsizex = width * (video_scale + 1) >> 1; - winsizey = height * (video_scale + 1) >> 1; + winsizex = width * (video_scale + 1) >> 1; + winsizey = height * (video_scale + 1) >> 1; - SDL_Rect rect; - rect.x = rect.y = 0; - rect.w = winsizex; - rect.h = winsizey; - sdl_scale(video_fullscreen_scale, rect, &rect, winsizex, winsizey); - winsizex = rect.w; - winsizey = rect.h; + SDL_Rect rect; + rect.x = rect.y = 0; + rect.w = winsizex; + rect.h = winsizey; + sdl_scale(video_fullscreen_scale, rect, &rect, winsizex, winsizey); + winsizex = rect.w; + winsizey = rect.h; - win_doresize = 1; + win_doresize = 1; } void releasemouse() { - if (mousecapture) { - SDL_SetWindowGrab(window, SDL_FALSE); - SDL_SetRelativeMouseMode(SDL_FALSE); - mousecapture = 0; - } + if (mousecapture) { + SDL_SetWindowGrab(window, SDL_FALSE); + SDL_SetRelativeMouseMode(SDL_FALSE); + mousecapture = 0; + } } int display_init() { - if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0) { - printf("SDL could not initialize! Error: %s\n", SDL_GetError()); - return 0; - } + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0) { + printf("SDL could not initialize! Error: %s\n", SDL_GetError()); + return 0; + } - SDL_version ver; - SDL_GetVersion(&ver); - printf("SDL %i.%i.%i initialized.\n", ver.major, ver.minor, ver.patch); - return 1; + SDL_version ver; + SDL_GetVersion(&ver); + printf("SDL %i.%i.%i initialized.\n", ver.major, ver.minor, ver.patch); + return 1; } -void display_close() { - SDL_Quit(); -} +void display_close() { SDL_Quit(); } void display_start(void *hwnd) { - ghwnd = hwnd; - menu = wx_getmenu(hwnd); - atexit(releasemouse); - rendererMutex = SDL_CreateMutex(); - rendererCond = SDL_CreateCond(); - renderer_start(); + ghwnd = hwnd; + menu = wx_getmenu(hwnd); + atexit(releasemouse); + rendererMutex = SDL_CreateMutex(); + rendererCond = SDL_CreateCond(); + renderer_start(); } void display_stop() { - renderer_stop(10 * 1000); + renderer_stop(10 * 1000); - SDL_DestroyMutex(rendererMutex); - SDL_DestroyCond(rendererCond); + SDL_DestroyMutex(rendererMutex); + SDL_DestroyCond(rendererCond); #if SDL_VERSION_ATLEAST(2, 0, 2) - SDL_DetachThread(renderthread); + SDL_DetachThread(renderthread); #endif - releasemouse(); + releasemouse(); } int is_fullscreen() { - int flags = SDL_GetWindowFlags(window); - return (flags & SDL_WINDOW_FULLSCREEN) || (flags & SDL_WINDOW_FULLSCREEN_DESKTOP); + int flags = SDL_GetWindowFlags(window); + return (flags & SDL_WINDOW_FULLSCREEN) || (flags & SDL_WINDOW_FULLSCREEN_DESKTOP); } void sdl_set_window_title(const char *title) { - if (window && !is_fullscreen()) - SDL_SetWindowTitle(window, title); + if (window && !is_fullscreen()) + SDL_SetWindowTitle(window, title); } int get_border_size(int *top, int *left, int *bottom, int *right) { #if SDL_VERSION_ATLEAST(2, 0, 5) - return SDL_GetWindowBordersSize(window, top, left, bottom, right); + return SDL_GetWindowBordersSize(window, top, left, bottom, right); #else - if (top) *top = 0; - if (left) *left = 0; - if (bottom) *bottom = 0; - if (right) *right = 0; - return 0; + if (top) + *top = 0; + if (left) + *left = 0; + if (bottom) + *bottom = 0; + if (right) + *right = 0; + return 0; #endif } static const struct { - SDL_Scancode sdl; - int system; -} SDLScancodeToSystemScancode[] = { - {SDL_SCANCODE_A, 0x1e}, - {SDL_SCANCODE_B, 0x30}, - {SDL_SCANCODE_C, 0x2e}, - {SDL_SCANCODE_D, 0x20}, - {SDL_SCANCODE_E, 0x12}, - {SDL_SCANCODE_F, 0x21}, - {SDL_SCANCODE_G, 0x22}, - {SDL_SCANCODE_H, 0x23}, - {SDL_SCANCODE_I, 0x17}, - {SDL_SCANCODE_J, 0x24}, - {SDL_SCANCODE_K, 0x25}, - {SDL_SCANCODE_L, 0x26}, - {SDL_SCANCODE_M, 0x32}, - {SDL_SCANCODE_N, 0x31}, - {SDL_SCANCODE_O, 0x18}, - {SDL_SCANCODE_P, 0x19}, - {SDL_SCANCODE_Q, 0x10}, - {SDL_SCANCODE_R, 0x13}, - {SDL_SCANCODE_S, 0x1f}, - {SDL_SCANCODE_T, 0x14}, - {SDL_SCANCODE_U, 0x16}, - {SDL_SCANCODE_V, 0x2f}, - {SDL_SCANCODE_W, 0x11}, - {SDL_SCANCODE_X, 0x2d}, - {SDL_SCANCODE_Y, 0x15}, - {SDL_SCANCODE_Z, 0x2c}, - {SDL_SCANCODE_0, 0x0B}, - {SDL_SCANCODE_1, 0x02}, - {SDL_SCANCODE_2, 0x03}, - {SDL_SCANCODE_3, 0x04}, - {SDL_SCANCODE_4, 0x05}, - {SDL_SCANCODE_5, 0x06}, - {SDL_SCANCODE_6, 0x07}, - {SDL_SCANCODE_7, 0x08}, - {SDL_SCANCODE_8, 0x09}, - {SDL_SCANCODE_9, 0x0A}, - {SDL_SCANCODE_GRAVE, 0x29}, - {SDL_SCANCODE_MINUS, 0x0c}, - {SDL_SCANCODE_EQUALS, 0x0d}, - {SDL_SCANCODE_NONUSBACKSLASH, 0x56}, - {SDL_SCANCODE_BACKSLASH, 0x2b}, - {SDL_SCANCODE_BACKSPACE, 0x0e}, - {SDL_SCANCODE_SPACE, 0x39}, - {SDL_SCANCODE_TAB, 0x0f}, - {SDL_SCANCODE_CAPSLOCK, 0x3a}, - {SDL_SCANCODE_LSHIFT, 0x2a}, - {SDL_SCANCODE_LCTRL, 0x1d}, - {SDL_SCANCODE_LGUI, 0xdb}, - {SDL_SCANCODE_LALT, 0x38}, - {SDL_SCANCODE_RSHIFT, 0x36}, - {SDL_SCANCODE_RCTRL, 0x9d}, - {SDL_SCANCODE_RGUI, 0xdc}, - {SDL_SCANCODE_RALT, 0xb8}, - {SDL_SCANCODE_SYSREQ, 0x54}, - {SDL_SCANCODE_APPLICATION, 0xdd}, - {SDL_SCANCODE_RETURN, 0x1c}, - {SDL_SCANCODE_ESCAPE, 0x01}, - {SDL_SCANCODE_F1, 0x3B}, - {SDL_SCANCODE_F2, 0x3C}, - {SDL_SCANCODE_F3, 0x3D}, - {SDL_SCANCODE_F4, 0x3e}, - {SDL_SCANCODE_F5, 0x3f}, - {SDL_SCANCODE_F6, 0x40}, - {SDL_SCANCODE_F7, 0x41}, - {SDL_SCANCODE_F8, 0x42}, - {SDL_SCANCODE_F9, 0x43}, - {SDL_SCANCODE_F10, 0x44}, - {SDL_SCANCODE_F11, 0x57}, - {SDL_SCANCODE_F12, 0x58}, - {SDL_SCANCODE_SCROLLLOCK, 0x46}, - {SDL_SCANCODE_LEFTBRACKET, 0x1a}, - {SDL_SCANCODE_RIGHTBRACKET, 0x1b}, - {SDL_SCANCODE_INSERT, 0xd2}, - {SDL_SCANCODE_HOME, 0xc7}, - {SDL_SCANCODE_PAGEUP, 0xc9}, - {SDL_SCANCODE_DELETE, 0xd3}, - {SDL_SCANCODE_END, 0xcf}, - {SDL_SCANCODE_PAGEDOWN, 0xd1}, - {SDL_SCANCODE_UP, 0xc8}, - {SDL_SCANCODE_LEFT, 0xcb}, - {SDL_SCANCODE_DOWN, 0xd0}, - {SDL_SCANCODE_RIGHT, 0xcd}, - {SDL_SCANCODE_NUMLOCKCLEAR, 0x45}, - {SDL_SCANCODE_KP_DIVIDE, 0xb5}, - {SDL_SCANCODE_KP_MULTIPLY, 0x37}, - {SDL_SCANCODE_KP_MINUS, 0x4a}, - {SDL_SCANCODE_KP_PLUS, 0x4e}, - {SDL_SCANCODE_KP_ENTER, 0x9c}, - {SDL_SCANCODE_KP_PERIOD, 0x53}, - {SDL_SCANCODE_KP_0, 0x52}, - {SDL_SCANCODE_KP_1, 0x4f}, - {SDL_SCANCODE_KP_2, 0x50}, - {SDL_SCANCODE_KP_3, 0x51}, - {SDL_SCANCODE_KP_4, 0x4b}, - {SDL_SCANCODE_KP_5, 0x4c}, - {SDL_SCANCODE_KP_6, 0x4d}, - {SDL_SCANCODE_KP_7, 0x47}, - {SDL_SCANCODE_KP_8, 0x48}, - {SDL_SCANCODE_KP_9, 0x49}, - {SDL_SCANCODE_SEMICOLON, 0x27}, - {SDL_SCANCODE_APOSTROPHE, 0x28}, - {SDL_SCANCODE_COMMA, 0x33}, - {SDL_SCANCODE_PERIOD, 0x34}, - {SDL_SCANCODE_SLASH, 0x35}, - {SDL_SCANCODE_PRINTSCREEN, 0xb7} -}; + SDL_Scancode sdl; + int system; +} SDLScancodeToSystemScancode[] = {{SDL_SCANCODE_A, 0x1e}, + {SDL_SCANCODE_B, 0x30}, + {SDL_SCANCODE_C, 0x2e}, + {SDL_SCANCODE_D, 0x20}, + {SDL_SCANCODE_E, 0x12}, + {SDL_SCANCODE_F, 0x21}, + {SDL_SCANCODE_G, 0x22}, + {SDL_SCANCODE_H, 0x23}, + {SDL_SCANCODE_I, 0x17}, + {SDL_SCANCODE_J, 0x24}, + {SDL_SCANCODE_K, 0x25}, + {SDL_SCANCODE_L, 0x26}, + {SDL_SCANCODE_M, 0x32}, + {SDL_SCANCODE_N, 0x31}, + {SDL_SCANCODE_O, 0x18}, + {SDL_SCANCODE_P, 0x19}, + {SDL_SCANCODE_Q, 0x10}, + {SDL_SCANCODE_R, 0x13}, + {SDL_SCANCODE_S, 0x1f}, + {SDL_SCANCODE_T, 0x14}, + {SDL_SCANCODE_U, 0x16}, + {SDL_SCANCODE_V, 0x2f}, + {SDL_SCANCODE_W, 0x11}, + {SDL_SCANCODE_X, 0x2d}, + {SDL_SCANCODE_Y, 0x15}, + {SDL_SCANCODE_Z, 0x2c}, + {SDL_SCANCODE_0, 0x0B}, + {SDL_SCANCODE_1, 0x02}, + {SDL_SCANCODE_2, 0x03}, + {SDL_SCANCODE_3, 0x04}, + {SDL_SCANCODE_4, 0x05}, + {SDL_SCANCODE_5, 0x06}, + {SDL_SCANCODE_6, 0x07}, + {SDL_SCANCODE_7, 0x08}, + {SDL_SCANCODE_8, 0x09}, + {SDL_SCANCODE_9, 0x0A}, + {SDL_SCANCODE_GRAVE, 0x29}, + {SDL_SCANCODE_MINUS, 0x0c}, + {SDL_SCANCODE_EQUALS, 0x0d}, + {SDL_SCANCODE_NONUSBACKSLASH, 0x56}, + {SDL_SCANCODE_BACKSLASH, 0x2b}, + {SDL_SCANCODE_BACKSPACE, 0x0e}, + {SDL_SCANCODE_SPACE, 0x39}, + {SDL_SCANCODE_TAB, 0x0f}, + {SDL_SCANCODE_CAPSLOCK, 0x3a}, + {SDL_SCANCODE_LSHIFT, 0x2a}, + {SDL_SCANCODE_LCTRL, 0x1d}, + {SDL_SCANCODE_LGUI, 0xdb}, + {SDL_SCANCODE_LALT, 0x38}, + {SDL_SCANCODE_RSHIFT, 0x36}, + {SDL_SCANCODE_RCTRL, 0x9d}, + {SDL_SCANCODE_RGUI, 0xdc}, + {SDL_SCANCODE_RALT, 0xb8}, + {SDL_SCANCODE_SYSREQ, 0x54}, + {SDL_SCANCODE_APPLICATION, 0xdd}, + {SDL_SCANCODE_RETURN, 0x1c}, + {SDL_SCANCODE_ESCAPE, 0x01}, + {SDL_SCANCODE_F1, 0x3B}, + {SDL_SCANCODE_F2, 0x3C}, + {SDL_SCANCODE_F3, 0x3D}, + {SDL_SCANCODE_F4, 0x3e}, + {SDL_SCANCODE_F5, 0x3f}, + {SDL_SCANCODE_F6, 0x40}, + {SDL_SCANCODE_F7, 0x41}, + {SDL_SCANCODE_F8, 0x42}, + {SDL_SCANCODE_F9, 0x43}, + {SDL_SCANCODE_F10, 0x44}, + {SDL_SCANCODE_F11, 0x57}, + {SDL_SCANCODE_F12, 0x58}, + {SDL_SCANCODE_SCROLLLOCK, 0x46}, + {SDL_SCANCODE_LEFTBRACKET, 0x1a}, + {SDL_SCANCODE_RIGHTBRACKET, 0x1b}, + {SDL_SCANCODE_INSERT, 0xd2}, + {SDL_SCANCODE_HOME, 0xc7}, + {SDL_SCANCODE_PAGEUP, 0xc9}, + {SDL_SCANCODE_DELETE, 0xd3}, + {SDL_SCANCODE_END, 0xcf}, + {SDL_SCANCODE_PAGEDOWN, 0xd1}, + {SDL_SCANCODE_UP, 0xc8}, + {SDL_SCANCODE_LEFT, 0xcb}, + {SDL_SCANCODE_DOWN, 0xd0}, + {SDL_SCANCODE_RIGHT, 0xcd}, + {SDL_SCANCODE_NUMLOCKCLEAR, 0x45}, + {SDL_SCANCODE_KP_DIVIDE, 0xb5}, + {SDL_SCANCODE_KP_MULTIPLY, 0x37}, + {SDL_SCANCODE_KP_MINUS, 0x4a}, + {SDL_SCANCODE_KP_PLUS, 0x4e}, + {SDL_SCANCODE_KP_ENTER, 0x9c}, + {SDL_SCANCODE_KP_PERIOD, 0x53}, + {SDL_SCANCODE_KP_0, 0x52}, + {SDL_SCANCODE_KP_1, 0x4f}, + {SDL_SCANCODE_KP_2, 0x50}, + {SDL_SCANCODE_KP_3, 0x51}, + {SDL_SCANCODE_KP_4, 0x4b}, + {SDL_SCANCODE_KP_5, 0x4c}, + {SDL_SCANCODE_KP_6, 0x4d}, + {SDL_SCANCODE_KP_7, 0x47}, + {SDL_SCANCODE_KP_8, 0x48}, + {SDL_SCANCODE_KP_9, 0x49}, + {SDL_SCANCODE_SEMICOLON, 0x27}, + {SDL_SCANCODE_APOSTROPHE, 0x28}, + {SDL_SCANCODE_COMMA, 0x33}, + {SDL_SCANCODE_PERIOD, 0x34}, + {SDL_SCANCODE_SLASH, 0x35}, + {SDL_SCANCODE_PRINTSCREEN, 0xb7}}; int sdl_scancode(SDL_Scancode scancode) { - int i; - for (i = 0; i < SDL_arraysize(SDLScancodeToSystemScancode); ++i) { - if (SDLScancodeToSystemScancode[i].sdl == scancode) { - return SDLScancodeToSystemScancode[i].system; - } - } - return -1; + int i; + for (i = 0; i < SDL_arraysize(SDLScancodeToSystemScancode); ++i) { + if (SDLScancodeToSystemScancode[i].sdl == scancode) { + return SDLScancodeToSystemScancode[i].system; + } + } + return -1; } SDL_Event event; @@ -269,436 +269,441 @@ uint32_t render_frame_time = 0; uint32_t render_frames = 0; void window_setup() { - SDL_SetHint(SDL_HINT_GRAB_KEYBOARD, "1"); + SDL_SetHint(SDL_HINT_GRAB_KEYBOARD, "1"); #if SDL_VERSION_ATLEAST(2, 0, 5) - SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1"); + SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1"); #endif - if (start_in_fullscreen) { - start_in_fullscreen = 0; - window_dofullscreen = 1; - window_doinputgrab = 1; - } + if (start_in_fullscreen) { + start_in_fullscreen = 0; + window_dofullscreen = 1; + window_doinputgrab = 1; + } - if (window_remember) { - rect.x = window_x; - rect.y = window_y; - rect.w = window_w; - rect.h = window_h; - } else { - rect.x = SDL_WINDOWPOS_CENTERED; - rect.y = SDL_WINDOWPOS_CENTERED; - rect.w = 640; - rect.h = 480; - } + if (window_remember) { + rect.x = window_x; + rect.y = window_y; + rect.w = window_w; + rect.h = window_h; + } else { + rect.x = SDL_WINDOWPOS_CENTERED; + rect.y = SDL_WINDOWPOS_CENTERED; + rect.w = 640; + rect.h = 480; + } - if (vid_resize == 2) { - rect.w = custom_resolution_width; - rect.h = custom_resolution_height; - } + if (vid_resize == 2) { + rect.w = custom_resolution_width; + rect.h = custom_resolution_height; + } } #ifdef __WINDOWS__ int sdl_winhook(int code) { - switch (code) { - case VK_LMENU:return SDL_SCANCODE_LALT; - case VK_LCONTROL:return SDL_SCANCODE_LCTRL; - case VK_LWIN:return SDL_SCANCODE_LGUI; - case VK_LSHIFT:return SDL_SCANCODE_LSHIFT; - case VK_RMENU:return SDL_SCANCODE_RALT; - case VK_RCONTROL:return SDL_SCANCODE_RCTRL; - case VK_RWIN:return SDL_SCANCODE_RGUI; - case VK_RSHIFT:return SDL_SCANCODE_RSHIFT; - } + switch (code) { + case VK_LMENU: + return SDL_SCANCODE_LALT; + case VK_LCONTROL: + return SDL_SCANCODE_LCTRL; + case VK_LWIN: + return SDL_SCANCODE_LGUI; + case VK_LSHIFT: + return SDL_SCANCODE_LSHIFT; + case VK_RMENU: + return SDL_SCANCODE_RALT; + case VK_RCONTROL: + return SDL_SCANCODE_RCTRL; + case VK_RWIN: + return SDL_SCANCODE_RGUI; + case VK_RSHIFT: + return SDL_SCANCODE_RSHIFT; + } - return -1; + return -1; } LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) { - KBDLLHOOKSTRUCT *p = (KBDLLHOOKSTRUCT *)lParam; + KBDLLHOOKSTRUCT *p = (KBDLLHOOKSTRUCT *)lParam; - int c = p->vkCode; + int c = p->vkCode; - int steal = 0; - int s = sdl_winhook(c); - if (s != -1) { - int key_state = !(p->flags & LLKHF_UP); - if (abs(modkeystate[c]) != key_state) { - /* if mousecapture is 0, key_state should be negative */ - if (!mousecapture) - key_state = -key_state; - /* if key_state is 0 and modkeystate[c] is negative, - an sdl_event should not be generated */ - if (key_state > 0 || modkeystate[c] > 0) { - steal = key_state != 0; - SDL_Event event; - event.key.keysym.scancode = s; - event.key.timestamp = p->time; + int steal = 0; + int s = sdl_winhook(c); + if (s != -1) { + int key_state = !(p->flags & LLKHF_UP); + if (abs(modkeystate[c]) != key_state) { + /* if mousecapture is 0, key_state should be negative */ + if (!mousecapture) + key_state = -key_state; + /* if key_state is 0 and modkeystate[c] is negative, + an sdl_event should not be generated */ + if (key_state > 0 || modkeystate[c] > 0) { + steal = key_state != 0; + SDL_Event event; + event.key.keysym.scancode = s; + event.key.timestamp = p->time; - event.type = key_state ? SDL_KEYDOWN : SDL_KEYUP; - SDL_PushEvent(&event); - } - modkeystate[c] = key_state; - } - if (steal) - return 1; - } + event.type = key_state ? SDL_KEYDOWN : SDL_KEYUP; + SDL_PushEvent(&event); + } + modkeystate[c] = key_state; + } + if (steal) + return 1; + } - return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam); + return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam); } #endif int window_create() { - window = SDL_CreateWindow("PCem Display", - rect.x, rect.y, rect.w, rect.h, - requested_render_driver.sdl_window_params | (vid_resize == 1 ? SDL_WINDOW_RESIZABLE : 0)); - if (!window) { - char message[200]; - sprintf(message, - "SDL window could not be created! Error: %s\n", - SDL_GetError()); - wx_messagebox(ghwnd, message, "SDL Error", WX_MB_OK); - return 0; - } + window = SDL_CreateWindow("PCem Display", rect.x, rect.y, rect.w, rect.h, + requested_render_driver.sdl_window_params | (vid_resize == 1 ? SDL_WINDOW_RESIZABLE : 0)); + if (!window) { + char message[200]; + sprintf(message, "SDL window could not be created! Error: %s\n", SDL_GetError()); + wx_messagebox(ghwnd, message, "SDL Error", WX_MB_OK); + return 0; + } #ifdef __WINDOWS__ - memset(modkeystate, 0, sizeof(modkeystate)); - hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandle(NULL), 0); + memset(modkeystate, 0, sizeof(modkeystate)); + hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandle(NULL), 0); #endif - render_time = 0; - render_fps = 0; - render_frame_time = SDL_GetTicks(); - render_frames = 0; - return 1; + render_time = 0; + render_fps = 0; + render_frame_time = SDL_GetTicks(); + render_frames = 0; + return 1; } void window_close() { #ifdef __WINDOWS__ - UnhookWindowsHookEx(hKeyboardHook); + UnhookWindowsHookEx(hKeyboardHook); #endif - sdl_renderer_close(); + sdl_renderer_close(); - if (window) { - SDL_GetWindowPosition(window, &rect.x, &rect.y); - SDL_GetWindowSize(window, &rect.w, &rect.h); - get_border_size(&border_y, &border_x, 0, 0); - rect.x -= border_x; - rect.y -= border_y; + if (window) { + SDL_GetWindowPosition(window, &rect.x, &rect.y); + SDL_GetWindowSize(window, &rect.w, &rect.h); + get_border_size(&border_y, &border_x, 0, 0); + rect.x -= border_x; + rect.y -= border_y; - SDL_DestroyWindow(window); - } - window = NULL; + SDL_DestroyWindow(window); + } + window = NULL; } int render() { - uint64_t start_time = timer_read(); - uint64_t end_time; + uint64_t start_time = timer_read(); + uint64_t end_time; - if (window_dosetresize) { - window_dosetresize = 0; + if (window_dosetresize) { + window_dosetresize = 0; #if SDL_VERSION_ATLEAST(2, 0, 5) - SDL_GetWindowSize(window, &rect.w, &rect.h); - SDL_SetWindowResizable(window, vid_resize == 1); - SDL_SetWindowSize(window, rect.w, rect.h); + SDL_GetWindowSize(window, &rect.w, &rect.h); + SDL_SetWindowResizable(window, vid_resize == 1); + SDL_SetWindowSize(window, rect.w, rect.h); #else - window_doreset = 1; + window_doreset = 1; #endif - if (vid_resize == 2) - SDL_SetWindowSize(window, custom_resolution_width, custom_resolution_height); + if (vid_resize == 2) + SDL_SetWindowSize(window, custom_resolution_width, custom_resolution_height); - device_force_redraw(); - } - if (window_doreset) { - pclog("window_doreset\n"); - window_doreset = 0; - renderer_doreset = 0; - return 0; - } - if (renderer_doreset) { - pclog("renderer_doreset\n"); - renderer_doreset = 0; - sdl_renderer_close(); - sdl_renderer_init(window); + device_force_redraw(); + } + if (window_doreset) { + pclog("window_doreset\n"); + window_doreset = 0; + renderer_doreset = 0; + return 0; + } + if (renderer_doreset) { + pclog("renderer_doreset\n"); + renderer_doreset = 0; + sdl_renderer_close(); + sdl_renderer_init(window); - device_force_redraw(); - video_wait_for_blit(); - } - while (SDL_PollEvent(&event)) { - switch (event.type) { - case SDL_MOUSEBUTTONUP: - if (!mousecapture) { - if (event.button.button == SDL_BUTTON_LEFT && !pause) { - window_doinputgrab = 1; - if (video_fullscreen) - window_dofullscreen = 1; - } else if (event.button.button == SDL_BUTTON_RIGHT) - wx_popupmenu(ghwnd, menu, 0, 0); + device_force_redraw(); + video_wait_for_blit(); + } + while (SDL_PollEvent(&event)) { + switch (event.type) { + case SDL_MOUSEBUTTONUP: + if (!mousecapture) { + if (event.button.button == SDL_BUTTON_LEFT && !pause) { + window_doinputgrab = 1; + if (video_fullscreen) + window_dofullscreen = 1; + } else if (event.button.button == SDL_BUTTON_RIGHT) + wx_popupmenu(ghwnd, menu, 0, 0); - } else if (event.button.button == SDL_BUTTON_MIDDLE && !is_fullscreen()) - window_doinputrelease = 1; - break; - case SDL_MOUSEWHEEL: - if (mousecapture) - mouse_wheel_update(event.wheel.y); - break; - case SDL_WINDOWEVENT: - if (event.window.event == SDL_WINDOWEVENT_CLOSE) - wx_stop_emulation(ghwnd); - if (event.window.event == SDL_WINDOWEVENT_RESIZED) - device_force_redraw(); - if (event.window.event == SDL_WINDOWEVENT_FOCUS_LOST) { - if (is_fullscreen()) - window_dowindowed = 1; - window_doinputrelease = 1; - } + } else if (event.button.button == SDL_BUTTON_MIDDLE && !is_fullscreen()) + window_doinputrelease = 1; + break; + case SDL_MOUSEWHEEL: + if (mousecapture) + mouse_wheel_update(event.wheel.y); + break; + case SDL_WINDOWEVENT: + if (event.window.event == SDL_WINDOWEVENT_CLOSE) + wx_stop_emulation(ghwnd); + if (event.window.event == SDL_WINDOWEVENT_RESIZED) + device_force_redraw(); + if (event.window.event == SDL_WINDOWEVENT_FOCUS_LOST) { + if (is_fullscreen()) + window_dowindowed = 1; + window_doinputrelease = 1; + } - if (window_remember) { - int flags = SDL_GetWindowFlags(window); - if (!(flags & SDL_WINDOW_FULLSCREEN) && !(flags & SDL_WINDOW_FULLSCREEN_DESKTOP)) { - if (event.window.event == SDL_WINDOWEVENT_MOVED) { - get_border_size(&border_y, &border_x, 0, 0); - window_x = event.window.data1 - border_x; - window_y = event.window.data2 - border_y; - } else if (event.window.event == SDL_WINDOWEVENT_RESIZED) { - window_w = event.window.data1; - window_h = event.window.data2; - } - //save_window_pos = 1; - } - } + if (window_remember) { + int flags = SDL_GetWindowFlags(window); + if (!(flags & SDL_WINDOW_FULLSCREEN) && !(flags & SDL_WINDOW_FULLSCREEN_DESKTOP)) { + if (event.window.event == SDL_WINDOWEVENT_MOVED) { + get_border_size(&border_y, &border_x, 0, 0); + window_x = event.window.data1 - border_x; + window_y = event.window.data2 - border_y; + } else if (event.window.event == SDL_WINDOWEVENT_RESIZED) { + window_w = event.window.data1; + window_h = event.window.data2; + } + // save_window_pos = 1; + } + } - break; - case SDL_KEYDOWN: { + break; + case SDL_KEYDOWN: { #ifdef __WINDOWS__ - /* international keyboard workaround */ - if (event.key.keysym.scancode == SDL_SCANCODE_RALT && - (event.key.keysym.mod & KMOD_LCTRL) && - event.key.timestamp == rawinputkey[sdl_scancode(SDL_SCANCODE_LCTRL)]) - rawinputkey[sdl_scancode(SDL_SCANCODE_LCTRL)] = 0; + /* international keyboard workaround */ + if (event.key.keysym.scancode == SDL_SCANCODE_RALT && (event.key.keysym.mod & KMOD_LCTRL) && + event.key.timestamp == rawinputkey[sdl_scancode(SDL_SCANCODE_LCTRL)]) + rawinputkey[sdl_scancode(SDL_SCANCODE_LCTRL)] = 0; #endif - int key_idx = sdl_scancode(event.key.keysym.scancode); - if (key_idx != -1) - rawinputkey[key_idx] = event.key.timestamp; - break; - } - case SDL_KEYUP: { - int key_idx = sdl_scancode(event.key.keysym.scancode); - if (key_idx != -1) - rawinputkey[key_idx] = 0; - break; - } - } - } - if ((rawinputkey[sdl_scancode(SDL_SCANCODE_PAGEDOWN)] || rawinputkey[sdl_scancode(SDL_SCANCODE_KP_3)]) && - (rawinputkey[sdl_scancode(SDL_SCANCODE_LCTRL)] || rawinputkey[sdl_scancode(SDL_SCANCODE_RCTRL)]) && - (rawinputkey[sdl_scancode(SDL_SCANCODE_LALT)] || rawinputkey[sdl_scancode(SDL_SCANCODE_RALT)])) - trigger_fullscreen = 1; - else if (trigger_fullscreen) { - trigger_fullscreen = 0; - toggle_fullscreen(); - } else if ((rawinputkey[sdl_scancode(SDL_SCANCODE_PAGEUP)] || rawinputkey[sdl_scancode(SDL_SCANCODE_KP_9)]) && - (rawinputkey[sdl_scancode(SDL_SCANCODE_LCTRL)] || rawinputkey[sdl_scancode(SDL_SCANCODE_RCTRL)]) && - (rawinputkey[sdl_scancode(SDL_SCANCODE_LALT)] || rawinputkey[sdl_scancode(SDL_SCANCODE_RALT)])) - trigger_screenshot = 1; - else if (trigger_screenshot) { - trigger_screenshot = 0; - take_screenshot = 1; - } else if ((rawinputkey[sdl_scancode(SDL_SCANCODE_END)] || rawinputkey[sdl_scancode(SDL_SCANCODE_KP_1)]) && - (rawinputkey[sdl_scancode(SDL_SCANCODE_LCTRL)] || rawinputkey[sdl_scancode(SDL_SCANCODE_RCTRL)])) - trigger_inputrelease = 1; - else if (trigger_inputrelease) { - trigger_inputrelease = 0; - if (!is_fullscreen()) - window_doinputrelease = 1; - } - if (window_doremember) { - window_doremember = 0; - SDL_GetWindowPosition(window, &window_x, &window_y); - SDL_GetWindowSize(window, &window_w, &window_h); - get_border_size(&border_y, &border_x, 0, 0); - window_x -= border_x; - window_y -= border_y; - saveconfig(NULL); - } + int key_idx = sdl_scancode(event.key.keysym.scancode); + if (key_idx != -1) + rawinputkey[key_idx] = event.key.timestamp; + break; + } + case SDL_KEYUP: { + int key_idx = sdl_scancode(event.key.keysym.scancode); + if (key_idx != -1) + rawinputkey[key_idx] = 0; + break; + } + } + } + if ((rawinputkey[sdl_scancode(SDL_SCANCODE_PAGEDOWN)] || rawinputkey[sdl_scancode(SDL_SCANCODE_KP_3)]) && + (rawinputkey[sdl_scancode(SDL_SCANCODE_LCTRL)] || rawinputkey[sdl_scancode(SDL_SCANCODE_RCTRL)]) && + (rawinputkey[sdl_scancode(SDL_SCANCODE_LALT)] || rawinputkey[sdl_scancode(SDL_SCANCODE_RALT)])) + trigger_fullscreen = 1; + else if (trigger_fullscreen) { + trigger_fullscreen = 0; + toggle_fullscreen(); + } else if ((rawinputkey[sdl_scancode(SDL_SCANCODE_PAGEUP)] || rawinputkey[sdl_scancode(SDL_SCANCODE_KP_9)]) && + (rawinputkey[sdl_scancode(SDL_SCANCODE_LCTRL)] || rawinputkey[sdl_scancode(SDL_SCANCODE_RCTRL)]) && + (rawinputkey[sdl_scancode(SDL_SCANCODE_LALT)] || rawinputkey[sdl_scancode(SDL_SCANCODE_RALT)])) + trigger_screenshot = 1; + else if (trigger_screenshot) { + trigger_screenshot = 0; + take_screenshot = 1; + } else if ((rawinputkey[sdl_scancode(SDL_SCANCODE_END)] || rawinputkey[sdl_scancode(SDL_SCANCODE_KP_1)]) && + (rawinputkey[sdl_scancode(SDL_SCANCODE_LCTRL)] || rawinputkey[sdl_scancode(SDL_SCANCODE_RCTRL)])) + trigger_inputrelease = 1; + else if (trigger_inputrelease) { + trigger_inputrelease = 0; + if (!is_fullscreen()) + window_doinputrelease = 1; + } + if (window_doremember) { + window_doremember = 0; + SDL_GetWindowPosition(window, &window_x, &window_y); + SDL_GetWindowSize(window, &window_w, &window_h); + get_border_size(&border_y, &border_x, 0, 0); + window_x -= border_x; + window_y -= border_y; + saveconfig(NULL); + } - if (window_dotogglefullscreen) { - window_dotogglefullscreen = 0; - if (SDL_GetWindowGrab(window) || is_fullscreen()) { - window_doinputrelease = 1; - if (is_fullscreen()) - window_dowindowed = 1; - } else { - window_doinputgrab = 1; - window_dofullscreen = 1; - } - } + if (window_dotogglefullscreen) { + window_dotogglefullscreen = 0; + if (SDL_GetWindowGrab(window) || is_fullscreen()) { + window_doinputrelease = 1; + if (is_fullscreen()) + window_dowindowed = 1; + } else { + window_doinputgrab = 1; + window_dofullscreen = 1; + } + } - if (window_dofullscreen) { - window_dofullscreen = 0; - video_wait_for_blit(); - SDL_RaiseWindow(window); + if (window_dofullscreen) { + window_dofullscreen = 0; + video_wait_for_blit(); + SDL_RaiseWindow(window); #if SDL_VERSION_ATLEAST(2, 0, 4) - SDL_GetGlobalMouseState(&remembered_mouse_x, &remembered_mouse_y); + SDL_GetGlobalMouseState(&remembered_mouse_x, &remembered_mouse_y); #endif - SDL_GetWindowPosition(window, &remembered_rect.x, &remembered_rect.y); - get_border_size(&border_y, &border_x, 0, 0); - remembered_rect.x -= border_x; - remembered_rect.y -= border_y; - SDL_GetWindowSize(window, &remembered_rect.w, &remembered_rect.h); - SDL_SetWindowFullscreen(window, video_fullscreen_mode == 0 ? SDL_WINDOW_FULLSCREEN_DESKTOP : SDL_WINDOW_FULLSCREEN); - device_force_redraw(); - } - if (window_doinputgrab) { - window_doinputgrab = 0; - mousecapture = 1; - SDL_GetRelativeMouseState(0, 0); - SDL_SetWindowGrab(window, SDL_TRUE); - SDL_SetRelativeMouseMode(SDL_TRUE); - } + SDL_GetWindowPosition(window, &remembered_rect.x, &remembered_rect.y); + get_border_size(&border_y, &border_x, 0, 0); + remembered_rect.x -= border_x; + remembered_rect.y -= border_y; + SDL_GetWindowSize(window, &remembered_rect.w, &remembered_rect.h); + SDL_SetWindowFullscreen(window, + video_fullscreen_mode == 0 ? SDL_WINDOW_FULLSCREEN_DESKTOP : SDL_WINDOW_FULLSCREEN); + device_force_redraw(); + } + if (window_doinputgrab) { + window_doinputgrab = 0; + mousecapture = 1; + SDL_GetRelativeMouseState(0, 0); + SDL_SetWindowGrab(window, SDL_TRUE); + SDL_SetRelativeMouseMode(SDL_TRUE); + } - if (window_doinputrelease) { - window_doinputrelease = 0; - mousecapture = 0; - SDL_SetWindowGrab(window, SDL_FALSE); - SDL_SetRelativeMouseMode(SDL_FALSE); - } - if (window_dowindowed) { - window_dowindowed = 0; - SDL_SetWindowFullscreen(window, 0); - SDL_SetWindowSize(window, remembered_rect.w, remembered_rect.h); - SDL_SetWindowPosition(window, remembered_rect.x, remembered_rect.y); + if (window_doinputrelease) { + window_doinputrelease = 0; + mousecapture = 0; + SDL_SetWindowGrab(window, SDL_FALSE); + SDL_SetRelativeMouseMode(SDL_FALSE); + } + if (window_dowindowed) { + window_dowindowed = 0; + SDL_SetWindowFullscreen(window, 0); + SDL_SetWindowSize(window, remembered_rect.w, remembered_rect.h); + SDL_SetWindowPosition(window, remembered_rect.x, remembered_rect.y); #if SDL_VERSION_ATLEAST(2, 0, 4) - SDL_WarpMouseGlobal(remembered_mouse_x, remembered_mouse_y); + SDL_WarpMouseGlobal(remembered_mouse_x, remembered_mouse_y); #endif - device_force_redraw(); - } + device_force_redraw(); + } - if (win_doresize) { - int flags = SDL_GetWindowFlags(window); + if (win_doresize) { + int flags = SDL_GetWindowFlags(window); - win_doresize = 0; - if (!vid_resize || (flags & SDL_WINDOW_FULLSCREEN)) { - SDL_GetWindowSize(window, &rect.w, &rect.h); - if (rect.w != winsizex || rect.h != winsizey) { - SDL_GetWindowPosition(window, &rect.x, &rect.y); - SDL_SetWindowSize(window, winsizex, winsizey); - SDL_SetWindowPosition(window, rect.x, rect.y); - device_force_redraw(); - } - } - } + win_doresize = 0; + if (!vid_resize || (flags & SDL_WINDOW_FULLSCREEN)) { + SDL_GetWindowSize(window, &rect.w, &rect.h); + if (rect.w != winsizex || rect.h != winsizey) { + SDL_GetWindowPosition(window, &rect.x, &rect.y); + SDL_SetWindowSize(window, winsizex, winsizey); + SDL_SetWindowPosition(window, rect.x, rect.y); + device_force_redraw(); + } + } + } - if (sdl_renderer_update(window)) - sdl_renderer_present(window); + if (sdl_renderer_update(window)) + sdl_renderer_present(window); - end_time = timer_read(); - render_time += end_time - start_time; + end_time = timer_read(); + render_time += end_time - start_time; - ++render_frames; - uint32_t ticks = SDL_GetTicks(); - if (ticks - render_frame_time >= 1000) { - render_fps = render_frames / ((ticks - render_frame_time) / 1000.0); - render_frames = 0; - render_frame_time = ticks; - } + ++render_frames; + uint32_t ticks = SDL_GetTicks(); + if (ticks - render_frame_time >= 1000) { + render_fps = render_frames / ((ticks - render_frame_time) / 1000.0); + render_frames = 0; + render_frame_time = ticks; + } - return 1; + return 1; } int renderer_thread(void *params) { - int internal_rendering; + int internal_rendering; - SDL_LockMutex(rendererMutex); - SDL_CondSignal(rendererCond); - SDL_UnlockMutex(rendererMutex); + SDL_LockMutex(rendererMutex); + SDL_CondSignal(rendererCond); + SDL_UnlockMutex(rendererMutex); - window_setup(); + window_setup(); - rendering = 1; - while (rendering) { + rendering = 1; + while (rendering) { - if (!window_create()) - rendering = 0; + if (!window_create()) + rendering = 0; - renderer_doreset = 1; - internal_rendering = 1; - while (rendering && internal_rendering) { - if (!render()) - internal_rendering = 0; + renderer_doreset = 1; + internal_rendering = 1; + while (rendering && internal_rendering) { + if (!render()) + internal_rendering = 0; - SDL_Delay(1); - } - window_close(); - } + SDL_Delay(1); + } + window_close(); + } - SDL_LockMutex(rendererMutex); - SDL_CondSignal(rendererCond); - SDL_UnlockMutex(rendererMutex); + SDL_LockMutex(rendererMutex); + SDL_CondSignal(rendererCond); + SDL_UnlockMutex(rendererMutex); - return SDL_TRUE; + return SDL_TRUE; } void *timer = 0; void render_timer() { #ifdef PCEM_RENDER_TIMER_LOOP - /* For some reason this while-loop works on OSX, which also fixes missing events. No idea why though. */ - renderer_thread(0); + /* For some reason this while-loop works on OSX, which also fixes missing events. No idea why though. */ + renderer_thread(0); #else - if (rendering && !render()) { - window_close(); - window_create(); - renderer_doreset = 1; - } + if (rendering && !render()) { + window_close(); + window_create(); + renderer_doreset = 1; + } #endif } void render_start_timer() { #ifdef PCEM_RENDER_TIMER_LOOP - timer = wx_createtimer(render_timer); - wx_starttimer(timer, 500, 1); + timer = wx_createtimer(render_timer); + wx_starttimer(timer, 500, 1); #else - window_setup(); - if (window_create()) { - rendering = 1; - renderer_doreset = 1; - wx_starttimer(timer, 1, 0); - } + window_setup(); + if (window_create()) { + rendering = 1; + renderer_doreset = 1; + wx_starttimer(timer, 1, 0); + } #endif } void renderer_start() { - if (!rendering) { + if (!rendering) { #ifdef PCEM_RENDER_WITH_TIMER - render_start_timer(); + render_start_timer(); #else - SDL_LockMutex(rendererMutex); - renderthread = SDL_CreateThread(renderer_thread, "SDL2 Thread", NULL); - SDL_CondWait(rendererCond, rendererMutex); - SDL_UnlockMutex(rendererMutex); + SDL_LockMutex(rendererMutex); + renderthread = SDL_CreateThread(renderer_thread, "SDL2 Thread", NULL); + SDL_CondWait(rendererCond, rendererMutex); + SDL_UnlockMutex(rendererMutex); #endif - } + } } void renderer_stop(int timeout) { #if defined(PCEM_RENDER_WITH_TIMER) && !defined(PCEM_RENDER_TIMER_LOOP) - rendering = 0; - window_close(); - wx_destroytimer(timer); + rendering = 0; + window_close(); + wx_destroytimer(timer); #else - if (rendering) { - SDL_LockMutex(rendererMutex); - rendering = 0; - if (timeout) - SDL_CondWaitTimeout(rendererCond, rendererMutex, timeout); - else - SDL_CondWait(rendererCond, rendererMutex); - SDL_UnlockMutex(rendererMutex); - renderthread = NULL; - } - if (timer) - wx_destroytimer(timer); + if (rendering) { + SDL_LockMutex(rendererMutex); + rendering = 0; + if (timeout) + SDL_CondWaitTimeout(rendererCond, rendererMutex, timeout); + else + SDL_CondWait(rendererCond, rendererMutex); + SDL_UnlockMutex(rendererMutex); + renderthread = NULL; + } + if (timer) + wx_destroytimer(timer); #endif } diff --git a/src/wx-ui/wx-sdl2-joystick.c b/src/wx-ui/wx-sdl2-joystick.c index d9848548..7458807e 100644 --- a/src/wx-ui/wx-sdl2-joystick.c +++ b/src/wx-ui/wx-sdl2-joystick.c @@ -13,133 +13,141 @@ plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; static SDL_Joystick *sdl_joy[MAX_PLAT_JOYSTICKS]; void joystick_init() { - int c; + int c; - SDL_InitSubSystem(SDL_INIT_JOYSTICK); - joysticks_present = SDL_NumJoysticks(); + SDL_InitSubSystem(SDL_INIT_JOYSTICK); + joysticks_present = SDL_NumJoysticks(); - memset(sdl_joy, 0, sizeof(sdl_joy)); - for (c = 0; c < joysticks_present; c++) { - sdl_joy[c] = SDL_JoystickOpen(c); + memset(sdl_joy, 0, sizeof(sdl_joy)); + for (c = 0; c < joysticks_present; c++) { + sdl_joy[c] = SDL_JoystickOpen(c); - if (sdl_joy[c]) { - int d; + if (sdl_joy[c]) { + int d; - pclog("Opened Joystick %i\n", c); - pclog(" Name: %s\n", SDL_JoystickName(sdl_joy[c])); - pclog(" Number of Axes: %d\n", SDL_JoystickNumAxes(sdl_joy[c])); - pclog(" Number of Buttons: %d\n", SDL_JoystickNumButtons(sdl_joy[c])); - pclog(" Number of Hats: %d\n", SDL_JoystickNumHats(sdl_joy[c])); + pclog("Opened Joystick %i\n", c); + pclog(" Name: %s\n", SDL_JoystickName(sdl_joy[c])); + pclog(" Number of Axes: %d\n", SDL_JoystickNumAxes(sdl_joy[c])); + pclog(" Number of Buttons: %d\n", SDL_JoystickNumButtons(sdl_joy[c])); + pclog(" Number of Hats: %d\n", SDL_JoystickNumHats(sdl_joy[c])); - strncpy(plat_joystick_state[c].name, SDL_JoystickNameForIndex(c), 64); - plat_joystick_state[c].nr_axes = SDL_JoystickNumAxes(sdl_joy[c]); - plat_joystick_state[c].nr_buttons = SDL_JoystickNumButtons(sdl_joy[c]); - plat_joystick_state[c].nr_povs = SDL_JoystickNumHats(sdl_joy[c]); + strncpy(plat_joystick_state[c].name, SDL_JoystickNameForIndex(c), 64); + plat_joystick_state[c].nr_axes = SDL_JoystickNumAxes(sdl_joy[c]); + plat_joystick_state[c].nr_buttons = SDL_JoystickNumButtons(sdl_joy[c]); + plat_joystick_state[c].nr_povs = SDL_JoystickNumHats(sdl_joy[c]); - for (d = 0; d < MIN(plat_joystick_state[c].nr_axes, 8); d++) { - sprintf(plat_joystick_state[c].axis[d].name, "Axis %i", d); - plat_joystick_state[c].axis[d].id = d; - } - for (d = 0; d < MIN(plat_joystick_state[c].nr_buttons, 8); d++) { - sprintf(plat_joystick_state[c].button[d].name, "Button %i", d); - plat_joystick_state[c].button[d].id = d; - } - for (d = 0; d < MIN(plat_joystick_state[c].nr_povs, 4); d++) { - sprintf(plat_joystick_state[c].pov[d].name, "POV %i", d); - plat_joystick_state[c].pov[d].id = d; - } - } - } + for (d = 0; d < MIN(plat_joystick_state[c].nr_axes, 8); d++) { + sprintf(plat_joystick_state[c].axis[d].name, "Axis %i", d); + plat_joystick_state[c].axis[d].id = d; + } + for (d = 0; d < MIN(plat_joystick_state[c].nr_buttons, 8); d++) { + sprintf(plat_joystick_state[c].button[d].name, "Button %i", d); + plat_joystick_state[c].button[d].id = d; + } + for (d = 0; d < MIN(plat_joystick_state[c].nr_povs, 4); d++) { + sprintf(plat_joystick_state[c].pov[d].name, "POV %i", d); + plat_joystick_state[c].pov[d].id = d; + } + } + } } void joystick_close() { - int c; + int c; - for (c = 0; c < joysticks_present; c++) { - if (sdl_joy[c]) - SDL_JoystickClose(sdl_joy[c]); - } + for (c = 0; c < joysticks_present; c++) { + if (sdl_joy[c]) + SDL_JoystickClose(sdl_joy[c]); + } } static int joystick_get_axis(int joystick_nr, int mapping) { - if (mapping & POV_X) { - switch (plat_joystick_state[joystick_nr].p[mapping & 3]) { - case SDL_HAT_LEFTUP: - case SDL_HAT_LEFT: - case SDL_HAT_LEFTDOWN:return -32767; + if (mapping & POV_X) { + switch (plat_joystick_state[joystick_nr].p[mapping & 3]) { + case SDL_HAT_LEFTUP: + case SDL_HAT_LEFT: + case SDL_HAT_LEFTDOWN: + return -32767; - case SDL_HAT_RIGHTUP: - case SDL_HAT_RIGHT: - case SDL_HAT_RIGHTDOWN:return 32767; + case SDL_HAT_RIGHTUP: + case SDL_HAT_RIGHT: + case SDL_HAT_RIGHTDOWN: + return 32767; - default:return 0; - } - } else if (mapping & POV_Y) { - switch (plat_joystick_state[joystick_nr].p[mapping & 3]) { - case SDL_HAT_LEFTUP: - case SDL_HAT_UP: - case SDL_HAT_RIGHTUP:return -32767; + default: + return 0; + } + } else if (mapping & POV_Y) { + switch (plat_joystick_state[joystick_nr].p[mapping & 3]) { + case SDL_HAT_LEFTUP: + case SDL_HAT_UP: + case SDL_HAT_RIGHTUP: + return -32767; - case SDL_HAT_LEFTDOWN: - case SDL_HAT_DOWN: - case SDL_HAT_RIGHTDOWN:return 32767; + case SDL_HAT_LEFTDOWN: + case SDL_HAT_DOWN: + case SDL_HAT_RIGHTDOWN: + return 32767; - default:return 0; - } - } else - return plat_joystick_state[joystick_nr].a[plat_joystick_state[joystick_nr].axis[mapping].id]; + default: + return 0; + } + } else + return plat_joystick_state[joystick_nr].a[plat_joystick_state[joystick_nr].axis[mapping].id]; } void joystick_poll() { - int c, d; + int c, d; - SDL_JoystickUpdate(); - for (c = 0; c < joysticks_present; c++) { - int b; + SDL_JoystickUpdate(); + for (c = 0; c < joysticks_present; c++) { + int b; - plat_joystick_state[c].a[0] = SDL_JoystickGetAxis(sdl_joy[c], 0); - plat_joystick_state[c].a[1] = SDL_JoystickGetAxis(sdl_joy[c], 1); - plat_joystick_state[c].a[2] = SDL_JoystickGetAxis(sdl_joy[c], 2); - plat_joystick_state[c].a[3] = SDL_JoystickGetAxis(sdl_joy[c], 3); - plat_joystick_state[c].a[4] = SDL_JoystickGetAxis(sdl_joy[c], 4); - plat_joystick_state[c].a[5] = SDL_JoystickGetAxis(sdl_joy[c], 5); + plat_joystick_state[c].a[0] = SDL_JoystickGetAxis(sdl_joy[c], 0); + plat_joystick_state[c].a[1] = SDL_JoystickGetAxis(sdl_joy[c], 1); + plat_joystick_state[c].a[2] = SDL_JoystickGetAxis(sdl_joy[c], 2); + plat_joystick_state[c].a[3] = SDL_JoystickGetAxis(sdl_joy[c], 3); + plat_joystick_state[c].a[4] = SDL_JoystickGetAxis(sdl_joy[c], 4); + plat_joystick_state[c].a[5] = SDL_JoystickGetAxis(sdl_joy[c], 5); - for (b = 0; b < 16; b++) - plat_joystick_state[c].b[b] = SDL_JoystickGetButton(sdl_joy[c], b); + for (b = 0; b < 16; b++) + plat_joystick_state[c].b[b] = SDL_JoystickGetButton(sdl_joy[c], b); - for (b = 0; b < 4; b++) - plat_joystick_state[c].p[b] = SDL_JoystickGetHat(sdl_joy[c], b); -// pclog("joystick %i - x=%i y=%i b[0]=%i b[1]=%i %i\n", c, joystick_state[c].x, joystick_state[c].y, joystick_state[c].b[0], joystick_state[c].b[1], joysticks_present); - } + for (b = 0; b < 4; b++) + plat_joystick_state[c].p[b] = SDL_JoystickGetHat(sdl_joy[c], b); + // pclog("joystick %i - x=%i y=%i b[0]=%i b[1]=%i %i\n", c, joystick_state[c].x, + // joystick_state[c].y, joystick_state[c].b[0], joystick_state[c].b[1], joysticks_present); + } - for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) { - if (joystick_state[c].plat_joystick_nr) { - int joystick_nr = joystick_state[c].plat_joystick_nr - 1; + for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) { + if (joystick_state[c].plat_joystick_nr) { + int joystick_nr = joystick_state[c].plat_joystick_nr - 1; - for (d = 0; d < joystick_get_axis_count(joystick_type); d++) - joystick_state[c].axis[d] = joystick_get_axis(joystick_nr, joystick_state[c].axis_mapping[d]); - for (d = 0; d < joystick_get_button_count(joystick_type); d++) - joystick_state[c].button[d] = plat_joystick_state[joystick_nr].b[joystick_state[c].button_mapping[d]]; - for (d = 0; d < joystick_get_pov_count(joystick_type); d++) { - int x, y; - double angle, magnitude; + for (d = 0; d < joystick_get_axis_count(joystick_type); d++) + joystick_state[c].axis[d] = joystick_get_axis(joystick_nr, joystick_state[c].axis_mapping[d]); + for (d = 0; d < joystick_get_button_count(joystick_type); d++) + joystick_state[c].button[d] = + plat_joystick_state[joystick_nr].b[joystick_state[c].button_mapping[d]]; + for (d = 0; d < joystick_get_pov_count(joystick_type); d++) { + int x, y; + double angle, magnitude; - x = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][0]); - y = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][1]); + x = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][0]); + y = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][1]); - angle = (atan2((double)y, (double)x) * 360.0) / (2 * M_PI); - magnitude = sqrt((double)x * (double)x + (double)y * (double)y); + angle = (atan2((double)y, (double)x) * 360.0) / (2 * M_PI); + magnitude = sqrt((double)x * (double)x + (double)y * (double)y); - if (magnitude < 16384) - joystick_state[c].pov[d] = -1; - else - joystick_state[c].pov[d] = ((int)angle + 90 + 360) % 360; - } - } else { - for (d = 0; d < joystick_get_axis_count(joystick_type); d++) - joystick_state[c].axis[d] = 0; - for (d = 0; d < joystick_get_button_count(joystick_type); d++) - joystick_state[c].button[d] = 0; - for (d = 0; d < joystick_get_pov_count(joystick_type); d++) - joystick_state[c].pov[d] = -1; - } - } + if (magnitude < 16384) + joystick_state[c].pov[d] = -1; + else + joystick_state[c].pov[d] = ((int)angle + 90 + 360) % 360; + } + } else { + for (d = 0; d < joystick_get_axis_count(joystick_type); d++) + joystick_state[c].axis[d] = 0; + for (d = 0; d < joystick_get_button_count(joystick_type); d++) + joystick_state[c].button[d] = 0; + for (d = 0; d < joystick_get_pov_count(joystick_type); d++) + joystick_state[c].pov[d] = -1; + } + } } diff --git a/src/wx-ui/wx-sdl2-keyboard.c b/src/wx-ui/wx-sdl2-keyboard.c index c89bd079..d6bca6dd 100644 --- a/src/wx-ui/wx-sdl2-keyboard.c +++ b/src/wx-ui/wx-sdl2-keyboard.c @@ -4,17 +4,13 @@ uint8_t pcem_key[272]; int rawinputkey[272]; -void keyboard_init() { - memset(pcem_key, 0, sizeof(pcem_key)); -} +void keyboard_init() { memset(pcem_key, 0, sizeof(pcem_key)); } -void keyboard_close() { -} +void keyboard_close() {} void keyboard_poll_host() { - int c; + int c; - for (c = 0; c < 272; ++c) - pcem_key[c] = rawinputkey[c] > 0; + for (c = 0; c < 272; ++c) + pcem_key[c] = rawinputkey[c] > 0; } - diff --git a/src/wx-ui/wx-sdl2-mouse.c b/src/wx-ui/wx-sdl2-mouse.c index 5be902a4..51218290 100644 --- a/src/wx-ui/wx-sdl2-mouse.c +++ b/src/wx-ui/wx-sdl2-mouse.c @@ -7,43 +7,37 @@ static int mouse_x = 0, mouse_y = 0, mouse_z = 0; int mouse[3]; -void mouse_init() { - memset(mouse, 0, sizeof(mouse)); -} +void mouse_init() { memset(mouse, 0, sizeof(mouse)); } -void mouse_close() { -} +void mouse_close() {} -void mouse_wheel_update(int dir) { - mouse[2] += dir; -} +void mouse_wheel_update(int dir) { mouse[2] += dir; } void mouse_poll_host() { - if (mousecapture) { - uint32_t mb = SDL_GetRelativeMouseState(&mouse[0], &mouse[1]); - mouse_buttons = 0; - if (mb & SDL_BUTTON(SDL_BUTTON_LEFT)) { - mouse_buttons |= 1; - } - if (mb & SDL_BUTTON(SDL_BUTTON_RIGHT)) { - mouse_buttons |= 2; - } - if (mb & SDL_BUTTON(SDL_BUTTON_MIDDLE)) { - mouse_buttons |= 4; - } - mouse_x += mouse[0]; - mouse_y += mouse[1]; - mouse_z += mouse[2]; - mouse[2] = 0; - } else { - mouse_x = mouse_y = mouse_z = mouse_buttons = 0; - } + if (mousecapture) { + uint32_t mb = SDL_GetRelativeMouseState(&mouse[0], &mouse[1]); + mouse_buttons = 0; + if (mb & SDL_BUTTON(SDL_BUTTON_LEFT)) { + mouse_buttons |= 1; + } + if (mb & SDL_BUTTON(SDL_BUTTON_RIGHT)) { + mouse_buttons |= 2; + } + if (mb & SDL_BUTTON(SDL_BUTTON_MIDDLE)) { + mouse_buttons |= 4; + } + mouse_x += mouse[0]; + mouse_y += mouse[1]; + mouse_z += mouse[2]; + mouse[2] = 0; + } else { + mouse_x = mouse_y = mouse_z = mouse_buttons = 0; + } } void mouse_get_mickeys(int *x, int *y, int *z) { - *x = mouse_x; - *y = mouse_y; - *z = mouse_z; - mouse_x = mouse_y = mouse_z = 0; + *x = mouse_x; + *y = mouse_y; + *z = mouse_z; + mouse_x = mouse_y = mouse_z = 0; } - diff --git a/src/wx-ui/wx-sdl2-status.c b/src/wx-ui/wx-sdl2-status.c index 4c3d0f77..df45467a 100644 --- a/src/wx-ui/wx-sdl2-status.c +++ b/src/wx-ui/wx-sdl2-status.c @@ -29,138 +29,130 @@ extern uint64_t render_time; static uint64_t status_time; drive_info_t *get_machine_info(char *s, int *num_drive_info) { - int drive, i; - int pos = 0; - sprintf(s, - "Model: %s\n" - "CPU: %s", - model_getname(), - models[model]->cpu[cpu_manufacturer].cpus[cpu].name); - if (emulation_state == EMULATION_RUNNING) - sprintf(s + strlen(s), "\nEmulation speed: %d%%", fps); - else if (emulation_state == EMULATION_PAUSED) - strcat(s, "\nEmulation is paused."); - else - strcat(s, "\nEmulation is not running."); + int drive, i; + int pos = 0; + sprintf(s, + "Model: %s\n" + "CPU: %s", + model_getname(), models[model]->cpu[cpu_manufacturer].cpus[cpu].name); + if (emulation_state == EMULATION_RUNNING) + sprintf(s + strlen(s), "\nEmulation speed: %d%%", fps); + else if (emulation_state == EMULATION_PAUSED) + strcat(s, "\nEmulation is paused."); + else + strcat(s, "\nEmulation is not running."); - for (i = 0; i < 2; ++i) { - drive = 'A' + i; - if (fdd_get_type(i) > 0) { - strcpy(drive_info[pos].fn, discfns[i]); - drive_info[pos].enabled = strlen(drive_info[pos].fn) > 0; - drive_info[pos].drive = i; - drive_info[pos].drive_letter = drive; - drive_info[pos].type = DRIVE_TYPE_FDD; - drive_info[pos].readflash = readflash_get(READFLASH_FDC, i); - readflash_clear(READFLASH_FDC, i); - pos++; - } - } - int num_hdds = hdd_controller_current_is_mfm() ? 2 : (hdd_controller_current_is_scsi() ? 7 : 4); - for (i = 0; i < num_hdds; ++i) { - drive = 'C' + i; - if (!hdd_controller_current_is_mfm() && i == cdrom_channel) { - if (cdrom_drive < 0) - continue; - if (cdrom_drive == CDROM_IMAGE) { - if (!strlen(image_path)) - continue; - strcpy(drive_info[pos].fn, image_path); - } else - strcpy(drive_info[pos].fn, ""); - drive_info[pos].enabled = strlen(drive_info[pos].fn) > 0; - drive_info[pos].drive = i; - drive_info[pos].drive_letter = drive; - drive_info[pos].type = DRIVE_TYPE_CDROM; - drive_info[pos].readflash = readflash_get(READFLASH_HDC, i); - readflash_clear(READFLASH_HDC, i); - pos++; - } else if (!hdd_controller_current_is_mfm() && i == zip_channel) { - strcpy(drive_info[pos].fn, ""); - drive_info[pos].enabled = zip_loaded(); - drive_info[pos].drive = i; - drive_info[pos].drive_letter = drive; - drive_info[pos].type = DRIVE_TYPE_FDD; - drive_info[pos].readflash = readflash_get(READFLASH_HDC, i); - readflash_clear(READFLASH_HDC, i); - pos++; - } else if (strlen(ide_fn[i]) > 0) { - strcpy(drive_info[pos].fn, ide_fn[i]); - drive_info[pos].enabled = 1; - drive_info[pos].drive = i; - drive_info[pos].drive_letter = drive; - drive_info[pos].type = DRIVE_TYPE_HDD; - drive_info[pos].readflash = readflash_get(READFLASH_HDC, i); - readflash_clear(READFLASH_HDC, i); - pos++; - } - } - *num_drive_info = pos; - return drive_info; + for (i = 0; i < 2; ++i) { + drive = 'A' + i; + if (fdd_get_type(i) > 0) { + strcpy(drive_info[pos].fn, discfns[i]); + drive_info[pos].enabled = strlen(drive_info[pos].fn) > 0; + drive_info[pos].drive = i; + drive_info[pos].drive_letter = drive; + drive_info[pos].type = DRIVE_TYPE_FDD; + drive_info[pos].readflash = readflash_get(READFLASH_FDC, i); + readflash_clear(READFLASH_FDC, i); + pos++; + } + } + int num_hdds = hdd_controller_current_is_mfm() ? 2 : (hdd_controller_current_is_scsi() ? 7 : 4); + for (i = 0; i < num_hdds; ++i) { + drive = 'C' + i; + if (!hdd_controller_current_is_mfm() && i == cdrom_channel) { + if (cdrom_drive < 0) + continue; + if (cdrom_drive == CDROM_IMAGE) { + if (!strlen(image_path)) + continue; + strcpy(drive_info[pos].fn, image_path); + } else + strcpy(drive_info[pos].fn, ""); + drive_info[pos].enabled = strlen(drive_info[pos].fn) > 0; + drive_info[pos].drive = i; + drive_info[pos].drive_letter = drive; + drive_info[pos].type = DRIVE_TYPE_CDROM; + drive_info[pos].readflash = readflash_get(READFLASH_HDC, i); + readflash_clear(READFLASH_HDC, i); + pos++; + } else if (!hdd_controller_current_is_mfm() && i == zip_channel) { + strcpy(drive_info[pos].fn, ""); + drive_info[pos].enabled = zip_loaded(); + drive_info[pos].drive = i; + drive_info[pos].drive_letter = drive; + drive_info[pos].type = DRIVE_TYPE_FDD; + drive_info[pos].readflash = readflash_get(READFLASH_HDC, i); + readflash_clear(READFLASH_HDC, i); + pos++; + } else if (strlen(ide_fn[i]) > 0) { + strcpy(drive_info[pos].fn, ide_fn[i]); + drive_info[pos].enabled = 1; + drive_info[pos].drive = i; + drive_info[pos].drive_letter = drive; + drive_info[pos].type = DRIVE_TYPE_HDD; + drive_info[pos].readflash = readflash_get(READFLASH_HDC, i); + readflash_clear(READFLASH_HDC, i); + pos++; + } + } + *num_drive_info = pos; + return drive_info; } int get_status(char *machine, char *device) { -// if (!status_is_open) { -// return 0; -// } -// char device_s[4096]; - uint64_t new_time = timer_read(); - uint64_t status_diff = new_time - status_time; - status_time = new_time; - sprintf(machine, - "CPU speed : %f MIPS\n" - "FPU speed : %f MFLOPS\n\n" + // if (!status_is_open) { + // return 0; + // } + // char device_s[4096]; + uint64_t new_time = timer_read(); + uint64_t status_diff = new_time - status_time; + status_time = new_time; + sprintf(machine, + "CPU speed : %f MIPS\n" + "FPU speed : %f MFLOPS\n\n" - /* "Cache misses (read) : %i/sec\n" - "Cache misses (write) : %i/sec\n\n"*/ + /* "Cache misses (read) : %i/sec\n" + "Cache misses (write) : %i/sec\n\n"*/ - "Video throughput (read) : %i bytes/sec\n" - "Video throughput (write) : %i bytes/sec\n\n" - "Effective clockspeed : %iHz\n\n" - "Timer 0 frequency : %fHz\n\n" - "CPU time : %f%% (%f%%)\n" - "Render time : %f%% (%f%%)\n" - "Renderer: %s\n" - "Render FPS: %d\n" - "\n" + "Video throughput (read) : %i bytes/sec\n" + "Video throughput (write) : %i bytes/sec\n\n" + "Effective clockspeed : %iHz\n\n" + "Timer 0 frequency : %fHz\n\n" + "CPU time : %f%% (%f%%)\n" + "Render time : %f%% (%f%%)\n" + "Renderer: %s\n" + "Render FPS: %d\n" + "\n" - "New blocks : %i\nOld blocks : %i\nRecompiled speed : %f MIPS\nAverage size : %f\n" - "Flushes : %i\nEvicted : %i\nReused : %i\nRemoved : %i\nReal speed : %f MIPS\nMem blocks used : %i (%g MB)" - // "\nFully recompiled ins %% : %f%%" - , mips, - flops, - /*#ifndef DYNAREC - sreadlnum, - swritelnum, - #endif*/ - segareads, - segawrites, - cpu_get_speed() - scycles_lost, - pit_timer0_freq(), - ((double)main_time * 100.0) / status_diff, - ((double)main_time * 100.0) / timer_freq, - ((double)render_time * 100.0) / status_diff, - ((double)render_time * 100.0) / timer_freq, - current_render_driver_name, - render_fps, cpu_new_blocks_latched, cpu_recomp_blocks_latched, (double)cpu_recomp_ins_latched / 1000000.0, (double)cpu_recomp_ins_latched / cpu_recomp_blocks_latched, - cpu_recomp_flushes_latched, cpu_recomp_evicted_latched, - cpu_recomp_reuse_latched, cpu_recomp_removed_latched, + "New blocks : %i\nOld blocks : %i\nRecompiled speed : %f MIPS\nAverage size : %f\n" + "Flushes : %i\nEvicted : %i\nReused : %i\nRemoved : %i\nReal speed : %f MIPS\nMem blocks used : %i (%g MB)" + // "\nFully recompiled ins %% : %f%%" + , + mips, flops, + /*#ifndef DYNAREC + sreadlnum, + swritelnum, + #endif*/ + segareads, segawrites, cpu_get_speed() - scycles_lost, pit_timer0_freq(), + ((double)main_time * 100.0) / status_diff, ((double)main_time * 100.0) / timer_freq, + ((double)render_time * 100.0) / status_diff, ((double)render_time * 100.0) / timer_freq, + current_render_driver_name, render_fps, cpu_new_blocks_latched, cpu_recomp_blocks_latched, + (double)cpu_recomp_ins_latched / 1000000.0, (double)cpu_recomp_ins_latched / cpu_recomp_blocks_latched, + cpu_recomp_flushes_latched, cpu_recomp_evicted_latched, cpu_recomp_reuse_latched, cpu_recomp_removed_latched, - ((double)cpu_recomp_ins_latched / 1000000.0) / ((double)main_time / timer_freq), - codegen_allocator_usage, - (double)(codegen_allocator_usage * MEM_BLOCK_SIZE) / (1024.0 * 1024.0) - // ((double)cpu_recomp_full_ins_latched / (double)cpu_recomp_ins_latched) * 100.0 - // cpu_reps_latched, cpu_notreps_latched - ); - main_time = 0; - render_time = 0; - /*#ifndef DYNAREC - device_add_status_info(device_s, 4096); - #endif*/ + ((double)cpu_recomp_ins_latched / 1000000.0) / ((double)main_time / timer_freq), codegen_allocator_usage, + (double)(codegen_allocator_usage * MEM_BLOCK_SIZE) / (1024.0 * 1024.0) + // ((double)cpu_recomp_full_ins_latched / (double)cpu_recomp_ins_latched) * 100.0 + // cpu_reps_latched, cpu_notreps_latched + ); + main_time = 0; + render_time = 0; + /*#ifndef DYNAREC + device_add_status_info(device_s, 4096); + #endif*/ -// device_s[0] = 0; - device[0] = 0; - device_add_status_info(device, 4096); + // device_s[0] = 0; + device[0] = 0; + device_add_status_info(device, 4096); - return 1; + return 1; } diff --git a/src/wx-ui/wx-sdl2-video-gl3.c b/src/wx-ui/wx-sdl2-video-gl3.c index 5cef7b41..836e78fb 100644 --- a/src/wx-ui/wx-sdl2-video-gl3.c +++ b/src/wx-ui/wx-sdl2-video-gl3.c @@ -41,12 +41,7 @@ static glsl_t *active_shader; static glw_t *glw; -static GLfloat matrix[] = { - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1 -}; +static GLfloat matrix[] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; extern int video_scale_mode; extern int video_vsync; @@ -55,1529 +50,1485 @@ extern int video_refresh_rate; static int glsl_version[2]; -const char *vertex_shader_default_tex_src = - "#version 130\n" - "\n" - "in vec4 VertexCoord;\n" - "in vec2 TexCoord;\n" - "\n" - "out vec2 texCoord;\n" - "\n" - "void main()\n" - "{\n" - " gl_Position = VertexCoord;\n" - " texCoord = TexCoord;\n" - "}\n"; +const char *vertex_shader_default_tex_src = "#version 130\n" + "\n" + "in vec4 VertexCoord;\n" + "in vec2 TexCoord;\n" + "\n" + "out vec2 texCoord;\n" + "\n" + "void main()\n" + "{\n" + " gl_Position = VertexCoord;\n" + " texCoord = TexCoord;\n" + "}\n"; -const char *fragment_shader_default_tex_src = - "#version 130\n" - "\n" - "in vec2 texCoord;\n" - "uniform sampler2D Texture;\n" - "\n" - "out vec4 color;" - "\n" - "void main()\n" - "{\n" - " color = texture(Texture, texCoord);\n" - "}\n"; +const char *fragment_shader_default_tex_src = "#version 130\n" + "\n" + "in vec2 texCoord;\n" + "uniform sampler2D Texture;\n" + "\n" + "out vec4 color;" + "\n" + "void main()\n" + "{\n" + " color = texture(Texture, texCoord);\n" + "}\n"; -const char *vertex_shader_default_color_src = - "#version 130\n" - "\n" - "in vec4 VertexCoord;\n" - "in vec4 Color;\n" - "\n" - "out vec4 color;\n" - "\n" - "void main()\n" - "{\n" - " gl_Position = VertexCoord;\n" - " color = Color;\n" - "}\n"; +const char *vertex_shader_default_color_src = "#version 130\n" + "\n" + "in vec4 VertexCoord;\n" + "in vec4 Color;\n" + "\n" + "out vec4 color;\n" + "\n" + "void main()\n" + "{\n" + " gl_Position = VertexCoord;\n" + " color = Color;\n" + "}\n"; -const char *fragment_shader_default_color_src = - "#version 130\n" - "\n" - "in vec4 color;\n" - "\n" - "out vec4 outColor;" - "\n" - "void main()\n" - "{\n" - " outColor = color;\n" - "}\n"; +const char *fragment_shader_default_color_src = "#version 130\n" + "\n" + "in vec4 color;\n" + "\n" + "out vec4 outColor;" + "\n" + "void main()\n" + "{\n" + " outColor = color;\n" + "}\n"; static int next_pow2(unsigned int n) { - n--; - n |= n >> 1; // Divide by 2^k for consecutive doublings of k up to 32, - n |= n >> 2; // and then or the results. - n |= n >> 4; - n |= n >> 8; - n |= n >> 16; - n++; + n--; + n |= n >> 1; // Divide by 2^k for consecutive doublings of k up to 32, + n |= n >> 2; // and then or the results. + n |= n >> 4; + n |= n >> 8; + n |= n >> 16; + n++; - return n; + return n; } static int compile_shader(GLenum shader_type, const char *prepend, const char *program, int *dst) { - const char *source[3]; - char version[50]; - int ver = 0; - char *version_loc = strstr(program, "#version"); - if (version_loc) - ver = (int)strtol(version_loc + 8, (char **)&program, 10); - else { - ver = glsl_version[0] * 100 + glsl_version[1] * 10; - if (ver == 300) - ver = 130; - else if (ver == 310) - ver = 140; - else if (ver == 320) - ver = 150; - } - sprintf(version, "#version %d\n", ver); - source[0] = version; - source[1] = prepend ? prepend : ""; - source[2] = program; + const char *source[3]; + char version[50]; + int ver = 0; + char *version_loc = strstr(program, "#version"); + if (version_loc) + ver = (int)strtol(version_loc + 8, (char **)&program, 10); + else { + ver = glsl_version[0] * 100 + glsl_version[1] * 10; + if (ver == 300) + ver = 130; + else if (ver == 310) + ver = 140; + else if (ver == 320) + ver = 150; + } + sprintf(version, "#version %d\n", ver); + source[0] = version; + source[1] = prepend ? prepend : ""; + source[2] = program; - pclog("GLSL version %d\n", ver); + pclog("GLSL version %d\n", ver); - GLuint shader = glw->glCreateShader(shader_type); - glw->glShaderSource(shader, 3, source, NULL); - glw->glCompileShader(shader); + GLuint shader = glw->glCreateShader(shader_type); + glw->glShaderSource(shader, 3, source, NULL); + glw->glCompileShader(shader); - GLint status = 0; - glw->glGetShaderiv(shader, GL_COMPILE_STATUS, &status); - if (!status) { - GLint length; - glw->glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length); - char *log = malloc(length); - glw->glGetShaderInfoLog(shader, length, &length, log); - wx_simple_messagebox("GLSL Error", "Could not compile shader:\n%s", log); - pclog("Could not compile shader: %s\n", log); -// pclog("Shader: %s\n", program); + GLint status = 0; + glw->glGetShaderiv(shader, GL_COMPILE_STATUS, &status); + if (!status) { + GLint length; + glw->glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length); + char *log = malloc(length); + glw->glGetShaderInfoLog(shader, length, &length, log); + wx_simple_messagebox("GLSL Error", "Could not compile shader:\n%s", log); + pclog("Could not compile shader: %s\n", log); + // pclog("Shader: %s\n", program); - free(log); - return 0; - } + free(log); + return 0; + } - *dst = shader; + *dst = shader; - return 1; + return 1; } static int create_program(struct shader_program *program) { - GLint status; - program->id = glw->glCreateProgram(); - glw->glAttachShader(program->id, program->vertex_shader); - glw->glAttachShader(program->id, program->fragment_shader); + GLint status; + program->id = glw->glCreateProgram(); + glw->glAttachShader(program->id, program->vertex_shader); + glw->glAttachShader(program->id, program->fragment_shader); - glw->glLinkProgram(program->id); + glw->glLinkProgram(program->id); - glw->glDeleteShader(program->vertex_shader); - glw->glDeleteShader(program->fragment_shader); + glw->glDeleteShader(program->vertex_shader); + glw->glDeleteShader(program->fragment_shader); - program->vertex_shader = program->fragment_shader = 0; + program->vertex_shader = program->fragment_shader = 0; - glw->glGetProgramiv(program->id, GL_LINK_STATUS, &status); + glw->glGetProgramiv(program->id, GL_LINK_STATUS, &status); - if (!status) { - int maxLength; - int length; - glw->glGetProgramiv(program->id, GL_INFO_LOG_LENGTH, &maxLength); - char *log = malloc(maxLength); - glw->glGetProgramInfoLog(program->id, maxLength, &length, log); - wx_simple_messagebox("GLSL Error", "Program not linked:\n%s", log); - free(log); - return 0; - } + if (!status) { + int maxLength; + int length; + glw->glGetProgramiv(program->id, GL_INFO_LOG_LENGTH, &maxLength); + char *log = malloc(maxLength); + glw->glGetProgramInfoLog(program->id, maxLength, &length, log); + wx_simple_messagebox("GLSL Error", "Program not linked:\n%s", log); + free(log); + return 0; + } - return 1; + return 1; } -static GLuint get_uniform(GLuint program, const char *name) { - return glw->glGetUniformLocation(program, name); -} +static GLuint get_uniform(GLuint program, const char *name) { return glw->glGetUniformLocation(program, name); } -static GLuint get_attrib(GLuint program, const char *name) { - return glw->glGetAttribLocation(program, name); -} +static GLuint get_attrib(GLuint program, const char *name) { return glw->glGetAttribLocation(program, name); } static void find_uniforms(struct glsl_shader *glsl, int num_pass) { - int i; - char s[50]; - struct shader_pass *pass = &glsl->passes[num_pass]; - int p = pass->program.id; - glw->glUseProgram(p); + int i; + char s[50]; + struct shader_pass *pass = &glsl->passes[num_pass]; + int p = pass->program.id; + glw->glUseProgram(p); - struct shader_uniforms *u = &pass->uniforms; + struct shader_uniforms *u = &pass->uniforms; - u->mvp_matrix = get_uniform(p, "MVPMatrix"); - u->vertex_coord = get_attrib(p, "VertexCoord"); - u->tex_coord = get_attrib(p, "TexCoord"); - u->color = get_attrib(p, "Color"); + u->mvp_matrix = get_uniform(p, "MVPMatrix"); + u->vertex_coord = get_attrib(p, "VertexCoord"); + u->tex_coord = get_attrib(p, "TexCoord"); + u->color = get_attrib(p, "Color"); - u->frame_count = get_uniform(p, "FrameCount"); - u->frame_direction = get_uniform(p, "FrameDirection"); + u->frame_count = get_uniform(p, "FrameCount"); + u->frame_direction = get_uniform(p, "FrameDirection"); - u->texture = get_uniform(p, "Texture"); - u->input_size = get_uniform(p, "InputSize"); - u->texture_size = get_uniform(p, "TextureSize"); - u->output_size = get_uniform(p, "OutputSize"); + u->texture = get_uniform(p, "Texture"); + u->input_size = get_uniform(p, "InputSize"); + u->texture_size = get_uniform(p, "TextureSize"); + u->output_size = get_uniform(p, "OutputSize"); - u->orig.texture = get_uniform(p, "OrigTexture"); - u->orig.input_size = get_uniform(p, "OrigInputSize"); - u->orig.texture_size = get_uniform(p, "OrigTextureSize"); + u->orig.texture = get_uniform(p, "OrigTexture"); + u->orig.input_size = get_uniform(p, "OrigInputSize"); + u->orig.texture_size = get_uniform(p, "OrigTextureSize"); - for (i = 0; i < glsl->num_passes; ++i) { - sprintf(s, "Pass%dTexture", (i + 1)); - u->pass[i].texture = get_uniform(p, s); - sprintf(s, "Pass%dInputSize", (i + 1)); - u->pass[i].input_size = get_uniform(p, s); - sprintf(s, "Pass%dTextureSize", (i + 1)); - u->pass[i].texture_size = get_uniform(p, s); + for (i = 0; i < glsl->num_passes; ++i) { + sprintf(s, "Pass%dTexture", (i + 1)); + u->pass[i].texture = get_uniform(p, s); + sprintf(s, "Pass%dInputSize", (i + 1)); + u->pass[i].input_size = get_uniform(p, s); + sprintf(s, "Pass%dTextureSize", (i + 1)); + u->pass[i].texture_size = get_uniform(p, s); - sprintf(s, "PassPrev%dTexture", num_pass - i); - u->prev_pass[i].texture = get_uniform(p, s); - sprintf(s, "PassPrev%dInputSize", num_pass - i); - u->prev_pass[i].input_size = get_uniform(p, s); - sprintf(s, "PassPrev%dTextureSize", num_pass - i); - u->prev_pass[i].texture_size = get_uniform(p, s); - } + sprintf(s, "PassPrev%dTexture", num_pass - i); + u->prev_pass[i].texture = get_uniform(p, s); + sprintf(s, "PassPrev%dInputSize", num_pass - i); + u->prev_pass[i].input_size = get_uniform(p, s); + sprintf(s, "PassPrev%dTextureSize", num_pass - i); + u->prev_pass[i].texture_size = get_uniform(p, s); + } - u->prev[0].texture = get_uniform(p, "PrevTexture"); - u->prev[0].tex_coord = get_attrib(p, "PrevTexCoord"); - for (i = 1; i < MAX_PREV; ++i) { - sprintf(s, "Prev%dTexture", i); - u->prev[i].texture = get_uniform(p, s); - sprintf(s, "Prev%dTexCoord", i); - u->prev[i].tex_coord = get_attrib(p, s); - } - for (i = 0; i < MAX_PREV; ++i) - if (u->prev[i].texture >= 0) - glsl->has_prev = 1; + u->prev[0].texture = get_uniform(p, "PrevTexture"); + u->prev[0].tex_coord = get_attrib(p, "PrevTexCoord"); + for (i = 1; i < MAX_PREV; ++i) { + sprintf(s, "Prev%dTexture", i); + u->prev[i].texture = get_uniform(p, s); + sprintf(s, "Prev%dTexCoord", i); + u->prev[i].tex_coord = get_attrib(p, s); + } + for (i = 0; i < MAX_PREV; ++i) + if (u->prev[i].texture >= 0) + glsl->has_prev = 1; - for (i = 0; i < glsl->num_lut_textures; ++i) - u->lut_textures[i] = get_uniform(p, glsl->lut_textures[i].name); + for (i = 0; i < glsl->num_lut_textures; ++i) + u->lut_textures[i] = get_uniform(p, glsl->lut_textures[i].name); - for (i = 0; i < glsl->num_parameters; ++i) - u->parameters[i] = get_uniform(p, glsl->parameters[i].id); + for (i = 0; i < glsl->num_parameters; ++i) + u->parameters[i] = get_uniform(p, glsl->parameters[i].id); - glw->glUseProgram(0); + glw->glUseProgram(0); } static void set_scale_mode(char *scale, int *dst) { - if (!strcmp(scale, "viewport")) - *dst = SCALE_VIEWPORT; - else if (!strcmp(scale, "absolute")) - *dst = SCALE_ABSOLUTE; - else - *dst = SCALE_SOURCE; + if (!strcmp(scale, "viewport")) + *dst = SCALE_VIEWPORT; + else if (!strcmp(scale, "absolute")) + *dst = SCALE_ABSOLUTE; + else + *dst = SCALE_SOURCE; } static void setup_scale(struct shader *shader, struct shader_pass *pass) { - set_scale_mode(shader->scale_type_x, &pass->scale.mode[0]); - set_scale_mode(shader->scale_type_y, &pass->scale.mode[1]); - pass->scale.value[0] = shader->scale_x; - pass->scale.value[1] = shader->scale_y; + set_scale_mode(shader->scale_type_x, &pass->scale.mode[0]); + set_scale_mode(shader->scale_type_y, &pass->scale.mode[1]); + pass->scale.value[0] = shader->scale_x; + pass->scale.value[1] = shader->scale_y; } static void create_texture(struct shader_texture *tex) { - if (tex->width > max_texture_size) - tex->width = max_texture_size; - if (tex->height > max_texture_size) - tex->height = max_texture_size; - pclog("Create texture with size %dx%d\n", tex->width, tex->height); - glGenTextures(1, (GLuint *)&tex->id); - glBindTexture(GL_TEXTURE_2D, tex->id); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, tex->wrap_mode); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, tex->wrap_mode); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, tex->min_filter); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, tex->mag_filter); - glTexImage2D(GL_TEXTURE_2D, 0, tex->internal_format, tex->width, tex->height, 0, tex->format, tex->type, tex->data); - if (tex->mipmap) - glw->glGenerateMipmap(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, 0); + if (tex->width > max_texture_size) + tex->width = max_texture_size; + if (tex->height > max_texture_size) + tex->height = max_texture_size; + pclog("Create texture with size %dx%d\n", tex->width, tex->height); + glGenTextures(1, (GLuint *)&tex->id); + glBindTexture(GL_TEXTURE_2D, tex->id); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, tex->wrap_mode); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, tex->wrap_mode); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, tex->min_filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, tex->mag_filter); + glTexImage2D(GL_TEXTURE_2D, 0, tex->internal_format, tex->width, tex->height, 0, tex->format, tex->type, tex->data); + if (tex->mipmap) + glw->glGenerateMipmap(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, 0); } static void delete_texture(struct shader_texture *tex) { - if (tex->id > 0) - glDeleteTextures(1, (GLuint *)&tex->id); - tex->id = 0; + if (tex->id > 0) + glDeleteTextures(1, (GLuint *)&tex->id); + tex->id = 0; } static void delete_fbo(struct shader_fbo *fbo) { - if (fbo->id >= 0) { - glw->glDeleteFramebuffers(1, (GLuint *)&fbo->id); - delete_texture(&fbo->texture); - } + if (fbo->id >= 0) { + glw->glDeleteFramebuffers(1, (GLuint *)&fbo->id); + delete_texture(&fbo->texture); + } } static void delete_program(struct shader_program *program) { - if (program->vertex_shader) - glw->glDeleteShader(program->vertex_shader); - if (program->fragment_shader) - glw->glDeleteShader(program->fragment_shader); - glw->glDeleteProgram(program->id); + if (program->vertex_shader) + glw->glDeleteShader(program->vertex_shader); + if (program->fragment_shader) + glw->glDeleteShader(program->fragment_shader); + glw->glDeleteProgram(program->id); } static void delete_vbo(struct shader_vbo *vbo) { - if (vbo->color >= 0) - glw->glDeleteBuffers(1, (GLuint *)&vbo->color); - glw->glDeleteBuffers(1, (GLuint *)&vbo->vertex_coord); - glw->glDeleteBuffers(1, (GLuint *)&vbo->tex_coord); + if (vbo->color >= 0) + glw->glDeleteBuffers(1, (GLuint *)&vbo->color); + glw->glDeleteBuffers(1, (GLuint *)&vbo->vertex_coord); + glw->glDeleteBuffers(1, (GLuint *)&vbo->tex_coord); } static void delete_pass(struct shader_pass *pass) { - delete_fbo(&pass->fbo); - delete_vbo(&pass->vbo); - delete_program(&pass->program); - glw->glDeleteVertexArrays(1, (GLuint *)&pass->vertex_array); + delete_fbo(&pass->fbo); + delete_vbo(&pass->vbo); + delete_program(&pass->program); + glw->glDeleteVertexArrays(1, (GLuint *)&pass->vertex_array); } static void delete_prev(struct shader_prev *prev) { - delete_fbo(&prev->fbo); - delete_vbo(&prev->vbo); + delete_fbo(&prev->fbo); + delete_vbo(&prev->vbo); } static void delete_shader(struct glsl_shader *glsl) { - int i; - for (i = 0; i < glsl->num_passes; ++i) - delete_pass(&glsl->passes[i]); - if (glsl->has_prev) { - delete_pass(&glsl->prev_scene); - for (i = 0; i < MAX_PREV; ++i) - delete_prev(&glsl->prev[i]); - } - for (i = 0; i < glsl->num_lut_textures; ++i) - delete_texture(&glsl->lut_textures[i].texture); + int i; + for (i = 0; i < glsl->num_passes; ++i) + delete_pass(&glsl->passes[i]); + if (glsl->has_prev) { + delete_pass(&glsl->prev_scene); + for (i = 0; i < MAX_PREV; ++i) + delete_prev(&glsl->prev[i]); + } + for (i = 0; i < glsl->num_lut_textures; ++i) + delete_texture(&glsl->lut_textures[i].texture); } static void delete_glsl(glsl_t *glsl) { - int i; - for (i = 0; i < glsl->num_shaders; ++i) - delete_shader(&glsl->shaders[i]); - delete_pass(&glsl->scene); - delete_pass(&glsl->fs_color); - delete_pass(&glsl->final_pass); + int i; + for (i = 0; i < glsl->num_shaders; ++i) + delete_shader(&glsl->shaders[i]); + delete_pass(&glsl->scene); + delete_pass(&glsl->fs_color); + delete_pass(&glsl->final_pass); #ifdef SDL2_SHADER_DEBUG - delete_pass(&glsl->debug); + delete_pass(&glsl->debug); #endif } static void create_fbo(struct shader_fbo *fbo) { - create_texture(&fbo->texture); + create_texture(&fbo->texture); - glw->glGenFramebuffers(1, (GLuint *)&fbo->id); - glw->glBindFramebuffer(GL_FRAMEBUFFER, fbo->id); - glw->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo->texture.id, 0); + glw->glGenFramebuffers(1, (GLuint *)&fbo->id); + glw->glBindFramebuffer(GL_FRAMEBUFFER, fbo->id); + glw->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo->texture.id, 0); - if (glw->glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) - pclog("Could not create framebuffer!\n"); + if (glw->glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + pclog("Could not create framebuffer!\n"); - glw->glBindFramebuffer(GL_FRAMEBUFFER, 0); + glw->glBindFramebuffer(GL_FRAMEBUFFER, 0); } static void setup_fbo(struct shader *shader, struct shader_fbo *fbo) { - fbo->texture.internal_format = GL_RGBA8; - fbo->texture.format = GL_RGBA; - fbo->texture.min_filter = fbo->texture.mag_filter = shader->filter_linear ? GL_LINEAR : GL_NEAREST; - fbo->texture.width = 1024; - fbo->texture.height = 1024; - fbo->texture.type = GL_UNSIGNED_BYTE; - if (!strcmp(shader->wrap_mode, "repeat")) - fbo->texture.wrap_mode = GL_REPEAT; - else if (!strcmp(shader->wrap_mode, "mirrored_repeat")) - fbo->texture.wrap_mode = GL_MIRRORED_REPEAT; - else if (!strcmp(shader->wrap_mode, "clamp_to_edge")) - fbo->texture.wrap_mode = GL_CLAMP_TO_EDGE; - else - fbo->texture.wrap_mode = GL_CLAMP_TO_BORDER; - fbo->srgb = 0; - if (shader->srgb_framebuffer) { - fbo->texture.internal_format = GL_SRGB8_ALPHA8; - fbo->srgb = 1; - } else if (shader->float_framebuffer) { - fbo->texture.internal_format = GL_RGBA32F; - fbo->texture.type = GL_FLOAT; - } + fbo->texture.internal_format = GL_RGBA8; + fbo->texture.format = GL_RGBA; + fbo->texture.min_filter = fbo->texture.mag_filter = shader->filter_linear ? GL_LINEAR : GL_NEAREST; + fbo->texture.width = 1024; + fbo->texture.height = 1024; + fbo->texture.type = GL_UNSIGNED_BYTE; + if (!strcmp(shader->wrap_mode, "repeat")) + fbo->texture.wrap_mode = GL_REPEAT; + else if (!strcmp(shader->wrap_mode, "mirrored_repeat")) + fbo->texture.wrap_mode = GL_MIRRORED_REPEAT; + else if (!strcmp(shader->wrap_mode, "clamp_to_edge")) + fbo->texture.wrap_mode = GL_CLAMP_TO_EDGE; + else + fbo->texture.wrap_mode = GL_CLAMP_TO_BORDER; + fbo->srgb = 0; + if (shader->srgb_framebuffer) { + fbo->texture.internal_format = GL_SRGB8_ALPHA8; + fbo->srgb = 1; + } else if (shader->float_framebuffer) { + fbo->texture.internal_format = GL_RGBA32F; + fbo->texture.type = GL_FLOAT; + } - if (fbo->texture.mipmap) - fbo->texture.min_filter = shader->filter_linear ? GL_LINEAR_MIPMAP_LINEAR : GL_NEAREST_MIPMAP_NEAREST; + if (fbo->texture.mipmap) + fbo->texture.min_filter = shader->filter_linear ? GL_LINEAR_MIPMAP_LINEAR : GL_NEAREST_MIPMAP_NEAREST; - create_fbo(fbo); + create_fbo(fbo); } static void recreate_fbo(struct shader_fbo *fbo, int width, int height) { - if (width != fbo->texture.width || height != fbo->texture.height) { - glw->glDeleteFramebuffers(1, (GLuint *)&fbo->id); - glDeleteTextures(1, (GLuint *)&fbo->texture.id); - fbo->texture.width = width; - fbo->texture.height = height; - create_fbo(fbo); - } + if (width != fbo->texture.width || height != fbo->texture.height) { + glw->glDeleteFramebuffers(1, (GLuint *)&fbo->id); + glDeleteTextures(1, (GLuint *)&fbo->texture.id); + fbo->texture.width = width; + fbo->texture.height = height; + create_fbo(fbo); + } } static int create_default_shader_tex(struct shader_pass *pass) { - if ( - !compile_shader(GL_VERTEX_SHADER, 0, vertex_shader_default_tex_src, &pass->program.vertex_shader) || - !compile_shader(GL_FRAGMENT_SHADER, 0, fragment_shader_default_tex_src, &pass->program.fragment_shader) || - !create_program(&pass->program)) - return 0; - glw->glGenVertexArrays(1, (GLuint *)&pass->vertex_array); + if (!compile_shader(GL_VERTEX_SHADER, 0, vertex_shader_default_tex_src, &pass->program.vertex_shader) || + !compile_shader(GL_FRAGMENT_SHADER, 0, fragment_shader_default_tex_src, &pass->program.fragment_shader) || + !create_program(&pass->program)) + return 0; + glw->glGenVertexArrays(1, (GLuint *)&pass->vertex_array); - struct shader_uniforms *u = &pass->uniforms; - int p = pass->program.id; - memset(u, -1, sizeof(struct shader_uniforms)); - u->vertex_coord = get_attrib(p, "VertexCoord"); - u->tex_coord = get_attrib(p, "TexCoord"); - u->texture = get_uniform(p, "Texture"); - pass->scale.mode[0] = pass->scale.mode[1] = SCALE_SOURCE; - pass->scale.value[0] = pass->scale.value[1] = 1.0f; - pass->fbo.id = -1; - pass->active = 1; - return 1; + struct shader_uniforms *u = &pass->uniforms; + int p = pass->program.id; + memset(u, -1, sizeof(struct shader_uniforms)); + u->vertex_coord = get_attrib(p, "VertexCoord"); + u->tex_coord = get_attrib(p, "TexCoord"); + u->texture = get_uniform(p, "Texture"); + pass->scale.mode[0] = pass->scale.mode[1] = SCALE_SOURCE; + pass->scale.value[0] = pass->scale.value[1] = 1.0f; + pass->fbo.id = -1; + pass->active = 1; + return 1; } static int create_default_shader_color(struct shader_pass *pass) { - if ( - !compile_shader(GL_VERTEX_SHADER, 0, vertex_shader_default_color_src, &pass->program.vertex_shader) || - !compile_shader(GL_FRAGMENT_SHADER, 0, fragment_shader_default_color_src, &pass->program.fragment_shader) || - !create_program(&pass->program)) - return 0; - glw->glGenVertexArrays(1, (GLuint *)&pass->vertex_array); + if (!compile_shader(GL_VERTEX_SHADER, 0, vertex_shader_default_color_src, &pass->program.vertex_shader) || + !compile_shader(GL_FRAGMENT_SHADER, 0, fragment_shader_default_color_src, &pass->program.fragment_shader) || + !create_program(&pass->program)) + return 0; + glw->glGenVertexArrays(1, (GLuint *)&pass->vertex_array); - struct shader_uniforms *u = &pass->uniforms; - int p = pass->program.id; - memset(u, -1, sizeof(struct shader_uniforms)); - u->vertex_coord = get_attrib(p, "VertexCoord"); - u->color = get_attrib(p, "Color"); - pass->scale.mode[0] = pass->scale.mode[1] = SCALE_SOURCE; - pass->scale.value[0] = pass->scale.value[1] = 1.0f; - pass->fbo.id = -1; - pass->active = 1; - return 1; + struct shader_uniforms *u = &pass->uniforms; + int p = pass->program.id; + memset(u, -1, sizeof(struct shader_uniforms)); + u->vertex_coord = get_attrib(p, "VertexCoord"); + u->color = get_attrib(p, "Color"); + pass->scale.mode[0] = pass->scale.mode[1] = SCALE_SOURCE; + pass->scale.value[0] = pass->scale.value[1] = 1.0f; + pass->fbo.id = -1; + pass->active = 1; + return 1; } /* create the default scene shader */ static void create_scene_shader() { - struct shader scene_shader_conf; - memset(&scene_shader_conf, 0, sizeof(struct shader)); - create_default_shader_tex(&active_shader->scene); - scene_shader_conf.filter_linear = video_scale_mode; - if (active_shader->num_shaders > 0 && active_shader->shaders[0].input_filter_linear >= 0) - scene_shader_conf.filter_linear = active_shader->shaders[0].input_filter_linear; - setup_fbo(&scene_shader_conf, &active_shader->scene.fbo); + struct shader scene_shader_conf; + memset(&scene_shader_conf, 0, sizeof(struct shader)); + create_default_shader_tex(&active_shader->scene); + scene_shader_conf.filter_linear = video_scale_mode; + if (active_shader->num_shaders > 0 && active_shader->shaders[0].input_filter_linear >= 0) + scene_shader_conf.filter_linear = active_shader->shaders[0].input_filter_linear; + setup_fbo(&scene_shader_conf, &active_shader->scene.fbo); - memset(&scene_shader_conf, 0, sizeof(struct shader)); - create_default_shader_color(&active_shader->fs_color); - setup_fbo(&scene_shader_conf, &active_shader->fs_color.fbo); + memset(&scene_shader_conf, 0, sizeof(struct shader)); + create_default_shader_color(&active_shader->fs_color); + setup_fbo(&scene_shader_conf, &active_shader->fs_color.fbo); } static int load_texture(const char *f, struct shader_texture *tex) { - void *img = wx_image_load(f); - if (!img) - return 0; - int width, height; - wx_image_get_size(img, &width, &height); + void *img = wx_image_load(f); + if (!img) + return 0; + int width, height; + wx_image_get_size(img, &width, &height); - if (width != next_pow2(width) || height != next_pow2(height)) - wx_image_rescale(img, next_pow2(width), next_pow2(height)); + if (width != next_pow2(width) || height != next_pow2(height)) + wx_image_rescale(img, next_pow2(width), next_pow2(height)); - wx_image_get_size(img, &width, &height); + wx_image_get_size(img, &width, &height); - GLubyte *rgb = wx_image_get_data(img); - GLubyte *alpha = wx_image_get_alpha(img); + GLubyte *rgb = wx_image_get_data(img); + GLubyte *alpha = wx_image_get_alpha(img); - int bpp = alpha ? 4 : 3; + int bpp = alpha ? 4 : 3; - GLubyte *data = malloc(width * height * bpp); + GLubyte *data = malloc(width * height * bpp); - int x, y, Y; - for (y = 0; y < height; ++y) { - Y = height - y - 1; - for (x = 0; x < width; x++) { - data[(y * width + x) * bpp + 0] = rgb[(Y * width + x) * 3 + 0]; - data[(y * width + x) * bpp + 1] = rgb[(Y * width + x) * 3 + 1]; - data[(y * width + x) * bpp + 2] = rgb[(Y * width + x) * 3 + 2]; + int x, y, Y; + for (y = 0; y < height; ++y) { + Y = height - y - 1; + for (x = 0; x < width; x++) { + data[(y * width + x) * bpp + 0] = rgb[(Y * width + x) * 3 + 0]; + data[(y * width + x) * bpp + 1] = rgb[(Y * width + x) * 3 + 1]; + data[(y * width + x) * bpp + 2] = rgb[(Y * width + x) * 3 + 2]; - if (alpha) - data[(y * width + x) * bpp + 3] = alpha[Y * width + x]; - } - } - wx_image_free(img); + if (alpha) + data[(y * width + x) * bpp + 3] = alpha[Y * width + x]; + } + } + wx_image_free(img); - tex->width = width; - tex->height = height; - tex->internal_format = alpha ? GL_RGBA8 : GL_RGB8; - tex->format = alpha ? GL_RGBA : GL_RGB; - tex->type = GL_UNSIGNED_BYTE; - tex->data = data; - return 1; + tex->width = width; + tex->height = height; + tex->internal_format = alpha ? GL_RGBA8 : GL_RGB8; + tex->format = alpha ? GL_RGBA : GL_RGB; + tex->type = GL_UNSIGNED_BYTE; + tex->data = data; + return 1; } static glsl_t *load_glslp(glsl_t *glsl, int num_shader, const char *f) { - int i, j; - glslp_t *p = glslp_parse(f); + int i, j; + glslp_t *p = glslp_parse(f); - if (p) { - char path[512]; - char file[1024]; - int failed = 0; - strcpy(path, f); - char *filename = get_filename(path); + if (p) { + char path[512]; + char file[1024]; + int failed = 0; + strcpy(path, f); + char *filename = get_filename(path); - struct glsl_shader *gshader = &glsl->shaders[num_shader]; + struct glsl_shader *gshader = &glsl->shaders[num_shader]; - strcpy(gshader->name, p->name); - *filename = 0; + strcpy(gshader->name, p->name); + *filename = 0; - gshader->num_lut_textures = p->num_textures; + gshader->num_lut_textures = p->num_textures; - for (i = 0; i < p->num_textures; ++i) { - struct texture *texture = &p->textures[i]; + for (i = 0; i < p->num_textures; ++i) { + struct texture *texture = &p->textures[i]; - sprintf(file, "%s%s", path, texture->path); + sprintf(file, "%s%s", path, texture->path); - struct shader_lut_texture *tex = &gshader->lut_textures[i]; - strcpy(tex->name, texture->name); + struct shader_lut_texture *tex = &gshader->lut_textures[i]; + strcpy(tex->name, texture->name); - pclog("Load texture %s...\n", file); + pclog("Load texture %s...\n", file); - if (!load_texture(file, &tex->texture)) { - wx_simple_messagebox("GLSL Error", "Could not load texture: %s", file); - pclog("Could not load texture %s!\n", file); - failed = 1; - break; - } + if (!load_texture(file, &tex->texture)) { + wx_simple_messagebox("GLSL Error", "Could not load texture: %s", file); + pclog("Could not load texture %s!\n", file); + failed = 1; + break; + } - if (!strcmp(texture->wrap_mode, "repeat")) - tex->texture.wrap_mode = GL_REPEAT; - else if (!strcmp(texture->wrap_mode, "mirrored_repeat")) - tex->texture.wrap_mode = GL_MIRRORED_REPEAT; - else if (!strcmp(texture->wrap_mode, "clamp_to_edge")) - tex->texture.wrap_mode = GL_CLAMP_TO_EDGE; - else - tex->texture.wrap_mode = GL_CLAMP_TO_BORDER; + if (!strcmp(texture->wrap_mode, "repeat")) + tex->texture.wrap_mode = GL_REPEAT; + else if (!strcmp(texture->wrap_mode, "mirrored_repeat")) + tex->texture.wrap_mode = GL_MIRRORED_REPEAT; + else if (!strcmp(texture->wrap_mode, "clamp_to_edge")) + tex->texture.wrap_mode = GL_CLAMP_TO_EDGE; + else + tex->texture.wrap_mode = GL_CLAMP_TO_BORDER; - tex->texture.mipmap = texture->mipmap; + tex->texture.mipmap = texture->mipmap; - tex->texture.min_filter = tex->texture.mag_filter = texture->linear ? GL_LINEAR : GL_NEAREST; - if (tex->texture.mipmap) - tex->texture.min_filter = texture->linear ? GL_LINEAR_MIPMAP_LINEAR : GL_NEAREST_MIPMAP_NEAREST; + tex->texture.min_filter = tex->texture.mag_filter = texture->linear ? GL_LINEAR : GL_NEAREST; + if (tex->texture.mipmap) + tex->texture.min_filter = texture->linear ? GL_LINEAR_MIPMAP_LINEAR : GL_NEAREST_MIPMAP_NEAREST; - create_texture(&tex->texture); - free(tex->texture.data); - tex->texture.data = 0; - } + create_texture(&tex->texture); + free(tex->texture.data); + tex->texture.data = 0; + } - if (!failed) { - gshader->input_filter_linear = p->input_filter_linear; + if (!failed) { + gshader->input_filter_linear = p->input_filter_linear; - gshader->num_parameters = p->num_parameters; - for (j = 0; j < gshader->num_parameters; ++j) - memcpy(&gshader->parameters[j], &p->parameters[j], sizeof(struct shader_parameter)); + gshader->num_parameters = p->num_parameters; + for (j = 0; j < gshader->num_parameters; ++j) + memcpy(&gshader->parameters[j], &p->parameters[j], sizeof(struct shader_parameter)); - gshader->num_passes = p->num_shaders; + gshader->num_passes = p->num_shaders; - for (i = 0; i < p->num_shaders; ++i) { - struct shader *shader = &p->shaders[i]; - struct shader_pass *pass = &gshader->passes[i]; + for (i = 0; i < p->num_shaders; ++i) { + struct shader *shader = &p->shaders[i]; + struct shader_pass *pass = &gshader->passes[i]; - strcpy(pass->alias, shader->alias); - if (!strlen(pass->alias)) - sprintf(pass->alias, "Pass %u", (i + 1)); + strcpy(pass->alias, shader->alias); + if (!strlen(pass->alias)) + sprintf(pass->alias, "Pass %u", (i + 1)); - pclog("Creating pass %u (%s)\n", (i + 1), pass->alias); - pclog("Loading shader %s...\n", shader->shader_fn); - if (!shader->shader_program) { - wx_simple_messagebox("GLSL Error", "Could not load shader: %s", shader->shader_fn); - pclog("Could not load shader %s\n", shader->shader_fn); - failed = 1; - break; - } else - pclog("Shader %s loaded\n", shader->shader_fn); - failed = - !compile_shader(GL_VERTEX_SHADER, "#define VERTEX\n#define PARAMETER_UNIFORM\n", shader->shader_program, &pass->program.vertex_shader) || - !compile_shader(GL_FRAGMENT_SHADER, "#define FRAGMENT\n#define PARAMETER_UNIFORM\n", shader->shader_program, &pass->program.fragment_shader); - if (failed) - break; + pclog("Creating pass %u (%s)\n", (i + 1), pass->alias); + pclog("Loading shader %s...\n", shader->shader_fn); + if (!shader->shader_program) { + wx_simple_messagebox("GLSL Error", "Could not load shader: %s", shader->shader_fn); + pclog("Could not load shader %s\n", shader->shader_fn); + failed = 1; + break; + } else + pclog("Shader %s loaded\n", shader->shader_fn); + failed = !compile_shader(GL_VERTEX_SHADER, "#define VERTEX\n#define PARAMETER_UNIFORM\n", + shader->shader_program, &pass->program.vertex_shader) || + !compile_shader(GL_FRAGMENT_SHADER, "#define FRAGMENT\n#define PARAMETER_UNIFORM\n", + shader->shader_program, &pass->program.fragment_shader); + if (failed) + break; - if (!create_program(&pass->program)) { - failed = 1; - break; - } - pass->frame_count_mod = shader->frame_count_mod; - pass->fbo.mipmap_input = shader->mipmap_input; + if (!create_program(&pass->program)) { + failed = 1; + break; + } + pass->frame_count_mod = shader->frame_count_mod; + pass->fbo.mipmap_input = shader->mipmap_input; - glw->glGenVertexArrays(1, (GLuint *)&pass->vertex_array); - find_uniforms(gshader, i); - setup_scale(shader, pass); - if (i == p->num_shaders - 1) /* last pass may or may not be an fbo depending on scale */ - { - if (num_shader == glsl->num_shaders - 1) { - pass->fbo.id = -1; + glw->glGenVertexArrays(1, (GLuint *)&pass->vertex_array); + find_uniforms(gshader, i); + setup_scale(shader, pass); + if (i == p->num_shaders - 1) /* last pass may or may not be an fbo depending on scale */ + { + if (num_shader == glsl->num_shaders - 1) { + pass->fbo.id = -1; - for (j = 0; j < 2; ++j) { - if (pass->scale.mode[j] != SCALE_SOURCE || pass->scale.value[j] != 1) { - setup_fbo(shader, &pass->fbo); - break; - } - } - } else { - /* check if next shaders' first pass wants the input mipmapped (will this ever happen?) */ - pass->fbo.texture.mipmap = glsl->shaders[num_shader + 1].num_passes > 0 && glsl->shaders[num_shader + 1].passes[0].fbo.mipmap_input; - /* check if next shader wants the output of this pass to be filtered */ - if (glsl->shaders[num_shader + 1].num_passes > 0 && glsl->shaders[num_shader + 1].input_filter_linear >= 0) - shader->filter_linear = glsl->shaders[num_shader + 1].input_filter_linear; - setup_fbo(shader, &pass->fbo); - } - } else { - /* check if next pass wants the input mipmapped, if so we need to generate mipmaps of this pass */ - pass->fbo.texture.mipmap = (i + 1) < p->num_shaders && p->shaders[i + 1].mipmap_input; - setup_fbo(shader, &pass->fbo); - } - if (pass->fbo.srgb) - glsl->srgb = 1; - pass->active = 1; - } - if (!failed) { - if (gshader->has_prev) { - struct shader scene_shader_conf; - memset(&scene_shader_conf, 0, sizeof(struct shader)); - for (i = 0; i < MAX_PREV; ++i) { - setup_fbo(&scene_shader_conf, &gshader->prev[i].fbo); - } + for (j = 0; j < 2; ++j) { + if (pass->scale.mode[j] != SCALE_SOURCE || pass->scale.value[j] != 1) { + setup_fbo(shader, &pass->fbo); + break; + } + } + } else { + /* check if next shaders' first pass wants the input mipmapped (will this ever + * happen?) */ + pass->fbo.texture.mipmap = + glsl->shaders[num_shader + 1].num_passes > 0 && + glsl->shaders[num_shader + 1].passes[0].fbo.mipmap_input; + /* check if next shader wants the output of this pass to be filtered */ + if (glsl->shaders[num_shader + 1].num_passes > 0 && + glsl->shaders[num_shader + 1].input_filter_linear >= 0) + shader->filter_linear = glsl->shaders[num_shader + 1].input_filter_linear; + setup_fbo(shader, &pass->fbo); + } + } else { + /* check if next pass wants the input mipmapped, if so we need to generate mipmaps of this + * pass */ + pass->fbo.texture.mipmap = (i + 1) < p->num_shaders && p->shaders[i + 1].mipmap_input; + setup_fbo(shader, &pass->fbo); + } + if (pass->fbo.srgb) + glsl->srgb = 1; + pass->active = 1; + } + if (!failed) { + if (gshader->has_prev) { + struct shader scene_shader_conf; + memset(&scene_shader_conf, 0, sizeof(struct shader)); + for (i = 0; i < MAX_PREV; ++i) { + setup_fbo(&scene_shader_conf, &gshader->prev[i].fbo); + } + } + } + } - } - } - } + glslp_free(p); - glslp_free(p); - - return glsl; - } - return 0; + return glsl; + } + return 0; } static glsl_t *load_shaders(int num, char shaders[MAX_USER_SHADERS][512]) { - int i; - glsl_t *glsl; + int i; + glsl_t *glsl; - glsl = malloc(sizeof(glsl_t)); - memset(glsl, 0, sizeof(glsl_t)); + glsl = malloc(sizeof(glsl_t)); + memset(glsl, 0, sizeof(glsl_t)); - glsl->num_shaders = num; - int failed = 0; - for (i = num - 1; i >= 0; --i) { - const char *f = shaders[i]; - if (f && strlen(f)) { - if (!load_glslp(glsl, i, f)) { - failed = 1; - break; - } - } - - } - if (failed) { - delete_glsl(glsl); - memset(glsl, 0, sizeof(glsl_t)); - } - return glsl; + glsl->num_shaders = num; + int failed = 0; + for (i = num - 1; i >= 0; --i) { + const char *f = shaders[i]; + if (f && strlen(f)) { + if (!load_glslp(glsl, i, f)) { + failed = 1; + break; + } + } + } + if (failed) { + delete_glsl(glsl); + memset(glsl, 0, sizeof(glsl_t)); + } + return glsl; } static void read_shader_config() { - char s[512]; - int i, j; - for (i = 0; i < active_shader->num_shaders; ++i) { - struct glsl_shader *shader = &active_shader->shaders[i]; - char *name = shader->name; - sprintf(s, "GL3 Shaders - %s", name); -// shader->shader_refresh_rate = config_get_float(CFG_MACHINE, s, "shader_refresh_rate", -1); - for (j = 0; j < shader->num_parameters; ++j) { - struct shader_parameter *param = &shader->parameters[j]; - param->value = config_get_float(CFG_MACHINE, s, param->id, param->default_value); - } - } + char s[512]; + int i, j; + for (i = 0; i < active_shader->num_shaders; ++i) { + struct glsl_shader *shader = &active_shader->shaders[i]; + char *name = shader->name; + sprintf(s, "GL3 Shaders - %s", name); + // shader->shader_refresh_rate = config_get_float(CFG_MACHINE, s, "shader_refresh_rate", -1); + for (j = 0; j < shader->num_parameters; ++j) { + struct shader_parameter *param = &shader->parameters[j]; + param->value = config_get_float(CFG_MACHINE, s, param->id, param->default_value); + } + } } int gl3_init(SDL_Window *window, sdl_render_driver requested_render_driver, SDL_Rect screen) { - int i, j; + int i, j; - strcpy(current_render_driver_name, requested_render_driver.name); + strcpy(current_render_driver_name, requested_render_driver.name); - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); #ifdef __APPLE__ - // without an explicit request for the core profile 3.0 macOS falls back to default ancient 2.1 - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); + // without an explicit request for the core profile 3.0 macOS falls back to default ancient 2.1 + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); #endif - context = SDL_GL_CreateContext(window); + context = SDL_GL_CreateContext(window); - if (!context) { - pclog("Could not create GL context.\n"); - return FALSE; - } + if (!context) { + pclog("Could not create GL context.\n"); + return FALSE; + } - SDL_GL_SetSwapInterval(video_vsync ? 1 : 0); + SDL_GL_SetSwapInterval(video_vsync ? 1 : 0); - pclog("OpenGL information: [%s] %s (%s)\n", glGetString(GL_VENDOR), glGetString(GL_RENDERER), glGetString(GL_VERSION)); - glsl_version[0] = glsl_version[1] = -1; - glGetIntegerv(GL_MAJOR_VERSION, &glsl_version[0]); - glGetIntegerv(GL_MINOR_VERSION, &glsl_version[1]); - if (glsl_version[0] < 3) { - pclog("OpenGL 3.0 is not available."); - return SDL_FALSE; - } - pclog("Using OpenGL %s\n", glGetString(GL_VERSION)); - pclog("Using Shading Language %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION)); + pclog("OpenGL information: [%s] %s (%s)\n", glGetString(GL_VENDOR), glGetString(GL_RENDERER), glGetString(GL_VERSION)); + glsl_version[0] = glsl_version[1] = -1; + glGetIntegerv(GL_MAJOR_VERSION, &glsl_version[0]); + glGetIntegerv(GL_MINOR_VERSION, &glsl_version[1]); + if (glsl_version[0] < 3) { + pclog("OpenGL 3.0 is not available."); + return SDL_FALSE; + } + pclog("Using OpenGL %s\n", glGetString(GL_VERSION)); + pclog("Using Shading Language %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION)); - glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size); - pclog("Max texture size: %dx%d\n", max_texture_size, max_texture_size); + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size); + pclog("Max texture size: %dx%d\n", max_texture_size, max_texture_size); - //SDL_GL_MakeCurrent(window, context); + // SDL_GL_MakeCurrent(window, context); - glw = glw_init(); + glw = glw_init(); - glEnable(GL_TEXTURE_2D); + glEnable(GL_TEXTURE_2D); - scene_texture.data = NULL; - scene_texture.width = screen.w; - scene_texture.height = screen.h; - scene_texture.internal_format = GL_RGBA8; - scene_texture.format = GL_RGBA; - scene_texture.type = GL_UNSIGNED_INT_8_8_8_8_REV; - scene_texture.wrap_mode = GL_CLAMP_TO_BORDER; - scene_texture.min_filter = scene_texture.mag_filter = video_scale_mode ? GL_LINEAR : GL_NEAREST; - scene_texture.mipmap = 0; + scene_texture.data = NULL; + scene_texture.width = screen.w; + scene_texture.height = screen.h; + scene_texture.internal_format = GL_RGBA8; + scene_texture.format = GL_RGBA; + scene_texture.type = GL_UNSIGNED_INT_8_8_8_8_REV; + scene_texture.wrap_mode = GL_CLAMP_TO_BORDER; + scene_texture.min_filter = scene_texture.mag_filter = video_scale_mode ? GL_LINEAR : GL_NEAREST; + scene_texture.mipmap = 0; - create_texture(&scene_texture); + create_texture(&scene_texture); - /* load shader */ -// const char* shaders[1]; -// shaders[0] = gl3_shader_file; -// -// active_shader = load_shaders(1, shaders); + /* load shader */ + // const char* shaders[1]; + // shaders[0] = gl3_shader_file; + // + // active_shader = load_shaders(1, shaders); -// const char* shaders[3]; -// shaders[0] = "/home/phantasy/git/glsl-shaders/ntsc/ntsc-320px.glslp"; -// shaders[1] = "/home/phantasy/git/glsl-shaders/motionblur/motionblur-simple.glslp"; -// shaders[2] = "/home/phantasy/git/glsl-shaders/crt/crt-lottes-multipass.glslp"; -// -// active_shader = load_shaders(3, shaders); - int num_shaders = 0; - for (i = 0; i < MAX_USER_SHADERS; ++i) { - if (strlen(gl3_shader_file[i])) - ++num_shaders; - else - break; - } - active_shader = load_shaders(num_shaders, gl3_shader_file); + // const char* shaders[3]; + // shaders[0] = "/home/phantasy/git/glsl-shaders/ntsc/ntsc-320px.glslp"; + // shaders[1] = "/home/phantasy/git/glsl-shaders/motionblur/motionblur-simple.glslp"; + // shaders[2] = "/home/phantasy/git/glsl-shaders/crt/crt-lottes-multipass.glslp"; + // + // active_shader = load_shaders(3, shaders); + int num_shaders = 0; + for (i = 0; i < MAX_USER_SHADERS; ++i) { + if (strlen(gl3_shader_file[i])) + ++num_shaders; + else + break; + } + active_shader = load_shaders(num_shaders, gl3_shader_file); - create_scene_shader(); + create_scene_shader(); - /* read config */ - read_shader_config(); + /* read config */ + read_shader_config(); - /* buffers */ + /* buffers */ - GLfloat vertex[] = { - -1.0f, -1.0f, - -1.0f, 1.0f, - 1.0f, -1.0f, - 1.0f, 1.0f - }; + GLfloat vertex[] = {-1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f}; - GLfloat inv_vertex[] = { - -1.0f, 1.0f, - -1.0f, -1.0f, - 1.0f, 1.0f, - 1.0f, -1.0f - }; + GLfloat inv_vertex[] = {-1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, -1.0f}; - GLfloat tex_coords[] = { - 0.0f, 0.0f, - 0.0f, 1.0f, - 1.0f, 0.0f, - 1.0f, 1.0f - }; + GLfloat tex_coords[] = {0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f}; - GLfloat colors[] = { - 1.0f, 1.0f, 1.0f, 1.0f, - 1.0f, 1.0f, 1.0f, 1.0f, - 1.0f, 1.0f, 1.0f, 1.0f, - 1.0f, 1.0f, 1.0f, 1.0f - }; + GLfloat colors[] = {1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f}; + /* set the scene shader buffers */ + { + glw->glBindVertexArray(active_shader->scene.vertex_array); - /* set the scene shader buffers */ - { - glw->glBindVertexArray(active_shader->scene.vertex_array); + struct shader_vbo *vbo = &active_shader->scene.vbo; - struct shader_vbo *vbo = &active_shader->scene.vbo; + glw->glGenBuffers(1, (GLuint *)&vbo->vertex_coord); + glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->vertex_coord); + glw->glBufferData(GL_ARRAY_BUFFER, sizeof(inv_vertex), inv_vertex, GL_STATIC_DRAW); + glw->glVertexAttribPointer(active_shader->scene.uniforms.vertex_coord, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), + (GLvoid *)0); - glw->glGenBuffers(1, (GLuint *)&vbo->vertex_coord); - glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->vertex_coord); - glw->glBufferData(GL_ARRAY_BUFFER, sizeof(inv_vertex), inv_vertex, GL_STATIC_DRAW); - glw->glVertexAttribPointer(active_shader->scene.uniforms.vertex_coord, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), (GLvoid *)0); + glw->glGenBuffers(1, (GLuint *)&vbo->tex_coord); + glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->tex_coord); + glw->glBufferData(GL_ARRAY_BUFFER, sizeof(tex_coords), tex_coords, GL_DYNAMIC_DRAW); + glw->glVertexAttribPointer(active_shader->scene.uniforms.tex_coord, 2, GL_FLOAT, GL_TRUE, 2 * sizeof(GLfloat), + (GLvoid *)0); + } - glw->glGenBuffers(1, (GLuint *)&vbo->tex_coord); - glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->tex_coord); - glw->glBufferData(GL_ARRAY_BUFFER, sizeof(tex_coords), tex_coords, GL_DYNAMIC_DRAW); - glw->glVertexAttribPointer(active_shader->scene.uniforms.tex_coord, 2, GL_FLOAT, GL_TRUE, 2 * sizeof(GLfloat), (GLvoid *)0); - } + /* set buffers for all passes */ + for (j = 0; j < active_shader->num_shaders; ++j) { + struct glsl_shader *shader = &active_shader->shaders[j]; + for (i = 0; i < shader->num_passes; ++i) { + struct shader_uniforms *u = &shader->passes[i].uniforms; - /* set buffers for all passes */ - for (j = 0; j < active_shader->num_shaders; ++j) { - struct glsl_shader *shader = &active_shader->shaders[j]; - for (i = 0; i < shader->num_passes; ++i) { - struct shader_uniforms *u = &shader->passes[i].uniforms; + glw->glBindVertexArray(shader->passes[i].vertex_array); - glw->glBindVertexArray(shader->passes[i].vertex_array); + struct shader_vbo *vbo = &shader->passes[i].vbo; - struct shader_vbo *vbo = &shader->passes[i].vbo; + glw->glGenBuffers(1, (GLuint *)&vbo->vertex_coord); + glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->vertex_coord); + glw->glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW); - glw->glGenBuffers(1, (GLuint *)&vbo->vertex_coord); - glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->vertex_coord); - glw->glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW); + glw->glVertexAttribPointer(u->vertex_coord, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), (GLvoid *)0); - glw->glVertexAttribPointer(u->vertex_coord, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), (GLvoid *)0); + glw->glGenBuffers(1, (GLuint *)&vbo->tex_coord); + glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->tex_coord); + glw->glBufferData(GL_ARRAY_BUFFER, sizeof(tex_coords), tex_coords, GL_DYNAMIC_DRAW); + glw->glVertexAttribPointer(u->tex_coord, 2, GL_FLOAT, GL_TRUE, 2 * sizeof(GLfloat), (GLvoid *)0); - glw->glGenBuffers(1, (GLuint *)&vbo->tex_coord); - glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->tex_coord); - glw->glBufferData(GL_ARRAY_BUFFER, sizeof(tex_coords), tex_coords, GL_DYNAMIC_DRAW); - glw->glVertexAttribPointer(u->tex_coord, 2, GL_FLOAT, GL_TRUE, 2 * sizeof(GLfloat), (GLvoid *)0); + if (u->color) { + glw->glGenBuffers(1, (GLuint *)&vbo->color); + glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->color); + glw->glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW); + glw->glVertexAttribPointer(u->color, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (GLvoid *)0); + } + } + } - if (u->color) { - glw->glGenBuffers(1, (GLuint *)&vbo->color); - glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->color); - glw->glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW); - glw->glVertexAttribPointer(u->color, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (GLvoid *)0); - } - } - } + for (i = 0; i < active_shader->num_shaders; ++i) { + struct glsl_shader *shader = &active_shader->shaders[i]; + if (shader->has_prev) { + struct shader_pass *prev_pass = &shader->prev_scene; + create_default_shader_tex(prev_pass); - for (i = 0; i < active_shader->num_shaders; ++i) { - struct glsl_shader *shader = &active_shader->shaders[i]; - if (shader->has_prev) { - struct shader_pass *prev_pass = &shader->prev_scene; - create_default_shader_tex(prev_pass); + struct shader_vbo *vbo = &prev_pass->vbo; - struct shader_vbo *vbo = &prev_pass->vbo; + glw->glBindVertexArray(prev_pass->vertex_array); - glw->glBindVertexArray(prev_pass->vertex_array); + glw->glGenBuffers(1, (GLuint *)&vbo->vertex_coord); + glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->vertex_coord); + glw->glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW); + glw->glVertexAttribPointer(prev_pass->uniforms.vertex_coord, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), + (GLvoid *)0); - glw->glGenBuffers(1, (GLuint *)&vbo->vertex_coord); - glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->vertex_coord); - glw->glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW); - glw->glVertexAttribPointer(prev_pass->uniforms.vertex_coord, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), (GLvoid *)0); + glw->glGenBuffers(1, (GLuint *)&vbo->tex_coord); + glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->tex_coord); + glw->glBufferData(GL_ARRAY_BUFFER, sizeof(tex_coords), tex_coords, GL_DYNAMIC_DRAW); + glw->glVertexAttribPointer(prev_pass->uniforms.tex_coord, 2, GL_FLOAT, GL_TRUE, 2 * sizeof(GLfloat), + (GLvoid *)0); - glw->glGenBuffers(1, (GLuint *)&vbo->tex_coord); - glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->tex_coord); - glw->glBufferData(GL_ARRAY_BUFFER, sizeof(tex_coords), tex_coords, GL_DYNAMIC_DRAW); - glw->glVertexAttribPointer(prev_pass->uniforms.tex_coord, 2, GL_FLOAT, GL_TRUE, 2 * sizeof(GLfloat), (GLvoid *)0); + for (j = 0; j < MAX_PREV; ++j) { + struct shader_prev *prev = &shader->prev[j]; + struct shader_vbo *prev_vbo = &prev->vbo; - for (j = 0; j < MAX_PREV; ++j) { - struct shader_prev *prev = &shader->prev[j]; - struct shader_vbo *prev_vbo = &prev->vbo; + glw->glGenBuffers(1, (GLuint *)&prev_vbo->vertex_coord); + glw->glBindBuffer(GL_ARRAY_BUFFER, prev_vbo->vertex_coord); + glw->glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW); - glw->glGenBuffers(1, (GLuint *)&prev_vbo->vertex_coord); - glw->glBindBuffer(GL_ARRAY_BUFFER, prev_vbo->vertex_coord); - glw->glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW); + glw->glGenBuffers(1, (GLuint *)&prev_vbo->tex_coord); + glw->glBindBuffer(GL_ARRAY_BUFFER, prev_vbo->tex_coord); + glw->glBufferData(GL_ARRAY_BUFFER, sizeof(tex_coords), tex_coords, GL_DYNAMIC_DRAW); + } + } + } - glw->glGenBuffers(1, (GLuint *)&prev_vbo->tex_coord); - glw->glBindBuffer(GL_ARRAY_BUFFER, prev_vbo->tex_coord); - glw->glBufferData(GL_ARRAY_BUFFER, sizeof(tex_coords), tex_coords, GL_DYNAMIC_DRAW); - } - } - } + /* create final pass */ + if (active_shader->num_shaders == 0 || + active_shader->shaders[active_shader->num_shaders - 1] + .passes[active_shader->shaders[active_shader->num_shaders - 1].num_passes - 1] + .fbo.id >= 0) { + struct shader_pass *final_pass = &active_shader->final_pass; + create_default_shader_tex(final_pass); - /* create final pass */ - if (active_shader->num_shaders == 0 || active_shader->shaders[active_shader->num_shaders - 1].passes[active_shader->shaders[active_shader->num_shaders - 1].num_passes - 1].fbo.id >= 0) { - struct shader_pass *final_pass = &active_shader->final_pass; - create_default_shader_tex(final_pass); + glw->glBindVertexArray(final_pass->vertex_array); - glw->glBindVertexArray(final_pass->vertex_array); + struct shader_vbo *vbo = &final_pass->vbo; - struct shader_vbo *vbo = &final_pass->vbo; + glw->glGenBuffers(1, (GLuint *)&vbo->vertex_coord); + glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->vertex_coord); + glw->glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW); + glw->glVertexAttribPointer(final_pass->uniforms.vertex_coord, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), + (GLvoid *)0); - glw->glGenBuffers(1, (GLuint *)&vbo->vertex_coord); - glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->vertex_coord); - glw->glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW); - glw->glVertexAttribPointer(final_pass->uniforms.vertex_coord, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), (GLvoid *)0); + glw->glGenBuffers(1, (GLuint *)&vbo->tex_coord); + glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->tex_coord); + glw->glBufferData(GL_ARRAY_BUFFER, sizeof(tex_coords), tex_coords, GL_DYNAMIC_DRAW); + glw->glVertexAttribPointer(final_pass->uniforms.tex_coord, 2, GL_FLOAT, GL_TRUE, 2 * sizeof(GLfloat), + (GLvoid *)0); + } - glw->glGenBuffers(1, (GLuint *)&vbo->tex_coord); - glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->tex_coord); - glw->glBufferData(GL_ARRAY_BUFFER, sizeof(tex_coords), tex_coords, GL_DYNAMIC_DRAW); - glw->glVertexAttribPointer(final_pass->uniforms.tex_coord, 2, GL_FLOAT, GL_TRUE, 2 * sizeof(GLfloat), (GLvoid *)0); - } + { + struct shader_pass *color_pass = &active_shader->fs_color; + create_default_shader_color(color_pass); - { - struct shader_pass *color_pass = &active_shader->fs_color; - create_default_shader_color(color_pass); + glw->glBindVertexArray(color_pass->vertex_array); - glw->glBindVertexArray(color_pass->vertex_array); + struct shader_vbo *vbo = &color_pass->vbo; - struct shader_vbo *vbo = &color_pass->vbo; + glw->glGenBuffers(1, (GLuint *)&vbo->vertex_coord); + glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->vertex_coord); + glw->glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW); + glw->glVertexAttribPointer(color_pass->uniforms.vertex_coord, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), + (GLvoid *)0); - glw->glGenBuffers(1, (GLuint *)&vbo->vertex_coord); - glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->vertex_coord); - glw->glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW); - glw->glVertexAttribPointer(color_pass->uniforms.vertex_coord, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), (GLvoid *)0); - - glw->glGenBuffers(1, (GLuint *)&vbo->color); - glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->color); - glw->glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_DYNAMIC_DRAW); - glw->glVertexAttribPointer(color_pass->uniforms.color, 4, GL_FLOAT, GL_TRUE, 4 * sizeof(GLfloat), (GLvoid *)0); - - } + glw->glGenBuffers(1, (GLuint *)&vbo->color); + glw->glBindBuffer(GL_ARRAY_BUFFER, vbo->color); + glw->glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_DYNAMIC_DRAW); + glw->glVertexAttribPointer(color_pass->uniforms.color, 4, GL_FLOAT, GL_TRUE, 4 * sizeof(GLfloat), (GLvoid *)0); + } #ifdef SDL2_SHADER_DEBUG - struct shader_pass* debug_pass = &active_shader->debug; - create_default_shader(debug_pass); + struct shader_pass *debug_pass = &active_shader->debug; + create_default_shader(debug_pass); - glBindVertexArray(debug_pass->vertex_array); + glBindVertexArray(debug_pass->vertex_array); - struct shader_vbo* vbo = &debug_pass->vbo; + struct shader_vbo *vbo = &debug_pass->vbo; - glGenBuffers(1, &vbo->vertex_coord); - glBindBuffer(GL_ARRAY_BUFFER, vbo->vertex_coord); - glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW); - glVertexAttribPointer(debug_pass->uniforms.vertex_coord, 2, GL_FLOAT, GL_FALSE, 2*sizeof(GLfloat), (GLvoid*)0); + glGenBuffers(1, &vbo->vertex_coord); + glBindBuffer(GL_ARRAY_BUFFER, vbo->vertex_coord); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW); + glVertexAttribPointer(debug_pass->uniforms.vertex_coord, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), (GLvoid *)0); - glGenBuffers(1, &vbo->tex_coord); - glBindBuffer(GL_ARRAY_BUFFER, vbo->tex_coord); - glBufferData(GL_ARRAY_BUFFER, sizeof(tex_coords), tex_coords, GL_DYNAMIC_DRAW); - glVertexAttribPointer(debug_pass->uniforms.tex_coord, 2, GL_FLOAT, GL_TRUE, 2*sizeof(GLfloat), (GLvoid*)0); + glGenBuffers(1, &vbo->tex_coord); + glBindBuffer(GL_ARRAY_BUFFER, vbo->tex_coord); + glBufferData(GL_ARRAY_BUFFER, sizeof(tex_coords), tex_coords, GL_DYNAMIC_DRAW); + glVertexAttribPointer(debug_pass->uniforms.tex_coord, 2, GL_FLOAT, GL_TRUE, 2 * sizeof(GLfloat), (GLvoid *)0); #endif - glw->glBindBuffer(GL_ARRAY_BUFFER, 0); - glw->glBindVertexArray(0); + glw->glBindBuffer(GL_ARRAY_BUFFER, 0); + glw->glBindVertexArray(0); - return SDL_TRUE; + return SDL_TRUE; } void gl3_close() { - if (context) { - delete_texture(&scene_texture); + if (context) { + delete_texture(&scene_texture); - if (active_shader) { - delete_glsl(active_shader); - free(active_shader); - } - active_shader = NULL; + if (active_shader) { + delete_glsl(active_shader); + free(active_shader); + } + active_shader = NULL; - SDL_GL_DeleteContext(context); - context = NULL; - } - glw_free(glw); + SDL_GL_DeleteContext(context); + context = NULL; + } + glw_free(glw); } void gl3_update(SDL_Window *window, SDL_Rect updated_rect, BITMAP *screen) { - if (!context) - return; - glBindTexture(GL_TEXTURE_2D, scene_texture.id); - glPixelStorei(GL_UNPACK_ROW_LENGTH, screen->w); - glTexSubImage2D(GL_TEXTURE_2D, - 0, - updated_rect.x, - updated_rect.y, - updated_rect.w, - updated_rect.h, - GL_BGRA, - GL_UNSIGNED_INT_8_8_8_8_REV, - &((uint32_t *)screen->dat)[updated_rect.y * screen->w + updated_rect.x]); - glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); - glBindTexture(GL_TEXTURE_2D, 0); + if (!context) + return; + glBindTexture(GL_TEXTURE_2D, scene_texture.id); + glPixelStorei(GL_UNPACK_ROW_LENGTH, screen->w); + glTexSubImage2D(GL_TEXTURE_2D, 0, updated_rect.x, updated_rect.y, updated_rect.w, updated_rect.h, GL_BGRA, + GL_UNSIGNED_INT_8_8_8_8_REV, &((uint32_t *)screen->dat)[updated_rect.y * screen->w + updated_rect.x]); + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + glBindTexture(GL_TEXTURE_2D, 0); } struct render_data { - int pass; - struct glsl_shader *shader; - struct shader_pass *shader_pass; - GLfloat *output_size; - struct shader_pass *orig_pass; - GLint texture; - int frame_count; + int pass; + struct glsl_shader *shader; + struct shader_pass *shader_pass; + GLfloat *output_size; + struct shader_pass *orig_pass; + GLint texture; + int frame_count; }; static void render_pass(struct render_data *data) { - int i; - GLuint texture_unit = 0; + int i; + GLuint texture_unit = 0; -// pclog("pass %d: %gx%g, %gx%g -> %gx%g, %gx%g, %gx%g\n", num_pass, pass->state.input_size[0], pass->state.input_size[1], pass->state.input_texture_size[0], pass->state.input_texture_size[1], pass->state.output_size[0], pass->state.output_size[1], pass->state.output_texture_size[0], pass->state.output_texture_size[1], output_size[0], output_size[1]); + // pclog("pass %d: %gx%g, %gx%g -> %gx%g, %gx%g, %gx%g\n", num_pass, pass->state.input_size[0], + // pass->state.input_size[1], pass->state.input_texture_size[0], pass->state.input_texture_size[1], + // pass->state.output_size[0], pass->state.output_size[1], pass->state.output_texture_size[0], + // pass->state.output_texture_size[1], output_size[0], output_size[1]); - glw->glBindVertexArray(data->shader_pass->vertex_array); + glw->glBindVertexArray(data->shader_pass->vertex_array); - GLint p = data->shader_pass->program.id; - struct shader_uniforms *u = &data->shader_pass->uniforms; + GLint p = data->shader_pass->program.id; + struct shader_uniforms *u = &data->shader_pass->uniforms; - glw->glUseProgram(p); + glw->glUseProgram(p); - if (data->texture) { - glw->glActiveTexture(GL_TEXTURE0 + texture_unit); - glBindTexture(GL_TEXTURE_2D, data->texture); - glw->glUniform1i(u->texture, texture_unit); - texture_unit++; - } + if (data->texture) { + glw->glActiveTexture(GL_TEXTURE0 + texture_unit); + glBindTexture(GL_TEXTURE_2D, data->texture); + glw->glUniform1i(u->texture, texture_unit); + texture_unit++; + } - if (u->color >= 0) - glw->glEnableVertexAttribArray(u->color); + if (u->color >= 0) + glw->glEnableVertexAttribArray(u->color); - if (u->mvp_matrix >= 0) - glw->glUniformMatrix4fv(u->mvp_matrix, 1, 0, matrix); - if (u->frame_direction >= 0) - glw->glUniform1i(u->frame_direction, 1); + if (u->mvp_matrix >= 0) + glw->glUniformMatrix4fv(u->mvp_matrix, 1, 0, matrix); + if (u->frame_direction >= 0) + glw->glUniform1i(u->frame_direction, 1); - int framecnt = data->frame_count; - if (data->shader_pass->frame_count_mod > 0) - framecnt = framecnt % data->shader_pass->frame_count_mod; - if (u->frame_count >= 0) - glw->glUniform1i(u->frame_count, framecnt); + int framecnt = data->frame_count; + if (data->shader_pass->frame_count_mod > 0) + framecnt = framecnt % data->shader_pass->frame_count_mod; + if (u->frame_count >= 0) + glw->glUniform1i(u->frame_count, framecnt); - if (u->input_size >= 0) - glw->glUniform2fv(u->input_size, 1, data->shader_pass->state.input_size); - if (u->texture_size >= 0) - glw->glUniform2fv(u->texture_size, 1, data->shader_pass->state.input_texture_size); - if (u->output_size >= 0) - glw->glUniform2fv(u->output_size, 1, data->output_size); + if (u->input_size >= 0) + glw->glUniform2fv(u->input_size, 1, data->shader_pass->state.input_size); + if (u->texture_size >= 0) + glw->glUniform2fv(u->texture_size, 1, data->shader_pass->state.input_texture_size); + if (u->output_size >= 0) + glw->glUniform2fv(u->output_size, 1, data->output_size); - if (data->shader) { - /* parameters */ - for (i = 0; i < data->shader->num_parameters; ++i) - if (u->parameters[i] >= 0) - glw->glUniform1f(u->parameters[i], data->shader->parameters[i].value); + if (data->shader) { + /* parameters */ + for (i = 0; i < data->shader->num_parameters; ++i) + if (u->parameters[i] >= 0) + glw->glUniform1f(u->parameters[i], data->shader->parameters[i].value); - if (data->pass > 0) { - struct shader_pass *passes = data->shader->passes; - struct shader_pass *orig = data->orig_pass; - if (u->orig.texture >= 0) { - glw->glActiveTexture(GL_TEXTURE0 + texture_unit); - glBindTexture(GL_TEXTURE_2D, orig->fbo.texture.id); - glw->glUniform1i(u->orig.texture, texture_unit); - texture_unit++; - } - if (u->orig.input_size >= 0) - glw->glUniform2fv(u->orig.input_size, 1, orig->state.input_size); - if (u->orig.texture_size >= 0) - glw->glUniform2fv(u->orig.texture_size, 1, orig->state.input_texture_size); + if (data->pass > 0) { + struct shader_pass *passes = data->shader->passes; + struct shader_pass *orig = data->orig_pass; + if (u->orig.texture >= 0) { + glw->glActiveTexture(GL_TEXTURE0 + texture_unit); + glBindTexture(GL_TEXTURE_2D, orig->fbo.texture.id); + glw->glUniform1i(u->orig.texture, texture_unit); + texture_unit++; + } + if (u->orig.input_size >= 0) + glw->glUniform2fv(u->orig.input_size, 1, orig->state.input_size); + if (u->orig.texture_size >= 0) + glw->glUniform2fv(u->orig.texture_size, 1, orig->state.input_texture_size); - for (i = 0; i < data->pass; ++i) { - if (u->pass[i].texture >= 0) { - glw->glActiveTexture(GL_TEXTURE0 + texture_unit); - glBindTexture(GL_TEXTURE_2D, passes[i].fbo.texture.id); - glw->glUniform1i(u->pass[i].texture, texture_unit); - texture_unit++; - } - if (u->pass[i].texture_size >= 0) - glw->glUniform2fv(u->pass[i].texture_size, 1, passes[i].state.input_texture_size); - if (u->pass[i].input_size >= 0) - glw->glUniform2fv(u->pass[i].input_size, 1, passes[i].state.input_size); + for (i = 0; i < data->pass; ++i) { + if (u->pass[i].texture >= 0) { + glw->glActiveTexture(GL_TEXTURE0 + texture_unit); + glBindTexture(GL_TEXTURE_2D, passes[i].fbo.texture.id); + glw->glUniform1i(u->pass[i].texture, texture_unit); + texture_unit++; + } + if (u->pass[i].texture_size >= 0) + glw->glUniform2fv(u->pass[i].texture_size, 1, passes[i].state.input_texture_size); + if (u->pass[i].input_size >= 0) + glw->glUniform2fv(u->pass[i].input_size, 1, passes[i].state.input_size); - if (u->prev_pass[i].texture >= 0) { - glw->glActiveTexture(GL_TEXTURE0 + texture_unit); - glBindTexture(GL_TEXTURE_2D, passes[i].fbo.texture.id); - glw->glUniform1i(u->prev_pass[i].texture, texture_unit); - texture_unit++; - } - if (u->prev_pass[i].texture_size >= 0) - glw->glUniform2fv(u->prev_pass[i].texture_size, 1, passes[i].state.input_texture_size); - if (u->prev_pass[i].input_size >= 0) - glw->glUniform2fv(u->prev_pass[i].input_size, 1, passes[i].state.input_size); + if (u->prev_pass[i].texture >= 0) { + glw->glActiveTexture(GL_TEXTURE0 + texture_unit); + glBindTexture(GL_TEXTURE_2D, passes[i].fbo.texture.id); + glw->glUniform1i(u->prev_pass[i].texture, texture_unit); + texture_unit++; + } + if (u->prev_pass[i].texture_size >= 0) + glw->glUniform2fv(u->prev_pass[i].texture_size, 1, passes[i].state.input_texture_size); + if (u->prev_pass[i].input_size >= 0) + glw->glUniform2fv(u->prev_pass[i].input_size, 1, passes[i].state.input_size); + } + } - } - } + if (data->shader->has_prev) { + /* loop through each previous frame */ + for (i = 0; i < MAX_PREV; ++i) { + if (u->prev[i].texture >= 0) { + glw->glActiveTexture(GL_TEXTURE0 + texture_unit); + glBindTexture(GL_TEXTURE_2D, data->shader->prev[i].fbo.texture.id); + glw->glUniform1i(u->prev[i].texture, texture_unit); + texture_unit++; + } + if (u->prev[i].tex_coord >= 0) { + glw->glBindBuffer(GL_ARRAY_BUFFER, data->shader->prev[i].vbo.tex_coord); + glw->glVertexAttribPointer(u->prev[i].tex_coord, 2, GL_FLOAT, GL_TRUE, + 2 * sizeof(GLfloat), (GLvoid *)0); + glw->glEnableVertexAttribArray(u->prev[i].tex_coord); + glw->glBindBuffer(GL_ARRAY_BUFFER, 0); + } + } + } - if (data->shader->has_prev) { - /* loop through each previous frame */ - for (i = 0; i < MAX_PREV; ++i) { - if (u->prev[i].texture >= 0) { - glw->glActiveTexture(GL_TEXTURE0 + texture_unit); - glBindTexture(GL_TEXTURE_2D, data->shader->prev[i].fbo.texture.id); - glw->glUniform1i(u->prev[i].texture, texture_unit); - texture_unit++; - } - if (u->prev[i].tex_coord >= 0) { - glw->glBindBuffer(GL_ARRAY_BUFFER, data->shader->prev[i].vbo.tex_coord); - glw->glVertexAttribPointer(u->prev[i].tex_coord, 2, GL_FLOAT, GL_TRUE, 2 * sizeof(GLfloat), (GLvoid *)0); - glw->glEnableVertexAttribArray(u->prev[i].tex_coord); - glw->glBindBuffer(GL_ARRAY_BUFFER, 0); - } - } - } + for (i = 0; i < data->shader->num_lut_textures; ++i) { + if (u->lut_textures[i] >= 0) { + glw->glActiveTexture(GL_TEXTURE0 + texture_unit); + glBindTexture(GL_TEXTURE_2D, data->shader->lut_textures[i].texture.id); + glw->glUniform1i(u->lut_textures[i], texture_unit); + texture_unit++; + } + } + } - for (i = 0; i < data->shader->num_lut_textures; ++i) { - if (u->lut_textures[i] >= 0) { - glw->glActiveTexture(GL_TEXTURE0 + texture_unit); - glBindTexture(GL_TEXTURE_2D, data->shader->lut_textures[i].texture.id); - glw->glUniform1i(u->lut_textures[i], texture_unit); - texture_unit++; - } + glw->glEnableVertexAttribArray(u->vertex_coord); + glw->glEnableVertexAttribArray(u->tex_coord); - } - } + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - glw->glEnableVertexAttribArray(u->vertex_coord); - glw->glEnableVertexAttribArray(u->tex_coord); + glw->glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, 0); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + glw->glDisableVertexAttribArray(data->shader_pass->uniforms.vertex_coord); + glw->glDisableVertexAttribArray(data->shader_pass->uniforms.tex_coord); + if (data->shader_pass->uniforms.color >= 0) + glw->glDisableVertexAttribArray(data->shader_pass->uniforms.color); - glw->glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, 0); + if (data->shader && data->shader->has_prev) { + for (i = 0; i < MAX_PREV; ++i) { + if (u->prev[i].tex_coord >= 0) + glw->glDisableVertexAttribArray(u->prev[i].tex_coord); + } + } - glw->glDisableVertexAttribArray(data->shader_pass->uniforms.vertex_coord); - glw->glDisableVertexAttribArray(data->shader_pass->uniforms.tex_coord); - if (data->shader_pass->uniforms.color >= 0) - glw->glDisableVertexAttribArray(data->shader_pass->uniforms.color); + glw->glBindVertexArray(0); - if (data->shader && data->shader->has_prev) { - for (i = 0; i < MAX_PREV; ++i) { - if (u->prev[i].tex_coord >= 0) - glw->glDisableVertexAttribArray(u->prev[i].tex_coord); - - } - } - - glw->glBindVertexArray(0); - - glw->glUseProgram(0); + glw->glUseProgram(0); } void gl3_present(SDL_Window *window, SDL_Rect video_rect, SDL_Rect window_rect, SDL_Rect screen) { - if (!context) - return; + if (!context) + return; - int s, i, j; + int s, i, j; - Uint32 ticks = SDL_GetTicks(); + Uint32 ticks = SDL_GetTicks(); - GLfloat orig_output_size[] = { - window_rect.w, window_rect.h - }; - - if (active_shader->srgb) - glEnable(GL_FRAMEBUFFER_SRGB); - - struct render_data data; - - /* render scene to texture */ - { - struct shader_pass *pass = &active_shader->scene; - - SDL_Rect rect; - rect.x = rect.y = 0; - rect.w = video_rect.w * gl3_input_scale; - rect.h = video_rect.h * gl3_input_scale; - sdl_scale(gl3_input_stretch, rect, &rect, video_rect.w, video_rect.h); + GLfloat orig_output_size[] = {window_rect.w, window_rect.h}; - pass->state.input_size[0] = pass->state.output_size[0] = rect.w; - pass->state.input_size[1] = pass->state.output_size[1] = rect.h; - - pass->state.input_texture_size[0] = pass->state.output_texture_size[0] = next_pow2(pass->state.output_size[0]); - pass->state.input_texture_size[1] = pass->state.output_texture_size[1] = next_pow2(pass->state.output_size[1]); - - recreate_fbo(&active_shader->scene.fbo, pass->state.output_texture_size[0], pass->state.output_texture_size[1]); - - glw->glBindFramebuffer(GL_FRAMEBUFFER, active_shader->scene.fbo.id); - glClearColor(0, 0, 0, 1); - glClear(GL_COLOR_BUFFER_BIT); - - glViewport(0, 0, pass->state.output_size[0], pass->state.output_size[1]); - - GLfloat minx = 0; - GLfloat miny = 0; - GLfloat maxx = pass->state.output_size[0] / (GLfloat)pass->state.output_texture_size[0]; - GLfloat maxy = pass->state.output_size[1] / (GLfloat)pass->state.output_texture_size[1]; - - pass->state.tex_coords[0] = minx; - pass->state.tex_coords[1] = miny; - pass->state.tex_coords[2] = minx; - pass->state.tex_coords[3] = maxy; - pass->state.tex_coords[4] = maxx; - pass->state.tex_coords[5] = miny; - pass->state.tex_coords[6] = maxx; - pass->state.tex_coords[7] = maxy; - - // create input tex coords - minx = video_rect.x / (float)screen.w; - miny = video_rect.y / (float)screen.h; - maxx = (video_rect.x + video_rect.w) / (float)screen.w; - maxy = (video_rect.y + video_rect.h) / (float)screen.h; - - GLfloat tex_coords[] = { - minx, miny, - minx, maxy, - maxx, miny, - maxx, maxy - }; - - glw->glBindVertexArray(pass->vertex_array); - - glw->glBindBuffer(GL_ARRAY_BUFFER, pass->vbo.tex_coord); - glw->glBufferSubData(GL_ARRAY_BUFFER, 0, 8 * sizeof(GLfloat), tex_coords); - glw->glBindBuffer(GL_ARRAY_BUFFER, 0); - - memset(&data, 0, sizeof(struct render_data)); - data.pass = -1; - data.shader_pass = &active_shader->scene; - data.texture = scene_texture.id; - data.output_size = orig_output_size; - render_pass(&data); - - glw->glBindFramebuffer(GL_FRAMEBUFFER, 0); - } + if (active_shader->srgb) + glEnable(GL_FRAMEBUFFER_SRGB); - struct shader_pass *orig = &active_shader->scene; - struct shader_pass *input = &active_shader->scene; + struct render_data data; - for (s = 0; s < active_shader->num_shaders; ++s) { - struct glsl_shader *shader = &active_shader->shaders[s]; + /* render scene to texture */ + { + struct shader_pass *pass = &active_shader->scene; -// float refresh_rate = shader->shader_refresh_rate; -// if (refresh_rate < 0) -// refresh_rate = gl3_shader_refresh_rate; - float refresh_rate = gl3_shader_refresh_rate; - if (refresh_rate == 0) - refresh_rate = video_refresh_rate; - int frame_count = ticks / (1000.0f / refresh_rate); + SDL_Rect rect; + rect.x = rect.y = 0; + rect.w = video_rect.w * gl3_input_scale; + rect.h = video_rect.h * gl3_input_scale; + sdl_scale(gl3_input_stretch, rect, &rect, video_rect.w, video_rect.h); - /* loop through each pass */ - for (i = 0; i < shader->num_passes; ++i) { - struct shader_pass *pass = &shader->passes[i]; + pass->state.input_size[0] = pass->state.output_size[0] = rect.w; + pass->state.input_size[1] = pass->state.output_size[1] = rect.h; - memcpy(pass->state.input_size, input->state.output_size, 2 * sizeof(GLfloat)); - memcpy(pass->state.input_texture_size, input->state.output_texture_size, 2 * sizeof(GLfloat)); + pass->state.input_texture_size[0] = pass->state.output_texture_size[0] = next_pow2(pass->state.output_size[0]); + pass->state.input_texture_size[1] = pass->state.output_texture_size[1] = next_pow2(pass->state.output_size[1]); - for (j = 0; j < 2; ++j) { - if (pass->scale.mode[j] == SCALE_VIEWPORT) - pass->state.output_size[j] = orig_output_size[j] * pass->scale.value[j]; - else if (pass->scale.mode[j] == SCALE_ABSOLUTE) - pass->state.output_size[j] = pass->scale.value[j]; - else - pass->state.output_size[j] = pass->state.input_size[j] * pass->scale.value[j]; + recreate_fbo(&active_shader->scene.fbo, pass->state.output_texture_size[0], pass->state.output_texture_size[1]); + + glw->glBindFramebuffer(GL_FRAMEBUFFER, active_shader->scene.fbo.id); + glClearColor(0, 0, 0, 1); + glClear(GL_COLOR_BUFFER_BIT); - pass->state.output_texture_size[j] = next_pow2(pass->state.output_size[j]); - } + glViewport(0, 0, pass->state.output_size[0], pass->state.output_size[1]); - if (pass->fbo.id >= 0) { - recreate_fbo(&pass->fbo, pass->state.output_texture_size[0], pass->state.output_texture_size[1]); + GLfloat minx = 0; + GLfloat miny = 0; + GLfloat maxx = pass->state.output_size[0] / (GLfloat)pass->state.output_texture_size[0]; + GLfloat maxy = pass->state.output_size[1] / (GLfloat)pass->state.output_texture_size[1]; - glw->glBindFramebuffer(GL_FRAMEBUFFER, pass->fbo.id); - glViewport(0, 0, pass->state.output_size[0], pass->state.output_size[1]); - } else - glViewport(window_rect.x, window_rect.y, window_rect.w, window_rect.h); + pass->state.tex_coords[0] = minx; + pass->state.tex_coords[1] = miny; + pass->state.tex_coords[2] = minx; + pass->state.tex_coords[3] = maxy; + pass->state.tex_coords[4] = maxx; + pass->state.tex_coords[5] = miny; + pass->state.tex_coords[6] = maxx; + pass->state.tex_coords[7] = maxy; - glClearColor(0, 0, 0, 1); - glClear(GL_COLOR_BUFFER_BIT); + // create input tex coords + minx = video_rect.x / (float)screen.w; + miny = video_rect.y / (float)screen.h; + maxx = (video_rect.x + video_rect.w) / (float)screen.w; + maxy = (video_rect.y + video_rect.h) / (float)screen.h; + + GLfloat tex_coords[] = {minx, miny, minx, maxy, maxx, miny, maxx, maxy}; + + glw->glBindVertexArray(pass->vertex_array); - GLfloat minx = 0; - GLfloat miny = 0; - GLfloat maxx = pass->state.output_size[0] / (GLfloat)pass->state.output_texture_size[0]; - GLfloat maxy = pass->state.output_size[1] / (GLfloat)pass->state.output_texture_size[1]; - - pass->state.tex_coords[0] = minx; - pass->state.tex_coords[1] = miny; - pass->state.tex_coords[2] = minx; - pass->state.tex_coords[3] = maxy; - pass->state.tex_coords[4] = maxx; - pass->state.tex_coords[5] = miny; - pass->state.tex_coords[6] = maxx; - pass->state.tex_coords[7] = maxy; + glw->glBindBuffer(GL_ARRAY_BUFFER, pass->vbo.tex_coord); + glw->glBufferSubData(GL_ARRAY_BUFFER, 0, 8 * sizeof(GLfloat), tex_coords); + glw->glBindBuffer(GL_ARRAY_BUFFER, 0); - glw->glBindVertexArray(pass->vertex_array); - - glw->glBindBuffer(GL_ARRAY_BUFFER, pass->vbo.tex_coord); - glw->glBufferSubData(GL_ARRAY_BUFFER, 0, 8 * sizeof(GLfloat), input->state.tex_coords); - glw->glBindBuffer(GL_ARRAY_BUFFER, 0); - - memset(&data, 0, sizeof(struct render_data)); - data.shader = shader; - data.pass = i; - data.shader_pass = pass; - data.texture = input->fbo.texture.id; - data.output_size = orig_output_size; - data.orig_pass = orig; - data.frame_count = frame_count; - - render_pass(&data); + memset(&data, 0, sizeof(struct render_data)); + data.pass = -1; + data.shader_pass = &active_shader->scene; + data.texture = scene_texture.id; + data.output_size = orig_output_size; + render_pass(&data); - glw->glBindFramebuffer(GL_FRAMEBUFFER, 0); + glw->glBindFramebuffer(GL_FRAMEBUFFER, 0); + } - if (pass->fbo.texture.mipmap) { - glw->glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, pass->fbo.texture.id); - glw->glGenerateMipmap(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, 0); + struct shader_pass *orig = &active_shader->scene; + struct shader_pass *input = &active_shader->scene; - } + for (s = 0; s < active_shader->num_shaders; ++s) { + struct glsl_shader *shader = &active_shader->shaders[s]; - input = pass; - } + // float refresh_rate = shader->shader_refresh_rate; + // if (refresh_rate < 0) + // refresh_rate = gl3_shader_refresh_rate; + float refresh_rate = gl3_shader_refresh_rate; + if (refresh_rate == 0) + refresh_rate = video_refresh_rate; + int frame_count = ticks / (1000.0f / refresh_rate); - if (shader->has_prev && (ticks - shader->last_prev_update) >= (1000.f / refresh_rate)) { - shader->last_prev_update = ticks; + /* loop through each pass */ + for (i = 0; i < shader->num_passes; ++i) { + struct shader_pass *pass = &shader->passes[i]; - /* shift array */ - memmove(&shader->prev[1], &shader->prev[0], MAX_PREV * sizeof(struct shader_prev)); - memcpy(&shader->prev[0], &shader->prev[MAX_PREV], sizeof(struct shader_prev)); - - struct shader_pass *pass = orig; - struct shader_pass *prev_pass = &shader->prev_scene; - struct shader_prev *prev = &shader->prev[0]; - - memcpy(&prev_pass->state, &pass->state, sizeof(struct shader_state)); - - recreate_fbo(&prev->fbo, prev_pass->state.output_texture_size[0], prev_pass->state.output_texture_size[1]); - - memcpy(&prev_pass->fbo, &prev->fbo, sizeof(struct shader_fbo)); - - glw->glBindFramebuffer(GL_FRAMEBUFFER, prev->fbo.id); - glClearColor(0, 0, 0, 1); - glClear(GL_COLOR_BUFFER_BIT); - - glViewport(0, 0, pass->state.output_size[0], pass->state.output_size[1]); - - glw->glBindVertexArray(prev_pass->vertex_array); - - glw->glBindBuffer(GL_ARRAY_BUFFER, prev->vbo.tex_coord); - glw->glBufferSubData(GL_ARRAY_BUFFER, 0, 8 * sizeof(GLfloat), pass->state.tex_coords); - glw->glBindBuffer(GL_ARRAY_BUFFER, 0); - - glw->glBindBuffer(GL_ARRAY_BUFFER, prev_pass->vbo.tex_coord); - glw->glBufferSubData(GL_ARRAY_BUFFER, 0, 8 * sizeof(GLfloat), pass->state.tex_coords); - glw->glBindBuffer(GL_ARRAY_BUFFER, 0); - - memset(&data, 0, sizeof(struct render_data)); - data.shader = shader; - data.pass = -10; - data.shader_pass = prev_pass; - data.texture = pass->fbo.texture.id; - data.output_size = orig_output_size; - - render_pass(&data); - - glw->glBindFramebuffer(GL_FRAMEBUFFER, 0); - } - - orig = input; - } - - if (active_shader->final_pass.active) { - struct shader_pass *pass = &active_shader->final_pass; - - memcpy(pass->state.input_size, input->state.output_size, 2 * sizeof(GLfloat)); - memcpy(pass->state.input_texture_size, input->state.output_texture_size, 2 * sizeof(GLfloat)); - - for (j = 0; j < 2; ++j) { - if (pass->scale.mode[j] == SCALE_VIEWPORT) - pass->state.output_size[j] = orig_output_size[j] * pass->scale.value[j]; - else if (pass->scale.mode[j] == SCALE_ABSOLUTE) - pass->state.output_size[j] = pass->scale.value[j]; - else - pass->state.output_size[j] = pass->state.input_size[j] * pass->scale.value[j]; - - pass->state.output_texture_size[j] = next_pow2(pass->state.output_size[j]); - } - - glViewport(window_rect.x, window_rect.y, window_rect.w, window_rect.h); - - glClearColor(0, 0, 0, 1); - glClear(GL_COLOR_BUFFER_BIT); - - GLfloat minx = 0; - GLfloat miny = 0; - GLfloat maxx = pass->state.output_size[0] / (GLfloat)pass->state.output_texture_size[0]; - GLfloat maxy = pass->state.output_size[1] / (GLfloat)pass->state.output_texture_size[1]; - - pass->state.tex_coords[0] = minx; - pass->state.tex_coords[1] = miny; - pass->state.tex_coords[2] = minx; - pass->state.tex_coords[3] = maxy; - pass->state.tex_coords[4] = maxx; - pass->state.tex_coords[5] = miny; - pass->state.tex_coords[6] = maxx; - pass->state.tex_coords[7] = maxy; - - glw->glBindVertexArray(pass->vertex_array); - - glw->glBindBuffer(GL_ARRAY_BUFFER, pass->vbo.tex_coord); - glw->glBufferSubData(GL_ARRAY_BUFFER, 0, 8 * sizeof(GLfloat), input->state.tex_coords); - glw->glBindBuffer(GL_ARRAY_BUFFER, 0); - - memset(&data, 0, sizeof(struct render_data)); - data.pass = -2; - data.shader_pass = pass; - data.texture = input->fbo.texture.id; - data.output_size = orig_output_size; - data.orig_pass = orig; - - render_pass(&data); - } - - if (!take_screenshot) { - if (video_focus_dim && !(SDL_GetWindowFlags(window) & SDL_WINDOW_INPUT_FOCUS)) { - struct shader_pass *pass = &active_shader->fs_color; - GLfloat r = 0; - GLfloat g = 0; - GLfloat b = 0; - GLfloat a = 0x80 / (float)0xff; - - GLfloat colors[] = { - r, g, b, a, - r, g, b, a, - r, g, b, a, - r, g, b, a - }; - - glw->glBindVertexArray(pass->vertex_array); - - glw->glBindBuffer(GL_ARRAY_BUFFER, pass->vbo.color); - glw->glBufferSubData(GL_ARRAY_BUFFER, 0, 16 * sizeof(GLfloat), colors); - glw->glBindBuffer(GL_ARRAY_BUFFER, 0); - - memset(&data, 0, sizeof(struct render_data)); - data.pass = -3; - data.shader_pass = pass; - data.texture = 0; - data.output_size = orig_output_size; - data.orig_pass = orig; - - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_BLEND); - render_pass(&data); - glDisable(GL_BLEND); - } - if (flash.enabled) { - struct shader_pass *pass = &active_shader->fs_color; - GLfloat r = (flash.color[0] & 0xff) / (float)0xff; - GLfloat g = (flash.color[1] & 0xff) / (float)0xff; - GLfloat b = (flash.color[2] & 0xff) / (float)0xff; - GLfloat a = (flash.color[3] & 0xff) / (float)0xff; - - GLfloat colors[] = { - r, g, b, a, - r, g, b, a, - r, g, b, a, - r, g, b, a - }; - - glw->glBindVertexArray(pass->vertex_array); - - glw->glBindBuffer(GL_ARRAY_BUFFER, pass->vbo.color); - glw->glBufferSubData(GL_ARRAY_BUFFER, 0, 16 * sizeof(GLfloat), colors); - glw->glBindBuffer(GL_ARRAY_BUFFER, 0); - - memset(&data, 0, sizeof(struct render_data)); - data.pass = -3; - data.shader_pass = pass; - data.texture = 0; - data.output_size = orig_output_size; - data.orig_pass = orig; - - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_BLEND); - render_pass(&data); - glDisable(GL_BLEND); - } - } else { - take_screenshot = 0; - - int width = window_rect.w; - int height = window_rect.h; - - SDL_GetWindowSize(window, &width, &height); - - unsigned char *rgba = (unsigned char *)malloc(width * height * 4); - - glFinish(); - glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, rgba); - - int x, y; - unsigned char *rgb = (unsigned char *)malloc(width * height * 3); - - for (x = 0; x < width; ++x) { - for (y = 0; y < height; ++y) { - rgb[(y * width + x) * 3 + 0] = rgba[((height - y - 1) * width + x) * 4 + 0]; - rgb[(y * width + x) * 3 + 1] = rgba[((height - y - 1) * width + x) * 4 + 1]; - rgb[(y * width + x) * 3 + 2] = rgba[((height - y - 1) * width + x) * 4 + 2]; - } - } - - screenshot_taken(rgb, width, height); - - free(rgb); - free(rgba); - } - - // DEBUG: render FBO + memcpy(pass->state.input_size, input->state.output_size, 2 * sizeof(GLfloat)); + memcpy(pass->state.input_texture_size, input->state.output_texture_size, 2 * sizeof(GLfloat)); + + for (j = 0; j < 2; ++j) { + if (pass->scale.mode[j] == SCALE_VIEWPORT) + pass->state.output_size[j] = orig_output_size[j] * pass->scale.value[j]; + else if (pass->scale.mode[j] == SCALE_ABSOLUTE) + pass->state.output_size[j] = pass->scale.value[j]; + else + pass->state.output_size[j] = pass->state.input_size[j] * pass->scale.value[j]; + + pass->state.output_texture_size[j] = next_pow2(pass->state.output_size[j]); + } + + if (pass->fbo.id >= 0) { + recreate_fbo(&pass->fbo, pass->state.output_texture_size[0], pass->state.output_texture_size[1]); + + glw->glBindFramebuffer(GL_FRAMEBUFFER, pass->fbo.id); + glViewport(0, 0, pass->state.output_size[0], pass->state.output_size[1]); + } else + glViewport(window_rect.x, window_rect.y, window_rect.w, window_rect.h); + + glClearColor(0, 0, 0, 1); + glClear(GL_COLOR_BUFFER_BIT); + + GLfloat minx = 0; + GLfloat miny = 0; + GLfloat maxx = pass->state.output_size[0] / (GLfloat)pass->state.output_texture_size[0]; + GLfloat maxy = pass->state.output_size[1] / (GLfloat)pass->state.output_texture_size[1]; + + pass->state.tex_coords[0] = minx; + pass->state.tex_coords[1] = miny; + pass->state.tex_coords[2] = minx; + pass->state.tex_coords[3] = maxy; + pass->state.tex_coords[4] = maxx; + pass->state.tex_coords[5] = miny; + pass->state.tex_coords[6] = maxx; + pass->state.tex_coords[7] = maxy; + + glw->glBindVertexArray(pass->vertex_array); + + glw->glBindBuffer(GL_ARRAY_BUFFER, pass->vbo.tex_coord); + glw->glBufferSubData(GL_ARRAY_BUFFER, 0, 8 * sizeof(GLfloat), input->state.tex_coords); + glw->glBindBuffer(GL_ARRAY_BUFFER, 0); + + memset(&data, 0, sizeof(struct render_data)); + data.shader = shader; + data.pass = i; + data.shader_pass = pass; + data.texture = input->fbo.texture.id; + data.output_size = orig_output_size; + data.orig_pass = orig; + data.frame_count = frame_count; + + render_pass(&data); + + glw->glBindFramebuffer(GL_FRAMEBUFFER, 0); + + if (pass->fbo.texture.mipmap) { + glw->glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, pass->fbo.texture.id); + glw->glGenerateMipmap(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, 0); + } + + input = pass; + } + + if (shader->has_prev && (ticks - shader->last_prev_update) >= (1000.f / refresh_rate)) { + shader->last_prev_update = ticks; + + /* shift array */ + memmove(&shader->prev[1], &shader->prev[0], MAX_PREV * sizeof(struct shader_prev)); + memcpy(&shader->prev[0], &shader->prev[MAX_PREV], sizeof(struct shader_prev)); + + struct shader_pass *pass = orig; + struct shader_pass *prev_pass = &shader->prev_scene; + struct shader_prev *prev = &shader->prev[0]; + + memcpy(&prev_pass->state, &pass->state, sizeof(struct shader_state)); + + recreate_fbo(&prev->fbo, prev_pass->state.output_texture_size[0], + prev_pass->state.output_texture_size[1]); + + memcpy(&prev_pass->fbo, &prev->fbo, sizeof(struct shader_fbo)); + + glw->glBindFramebuffer(GL_FRAMEBUFFER, prev->fbo.id); + glClearColor(0, 0, 0, 1); + glClear(GL_COLOR_BUFFER_BIT); + + glViewport(0, 0, pass->state.output_size[0], pass->state.output_size[1]); + + glw->glBindVertexArray(prev_pass->vertex_array); + + glw->glBindBuffer(GL_ARRAY_BUFFER, prev->vbo.tex_coord); + glw->glBufferSubData(GL_ARRAY_BUFFER, 0, 8 * sizeof(GLfloat), pass->state.tex_coords); + glw->glBindBuffer(GL_ARRAY_BUFFER, 0); + + glw->glBindBuffer(GL_ARRAY_BUFFER, prev_pass->vbo.tex_coord); + glw->glBufferSubData(GL_ARRAY_BUFFER, 0, 8 * sizeof(GLfloat), pass->state.tex_coords); + glw->glBindBuffer(GL_ARRAY_BUFFER, 0); + + memset(&data, 0, sizeof(struct render_data)); + data.shader = shader; + data.pass = -10; + data.shader_pass = prev_pass; + data.texture = pass->fbo.texture.id; + data.output_size = orig_output_size; + + render_pass(&data); + + glw->glBindFramebuffer(GL_FRAMEBUFFER, 0); + } + + orig = input; + } + + if (active_shader->final_pass.active) { + struct shader_pass *pass = &active_shader->final_pass; + + memcpy(pass->state.input_size, input->state.output_size, 2 * sizeof(GLfloat)); + memcpy(pass->state.input_texture_size, input->state.output_texture_size, 2 * sizeof(GLfloat)); + + for (j = 0; j < 2; ++j) { + if (pass->scale.mode[j] == SCALE_VIEWPORT) + pass->state.output_size[j] = orig_output_size[j] * pass->scale.value[j]; + else if (pass->scale.mode[j] == SCALE_ABSOLUTE) + pass->state.output_size[j] = pass->scale.value[j]; + else + pass->state.output_size[j] = pass->state.input_size[j] * pass->scale.value[j]; + + pass->state.output_texture_size[j] = next_pow2(pass->state.output_size[j]); + } + + glViewport(window_rect.x, window_rect.y, window_rect.w, window_rect.h); + + glClearColor(0, 0, 0, 1); + glClear(GL_COLOR_BUFFER_BIT); + + GLfloat minx = 0; + GLfloat miny = 0; + GLfloat maxx = pass->state.output_size[0] / (GLfloat)pass->state.output_texture_size[0]; + GLfloat maxy = pass->state.output_size[1] / (GLfloat)pass->state.output_texture_size[1]; + + pass->state.tex_coords[0] = minx; + pass->state.tex_coords[1] = miny; + pass->state.tex_coords[2] = minx; + pass->state.tex_coords[3] = maxy; + pass->state.tex_coords[4] = maxx; + pass->state.tex_coords[5] = miny; + pass->state.tex_coords[6] = maxx; + pass->state.tex_coords[7] = maxy; + + glw->glBindVertexArray(pass->vertex_array); + + glw->glBindBuffer(GL_ARRAY_BUFFER, pass->vbo.tex_coord); + glw->glBufferSubData(GL_ARRAY_BUFFER, 0, 8 * sizeof(GLfloat), input->state.tex_coords); + glw->glBindBuffer(GL_ARRAY_BUFFER, 0); + + memset(&data, 0, sizeof(struct render_data)); + data.pass = -2; + data.shader_pass = pass; + data.texture = input->fbo.texture.id; + data.output_size = orig_output_size; + data.orig_pass = orig; + + render_pass(&data); + } + + if (!take_screenshot) { + if (video_focus_dim && !(SDL_GetWindowFlags(window) & SDL_WINDOW_INPUT_FOCUS)) { + struct shader_pass *pass = &active_shader->fs_color; + GLfloat r = 0; + GLfloat g = 0; + GLfloat b = 0; + GLfloat a = 0x80 / (float)0xff; + + GLfloat colors[] = {r, g, b, a, r, g, b, a, r, g, b, a, r, g, b, a}; + + glw->glBindVertexArray(pass->vertex_array); + + glw->glBindBuffer(GL_ARRAY_BUFFER, pass->vbo.color); + glw->glBufferSubData(GL_ARRAY_BUFFER, 0, 16 * sizeof(GLfloat), colors); + glw->glBindBuffer(GL_ARRAY_BUFFER, 0); + + memset(&data, 0, sizeof(struct render_data)); + data.pass = -3; + data.shader_pass = pass; + data.texture = 0; + data.output_size = orig_output_size; + data.orig_pass = orig; + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + render_pass(&data); + glDisable(GL_BLEND); + } + if (flash.enabled) { + struct shader_pass *pass = &active_shader->fs_color; + GLfloat r = (flash.color[0] & 0xff) / (float)0xff; + GLfloat g = (flash.color[1] & 0xff) / (float)0xff; + GLfloat b = (flash.color[2] & 0xff) / (float)0xff; + GLfloat a = (flash.color[3] & 0xff) / (float)0xff; + + GLfloat colors[] = {r, g, b, a, r, g, b, a, r, g, b, a, r, g, b, a}; + + glw->glBindVertexArray(pass->vertex_array); + + glw->glBindBuffer(GL_ARRAY_BUFFER, pass->vbo.color); + glw->glBufferSubData(GL_ARRAY_BUFFER, 0, 16 * sizeof(GLfloat), colors); + glw->glBindBuffer(GL_ARRAY_BUFFER, 0); + + memset(&data, 0, sizeof(struct render_data)); + data.pass = -3; + data.shader_pass = pass; + data.texture = 0; + data.output_size = orig_output_size; + data.orig_pass = orig; + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + render_pass(&data); + glDisable(GL_BLEND); + } + } else { + take_screenshot = 0; + + int width = window_rect.w; + int height = window_rect.h; + + SDL_GetWindowSize(window, &width, &height); + + unsigned char *rgba = (unsigned char *)malloc(width * height * 4); + + glFinish(); + glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, rgba); + + int x, y; + unsigned char *rgb = (unsigned char *)malloc(width * height * 3); + + for (x = 0; x < width; ++x) { + for (y = 0; y < height; ++y) { + rgb[(y * width + x) * 3 + 0] = rgba[((height - y - 1) * width + x) * 4 + 0]; + rgb[(y * width + x) * 3 + 1] = rgba[((height - y - 1) * width + x) * 4 + 1]; + rgb[(y * width + x) * 3 + 2] = rgba[((height - y - 1) * width + x) * 4 + 2]; + } + } + + screenshot_taken(rgb, width, height); + + free(rgb); + free(rgba); + } + + // DEBUG: render FBO #ifdef SDL2_SHADER_DEBUG - // GLint texture = scene_texture.id; - GLint texture = active_shader->lut_textures[0].texture.id; - // GLint texture = active_shader->scene.fbo.texture; + // GLint texture = scene_texture.id; + GLint texture = active_shader->lut_textures[0].texture.id; + // GLint texture = active_shader->scene.fbo.texture; - glClearColor(1, 1, 1, 1); - glClear(GL_COLOR_BUFFER_BIT); + glClearColor(1, 1, 1, 1); + glClear(GL_COLOR_BUFFER_BIT); - glViewport(0, 0, orig_output_size[0], orig_output_size[1]); + glViewport(0, 0, orig_output_size[0], orig_output_size[1]); - struct shader_pass* pass = &active_shader->debug; + struct shader_pass *pass = &active_shader->debug; - render_pass(-999, pass, orig_output_size, texture); + render_pass(-999, pass, orig_output_size, texture); #endif - glDisable(GL_FRAMEBUFFER_SRGB); - - SDL_GL_SwapWindow(window); + glDisable(GL_FRAMEBUFFER_SRGB); + SDL_GL_SwapWindow(window); } sdl_renderer_t *gl3_renderer_create() { - sdl_renderer_t *renderer = malloc(sizeof(sdl_renderer_t)); - renderer->init = gl3_init; - renderer->close = gl3_close; - renderer->update = gl3_update; - renderer->present = gl3_present; - renderer->always_update = 1; - return renderer; + sdl_renderer_t *renderer = malloc(sizeof(sdl_renderer_t)); + renderer->init = gl3_init; + renderer->close = gl3_close; + renderer->update = gl3_update; + renderer->present = gl3_present; + renderer->always_update = 1; + return renderer; } -void gl3_renderer_close(sdl_renderer_t *renderer) { - free(renderer); -} +void gl3_renderer_close(sdl_renderer_t *renderer) { free(renderer); } static int available = -1; int gl3_renderer_available(struct sdl_render_driver *driver) { - if (available < 0) { - available = 0; + if (available < 0) { + available = 0; - // GL SetAttribute should be done *before* window creation for the attributes to apply on - // context creation (seems to depend on OpenGL impl. but it souldn't hurt other platforms - // to do it here (earlier than before) - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); + // GL SetAttribute should be done *before* window creation for the attributes to apply on + // context creation (seems to depend on OpenGL impl. but it souldn't hurt other platforms + // to do it here (earlier than before) + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); #ifdef __APPLE__ - // without an explicit request for the core profile 3.0 macOS falls back to default ancient 2.1 - SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); + // without an explicit request for the core profile 3.0 macOS falls back to default ancient 2.1 + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); #endif - SDL_Window *window = SDL_CreateWindow("GL3 test", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1, 1, SDL_WINDOW_HIDDEN | SDL_WINDOW_OPENGL); - if (window) { - SDL_GLContext context = SDL_GL_CreateContext(window); - if (context) { - int version = -1; - glGetIntegerv(GL_MAJOR_VERSION, &version); + SDL_Window *window = SDL_CreateWindow("GL3 test", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1, 1, + SDL_WINDOW_HIDDEN | SDL_WINDOW_OPENGL); + if (window) { + SDL_GLContext context = SDL_GL_CreateContext(window); + if (context) { + int version = -1; + glGetIntegerv(GL_MAJOR_VERSION, &version); - SDL_GL_DeleteContext(context); + SDL_GL_DeleteContext(context); - available = version >= 3; - } - SDL_DestroyWindow(window); - } - - } - return available; + available = version >= 3; + } + SDL_DestroyWindow(window); + } + } + return available; } diff --git a/src/wx-ui/wx-sdl2-video-renderer.c b/src/wx-ui/wx-sdl2-video-renderer.c index e6db3bc8..9b6aa466 100644 --- a/src/wx-ui/wx-sdl2-video-renderer.c +++ b/src/wx-ui/wx-sdl2-video-renderer.c @@ -17,147 +17,140 @@ extern int take_screenshot; extern void screenshot_taken(unsigned char *rgb, int width, int height); int sdl_video_renderer_init(SDL_Window *window, sdl_render_driver requested_render_driver, SDL_Rect screen) { - SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, video_scale_mode ? "1" : "0"); - const char *driver = requested_render_driver.sdl_id; - if (!driver) - driver = "0"; - SDL_SetHint(SDL_HINT_RENDER_DRIVER, driver); + SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, video_scale_mode ? "1" : "0"); + const char *driver = requested_render_driver.sdl_id; + if (!driver) + driver = "0"; + SDL_SetHint(SDL_HINT_RENDER_DRIVER, driver); - int flags = SDL_RENDERER_ACCELERATED; - if (video_vsync) { - flags |= SDL_RENDERER_PRESENTVSYNC; - } - renderer = SDL_CreateRenderer(window, -1, flags); + int flags = SDL_RENDERER_ACCELERATED; + if (video_vsync) { + flags |= SDL_RENDERER_PRESENTVSYNC; + } + renderer = SDL_CreateRenderer(window, -1, flags); - if (!renderer) { - char message[200]; - sprintf(message, - "SDL window could not be created! Error: %s\n", - SDL_GetError()); - wx_messagebox(0, message, "SDL Error", WX_MB_OK); - return SDL_FALSE; - } + if (!renderer) { + char message[200]; + sprintf(message, "SDL window could not be created! Error: %s\n", SDL_GetError()); + wx_messagebox(0, message, "SDL Error", WX_MB_OK); + return SDL_FALSE; + } - SDL_RendererInfo rendererInfo; - SDL_GetRendererInfo(renderer, &rendererInfo); - sdl_render_driver *d = sdl_get_render_driver_by_name_ptr(rendererInfo.name); - if (!d) - strcpy(current_render_driver_name, "Unknown"); - else - strcpy(current_render_driver_name, d->name); + SDL_RendererInfo rendererInfo; + SDL_GetRendererInfo(renderer, &rendererInfo); + sdl_render_driver *d = sdl_get_render_driver_by_name_ptr(rendererInfo.name); + if (!d) + strcpy(current_render_driver_name, "Unknown"); + else + strcpy(current_render_driver_name, d->name); - texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, - SDL_TEXTUREACCESS_STREAMING, - screen.w, screen.h); - - return SDL_TRUE; + texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, screen.w, screen.h); + return SDL_TRUE; } void sdl_video_renderer_close() { - if (texture) { - SDL_DestroyTexture(texture); - texture = NULL; - } - if (renderer) { - SDL_DestroyRenderer(renderer); - renderer = NULL; - } + if (texture) { + SDL_DestroyTexture(texture); + texture = NULL; + } + if (renderer) { + SDL_DestroyRenderer(renderer); + renderer = NULL; + } } void sdl_video_renderer_update(SDL_Window *window, SDL_Rect updated_rect, BITMAP *screen) { - SDL_UpdateTexture(texture, &updated_rect, &((uint32_t *)screen->dat)[updated_rect.y * screen->w + updated_rect.x], screen->w * 4); + SDL_UpdateTexture(texture, &updated_rect, &((uint32_t *)screen->dat)[updated_rect.y * screen->w + updated_rect.x], + screen->w * 4); } void sdl_video_renderer_present(SDL_Window *window, SDL_Rect texture_rect, SDL_Rect window_rect, SDL_Rect screen) { - SDL_RenderClear(renderer); - SDL_RenderCopy(renderer, texture, &texture_rect, &window_rect); - int sshot = take_screenshot; - if (!sshot) { - if (video_focus_dim && !(SDL_GetWindowFlags(window) & SDL_WINDOW_INPUT_FOCUS)) { - SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND); - SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0x80); - SDL_RenderFillRect(renderer, NULL); - SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0xff); - SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE); - } - if (flash.enabled) { - SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND); - SDL_SetRenderDrawColor(renderer, flash.color[0], flash.color[1], flash.color[2], flash.color[3]); - SDL_RenderFillRect(renderer, NULL); - SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0xff); - SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE); - } - } - SDL_RenderPresent(renderer); + SDL_RenderClear(renderer); + SDL_RenderCopy(renderer, texture, &texture_rect, &window_rect); + int sshot = take_screenshot; + if (!sshot) { + if (video_focus_dim && !(SDL_GetWindowFlags(window) & SDL_WINDOW_INPUT_FOCUS)) { + SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND); + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0x80); + SDL_RenderFillRect(renderer, NULL); + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0xff); + SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE); + } + if (flash.enabled) { + SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND); + SDL_SetRenderDrawColor(renderer, flash.color[0], flash.color[1], flash.color[2], flash.color[3]); + SDL_RenderFillRect(renderer, NULL); + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0xff); + SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE); + } + } + SDL_RenderPresent(renderer); - if (sshot) { - take_screenshot = 0; + if (sshot) { + take_screenshot = 0; - int width = window_rect.w; - int height = window_rect.h; + int width = window_rect.w; + int height = window_rect.h; - SDL_GetWindowSize(window, &width, &height); + SDL_GetWindowSize(window, &width, &height); - /* seems to work without rendering to texture first */ -// SDL_Texture* tex = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_TARGET, width, height); -// -// SDL_SetRenderTarget(renderer, tex); -// SDL_RenderClear(renderer); -// SDL_RenderCopy(renderer, texture, &texture_rect, &window_rect); -// SDL_RenderPresent(renderer); + /* seems to work without rendering to texture first */ + // SDL_Texture* tex = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ABGR8888, + // SDL_TEXTUREACCESS_TARGET, width, height); + // + // SDL_SetRenderTarget(renderer, tex); + // SDL_RenderClear(renderer); + // SDL_RenderCopy(renderer, texture, &texture_rect, &window_rect); + // SDL_RenderPresent(renderer); - unsigned char *rgba = (unsigned char *)malloc(width * height * 4); - int res = SDL_RenderReadPixels(renderer, NULL, SDL_PIXELFORMAT_ABGR8888, rgba, width * 4); + unsigned char *rgba = (unsigned char *)malloc(width * height * 4); + int res = SDL_RenderReadPixels(renderer, NULL, SDL_PIXELFORMAT_ABGR8888, rgba, width * 4); -// SDL_SetRenderTarget(renderer, NULL); -// SDL_DestroyTexture(tex); + // SDL_SetRenderTarget(renderer, NULL); + // SDL_DestroyTexture(tex); - if (!res) { - int x, y; - unsigned char *rgb = (unsigned char *)malloc(width * height * 3); + if (!res) { + int x, y; + unsigned char *rgb = (unsigned char *)malloc(width * height * 3); - for (x = 0; x < width; ++x) { - for (y = 0; y < height; ++y) { - rgb[(y * width + x) * 3 + 0] = rgba[(y * width + x) * 4 + 0]; - rgb[(y * width + x) * 3 + 1] = rgba[(y * width + x) * 4 + 1]; - rgb[(y * width + x) * 3 + 2] = rgba[(y * width + x) * 4 + 2]; - } - } + for (x = 0; x < width; ++x) { + for (y = 0; y < height; ++y) { + rgb[(y * width + x) * 3 + 0] = rgba[(y * width + x) * 4 + 0]; + rgb[(y * width + x) * 3 + 1] = rgba[(y * width + x) * 4 + 1]; + rgb[(y * width + x) * 3 + 2] = rgba[(y * width + x) * 4 + 2]; + } + } - screenshot_taken(rgb, width, height); + screenshot_taken(rgb, width, height); - free(rgb); - } else - screenshot_taken(0, 0, 0); - - free(rgba); - } + free(rgb); + } else + screenshot_taken(0, 0, 0); + free(rgba); + } } sdl_renderer_t *sdl2_renderer_create() { - sdl_renderer_t *renderer = malloc(sizeof(sdl_renderer_t)); - renderer->init = sdl_video_renderer_init; - renderer->close = sdl_video_renderer_close; - renderer->update = sdl_video_renderer_update; - renderer->present = sdl_video_renderer_present; - renderer->always_update = 0; - return renderer; + sdl_renderer_t *renderer = malloc(sizeof(sdl_renderer_t)); + renderer->init = sdl_video_renderer_init; + renderer->close = sdl_video_renderer_close; + renderer->update = sdl_video_renderer_update; + renderer->present = sdl_video_renderer_present; + renderer->always_update = 0; + return renderer; } -void sdl2_renderer_close(sdl_renderer_t *renderer) { - free(renderer); -} +void sdl2_renderer_close(sdl_renderer_t *renderer) { free(renderer); } int sdl2_renderer_available(struct sdl_render_driver *driver) { - int i; - SDL_RendererInfo renderInfo; - for (i = 0; i < SDL_GetNumRenderDrivers(); ++i) { - SDL_GetRenderDriverInfo(i, &renderInfo); - if (!strcmp(driver->sdl_id, renderInfo.name)) - return 1; - } - return 0; - + int i; + SDL_RendererInfo renderInfo; + for (i = 0; i < SDL_GetNumRenderDrivers(); ++i) { + SDL_GetRenderDriverInfo(i, &renderInfo); + if (!strcmp(driver->sdl_id, renderInfo.name)) + return 1; + } + return 0; } diff --git a/src/wx-ui/wx-sdl2-video.c b/src/wx-ui/wx-sdl2-video.c index db78dc24..54f609aa 100644 --- a/src/wx-ui/wx-sdl2-video.c +++ b/src/wx-ui/wx-sdl2-video.c @@ -32,14 +32,13 @@ int video_fullscreen_mode = 0; int video_alternative_update_lock = 0; static sdl_render_driver sdl_render_drivers[] = { - {RENDERER_AUTO, "auto", "Auto", 0, sdl2_renderer_create, sdl2_renderer_close, sdl2_renderer_available}, - {RENDERER_DIRECT3D, "direct3d", "Direct3D", 0, sdl2_renderer_create, sdl2_renderer_close, sdl2_renderer_available}, - {RENDERER_OPENGL, "opengl", "OpenGL", 0, sdl2_renderer_create, sdl2_renderer_close, sdl2_renderer_available}, - {RENDERER_OPENGLES2, "opengles2", "OpenGL ES 2", 0, sdl2_renderer_create, sdl2_renderer_close, sdl2_renderer_available}, - {RENDERER_OPENGLES, "opengles", "OpenGL ES", 0, sdl2_renderer_create, sdl2_renderer_close, sdl2_renderer_available}, - {RENDERER_SOFTWARE, "software", "Software", 0, sdl2_renderer_create, sdl2_renderer_close, sdl2_renderer_available}, - {RENDERER_GL3, "gl3", "OpenGL 3.0", SDL_WINDOW_OPENGL, gl3_renderer_create, gl3_renderer_close, gl3_renderer_available} -}; + {RENDERER_AUTO, "auto", "Auto", 0, sdl2_renderer_create, sdl2_renderer_close, sdl2_renderer_available}, + {RENDERER_DIRECT3D, "direct3d", "Direct3D", 0, sdl2_renderer_create, sdl2_renderer_close, sdl2_renderer_available}, + {RENDERER_OPENGL, "opengl", "OpenGL", 0, sdl2_renderer_create, sdl2_renderer_close, sdl2_renderer_available}, + {RENDERER_OPENGLES2, "opengles2", "OpenGL ES 2", 0, sdl2_renderer_create, sdl2_renderer_close, sdl2_renderer_available}, + {RENDERER_OPENGLES, "opengles", "OpenGL ES", 0, sdl2_renderer_create, sdl2_renderer_close, sdl2_renderer_available}, + {RENDERER_SOFTWARE, "software", "Software", 0, sdl2_renderer_create, sdl2_renderer_close, sdl2_renderer_available}, + {RENDERER_GL3, "gl3", "OpenGL 3.0", SDL_WINDOW_OPENGL, gl3_renderer_create, gl3_renderer_close, gl3_renderer_available}}; sdl_render_driver requested_render_driver; @@ -47,245 +46,242 @@ char current_render_driver_name[50]; static sdl_renderer_t *renderer = NULL; void hline(BITMAP *b, int x1, int y, int x2, int col) { - if (y < 0 || y >= buffer32->h) - return; + if (y < 0 || y >= buffer32->h) + return; - for (; x1 < x2; x1++) - ((uint32_t *)b->line[y])[x1] = col; + for (; x1 < x2; x1++) + ((uint32_t *)b->line[y])[x1] = col; } -void destroy_bitmap(BITMAP *b) { - free(b); -} +void destroy_bitmap(BITMAP *b) { free(b); } BITMAP *create_bitmap(int x, int y) { - BITMAP *b = malloc(sizeof(BITMAP) + (y * sizeof(uint8_t *))); - int c; - b->dat = malloc(x * y * 4); - for (c = 0; c < y; c++) { - b->line[c] = b->dat + (c * x * 4); - } - b->w = x; - b->h = y; - return b; + BITMAP *b = malloc(sizeof(BITMAP) + (y * sizeof(uint8_t *))); + int c; + b->dat = malloc(x * y * 4); + for (c = 0; c < y; c++) { + b->line[c] = b->dat + (c * x * 4); + } + b->w = x; + b->h = y; + return b; } sdl_render_driver *sdl_get_render_drivers(int *num) { - if (num) - *num = SDL_arraysize(sdl_render_drivers); - return sdl_render_drivers; + if (num) + *num = SDL_arraysize(sdl_render_drivers); + return sdl_render_drivers; } sdl_render_driver sdl_get_render_driver_by_name(const char *name, int def) { - int i; - for (i = 0; i < SDL_arraysize(sdl_render_drivers); ++i) { - if (!strcmp(sdl_render_drivers[i].sdl_id, name)) { - return sdl_render_drivers[i]; - } - } - return sdl_render_drivers[def]; + int i; + for (i = 0; i < SDL_arraysize(sdl_render_drivers); ++i) { + if (!strcmp(sdl_render_drivers[i].sdl_id, name)) { + return sdl_render_drivers[i]; + } + } + return sdl_render_drivers[def]; } sdl_render_driver *sdl_get_render_driver_by_name_ptr(const char *name) { - int i; - for (i = 0; i < SDL_arraysize(sdl_render_drivers); ++i) { - if (!strcmp(sdl_render_drivers[i].sdl_id, name)) { - return &sdl_render_drivers[i]; - } - } - return 0; + int i; + for (i = 0; i < SDL_arraysize(sdl_render_drivers); ++i) { + if (!strcmp(sdl_render_drivers[i].sdl_id, name)) { + return &sdl_render_drivers[i]; + } + } + return 0; } sdl_render_driver sdl_get_render_driver_by_id(int id, int def) { - int i; - for (i = 0; i < SDL_arraysize(sdl_render_drivers); ++i) { - if (sdl_render_drivers[i].id == id) { - return sdl_render_drivers[i]; - } - } - return sdl_render_drivers[def]; + int i; + for (i = 0; i < SDL_arraysize(sdl_render_drivers); ++i) { + if (sdl_render_drivers[i].id == id) { + return sdl_render_drivers[i]; + } + } + return sdl_render_drivers[def]; } void sdl_scale(int scale, SDL_Rect src, SDL_Rect *dst, int w, int h) { - double t, b, l, r; - int ratio_w, ratio_h; - switch (scale) { - case FULLSCR_SCALE_43:t = 0; - b = src.h; - l = (src.w / 2) - ((src.h * 4) / (3 * 2)); - r = (src.w / 2) + ((src.h * 4) / (3 * 2)); - if (l < 0) { - l = 0; - r = src.w; - t = (src.h / 2) - - ((src.w * 3) / (4 * 2)); - b = (src.h / 2) - + ((src.w * 3) / (4 * 2)); - } - break; - case FULLSCR_SCALE_SQ:t = 0; - b = src.h; - l = (src.w / 2) - ((src.h * w) / (h * 2)); - r = (src.w / 2) + ((src.h * w) / (h * 2)); - if (l < 0) { - l = 0; - r = src.w; - t = (src.h / 2) - - ((src.w * h) / (w * 2)); - b = (src.h / 2) - + ((src.w * h) / (w * 2)); - } - break; - case FULLSCR_SCALE_INT:ratio_w = src.w / w; - ratio_h = src.h / h; - if (ratio_h < ratio_w) - ratio_w = ratio_h; - l = (src.w / 2) - ((w * ratio_w) / 2); - r = (src.w / 2) + ((w * ratio_w) / 2); - t = (src.h / 2) - ((h * ratio_w) / 2); - b = (src.h / 2) + ((h * ratio_w) / 2); - break; - case FULLSCR_SCALE_FULL: - default:l = 0; - t = 0; - r = src.w; - b = src.h; - break; - } + double t, b, l, r; + int ratio_w, ratio_h; + switch (scale) { + case FULLSCR_SCALE_43: + t = 0; + b = src.h; + l = (src.w / 2) - ((src.h * 4) / (3 * 2)); + r = (src.w / 2) + ((src.h * 4) / (3 * 2)); + if (l < 0) { + l = 0; + r = src.w; + t = (src.h / 2) - ((src.w * 3) / (4 * 2)); + b = (src.h / 2) + ((src.w * 3) / (4 * 2)); + } + break; + case FULLSCR_SCALE_SQ: + t = 0; + b = src.h; + l = (src.w / 2) - ((src.h * w) / (h * 2)); + r = (src.w / 2) + ((src.h * w) / (h * 2)); + if (l < 0) { + l = 0; + r = src.w; + t = (src.h / 2) - ((src.w * h) / (w * 2)); + b = (src.h / 2) + ((src.w * h) / (w * 2)); + } + break; + case FULLSCR_SCALE_INT: + ratio_w = src.w / w; + ratio_h = src.h / h; + if (ratio_h < ratio_w) + ratio_w = ratio_h; + l = (src.w / 2) - ((w * ratio_w) / 2); + r = (src.w / 2) + ((w * ratio_w) / 2); + t = (src.h / 2) - ((h * ratio_w) / 2); + b = (src.h / 2) + ((h * ratio_w) / 2); + break; + case FULLSCR_SCALE_FULL: + default: + l = 0; + t = 0; + r = src.w; + b = src.h; + break; + } - dst->x = l; - dst->y = t; - dst->w = r - l; - dst->h = b - t; + dst->x = l; + dst->y = t; + dst->w = r - l; + dst->h = b - t; } static void set_updated_size(int x, int y, int w, int h) { - if (updated) { - updated_rect.x = x < updated_rect.x ? x : updated_rect.x; - updated_rect.y = y < updated_rect.y ? y : updated_rect.y; - updated_rect.w = w > updated_rect.w ? w : updated_rect.w; - updated_rect.h = h > updated_rect.h ? h : updated_rect.h; - } else { - updated_rect.x = x; - updated_rect.y = y; - updated_rect.w = w; - updated_rect.h = h; - updated = 1; - } + if (updated) { + updated_rect.x = x < updated_rect.x ? x : updated_rect.x; + updated_rect.y = y < updated_rect.y ? y : updated_rect.y; + updated_rect.w = w > updated_rect.w ? w : updated_rect.w; + updated_rect.h = h > updated_rect.h ? h : updated_rect.h; + } else { + updated_rect.x = x; + updated_rect.y = y; + updated_rect.w = w; + updated_rect.h = h; + updated = 1; + } } static void sdl_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) { - if (y1 == y2) { - video_blit_complete(); - return; /*Nothing to do*/ - } + if (y1 == y2) { + video_blit_complete(); + return; /*Nothing to do*/ + } - int yy; - SDL_LockMutex(blitMutex); - for (yy = y1; yy < y2; yy++) { - if ((y + yy) >= 0 && (y + yy) < buffer32->h) - memcpy(screen->dat + (yy * screen->w * 4), - &(((uint32_t *)buffer32->line[y + yy])[x]), w * 4); - } - set_updated_size(0, y1, w, y2 - y1); -// set_updated_size(0, 0, w, h); - blit_rect.w = w; - blit_rect.h = h; - SDL_UnlockMutex(blitMutex); - video_blit_complete(); + int yy; + SDL_LockMutex(blitMutex); + for (yy = y1; yy < y2; yy++) { + if ((y + yy) >= 0 && (y + yy) < buffer32->h) + memcpy(screen->dat + (yy * screen->w * 4), &(((uint32_t *)buffer32->line[y + yy])[x]), w * 4); + } + set_updated_size(0, y1, w, y2 - y1); + // set_updated_size(0, 0, w, h); + blit_rect.w = w; + blit_rect.h = h; + SDL_UnlockMutex(blitMutex); + video_blit_complete(); } int sdl_is_fullscreen(SDL_Window *window) { - int flags = SDL_GetWindowFlags(window); - return (flags & SDL_WINDOW_FULLSCREEN) || (flags & SDL_WINDOW_FULLSCREEN_DESKTOP); + int flags = SDL_GetWindowFlags(window); + return (flags & SDL_WINDOW_FULLSCREEN) || (flags & SDL_WINDOW_FULLSCREEN_DESKTOP); } int sdl_video_init() { - blitMutex = SDL_CreateMutex(); - updated = 0; + blitMutex = SDL_CreateMutex(); + updated = 0; - video_blit_memtoscreen_func = sdl_blit_memtoscreen; - requested_render_driver = sdl_get_render_driver_by_id(RENDERER_AUTO, RENDERER_AUTO); + video_blit_memtoscreen_func = sdl_blit_memtoscreen; + requested_render_driver = sdl_get_render_driver_by_id(RENDERER_AUTO, RENDERER_AUTO); - screen_rect.w = screen_rect.h = 2048; + screen_rect.w = screen_rect.h = 2048; - screen = create_bitmap(screen_rect.w, screen_rect.h); + screen = create_bitmap(screen_rect.w, screen_rect.h); - return SDL_TRUE; + return SDL_TRUE; } void sdl_video_close() { - requested_render_driver.renderer_close(renderer); - renderer = NULL; - destroy_bitmap(screen); - screen = NULL; - SDL_DestroyMutex(blitMutex); + requested_render_driver.renderer_close(renderer); + renderer = NULL; + destroy_bitmap(screen); + screen = NULL; + SDL_DestroyMutex(blitMutex); } int sdl_renderer_init(SDL_Window *window) { - if (video_alternative_update_lock) - screen_copy = create_bitmap(screen_rect.w, screen_rect.h); - else - screen_copy = NULL; + if (video_alternative_update_lock) + screen_copy = create_bitmap(screen_rect.w, screen_rect.h); + else + screen_copy = NULL; - renderer = requested_render_driver.renderer_create(); - return renderer->init(window, requested_render_driver, screen_rect); + renderer = requested_render_driver.renderer_create(); + return renderer->init(window, requested_render_driver, screen_rect); } void sdl_renderer_close() { - if (renderer) - renderer->close(); - renderer = NULL; + if (renderer) + renderer->close(); + renderer = NULL; - if (screen_copy) - destroy_bitmap(screen_copy); - screen_copy = NULL; + if (screen_copy) + destroy_bitmap(screen_copy); + screen_copy = NULL; } int sdl_renderer_update(SDL_Window *window) { - int render = 0; - SDL_LockMutex(blitMutex); - if (updated) { - updated = 0; - if (screen_copy) { - memcpy(&updated_rect_copy, &updated_rect, sizeof(updated_rect)); - memcpy(screen_copy->dat + (updated_rect.y * screen_copy->w * 4), screen->dat + (updated_rect.y * screen->w * 4), updated_rect.h * screen->w * 4); - } else - renderer->update(window, updated_rect, screen); - texture_rect.w = blit_rect.w; - texture_rect.h = blit_rect.h; - render = 1; - } - SDL_UnlockMutex(blitMutex); - if (screen_copy && render) - renderer->update(window, updated_rect_copy, screen_copy); - return render || renderer->always_update; + int render = 0; + SDL_LockMutex(blitMutex); + if (updated) { + updated = 0; + if (screen_copy) { + memcpy(&updated_rect_copy, &updated_rect, sizeof(updated_rect)); + memcpy(screen_copy->dat + (updated_rect.y * screen_copy->w * 4), + screen->dat + (updated_rect.y * screen->w * 4), updated_rect.h * screen->w * 4); + } else + renderer->update(window, updated_rect, screen); + texture_rect.w = blit_rect.w; + texture_rect.h = blit_rect.h; + render = 1; + } + SDL_UnlockMutex(blitMutex); + if (screen_copy && render) + renderer->update(window, updated_rect_copy, screen_copy); + return render || renderer->always_update; } void sdl_renderer_present(SDL_Window *window) { - if (flash.enabled) { - int elapsed = SDL_GetTicks() - flash.start; - float a = flash.func(elapsed / (float)flash.time) * (flash.alpha & 0xff); - flash.color[3] = (char)a; - if (elapsed >= flash.time) - flash.enabled = 0; - } - - SDL_Rect wr; - SDL_GetWindowSize(window, &wr.w, &wr.h); - sdl_scale(video_fullscreen_scale, wr, &wr, texture_rect.w, texture_rect.h); - renderer->present(window, texture_rect, wr, screen_rect); + if (flash.enabled) { + int elapsed = SDL_GetTicks() - flash.start; + float a = flash.func(elapsed / (float)flash.time) * (flash.alpha & 0xff); + flash.color[3] = (char)a; + if (elapsed >= flash.time) + flash.enabled = 0; + } + SDL_Rect wr; + SDL_GetWindowSize(window, &wr.w, &wr.h); + sdl_scale(video_fullscreen_scale, wr, &wr, texture_rect.w, texture_rect.h); + renderer->present(window, texture_rect, wr, screen_rect); } void color_flash(FLASH_FUNC func, int time_ms, char r, char g, char b, char a) { - flash.func = func; - flash.color[0] = r; - flash.color[1] = g; - flash.color[2] = b; - flash.color[3] = 0; - flash.alpha = a; - flash.start = SDL_GetTicks(); - flash.time = time_ms; - flash.enabled = 1; + flash.func = func; + flash.color[0] = r; + flash.color[1] = g; + flash.color[2] = b; + flash.color[3] = 0; + flash.alpha = a; + flash.start = SDL_GetTicks(); + flash.time = time_ms; + flash.enabled = 1; } diff --git a/src/wx-ui/wx-sdl2.c b/src/wx-ui/wx-sdl2.c index cb8f3ed6..182b7fdd 100644 --- a/src/wx-ui/wx-sdl2.c +++ b/src/wx-ui/wx-sdl2.c @@ -128,857 +128,824 @@ int screenshot_flash = 1; int take_screenshot = 0; void updatewindowsize(int x, int y) { - if (video_width == x && video_height == y) { - return; - } - video_width = x; - video_height = y; + if (video_width == x && video_height == y) { + return; + } + video_width = x; + video_height = y; - display_resize(x, y); + display_resize(x, y); } -unsigned int get_ticks() { - return SDL_GetTicks(); -} +unsigned int get_ticks() { return SDL_GetTicks(); } -void delay_ms(unsigned int ms) { - SDL_Delay(ms); -} +void delay_ms(unsigned int ms) { SDL_Delay(ms); } -void startblit() { - SDL_LockMutex(ghMutex); -} +void startblit() { SDL_LockMutex(ghMutex); } -void endblit() { - SDL_UnlockMutex(ghMutex); -} +void endblit() { SDL_UnlockMutex(ghMutex); } -void enter_fullscreen() { - window_dofullscreen = window_doinputgrab = 1; -} +void enter_fullscreen() { window_dofullscreen = window_doinputgrab = 1; } -void leave_fullscreen() { - window_dowindowed = window_doinputrelease = 1; -} +void leave_fullscreen() { window_dowindowed = window_doinputrelease = 1; } -void toggle_fullscreen() { - window_dotogglefullscreen = 1; -} +void toggle_fullscreen() { window_dotogglefullscreen = 1; } uint64_t main_time; int mainthread(void *param) { - SDL_SetThreadPriority(SDL_THREAD_PRIORITY_HIGH); + SDL_SetThreadPriority(SDL_THREAD_PRIORITY_HIGH); - int frames = 0; - uint32_t old_time, new_time; + int frames = 0; + uint32_t old_time, new_time; - drawits = 0; - old_time = SDL_GetTicks(); - running = 1; - while (running) { - new_time = SDL_GetTicks(); - drawits += new_time - old_time; - old_time = new_time; + drawits = 0; + old_time = SDL_GetTicks(); + running = 1; + while (running) { + new_time = SDL_GetTicks(); + drawits += new_time - old_time; + old_time = new_time; - if (drawits > 0 && !pause) { - uint64_t start_time = timer_read(); - uint64_t end_time; - drawits -= 10; - if (drawits > 50) - drawits = 0; - runpc(); - frames++; - if (frames >= 200 && nvr_dosave) { - frames = 0; - nvr_dosave = 0; - savenvr(); - } - end_time = timer_read(); - main_time += end_time - start_time; - } else - SDL_Delay(1); - } + if (drawits > 0 && !pause) { + uint64_t start_time = timer_read(); + uint64_t end_time; + drawits -= 10; + if (drawits > 50) + drawits = 0; + runpc(); + frames++; + if (frames >= 200 && nvr_dosave) { + frames = 0; + nvr_dosave = 0; + savenvr(); + } + end_time = timer_read(); + main_time += end_time - start_time; + } else + SDL_Delay(1); + } - SDL_LockMutex(mainMutex); - SDL_CondSignal(mainCond); - SDL_UnlockMutex(mainMutex); + SDL_LockMutex(mainMutex); + SDL_CondSignal(mainCond); + SDL_UnlockMutex(mainMutex); - return TRUE; + return TRUE; } void stop_emulation_now(void) { - /*Deduct a sufficiently large number of cycles that no instructions will - run before the main thread is terminated*/ - cycles -= 99999999; - wx_stop_emulation_now(ghwnd); + /*Deduct a sufficiently large number of cycles that no instructions will + run before the main thread is terminated*/ + cycles -= 99999999; + wx_stop_emulation_now(ghwnd); } -void set_window_title(const char *s) { - sdl_set_window_title(s); -} +void set_window_title(const char *s) { sdl_set_window_title(s); } -float flash_func(float x) { - return 1 - pow(x, 4); -} +float flash_func(float x) { return 1 - pow(x, 4); } -float flash_failed_func(float x) { - return fabs(sin(x * 3.1415926 * 2)); -} +float flash_failed_func(float x) { return fabs(sin(x * 3.1415926 * 2)); } void screenshot_taken(unsigned char *rgb, int width, int height) { - char name[512]; - char date[128]; - strcpy(name, "Screenshot from "); - wx_date_format(date, "%Y-%m-%d %H-%M-%S"); - strcat(name, date); - if (wx_image_save(screenshots_path, name, screenshot_format, rgb, width, height, 0)) { - pclog("Screenshot saved\n"); - if (screenshot_flash) - color_flash(flash_func, 500, 0xff, 0xff, 0xff, 0xff); - } else { - pclog("Screenshot was not saved\n"); - if (screenshot_flash) - color_flash(flash_failed_func, 500, 0xff, 0, 0, 0xff); - } + char name[512]; + char date[128]; + strcpy(name, "Screenshot from "); + wx_date_format(date, "%Y-%m-%d %H-%M-%S"); + strcat(name, date); + if (wx_image_save(screenshots_path, name, screenshot_format, rgb, width, height, 0)) { + pclog("Screenshot saved\n"); + if (screenshot_flash) + color_flash(flash_func, 500, 0xff, 0xff, 0xff, 0xff); + } else { + pclog("Screenshot was not saved\n"); + if (screenshot_flash) + color_flash(flash_failed_func, 500, 0xff, 0, 0, 0xff); + } } -uint64_t timer_read() { - return SDL_GetPerformanceCounter(); -} +uint64_t timer_read() { return SDL_GetPerformanceCounter(); } Uint32 timer_onesec(Uint32 interval, void *param) { - onesec(); - return interval; + onesec(); + return interval; } void sdl_loadconfig() { - vid_resize = config_get_int(CFG_MACHINE, NULL, "vid_resize", 0); - video_fullscreen_scale = config_get_int(CFG_MACHINE, NULL, "video_fullscreen_scale", 0); - video_fullscreen_first = config_get_int(CFG_MACHINE, NULL, "video_fullscreen_first", 1); + vid_resize = config_get_int(CFG_MACHINE, NULL, "vid_resize", 0); + video_fullscreen_scale = config_get_int(CFG_MACHINE, NULL, "video_fullscreen_scale", 0); + video_fullscreen_first = config_get_int(CFG_MACHINE, NULL, "video_fullscreen_first", 1); - strcpy(screenshot_format, config_get_string(CFG_MACHINE, "SDL2", "screenshot_format", IMAGE_PNG)); - screenshot_flash = config_get_int(CFG_MACHINE, "SDL2", "screenshot_flash", 1); + strcpy(screenshot_format, config_get_string(CFG_MACHINE, "SDL2", "screenshot_format", IMAGE_PNG)); + screenshot_flash = config_get_int(CFG_MACHINE, "SDL2", "screenshot_flash", 1); - custom_resolution_width = config_get_int(CFG_MACHINE, "SDL2", "custom_width", custom_resolution_width); - custom_resolution_height = config_get_int(CFG_MACHINE, "SDL2", "custom_height", custom_resolution_height); + custom_resolution_width = config_get_int(CFG_MACHINE, "SDL2", "custom_width", custom_resolution_width); + custom_resolution_height = config_get_int(CFG_MACHINE, "SDL2", "custom_height", custom_resolution_height); - video_fullscreen = config_get_int(CFG_MACHINE, "SDL2", "fullscreen", video_fullscreen); - video_fullscreen_mode = config_get_int(CFG_MACHINE, "SDL2", "fullscreen_mode", video_fullscreen_mode); - video_scale = config_get_int(CFG_MACHINE, "SDL2", "scale", video_scale); - video_scale_mode = config_get_int(CFG_MACHINE, "SDL2", "scale_mode", video_scale_mode); - video_vsync = config_get_int(CFG_MACHINE, "SDL2", "vsync", video_vsync); - video_focus_dim = config_get_int(CFG_MACHINE, "SDL2", "focus_dim", video_focus_dim); - video_alternative_update_lock = config_get_int(CFG_MACHINE, "SDL2", "alternative_update_lock", video_alternative_update_lock); - requested_render_driver = sdl_get_render_driver_by_name(config_get_string(CFG_MACHINE, "SDL2", "render_driver", ""), RENDERER_SOFTWARE); + video_fullscreen = config_get_int(CFG_MACHINE, "SDL2", "fullscreen", video_fullscreen); + video_fullscreen_mode = config_get_int(CFG_MACHINE, "SDL2", "fullscreen_mode", video_fullscreen_mode); + video_scale = config_get_int(CFG_MACHINE, "SDL2", "scale", video_scale); + video_scale_mode = config_get_int(CFG_MACHINE, "SDL2", "scale_mode", video_scale_mode); + video_vsync = config_get_int(CFG_MACHINE, "SDL2", "vsync", video_vsync); + video_focus_dim = config_get_int(CFG_MACHINE, "SDL2", "focus_dim", video_focus_dim); + video_alternative_update_lock = + config_get_int(CFG_MACHINE, "SDL2", "alternative_update_lock", video_alternative_update_lock); + requested_render_driver = + sdl_get_render_driver_by_name(config_get_string(CFG_MACHINE, "SDL2", "render_driver", ""), RENDERER_SOFTWARE); - gl3_input_scale = config_get_float(CFG_MACHINE, "GL3", "input_scale", gl3_input_scale); - gl3_input_stretch = config_get_int(CFG_MACHINE, "GL3", "input_stretch", gl3_input_stretch); - gl3_shader_refresh_rate = config_get_float(CFG_MACHINE, "GL3", "shader_refresh_rate", gl3_shader_refresh_rate); + gl3_input_scale = config_get_float(CFG_MACHINE, "GL3", "input_scale", gl3_input_scale); + gl3_input_stretch = config_get_int(CFG_MACHINE, "GL3", "input_stretch", gl3_input_stretch); + gl3_shader_refresh_rate = config_get_float(CFG_MACHINE, "GL3", "shader_refresh_rate", gl3_shader_refresh_rate); - memset(&gl3_shader_file, 0, sizeof(gl3_shader_file)); - int num_shaders = config_get_int(CFG_MACHINE, "GL3 Shaders", "shaders", 0); - char s[20]; - int i; - for (i = 0; i < num_shaders; ++i) { - sprintf(s, "shader%d", i); - strncpy(gl3_shader_file[i], config_get_string(CFG_MACHINE, "GL3 Shaders", s, ""), 511); - gl3_shader_file[i][511] = 0; - } + memset(&gl3_shader_file, 0, sizeof(gl3_shader_file)); + int num_shaders = config_get_int(CFG_MACHINE, "GL3 Shaders", "shaders", 0); + char s[20]; + int i; + for (i = 0; i < num_shaders; ++i) { + sprintf(s, "shader%d", i); + strncpy(gl3_shader_file[i], config_get_string(CFG_MACHINE, "GL3 Shaders", s, ""), 511); + gl3_shader_file[i][511] = 0; + } } void sdl_saveconfig() { - config_set_int(CFG_MACHINE, NULL, "vid_resize", vid_resize); - config_set_int(CFG_MACHINE, NULL, "video_fullscreen_scale", video_fullscreen_scale); - config_set_int(CFG_MACHINE, NULL, "video_fullscreen_first", video_fullscreen_first); + config_set_int(CFG_MACHINE, NULL, "vid_resize", vid_resize); + config_set_int(CFG_MACHINE, NULL, "video_fullscreen_scale", video_fullscreen_scale); + config_set_int(CFG_MACHINE, NULL, "video_fullscreen_first", video_fullscreen_first); - config_set_string(CFG_MACHINE, "SDL2", "screenshot_format", screenshot_format); - config_set_int(CFG_MACHINE, "SDL2", "screenshot_flash", screenshot_flash); + config_set_string(CFG_MACHINE, "SDL2", "screenshot_format", screenshot_format); + config_set_int(CFG_MACHINE, "SDL2", "screenshot_flash", screenshot_flash); - config_set_int(CFG_MACHINE, "SDL2", "custom_width", custom_resolution_width); - config_set_int(CFG_MACHINE, "SDL2", "custom_height", custom_resolution_height); + config_set_int(CFG_MACHINE, "SDL2", "custom_width", custom_resolution_width); + config_set_int(CFG_MACHINE, "SDL2", "custom_height", custom_resolution_height); - config_set_int(CFG_MACHINE, "SDL2", "fullscreen", video_fullscreen); - config_set_int(CFG_MACHINE, "SDL2", "fullscreen_mode", video_fullscreen_mode); - config_set_int(CFG_MACHINE, "SDL2", "scale", video_scale); - config_set_int(CFG_MACHINE, "SDL2", "scale_mode", video_scale_mode); - config_set_int(CFG_MACHINE, "SDL2", "vsync", video_vsync); - config_set_int(CFG_MACHINE, "SDL2", "focus_dim", video_focus_dim); - config_set_int(CFG_MACHINE, "SDL2", "alternative_update_lock", video_alternative_update_lock); - config_set_string(CFG_MACHINE, "SDL2", "render_driver", (char *)requested_render_driver.sdl_id); + config_set_int(CFG_MACHINE, "SDL2", "fullscreen", video_fullscreen); + config_set_int(CFG_MACHINE, "SDL2", "fullscreen_mode", video_fullscreen_mode); + config_set_int(CFG_MACHINE, "SDL2", "scale", video_scale); + config_set_int(CFG_MACHINE, "SDL2", "scale_mode", video_scale_mode); + config_set_int(CFG_MACHINE, "SDL2", "vsync", video_vsync); + config_set_int(CFG_MACHINE, "SDL2", "focus_dim", video_focus_dim); + config_set_int(CFG_MACHINE, "SDL2", "alternative_update_lock", video_alternative_update_lock); + config_set_string(CFG_MACHINE, "SDL2", "render_driver", (char *)requested_render_driver.sdl_id); - config_set_float(CFG_MACHINE, "GL3", "input_scale", gl3_input_scale); - config_set_int(CFG_MACHINE, "GL3", "input_stretch", gl3_input_stretch); - config_set_float(CFG_MACHINE, "GL3", "shader_refresh_rate", gl3_shader_refresh_rate); + config_set_float(CFG_MACHINE, "GL3", "input_scale", gl3_input_scale); + config_set_int(CFG_MACHINE, "GL3", "input_stretch", gl3_input_stretch); + config_set_float(CFG_MACHINE, "GL3", "shader_refresh_rate", gl3_shader_refresh_rate); - char s[20]; - int i; - for (i = 0; i < 20; ++i) { - sprintf(s, "shader%d", i); - if (strlen(gl3_shader_file[i])) - config_set_string(CFG_MACHINE, "GL3 Shaders", s, gl3_shader_file[i]); - else - break; - } - config_set_int(CFG_MACHINE, "GL3 Shaders", "shaders", i); + char s[20]; + int i; + for (i = 0; i < 20; ++i) { + sprintf(s, "shader%d", i); + if (strlen(gl3_shader_file[i])) + config_set_string(CFG_MACHINE, "GL3 Shaders", s, gl3_shader_file[i]); + else + break; + } + config_set_int(CFG_MACHINE, "GL3 Shaders", "shaders", i); } void update_cdrom_menu(void *hmenu) { - if (cdrom_drive == CDROM_IMAGE) - wx_checkmenuitem(menu, WX_ID("IDM_CDROM_IMAGE"), WX_MB_CHECKED); - else if (cdrom_drive > 0) - wx_checkmenuitem(menu, IDM_CDROM_REAL + cdrom_drive, WX_MB_CHECKED); - else - wx_checkmenuitem(menu, WX_ID("IDM_CDROM_EMPTY"), WX_MB_CHECKED); + if (cdrom_drive == CDROM_IMAGE) + wx_checkmenuitem(menu, WX_ID("IDM_CDROM_IMAGE"), WX_MB_CHECKED); + else if (cdrom_drive > 0) + wx_checkmenuitem(menu, IDM_CDROM_REAL + cdrom_drive, WX_MB_CHECKED); + else + wx_checkmenuitem(menu, WX_ID("IDM_CDROM_EMPTY"), WX_MB_CHECKED); } void wx_initmenu() { - menu = wx_getmenu(ghwnd); + menu = wx_getmenu(ghwnd); - void *cdrom_submenu = wx_getsubmenu(menu, WX_ID("IDM_CDROM")); + void *cdrom_submenu = wx_getsubmenu(menu, WX_ID("IDM_CDROM")); #ifdef __WINDOWS__ - char s[32]; - int c; - /* Loop through each Windows drive letter and test to see if - it's a CDROM */ - for (c = 'A'; c <= 'Z'; c++) { - sprintf(s, "%c:\\", c); - if (GetDriveTypeA(s) == DRIVE_CDROM) { - sprintf(s, "Host CD/DVD Drive (%c:)", c); - wx_appendmenu(cdrom_submenu, IDM_CDROM_REAL + c, s, wxITEM_RADIO); - } - } + char s[32]; + int c; + /* Loop through each Windows drive letter and test to see if + it's a CDROM */ + for (c = 'A'; c <= 'Z'; c++) { + sprintf(s, "%c:\\", c); + if (GetDriveTypeA(s) == DRIVE_CDROM) { + sprintf(s, "Host CD/DVD Drive (%c:)", c); + wx_appendmenu(cdrom_submenu, IDM_CDROM_REAL + c, s, wxITEM_RADIO); + } + } #elif __linux__ - wx_appendmenu(cdrom_submenu, IDM_CDROM_REAL + 1, "Host CD/DVD Drive (/dev/cdrom)", wxITEM_RADIO); + wx_appendmenu(cdrom_submenu, IDM_CDROM_REAL + 1, "Host CD/DVD Drive (/dev/cdrom)", wxITEM_RADIO); #elif __APPLE__ - int c; + int c; - for (c = 1; c < 99; c++) - { - char s[80]; - int fd; + for (c = 1; c < 99; c++) { + char s[80]; + int fd; - sprintf(s, "disk%i", c); - fd = opendev(s, O_RDONLY, 0, NULL); - if (fd > 0) - { - char name[255]; + sprintf(s, "disk%i", c); + fd = opendev(s, O_RDONLY, 0, NULL); + if (fd > 0) { + char name[255]; - close(fd); + close(fd); - sprintf(name, "Host CD/DVD Drive (/dev/disk%i)", c); - wx_appendmenu(cdrom_submenu, IDM_CDROM_REAL + c, name, wxITEM_RADIO); - } - } + sprintf(name, "Host CD/DVD Drive (/dev/disk%i)", c); + wx_appendmenu(cdrom_submenu, IDM_CDROM_REAL + c, name, wxITEM_RADIO); + } + } #endif } int wx_setupmenu(void *data) { - int c; - update_cdrom_menu(menu); - sprintf(menuitem, "IDM_VID_RESOLUTION[%d]", vid_resize); - wx_checkmenuitem(menu, WX_ID(menuitem), WX_MB_CHECKED); - wx_enablemenuitem(menu, wx_xrcid("IDM_VID_SCALE_MENU"), !vid_resize); - sprintf(menuitem, "IDM_VID_FS[%d]", video_fullscreen_scale); - wx_checkmenuitem(menu, WX_ID(menuitem), WX_MB_CHECKED); - wx_checkmenuitem(menu, WX_ID("IDM_VID_FULLSCREEN"), video_fullscreen); - wx_checkmenuitem(menu, WX_ID("IDM_VID_REMEMBER"), - window_remember ? WX_MB_CHECKED : WX_MB_UNCHECKED); - wx_checkmenuitem(menu, WX_ID("IDM_BPB_DISABLE"), bpb_disable ? WX_MB_CHECKED : WX_MB_UNCHECKED); + int c; + update_cdrom_menu(menu); + sprintf(menuitem, "IDM_VID_RESOLUTION[%d]", vid_resize); + wx_checkmenuitem(menu, WX_ID(menuitem), WX_MB_CHECKED); + wx_enablemenuitem(menu, wx_xrcid("IDM_VID_SCALE_MENU"), !vid_resize); + sprintf(menuitem, "IDM_VID_FS[%d]", video_fullscreen_scale); + wx_checkmenuitem(menu, WX_ID(menuitem), WX_MB_CHECKED); + wx_checkmenuitem(menu, WX_ID("IDM_VID_FULLSCREEN"), video_fullscreen); + wx_checkmenuitem(menu, WX_ID("IDM_VID_REMEMBER"), window_remember ? WX_MB_CHECKED : WX_MB_UNCHECKED); + wx_checkmenuitem(menu, WX_ID("IDM_BPB_DISABLE"), bpb_disable ? WX_MB_CHECKED : WX_MB_UNCHECKED); - sprintf(menuitem, "IDM_SND_BUF[%d]", (int)(log(sound_buf_len / MIN_SND_BUF) / log(2))); - wx_checkmenuitem(menu, WX_ID(menuitem), WX_MB_CHECKED); + sprintf(menuitem, "IDM_SND_BUF[%d]", (int)(log(sound_buf_len / MIN_SND_BUF) / log(2))); + wx_checkmenuitem(menu, WX_ID(menuitem), WX_MB_CHECKED); - sprintf(menuitem, "IDM_SND_GAIN[%d]", (int)(sound_gain / 2)); - wx_checkmenuitem(menu, WX_ID(menuitem), WX_MB_CHECKED); + sprintf(menuitem, "IDM_SND_GAIN[%d]", (int)(sound_gain / 2)); + wx_checkmenuitem(menu, WX_ID(menuitem), WX_MB_CHECKED); - sprintf(menuitem, "IDM_VID_SCALE_MODE[%d]", video_scale_mode); - wx_checkmenuitem(menu, WX_ID(menuitem), WX_MB_CHECKED); - sprintf(menuitem, "IDM_VID_SCALE[%d]", video_scale); - wx_checkmenuitem(menu, WX_ID(menuitem), WX_MB_CHECKED); - sprintf(menuitem, "IDM_VID_FS_MODE[%d]", video_fullscreen_mode); - wx_checkmenuitem(menu, WX_ID(menuitem), WX_MB_CHECKED); - wx_checkmenuitem(menu, WX_ID("IDM_VID_VSYNC"), video_vsync); - wx_checkmenuitem(menu, WX_ID("IDM_VID_LOST_FOCUS_DIM"), video_focus_dim); - wx_checkmenuitem(menu, WX_ID("IDM_VID_ALTERNATIVE_UPDATE_LOCK"), video_alternative_update_lock); + sprintf(menuitem, "IDM_VID_SCALE_MODE[%d]", video_scale_mode); + wx_checkmenuitem(menu, WX_ID(menuitem), WX_MB_CHECKED); + sprintf(menuitem, "IDM_VID_SCALE[%d]", video_scale); + wx_checkmenuitem(menu, WX_ID(menuitem), WX_MB_CHECKED); + sprintf(menuitem, "IDM_VID_FS_MODE[%d]", video_fullscreen_mode); + wx_checkmenuitem(menu, WX_ID(menuitem), WX_MB_CHECKED); + wx_checkmenuitem(menu, WX_ID("IDM_VID_VSYNC"), video_vsync); + wx_checkmenuitem(menu, WX_ID("IDM_VID_LOST_FOCUS_DIM"), video_focus_dim); + wx_checkmenuitem(menu, WX_ID("IDM_VID_ALTERNATIVE_UPDATE_LOCK"), video_alternative_update_lock); - int format = 0; - if (!strcmp(screenshot_format, IMAGE_TIFF)) - format = 1; - else if (!strcmp(screenshot_format, IMAGE_BMP)) - format = 2; - else if (!strcmp(screenshot_format, IMAGE_JPG)) - format = 3; - sprintf(menuitem, "IDM_SCREENSHOT_FORMAT[%d]", format); - wx_checkmenuitem(menu, WX_ID(menuitem), WX_MB_CHECKED); - wx_checkmenuitem(menu, WX_ID("IDM_SCREENSHOT_FLASH"), screenshot_flash); + int format = 0; + if (!strcmp(screenshot_format, IMAGE_TIFF)) + format = 1; + else if (!strcmp(screenshot_format, IMAGE_BMP)) + format = 2; + else if (!strcmp(screenshot_format, IMAGE_JPG)) + format = 3; + sprintf(menuitem, "IDM_SCREENSHOT_FORMAT[%d]", format); + wx_checkmenuitem(menu, WX_ID(menuitem), WX_MB_CHECKED); + wx_checkmenuitem(menu, WX_ID("IDM_SCREENSHOT_FLASH"), screenshot_flash); - int num_renderers; - sdl_render_driver *drivers = sdl_get_render_drivers(&num_renderers); - for (c = 1; c < num_renderers; ++c) { - sprintf(menuitem, "IDM_VID_RENDER_DRIVER[%d]", drivers[c].id); - wx_enablemenuitem(menu, WX_ID(menuitem), drivers[c].renderer_available(&drivers[c])); - } - sprintf(menuitem, "IDM_VID_RENDER_DRIVER[%d]", requested_render_driver.id); - wx_checkmenuitem(menu, WX_ID(menuitem), WX_MB_CHECKED); + int num_renderers; + sdl_render_driver *drivers = sdl_get_render_drivers(&num_renderers); + for (c = 1; c < num_renderers; ++c) { + sprintf(menuitem, "IDM_VID_RENDER_DRIVER[%d]", drivers[c].id); + wx_enablemenuitem(menu, WX_ID(menuitem), drivers[c].renderer_available(&drivers[c])); + } + sprintf(menuitem, "IDM_VID_RENDER_DRIVER[%d]", requested_render_driver.id); + wx_checkmenuitem(menu, WX_ID(menuitem), WX_MB_CHECKED); - // wx_enablemenuitem(menu, WX_ID("IDM_VID_SDL2"), requested_render_driver.id != RENDERER_GL3); - wx_enablemenuitem(menu, WX_ID("IDM_VID_GL3"), requested_render_driver.id == RENDERER_GL3); + // wx_enablemenuitem(menu, WX_ID("IDM_VID_SDL2"), requested_render_driver.id != RENDERER_GL3); + wx_enablemenuitem(menu, WX_ID("IDM_VID_GL3"), requested_render_driver.id == RENDERER_GL3); - sprintf(menuitem, "IDM_VID_GL3_INPUT_STRETCH[%d]", gl3_input_stretch); - wx_checkmenuitem(menu, WX_ID(menuitem), WX_MB_CHECKED); - sprintf(menuitem, "IDM_VID_GL3_INPUT_SCALE[%d]", (int)((gl3_input_scale - 0.5) * 2)); - wx_checkmenuitem(menu, WX_ID(menuitem), WX_MB_CHECKED); - sprintf(menuitem, "IDM_VID_GL3_SHADER_REFRESH_RATE[%g]", gl3_shader_refresh_rate); - wx_checkmenuitem(menu, WX_ID(menuitem), WX_MB_CHECKED); + sprintf(menuitem, "IDM_VID_GL3_INPUT_STRETCH[%d]", gl3_input_stretch); + wx_checkmenuitem(menu, WX_ID(menuitem), WX_MB_CHECKED); + sprintf(menuitem, "IDM_VID_GL3_INPUT_SCALE[%d]", (int)((gl3_input_scale - 0.5) * 2)); + wx_checkmenuitem(menu, WX_ID(menuitem), WX_MB_CHECKED); + sprintf(menuitem, "IDM_VID_GL3_SHADER_REFRESH_RATE[%g]", gl3_shader_refresh_rate); + wx_checkmenuitem(menu, WX_ID(menuitem), WX_MB_CHECKED); - return 1; + return 1; } void sdl_onconfigloaded() { - if (ghwnd) - wx_callback(ghwnd, wx_setupmenu, 0); + if (ghwnd) + wx_callback(ghwnd, wx_setupmenu, 0); - /* create directories */ - if (!wx_dir_exists(configs_path)) - wx_create_directory(configs_path); - if (!wx_dir_exists(nvr_path)) - wx_create_directory(nvr_path); - if (!wx_dir_exists(logs_path)) - wx_create_directory(logs_path); - if (!wx_dir_exists(screenshots_path)) - wx_create_directory(screenshots_path); + /* create directories */ + if (!wx_dir_exists(configs_path)) + wx_create_directory(configs_path); + if (!wx_dir_exists(nvr_path)) + wx_create_directory(nvr_path); + if (!wx_dir_exists(logs_path)) + wx_create_directory(logs_path); + if (!wx_dir_exists(screenshots_path)) + wx_create_directory(screenshots_path); } extern void wx_loadconfig(); extern void wx_saveconfig(); int pc_main(int argc, char **argv) { - // Expose some functions to libpcem-plugin-api without moving them over to - // the plugin api proper - _savenvr = savenvr; - _dumppic = dumppic; - _dumpregs = dumpregs; - _sound_speed_changed = sound_speed_changed; + // Expose some functions to libpcem-plugin-api without moving them over to + // the plugin api proper + _savenvr = savenvr; + _dumppic = dumppic; + _dumpregs = dumpregs; + _sound_speed_changed = sound_speed_changed; - paths_init(); + paths_init(); - init_plugin_engine(); - model_init_builtin(); - video_init_builtin(); - lpt_init_builtin(); - sound_init_builtin(); - hdd_controller_init_builtin(); + init_plugin_engine(); + model_init_builtin(); + video_init_builtin(); + lpt_init_builtin(); + sound_init_builtin(); + hdd_controller_init_builtin(); #ifdef USE_NETWORKING - network_card_init_builtin(); + network_card_init_builtin(); #endif - add_config_callback(sdl_loadconfig, sdl_saveconfig, sdl_onconfigloaded); - add_config_callback(wx_loadconfig, wx_saveconfig, 0); + add_config_callback(sdl_loadconfig, sdl_saveconfig, sdl_onconfigloaded); + add_config_callback(wx_loadconfig, wx_saveconfig, 0); - initpc(argc, argv); - resetpchard(); + initpc(argc, argv); + resetpchard(); - sound_init(); + sound_init(); #ifndef __APPLE__ - display_init(); + display_init(); #endif - sdl_video_init(); - joystick_init(); + sdl_video_init(); + joystick_init(); - return TRUE; + return TRUE; } int wx_load_config(void *hwnd) { - if (!config_override) { - if (!config_selection_open(NULL, 0)) - return FALSE; - } + if (!config_override) { + if (!config_selection_open(NULL, 0)) + return FALSE; + } - return TRUE; + return TRUE; } int wx_start(void *hwnd) { - int c, d; - ghwnd = hwnd; + int c, d; + ghwnd = hwnd; #ifdef __APPLE__ - /* OSX requires SDL to be initialized after wxWidgets. */ - display_init(); + /* OSX requires SDL to be initialized after wxWidgets. */ + display_init(); #endif - readflash = 0; + readflash = 0; - wx_initmenu(); - wx_setupmenu(0); + wx_initmenu(); + wx_setupmenu(0); - d = romset; - for (c = 0; c < ROM_MAX; c++) { - romset = c; - romspresent[c] = loadbios(); - pclog("romset %i - %i\n", c, romspresent[c]); - } + d = romset; + for (c = 0; c < ROM_MAX; c++) { + romset = c; + romspresent[c] = loadbios(); + pclog("romset %i - %i\n", c, romspresent[c]); + } - for (c = 0; c < ROM_MAX; c++) { - if (romspresent[c]) - break; - } - if (c == ROM_MAX) { - wx_messagebox(hwnd, - "No ROMs present!\nYou must have at least one romset to use PCem.", - "PCem fatal error", WX_MB_OK); - return 0; - } + for (c = 0; c < ROM_MAX; c++) { + if (romspresent[c]) + break; + } + if (c == ROM_MAX) { + wx_messagebox(hwnd, "No ROMs present!\nYou must have at least one romset to use PCem.", "PCem fatal error", + WX_MB_OK); + return 0; + } - romset = d; - for (c = 0; c < GFX_MAX; c++) - gfx_present[c] = video_card_available(video_old_to_new(c)); + romset = d; + for (c = 0; c < GFX_MAX; c++) + gfx_present[c] = video_card_available(video_old_to_new(c)); - return TRUE; + return TRUE; } int resume_emulation() { - if (emulation_state == EMULATION_PAUSED) { - emulation_state = EMULATION_RUNNING; - pause = 0; - return TRUE; - } - return FALSE; + if (emulation_state == EMULATION_PAUSED) { + emulation_state = EMULATION_RUNNING; + pause = 0; + return TRUE; + } + return FALSE; } int start_emulation(void *params) { - if (resume_emulation()) - return TRUE; - int c; - pclog("Starting emulation...\n"); - loadconfig(NULL); + if (resume_emulation()) + return TRUE; + int c; + pclog("Starting emulation...\n"); + loadconfig(NULL); - emulation_state = EMULATION_RUNNING; - pause = 0; + emulation_state = EMULATION_RUNNING; + pause = 0; - ghMutex = SDL_CreateMutex(); - mainMutex = SDL_CreateMutex(); - mainCond = SDL_CreateCond(); + ghMutex = SDL_CreateMutex(); + mainMutex = SDL_CreateMutex(); + mainCond = SDL_CreateCond(); - if (!loadbios()) { - if (romset != -1) - wx_messagebox(ghwnd, - "Configured romset not available.\nDefaulting to available romset.", - "PCem error", WX_MB_OK); - for (c = 0; c < ROM_MAX; c++) { - if (romspresent[c]) { - romset = c; - model = model_getmodel(romset); - break; - } - } - } + if (!loadbios()) { + if (romset != -1) + wx_messagebox(ghwnd, "Configured romset not available.\nDefaulting to available romset.", "PCem error", + WX_MB_OK); + for (c = 0; c < ROM_MAX; c++) { + if (romspresent[c]) { + romset = c; + model = model_getmodel(romset); + break; + } + } + } - if (!video_card_available(video_old_to_new(gfxcard))) { - if (romset != -1) - wx_messagebox(ghwnd, - "Configured video BIOS not available.\nDefaulting to available romset.", - "PCem error", WX_MB_OK); - for (c = GFX_MAX - 1; c >= 0; c--) { - if (gfx_present[c]) { - gfxcard = c; - break; - } - } - } + if (!video_card_available(video_old_to_new(gfxcard))) { + if (romset != -1) + wx_messagebox(ghwnd, "Configured video BIOS not available.\nDefaulting to available romset.", + "PCem error", WX_MB_OK); + for (c = GFX_MAX - 1; c >= 0; c--) { + if (gfx_present[c]) { + gfxcard = c; + break; + } + } + } - loadbios(); - resetpchard(); - midi_init(); + loadbios(); + resetpchard(); + midi_init(); - display_start(params); - mainthreadh = SDL_CreateThread(mainthread, "Main Thread", NULL); + display_start(params); + mainthreadh = SDL_CreateThread(mainthread, "Main Thread", NULL); - onesectimer = SDL_AddTimer(1000, timer_onesec, NULL); + onesectimer = SDL_AddTimer(1000, timer_onesec, NULL); - updatewindowsize(640, 480); + updatewindowsize(640, 480); - timer_freq = SDL_GetPerformanceFrequency(); + timer_freq = SDL_GetPerformanceFrequency(); - if (show_machine_on_start) - wx_show_status(ghwnd); + if (show_machine_on_start) + wx_show_status(ghwnd); - return TRUE; + return TRUE; } int pause_emulation() { - pclog("Emulation paused.\n"); - emulation_state = EMULATION_PAUSED; - pause = 1; - return TRUE; + pclog("Emulation paused.\n"); + emulation_state = EMULATION_PAUSED; + pause = 1; + return TRUE; } int stop_emulation() { - emulation_state = EMULATION_STOPPED; - pclog("Stopping emulation...\n"); - SDL_LockMutex(mainMutex); - running = 0; - SDL_CondWaitTimeout(mainCond, mainMutex, 10 * 1000); - SDL_UnlockMutex(mainMutex); + emulation_state = EMULATION_STOPPED; + pclog("Stopping emulation...\n"); + SDL_LockMutex(mainMutex); + running = 0; + SDL_CondWaitTimeout(mainCond, mainMutex, 10 * 1000); + SDL_UnlockMutex(mainMutex); - SDL_DestroyCond(mainCond); - SDL_DestroyMutex(mainMutex); + SDL_DestroyCond(mainCond); + SDL_DestroyMutex(mainMutex); - startblit(); - display_stop(); + startblit(); + display_stop(); #if SDL_VERSION_ATLEAST(2, 0, 2) - SDL_DetachThread(mainthreadh); + SDL_DetachThread(mainthreadh); #endif - mainthreadh = NULL; - SDL_RemoveTimer(onesectimer); - savenvr(); - saveconfig(NULL); + mainthreadh = NULL; + SDL_RemoveTimer(onesectimer); + savenvr(); + saveconfig(NULL); - endblit(); - SDL_DestroyMutex(ghMutex); + endblit(); + SDL_DestroyMutex(ghMutex); - device_close_all(); - midi_close(); + device_close_all(); + midi_close(); - pclog("Emulation stopped.\n"); + pclog("Emulation stopped.\n"); - wx_close_status(ghwnd); + wx_close_status(ghwnd); - return TRUE; + return TRUE; } void reset_emulation() { - pause_emulation(); - SDL_Delay(100); - resetpchard(); - resume_emulation(); + pause_emulation(); + SDL_Delay(100); + resetpchard(); + resume_emulation(); } int wx_stop() { - pclog("Shutting down...\n"); - closepc(); - display_close(); - sdl_video_close(); + pclog("Shutting down...\n"); + closepc(); + display_close(); + sdl_video_close(); - printf("Shut down successfully!\n"); - return TRUE; + printf("Shut down successfully!\n"); + return TRUE; } char openfilestring[260]; int getfile(void *hwnd, char *f, char *fn) { - int ret = wx_filedialog(hwnd, "Open", fn, f, 0, 1, openfilestring); + int ret = wx_filedialog(hwnd, "Open", fn, f, 0, 1, openfilestring); #ifdef __APPLE__ - /* wxWidgets on OSX may mess up the SDL-window somehow, so just in case we reset it here */ - window_doreset = 1; + /* wxWidgets on OSX may mess up the SDL-window somehow, so just in case we reset it here */ + window_doreset = 1; #endif - return ret; + return ret; } int getsfile(void *hwnd, char *f, char *fn, char *dir, char *ext) { - int ret = wx_filedialog(hwnd, "Save", dir, f, ext, 0, openfilestring); + int ret = wx_filedialog(hwnd, "Save", dir, f, ext, 0, openfilestring); #ifdef __APPLE__ - window_doreset = 1; + window_doreset = 1; #endif - return ret; + return ret; } int getfilewithcaption(void *hwnd, char *f, char *fn, char *caption) { - int ret = wx_filedialog(hwnd, caption, fn, f, 0, 1, openfilestring); + int ret = wx_filedialog(hwnd, caption, fn, f, 0, 1, openfilestring); #ifdef __APPLE__ - /* wxWidgets on OSX may mess up the SDL-window somehow, so just in case we reset it here */ - window_doreset = 1; + /* wxWidgets on OSX may mess up the SDL-window somehow, so just in case we reset it here */ + window_doreset = 1; #endif - return ret; + return ret; } void atapi_close(void) { - switch (cdrom_drive) { - case CDROM_IMAGE:image_close(); - break; - default:ioctl_close(); - break; - } + switch (cdrom_drive) { + case CDROM_IMAGE: + image_close(); + break; + default: + ioctl_close(); + break; + } } int custom_resolution_callback(void *window, int message, INT_PARAM wParam, LONG_PARAM lParam) { - switch (message) { - case WX_INITDIALOG: { - wx_sendmessage(wx_getdlgitem(window, wx_xrcid("IDC_WIDTH")), WX_UDM_SETPOS, 0, custom_resolution_width); - wx_sendmessage(wx_getdlgitem(window, wx_xrcid("IDC_HEIGHT")), WX_UDM_SETPOS, 0, custom_resolution_height); - return TRUE; - } - case WX_COMMAND: { - if (wParam == wxID_OK) { - custom_resolution_width = wx_sendmessage(wx_getdlgitem(window, wx_xrcid("IDC_WIDTH")), WX_UDM_GETPOS, 0, 0); - custom_resolution_height = wx_sendmessage(wx_getdlgitem(window, wx_xrcid("IDC_HEIGHT")), WX_UDM_GETPOS, 0, 0); - wx_enddialog(window, 1); - return TRUE; - } else if (wParam == wxID_CANCEL) { - wx_enddialog(window, 0); - return TRUE; - } - } - } - return 0; + switch (message) { + case WX_INITDIALOG: { + wx_sendmessage(wx_getdlgitem(window, wx_xrcid("IDC_WIDTH")), WX_UDM_SETPOS, 0, custom_resolution_width); + wx_sendmessage(wx_getdlgitem(window, wx_xrcid("IDC_HEIGHT")), WX_UDM_SETPOS, 0, custom_resolution_height); + return TRUE; + } + case WX_COMMAND: { + if (wParam == wxID_OK) { + custom_resolution_width = + wx_sendmessage(wx_getdlgitem(window, wx_xrcid("IDC_WIDTH")), WX_UDM_GETPOS, 0, 0); + custom_resolution_height = + wx_sendmessage(wx_getdlgitem(window, wx_xrcid("IDC_HEIGHT")), WX_UDM_GETPOS, 0, 0); + wx_enddialog(window, 1); + return TRUE; + } else if (wParam == wxID_CANCEL) { + wx_enddialog(window, 0); + return TRUE; + } + } + } + return 0; } int wx_handle_command(void *hwnd, int wParam, int checked) { - void *hmenu; - char temp_image_path[1024]; - int new_cdrom_drive; - hmenu = wx_getmenu(hwnd); + void *hmenu; + char temp_image_path[1024]; + int new_cdrom_drive; + hmenu = wx_getmenu(hwnd); - if (ID_IS("IDM_STATUS")) { - wx_show_status(hwnd); - } else if (ID_IS("IDM_FILE_RESET")) { - pause = 1; - SDL_Delay(100); - savenvr(); - resetpc(); - pause = 0; - } else if (ID_IS("IDM_FILE_HRESET")) { - pause = 1; - SDL_Delay(100); - savenvr(); - resetpchard(); - pause = 0; - } else if (ID_IS("IDM_FILE_RESET_CAD")) { - pause = 1; - SDL_Delay(100); - savenvr(); - resetpc_cad(); - pause = 0; - } else if (ID_IS("IDM_FILE_EXIT")) { - // wx_exit(hwnd, 0); - wx_stop_emulation(hwnd); - } else if (ID_IS("IDM_DISC_A")) { - if (!getfile(hwnd, - "Disc image (*.img;*.ima;*.fdi)|*.img;*.ima;*.fdi|All files (*.*)|*.*", - discfns[0])) { - disc_close(0); - disc_load(0, openfilestring); - saveconfig(NULL); - } - } else if (ID_IS("IDM_DISC_B")) { - if (!getfile(hwnd, - "Disc image (*.img;*.ima;*.fdi)|*.img;*.ima;*.fdi|All files (*.*)|*.*", - discfns[1])) { - disc_close(1); - disc_load(1, openfilestring); - saveconfig(NULL); - } - } else if (ID_IS("IDM_EJECT_A")) { - disc_close(0); - saveconfig(NULL); - } else if (ID_IS("IDM_EJECT_B")) { - disc_close(1); - saveconfig(NULL); - } else if (ID_IS("IDM_BPB_DISABLE")) { - bpb_disable = !bpb_disable; - wx_checkmenuitem(hmenu, wParam, bpb_disable); - saveconfig(NULL); - } else if (ID_IS("IDM_DISC_CREATE")) { - creatediscimage_open(hwnd); - } else if (ID_IS("IDM_DISC_ZIP")) { - char zip_fn[256] = ""; + if (ID_IS("IDM_STATUS")) { + wx_show_status(hwnd); + } else if (ID_IS("IDM_FILE_RESET")) { + pause = 1; + SDL_Delay(100); + savenvr(); + resetpc(); + pause = 0; + } else if (ID_IS("IDM_FILE_HRESET")) { + pause = 1; + SDL_Delay(100); + savenvr(); + resetpchard(); + pause = 0; + } else if (ID_IS("IDM_FILE_RESET_CAD")) { + pause = 1; + SDL_Delay(100); + savenvr(); + resetpc_cad(); + pause = 0; + } else if (ID_IS("IDM_FILE_EXIT")) { + // wx_exit(hwnd, 0); + wx_stop_emulation(hwnd); + } else if (ID_IS("IDM_DISC_A")) { + if (!getfile(hwnd, "Disc image (*.img;*.ima;*.fdi)|*.img;*.ima;*.fdi|All files (*.*)|*.*", discfns[0])) { + disc_close(0); + disc_load(0, openfilestring); + saveconfig(NULL); + } + } else if (ID_IS("IDM_DISC_B")) { + if (!getfile(hwnd, "Disc image (*.img;*.ima;*.fdi)|*.img;*.ima;*.fdi|All files (*.*)|*.*", discfns[1])) { + disc_close(1); + disc_load(1, openfilestring); + saveconfig(NULL); + } + } else if (ID_IS("IDM_EJECT_A")) { + disc_close(0); + saveconfig(NULL); + } else if (ID_IS("IDM_EJECT_B")) { + disc_close(1); + saveconfig(NULL); + } else if (ID_IS("IDM_BPB_DISABLE")) { + bpb_disable = !bpb_disable; + wx_checkmenuitem(hmenu, wParam, bpb_disable); + saveconfig(NULL); + } else if (ID_IS("IDM_DISC_CREATE")) { + creatediscimage_open(hwnd); + } else if (ID_IS("IDM_DISC_ZIP")) { + char zip_fn[256] = ""; - if (!getfile(hwnd, - "Disc image (*.img)|*.img|All files (*.*)|*.*", - zip_fn)) { - zip_load(openfilestring); - } - } else if (ID_IS("IDM_EJECT_ZIP")) { - zip_eject(); - } else if (ID_IS("IDM_CASSETTE_LOAD")) { - if (!getfile(hwnd, - "Tape image (*.pzxi;*.pzx)|*.pzxi;*.pzx|All files (*.*)|*.*", - cassettefn)) { - cassette_eject(); - cassette_load(openfilestring); - saveconfig(NULL); - } - } else if (ID_IS("IDM_CASSETTE_EJECT")) { - cassette_eject(); - saveconfig(NULL); - } else if (ID_IS("IDM_MACHINE_TOGGLE")) { - if (emulation_state != EMULATION_STOPPED) - wx_togglewindow(hwnd); - } else if (ID_RANGE("IDM_VID_RESOLUTION[start]", "IDM_VID_RESOLUTION[end]")) { - vid_resize = wParam - wx_xrcid("IDM_VID_RESOLUTION[start]"); - wx_checkmenuitem(hmenu, wParam, WX_MB_CHECKED); - window_dosetresize = 1; - wx_enablemenuitem(hmenu, wx_xrcid("IDM_VID_SCALE_MENU"), !vid_resize); - saveconfig(NULL); - } else if (ID_IS("IDM_VID_RESOLUTION_CUSTOM")) { - if (wx_dialogbox(hwnd, "CustomResolutionDlg", custom_resolution_callback)) { - if (vid_resize != 2) { - vid_resize = 2; - wx_checkmenuitem(hmenu, wx_xrcid("IDM_VID_RESOLUTION[2]"), WX_MB_CHECKED); - wx_enablemenuitem(hmenu, wx_xrcid("IDM_VID_SCALE_MENU"), !vid_resize); - } - window_dosetresize = 1; - } - } else if (ID_IS("IDM_SCREENSHOT")) { - take_screenshot = 1; - } else if (ID_RANGE("IDM_SCREENSHOT_FORMAT[start]", "IDM_SCREENSHOT_FORMAT[end]")) { - int format = wParam - wx_xrcid("IDM_SCREENSHOT_FORMAT[start]"); - if (format == 0) - strcpy(screenshot_format, IMAGE_PNG); - else if (format == 1) - strcpy(screenshot_format, IMAGE_TIFF); - else if (format == 2) - strcpy(screenshot_format, IMAGE_BMP); - else if (format == 3) - strcpy(screenshot_format, IMAGE_JPG); - saveconfig(NULL); - wx_checkmenuitem(hmenu, wParam, WX_MB_CHECKED); - } else if (ID_IS("IDM_SCREENSHOT_FLASH")) { - screenshot_flash = !screenshot_flash; - wx_checkmenuitem(hmenu, wParam, screenshot_flash); - saveconfig(NULL); - } else if (ID_IS("IDM_VID_REMEMBER")) { - window_remember = !window_remember; - wx_checkmenuitem(hmenu, WX_ID("IDM_VID_REMEMBER"), - window_remember ? WX_MB_CHECKED : WX_MB_UNCHECKED); - window_doremember = 1; - saveconfig(NULL); - } else if (ID_IS("IDM_VID_FULLSCREEN")) { - if (video_fullscreen_first) { - video_fullscreen_first = 0; - wx_messagebox(hwnd, - "Use CTRL + ALT + PAGE DOWN to return to windowed mode", - "PCem", WX_MB_OK); - } - video_fullscreen = !video_fullscreen; - wx_checkmenuitem(hmenu, wParam, video_fullscreen); - saveconfig(NULL); - } else if (ID_IS("IDM_VID_FULLSCREEN_TOGGLE")) { - toggle_fullscreen(); - } else if (ID_RANGE("IDM_VID_FS[start]", "IDM_VID_FS[end]")) { - video_fullscreen_scale = wParam - wx_xrcid("IDM_VID_FS[start]"); - display_resize(video_width, video_height); - wx_checkmenuitem(hmenu, wParam, WX_MB_CHECKED); - saveconfig(NULL); - } else if (ID_RANGE("IDM_VID_SCALE_MODE[start]", "IDM_VID_SCALE_MODE[end]")) { - video_scale_mode = wParam - wx_xrcid("IDM_VID_SCALE_MODE[start]"); - renderer_doreset = 1; - wx_checkmenuitem(hmenu, wParam, WX_MB_CHECKED); - saveconfig(NULL); - } else if (ID_RANGE("IDM_VID_SCALE[start]", "IDM_VID_SCALE[end]")) { - video_scale = wParam - wx_xrcid("IDM_VID_SCALE[start]"); - wx_checkmenuitem(hmenu, wParam, WX_MB_CHECKED); - display_resize(video_width, video_height); - saveconfig(NULL); - } else if (ID_RANGE("IDM_VID_FS_MODE[start]", "IDM_VID_FS_MODE[end]")) { - video_fullscreen_mode = wParam - wx_xrcid("IDM_VID_FS_MODE[start]"); - wx_checkmenuitem(hmenu, wParam, WX_MB_CHECKED); - saveconfig(NULL); - } else if (ID_RANGE("IDM_VID_RENDER_DRIVER[start]", "IDM_VID_RENDER_DRIVER[end]")) { - requested_render_driver = sdl_get_render_driver_by_id(wParam - wx_xrcid("IDM_VID_RENDER_DRIVER[start]"), RENDERER_AUTO); - window_doreset = 1; + if (!getfile(hwnd, "Disc image (*.img)|*.img|All files (*.*)|*.*", zip_fn)) { + zip_load(openfilestring); + } + } else if (ID_IS("IDM_EJECT_ZIP")) { + zip_eject(); + } else if (ID_IS("IDM_CASSETTE_LOAD")) { + if (!getfile(hwnd, "Tape image (*.pzxi;*.pzx)|*.pzxi;*.pzx|All files (*.*)|*.*", cassettefn)) { + cassette_eject(); + cassette_load(openfilestring); + saveconfig(NULL); + } + } else if (ID_IS("IDM_CASSETTE_EJECT")) { + cassette_eject(); + saveconfig(NULL); + } else if (ID_IS("IDM_MACHINE_TOGGLE")) { + if (emulation_state != EMULATION_STOPPED) + wx_togglewindow(hwnd); + } else if (ID_RANGE("IDM_VID_RESOLUTION[start]", "IDM_VID_RESOLUTION[end]")) { + vid_resize = wParam - wx_xrcid("IDM_VID_RESOLUTION[start]"); + wx_checkmenuitem(hmenu, wParam, WX_MB_CHECKED); + window_dosetresize = 1; + wx_enablemenuitem(hmenu, wx_xrcid("IDM_VID_SCALE_MENU"), !vid_resize); + saveconfig(NULL); + } else if (ID_IS("IDM_VID_RESOLUTION_CUSTOM")) { + if (wx_dialogbox(hwnd, "CustomResolutionDlg", custom_resolution_callback)) { + if (vid_resize != 2) { + vid_resize = 2; + wx_checkmenuitem(hmenu, wx_xrcid("IDM_VID_RESOLUTION[2]"), WX_MB_CHECKED); + wx_enablemenuitem(hmenu, wx_xrcid("IDM_VID_SCALE_MENU"), !vid_resize); + } + window_dosetresize = 1; + } + } else if (ID_IS("IDM_SCREENSHOT")) { + take_screenshot = 1; + } else if (ID_RANGE("IDM_SCREENSHOT_FORMAT[start]", "IDM_SCREENSHOT_FORMAT[end]")) { + int format = wParam - wx_xrcid("IDM_SCREENSHOT_FORMAT[start]"); + if (format == 0) + strcpy(screenshot_format, IMAGE_PNG); + else if (format == 1) + strcpy(screenshot_format, IMAGE_TIFF); + else if (format == 2) + strcpy(screenshot_format, IMAGE_BMP); + else if (format == 3) + strcpy(screenshot_format, IMAGE_JPG); + saveconfig(NULL); + wx_checkmenuitem(hmenu, wParam, WX_MB_CHECKED); + } else if (ID_IS("IDM_SCREENSHOT_FLASH")) { + screenshot_flash = !screenshot_flash; + wx_checkmenuitem(hmenu, wParam, screenshot_flash); + saveconfig(NULL); + } else if (ID_IS("IDM_VID_REMEMBER")) { + window_remember = !window_remember; + wx_checkmenuitem(hmenu, WX_ID("IDM_VID_REMEMBER"), window_remember ? WX_MB_CHECKED : WX_MB_UNCHECKED); + window_doremember = 1; + saveconfig(NULL); + } else if (ID_IS("IDM_VID_FULLSCREEN")) { + if (video_fullscreen_first) { + video_fullscreen_first = 0; + wx_messagebox(hwnd, "Use CTRL + ALT + PAGE DOWN to return to windowed mode", "PCem", WX_MB_OK); + } + video_fullscreen = !video_fullscreen; + wx_checkmenuitem(hmenu, wParam, video_fullscreen); + saveconfig(NULL); + } else if (ID_IS("IDM_VID_FULLSCREEN_TOGGLE")) { + toggle_fullscreen(); + } else if (ID_RANGE("IDM_VID_FS[start]", "IDM_VID_FS[end]")) { + video_fullscreen_scale = wParam - wx_xrcid("IDM_VID_FS[start]"); + display_resize(video_width, video_height); + wx_checkmenuitem(hmenu, wParam, WX_MB_CHECKED); + saveconfig(NULL); + } else if (ID_RANGE("IDM_VID_SCALE_MODE[start]", "IDM_VID_SCALE_MODE[end]")) { + video_scale_mode = wParam - wx_xrcid("IDM_VID_SCALE_MODE[start]"); + renderer_doreset = 1; + wx_checkmenuitem(hmenu, wParam, WX_MB_CHECKED); + saveconfig(NULL); + } else if (ID_RANGE("IDM_VID_SCALE[start]", "IDM_VID_SCALE[end]")) { + video_scale = wParam - wx_xrcid("IDM_VID_SCALE[start]"); + wx_checkmenuitem(hmenu, wParam, WX_MB_CHECKED); + display_resize(video_width, video_height); + saveconfig(NULL); + } else if (ID_RANGE("IDM_VID_FS_MODE[start]", "IDM_VID_FS_MODE[end]")) { + video_fullscreen_mode = wParam - wx_xrcid("IDM_VID_FS_MODE[start]"); + wx_checkmenuitem(hmenu, wParam, WX_MB_CHECKED); + saveconfig(NULL); + } else if (ID_RANGE("IDM_VID_RENDER_DRIVER[start]", "IDM_VID_RENDER_DRIVER[end]")) { + requested_render_driver = + sdl_get_render_driver_by_id(wParam - wx_xrcid("IDM_VID_RENDER_DRIVER[start]"), RENDERER_AUTO); + window_doreset = 1; - /* update enabled menu-items */ - // wx_enablemenuitem(menu, WX_ID("IDM_VID_SDL2"), requested_render_driver.id != RENDERER_GL3); - wx_enablemenuitem(menu, WX_ID("IDM_VID_GL3"), requested_render_driver.id == RENDERER_GL3); + /* update enabled menu-items */ + // wx_enablemenuitem(menu, WX_ID("IDM_VID_SDL2"), requested_render_driver.id != RENDERER_GL3); + wx_enablemenuitem(menu, WX_ID("IDM_VID_GL3"), requested_render_driver.id == RENDERER_GL3); - wx_checkmenuitem(hmenu, wParam, WX_MB_CHECKED); - saveconfig(NULL); - } else if (ID_IS("IDM_VID_VSYNC")) { - video_vsync = !video_vsync; - wx_checkmenuitem(menu, wParam, video_vsync); - renderer_doreset = 1; - saveconfig(NULL); - } else if (ID_IS("IDM_VID_LOST_FOCUS_DIM")) { - video_focus_dim = !video_focus_dim; - wx_checkmenuitem(menu, wParam, video_focus_dim); - saveconfig(NULL); - } else if (ID_IS("IDM_VID_ALTERNATIVE_UPDATE_LOCK")) { - video_alternative_update_lock = !video_alternative_update_lock; - wx_checkmenuitem(menu, wParam, video_alternative_update_lock); - renderer_doreset = 1; - saveconfig(NULL); - } else if (ID_RANGE("IDM_VID_GL3_INPUT_STRETCH[start]", "IDM_VID_GL3_INPUT_STRETCH[end]")) { - gl3_input_stretch = wParam - wx_xrcid("IDM_VID_GL3_INPUT_STRETCH[start]"); - wx_checkmenuitem(menu, wParam, WX_MB_CHECKED); - saveconfig(NULL); - } else if (ID_RANGE("IDM_VID_GL3_INPUT_SCALE[start]", "IDM_VID_GL3_INPUT_SCALE[end]")) { - int input_scale = wParam - wx_xrcid("IDM_VID_GL3_INPUT_SCALE[start]"); - gl3_input_scale = input_scale / 2.0f + 0.5f; - wx_checkmenuitem(menu, wParam, WX_MB_CHECKED); - saveconfig(NULL); - } else if (ID_RANGE("IDM_VID_GL3_SHADER_REFRESH_RATE[start]", "IDM_VID_GL3_SHADER_REFRESH_RATE[end]")) { - gl3_shader_refresh_rate = wParam - wx_xrcid("IDM_VID_GL3_SHADER_REFRESH_RATE[start]"); - wx_checkmenuitem(menu, wParam, WX_MB_CHECKED); - saveconfig(NULL); - } else if (ID_IS("IDM_VID_GL3_SHADER_MANAGER")) { - if (shader_manager_open(hwnd)) { - renderer_doreset = 1; - saveconfig(NULL); - } - // if (!getfile(hwnd, "GLSL Shaders (*.glslp;*.glsl)|*.glslp;*.glsl|All files (*.*)|*.*", gl3_shader_file)) - // { - // strncpy(gl3_shader_file, openfilestring, 511); - // gl3_shader_file[511] = 0; - // renderer_doreset = 1; - // saveconfig(NULL); - // } - } else if (ID_RANGE("IDM_SND_BUF[start]", "IDM_SND_BUF[end]")) { - sound_buf_len = MIN_SND_BUF * 1 << (wParam - wx_xrcid("IDM_SND_BUF[start]")); - wx_checkmenuitem(menu, wParam, WX_MB_CHECKED); - saveconfig(NULL); - } else if (ID_RANGE("IDM_SND_GAIN[start]", "IDM_SND_GAIN[end]")) { - sound_gain = 2 * (wParam - wx_xrcid("IDM_SND_GAIN[start]")); - wx_checkmenuitem(menu, wParam, WX_MB_CHECKED); - saveconfig(NULL); - } else if (ID_IS("IDM_CDROM_EMPTY")) { - if (cdrom_drive == 0) { - update_cdrom_menu(hmenu); - /* Switch from empty to empty. Do nothing. */ - return 0; - } - atapi->exit(); - atapi_close(); - ioctl_set_drive(0); - old_cdrom_drive = cdrom_drive; - cdrom_drive = 0; - saveconfig(NULL); - update_cdrom_menu(hmenu); - } else if (ID_IS("IDM_CDROM_IMAGE") || ID_IS("IDM_CDROM_IMAGE_LOAD")) { - if (!getfile(hwnd, - "CD-ROM image (*.iso;*.cue)|*.iso;*.cue|All files (*.*)|*.*", - image_path)) { - old_cdrom_drive = cdrom_drive; - strcpy(temp_image_path, openfilestring); - if ((strcmp(image_path, temp_image_path) == 0) && (cdrom_drive == CDROM_IMAGE)) { - /* Switching from ISO to the same ISO. Do nothing. */ - update_cdrom_menu(hmenu); - return 0; - } - atapi->exit(); - atapi_close(); - image_open(temp_image_path); - cdrom_drive = CDROM_IMAGE; - saveconfig(NULL); - update_cdrom_menu(hmenu); - } else - update_cdrom_menu(hmenu); - } else if (wParam >= IDM_CDROM_REAL && wParam < IDM_CDROM_REAL + 100) { - new_cdrom_drive = wParam - IDM_CDROM_REAL; - if (cdrom_drive == new_cdrom_drive) { - /* Switching to the same drive. Do nothing. */ - update_cdrom_menu(hmenu); - return 0; - } - old_cdrom_drive = cdrom_drive; - atapi->exit(); - atapi_close(); - ioctl_set_drive(new_cdrom_drive); - cdrom_drive = new_cdrom_drive; - saveconfig(NULL); - update_cdrom_menu(hmenu); - } - return 0; + wx_checkmenuitem(hmenu, wParam, WX_MB_CHECKED); + saveconfig(NULL); + } else if (ID_IS("IDM_VID_VSYNC")) { + video_vsync = !video_vsync; + wx_checkmenuitem(menu, wParam, video_vsync); + renderer_doreset = 1; + saveconfig(NULL); + } else if (ID_IS("IDM_VID_LOST_FOCUS_DIM")) { + video_focus_dim = !video_focus_dim; + wx_checkmenuitem(menu, wParam, video_focus_dim); + saveconfig(NULL); + } else if (ID_IS("IDM_VID_ALTERNATIVE_UPDATE_LOCK")) { + video_alternative_update_lock = !video_alternative_update_lock; + wx_checkmenuitem(menu, wParam, video_alternative_update_lock); + renderer_doreset = 1; + saveconfig(NULL); + } else if (ID_RANGE("IDM_VID_GL3_INPUT_STRETCH[start]", "IDM_VID_GL3_INPUT_STRETCH[end]")) { + gl3_input_stretch = wParam - wx_xrcid("IDM_VID_GL3_INPUT_STRETCH[start]"); + wx_checkmenuitem(menu, wParam, WX_MB_CHECKED); + saveconfig(NULL); + } else if (ID_RANGE("IDM_VID_GL3_INPUT_SCALE[start]", "IDM_VID_GL3_INPUT_SCALE[end]")) { + int input_scale = wParam - wx_xrcid("IDM_VID_GL3_INPUT_SCALE[start]"); + gl3_input_scale = input_scale / 2.0f + 0.5f; + wx_checkmenuitem(menu, wParam, WX_MB_CHECKED); + saveconfig(NULL); + } else if (ID_RANGE("IDM_VID_GL3_SHADER_REFRESH_RATE[start]", "IDM_VID_GL3_SHADER_REFRESH_RATE[end]")) { + gl3_shader_refresh_rate = wParam - wx_xrcid("IDM_VID_GL3_SHADER_REFRESH_RATE[start]"); + wx_checkmenuitem(menu, wParam, WX_MB_CHECKED); + saveconfig(NULL); + } else if (ID_IS("IDM_VID_GL3_SHADER_MANAGER")) { + if (shader_manager_open(hwnd)) { + renderer_doreset = 1; + saveconfig(NULL); + } + // if (!getfile(hwnd, "GLSL Shaders (*.glslp;*.glsl)|*.glslp;*.glsl|All files (*.*)|*.*", + // gl3_shader_file)) + // { + // strncpy(gl3_shader_file, openfilestring, 511); + // gl3_shader_file[511] = 0; + // renderer_doreset = 1; + // saveconfig(NULL); + // } + } else if (ID_RANGE("IDM_SND_BUF[start]", "IDM_SND_BUF[end]")) { + sound_buf_len = MIN_SND_BUF * 1 << (wParam - wx_xrcid("IDM_SND_BUF[start]")); + wx_checkmenuitem(menu, wParam, WX_MB_CHECKED); + saveconfig(NULL); + } else if (ID_RANGE("IDM_SND_GAIN[start]", "IDM_SND_GAIN[end]")) { + sound_gain = 2 * (wParam - wx_xrcid("IDM_SND_GAIN[start]")); + wx_checkmenuitem(menu, wParam, WX_MB_CHECKED); + saveconfig(NULL); + } else if (ID_IS("IDM_CDROM_EMPTY")) { + if (cdrom_drive == 0) { + update_cdrom_menu(hmenu); + /* Switch from empty to empty. Do nothing. */ + return 0; + } + atapi->exit(); + atapi_close(); + ioctl_set_drive(0); + old_cdrom_drive = cdrom_drive; + cdrom_drive = 0; + saveconfig(NULL); + update_cdrom_menu(hmenu); + } else if (ID_IS("IDM_CDROM_IMAGE") || ID_IS("IDM_CDROM_IMAGE_LOAD")) { + if (!getfile(hwnd, "CD-ROM image (*.iso;*.cue)|*.iso;*.cue|All files (*.*)|*.*", image_path)) { + old_cdrom_drive = cdrom_drive; + strcpy(temp_image_path, openfilestring); + if ((strcmp(image_path, temp_image_path) == 0) && (cdrom_drive == CDROM_IMAGE)) { + /* Switching from ISO to the same ISO. Do nothing. */ + update_cdrom_menu(hmenu); + return 0; + } + atapi->exit(); + atapi_close(); + image_open(temp_image_path); + cdrom_drive = CDROM_IMAGE; + saveconfig(NULL); + update_cdrom_menu(hmenu); + } else + update_cdrom_menu(hmenu); + } else if (wParam >= IDM_CDROM_REAL && wParam < IDM_CDROM_REAL + 100) { + new_cdrom_drive = wParam - IDM_CDROM_REAL; + if (cdrom_drive == new_cdrom_drive) { + /* Switching to the same drive. Do nothing. */ + update_cdrom_menu(hmenu); + return 0; + } + old_cdrom_drive = cdrom_drive; + atapi->exit(); + atapi_close(); + ioctl_set_drive(new_cdrom_drive); + cdrom_drive = new_cdrom_drive; + saveconfig(NULL); + update_cdrom_menu(hmenu); + } + return 0; } diff --git a/src/wx-ui/wx-shader_man.c b/src/wx-ui/wx-shader_man.c index a2a89076..ac7f289c 100644 --- a/src/wx-ui/wx-shader_man.c +++ b/src/wx-ui/wx-shader_man.c @@ -14,172 +14,169 @@ extern char gl3_shader_file[MAX_USER_SHADERS][512]; static char shaders[MAX_USER_SHADERS][512]; void read_shader_config(glslp_t *shader) { - char s[512]; - int i; - char *name = shader->name; - sprintf(s, "GL3 Shaders - %s", name); - for (i = 0; i < shader->num_parameters; ++i) { - struct parameter *param = &shader->parameters[i]; - param->value = config_get_float(CFG_MACHINE, s, param->id, param->default_value); - } + char s[512]; + int i; + char *name = shader->name; + sprintf(s, "GL3 Shaders - %s", name); + for (i = 0; i < shader->num_parameters; ++i) { + struct parameter *param = &shader->parameters[i]; + param->value = config_get_float(CFG_MACHINE, s, param->id, param->default_value); + } } void write_shader_config(glslp_t *shader) { - char s[512]; - int i; - char *name = shader->name; - sprintf(s, "GL3 Shaders - %s", name); - for (i = 0; i < shader->num_parameters; ++i) { - struct parameter *param = &shader->parameters[i]; - config_set_float(CFG_MACHINE, s, param->id, param->value); - } + char s[512]; + int i; + char *name = shader->name; + sprintf(s, "GL3 Shaders - %s", name); + for (i = 0; i < shader->num_parameters; ++i) { + struct parameter *param = &shader->parameters[i]; + config_set_float(CFG_MACHINE, s, param->id, param->value); + } } static void add_shader(int p, const char *s) { - memmove(&shaders[p + 1], &shaders[p], (MAX_USER_SHADERS - p - 2) * 512); - strcpy(shaders[p], s); + memmove(&shaders[p + 1], &shaders[p], (MAX_USER_SHADERS - p - 2) * 512); + strcpy(shaders[p], s); } static int shader_list_update(void *hdlg) { - int c; - void *h; - int num = 0; + int c; + void *h; + int num = 0; - h = wx_getdlgitem(hdlg, WX_ID("IDC_LIST")); - wx_sendmessage(h, WX_LB_RESETCONTENT, 0, 0); + h = wx_getdlgitem(hdlg, WX_ID("IDC_LIST")); + wx_sendmessage(h, WX_LB_RESETCONTENT, 0, 0); - for (c = 0; c < MAX_USER_SHADERS; c++) { - if (strlen(shaders[c])) { - char *p = get_filename(shaders[c]); - wx_sendmessage(h, WX_LB_INSERTSTRING, c, (LONG_PARAM)p); - ++num; - } - } - return num; + for (c = 0; c < MAX_USER_SHADERS; c++) { + if (strlen(shaders[c])) { + char *p = get_filename(shaders[c]); + wx_sendmessage(h, WX_LB_INSERTSTRING, c, (LONG_PARAM)p); + ++num; + } + } + return num; } static void set_shaders() { - int i, j, available; - char s[128]; - char name[64]; - for (i = 0; i < MAX_USER_SHADERS; ++i) { - if (strlen(gl3_shader_file[i])) { - available = 0; - for (j = 0; j < MAX_USER_SHADERS; ++j) { - if (!strcmp(gl3_shader_file[i], shaders[j])) { - available = 1; - continue; - } - } - if (!available) { - get_glslp_name(gl3_shader_file[i], name, sizeof(name)); - sprintf(s, "GL3 Shaders - %s", name); - config_free_section(CFG_MACHINE, s); - } - } - } - memcpy(&gl3_shader_file, &shaders, sizeof(gl3_shader_file)); - + int i, j, available; + char s[128]; + char name[64]; + for (i = 0; i < MAX_USER_SHADERS; ++i) { + if (strlen(gl3_shader_file[i])) { + available = 0; + for (j = 0; j < MAX_USER_SHADERS; ++j) { + if (!strcmp(gl3_shader_file[i], shaders[j])) { + available = 1; + continue; + } + } + if (!available) { + get_glslp_name(gl3_shader_file[i], name, sizeof(name)); + sprintf(s, "GL3 Shaders - %s", name); + config_free_section(CFG_MACHINE, s); + } + } + } + memcpy(&gl3_shader_file, &shaders, sizeof(gl3_shader_file)); } static int shader_manager_dlgproc(void *hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) { - char s[512]; - switch (message) { - case WX_INITDIALOG: { - void *h = wx_getdlgitem(hdlg, WX_ID("IDC_LIST")); - memcpy(&shaders, &gl3_shader_file, sizeof(gl3_shader_file)); - int len = shader_list_update(hdlg); - if (len) - wx_sendmessage(h, WX_LB_SETCURSEL, len - 1, 0); - return TRUE; - } - case WX_COMMAND: { - if (wParam == wxID_OK) { - set_shaders(); - wx_enddialog(hdlg, 1); - return TRUE; - } else if (wParam == wxID_CANCEL) { - wx_enddialog(hdlg, 0); - return TRUE; - } else if (wParam == WX_ID("IDC_APPLY")) { - set_shaders(); - renderer_doreset = 1; - return TRUE; - } else if (wParam == WX_ID("IDC_ADD")) { - void *h = wx_getdlgitem(hdlg, WX_ID("IDC_LIST")); - int c = wx_sendmessage(h, WX_LB_GETCURSEL, 0, 0); - int count = wx_sendmessage(h, WX_LB_GETCOUNT, 0, 0); - if (count >= MAX_USER_SHADERS) { - wx_simple_messagebox("Error", "Can't add more shaders."); - return FALSE; - } + char s[512]; + switch (message) { + case WX_INITDIALOG: { + void *h = wx_getdlgitem(hdlg, WX_ID("IDC_LIST")); + memcpy(&shaders, &gl3_shader_file, sizeof(gl3_shader_file)); + int len = shader_list_update(hdlg); + if (len) + wx_sendmessage(h, WX_LB_SETCURSEL, len - 1, 0); + return TRUE; + } + case WX_COMMAND: { + if (wParam == wxID_OK) { + set_shaders(); + wx_enddialog(hdlg, 1); + return TRUE; + } else if (wParam == wxID_CANCEL) { + wx_enddialog(hdlg, 0); + return TRUE; + } else if (wParam == WX_ID("IDC_APPLY")) { + set_shaders(); + renderer_doreset = 1; + return TRUE; + } else if (wParam == WX_ID("IDC_ADD")) { + void *h = wx_getdlgitem(hdlg, WX_ID("IDC_LIST")); + int c = wx_sendmessage(h, WX_LB_GETCURSEL, 0, 0); + int count = wx_sendmessage(h, WX_LB_GETCOUNT, 0, 0); + if (count >= MAX_USER_SHADERS) { + wx_simple_messagebox("Error", "Can't add more shaders."); + return FALSE; + } - int ret = !wx_filedialog(hdlg, "Open", shaders[c], "GLSL Shaders (*.glslp;*.glsl)|*.glslp;*.glsl|All files (*.*)|*.*", 0, 1, s); + int ret = !wx_filedialog(hdlg, "Open", shaders[c], + "GLSL Shaders (*.glslp;*.glsl)|*.glslp;*.glsl|All files (*.*)|*.*", 0, 1, s); - if (ret) { - add_shader(c + 1, s); - shader_list_update(hdlg); - wx_sendmessage(h, WX_LB_SETCURSEL, c + 1, 0); - } + if (ret) { + add_shader(c + 1, s); + shader_list_update(hdlg); + wx_sendmessage(h, WX_LB_SETCURSEL, c + 1, 0); + } - return TRUE; - } else if (wParam == WX_ID("IDC_CONFIG")) { - void *h = wx_getdlgitem(hdlg, WX_ID("IDC_LIST")); - int c = wx_sendmessage(h, WX_LB_GETCURSEL, 0, 0); - if (c >= 0) { - glslp_t *glsl = glslp_parse(shaders[c]); - if (glsl) { - read_shader_config(glsl); - shaderconfig_open(hdlg, glsl); - write_shader_config(glsl); - glslp_free(glsl); - return TRUE; - } - } - return FALSE; - } else if (wParam == WX_ID("IDC_REMOVE")) { - void *h; - int c; - h = wx_getdlgitem(hdlg, WX_ID("IDC_LIST")); - c = wx_sendmessage(h, WX_LB_GETCURSEL, 0, 0); - if (c >= 0) { - memmove(&shaders[c], &shaders[c + 1], (MAX_USER_SHADERS - c - 1) * 512); - int len = shader_list_update(hdlg); - if (len > 0) { - if (c > 0) - c--; - wx_sendmessage(h, WX_LB_SETCURSEL, c, 0); - } - } - } else if (wParam == WX_ID("IDC_MOVE_UP")) { - void *h = wx_getdlgitem(hdlg, WX_ID("IDC_LIST")); - int c = wx_sendmessage(h, WX_LB_GETCURSEL, 0, 0); - if (c > 0) { - strcpy(s, shaders[c - 1]); - strcpy(shaders[c - 1], shaders[c]); - strcpy(shaders[c], s); - shader_list_update(hdlg); - wx_sendmessage(h, WX_LB_SETCURSEL, c - 1, 0); - } - } else if (wParam == WX_ID("IDC_MOVE_DOWN")) { - void *h = wx_getdlgitem(hdlg, WX_ID("IDC_LIST")); - int c = wx_sendmessage(h, WX_LB_GETCURSEL, 0, 0); - if (c < MAX_USER_SHADERS - 1) { - if (strlen(shaders[c + 1])) { - strcpy(s, shaders[c + 1]); - strcpy(shaders[c + 1], shaders[c]); - strcpy(shaders[c], s); - shader_list_update(hdlg); - wx_sendmessage(h, WX_LB_SETCURSEL, c + 1, 0); - } - } - } - } - break; - } - return FALSE; + return TRUE; + } else if (wParam == WX_ID("IDC_CONFIG")) { + void *h = wx_getdlgitem(hdlg, WX_ID("IDC_LIST")); + int c = wx_sendmessage(h, WX_LB_GETCURSEL, 0, 0); + if (c >= 0) { + glslp_t *glsl = glslp_parse(shaders[c]); + if (glsl) { + read_shader_config(glsl); + shaderconfig_open(hdlg, glsl); + write_shader_config(glsl); + glslp_free(glsl); + return TRUE; + } + } + return FALSE; + } else if (wParam == WX_ID("IDC_REMOVE")) { + void *h; + int c; + h = wx_getdlgitem(hdlg, WX_ID("IDC_LIST")); + c = wx_sendmessage(h, WX_LB_GETCURSEL, 0, 0); + if (c >= 0) { + memmove(&shaders[c], &shaders[c + 1], (MAX_USER_SHADERS - c - 1) * 512); + int len = shader_list_update(hdlg); + if (len > 0) { + if (c > 0) + c--; + wx_sendmessage(h, WX_LB_SETCURSEL, c, 0); + } + } + } else if (wParam == WX_ID("IDC_MOVE_UP")) { + void *h = wx_getdlgitem(hdlg, WX_ID("IDC_LIST")); + int c = wx_sendmessage(h, WX_LB_GETCURSEL, 0, 0); + if (c > 0) { + strcpy(s, shaders[c - 1]); + strcpy(shaders[c - 1], shaders[c]); + strcpy(shaders[c], s); + shader_list_update(hdlg); + wx_sendmessage(h, WX_LB_SETCURSEL, c - 1, 0); + } + } else if (wParam == WX_ID("IDC_MOVE_DOWN")) { + void *h = wx_getdlgitem(hdlg, WX_ID("IDC_LIST")); + int c = wx_sendmessage(h, WX_LB_GETCURSEL, 0, 0); + if (c < MAX_USER_SHADERS - 1) { + if (strlen(shaders[c + 1])) { + strcpy(s, shaders[c + 1]); + strcpy(shaders[c + 1], shaders[c]); + strcpy(shaders[c], s); + shader_list_update(hdlg); + wx_sendmessage(h, WX_LB_SETCURSEL, c + 1, 0); + } + } + } + } break; + } + return FALSE; } -int shader_manager_open(void *hwnd) { - return wx_dialogbox(hwnd, "ShaderManagerDlg", shader_manager_dlgproc); -} +int shader_manager_open(void *hwnd) { return wx_dialogbox(hwnd, "ShaderManagerDlg", shader_manager_dlgproc); } diff --git a/src/wx-ui/wx-shaderconfig.cc b/src/wx-ui/wx-shaderconfig.cc index 08fea39a..beeaf3e9 100644 --- a/src/wx-ui/wx-shaderconfig.cc +++ b/src/wx-ui/wx-shaderconfig.cc @@ -13,8 +13,7 @@ #include "wx-glslp-parser.h" #include "wx-shaderconfig.h" -extern "C" -{ +extern "C" { #include "config.h" void saveconfig(char *); void resetpchard(); @@ -29,109 +28,110 @@ int confirm(); extern int renderer_doreset; static int shaderconfig_dlgproc(void *hdlg, int message, INT_PARAM wParam, LONG_PARAM lParam) { - int i; - switch (message) { - case WX_INITDIALOG: { - return TRUE; - } - case WX_COMMAND: - switch (wParam) { - case ID_APPLY: { - for (i = 0; i < current_glsl->num_parameters; ++i) { - struct parameter *p = ¤t_glsl->parameters[i]; - wxSpinCtrlDouble *h = (wxSpinCtrlDouble *)wx_getdlgitem(hdlg, IDC_CONFIG_BASE + i); - p->value = (float)h->GetValue(); - } - write_shader_config(current_glsl); - renderer_doreset = 1; - return TRUE; - } - case wxID_OK: { - for (i = 0; i < current_glsl->num_parameters; ++i) { - struct parameter *p = ¤t_glsl->parameters[i]; - wxSpinCtrlDouble *h = (wxSpinCtrlDouble *)wx_getdlgitem(hdlg, IDC_CONFIG_BASE + i); - p->value = (float)h->GetValue(); - } - write_shader_config(current_glsl); - renderer_doreset = 1; - wx_enddialog(hdlg, 0); - return TRUE; - } - case wxID_CANCEL:wx_enddialog(hdlg, 0); - return TRUE; - case ID_RESET: { - for (i = 0; i < current_glsl->num_parameters; ++i) { - struct parameter *p = ¤t_glsl->parameters[i]; - wxSpinCtrlDouble *h = (wxSpinCtrlDouble *)wx_getdlgitem(hdlg, IDC_CONFIG_BASE + i); - h->SetValue(p->default_value); - } - return TRUE; - } - } - } - return TRUE; + int i; + switch (message) { + case WX_INITDIALOG: { + return TRUE; + } + case WX_COMMAND: + switch (wParam) { + case ID_APPLY: { + for (i = 0; i < current_glsl->num_parameters; ++i) { + struct parameter *p = ¤t_glsl->parameters[i]; + wxSpinCtrlDouble *h = (wxSpinCtrlDouble *)wx_getdlgitem(hdlg, IDC_CONFIG_BASE + i); + p->value = (float)h->GetValue(); + } + write_shader_config(current_glsl); + renderer_doreset = 1; + return TRUE; + } + case wxID_OK: { + for (i = 0; i < current_glsl->num_parameters; ++i) { + struct parameter *p = ¤t_glsl->parameters[i]; + wxSpinCtrlDouble *h = (wxSpinCtrlDouble *)wx_getdlgitem(hdlg, IDC_CONFIG_BASE + i); + p->value = (float)h->GetValue(); + } + write_shader_config(current_glsl); + renderer_doreset = 1; + wx_enddialog(hdlg, 0); + return TRUE; + } + case wxID_CANCEL: + wx_enddialog(hdlg, 0); + return TRUE; + case ID_RESET: { + for (i = 0; i < current_glsl->num_parameters; ++i) { + struct parameter *p = ¤t_glsl->parameters[i]; + wxSpinCtrlDouble *h = (wxSpinCtrlDouble *)wx_getdlgitem(hdlg, IDC_CONFIG_BASE + i); + h->SetValue(p->default_value); + } + return TRUE; + } + } + } + return TRUE; } void shaderconfig_open(void *hwnd, struct glslp_t *glsl) { - int i; - current_glsl = glsl; + int i; + current_glsl = glsl; - PCemDialogBox dialog((wxWindow *)hwnd, shaderconfig_dlgproc); -// dialog.SetWindowStyle(wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER); + PCemDialogBox dialog((wxWindow *)hwnd, shaderconfig_dlgproc); + // dialog.SetWindowStyle(wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER); - dialog.SetTitle("Shader Configuration"); + dialog.SetTitle("Shader Configuration"); - wxBoxSizer *root = new wxBoxSizer(wxVERTICAL); - dialog.SetSizer(root); + wxBoxSizer *root = new wxBoxSizer(wxVERTICAL); + dialog.SetSizer(root); - wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL); - root->Add(sizer, 0, wxALL, 5); + wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL); + root->Add(sizer, 0, wxALL, 5); - wxPanel *panel = new wxPanel(&dialog, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL | wxBORDER_SUNKEN); - sizer->Add(panel); + wxPanel *panel = new wxPanel(&dialog, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL | wxBORDER_SUNKEN); + sizer->Add(panel); - wxBoxSizer *panelSizer = new wxBoxSizer(wxVERTICAL); - panel->SetSizer(panelSizer); + wxBoxSizer *panelSizer = new wxBoxSizer(wxVERTICAL); + panel->SetSizer(panelSizer); - wxScrolledWindow *win = new wxScrolledWindow(panel, wxID_ANY, wxDefaultPosition, wxSize(300, 350), wxHSCROLL | wxVSCROLL); - win->SetScrollRate(5, 5); - panelSizer->Add(win, 1, wxEXPAND | wxALL, 5); + wxScrolledWindow *win = new wxScrolledWindow(panel, wxID_ANY, wxDefaultPosition, wxSize(300, 350), wxHSCROLL | wxVSCROLL); + win->SetScrollRate(5, 5); + panelSizer->Add(win, 1, wxEXPAND | wxALL, 5); - wxBoxSizer *winSizer = new wxBoxSizer(wxVERTICAL); - win->SetSizer(winSizer); + wxBoxSizer *winSizer = new wxBoxSizer(wxVERTICAL); + win->SetSizer(winSizer); - if (glsl->num_parameters > 0) { - wxPanel *scrollPanel = new wxPanel(win); - winSizer->Add(scrollPanel); + if (glsl->num_parameters > 0) { + wxPanel *scrollPanel = new wxPanel(win); + winSizer->Add(scrollPanel); - wxBoxSizer *scollPanelSizer = new wxBoxSizer(wxVERTICAL); - scrollPanel->SetSizer(scollPanelSizer); + wxBoxSizer *scollPanelSizer = new wxBoxSizer(wxVERTICAL); + scrollPanel->SetSizer(scollPanelSizer); - for (i = 0; i < glsl->num_parameters; ++i) { - struct parameter *p = &glsl->parameters[i]; - scollPanelSizer->Add(new wxStaticText(scrollPanel, wxID_ANY, p->description), 0, wxALL); - wxSpinCtrlDouble *spin = new wxSpinCtrlDouble(scrollPanel, IDC_CONFIG_BASE + i); - spin->SetRange(p->min, p->max); - spin->SetIncrement(p->step); - spin->SetValue(p->value); - spin->SetDigits(2); + for (i = 0; i < glsl->num_parameters; ++i) { + struct parameter *p = &glsl->parameters[i]; + scollPanelSizer->Add(new wxStaticText(scrollPanel, wxID_ANY, p->description), 0, wxALL); + wxSpinCtrlDouble *spin = new wxSpinCtrlDouble(scrollPanel, IDC_CONFIG_BASE + i); + spin->SetRange(p->min, p->max); + spin->SetIncrement(p->step); + spin->SetValue(p->value); + spin->SetDigits(2); - scollPanelSizer->Add(spin, 0, wxALL); - } - } else - winSizer->Add(new wxStaticText(win, wxID_ANY, "No configuration available."), 0, wxALL); + scollPanelSizer->Add(spin, 0, wxALL); + } + } else + winSizer->Add(new wxStaticText(win, wxID_ANY, "No configuration available."), 0, wxALL); - wxBoxSizer *buttonSizer = new wxBoxSizer(wxHORIZONTAL); + wxBoxSizer *buttonSizer = new wxBoxSizer(wxHORIZONTAL); - buttonSizer->Add(new wxButton(&dialog, ID_APPLY, "Apply")); - buttonSizer->Add(new wxButton(&dialog, wxID_OK)); - buttonSizer->Add(new wxButton(&dialog, wxID_CANCEL)); - buttonSizer->Add(new wxButton(&dialog, ID_RESET, "Reset")); + buttonSizer->Add(new wxButton(&dialog, ID_APPLY, "Apply")); + buttonSizer->Add(new wxButton(&dialog, wxID_OK)); + buttonSizer->Add(new wxButton(&dialog, wxID_CANCEL)); + buttonSizer->Add(new wxButton(&dialog, ID_RESET, "Reset")); - sizer->Add(buttonSizer); + sizer->Add(buttonSizer); - dialog.Fit(); - dialog.OnInit(); - dialog.ShowModal(); - dialog.Destroy(); + dialog.Fit(); + dialog.OnInit(); + dialog.ShowModal(); + dialog.Destroy(); } diff --git a/src/wx-ui/wx-status.cc b/src/wx-ui/wx-status.cc index 67d6d40e..257979df 100644 --- a/src/wx-ui/wx-status.cc +++ b/src/wx-ui/wx-status.cc @@ -25,198 +25,196 @@ int show_mount_paths = 0; #define MAX(a, b) (a > b ? a : b) -#define render_disc_activity(x, y) do { \ -if (show_disc_activity) \ -{ \ - int w = 8; \ - int h = 8; \ - if (info.readflash) { \ - dc.SetBrush(wxBrush(wxColour(0,255,0))); \ - } else { \ - dc.SetBrush(wxBrush(wxColour(0,100,0))); \ - } \ - dc.DrawRectangle(x+bitmap.GetWidth()-w, y, w, h); \ -}} while (0) +#define render_disc_activity(x, y) \ + do { \ + if (show_disc_activity) { \ + int w = 8; \ + int h = 8; \ + if (info.readflash) { \ + dc.SetBrush(wxBrush(wxColour(0, 255, 0))); \ + } else { \ + dc.SetBrush(wxBrush(wxColour(0, 100, 0))); \ + } \ + dc.DrawRectangle(x + bitmap.GetWidth() - w, y, w, h); \ + } \ + } while (0) -StatusTimer::StatusTimer(StatusPane *pane) { - this->pane = pane; -} +StatusTimer::StatusTimer(StatusPane *pane) { this->pane = pane; } -void StatusTimer::Notify() { - pane->Refresh(); -} +void StatusTimer::Notify() { pane->Refresh(); } -void StatusTimer::Start() { - wxTimer::Start(10); -} +void StatusTimer::Start() { wxTimer::Start(10); } -BEGIN_EVENT_TABLE(StatusPane, wxPanel)EVT_PAINT(StatusPane::PaintEvent) -END_EVENT_TABLE() +BEGIN_EVENT_TABLE(StatusPane, wxPanel) +EVT_PAINT(StatusPane::PaintEvent) END_EVENT_TABLE() -BEGIN_EVENT_TABLE(StatusFrame, wxFrame)END_EVENT_TABLE() + BEGIN_EVENT_TABLE(StatusFrame, wxFrame) END_EVENT_TABLE() -StatusPane::StatusPane(wxFrame *parent) : - wxPanel(parent) { + StatusPane::StatusPane(wxFrame *parent) + : wxPanel(parent) { #ifndef __WXOSX_MAC__ - SetDoubleBuffered(true); + SetDoubleBuffered(true); #endif - machineInfoText[0] = statusMachineText[0] = statusDeviceText[0] = 0; - lastSpeedUpdate = 0; - memset(speedHistory, -1, sizeof(speedHistory)); + machineInfoText[0] = statusMachineText[0] = statusDeviceText[0] = 0; + lastSpeedUpdate = 0; + memset(speedHistory, -1, sizeof(speedHistory)); - bitmapFDD[0] = wxXmlResource::Get()->LoadBitmap("BITMAP_FLOPPY"); - bitmapFDD[1] = bitmapFDD[0].ConvertToDisabled(); - bitmapHDD[0] = wxXmlResource::Get()->LoadBitmap("BITMAP_HARDDISK"); - bitmapHDD[1] = bitmapHDD[0].ConvertToDisabled(); - bitmapCDROM[0] = wxXmlResource::Get()->LoadBitmap("BITMAP_CDROM"); - bitmapCDROM[1] = bitmapCDROM[0].ConvertToDisabled(); + bitmapFDD[0] = wxXmlResource::Get()->LoadBitmap("BITMAP_FLOPPY"); + bitmapFDD[1] = bitmapFDD[0].ConvertToDisabled(); + bitmapHDD[0] = wxXmlResource::Get()->LoadBitmap("BITMAP_HARDDISK"); + bitmapHDD[1] = bitmapHDD[0].ConvertToDisabled(); + bitmapCDROM[0] = wxXmlResource::Get()->LoadBitmap("BITMAP_CDROM"); + bitmapCDROM[1] = bitmapCDROM[0].ConvertToDisabled(); } -StatusPane::~StatusPane() { -} +StatusPane::~StatusPane() {} void StatusPane::PaintEvent(wxPaintEvent &evt) { - wxPaintDC dc(this); - Render(dc); + wxPaintDC dc(this); + Render(dc); } void StatusPane::PaintNow() { - wxClientDC dc(this); - Render(dc); + wxClientDC dc(this); + Render(dc); } void StatusPane::Render(wxDC &dc) { - wxSize cSize = GetParent()->GetClientSize(); + wxSize cSize = GetParent()->GetClientSize(); - int width = 0; - int height = 0; - wxLongLong millis = wxGetUTCTimeMillis(); + int width = 0; + int height = 0; + wxLongLong millis = wxGetUTCTimeMillis(); - dc.SetBackground(wxSystemSettings::GetColour(wxSYS_COLOUR_FRAMEBK)); - dc.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)); - dc.Clear(); + dc.SetBackground(wxSystemSettings::GetColour(wxSYS_COLOUR_FRAMEBK)); + dc.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)); + dc.Clear(); - // draw model/cpu etc - if (show_machine_info) { - int num_info; - drive_info_t *drive_info = get_machine_info(machineInfoText, &num_info); - wxSize size = dc.GetMultiLineTextExtent(machineInfoText); - dc.DrawText(machineInfoText, 5, height + 5); + // draw model/cpu etc + if (show_machine_info) { + int num_info; + drive_info_t *drive_info = get_machine_info(machineInfoText, &num_info); + wxSize size = dc.GetMultiLineTextExtent(machineInfoText); + dc.DrawText(machineInfoText, 5, height + 5); - width = MAX(width, width + 5 + size.x); - height = MAX(height, height + 5 + size.y); + width = MAX(width, width + 5 + size.x); + height = MAX(height, height + 5 + size.y); - int x = cSize.x - 5; + int x = cSize.x - 5; - for (int i = 0; i < num_info; ++i) { - drive_info_t info = show_mount_paths ? drive_info[i] : drive_info[num_info - i - 1]; - wxBitmap bitmap; - if (info.type == DRIVE_TYPE_FDD) - bitmap = info.enabled ? bitmapFDD[0] : bitmapFDD[1]; - else if (info.type == DRIVE_TYPE_CDROM) - bitmap = info.enabled ? bitmapCDROM[0] : bitmapCDROM[1]; - else - bitmap = info.enabled ? bitmapHDD[0] : bitmapHDD[1]; - if (show_mount_paths) { - x = 5; - dc.DrawBitmap(bitmap, x, height + 5); - render_disc_activity(x, height + 5); - x += bitmap.GetWidth() + 5; + for (int i = 0; i < num_info; ++i) { + drive_info_t info = show_mount_paths ? drive_info[i] : drive_info[num_info - i - 1]; + wxBitmap bitmap; + if (info.type == DRIVE_TYPE_FDD) + bitmap = info.enabled ? bitmapFDD[0] : bitmapFDD[1]; + else if (info.type == DRIVE_TYPE_CDROM) + bitmap = info.enabled ? bitmapCDROM[0] : bitmapCDROM[1]; + else + bitmap = info.enabled ? bitmapHDD[0] : bitmapHDD[1]; + if (show_mount_paths) { + x = 5; + dc.DrawBitmap(bitmap, x, height + 5); + render_disc_activity(x, height + 5); + x += bitmap.GetWidth() + 5; - std::ostringstream ss; - ss << info.drive_letter << ":" << " " << info.fn; - std::string s = ss.str(); - size = dc.GetTextExtent(s); - dc.DrawText(s, x, height + 5 + (bitmap.GetHeight() - size.y) / 2); - width = MAX(width, x + size.x); - height = height + 5 + MAX(bitmap.GetHeight(), size.y); - } else { - x -= bitmap.GetWidth(); - dc.DrawBitmap(bitmap, x, 5); - render_disc_activity(x, 5); - x -= 5; - height = MAX(height, 5 + bitmap.GetHeight()); - } - } - } + std::ostringstream ss; + ss << info.drive_letter << ":" + << " " << info.fn; + std::string s = ss.str(); + size = dc.GetTextExtent(s); + dc.DrawText(s, x, height + 5 + (bitmap.GetHeight() - size.y) / 2); + width = MAX(width, x + size.x); + height = height + 5 + MAX(bitmap.GetHeight(), size.y); + } else { + x -= bitmap.GetWidth(); + dc.DrawBitmap(bitmap, x, 5); + render_disc_activity(x, 5); + x -= 5; + height = MAX(height, 5 + bitmap.GetHeight()); + } + } + } - if (emulation_state != EMULATION_STOPPED) { - // draw status text - if (show_status) { - if (updatestatus) { - updatestatus = 0; - get_status(statusMachineText, statusDeviceText); - } - if (statusMachineText) { - int statusX = 5; - int statusY = height + 5; - wxSize size = dc.GetMultiLineTextExtent(statusMachineText); - dc.DrawText(statusMachineText, statusX, statusY); - width = MAX(width, statusX + size.GetWidth()); - height = MAX(height, statusY + size.GetHeight()); - if (statusDeviceText) { - wxSize dSize = dc.GetMultiLineTextExtent(statusDeviceText); - dc.DrawText(statusDeviceText, statusX + ceil((size.GetWidth() + 50) / 100.0) * 100, statusY); - width = MAX(width, statusX + ceil((size.GetWidth() + 50) / 100.0) * 100 + ceil((dSize.GetWidth() + 50) / 100.0) * 100); - height = MAX(height, statusY + dSize.GetHeight()); - } - } - } + if (emulation_state != EMULATION_STOPPED) { + // draw status text + if (show_status) { + if (updatestatus) { + updatestatus = 0; + get_status(statusMachineText, statusDeviceText); + } + if (statusMachineText) { + int statusX = 5; + int statusY = height + 5; + wxSize size = dc.GetMultiLineTextExtent(statusMachineText); + dc.DrawText(statusMachineText, statusX, statusY); + width = MAX(width, statusX + size.GetWidth()); + height = MAX(height, statusY + size.GetHeight()); + if (statusDeviceText) { + wxSize dSize = dc.GetMultiLineTextExtent(statusDeviceText); + dc.DrawText(statusDeviceText, statusX + ceil((size.GetWidth() + 50) / 100.0) * 100, + statusY); + width = MAX(width, statusX + ceil((size.GetWidth() + 50) / 100.0) * 100 + + ceil((dSize.GetWidth() + 50) / 100.0) * 100); + height = MAX(height, statusY + dSize.GetHeight()); + } + } + } - if (emulation_state == EMULATION_RUNNING && (millis - lastSpeedUpdate > 500)) { - lastSpeedUpdate = millis; - memmove(speedHistory + 1, speedHistory, SPEED_HISTORY_LENGTH - 2); - speedHistory[0] = fps; - } - // draw speed history - if (show_speed_history) { - int speedGraphBorder = 5; - int speedGraphX = 5; - int speedGraphY = height + 5; - int speedGraphWidth = MAX(2 * SPEED_HISTORY_LENGTH, width - 5); - double lineLength = (double)(speedGraphWidth - 2) / (SPEED_HISTORY_LENGTH - 1); - int speedGraphHeight = 125; - dc.SetBrush(wxBrush(wxColour(255, 255, 255))); - dc.DrawRectangle(speedGraphX, speedGraphY, speedGraphWidth, speedGraphHeight + speedGraphBorder * 2); - dc.SetPen(wxPen(wxColour(200, 200, 200))); - dc.DrawLine(speedGraphX, speedGraphY + speedGraphBorder + speedGraphHeight - 0, speedGraphX + speedGraphWidth, speedGraphY + speedGraphHeight + speedGraphBorder - 0); // 0 - dc.DrawLine(speedGraphX, speedGraphY + speedGraphBorder + speedGraphHeight - 50, speedGraphX + speedGraphWidth, speedGraphY + speedGraphHeight + speedGraphBorder - 50); // 50 - dc.DrawLine(speedGraphX, - speedGraphY + speedGraphBorder + speedGraphHeight - 100, - speedGraphX + speedGraphWidth, - speedGraphY + speedGraphHeight + speedGraphBorder - 100); // 100 - dc.DrawLine(speedGraphX, - speedGraphY + speedGraphBorder + speedGraphHeight - 125, - speedGraphX + speedGraphWidth, - speedGraphY + speedGraphHeight + speedGraphBorder - 125); // 125 - dc.SetPen(wxPen(wxColour(0, 0, 0))); - for (int i = 0; i < SPEED_HISTORY_LENGTH - 1; ++i) { - int v0 = speedHistory[i]; - int v1 = speedHistory[i + 1]; - if (v0 >= 0 && v1 >= 0) { - dc.DrawLine(speedGraphX + speedGraphWidth - i * lineLength - 1, speedGraphY + speedGraphHeight + speedGraphBorder - v0, - speedGraphX + speedGraphWidth - (i + 1) * lineLength - 1, speedGraphY + speedGraphHeight + speedGraphBorder - v1); - } - } - dc.SetBrush(wxBrush(wxColour(255, 255, 255), wxBrushStyle(wxBRUSHSTYLE_TRANSPARENT))); - dc.DrawRectangle(speedGraphX, speedGraphY, speedGraphWidth, speedGraphHeight + speedGraphBorder * 2); + if (emulation_state == EMULATION_RUNNING && (millis - lastSpeedUpdate > 500)) { + lastSpeedUpdate = millis; + memmove(speedHistory + 1, speedHistory, SPEED_HISTORY_LENGTH - 2); + speedHistory[0] = fps; + } + // draw speed history + if (show_speed_history) { + int speedGraphBorder = 5; + int speedGraphX = 5; + int speedGraphY = height + 5; + int speedGraphWidth = MAX(2 * SPEED_HISTORY_LENGTH, width - 5); + double lineLength = (double)(speedGraphWidth - 2) / (SPEED_HISTORY_LENGTH - 1); + int speedGraphHeight = 125; + dc.SetBrush(wxBrush(wxColour(255, 255, 255))); + dc.DrawRectangle(speedGraphX, speedGraphY, speedGraphWidth, speedGraphHeight + speedGraphBorder * 2); + dc.SetPen(wxPen(wxColour(200, 200, 200))); + dc.DrawLine(speedGraphX, speedGraphY + speedGraphBorder + speedGraphHeight - 0, + speedGraphX + speedGraphWidth, speedGraphY + speedGraphHeight + speedGraphBorder - 0); // 0 + dc.DrawLine(speedGraphX, speedGraphY + speedGraphBorder + speedGraphHeight - 50, + speedGraphX + speedGraphWidth, speedGraphY + speedGraphHeight + speedGraphBorder - 50); // 50 + dc.DrawLine(speedGraphX, speedGraphY + speedGraphBorder + speedGraphHeight - 100, + speedGraphX + speedGraphWidth, + speedGraphY + speedGraphHeight + speedGraphBorder - 100); // 100 + dc.DrawLine(speedGraphX, speedGraphY + speedGraphBorder + speedGraphHeight - 125, + speedGraphX + speedGraphWidth, + speedGraphY + speedGraphHeight + speedGraphBorder - 125); // 125 + dc.SetPen(wxPen(wxColour(0, 0, 0))); + for (int i = 0; i < SPEED_HISTORY_LENGTH - 1; ++i) { + int v0 = speedHistory[i]; + int v1 = speedHistory[i + 1]; + if (v0 >= 0 && v1 >= 0) { + dc.DrawLine(speedGraphX + speedGraphWidth - i * lineLength - 1, + speedGraphY + speedGraphHeight + speedGraphBorder - v0, + speedGraphX + speedGraphWidth - (i + 1) * lineLength - 1, + speedGraphY + speedGraphHeight + speedGraphBorder - v1); + } + } + dc.SetBrush(wxBrush(wxColour(255, 255, 255), wxBrushStyle(wxBRUSHSTYLE_TRANSPARENT))); + dc.DrawRectangle(speedGraphX, speedGraphY, speedGraphWidth, speedGraphHeight + speedGraphBorder * 2); - width = MAX(width, (speedGraphX + speedGraphWidth)); - height = MAX(height, speedGraphY + speedGraphHeight + speedGraphBorder * 2); - } - } + width = MAX(width, (speedGraphX + speedGraphWidth)); + height = MAX(height, speedGraphY + speedGraphHeight + speedGraphBorder * 2); + } + } - width += 5; - height += 5; - width = width < DEFAULT_WINDOW_WIDTH ? DEFAULT_WINDOW_WIDTH : width; - height = height < DEFAULT_WINDOW_HEIGHT ? DEFAULT_WINDOW_HEIGHT : height; - if (cSize.GetWidth() != width || cSize.GetHeight() != height) { - GetParent()->SetClientSize(width, height); - } + width += 5; + height += 5; + width = width < DEFAULT_WINDOW_WIDTH ? DEFAULT_WINDOW_WIDTH : width; + height = height < DEFAULT_WINDOW_HEIGHT ? DEFAULT_WINDOW_HEIGHT : height; + if (cSize.GetWidth() != width || cSize.GetHeight() != height) { + GetParent()->SetClientSize(width, height); + } } -extern "C" -{ +extern "C" { int window_remember; void wx_handle_command(void *, int, int); @@ -232,103 +230,103 @@ void config_open(void *hwnd); int wx_window_x = 0; int wx_window_y = 0; -StatusFrame::StatusFrame(wxWindow *parent) : - wxFrame(parent, STATUS_WINDOW_ID, "PCem Machine", wxPoint(0, 0), wxSize(DEFAULT_WINDOW_WIDTH, 200), wxCAPTION | wxCLOSE_BOX) { - SetMenuBar(wxXmlResource::Get()->LoadMenuBar(wxT("status_menu"))); - SetToolBar(wxXmlResource::Get()->LoadToolBar(this, wxT("tool_bar"))); +StatusFrame::StatusFrame(wxWindow *parent) + : wxFrame(parent, STATUS_WINDOW_ID, "PCem Machine", wxPoint(0, 0), wxSize(DEFAULT_WINDOW_WIDTH, 200), + wxCAPTION | wxCLOSE_BOX) { + SetMenuBar(wxXmlResource::Get()->LoadMenuBar(wxT("status_menu"))); + SetToolBar(wxXmlResource::Get()->LoadToolBar(this, wxT("tool_bar"))); - this->statusPane = new StatusPane(this); - wxBoxSizer *sizer = new wxBoxSizer(wxHORIZONTAL); - sizer->Add(statusPane, 1, wxEXPAND); - SetSizer(sizer); + this->statusPane = new StatusPane(this); + wxBoxSizer *sizer = new wxBoxSizer(wxHORIZONTAL); + sizer->Add(statusPane, 1, wxEXPAND); + SetSizer(sizer); - Bind(wxEVT_MENU, &StatusFrame::OnCommand, this); - Bind(wxEVT_MOVE, &StatusFrame::OnMoveWindow, this); + Bind(wxEVT_MENU, &StatusFrame::OnCommand, this); + Bind(wxEVT_MOVE, &StatusFrame::OnMoveWindow, this); - statusTimer = new StatusTimer(statusPane); - statusTimer->Start(); + statusTimer = new StatusTimer(statusPane); + statusTimer->Start(); - if (window_remember) - SetPosition(wxPoint(wx_window_x, wx_window_y)); - else - CenterOnScreen(); + if (window_remember) + SetPosition(wxPoint(wx_window_x, wx_window_y)); + else + CenterOnScreen(); - UpdateToolbar(); - GetMenuBar()->FindItem(XRCID("IDM_SHOW_STATUS"))->Check(show_status); - GetMenuBar()->FindItem(XRCID("IDM_SPEED_HISTORY"))->Check(show_speed_history); - GetMenuBar()->FindItem(XRCID("IDM_DISC_ACTIVITY"))->Check(show_disc_activity); - GetMenuBar()->FindItem(XRCID("IDM_MACHINE_MOUNT_PATHS"))->Check(show_mount_paths); - GetMenuBar()->FindItem(XRCID("IDM_SHOW_MACHINE_ON_START"))->Check(show_machine_on_start); + UpdateToolbar(); + GetMenuBar()->FindItem(XRCID("IDM_SHOW_STATUS"))->Check(show_status); + GetMenuBar()->FindItem(XRCID("IDM_SPEED_HISTORY"))->Check(show_speed_history); + GetMenuBar()->FindItem(XRCID("IDM_DISC_ACTIVITY"))->Check(show_disc_activity); + GetMenuBar()->FindItem(XRCID("IDM_MACHINE_MOUNT_PATHS"))->Check(show_mount_paths); + GetMenuBar()->FindItem(XRCID("IDM_SHOW_MACHINE_ON_START"))->Check(show_machine_on_start); } StatusFrame::~StatusFrame() { - statusTimer->Stop(); - delete statusTimer; + statusTimer->Stop(); + delete statusTimer; } void StatusFrame::UpdateToolbar() { - GetToolBar()->EnableTool(XRCID("TOOLBAR_RUN"), emulation_state != EMULATION_RUNNING); - GetToolBar()->EnableTool(XRCID("TOOLBAR_PAUSE"), emulation_state != EMULATION_PAUSED); + GetToolBar()->EnableTool(XRCID("TOOLBAR_RUN"), emulation_state != EMULATION_RUNNING); + GetToolBar()->EnableTool(XRCID("TOOLBAR_PAUSE"), emulation_state != EMULATION_PAUSED); } void StatusFrame::OnCommand(wxCommandEvent &event) { - if (event.GetId() == XRCID("TOOLBAR_RUN")) { - resume_emulation(); - UpdateToolbar(); - } else if (event.GetId() == XRCID("TOOLBAR_PAUSE")) { - pause_emulation(); - UpdateToolbar(); - } else if (event.GetId() == XRCID("TOOLBAR_RESET")) { - int ret = wxID_OK; - if (confirm_on_reset_machine) { - wxDialog dlg; - wxXmlResource::Get()->LoadDialog(&dlg, this, "ConfirmRememberDlg"); - dlg.FindWindow("IDC_CONFIRM_LABEL")->SetLabel("Reset machine?"); - dlg.FindWindow("IDC_CONFIRM_REMEMBER")->SetLabel("Do not ask again"); - dlg.Fit(); - ret = dlg.ShowModal(); - if (ret == wxID_OK) - confirm_on_reset_machine = !((wxCheckBox *)dlg.FindWindow("IDC_CONFIRM_REMEMBER"))->IsChecked(); - } - if (ret == wxID_OK) { - reset_emulation(); - UpdateToolbar(); - } - } else if (event.GetId() == XRCID("TOOLBAR_STOP")) - wx_stop_emulation(GetParent()); - else if (event.GetId() == XRCID("IDM_SHOW_STATUS")) - show_status = event.IsChecked(); - else if (event.GetId() == XRCID("IDM_SPEED_HISTORY")) - show_speed_history = event.IsChecked(); - else if (event.GetId() == XRCID("IDM_DISC_ACTIVITY")) - show_disc_activity = event.IsChecked(); - else if (event.GetId() == XRCID("IDM_MACHINE_MOUNT_PATHS")) - show_mount_paths = event.IsChecked(); - else if (event.GetId() == XRCID("IDM_SHOW_MACHINE_ON_START")) - show_machine_on_start = event.IsChecked(); -// else if (event.GetId() == XRCID("IDM_HDCONF")) -// hdconf_open(this); - else if (event.GetId() == XRCID("IDM_CONFIG")) - config_open(this); - else if (event.GetId() == XRCID("IDM_RESET_CONFIRMATION_DIALOGS")) { - confirm_on_reset_machine = 1; - confirm_on_stop_emulation = 1; - wxMessageBox("Confirmation dialogs has been reset.", "PCem"); - } else if (event.GetId() == XRCID("IDM_ABOUT")) { - wxDialog dlg; - wxXmlResource::Get()->LoadDialog(&dlg, this, "AboutDlg"); - wxString version = dlg.FindWindow("VERSION_TEXT")->GetLabel(); - version.Replace("PCEM-VERSION-STRING", PCEM_VERSION_STRING); - dlg.FindWindow("VERSION_TEXT")->SetLabel(version); - dlg.Fit(); - dlg.ShowModal(); - } - + if (event.GetId() == XRCID("TOOLBAR_RUN")) { + resume_emulation(); + UpdateToolbar(); + } else if (event.GetId() == XRCID("TOOLBAR_PAUSE")) { + pause_emulation(); + UpdateToolbar(); + } else if (event.GetId() == XRCID("TOOLBAR_RESET")) { + int ret = wxID_OK; + if (confirm_on_reset_machine) { + wxDialog dlg; + wxXmlResource::Get()->LoadDialog(&dlg, this, "ConfirmRememberDlg"); + dlg.FindWindow("IDC_CONFIRM_LABEL")->SetLabel("Reset machine?"); + dlg.FindWindow("IDC_CONFIRM_REMEMBER")->SetLabel("Do not ask again"); + dlg.Fit(); + ret = dlg.ShowModal(); + if (ret == wxID_OK) + confirm_on_reset_machine = !((wxCheckBox *)dlg.FindWindow("IDC_CONFIRM_REMEMBER"))->IsChecked(); + } + if (ret == wxID_OK) { + reset_emulation(); + UpdateToolbar(); + } + } else if (event.GetId() == XRCID("TOOLBAR_STOP")) + wx_stop_emulation(GetParent()); + else if (event.GetId() == XRCID("IDM_SHOW_STATUS")) + show_status = event.IsChecked(); + else if (event.GetId() == XRCID("IDM_SPEED_HISTORY")) + show_speed_history = event.IsChecked(); + else if (event.GetId() == XRCID("IDM_DISC_ACTIVITY")) + show_disc_activity = event.IsChecked(); + else if (event.GetId() == XRCID("IDM_MACHINE_MOUNT_PATHS")) + show_mount_paths = event.IsChecked(); + else if (event.GetId() == XRCID("IDM_SHOW_MACHINE_ON_START")) + show_machine_on_start = event.IsChecked(); + // else if (event.GetId() == XRCID("IDM_HDCONF")) + // hdconf_open(this); + else if (event.GetId() == XRCID("IDM_CONFIG")) + config_open(this); + else if (event.GetId() == XRCID("IDM_RESET_CONFIRMATION_DIALOGS")) { + confirm_on_reset_machine = 1; + confirm_on_stop_emulation = 1; + wxMessageBox("Confirmation dialogs has been reset.", "PCem"); + } else if (event.GetId() == XRCID("IDM_ABOUT")) { + wxDialog dlg; + wxXmlResource::Get()->LoadDialog(&dlg, this, "AboutDlg"); + wxString version = dlg.FindWindow("VERSION_TEXT")->GetLabel(); + version.Replace("PCEM-VERSION-STRING", PCEM_VERSION_STRING); + dlg.FindWindow("VERSION_TEXT")->SetLabel(version); + dlg.Fit(); + dlg.ShowModal(); + } } void StatusFrame::OnMoveWindow(wxMoveEvent &event) { - if (window_remember) { - wx_window_x = GetScreenPosition().x; - wx_window_y = GetScreenPosition().y; - } + if (window_remember) { + wx_window_x = GetScreenPosition().x; + wx_window_y = GetScreenPosition().y; + } } diff --git a/src/wx-ui/wx-thread.c b/src/wx-ui/wx-thread.c index 59227b60..5f77b242 100644 --- a/src/wx-ui/wx-thread.c +++ b/src/wx-ui/wx-thread.c @@ -8,238 +8,210 @@ #if defined WIN32 || defined _WIN32 || defined _WIN32 #include #include -void *thread_create(void (*thread_rout)(void *param), void *param) { - return (void *)_beginthread(thread_rout, 0, param); -} +void *thread_create(void (*thread_rout)(void *param), void *param) { return (void *)_beginthread(thread_rout, 0, param); } -void thread_kill(void *handle) { - TerminateThread(handle, 0); -} +void thread_kill(void *handle) { TerminateThread(handle, 0); } -void thread_sleep(int t) { - Sleep(t); -} +void thread_sleep(int t) { Sleep(t); } typedef struct win_event_t { - HANDLE handle; + HANDLE handle; } win_event_t; event_t *thread_create_event() { - win_event_t *event = malloc(sizeof(win_event_t)); + win_event_t *event = malloc(sizeof(win_event_t)); - event->handle = CreateEvent(NULL, FALSE, FALSE, NULL); + event->handle = CreateEvent(NULL, FALSE, FALSE, NULL); - return (event_t *)event; + return (event_t *)event; } void thread_set_event(event_t *_event) { - win_event_t *event = (win_event_t *)_event; + win_event_t *event = (win_event_t *)_event; - SetEvent(event->handle); + SetEvent(event->handle); } void thread_reset_event(event_t *_event) { - win_event_t *event = (win_event_t *)_event; + win_event_t *event = (win_event_t *)_event; - ResetEvent(event->handle); + ResetEvent(event->handle); } int thread_wait_event(event_t *_event, int timeout) { - win_event_t *event = (win_event_t *)_event; + win_event_t *event = (win_event_t *)_event; - if (timeout == -1) - timeout = INFINITE; + if (timeout == -1) + timeout = INFINITE; - if (WaitForSingleObject(event->handle, timeout)) - return 1; - return 0; + if (WaitForSingleObject(event->handle, timeout)) + return 1; + return 0; } void thread_destroy_event(event_t *_event) { - win_event_t *event = (win_event_t *)_event; + win_event_t *event = (win_event_t *)_event; - CloseHandle(event->handle); + CloseHandle(event->handle); - free(event); + free(event); } typedef struct win_mutex_t { - HANDLE handle; + HANDLE handle; } win_mutex_t; mutex_t *thread_create_mutex(void) { - win_mutex_t *mutex = malloc(sizeof(win_mutex_t)); + win_mutex_t *mutex = malloc(sizeof(win_mutex_t)); - mutex->handle = CreateSemaphore(NULL, 1, 1, NULL); - - return mutex; + mutex->handle = CreateSemaphore(NULL, 1, 1, NULL); + return mutex; } void thread_lock_mutex(mutex_t *_mutex) { - win_mutex_t *mutex = (win_mutex_t *)_mutex; + win_mutex_t *mutex = (win_mutex_t *)_mutex; - WaitForSingleObject(mutex->handle, INFINITE); + WaitForSingleObject(mutex->handle, INFINITE); } void thread_unlock_mutex(mutex_t *_mutex) { - win_mutex_t *mutex = (win_mutex_t *)_mutex; + win_mutex_t *mutex = (win_mutex_t *)_mutex; - ReleaseSemaphore(mutex->handle, 1, NULL); + ReleaseSemaphore(mutex->handle, 1, NULL); } void thread_destroy_mutex(mutex_t *_mutex) { - win_mutex_t *mutex = (win_mutex_t *)_mutex; + win_mutex_t *mutex = (win_mutex_t *)_mutex; - CloseHandle(mutex->handle); + CloseHandle(mutex->handle); - free(mutex); + free(mutex); } #else #include #include -typedef struct event_pthread_t -{ - pthread_cond_t cond; - pthread_mutex_t mutex; - int state; +typedef struct event_pthread_t { + pthread_cond_t cond; + pthread_mutex_t mutex; + int state; } event_pthread_t; -thread_t *thread_create(void (*thread_rout)(void *param), void *param) -{ - pthread_t *thread = malloc(sizeof(pthread_t)); +thread_t *thread_create(void (*thread_rout)(void *param), void *param) { + pthread_t *thread = malloc(sizeof(pthread_t)); - pthread_create(thread, NULL, (void*)thread_rout, param); + pthread_create(thread, NULL, (void *)thread_rout, param); - return thread; + return thread; } -void thread_kill(thread_t *handle) -{ - pthread_t *thread = (pthread_t *)handle; +void thread_kill(thread_t *handle) { + pthread_t *thread = (pthread_t *)handle; - pthread_cancel(*thread); - pthread_join(*thread, NULL); + pthread_cancel(*thread); + pthread_join(*thread, NULL); - free(thread); + free(thread); } -event_t *thread_create_event() -{ - event_pthread_t *event = malloc(sizeof(event_pthread_t)); +event_t *thread_create_event() { + event_pthread_t *event = malloc(sizeof(event_pthread_t)); - pthread_cond_init(&event->cond, NULL); - pthread_mutex_init(&event->mutex, NULL); - event->state = 0; + pthread_cond_init(&event->cond, NULL); + pthread_mutex_init(&event->mutex, NULL); + event->state = 0; - return (event_t *)event; + return (event_t *)event; } -void thread_set_event(event_t *handle) -{ - event_pthread_t *event = (event_pthread_t *)handle; +void thread_set_event(event_t *handle) { + event_pthread_t *event = (event_pthread_t *)handle; - pthread_mutex_lock(&event->mutex); - event->state = 1; - pthread_cond_broadcast(&event->cond); - pthread_mutex_unlock(&event->mutex); + pthread_mutex_lock(&event->mutex); + event->state = 1; + pthread_cond_broadcast(&event->cond); + pthread_mutex_unlock(&event->mutex); } -void thread_reset_event(event_t *handle) -{ - event_pthread_t *event = (event_pthread_t *)handle; +void thread_reset_event(event_t *handle) { + event_pthread_t *event = (event_pthread_t *)handle; - pthread_mutex_lock(&event->mutex); - event->state = 0; - pthread_mutex_unlock(&event->mutex); + pthread_mutex_lock(&event->mutex); + event->state = 0; + pthread_mutex_unlock(&event->mutex); } -int thread_wait_event(event_t *handle, int timeout) -{ - event_pthread_t *event = (event_pthread_t *)handle; - struct timespec abstime; +int thread_wait_event(event_t *handle, int timeout) { + event_pthread_t *event = (event_pthread_t *)handle; + struct timespec abstime; #ifdef __linux__ - clock_gettime(CLOCK_REALTIME, &abstime); + clock_gettime(CLOCK_REALTIME, &abstime); #else - struct timeval now; - gettimeofday(&now, 0); - abstime.tv_sec = now.tv_sec; - abstime.tv_nsec = now.tv_usec*1000UL; + struct timeval now; + gettimeofday(&now, 0); + abstime.tv_sec = now.tv_sec; + abstime.tv_nsec = now.tv_usec * 1000UL; #endif - abstime.tv_nsec += (timeout % 1000) * 1000000; - abstime.tv_sec += (timeout / 1000); - if (abstime.tv_nsec > 1000000000) - { - abstime.tv_nsec -= 1000000000; - abstime.tv_sec++; - } + abstime.tv_nsec += (timeout % 1000) * 1000000; + abstime.tv_sec += (timeout / 1000); + if (abstime.tv_nsec > 1000000000) { + abstime.tv_nsec -= 1000000000; + abstime.tv_sec++; + } - pthread_mutex_lock(&event->mutex); - if (timeout == -1) - { - while (!event->state) - pthread_cond_wait(&event->cond, &event->mutex); - } - else if (!event->state) - pthread_cond_timedwait(&event->cond, &event->mutex, &abstime); - pthread_mutex_unlock(&event->mutex); + pthread_mutex_lock(&event->mutex); + if (timeout == -1) { + while (!event->state) + pthread_cond_wait(&event->cond, &event->mutex); + } else if (!event->state) + pthread_cond_timedwait(&event->cond, &event->mutex, &abstime); + pthread_mutex_unlock(&event->mutex); - return 0; + return 0; } -void thread_destroy_event(event_t *handle) -{ - event_pthread_t *event = (event_pthread_t *)handle; +void thread_destroy_event(event_t *handle) { + event_pthread_t *event = (event_pthread_t *)handle; - pthread_cond_destroy(&event->cond); - pthread_mutex_destroy(&event->mutex); + pthread_cond_destroy(&event->cond); + pthread_mutex_destroy(&event->mutex); - free(event); + free(event); } -void thread_sleep(int t) -{ - usleep(t * 1000); -} +void thread_sleep(int t) { usleep(t * 1000); } - -typedef struct pt_mutex_t -{ - pthread_mutex_t mutex; +typedef struct pt_mutex_t { + pthread_mutex_t mutex; } pt_mutex_t; -mutex_t *thread_create_mutex(void) -{ - pt_mutex_t *mutex = malloc(sizeof(pt_mutex_t)); +mutex_t *thread_create_mutex(void) { + pt_mutex_t *mutex = malloc(sizeof(pt_mutex_t)); - pthread_mutex_init(&mutex->mutex, NULL); - - return mutex; + pthread_mutex_init(&mutex->mutex, NULL); + return mutex; } -void thread_lock_mutex(mutex_t *_mutex) -{ - pt_mutex_t *mutex = (pt_mutex_t *)_mutex; +void thread_lock_mutex(mutex_t *_mutex) { + pt_mutex_t *mutex = (pt_mutex_t *)_mutex; - pthread_mutex_lock(&mutex->mutex); + pthread_mutex_lock(&mutex->mutex); } -void thread_unlock_mutex(mutex_t *_mutex) -{ - pt_mutex_t *mutex = (pt_mutex_t *)_mutex; +void thread_unlock_mutex(mutex_t *_mutex) { + pt_mutex_t *mutex = (pt_mutex_t *)_mutex; - pthread_mutex_unlock(&mutex->mutex); + pthread_mutex_unlock(&mutex->mutex); } -void thread_destroy_mutex(mutex_t *_mutex) -{ - pt_mutex_t *mutex = (pt_mutex_t *)_mutex; +void thread_destroy_mutex(mutex_t *_mutex) { + pt_mutex_t *mutex = (pt_mutex_t *)_mutex; - pthread_mutex_destroy(&mutex->mutex); + pthread_mutex_destroy(&mutex->mutex); - free(mutex); + free(mutex); } #endif diff --git a/src/wx-ui/wx-utils.cc b/src/wx-ui/wx-utils.cc index 8a571410..ec86d67f 100644 --- a/src/wx-ui/wx-utils.cc +++ b/src/wx-ui/wx-utils.cc @@ -20,675 +20,635 @@ #include "wx-common.h" #include "wx-status.h" -extern "C" -{ +extern "C" { #include "thread.h" } int confirm() { - if (emulation_state != EMULATION_STOPPED) { - return wx_messagebox(NULL, "This will reset PCem!\nOkay to continue?", "PCem", WX_MB_OKCANCEL) == WX_IDOK; - } - return 1; + if (emulation_state != EMULATION_STOPPED) { + return wx_messagebox(NULL, "This will reset PCem!\nOkay to continue?", "PCem", WX_MB_OKCANCEL) == WX_IDOK; + } + return 1; } int wx_messagebox(void *window, const char *message, const char *title = NULL, int style = 5) { - return wxMessageBox(message, title, style | wxCENTRE | wxSTAY_ON_TOP, (wxWindow *)window); + return wxMessageBox(message, title, style | wxCENTRE | wxSTAY_ON_TOP, (wxWindow *)window); } void wx_simple_messagebox(const char *title, const char *format, ...) { - char message[2048]; - va_list ap; - va_start(ap, format); - vsnprintf(message, 2047, format, ap); - message[2047] = 0; - va_end(ap); - wx_messagebox(0, message, title, WX_MB_OK); + char message[2048]; + va_list ap; + va_start(ap, format); + vsnprintf(message, 2047, format, ap); + message[2047] = 0; + va_end(ap); + wx_messagebox(0, message, title, WX_MB_OK); } -int wx_textentrydialog(void *window, const char *message, const char *title, const char *value, unsigned int min_length, unsigned int max_length, LONG_PARAM result) { - while (1) { - wxTextEntryDialog dlg((wxWindow *)window, message, title, value); - if (max_length > 0) - dlg.SetMaxLength(max_length); - if (dlg.ShowModal() == wxID_OK) { - wxString value = dlg.GetValue(); - if (value.Length() >= min_length) { - strcpy((char *)result, value.mb_str()); - return TRUE; - } - } else - return FALSE; - } - return FALSE; +int wx_textentrydialog(void *window, const char *message, const char *title, const char *value, unsigned int min_length, + unsigned int max_length, LONG_PARAM result) { + while (1) { + wxTextEntryDialog dlg((wxWindow *)window, message, title, value); + if (max_length > 0) + dlg.SetMaxLength(max_length); + if (dlg.ShowModal() == wxID_OK) { + wxString value = dlg.GetValue(); + if (value.Length() >= min_length) { + strcpy((char *)result, value.mb_str()); + return TRUE; + } + } else + return FALSE; + } + return FALSE; } -void wx_setwindowtitle(void *window, char *s) { - ((wxFrame *)window)->SetTitle(s); -} +void wx_setwindowtitle(void *window, char *s) { ((wxFrame *)window)->SetTitle(s); } -int wx_xrcid(const char *s) { - return XRCID(s); -} +int wx_xrcid(const char *s) { return XRCID(s); } -int wx_filedialog(void *window, const char *title, const char *path, - const char *extensions, const char *extension, int open, char *file) { - wxFileDialog dlg((wxWindow *)window, title, "", path, extensions, - open ? (wxFD_OPEN | wxFD_FILE_MUST_EXIST) : (wxFD_SAVE | wxFD_OVERWRITE_PROMPT)); - if (dlg.ShowModal() == wxID_OK) { - wxString p = dlg.GetPath(); - wxFileName f(p); - if (!open && !f.HasExt() && extension) { - wxString e = extension; - if (!p.EndsWith(".")) - p += "."; - p += extension; - strcpy(file, p.mb_str()); - } else - strcpy(file, p.mb_str()); - return 0; - } - return 1; +int wx_filedialog(void *window, const char *title, const char *path, const char *extensions, const char *extension, int open, + char *file) { + wxFileDialog dlg((wxWindow *)window, title, "", path, extensions, + open ? (wxFD_OPEN | wxFD_FILE_MUST_EXIST) : (wxFD_SAVE | wxFD_OVERWRITE_PROMPT)); + if (dlg.ShowModal() == wxID_OK) { + wxString p = dlg.GetPath(); + wxFileName f(p); + if (!open && !f.HasExt() && extension) { + wxString e = extension; + if (!p.EndsWith(".")) + p += "."; + p += extension; + strcpy(file, p.mb_str()); + } else + strcpy(file, p.mb_str()); + return 0; + } + return 1; } void wx_checkmenuitem(void *menu, int id, int checked) { - wxMenuItem *item = NULL; - if (((wxObject *)menu)->GetClassInfo()->IsKindOf(CLASSINFO(wxMenuBar))) - item = ((wxMenuBar *)menu)->FindItem(id); - else - item = ((wxMenu *)menu)->FindItem(id); + wxMenuItem *item = NULL; + if (((wxObject *)menu)->GetClassInfo()->IsKindOf(CLASSINFO(wxMenuBar))) + item = ((wxMenuBar *)menu)->FindItem(id); + else + item = ((wxMenu *)menu)->FindItem(id); - if (item) - item->Check(checked); + if (item) + item->Check(checked); #ifndef RELEASE_BUILD - else - std::cout << "Menu item not found: " << id << std::endl; + else + std::cout << "Menu item not found: " << id << std::endl; #endif } void wx_enablemenuitem(void *menu, int id, int enable) { - wxMenuItem *item = NULL; - if (((wxObject *)menu)->GetClassInfo()->IsKindOf(CLASSINFO(wxMenuBar))) - item = ((wxMenuBar *)menu)->FindItem(id); - else - item = ((wxMenu *)menu)->FindItem(id); + wxMenuItem *item = NULL; + if (((wxObject *)menu)->GetClassInfo()->IsKindOf(CLASSINFO(wxMenuBar))) + item = ((wxMenuBar *)menu)->FindItem(id); + else + item = ((wxMenu *)menu)->FindItem(id); - if (item) - item->Enable(enable); + if (item) + item->Enable(enable); #ifndef RELEASE_BUILD - else - std::cout << "Menu item not found: " << id << std::endl; + else + std::cout << "Menu item not found: " << id << std::endl; #endif } void *wx_getsubmenu(void *menu, int id) { - wxMenuItem *m = ((wxMenu *)menu)->FindItem(id); - if (m) - return m->GetSubMenu(); + wxMenuItem *m = ((wxMenu *)menu)->FindItem(id); + if (m) + return m->GetSubMenu(); - return 0; + return 0; } void *wx_getnativemenu(void *menu) { #ifdef _WIN32 - return ((wxMenu *)menu)->GetHMenu(); + return ((wxMenu *)menu)->GetHMenu(); #endif - return 0; + return 0; } void *wx_getnativewindow(void *window) { #ifdef _WIN32 - return ((wxWindow *)window)->GetHWND(); + return ((wxWindow *)window)->GetHWND(); #endif - return 0; + return 0; } #ifdef _WIN32 void wx_winsendmessage(void *window, int msg, INT_PARAM wParam, LONG_PARAM lParam) { - WinSendMessageEvent *event = new WinSendMessageEvent(wx_getnativewindow(window), msg, wParam, lParam); - wxQueueEvent((wxWindow *)window, event); + WinSendMessageEvent *event = new WinSendMessageEvent(wx_getnativewindow(window), msg, wParam, lParam); + wxQueueEvent((wxWindow *)window, event); } #endif void wx_appendmenu(void *sub_menu, int id, const char *title, enum wxItemKind type) { - ((wxMenu *)sub_menu)->Append(id, title, wxEmptyString, type); + ((wxMenu *)sub_menu)->Append(id, title, wxEmptyString, type); } -void wx_enabletoolbaritem(void *toolbar, int id, int enable) { - ((wxToolBar *)toolbar)->EnableTool(id, enable); -} +void wx_enabletoolbaritem(void *toolbar, int id, int enable) { ((wxToolBar *)toolbar)->EnableTool(id, enable); } -void *wx_getmenu(void *window) { - return ((Frame *)window)->GetMenu(); -} +void *wx_getmenu(void *window) { return ((Frame *)window)->GetMenu(); } -void *wx_getmenubar(void *window) { - return ((wxFrame *)window)->GetMenuBar(); -} +void *wx_getmenubar(void *window) { return ((wxFrame *)window)->GetMenuBar(); } -void *wx_gettoolbar(void *window) { - return ((wxFrame *)window)->GetToolBar(); -} +void *wx_gettoolbar(void *window) { return ((wxFrame *)window)->GetToolBar(); } -void *wx_getdlgitem(void *window, int id) { - return ((wxWindow *)window)->FindWindow(id); -} +void *wx_getdlgitem(void *window, int id) { return ((wxWindow *)window)->FindWindow(id); } void wx_setdlgitemtext(void *window, int id, char *str) { - wxWindow *w = ((wxWindow *)window)->FindWindow(id); - if (w->GetClassInfo()->IsKindOf(CLASSINFO(wxTextCtrl))) - ((wxTextCtrl *)w)->SetValue(str); - else - ((wxStaticText *)w)->SetLabel(str); + wxWindow *w = ((wxWindow *)window)->FindWindow(id); + if (w->GetClassInfo()->IsKindOf(CLASSINFO(wxTextCtrl))) + ((wxTextCtrl *)w)->SetValue(str); + else + ((wxStaticText *)w)->SetLabel(str); } -void wx_enablewindow(void *window, int enabled) { - ((wxWindow *)window)->Enable(enabled); -} +void wx_enablewindow(void *window, int enabled) { ((wxWindow *)window)->Enable(enabled); } void wx_showwindow(void *window, int show) { - wxCommandEvent *event = new wxCommandEvent(WX_SHOW_WINDOW_EVENT, wxID_ANY); - event->SetEventObject((wxWindow *)window); - event->SetInt(show); - wxQueueEvent((wxWindow *)window, event); + wxCommandEvent *event = new wxCommandEvent(WX_SHOW_WINDOW_EVENT, wxID_ANY); + event->SetEventObject((wxWindow *)window); + event->SetInt(show); + wxQueueEvent((wxWindow *)window, event); } -int wx_iswindowvisible(void *window) { - return ((wxWindow *)window)->IsShown(); -} +int wx_iswindowvisible(void *window) { return ((wxWindow *)window)->IsShown(); } -void wx_togglewindow(void *window) { - wx_showwindow(window, -1); -} +void wx_togglewindow(void *window) { wx_showwindow(window, -1); } void wx_callback(void *window, WX_CALLBACK callback, void *data) { - CallbackEvent *event = new CallbackEvent(callback, data); - wxQueueEvent((wxWindow *)window, event); + CallbackEvent *event = new CallbackEvent(callback, data); + wxQueueEvent((wxWindow *)window, event); } -void wx_enddialog(void *window, int ret_code) { - ((wxDialog *)window)->EndModal(ret_code); -} +void wx_enddialog(void *window, int ret_code) { ((wxDialog *)window)->EndModal(ret_code); } int wx_dlgdirlist(void *window, const char *path, int id, int static_path, int file_type) { - wxWindow *w = ((wxWindow *)window)->FindWindow(id); - if (w->GetClassInfo()->IsKindOf(CLASSINFO(wxListBox))) { - wxListBox *list = (wxListBox *)w; - list->Clear(); - wxArrayString items; - wxString f = wxFindFirstFile(path); - while (!f.empty()) { - wxFileName file(f); - items.Add(file.GetName()); - f = wxFindNextFile(); - } - items.Sort(); - list->Set(items); - return TRUE; - } - return FALSE; + wxWindow *w = ((wxWindow *)window)->FindWindow(id); + if (w->GetClassInfo()->IsKindOf(CLASSINFO(wxListBox))) { + wxListBox *list = (wxListBox *)w; + list->Clear(); + wxArrayString items; + wxString f = wxFindFirstFile(path); + while (!f.empty()) { + wxFileName file(f); + items.Add(file.GetName()); + f = wxFindNextFile(); + } + items.Sort(); + list->Set(items); + return TRUE; + } + return FALSE; } int wx_dlgdirselectex(void *window, LONG_PARAM path, int count, int id) { - wxWindow *w = ((wxWindow *)window)->FindWindow(id); - if (w->GetClassInfo()->IsKindOf(CLASSINFO(wxListBox))) { - wxListBox *list = (wxListBox *)w; - strcpy((char *)path, (list->GetStringSelection() + ".").GetData().AsChar()); - return TRUE; - } - return FALSE; + wxWindow *w = ((wxWindow *)window)->FindWindow(id); + if (w->GetClassInfo()->IsKindOf(CLASSINFO(wxListBox))) { + wxListBox *list = (wxListBox *)w; + strcpy((char *)path, (list->GetStringSelection() + ".").GetData().AsChar()); + return TRUE; + } + return FALSE; } int wx_sendmessage(void *window, int type, LONG_PARAM param1, LONG_PARAM param2) { - switch (type) { - case WX_CB_ADDSTRING:((wxComboBox *)window)->Append((char *)param2); - break; - case WX_CB_SETCURSEL: - if (param1 >= 0 && param1 < (int)((wxComboBox *)window)->GetCount()) - ((wxComboBox *)window)->Select(param1); - break; - case WX_CB_GETCURSEL:return ((wxComboBox *)window)->GetCurrentSelection(); - break; - case WX_CB_GETLBTEXT:strcpy((char *)param2, ((wxComboBox *)window)->GetString(param1).mb_str()); - break; - case WX_CB_RESETCONTENT: { + switch (type) { + case WX_CB_ADDSTRING: + ((wxComboBox *)window)->Append((char *)param2); + break; + case WX_CB_SETCURSEL: + if (param1 >= 0 && param1 < (int)((wxComboBox *)window)->GetCount()) + ((wxComboBox *)window)->Select(param1); + break; + case WX_CB_GETCURSEL: + return ((wxComboBox *)window)->GetCurrentSelection(); + break; + case WX_CB_GETLBTEXT: + strcpy((char *)param2, ((wxComboBox *)window)->GetString(param1).mb_str()); + break; + case WX_CB_RESETCONTENT: { #ifndef __WXOSX_MAC__ - ((wxComboBox *)window)->SetValue(""); - ((wxComboBox *)window)->Clear(); + ((wxComboBox *)window)->SetValue(""); + ((wxComboBox *)window)->Clear(); #else - /* Clear() does not work on OSX */ - wxComboBox* cb = (wxComboBox*) window; - int count = cb->GetCount(); - while (count--) - cb->Delete(0); + /* Clear() does not work on OSX */ + wxComboBox *cb = (wxComboBox *)window; + int count = cb->GetCount(); + while (count--) + cb->Delete(0); #endif - break; - } - case WX_BM_SETCHECK:((wxCheckBox *)window)->SetValue(param1); - break; - case WX_BM_GETCHECK:return ((wxCheckBox *)window)->GetValue(); - break; - case WX_WM_SETTEXT: { - if (((wxWindow *)window)->GetClassInfo()->IsKindOf(CLASSINFO(wxTextCtrl))) - ((wxTextCtrl *)window)->SetValue((char *)param2); - else - ((wxStaticText *)window)->SetLabel((char *)param2); - } - break; - case WX_WM_GETTEXT: - if (((wxWindow *)window)->GetClassInfo()->IsKindOf(CLASSINFO(wxTextCtrl))) - strcpy((char *)param2, ((wxTextCtrl *)window)->GetValue().mb_str()); - else - strcpy((char *)param2, ((wxStaticText *)window)->GetLabel().mb_str()); - break; - case WX_UDM_SETPOS:((wxSpinCtrl *)window)->SetValue(param2); - break; - case WX_UDM_GETPOS:return ((wxSpinCtrl *)window)->GetValue(); - case WX_UDM_SETRANGE: { - int min = (param2 >> 16) & 0xffff; - int max = param2 & 0xffff; - ((wxSpinCtrl *)window)->SetRange(min, max); - break; - } - case WX_UDM_SETINCR: { - /* SetIncrement-method may not exist on all platforms */ + break; + } + case WX_BM_SETCHECK: + ((wxCheckBox *)window)->SetValue(param1); + break; + case WX_BM_GETCHECK: + return ((wxCheckBox *)window)->GetValue(); + break; + case WX_WM_SETTEXT: { + if (((wxWindow *)window)->GetClassInfo()->IsKindOf(CLASSINFO(wxTextCtrl))) + ((wxTextCtrl *)window)->SetValue((char *)param2); + else + ((wxStaticText *)window)->SetLabel((char *)param2); + } break; + case WX_WM_GETTEXT: + if (((wxWindow *)window)->GetClassInfo()->IsKindOf(CLASSINFO(wxTextCtrl))) + strcpy((char *)param2, ((wxTextCtrl *)window)->GetValue().mb_str()); + else + strcpy((char *)param2, ((wxStaticText *)window)->GetLabel().mb_str()); + break; + case WX_UDM_SETPOS: + ((wxSpinCtrl *)window)->SetValue(param2); + break; + case WX_UDM_GETPOS: + return ((wxSpinCtrl *)window)->GetValue(); + case WX_UDM_SETRANGE: { + int min = (param2 >> 16) & 0xffff; + int max = param2 & 0xffff; + ((wxSpinCtrl *)window)->SetRange(min, max); + break; + } + case WX_UDM_SETINCR: { + /* SetIncrement-method may not exist on all platforms */ #ifdef __WXGTK__ - ((wxSpinCtrl*) window)->SetIncrement(param2); + ((wxSpinCtrl *)window)->SetIncrement(param2); #endif - break; - } - case WX_LB_GETCOUNT: { - return ((wxListBox *)window)->GetCount(); - } - case WX_LB_GETCURSEL: { - return ((wxListBox *)window)->GetSelection(); - } - case WX_LB_SETCURSEL: { - ((wxListBox *)window)->SetSelection(param1); - break; - } - case WX_LB_GETTEXT: { - strcpy((char *)param2, ((wxListBox *)window)->GetString(param1).mb_str()); - break; - } - case WX_LB_INSERTSTRING: { - ((wxListBox *)window)->Insert((char *)param2, param1); - break; - } - case WX_LB_DELETESTRING: { - ((wxListBox *)window)->Delete(param1); - break; - } - case WX_LB_RESETCONTENT: { - ((wxListBox *)window)->Clear(); - break; - } - case WX_CHB_SETPAGETEXT: { - ((wxChoicebook *)window)->SetPageText(param1, (char *)param2); - break; - } - case WX_CHB_ADDPAGE: { - ((wxChoicebook *)window)->AddPage((wxWindow *)param1, (char *)param2); - break; - } - case WX_CHB_REMOVEPAGE: { - ((wxChoicebook *)window)->RemovePage(param1); - break; - } - case WX_CHB_GETPAGECOUNT: { - return ((wxChoicebook *)window)->GetPageCount(); - } - case WX_REPARENT: { - ((wxWindow *)window)->Reparent((wxWindow *)param1); - break; - } - case WX_WM_ENABLE: { - ((wxWindow *)window)->Enable((bool)param2); - break; - } - case WX_WM_SHOW: { - ((wxWindow *)window)->Show((bool)param2); - break; - } - case WX_WM_LAYOUT: { - ((wxWindow *)window)->Layout(); - break; - } - case WX_SB_SETCURSEL: - if (param1 >= 0 && param1 < (int)((wxSimplebook *)window)->GetChildren().GetCount()) - ((wxSimplebook *)window)->SetSelection(param1); - break; - } + break; + } + case WX_LB_GETCOUNT: { + return ((wxListBox *)window)->GetCount(); + } + case WX_LB_GETCURSEL: { + return ((wxListBox *)window)->GetSelection(); + } + case WX_LB_SETCURSEL: { + ((wxListBox *)window)->SetSelection(param1); + break; + } + case WX_LB_GETTEXT: { + strcpy((char *)param2, ((wxListBox *)window)->GetString(param1).mb_str()); + break; + } + case WX_LB_INSERTSTRING: { + ((wxListBox *)window)->Insert((char *)param2, param1); + break; + } + case WX_LB_DELETESTRING: { + ((wxListBox *)window)->Delete(param1); + break; + } + case WX_LB_RESETCONTENT: { + ((wxListBox *)window)->Clear(); + break; + } + case WX_CHB_SETPAGETEXT: { + ((wxChoicebook *)window)->SetPageText(param1, (char *)param2); + break; + } + case WX_CHB_ADDPAGE: { + ((wxChoicebook *)window)->AddPage((wxWindow *)param1, (char *)param2); + break; + } + case WX_CHB_REMOVEPAGE: { + ((wxChoicebook *)window)->RemovePage(param1); + break; + } + case WX_CHB_GETPAGECOUNT: { + return ((wxChoicebook *)window)->GetPageCount(); + } + case WX_REPARENT: { + ((wxWindow *)window)->Reparent((wxWindow *)param1); + break; + } + case WX_WM_ENABLE: { + ((wxWindow *)window)->Enable((bool)param2); + break; + } + case WX_WM_SHOW: { + ((wxWindow *)window)->Show((bool)param2); + break; + } + case WX_WM_LAYOUT: { + ((wxWindow *)window)->Layout(); + break; + } + case WX_SB_SETCURSEL: + if (param1 >= 0 && param1 < (int)((wxSimplebook *)window)->GetChildren().GetCount()) + ((wxSimplebook *)window)->SetSelection(param1); + break; + } - ((wxWindow *)window)->Fit(); + ((wxWindow *)window)->Fit(); - return 0; + return 0; } -int wx_dialogbox(void *window, const char *name, int (*callback)(void *window, int message, INT_PARAM param1, LONG_PARAM param2)) { - PCemDialogBox dlg((wxWindow *)window, name, callback); - dlg.OnInit(); - dlg.Fit(); - int ret = dlg.ShowModal(); - dlg.Destroy(); - return ret; +int wx_dialogbox(void *window, const char *name, + int (*callback)(void *window, int message, INT_PARAM param1, LONG_PARAM param2)) { + PCemDialogBox dlg((wxWindow *)window, name, callback); + dlg.OnInit(); + dlg.Fit(); + int ret = dlg.ShowModal(); + dlg.Destroy(); + return ret; } void wx_exit(void *window, int value) { - wxCommandEvent *event = new wxCommandEvent(WX_EXIT_EVENT, wxID_ANY); - event->SetEventObject((wxWindow *)window); - event->SetInt(value); - wxQueueEvent((wxWindow *)window, event); + wxCommandEvent *event = new wxCommandEvent(WX_EXIT_EVENT, wxID_ANY); + event->SetEventObject((wxWindow *)window); + event->SetInt(value); + wxQueueEvent((wxWindow *)window, event); } void wx_stop_emulation(void *window) { - wxCommandEvent *event = new wxCommandEvent(WX_STOP_EMULATION_EVENT, wxID_ANY); - event->SetEventObject((wxWindow *)window); - wxQueueEvent((wxWindow *)window, event); + wxCommandEvent *event = new wxCommandEvent(WX_STOP_EMULATION_EVENT, wxID_ANY); + event->SetEventObject((wxWindow *)window); + wxQueueEvent((wxWindow *)window, event); } void wx_stop_emulation_now(void *window) { - wxCommandEvent *event = new wxCommandEvent(WX_STOP_EMULATION_NOW_EVENT, wxID_ANY); - event->SetEventObject((wxWindow *)window); - wxQueueEvent((wxWindow *)window, event); + wxCommandEvent *event = new wxCommandEvent(WX_STOP_EMULATION_NOW_EVENT, wxID_ANY); + event->SetEventObject((wxWindow *)window); + wxQueueEvent((wxWindow *)window, event); } -int wx_yield() { - return wxYield(); -} +int wx_yield() { return wxYield(); } /* Timer stuff */ class PCemTimer : public wxTimer { public: - PCemTimer(void (*fn)()) { - this->fn = fn; - } - virtual ~PCemTimer() {}; + PCemTimer(void (*fn)()) { this->fn = fn; } + virtual ~PCemTimer(){}; + + void Notify() { fn(); } - void Notify() { - fn(); - } private: - void (*fn)(); + void (*fn)(); }; -void *wx_createtimer(void (*fn)()) { - return new PCemTimer(fn); -} +void *wx_createtimer(void (*fn)()) { return new PCemTimer(fn); } void wx_starttimer(void *timer, int milliseconds, int once) { - wxTimer *t = (wxTimer *)timer; - t->Start(milliseconds, once); + wxTimer *t = (wxTimer *)timer; + t->Start(milliseconds, once); } void wx_stoptimer(void *timer) { - wxTimer *t = (wxTimer *)timer; - t->Stop(); + wxTimer *t = (wxTimer *)timer; + t->Stop(); } void wx_destroytimer(void *timer) { - wx_stoptimer(timer); - delete (wxTimer *)timer; + wx_stoptimer(timer); + delete (wxTimer *)timer; } void wx_popupmenu(void *window, void *menu, int *x, int *y) { - PopupMenuEvent *event = new PopupMenuEvent((wxWindow *)window, (wxMenu *)menu, x, y); - wxQueueEvent((wxWindow *)window, event); + PopupMenuEvent *event = new PopupMenuEvent((wxWindow *)window, (wxMenu *)menu, x, y); + wxQueueEvent((wxWindow *)window, event); } void *wx_create_status_frame(void *window) { - StatusFrame *frame = new StatusFrame((wxWindow *)window); - return frame; + StatusFrame *frame = new StatusFrame((wxWindow *)window); + return frame; } void wx_destroy_status_frame(void *window) { - StatusFrame *frame = (StatusFrame *)window; - delete frame; + StatusFrame *frame = (StatusFrame *)window; + delete frame; } -void wx_setwindowposition(void *window, int x, int y) { - ((wxFrame *)window)->SetPosition(wxPoint(x, y)); -} +void wx_setwindowposition(void *window, int x, int y) { ((wxFrame *)window)->SetPosition(wxPoint(x, y)); } -void wx_setwindowsize(void *window, int width, int height) { - ((wxFrame *)window)->SetSize(wxSize(width, height)); -} +void wx_setwindowsize(void *window, int width, int height) { ((wxFrame *)window)->SetSize(wxSize(width, height)); } void wx_show_status(void *window) { - wxWindow *status = ((wxWindow *)window)->FindWindowById(STATUS_WINDOW_ID); - if (!status) { - StatusFrame *statusFrame = new StatusFrame((wxWindow *)window); - statusFrame->Show(); - } + wxWindow *status = ((wxWindow *)window)->FindWindowById(STATUS_WINDOW_ID); + if (!status) { + StatusFrame *statusFrame = new StatusFrame((wxWindow *)window); + statusFrame->Show(); + } } void wx_close_status(void *window) { - wxWindow *status = ((wxWindow *)window)->FindWindowById(STATUS_WINDOW_ID); - if (status) { - status->Close(); - } + wxWindow *status = ((wxWindow *)window)->FindWindowById(STATUS_WINDOW_ID); + if (status) { + status->Close(); + } } -int wx_create_directory(char *path) { - return wxFileName::Mkdir(path); -} +int wx_create_directory(char *path) { return wxFileName::Mkdir(path); } int wx_setup(char *path) { - wxFileName p(path); - if (!p.DirExists()) { - if (!p.Mkdir()) - return FALSE; - wxFileName configs(p); - configs.AppendDir("configs"); - if (!configs.DirExists() && !configs.Mkdir()) - return FALSE; + wxFileName p(path); + if (!p.DirExists()) { + if (!p.Mkdir()) + return FALSE; + wxFileName configs(p); + configs.AppendDir("configs"); + if (!configs.DirExists() && !configs.Mkdir()) + return FALSE; - wxFileName roms(p); - roms.AppendDir("roms"); - if (!roms.DirExists() && !roms.Mkdir()) - return FALSE; + wxFileName roms(p); + roms.AppendDir("roms"); + if (!roms.DirExists() && !roms.Mkdir()) + return FALSE; - wxFileName nvr(p); - nvr.AppendDir("nvr"); - if (!nvr.DirExists() && !nvr.Mkdir()) - return FALSE; + wxFileName nvr(p); + nvr.AppendDir("nvr"); + if (!nvr.DirExists() && !nvr.Mkdir()) + return FALSE; - wxFileName screenshots(p); - screenshots.AppendDir("screenshots"); - if (!screenshots.DirExists() && !screenshots.Mkdir()) - return FALSE; + wxFileName screenshots(p); + screenshots.AppendDir("screenshots"); + if (!screenshots.DirExists() && !screenshots.Mkdir()) + return FALSE; - wxFileName logs(p); - logs.AppendDir("logs"); - if (!logs.DirExists() && !logs.Mkdir()) - return FALSE; - } + wxFileName logs(p); + logs.AppendDir("logs"); + if (!logs.DirExists() && !logs.Mkdir()) + return FALSE; + } - return TRUE; + return TRUE; } int wx_file_exists(char *path) { - wxFileName p(path); - return p.Exists(); + wxFileName p(path); + return p.Exists(); } -int wx_copy_file(char *from, char *to, int overwrite) { - return wxCopyFile(from, to, overwrite); -} +int wx_copy_file(char *from, char *to, int overwrite) { return wxCopyFile(from, to, overwrite); } int wx_image_save(const char *path, const char *name, const char *format, unsigned char *rgba, int width, int height, int alpha) { - int x, y; - wxLogNull logNull; - wxImage image(width, height); - if (alpha) { - unsigned char *rgb = (unsigned char *)malloc(width * height * 3); - unsigned char *a = (unsigned char *)malloc(width * height); - for (x = 0; x < width; ++x) { - for (y = 0; y < height; ++y) { - rgb[(y * width + x) * 3 + 0] = rgba[(y * width + x) * 4 + 0]; - rgb[(y * width + x) * 3 + 1] = rgba[(y * width + x) * 4 + 1]; - rgb[(y * width + x) * 3 + 2] = rgba[(y * width + x) * 4 + 2]; - a[y * width + x] = rgba[(y * width + x) * 4 + 3]; - } - } - image.SetData(rgb); - image.SetAlpha(a); - } else - image.SetData(rgba, true); + int x, y; + wxLogNull logNull; + wxImage image(width, height); + if (alpha) { + unsigned char *rgb = (unsigned char *)malloc(width * height * 3); + unsigned char *a = (unsigned char *)malloc(width * height); + for (x = 0; x < width; ++x) { + for (y = 0; y < height; ++y) { + rgb[(y * width + x) * 3 + 0] = rgba[(y * width + x) * 4 + 0]; + rgb[(y * width + x) * 3 + 1] = rgba[(y * width + x) * 4 + 1]; + rgb[(y * width + x) * 3 + 2] = rgba[(y * width + x) * 4 + 2]; + a[y * width + x] = rgba[(y * width + x) * 4 + 3]; + } + } + image.SetData(rgb); + image.SetAlpha(a); + } else + image.SetData(rgba, true); - wxImageHandler *h; - wxString ext; + wxImageHandler *h; + wxString ext; - if (!strcmp(format, IMAGE_TIFF)) { - h = new wxTIFFHandler(); - ext = "tif"; - } else if (!strcmp(format, IMAGE_BMP)) { - h = new wxBMPHandler(); - ext = "bmp"; - } else if (!strcmp(format, IMAGE_JPG)) { - h = new wxJPEGHandler(); - ext = "jpg"; - } else { - h = new wxPNGHandler(); - ext = "png"; - } + if (!strcmp(format, IMAGE_TIFF)) { + h = new wxTIFFHandler(); + ext = "tif"; + } else if (!strcmp(format, IMAGE_BMP)) { + h = new wxBMPHandler(); + ext = "bmp"; + } else if (!strcmp(format, IMAGE_JPG)) { + h = new wxJPEGHandler(); + ext = "jpg"; + } else { + h = new wxPNGHandler(); + ext = "png"; + } - int res = 0; - if (h) { - wxString p(path); - if (!p.EndsWith("/")) - p = p.Append("/"); - p = p.Append(name).Append(".").Append(ext); + int res = 0; + if (h) { + wxString p(path); + if (!p.EndsWith("/")) + p = p.Append("/"); + p = p.Append(name).Append(".").Append(ext); - wxFileOutputStream stream(p); - res = h->SaveFile(&image, stream, false); - delete h; - } + wxFileOutputStream stream(p); + res = h->SaveFile(&image, stream, false); + delete h; + } - return res; + return res; } void *wx_image_load(const char *path) { - wxLogNull logNull; /* removes sRGB-warnings on Windows */ - wxImage *image = new wxImage(path); - if (image->IsOk()) - return image; - delete image; - return 0; + wxLogNull logNull; /* removes sRGB-warnings on Windows */ + wxImage *image = new wxImage(path); + if (image->IsOk()) + return image; + delete image; + return 0; } -void wx_image_free(void *image) { - delete (wxImage *)image; -} +void wx_image_free(void *image) { delete (wxImage *)image; } -void wx_image_rescale(void *image, int width, int height) { - ((wxImage *)image)->Rescale(width, height); -} +void wx_image_rescale(void *image, int width, int height) { ((wxImage *)image)->Rescale(width, height); } void wx_image_get_size(void *image, int *width, int *height) { - *width = ((wxImage *)image)->GetWidth(); - *height = ((wxImage *)image)->GetHeight(); + *width = ((wxImage *)image)->GetWidth(); + *height = ((wxImage *)image)->GetHeight(); } -unsigned char *wx_image_get_data(void *image) { - return ((wxImage *)image)->GetData(); -} +unsigned char *wx_image_get_data(void *image) { return ((wxImage *)image)->GetData(); } -unsigned char *wx_image_get_alpha(void *image) { - return ((wxImage *)image)->GetAlpha(); -} +unsigned char *wx_image_get_alpha(void *image) { return ((wxImage *)image)->GetAlpha(); } /* wxFileConfig */ void *wx_config_load(const char *path) { - if (!wxFileExists(path)) - return 0; - wxFileInputStream stream(path); - if (stream.IsOk()) - return new wxFileConfig(stream); - return 0; + if (!wxFileExists(path)) + return 0; + wxFileInputStream stream(path); + if (stream.IsOk()) + return new wxFileConfig(stream); + return 0; } int wx_config_get_string(void *config, const char *name, char *dst, int size, const char *defVal) { - wxFileConfig *c = ((wxFileConfig *)config); - wxString val; - bool res = c->Read(name, &val, wxString(defVal)); - strncpy(dst, val.GetData().AsChar(), size - 1); - dst[size - 1] = 0; - return res; + wxFileConfig *c = ((wxFileConfig *)config); + wxString val; + bool res = c->Read(name, &val, wxString(defVal)); + strncpy(dst, val.GetData().AsChar(), size - 1); + dst[size - 1] = 0; + return res; } int wx_config_get_int(void *config, const char *name, int *dst, int defVal) { - wxFileConfig *c = ((wxFileConfig *)config); - return c->Read(name, dst, defVal); + wxFileConfig *c = ((wxFileConfig *)config); + return c->Read(name, dst, defVal); } int wx_config_get_float(void *config, const char *name, float *dst, float defVal) { - wxFileConfig *c = ((wxFileConfig *)config); - return c->Read(name, dst, defVal); - + wxFileConfig *c = ((wxFileConfig *)config); + return c->Read(name, dst, defVal); } int wx_config_get_bool(void *config, const char *name, int *dst, int defVal) { - wxFileConfig *c = ((wxFileConfig *)config); - wxString val; - bool res = 1; - if (c->Read(name, &val)) { - val.LowerCase(); - if (val.StartsWith("true")) - *dst = 1; - else if (val.StartsWith("false")) - *dst = 0; - else - res = 0; - } - if (!res) - res = c->Read(name, (bool *)dst, (bool)defVal); + wxFileConfig *c = ((wxFileConfig *)config); + wxString val; + bool res = 1; + if (c->Read(name, &val)) { + val.LowerCase(); + if (val.StartsWith("true")) + *dst = 1; + else if (val.StartsWith("false")) + *dst = 0; + else + res = 0; + } + if (!res) + res = c->Read(name, (bool *)dst, (bool)defVal); - return res; + return res; } int wx_config_has_entry(void *config, const char *name) { - wxFileConfig *c = ((wxFileConfig *)config); - return c->HasEntry(name); + wxFileConfig *c = ((wxFileConfig *)config); + return c->HasEntry(name); } -void wx_config_free(void *config) { - delete (wxFileConfig *)config; -} +void wx_config_free(void *config) { delete (wxFileConfig *)config; } typedef struct progress_data_t { - WX_CALLBACK callback; - void *data; - int active; - int result; + WX_CALLBACK callback; + void *data; + int active; + int result; } progress_data_t; static void progress_callback(void *data) { - progress_data_t *d = (progress_data_t *)data; - d->result = d->callback(d->data); - d->active = 0; + progress_data_t *d = (progress_data_t *)data; + d->result = d->callback(d->data); + d->active = 0; } -int wx_progressdialog(void *window, const char *title, const char *message, WX_CALLBACK callback, void *data, int range, volatile int *pos) { - struct progress_data_t pdata; - pdata.callback = callback; - pdata.data = data; - pdata.active = 1; - pdata.result = 0; +int wx_progressdialog(void *window, const char *title, const char *message, WX_CALLBACK callback, void *data, int range, + volatile int *pos) { + struct progress_data_t pdata; + pdata.callback = callback; + pdata.data = data; + pdata.active = 1; + pdata.result = 0; - thread_t *t = thread_create(progress_callback, &pdata); + thread_t *t = thread_create(progress_callback, &pdata); - wxProgressDialog dlg(title, message, range, (wxWindow *)window, wxPD_APP_MODAL | wxPD_SMOOTH | wxPD_AUTO_HIDE); - while (pdata.active) { - dlg.Update(*pos); - wxMilliSleep(50); - } - thread_kill(t); + wxProgressDialog dlg(title, message, range, (wxWindow *)window, wxPD_APP_MODAL | wxPD_SMOOTH | wxPD_AUTO_HIDE); + while (pdata.active) { + dlg.Update(*pos); + wxMilliSleep(50); + } + thread_kill(t); - return pdata.result; + return pdata.result; } void wx_date_format(char *s, const char *format) { - wxString res = wxDateTime::Now().Format(format); - strcpy(s, res.mb_str()); + wxString res = wxDateTime::Now().Format(format); + strcpy(s, res.mb_str()); }